summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt22
-rw-r--r--src/animation/AnimBlendAssocGroup.cpp51
-rw-r--r--src/animation/AnimBlendAssocGroup.h4
-rw-r--r--src/animation/AnimBlendAssociation.cpp47
-rw-r--r--src/animation/AnimBlendAssociation.h26
-rw-r--r--src/animation/AnimBlendClumpData.h18
-rw-r--r--src/animation/AnimBlendHierarchy.cpp49
-rw-r--r--src/animation/AnimBlendHierarchy.h5
-rw-r--r--src/animation/AnimBlendNode.cpp172
-rw-r--r--src/animation/AnimBlendNode.h6
-rw-r--r--src/animation/AnimBlendSequence.cpp22
-rw-r--r--src/animation/AnimBlendSequence.h45
-rw-r--r--src/animation/AnimManager.cpp1070
-rw-r--r--src/animation/AnimManager.h59
-rw-r--r--src/animation/AnimationId.h193
-rw-r--r--src/animation/Bones.cpp73
-rw-r--r--src/animation/Bones.h38
-rw-r--r--src/animation/CutsceneMgr.cpp531
-rw-r--r--src/animation/CutsceneMgr.h12
-rw-r--r--src/animation/FrameUpdate.cpp249
-rw-r--r--src/animation/RpAnimBlend.cpp112
-rw-r--r--src/animation/RpAnimBlend.h8
-rw-r--r--src/audio/AudioCollision.cpp50
-rw-r--r--src/audio/AudioCollision.h2
-rw-r--r--src/audio/AudioLogic.cpp10635
-rw-r--r--src/audio/AudioManager.cpp309
-rw-r--r--src/audio/AudioManager.h393
-rw-r--r--src/audio/AudioSamples.h12758
-rw-r--r--src/audio/AudioScriptObject.cpp2
-rw-r--r--src/audio/DMAudio.cpp104
-rw-r--r--src/audio/DMAudio.h38
-rw-r--r--src/audio/MusicManager.cpp1797
-rw-r--r--src/audio/MusicManager.h78
-rw-r--r--src/audio/PolRadio.cpp709
-rw-r--r--src/audio/PolRadio.h2
-rw-r--r--src/audio/audio_enums.h1450
-rw-r--r--src/audio/oal/stream.cpp74
-rw-r--r--src/audio/sampman.h3031
-rw-r--r--src/audio/sampman_miles.cpp754
-rw-r--r--src/audio/sampman_null.cpp23
-rw-r--r--src/audio/sampman_oal.cpp204
-rw-r--r--src/audio/soundlist.h291
-rw-r--r--src/buildings/Building.cpp22
-rw-r--r--src/buildings/Building.h3
-rw-r--r--src/buildings/Treadable.h5
-rw-r--r--src/collision/ColBox.h12
-rw-r--r--src/collision/ColModel.cpp20
-rw-r--r--src/collision/ColModel.h12
-rw-r--r--src/collision/ColSphere.cpp16
-rw-r--r--src/collision/ColSphere.h12
-rw-r--r--src/collision/ColStore.cpp255
-rw-r--r--src/collision/ColStore.h43
-rw-r--r--src/collision/ColTriangle.cpp9
-rw-r--r--src/collision/ColTriangle.h11
-rw-r--r--src/collision/Collision.cpp413
-rw-r--r--src/collision/Collision.h20
-rw-r--r--src/collision/TempColModels.cpp9
-rw-r--r--src/collision/TempColModels.h1
-rw-r--r--src/control/AutoPilot.cpp8
-rw-r--r--src/control/AutoPilot.h14
-rw-r--r--src/control/Bridge.cpp14
-rw-r--r--src/control/CarAI.cpp268
-rw-r--r--src/control/CarAI.h5
-rw-r--r--src/control/CarCtrl.cpp1290
-rw-r--r--src/control/CarCtrl.h69
-rw-r--r--src/control/Curves.cpp28
-rw-r--r--src/control/Darkel.cpp199
-rw-r--r--src/control/Darkel.h4
-rw-r--r--src/control/GameLogic.cpp346
-rw-r--r--src/control/GameLogic.h38
-rw-r--r--src/control/Garages.cpp1201
-rw-r--r--src/control/Garages.h100
-rw-r--r--src/control/OnscreenTimer.cpp166
-rw-r--r--src/control/OnscreenTimer.h36
-rw-r--r--src/control/PathFind.cpp1117
-rw-r--r--src/control/PathFind.h196
-rw-r--r--src/control/Phones.cpp125
-rw-r--r--src/control/Phones.h10
-rw-r--r--src/control/Pickups.cpp1436
-rw-r--r--src/control/Pickups.h50
-rw-r--r--src/control/Record.cpp430
-rw-r--r--src/control/Remote.cpp19
-rw-r--r--src/control/Remote.h2
-rw-r--r--src/control/Replay.cpp540
-rw-r--r--src/control/Replay.h126
-rw-r--r--src/control/Restart.cpp9
-rw-r--r--src/control/RoadBlocks.cpp263
-rw-r--r--src/control/RoadBlocks.h18
-rw-r--r--src/control/SceneEdit.cpp10
-rw-r--r--src/control/Script.cpp657
-rw-r--r--src/control/Script.h123
-rw-r--r--src/control/Script2.cpp356
-rw-r--r--src/control/Script3.cpp255
-rw-r--r--src/control/Script4.cpp406
-rw-r--r--src/control/Script5.cpp318
-rw-r--r--src/control/Script6.cpp648
-rw-r--r--src/control/Script7.cpp1404
-rw-r--r--src/control/Script8.cpp618
-rw-r--r--src/control/ScriptCommands.h334
-rw-r--r--src/control/ScriptDebug.cpp440
-rw-r--r--src/control/SetPieces.cpp325
-rw-r--r--src/control/SetPieces.h48
-rw-r--r--src/control/TrafficLights.cpp486
-rw-r--r--src/control/TrafficLights.h7
-rw-r--r--src/core/AnimViewer.cpp65
-rw-r--r--src/core/Cam.cpp3352
-rw-r--r--src/core/Camera.cpp1877
-rw-r--r--src/core/Camera.h112
-rw-r--r--src/core/Clock.cpp21
-rw-r--r--src/core/ControllerConfig.cpp248
-rw-r--r--src/core/ControllerConfig.h3
-rw-r--r--src/core/Crime.h3
-rw-r--r--src/core/Debug.cpp6
-rw-r--r--src/core/EventList.cpp26
-rw-r--r--src/core/EventList.h7
-rw-r--r--src/core/FileLoader.cpp1004
-rw-r--r--src/core/FileLoader.h19
-rw-r--r--src/core/Fire.cpp126
-rw-r--r--src/core/Fire.h12
-rw-r--r--src/core/Frontend.cpp8495
-rw-r--r--src/core/Frontend.h839
-rw-r--r--src/core/Frontend_PS2.cpp31
-rw-r--r--src/core/Frontend_PS2.h6
-rw-r--r--src/core/Game.cpp720
-rw-r--r--src/core/Game.h46
-rw-r--r--src/core/General.h14
-rw-r--r--src/core/IniFile.cpp5
-rw-r--r--src/core/IniFile.h1
-rw-r--r--src/core/MenuScreens.cpp628
-rw-r--r--src/core/MenuScreensCustom.cpp789
-rw-r--r--src/core/Pad.cpp1262
-rw-r--r--src/core/Pad.h33
-rw-r--r--src/core/Placeable.cpp4
-rw-r--r--src/core/Placeable.h5
-rw-r--r--src/core/PlayerInfo.cpp360
-rw-r--r--src/core/PlayerInfo.h45
-rw-r--r--src/core/Pools.cpp104
-rw-r--r--src/core/Pools.h7
-rw-r--r--src/core/Radar.cpp1097
-rw-r--r--src/core/Radar.h189
-rw-r--r--src/core/References.cpp17
-rw-r--r--src/core/Ropes.cpp176
-rw-r--r--src/core/Ropes.h31
-rw-r--r--src/core/Stats.cpp1289
-rw-r--r--src/core/Stats.h108
-rw-r--r--src/core/Streaming.cpp1373
-rw-r--r--src/core/Streaming.h40
-rw-r--r--src/core/SurfaceTable.cpp15
-rw-r--r--src/core/SurfaceTable.h29
-rw-r--r--src/core/Timer.cpp42
-rw-r--r--src/core/User.cpp16
-rw-r--r--src/core/User.h1
-rw-r--r--src/core/Wanted.cpp146
-rw-r--r--src/core/Wanted.h7
-rw-r--r--src/core/World.cpp360
-rw-r--r--src/core/World.h49
-rw-r--r--src/core/ZoneCull.cpp1479
-rw-r--r--src/core/ZoneCull.h100
-rw-r--r--src/core/Zones.cpp807
-rw-r--r--src/core/Zones.h54
-rw-r--r--src/core/common.h11
-rw-r--r--src/core/config.h250
-rw-r--r--src/core/main.cpp866
-rw-r--r--src/core/re3.cpp272
-rw-r--r--src/core/templates.h17
-rw-r--r--src/core/timebars.cpp2
-rw-r--r--src/entities/Dummy.cpp15
-rw-r--r--src/entities/Dummy.h3
-rw-r--r--src/entities/Entity.cpp302
-rw-r--r--src/entities/Entity.h35
-rw-r--r--src/entities/Physical.cpp543
-rw-r--r--src/entities/Physical.h24
-rw-r--r--src/extras/custompipes.cpp2
-rw-r--r--src/extras/custompipes_d3d9.cpp20
-rw-r--r--src/extras/custompipes_gl.cpp12
-rw-r--r--src/extras/debugmenu.h40
-rw-r--r--src/extras/frontendoption.cpp54
-rw-r--r--src/extras/frontendoption.h19
-rw-r--r--src/extras/postfx.cpp198
-rw-r--r--src/extras/postfx.h12
-rw-r--r--src/extras/shaders/colourfilterVC.frag (renamed from src/extras/shaders/colourfilterIII.frag)5
-rw-r--r--src/extras/shaders/colourfilterVC_PS.hlsl (renamed from src/extras/shaders/colourfilterIII_PS.hlsl)10
-rw-r--r--src/extras/shaders/neoWorldVC.frag (renamed from src/extras/shaders/neoWorldIII.frag)3
-rw-r--r--src/extras/shaders/neoWorldVC_PS.hlsl (renamed from src/extras/shaders/neoWorldIII_PS.hlsl)2
-rw-r--r--src/extras/shaders/obj/colourfilterIII_PS.csobin452 -> 0 bytes
-rw-r--r--src/extras/shaders/obj/colourfilterIII_PS.inc40
-rw-r--r--src/extras/shaders/obj/colourfilterVC_PS.csobin0 -> 648 bytes
-rw-r--r--src/extras/shaders/obj/colourfilterVC_PS.inc56
-rw-r--r--src/extras/shaders/obj/colourfilterVC_frag.inc (renamed from src/extras/shaders/obj/colourfilterIII_frag.inc)7
-rw-r--r--src/extras/shaders/obj/neoWorldIII_PS.csobin528 -> 0 bytes
-rw-r--r--src/extras/shaders/obj/neoWorldVC_PS.csobin0 -> 524 bytes
-rw-r--r--src/extras/shaders/obj/neoWorldVC_PS.inc (renamed from src/extras/shaders/obj/neoWorldIII_PS.inc)30
-rw-r--r--src/extras/shaders/obj/neoWorldVC_frag.inc (renamed from src/extras/shaders/obj/neoWorldIII_frag.inc)5
-rw-r--r--src/fakerw/fake.cpp1
-rw-r--r--src/math/Matrix.cpp39
-rw-r--r--src/math/Matrix.h31
-rw-r--r--src/math/Vector.h4
-rw-r--r--src/math/Vector2D.h11
-rw-r--r--src/modelinfo/BaseModelInfo.cpp16
-rw-r--r--src/modelinfo/BaseModelInfo.h48
-rw-r--r--src/modelinfo/ClumpModelInfo.cpp61
-rw-r--r--src/modelinfo/ClumpModelInfo.h14
-rw-r--r--src/modelinfo/MloModelInfo.cpp4
-rw-r--r--src/modelinfo/ModelIndices.h728
-rw-r--r--src/modelinfo/ModelInfo.cpp102
-rw-r--r--src/modelinfo/ModelInfo.h19
-rw-r--r--src/modelinfo/PedModelInfo.cpp290
-rw-r--r--src/modelinfo/PedModelInfo.h43
-rw-r--r--src/modelinfo/SimpleModelInfo.cpp59
-rw-r--r--src/modelinfo/SimpleModelInfo.h32
-rw-r--r--src/modelinfo/TimeModelInfo.h3
-rw-r--r--src/modelinfo/VehicleModelInfo.cpp300
-rw-r--r--src/modelinfo/VehicleModelInfo.h51
-rw-r--r--src/modelinfo/WeaponModelInfo.cpp53
-rw-r--r--src/modelinfo/WeaponModelInfo.h23
-rw-r--r--src/modelinfo/XtraCompsModelInfo.h13
-rw-r--r--src/objects/CutsceneHead.cpp230
-rw-r--r--src/objects/CutsceneHead.h28
-rw-r--r--src/objects/CutsceneObject.cpp153
-rw-r--r--src/objects/CutsceneObject.h25
-rw-r--r--src/objects/DummyObject.cpp1
-rw-r--r--src/objects/DummyObject.h2
-rw-r--r--src/objects/Object.cpp733
-rw-r--r--src/objects/Object.h46
-rw-r--r--src/objects/ObjectData.cpp71
-rw-r--r--src/objects/ParticleObject.cpp882
-rw-r--r--src/objects/ParticleObject.h22
-rw-r--r--src/objects/Stinger.cpp259
-rw-r--r--src/objects/Stinger.h40
-rw-r--r--src/peds/CivilianPed.cpp381
-rw-r--r--src/peds/CivilianPed.h16
-rw-r--r--src/peds/CopPed.cpp404
-rw-r--r--src/peds/CopPed.h28
-rw-r--r--src/peds/DummyPed.h2
-rw-r--r--src/peds/EmergencyPed.cpp45
-rw-r--r--src/peds/EmergencyPed.h4
-rw-r--r--src/peds/Gangs.cpp69
-rw-r--r--src/peds/Gangs.h31
-rw-r--r--src/peds/Ped.cpp4871
-rw-r--r--src/peds/Ped.h530
-rw-r--r--src/peds/PedAI.cpp4498
-rw-r--r--src/peds/PedAttractor.cpp802
-rw-r--r--src/peds/PedAttractor.h196
-rw-r--r--src/peds/PedChat.cpp181
-rw-r--r--src/peds/PedDebug.cpp61
-rw-r--r--src/peds/PedFight.cpp2855
-rw-r--r--src/peds/PedIK.cpp489
-rw-r--r--src/peds/PedIK.h2
-rw-r--r--src/peds/PedPlacement.cpp15
-rw-r--r--src/peds/PedPlacement.h4
-rw-r--r--src/peds/PedType.h11
-rw-r--r--src/peds/PlayerPed.cpp1136
-rw-r--r--src/peds/PlayerPed.h59
-rw-r--r--src/peds/Population.cpp1333
-rw-r--r--src/peds/Population.h51
-rw-r--r--src/renderer/2dEffect.h16
-rw-r--r--src/renderer/Clouds.cpp229
-rw-r--r--src/renderer/Clouds.h2
-rw-r--r--src/renderer/Console.cpp2
-rw-r--r--src/renderer/Coronas.cpp474
-rw-r--r--src/renderer/Coronas.h30
-rw-r--r--src/renderer/Credits.cpp1184
-rw-r--r--src/renderer/CutsceneShadow.cpp269
-rw-r--r--src/renderer/CutsceneShadow.h52
-rw-r--r--src/renderer/Draw.cpp34
-rw-r--r--src/renderer/Draw.h11
-rw-r--r--src/renderer/Fluff.cpp1536
-rw-r--r--src/renderer/Fluff.h181
-rw-r--r--src/renderer/Font.cpp1324
-rw-r--r--src/renderer/Font.h77
-rw-r--r--src/renderer/Glass.cpp478
-rw-r--r--src/renderer/Glass.h9
-rw-r--r--src/renderer/Hud.cpp2206
-rw-r--r--src/renderer/Hud.h148
-rw-r--r--src/renderer/MBlur.cpp536
-rw-r--r--src/renderer/MBlur.h22
-rw-r--r--src/renderer/Occlusion.cpp530
-rw-r--r--src/renderer/Occlusion.h62
-rw-r--r--src/renderer/Particle.cpp1628
-rw-r--r--src/renderer/Particle.h40
-rw-r--r--src/renderer/ParticleMgr.cpp12
-rw-r--r--src/renderer/ParticleMgr.h26
-rw-r--r--src/renderer/ParticleType.h19
-rw-r--r--src/renderer/PlayerSkin.cpp14
-rw-r--r--src/renderer/PointLights.cpp57
-rw-r--r--src/renderer/PointLights.h5
-rw-r--r--src/renderer/RenderBuffer.cpp2
-rw-r--r--src/renderer/RenderBuffer.h11
-rw-r--r--src/renderer/Renderer.cpp764
-rw-r--r--src/renderer/Renderer.h20
-rw-r--r--src/renderer/Rubbish.cpp65
-rw-r--r--src/renderer/Rubbish.h2
-rw-r--r--src/renderer/ShadowCamera.cpp549
-rw-r--r--src/renderer/ShadowCamera.h54
-rw-r--r--src/renderer/Shadows.cpp1273
-rw-r--r--src/renderer/Shadows.h108
-rw-r--r--src/renderer/Skidmarks.cpp99
-rw-r--r--src/renderer/Skidmarks.h25
-rw-r--r--src/renderer/SpecialFX.cpp541
-rw-r--r--src/renderer/SpecialFX.h45
-rw-r--r--src/renderer/Sprite.cpp14
-rw-r--r--src/renderer/Sprite.h3
-rw-r--r--src/renderer/Sprite2d.cpp386
-rw-r--r--src/renderer/Sprite2d.h21
-rw-r--r--src/renderer/Timecycle.cpp373
-rw-r--r--src/renderer/Timecycle.h133
-rw-r--r--src/renderer/VarConsole.cpp786
-rw-r--r--src/renderer/VarConsole.h92
-rw-r--r--src/renderer/WaterCannon.cpp26
-rw-r--r--src/renderer/WaterCreatures.cpp275
-rw-r--r--src/renderer/WaterCreatures.h49
-rw-r--r--src/renderer/WaterLevel.cpp2951
-rw-r--r--src/renderer/WaterLevel.h115
-rw-r--r--src/renderer/Weather.cpp496
-rw-r--r--src/renderer/Weather.h38
-rw-r--r--src/renderer/WindModifiers.cpp52
-rw-r--r--src/renderer/WindModifiers.h11
-rw-r--r--src/rw/ClumpRead.cpp1
-rw-r--r--src/rw/Lights.cpp52
-rw-r--r--src/rw/Lights.h1
-rw-r--r--src/rw/MemoryHeap.cpp4
-rw-r--r--src/rw/MemoryHeap.h24
-rw-r--r--src/rw/RwHelper.cpp183
-rw-r--r--src/rw/RwHelper.h11
-rw-r--r--src/rw/TexRead.cpp42
-rw-r--r--src/rw/TxdStore.cpp2
-rw-r--r--src/rw/VisibilityPlugins.cpp525
-rw-r--r--src/rw/VisibilityPlugins.h17
-rw-r--r--src/save/GenericGameStorage.cpp497
-rw-r--r--src/save/GenericGameStorage.h11
-rw-r--r--src/save/PCSave.cpp18
-rw-r--r--src/save/PCSave.h2
-rw-r--r--src/save/SaveBuf.h74
-rw-r--r--src/skel/crossplatform.cpp176
-rw-r--r--src/skel/crossplatform.h29
-rw-r--r--src/skel/events.cpp2
-rw-r--r--src/skel/glfw/glfw.cpp186
-rw-r--r--src/skel/platform.h4
-rw-r--r--src/skel/skeleton.cpp8
-rw-r--r--src/skel/win/gta3.icobin161654 -> 0 bytes
-rw-r--r--src/skel/win/gtavc.icobin0 -> 81817 bytes
-rw-r--r--src/skel/win/resource.h2
-rw-r--r--src/skel/win/win.cpp120
-rw-r--r--src/skel/win/win.rc2
-rw-r--r--src/text/Messages.cpp8
-rw-r--r--src/text/Text.cpp293
-rw-r--r--src/text/Text.h41
-rw-r--r--src/vehicles/Automobile.cpp2494
-rw-r--r--src/vehicles/Automobile.h97
-rw-r--r--src/vehicles/Bike.cpp2962
-rw-r--r--src/vehicles/Bike.h153
-rw-r--r--src/vehicles/Boat.cpp1029
-rw-r--r--src/vehicles/Boat.h34
-rw-r--r--src/vehicles/CarGen.cpp172
-rw-r--r--src/vehicles/CarGen.h7
-rw-r--r--src/vehicles/Cranes.cpp95
-rw-r--r--src/vehicles/Cranes.h1
-rw-r--r--src/vehicles/DamageManager.cpp20
-rw-r--r--src/vehicles/Floater.cpp171
-rw-r--r--src/vehicles/Floater.h2
-rw-r--r--src/vehicles/HandlingMgr.cpp324
-rw-r--r--src/vehicles/HandlingMgr.h163
-rw-r--r--src/vehicles/Heli.cpp209
-rw-r--r--src/vehicles/Heli.h12
-rw-r--r--src/vehicles/Plane.cpp242
-rw-r--r--src/vehicles/Plane.h16
-rw-r--r--src/vehicles/Train.cpp28
-rw-r--r--src/vehicles/Train.h2
-rw-r--r--src/vehicles/Transmission.cpp76
-rw-r--r--src/vehicles/Vehicle.cpp1691
-rw-r--r--src/vehicles/Vehicle.h224
-rw-r--r--src/weapons/BulletInfo.cpp190
-rw-r--r--src/weapons/Explosion.cpp191
-rw-r--r--src/weapons/Explosion.h31
-rw-r--r--src/weapons/ProjectileInfo.cpp261
-rw-r--r--src/weapons/ProjectileInfo.h1
-rw-r--r--src/weapons/ShotInfo.cpp2
-rw-r--r--src/weapons/Weapon.cpp1933
-rw-r--r--src/weapons/Weapon.h30
-rw-r--r--src/weapons/WeaponEffects.cpp73
-rw-r--r--src/weapons/WeaponInfo.cpp168
-rw-r--r--src/weapons/WeaponInfo.h28
-rw-r--r--src/weapons/WeaponType.h57
383 files changed, 93774 insertions, 46349 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 28090d7e..7afdfa4d 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -54,9 +54,13 @@ target_compile_definitions(${EXECUTABLE} PRIVATE USE_OUR_VERSIONING)
if(${PROJECT}_AUDIO STREQUAL "OAL")
find_package(OpenAL REQUIRED)
- target_include_directories(${EXECUTABLE} PRIVATE ${OPENAL_INCLUDE_DIR})
- target_link_libraries(${EXECUTABLE} PRIVATE ${OPENAL_LIBRARY})
- target_compile_definitions(${EXECUTABLE} PRIVATE ${OPENAL_DEFINITIONS})
+ if(TARGET OpenAL::OpenAL)
+ target_link_libraries(${EXECUTABLE} PRIVATE OpenAL::OpenAL)
+ else()
+ target_include_directories(${EXECUTABLE} PRIVATE ${OPENAL_INCLUDE_DIR})
+ target_link_libraries(${EXECUTABLE} PRIVATE ${OPENAL_LIBRARY})
+ target_compile_definitions(${EXECUTABLE} PRIVATE ${OPENAL_DEFINITIONS})
+ endif()
target_compile_definitions(${EXECUTABLE} PRIVATE AUDIO_OAL)
elseif(${PROJECT}_AUDIO STREQUAL "MSS")
find_package(MilesSDK REQUIRED)
@@ -120,13 +124,19 @@ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
)
endif()
+if(NINTENDO_SWITCH)
+ set(${PROJECT}_C_CXX_EXTENSIONS ON)
+else()
+ set(${PROJECT}_C_CXX_EXTENSIONS OFF)
+endif()
+
set_target_properties(${EXECUTABLE}
PROPERTIES
C_STANDARD 11
- C_EXTENSIONS OFF
+ C_EXTENSIONS ${${PROJECT}_C_CXX_EXTENSIONS}
C_STANDARD_REQUIRED ON
CXX_STANDARD 11
- CXX_EXTENSIONS OFF
+ CXX_EXTENSIONS ${${PROJECT}_C_CXX_EXTENSIONS}
CXX_STANDARD_REQUIRED ON
)
@@ -140,3 +150,5 @@ if(${PROJECT}_INSTALL)
install(FILES $<TARGET_PDB_FILE:${EXECUTABLE}> DESTINATION "." OPTIONAL)
endif()
endif()
+
+reVC_platform_target(${EXECUTABLE} INSTALL)
diff --git a/src/animation/AnimBlendAssocGroup.cpp b/src/animation/AnimBlendAssocGroup.cpp
index 295d6be3..935e7fd6 100644
--- a/src/animation/AnimBlendAssocGroup.cpp
+++ b/src/animation/AnimBlendAssocGroup.cpp
@@ -12,6 +12,7 @@
#include "General.h"
#include "RwHelper.h"
+#include "ModelIndices.h"
#include "ModelInfo.h"
#include "AnimManager.h"
#include "RpAnimBlend.h"
@@ -20,8 +21,11 @@
CAnimBlendAssocGroup::CAnimBlendAssocGroup(void)
{
+ animBlock = nil;
assocList = nil;
numAssociations = 0;
+ firstAnimId = 0;
+ groupId = -1;
}
CAnimBlendAssocGroup::~CAnimBlendAssocGroup(void)
@@ -42,7 +46,7 @@ CAnimBlendAssocGroup::DestroyAssociations(void)
CAnimBlendAssociation*
CAnimBlendAssocGroup::GetAnimation(uint32 id)
{
- return &assocList[id];
+ return &assocList[id - firstAnimId];
}
CAnimBlendAssociation*
@@ -52,6 +56,7 @@ CAnimBlendAssocGroup::GetAnimation(const char *name)
for(i = 0; i < numAssociations; i++)
if(!CGeneral::faststricmp(assocList[i].hierarchy->name, name))
return &assocList[i];
+ debug("\n\nCan't find the fucking animation %s\n\n\n", name);
return nil;
}
@@ -101,7 +106,7 @@ strcmpIgnoringDigits(const char *s1, const char *s2)
c2 = __ascii_toupper(c2);
#endif
- if(c1 != c2)
+ if(c1 && c2 && c1 != c2)
return false;
}
}
@@ -111,6 +116,15 @@ GetModelFromName(const char *name)
{
int i;
CBaseModelInfo *mi;
+ char playername[32];
+
+ if(strncasecmp(name, "CSplay", 6) == 0 &&
+ strncasecmp(CModelInfo::GetModelInfo(MI_PLAYER)->GetModelName(), "ig", 2) == 0){
+ strcpy(playername, CModelInfo::GetModelInfo(MI_PLAYER)->GetModelName());
+ playername[0] = 'C';
+ playername[1] = 'S';
+ name = playername;
+ }
for(i = 0; i < MODELINFOSIZE; i++){
mi = CModelInfo::GetModelInfo(i);
@@ -127,8 +141,7 @@ CAnimBlendAssocGroup::CreateAssociations(const char *name)
int i;
CAnimBlock *animBlock;
- if(assocList)
- DestroyAssociations();
+ DestroyAssociations();
animBlock = CAnimManager::GetAnimationBlock(name);
assocList = new CAnimBlendAssociation[animBlock->numAnims];
@@ -137,17 +150,18 @@ CAnimBlendAssocGroup::CreateAssociations(const char *name)
for(i = 0; i < animBlock->numAnims; i++){
CAnimBlendHierarchy *anim = CAnimManager::GetAnimation(animBlock->firstIndex + i);
CBaseModelInfo *model = GetModelFromName(anim->name);
- assert(model);
- printf("Associated anim %s with model %s\n", anim->name, model->GetModelName());
- RpClump *clump = (RpClump*)model->CreateInstance();
-#ifdef PED_SKIN
- if(IsClumpSkinned(clump))
- RpClumpForAllAtomics(clump, AtomicRemoveAnimFromSkinCB, nil);
-#endif
- RpAnimBlendClumpInit(clump);
- assocList[i].Init(clump, anim);
- RpClumpDestroy(clump);
- assocList[i].animId = i;
+ if(model){
+ debug("Associated anim %s with model %s\n", anim->name, model->GetModelName());
+ RpClump *clump = (RpClump*)model->CreateInstance();
+ RpAnimBlendClumpInit(clump);
+ assocList[i].Init(clump, anim);
+ if(IsClumpSkinned(clump))
+ RpClumpForAllAtomics(clump, AtomicRemoveAnimFromSkinCB, nil);
+ RpClumpDestroy(clump);
+ assocList[i].animId = firstAnimId + i;
+ assocList[i].groupId = groupId;
+ }else
+ debug("\n\nCANNOT FIND MODELINFO WITH NAME %s\n\n\n", anim->name);
}
numAssociations = animBlock->numAnims;
}
@@ -157,10 +171,8 @@ void
CAnimBlendAssocGroup::CreateAssociations(const char *blockName, RpClump *clump, const char **animNames, int numAssocs)
{
int i;
- CAnimBlock *animBlock;
- if(assocList)
- DestroyAssociations();
+ DestroyAssociations();
animBlock = CAnimManager::GetAnimationBlock(blockName);
assocList = new CAnimBlendAssociation[numAssocs];
@@ -168,7 +180,8 @@ CAnimBlendAssocGroup::CreateAssociations(const char *blockName, RpClump *clump,
numAssociations = 0;
for(i = 0; i < numAssocs; i++){
assocList[i].Init(clump, CAnimManager::GetAnimation(animNames[i], animBlock));
- assocList[i].animId = i;
+ assocList[i].animId = firstAnimId + i;
+ assocList[i].groupId = groupId;
}
numAssociations = numAssocs;
}
diff --git a/src/animation/AnimBlendAssocGroup.h b/src/animation/AnimBlendAssocGroup.h
index aa58b0d3..86f0ca18 100644
--- a/src/animation/AnimBlendAssocGroup.h
+++ b/src/animation/AnimBlendAssocGroup.h
@@ -1,12 +1,16 @@
#pragma once
class CAnimBlendAssociation;
+struct CAnimBlock;
class CAnimBlendAssocGroup
{
public:
+ CAnimBlock *animBlock;
CAnimBlendAssociation *assocList;
int32 numAssociations;
+ int32 firstAnimId;
+ int32 groupId; // id of self in ms_aAnimAssocGroups
CAnimBlendAssocGroup(void);
~CAnimBlendAssocGroup(void);
diff --git a/src/animation/AnimBlendAssociation.cpp b/src/animation/AnimBlendAssociation.cpp
index b03571b0..bb4e7bf4 100644
--- a/src/animation/AnimBlendAssociation.cpp
+++ b/src/animation/AnimBlendAssociation.cpp
@@ -9,6 +9,7 @@
CAnimBlendAssociation::CAnimBlendAssociation(void)
{
+ groupId = -1;
nodes = nil;
blendAmount = 1.0f;
blendDelta = 0.0f;
@@ -54,8 +55,8 @@ CAnimBlendAssociation::AllocateAnimBlendNodeArray(int n)
void
CAnimBlendAssociation::FreeAnimBlendNodeArray(void)
{
- assert(nodes != nil);
- RwFreeAlign(nodes);
+ if(nodes)
+ RwFreeAlign(nodes);
}
void
@@ -75,7 +76,10 @@ CAnimBlendAssociation::Init(RpClump *clump, CAnimBlendHierarchy *hier)
// NB: This is where the order of nodes is defined
for(i = 0; i < hier->numSequences; i++){
CAnimBlendSequence *seq = &hier->sequences[i];
- frame = RpAnimBlendClumpFindFrame(clump, seq->name);
+ if(seq->boneTag == -1)
+ frame = RpAnimBlendClumpFindFrame(clump, seq->name);
+ else
+ frame = RpAnimBlendClumpFindBone(clump, seq->boneTag);
if(frame && seq->numFrames > 0)
nodes[frame - clumpData->frames].sequence = seq;
}
@@ -90,6 +94,7 @@ CAnimBlendAssociation::Init(CAnimBlendAssociation &assoc)
numNodes = assoc.numNodes;
flags = assoc.flags;
animId = assoc.animId;
+ groupId = assoc.groupId;
AllocateAnimBlendNodeArray(numNodes);
for(i = 0; i < numNodes; i++){
nodes[i] = assoc.nodes[i];
@@ -126,12 +131,25 @@ CAnimBlendAssociation::SetCurrentTime(float time)
int i;
for(currentTime = time; currentTime >= hierarchy->totalLength; currentTime -= hierarchy->totalLength)
- if(!IsRepeating())
- return;
+ if (!IsRepeating()) {
+ currentTime = hierarchy->totalLength;
+ break;
+ }
+
CAnimManager::UncompressAnimation(hierarchy);
- for(i = 0; i < numNodes; i++)
- if(nodes[i].sequence)
- nodes[i].FindKeyFrame(currentTime);
+#ifdef ANIM_COMPRESSION
+ // strangely PC has this but android doesn't
+ if(hierarchy->keepCompressed){
+ for(i = 0; i < numNodes; i++)
+ if(nodes[i].sequence)
+ nodes[i].SetupKeyFrameCompressed();
+ }else
+#endif
+ {
+ for(i = 0; i < numNodes; i++)
+ if(nodes[i].sequence)
+ nodes[i].FindKeyFrame(currentTime);
+ }
}
void
@@ -147,13 +165,23 @@ CAnimBlendAssociation::Start(float time)
SetCurrentTime(time);
}
+void
+CAnimBlendAssociation::UpdateTimeStep(float timeDelta, float relSpeed)
+{
+ if(IsRunning())
+ timeStep = (flags & ASSOC_MOVEMENT ? relSpeed*hierarchy->totalLength : speed) * timeDelta;
+}
+
bool
CAnimBlendAssociation::UpdateTime(float timeDelta, float relSpeed)
{
if(!IsRunning())
return true;
+ if(currentTime >= hierarchy->totalLength){
+ flags &= ~ASSOC_RUNNING;
+ return true;
+ }
- timeStep = (flags & ASSOC_MOVEMENT ? relSpeed*hierarchy->totalLength : speed) * timeDelta;
currentTime += timeStep;
if(currentTime >= hierarchy->totalLength){
@@ -163,7 +191,6 @@ CAnimBlendAssociation::UpdateTime(float timeDelta, float relSpeed)
currentTime -= hierarchy->totalLength;
else{
currentTime = hierarchy->totalLength;
- flags &= ~ASSOC_RUNNING;
if(flags & ASSOC_FADEOUTWHENDONE){
flags |= ASSOC_DELETEFADEDOUT;
blendDelta = -4.0f;
diff --git a/src/animation/AnimBlendAssociation.h b/src/animation/AnimBlendAssociation.h
index 45720b6f..dbfcb722 100644
--- a/src/animation/AnimBlendAssociation.h
+++ b/src/animation/AnimBlendAssociation.h
@@ -12,12 +12,13 @@ enum {
ASSOC_PARTIAL = 0x10,
ASSOC_MOVEMENT = 0x20, // ???
ASSOC_HAS_TRANSLATION = 0x40,
- ASSOC_WALK = 0x80, // for CPed::PlayFootSteps(void)
- ASSOC_IDLE = 0x100, // only used by xpress scratch, see CPed::Chat(void)
- ASSOC_NOWALK = 0x200, // see CPed::PlayFootSteps(void)
- ASSOC_BLOCK = 0x400, // unused in assoc description, blocks other anims from being played
- ASSOC_FRONTAL = 0x800, // anims that we fall to front
- ASSOC_HAS_X_TRANSLATION = 0x1000, // for 2d velocity extraction
+ ASSOC_HAS_X_TRANSLATION = 0x80, // for 2d velocity extraction
+ ASSOC_WALK = 0x100, // for CPed::PlayFootSteps(void)
+ ASSOC_IDLE = 0x200, // only xpress scratch has it by default, but game adds it to player's idle animations later
+ ASSOC_NOWALK = 0x400, // see CPed::PlayFootSteps(void)
+ ASSOC_BLOCK = 0x800, // unused in assoc description, blocks other anims from being played
+ ASSOC_FRONTAL = 0x1000, // anims that we fall to front
+ ASSOC_DRIVING = 0x2000, // new in VC
};
// Anim hierarchy associated with a clump
@@ -35,7 +36,8 @@ public:
CAnimBlendLink link;
- int32 numNodes; // taken from CAnimBlendClumpData::numFrames
+ int16 numNodes; // taken from CAnimBlendClumpData::numFrames
+ int16 groupId; // ID of CAnimBlendAssocGroup this is in
// NB: Order of these depends on order of nodes in Clump this was built from
CAnimBlendNode *nodes;
CAnimBlendHierarchy *hierarchy;
@@ -44,8 +46,8 @@ public:
float currentTime;
float speed;
float timeStep;
- int32 animId;
- int32 flags;
+ int16 animId;
+ int16 flags;
int32 callbackType;
void (*callback)(CAnimBlendAssociation*, void*);
void *callbackArg;
@@ -76,16 +78,16 @@ public:
void SetCurrentTime(float time);
void SyncAnimation(CAnimBlendAssociation *other);
void Start(float time);
+ void UpdateTimeStep(float timeDelta, float relSpeed);
bool UpdateTime(float timeDelta, float relSpeed);
bool UpdateBlend(float timeDelta);
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));
}
};
-
-VALIDATE_SIZE(CAnimBlendAssociation, 0x40);
diff --git a/src/animation/AnimBlendClumpData.h b/src/animation/AnimBlendClumpData.h
index acfd006f..bb711b28 100644
--- a/src/animation/AnimBlendClumpData.h
+++ b/src/animation/AnimBlendClumpData.h
@@ -10,23 +10,19 @@ struct AnimBlendFrameData
IGNORE_TRANSLATION = 4,
VELOCITY_EXTRACTION = 8,
VELOCITY_EXTRACTION_3D = 0x10,
+ UPDATE_KEYFRAMES = 0x20,
+ COMPRESSED = 0x40
};
uint8 flag;
RwV3d resetPos;
-#ifdef PED_SKIN
union {
RwFrame *frame;
RpHAnimStdInterpFrame *hanimFrame;
};
int32 nodeID;
-#else
- RwFrame *frame;
-#endif
};
-#ifndef PED_SKIN
-VALIDATE_SIZE(AnimBlendFrameData, 0x14);
-#endif
+VALIDATE_SIZE(AnimBlendFrameData, 0x18);
class CAnimBlendClumpData
@@ -34,9 +30,6 @@ class CAnimBlendClumpData
public:
CAnimBlendLink link;
int32 numFrames;
-#ifdef PED_SKIN
- int32 modelNumber; // doesn't seem to be used
-#endif
union {
CVector2D *velocity2d;
CVector *velocity3d;
@@ -47,11 +40,6 @@ public:
CAnimBlendClumpData(void);
~CAnimBlendClumpData(void);
void SetNumberOfFrames(int n);
-#ifdef PED_SKIN
void SetNumberOfBones(int n) { SetNumberOfFrames(n); }
-#endif
void ForAllFrames(void (*cb)(AnimBlendFrameData*, void*), void *arg);
};
-#ifndef PED_SKIN
-VALIDATE_SIZE(CAnimBlendClumpData, 0x14);
-#endif
diff --git a/src/animation/AnimBlendHierarchy.cpp b/src/animation/AnimBlendHierarchy.cpp
index ea669999..bfa39ef9 100644
--- a/src/animation/AnimBlendHierarchy.cpp
+++ b/src/animation/AnimBlendHierarchy.cpp
@@ -2,6 +2,7 @@
#include "AnimBlendSequence.h"
#include "AnimBlendHierarchy.h"
+#include "AnimManager.h"
CAnimBlendHierarchy::CAnimBlendHierarchy(void)
{
@@ -15,9 +16,10 @@ CAnimBlendHierarchy::CAnimBlendHierarchy(void)
void
CAnimBlendHierarchy::Shutdown(void)
{
+ CAnimManager::RemoveFromUncompressedCache(this);
RemoveAnimSequences();
+ totalLength = 0.0f;
compressed = 0;
- linkPtr = nil;
}
void
@@ -30,13 +32,43 @@ void
CAnimBlendHierarchy::CalcTotalTime(void)
{
int i, j;
+
totalLength = 0.0f;
for(i = 0; i < numSequences; i++){
- float seqTime = 0.0f;
- for(j = 0; j < sequences[i].numFrames; j++)
- seqTime += sequences[i].GetKeyFrame(j)->deltaTime;
- totalLength = Max(totalLength, seqTime);
+#ifdef FIX_BUGS
+ if(sequences[i].numFrames == 0)
+ continue;
+#endif
+
+ totalLength = Max(totalLength, sequences[i].GetKeyFrame(sequences[i].numFrames-1)->deltaTime);
+ for(j = sequences[i].numFrames-1; j >= 1; j--){
+ KeyFrame *kf1 = sequences[i].GetKeyFrame(j);
+ KeyFrame *kf2 = sequences[i].GetKeyFrame(j-1);
+ kf1->deltaTime -= kf2->deltaTime;
+ }
+ }
+}
+
+void
+CAnimBlendHierarchy::CalcTotalTimeCompressed(void)
+{
+ int i, j;
+
+ totalLength = 0.0f;
+
+ for(i = 0; i < numSequences; i++){
+#ifdef FIX_BUGS
+ if(sequences[i].numFrames == 0)
+ continue;
+#endif
+
+ totalLength = Max(totalLength, sequences[i].GetKeyFrameCompressed(sequences[i].numFrames-1)->GetDeltaTime());
+ for(j = sequences[i].numFrames-1; j >= 1; j--){
+ KeyFrameCompressed *kf1 = sequences[i].GetKeyFrameCompressed(j);
+ KeyFrameCompressed *kf2 = sequences[i].GetKeyFrameCompressed(j-1);
+ kf1->deltaTime -= kf2->deltaTime;
+ }
}
}
@@ -53,6 +85,7 @@ void
CAnimBlendHierarchy::RemoveAnimSequences(void)
{
delete[] sequences;
+ sequences = nil;
numSequences = 0;
}
@@ -65,9 +98,11 @@ CAnimBlendHierarchy::Uncompress(void)
for(i = 0; i < numSequences; i++)
sequences[i].Uncompress();
#endif
- if(totalLength == 0.0f)
- CalcTotalTime();
compressed = 0;
+ if(totalLength == 0.0f){
+ RemoveQuaternionFlips();
+ CalcTotalTime();
+ }
}
void
diff --git a/src/animation/AnimBlendHierarchy.h b/src/animation/AnimBlendHierarchy.h
index 40d2731b..4838c4f8 100644
--- a/src/animation/AnimBlendHierarchy.h
+++ b/src/animation/AnimBlendHierarchy.h
@@ -15,7 +15,8 @@ public:
char name[24];
CAnimBlendSequence *sequences;
int16 numSequences;
- int16 compressed;
+ bool compressed;
+ bool keepCompressed;
float totalLength;
CLink<CAnimBlendHierarchy*> *linkPtr;
@@ -23,11 +24,13 @@ public:
void Shutdown(void);
void SetName(char *name);
void CalcTotalTime(void);
+ void CalcTotalTimeCompressed(void);
void RemoveQuaternionFlips(void);
void RemoveAnimSequences(void);
void Uncompress(void);
void RemoveUncompressedData(void);
void MoveMemory(bool onlyone = false);
+ bool IsCompressed() { return !!compressed; };
};
VALIDATE_SIZE(CAnimBlendHierarchy, 0x28); \ No newline at end of file
diff --git a/src/animation/AnimBlendNode.cpp b/src/animation/AnimBlendNode.cpp
index df6cd1d5..6352c11b 100644
--- a/src/animation/AnimBlendNode.cpp
+++ b/src/animation/AnimBlendNode.cpp
@@ -46,6 +46,44 @@ CAnimBlendNode::Update(CVector &trans, CQuaternion &rot, float weight)
}
bool
+CAnimBlendNode::UpdateCompressed(CVector &trans, CQuaternion &rot, float weight)
+{
+ bool looped = false;
+
+ trans = CVector(0.0f, 0.0f, 0.0f);
+ rot = CQuaternion(0.0f, 0.0f, 0.0f, 0.0f);
+
+ if(association->IsRunning()){
+ remainingTime -= association->timeStep;
+ if(remainingTime <= 0.0f)
+ looped = NextKeyFrameCompressed();
+ }
+
+ float blend = association->GetBlendAmount(weight);
+ if(blend > 0.0f){
+ KeyFrameTransCompressed *kfA = (KeyFrameTransCompressed*)sequence->GetKeyFrameCompressed(frameA);
+ KeyFrameTransCompressed *kfB = (KeyFrameTransCompressed*)sequence->GetKeyFrameCompressed(frameB);
+ float t = kfA->deltaTime == 0 ? 0.0f : (kfA->GetDeltaTime() - remainingTime)/kfA->GetDeltaTime();
+ if(sequence->type & CAnimBlendSequence::KF_TRANS){
+ CVector transA, transB;
+ kfA->GetTranslation(&transA);
+ kfB->GetTranslation(&transB);
+ trans = transB + t*(transA - transB);
+ trans *= blend;
+ }
+ if(sequence->type & CAnimBlendSequence::KF_ROT){
+ CQuaternion rotA, rotB;
+ kfA->GetRotation(&rotA);
+ kfB->GetRotation(&rotB);
+ rot.Slerp(rotB, rotA, theta, invSin, t);
+ rot *= blend;
+ }
+ }
+
+ return looped;
+}
+
+bool
CAnimBlendNode::NextKeyFrame(void)
{
bool looped;
@@ -82,6 +120,43 @@ CAnimBlendNode::NextKeyFrame(void)
return looped;
}
+bool
+CAnimBlendNode::NextKeyFrameCompressed(void)
+{
+ bool looped;
+
+ if(sequence->numFrames <= 1)
+ return false;
+
+ looped = false;
+ frameB = frameA;
+
+ // Advance as long as we have to
+ while(remainingTime <= 0.0f){
+ frameA++;
+
+ if(frameA >= sequence->numFrames){
+ // reached end of animation
+ if(!association->IsRepeating()){
+ frameA--;
+ remainingTime = 0.0f;
+ return false;
+ }
+ looped = true;
+ frameA = 0;
+ }
+
+ remainingTime += sequence->GetKeyFrameCompressed(frameA)->GetDeltaTime();
+ }
+
+ frameB = frameA - 1;
+ if(frameB < 0)
+ frameB += sequence->numFrames;
+
+ CalcDeltasCompressed();
+ return looped;
+}
+
// Set animation to time t
bool
CAnimBlendNode::FindKeyFrame(float t)
@@ -92,20 +167,22 @@ CAnimBlendNode::FindKeyFrame(float t)
frameA = 0;
frameB = frameA;
- if(sequence->numFrames >= 2){
- frameA++;
-
+ if(sequence->numFrames == 1){
+ remainingTime = 0.0f;
+ }else{
// advance until t is between frameB and frameA
- while(t > sequence->GetKeyFrame(frameA)->deltaTime){
+ while (t > sequence->GetKeyFrame(++frameA)->deltaTime) {
t -= sequence->GetKeyFrame(frameA)->deltaTime;
- frameB = frameA++;
- if(frameA >= sequence->numFrames){
+ if (frameA + 1 >= sequence->numFrames) {
// reached end of animation
- if(!association->IsRepeating())
+ if (!association->IsRepeating()) {
+ CalcDeltas();
+ remainingTime = 0.0f;
return false;
+ }
frameA = 0;
- frameB = 0;
}
+ frameB = frameA;
}
remainingTime = sequence->GetKeyFrame(frameA)->deltaTime - t;
@@ -115,6 +192,25 @@ CAnimBlendNode::FindKeyFrame(float t)
return true;
}
+bool
+CAnimBlendNode::SetupKeyFrameCompressed(void)
+{
+ if(sequence->numFrames < 1)
+ return false;
+
+ frameA = 1;
+ frameB = 0;
+
+ if(sequence->numFrames == 1){
+ frameA = 0;
+ remainingTime = 0.0f;
+ }else
+ remainingTime = sequence->GetKeyFrameCompressed(frameA)->GetDeltaTime();
+
+ CalcDeltasCompressed();
+ return true;
+}
+
void
CAnimBlendNode::CalcDeltas(void)
{
@@ -130,6 +226,28 @@ CAnimBlendNode::CalcDeltas(void)
}
void
+CAnimBlendNode::CalcDeltasCompressed(void)
+{
+ if((sequence->type & CAnimBlendSequence::KF_ROT) == 0)
+ return;
+ KeyFrameCompressed *kfA = sequence->GetKeyFrameCompressed(frameA);
+ KeyFrameCompressed *kfB = sequence->GetKeyFrameCompressed(frameB);
+ CQuaternion rotA, rotB;
+ kfA->GetRotation(&rotA);
+ kfB->GetRotation(&rotB);
+ float cos = DotProduct(rotA, rotB);
+ if(cos < 0.0f){
+ rotB *= -1.0f;
+ kfB->SetRotation(rotB);
+ }
+ cos = DotProduct(rotA, rotB);
+ if(cos > 1.0f)
+ cos = 1.0f;
+ theta = Acos(cos);
+ invSin = theta == 0.0f ? 0.0f : 1.0f/Sin(theta);
+}
+
+void
CAnimBlendNode::GetCurrentTranslation(CVector &trans, float weight)
{
trans = CVector(0.0f, 0.0f, 0.0f);
@@ -138,7 +256,7 @@ CAnimBlendNode::GetCurrentTranslation(CVector &trans, float weight)
if(blend > 0.0f){
KeyFrameTrans *kfA = (KeyFrameTrans*)sequence->GetKeyFrame(frameA);
KeyFrameTrans *kfB = (KeyFrameTrans*)sequence->GetKeyFrame(frameB);
- float t = (kfA->deltaTime - remainingTime)/kfA->deltaTime;
+ float t = kfA->deltaTime == 0.0f ? 0.0f : (kfA->deltaTime - remainingTime)/kfA->deltaTime;
if(sequence->type & CAnimBlendSequence::KF_TRANS){
trans = kfB->translation + t*(kfA->translation - kfB->translation);
trans *= blend;
@@ -147,6 +265,26 @@ CAnimBlendNode::GetCurrentTranslation(CVector &trans, float weight)
}
void
+CAnimBlendNode::GetCurrentTranslationCompressed(CVector &trans, float weight)
+{
+ trans = CVector(0.0f, 0.0f, 0.0f);
+
+ float blend = association->GetBlendAmount(weight);
+ if(blend > 0.0f){
+ KeyFrameTransCompressed *kfA = (KeyFrameTransCompressed*)sequence->GetKeyFrameCompressed(frameA);
+ KeyFrameTransCompressed *kfB = (KeyFrameTransCompressed*)sequence->GetKeyFrameCompressed(frameB);
+ float t = kfA->deltaTime == 0 ? 0.0f : (kfA->GetDeltaTime() - remainingTime)/kfA->GetDeltaTime();
+ if(sequence->type & CAnimBlendSequence::KF_TRANS){
+ CVector transA, transB;
+ kfA->GetTranslation(&transA);
+ kfB->GetTranslation(&transB);
+ trans = transB + t*(transA - transB);
+ trans *= blend;
+ }
+ }
+}
+
+void
CAnimBlendNode::GetEndTranslation(CVector &trans, float weight)
{
trans = CVector(0.0f, 0.0f, 0.0f);
@@ -158,3 +296,19 @@ CAnimBlendNode::GetEndTranslation(CVector &trans, float weight)
trans = kf->translation * blend;
}
}
+
+void
+CAnimBlendNode::GetEndTranslationCompressed(CVector &trans, float weight)
+{
+ trans = CVector(0.0f, 0.0f, 0.0f);
+
+ float blend = association->GetBlendAmount(weight);
+ if(blend > 0.0f){
+ KeyFrameTransCompressed *kf = (KeyFrameTransCompressed*)sequence->GetKeyFrameCompressed(sequence->numFrames-1);
+ if(sequence->type & CAnimBlendSequence::KF_TRANS){
+ CVector pos;
+ kf->GetTranslation(&pos);
+ trans = pos * blend;
+ }
+ }
+}
diff --git a/src/animation/AnimBlendNode.h b/src/animation/AnimBlendNode.h
index 89924d6a..99a657ac 100644
--- a/src/animation/AnimBlendNode.h
+++ b/src/animation/AnimBlendNode.h
@@ -20,11 +20,17 @@ public:
void Init(void);
bool Update(CVector &trans, CQuaternion &rot, float weight);
+ bool UpdateCompressed(CVector &trans, CQuaternion &rot, float weight);
bool NextKeyFrame(void);
+ bool NextKeyFrameCompressed(void);
bool FindKeyFrame(float t);
+ bool SetupKeyFrameCompressed(void);
void CalcDeltas(void);
+ void CalcDeltasCompressed(void);
void GetCurrentTranslation(CVector &trans, float weight);
+ void GetCurrentTranslationCompressed(CVector &trans, float weight);
void GetEndTranslation(CVector &trans, float weight);
+ void GetEndTranslationCompressed(CVector &trans, float weight);
};
diff --git a/src/animation/AnimBlendSequence.cpp b/src/animation/AnimBlendSequence.cpp
index 2ae150c1..36ac9495 100644
--- a/src/animation/AnimBlendSequence.cpp
+++ b/src/animation/AnimBlendSequence.cpp
@@ -9,9 +9,7 @@ CAnimBlendSequence::CAnimBlendSequence(void)
numFrames = 0;
keyFrames = nil;
keyFramesCompressed = nil;
-#ifdef PED_SKIN
boneTag = -1;
-#endif
}
CAnimBlendSequence::~CAnimBlendSequence(void)
@@ -29,18 +27,21 @@ CAnimBlendSequence::SetName(char *name)
}
void
-CAnimBlendSequence::SetNumFrames(int numFrames, bool translation)
+CAnimBlendSequence::SetNumFrames(int numFrames, bool translation, bool compressed)
{
- int sz;
-
if(translation){
- sz = sizeof(KeyFrameTrans);
type |= KF_ROT | KF_TRANS;
+ if(compressed)
+ keyFramesCompressed = RwMalloc(sizeof(KeyFrameTrans) * numFrames);
+ else
+ keyFrames = RwMalloc(sizeof(KeyFrameTrans) * numFrames);
}else{
- sz = sizeof(KeyFrame);
type |= KF_ROT;
+ if(compressed)
+ keyFramesCompressed = RwMalloc(sizeof(KeyFrame) * numFrames);
+ else
+ keyFrames = RwMalloc(sizeof(KeyFrame) * numFrames);
}
- keyFrames = RwMalloc(sz * numFrames);
this->numFrames = numFrames;
}
@@ -76,7 +77,7 @@ CAnimBlendSequence::Uncompress(void)
float rotScale = 1.0f/4096.0f;
float timeScale = 1.0f/60.0f;
- float transScale = 1.0f/128.0f;
+ float transScale = 1.0f/1024.0f;
if(type & KF_TRANS){
void *newKfs = RwMalloc(numFrames * sizeof(KeyFrameTrans));
KeyFrameTransCompressed *ckf = (KeyFrameTransCompressed*)keyFramesCompressed;
@@ -129,7 +130,7 @@ CAnimBlendSequence::CompressKeyframes(void)
float rotScale = 4096.0f;
float timeScale = 60.0f;
- float transScale = 128.0f;
+ float transScale = 1024.0f;
if(type & KF_TRANS){
void *newKfs = RwMalloc(numFrames * sizeof(KeyFrameTransCompressed));
KeyFrameTransCompressed *ckf = (KeyFrameTransCompressed*)newKfs;
@@ -197,4 +198,3 @@ CAnimBlendSequence::MoveMemory(void)
return false;
}
#endif
-
diff --git a/src/animation/AnimBlendSequence.h b/src/animation/AnimBlendSequence.h
index c6e70f22..67118b2f 100644
--- a/src/animation/AnimBlendSequence.h
+++ b/src/animation/AnimBlendSequence.h
@@ -19,10 +19,38 @@ struct KeyFrameTrans : KeyFrame {
struct KeyFrameCompressed {
int16 rot[4]; // 4096
int16 deltaTime; // 60
+
+ void GetRotation(CQuaternion *quat){
+ float scale = 1.0f/4096.0f;
+ quat->x = rot[0]*scale;
+ quat->y = rot[1]*scale;
+ quat->z = rot[2]*scale;
+ quat->w = rot[3]*scale;
+ }
+ void SetRotation(const CQuaternion &quat){
+ rot[0] = quat.x * 4096.0f;
+ rot[1] = quat.y * 4096.0f;
+ rot[2] = quat.z * 4096.0f;
+ rot[3] = quat.w * 4096.0f;
+ }
+ float GetDeltaTime(void) { return deltaTime/60.0f; }
+ void SetTime(float t) { deltaTime = t*60.0f + 0.5f; }
};
struct KeyFrameTransCompressed : KeyFrameCompressed {
- int16 trans[3]; // 128
+ int16 trans[3]; // 1024
+
+ void GetTranslation(CVector *vec) {
+ float scale = 1.0f/1024.0f;
+ vec->x = trans[0]*scale;
+ vec->y = trans[1]*scale;
+ vec->z = trans[2]*scale;
+ }
+ void SetTranslation(const CVector &vec){
+ trans[0] = vec.x*1024.0f;
+ trans[1] = vec.y*1024.0f;
+ trans[2] = vec.z*1024.0f;
+ }
};
@@ -37,32 +65,31 @@ public:
int32 type;
char name[24];
int32 numFrames;
-#ifdef PED_SKIN
int16 boneTag;
-#endif
void *keyFrames;
void *keyFramesCompressed;
CAnimBlendSequence(void);
virtual ~CAnimBlendSequence(void);
void SetName(char *name);
- void SetNumFrames(int numFrames, bool translation);
+ void SetNumFrames(int numFrames, bool translation, bool compressed);
void RemoveQuaternionFlips(void);
KeyFrame *GetKeyFrame(int n) {
return type & KF_TRANS ?
&((KeyFrameTrans*)keyFrames)[n] :
&((KeyFrame*)keyFrames)[n];
}
+ KeyFrameCompressed *GetKeyFrameCompressed(int n) {
+ return type & KF_TRANS ?
+ &((KeyFrameTransCompressed*)keyFramesCompressed)[n] :
+ &((KeyFrameCompressed*)keyFramesCompressed)[n];
+ }
bool HasTranslation(void) { return !!(type & KF_TRANS); }
void Uncompress(void);
void CompressKeyframes(void);
void RemoveUncompressedData(void);
bool MoveMemory(void);
-#ifdef PED_SKIN
void SetBoneTag(int tag) { boneTag = tag; }
-#endif
};
-#ifndef PED_SKIN
-VALIDATE_SIZE(CAnimBlendSequence, 0x2C);
-#endif
+VALIDATE_SIZE(CAnimBlendSequence, 0x30);
diff --git a/src/animation/AnimManager.cpp b/src/animation/AnimManager.cpp
index c66997ce..f6ac3eb5 100644
--- a/src/animation/AnimManager.cpp
+++ b/src/animation/AnimManager.cpp
@@ -10,6 +10,7 @@
#include "AnimBlendAssociation.h"
#include "AnimBlendAssocGroup.h"
#include "AnimManager.h"
+#include "Streaming.h"
CAnimBlock CAnimManager::ms_aAnimBlocks[NUMANIMBLOCKS];
CAnimBlendHierarchy CAnimManager::ms_aAnimations[NUMANIMATIONS];
@@ -32,65 +33,38 @@ AnimAssocDesc aStdAnimDescs[] = {
{ ANIM_STD_IDLE_BIGGUN, ASSOC_REPEAT | ASSOC_PARTIAL },
{ ANIM_STD_CHAT, ASSOC_REPEAT | ASSOC_PARTIAL },
{ ANIM_STD_HAILTAXI, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_STD_KO_FRONT, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
- { ANIM_STD_KO_LEFT, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
- { ANIM_STD_KO_BACK, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
- { ANIM_STD_KO_RIGHT, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
- { ANIM_STD_KO_SHOT_FACE, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
+ { ANIM_STD_KO_FRONT, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
+ { ANIM_STD_KO_LEFT, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
+ { ANIM_STD_KO_BACK, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
+ { ANIM_STD_KO_RIGHT, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
+ { ANIM_STD_KO_SHOT_FACE, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
{ ANIM_STD_KO_SHOT_STOMACH, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
- { ANIM_STD_KO_SHOT_ARM_L, ASSOC_PARTIAL | ASSOC_FRONTAL },
- { ANIM_STD_KO_SHOT_ARM_R, ASSOC_PARTIAL | ASSOC_FRONTAL },
+ { ANIM_STD_KO_SHOT_ARM_L, ASSOC_PARTIAL | ASSOC_FRONTAL },
+ { ANIM_STD_KO_SHOT_ARM_R, ASSOC_PARTIAL | ASSOC_FRONTAL },
{ ANIM_STD_KO_SHOT_LEG_L, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_STD_KO_SHOT_LEG_R, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
- { ANIM_STD_SPINFORWARD_LEFT, ASSOC_PARTIAL | ASSOC_FRONTAL },
- { ANIM_STD_SPINFORWARD_RIGHT, ASSOC_PARTIAL | ASSOC_FRONTAL },
+ { ANIM_STD_SPINFORWARD_LEFT, ASSOC_PARTIAL | ASSOC_FRONTAL },
+ { ANIM_STD_SPINFORWARD_RIGHT, ASSOC_PARTIAL | ASSOC_FRONTAL },
{ ANIM_STD_HIGHIMPACT_FRONT, ASSOC_PARTIAL },
{ ANIM_STD_HIGHIMPACT_LEFT, ASSOC_PARTIAL },
- { ANIM_STD_HIGHIMPACT_BACK, ASSOC_PARTIAL | ASSOC_FRONTAL },
+ { ANIM_STD_HIGHIMPACT_BACK, ASSOC_PARTIAL | ASSOC_FRONTAL },
{ ANIM_STD_HIGHIMPACT_RIGHT, ASSOC_PARTIAL },
- { ANIM_STD_HITBYGUN_FRONT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
- { ANIM_STD_HITBYGUN_LEFT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
- { ANIM_STD_HITBYGUN_BACK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
- { ANIM_STD_HITBYGUN_RIGHT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
+ { ANIM_STD_HITBYGUN_FRONT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
+ { ANIM_STD_HITBYGUN_LEFT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
+ { ANIM_STD_HITBYGUN_BACK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
+ { ANIM_STD_HITBYGUN_RIGHT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
{ ANIM_STD_HIT_FRONT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_STD_HIT_LEFT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_STD_HIT_BACK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_STD_HIT_RIGHT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_STD_HIT_FLOOR, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
-#if GTA_VERSION <= GTA3_PS2_160
- { ANIM_STD_HIT_BODY, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
-#endif
{ ANIM_STD_HIT_BODYBLOW, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_STD_HIT_CHEST, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_STD_HIT_HEAD, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_STD_HIT_WALK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_STD_HIT_WALL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
- { ANIM_STD_HIT_FLOOR_FRONT, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_FRONTAL },
+ { ANIM_STD_HIT_FLOOR_FRONT, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_FRONTAL },
{ ANIM_STD_HIT_BEHIND, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_STD_PUNCH, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_STD_KICKGROUND, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_STD_WEAPON_BAT_H, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_STD_WEAPON_BAT_V, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_STD_WEAPON_HGUN_BODY, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
- { ANIM_STD_WEAPON_AK_BODY, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_STD_WEAPON_PUMP, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_STD_WEAPON_SNIPER, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_STD_WEAPON_THROW, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_STD_THROW_UNDER, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_STD_START_THROW, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_STD_DETONATE, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
- { ANIM_STD_HGUN_RELOAD, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
- { ANIM_STD_AK_RELOAD, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
-#ifdef PC_PLAYER_CONTROLS
- // maybe wrong define, but unused anyway
- { ANIM_FPS_PUNCH, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_FPS_BAT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_FPS_UZI, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_FPS_PUMP, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_FPS_AK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_FPS_M16, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_FPS_ROCKET, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
-#endif
{ ANIM_STD_FIGHT_IDLE, ASSOC_REPEAT },
{ ANIM_STD_FIGHT_2IDLE, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_STD_FIGHT_SHUFFLE_F, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
@@ -102,7 +76,18 @@ AnimAssocDesc aStdAnimDescs[] = {
{ ANIM_STD_FIGHT_PUNCH, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_STD_FIGHT_ROUNDHOUSE, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_STD_FIGHT_LONGKICK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
- { ANIM_STD_PARTIAL_PUNCH, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_NOWALK },
+ { ANIM_STD_PARTIAL_PUNCH, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_NOWALK },
+ { ANIM_STD_FIGHT_JAB, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STD_FIGHT_ELBOW_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STD_FIGHT_ELBOW_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STD_FIGHT_BKICK_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STD_FIGHT_BKICK_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STD_DETONATE, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STD_PUNCH, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STD_PARTIALPUNCH, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STD_KICKGROUND, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STD_THROW_UNDER, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STD_FIGHT_SHUFFLE_B, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_STD_JACKEDCAR_RHS, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
{ ANIM_STD_JACKEDCAR_LO_RHS, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
{ ANIM_STD_JACKEDCAR_LHS, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
@@ -121,6 +106,7 @@ AnimAssocDesc aStdAnimDescs[] = {
{ ANIM_STD_CAR_CLOSE_DOOR_LO_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_STD_CAR_CLOSE_DOOR_ROLLING_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_STD_CAR_CLOSE_DOOR_ROLLING_LO_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STD_CAR_JUMP_IN_LO_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_STD_GETOUT_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_STD_GETOUT_LO_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_STD_CAR_CLOSE_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
@@ -136,39 +122,41 @@ AnimAssocDesc aStdAnimDescs[] = {
{ ANIM_STD_CAR_CLOSE_DOOR_LO_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_STD_CAR_SHUFFLE_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_STD_CAR_SHUFFLE_LO_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_STD_CAR_SIT, ASSOC_DELETEFADEDOUT },
- { ANIM_STD_CAR_SIT_LO, ASSOC_DELETEFADEDOUT },
- { ANIM_STD_CAR_SIT_P, ASSOC_DELETEFADEDOUT },
- { ANIM_STD_CAR_SIT_P_LO, ASSOC_DELETEFADEDOUT },
- { ANIM_STD_CAR_DRIVE_LEFT, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
- { ANIM_STD_CAR_DRIVE_RIGHT, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
- { ANIM_STD_CAR_DRIVE_LEFT_LO, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
- { ANIM_STD_CAR_DRIVE_RIGHT_LO, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
- { ANIM_STD_CAR_DRIVEBY_LEFT, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
- { ANIM_STD_CAR_DRIVEBY_RIGHT, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
- { ANIM_STD_CAR_LOOKBEHIND, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
- { ANIM_STD_BOAT_DRIVE, ASSOC_DELETEFADEDOUT },
+ { ANIM_STD_CAR_SIT, ASSOC_DELETEFADEDOUT},
+ { ANIM_STD_CAR_SIT_LO, ASSOC_DELETEFADEDOUT},
+ { ANIM_STD_CAR_SIT_P, ASSOC_DELETEFADEDOUT},
+ { ANIM_STD_CAR_SIT_P_LO, ASSOC_DELETEFADEDOUT},
+ { ANIM_STD_CAR_DRIVE_LEFT, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_STD_CAR_DRIVE_RIGHT, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_STD_CAR_DRIVE_LEFT_LO, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_STD_CAR_DRIVE_RIGHT_LO, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_STD_CAR_DRIVEBY_LEFT, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_STD_CAR_DRIVEBY_RIGHT, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_STD_CAR_DRIVEBY_LEFT_LO, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_STD_CAR_DRIVEBY_RIGHT_LO, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_STD_CAR_LOOKBEHIND, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_STD_BOAT_DRIVE, ASSOC_DELETEFADEDOUT | ASSOC_DRIVING },
+ { ANIM_STD_BOAT_DRIVE_LEFT, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_STD_BOAT_DRIVE_RIGHT, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_STD_BOAT_LOOKBEHIND, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_STD_BIKE_PICKUP_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STD_BIKE_PICKUP_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STD_BIKE_PULLUP_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STD_BIKE_PULLUP_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STD_BIKE_ELBOW_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STD_BIKE_ELBOW_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STD_BIKE_FALLOFF, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
+ { ANIM_STD_BIKE_FALLBACK, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_STD_GETOUT_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_STD_GETOUT_LO_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_STD_CAR_CLOSE_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_STD_CAR_HOOKERTALK, ASSOC_REPEAT | ASSOC_PARTIAL },
- { ANIM_STD_COACH_OPEN_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_STD_COACH_OPEN_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_STD_COACH_GET_IN_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_STD_COACH_GET_IN_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_STD_COACH_GET_OUT_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_STD_TRAIN_GETIN, ASSOC_PARTIAL },
{ ANIM_STD_TRAIN_GETOUT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_STD_CRAWLOUT_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_STD_CRAWLOUT_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_STD_VAN_OPEN_DOOR_REAR_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_STD_VAN_GET_IN_REAR_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_STD_VAN_CLOSE_DOOR_REAR_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_STD_VAN_GET_OUT_REAR_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_STD_VAN_OPEN_DOOR_REAR_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_STD_VAN_GET_IN_REAR_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_STD_VAN_CLOSE_DOOR_REAR_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_STD_VAN_GET_OUT_REAR_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STD_ROLLOUT_LHS, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION },
+ { ANIM_STD_ROLLOUT_RHS, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION },
{ ANIM_STD_GET_UP, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_STD_GET_UP_LEFT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_STD_GET_UP_RIGHT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
@@ -180,35 +168,133 @@ AnimAssocDesc aStdAnimDescs[] = {
{ ANIM_STD_FALL_GLIDE, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
{ ANIM_STD_FALL_LAND, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_STD_FALL_COLLAPSE, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
+ { ANIM_STD_FALL_ONBACK, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
+ { ANIM_STD_FALL_ONFRONT, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_FRONTAL },
{ ANIM_STD_EVADE_STEP, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
- { ANIM_STD_EVADE_DIVE, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
- { ANIM_STD_XPRESS_SCRATCH, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_IDLE },
+ { ANIM_STD_EVADE_DIVE, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
+ { ANIM_STD_XPRESS_SCRATCH, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_IDLE },
{ ANIM_STD_ROADCROSS, ASSOC_REPEAT | ASSOC_PARTIAL },
{ ANIM_STD_TURN180, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_STD_ARREST, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_STD_DROWN, ASSOC_PARTIAL },
- { ANIM_MEDIC_CPR, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_STD_DUCK_DOWN, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
{ ANIM_STD_DUCK_LOW, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
+ { ANIM_STD_DUCK_WEAPON, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
{ ANIM_STD_RBLOCK_SHOOT, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
- { ANIM_STD_THROW_UNDER2, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_STD_HANDSUP, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_STD_HANDSCOWER, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
- { ANIM_STD_PARTIAL_FUCKU, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
- { ANIM_STD_PHONE_IN, ASSOC_PARTIAL },
+ { ANIM_STD_PARTIAL_FUCKU, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
+ { ANIM_STD_PHONE_IN, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_STD_PHONE_OUT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_STD_PHONE_TALK, ASSOC_REPEAT | ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
+ { ANIM_STD_SEAT_DOWN, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STD_SEAT_UP, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STD_SEAT_IDLE, ASSOC_REPEAT | ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STD_SEAT_RVRS, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STD_ATM, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STD_ABSEIL, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
+};
+AnimAssocDesc aVanAnimDescs[] = {
+ { ANIM_STD_VAN_OPEN_DOOR_REAR_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STD_VAN_GET_IN_REAR_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STD_VAN_CLOSE_DOOR_REAR_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STD_VAN_GET_OUT_REAR_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STD_VAN_OPEN_DOOR_REAR_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STD_VAN_GET_IN_REAR_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STD_VAN_CLOSE_DOOR_REAR_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STD_VAN_GET_OUT_REAR_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+};
+AnimAssocDesc aCoachAnimDescs[] = {
+ { ANIM_STD_COACH_OPEN_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STD_COACH_OPEN_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STD_COACH_GET_IN_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STD_COACH_GET_IN_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STD_COACH_GET_OUT_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+};
+AnimAssocDesc aBikeAnimDescs[] = {
+ { ANIM_BIKE_RIDE, ASSOC_DELETEFADEDOUT},
+ { ANIM_BIKE_READY, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_BIKE_LEFT, ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_BIKE_RIGHT, ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_BIKE_LEANB, ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_BIKE_LEANF, ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_BIKE_WALKBACK, ASSOC_REPEAT | ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_BIKE_JUMPON_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_BIKE_JUMPON_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_BIKE_KICK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_BIKE_HIT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_BIKE_GETOFF_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_BIKE_GETOFF_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_BIKE_GETOFF_BACK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
+ { ANIM_BIKE_DRIVEBY_LHS, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_BIKE_DRIVEBY_RHS, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_BIKE_DRIVEBY_FORWARD, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_BIKE_RIDE_P, ASSOC_DELETEFADEDOUT | ASSOC_DRIVING },
+};
+AnimAssocDesc aMeleeAnimDescs[] = {
+ { ANIM_MELEE_ATTACK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_MELEE_ATTACK_2ND, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_MELEE_ATTACK_START, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
+ { ANIM_MELEE_IDLE_FIGHTMODE, ASSOC_REPEAT },
+ { ANIM_MELEE_ATTACK_FINISH, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
+};
+AnimAssocDesc aSwingAnimDescs[] = {
+ { ANIM_MELEE_ATTACK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_MELEE_ATTACK_2ND, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_MELEE_ATTACK_START, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_MELEE_IDLE_FIGHTMODE, ASSOC_REPEAT },
+ { ANIM_MELEE_ATTACK_FINISH, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+};
+AnimAssocDesc aWeaponAnimDescs[] = {
+ { ANIM_WEAPON_FIRE, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_WEAPON_CROUCHFIRE, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_WEAPON_RELOAD, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_WEAPON_CROUCHRELOAD, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_WEAPON_FIRE_3RD, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+};
+AnimAssocDesc aMedicAnimDescs[] = {
+ { ANIM_MEDIC_CPR, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+};
+AnimAssocDesc aSunbatheAnimDescs[] = {
+ { ANIM_SUNBATHE_IDLE, ASSOC_REPEAT | ASSOC_PARTIAL },
+ { ANIM_SUNBATHE_DOWN, ASSOC_REPEAT | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION },
+ { ANIM_SUNBATHE_UP, ASSOC_REPEAT | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION },
+ { ANIM_SUNBATHE_ESCAPE, ASSOC_REPEAT | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION },
+};
+AnimAssocDesc aPlayerIdleAnimDescs[] = {
+ { ANIM_PLAYER_IDLE1, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_PLAYER_IDLE2, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_PLAYER_IDLE3, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_PLAYER_IDLE4, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+};
+AnimAssocDesc aRiotAnimDescs[] = {
+ { ANIM_RIOT_ANGRY, ASSOC_REPEAT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_RIOT_ANGRY_B, ASSOC_REPEAT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_RIOT_CHANT, ASSOC_REPEAT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_RIOT_PUNCHES, ASSOC_REPEAT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_RIOT_SHOUT, ASSOC_REPEAT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_RIOT_CHALLENGE, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_RIOT_FUCKYOU, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+};
+AnimAssocDesc aStripAnimDescs[] = {
+ { ANIM_STRIP_A, ASSOC_REPEAT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STRIP_B, ASSOC_REPEAT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STRIP_C, ASSOC_REPEAT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STRIP_D, ASSOC_REPEAT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STRIP_E, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STRIP_F, ASSOC_REPEAT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_STRIP_G, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
};
#ifdef PC_PLAYER_CONTROLS
AnimAssocDesc aStdAnimDescsSide[] = {
- { ANIM_STD_WALK, ASSOC_REPEAT | ASSOC_MOVEMENT | ASSOC_HAS_TRANSLATION | ASSOC_WALK | ASSOC_HAS_X_TRANSLATION },
- { ANIM_STD_RUN, ASSOC_REPEAT | ASSOC_MOVEMENT | ASSOC_HAS_TRANSLATION | ASSOC_WALK | ASSOC_HAS_X_TRANSLATION },
- { ANIM_STD_RUNFAST, ASSOC_REPEAT | ASSOC_MOVEMENT | ASSOC_HAS_TRANSLATION | ASSOC_WALK | ASSOC_HAS_X_TRANSLATION },
+ { ANIM_STD_WALK, ASSOC_REPEAT | ASSOC_MOVEMENT | ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION | ASSOC_WALK },
+ { ANIM_STD_RUN, ASSOC_REPEAT | ASSOC_MOVEMENT | ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION | ASSOC_WALK },
+ { ANIM_STD_RUNFAST, ASSOC_REPEAT | ASSOC_MOVEMENT | ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION | ASSOC_WALK },
{ ANIM_STD_IDLE, ASSOC_REPEAT },
{ ANIM_STD_STARTWALK, ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION },
};
#endif
-char const *aStdAnimations[] = {
+char const* aStdAnimations[] = {
"walk_civi",
"run_civi",
"sprint_panic",
@@ -216,7 +302,7 @@ char const *aStdAnimations[] = {
"walk_start",
"run_stop",
"run_stopR",
- "idle_cam",
+ "idle_hbhb",
"idle_hbhb",
"idle_tired",
"idle_armed",
@@ -247,9 +333,6 @@ char const *aStdAnimations[] = {
"HIT_back",
"HIT_R",
"FLOOR_hit",
-#if GTA_VERSION <= GTA3_PS2_160
- "HIT_body",
-#endif
"HIT_bodyblow",
"HIT_chest",
"HIT_head",
@@ -257,30 +340,6 @@ char const *aStdAnimations[] = {
"HIT_wall",
"FLOOR_hit_f",
"HIT_behind",
- "punchR",
- "KICK_floor",
- "WEAPON_bat_h",
- "WEAPON_bat_v",
- "WEAPON_hgun_body",
- "WEAPON_AK_body",
- "WEAPON_pump",
- "WEAPON_sniper",
- "WEAPON_throw",
- "WEAPON_throwu",
- "WEAPON_start_throw",
- "bomber",
- "WEAPON_hgun_rload",
- "WEAPON_AK_rload",
-#ifdef PC_PLAYER_CONTROLS
- // maybe wrong define, but unused anyway
- "FPS_PUNCH",
- "FPS_BAT",
- "FPS_UZI",
- "FPS_PUMP",
- "FPS_AK",
- "FPS_M16",
- "FPS_ROCKET",
-#endif
"FIGHTIDLE",
"FIGHT2IDLE",
"FIGHTsh_F",
@@ -293,6 +352,17 @@ char const *aStdAnimations[] = {
"FIGHTrndhse",
"FIGHTlngkck",
"FIGHTppunch",
+ "FIGHTjab",
+ "FIGHTelbowL",
+ "FIGHTelbowR",
+ "FIGHTbkickL",
+ "FIGHTbkickR",
+ "bomber",
+ "punchR",
+ "FIGHTppunch",
+ "KICK_floor",
+ "WEAPON_throwu",
+ "FIGHTsh_back",
"car_jackedRHS",
"car_LjackedRHS",
"car_jackedLHS",
@@ -311,6 +381,7 @@ char const *aStdAnimations[] = {
"CAR_closedoorL_LHS",
"CAR_rolldoor",
"CAR_rolldoorLO",
+ "CAR_jumpin_LHS",
"CAR_getout_LHS",
"CAR_getoutL_LHS",
"CAR_close_LHS",
@@ -336,29 +407,31 @@ char const *aStdAnimations[] = {
"Drive_LO_R",
"Driveby_L",
"Driveby_R",
+ "DrivebyL_L",
+ "DrivebyL_R",
"CAR_LB",
"DRIVE_BOAT",
+ "DRIVE_BOAT_L",
+ "DRIVE_BOAT_R",
+ "DRIVE_BOAT_back",
+ "BIKE_pickupR",
+ "BIKE_pickupL",
+ "BIKE_pullupR",
+ "BIKE_pullupL",
+ "BIKE_elbowR",
+ "BIKE_elbowL",
+ "BIKE_fall_off",
+ "BIKE_fallR",
"CAR_getout_RHS",
"CAR_getoutL_RHS",
"CAR_close_RHS",
"car_hookertalk",
- "COACH_opnL",
- "COACH_opnR",
- "COACH_inL",
- "COACH_inR",
- "COACH_outL",
- "TRAIN_getin",
- "TRAIN_getout",
+ "idle_stance",
+ "idle_stance",
"CAR_crawloutRHS",
"CAR_crawloutRHS",
- "VAN_openL",
- "VAN_getinL",
- "VAN_closeL",
- "VAN_getoutL",
- "VAN_open",
- "VAN_getin",
- "VAN_close",
- "VAN_getout",
+ "CAR_rollout_LHS",
+ "CAR_rollout_LHS",
"Getup",
"Getup",
"Getup",
@@ -370,6 +443,8 @@ char const *aStdAnimations[] = {
"FALL_glide",
"FALL_land",
"FALL_collapse",
+ "FALL_back",
+ "FALL_front",
"EV_step",
"EV_dive",
"XPRESSscratch",
@@ -377,197 +452,507 @@ char const *aStdAnimations[] = {
"TURN_180",
"ARRESTgun",
"DROWN",
- "CPR",
"DUCK_down",
"DUCK_low",
+ "WEAPON_crouch",
"RBLOCK_Cshoot",
- "WEAPON_throwu",
"handsup",
"handsCOWER",
"FUCKU",
"PHONE_in",
"PHONE_out",
"PHONE_talk",
+ "SEAT_down",
+ "SEAT_up",
+ "SEAT_idle",
+ "SEAT_down",
+ "ATM",
+ "abseil",
+};
+char const* aVanAnimations[] = {
+ "VAN_openL",
+ "VAN_getinL",
+ "VAN_closeL",
+ "VAN_getoutL",
+ "VAN_open",
+ "VAN_getin",
+ "VAN_close",
+ "VAN_getout",
+};
+char const* aCoachAnimations[] = {
+ "COACH_opnL",
+ "COACH_opnL",
+ "COACH_inL",
+ "COACH_inL",
+ "COACH_outL",
+};
+char const* aBikesAnimations[] = {
+ "BIKEs_Ride",
+ "BIKEs_Still",
+ "BIKEs_Left",
+ "BIKEs_Right",
+ "BIKEs_Back",
+ "BIKEs_Fwd",
+ "BIKEs_pushes",
+ "BIKEs_jumponR",
+ "BIKEs_jumponL",
+ "BIKEs_kick",
+ "BIKEs_hit",
+ "BIKEs_getoffRHS",
+ "BIKEs_getoffLHS",
+ "BIKEs_getoffBACK",
+ "BIKEs_drivebyLHS",
+ "BIKEs_drivebyRHS",
+ "BIKEs_drivebyFT",
+ "BIKEs_passenger",
+};
+char const* aBikevAnimations[] = {
+ "BIKEv_Ride",
+ "BIKEv_Still",
+ "BIKEv_Left",
+ "BIKEv_Right",
+ "BIKEv_Back",
+ "BIKEv_Fwd",
+ "BIKEv_pushes",
+ "BIKEv_jumponR",
+ "BIKEv_jumponL",
+ "BIKEv_kick",
+ "BIKEv_hit",
+ "BIKEv_getoffRHS",
+ "BIKEv_getoffLHS",
+ "BIKEv_getoffBACK",
+ "BIKEv_drivebyLHS",
+ "BIKEv_drivebyRHS",
+ "BIKEv_drivebyFT",
+ "BIKEv_passenger",
+};
+char const* aBikehAnimations[] = {
+ "BIKEh_Ride",
+ "BIKEh_Still",
+ "BIKEh_Left",
+ "BIKEh_Right",
+ "BIKEh_Back",
+ "BIKEh_Fwd",
+ "BIKEh_pushes",
+ "BIKEh_jumponR",
+ "BIKEh_jumponL",
+ "BIKEh_kick",
+ "BIKEh_hit",
+ "BIKEh_getoffRHS",
+ "BIKEh_getoffLHS",
+ "BIKEh_getoffBACK",
+ "BIKEh_drivebyLHS",
+ "BIKEh_drivebyRHS",
+ "BIKEh_drivebyFT",
+ "BIKEh_passenger",
+};
+char const* aBikedAnimations[] = {
+ "BIKEd_Ride",
+ "BIKEd_Still",
+ "BIKEd_Left",
+ "BIKEd_Right",
+ "BIKEd_Back",
+ "BIKEd_Fwd",
+ "BIKEd_pushes",
+ "BIKEd_jumponR",
+ "BIKEd_jumponL",
+ "BIKEd_kick",
+ "BIKEd_hit",
+ "BIKEd_getoffRHS",
+ "BIKEd_getoffLHS",
+ "BIKEd_getoffBACK",
+ "BIKEd_drivebyLHS",
+ "BIKEd_drivebyRHS",
+ "BIKEd_drivebyFT",
+ "BIKEd_passenger",
+};
+char const* aUnarmedAnimations[] = {
+ "punchR",
+ "KICK_floor",
+ "FIGHTppunch",
+};
+char const* aScrewdriverAnimations[] = {
+ "FIGHTbodyblow",
+ "FIGHTbodyblow",
+ "FIGHTppunch",
+ "FIGHTIDLE",
+ "FIGHTbodyblow",
+};
+char const* aKnifeAnimations[] = {
+ "WEAPON_knife_1",
+ "WEAPON_knife_2",
+ "knife_part",
+ "WEAPON_knifeidle",
+ "WEAPON_knife_3",
+};
+char const* aBaseballbatAnimations[] = {
+ "WEAPON_bat_h",
+ "WEAPON_bat_v",
+ "BAT_PART",
+ "WEAPON_bat_h",
+ "WEAPON_golfclub",
+};
+char const* aGolfclubAnimations[] = {
+ "WEAPON_bat_h",
+ "WEAPON_golfclub",
+ "BAT_PART",
+ "WEAPON_bat_h",
+ "WEAPON_bat_v",
+};
+char const* aChainsawAnimations[] = {
+ "WEAPON_csaw",
+ "WEAPON_csawlo",
+ "csaw_part",
+};
+char const* aPythonAnimations[] = {
+ "python_fire",
+ "python_crouchfire",
+ "python_reload",
+ "python_crouchreload",
+};
+char const* aColtAnimations[] = {
+ "colt45_fire",
+ "colt45_crouchfire",
+ "colt45_reload",
+ "colt45_crouchreload",
+ "colt45_cop",
+};
+char const* aShotgunAnimations[] = {
+ "shotgun_fire",
+ "shotgun_crouchfire",
+};
+char const* aBuddyAnimations[] = {
+ "buddy_fire",
+ "buddy_crouchfire",
};
-char const *aPlayerAnimations[] = {
+char const* aTecAnimations[] = {
+ "TEC_fire",
+ "TEC_crouchfire",
+ "TEC_reload",
+ "TEC_crouchreload",
+};
+char const* aUziAnimations[] = {
+ "UZI_fire",
+ "UZI_crouchfire",
+ "UZI_reload",
+ "UZI_crouchreload",
+};
+char const* aRifleAnimations[] = {
+ "RIFLE_fire",
+ "RIFLE_crouchfire",
+ "RIFLE_load",
+ "RIFLE_crouchload",
+};
+char const* aM60Animations[] = {
+ "M60_fire",
+ "M60_fire",
+ "M60_reload",
+};
+char const* aSniperAnimations[] = {
+ "WEAPON_sniper",
+};
+char const* aThrowAnimations[] = {
+ "WEAPON_throw",
+ "WEAPON_throwu",
+ "WEAPON_start_throw",
+};
+char const* aFlamethrowerAnimations[] = {
+ "FLAME_fire",
+};
+char const* aMedicAnimations[] = {
+ "CPR",
+};
+char const* aSunbatheAnimations[] = {
+ "bather",
+ "batherdown",
+ "batherup",
+ "batherscape",
+};
+char const* aPlayerIdleAnimations[] = {
+ "stretch",
+ "time",
+ "shldr",
+ "strleg",
+};
+char const* aRiotAnimations[] = {
+ "riot_angry",
+ "riot_angry_b",
+ "riot_chant",
+ "riot_punches",
+ "riot_shout",
+ "riot_challenge",
+ "riot_fuku",
+};
+char const* aStripAnimations[] = {
+ "strip_A",
+ "strip_B",
+ "strip_C",
+ "strip_D",
+ "strip_E",
+ "strip_F",
+ "strip_G",
+};
+char const* aLanceAnimations[] = {
+ "lance",
+};
+char const* aPlayerAnimations[] = {
"walk_player",
"run_player",
"SPRINT_civi",
"IDLE_STANCE",
"walk_start",
};
-char const *aPlayerWithRocketAnimations[] = {
+char const* aPlayerWithRocketAnimations[] = {
"walk_rocket",
"run_rocket",
"run_rocket",
"idle_rocket",
"walk_start_rocket",
};
-char const *aPlayer1ArmedAnimations[] = {
+char const* aPlayer1ArmedAnimations[] = {
"walk_player",
"run_1armed",
"SPRINT_civi",
"IDLE_STANCE",
"walk_start",
};
-char const *aPlayer2ArmedAnimations[] = {
- "walk_player",
+char const* aPlayer2ArmedAnimations[] = {
+ "walk_armed",
"run_armed",
"run_armed",
- "idle_stance",
- "walk_start",
+ "idle_armed",
+ "walk_start_armed",
};
-char const *aPlayerBBBatAnimations[] = {
+char const* aPlayerBBBatAnimations[] = {
"walk_player",
"run_player",
"run_player",
"IDLE_STANCE",
"walk_start",
};
-char const *aShuffleAnimations[] = {
+char const* aPlayerChainsawAnimations[] = {
+ "walk_csaw",
+ "run_csaw",
+ "run_csaw",
+ "IDLE_csaw",
+ "walk_start_csaw",
+};
+char const* aShuffleAnimations[] = {
"WALK_shuffle",
"RUN_civi",
"SPRINT_civi",
"IDLE_STANCE",
};
-char const *aOldAnimations[] = {
+char const* aOldAnimations[] = {
"walk_old",
"run_civi",
"sprint_civi",
"idle_stance",
};
-char const *aGang1Animations[] = {
+char const* aGang1Animations[] = {
"walk_gang1",
"run_gang1",
"sprint_civi",
"idle_stance",
};
-char const *aGang2Animations[] = {
+char const* aGang2Animations[] = {
"walk_gang2",
"run_gang1",
"sprint_civi",
"idle_stance",
};
-char const *aFatAnimations[] = {
+char const* aFatAnimations[] = {
"walk_fat",
"run_civi",
"woman_runpanic",
"idle_stance",
};
-char const *aOldFatAnimations[] = {
+char const* aOldFatAnimations[] = {
"walk_fatold",
"run_fatold",
"woman_runpanic",
"idle_stance",
};
-char const *aStdWomanAnimations[] = {
+char const* aJoggerAnimations[] = {
+ "JOG_maleA",
+ "run_civi",
+ "sprint_civi",
+ "idle_stance",
+};
+char const* aStdWomanAnimations[] = {
"woman_walknorm",
"woman_run",
"woman_runpanic",
"woman_idlestance",
};
-char const *aWomanShopAnimations[] = {
+char const* aWomanShopAnimations[] = {
"woman_walkshop",
"woman_run",
"woman_run",
"woman_idlestance",
};
-char const *aBusyWomanAnimations[] = {
+char const* aBusyWomanAnimations[] = {
"woman_walkbusy",
"woman_run",
"woman_runpanic",
"woman_idlestance",
};
-char const *aSexyWomanAnimations[] = {
+char const* aSexyWomanAnimations[] = {
"woman_walksexy",
"woman_run",
"woman_runpanic",
"woman_idlestance",
};
-char const *aOldWomanAnimations[] = {
+char const* aFatWomanAnimations[] = {
+ "walk_fat",
+ "woman_run",
+ "woman_runpanic",
+ "woman_idlestance",
+};
+char const* aOldWomanAnimations[] = {
"woman_walkold",
"woman_run",
"woman_runpanic",
"woman_idlestance",
};
-char const *aFatWomanAnimations[] = {
- "walk_fat",
+char const* aJoggerWomanAnimations[] = {
+ "JOG_maleB",
"woman_run",
"woman_runpanic",
"woman_idlestance",
};
-char const *aPanicChunkyAnimations[] = {
+char const* aPanicChunkyAnimations[] = {
"run_fatold",
"woman_runpanic",
"woman_runpanic",
"idle_stance",
};
+char const* aSkateAnimations[] = {
+ "skate_run",
+ "skate_sprint",
+ "skate_sprint",
+ "skate_idle",
+};
#ifdef PC_PLAYER_CONTROLS
-char const *aPlayerStrafeBackAnimations[] = {
- "walk_player_back",
- "run_player_back",
- "run_player_back",
+char const* aPlayerStrafeBackAnimations[] = {
+ "walk_back",
+ "run_back",
+ "run_back",
"IDLE_STANCE",
"walk_start_back",
};
-char const *aPlayerStrafeLeftAnimations[] = {
- "walk_player_left",
+char const* aPlayerStrafeLeftAnimations[] = {
+ "walk_left",
"run_left",
"run_left",
"IDLE_STANCE",
"walk_start_left",
};
-char const *aPlayerStrafeRightAnimations[] = {
- "walk_player_right",
+char const* aPlayerStrafeRightAnimations[] = {
+ "walk_right",
"run_right",
"run_right",
"IDLE_STANCE",
"walk_start_right",
};
-char const *aRocketStrafeBackAnimations[] = {
+char const* aRocketStrafeBackAnimations[] = {
"walk_rocket_back",
"run_rocket_back",
"run_rocket_back",
"idle_rocket",
"walkst_rocket_back",
};
-char const *aRocketStrafeLeftAnimations[] = {
+char const* aRocketStrafeLeftAnimations[] = {
"walk_rocket_left",
"run_rocket_left",
"run_rocket_left",
"idle_rocket",
"walkst_rocket_left",
};
-char const *aRocketStrafeRightAnimations[] = {
+char const* aRocketStrafeRightAnimations[] = {
"walk_rocket_right",
"run_rocket_right",
"run_rocket_right",
"idle_rocket",
"walkst_rocket_right",
};
+char const* aChainsawStrafeBackAnimations[] = {
+ "walk_csaw_back",
+ "run_csaw_back",
+ "run_csaw_back",
+ "idle_csaw",
+ "walkst_csaw_back",
+};
+char const* aChainsawStrafeLeftAnimations[] = {
+ "walk_csaw_left",
+ "run_csaw_left",
+ "run_csaw_left",
+ "idle_csaw",
+ "walkst_csaw_left",
+};
+char const* aChainsawStrafeRightAnimations[] = {
+ "walk_csaw_right",
+ "run_csaw_right",
+ "run_csaw_right",
+ "idle_csaw",
+ "walkst_csaw_right",
+};
#endif
#define awc(a) ARRAY_SIZE(a), a
const AnimAssocDefinition CAnimManager::ms_aAnimAssocDefinitions[NUM_ANIM_ASSOC_GROUPS] = {
{ "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 },
- { "oldwoman", "ped", MI_COP, awc(aOldWomanAnimations), 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 },
#ifdef PC_PLAYER_CONTROLS
{ "playerback", "ped", MI_COP, awc(aPlayerStrafeBackAnimations), aStdAnimDescs },
{ "playerleft", "ped", MI_COP, awc(aPlayerStrafeLeftAnimations), aStdAnimDescsSide },
@@ -575,6 +960,9 @@ const AnimAssocDefinition CAnimManager::ms_aAnimAssocDefinitions[NUM_ANIM_ASSOC_
{ "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 },
#endif
};
#undef awc
@@ -585,8 +973,6 @@ CAnimManager::Initialise(void)
ms_numAnimations = 0;
ms_numAnimBlocks = 0;
ms_animCache.Init(25);
-
-// dumpanimdata();
}
void
@@ -594,31 +980,50 @@ CAnimManager::Shutdown(void)
{
int i;
- ms_animCache.Shutdown();
+ for(i = 0; i < NUMANIMBLOCKS; i++)
+ CStreaming::RemoveAnim(i);
for(i = 0; i < ms_numAnimations; i++)
ms_aAnimations[i].Shutdown();
+ ms_animCache.Shutdown();
+
delete[] ms_aAnimAssocGroups;
}
void
CAnimManager::UncompressAnimation(CAnimBlendHierarchy *hier)
{
- if(!hier->compressed){
- if(hier->linkPtr){
- hier->linkPtr->Remove();
- ms_animCache.head.Insert(hier->linkPtr);
- }
+ if(hier->keepCompressed){
+ if(hier->totalLength == 0.0f)
+ hier->CalcTotalTimeCompressed();
}else{
- CLink<CAnimBlendHierarchy*> *link = ms_animCache.Insert(hier);
- if(link == nil){
- ms_animCache.tail.prev->item->RemoveUncompressedData();
- ms_animCache.Remove(ms_animCache.tail.prev);
- link = ms_animCache.Insert(hier);
+ if(!hier->compressed){
+ if(hier->linkPtr){
+ hier->linkPtr->Remove();
+ ms_animCache.head.Insert(hier->linkPtr);
+ }
+ }else{
+ CLink<CAnimBlendHierarchy*> *link = ms_animCache.Insert(hier);
+ if(link == nil){
+ CAnimBlendHierarchy *lastHier = ms_animCache.tail.prev->item;
+ lastHier->RemoveUncompressedData();
+ ms_animCache.Remove(ms_animCache.tail.prev);
+ lastHier->linkPtr = nil;
+ link = ms_animCache.Insert(hier);
+ }
+ hier->linkPtr = link;
+ hier->Uncompress();
}
- hier->linkPtr = link;
- hier->Uncompress();
+ }
+}
+
+void
+CAnimManager::RemoveFromUncompressedCache(CAnimBlendHierarchy *hier)
+{
+ if(hier->linkPtr){
+ ms_animCache.Remove(hier->linkPtr);
+ hier->linkPtr = nil;
}
}
@@ -633,6 +1038,73 @@ CAnimManager::GetAnimationBlock(const char *name)
return nil;
}
+int32
+CAnimManager::GetAnimationBlockIndex(const char *name)
+{
+ int i;
+
+ for(i = 0; i < ms_numAnimBlocks; i++)
+ if(strcasecmp(ms_aAnimBlocks[i].name, name) == 0)
+ return i;
+ return -1;
+}
+
+int32
+CAnimManager::RegisterAnimBlock(const char *name)
+{
+ CAnimBlock *animBlock = GetAnimationBlock(name);
+ if(animBlock == nil){
+ animBlock = &ms_aAnimBlocks[ms_numAnimBlocks++];
+ strncpy(animBlock->name, name, MAX_ANIMBLOCK_NAME);
+ animBlock->numAnims = 0;
+ assert(animBlock->refCount == 0);
+ }
+ return animBlock - ms_aAnimBlocks;
+}
+
+int32
+CAnimManager::GetNumRefsToAnimBlock(int32 block)
+{
+ return ms_aAnimBlocks[block].refCount;
+}
+
+void
+CAnimManager::AddAnimBlockRef(int32 block)
+{
+ ms_aAnimBlocks[block].refCount++;
+}
+
+void
+CAnimManager::RemoveAnimBlockRefWithoutDelete(int32 block)
+{
+ ms_aAnimBlocks[block].refCount--;
+}
+
+void
+CAnimManager::RemoveAnimBlockRef(int32 block)
+{
+ ms_aAnimBlocks[block].refCount--;
+ if(ms_aAnimBlocks[block].refCount == 0)
+ CStreaming::RemoveAnim(block);
+}
+
+void
+CAnimManager::RemoveAnimBlock(int32 block)
+{
+ int i;
+ CAnimBlock *animblock;
+
+ animblock = &ms_aAnimBlocks[block];
+ debug("Removing ANIMS %s\n", animblock->name);
+ for(i = 0; i < NUM_ANIM_ASSOC_GROUPS; i++)
+ if(ms_aAnimAssocGroups[i].animBlock == animblock)
+ ms_aAnimAssocGroups[i].DestroyAssociations();
+ for(i = 0; i < animblock->numAnims; i++)
+ ms_aAnimations[animblock->firstIndex + i].Shutdown();
+ animblock->isLoaded = false;
+ animblock->refCount = 0;
+}
+
CAnimBlendHierarchy*
CAnimManager::GetAnimation(const char *name, CAnimBlock *animBlock)
{
@@ -640,7 +1112,7 @@ CAnimManager::GetAnimation(const char *name, CAnimBlock *animBlock)
CAnimBlendHierarchy *hier = &ms_aAnimations[animBlock->firstIndex];
for(i = 0; i < animBlock->numAnims; i++){
- if(!CGeneral::faststricmp(hier->name, name))
+ if(strcasecmp(hier->name, name) == 0)
return hier;
hier++;
}
@@ -761,26 +1233,34 @@ CAnimManager::BlendAnimation(RpClump *clump, AssocGroupId groupId, AnimationId a
void
CAnimManager::LoadAnimFiles(void)
{
- int i, j;
-
LoadAnimFile("ANIM\\PED.IFP");
-
- // Create all assoc groups
ms_aAnimAssocGroups = new CAnimBlendAssocGroup[NUM_ANIM_ASSOC_GROUPS];
+ CreateAnimAssocGroups();
+}
+
+void
+CAnimManager::CreateAnimAssocGroups(void)
+{
+ int i, j;
+
for(i = 0; i < NUM_ANIM_ASSOC_GROUPS; i++){
+ CAnimBlock *block = GetAnimationBlock(ms_aAnimAssocDefinitions[i].blockName);
+ if(block == nil || !block->isLoaded || ms_aAnimAssocGroups[i].assocList)
+ continue;
+
CBaseModelInfo *mi = CModelInfo::GetModelInfo(ms_aAnimAssocDefinitions[i].modelIndex);
RpClump *clump = (RpClump*)mi->CreateInstance();
RpAnimBlendClumpInit(clump);
CAnimBlendAssocGroup *group = &ms_aAnimAssocGroups[i];
const AnimAssocDefinition *def = &ms_aAnimAssocDefinitions[i];
+ group->groupId = i;
+ group->firstAnimId = def->animDescs[0].animId;
group->CreateAssociations(def->blockName, clump, def->animNames, def->numAnims);
for(j = 0; j < group->numAssociations; j++)
- group->GetAnimation(j)->flags |= def->animDescs[j].flags;
-#ifdef PED_SKIN
- // forgot on xbox/android
+ // GetAnimation(i) in III (but it's in LoadAnimFiles), GetAnimation(group->animDesc[j].animId) in VC
+ group->GetAnimation(def->animDescs[j].animId)->flags |= def->animDescs[j].flags;
if(IsClumpSkinned(clump))
RpClumpForAllAtomics(clump, AtomicRemoveAnimFromSkinCB, nil);
-#endif
RpClumpDestroy(clump);
}
}
@@ -788,15 +1268,15 @@ CAnimManager::LoadAnimFiles(void)
void
CAnimManager::LoadAnimFile(const char *filename)
{
- int fd;
- fd = CFileMgr::OpenFile(filename, "rb");
- assert(fd > 0);
- LoadAnimFile(fd, true);
- CFileMgr::CloseFile(fd);
+ RwStream *stream;
+ stream = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMREAD, filename);
+ assert(stream);
+ LoadAnimFile(stream, true);
+ RwStreamClose(stream, nil);
}
void
-CAnimManager::LoadAnimFile(int fd, bool compress)
+CAnimManager::LoadAnimFile(RwStream *stream, bool compress, char (*uncompressedAnims)[32])
{
#define ROUNDSIZE(x) if((x) & 3) (x) += 4 - ((x)&3)
struct IfpHeader {
@@ -804,130 +1284,161 @@ CAnimManager::LoadAnimFile(int fd, bool compress)
uint32 size;
};
IfpHeader anpk, info, name, dgan, cpan, anim;
- int numANPK;
char buf[256];
- int i, j, k, l;
+ int j, k, l;
float *fbuf = (float*)buf;
- CFileMgr::Read(fd, (char*)&anpk, sizeof(IfpHeader));
- if(!CGeneral::faststrncmp(anpk.ident, "ANLF", 4)) {
- ROUNDSIZE(anpk.size);
- CFileMgr::Read(fd, buf, anpk.size);
- numANPK = *(int*)buf;
- } else if(!CGeneral::faststrncmp(anpk.ident, "ANPK", 4)) {
- CFileMgr::Seek(fd, -8, 1);
- numANPK = 1;
- }
-
- for(i = 0; i < numANPK; i++){
- // block name
- CFileMgr::Read(fd, (char*)&anpk, sizeof(IfpHeader));
- ROUNDSIZE(anpk.size);
- CFileMgr::Read(fd, (char*)&info, sizeof(IfpHeader));
- ROUNDSIZE(info.size);
- CFileMgr::Read(fd, buf, info.size);
- CAnimBlock *animBlock = &ms_aAnimBlocks[ms_numAnimBlocks++];
- strncpy(animBlock->name, buf+4, 24);
+ // block name
+ RwStreamRead(stream, &anpk, sizeof(IfpHeader));
+ ROUNDSIZE(anpk.size);
+ RwStreamRead(stream, &info, sizeof(IfpHeader));
+ ROUNDSIZE(info.size);
+ RwStreamRead(stream, buf, info.size);
+ CAnimBlock *animBlock = GetAnimationBlock(buf+4);
+ if(animBlock){
+ if(animBlock->numAnims == 0){
+ animBlock->numAnims = *(int*)buf;
+ animBlock->firstIndex = ms_numAnimations;
+ }
+ }else{
+ animBlock = &ms_aAnimBlocks[ms_numAnimBlocks++];
+ strncpy(animBlock->name, buf+4, MAX_ANIMBLOCK_NAME);
animBlock->numAnims = *(int*)buf;
-
animBlock->firstIndex = ms_numAnimations;
+ }
- for(j = 0; j < animBlock->numAnims; j++){
- CAnimBlendHierarchy *hier = &ms_aAnimations[ms_numAnimations++];
+ debug("Loading ANIMS %s\n", animBlock->name);
+ animBlock->isLoaded = true;
- // animation name
- CFileMgr::Read(fd, (char*)&name, sizeof(IfpHeader));
- ROUNDSIZE(name.size);
- CFileMgr::Read(fd, buf, name.size);
- hier->SetName(buf);
+ int animIndex = animBlock->firstIndex;
+ for(j = 0; j < animBlock->numAnims; j++){
+ assert(animIndex < ARRAY_SIZE(ms_aAnimations));
+ CAnimBlendHierarchy *hier = &ms_aAnimations[animIndex++];
- // DG info has number of nodes/sequences
- CFileMgr::Read(fd, (char*)&dgan, sizeof(IfpHeader));
- ROUNDSIZE(dgan.size);
- CFileMgr::Read(fd, (char*)&info, sizeof(IfpHeader));
- ROUNDSIZE(info.size);
- CFileMgr::Read(fd, buf, info.size);
- hier->numSequences = *(int*)buf;
- hier->sequences = new CAnimBlendSequence[hier->numSequences];
-
- CAnimBlendSequence *seq = hier->sequences;
- for(k = 0; k < hier->numSequences; k++, seq++){
- // Each node has a name and key frames
- CFileMgr::Read(fd, (char*)&cpan, sizeof(IfpHeader));
- ROUNDSIZE(dgan.size);
- CFileMgr::Read(fd, (char*)&anim, sizeof(IfpHeader));
- ROUNDSIZE(anim.size);
- CFileMgr::Read(fd, buf, anim.size);
- int numFrames = *(int*)(buf+28);
- seq->SetName(buf);
-#ifdef PED_SKIN
- if(anim.size == 44)
- seq->SetBoneTag(*(int*)(buf+40));
+ // animation name
+ RwStreamRead(stream, &name, sizeof(IfpHeader));
+ ROUNDSIZE(name.size);
+ RwStreamRead(stream, buf, name.size);
+ hier->SetName(buf);
+
+#ifdef ANIM_COMPRESSION
+ bool compressHier = compress;
+#else
+ bool compressHier = false;
#endif
- if(numFrames == 0)
- continue;
-
- bool hasScale = false;
- bool hasTranslation = false;
- CFileMgr::Read(fd, (char*)&info, sizeof(info));
- if(!CGeneral::faststrncmp(info.ident, "KRTS", 4)) {
- hasScale = true;
- seq->SetNumFrames(numFrames, true);
- }else if(!CGeneral::faststrncmp(info.ident, "KRT0", 4)) {
- hasTranslation = true;
- seq->SetNumFrames(numFrames, true);
- }else if(!CGeneral::faststrncmp(info.ident, "KR00", 4)){
- seq->SetNumFrames(numFrames, false);
+ if (uncompressedAnims) {
+ for (int i = 0; uncompressedAnims[i][0]; i++) {
+ if (!CGeneral::faststricmp(uncompressedAnims[i], hier->name)){
+ debug("Loading %s uncompressed\n", hier->name);
+ compressHier = false;
}
+ }
+ }
+
+ hier->compressed = compressHier;
+ hier->keepCompressed = false;
+
+ // DG info has number of nodes/sequences
+ RwStreamRead(stream, (char*)&dgan, sizeof(IfpHeader));
+ ROUNDSIZE(dgan.size);
+ RwStreamRead(stream, (char*)&info, sizeof(IfpHeader));
+ ROUNDSIZE(info.size);
+ RwStreamRead(stream, buf, info.size);
+ hier->numSequences = *(int*)buf;
+ hier->sequences = new CAnimBlendSequence[hier->numSequences];
- for(l = 0; l < numFrames; l++){
- if(hasScale){
- CFileMgr::Read(fd, buf, 0x2C);
- CQuaternion rot(fbuf[0], fbuf[1], fbuf[2], fbuf[3]);
- rot.Invert();
- CVector trans(fbuf[4], fbuf[5], fbuf[6]);
+ CAnimBlendSequence *seq = hier->sequences;
+ for(k = 0; k < hier->numSequences; k++, seq++){
+ // Each node has a name and key frames
+ RwStreamRead(stream, &cpan, sizeof(IfpHeader));
+ ROUNDSIZE(dgan.size);
+ RwStreamRead(stream, &anim, sizeof(IfpHeader));
+ ROUNDSIZE(anim.size);
+ RwStreamRead(stream, buf, anim.size);
+ int numFrames = *(int*)(buf+28);
+ seq->SetName(buf);
+ if(anim.size == 44)
+ seq->SetBoneTag(*(int*)(buf+40));
+ if(numFrames == 0)
+ continue;
+
+ bool hasScale = false;
+ bool hasTranslation = false;
+ RwStreamRead(stream, &info, sizeof(info));
+ if(strncmp(info.ident, "KRTS", 4) == 0){
+ hasScale = true;
+ seq->SetNumFrames(numFrames, true, compressHier);
+ }else if(strncmp(info.ident, "KRT0", 4) == 0){
+ hasTranslation = true;
+ seq->SetNumFrames(numFrames, true, compressHier);
+ }else if(strncmp(info.ident, "KR00", 4) == 0){
+ seq->SetNumFrames(numFrames, false, compressHier);
+ }
+ if(strstr(seq->name, "L Toe"))
+ debug("anim %s has toe keyframes\n", hier->name); // BUG: seq->name
+
+ for(l = 0; l < numFrames; l++){
+ if(hasScale){
+ RwStreamRead(stream, buf, 0x2C);
+ CQuaternion rot(fbuf[0], fbuf[1], fbuf[2], fbuf[3]);
+ rot.Invert();
+ CVector trans(fbuf[4], fbuf[5], fbuf[6]);
+ if(compressHier){
+ KeyFrameTransCompressed *kf = (KeyFrameTransCompressed*)seq->GetKeyFrameCompressed(l);
+ kf->SetRotation(rot);
+ kf->SetTranslation(trans);
+ // scaling ignored
+ kf->SetTime(fbuf[10]); // absolute time here
+ }else{
KeyFrameTrans *kf = (KeyFrameTrans*)seq->GetKeyFrame(l);
kf->rotation = rot;
kf->translation = trans;
// scaling ignored
kf->deltaTime = fbuf[10]; // absolute time here
- }else if(hasTranslation){
- CFileMgr::Read(fd, buf, 0x20);
- CQuaternion rot(fbuf[0], fbuf[1], fbuf[2], fbuf[3]);
- rot.Invert();
- CVector trans(fbuf[4], fbuf[5], fbuf[6]);
+ }
+ }else if(hasTranslation){
+ RwStreamRead(stream, buf, 0x20);
+ CQuaternion rot(fbuf[0], fbuf[1], fbuf[2], fbuf[3]);
+ rot.Invert();
+ CVector trans(fbuf[4], fbuf[5], fbuf[6]);
+ if(compressHier){
+ KeyFrameTransCompressed *kf = (KeyFrameTransCompressed*)seq->GetKeyFrameCompressed(l);
+ kf->SetRotation(rot);
+ kf->SetTranslation(trans);
+ kf->SetTime(fbuf[7]); // absolute time here
+ }else{
KeyFrameTrans *kf = (KeyFrameTrans*)seq->GetKeyFrame(l);
kf->rotation = rot;
kf->translation = trans;
kf->deltaTime = fbuf[7]; // absolute time here
- }else{
- CFileMgr::Read(fd, buf, 0x14);
- CQuaternion rot(fbuf[0], fbuf[1], fbuf[2], fbuf[3]);
- rot.Invert();
+ }
+ }else{
+ RwStreamRead(stream, buf, 0x14);
+ CQuaternion rot(fbuf[0], fbuf[1], fbuf[2], fbuf[3]);
+ rot.Invert();
+ if(compressHier){
+ KeyFrameCompressed *kf = (KeyFrameCompressed*)seq->GetKeyFrameCompressed(l);
+ kf->SetRotation(rot);
+ kf->SetTime(fbuf[4]); // absolute time here
+ }else{
KeyFrame *kf = (KeyFrame*)seq->GetKeyFrame(l);
kf->rotation = rot;
kf->deltaTime = fbuf[4]; // absolute time here
}
}
-
- // convert absolute time to deltas
- for(l = seq->numFrames-1; l > 0; l--){
- KeyFrame *kf1 = seq->GetKeyFrame(l);
- KeyFrame *kf2 = seq->GetKeyFrame(l-1);
- kf1->deltaTime -= kf2->deltaTime;
- }
}
+ }
+ if(!compressHier){
hier->RemoveQuaternionFlips();
- if(compress)
- hier->RemoveUncompressedData();
- else
- hier->CalcTotalTime();
+ hier->CalcTotalTime();
}
}
+ if(animIndex > ms_numAnimations)
+ ms_numAnimations = animIndex;
}
void
@@ -937,5 +1448,6 @@ CAnimManager::RemoveLastAnimFile(void)
ms_numAnimBlocks--;
ms_numAnimations = ms_aAnimBlocks[ms_numAnimBlocks].firstIndex;
for(i = 0; i < ms_aAnimBlocks[ms_numAnimBlocks].numAnims; i++)
- ms_aAnimations[ms_aAnimBlocks[ms_numAnimBlocks].firstIndex + i].RemoveAnimSequences();
+ ms_aAnimations[ms_aAnimBlocks[ms_numAnimBlocks].firstIndex + i].Shutdown();
+ ms_aAnimBlocks[ms_numAnimBlocks].isLoaded = false;
}
diff --git a/src/animation/AnimManager.h b/src/animation/AnimManager.h
index 92192c71..213326b6 100644
--- a/src/animation/AnimManager.h
+++ b/src/animation/AnimManager.h
@@ -6,24 +6,57 @@
enum AssocGroupId
{
ASSOCGRP_STD,
+ ASSOCGRP_VAN,
+ ASSOCGRP_COACH,
+ ASSOCGRP_BIKE_STANDARD,
+ ASSOCGRP_BIKE_VESPA,
+ ASSOCGRP_BIKE_HARLEY,
+ ASSOCGRP_BIKE_DIRT,
+ ASSOCGRP_UNARMED,
+ ASSOCGRP_SCREWDRIVER,
+ ASSOCGRP_KNIFE,
+ ASSOCGRP_BASEBALLBAT,
+ ASSOCGRP_GOLFCLUB,
+ ASSOCGRP_CHAINSAW,
+ ASSOCGRP_PYTHON,
+ ASSOCGRP_COLT,
+ ASSOCGRP_SHOTGUN,
+ ASSOCGRP_BUDDY,
+ ASSOCGRP_TEC,
+ ASSOCGRP_UZI,
+ ASSOCGRP_RIFLE,
+ ASSOCGRP_M60,
+ ASSOCGRP_SNIPER,
+ ASSOCGRP_THROW,
+ ASSOCGRP_FLAMETHROWER,
+ ASSOCGRP_MEDIC,
+ ASSOCGRP_SUNBATHE,
+ ASSOCGRP_PLAYER_IDLE,
+ ASSOCGRP_RIOT,
+ ASSOCGRP_STRIP,
+ ASSOCGRP_LANCE,
ASSOCGRP_PLAYER,
ASSOCGRP_PLAYERROCKET,
ASSOCGRP_PLAYER1ARMED,
ASSOCGRP_PLAYER2ARMED,
ASSOCGRP_PLAYERBBBAT,
+ ASSOCGRP_PLAYERCHAINSAW,
ASSOCGRP_SHUFFLE,
ASSOCGRP_OLD,
ASSOCGRP_GANG1,
ASSOCGRP_GANG2,
ASSOCGRP_FAT,
ASSOCGRP_OLDFAT,
+ ASSOCGRP_JOGGER,
ASSOCGRP_WOMAN,
ASSOCGRP_WOMANSHOP,
ASSOCGRP_BUSYWOMAN,
ASSOCGRP_SEXYWOMAN,
- ASSOCGRP_OLDWOMAN,
ASSOCGRP_FATWOMAN,
+ ASSOCGRP_OLDWOMAN,
+ ASSOCGRP_JOGWOMAN,
ASSOCGRP_PANICCHUNKY,
+ ASSOCGRP_SKATE,
#ifdef PC_PLAYER_CONTROLS
ASSOCGRP_PLAYERBACK,
ASSOCGRP_PLAYERLEFT,
@@ -31,6 +64,9 @@ enum AssocGroupId
ASSOCGRP_ROCKETBACK,
ASSOCGRP_ROCKETLEFT,
ASSOCGRP_ROCKETRIGHT,
+ ASSOCGRP_CHAINSAWBACK,
+ ASSOCGRP_CHAINSAWLEFT,
+ ASSOCGRP_CHAINSAWRIGHT,
#endif
NUM_ANIM_ASSOC_GROUPS
@@ -39,11 +75,15 @@ enum AssocGroupId
class CAnimBlendAssociation;
class CAnimBlendAssocGroup;
+#define MAX_ANIMBLOCK_NAME 20
+
// A block of hierarchies
struct CAnimBlock
{
- char name[24];
- int32 firstIndex;
+ char name[MAX_ANIMBLOCK_NAME];
+ bool isLoaded;
+ int16 refCount;
+ int32 firstIndex; // first animtion in ms_aAnimations
int32 numAnims;
};
@@ -77,7 +117,16 @@ public:
static void Initialise(void);
static void Shutdown(void);
static void UncompressAnimation(CAnimBlendHierarchy *anim);
+ static void RemoveFromUncompressedCache(CAnimBlendHierarchy *hier);
+ static CAnimBlock *GetAnimationBlock(int32 block) { return &ms_aAnimBlocks[block]; }
static CAnimBlock *GetAnimationBlock(const char *name);
+ static int32 GetAnimationBlockIndex(const char *name);
+ static int32 RegisterAnimBlock(const char *name);
+ static int32 GetNumRefsToAnimBlock(int32 block);
+ static void AddAnimBlockRef(int32 block);
+ static void RemoveAnimBlockRefWithoutDelete(int32 block);
+ static void RemoveAnimBlockRef(int32 block);
+ static void RemoveAnimBlock(int32 block);
static CAnimBlendHierarchy *GetAnimation(const char *name, CAnimBlock *animBlock);
static CAnimBlendHierarchy *GetAnimation(int32 n) { return &ms_aAnimations[n]; }
static const char *GetAnimGroupName(AssocGroupId groupId);
@@ -89,6 +138,8 @@ public:
static CAnimBlendAssociation *BlendAnimation(RpClump *clump, AssocGroupId groupId, AnimationId animId, float delta);
static void LoadAnimFiles(void);
static void LoadAnimFile(const char *filename);
- static void LoadAnimFile(int fd, bool compress);
+ static void LoadAnimFile(RwStream *stream, bool compress, char (*uncompressedAnims)[32] = nil);
+ static void CreateAnimAssocGroups(void);
static void RemoveLastAnimFile(void);
+ static CAnimBlendAssocGroup* GetAnimAssocGroups(void) { return ms_aAnimAssocGroups; }
};
diff --git a/src/animation/AnimationId.h b/src/animation/AnimationId.h
index baf6eb33..0b5d8d8e 100644
--- a/src/animation/AnimationId.h
+++ b/src/animation/AnimationId.h
@@ -42,9 +42,6 @@ enum AnimationId
ANIM_STD_HIT_FLOOR,
/* names made up */
-#if GTA_VERSION <= GTA3_PS2_160
- ANIM_STD_HIT_BODY,
-#endif
ANIM_STD_HIT_BODYBLOW,
ANIM_STD_HIT_CHEST,
ANIM_STD_HIT_HEAD,
@@ -54,42 +51,6 @@ enum AnimationId
ANIM_STD_HIT_WALL,
ANIM_STD_HIT_FLOOR_FRONT,
ANIM_STD_HIT_BEHIND,
- ANIM_STD_PUNCH,
- ANIM_STD_KICKGROUND,
-
- /* names made up */
- ANIM_STD_WEAPON_BAT_H,
- ANIM_STD_WEAPON_BAT_V,
- ANIM_STD_WEAPON_HGUN_BODY,
- ANIM_STD_WEAPON_AK_BODY,
- ANIM_STD_WEAPON_PUMP,
- ANIM_STD_WEAPON_SNIPER,
- ANIM_STD_WEAPON_THROW,
- /**/
-
- ANIM_STD_THROW_UNDER,
-
- /* names made up */
- ANIM_STD_START_THROW,
- /**/
-
- ANIM_STD_DETONATE,
-
- /* names made up */
- ANIM_STD_HGUN_RELOAD,
- ANIM_STD_AK_RELOAD,
-#ifdef PC_PLAYER_CONTROLS
- // maybe wrong define, but unused anyway
- ANIM_FPS_PUNCH,
- ANIM_FPS_BAT,
- ANIM_FPS_UZI,
- ANIM_FPS_PUMP,
- ANIM_FPS_AK,
- ANIM_FPS_M16,
- ANIM_FPS_ROCKET,
-#endif
- /**/
-
ANIM_STD_FIGHT_IDLE,
ANIM_STD_FIGHT_2IDLE,
ANIM_STD_FIGHT_SHUFFLE_F,
@@ -106,6 +67,23 @@ enum AnimationId
/**/
ANIM_STD_PARTIAL_PUNCH,
+
+ /* names made up */
+ ANIM_STD_FIGHT_JAB,
+ ANIM_STD_FIGHT_ELBOW_L,
+ ANIM_STD_FIGHT_ELBOW_R,
+ ANIM_STD_FIGHT_BKICK_L,
+ ANIM_STD_FIGHT_BKICK_R,
+ /**/
+
+ ANIM_STD_DETONATE,
+ ANIM_STD_PUNCH,
+ ANIM_STD_PARTIALPUNCH,
+ ANIM_STD_KICKGROUND,
+
+ ANIM_STD_THROW_UNDER,
+ ANIM_STD_FIGHT_SHUFFLE_B,
+
ANIM_STD_JACKEDCAR_RHS,
ANIM_STD_JACKEDCAR_LO_RHS,
ANIM_STD_JACKEDCAR_LHS,
@@ -124,6 +102,7 @@ enum AnimationId
ANIM_STD_CAR_CLOSE_DOOR_LO_LHS,
ANIM_STD_CAR_CLOSE_DOOR_ROLLING_LHS,
ANIM_STD_CAR_CLOSE_DOOR_ROLLING_LO_LHS,
+ ANIM_STD_CAR_JUMP_IN_LO_LHS,
ANIM_STD_GETOUT_LHS,
ANIM_STD_GETOUT_LO_LHS,
ANIM_STD_CAR_CLOSE_LHS,
@@ -149,29 +128,36 @@ enum AnimationId
ANIM_STD_CAR_DRIVE_RIGHT_LO,
ANIM_STD_CAR_DRIVEBY_LEFT,
ANIM_STD_CAR_DRIVEBY_RIGHT,
+ ANIM_STD_CAR_DRIVEBY_LEFT_LO,
+ ANIM_STD_CAR_DRIVEBY_RIGHT_LO,
ANIM_STD_CAR_LOOKBEHIND,
ANIM_STD_BOAT_DRIVE,
+ ANIM_STD_BOAT_DRIVE_LEFT,
+ ANIM_STD_BOAT_DRIVE_RIGHT,
+ ANIM_STD_BOAT_LOOKBEHIND,
+
+ ANIM_STD_BIKE_PICKUP_LHS,
+ ANIM_STD_BIKE_PICKUP_RHS,
+ ANIM_STD_BIKE_PULLUP_LHS,
+ ANIM_STD_BIKE_PULLUP_RHS,
+ ANIM_STD_BIKE_ELBOW_LHS,
+ ANIM_STD_BIKE_ELBOW_RHS,
+ ANIM_STD_BIKE_FALLOFF,
+ ANIM_STD_BIKE_FALLBACK,
+
ANIM_STD_GETOUT_RHS,
ANIM_STD_GETOUT_LO_RHS,
ANIM_STD_CAR_CLOSE_RHS,
ANIM_STD_CAR_HOOKERTALK,
- ANIM_STD_COACH_OPEN_LHS,
- ANIM_STD_COACH_OPEN_RHS,
- ANIM_STD_COACH_GET_IN_LHS,
- ANIM_STD_COACH_GET_IN_RHS,
- ANIM_STD_COACH_GET_OUT_LHS,
+
ANIM_STD_TRAIN_GETIN,
ANIM_STD_TRAIN_GETOUT,
+
ANIM_STD_CRAWLOUT_LHS,
ANIM_STD_CRAWLOUT_RHS,
- ANIM_STD_VAN_OPEN_DOOR_REAR_LHS,
- ANIM_STD_VAN_GET_IN_REAR_LHS,
- ANIM_STD_VAN_CLOSE_DOOR_REAR_LHS,
- ANIM_STD_VAN_GET_OUT_REAR_LHS,
- ANIM_STD_VAN_OPEN_DOOR_REAR_RHS,
- ANIM_STD_VAN_GET_IN_REAR_RHS,
- ANIM_STD_VAN_CLOSE_DOOR_REAR_RHS,
- ANIM_STD_VAN_GET_OUT_REAR_RHS,
+ ANIM_STD_ROLLOUT_LHS,
+ ANIM_STD_ROLLOUT_RHS,
+
ANIM_STD_GET_UP,
ANIM_STD_GET_UP_LEFT,
ANIM_STD_GET_UP_RIGHT,
@@ -183,6 +169,9 @@ enum AnimationId
ANIM_STD_FALL_GLIDE,
ANIM_STD_FALL_LAND,
ANIM_STD_FALL_COLLAPSE,
+ ANIM_STD_FALL_ONBACK,
+ ANIM_STD_FALL_ONFRONT,
+
ANIM_STD_EVADE_STEP,
ANIM_STD_EVADE_DIVE,
ANIM_STD_XPRESS_SCRATCH,
@@ -190,15 +179,12 @@ enum AnimationId
ANIM_STD_TURN180,
ANIM_STD_ARREST,
ANIM_STD_DROWN,
- ANIM_MEDIC_CPR,
ANIM_STD_DUCK_DOWN,
ANIM_STD_DUCK_LOW,
- ANIM_STD_RBLOCK_SHOOT,
- /* names made up */
- ANIM_STD_THROW_UNDER2,
- /**/
+ ANIM_STD_DUCK_WEAPON,
+ ANIM_STD_RBLOCK_SHOOT,
ANIM_STD_HANDSUP,
ANIM_STD_HANDSCOWER,
ANIM_STD_PARTIAL_FUCKU,
@@ -206,5 +192,96 @@ enum AnimationId
ANIM_STD_PHONE_OUT,
ANIM_STD_PHONE_TALK,
- ANIM_STD_NUM
+ ANIM_STD_SEAT_DOWN,
+ ANIM_STD_SEAT_UP,
+ ANIM_STD_SEAT_IDLE,
+ ANIM_STD_SEAT_RVRS,
+ ANIM_STD_ATM,
+ ANIM_STD_ABSEIL,
+
+ ANIM_STD_NUM,
+
+ ANIM_STD_VAN_OPEN_DOOR_REAR_LHS,
+ ANIM_STD_VAN_GET_IN_REAR_LHS,
+ ANIM_STD_VAN_CLOSE_DOOR_REAR_LHS,
+ ANIM_STD_VAN_GET_OUT_REAR_LHS,
+ ANIM_STD_VAN_OPEN_DOOR_REAR_RHS,
+ ANIM_STD_VAN_GET_IN_REAR_RHS,
+ ANIM_STD_VAN_CLOSE_DOOR_REAR_RHS,
+ ANIM_STD_VAN_GET_OUT_REAR_RHS,
+
+ ANIM_STD_COACH_OPEN_LHS,
+ ANIM_STD_COACH_OPEN_RHS,
+ ANIM_STD_COACH_GET_IN_LHS,
+ ANIM_STD_COACH_GET_IN_RHS,
+ ANIM_STD_COACH_GET_OUT_LHS,
+
+ ANIM_BIKE_RIDE,
+ ANIM_BIKE_READY,
+ ANIM_BIKE_LEFT,
+ ANIM_BIKE_RIGHT,
+ ANIM_BIKE_LEANB,
+ ANIM_BIKE_LEANF,
+ ANIM_BIKE_WALKBACK,
+ ANIM_BIKE_JUMPON_LHS,
+ ANIM_BIKE_JUMPON_RHS,
+ ANIM_BIKE_KICK,
+ ANIM_BIKE_HIT,
+ ANIM_BIKE_GETOFF_LHS,
+ ANIM_BIKE_GETOFF_RHS,
+ ANIM_BIKE_GETOFF_BACK,
+ ANIM_BIKE_DRIVEBY_LHS,
+ ANIM_BIKE_DRIVEBY_RHS,
+ ANIM_BIKE_DRIVEBY_FORWARD,
+ ANIM_BIKE_RIDE_P,
+
+ ANIM_ATTACK_1,
+ ANIM_ATTACK_2,
+ ANIM_ATTACK_EXTRA1,
+ ANIM_ATTACK_EXTRA2,
+ ANIM_ATTACK_3,
+
+ // our synonyms... because originals are hard to understand
+ ANIM_WEAPON_FIRE = ANIM_ATTACK_1,
+ ANIM_WEAPON_CROUCHFIRE,
+ ANIM_WEAPON_FIRE_2ND = ANIM_WEAPON_CROUCHFIRE,
+ ANIM_WEAPON_RELOAD,
+ ANIM_WEAPON_CROUCHRELOAD,
+ ANIM_WEAPON_FIRE_3RD,
+ ANIM_THROWABLE_THROW = ANIM_ATTACK_1,
+ ANIM_THROWABLE_THROWU,
+ ANIM_THROWABLE_START_THROW,
+ ANIM_MELEE_ATTACK = ANIM_ATTACK_1,
+ ANIM_MELEE_ATTACK_2ND,
+ ANIM_MELEE_ATTACK_START,
+ ANIM_MELEE_IDLE_FIGHTMODE,
+ ANIM_MELEE_ATTACK_FINISH,
+
+ ANIM_SUNBATHE_IDLE,
+ ANIM_SUNBATHE_DOWN,
+ ANIM_SUNBATHE_UP,
+ ANIM_SUNBATHE_ESCAPE,
+
+ ANIM_MEDIC_CPR,
+
+ ANIM_PLAYER_IDLE1,
+ ANIM_PLAYER_IDLE2,
+ ANIM_PLAYER_IDLE3,
+ ANIM_PLAYER_IDLE4,
+
+ ANIM_RIOT_ANGRY,
+ ANIM_RIOT_ANGRY_B,
+ ANIM_RIOT_CHANT,
+ ANIM_RIOT_PUNCHES,
+ ANIM_RIOT_SHOUT,
+ ANIM_RIOT_CHALLENGE,
+ ANIM_RIOT_FUCKYOU,
+
+ ANIM_STRIP_A,
+ ANIM_STRIP_B,
+ ANIM_STRIP_C,
+ ANIM_STRIP_D,
+ ANIM_STRIP_E,
+ ANIM_STRIP_F,
+ ANIM_STRIP_G,
}; \ No newline at end of file
diff --git a/src/animation/Bones.cpp b/src/animation/Bones.cpp
index 1608449d..87f3b6e7 100644
--- a/src/animation/Bones.cpp
+++ b/src/animation/Bones.cpp
@@ -2,26 +2,29 @@
#include "PedModelInfo.h"
#include "Bones.h"
-#ifdef PED_SKIN
-
int
ConvertPedNode2BoneTag(int node)
{
switch(node){
- case PED_TORSO: return BONE_waist;
- case PED_MID: return BONE_torso; // this is what Xbox/Mobile use
- // return BONE_mid; // this is what PS2/PC use
- case PED_HEAD: return BONE_head;
- case PED_UPPERARML: return BONE_upperarml;
- case PED_UPPERARMR: return BONE_upperarmr;
- case PED_HANDL: return BONE_Lhand;
- case PED_HANDR: return BONE_Rhand;
- case PED_UPPERLEGL: return BONE_upperlegl;
- case PED_UPPERLEGR: return BONE_upperlegr;
- case PED_FOOTL: return BONE_footl;
- case PED_FOOTR: return BONE_footr;
- case PED_LOWERLEGR: return BONE_lowerlegl;
+ case PED_MID: return BONE_spine1;
+ case PED_HEAD: return BONE_head;
+ case PED_UPPERARML: return BONE_l_upperarm;
+ case PED_UPPERARMR: return BONE_r_upperarm;
+ case PED_HANDL: return BONE_l_hand;
+ case PED_HANDR: return BONE_r_hand;
+ case PED_UPPERLEGL: return BONE_l_thigh;
+ case PED_UPPERLEGR: return BONE_r_thigh;
+ case PED_FOOTL: return BONE_l_foot;
+ case PED_FOOTR: return BONE_r_foot;
+ case PED_LOWERLEGR: return BONE_r_calf;
+ case PED_LOWERLEGL: return BONE_l_calf;
+ case PED_FOREARML: return BONE_l_forearm;
+ case PED_FOREARMR: return BONE_r_forearm;
+ case PED_CLAVICLEL: return BONE_l_clavicle;
+ case PED_CLAVICLER: return BONE_r_clavicle;
+ case PED_NECK: return BONE_neck;
}
+ assert(0 && "this node has no bone");
return -1;
}
@@ -29,24 +32,28 @@ const char*
ConvertBoneTag2BoneName(int tag)
{
switch(tag){
- case BONE_waist: return "Swaist";
- case BONE_upperlegr: return "Supperlegr";
- case BONE_lowerlegr: return "Slowerlegr";
- case BONE_footr: return "Sfootr";
- case BONE_upperlegl: return "Supperlegl";
- case BONE_lowerlegl: return "Slowerlegl";
- case BONE_footl: return "Sfootl";
- case BONE_mid: return "Smid";
- case BONE_torso: return "Storso";
- case BONE_head: return "Shead";
- case BONE_upperarmr: return "Supperarmr";
- case BONE_lowerarmr: return "Slowerarmr";
- case BONE_Rhand: return "SRhand";
- case BONE_upperarml: return "Supperarml";
- case BONE_lowerarml: return "Slowerarml";
- case BONE_Lhand: return "SLhand";
+ case BONE_root: return "Root";
+ case BONE_pelvis: return "Pelvis";
+ case BONE_spine: return "Spine";
+ case BONE_spine1: return "Spine1";
+ case BONE_neck: return "Neck";
+ case BONE_head: return "Head";
+ case BONE_r_clavicle: return "Bip01 R Clavicle";
+ case BONE_r_upperarm: return "R UpperArm";
+ case BONE_r_forearm: return "R Forearm";
+ case BONE_r_hand: return "R Hand";
+ case BONE_r_finger: return "R Fingers";
+ case BONE_l_clavicle: return "Bip01 L Clavicle";
+ case BONE_l_upperarm: return "L UpperArm";
+ case BONE_l_forearm: return "L Forearm";
+ case BONE_l_hand: return "L Hand";
+ case BONE_l_finger: return "L Fingers";
+ case BONE_l_thigh: return "L Thigh";
+ case BONE_l_calf: return "L Calf";
+ case BONE_l_foot: return "L Foot";
+ case BONE_r_thigh: return "R Thigh";
+ case BONE_r_calf: return "R Calf";
+ case BONE_r_foot: return "R Foot";
}
return nil;
}
-
-#endif
diff --git a/src/animation/Bones.h b/src/animation/Bones.h
index 38d91ba3..e133fd7f 100644
--- a/src/animation/Bones.h
+++ b/src/animation/Bones.h
@@ -2,22 +2,28 @@
enum BoneTag
{
- BONE_waist,
- BONE_upperlegr,
- BONE_lowerlegr,
- BONE_footr,
- BONE_upperlegl,
- BONE_lowerlegl,
- BONE_footl,
- BONE_mid,
- BONE_torso,
- BONE_head,
- BONE_upperarmr,
- BONE_lowerarmr,
- BONE_Rhand,
- BONE_upperarml,
- BONE_lowerarml,
- BONE_Lhand,
+ BONE_root = 0,
+ BONE_pelvis = 1,
+ BONE_spine = 2,
+ BONE_spine1 = 3,
+ BONE_neck = 4,
+ BONE_head = 5,
+ BONE_l_clavicle = 31,
+ BONE_l_upperarm = 32,
+ BONE_l_forearm = 33,
+ BONE_l_hand = 34,
+ BONE_l_finger = 35,
+ BONE_r_clavicle = 21,
+ BONE_r_upperarm = 22,
+ BONE_r_forearm = 23,
+ BONE_r_hand = 24,
+ BONE_r_finger = 25,
+ BONE_l_thigh = 41,
+ BONE_l_calf = 42,
+ BONE_l_foot = 43,
+ BONE_r_thigh = 51,
+ BONE_r_calf = 52,
+ BONE_r_foot = 53,
};
int ConvertPedNode2BoneTag(int node);
diff --git a/src/animation/CutsceneMgr.cpp b/src/animation/CutsceneMgr.cpp
index 83c4dbcb..633618b1 100644
--- a/src/animation/CutsceneMgr.cpp
+++ b/src/animation/CutsceneMgr.cpp
@@ -16,94 +16,92 @@
#include "World.h"
#include "PlayerPed.h"
#include "Wanted.h"
-#include "CutsceneHead.h"
#include "RpAnimBlend.h"
#include "ModelIndices.h"
#include "TempColModels.h"
+#include "ColStore.h"
+#include "Radar.h"
+#include "Pools.h"
const struct {
const char *szTrackName;
int iTrackId;
} musicNameIdAssoc[] = {
- { "JB", STREAMED_SOUND_NEWS_INTRO },
- { "BET", STREAMED_SOUND_BANK_INTRO },
- { "L1_LG", STREAMED_SOUND_CUTSCENE_LUIGI1_LG },
- { "L2_DSB", STREAMED_SOUND_CUTSCENE_LUIGI2_DSB },
- { "L3_DM", STREAMED_SOUND_CUTSCENE_LUIGI3_DM },
- { "L4_PAP", STREAMED_SOUND_CUTSCENE_LUIGI4_PAP },
- { "L5_TFB", STREAMED_SOUND_CUTSCENE_LUIGI5_TFB },
- { "J0_DM2", STREAMED_SOUND_CUTSCENE_JOEY0_DM2 },
- { "J1_LFL", STREAMED_SOUND_CUTSCENE_JOEY1_LFL },
- { "J2_KCL", STREAMED_SOUND_CUTSCENE_JOEY2_KCL },
- { "J3_VH", STREAMED_SOUND_CUTSCENE_JOEY3_VH },
- { "J4_ETH", STREAMED_SOUND_CUTSCENE_JOEY4_ETH },
- { "J5_DST", STREAMED_SOUND_CUTSCENE_JOEY5_DST },
- { "J6_TBJ", STREAMED_SOUND_CUTSCENE_JOEY6_TBJ },
- { "T1_TOL", STREAMED_SOUND_CUTSCENE_TONI1_TOL },
- { "T2_TPU", STREAMED_SOUND_CUTSCENE_TONI2_TPU },
- { "T3_MAS", STREAMED_SOUND_CUTSCENE_TONI3_MAS },
- { "T4_TAT", STREAMED_SOUND_CUTSCENE_TONI4_TAT },
- { "T5_BF", STREAMED_SOUND_CUTSCENE_TONI5_BF },
- { "S0_MAS", STREAMED_SOUND_CUTSCENE_SAL0_MAS },
- { "S1_PF", STREAMED_SOUND_CUTSCENE_SAL1_PF },
- { "S2_CTG", STREAMED_SOUND_CUTSCENE_SAL2_CTG },
- { "S3_RTC", STREAMED_SOUND_CUTSCENE_SAL3_RTC },
- { "S5_LRQ", STREAMED_SOUND_CUTSCENE_SAL5_LRQ },
- { "S4_BDBA", STREAMED_SOUND_CUTSCENE_SAL4_BDBA },
- { "S4_BDBB", STREAMED_SOUND_CUTSCENE_SAL4_BDBB },
- { "S2_CTG2", STREAMED_SOUND_CUTSCENE_SAL2_CTG2 },
- { "S4_BDBD", STREAMED_SOUND_CUTSCENE_SAL4_BDBD },
- { "S5_LRQB", STREAMED_SOUND_CUTSCENE_SAL5_LRQB },
- { "S5_LRQC", STREAMED_SOUND_CUTSCENE_SAL5_LRQC },
- { "A1_SS0", STREAMED_SOUND_CUTSCENE_ASUKA_1_SSO },
- { "A2_PP", STREAMED_SOUND_CUTSCENE_ASUKA_2_PP },
- { "A3_SS", STREAMED_SOUND_CUTSCENE_ASUKA_3_SS },
- { "A4_PDR", STREAMED_SOUND_CUTSCENE_ASUKA_4_PDR },
- { "A5_K2FT", STREAMED_SOUND_CUTSCENE_ASUKA_5_K2FT},
- { "K1_KBO", STREAMED_SOUND_CUTSCENE_KENJI1_KBO },
- { "K2_GIS", STREAMED_SOUND_CUTSCENE_KENJI2_GIS },
- { "K3_DS", STREAMED_SOUND_CUTSCENE_KENJI3_DS },
- { "K4_SHI", STREAMED_SOUND_CUTSCENE_KENJI4_SHI },
- { "K5_SD", STREAMED_SOUND_CUTSCENE_KENJI5_SD },
- { "R0_PDR2", STREAMED_SOUND_CUTSCENE_RAY0_PDR2 },
- { "R1_SW", STREAMED_SOUND_CUTSCENE_RAY1_SW },
- { "R2_AP", STREAMED_SOUND_CUTSCENE_RAY2_AP },
- { "R3_ED", STREAMED_SOUND_CUTSCENE_RAY3_ED },
- { "R4_GF", STREAMED_SOUND_CUTSCENE_RAY4_GF },
- { "R5_PB", STREAMED_SOUND_CUTSCENE_RAY5_PB },
- { "R6_MM", STREAMED_SOUND_CUTSCENE_RAY6_MM },
- { "D1_STOG", STREAMED_SOUND_CUTSCENE_DONALD1_STOG },
- { "D2_KK", STREAMED_SOUND_CUTSCENE_DONALD2_KK },
- { "D3_ADO", STREAMED_SOUND_CUTSCENE_DONALD3_ADO },
- { "D5_ES", STREAMED_SOUND_CUTSCENE_DONALD5_ES },
- { "D7_MLD", STREAMED_SOUND_CUTSCENE_DONALD7_MLD },
- { "D4_GTA", STREAMED_SOUND_CUTSCENE_DONALD4_GTA },
- { "D4_GTA2", STREAMED_SOUND_CUTSCENE_DONALD4_GTA2 },
- { "D6_STS", STREAMED_SOUND_CUTSCENE_DONALD6_STS },
- { "A6_BAIT", STREAMED_SOUND_CUTSCENE_ASUKA6_BAIT },
- { "A7_ETG", STREAMED_SOUND_CUTSCENE_ASUKA7_ETG },
- { "A8_PS", STREAMED_SOUND_CUTSCENE_ASUKA8_PS },
- { "A9_ASD", STREAMED_SOUND_CUTSCENE_ASUKA9_ASD },
- { "K4_SHI2", STREAMED_SOUND_CUTSCENE_KENJI4_SHI2 },
- { "C1_TEX", STREAMED_SOUND_CUTSCENE_CATALINA1_TEX },
- { "EL_PH1", STREAMED_SOUND_CUTSCENE_ELBURRO1_PH1 },
- { "EL_PH2", STREAMED_SOUND_CUTSCENE_ELBURRO2_PH2 },
- { "EL_PH3", STREAMED_SOUND_CUTSCENE_ELBURRO3_PH3 },
- { "EL_PH4", STREAMED_SOUND_CUTSCENE_ELBURRO4_PH4 },
- { "YD_PH1", STREAMED_SOUND_CUTSCENE_YARDIE_PH1 },
- { "YD_PH2", STREAMED_SOUND_CUTSCENE_YARDIE_PH2 },
- { "YD_PH3", STREAMED_SOUND_CUTSCENE_YARDIE_PH3 },
- { "YD_PH4", STREAMED_SOUND_CUTSCENE_YARDIE_PH4 },
- { "HD_PH1", STREAMED_SOUND_CUTSCENE_HOODS_PH1 },
- { "HD_PH2", STREAMED_SOUND_CUTSCENE_HOODS_PH2 },
- { "HD_PH3", STREAMED_SOUND_CUTSCENE_HOODS_PH3 },
- { "HD_PH4", STREAMED_SOUND_CUTSCENE_HOODS_PH4 },
- { "HD_PH5", STREAMED_SOUND_CUTSCENE_HOODS_PH5 },
- { "MT_PH1", STREAMED_SOUND_CUTSCENE_MARTY_PH1 },
- { "MT_PH2", STREAMED_SOUND_CUTSCENE_MARTY_PH2 },
- { "MT_PH3", STREAMED_SOUND_CUTSCENE_MARTY_PH3 },
- { "MT_PH4", STREAMED_SOUND_CUTSCENE_MARTY_PH4 },
- { NULL, 0 }
+ { "ASS_1", STREAMED_SOUND_CUTSCENE_ASS_1 },
+ { "ASS_2", STREAMED_SOUND_CUTSCENE_ASS_2 },
+ { "BANK_1", STREAMED_SOUND_CUTSCENE_BANK_1 },
+ { "BANK_2A", STREAMED_SOUND_CUTSCENE_BANK_2A },
+ { "BANK_2B", STREAMED_SOUND_CUTSCENE_BANK_2B },
+ { "BANK_3A", STREAMED_SOUND_CUTSCENE_BANK_3A },
+ { "BANK_3B", STREAMED_SOUND_CUTSCENE_BANK_3B },
+ { "BANK_4", STREAMED_SOUND_CUTSCENE_BANK_4 },
+ { "BIKE_1", STREAMED_SOUND_CUTSCENE_BIKE_1 },
+ { "BIKE_2", STREAMED_SOUND_CUTSCENE_BIKE_2 },
+ { "BIKE_3", STREAMED_SOUND_CUTSCENE_BIKE_3 },
+ { "BUD_1", STREAMED_SOUND_CUTSCENE_BUD_1 },
+ { "BUD_2", STREAMED_SOUND_CUTSCENE_BUD_2 },
+ { "BUD_3", STREAMED_SOUND_CUTSCENE_BUD_3 },
+ { "CAP_1", STREAMED_SOUND_CUTSCENE_CAP_1 },
+ { "CAR_1", STREAMED_SOUND_CUTSCENE_CAR_1 },
+ { "CNT_1A", STREAMED_SOUND_CUTSCENE_CNT_1A },
+ { "CNT_1B", STREAMED_SOUND_CUTSCENE_CNT_1B },
+ { "CNT_2", STREAMED_SOUND_CUTSCENE_CNT_2 },
+ { "COK_1", STREAMED_SOUND_CUTSCENE_COK_1 },
+ { "COK_2A", STREAMED_SOUND_CUTSCENE_COK_2A },
+ { "COK_2B", STREAMED_SOUND_CUTSCENE_COK_2B },
+ { "COK_3", STREAMED_SOUND_CUTSCENE_COK_3 },
+ { "COK_4A", STREAMED_SOUND_CUTSCENE_COK_4A },
+ { "COK_4A2", STREAMED_SOUND_CUTSCENE_COK_4A2 },
+ { "COK_4B", STREAMED_SOUND_CUTSCENE_COK_4B },
+ { "COL_1", STREAMED_SOUND_CUTSCENE_COL_1 },
+ { "COL_2", STREAMED_SOUND_CUTSCENE_COL_2 },
+ { "COL_3A", STREAMED_SOUND_CUTSCENE_COL_3A },
+ { "COL_4A", STREAMED_SOUND_CUTSCENE_COL_4A },
+ { "COL_5A", STREAMED_SOUND_CUTSCENE_COL_5A },
+ { "COL_5B", STREAMED_SOUND_CUTSCENE_COL_5B },
+ { "CUB_1", STREAMED_SOUND_CUTSCENE_CUB_1 },
+ { "CUB_2", STREAMED_SOUND_CUTSCENE_CUB_2 },
+ { "CUB_3", STREAMED_SOUND_CUTSCENE_CUB_3 },
+ { "CUB_4", STREAMED_SOUND_CUTSCENE_CUB_4 },
+ { "DRUG_1", STREAMED_SOUND_CUTSCENE_DRUG_1 },
+ { "FIN", STREAMED_SOUND_CUTSCENE_FIN },
+ { "FIN_2", STREAMED_SOUND_CUTSCENE_FIN2 },
+ { "FINALE", STREAMED_SOUND_CUTSCENE_FINALE },
+ { "HAT_1", STREAMED_SOUND_CUTSCENE_HAT_1 },
+ { "HAT_2", STREAMED_SOUND_CUTSCENE_HAT_2 },
+ { "HAT_3", STREAMED_SOUND_CUTSCENE_HAT_3 },
+ { "ICE_1", STREAMED_SOUND_CUTSCENE_ICE_1 },
+ { "INT_A", STREAMED_SOUND_CUTSCENE_INT_A },
+ { "INT_B", STREAMED_SOUND_CUTSCENE_INT_B },
+ { "INT_D", STREAMED_SOUND_CUTSCENE_INT_D },
+ { "INT_M", STREAMED_SOUND_CUTSCENE_INT_M },
+ { "LAW_1A", STREAMED_SOUND_CUTSCENE_LAW_1A },
+ { "LAW_1B", STREAMED_SOUND_CUTSCENE_LAW_1B },
+ { "LAW_2A", STREAMED_SOUND_CUTSCENE_LAW_2A },
+ { "LAW_2B", STREAMED_SOUND_CUTSCENE_LAW_2B },
+ { "LAW_2C", STREAMED_SOUND_CUTSCENE_LAW_2C },
+ { "LAW_3", STREAMED_SOUND_CUTSCENE_LAW_3 },
+ { "LAW_4", STREAMED_SOUND_CUTSCENE_LAW_4 },
+ { "PHIL_1", STREAMED_SOUND_CUTSCENE_PHIL_1 },
+ { "PHIL_2", STREAMED_SOUND_CUTSCENE_PHIL_2 },
+ { "PORN_1", STREAMED_SOUND_CUTSCENE_PORN_1 },
+ { "PORN_2", STREAMED_SOUND_CUTSCENE_PORN_2 },
+ { "PORN_3", STREAMED_SOUND_CUTSCENE_PORN_3 },
+ { "PORN_4", STREAMED_SOUND_CUTSCENE_PORN_4 },
+ { "RESC_1A", STREAMED_SOUND_CUTSCENE_RESC_1A },
+ { "ROK_1", STREAMED_SOUND_CUTSCENE_ROK_1 },
+ { "ROK_2", STREAMED_SOUND_CUTSCENE_ROK_2 },
+ { "ROK_3A", STREAMED_SOUND_CUTSCENE_ROK_3A },
+ { "STRIPA", STREAMED_SOUND_CUTSCENE_STRIPA },
+ { "TAX_1", STREAMED_SOUND_CUTSCENE_TAX_1 },
+ { "TEX_1", STREAMED_SOUND_CUTSCENE_TEX_1 },
+ { "TEX_2", STREAMED_SOUND_CUTSCENE_TEX_2 },
+ { "TEX_3", STREAMED_SOUND_CUTSCENE_TEX_3 },
+ { "GSPOT", STREAMED_SOUND_CUTSCENE_GLIGHT },
+ { "FIST", STREAMED_SOUND_CUTSCENE_FIST },
+ { "EL_PH1", STREAMED_SOUND_CUTSCENE_ELBURRO1_PH1 },
+ { "EL_PH2", STREAMED_SOUND_CUTSCENE_ELBURRO2_PH2 },
+ { NULL, 0 }
};
int
@@ -128,7 +126,18 @@ char CCutsceneMgr::ms_cutsceneName[CUTSCENENAMESIZE];
CAnimBlendAssocGroup CCutsceneMgr::ms_cutsceneAssociations;
CVector CCutsceneMgr::ms_cutsceneOffset;
float CCutsceneMgr::ms_cutsceneTimer;
+bool CCutsceneMgr::ms_wasCutsceneSkipped;
uint32 CCutsceneMgr::ms_cutsceneLoadStatus;
+bool CCutsceneMgr::ms_useCutsceneShadows = true;
+
+bool bCamLoaded;
+bool bIsEverythingRemovedFromTheWorldForTheBiggestFuckoffCutsceneEver; // pls don't shrink the name :P
+int32 NumberOfSavedWeapons;
+eWeaponType SavedWeaponIDs[TOTAL_WEAPON_SLOTS];
+int32 SavedWeaponAmmo[TOTAL_WEAPON_SLOTS];
+char uncompressedAnims[8][32];
+uint32 numUncompressedAnims;
+
RpAtomic *
CalculateBoundingSphereRadiusCB(RpAtomic *atomic, void *data)
@@ -150,13 +159,17 @@ CCutsceneMgr::Initialise(void)
{
ms_numCutsceneObjs = 0;
ms_loaded = false;
+ ms_wasCutsceneSkipped = false;
ms_running = false;
+ ms_useLodMultiplier = false;
ms_animLoaded = false;
ms_cutsceneProcessing = false;
- ms_useLodMultiplier = false;
ms_pCutsceneDir = new CDirectory(CUTSCENEDIRSIZE);
ms_pCutsceneDir->ReadDirFile("ANIM\\CUTS.DIR");
+
+ numUncompressedAnims = 0;
+ uncompressedAnims[0][0] = '\0';
}
void
@@ -174,9 +187,10 @@ CCutsceneMgr::LoadCutsceneData(const char *szCutsceneName)
CPlayerPed *pPlayerPed;
ms_cutsceneProcessing = true;
- if (!strcasecmp(szCutsceneName, "jb"))
- ms_useLodMultiplier = true;
- CTimer::Stop();
+ ms_wasCutsceneSkipped = false;
+ CTimer::Suspend();
+ if (!bIsEverythingRemovedFromTheWorldForTheBiggestFuckoffCutsceneEver)
+ CStreaming::RemoveCurrentZonesModels();
ms_pCutsceneDir->numEntries = 0;
ms_pCutsceneDir->ReadDirFile("ANIM\\CUTS.DIR");
@@ -185,32 +199,42 @@ CCutsceneMgr::LoadCutsceneData(const char *szCutsceneName)
CGame::DrasticTidyUpMemory(true);
strcpy(ms_cutsceneName, szCutsceneName);
- file = CFileMgr::OpenFile("ANIM\\CUTS.IMG", "rb");
+
+ RwStream *stream;
+ stream = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMREAD, "ANIM\\CUTS.IMG");
+ assert(stream);
// Load animations
sprintf(gString, "%s.IFP", szCutsceneName);
if (ms_pCutsceneDir->FindItem(gString, offset, size)) {
CStreaming::MakeSpaceFor(size << 11);
CStreaming::ImGonnaUseStreamingMemory();
- CFileMgr::Seek(file, offset << 11, SEEK_SET);
- CAnimManager::LoadAnimFile(file, false);
+ RwStreamSkip(stream, offset << 11);
+ CAnimManager::LoadAnimFile(stream, true, uncompressedAnims);
ms_cutsceneAssociations.CreateAssociations(szCutsceneName);
CStreaming::IHaveUsedStreamingMemory();
ms_animLoaded = true;
} else {
ms_animLoaded = false;
}
+ RwStreamClose(stream, nil);
// Load camera data
+ file = CFileMgr::OpenFile("ANIM\\CUTS.IMG", "rb");
sprintf(gString, "%s.DAT", szCutsceneName);
if (ms_pCutsceneDir->FindItem(gString, offset, size)) {
+ CStreaming::ImGonnaUseStreamingMemory();
CFileMgr::Seek(file, offset << 11, SEEK_SET);
TheCamera.LoadPathSplines(file);
+ CStreaming::IHaveUsedStreamingMemory();
+ bCamLoaded = true;
+ } else {
+ bCamLoaded = false;
}
CFileMgr::CloseFile(file);
- if (CGeneral::faststricmp(ms_cutsceneName, "end")) {
+ if (CGeneral::faststricmp(ms_cutsceneName, "finale")) {
DMAudio.ChangeMusicMode(MUSICMODE_CUTSCENE);
int trackId = FindCutsceneAudioTrackId(szCutsceneName);
if (trackId != -1) {
@@ -225,30 +249,23 @@ CCutsceneMgr::LoadCutsceneData(const char *szCutsceneName)
ms_cutsceneOffset = CVector(0.0f, 0.0f, 0.0f);
pPlayerPed = FindPlayerPed();
- CTimer::Update();
-
pPlayerPed->m_pWanted->ClearQdCrimes();
pPlayerPed->bIsVisible = false;
pPlayerPed->m_fCurrentStamina = pPlayerPed->m_fMaxStamina;
CPad::GetPad(0)->SetDisablePlayerControls(PLAYERCONTROL_CUTSCENE);
CWorld::Players[CWorld::PlayerInFocus].MakePlayerSafe(true);
-}
-
-void
-CCutsceneMgr::SetHeadAnim(const char *animName, CObject *pObject)
-{
- CCutsceneHead *pCutsceneHead = (CCutsceneHead*)pObject;
- char szAnim[CUTSCENENAMESIZE * 2];
- sprintf(szAnim, "%s_%s", ms_cutsceneName, animName);
- pCutsceneHead->PlayAnimation(szAnim);
+ CTimer::Resume();
}
void
CCutsceneMgr::FinishCutscene()
{
- CCutsceneMgr::ms_cutsceneTimer = TheCamera.GetCutSceneFinishTime() * 0.001f;
- TheCamera.FinishCutscene();
+ ms_wasCutsceneSkipped = true;
+ if (bCamLoaded) {
+ CCutsceneMgr::ms_cutsceneTimer = TheCamera.GetCutSceneFinishTime() * 0.001f;
+ TheCamera.FinishCutscene();
+ }
FindPlayerPed()->bIsVisible = true;
CWorld::Players[CWorld::PlayerInFocus].MakePlayerSafe(false);
@@ -257,9 +274,11 @@ CCutsceneMgr::FinishCutscene()
void
CCutsceneMgr::SetupCutsceneToStart(void)
{
- TheCamera.SetCamCutSceneOffSet(ms_cutsceneOffset);
- TheCamera.TakeControlWithSpline(JUMP_CUT);
- TheCamera.SetWideScreenOn();
+ if (bCamLoaded) {
+ TheCamera.SetCamCutSceneOffSet(ms_cutsceneOffset);
+ TheCamera.TakeControlWithSpline(JUMP_CUT);
+ TheCamera.SetWideScreenOn();
+ }
ms_cutsceneOffset.z++;
@@ -267,12 +286,27 @@ CCutsceneMgr::SetupCutsceneToStart(void)
assert(RwObjectGetType(ms_pCutsceneObjects[i]->m_rwObject) == rpCLUMP);
if (CAnimBlendAssociation *pAnimBlendAssoc = RpAnimBlendClumpGetFirstAssociation((RpClump*)ms_pCutsceneObjects[i]->m_rwObject)) {
assert(pAnimBlendAssoc->hierarchy->sequences[0].HasTranslation());
- ms_pCutsceneObjects[i]->SetPosition(ms_cutsceneOffset + ((KeyFrameTrans*)pAnimBlendAssoc->hierarchy->sequences[0].GetKeyFrame(0))->translation);
- CWorld::Add(ms_pCutsceneObjects[i]);
+ if (ms_pCutsceneObjects[i]->m_pAttachTo != nil) {
+ pAnimBlendAssoc->flags &= (~ASSOC_HAS_TRANSLATION);
+ } else {
+ if (pAnimBlendAssoc->hierarchy->IsCompressed()){
+ KeyFrameTransCompressed *keyFrames = ((KeyFrameTransCompressed*)pAnimBlendAssoc->hierarchy->sequences[0].GetKeyFrameCompressed(0));
+ CVector trans;
+ keyFrames->GetTranslation(&trans);
+ ms_pCutsceneObjects[i]->SetPosition(ms_cutsceneOffset + trans);
+ }else{
+ KeyFrameTrans *keyFrames = ((KeyFrameTrans*)pAnimBlendAssoc->hierarchy->sequences[0].GetKeyFrame(0));
+ ms_pCutsceneObjects[i]->SetPosition(ms_cutsceneOffset + keyFrames->translation);
+ }
+ }
pAnimBlendAssoc->SetRun();
} else {
ms_pCutsceneObjects[i]->SetPosition(ms_cutsceneOffset);
}
+ CWorld::Add(ms_pCutsceneObjects[i]);
+ if (RwObjectGetType(ms_pCutsceneObjects[i]->m_rwObject) == rpCLUMP) {
+ ms_pCutsceneObjects[i]->UpdateRpHAnim();
+ }
}
CTimer::Update();
@@ -288,25 +322,55 @@ CCutsceneMgr::SetCutsceneAnim(const char *animName, CObject *pObject)
CAnimBlendClumpData *pAnimBlendClumpData;
assert(RwObjectGetType(pObject->m_rwObject) == rpCLUMP);
+ debug("Give cutscene anim %s\n", animName);
RpAnimBlendClumpRemoveAllAssociations((RpClump*)pObject->m_rwObject);
+ pNewAnim = ms_cutsceneAssociations.GetAnimation(animName);
+ if (!pNewAnim) {
+ debug("\n\nHaven't I told you I can't find the fucking animation %s\n\n\n", animName);
+ return;
+ }
+
+ if (pNewAnim->hierarchy->IsCompressed())
+ pNewAnim->hierarchy->keepCompressed = true;
+
+ CStreaming::ImGonnaUseStreamingMemory();
pNewAnim = ms_cutsceneAssociations.CopyAnimation(animName);
+ CStreaming::IHaveUsedStreamingMemory();
+
pNewAnim->SetCurrentTime(0.0f);
pNewAnim->flags |= ASSOC_HAS_TRANSLATION;
pNewAnim->flags &= ~ASSOC_RUNNING;
pAnimBlendClumpData = *RPANIMBLENDCLUMPDATA(pObject->m_rwObject);
pAnimBlendClumpData->link.Prepend(&pNewAnim->link);
+
+ if (pNewAnim->hierarchy->keepCompressed)
+ pAnimBlendClumpData->frames->flag |= AnimBlendFrameData::COMPRESSED;
+}
+
+void
+CCutsceneMgr::SetCutsceneAnimToLoop(const char* animName)
+{
+ ms_cutsceneAssociations.GetAnimation(animName)->flags |= ASSOC_REPEAT;
}
CCutsceneHead *
CCutsceneMgr::AddCutsceneHead(CObject *pObject, int modelId)
{
- CCutsceneHead *pHead = new CCutsceneHead(pObject);
- pHead->SetModelIndex(modelId);
- CWorld::Add(pHead);
- ms_pCutsceneObjects[ms_numCutsceneObjs++] = pHead;
- return pHead;
+ return nil;
+}
+
+void UpdateCutsceneObjectBoundingBox(RpClump* clump, int modelId)
+{
+ if (modelId >= MI_CUTOBJ01 && modelId <= MI_CUTOBJ05) {
+ CColModel* pColModel = &CTempColModels::ms_colModelCutObj[modelId - MI_CUTOBJ01];
+ float radius = 0.0f;
+ RpClumpForAllAtomics(clump, CalculateBoundingSphereRadiusCB, &radius);
+ pColModel->boundingSphere.radius = radius;
+ pColModel->boundingBox.min = CVector(-radius, -radius, -radius);
+ pColModel->boundingBox.max = CVector(radius, radius, radius);
+ }
}
CCutsceneObject *
@@ -314,20 +378,25 @@ CCutsceneMgr::CreateCutsceneObject(int modelId)
{
CBaseModelInfo *pModelInfo;
CColModel *pColModel;
- float radius;
- RpClump *clump;
CCutsceneObject *pCutsceneObject;
+ CStreaming::ImGonnaUseStreamingMemory();
+ debug("Created cutscene object %s\n", CModelInfo::GetModelInfo(modelId)->GetModelName());
if (modelId >= MI_CUTOBJ01 && modelId <= MI_CUTOBJ05) {
pModelInfo = CModelInfo::GetModelInfo(modelId);
pColModel = &CTempColModels::ms_colModelCutObj[modelId - MI_CUTOBJ01];
- radius = 0.0f;
-
pModelInfo->SetColModel(pColModel);
- clump = (RpClump*)pModelInfo->GetRwObject();
- assert(RwObjectGetType((RwObject*)clump) == rpCLUMP);
- RpClumpForAllAtomics(clump, CalculateBoundingSphereRadiusCB, &radius);
-
+ UpdateCutsceneObjectBoundingBox((RpClump*)pModelInfo->GetRwObject(), modelId);
+ } else if (modelId >= MI_SPECIAL01 && modelId <= MI_SPECIAL21) {
+ pModelInfo = CModelInfo::GetModelInfo(modelId);
+ if (pModelInfo->GetColModel() == &CTempColModels::ms_colModelPed1) {
+ CColModel *colModel = new CColModel();
+ colModel->boundingSphere.radius = 2.0f;
+ colModel->boundingSphere.center = CVector(0.0f, 0.0f, 0.0f);
+ pModelInfo->SetColModel(colModel, true);
+ }
+ pColModel = pModelInfo->GetColModel();
+ float radius = 2.0f;
pColModel->boundingSphere.radius = radius;
pColModel->boundingBox.min = CVector(-radius, -radius, -radius);
pColModel->boundingBox.max = CVector(radius, radius, radius);
@@ -335,7 +404,10 @@ CCutsceneMgr::CreateCutsceneObject(int modelId)
pCutsceneObject = new CCutsceneObject();
pCutsceneObject->SetModelIndex(modelId);
+ if (ms_useCutsceneShadows)
+ pCutsceneObject->CreateShadow();
ms_pCutsceneObjects[ms_numCutsceneObjs++] = pCutsceneObject;
+ CStreaming::IHaveUsedStreamingMemory();
return pCutsceneObject;
}
@@ -343,9 +415,11 @@ void
CCutsceneMgr::DeleteCutsceneData(void)
{
if (!ms_loaded) return;
+ CTimer::Suspend();
ms_cutsceneProcessing = false;
ms_useLodMultiplier = false;
+ ms_useCutsceneShadows = true;
for (--ms_numCutsceneObjs; ms_numCutsceneObjs >= 0; ms_numCutsceneObjs--) {
CWorld::Remove(ms_pCutsceneObjects[ms_numCutsceneObjs]);
@@ -355,12 +429,27 @@ CCutsceneMgr::DeleteCutsceneData(void)
}
ms_numCutsceneObjs = 0;
+ for (int i = MI_SPECIAL01; i < MI_SPECIAL21; i++) {
+ CBaseModelInfo *minfo = CModelInfo::GetModelInfo(i);
+ CColModel *colModel = minfo->GetColModel();
+ if (colModel != &CTempColModels::ms_colModelPed1) {
+ delete colModel;
+ minfo->SetColModel(&CTempColModels::ms_colModelPed1);
+ }
+ }
+
if (ms_animLoaded)
CAnimManager::RemoveLastAnimFile();
ms_animLoaded = false;
- TheCamera.RestoreWithJumpCut();
- TheCamera.SetWideScreenOff();
+ numUncompressedAnims = 0;
+ uncompressedAnims[0][0] = '\0';
+
+ if (bCamLoaded) {
+ TheCamera.RestoreWithJumpCut();
+ TheCamera.SetWideScreenOff();
+ TheCamera.DeleteCutSceneCamDataMemory();
+ }
ms_running = false;
ms_loaded = false;
@@ -368,14 +457,42 @@ CCutsceneMgr::DeleteCutsceneData(void)
CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_CUTSCENE);
CWorld::Players[CWorld::PlayerInFocus].MakePlayerSafe(false);
- if (CGeneral::faststricmp(ms_cutsceneName, "end")) {
+ if (CGeneral::faststricmp(ms_cutsceneName, "finale")) {
DMAudio.StopCutSceneMusic();
- if (CGeneral::faststricmp(ms_cutsceneName, "bet"))
- DMAudio.ChangeMusicMode(MUSICMODE_GAME);
+ DMAudio.ChangeMusicMode(MUSICMODE_GAME);
}
- CTimer::Stop();
- CGame::DrasticTidyUpMemory(TheCamera.GetScreenFadeStatus() == FADE_2);
- CTimer::Update();
+
+ CStreaming::ms_disableStreaming = false;
+ CWorld::bProcessCutsceneOnly = false;
+
+ if(bCamLoaded)
+ CGame::DrasticTidyUpMemory(TheCamera.GetScreenFadeStatus() == FADE_2);
+
+ CPad::GetPad(0)->Clear(false);
+ if (bIsEverythingRemovedFromTheWorldForTheBiggestFuckoffCutsceneEver) {
+ CStreaming::LoadInitialPeds();
+ CStreaming::LoadInitialWeapons();
+ CStreaming::LoadInitialVehicles();
+ bIsEverythingRemovedFromTheWorldForTheBiggestFuckoffCutsceneEver = false;
+
+ CPlayerPed *pPlayerPed = FindPlayerPed();
+ for (int i = 0; i < NumberOfSavedWeapons; i++) {
+ int32 weaponModelId = CWeaponInfo::GetWeaponInfo(SavedWeaponIDs[i])->m_nModelId;
+ uint8 flags = CStreaming::ms_aInfoForModel[weaponModelId].m_flags;
+ CStreaming::RequestModel(weaponModelId, STREAMFLAGS_DONT_REMOVE);
+ CStreaming::LoadAllRequestedModels(false);
+ if (CWeaponInfo::GetWeaponInfo(SavedWeaponIDs[i])->m_nModel2Id != -1) {
+ CStreaming::RequestModel(CWeaponInfo::GetWeaponInfo(SavedWeaponIDs[i])->m_nModel2Id, 0);
+ CStreaming::LoadAllRequestedModels(false);
+ }
+ if (!(flags & STREAMFLAGS_DONT_REMOVE))
+ CStreaming::SetModelIsDeletable(weaponModelId);
+ pPlayerPed->GiveWeapon(SavedWeaponIDs[i], SavedWeaponAmmo[i], true);
+ }
+ NumberOfSavedWeapons = 0;
+ }
+
+ CTimer::Resume();
}
void
@@ -392,7 +509,7 @@ CCutsceneMgr::Update(void)
switch (ms_cutsceneLoadStatus) {
case CUTSCENE_LOADING_AUDIO:
SetupCutsceneToStart();
- if (CGeneral::faststricmp(ms_cutsceneName, "end"))
+ if (CGeneral::faststricmp(ms_cutsceneName, "finale"))
DMAudio.PlayPreloadedCutSceneMusic();
ms_cutsceneLoadStatus++;
break;
@@ -410,15 +527,157 @@ CCutsceneMgr::Update(void)
if (!ms_running) return;
ms_cutsceneTimer += CTimer::GetTimeStepNonClippedInSeconds();
- if (CGeneral::faststricmp(ms_cutsceneName, "end") && TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_FLYBY && ms_cutsceneLoadStatus == CUTSCENE_LOADING_0) {
- if (CPad::GetPad(0)->GetCrossJustDown()
- || (CGame::playingIntro && CPad::GetPad(0)->GetStartJustDown())
- || CPad::GetPad(0)->GetLeftMouseJustDown()
- || CPad::GetPad(0)->GetEnterJustDown()
- || CPad::GetPad(0)->GetCharJustDown(' '))
- FinishCutscene();
+
+ for (int i = 0; i < ms_numCutsceneObjs; i++) {
+ int modelId = ms_pCutsceneObjects[i]->GetModelIndex();
+ if (modelId >= MI_CUTOBJ01 && modelId <= MI_CUTOBJ05)
+ UpdateCutsceneObjectBoundingBox(ms_pCutsceneObjects[i]->GetClump(), modelId);
+
+ if (ms_pCutsceneObjects[i]->m_pAttachTo != nil && modelId >= MI_SPECIAL01 && modelId <= MI_SPECIAL21)
+ UpdateCutsceneObjectBoundingBox(ms_pCutsceneObjects[i]->GetClump(), modelId);
}
+
+ if (bCamLoaded)
+ if (CGeneral::faststricmp(ms_cutsceneName, "finale") && TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_FLYBY && ms_cutsceneLoadStatus == CUTSCENE_LOADING_0) {
+ if (CPad::GetPad(0)->GetCrossJustDown()
+ || (CGame::playingIntro && CPad::GetPad(0)->GetStartJustDown())
+ || CPad::GetPad(0)->GetLeftMouseJustDown()
+ || CPad::GetPad(0)->GetEnterJustDown()
+ || CPad::GetPad(0)->GetCharJustDown(' '))
+ FinishCutscene();
+ }
}
-bool CCutsceneMgr::HasCutsceneFinished(void) { return TheCamera.GetPositionAlongSpline() == 1.0f; }
+bool CCutsceneMgr::HasCutsceneFinished(void) { return !bCamLoaded || TheCamera.GetPositionAlongSpline() == 1.0f; }
+
+void
+CCutsceneMgr::LoadAnimationUncompressed(char const* name)
+{
+ strcpy(uncompressedAnims[numUncompressedAnims], name);
+
+ // Because that's how CAnimManager knows the end of array
+ ++numUncompressedAnims;
+ assert(numUncompressedAnims < ARRAY_SIZE(uncompressedAnims));
+ uncompressedAnims[numUncompressedAnims][0] = '\0';
+}
+void
+CCutsceneMgr::AttachObjectToParent(CObject *pObject, CEntity *pAttachTo)
+{
+ ((CCutsceneObject*)pObject)->m_pAttachmentObject = nil;
+ ((CCutsceneObject*)pObject)->m_pAttachTo = RpClumpGetFrame(pAttachTo->GetClump());
+
+ debug("Attach %s to %s\n", CModelInfo::GetModelInfo(pObject->GetModelIndex())->GetModelName(), CModelInfo::GetModelInfo(pAttachTo->GetModelIndex())->GetModelName());
+}
+
+void
+CCutsceneMgr::AttachObjectToFrame(CObject *pObject, CEntity *pAttachTo, const char *frame)
+{
+ ((CCutsceneObject*)pObject)->m_pAttachmentObject = nil;
+ ((CCutsceneObject*)pObject)->m_pAttachTo = RpAnimBlendClumpFindFrame(pAttachTo->GetClump(), frame)->frame;
+ debug("Attach %s to component %s of %s\n",
+ CModelInfo::GetModelInfo(pObject->GetModelIndex())->GetModelName(),
+ frame,
+ CModelInfo::GetModelInfo(pAttachTo->GetModelIndex())->GetModelName());
+ if (RwObjectGetType(pObject->m_rwObject) == rpCLUMP) {
+ RpClump *clump = (RpClump*)pObject->m_rwObject;
+ if (IsClumpSkinned(clump))
+ RpAtomicGetBoundingSphere(GetFirstAtomic(clump))->radius *= 1.1f;
+ }
+}
+
+void
+CCutsceneMgr::AttachObjectToBone(CObject *pObject, CObject *pAttachTo, int bone)
+{
+ RpHAnimHierarchy *hanim = GetAnimHierarchyFromSkinClump(pAttachTo->GetClump());
+ RwInt32 id = RpHAnimIDGetIndex(hanim, bone);
+ RwMatrix *matrixArray = RpHAnimHierarchyGetMatrixArray(hanim);
+ ((CCutsceneObject*)pObject)->m_pAttachmentObject = pAttachTo;
+ ((CCutsceneObject*)pObject)->m_pAttachTo = &matrixArray[id];
+ debug("Attach %s to %s\n",
+ CModelInfo::GetModelInfo(pObject->GetModelIndex())->GetModelName(),
+ CModelInfo::GetModelInfo(pAttachTo->GetModelIndex())->GetModelName());
+}
+
+void
+CCutsceneMgr::RemoveEverythingFromTheWorldForTheBiggestFuckoffCutsceneEver()
+{
+ CStreaming::ms_disableStreaming = true;
+ CColStore::RemoveAllCollision();
+ CWorld::bProcessCutsceneOnly = true;
+ ms_cutsceneProcessing = true;
+
+ for (int i = CPools::GetPedPool()->GetSize() - 1; i >= 0; i--) {
+ CPed *pPed = CPools::GetPedPool()->GetSlot(i);
+ if (pPed) {
+ if (!pPed->IsPlayer() && pPed->CanBeDeleted()) {
+ CWorld::Remove(pPed);
+ delete pPed;
+ }
+ }
+ }
+
+ for (int i = CPools::GetVehiclePool()->GetSize() - 1; i >= 0; i--) {
+ CVehicle *pVehicle = CPools::GetVehiclePool()->GetSlot(i);
+ if (pVehicle) {
+ if (pVehicle->CanBeDeleted()) {
+ CWorld::Remove(pVehicle);
+ delete pVehicle;
+ }
+ }
+ }
+
+ bIsEverythingRemovedFromTheWorldForTheBiggestFuckoffCutsceneEver = true;
+ CStreaming::RemoveCurrentZonesModels();
+ CStreaming::SetModelIsDeletable(MI_MALE01);
+ CStreaming::SetModelTxdIsDeletable(MI_MALE01);
+ CStreaming::SetModelIsDeletable(MI_TAXI_D);
+ CStreaming::SetModelTxdIsDeletable(MI_TAXI_D);
+ CStreaming::SetModelIsDeletable(MI_NIGHTSTICK);
+ CStreaming::SetModelTxdIsDeletable(MI_NIGHTSTICK);
+ CStreaming::SetModelIsDeletable(MI_MISSILE);
+ CStreaming::SetModelTxdIsDeletable(MI_MISSILE);
+ CStreaming::SetModelIsDeletable(MI_POLICE);
+ CStreaming::SetModelTxdIsDeletable(MI_POLICE);
+
+ while (CStreaming::RemoveLoadedVehicle()) ;
+
+ CRadar::RemoveRadarSections();
+
+ for (int i = CPools::GetDummyPool()->GetSize() - 1; i >= 0; i--) {
+ CDummy* pDummy = CPools::GetDummyPool()->GetSlot(i);
+ if (pDummy)
+ pDummy->DeleteRwObject();
+ }
+
+ for (int i = CPools::GetObjectPool()->GetSize() - 1; i >= 0; i--) {
+ CObject* pObject = CPools::GetObjectPool()->GetSlot(i);
+ if (pObject)
+ pObject->DeleteRwObject();
+ }
+
+ for (int i = CPools::GetBuildingPool()->GetSize() - 1; i >= 0; i--) {
+ CBuilding* pBuilding = CPools::GetBuildingPool()->GetSlot(i);
+ if (pBuilding && pBuilding->m_rwObject != nil && pBuilding->bIsBIGBuilding && pBuilding->bStreamBIGBuilding) {
+ if (pBuilding->bIsBIGBuilding)
+ CStreaming::RequestModel(pBuilding->GetModelIndex(), 0);
+ if (!pBuilding->bImBeingRendered)
+ pBuilding->DeleteRwObject();
+ }
+ }
+
+ CPlayerPed *pPlayerPed = FindPlayerPed();
+ pPlayerPed->RemoveWeaponAnims(0, -1000.0f);
+ NumberOfSavedWeapons = 0;
+
+ for (int i = 0; i < TOTAL_WEAPON_SLOTS; i++) {
+ if (pPlayerPed->m_weapons[i].m_eWeaponType != WEAPONTYPE_UNARMED) {
+ SavedWeaponIDs[NumberOfSavedWeapons] = pPlayerPed->m_weapons[i].m_eWeaponType;
+ SavedWeaponAmmo[NumberOfSavedWeapons] = pPlayerPed->m_weapons[i].m_nAmmoTotal;
+ NumberOfSavedWeapons++;
+ }
+ }
+
+ pPlayerPed->ClearWeapons();
+ CGame::DrasticTidyUpMemory(true);
+} \ No newline at end of file
diff --git a/src/animation/CutsceneMgr.h b/src/animation/CutsceneMgr.h
index bfdcdb57..51ef6c04 100644
--- a/src/animation/CutsceneMgr.h
+++ b/src/animation/CutsceneMgr.h
@@ -21,7 +21,9 @@ class CCutsceneMgr
static CAnimBlendAssocGroup ms_cutsceneAssociations;
static CVector ms_cutsceneOffset;
static float ms_cutsceneTimer;
+ static bool ms_wasCutsceneSkipped;
static bool ms_cutsceneProcessing;
+ static bool ms_useCutsceneShadows;
public:
static CDirectory *ms_pCutsceneDir;
static uint32 ms_cutsceneLoadStatus;
@@ -30,6 +32,7 @@ public:
static bool IsRunning(void) { return ms_running; }
static bool HasLoaded(void) { return ms_loaded; }
static bool IsCutsceneProcessing(void) { return ms_cutsceneProcessing; }
+ static bool WasCutsceneSkipped(void) { return ms_wasCutsceneSkipped; }
static bool UseLodMultiplier(void) { return ms_useLodMultiplier; }
static CCutsceneObject* GetCutsceneObject(int id) { return ms_pCutsceneObjects[id]; }
static int GetCutsceneTimeInMilleseconds(void) { return 1000.0f * ms_cutsceneTimer; }
@@ -41,11 +44,18 @@ public:
static void Shutdown(void);
static void LoadCutsceneData(const char *szCutsceneName);
static void FinishCutscene(void);
- static void SetHeadAnim(const char *animName, CObject *pObject);
static void SetupCutsceneToStart(void);
static void SetCutsceneAnim(const char *animName, CObject *pObject);
+ static void SetCutsceneAnimToLoop(const char *animName);
static CCutsceneHead *AddCutsceneHead(CObject *pObject, int modelId);
static CCutsceneObject *CreateCutsceneObject(int modelId);
static void DeleteCutsceneData(void);
+ static void LoadAnimationUncompressed(char const*);
static void Update(void);
+
+ static void AttachObjectToParent(CObject *pObject, CEntity *pAttachTo);
+ static void AttachObjectToFrame(CObject *pObject, CEntity *pAttachTo, const char *frame);
+ static void AttachObjectToBone(CObject *pObject, CObject *pAttachTo, int frame);
+ static void RemoveEverythingFromTheWorldForTheBiggestFuckoffCutsceneEver();
+ static void DisableCutsceneShadows() { ms_useCutsceneShadows = false; }
};
diff --git a/src/animation/FrameUpdate.cpp b/src/animation/FrameUpdate.cpp
index c7d347b3..d3094bb0 100644
--- a/src/animation/FrameUpdate.cpp
+++ b/src/animation/FrameUpdate.cpp
@@ -17,6 +17,8 @@ void FrameUpdateCallBackSkinned(AnimBlendFrameData *frame, void *arg);
void FrameUpdateCallBackWithVelocityExtractionSkinned(AnimBlendFrameData *frame, void *arg);
void FrameUpdateCallBackWith3dVelocityExtractionSkinned(AnimBlendFrameData *frame, void *arg);
+void FrameUpdateCallBackNonSkinnedCompressed(AnimBlendFrameData *frame, void *arg);
+void FrameUpdateCallBackSkinnedCompressed(AnimBlendFrameData *frame, void *arg);
void
FrameUpdateCallBackNonSkinned(AnimBlendFrameData *frame, void *arg)
@@ -228,12 +230,11 @@ FrameUpdateCallBackWith3dVelocityExtractionNonSkinned(AnimBlendFrameData *frame,
RwMatrixUpdate(mat);
}
-#ifdef PED_SKIN
-
void
FrameUpdateCallBackSkinned(AnimBlendFrameData *frame, void *arg)
{
CVector vec, pos(0.0f, 0.0f, 0.0f);
+ float transBlendAmount = 0.0f;
CQuaternion q, rot(0.0f, 0.0f, 0.0f, 0.0f);
float totalBlendAmount = 0.0f;
RpHAnimStdInterpFrame *xform = frame->hanimFrame;
@@ -257,13 +258,13 @@ FrameUpdateCallBackSkinned(AnimBlendFrameData *frame, void *arg)
for(node = updateData->nodes; *node; node++){
if((*node)->sequence){
(*node)->Update(vec, q, 1.0f-totalBlendAmount);
- if((*node)->sequence->HasTranslation())
+ if((*node)->sequence->HasTranslation()){
pos += vec;
-#ifdef FIX_BUGS
+ transBlendAmount += (*node)->association->blendAmount;
+ }
if(DotProduct(rot, q) < 0.0f)
rot -= q;
else
-#endif
rot += q;
}
++*node;
@@ -278,12 +279,12 @@ FrameUpdateCallBackSkinned(AnimBlendFrameData *frame, void *arg)
}
if((frame->flag & AnimBlendFrameData::IGNORE_TRANSLATION) == 0){
- xform->t.x = pos.x;
- xform->t.y = pos.y;
- xform->t.z = pos.z;
- xform->t.x += frame->resetPos.x;
- xform->t.y += frame->resetPos.y;
- xform->t.z += frame->resetPos.z;
+ xform->t.x = transBlendAmount*pos.x;
+ xform->t.y = transBlendAmount*pos.y;
+ xform->t.z = transBlendAmount*pos.z;
+ xform->t.x += (1.0f-transBlendAmount)*frame->resetPos.x;
+ xform->t.y += (1.0f-transBlendAmount)*frame->resetPos.y;
+ xform->t.z += (1.0f-transBlendAmount)*frame->resetPos.z;
}
}
@@ -319,11 +320,9 @@ FrameUpdateCallBackWithVelocityExtractionSkinned(AnimBlendFrameData *frame, void
for(node = updateData->nodes; *node; node++){
if((*node)->sequence){
bool nodelooped = (*node)->Update(vec, q, 1.0f-totalBlendAmount);
-#ifdef FIX_BUGS
if(DotProduct(rot, q) < 0.0f)
rot -= q;
else
-#endif
rot += q;
if((*node)->sequence->HasTranslation()){
pos += vec;
@@ -442,4 +441,228 @@ FrameUpdateCallBackWith3dVelocityExtractionSkinned(AnimBlendFrameData *frame, vo
}
}
+void
+FrameUpdateCallBackOffscreen(AnimBlendFrameData *frame, void *arg)
+{
+ if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION && gpAnimBlendClump->velocity2d)
+ FrameUpdateCallBackWithVelocityExtractionSkinned(frame, arg);
+}
+
+
+void
+FrameUpdateCallBackNonSkinnedCompressed(AnimBlendFrameData *frame, void *arg)
+{
+ CVector vec, pos(0.0f, 0.0f, 0.0f);
+ CQuaternion q, rot(0.0f, 0.0f, 0.0f, 0.0f);
+ float totalBlendAmount = 0.0f;
+ CVector trans(0.0f, 0.0f, 0.0f);
+ CVector cur(0.0f, 0.0f, 0.0f);
+ CVector end(0.0f, 0.0f, 0.0f);
+ bool looped = false;
+ RwMatrix *mat = RwFrameGetMatrix(frame->frame);
+ CAnimBlendNode **node;
+ AnimBlendFrameUpdateData *updateData = (AnimBlendFrameUpdateData*)arg;
+
+ if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION &&
+ gpAnimBlendClump->velocity2d){
+ if(updateData->foobar)
+ for(node = updateData->nodes; *node; node++)
+ if((*node)->sequence && (*node)->association->IsPartial())
+ totalBlendAmount += (*node)->association->blendAmount;
+
+ for(node = updateData->nodes; *node; node++)
+ if((*node)->sequence && (*node)->sequence->HasTranslation()){
+ if((*node)->association->HasTranslation()){
+ (*node)->GetCurrentTranslationCompressed(vec, 1.0f-totalBlendAmount);
+ cur += vec;
+ }
+ }
+
+ for(node = updateData->nodes; *node; node++){
+ if((*node)->sequence){
+ bool nodelooped = (*node)->UpdateCompressed(vec, q, 1.0f-totalBlendAmount);
+#ifdef FIX_BUGS
+ if(DotProduct(rot, q) < 0.0f)
+ rot -= q;
+ else
+#endif
+ rot += q;
+ if((*node)->sequence->HasTranslation()){
+ pos += vec;
+ if((*node)->association->HasTranslation()){
+ trans += vec;
+ looped |= nodelooped;
+ if(nodelooped){
+ (*node)->GetEndTranslationCompressed(vec, 1.0f-totalBlendAmount);
+ end += vec;
+ }
+ }
+ }
+ }
+ ++*node;
+ }
+
+ if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){
+ RwMatrixSetIdentity(mat);
+ rot.Normalise();
+ rot.Get(mat);
+ }
+
+ if((frame->flag & AnimBlendFrameData::IGNORE_TRANSLATION) == 0){
+ *gpAnimBlendClump->velocity3d = trans - cur;
+ if(looped)
+ *gpAnimBlendClump->velocity3d += end;
+ mat->pos.x = (pos - trans).x + frame->resetPos.x;
+ mat->pos.y = (pos - trans).y + frame->resetPos.y;
+ mat->pos.z = (pos - trans).z + frame->resetPos.z;
+ }
+ RwMatrixUpdate(mat);
+ }else{
+ if(updateData->foobar)
+ for(node = updateData->nodes; *node; node++)
+ if((*node)->sequence && (*node)->association->IsPartial())
+ totalBlendAmount += (*node)->association->blendAmount;
+
+ for(node = updateData->nodes; *node; node++){
+ if((*node)->sequence){
+ (*node)->UpdateCompressed(vec, q, 1.0f-totalBlendAmount);
+ if((*node)->sequence->HasTranslation())
+ pos += vec;
+#ifdef FIX_BUGS
+ if(DotProduct(rot, q) < 0.0f)
+ rot -= q;
+ else
#endif
+ rot += q;
+ }
+ ++*node;
+ }
+
+ if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){
+ RwMatrixSetIdentity(mat);
+ rot.Normalise();
+ rot.Get(mat);
+ }
+
+ if((frame->flag & AnimBlendFrameData::IGNORE_TRANSLATION) == 0){
+ mat->pos.x = pos.x;
+ mat->pos.y = pos.y;
+ mat->pos.z = pos.z;
+ mat->pos.x += frame->resetPos.x;
+ mat->pos.y += frame->resetPos.y;
+ mat->pos.z += frame->resetPos.z;
+ }
+ RwMatrixUpdate(mat);
+ }
+}
+
+void
+FrameUpdateCallBackSkinnedCompressed(AnimBlendFrameData *frame, void *arg)
+{
+ CVector vec, pos(0.0f, 0.0f, 0.0f);
+ CQuaternion q, rot(0.0f, 0.0f, 0.0f, 0.0f);
+ float totalBlendAmount = 0.0f;
+ CVector trans(0.0f, 0.0f, 0.0f);
+ CVector cur(0.0f, 0.0f, 0.0f);
+ CVector end(0.0f, 0.0f, 0.0f);
+ bool looped = false;
+ RpHAnimStdInterpFrame *xform = frame->hanimFrame;
+ CAnimBlendNode **node;
+ AnimBlendFrameUpdateData *updateData = (AnimBlendFrameUpdateData*)arg;
+
+ if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION &&
+ gpAnimBlendClump->velocity2d){
+ if(updateData->foobar)
+ for(node = updateData->nodes; *node; node++)
+ if((*node)->sequence && (*node)->association->IsPartial())
+ totalBlendAmount += (*node)->association->blendAmount;
+
+ for(node = updateData->nodes; *node; node++)
+ if((*node)->sequence && (*node)->sequence->HasTranslation()){
+ if((*node)->association->HasTranslation()){
+ (*node)->GetCurrentTranslationCompressed(vec, 1.0f-totalBlendAmount);
+ cur += vec;
+ }
+ }
+
+ for(node = updateData->nodes; *node; node++){
+ if((*node)->sequence){
+ bool nodelooped = (*node)->UpdateCompressed(vec, q, 1.0f-totalBlendAmount);
+#ifdef FIX_BUGS
+ if(DotProduct(rot, q) < 0.0f)
+ rot -= q;
+ else
+#endif
+ rot += q;
+ if((*node)->sequence->HasTranslation()){
+ pos += vec;
+ if((*node)->association->HasTranslation()){
+ trans += vec;
+ looped |= nodelooped;
+ if(nodelooped){
+ (*node)->GetEndTranslationCompressed(vec, 1.0f-totalBlendAmount);
+ end += vec;
+ }
+ }
+ }
+ }
+ ++*node;
+ }
+
+ if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){
+ rot.Normalise();
+ xform->q.imag.x = rot.x;
+ xform->q.imag.y = rot.y;
+ xform->q.imag.z = rot.z;
+ xform->q.real = rot.w;
+ }
+
+ if((frame->flag & AnimBlendFrameData::IGNORE_TRANSLATION) == 0){
+ *gpAnimBlendClump->velocity3d = trans - cur;
+ if(looped)
+ *gpAnimBlendClump->velocity3d += end;
+ xform->t.x = (pos - trans).x + frame->resetPos.x;
+ xform->t.y = (pos - trans).y + frame->resetPos.y;
+ xform->t.z = (pos - trans).z + frame->resetPos.z;
+ }
+ }else{
+ float transBlendAmount = 0.0f;
+
+ if(updateData->foobar)
+ for(node = updateData->nodes; *node; node++)
+ if((*node)->sequence && (*node)->association->IsPartial())
+ totalBlendAmount += (*node)->association->blendAmount;
+
+ for(node = updateData->nodes; *node; node++){
+ if((*node)->sequence){
+ (*node)->UpdateCompressed(vec, q, 1.0f-totalBlendAmount);
+ if((*node)->sequence->HasTranslation()){
+ pos += vec;
+ transBlendAmount += (*node)->association->blendAmount;
+ }
+ if(DotProduct(rot, q) < 0.0f)
+ rot -= q;
+ else
+ rot += q;
+ }
+ ++*node;
+ }
+
+ if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){
+ rot.Normalise();
+ xform->q.imag.x = rot.x;
+ xform->q.imag.y = rot.y;
+ xform->q.imag.z = rot.z;
+ xform->q.real = rot.w;
+ }
+
+ if((frame->flag & AnimBlendFrameData::IGNORE_TRANSLATION) == 0){
+ xform->t.x = transBlendAmount*pos.x;
+ xform->t.y = transBlendAmount*pos.y;
+ xform->t.z = transBlendAmount*pos.z;
+ xform->t.x += (1.0f-transBlendAmount)*frame->resetPos.x;
+ xform->t.y += (1.0f-transBlendAmount)*frame->resetPos.y;
+ xform->t.z += (1.0f-transBlendAmount)*frame->resetPos.z;
+ }
+ }
+}
diff --git a/src/animation/RpAnimBlend.cpp b/src/animation/RpAnimBlend.cpp
index e430e52a..9a11d8bb 100644
--- a/src/animation/RpAnimBlend.cpp
+++ b/src/animation/RpAnimBlend.cpp
@@ -10,9 +10,7 @@
#include "AnimBlendAssociation.h"
#include "AnimManager.h"
#include "RpAnimBlend.h"
-#ifdef PED_SKIN
#include "PedModelInfo.h"
-#endif
RwInt32 ClumpOffset;
@@ -142,7 +140,6 @@ FrameInitCBskin(AnimBlendFrameData *frameData, void*)
frameData->flag = 0;
}
-#ifdef PED_SKIN
void
RpAnimBlendClumpInitSkinned(RpClump *clump)
{
@@ -156,7 +153,7 @@ RpAnimBlendClumpInitSkinned(RpClump *clump)
RpAnimBlendAllocateData(clump);
clumpData = *RPANIMBLENDCLUMPDATA(clump);
- atomic = IsClumpSkinned(clump);
+ atomic = GetFirstAtomic(clump);
assert(atomic);
skin = RpSkinGeometryGetSkin(RpAtomicGetGeometry(atomic));
assert(skin);
@@ -171,12 +168,15 @@ RpAnimBlendClumpInitSkinned(RpClump *clump)
for(i = 0; i < numBones; i++){
frames[i].nodeID = HIERNODEID(hier, i);
frames[i].resetPos = boneTab[i];
+#ifdef LIBRW
frames[i].hanimFrame = (RpHAnimStdInterpFrame*)rpHANIMHIERARCHYGETINTERPFRAME(hier, i);
+#else
+ frames[i].hanimFrame = (RpHAnimStdInterpFrame*)rtANIMGETINTERPFRAME(hier->currentAnim, i);
+#endif
}
clumpData->ForAllFrames(FrameInitCBskin, nil);
clumpData->frames[0].flag |= AnimBlendFrameData::VELOCITY_EXTRACTION;
}
-#endif
void
RpAnimBlendClumpInitNotSkinned(RpClump *clump)
@@ -200,11 +200,9 @@ RpAnimBlendClumpInitNotSkinned(RpClump *clump)
void
RpAnimBlendClumpInit(RpClump *clump)
{
-#ifdef PED_SKIN
if(IsClumpSkinned(clump))
RpAnimBlendClumpInitSkinned(clump);
else
-#endif
RpAnimBlendClumpInitNotSkinned(clump);
}
@@ -364,7 +362,6 @@ FillFrameArrayCBnonskin(AnimBlendFrameData *frame, void *arg)
frames[CVisibilityPlugins::GetFrameHierarchyId(frame->frame)] = frame;
}
-#ifdef PED_SKIN
void
RpAnimBlendClumpFillFrameArraySkin(RpClump *clump, AnimBlendFrameData **frames)
{
@@ -374,22 +371,18 @@ RpAnimBlendClumpFillFrameArraySkin(RpClump *clump, AnimBlendFrameData **frames)
for(i = PED_MID; i < PED_NODE_MAX; i++)
frames[i] = &clumpData->frames[RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(i))];
}
-#endif
void
RpAnimBlendClumpFillFrameArray(RpClump *clump, AnimBlendFrameData **frames)
{
-#ifdef PED_SKIN
if(IsClumpSkinned(clump))
RpAnimBlendClumpFillFrameArraySkin(clump, frames);
else
-#endif
(*RPANIMBLENDCLUMPDATA(clump))->ForAllFrames(FillFrameArrayCBnonskin, frames);
}
AnimBlendFrameData *pFrameDataFound;
-// FrameFindCallBack on PS2
void
FrameFindByNameCBnonskin(AnimBlendFrameData *frame, void *arg)
{
@@ -398,7 +391,6 @@ FrameFindByNameCBnonskin(AnimBlendFrameData *frame, void *arg)
pFrameDataFound = frame;
}
-#ifdef PED_SKIN
void
FrameFindByNameCBskin(AnimBlendFrameData *frame, void *arg)
{
@@ -406,25 +398,58 @@ FrameFindByNameCBskin(AnimBlendFrameData *frame, void *arg)
if(name && CGeneral::faststricmp(name, (char*)arg) == 0)
pFrameDataFound = frame;
}
-#endif
+
+void
+FrameFindByBoneCB(AnimBlendFrameData *frame, void *arg)
+{
+ if(frame->nodeID == (int32)(uintptr)arg)
+ pFrameDataFound = frame;
+}
AnimBlendFrameData*
RpAnimBlendClumpFindFrame(RpClump *clump, const char *name)
{
pFrameDataFound = nil;
-#ifdef PED_SKIN
if(IsClumpSkinned(clump))
(*RPANIMBLENDCLUMPDATA(clump))->ForAllFrames(FrameFindByNameCBskin, (void*)name);
else
-#endif
(*RPANIMBLENDCLUMPDATA(clump))->ForAllFrames(FrameFindByNameCBnonskin, (void*)name);
return pFrameDataFound;
}
+AnimBlendFrameData*
+RpAnimBlendClumpFindBone(RpClump *clump, uint32 boneTag)
+{
+ pFrameDataFound = nil;
+ (*RPANIMBLENDCLUMPDATA(clump))->ForAllFrames(FrameFindByBoneCB, (void*)boneTag);
+ return pFrameDataFound;
+}
+
void
-RpAnimBlendClumpUpdateAnimations(RpClump *clump, float timeDelta)
+RpAnimBlendNodeUpdateKeyframes(AnimBlendFrameData *frames, AnimBlendFrameUpdateData *updateData, int32 numNodes)
{
+ CAnimBlendNode **node;
int i;
+
+ for(node = updateData->nodes; *node; node++){
+ CAnimBlendAssociation *a = (*node)->association;
+ for(i = 0; i < numNodes; i++)
+ if((frames[i].flag & AnimBlendFrameData::VELOCITY_EXTRACTION) == 0 ||
+ gpAnimBlendClump->velocity2d == nil){
+ if((*node)[i].sequence)
+ (*node)[i].FindKeyFrame(a->currentTime - a->timeStep);
+ }
+ }
+}
+
+// TODO:
+// CAnimBlendClumpData::LoadFramesIntoSPR
+// CAnimBlendClumpData::ForAllFramesInSPR
+void
+RpAnimBlendClumpUpdateAnimations(RpClump *clump, float timeDelta, bool doRender)
+{
+ int i;
+ CAnimBlendAssociation *assoc;
AnimBlendFrameUpdateData updateData;
float totalLength = 0.0f;
float totalBlend = 0.0f;
@@ -440,30 +465,53 @@ RpAnimBlendClumpUpdateAnimations(RpClump *clump, float timeDelta)
updateData.foobar = 0;
for(link = clumpData->link.next; link; link = next){
next = link->next;
- CAnimBlendAssociation *assoc = CAnimBlendAssociation::FromLink(link);
+ assoc = CAnimBlendAssociation::FromLink(link);
if(assoc->UpdateBlend(timeDelta)){
- CAnimManager::UncompressAnimation(assoc->hierarchy);
- updateData.nodes[i++] = assoc->GetNode(0);
- if(assoc->flags & ASSOC_MOVEMENT){
- totalLength += assoc->hierarchy->totalLength/assoc->speed * assoc->blendAmount;
- totalBlend += assoc->blendAmount;
+ if(assoc->hierarchy->sequences){
+ CAnimManager::UncompressAnimation(assoc->hierarchy);
+ if(i < 11)
+ updateData.nodes[i++] = assoc->GetNode(0);
+ if(assoc->flags & ASSOC_MOVEMENT){
+ totalLength += assoc->hierarchy->totalLength/assoc->speed * assoc->blendAmount;
+ totalBlend += assoc->blendAmount;
+ }else
+ updateData.foobar = 1;
}else
- updateData.foobar = 1;
+ debug("anim %s is not loaded\n", assoc->hierarchy->name);
}
}
+
+ for(link = clumpData->link.next; link; link = link->next){
+ assoc = CAnimBlendAssociation::FromLink(link);
+ assoc->UpdateTimeStep(timeDelta, totalLength == 0.0f ? 1.0f : totalBlend/totalLength);
+ }
+
updateData.nodes[i] = nil;
-#ifdef PED_SKIN
- if(IsClumpSkinned(clump))
- clumpData->ForAllFrames(FrameUpdateCallBackSkinned, &updateData);
- else
+#ifdef ANIM_COMPRESSION
+ if(clumpData->frames[0].flag & AnimBlendFrameData::COMPRESSED){
+ if(IsClumpSkinned(clump))
+ clumpData->ForAllFrames(FrameUpdateCallBackSkinnedCompressed, &updateData);
+ else
+ clumpData->ForAllFrames(FrameUpdateCallBackNonSkinnedCompressed, &updateData);
+ }else
#endif
- clumpData->ForAllFrames(FrameUpdateCallBackNonSkinned, &updateData);
+ if(doRender){
+ if(clumpData->frames[0].flag & AnimBlendFrameData::UPDATE_KEYFRAMES)
+ RpAnimBlendNodeUpdateKeyframes(clumpData->frames, &updateData, clumpData->numFrames);
+ if(IsClumpSkinned(clump))
+ clumpData->ForAllFrames(FrameUpdateCallBackSkinned, &updateData);
+ else
+ clumpData->ForAllFrames(FrameUpdateCallBackNonSkinned, &updateData);
+ clumpData->frames[0].flag &= ~AnimBlendFrameData::UPDATE_KEYFRAMES;
+ }else{
+ clumpData->ForAllFrames(FrameUpdateCallBackOffscreen, &updateData);
+ clumpData->frames[0].flag |= AnimBlendFrameData::UPDATE_KEYFRAMES;
+ }
for(link = clumpData->link.next; link; link = link->next){
- CAnimBlendAssociation *assoc = CAnimBlendAssociation::FromLink(link);
- float relSpeed = totalLength == 0.0f ? 1.0f : totalBlend/totalLength;
- assoc->UpdateTime(timeDelta, relSpeed);
+ assoc = CAnimBlendAssociation::FromLink(link);
+ assoc->UpdateTime(timeDelta, totalLength == 0.0f ? 1.0f : totalBlend/totalLength);
}
RwFrameUpdateObjects(RpClumpGetFrame(clump));
}
diff --git a/src/animation/RpAnimBlend.h b/src/animation/RpAnimBlend.h
index 838c8816..6e9e0f0f 100644
--- a/src/animation/RpAnimBlend.h
+++ b/src/animation/RpAnimBlend.h
@@ -26,6 +26,7 @@ void RpAnimBlendClumpInit(RpClump *clump);
bool RpAnimBlendClumpIsInitialized(RpClump *clump);
void RpAnimBlendClumpFillFrameArray(RpClump* clump, AnimBlendFrameData** frames);
AnimBlendFrameData *RpAnimBlendClumpFindFrame(RpClump *clump, const char *name);
+AnimBlendFrameData *RpAnimBlendClumpFindBone(RpClump *clump, uint32 boneTag);
void FillFrameArrayCallBack(AnimBlendFrameData *frame, void *arg);
CAnimBlendAssociation *RpAnimBlendClumpGetAssociation(RpClump *clump, uint32 id);
CAnimBlendAssociation *RpAnimBlendClumpGetMainAssociation(RpClump *clump, CAnimBlendAssociation **assocRet, float *blendRet);
@@ -34,9 +35,14 @@ CAnimBlendAssociation *RpAnimBlendClumpGetMainAssociation_N(RpClump *clump, int
CAnimBlendAssociation *RpAnimBlendClumpGetMainPartialAssociation_N(RpClump *clump, int n);
CAnimBlendAssociation *RpAnimBlendClumpGetFirstAssociation(RpClump *clump, uint32 mask);
CAnimBlendAssociation *RpAnimBlendClumpGetFirstAssociation(RpClump *clump);
-void RpAnimBlendClumpUpdateAnimations(RpClump* clump, float timeDelta);
+void RpAnimBlendNodeUpdateKeyframes(AnimBlendFrameData *frames, AnimBlendFrameUpdateData *updateData, int32 numNodes);
+void RpAnimBlendClumpUpdateAnimations(RpClump* clump, float timeDelta, bool doRender = true);
extern CAnimBlendClumpData *gpAnimBlendClump;
void FrameUpdateCallBackNonSkinned(AnimBlendFrameData *frame, void *arg);
void FrameUpdateCallBackSkinned(AnimBlendFrameData *frame, void *arg);
+void FrameUpdateCallBackOffscreen(AnimBlendFrameData *frame, void *arg);
+
+void FrameUpdateCallBackNonSkinnedCompressed(AnimBlendFrameData *frame, void *arg);
+void FrameUpdateCallBackSkinnedCompressed(AnimBlendFrameData *frame, void *arg);
diff --git a/src/audio/AudioCollision.cpp b/src/audio/AudioCollision.cpp
index 1b72764e..4bf6a404 100644
--- a/src/audio/AudioCollision.cpp
+++ b/src/audio/AudioCollision.cpp
@@ -83,11 +83,11 @@ cAudioManager::ServiceCollisions()
m_sQueueSample.m_nEntityIndex = m_nCollisionEntity;
- for (int i = 0; i < NUMAUDIOCOLLISIONS; i++)
+ for(int i = 0; i < NUMAUDIOCOLLISIONS; i++)
abRepeatedCollision1[i] = abRepeatedCollision2[i] = FALSE;
- for (i = 0; i < m_sCollisionManager.m_bCollisionsInQueue; i++) {
- for (j = 0; j < NUMAUDIOCOLLISIONS; j++) {
+ for(i = 0; i < m_sCollisionManager.m_bCollisionsInQueue; i++) {
+ for(j = 0; j < NUMAUDIOCOLLISIONS; j++) {
int index = m_sCollisionManager.m_bIndicesTable[i];
if ((m_sCollisionManager.m_asCollisions1[index].m_pEntity1 == m_sCollisionManager.m_asCollisions2[j].m_pEntity1)
&& (m_sCollisionManager.m_asCollisions1[index].m_pEntity2 == m_sCollisionManager.m_asCollisions2[j].m_pEntity2)
@@ -103,8 +103,8 @@ cAudioManager::ServiceCollisions()
}
}
- for (i = 0; i < NUMAUDIOCOLLISIONS; i++) {
- if (!abRepeatedCollision2[i]) {
+ for(i = 0; i < NUMAUDIOCOLLISIONS; i++) {
+ if(!abRepeatedCollision2[i]) {
m_sCollisionManager.m_asCollisions2[i].m_pEntity1 = nil;
m_sCollisionManager.m_asCollisions2[i].m_pEntity2 = nil;
m_sCollisionManager.m_asCollisions2[i].m_bSurface1 = SURFACE_DEFAULT;
@@ -116,11 +116,11 @@ cAudioManager::ServiceCollisions()
}
}
- for (i = 0; i < m_sCollisionManager.m_bCollisionsInQueue; i++) {
+ for(i = 0; i < m_sCollisionManager.m_bCollisionsInQueue; i++) {
int index = m_sCollisionManager.m_bIndicesTable[i];
- if (!abRepeatedCollision1[index]) {
- for (j = 0; j < NUMAUDIOCOLLISIONS; j++) {
- if (!abRepeatedCollision2[j]) {
+ if(!abRepeatedCollision1[index]) {
+ for(j = 0; j < NUMAUDIOCOLLISIONS; j++) {
+ if(!abRepeatedCollision2[j]) {
m_sCollisionManager.m_asCollisions2[j].m_nBaseVolume = 1;
m_sCollisionManager.m_asCollisions2[j].m_pEntity1 = m_sCollisionManager.m_asCollisions1[index].m_pEntity1;
m_sCollisionManager.m_asCollisions2[j].m_pEntity2 = m_sCollisionManager.m_asCollisions1[index].m_pEntity2;
@@ -134,7 +134,7 @@ cAudioManager::ServiceCollisions()
}
}
- for (int i = 0; i < NUMAUDIOCOLLISIONS; i++)
+ for(int i = 0; i < NUMAUDIOCOLLISIONS; i++)
m_sCollisionManager.m_bIndicesTable[i] = NUMAUDIOCOLLISIONS;
m_sCollisionManager.m_bCollisionsInQueue = 0;
}
@@ -171,7 +171,9 @@ static const int32 gOneShotCol[] = {SFX_COL_TARMAC_1,
SFX_TYRE_BUMP,
SFX_COL_CARDBOARD_1,
SFX_COL_TARMAC_1,
- SFX_COL_GATE};
+ SFX_COL_GATE,
+ SFX_COL_SAND_1,
+ SFX_COL_TARMAC_1 };
void
cAudioManager::SetUpOneShotCollisionSound(const cAudioCollision &col)
@@ -219,7 +221,7 @@ cAudioManager::SetUpOneShotCollisionSound(const cAudioCollision &col)
m_sQueueSample.m_nSampleIndex += m_anRandomTable[3] % 4;
break;
case SFX_COL_PED_1:
- m_sQueueSample.m_nSampleIndex += m_anRandomTable[4] % 5;
+ m_sQueueSample.m_nSampleIndex += m_anRandomTable[4] % 2;
break;
case SFX_COL_WOOD_CRATES_1:
m_sQueueSample.m_nSampleIndex += m_anRandomTable[4] % 4;
@@ -279,12 +281,12 @@ cAudioManager::SetUpOneShotCollisionSound(const cAudioCollision &col)
void
cAudioManager::SetUpLoopingCollisionSound(const cAudioCollision &col, uint8 counter)
{
+ bool8 distCalculated = FALSE;
if(col.m_fIntensity2 > 0.0016f) {
uint8 emittingVol = SetLoopingCollisionRequestedSfxFreqAndGetVol(col);
if(emittingVol) {
- m_sQueueSample.m_fDistance = Sqrt(col.m_fDistance);
- m_sQueueSample.m_nVolume =
- ComputeVolume(emittingVol, CollisionSoundIntensity, m_sQueueSample.m_fDistance);
+ CalculateDistance(distCalculated, m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, CollisionSoundIntensity, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_nVolume) {
m_sQueueSample.m_nCounter = counter;
m_sQueueSample.m_vecPos = col.m_vecPosition;
@@ -293,7 +295,7 @@ cAudioManager::SetUpLoopingCollisionSound(const cAudioCollision &col, uint8 coun
m_sQueueSample.m_nReleasingVolumeModificator = 7;
m_sQueueSample.m_nLoopCount = 0;
SET_EMITTING_VOLUME(emittingVol);
- SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex);
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
m_sQueueSample.m_fSpeedMultiplier = 4.0f;
m_sQueueSample.m_SoundIntensity = CollisionSoundIntensity;
m_sQueueSample.m_bReleasingSoundFlag = FALSE;
@@ -325,8 +327,8 @@ cAudioManager::SetLoopingCollisionRequestedSfxFreqAndGetVol(const cAudioCollisio
m_sQueueSample.m_nSampleIndex = SFX_BOAT_WATER_LOOP;
m_sQueueSample.m_nFrequency = 6050.f * ratio + 16000;
vol = 30.f * ratio;
- } else if(surface1 == SURFACE_GRAVEL || surface2 == SURFACE_GRAVEL || surface1 == SURFACE_MUD_DRY ||
- surface2 == SURFACE_MUD_DRY || 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 || surface1 == SURFACE_SAND_BEACH || surface2 == SURFACE_SAND_BEACH) {
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;
@@ -351,11 +353,12 @@ cAudioManager::GetCollisionOneShotRatio(uint32 a, float b)
case SURFACE_TARMAC:
case SURFACE_PAVEMENT:
case SURFACE_STEEP_CLIFF:
- case SURFACE_TRANSPARENT_STONE: return GetCollisionRatio(b, 10.f, 60.f, 50.f);
+ case SURFACE_TRANSPARENT_STONE:
+ case SURFACE_CONCRETE_BEACH: return GetCollisionRatio(b, 10.f, 60.f, 50.f);
case SURFACE_GRASS:
- case SURFACE_CARDBOARDBOX:
case SURFACE_GRAVEL:
- case SURFACE_MUD_DRY: return GetCollisionRatio(b, 0.f, 2.f, 2.f);
+ case SURFACE_MUD_DRY:
+ case SURFACE_CARDBOARDBOX: return GetCollisionRatio(b, 0.f, 2.f, 2.f);
case SURFACE_CAR: return GetCollisionRatio(b, 6.f, 50.f, 44.f);
case SURFACE_GLASS:
case SURFACE_METAL_CHAIN_FENCE: return GetCollisionRatio(b, 0.1f, 10.f, 9.9f);
@@ -364,7 +367,7 @@ cAudioManager::GetCollisionOneShotRatio(uint32 a, float b)
case SURFACE_GARAGE_DOOR: return GetCollisionRatio(b, 20.f, 100.f, 80.f);
case SURFACE_CAR_PANEL: return GetCollisionRatio(b, 0.f, 4.f, 4.f);
case SURFACE_SCAFFOLD_POLE:
- case SURFACE_METAL_GATE:
+ case SURFACE_METAL_GATE:
case SURFACE_LAMP_POST: return GetCollisionRatio(b, 1.f, 10.f, 9.f);
case SURFACE_FIRE_HYDRANT: return GetCollisionRatio(b, 1.f, 15.f, 14.f);
case SURFACE_GIRDER: return GetCollisionRatio(b, 8.f, 50.f, 42.f);
@@ -372,7 +375,8 @@ cAudioManager::GetCollisionOneShotRatio(uint32 a, float b)
case SURFACE_SAND:
case SURFACE_WATER:
case SURFACE_RUBBER:
- case SURFACE_WHEELBASE: return GetCollisionRatio(b, 0.f, 10.f, 10.f);
+ case SURFACE_WHEELBASE:
+ case SURFACE_SAND_BEACH: return GetCollisionRatio(b, 0.f, 10.f, 10.f);
case SURFACE_WOOD_CRATES: return GetCollisionRatio(b, 1.f, 4.f, 3.f);
case SURFACE_WOOD_BENCH: return GetCollisionRatio(b, 0.1f, 5.f, 4.9f);
case SURFACE_WOOD_SOLID: return GetCollisionRatio(b, 0.1f, 40.f, 39.9f);
diff --git a/src/audio/AudioCollision.h b/src/audio/AudioCollision.h
index a201d500..31be0334 100644
--- a/src/audio/AudioCollision.h
+++ b/src/audio/AudioCollision.h
@@ -54,4 +54,4 @@ public:
void AddCollisionToRequestedQueue();
};
-VALIDATE_SIZE(cAudioCollisionManager, 852);
+VALIDATE_SIZE(cAudioCollisionManager, 0x354);
diff --git a/src/audio/AudioLogic.cpp b/src/audio/AudioLogic.cpp
index d3f38345..564881b8 100644
--- a/src/audio/AudioLogic.cpp
+++ b/src/audio/AudioLogic.cpp
@@ -37,85 +37,80 @@
#include "Weather.h"
#include "ZoneCull.h"
#include "sampman.h"
+#include "Bike.h"
+#include "WindModifiers.h"
+#include "Fluff.h"
+#include "Script.h"
+#include "Wanted.h"
#ifndef GTA_PS2
#define CHANNEL_PLAYER_VEHICLE_ENGINE m_nActiveSamples
#endif
-uint32 gPornNextTime;
-uint32 gSawMillNextTime;
-uint32 gShopNextTime;
-uint32 gAirportNextTime;
-uint32 gCinemaNextTime;
-uint32 gDocksNextTime;
-uint32 gHomeNextTime;
-uint32 gCellNextTime;
-uint32 gNextCryTime;
-
void
cAudioManager::PreInitialiseGameSpecificSetup()
{
BankStartOffset[SFX_BANK_0] = SAMPLEBANK_START;
#ifdef GTA_PS2
- BankStartOffset[SFX_BANK_PACARD] = SFX_CAR_ACCEL_1;
- BankStartOffset[SFX_BANK_PATHFINDER] = SFX_CAR_ACCEL_2;
- BankStartOffset[SFX_BANK_PORSCHE] = SFX_CAR_ACCEL_3;
- BankStartOffset[SFX_BANK_SPIDER] = SFX_CAR_ACCEL_4;
- BankStartOffset[SFX_BANK_MERC] = SFX_CAR_ACCEL_5;
- BankStartOffset[SFX_BANK_TRUCK] = SFX_CAR_ACCEL_6;
- BankStartOffset[SFX_BANK_HOTROD] = SFX_CAR_ACCEL_7;
- BankStartOffset[SFX_BANK_COBRA] = SFX_CAR_ACCEL_8;
- BankStartOffset[SFX_BANK_NONE] = SFX_CAR_ACCEL_9;
- BankStartOffset[SFX_BANK_FRONT_END_MENU] = SFX_PAGE_CHANGE_AND_BACK_LEFT;
- BankStartOffset[SFX_BANK_TRAIN] = SFX_TRAIN_STATION_AMBIENCE_LOOP;
- BankStartOffset[SFX_BANK_BUILDING_CLUB_1] = SFX_CLUB_1;
- BankStartOffset[SFX_BANK_BUILDING_CLUB_2] = SFX_CLUB_2;
- BankStartOffset[SFX_BANK_BUILDING_CLUB_3] = SFX_CLUB_3;
- BankStartOffset[SFX_BANK_BUILDING_CLUB_4] = SFX_CLUB_4;
- BankStartOffset[SFX_BANK_BUILDING_CLUB_5] = SFX_CLUB_5;
- BankStartOffset[SFX_BANK_BUILDING_CLUB_6] = SFX_CLUB_6;
- BankStartOffset[SFX_BANK_BUILDING_CLUB_7] = SFX_CLUB_7;
- BankStartOffset[SFX_BANK_BUILDING_CLUB_8] = SFX_CLUB_8;
- BankStartOffset[SFX_BANK_BUILDING_CLUB_9] = SFX_CLUB_9;
- BankStartOffset[SFX_BANK_BUILDING_CLUB_10] = SFX_CLUB_10;
- BankStartOffset[SFX_BANK_BUILDING_CLUB_11] = SFX_CLUB_11;
- BankStartOffset[SFX_BANK_BUILDING_CLUB_12] = SFX_CLUB_12;
- BankStartOffset[SFX_BANK_BUILDING_CLUB_RAGGA] = SFX_CLUB_RAGGA;
- BankStartOffset[SFX_BANK_BUILDING_STRIP_CLUB_1] = SFX_STRIP_CLUB_1;
- BankStartOffset[SFX_BANK_BUILDING_STRIP_CLUB_2] = SFX_STRIP_CLUB_2;
- BankStartOffset[SFX_BANK_BUILDING_WORKSHOP] = SFX_WORKSHOP_1;
- BankStartOffset[SFX_BANK_BUILDING_PIANO_BAR] = SFX_PIANO_BAR_1;
- BankStartOffset[SFX_BANK_BUILDING_SAWMILL] = SFX_SAWMILL_LOOP;
- BankStartOffset[SFX_BANK_BUILDING_DOG_FOOD_FACTORY] = SFX_DOG_FOOD_FACTORY;
- BankStartOffset[SFX_BANK_BUILDING_LAUNDERETTE] = SFX_LAUNDERETTE_LOOP;
- BankStartOffset[SFX_BANK_BUILDING_RESTAURANT_CHINATOWN] = SFX_RESTAURANT_CHINATOWN;
- BankStartOffset[SFX_BANK_BUILDING_RESTAURANT_ITALY] = SFX_RESTAURANT_ITALY;
- BankStartOffset[SFX_BANK_BUILDING_RESTAURANT_GENERIC_1] = SFX_RESTAURANT_GENERIC_1;
- BankStartOffset[SFX_BANK_BUILDING_RESTAURANT_GENERIC_2] = SFX_RESTAURANT_GENERIC_2;
- BankStartOffset[SFX_BANK_BUILDING_AIRPORT] = SFX_AIRPORT_ANNOUNCEMENT_1;
- BankStartOffset[SFX_BANK_BUILDING_SHOP] = SFX_SHOP_LOOP;
- BankStartOffset[SFX_BANK_BUILDING_CINEMA] = SFX_CINEMA_BASS_1;
- BankStartOffset[SFX_BANK_BUILDING_DOCKS] = SFX_DOCKS_FOGHORN;
- BankStartOffset[SFX_BANK_BUILDING_HOME] = SFX_HOME_1;
- BankStartOffset[SFX_BANK_BUILDING_PORN_1] = SFX_PORN_1_LOOP;
- BankStartOffset[SFX_BANK_BUILDING_PORN_2] = SFX_PORN_2_LOOP;
- BankStartOffset[SFX_BANK_BUILDING_PORN_3] = SFX_PORN_3_LOOP;
- BankStartOffset[SFX_BANK_BUILDING_POLICE_BALL] = SFX_POLICE_BALL_1;
- BankStartOffset[SFX_BANK_BUILDING_BANK_ALARM] = SFX_BANK_ALARM_1;
- BankStartOffset[SFX_BANK_BUILDING_RAVE_INDUSTRIAL] = SFX_RAVE_INDUSTRIAL;
- BankStartOffset[SFX_BANK_BUILDING_RAVE_COMMERCIAL] = SFX_RAVE_COMMERCIAL;
- BankStartOffset[SFX_BANK_BUILDING_RAVE_SUBURBAN] = SFX_RAVE_SUBURBAN;
- BankStartOffset[SFX_BANK_BUILDING_RAVE_COMMERCIAL_2] = SFX_RAVE_COMMERCIAL_2;
- BankStartOffset[SFX_BANK_BUILDING_39] = SFX_CLUB_1_1;
- BankStartOffset[SFX_BANK_BUILDING_40] = SFX_CLUB_1_2;
- BankStartOffset[SFX_BANK_BUILDING_41] = SFX_CLUB_1_3;
- BankStartOffset[SFX_BANK_BUILDING_42] = SFX_CLUB_1_4;
- BankStartOffset[SFX_BANK_BUILDING_43] = SFX_CLUB_1_5;
- BankStartOffset[SFX_BANK_BUILDING_44] = SFX_CLUB_1_6;
- BankStartOffset[SFX_BANK_BUILDING_45] = SFX_CLUB_1_7;
- BankStartOffset[SFX_BANK_BUILDING_46] = SFX_CLUB_1_8;
- BankStartOffset[SFX_BANK_BUILDING_47] = SFX_CLUB_1_9;
- BankStartOffset[SFX_BANK_GENERIC_EXTRA] = SFX_EXPLOSION_1;
+ BankStartOffset[SAMPLEBANK_CAR_PACARD] = SFX_CAR_ACCEL_1;
+ BankStartOffset[SAMPLEBANK_CAR_PATHFINDER] = SFX_CAR_ACCEL_2;
+ BankStartOffset[SAMPLEBANK_CAR_PORSCHE] = SFX_CAR_ACCEL_3;
+ BankStartOffset[SAMPLEBANK_CAR_SPIDER] = SFX_CAR_ACCEL_4;
+ BankStartOffset[SAMPLEBANK_CAR_MERC] = SFX_CAR_ACCEL_5;
+ BankStartOffset[SAMPLEBANK_CAR_MACKTRUCK] = SFX_CAR_ACCEL_6;
+ BankStartOffset[SAMPLEBANK_CAR_HOTROD] = SFX_CAR_ACCEL_7;
+ BankStartOffset[SAMPLEBANK_CAR_COBRA] = SFX_CAR_ACCEL_8;
+ BankStartOffset[SAMPLEBANK_CAR_NONE] = SFX_CAR_ACCEL_9;
+ BankStartOffset[SAMPLEBANK_FRONTEND] = SFX_PAGE_CHANGE_AND_BACK_LEFT;
+ BankStartOffset[SAMPLEBANK_TRAIN] = SFX_TRAIN_STATION_AMBIENCE_LOOP;
+ BankStartOffset[SAMPLEBANK_BUILDING_CLUB_1] = SFX_CLUB_1;
+ BankStartOffset[SAMPLEBANK_BUILDING_CLUB_2] = SFX_CLUB_2;
+ BankStartOffset[SAMPLEBANK_BUILDING_CLUB_3] = SFX_CLUB_3;
+ BankStartOffset[SAMPLEBANK_BUILDING_CLUB_4] = SFX_CLUB_4;
+ BankStartOffset[SAMPLEBANK_BUILDING_CLUB_5] = SFX_CLUB_5;
+ BankStartOffset[SAMPLEBANK_BUILDING_CLUB_6] = SFX_CLUB_6;
+ BankStartOffset[SAMPLEBANK_BUILDING_CLUB_7] = SFX_CLUB_7;
+ BankStartOffset[SAMPLEBANK_BUILDING_CLUB_8] = SFX_CLUB_8;
+ BankStartOffset[SAMPLEBANK_BUILDING_CLUB_9] = SFX_CLUB_9;
+ BankStartOffset[SAMPLEBANK_BUILDING_CLUB_10] = SFX_CLUB_10;
+ BankStartOffset[SAMPLEBANK_BUILDING_CLUB_11] = SFX_CLUB_11;
+ BankStartOffset[SAMPLEBANK_BUILDING_CLUB_12] = SFX_CLUB_12;
+ BankStartOffset[SAMPLEBANK_BUILDING_CLUB_RAGGA] = SFX_CLUB_RAGGA;
+ BankStartOffset[SAMPLEBANK_BUILDING_STRIP_CLUB_1] = SFX_STRIP_CLUB_1;
+ BankStartOffset[SAMPLEBANK_BUILDING_STRIP_CLUB_2] = SFX_STRIP_CLUB_2;
+ BankStartOffset[SAMPLEBANK_BUILDING_WORKSHOP] = SFX_WORKSHOP_1;
+ BankStartOffset[SAMPLEBANK_BUILDING_PIANO_BAR] = SFX_PIANO_BAR_1;
+ BankStartOffset[SAMPLEBANK_BUILDING_SAWMILL] = SFX_SAWMILL_LOOP;
+ BankStartOffset[SAMPLEBANK_BUILDING_DOG_FOOD_FACTORY] = SFX_DOG_FOOD_FACTORY;
+ BankStartOffset[SAMPLEBANK_BUILDING_LAUNDERETTE] = SFX_LAUNDERETTE_LOOP;
+ BankStartOffset[SAMPLEBANK_BUILDING_RESTAURANT_CHINATOWN] = SFX_RESTAURANT_CHINATOWN;
+ BankStartOffset[SAMPLEBANK_BUILDING_RESTAURANT_ITALY] = SFX_RESTAURANT_ITALY;
+ BankStartOffset[SAMPLEBANK_BUILDING_RESTAURANT_GENERIC_1] = SFX_RESTAURANT_GENERIC_1;
+ BankStartOffset[SAMPLEBANK_BUILDING_RESTAURANT_GENERIC_2] = SFX_RESTAURANT_GENERIC_2;
+ BankStartOffset[SAMPLEBANK_BUILDING_AIRPORT] = SFX_AIRPORT_ANNOUNCEMENT_1;
+ BankStartOffset[SAMPLEBANK_BUILDING_SHOP] = SFX_SHOP_LOOP;
+ BankStartOffset[SAMPLEBANK_BUILDING_CINEMA] = SFX_CINEMA_BASS_1;
+ BankStartOffset[SAMPLEBANK_BUILDING_DOCKS] = SFX_DOCKS_FOGHORN;
+ BankStartOffset[SAMPLEBANK_BUILDING_HOME] = SFX_HOME_1;
+ BankStartOffset[SAMPLEBANK_BUILDING_PORN_1] = SFX_PORN_1_LOOP;
+ BankStartOffset[SAMPLEBANK_BUILDING_PORN_2] = SFX_PORN_2_LOOP;
+ BankStartOffset[SAMPLEBANK_BUILDING_PORN_3] = SFX_PORN_3_LOOP;
+ BankStartOffset[SAMPLEBANK_BUILDING_POLICE_BALL] = SFX_POLICE_BALL_1;
+ BankStartOffset[SAMPLEBANK_BUILDING_BANK_ALARM] = SFX_BANK_ALARM_1;
+ BankStartOffset[SAMPLEBANK_BUILDING_RAVE_INDUSTRIAL] = SFX_RAVE_INDUSTRIAL;
+ BankStartOffset[SAMPLEBANK_BUILDING_RAVE_COMMERCIAL] = SFX_RAVE_COMMERCIAL;
+ BankStartOffset[SAMPLEBANK_BUILDING_RAVE_SUBURBAN] = SFX_RAVE_SUBURBAN;
+ BankStartOffset[SAMPLEBANK_BUILDING_RAVE_COMMERCIAL_2] = SFX_RAVE_COMMERCIAL_2;
+ BankStartOffset[SAMPLEBANK_BUILDING_39] = SFX_CLUB_1_1;
+ BankStartOffset[SAMPLEBANK_BUILDING_40] = SFX_CLUB_1_2;
+ BankStartOffset[SAMPLEBANK_BUILDING_41] = SFX_CLUB_1_3;
+ BankStartOffset[SAMPLEBANK_BUILDING_42] = SFX_CLUB_1_4;
+ BankStartOffset[SAMPLEBANK_BUILDING_43] = SFX_CLUB_1_5;
+ BankStartOffset[SAMPLEBANK_BUILDING_44] = SFX_CLUB_1_6;
+ BankStartOffset[SAMPLEBANK_BUILDING_45] = SFX_CLUB_1_7;
+ BankStartOffset[SAMPLEBANK_BUILDING_46] = SFX_CLUB_1_8;
+ BankStartOffset[SAMPLEBANK_BUILDING_47] = SFX_CLUB_1_9;
+ BankStartOffset[SAMPLEBANK_EXTRAS] = SFX_EXPLOSION_1;
#endif // GTA_PS2
BankStartOffset[SFX_BANK_PED_COMMENTS] = SAMPLEBANK_PED_START;
}
@@ -146,28 +141,62 @@ cAudioManager::PostInitialiseGameSpecificSetup()
m_nPoliceChannelEntity = CreateEntity(AUDIOTYPE_POLICERADIO, (void *)1);
if (m_nPoliceChannelEntity >= 0)
SetEntityStatus(m_nPoliceChannelEntity, TRUE);
-
- m_nBridgeEntity = CreateEntity(AUDIOTYPE_BRIDGE, (void *)1);
+#ifdef GTA_BRIDGE
+ m_nBridgeEntity = CreateEntity(AUDIOTYPE_BRIDGE, (void*)1);
if (m_nBridgeEntity >= 0)
SetEntityStatus(m_nBridgeEntity, TRUE);
+#endif // GTA_BRIDGE
+ m_nEscalatorEntity = CreateEntity(AUDIOTYPE_ESCALATOR, (void*)1);
+ if (m_nEscalatorEntity >= 0)
+ SetEntityStatus(m_nEscalatorEntity, TRUE);
+
+ m_nExtraSoundsEntity = CreateEntity(AUDIOTYPE_EXTRA_SOUNDS, (void*)1);
+ if (m_nExtraSoundsEntity >= 0)
+ SetEntityStatus(m_nExtraSoundsEntity, TRUE);
+
+
+ m_sMissionAudio.m_nSampleIndex[0] = NO_SAMPLE;
+ m_sMissionAudio.m_nLoadingStatus[0] = LOADING_STATUS_NOT_LOADED;
+ m_sMissionAudio.m_nPlayStatus[0] = PLAY_STATUS_STOPPED;
+ m_sMissionAudio.m_bIsPlaying[0] = FALSE;
+ m_sMissionAudio.m_bIsPlayed[0] = FALSE;
+ m_sMissionAudio.m_bPredefinedProperties[0] = TRUE;
+ m_sMissionAudio.m_nMissionAudioCounter[0] = 0;
+ m_sMissionAudio.m_bIsMobile[0] = FALSE;
+ field_5538 = 127;
+ m_sMissionAudio.m_nSampleIndex[1] = NO_SAMPLE;
+ m_sMissionAudio.m_nLoadingStatus[1] = LOADING_STATUS_NOT_LOADED;
+ m_sMissionAudio.m_nPlayStatus[1] = PLAY_STATUS_STOPPED;
+ m_sMissionAudio.m_bIsPlaying[1] = FALSE;
+ m_sMissionAudio.m_bIsPlayed[1] = FALSE;
+ m_sMissionAudio.m_bPredefinedProperties[1] = TRUE;
+ m_sMissionAudio.m_nMissionAudioCounter[1] = 0;
+ m_sMissionAudio.m_bIsMobile[1] = FALSE;
+ field_5538 = 127;
- m_sMissionAudio.m_nSampleIndex = NO_SAMPLE;
- m_sMissionAudio.m_nLoadingStatus = LOADING_STATUS_NOT_LOADED;
- m_sMissionAudio.m_nPlayStatus = PLAY_STATUS_STOPPED;
- m_sMissionAudio.m_bIsPlaying = FALSE;
- m_sMissionAudio.m_bIsPlayed = FALSE;
- m_sMissionAudio.m_bPredefinedProperties = TRUE;
- m_sMissionAudio.m_nMissionAudioCounter = 0;
ResetAudioLogicTimers(CTimer::GetTimeInMilliseconds());
+ m_bIsPlayerShutUp = FALSE;
+ m_nPlayerMood = PLAYER_MOOD_CALM;
+ m_nPlayerMoodTimer = 0;
}
void
cAudioManager::PreTerminateGameSpecificShutdown()
{
+#ifdef GTA_BRIDGE
if (m_nBridgeEntity >= 0) {
DestroyEntity(m_nBridgeEntity);
m_nBridgeEntity = AEHANDLE_NONE;
}
+#endif
+ if (m_nEscalatorEntity >= 0) {
+ DestroyEntity(m_nEscalatorEntity);
+ m_nEscalatorEntity = AEHANDLE_NONE;
+ }
+ if (m_nExtraSoundsEntity >= 0) {
+ DestroyEntity(m_nExtraSoundsEntity);
+ m_nExtraSoundsEntity = AEHANDLE_NONE;
+ }
if (m_nPoliceChannelEntity >= 0) {
DestroyEntity(m_nPoliceChannelEntity);
m_nPoliceChannelEntity = AEHANDLE_NONE;
@@ -203,15 +232,6 @@ 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;
@@ -221,33 +241,28 @@ cAudioManager::ResetAudioLogicTimers(uint32 timer)
}
}
}
- ClearMissionAudio();
+ ClearMissionAudio(0);
+ ClearMissionAudio(1);
SampleManager.StopChannel(CHANNEL_POLICE_RADIO);
}
void
cAudioManager::ProcessReverb()
{
-#ifdef EXTERNAL_3D_SOUND
- if (SampleManager.UpdateReverb() && m_bDynamicAcousticModelingStatus) {
-#ifndef GTA_PS2
- for (uint32 i = 0; i <
#ifdef FIX_BUGS
- NUM_CHANNELS_GENERIC
+ const uint32 numChannels = NUM_CHANNELS_GENERIC;
#else
- NUM_CHANNELS_GENERIC+1
+ const uint32 numChannels = NUM_CHANNELS_GENERIC+1;
#endif
- ;
- i++) {
+
+ if (SampleManager.UpdateReverb() && m_bDynamicAcousticModelingStatus) {
+#ifndef GTA_PS2
+ for (uint32 i = 0; i < numChannels; i++) {
if (m_asActiveSamples[i].m_bReverbFlag)
SampleManager.SetChannelReverbFlag(i, TRUE);
}
#endif
}
-#else
- // TODO: PS2 code
- SampleManager.UpdateReverb();
-#endif
}
float
@@ -266,24 +281,40 @@ cAudioManager::CalculateDistance(bool8 &distCalculated, float dist)
}
}
+CVehicle *
+cAudioManager::FindVehicleOfPlayer()
+{
+ CVehicle* vehicle = FindPlayerVehicle();
+ CPlayerPed* ped = FindPlayerPed();
+ if (vehicle == nil && ped != nil) {
+ CEntity *attachedTo = ped->m_attachedTo;
+ if (attachedTo && attachedTo->IsVehicle())
+ vehicle = (CVehicle*)attachedTo;
+ }
+ return vehicle;
+}
+
void
cAudioManager::ProcessSpecial()
{
+ CPlayerPed *playerPed;
+
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) {
- if(playerPed->EnteringCar() && !playerPed->bInVehicle)
- SampleManager.StopChannel(CHANNEL_PLAYER_VEHICLE_ENGINE);
+ if (!CReplay::IsPlayingBack())
+ ProcessPlayerMood();
+ playerPed = FindPlayerPed();
+ if (playerPed != nil) {
+ if (playerPed->m_audioEntityId >= 0 && m_asAudioEntities[playerPed->m_audioEntityId].m_bIsUsed) {
+ if (playerPed->EnteringCar()) {
+ if(!playerPed->bInVehicle && CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle == nil)
+ SampleManager.StopChannel(CHANNEL_PLAYER_VEHICLE_ENGINE);
+ }
+ }
}
}
}
@@ -315,27 +346,30 @@ cAudioManager::ProcessEntity(int32 id)
case AUDIOTYPE_WEATHER:
if (!m_nUserPause) {
m_sQueueSample.m_bReverbFlag = TRUE;
- ProcessWeather(id);
+ if(CGame::currArea == AREA_MAIN_MAP || CGame::currArea == AREA_EVERYWHERE)
+ ProcessWeather(id);
}
break;
- case AUDIOTYPE_CRANE:
+/* case AUDIOTYPE_CRANE:
if (!m_nUserPause) {
m_sQueueSample.m_bReverbFlag = TRUE;
ProcessCrane();
}
- break;
+ break;*/
case AUDIOTYPE_SCRIPTOBJECT:
if (!m_nUserPause) {
m_sQueueSample.m_bReverbFlag = TRUE;
ProcessScriptObject(id);
}
break;
+#ifdef GTA_BRIDGE
case AUDIOTYPE_BRIDGE:
if (!m_nUserPause) {
m_sQueueSample.m_bReverbFlag = TRUE;
ProcessBridge();
}
break;
+#endif
case AUDIOTYPE_FRONTEND:
m_sQueueSample.m_bReverbFlag = FALSE;
ProcessFrontEnd();
@@ -362,6 +396,18 @@ cAudioManager::ProcessEntity(int32 id)
ProcessWaterCannon(id);
}
break;
+ case AUDIOTYPE_ESCALATOR:
+ if (!m_nUserPause) {
+ m_sQueueSample.m_bReverbFlag = TRUE;
+ ProcessEscalators();
+ }
+ break;
+ case AUDIOTYPE_EXTRA_SOUNDS:
+ if (!m_nUserPause) {
+ m_sQueueSample.m_bReverbFlag = TRUE;
+ ProcessExtraSounds();
+ }
+ break;
default:
return;
}
@@ -394,13 +440,13 @@ enum eVehicleModel {
LINERUN,
PEREN,
SENTINEL,
- PATRIOT,
+ RIO,
FIRETRUK,
TRASH,
STRETCH,
MANANA,
INFERNUS,
- BLISTA,
+ VOODOO,
PONY,
MULE,
CHEETAH,
@@ -409,11 +455,11 @@ enum eVehicleModel {
MOONBEAM,
ESPERANT,
TAXI,
- KURUMA,
+ WASHING,
BOBCAT,
MRWHOOP,
BFINJECT,
- CORPSE,
+ HUNTER,
POLICE,
ENFORCER,
SECURICA,
@@ -422,43 +468,87 @@ enum eVehicleModel {
BUS,
RHINO,
BARRACKS,
- TRAIN,
+ CUBAN,
CHOPPER,
- DODO,
+ ANGEL,
COACH,
CABBIE,
STALLION,
RUMPO,
RCBANDIT,
- BELLYUP,
- MRWONGS,
- MAFIA,
- YARDIE,
- YAKUZA,
- DIABLOS,
- COLUMB,
- HOODS,
+ ROMERO,
+ PACKER,
+ SENTXS,
+ ADMIRAL,
+ SQUALO,
+ SEASPAR,
+ PIZZABOY,
+ GANGBUR,
AIRTRAIN,
DEADDODO,
SPEEDER,
REEFER,
- PANLANT,
+ TROPIC,
FLATBED,
YANKEE,
- ESCAPE,
- BORGNINE,
- TOYZ,
- GHOST,
- CAR151,
- CAR152,
- CAR153,
- CAR154,
- CAR155,
- CAR156,
- CAR157,
- CAR158,
- CAR159,
- MAX_CARS
+ 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,
+ CAR237,
+ CAR238,
+ CAR239,
+ MAX_CARS,
+
+ // HACK so this compiles
+ // TODO(MIAMI): check it out
+ DODO = -1
};
enum
@@ -481,77 +571,116 @@ struct tVehicleSampleData {
};
const tVehicleSampleData aVehicleSettings[MAX_CARS] = {
- {SFX_CAR_REV_2, SFX_BANK_PATHFINDER, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_ALARM_1, 9935, NEW_DOOR},
- {SFX_CAR_REV_1, SFX_BANK_PACARD, SFX_CAR_HORN_56CHEV, 11487, SFX_CAR_ALARM_1, 9935, OLD_DOOR},
- {SFX_CAR_REV_8, SFX_BANK_COBRA, SFX_CAR_HORN_PORSCHE, 11025, SFX_CAR_ALARM_1, 10928, NEW_DOOR},
- {SFX_CAR_REV_6, SFX_BANK_TRUCK, SFX_CAR_HORN_TRUCK, 29711, SFX_CAR_ALARM_1, 9935, TRUCK_DOOR},
- {SFX_CAR_REV_1, SFX_BANK_PACARD, SFX_CAR_HORN_56CHEV, 12893, SFX_CAR_ALARM_1, 8941, OLD_DOOR},
- {SFX_CAR_REV_5, SFX_BANK_MERC, SFX_CAR_HORN_BMW328, 10706, SFX_CAR_ALARM_1, 11922, NEW_DOOR},
- {SFX_CAR_REV_4, SFX_BANK_SPIDER, SFX_CAR_HORN_TRUCK, 29711, SFX_CAR_ALARM_1, 7948, TRUCK_DOOR},
- {SFX_CAR_REV_6, SFX_BANK_TRUCK, SFX_CAR_HORN_TRUCK, 29711, SFX_POLICE_SIREN_SLOW, 11556, TRUCK_DOOR},
- {SFX_CAR_REV_6, SFX_BANK_TRUCK, SFX_CAR_HORN_TRUCK, 31478, SFX_CAR_ALARM_1, 8941, TRUCK_DOOR},
- {SFX_CAR_REV_1, SFX_BANK_PACARD, SFX_CAR_HORN_BMW328, 9538, SFX_CAR_ALARM_1, 12220, NEW_DOOR},
- {SFX_CAR_REV_1, SFX_BANK_PACARD, SFX_CAR_HORN_56CHEV, 10842, SFX_CAR_ALARM_1, 9935, OLD_DOOR},
- {SFX_CAR_REV_3, SFX_BANK_PORSCHE, SFX_CAR_HORN_BMW328, 12017, SFX_CAR_ALARM_1, 9935, NEW_DOOR},
- {SFX_CAR_REV_2, SFX_BANK_PATHFINDER, SFX_CAR_HORN_JEEP, 22295, SFX_CAR_ALARM_1, 12200, NEW_DOOR},
- {SFX_CAR_REV_4, SFX_BANK_SPIDER, SFX_CAR_HORN_BUS2, 18000, SFX_CAR_ALARM_1, 13400, NEW_DOOR},
- {SFX_CAR_REV_4, SFX_BANK_SPIDER, SFX_CAR_HORN_BUS, 18286, SFX_CAR_ALARM_1, 9935, TRUCK_DOOR},
- {SFX_CAR_REV_3, SFX_BANK_PORSCHE, SFX_CAR_HORN_PORSCHE, 11025, SFX_CAR_ALARM_1, 13600, NEW_DOOR},
- {SFX_CAR_REV_4, SFX_BANK_SPIDER, SFX_CAR_HORN_JEEP, 22295, SFX_AMBULANCE_SIREN_SLOW, 8795, TRUCK_DOOR},
- {SFX_CAR_REV_5, SFX_BANK_MERC, SFX_CAR_HORN_PORSCHE, 9271, SFX_POLICE_SIREN_SLOW, 16168, NEW_DOOR},
- {SFX_CAR_REV_1, SFX_BANK_PACARD, SFX_CAR_HORN_56CHEV, 12170, SFX_CAR_ALARM_1, 8000, NEW_DOOR},
- {SFX_CAR_REV_1, SFX_BANK_PACARD, SFX_CAR_HORN_BUS2, 12345, SFX_CAR_ALARM_1, 9935, OLD_DOOR},
- {SFX_CAR_REV_2, SFX_BANK_PATHFINDER, SFX_CAR_HORN_BMW328, 10796, SFX_CAR_ALARM_1, 8543, NEW_DOOR},
- {SFX_CAR_REV_5, SFX_BANK_MERC, SFX_CAR_HORN_PORSCHE, 9271, SFX_CAR_ALARM_1, 9935, NEW_DOOR},
- {SFX_CAR_REV_2, SFX_BANK_PATHFINDER, SFX_CAR_HORN_PICKUP, 10924, SFX_CAR_ALARM_1, 9935, NEW_DOOR},
- {SFX_CAR_REV_1, SFX_BANK_PACARD, SFX_CAR_HORN_PICKUP, 11025, SFX_ICE_CREAM_TUNE, 11025, OLD_DOOR},
- {SFX_CAR_REV_7, SFX_BANK_HOTROD, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_ALARM_1, 9935, NEW_DOOR},
- {SFX_CAR_REV_1, SFX_BANK_PACARD, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_ALARM_1, 10000, OLD_DOOR},
- {SFX_CAR_REV_5, SFX_BANK_MERC, SFX_CAR_HORN_BMW328, 10706, SFX_POLICE_SIREN_SLOW, 13596, NEW_DOOR},
- {SFX_CAR_REV_4, SFX_BANK_SPIDER, SFX_CAR_HORN_BUS, 17260, SFX_POLICE_SIREN_SLOW, 13000, TRUCK_DOOR},
- {SFX_CAR_REV_4, SFX_BANK_SPIDER, SFX_CAR_HORN_PICKUP, 8670, SFX_CAR_ALARM_1, 9935, TRUCK_DOOR},
- {SFX_CAR_REV_8, SFX_BANK_COBRA, SFX_CAR_HORN_PORSCHE, 10400, SFX_CAR_ALARM_1, 10123, NEW_DOOR},
- {SFX_CAR_REV_1, SFX_BANK_PACARD, SFX_CAR_HORN_JEEP, 26513, SFX_POLICE_SIREN_SLOW, 13596, OLD_DOOR},
- {SFX_CAR_REV_6, SFX_BANK_TRUCK, SFX_CAR_HORN_BUS2, 11652, SFX_CAR_ALARM_1, 10554, BUS_DOOR},
- {SFX_CAR_REV_6, SFX_BANK_TRUCK, SFX_CAR_HORN_TRUCK, 29711, SFX_CAR_ALARM_1, 8000, TRUCK_DOOR},
- {SFX_CAR_REV_6, SFX_BANK_TRUCK, SFX_CAR_HORN_TRUCK, 28043, SFX_CAR_ALARM_1, 9935, TRUCK_DOOR},
- {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_TRUCK, 29711, SFX_CAR_ALARM_1, 9935, BUS_DOOR},
- {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_ALARM_1, 9935, OLD_DOOR},
- {SFX_CESNA_IDLE, SFX_BANK_0, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_ALARM_1, 9935, OLD_DOOR},
- {SFX_CAR_REV_6, SFX_BANK_TRUCK, SFX_CAR_HORN_BUS, 16291, SFX_CAR_ALARM_1, 7500, BUS_DOOR},
- {SFX_CAR_REV_1, SFX_BANK_PACARD, SFX_CAR_HORN_56CHEV, 10842, SFX_CAR_ALARM_1, 9935, OLD_DOOR},
- {SFX_CAR_REV_1, SFX_BANK_PACARD, SFX_CAR_HORN_56CHEV, 10233, SFX_CAR_ALARM_1, 8935, OLD_DOOR},
- {SFX_CAR_REV_4, SFX_BANK_SPIDER, SFX_CAR_HORN_PICKUP, 8670, SFX_CAR_ALARM_1, 8935, OLD_DOOR},
- {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_PICKUP, 2000, SFX_CAR_ALARM_1, 17000, OLD_DOOR},
- {SFX_CAR_REV_4, SFX_BANK_SPIDER, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, OLD_DOOR},
- {SFX_CAR_REV_4, SFX_BANK_SPIDER, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, OLD_DOOR},
- {SFX_CAR_REV_5, SFX_BANK_MERC, SFX_CAR_HORN_BMW328, 9003, SFX_CAR_ALARM_1, 9935, NEW_DOOR},
- {SFX_CAR_REV_2, SFX_BANK_PATHFINDER, SFX_CAR_HORN_PORSCHE, 12375, SFX_CAR_ALARM_1, 9935, NEW_DOOR},
- {SFX_CAR_REV_5, SFX_BANK_MERC, SFX_CAR_HORN_BUS2, 15554, SFX_CAR_ALARM_1, 9935, NEW_DOOR},
- {SFX_CAR_REV_7, SFX_BANK_HOTROD, SFX_CAR_HORN_BUS2, 13857, SFX_CAR_ALARM_1, 9935, OLD_DOOR},
- {SFX_CAR_REV_7, SFX_BANK_HOTROD, SFX_CAR_HORN_PICKUP, 10924, SFX_CAR_ALARM_1, 9935, OLD_DOOR},
- {SFX_CAR_REV_4, SFX_BANK_SPIDER, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, TRUCK_DOOR},
- {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_JEEP, 20143, SFX_CAR_ALARM_1, 9935, OLD_DOOR},
- {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, OLD_DOOR},
- {SFX_CAR_REV_1, SFX_BANK_PACARD, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, OLD_DOOR},
- {SFX_CAR_REV_1, SFX_BANK_PACARD, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, OLD_DOOR},
- {SFX_CAR_REV_4, SFX_BANK_SPIDER, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9000, OLD_DOOR},
- {SFX_CAR_REV_6, SFX_BANK_TRUCK, SFX_CAR_HORN_TRUCK, 28043, SFX_CAR_ALARM_1, 9935, TRUCK_DOOR},
- {SFX_CAR_REV_4, SFX_BANK_SPIDER, SFX_CAR_HORN_BUS, 18286, SFX_CAR_ALARM_1, 9935, TRUCK_DOOR},
- {SFX_CAR_REV_1, SFX_BANK_PACARD, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, OLD_DOOR},
- {SFX_CAR_REV_1, SFX_BANK_PACARD, SFX_CAR_HORN_56CHEV, 10842, SFX_CAR_ALARM_1, 9935, OLD_DOOR},
- {SFX_CAR_REV_4, SFX_BANK_SPIDER, SFX_CAR_HORN_BUS2, 18000, SFX_CAR_ALARM_1, 13400, NEW_DOOR},
- {SFX_CAR_REV_1, SFX_BANK_PACARD, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, OLD_DOOR},
- {SFX_CAR_REV_1, SFX_BANK_PACARD, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, OLD_DOOR},
- {SFX_CAR_REV_1, SFX_BANK_PACARD, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, OLD_DOOR},
- {SFX_CAR_REV_1, SFX_BANK_PACARD, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, OLD_DOOR},
- {SFX_CAR_REV_1, SFX_BANK_PACARD, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, OLD_DOOR},
- {SFX_CAR_REV_1, SFX_BANK_PACARD, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, OLD_DOOR},
- {SFX_CAR_REV_1, SFX_BANK_PACARD, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, OLD_DOOR},
- {SFX_CAR_REV_1, SFX_BANK_PACARD, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, OLD_DOOR},
- {SFX_CAR_REV_1, SFX_BANK_PACARD, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, OLD_DOOR},
- {SFX_CAR_REV_1, SFX_BANK_PACARD, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, OLD_DOOR}};
-
+ {SFX_CAR_REV_10, SFX_BANK_PATHFINDER, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9935, OLD_DOOR},
+ {SFX_CAR_REV_11, SFX_BANK_PACARD, SFX_CAR_HORN_56CHEV, 11487, SFX_CAR_HORN_JEEP, 9900, OLD_DOOR},
+ {SFX_CAR_REV_2, SFX_BANK_PORSCHE, SFX_CAR_HORN_PORSCHE, 11025, SFX_CAR_HORN_JEEP, 9890, NEW_DOOR},
+ {SFX_CAR_REV_5, SFX_BANK_TRUCK, SFX_CAR_HORN_TRUCK, 29711, SFX_CAR_HORN_JEEP, 9960, TRUCK_DOOR},
+ {SFX_CAR_REV_11, SFX_BANK_PACARD, SFX_CAR_HORN_56CHEV, 12893, SFX_CAR_HORN_JEEP, 9500, OLD_DOOR},
+ {SFX_CAR_REV_4, SFX_BANK_MERC, SFX_CAR_HORN_BMW328, 10706, SFX_CAR_HORN_JEEP, 9600, NEW_DOOR},
+ {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_TRUCK, 29711, SFX_CAR_HORN_JEEP, 9700, NEW_DOOR},
+ {SFX_CAR_REV_5, SFX_BANK_TRUCK, SFX_CAR_HORN_TRUCK, 29711, SFX_POLICE_SIREN_SLOW, 10588, TRUCK_DOOR},
+ {SFX_CAR_REV_5, SFX_BANK_TRUCK, SFX_CAR_HORN_TRUCK, 31478, SFX_CAR_HORN_JEEP, 9800, TRUCK_DOOR},
+ {SFX_CAR_REV_11, SFX_BANK_PACARD, SFX_CAR_HORN_BMW328, 9538, SFX_CAR_HORN_JEEP, 9900, NEW_DOOR},
+ {SFX_CAR_REV_11, SFX_BANK_PACARD, SFX_CAR_HORN_56CHEV, 10842, SFX_CAR_HORN_JEEP, 10000, OLD_DOOR},
+ {SFX_CAR_REV_7, SFX_BANK_COBRA, SFX_CAR_HORN_BMW328, 12017, SFX_CAR_HORN_JEEP, 9900, NEW_DOOR},
+ {SFX_CAR_REV_9, SFX_BANK_CADILLAC, SFX_CAR_HORN_JEEP, 22293, SFX_CAR_HORN_JEEP, 9800, NEW_DOOR},
+ {SFX_CAR_REV_3, SFX_BANK_SPIDER, SFX_CAR_HORN_BUS2, 18000, SFX_CAR_HORN_JEEP, 9700, OLD_DOOR},
+ {SFX_CAR_REV_3, SFX_BANK_SPIDER, SFX_CAR_HORN_BUS, 18286, SFX_CAR_HORN_JEEP, 9600, OLD_DOOR},
+ {SFX_CAR_REV_2, SFX_BANK_PORSCHE, SFX_CAR_HORN_PORSCHE, 11025, SFX_CAR_HORN_JEEP, 9500, NEW_DOOR},
+ {SFX_CAR_REV_3, SFX_BANK_SPIDER, SFX_CAR_HORN_JEEP, 22295, SFX_AMBULANCE_SIREN_SLOW, 12688, OLD_DOOR},
+ {SFX_CAR_REV_4, SFX_BANK_MERC, SFX_CAR_HORN_PORSCHE, 9271, SFX_POLICE_SIREN_SLOW, 11471, NEW_DOOR},
+ {SFX_CAR_REV_11, SFX_BANK_PACARD, SFX_CAR_HORN_56CHEV, 12170, SFX_CAR_HORN_JEEP, 9400, OLD_DOOR},
+ {SFX_CAR_REV_11, SFX_BANK_PACARD, SFX_CAR_HORN_BMW328, 11000, SFX_CAR_HORN_JEEP, 9300, OLD_DOOR},
+ {SFX_CAR_REV_10, SFX_BANK_PATHFINDER, SFX_CAR_HORN_BMW328, 10796, SFX_CAR_HORN_JEEP, 9200, NEW_DOOR},
+ {SFX_CAR_REV_4, SFX_BANK_MERC, SFX_CAR_HORN_BMW328, 10500, SFX_CAR_HORN_JEEP, 9100, NEW_DOOR},
+ {SFX_CAR_REV_10, SFX_BANK_PATHFINDER, SFX_CAR_HORN_PICKUP, 10924, SFX_CAR_HORN_JEEP, 9000, OLD_DOOR},
+ {SFX_CAR_REV_3, SFX_BANK_SPIDER, SFX_CAR_HORN_PICKUP, 11025, SFX_ICE_CREAM_TUNE, 11025, OLD_DOOR},
+ {SFX_CAR_REV_6, SFX_BANK_HOTROD, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9100, OLD_DOOR},
+ {SFX_HELI_APACHE_1, SFX_BANK_HELI_APACHE, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9200, NEW_DOOR},
+ {SFX_CAR_REV_4, SFX_BANK_MERC, SFX_CAR_HORN_BMW328, 10706, SFX_POLICE_SIREN_SLOW, 10511, NEW_DOOR},
+ {SFX_CAR_REV_3, SFX_BANK_SPIDER, SFX_CAR_HORN_BUS, 17260, SFX_POLICE_SIREN_SLOW, 11029, OLD_DOOR},
+ {SFX_CAR_REV_3, SFX_BANK_SPIDER, SFX_CAR_HORN_PICKUP, 8670, SFX_CAR_HORN_JEEP, 9300, OLD_DOOR},
+ {SFX_CAR_REV_7, SFX_BANK_COBRA, SFX_CAR_HORN_PORSCHE, 10400, SFX_CAR_HORN_JEEP, 9400, NEW_DOOR},
+ {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_JEEP, 26513, SFX_POLICE_SIREN_SLOW, 11912, NEW_DOOR},
+ {SFX_CAR_REV_5, SFX_BANK_TRUCK, SFX_CAR_HORN_BUS2, 11652, SFX_CAR_HORN_JEEP, 9500, BUS_DOOR},
+ {SFX_CAR_REV_5, SFX_BANK_TRUCK, SFX_CAR_HORN_TRUCK, 29711, SFX_CAR_HORN_JEEP, 9600, TRUCK_DOOR},
+ {SFX_CAR_REV_5, SFX_BANK_TRUCK, SFX_CAR_HORN_TRUCK, 28043, SFX_CAR_HORN_JEEP, 9700, TRUCK_DOOR},
+ {SFX_CAR_REV_6, SFX_BANK_HOTROD, SFX_CAR_HORN_JEEP, 25400, SFX_CAR_HORN_JEEP, 9800, OLD_DOOR},
+ {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9900, NEW_DOOR},
+ {SFX_CAR_REV_17, SFX_BANK_VTWIN, SFX_CAR_HORN_JEEP, 26313, SFX_CAR_HORN_JEEP, 10000, NEW_DOOR},
+ {SFX_CAR_REV_5, SFX_BANK_TRUCK, SFX_CAR_HORN_BUS, 16291, SFX_CAR_HORN_JEEP, 10100, BUS_DOOR},
+ {SFX_CAR_REV_11, SFX_BANK_PACARD, SFX_CAR_HORN_56CHEV, 10842, SFX_CAR_HORN_JEEP, 9900, OLD_DOOR},
+ {SFX_CAR_REV_11, SFX_BANK_PACARD, SFX_CAR_HORN_56CHEV, 10233, SFX_CAR_HORN_JEEP, 9800, NEW_DOOR},
+ {SFX_CAR_REV_3, SFX_BANK_SPIDER, SFX_CAR_HORN_PICKUP, 8670, SFX_CAR_HORN_JEEP, 9700, OLD_DOOR},
+ {SFX_RC_REV, SFX_BANK_RC, SFX_CAR_HORN_PICKUP, 20000, SFX_CAR_HORN_JEEP, 9600, NEW_DOOR},
+ {SFX_CAR_REV_11, SFX_BANK_PACARD, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9500, NEW_DOOR},
+ {SFX_CAR_REV_5, SFX_BANK_TRUCK, SFX_CAR_HORN_TRUCK, 29000, SFX_CAR_HORN_JEEP, 9400, TRUCK_DOOR},
+ {SFX_CAR_REV_1, CAR_SFX_BANKS_OFFSET, SFX_CAR_HORN_BMW328, 9003, SFX_CAR_HORN_JEEP, 9300, NEW_DOOR},
+ {SFX_CAR_REV_4, SFX_BANK_MERC, SFX_CAR_HORN_PORSCHE, 12375, SFX_CAR_HORN_JEEP, 9200, NEW_DOOR},
+ {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_BUS2, 15554, SFX_CAR_HORN_JEEP, 9100, NEW_DOOR},
+ {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_BUS2, 13857, SFX_CAR_HORN_JEEP, 9000, TRUCK_DOOR},
+ {SFX_MOPED_REV, SFX_BANK_MOPED, SFX_CAR_HORN_JEEP, 30000, SFX_CAR_HORN_JEEP, 9100, NEW_DOOR},
+ {SFX_CAR_REV_7, SFX_BANK_COBRA, SFX_CAR_HORN_JEEP, 22043, SFX_CAR_HORN_JEEP, 9200, OLD_DOOR},
+ {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9300, NEW_DOOR},
+ {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9400, NEW_DOOR},
+ {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9500, NEW_DOOR},
+ {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9600, NEW_DOOR},
+ {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_JEEP, 21043, SFX_CAR_HORN_JEEP, 9700, NEW_DOOR},
+ {SFX_CAR_REV_5, SFX_BANK_TRUCK, SFX_CAR_HORN_TRUCK, 28043, SFX_CAR_HORN_JEEP, 9800, TRUCK_DOOR},
+ {SFX_CAR_REV_3, SFX_BANK_SPIDER, SFX_CAR_HORN_BUS, 18286, SFX_CAR_HORN_JEEP, 9900, OLD_DOOR},
+ {SFX_CAR_REV_12, SFX_BANK_GOLF_CART, SFX_CAR_HORN_JEEP, 28500, SFX_CAR_HORN_JEEP, 9800, NEW_DOOR},
+ {SFX_CAR_REV_1, CAR_SFX_BANKS_OFFSET, SFX_CAR_HORN_56CHEV, 10842, SFX_CAR_HORN_JEEP, 9700, OLD_DOOR},
+ {SFX_CAR_REV_8, SFX_BANK_PONTIAC_SLOW, SFX_CAR_HORN_BUS2, 18000, SFX_CAR_HORN_JEEP, 9700, OLD_DOOR},
+ {SFX_SEAPLANE_PRO1, SFX_BANK_PLANE_SEAPLANE, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9700, NEW_DOOR},
+ {SFX_CAR_REV_20, SFX_BANK_SPORTS_BIKE, SFX_CAR_HORN_JEEP, 27000, SFX_CAR_HORN_JEEP, 9600, NEW_DOOR},
+ {SFX_MOPED_REV, SFX_BANK_MOPED, SFX_CAR_HORN_JEEP, 31000, SFX_CAR_HORN_JEEP, 9500, NEW_DOOR},
+ {SFX_CAR_REV_17, SFX_BANK_VTWIN, SFX_CAR_HORN_PICKUP, 11000, SFX_CAR_HORN_JEEP, 9400, NEW_DOOR},
+ {SFX_RC_REV, SFX_BANK_RC, SFX_CAR_HORN_JEEP, 30000, SFX_CAR_HORN_JEEP, 15000, NEW_DOOR},
+ {SFX_CAR_RC_HELI, SFX_BANK_RC_HELI, SFX_CAR_HORN_JEEP, 30000, SFX_CAR_HORN_JEEP, 15000, NEW_DOOR},
+ {SFX_CAR_REV_9, SFX_BANK_CADILLAC, SFX_CAR_HORN_56CHEV, 10300, SFX_CAR_HORN_JEEP, 9100, OLD_DOOR},
+ {SFX_CAR_REV_9, SFX_BANK_CADILLAC, SFX_CAR_HORN_56CHEV, 10500, SFX_CAR_HORN_JEEP, 9000, OLD_DOOR},
+ {SFX_CAR_REV_19, SFX_BANK_HONDA250, SFX_CAR_HORN_JEEP, 30000, SFX_CAR_HORN_JEEP, 9000, NEW_DOOR},
+ {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9100, TRUCK_DOOR},
+ {SFX_CAR_REV_3, SFX_BANK_SPIDER, SFX_CAR_HORN_TRUCK, 28000, SFX_CAR_HORN_JEEP, 9200, TRUCK_DOOR},
+ {SFX_CAR_REV_7, SFX_BANK_COBRA, SFX_CAR_HORN_PICKUP, 11200, SFX_CAR_HORN_JEEP, 9300, NEW_DOOR},
+ {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9400, NEW_DOOR},
+ {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9500, NEW_DOOR},
+ {SFX_CAR_REV_9, SFX_BANK_CADILLAC, SFX_CAR_HORN_56CHEV, 10700, SFX_CAR_HORN_JEEP, 9600, OLD_DOOR},
+ {SFX_CAR_REV_1, CAR_SFX_BANKS_OFFSET, SFX_CAR_HORN_BMW328, 9000, SFX_CAR_HORN_JEEP, 9700, OLD_DOOR},
+ {SFX_CAR_REV_6, SFX_BANK_HOTROD, SFX_CAR_HORN_BMW328, 9200, SFX_CAR_HORN_JEEP, 9800, OLD_DOOR},
+ {SFX_CAR_REV_7, SFX_BANK_COBRA, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9900, NEW_DOOR},
+ {SFX_CAR_REV_11, SFX_BANK_PACARD, SFX_CAR_HORN_56CHEV, 10540, SFX_CAR_HORN_JEEP, 9935, TRUCK_DOOR},
+ {SFX_CAR_REV_8, SFX_BANK_PONTIAC_SLOW, SFX_CAR_HORN_PICKUP, 11000, SFX_CAR_HORN_JEEP, 9700, NEW_DOOR},
+ {SFX_CAR_REV_2, SFX_BANK_PORSCHE, SFX_CAR_HORN_BMW328, 9500, SFX_CAR_HORN_JEEP, 9800, NEW_DOOR},
+ {SFX_CAR_REV_7, SFX_BANK_COBRA, SFX_CAR_HORN_BMW328, 9700, SFX_CAR_HORN_JEEP, 9700, NEW_DOOR},
+ {SFX_CAR_REV_8, SFX_BANK_PONTIAC_SLOW, SFX_CAR_HORN_BUS2, 18000, SFX_CAR_HORN_JEEP, 9600, OLD_DOOR},
+ {SFX_CAR_REV_3, SFX_BANK_SPIDER, SFX_CAR_HORN_BUS, 18000, SFX_CAR_HORN_JEEP, 9500, TRUCK_DOOR},
+ {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9400, NEW_DOOR},
+ {SFX_CAR_REV_8, SFX_BANK_PONTIAC_SLOW, SFX_CAR_HORN_JEEP, 27513, SFX_CAR_HORN_JEEP, 9300, NEW_DOOR},
+ {SFX_CAR_REV_8, SFX_BANK_PONTIAC_SLOW, SFX_CAR_HORN_56CHEV, 10700, SFX_CAR_HORN_JEEP, 9200, OLD_DOOR},
+ {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9100, TRUCK_DOOR},
+ {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9000, TRUCK_DOOR},
+ {SFX_CAR_REV_10, SFX_BANK_PATHFINDER, SFX_CAR_HORN_BUS2, 18000, SFX_CAR_HORN_JEEP, 9100, TRUCK_DOOR},
+ {SFX_CAR_REV_1, CAR_SFX_BANKS_OFFSET, SFX_CAR_HORN_BUS2, 17900, SFX_POLICE_SIREN_SLOW, 10511, TRUCK_DOOR},
+ {SFX_CAR_REV_4, SFX_BANK_MERC, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9200, NEW_DOOR},
+ {SFX_CAR_REV_8, SFX_BANK_PONTIAC_SLOW, SFX_CAR_HORN_BMW328, 9600, SFX_CAR_HORN_JEEP, 9300, NEW_DOOR},
+ {SFX_CAR_REV_4, SFX_BANK_0, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9400, NEW_DOOR},
+ {SFX_CAR_REV_7, SFX_BANK_COBRA, SFX_CAR_HORN_PORSCHE, 10000, SFX_CAR_HORN_JEEP, 9500, OLD_DOOR},
+ {SFX_CAR_REV_6, SFX_BANK_HOTROD, SFX_CAR_HORN_PORSCHE, 10500, SFX_CAR_HORN_JEEP, 9600, OLD_DOOR},
+ {SFX_CAR_REV_10, SFX_BANK_PATHFINDER, SFX_CAR_HORN_JEEP, 25513, SFX_CAR_HORN_JEEP, 9700, NEW_DOOR},
+ {SFX_CAR_REV_1, SFX_BANK_0, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9800, NEW_DOOR},
+ {SFX_CAR_REV_3, SFX_BANK_SPIDER, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9900, NEW_DOOR},
+ {SFX_CAR_REV_10, SFX_BANK_PATHFINDER, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9800, NEW_DOOR},
+ {SFX_CAR_REV_1, CAR_SFX_BANKS_OFFSET, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9700, NEW_DOOR},
+ {SFX_CAR_RC_HELI, SFX_BANK_RC_HELI, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9600, NEW_DOOR},
+ {SFX_CAR_REV_6, SFX_BANK_HOTROD, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9700, NEW_DOOR},
+ {SFX_CAR_REV_7, SFX_BANK_COBRA, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9600, NEW_DOOR},
+ {SFX_CAR_REV_1, CAR_SFX_BANKS_OFFSET, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9500, NEW_DOOR},
+ {SFX_CAR_REV_9, SFX_BANK_CADILLAC, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9400, NEW_DOOR},
+ {SFX_CAR_REV_2, SFX_BANK_PORSCHE, SFX_CAR_HORN_PORSCHE, 11025, SFX_POLICE_SIREN_SLOW, 11000, NEW_DOOR},
+ {SFX_CAR_REV_1, CAR_SFX_BANKS_OFFSET, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9200, NEW_DOOR},
+ {SFX_CAR_REV_1, CAR_SFX_BANKS_OFFSET, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9300, NEW_DOOR},
+ {SFX_CAR_REV_1, CAR_SFX_BANKS_OFFSET, SFX_CAR_HORN_JEEP, 26513, SFX_CAR_HORN_JEEP, 9400, NEW_DOOR} };
bool8 bPlayerJustEnteredCar;
@@ -574,128 +703,504 @@ const bool8 hornPatternsArray[8][44] = {
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)
+cAudioManager::ProcessVehicle(CVehicle* veh)
{
- tHandlingData *handling = veh->pHandling;
- float velChange;
+ CVehicle* playerVeh;
cVehicleParams params;
- m_sQueueSample.m_vecPos = veh->GetPosition();
+ CBike* bike;
+ CAutomobile* automobile;
+
+ playerVeh = FindVehicleOfPlayer();
+ if (playerVeh == veh
+ || CGame::currArea == AREA_OVALRING
+ || CGame::currArea == AREA_BLOOD
+ || CGame::currArea == AREA_DIRT
+ || CGame::currArea == AREA_EVERYWHERE
+ || CGame::currArea == AREA_MALL
+ || CGame::currArea == AREA_MAIN_MAP) {
+ m_sQueueSample.m_vecPos = veh->GetPosition();
+ params.m_bDistanceCalculated = FALSE;
+ params.m_pVehicle = veh;
+ params.m_fDistance = GetDistanceSquared(m_sQueueSample.m_vecPos);
+ params.m_pTransmission = veh->pHandling != nil ? &veh->pHandling->Transmission : nil;
+ params.m_nIndex = veh->m_modelIndex - MI_FIRST_VEHICLE;
+ if (veh->GetStatus() == STATUS_SIMPLE)
+ params.m_fVelocityChange = veh->AutoPilot.m_fMaxTrafficSpeed * 0.02f;
+ else
+ params.m_fVelocityChange = DotProduct(veh->m_vecMoveSpeed, veh->GetForward());
+ params.m_VehicleType = veh->m_vehType;
+
+ if (CGame::currArea == AREA_MALL && playerVeh != veh) {
+ ProcessVehicleOneShots(params);
+ ProcessVehicleSirenOrAlarm(params);
+ ProcessEngineDamage(params);
+ return;
+ }
+ switch (params.m_VehicleType) {
+ case VEHICLE_TYPE_CAR:
+ automobile = (CAutomobile*)veh;
+ UpdateGasPedalAudio(veh, params.m_VehicleType);
+ if (veh->m_modelIndex == MI_RCBANDIT || veh->m_modelIndex == MI_RCBARON) {
+ ProcessModelVehicle(params);
+ ProcessEngineDamage(params);
+ } else if (veh->m_modelIndex == MI_RCRAIDER || veh->m_modelIndex == MI_RCGOBLIN) {
+ ProcessModelHeliVehicle(params);
+ ProcessEngineDamage(params);
+ } else {
+ switch (veh->GetVehicleAppearance()) {
+ case VEHICLE_APPEARANCE_HELI:
+ ProcessCarHeli(params);
+ ProcessVehicleFlatTyre(params);
+ ProcessEngineDamage(params);
+ break;
+ case VEHICLE_APPEARANCE_BOAT:
+ case VEHICLE_APPEARANCE_PLANE:
+ break;
+ default:
+ if (ProcessVehicleRoadNoise(params)) {
+ ProcessReverseGear(params);
+ if (CWeather::WetRoads > 0.0f)
+ ProcessWetRoadNoise(params);
+ ProcessVehicleSkidding(params);
+ ProcessVehicleFlatTyre(params);
+ ProcessVehicleHorn(params);
+ ProcessVehicleSirenOrAlarm(params);
+ if (UsesReverseWarning(params.m_nIndex))
+ ProcessVehicleReverseWarning(params);
+ if(HasAirBrakes(params.m_nIndex))
+ ProcessAirBrakes(params);
+ ProcessCarBombTick(params);
+ ProcessVehicleEngine(params);
+ ProcessEngineDamage(params);
+ ProcessVehicleDoors(params);
+ }
+ break;
+ }
+ }
+ ProcessVehicleOneShots(params);
+ automobile->m_fVelocityChangeForAudio = params.m_fVelocityChange;
+ break;
+ case VEHICLE_TYPE_BOAT:
+ if (veh->m_modelIndex == MI_SKIMMER)
+ ProcessCarHeli(params);
+ else
+ ProcessBoatEngine(params);
+ ProcessBoatMovingOverWater(params);
+ ProcessVehicleOneShots(params);
+ break;
+ case VEHICLE_TYPE_HELI:
+ ProcessCarHeli(params);
+ ProcessVehicleOneShots(params);
+ break;
+ case VEHICLE_TYPE_PLANE:
+ ProcessPlane(params);
+ ProcessVehicleOneShots(params);
+ ProcessVehicleFlatTyre(params);
+ break;
+ case VEHICLE_TYPE_BIKE:
+ bike = (CBike*)veh;
+ UpdateGasPedalAudio(veh, params.m_VehicleType);
+ if (ProcessVehicleRoadNoise(params)) {
+ if (CWeather::WetRoads > 0.0f)
+ ProcessWetRoadNoise(params);
+ ProcessVehicleSkidding(params);
+ ProcessVehicleHorn(params);
+ ProcessVehicleSirenOrAlarm(params);
+ ProcessCarBombTick(params);
+ ProcessEngineDamage(params);
+ ProcessVehicleEngine(params);
+ ProcessVehicleFlatTyre(params);
+ }
+ ProcessVehicleOneShots(params);
+ bike->m_fVelocityChangeForAudio = params.m_fVelocityChange;
+ break;
+ default:
+ break;
+ }
+ ProcessRainOnVehicle(params);
+ }
+}
- params.m_bDistanceCalculated = FALSE;
- params.m_pVehicle = veh;
- params.m_fDistance = GetDistanceSquared(m_sQueueSample.m_vecPos);
+void
+cAudioManager::ProcessCarHeli(cVehicleParams& params)
+{
+ const float SOUND_INTENSITY = 250.0f;
+
+ CVehicle* playerVeh;
+ CVehicle* veh;
+ CAutomobile* automobile;
+ CBoat* boat;
+
+ uint8 emittingVol;
+ int16 brakeState;
+ int16 accelerateState;
+ uint32 freq;
+ float propellerSpeed;
+ float freqModifier; //may be relate to angle with horison
+ float cameraAngle;
+ bool8 distanceCalculatedOld;
+ float distanceOld;
+ CVector vecPosOld;
+
+ float volumeModifier;//TODO find better name
+ bool8 hunterBool;
+
+ static uint32 freqFrontPrev = 14287;
+ static uint32 freqPropellerPrev = 7143;
+ static uint32 freqSkimmerPrev = 14287;
+
+ boat = nil;
+ automobile = nil;
+ hunterBool = FALSE;
+
+ if (params.m_fDistance >= SQR(SOUND_INTENSITY))
+ return;
+
+ playerVeh = FindPlayerVehicle();
+ veh = params.m_pVehicle;
+ if (playerVeh == veh) {
+ accelerateState = Pads[0].GetAccelerate();
+ brakeState = Pads[0].GetBrake();
+ } else {
+ accelerateState = veh->m_fGasPedal * 255.0f;
+ brakeState = veh->m_fBrakePedal * 255.0f;
+ }
+ freqModifier = Abs(veh->GetUp().y);
+ cameraAngle = (DotProduct(veh->GetMatrix().GetForward(), TheCamera.GetForward()) + 1.0f) / 2.0f;
+ if (veh->m_modelIndex == MI_SKIMMER) {
+ boat = (CBoat*)veh;
+ propellerSpeed = boat->m_fMovingSpeed * 50.0f / 11.0f;
+ } else if (params.m_VehicleType == VEHICLE_TYPE_HELI) {
+ propellerSpeed = 1.0f;
+ } else {
+ automobile = (CAutomobile*)veh;
+ propellerSpeed = automobile->m_aWheelSpeed[1] * 50.0f / 11.0f;
+ }
- if (handling != nil)
- params.m_pTransmission = &handling->Transmission;
+ if (propellerSpeed == 0.0f)
+ return;
+
+ propellerSpeed = Min(1.0f, propellerSpeed);
+ CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance);
+
+
+ //sound on long distances
+ if (m_sQueueSample.m_fDistance >= 40.0f)
+ emittingVol = propellerSpeed * 75.0f;
+ else if (m_sQueueSample.m_fDistance >= 25.0f)
+ emittingVol = (m_sQueueSample.m_fDistance - 25.0f) * (75.0f * propellerSpeed) / 15.0f;
+ else
+ emittingVol = 0;
+ if (emittingVol != 0) {
+ m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance);
+ if (m_sQueueSample.m_nVolume != 0) {
+ m_sQueueSample.m_nCounter = 88;
+ if (boat != nil) {
+ m_sQueueSample.m_nSampleIndex = SFX_SEAPLANE_PRO3;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ if (accelerateState > 0 || brakeState > 0)
+ m_sQueueSample.m_nFrequency = 4600 + Min(1.0f, (Max(accelerateState, brakeState) / 255.0f) * freqModifier) * 563;
+ else
+ m_sQueueSample.m_nFrequency = 3651 + Min(1.0f, freqModifier) * 949;
+ } else {
+ m_sQueueSample.m_nSampleIndex = SFX_HELI_1;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
+ }
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_nReleasingVolumeModificator = 2;
+ m_sQueueSample.m_nLoopCount = 0;
+ SET_EMITTING_VOLUME(emittingVol);
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
+ m_sQueueSample.m_fSpeedMultiplier = 6.0f;
+ m_sQueueSample.m_SoundIntensity = SOUND_INTENSITY;
+ m_sQueueSample.m_bReleasingSoundFlag = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 5;
+ m_sQueueSample.m_bReverbFlag = TRUE;
+ m_sQueueSample.m_bRequireReflection = FALSE;
+ AddSampleToRequestedQueue();
+ }
+ }
+
+ CVector backPropellerPos;
+ if (automobile != nil)
+ automobile->GetComponentWorldPosition(CAR_BOOT, backPropellerPos);
+ else if (params.m_VehicleType == VEHICLE_TYPE_HELI)
+#ifdef FIX_BUGS
+ backPropellerPos =
+#endif
+ params.m_pVehicle->GetMatrix() * CVector(0.0f, -10.0f, 0.0f);
else
- params.m_pTransmission = nil;
+ backPropellerPos = m_sQueueSample.m_vecPos;
- params.m_nIndex = veh->GetModelIndex() - MI_FIRST_VEHICLE;
- if (params.m_pVehicle->GetStatus() == STATUS_SIMPLE)
- velChange = params.m_pVehicle->AutoPilot.m_fMaxTrafficSpeed * 0.02f;
+ if (params.m_fDistance >= SQR(140.0f))
+ return;
+
+ if (propellerSpeed >= 0.4f)
+ volumeModifier = (propellerSpeed - 0.4f) * 5.0f / 3.0f;
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(params);
- ProcessVehicleOneShots(params);
- ((CAutomobile *)veh)->m_fVelocityChangeForAudio = params.m_fVelocityChange;
- break;
+ volumeModifier = 0.0f;
+ if (!boat) {
+ freq = Min(1300, 7000.0f * freqModifier);
+ if (playerVeh == veh && (accelerateState > 0 || brakeState > 0) && freq < 1300)//unnesesary freqModifier alredy <= 1300
+ freq = 1300;
+ if (veh->m_modelIndex == MI_HUNTER)
+ hunterBool = TRUE;
+ }
+
+
+ //sound from front of helicopter
+ emittingVol = (1.0f - cameraAngle) * volumeModifier * 127.0f;
+ m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, 140.0f, m_sQueueSample.m_fDistance);
+ if (m_sQueueSample.m_nVolume != 0) {
+ m_sQueueSample.m_nCounter = 3;
+ if (hunterBool) {
+ m_sQueueSample.m_nSampleIndex = SFX_HELI_APACHE_1;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nFrequency = (volumeModifier + 1.0f) * 16000 + freq;
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_nReleasingVolumeModificator = 1;
+ m_sQueueSample.m_nLoopCount = 0;
+ SET_EMITTING_VOLUME(emittingVol);
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
+ m_sQueueSample.m_fSpeedMultiplier = 6.0f;
+ m_sQueueSample.m_SoundIntensity = 140.0f;
+ m_sQueueSample.m_bReleasingSoundFlag = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 5;
+ m_sQueueSample.m_bReverbFlag = TRUE;
+ m_sQueueSample.m_bRequireReflection = FALSE;
+ AddSampleToRequestedQueue();
+ } else if (boat != nil) {
+ m_sQueueSample.m_nSampleIndex = SFX_SEAPLANE_PRO1;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+
+ if (accelerateState > 0 || brakeState > 0)
+ m_sQueueSample.m_nFrequency = 18000 + Min(1.0f, freqModifier * (Max(accelerateState, brakeState) / 255.0f)) * 2204;
+ else
+ m_sQueueSample.m_nFrequency = 14287 + Min(1.0f, freqModifier) * 3713;
+ if (propellerSpeed < 1.0f)
+ m_sQueueSample.m_nFrequency = (propellerSpeed + 1.0f) * (m_sQueueSample.m_nFrequency / 2.0f);
+ m_sQueueSample.m_nFrequency = Clamp2(m_sQueueSample.m_nFrequency, freqFrontPrev, 197);
+ freqFrontPrev = m_sQueueSample.m_nFrequency;
+
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_nReleasingVolumeModificator = 1;
+ m_sQueueSample.m_nLoopCount = 0;
+ SET_EMITTING_VOLUME(emittingVol);
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
+ m_sQueueSample.m_fSpeedMultiplier = 6.0f;
+ m_sQueueSample.m_SoundIntensity = 140.0f;
+ m_sQueueSample.m_bReleasingSoundFlag = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 5;
+ m_sQueueSample.m_bReverbFlag = TRUE;
+ m_sQueueSample.m_bRequireReflection = FALSE;
+ AddSampleToRequestedQueue();
+ } else {
+ m_sQueueSample.m_nSampleIndex = SFX_CAR_HELI_MAI;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nFrequency = (volumeModifier + 1) * 16000 + freq;
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_nReleasingVolumeModificator = 1;
+ m_sQueueSample.m_nLoopCount = 0;
+ SET_EMITTING_VOLUME(emittingVol);
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
+ m_sQueueSample.m_fSpeedMultiplier = 6.0f;
+ m_sQueueSample.m_SoundIntensity = 140.0f;
+ m_sQueueSample.m_bReleasingSoundFlag = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 5;
+ m_sQueueSample.m_bReverbFlag = TRUE;
+ m_sQueueSample.m_bRequireReflection = FALSE;
+ AddSampleToRequestedQueue();
}
- if (params.m_nIndex == DODO) {
- if (!ProcessVehicleRoadNoise(params)) {
- ProcessVehicleOneShots(params);
- ((CAutomobile *)veh)->m_fVelocityChangeForAudio = params.m_fVelocityChange;
- break;
- }
- if (CWeather::WetRoads > 0.f)
- ProcessWetRoadNoise(params);
- ProcessVehicleSkidding(params);
+ }
+
+
+ //after accel rotor sound
+ emittingVol = ((cameraAngle + 1.0f) * volumeModifier * 127.0f) / 2.0f;
+ m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, 140.0f, m_sQueueSample.m_fDistance);
+ if (m_sQueueSample.m_nVolume != 0) {
+ m_sQueueSample.m_nCounter = 1;
+ if (hunterBool) {
+ m_sQueueSample.m_nSampleIndex = SFX_HELI_APACHE_2;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nFrequency = (volumeModifier + 1) * 16000 + freq;
+ } else if (boat) {
+ m_sQueueSample.m_nSampleIndex = SFX_SEAPLANE_PRO2;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+
+ if (accelerateState > 0 || brakeState > 0)
+ m_sQueueSample.m_nFrequency = 9000 + Min(1.0f, (Max(accelerateState, brakeState) / 255) * freqModifier) * 1102;
+ else
+ m_sQueueSample.m_nFrequency = 7143 + Min(1.0f, freqModifier) * 1857;
+
+ if (propellerSpeed < 1.0f)
+ m_sQueueSample.m_nFrequency = (propellerSpeed + 1) * (m_sQueueSample.m_nFrequency / 2);
+
+ m_sQueueSample.m_nFrequency = Clamp2(m_sQueueSample.m_nFrequency, freqPropellerPrev, 98);
+ freqPropellerPrev = m_sQueueSample.m_nFrequency;
} else {
- if (!ProcessVehicleRoadNoise(params)) {
- ProcessVehicleOneShots(params);
- ((CAutomobile *)veh)->m_fVelocityChangeForAudio = params.m_fVelocityChange;
- break;
+ m_sQueueSample.m_nSampleIndex = SFX_CAR_HELI_MAI2;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nFrequency = (volumeModifier + 1) * 16000 + freq;
+ }
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_nReleasingVolumeModificator = 1;
+ m_sQueueSample.m_nLoopCount = 0;
+ SET_EMITTING_VOLUME(emittingVol);
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
+ m_sQueueSample.m_fSpeedMultiplier = 6.0f;
+ m_sQueueSample.m_SoundIntensity = 140.0f;
+ m_sQueueSample.m_bReleasingSoundFlag = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 5;
+ m_sQueueSample.m_bReverbFlag = TRUE;
+ m_sQueueSample.m_bRequireReflection = FALSE;
+ AddSampleToRequestedQueue();
+ }
+
+
+ //engine starting sound
+ if (boat == nil && params.m_VehicleType != VEHICLE_TYPE_HELI && m_sQueueSample.m_fDistance < 30.0f) { //strange way to check if automobile != nil
+ if (automobile->bEngineOn) {
+ if (propellerSpeed < 1.0f) {
+ emittingVol = (1.0f - propellerSpeed / 2.0f) * 70.0f;
+ m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, 30.0f, m_sQueueSample.m_fDistance);
+ if (m_sQueueSample.m_nVolume) {
+ if (hunterBool) {
+ m_sQueueSample.m_nSampleIndex = SFX_HELI_APACHE_4;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ freq = 3000.0f * propellerSpeed + 30000;
+ } else {
+ m_sQueueSample.m_nSampleIndex = SFX_CAR_HELI_STA;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ freq = 3000.0f * propellerSpeed + 6000;
+ }
+ m_sQueueSample.m_nFrequency = freq;
+ m_sQueueSample.m_nCounter = 12;
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_nReleasingVolumeModificator = 1;
+ m_sQueueSample.m_nLoopCount = 0;
+ SET_EMITTING_VOLUME(emittingVol);
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
+ m_sQueueSample.m_fSpeedMultiplier = 6.0f;
+ m_sQueueSample.m_SoundIntensity = 30.0f;
+ m_sQueueSample.m_bReleasingSoundFlag = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 30;
+ m_sQueueSample.m_bReverbFlag = TRUE;
+ m_sQueueSample.m_bRequireReflection = FALSE;
+ AddSampleToRequestedQueue();
+ }
}
- ProcessReverseGear(params);
- if (CWeather::WetRoads > 0.f)
- ProcessWetRoadNoise(params);
- ProcessVehicleSkidding(params);
- ProcessVehicleHorn(params);
- ProcessVehicleSirenOrAlarm(params);
- if (UsesReverseWarning(params.m_nIndex))
- ProcessVehicleReverseWarning(params);
- if (HasAirBrakes(params.m_nIndex))
- ProcessAirBrakes(params);
- }
- ProcessCarBombTick(params);
- ProcessVehicleEngine(params);
- ProcessEngineDamage(params);
- ProcessVehicleDoors(params);
-
- ProcessVehicleOneShots(params);
- ((CAutomobile *)veh)->m_fVelocityChangeForAudio = params.m_fVelocityChange;
- break;
- case VEHICLE_TYPE_BOAT:
- ProcessBoatEngine(params);
- ProcessBoatMovingOverWater(params);
- ProcessVehicleOneShots(params);
- break;
- case VEHICLE_TYPE_TRAIN:
- ProcessTrainNoise(params);
- ProcessVehicleOneShots(params);
- break;
- case VEHICLE_TYPE_HELI:
- ProcessHelicopter(params);
- ProcessVehicleOneShots(params);
- break;
- case VEHICLE_TYPE_PLANE:
- ProcessPlane(params);
- ProcessVehicleOneShots(params);
- break;
- default:
- break;
+ }
}
- ProcessRainOnVehicle(params);
-}
-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;
+
+ if (boat) {
+ if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_FIXED && m_sQueueSample.m_fDistance < 20.0f && propellerSpeed > 0.0f) {
+ m_sQueueSample.m_nVolume = ComputeVolume(propellerSpeed * 100.0f, 20.0f, m_sQueueSample.m_fDistance);
+ if (m_sQueueSample.m_nVolume) {
+
+ if (accelerateState > 0 || brakeState > 0)
+ m_sQueueSample.m_nFrequency = 18000 + Min(1.0f, (Max(accelerateState, brakeState) / 255.0f) * freqModifier) * 2204;
+ else
+ m_sQueueSample.m_nFrequency = 14287 + Min(1.0f, freqModifier) * 3713;
+ if (propellerSpeed < 1.0f)
+ m_sQueueSample.m_nFrequency = (propellerSpeed + 1) * (m_sQueueSample.m_nFrequency / 2.0f);
+ m_sQueueSample.m_nFrequency = Clamp2(m_sQueueSample.m_nFrequency, freqSkimmerPrev, 197);
+ freqSkimmerPrev = m_sQueueSample.m_nFrequency;
+
+ m_sQueueSample.m_nSampleIndex = SFX_SEAPLANE_PRO4;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nCounter = 12;
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nLoopCount = 0;
+ SET_EMITTING_VOLUME(propellerSpeed * 100.0f);
+ SET_LOOP_OFFSETS(SFX_SEAPLANE_PRO4)
+ m_sQueueSample.m_fSpeedMultiplier = 5.0f;
+ m_sQueueSample.m_SoundIntensity = 20.0f;
+ m_sQueueSample.m_bReleasingSoundFlag = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 7;
+ m_sQueueSample.m_bReverbFlag = TRUE;
+ m_sQueueSample.m_bRequireReflection = FALSE;
+ AddSampleToRequestedQueue();
+ }
+ }
+ } else {
+ //vacuum cleaner sound
+ vecPosOld = m_sQueueSample.m_vecPos;
+ distanceCalculatedOld = params.m_bDistanceCalculated;
+ distanceOld = params.m_fDistance;
+
+ m_sQueueSample.m_vecPos = backPropellerPos;
+ params.m_bDistanceCalculated = FALSE;
+ params.m_fDistance = GetDistanceSquared(m_sQueueSample.m_vecPos);
+ if (params.m_fDistance < SQR(27.0f)) {
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_nVolume = ComputeVolume(volumeModifier * 25.0f, 27.0f, m_sQueueSample.m_fDistance);
+ if (m_sQueueSample.m_nVolume) {
+ m_sQueueSample.m_nCounter = 2;
+ m_sQueueSample.m_nSampleIndex = hunterBool ? SFX_HELI_APACHE_3 : SFX_CAR_HELI_REA;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_bIs2D = FALSE;
- m_sQueueSample.m_nReleasingVolumeModificator = 9;
- m_sQueueSample.m_nFrequency = m_anRandomTable[1] % 4000 + 28000;
- m_sQueueSample.m_nLoopCount = 1;
- SET_EMITTING_VOLUME((uint8)emittingVol);
- RESET_LOOP_OFFSETS
- m_sQueueSample.m_fSpeedMultiplier = 0.0f;
- m_sQueueSample.m_SoundIntensity = rainOnVehicleIntensity;
- m_sQueueSample.m_bReleasingSoundFlag = TRUE;
- m_sQueueSample.m_bReverbFlag = FALSE;
+ m_sQueueSample.m_nReleasingVolumeModificator = 1;
+ m_sQueueSample.m_nFrequency = (volumeModifier + 1.0f) * 16000;
+ m_sQueueSample.m_nLoopCount = 0;
+ SET_EMITTING_VOLUME(volumeModifier * 25.0f);
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
+ m_sQueueSample.m_fSpeedMultiplier = 6.0f;
+ m_sQueueSample.m_SoundIntensity = 27.0f;
+ m_sQueueSample.m_bReleasingSoundFlag = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 5;
+ m_sQueueSample.m_bReverbFlag = TRUE;
m_sQueueSample.m_bRequireReflection = FALSE;
AddSampleToRequestedQueue();
}
}
+
+ m_sQueueSample.m_vecPos = vecPosOld;
+ params.m_bDistanceCalculated = distanceCalculatedOld;
+ params.m_fDistance = distanceOld;
+ }
+}
+
+void
+cAudioManager::ProcessRainOnVehicle(cVehicleParams& params)
+{
+ const int SOUND_INTENSITY = 22.0f;
+
+ CVehicle *veh;
+ uint8 emittingVol;
+
+ if (params.m_fDistance >= SQR(SOUND_INTENSITY) || CWeather::Rain <= 0.01f || CCullZones::CamNoRain() && CCullZones::PlayerNoRain())
+ return;
+
+ veh = params.m_pVehicle;
+ veh->m_bRainAudioCounter++;
+ if (veh->m_bRainAudioCounter >= 2) {
+ veh->m_bRainAudioCounter = 0;
+ CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance);
+ emittingVol = 30.0f * CWeather::Rain;
+ m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, 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 = SFX_BANK_0;
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_nReleasingVolumeModificator = 9;
+ m_sQueueSample.m_nFrequency = m_anRandomTable[1] % 4000 + 28000;
+ m_sQueueSample.m_nLoopCount = 1;
+ SET_EMITTING_VOLUME(emittingVol);
+ RESET_LOOP_OFFSETS
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_SoundIntensity = SOUND_INTENSITY;
+ m_sQueueSample.m_bReleasingSoundFlag = TRUE;
+ m_sQueueSample.m_bReverbFlag = FALSE;
+ m_sQueueSample.m_bRequireReflection = FALSE;
+ AddSampleToRequestedQueue();
+ }
}
}
@@ -704,27 +1209,28 @@ cAudioManager::ProcessReverseGear(cVehicleParams& params)
{
const int reverseGearIntensity = 30;
- CVehicle *veh;
- CAutomobile *automobile;
- int32 emittingVol;
+ CAutomobile* automobile;
float modificator;
+ uint8 emittingVolume;
if (params.m_fDistance >= SQR(reverseGearIntensity))
return FALSE;
- veh = params.m_pVehicle;
- if (veh->bEngineOn && (veh->m_fGasPedal < 0.0f || veh->m_nCurrentGear == 0)) {
+ automobile = (CAutomobile*)params.m_pVehicle;
+ if (automobile->m_modelIndex == MI_CADDY)
+ return TRUE;
+ if (automobile->bEngineOn && (automobile->m_fGasPedal < 0.0f || automobile->m_nCurrentGear == 0)) {
CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance);
- automobile = (CAutomobile *)params.m_pVehicle;
- if (automobile->m_nWheelsOnGround != 0) {
+ if (automobile->m_nDriveWheelsOnGround != 0) {
modificator = params.m_fVelocityChange / params.m_pTransmission->fMaxReverseVelocity;
} else {
- if (automobile->m_nDriveWheelsOnGround != 0)
+ if (automobile->m_nDriveWheelsOnGroundPrev != 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);
+ emittingVolume = modificator * 24.0f;
+ m_sQueueSample.m_nVolume = ComputeVolume(emittingVolume, reverseGearIntensity, m_sQueueSample.m_fDistance);
+
if (m_sQueueSample.m_nVolume != 0) {
if (params.m_pVehicle->m_fGasPedal >= 0.0f) {
m_sQueueSample.m_nCounter = 62;
@@ -736,9 +1242,9 @@ cAudioManager::ProcessReverseGear(cVehicleParams& params)
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_bIs2D = FALSE;
m_sQueueSample.m_nReleasingVolumeModificator = 3;
- m_sQueueSample.m_nFrequency = (6000.f * modificator) + 7000;
+ m_sQueueSample.m_nFrequency = (6000.0f * modificator) + 7000;
m_sQueueSample.m_nLoopCount = 0;
- SET_EMITTING_VOLUME(emittingVol);
+ SET_EMITTING_VOLUME(emittingVolume);
SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
m_sQueueSample.m_fSpeedMultiplier = 3.0f;
m_sQueueSample.m_SoundIntensity = reverseGearIntensity;
@@ -753,54 +1259,254 @@ cAudioManager::ProcessReverseGear(cVehicleParams& params)
}
void
-cAudioManager::ProcessModelCarEngine(cVehicleParams& params)
+cAudioManager::ProcessModelHeliVehicle(cVehicleParams& params)
{
- const float SOUND_INTENSITY = 30.0f;
- CAutomobile *automobile;
- float allowedVelocity;
- int32 emittingVol;
- float velocityChange;
+ const float SOUND_INTENSITY = 35.0f;
- 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);
+ static uint32 prevFreq = 22050;
+
+ uint32 freq;
+ bool8 isPlayerVeh;
+ int16 acceletateState;
+ int16 brakeState;
+
+ if (params.m_fDistance >= SQR(SOUND_INTENSITY))
+ return;
+
+ if (FindPlayerVehicle() == params.m_pVehicle)
+ isPlayerVeh = TRUE;
+ else
+#ifdef FIX_BUGS
+ isPlayerVeh = CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle == params.m_pVehicle;
+#else
+ isPlayerVeh = CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle != nil;
+#endif
+ if (isPlayerVeh) {
+ brakeState = Pads[0].GetBrake();
+ acceletateState = Max(Pads[0].GetAccelerate(), Abs(Pads[0].GetCarGunUpDown()) * 2);
+ } else {
+ acceletateState = 255.0f * params.m_pVehicle->m_fGasPedal;
+ brakeState = 255.0f * params.m_pVehicle->m_fBrakePedal;
+ }
+ if (acceletateState < brakeState)
+ acceletateState = brakeState;
+ freq = Clamp2(5 * acceletateState + 22050, (int)prevFreq, 30);
+ CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance);
+ m_sQueueSample.m_nVolume = ComputeVolume(70, SOUND_INTENSITY, m_sQueueSample.m_fDistance);
+ if (m_sQueueSample.m_nVolume != 0) {
+ m_sQueueSample.m_nCounter = 2;
+ m_sQueueSample.m_nSampleIndex = SFX_CAR_RC_HELI;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nFrequency = freq;
+ m_sQueueSample.m_nLoopCount = 0;
+ SET_EMITTING_VOLUME(70);
+ SET_LOOP_OFFSETS(SFX_CAR_RC_HELI)
+ m_sQueueSample.m_fSpeedMultiplier = 3.0f;
+ m_sQueueSample.m_SoundIntensity = SOUND_INTENSITY;
+ m_sQueueSample.m_bReleasingSoundFlag = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 4;
+ m_sQueueSample.m_bReverbFlag = TRUE;
+ m_sQueueSample.m_bRequireReflection = FALSE;
+ AddSampleToRequestedQueue();
+ }
+ if (isPlayerVeh)
+ prevFreq = freq;
+}
+
+void
+cAudioManager::ProcessModelVehicle(cVehicleParams& params)
+{
+ const float SOUND_INTENSITY = 35.0f;
+
+ static uint32 prevFreq = 14000;
+ static uint8 prevVolume = 0;
+
+ uint32 freq;
+ int16 acceletateState;
+ int16 brakeState;
+ uint8 volume;
+ bool8 isPlayerVeh;
+ bool8 vehSlowdown;
+
+ if (params.m_fDistance >= SQR(SOUND_INTENSITY))
+ return;
+
+ if (FindPlayerVehicle() == params.m_pVehicle)
+ isPlayerVeh = TRUE;
+ else
+#ifdef FIX_BUGS
+ isPlayerVeh = CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle == params.m_pVehicle;
+#else
+ isPlayerVeh = CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle != nil;
+#endif
+ if (params.m_pVehicle->m_modelIndex == MI_RCBANDIT) {
+ if (((CAutomobile*)params.m_pVehicle)->m_nDriveWheelsOnGround != 0) {
+ volume = Min(127, 127.0f * Abs(params.m_fVelocityChange) * 3.0f);
+ freq = 8000.0f * Abs(params.m_fVelocityChange) + 14000;
+ } else {
+ volume = 127;
+ freq = 25000;
+ }
+ if (isPlayerVeh) {
+ volume = Clamp2(volume, prevVolume, 7);
+ freq = Clamp2(freq, prevFreq, 800);
+ }
+ if (volume > 0) {
+ CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance);
+ m_sQueueSample.m_nVolume = ComputeVolume(volume, SOUND_INTENSITY, m_sQueueSample.m_fDistance);
+ if (m_sQueueSample.m_nVolume != 0) {
+ m_sQueueSample.m_nCounter = 2;
+ m_sQueueSample.m_nSampleIndex = SFX_RC_REV;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_nReleasingVolumeModificator = 1;
+ m_sQueueSample.m_nFrequency = freq;
+ m_sQueueSample.m_nLoopCount = 0;
+ SET_EMITTING_VOLUME(volume);
+ SET_LOOP_OFFSETS(SFX_RC_REV)
+ m_sQueueSample.m_fSpeedMultiplier = 3.0f;
+ m_sQueueSample.m_SoundIntensity = SOUND_INTENSITY;
+ m_sQueueSample.m_bReleasingSoundFlag = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 4;
+ m_sQueueSample.m_bReverbFlag = TRUE;
+ m_sQueueSample.m_bRequireReflection = FALSE;
+ AddSampleToRequestedQueue();
}
- 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 = SFX_BANK_0;
- 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;
- SET_EMITTING_VOLUME(emittingVol);
- SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
- m_sQueueSample.m_fSpeedMultiplier = 3.0f;
- m_sQueueSample.m_SoundIntensity = SOUND_INTENSITY;
- m_sQueueSample.m_bReleasingSoundFlag = FALSE;
- m_sQueueSample.m_nReleasingVolumeDivider = 3;
- m_sQueueSample.m_bReverbFlag = TRUE;
- m_sQueueSample.m_bRequireReflection = FALSE;
- AddSampleToRequestedQueue();
- }
+ }
+ if (isPlayerVeh) {
+ prevFreq = freq;
+ prevVolume = volume;
+ }
+ } else if (params.m_pVehicle != nil) {
+ if (isPlayerVeh) {
+ acceletateState = Pads[0].GetAccelerate();
+ brakeState = Pads[0].GetBrake();
+ } else {
+ acceletateState = 255.0f * params.m_pVehicle->m_fGasPedal;
+ brakeState = 255.0f * params.m_pVehicle->m_fBrakePedal;
+ }
+ if (acceletateState < brakeState)
+ acceletateState = brakeState;
+ if (acceletateState <= 0) {
+ vehSlowdown = TRUE;
+ volume = 127;
+ freq = 18000;
+ } else {
+ vehSlowdown = FALSE;
+ volume = Min(127, (127 * acceletateState / 255) * 3.0f * Abs(params.m_fVelocityChange));
+ freq = Min(22000, (8000 * acceletateState / 255 + 14000) * 3.0f * Abs(params.m_fVelocityChange));
+ }
+ if (isPlayerVeh && !vehSlowdown) {
+ volume = Clamp2(volume, prevVolume, 7);
+ freq = Clamp2(freq, prevFreq, 800);
+ }
+ if (!vehSlowdown)
+#ifdef THIS_IS_STUPID
+ freq += 8000.0f * Abs(DotProduct(params.m_pVehicle->GetUp(), CVector(0.0f, 1.0f, 0.0f)));
+#else
+ freq += 8000.0f * Abs(params.m_pVehicle->GetUp().y);
+#endif
+ if (params.m_pVehicle->bIsDrowning)
+ volume /= 4;
+ if (volume > 0) {
+ CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance);
+ m_sQueueSample.m_nVolume = ComputeVolume(volume, SOUND_INTENSITY, m_sQueueSample.m_fDistance);
+ if (m_sQueueSample.m_nVolume != 0) {
+ if (vehSlowdown) {
+ m_sQueueSample.m_nCounter = 0;
+ m_sQueueSample.m_nSampleIndex = SFX_RC_IDLE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 6;
+ } else {
+ m_sQueueSample.m_nCounter = 2;
+ m_sQueueSample.m_nSampleIndex = SFX_RC_REV;
+ m_sQueueSample.m_nReleasingVolumeDivider = 4;
}
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nFrequency = freq;
+ m_sQueueSample.m_nLoopCount = 0;
+ SET_EMITTING_VOLUME(volume);
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
+ m_sQueueSample.m_fSpeedMultiplier = 3.0f;
+ m_sQueueSample.m_SoundIntensity = SOUND_INTENSITY;
+ m_sQueueSample.m_bReleasingSoundFlag = FALSE;
+ m_sQueueSample.m_bReverbFlag = TRUE;
+ m_sQueueSample.m_bRequireReflection = FALSE;
+ AddSampleToRequestedQueue();
}
}
+ if (isPlayerVeh) {
+ if (vehSlowdown) {
+ prevFreq = freq;
+ prevVolume = volume;
+ }
+ }
+ }
+}
+
+void
+cAudioManager::ProcessVehicleFlatTyre(cVehicleParams& params)
+{
+ const float SOUND_INTENSITY = 60.0f;
+
+ CAutomobile* automobile;
+ CBike* bike;
+ bool8 wheelBurst;
+ uint8 emittingVol;
+
+ float modifier;
+
+ if (params.m_fDistance >= SQR(SOUND_INTENSITY))
+ return;
+
+ switch (params.m_VehicleType) {
+ case VEHICLE_TYPE_CAR:
+ automobile = (CAutomobile*)params.m_pVehicle;
+ wheelBurst = FALSE;
+ for (int i = 0; i < 4; i++)
+ if (automobile->Damage.GetWheelStatus(i) == WHEEL_STATUS_BURST && automobile->m_aWheelTimer[i] > 0.0f)
+ wheelBurst = TRUE;
+ if (!wheelBurst)
+ return;
+ break;
+ case VEHICLE_TYPE_BIKE:
+ bike = (CBike*)params.m_pVehicle;
+ wheelBurst = FALSE;
+ for(int i = 0; i < 2; i++)
+ if (bike->m_wheelStatus[i] == WHEEL_STATUS_BURST && bike->m_aWheelTimer[i] > 0.0f)
+ wheelBurst = TRUE;
+ if (!wheelBurst)
+ return;
+ break;
+ default:
+ return;
+ }
+ modifier = Min(1.0f, Abs(params.m_fVelocityChange) / (0.3f * params.m_pTransmission->fMaxVelocity));
+ if (modifier > 0.01f) { //mb can be replaced by (emittingVol > 1)
+ emittingVol = (100.0f * modifier);
+ CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance);
+ m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance);
+ if (m_sQueueSample.m_nVolume) {
+ m_sQueueSample.m_nCounter = 95;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_nReleasingVolumeModificator = 5;
+ m_sQueueSample.m_nSampleIndex = SFX_TYRE_BURST_L;
+ m_sQueueSample.m_nFrequency = (5500.0f * modifier) + 8000;
+ m_sQueueSample.m_nLoopCount = 0;
+ SET_EMITTING_VOLUME(emittingVol);
+ SET_LOOP_OFFSETS(SFX_TYRE_BURST_L)
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
+ m_sQueueSample.m_SoundIntensity = SOUND_INTENSITY;
+ m_sQueueSample.m_bReleasingSoundFlag = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_bReverbFlag = TRUE;
+ m_sQueueSample.m_bRequireReflection = FALSE;
+ AddSampleToRequestedQueue();
+ }
}
}
@@ -814,45 +1520,60 @@ cAudioManager::ProcessVehicleRoadNoise(cVehicleParams& params)
float multiplier;
int sampleFreq;
float velocity;
+ uint8 wheelsOnGround;
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 = SFX_BANK_0;
- 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;
- multiplier = (m_sQueueSample.m_fDistance / SOUND_INTENSITY) * 0.5f;
- sampleFreq = SampleManager.GetSampleBaseFrequency(SFX_ROAD_NOISE);
- freq = (sampleFreq * multiplier) + ((3 * sampleFreq) / 4);
- }
- m_sQueueSample.m_nFrequency = freq;
- m_sQueueSample.m_nLoopCount = 0;
- SET_EMITTING_VOLUME(emittingVol);
- SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
- m_sQueueSample.m_fSpeedMultiplier = 6.0f;
- m_sQueueSample.m_SoundIntensity = SOUND_INTENSITY;
- m_sQueueSample.m_bReleasingSoundFlag = FALSE;
- m_sQueueSample.m_nReleasingVolumeDivider = 4;
- m_sQueueSample.m_bReverbFlag = TRUE;
- m_sQueueSample.m_bRequireReflection = FALSE;
- AddSampleToRequestedQueue();
- }
+
+ if (params.m_fDistance >= SQR(SOUND_INTENSITY))
+ return FALSE;
+ switch (params.m_VehicleType) {
+ case VEHICLE_TYPE_CAR:
+ wheelsOnGround = ((CAutomobile*)params.m_pVehicle)->m_nWheelsOnGround;
+ break;
+ case VEHICLE_TYPE_BIKE:
+ wheelsOnGround = ((CBike*)params.m_pVehicle)->m_nWheelsOnGround;
+ break;
+ default:
+ wheelsOnGround = 4;
+ break;
+ }
+ if (params.m_pTransmission == nil || wheelsOnGround == 0)
+ return TRUE;
+
+ 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 = SFX_BANK_0;
+ 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;
+ multiplier = (m_sQueueSample.m_fDistance / SOUND_INTENSITY) * 0.5f;
+ sampleFreq = SampleManager.GetSampleBaseFrequency(SFX_ROAD_NOISE);
+ freq = (sampleFreq * multiplier) + ((3 * sampleFreq) / 4);
}
+ m_sQueueSample.m_nFrequency = freq;
+ m_sQueueSample.m_nLoopCount = 0;
+ SET_EMITTING_VOLUME(emittingVol);
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
+ m_sQueueSample.m_fSpeedMultiplier = 6.0f;
+ m_sQueueSample.m_SoundIntensity = 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;
}
@@ -865,45 +1586,53 @@ cAudioManager::ProcessWetRoadNoise(cVehicleParams& params)
int32 emittingVol;
float multiplier;
int freq;
- float velChange;
+ float velocity;
+ uint8 wheelsOnGround;
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 = SFX_BANK_0;
- m_sQueueSample.m_bIs2D = FALSE;
- m_sQueueSample.m_nReleasingVolumeModificator = 3;
-#ifdef FIX_BUGS
- multiplier = (m_sQueueSample.m_fDistance / SOUND_INTENSITY) * 0.5f;
-#else
- multiplier = (m_sQueueSample.m_fDistance / 3.0f) * 0.5f;
-#endif
- freq = SampleManager.GetSampleBaseFrequency(SFX_ROAD_NOISE);
- m_sQueueSample.m_nFrequency = freq + freq * multiplier;
- m_sQueueSample.m_nLoopCount = 0;
- SET_EMITTING_VOLUME(emittingVol);
- SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
- m_sQueueSample.m_fSpeedMultiplier = 6.0f;
- m_sQueueSample.m_SoundIntensity = SOUND_INTENSITY;
- m_sQueueSample.m_bReleasingSoundFlag = FALSE;
- m_sQueueSample.m_nReleasingVolumeDivider = 4;
- m_sQueueSample.m_bReverbFlag = TRUE;
- m_sQueueSample.m_bRequireReflection = FALSE;
- AddSampleToRequestedQueue();
- }
- }
+ switch (params.m_VehicleType) {
+ case VEHICLE_TYPE_CAR:
+ wheelsOnGround = ((CAutomobile*)params.m_pVehicle)->m_nWheelsOnGround;
+ break;
+ case VEHICLE_TYPE_BIKE:
+ wheelsOnGround = ((CBike*)params.m_pVehicle)->m_nWheelsOnGround;
+ break;
+ default:
+ wheelsOnGround = 4;
+ break;
+ }
+ if (params.m_pTransmission == nil || wheelsOnGround == 0)
+ return TRUE;
+
+ velocity = Abs(params.m_fVelocityChange);
+ if (velocity > 0.0f) {
+ CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance);
+ relativeVelocity = Min(1.0f, velocity / (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 = SFX_BANK_0;
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ multiplier = (m_sQueueSample.m_fDistance / SOUND_INTENSITY) * 0.5f;
+ freq = SampleManager.GetSampleBaseFrequency(SFX_ROAD_NOISE);
+ m_sQueueSample.m_nFrequency = freq + freq * multiplier;
+ m_sQueueSample.m_nLoopCount = 0;
+ SET_EMITTING_VOLUME(emittingVol);
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
+ m_sQueueSample.m_fSpeedMultiplier = 6.0f;
+ m_sQueueSample.m_SoundIntensity = 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;
}
@@ -912,19 +1641,29 @@ cAudioManager::ProcessVehicleEngine(cVehicleParams& params)
{
const float SOUND_INTENSITY = 50.0f;
- CVehicle *playerVeh;
- CVehicle *veh;
- CAutomobile *automobile;
+ CVehicle* playerVeh;
+ CVehicle* veh;
+ CAutomobile* automobile;
+ cTransmission* transmission;
+ CBike* bike;
+ tWheelState* wheelState;
+ float* gasPedalAudioPtr;
+
+ int32 freq = 0;
+ uint8 currentGear;
+ uint8 emittingVol;
+ int8 wheelsOnGround;
+ int8 wheelsOnGroundPrev;
float relativeGearChange;
float relativeChange;
- uint8 volume;
- int32 freq = 0; // uninitialized variable
- uint8 emittingVol;
- cTransmission *transmission;
- uint8 currentGear;
float modificator;
- float traction = 0.f;
+ float traction;
+ bool8 isMoped;
+ bool8 caddyBool;
+ isMoped = FALSE;
+ caddyBool = FALSE;
+ traction = 0.0f;
if (params.m_fDistance < SQR(SOUND_INTENSITY)) {
playerVeh = FindPlayerVehicle();
veh = params.m_pVehicle;
@@ -934,107 +1673,174 @@ cAudioManager::ProcessVehicleEngine(cVehicleParams& params)
}
if (veh->bEngineOn) {
CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance);
- automobile = (CAutomobile *)params.m_pVehicle;
- if (params.m_nIndex == DODO) {
- ProcessCesna(params);
- return TRUE;
- }
- if (FindPlayerVehicle() == veh) {
- ProcessPlayersVehicleEngine(params, automobile);
+ if (playerVeh == veh && veh->m_modelIndex != MI_CADDY) {
+ ProcessPlayersVehicleEngine(params, params.m_pVehicle);
return TRUE;
}
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;
+ switch (veh->m_modelIndex) {
+ case MI_PIZZABOY:
+ case MI_FAGGIO:
+ isMoped = TRUE;
+ currentGear = transmission->nNumberOfGears;
+ break;
+ case MI_CADDY:
+ currentGear = transmission->nNumberOfGears;
+ caddyBool = TRUE;
+ break;
+ default:
+ currentGear = veh->m_nCurrentGear;
+ break;
+ }
+ switch (params.m_VehicleType) {
+ case VEHICLE_TYPE_CAR:
+ automobile = (CAutomobile*)veh;
+ wheelsOnGround = automobile->m_nDriveWheelsOnGround;
+ wheelsOnGroundPrev = automobile->m_nDriveWheelsOnGroundPrev;
+ wheelState = automobile->m_aWheelState;
+ gasPedalAudioPtr = &automobile->m_fGasPedalAudio;
+ break;
+ case VEHICLE_TYPE_BIKE:
+ bike = (CBike*)veh;
+ wheelsOnGround = bike->m_nDriveWheelsOnGround;
+ wheelsOnGroundPrev = bike->m_nDriveWheelsOnGroundPrev;
+ wheelState = bike->m_aWheelState;
+ gasPedalAudioPtr = &bike->m_fGasPedalAudio;
+ break;
+ default:
+ debug(" ** AUDIOLOG: Unrecognised vehicle type %d in ProcessVehicleEngine() * \n", params.m_VehicleType);
+ return TRUE;
+ }
+
+ if (wheelsOnGround != 0) {
+ if (!veh->bIsHandbrakeOn || isMoped && caddyBool) { //mb bug, bcs it's can't be TRUE together
+ if (veh->GetStatus() == STATUS_SIMPLE || isMoped || caddyBool) {
+ traction = 0.0f;
+ } else {
+ switch (transmission->nDriveType) {
+ case '4':
+ if (params.m_VehicleType == VEHICLE_TYPE_BIKE) {
+ for (int i = 0; i < 2; i++)
+ if (wheelState[i] == WHEEL_STATE_SPINNING)
+ traction += 0.1f;
+ } else {
+ for (int i = 0; i < 4; i++)
+ if (wheelState[i] == WHEEL_STATE_SPINNING)
+ traction += 0.05f;
+ }
+ break;
+ case 'F':
+ if (params.m_VehicleType == VEHICLE_TYPE_BIKE) {
+ if (wheelState[BIKEWHEEL_FRONT] == WHEEL_STATE_SPINNING)
+ traction += 0.2f;
+ } else {
+ if (wheelState[CARWHEEL_FRONT_LEFT] == WHEEL_STATE_SPINNING)
+ traction += 0.1f;
+ if (wheelState[CARWHEEL_FRONT_RIGHT] == WHEEL_STATE_SPINNING)
+ traction += 0.1f;
+ }
+ break;
+ case 'R':
+ if (params.m_VehicleType == VEHICLE_TYPE_BIKE) {
+ if (wheelState[BIKEWHEEL_REAR] == WHEEL_STATE_SPINNING)
+ traction += 0.2f;
+ } else {
+ if (wheelState[CARWHEEL_REAR_LEFT] == WHEEL_STATE_SPINNING)
+ traction += 0.1f;
+ if (wheelState[CARWHEEL_REAR_RIGHT] == WHEEL_STATE_SPINNING)
+ traction += 0.1f;
+ }
+ break;
+ default:
+ break;
}
- break;
- case 'F':
- if (automobile->m_aWheelState[CARWHEEL_FRONT_LEFT] == WHEEL_STATE_SPINNING)
- traction += 0.1f;
- if (automobile->m_aWheelState[CARWHEEL_FRONT_RIGHT] == WHEEL_STATE_SPINNING)
- traction += 0.1f;
- break;
- case 'R':
- if (automobile->m_aWheelState[CARWHEEL_REAR_LEFT] == WHEEL_STATE_SPINNING)
- traction += 0.1f;
- if (automobile->m_aWheelState[CARWHEEL_REAR_RIGHT] == WHEEL_STATE_SPINNING)
- traction += 0.1f;
- break;
}
+ } else if (params.m_fVelocityChange == 0.0f) {
+ traction = 0.9f;
}
- 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;
+ if (transmission->fMaxVelocity <= 0.0f) {
+ relativeChange = 0.0f;
+ modificator = 0.0f;
+ } else {
+ if (!isMoped && !caddyBool) {
+ if (currentGear != 0) {
+ relativeGearChange = Min(1.0f,
+ params.m_fVelocityChange - transmission->Gears[currentGear].fShiftDownVelocity) / transmission->fMaxVelocity * 2.5f;
+ if (traction == 0.0f && veh->GetStatus() != STATUS_SIMPLE &&
+ params.m_fVelocityChange < transmission->Gears[1].fShiftUpVelocity)
+ traction = 0.7f;
+ relativeChange = traction * *gasPedalAudioPtr * 0.95f + (1.0f - traction) * relativeGearChange;
+ } else {
+ relativeChange = Min(1.0f,
+ 1.0f - Abs((params.m_fVelocityChange - transmission->Gears[0].fShiftDownVelocity) / transmission->fMaxReverseVelocity));
+ }
+ modificator = relativeChange;
+ } else {
+ modificator = Min(1.0f, Abs(params.m_fVelocityChange / transmission->fMaxVelocity > 1.0f));
}
- 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;
+ if (wheelsOnGroundPrev != 0)
+ *gasPedalAudioPtr *= 0.4f;
+ relativeChange = *gasPedalAudioPtr;
+ modificator = relativeChange;
}
- modificator = relativeChange;
- if (currentGear != 0 || automobile->m_nWheelsOnGround == 0)
- freq = 1200 * currentGear + 18000.f * modificator + 14000;
+ if (currentGear != 0 || wheelsOnGround == 0)
+ freq = 1200 * currentGear + 18000.0f * modificator + 14000;
+ else if (params.m_VehicleType == VEHICLE_TYPE_BIKE)
+ freq = 22050;
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);
- }
+ freq = 13000.0f * modificator + 14000;
+ if (modificator >= 0.75f)
+ emittingVol = 90;
+ else
+ emittingVol = modificator * (4.0f / 3.0f) * 15.0f + 75;
} else {
- modificator = 0.f;
- emittingVol = 80;
- volume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance);
+ modificator = 0.0f;
+ emittingVol = 75;
}
- m_sQueueSample.m_nVolume = volume;
+ if (veh->bIsDrowning)
+ emittingVol /= 4;
+ if (caddyBool) {
+ emittingVol = 100.0f * modificator;
+ freq = 2130.0f * modificator + 4270;
+ m_sQueueSample.m_nCounter = 2;
+ }
+ m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance);
if (m_sQueueSample.m_nVolume != 0) {
- if (automobile->GetStatus() == STATUS_SIMPLE) {
- if (modificator < 0.02f) {
- m_sQueueSample.m_nSampleIndex = aVehicleSettings[params.m_nIndex].m_nBank - CAR_SFX_BANKS_OFFSET + SFX_CAR_IDLE_1;
- freq = modificator * 10000 + 22050;
- m_sQueueSample.m_nCounter = 52;
+ if (!caddyBool) {
+ if (veh->GetStatus() == STATUS_SIMPLE) {
+ if (modificator < 0.02f) {
+ m_sQueueSample.m_nSampleIndex = aVehicleSettings[params.m_nIndex].m_nBank - CAR_SFX_BANKS_OFFSET + SFX_CAR_IDLE_1;
+ m_sQueueSample.m_nCounter = 52;
+ freq = 10000.0f * modificator + 22050;
+ } else {
+ m_sQueueSample.m_nSampleIndex = aVehicleSettings[params.m_nIndex].m_nAccelerationSampleIndex;
+ m_sQueueSample.m_nCounter = 2;
+ }
} else {
- m_sQueueSample.m_nSampleIndex = aVehicleSettings[params.m_nIndex].m_nAccelerationSampleIndex;
- m_sQueueSample.m_nCounter = 2;
+ if (veh->m_fGasPedal < 0.02f) {
+ m_sQueueSample.m_nSampleIndex = aVehicleSettings[params.m_nIndex].m_nBank - CAR_SFX_BANKS_OFFSET + SFX_CAR_IDLE_1;
+ m_sQueueSample.m_nCounter = 52;
+ freq = 10000.0f * modificator + 22050;
+ } else {
+ m_sQueueSample.m_nSampleIndex = aVehicleSettings[params.m_nIndex].m_nAccelerationSampleIndex;
+ m_sQueueSample.m_nCounter = 2;
+ }
}
+ m_sQueueSample.m_nFrequency = freq + 100 * m_sQueueSample.m_nBankIndex % 1000;
} else {
- if (automobile->m_fGasPedal < 0.05f) {
- m_sQueueSample.m_nSampleIndex = aVehicleSettings[params.m_nIndex].m_nBank - CAR_SFX_BANKS_OFFSET + 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;
- }
+ if (FindVehicleOfPlayer() == params.m_pVehicle)
+ m_sQueueSample.m_nSampleIndex = SFX_CAR_AFTER_ACCEL_12;
+ else
+ m_sQueueSample.m_nSampleIndex = SFX_CAR_REV_12;
+ m_sQueueSample.m_nFrequency = freq + 20 * m_sQueueSample.m_nBankIndex % 100;
}
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
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)
+ if (m_sQueueSample.m_nSampleIndex == SFX_CAR_IDLE_5 || m_sQueueSample.m_nSampleIndex == SFX_CAR_REV_5)
m_sQueueSample.m_nFrequency /= 2;
m_sQueueSample.m_nLoopCount = 0;
SET_EMITTING_VOLUME(emittingVol);
@@ -1054,15 +1860,20 @@ cAudioManager::ProcessVehicleEngine(cVehicleParams& params)
}
void
-cAudioManager::UpdateGasPedalAudio(CAutomobile *automobile)
+cAudioManager::UpdateGasPedalAudio(CVehicle* veh, int vehType)
{
- float gasPedal = Abs(automobile->m_fGasPedal);
- float gasPedalAudio = automobile->m_fGasPedalAudio;
+ float gasPedal = Abs(veh->m_fGasPedal);
+ float* gasPealAudioPtr;
- if (gasPedalAudio < gasPedal)
- automobile->m_fGasPedalAudio = Min(gasPedalAudio + 0.09f, gasPedal);
+ switch(vehType) {
+ case VEHICLE_TYPE_CAR: gasPealAudioPtr = &((CAutomobile *)veh)->m_fGasPedalAudio; break;
+ case VEHICLE_TYPE_BIKE: gasPealAudioPtr = &((CBike *)veh)->m_fGasPedalAudio; break;
+ default: return;
+ }
+ if (*gasPealAudioPtr < gasPedal)
+ *gasPealAudioPtr = Min(*gasPealAudioPtr + 0.09f, gasPedal);
else
- automobile->m_fGasPedalAudio = Max(gasPedalAudio - 0.07f, gasPedal);
+ *gasPealAudioPtr = Max(*gasPealAudioPtr - 0.07f, gasPedal);
}
void
@@ -1111,29 +1922,12 @@ cAudioManager::AddPlayerCarSample(uint8 emittingVolume, uint32 freq, uint32 samp
}
void
-cAudioManager::ProcessCesna(cVehicleParams& params)
+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, SFX_BANK_0, 52, TRUE);
- AddPlayerCarSample(85 * nAccel / 60 + 20, 8500 * nAccel / 60 + 17000, SFX_CESNA_REV, SFX_BANK_0, 2, TRUE);
- }
- } else if (params.m_nIndex == DODO) {
- AddPlayerCarSample(105, 17000, SFX_CESNA_IDLE, SFX_BANK_0, 52, TRUE);
- } else if (params.m_fDistance < SQR(200)) {
+ 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) {
+ if(m_sQueueSample.m_nVolume != 0) {
m_sQueueSample.m_nCounter = 52;
m_sQueueSample.m_nSampleIndex = SFX_CESNA_IDLE;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
@@ -1144,27 +1938,27 @@ cAudioManager::ProcessCesna(cVehicleParams& params)
m_sQueueSample.m_nReleasingVolumeDivider = 8;
SET_EMITTING_VOLUME(80);
SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
- m_sQueueSample.m_fSpeedMultiplier = 8.0f;
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
m_sQueueSample.m_SoundIntensity = 200.0f;
m_sQueueSample.m_bReleasingSoundFlag = FALSE;
m_sQueueSample.m_bReverbFlag = TRUE;
m_sQueueSample.m_bRequireReflection = FALSE;
AddSampleToRequestedQueue();
}
- if (params.m_fDistance < SQR(90)) {
+ if(params.m_fDistance < SQR(90)) {
m_sQueueSample.m_nVolume = ComputeVolume(80, 90.f, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
+ if(m_sQueueSample.m_nVolume != 0) {
m_sQueueSample.m_nCounter = 2;
m_sQueueSample.m_nSampleIndex = SFX_CESNA_REV;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_bIs2D = FALSE;
- m_sQueueSample.m_nReleasingVolumeModificator = 0;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
m_sQueueSample.m_nFrequency = 25000;
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_nReleasingVolumeDivider = 4;
SET_EMITTING_VOLUME(80);
SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
- m_sQueueSample.m_fSpeedMultiplier = 8.0f;
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
m_sQueueSample.m_SoundIntensity = 90.0f;
m_sQueueSample.m_bReleasingSoundFlag = FALSE;
m_sQueueSample.m_bReverbFlag = TRUE;
@@ -1176,41 +1970,52 @@ cAudioManager::ProcessCesna(cVehicleParams& params)
}
void
-cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams& params, CAutomobile *automobile)
+cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams& params, CVehicle* veh)
{
- static int32 GearFreqAdj[] = {6000, 6000, 3400, 1200, 0, -1000};
+ static int32 GearFreqAdj[] = { 6000, 6000, 3400, 1200, 0, -1000 };
- cTransmission *transmission;
- float velocityChange;
- float relativeVelocityChange;
- float accelerationMultipler;
+ tWheelState* wheelState;
+ CAutomobile* automobile;
+ CBike* bike;
+ CVector pos;
+ float* gasPedalAudioPtr;
+
+ int32 accelerateState;
+ int32 brakeState;
+ int32 freq;
+ int32 baseFreq;
+ int32 freqModifier;
+ uint32 gearSoundLength;
+ uint32 soundOffset;
+ uint8 engineSoundType;
uint8 wheelInUseCounter;
- float time;
- int baseFreq;
+ uint8 wheelsOnGround;
uint8 vol;
- int gearNr;
- int32 freq;
+ uint8 currentGear;
+ uint8 wheelsOnGroundPrev;
- int freqModifier;
- int soundOffset;
- uint8 engineSoundType;
- int16 accelerateState;
+ float accelerationMultipler;
+ float gasPedalAudio;
+ float velocityChangeForAudio;
+ float relativeVelocityChange;
+ float time;
bool8 channelUsed;
bool8 lostTraction;
+ bool8 noGearBox;
+ bool8 stuckInSand;
bool8 processedAccelSampleStopped;
- uint8 currentGear;
- float gasPedalAudio;
- CVector pos;
+ bool8 isMoped;
+ static uint32 gearSoundStartTime = CTimer::GetTimeInMilliseconds();
+ static int32 nCruising = 0;
static int16 LastAccel = 0;
- static int16 LastBrake = 0;
static uint8 CurrentPretendGear = 1;
static bool8 bLostTractionLastFrame = FALSE;
static bool8 bHandbrakeOnLastFrame = FALSE;
- static int32 nCruising = 0;
static bool8 bAccelSampleStopped = TRUE;
lostTraction = FALSE;
+ isMoped = params.m_pVehicle->m_modelIndex == MI_PIZZABOY || params.m_pVehicle->m_modelIndex == MI_FAGGIO;
processedAccelSampleStopped = FALSE;
if (bPlayerJustEnteredCar) {
bAccelSampleStopped = TRUE;
@@ -1218,48 +2023,91 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams& params, CAutomobile *
nCruising = 0;
LastAccel = 0;
bLostTractionLastFrame = FALSE;
- LastBrake = 0;
- bHandbrakeOnLastFrame = FALSE;
CurrentPretendGear = 1;
+ bHandbrakeOnLastFrame = FALSE;
}
- if (CReplay::IsPlayingBack())
- accelerateState = 255.f * Clamp(automobile->m_fGasPedal, 0.0f, 1.0f);
- else
+ if (CReplay::IsPlayingBack()) {
+ accelerateState = (255.0f * Clamp(params.m_pVehicle->m_fGasPedal, 0.0f, 1.0f));
+ brakeState = (255.0f * Clamp(params.m_pVehicle->m_fBrakePedal, 0.0f, 1.0f));
+ } else {
accelerateState = Pads[0].GetAccelerate();
-
+ brakeState = Pads[0].GetBrake();
+ }
channelUsed = SampleManager.GetChannelUsedFlag(CHANNEL_PLAYER_VEHICLE_ENGINE);
- 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;
+ if (isMoped) {
+ CurrentPretendGear = params.m_pTransmission->nNumberOfGears;
+ currentGear = CurrentPretendGear;
+ if (params.m_pVehicle->bIsHandbrakeOn) {
+ brakeState = 0;
+ nCruising = 0;
+ LastAccel = 0;
+ accelerateState = 0;
+ } else {
+ nCruising = 1;
+ }
+ } else {
+ 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[CARWHEEL_FRONT_LEFT] != WHEEL_STATE_NORMAL || automobile->m_aWheelState[CARWHEEL_FRONT_RIGHT] != WHEEL_STATE_NORMAL) &&
- (automobile->m_aWheelState[CARWHEEL_REAR_LEFT] != WHEEL_STATE_NORMAL || automobile->m_aWheelState[CARWHEEL_REAR_RIGHT] != WHEEL_STATE_NORMAL))
- lostTraction = TRUE;
- break;
- case 'R':
- if ((automobile->m_aWheelState[CARWHEEL_REAR_LEFT] != WHEEL_STATE_NORMAL) || (automobile->m_aWheelState[CARWHEEL_REAR_RIGHT] != WHEEL_STATE_NORMAL))
- lostTraction = TRUE;
+ switch (params.m_VehicleType) {
+ case VEHICLE_TYPE_CAR:
+ automobile = (CAutomobile*)params.m_pVehicle;
+ wheelsOnGround = automobile->m_nDriveWheelsOnGround;
+ wheelsOnGroundPrev = automobile->m_nDriveWheelsOnGroundPrev;
+ gasPedalAudioPtr = &automobile->m_fGasPedalAudio;
+ wheelState = automobile->m_aWheelState;
+ velocityChangeForAudio = automobile->m_fVelocityChangeForAudio;
+ break;
+ case VEHICLE_TYPE_BIKE:
+ bike = (CBike*)params.m_pVehicle;
+ wheelsOnGround = bike->m_nDriveWheelsOnGround;
+ wheelsOnGroundPrev = bike->m_nDriveWheelsOnGroundPrev;
+ gasPedalAudioPtr = &bike->m_fGasPedalAudio;
+ wheelState = bike->m_aWheelState;
+ velocityChangeForAudio = bike->m_fVelocityChangeForAudio;
break;
+ default:
+ debug(" ** AUDIOLOG: Unrecognised vehicle type %d in ProcessVehicleEngine() * \n", params.m_VehicleType);
+ return;
}
-
- if (velocityChange != 0.0f) {
- time = params.m_pVehicle->m_vecMoveSpeed.z / velocityChange;
+ if (!isMoped) {
+ switch (params.m_pTransmission->nDriveType) {
+ case '4':
+ if (params.m_VehicleType != VEHICLE_TYPE_BIKE) {
+ wheelInUseCounter = 0;
+ for (uint8 i = 0; i < 4; i++) {
+ if (wheelState[i] != WHEEL_STATE_NORMAL)
+ ++wheelInUseCounter;
+ }
+ if (wheelInUseCounter > 2)
+ lostTraction = TRUE;
+ }
+ break;
+ case 'F':
+ if (params.m_VehicleType == VEHICLE_TYPE_BIKE) {
+ if (wheelState[BIKEWHEEL_FRONT] != WHEEL_STATE_NORMAL)
+ lostTraction = TRUE;
+ } else {
+ if ((wheelState[CARWHEEL_FRONT_LEFT] != WHEEL_STATE_NORMAL || wheelState[CARWHEEL_FRONT_RIGHT] != WHEEL_STATE_NORMAL) &&
+ (wheelState[CARWHEEL_REAR_LEFT] != WHEEL_STATE_NORMAL || wheelState[CARWHEEL_REAR_RIGHT] != WHEEL_STATE_NORMAL))
+ lostTraction = TRUE;
+ }
+ break;
+ case 'R':
+ if (params.m_VehicleType == VEHICLE_TYPE_BIKE) {
+ if (wheelState[BIKEWHEEL_REAR] != WHEEL_STATE_NORMAL)
+ lostTraction = TRUE;
+ } else {
+ if (wheelState[CARWHEEL_REAR_LEFT] != WHEEL_STATE_NORMAL || wheelState[CARWHEEL_REAR_RIGHT] != WHEEL_STATE_NORMAL)
+ lostTraction = TRUE;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if (params.m_fVelocityChange != 0.0f) {
+ time = params.m_pVehicle->m_vecMoveSpeed.z / params.m_fVelocityChange;
if (time > 0.0f)
freqModifier = -(Min(0.2f, time) * 3000.0f * 5.0f);
else
@@ -1268,63 +2116,155 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams& params, CAutomobile *
freqModifier = -freqModifier;
} else
freqModifier = 0;
-
+ if (params.m_VehicleType == VEHICLE_TYPE_BIKE && bike->bExtraSpeed)
+ freqModifier += 1400;
+ gearSoundLength = 0;
engineSoundType = aVehicleSettings[params.m_nIndex].m_nBank;
soundOffset = 3 * (engineSoundType - CAR_SFX_BANKS_OFFSET);
+ noGearBox = FALSE;
+ switch (engineSoundType) {
+ case SFX_BANK_PONTIAC:
+ gearSoundLength = 2526;
+ break;
+ case SFX_BANK_PORSCHE:
+ gearSoundLength = 3587;
+ break;
+ case SFX_BANK_SPIDER:
+ gearSoundLength = 4898;
+ break;
+ case SFX_BANK_MERC:
+ gearSoundLength = 4003;
+ break;
+ case SFX_BANK_TRUCK:
+ gearSoundLength = 6289;
+ break;
+ case SFX_BANK_HOTROD:
+ gearSoundLength = 2766;
+ break;
+ case SFX_BANK_COBRA:
+ gearSoundLength = 3523;
+ break;
+ case SFX_BANK_PONTIAC_SLOW:
+ gearSoundLength = 2773;
+ break;
+ case SFX_BANK_CADILLAC:
+ gearSoundLength = 2560;
+ break;
+ case SFX_BANK_PATHFINDER:
+ gearSoundLength = 4228;
+ break;
+ case SFX_BANK_PACARD:
+ gearSoundLength = 4648;
+ break;
+ case SFX_BANK_VTWIN:
+ gearSoundLength = 3480;
+ break;
+ case SFX_BANK_HONDA250:
+ gearSoundLength = 2380;
+ break;
+ case SFX_BANK_SPORTS_BIKE:
+ gearSoundLength = 2410;
+ break;
+ default:
+ noGearBox = TRUE;
+ break;
+ }
+ if (!channelUsed || nCruising || noGearBox) {
+ gearSoundStartTime = CTimer::GetTimeInMilliseconds();
+ } else {
+ gearSoundLength -= 1000;
+ if (CTimer::GetTimeInMilliseconds() - gearSoundStartTime > gearSoundLength) {
+ channelUsed = FALSE;
+ gearSoundStartTime = CTimer::GetTimeInMilliseconds();
+ }
+ }
+ relativeVelocityChange = 2.0f * params.m_fVelocityChange / params.m_pTransmission->fMaxVelocity;
+ accelerationMultipler = Clamp(relativeVelocityChange, 0.0f, 1.0f);
+ gasPedalAudio = accelerationMultipler;
+ switch (engineSoundType) {
+ case SFX_BANK_MOPED:
+ ++soundOffset;
+ break;
+ case SFX_BANK_HONDA250:
+ soundOffset += 2;
+ break;
+ case SFX_BANK_SPORTS_BIKE:
+ soundOffset += 3;
+ break;
+ default:
+ break;
+ }
if (accelerateState <= 0) {
if (params.m_fVelocityChange < -0.001f) {
if (channelUsed) {
SampleManager.StopChannel(CHANNEL_PLAYER_VEHICLE_ENGINE);
bAccelSampleStopped = TRUE;
}
- if (automobile->m_nWheelsOnGround == 0 || automobile->bIsHandbrakeOn || lostTraction)
- gasPedalAudio = automobile->m_fGasPedalAudio;
+ if (wheelsOnGround == 0 || params.m_pVehicle->bIsHandbrakeOn || lostTraction)
+ gasPedalAudio = *gasPedalAudioPtr;
+ else if (params.m_VehicleType == VEHICLE_TYPE_BIKE)
+ gasPedalAudio = 0.0f;
else
gasPedalAudio = Min(1.0f, params.m_fVelocityChange / params.m_pTransmission->fMaxReverseVelocity);
-
- gasPedalAudio = Max(0.0f, gasPedalAudio);
- automobile->m_fGasPedalAudio = gasPedalAudio;
+ *gasPedalAudioPtr = Max(0.0f, gasPedalAudio);
} else if (LastAccel > 0) {
if (channelUsed) {
SampleManager.StopChannel(CHANNEL_PLAYER_VEHICLE_ENGINE);
bAccelSampleStopped = TRUE;
}
nCruising = 0;
- if (automobile->m_nWheelsOnGround == 0 || automobile->bIsHandbrakeOn || lostTraction ||
- params.m_fVelocityChange < 0.01f && automobile->m_fGasPedalAudio > 0.2f) {
- automobile->m_fGasPedalAudio *= 0.6f;
- gasPedalAudio = automobile->m_fGasPedalAudio;
+ if (wheelsOnGround == 0
+ || params.m_pVehicle->bIsHandbrakeOn
+ || lostTraction
+ || params.m_fVelocityChange < 0.01f && *gasPedalAudioPtr > 0.2f) {
+ if (isMoped) {
+ gasPedalAudio = 0.0f;
+ } else {
+ *gasPedalAudioPtr *= 0.6f;
+ gasPedalAudio = *gasPedalAudioPtr;
+ }
}
if (gasPedalAudio > 0.05f) {
freq = (5000.f * (gasPedalAudio - 0.05f) * 20.f / 19) + 19000;
+ vol = (25.0f * (gasPedalAudio - 0.05f) * 20.f / 19) + 40;
+ if (params.m_pVehicle->bIsDrowning)
+ vol /= 4;
if (engineSoundType == SFX_BANK_TRUCK)
freq /= 2;
- AddPlayerCarSample((25.f * (gasPedalAudio - 0.05f) * 20.f / 19) + 40, freq, (soundOffset + SFX_CAR_FINGER_OFF_ACCEL_1), engineSoundType, 63,
- FALSE);
+ AddPlayerCarSample(vol, freq, soundOffset + SFX_CAR_FINGER_OFF_ACCEL_1, engineSoundType, 63, FALSE);
}
}
freq = (10000.f * gasPedalAudio) + 22050;
+ vol = 110 - (40.0f * gasPedalAudio);
if (engineSoundType == SFX_BANK_TRUCK)
freq /= 2;
- AddPlayerCarSample(110 - (40.f * gasPedalAudio), freq, (engineSoundType - CAR_SFX_BANKS_OFFSET + SFX_CAR_IDLE_1), SFX_BANK_0, 52, TRUE);
+ if (params.m_pVehicle->bIsDrowning)
+ vol /= 4;
+ AddPlayerCarSample(vol, freq, engineSoundType - CAR_SFX_BANKS_OFFSET + SFX_CAR_IDLE_1, SFX_BANK_0, 52, TRUE);
CurrentPretendGear = Max(1, currentGear);
- } else {
- while (nCruising == 0) {
- if (accelerateState < 150 || automobile->m_nWheelsOnGround == 0 || automobile->bIsHandbrakeOn || lostTraction ||
- currentGear < 2 && velocityChange - automobile->m_fVelocityChangeForAudio < 0.01f) { // here could be used abs
- if (automobile->m_nWheelsOnGround == 0 || automobile->bIsHandbrakeOn || lostTraction) {
- if (automobile->m_nWheelsOnGround == 0 && automobile->m_nDriveWheelsOnGround != 0 ||
- (automobile->bIsHandbrakeOn && !bHandbrakeOnLastFrame || lostTraction && !bLostTractionLastFrame) && automobile->m_nWheelsOnGround != 0) {
- automobile->m_fGasPedalAudio *= 0.6f;
+ }
+ else {
+ if (nCruising == 0){
+ stuckInSand = params.m_VehicleType == VEHICLE_TYPE_CAR && ((CAutomobile*)params.m_pVehicle)->bStuckInSand;
+ if (accelerateState < 150 || wheelsOnGround == 0 || params.m_pVehicle->bIsHandbrakeOn || lostTraction
+ || (currentGear < 2 && params.m_fVelocityChange - velocityChangeForAudio < 0.01f) || brakeState > 0) {
+
+ if (((wheelsOnGround && !params.m_pVehicle->bIsHandbrakeOn && !lostTraction ) || stuckInSand) && brakeState <= 0) {
+ baseFreq = (8000.0f * accelerationMultipler) + 16000;
+ vol = (25.0f * accelerationMultipler) + 60;
+ *gasPedalAudioPtr = accelerationMultipler;
+ } else {
+ if (wheelsOnGround == 0 && wheelsOnGroundPrev != 0 || (params.m_pVehicle->bIsHandbrakeOn && !bHandbrakeOnLastFrame || lostTraction && !bLostTractionLastFrame)
+ && wheelsOnGround != 0) {
+ *gasPedalAudioPtr *= 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;
+ if (engineSoundType != SFX_BANK_GOLF_CART && engineSoundType != SFX_BANK_CAR_CHAINSAW)
+ baseFreq = (25000.0f * *gasPedalAudioPtr) + 14000;
+ else
+ baseFreq = (15000.0f * *gasPedalAudioPtr) + 14000;
+ vol = (25.0f * *gasPedalAudioPtr) + 60;
}
freq = freqModifier + baseFreq;
if (engineSoundType == SFX_BANK_TRUCK)
@@ -1333,66 +2273,98 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams& params, CAutomobile *
SampleManager.StopChannel(CHANNEL_PLAYER_VEHICLE_ENGINE);
bAccelSampleStopped = TRUE;
}
- AddPlayerCarSample(vol, freq, (engineSoundType - CAR_SFX_BANKS_OFFSET + SFX_CAR_REV_1), SFX_BANK_0, 2, TRUE);
+ if (params.m_pVehicle->bIsDrowning)
+ vol /= 4;
+ AddPlayerCarSample(vol, freq, engineSoundType - CAR_SFX_BANKS_OFFSET + SFX_CAR_REV_1, SFX_BANK_0, 2, TRUE);
} else {
TranslateEntity(&m_sQueueSample.m_vecPos, &pos);
#ifndef EXTERNAL_3D_SOUND
m_sQueueSample.m_nOffset = ComputePan(m_sQueueSample.m_fDistance, &pos);
#endif
if (bAccelSampleStopped) {
- if (CurrentPretendGear != 1 || currentGear != 2) {
- gearNr = currentGear - 1;
- if (gearNr < 1)
- gearNr = 1;
- CurrentPretendGear = gearNr;
- }
+ if (CurrentPretendGear != 1 || currentGear != 2)
+ CurrentPretendGear = Max(1, currentGear - 1);
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 (channelUsed) {
+#ifdef EXTERNAL_3D_SOUND
+ SampleManager.SetChannelEmittingVolume(CHANNEL_PLAYER_VEHICLE_ENGINE, 120);
+ SampleManager.SetChannel3DPosition(CHANNEL_PLAYER_VEHICLE_ENGINE, pos.x, pos.y, pos.z);
+ SampleManager.SetChannel3DDistances(CHANNEL_PLAYER_VEHICLE_ENGINE, 50.0f, 50.0f * 0.25f);
+#else
+ SampleManager.SetChannelVolume(CHANNEL_PLAYER_VEHICLE_ENGINE, ComputeVolume(120, 50.0f, m_sQueueSample.m_fDistance));
+ SampleManager.SetChannelPan(CHANNEL_PLAYER_VEHICLE_ENGINE, m_sQueueSample.m_nOffset);
+#endif
+ freq = GearFreqAdj[CurrentPretendGear] + freqModifier + 22050;
+ if (engineSoundType == SFX_BANK_TRUCK)
+ freq /= 2;
+ SampleManager.SetChannelFrequency(CHANNEL_PLAYER_VEHICLE_ENGINE, freq);
+ if (!channelUsed) {
+ SampleManager.SetChannelReverbFlag(CHANNEL_PLAYER_VEHICLE_ENGINE, m_bDynamicAcousticModelingStatus != FALSE);
+ SampleManager.StartChannel(CHANNEL_PLAYER_VEHICLE_ENGINE);
}
+ } else if (processedAccelSampleStopped) {
+ gearSoundStartTime = CTimer::GetTimeInMilliseconds();
+ params.m_pVehicle->bAudioChangingGear = TRUE;
+ if (!SampleManager.InitialiseChannel(CHANNEL_PLAYER_VEHICLE_ENGINE, soundOffset + SFX_CAR_ACCEL_1, SFX_BANK_0))
+ return;
+ SampleManager.SetChannelLoopCount(CHANNEL_PLAYER_VEHICLE_ENGINE, 1);
+ SampleManager.SetChannelLoopPoints(CHANNEL_PLAYER_VEHICLE_ENGINE, 0, -1);
+#ifdef EXTERNAL_3D_SOUND
+ SampleManager.SetChannelEmittingVolume(CHANNEL_PLAYER_VEHICLE_ENGINE, 120);
+ SampleManager.SetChannel3DPosition(CHANNEL_PLAYER_VEHICLE_ENGINE, pos.x, pos.y, pos.z);
+ SampleManager.SetChannel3DDistances(CHANNEL_PLAYER_VEHICLE_ENGINE, 50.0f, 50.0f * 0.25f);
+#else
+ SampleManager.SetChannelVolume(CHANNEL_PLAYER_VEHICLE_ENGINE, ComputeVolume(120, 50.0f, m_sQueueSample.m_fDistance));
+ SampleManager.SetChannelPan(CHANNEL_PLAYER_VEHICLE_ENGINE, m_sQueueSample.m_nOffset);
+#endif
+ freq = (GearFreqAdj[CurrentPretendGear] + freqModifier + 22050);
+ if (engineSoundType == SFX_BANK_TRUCK)
+ freq /= 2;
+ SampleManager.SetChannelFrequency(CHANNEL_PLAYER_VEHICLE_ENGINE, freq);
+ if (!channelUsed) {
+ SampleManager.SetChannelReverbFlag(CHANNEL_PLAYER_VEHICLE_ENGINE, m_bDynamicAcousticModelingStatus != FALSE);
+ SampleManager.StartChannel(CHANNEL_PLAYER_VEHICLE_ENGINE);
+ }
+ } else if (CurrentPretendGear < params.m_pTransmission->nNumberOfGears - 1) {
+ ++CurrentPretendGear;
+ gearSoundStartTime = CTimer::GetTimeInMilliseconds();
+ params.m_pVehicle->bAudioChangingGear = TRUE;
if (!SampleManager.InitialiseChannel(CHANNEL_PLAYER_VEHICLE_ENGINE, soundOffset + SFX_CAR_ACCEL_1, SFX_BANK_0))
return;
SampleManager.SetChannelLoopCount(CHANNEL_PLAYER_VEHICLE_ENGINE, 1);
SampleManager.SetChannelLoopPoints(CHANNEL_PLAYER_VEHICLE_ENGINE, 0, -1);
- }
#ifdef EXTERNAL_3D_SOUND
- SampleManager.SetChannelEmittingVolume(CHANNEL_PLAYER_VEHICLE_ENGINE, 85);
- SampleManager.SetChannel3DPosition(CHANNEL_PLAYER_VEHICLE_ENGINE, pos.x, pos.y, pos.z);
- SampleManager.SetChannel3DDistances(CHANNEL_PLAYER_VEHICLE_ENGINE, 50.0f, 50.0f * 0.25f);
+ SampleManager.SetChannelEmittingVolume(CHANNEL_PLAYER_VEHICLE_ENGINE, 120);
+ SampleManager.SetChannel3DPosition(CHANNEL_PLAYER_VEHICLE_ENGINE, pos.x, pos.y, pos.z);
+ SampleManager.SetChannel3DDistances(CHANNEL_PLAYER_VEHICLE_ENGINE, 50.0f, 50.0f * 0.25f);
#else
-
- SampleManager.SetChannelVolume(CHANNEL_PLAYER_VEHICLE_ENGINE, ComputeVolume(85, 50.0f, m_sQueueSample.m_fDistance));
- SampleManager.SetChannelPan(CHANNEL_PLAYER_VEHICLE_ENGINE, m_sQueueSample.m_nOffset);
+ SampleManager.SetChannelVolume(CHANNEL_PLAYER_VEHICLE_ENGINE, ComputeVolume(120, 50.0f, m_sQueueSample.m_fDistance));
+ SampleManager.SetChannelPan(CHANNEL_PLAYER_VEHICLE_ENGINE, m_sQueueSample.m_nOffset);
#endif
- freq = GearFreqAdj[CurrentPretendGear] + freqModifier + 22050;
- if (engineSoundType == SFX_BANK_TRUCK)
- freq /= 2;
- SampleManager.SetChannelFrequency(CHANNEL_PLAYER_VEHICLE_ENGINE, freq);
- if (!channelUsed) {
- SampleManager.SetChannelReverbFlag(CHANNEL_PLAYER_VEHICLE_ENGINE, m_bDynamicAcousticModelingStatus != FALSE);
- SampleManager.StartChannel(CHANNEL_PLAYER_VEHICLE_ENGINE);
+ freq = (GearFreqAdj[CurrentPretendGear] + freqModifier + 22050);
+ if (engineSoundType == SFX_BANK_TRUCK)
+ freq /= 2;
+ SampleManager.SetChannelFrequency(CHANNEL_PLAYER_VEHICLE_ENGINE, freq);
+ if (!channelUsed) {
+ SampleManager.SetChannelReverbFlag(CHANNEL_PLAYER_VEHICLE_ENGINE, m_bDynamicAcousticModelingStatus != FALSE);
+ SampleManager.StartChannel(CHANNEL_PLAYER_VEHICLE_ENGINE);
+ }
+ } else {
+ nCruising = 1;
+ goto PlayCruising;
}
}
- break;
- }
- if (nCruising != 0) {
+ } else {
+PlayCruising:
bAccelSampleStopped = TRUE;
- if (accelerateState < 150 || automobile->m_nWheelsOnGround == 0 || automobile->bIsHandbrakeOn || lostTraction ||
- currentGear < params.m_pTransmission->nNumberOfGears - 1) {
- nCruising = 0;
- } else {
- if (accelerateState >= 220 && params.m_fVelocityChange + 0.001f < automobile->m_fVelocityChangeForAudio) {
+ SampleManager.StopChannel(CHANNEL_PLAYER_VEHICLE_ENGINE);
+ if (isMoped || accelerateState >= 150 && wheelsOnGround && brakeState <= 0 && !params.m_pVehicle->bIsHandbrakeOn
+ && !lostTraction && currentGear >= params.m_pTransmission->nNumberOfGears - 1) {
+ if (accelerateState >= 220 && params.m_fVelocityChange + 0.001f >= velocityChangeForAudio) {
if (nCruising < 800)
++nCruising;
} else if (nCruising > 3) {
@@ -1401,14 +2373,16 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams& params, CAutomobile *
freq = 27 * nCruising + freqModifier + 22050;
if (engineSoundType == SFX_BANK_TRUCK)
freq /= 2;
- AddPlayerCarSample(85, freq, (soundOffset + SFX_CAR_AFTER_ACCEL_1), engineSoundType, 64, TRUE);
+ AddPlayerCarSample(120, freq, soundOffset + SFX_CAR_AFTER_ACCEL_1, engineSoundType, 64, TRUE);
+ } else {
+ nCruising = 0;
}
}
}
LastAccel = accelerateState;
-
- bHandbrakeOnLastFrame = !!automobile->bIsHandbrakeOn;
+ bHandbrakeOnLastFrame = params.m_pVehicle->bIsHandbrakeOn;
bLostTractionLastFrame = lostTraction;
+ return;
}
bool8
@@ -1417,6 +2391,13 @@ cAudioManager::ProcessVehicleSkidding(cVehicleParams& params)
const float SOUND_INTENSITY = 40.0f;
CAutomobile *automobile;
+ CBike *bike;
+ uint8 numWheels;
+ uint8 wheelsOnGround;
+ float gasPedalAudio;
+ tWheelState* wheelStateArr;
+
+
cTransmission *transmission;
int32 emittingVol;
float newSkidVal = 0.0f;
@@ -1424,29 +2405,48 @@ cAudioManager::ProcessVehicleSkidding(cVehicleParams& params)
if (params.m_fDistance >= SQR(SOUND_INTENSITY))
return FALSE;
- automobile = (CAutomobile *)params.m_pVehicle;
- if (automobile->m_nWheelsOnGround == 0)
+ switch (params.m_VehicleType) {
+ case VEHICLE_TYPE_CAR:
+ automobile = (CAutomobile*)params.m_pVehicle;
+ numWheels = 4;
+ wheelStateArr = automobile->m_aWheelState;
+ wheelsOnGround = automobile->m_nWheelsOnGround;
+ gasPedalAudio = automobile->m_fGasPedalAudio;
+ break;
+ case VEHICLE_TYPE_BIKE:
+ bike = (CBike*)params.m_pVehicle;
+ numWheels = 2;
+ wheelStateArr = bike->m_aWheelState;
+ wheelsOnGround = bike->m_nWheelsOnGround;
+ gasPedalAudio = bike->m_fGasPedalAudio;
+ break;
+ default:
+ debug("\n * AUDIOLOG: ProcessVehicleSkidding() Unsupported vehicle type %d * \n", params.m_VehicleType);
+ return TRUE;
+ }
+ if (wheelsOnGround == 0)
return TRUE;
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)
+
+ for (int32 i = 0; i < numWheels; i++) {
+ if (wheelStateArr[i] == WHEEL_STATE_NORMAL)
continue;
transmission = params.m_pTransmission;
switch (transmission->nDriveType) {
case '4':
- newSkidVal = GetVehicleDriveWheelSkidValue(i, automobile, transmission, params.m_fVelocityChange);
+ newSkidVal = GetVehicleDriveWheelSkidValue(params.m_pVehicle, wheelStateArr[i], gasPedalAudio, transmission, params.m_fVelocityChange);
break;
case 'F':
if (i == CARWHEEL_FRONT_LEFT || i == CARWHEEL_FRONT_RIGHT)
- newSkidVal = GetVehicleDriveWheelSkidValue(i, automobile, transmission, params.m_fVelocityChange);
+ newSkidVal = GetVehicleDriveWheelSkidValue(params.m_pVehicle, wheelStateArr[i], gasPedalAudio, transmission, params.m_fVelocityChange);
else
- newSkidVal = GetVehicleNonDriveWheelSkidValue(i, automobile, transmission, params.m_fVelocityChange);
+ newSkidVal = GetVehicleNonDriveWheelSkidValue(params.m_pVehicle, wheelStateArr[i], transmission, params.m_fVelocityChange);
break;
case 'R':
if (i == CARWHEEL_REAR_LEFT || i == CARWHEEL_REAR_RIGHT)
- newSkidVal = GetVehicleDriveWheelSkidValue(i, automobile, transmission, params.m_fVelocityChange);
+ newSkidVal = GetVehicleDriveWheelSkidValue(params.m_pVehicle, wheelStateArr[i], gasPedalAudio, transmission, params.m_fVelocityChange);
else
- newSkidVal = GetVehicleNonDriveWheelSkidValue(i, automobile, transmission, params.m_fVelocityChange);
+ newSkidVal = GetVehicleNonDriveWheelSkidValue(params.m_pVehicle, wheelStateArr[i], transmission, params.m_fVelocityChange);
break;
default:
break;
@@ -1473,6 +2473,7 @@ cAudioManager::ProcessVehicleSkidding(cVehicleParams& params)
case SURFACE_MUD_DRY:
case SURFACE_SAND:
case SURFACE_WATER:
+ case SURFACE_SAND_BEACH:
m_sQueueSample.m_nSampleIndex = SFX_GRAVEL_SKID;
m_sQueueSample.m_nFrequency = 6000.f * skidVal + 10000.f;
break;
@@ -1480,6 +2481,8 @@ cAudioManager::ProcessVehicleSkidding(cVehicleParams& params)
default:
m_sQueueSample.m_nSampleIndex = SFX_SKID;
m_sQueueSample.m_nFrequency = 5000.f * skidVal + 11000.f;
+ if (params.m_VehicleType == VEHICLE_TYPE_BIKE)
+ m_sQueueSample.m_nFrequency += 2000;
break;
}
@@ -1502,18 +2505,17 @@ cAudioManager::ProcessVehicleSkidding(cVehicleParams& params)
}
float
-cAudioManager::GetVehicleDriveWheelSkidValue(uint8 wheel, CAutomobile *automobile, cTransmission *transmission, float velocityChange)
+cAudioManager::GetVehicleDriveWheelSkidValue(CVehicle *veh, tWheelState wheelState, float gasPedalAudio, cTransmission *transmission, float velocityChange)
{
float relativeVelChange = 0.0f;
- float gasPedalAudio = automobile->m_fGasPedalAudio;
float velChange;
float relativeVel;
- switch (automobile->m_aWheelState[wheel])
+ switch (wheelState)
{
case WHEEL_STATE_SPINNING:
if (gasPedalAudio > 0.4f)
- relativeVelChange = (gasPedalAudio - 0.4f) * (5.0f / 3.0f) / (4.0f / 3.0f);
+ relativeVelChange = (gasPedalAudio - 0.4f) * (5.0f / 3.0f) * 0.75f;
break;
case WHEEL_STATE_SKIDDING:
relativeVelChange = Min(1.0f, Abs(velocityChange) / transmission->fMaxVelocity);
@@ -1534,92 +2536,92 @@ cAudioManager::GetVehicleDriveWheelSkidValue(uint8 wheel, CAutomobile *automobil
break;
}
- return Max(relativeVelChange, Min(1.0f, Abs(automobile->m_vecTurnSpeed.z) * 20.0f));
+ return Max(relativeVelChange, Min(1.0f, Abs(veh->m_vecTurnSpeed.z) * 20.0f));
}
float
-cAudioManager::GetVehicleNonDriveWheelSkidValue(uint8 wheel, CAutomobile *automobile, cTransmission *transmission, float velocityChange)
+cAudioManager::GetVehicleNonDriveWheelSkidValue(CVehicle *veh, tWheelState wheelState, cTransmission *transmission, float velocityChange)
{
float relativeVelChange = 0.0f;
- if (automobile->m_aWheelState[wheel] == WHEEL_STATE_SKIDDING)
+ if (wheelState == WHEEL_STATE_SKIDDING)
relativeVelChange = Min(1.0f, Abs(velocityChange) / transmission->fMaxVelocity);
- return Max(relativeVelChange, Min(1.0f, Abs(automobile->m_vecTurnSpeed.z) * 20.0f));
+ return Max(relativeVelChange, Min(1.0f, Abs(veh->m_vecTurnSpeed.z) * 20.0f));
}
-void
+bool8
cAudioManager::ProcessVehicleHorn(cVehicleParams& params)
{
const float SOUND_INTENSITY = 40.0f;
- CAutomobile *automobile;
+ CVehicle *veh;
+ uint8 volume;
- 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;
- }
+ if (params.m_fDistance >= SQR(SOUND_INTENSITY))
+ return FALSE;
- 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 = SFX_BANK_0;
- 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;
- SET_EMITTING_VOLUME(80);
- SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
- m_sQueueSample.m_fSpeedMultiplier = 5.0f;
- m_sQueueSample.m_SoundIntensity = SOUND_INTENSITY;
- m_sQueueSample.m_bReleasingSoundFlag = FALSE;
- m_sQueueSample.m_nReleasingVolumeDivider = 3;
- m_sQueueSample.m_bReverbFlag = TRUE;
- m_sQueueSample.m_bRequireReflection = FALSE;
- AddSampleToRequestedQueue();
- }
- }
+ veh = params.m_pVehicle;
+ if (veh->m_bSirenOrAlarm && UsesSirenSwitching(params))
+ return TRUE;
+
+ if (veh->m_modelIndex == MI_MRWHOOP)
+ return TRUE;
+
+ if (veh->IsAlarmOn())
+ return TRUE;
+
+ if (veh->m_nCarHornTimer != 0) {
+ if (veh->GetStatus() != STATUS_PLAYER) {
+ veh->m_nCarHornTimer = Min(44, veh->m_nCarHornTimer);
+ if (veh->m_nCarHornTimer == 44)
+ veh->m_nCarHornPattern = (m_FrameCounter + m_sQueueSample.m_nEntityIndex) & 7;
+
+ if (!hornPatternsArray[veh->m_nCarHornPattern][44 - veh->m_nCarHornTimer])
+ return TRUE;
+ }
+
+ CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance);
+ volume = veh->bIsDrowning ? 20 : 80;
+ m_sQueueSample.m_nVolume = ComputeVolume(volume, 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 = SFX_BANK_0;
+ 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;
+#ifdef FIX_BUGS
+ SET_EMITTING_VOLUME(volume);
+#else
+ SET_EMITTING_VOLUME(80);
+#endif
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
+ m_sQueueSample.m_fSpeedMultiplier = 5.0f;
+ m_sQueueSample.m_SoundIntensity = 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;
}
bool8
-cAudioManager::UsesSiren(uint32 model)
-{
- switch (model) {
- case FIRETRUK:
- case AMBULAN:
- case FBICAR:
- case POLICE:
- case ENFORCER:
- case PREDATOR:
- return TRUE;
- default:
- return FALSE;
- }
+cAudioManager::UsesSiren(cVehicleParams& params)
+{
+ return params.m_pVehicle->UsesSiren();
}
bool8
-cAudioManager::UsesSirenSwitching(uint32 model)
+cAudioManager::UsesSirenSwitching(cVehicleParams& params)
{
- switch (model) {
- case AMBULAN:
- case POLICE:
- case ENFORCER:
- case PREDATOR:
- return TRUE;
- default:
+ if (params.m_nIndex == FIRETRUK || params.m_nIndex == MRWHOOP)
return FALSE;
- }
+ return UsesSiren(params);
}
bool8
@@ -1627,57 +2629,71 @@ 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->IsAlarmOn())
+ CVehicle *veh;
+ uint8 volume;
+
+ if (params.m_fDistance >= SQR(SOUND_INTENSITY))
+ return FALSE;
+
+ veh = params.m_pVehicle;
+ if (!veh->m_bSirenOrAlarm && !veh->IsAlarmOn())
+ return TRUE;
+
+ if (veh->IsAlarmOn()) {
+ if (CTimer::GetTimeInMilliseconds() > veh->m_nCarHornTimer)
+ veh->m_nCarHornTimer = CTimer::GetTimeInMilliseconds() + 750;
+
+ if (veh->m_nCarHornTimer < CTimer::GetTimeInMilliseconds() + 375)
return TRUE;
+ }
- 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 TRUE;
- 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;
- }
+ CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance);
+ volume = veh->bIsDrowning ? 20 : 80;
+ m_sQueueSample.m_nVolume = ComputeVolume(volume, SOUND_INTENSITY, m_sQueueSample.m_fDistance);
+ if (m_sQueueSample.m_nVolume != 0) {
+ m_sQueueSample.m_nCounter = 5;
+ if (UsesSiren(params)) {
+ if (params.m_pVehicle->GetStatus() == STATUS_ABANDONED)
+ return TRUE;
+ if (veh->m_nCarHornTimer != 0 && params.m_nIndex != FIRETRUK && params.m_nIndex != MRWHOOP) {
+ m_sQueueSample.m_nSampleIndex = SFX_SIREN_FAST;
+ if (params.m_nIndex == FBIRANCH)
+ m_sQueueSample.m_nFrequency = 12668;
+ else
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_SIREN_FAST);
+ m_sQueueSample.m_nCounter = 60;
+ } else if (params.m_nIndex == VICECHEE) {
+ m_sQueueSample.m_nSampleIndex = SFX_POLICE_SIREN_SLOW;
+ m_sQueueSample.m_nFrequency = 11440;
} 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 = SFX_BANK_0;
- m_sQueueSample.m_bIs2D = FALSE;
- m_sQueueSample.m_nReleasingVolumeModificator = 1;
- m_sQueueSample.m_nLoopCount = 0;
- SET_EMITTING_VOLUME(80);
- SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
- m_sQueueSample.m_fSpeedMultiplier = 7.0f;
- m_sQueueSample.m_SoundIntensity = SOUND_INTENSITY;
- m_sQueueSample.m_bReleasingSoundFlag = FALSE;
- m_sQueueSample.m_nReleasingVolumeDivider = 5;
- m_sQueueSample.m_bReverbFlag = TRUE;
- m_sQueueSample.m_bRequireReflection = FALSE;
- AddSampleToRequestedQueue();
- return TRUE;
- } else
- return TRUE;
- } else
- return FALSE;
+ } else {
+ m_sQueueSample.m_nSampleIndex = aVehicleSettings[params.m_nIndex].m_nHornSample;
+ m_sQueueSample.m_nFrequency = aVehicleSettings[params.m_nIndex].m_nHornFrequency;
+ }
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_nReleasingVolumeModificator = 1;
+ m_sQueueSample.m_nLoopCount = 0;
+ SET_EMITTING_VOLUME(volume);
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
+ m_sQueueSample.m_fSpeedMultiplier = 7.0f;
+ m_sQueueSample.m_SoundIntensity = SOUND_INTENSITY;
+ m_sQueueSample.m_bReleasingSoundFlag = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 5;
+ m_sQueueSample.m_bReverbFlag = TRUE;
+ m_sQueueSample.m_bRequireReflection = FALSE;
+ AddSampleToRequestedQueue();
+ }
+ return TRUE;
}
bool8
cAudioManager::UsesReverseWarning(uint32 model)
{
- return model == LINERUN || model == FIRETRUK || model == TRASH || model == BUS || model == COACH;
+ return model == LINERUN || model == FIRETRUK || model == BUS || model == COACH || model == PACKER || model == FLATBED;
}
bool8
@@ -1686,13 +2702,15 @@ cAudioManager::ProcessVehicleReverseWarning(cVehicleParams& params)
const float SOUND_INTENSITY = 50.0f;
CVehicle *veh = params.m_pVehicle;
+ uint8 volume;
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);
+ volume = veh->bIsDrowning ? 15 : 60;
+ m_sQueueSample.m_nVolume = ComputeVolume(volume, SOUND_INTENSITY, m_sQueueSample.m_fDistance);
if (m_sQueueSample.m_nVolume != 0) {
m_sQueueSample.m_nCounter = 12;
m_sQueueSample.m_nSampleIndex = SFX_REVERSE_WARNING;
@@ -1701,7 +2719,11 @@ cAudioManager::ProcessVehicleReverseWarning(cVehicleParams& params)
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;
+#ifdef FIX_BUGS
+ SET_EMITTING_VOLUME(volume);
+#else
SET_EMITTING_VOLUME(60);
+#endif
SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
m_sQueueSample.m_fSpeedMultiplier = 3.0f;
m_sQueueSample.m_SoundIntensity = SOUND_INTENSITY;
@@ -1736,7 +2758,7 @@ cAudioManager::ProcessVehicleDoors(cVehicleParams& params)
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);
+ emittingVol = (100.0f * velocity * 10.0f / 3.0f);
m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance);
if (m_sQueueSample.m_nVolume != 0) {
m_sQueueSample.m_nCounter = i + 6;
@@ -1765,10 +2787,11 @@ cAudioManager::ProcessVehicleDoors(cVehicleParams& params)
bool8
cAudioManager::ProcessAirBrakes(cVehicleParams& params)
{
+ const float SOUND_INTENSITY = 30.0f;
CAutomobile *automobile;
- uint8 rand;
+ uint8 volume;
- if (params.m_fDistance > SQR(30))
+ if (params.m_fDistance > SQR(SOUND_INTENSITY))
return FALSE;
automobile = (CAutomobile *)params.m_pVehicle;
if (!automobile->bEngineOn)
@@ -1779,8 +2802,8 @@ cAudioManager::ProcessAirBrakes(cVehicleParams& params)
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);
+ volume = m_anRandomTable[0] % 10 + 70;
+ m_sQueueSample.m_nVolume = ComputeVolume(volume, SOUND_INTENSITY, m_sQueueSample.m_fDistance);
if (m_sQueueSample.m_nVolume != 0) {
m_sQueueSample.m_nCounter = 13;
m_sQueueSample.m_nSampleIndex = SFX_AIR_BRAKES;
@@ -1790,10 +2813,10 @@ cAudioManager::ProcessAirBrakes(cVehicleParams& params)
m_sQueueSample.m_bIs2D = FALSE;
m_sQueueSample.m_nReleasingVolumeModificator = 10;
m_sQueueSample.m_nLoopCount = 1;
- SET_EMITTING_VOLUME(rand);
+ SET_EMITTING_VOLUME(volume);
RESET_LOOP_OFFSETS
m_sQueueSample.m_fSpeedMultiplier = 0.0f;
- m_sQueueSample.m_SoundIntensity = 30.0f;
+ m_sQueueSample.m_SoundIntensity = SOUND_INTENSITY;
m_sQueueSample.m_bReleasingSoundFlag = TRUE;
m_sQueueSample.m_bReverbFlag = TRUE;
m_sQueueSample.m_bRequireReflection = FALSE;
@@ -1806,38 +2829,41 @@ cAudioManager::ProcessAirBrakes(cVehicleParams& params)
bool8
cAudioManager::HasAirBrakes(uint32 model)
{
- return model == LINERUN || model == FIRETRUK || model == TRASH || model == BUS || model == COACH;
+ return model == LINERUN || model == FIRETRUK || model == TRASH || model == BUS || model == BARRACKS
+ || model == COACH || model == PACKER || model == FLATBED;
}
bool8
cAudioManager::ProcessEngineDamage(cVehicleParams& params)
{
- const int engineDamageIntensity = 40;
+ const float SOUND_INTENSITY = 40.0f;
- CAutomobile *veh;
- uint8 engineStatus;
+ float health;
uint8 emittingVolume;
- if (params.m_fDistance >= SQR(engineDamageIntensity))
+ if (params.m_fDistance >= SQR(SOUND_INTENSITY))
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 {
+ if (params.m_pVehicle->m_modelIndex == MI_CADDY)
+ return TRUE;
+ if (params.m_pVehicle->GetStatus() == STATUS_WRECKED)
+ return TRUE;
+ health = params.m_pVehicle->m_fHealth;
+ if (health < 390.0f) {
+ if (health < 250.0f) {
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);
+ } else {
+ emittingVolume = 30;
+ m_sQueueSample.m_nSampleIndex = SFX_PALM_TREE_LO;
+ m_sQueueSample.m_nReleasingVolumeModificator = 7;
+ m_sQueueSample.m_nFrequency = 27000;
}
CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance);
- m_sQueueSample.m_nVolume = ComputeVolume(emittingVolume, engineDamageIntensity, m_sQueueSample.m_fDistance);
+ if (params.m_pVehicle->bIsDrowning)
+ emittingVolume /= 2;
+ m_sQueueSample.m_nVolume = ComputeVolume(emittingVolume, SOUND_INTENSITY, m_sQueueSample.m_fDistance);
if (m_sQueueSample.m_nVolume != 0) {
m_sQueueSample.m_nCounter = 28;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
@@ -1846,7 +2872,7 @@ cAudioManager::ProcessEngineDamage(cVehicleParams& params)
SET_EMITTING_VOLUME(emittingVolume);
SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
m_sQueueSample.m_fSpeedMultiplier = 2.0f;
- m_sQueueSample.m_SoundIntensity = engineDamageIntensity;
+ m_sQueueSample.m_SoundIntensity = SOUND_INTENSITY;
m_sQueueSample.m_bReleasingSoundFlag = FALSE;
m_sQueueSample.m_nReleasingVolumeDivider = 3;
m_sQueueSample.m_bReverbFlag = TRUE;
@@ -1860,31 +2886,47 @@ cAudioManager::ProcessEngineDamage(cVehicleParams& params)
bool8
cAudioManager::ProcessCarBombTick(cVehicleParams& params)
{
- CAutomobile *automobile;
+ const float SOUND_INTENSITY = 40.0f;
+ const uint8 EMITTING_VOLUME = 60;
- if (params.m_fDistance >= SQR(40.f))
+ uint8 bombType;
+
+ if (params.m_fDistance >= SQR(SOUND_INTENSITY))
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 = SFX_BANK_0;
- m_sQueueSample.m_bIs2D = FALSE;
- m_sQueueSample.m_nReleasingVolumeModificator = 0;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_COUNTDOWN);
- m_sQueueSample.m_nLoopCount = 0;
- SET_EMITTING_VOLUME(60);
- SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
- m_sQueueSample.m_fSpeedMultiplier = 2.0f;
- m_sQueueSample.m_SoundIntensity = 40.0f;
- m_sQueueSample.m_bReleasingSoundFlag = FALSE;
- m_sQueueSample.m_nReleasingVolumeDivider = 3;
- m_sQueueSample.m_bReverbFlag = TRUE;
- m_sQueueSample.m_bRequireReflection = FALSE;
- AddSampleToRequestedQueue();
+ if (params.m_pVehicle->bEngineOn) {
+ switch (params.m_VehicleType) {
+ case VEHICLE_TYPE_CAR:
+ bombType = params.m_pVehicle->m_bombType;
+ break;
+ case VEHICLE_TYPE_BIKE:
+ bombType = params.m_pVehicle->m_bombType;
+ break;
+ default:
+ debug("\n * AUDIOLOG: ProcessCarBombTick() Unsupported vehicle type %d * \n", params.m_VehicleType);
+ return TRUE;
+ break;
+ }
+ if (bombType == CARBOMB_TIMEDACTIVE) {
+ CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance);
+ m_sQueueSample.m_nVolume = ComputeVolume(EMITTING_VOLUME, SOUND_INTENSITY, 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 = SFX_BANK_0;
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_nReleasingVolumeModificator = 0;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_COUNTDOWN);
+ m_sQueueSample.m_nLoopCount = 0;
+ SET_EMITTING_VOLUME(EMITTING_VOLUME);
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
+ m_sQueueSample.m_SoundIntensity = 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;
@@ -1898,15 +2940,13 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams& params)
float relVol;
float vol;
bool8 noReflections;
+ bool8 isHeli;
float maxDist;
-
- static uint8 WaveIndex = 41;
static uint8 GunIndex = 53;
- static uint8 iWheelIndex = 82;
- static uint8 CrunchOffset = 0;
for (uint16 i = 0; i < m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_AudioEvents; i++) {
noReflections = FALSE;
+ isHeli = FALSE;
m_sQueueSample.m_bRequireReflection = FALSE;
event = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i];
switch (event) {
@@ -1942,7 +2982,10 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams& params)
#else
m_sQueueSample.m_nCounter = event + 22;
#endif
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
+ if (params.m_pVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI)
+ m_sQueueSample.m_nFrequency = 28062;
+ else
+ 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;
@@ -1963,16 +3006,15 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams& params)
case OLD_DOOR:
m_sQueueSample.m_nSampleIndex = SFX_OLD_CAR_DOOR_OPEN;
break;
- case NEW_DOOR:
- default:
- m_sQueueSample.m_nSampleIndex = SFX_NEW_CAR_DOOR_OPEN;
- break;
case TRUCK_DOOR:
m_sQueueSample.m_nSampleIndex = SFX_TRUCK_DOOR_OPEN;
break;
case BUS_DOOR:
m_sQueueSample.m_nSampleIndex = SFX_AIR_BRAKES;
break;
+ default:
+ m_sQueueSample.m_nSampleIndex = SFX_NEW_CAR_DOOR_OPEN;
+ break;
}
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
#ifdef THIS_IS_STUPID
@@ -1980,7 +3022,10 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams& params)
#else
m_sQueueSample.m_nCounter = event + 10;
#endif
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
+ if (params.m_pVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI)
+ m_sQueueSample.m_nFrequency = 23459;
+ else
+ 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;
@@ -1989,39 +3034,68 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams& params)
break;
}
case SOUND_CAR_WINDSHIELD_CRACK: {
- const float SOUND_INTENSITY = 30.0f;
+ const float SOUND_INTENSITY = 40.0f;
maxDist = SQR(SOUND_INTENSITY);
m_sQueueSample.m_nSampleIndex = SFX_GLASS_CRACK;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_nCounter = 68;
- emittingVol = m_anRandomTable[1] % 30 + 60;
+ emittingVol = m_anRandomTable[1] % 30 + 80;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_GLASS_CRACK);
m_sQueueSample.m_nReleasingVolumeModificator = 5;
m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_SoundIntensity = SOUND_INTENSITY;
} break;
- case SOUND_CAR_JUMP: {
+ case SOUND_CAR_JUMP:
+ case SOUND_CAR_JUMP_2: {
const float SOUND_INTENSITY = 35.0f;
- emittingVol = Max(80.f, 2 * (100.f * m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]));
+ static uint8 WheelIndex = 82;
maxDist = SQR(SOUND_INTENSITY);
- m_sQueueSample.m_nSampleIndex = SFX_TYRE_BUMP;
+#ifdef THIS_IS_STUPID
+ if (m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i] == SOUND_CAR_JUMP_2) {
+#else
+ if (event == SOUND_CAR_JUMP_2) {
+#endif
+ m_sQueueSample.m_nSampleIndex = SFX_TYRE_BURST_B;
+ emittingVol = Max(50.0f, 2 * (60.0f * m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]));
+ } else {
+ m_sQueueSample.m_nSampleIndex = SFX_TYRE_BUMP;
+ emittingVol = Max(80.f, 2 * (100.0f * m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]));
+ }
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
- m_sQueueSample.m_nCounter = iWheelIndex++;
- if (iWheelIndex > 85)
- iWheelIndex = 82;
+ m_sQueueSample.m_nCounter = WheelIndex++;
+ if (WheelIndex > 85)
+ WheelIndex = 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) {
+ if (params.m_VehicleType == VEHICLE_TYPE_BIKE)
m_sQueueSample.m_nFrequency *= 2;
- emittingVol /= 2;
- }
m_sQueueSample.m_nReleasingVolumeModificator = 6;
m_sQueueSample.m_fSpeedMultiplier = 2.0f;
m_sQueueSample.m_SoundIntensity = SOUND_INTENSITY;
break;
}
+ case SOUND_CAR_TYRE_POP: {
+ const float SOUND_INTENSITY = 60.0f;
+ static uint8 WheelIndex = 91;
+ m_sQueueSample.m_nSampleIndex = SFX_TYRE_BURST;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nCounter = WheelIndex++;
+ if (WheelIndex > 94)
+ WheelIndex = 91;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_TYRE_BURST);
+ m_sQueueSample.m_nFrequency += RandomDisplacement(2000);
+ m_sQueueSample.m_nReleasingVolumeModificator = 2;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_SoundIntensity = SOUND_INTENSITY;
+ maxDist = SQR(SOUND_INTENSITY);
+ emittingVol = m_anRandomTable[4] % 10 + 117;
+ break;
+ }
case SOUND_CAR_ENGINE_START: {
const float SOUND_INTENSITY = 40.0f;
+ if (params.m_pVehicle->GetVehicleAppearance() != VEHICLE_APPEARANCE_CAR
+ || params.m_pVehicle->m_modelIndex == MI_CADDY)
+ continue;
emittingVol = 60;
maxDist = SQR(SOUND_INTENSITY);
m_sQueueSample.m_nSampleIndex = SFX_CAR_STARTER;
@@ -2096,27 +3170,28 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams& params)
break;
}
case SOUND_CAR_SPLASH: {
- const float SOUND_INTENSITY = 40.0f;
+ const float SOUND_INTENSITY = 60.0f;
+ static uint8 WaveIndex = 41;
vol = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i];
- if (vol <= 300.f)
+ if (vol <= 150.0f)
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;
+ if (vol > 800.0f)
+ m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i] = 800.0f;
+ relVol = (m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i] - 150.0f) / 650.0f;
m_sQueueSample.m_nSampleIndex = (m_anRandomTable[0] & 1) + SFX_BOAT_SPLASH_1;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_nCounter = WaveIndex++;
if (WaveIndex > 46)
WaveIndex = 41;
- m_sQueueSample.m_nFrequency = (7000.f * relVol) + 6000;
+ m_sQueueSample.m_nFrequency = (7000.0f * relVol) + 6000;
m_sQueueSample.m_nReleasingVolumeModificator = 3;
m_sQueueSample.m_fSpeedMultiplier = 2.0f;
m_sQueueSample.m_SoundIntensity = SOUND_INTENSITY;
- emittingVol = (55.f * relVol);
+ emittingVol = (35.0f * relVol);
maxDist = SQR(SOUND_INTENSITY);
break;
}
- case SOUND_BOAT_SLOWDOWN: {
+ /*case SOUND_17: {
const float SOUND_INTENSITY = 50.0f;
m_sQueueSample.m_nSampleIndex = SFX_POLICE_BOAT_THUMB_OFF;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
@@ -2124,11 +3199,12 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams& params)
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_SoundIntensity = SOUND_INTENSITY;
+ m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
emittingVol = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i];
maxDist = SQR(SOUND_INTENSITY);
break;
- }
+ }*/
+#ifdef GTA_TRAIN
case SOUND_TRAIN_DOOR_CLOSE:
case SOUND_TRAIN_DOOR_OPEN: {
const float SOUND_INTENSITY = 35.0f;
@@ -2143,20 +3219,21 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams& params)
emittingVol = m_anRandomTable[1] % 20 + 70;
break;
}
+#endif
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;
+ if (vol > 24.0f / 625.0f)
+ vol = 24.0f / 625.0f;
m_sQueueSample.m_nSampleIndex = SFX_TANK_TURRET;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_nCounter = 79;
- m_sQueueSample.m_nFrequency = (3000.f * vol * 2500.0f / 96.0f) + 9000;
+ m_sQueueSample.m_nFrequency = (3000.0f * vol * 625.0f / 24.0f) + 9000;
m_sQueueSample.m_nReleasingVolumeModificator = 2;
m_sQueueSample.m_fSpeedMultiplier = 2.0f;
m_sQueueSample.m_nReleasingVolumeDivider = 3;
m_sQueueSample.m_SoundIntensity = SOUND_INTENSITY;
- emittingVol = (37.f * vol * 2500.0f / 96.0f) + 90;
+ emittingVol = (37.0f * vol * 625.0f / 24.0f) + 90;
maxDist = SQR(SOUND_INTENSITY);
noReflections = TRUE;
break;
@@ -2188,23 +3265,131 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams& params)
emittingVol = m_anRandomTable[4] % 25 + 75;
break;
}
- case SOUND_WEAPON_SHOT_FIRED: {
- const float SOUND_INTENSITY = 120.0f;
- emittingVol = m_anRandomTable[2];
+ case SOUND_HELI_BLADE:{
+ const float SOUND_INTENSITY = 35.0f;
+ static uint8 HeliIndex = 89;
+ relVol = ((CAutomobile*)params.m_pVehicle)->m_aWheelSpeed[1] * 50.0f / 11.0f;
+ if (relVol < 0.2f || relVol == 1.0f)
+ continue;
+ emittingVol = (1.0f - relVol) * 70.0f;
maxDist = SQR(SOUND_INTENSITY);
- m_sQueueSample.m_nSampleIndex = SFX_UZI_LEFT;
+ m_sQueueSample.m_nSampleIndex = SFX_CAR_HELI_ROT;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
- 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_nCounter = HeliIndex++;
+ if (HeliIndex > 90)
+ HeliIndex = 89;
+ m_sQueueSample.m_nFrequency = (8000.0f * relVol) + 16000;
+ m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32);
+ m_sQueueSample.m_nReleasingVolumeModificator = 2;
m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_SoundIntensity = SOUND_INTENSITY;
break;
}
+ case SOUND_WEAPON_SHOT_FIRED: {
+ const float SOUND_INTENSITY = 120.0f;
+ CVehicle *playerVeh;
+ CPlayerPed *playerPed;
+
+ switch (params.m_pVehicle->m_modelIndex) {
+ case MI_HUNTER:
+ case MI_CHOPPER:
+ case MI_SEASPAR:
+ case MI_SPARROW:
+ case MI_MAVERICK:
+ case MI_VCNMAV:
+ if (params.m_pVehicle->m_modelIndex == MI_HUNTER) {
+ if (Pads[0].GetHandBrake() == 0) {
+ playerVeh = FindPlayerVehicle();
+ playerPed = FindPlayerPed();
+ if (playerVeh == nil && playerPed != nil) {
+ if (playerPed->m_attachedTo != nil && playerPed->m_attachedTo->GetType() == ENTITY_TYPE_VEHICLE)
+ playerVeh = (CVehicle*)playerPed->m_attachedTo;
+ }
+ if (playerVeh != params.m_pVehicle) {
+ m_sQueueSample.m_nSampleIndex = SFX_M60_LEFT;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ } else {
+ m_sQueueSample.m_nSampleIndex = SFX_ROCKET_LEFT;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ }
+ } else {
+ m_sQueueSample.m_nSampleIndex = SFX_M60_LEFT;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ }
+ } else {
+ m_sQueueSample.m_nSampleIndex = SFX_M60_LEFT;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ }
+ maxDist = SQR(SOUND_INTENSITY);
+ m_sQueueSample.m_nCounter = GunIndex++;
+ emittingVol = MAX_VOLUME;
+ if (GunIndex > 58)
+ GunIndex = 53;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_M60_LEFT);
+ m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16);
+ m_sQueueSample.m_nReleasingVolumeModificator = 2;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_SoundIntensity = SOUND_INTENSITY;
+ m_sQueueSample.m_bRequireReflection = TRUE;
+ isHeli = TRUE;
+ break;
+ default:
+ {
+ maxDist = SQR(SOUND_INTENSITY);
+#ifdef FIX_BUGS
+ int32 sampleIndex;
+ int32 frequency;
+ CPed *pPed = params.m_pVehicle->pDriver;
+ if(!pPed)
+ break;
+ if(!pPed->HasWeaponSlot(WEAPONSLOT_SUBMACHINEGUN) || (params.m_pVehicle->GetModelIndex() == MI_PREDATOR && !pPed->IsPedDoingDriveByShooting())) {
+ sampleIndex = SFX_UZI_LEFT;
+ frequency = SampleManager.GetSampleBaseFrequency(sampleIndex);
+ frequency += RandomDisplacement(frequency / 32);
+ } else
+ switch(pPed->GetWeapon(WEAPONSLOT_SUBMACHINEGUN).m_eWeaponType) {
+ case WEAPONTYPE_TEC9:
+ sampleIndex = SFX_TEC_LEFT;
+ frequency = RandomDisplacement(500) + 17000;
+ break;
+ case WEAPONTYPE_SILENCED_INGRAM:
+ sampleIndex = SFX_TEC_LEFT;
+ frequency = RandomDisplacement(1000) + 34000;
+ break;
+ case WEAPONTYPE_MP5:
+ sampleIndex = SFX_MP5_LEFT;
+ frequency = SampleManager.GetSampleBaseFrequency(sampleIndex);
+ frequency += RandomDisplacement(frequency / 32);
+ break;
+ default:
+ sampleIndex = SFX_UZI_LEFT;
+ frequency = SampleManager.GetSampleBaseFrequency(sampleIndex);
+ frequency += RandomDisplacement(frequency / 32);
+ break;
+ }
+ m_sQueueSample.m_nSampleIndex = sampleIndex;
+#else
+ m_sQueueSample.m_nSampleIndex = SFX_UZI_LEFT;
+#endif
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nCounter = GunIndex++;
+ emittingVol = m_anRandomTable[2] % 15 + 65;
+ if(GunIndex > 58) GunIndex = 53;
+#ifdef FIX_BUGS
+ m_sQueueSample.m_nFrequency = frequency;
+#else
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_UZI_LEFT);
+ m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16);
+#endif
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_SoundIntensity = SOUND_INTENSITY;
+ m_sQueueSample.m_bRequireReflection = TRUE;
+ break;
+ }
+ }
+ 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;
@@ -2220,7 +3405,7 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams& params)
break;
}
case SOUND_BOMB_TIMED_ACTIVATED:
- case SOUND_55:
+ case SOUND_91:
case SOUND_BOMB_ONIGNITION_ACTIVATED:
case SOUND_BOMB_TICK: {
const float SOUND_INTENSITY = 50.0f;
@@ -2236,24 +3421,34 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams& params)
maxDist = SQR(SOUND_INTENSITY);
break;
}
- case SOUND_PED_HELI_PLAYER_FOUND:
- {
+ case SOUND_PED_HELI_PLAYER_FOUND: {
cPedParams pedParams;
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:
- {
+ /* 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_PED_VCPA_PLAYER_FOUND: {
cPedParams pedParams;
pedParams.m_bDistanceCalculated = params.m_bDistanceCalculated;
pedParams.m_fDistance = params.m_fDistance;
- SetupPedComments(pedParams, SOUND_PED_BODYCAST_HIT);
+ SetupPedComments(pedParams, SOUND_PED_VCPA_PLAYER_FOUND);
continue;
}
case SOUND_WATER_FALL: {
const float SOUND_INTENSITY = 40.0f;
+ static uint32 WaterFallFrame = 0;
+ if (m_FrameCounter <= WaterFallFrame)
+ continue;
+ WaterFallFrame = m_FrameCounter + 6;
m_sQueueSample.m_nSampleIndex = SFX_SPLASH_1;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_nCounter = 15;
@@ -2268,13 +3463,14 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams& params)
}
case SOUND_SPLATTER: {
const float SOUND_INTENSITY = 40.0f;
+ static uint8 CrunchOffset = 0;
m_sQueueSample.m_nSampleIndex = CrunchOffset + SFX_PED_CRUNCH_1;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_nCounter = 48;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_PED_CRUNCH_1) + RandomDisplacement(600);
+ m_sQueueSample.m_nFrequency = RandomDisplacement(6000) + 16000;
m_sQueueSample.m_nReleasingVolumeModificator = 1;
m_sQueueSample.m_fSpeedMultiplier = 0.0f;
- m_sQueueSample.m_SoundIntensity = 40.0f;
+ m_sQueueSample.m_SoundIntensity = SOUND_INTENSITY;
++CrunchOffset;
maxDist = SQR(SOUND_INTENSITY);
emittingVol = m_anRandomTable[4] % 20 + 55;
@@ -2285,14 +3481,15 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams& params)
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)
+ emittingVol = Min(127, (3 * (vol / 20.0f * 127.f)) / 2);
+ if (emittingVol == 0)
continue;
- m_sQueueSample.m_nSampleIndex = (m_anRandomTable[2] & 3) + SFX_FIGHT_1;
+ m_sQueueSample.m_nSampleIndex = SFX_FIGHT_1;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_nCounter = 50;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex) / 2;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16);
m_sQueueSample.m_nReleasingVolumeModificator = 1;
m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_SoundIntensity = SOUND_INTENSITY;
@@ -2316,13 +3513,50 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams& params)
SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
SET_EMITTING_VOLUME(emittingVol);
m_sQueueSample.m_bReverbFlag = TRUE;
+ if (isHeli) {
+ if (0.2f * m_sQueueSample.m_SoundIntensity > m_sQueueSample.m_fDistance) {
+ m_sQueueSample.m_bIs2D = TRUE;
+ m_sQueueSample.m_nOffset = 0;
+#ifdef THIS_IS_STUPID
+ goto AddSample;
+#else
+ AddSampleToRequestedQueue();
+ m_sQueueSample.m_nOffset = 127;
+ m_sQueueSample.m_nSampleIndex++;
+ m_sQueueSample.m_nCounter = GunIndex++;
+ if (GunIndex > 58)
+ GunIndex = 53;
+ m_sQueueSample.m_bRequireReflection = FALSE;
+ AddSampleToRequestedQueue();
+ continue;
+#endif
+ }
+ isHeli = FALSE;
+ }
m_sQueueSample.m_bIs2D = FALSE;
+#ifdef THIS_IS_STUPID
+AddSample:
AddSampleToRequestedQueue();
+ if (isHeli) {
+ m_sQueueSample.m_nOffset = 127;
+ m_sQueueSample.m_nSampleIndex++;
+ m_sQueueSample.m_nCounter = GunIndex++;
+ if (GunIndex > 58)
+ GunIndex = 53;
+ m_sQueueSample.m_bRequireReflection = 0;
+ AddSampleToRequestedQueue();
+ }
+#else
+ AddSampleToRequestedQueue();
+#endif
+ continue;
+
}
}
}
}
+#ifdef GTA_TRAIN
bool8
cAudioManager::ProcessTrainNoise(cVehicleParams& params)
{
@@ -2386,31 +3620,133 @@ cAudioManager::ProcessTrainNoise(cVehicleParams& params)
}
return TRUE;
}
-
+#endif
bool8
cAudioManager::ProcessBoatEngine(cVehicleParams& params)
{
CBoat *boat;
float padRelativeAccerate;
- float gasPedal;
- float padAccelerate;
- uint8 emittingVol;
- float oneShotVol;
- static uint16 LastAccel = 0;
- static uint8 LastVol = 0;
+ bool8 isV12 = FALSE;
+ static int32 LastFreq = 2000;
+ static int8 LastVol = 0;
- static const float intensity = 50.0f;
+ static const float intensity = 90.0f;
if (params.m_fDistance < SQR(intensity)) {
boat = (CBoat *)params.m_pVehicle;
- if (params.m_nIndex == REEFER) {
+ if(boat->GetStatus() == STATUS_WRECKED)
+ return TRUE;
+
+ float freqModificator;
+ float volModificator;
+ int BaseVol;
+ int BaseFreq;
+
+ switch(boat->GetModelIndex()) {
+ case MI_RIO:
+ freqModificator = 490.0f;
+ volModificator = 60.0f;
+ BaseVol = 20;
+ BaseFreq = 1888;
+ break;
+ case MI_PREDATOR:
+ case MI_SQUALO:
+ case MI_SPEEDER:
+ case MI_COASTG:
+ case MI_DINGHY:
+ case MI_JETMAX:
+ freqModificator = 6000.0f;
+ volModificator = 60.0f;
+ isV12 = TRUE;
+ BaseFreq = 9000;
+ BaseVol = 20;
+ break;
+ case MI_REEFER:
+ freqModificator = 715.0f;
+ volModificator = 80.0f;
+ BaseVol = 0;
+ BaseFreq = 3775;
+ break;
+ case MI_TROPIC:
+ case MI_MARQUIS:
+ freqModificator = 463.0f;
+ volModificator = 60.0f;
+ BaseVol = 20;
+ BaseFreq = 1782;
+ break;
+ default:
+ return TRUE;
+ }
+
+ bool8 bIsPlayerVeh;
+
+ if(FindPlayerVehicle() == params.m_pVehicle) {
+ float padAccelerate = Max(Pads[0].GetAccelerate(), Pads[0].GetBrake());
+ padRelativeAccerate = padAccelerate / 255.0f;
+ bIsPlayerVeh = TRUE;
+ } else {
+ padRelativeAccerate = Max(params.m_pVehicle->m_fGasPedal, params.m_pVehicle->m_fBrakePedal);
+ bIsPlayerVeh = FALSE;
+ }
+
+ int Freq = BaseFreq + (padRelativeAccerate * freqModificator);
+ int Vol = BaseVol + (padRelativeAccerate * volModificator);
+
+ if(!boat->bPropellerInWater)
+ Freq = (9 * Freq) / 8;
+
+ if(bIsPlayerVeh) {
+ if(Freq > LastFreq) {
+ if(isV12)
+ Freq = Min(Freq, LastFreq + 100);
+ else
+ Freq = Min(Freq, LastFreq + 15);
+ } else {
+ if(isV12)
+ Freq = Max(Freq, LastFreq - 100);
+ else
+ Freq = Max(Freq, LastFreq - 15);
+ }
+ if(Vol > LastVol)
+ Vol = Min(Vol, LastVol + 3);
+ else
+ Vol = Max(Vol, LastVol - 3);
+ }
+
+ if (Vol > 0) {
+ CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance);
+ m_sQueueSample.m_nVolume = ComputeVolume(Vol, intensity, m_sQueueSample.m_fDistance);
+ if (m_sQueueSample.m_nVolume != 0) {
+ m_sQueueSample.m_nFrequency = Freq;
+ m_sQueueSample.m_nCounter = 40;
+ if (isV12)
+ m_sQueueSample.m_nSampleIndex = SFX_BOAT_V12_LOOP;
+ else
+ m_sQueueSample.m_nSampleIndex = SFX_BOAT_CRUISER_LOOP;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nLoopCount = 0;
+ SET_EMITTING_VOLUME(Vol);
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
+ m_sQueueSample.m_SoundIntensity = intensity;
+ m_sQueueSample.m_bReleasingSoundFlag = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 7;
+ m_sQueueSample.m_bReverbFlag = TRUE;
+ m_sQueueSample.m_bRequireReflection = FALSE;
+ AddSampleToRequestedQueue();
+ }
+ }
+
+ if(boat->GetModelIndex() == MI_REEFER) {
CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance);
m_sQueueSample.m_nVolume = ComputeVolume(80, intensity, m_sQueueSample.m_fDistance);
if (m_sQueueSample.m_nVolume != 0) {
+ m_sQueueSample.m_nFrequency = 6000;
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 = SFX_BANK_0;
m_sQueueSample.m_bIs2D = FALSE;
@@ -2426,100 +3762,11 @@ cAudioManager::ProcessBoatEngine(cVehicleParams& params)
m_sQueueSample.m_bRequireReflection = FALSE;
AddSampleToRequestedQueue();
}
- if (FindPlayerVehicle() == params.m_pVehicle) {
- padAccelerate = Max(Pads[0].GetAccelerate(), Pads[0].GetBrake());
- padRelativeAccerate = padAccelerate / 255.0f;
- emittingVol = (100.f * padRelativeAccerate) + 15;
- m_sQueueSample.m_nFrequency = (3000.f * padRelativeAccerate) + 6000;
- if (!boat->bPropellerInWater)
- 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->bPropellerInWater)
- m_sQueueSample.m_nFrequency = 11 * m_sQueueSample.m_nFrequency / 10;
- }
- }
- m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, intensity, 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 = SFX_BANK_0;
- m_sQueueSample.m_bIs2D = FALSE;
- m_sQueueSample.m_nReleasingVolumeModificator = 3;
- m_sQueueSample.m_nLoopCount = 0;
- SET_EMITTING_VOLUME(emittingVol);
- SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
- m_sQueueSample.m_fSpeedMultiplier = 2.0f;
- m_sQueueSample.m_SoundIntensity = 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) {
- padAccelerate = Max(Pads[0].GetAccelerate(), Pads[0].GetBrake());
- 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_BOAT_SLOWDOWN, 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, intensity, 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 = SFX_BANK_0;
- m_sQueueSample.m_bIs2D = FALSE;
- m_sQueueSample.m_nReleasingVolumeModificator = 3;
- m_sQueueSample.m_nLoopCount = 0;
- SET_EMITTING_VOLUME(emittingVol);
- SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
- m_sQueueSample.m_fSpeedMultiplier = 2.0f;
- m_sQueueSample.m_SoundIntensity = intensity;
- m_sQueueSample.m_bReleasingSoundFlag = FALSE;
- m_sQueueSample.m_nReleasingVolumeDivider = 7;
- m_sQueueSample.m_bReverbFlag = TRUE;
- m_sQueueSample.m_bRequireReflection = FALSE;
}
- AddSampleToRequestedQueue();
+ if(bIsPlayerVeh) {
+ LastFreq = Freq;
+ LastVol = Vol;
+ }
return TRUE;
}
return FALSE;
@@ -2557,7 +3804,7 @@ cAudioManager::ProcessBoatMovingOverWater(cVehicleParams& params)
m_sQueueSample.m_fSpeedMultiplier = 2.0f;
m_sQueueSample.m_SoundIntensity = 50.0f;
m_sQueueSample.m_bReleasingSoundFlag = FALSE;
- m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 6;
m_sQueueSample.m_bReverbFlag = TRUE;
m_sQueueSample.m_bRequireReflection = FALSE;
AddSampleToRequestedQueue();
@@ -2566,61 +3813,6 @@ cAudioManager::ProcessBoatMovingOverWater(cVehicleParams& params)
return TRUE;
}
-struct tHelicopterSampleData {
- float m_fMaxDistance;
- float m_fBaseDistance;
- uint8 m_bBaseVolume;
-};
-
-bool8
-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 = SFX_BANK_0;
- 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;
- SET_EMITTING_VOLUME(emittingVol);
- SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
- m_sQueueSample.m_fSpeedMultiplier = 6.0f;
- m_sQueueSample.m_SoundIntensity = 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)
{
@@ -2632,7 +3824,6 @@ cAudioManager::ProcessPlane(cVehicleParams& params)
ProcessCesna(params);
break;
default:
- debug("Plane Model Id is %d\n, ", params.m_pVehicle->GetModelIndex());
break;
}
}
@@ -2653,33 +3844,29 @@ 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.103344f) {
- ProcessJumboTaxi();
- return;
- }
+ if (params.m_fDistance >= SQR(440))
+ return;
+ 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.103344f) {
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.103344f) {
- ProcessJumboDecel(plane);
- return;
- }
- ProcessJumboTaxi();
- return;
- }
- ProcessJumboLanding(plane);
+ ProcessJumboTaxi();
}
+ } else if (position <= TakeOffPoint + 300.0f) {
+ ProcessJumboTakeOff(plane);
+ } else if (position <= LandingPoint - 350.0f) {
+ ProcessJumboFlying();
+ } else if (position <= LandingPoint) {
+ ProcessJumboLanding(plane);
+ } else if (plane->m_fSpeed > 0.103344f) {
+ ProcessJumboDecel(plane);
+ } else {
+ ProcessJumboTaxi();
}
}
@@ -2697,25 +3884,23 @@ cAudioManager::ProcessJumboAccel(CPlane *plane)
{
int32 engineFreq;
int32 vol;
- float whineSoundFreq;
float modificator;
+ float freqModifier;
if (SetupJumboFlySound(20)) {
- modificator = (plane->m_fSpeed - 0.103344f) * 1.6760077f;
- if (modificator > 1.0f)
- modificator = 1.0f;
+ modificator = Min(1.0f, (plane->m_fSpeed - 0.103344f) * 1.6760077f);
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;
+ freqModifier = modificator * 5.0f;
+ vol = MAX_VOLUME * freqModifier;
+ engineFreq = 6050.0f * freqModifier + 16000;
} else {
- whineSoundFreq = 44100;
+ freqModifier = 1.0f;
engineFreq = 22050;
vol = MAX_VOLUME;
}
SetupJumboEngineSound(vol, engineFreq);
- SetupJumboWhineSound(18, whineSoundFreq);
+ SetupJumboWhineSound(18, 14600.0f * freqModifier + 29500);
}
}
}
@@ -2859,12 +4044,11 @@ bool8
cAudioManager::SetupJumboFlySound(uint8 emittingVol)
{
const float SOUND_INTENSITY = 440.0f;
- if (m_sQueueSample.m_fDistance >= SOUND_INTENSITY)
- return FALSE;
+ 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) {
+ if(m_sQueueSample.m_nVolume != 0) {
m_sQueueSample.m_nCounter = 0;
m_sQueueSample.m_nSampleIndex = SFX_JUMBO_DIST_FLY;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
@@ -2879,7 +4063,7 @@ cAudioManager::SetupJumboFlySound(uint8 emittingVol)
m_sQueueSample.m_bReleasingSoundFlag = FALSE;
m_sQueueSample.m_nReleasingVolumeDivider = 5;
m_sQueueSample.m_bReverbFlag = TRUE;
- m_sQueueSample.m_bRequireReflection = FALSE;
+ m_sQueueSample.m_bRequireReflection = FALSE; // todo port fix to re3
AddSampleToRequestedQueue();
}
return TRUE;
@@ -2924,7 +4108,7 @@ cAudioManager::SetupJumboRumbleSound(uint8 emittingVol)
int32
cAudioManager::GetJumboTaxiFreq()
{
- return (60.833f * m_sQueueSample.m_fDistance) + 22050;
+ return (1.f / 180 * 10950 * m_sQueueSample.m_fDistance) + 22050; // todo port fix to re3
}
#pragma endregion Some jumbo crap
@@ -2942,62 +4126,10 @@ cAudioManager::ProcessPed(CPhysical *ped)
params.m_bDistanceCalculated = FALSE;
params.m_pPed = (CPed *)ped;
params.m_fDistance = GetDistanceSquared(m_sQueueSample.m_vecPos);
- if (ped->GetModelIndex() == MI_FATMALE02)
- ProcessPedHeadphones(params);
ProcessPedOneShots(params);
}
void
-cAudioManager::ProcessPedHeadphones(cPedParams &params)
-{
- CPed *ped;
- CAutomobile *veh;
- uint8 emittingVol;
-
- if (params.m_fDistance < SQR(7)) {
- 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 = DOOR_FRONT_LEFT; 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 != 0) {
- m_sQueueSample.m_nCounter = 64;
- m_sQueueSample.m_nSampleIndex = SFX_HEADPHONES;
- m_sQueueSample.m_nBankIndex = SFX_BANK_0;
- m_sQueueSample.m_bIs2D = FALSE;
- m_sQueueSample.m_nReleasingVolumeModificator = 5;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_HEADPHONES);
- m_sQueueSample.m_nLoopCount = 0;
- SET_EMITTING_VOLUME(emittingVol);
- SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
- m_sQueueSample.m_fSpeedMultiplier = 4.0f;
- m_sQueueSample.m_SoundIntensity = 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;
@@ -3012,6 +4144,7 @@ cAudioManager::ProcessPedOneShots(cPedParams &params)
float maxDist = 0.f; // uninitialized variable
static uint8 iSound = 21;
+ static uint32 iSplashFrame = 0;
weapon = params.m_pPed->GetWeapon();
for (uint32 i = 0; i < m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_AudioEvents; i++) {
@@ -3124,54 +4257,85 @@ cAudioManager::ProcessPedOneShots(cPedParams &params)
m_sQueueSample.m_bReleasingSoundFlag = TRUE;
m_sQueueSample.m_bRequireReflection = TRUE;
break;
- case SOUND_FIGHT_PUNCH_33:
+ case SOUND_FIGHT_37:
m_sQueueSample.m_nSampleIndex = SFX_FIGHT_1;
m_sQueueSample.m_nFrequency = 18000;
goto AddFightSound;
- case SOUND_FIGHT_KICK_34:
+ case SOUND_FIGHT_38:
m_sQueueSample.m_nSampleIndex = SFX_FIGHT_1;
m_sQueueSample.m_nFrequency = 16500;
goto AddFightSound;
- case SOUND_FIGHT_HEADBUTT_35:
+ case SOUND_FIGHT_39:
m_sQueueSample.m_nSampleIndex = SFX_FIGHT_1;
m_sQueueSample.m_nFrequency = 20000;
goto AddFightSound;
- case SOUND_FIGHT_PUNCH_36:
+ case SOUND_FIGHT_40:
+ case SOUND_186:
m_sQueueSample.m_nSampleIndex = SFX_FIGHT_2;
m_sQueueSample.m_nFrequency = 18000;
goto AddFightSound;
- case SOUND_FIGHT_PUNCH_37:
+ case SOUND_FIGHT_41:
m_sQueueSample.m_nSampleIndex = SFX_FIGHT_2;
m_sQueueSample.m_nFrequency = 16500;
goto AddFightSound;
- case SOUND_FIGHT_CLOSE_PUNCH_38:
+ case SOUND_FIGHT_42:
m_sQueueSample.m_nSampleIndex = SFX_FIGHT_2;
m_sQueueSample.m_nFrequency = 20000;
goto AddFightSound;
- case SOUND_FIGHT_PUNCH_39:
+ case SOUND_FIGHT_43:
m_sQueueSample.m_nSampleIndex = SFX_FIGHT_4;
m_sQueueSample.m_nFrequency = 18000;
goto AddFightSound;
- case SOUND_FIGHT_PUNCH_OR_KICK_BELOW_40:
+ case SOUND_FIGHT_44:
m_sQueueSample.m_nSampleIndex = SFX_FIGHT_4;
m_sQueueSample.m_nFrequency = 16500;
goto AddFightSound;
- case SOUND_FIGHT_PUNCH_41:
+ case SOUND_FIGHT_45:
m_sQueueSample.m_nSampleIndex = SFX_FIGHT_4;
m_sQueueSample.m_nFrequency = 20000;
goto AddFightSound;
- case SOUND_FIGHT_PUNCH_FROM_BEHIND_42:
+ case SOUND_FIGHT_46:
+ case SOUND_187:
m_sQueueSample.m_nSampleIndex = SFX_FIGHT_5;
m_sQueueSample.m_nFrequency = 18000;
goto AddFightSound;
- case SOUND_FIGHT_KNEE_OR_KICK_43:
+ case SOUND_FIGHT_47:
m_sQueueSample.m_nSampleIndex = SFX_FIGHT_5;
m_sQueueSample.m_nFrequency = 16500;
goto AddFightSound;
- case SOUND_FIGHT_KICK_44:
+ case SOUND_FIGHT_48:
m_sQueueSample.m_nSampleIndex = SFX_FIGHT_5;
m_sQueueSample.m_nFrequency = 20000;
AddFightSound:
+ {
+ uint32 soundParams = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; // wtf? storing int as float
+ uint8 damagerType = soundParams & 0xFF;
+ uint32 weaponType = soundParams >> 8;
+
+ if (damagerType == ENTITY_TYPE_PED) {
+ if (weaponType == WEAPONTYPE_BRASSKNUCKLE) {
+ CPed* ped = params.m_pPed;
+ uint32 fightMove = ped->m_curFightMove;
+ if (fightMove == FIGHTMOVE_BACKLEFT || fightMove == FIGHTMOVE_STDPUNCH || fightMove == FIGHTMOVE_PUNCH ||
+ ped->m_nPedState == PED_ATTACK) {
+ CEntity* damageEntity = ped->m_pDamageEntity;
+ if (!damageEntity)
+ m_sQueueSample.m_nSampleIndex = m_anRandomTable[3] % 2 + SFX_HAMMER_HIT_1;
+ else if (damageEntity->GetType() != ENTITY_TYPE_PED)
+ m_sQueueSample.m_nSampleIndex = m_anRandomTable[3] % 2 + SFX_HAMMER_HIT_1;
+ else if (((CPed*)damageEntity)->m_curFightMove != FIGHTMOVE_HITHEAD)
+ m_sQueueSample.m_nSampleIndex = m_anRandomTable[3] % 2 + SFX_HAMMER_HIT_1;
+ else
+ m_sQueueSample.m_nSampleIndex = SFX_HAMMER_HIT_1;
+ }
+ }
+ }
+ else {
+ m_sQueueSample.m_nSampleIndex = m_anRandomTable[4] % 6 + SFX_COL_CAR_PANEL_1;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16);
+ }
+ }
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_nCounter = iSound;
narrowSoundRange = TRUE;
@@ -3189,11 +4353,48 @@ cAudioManager::ProcessPedOneShots(cPedParams &params)
m_sQueueSample.m_bRequireReflection = TRUE;
break;
case SOUND_WEAPON_BAT_ATTACK:
- m_sQueueSample.m_nSampleIndex = SFX_BAT_HIT_LEFT;
- m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ case SOUND_WEAPON_KNIFE_ATTACK:
+ {
+ uint32 soundParams = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; // wtf? storing int as float
+ uint8 damagerType = soundParams & 0xFF;
+ uint32 weaponType = soundParams >> 8;
+ if (damagerType == ENTITY_TYPE_PED) {
+ switch (weaponType) {
+ case WEAPONTYPE_SCREWDRIVER:
+ case WEAPONTYPE_KNIFE:
+ case WEAPONTYPE_CLEAVER:
+ case WEAPONTYPE_MACHETE:
+ case WEAPONTYPE_KATANA:
+ if (sound == SOUND_WEAPON_KNIFE_ATTACK)
+ m_sQueueSample.m_nSampleIndex = SFX_KNIFE_SLASH;
+ else
+ m_sQueueSample.m_nSampleIndex = SFX_KNIFE_STAB;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32);
+ break;
+ case WEAPONTYPE_HAMMER:
+ m_sQueueSample.m_nSampleIndex = m_anRandomTable[3] % 2 + SFX_HAMMER_HIT_1;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32);
+ break;
+ default:
+ m_sQueueSample.m_nSampleIndex = SFX_BAT_HIT_LEFT;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nFrequency = RandomDisplacement(2000) + 22000;
+ stereo = TRUE;
+ break;
+ }
+ }
+ else {
+ m_sQueueSample.m_nSampleIndex = m_anRandomTable[4] % 6 + SFX_COL_CAR_PANEL_1;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ 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++;
narrowSoundRange = TRUE;
- m_sQueueSample.m_nFrequency = RandomDisplacement(2000) + 22000;
m_sQueueSample.m_nReleasingVolumeModificator = 3;
m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_SoundIntensity = 30.0f;
@@ -3204,14 +4405,106 @@ cAudioManager::ProcessPedOneShots(cPedParams &params)
SET_EMITTING_VOLUME(emittingVol);
m_sQueueSample.m_bIs2D = FALSE;
m_sQueueSample.m_bReleasingSoundFlag = TRUE;
- if (m_bDynamicAcousticModelingStatus)
- m_sQueueSample.m_bRequireReflection = TRUE;
- else
- stereo = TRUE;
+ m_sQueueSample.m_bRequireReflection = TRUE;
+ break;
+ }
+ case SOUND_WEAPON_CHAINSAW_IDLE:
+ if (FindVehicleOfPlayer())
+ continue;
+ m_sQueueSample.m_nSampleIndex = SFX_CAR_CHAINSAW_IDLE;
+#ifdef GTA_PS2
+ m_sQueueSample.m_nBankIndex = SFX_BANK_CAR_CHAINSAW;
+#else
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+#endif
+ m_sQueueSample.m_nCounter = 70;
+ m_sQueueSample.m_nFrequency = 27000;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 3.0f;
+ m_sQueueSample.m_SoundIntensity = 50.0f;
+ maxDist = SQR(50);
+ m_sQueueSample.m_nLoopCount = 0;
+ emittingVol = 100;
+ SET_LOOP_OFFSETS(SFX_CAR_CHAINSAW_IDLE)
+ SET_EMITTING_VOLUME(100);
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_bReleasingSoundFlag = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 5;
+ break;
+ case SOUND_WEAPON_CHAINSAW_ATTACK:
+ if (FindVehicleOfPlayer())
+ continue;
+ m_sQueueSample.m_nSampleIndex = SFX_CAR_CHAINSAW_ATTACK;
+#ifdef GTA_PS2
+ m_sQueueSample.m_nBankIndex = SFX_BANK_CAR_CHAINSAW;
+#else
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+#endif
+ m_sQueueSample.m_nCounter = 68;
+ m_sQueueSample.m_nFrequency = 27000;
+ m_sQueueSample.m_nReleasingVolumeModificator = 2;
+ m_sQueueSample.m_fSpeedMultiplier = 3.0f;
+ m_sQueueSample.m_SoundIntensity = 60.0f;
+ maxDist = SQR(60);
+ m_sQueueSample.m_nLoopCount = 0;
+ emittingVol = 100;
+ SET_LOOP_OFFSETS(SFX_CAR_CHAINSAW_ATTACK)
+ SET_EMITTING_VOLUME(100);
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_bReleasingSoundFlag = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 5;
+ break;
+ case SOUND_WEAPON_CHAINSAW_MADECONTACT:
+ if (FindVehicleOfPlayer())
+ continue;
+ if ((int32)m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i] != ENTITY_TYPE_PED)
+ ReportCollision(params.m_pPed, params.m_pPed, SURFACE_CAR, SURFACE_TARMAC, 0.0f, 0.09f);
+ m_sQueueSample.m_nSampleIndex = SFX_CAR_CHAINSAW_ATTACK;
+#ifdef GTA_PS2
+ m_sQueueSample.m_nBankIndex = SFX_BANK_CAR_CHAINSAW;
+#else
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+#endif
+ m_sQueueSample.m_nCounter = 68;
+ m_sQueueSample.m_nFrequency = RandomDisplacement(500) + 22000;
+ m_sQueueSample.m_nReleasingVolumeModificator = 2;
+ m_sQueueSample.m_fSpeedMultiplier = 3.0f;
+ m_sQueueSample.m_SoundIntensity = 60.0f;
+ maxDist = SQR(60);
+ m_sQueueSample.m_nLoopCount = 0;
+ emittingVol = 100;
+ SET_LOOP_OFFSETS(SFX_CAR_CHAINSAW_ATTACK)
+ SET_EMITTING_VOLUME(100);
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_bReleasingSoundFlag = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 5;
break;
case SOUND_WEAPON_SHOT_FIRED:
weapon = ped->GetWeapon();
+ if (!weapon)
+ continue;
switch (weapon->m_eWeaponType) {
+ case WEAPONTYPE_ROCKET:
+ case WEAPONTYPE_ROCKETLAUNCHER:
+ m_sQueueSample.m_nSampleIndex = SFX_ROCKET_LEFT;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nCounter = iSound++;
+ narrowSoundRange = 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_SoundIntensity = 120.0f;
+ maxDist = SQR(120);
+ m_sQueueSample.m_nLoopCount = 1;
+ RESET_LOOP_OFFSETS
+ emittingVol = m_anRandomTable[0] % 20 + 80;
+ SET_EMITTING_VOLUME(emittingVol);
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_bReleasingSoundFlag = TRUE;
+ m_sQueueSample.m_bRequireReflection = TRUE;
+ stereo = TRUE;
+ break;
case WEAPONTYPE_COLT45:
m_sQueueSample.m_nSampleIndex = SFX_COLT45_LEFT;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
@@ -3221,38 +4514,39 @@ cAudioManager::ProcessPedOneShots(cPedParams &params)
m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32);
m_sQueueSample.m_nReleasingVolumeModificator = 3;
m_sQueueSample.m_fSpeedMultiplier = 0.0f;
- m_sQueueSample.m_SoundIntensity = 50.0f;
- maxDist = SQR(50);
+ m_sQueueSample.m_SoundIntensity = 120.0f;
+ maxDist = SQR(120);
m_sQueueSample.m_nLoopCount = 1;
RESET_LOOP_OFFSETS
emittingVol = m_anRandomTable[1] % 10 + 90;
SET_EMITTING_VOLUME(emittingVol);
m_sQueueSample.m_bIs2D = FALSE;
m_sQueueSample.m_bReleasingSoundFlag = TRUE;
- if (m_bDynamicAcousticModelingStatus)
- m_sQueueSample.m_bRequireReflection = TRUE;
- else
- stereo = TRUE;
+ m_sQueueSample.m_bRequireReflection = TRUE;
+ stereo = TRUE;
break;
- case WEAPONTYPE_UZI:
- m_sQueueSample.m_nSampleIndex = SFX_UZI_LEFT;
+ case WEAPONTYPE_PYTHON:
+ m_sQueueSample.m_nSampleIndex = SFX_PYTHON_LEFT;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_nCounter = iSound++;
narrowSoundRange = TRUE;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_UZI_LEFT);
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_PYTHON_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_SoundIntensity = 80.0f;
- maxDist = SQR(80);
+ m_sQueueSample.m_SoundIntensity = 120.0f;
+ maxDist = SQR(120);
m_sQueueSample.m_nLoopCount = 1;
RESET_LOOP_OFFSETS
- emittingVol = m_anRandomTable[3] % 15 + 70;
+ emittingVol = 127;
SET_EMITTING_VOLUME(emittingVol);
m_sQueueSample.m_bIs2D = FALSE;
m_sQueueSample.m_bReleasingSoundFlag = TRUE;
+ m_sQueueSample.m_bRequireReflection = TRUE;
+ stereo = TRUE;
break;
case WEAPONTYPE_SHOTGUN:
+ case WEAPONTYPE_STUBBY_SHOTGUN:
m_sQueueSample.m_nSampleIndex = SFX_SHOTGUN_LEFT;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_nCounter = iSound++;
@@ -3261,98 +4555,172 @@ cAudioManager::ProcessPedOneShots(cPedParams &params)
m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32);
m_sQueueSample.m_nReleasingVolumeModificator = 3;
m_sQueueSample.m_fSpeedMultiplier = 0.0f;
- m_sQueueSample.m_SoundIntensity = 60.0f;
- maxDist = SQR(60);
+ m_sQueueSample.m_SoundIntensity = 120.0f;
+ maxDist = SQR(120);
m_sQueueSample.m_nLoopCount = 1;
RESET_LOOP_OFFSETS
emittingVol = m_anRandomTable[2] % 10 + 100;
SET_EMITTING_VOLUME(emittingVol);
m_sQueueSample.m_bIs2D = FALSE;
m_sQueueSample.m_bReleasingSoundFlag = TRUE;
- if (m_bDynamicAcousticModelingStatus)
- m_sQueueSample.m_bRequireReflection = TRUE;
- else
- stereo = TRUE;
+ m_sQueueSample.m_bRequireReflection = TRUE;
+ stereo = TRUE;
break;
- case WEAPONTYPE_AK47:
- m_sQueueSample.m_nSampleIndex = SFX_AK47_LEFT;
+ case WEAPONTYPE_SPAS12_SHOTGUN:
+ m_sQueueSample.m_nSampleIndex = SFX_SPAS12_LEFT;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_nCounter = iSound++;
narrowSoundRange = TRUE;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_AK47_LEFT);
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_SPAS12_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_SoundIntensity = 80.0f;
- maxDist = SQR(80);
+ m_sQueueSample.m_SoundIntensity = 120.0f;
+ maxDist = SQR(120);
+ m_sQueueSample.m_nLoopCount = 1;
+ RESET_LOOP_OFFSETS
+ emittingVol = m_anRandomTable[2] % 10 + 100;
+ SET_EMITTING_VOLUME(emittingVol);
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_bReleasingSoundFlag = TRUE;
+ m_sQueueSample.m_bRequireReflection = TRUE;
+ stereo = TRUE;
+ break;
+ case WEAPONTYPE_TEC9:
+ m_sQueueSample.m_nSampleIndex = SFX_TEC_LEFT;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nCounter = iSound++;
+ narrowSoundRange = TRUE;
+ m_sQueueSample.m_nFrequency = RandomDisplacement(500) + 17000;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_SoundIntensity = 120.0f;
+ maxDist = SQR(120);
m_sQueueSample.m_nLoopCount = 1;
RESET_LOOP_OFFSETS
- emittingVol = m_anRandomTable[1] % 15 + 70;
+ emittingVol = m_anRandomTable[3] % 15 + 70;
SET_EMITTING_VOLUME(emittingVol);
m_sQueueSample.m_bIs2D = FALSE;
m_sQueueSample.m_bReleasingSoundFlag = TRUE;
+ stereo = TRUE;
break;
- case WEAPONTYPE_M16:
- m_sQueueSample.m_nSampleIndex = SFX_M16_LEFT;
+ case WEAPONTYPE_UZI:
+ case WEAPONTYPE_MINIGUN:
+ m_sQueueSample.m_nSampleIndex = SFX_UZI_LEFT;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_nCounter = iSound++;
narrowSoundRange = TRUE;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_M16_LEFT);
+ 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_SoundIntensity = 80.0f;
- maxDist = SQR(80);
+ m_sQueueSample.m_SoundIntensity = 120.0f;
+ maxDist = SQR(120);
m_sQueueSample.m_nLoopCount = 1;
RESET_LOOP_OFFSETS
- emittingVol = m_anRandomTable[4] % 15 + 70;
+ emittingVol = m_anRandomTable[3] % 15 + 70;
SET_EMITTING_VOLUME(emittingVol);
m_sQueueSample.m_bIs2D = FALSE;
m_sQueueSample.m_bReleasingSoundFlag = TRUE;
+ stereo = TRUE;
break;
- case WEAPONTYPE_SNIPERRIFLE:
- m_sQueueSample.m_nSampleIndex = SFX_SNIPER_LEFT;
+ case WEAPONTYPE_SILENCED_INGRAM:
+ m_sQueueSample.m_nSampleIndex = SFX_TEC_LEFT;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_nCounter = iSound++;
narrowSoundRange = TRUE;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_SNIPER_LEFT);
+ m_sQueueSample.m_nFrequency = RandomDisplacement(1000) + 34000;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_SoundIntensity = 120.0f;
+ maxDist = SQR(120);
+ m_sQueueSample.m_nLoopCount = 1;
+ RESET_LOOP_OFFSETS
+ emittingVol = m_anRandomTable[3] % 15 + 70;
+ SET_EMITTING_VOLUME(emittingVol);
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_bReleasingSoundFlag = TRUE;
+ stereo = TRUE;
+ break;
+ case WEAPONTYPE_MP5:
+ m_sQueueSample.m_nSampleIndex = SFX_MP5_LEFT;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nCounter = iSound++;
+ narrowSoundRange = TRUE;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_MP5_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_SoundIntensity = 60.0f;
- maxDist = SQR(60);
+ m_sQueueSample.m_SoundIntensity = 120.0f;
+ maxDist = SQR(120);
m_sQueueSample.m_nLoopCount = 1;
RESET_LOOP_OFFSETS
- emittingVol = m_anRandomTable[4] % 10 + 110;
+ emittingVol = m_anRandomTable[3] % 15 + 70;
SET_EMITTING_VOLUME(emittingVol);
m_sQueueSample.m_bIs2D = FALSE;
m_sQueueSample.m_bReleasingSoundFlag = TRUE;
- if (m_bDynamicAcousticModelingStatus)
- m_sQueueSample.m_bRequireReflection = TRUE;
- else
- stereo = TRUE;
+ stereo = TRUE;
break;
- case WEAPONTYPE_ROCKETLAUNCHER:
- m_sQueueSample.m_nSampleIndex = SFX_ROCKET_LEFT;
+ case WEAPONTYPE_M4:
+ m_sQueueSample.m_nSampleIndex = SFX_RUGER_LEFT;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_nCounter = iSound++;
narrowSoundRange = TRUE;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_ROCKET_LEFT);
+ m_sQueueSample.m_nFrequency = RandomDisplacement(1000) + 43150;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_SoundIntensity = 120.0f;
+ maxDist = SQR(120);
+ m_sQueueSample.m_nLoopCount = 1;
+ RESET_LOOP_OFFSETS
+ emittingVol = m_anRandomTable[3] % 15 + 90;
+ SET_EMITTING_VOLUME(emittingVol);
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_bReleasingSoundFlag = TRUE;
+ stereo = TRUE;
+ break;
+ case WEAPONTYPE_RUGER:
+ m_sQueueSample.m_nSampleIndex = SFX_RUGER_LEFT;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nCounter = iSound++;
+ narrowSoundRange = TRUE;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RUGER_LEFT);
m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32);
- m_sQueueSample.m_nReleasingVolumeModificator = 1;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
m_sQueueSample.m_fSpeedMultiplier = 0.0f;
- m_sQueueSample.m_SoundIntensity = 90.0f;
- maxDist = SQR(90);
+ m_sQueueSample.m_SoundIntensity = 120.0f;
+ maxDist = SQR(120);
m_sQueueSample.m_nLoopCount = 1;
RESET_LOOP_OFFSETS
- emittingVol = m_anRandomTable[0] % 20 + 80;
+ emittingVol = m_anRandomTable[3] % 15 + 90;
SET_EMITTING_VOLUME(emittingVol);
m_sQueueSample.m_bIs2D = FALSE;
m_sQueueSample.m_bReleasingSoundFlag = TRUE;
- if (m_bDynamicAcousticModelingStatus)
- m_sQueueSample.m_bRequireReflection = TRUE;
+ stereo = TRUE;
+ break;
+ case WEAPONTYPE_SNIPERRIFLE:
+ case WEAPONTYPE_LASERSCOPE:
+ m_sQueueSample.m_nSampleIndex = SFX_SNIPER_LEFT;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nCounter = iSound++;
+ narrowSoundRange = TRUE;
+ if (weapon->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE)
+ m_sQueueSample.m_nFrequency = 25472;
else
- stereo = TRUE;
+ m_sQueueSample.m_nFrequency = 20182;
+ m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_SoundIntensity = 120.0f;
+ maxDist = SQR(120);
+ m_sQueueSample.m_nLoopCount = 1;
+ RESET_LOOP_OFFSETS
+ emittingVol = m_anRandomTable[4] % 10 + 110;
+ SET_EMITTING_VOLUME(emittingVol);
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_bReleasingSoundFlag = TRUE;
+ m_sQueueSample.m_bRequireReflection = TRUE;
+ stereo = TRUE;
break;
case WEAPONTYPE_FLAMETHROWER:
m_sQueueSample.m_nSampleIndex = SFX_FLAMETHROWER_LEFT;
@@ -3370,47 +4738,66 @@ cAudioManager::ProcessPedOneShots(cPedParams &params)
m_sQueueSample.m_bIs2D = FALSE;
m_sQueueSample.m_bReleasingSoundFlag = FALSE;
m_sQueueSample.m_nReleasingVolumeDivider = 6;
- if (m_bDynamicAcousticModelingStatus)
- m_sQueueSample.m_bRequireReflection = TRUE;
- else
- stereo = TRUE;
+ stereo = TRUE;
+ break;
+ case WEAPONTYPE_M60:
+ case WEAPONTYPE_HELICANNON:
+ m_sQueueSample.m_nSampleIndex = SFX_M60_LEFT;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nCounter = iSound++;
+ narrowSoundRange = TRUE;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_M60_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_SoundIntensity = 120.0f;
+ maxDist = SQR(120);
+ m_sQueueSample.m_nLoopCount = 1;
+ RESET_LOOP_OFFSETS
+ emittingVol = 127;
+ SET_EMITTING_VOLUME(127);
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_bReleasingSoundFlag = TRUE;
+ stereo = TRUE;
break;
default:
continue;
}
-
break;
case SOUND_WEAPON_RELOAD:
- weapon = &ped->m_weapons[ped->m_currentWeapon];
- switch (weapon->m_eWeaponType) {
+ switch ((int32)m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]) {
+ case WEAPONTYPE_ROCKET:
+ case WEAPONTYPE_ROCKETLAUNCHER:
+ m_sQueueSample.m_nSampleIndex = SFX_ROCKET_RELOAD;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_ROCKET_RELOAD);
+ break;
case WEAPONTYPE_COLT45:
+ case WEAPONTYPE_PYTHON:
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:
+ case WEAPONTYPE_SPAS12_SHOTGUN:
+ case WEAPONTYPE_STUBBY_SHOTGUN:
+ case WEAPONTYPE_RUGER:
m_sQueueSample.m_nSampleIndex = SFX_AK47_RELOAD;
m_sQueueSample.m_nFrequency = 30290;
break;
- case WEAPONTYPE_AK47:
+ case WEAPONTYPE_TEC9:
+ case WEAPONTYPE_UZI:
+ case WEAPONTYPE_SILENCED_INGRAM:
+ case WEAPONTYPE_MP5:
+ case WEAPONTYPE_M4:
+ case WEAPONTYPE_M60:
+ case WEAPONTYPE_HELICANNON:
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);
+ m_sQueueSample.m_nFrequency = 39243;
break;
case WEAPONTYPE_SNIPERRIFLE:
+ case WEAPONTYPE_LASERSCOPE:
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;
}
@@ -3431,29 +4818,70 @@ cAudioManager::ProcessPedOneShots(cPedParams &params)
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;
+ {
+ uint32 weaponType = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i];
+ switch (weaponType) {
+ case WEAPONTYPE_SPAS12_SHOTGUN:
+ m_sQueueSample.m_nSampleIndex = SFX_SPAS12_TAIL_LEFT;
+ break;
+ case WEAPONTYPE_TEC9:
+ case WEAPONTYPE_SILENCED_INGRAM:
+ m_sQueueSample.m_nSampleIndex = SFX_TEC_TAIL;
+ break;
+ case WEAPONTYPE_UZI:
+ case WEAPONTYPE_MP5:
+ m_sQueueSample.m_nSampleIndex = SFX_UZI_END_LEFT;
+ break;
+ case WEAPONTYPE_M4:
+ case WEAPONTYPE_RUGER:
+ case WEAPONTYPE_SNIPERRIFLE:
+ case WEAPONTYPE_LASERSCOPE:
+ m_sQueueSample.m_nSampleIndex = SFX_RUGER_TAIL;
+ break;
+ case WEAPONTYPE_M60:
+ case WEAPONTYPE_HELICANNON:
+ m_sQueueSample.m_nSampleIndex = SFX_M60_TAIL_LEFT;
+ break;
+ default:
+ continue;
+ }
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_nCounter = iSound++;
narrowSoundRange = TRUE;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_UZI_END_LEFT);
+ switch (weaponType) {
+ case WEAPONTYPE_TEC9:
+ m_sQueueSample.m_nFrequency = 13000;
+ break;
+ case WEAPONTYPE_SILENCED_INGRAM:
+ m_sQueueSample.m_nFrequency = 26000;
+ break;
+ case WEAPONTYPE_M4:
+ m_sQueueSample.m_nFrequency = 15600;
+ break;
+ case WEAPONTYPE_SNIPERRIFLE:
+ m_sQueueSample.m_nFrequency = 9959;
+ break;
+ case WEAPONTYPE_LASERSCOPE:
+ m_sQueueSample.m_nFrequency = 7904;
+ break;
+ default:
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
+ break;
+ }
m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16);
m_sQueueSample.m_nReleasingVolumeModificator = 3;
m_sQueueSample.m_fSpeedMultiplier = 0.0f;
- m_sQueueSample.m_SoundIntensity = 80.0f;
- maxDist = SQR(80);
+ m_sQueueSample.m_SoundIntensity = 120.0f;
+ maxDist = SQR(120);
m_sQueueSample.m_nLoopCount = 1;
RESET_LOOP_OFFSETS
- emittingVol = m_anRandomTable[4] % 10 + 40;
+ emittingVol = m_anRandomTable[4] % 10 + 80;
SET_EMITTING_VOLUME(emittingVol);
m_sQueueSample.m_bIs2D = FALSE;
m_sQueueSample.m_bReleasingSoundFlag = TRUE;
- if (m_bDynamicAcousticModelingStatus)
- m_sQueueSample.m_bRequireReflection = TRUE;
- else
- stereo = TRUE;
+ m_sQueueSample.m_bRequireReflection = TRUE;
break;
+ }
case SOUND_WEAPON_FLAMETHROWER_FIRE:
m_sQueueSample.m_nSampleIndex = SFX_FLAMETHROWER_START_LEFT;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
@@ -3490,6 +4918,9 @@ cAudioManager::ProcessPedOneShots(cPedParams &params)
m_sQueueSample.m_bReleasingSoundFlag = TRUE;
break;
case SOUND_SPLASH:
+ if (m_FrameCounter <= iSplashFrame)
+ continue;
+ iSplashFrame = m_FrameCounter + 6;
m_sQueueSample.m_nSampleIndex = SFX_SPLASH_1;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_nCounter = iSound++;
@@ -3507,6 +4938,164 @@ cAudioManager::ProcessPedOneShots(cPedParams &params)
m_sQueueSample.m_bReleasingSoundFlag = TRUE;
m_sQueueSample.m_bRequireReflection = TRUE;
break;
+ case SOUND_MELEE_ATTACK_START:
+ {
+ uint32 weaponType = ((uint32)m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]) >> 8;
+ switch (weaponType)
+ {
+ case WEAPONTYPE_SCREWDRIVER:
+ case WEAPONTYPE_KNIFE:
+ case WEAPONTYPE_CLEAVER:
+ case WEAPONTYPE_MACHETE:
+ case WEAPONTYPE_KATANA:
+ m_sQueueSample.m_nSampleIndex = SFX_KNIFE_SWING;
+ break;
+ default:
+ m_sQueueSample.m_nSampleIndex = SFX_GOLF_CLUB_SWING;
+ break;
+ }
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nCounter = iSound++;
+ narrowSoundRange = TRUE;
+ 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_SoundIntensity = 30.0f;
+ if (weaponType == WEAPONTYPE_UNARMED || weaponType == WEAPONTYPE_BRASSKNUCKLE)
+ emittingVol = m_anRandomTable[1] % 10 + 35;
+ else
+ emittingVol = m_anRandomTable[2] % 20 + 70;
+ maxDist = SQR(30);
+ m_sQueueSample.m_nLoopCount = 1;
+ RESET_LOOP_OFFSETS
+ SET_EMITTING_VOLUME(emittingVol);
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_bReleasingSoundFlag = TRUE;
+ m_sQueueSample.m_bRequireReflection = TRUE;
+ break;
+ }
+ case SOUND_SKATING:
+ {
+ uint32 soundParams = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i];
+ uint8 param1 = soundParams & 0xFF;
+ uint32 param2 = soundParams >> 8;
+ m_sQueueSample.m_nSampleIndex = (m_anRandomTable[3] & 1) + SFX_SKATE_1;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nCounter = iSound;
+ stereo = TRUE;
+ ++iSound;
+ m_sQueueSample.m_nFrequency = m_anRandomTable[1] % 1000 + 17000;
+ if (param2 == 0)
+ m_sQueueSample.m_nFrequency = (3 * m_sQueueSample.m_nFrequency) / 4;
+ m_sQueueSample.m_nReleasingVolumeModificator = 6;
+ m_sQueueSample.m_fSpeedMultiplier = 3.0f;
+ m_sQueueSample.m_SoundIntensity = 20.0f;
+ maxDist = SQR(20);
+ m_sQueueSample.m_nLoopCount = 1;
+ RESET_LOOP_OFFSETS
+ emittingVol = (m_anRandomTable[2] % 20 + 70) * param1 / 127;
+ SET_EMITTING_VOLUME(emittingVol);
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_bReleasingSoundFlag = TRUE;
+ m_sQueueSample.m_bRequireReflection = TRUE;
+ break;
+ }
+ case SOUND_WEAPON_MINIGUN_ATTACK:
+ m_sQueueSample.m_nSampleIndex = SFX_MINIGUN_FIRE_LEFT;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nCounter = 68;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_MINIGUN_FIRE_LEFT);
+ m_sQueueSample.m_nReleasingVolumeModificator = 2;
+ m_sQueueSample.m_fSpeedMultiplier = 3.0f;
+ m_sQueueSample.m_SoundIntensity = 150.0f;
+ emittingVol = 127;
+ maxDist = SQR(150);
+ m_sQueueSample.m_nLoopCount = 0;
+ SET_LOOP_OFFSETS(SFX_MINIGUN_FIRE_LEFT)
+ SET_EMITTING_VOLUME(127);
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_bReleasingSoundFlag = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ break;
+ case SOUND_WEAPON_MINIGUN_2:
+ m_sQueueSample.m_nSampleIndex = SFX_MINIGUN_FIRE_RIGHT;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nCounter = 69;
+ m_sQueueSample.m_nFrequency = 18569;
+ m_sQueueSample.m_nReleasingVolumeModificator = 2;
+ m_sQueueSample.m_fSpeedMultiplier = 3.0f;
+ m_sQueueSample.m_SoundIntensity = 150.0f;
+ emittingVol = 127.0f * m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i];
+ maxDist = SQR(150);
+ m_sQueueSample.m_nLoopCount = 0;
+ SET_LOOP_OFFSETS(SFX_MINIGUN_FIRE_RIGHT)
+ SET_EMITTING_VOLUME(emittingVol);
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_bReleasingSoundFlag = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ break;
+ case SOUND_WEAPON_MINIGUN_3:
+ m_sQueueSample.m_nSampleIndex = SFX_MINIGUN_STOP;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nCounter = 69;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_MINIGUN_STOP);
+ m_sQueueSample.m_nReleasingVolumeModificator = 4;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_SoundIntensity = 150.0f;
+ maxDist = SQR(150);
+ m_sQueueSample.m_nLoopCount = 1;
+ RESET_LOOP_OFFSETS
+ emittingVol = 127;
+ SET_EMITTING_VOLUME(127);
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_bReleasingSoundFlag = TRUE;
+ m_sQueueSample.m_bRequireReflection = TRUE;
+ break;
+ case SOUND_SHIRT_WIND_FLAP:
+ if (params.m_pPed->IsPlayer() && params.m_pPed->m_pMyVehicle) {
+ if (m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i] > 0.0f) {
+ if (m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i] > 1.0f)
+ m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i] = 1.0f;
+
+ emittingVol = 90.0f * m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i];
+
+ switch (params.m_pPed->m_pMyVehicle->GetModelIndex())
+ {
+ case MI_ANGEL:
+ case MI_FREEWAY:
+ m_sQueueSample.m_nSampleIndex = SFX_CAR_WIND_17;
+ break;
+ case MI_PIZZABOY:
+ case MI_FAGGIO:
+ m_sQueueSample.m_nSampleIndex = SFX_CAR_WIND_18;
+ break;
+ case MI_PCJ600:
+ m_sQueueSample.m_nSampleIndex = SFX_CAR_WIND_20;
+ break;
+ case MI_SANCHEZ:
+ m_sQueueSample.m_nSampleIndex = SFX_CAR_WIND_19;
+ break;
+ default:
+ continue;
+ };
+
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nCounter = 71;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 3.0f;
+ m_sQueueSample.m_SoundIntensity = 15.0f;
+ maxDist = SQR(15);
+ m_sQueueSample.m_nLoopCount = 0;
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
+ SET_EMITTING_VOLUME(emittingVol);
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_bReleasingSoundFlag = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ }
+ }
+ continue;
default:
SetupPedComments(params, sound);
continue;
@@ -3547,6 +5136,60 @@ cAudioManager::ProcessPedOneShots(cPedParams &params)
}
void
+cAudioManager::SetPedTalkingStatus(CPed *ped, bool8 status)
+{
+ if (ped != nil)
+ ped->m_canTalk = status;
+}
+
+void
+cAudioManager::SetPlayersMood(uint8 mood, uint32 time)
+{
+ if (!m_bIsInitialised) return;
+
+ if (mood < MAX_PLAYER_MOODS) {
+ m_nPlayerMood = mood;
+ m_nPlayerMoodTimer = CTimer::GetTimeInMilliseconds() + time;
+ }
+
+}
+
+void
+cAudioManager::ProcessPlayerMood()
+{
+ CPlayerPed *playerPed;
+ uint32& lastMissionPassedTime = CTheScripts::GetLastMissionPassedTime();
+ uint32 curTime = CTimer::GetTimeInMilliseconds();
+
+ if (m_nPlayerMoodTimer <= curTime) {
+ playerPed = FindPlayerPed();
+ if (playerPed != nil) {
+
+ if (playerPed->m_pWanted->GetWantedLevel() > 3) {
+ m_nPlayerMood = PLAYER_MOOD_ANGRY;
+ return;
+ }
+ if (playerPed->m_pWanted->GetWantedLevel() > 1) {
+ m_nPlayerMood = PLAYER_MOOD_PISSED_OFF;
+ return;
+ }
+
+ if (lastMissionPassedTime != -1) {
+ if (curTime < lastMissionPassedTime) {
+ lastMissionPassedTime = curTime;
+ return;
+ }
+ if (curTime < lastMissionPassedTime + 180000) {
+ m_nPlayerMood = PLAYER_MOOD_WISECRACKING;
+ return;
+ }
+ }
+ m_nPlayerMood = PLAYER_MOOD_CALM;
+ }
+ }
+}
+
+void
cAudioManager::SetupPedComments(cPedParams &params, uint16 sound)
{
CPed *ped = params.m_pPed;
@@ -3554,239 +5197,202 @@ cAudioManager::SetupPedComments(cPedParams &params, uint16 sound)
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;
+ if(ped != nil) {
+ if(!ped->m_canTalk) return;
+ m_bGenericSfx = FALSE;
+ pedComment.m_nSampleIndex = GetPedCommentSfx(ped, sound);
+ if(pedComment.m_nSampleIndex == NO_SAMPLE) return;
+ soundIntensity = 40.0f;
} else {
- switch (sound) {
+ m_bGenericSfx = TRUE;
+ switch(sound) {
case SOUND_PED_HELI_PLAYER_FOUND:
soundIntensity = 400.0f;
- pedComment.m_nSampleIndex = m_anRandomTable[m_sQueueSample.m_nEntityIndex % 4] % 29 + SFX_POLICE_HELI_1;
+ pedComment.m_nSampleIndex = m_anRandomTable[m_sQueueSample.m_nEntityIndex % 4] % 20 + SFX_POLICE_HELI_1;
break;
- case SOUND_PED_BODYCAST_HIT:
- if (CTimer::GetTimeInMilliseconds() <= gNextCryTime)
- return;
- soundIntensity = 50.0f;
- gNextCryTime = CTimer::GetTimeInMilliseconds() + 500;
- pedComment.m_nSampleIndex = m_anRandomTable[m_sQueueSample.m_nEntityIndex % 4] % 4 + SFX_PLASTER_BLOKE_1;
+ case SOUND_PED_VCPA_PLAYER_FOUND:
+ soundIntensity = 400.0f;
+#ifdef FIX_BUGS
+ pedComment.m_nSampleIndex = m_anRandomTable[m_sQueueSample.m_nEntityIndex % 4] % 23 + SFX_POLICE_BOAT_1;
+#else
+ pedComment.m_nSampleIndex = m_anRandomTable[m_sQueueSample.m_nEntityIndex % 4] % 29 + SFX_POLICE_BOAT_1;
+#endif
break;
case SOUND_INJURED_PED_MALE_OUCH:
- case SOUND_INJURED_PED_MALE_PRISON:
- soundIntensity = 50.0f;
- pedComment.m_nSampleIndex = m_anRandomTable[m_sQueueSample.m_nEntityIndex % 4] % 15 + SFX_GENERIC_MALE_GRUNT_1;
+ soundIntensity = 40.0f;
+ pedComment.m_nSampleIndex = m_anRandomTable[m_sQueueSample.m_nEntityIndex % 4] % 41 + SFX_GENERIC_MALE_GRUNT_1;
break;
case SOUND_INJURED_PED_FEMALE:
- soundIntensity = 50.0f;
- pedComment.m_nSampleIndex = m_anRandomTable[m_sQueueSample.m_nEntityIndex % 4] % 11 + SFX_GENERIC_FEMALE_GRUNT_1;
+ soundIntensity = 40.0f;
+ pedComment.m_nSampleIndex = m_anRandomTable[m_sQueueSample.m_nEntityIndex % 4] % 33 + SFX_GENERIC_FEMALE_GRUNT_1;
break;
default:
return;
}
}
- if (params.m_fDistance < SQR(soundIntensity)) {
+ 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_nVolume = m_sQueueSample.m_nVolume;
+ if(CWorld::GetIsLineOfSightClear(TheCamera.GetPosition(), m_sQueueSample.m_vecPos, true, false, false, false, false, false))
+ emittingVol = MAX_VOLUME;
+ else
+ emittingVol = 31;
+ 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_nVolume = m_sQueueSample.m_nVolume;
#if defined(EXTERNAL_3D_SOUND) && defined(FIX_BUGS)
- pedComment.m_nEmittingVolume = emittingVol;
+ pedComment.m_nEmittingVolume = emittingVol;
#endif
- m_sPedComments.Add(&pedComment);
- }
+ m_sPedComments.Add(&pedComment);
}
}
}
-int32
+uint32
cAudioManager::GetPedCommentSfx(CPed *ped, uint16 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 GetAsianTaxiDriverTalkSfx(sound);
- 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 GetCasualMaleOldTalkSfx(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 GetCasualMaleYoungTalkSfx(sound);
- default:
- return GetGenericMaleTalkSfx(sound);
+ if(ped->m_nPedState != PED_FALL || sound == SOUND_PED_DAMAGE || sound == SOUND_PED_HIT || sound == SOUND_PED_LAND) {
+ if(ped->m_getUpTimer == UINT32_MAX || ped->m_getUpTimer > CTimer::GetTimeInMilliseconds()) {
+ if(sound != SOUND_PED_DAMAGE && sound != SOUND_PED_HIT && sound != SOUND_PED_LAND) return NO_SAMPLE;
+ }
+ if(ped->IsPlayer()) return GetPlayerTalkSfx(ped, sound);
+ switch(ped->GetModelIndex()) {
+ case MI_PLAYER: return GetPlayerTalkSfx(ped, sound);
+ case MI_COP: return GetCopTalkSfx(ped, sound);
+ case MI_SWAT: return GetSwatTalkSfx(ped, sound);
+ case MI_FBI: return GetFBITalkSfx(ped, sound);
+ case MI_ARMY: return GetArmyTalkSfx(ped, sound);
+ case MI_MEDIC: return GetMedicTalkSfx(ped, sound);
+ case MI_FIREMAN: return GetFiremanTalkSfx(ped, sound);
+ case MI_MALE01: return GetDefaultTalkSfx(ped, sound);
+ case MI_HFYST: return GetHFYSTTalkSfx(ped, sound);
+ case MI_HFOST: return GetHFOSTTalkSfx(ped, sound);
+ case MI_HMYST: return GetHMYSTTalkSfx(ped, sound);
+ case MI_HMOST: return GetHMOSTTalkSfx(ped, sound);
+ case MI_HFYRI: return GetHFYRITalkSfx(ped, sound);
+ case MI_HFORI: return GetHFORITalkSfx(ped, sound);
+ case MI_HMYRI: return GetHMYRITalkSfx(ped, sound);
+ case MI_HMORI: return GetHMORITalkSfx(ped, sound);
+ case MI_HFYBE: return GetHFYBETalkSfx(ped, sound);
+ case MI_HFOBE: return GetHFOBETalkSfx(ped, sound);
+ case MI_HMYBE: return GetHMYBETalkSfx(ped, sound);
+ case MI_HMOBE: return GetHMOBETalkSfx(ped, sound);
+ case MI_HFYBU: return GetHFYBUTalkSfx(ped, sound);
+ case MI_HFYMD: return GetHFYMDTalkSfx(ped, sound);
+ case MI_HFYCG: return GetHFYCGTalkSfx(ped, sound);
+ case MI_HFYPR: return GetHFYPRTalkSfx(ped, sound);
+ case MI_HFOTR: return GetHFOTRTalkSfx(ped, sound);
+ case MI_HMOTR: return GetHMOTRTalkSfx(ped, sound);
+ case MI_HMYAP: return GetHMYAPTalkSfx(ped, sound);
+ case MI_HMOCA: return GetHMOCATalkSfx(ped, sound);
+ case MI_BMODK: return GetBMODKTalkSfx(ped, sound);
+ case MI_BMYKR: return GetBMYCRTalkSfx(ped, sound);
+ case MI_BFYST: return GetBFYSTTalkSfx(ped, sound);
+ case MI_BFOST: return GetBFOSTTalkSfx(ped, sound);
+ case MI_BMYST: return GetBMYSTTalkSfx(ped, sound);
+ case MI_BMOST: return GetBMOSTTalkSfx(ped, sound);
+ case MI_BFYRI: return GetBFYRITalkSfx(ped, sound);
+ case MI_BFORI: return GetBFORITalkSfx(ped, sound);
+ case MI_BMYRI: return GetBMYRITalkSfx(ped, sound);
+ case MI_BFYBE: return GetBFYBETalkSfx(ped, sound);
+ case MI_BMYBE: return GetBMYBETalkSfx(ped, sound);
+ case MI_BFOBE: return GetBFOBETalkSfx(ped, sound);
+ case MI_BMOBE: return GetBMOBETalkSfx(ped, sound);
+ case MI_BMYBU: return GetBMYBUTalkSfx(ped, sound);
+ case MI_BFYPR: return GetBFYPRTalkSfx(ped, sound);
+ case MI_BFOTR: return GetBFOTRTalkSfx(ped, sound);
+ case MI_BMOTR: return GetBMOTRTalkSfx(ped, sound);
+ case MI_BMYPI: return GetBMYPITalkSfx(ped, sound);
+ case MI_BMYBB: return GetBMYBBTalkSfx(ped, sound);
+ case MI_WMYCR: return GetWMYCRTalkSfx(ped, sound);
+ case MI_WFYST: return GetWFYSTTalkSfx(ped, sound);
+ case MI_WFOST: return GetWFOSTTalkSfx(ped, sound);
+ case MI_WMYST: return GetWMYSTTalkSfx(ped, sound);
+ case MI_WMOST: return GetWMOSTTalkSfx(ped, sound);
+ case MI_WFYRI: return GetWFYRITalkSfx(ped, sound);
+ case MI_WFORI: return GetWFORITalkSfx(ped, sound);
+ case MI_WMYRI: return GetWMYRITalkSfx(ped, sound);
+ case MI_WMORI: return GetWMORITalkSfx(ped, sound);
+ case MI_WFYBE: return GetWFYBETalkSfx(ped, sound);
+ case MI_WMYBE: return GetWMYBETalkSfx(ped, sound);
+ case MI_WFOBE: return GetWFOBETalkSfx(ped, sound);
+ case MI_WMOBE: return GetWMOBETalkSfx(ped, sound);
+ case MI_WMYCW: return GetWMYCWTalkSfx(ped, sound);
+ case MI_WMYGO: return GetWMYGOTalkSfx(ped, sound);
+ case MI_WFOGO: return GetWFOGOTalkSfx(ped, sound);
+ case MI_WMOGO: return GetWMOGOTalkSfx(ped, sound);
+ case MI_WFYLG: return GetWFYLGTalkSfx(ped, sound);
+ case MI_WMYLG: return GetWMYLGTalkSfx(ped, sound);
+ case MI_WFYBU: return GetWFYBUTalkSfx(ped, sound);
+ case MI_WMYBU: return GetWMYBUTalkSfx(ped, sound);
+ case MI_WMOBU: return GetWMOBUTalkSfx(ped, sound);
+ case MI_WFYPR: return GetWFYPRTalkSfx(ped, sound);
+ case MI_WFOTR: return GetWFOTRTalkSfx(ped, sound);
+ case MI_WMOTR: return GetWMOTRTalkSfx(ped, sound);
+ case MI_WMYPI: return GetWMYPITalkSfx(ped, sound);
+ case MI_WMOCA: return GetWMOCATalkSfx(ped, sound);
+ case MI_WFYJG: return GetWFYJGTalkSfx(ped, sound);
+ case MI_WMYJG: return GetWMYJGTalkSfx(ped, sound);
+ case MI_WFYSK: return GetWFYSKTalkSfx(ped, sound);
+ case MI_WMYSK: return GetWMYSKTalkSfx(ped, sound);
+ case MI_WFYSH: return GetWFYSHTalkSfx(ped, sound);
+ case MI_WFOSH: return GetWFOSHTalkSfx(ped, sound);
+ case MI_JFOTO: return GetJFOTOTalkSfx(ped, sound);
+ case MI_JMOTO: return GetJMOTOTalkSfx(ped, sound);
+ case MI_CBA:
+ case MI_CBB: return GetCBTalkSfx(ped, sound);
+ case MI_HNA:
+ case MI_HNB: return GetHNTalkSfx(ped, sound);
+ case MI_SGA:
+ case MI_SGB: return GetSGTalkSfx(ped, sound);
+ case MI_CLA:
+ case MI_CLB: return GetCLTalkSfx(ped, sound);
+ case MI_GDA:
+ case MI_GDB: return GetGDTalkSfx(ped, sound);
+ case MI_BKA:
+ case MI_BKB: return GetBKTalkSfx(ped, sound);
+ case MI_PGA:
+ case MI_PGB: return GetPGTalkSfx(ped, sound);
+ case MI_VICE1:
+ case MI_VICE2:
+ case MI_VICE3:
+ case MI_VICE4:
+ case MI_VICE5:
+ case MI_VICE7:
+ case MI_VICE8: return GetViceWhiteTalkSfx(ped, sound);
+ case MI_VICE6: return GetViceBlackTalkSfx(ped, sound);
+ case MI_WFYG1: return GetWFYG1TalkSfx(ped, sound);
+ case MI_WFYG2: return GetWFYG2TalkSfx(ped, sound);
+ case MI_SPECIAL01:
+ case MI_SPECIAL02:
+ case MI_SPECIAL03:
+ case MI_SPECIAL04:
+ case MI_SPECIAL05:
+ case MI_SPECIAL06:
+ case MI_SPECIAL07:
+ case MI_SPECIAL08:
+ case MI_SPECIAL09:
+ case MI_SPECIAL10:
+ case MI_SPECIAL11:
+ case MI_SPECIAL12:
+ case MI_SPECIAL13:
+ case MI_SPECIAL14:
+ case MI_SPECIAL15:
+ case MI_SPECIAL16:
+ case MI_SPECIAL17:
+ case MI_SPECIAL18:
+ case MI_SPECIAL19:
+ case MI_SPECIAL20:
+ case MI_SPECIAL21: return GetSpecialCharacterTalkSfx(ped, ped->GetModelIndex(), sound);
+ default: return GetGenericMaleTalkSfx(ped, sound);
+ }
}
+
+ return NO_SAMPLE;
}
void
@@ -3803,2209 +5409,2436 @@ cAudioManager::GetPhrase(uint32 &phrase, uint32 &prevPhrase, uint32 sample, uint
#pragma region PED_COMMENTS
+#define cooldown_phrase(count) static uint8 cooldown = 0;\
+if (cooldown != 0) {\
+ if (++cooldown == count) cooldown = 0;\
+ return NO_SAMPLE;\
+}\
+cooldown = 1;
+
uint32
-cAudioManager::GetPlayerTalkSfx(uint16 sound)
+cAudioManager::GetPlayerTalkSfx(CPed *ped, uint16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
+ if(m_bIsPlayerShutUp) return NO_SAMPLE;
+ switch(sound) {
+ case SOUND_PED_DEATH: return SFX_PLAYER_DEATH;
case SOUND_PED_DAMAGE:
- GetPhrase(sfx, lastSfx, SFX_CLAUDE_HIGH_DAMAGE_GRUNT_1, 11);
- break;
+ case SOUND_PED_BULLET_HIT: GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_HIT_BULLET_1, 33); break;
case SOUND_PED_HIT:
- GetPhrase(sfx, lastSfx, SFX_CLAUDE_LOW_DAMAGE_GRUNT_1, 10);
+ case SOUND_PED_DEFEND: GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_HIT_FIST_1, 42); break;
+ case SOUND_PED_LAND: GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_HIT_GROUND_1, 35); break;
+ case SOUND_PED_BURNING: GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_ON_FIRE_1, 16); break;
+ case SOUND_PED_PLAYER_REACTTOCOP:
+ switch(m_nPlayerMood) {
+ case PLAYER_MOOD_ANGRY:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_ANGRY_BUSTED_1, 38);
+ break;
+ case PLAYER_MOOD_WISECRACKING:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_WISECRACKING_BUSTED_1, 20);
+ break;
+ default:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_CALM_BUSTED_1, 22);
+ break;
+ }
break;
- case SOUND_PED_LAND:
- GetPhrase(sfx, lastSfx, SFX_CLAUDE_HIT_GROUND_GRUNT_1, 6);
+ case SOUND_PED_ON_FIRE: {
+ cooldown_phrase(8);
+ switch(m_nPlayerMood) {
+ case PLAYER_MOOD_PISSED_OFF:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_PISSED_OFF_SHOOT_1, 29);
+ break;
+ case PLAYER_MOOD_ANGRY:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_ANGRY_SHOOT_1, 39);
+ break;
+ case PLAYER_MOOD_WISECRACKING:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_WISECRACKING_SHOOT_1, 9);
+ break;
+ default:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_CALM_SHOOT_1, 35);
+ break;
+ }
break;
- default:
- sfx = NO_SAMPLE;
+ }
+ case SOUND_PED_AIMING: {
+ cooldown_phrase(8);
+ switch(m_nPlayerMood) {
+ case PLAYER_MOOD_PISSED_OFF:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_PISSED_OFF_PULL_GUN_1, 25);
+ break;
+ case PLAYER_MOOD_ANGRY:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_ANGRY_PULL_GUN_1, 52);
+ break;
+ case PLAYER_MOOD_WISECRACKING:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_WISECRACKING_PULL_GUN_1, 19);
+ break;
+ default:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_CALM_PULL_GUN_1, 39);
+ break;
+ }
+ break;
+ }
+ case SOUND_PED_CAR_JACKING: {
+ cooldown_phrase(4);
+ switch(m_nPlayerMood) {
+ case PLAYER_MOOD_PISSED_OFF:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_PISSED_OFF_JACKING_1, 36);
+ break;
+ case PLAYER_MOOD_ANGRY:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_ANGRY_JACKING_1, 43);
+ break;
+ case PLAYER_MOOD_WISECRACKING:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_WISECRACKING_JACKING_1, 18);
+ break;
+ default:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_CALM_JACKING_1, 40);
+ break;
+ }
+ break;
+ }
+ case SOUND_PED_MUGGING: {
+ cooldown_phrase(8);
+ switch(m_nPlayerMood) {
+ case PLAYER_MOOD_PISSED_OFF:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_PISSED_OFF_PICK_UP_CASH_1, 25);
+ break;
+ case PLAYER_MOOD_ANGRY:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_ANGRY_PICK_UP_CASH_1, 12);
+ break;
+ case PLAYER_MOOD_WISECRACKING:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_WISECRACKING_PICK_UP_CASH_1, 23);
+ break;
+ default:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_CALM_PICK_UP_CASH_1, 11);
+ break;
+ }
+ break;
+ }
+ case SOUND_PED_CAR_JACKED: {
+ cooldown_phrase(4);
+ switch(m_nPlayerMood) {
+ case PLAYER_MOOD_PISSED_OFF:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_PISSED_OFF_JACKED_1, 21);
+ break;
+ case PLAYER_MOOD_ANGRY:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_ANGRY_JACKED_1, 33);
+ break;
+ case PLAYER_MOOD_WISECRACKING:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_WISECRACKING_JACKED_1, 18);
+ break;
+ default:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_CALM_JACKED_1, 24);
+ break;
+ }
+ break;
+ }
+ case SOUND_PED_PLAYER_AFTERSEX: GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_AFTERSEX_1, 18); break;
+ case SOUND_PED_PLAYER_BEFORESEX:
+ switch(m_nPlayerMood) {
+ case PLAYER_MOOD_ANGRY:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_ANGRY_SEX_1, 18);
+ break;
+ case PLAYER_MOOD_WISECRACKING:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_WISECRACKING_SEX_1, 10);
+ break;
+ default:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_CALM_SEX_1, 8);
+ break;
+ }
+ break;
+ case SOUND_PED_PLAYER_FARFROMCOPS: {
+ cooldown_phrase(4);
+ switch(m_nPlayerMood) {
+ case PLAYER_MOOD_ANGRY:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_ANGRY_CHASED_1, 9);
+ break;
+ case PLAYER_MOOD_WISECRACKING:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_WISECRACKING_CHASED_1, 7);
+ break;
+ default:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_CALM_CHASED_1, 20);
+ break;
+ }
+ break;
+ }
+ case SOUND_PED_ATTACK: {
+ cooldown_phrase(4);
+ switch(m_nPlayerMood) {
+ case PLAYER_MOOD_PISSED_OFF:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_PISSED_OFF_FIGHT_1, 61);
+ break;
+ case PLAYER_MOOD_ANGRY:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_ANGRY_FIGHT_1, 61);
+ break;
+ case PLAYER_MOOD_WISECRACKING:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_WISECRACKING_FIGHT_1, 27);
+ break;
+ default:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_CALM_FIGHT_1, 47);
+ break;
+ }
+ break;
+ }
+ case SOUND_PED_CRASH_VEHICLE:
+ case SOUND_PED_CRASH_CAR:
+ case SOUND_PED_ANNOYED_DRIVER: {
+ cooldown_phrase(4);
+ switch(m_nPlayerMood) {
+ case PLAYER_MOOD_PISSED_OFF:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_PISSED_OFF_CRASH_1, 44);
+ break;
+ case PLAYER_MOOD_ANGRY:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_ANGRY_CRASH_1, 41);
+ break;
+ case PLAYER_MOOD_WISECRACKING:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_WISECRACKING_CRASH_1, 19);
+ break;
+ default:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_CALM_CRASH_1, 43);
+ break;
+ }
break;
}
+ case SOUND_PED_SOLICIT: {
+ cooldown_phrase(4);
+ switch(m_nPlayerMood) {
+ case PLAYER_MOOD_PISSED_OFF:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_PISSED_OFF_PICK_UP_HOOKER_1, 17);
+ break;
+ case PLAYER_MOOD_ANGRY:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_ANGRY_PICK_UP_HOOKER_1, 6);
+ break;
+ case PLAYER_MOOD_WISECRACKING:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_WISECRACKING_PICK_UP_HOOKER_1, 11);
+ break;
+ default:
+ GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_CALM_PICK_UP_HOOKER_1, 22);
+ break;
+ }
+ break;
+ }
+ default: return GetGenericMaleTalkSfx(ped, sound);
+ }
return sfx;
}
uint32
-cAudioManager::GetCopTalkSfx(uint16 sound)
+cAudioManager::GetGenericMaleTalkSfx(CPed *ped, uint16 sound)
{
uint32 sfx;
- PedState pedState;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_ARREST_COP:
- GetPhrase(sfx, lastSfx, SFX_COP_VOICE_1_ARREST_1, 6);
- break;
- case SOUND_PED_PURSUIT_COP:
- 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);
- break;
- default:
- return GetGenericMaleTalkSfx(sound);
+ m_bGenericSfx = TRUE;
+ switch(sound) {
+ case SOUND_PED_DEATH: GetPhrase(sfx, ped->m_lastComment, SFX_GENERIC_MALE_DEATH_1, 41); break;
+ case SOUND_PED_BULLET_HIT:
+ case SOUND_PED_DEFEND: GetPhrase(sfx, ped->m_lastComment, SFX_GENERIC_MALE_GRUNT_1, 41); break;
+ case SOUND_PED_BURNING: GetPhrase(sfx, ped->m_lastComment, SFX_GENERIC_MALE_FIRE_1, 32); break;
+ case SOUND_PED_FLEE_SPRINT: GetPhrase(sfx, ped->m_lastComment, SFX_GENERIC_MALE_PANIC_1, 35); break;
+ default: return NO_SAMPLE;
}
+ return sfx;
+}
- return (SFX_COP_VOICE_2_ARREST_1 - SFX_COP_VOICE_1_ARREST_1) * (m_sQueueSample.m_nEntityIndex % 5) + sfx;
+uint32
+cAudioManager::GetGenericFemaleTalkSfx(CPed *ped, uint16 sound)
+{
+ uint32 sfx;
+ m_bGenericSfx = TRUE;
+ switch(sound) {
+ case SOUND_PED_DEATH: GetPhrase(sfx, ped->m_lastComment, SFX_GENERIC_FEMALE_DEATH_1, 22); break;
+ case SOUND_PED_BULLET_HIT:
+ case SOUND_PED_DEFEND: GetPhrase(sfx, ped->m_lastComment, SFX_GENERIC_FEMALE_GRUNT_1, 33); break;
+ case SOUND_PED_BURNING: GetPhrase(sfx, ped->m_lastComment, SFX_GENERIC_FEMALE_FIRE_1, 17); break;
+ case SOUND_PED_FLEE_SPRINT: GetPhrase(sfx, ped->m_lastComment, SFX_GENERIC_FEMALE_PANIC_1, 27); break;
+ default: return NO_SAMPLE;
+ }
+ return sfx;
}
uint32
-cAudioManager::GetSwatTalkSfx(uint16 sound)
+cAudioManager::GetDefaultTalkSfx(CPed *ped, uint16 sound)
{
uint32 sfx;
- PedState pedState;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_ARREST_SWAT:
- GetPhrase(sfx, lastSfx, SFX_SWAT_VOICE_1_CHASE_1, 6);
- break;
- case SOUND_PED_PURSUIT_SWAT:
- 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);
- break;
- default:
- return GetGenericMaleTalkSfx(sound);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_DEFAULT_VOICE_GUN_PANIC_1, 12); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_DEFAULT_VOICE_JACKED_1, 12); break;
+#ifdef FIX_BUGS
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, SFX_DEFAULT_VOICE_JACKING_1, 13); break;
+#endif
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_DEFAULT_VOICE_MUGGED_1, 4); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, SFX_DEFAULT_VOICE_SAVED_1, 4); break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, SFX_DEFAULT_VOICE_TAXI_1, 5); break;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_DEFAULT_VOICE_FIGHT_1, 16); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_DEFAULT_VOICE_DODGE_1, 19); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_DEFAULT_VOICE_RUN_1, 19); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_DEFAULT_VOICE_GENERIC_CRASH_1, 13); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_DEFAULT_VOICE_CAR_CRASH_1, 15); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_DEFAULT_VOICE_BLOCKED_1, 16); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_DEFAULT_VOICE_LOST_1, 5); break;
+#ifdef FIX_BUGS
+ case SOUND_PED_CHAT_SEXY_MALE: GetPhrase(sfx, ped->m_lastComment, SFX_DEFAULT_VOICE_EYEING_1, 6); break;
+#else
+ case SOUND_PED_CHAT_SEXY_FEMALE: GetPhrase(sfx, ped->m_lastComment, SFX_DEFAULT_VOICE_EYEING_1, 6); break;
+#endif
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_DEFAULT_VOICE_SHOCKED_1, 6); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_DEFAULT_VOICE_BUMP_1, 25); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_DEFAULT_VOICE_CHAT_1, 25); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
-
- return (SFX_SWAT_VOICE_2_CHASE_1 - SFX_SWAT_VOICE_1_CHASE_1) * (m_sQueueSample.m_nEntityIndex % 4) + sfx;
+ return sfx;
}
uint32
-cAudioManager::GetFBITalkSfx(uint16 sound)
+cAudioManager::GetCopTalkSfx(CPed *ped, uint16 sound)
{
uint32 sfx;
- PedState pedState;
- static uint32 lastSfx = NO_SAMPLE;
-
- switch (sound) {
- case SOUND_PED_ARREST_FBI:
- GetPhrase(sfx, lastSfx, SFX_FBI_VOICE_1_CHASE_1, 6);
- break;
- case SOUND_PED_PURSUIT_FBI:
- pedState = FindPlayerPed()->m_nPedState;
- if (pedState == PED_ARRESTED || pedState == PED_DEAD || pedState == PED_DIE)
+ PedState objective;
+ switch(sound) {
+ case SOUND_PED_ARREST_COP: GetPhrase(sfx, ped->m_lastComment, SFX_COP_VOICE_1_ARREST_1, 4); break;
+ case SOUND_PED_PULLOUTWEAPON: GetPhrase(sfx, ped->m_lastComment, SFX_COP_VOICE_1_PULLOUTWEAPON_1, 3); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, SFX_COP_VOICE_1_SAVED_1, 2); break;
+ case SOUND_PED_COP_TARGETING: GetPhrase(sfx, ped->m_lastComment, SFX_COP_VOICE_1_COP_TARGETING_1, 4); break;
+ case SOUND_PED_COP_MANYCOPSAROUND: GetPhrase(sfx, ped->m_lastComment, SFX_COP_VOICE_1_COP_MANYCOPSAROUND_1, 2); break;
+ case SOUND_PED_GUNAIMEDAT2: GetPhrase(sfx, ped->m_lastComment, SFX_COP_VOICE_1_GUNAIMEDAT2_1, 2); break;
+ case SOUND_PED_COP_ALONE: GetPhrase(sfx, ped->m_lastComment, SFX_COP_VOICE_1_COP_ALONE_1, 4); break;
+ case SOUND_PED_GUNAIMEDAT3: GetPhrase(sfx, ped->m_lastComment, SFX_COP_VOICE_1_GUNAIMEDAT2_1, 2); break;
+ case SOUND_PED_COP_ASK_FOR_ID: {
+ cooldown_phrase(4);
+ GetPhrase(sfx, ped->m_lastComment, SFX_COP_VOICE_1_COP_ASK_FOR_ID_1, 2);
+ break;
+ }
+ case SOUND_PED_COP_LITTLECOPSAROUND:
+ objective = FindPlayerPed()->m_nPedState;
+ if(objective == PED_ARRESTED || objective == PED_DEAD || objective == PED_DIE) return NO_SAMPLE;
+ GetPhrase(sfx, ped->m_lastComment, SFX_COP_VOICE_1_COP_LITTLECOPSAROUND_1, 4);
+ break;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_COP_VOICE_1_FIGHT_1, 4); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_COP_VOICE_1_DODGE_1, 3); break;
+#ifdef FIX_BUGS
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_COP_VOICE_1_CAR_CRASH_1, 4); break;
+#endif
+ case SOUND_PED_PED_COLLISION:
+ if(FindPlayerPed()->m_pWanted->GetWantedLevel() > 0)
+ GetPhrase(sfx, ped->m_lastComment, SFX_COP_VOICE_1_BUMP_1, 5);
+ else
return NO_SAMPLE;
- GetPhrase(sfx, lastSfx, SFX_FBI_VOICE_1_CHASE_1, 6);
break;
- default:
- return GetGenericMaleTalkSfx(sound);
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
-
- return (SFX_FBI_VOICE_2_CHASE_1 - SFX_FBI_VOICE_1_CHASE_1) * (m_sQueueSample.m_nEntityIndex % 3) + sfx;
+ return (SFX_COP_VOICE_2_ARREST_1 - SFX_COP_VOICE_1_ARREST_1) * (m_sQueueSample.m_nEntityIndex % 5) + sfx;
}
uint32
-cAudioManager::GetArmyTalkSfx(uint16 sound)
+cAudioManager::GetSwatTalkSfx(CPed *ped, uint16 sound)
{
uint32 sfx;
- PedState pedState;
- static uint32 lastSfx = NO_SAMPLE;
+ switch(sound) {
+ case SOUND_PED_COP_HELIPILOTPHRASE: GetPhrase(sfx, ped->m_lastComment, SFX_SWAT_VOICE_1_COP_HELIPILOTPHRASE_1, 7); break;
+ case SOUND_PED_COP_TARGETING: GetPhrase(sfx, ped->m_lastComment, SFX_SWAT_VOICE_1_COP_TARGETING_1, 4); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_SWAT_VOICE_1_DODGE_1, 3); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
+ }
+ sfx += (SFX_SWAT_VOICE_2_DODGE_1 - SFX_SWAT_VOICE_1_DODGE_1) * (m_sQueueSample.m_nEntityIndex % 3);
+ return sfx;
+}
+uint32
+cAudioManager::GetFBITalkSfx(CPed *ped, uint16 sound)
+{
+ uint32 sfx;
switch(sound) {
- case SOUND_PED_PURSUIT_ARMY:
- 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);
- break;
- default: return GetGenericMaleTalkSfx(sound);
+#ifdef FIX_BUGS
+ case SOUND_PED_COP_TARGETING: GetPhrase(sfx, ped->m_lastComment, SFX_FBI_VOICE_1_COP_TARGETING_1, 6); break;
+#else
+ case SOUND_PED_COP_TARGETING: GetPhrase(sfx, ped->m_lastComment, SFX_FBI_VOICE_1_COP_TARGETING_1, 4); break;
+#endif
+ case SOUND_PED_COP_MANYCOPSAROUND: GetPhrase(sfx, ped->m_lastComment, SFX_FBI_VOICE_1_COP_MANYCOPSAROUND_1, 3); break;
+ case SOUND_PED_GUNAIMEDAT2: sfx = SFX_FBI_VOICE_1_GUNAIMEDAT2_1; break;
+ case SOUND_PED_GUNAIMEDAT3: GetPhrase(sfx, ped->m_lastComment, SFX_FBI_VOICE_1_GUNAIMEDAT3_1, 4); break;
+ case SOUND_PED_CRASH_VEHICLE:
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_FBI_VOICE_1_CAR_CRASH_1, 4); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
+#ifdef FIX_BUGS
+ sfx += (SFX_FBI_VOICE_2_GUNAIMEDAT3_1 - SFX_FBI_VOICE_1_GUNAIMEDAT3_1) * (m_sQueueSample.m_nEntityIndex % 3);
+#else
+ sfx += 16 * (m_sQueueSample.m_nEntityIndex % 3);
+#endif
+ return sfx;
+}
- return (SFX_ARMY_VOICE_2_CHASE_1 - SFX_ARMY_VOICE_1_CHASE_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx;
+uint32
+cAudioManager::GetArmyTalkSfx(CPed *ped, uint16 sound)
+{
+ return GetGenericMaleTalkSfx(ped, sound);
}
uint32
-cAudioManager::GetMedicTalkSfx(uint16 sound)
+cAudioManager::GetMedicTalkSfx(CPed *ped, uint16 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);
+ switch(sound) {
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_MEDIC_VOICE_1_FIGHT_1, 6); break;
+ case SOUND_PED_HEALING: GetPhrase(sfx, ped->m_lastComment, SFX_MEDIC_VOICE_1_AT_VICTIM_1, 17); break;
+ case SOUND_PED_LEAVE_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_MEDIC_VOICE_1_GET_OUT_VAN_CHAT_1, 10); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
- return (SFX_MEDIC_VOICE_2_GUN_PANIC_1 - SFX_MEDIC_VOICE_1_GUN_PANIC_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx;
+ sfx += (SFX_MEDIC_VOICE_2_FIGHT_1 - SFX_MEDIC_VOICE_1_FIGHT_1) * (m_sQueueSample.m_nEntityIndex % 2);
+ return sfx;
}
uint32
-cAudioManager::GetFiremanTalkSfx(uint16 sound)
+cAudioManager::GetFiremanTalkSfx(CPed *ped, uint16 sound)
{
- return GetGenericMaleTalkSfx(sound);
+ return GetGenericMaleTalkSfx(ped, sound);
}
uint32
-cAudioManager::GetBusinessMaleOldTalkSfx(uint16 sound)
+cAudioManager::GetWFYG1TalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, SFX_WFYG1_GUN_COOL_1, 6); break;
+ case SOUND_PED_MUGGING: GetPhrase(sfx, ped->m_lastComment, SFX_WFYG1_MUGGING_1, 2); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_WFYG1_JACKED_1, 5); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_WFYG1_MUGGED_1, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return SFX_WFYG1_SAVED_1;
+ case SOUND_PED_TAXI_WAIT: return SFX_WFYG1_TAXI_1;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_WFYG1_FIGHT_1, 4); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_WFYG1_DODGE_1, 9); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_WFYG1_RUN_1, 2); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_WFYG1_GENERIC_CRASH_1, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_WFYG1_CAR_CRASH_1, 9); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_WFYG1_BLOCKED_1, 7); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_WFYG1_LOST_1, 3); break;
+ case SOUND_PED_CHAT_SEXY_FEMALE: GetPhrase(sfx, ped->m_lastComment, SFX_WFYG1_EYEING_1, 2); break;
+ case SOUND_PED_CHAT_EVENT: return SFX_WFYG1_SHOCKED_1;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_WFYG1_BUMP_1, 11); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_WFYG1_CHAT_1, 10); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetBusinessMaleYoungTalkSfx(uint16 sound, uint32 model)
+cAudioManager::GetWFYG2TalkSfx(CPed *ped, uint16 sound)
{
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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, SFX_WFYG2_GUN_COOL_1, 3); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_WFYG2_JACKED_1, 5); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_WFYG2_MUGGED_1, 2); break;
+#ifdef FIX_BUGS
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, SFX_WFYG2_TAXI_1, 2); break;
+#else
+ case SOUND_PED_TAXI_WAIT: return SFX_WFYG2_TAXI_1;
+#endif
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_WFYG2_FIGHT_1, 5); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_WFYG2_DODGE_1, 8); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_WFYG2_GENERIC_CRASH_1, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_WFYG2_CAR_CRASH_1, 9); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_WFYG2_BLOCKED_1, 5); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: return SFX_WFYG2_LOST_1;
+ case SOUND_PED_CHAT_SEXY_FEMALE: GetPhrase(sfx, ped->m_lastComment, SFX_WFYG2_EYEING_1, 4); break;
+ case SOUND_PED_CHAT_EVENT: return SFX_WFYG2_SHOCKED_1;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_WFYG2_BUMP_1, 11); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_WFYG2_CHAT_1, 9); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
- 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::GetMafiaTalkSfx(uint16 sound)
+cAudioManager::GetHFYSTTalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, SFX_HFYST_GUN_COOL_1, 5); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, SFX_HFYST_JACKING_1, 4); break;
+ case SOUND_PED_MUGGING: GetPhrase(sfx, ped->m_lastComment, SFX_HFYST_MUGGING_1, 4); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_HFYST_JACKED_1, 6); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_HFYST_MUGGED_1, 2); break;
+ case SOUND_PED_TAXI_WAIT: return SFX_HFYST_TAXI_1;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_HFYST_FIGHT_1, 7); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_HFYST_DODGE_1, 10); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_HFYST_GENERIC_CRASH_1, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_HFYST_CAR_CRASH_1, 8); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_HFYST_BLOCKED_1, 7); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_HFYST_LOST_1, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_HFYST_BUMP_1, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_HFYST_CHAT_1, 9); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
- return (SFX_MAFIA_MALE_VOICE_2_DRIVER_ABUSE_1 - SFX_MAFIA_MALE_VOICE_1_DRIVER_ABUSE_1) * (m_sQueueSample.m_nEntityIndex % 3) + sfx;
+ return sfx;
}
uint32
-cAudioManager::GetTriadTalkSfx(uint16 sound)
+cAudioManager::GetHFOSTTalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, SFX_HFOST_GUN_COOL_1, 6); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_HFOST_JACKED_1, 8); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_HFOST_MUGGED_1, 3); break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, SFX_HFOST_TAXI_1, 2); break;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_HFOST_FIGHT_1, 8); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_HFOST_DODGE_1, 10); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_HFOST_GENERIC_CRASH_1, 11); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_HFOST_CAR_CRASH_1, 8); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_HFOST_BLOCKED_1, 9); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_HFOST_LOST_1, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_HFOST_BUMP_1, 12); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_HFOST_CHAT_1, 11); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetDiabloTalkSfx(uint16 sound)
+cAudioManager::GetHMYSTTalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_HMYST_GUN_PANIC_1, 6); break;
+ case SOUND_PED_ACCIDENTREACTION1: return SFX_HMYST_SAVED_1;
+ case SOUND_PED_TAXI_WAIT: return SFX_HMYST_TAXI_1;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_HMYST_DODGE_1, 6); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_HMYST_RUN_1, 4); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_HMYST_GENERIC_CRASH_1, 7); break;
+ case SOUND_PED_CHAT_SEXY_MALE: GetPhrase(sfx, ped->m_lastComment, SFX_HMYST_EYEING_1, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_HMYST_SHOCKED_1, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_HMYST_BUMP_1, 13); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_HMYST_CHAT_1, 11); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
- return (SFX_DIABLO_MALE_VOICE_2_CHAT_1 - SFX_DIABLO_MALE_VOICE_1_CHAT_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx;
+ return sfx;
}
uint32
-cAudioManager::GetYakuzaTalkSfx(uint16 sound)
+cAudioManager::GetHMOSTTalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, SFX_HMOST_GUN_COOL_1, 5); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, SFX_HMOST_JACKING_1, 3); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_HMOST_JACKED_1, 6); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_HMOST_MUGGED_1, 2); break;
+ case SOUND_PED_TAXI_WAIT: return SFX_HMOST_TAXI_1;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_HMOST_FIGHT_1, 8); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_HMOST_DODGE_1, 9); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_HMOST_GENERIC_CRASH_1, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_HMOST_CAR_CRASH_1, 7); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_HMOST_BLOCKED_1, 7); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_HMOST_LOST_1, 2); break;
+ case SOUND_PED_CHAT_SEXY_MALE: return SFX_HMOST_EYEING_1;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_HMOST_BUMP_1, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_HMOST_CHAT_1, 11); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
- return (SFX_YAKUZA_MALE_VOICE_2_DRIVER_ABUSE_1 - SFX_YAKUZA_MALE_VOICE_1_DRIVER_ABUSE_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx;
+ return sfx;
}
uint32
-cAudioManager::GetYardieTalkSfx(uint16 sound)
+cAudioManager::GetHFYRITalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_HFYRI_GUN_PANIC_1, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_HFYRI_JACKED_1, 6); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_HFYRI_MUGGED_1, 4); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, SFX_HFYRI_SAVED_1, 2); break;
+ case SOUND_PED_TAXI_WAIT: return SFX_HFYRI_TAXI_1;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_HFYRI_DODGE_1, 10); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_HFYRI_RUN_1, 4); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_HFYRI_GENERIC_CRASH_1, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_HFYRI_CAR_CRASH_1, 8); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_HFYRI_BLOCKED_1, 8); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_HFYRI_LOST_1, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_HFYRI_SHOCKED_1, 3); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_HFYRI_BUMP_1, 9); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
- return (SFX_YARDIE_MALE_VOICE_2_DRIVER_ABUSE_1 - SFX_YARDIE_MALE_VOICE_1_DRIVER_ABUSE_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx;
+ return sfx;
}
uint32
-cAudioManager::GetColumbianTalkSfx(uint16 sound)
+cAudioManager::GetHFORITalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_HFORI_GUN_PANIC_1, 6); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_HFORI_JACKED_1, 9); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_HFORI_MUGGED_1, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return SFX_HFORI_SAVED_1;
+ case SOUND_PED_TAXI_WAIT: return SFX_HFORI_TAXI_1;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_HFORI_DODGE_1, 6); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_HFORI_RUN_1, 4); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_HFORI_GENERIC_CRASH_1, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_HFORI_CAR_CRASH_1, 7); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_HFORI_BLOCKED_1, 6); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_HFORI_LOST_1, 2); break;
+ case SOUND_PED_CHAT_SEXY_FEMALE: GetPhrase(sfx, ped->m_lastComment, SFX_HFORI_EYEING_1, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_HFORI_SHOCKED_1, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_HFORI_BUMP_1, 10); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
- return (SFX_COLUMBIAN_MALE_VOICE_2_DRIVER_ABUSE_1 - SFX_COLUMBIAN_MALE_VOICE_1_DRIVER_ABUSE_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx;
+ return sfx;
}
uint32
-cAudioManager::GetHoodTalkSfx(uint16 sound)
+cAudioManager::GetHMYRITalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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;
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_HMYRI_GUN_PANIC_1, 7); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, SFX_HMYRI_JACKING_1, 3); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_HMYRI_JACKED_1, 8); break;
+ case SOUND_PED_ROBBED: return SFX_HMYRI_MUGGED_1;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_HMYRI_FIGHT_1, 5); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_HMYRI_DODGE_1, 9); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_HMYRI_GENERIC_CRASH_1, 12); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_HMYRI_CAR_CRASH_1, 8); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_HMYRI_BLOCKED_1, 7); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_HMYRI_SHOCKED_1, 3); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_HMYRI_BUMP_1, 10); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
- return (SFX_HOOD_MALE_VOICE_2_DRIVER_ABUSE_1 - SFX_HOOD_MALE_VOICE_1_DRIVER_ABUSE_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx;
+ return sfx;
}
uint32
-cAudioManager::GetBlackCriminalTalkSfx(uint16 sound)
+cAudioManager::GetHMORITalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- GetPhrase(sfx, lastSfx, SFX_BLACK_CRIMINAL_VOICE_1_DRIVER_ABUSE_1, 5);
- break;
- default:
- return GetGenericMaleTalkSfx(sound);
- break;
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_HMORI_GUN_PANIC_1, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_HMORI_JACKED_1, 8); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_HMORI_MUGGED_1, 3); break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, SFX_HMORI_TAXI_1, 2); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_HMORI_DODGE_1, 7); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_HMORI_RUN_1, 6); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_HMORI_GENERIC_CRASH_1, 11); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_HMORI_CAR_CRASH_1, 6); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_HMORI_BLOCKED_1, 8); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_HMORI_LOST_1, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_HMORI_BUMP_1, 11); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_HMORI_CHAT_1, 8); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetWhiteCriminalTalkSfx(uint16 sound)
+cAudioManager::GetHFYBETalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- GetPhrase(sfx, lastSfx, SFX_WHITE_CRIMINAL_VOICE_1_DRIVER_ABUSE_1, 4);
- break;
- default:
- return GetGenericMaleTalkSfx(sound);
- break;
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_HFYBE_GUN_PANIC_1, 7); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_HFYBE_JACKED_1, 7); break;
+ case SOUND_PED_TAXI_WAIT: return SFX_HFYBE_TAXI_1;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_HFYBE_DODGE_1, 11); break;
+#ifdef FIX_BUGS // assumption
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_HFYBE_RUN_1, 7); break;
+#endif
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_HFYBE_GENERIC_CRASH_1, 8); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_HFYBE_CAR_CRASH_1, 6); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_HFYBE_LOST_1, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_HFYBE_SHOCKED_1, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_HFYBE_BUMP_1, 8); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_HFYBE_CHAT_1, 10); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetCasualMaleOldTalkSfx(uint16 sound)
+cAudioManager::GetHFOBETalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_HFOBE_GUN_PANIC_1, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_HFOBE_JACKED_1, 6); break;
+ case SOUND_PED_ACCIDENTREACTION1: return SFX_HFOBE_SAVED_1;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, SFX_HFOBE_TAXI_1, 2); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_HFOBE_DODGE_1, 7); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_HFOBE_RUN_1, 4); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_HFOBE_GENERIC_CRASH_1, 5); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_HFOBE_CAR_CRASH_1, 6); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_HFOBE_BLOCKED_1, 6); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_HFOBE_LOST_1, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_HFOBE_SHOCKED_1, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_HFOBE_BUMP_1, 11); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_HFOBE_CHAT_1, 10); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetCasualMaleYoungTalkSfx(uint16 sound)
+cAudioManager::GetHMYBETalkSfx(CPed *ped, uint16 sound)
{
- return GetGenericMaleTalkSfx(sound);
+ uint32 sfx;
+
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_HMYBE_GUN_PANIC_1, 6); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_HMYBE_JACKED_1, 12); break;
+ case SOUND_PED_ACCIDENTREACTION1: return SFX_HMYBE_SAVED_1;
+ case SOUND_PED_INNOCENT: GetPhrase(sfx, ped->m_lastComment, SFX_HMYBE_INNOCENT_1, 4); break;
+ case SOUND_PED_TAXI_WAIT: return SFX_HMYBE_TAXI_1;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_HMYBE_FIGHT_1, 8); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_HMYBE_DODGE_1, 7); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_HMYBE_GENERIC_CRASH_1, 10); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_HMYBE_CAR_CRASH_1, 7); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_HMYBE_LOST_1, 3); break;
+ case SOUND_PED_CHAT_SEXY_MALE: GetPhrase(sfx, ped->m_lastComment, SFX_HMYBE_EYEING_1, 5); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_HMYBE_SHOCKED_1, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_HMYBE_BUMP_1, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_HMYBE_CHAT_1, 10); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
+ }
+ return sfx;
}
uint32
-cAudioManager::GetBlackCasualFemaleTalkSfx(uint16 sound)
+cAudioManager::GetHMOBETalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_HMOBE_GUN_PANIC_1, 3); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_HMOBE_JACKED_1, 6); break;
+ case SOUND_PED_INNOCENT: GetPhrase(sfx, ped->m_lastComment, SFX_HMOBE_INNOCENT_1, 3); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_HMOBE_DODGE_1, 9); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_HMOBE_BLOCKED_1, 10); break;
+ case SOUND_PED_CHAT_SEXY_MALE: GetPhrase(sfx, ped->m_lastComment, SFX_HMOBE_EYEING_1, 4); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_HMOBE_BUMP_1, 8); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
+
return sfx;
}
uint32
-cAudioManager::GetWhiteCasualFemaleTalkSfx(uint16 sound)
+cAudioManager::GetHFYBUTalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_HFYBU_GUN_PANIC_1, 5); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, SFX_HFYBU_JACKING_1, 3); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_HFYBU_JACKED_1, 6); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_HFYBU_MUGGED_1, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return SFX_HFYBU_SAVED_1;
+ case SOUND_PED_TAXI_WAIT: return SFX_HFYBU_TAXI_1;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_HFYBU_FIGHT_1, 7); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_HFYBU_DODGE_1, 10); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_HFYBU_GENERIC_CRASH_1, 12); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_HFYBU_CAR_CRASH_1, 8); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_HFYBU_BLOCKED_1, 8); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_HFYBU_LOST_1, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_HFYBU_BUMP_1, 11); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetFemaleNo3TalkSfx(uint16 sound)
+cAudioManager::GetHFYMDTalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_HFYMD_GUN_PANIC_1, 5); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_HFYMD_MUGGED_1, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, SFX_HFYMD_SAVED_1, 3); break;
+#ifdef FIX_BUGS
+ case SOUND_PED_TAXI_WAIT: return SFX_HFYMD_TAXI_1;
+#else
+ case SOUND_PED_TAXI_WAIT: return SFX_BFOBE_TAXI_1;
+#endif
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_HFYMD_FIGHT_1, 9); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_HFYMD_DODGE_1, 8); break;
+ case SOUND_PED_SOLICIT: GetPhrase(sfx, ped->m_lastComment, SFX_HFYMD_SOLICIT_1, 15); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_HFYMD_BUMP_1, 9); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetWhiteBusinessFemaleTalkSfx(uint16 sound, uint32 model)
+cAudioManager::GetHFYCGTalkSfx(CPed *ped, uint16 sound)
{
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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_HFYCG_GUN_PANIC_1, 5); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_HFYCG_MUGGED_1, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return SFX_HFYCG_SAVED_1;
+#ifdef FIX_BUGS
+ case SOUND_PED_TAXI_WAIT: return SFX_HFYCG_TAXI_1;
+#else
+ case SOUND_PED_TAXI_WAIT: return SFX_BFOBE_TAXI_1;
+#endif
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_HFYCG_DODGE_1, 8); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_HFYCG_RUN_1, 4); break;
+ case SOUND_PED_SOLICIT: GetPhrase(sfx, ped->m_lastComment, SFX_HFYCG_SOLICIT_1, 14); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_HFYCG_BUMP_1, 9); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
-
- 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::GetBlackFatFemaleTalkSfx(uint16 sound)
+cAudioManager::GetHFYPRTalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, SFX_HFYPR_GUN_COOL_1, 6); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_HFYPR_MUGGED_1, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return SFX_HFYPR_SAVED_1;
+ case SOUND_PED_PLAYER_BEFORESEX: GetPhrase(sfx, ped->m_lastComment, SFX_HFYPR_FUCKING_1, 8); break;
+ case SOUND_PED_TAXI_WAIT: return SFX_HFYPR_TAXI_1;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_HFYPR_FIGHT_1, 10); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_HFYPR_DODGE_1, 9); break;
+ case SOUND_PED_SOLICIT: GetPhrase(sfx, ped->m_lastComment, SFX_HFYPR_SOLICIT_1, 14); break;
+ case SOUND_PED_CHAT_SEXY_FEMALE: GetPhrase(sfx, ped->m_lastComment, SFX_HFYPR_EYEING_1, 3); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_HFYPR_BUMP_1, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_HFYPR_CHAT_1, 12); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetWhiteFatMaleTalkSfx(uint16 sound)
+cAudioManager::GetHFOTRTalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER: 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); break;
- default: return GetGenericMaleTalkSfx(sound);
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, SFX_HFOTR_GUN_COOL_1, 5); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_HFOTR_MUGGED_1, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return SFX_HFOTR_SAVED_1;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, SFX_HFOTR_TAXI_1, 2); break;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_HFOTR_FIGHT_1, 6); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_HFOTR_DODGE_1, 8); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_HFOTR_SHOCKED_1, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_HFOTR_BUMP_1, 11); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_HFOTR_CHAT_1, 12); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetBlackFatMaleTalkSfx(uint16 sound)
+cAudioManager::GetHMOTRTalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, SFX_HMOTR_GUN_COOL_1, 6); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, SFX_HMOTR_SAVED_1, 2); break;
+ case SOUND_PED_TAXI_WAIT: return SFX_HMOTR_TAXI_1;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_HMOTR_FIGHT_1, 7); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_HMOTR_DODGE_1, 11); break;
+ case SOUND_PED_SOLICIT: GetPhrase(sfx, ped->m_lastComment, SFX_HMOTR_SOLICIT_1, 8); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_HMOTR_SHOCKED_1, 3); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_HMOTR_BUMP_1, 8); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_HMOTR_CHAT_1, 9); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetWhiteFatFemaleTalkSfx(uint16 sound)
+cAudioManager::GetHMOCATalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_HMOCA_GUN_PANIC_1, 5); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, SFX_HMOCA_JACKING_1, 11); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_HMOCA_JACKED_1, 10); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_HMOCA_MUGGED_1, 7); break;
+ case SOUND_PED_TAXI_WAIT: return SFX_HMOCA_TAXI_1;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_HMOCA_RUN_1, 2); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_HMOCA_CAR_CRASH_1, 8); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_HMOCA_BLOCKED_1, 8); break;
+ case SOUND_PED_CHAT_SEXY_MALE: GetPhrase(sfx, ped->m_lastComment, SFX_HMOCA_EYEING_1, 2); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_HMOCA_CHAT_1, 10); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetBlackFemaleProstituteTalkSfx(uint16 sound)
+cAudioManager::GetBMYCRTalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, SFX_BMYCR_GUN_COOL_1, 6); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, SFX_BMYCR_JACKING_1, 12); break;
+ case SOUND_PED_MUGGING: GetPhrase(sfx, ped->m_lastComment, SFX_BMYCR_MUGGING_1, 6); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_BMYCR_JACKED_1, 6); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_BMYCR_MUGGED_1, 3); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, SFX_BMYCR_SAVED_1, 2); break;
+ case SOUND_PED_INNOCENT: GetPhrase(sfx, ped->m_lastComment, SFX_BMYCR_INNOCENT_1, 4); break;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_BMYCR_FIGHT_1, 8); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_BMYCR_DODGE_1, 8); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_BMYCR_GENERIC_CRASH_1, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_BMYCR_CAR_CRASH_1, 9); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_BMYCR_BLOCKED_1, 12); break;
+ case SOUND_PED_CHAT_SEXY_MALE: GetPhrase(sfx, ped->m_lastComment, SFX_BMYCR_EYEING_1, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_BMYCR_BUMP_1, 11); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
- return (SFX_BLACK_PROSTITUTE_VOICE_2_CHAT_1 - SFX_BLACK_PROSTITUTE_VOICE_1_CHAT_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx;
+ return sfx;
}
uint32
-cAudioManager::GetWhiteFemaleProstituteTalkSfx(uint16 sound)
+cAudioManager::GetBFYSTTalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_BFYST_GUN_PANIC_1, 4); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_BFYST_JACKED_1, 5); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_BFYST_MUGGED_1, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, SFX_BFYST_SAVED_1, 2); break;
+ case SOUND_PED_TAXI_WAIT: return SFX_BFYST_TAXI_1;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_BFYST_DODGE_1, 9); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_BFYST_RUN_1, 6); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_BFYST_GENERIC_CRASH_1, 8); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_BFYST_CAR_CRASH_1, 9); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_BFYST_BLOCKED_1, 8); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_BFYST_LOST_1, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_BFYST_BUMP_1, 9); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_BFYST_CHAT_1, 9); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
- return (SFX_WHITE_PROSTITUTE_VOICE_2_CHAT_1 - SFX_WHITE_PROSTITUTE_VOICE_1_CHAT_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx;
+ return sfx;
}
uint32
-cAudioManager::GetBlackProjectMaleTalkSfx(uint16 sound, uint32 model)
+cAudioManager::GetBFOSTTalkSfx(CPed *ped, uint16 sound)
{
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_ANNOYED_DRIVER: 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); break;
- default: return GetGenericMaleTalkSfx(sound);
- }
-
- if (model == MI_P_MAN2)
- sfx += (SFX_BLACK_PROJECT_MALE_VOICE_2_DRIVER_ABUSE_1 - SFX_BLACK_PROJECT_MALE_VOICE_1_DRIVER_ABUSE_1);
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_BFOST_GUN_PANIC_1, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_BFOST_JACKED_1, 8); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_BFOST_MUGGED_1, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, SFX_BFOST_SAVED_1, 2); break;
+ case SOUND_PED_TAXI_WAIT: return SFX_BFOST_TAXI_1;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_BFOST_DODGE_1, 11); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_BFOST_RUN_1, 4); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_BFOST_GENERIC_CRASH_1, 8); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_BFOST_CAR_CRASH_1, 8); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_BFOST_BLOCKED_1, 7); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_BFOST_LOST_1, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_BFOST_BUMP_1, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_BFOST_CHAT_1, 10); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
+ }
return sfx;
}
uint32
-cAudioManager::GetBlackProjectFemaleOldTalkSfx(uint16 sound)
+cAudioManager::GetBMYSTTalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, SFX_BMYST_GUN_COOL_1, 6); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, SFX_BMYST_JACKING_1, 4); break;
+ case SOUND_PED_MUGGING: GetPhrase(sfx, ped->m_lastComment, SFX_BMYST_MUGGING_1, 4); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_BMYST_JACKED_1, 8); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_BMYST_MUGGED_1, 2); break;
+#ifdef FIX_BUGS
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, SFX_BMYST_TAXI_1, 2); break;
+#else
+ case SOUND_PED_TAXI_WAIT: return SFX_BMYST_TAXI_1;
+#endif
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_BMYST_FIGHT_1, 6); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_BMYST_DODGE_1, 8); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_BMYST_GENERIC_CRASH_1, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_BMYST_CAR_CRASH_1, 9); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_BMYST_BLOCKED_1, 8); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_BMYST_BUMP_1, 11); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_BMYST_CHAT_1, 12); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetBlackProjectFemaleYoungTalkSfx(uint16 sound)
+cAudioManager::GetBMOSTTalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_BMOST_GUN_PANIC_1, 9); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_BMOST_MUGGED_1, 4); break;
+ case SOUND_PED_ACCIDENTREACTION1: return SFX_BMOST_SAVED_1;
+ case SOUND_PED_TAXI_WAIT: return SFX_BMOST_TAXI_1;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_BMOST_FIGHT_1, 7); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_BMOST_DODGE_1, 8); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_BMOST_GENERIC_CRASH_1, 13); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_BMOST_CAR_CRASH_1, 8); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_BMOST_LOST_1, 6); break;
+ case SOUND_PED_CHAT_SEXY_MALE: GetPhrase(sfx, ped->m_lastComment, SFX_BMOST_EYEING_1, 6); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_BMOST_BUMP_1, 17); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_BMOST_CHAT_1, 18); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetChinatownMaleOldTalkSfx(uint16 sound)
+cAudioManager::GetBFYRITalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_BFYRI_GUN_PANIC_1, 4); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, SFX_BFYRI_JACKING_1, 4); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_BFYRI_JACKED_1, 8); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_BFYRI_MUGGED_1, 3); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, SFX_BFYRI_SAVED_1, 2); break;
+ case SOUND_PED_TAXI_WAIT: return SFX_BFYRI_TAXI_1;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_BFYRI_DODGE_1, 8); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_BFYRI_RUN_1, 6); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_BFYRI_GENERIC_CRASH_1, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_BFYRI_CAR_CRASH_1, 8); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_BFYRI_BLOCKED_1, 9); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_BFYRI_LOST_1, 2); break;
+ case SOUND_PED_CHAT_SEXY_FEMALE: GetPhrase(sfx, ped->m_lastComment, SFX_BFYRI_EYEING_1, 3); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_BFYRI_SHOCKED_1, 4); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_BFYRI_BUMP_1, 9); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetChinatownMaleYoungTalkSfx(uint16 sound)
+cAudioManager::GetBFORITalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_BFORI_GUN_PANIC_1, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_BFORI_JACKED_1, 4); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_BFORI_MUGGED_1, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return SFX_BFORI_SAVED_1;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, SFX_BFORI_TAXI_1, 2); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_BFORI_DODGE_1, 9); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_BFORI_RUN_1, 4); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_BFORI_GENERIC_CRASH_1, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_BFORI_CAR_CRASH_1, 7); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_BFORI_BLOCKED_1, 8); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_BFORI_LOST_1, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_BFORI_SHOCKED_1, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_BFORI_BUMP_1, 9); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetChinatownFemaleOldTalkSfx(uint16 sound)
+cAudioManager::GetBMYRITalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_BMYRI_GUN_PANIC_1, 7); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_BMYRI_JACKED_1, 4); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_BMYRI_MUGGED_1, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return SFX_BMYRI_SAVED_1;
+ case SOUND_PED_TAXI_WAIT: return SFX_BMYRI_TAXI_1;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_BMYRI_DODGE_1, 8); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_BMYRI_RUN_1, 4); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_BMYRI_GENERIC_CRASH_1, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_BMYRI_CAR_CRASH_1, 7); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_BMYRI_BLOCKED_1, 6); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_BMYRI_LOST_1, 2); break;
+ case SOUND_PED_CHAT_SEXY_MALE: return SFX_BMYRI_EYEING_1;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_BMYRI_SHOCKED_1, 3); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_BMYRI_BUMP_1, 7); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetChinatownFemaleYoungTalkSfx(uint16 sound)
+cAudioManager::GetBFYBETalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, SFX_BFYBE_GUN_COOL_1, 6); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_BFYBE_JACKED_1, 8); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_BFYBE_MUGGED_1, 5); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, SFX_BFYBE_SAVED_1, 2); break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, SFX_BFYBE_TAXI_1, 3); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_BFYBE_DODGE_1, 10); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_BFYBE_RUN_1, 6); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_BFYBE_GENERIC_CRASH_1, 8); break;
+#ifdef FIX_BUGS
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_BFYBE_CAR_CRASH_1, 10); break;
+#else
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_BFYBE_CAR_CRASH_1, 8); break;
+#endif
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_BFYBE_BLOCKED_1, 12); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_BFYBE_LOST_1, 4); break;
+#ifdef FIX_BUGS
+ case SOUND_PED_CHAT_SEXY_FEMALE: GetPhrase(sfx, ped->m_lastComment, SFX_BFYBE_EYEING_1, 4); break;
+#else
+ case SOUND_PED_CHAT_SEXY_MALE: GetPhrase(sfx, ped->m_lastComment, SFX_BFYBE_EYEING_1, 4); break;
+#endif
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_BFYBE_SHOCKED_1, 4); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_BFYBE_CHAT_1, 16); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetLittleItalyMaleTalkSfx(uint16 sound)
+cAudioManager::GetBMYBETalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBE_GUN_COOL_1, 4); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBE_JACKING_1, 3); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBE_JACKED_1, 6); break;
+ case SOUND_PED_ROBBED: return SFX_BMYBE_MUGGED_1;
+ case SOUND_PED_ACCIDENTREACTION1: return SFX_BMYBE_SAVED_1;
+ case SOUND_PED_TAXI_WAIT: return SFX_BMYBE_TAXI_1;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBE_FIGHT_1, 8); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBE_DODGE_1, 10); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBE_GENERIC_CRASH_1, 8); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBE_CAR_CRASH_1, 8); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBE_BLOCKED_1, 8); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: return SFX_BMYBE_LOST_1;
+ case SOUND_PED_CHAT_SEXY_MALE: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBE_EYEING_1, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBE_BUMP_1, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBE_CHAT_1, 10); break;
+ default: return GetGenericMaleTalkSfx(ped, 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;
+ return sfx;
}
uint32
-cAudioManager::GetLittleItalyFemaleOldTalkSfx(uint16 sound)
+cAudioManager::GetBFOBETalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_BFOBE_GUN_PANIC_1, 5); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, SFX_BFOBE_JACKING_1, 4); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_BFOBE_JACKED_1, 5); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_BFOBE_MUGGED_1, 2); break;
+ case SOUND_PED_TAXI_WAIT: return SFX_BFOBE_TAXI_1;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_BFOBE_DODGE_1, 9); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_BFOBE_GENERIC_CRASH_1, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_BFOBE_CAR_CRASH_1, 7); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_BFOBE_BLOCKED_1, 8); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_BFOBE_SHOCKED_1, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_BFOBE_BUMP_1, 8); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_BFOBE_CHAT_1, 8); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetLittleItalyFemaleYoungTalkSfx(uint16 sound)
+cAudioManager::GetBMOBETalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_BMOBE_GUN_PANIC_1, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_BMOBE_JACKED_1, 6); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_BMOBE_MUGGED_1, 4); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, SFX_BMOBE_SAVED_1, 3); break;
+ case SOUND_PED_TAXI_WAIT: return SFX_BMOBE_TAXI_1;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_BMOBE_FIGHT_1, 10); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_BMOBE_DODGE_1, 11); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_BMOBE_GENERIC_CRASH_1, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_BMOBE_CAR_CRASH_1, 9); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_BMOBE_SHOCKED_1, 3); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_BMOBE_BUMP_1, 5); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_BMOBE_CHAT_1, 10); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetWhiteDockerMaleTalkSfx(uint16 sound)
+cAudioManager::GetBMYBUTalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBU_GUN_PANIC_1, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBU_JACKED_1, 6); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBU_MUGGED_1, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return SFX_BMYBU_SAVED_1;
+ case SOUND_PED_INNOCENT: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBU_INNOCENT_1, 2); break;
+ case SOUND_PED_TAXI_WAIT: return SFX_BMYBU_TAXI_1;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBU_FIGHT_1, 5); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBU_DODGE_1, 10); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBU_GENERIC_CRASH_1, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBU_CAR_CRASH_1, 7); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBU_BLOCKED_1, 8); break;
+ case SOUND_PED_CHAT_SEXY_MALE: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBU_EYEING_1, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBU_SHOCKED_1, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBU_BUMP_1, 7); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetBlackDockerMaleTalkSfx(uint16 sound)
+cAudioManager::GetBFYPRTalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, SFX_BFYPR_GUN_COOL_1, 5); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_BFYPR_MUGGED_1, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return SFX_BFYPR_SAVED_1;
+ case SOUND_PED_PLAYER_BEFORESEX: GetPhrase(sfx, ped->m_lastComment, SFX_BFYPR_FUCKING_1, 7); break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, SFX_BFYPR_TAXI_1, 2); break;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_BFYPR_FIGHT_1, 7); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_BFYPR_DODGE_1, 7); break;
+ case SOUND_PED_SOLICIT: GetPhrase(sfx, ped->m_lastComment, SFX_BFYPR_SOLICIT_1, 13); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_BFYPR_SHOCKED_1, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_BFYPR_BUMP_1, 11); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_BFYPR_CHAT_1, 13); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetScumMaleTalkSfx(uint16 sound)
+cAudioManager::GetBFOTRTalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, SFX_BFOTR_GUN_COOL_1, 6); break;
+ case SOUND_PED_MUGGING: GetPhrase(sfx, ped->m_lastComment, SFX_BFOTR_MUGGING_1, 3); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_BFOTR_MUGGED_1, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return SFX_BFOTR_SAVED_1;
+ case SOUND_PED_TAXI_WAIT: return SFX_BFOTR_TAXI_1;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_BFOTR_FIGHT_1, 6); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_BFOTR_DODGE_1, 9); break;
+ case SOUND_PED_SOLICIT: GetPhrase(sfx, ped->m_lastComment, SFX_BFOTR_SOLICIT_1, 5); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_BFOTR_SHOCKED_1, 3); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_BFOTR_BUMP_1, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_BFOTR_CHAT_1, 15); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetScumFemaleTalkSfx(uint16 sound)
+cAudioManager::GetBMOTRTalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, SFX_BMOTR_GUN_COOL_1, 5); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, SFX_BMOTR_SAVED_1, 1); break;
+ case SOUND_PED_INNOCENT: GetPhrase(sfx, ped->m_lastComment, SFX_BMOTR_INNOCENT_1, 4); break;
+ case SOUND_PED_TAXI_WAIT: return SFX_BMOTR_TAXI_1;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_BMOTR_DODGE_1, 11); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_BMOTR_RUN_1, 7); break;
+ case SOUND_PED_SOLICIT: GetPhrase(sfx, ped->m_lastComment, SFX_BMOTR_SOLICIT_1, 7); break;
+ case SOUND_PED_CHAT_SEXY_MALE: GetPhrase(sfx, ped->m_lastComment, SFX_BMOTR_EYEING_1, 3); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_BMOTR_BUMP_1, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_BMOTR_CHAT_1, 10); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetWhiteWorkerMaleTalkSfx(uint16 sound)
+cAudioManager::GetBMYPITalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, SFX_BMYPI_GUN_COOL_1, 5); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, SFX_BMYPI_JACKING_1, 4); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_BMYPI_JACKED_1, 6); break;
+ case SOUND_PED_ROBBED: return SFX_BMYPI_MUGGED_1;
+ case SOUND_PED_ACCIDENTREACTION1: return SFX_BMYPI_SAVED_1;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, SFX_BMYPI_TAXI_1, 2); break;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_BMYPI_FIGHT_1, 8); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_BMYPI_DODGE_1, 10); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_BMYPI_GENERIC_CRASH_1, 13); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_BMYPI_CAR_CRASH_1, 5); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_BMYPI_BLOCKED_1, 6); break;
+ case SOUND_PED_CHAT_SEXY_MALE: GetPhrase(sfx, ped->m_lastComment, SFX_BMYPI_EYEING_1, 4); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_BMYPI_BUMP_1, 9); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetBlackWorkerMaleTalkSfx(uint16 sound)
+cAudioManager::GetBMYBBTalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBB_GUN_COOL_1, 5); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBB_JACKING_1, 9); break;
+ case SOUND_PED_MUGGING: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBB_MUGGING_1, 8); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBB_JACKED_1, 11); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBB_MUGGED_1, 5); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBB_SAVED_1, 6); break;
+ case SOUND_PED_INNOCENT: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBB_INNOCENT_1, 4); break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBB_TAXI_1, 3); break;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBB_FIGHT_1, 12); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBB_DODGE_1, 18); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBB_GENERIC_CRASH_1, 9); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBB_CAR_CRASH_1, 9); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBB_BLOCKED_1, 13); break;
+ case SOUND_PED_JEER: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBB_JEER_1, 16); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBB_LOST_1, 2); break;
+ case SOUND_PED_CHAT_SEXY_MALE: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBB_EYEING_1, 16); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBB_SHOCKED_1, 6); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBB_BUMP_1, 17); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_BMYBB_CHAT_1, 21); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetBlackBusinessFemaleTalkSfx(uint16 sound)
+cAudioManager::GetWMYCRTalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, SFX_WMYCR_GUN_COOL_1, 5); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, SFX_WMYCR_JACKING_1, 6); break;
+ case SOUND_PED_MUGGING: GetPhrase(sfx, ped->m_lastComment, SFX_WMYCR_MUGGING_1, 5); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_WMYCR_MUGGED_1, 3); break;
+ case SOUND_PED_TAXI_WAIT: return SFX_WMYCR_TAXI_1;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_WMYCR_FIGHT_1, 7); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_WMYCR_DODGE_1, 10); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_WMYCR_GENERIC_CRASH_1, 9); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_WMYCR_CAR_CRASH_1, 9); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_WMYCR_BUMP_1, 18); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetSupermodelMaleTalkSfx(uint16 sound)
+cAudioManager::GetWFYSTTalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, SFX_WFYST_GUN_COOL_1, 5); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, SFX_WFYST_JACKING_1, 4); break;
+ case SOUND_PED_MUGGING: GetPhrase(sfx, ped->m_lastComment, SFX_WFYST_MUGGING_1, 4); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_WFYST_JACKED_1, 6); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_WFYST_MUGGED_1, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return SFX_WFYST_SAVED_1;
+ case SOUND_PED_TAXI_WAIT: return SFX_WFYST_TAXI_1;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_WFYST_FIGHT_1, 7); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_WFYST_DODGE_1, 10); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_WFYST_GENERIC_CRASH_1, 8); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_WFYST_CAR_CRASH_1, 8); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_WFYST_BLOCKED_1, 6); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: return SFX_WFYST_LOST_1;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_WFYST_BUMP_1, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_WFYST_CHAT_1, 10); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetSupermodelFemaleTalkSfx(uint16 sound)
+cAudioManager::GetWFYSKTalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_WFYSK_GUN_PANIC_1, 5); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_WFYSK_MUGGED_1, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, SFX_WFYSK_SAVED_1, 2); break;
+ case SOUND_PED_TAXI_WAIT: return SFX_WFYSK_TAXI_1;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_WFYSK_FIGHT_1, 11); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_WFYSK_DODGE_1, 9); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_WFYSK_BLOCKED_1, 11); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_WFYSK_BUMP_1, 18); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetStewardMaleTalkSfx(uint16 sound)
+cAudioManager::GetWMYSKTalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_WMYSK_GUN_PANIC_1, 5); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_WMYSK_MUGGED_1, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, SFX_WMYSK_SAVED_1, 2); break;
+ case SOUND_PED_INNOCENT: GetPhrase(sfx, ped->m_lastComment, SFX_WMYSK_INNOCENT_1, 3); break;
+ case SOUND_PED_TAXI_WAIT: return SFX_WMYSK_TAXI_1;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_WMYSK_FIGHT_1, 5); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_WMYSK_DODGE_1, 10); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_WMYSK_LOST_1, 2); break;
+ case SOUND_PED_CHAT_SEXY_MALE: GetPhrase(sfx, ped->m_lastComment, SFX_WMYSK_EYEING_1, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_WMYSK_SHOCKED_1, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_WMYSK_BUMP_1, 14); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_WMYSK_CHAT_1, 13); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetStewardFemaleTalkSfx(uint16 sound)
+cAudioManager::GetWFOSTTalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_WFOST_GUN_PANIC_1, 4); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_WFOST_JACKED_1, 8); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_WFOST_MUGGED_1, 5); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, SFX_WFOST_SAVED_1, 4); break;
+ case SOUND_PED_TAXI_WAIT: return SFX_WFOST_TAXI_1;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_WFOST_DODGE_1, 12); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_WFOST_RUN_1, 7); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_WFOST_GENERIC_CRASH_1, 10); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_WFOST_CAR_CRASH_1, 11); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_WFOST_BLOCKED_1, 12); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_WFOST_LOST_1, 3); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_WFOST_BUMP_1, 19); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_WFOST_CHAT_1, 16); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
- return (SFX_STEWARD_FEMALE_VOICE_2_DRIVER_ABUSE_1 - SFX_STEWARD_FEMALE_VOICE_1_DRIVER_ABUSE_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx;
+ return sfx;
}
uint32
-cAudioManager::GetFanMaleTalkSfx(uint16 sound, uint32 model)
+cAudioManager::GetWMYSTTalkSfx(CPed *ped, uint16 sound)
{
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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_WMYST_GUN_PANIC_1, 5); break;
+ case SOUND_PED_MUGGING: GetPhrase(sfx, ped->m_lastComment, SFX_WMYST_MUGGING_1, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_WMYST_JACKED_1, 5); break;
+ case SOUND_PED_ROBBED: return SFX_WMYST_MUGGED_1;
+ case SOUND_PED_ACCIDENTREACTION1: return SFX_WMYST_SAVED_1;
+ case SOUND_PED_INNOCENT: GetPhrase(sfx, ped->m_lastComment, SFX_WMYST_INNOCENT_1, 3); break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, SFX_WMYST_TAXI_1, 2); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_WMYST_DODGE_1, 10); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_WMYST_RUN_1, 7); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_WMYST_GENERIC_CRASH_1, 5); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_WMYST_CAR_CRASH_1, 8); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_WMYST_BLOCKED_1, 8); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_WMYST_LOST_1, 2); break;
+ case SOUND_PED_CHAT_SEXY_MALE: GetPhrase(sfx, ped->m_lastComment, SFX_WMYST_EYEING_1, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_WMYST_BUMP_1, 11); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_WMYST_CHAT_1, 10); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
-
- 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(uint16 sound)
+cAudioManager::GetWMOSTTalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, SFX_WMOST_GUN_COOL_1, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_WMOST_JACKED_1, 4); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_WMOST_MUGGED_1, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return SFX_WMOST_SAVED_1;
+ case SOUND_PED_INNOCENT: GetPhrase(sfx, ped->m_lastComment, SFX_WMOST_INNOCENT_1, 3); break;
+ case SOUND_PED_TAXI_WAIT: return SFX_WMOST_TAXI_1;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_WMOST_FIGHT_1, 8); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_WMOST_DODGE_1, 8); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_WMOST_GENERIC_CRASH_1, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_WMOST_CAR_CRASH_1, 7); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_WMOST_BLOCKED_1, 8); break;
+ case SOUND_PED_JEER: GetPhrase(sfx, ped->m_lastComment, SFX_WMOST_JEER_1, 4); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_WMOST_LOST_1, 2); break;
+ case SOUND_PED_CHAT_SEXY_MALE: GetPhrase(sfx, ped->m_lastComment, SFX_WMOST_EYEING_1, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_WMOST_BUMP_1, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_WMOST_CHAT_1, 9); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
- return (SFX_FOOTBALL_FEMALE_VOICE_2_DRIVER_ABUSE_1 - SFX_FOOTBALL_FEMALE_VOICE_1_DRIVER_ABUSE_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx;
+ return sfx;
}
uint32
-cAudioManager::GetHospitalMaleTalkSfx(uint16 sound)
+cAudioManager::GetWFYRITalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_WFYRI_GUN_PANIC_1, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_WFYRI_JACKED_1, 7); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_WFYRI_MUGGED_1, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return SFX_WFYRI_SAVED_1;
+ case SOUND_PED_TAXI_WAIT: return SFX_WFYRI_TAXI_1;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_WFYRI_DODGE_1, 9); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_WFYRI_RUN_1, 5); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_WFYRI_GENERIC_CRASH_1, 8); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_WFYRI_CAR_CRASH_1, 9); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_WFYRI_BLOCKED_1, 8); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_WFYRI_LOST_1, 2); break;
+ case SOUND_PED_CHAT_SEXY_FEMALE: GetPhrase(sfx, ped->m_lastComment, SFX_WFYRI_EYEING_1, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_WFYRI_SHOCKED_1, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_WFYRI_BUMP_1, 10); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetHospitalFemaleTalkSfx(uint16 sound)
+cAudioManager::GetWFORITalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_WFORI_GUN_PANIC_1, 6); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_WFORI_JACKED_1, 6); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_WFORI_MUGGED_1, 3); break;
+ case SOUND_PED_ACCIDENTREACTION1: return SFX_WFORI_SAVED_1;
+ case SOUND_PED_TAXI_WAIT: return SFX_WFORI_TAXI_1;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_WFORI_FIGHT_1, 7); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_WFORI_DODGE_1, 11); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_WFORI_GENERIC_CRASH_1, 8); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_WFORI_CAR_CRASH_1, 10); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_WFORI_BLOCKED_1, 7); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_WFORI_LOST_1, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_WFORI_SHOCKED_1, 3); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_WFORI_BUMP_1, 11); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetWhiteConstructionWorkerTalkSfx(uint16 sound)
+cAudioManager::GetWMYRITalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_WMYRI_GUN_PANIC_1, 8); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_WMYRI_JACKED_1, 8); break;
+ case SOUND_PED_ACCIDENTREACTION1: return SFX_WMYRI_SAVED_1;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, SFX_WMYRI_TAXI_1, 2); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_WMYRI_DODGE_1, 9); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_WMYRI_RUN_1, 5); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_WMYRI_GENERIC_CRASH_1, 11); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_WMYRI_CAR_CRASH_1, 9); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_WMYRI_BLOCKED_1, 10); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: return SFX_WMYRI_LOST_1;
+ case SOUND_PED_CHAT_SEXY_MALE: GetPhrase(sfx, ped->m_lastComment, SFX_WMYRI_EYEING_1, 3); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_WMYRI_SHOCKED_1, 4); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_WMYRI_BUMP_1, 8); break;
+#ifdef FIX_BUGS
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_WMYRI_CHAT_1, 10); break;
+#endif
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetBlackConstructionWorkerTalkSfx(uint16 sound)
+cAudioManager::GetWMORITalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_WMORI_GUN_PANIC_1, 9); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_WMORI_JACKED_1, 6); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_WMORI_MUGGED_1, 4); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, SFX_WMORI_SAVED_1, 2); break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, SFX_WMORI_TAXI_1, 2); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_WMORI_DODGE_1, 10); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_WMORI_RUN_1, 12); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_WMORI_GENERIC_CRASH_1, 8); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_WMORI_CAR_CRASH_1, 6); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_WMORI_BLOCKED_1, 10); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_WMORI_LOST_1, 2); break;
+ case SOUND_PED_CHAT_SEXY_MALE: GetPhrase(sfx, ped->m_lastComment, SFX_WMORI_EYEING_1, 3); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_WMORI_SHOCKED_1, 4); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_WMORI_BUMP_1, 14); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetShopperFemaleTalkSfx(uint16 sound, uint32 model)
+cAudioManager::GetWFYBETalkSfx(CPed *ped, uint16 sound)
{
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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_WFYBE_GUN_PANIC_1, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_WFYBE_JACKED_1, 4); break;
+ case SOUND_PED_ACCIDENTREACTION1: return SFX_WFYBE_SAVED_1;
+ case SOUND_PED_TAXI_WAIT: return SFX_WFYBE_TAXI_1;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_WFYBE_DODGE_1, 8); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_WFYBE_RUN_1, 5); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_WFYBE_GENERIC_CRASH_1, 6); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_WFYBE_CAR_CRASH_1, 6); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_WFYBE_BLOCKED_1, 7); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_WFYBE_SHOCKED_1, 3); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_WFYBE_BUMP_1, 11); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_WFYBE_CHAT_1, 10); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
+ return sfx;
+}
+
+uint32
+cAudioManager::GetWMYBETalkSfx(CPed *ped, uint16 sound)
+{
+ uint32 sfx;
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_WMYBE_GUN_PANIC_1, 8); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, SFX_WMYBE_JACKING_1, 3); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_WMYBE_JACKED_1, 7); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_WMYBE_DODGE_1, 12); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_WMYBE_RUN_1, 5); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_WMYBE_GENERIC_CRASH_1, 8); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_WMYBE_CAR_CRASH_1, 8); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_WMYBE_BLOCKED_1, 9); break;
+ case SOUND_PED_JEER: GetPhrase(sfx, ped->m_lastComment, SFX_WMYBE_JEER_1, 7); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_WMYBE_LOST_1, 3); break;
+ case SOUND_PED_CHAT_SEXY_MALE: GetPhrase(sfx, ped->m_lastComment, SFX_WMYBE_EYEING_1, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_WMYBE_SHOCKED_1, 6); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_WMYBE_BUMP_1, 14); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_WMYBE_CHAT_1, 11); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetStudentMaleTalkSfx(uint16 sound)
+cAudioManager::GetWFOBETalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_WFOBE_GUN_PANIC_1, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_WFOBE_JACKED_1, 4); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, SFX_WFOBE_SAVED_1, 3); break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, SFX_WFOBE_TAXI_1, 2); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_WFOBE_DODGE_1, 8); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_WFOBE_RUN_1, 7); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_WFOBE_GENERIC_CRASH_1, 10); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_WFOBE_CAR_CRASH_1, 7); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_WFOBE_BLOCKED_1, 8); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_WFOBE_SHOCKED_1, 3); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_WFOBE_BUMP_1, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_WFOBE_CHAT_1, 10); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetStudentFemaleTalkSfx(uint16 sound)
+cAudioManager::GetWMOBETalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_WMOBE_GUN_PANIC_1, 5); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, SFX_WMOBE_JACKING_1, 4); break;
+ case SOUND_PED_MUGGING: GetPhrase(sfx, ped->m_lastComment, SFX_WMOBE_MUGGING_1, 6); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_WMOBE_JACKED_1, 8); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, SFX_WMOBE_SAVED_1, 2); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_WMOBE_DODGE_1, 8); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_WMOBE_RUN_1, 4); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_WMOBE_GENERIC_CRASH_1, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_WMOBE_CAR_CRASH_1, 8); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_WMOBE_BLOCKED_1, 6); break;
+ case SOUND_PED_JEER: GetPhrase(sfx, ped->m_lastComment, SFX_WMOBE_JEER_1, 16); break;
+ case SOUND_PED_CHAT_SEXY_MALE: GetPhrase(sfx, ped->m_lastComment, SFX_WMOBE_EYEING_1, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_WMOBE_SHOCKED_1, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_WMOBE_BUMP_1, 12); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_WMOBE_CHAT_1, 10); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetSpecialCharacterTalkSfx(uint32 modelIndex, uint16 sound)
+cAudioManager::GetWMYCWTalkSfx(CPed *ped, uint16 sound)
{
- char *modelName = CModelInfo::GetModelInfo(modelIndex)->GetModelName();
- if (!CGeneral::faststricmp(modelName, "eight") || !CGeneral::faststricmp(modelName, "eight2")) {
- return GetEightBallTalkSfx(sound);
- }
- if (!CGeneral::faststricmp(modelName, "frankie")) {
- return GetSalvatoreTalkSfx(sound);
+ uint32 sfx;
+
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_WMYCW_GUN_PANIC_1, 6); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, SFX_WMYCW_JACKING_1, 4); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_WMYCW_JACKED_1, 6); break;
+ case SOUND_PED_ROBBED: return SFX_WMYCW_MUGGED_1;
+#ifdef FIX_BUGS
+ case SOUND_PED_INNOCENT: GetPhrase(sfx, ped->m_lastComment, SFX_WMYCW_INNOCENT_1, 3); break;
+#endif
+ case SOUND_PED_TAXI_WAIT: return SFX_WMYCW_TAXI_1;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_WMYCW_FIGHT_1, 8); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_WMYCW_DODGE_1, 10); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_WMYCW_GENERIC_CRASH_1, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_WMYCW_CAR_CRASH_1, 9); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_WMYCW_BLOCKED_1, 9); break;
+ case SOUND_PED_JEER: GetPhrase(sfx, ped->m_lastComment, SFX_WMYCW_JEER_1, 5); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_WMYCW_LOST_1, 2); break;
+ case SOUND_PED_CHAT_SEXY_MALE: GetPhrase(sfx, ped->m_lastComment, SFX_WMYCW_EYEING_1, 3); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_WMYCW_BUMP_1, 9); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_WMYCW_CHAT_1, 15); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
- if (!CGeneral::faststricmp(modelName, "misty")) {
- return GetMistyTalkSfx(sound);
+ return sfx;
+}
+
+uint32
+cAudioManager::GetWMYGOTalkSfx(CPed *ped, uint16 sound)
+{
+ uint32 sfx;
+
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_WMYGO_GUN_PANIC_1, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_WMYGO_JACKED_1, 6); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_WMYGO_MUGGED_1, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return SFX_WMYGO_SAVED_1;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, SFX_WMYGO_TAXI_1, 3); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_WMYGO_DODGE_1, 11); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_WMYGO_RUN_1, 6); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_WMYGO_GENERIC_CRASH_1, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_WMYGO_CAR_CRASH_1, 7); break;
+ case SOUND_PED_CHAT_SEXY_MALE: GetPhrase(sfx, ped->m_lastComment, SFX_WMYGO_EYEING_1, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_WMYGO_SHOCKED_1, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_WMYGO_BUMP_1, 9); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_WMYGO_CHAT_1, 10); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
- if (!CGeneral::faststricmp(modelName, "ojg") || !CGeneral::faststricmp(modelName, "ojg_p")) {
- return GetOldJapTalkSfx(sound);
+ return sfx;
+}
+
+uint32
+cAudioManager::GetWFOGOTalkSfx(CPed *ped, uint16 sound)
+{
+ uint32 sfx;
+
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_WFOGO_GUN_PANIC_1, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_WFOGO_JACKED_1, 6); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_WFOGO_MUGGED_1, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return SFX_WFOGO_SAVED_1;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_WFOGO_FIGHT_1, 14); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_WFOGO_DODGE_1, 9); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_WFOGO_RUN_1, 2); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_WFOGO_GENERIC_CRASH_1, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_WFOGO_CAR_CRASH_1, 8); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_WFOGO_SHOCKED_1, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_WFOGO_BUMP_1, 8); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_WFOGO_CHAT_1, 11); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
- if (!CGeneral::faststricmp(modelName, "cat")) {
- return GetCatalinaTalkSfx(sound);
+ return sfx;
+}
+
+uint32
+cAudioManager::GetWMOGOTalkSfx(CPed *ped, uint16 sound)
+{
+ uint32 sfx;
+
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_WMOGO_GUN_PANIC_1, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_WMOGO_JACKED_1, 6); break;
+ case SOUND_PED_ACCIDENTREACTION1: return SFX_WMOGO_SAVED_1;
+ case SOUND_PED_TAXI_WAIT: return SFX_WMOGO_TAXI_1;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_WMOGO_FIGHT_1, 13); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_WMOGO_DODGE_1, 12); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_WMOGO_RUN_1, 5); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_WMOGO_GENERIC_CRASH_1, 8); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_WMOGO_CAR_CRASH_1, 9); break;
+ case SOUND_PED_CHAT_SEXY_MALE: GetPhrase(sfx, ped->m_lastComment, SFX_WMOGO_EYEING_1, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_WMOGO_SHOCKED_1, 3); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_WMOGO_BUMP_1, 8); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_WMOGO_CHAT_1, 9); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
- if (!CGeneral::faststricmp(modelName, "bomber")) {
- return GetBomberTalkSfx(sound);
+ return sfx;
+}
+
+uint32
+cAudioManager::GetWFYLGTalkSfx(CPed *ped, uint16 sound)
+{
+ uint32 sfx;
+
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, SFX_WFYLG_GUN_COOL_1, 5); break;
+ case SOUND_PED_ACCIDENTREACTION1: return SFX_WFYLG_SAVED_1;
+ case SOUND_PED_TAXI_WAIT: return SFX_WFYLG_TAXI_1;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_WFYLG_FIGHT_1, 7); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_WFYLG_DODGE_1, 8); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_WFYLG_BUMP_1, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_WFYLG_CHAT_1, 10); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
- if (!CGeneral::faststricmp(modelName, "s_guard")) {
- return GetSecurityGuardTalkSfx(sound);
+ return sfx;
+}
+
+uint32
+cAudioManager::GetWMYLGTalkSfx(CPed *ped, uint16 sound)
+{
+ uint32 sfx;
+
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, SFX_WMYLG_GUN_COOL_1, 6); break;
+ case SOUND_PED_ACCIDENTREACTION1: return SFX_WMYLG_SAVED_1;
+ case SOUND_PED_TAXI_WAIT: return SFX_WMYLG_TAXI_1;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_WMYLG_FIGHT_1, 7); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_WMYLG_DODGE_1, 9); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_WMYLG_BUMP_1, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_WMYLG_CHAT_1, 10); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
- if (!CGeneral::faststricmp(modelName, "chunky")) {
- return GetChunkyTalkSfx(sound);
+ return sfx;
+}
+
+uint32
+cAudioManager::GetWFYBUTalkSfx(CPed *ped, uint16 sound)
+{
+ uint32 sfx;
+
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_WFYBU_GUN_PANIC_1, 8); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_WFYBU_JACKED_1, 8); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_WFYBU_MUGGED_1, 4); break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, SFX_WFYBU_TAXI_1, 2); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_WFYBU_RUN_1, 8); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_WFYBU_GENERIC_CRASH_1, 8); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_WFYBU_CAR_CRASH_1, 9); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_WFYBU_SHOCKED_1, 3); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_WFYBU_BUMP_1, 21); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
- if (!CGeneral::faststricmp(modelName, "asuka")) {
- return GetGenericFemaleTalkSfx(sound);
+ return sfx;
+}
+
+uint32
+cAudioManager::GetWMYBUTalkSfx(CPed *ped, uint16 sound)
+{
+ uint32 sfx;
+
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_WMYBU_GUN_PANIC_1, 6); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_WMYBU_JACKED_1, 5); break;
+ case SOUND_PED_ROBBED: return SFX_WMYBU_MUGGED_1;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, SFX_WMYBU_SAVED_1, 2); break;
+ case SOUND_PED_INNOCENT: GetPhrase(sfx, ped->m_lastComment, SFX_WMYBU_INNOCENT_1, 2); break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, SFX_WMYBU_TAXI_1, 2); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_WMYBU_DODGE_1, 10); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_WMYBU_RUN_1, 3); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_WMYBU_GENERIC_CRASH_1, 5); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_WMYBU_CAR_CRASH_1, 9); break;
+#ifdef FIX_BUGS
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_WMYBU_BLOCKED_1, 9); break;
+#else
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_WMOBE_BLOCKED_1, 6); break;
+#endif
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_WMYBU_LOST_1, 5); break;
+ case SOUND_PED_CHAT_SEXY_MALE: GetPhrase(sfx, ped->m_lastComment, SFX_WMYBU_EYEING_1, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_WMYBU_SHOCKED_1, 5); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_WMYBU_BUMP_1, 11); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_WMYBU_CHAT_1, 10); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
- if (!CGeneral::faststricmp(modelName, "maria")) {
- return GetGenericFemaleTalkSfx(sound);
+ return sfx;
+}
+
+uint32
+cAudioManager::GetWMOBUTalkSfx(CPed *ped, uint16 sound)
+{
+ uint32 sfx;
+
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_WMOBU_GUN_PANIC_1, 6); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_WMOBU_JACKED_1, 7); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_WMOBU_MUGGED_1, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, SFX_WMOBU_SAVED_1, 3); break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, SFX_WMOBU_TAXI_1, 2); break;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_WMOBU_FIGHT_1, 3); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_WMOBU_DODGE_1, 8); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_WMOBU_GENERIC_CRASH_1, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_WMOBU_CAR_CRASH_1, 7); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_WMOBU_BLOCKED_1, 7); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_WMOBU_LOST_1, 3); break;
+ case SOUND_PED_CHAT_SEXY_MALE: GetPhrase(sfx, ped->m_lastComment, SFX_WMOBU_EYEING_1, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_WMOBU_BUMP_1, 10); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
+ return sfx;
+}
- return GetGenericMaleTalkSfx(sound);
+uint32
+cAudioManager::GetWFYPRTalkSfx(CPed *ped, uint16 sound)
+{
+ uint32 sfx;
+
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, SFX_WFYPR_GUN_COOL_1, 6); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_WFYPR_MUGGED_1, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return SFX_WFYPR_SAVED_1;
+ case SOUND_PED_PLAYER_BEFORESEX: GetPhrase(sfx, ped->m_lastComment, SFX_WFYPR_FUCKING_1, 5); break;
+ case SOUND_PED_TAXI_WAIT: return SFX_WFYPR_TAXI_1;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_WFYPR_FIGHT_1, 9); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_WFYPR_DODGE_1, 10); break;
+ case SOUND_PED_SOLICIT: GetPhrase(sfx, ped->m_lastComment, SFX_WFYPR_SOLICIT_1, 15); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_WFYPR_BUMP_1, 11); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_WFYPR_CHAT_1, 14); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
+ }
+ return sfx;
}
uint32
-cAudioManager::GetEightBallTalkSfx(uint16 sound)
+cAudioManager::GetWFOTRTalkSfx(CPed *ped, uint16 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, SFX_WFOTR_GUN_COOL_1, 6); break;
+ case SOUND_PED_ACCIDENTREACTION1: return SFX_WFOTR_SAVED_1;
+ case SOUND_PED_TAXI_WAIT: return SFX_WFOTR_TAXI_1;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_WFOTR_DODGE_1, 9); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_WFOTR_RUN_1, 6); break;
+ case SOUND_PED_SOLICIT: GetPhrase(sfx, ped->m_lastComment, SFX_WFOTR_SOLICIT_1, 9); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_WFOTR_BUMP_1, 11); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_WFOTR_CHAT_1, 9); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetSalvatoreTalkSfx(uint16 sound)
+cAudioManager::GetWMOTRTalkSfx(CPed *ped, uint16 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, SFX_WMOTR_GUN_COOL_1, 5); break;
+ case SOUND_PED_ACCIDENTREACTION1: return SFX_WMOTR_SAVED_1;
+ case SOUND_PED_TAXI_WAIT: return SFX_WMOTR_TAXI_1;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_WMOTR_FIGHT_1, 6); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_WMOTR_DODGE_1, 17); break;
+ case SOUND_PED_SOLICIT: GetPhrase(sfx, ped->m_lastComment, SFX_WMOTR_SOLICIT_1, 7); break;
+ case SOUND_PED_CHAT_SEXY_MALE: GetPhrase(sfx, ped->m_lastComment, SFX_WMOTR_EYEING_1, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_WMOTR_SHOCKED_1, 3); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_WMOTR_BUMP_1, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_WMOTR_CHAT_1, 13); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetMistyTalkSfx(uint16 sound)
+cAudioManager::GetWMYPITalkSfx(CPed *ped, uint16 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;
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, SFX_WMYPI_GUN_COOL_1, 5); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, SFX_WMYPI_JACKING_1, 4); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_WMYPI_JACKED_1, 6); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_WMYPI_MUGGED_1, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, SFX_WMYPI_SAVED_1, 2); break;
+ case SOUND_PED_INNOCENT: GetPhrase(sfx, ped->m_lastComment, SFX_WMYPI_INNOCENT_1, 2); break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, SFX_WMYPI_TAXI_1, 4); break;
+#ifdef FIX_BUGS
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_WMYPI_FIGHT_1, 9); break;
+#else
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_WMYPI_FIGHT_1, 7); break;
+#endif
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_WMYPI_DODGE_1, 8); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_WMYPI_GENERIC_CRASH_1, 8); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_WMYPI_CAR_CRASH_1, 8); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_WMYPI_BLOCKED_1, 8); break;
+ case SOUND_PED_CHAT_SEXY_MALE: GetPhrase(sfx, ped->m_lastComment, SFX_WMYPI_EYEING_1, 6); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_WMYPI_BUMP_1, 10); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetOldJapTalkSfx(uint16 sound)
+cAudioManager::GetWMOCATalkSfx(CPed *ped, uint16 sound)
{
- return GetGenericMaleTalkSfx(sound);
+ uint32 sfx;
+
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_WMOCA_GUN_PANIC_1, 6); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, SFX_WMOCA_JACKING_1, 11); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_WMOCA_JACKED_1, 10); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_WMOCA_MUGGED_1, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return SFX_WMOCA_SAVED_1;
+ case SOUND_PED_TAXI_WAIT: return SFX_WMOCA_TAXI_1;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_WMOCA_FIGHT_1, 8); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_WMOCA_DODGE_1, 10); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_WMOCA_GENERIC_CRASH_1, 9); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_WMOCA_CAR_CRASH_1, 10); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_WMOCA_BLOCKED_1, 12); break;
+ case SOUND_PED_CHAT_SEXY_MALE: GetPhrase(sfx, ped->m_lastComment, SFX_WMOCA_EYEING_1, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_WMOCA_BUMP_1, 6); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
+ }
+ return sfx;
}
uint32
-cAudioManager::GetCatalinaTalkSfx(uint16 sound)
+cAudioManager::GetWFYSHTalkSfx(CPed *ped, uint16 sound)
{
- return GetGenericFemaleTalkSfx(sound);
+ uint32 sfx;
+
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, SFX_WFYSH_GUN_COOL_1, 9); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_WFYSH_MUGGED_1, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, SFX_WFYSH_SAVED_1, 4); break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, SFX_WFYSH_TAXI_1, 2); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_WFYSH_DODGE_1, 11); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_WFYSH_RUN_1, 11); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_WFYSH_LOST_1, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_WFYSH_SHOCKED_1, 5); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_WFYSH_BUMP_1, 12); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_WFYSH_CHAT_1, 10); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
+ }
+ return sfx;
}
uint32
-cAudioManager::GetBomberTalkSfx(uint16 sound)
+cAudioManager::GetWFOSHTalkSfx(CPed *ped, uint16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound)
- {
- case SOUND_PED_BOMBER:
- GetPhrase(sfx, lastSfx, SFX_BOMBERMAN_1, 7);
- break;
- default:
- return GetGenericMaleTalkSfx(sound);
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, SFX_WFOSH_GUN_COOL_1, 10); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_WFOSH_MUGGED_1, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, SFX_WFOSH_SAVED_1, 3); break;
+ case SOUND_PED_TAXI_WAIT: return SFX_WFOSH_TAXI_1;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_WFOSH_DODGE_1, 10); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_WFOSH_RUN_1, 9); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_WFOSH_LOST_1, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_WFOSH_SHOCKED_1, 5); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_WFOSH_BUMP_1, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_WFOSH_CHAT_1, 9); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetSecurityGuardTalkSfx(uint16 sound)
+cAudioManager::GetJFOTOTalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_JFOTO_GUN_PANIC_1, 4); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_JFOTO_JACKED_1, 5); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_JFOTO_MUGGED_1, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, SFX_JFOTO_SAVED_1, 2); break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, SFX_JFOTO_TAXI_1, 2); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_JFOTO_DODGE_1, 9); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_JFOTO_RUN_1, 5); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_JFOTO_GENERIC_CRASH_1, 6); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_JFOTO_CAR_CRASH_1, 8); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_JFOTO_BLOCKED_1, 8); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: return SFX_JFOTO_LOST_1;
+ case SOUND_PED_CHAT_EVENT: return SFX_JFOTO_SHOCKED_1;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_JFOTO_BUMP_1, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_JFOTO_CHAT_1, 13); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetChunkyTalkSfx(uint16 sound)
+cAudioManager::GetJMOTOTalkSfx(CPed *ped, uint16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound)
- {
- case SOUND_PED_DEATH:
- return SFX_CHUNKY_DEATH;
- case SOUND_PED_FLEE_RUN:
- GetPhrase(sfx, lastSfx, SFX_CHUNKY_RUN_1, 5);
- break;
- default:
- return GetGenericMaleTalkSfx(sound);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_JMOTO_GUN_PANIC_1, 4); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_JMOTO_JACKED_1, 4); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_JMOTO_MUGGED_1, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return SFX_JMOTO_SAVED_1;
+ case SOUND_PED_TAXI_WAIT: return SFX_JMOTO_TAXI_1;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_JMOTO_DODGE_1, 6); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_JMOTO_RUN_1, 4); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_JMOTO_GENERIC_CRASH_1, 6); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_JMOTO_CAR_CRASH_1, 6); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_JMOTO_BLOCKED_1, 8); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: return SFX_JMOTO_LOST_1;
+ case SOUND_PED_CHAT_EVENT: return SFX_JMOTO_SHOCKED_1;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_JMOTO_BUMP_1, 8); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_JMOTO_CHAT_1, 7); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
+ return sfx;
+}
+
+uint32
+cAudioManager::GetHNTalkSfx(CPed *ped, uint16 sound)
+{
+ uint32 sfx;
+
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, SFX_HAITIAN_GANG_1_GUN_COOL_1, 5); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, SFX_HAITIAN_GANG_1_JACKING_1, 4); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_HAITIAN_GANG_1_JACKED_1, 6); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_HAITIAN_GANG_1_MUGGED_1, 3); break;
+ case SOUND_PED_ACCIDENTREACTION1: sfx = SFX_HAITIAN_GANG_1_SAVED_1; break;
+ case SOUND_PED_TAXI_WAIT: sfx = SFX_HAITIAN_GANG_1_TAXI_1; break;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_HAITIAN_GANG_1_FIGHT_1, 10); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_HAITIAN_GANG_1_DODGE_1, 10); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_HAITIAN_GANG_1_GENERIC_CRASH_1, 9); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_HAITIAN_GANG_1_CAR_CRASH_1, 9); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_HAITIAN_GANG_1_BLOCKED_1, 9); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_HAITIAN_GANG_1_LOST_1, 4); break;
+ case SOUND_PED_CHAT_SEXY_MALE: GetPhrase(sfx, ped->m_lastComment, SFX_HAITIAN_GANG_1_EYEING_1, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_HAITIAN_GANG_1_BUMP_1, 12); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_HAITIAN_GANG_1_CHAT_1, 14); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
+ }
+ return (SFX_HAITIAN_GANG_2_BLOCKED_1 - SFX_HAITIAN_GANG_1_BLOCKED_1) * (m_sQueueSample.m_nEntityIndex % 3) + sfx;
+}
+
+uint32
+cAudioManager::GetBKTalkSfx(CPed *ped, uint16 sound)
+{
+ uint32 sfx;
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, SFX_BIKER_GANG_1_GUN_COOL_1, 5); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, SFX_BIKER_GANG_1_JACKING_1, 4); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_BIKER_GANG_1_JACKED_1, 8); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_BIKER_GANG_1_MUGGED_1, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: sfx = SFX_BIKER_GANG_1_SAVED_1; break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, SFX_BIKER_GANG_1_TAXI_1, 2); break;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_BIKER_GANG_1_FIGHT_1, 9); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_BIKER_GANG_1_DODGE_1, 9); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_BIKER_GANG_1_GENERIC_CRASH_1, 8); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_BIKER_GANG_1_BLOCKED_1, 10); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_BIKER_GANG_1_LOST_1, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_BIKER_GANG_1_BUMP_1, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_BIKER_GANG_1_CHAT_1, 12); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
+ }
+ return (SFX_BIKER_GANG_2_BLOCKED_1 - SFX_BIKER_GANG_1_BLOCKED_1) * (m_sQueueSample.m_nEntityIndex % 3) + sfx;
+}
+
+uint32
+cAudioManager::GetCBTalkSfx(CPed *ped, uint16 sound)
+{
+ uint32 sfx;
+
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, SFX_CUBAN_GANG_1_GUN_COOL_1, 5); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, SFX_CUBAN_GANG_1_JACKING_1, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_CUBAN_GANG_1_JACKED_1, 4); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_CUBAN_GANG_1_MUGGED_1, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: sfx = SFX_CUBAN_GANG_1_SAVED_1; break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, SFX_CUBAN_GANG_1_TAXI_1, 2); break;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_CUBAN_GANG_1_FIGHT_1, 9); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_CUBAN_GANG_1_DODGE_1, 9); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_CUBAN_GANG_1_GENERIC_CRASH_1, 8); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_CUBAN_GANG_1_CAR_CRASH_1, 8); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_CUBAN_GANG_1_BLOCKED_1, 8); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_CUBAN_GANG_1_LOST_1, 2); break;
+ case SOUND_PED_CHAT_SEXY_MALE: GetPhrase(sfx, ped->m_lastComment, SFX_CUBAN_GANG_1_EYEING_1, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_CUBAN_GANG_1_BUMP_1, 11); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_CUBAN_GANG_1_CHAT_1, 10); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
+ }
+ return (SFX_CUBAN_GANG_2_BLOCKED_1 - SFX_CUBAN_GANG_1_BLOCKED_1) * (m_sQueueSample.m_nEntityIndex % 3) + sfx;
+}
+
+uint32
+cAudioManager::GetSGTalkSfx(CPed *ped, uint16 sound)
+{
+ uint32 sfx;
+
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, SFX_STREET_GANG_1_GUN_COOL_1, 5); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, SFX_STREET_GANG_1_JACKING_1, 5); break;
+ case SOUND_PED_MUGGING: GetPhrase(sfx, ped->m_lastComment, SFX_STREET_GANG_1_MUGGING_1, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_STREET_GANG_1_JACKED_1, 5); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_STREET_GANG_1_MUGGED_1, 3); break;
+ case SOUND_PED_ACCIDENTREACTION1: sfx = SFX_STREET_GANG_1_SAVED_1; break;
+ case SOUND_PED_TAXI_WAIT: sfx = SFX_STREET_GANG_1_TAXI_1; break;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_STREET_GANG_1_FIGHT_1, 10); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_STREET_GANG_1_DODGE_1, 9); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_STREET_GANG_1_GENERIC_CRASH_1, 6); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_STREET_GANG_1_CAR_CRASH_1, 6); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_STREET_GANG_1_BLOCKED_1, 8); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_STREET_GANG_1_LOST_1, 2); break;
+ case SOUND_PED_CHAT_SEXY_MALE: GetPhrase(sfx, ped->m_lastComment, SFX_STREET_GANG_1_EYEING_1, 3); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_STREET_GANG_1_SHOCKED_1, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_STREET_GANG_1_BUMP_1, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_STREET_GANG_1_CHAT_1, 12); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
+ }
+ if(ped->GetModelIndex() == MI_SGB) sfx += (SFX_STREET_GANG_2_BLOCKED_1 - SFX_STREET_GANG_1_BLOCKED_1);
return sfx;
}
uint32
-cAudioManager::GetAsianTaxiDriverTalkSfx(uint16 sound)
+cAudioManager::GetCLTalkSfx(CPed *ped, uint16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_CAR_JACKED:
- GetPhrase(sfx, lastSfx, SFX_ASIAN_TAXI_DRIVER_VOICE_1_CARJACKED_1, 7);
- break;
- case SOUND_PED_ANNOYED_DRIVER:
- GetPhrase(sfx, lastSfx, SFX_ASIAN_TAXI_DRIVER_VOICE_1_DRIVER_ABUSE_1, 6);
- break;
- default:
- return GetGenericMaleTalkSfx(sound);
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, SFX_CUBAN_LORD_GANG_1_GUN_COOL_1, 5); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, SFX_CUBAN_LORD_GANG_1_JACKING_1, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_CUBAN_LORD_GANG_1_JACKED_1, 6); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_CUBAN_LORD_GANG_1_MUGGED_1, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: sfx = SFX_CUBAN_LORD_GANG_1_SAVED_1; break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, SFX_CUBAN_LORD_GANG_1_TAXI_1, 2); break;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_CUBAN_LORD_GANG_1_FIGHT_1, 10); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_CUBAN_LORD_GANG_1_DODGE_1, 13); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_CUBAN_LORD_GANG_1_GENERIC_CRASH_1, 8); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_CUBAN_LORD_GANG_1_CAR_CRASH_1, 10); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_CUBAN_LORD_GANG_1_BLOCKED_1, 10); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_CUBAN_LORD_GANG_1_LOST_1, 2); break;
+ case SOUND_PED_CHAT_SEXY_MALE: GetPhrase(sfx, ped->m_lastComment, SFX_CUBAN_LORD_GANG_1_EYEING_1, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_CUBAN_LORD_GANG_1_BUMP_1, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_CUBAN_LORD_GANG_1_CHAT_1, 10); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
+ }
+ return (SFX_CUBAN_LORD_GANG_2_BLOCKED_1 - SFX_CUBAN_LORD_GANG_1_BLOCKED_1) * (m_sQueueSample.m_nEntityIndex % 3) + sfx;
+}
+
+uint32
+cAudioManager::GetGDTalkSfx(CPed *ped, uint16 sound)
+{
+ uint32 sfx;
+
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, SFX_GUARD_DUTY_1_GUN_COOL_1, 6); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, SFX_GUARD_DUTY_1_SAVED_1, 2); break;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_GUARD_DUTY_1_FIGHT_1, 7); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_GUARD_DUTY_1_DODGE_1, 9); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_GUARD_DUTY_1_LOST_1, 2); break;
+ case SOUND_PED_CHAT_SEXY_MALE: GetPhrase(sfx, ped->m_lastComment, SFX_GUARD_DUTY_1_EYEING_1, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_GUARD_DUTY_1_SHOCKED_1, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_GUARD_DUTY_1_BUMP_1, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_GUARD_DUTY_1_CHAT_1, 10); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
+ return (SFX_GUARD_DUTY_2_BUMP_1 - SFX_GUARD_DUTY_1_BUMP_1) * (m_sQueueSample.m_nEntityIndex % 3) + sfx;
+}
+
+uint32
+cAudioManager::GetPGTalkSfx(CPed *ped, uint16 sound)
+{
+ uint32 sfx;
- 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;
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_GANG_1_GUN_COOL_1, 4); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_GANG_1_JACKING_1, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_GANG_1_JACKED_1, 5); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_GANG_1_MUGGED_1, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: sfx = SFX_PLAYER_GANG_1_SAVED_1; break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_GANG_1_TAXI_1, 2); break;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_GANG_1_FIGHT_1, 5); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_GANG_1_DODGE_1, 7); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_GANG_1_GENERIC_CRASH_1, 5); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_GANG_1_CAR_CRASH_1, 5); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_GANG_1_BLOCKED_1, 10); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_GANG_1_LOST_1, 2); break;
+ case SOUND_PED_CHAT_SEXY_MALE: GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_GANG_1_EYEING_1, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_GANG_1_SHOCKED_1, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_GANG_1_BUMP_1, 5); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_PLAYER_GANG_1_CHAT_1, 8); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
+ }
+ return (SFX_PLAYER_GANG_2_BLOCKED_1 - SFX_PLAYER_GANG_1_BLOCKED_1) * (m_sQueueSample.m_nEntityIndex % 3) + sfx;
}
uint32
-cAudioManager::GetPimpTalkSfx(uint16 sound)
+cAudioManager::GetViceWhiteTalkSfx(CPed *ped, uint16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
+ switch(sound) {
+ case SOUND_PED_ARREST_COP: GetPhrase(sfx, ped->m_lastComment, SFX_VICE_VOICE_1_ARREST_1, 3); break;
+ case SOUND_PED_MIAMIVICE_EXITING_CAR: sfx = SFX_VICE_VOICE_1_MIAMIVICE_EXITING_CAR_1; break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
+ }
+ sfx += (SFX_VICE_VOICE_2_ARREST_1-SFX_VICE_VOICE_1_ARREST_1) * (m_sQueueSample.m_nEntityIndex % 5);
+ return sfx;
+}
- 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_ANNOYED_DRIVER:
- 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);
+uint32
+cAudioManager::GetViceBlackTalkSfx(CPed *ped, uint16 sound)
+{
+ uint32 sfx;
+ switch(sound) {
+ case SOUND_PED_ARREST_COP: GetPhrase(sfx, ped->m_lastComment, SFX_VICE_VOICE_6_ARREST_1, 3); break;
+ case SOUND_PED_MIAMIVICE_EXITING_CAR: return SFX_VICE_VOICE_6_MIAMIVICE_EXITING_CAR_1;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetNormalMaleTalkSfx(uint16 sound)
+cAudioManager::GetBMODKTalkSfx(CPed *ped, uint16 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_ANNOYED_DRIVER:
- 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);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_BMODK_GUN_PANIC_1, 4); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_BMODK_JACKED_1, 9); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_BMODK_MUGGED_1, 2); break;
+ case SOUND_PED_INNOCENT: GetPhrase(sfx, ped->m_lastComment, SFX_BMODK_INNOCENT_1, 3); break;
+ case SOUND_PED_TAXI_WAIT: return SFX_BMODK_TAXI_1;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_BMODK_DODGE_1, 7); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_BMODK_RUN_1, 4); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_BMODK_GENERIC_CRASH_1, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_BMODK_CAR_CRASH_1, 10); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_BMODK_BLOCKED_1, 8); break;
+ case SOUND_PED_147: // this is some cut behaviour, the guy was selling something
+ GetPhrase(sfx, ped->m_lastComment, SFX_BMODK_UNK_147_1, 11);
+ // what is this? some sort of censorship?
+ switch(sfx) {
+ case SFX_BMODK_UNK_147_5:
+ case SFX_BMODK_UNK_147_6:
+ case SFX_BMODK_UNK_147_7: GetPhrase(sfx, ped->m_lastComment, SFX_BMODK_UNK_147_1, 4); break;
+ default: break;
+ }
break;
- default:
- return GetGenericMaleTalkSfx(sound);
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_BMODK_BUMP_1, 10); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetGenericMaleTalkSfx(uint16 sound)
+cAudioManager::GetHMYAPTalkSfx(CPed *ped, uint16 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;
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_HMYAP_GUN_PANIC_1, 7); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, SFX_HMYAP_JACKING_1, 4); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, SFX_HMYAP_JACKED_1, 7); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_HMYAP_MUGGED_1, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, SFX_HMYAP_SAVED_1, 2); break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, SFX_HMYAP_TAXI_1, 2); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_HMYAP_DODGE_1, 9); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_HMYAP_RUN_1, 6); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, SFX_HMYAP_GENERIC_CRASH_1, 6); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, SFX_HMYAP_CAR_CRASH_1, 9); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_HMYAP_BLOCKED_1, 9); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, SFX_HMYAP_LOST_1, 2); break;
+ case SOUND_PED_CHAT_SEXY_MALE: GetPhrase(sfx, ped->m_lastComment, SFX_HMYAP_EYEING_1, 3); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_HMYAP_BUMP_1, 11); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, SFX_HMYAP_CHAT_1, 9); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
+ }
+ return sfx;
+}
+
+uint32
+cAudioManager::GetWFYJGTalkSfx(CPed *ped, uint16 sound)
+{
+ uint32 sfx;
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_WFYJG_GUN_PANIC_1, 4); break;
+ case SOUND_PED_ACCIDENTREACTION1: sfx = SFX_WFYJG_SAVED_1; break;
+ case SOUND_PED_TAXI_WAIT: sfx = SFX_WFYJG_TAXI_1; break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, SFX_WFYJG_DODGE_1, 8); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_WFYJG_RUN_1, 6); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_WFYJG_BUMP_1, 12); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetGenericFemaleTalkSfx(uint16 sound)
+cAudioManager::GetWMYJGTalkSfx(CPed *ped, uint16 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;
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, SFX_WMYJG_GUN_PANIC_1, 4); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, SFX_WMYJG_MUGGED_1, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return SFX_WMYJG_SAVED_1;
+ case SOUND_PED_TAXI_WAIT: return SFX_WMYJG_TAXI_1;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, SFX_WMYJG_RUN_1, 5); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, SFX_WMYJG_BLOCKED_1, 10); break;
+ case SOUND_PED_CHAT_SEXY_MALE: GetPhrase(sfx, ped->m_lastComment, SFX_WMYJG_EYEING_1, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, SFX_WMYJG_BUMP_1, 10); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
+uint32
+cAudioManager::GetSpecialCharacterTalkSfx(CPed *ped, int32 model, uint16 sound)
+{
+ return NO_SAMPLE;
+}
+
+void
+cAudioManager::DebugPlayPedComment(int32 sound)
+{
+ tPedComment pedComment;
+
+ pedComment.m_nSampleIndex = sound;
+ pedComment.m_nProcess = 10;
+ pedComment.m_nEntityIndex = 0;
+ pedComment.m_fDistance = 0.0f;
+ pedComment.m_nVolume = 99;
+#if defined(EXTERNAL_3D_SOUND) && defined(FIX_BUGS)
+ pedComment.m_nEmittingVolume = 99;
+#endif
+
+ pedComment.m_vecPos = CWorld::Players[0].m_pPed->GetPosition();
+
+ m_sPedComments.Add(&pedComment);
+}
+
void
cPedComments::Add(tPedComment *com)
{
@@ -6039,65 +7872,77 @@ cPedComments::Add(tPedComment *com)
void
cPedComments::Process()
{
- int sampleIndex;
+ uint32 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 = SFX_BANK_PED_COMMENTS;
- AudioManager.m_sQueueSample.m_nReleasingVolumeModificator = 3;
- AudioManager.m_sQueueSample.m_nVolume = m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]].m_nVolume;
- AudioManager.m_sQueueSample.m_fDistance = m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]].m_fDistance;
- AudioManager.m_sQueueSample.m_nLoopCount = 1;
+ bool8 prevUsed = FALSE;
+ static uint8 counter = 0;
+ static int32 prevSamples[10];
+
+ if(AudioManager.m_nUserPause != 0) return;
+
+ if(m_nCommentsInBank[m_nActiveBank]) {
+ for(int i = 0; i < ARRAY_SIZE(prevSamples); i++) {
+ if(m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]].m_nSampleIndex ==
+ prevSamples[(counter + 1 + i) % ARRAY_SIZE(prevSamples)]) {
+ m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]].m_nProcess = -1;
+ prevUsed = TRUE;
+ break;
+ }
+ }
+ if(!prevUsed) {
+ sampleIndex = m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]].m_nSampleIndex;
+ if(!SampleManager.IsPedCommentLoaded(sampleIndex)) {
+#if defined(GTA_PC) && !defined(FIX_BUGS)
+ if(!m_bDelay)
+#endif
+ SampleManager.LoadPedComment(sampleIndex);
+ } else {
+ 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 = SFX_BANK_PED_COMMENTS;
+ AudioManager.m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ AudioManager.m_sQueueSample.m_nVolume = m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]].m_nVolume;
+ AudioManager.m_sQueueSample.m_fDistance = m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]].m_fDistance;
+ AudioManager.m_sQueueSample.m_nLoopCount = 1;
#ifndef GTA_PS2
- AudioManager.m_sQueueSample.m_nLoopStart = 0;
- AudioManager.m_sQueueSample.m_nLoopEnd = -1;
-#endif // !GTA_PS2
+ AudioManager.m_sQueueSample.m_nLoopStart = 0;
+ AudioManager.m_sQueueSample.m_nLoopEnd = -1;
+#endif
#ifdef EXTERNAL_3D_SOUND
#ifdef FIX_BUGS
- AudioManager.m_sQueueSample.m_nEmittingVolume = m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]].m_nEmittingVolume;
+ AudioManager.m_sQueueSample.m_nEmittingVolume = m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]].m_nEmittingVolume;
#else
- AudioManager.m_sQueueSample.m_nEmittingVolume = MAX_VOLUME;
+ AudioManager.m_sQueueSample.m_nEmittingVolume = MAX_VOLUME;
#endif // FIX_BUGS
#endif // EXTERNAL_3D_SOUND
- 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_SoundIntensity = 400.0f;
- break;
- default:
- AudioManager.m_sQueueSample.m_SoundIntensity = 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_fSpeedMultiplier = 3.0f;
+ AudioManager.m_sQueueSample.m_SoundIntensity = 40.0f;
+ AudioManager.m_sQueueSample.m_bReleasingSoundFlag = TRUE;
+ AudioManager.m_sQueueSample.m_vecPos = m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]].m_vecPos;
+ AudioManager.m_sQueueSample.m_bReverbFlag = TRUE;
+ AudioManager.m_sQueueSample.m_bRequireReflection = TRUE;
+ AudioManager.m_sQueueSample.m_bIs2D = FALSE;
+#ifdef FIX_BUGS
+ if (sampleIndex >= SFX_PLAYER_ANGRY_BUSTED_1 && sampleIndex < TOTAL_AUDIO_SAMPLES) { // check if player sfx
+ AudioManager.m_sQueueSample.m_bIs2D = TRUE;
+ AudioManager.m_sQueueSample.m_nOffset = 63;
+ }
+#endif // FIX_BUGS
+ 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;
+ prevSamples[counter++] = sampleIndex;
+ if(counter == 10) counter = 0;
+ AudioManager.AddSampleToRequestedQueue();
+#if defined(GTA_PC) && !defined(FIX_BUGS)
+ m_nDelayTimer = CTimer::GetTimeInMilliseconds();
+ m_bDelay = TRUE;
+#endif
+ }
}
-
- 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
@@ -6120,8 +7965,14 @@ cPedComments::Process()
m_nIndexMap[actualUsedBank][i] = NUM_PED_COMMENTS_SLOTS;
}
m_nCommentsInBank[actualUsedBank] = 0;
+#if defined(GTA_PC) && !defined(FIX_BUGS)
+ if(m_bDelay)
+ if(CTimer::GetTimeInMilliseconds() - m_nDelayTimer > 6000) m_bDelay = FALSE;
+#endif
}
+#undef cooldown_phrase
+
#pragma endregion
#pragma endregion All the ped audio code
@@ -6130,11 +7981,10 @@ 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) {
+ if (CExplosion::DoesExplosionMakeSound(i) && CExplosion::GetExplosionActiveCounter(i) == 1) {
CExplosion::ResetExplosionActiveCounter(i);
type = CExplosion::GetExplosionType(i);
switch (type) {
@@ -6142,39 +7992,41 @@ cAudioManager::ProcessExplosions(int32 explosion)
case EXPLOSION_ROCKET:
case EXPLOSION_BARREL:
case EXPLOSION_TANK_GRENADE:
- m_sQueueSample.m_SoundIntensity = 400.0f;
+ m_sQueueSample.m_SoundIntensity = 200.0f;
m_sQueueSample.m_nSampleIndex = SFX_EXPLOSION_2;
- m_sQueueSample.m_nFrequency = RandomDisplacement(2000) + 38000;
+ m_sQueueSample.m_nFrequency = RandomDisplacement(1000) + 19000;
m_sQueueSample.m_nReleasingVolumeModificator = 0;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_bRequireReflection = TRUE;
break;
case EXPLOSION_MOLOTOV:
- m_sQueueSample.m_SoundIntensity = 200.0f;
+ m_sQueueSample.m_SoundIntensity = 150.0f;
m_sQueueSample.m_nSampleIndex = SFX_EXPLOSION_3;
m_sQueueSample.m_nFrequency = RandomDisplacement(1000) + 19000;
m_sQueueSample.m_nReleasingVolumeModificator = 0;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_bRequireReflection = FALSE;
break;
case EXPLOSION_MINE:
case EXPLOSION_HELI_BOMB:
- m_sQueueSample.m_SoundIntensity = 300.0f;
+ m_sQueueSample.m_SoundIntensity = 200.0f;
m_sQueueSample.m_nSampleIndex = SFX_ROCKET_LEFT;
m_sQueueSample.m_nFrequency = RandomDisplacement(1000) + 12347;
m_sQueueSample.m_nReleasingVolumeModificator = 0;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_bRequireReflection = TRUE;
break;
default:
- m_sQueueSample.m_SoundIntensity = 400.0f;
+ m_sQueueSample.m_SoundIntensity = 200.0f;
m_sQueueSample.m_nSampleIndex = SFX_EXPLOSION_1;
- m_sQueueSample.m_nFrequency = RandomDisplacement(2000) + 38000;
+ m_sQueueSample.m_nFrequency = RandomDisplacement(1000) + 19500;
if (type == EXPLOSION_HELI)
- m_sQueueSample.m_nFrequency = 8 * m_sQueueSample.m_nFrequency / 10;
+ m_sQueueSample.m_nFrequency = 8 * m_sQueueSample.m_nFrequency / 10; //same *= 8 / 10;
m_sQueueSample.m_nReleasingVolumeModificator = 0;
m_sQueueSample.m_nBankIndex = SFX_BANK_GENERIC_EXTRA;
break;
}
- pos = CExplosion::GetExplosionPosition(i);
- m_sQueueSample.m_vecPos = *pos;
+ m_sQueueSample.m_vecPos = *CExplosion::GetExplosionPosition(i);
distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos);
if (distSquared < SQR(m_sQueueSample.m_SoundIntensity)) {
m_sQueueSample.m_fDistance = Sqrt(distSquared);
@@ -6185,11 +8037,9 @@ cAudioManager::ProcessExplosions(int32 explosion)
m_sQueueSample.m_bIs2D = FALSE;
m_sQueueSample.m_nLoopCount = 1;
m_sQueueSample.m_bReleasingSoundFlag = TRUE;
- m_sQueueSample.m_bReverbFlag = TRUE;
SET_EMITTING_VOLUME(MAX_VOLUME);
RESET_LOOP_OFFSETS
m_sQueueSample.m_bReverbFlag = TRUE;
- m_sQueueSample.m_bRequireReflection = TRUE;
AddSampleToRequestedQueue();
}
}
@@ -6210,7 +8060,7 @@ cAudioManager::ProcessFires(int32)
if (entity) {
switch (entity->GetType()) {
case ENTITY_TYPE_BUILDING:
- m_sQueueSample.m_SoundIntensity = 50.0f;
+ m_sQueueSample.m_SoundIntensity = 80.0f;
m_sQueueSample.m_nSampleIndex = SFX_CAR_ON_FIRE;
emittingVol = 100;
m_sQueueSample.m_nFrequency = 8 * SampleManager.GetSampleBaseFrequency(SFX_CAR_ON_FIRE) / 10;
@@ -6226,7 +8076,7 @@ cAudioManager::ProcessFires(int32)
m_sQueueSample.m_nReleasingVolumeModificator = 10;
break;
default:
- m_sQueueSample.m_SoundIntensity = 50.0f;
+ m_sQueueSample.m_SoundIntensity = 80.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);
@@ -6234,10 +8084,9 @@ cAudioManager::ProcessFires(int32)
m_sQueueSample.m_nReleasingVolumeModificator = 8;
}
} else {
- m_sQueueSample.m_SoundIntensity = 50.0f;
+ m_sQueueSample.m_SoundIntensity = 80.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;
}
@@ -6261,6 +8110,29 @@ cAudioManager::ProcessFires(int32)
AddSampleToRequestedQueue();
}
}
+ if (gFireManager.m_aFires[i].m_bExtinguishedWithWater) {
+ gFireManager.m_aFires[i].m_bExtinguishedWithWater = FALSE;
+ emittingVol = 100.0f * gFireManager.m_aFires[i].m_fWaterExtinguishCountdown;
+ m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, m_sQueueSample.m_SoundIntensity, m_sQueueSample.m_fDistance);
+ if (m_sQueueSample.m_nVolume != 0) {
+ m_sQueueSample.m_nSampleIndex = SFX_JUMBO_TAXI;
+ m_sQueueSample.m_nFrequency = 19591;
+ m_sQueueSample.m_nFrequency += i * (m_sQueueSample.m_nFrequency / 64);
+ m_sQueueSample.m_nReleasingVolumeModificator = 9;
+ m_sQueueSample.m_nCounter = i + 40;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ 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;
+ SET_EMITTING_VOLUME(emittingVol);
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
+ m_sQueueSample.m_bReverbFlag = TRUE;
+ m_sQueueSample.m_bRequireReflection = FALSE;
+ AddSampleToRequestedQueue();
+ }
+ }
}
}
}
@@ -6276,17 +8148,9 @@ cAudioManager::ProcessWaterCannon(int32)
float distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos);
if (distSquared < SQR(SOUND_INTENSITY)) {
m_sQueueSample.m_fDistance = Sqrt(distSquared);
-#ifdef FIX_BUGS
m_sQueueSample.m_nVolume = ComputeVolume(50, SOUND_INTENSITY, m_sQueueSample.m_fDistance);
-#else
- m_sQueueSample.m_nVolume = ComputeVolume(50, m_sQueueSample.m_SoundIntensity, m_sQueueSample.m_fDistance);
-#endif
if (m_sQueueSample.m_nVolume != 0) {
-#ifdef FIX_BUGS
m_sQueueSample.m_SoundIntensity = SOUND_INTENSITY;
-#else
- m_sQueueSample.m_SoundIntensity = SQR(SOUND_INTENSITY);
-#endif
m_sQueueSample.m_nSampleIndex = SFX_JUMBO_TAXI;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_nFrequency = 15591;
@@ -6315,13 +8179,15 @@ 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);
+ if (MusicManager.m_nMusicMode == MUSICMODE_GAME) {
+ 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);
+ }
}
}
@@ -6335,37 +8201,31 @@ cAudioManager::ProcessOneShotScriptObject(uint8 sound)
static uint8 iSound = 0;
switch (sound) {
- case SCRIPT_SOUND_INJURED_PED_MALE_OUCH_S:
- case SCRIPT_SOUND_INJURED_PED_MALE_OUCH_L:
- {
- cPedParams pedParams;
- pedParams.m_fDistance = GetDistanceSquared(m_sQueueSample.m_vecPos);
- SetupPedComments(pedParams, SOUND_INJURED_PED_MALE_OUCH);
- return;
- }
- case SCRIPT_SOUND_INJURED_PED_FEMALE_OUCH_S:
- case SCRIPT_SOUND_INJURED_PED_FEMALE_OUCH_L:
- {
- cPedParams pedParams;
- pedParams.m_fDistance = GetDistanceSquared(m_sQueueSample.m_vecPos);
- SetupPedComments(pedParams, SOUND_INJURED_PED_FEMALE);
- return;
- }
- case SCRIPT_SOUND_GATE_START_CLUNK:
- case SCRIPT_SOUND_GATE_STOP_CLUNK:
+ case SCRIPT_SOUND_POLICE_CELL_DOOR_CLUNK:
m_sQueueSample.m_SoundIntensity = 40.0f;
m_sQueueSample.m_nSampleIndex = SFX_COL_GATE;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
- 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_nFrequency = 10600;
+ m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ emittingVolume = 60;
m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_bIs2D = FALSE;
m_sQueueSample.m_bRequireReflection = TRUE;
- emittingVolume = RandomDisplacement(10) + 50;
break;
+ case SCRIPT_SOUND_GARAGE_DOOR_CLUNK:
+ m_sQueueSample.m_SoundIntensity = 80.0f;
+ m_sQueueSample.m_nSampleIndex = SFX_COL_CAR_PANEL_2; // huh?
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nFrequency = 22000;
+ m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32);
+ m_sQueueSample.m_nReleasingVolumeModificator = 4;
+ emittingVolume = 60;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_bRequireReflection = TRUE;
+ break;
+ case SCRIPT_SOUND_SHOOTING_RANGE_TARGET_HIT:
case SCRIPT_SOUND_BULLET_HIT_GROUND_1:
case SCRIPT_SOUND_BULLET_HIT_GROUND_2:
case SCRIPT_SOUND_BULLET_HIT_GROUND_3:
@@ -6379,18 +8239,41 @@ cAudioManager::ProcessOneShotScriptObject(uint8 sound)
m_sQueueSample.m_bIs2D = FALSE;
emittingVolume = m_anRandomTable[2] % 20 + 90;
break;
- case SCRIPT_SOUND_TRAIN_ANNOUNCEMENT_1:
- case SCRIPT_SOUND_TRAIN_ANNOUNCEMENT_2:
- if (!SampleManager.IsSampleBankLoaded(SFX_BANK_TRAIN))
- return;
- m_sQueueSample.m_SoundIntensity = 80.0f;
- m_sQueueSample.m_nSampleIndex = SFX_TRAIN_STATION_ANNOUNCE;
- m_sQueueSample.m_nBankIndex = SFX_BANK_TRAIN;
- emittingVolume = MAX_VOLUME;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_TRAIN_STATION_ANNOUNCE);
- m_sQueueSample.m_nReleasingVolumeModificator = 0;
- m_sQueueSample.m_fSpeedMultiplier = 2.0f;
+ case SCRIPT_SOUND_WILLIE_CARD_SWIPE:
+ emittingVolume = 70;
+ m_sQueueSample.m_SoundIntensity = 40.0f;
+ m_sQueueSample.m_nSampleIndex = SFX_BOMB_BEEP;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nFrequency = 20159;
+ m_sQueueSample.m_nReleasingVolumeModificator = 1;
+ m_sQueueSample.m_fSpeedMultiplier = 1.0f;
m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_bRequireReflection = FALSE;
+ break;
+ case SCRIPT_SOUND_MALE_AMBULANCE_OUCH:
+ {
+ cPedParams pedParams;
+ pedParams.m_fDistance = GetDistanceSquared(m_sQueueSample.m_vecPos);
+ SetupPedComments(pedParams, SOUND_INJURED_PED_MALE_OUCH);
+ return;
+ }
+ case SCRIPT_SOUND_FEMALE_AMBULANCE_OUCH:
+ {
+ cPedParams pedParams;
+ pedParams.m_fDistance = GetDistanceSquared(m_sQueueSample.m_vecPos);
+ SetupPedComments(pedParams, SOUND_INJURED_PED_FEMALE);
+ return;
+ }
+ case SCRIPT_SOUND_SEAPLANE_LOW_FUEL:
+ m_sQueueSample.m_SoundIntensity = 1000.0f;
+ m_sQueueSample.m_nSampleIndex = SFX_SEAPLANE_LOW;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ emittingVolume = 100;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CAR_HORN_JEEP); // BUG?
+ m_sQueueSample.m_nReleasingVolumeModificator = 1;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_bIs2D = TRUE;
+ m_sQueueSample.m_bRequireReflection = FALSE;
break;
case SCRIPT_SOUND_PAYPHONE_RINGING:
m_sQueueSample.m_SoundIntensity = 80.0f;
@@ -6490,6 +8373,18 @@ cAudioManager::ProcessOneShotScriptObject(uint8 sound)
m_sQueueSample.m_bRequireReflection = TRUE;
emittingVolume = m_anRandomTable[2] % 30 + 60;
break;
+ case SCRIPT_SOUND_HIT_BALL:
+ m_sQueueSample.m_SoundIntensity = 60.0f;
+ m_sQueueSample.m_nSampleIndex = SFX_HIT_BALL;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16);
+ m_sQueueSample.m_nReleasingVolumeModificator = 5;
+ 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) {
@@ -6502,21 +8397,22 @@ cAudioManager::ProcessOneShotScriptObject(uint8 sound)
case SURFACE_SAND:
case SURFACE_RUBBER:
case SURFACE_HEDGE:
+ case SURFACE_SAND_BEACH:
m_sQueueSample.m_nSampleIndex = SFX_BULLET_SHELL_HIT_GROUND_2;
- m_sQueueSample.m_nFrequency = RandomDisplacement(500) + 11000;
+ m_sQueueSample.m_nFrequency = RandomDisplacement(600) + 10600;
m_sQueueSample.m_nReleasingVolumeModificator = 18;
break;
case SURFACE_WATER:
return;
default:
m_sQueueSample.m_nSampleIndex = SFX_BULLET_SHELL_HIT_GROUND_1;
- m_sQueueSample.m_nFrequency = RandomDisplacement(750) + 18000;
+ m_sQueueSample.m_nFrequency = RandomDisplacement(1500) + 30000;
m_sQueueSample.m_nReleasingVolumeModificator = 15;
break;
}
} else {
m_sQueueSample.m_nSampleIndex = SFX_BULLET_SHELL_HIT_GROUND_1;
- m_sQueueSample.m_nFrequency = RandomDisplacement(750) + 18000;
+ m_sQueueSample.m_nFrequency = RandomDisplacement(1500) + 30000;
m_sQueueSample.m_nReleasingVolumeModificator = 15;
}
m_sQueueSample.m_SoundIntensity = 20.0f;
@@ -6561,594 +8457,204 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
uint8 emittingVolume;
float distSquared;
- switch (sound) {
- case SCRIPT_SOUND_PARTY_1_LOOP_S:
- m_sQueueSample.m_SoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- m_sQueueSample.m_nSampleIndex = SFX_CLUB_1;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_CLUB_1;
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- m_sQueueSample.m_nSampleIndex = SFX_CLUB_1;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_CLUB_1;
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- m_sQueueSample.m_nSampleIndex = SFX_CLUB_2;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_CLUB_2;
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- m_sQueueSample.m_nSampleIndex = SFX_CLUB_2;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_CLUB_2;
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- m_sQueueSample.m_nSampleIndex = SFX_CLUB_3;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_CLUB_3;
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- m_sQueueSample.m_nSampleIndex = SFX_CLUB_3;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_CLUB_3;
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- m_sQueueSample.m_nSampleIndex = SFX_CLUB_4;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_CLUB_4;
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- m_sQueueSample.m_nSampleIndex = SFX_CLUB_4;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_CLUB_4;
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- m_sQueueSample.m_nSampleIndex = SFX_CLUB_5;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_CLUB_5;
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- m_sQueueSample.m_nSampleIndex = SFX_CLUB_5;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_CLUB_5;
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- m_sQueueSample.m_nSampleIndex = SFX_CLUB_6;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_CLUB_6;
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- m_sQueueSample.m_nSampleIndex = SFX_CLUB_6;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_CLUB_6;
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- m_sQueueSample.m_nSampleIndex = SFX_CLUB_7;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_CLUB_7;
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- m_sQueueSample.m_nSampleIndex = SFX_CLUB_7;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_CLUB_7;
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- m_sQueueSample.m_nSampleIndex = SFX_CLUB_8;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_CLUB_8;
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- m_sQueueSample.m_nSampleIndex = SFX_CLUB_8;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_CLUB_8;
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- m_sQueueSample.m_nSampleIndex = SFX_CLUB_9;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_CLUB_9;
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- m_sQueueSample.m_nSampleIndex = SFX_CLUB_9;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_CLUB_9;
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- m_sQueueSample.m_nSampleIndex = SFX_CLUB_10;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_CLUB_10;
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- m_sQueueSample.m_nSampleIndex = SFX_CLUB_10;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_CLUB_10;
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- m_sQueueSample.m_nSampleIndex = SFX_CLUB_11;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_CLUB_11;
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- m_sQueueSample.m_nSampleIndex = SFX_CLUB_11;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_CLUB_11;
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- m_sQueueSample.m_nSampleIndex = SFX_CLUB_12;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_CLUB_12;
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- m_sQueueSample.m_nSampleIndex = SFX_CLUB_12;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_CLUB_12;
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- m_sQueueSample.m_nSampleIndex = SFX_CLUB_RAGGA;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_CLUB_RAGGA;
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- m_sQueueSample.m_nSampleIndex = SFX_CLUB_RAGGA;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_CLUB_RAGGA;
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- m_sQueueSample.m_nSampleIndex = SFX_STRIP_CLUB_1;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_STRIP_CLUB_1;
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- m_sQueueSample.m_nSampleIndex = SFX_STRIP_CLUB_1;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_STRIP_CLUB_1;
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- m_sQueueSample.m_nSampleIndex = SFX_STRIP_CLUB_2;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_STRIP_CLUB_2;
- emittingVolume = MAX_VOLUME;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_STRIP_CLUB_2);
- m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ switch(sound) {
+ case SCRIPT_SOUND_BANK_ALARM_LOOP:
+ m_sQueueSample.m_SoundIntensity = 80.0f;
+ m_sQueueSample.m_nSampleIndex = SFX_BUILDINGS_BANK_ALARM;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_BANK_ALARM;
+ emittingVolume = 90;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_BUILDINGS_BANK_ALARM);
+ m_sQueueSample.m_nReleasingVolumeModificator = 2;
m_sQueueSample.m_nReleasingVolumeDivider = 3;
m_sQueueSample.m_fSpeedMultiplier = 2.0f;
+ m_sQueueSample.m_bIs2D = FALSE;
break;
- case SCRIPT_SOUND_STRIP_CLUB_LOOP_2_L:
- m_sQueueSample.m_SoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- m_sQueueSample.m_nSampleIndex = SFX_STRIP_CLUB_2;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_STRIP_CLUB_2;
- emittingVolume = MAX_VOLUME;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_STRIP_CLUB_2);
+ case SCRIPT_SOUND_POLICE_CELL_DOOR_SLIDING_LOOP:
+ case SCRIPT_SOUND_GARAGE_DOOR_SLIDING_LOOP:
+ m_sQueueSample.m_SoundIntensity = 80.0f;
+ m_sQueueSample.m_nSampleIndex = SFX_GARAGE_DOOR_LOOP;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ emittingVolume = 90;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_GARAGE_DOOR_LOOP);
m_sQueueSample.m_nReleasingVolumeModificator = 3;
m_sQueueSample.m_nReleasingVolumeDivider = 3;
m_sQueueSample.m_fSpeedMultiplier = 2.0f;
+ m_sQueueSample.m_bIs2D = FALSE;
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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- m_sQueueSample.m_nSampleIndex = SFX_DOG_FOOD_FACTORY;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_DOG_FOOD_FACTORY;
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- m_sQueueSample.m_nSampleIndex = SFX_DOG_FOOD_FACTORY;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_DOG_FOOD_FACTORY;
- emittingVolume = 110;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_DOG_FOOD_FACTORY);
+ case SCRIPT_SOUND_SNORING_LOOP:
+ m_sQueueSample.m_SoundIntensity = 6.0f;
+ m_sQueueSample.m_nSampleIndex = SFX_BUILDING_SNORE;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_SNORING;
+ emittingVolume = 25;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_BUILDING_SNORE);
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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- m_sQueueSample.m_nSampleIndex = SFX_RESTAURANT_CHINATOWN;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_RESTAURANT_CHINATOWN;
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- m_sQueueSample.m_nSampleIndex = SFX_RESTAURANT_CHINATOWN;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_RESTAURANT_CHINATOWN;
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- m_sQueueSample.m_nSampleIndex = SFX_RESTAURANT_ITALY;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_RESTAURANT_ITALY;
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- m_sQueueSample.m_nSampleIndex = SFX_RESTAURANT_ITALY;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_RESTAURANT_ITALY;
- 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;
+ m_sQueueSample.m_fSpeedMultiplier = 3.0f;
+ m_sQueueSample.m_bIs2D = FALSE;
break;
- case SCRIPT_SOUND_46_S:
- m_sQueueSample.m_SoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- m_sQueueSample.m_nSampleIndex = SFX_RESTAURANT_GENERIC_1;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_RESTAURANT_GENERIC_1;
- emittingVolume = 110;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_GENERIC_1);
- m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ case SCRIPT_SOUND_SHOOTING_RANGE_TARGET_MOVING_LOOP:
+ m_sQueueSample.m_SoundIntensity = 40.0f;
+ m_sQueueSample.m_nSampleIndex = SFX_TANK_TURRET;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ emittingVolume = 60;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_TANK_TURRET);
+ m_sQueueSample.m_nReleasingVolumeModificator = 4;
m_sQueueSample.m_nReleasingVolumeDivider = 3;
m_sQueueSample.m_fSpeedMultiplier = 2.0f;
+ m_sQueueSample.m_bIs2D = FALSE;
break;
- case SCRIPT_SOUND_47_L:
- m_sQueueSample.m_SoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- m_sQueueSample.m_nSampleIndex = SFX_RESTAURANT_GENERIC_1;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_RESTAURANT_GENERIC_1;
- emittingVolume = 110;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_GENERIC_1);
+ case SCRIPT_SOUND_NEW_BUILDING_BAR_1:
+ m_sQueueSample.m_nSampleIndex = SFX_BUILDING_BAR_1;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_BAR_1;
+ m_sQueueSample.m_SoundIntensity = 80.0f;
+ emittingVolume = 127;
+ 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;
+ m_sQueueSample.m_nReleasingVolumeDivider = 15;
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
+ m_sQueueSample.m_bIs2D = FALSE;
break;
- case SCRIPT_SOUND_MARCO_BISTRO_S:
- m_sQueueSample.m_SoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- m_sQueueSample.m_nSampleIndex = SFX_RESTAURANT_GENERIC_2;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_RESTAURANT_GENERIC_2;
- emittingVolume = 110;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_GENERIC_2);
+ case SCRIPT_SOUND_NEW_BUILDING_BAR_2:
+ m_sQueueSample.m_nSampleIndex = SFX_BUILDING_BAR_2;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_BAR_2;
+ m_sQueueSample.m_SoundIntensity = 80.0f;
+ emittingVolume = 127;
+ 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;
+ m_sQueueSample.m_nReleasingVolumeDivider = 15;
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
+ m_sQueueSample.m_bIs2D = FALSE;
break;
- case SCRIPT_SOUND_MARCO_BISTRO_L:
- m_sQueueSample.m_SoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- m_sQueueSample.m_nSampleIndex = SFX_RESTAURANT_GENERIC_2;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_RESTAURANT_GENERIC_2;
- emittingVolume = 110;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_GENERIC_2);
+ case SCRIPT_SOUND_NEW_BUILDING_BAR_3:
+ m_sQueueSample.m_nSampleIndex = SFX_BUILDING_BAR_3;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_BAR_3;
+ m_sQueueSample.m_SoundIntensity = 80.0f;
+ emittingVolume = 127;
+ 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;
+ m_sQueueSample.m_nReleasingVolumeDivider = 15;
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
+ m_sQueueSample.m_bIs2D = FALSE;
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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- m_sQueueSample.m_nSampleIndex = SFX_PIANO_BAR_1;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_PIANO_BAR;
- emittingVolume = MAX_VOLUME;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_PIANO_BAR_1);
+ case SCRIPT_SOUND_NEW_BUILDING_BAR_4:
+ m_sQueueSample.m_nSampleIndex = SFX_BUILDING_BAR_4;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_BAR_4;
+ m_sQueueSample.m_SoundIntensity = 80.0f;
+ emittingVolume = 127;
+ 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;
+ m_sQueueSample.m_nReleasingVolumeDivider = 15;
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
+ m_sQueueSample.m_bIs2D = FALSE;
break;
- case SCRIPT_SOUND_PARTY_1_LOOP:
- m_sQueueSample.m_SoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- m_sQueueSample.m_nSampleIndex = SFX_CLUB_1;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_CLUB_1;
- emittingVolume = MAX_VOLUME;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_1);
+ case SCRIPT_SOUND_NEW_BUILDING_MALIBU_1:
+ if(MusicManager.m_nPlayingTrack == STREAMED_SOUND_MALIBU_AMBIENT) return;
+ m_sQueueSample.m_nSampleIndex = SFX_BUILDING_MAL1;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_MALIBU_1;
+ MusicManager.SetMalibuClubTrackPos(SCRIPT_SOUND_NEW_BUILDING_MALIBU_1);
+ m_sQueueSample.m_SoundIntensity = 80.0f;
+ emittingVolume = 127;
+ 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_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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- m_sQueueSample.m_nSampleIndex = SFX_BANK_ALARM_1;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_BANK_ALARM;
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- m_sQueueSample.m_nSampleIndex = SFX_BANK_ALARM_1;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_BANK_ALARM;
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- m_sQueueSample.m_nSampleIndex = SFX_POLICE_BALL_1;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_POLICE_BALL;
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- m_sQueueSample.m_nSampleIndex = SFX_POLICE_BALL_1;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_POLICE_BALL;
- 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;
+ m_sQueueSample.m_nReleasingVolumeDivider = 15;
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
+ m_sQueueSample.m_bIs2D = FALSE;
break;
- case SCRIPT_SOUND_RAVE_LOOP_INDUSTRIAL_S:
- m_sQueueSample.m_SoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- m_sQueueSample.m_nSampleIndex = SFX_RAVE_INDUSTRIAL;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_RAVE_INDUSTRIAL;
- emittingVolume = MAX_VOLUME;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RAVE_INDUSTRIAL);
+ case SCRIPT_SOUND_NEW_BUILDING_MALIBU_2:
+ if(MusicManager.m_nPlayingTrack == STREAMED_SOUND_MALIBU_AMBIENT) return;
+ m_sQueueSample.m_nSampleIndex = SFX_BUILDING_MAL2;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_MALIBU_2;
+ MusicManager.SetMalibuClubTrackPos(SCRIPT_SOUND_NEW_BUILDING_MALIBU_2);
+ m_sQueueSample.m_SoundIntensity = 80.0f;
+ emittingVolume = 127;
+ 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;
+ m_sQueueSample.m_nReleasingVolumeDivider = 15;
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
+ m_sQueueSample.m_bIs2D = FALSE;
break;
- case SCRIPT_SOUND_RAVE_LOOP_INDUSTRIAL_L:
- m_sQueueSample.m_SoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- m_sQueueSample.m_nSampleIndex = SFX_RAVE_INDUSTRIAL;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_RAVE_INDUSTRIAL;
- emittingVolume = MAX_VOLUME;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RAVE_INDUSTRIAL);
+ case SCRIPT_SOUND_NEW_BUILDING_MALIBU_3:
+ if(MusicManager.m_nPlayingTrack == STREAMED_SOUND_MALIBU_AMBIENT) return;
+ m_sQueueSample.m_nSampleIndex = SFX_BUILDING_MAL3;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_MALIBU_3;
+ MusicManager.SetMalibuClubTrackPos(SCRIPT_SOUND_NEW_BUILDING_MALIBU_3);
+ m_sQueueSample.m_SoundIntensity = 80.0f;
+ emittingVolume = 127;
+ 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;
+ m_sQueueSample.m_nReleasingVolumeDivider = 15;
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
+ m_sQueueSample.m_bIs2D = FALSE;
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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- m_sQueueSample.m_nSampleIndex = SFX_RAVE_COMMERCIAL;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_RAVE_COMMERCIAL;
- emittingVolume = MAX_VOLUME;
+ case SCRIPT_SOUND_NEW_BUILDING_STRIP_1:
+ if(MusicManager.m_nPlayingTrack == STREAMED_SOUND_STRIPCLUB_AMBIENT) return;
+ m_sQueueSample.m_nSampleIndex = SFX_BUILDING_STR1;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_STRIP_1;
+ MusicManager.SetStripClubTrackPos(SCRIPT_SOUND_NEW_BUILDING_STRIP_1);
+ m_sQueueSample.m_SoundIntensity = 80.0f;
+ emittingVolume = 127;
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;
+ m_sQueueSample.m_nReleasingVolumeDivider = 15;
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
+ m_sQueueSample.m_bIs2D = FALSE;
break;
- case SCRIPT_SOUND_RAVE_1_LOOP_L:
- case SCRIPT_SOUND_RAVE_2_LOOP_L:
- m_sQueueSample.m_SoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- m_sQueueSample.m_nSampleIndex = SFX_RAVE_COMMERCIAL;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_RAVE_COMMERCIAL;
- emittingVolume = MAX_VOLUME;
+ case SCRIPT_SOUND_NEW_BUILDING_STRIP_2:
+ if(MusicManager.m_nPlayingTrack == STREAMED_SOUND_STRIPCLUB_AMBIENT) return;
+ m_sQueueSample.m_nSampleIndex = SFX_BUILDING_STR2;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_STRIP_2;
+ MusicManager.SetStripClubTrackPos(SCRIPT_SOUND_NEW_BUILDING_STRIP_2);
+ m_sQueueSample.m_SoundIntensity = 80.0f;
+ emittingVolume = 127;
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;
+ m_sQueueSample.m_nReleasingVolumeDivider = 15;
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
+ m_sQueueSample.m_bIs2D = FALSE;
break;
- case SCRIPT_SOUND_RAVE_3_LOOP_S:
- m_sQueueSample.m_SoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- m_sQueueSample.m_nSampleIndex = SFX_RAVE_SUBURBAN;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_RAVE_SUBURBAN;
- emittingVolume = MAX_VOLUME;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RAVE_SUBURBAN);
+ case SCRIPT_SOUND_NEW_BUILDING_STRIP_3:
+ if(MusicManager.m_nPlayingTrack == STREAMED_SOUND_STRIPCLUB_AMBIENT) return;
+ m_sQueueSample.m_nSampleIndex = SFX_BUILDING_STR3;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_STRIP_3;
+ MusicManager.SetStripClubTrackPos(SCRIPT_SOUND_NEW_BUILDING_STRIP_3);
+ m_sQueueSample.m_SoundIntensity = 80.0f;
+ emittingVolume = 127;
+ 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;
+ m_sQueueSample.m_nReleasingVolumeDivider = 15;
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
+ m_sQueueSample.m_bIs2D = FALSE;
break;
- case SCRIPT_SOUND_RAVE_3_LOOP_L:
- m_sQueueSample.m_SoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- m_sQueueSample.m_nSampleIndex = SFX_RAVE_SUBURBAN;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_RAVE_SUBURBAN;
- emittingVolume = MAX_VOLUME;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RAVE_SUBURBAN);
+ case SCRIPT_SOUND_NEW_BUILDING_CHURCH:
+ m_sQueueSample.m_nSampleIndex = SFX_BUILDING_CHURCH;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_CHURCH;
+ m_sQueueSample.m_SoundIntensity = 80.0f;
+ emittingVolume = 127;
+ 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;
+ m_sQueueSample.m_nReleasingVolumeDivider = 15;
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
+ m_sQueueSample.m_bIs2D = FALSE;
break;
- case SCRIPT_SOUND_PRETEND_FIRE_LOOP:
- m_sQueueSample.m_SoundIntensity = 50.0f;
- m_sQueueSample.m_nSampleIndex = SFX_CAR_ON_FIRE;
+ case SCRIPT_SOUND_NEW_WATERFALL:
+ emittingVolume = 30;
+ m_sQueueSample.m_SoundIntensity = 80.0f;
+ m_sQueueSample.m_nSampleIndex = SFX_BOAT_WATER_LOOP;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
- 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_nFrequency = 20812;
+ m_sQueueSample.m_nReleasingVolumeModificator = 4;
+ m_sQueueSample.m_nReleasingVolumeDivider = 9;
m_sQueueSample.m_fSpeedMultiplier = 2.0f;
+ m_sQueueSample.m_bIs2D = FALSE;
break;
- default:
- return;
+ default: return;
}
distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos);
- if (distSquared < SQR(m_sQueueSample.m_SoundIntensity)) {
+ if(distSquared < SQR(m_sQueueSample.m_SoundIntensity)) {
m_sQueueSample.m_fDistance = Sqrt(distSquared);
m_sQueueSample.m_nVolume = ComputeVolume(emittingVolume, m_sQueueSample.m_SoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
+ if(m_sQueueSample.m_nVolume != 0) {
m_sQueueSample.m_nCounter = 0;
m_sQueueSample.m_bIs2D = FALSE;
m_sQueueSample.m_nLoopCount = 0;
@@ -7161,565 +8667,25 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
}
}
}
-
-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 = SFX_BANK_BUILDING_PORN_1;
- sample = SFX_PORN_1_GROAN_1;
- m_sQueueSample.m_SoundIntensity = 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 = SFX_BANK_BUILDING_PORN_1;
- sample = SFX_PORN_1_GROAN_1;
- m_sQueueSample.m_SoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- break;
- case SCRIPT_SOUND_PORN_CINEMA_2_S:
- m_sQueueSample.m_nSampleIndex = SFX_PORN_2_LOOP;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_PORN_2;
- sample = SFX_PORN_2_GROAN_1;
- m_sQueueSample.m_SoundIntensity = 20.0f;
- break;
- case SCRIPT_SOUND_PORN_CINEMA_2_L:
- m_sQueueSample.m_nSampleIndex = SFX_PORN_2_LOOP;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_PORN_2;
- sample = SFX_PORN_2_GROAN_1;
- m_sQueueSample.m_SoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- break;
- case SCRIPT_SOUND_PORN_CINEMA_3_S:
- m_sQueueSample.m_nSampleIndex = SFX_PORN_3_LOOP;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_PORN_3;
- m_sQueueSample.m_SoundIntensity = 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 = SFX_BANK_BUILDING_PORN_3;
- m_sQueueSample.m_SoundIntensity = 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_SoundIntensity)) {
- 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_SoundIntensity, 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;
- SET_EMITTING_VOLUME(MAX_VOLUME);
- SET_LOOP_OFFSETS(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_SoundIntensity, 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;
-#ifdef FIX_BUGS
- SET_EMITTING_VOLUME(90);
-#endif
- RESET_LOOP_OFFSETS
- 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_SoundIntensity = 20.0f;
- break;
- default:
- return;
- }
- distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos);
- if (distSquared < SQR(m_sQueueSample.m_SoundIntensity)) {
- m_sQueueSample.m_fDistance = Sqrt(distSquared);
- m_sQueueSample.m_nVolume = ComputeVolume(30, m_sQueueSample.m_SoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
- m_sQueueSample.m_nSampleIndex = SFX_WORKSHOP_1;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_WORKSHOP;
- 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;
- SET_EMITTING_VOLUME(30);
- SET_LOOP_OFFSETS(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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- break;
- default:
- return;
- }
- distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos);
- if (distSquared < SQR(m_sQueueSample.m_SoundIntensity)) {
- m_sQueueSample.m_fDistance = Sqrt(distSquared);
- m_sQueueSample.m_nVolume = ComputeVolume(30, m_sQueueSample.m_SoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
- m_sQueueSample.m_nSampleIndex = SFX_SAWMILL_LOOP;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_SAWMILL;
- 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;
- SET_EMITTING_VOLUME(30);
- SET_LOOP_OFFSETS(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_SoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
- m_sQueueSample.m_nSampleIndex = SFX_SAWMILL_CUT_WOOD;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_SAWMILL;
- 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;
-#ifdef FIX_BUGS
- SET_EMITTING_VOLUME(70);
-#endif
- RESET_LOOP_OFFSETS
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- break;
- default:
- return;
- }
- float distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos);
- if (distSquared < SQR(m_sQueueSample.m_SoundIntensity)) {
- m_sQueueSample.m_fDistance = Sqrt(distSquared);
- m_sQueueSample.m_nVolume = ComputeVolume(45, m_sQueueSample.m_SoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
- m_sQueueSample.m_nSampleIndex = SFX_LAUNDERETTE_LOOP;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_LAUNDERETTE;
- 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;
- SET_EMITTING_VOLUME(45);
- SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
- m_sQueueSample.m_bReverbFlag = TRUE;
- m_sQueueSample.m_bRequireReflection = FALSE;
- AddSampleToRequestedQueue();
- }
- m_sQueueSample.m_nVolume = ComputeVolume(110, m_sQueueSample.m_SoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
- m_sQueueSample.m_nSampleIndex = SFX_LAUNDERETTE_SONG_LOOP;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_LAUNDERETTE;
- 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;
- SET_EMITTING_VOLUME(110);
- SET_LOOP_OFFSETS(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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- break;
- default:
- return;
- }
- distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos);
- if (distSquared < SQR(m_sQueueSample.m_SoundIntensity)) {
- m_sQueueSample.m_fDistance = Sqrt(distSquared);
- m_sQueueSample.m_nVolume = ComputeVolume(30, m_sQueueSample.m_SoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
- m_sQueueSample.m_nSampleIndex = SFX_SHOP_LOOP;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_SHOP;
- 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;
- SET_EMITTING_VOLUME(30);
- SET_LOOP_OFFSETS(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_SoundIntensity, 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 = SFX_BANK_BUILDING_SHOP;
- 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;
- SET_EMITTING_VOLUME(70);
- RESET_LOOP_OFFSETS
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- break;
- case SCRIPT_SOUND_AIRPORT_LOOP_L:
- m_sQueueSample.m_SoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- break;
- default:
- return;
- }
- float distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos);
- if (distSquared < SQR(m_sQueueSample.m_SoundIntensity)) {
- m_sQueueSample.m_fDistance = Sqrt(distSquared);
- m_sQueueSample.m_nVolume = ComputeVolume(110, m_sQueueSample.m_SoundIntensity, 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 = SFX_BANK_BUILDING_AIRPORT;
- 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;
- SET_EMITTING_VOLUME(110);
- RESET_LOOP_OFFSETS
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- break;
- case SCRIPT_SOUND_CINEMA_LOOP_L:
- m_sQueueSample.m_SoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- break;
- default:
- return;
- }
- float distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos);
- if (distSquared < SQR(m_sQueueSample.m_SoundIntensity)) {
- m_sQueueSample.m_fDistance = Sqrt(distSquared);
- rand = m_anRandomTable[0] % 90 + 30;
- m_sQueueSample.m_nVolume = ComputeVolume(rand, m_sQueueSample.m_SoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
- m_sQueueSample.m_nSampleIndex = iSound % 3 + SFX_CINEMA_BASS_1;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_CINEMA;
- 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;
- SET_EMITTING_VOLUME(rand);
- RESET_LOOP_OFFSETS
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- break;
- case SCRIPT_SOUND_DOCKS_LOOP_L:
- m_sQueueSample.m_SoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- break;
- default:
- return;
- }
- distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos);
- if (distSquared < SQR(m_sQueueSample.m_SoundIntensity)) {
- m_sQueueSample.m_fDistance = Sqrt(distSquared);
- rand = m_anRandomTable[0] % 60 + 40;
- m_sQueueSample.m_nVolume = ComputeVolume(rand, m_sQueueSample.m_SoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
- m_sQueueSample.m_nSampleIndex = SFX_DOCKS_FOGHORN;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_DOCKS;
- 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;
- SET_EMITTING_VOLUME(rand);
- RESET_LOOP_OFFSETS
- 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_SoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- break;
- case SCRIPT_SOUND_HOME_LOOP_L:
- m_sQueueSample.m_SoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- break;
- default:
- return;
- }
- dist = GetDistanceSquared(m_sQueueSample.m_vecPos);
- if (dist < SQR(m_sQueueSample.m_SoundIntensity)) {
- m_sQueueSample.m_fDistance = Sqrt(dist);
- rand = m_anRandomTable[0] % 30 + 40;
- m_sQueueSample.m_nVolume = ComputeVolume(rand, m_sQueueSample.m_SoundIntensity, 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 = SFX_BANK_BUILDING_HOME;
- 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;
- SET_EMITTING_VOLUME(rand);
- RESET_LOOP_OFFSETS
- 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;
-
- static uint8 iSound = 0;
-
- if (time > gCellNextTime) {
- switch (sound) {
- case SCRIPT_SOUND_POLICE_CELL_BEATING_LOOP_S:
- m_sQueueSample.m_SoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- break;
- case SCRIPT_SOUND_POLICE_CELL_BEATING_LOOP_L:
- m_sQueueSample.m_SoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- break;
- default:
- return;
- }
- distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos);
- if (distSquared < SQR(m_sQueueSample.m_SoundIntensity)) {
- 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_SoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
- m_sQueueSample.m_nBankIndex = SFX_BANK_0;
- 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;
- SET_EMITTING_VOLUME(emittingVol);
- RESET_LOOP_OFFSETS
- m_sQueueSample.m_bReverbFlag = TRUE;
- m_sQueueSample.m_bRequireReflection = FALSE;
- AddSampleToRequestedQueue();
- cPedParams params;
- params.m_bDistanceCalculated = TRUE;
- params.m_fDistance = distSquared;
- SetupPedComments(params, 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;
+ float x;
+ float y;
+ float modifier;
+ float wind;
+
static uint8 iSound = 0;
if (m_asAudioEntities[id].m_AudioEvents > 0 && m_asAudioEntities[id].m_awAudioEvent[0] == SOUND_LIGHTNING) {
- if (m_asAudioEntities[id].m_afVolume[0] < 10.f) {
+ if (m_asAudioEntities[id].m_afVolume[0] < 10.0f) {
m_sQueueSample.m_nSampleIndex = SFX_EXPLOSION_2;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_nFrequency = RandomDisplacement(500) + 4000;
- vol = (m_asAudioEntities[id].m_afVolume[0] * 10.0f * 0.1f);
+ vol = (m_asAudioEntities[id].m_afVolume[0] * 10.0f * 0.1f) + 35;
vol += 35;
} else {
m_sQueueSample.m_nSampleIndex = SFX_EXPLOSION_1;
@@ -7763,6 +8729,31 @@ cAudioManager::ProcessWeather(int32 id)
m_sQueueSample.m_bRequireReflection = FALSE;
AddSampleToRequestedQueue();
}
+ x = 0.0f;
+ y = 0.0f;
+ CWindModifiers::FindWindModifier(TheCamera.GetPosition(), &x, &y);
+ modifier = Max(Abs(x), Abs(y)) * 10.0f;
+ modifier = Min(1.0f, modifier);
+ wind = Max(CWeather::Wind, modifier);
+ if (wind > 0.0f && CObject::fDistToNearestTree < 75.0f) {
+ m_sQueueSample.m_nSampleIndex = SFX_PALM_TREE_LO;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_PALM_TREE_LO);
+ m_sQueueSample.m_nVolume = (m_anRandomTable[1] % 10 + 45.0f) * (75.0f - CObject::fDistToNearestTree) * (4.0f / 300.0f) * wind;
+ m_sQueueSample.m_nCounter = 5;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nReleasingVolumeModificator = 1;
+ m_sQueueSample.m_nOffset = 63;
+ m_sQueueSample.m_bIs2D = TRUE;
+ m_sQueueSample.m_nLoopCount = 0;
+ m_sQueueSample.m_bReleasingSoundFlag = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 7;
+ m_sQueueSample.m_bReverbFlag = FALSE;
+ SET_EMITTING_VOLUME(m_sQueueSample.m_nVolume);
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
+ m_sQueueSample.m_bRequireReflection = FALSE;
+ AddSampleToRequestedQueue();
+ CObject::fDistToNearestTree = 999999.9f;
+ }
}
void
@@ -7771,18 +8762,21 @@ cAudioManager::ProcessFrontEnd()
bool8 stereo;
bool8 processedPickup;
bool8 processedMission;
- bool8 frontendBank;
+ bool8 staticFreq;
+ bool8 center;
int16 sample;
static uint8 iSound = 0;
static uint32 cPickupNextFrame = 0;
static uint32 cPartMisComNextFrame = 0;
+ static uint32 radioDial = SFX_RADIO_DIAL_1;
for (uint32 i = 0; i < m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_AudioEvents; i++) {
+ staticFreq = FALSE;
processedPickup = FALSE;
- stereo = FALSE;
+ center = FALSE;
processedMission = FALSE;
- frontendBank = FALSE;
+ stereo = 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;
@@ -7793,112 +8787,122 @@ cAudioManager::ProcessFrontEnd()
case SOUND_GARAGE_NO_MONEY:
case SOUND_GARAGE_BAD_VEHICLE:
case SOUND_GARAGE_BOMB_ALREADY_SET:
- m_sQueueSample.m_nSampleIndex = SFX_PICKUP_ERROR_LEFT;
+ m_sQueueSample.m_nSampleIndex = SFX_WEAPON_LEFT;
stereo = TRUE;
+ staticFreq = TRUE;
+ center = 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_71: //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;
+ processedPickup = TRUE;
+ m_sQueueSample.m_nSampleIndex = SFX_MONEY_LEFT;
break;
+ case SOUND_GARAGE_BOMB1_SET:
+ case SOUND_GARAGE_BOMB2_SET:
+ case SOUND_GARAGE_BOMB3_SET:
case SOUND_PICKUP_WEAPON_BOUGHT:
case SOUND_PICKUP_WEAPON:
- m_sQueueSample.m_nSampleIndex = SFX_PICKUP_1_LEFT;
+ center = TRUE;
processedPickup = TRUE;
+ m_sQueueSample.m_nSampleIndex = SFX_WEAPON_LEFT;
stereo = TRUE;
break;
- case SOUND_PICKUP_ERROR:
- m_sQueueSample.m_nSampleIndex = SFX_PICKUP_ERROR_LEFT;
+ case SOUND_PICKUP_HEALTH:
+ case SOUND_81: //case SOUND_4B:
+ case SOUND_PICKUP_ADRENALINE:
+ case SOUND_PICKUP_ARMOUR:
+ stereo = TRUE;
processedPickup = TRUE;
+ m_sQueueSample.m_nSampleIndex = SFX_MONEY_LEFT;
+ break;
+ case SOUND_80:
stereo = TRUE;
+ processedPickup = TRUE;
+ m_sQueueSample.m_nSampleIndex = SFX_WEAPON_LEFT;
+ center = TRUE;
+ staticFreq = TRUE;
break;
case SOUND_PICKUP_BONUS:
+ case SOUND_FRONTEND_MENU_STARTING:
+ case SOUND_HUD:
+ stereo = TRUE;
+ m_sQueueSample.m_nSampleIndex = SFX_INFO_LEFT;
+ center = TRUE;
+ break;
case SOUND_PICKUP_MONEY:
+ stereo = TRUE;
+ processedPickup = TRUE;
+ m_sQueueSample.m_nSampleIndex = SFX_MONEY_LEFT;
+ break;
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;
+ center = TRUE;
processedPickup = TRUE;
+ m_sQueueSample.m_nSampleIndex = SFX_PART_MISSION_COMPLETE_LEFT;
stereo = TRUE;
break;
- case SOUND_PAGER:
- // TODO: ps2 code
- 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;
+ stereo = TRUE;
+ m_sQueueSample.m_nSampleIndex = SFX_PART_MISSION_COMPLETE_LEFT;
processedMission = TRUE;
+ center = TRUE;
break;
- case SOUND_FRONTEND_MENU_STARTING:
- m_sQueueSample.m_nSampleIndex = SFX_START_BUTTON_LEFT;
+ case SOUND_RACE_START_GO:
stereo = TRUE;
+ m_sQueueSample.m_nSampleIndex = SFX_GO_LEFT;
+ center = TRUE;
break;
- case SOUND_FRONTEND_MENU_NEW_PAGE:
- m_sQueueSample.m_nSampleIndex = SFX_PAGE_CHANGE_AND_BACK_LEFT;
- stereo = TRUE;
- frontendBank = TRUE;
+ case SOUND_CLOCK_TICK:
+ m_sQueueSample.m_nSampleIndex = SFX_TIMER;
break;
- case SOUND_FRONTEND_MENU_NAVIGATION:
- m_sQueueSample.m_nSampleIndex = SFX_HIGHLIGHT_LEFT;
- stereo = TRUE;
- frontendBank = TRUE;
+ case SOUND_FRONTEND_RADIO_TURN_OFF:
+ case SOUND_FRONTEND_RADIO_TURN_ON:
+ m_sQueueSample.m_nSampleIndex = SFX_RADIO_CLICK;
break;
- case SOUND_FRONTEND_MENU_SETTING_CHANGE:
- m_sQueueSample.m_nSampleIndex = SFX_SELECT_LEFT;
- stereo = TRUE;
- frontendBank = TRUE;
+ case SOUND_FRONTEND_HURRICANE:
+ m_sQueueSample.m_nSampleIndex = SFX_HURRICANE_MA;
break;
- case SOUND_FRONTEND_MENU_BACK:
- m_sQueueSample.m_nSampleIndex = SFX_SUB_MENU_BACK_LEFT;
- stereo = TRUE;
- frontendBank = TRUE;
+ case SOUND_BULLETTRACE_1:
+ case SOUND_BULLETTRACE_2:
+ m_sQueueSample.m_nSampleIndex = (m_anRandomTable[0] % 2) + SFX_BULLET_PASS_1;
+ break;
+ case SOUND_AMMUNATION_IMRAN_ARM_BOMB:
+ m_sQueueSample.m_nSampleIndex = SFX_ARM_BOMB;
+ break;
+ case SOUND_RADIO_CHANGE:
+ m_sQueueSample.m_nSampleIndex = (m_anRandomTable[1] % 2) ? radioDial + 1 : radioDial + 2;
+ if (m_sQueueSample.m_nSampleIndex > SFX_RADIO_DIAL_12)
+ m_sQueueSample.m_nSampleIndex -= 12;
+ radioDial = m_sQueueSample.m_nSampleIndex;
break;
- case SOUND_FRONTEND_STEREO:
- m_sQueueSample.m_nSampleIndex = SFX_STEREO_LEFT;
+ case SOUND_FRONTEND_HIGHLIGHT_OPTION:
stereo = TRUE;
- frontendBank = TRUE;
+ m_sQueueSample.m_nSampleIndex = SFX_FE_HIGHLIGHT_LEFT;
break;
- case SOUND_FRONTEND_MONO:
- m_sQueueSample.m_nSampleIndex = SFX_MONO;
- frontendBank = TRUE;
+ case SOUND_FRONTEND_ENTER_OR_ADJUST:
+ stereo = TRUE;
+ m_sQueueSample.m_nSampleIndex = SFX_FE_SELECT_LEFT;
break;
- case SOUND_FRONTEND_AUDIO_TEST:
- m_sQueueSample.m_nSampleIndex = m_anRandomTable[0] % 3 + SFX_NOISE_BURST_1;
- frontendBank = TRUE;
+ case SOUND_FRONTEND_BACK:
+ stereo = TRUE;
+ m_sQueueSample.m_nSampleIndex = SFX_FE_BACK_LEFT;
break;
case SOUND_FRONTEND_FAIL:
- m_sQueueSample.m_nSampleIndex = SFX_ERROR_LEFT;
- frontendBank = TRUE;
stereo = TRUE;
+ m_sQueueSample.m_nSampleIndex = SFX_FE_ERROR_LEFT;
break;
- case SOUND_FRONTEND_RADIO_TURN_OFF:
- case SOUND_FRONTEND_RADIO_CHANGE:
- m_sQueueSample.m_nSampleIndex = SFX_RADIO_CLICK;
- break;
- case SOUND_HUD:
- m_sQueueSample.m_nSampleIndex = SFX_INFO;
+ case SOUND_FRONTEND_AUDIO_TEST:
+ m_sQueueSample.m_nSampleIndex = m_anRandomTable[0] % 3 + SFX_FE_NOISE_BURST_1;
break;
default:
continue;
@@ -7915,29 +8919,50 @@ cAudioManager::ProcessFrontEnd()
}
sample = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i];
- if (sample == SFX_RAIN) {
+
+ if (sample == SOUND_FRONTEND_RADIO_TURN_OFF)
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 {
+ else if (sample == SOUND_FRONTEND_RADIO_TURN_ON)
+ m_sQueueSample.m_nFrequency = 32000;
+ else if (sample == SOUND_BULLETTRACE_1 || sample == SOUND_BULLETTRACE_2) {
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
- }
- m_sQueueSample.m_nVolume = 110;
+ m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32);
+ } else if (staticFreq)
+ m_sQueueSample.m_nFrequency = 5382;
+ else
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
+
+ m_sQueueSample.m_nVolume = 127;
+ if (m_sQueueSample.m_nSampleIndex == SFX_HURRICANE_MA && CWeather::Wind > 1.0f)
+ m_sQueueSample.m_nVolume = (CWeather::Wind - 1.0f) * m_sQueueSample.m_nVolume;
m_sQueueSample.m_nCounter = iSound++;
m_sQueueSample.m_nLoopCount = 1;
m_sQueueSample.m_bReleasingSoundFlag = TRUE;
- m_sQueueSample.m_nBankIndex = frontendBank ? SFX_BANK_FRONT_END_MENU : SFX_BANK_0;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_FRONT_END_MENU;
m_sQueueSample.m_nReleasingVolumeModificator = 0;
m_sQueueSample.m_bIs2D = TRUE;
SET_EMITTING_VOLUME(m_sQueueSample.m_nVolume);
RESET_LOOP_OFFSETS
- if (stereo)
- m_sQueueSample.m_nOffset = m_anRandomTable[0] & 31;
- else
- m_sQueueSample.m_nOffset = 63;
+ if (stereo) {
+ m_sQueueSample.m_nOffset = 0;
+ m_sQueueSample.m_fDistance = 1.0f;
+ } else {
+ sample = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i];
+ if (sample == SOUND_BULLETTRACE_1) {
+ m_sQueueSample.m_nOffset = 20;
+ m_sQueueSample.m_nVolume = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i];
+ m_sQueueSample.m_nReleasingVolumeModificator = 10;
+ m_sQueueSample.m_fDistance = 100.0f;
+ } else if (sample == SOUND_BULLETTRACE_2) {
+ m_sQueueSample.m_nOffset = 107;
+ m_sQueueSample.m_nVolume = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i];
+ m_sQueueSample.m_nReleasingVolumeModificator = 10;
+ m_sQueueSample.m_fDistance = 100.0f;
+ } else {
+ m_sQueueSample.m_nOffset = 63;
+ m_sQueueSample.m_fDistance = 1.0f;
+ }
+ }
m_sQueueSample.m_bReverbFlag = FALSE;
m_sQueueSample.m_bRequireReflection = FALSE;
AddSampleToRequestedQueue();
@@ -7947,10 +8972,17 @@ cAudioManager::ProcessFrontEnd()
m_sQueueSample.m_nOffset = 127 - m_sQueueSample.m_nOffset;
AddSampleToRequestedQueue();
}
+ if (center) {
+ ++m_sQueueSample.m_nSampleIndex;
+ m_sQueueSample.m_nCounter = iSound++;
+ m_sQueueSample.m_nOffset = 63;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
+ AddSampleToRequestedQueue();
+ }
}
}
-void
+/*void
cAudioManager::ProcessCrane()
{
CCrane *crane = (CCrane *)m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_pEntity;
@@ -7977,14 +9009,14 @@ cAudioManager::ProcessCrane()
SET_EMITTING_VOLUME(100);
SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
m_sQueueSample.m_fSpeedMultiplier = 4.0f;
- m_sQueueSample.m_SoundIntensity = intensity;
+ 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 > 0) {
+ 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);
@@ -7998,42 +9030,48 @@ cAudioManager::ProcessCrane()
}
}
}
-}
+}*/
void
cAudioManager::ProcessProjectiles()
{
- const int rocketLauncherIntensity = 90;
- const int molotovIntensity = 30;
- const int molotovVolume = 50;
uint8 emittingVol;
+ float distSquared;
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_SoundIntensity = rocketLauncherIntensity;
- m_sQueueSample.m_nSampleIndex = SFX_ROCKET_FLY;
+ case WEAPONTYPE_TEARGAS:
+ emittingVol = 80;
+ m_sQueueSample.m_SoundIntensity = 40.0f;
+ m_sQueueSample.m_nSampleIndex = SFX_PALM_TREE_LO;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_ROCKET_FLY);
- m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nFrequency = 13879;
+ m_sQueueSample.m_nReleasingVolumeModificator = 7;
break;
case WEAPONTYPE_MOLOTOV:
- emittingVol = molotovVolume;
- m_sQueueSample.m_SoundIntensity = molotovIntensity;
+ emittingVol = 50;
+ m_sQueueSample.m_SoundIntensity = 30.0f;
m_sQueueSample.m_nSampleIndex = SFX_PED_ON_FIRE;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_nFrequency = 32 * SampleManager.GetSampleBaseFrequency(SFX_PED_ON_FIRE) / 25;
m_sQueueSample.m_nReleasingVolumeModificator = 7;
break;
+ case WEAPONTYPE_ROCKET:
+ emittingVol = 127;
+ m_sQueueSample.m_SoundIntensity = 90.0f;
+ m_sQueueSample.m_nSampleIndex = SFX_ROCKET_FLY;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_ROCKET_FLY);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ 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);
+ distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos);
if (distSquared < SQR(m_sQueueSample.m_SoundIntensity)) {
m_sQueueSample.m_fDistance = Sqrt(distSquared);
m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, m_sQueueSample.m_SoundIntensity, m_sQueueSample.m_fDistance);
@@ -8054,6 +9092,83 @@ cAudioManager::ProcessProjectiles()
}
void
+cAudioManager::ProcessEscalators()
+{
+ const float SOUND_INTENSITY = 30.0f;
+ const uint8 EMITTING_VOLUME = 26;
+
+ float distance;
+
+ for (int i = 0; i < CEscalators::NumEscalators; i++) {
+ if (!CEscalators::GetEscalator(i).IsActive())
+ continue;
+ m_sQueueSample.m_vecPos = CEscalators::GetEscalator(i).GetPosition();
+ distance = GetDistanceSquared(m_sQueueSample.m_vecPos);
+ if (distance < SQR(SOUND_INTENSITY)) {
+ m_sQueueSample.m_fDistance = Sqrt(distance);
+ m_sQueueSample.m_nVolume = ComputeVolume(EMITTING_VOLUME, SOUND_INTENSITY, m_sQueueSample.m_fDistance);
+ if (m_sQueueSample.m_nVolume != 0) {
+ m_sQueueSample.m_nSampleIndex = SFX_BOAT_V12_LOOP;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nFrequency = i * 50 % 250 + 3973;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 3.0f;
+ m_sQueueSample.m_nReleasingVolumeDivider = 5;
+ m_sQueueSample.m_SoundIntensity = SOUND_INTENSITY;
+ m_sQueueSample.m_nCounter = i;
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_nLoopCount = 0;
+ SET_EMITTING_VOLUME(EMITTING_VOLUME);
+ SET_LOOP_OFFSETS(SFX_BOAT_V12_LOOP)
+ m_sQueueSample.m_bReverbFlag = TRUE;
+ m_sQueueSample.m_bReleasingSoundFlag = FALSE;
+ m_sQueueSample.m_bRequireReflection = FALSE;
+ AddSampleToRequestedQueue();
+ }
+ }
+ }
+}
+
+//positon of arcade machines
+CVector aVecExtraSoundPosition[] = { CVector(-1042.546f, 88.794f, 11.324f), CVector(-1004.476f, 181.697f, 11.324f) };
+
+void
+cAudioManager::ProcessExtraSounds()
+{
+ const float SOUND_INTENSITY = 18.0f;
+ const uint8 EMITTING_VOLUME = 50;
+
+ float distance;
+
+ for (int i = 0; i < ARRAY_SIZE(aVecExtraSoundPosition); i++) {
+ m_sQueueSample.m_vecPos = aVecExtraSoundPosition[i];
+ distance = GetDistanceSquared(m_sQueueSample.m_vecPos);
+ if (distance < SQR(SOUND_INTENSITY)) {
+ m_sQueueSample.m_fDistance = Sqrt(distance);
+ m_sQueueSample.m_nVolume = ComputeVolume(EMITTING_VOLUME, SOUND_INTENSITY, m_sQueueSample.m_fDistance);
+ if (m_sQueueSample.m_nVolume != 0) {
+ m_sQueueSample.m_nCounter = i;
+ m_sQueueSample.m_nSampleIndex = SFX_ARCADE;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_ARCADE);
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_nLoopCount = 0;
+ m_sQueueSample.m_bReleasingSoundFlag = FALSE;
+ m_sQueueSample.m_nReleasingVolumeModificator = 4;
+ m_sQueueSample.m_fSpeedMultiplier = 3.0f;
+ SET_EMITTING_VOLUME(EMITTING_VOLUME);
+ SET_LOOP_OFFSETS(SFX_ARCADE)
+ m_sQueueSample.m_bReverbFlag = TRUE;
+ m_sQueueSample.m_SoundIntensity = SOUND_INTENSITY;
+ m_sQueueSample.m_bRequireReflection = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ AddSampleToRequestedQueue();
+ }
+ }
+ }
+}
+
+void
cAudioManager::ProcessGarages()
{
const float SOUND_INTENSITY = 80.0f;
@@ -8178,36 +9293,36 @@ cAudioManager::ProcessGarages()
void
cAudioManager::ProcessFireHydrant()
{
+ const float SOUND_INTENSITY = 35;
+
float distSquared;
bool8 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)) {
+ if (distSquared < SQR(SOUND_INTENSITY)) {
CalculateDistance(distCalculated, distSquared);
- m_sQueueSample.m_nVolume = ComputeVolume(40, 35.f, m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_nVolume = ComputeVolume(40, 35.0f, 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 = SFX_BANK_0;
- m_sQueueSample.m_bIs2D = FALSE;
m_sQueueSample.m_nReleasingVolumeModificator = 4;
m_sQueueSample.m_nFrequency = 15591;
- m_sQueueSample.m_nLoopCount = 0;
+ m_sQueueSample.m_nCounter = 0;
SET_EMITTING_VOLUME(40);
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_nLoopCount = 0;
SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
- m_sQueueSample.m_fSpeedMultiplier = 2.0f;
- m_sQueueSample.m_SoundIntensity = intensity;
+ m_sQueueSample.m_SoundIntensity = SOUND_INTENSITY;
m_sQueueSample.m_bReleasingSoundFlag = FALSE;
- m_sQueueSample.m_nReleasingVolumeDivider = 3;
- m_sQueueSample.m_bReverbFlag = TRUE;
m_sQueueSample.m_bRequireReflection = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
AddSampleToRequestedQueue();
}
}
}
-
+#ifdef GTA_BRIDGE
#pragma region BRIDGE
const int bridgeIntensity = 400;
@@ -8249,7 +9364,7 @@ cAudioManager::ProcessBridgeWarning()
if (m_sQueueSample.m_nVolume != 0) {
m_sQueueSample.m_nCounter = 0;
m_sQueueSample.m_nSampleIndex = SFX_BRIDGE_OPEN_WARNING;
- m_sQueueSample.m_nBankIndex = SFX_BANK_GENERIC_EXTRA;
+ m_sQueueSample.m_nBankIndex = SAMPLEBANK_EXTRAS;
m_sQueueSample.m_bIs2D = FALSE;
m_sQueueSample.m_nReleasingVolumeModificator = 1;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_BRIDGE_OPEN_WARNING);
@@ -8326,50 +9441,392 @@ cAudioManager::ProcessBridgeOneShots()
}
}
#pragma endregion
+#endif
#pragma region MISSION_AUDIO
-bool8 g_bMissionAudioLoadFailed;
+bool8 g_bMissionAudioLoadFailed[MISSION_AUDIO_SLOTS];
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}, {nil, 0}};
+ {"mobring", STREAMED_SOUND_MISSION_MOBR1}, {"pagring", STREAMED_SOUND_MISSION_PAGER}, {"carrev", STREAMED_SOUND_MISSION_CARREV},
+ {"bikerev", STREAMED_SOUND_MISSION_BIKEREV}, {"liftop", STREAMED_SOUND_MISSION_LIFTOP}, {"liftcl", STREAMED_SOUND_MISSION_LIFTCL},
+ {"liftrun", STREAMED_SOUND_MISSION_LIFTRUN}, {"liftbel", STREAMED_SOUND_MISSION_LIFTBEL}, {"inlift", STREAMED_SOUND_MISSION_INLIFT},
+ {"caml", STREAMED_SOUND_MISSION_CAMERAL}, {"camr", STREAMED_SOUND_MISSION_CAMERAR}, {"cheer1", STREAMED_SOUND_MISSION_CHEER1},
+ {"cheer2", STREAMED_SOUND_MISSION_CHEER2}, {"cheer3", STREAMED_SOUND_MISSION_CHEER3}, {"cheer4", STREAMED_SOUND_MISSION_CHEER4},
+ {"ooh1", STREAMED_SOUND_MISSION_OOH1}, {"ooh2", STREAMED_SOUND_MISSION_OOH2}, {"race1", STREAMED_SOUND_MISSION_RACE1},
+ {"race2", STREAMED_SOUND_MISSION_RACE2}, {"race3", STREAMED_SOUND_MISSION_RACE3}, {"race4", STREAMED_SOUND_MISSION_RACE4},
+ {"race5", STREAMED_SOUND_MISSION_RACE5}, {"race6", STREAMED_SOUND_MISSION_RACE6}, {"race7", STREAMED_SOUND_MISSION_RACE7},
+ {"race8", STREAMED_SOUND_MISSION_RACE8}, {"race9", STREAMED_SOUND_MISSION_RACE9}, {"race10", STREAMED_SOUND_MISSION_RACE10},
+ {"race11", STREAMED_SOUND_MISSION_RACE11}, {"race12", STREAMED_SOUND_MISSION_RACE12}, {"race13", STREAMED_SOUND_MISSION_RACE13},
+ {"race14", STREAMED_SOUND_MISSION_RACE14}, {"race15", STREAMED_SOUND_MISSION_RACE15}, {"hot1", STREAMED_SOUND_MISSION_HOT1},
+ {"hot2", STREAMED_SOUND_MISSION_HOT2}, {"hot3", STREAMED_SOUND_MISSION_HOT3}, {"hot4", STREAMED_SOUND_MISSION_HOT4},
+ {"hot5", STREAMED_SOUND_MISSION_HOT5}, {"hot6", STREAMED_SOUND_MISSION_HOT6}, {"hot7", STREAMED_SOUND_MISSION_HOT7},
+ {"hot8", STREAMED_SOUND_MISSION_HOT8}, {"hot9", STREAMED_SOUND_MISSION_HOT9}, {"hot10", STREAMED_SOUND_MISSION_HOT10},
+ {"hot11", STREAMED_SOUND_MISSION_HOT11}, {"hot12", STREAMED_SOUND_MISSION_HOT12}, {"hot13", STREAMED_SOUND_MISSION_HOT13},
+ {"hot14", STREAMED_SOUND_MISSION_HOT14}, {"hot15", STREAMED_SOUND_MISSION_HOT15}, {"lanstp1", STREAMED_SOUND_MISSION_LANSTP1},
+ {"lanstp2", STREAMED_SOUND_MISSION_LANSTP2}, {"lanamu1", STREAMED_SOUND_MISSION_LANAMU1}, {"lanamu2", STREAMED_SOUND_MISSION_LANAMU2},
+ {"airhrnl", STREAMED_SOUND_MISSION_AIRHORNL}, {"airhrnr", STREAMED_SOUND_MISSION_AIRHORNR}, {"sniper", STREAMED_SOUND_MISSION_SNIPSCRL},
+ {"snipsh", STREAMED_SOUND_MISSION_SNIPSHORT}, {"bloroof", STREAMED_SOUND_MISSION_BLOWROOF}, {"sfx_01", STREAMED_SOUND_MISSION_SFX_01},
+ {"sfx_02", STREAMED_SOUND_MISSION_SFX_02}, {"LAW1_1", STREAMED_SOUND_MISSION_LAW1_1}, {"LAW1_2", STREAMED_SOUND_MISSION_LAW1_2},
+ {"LAW1_3", STREAMED_SOUND_MISSION_LAW1_3}, {"LAW1_4", STREAMED_SOUND_MISSION_LAW1_4}, {"LAW1_5", STREAMED_SOUND_MISSION_LAW1_5},
+ {"LAW1_6", STREAMED_SOUND_MISSION_LAW1_6}, {"LAW1_7", STREAMED_SOUND_MISSION_LAW1_7}, {"LAW1_8", STREAMED_SOUND_MISSION_LAW1_8},
+ {"LAW1_9", STREAMED_SOUND_MISSION_LAW1_9}, {"LAW1_10", STREAMED_SOUND_MISSION_LAW1_10}, {"LAW2_1", STREAMED_SOUND_MISSION_LAW2_1},
+ {"LAW2_2", STREAMED_SOUND_MISSION_LAW2_2}, {"LAW2_3", STREAMED_SOUND_MISSION_LAW2_3}, {"LAW2_4", STREAMED_SOUND_MISSION_LAW2_4},
+ {"LAW2_5", STREAMED_SOUND_MISSION_LAW2_5}, {"LAW2_6", STREAMED_SOUND_MISSION_LAW2_6}, {"LAW2_7", STREAMED_SOUND_MISSION_LAW2_7},
+ {"LAW2_8", STREAMED_SOUND_MISSION_LAW2_8}, {"LAW2_9", STREAMED_SOUND_MISSION_LAW2_9}, {"LAW2_10", STREAMED_SOUND_MISSION_LAW2_10},
+ {"LAW3_1", STREAMED_SOUND_MISSION_LAW3_1}, {"LAW3_2", STREAMED_SOUND_MISSION_LAW3_2}, {"LAW3_3", STREAMED_SOUND_MISSION_LAW3_3},
+ {"LAW3_4", STREAMED_SOUND_MISSION_LAW3_4}, {"LAW3_5", STREAMED_SOUND_MISSION_LAW3_5}, {"LAW3_6", STREAMED_SOUND_MISSION_LAW3_6},
+ {"LAW3_10", STREAMED_SOUND_MISSION_LAW3_10}, {"LAW3_11", STREAMED_SOUND_MISSION_LAW3_11}, {"LAW3_12", STREAMED_SOUND_MISSION_LAW3_12},
+ {"LAW3_13", STREAMED_SOUND_MISSION_LAW3_13}, {"LAW3_14", STREAMED_SOUND_MISSION_LAW3_14}, {"LAW3_16", STREAMED_SOUND_MISSION_LAW3_16},
+ {"LAW3_17", STREAMED_SOUND_MISSION_LAW3_17}, {"LAW3_18", STREAMED_SOUND_MISSION_LAW3_18}, {"LAW3_19", STREAMED_SOUND_MISSION_LAW3_19},
+ {"LAW3_20", STREAMED_SOUND_MISSION_LAW3_20}, {"LAW3_21", STREAMED_SOUND_MISSION_LAW3_21}, {"LAW3_22", STREAMED_SOUND_MISSION_LAW3_22},
+ {"LAW3_23", STREAMED_SOUND_MISSION_LAW3_23}, {"LAW3_24", STREAMED_SOUND_MISSION_LAW3_24}, {"LAW3_25", STREAMED_SOUND_MISSION_LAW3_25},
+ {"LAW4_1a", STREAMED_SOUND_MISSION_LAW4_1A}, {"LAW4_1b", STREAMED_SOUND_MISSION_LAW4_1B}, {"LAW4_1c", STREAMED_SOUND_MISSION_LAW4_1C},
+ {"LAW4_1d", STREAMED_SOUND_MISSION_LAW4_1D}, {"LAW4_10", STREAMED_SOUND_MISSION_LAW4_10}, {"LAW4_3", STREAMED_SOUND_MISSION_LAW4_3},
+ {"LAW4_4", STREAMED_SOUND_MISSION_LAW4_4}, {"LAW4_5", STREAMED_SOUND_MISSION_LAW4_5}, {"LAW4_6", STREAMED_SOUND_MISSION_LAW4_6},
+ {"LAW4_7", STREAMED_SOUND_MISSION_LAW4_7}, {"LAW4_8", STREAMED_SOUND_MISSION_LAW4_8}, {"LAW4_9", STREAMED_SOUND_MISSION_LAW4_9},
+ {"COL1_1", STREAMED_SOUND_MISSION_COL1_1}, {"COL1_2", STREAMED_SOUND_MISSION_COL1_2}, {"COL1_3", STREAMED_SOUND_MISSION_COL1_3},
+ {"COL1_4", STREAMED_SOUND_MISSION_COL1_4}, {"COL1_5", STREAMED_SOUND_MISSION_COL1_5}, {"COL1_6", STREAMED_SOUND_MISSION_COL1_6},
+ {"COL1_7", STREAMED_SOUND_MISSION_COL1_7}, {"COL1_8", STREAMED_SOUND_MISSION_COL1_8}, {"COL2_1", STREAMED_SOUND_MISSION_COL2_1},
+ {"COL2_2", STREAMED_SOUND_MISSION_COL2_2}, {"COL2_3", STREAMED_SOUND_MISSION_COL2_3}, {"COL2_4", STREAMED_SOUND_MISSION_COL2_4},
+ {"COL2_5", STREAMED_SOUND_MISSION_COL2_5}, {"COL2_6a", STREAMED_SOUND_MISSION_COL2_6A}, {"COL2_7", STREAMED_SOUND_MISSION_COL2_7},
+ {"COL2_8", STREAMED_SOUND_MISSION_COL2_8}, {"COL2_9", STREAMED_SOUND_MISSION_COL2_9}, {"COL2_10", STREAMED_SOUND_MISSION_COL2_10},
+ {"COL2_11", STREAMED_SOUND_MISSION_COL2_11}, {"COL2_12", STREAMED_SOUND_MISSION_COL2_12}, {"COL2_13", STREAMED_SOUND_MISSION_COL2_13},
+ {"COL2_14", STREAMED_SOUND_MISSION_COL2_14}, {"COL2_15", STREAMED_SOUND_MISSION_COL2_15}, {"COL2_16", STREAMED_SOUND_MISSION_COL2_16},
+ {"COL3_1", STREAMED_SOUND_MISSION_COL3_1}, {"COL3_2", STREAMED_SOUND_MISSION_COL3_2}, {"COL3_2a", STREAMED_SOUND_MISSION_COL3_2A},
+ {"COL3_2b", STREAMED_SOUND_MISSION_COL3_2B}, {"COL3_3", STREAMED_SOUND_MISSION_COL3_3}, {"COL3_4", STREAMED_SOUND_MISSION_COL3_4},
+ {"COL3_5", STREAMED_SOUND_MISSION_COL3_5}, {"COL3_6", STREAMED_SOUND_MISSION_COL3_6}, {"COL3_7", STREAMED_SOUND_MISSION_COL3_7},
+ {"COL3_8", STREAMED_SOUND_MISSION_COL3_8}, {"COL3_9", STREAMED_SOUND_MISSION_COL3_9}, {"COL3_10", STREAMED_SOUND_MISSION_COL3_10},
+ {"COL3_11", STREAMED_SOUND_MISSION_COL3_11}, {"COL3_12", STREAMED_SOUND_MISSION_COL3_12}, {"COL3_13", STREAMED_SOUND_MISSION_COL3_13},
+ {"COL3_14", STREAMED_SOUND_MISSION_COL3_14}, {"COL3_15", STREAMED_SOUND_MISSION_COL3_15}, {"COL3_16", STREAMED_SOUND_MISSION_COL3_16},
+ {"COL3_17", STREAMED_SOUND_MISSION_COL3_17}, {"COL3_18", STREAMED_SOUND_MISSION_COL3_18}, {"COL3_19", STREAMED_SOUND_MISSION_COL3_19},
+ {"COL3_20", STREAMED_SOUND_MISSION_COL3_20}, {"COL3_21", STREAMED_SOUND_MISSION_COL3_21}, {"COL3_23", STREAMED_SOUND_MISSION_COL3_23},
+ {"COL3_24", STREAMED_SOUND_MISSION_COL3_24}, {"COL3_25", STREAMED_SOUND_MISSION_COL3_25}, {"COL4_1", STREAMED_SOUND_MISSION_COL4_1},
+ {"COL4_2", STREAMED_SOUND_MISSION_COL4_2}, {"COL4_3", STREAMED_SOUND_MISSION_COL4_3}, {"COL4_4", STREAMED_SOUND_MISSION_COL4_4},
+ {"COL4_5", STREAMED_SOUND_MISSION_COL4_5}, {"COL4_6", STREAMED_SOUND_MISSION_COL4_6}, {"COL4_7", STREAMED_SOUND_MISSION_COL4_7},
+ {"COL4_8", STREAMED_SOUND_MISSION_COL4_8}, {"COL4_9", STREAMED_SOUND_MISSION_COL4_9}, {"COL4_10", STREAMED_SOUND_MISSION_COL4_10},
+ {"COL4_11", STREAMED_SOUND_MISSION_COL4_11}, {"COL4_12", STREAMED_SOUND_MISSION_COL4_12}, {"COL4_13", STREAMED_SOUND_MISSION_COL4_13},
+ {"COL4_14", STREAMED_SOUND_MISSION_COL4_14}, {"COL4_15", STREAMED_SOUND_MISSION_COL4_15}, {"COL4_16", STREAMED_SOUND_MISSION_COL4_16},
+ {"COL4_17", STREAMED_SOUND_MISSION_COL4_17}, {"COL4_18", STREAMED_SOUND_MISSION_COL4_18}, {"COL4_19", STREAMED_SOUND_MISSION_COL4_19},
+ {"COL4_20", STREAMED_SOUND_MISSION_COL4_20}, {"COL4_21", STREAMED_SOUND_MISSION_COL4_21}, {"COL4_22", STREAMED_SOUND_MISSION_COL4_22},
+ {"COL4_23", STREAMED_SOUND_MISSION_COL4_23}, {"COL4_24", STREAMED_SOUND_MISSION_COL4_24}, {"COL4_25", STREAMED_SOUND_MISSION_COL4_25},
+ {"COL4_26", STREAMED_SOUND_MISSION_COL4_26}, {"COL5_1", STREAMED_SOUND_MISSION_COL5_1}, {"COL5_2", STREAMED_SOUND_MISSION_COL5_2},
+ {"COL5_3", STREAMED_SOUND_MISSION_COL5_3}, {"COL5_4", STREAMED_SOUND_MISSION_COL5_4}, {"COL5_5", STREAMED_SOUND_MISSION_COL5_5},
+ {"COL5_6", STREAMED_SOUND_MISSION_COL5_6}, {"COL5_7", STREAMED_SOUND_MISSION_COL5_7}, {"COL5_8", STREAMED_SOUND_MISSION_COL5_8},
+ {"COL5_9", STREAMED_SOUND_MISSION_COL5_9}, {"COL5_10", STREAMED_SOUND_MISSION_COL5_10}, {"COL5_11", STREAMED_SOUND_MISSION_COL5_11},
+ {"COL5_12", STREAMED_SOUND_MISSION_COL5_12}, {"COL5_13", STREAMED_SOUND_MISSION_COL5_13}, {"COL5_14", STREAMED_SOUND_MISSION_COL5_14},
+ {"COL5_15", STREAMED_SOUND_MISSION_COL5_15}, {"COL5_16", STREAMED_SOUND_MISSION_COL5_16}, {"COL5_17", STREAMED_SOUND_MISSION_COL5_17},
+ {"COL5_18", STREAMED_SOUND_MISSION_COL5_18}, {"COL5_19", STREAMED_SOUND_MISSION_COL5_19}, {"COL5_20", STREAMED_SOUND_MISSION_COL5_20},
+ {"COL5_21", STREAMED_SOUND_MISSION_COL5_21}, {"COL5_22", STREAMED_SOUND_MISSION_COL5_22}, {"COK1_1", STREAMED_SOUND_MISSION_COK1_1},
+ {"COK1_2", STREAMED_SOUND_MISSION_COK1_2}, {"COK1_3", STREAMED_SOUND_MISSION_COK1_3}, {"COK1_4", STREAMED_SOUND_MISSION_COK1_4},
+ {"COK1_5", STREAMED_SOUND_MISSION_COK1_5}, {"COK1_6", STREAMED_SOUND_MISSION_COK1_6}, {"COK2_1", STREAMED_SOUND_MISSION_COK2_1},
+ {"COK2_2", STREAMED_SOUND_MISSION_COK2_2}, {"COK2_3", STREAMED_SOUND_MISSION_COK2_3}, {"COK2_4", STREAMED_SOUND_MISSION_COK2_4},
+ {"COK2_5", STREAMED_SOUND_MISSION_COK2_5}, {"COK2_6", STREAMED_SOUND_MISSION_COK2_6}, {"COK2_7a", STREAMED_SOUND_MISSION_COK2_7A},
+ {"COK2_7b", STREAMED_SOUND_MISSION_COK2_7B}, {"COK2_7c", STREAMED_SOUND_MISSION_COK2_7C}, {"COK2_8a", STREAMED_SOUND_MISSION_COK2_8A},
+ {"COK2_8b", STREAMED_SOUND_MISSION_COK2_8B}, {"COK2_8c", STREAMED_SOUND_MISSION_COK2_8C}, {"COK2_8d", STREAMED_SOUND_MISSION_COK2_8D},
+ {"COK2_9", STREAMED_SOUND_MISSION_COK2_9}, {"COK210a", STREAMED_SOUND_MISSION_COK210A}, {"COK210b", STREAMED_SOUND_MISSION_COK210B},
+ {"COK210c", STREAMED_SOUND_MISSION_COK210C}, {"COK212a", STREAMED_SOUND_MISSION_COK212A}, {"COK212b", STREAMED_SOUND_MISSION_COK212B},
+ {"COK2_13", STREAMED_SOUND_MISSION_COK2_13}, {"COK2_14", STREAMED_SOUND_MISSION_COK2_14}, {"COK2_15", STREAMED_SOUND_MISSION_COK2_15},
+ {"COK2_16", STREAMED_SOUND_MISSION_COK2_16}, {"COK2_20", STREAMED_SOUND_MISSION_COK2_20}, {"COK2_21", STREAMED_SOUND_MISSION_COK2_21},
+ {"COK2_22", STREAMED_SOUND_MISSION_COK2_22}, {"COK3_1", STREAMED_SOUND_MISSION_COK3_1}, {"COK3_2", STREAMED_SOUND_MISSION_COK3_2},
+ {"COK3_3", STREAMED_SOUND_MISSION_COK3_3}, {"COK3_4", STREAMED_SOUND_MISSION_COK3_4}, {"COK4_1", STREAMED_SOUND_MISSION_COK4_1},
+ {"COK4_2", STREAMED_SOUND_MISSION_COK4_2}, {"COK4_3", STREAMED_SOUND_MISSION_COK4_3}, {"COK4_4", STREAMED_SOUND_MISSION_COK4_4},
+ {"COK4_5", STREAMED_SOUND_MISSION_COK4_5}, {"COK4_6", STREAMED_SOUND_MISSION_COK4_6}, {"COK4_7", STREAMED_SOUND_MISSION_COK4_7},
+ {"COK4_8", STREAMED_SOUND_MISSION_COK4_8}, {"COK4_9", STREAMED_SOUND_MISSION_COK4_9}, {"COK4_9A", STREAMED_SOUND_MISSION_COK4_9A},
+ {"COK4_10", STREAMED_SOUND_MISSION_COK4_10}, {"COK4_11", STREAMED_SOUND_MISSION_COK4_11}, {"COK4_12", STREAMED_SOUND_MISSION_COK4_12},
+ {"COK4_13", STREAMED_SOUND_MISSION_COK4_13}, {"COK4_14", STREAMED_SOUND_MISSION_COK4_14}, {"COK4_15", STREAMED_SOUND_MISSION_COK4_15},
+ {"COK4_16", STREAMED_SOUND_MISSION_COK4_16}, {"COK4_17", STREAMED_SOUND_MISSION_COK4_17}, {"COK4_18", STREAMED_SOUND_MISSION_COK4_18},
+ {"COK4_19", STREAMED_SOUND_MISSION_COK4_19}, {"COK4_20", STREAMED_SOUND_MISSION_COK4_20}, {"COK4_21", STREAMED_SOUND_MISSION_COK4_21},
+ {"COK4_22", STREAMED_SOUND_MISSION_COK4_22}, {"COK4_23", STREAMED_SOUND_MISSION_COK4_23}, {"COK4_24", STREAMED_SOUND_MISSION_COK4_24},
+ {"COK4_25", STREAMED_SOUND_MISSION_COK4_25}, {"COK4_26", STREAMED_SOUND_MISSION_COK4_26}, {"COK4_27", STREAMED_SOUND_MISSION_COK4_27},
+ {"RESC_1", STREAMED_SOUND_MISSION_RESC_1}, {"RESC_2", STREAMED_SOUND_MISSION_RESC_2}, {"RESC_3", STREAMED_SOUND_MISSION_RESC_3},
+ {"RESC_4", STREAMED_SOUND_MISSION_RESC_4}, {"RESC_5", STREAMED_SOUND_MISSION_RESC_5}, {"RESC_6", STREAMED_SOUND_MISSION_RESC_6},
+ {"RESC_7", STREAMED_SOUND_MISSION_RESC_7}, {"RESC_8", STREAMED_SOUND_MISSION_RESC_8}, {"RESC_9", STREAMED_SOUND_MISSION_RESC_9},
+ {"RESC_10", STREAMED_SOUND_MISSION_RESC_10}, {"ASS_1", STREAMED_SOUND_MISSION_ASS_1}, {"ASS_2", STREAMED_SOUND_MISSION_ASS_2},
+ {"ASS_3", STREAMED_SOUND_MISSION_ASS_3}, {"ASS_4", STREAMED_SOUND_MISSION_ASS_4}, {"ASS_5", STREAMED_SOUND_MISSION_ASS_5},
+ {"ASS_6", STREAMED_SOUND_MISSION_ASS_6}, {"ASS_7", STREAMED_SOUND_MISSION_ASS_7}, {"ASS_8", STREAMED_SOUND_MISSION_ASS_8},
+ {"ASS_9", STREAMED_SOUND_MISSION_ASS_9}, {"ASS_10", STREAMED_SOUND_MISSION_ASS_10}, {"ASS_11", STREAMED_SOUND_MISSION_ASS_11},
+ {"ASS_12", STREAMED_SOUND_MISSION_ASS_12}, {"ASS_13", STREAMED_SOUND_MISSION_ASS_13}, {"ASS_14", STREAMED_SOUND_MISSION_ASS_14},
+ {"BUD1_1", STREAMED_SOUND_MISSION_BUD1_1}, {"BUD1_2", STREAMED_SOUND_MISSION_BUD1_2}, {"BUD1_3", STREAMED_SOUND_MISSION_BUD1_3},
+ {"BUD1_4", STREAMED_SOUND_MISSION_BUD1_4}, {"BUD1_5", STREAMED_SOUND_MISSION_BUD1_5}, {"BUD1_9", STREAMED_SOUND_MISSION_BUD1_9},
+ {"BUD1_10", STREAMED_SOUND_MISSION_BUD1_10}, {"BUD2_1", STREAMED_SOUND_MISSION_BUD2_1}, {"BUD2_2", STREAMED_SOUND_MISSION_BUD2_2},
+ {"BUD2_3", STREAMED_SOUND_MISSION_BUD2_3}, {"BUD2_4", STREAMED_SOUND_MISSION_BUD2_4}, {"BUD2_5", STREAMED_SOUND_MISSION_BUD2_5},
+ {"BUD2_6", STREAMED_SOUND_MISSION_BUD2_6}, {"BUD2_7", STREAMED_SOUND_MISSION_BUD2_7}, {"BUD3_1a", STREAMED_SOUND_MISSION_BUD3_1A},
+ {"BUD3_1b", STREAMED_SOUND_MISSION_BUD3_1B}, {"BUD3_1", STREAMED_SOUND_MISSION_BUD3_1}, {"BUD3_2", STREAMED_SOUND_MISSION_BUD3_2},
+ {"BUD3_3", STREAMED_SOUND_MISSION_BUD3_3}, {"BUD3_4", STREAMED_SOUND_MISSION_BUD3_4}, {"BUD3_1c", STREAMED_SOUND_MISSION_BUD3_1C},
+ {"BUD3_5", STREAMED_SOUND_MISSION_BUD3_5}, {"BUD3_6", STREAMED_SOUND_MISSION_BUD3_6}, {"BUD3_7", STREAMED_SOUND_MISSION_BUD3_7},
+ {"BUD3_8a", STREAMED_SOUND_MISSION_BUD3_8A}, {"BUD3_8b", STREAMED_SOUND_MISSION_BUD3_8B}, {"BUD3_8c", STREAMED_SOUND_MISSION_BUD3_8C},
+ {"BUD3_9a", STREAMED_SOUND_MISSION_BUD3_9A}, {"BUD3_9b", STREAMED_SOUND_MISSION_BUD3_9B}, {"BUD3_9c", STREAMED_SOUND_MISSION_BUD3_9C},
+ {"CAP1_2", STREAMED_SOUND_MISSION_CAP1_2}, {"CAP1_3", STREAMED_SOUND_MISSION_CAP1_3}, {"CAP1_4", STREAMED_SOUND_MISSION_CAP1_4},
+ {"CAP1_5", STREAMED_SOUND_MISSION_CAP1_5}, {"CAP1_6", STREAMED_SOUND_MISSION_CAP1_6}, {"CAP1_7", STREAMED_SOUND_MISSION_CAP1_7},
+ {"CAP1_8", STREAMED_SOUND_MISSION_CAP1_8}, {"CAP1_9", STREAMED_SOUND_MISSION_CAP1_9}, {"CAP1_10", STREAMED_SOUND_MISSION_CAP1_10},
+ {"CAP1_11", STREAMED_SOUND_MISSION_CAP1_11}, {"CAP1_12", STREAMED_SOUND_MISSION_CAP1_12}, {"FINKILL", STREAMED_SOUND_MISSION_FINKILL},
+ {"FIN_1a", STREAMED_SOUND_MISSION_FIN_1A}, {"FIN_1b", STREAMED_SOUND_MISSION_FIN_1B}, {"FIN_1c", STREAMED_SOUND_MISSION_FIN_1C},
+ {"FIN_2b", STREAMED_SOUND_MISSION_FIN_2B}, {"FIN_2c", STREAMED_SOUND_MISSION_FIN_2C}, {"FIN_3", STREAMED_SOUND_MISSION_FIN_3},
+ {"FIN_4", STREAMED_SOUND_MISSION_FIN_4}, {"FIN_5", STREAMED_SOUND_MISSION_FIN_5}, {"FIN_6", STREAMED_SOUND_MISSION_FIN_6},
+ {"FIN_10", STREAMED_SOUND_MISSION_FIN_10}, {"FIN_11a", STREAMED_SOUND_MISSION_FIN_11A}, {"FIN_11b", STREAMED_SOUND_MISSION_FIN_11B},
+ {"FIN_12a", STREAMED_SOUND_MISSION_FIN_12A}, {"FIN_12b", STREAMED_SOUND_MISSION_FIN_12B}, {"FIN_12c", STREAMED_SOUND_MISSION_FIN_12C},
+ {"FIN_13", STREAMED_SOUND_MISSION_FIN_13}, {"BNK1_1", STREAMED_SOUND_MISSION_BNK1_1}, {"BNK1_2", STREAMED_SOUND_MISSION_BNK1_2},
+ {"BNK1_3", STREAMED_SOUND_MISSION_BNK1_3}, {"BNK1_4", STREAMED_SOUND_MISSION_BNK1_4}, {"BNK1_5", STREAMED_SOUND_MISSION_BNK1_5},
+ {"BNK1_6", STREAMED_SOUND_MISSION_BNK1_6}, {"BNK1_7", STREAMED_SOUND_MISSION_BNK1_7}, {"BNK1_8", STREAMED_SOUND_MISSION_BNK1_8},
+ {"BNK1_10", STREAMED_SOUND_MISSION_BNK1_10}, {"BNK1_11", STREAMED_SOUND_MISSION_BNK1_11}, {"BNK1_12", STREAMED_SOUND_MISSION_BNK1_12},
+ {"BNK1_13", STREAMED_SOUND_MISSION_BNK1_13}, {"BNK1_14", STREAMED_SOUND_MISSION_BNK1_14}, {"BNK2_1", STREAMED_SOUND_MISSION_BNK2_1},
+ {"BNK2_2", STREAMED_SOUND_MISSION_BNK2_2}, {"BNK2_3", STREAMED_SOUND_MISSION_BNK2_3}, {"BNK2_4", STREAMED_SOUND_MISSION_BNK2_4},
+ {"BNK2_5", STREAMED_SOUND_MISSION_BNK2_5}, {"BNK2_6", STREAMED_SOUND_MISSION_BNK2_6}, {"BNK2_7", STREAMED_SOUND_MISSION_BNK2_7},
+ {"BNK2_8", STREAMED_SOUND_MISSION_BNK2_8}, {"BNK2_9", STREAMED_SOUND_MISSION_BNK2_9}, {"BNK3_1", STREAMED_SOUND_MISSION_BNK3_1},
+ {"BNK3_2", STREAMED_SOUND_MISSION_BNK3_2}, {"BNK3_3a", STREAMED_SOUND_MISSION_BNK3_3A}, {"BNK3_3b", STREAMED_SOUND_MISSION_BNK3_3B},
+ {"BNK3_3c", STREAMED_SOUND_MISSION_BNK3_3C}, {"BNK3_4a", STREAMED_SOUND_MISSION_BNK3_4A}, {"BNK3_4b", STREAMED_SOUND_MISSION_BNK3_4B},
+ {"BNK3_4c", STREAMED_SOUND_MISSION_BNK3_4C}, {"BNK4_1", STREAMED_SOUND_MISSION_BNK4_1}, {"BNK4_2", STREAMED_SOUND_MISSION_BNK4_2},
+ {"BNK4_3A", STREAMED_SOUND_MISSION_BNK4_3A}, {"BNK4_3B", STREAMED_SOUND_MISSION_BNK4_3B}, {"BNK4_3C", STREAMED_SOUND_MISSION_BNK4_3C},
+ {"BNK4_3D", STREAMED_SOUND_MISSION_BNK4_3D}, {"BNK4_3E", STREAMED_SOUND_MISSION_BNK4_3E}, {"BNK4_3F", STREAMED_SOUND_MISSION_BNK4_3F},
+ {"BNK4_3G", STREAMED_SOUND_MISSION_BNK4_3G}, {"BNK4_3H", STREAMED_SOUND_MISSION_BNK4_3H}, {"BNK4_3I", STREAMED_SOUND_MISSION_BNK4_3I},
+ {"BNK4_3J", STREAMED_SOUND_MISSION_BNK4_3J}, {"BNK4_3K", STREAMED_SOUND_MISSION_BNK4_3K}, {"BNK4_3M", STREAMED_SOUND_MISSION_BNK4_3M},
+ {"BNK4_3O", STREAMED_SOUND_MISSION_BNK4_3O}, {"BNK4_3P", STREAMED_SOUND_MISSION_BNK4_3P}, {"BNK4_3Q", STREAMED_SOUND_MISSION_BNK4_3Q},
+ {"BNK4_3R", STREAMED_SOUND_MISSION_BNK4_3R}, {"BNK4_3S", STREAMED_SOUND_MISSION_BNK4_3S}, {"BNK4_3T", STREAMED_SOUND_MISSION_BNK4_3T},
+ {"BNK4_3U", STREAMED_SOUND_MISSION_BNK4_3U}, {"BNK4_3V", STREAMED_SOUND_MISSION_BNK4_3V}, {"BNK4_4a", STREAMED_SOUND_MISSION_BNK4_4A},
+ {"BNK4_4b", STREAMED_SOUND_MISSION_BNK4_4B}, {"BNK4_5", STREAMED_SOUND_MISSION_BNK4_5}, {"BNK4_6", STREAMED_SOUND_MISSION_BNK4_6},
+ {"BNK4_7", STREAMED_SOUND_MISSION_BNK4_7}, {"BNK4_8", STREAMED_SOUND_MISSION_BNK4_8}, {"BNK4_9", STREAMED_SOUND_MISSION_BNK4_9},
+ {"BNK4_10", STREAMED_SOUND_MISSION_BNK4_10}, {"BNK4_11", STREAMED_SOUND_MISSION_BNK4_11}, {"BK4_12a", STREAMED_SOUND_MISSION_BK4_12A},
+ {"BK4_12b", STREAMED_SOUND_MISSION_BK4_12B}, {"BK4_12c", STREAMED_SOUND_MISSION_BK4_12C}, {"BNK4_13", STREAMED_SOUND_MISSION_BNK4_13},
+ {"BK4_14a", STREAMED_SOUND_MISSION_BK4_14A}, {"BK4_14b", STREAMED_SOUND_MISSION_BK4_14B}, {"BNK4_15", STREAMED_SOUND_MISSION_BNK4_15},
+ {"BNK4_16", STREAMED_SOUND_MISSION_BNK4_16}, {"BNK4_17", STREAMED_SOUND_MISSION_BNK4_17}, {"BNK4_18", STREAMED_SOUND_MISSION_BNK4_18},
+ {"BK4_19a", STREAMED_SOUND_MISSION_BK4_19A}, {"BK4_19b", STREAMED_SOUND_MISSION_BK4_19B}, {"BK4_20a", STREAMED_SOUND_MISSION_BK4_20A},
+ {"BK4_20b", STREAMED_SOUND_MISSION_BK4_20B}, {"BNK4_21", STREAMED_SOUND_MISSION_BNK4_21}, {"BNK422a", STREAMED_SOUND_MISSION_BNK422A},
+ {"BNK422b", STREAMED_SOUND_MISSION_BNK422B}, {"BK4_23a", STREAMED_SOUND_MISSION_BK4_23A}, {"BK4_23b", STREAMED_SOUND_MISSION_BK4_23B},
+ {"BK4_23c", STREAMED_SOUND_MISSION_BK4_23C}, {"BK4_23d", STREAMED_SOUND_MISSION_BK4_23D}, {"BK4_24a", STREAMED_SOUND_MISSION_BK4_24A},
+ {"BK4_24b", STREAMED_SOUND_MISSION_BK4_24B}, {"BNK4_25", STREAMED_SOUND_MISSION_BNK4_25}, {"BNK4_26", STREAMED_SOUND_MISSION_BNK4_26},
+ {"BNK4_27", STREAMED_SOUND_MISSION_BNK4_27}, {"BNK4_28", STREAMED_SOUND_MISSION_BNK4_28}, {"BNK4_29", STREAMED_SOUND_MISSION_BNK4_29},
+ {"BNK4_30", STREAMED_SOUND_MISSION_BNK4_30}, {"BK4_31a", STREAMED_SOUND_MISSION_BK4_31A}, {"BK4_31b", STREAMED_SOUND_MISSION_BK4_31B},
+ {"BNK4_32", STREAMED_SOUND_MISSION_BNK4_32}, {"BK4_34a", STREAMED_SOUND_MISSION_BK4_34A}, {"BK4_34b", STREAMED_SOUND_MISSION_BK4_34B},
+ {"BK4_35a", STREAMED_SOUND_MISSION_BK4_35A}, {"BK4_35b", STREAMED_SOUND_MISSION_BK4_35B}, {"BNK4_36", STREAMED_SOUND_MISSION_BNK4_36},
+ {"BNK4_37", STREAMED_SOUND_MISSION_BNK4_37}, {"BNK4_38", STREAMED_SOUND_MISSION_BNK4_38}, {"BNK_39", STREAMED_SOUND_MISSION_BNK4_39},
+ {"BK4_40a", STREAMED_SOUND_MISSION_BK4_40A}, {"BK4_40b", STREAMED_SOUND_MISSION_BK4_40B}, {"BNK4_41", STREAMED_SOUND_MISSION_BNK4_41},
+ {"BNK4_42", STREAMED_SOUND_MISSION_BNK4_42}, {"BNK4_43", STREAMED_SOUND_MISSION_BNK4_43}, {"BNK4_44", STREAMED_SOUND_MISSION_BNK4_44},
+ {"BNK4_45", STREAMED_SOUND_MISSION_BNK4_45}, {"BNK4_46", STREAMED_SOUND_MISSION_BNK4_46}, {"BNK4_47", STREAMED_SOUND_MISSION_BNK4_47},
+ {"BNK4_48", STREAMED_SOUND_MISSION_BNK4_48}, {"BNK4_49", STREAMED_SOUND_MISSION_BNK4_49}, {"BNK450A", STREAMED_SOUND_MISSION_BNK450A},
+ {"BNK450B", STREAMED_SOUND_MISSION_BNK450B}, {"BNK4_51", STREAMED_SOUND_MISSION_BNK4_51}, {"BNK4_94", STREAMED_SOUND_MISSION_BNK4_94},
+ {"BNK4_95", STREAMED_SOUND_MISSION_BNK4_95}, {"BNK4_96", STREAMED_SOUND_MISSION_BNK4_96}, {"BNK4_97", STREAMED_SOUND_MISSION_BNK4_97},
+ {"BNK4_98", STREAMED_SOUND_MISSION_BNK4_98}, {"BNK4_99", STREAMED_SOUND_MISSION_BNK4_99}, {"CNT1_1", STREAMED_SOUND_MISSION_CNT1_1},
+ {"CNT1_2", STREAMED_SOUND_MISSION_CNT1_2}, {"CNT1_3", STREAMED_SOUND_MISSION_CNT1_3}, {"CNT1_4", STREAMED_SOUND_MISSION_CNT1_4},
+ {"CNT1_5", STREAMED_SOUND_MISSION_CNT1_5}, {"CNT2_1", STREAMED_SOUND_MISSION_CNT2_1}, {"CNT2_2", STREAMED_SOUND_MISSION_CNT2_2},
+ {"CNT2_3", STREAMED_SOUND_MISSION_CNT2_3}, {"CNT2_4", STREAMED_SOUND_MISSION_CNT2_4}, {"PORN1_1", STREAMED_SOUND_MISSION_PORN1_1},
+ {"PORN1_2", STREAMED_SOUND_MISSION_PORN1_2}, {"PORN1_3", STREAMED_SOUND_MISSION_PORN1_3}, {"PRN1_3A", STREAMED_SOUND_MISSION_PRN1_3A},
+ {"PORN1_4", STREAMED_SOUND_MISSION_PORN1_4}, {"PORN1_5", STREAMED_SOUND_MISSION_PORN1_5}, {"PORN1_6", STREAMED_SOUND_MISSION_PORN1_6},
+ {"PORN1_7", STREAMED_SOUND_MISSION_PORN1_7}, {"PORN1_8", STREAMED_SOUND_MISSION_PORN1_8}, {"PORN1_9", STREAMED_SOUND_MISSION_PORN1_9},
+ {"PRN1_10", STREAMED_SOUND_MISSION_PRN1_10}, {"PRN1_11", STREAMED_SOUND_MISSION_PRN1_11}, {"PRN1_12", STREAMED_SOUND_MISSION_PRN1_12},
+ {"PRN1_13", STREAMED_SOUND_MISSION_PRN1_13}, {"PRN1_14", STREAMED_SOUND_MISSION_PRN1_14}, {"PRN1_15", STREAMED_SOUND_MISSION_PRN1_15},
+ {"PRN1_16", STREAMED_SOUND_MISSION_PRN1_16}, {"PRN1_17", STREAMED_SOUND_MISSION_PRN1_17}, {"PRN1_18", STREAMED_SOUND_MISSION_PRN1_18},
+ {"PRN1_19", STREAMED_SOUND_MISSION_PRN1_19}, {"PRN1_20", STREAMED_SOUND_MISSION_PRN1_20}, {"PRN1_21", STREAMED_SOUND_MISSION_PRN1_21},
+ {"PORN3_1", STREAMED_SOUND_MISSION_PORN3_1}, {"PORN3_2", STREAMED_SOUND_MISSION_PORN3_2}, {"PORN3_3", STREAMED_SOUND_MISSION_PORN3_3},
+ {"PORN3_4", STREAMED_SOUND_MISSION_PORN3_4}, {"TAX1_1", STREAMED_SOUND_MISSION_TAX1_1}, {"TAX1_2", STREAMED_SOUND_MISSION_TAX1_2},
+ {"TAX1_3", STREAMED_SOUND_MISSION_TAX1_3}, {"TAX1_4", STREAMED_SOUND_MISSION_TAX1_4}, {"TAX1_5", STREAMED_SOUND_MISSION_TAX1_5},
+ {"TAX2_1", STREAMED_SOUND_MISSION_TAX2_1}, {"TAX2_2", STREAMED_SOUND_MISSION_TAX2_2}, {"TAX2_3", STREAMED_SOUND_MISSION_TAX2_3},
+ {"TAX2_4", STREAMED_SOUND_MISSION_TAX2_4}, {"TAX2_5", STREAMED_SOUND_MISSION_TAX2_5}, {"TAX2_6", STREAMED_SOUND_MISSION_TAX2_6},
+ {"TAX2_7", STREAMED_SOUND_MISSION_TAX2_7}, {"TAX3_1", STREAMED_SOUND_MISSION_TAX3_1}, {"TAX3_2", STREAMED_SOUND_MISSION_TAX3_2},
+ {"TAX3_3", STREAMED_SOUND_MISSION_TAX3_3}, {"TAX3_4", STREAMED_SOUND_MISSION_TAX3_4}, {"TAX3_5", STREAMED_SOUND_MISSION_TAX3_5},
+ {"TEX1_1", STREAMED_SOUND_MISSION_TEX1_1}, {"TEX1_2", STREAMED_SOUND_MISSION_TEX1_2}, {"TEX1_3", STREAMED_SOUND_MISSION_TEX1_3},
+ {"TEX1_4", STREAMED_SOUND_MISSION_TEX1_4}, {"TEX1_5", STREAMED_SOUND_MISSION_TEX1_5}, {"TEX1_6", STREAMED_SOUND_MISSION_TEX1_6},
+ {"TEX2_1", STREAMED_SOUND_MISSION_TEX2_1}, {"TEX3_1", STREAMED_SOUND_MISSION_TEX3_1}, {"TEX3_2", STREAMED_SOUND_MISSION_TEX3_2},
+ {"TEX3_3", STREAMED_SOUND_MISSION_TEX3_3}, {"TEX3_4", STREAMED_SOUND_MISSION_TEX3_4}, {"TEX3_5", STREAMED_SOUND_MISSION_TEX3_5},
+ {"TEX3_6", STREAMED_SOUND_MISSION_TEX3_6}, {"TEX3_7", STREAMED_SOUND_MISSION_TEX3_7}, {"TEX3_8", STREAMED_SOUND_MISSION_TEX3_8},
+ {"PHIL1_2", STREAMED_SOUND_MISSION_PHIL1_2}, {"PHIL1_3", STREAMED_SOUND_MISSION_PHIL1_3}, {"PHIL2_1", STREAMED_SOUND_MISSION_PHIL2_1},
+ {"PHIL2_2", STREAMED_SOUND_MISSION_PHIL2_2}, {"PHIL2_3", STREAMED_SOUND_MISSION_PHIL2_3}, {"PHIL2_4", STREAMED_SOUND_MISSION_PHIL2_4},
+ {"PHIL2_5", STREAMED_SOUND_MISSION_PHIL2_5}, {"PHIL2_6", STREAMED_SOUND_MISSION_PHIL2_6}, {"PHIL2_7", STREAMED_SOUND_MISSION_PHIL2_7},
+ {"PHIL2_8", STREAMED_SOUND_MISSION_PHIL2_8}, {"PHIL2_9", STREAMED_SOUND_MISSION_PHIL2_9}, {"PHIL210", STREAMED_SOUND_MISSION_PHIL210},
+ {"PHIL211", STREAMED_SOUND_MISSION_PHIL211}, {"BIKE1_1", STREAMED_SOUND_MISSION_BIKE1_1}, {"BIKE1_2", STREAMED_SOUND_MISSION_BIKE1_2},
+ {"BIKE1_3", STREAMED_SOUND_MISSION_BIKE1_3}, {"ROK1_1a", STREAMED_SOUND_MISSION_ROK1_1A}, {"ROK1_1b", STREAMED_SOUND_MISSION_ROK1_1B},
+ {"ROK1_5", STREAMED_SOUND_MISSION_ROK1_5}, {"ROK1_6", STREAMED_SOUND_MISSION_ROK1_6}, {"ROK1_7", STREAMED_SOUND_MISSION_ROK1_7},
+ {"ROK1_8", STREAMED_SOUND_MISSION_ROK1_8}, {"ROK1_9", STREAMED_SOUND_MISSION_ROK1_9}, {"PSYCH_1", STREAMED_SOUND_MISSION_PSYCH_1},
+ {"PSYCH_2", STREAMED_SOUND_MISSION_PSYCH_2}, {"ROK2_01", STREAMED_SOUND_MISSION_ROK2_01}, {"ROK3_1", STREAMED_SOUND_MISSION_ROK3_1},
+ {"ROK3_2", STREAMED_SOUND_MISSION_ROK3_2}, {"ROK3_3", STREAMED_SOUND_MISSION_ROK3_3}, {"ROK3_4", STREAMED_SOUND_MISSION_ROK3_4},
+ {"ROK3_5", STREAMED_SOUND_MISSION_ROK3_5}, {"ROK3_6", STREAMED_SOUND_MISSION_ROK3_6}, {"ROK3_7", STREAMED_SOUND_MISSION_ROK3_7},
+ {"ROK3_8", STREAMED_SOUND_MISSION_ROK3_8}, {"ROK3_9", STREAMED_SOUND_MISSION_ROK3_9}, {"ROK3_10", STREAMED_SOUND_MISSION_ROK3_10},
+ {"ROK3_11", STREAMED_SOUND_MISSION_ROK3_11}, {"ROK3_12", STREAMED_SOUND_MISSION_ROK3_12}, {"ROK3_13", STREAMED_SOUND_MISSION_ROK3_13},
+ {"ROK3_14", STREAMED_SOUND_MISSION_ROK3_14}, {"ROK3_15", STREAMED_SOUND_MISSION_ROK3_15}, {"ROK3_16", STREAMED_SOUND_MISSION_ROK3_16},
+ {"ROK3_17", STREAMED_SOUND_MISSION_ROK3_17}, {"ROK3_18", STREAMED_SOUND_MISSION_ROK3_18}, {"ROK3_19", STREAMED_SOUND_MISSION_ROK3_19},
+ {"ROK3_20", STREAMED_SOUND_MISSION_ROK3_20}, {"ROK3_21", STREAMED_SOUND_MISSION_ROK3_21}, {"ROK3_22", STREAMED_SOUND_MISSION_ROK3_22},
+ {"ROK3_23", STREAMED_SOUND_MISSION_ROK3_23}, {"ROK3_24", STREAMED_SOUND_MISSION_ROK3_24}, {"ROK3_25", STREAMED_SOUND_MISSION_ROK3_25},
+ {"ROK3_26", STREAMED_SOUND_MISSION_ROK3_26}, {"ROK3_27", STREAMED_SOUND_MISSION_ROK3_27}, {"ROK3_62", STREAMED_SOUND_MISSION_ROK3_62},
+ {"ROK3_63", STREAMED_SOUND_MISSION_ROK3_63}, {"ROK3_64", STREAMED_SOUND_MISSION_ROK3_64}, {"ROK3_65", STREAMED_SOUND_MISSION_ROK3_65},
+ {"ROK3_66", STREAMED_SOUND_MISSION_ROK3_66}, {"ROK3_67", STREAMED_SOUND_MISSION_ROK3_67}, {"ROK3_68", STREAMED_SOUND_MISSION_ROK3_68},
+ {"ROK3_69", STREAMED_SOUND_MISSION_ROK3_69}, {"ROK3_70", STREAMED_SOUND_MISSION_ROK3_70}, {"ROK3_71", STREAMED_SOUND_MISSION_ROK3_71},
+ {"ROK3_73", STREAMED_SOUND_MISSION_ROK3_73}, {"HAT_1a", STREAMED_SOUND_MISSION_HAT_1A}, {"intro1", STREAMED_SOUND_MISSION_INTRO1},
+ {"intro2", STREAMED_SOUND_MISSION_INTRO2}, {"intro3", STREAMED_SOUND_MISSION_INTRO3}, {"intro4", STREAMED_SOUND_MISSION_INTRO4},
+ {"CUB1_1", STREAMED_SOUND_MISSION_CUB1_1}, {"CUB1_2", STREAMED_SOUND_MISSION_CUB1_2}, {"CUB1_3", STREAMED_SOUND_MISSION_CUB1_3},
+ {"CUB1_4", STREAMED_SOUND_MISSION_CUB1_4}, {"CUB1_5", STREAMED_SOUND_MISSION_CUB1_5}, {"CUB1_6", STREAMED_SOUND_MISSION_CUB1_6},
+ {"CUB1_7", STREAMED_SOUND_MISSION_CUB1_7}, {"CUB1_8", STREAMED_SOUND_MISSION_CUB1_8}, {"CUB1_9", STREAMED_SOUND_MISSION_CUB1_9},
+ {"CUB1_10", STREAMED_SOUND_MISSION_CUB1_10}, {"CUB2_1", STREAMED_SOUND_MISSION_CUB2_1}, {"CUB2_2", STREAMED_SOUND_MISSION_CUB2_2},
+ {"CUB2_3a", STREAMED_SOUND_MISSION_CUB2_3A}, {"CUB2_3b", STREAMED_SOUND_MISSION_CUB2_3B}, {"CUB2_3c", STREAMED_SOUND_MISSION_CUB2_3C},
+ {"CUB2_4a", STREAMED_SOUND_MISSION_CUB2_4A}, {"CUB2_5", STREAMED_SOUND_MISSION_CUB2_5}, {"CUB2_6", STREAMED_SOUND_MISSION_CUB2_6},
+ {"CUB2_7", STREAMED_SOUND_MISSION_CUB2_7}, {"CUB2_8", STREAMED_SOUND_MISSION_CUB2_8}, {"CUB2_9", STREAMED_SOUND_MISSION_CUB2_9},
+ {"CUB2_10", STREAMED_SOUND_MISSION_CUB2_10}, {"CUB2_11", STREAMED_SOUND_MISSION_CUB2_11}, {"CUB3_1", STREAMED_SOUND_MISSION_CUB3_1},
+ {"CUB3_2", STREAMED_SOUND_MISSION_CUB3_2}, {"CUB3_3", STREAMED_SOUND_MISSION_CUB3_3}, {"CUB3_4", STREAMED_SOUND_MISSION_CUB3_4},
+ {"CUB4_1", STREAMED_SOUND_MISSION_CUB4_1}, {"CUB4_2", STREAMED_SOUND_MISSION_CUB4_2}, {"CUB4_3", STREAMED_SOUND_MISSION_CUB4_3},
+ {"CUB4_4", STREAMED_SOUND_MISSION_CUB4_4}, {"CUB4_5", STREAMED_SOUND_MISSION_CUB4_5}, {"CUB4_5A", STREAMED_SOUND_MISSION_CUB4_5A},
+ {"CUB4_6", STREAMED_SOUND_MISSION_CUB4_6}, {"CUB4_7", STREAMED_SOUND_MISSION_CUB4_7}, {"CUB4_8", STREAMED_SOUND_MISSION_CUB4_8},
+ {"CUB4_9", STREAMED_SOUND_MISSION_CUB4_9}, {"CUB4_10", STREAMED_SOUND_MISSION_CUB4_10}, {"CUB4_11", STREAMED_SOUND_MISSION_CUB4_11},
+ {"CUB4_12", STREAMED_SOUND_MISSION_CUB4_12}, {"CUB4_13", STREAMED_SOUND_MISSION_CUB4_13}, {"CUB4_14", STREAMED_SOUND_MISSION_CUB4_14},
+ {"CUB4_15", STREAMED_SOUND_MISSION_CUB4_15}, {"CUB4_16", STREAMED_SOUND_MISSION_CUB4_16}, {"golf_1", STREAMED_SOUND_MISSION_GOLF_1},
+ {"golf_2", STREAMED_SOUND_MISSION_GOLF_2}, {"golf_3", STREAMED_SOUND_MISSION_GOLF_3}, {"bar_1", STREAMED_SOUND_MISSION_BAR_1},
+ {"bar_2", STREAMED_SOUND_MISSION_BAR_2}, {"bar_3", STREAMED_SOUND_MISSION_BAR_3}, {"bar_4", STREAMED_SOUND_MISSION_BAR_4},
+ {"bar_5", STREAMED_SOUND_MISSION_BAR_5}, {"bar_6", STREAMED_SOUND_MISSION_BAR_6}, {"bar_7", STREAMED_SOUND_MISSION_BAR_7},
+ {"bar_8", STREAMED_SOUND_MISSION_BAR_8}, {"strip_1", STREAMED_SOUND_MISSION_STRIP_1}, {"strip_2", STREAMED_SOUND_MISSION_STRIP_2},
+ {"strip_3", STREAMED_SOUND_MISSION_STRIP_3}, {"strip_4", STREAMED_SOUND_MISSION_STRIP_4}, {"strip_5", STREAMED_SOUND_MISSION_STRIP_5},
+ {"strip_6", STREAMED_SOUND_MISSION_STRIP_6}, {"strip_7", STREAMED_SOUND_MISSION_STRIP_7}, {"strip_8", STREAMED_SOUND_MISSION_STRIP_8},
+ {"strip_9", STREAMED_SOUND_MISSION_STRIP_9}, {"star_1", STREAMED_SOUND_MISSION_STAR_1}, {"star_2", STREAMED_SOUND_MISSION_STAR_2},
+ {"star_3", STREAMED_SOUND_MISSION_STAR_3}, {"star_4", STREAMED_SOUND_MISSION_STAR_4}, {"mob_01a", STREAMED_SOUND_MISSION_MOB_01A},
+ {"mob_01b", STREAMED_SOUND_MISSION_MOB_01B}, {"mob_01c", STREAMED_SOUND_MISSION_MOB_01C}, {"mob_02a", STREAMED_SOUND_MISSION_MOB_02A},
+ {"mob_02b", STREAMED_SOUND_MISSION_MOB_02B}, {"mob_02c", STREAMED_SOUND_MISSION_MOB_02C}, {"mob_03a", STREAMED_SOUND_MISSION_MOB_03A},
+ {"mob_03b", STREAMED_SOUND_MISSION_MOB_03B}, {"mob_03c", STREAMED_SOUND_MISSION_MOB_03C}, {"mob_03d", STREAMED_SOUND_MISSION_MOB_03D},
+ {"mob_03e", STREAMED_SOUND_MISSION_MOB_03E}, {"shark_1", STREAMED_SOUND_MISSION_SHARK_1}, {"shark_2", STREAMED_SOUND_MISSION_SHARK_2},
+ {"shark_3", STREAMED_SOUND_MISSION_SHARK_3}, {"shark_4", STREAMED_SOUND_MISSION_SHARK_4}, {"shark_5", STREAMED_SOUND_MISSION_SHARK_5},
+ {"mob_04a", STREAMED_SOUND_MISSION_MOB_04A}, {"mob_04b", STREAMED_SOUND_MISSION_MOB_04B}, {"mob_04c", STREAMED_SOUND_MISSION_MOB_04C},
+ {"mob_04d", STREAMED_SOUND_MISSION_MOB_04D}, {"mob_05a", STREAMED_SOUND_MISSION_MOB_05A}, {"mob_05b", STREAMED_SOUND_MISSION_MOB_05B},
+ {"mob_05c", STREAMED_SOUND_MISSION_MOB_05C}, {"mob_05d", STREAMED_SOUND_MISSION_MOB_05D}, {"mob_06a", STREAMED_SOUND_MISSION_MOB_06A},
+ {"mob_06b", STREAMED_SOUND_MISSION_MOB_06B}, {"mob_06c", STREAMED_SOUND_MISSION_MOB_06C}, {"mob_07a", STREAMED_SOUND_MISSION_MOB_07A},
+ {"mob_07b", STREAMED_SOUND_MISSION_MOB_07B}, {"mob_08a", STREAMED_SOUND_MISSION_MOB_08A}, {"mob_08b", STREAMED_SOUND_MISSION_MOB_08B},
+ {"mob_08c", STREAMED_SOUND_MISSION_MOB_08C}, {"mob_08d", STREAMED_SOUND_MISSION_MOB_08D}, {"mob_08e", STREAMED_SOUND_MISSION_MOB_08E},
+ {"mob_08f", STREAMED_SOUND_MISSION_MOB_08F}, {"mob_08g", STREAMED_SOUND_MISSION_MOB_08G}, {"mob_09a", STREAMED_SOUND_MISSION_MOB_09A},
+ {"mob_09b", STREAMED_SOUND_MISSION_MOB_09B}, {"mob_09c", STREAMED_SOUND_MISSION_MOB_09C}, {"mob_09d", STREAMED_SOUND_MISSION_MOB_09D},
+ {"mob_09e", STREAMED_SOUND_MISSION_MOB_09E}, {"mob_09f", STREAMED_SOUND_MISSION_MOB_09F}, {"mob_10a", STREAMED_SOUND_MISSION_MOB_10A},
+ {"mob_10b", STREAMED_SOUND_MISSION_MOB_10B}, {"mob_10c", STREAMED_SOUND_MISSION_MOB_10C}, {"mob_10d", STREAMED_SOUND_MISSION_MOB_10D},
+ {"mob_10e", STREAMED_SOUND_MISSION_MOB_10E}, {"mob_11a", STREAMED_SOUND_MISSION_MOB_11A}, {"mob_11b", STREAMED_SOUND_MISSION_MOB_11B},
+ {"mob_11c", STREAMED_SOUND_MISSION_MOB_11C}, {"mob_11d", STREAMED_SOUND_MISSION_MOB_11D}, {"mob_11e", STREAMED_SOUND_MISSION_MOB_11E},
+ {"mob_11f", STREAMED_SOUND_MISSION_MOB_11F}, {"mob_14a", STREAMED_SOUND_MISSION_MOB_14A}, {"mob_14b", STREAMED_SOUND_MISSION_MOB_14B},
+ {"mob_14c", STREAMED_SOUND_MISSION_MOB_14C}, {"mob_14d", STREAMED_SOUND_MISSION_MOB_14D}, {"mob_14e", STREAMED_SOUND_MISSION_MOB_14E},
+ {"mob_14f", STREAMED_SOUND_MISSION_MOB_14F}, {"mob_14g", STREAMED_SOUND_MISSION_MOB_14G}, {"mob_14h", STREAMED_SOUND_MISSION_MOB_14H},
+ {"mob_16a", STREAMED_SOUND_MISSION_MOB_16A}, {"mob_16b", STREAMED_SOUND_MISSION_MOB_16B}, {"mob_16c", STREAMED_SOUND_MISSION_MOB_16C},
+ {"mob_16d", STREAMED_SOUND_MISSION_MOB_16D}, {"mob_16e", STREAMED_SOUND_MISSION_MOB_16E}, {"mob_16f", STREAMED_SOUND_MISSION_MOB_16F},
+ {"mob_16g", STREAMED_SOUND_MISSION_MOB_16G}, {"mob_17a", STREAMED_SOUND_MISSION_MOB_17A}, {"mob_17b", STREAMED_SOUND_MISSION_MOB_17B},
+ {"mob_17c", STREAMED_SOUND_MISSION_MOB_17C}, {"mob_17d", STREAMED_SOUND_MISSION_MOB_17D}, {"mob_17e", STREAMED_SOUND_MISSION_MOB_17E},
+ {"mob_17g", STREAMED_SOUND_MISSION_MOB_17G}, {"mob_17h", STREAMED_SOUND_MISSION_MOB_17H}, {"mob_17i", STREAMED_SOUND_MISSION_MOB_17I},
+ {"mob_17j", STREAMED_SOUND_MISSION_MOB_17J}, {"mob_17k", STREAMED_SOUND_MISSION_MOB_17K}, {"mob_17l", STREAMED_SOUND_MISSION_MOB_17L},
+ {"mob_18a", STREAMED_SOUND_MISSION_MOB_18A}, {"mob_18b", STREAMED_SOUND_MISSION_MOB_18B}, {"mob_18c", STREAMED_SOUND_MISSION_MOB_18C},
+ {"mob_18d", STREAMED_SOUND_MISSION_MOB_18D}, {"mob_18e", STREAMED_SOUND_MISSION_MOB_18E}, {"mob_18f", STREAMED_SOUND_MISSION_MOB_18F},
+ {"mob_18g", STREAMED_SOUND_MISSION_MOB_18G}, {"mob_20a", STREAMED_SOUND_MISSION_MOB_20A}, {"mob_20b", STREAMED_SOUND_MISSION_MOB_20B},
+ {"mob_20c", STREAMED_SOUND_MISSION_MOB_20C}, {"mob_20d", STREAMED_SOUND_MISSION_MOB_20D}, {"mob_20e", STREAMED_SOUND_MISSION_MOB_20E},
+ {"mob_24a", STREAMED_SOUND_MISSION_MOB_24A}, {"mob_24b", STREAMED_SOUND_MISSION_MOB_24B}, {"mob_24c", STREAMED_SOUND_MISSION_MOB_24C},
+ {"mob_24d", STREAMED_SOUND_MISSION_MOB_24D}, {"mob_24e", STREAMED_SOUND_MISSION_MOB_24E}, {"mob_24f", STREAMED_SOUND_MISSION_MOB_24F},
+ {"mob_24g", STREAMED_SOUND_MISSION_MOB_24G}, {"mob_24h", STREAMED_SOUND_MISSION_MOB_24H}, {"mob_25a", STREAMED_SOUND_MISSION_MOB_25A},
+ {"mob_25b", STREAMED_SOUND_MISSION_MOB_25B}, {"mob_25c", STREAMED_SOUND_MISSION_MOB_25C}, {"mob_25d", STREAMED_SOUND_MISSION_MOB_25D},
+ {"mob_26a", STREAMED_SOUND_MISSION_MOB_26A}, {"mob_26b", STREAMED_SOUND_MISSION_MOB_26B}, {"mob_26c", STREAMED_SOUND_MISSION_MOB_26C},
+ {"mob_26d", STREAMED_SOUND_MISSION_MOB_26D}, {"mob_26e", STREAMED_SOUND_MISSION_MOB_26E}, {"mob_29a", STREAMED_SOUND_MISSION_MOB_29A},
+ {"mob_29b", STREAMED_SOUND_MISSION_MOB_29B}, {"mob_29c", STREAMED_SOUND_MISSION_MOB_29C}, {"mob_29d", STREAMED_SOUND_MISSION_MOB_29D},
+ {"mob_29e", STREAMED_SOUND_MISSION_MOB_29E}, {"mob_29f", STREAMED_SOUND_MISSION_MOB_29F}, {"mob_29g", STREAMED_SOUND_MISSION_MOB_29G},
+ {"mob_30a", STREAMED_SOUND_MISSION_MOB_30A}, {"mob_30b", STREAMED_SOUND_MISSION_MOB_30B}, {"mob_30c", STREAMED_SOUND_MISSION_MOB_30C},
+ {"mob_30d", STREAMED_SOUND_MISSION_MOB_30D}, {"mob_30e", STREAMED_SOUND_MISSION_MOB_30E}, {"mob_30f", STREAMED_SOUND_MISSION_MOB_30F},
+ {"mob_33a", STREAMED_SOUND_MISSION_MOB_33A}, {"mob_33b", STREAMED_SOUND_MISSION_MOB_33B}, {"mob_33c", STREAMED_SOUND_MISSION_MOB_33C},
+ {"mob_33d", STREAMED_SOUND_MISSION_MOB_33D}, {"mob_34a", STREAMED_SOUND_MISSION_MOB_34A}, {"mob_34b", STREAMED_SOUND_MISSION_MOB_34B},
+ {"mob_34c", STREAMED_SOUND_MISSION_MOB_34C}, {"mob_34d", STREAMED_SOUND_MISSION_MOB_34D}, {"mob_35a", STREAMED_SOUND_MISSION_MOB_35A},
+ {"mob_35b", STREAMED_SOUND_MISSION_MOB_35B}, {"mob_35c", STREAMED_SOUND_MISSION_MOB_35C}, {"mob_35d", STREAMED_SOUND_MISSION_MOB_35D},
+ {"mob_36a", STREAMED_SOUND_MISSION_MOB_36A}, {"mob_36b", STREAMED_SOUND_MISSION_MOB_36B}, {"mob_36c", STREAMED_SOUND_MISSION_MOB_36C},
+ {"mob_40a", STREAMED_SOUND_MISSION_MOB_40A}, {"mob_40b", STREAMED_SOUND_MISSION_MOB_40B}, {"mob_40c", STREAMED_SOUND_MISSION_MOB_40C},
+ {"mob_40d", STREAMED_SOUND_MISSION_MOB_40D}, {"mob_40e", STREAMED_SOUND_MISSION_MOB_40E}, {"mob_40f", STREAMED_SOUND_MISSION_MOB_40F},
+ {"mob_40g", STREAMED_SOUND_MISSION_MOB_40G}, {"mob_40h", STREAMED_SOUND_MISSION_MOB_40H}, {"mob_40i", STREAMED_SOUND_MISSION_MOB_40I},
+ {"mob_41a", STREAMED_SOUND_MISSION_MOB_41A}, {"mob_41b", STREAMED_SOUND_MISSION_MOB_41B}, {"mob_41c", STREAMED_SOUND_MISSION_MOB_41C},
+ {"mob_41d", STREAMED_SOUND_MISSION_MOB_41D}, {"mob_41e", STREAMED_SOUND_MISSION_MOB_41E}, {"mob_41f", STREAMED_SOUND_MISSION_MOB_41F},
+ {"mob_41g", STREAMED_SOUND_MISSION_MOB_41G}, {"mob_41h", STREAMED_SOUND_MISSION_MOB_41H}, {"mob_42a", STREAMED_SOUND_MISSION_MOB_42A},
+ {"mob_42b", STREAMED_SOUND_MISSION_MOB_42B}, {"mob_42c", STREAMED_SOUND_MISSION_MOB_42C}, {"mob_42d", STREAMED_SOUND_MISSION_MOB_42D},
+ {"mob_42e", STREAMED_SOUND_MISSION_MOB_42E}, {"mob_43a", STREAMED_SOUND_MISSION_MOB_43A}, {"mob_43b", STREAMED_SOUND_MISSION_MOB_43B},
+ {"mob_43c", STREAMED_SOUND_MISSION_MOB_43C}, {"mob_43d", STREAMED_SOUND_MISSION_MOB_43D}, {"mob_43e", STREAMED_SOUND_MISSION_MOB_43E},
+ {"mob_43f", STREAMED_SOUND_MISSION_MOB_43F}, {"mob_43g", STREAMED_SOUND_MISSION_MOB_43G}, {"mob_43h", STREAMED_SOUND_MISSION_MOB_43H},
+ {"mob_45a", STREAMED_SOUND_MISSION_MOB_45A}, {"mob_45b", STREAMED_SOUND_MISSION_MOB_45B}, {"mob_45c", STREAMED_SOUND_MISSION_MOB_45C},
+ {"mob_45d", STREAMED_SOUND_MISSION_MOB_45D}, {"mob_45e", STREAMED_SOUND_MISSION_MOB_45E}, {"mob_45f", STREAMED_SOUND_MISSION_MOB_45F},
+ {"mob_45g", STREAMED_SOUND_MISSION_MOB_45G}, {"mob_45h", STREAMED_SOUND_MISSION_MOB_45H}, {"mob_45i", STREAMED_SOUND_MISSION_MOB_45I},
+ {"mob_45j", STREAMED_SOUND_MISSION_MOB_45J}, {"mob_45k", STREAMED_SOUND_MISSION_MOB_45K}, {"mob_45l", STREAMED_SOUND_MISSION_MOB_45L},
+ {"mob_45m", STREAMED_SOUND_MISSION_MOB_45M}, {"mob_45n", STREAMED_SOUND_MISSION_MOB_45N}, {"mob_46a", STREAMED_SOUND_MISSION_MOB_46A},
+ {"mob_46b", STREAMED_SOUND_MISSION_MOB_46B}, {"mob_46c", STREAMED_SOUND_MISSION_MOB_46C}, {"mob_46d", STREAMED_SOUND_MISSION_MOB_46D},
+ {"mob_46e", STREAMED_SOUND_MISSION_MOB_46E}, {"mob_46f", STREAMED_SOUND_MISSION_MOB_46F}, {"mob_46g", STREAMED_SOUND_MISSION_MOB_46G},
+ {"mob_46h", STREAMED_SOUND_MISSION_MOB_46H}, {"mob_47a", STREAMED_SOUND_MISSION_MOB_47A}, {"mob_52a", STREAMED_SOUND_MISSION_MOB_52A},
+ {"mob_52b", STREAMED_SOUND_MISSION_MOB_52B}, {"mob_52c", STREAMED_SOUND_MISSION_MOB_52C}, {"mob_52d", STREAMED_SOUND_MISSION_MOB_52D},
+ {"mob_52e", STREAMED_SOUND_MISSION_MOB_52E}, {"mob_52f", STREAMED_SOUND_MISSION_MOB_52F}, {"mob_52g", STREAMED_SOUND_MISSION_MOB_52G},
+ {"mob_52h", STREAMED_SOUND_MISSION_MOB_52H}, {"mob_54a", STREAMED_SOUND_MISSION_MOB_54A}, {"mob_54b", STREAMED_SOUND_MISSION_MOB_54B},
+ {"mob_54c", STREAMED_SOUND_MISSION_MOB_54C}, {"mob_54d", STREAMED_SOUND_MISSION_MOB_54D}, {"mob_54e", STREAMED_SOUND_MISSION_MOB_54E},
+ {"mob_55a", STREAMED_SOUND_MISSION_MOB_55A}, {"mob_55b", STREAMED_SOUND_MISSION_MOB_55B}, {"mob_55c", STREAMED_SOUND_MISSION_MOB_55C},
+ {"mob_55d", STREAMED_SOUND_MISSION_MOB_55D}, {"mob_55e", STREAMED_SOUND_MISSION_MOB_55E}, {"mob_55f", STREAMED_SOUND_MISSION_MOB_55F},
+ {"mob_56a", STREAMED_SOUND_MISSION_MOB_56A}, {"mob_56b", STREAMED_SOUND_MISSION_MOB_56B}, {"mob_56c", STREAMED_SOUND_MISSION_MOB_56C},
+ {"mob_56d", STREAMED_SOUND_MISSION_MOB_56D}, {"mob_56e", STREAMED_SOUND_MISSION_MOB_56E}, {"mob_56f", STREAMED_SOUND_MISSION_MOB_56F},
+ {"mob_57a", STREAMED_SOUND_MISSION_MOB_57A}, {"mob_57b", STREAMED_SOUND_MISSION_MOB_57B}, {"mob_57c", STREAMED_SOUND_MISSION_MOB_57C},
+ {"mob_57d", STREAMED_SOUND_MISSION_MOB_57D}, {"mob_57e", STREAMED_SOUND_MISSION_MOB_57E}, {"mob_58a", STREAMED_SOUND_MISSION_MOB_58A},
+ {"mob_58b", STREAMED_SOUND_MISSION_MOB_58B}, {"mob_58c", STREAMED_SOUND_MISSION_MOB_58C}, {"mob_58d", STREAMED_SOUND_MISSION_MOB_58D},
+ {"mob_58e", STREAMED_SOUND_MISSION_MOB_58E}, {"mob_58f", STREAMED_SOUND_MISSION_MOB_58F}, {"mob_58g", STREAMED_SOUND_MISSION_MOB_58G},
+ {"mob_61a", STREAMED_SOUND_MISSION_MOB_61A}, {"mob_61b", STREAMED_SOUND_MISSION_MOB_61B}, {"mob_62a", STREAMED_SOUND_MISSION_MOB_62A},
+ {"mob_62b", STREAMED_SOUND_MISSION_MOB_62B}, {"mob_62c", STREAMED_SOUND_MISSION_MOB_62C}, {"mob_62d", STREAMED_SOUND_MISSION_MOB_62D},
+ {"mob_63a", STREAMED_SOUND_MISSION_MOB_63A}, {"mob_63b", STREAMED_SOUND_MISSION_MOB_63B}, {"mob_63c", STREAMED_SOUND_MISSION_MOB_63C},
+ {"mob_63d", STREAMED_SOUND_MISSION_MOB_63D}, {"mob_63e", STREAMED_SOUND_MISSION_MOB_63E}, {"mob_63f", STREAMED_SOUND_MISSION_MOB_63F},
+ {"mob_63g", STREAMED_SOUND_MISSION_MOB_63G}, {"mob_63h", STREAMED_SOUND_MISSION_MOB_63H}, {"mob_63i", STREAMED_SOUND_MISSION_MOB_63I},
+ {"mob_63j", STREAMED_SOUND_MISSION_MOB_63J}, {"mob_66a", STREAMED_SOUND_MISSION_MOB_66A}, {"mob_66b", STREAMED_SOUND_MISSION_MOB_66B},
+ {"mob_68a", STREAMED_SOUND_MISSION_MOB_68A}, {"mob_68b", STREAMED_SOUND_MISSION_MOB_68B}, {"mob_68c", STREAMED_SOUND_MISSION_MOB_68C},
+ {"mob_68d", STREAMED_SOUND_MISSION_MOB_68D}, {"mob_70a", STREAMED_SOUND_MISSION_MOB_70A}, {"mob_70b", STREAMED_SOUND_MISSION_MOB_70B},
+ {"mob_71a", STREAMED_SOUND_MISSION_MOB_71A}, {"mob_71b", STREAMED_SOUND_MISSION_MOB_71B}, {"mob_71c", STREAMED_SOUND_MISSION_MOB_71C},
+ {"mob_71d", STREAMED_SOUND_MISSION_MOB_71D}, {"mob_71e", STREAMED_SOUND_MISSION_MOB_71E}, {"mob_71f", STREAMED_SOUND_MISSION_MOB_71F},
+ {"mob_71g", STREAMED_SOUND_MISSION_MOB_71G}, {"mob_71h", STREAMED_SOUND_MISSION_MOB_71H}, {"mob_71i", STREAMED_SOUND_MISSION_MOB_71I},
+ {"mob_71j", STREAMED_SOUND_MISSION_MOB_71J}, {"mob_71k", STREAMED_SOUND_MISSION_MOB_71K}, {"mob_71l", STREAMED_SOUND_MISSION_MOB_71L},
+ {"mob_71m", STREAMED_SOUND_MISSION_MOB_71M}, {"mob_71n", STREAMED_SOUND_MISSION_MOB_71N}, {"mob_72a", STREAMED_SOUND_MISSION_MOB_72A},
+ {"mob_72b", STREAMED_SOUND_MISSION_MOB_72B}, {"mob_72c", STREAMED_SOUND_MISSION_MOB_72C}, {"mob_72d", STREAMED_SOUND_MISSION_MOB_72D},
+ {"mob_72e", STREAMED_SOUND_MISSION_MOB_72E}, {"mob_72f", STREAMED_SOUND_MISSION_MOB_72F}, {"mob_72g", STREAMED_SOUND_MISSION_MOB_72G},
+ {"mob_73a", STREAMED_SOUND_MISSION_MOB_73A}, {"mob_73c", STREAMED_SOUND_MISSION_MOB_73C}, {"mob_73d", STREAMED_SOUND_MISSION_MOB_73D},
+ {"mob_73f", STREAMED_SOUND_MISSION_MOB_73F}, {"mob_73g", STREAMED_SOUND_MISSION_MOB_73G}, {"mob_73i", STREAMED_SOUND_MISSION_MOB_73I},
+ {"mob_95a", STREAMED_SOUND_MISSION_MOB_95A}, {"mob_96a", STREAMED_SOUND_MISSION_MOB_96A}, {"mob_98a", STREAMED_SOUND_MISSION_MOB_98A},
+ {"mob_99a", STREAMED_SOUND_MISSION_MOB_99A}, {"job1_1b", STREAMED_SOUND_MISSION_JOB1_1B}, {"job1_1c", STREAMED_SOUND_MISSION_JOB1_1C},
+ {"job1_1d", STREAMED_SOUND_MISSION_JOB1_1D}, {"job2_1b", STREAMED_SOUND_MISSION_JOB2_1B}, {"job2_2", STREAMED_SOUND_MISSION_JOB2_2},
+ {"job2_3", STREAMED_SOUND_MISSION_JOB2_3}, {"job2_4", STREAMED_SOUND_MISSION_JOB2_4}, {"job2_5", STREAMED_SOUND_MISSION_JOB2_5},
+ {"job2_6", STREAMED_SOUND_MISSION_JOB2_6}, {"job2_7", STREAMED_SOUND_MISSION_JOB2_7}, {"job2_8", STREAMED_SOUND_MISSION_JOB2_8},
+ {"job2_9", STREAMED_SOUND_MISSION_JOB2_9}, {"job3_1", STREAMED_SOUND_MISSION_JOB3_1}, {"job3_2", STREAMED_SOUND_MISSION_JOB3_2},
+ {"job3_3", STREAMED_SOUND_MISSION_JOB3_3}, {"job4_1", STREAMED_SOUND_MISSION_JOB4_1}, {"job4_2", STREAMED_SOUND_MISSION_JOB4_2},
+ {"job4_3", STREAMED_SOUND_MISSION_JOB4_3}, {"job5_1", STREAMED_SOUND_MISSION_JOB5_1}, {"job5_2", STREAMED_SOUND_MISSION_JOB5_2},
+ {"job5_3", STREAMED_SOUND_MISSION_JOB5_3}, {"bjm1_20", STREAMED_SOUND_MISSION_BJM1_20}, {"bjm1_4", STREAMED_SOUND_MISSION_BJM1_4},
+ {"bjm1_5", STREAMED_SOUND_MISSION_BJM1_5}, {"merc_39", STREAMED_SOUND_MISSION_MERC_39}, {"mono_1", STREAMED_SOUND_MISSION_MONO_1},
+ {"mono_2", STREAMED_SOUND_MISSION_MONO_2}, {"mono_3", STREAMED_SOUND_MISSION_MONO_3}, {"mono_4", STREAMED_SOUND_MISSION_MONO_4},
+ {"mono_5", STREAMED_SOUND_MISSION_MONO_5}, {"mono_6", STREAMED_SOUND_MISSION_MONO_6}, {"mono_7", STREAMED_SOUND_MISSION_MONO_7},
+ {"mono_8", STREAMED_SOUND_MISSION_MONO_8}, {"mono_9", STREAMED_SOUND_MISSION_MONO_9}, {"mono10", STREAMED_SOUND_MISSION_MONO10},
+ {"mono11", STREAMED_SOUND_MISSION_MONO11}, {"mono12", STREAMED_SOUND_MISSION_MONO12}, {"mono13", STREAMED_SOUND_MISSION_MONO13},
+ {"mono14", STREAMED_SOUND_MISSION_MONO14}, {"mono15", STREAMED_SOUND_MISSION_MONO15}, {"mono16", STREAMED_SOUND_MISSION_MONO16},
+ {"fud_01", STREAMED_SOUND_MISSION_FUD_01}, {"fud_02", STREAMED_SOUND_MISSION_FUD_02}, {"fud_03", STREAMED_SOUND_MISSION_FUD_03},
+ {"fud_04", STREAMED_SOUND_MISSION_FUD_04}, {"fud_05", STREAMED_SOUND_MISSION_FUD_05}, {"fud_06", STREAMED_SOUND_MISSION_FUD_06},
+ {"fud_07", STREAMED_SOUND_MISSION_FUD_07}, {"fud_08", STREAMED_SOUND_MISSION_FUD_08}, {"fud_09", STREAMED_SOUND_MISSION_FUD_09},
+ {"fud_10", STREAMED_SOUND_MISSION_FUD_10}, {"fud_11", STREAMED_SOUND_MISSION_FUD_11}, {"fud_12", STREAMED_SOUND_MISSION_FUD_12},
+ {"fud_13", STREAMED_SOUND_MISSION_FUD_13}, {"fud_14", STREAMED_SOUND_MISSION_FUD_14}, {"fud_15", STREAMED_SOUND_MISSION_FUD_15},
+ {"fud_16", STREAMED_SOUND_MISSION_FUD_16}, {"fud_17", STREAMED_SOUND_MISSION_FUD_17}, {"fud_18", STREAMED_SOUND_MISSION_FUD_18},
+ {"fud_19", STREAMED_SOUND_MISSION_FUD_19}, {"fud_20", STREAMED_SOUND_MISSION_FUD_20}, {"burg_01", STREAMED_SOUND_MISSION_BURG_01},
+ {"burg_02", STREAMED_SOUND_MISSION_BURG_02}, {"burg_03", STREAMED_SOUND_MISSION_BURG_03}, {"burg_04", STREAMED_SOUND_MISSION_BURG_04},
+ {"burg_05", STREAMED_SOUND_MISSION_BURG_05}, {"burg_06", STREAMED_SOUND_MISSION_BURG_06}, {"burg_07", STREAMED_SOUND_MISSION_BURG_07},
+ {"burg_08", STREAMED_SOUND_MISSION_BURG_08}, {"burg_09", STREAMED_SOUND_MISSION_BURG_09}, {"burg_10", STREAMED_SOUND_MISSION_BURG_10},
+ {"burg_11", STREAMED_SOUND_MISSION_BURG_11}, {"burg_12", STREAMED_SOUND_MISSION_BURG_12}, {"crust01", STREAMED_SOUND_MISSION_CRUST01},
+ {"crust02", STREAMED_SOUND_MISSION_CRUST02}, {"crust03", STREAMED_SOUND_MISSION_CRUST03}, {"crust04", STREAMED_SOUND_MISSION_CRUST04},
+ {"crust05", STREAMED_SOUND_MISSION_CRUST05}, {"crust06", STREAMED_SOUND_MISSION_CRUST06}, {"crust07", STREAMED_SOUND_MISSION_CRUST07},
+ {"crust08", STREAMED_SOUND_MISSION_CRUST08}, {"crust09", STREAMED_SOUND_MISSION_CRUST09}, {"band_01", STREAMED_SOUND_MISSION_BAND_01},
+ {"band_02", STREAMED_SOUND_MISSION_BAND_02}, {"band_03", STREAMED_SOUND_MISSION_BAND_03}, {"band_04", STREAMED_SOUND_MISSION_BAND_04},
+ {"band_05", STREAMED_SOUND_MISSION_BAND_05}, {"band_06", STREAMED_SOUND_MISSION_BAND_06}, {"band_07", STREAMED_SOUND_MISSION_BAND_07},
+ {"band_08", STREAMED_SOUND_MISSION_BAND_08}, {"shaft01", STREAMED_SOUND_MISSION_SHAFT01}, {"shaft02", STREAMED_SOUND_MISSION_SHAFT02},
+ {"shaft03", STREAMED_SOUND_MISSION_SHAFT03}, {"shaft04", STREAMED_SOUND_MISSION_SHAFT04}, {"shaft05", STREAMED_SOUND_MISSION_SHAFT05},
+ {"shaft06", STREAMED_SOUND_MISSION_SHAFT06}, {"shaft07", STREAMED_SOUND_MISSION_SHAFT07}, {"shaft08", STREAMED_SOUND_MISSION_SHAFT08},
+ {"piss_01", STREAMED_SOUND_MISSION_PISS_01}, {"piss_02", STREAMED_SOUND_MISSION_PISS_02}, {"piss_03", STREAMED_SOUND_MISSION_PISS_03},
+ {"piss_04", STREAMED_SOUND_MISSION_PISS_04}, {"piss_05", STREAMED_SOUND_MISSION_PISS_05}, {"piss_06", STREAMED_SOUND_MISSION_PISS_06},
+ {"piss_07", STREAMED_SOUND_MISSION_PISS_07}, {"piss_08", STREAMED_SOUND_MISSION_PISS_08}, {"piss_09", STREAMED_SOUND_MISSION_PISS_09},
+ {"piss_10", STREAMED_SOUND_MISSION_PISS_10}, {"piss_11", STREAMED_SOUND_MISSION_PISS_11}, {"piss_12", STREAMED_SOUND_MISSION_PISS_12},
+ {"piss_13", STREAMED_SOUND_MISSION_PISS_13}, {"piss_14", STREAMED_SOUND_MISSION_PISS_14}, {"piss_15", STREAMED_SOUND_MISSION_PISS_15},
+ {"piss_16", STREAMED_SOUND_MISSION_PISS_16}, {"piss_17", STREAMED_SOUND_MISSION_PISS_17}, {"piss_18", STREAMED_SOUND_MISSION_PISS_18},
+ {"piss_19", STREAMED_SOUND_MISSION_PISS_19}, {"gimme01", STREAMED_SOUND_MISSION_GIMME01}, {"gimme02", STREAMED_SOUND_MISSION_GIMME02},
+ {"gimme03", STREAMED_SOUND_MISSION_GIMME03}, {"gimme04", STREAMED_SOUND_MISSION_GIMME04}, {"gimme05", STREAMED_SOUND_MISSION_GIMME05},
+ {"gimme06", STREAMED_SOUND_MISSION_GIMME06}, {"gimme07", STREAMED_SOUND_MISSION_GIMME07}, {"gimme08", STREAMED_SOUND_MISSION_GIMME08},
+ {"gimme09", STREAMED_SOUND_MISSION_GIMME09}, {"gimme10", STREAMED_SOUND_MISSION_GIMME10}, {"gimme11", STREAMED_SOUND_MISSION_GIMME11},
+ {"gimme12", STREAMED_SOUND_MISSION_GIMME12}, {"gimme13", STREAMED_SOUND_MISSION_GIMME13}, {"gimme14", STREAMED_SOUND_MISSION_GIMME14},
+ {"gimme15", STREAMED_SOUND_MISSION_GIMME15}, {"bust_01", STREAMED_SOUND_MISSION_BUST_01}, {"bust_02", STREAMED_SOUND_MISSION_BUST_02},
+ {"bust_03", STREAMED_SOUND_MISSION_BUST_03}, {"bust_04", STREAMED_SOUND_MISSION_BUST_04}, {"bust_05", STREAMED_SOUND_MISSION_BUST_05},
+ {"bust_06", STREAMED_SOUND_MISSION_BUST_06}, {"bust_07", STREAMED_SOUND_MISSION_BUST_07}, {"bust_08", STREAMED_SOUND_MISSION_BUST_08},
+ {"bust_09", STREAMED_SOUND_MISSION_BUST_09}, {"bust_10", STREAMED_SOUND_MISSION_BUST_10}, {"bust_11", STREAMED_SOUND_MISSION_BUST_11},
+ {"bust_12", STREAMED_SOUND_MISSION_BUST_12}, {"bust_13", STREAMED_SOUND_MISSION_BUST_13}, {"bust_14", STREAMED_SOUND_MISSION_BUST_14},
+ {"bust_15", STREAMED_SOUND_MISSION_BUST_15}, {"bust_16", STREAMED_SOUND_MISSION_BUST_16}, {"bust_17", STREAMED_SOUND_MISSION_BUST_17},
+ {"bust_18", STREAMED_SOUND_MISSION_BUST_18}, {"bust_19", STREAMED_SOUND_MISSION_BUST_19}, {"bust_20", STREAMED_SOUND_MISSION_BUST_20},
+ {"bust_21", STREAMED_SOUND_MISSION_BUST_21}, {"bust_22", STREAMED_SOUND_MISSION_BUST_22}, {"bust_23", STREAMED_SOUND_MISSION_BUST_23},
+ {"bust_24", STREAMED_SOUND_MISSION_BUST_24}, {"bust_25", STREAMED_SOUND_MISSION_BUST_25}, {"bust_26", STREAMED_SOUND_MISSION_BUST_26},
+ {"bust_27", STREAMED_SOUND_MISSION_BUST_27}, {"bust_28", STREAMED_SOUND_MISSION_BUST_28}, {nil, 0} };
int32
FindMissionAudioSfx(const char *name)
@@ -8382,100 +9839,130 @@ FindMissionAudioSfx(const char *name)
return NO_SAMPLE;
}
+const char *
+cAudioManager::GetMissionAudioLoadedLabel(uint8 slot)
+{
+ if (m_bIsInitialised && slot < MISSION_AUDIO_SLOTS && m_sMissionAudio.m_nSampleIndex[slot] != NO_SAMPLE) {
+ for (uint32 i = 0; MissionAudioNameSfxAssoc[i].m_pName != nil; ++i) {
+ if (m_sMissionAudio.m_nSampleIndex[slot] == MissionAudioNameSfxAssoc[i].m_nId)
+ return MissionAudioNameSfxAssoc[i].m_pName;
+ }
+ }
+
+#ifdef THIS_IS_STUPID
+ return MissionAudioNameSfxAssoc[0].m_pName; // yeah this is dumb
+#else
+ return "";
+#endif
+}
+
bool8
cAudioManager::MissionScriptAudioUsesPoliceChannel(uint32 soundMission)
{
- 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;
- }
+ return FALSE;
}
void
-cAudioManager::PreloadMissionAudio(Const char *name)
+cAudioManager::PreloadMissionAudio(uint8 slot, Const char *name)
{
- if (m_bIsInitialised) {
+ if (m_bIsInitialised && slot < MISSION_AUDIO_SLOTS) {
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.m_bIsPlaying = FALSE;
- m_sMissionAudio.m_nMissionAudioCounter = m_nTimeSpent * SampleManager.GetStreamedFileLength(missionAudioSfx) / 1000;
- m_sMissionAudio.m_nMissionAudioCounter *= 4;
- m_sMissionAudio.m_bIsPlayed = FALSE;
- m_sMissionAudio.m_bPredefinedProperties = TRUE;
- g_bMissionAudioLoadFailed = FALSE;
+ m_sMissionAudio.m_nSampleIndex[slot] = missionAudioSfx;
+ m_sMissionAudio.m_nLoadingStatus[slot] = LOADING_STATUS_NOT_LOADED;
+ m_sMissionAudio.m_nPlayStatus[slot] = PLAY_STATUS_STOPPED;
+ m_sMissionAudio.m_bIsPlaying[slot] = FALSE;
+ m_sMissionAudio.m_nMissionAudioCounter[slot] = m_nTimeSpent * SampleManager.GetStreamedFileLength(missionAudioSfx) / 1000;
+ m_sMissionAudio.m_nMissionAudioCounter[slot] *= 4;
+ m_sMissionAudio.m_bIsPlayed[slot] = FALSE;
+ m_sMissionAudio.m_bPredefinedProperties[slot] = TRUE;
+ g_bMissionAudioLoadFailed[slot] = FALSE;
}
}
}
uint8
-cAudioManager::GetMissionAudioLoadingStatus()
+cAudioManager::GetMissionAudioLoadingStatus(uint8 slot)
{
- if (m_bIsInitialised)
- return m_sMissionAudio.m_nLoadingStatus;
+ if (m_bIsInitialised && slot < MISSION_AUDIO_SLOTS)
+ return m_sMissionAudio.m_nLoadingStatus[slot];
return LOADING_STATUS_LOADED;
}
void
-cAudioManager::SetMissionAudioLocation(float x, float y, float z)
+cAudioManager::SetMissionAudioLocation(uint8 slot, float x, float y, float z)
{
- if (m_bIsInitialised) {
- m_sMissionAudio.m_bPredefinedProperties = FALSE;
- m_sMissionAudio.m_vecPos = CVector(x, y, z);
+ if (m_bIsInitialised && slot < MISSION_AUDIO_SLOTS) {
+ m_sMissionAudio.m_bPredefinedProperties[slot] = FALSE;
+ m_sMissionAudio.m_vecPos[slot] = CVector(x, y, z);
}
}
void
-cAudioManager::PlayLoadedMissionAudio()
+cAudioManager::PlayLoadedMissionAudio(uint8 slot)
{
- 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;
+ if (m_bIsInitialised && slot < MISSION_AUDIO_SLOTS && m_sMissionAudio.m_nSampleIndex[slot] != NO_SAMPLE && m_sMissionAudio.m_nLoadingStatus[slot] == LOADING_STATUS_LOADED &&
+ m_sMissionAudio.m_nPlayStatus[slot] == PLAY_STATUS_STOPPED)
+ m_sMissionAudio.m_bIsPlayed[slot] = TRUE;
}
bool8
-cAudioManager::IsMissionAudioSampleFinished()
+cAudioManager::ShouldDuckMissionAudio(uint8 slot)
{
- if (m_bIsInitialised)
- return m_sMissionAudio.m_nPlayStatus == PLAY_STATUS_FINISHED;
+ if (IsMissionAudioSamplePlaying(slot))
+ return m_sMissionAudio.m_nSampleIndex[slot] != STREAMED_SOUND_MISSION_ROK2_01;
+ return FALSE;
+}
- static int32 cPretendFrame = 1;
+bool8
+cAudioManager::IsMissionAudioSamplePlaying(uint8 slot)
+{
+ if (m_bIsInitialised) {
+ if (slot < MISSION_AUDIO_SLOTS)
+ return m_sMissionAudio.m_nPlayStatus[slot] == PLAY_STATUS_PLAYING;
+ else
+ return TRUE;
+ } else {
+ static int32 cPretendFrame[MISSION_AUDIO_SLOTS] = { 1, 1 };
- return (cPretendFrame++ & 63) == 0;
+ return (cPretendFrame[slot]++ % 64) != 0;
+ }
}
-void
-cAudioManager::ClearMissionAudio()
+bool8
+cAudioManager::IsMissionAudioSampleFinished(uint8 slot)
{
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.m_bIsPlaying = FALSE;
- m_sMissionAudio.m_bIsPlayed = FALSE;
- m_sMissionAudio.m_bPredefinedProperties = TRUE;
- m_sMissionAudio.m_nMissionAudioCounter = 0;
+ if (slot < MISSION_AUDIO_SLOTS)
+ return m_sMissionAudio.m_nPlayStatus[slot] == PLAY_STATUS_FINISHED;
+ else
+ return TRUE;
}
+
+ static int32 cPretendFrame[MISSION_AUDIO_SLOTS] = { 1, 1 };
+
+ return (cPretendFrame[slot]++ % 64) == 0;
}
void
-cAudioManager::ProcessMissionAudio()
+cAudioManager::ClearMissionAudio(uint8 slot)
+{
+ if (m_bIsInitialised && slot < MISSION_AUDIO_SLOTS) {
+ m_sMissionAudio.m_nSampleIndex[slot] = NO_SAMPLE;
+ m_sMissionAudio.m_nLoadingStatus[slot] = LOADING_STATUS_NOT_LOADED;
+ m_sMissionAudio.m_nPlayStatus[slot] = PLAY_STATUS_STOPPED;
+ m_sMissionAudio.m_bIsPlaying[slot] = FALSE;
+ m_sMissionAudio.m_bIsPlayed[slot] = FALSE;
+ m_sMissionAudio.m_bPredefinedProperties[slot] = TRUE;
+ m_sMissionAudio.m_nMissionAudioCounter[slot] = 0;
+ m_sMissionAudio.m_bIsMobile[slot] = FALSE;
+ SampleManager.StopStreamedFile(slot + 1);
+ }
+}
+
+void
+cAudioManager::ProcessMissionAudioSlot(uint8 slot)
{
float dist;
uint8 emittingVol;
@@ -8483,104 +9970,137 @@ cAudioManager::ProcessMissionAudio()
float distSquared;
CVector vec;
- static uint8 nCheckPlayingDelay = 0;
- static uint8 nFramesUntilFailedLoad = 0;
- static uint8 nFramesForPretendPlaying = 0;
+ static uint8 nCheckPlayingDelay[MISSION_AUDIO_SLOTS] = { 0, 0 };
+ static uint8 nFramesUntilFailedLoad[MISSION_AUDIO_SLOTS] = { 0, 0 };
+ static uint8 nFramesForPretendPlaying[MISSION_AUDIO_SLOTS] = { 0, 0 };
- if (!m_bIsInitialised) return;
- if (m_sMissionAudio.m_nSampleIndex == NO_SAMPLE) return;
+ if (m_sMissionAudio.m_nSampleIndex[slot] == NO_SAMPLE) return;
- switch (m_sMissionAudio.m_nLoadingStatus) {
+ switch (m_sMissionAudio.m_nLoadingStatus[slot]) {
case LOADING_STATUS_NOT_LOADED:
- SampleManager.PreloadStreamedFile(m_sMissionAudio.m_nSampleIndex, 1);
- m_sMissionAudio.m_nLoadingStatus = LOADING_STATUS_LOADED;
- nFramesUntilFailedLoad = 0;
+ SampleManager.PreloadStreamedFile(m_sMissionAudio.m_nSampleIndex[slot], slot + 1);
+ m_sMissionAudio.m_nLoadingStatus[slot] = LOADING_STATUS_LOADED;
+ nFramesUntilFailedLoad[slot] = 0;
break;
case LOADING_STATUS_LOADED:
- if (!m_sMissionAudio.m_bIsPlayed)
+ if (!m_sMissionAudio.m_bIsPlayed[slot])
return;
- if (g_bMissionAudioLoadFailed) {
+ if (g_bMissionAudioLoadFailed[slot]) {
if (m_bTimerJustReset) {
- ClearMissionAudio();
- SampleManager.StopStreamedFile(1);
- nFramesForPretendPlaying = 0;
- nCheckPlayingDelay = 0;
- nFramesUntilFailedLoad = 0;
+ ClearMissionAudio(slot);
+ SampleManager.StopStreamedFile(slot + 1);
+ nFramesForPretendPlaying[slot] = 0;
+ nCheckPlayingDelay[slot] = 0;
+ nFramesUntilFailedLoad[slot] = 0;
} else if (!m_nUserPause) {
- if (++nFramesForPretendPlaying < 120) {
- m_sMissionAudio.m_nPlayStatus = PLAY_STATUS_PLAYING;
+ if (++nFramesForPretendPlaying[slot] < 90) {
+ m_sMissionAudio.m_nPlayStatus[slot] = PLAY_STATUS_PLAYING;
} else {
- m_sMissionAudio.m_nPlayStatus = PLAY_STATUS_FINISHED;
- m_sMissionAudio.m_nSampleIndex = NO_SAMPLE;
+ m_sMissionAudio.m_nPlayStatus[slot] = PLAY_STATUS_FINISHED;
+ m_sMissionAudio.m_nSampleIndex[slot] = NO_SAMPLE;
}
}
break;
}
- switch (m_sMissionAudio.m_nPlayStatus) {
+ switch (m_sMissionAudio.m_nPlayStatus[slot]) {
case PLAY_STATUS_STOPPED:
- if (MissionScriptAudioUsesPoliceChannel(m_sMissionAudio.m_nSampleIndex)) {
- SetMissionScriptPoliceAudio(m_sMissionAudio.m_nSampleIndex);
+ if (MissionScriptAudioUsesPoliceChannel(m_sMissionAudio.m_nSampleIndex[slot])) {
+ SetMissionScriptPoliceAudio(m_sMissionAudio.m_nSampleIndex[slot]);
} else {
if (m_nUserPause)
- SampleManager.PauseStream(TRUE, 1);
- if (m_sMissionAudio.m_bPredefinedProperties) {
- SampleManager.SetStreamedVolumeAndPan(80, 63, TRUE, 1);
+ SampleManager.PauseStream(TRUE, slot + 1);
+ if (m_sMissionAudio.m_bPredefinedProperties[slot]) {
+ if (m_sMissionAudio.m_nSampleIndex[slot] == STREAMED_SOUND_MISSION_CAMERAL)
+ SampleManager.SetStreamedVolumeAndPan(80, 0, TRUE, slot + 1);
+ else if (m_sMissionAudio.m_nSampleIndex[slot] == STREAMED_SOUND_MISSION_CAMERAR)
+ SampleManager.SetStreamedVolumeAndPan(80, 127, TRUE, slot + 1);
+ else
+ SampleManager.SetStreamedVolumeAndPan(80, 63, TRUE, slot + 1);
} else {
- distSquared = GetDistanceSquared(m_sMissionAudio.m_vecPos);
- if (distSquared >= SQR(50.0f)) {
+ distSquared = GetDistanceSquared(m_sMissionAudio.m_vecPos[slot]);
+ if (distSquared >= SQR(80.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);
+ emittingVol = 80;
+ if (distSquared > 0.0f) {
+ dist = Sqrt(distSquared);
+ emittingVol = ComputeVolume(80, 80.0f, dist);
+ }
+ TranslateEntity(&m_sMissionAudio.m_vecPos[slot], &vec);
+ pan = ComputePan(80.f, &vec);
}
- SampleManager.SetStreamedVolumeAndPan(emittingVol, pan, TRUE, 1);
+ SampleManager.SetStreamedVolumeAndPan(emittingVol, pan, TRUE, slot + 1);
}
- SampleManager.StartPreloadedStreamedFile(1);
+ SampleManager.StartPreloadedStreamedFile(slot + 1);
}
- m_sMissionAudio.m_nPlayStatus = PLAY_STATUS_PLAYING;
- nCheckPlayingDelay = 30;
+ m_sMissionAudio.m_nPlayStatus[slot] = PLAY_STATUS_PLAYING;
+ nCheckPlayingDelay[slot] = 30;
+ if (m_sMissionAudio.m_nSampleIndex[slot] >= STREAMED_SOUND_MISSION_MOB_01A && m_sMissionAudio.m_nSampleIndex[slot] <= STREAMED_SOUND_MISSION_MOB_99A)
+ m_sMissionAudio.m_bIsMobile[slot] = TRUE;
break;
case PLAY_STATUS_PLAYING:
if (m_bTimerJustReset) {
- ClearMissionAudio();
- SampleManager.StopStreamedFile(1);
+ ClearMissionAudio(slot);
+ SampleManager.StopStreamedFile(slot + 1);
break;
}
- if (MissionScriptAudioUsesPoliceChannel(m_sMissionAudio.m_nSampleIndex)) {
+ if (MissionScriptAudioUsesPoliceChannel(m_sMissionAudio.m_nSampleIndex[slot])) {
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;
+ if (nCheckPlayingDelay[slot]) {
+ --nCheckPlayingDelay[slot];
+ } else if ((g_bMissionAudioLoadFailed[slot] && m_sMissionAudio.m_nMissionAudioCounter[slot]-- == 0) || GetMissionScriptPoliceAudioPlayingStatus() == PLAY_STATUS_FINISHED) {
+ m_sMissionAudio.m_nPlayStatus[slot] = PLAY_STATUS_FINISHED;
+ if (m_sMissionAudio.m_nSampleIndex[slot] >= STREAMED_SOUND_MISSION_MOB_01A && m_sMissionAudio.m_nSampleIndex[slot] <= STREAMED_SOUND_MISSION_MOB_99A)
+ m_sMissionAudio.m_bIsMobile[slot] = FALSE;
+ m_sMissionAudio.m_nSampleIndex[slot] = NO_SAMPLE;
+ SampleManager.StopStreamedFile(slot + 1);
+ m_sMissionAudio.m_nMissionAudioCounter[slot] = 0;
}
}
- } else if (m_sMissionAudio.m_bIsPlaying) {
- if (SampleManager.IsStreamPlaying(1) || m_nUserPause || m_nPreviousUserPause) {
+ } else if (m_sMissionAudio.m_bIsPlaying[slot]) {
+ if (SampleManager.IsStreamPlaying(slot + 1) || m_nUserPause || m_nPreviousUserPause) {
if (m_nUserPause)
- SampleManager.PauseStream(TRUE, 1);
+ SampleManager.PauseStream(TRUE, slot + 1);
else
- SampleManager.PauseStream(FALSE, 1);
+ {
+ SampleManager.PauseStream(FALSE, slot + 1);
+ if (!m_sMissionAudio.m_bPredefinedProperties[slot]) {
+ distSquared = GetDistanceSquared(m_sMissionAudio.m_vecPos[slot]);
+ if (distSquared >= SQR(80.0f)) {
+ emittingVol = 0;
+ pan = 63;
+ } else {
+ emittingVol = 127;
+ if (distSquared > 0.0f) {
+ dist = Sqrt(distSquared);
+ emittingVol = ComputeVolume(127, 80.0f, dist);
+ }
+ TranslateEntity(&m_sMissionAudio.m_vecPos[slot], &vec);
+ pan = ComputePan(80.f, &vec);
+ }
+ SampleManager.SetStreamedVolumeAndPan(emittingVol, pan, TRUE, slot + 1);
+ }
+ }
+ } else if (m_sMissionAudio.m_nSampleIndex[slot] == STREAMED_SOUND_MISSION_ROK2_01) {
+ m_sMissionAudio.m_nPlayStatus[slot] = PLAY_STATUS_STOPPED;
} else {
- m_sMissionAudio.m_nPlayStatus = PLAY_STATUS_FINISHED;
- m_sMissionAudio.m_nSampleIndex = NO_SAMPLE;
- SampleManager.StopStreamedFile(1);
- m_sMissionAudio.m_nMissionAudioCounter = 0;
+ m_sMissionAudio.m_nPlayStatus[slot] = PLAY_STATUS_FINISHED;
+ if (m_sMissionAudio.m_nSampleIndex[slot] >= STREAMED_SOUND_MISSION_MOB_01A && m_sMissionAudio.m_nSampleIndex[slot] <= STREAMED_SOUND_MISSION_MOB_99A)
+ m_sMissionAudio.m_bIsMobile[slot] = FALSE;
+ m_sMissionAudio.m_nSampleIndex[slot] = NO_SAMPLE;
+ SampleManager.StopStreamedFile(slot + 1);
+ m_sMissionAudio.m_nMissionAudioCounter[slot] = 0;
}
} else {
if (m_nUserPause)
break;
- if (nCheckPlayingDelay--) {
- if (!SampleManager.IsStreamPlaying(1))
+ if (nCheckPlayingDelay[slot]--) {
+ if (!SampleManager.IsStreamPlaying(slot + 1))
break;
- nCheckPlayingDelay = 0;
+ nCheckPlayingDelay[slot] = 0;
}
- m_sMissionAudio.m_bIsPlaying = TRUE;
+ m_sMissionAudio.m_bIsPlaying[slot] = TRUE;
}
break;
default:
@@ -8588,15 +10108,32 @@ cAudioManager::ProcessMissionAudio()
}
break;
case LOADING_STATUS_FAILED:
- if (++nFramesUntilFailedLoad >= 90) {
- nFramesForPretendPlaying = 0;
- g_bMissionAudioLoadFailed = TRUE;
- nFramesUntilFailedLoad = 0;
- m_sMissionAudio.m_nLoadingStatus = LOADING_STATUS_LOADED;
+ if (++nFramesUntilFailedLoad[slot] >= 120) {
+ nFramesForPretendPlaying[slot] = 0;
+ g_bMissionAudioLoadFailed[slot] = TRUE;
+ nFramesUntilFailedLoad[slot] = 0;
+ m_sMissionAudio.m_nLoadingStatus[slot] = LOADING_STATUS_LOADED;
}
break;
default:
break;
}
}
+
+void
+cAudioManager::ProcessMissionAudio()
+{
+ if (!m_bIsInitialised) return;
+
+ for (int i = 0; i < MISSION_AUDIO_SLOTS; i++)
+ ProcessMissionAudioSlot(i);
+
+ if (m_sMissionAudio.m_bIsMobile[0] || m_sMissionAudio.m_bIsMobile[1])
+ field_5538 = 64;
+ else if (field_5538 < 127) {
+ field_5538 += 5;
+ if (field_5538 > 127)
+ field_5538 = 127;
+ }
+}
#pragma endregion All the mission audio stuff
diff --git a/src/audio/AudioManager.cpp b/src/audio/AudioManager.cpp
index 9b1337c9..686b9206 100644
--- a/src/audio/AudioManager.cpp
+++ b/src/audio/AudioManager.cpp
@@ -10,16 +10,18 @@
#include "sampman.h"
#include "Camera.h"
#include "World.h"
+#include "ZoneCull.h"
cAudioManager AudioManager;
#define SPEED_OF_SOUND 343.f
-#define TIME_SPENT 50
+#define TIME_SPENT 40
cAudioManager::cAudioManager()
{
m_bIsInitialised = FALSE;
m_bReverb = TRUE;
+ field_6 = 0;
m_fSpeedOfSound = SPEED_OF_SOUND / TIME_SPENT;
m_nTimeSpent = TIME_SPENT;
m_nActiveSamples = NUM_CHANNELS_GENERIC;
@@ -114,9 +116,7 @@ cAudioManager::Service()
if (m_bIsInitialised) {
m_nPreviousUserPause = m_nUserPause;
m_nUserPause = CTimer::GetIsUserPaused();
-#if GTA_VERSION >= GTA3_PC_10
UpdateReflections();
-#endif
ServiceSoundEffects();
MusicManager.Service();
}
@@ -191,11 +191,11 @@ cAudioManager::GetEntityPointer(int32 id)
void
cAudioManager::PlayOneShot(int32 index, uint16 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};
+ static const uint8 OneShotPriority[] = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 4, 2, 5, 5, 3, 5, 2, 2, 1, 1, 3, 1, 3, 3, 1, 1, 1, 1, 4, 4, 4, 3, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 6, 1, 1, 1, 1, 1, 1, 3, 4, 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, 0, 0, 0, 1, 2, 2, 0, 0, 2, 3, 3, 3, 5, 1, 1,
+ 1, 1, 1, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 7, 1, 4, 3, 4, 2, 2, 2, 3, 1, 2, 1, 3, 5, 3, 4, 6, 4, 6, 3, 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, 1, 1, 1, 1, 1, 3, 1, 1, 2, 1, 1, 0, 0, 0, 0, 0, 3, 3, 1, 0 };
if (m_bIsInitialised) {
if (index >= 0 && index < NUM_AUDIOENTITIES) {
@@ -251,6 +251,12 @@ cAudioManager::SetMusicMasterVolume(uint8 volume)
}
void
+cAudioManager::SetMP3BoostVolume(uint8 volume)
+{
+ SampleManager.SetMP3BoostVolume(volume);
+}
+
+void
cAudioManager::SetEffectsFadeVol(uint8 volume)
{
SampleManager.SetEffectsFadeVolume(volume);
@@ -263,9 +269,9 @@ cAudioManager::SetMusicFadeVol(uint8 volume)
}
void
-cAudioManager::SetMonoMode(bool8 mono)
+cAudioManager::SetOutputMode(bool8 surround)
{
- SampleManager.SetMonoMode(mono);
+ // on ps2 this calls another method of cAudioManager to set DTS mode on or off
}
void
@@ -285,11 +291,13 @@ cAudioManager::ResetTimers(uint32 time)
m_nActiveSampleQueue = 0;
}
ClearActiveSamples();
- ClearMissionAudio();
+ ClearMissionAudio(0);
+ ClearMissionAudio(1);
SampleManager.StopChannel(CHANNEL_POLICE_RADIO);
SampleManager.SetEffectsFadeVolume(0);
SampleManager.SetMusicFadeVolume(0);
MusicManager.ResetMusicAfterReload();
+ m_bIsPlayerShutUp = FALSE;
#ifdef AUDIO_OAL
SampleManager.Service();
#endif
@@ -308,7 +316,7 @@ cAudioManager::DestroyAllGameCreatedEntities()
case AUDIOTYPE_PHYSICAL:
case AUDIOTYPE_EXPLOSION:
case AUDIOTYPE_WEATHER:
- case AUDIOTYPE_CRANE:
+ //case AUDIOTYPE_CRANE:
case AUDIOTYPE_GARAGE:
case AUDIOTYPE_FIREHYDRANT:
DestroyEntity(i);
@@ -373,6 +381,17 @@ cAudioManager::GetCurrent3DProviderIndex()
}
int8
+cAudioManager::AutoDetect3DProviders()
+{
+#ifdef EXTERNAL_3D_SOUND
+ if (m_bIsInitialised)
+ return SampleManager.AutoDetect3DProviders();
+#endif
+
+ return -1;
+}
+
+int8
cAudioManager::SetCurrent3DProvider(uint8 which)
{
#ifndef EXTERNAL_3D_SOUND
@@ -391,11 +410,9 @@ cAudioManager::SetCurrent3DProvider(uint8 which)
ClearActiveSamples();
int8 current = SampleManager.SetCurrent3DProvider(which);
if (current > 0) {
-#ifdef EXTERNAL_3D_SOUND
m_nActiveSamples = SampleManager.GetMaximumSupportedChannels();
if (m_nActiveSamples > 1)
--m_nActiveSamples;
-#endif
}
return current;
#endif
@@ -451,7 +468,6 @@ cAudioManager::GetCDAudioDriveLetter()
{
if (m_bIsInitialised)
return SampleManager.GetCDAudioDriveLetter();
-
return '\0';
}
@@ -487,7 +503,7 @@ cAudioManager::ServiceSoundEffects()
ClearActiveSamples();
}
m_nActiveSampleQueue = m_nActiveSampleQueue == 1 ? 0 : 1;
- ProcessReverb();
+ if(m_bReverb) ProcessReverb();
ProcessSpecial();
ClearRequestedQueue();
InterrogateAudioEntities();
@@ -512,22 +528,22 @@ cAudioManager::ServiceSoundEffects()
m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal = 0;
}
-uint32
-cAudioManager::FL(float f)
-{
- return SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex) * f;
-}
-
uint8
cAudioManager::ComputeVolume(uint8 emittingVolume, float soundIntensity, float distance)
{
float newSoundIntensity;
+ float newEmittingVolume;
+
if (soundIntensity <= 0.0f)
return 0;
+
newSoundIntensity = soundIntensity / 5.0f;
- if (newSoundIntensity <= distance)
- emittingVolume = sq((soundIntensity - newSoundIntensity - (distance - newSoundIntensity)) / (soundIntensity - newSoundIntensity)) * emittingVolume;
- return emittingVolume;
+ if (newSoundIntensity > distance)
+ return emittingVolume;
+
+ newEmittingVolume = emittingVolume * SQR((soundIntensity - newSoundIntensity - (distance - newSoundIntensity))
+ / (soundIntensity - newSoundIntensity));
+ return Min(127, newEmittingVolume);
}
void
@@ -536,12 +552,23 @@ cAudioManager::TranslateEntity(Const CVector *in, CVector *out)
*out = MultiplyInverse(TheCamera.GetMatrix(), *in);
}
+Const static 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
-cAudioManager::ComputePan(float dist, CVector *vec)
+cAudioManager::ComputeFrontRearMix(float dist, CVector *vec)
{
- Const static 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 = vec->y / (dist / 64.f);
+ index = Min(63, ABS(index));
+
+ if (vec->y > 0.f)
+ return Max(0, 63 - (int8)PanTable[index]);
+ return Min(127, PanTable[index] + 63);
+}
+int32
+cAudioManager::ComputePan(float dist, CVector *vec)
+{
int32 index = vec->x / (dist / 64.f);
index = Min(63, ABS(index));
@@ -617,7 +644,7 @@ cAudioManager::AddSampleToRequestedQueue()
}
m_sQueueSample.m_nCalculatedVolume = calculatedVolume;
m_sQueueSample.m_bLoopEnded = FALSE;
- if (m_sQueueSample.m_bIs2D) {
+ if (m_sQueueSample.m_bIs2D || CCullZones::InRoomForAudio()) {
m_sQueueSample.m_bRequireReflection = FALSE;
m_sQueueSample.m_nLoopsRemaining = 0;
}
@@ -629,6 +656,9 @@ cAudioManager::AddSampleToRequestedQueue()
}
m_sQueueSample.m_bRequireReflection = FALSE;
+ if ( m_bReverb && m_sQueueSample.m_bIs2D )
+ m_sQueueSample.field_4C = 30;
+
if (!m_bDynamicAcousticModelingStatus)
m_sQueueSample.m_bReverbFlag = FALSE;
@@ -657,30 +687,55 @@ cAudioManager::AddDetailsToRequestedOrderList(uint8 sample)
m_abSampleQueueIndexTable[m_nActiveSampleQueue][i] = sample;
}
-#if GTA_VERSION >= GTA3_PC_10
void
cAudioManager::AddReflectionsToRequestedQueue()
{
+#ifdef FIX_BUGS
+ uint32 oldFreq = 0;
+#else
+ uint32 oldFreq;
+#endif
float reflectionDistance;
int32 noise;
- uint8 emittingVolume = (m_sQueueSample.m_nVolume / 2) + (m_sQueueSample.m_nVolume / 8);
+ uint8 emittingVolume;
+
+ uint32 oldCounter = m_sQueueSample.m_nCounter;
+ float oldDist = m_sQueueSample.m_fDistance;
+ CVector oldPos = m_sQueueSample.m_vecPos;
+ if ( CTimer::GetIsSlowMotionActive() ) {
+ emittingVolume = m_sQueueSample.m_nVolume;
+ oldFreq = m_sQueueSample.m_nFrequency;
+ } else {
+ emittingVolume = (9 * m_sQueueSample.m_nVolume) / 16;
+ }
+ m_sQueueSample.m_SoundIntensity /= 2.f;
+
+ int halfOldFreq = oldFreq >> 1;
for (uint32 i = 0; i < ARRAY_SIZE(m_afReflectionsDistances); i++) {
+ if ( CTimer::GetIsSlowMotionActive() )
+ m_afReflectionsDistances[i] = (m_anRandomTable[i % 4] % 3) * 100.f / 8.f;
+
reflectionDistance = m_afReflectionsDistances[i];
if (reflectionDistance > 0.0f && reflectionDistance < 100.f && reflectionDistance < m_sQueueSample.m_SoundIntensity) {
- m_sQueueSample.m_nLoopsRemaining = (reflectionDistance * 500.f / 1029.f);
- if (m_sQueueSample.m_nLoopsRemaining > 5) {
+ m_sQueueSample.m_nLoopsRemaining = CTimer::GetIsSlowMotionActive() ? (reflectionDistance * 800.f / 1029.f) : (reflectionDistance * 500.f / 1029.f);
+ if (m_sQueueSample.m_nLoopsRemaining > 3) {
m_sQueueSample.m_fDistance = m_afReflectionsDistances[i];
SET_EMITTING_VOLUME(emittingVolume);
m_sQueueSample.m_nVolume = ComputeVolume(emittingVolume, m_sQueueSample.m_SoundIntensity, m_sQueueSample.m_fDistance);
+
if (m_sQueueSample.m_nVolume > emittingVolume / 16) {
- m_sQueueSample.m_nCounter += (i + 1) * 256;
+ m_sQueueSample.m_nCounter = oldCounter + (i + 1) * 256;
if (m_sQueueSample.m_nLoopCount) {
- noise = RandomDisplacement(m_sQueueSample.m_nFrequency / 32);
- if (noise <= 0)
- m_sQueueSample.m_nFrequency += noise;
- else
- m_sQueueSample.m_nFrequency -= noise;
+ if ( CTimer::GetIsSlowMotionActive() ) {
+ m_sQueueSample.m_nFrequency = halfOldFreq + ((halfOldFreq * i) / ARRAY_SIZE(m_afReflectionsDistances));
+ } else {
+ noise = RandomDisplacement(m_sQueueSample.m_nFrequency / 32);
+ if (noise <= 0)
+ m_sQueueSample.m_nFrequency += noise;
+ else
+ m_sQueueSample.m_nFrequency -= noise;
+ }
}
m_sQueueSample.m_nReleasingVolumeModificator += 20;
m_sQueueSample.m_vecPos = m_avecReflectionsPos[i];
@@ -689,6 +744,8 @@ cAudioManager::AddReflectionsToRequestedQueue()
}
}
}
+ m_sQueueSample.m_vecPos = oldPos;
+ m_sQueueSample.m_fDistance = oldDist;
}
void
@@ -698,6 +755,7 @@ cAudioManager::UpdateReflections()
CColPoint colpoint;
CEntity *ent;
+#if GTA_VERSION < GTAVC_PC_10
if (m_FrameCounter % 8 == 0) {
camPos = TheCamera.GetPosition();
m_avecReflectionsPos[0] = camPos;
@@ -739,8 +797,78 @@ cAudioManager::UpdateReflections()
else
m_afReflectionsDistances[4] = 50.0f;
}
+#else
+ if (m_FrameCounter % 8 == 0) {
+ camPos = TheCamera.GetPosition();
+ m_avecReflectionsPos[0] = camPos;
+ m_avecReflectionsPos[0].y += 100.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] = 100.0f;
+ } else if ((m_FrameCounter + 1) % 8 == 0) {
+ camPos = TheCamera.GetPosition();
+ m_avecReflectionsPos[1] = camPos;
+ m_avecReflectionsPos[1].y -= 100.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] = 100.0f;
+ } else if ((m_FrameCounter + 2) % 8 == 0) {
+ camPos = TheCamera.GetPosition();
+ m_avecReflectionsPos[2] = camPos;
+ m_avecReflectionsPos[2].x -= 100.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] = 100.0f;
+ } else if ((m_FrameCounter + 3) % 8 == 0) {
+ camPos = TheCamera.GetPosition();
+ m_avecReflectionsPos[3] = camPos;
+ m_avecReflectionsPos[3].x += 100.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] = 100.0f;
+ } else if ((m_FrameCounter + 4) % 8 == 0) {
+ camPos = TheCamera.GetPosition();
+ camPos.y += 1.0f;
+ m_avecReflectionsPos[4] = camPos;
+ m_avecReflectionsPos[4].z += 100.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] = 100.0f;
+ } else if ((m_FrameCounter + 5) % 8 == 0) {
+ camPos = TheCamera.GetPosition();
+ camPos.y -= 1.0f;
+ m_avecReflectionsPos[5] = camPos;
+ m_avecReflectionsPos[5].z += 100.0f;
+ if (CWorld::ProcessVerticalLine(camPos, m_avecReflectionsPos[5].z, colpoint, ent, true, false, false, false, true, false, nil))
+ m_afReflectionsDistances[5] = colpoint.point.z - camPos.z;
+ else
+ m_afReflectionsDistances[5] = 100.0f;
+ } else if ((m_FrameCounter + 6) % 8 == 0) {
+ camPos = TheCamera.GetPosition();
+ camPos.x -= 1.0f;
+ m_avecReflectionsPos[6] = camPos;
+ m_avecReflectionsPos[6].z += 100.0f;
+ if (CWorld::ProcessVerticalLine(camPos, m_avecReflectionsPos[6].z, colpoint, ent, true, false, false, false, true, false, nil))
+ m_afReflectionsDistances[6] = colpoint.point.z - camPos.z;
+ else
+ m_afReflectionsDistances[6] = 100.0f;
+ } else if ((m_FrameCounter + 7) % 8 == 0) {
+ camPos = TheCamera.GetPosition();
+ camPos.x += 1.0f;
+ m_avecReflectionsPos[7] = camPos;
+ m_avecReflectionsPos[7].z += 100.0f;
+ if (CWorld::ProcessVerticalLine(camPos, m_avecReflectionsPos[7].z, colpoint, ent, true, false, false, false, true, false, nil))
+ m_afReflectionsDistances[7] = colpoint.point.z - camPos.z;
+ else
+ m_afReflectionsDistances[7] = 100.0f;
+ }
+#endif
}
-#endif // GTA_VERSION >= GTA3_PC_10
void
cAudioManager::AddReleasingSounds()
@@ -791,7 +919,7 @@ cAudioManager::AddReleasingSounds()
if (sample.m_nReleasingVolumeModificator < 20)
++sample.m_nReleasingVolumeModificator;
}
- sample.m_bReleasingSoundFlag = 0;
+ sample.m_bReleasingSoundFlag = FALSE;
}
memcpy(&m_sQueueSample, &sample, sizeof(tSound));
AddSampleToRequestedQueue();
@@ -820,6 +948,8 @@ cAudioManager::ProcessActiveQueues()
uint8 emittingVol;
CVector position;
+ bool8 missionState;
+
for (int32 i = 0; i < m_nActiveSamples; i++) {
m_asSamples[m_nActiveSampleQueue][i].m_bIsProcessed = FALSE;
m_asActiveSamples[i].m_bIsProcessed = FALSE;
@@ -830,7 +960,7 @@ cAudioManager::ProcessActiveQueues()
if (sample.m_nSampleIndex != NO_SAMPLE) {
for (int32 j = 0; j < m_nActiveSamples; j++) {
if (sample.m_nEntityIndex == m_asActiveSamples[j].m_nEntityIndex && sample.m_nCounter == m_asActiveSamples[j].m_nCounter &&
- sample.m_nSampleIndex == m_asActiveSamples[j].m_nSampleIndex) {
+ sample.m_nSampleIndex == m_asActiveSamples[j].m_nSampleIndex) {
if (sample.m_nLoopCount) {
if (m_FrameCounter & 1)
flag = !!(j & 1);
@@ -844,6 +974,8 @@ cAudioManager::ProcessActiveQueues()
m_asActiveSamples[j].m_nEntityIndex = AEHANDLE_NONE;
continue;
}
+ if (sample.m_nReleasingVolumeDivider == 0)
+ sample.m_nReleasingVolumeDivider = 1;
}
sample.m_bIsProcessed = TRUE;
m_asActiveSamples[j].m_bIsProcessed = TRUE;
@@ -860,7 +992,7 @@ cAudioManager::ProcessActiveQueues()
SampleManager.SetChannelEmittingVolume(j, emittingVol);
#else
SampleManager.SetChannelPan(j, sample.m_nOffset);
- SampleManager.SetChannelVolume(j, sample.m_nVolume);
+ SampleManager.SetChannelVolume(j, emittingVol);
#endif
} else {
position2 = sample.m_fDistance;
@@ -872,20 +1004,37 @@ cAudioManager::ProcessActiveQueues()
m_asActiveSamples[j].m_nFrequency = freq;
SampleManager.SetChannelFrequency(j, freq);
}
-
#ifdef EXTERNAL_3D_SOUND
if (sample.m_nEmittingVolume != m_asActiveSamples[j].m_nEmittingVolume) {
vol = Clamp2((int8)sample.m_nEmittingVolume, (int8)m_asActiveSamples[j].m_nEmittingVolume, 10);
- SampleManager.SetChannelEmittingVolume(j, m_bDoubleVolume ? 2 * Min(63, vol) : vol);
- m_asActiveSamples[j].m_nEmittingVolume = vol;
- }
#else
if (sample.m_nVolume != m_asActiveSamples[j].m_nVolume) {
vol = Clamp2((int8)sample.m_nVolume, (int8)m_asActiveSamples[j].m_nVolume, 10);
+#endif
+ emittingVol = m_bDoubleVolume ? 2 * Min(63, vol) : vol;
+
+ missionState = FALSE;
+ for (int32 k = 0; k < MISSION_AUDIO_SLOTS; k++) {
+ if (m_sMissionAudio.m_bIsMobile[k]) {
+ missionState = TRUE;
+ break;
+ }
+ }
+ if (missionState) {
+ emittingVol = (emittingVol * field_5538) / 127;
+ } else {
+ if (field_5538 < 127)
+ emittingVol = (emittingVol * field_5538) / 127;
+ }
+
+#ifdef EXTERNAL_3D_SOUND
+ SampleManager.SetChannelEmittingVolume(j, emittingVol);
+ m_asActiveSamples[j].m_nEmittingVolume = vol;
+#else
+ SampleManager.SetChannelVolume(j, emittingVol);
m_asActiveSamples[j].m_nVolume = vol;
- SampleManager.SetChannelVolume(j, m_bDoubleVolume ? 2 * Min(63, vol) : vol);
- }
#endif
+ }
TranslateEntity(&sample.m_vecPos, &position);
#ifdef EXTERNAL_3D_SOUND
SampleManager.SetChannel3DPosition(j, position.x, position.y, position.z);
@@ -896,10 +1045,11 @@ cAudioManager::ProcessActiveQueues()
#endif
}
SampleManager.SetChannelReverbFlag(j, sample.m_bReverbFlag);
- break;
+ break; //continue for i
}
sample.m_bIsProcessed = FALSE;
m_asActiveSamples[j].m_bIsProcessed = FALSE;
+ //continue for j
}
}
}
@@ -919,7 +1069,8 @@ cAudioManager::ProcessActiveQueues()
sample.m_nReleasingVolumeDivider = 1;
} else {
for (uint8 j = 0; j < m_nActiveSamples; j++) {
- if (!m_asActiveSamples[j].m_bIsProcessed) {
+ uint8 k = (j + field_6) % m_nActiveSamples;
+ if (!m_asActiveSamples[k].m_bIsProcessed) {
if (sample.m_nLoopCount != 0) {
samplesPerFrame = sample.m_nFrequency / m_nTimeSpent;
samplesToPlay = sample.m_nLoopCount * SampleManager.GetSampleLength(sample.m_nSampleIndex);
@@ -927,9 +1078,9 @@ cAudioManager::ProcessActiveQueues()
continue;
sample.m_nReleasingVolumeDivider = samplesToPlay / samplesPerFrame + 1;
}
- memcpy(&m_asActiveSamples[j], &sample, sizeof(tSound));
- if (!m_asActiveSamples[j].m_bIs2D) {
- TranslateEntity(&m_asActiveSamples[j].m_vecPos, &position);
+ memcpy(&m_asActiveSamples[k], &sample, sizeof(tSound));
+ if (!m_asActiveSamples[k].m_bIs2D) {
+ TranslateEntity(&m_asActiveSamples[k].m_vecPos, &position);
#ifndef EXTERNAL_3D_SOUND
m_asActiveSamples[j].m_nOffset = ComputePan(m_asActiveSamples[j].m_fDistance, &position);
#endif
@@ -939,41 +1090,55 @@ cAudioManager::ProcessActiveQueues()
#else
emittingVol = m_bDoubleVolume ? 2 * Min(63, m_asActiveSamples[j].m_nVolume) : m_asActiveSamples[j].m_nVolume;
#endif
- if (SampleManager.InitialiseChannel(j, m_asActiveSamples[j].m_nSampleIndex, m_asActiveSamples[j].m_nBankIndex)) {
- SampleManager.SetChannelFrequency(j, m_asActiveSamples[j].m_nFrequency);
+ if (SampleManager.InitialiseChannel(k, m_asActiveSamples[k].m_nSampleIndex, m_asActiveSamples[k].m_nBankIndex)) {
+ SampleManager.SetChannelFrequency(k, m_asActiveSamples[k].m_nFrequency);
+ bool8 isMobile = FALSE;
+ for (int32 l = 0; l < MISSION_AUDIO_SLOTS; l++) {
+ if (m_sMissionAudio.m_bIsMobile[l]) {
+ isMobile = TRUE;
+ break;
+ }
+ }
+ if (!isMobile || m_asActiveSamples[k].m_bIs2D) {
+ if (field_5538 < 127)
+ emittingVol *= field_5538 / 127;
+ vol = emittingVol;
+ } else {
+ vol = (emittingVol * field_5538 / 127);
+ }
#ifdef EXTERNAL_3D_SOUND
- SampleManager.SetChannelEmittingVolume(j, emittingVol);
+ SampleManager.SetChannelEmittingVolume(k, vol);
#else
SampleManager.SetChannelVolume(j, emittingVol);
SampleManager.SetChannelPan(j, m_asActiveSamples[j].m_nOffset);
#endif
- SampleManager.SetChannelLoopPoints(j, m_asActiveSamples[j].m_nLoopStart, m_asActiveSamples[j].m_nLoopEnd);
- SampleManager.SetChannelLoopCount(j, m_asActiveSamples[j].m_nLoopCount);
- SampleManager.SetChannelReverbFlag(j, m_asActiveSamples[j].m_bReverbFlag);
+ SampleManager.SetChannelLoopPoints(k, m_asActiveSamples[k].m_nLoopStart, m_asActiveSamples[k].m_nLoopEnd);
+ SampleManager.SetChannelLoopCount(k, m_asActiveSamples[k].m_nLoopCount);
+ SampleManager.SetChannelReverbFlag(k, m_asActiveSamples[k].m_bReverbFlag);
#ifdef EXTERNAL_3D_SOUND
- if (m_asActiveSamples[j].m_bIs2D) {
- uint8 offset = m_asActiveSamples[j].m_nOffset;
+ if (m_asActiveSamples[k].m_bIs2D) {
+ uint8 offset = m_asActiveSamples[k].m_nOffset;
if (offset == 63)
- x = 0.f;
+ x = 0.0f;
else if (offset >= 63)
x = (offset - 63) * 1000.0f / 63;
else
- x = -(63 - offset) * 1000.0f / 63;
+ x = -(63 - offset) * 1000.0f / 63; //same like line below
usedX = x;
usedY = 0.0f;
usedZ = 0.0f;
- m_asActiveSamples[j].m_SoundIntensity = 100000.0f;
+ m_asActiveSamples[k].m_SoundIntensity = 100000.0f;
} else {
usedX = position.x;
usedY = position.y;
usedZ = position.z;
}
- SampleManager.SetChannel3DPosition(j, usedX, usedY, usedZ);
- SampleManager.SetChannel3DDistances(j, m_asActiveSamples[j].m_SoundIntensity, 0.25f * m_asActiveSamples[j].m_SoundIntensity);
+ SampleManager.SetChannel3DPosition(k, usedX, usedY, usedZ);
+ SampleManager.SetChannel3DDistances(k, m_asActiveSamples[k].m_SoundIntensity, 0.25f * m_asActiveSamples[k].m_SoundIntensity);
#endif
- SampleManager.StartChannel(j);
+ SampleManager.StartChannel(k);
}
- m_asActiveSamples[j].m_bIsProcessed = TRUE;
+ m_asActiveSamples[k].m_bIsProcessed = TRUE;
sample.m_bIsProcessed = TRUE;
sample.m_nVolumeChange = -1;
break;
@@ -982,6 +1147,7 @@ cAudioManager::ProcessActiveQueues()
}
}
}
+ field_6 %= m_nActiveSamples;
}
void
@@ -1020,18 +1186,13 @@ cAudioManager::ClearActiveSamples()
m_asActiveSamples[i].m_SoundIntensity = 200.0f;
m_asActiveSamples[i].m_nOffset = 63;
m_asActiveSamples[i].m_bReleasingSoundFlag = FALSE;
-#if GTA_VERSION < GTA3_PC_10
- m_asActiveSamples[i].unk = -3;
-#endif
m_asActiveSamples[i].m_nCalculatedVolume = 0;
m_asActiveSamples[i].m_nReleasingVolumeDivider = 0;
m_asActiveSamples[i].m_nVolumeChange = -1;
m_asActiveSamples[i].m_vecPos = CVector(0.0f, 0.0f, 0.0f);
m_asActiveSamples[i].m_bReverbFlag = FALSE;
-#if GTA_VERSION >= GTA3_PC_10
m_asActiveSamples[i].m_nLoopsRemaining = 0;
m_asActiveSamples[i].m_bRequireReflection = FALSE;
-#endif
}
}
diff --git a/src/audio/AudioManager.h b/src/audio/AudioManager.h
index 7934996e..94443ce2 100644
--- a/src/audio/AudioManager.h
+++ b/src/audio/AudioManager.h
@@ -3,16 +3,14 @@
#include "audio_enums.h"
#include "AudioCollision.h"
#include "PolRadio.h"
+#include "VehicleModelInfo.h"
+#include "Vehicle.h"
class tSound
{
public:
int32 m_nEntityIndex;
-#if GTA_VERSION >= GTA3_PC_10
int32 m_nCounter;
-#else
- uint8 m_nCounter;
-#endif
int32 m_nSampleIndex;
uint8 m_nBankIndex;
bool8 m_bIs2D;
@@ -29,30 +27,24 @@ public:
uint8 m_nEmittingVolume;
#endif
float m_fSpeedMultiplier;
-#if GTA_VERSION >= GTA3_PC_10
float m_SoundIntensity;
-#else
- uint32 m_SoundIntensity;
-#endif
bool8 m_bReleasingSoundFlag;
CVector m_vecPos;
- bool8 m_bReverbFlag;
-#if GTA_VERSION >= GTA3_PC_10
+#ifndef GTA_PS2
+ bool8 m_bReverbFlag; // TODO: ifdef all the occurrences
+#endif
uint8 m_nLoopsRemaining;
bool8 m_bRequireReflection; // Used for oneshots
-#endif
uint8 m_nOffset;
+ uint8 field_4C;
int32 m_nReleasingVolumeDivider;
bool8 m_bIsProcessed;
bool8 m_bLoopEnded;
-#if GTA_VERSION < GTA3_PC_10
- int32 unk; // only on PS2, seems unused
-#endif
int32 m_nCalculatedVolume;
int8 m_nVolumeChange;
};
-VALIDATE_SIZE(tSound, 92);
+VALIDATE_SIZE(tSound, 96);
class CPhysical;
class CAutomobile;
@@ -74,7 +66,7 @@ VALIDATE_SIZE(tAudioEntity, 40);
class tPedComment
{
public:
- int32 m_nSampleIndex;
+ uint32 m_nSampleIndex;
int32 m_nEntityIndex;
CVector m_vecPos;
float m_fDistance;
@@ -94,6 +86,10 @@ public:
uint8 m_nIndexMap[NUM_PED_COMMENTS_BANKS][NUM_PED_COMMENTS_SLOTS];
uint8 m_nCommentsInBank[NUM_PED_COMMENTS_BANKS];
uint8 m_nActiveBank;
+#ifdef GTA_PC
+ bool8 m_bDelay;
+ uint32 m_nDelayTimer;
+#endif
cPedComments()
{
@@ -111,23 +107,28 @@ public:
void Process();
};
-VALIDATE_SIZE(cPedComments, 1164);
+VALIDATE_SIZE(cPedComments, 0x490);
class CEntity;
+#define MISSION_AUDIO_SLOTS (2)
+
+// So instead of doing cMissionAudio [2] they've added [2] to every field of the struct...
+// Only someone with a VERY EXTRAORDINARY mind could have come up with that
class cMissionAudio
{
public:
- CVector m_vecPos;
- bool8 m_bPredefinedProperties;
- int32 m_nSampleIndex;
- uint8 m_nLoadingStatus;
- uint8 m_nPlayStatus;
- bool8 m_bIsPlaying;
- int32 m_nMissionAudioCounter;
- bool8 m_bIsPlayed;
+ CVector m_vecPos[MISSION_AUDIO_SLOTS];
+ bool8 m_bPredefinedProperties[MISSION_AUDIO_SLOTS];
+ int32 m_nSampleIndex[MISSION_AUDIO_SLOTS];
+ uint8 m_nLoadingStatus[MISSION_AUDIO_SLOTS];
+ uint8 m_nPlayStatus[MISSION_AUDIO_SLOTS];
+ bool8 m_bIsPlaying[MISSION_AUDIO_SLOTS];
+ int32 m_nMissionAudioCounter[MISSION_AUDIO_SLOTS];
+ bool8 m_bIsPlayed[MISSION_AUDIO_SLOTS];
+ bool8 m_bIsMobile[MISSION_AUDIO_SLOTS];
};
-VALIDATE_SIZE(cMissionAudio, 32);
+VALIDATE_SIZE(cMissionAudio, 0x38);
// name made up
class cAudioScriptObjectManager
@@ -164,6 +165,7 @@ public:
class cVehicleParams
{
public:
+ int32 m_VehicleType;
bool8 m_bDistanceCalculated;
float m_fDistance;
CVehicle *m_pVehicle;
@@ -173,6 +175,7 @@ public:
cVehicleParams()
{
+ m_VehicleType = -1;
m_bDistanceCalculated = false;
m_fDistance = 0.0f;
m_pVehicle = nil;
@@ -182,8 +185,9 @@ public:
}
};
-VALIDATE_SIZE(cVehicleParams, 0x18);
+VALIDATE_SIZE(cVehicleParams, 0x1C);
+#if GTA_VERSION < GTAVC_PC_10
enum {
/*
REFLECTION_YMAX = 0, top
@@ -200,6 +204,19 @@ enum {
REFLECTION_UP,
MAX_REFLECTIONS,
};
+#else
+enum {
+ REFLECTION_NORTH = 0,
+ REFLECTION_SOUTH,
+ REFLECTION_WEST,
+ REFLECTION_EAST,
+ REFLECTION_CEIL_NORTH,
+ REFLECTION_CEIL_SOUTH,
+ REFLECTION_CEIL_WEST,
+ REFLECTION_CEIL_EAST,
+ MAX_REFLECTIONS,
+};
+#endif
enum PLAY_STATUS { PLAY_STATUS_STOPPED = 0, PLAY_STATUS_PLAYING, PLAY_STATUS_FINISHED };
enum LOADING_STATUS { LOADING_STATUS_NOT_LOADED = 0, LOADING_STATUS_LOADED, LOADING_STATUS_FAILED };
@@ -208,11 +225,12 @@ class cAudioManager
{
public:
bool8 m_bIsInitialised;
- bool8 m_bReverb; // unused
+ uint8 m_bReverb; // unused
bool8 m_bFifthFrameFlag;
uint8 m_nActiveSamples;
uint8 m_bDoubleVolume; // unused
bool8 m_bDynamicAcousticModelingStatus;
+ int8 field_6;
float m_fSpeedOfSound;
bool8 m_bTimerJustReset;
int32 m_nTimer;
@@ -225,11 +243,17 @@ public:
tAudioEntity m_asAudioEntities[NUM_AUDIOENTITIES];
int32 m_anAudioEntityIndices[NUM_AUDIOENTITIES];
int32 m_nAudioEntitiesTotal;
-#if GTA_VERSION >= GTA3_PC_10
CVector m_avecReflectionsPos[MAX_REFLECTIONS];
float m_afReflectionsDistances[MAX_REFLECTIONS];
-#endif
cAudioScriptObjectManager m_sAudioScriptObjectManager;
+
+ // miami
+ bool8 m_bIsPlayerShutUp;
+ uint8 m_nPlayerMood;
+ uint32 m_nPlayerMoodTimer;
+ uint8 field_rest[4];
+ bool8 m_bGenericSfx;
+
cPedComments m_sPedComments;
int32 m_nFireAudioEntity;
int32 m_nWaterCannonEntity;
@@ -239,8 +263,13 @@ public:
int32 m_nCollisionEntity;
cAudioCollisionManager m_sCollisionManager;
int32 m_nProjectileEntity;
+#ifdef GTA_BRIDGE
int32 m_nBridgeEntity;
+#endif
+ int32 m_nEscalatorEntity;
+ int32 m_nExtraSoundsEntity;
cMissionAudio m_sMissionAudio;
+ uint8 field_5538; // something related to phone dialogues
int32 m_anRandomTable[5];
uint8 m_nTimeSpent;
uint8 m_nUserPause;
@@ -254,23 +283,25 @@ public:
void Terminate();
void Service();
int32 CreateEntity(eAudioType type, void *entity);
- void DestroyEntity(int32 id);
+ void DestroyEntity(int32 id); // inlined in vc
bool8 GetEntityStatus(int32 id);
void SetEntityStatus(int32 id, bool8 status);
void *GetEntityPointer(int32 id);
void PlayOneShot(int32 index, uint16 sound, float vol);
void SetEffectsMasterVolume(uint8 volume);
void SetMusicMasterVolume(uint8 volume);
+ void SetMP3BoostVolume(uint8 volume);
void SetEffectsFadeVol(uint8 volume);
void SetMusicFadeVol(uint8 volume);
- void SetMonoMode(bool8 mono);
+ void SetOutputMode(bool8 surround);
void ResetTimers(uint32 time);
void DestroyAllGameCreatedEntities();
-
+
#ifdef GTA_PC
uint8 GetNum3DProvidersAvailable();
char *Get3DProviderName(uint8 id);
int8 GetCurrent3DProviderIndex();
+ int8 AutoDetect3DProviders();
int8 SetCurrent3DProvider(uint8 which);
void SetSpeakerConfig(int32 conf);
bool8 IsMP3RadioChannelAvailable();
@@ -283,29 +314,27 @@ public:
#endif
void ServiceSoundEffects();
- uint32 FL(float f); // not used
uint8 ComputeVolume(uint8 emittingVolume, float soundIntensity, float distance);
void TranslateEntity(Const CVector *v1, CVector *v2);
+ int32 ComputeFrontRearMix(float, CVector *);
int32 ComputePan(float, CVector *);
- uint32 ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1, float position2, float speedMultiplier); // inlined on PS2
+ uint32 ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1, float position2, float speedMultiplier);
int32 RandomDisplacement(uint32 seed);
- void InterrogateAudioEntities(); // inlined on PS2
+ void InterrogateAudioEntities(); // inlined
void AddSampleToRequestedQueue();
- void AddDetailsToRequestedOrderList(uint8 sample); // inlined on PS2
-#if GTA_VERSION >= GTA3_PC_10
+ void AddDetailsToRequestedOrderList(uint8 sample); // inlined in vc
void AddReflectionsToRequestedQueue();
void UpdateReflections();
-#endif
void AddReleasingSounds();
void ProcessActiveQueues();
- void ClearRequestedQueue(); // inlined on PS2
+ void ClearRequestedQueue(); // inlined in vc
void ClearActiveSamples();
- void GenerateIntegerRandomNumberTable(); // inlined on PS2
- void LoadBankIfNecessary(uint8 bank); // this is used only on PS2 but technically not a platform code
+ void GenerateIntegerRandomNumberTable();
+ void LoadBankIfNecessary(uint8 bank);
#ifdef EXTERNAL_3D_SOUND // actually must have been && AUDIO_MSS as well
- void AdjustSamplesVolume();
- uint8 ComputeEmittingVolume(uint8 emittingVolume, float intensity, float dist);
+ void AdjustSamplesVolume(); // inlined
+ uint8 ComputeEmittingVolume(uint8 emittingVolume, float intensity, float dist); // inlined
#endif
// audio logic
@@ -315,145 +344,174 @@ public:
void PostTerminateGameSpecificShutdown();
void ResetAudioLogicTimers(uint32 timer);
void ProcessReverb();
- float GetDistanceSquared(const CVector &v);
+ float GetDistanceSquared(const CVector &v); // inlined in vc
void CalculateDistance(bool8 &condition, float dist);
+ CVehicle *FindVehicleOfPlayer();
void ProcessSpecial();
void ProcessEntity(int32 sound);
void ProcessPhysical(int32 id);
// vehicles
void ProcessVehicle(CVehicle *vehicle);
+ void ProcessCarHeli(cVehicleParams &params);
void ProcessRainOnVehicle(cVehicleParams &params);
bool8 ProcessReverseGear(cVehicleParams &params);
- void ProcessModelCarEngine(cVehicleParams &params);
+ void ProcessModelHeliVehicle(cVehicleParams &params);
+ void ProcessModelVehicle(cVehicleParams &params);
+ void ProcessVehicleFlatTyre(cVehicleParams &params);
bool8 ProcessVehicleRoadNoise(cVehicleParams &params);
bool8 ProcessWetRoadNoise(cVehicleParams &params);
bool8 ProcessVehicleEngine(cVehicleParams &params);
- void UpdateGasPedalAudio(CAutomobile *automobile); // inlined on PS2
+ void UpdateGasPedalAudio(CVehicle *veh, int vehType);
void PlayerJustGotInCar();
void PlayerJustLeftCar();
void AddPlayerCarSample(uint8 emittingVolume, uint32 freq, uint32 sample, uint8 bank, uint8 counter, bool8 notLooping);
void ProcessCesna(cVehicleParams &params);
- void ProcessPlayersVehicleEngine(cVehicleParams &params, CAutomobile *automobile);
+ void ProcessPlayersVehicleEngine(cVehicleParams &params, CVehicle *veh);
bool8 ProcessVehicleSkidding(cVehicleParams &params);
- float GetVehicleDriveWheelSkidValue(uint8 wheel, CAutomobile *automobile, cTransmission *transmission, float velocityChange);
- float GetVehicleNonDriveWheelSkidValue(uint8 wheel, CAutomobile *automobile, cTransmission *transmission, float velocityChange); // inlined on PS2
- void ProcessVehicleHorn(cVehicleParams &params);
- bool8 UsesSiren(uint32 model); // inlined on PS2
- bool8 UsesSirenSwitching(uint32 model); // inlined on PS2
+ float GetVehicleDriveWheelSkidValue(CVehicle *veh, tWheelState wheelState, float gasPedalAudio, cTransmission *transmission, float velocityChange);
+ float GetVehicleNonDriveWheelSkidValue(CVehicle *veh, tWheelState wheelState, cTransmission *transmission, float velocityChange);
+ bool8 ProcessVehicleHorn(cVehicleParams &params);
+ bool8 UsesSiren(cVehicleParams &params);
+ bool8 UsesSirenSwitching(cVehicleParams &params);
bool8 ProcessVehicleSirenOrAlarm(cVehicleParams &params);
- bool8 UsesReverseWarning(uint32 model); // inlined on PS2
+ bool8 UsesReverseWarning(uint32 model);
bool8 ProcessVehicleReverseWarning(cVehicleParams &params);
bool8 ProcessVehicleDoors(cVehicleParams &params);
bool8 ProcessAirBrakes(cVehicleParams &params);
- bool8 HasAirBrakes(uint32 model); // inlined on PS2
+ bool8 HasAirBrakes(uint32 model);
bool8 ProcessEngineDamage(cVehicleParams &params);
bool8 ProcessCarBombTick(cVehicleParams &params);
void ProcessVehicleOneShots(cVehicleParams &params);
+#ifdef GTA_TRAIN
bool8 ProcessTrainNoise(cVehicleParams &params);
+#endif
bool8 ProcessBoatEngine(cVehicleParams &params);
bool8 ProcessBoatMovingOverWater(cVehicleParams &params);
- bool8 ProcessHelicopter(cVehicleParams &params);
- void ProcessPlane(cVehicleParams &params); // inlined on PS2
+ void ProcessPlane(cVehicleParams &params);
void ProcessJumbo(cVehicleParams &params);
- void ProcessJumboTaxi(); // inlined on PS2
+ void ProcessJumboTaxi();
void ProcessJumboAccel(CPlane *plane);
- void ProcessJumboTakeOff(CPlane *plane); // inlined on PS2
- void ProcessJumboFlying(); // inlined on PS2
- void ProcessJumboLanding(CPlane *plane); // inlined on PS2
- void ProcessJumboDecel(CPlane *plane); // inlined on PS2
+ void ProcessJumboTakeOff(CPlane *plane);
+ void ProcessJumboFlying();
+ void ProcessJumboLanding(CPlane *plane);
+ void ProcessJumboDecel(CPlane *plane);
bool8 SetupJumboTaxiSound(uint8 vol);
bool8 SetupJumboWhineSound(uint8 emittingVol, uint32 freq);
bool8 SetupJumboEngineSound(uint8 vol, uint32 freq);
bool8 SetupJumboFlySound(uint8 emittingVol);
bool8 SetupJumboRumbleSound(uint8 emittingVol);
- int32 GetJumboTaxiFreq(); // inlined on PS2
+ int32 GetJumboTaxiFreq(); // inlined in vc
// peds
- void ProcessPed(CPhysical *ped); // inlined on PS2
- void ProcessPedHeadphones(cPedParams &params);
+ void ProcessPed(CPhysical *ped);
void ProcessPedOneShots(cPedParams &params);
+ void SetPedTalkingStatus(CPed *ped, bool8 status);
+ void SetPlayersMood(uint8 mood, uint32 time);
+ void ProcessPlayerMood();
// ped comments
void SetupPedComments(cPedParams &params, uint16 sound);
- int32 GetPedCommentSfx(CPed *ped, uint16 sound);
- void GetPhrase(uint32 &phrase, uint32 &prevPhrase, uint32 sample, uint32 maxOffset); // inlined on PS2
- uint32 GetPlayerTalkSfx(uint16 sound); // inlined on PS2
- uint32 GetCopTalkSfx(uint16 sound);
- uint32 GetSwatTalkSfx(uint16 sound);
- uint32 GetFBITalkSfx(uint16 sound);
- uint32 GetArmyTalkSfx(uint16 sound);
- uint32 GetMedicTalkSfx(uint16 sound);
- uint32 GetFiremanTalkSfx(uint16 sound); // inlined on PS2
- uint32 GetBusinessMaleOldTalkSfx(uint16 sound);
- uint32 GetBusinessMaleYoungTalkSfx(uint16 sound, uint32 model);
- uint32 GetMafiaTalkSfx(uint16 sound);
- uint32 GetTriadTalkSfx(uint16 sound);
- uint32 GetDiabloTalkSfx(uint16 sound);
- uint32 GetYakuzaTalkSfx(uint16 sound);
- uint32 GetYardieTalkSfx(uint16 sound);
- uint32 GetColumbianTalkSfx(uint16 sound);
- uint32 GetHoodTalkSfx(uint16 sound);
- uint32 GetBlackCriminalTalkSfx(uint16 sound);
- uint32 GetWhiteCriminalTalkSfx(uint16 sound);
- uint32 GetCasualMaleOldTalkSfx(uint16 sound);
- uint32 GetCasualMaleYoungTalkSfx(uint16 sound);
- uint32 GetBlackCasualFemaleTalkSfx(uint16 sound);
- uint32 GetWhiteCasualFemaleTalkSfx(uint16 sound);
- uint32 GetFemaleNo3TalkSfx(uint16 sound);
- uint32 GetWhiteBusinessFemaleTalkSfx(uint16 sound, uint32 model);
- uint32 GetBlackFatFemaleTalkSfx(uint16 sound);
- uint32 GetWhiteFatMaleTalkSfx(uint16 sound);
- uint32 GetBlackFatMaleTalkSfx(uint16 sound);
- uint32 GetWhiteFatFemaleTalkSfx(uint16 sound);
- uint32 GetBlackFemaleProstituteTalkSfx(uint16 sound);
- uint32 GetWhiteFemaleProstituteTalkSfx(uint16 sound);
- uint32 GetBlackProjectMaleTalkSfx(uint16 sound, uint32 model);
- uint32 GetBlackProjectFemaleOldTalkSfx(uint16 sound);
- uint32 GetBlackProjectFemaleYoungTalkSfx(uint16 sound);
- uint32 GetChinatownMaleOldTalkSfx(uint16 sound);
- uint32 GetChinatownMaleYoungTalkSfx(uint16 sound);
- uint32 GetChinatownFemaleOldTalkSfx(uint16 sound);
- uint32 GetChinatownFemaleYoungTalkSfx(uint16 sound);
- uint32 GetLittleItalyMaleTalkSfx(uint16 sound);
- uint32 GetLittleItalyFemaleOldTalkSfx(uint16 sound);
- uint32 GetLittleItalyFemaleYoungTalkSfx(uint16 sound);
- uint32 GetWhiteDockerMaleTalkSfx(uint16 sound);
- uint32 GetBlackDockerMaleTalkSfx(uint16 sound);
- uint32 GetScumMaleTalkSfx(uint16 sound);
- uint32 GetScumFemaleTalkSfx(uint16 sound);
- uint32 GetWhiteWorkerMaleTalkSfx(uint16 sound);
- uint32 GetBlackWorkerMaleTalkSfx(uint16 sound);
- uint32 GetBlackBusinessFemaleTalkSfx(uint16 sound);
- uint32 GetSupermodelMaleTalkSfx(uint16 sound);
- uint32 GetSupermodelFemaleTalkSfx(uint16 sound);
- uint32 GetStewardMaleTalkSfx(uint16 sound);
- uint32 GetStewardFemaleTalkSfx(uint16 sound);
- uint32 GetFanMaleTalkSfx(uint16 sound, uint32 model);
- uint32 GetFanFemaleTalkSfx(uint16 sound);
- uint32 GetHospitalMaleTalkSfx(uint16 sound);
- uint32 GetHospitalFemaleTalkSfx(uint16 sound); // inlined on PS2
- uint32 GetWhiteConstructionWorkerTalkSfx(uint16 sound);
- uint32 GetBlackConstructionWorkerTalkSfx(uint16 sound);
- uint32 GetShopperFemaleTalkSfx(uint16 sound, uint32 model);
- uint32 GetStudentMaleTalkSfx(uint16 sound);
- uint32 GetStudentFemaleTalkSfx(uint16 sound);
-
- uint32 GetSpecialCharacterTalkSfx(uint32 modelIndex, uint16 sound);
- uint32 GetEightBallTalkSfx(uint16 sound); // inlined on PS2
- uint32 GetSalvatoreTalkSfx(uint16 sound); // inlined on PS2
- uint32 GetMistyTalkSfx(uint16 sound);
- uint32 GetOldJapTalkSfx(uint16 sound); // inlined on PS2
- uint32 GetCatalinaTalkSfx(uint16 sound); // inlined on PS2
- uint32 GetBomberTalkSfx(uint16 sound); // inlined on PS2
- uint32 GetSecurityGuardTalkSfx(uint16 sound);
- uint32 GetChunkyTalkSfx(uint16 sound); // inlined on PS2
-
- uint32 GetAsianTaxiDriverTalkSfx(uint16 sound); // inlined on PS2
- uint32 GetPimpTalkSfx(uint16 sound);
- uint32 GetNormalMaleTalkSfx(uint16 sound);
- uint32 GetGenericMaleTalkSfx(uint16 sound);
- uint32 GetGenericFemaleTalkSfx(uint16 sound);
+ uint32 GetPedCommentSfx(CPed *ped, uint16 sound);
+ void GetPhrase(uint32 &phrase, uint32 &prevPhrase, uint32 sample, uint32 maxOffset);
+ uint32 GetPlayerTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetGenericMaleTalkSfx(CPed *ped, uint16 sound); // inlined in vc
+ uint32 GetGenericFemaleTalkSfx(CPed *ped, uint16 sound); // inlined in vc
+ uint32 GetDefaultTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetCopTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetSwatTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetFBITalkSfx(CPed *ped, uint16 sound);
+ uint32 GetArmyTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetMedicTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetFiremanTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetWFYG1TalkSfx(CPed *ped, uint16 sound);
+ uint32 GetWFYG2TalkSfx(CPed *ped, uint16 sound);
+ uint32 GetHFYSTTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetHFOSTTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetHMYSTTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetHMOSTTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetHFYRITalkSfx(CPed *ped, uint16 sound);
+ uint32 GetHFORITalkSfx(CPed *ped, uint16 sound);
+ uint32 GetHMYRITalkSfx(CPed *ped, uint16 sound);
+ uint32 GetHMORITalkSfx(CPed *ped, uint16 sound);
+ uint32 GetHFYBETalkSfx(CPed *ped, uint16 sound);
+ uint32 GetHFOBETalkSfx(CPed *ped, uint16 sound);
+ uint32 GetHMYBETalkSfx(CPed *ped, uint16 sound);
+ uint32 GetHMOBETalkSfx(CPed *ped, uint16 sound);
+ uint32 GetHFYBUTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetHFYMDTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetHFYCGTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetHFYPRTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetHFOTRTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetHMOTRTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetHMOCATalkSfx(CPed *ped, uint16 sound);
+ uint32 GetBMYCRTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetBFYSTTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetBFOSTTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetBMYSTTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetBMOSTTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetBFYRITalkSfx(CPed *ped, uint16 sound);
+ uint32 GetBFORITalkSfx(CPed *ped, uint16 sound);
+ uint32 GetBMYRITalkSfx(CPed *ped, uint16 sound);
+ uint32 GetBFYBETalkSfx(CPed *ped, uint16 sound);
+ uint32 GetBMYBETalkSfx(CPed *ped, uint16 sound);
+ uint32 GetBFOBETalkSfx(CPed *ped, uint16 sound);
+ uint32 GetBMOBETalkSfx(CPed *ped, uint16 sound);
+ uint32 GetBMYBUTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetBFYPRTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetBFOTRTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetBMOTRTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetBMYPITalkSfx(CPed *ped, uint16 sound);
+ uint32 GetBMYBBTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetWMYCRTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetWFYSTTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetWFYSKTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetWMYSKTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetWFOSTTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetWMYSTTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetWMOSTTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetWFYRITalkSfx(CPed *ped, uint16 sound);
+ uint32 GetWFORITalkSfx(CPed *ped, uint16 sound);
+ uint32 GetWMYRITalkSfx(CPed *ped, uint16 sound);
+ uint32 GetWMORITalkSfx(CPed *ped, uint16 sound);
+ uint32 GetWFYBETalkSfx(CPed *ped, uint16 sound);
+ uint32 GetWMYBETalkSfx(CPed *ped, uint16 sound);
+ uint32 GetWFOBETalkSfx(CPed *ped, uint16 sound);
+ uint32 GetWMOBETalkSfx(CPed *ped, uint16 sound);
+ uint32 GetWMYCWTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetWMYGOTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetWFOGOTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetWMOGOTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetWFYLGTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetWMYLGTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetWFYBUTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetWMYBUTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetWMOBUTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetWFYPRTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetWFOTRTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetWMOTRTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetWMYPITalkSfx(CPed *ped, uint16 sound);
+ uint32 GetWMOCATalkSfx(CPed *ped, uint16 sound);
+ uint32 GetWFYSHTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetWFOSHTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetJFOTOTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetJMOTOTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetHNTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetBKTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetCBTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetSGTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetCLTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetGDTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetPGTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetViceWhiteTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetViceBlackTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetBMODKTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetHMYAPTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetWFYJGTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetWMYJGTalkSfx(CPed *ped, uint16 sound);
+ uint32 GetSpecialCharacterTalkSfx(CPed *ped, int32 model, uint16 sound);
+
+ void DebugPlayPedComment(int32 sound);
// particles
void ProcessExplosions(int32 explosion);
@@ -461,51 +519,46 @@ public:
void ProcessWaterCannon(int32);
// script objects
- void ProcessScriptObject(int32 id); // inlined on PS2
+ void ProcessScriptObject(int32 id);
void ProcessOneShotScriptObject(uint8 sound);
void ProcessLoopingScriptObject(uint8 sound);
- void ProcessPornCinema(uint8 sound);
- void ProcessWorkShopScriptObject(uint8 sound);
- void ProcessSawMillScriptObject(uint8 sound);
- void ProcessLaunderetteScriptObject(uint8 sound);
- void ProcessShopScriptObject(uint8 sound);
- void ProcessAirportScriptObject(uint8 sound);
- void ProcessCinemaScriptObject(uint8 sound);
- void ProcessDocksScriptObject(uint8 sound);
- void ProcessHomeScriptObject(uint8 sound);
- void ProcessPoliceCellBeatingScriptObject(uint8 sound);
// misc
void ProcessWeather(int32 id);
void ProcessFrontEnd();
- void ProcessCrane();
+ //void ProcessCrane();
void ProcessProjectiles();
+ void ProcessEscalators();
+ void ProcessExtraSounds();
void ProcessGarages();
void ProcessFireHydrant();
- // bridge
- void ProcessBridge(); // inlined on PS2
+#ifdef GTA_BRIDGE
+ void ProcessBridge();
void ProcessBridgeWarning();
void ProcessBridgeMotor();
void ProcessBridgeOneShots();
+#endif
// mission audio
+ const char *GetMissionAudioLoadedLabel(uint8 slot);
bool8 MissionScriptAudioUsesPoliceChannel(uint32 soundMission);
- void PreloadMissionAudio(Const char *name);
- uint8 GetMissionAudioLoadingStatus();
- void SetMissionAudioLocation(float x, float y, float z);
- void PlayLoadedMissionAudio();
- bool8 IsMissionAudioSampleFinished();
- bool8 IsMissionAudioSamplePlaying() { return m_sMissionAudio.m_nPlayStatus == PLAY_STATUS_PLAYING; }
- bool8 ShouldDuckMissionAudio() { return IsMissionAudioSamplePlaying(); }
- void ClearMissionAudio();
+ void PreloadMissionAudio(uint8 slot, Const char *name);
+ uint8 GetMissionAudioLoadingStatus(uint8 slot);
+ void SetMissionAudioLocation(uint8 slot, float x, float y, float z);
+ void PlayLoadedMissionAudio(uint8 slot);
+ bool8 ShouldDuckMissionAudio(uint8 slot);
+ bool8 IsMissionAudioSamplePlaying(uint8 slot);
+ bool8 IsMissionAudioSampleFinished(uint8 slot);
+ void ClearMissionAudio(uint8 slot); // inlined in vc
+ void ProcessMissionAudioSlot(uint8 slot);
void ProcessMissionAudio();
// police radio
void InitialisePoliceRadioZones();
void InitialisePoliceRadio();
void ResetPoliceRadio();
- void SetMissionScriptPoliceAudio(uint32 sfx);
+ void SetMissionScriptPoliceAudio(uint32 sfx); // inlined and optimized
int8 GetMissionScriptPoliceAudioPlayingStatus();
void DoPoliceRadioCrackle();
void ServicePoliceRadio();
@@ -514,7 +567,7 @@ public:
void SetupSuspectLastSeenReport();
void ReportCrime(eCrimeType crime, const CVector &pos);
void PlaySuspectLastSeen(float x, float y, float z);
- void AgeCrimes(); // inlined on PS2
+ void AgeCrimes(); // inlined in vc
// collision stuff
void ReportCollision(CEntity *entity1, CEntity *entity2, uint8 surface1, uint8 surface2, float collisionPower, float intensity2);
@@ -524,7 +577,9 @@ public:
uint32 SetLoopingCollisionRequestedSfxFreqAndGetVol(const cAudioCollision &audioCollision);
float GetCollisionOneShotRatio(uint32 a, float b);
float GetCollisionLoopingRatio(uint32 a, uint32 b, float c); // not used
- float GetCollisionRatio(float a, float b, float c, float d); // inlined on PS2
+ float GetCollisionRatio(float a, float b, float c, float d); // inlined in vc
+
+ float Sqrt(float v) const { return v <= 0.0f ? 0.0f : ::Sqrt(v); }
};
/*
@@ -550,7 +605,7 @@ public:
#endif
#if defined(AUDIO_MSS) && !defined(PS2_AUDIO_CHANNELS)
-static_assert(sizeof(cAudioManager) == 19220, "cAudioManager: error");
+static_assert(sizeof(cAudioManager) == 0x5558, "cAudioManager: error");
#endif
extern cAudioManager AudioManager;
diff --git a/src/audio/AudioSamples.h b/src/audio/AudioSamples.h
index df64521c..b98bfd7c 100644
--- a/src/audio/AudioSamples.h
+++ b/src/audio/AudioSamples.h
@@ -12,96 +12,97 @@ enum eSfxSample
SFX_CAR_HORN_PICKUP,
SFX_CAR_HORN_PORSCHE,
SFX_CAR_HORN_TRUCK,
+
+ SFX_CAR_HELI_MAI, // 8
+ SFX_CAR_HELI_MAI2, // 9
+ SFX_CAR_HELI_REA, // 10
+ SFX_CAR_HELI_STA, // 11
+ SFX_CAR_HELI_ROT, // 12
+ SFX_CAR_HELI_FAR, // 13
+ SFX_CAR_HELI_ROL, // 14
+
SFX_OLD_CAR_DOOR_OPEN,
SFX_OLD_CAR_DOOR_CLOSE,
SFX_NEW_CAR_DOOR_OPEN,
SFX_NEW_CAR_DOOR_CLOSE,
SFX_TRUCK_DOOR_OPEN,
SFX_TRUCK_DOOR_CLOSE,
- SFX_REMOTE_CONTROLLED_CAR,
SFX_REVERSE_GEAR,
SFX_REVERSE_GEAR_2,
- SFX_CAR_STARTER,
- SFX_ROAD_NOISE,
- SFX_SKID,
- SFX_GRAVEL_SKID,
+ SFX_CAR_STARTER, // 23
+ SFX_ROAD_NOISE, // 24
+ SFX_SKID, // 25
+ SFX_GRAVEL_SKID, // 26
SFX_POLICE_SIREN_SLOW,
- SFX_SIREN_FAST,
+ SFX_SIREN_FAST, // 28
SFX_AMBULANCE_SIREN_SLOW,
SFX_REVERSE_WARNING,
SFX_ICE_CREAM_TUNE,
- SFX_CAR_ALARM_1,
- SFX_AIR_BRAKES,
- SFX_SQUEAKY_BRAKES,
- SFX_TYRE_BUMP,
- SFX_TRAIN_FAR,
- SFX_TRAIN_NEAR,
+ SFX_AIR_BRAKES, // 32
+ SFX_TYRE_BUMP, // 33
+ SFX_TYRE_BURST_B, // 34
+ SFX_TYRE_BURST, // 35
+ SFX_TYRE_BURST_L, // 36
+ SFX_PALM_TREE_LO, // 37
+ SFX_BULLET_PASS_1, // 38
+ SFX_BULLET_PASS_2, // 39
+ SFX_SKATE_1, // 40
+ SFX_SKATE_2, // 41
SFX_FOOTSTEP_CONCRETE_1,
SFX_FOOTSTEP_CONCRETE_2,
SFX_FOOTSTEP_CONCRETE_3,
SFX_FOOTSTEP_CONCRETE_4,
SFX_FOOTSTEP_CONCRETE_5,
- SFX_FOOTSTEP_GRASS_1,
- SFX_FOOTSTEP_GRASS_2,
- SFX_FOOTSTEP_GRASS_3,
- SFX_FOOTSTEP_GRASS_4,
- SFX_FOOTSTEP_GRASS_5,
- SFX_FOOTSTEP_GRAVEL_1,
- SFX_FOOTSTEP_GRAVEL_2,
- SFX_FOOTSTEP_GRAVEL_3,
- SFX_FOOTSTEP_GRAVEL_4,
- SFX_FOOTSTEP_GRAVEL_5,
- SFX_FOOTSTEP_WOOD_1,
- SFX_FOOTSTEP_WOOD_2,
- SFX_FOOTSTEP_WOOD_3,
- SFX_FOOTSTEP_WOOD_4,
- SFX_FOOTSTEP_WOOD_5,
- SFX_FOOTSTEP_METAL_1,
- SFX_FOOTSTEP_METAL_2,
- SFX_FOOTSTEP_METAL_3,
- SFX_FOOTSTEP_METAL_4,
- SFX_FOOTSTEP_METAL_5,
- SFX_FOOTSTEP_WATER_1,
- SFX_FOOTSTEP_WATER_2,
- SFX_FOOTSTEP_WATER_3,
- SFX_FOOTSTEP_WATER_4,
- SFX_FOOTSTEP_SAND_1,
- SFX_FOOTSTEP_SAND_2,
- SFX_FOOTSTEP_SAND_3,
- SFX_FOOTSTEP_SAND_4,
- SFX_EXPLOSION_2,
- SFX_EXPLOSION_3,
- SFX_COLT45_LEFT,
- SFX_COLT45_RIGHT,
- SFX_M16_LEFT,
- SFX_M16_RIGHT,
- SFX_AK47_LEFT,
- SFX_AK47_RIGHT,
- SFX_UZI_LEFT,
- SFX_UZI_RIGHT,
- SFX_UZI_END_LEFT,
- SFX_UZI_END_RIGHT,
- SFX_SNIPER_LEFT,
- SFX_SNIPER_RIGHT,
- SFX_ROCKET_LEFT,
- SFX_ROCKET_RIGHT,
- SFX_ROCKET_FLY,
- SFX_FLAMETHROWER_LEFT,
- SFX_FLAMETHROWER_RIGHT,
- SFX_FLAMETHROWER_START_LEFT,
- SFX_FLAMETHROWER_START_RIGHT,
- SFX_SHOTGUN_LEFT,
- SFX_SHOTGUN_RIGHT,
- SFX_PISTOL_RELOAD,
- SFX_AK47_RELOAD,
- SFX_M16_RELOAD,
- SFX_ROCKET_RELOAD,
- SFX_RIFLE_RELOAD,
- SFX_COL_TARMAC_1,
- SFX_COL_TARMAC_2,
- SFX_COL_TARMAC_3,
- SFX_COL_TARMAC_4,
- SFX_COL_TARMAC_5,
+ SFX_EXPLOSION_1, // 47
+ SFX_EXPLOSION_2, // 48
+ SFX_EXPLOSION_3, // 49
+ SFX_COLT45_LEFT, // 50
+ SFX_COLT45_RIGHT, // 51
+ SFX_AK47_LEFT, // 52
+ SFX_AK47_RIGHT, // 53
+ SFX_UZI_LEFT, // 54
+ SFX_UZI_RIGHT, // 55
+ SFX_UZI_END_LEFT, // 56
+ SFX_SNIPER_LEFT, // 57
+ SFX_SNIPER_RIGHT, // 58
+ SFX_ROCKET_LEFT, // 59
+ SFX_ROCKET_RIGHT, // 60
+ SFX_ROCKET_FLY, // 61
+ SFX_FLAMETHROWER_LEFT, // 62
+ SFX_FLAMETHROWER_RIGHT, // 63
+ SFX_FLAMETHROWER_START_LEFT, // 64
+ SFX_FLAMETHROWER_START_RIGHT, // 65
+ SFX_SHOTGUN_LEFT, // 66
+ SFX_SHOTGUN_RIGH, // 67
+ SFX_M60_LEFT, // 68
+ SFX_M60_RIGHT, // 69
+ SFX_M60_TAIL_LEFT, // 70
+ SFX_TEC_LEFT, // 71
+ SFX_TEC_RIGHT, // 72
+ SFX_TEC_TAIL, // 73
+ SFX_RUGER_LEFT, // 74
+ SFX_RUGER_RIGHT, // 75
+ SFX_RUGER_TAIL, // 76
+ SFX_PISTOL_RELOAD, // 77
+ SFX_AK47_RELOAD, // 78
+ SFX_ROCKET_RELOAD, // 79
+ SFX_RIFLE_RELOAD, // 80
+ SFX_GOLF_CLUB_SWING, // 81
+ SFX_MINIGUN_FIRE_LEFT, // 82
+ SFX_MINIGUN_FIRE_RIGHT, // 83
+ SFX_MINIGUN_STOP, // 84
+ SFX_SPAS12_LEFT, // 85
+ SFX_SPAS12_RIGHT, // 86
+ SFX_SPAS12_TAIL_LEFT, // 87
+ SFX_PYTHON_LEFT, // 88
+ SFX_PYTHON_RIGHT, // 89
+ SFX_MP5_LEFT, // 90
+ SFX_MP5_RIGHT, // 91
+ SFX_COL_TARMAC_1, // 92
+ SFX_COL_TARMAC_2, // 93
+ SFX_COL_TARMAC_3, // 94
+ SFX_COL_TARMAC_4, // 95
+ SFX_COL_TARMAC_5, // 96
SFX_COL_GRASS_1,
SFX_COL_GRAVEL_1,
SFX_COL_MUD_1,
@@ -120,11 +121,8 @@ enum eSfxSample
SFX_COL_METAL_CHAIN_FENCE_2,
SFX_COL_METAL_CHAIN_FENCE_3,
SFX_COL_METAL_CHAIN_FENCE_4,
- SFX_COL_PED_1,
- SFX_COL_PED_2,
- SFX_COL_PED_3,
- SFX_COL_PED_4,
- SFX_COL_PED_5,
+ SFX_COL_PED_1, // 115
+ SFX_COL_PED_2, // 116
SFX_COL_SAND_1,
SFX_COL_WOOD_CRATES_1,
SFX_COL_WOOD_CRATES_2,
@@ -135,69 +133,79 @@ enum eSfxSample
SFX_COL_WOOD_BENCH_3,
SFX_COL_WOOD_BENCH_4,
SFX_COL_WOOD_SOLID_1,
- SFX_COL_VEG_1,
- SFX_COL_VEG_2,
- SFX_COL_VEG_3,
- SFX_COL_VEG_4,
- SFX_COL_VEG_5,
+ SFX_COL_VEG_1, // 127
+ SFX_COL_VEG_2, // 128
+ SFX_COL_VEG_3, // 129
+ SFX_COL_VEG_4, // 130
+ SFX_COL_VEG_5, // 131
SFX_COL_CONTAINER_1,
SFX_COL_NEWS_VENDOR_1,
SFX_COL_NEWS_VENDOR_2,
SFX_COL_NEWS_VENDOR_3,
- SFX_COL_CAR_1,
- SFX_COL_CAR_2,
- SFX_COL_CAR_3,
- SFX_COL_CAR_4,
- SFX_COL_CAR_5,
+ SFX_COL_CAR_1, // 136
+ SFX_COL_CAR_2, // 137
+ SFX_COL_CAR_3, // 138
+ SFX_COL_CAR_4, // 139
+ SFX_COL_CAR_5, // 140
SFX_COL_CARDBOARD_1,
SFX_COL_CARDBOARD_2,
- SFX_COL_GATE,
- SFX_SCRAPE_CAR_1,
+ SFX_COL_GATE, // 143
+ SFX_SCRAPE_CAR_1, // 144
SFX_CRATE_SMASH,
- SFX_GLASS_CRACK,
- SFX_GLASS_SMASH,
+ SFX_GLASS_CRACK, // 146
+ SFX_GLASS_SMASH, // 147
SFX_GLASS_SHARD_1,
SFX_GLASS_SHARD_2,
SFX_GLASS_SHARD_3,
SFX_GLASS_SHARD_4,
- SFX_PED_ON_FIRE,
- SFX_CAR_ON_FIRE,
- SFX_RAIN,
- SFX_PICKUP_1_LEFT,
- SFX_PICKUP_1_RIGHT,
- SFX_PICKUP_2_LEFT,
- SFX_PICKUP_2_RIGHT,
- SFX_PICKUP_3_LEFT,
- SFX_PICKUP_3_RIGHT,
- SFX_PICKUP_ERROR_LEFT,
- SFX_PICKUP_ERROR_RIGHT,
+ SFX_PED_ON_FIRE, // 152
+ SFX_CAR_ON_FIRE, // 153
+ SFX_RAIN, // 154
+ SFX_HURRICANE_MA, // 155
SFX_BULLET_SHELL_HIT_GROUND_1,
SFX_BULLET_SHELL_HIT_GROUND_2,
- SFX_BULLET_PED,
- SFX_BULLET_CAR_1,
- SFX_BULLET_CAR_2,
- SFX_BULLET_CAR_3,
- SFX_BULLET_CAR_4,
- SFX_BULLET_CAR_5,
- SFX_BULLET_CAR_6,
- SFX_BULLET_WALL_1,
- SFX_BULLET_WALL_2,
- SFX_BULLET_WALL_3,
- SFX_BAT_HIT_LEFT,
- SFX_BAT_HIT_RIGHT,
- SFX_FIGHT_1,
- SFX_FIGHT_2,
- SFX_FIGHT_4,
- SFX_FIGHT_5,
- SFX_GARAGE_DOOR_LOOP,
- SFX_COUNTDOWN,
- SFX_ARM_BOMB,
- SFX_POLICE_RADIO_CRACKLE,
+ SFX_BULLET_PED, // 158
+ SFX_BULLET_CAR_1, // 159
+ SFX_BULLET_CAR_2, // 160
+ SFX_BULLET_CAR_3, // 161
+ SFX_BULLET_WALL_1, // 162
+ SFX_BULLET_WALL_2, // 163
+ SFX_BULLET_WALL_3, // 164
+ SFX_BAT_HIT_LEFT, // 165
+ SFX_BAT_HIT_RIGH, // 166
+ SFX_FIGHT_1, // 167
+ SFX_FIGHT_2, // 168
+ SFX_FIGHT_4, // 169
+ SFX_FIGHT_5, // 170
+ SFX_KNIFE_SWING, // 171
+ SFX_KNIFE_SLASH, // 172
+ SFX_KNIFE_STAB, // 173
+ SFX_HAMMER_HIT_1, // 174
+ SFX_HAMMER_HIT_2, // 175
+ SFX_GARAGE_DOOR_LOOP, // 176
+ SFX_COUNTDOWN, // 177
+ SFX_ARM_BOMB, // 178
+ SFX_POLICE_RADIO_CRACKLE, // 179
+
SFX_WEVE_GOT,
SFX_THERES,
SFX_RESPOND_TO,
- SFX_A_10_1,
- SFX_A_10_2,
+ SFX_A_10,
+ SFX_IN,
+ SFX_NORTH,
+ SFX_EAST,
+ SFX_SOUTH,
+ SFX_WEST,
+ SFX_CENTRAL,
+ SFX_POLICE_RADIO_MESSAGE_NOISE_1,
+ SFX_POLICE_RADIO_SUSPECT,
+ SFX_POLICE_RADIO_LAST_SEEN,
+ SFX_POLICE_RADIO_ON_FOOT,
+ SFX_POLICE_RADIO_IN_A,
+ SFX_POLICE_RADIO_DARK,
+ SFX_POLICE_RADIO_LIGHT,
+ SFX_POLICE_RADIO_BRIGHT,
+
SFX_CRIME_1,
SFX_CRIME_2,
SFX_CRIME_3,
@@ -210,48 +218,20 @@ enum eSfxSample
SFX_CRIME_10,
SFX_CRIME_11,
SFX_CRIME_12,
- SFX_IN,
- SFX_NORTH,
- SFX_EAST,
- SFX_SOUTH,
- SFX_WEST,
- SFX_CENTRAL,
- SFX_POLICE_RADIO_MESSAGE_NOISE_1,
- SFX_POLICE_RADIO_MESSAGE_NOISE_2,
- SFX_POLICE_RADIO_MESSAGE_NOISE_3,
- SFX_POLICE_RADIO_LIBERTY_CITY,
- SFX_POLICE_RADIO_PORTLAND,
- SFX_POLICE_RADIO_STAUNTON_ISLAND,
- SFX_POLICE_RADIO_SHORESIDE_VALE,
- SFX_POLICE_RADIO_ROCKFORD,
- SFX_POLICE_RADIO_FORT_STAUNTON,
- SFX_POLICE_RADIO_ASPATRIA,
- SFX_POLICE_RADIO_TORRINGTON,
- SFX_POLICE_RADIO_BEDFORD_POINT,
- SFX_POLICE_RADIO_NEWPORT,
- SFX_POLICE_RADIO_BELLEVILLE_PARK,
- SFX_POLICE_RADIO_LIBERTY_CAMPUS,
- SFX_POLICE_RADIO_COCHRANE_DAM,
- SFX_POLICE_RADIO_PIKE_CREEK,
- SFX_POLICE_RADIO_CEDAR_GROVE,
- SFX_POLICE_RADIO_WICHITA_GARDENS,
- SFX_POLICE_RADIO_FRANCIS_INTERNATIONAL_AIRPORT,
- SFX_POLICE_RADIO_CALLAHAN_POINT,
- SFX_POLICE_RADIO_ATLANTIC_QUAYS,
- SFX_POLICE_RADIO_PORTLAND_HARBOUR,
- SFX_POLICE_RADIO_TRENTON,
- SFX_POLICE_RADIO_CHINATOWN,
- SFX_POLICE_RADIO_RED_LIGHT_DISTRICT,
- SFX_POLICE_RADIO_HEPBURN_HEIGHTS,
- SFX_POLICE_RADIO_SAINT_MARKS,
- SFX_POLICE_RADIO_HARWOOD,
- SFX_POLICE_RADIO_PORTLAND_BEACH,
- SFX_POLICE_RADIO_PORTLAND_STRAIGHTS, // shouldn't be used anymore
- SFX_POLICE_RADIO_SUSPECT,
- SFX_POLICE_RADIO_LAST_SEEN,
- SFX_POLICE_RADIO_ON_FOOT,
- SFX_POLICE_RADIO_IN_A,
- SFX_POLICE_RADIO_IN_AN,
+ SFX_POLICE_RADIO_VICE_CITY,
+ SFX_POLICE_RADIO_VICE_CITY_BEACH,
+ SFX_POLICE_RADIO_VICE_CITY_MAINLAND,
+ SFX_POLICE_RADIO_OCEAN_BEACH, //???
+ SFX_POLICE_RADIO_WASHINGTON_BEACH,
+ SFX_POLICE_RADIO_VICE_POINT,
+ SFX_POLICE_RADIO_LEAF_LINKS,
+ SFX_POLICE_RADIO_STARFISH_ISLAND, //???????????
+ SFX_POLICE_RADIO_VICEPORT,
+ SFX_POLICE_RADIO_LITTLE_HAVANA,
+ SFX_POLICE_RADIO_LITTLE_HAITI,
+ SFX_POLICE_RADIO_PRAWN_ISLAND, //??????????? IS THAT HOW SHE PRONOUNCES ISLAND?
+ SFX_POLICE_RADIO_DOWNTOWN,
+ SFX_POLICE_RADIO_ESCOBAR_INTERNATIONAL,
SFX_POLICE_RADIO_BLACK,
SFX_POLICE_RADIO_WHITE,
SFX_POLICE_RADIO_BLUE,
@@ -262,2123 +242,2779 @@ enum eSfxSample
SFX_POLICE_RADIO_ORANGE,
SFX_POLICE_RADIO_GREEN,
SFX_POLICE_RADIO_SILVER,
- SFX_POLICE_RADIO_DARK,
- SFX_POLICE_RADIO_LIGHT,
- SFX_POLICE_RADIO_BRIGHT,
SFX_POLICE_RADIO_AMBULANCE,
- SFX_POLICE_RADIO_VAN,
+ SFX_POLICE_RADIO_TUDOOR,
SFX_POLICE_RADIO_TRUCK,
- SFX_POLICE_RADIO_SALOON,
- SFX_POLICE_RADIO_SPORTS_CAR,
- SFX_POLICE_RADIO_BUGGY,
- SFX_POLICE_RADIO_TAXI,
- SFX_POLICE_RADIO_CRUISER,
- SFX_POLICE_RADIO_BUS,
- SFX_POLICE_RADIO_2_DOOR,
SFX_POLICE_RADIO_FIRE_TRUCK,
- SFX_POLICE_RADIO_BOAT,
SFX_POLICE_RADIO_PICKUP,
- SFX_POLICE_RADIO_ICE_CREAM_VAN,
- SFX_POLICE_RADIO_LIMO,
SFX_POLICE_RADIO_POLICE_CAR,
- SFX_POLICE_RADIO_CONVERTIBLE,
- SFX_POLICE_RADIO_SUBWAY_CAR,
+ SFX_POLICE_RADIO_BOAT,
+ SFX_POLICE_RADIO_BUGGY,
+ SFX_POLICE_RADIO_BUS,
+ SFX_POLICE_RADIO_COACH,
+ SFX_POLICE_RADIO_CRUISER,
+ SFX_POLICE_RADIO_DINGHY,
+ SFX_POLICE_RADIO_GARBAGE_TRUCK,
+ SFX_POLICE_RADIO_GOLF_CART,
+ SFX_POLICE_RADIO_HEARSE,
+ SFX_POLICE_RADIO_HELICOPTER,
+ SFX_POLICE_RADIO_ICE_CREAM_VAN,
+ SFX_POLICE_RADIO_LOWRIDER,
+ SFX_POLICE_RADIO_MOPED,
+ SFX_POLICE_RADIO_MOTOBIKE,
+ SFX_POLICE_RADIO_OFFROAD,
+ SFX_POLICE_RADIO_PLANE,
+ SFX_POLICE_RADIO_RIG,
+ SFX_POLICE_RADIO_SEDAN,
+ SFX_POLICE_RADIO_SPEEDBOAT,
+ SFX_POLICE_RADIO_SPORTS_CAR,
+ SFX_POLICE_RADIO_STATION_WAGON,
+ SFX_POLICE_RADIO_STRETCH,
+ SFX_POLICE_RADIO_SWAT_VAN,
SFX_POLICE_RADIO_TANK,
- SFX_HELI_1,
- SFX_HELI_2,
- SFX_HELI_3,
- SFX_PHONE_RING,
- SFX_CAR_REV_1,
- SFX_CAR_REV_2,
- SFX_CAR_REV_3,
- SFX_CAR_REV_4,
- SFX_CAR_REV_5,
- SFX_CAR_REV_6,
- SFX_CAR_REV_7,
- SFX_CAR_REV_8,
- SFX_CAR_REV_9,
- SFX_CAR_REV_10,
- SFX_CAR_IDLE_1,
- SFX_CAR_IDLE_2,
- SFX_CAR_IDLE_3,
- SFX_CAR_IDLE_4,
- SFX_CAR_IDLE_5,
- SFX_CAR_IDLE_6,
- SFX_CAR_IDLE_7,
- SFX_CAR_IDLE_8,
- SFX_CAR_IDLE_9,
- SFX_CAR_IDLE_10,
+ SFX_POLICE_RADIO_TAXI,
+ SFX_POLICE_RADIO_VAN,
+
+ SFX_HELI_1, // 198
+ SFX_PHONE_RING, // 199
+ SFX_CAR_REV_1, // PONT
+ SFX_CAR_REV_2, // PORSHE
+ SFX_CAR_REV_3, // SPIDER
+ SFX_CAR_REV_4, // MERC
+ SFX_CAR_REV_5, // TRUC
+ SFX_CAR_REV_6, // HOTROD
+ SFX_CAR_REV_7, // COBRA
+ SFX_CAR_REV_8, // PONT2
+ SFX_CAR_REV_9, // CADI
+ SFX_CAR_REV_10, // PATHFINDER
+ SFX_CAR_REV_11, // PACARD
+ SFX_CAR_REV_12, // GOLFCART
+ SFX_CAR_REV_13, // SFX_CAR_IDLE_GOL
+ SFX_CAR_REV_14, // SFX_CAR_IDLE_GOL
+ SFX_CAR_REV_15, // SFX_CAR_IDLE_GOL
+ SFX_CAR_REV_16, // SFX_CAR_IDLE_GOL
+ SFX_CAR_REV_17, // VTWI
+ SFX_MOPED_REV, // just moped
+ SFX_CAR_REV_19, // HOND(A)
+ SFX_CAR_REV_20, // SPOR(TCAR)
+ SFX_CAR_IDLE_1, // PONT
+ SFX_CAR_IDLE_2, // PORSHE
+ SFX_CAR_IDLE_3, // SPIDER
+ SFX_CAR_IDLE_4, // MERC
+ SFX_CAR_IDLE_5, // TRUC
+ SFX_CAR_IDLE_6, // HOTROD
+ SFX_CAR_IDLE_7, // COBRA
+ SFX_CAR_IDLE_8, // PONT2
+ SFX_CAR_IDLE_9, // CADI
+ SFX_CAR_IDLE_10, // PATHFINDER
+ SFX_CAR_IDLE_11, // PACARD
+ SFX_CAR_IDLE_12, // GOLFCART
+ SFX_CAR_IDLE_13, // SFX_CAR_IDLE_GOL
+ SFX_CAR_IDLE_14, // SFX_CAR_IDLE_GOL
+ SFX_CAR_IDLE_15, // SFX_CAR_IDLE_GOL
+ SFX_CAR_IDLE_16, // SFX_CAR_IDLE_GOL
+ SFX_CAR_IDLE_17, // VTWI
+ SFX_MOPED_IDLE, // 237
+ SFX_CAR_IDLE_19, // HOND(A)
+ SFX_CAR_IDLE_20, // SPOR(TCAR)
SFX_JUMBO_DIST_FLY,
- SFX_JUMBO_TAXI,
- SFX_JUMBO_WHINE,
- SFX_JUMBO_ENGINE,
- SFX_JUMBO_RUMBLE,
+ SFX_JUMBO_TAXI, // 241
+ SFX_JUMBO_WHINE, // 242
+ SFX_JUMBO_ENGINE, // 243
+ SFX_JUMBO_RUMBLE, // 244
SFX_JUMBO_LAND_WHEELS,
- SFX_POLICE_BOAT_IDLE,
- SFX_POLICE_BOAT_ACCEL,
- SFX_POLICE_BOAT_THUMB_OFF,
+ SFX_BOAT_CRUISER_LOOP, // 246
+ SFX_BOAT_V12_LOOP, // 247
SFX_BOAT_WATER_LOOP,
SFX_BOAT_SPLASH_1,
SFX_BOAT_SPLASH_2,
SFX_FISHING_BOAT_IDLE,
- SFX_CESNA_IDLE,
- SFX_CESNA_REV,
- SFX_CAR_RAIN_1,
- SFX_CAR_RAIN_2,
- SFX_CAR_RAIN_3,
- SFX_CAR_RAIN_4,
- SFX_SPLASH_1,
- SFX_PED_CRUNCH_1,
- SFX_PED_CRUNCH_2,
- SFX_HEADPHONES,
+ SFX_CAR_RAIN_1, // 252
+ SFX_CAR_RAIN_2, // 253
+ SFX_CAR_RAIN_3, // 254
+ SFX_CAR_RAIN_4, // 255
+ SFX_SPLASH_1, // 256
+ SFX_PED_CRUNCH_1, // 257
+ SFX_PED_CRUNCH_2, // 258
SFX_WOODEN_BOX_SMASH,
SFX_CARDBOARD_BOX_SMASH,
SFX_ERROR_FIRE_ROCKET_LAUNCHER,
SFX_ERROR_FIRE_RIFLE,
- SFX_TANK_TURRET,
- SFX_CRANE_MAGNET,
+ SFX_TANK_TURRET, // 263
SFX_BODY_LAND_AND_FALL,
- SFX_BODY_LAND,
- SFX_BOMB_BEEP,
- SFX_TIMER_BEEP,
- SFX_PART_MISSION_COMPLETE,
- SFX_START_BUTTON_LEFT,
- SFX_START_BUTTON_RIGHT,
+ SFX_BODY_LAND, // 265
+ SFX_BOMB_BEEP, // 266
+ SFX_TIMER_BEEP, // 267
SFX_SUSPENSION_FAST_MOVE,
SFX_SUSPENSION_SLOW_MOVE_LOOP,
SFX_SHAG_SUSPENSION,
- SFX_RADIO_CLICK,
- SFX_INFO,
+ SFX_HIT_BALL, // 271
+ SFX_ARCADE, // 272
+ SFX_CESNA_IDLE, // 273
+ SFX_CESNA_REV, // 274
+ SFX_RADIO_CLICK, // 275
+ SFX_RADIO_DIAL_1, // 276
+ SFX_RADIO_DIAL_2, // 277
+ SFX_RADIO_DIAL_3, // 278
+
+ // pc only
+ SFX_RADIO_DIAL_4,
+ SFX_RADIO_DIAL_5,
+ SFX_RADIO_DIAL_6,
+ SFX_RADIO_DIAL_7,
+ SFX_RADIO_DIAL_8,
+ SFX_RADIO_DIAL_9,
+ SFX_RADIO_DIAL_10,
+ SFX_RADIO_DIAL_11,
+ SFX_RADIO_DIAL_12,
+
+ SFX_INFO_LEFT, // 279
+ SFX_INFO_RIGHT, // 280
+ SFX_INFO_CENTRE, // 281
+ SFX_MONEY_LEFT, // 282
+ SFX_MONEY_RIGHT, // 283
+ SFX_WEAPON_LEFT, // 284
+ SFX_WEAPON_RIGHT, // 285
+ SFX_WEAPON_CENTRE, // 286
+ SFX_PART_MISSION_COMPLETE_LEFT, // 287
+ SFX_PART_MISSION_COMPLETE_RIGHT, // 288
+ SFX_PART_MISSION_COMPLETE_CENTRE, // 289
+ SFX_GO_LEFT, // 290
+ SFX_GO_RIGHT, // 291
+ SFX_GO_CENTRE, // 292
+ SFX_TIMER, // 293
+ SFX_EMPTY, // 294
+
+ SFX_FE_HIGHLIGHT_LEFT, //
+ SFX_FE_HIGHLIGHT_RIGHT, //
+ SFX_FE_SELECT_LEFT, //
+ SFX_FE_SELECT_RIGHT, //
+ SFX_FE_BACK_LEFT, //
+ SFX_FE_BACK_RIGHT, //
+ SFX_FE_ERROR_LEFT, //
+ SFX_FE_ERROR_RIGHT, //
+ SFX_FE_NOISE_BURST_1,
+ SFX_FE_NOISE_BURST_2,
+ SFX_FE_NOISE_BURST_3,
- // bank 1
SFX_CAR_ACCEL_1,
SFX_CAR_AFTER_ACCEL_1,
SFX_CAR_FINGER_OFF_ACCEL_1,
- // bank 2
SFX_CAR_ACCEL_2,
SFX_CAR_AFTER_ACCEL_2,
SFX_CAR_FINGER_OFF_ACCEL_2,
- // bank 3
SFX_CAR_ACCEL_3,
SFX_CAR_AFTER_ACCEL_3,
SFX_CAR_FINGER_OFF_ACCEL_3,
- // bank 4
SFX_CAR_ACCEL_4,
SFX_CAR_AFTER_ACCEL_4,
SFX_CAR_FINGER_OFF_ACCEL_4,
- // bank 5
SFX_CAR_ACCEL_5,
SFX_CAR_AFTER_ACCEL_5,
SFX_CAR_FINGER_OFF_ACCEL_5,
- // bank 6
SFX_CAR_ACCEL_6,
SFX_CAR_AFTER_ACCEL_6,
SFX_CAR_FINGER_OFF_ACCEL_6,
- // bank 7
SFX_CAR_ACCEL_7,
SFX_CAR_AFTER_ACCEL_7,
SFX_CAR_FINGER_OFF_ACCEL_7,
- // bank 8
SFX_CAR_ACCEL_8,
SFX_CAR_AFTER_ACCEL_8,
SFX_CAR_FINGER_OFF_ACCEL_8,
- // bank 9
SFX_CAR_ACCEL_9,
SFX_CAR_AFTER_ACCEL_9,
SFX_CAR_FINGER_OFF_ACCEL_9,
- // bank 10
- SFX_PAGE_CHANGE_AND_BACK_LEFT,
- SFX_PAGE_CHANGE_AND_BACK_RIGHT,
- SFX_HIGHLIGHT_LEFT,
- SFX_HIGHLIGHT_RIGHT,
- SFX_SELECT_LEFT,
- SFX_SELECT_RIGHT,
- SFX_SUB_MENU_BACK_LEFT,
- SFX_SUB_MENU_BACK_RIGHT,
- SFX_STEREO_LEFT,
- SFX_STEREO_RIGHT,
- SFX_MONO,
- SFX_NOISE_BURST_1,
- SFX_NOISE_BURST_2,
- SFX_NOISE_BURST_3,
- SFX_ERROR_LEFT,
- SFX_ERROR_RIGHT,
+ SFX_CAR_ACCEL_10,
+ SFX_CAR_AFTER_ACCEL_10,
+ SFX_CAR_FINGER_OFF_ACCEL_10,
- // bank 11
- SFX_TRAIN_STATION_AMBIENCE_LOOP,
- SFX_TRAIN_STATION_ANNOUNCE,
+ SFX_CAR_ACCEL_11,
+ SFX_CAR_AFTER_ACCEL_11,
+ SFX_CAR_FINGER_OFF_ACCEL_11,
- // bank 12
- SFX_CLUB_1,
+ SFX_CAR_ACCEL_12,
+ SFX_CAR_AFTER_ACCEL_12,
+ SFX_CAR_FINGER_OFF_ACCEL_12,
- // bank 13
- SFX_CLUB_2,
+ // some CHAINSAW STUFF
+ SFX_CAR_CHAINSAW_IDLE,
+ SFX_CAR_CHAINSAW_ATTACK,
+ SFX_CAR_CHAINSAW_EMPTY, // unused
- // bank 14
- SFX_CLUB_3,
+ SFX_RC_IDLE, // 10976
+ SFX_RC_REV, // 10977
+ SFX_RC_EMPTY, // 10978
- // bank 15
- SFX_CLUB_4,
+ SFX_CAR_RC_HELI, // 10979
+ SFX_CAR_AFTER_ACCEL_15, // empty
+ SFX_CAR_FINGER_OFF_ACCEL_15, // empty
- // bank 16
- SFX_CLUB_5,
+ SFX_CAR_ACCEL_16, // empty
+ SFX_CAR_AFTER_ACCEL_16, // empty
+ SFX_CAR_FINGER_OFF_ACCEL_16, // empty
- // bank 17
- SFX_CLUB_6,
+ // bike stuff apparently
+ SFX_CAR_ACCEL_17,
+ SFX_CAR_AFTER_ACCEL_17,
+ SFX_CAR_FINGER_OFF_ACCEL_17,
+ SFX_CAR_WIND_17,
- // bank 18
- SFX_CLUB_7,
+ SFX_CAR_ACCEL_18,
+ SFX_CAR_AFTER_ACCEL_18,
+ SFX_CAR_FINGER_OFF_ACCEL_18,
+ SFX_CAR_WIND_18,
- // bank 19
- SFX_CLUB_8,
+ SFX_CAR_ACCEL_19,
+ SFX_CAR_AFTER_ACCEL_19,
+ SFX_CAR_FINGER_OFF_ACCEL_19,
+ SFX_CAR_WIND_19,
- // bank 20
- SFX_CLUB_9,
+ SFX_CAR_ACCEL_20,
+ SFX_CAR_AFTER_ACCEL_20,
+ SFX_CAR_FINGER_OFF_ACCEL_20,
+ SFX_CAR_WIND_20,
- // bank 21
- SFX_CLUB_10,
+ // some emptinnes here
+ SFX_CAR_ACCEL_21,
+ SFX_CAR_AFTER_ACCEL_21,
+ SFX_CAR_FINGER_OFF_ACCEL_21,
+ SFX_CAR_ACCEL_22,
+ SFX_CAR_AFTER_ACCEL_22,
+ SFX_CAR_FINGER_OFF_ACCEL_22,
- // bank 22
- SFX_CLUB_11,
+ SFX_HELI_APACHE_1,
+ SFX_HELI_APACHE_2,
+ SFX_HELI_APACHE_3,
+ SFX_HELI_APACHE_4,
- // bank 23
- SFX_CLUB_12,
+ // something padded for more heli?
+ SFX_HELI_UNUSED_1,
+ SFX_HELI_UNUSED_2,
+ SFX_HELI_UNUSED_3,
+ SFX_HELI_UNUSED_4,
- // bank 24
- SFX_CLUB_RAGGA,
+ SFX_SEAPLANE_PRO1, // 11018
+ SFX_SEAPLANE_PRO2, // 11019
+ SFX_SEAPLANE_PRO3, // 11020
+ SFX_SEAPLANE_PRO4, // 11021
+ // low fuel
+ SFX_SEAPLANE_LOW, // 11022
- // bank 25
- SFX_STRIP_CLUB_1,
+ // something padded for more plane?
+ SFX_PLANE_UNUSED_1,
+ SFX_PLANE_UNUSED_2,
+ SFX_PLANE_UNUSED_3,
+ SFX_PLANE_UNUSED_4,
- // bank 26
- SFX_STRIP_CLUB_2,
+ // script objects
+ SFX_BUILDINGS_BANK_ALARM, // 11027
+ SFX_BUILDING_SNORE, // 11028
+ SFX_BUILDING_BAR_1, // 11029
+ SFX_BUILDING_BAR_2, // 11030
+ SFX_BUILDING_BAR_3, // 11031
+ SFX_BUILDING_BAR_4, // 11032
+ SFX_BUILDING_MAL1, // 11033
+ SFX_BUILDING_MAL2, // 11034
+ SFX_BUILDING_MAL3, // 11035
+ SFX_BUILDING_STR1, // 11036
+ SFX_BUILDING_STR2, // 11037
+ SFX_BUILDING_STR3, // 11038
+ SFX_BUILDING_CHURCH, // 11039
+ SFX_BUILDING_FAN_1, // 11040
+ SFX_BUILDING_FAN_2, // 11041
+ SFX_BUILDING_FAN_3, // 11042
+ SFX_BUILDING_FAN_4, // 11043
+ SFX_BUILDING_INSECTS_1, // 11044
+ SFX_BUILDING_INSECTS_2, // 11045
+ SFX_BUILDING_INSECTS_3, // 11046
+ SFX_BUILDING_INSECTS_4, // 11047
+ SFX_BUILDING_INSECTS_5, // 11048
+ SFX_CLUB_1, // 11049
+ SFX_CLUB_2, // 11050
+ SFX_CLUB_3, // 11051
+ SFX_CLUB_4, // 11052
- // bank 27
- SFX_WORKSHOP_1,
+ SFX_FOOTSTEP_GRASS_1,
+ SFX_FOOTSTEP_GRASS_2,
+ SFX_FOOTSTEP_GRASS_3,
+ SFX_FOOTSTEP_GRASS_4,
+ SFX_FOOTSTEP_GRASS_5,
+ SFX_FOOTSTEP_GRAVEL_1,
+ SFX_FOOTSTEP_GRAVEL_2,
+ SFX_FOOTSTEP_GRAVEL_3,
+ SFX_FOOTSTEP_GRAVEL_4,
+ SFX_FOOTSTEP_GRAVEL_5,
+ SFX_FOOTSTEP_WOOD_1,
+ SFX_FOOTSTEP_WOOD_2,
+ SFX_FOOTSTEP_WOOD_3,
+ SFX_FOOTSTEP_WOOD_4,
+ SFX_FOOTSTEP_WOOD_5,
+ SFX_FOOTSTEP_METAL_1,
+ SFX_FOOTSTEP_METAL_2,
+ SFX_FOOTSTEP_METAL_3,
+ SFX_FOOTSTEP_METAL_4,
+ SFX_FOOTSTEP_METAL_5,
+ SFX_FOOTSTEP_WATER_1,
+ SFX_FOOTSTEP_WATER_2,
+ SFX_FOOTSTEP_WATER_3,
+ SFX_FOOTSTEP_WATER_4,
+ SFX_FOOTSTEP_SAND_1,
+ SFX_FOOTSTEP_SAND_2,
+ SFX_FOOTSTEP_SAND_3,
+ SFX_FOOTSTEP_SAND_4,
- // bank 28
- SFX_PIANO_BAR_1,
+ // ped comments
- // bank 29
- SFX_SAWMILL_LOOP,
- SFX_SAWMILL_CUT_WOOD,
+ SFX_BMYBB_BLOCKED_1,
+ SFX_BMYBB_BLOCKED_2,
+ SFX_BMYBB_BLOCKED_3,
+ SFX_BMYBB_BLOCKED_4,
+ SFX_BMYBB_BLOCKED_5,
+ SFX_BMYBB_BLOCKED_6,
+ SFX_BMYBB_BLOCKED_7,
+ SFX_BMYBB_BLOCKED_8,
+ SFX_BMYBB_BLOCKED_9,
+ SFX_BMYBB_BLOCKED_10,
+ SFX_BMYBB_BLOCKED_11,
+ SFX_BMYBB_BLOCKED_12,
+ SFX_BMYBB_BLOCKED_13,
+ SFX_BMYBB_BUMP_1,
+ SFX_BMYBB_BUMP_2,
+ SFX_BMYBB_BUMP_3,
+ SFX_BMYBB_BUMP_4,
+ SFX_BMYBB_BUMP_5,
+ SFX_BMYBB_BUMP_6,
+ SFX_BMYBB_BUMP_7,
+ SFX_BMYBB_BUMP_8,
+ SFX_BMYBB_BUMP_9,
+ SFX_BMYBB_BUMP_10,
+ SFX_BMYBB_BUMP_11,
+ SFX_BMYBB_BUMP_12,
+ SFX_BMYBB_BUMP_13,
+ SFX_BMYBB_BUMP_14,
+ SFX_BMYBB_BUMP_15,
+ SFX_BMYBB_BUMP_16,
+ SFX_BMYBB_BUMP_17,
+ SFX_BMYBB_CAR_CRASH_1,
+ SFX_BMYBB_CAR_CRASH_2,
+ SFX_BMYBB_CAR_CRASH_3,
+ SFX_BMYBB_CAR_CRASH_4,
+ SFX_BMYBB_CAR_CRASH_5,
+ SFX_BMYBB_CAR_CRASH_6,
+ SFX_BMYBB_CAR_CRASH_7,
+ SFX_BMYBB_CAR_CRASH_8,
+ SFX_BMYBB_CAR_CRASH_9,
+ SFX_BMYBB_CHAT_1,
+ SFX_BMYBB_CHAT_2,
+ SFX_BMYBB_CHAT_3,
+ SFX_BMYBB_CHAT_4,
+ SFX_BMYBB_CHAT_5,
+ SFX_BMYBB_CHAT_6,
+ SFX_BMYBB_CHAT_7,
+ SFX_BMYBB_CHAT_8,
+ SFX_BMYBB_CHAT_9,
+ SFX_BMYBB_CHAT_10,
+ SFX_BMYBB_CHAT_11,
+ SFX_BMYBB_CHAT_12,
+ SFX_BMYBB_CHAT_13,
+ SFX_BMYBB_CHAT_14,
+ SFX_BMYBB_CHAT_15,
+ SFX_BMYBB_CHAT_16,
+ SFX_BMYBB_CHAT_17,
+ SFX_BMYBB_CHAT_18,
+ SFX_BMYBB_CHAT_19,
+ SFX_BMYBB_CHAT_20,
+ SFX_BMYBB_CHAT_21,
+ SFX_BMYBB_DODGE_1,
+ SFX_BMYBB_DODGE_2,
+ SFX_BMYBB_DODGE_3,
+ SFX_BMYBB_DODGE_4,
+ SFX_BMYBB_DODGE_5,
+ SFX_BMYBB_DODGE_6,
+ SFX_BMYBB_DODGE_7,
+ SFX_BMYBB_DODGE_8,
+ SFX_BMYBB_DODGE_9,
+ SFX_BMYBB_DODGE_10,
+ SFX_BMYBB_DODGE_11,
+ SFX_BMYBB_DODGE_12,
+ SFX_BMYBB_DODGE_13,
+ SFX_BMYBB_DODGE_14,
+ SFX_BMYBB_DODGE_15,
+ SFX_BMYBB_DODGE_16,
+ SFX_BMYBB_DODGE_17,
+ SFX_BMYBB_DODGE_18,
+ SFX_BMYBB_EYEING_1,
+ SFX_BMYBB_EYEING_2,
+ SFX_BMYBB_EYEING_3,
+ SFX_BMYBB_EYEING_4,
+ SFX_BMYBB_EYEING_5,
+ SFX_BMYBB_EYEING_6,
+ SFX_BMYBB_EYEING_7,
+ SFX_BMYBB_EYEING_8,
+ SFX_BMYBB_EYEING_9,
+ SFX_BMYBB_EYEING_10,
+ SFX_BMYBB_EYEING_11,
+ SFX_BMYBB_EYEING_12,
+ SFX_BMYBB_EYEING_13,
+ SFX_BMYBB_EYEING_14,
+ SFX_BMYBB_EYEING_15,
+ SFX_BMYBB_EYEING_16,
+ SFX_BMYBB_FIGHT_1,
+ SFX_BMYBB_FIGHT_2,
+ SFX_BMYBB_FIGHT_3,
+ SFX_BMYBB_FIGHT_4,
+ SFX_BMYBB_FIGHT_5,
+ SFX_BMYBB_FIGHT_6,
+ SFX_BMYBB_FIGHT_7,
+ SFX_BMYBB_FIGHT_8,
+ SFX_BMYBB_FIGHT_9,
+ SFX_BMYBB_FIGHT_10,
+ SFX_BMYBB_FIGHT_11,
+ SFX_BMYBB_FIGHT_12,
+ SFX_BMYBB_GENERIC_CRASH_1,
+ SFX_BMYBB_GENERIC_CRASH_2,
+ SFX_BMYBB_GENERIC_CRASH_3,
+ SFX_BMYBB_GENERIC_CRASH_4,
+ SFX_BMYBB_GENERIC_CRASH_5,
+ SFX_BMYBB_GENERIC_CRASH_6,
+ SFX_BMYBB_GENERIC_CRASH_7,
+ SFX_BMYBB_GENERIC_CRASH_8,
+ SFX_BMYBB_GENERIC_CRASH_9,
+ SFX_BMYBB_GUN_COOL_1,
+ SFX_BMYBB_GUN_COOL_2,
+ SFX_BMYBB_GUN_COOL_3,
+ SFX_BMYBB_GUN_COOL_4,
+ SFX_BMYBB_GUN_COOL_5,
+ SFX_BMYBB_INNOCENT_1,
+ SFX_BMYBB_INNOCENT_2,
+ SFX_BMYBB_INNOCENT_3,
+ SFX_BMYBB_INNOCENT_4,
+ SFX_BMYBB_JACKED_1,
+ SFX_BMYBB_JACKED_2,
+ SFX_BMYBB_JACKED_3,
+ SFX_BMYBB_JACKED_4,
+ SFX_BMYBB_JACKED_5,
+ SFX_BMYBB_JACKED_6,
+ SFX_BMYBB_JACKED_7,
+ SFX_BMYBB_JACKED_8,
+ SFX_BMYBB_JACKED_9,
+ SFX_BMYBB_JACKED_10,
+ SFX_BMYBB_JACKED_11,
+ SFX_BMYBB_JACKING_1,
+ SFX_BMYBB_JACKING_2,
+ SFX_BMYBB_JACKING_3,
+ SFX_BMYBB_JACKING_4,
+ SFX_BMYBB_JACKING_5,
+ SFX_BMYBB_JACKING_6,
+ SFX_BMYBB_JACKING_7,
+ SFX_BMYBB_JACKING_8,
+ SFX_BMYBB_JACKING_9,
+ SFX_BMYBB_JEER_1,
+ SFX_BMYBB_JEER_2,
+ SFX_BMYBB_JEER_3,
+ SFX_BMYBB_JEER_4,
+ SFX_BMYBB_JEER_5,
+ SFX_BMYBB_JEER_6,
+ SFX_BMYBB_JEER_7,
+ SFX_BMYBB_JEER_8,
+ SFX_BMYBB_JEER_9,
+ SFX_BMYBB_JEER_10,
+ SFX_BMYBB_JEER_11,
+ SFX_BMYBB_JEER_12,
+ SFX_BMYBB_JEER_13,
+ SFX_BMYBB_JEER_14,
+ SFX_BMYBB_JEER_15,
+ SFX_BMYBB_JEER_16,
+ SFX_BMYBB_LOST_1,
+ SFX_BMYBB_LOST_2,
+ SFX_BMYBB_MUGGED_1,
+ SFX_BMYBB_MUGGED_2,
+ SFX_BMYBB_MUGGED_3,
+ SFX_BMYBB_MUGGED_4,
+ SFX_BMYBB_MUGGED_5,
+ SFX_BMYBB_MUGGING_1,
+ SFX_BMYBB_MUGGING_2,
+ SFX_BMYBB_MUGGING_3,
+ SFX_BMYBB_MUGGING_4,
+ SFX_BMYBB_MUGGING_5,
+ SFX_BMYBB_MUGGING_6,
+ SFX_BMYBB_MUGGING_7,
+ SFX_BMYBB_MUGGING_8,
+ SFX_BMYBB_SAVED_1,
+ SFX_BMYBB_SAVED_2,
+ SFX_BMYBB_SAVED_3,
+ SFX_BMYBB_SAVED_4,
+ SFX_BMYBB_SAVED_5,
+ SFX_BMYBB_SAVED_6,
+ SFX_BMYBB_SHOCKED_1,
+ SFX_BMYBB_SHOCKED_2,
+ SFX_BMYBB_SHOCKED_3,
+ SFX_BMYBB_SHOCKED_4,
+ SFX_BMYBB_SHOCKED_5,
+ SFX_BMYBB_SHOCKED_6,
+ SFX_BMYBB_TAXI_1,
+ SFX_BMYBB_TAXI_2,
+ SFX_BMYBB_TAXI_3,
- // bank 30
- SFX_DOG_FOOD_FACTORY,
+ SFX_POLICE_BOAT_1,
+ SFX_POLICE_BOAT_2,
+ SFX_POLICE_BOAT_3,
+ SFX_POLICE_BOAT_4,
+ SFX_POLICE_BOAT_5,
+ SFX_POLICE_BOAT_6,
+ SFX_POLICE_BOAT_7,
+ SFX_POLICE_BOAT_8,
+ SFX_POLICE_BOAT_9,
+ SFX_POLICE_BOAT_10,
+ SFX_POLICE_BOAT_11,
+ SFX_POLICE_BOAT_12,
+ SFX_POLICE_BOAT_13,
+ SFX_POLICE_BOAT_14,
+ SFX_POLICE_BOAT_15,
+ SFX_POLICE_BOAT_16,
+ SFX_POLICE_BOAT_17,
+ SFX_POLICE_BOAT_18,
+ SFX_POLICE_BOAT_19,
+ SFX_POLICE_BOAT_20,
+ SFX_POLICE_BOAT_21,
+ SFX_POLICE_BOAT_22,
+ SFX_POLICE_BOAT_23,
- // bank 31
- SFX_LAUNDERETTE_LOOP,
- SFX_LAUNDERETTE_SONG_LOOP,
+ SFX_POLICE_HELI_1,
+ SFX_POLICE_HELI_2,
+ SFX_POLICE_HELI_3,
+ SFX_POLICE_HELI_4,
+ SFX_POLICE_HELI_5,
+ SFX_POLICE_HELI_6,
+ SFX_POLICE_HELI_7,
+ SFX_POLICE_HELI_8,
+ SFX_POLICE_HELI_9,
+ SFX_POLICE_HELI_10,
+ SFX_POLICE_HELI_11,
+ SFX_POLICE_HELI_12,
+ SFX_POLICE_HELI_13,
+ SFX_POLICE_HELI_14,
+ SFX_POLICE_HELI_15,
+ SFX_POLICE_HELI_16,
+ SFX_POLICE_HELI_17,
+ SFX_POLICE_HELI_18,
+ SFX_POLICE_HELI_19,
+ SFX_POLICE_HELI_20,
- // bank 32
- SFX_RESTAURANT_CHINATOWN,
+ SFX_JFOTO_BLOCKED_1,
+ SFX_JFOTO_BLOCKED_2,
+ SFX_JFOTO_BLOCKED_3,
+ SFX_JFOTO_BLOCKED_4,
+ SFX_JFOTO_BLOCKED_5,
+ SFX_JFOTO_BLOCKED_6,
+ SFX_JFOTO_BLOCKED_7,
+ SFX_JFOTO_BLOCKED_8,
- // bank 33
- SFX_RESTAURANT_ITALY,
+ SFX_JFOTO_BUMP_1,
+ SFX_JFOTO_BUMP_2,
+ SFX_JFOTO_BUMP_3,
+ SFX_JFOTO_BUMP_4,
+ SFX_JFOTO_BUMP_5,
+ SFX_JFOTO_BUMP_6,
+ SFX_JFOTO_BUMP_7,
+ SFX_JFOTO_BUMP_8,
+ SFX_JFOTO_BUMP_9,
+ SFX_JFOTO_BUMP_10,
- // bank 34
- SFX_RESTAURANT_GENERIC_1,
+ SFX_JFOTO_CAR_CRASH_1,
+ SFX_JFOTO_CAR_CRASH_2,
+ SFX_JFOTO_CAR_CRASH_3,
+ SFX_JFOTO_CAR_CRASH_4,
+ SFX_JFOTO_CAR_CRASH_5,
+ SFX_JFOTO_CAR_CRASH_6,
+ SFX_JFOTO_CAR_CRASH_7,
+ SFX_JFOTO_CAR_CRASH_8,
- // bank 35
- SFX_RESTAURANT_GENERIC_2,
+ SFX_JFOTO_CHAT_1,
+ SFX_JFOTO_CHAT_2,
+ SFX_JFOTO_CHAT_3,
+ SFX_JFOTO_CHAT_4,
+ SFX_JFOTO_CHAT_5,
+ SFX_JFOTO_CHAT_6,
+ SFX_JFOTO_CHAT_7,
+ SFX_JFOTO_CHAT_8,
+ SFX_JFOTO_CHAT_9,
+ SFX_JFOTO_CHAT_10,
+ SFX_JFOTO_CHAT_11,
+ SFX_JFOTO_CHAT_12,
+ SFX_JFOTO_CHAT_13,
- // bank 36
- SFX_AIRPORT_ANNOUNCEMENT_1,
- SFX_AIRPORT_ANNOUNCEMENT_2,
- SFX_AIRPORT_ANNOUNCEMENT_3,
- SFX_AIRPORT_ANNOUNCEMENT_4,
+ SFX_JFOTO_DODGE_1,
+ SFX_JFOTO_DODGE_2,
+ SFX_JFOTO_DODGE_3,
+ SFX_JFOTO_DODGE_4,
+ SFX_JFOTO_DODGE_5,
+ SFX_JFOTO_DODGE_6,
+ SFX_JFOTO_DODGE_7,
+ SFX_JFOTO_DODGE_8,
+ SFX_JFOTO_DODGE_9,
- // bank 37
- SFX_SHOP_LOOP,
- SFX_SHOP_TILL_1,
- SFX_SHOP_TILL_2,
+ SFX_JFOTO_GENERIC_CRASH_1,
+ SFX_JFOTO_GENERIC_CRASH_2,
+ SFX_JFOTO_GENERIC_CRASH_3,
+ SFX_JFOTO_GENERIC_CRASH_4,
+ SFX_JFOTO_GENERIC_CRASH_5,
+ SFX_JFOTO_GENERIC_CRASH_6,
+ SFX_JFOTO_GUN_PANIC_1,
+ SFX_JFOTO_GUN_PANIC_2,
+ SFX_JFOTO_GUN_PANIC_3,
+ SFX_JFOTO_GUN_PANIC_4,
+ SFX_JFOTO_JACKED_1,
+ SFX_JFOTO_JACKED_2,
+ SFX_JFOTO_JACKED_3,
+ SFX_JFOTO_JACKED_4,
+ SFX_JFOTO_JACKED_5,
+ SFX_JFOTO_LOST_1,
+ SFX_JFOTO_MUGGED_1,
+ SFX_JFOTO_MUGGED_2,
+ SFX_JFOTO_RUN_1,
+ SFX_JFOTO_RUN_2,
+ SFX_JFOTO_RUN_3,
+ SFX_JFOTO_RUN_4,
+ SFX_JFOTO_RUN_5,
+ SFX_JFOTO_SAVED_1,
+ SFX_JFOTO_SAVED_2,
+ SFX_JFOTO_SHOCKED_1,
+ SFX_JFOTO_TAXI_1,
+ SFX_JFOTO_TAXI_2,
- // bank 38
- SFX_CINEMA_BASS_1,
- SFX_CINEMA_BASS_2,
- SFX_CINEMA_BASS_3,
+ SFX_JMOTO_BLOCKED_1,
+ SFX_JMOTO_BLOCKED_2,
+ SFX_JMOTO_BLOCKED_3,
+ SFX_JMOTO_BLOCKED_4,
+ SFX_JMOTO_BLOCKED_5,
+ SFX_JMOTO_BLOCKED_6,
+ SFX_JMOTO_BLOCKED_7,
+ SFX_JMOTO_BLOCKED_8,
+ SFX_JMOTO_BUMP_1,
+ SFX_JMOTO_BUMP_2,
+ SFX_JMOTO_BUMP_3,
+ SFX_JMOTO_BUMP_4,
+ SFX_JMOTO_BUMP_5,
+ SFX_JMOTO_BUMP_6,
+ SFX_JMOTO_BUMP_7,
+ SFX_JMOTO_BUMP_8,
+ SFX_JMOTO_CAR_CRASH_1,
+ SFX_JMOTO_CAR_CRASH_2,
+ SFX_JMOTO_CAR_CRASH_3,
+ SFX_JMOTO_CAR_CRASH_4,
+ SFX_JMOTO_CAR_CRASH_5,
+ SFX_JMOTO_CAR_CRASH_6,
+ SFX_JMOTO_CHAT_1,
+ SFX_JMOTO_CHAT_2,
+ SFX_JMOTO_CHAT_3,
+ SFX_JMOTO_CHAT_4,
+ SFX_JMOTO_CHAT_5,
+ SFX_JMOTO_CHAT_6,
+ SFX_JMOTO_CHAT_7,
+ SFX_JMOTO_DODGE_1,
+ SFX_JMOTO_DODGE_2,
+ SFX_JMOTO_DODGE_3,
+ SFX_JMOTO_DODGE_4,
+ SFX_JMOTO_DODGE_5,
+ SFX_JMOTO_DODGE_6,
+ SFX_JMOTO_GENERIC_CRASH_1,
+ SFX_JMOTO_GENERIC_CRASH_2,
+ SFX_JMOTO_GENERIC_CRASH_3,
+ SFX_JMOTO_GENERIC_CRASH_4,
+ SFX_JMOTO_GENERIC_CRASH_5,
+ SFX_JMOTO_GENERIC_CRASH_6,
+ SFX_JMOTO_GUN_PANIC_1,
+ SFX_JMOTO_GUN_PANIC_2,
+ SFX_JMOTO_GUN_PANIC_3,
+ SFX_JMOTO_GUN_PANIC_4,
+ SFX_JMOTO_JACKED_1,
+ SFX_JMOTO_JACKED_2,
+ SFX_JMOTO_JACKED_3,
+ SFX_JMOTO_JACKED_4,
+ SFX_JMOTO_LOST_1,
+ SFX_JMOTO_MUGGED_1,
+ SFX_JMOTO_MUGGED_2,
+ SFX_JMOTO_RUN_1,
+ SFX_JMOTO_RUN_2,
+ SFX_JMOTO_RUN_3,
+ SFX_JMOTO_RUN_4,
+ SFX_JMOTO_SAVED_1,
+ SFX_JMOTO_SHOCKED_1,
+ SFX_JMOTO_TAXI_1,
- // bank 39
- SFX_DOCKS_FOGHORN,
+ SFX_BMYBE_BLOCKED_1,
+ SFX_BMYBE_BLOCKED_2,
+ SFX_BMYBE_BLOCKED_3,
+ SFX_BMYBE_BLOCKED_4,
+ SFX_BMYBE_BLOCKED_5,
+ SFX_BMYBE_BLOCKED_6,
+ SFX_BMYBE_BLOCKED_7,
+ SFX_BMYBE_BLOCKED_8,
+ SFX_BMYBE_BUMP_1,
+ SFX_BMYBE_BUMP_2,
+ SFX_BMYBE_BUMP_3,
+ SFX_BMYBE_BUMP_4,
+ SFX_BMYBE_BUMP_5,
+ SFX_BMYBE_BUMP_6,
+ SFX_BMYBE_BUMP_7,
+ SFX_BMYBE_BUMP_8,
+ SFX_BMYBE_BUMP_9,
+ SFX_BMYBE_BUMP_10,
+ SFX_BMYBE_CAR_CRASH_1,
+ SFX_BMYBE_CAR_CRASH_2,
+ SFX_BMYBE_CAR_CRASH_3,
+ SFX_BMYBE_CAR_CRASH_4,
+ SFX_BMYBE_CAR_CRASH_5,
+ SFX_BMYBE_CAR_CRASH_6,
+ SFX_BMYBE_CAR_CRASH_7,
+ SFX_BMYBE_CAR_CRASH_8,
+ SFX_BMYBE_CHAT_1,
+ SFX_BMYBE_CHAT_2,
+ SFX_BMYBE_CHAT_3,
+ SFX_BMYBE_CHAT_4,
+ SFX_BMYBE_CHAT_5,
+ SFX_BMYBE_CHAT_6,
+ SFX_BMYBE_CHAT_7,
+ SFX_BMYBE_CHAT_8,
+ SFX_BMYBE_CHAT_9,
+ SFX_BMYBE_CHAT_10,
+ SFX_BMYBE_DODGE_1,
+ SFX_BMYBE_DODGE_2,
+ SFX_BMYBE_DODGE_3,
+ SFX_BMYBE_DODGE_4,
+ SFX_BMYBE_DODGE_5,
+ SFX_BMYBE_DODGE_6,
+ SFX_BMYBE_DODGE_7,
+ SFX_BMYBE_DODGE_8,
+ SFX_BMYBE_DODGE_9,
+ SFX_BMYBE_DODGE_10,
+ SFX_BMYBE_EYEING_1,
+ SFX_BMYBE_EYEING_2,
+ SFX_BMYBE_FIGHT_1,
+ SFX_BMYBE_FIGHT_2,
+ SFX_BMYBE_FIGHT_3,
+ SFX_BMYBE_FIGHT_4,
+ SFX_BMYBE_FIGHT_5,
+ SFX_BMYBE_FIGHT_6,
+ SFX_BMYBE_FIGHT_7,
+ SFX_BMYBE_FIGHT_8,
+ SFX_BMYBE_GENERIC_CRASH_1,
+ SFX_BMYBE_GENERIC_CRASH_2,
+ SFX_BMYBE_GENERIC_CRASH_3,
+ SFX_BMYBE_GENERIC_CRASH_4,
+ SFX_BMYBE_GENERIC_CRASH_5,
+ SFX_BMYBE_GENERIC_CRASH_6,
+ SFX_BMYBE_GENERIC_CRASH_7,
+ SFX_BMYBE_GENERIC_CRASH_8,
+ SFX_BMYBE_GUN_COOL_1,
+ SFX_BMYBE_GUN_COOL_2,
+ SFX_BMYBE_GUN_COOL_3,
+ SFX_BMYBE_GUN_COOL_4,
+ SFX_BMYBE_JACKED_1,
+ SFX_BMYBE_JACKED_2,
+ SFX_BMYBE_JACKED_3,
+ SFX_BMYBE_JACKED_4,
+ SFX_BMYBE_JACKED_5,
+ SFX_BMYBE_JACKED_6,
+ SFX_BMYBE_JACKING_1,
+ SFX_BMYBE_JACKING_2,
+ SFX_BMYBE_JACKING_3,
+ SFX_BMYBE_LOST_1,
+ SFX_BMYBE_MUGGED_1,
+ SFX_BMYBE_SAVED_1,
+ SFX_BMYBE_TAXI_1,
- // bank 40
- SFX_HOME_1,
- SFX_HOME_2,
- SFX_HOME_3,
- SFX_HOME_4,
- SFX_HOME_5,
+ SFX_HFOBE_BLOCKED_1,
+ SFX_HFOBE_BLOCKED_2,
+ SFX_HFOBE_BLOCKED_3,
+ SFX_HFOBE_BLOCKED_4,
+ SFX_HFOBE_BLOCKED_5,
+ SFX_HFOBE_BLOCKED_6,
+ SFX_HFOBE_BUMP_1,
+ SFX_HFOBE_BUMP_2,
+ SFX_HFOBE_BUMP_3,
+ SFX_HFOBE_BUMP_4,
+ SFX_HFOBE_BUMP_5,
+ SFX_HFOBE_BUMP_6,
+ SFX_HFOBE_BUMP_7,
+ SFX_HFOBE_BUMP_8,
+ SFX_HFOBE_BUMP_9,
+ SFX_HFOBE_BUMP_10,
+ SFX_HFOBE_BUMP_11,
+ SFX_HFOBE_CAR_CRASH_1,
+ SFX_HFOBE_CAR_CRASH_2,
+ SFX_HFOBE_CAR_CRASH_3,
+ SFX_HFOBE_CAR_CRASH_4,
+ SFX_HFOBE_CAR_CRASH_5,
+ SFX_HFOBE_CAR_CRASH_6,
+ SFX_HFOBE_CHAT_1,
+ SFX_HFOBE_CHAT_2,
+ SFX_HFOBE_CHAT_3,
+ SFX_HFOBE_CHAT_4,
+ SFX_HFOBE_CHAT_5,
+ SFX_HFOBE_CHAT_6,
+ SFX_HFOBE_CHAT_7,
+ SFX_HFOBE_CHAT_8,
+ SFX_HFOBE_CHAT_9,
+ SFX_HFOBE_CHAT_10,
+ SFX_HFOBE_DODGE_1,
+ SFX_HFOBE_DODGE_2,
+ SFX_HFOBE_DODGE_3,
+ SFX_HFOBE_DODGE_4,
+ SFX_HFOBE_DODGE_5,
+ SFX_HFOBE_DODGE_6,
+ SFX_HFOBE_DODGE_7,
+ SFX_HFOBE_GENERIC_CRASH_1,
+ SFX_HFOBE_GENERIC_CRASH_2,
+ SFX_HFOBE_GENERIC_CRASH_3,
+ SFX_HFOBE_GENERIC_CRASH_4,
+ SFX_HFOBE_GENERIC_CRASH_5,
+ SFX_HFOBE_GUN_PANIC_1,
+ SFX_HFOBE_GUN_PANIC_2,
+ SFX_HFOBE_GUN_PANIC_3,
+ SFX_HFOBE_GUN_PANIC_4,
+ SFX_HFOBE_GUN_PANIC_5,
+ SFX_HFOBE_JACKED_1,
+ SFX_HFOBE_JACKED_2,
+ SFX_HFOBE_JACKED_3,
+ SFX_HFOBE_JACKED_4,
+ SFX_HFOBE_JACKED_5,
+ SFX_HFOBE_JACKED_6,
+ SFX_HFOBE_LOST_1,
+ SFX_HFOBE_LOST_2,
+ SFX_HFOBE_RUN_1,
+ SFX_HFOBE_RUN_2,
+ SFX_HFOBE_RUN_3,
+ SFX_HFOBE_RUN_4,
+ SFX_HFOBE_SAVED_1,
+ SFX_HFOBE_SHOCKED_1,
+ SFX_HFOBE_SHOCKED_2,
+ SFX_HFOBE_TAXI_1,
+ SFX_HFOBE_TAXI_2,
- // bank 41
- SFX_PORN_1_LOOP,
- SFX_PORN_1_GROAN_1,
- SFX_PORN_1_GROAN_2,
+ SFX_STREET_GANG_1_BLOCKED_1,
+ SFX_STREET_GANG_1_BLOCKED_2,
+ SFX_STREET_GANG_1_BLOCKED_3,
+ SFX_STREET_GANG_1_BLOCKED_4,
+ SFX_STREET_GANG_1_BLOCKED_5,
+ SFX_STREET_GANG_1_BLOCKED_6,
+ SFX_STREET_GANG_1_BLOCKED_7,
+ SFX_STREET_GANG_1_BLOCKED_8,
+ SFX_STREET_GANG_1_BUMP_1,
+ SFX_STREET_GANG_1_BUMP_2,
+ SFX_STREET_GANG_1_BUMP_3,
+ SFX_STREET_GANG_1_BUMP_4,
+ SFX_STREET_GANG_1_BUMP_5,
+ SFX_STREET_GANG_1_BUMP_6,
+ SFX_STREET_GANG_1_BUMP_7,
+ SFX_STREET_GANG_1_BUMP_8,
+ SFX_STREET_GANG_1_BUMP_9,
+ SFX_STREET_GANG_1_BUMP_10,
+ SFX_STREET_GANG_1_CAR_CRASH_1,
+ SFX_STREET_GANG_1_CAR_CRASH_2,
+ SFX_STREET_GANG_1_CAR_CRASH_3,
+ SFX_STREET_GANG_1_CAR_CRASH_4,
+ SFX_STREET_GANG_1_CAR_CRASH_5,
+ SFX_STREET_GANG_1_CAR_CRASH_6,
+ SFX_STREET_GANG_1_CHAT_1,
+ SFX_STREET_GANG_1_CHAT_2,
+ SFX_STREET_GANG_1_CHAT_3,
+ SFX_STREET_GANG_1_CHAT_4,
+ SFX_STREET_GANG_1_CHAT_5,
+ SFX_STREET_GANG_1_CHAT_6,
+ SFX_STREET_GANG_1_CHAT_7,
+ SFX_STREET_GANG_1_CHAT_8,
+ SFX_STREET_GANG_1_CHAT_9,
+ SFX_STREET_GANG_1_CHAT_10,
+ SFX_STREET_GANG_1_CHAT_11,
+ SFX_STREET_GANG_1_CHAT_12,
+ SFX_STREET_GANG_1_DODGE_1,
+ SFX_STREET_GANG_1_DODGE_2,
+ SFX_STREET_GANG_1_DODGE_3,
+ SFX_STREET_GANG_1_DODGE_4,
+ SFX_STREET_GANG_1_DODGE_5,
+ SFX_STREET_GANG_1_DODGE_6,
+ SFX_STREET_GANG_1_DODGE_7,
+ SFX_STREET_GANG_1_DODGE_8,
+ SFX_STREET_GANG_1_DODGE_9,
+ SFX_STREET_GANG_1_EYEING_1,
+ SFX_STREET_GANG_1_EYEING_2,
+ SFX_STREET_GANG_1_EYEING_3,
+ SFX_STREET_GANG_1_FIGHT_1,
+ SFX_STREET_GANG_1_FIGHT_2,
+ SFX_STREET_GANG_1_FIGHT_3,
+ SFX_STREET_GANG_1_FIGHT_4,
+ SFX_STREET_GANG_1_FIGHT_5,
+ SFX_STREET_GANG_1_FIGHT_6,
+ SFX_STREET_GANG_1_FIGHT_7,
+ SFX_STREET_GANG_1_FIGHT_8,
+ SFX_STREET_GANG_1_FIGHT_9,
+ SFX_STREET_GANG_1_FIGHT_10,
+ SFX_STREET_GANG_1_GENERIC_CRASH_1,
+ SFX_STREET_GANG_1_GENERIC_CRASH_2,
+ SFX_STREET_GANG_1_GENERIC_CRASH_3,
+ SFX_STREET_GANG_1_GENERIC_CRASH_4,
+ SFX_STREET_GANG_1_GENERIC_CRASH_5,
+ SFX_STREET_GANG_1_GENERIC_CRASH_6,
+ SFX_STREET_GANG_1_GUN_COOL_1,
+ SFX_STREET_GANG_1_GUN_COOL_2,
+ SFX_STREET_GANG_1_GUN_COOL_3,
+ SFX_STREET_GANG_1_GUN_COOL_4,
+ SFX_STREET_GANG_1_GUN_COOL_5,
+ SFX_STREET_GANG_1_JACKED_1,
+ SFX_STREET_GANG_1_JACKED_2,
+ SFX_STREET_GANG_1_JACKED_3,
+ SFX_STREET_GANG_1_JACKED_4,
+ SFX_STREET_GANG_1_JACKED_5,
+ SFX_STREET_GANG_1_JACKING_1,
+ SFX_STREET_GANG_1_JACKING_2,
+ SFX_STREET_GANG_1_JACKING_3,
+ SFX_STREET_GANG_1_JACKING_4,
+ SFX_STREET_GANG_1_JACKING_5,
+ SFX_STREET_GANG_1_LOST_1,
+ SFX_STREET_GANG_1_LOST_2,
+ SFX_STREET_GANG_1_MUGGED_1,
+ SFX_STREET_GANG_1_MUGGED_2,
+ SFX_STREET_GANG_1_MUGGED_3,
+ SFX_STREET_GANG_1_MUGGING_1,
+ SFX_STREET_GANG_1_MUGGING_2,
+ SFX_STREET_GANG_1_MUGGING_3,
+ SFX_STREET_GANG_1_MUGGING_4,
+ SFX_STREET_GANG_1_MUGGING_5,
+ SFX_STREET_GANG_1_SAVED_1,
+ SFX_STREET_GANG_1_SHOCKED_1,
+ SFX_STREET_GANG_1_SHOCKED_2,
+ SFX_STREET_GANG_1_TAXI_1,
- // bank 42
- SFX_PORN_2_LOOP,
- SFX_PORN_2_GROAN_1,
- SFX_PORN_2_GROAN_2,
+ SFX_STREET_GANG_2_BLOCKED_1,
+ SFX_STREET_GANG_2_BLOCKED_2,
+ SFX_STREET_GANG_2_BLOCKED_3,
+ SFX_STREET_GANG_2_BLOCKED_4,
+ SFX_STREET_GANG_2_BLOCKED_5,
+ SFX_STREET_GANG_2_BLOCKED_6,
+ SFX_STREET_GANG_2_BLOCKED_7,
+ SFX_STREET_GANG_2_BLOCKED_8,
+ SFX_STREET_GANG_2_BUMP_1,
+ SFX_STREET_GANG_2_BUMP_2,
+ SFX_STREET_GANG_2_BUMP_3,
+ SFX_STREET_GANG_2_BUMP_4,
+ SFX_STREET_GANG_2_BUMP_5,
+ SFX_STREET_GANG_2_BUMP_6,
+ SFX_STREET_GANG_2_BUMP_7,
+ SFX_STREET_GANG_2_BUMP_8,
+ SFX_STREET_GANG_2_BUMP_9,
+ SFX_STREET_GANG_2_BUMP_10,
+ SFX_STREET_GANG_2_CAR_CRASH_1,
+ SFX_STREET_GANG_2_CAR_CRASH_2,
+ SFX_STREET_GANG_2_CAR_CRASH_3,
+ SFX_STREET_GANG_2_CAR_CRASH_4,
+ SFX_STREET_GANG_2_CAR_CRASH_5,
+ SFX_STREET_GANG_2_CAR_CRASH_6,
+ SFX_STREET_GANG_2_CHAT_1,
+ SFX_STREET_GANG_2_CHAT_2,
+ SFX_STREET_GANG_2_CHAT_3,
+ SFX_STREET_GANG_2_CHAT_4,
+ SFX_STREET_GANG_2_CHAT_5,
+ SFX_STREET_GANG_2_CHAT_6,
+ SFX_STREET_GANG_2_CHAT_7,
+ SFX_STREET_GANG_2_CHAT_8,
+ SFX_STREET_GANG_2_CHAT_9,
+ SFX_STREET_GANG_2_CHAT_10,
+ SFX_STREET_GANG_2_CHAT_11,
+ SFX_STREET_GANG_2_CHAT_12,
+ SFX_STREET_GANG_2_DODGE_1,
+ SFX_STREET_GANG_2_DODGE_2,
+ SFX_STREET_GANG_2_DODGE_3,
+ SFX_STREET_GANG_2_DODGE_4,
+ SFX_STREET_GANG_2_DODGE_5,
+ SFX_STREET_GANG_2_DODGE_6,
+ SFX_STREET_GANG_2_DODGE_7,
+ SFX_STREET_GANG_2_DODGE_8,
+ SFX_STREET_GANG_2_DODGE_9,
+ SFX_STREET_GANG_2_EYEING_1,
+ SFX_STREET_GANG_2_EYEING_2,
+ SFX_STREET_GANG_2_EYEING_3,
+ SFX_STREET_GANG_2_FIGHT_1,
+ SFX_STREET_GANG_2_FIGHT_2,
+ SFX_STREET_GANG_2_FIGHT_3,
+ SFX_STREET_GANG_2_FIGHT_4,
+ SFX_STREET_GANG_2_FIGHT_5,
+ SFX_STREET_GANG_2_FIGHT_6,
+ SFX_STREET_GANG_2_FIGHT_7,
+ SFX_STREET_GANG_2_FIGHT_8,
+ SFX_STREET_GANG_2_FIGHT_9,
+ SFX_STREET_GANG_2_FIGHT_10,
+ SFX_STREET_GANG_2_GENERIC_CRASH_1,
+ SFX_STREET_GANG_2_GENERIC_CRASH_2,
+ SFX_STREET_GANG_2_GENERIC_CRASH_3,
+ SFX_STREET_GANG_2_GENERIC_CRASH_4,
+ SFX_STREET_GANG_2_GENERIC_CRASH_5,
+ SFX_STREET_GANG_2_GENERIC_CRASH_6,
+ SFX_STREET_GANG_2_GUN_COOL_1,
+ SFX_STREET_GANG_2_GUN_COOL_2,
+ SFX_STREET_GANG_2_GUN_COOL_3,
+ SFX_STREET_GANG_2_GUN_COOL_4,
+ SFX_STREET_GANG_2_GUN_COOL_5,
+ SFX_STREET_GANG_2_JACKED_1,
+ SFX_STREET_GANG_2_JACKED_2,
+ SFX_STREET_GANG_2_JACKED_3,
+ SFX_STREET_GANG_2_JACKED_4,
+ SFX_STREET_GANG_2_JACKED_5,
+ SFX_STREET_GANG_2_JACKING_1,
+ SFX_STREET_GANG_2_JACKING_2,
+ SFX_STREET_GANG_2_JACKING_3,
+ SFX_STREET_GANG_2_JACKING_4,
+ SFX_STREET_GANG_2_JACKING_5,
+ SFX_STREET_GANG_2_LOST_1,
+ SFX_STREET_GANG_2_LOST_2,
+ SFX_STREET_GANG_2_MUGGED_1,
+ SFX_STREET_GANG_2_MUGGED_2,
+ SFX_STREET_GANG_2_MUGGED_3,
+ SFX_STREET_GANG_2_MUGGING_1,
+ SFX_STREET_GANG_2_MUGGING_2,
+ SFX_STREET_GANG_2_MUGGING_3,
+ SFX_STREET_GANG_2_MUGGING_4,
+ SFX_STREET_GANG_2_MUGGING_5,
+ SFX_STREET_GANG_2_SAVED_1,
+ SFX_STREET_GANG_2_SHOCKED_1,
+ SFX_STREET_GANG_2_SHOCKED_2,
+ SFX_STREET_GANG_2_TAXI_1,
- // bank 43
- SFX_PORN_3_LOOP,
- SFX_PORN_3_GROAN_1,
- SFX_PORN_3_GROAN_2,
+ SFX_CUBAN_LORD_GANG_1_BLOCKED_1,
+ SFX_CUBAN_LORD_GANG_1_BLOCKED_2,
+ SFX_CUBAN_LORD_GANG_1_BLOCKED_3,
+ SFX_CUBAN_LORD_GANG_1_BLOCKED_4,
+ SFX_CUBAN_LORD_GANG_1_BLOCKED_5,
+ SFX_CUBAN_LORD_GANG_1_BLOCKED_6,
+ SFX_CUBAN_LORD_GANG_1_BLOCKED_7,
+ SFX_CUBAN_LORD_GANG_1_BLOCKED_8,
+ SFX_CUBAN_LORD_GANG_1_BLOCKED_9,
+ SFX_CUBAN_LORD_GANG_1_BLOCKED_10,
+ SFX_CUBAN_LORD_GANG_1_BUMP_1,
+ SFX_CUBAN_LORD_GANG_1_BUMP_2,
+ SFX_CUBAN_LORD_GANG_1_BUMP_3,
+ SFX_CUBAN_LORD_GANG_1_BUMP_4,
+ SFX_CUBAN_LORD_GANG_1_BUMP_5,
+ SFX_CUBAN_LORD_GANG_1_BUMP_6,
+ SFX_CUBAN_LORD_GANG_1_BUMP_7,
+ SFX_CUBAN_LORD_GANG_1_BUMP_8,
+ SFX_CUBAN_LORD_GANG_1_BUMP_9,
+ SFX_CUBAN_LORD_GANG_1_BUMP_10,
+ SFX_CUBAN_LORD_GANG_1_CAR_CRASH_1,
+ SFX_CUBAN_LORD_GANG_1_CAR_CRASH_2,
+ SFX_CUBAN_LORD_GANG_1_CAR_CRASH_3,
+ SFX_CUBAN_LORD_GANG_1_CAR_CRASH_4,
+ SFX_CUBAN_LORD_GANG_1_CAR_CRASH_5,
+ SFX_CUBAN_LORD_GANG_1_CAR_CRASH_6,
+ SFX_CUBAN_LORD_GANG_1_CAR_CRASH_7,
+ SFX_CUBAN_LORD_GANG_1_CAR_CRASH_8,
+ SFX_CUBAN_LORD_GANG_1_CAR_CRASH_9,
+ SFX_CUBAN_LORD_GANG_1_CAR_CRASH_10,
+ SFX_CUBAN_LORD_GANG_1_CHAT_1,
+ SFX_CUBAN_LORD_GANG_1_CHAT_2,
+ SFX_CUBAN_LORD_GANG_1_CHAT_3,
+ SFX_CUBAN_LORD_GANG_1_CHAT_4,
+ SFX_CUBAN_LORD_GANG_1_CHAT_5,
+ SFX_CUBAN_LORD_GANG_1_CHAT_6,
+ SFX_CUBAN_LORD_GANG_1_CHAT_7,
+ SFX_CUBAN_LORD_GANG_1_CHAT_8,
+ SFX_CUBAN_LORD_GANG_1_CHAT_9,
+ SFX_CUBAN_LORD_GANG_1_CHAT_10,
+ SFX_CUBAN_LORD_GANG_1_DODGE_1,
+ SFX_CUBAN_LORD_GANG_1_DODGE_2,
+ SFX_CUBAN_LORD_GANG_1_DODGE_3,
+ SFX_CUBAN_LORD_GANG_1_DODGE_4,
+ SFX_CUBAN_LORD_GANG_1_DODGE_5,
+ SFX_CUBAN_LORD_GANG_1_DODGE_6,
+ SFX_CUBAN_LORD_GANG_1_DODGE_7,
+ SFX_CUBAN_LORD_GANG_1_DODGE_8,
+ SFX_CUBAN_LORD_GANG_1_DODGE_9,
+ SFX_CUBAN_LORD_GANG_1_DODGE_10,
+ SFX_CUBAN_LORD_GANG_1_DODGE_11,
+ SFX_CUBAN_LORD_GANG_1_DODGE_12,
+ SFX_CUBAN_LORD_GANG_1_DODGE_13,
+ SFX_CUBAN_LORD_GANG_1_EYEING_1,
+ SFX_CUBAN_LORD_GANG_1_EYEING_2,
+ SFX_CUBAN_LORD_GANG_1_FIGHT_1,
+ SFX_CUBAN_LORD_GANG_1_FIGHT_2,
+ SFX_CUBAN_LORD_GANG_1_FIGHT_3,
+ SFX_CUBAN_LORD_GANG_1_FIGHT_4,
+ SFX_CUBAN_LORD_GANG_1_FIGHT_5,
+ SFX_CUBAN_LORD_GANG_1_FIGHT_6,
+ SFX_CUBAN_LORD_GANG_1_FIGHT_7,
+ SFX_CUBAN_LORD_GANG_1_FIGHT_8,
+ SFX_CUBAN_LORD_GANG_1_FIGHT_9,
+ SFX_CUBAN_LORD_GANG_1_FIGHT_10,
+ SFX_CUBAN_LORD_GANG_1_GENERIC_CRASH_1,
+ SFX_CUBAN_LORD_GANG_1_GENERIC_CRASH_2,
+ SFX_CUBAN_LORD_GANG_1_GENERIC_CRASH_3,
+ SFX_CUBAN_LORD_GANG_1_GENERIC_CRASH_4,
+ SFX_CUBAN_LORD_GANG_1_GENERIC_CRASH_5,
+ SFX_CUBAN_LORD_GANG_1_GENERIC_CRASH_6,
+ SFX_CUBAN_LORD_GANG_1_GENERIC_CRASH_7,
+ SFX_CUBAN_LORD_GANG_1_GENERIC_CRASH_8,
+ SFX_CUBAN_LORD_GANG_1_GUN_COOL_1,
+ SFX_CUBAN_LORD_GANG_1_GUN_COOL_2,
+ SFX_CUBAN_LORD_GANG_1_GUN_COOL_3,
+ SFX_CUBAN_LORD_GANG_1_GUN_COOL_4,
+ SFX_CUBAN_LORD_GANG_1_GUN_COOL_5,
+ SFX_CUBAN_LORD_GANG_1_JACKED_1,
+ SFX_CUBAN_LORD_GANG_1_JACKED_2,
+ SFX_CUBAN_LORD_GANG_1_JACKED_3,
+ SFX_CUBAN_LORD_GANG_1_JACKED_4,
+ SFX_CUBAN_LORD_GANG_1_JACKED_5,
+ SFX_CUBAN_LORD_GANG_1_JACKED_6,
+ SFX_CUBAN_LORD_GANG_1_JACKING_1,
+ SFX_CUBAN_LORD_GANG_1_JACKING_2,
+ SFX_CUBAN_LORD_GANG_1_JACKING_3,
+ SFX_CUBAN_LORD_GANG_1_JACKING_4,
+ SFX_CUBAN_LORD_GANG_1_JACKING_5,
+ SFX_CUBAN_LORD_GANG_1_LOST_1,
+ SFX_CUBAN_LORD_GANG_1_LOST_2,
+ SFX_CUBAN_LORD_GANG_1_MUGGED_1,
+ SFX_CUBAN_LORD_GANG_1_MUGGED_2,
+ SFX_CUBAN_LORD_GANG_1_SAVED_1,
+ SFX_CUBAN_LORD_GANG_1_TAXI_1,
+ SFX_CUBAN_LORD_GANG_1_TAXI_2,
+ SFX_CUBAN_LORD_GANG_2_BLOCKED_1,
+ SFX_CUBAN_LORD_GANG_2_BLOCKED_2,
+ SFX_CUBAN_LORD_GANG_2_BLOCKED_3,
+ SFX_CUBAN_LORD_GANG_2_BLOCKED_4,
+ SFX_CUBAN_LORD_GANG_2_BLOCKED_5,
+ SFX_CUBAN_LORD_GANG_2_BLOCKED_6,
+ SFX_CUBAN_LORD_GANG_2_BLOCKED_7,
+ SFX_CUBAN_LORD_GANG_2_BLOCKED_8,
+ SFX_CUBAN_LORD_GANG_2_BLOCKED_9,
+ SFX_CUBAN_LORD_GANG_2_BLOCKED_10,
+ SFX_CUBAN_LORD_GANG_2_BUMP_1,
+ SFX_CUBAN_LORD_GANG_2_BUMP_2,
+ SFX_CUBAN_LORD_GANG_2_BUMP_3,
+ SFX_CUBAN_LORD_GANG_2_BUMP_4,
+ SFX_CUBAN_LORD_GANG_2_BUMP_5,
+ SFX_CUBAN_LORD_GANG_2_BUMP_6,
+ SFX_CUBAN_LORD_GANG_2_BUMP_7,
+ SFX_CUBAN_LORD_GANG_2_BUMP_8,
+ SFX_CUBAN_LORD_GANG_2_BUMP_9,
+ SFX_CUBAN_LORD_GANG_2_BUMP_10,
+ SFX_CUBAN_LORD_GANG_2_CAR_CRASH_1,
+ SFX_CUBAN_LORD_GANG_2_CAR_CRASH_2,
+ SFX_CUBAN_LORD_GANG_2_CAR_CRASH_3,
+ SFX_CUBAN_LORD_GANG_2_CAR_CRASH_4,
+ SFX_CUBAN_LORD_GANG_2_CAR_CRASH_5,
+ SFX_CUBAN_LORD_GANG_2_CAR_CRASH_6,
+ SFX_CUBAN_LORD_GANG_2_CAR_CRASH_7,
+ SFX_CUBAN_LORD_GANG_2_CAR_CRASH_8,
+ SFX_CUBAN_LORD_GANG_2_CAR_CRASH_9,
+ SFX_CUBAN_LORD_GANG_2_CAR_CRASH_10,
+ SFX_CUBAN_LORD_GANG_2_CHAT_1,
+ SFX_CUBAN_LORD_GANG_2_CHAT_2,
+ SFX_CUBAN_LORD_GANG_2_CHAT_3,
+ SFX_CUBAN_LORD_GANG_2_CHAT_4,
+ SFX_CUBAN_LORD_GANG_2_CHAT_5,
+ SFX_CUBAN_LORD_GANG_2_CHAT_6,
+ SFX_CUBAN_LORD_GANG_2_CHAT_7,
+ SFX_CUBAN_LORD_GANG_2_CHAT_8,
+ SFX_CUBAN_LORD_GANG_2_CHAT_9,
+ SFX_CUBAN_LORD_GANG_2_CHAT_10,
+ SFX_CUBAN_LORD_GANG_2_DODGE_1,
+ SFX_CUBAN_LORD_GANG_2_DODGE_2,
+ SFX_CUBAN_LORD_GANG_2_DODGE_3,
+ SFX_CUBAN_LORD_GANG_2_DODGE_4,
+ SFX_CUBAN_LORD_GANG_2_DODGE_5,
+ SFX_CUBAN_LORD_GANG_2_DODGE_6,
+ SFX_CUBAN_LORD_GANG_2_DODGE_7,
+ SFX_CUBAN_LORD_GANG_2_DODGE_8,
+ SFX_CUBAN_LORD_GANG_2_DODGE_9,
+ SFX_CUBAN_LORD_GANG_2_DODGE_10,
+ SFX_CUBAN_LORD_GANG_2_DODGE_11,
+ SFX_CUBAN_LORD_GANG_2_DODGE_12,
+ SFX_CUBAN_LORD_GANG_2_DODGE_13,
+ SFX_CUBAN_LORD_GANG_2_EYEING_1,
+ SFX_CUBAN_LORD_GANG_2_EYEING_2,
+ SFX_CUBAN_LORD_GANG_2_FIGHT_1,
+ SFX_CUBAN_LORD_GANG_2_FIGHT_2,
+ SFX_CUBAN_LORD_GANG_2_FIGHT_3,
+ SFX_CUBAN_LORD_GANG_2_FIGHT_4,
+ SFX_CUBAN_LORD_GANG_2_FIGHT_5,
+ SFX_CUBAN_LORD_GANG_2_FIGHT_6,
+ SFX_CUBAN_LORD_GANG_2_FIGHT_7,
+ SFX_CUBAN_LORD_GANG_2_FIGHT_8,
+ SFX_CUBAN_LORD_GANG_2_FIGHT_9,
+ SFX_CUBAN_LORD_GANG_2_FIGHT_10,
+ SFX_CUBAN_LORD_GANG_2_GENERIC_CRASH_1,
+ SFX_CUBAN_LORD_GANG_2_GENERIC_CRASH_2,
+ SFX_CUBAN_LORD_GANG_2_GENERIC_CRASH_3,
+ SFX_CUBAN_LORD_GANG_2_GENERIC_CRASH_4,
+ SFX_CUBAN_LORD_GANG_2_GENERIC_CRASH_5,
+ SFX_CUBAN_LORD_GANG_2_GENERIC_CRASH_6,
+ SFX_CUBAN_LORD_GANG_2_GENERIC_CRASH_7,
+ SFX_CUBAN_LORD_GANG_2_GENERIC_CRASH_8,
+ SFX_CUBAN_LORD_GANG_2_GUN_COOL_1,
+ SFX_CUBAN_LORD_GANG_2_GUN_COOL_2,
+ SFX_CUBAN_LORD_GANG_2_GUN_COOL_3,
+ SFX_CUBAN_LORD_GANG_2_GUN_COOL_4,
+ SFX_CUBAN_LORD_GANG_2_GUN_COOL_5,
+ SFX_CUBAN_LORD_GANG_2_JACKED_1,
+ SFX_CUBAN_LORD_GANG_2_JACKED_2,
+ SFX_CUBAN_LORD_GANG_2_JACKED_3,
+ SFX_CUBAN_LORD_GANG_2_JACKED_4,
+ SFX_CUBAN_LORD_GANG_2_JACKED_5,
+ SFX_CUBAN_LORD_GANG_2_JACKED_6,
+ SFX_CUBAN_LORD_GANG_2_JACKING_1,
+ SFX_CUBAN_LORD_GANG_2_JACKING_2,
+ SFX_CUBAN_LORD_GANG_2_JACKING_3,
+ SFX_CUBAN_LORD_GANG_2_JACKING_4,
+ SFX_CUBAN_LORD_GANG_2_JACKING_5,
+ SFX_CUBAN_LORD_GANG_2_LOST_1,
+ SFX_CUBAN_LORD_GANG_2_LOST_2,
+ SFX_CUBAN_LORD_GANG_2_MUGGED_1,
+ SFX_CUBAN_LORD_GANG_2_MUGGED_2,
+ SFX_CUBAN_LORD_GANG_2_SAVED_1,
+ SFX_CUBAN_LORD_GANG_2_TAXI_1,
+ SFX_CUBAN_LORD_GANG_2_TAXI_2,
+ SFX_CUBAN_LORD_GANG_3_BLOCKED_1,
+ SFX_CUBAN_LORD_GANG_3_BLOCKED_2,
+ SFX_CUBAN_LORD_GANG_3_BLOCKED_3,
+ SFX_CUBAN_LORD_GANG_3_BLOCKED_4,
+ SFX_CUBAN_LORD_GANG_3_BLOCKED_5,
+ SFX_CUBAN_LORD_GANG_3_BLOCKED_6,
+ SFX_CUBAN_LORD_GANG_3_BLOCKED_7,
+ SFX_CUBAN_LORD_GANG_3_BLOCKED_8,
+ SFX_CUBAN_LORD_GANG_3_BLOCKED_9,
+ SFX_CUBAN_LORD_GANG_3_BLOCKED_10,
+ SFX_CUBAN_LORD_GANG_3_BUMP_1,
+ SFX_CUBAN_LORD_GANG_3_BUMP_2,
+ SFX_CUBAN_LORD_GANG_3_BUMP_3,
+ SFX_CUBAN_LORD_GANG_3_BUMP_4,
+ SFX_CUBAN_LORD_GANG_3_BUMP_5,
+ SFX_CUBAN_LORD_GANG_3_BUMP_6,
+ SFX_CUBAN_LORD_GANG_3_BUMP_7,
+ SFX_CUBAN_LORD_GANG_3_BUMP_8,
+ SFX_CUBAN_LORD_GANG_3_BUMP_9,
+ SFX_CUBAN_LORD_GANG_3_BUMP_10,
+ SFX_CUBAN_LORD_GANG_3_CAR_CRASH_1,
+ SFX_CUBAN_LORD_GANG_3_CAR_CRASH_2,
+ SFX_CUBAN_LORD_GANG_3_CAR_CRASH_3,
+ SFX_CUBAN_LORD_GANG_3_CAR_CRASH_4,
+ SFX_CUBAN_LORD_GANG_3_CAR_CRASH_5,
+ SFX_CUBAN_LORD_GANG_3_CAR_CRASH_6,
+ SFX_CUBAN_LORD_GANG_3_CAR_CRASH_7,
+ SFX_CUBAN_LORD_GANG_3_CAR_CRASH_8,
+ SFX_CUBAN_LORD_GANG_3_CAR_CRASH_9,
+ SFX_CUBAN_LORD_GANG_3_CAR_CRASH_10,
+ SFX_CUBAN_LORD_GANG_3_CHAT_1,
+ SFX_CUBAN_LORD_GANG_3_CHAT_2,
+ SFX_CUBAN_LORD_GANG_3_CHAT_3,
+ SFX_CUBAN_LORD_GANG_3_CHAT_4,
+ SFX_CUBAN_LORD_GANG_3_CHAT_5,
+ SFX_CUBAN_LORD_GANG_3_CHAT_6,
+ SFX_CUBAN_LORD_GANG_3_CHAT_7,
+ SFX_CUBAN_LORD_GANG_3_CHAT_8,
+ SFX_CUBAN_LORD_GANG_3_CHAT_9,
+ SFX_CUBAN_LORD_GANG_3_CHAT_10,
+ SFX_CUBAN_LORD_GANG_3_DODGE_1,
+ SFX_CUBAN_LORD_GANG_3_DODGE_2,
+ SFX_CUBAN_LORD_GANG_3_DODGE_3,
+ SFX_CUBAN_LORD_GANG_3_DODGE_4,
+ SFX_CUBAN_LORD_GANG_3_DODGE_5,
+ SFX_CUBAN_LORD_GANG_3_DODGE_6,
+ SFX_CUBAN_LORD_GANG_3_DODGE_7,
+ SFX_CUBAN_LORD_GANG_3_DODGE_8,
+ SFX_CUBAN_LORD_GANG_3_DODGE_9,
+ SFX_CUBAN_LORD_GANG_3_DODGE_10,
+ SFX_CUBAN_LORD_GANG_3_DODGE_11,
+ SFX_CUBAN_LORD_GANG_3_DODGE_12,
+ SFX_CUBAN_LORD_GANG_3_DODGE_13,
+ SFX_CUBAN_LORD_GANG_3_EYEING_1,
+ SFX_CUBAN_LORD_GANG_3_EYEING_2,
+ SFX_CUBAN_LORD_GANG_3_FIGHT_1,
+ SFX_CUBAN_LORD_GANG_3_FIGHT_2,
+ SFX_CUBAN_LORD_GANG_3_FIGHT_3,
+ SFX_CUBAN_LORD_GANG_3_FIGHT_4,
+ SFX_CUBAN_LORD_GANG_3_FIGHT_5,
+ SFX_CUBAN_LORD_GANG_3_FIGHT_6,
+ SFX_CUBAN_LORD_GANG_3_FIGHT_7,
+ SFX_CUBAN_LORD_GANG_3_FIGHT_8,
+ SFX_CUBAN_LORD_GANG_3_FIGHT_9,
+ SFX_CUBAN_LORD_GANG_3_FIGHT_10,
+ SFX_CUBAN_LORD_GANG_3_GENERIC_CRASH_1,
+ SFX_CUBAN_LORD_GANG_3_GENERIC_CRASH_2,
+ SFX_CUBAN_LORD_GANG_3_GENERIC_CRASH_3,
+ SFX_CUBAN_LORD_GANG_3_GENERIC_CRASH_4,
+ SFX_CUBAN_LORD_GANG_3_GENERIC_CRASH_5,
+ SFX_CUBAN_LORD_GANG_3_GENERIC_CRASH_6,
+ SFX_CUBAN_LORD_GANG_3_GENERIC_CRASH_7,
+ SFX_CUBAN_LORD_GANG_3_GENERIC_CRASH_8,
+ SFX_CUBAN_LORD_GANG_3_GUN_COOL_1,
+ SFX_CUBAN_LORD_GANG_3_GUN_COOL_2,
+ SFX_CUBAN_LORD_GANG_3_GUN_COOL_3,
+ SFX_CUBAN_LORD_GANG_3_GUN_COOL_4,
+ SFX_CUBAN_LORD_GANG_3_GUN_COOL_5,
+ SFX_CUBAN_LORD_GANG_3_JACKED_1,
+ SFX_CUBAN_LORD_GANG_3_JACKED_2,
+ SFX_CUBAN_LORD_GANG_3_JACKED_3,
+ SFX_CUBAN_LORD_GANG_3_JACKED_4,
+ SFX_CUBAN_LORD_GANG_3_JACKED_5,
+ SFX_CUBAN_LORD_GANG_3_JACKED_6,
+ SFX_CUBAN_LORD_GANG_3_JACKING_1,
+ SFX_CUBAN_LORD_GANG_3_JACKING_2,
+ SFX_CUBAN_LORD_GANG_3_JACKING_3,
+ SFX_CUBAN_LORD_GANG_3_JACKING_4,
+ SFX_CUBAN_LORD_GANG_3_JACKING_5,
+ SFX_CUBAN_LORD_GANG_3_LOST_1,
+ SFX_CUBAN_LORD_GANG_3_LOST_2,
+ SFX_CUBAN_LORD_GANG_3_MUGGED_1,
+ SFX_CUBAN_LORD_GANG_3_MUGGED_2,
+ SFX_CUBAN_LORD_GANG_3_SAVED_1,
+ SFX_CUBAN_LORD_GANG_3_TAXI_1,
+ SFX_CUBAN_LORD_GANG_3_TAXI_2,
- // bank 44
- SFX_POLICE_BALL_1,
+ SFX_PLAYER_GANG_1_BLOCKED_1,
+ SFX_PLAYER_GANG_1_BLOCKED_2,
+ SFX_PLAYER_GANG_1_BLOCKED_3,
+ SFX_PLAYER_GANG_1_BLOCKED_4,
+ SFX_PLAYER_GANG_1_BLOCKED_5,
+ SFX_PLAYER_GANG_1_BLOCKED_6,
+ SFX_PLAYER_GANG_1_BLOCKED_7,
+ SFX_PLAYER_GANG_1_BLOCKED_8,
+ SFX_PLAYER_GANG_1_BLOCKED_9,
+ SFX_PLAYER_GANG_1_BLOCKED_10,
+ SFX_PLAYER_GANG_1_BUMP_1,
+ SFX_PLAYER_GANG_1_BUMP_2,
+ SFX_PLAYER_GANG_1_BUMP_3,
+ SFX_PLAYER_GANG_1_BUMP_4,
+ SFX_PLAYER_GANG_1_BUMP_5,
+ SFX_PLAYER_GANG_1_CAR_CRASH_1,
+ SFX_PLAYER_GANG_1_CAR_CRASH_2,
+ SFX_PLAYER_GANG_1_CAR_CRASH_3,
+ SFX_PLAYER_GANG_1_CAR_CRASH_4,
+ SFX_PLAYER_GANG_1_CAR_CRASH_5,
+ SFX_PLAYER_GANG_1_CHAT_1,
+ SFX_PLAYER_GANG_1_CHAT_2,
+ SFX_PLAYER_GANG_1_CHAT_3,
+ SFX_PLAYER_GANG_1_CHAT_4,
+ SFX_PLAYER_GANG_1_CHAT_5,
+ SFX_PLAYER_GANG_1_CHAT_6,
+ SFX_PLAYER_GANG_1_CHAT_7,
+ SFX_PLAYER_GANG_1_CHAT_8,
+ SFX_PLAYER_GANG_1_DODGE_1,
+ SFX_PLAYER_GANG_1_DODGE_2,
+ SFX_PLAYER_GANG_1_DODGE_3,
+ SFX_PLAYER_GANG_1_DODGE_4,
+ SFX_PLAYER_GANG_1_DODGE_5,
+ SFX_PLAYER_GANG_1_DODGE_6,
+ SFX_PLAYER_GANG_1_DODGE_7,
+ SFX_PLAYER_GANG_1_EYEING_1,
+ SFX_PLAYER_GANG_1_EYEING_2,
+ SFX_PLAYER_GANG_1_FIGHT_1,
+ SFX_PLAYER_GANG_1_FIGHT_2,
+ SFX_PLAYER_GANG_1_FIGHT_3,
+ SFX_PLAYER_GANG_1_FIGHT_4,
+ SFX_PLAYER_GANG_1_FIGHT_5,
+ SFX_PLAYER_GANG_1_GENERIC_CRASH_1,
+ SFX_PLAYER_GANG_1_GENERIC_CRASH_2,
+ SFX_PLAYER_GANG_1_GENERIC_CRASH_3,
+ SFX_PLAYER_GANG_1_GENERIC_CRASH_4,
+ SFX_PLAYER_GANG_1_GENERIC_CRASH_5,
+ SFX_PLAYER_GANG_1_GUN_COOL_1,
+ SFX_PLAYER_GANG_1_GUN_COOL_2,
+ SFX_PLAYER_GANG_1_GUN_COOL_3,
+ SFX_PLAYER_GANG_1_GUN_COOL_4,
+ SFX_PLAYER_GANG_1_JACKED_1,
+ SFX_PLAYER_GANG_1_JACKED_2,
+ SFX_PLAYER_GANG_1_JACKED_3,
+ SFX_PLAYER_GANG_1_JACKED_4,
+ SFX_PLAYER_GANG_1_JACKED_5,
+ SFX_PLAYER_GANG_1_JACKING_1,
+ SFX_PLAYER_GANG_1_JACKING_2,
+ SFX_PLAYER_GANG_1_JACKING_3,
+ SFX_PLAYER_GANG_1_JACKING_4,
+ SFX_PLAYER_GANG_1_JACKING_5,
+ SFX_PLAYER_GANG_1_LOST_1,
+ SFX_PLAYER_GANG_1_LOST_2,
+ SFX_PLAYER_GANG_1_MUGGED_1,
+ SFX_PLAYER_GANG_1_MUGGED_2,
+ SFX_PLAYER_GANG_1_SAVED_1,
+ SFX_PLAYER_GANG_1_SHOCKED_1,
+ SFX_PLAYER_GANG_1_SHOCKED_2,
+ SFX_PLAYER_GANG_1_TAXI_1,
+ SFX_PLAYER_GANG_1_TAXI_2,
+ SFX_PLAYER_GANG_2_BLOCKED_1,
+ SFX_PLAYER_GANG_2_BLOCKED_2,
+ SFX_PLAYER_GANG_2_BLOCKED_3,
+ SFX_PLAYER_GANG_2_BLOCKED_4,
+ SFX_PLAYER_GANG_2_BLOCKED_5,
+ SFX_PLAYER_GANG_2_BLOCKED_6,
+ SFX_PLAYER_GANG_2_BLOCKED_7,
+ SFX_PLAYER_GANG_2_BLOCKED_8,
+ SFX_PLAYER_GANG_2_BLOCKED_9,
+ SFX_PLAYER_GANG_2_BLOCKED_10,
+ SFX_PLAYER_GANG_2_BUMP_1,
+ SFX_PLAYER_GANG_2_BUMP_2,
+ SFX_PLAYER_GANG_2_BUMP_3,
+ SFX_PLAYER_GANG_2_BUMP_4,
+ SFX_PLAYER_GANG_2_BUMP_5,
+ SFX_PLAYER_GANG_2_CAR_CRASH_1,
+ SFX_PLAYER_GANG_2_CAR_CRASH_2,
+ SFX_PLAYER_GANG_2_CAR_CRASH_3,
+ SFX_PLAYER_GANG_2_CAR_CRASH_4,
+ SFX_PLAYER_GANG_2_CAR_CRASH_5,
+ SFX_PLAYER_GANG_2_CHAT_1,
+ SFX_PLAYER_GANG_2_CHAT_2,
+ SFX_PLAYER_GANG_2_CHAT_3,
+ SFX_PLAYER_GANG_2_CHAT_4,
+ SFX_PLAYER_GANG_2_CHAT_5,
+ SFX_PLAYER_GANG_2_CHAT_6,
+ SFX_PLAYER_GANG_2_CHAT_7,
+ SFX_PLAYER_GANG_2_CHAT_8,
+ SFX_PLAYER_GANG_2_DODGE_1,
+ SFX_PLAYER_GANG_2_DODGE_2,
+ SFX_PLAYER_GANG_2_DODGE_3,
+ SFX_PLAYER_GANG_2_DODGE_4,
+ SFX_PLAYER_GANG_2_DODGE_5,
+ SFX_PLAYER_GANG_2_DODGE_6,
+ SFX_PLAYER_GANG_2_DODGE_7,
+ SFX_PLAYER_GANG_2_EYEING_1,
+ SFX_PLAYER_GANG_2_EYEING_2,
+ SFX_PLAYER_GANG_2_FIGHT_1,
+ SFX_PLAYER_GANG_2_FIGHT_2,
+ SFX_PLAYER_GANG_2_FIGHT_3,
+ SFX_PLAYER_GANG_2_FIGHT_4,
+ SFX_PLAYER_GANG_2_FIGHT_5,
+ SFX_PLAYER_GANG_2_GENERIC_CRASH_1,
+ SFX_PLAYER_GANG_2_GENERIC_CRASH_2,
+ SFX_PLAYER_GANG_2_GENERIC_CRASH_3,
+ SFX_PLAYER_GANG_2_GENERIC_CRASH_4,
+ SFX_PLAYER_GANG_2_GENERIC_CRASH_5,
+ SFX_PLAYER_GANG_2_GUN_COOL_1,
+ SFX_PLAYER_GANG_2_GUN_COOL_2,
+ SFX_PLAYER_GANG_2_GUN_COOL_3,
+ SFX_PLAYER_GANG_2_GUN_COOL_4,
+ SFX_PLAYER_GANG_2_JACKED_1,
+ SFX_PLAYER_GANG_2_JACKED_2,
+ SFX_PLAYER_GANG_2_JACKED_3,
+ SFX_PLAYER_GANG_2_JACKED_4,
+ SFX_PLAYER_GANG_2_JACKED_5,
+ SFX_PLAYER_GANG_2_JACKING_1,
+ SFX_PLAYER_GANG_2_JACKING_2,
+ SFX_PLAYER_GANG_2_JACKING_3,
+ SFX_PLAYER_GANG_2_JACKING_4,
+ SFX_PLAYER_GANG_2_JACKING_5,
+ SFX_PLAYER_GANG_2_LOST_1,
+ SFX_PLAYER_GANG_2_LOST_2,
+ SFX_PLAYER_GANG_2_MUGGED_1,
+ SFX_PLAYER_GANG_2_MUGGED_2,
+ SFX_PLAYER_GANG_2_SAVED_1,
+ SFX_PLAYER_GANG_2_SHOCKED_1,
+ SFX_PLAYER_GANG_2_SHOCKED_2,
+ SFX_PLAYER_GANG_2_TAXI_1,
+ SFX_PLAYER_GANG_2_TAXI_2,
+ SFX_PLAYER_GANG_3_BLOCKED_1,
+ SFX_PLAYER_GANG_3_BLOCKED_2,
+ SFX_PLAYER_GANG_3_BLOCKED_3,
+ SFX_PLAYER_GANG_3_BLOCKED_4,
+ SFX_PLAYER_GANG_3_BLOCKED_5,
+ SFX_PLAYER_GANG_3_BLOCKED_6,
+ SFX_PLAYER_GANG_3_BLOCKED_7,
+ SFX_PLAYER_GANG_3_BLOCKED_8,
+ SFX_PLAYER_GANG_3_BLOCKED_9,
+ SFX_PLAYER_GANG_3_BLOCKED_10,
+ SFX_PLAYER_GANG_3_BUMP_1,
+ SFX_PLAYER_GANG_3_BUMP_2,
+ SFX_PLAYER_GANG_3_BUMP_3,
+ SFX_PLAYER_GANG_3_BUMP_4,
+ SFX_PLAYER_GANG_3_BUMP_5,
+ SFX_PLAYER_GANG_3_CAR_CRASH_1,
+ SFX_PLAYER_GANG_3_CAR_CRASH_2,
+ SFX_PLAYER_GANG_3_CAR_CRASH_3,
+ SFX_PLAYER_GANG_3_CAR_CRASH_4,
+ SFX_PLAYER_GANG_3_CAR_CRASH_5,
+ SFX_PLAYER_GANG_3_CHAT_1,
+ SFX_PLAYER_GANG_3_CHAT_2,
+ SFX_PLAYER_GANG_3_CHAT_3,
+ SFX_PLAYER_GANG_3_CHAT_4,
+ SFX_PLAYER_GANG_3_CHAT_5,
+ SFX_PLAYER_GANG_3_CHAT_6,
+ SFX_PLAYER_GANG_3_CHAT_7,
+ SFX_PLAYER_GANG_3_CHAT_8,
+ SFX_PLAYER_GANG_3_DODGE_1,
+ SFX_PLAYER_GANG_3_DODGE_2,
+ SFX_PLAYER_GANG_3_DODGE_3,
+ SFX_PLAYER_GANG_3_DODGE_4,
+ SFX_PLAYER_GANG_3_DODGE_5,
+ SFX_PLAYER_GANG_3_DODGE_6,
+ SFX_PLAYER_GANG_3_DODGE_7,
+ SFX_PLAYER_GANG_3_EYEING_1,
+ SFX_PLAYER_GANG_3_EYEING_2,
+ SFX_PLAYER_GANG_3_FIGHT_1,
+ SFX_PLAYER_GANG_3_FIGHT_2,
+ SFX_PLAYER_GANG_3_FIGHT_3,
+ SFX_PLAYER_GANG_3_FIGHT_4,
+ SFX_PLAYER_GANG_3_FIGHT_5,
+ SFX_PLAYER_GANG_3_GENERIC_CRASH_1,
+ SFX_PLAYER_GANG_3_GENERIC_CRASH_2,
+ SFX_PLAYER_GANG_3_GENERIC_CRASH_3,
+ SFX_PLAYER_GANG_3_GENERIC_CRASH_4,
+ SFX_PLAYER_GANG_3_GENERIC_CRASH_5,
+ SFX_PLAYER_GANG_3_GUN_COOL_1,
+ SFX_PLAYER_GANG_3_GUN_COOL_2,
+ SFX_PLAYER_GANG_3_GUN_COOL_3,
+ SFX_PLAYER_GANG_3_GUN_COOL_4,
+ SFX_PLAYER_GANG_3_JACKED_1,
+ SFX_PLAYER_GANG_3_JACKED_2,
+ SFX_PLAYER_GANG_3_JACKED_3,
+ SFX_PLAYER_GANG_3_JACKED_4,
+ SFX_PLAYER_GANG_3_JACKED_5,
+ SFX_PLAYER_GANG_3_JACKING_1,
+ SFX_PLAYER_GANG_3_JACKING_2,
+ SFX_PLAYER_GANG_3_JACKING_3,
+ SFX_PLAYER_GANG_3_JACKING_4,
+ SFX_PLAYER_GANG_3_JACKING_5,
+ SFX_PLAYER_GANG_3_LOST_1,
+ SFX_PLAYER_GANG_3_LOST_2,
+ SFX_PLAYER_GANG_3_MUGGED_1,
+ SFX_PLAYER_GANG_3_MUGGED_2,
+ SFX_PLAYER_GANG_3_SAVED_1,
+ SFX_PLAYER_GANG_3_SHOCKED_1,
+ SFX_PLAYER_GANG_3_SHOCKED_2,
+ SFX_PLAYER_GANG_3_TAXI_1,
+ SFX_PLAYER_GANG_3_TAXI_2,
- // bank 45
- SFX_BANK_ALARM_1,
+ SFX_GUARD_DUTY_1_BUMP_1,
+ SFX_GUARD_DUTY_1_BUMP_2,
+ SFX_GUARD_DUTY_1_BUMP_3,
+ SFX_GUARD_DUTY_1_BUMP_4,
+ SFX_GUARD_DUTY_1_BUMP_5,
+ SFX_GUARD_DUTY_1_BUMP_6,
+ SFX_GUARD_DUTY_1_BUMP_7,
+ SFX_GUARD_DUTY_1_BUMP_8,
+ SFX_GUARD_DUTY_1_BUMP_9,
+ SFX_GUARD_DUTY_1_BUMP_10,
+ SFX_GUARD_DUTY_1_CHAT_1,
+ SFX_GUARD_DUTY_1_CHAT_2,
+ SFX_GUARD_DUTY_1_CHAT_3,
+ SFX_GUARD_DUTY_1_CHAT_4,
+ SFX_GUARD_DUTY_1_CHAT_5,
+ SFX_GUARD_DUTY_1_CHAT_6,
+ SFX_GUARD_DUTY_1_CHAT_7,
+ SFX_GUARD_DUTY_1_CHAT_8,
+ SFX_GUARD_DUTY_1_CHAT_9,
+ SFX_GUARD_DUTY_1_CHAT_10,
+ SFX_GUARD_DUTY_1_DODGE_1,
+ SFX_GUARD_DUTY_1_DODGE_2,
+ SFX_GUARD_DUTY_1_DODGE_3,
+ SFX_GUARD_DUTY_1_DODGE_4,
+ SFX_GUARD_DUTY_1_DODGE_5,
+ SFX_GUARD_DUTY_1_DODGE_6,
+ SFX_GUARD_DUTY_1_DODGE_7,
+ SFX_GUARD_DUTY_1_DODGE_8,
+ SFX_GUARD_DUTY_1_DODGE_9,
+ SFX_GUARD_DUTY_1_EYEING_1,
+ SFX_GUARD_DUTY_1_EYEING_2,
+ SFX_GUARD_DUTY_1_FIGHT_1,
+ SFX_GUARD_DUTY_1_FIGHT_2,
+ SFX_GUARD_DUTY_1_FIGHT_3,
+ SFX_GUARD_DUTY_1_FIGHT_4,
+ SFX_GUARD_DUTY_1_FIGHT_5,
+ SFX_GUARD_DUTY_1_FIGHT_6,
+ SFX_GUARD_DUTY_1_FIGHT_7,
+ SFX_GUARD_DUTY_1_GUN_COOL_1,
+ SFX_GUARD_DUTY_1_GUN_COOL_2,
+ SFX_GUARD_DUTY_1_GUN_COOL_3,
+ SFX_GUARD_DUTY_1_GUN_COOL_4,
+ SFX_GUARD_DUTY_1_GUN_COOL_5,
+ SFX_GUARD_DUTY_1_GUN_COOL_6,
+ SFX_GUARD_DUTY_1_LOST_1,
+ SFX_GUARD_DUTY_1_LOST_2,
+ SFX_GUARD_DUTY_1_SAVED_1,
+ SFX_GUARD_DUTY_1_SAVED_2,
+ SFX_GUARD_DUTY_1_SHOCKED_1,
+ SFX_GUARD_DUTY_1_SHOCKED_2,
- // bank 46
- SFX_RAVE_INDUSTRIAL,
+ SFX_GUARD_DUTY_2_BUMP_1,
+ SFX_GUARD_DUTY_2_BUMP_2,
+ SFX_GUARD_DUTY_2_BUMP_3,
+ SFX_GUARD_DUTY_2_BUMP_4,
+ SFX_GUARD_DUTY_2_BUMP_5,
+ SFX_GUARD_DUTY_2_BUMP_6,
+ SFX_GUARD_DUTY_2_BUMP_7,
+ SFX_GUARD_DUTY_2_BUMP_8,
+ SFX_GUARD_DUTY_2_BUMP_9,
+ SFX_GUARD_DUTY_2_BUMP_10,
+ SFX_GUARD_DUTY_2_CHAT_1,
+ SFX_GUARD_DUTY_2_CHAT_2,
+ SFX_GUARD_DUTY_2_CHAT_3,
+ SFX_GUARD_DUTY_2_CHAT_4,
+ SFX_GUARD_DUTY_2_CHAT_5,
+ SFX_GUARD_DUTY_2_CHAT_6,
+ SFX_GUARD_DUTY_2_CHAT_7,
+ SFX_GUARD_DUTY_2_CHAT_8,
+ SFX_GUARD_DUTY_2_CHAT_9,
+ SFX_GUARD_DUTY_2_CHAT_10,
+ SFX_GUARD_DUTY_2_DODGE_1,
+ SFX_GUARD_DUTY_2_DODGE_2,
+ SFX_GUARD_DUTY_2_DODGE_3,
+ SFX_GUARD_DUTY_2_DODGE_4,
+ SFX_GUARD_DUTY_2_DODGE_5,
+ SFX_GUARD_DUTY_2_DODGE_6,
+ SFX_GUARD_DUTY_2_DODGE_7,
+ SFX_GUARD_DUTY_2_DODGE_8,
+ SFX_GUARD_DUTY_2_DODGE_9,
+ SFX_GUARD_DUTY_2_EYEING_1,
+ SFX_GUARD_DUTY_2_EYEING_2,
+ SFX_GUARD_DUTY_2_FIGHT_1,
+ SFX_GUARD_DUTY_2_FIGHT_2,
+ SFX_GUARD_DUTY_2_FIGHT_3,
+ SFX_GUARD_DUTY_2_FIGHT_4,
+ SFX_GUARD_DUTY_2_FIGHT_5,
+ SFX_GUARD_DUTY_2_FIGHT_6,
+ SFX_GUARD_DUTY_2_FIGHT_7,
+ SFX_GUARD_DUTY_2_GUN_COOL_1,
+ SFX_GUARD_DUTY_2_GUN_COOL_2,
+ SFX_GUARD_DUTY_2_GUN_COOL_3,
+ SFX_GUARD_DUTY_2_GUN_COOL_4,
+ SFX_GUARD_DUTY_2_GUN_COOL_5,
+ SFX_GUARD_DUTY_2_GUN_COOL_6,
+ SFX_GUARD_DUTY_2_LOST_1,
+ SFX_GUARD_DUTY_2_LOST_2,
+ SFX_GUARD_DUTY_2_SAVED_1,
+ SFX_GUARD_DUTY_2_SAVED_2,
+ SFX_GUARD_DUTY_2_SHOCKED_1,
+ SFX_GUARD_DUTY_2_SHOCKED_2,
- // bank 47
- SFX_RAVE_COMMERCIAL,
+ SFX_GUARD_DUTY_3_BUMP_1,
+ SFX_GUARD_DUTY_3_BUMP_2,
+ SFX_GUARD_DUTY_3_BUMP_3,
+ SFX_GUARD_DUTY_3_BUMP_4,
+ SFX_GUARD_DUTY_3_BUMP_5,
+ SFX_GUARD_DUTY_3_BUMP_6,
+ SFX_GUARD_DUTY_3_BUMP_7,
+ SFX_GUARD_DUTY_3_BUMP_8,
+ SFX_GUARD_DUTY_3_BUMP_9,
+ SFX_GUARD_DUTY_3_BUMP_10,
+ SFX_GUARD_DUTY_3_CHAT_1,
+ SFX_GUARD_DUTY_3_CHAT_2,
+ SFX_GUARD_DUTY_3_CHAT_3,
+ SFX_GUARD_DUTY_3_CHAT_4,
+ SFX_GUARD_DUTY_3_CHAT_5,
+ SFX_GUARD_DUTY_3_CHAT_6,
+ SFX_GUARD_DUTY_3_CHAT_7,
+ SFX_GUARD_DUTY_3_CHAT_8,
+ SFX_GUARD_DUTY_3_CHAT_9,
+ SFX_GUARD_DUTY_3_CHAT_10,
+ SFX_GUARD_DUTY_3_DODGE_1,
+ SFX_GUARD_DUTY_3_DODGE_2,
+ SFX_GUARD_DUTY_3_DODGE_3,
+ SFX_GUARD_DUTY_3_DODGE_4,
+ SFX_GUARD_DUTY_3_DODGE_5,
+ SFX_GUARD_DUTY_3_DODGE_6,
+ SFX_GUARD_DUTY_3_DODGE_7,
+ SFX_GUARD_DUTY_3_DODGE_8,
+ SFX_GUARD_DUTY_3_DODGE_9,
+ SFX_GUARD_DUTY_3_EYEING_1,
+ SFX_GUARD_DUTY_3_EYEING_2,
+ SFX_GUARD_DUTY_3_FIGHT_1,
+ SFX_GUARD_DUTY_3_FIGHT_2,
+ SFX_GUARD_DUTY_3_FIGHT_3,
+ SFX_GUARD_DUTY_3_FIGHT_4,
+ SFX_GUARD_DUTY_3_FIGHT_5,
+ SFX_GUARD_DUTY_3_FIGHT_6,
+ SFX_GUARD_DUTY_3_FIGHT_7,
+ SFX_GUARD_DUTY_3_GUN_COOL_1,
+ SFX_GUARD_DUTY_3_GUN_COOL_2,
+ SFX_GUARD_DUTY_3_GUN_COOL_3,
+ SFX_GUARD_DUTY_3_GUN_COOL_4,
+ SFX_GUARD_DUTY_3_GUN_COOL_5,
+ SFX_GUARD_DUTY_3_GUN_COOL_6,
+ SFX_GUARD_DUTY_3_LOST_1,
+ SFX_GUARD_DUTY_3_LOST_2,
+ SFX_GUARD_DUTY_3_SAVED_1,
+ SFX_GUARD_DUTY_3_SAVED_2,
+ SFX_GUARD_DUTY_3_SHOCKED_1,
+ SFX_GUARD_DUTY_3_SHOCKED_2,
- // bank 48
- SFX_RAVE_SUBURBAN,
+ SFX_VICE_VOICE_1_ARREST_1,
+ SFX_VICE_VOICE_1_ARREST_2,
+ SFX_VICE_VOICE_1_ARREST_3,
+ SFX_VICE_VOICE_1_MIAMIVICE_EXITING_CAR_1,
- // bank 49
- SFX_RAVE_COMMERCIAL_2,
+ SFX_VICE_VOICE_2_ARREST_1,
+ SFX_VICE_VOICE_2_ARREST_2,
+ SFX_VICE_VOICE_2_ARREST_3,
+ SFX_VICE_VOICE_2_MIAMIVICE_EXITING_CAR_1,
- // unused banks 50-58
- SFX_CLUB_1_1,
- SFX_CLUB_1_2,
- SFX_CLUB_1_3,
- SFX_CLUB_1_4,
- SFX_CLUB_1_5,
- SFX_CLUB_1_6,
- SFX_CLUB_1_7,
- SFX_CLUB_1_8,
- SFX_CLUB_1_9,
+ SFX_VICE_VOICE_3_ARREST_1,
+ SFX_VICE_VOICE_3_ARREST_2,
+ SFX_VICE_VOICE_3_ARREST_3,
+ SFX_VICE_VOICE_3_MIAMIVICE_EXITING_CAR_1,
- // bank 59
- SFX_EXPLOSION_1,
- SFX_BRIDGE_OPEN_WARNING,
+ SFX_VICE_VOICE_4_ARREST_1,
+ SFX_VICE_VOICE_4_ARREST_2,
+ SFX_VICE_VOICE_4_ARREST_3,
+ SFX_VICE_VOICE_4_MIAMIVICE_EXITING_CAR_1,
- SFX_PAGER, // used to be ped comment on PS2
+ SFX_VICE_VOICE_5_ARREST_1,
+ SFX_VICE_VOICE_5_ARREST_2,
+ SFX_VICE_VOICE_5_ARREST_3,
+ SFX_VICE_VOICE_5_MIAMIVICE_EXITING_CAR_1,
- SFX_COP_VOICE_1_ARREST_1,
- SFX_COP_VOICE_1_ARREST_2,
- SFX_COP_VOICE_1_ARREST_3,
- SFX_COP_VOICE_1_ARREST_4,
- SFX_COP_VOICE_1_ARREST_5,
- SFX_COP_VOICE_1_ARREST_6,
- SFX_COP_VOICE_1_CHASE_1,
- SFX_COP_VOICE_1_CHASE_2,
- SFX_COP_VOICE_1_CHASE_3,
- SFX_COP_VOICE_1_CHASE_4,
- SFX_COP_VOICE_1_CHASE_5,
- SFX_COP_VOICE_1_CHASE_6,
- SFX_COP_VOICE_1_CHASE_7,
- SFX_COP_VOICE_2_ARREST_1,
- SFX_COP_VOICE_2_ARREST_2,
- SFX_COP_VOICE_2_ARREST_3,
- SFX_COP_VOICE_2_ARREST_4,
- SFX_COP_VOICE_2_ARREST_5,
- SFX_COP_VOICE_2_ARREST_6,
- SFX_COP_VOICE_2_CHASE_1,
- SFX_COP_VOICE_2_CHASE_2,
- SFX_COP_VOICE_2_CHASE_3,
- SFX_COP_VOICE_2_CHASE_4,
- SFX_COP_VOICE_2_CHASE_5,
- SFX_COP_VOICE_2_CHASE_6,
- SFX_COP_VOICE_2_CHASE_7,
- SFX_COP_VOICE_3_ARREST_1,
- SFX_COP_VOICE_3_ARREST_2,
- SFX_COP_VOICE_3_ARREST_3,
- SFX_COP_VOICE_3_ARREST_4,
- SFX_COP_VOICE_3_ARREST_5,
- SFX_COP_VOICE_3_ARREST_6,
- SFX_COP_VOICE_3_CHASE_1,
- SFX_COP_VOICE_3_CHASE_2,
- SFX_COP_VOICE_3_CHASE_3,
- SFX_COP_VOICE_3_CHASE_4,
- SFX_COP_VOICE_3_CHASE_5,
- SFX_COP_VOICE_3_CHASE_6,
- SFX_COP_VOICE_3_CHASE_7,
- SFX_COP_VOICE_4_ARREST_1,
- SFX_COP_VOICE_4_ARREST_2,
- SFX_COP_VOICE_4_ARREST_3,
- SFX_COP_VOICE_4_ARREST_4,
- SFX_COP_VOICE_4_ARREST_5,
- SFX_COP_VOICE_4_ARREST_6,
- SFX_COP_VOICE_4_CHASE_1,
- SFX_COP_VOICE_4_CHASE_2,
- SFX_COP_VOICE_4_CHASE_3,
- SFX_COP_VOICE_4_CHASE_4,
- SFX_COP_VOICE_4_CHASE_5,
- SFX_COP_VOICE_4_CHASE_6,
- SFX_COP_VOICE_4_CHASE_7,
- SFX_COP_VOICE_5_ARREST_1,
- SFX_COP_VOICE_5_ARREST_2,
- SFX_COP_VOICE_5_ARREST_3,
- SFX_COP_VOICE_5_ARREST_4,
- SFX_COP_VOICE_5_ARREST_5,
- SFX_COP_VOICE_5_ARREST_6,
- SFX_COP_VOICE_5_CHASE_1,
- SFX_COP_VOICE_5_CHASE_2,
- SFX_COP_VOICE_5_CHASE_3,
- SFX_COP_VOICE_5_CHASE_4,
- SFX_COP_VOICE_5_CHASE_5,
- SFX_COP_VOICE_5_CHASE_6,
- SFX_COP_VOICE_5_CHASE_7,
- SFX_SWAT_VOICE_1_CHASE_1,
- SFX_SWAT_VOICE_1_CHASE_2,
- SFX_SWAT_VOICE_1_CHASE_3,
- SFX_SWAT_VOICE_1_CHASE_4,
- SFX_SWAT_VOICE_1_CHASE_5,
- SFX_SWAT_VOICE_1_CHASE_6,
- SFX_SWAT_VOICE_2_CHASE_1,
- SFX_SWAT_VOICE_2_CHASE_2,
- SFX_SWAT_VOICE_2_CHASE_3,
- SFX_SWAT_VOICE_2_CHASE_4,
- SFX_SWAT_VOICE_2_CHASE_5,
- SFX_SWAT_VOICE_2_CHASE_6,
- SFX_SWAT_VOICE_3_CHASE_1,
- SFX_SWAT_VOICE_3_CHASE_2,
- SFX_SWAT_VOICE_3_CHASE_3,
- SFX_SWAT_VOICE_3_CHASE_4,
- SFX_SWAT_VOICE_3_CHASE_5,
- SFX_SWAT_VOICE_3_CHASE_6,
- SFX_SWAT_VOICE_4_CHASE_1,
- SFX_SWAT_VOICE_4_CHASE_2,
- SFX_SWAT_VOICE_4_CHASE_3,
- SFX_SWAT_VOICE_4_CHASE_4,
- SFX_SWAT_VOICE_4_CHASE_5,
- SFX_SWAT_VOICE_4_CHASE_6,
- SFX_FBI_VOICE_1_CHASE_1,
- SFX_FBI_VOICE_1_CHASE_2,
- SFX_FBI_VOICE_1_CHASE_3,
- SFX_FBI_VOICE_1_CHASE_4,
- SFX_FBI_VOICE_1_CHASE_5,
- SFX_FBI_VOICE_1_CHASE_6,
- SFX_FBI_VOICE_2_CHASE_1,
- SFX_FBI_VOICE_2_CHASE_2,
- SFX_FBI_VOICE_2_CHASE_3,
- SFX_FBI_VOICE_2_CHASE_4,
- SFX_FBI_VOICE_2_CHASE_5,
- SFX_FBI_VOICE_2_CHASE_6,
- SFX_FBI_VOICE_3_CHASE_1,
- SFX_FBI_VOICE_3_CHASE_2,
- SFX_FBI_VOICE_3_CHASE_3,
- SFX_FBI_VOICE_3_CHASE_4,
- SFX_FBI_VOICE_3_CHASE_5,
- SFX_FBI_VOICE_3_CHASE_6,
- SFX_POLICE_HELI_1,
- SFX_POLICE_HELI_2,
- SFX_POLICE_HELI_3,
- SFX_POLICE_HELI_4,
- SFX_POLICE_HELI_5,
- SFX_POLICE_HELI_6,
- SFX_POLICE_HELI_7,
- SFX_POLICE_HELI_8,
- SFX_POLICE_HELI_9,
- SFX_POLICE_HELI_10,
- SFX_POLICE_HELI_11,
- SFX_POLICE_HELI_12,
- SFX_POLICE_HELI_13,
- SFX_POLICE_HELI_14,
- SFX_POLICE_HELI_15,
- SFX_POLICE_HELI_16,
- SFX_POLICE_HELI_17,
- SFX_POLICE_HELI_18,
- SFX_POLICE_HELI_19,
- SFX_POLICE_HELI_20,
- SFX_POLICE_HELI_21,
- SFX_POLICE_HELI_22,
- SFX_POLICE_HELI_23,
- SFX_POLICE_HELI_24,
- SFX_POLICE_HELI_25,
- SFX_POLICE_HELI_26,
- SFX_POLICE_HELI_27,
- SFX_POLICE_HELI_28,
- SFX_POLICE_HELI_29,
- SFX_CHUNKY_DEATH,
- SFX_BLACK_DOCKER_VOICE_1_DRIVER_ABUSE_1,
- SFX_BLACK_DOCKER_VOICE_1_DRIVER_ABUSE_2,
- SFX_BLACK_DOCKER_VOICE_1_DRIVER_ABUSE_3,
- SFX_BLACK_DOCKER_VOICE_1_DRIVER_ABUSE_4,
- SFX_BLACK_DOCKER_VOICE_1_DRIVER_ABUSE_5,
- SFX_BLACK_DOCKER_VOICE_1_DRIVER_ABUSE_6,
- SFX_BLACK_DOCKER_VOICE_1_CHAT_1,
- SFX_BLACK_DOCKER_VOICE_1_CHAT_2,
- SFX_BLACK_DOCKER_VOICE_1_CHAT_3,
- SFX_BLACK_DOCKER_VOICE_1_CHAT_4,
- SFX_BLACK_DOCKER_VOICE_1_CHAT_5,
- SFX_BLACK_DOCKER_VOICE_1_DODGE_1,
- SFX_BLACK_DOCKER_VOICE_1_DODGE_2,
- SFX_BLACK_DOCKER_VOICE_1_DODGE_3,
- SFX_BLACK_DOCKER_VOICE_1_DODGE_4,
- SFX_BLACK_DOCKER_VOICE_1_DODGE_5,
- SFX_BLACK_DOCKER_VOICE_1_EYING_1,
- SFX_BLACK_DOCKER_VOICE_1_EYING_2,
- SFX_BLACK_DOCKER_VOICE_1_EYING_3,
- SFX_BLACK_DOCKER_VOICE_1_FIGHT_1,
- SFX_BLACK_DOCKER_VOICE_1_FIGHT_2,
- SFX_BLACK_DOCKER_VOICE_1_FIGHT_3,
- SFX_BLACK_DOCKER_VOICE_1_FIGHT_4,
- SFX_BLACK_DOCKER_VOICE_1_FIGHT_5,
- SFX_BLACK_DOCKER_VOICE_1_GUN_PANIC_1,
- SFX_BLACK_DOCKER_VOICE_1_GUN_PANIC_2,
- SFX_BLACK_DOCKER_VOICE_1_GUN_PANIC_3,
- SFX_ARMY_VOICE_1_CHASE_1,
- SFX_ARMY_VOICE_1_CHASE_2,
- SFX_ARMY_VOICE_1_CHASE_3,
- SFX_ARMY_VOICE_1_CHASE_4,
- SFX_ARMY_VOICE_1_CHASE_5,
- SFX_ARMY_VOICE_1_CHASE_6,
- SFX_ARMY_VOICE_1_CHASE_7,
- SFX_ARMY_VOICE_1_CHASE_8,
- SFX_ARMY_VOICE_1_CHASE_9,
- SFX_ARMY_VOICE_1_CHASE_10,
- SFX_ARMY_VOICE_1_CHASE_11,
- SFX_ARMY_VOICE_1_CHASE_12,
- SFX_ARMY_VOICE_1_CHASE_13,
- SFX_ARMY_VOICE_1_CHASE_14,
- SFX_ARMY_VOICE_1_CHASE_15,
- SFX_ARMY_VOICE_2_CHASE_1,
- SFX_ARMY_VOICE_2_CHASE_2,
- SFX_ARMY_VOICE_2_CHASE_3,
- SFX_ARMY_VOICE_2_CHASE_4,
- SFX_ARMY_VOICE_2_CHASE_5,
- SFX_ARMY_VOICE_2_CHASE_6,
- SFX_ARMY_VOICE_2_CHASE_7,
- SFX_ARMY_VOICE_2_CHASE_8,
- SFX_ARMY_VOICE_2_CHASE_9,
- SFX_ARMY_VOICE_2_CHASE_10,
- SFX_ARMY_VOICE_2_CHASE_11,
- SFX_ARMY_VOICE_2_CHASE_12,
- SFX_ARMY_VOICE_2_CHASE_13,
- SFX_ARMY_VOICE_2_CHASE_14,
- SFX_ARMY_VOICE_2_CHASE_15,
- SFX_CLAUDE_LOW_DAMAGE_GRUNT_1,
- SFX_CLAUDE_LOW_DAMAGE_GRUNT_2,
- SFX_CLAUDE_LOW_DAMAGE_GRUNT_3,
- SFX_CLAUDE_LOW_DAMAGE_GRUNT_4,
- SFX_CLAUDE_LOW_DAMAGE_GRUNT_5,
- SFX_CLAUDE_LOW_DAMAGE_GRUNT_6,
- SFX_CLAUDE_LOW_DAMAGE_GRUNT_7,
- SFX_CLAUDE_LOW_DAMAGE_GRUNT_8,
- SFX_CLAUDE_LOW_DAMAGE_GRUNT_9,
- SFX_CLAUDE_LOW_DAMAGE_GRUNT_10,
- SFX_CLAUDE_HIGH_DAMAGE_GRUNT_1,
- SFX_CLAUDE_HIGH_DAMAGE_GRUNT_2,
- SFX_CLAUDE_HIGH_DAMAGE_GRUNT_3,
- SFX_CLAUDE_HIGH_DAMAGE_GRUNT_4,
- SFX_CLAUDE_HIGH_DAMAGE_GRUNT_5,
- SFX_CLAUDE_HIGH_DAMAGE_GRUNT_6,
- SFX_CLAUDE_HIGH_DAMAGE_GRUNT_7,
- SFX_CLAUDE_HIGH_DAMAGE_GRUNT_8,
- SFX_CLAUDE_HIGH_DAMAGE_GRUNT_9,
- SFX_CLAUDE_HIGH_DAMAGE_GRUNT_10,
- SFX_CLAUDE_HIGH_DAMAGE_GRUNT_11,
- SFX_CLAUDE_HIT_GROUND_GRUNT_1,
- SFX_CLAUDE_HIT_GROUND_GRUNT_2,
- SFX_CLAUDE_HIT_GROUND_GRUNT_3,
- SFX_CLAUDE_HIT_GROUND_GRUNT_4,
- SFX_CLAUDE_HIT_GROUND_GRUNT_5,
- SFX_CLAUDE_HIT_GROUND_GRUNT_6,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_DRIVER_ABUSE_1,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_DRIVER_ABUSE_2,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_DRIVER_ABUSE_3,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_DRIVER_ABUSE_4,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_DRIVER_ABUSE_5,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_DRIVER_ABUSE_6,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_DRIVER_ABUSE_7,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_CHAT_1,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_CHAT_2,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_CHAT_3,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_CHAT_4,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_CHAT_5,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_CHAT_6,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_CHAT_7,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_CHAT_8,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_CHAT_9,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_CHAT_10,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_DODGE_1,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_DODGE_2,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_DODGE_3,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_DODGE_4,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_DODGE_5,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_DODGE_6,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_DODGE_7,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_DODGE_8,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_DODGE_9,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_DODGE_10,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_CARJACKED_1,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_CARJACKED_2,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_CARJACKED_3,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_CARJACKED_4,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_CARJACKED_5,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_CARJACKED_6,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_MUGGED_1,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_MUGGED_2,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_RUN_FROM_FIGHT_1,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_RUN_FROM_FIGHT_2,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_RUN_FROM_FIGHT_3,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_RUN_FROM_FIGHT_4,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_RUN_FROM_FIGHT_5,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_RUN_FROM_FIGHT_6,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_SHOCKED_1,
- SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_SHOCKED_2,
- SFX_CHUNKY_RUN_1,
- SFX_CHUNKY_RUN_2,
- SFX_CHUNKY_RUN_3,
- SFX_CHUNKY_RUN_4,
- SFX_CHUNKY_RUN_5,
- SFX_PIMP_DRIVER_ABUSE_1,
- SFX_PIMP_DRIVER_ABUSE_2,
- SFX_PIMP_DRIVER_ABUSE_3,
- SFX_PIMP_DRIVER_ABUSE_4,
- SFX_PIMP_DRIVER_ABUSE_5,
- SFX_PIMP_CHAT_1,
- SFX_PIMP_CHAT_2,
- SFX_PIMP_CHAT_3,
- SFX_PIMP_CHAT_4,
- SFX_PIMP_CHAT_5,
- SFX_PIMP_CHAT_6,
- SFX_PIMP_CHAT_7,
- SFX_PIMP_CHAT_8,
- SFX_PIMP_CHAT_9,
- SFX_PIMP_CHAT_10,
- SFX_PIMP_CHAT_11,
- SFX_PIMP_CHAT_12,
- SFX_PIMP_CHAT_13,
- SFX_PIMP_CHAT_14,
- SFX_PIMP_CHAT_15,
- SFX_PIMP_CHAT_16,
- SFX_PIMP_CHAT_17,
- SFX_PIMP_DODGE_1,
- SFX_PIMP_DODGE_2,
- SFX_PIMP_DODGE_3,
- SFX_PIMP_DODGE_4,
- SFX_PIMP_DODGE_5,
- SFX_PIMP_DODGE_6,
- SFX_PIMP_FIGHT_1,
- SFX_PIMP_FIGHT_2,
- SFX_PIMP_FIGHT_3,
- SFX_PIMP_FIGHT_4,
- SFX_PIMP_FIGHT_5,
- SFX_PIMP_FIGHT_6,
- SFX_PIMP_FIGHT_7,
- SFX_PIMP_FIGHT_8,
- SFX_PIMP_FIGHT_9,
- SFX_PIMP_GUN_COOL_1,
- SFX_PIMP_GUN_COOL_2,
- SFX_PIMP_GUN_COOL_3,
- SFX_PIMP_GUN_COOL_4,
- SFX_PIMP_GUN_COOL_5,
- SFX_PIMP_GUN_COOL_6,
- SFX_PIMP_GUN_COOL_7,
- SFX_PIMP_CARJACKED_1,
- SFX_PIMP_CARJACKED_2,
- SFX_PIMP_CARJACKED_3,
- SFX_PIMP_CARJACKED_4,
- SFX_PIMP_SHOCKED_1,
- SFX_PIMP_SHOCKED_2,
- SFX_NORMAL_MALE_DRIVER_ABUSE_1,
- SFX_NORMAL_MALE_DRIVER_ABUSE_2,
- SFX_NORMAL_MALE_DRIVER_ABUSE_3,
- SFX_NORMAL_MALE_DRIVER_ABUSE_4,
- SFX_NORMAL_MALE_DRIVER_ABUSE_5,
- SFX_NORMAL_MALE_DRIVER_ABUSE_6,
- SFX_NORMAL_MALE_DRIVER_ABUSE_7,
- SFX_NORMAL_MALE_DRIVER_ABUSE_8,
- SFX_NORMAL_MALE_DRIVER_ABUSE_9,
- SFX_NORMAL_MALE_DRIVER_ABUSE_10,
- SFX_NORMAL_MALE_DRIVER_ABUSE_11,
- SFX_NORMAL_MALE_DRIVER_ABUSE_12,
- SFX_NORMAL_MALE_CHAT_1,
- SFX_NORMAL_MALE_CHAT_2,
- SFX_NORMAL_MALE_CHAT_3,
- SFX_NORMAL_MALE_CHAT_4,
- SFX_NORMAL_MALE_CHAT_5,
- SFX_NORMAL_MALE_CHAT_6,
- SFX_NORMAL_MALE_CHAT_7,
- SFX_NORMAL_MALE_CHAT_8,
- SFX_NORMAL_MALE_CHAT_9,
- SFX_NORMAL_MALE_CHAT_10,
- SFX_NORMAL_MALE_CHAT_11,
- SFX_NORMAL_MALE_CHAT_12,
- SFX_NORMAL_MALE_CHAT_13,
- SFX_NORMAL_MALE_CHAT_14,
- SFX_NORMAL_MALE_CHAT_15,
- SFX_NORMAL_MALE_CHAT_16,
- SFX_NORMAL_MALE_CHAT_17,
- SFX_NORMAL_MALE_CHAT_18,
- SFX_NORMAL_MALE_CHAT_19,
- SFX_NORMAL_MALE_CHAT_20,
- SFX_NORMAL_MALE_CHAT_21,
- SFX_NORMAL_MALE_CHAT_22,
- SFX_NORMAL_MALE_CHAT_23,
- SFX_NORMAL_MALE_CHAT_24,
- SFX_NORMAL_MALE_CHAT_25,
- SFX_NORMAL_MALE_DODGE_1,
- SFX_NORMAL_MALE_DODGE_2,
- SFX_NORMAL_MALE_DODGE_3,
- SFX_NORMAL_MALE_DODGE_4,
- SFX_NORMAL_MALE_DODGE_5,
- SFX_NORMAL_MALE_DODGE_6,
- SFX_NORMAL_MALE_DODGE_7,
- SFX_NORMAL_MALE_DODGE_8,
- SFX_NORMAL_MALE_DODGE_9,
- SFX_NORMAL_MALE_EYING_1,
- SFX_NORMAL_MALE_EYING_2,
- SFX_NORMAL_MALE_EYING_3,
- SFX_NORMAL_MALE_EYING_4,
- SFX_NORMAL_MALE_EYING_5,
- SFX_NORMAL_MALE_EYING_6,
- SFX_NORMAL_MALE_EYING_7,
- SFX_NORMAL_MALE_EYING_8,
- SFX_NORMAL_MALE_GUN_PANIC_1,
- SFX_NORMAL_MALE_GUN_PANIC_2,
- SFX_NORMAL_MALE_GUN_PANIC_3,
- SFX_NORMAL_MALE_GUN_PANIC_4,
- SFX_NORMAL_MALE_GUN_PANIC_5,
- SFX_NORMAL_MALE_GUN_PANIC_6,
- SFX_NORMAL_MALE_GUN_PANIC_7,
- SFX_NORMAL_MALE_CARJACKED_1,
- SFX_NORMAL_MALE_CARJACKED_2,
- SFX_NORMAL_MALE_CARJACKED_3,
- SFX_NORMAL_MALE_CARJACKED_4,
- SFX_NORMAL_MALE_CARJACKED_5,
- SFX_NORMAL_MALE_CARJACKED_6,
- SFX_NORMAL_MALE_CARJACKED_7,
- SFX_NORMAL_MALE_RUN_FROM_FIGHT_1,
- SFX_NORMAL_MALE_RUN_FROM_FIGHT_2,
- SFX_NORMAL_MALE_RUN_FROM_FIGHT_3,
- SFX_NORMAL_MALE_RUN_FROM_FIGHT_4,
- SFX_NORMAL_MALE_RUN_FROM_FIGHT_5,
- SFX_NORMAL_MALE_SHOCKED_1,
- SFX_NORMAL_MALE_SHOCKED_2,
- SFX_NORMAL_MALE_SHOCKED_3,
- SFX_NORMAL_MALE_SHOCKED_4,
- SFX_NORMAL_MALE_SHOCKED_5,
- SFX_NORMAL_MALE_SHOCKED_6,
- SFX_NORMAL_MALE_SHOCKED_7,
- SFX_NORMAL_MALE_SHOCKED_8,
- SFX_NORMAL_MALE_SHOCKED_9,
- SFX_NORMAL_MALE_SHOCKED_10,
- SFX_BOMBERMAN_1,
- SFX_BOMBERMAN_2,
- SFX_BOMBERMAN_3,
- SFX_BOMBERMAN_4,
- SFX_BOMBERMAN_5,
- SFX_BOMBERMAN_6,
- SFX_BOMBERMAN_7,
- SFX_8BALL_DODGE_1,
- SFX_8BALL_DODGE_2,
- SFX_8BALL_DODGE_3,
- SFX_8BALL_DODGE_4,
- SFX_8BALL_DODGE_5,
- SFX_8BALL_DODGE_6,
- SFX_8BALL_DODGE_7,
- SFX_8BALL_FIGHT_1,
- SFX_8BALL_FIGHT_2,
- SFX_8BALL_FIGHT_3,
- SFX_8BALL_FIGHT_4,
- SFX_8BALL_FIGHT_5,
- SFX_8BALL_FIGHT_6,
- SFX_8BALL_GUN_COOL_1,
- SFX_8BALL_GUN_COOL_2,
- SFX_8BALL_MUGGED_1,
- SFX_8BALL_MUGGED_2,
- SFX_SALVATORE_DODGE_1,
- SFX_SALVATORE_DODGE_2,
- SFX_SALVATORE_DODGE_3,
- SFX_SALVATORE_FIGHT_1,
- SFX_SALVATORE_FIGHT_2,
- SFX_SALVATORE_FIGHT_3,
- SFX_SALVATORE_FIGHT_4,
- SFX_SALVATORE_FIGHT_5,
- SFX_SALVATORE_FIGHT_6,
- SFX_SALVATORE_GUN_COOL_1,
- SFX_SALVATORE_GUN_COOL_2,
- SFX_SALVATORE_GUN_COOL_3,
- SFX_SALVATORE_GUN_COOL_4,
- SFX_SALVATORE_MUGGED_1,
- SFX_SALVATORE_MUGGED_2,
- SFX_MISTY_DODGE_1,
- SFX_MISTY_DODGE_2,
- SFX_MISTY_DODGE_3,
- SFX_MISTY_DODGE_4,
- SFX_MISTY_DODGE_5,
- SFX_MISTY_FIGHT_1,
- SFX_MISTY_FIGHT_2,
- SFX_MISTY_FIGHT_3,
- SFX_MISTY_FIGHT_4,
- SFX_MISTY_GUN_COOL_1,
- SFX_MISTY_GUN_COOL_2,
- SFX_MISTY_GUN_COOL_3,
- SFX_MISTY_GUN_COOL_4,
- SFX_MISTY_GUN_COOL_5,
- SFX_MISTY_HERE_1,
- SFX_MISTY_HERE_2,
- SFX_MISTY_HERE_3,
- SFX_MISTY_HERE_4,
- SFX_MISTY_MUGGED_1,
- SFX_MISTY_MUGGED_2,
- SFX_MEDIC_VOICE_1_GUN_PANIC_1,
- SFX_MEDIC_VOICE_1_GUN_PANIC_2,
- SFX_MEDIC_VOICE_1_GUN_PANIC_3,
- SFX_MEDIC_VOICE_1_GUN_PANIC_4,
- SFX_MEDIC_VOICE_1_GUN_PANIC_5,
- SFX_MEDIC_VOICE_1_CARJACKED_1,
- SFX_MEDIC_VOICE_1_CARJACKED_2,
- SFX_MEDIC_VOICE_1_CARJACKED_3,
- SFX_MEDIC_VOICE_1_CARJACKED_4,
- SFX_MEDIC_VOICE_1_CARJACKED_5,
- SFX_MEDIC_VOICE_1_RUN_FROM_FIGHT_1,
- SFX_MEDIC_VOICE_1_RUN_FROM_FIGHT_2,
- SFX_MEDIC_VOICE_1_RUN_FROM_FIGHT_3,
- SFX_MEDIC_VOICE_1_RUN_FROM_FIGHT_4,
- SFX_MEDIC_VOICE_1_RUN_FROM_FIGHT_5,
- SFX_MEDIC_VOICE_1_RUN_FROM_FIGHT_6,
- SFX_MEDIC_VOICE_1_GET_OUT_VAN_CHAT_1,
- SFX_MEDIC_VOICE_1_GET_OUT_VAN_CHAT_2,
- SFX_MEDIC_VOICE_1_GET_OUT_VAN_CHAT_3,
- SFX_MEDIC_VOICE_1_GET_OUT_VAN_CHAT_4,
- SFX_MEDIC_VOICE_1_GET_OUT_VAN_CHAT_5,
- SFX_MEDIC_VOICE_1_GET_OUT_VAN_CHAT_6,
- SFX_MEDIC_VOICE_1_GET_OUT_VAN_CHAT_7,
- SFX_MEDIC_VOICE_1_GET_OUT_VAN_CHAT_8,
- SFX_MEDIC_VOICE_1_GET_OUT_VAN_CHAT_9,
- SFX_MEDIC_VOICE_1_AT_VICTIM_1,
- SFX_MEDIC_VOICE_1_AT_VICTIM_2,
- SFX_MEDIC_VOICE_1_AT_VICTIM_3,
- SFX_MEDIC_VOICE_1_AT_VICTIM_4,
- SFX_MEDIC_VOICE_1_AT_VICTIM_5,
- SFX_MEDIC_VOICE_1_AT_VICTIM_6,
- SFX_MEDIC_VOICE_1_AT_VICTIM_7,
- SFX_MEDIC_VOICE_1_AT_VICTIM_8,
- SFX_MEDIC_VOICE_1_AT_VICTIM_9,
- SFX_MEDIC_VOICE_1_AT_VICTIM_10,
- SFX_MEDIC_VOICE_1_AT_VICTIM_11,
- SFX_MEDIC_VOICE_1_AT_VICTIM_12,
- SFX_MEDIC_VOICE_2_GUN_PANIC_1,
- SFX_MEDIC_VOICE_2_GUN_PANIC_2,
- SFX_MEDIC_VOICE_2_GUN_PANIC_3,
- SFX_MEDIC_VOICE_2_GUN_PANIC_4,
- SFX_MEDIC_VOICE_2_GUN_PANIC_5,
- SFX_MEDIC_VOICE_2_CARJACKED_1,
- SFX_MEDIC_VOICE_2_CARJACKED_2,
- SFX_MEDIC_VOICE_2_CARJACKED_3,
- SFX_MEDIC_VOICE_2_CARJACKED_4,
- SFX_MEDIC_VOICE_2_CARJACKED_5,
- SFX_MEDIC_VOICE_2_RUN_FROM_FIGHT_1,
- SFX_MEDIC_VOICE_2_RUN_FROM_FIGHT_2,
- SFX_MEDIC_VOICE_2_RUN_FROM_FIGHT_3,
- SFX_MEDIC_VOICE_2_RUN_FROM_FIGHT_4,
- SFX_MEDIC_VOICE_2_RUN_FROM_FIGHT_5,
- SFX_MEDIC_VOICE_2_RUN_FROM_FIGHT_6,
- SFX_MEDIC_VOICE_2_GET_OUT_VAN_CHAT_1,
- SFX_MEDIC_VOICE_2_GET_OUT_VAN_CHAT_2,
- SFX_MEDIC_VOICE_2_GET_OUT_VAN_CHAT_3,
- SFX_MEDIC_VOICE_2_GET_OUT_VAN_CHAT_4,
- SFX_MEDIC_VOICE_2_GET_OUT_VAN_CHAT_5,
- SFX_MEDIC_VOICE_2_GET_OUT_VAN_CHAT_6,
- SFX_MEDIC_VOICE_2_GET_OUT_VAN_CHAT_7,
- SFX_MEDIC_VOICE_2_GET_OUT_VAN_CHAT_8,
- SFX_MEDIC_VOICE_2_GET_OUT_VAN_CHAT_9,
- SFX_MEDIC_VOICE_2_AT_VICTIM_1,
- SFX_MEDIC_VOICE_2_AT_VICTIM_2,
- SFX_MEDIC_VOICE_2_AT_VICTIM_3,
- SFX_MEDIC_VOICE_2_AT_VICTIM_4,
- SFX_MEDIC_VOICE_2_AT_VICTIM_5,
- SFX_MEDIC_VOICE_2_AT_VICTIM_6,
- SFX_MEDIC_VOICE_2_AT_VICTIM_7,
- SFX_MEDIC_VOICE_2_AT_VICTIM_8,
- SFX_MEDIC_VOICE_2_AT_VICTIM_9,
- SFX_MEDIC_VOICE_2_AT_VICTIM_10,
- SFX_MEDIC_VOICE_2_AT_VICTIM_11,
- SFX_MEDIC_VOICE_2_AT_VICTIM_12,
- SFX_PLASTER_BLOKE_1,
- SFX_PLASTER_BLOKE_2,
- SFX_PLASTER_BLOKE_3,
- SFX_PLASTER_BLOKE_4,
- SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_DRIVER_ABUSE_1,
- SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_DRIVER_ABUSE_2,
- SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_DRIVER_ABUSE_3,
- SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_DRIVER_ABUSE_4,
- SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_DRIVER_ABUSE_5,
- SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_CHAT_1,
- SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_CHAT_2,
- SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_CHAT_3,
- SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_CHAT_4,
- SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_DODGE_1,
- SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_DODGE_2,
- SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_DODGE_3,
- SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_DODGE_4,
- SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_DODGE_5,
- SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_EYING_1,
- SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_EYING_2,
- SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_EYING_3,
- SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_EYING_4,
- SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_FIGHT_1,
- SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_FIGHT_2,
- SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_FIGHT_3,
- SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_FIGHT_4,
- SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_FIGHT_5,
- SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_GUN_PANIC_1,
- SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_GUN_PANIC_2,
- SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_GUN_PANIC_3,
- SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_CARJACKED_1,
- SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_CARJACKED_2,
- SFX_FOOTBALL_FEMALE_VOICE_1_DRIVER_ABUSE_1,
- SFX_FOOTBALL_FEMALE_VOICE_1_DRIVER_ABUSE_2,
- SFX_FOOTBALL_FEMALE_VOICE_1_DRIVER_ABUSE_3,
- SFX_FOOTBALL_FEMALE_VOICE_1_DRIVER_ABUSE_4,
- SFX_FOOTBALL_FEMALE_VOICE_1_DRIVER_ABUSE_5,
- SFX_FOOTBALL_FEMALE_VOICE_1_CHAT_1,
- SFX_FOOTBALL_FEMALE_VOICE_1_CHAT_2,
- SFX_FOOTBALL_FEMALE_VOICE_1_CHAT_3,
- SFX_FOOTBALL_FEMALE_VOICE_1_CHAT_4,
- SFX_FOOTBALL_FEMALE_VOICE_1_CHAT_5,
- SFX_FOOTBALL_FEMALE_VOICE_1_CHAT_6,
- SFX_FOOTBALL_FEMALE_VOICE_1_DODGE_1,
- SFX_FOOTBALL_FEMALE_VOICE_1_DODGE_2,
- SFX_FOOTBALL_FEMALE_VOICE_1_DODGE_3,
- SFX_FOOTBALL_FEMALE_VOICE_1_DODGE_4,
- SFX_FOOTBALL_FEMALE_VOICE_1_MUGGED_1,
- SFX_FOOTBALL_FEMALE_VOICE_1_SHOCKED_1,
- SFX_FOOTBALL_FEMALE_VOICE_1_SHOCKED_2,
- SFX_FOOTBALL_FEMALE_VOICE_2_DRIVER_ABUSE_1,
- SFX_FOOTBALL_FEMALE_VOICE_2_DRIVER_ABUSE_2,
- SFX_FOOTBALL_FEMALE_VOICE_2_DRIVER_ABUSE_3,
- SFX_FOOTBALL_FEMALE_VOICE_2_DRIVER_ABUSE_4,
- SFX_FOOTBALL_FEMALE_VOICE_2_DRIVER_ABUSE_5,
- SFX_FOOTBALL_FEMALE_VOICE_2_CHAT_1,
- SFX_FOOTBALL_FEMALE_VOICE_2_CHAT_2,
- SFX_FOOTBALL_FEMALE_VOICE_2_CHAT_3,
- SFX_FOOTBALL_FEMALE_VOICE_2_CHAT_4,
- SFX_FOOTBALL_FEMALE_VOICE_2_CHAT_5,
- SFX_FOOTBALL_FEMALE_VOICE_2_CHAT_6,
- SFX_FOOTBALL_FEMALE_VOICE_2_DODGE_1,
- SFX_FOOTBALL_FEMALE_VOICE_2_DODGE_2,
- SFX_FOOTBALL_FEMALE_VOICE_2_DODGE_3,
- SFX_FOOTBALL_FEMALE_VOICE_2_DODGE_4,
- SFX_FOOTBALL_FEMALE_VOICE_2_MUGGED_1,
- SFX_FOOTBALL_FEMALE_VOICE_2_SHOCKED_1,
- SFX_FOOTBALL_FEMALE_VOICE_2_SHOCKED_2,
- SFX_FOOTBALL_MALE_VOICE_1_DRIVER_ABUSE_1,
- SFX_FOOTBALL_MALE_VOICE_1_DRIVER_ABUSE_2,
- SFX_FOOTBALL_MALE_VOICE_1_DRIVER_ABUSE_3,
- SFX_FOOTBALL_MALE_VOICE_1_DRIVER_ABUSE_4,
- SFX_FOOTBALL_MALE_VOICE_1_DRIVER_ABUSE_5,
- SFX_FOOTBALL_MALE_VOICE_1_CHAT_1,
- SFX_FOOTBALL_MALE_VOICE_1_CHAT_2,
- SFX_FOOTBALL_MALE_VOICE_1_CHAT_3,
- SFX_FOOTBALL_MALE_VOICE_1_CHAT_4,
- SFX_FOOTBALL_MALE_VOICE_1_CHAT_5,
- SFX_FOOTBALL_MALE_VOICE_1_CHAT_6,
- SFX_FOOTBALL_MALE_VOICE_1_DODGE_1,
- SFX_FOOTBALL_MALE_VOICE_1_DODGE_2,
- SFX_FOOTBALL_MALE_VOICE_1_DODGE_3,
- SFX_FOOTBALL_MALE_VOICE_1_DODGE_4,
- SFX_FOOTBALL_MALE_VOICE_1_FIGHT_1,
- SFX_FOOTBALL_MALE_VOICE_1_FIGHT_2,
- SFX_FOOTBALL_MALE_VOICE_1_FIGHT_3,
- SFX_FOOTBALL_MALE_VOICE_1_SHOCKED_1,
- SFX_FOOTBALL_MALE_VOICE_1_SHOCKED_2,
- SFX_FOOTBALL_MALE_VOICE_2_DRIVER_ABUSE_1,
- SFX_FOOTBALL_MALE_VOICE_2_DRIVER_ABUSE_2,
- SFX_FOOTBALL_MALE_VOICE_2_DRIVER_ABUSE_3,
- SFX_FOOTBALL_MALE_VOICE_2_DRIVER_ABUSE_4,
- SFX_FOOTBALL_MALE_VOICE_2_DRIVER_ABUSE_5,
- SFX_FOOTBALL_MALE_VOICE_2_CHAT_1,
- SFX_FOOTBALL_MALE_VOICE_2_CHAT_2,
- SFX_FOOTBALL_MALE_VOICE_2_CHAT_3,
- SFX_FOOTBALL_MALE_VOICE_2_CHAT_4,
- SFX_FOOTBALL_MALE_VOICE_2_CHAT_5,
- SFX_FOOTBALL_MALE_VOICE_2_CHAT_6,
- SFX_FOOTBALL_MALE_VOICE_2_DODGE_1,
- SFX_FOOTBALL_MALE_VOICE_2_DODGE_2,
- SFX_FOOTBALL_MALE_VOICE_2_DODGE_3,
- SFX_FOOTBALL_MALE_VOICE_2_DODGE_4,
- SFX_FOOTBALL_MALE_VOICE_2_FIGHT_1,
- SFX_FOOTBALL_MALE_VOICE_2_FIGHT_2,
- SFX_FOOTBALL_MALE_VOICE_2_FIGHT_3,
- SFX_FOOTBALL_MALE_VOICE_2_SHOCKED_1,
- SFX_FOOTBALL_MALE_VOICE_2_SHOCKED_2,
- SFX_MODEL_FEMALE_VOICE_1_DRIVER_ABUSE_1,
- SFX_MODEL_FEMALE_VOICE_1_DRIVER_ABUSE_2,
- SFX_MODEL_FEMALE_VOICE_1_DRIVER_ABUSE_3,
- SFX_MODEL_FEMALE_VOICE_1_DRIVER_ABUSE_4,
- SFX_MODEL_FEMALE_VOICE_1_DRIVER_ABUSE_5,
- SFX_MODEL_FEMALE_VOICE_1_DRIVER_ABUSE_6,
- SFX_MODEL_FEMALE_VOICE_1_DRIVER_ABUSE_7,
- SFX_MODEL_FEMALE_VOICE_1_CHAT_1,
- SFX_MODEL_FEMALE_VOICE_1_CHAT_2,
- SFX_MODEL_FEMALE_VOICE_1_CHAT_3,
- SFX_MODEL_FEMALE_VOICE_1_CHAT_4,
- SFX_MODEL_FEMALE_VOICE_1_CHAT_5,
- SFX_MODEL_FEMALE_VOICE_1_CHAT_6,
- SFX_MODEL_FEMALE_VOICE_1_CHAT_7,
- SFX_MODEL_FEMALE_VOICE_1_CHAT_8,
- SFX_MODEL_FEMALE_VOICE_1_DODGE_1,
- SFX_MODEL_FEMALE_VOICE_1_DODGE_2,
- SFX_MODEL_FEMALE_VOICE_1_DODGE_3,
- SFX_MODEL_FEMALE_VOICE_1_DODGE_4,
- SFX_MODEL_FEMALE_VOICE_1_GUN_PANIC_1,
- SFX_MODEL_FEMALE_VOICE_1_GUN_PANIC_2,
- SFX_MODEL_FEMALE_VOICE_1_GUN_PANIC_3,
- SFX_MODEL_FEMALE_VOICE_1_GUN_PANIC_4,
- SFX_MODEL_FEMALE_VOICE_1_MUGGED_1,
- SFX_MODEL_FEMALE_VOICE_1_MUGGED_2,
- SFX_MODEL_FEMALE_VOICE_1_MUGGED_3,
- SFX_MODEL_FEMALE_VOICE_1_SHOCKED_1,
- SFX_MODEL_FEMALE_VOICE_1_SHOCKED_2,
- SFX_MODEL_FEMALE_VOICE_1_SHOCKED_3,
- SFX_MODEL_FEMALE_VOICE_1_SHOCKED_4,
- SFX_MODEL_FEMALE_VOICE_1_SHOCKED_5,
- SFX_MODEL_MALE_VOICE_1_DRIVER_ABUSE_1,
- SFX_MODEL_MALE_VOICE_1_DRIVER_ABUSE_2,
- SFX_MODEL_MALE_VOICE_1_DRIVER_ABUSE_3,
- SFX_MODEL_MALE_VOICE_1_DRIVER_ABUSE_4,
- SFX_MODEL_MALE_VOICE_1_DRIVER_ABUSE_5,
- SFX_MODEL_MALE_VOICE_1_DRIVER_ABUSE_6,
- SFX_MODEL_MALE_VOICE_1_CHAT_1,
- SFX_MODEL_MALE_VOICE_1_CHAT_2,
- SFX_MODEL_MALE_VOICE_1_CHAT_3,
- SFX_MODEL_MALE_VOICE_1_CHAT_4,
- SFX_MODEL_MALE_VOICE_1_CHAT_5,
- SFX_MODEL_MALE_VOICE_1_CHAT_6,
- SFX_MODEL_MALE_VOICE_1_DODGE_1,
- SFX_MODEL_MALE_VOICE_1_DODGE_2,
- SFX_MODEL_MALE_VOICE_1_DODGE_3,
- SFX_MODEL_MALE_VOICE_1_DODGE_4,
- SFX_MODEL_MALE_VOICE_1_DODGE_5,
- SFX_MODEL_MALE_VOICE_1_DODGE_6,
- SFX_MODEL_MALE_VOICE_1_EYING_1,
- SFX_MODEL_MALE_VOICE_1_EYING_2,
- SFX_MODEL_MALE_VOICE_1_EYING_3,
- SFX_MODEL_MALE_VOICE_1_FIGHT_1,
- SFX_MODEL_MALE_VOICE_1_FIGHT_2,
- SFX_MODEL_MALE_VOICE_1_FIGHT_3,
- SFX_MODEL_MALE_VOICE_1_FIGHT_4,
- SFX_MODEL_MALE_VOICE_1_FIGHT_5,
- SFX_MODEL_MALE_VOICE_1_CARJACKED_1,
- SFX_MODEL_MALE_VOICE_1_CARJACKED_2,
- SFX_MODEL_MALE_VOICE_1_MUGGED_1,
- SFX_MODEL_MALE_VOICE_1_MUGGED_2,
- SFX_CHINATOWN_MALE_YOUNG_VOICE_1_DRIVER_ABUSE_1,
- SFX_CHINATOWN_MALE_YOUNG_VOICE_1_DRIVER_ABUSE_2,
- SFX_CHINATOWN_MALE_YOUNG_VOICE_1_DRIVER_ABUSE_3,
- SFX_CHINATOWN_MALE_YOUNG_VOICE_1_DRIVER_ABUSE_4,
- SFX_CHINATOWN_MALE_YOUNG_VOICE_1_DRIVER_ABUSE_5,
- SFX_CHINATOWN_MALE_YOUNG_VOICE_1_DRIVER_ABUSE_6,
- SFX_CHINATOWN_MALE_YOUNG_VOICE_1_CHAT_1,
- SFX_CHINATOWN_MALE_YOUNG_VOICE_1_CHAT_2,
- SFX_CHINATOWN_MALE_YOUNG_VOICE_1_CHAT_3,
- SFX_CHINATOWN_MALE_YOUNG_VOICE_1_CHAT_4,
- SFX_CHINATOWN_MALE_YOUNG_VOICE_1_CHAT_5,
- SFX_CHINATOWN_MALE_YOUNG_VOICE_1_CHAT_6,
- SFX_CHINATOWN_MALE_YOUNG_VOICE_1_DODGE_1,
- SFX_CHINATOWN_MALE_YOUNG_VOICE_1_DODGE_2,
- SFX_CHINATOWN_MALE_YOUNG_VOICE_1_DODGE_3,
- SFX_CHINATOWN_MALE_YOUNG_VOICE_1_DODGE_4,
- SFX_CHINATOWN_MALE_YOUNG_VOICE_1_DODGE_5,
- SFX_CHINATOWN_MALE_YOUNG_VOICE_1_EYING_1,
- SFX_CHINATOWN_MALE_YOUNG_VOICE_1_EYING_2,
- SFX_CHINATOWN_MALE_YOUNG_VOICE_1_EYING_3,
- SFX_CHINATOWN_MALE_YOUNG_VOICE_1_FIGHT_1,
- SFX_CHINATOWN_MALE_YOUNG_VOICE_1_FIGHT_2,
- SFX_CHINATOWN_MALE_YOUNG_VOICE_1_FIGHT_3,
- SFX_CHINATOWN_MALE_YOUNG_VOICE_1_FIGHT_4,
- SFX_CHINATOWN_MALE_YOUNG_VOICE_1_FIGHT_5,
- SFX_CHINATOWN_MALE_YOUNG_VOICE_1_FIGHT_6,
- SFX_CHINATOWN_MALE_YOUNG_VOICE_1_GUN_PANIC_1,
- SFX_CHINATOWN_MALE_YOUNG_VOICE_1_GUN_PANIC_2,
- SFX_CHINATOWN_MALE_YOUNG_VOICE_1_CARJACKED_1,
- SFX_CHINATOWN_MALE_YOUNG_VOICE_1_CARJACKED_2,
- SFX_SCUM_MALE_VOICE_1_DRIVER_ABUSE_1,
- SFX_SCUM_MALE_VOICE_1_DRIVER_ABUSE_2,
- SFX_SCUM_MALE_VOICE_1_DRIVER_ABUSE_3,
- SFX_SCUM_MALE_VOICE_1_DRIVER_ABUSE_4,
- SFX_SCUM_MALE_VOICE_1_DRIVER_ABUSE_5,
- SFX_SCUM_MALE_VOICE_1_DRIVER_ABUSE_6,
- SFX_SCUM_MALE_VOICE_1_CHAT_1,
- SFX_SCUM_MALE_VOICE_1_CHAT_2,
- SFX_SCUM_MALE_VOICE_1_CHAT_3,
- SFX_SCUM_MALE_VOICE_1_CHAT_4,
- SFX_SCUM_MALE_VOICE_1_CHAT_5,
- SFX_SCUM_MALE_VOICE_1_CHAT_6,
- SFX_SCUM_MALE_VOICE_1_CHAT_7,
- SFX_SCUM_MALE_VOICE_1_CHAT_8,
- SFX_SCUM_MALE_VOICE_1_CHAT_9,
- SFX_SCUM_MALE_VOICE_1_DODGE_1,
- SFX_SCUM_MALE_VOICE_1_DODGE_2,
- SFX_SCUM_MALE_VOICE_1_DODGE_3,
- SFX_SCUM_MALE_VOICE_1_DODGE_4,
- SFX_SCUM_MALE_VOICE_1_DODGE_5,
- SFX_SCUM_MALE_VOICE_1_EYING_1,
- SFX_SCUM_MALE_VOICE_1_EYING_2,
- SFX_SCUM_MALE_VOICE_1_EYING_3,
- SFX_SCUM_MALE_VOICE_1_EYING_4,
- SFX_SCUM_MALE_VOICE_1_EYING_5,
- SFX_SCUM_MALE_VOICE_1_FIGHT_1,
- SFX_SCUM_MALE_VOICE_1_FIGHT_2,
- SFX_SCUM_MALE_VOICE_1_FIGHT_3,
- SFX_SCUM_MALE_VOICE_1_FIGHT_4,
- SFX_SCUM_MALE_VOICE_1_FIGHT_5,
- SFX_SCUM_MALE_VOICE_1_FIGHT_6,
- SFX_SCUM_MALE_VOICE_1_FIGHT_7,
- SFX_SCUM_MALE_VOICE_1_FIGHT_8,
- SFX_SCUM_MALE_VOICE_1_FIGHT_9,
- SFX_SCUM_MALE_VOICE_1_FIGHT_10,
- SFX_SCUM_MALE_VOICE_1_GUN_PANIC_1,
- SFX_SCUM_MALE_VOICE_1_GUN_PANIC_2,
- SFX_SCUM_MALE_VOICE_1_GUN_PANIC_3,
- SFX_SCUM_MALE_VOICE_1_GUN_PANIC_4,
- SFX_SCUM_MALE_VOICE_1_GUN_PANIC_5,
- SFX_SCUM_MALE_VOICE_1_LOST_1,
- SFX_SCUM_MALE_VOICE_1_LOST_2,
- SFX_SCUM_MALE_VOICE_1_LOST_3,
- SFX_SCUM_MALE_VOICE_1_MUGGED_1,
- SFX_SCUM_FEMALE_VOICE_1_DRIVER_ABUSE_1,
- SFX_SCUM_FEMALE_VOICE_1_DRIVER_ABUSE_2,
- SFX_SCUM_FEMALE_VOICE_1_DRIVER_ABUSE_3,
- SFX_SCUM_FEMALE_VOICE_1_DRIVER_ABUSE_4,
- SFX_SCUM_FEMALE_VOICE_1_DRIVER_ABUSE_5,
- SFX_SCUM_FEMALE_VOICE_1_CHAT_1,
- SFX_SCUM_FEMALE_VOICE_1_CHAT_2,
- SFX_SCUM_FEMALE_VOICE_1_CHAT_3,
- SFX_SCUM_FEMALE_VOICE_1_CHAT_4,
- SFX_SCUM_FEMALE_VOICE_1_CHAT_5,
- SFX_SCUM_FEMALE_VOICE_1_CHAT_6,
- SFX_SCUM_FEMALE_VOICE_1_CHAT_7,
- SFX_SCUM_FEMALE_VOICE_1_CHAT_8,
- SFX_SCUM_FEMALE_VOICE_1_CHAT_9,
- SFX_SCUM_FEMALE_VOICE_1_CHAT_10,
- SFX_SCUM_FEMALE_VOICE_1_CHAT_11,
- SFX_SCUM_FEMALE_VOICE_1_CHAT_12,
- SFX_SCUM_FEMALE_VOICE_1_CHAT_13,
- SFX_SCUM_FEMALE_VOICE_1_DODGE_1,
- SFX_SCUM_FEMALE_VOICE_1_DODGE_2,
- SFX_SCUM_FEMALE_VOICE_1_DODGE_3,
- SFX_SCUM_FEMALE_VOICE_1_DODGE_4,
- SFX_SCUM_FEMALE_VOICE_1_DODGE_5,
- SFX_SCUM_FEMALE_VOICE_1_DODGE_6,
- SFX_SCUM_FEMALE_VOICE_1_DODGE_7,
- SFX_SCUM_FEMALE_VOICE_1_DODGE_8,
- SFX_SCUM_FEMALE_VOICE_1_FIGHT_1,
- SFX_SCUM_FEMALE_VOICE_1_FIGHT_2,
- SFX_SCUM_FEMALE_VOICE_1_FIGHT_3,
- SFX_SCUM_FEMALE_VOICE_1_FIGHT_4,
- SFX_SCUM_FEMALE_VOICE_1_GUN_PANIC_1,
- SFX_SCUM_FEMALE_VOICE_1_GUN_PANIC_2,
- SFX_SCUM_FEMALE_VOICE_1_GUN_PANIC_3,
- SFX_SCUM_FEMALE_VOICE_1_GUN_PANIC_4,
- SFX_SCUM_FEMALE_VOICE_1_MUGGED_1,
- SFX_SCUM_FEMALE_VOICE_1_MUGGED_2,
- SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_DRIVER_ABUSE_1,
- SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_DRIVER_ABUSE_2,
- SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_DRIVER_ABUSE_3,
- SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_DRIVER_ABUSE_4,
- SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_DRIVER_ABUSE_5,
- SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_DRIVER_ABUSE_6,
- SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_CHAT_1,
- SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_CHAT_2,
- SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_CHAT_3,
- SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_CHAT_4,
- SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_CHAT_5,
- SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_CHAT_6,
- SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_CHAT_7,
- SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_DODGE_1,
- SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_DODGE_2,
- SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_DODGE_3,
- SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_DODGE_4,
- SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_DODGE_5,
- SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_GUN_PANIC_1,
- SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_GUN_PANIC_2,
- SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_GUN_PANIC_3,
- SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_GUN_PANIC_4,
- SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_CARJACKED_1,
- SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_MUGGED_1,
- SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_MUGGED_2,
- SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_SHOCKED_1,
- SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_SHOCKED_2,
- SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_SHOCKED_3,
- SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_SHOCKED_4,
- SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_SHOCKED_5,
- SFX_BUSINESS_MALE_YOUNG_VOICE_1_DRIVER_ABUSE_1,
- SFX_BUSINESS_MALE_YOUNG_VOICE_1_DRIVER_ABUSE_2,
- SFX_BUSINESS_MALE_YOUNG_VOICE_1_DRIVER_ABUSE_3,
- SFX_BUSINESS_MALE_YOUNG_VOICE_1_DRIVER_ABUSE_4,
- SFX_BUSINESS_MALE_YOUNG_VOICE_1_DRIVER_ABUSE_5,
- SFX_BUSINESS_MALE_YOUNG_VOICE_1_DRIVER_ABUSE_6,
- SFX_BUSINESS_MALE_YOUNG_VOICE_1_CHAT_1,
- SFX_BUSINESS_MALE_YOUNG_VOICE_1_CHAT_2,
- SFX_BUSINESS_MALE_YOUNG_VOICE_1_CHAT_3,
- SFX_BUSINESS_MALE_YOUNG_VOICE_1_CHAT_4,
- SFX_BUSINESS_MALE_YOUNG_VOICE_1_CHAT_5,
- SFX_BUSINESS_MALE_YOUNG_VOICE_1_CHAT_6,
- SFX_BUSINESS_MALE_YOUNG_VOICE_1_DODGE_1,
- SFX_BUSINESS_MALE_YOUNG_VOICE_1_DODGE_2,
- SFX_BUSINESS_MALE_YOUNG_VOICE_1_DODGE_3,
- SFX_BUSINESS_MALE_YOUNG_VOICE_1_DODGE_4,
- SFX_BUSINESS_MALE_YOUNG_VOICE_1_FIGHT_1,
- SFX_BUSINESS_MALE_YOUNG_VOICE_1_FIGHT_2,
- SFX_BUSINESS_MALE_YOUNG_VOICE_1_FIGHT_3,
- SFX_BUSINESS_MALE_YOUNG_VOICE_1_FIGHT_4,
- SFX_BUSINESS_MALE_YOUNG_VOICE_1_GUN_PANIC_1,
- SFX_BUSINESS_MALE_YOUNG_VOICE_1_GUN_PANIC_2,
- SFX_BUSINESS_MALE_YOUNG_VOICE_1_GUN_PANIC_3,
- SFX_BUSINESS_MALE_YOUNG_VOICE_1_CARJACKED_1,
- SFX_BUSINESS_MALE_YOUNG_VOICE_1_CARJACKED_2,
- SFX_BUSINESS_MALE_YOUNG_VOICE_1_MUGGED_1,
- SFX_BUSINESS_MALE_YOUNG_VOICE_1_MUGGED_2,
- SFX_BUSINESS_MALE_YOUNG_VOICE_1_RUN_FROM_FIGHT_1,
- SFX_BUSINESS_MALE_YOUNG_VOICE_1_RUN_FROM_FIGHT_2,
- SFX_BUSINESS_MALE_YOUNG_VOICE_1_RUN_FROM_FIGHT_3,
- SFX_BUSINESS_MALE_YOUNG_VOICE_1_RUN_FROM_FIGHT_4,
- SFX_BUSINESS_MALE_YOUNG_VOICE_1_RUN_FROM_FIGHT_5,
- SFX_BUSINESS_MALE_YOUNG_VOICE_2_DRIVER_ABUSE_1,
- SFX_BUSINESS_MALE_YOUNG_VOICE_2_DRIVER_ABUSE_2,
- SFX_BUSINESS_MALE_YOUNG_VOICE_2_DRIVER_ABUSE_3,
- SFX_BUSINESS_MALE_YOUNG_VOICE_2_DRIVER_ABUSE_4,
- SFX_BUSINESS_MALE_YOUNG_VOICE_2_DRIVER_ABUSE_5,
- SFX_BUSINESS_MALE_YOUNG_VOICE_2_DRIVER_ABUSE_6,
- SFX_BUSINESS_MALE_YOUNG_VOICE_2_CHAT_1,
- SFX_BUSINESS_MALE_YOUNG_VOICE_2_CHAT_2,
- SFX_BUSINESS_MALE_YOUNG_VOICE_2_CHAT_3,
- SFX_BUSINESS_MALE_YOUNG_VOICE_2_CHAT_4,
- SFX_BUSINESS_MALE_YOUNG_VOICE_2_CHAT_5,
- SFX_BUSINESS_MALE_YOUNG_VOICE_2_CHAT_6,
- SFX_BUSINESS_MALE_YOUNG_VOICE_2_DODGE_1,
- SFX_BUSINESS_MALE_YOUNG_VOICE_2_DODGE_2,
- SFX_BUSINESS_MALE_YOUNG_VOICE_2_DODGE_3,
- SFX_BUSINESS_MALE_YOUNG_VOICE_2_DODGE_4,
- SFX_BUSINESS_MALE_YOUNG_VOICE_2_FIGHT_1,
- SFX_BUSINESS_MALE_YOUNG_VOICE_2_FIGHT_2,
- SFX_BUSINESS_MALE_YOUNG_VOICE_2_FIGHT_3,
- SFX_BUSINESS_MALE_YOUNG_VOICE_2_FIGHT_4,
- SFX_BUSINESS_MALE_YOUNG_VOICE_2_GUN_PANIC_1,
- SFX_BUSINESS_MALE_YOUNG_VOICE_2_GUN_PANIC_2,
- SFX_BUSINESS_MALE_YOUNG_VOICE_2_GUN_PANIC_3,
- SFX_BUSINESS_MALE_YOUNG_VOICE_2_CARJACKED_1,
- SFX_BUSINESS_MALE_YOUNG_VOICE_2_CARJACKED_2,
- SFX_BUSINESS_MALE_YOUNG_VOICE_2_MUGGED_1,
- SFX_BUSINESS_MALE_YOUNG_VOICE_2_MUGGED_2,
- SFX_BUSINESS_MALE_YOUNG_VOICE_2_RUN_FROM_FIGHT_1,
- SFX_BUSINESS_MALE_YOUNG_VOICE_2_RUN_FROM_FIGHT_2,
- SFX_BUSINESS_MALE_YOUNG_VOICE_2_RUN_FROM_FIGHT_3,
- SFX_BUSINESS_MALE_YOUNG_VOICE_2_RUN_FROM_FIGHT_4,
- SFX_BUSINESS_MALE_YOUNG_VOICE_2_RUN_FROM_FIGHT_5,
- SFX_BLACK_FAT_FEMALE_VOICE_1_DRIVER_ABUSE_1,
- SFX_BLACK_FAT_FEMALE_VOICE_1_DRIVER_ABUSE_2,
- SFX_BLACK_FAT_FEMALE_VOICE_1_DRIVER_ABUSE_3,
- SFX_BLACK_FAT_FEMALE_VOICE_1_DRIVER_ABUSE_4,
- SFX_BLACK_FAT_FEMALE_VOICE_1_DRIVER_ABUSE_5,
- SFX_BLACK_FAT_FEMALE_VOICE_1_DRIVER_ABUSE_6,
- SFX_BLACK_FAT_FEMALE_VOICE_1_CHAT_1,
- SFX_BLACK_FAT_FEMALE_VOICE_1_CHAT_2,
- SFX_BLACK_FAT_FEMALE_VOICE_1_CHAT_3,
- SFX_BLACK_FAT_FEMALE_VOICE_1_CHAT_4,
- SFX_BLACK_FAT_FEMALE_VOICE_1_CHAT_5,
- SFX_BLACK_FAT_FEMALE_VOICE_1_CHAT_6,
- SFX_BLACK_FAT_FEMALE_VOICE_1_CHAT_7,
- SFX_BLACK_FAT_FEMALE_VOICE_1_DODGE_1,
- SFX_BLACK_FAT_FEMALE_VOICE_1_DODGE_2,
- SFX_BLACK_FAT_FEMALE_VOICE_1_DODGE_3,
- SFX_BLACK_FAT_FEMALE_VOICE_1_DODGE_4,
- SFX_BLACK_FAT_FEMALE_VOICE_1_DODGE_5,
- SFX_BLACK_FAT_FEMALE_VOICE_1_GUN_PANIC_1,
- SFX_BLACK_FAT_FEMALE_VOICE_1_GUN_PANIC_2,
- SFX_BLACK_FAT_FEMALE_VOICE_1_GUN_PANIC_3,
- SFX_BLACK_FAT_FEMALE_VOICE_1_GUN_PANIC_4,
- SFX_BLACK_FAT_FEMALE_VOICE_1_CARJACKED_1,
- SFX_BLACK_FAT_FEMALE_VOICE_1_CARJACKED_2,
- SFX_BLACK_FAT_FEMALE_VOICE_1_MUGGED_1,
- SFX_BLACK_FAT_FEMALE_VOICE_1_MUGGED_2,
- SFX_BLACK_FAT_FEMALE_VOICE_1_SHOCKED_1,
- SFX_BLACK_FAT_FEMALE_VOICE_1_SHOCKED_2,
- SFX_BLACK_FAT_FEMALE_VOICE_1_SHOCKED_3,
- SFX_BLACK_FAT_FEMALE_VOICE_1_SHOCKED_4,
- SFX_BLACK_FAT_FEMALE_VOICE_1_SHOCKED_5,
- SFX_WHITE_DOCKER_MALE_VOICE_1_DRIVER_ABUSE_1,
- SFX_WHITE_DOCKER_MALE_VOICE_1_DRIVER_ABUSE_2,
- SFX_WHITE_DOCKER_MALE_VOICE_1_DRIVER_ABUSE_3,
- SFX_WHITE_DOCKER_MALE_VOICE_1_DRIVER_ABUSE_4,
- SFX_WHITE_DOCKER_MALE_VOICE_1_CHAT_1,
- SFX_WHITE_DOCKER_MALE_VOICE_1_CHAT_2,
- SFX_WHITE_DOCKER_MALE_VOICE_1_CHAT_3,
- SFX_WHITE_DOCKER_MALE_VOICE_1_CHAT_4,
- SFX_WHITE_DOCKER_MALE_VOICE_1_CHAT_5,
- SFX_WHITE_DOCKER_MALE_VOICE_1_DODGE_1,
- SFX_WHITE_DOCKER_MALE_VOICE_1_DODGE_2,
- SFX_WHITE_DOCKER_MALE_VOICE_1_DODGE_3,
- SFX_WHITE_DOCKER_MALE_VOICE_1_DODGE_4,
- SFX_WHITE_DOCKER_MALE_VOICE_1_EYING_1,
- SFX_WHITE_DOCKER_MALE_VOICE_1_EYING_2,
- SFX_WHITE_DOCKER_MALE_VOICE_1_EYING_3,
- SFX_WHITE_DOCKER_MALE_VOICE_1_FIGHT_1,
- SFX_WHITE_DOCKER_MALE_VOICE_1_FIGHT_2,
- SFX_WHITE_DOCKER_MALE_VOICE_1_FIGHT_3,
- SFX_WHITE_DOCKER_MALE_VOICE_1_GUN_PANIC_1,
- SFX_WHITE_DOCKER_MALE_VOICE_1_GUN_PANIC_2,
- SFX_HOSPITAL_MALE_VOICE_1_DRIVER_ABUSE_1,
- SFX_HOSPITAL_MALE_VOICE_1_DRIVER_ABUSE_2,
- SFX_HOSPITAL_MALE_VOICE_1_DRIVER_ABUSE_3,
- SFX_HOSPITAL_MALE_VOICE_1_DRIVER_ABUSE_4,
- SFX_HOSPITAL_MALE_VOICE_1_DRIVER_ABUSE_5,
- SFX_HOSPITAL_MALE_VOICE_1_CHAT_1,
- SFX_HOSPITAL_MALE_VOICE_1_CHAT_2,
- SFX_HOSPITAL_MALE_VOICE_1_CHAT_3,
- SFX_HOSPITAL_MALE_VOICE_1_CHAT_4,
- SFX_HOSPITAL_MALE_VOICE_1_CHAT_5,
- SFX_HOSPITAL_MALE_VOICE_1_DODGE_1,
- SFX_HOSPITAL_MALE_VOICE_1_DODGE_2,
- SFX_HOSPITAL_MALE_VOICE_1_DODGE_3,
- SFX_HOSPITAL_MALE_VOICE_1_DODGE_4,
- SFX_HOSPITAL_MALE_VOICE_1_FIGHT_1,
- SFX_HOSPITAL_MALE_VOICE_1_FIGHT_2,
- SFX_HOSPITAL_MALE_VOICE_1_FIGHT_3,
- SFX_HOSPITAL_MALE_VOICE_1_FIGHT_4,
- SFX_HOSPITAL_MALE_VOICE_1_GUN_PANIC_1,
- SFX_HOSPITAL_MALE_VOICE_1_GUN_PANIC_2,
- SFX_HOSPITAL_MALE_VOICE_1_GUN_PANIC_3,
- SFX_HOSPITAL_MALE_VOICE_1_GUN_PANIC_4,
- SFX_HOSPITAL_FEMALE_VOICE_1_DRIVER_ABUSE_1,
- SFX_HOSPITAL_FEMALE_VOICE_1_DRIVER_ABUSE_2,
- SFX_HOSPITAL_FEMALE_VOICE_1_DRIVER_ABUSE_3,
- SFX_HOSPITAL_FEMALE_VOICE_1_DRIVER_ABUSE_4,
- SFX_HOSPITAL_FEMALE_VOICE_1_DRIVER_ABUSE_5,
- SFX_HOSPITAL_FEMALE_VOICE_1_DRIVER_ABUSE_6,
- SFX_HOSPITAL_FEMALE_VOICE_1_CHAT_1,
- SFX_HOSPITAL_FEMALE_VOICE_1_CHAT_2,
- SFX_HOSPITAL_FEMALE_VOICE_1_CHAT_3,
- SFX_HOSPITAL_FEMALE_VOICE_1_CHAT_4,
- SFX_HOSPITAL_FEMALE_VOICE_1_CHAT_5,
- SFX_HOSPITAL_FEMALE_VOICE_1_CHAT_6,
- SFX_HOSPITAL_FEMALE_VOICE_1_DODGE_1,
- SFX_HOSPITAL_FEMALE_VOICE_1_DODGE_2,
- SFX_HOSPITAL_FEMALE_VOICE_1_DODGE_3,
- SFX_HOSPITAL_FEMALE_VOICE_1_DODGE_4,
- SFX_HOSPITAL_FEMALE_VOICE_1_DODGE_5,
- SFX_FEMALE_1_VOICE_1_DRIVER_ABUSE_1,
- SFX_FEMALE_1_VOICE_1_DRIVER_ABUSE_2,
- SFX_FEMALE_1_VOICE_1_DRIVER_ABUSE_3,
- SFX_FEMALE_1_VOICE_1_DRIVER_ABUSE_4,
- SFX_FEMALE_1_VOICE_1_DRIVER_ABUSE_5,
- SFX_FEMALE_1_VOICE_1_DRIVER_ABUSE_6,
- SFX_FEMALE_1_VOICE_1_DRIVER_ABUSE_7,
- SFX_FEMALE_1_VOICE_1_CHAT_1,
- SFX_FEMALE_1_VOICE_1_CHAT_2,
- SFX_FEMALE_1_VOICE_1_CHAT_3,
- SFX_FEMALE_1_VOICE_1_CHAT_4,
- SFX_FEMALE_1_VOICE_1_CHAT_5,
- SFX_FEMALE_1_VOICE_1_CHAT_6,
- SFX_FEMALE_1_VOICE_1_CHAT_7,
- SFX_FEMALE_1_VOICE_1_CHAT_8,
- SFX_FEMALE_1_VOICE_1_DODGE_1,
- SFX_FEMALE_1_VOICE_1_DODGE_2,
- SFX_FEMALE_1_VOICE_1_DODGE_3,
- SFX_FEMALE_1_VOICE_1_DODGE_4,
- SFX_FEMALE_1_VOICE_1_DODGE_5,
- SFX_FEMALE_1_VOICE_1_DODGE_6,
- SFX_FEMALE_1_VOICE_1_GUN_PANIC_1,
- SFX_FEMALE_1_VOICE_1_GUN_PANIC_2,
- SFX_FEMALE_1_VOICE_1_CARJACKED_1,
- SFX_FEMALE_1_VOICE_1_CARJACKED_2,
- SFX_FEMALE_1_VOICE_1_MUGGED_1,
- SFX_FEMALE_1_VOICE_1_MUGGED_2,
- SFX_FEMALE_1_VOICE_1_MUGGED_3,
- SFX_FEMALE_1_VOICE_1_RUN_FROM_FIGHT_1,
- SFX_FEMALE_1_VOICE_1_RUN_FROM_FIGHT_2,
- SFX_FEMALE_1_VOICE_1_SHOCKED_1,
- SFX_FEMALE_1_VOICE_1_SHOCKED_2,
- SFX_FEMALE_1_VOICE_1_SHOCKED_3,
- SFX_FEMALE_1_VOICE_1_SHOCKED_4,
- SFX_FEMALE_3_VOICE_1_DRIVER_ABUSE_1,
- SFX_FEMALE_3_VOICE_1_DRIVER_ABUSE_2,
- SFX_FEMALE_3_VOICE_1_DRIVER_ABUSE_3,
- SFX_FEMALE_3_VOICE_1_DRIVER_ABUSE_4,
- SFX_FEMALE_3_VOICE_1_DRIVER_ABUSE_5,
- SFX_FEMALE_3_VOICE_1_DRIVER_ABUSE_6,
- SFX_FEMALE_3_VOICE_1_CHAT_1,
- SFX_FEMALE_3_VOICE_1_CHAT_2,
- SFX_FEMALE_3_VOICE_1_CHAT_3,
- SFX_FEMALE_3_VOICE_1_CHAT_4,
- SFX_FEMALE_3_VOICE_1_CHAT_5,
- SFX_FEMALE_3_VOICE_1_DODGE_1,
- SFX_FEMALE_3_VOICE_1_DODGE_2,
- SFX_FEMALE_3_VOICE_1_DODGE_3,
- SFX_FEMALE_3_VOICE_1_DODGE_4,
- SFX_FEMALE_3_VOICE_1_DODGE_5,
- SFX_FEMALE_3_VOICE_1_DODGE_6,
- SFX_FEMALE_3_VOICE_1_GUN_PANIC_1,
- SFX_FEMALE_3_VOICE_1_GUN_PANIC_2,
- SFX_FEMALE_3_VOICE_1_GUN_PANIC_3,
- SFX_FEMALE_3_VOICE_1_GUN_PANIC_4,
- SFX_FEMALE_3_VOICE_1_GUN_PANIC_5,
- SFX_FEMALE_3_VOICE_1_CARJACKED_1,
- SFX_FEMALE_3_VOICE_1_CARJACKED_2,
- SFX_FEMALE_3_VOICE_1_CARJACKED_3,
- SFX_FEMALE_3_VOICE_1_MUGGED_1,
- SFX_FEMALE_3_VOICE_1_MUGGED_2,
- SFX_FEMALE_3_VOICE_1_MUGGED_3,
- SFX_FEMALE_3_VOICE_1_RUN_FROM_FIGHT_1,
- SFX_FEMALE_3_VOICE_1_RUN_FROM_FIGHT_2,
- SFX_FEMALE_3_VOICE_1_RUN_FROM_FIGHT_3,
- SFX_FEMALE_3_VOICE_1_RUN_FROM_FIGHT_4,
- SFX_FEMALE_3_VOICE_1_SHOCKED_1,
- SFX_FEMALE_3_VOICE_1_SHOCKED_2,
- SFX_FEMALE_3_VOICE_1_SHOCKED_3,
- SFX_FEMALE_3_VOICE_1_SHOCKED_4,
- SFX_CASUAL_MALE_OLD_VOICE_1_DRIVER_ABUSE_1,
- SFX_CASUAL_MALE_OLD_VOICE_1_DRIVER_ABUSE_2,
- SFX_CASUAL_MALE_OLD_VOICE_1_DRIVER_ABUSE_3,
- SFX_CASUAL_MALE_OLD_VOICE_1_DRIVER_ABUSE_4,
- SFX_CASUAL_MALE_OLD_VOICE_1_DRIVER_ABUSE_5,
- SFX_CASUAL_MALE_OLD_VOICE_1_DRIVER_ABUSE_6,
- SFX_CASUAL_MALE_OLD_VOICE_1_DRIVER_ABUSE_7,
- SFX_CASUAL_MALE_OLD_VOICE_1_CHAT_1,
- SFX_CASUAL_MALE_OLD_VOICE_1_CHAT_2,
- SFX_CASUAL_MALE_OLD_VOICE_1_CHAT_3,
- SFX_CASUAL_MALE_OLD_VOICE_1_CHAT_4,
- SFX_CASUAL_MALE_OLD_VOICE_1_CHAT_5,
- SFX_CASUAL_MALE_OLD_VOICE_1_CHAT_6,
- SFX_CASUAL_MALE_OLD_VOICE_1_CHAT_7,
- SFX_CASUAL_MALE_OLD_VOICE_1_DODGE_1,
- SFX_CASUAL_MALE_OLD_VOICE_1_DODGE_2,
- SFX_CASUAL_MALE_OLD_VOICE_1_DODGE_3,
- SFX_CASUAL_MALE_OLD_VOICE_1_DODGE_4,
- SFX_CASUAL_MALE_OLD_VOICE_1_EYING_1,
- SFX_CASUAL_MALE_OLD_VOICE_1_EYING_2,
- SFX_CASUAL_MALE_OLD_VOICE_1_EYING_3,
- SFX_CASUAL_MALE_OLD_VOICE_1_EYING_4,
- SFX_CASUAL_MALE_OLD_VOICE_1_EYING_5,
- SFX_CASUAL_MALE_OLD_VOICE_1_FIGHT_1,
- SFX_CASUAL_MALE_OLD_VOICE_1_FIGHT_2,
- SFX_CASUAL_MALE_OLD_VOICE_1_FIGHT_3,
- SFX_CASUAL_MALE_OLD_VOICE_1_FIGHT_4,
- SFX_CASUAL_MALE_OLD_VOICE_1_CARJACKED_1,
- SFX_CASUAL_MALE_OLD_VOICE_1_CARJACKED_2,
- SFX_CASUAL_MALE_OLD_VOICE_1_CARJACKED_3,
- SFX_CASUAL_MALE_OLD_VOICE_1_MUGGED_1,
- SFX_CASUAL_MALE_OLD_VOICE_1_MUGGED_2,
- SFX_CASUAL_MALE_OLD_VOICE_1_MUGGED_3,
- SFX_CASUAL_MALE_OLD_VOICE_1_MUGGED_4,
- SFX_STUDENT_MALE_VOICE_1_DRIVER_ABUSE_1,
- SFX_STUDENT_MALE_VOICE_1_DRIVER_ABUSE_2,
- SFX_STUDENT_MALE_VOICE_1_DRIVER_ABUSE_3,
- SFX_STUDENT_MALE_VOICE_1_DRIVER_ABUSE_4,
- SFX_STUDENT_MALE_VOICE_1_CHAT_1,
- SFX_STUDENT_MALE_VOICE_1_CHAT_2,
- SFX_STUDENT_MALE_VOICE_1_CHAT_3,
- SFX_STUDENT_MALE_VOICE_1_CHAT_4,
- SFX_STUDENT_MALE_VOICE_1_CHAT_5,
- SFX_STUDENT_MALE_VOICE_1_DODGE_1,
- SFX_STUDENT_MALE_VOICE_1_DODGE_2,
- SFX_STUDENT_MALE_VOICE_1_DODGE_3,
- SFX_STUDENT_MALE_VOICE_1_DODGE_4,
- SFX_STUDENT_MALE_VOICE_1_FIGHT_1,
- SFX_STUDENT_MALE_VOICE_1_FIGHT_2,
- SFX_STUDENT_MALE_VOICE_1_FIGHT_3,
- SFX_STUDENT_MALE_VOICE_1_FIGHT_4,
- SFX_STUDENT_MALE_VOICE_1_GUN_PANIC_1,
- SFX_STUDENT_MALE_VOICE_1_GUN_PANIC_2,
- SFX_STUDENT_MALE_VOICE_1_MUGGED_1,
- SFX_STUDENT_MALE_VOICE_1_MUGGED_2,
- SFX_STUDENT_MALE_VOICE_1_SHOCKED_1,
- SFX_STUDENT_MALE_VOICE_1_SHOCKED_2,
- SFX_STUDENT_MALE_VOICE_1_SHOCKED_3,
- SFX_STUDENT_FEMALE_VOICE_1_DRIVER_ABUSE_1,
- SFX_STUDENT_FEMALE_VOICE_1_DRIVER_ABUSE_2,
- SFX_STUDENT_FEMALE_VOICE_1_DRIVER_ABUSE_3,
- SFX_STUDENT_FEMALE_VOICE_1_DRIVER_ABUSE_4,
- SFX_STUDENT_FEMALE_VOICE_1_CHAT_1,
- SFX_STUDENT_FEMALE_VOICE_1_CHAT_2,
- SFX_STUDENT_FEMALE_VOICE_1_CHAT_3,
- SFX_STUDENT_FEMALE_VOICE_1_CHAT_4,
- SFX_STUDENT_FEMALE_VOICE_1_DODGE_1,
- SFX_STUDENT_FEMALE_VOICE_1_DODGE_2,
- SFX_STUDENT_FEMALE_VOICE_1_DODGE_3,
- SFX_STUDENT_FEMALE_VOICE_1_DODGE_4,
- SFX_STUDENT_FEMALE_VOICE_1_FIGHT_1,
- SFX_STUDENT_FEMALE_VOICE_1_FIGHT_2,
- SFX_STUDENT_FEMALE_VOICE_1_FIGHT_3,
- SFX_STUDENT_FEMALE_VOICE_1_FIGHT_4,
- SFX_STUDENT_FEMALE_VOICE_1_GUN_PANIC_1,
- SFX_STUDENT_FEMALE_VOICE_1_GUN_PANIC_2,
- SFX_STUDENT_FEMALE_VOICE_1_GUN_PANIC_3,
- SFX_STUDENT_FEMALE_VOICE_1_GUN_PANIC_4,
- SFX_STUDENT_FEMALE_VOICE_1_MUGGED_1,
- SFX_STUDENT_FEMALE_VOICE_1_MUGGED_2,
- SFX_STUDENT_FEMALE_VOICE_1_SHOCKED_1,
- SFX_STUDENT_FEMALE_VOICE_1_SHOCKED_2,
- SFX_HOOD_MALE_VOICE_1_DRIVER_ABUSE_1,
- SFX_HOOD_MALE_VOICE_1_DRIVER_ABUSE_2,
- SFX_HOOD_MALE_VOICE_1_DRIVER_ABUSE_3,
- SFX_HOOD_MALE_VOICE_1_DRIVER_ABUSE_4,
- SFX_HOOD_MALE_VOICE_1_DRIVER_ABUSE_5,
- SFX_HOOD_MALE_VOICE_1_DRIVER_ABUSE_6,
- SFX_HOOD_MALE_VOICE_1_DRIVER_ABUSE_7,
- SFX_HOOD_MALE_VOICE_1_CHAT_1,
- SFX_HOOD_MALE_VOICE_1_CHAT_2,
- SFX_HOOD_MALE_VOICE_1_CHAT_3,
- SFX_HOOD_MALE_VOICE_1_CHAT_4,
- SFX_HOOD_MALE_VOICE_1_CHAT_5,
- SFX_HOOD_MALE_VOICE_1_CHAT_6,
- SFX_HOOD_MALE_VOICE_1_DODGE_1,
- SFX_HOOD_MALE_VOICE_1_DODGE_2,
- SFX_HOOD_MALE_VOICE_1_DODGE_3,
- SFX_HOOD_MALE_VOICE_1_DODGE_4,
- SFX_HOOD_MALE_VOICE_1_DODGE_5,
- SFX_HOOD_MALE_VOICE_1_EYING_1,
- SFX_HOOD_MALE_VOICE_1_EYING_2,
- SFX_HOOD_MALE_VOICE_1_FIGHT_1,
- SFX_HOOD_MALE_VOICE_1_FIGHT_2,
- SFX_HOOD_MALE_VOICE_1_FIGHT_3,
- SFX_HOOD_MALE_VOICE_1_FIGHT_4,
- SFX_HOOD_MALE_VOICE_1_FIGHT_5,
- SFX_HOOD_MALE_VOICE_1_FIGHT_6,
- SFX_HOOD_MALE_VOICE_1_GUN_COOL_1,
- SFX_HOOD_MALE_VOICE_1_GUN_COOL_2,
- SFX_HOOD_MALE_VOICE_1_GUN_COOL_3,
- SFX_HOOD_MALE_VOICE_1_GUN_COOL_4,
- SFX_HOOD_MALE_VOICE_1_GUN_COOL_5,
- SFX_HOOD_MALE_VOICE_1_CARJACKED_1,
- SFX_HOOD_MALE_VOICE_1_CARJACKED_2,
- SFX_HOOD_MALE_VOICE_1_CARJACKING_1,
- SFX_HOOD_MALE_VOICE_1_CARJACKING_2,
- SFX_HOOD_MALE_VOICE_2_DRIVER_ABUSE_1,
- SFX_HOOD_MALE_VOICE_2_DRIVER_ABUSE_2,
- SFX_HOOD_MALE_VOICE_2_DRIVER_ABUSE_3,
- SFX_HOOD_MALE_VOICE_2_DRIVER_ABUSE_4,
- SFX_HOOD_MALE_VOICE_2_DRIVER_ABUSE_5,
- SFX_HOOD_MALE_VOICE_2_DRIVER_ABUSE_6,
- SFX_HOOD_MALE_VOICE_2_DRIVER_ABUSE_7,
- SFX_HOOD_MALE_VOICE_2_CHAT_1,
- SFX_HOOD_MALE_VOICE_2_CHAT_2,
- SFX_HOOD_MALE_VOICE_2_CHAT_3,
- SFX_HOOD_MALE_VOICE_2_CHAT_4,
- SFX_HOOD_MALE_VOICE_2_CHAT_5,
- SFX_HOOD_MALE_VOICE_2_CHAT_6,
- SFX_HOOD_MALE_VOICE_2_DODGE_1,
- SFX_HOOD_MALE_VOICE_2_DODGE_2,
- SFX_HOOD_MALE_VOICE_2_DODGE_3,
- SFX_HOOD_MALE_VOICE_2_DODGE_4,
- SFX_HOOD_MALE_VOICE_2_DODGE_5,
- SFX_HOOD_MALE_VOICE_2_EYING_1,
- SFX_HOOD_MALE_VOICE_2_EYING_2,
- SFX_HOOD_MALE_VOICE_2_FIGHT_1,
- SFX_HOOD_MALE_VOICE_2_FIGHT_2,
- SFX_HOOD_MALE_VOICE_2_FIGHT_3,
- SFX_HOOD_MALE_VOICE_2_FIGHT_4,
- SFX_HOOD_MALE_VOICE_2_FIGHT_5,
- SFX_HOOD_MALE_VOICE_2_FIGHT_6,
- SFX_HOOD_MALE_VOICE_2_GUN_COOL_1,
- SFX_HOOD_MALE_VOICE_2_GUN_COOL_2,
- SFX_HOOD_MALE_VOICE_2_GUN_COOL_3,
- SFX_HOOD_MALE_VOICE_2_GUN_COOL_4,
- SFX_HOOD_MALE_VOICE_2_GUN_COOL_5,
- SFX_HOOD_MALE_VOICE_2_CARJACKED_1,
- SFX_HOOD_MALE_VOICE_2_CARJACKED_2,
- SFX_HOOD_MALE_VOICE_2_CARJACKING_1,
- SFX_HOOD_MALE_VOICE_2_CARJACKING_2,
- SFX_YARDIE_MALE_VOICE_1_DRIVER_ABUSE_1,
- SFX_YARDIE_MALE_VOICE_1_DRIVER_ABUSE_2,
- SFX_YARDIE_MALE_VOICE_1_DRIVER_ABUSE_3,
- SFX_YARDIE_MALE_VOICE_1_DRIVER_ABUSE_4,
- SFX_YARDIE_MALE_VOICE_1_DRIVER_ABUSE_5,
- SFX_YARDIE_MALE_VOICE_1_DRIVER_ABUSE_6,
- SFX_YARDIE_MALE_VOICE_1_CHAT_1,
- SFX_YARDIE_MALE_VOICE_1_CHAT_2,
- SFX_YARDIE_MALE_VOICE_1_CHAT_3,
- SFX_YARDIE_MALE_VOICE_1_CHAT_4,
- SFX_YARDIE_MALE_VOICE_1_CHAT_5,
- SFX_YARDIE_MALE_VOICE_1_CHAT_6,
- SFX_YARDIE_MALE_VOICE_1_CHAT_7,
- SFX_YARDIE_MALE_VOICE_1_CHAT_8,
- SFX_YARDIE_MALE_VOICE_1_DODGE_1,
- SFX_YARDIE_MALE_VOICE_1_DODGE_2,
- SFX_YARDIE_MALE_VOICE_1_DODGE_3,
- SFX_YARDIE_MALE_VOICE_1_DODGE_4,
- SFX_YARDIE_MALE_VOICE_1_DODGE_5,
- SFX_YARDIE_MALE_VOICE_1_EYING_1,
- SFX_YARDIE_MALE_VOICE_1_EYING_2,
- SFX_YARDIE_MALE_VOICE_1_FIGHT_1,
- SFX_YARDIE_MALE_VOICE_1_FIGHT_2,
- SFX_YARDIE_MALE_VOICE_1_FIGHT_3,
- SFX_YARDIE_MALE_VOICE_1_FIGHT_4,
- SFX_YARDIE_MALE_VOICE_1_FIGHT_5,
- SFX_YARDIE_MALE_VOICE_1_FIGHT_6,
- SFX_YARDIE_MALE_VOICE_1_GUN_COOL_1,
- SFX_YARDIE_MALE_VOICE_1_CARJACKED_1,
- SFX_YARDIE_MALE_VOICE_1_CARJACKING_1,
- SFX_YARDIE_MALE_VOICE_1_CARJACKING_2,
- SFX_YARDIE_MALE_VOICE_2_DRIVER_ABUSE_1,
- SFX_YARDIE_MALE_VOICE_2_DRIVER_ABUSE_2,
- SFX_YARDIE_MALE_VOICE_2_DRIVER_ABUSE_3,
- SFX_YARDIE_MALE_VOICE_2_DRIVER_ABUSE_4,
- SFX_YARDIE_MALE_VOICE_2_DRIVER_ABUSE_5,
- SFX_YARDIE_MALE_VOICE_2_DRIVER_ABUSE_6,
- SFX_YARDIE_MALE_VOICE_2_CHAT_1,
- SFX_YARDIE_MALE_VOICE_2_CHAT_2,
- SFX_YARDIE_MALE_VOICE_2_CHAT_3,
- SFX_YARDIE_MALE_VOICE_2_CHAT_4,
- SFX_YARDIE_MALE_VOICE_2_CHAT_5,
- SFX_YARDIE_MALE_VOICE_2_CHAT_6,
- SFX_YARDIE_MALE_VOICE_2_CHAT_7,
- SFX_YARDIE_MALE_VOICE_2_CHAT_8,
- SFX_YARDIE_MALE_VOICE_2_DODGE_1,
- SFX_YARDIE_MALE_VOICE_2_DODGE_2,
- SFX_YARDIE_MALE_VOICE_2_DODGE_3,
- SFX_YARDIE_MALE_VOICE_2_DODGE_4,
- SFX_YARDIE_MALE_VOICE_2_DODGE_5,
- SFX_YARDIE_MALE_VOICE_2_EYING_1,
- SFX_YARDIE_MALE_VOICE_2_EYING_2,
- SFX_YARDIE_MALE_VOICE_2_FIGHT_1,
- SFX_YARDIE_MALE_VOICE_2_FIGHT_2,
- SFX_YARDIE_MALE_VOICE_2_FIGHT_3,
- SFX_YARDIE_MALE_VOICE_2_FIGHT_4,
- SFX_YARDIE_MALE_VOICE_2_FIGHT_5,
- SFX_YARDIE_MALE_VOICE_2_FIGHT_6,
- SFX_YARDIE_MALE_VOICE_2_GUN_COOL_1,
- SFX_YARDIE_MALE_VOICE_2_CARJACKED_1,
- SFX_YARDIE_MALE_VOICE_2_CARJACKING_1,
- SFX_YARDIE_MALE_VOICE_2_CARJACKING_2,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_DRIVER_ABUSE_1,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_DRIVER_ABUSE_2,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_DRIVER_ABUSE_3,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_DRIVER_ABUSE_4,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_DRIVER_ABUSE_5,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_DRIVER_ABUSE_6,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_DRIVER_ABUSE_7,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_CHAT_1,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_CHAT_2,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_CHAT_3,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_CHAT_4,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_CHAT_5,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_CHAT_6,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_CHAT_7,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_DODGE_1,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_DODGE_2,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_DODGE_3,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_DODGE_4,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_DODGE_5,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_DODGE_6,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_GUN_PANIC_1,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_GUN_PANIC_2,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_GUN_PANIC_3,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_GUN_PANIC_4,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_GUN_PANIC_5,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_CARAJACKED_1,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_CARAJACKED_2,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_CARAJACKED_3,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_CARAJACKED_4,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_MUGGED_1,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_MUGGED_2,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_MUGGED_3,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_RUN_FROM_FIGHT_1,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_RUN_FROM_FIGHT_2,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_RUN_FROM_FIGHT_3,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_RUN_FROM_FIGHT_4,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_RUN_FROM_FIGHT_5,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_RUN_FROM_FIGHT_6,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_SHOCKED_1,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_SHOCKED_2,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_SHOCKED_3,
- SFX_BLACK_BUSINESS_FEMALE_VOICE_1_SHOCKED_4,
- SFX_WHITE_WORKER_MALE_VOICE_1_DRIVER_ABUSE_1,
- SFX_WHITE_WORKER_MALE_VOICE_1_DRIVER_ABUSE_2,
- SFX_WHITE_WORKER_MALE_VOICE_1_DRIVER_ABUSE_3,
- SFX_WHITE_WORKER_MALE_VOICE_1_DRIVER_ABUSE_4,
- SFX_WHITE_WORKER_MALE_VOICE_1_DRIVER_ABUSE_5,
- SFX_WHITE_WORKER_MALE_VOICE_1_DRIVER_ABUSE_6,
- SFX_WHITE_WORKER_MALE_VOICE_1_CHAT_1,
- SFX_WHITE_WORKER_MALE_VOICE_1_CHAT_2,
- SFX_WHITE_WORKER_MALE_VOICE_1_CHAT_3,
- SFX_WHITE_WORKER_MALE_VOICE_1_CHAT_4,
- SFX_WHITE_WORKER_MALE_VOICE_1_CHAT_5,
- SFX_WHITE_WORKER_MALE_VOICE_1_CHAT_6,
- SFX_WHITE_WORKER_MALE_VOICE_1_DODGE_1,
- SFX_WHITE_WORKER_MALE_VOICE_1_DODGE_2,
- SFX_WHITE_WORKER_MALE_VOICE_1_DODGE_3,
- SFX_WHITE_WORKER_MALE_VOICE_1_DODGE_4,
- SFX_WHITE_WORKER_MALE_VOICE_1_EYING_1,
- SFX_WHITE_WORKER_MALE_VOICE_1_EYING_2,
- SFX_WHITE_WORKER_MALE_VOICE_1_FIGHT_1,
- SFX_WHITE_WORKER_MALE_VOICE_1_FIGHT_2,
- SFX_WHITE_WORKER_MALE_VOICE_1_FIGHT_3,
- SFX_WHITE_WORKER_MALE_VOICE_1_GUN_PANIC_1,
- SFX_WHITE_WORKER_MALE_VOICE_1_GUN_PANIC_2,
- SFX_WHITE_WORKER_MALE_VOICE_1_GUN_PANIC_3,
- SFX_STEWARD_MALE_VOICE_1_DRIVER_ABUSE_1,
- SFX_STEWARD_MALE_VOICE_1_DRIVER_ABUSE_2,
- SFX_STEWARD_MALE_VOICE_1_DRIVER_ABUSE_3,
- SFX_STEWARD_MALE_VOICE_1_DRIVER_ABUSE_4,
- SFX_STEWARD_MALE_VOICE_1_DRIVER_ABUSE_5,
- SFX_STEWARD_MALE_VOICE_1_CHAT_1,
- SFX_STEWARD_MALE_VOICE_1_CHAT_2,
- SFX_STEWARD_MALE_VOICE_1_CHAT_3,
- SFX_STEWARD_MALE_VOICE_1_CHAT_4,
- SFX_STEWARD_MALE_VOICE_1_DODGE_1,
- SFX_STEWARD_MALE_VOICE_1_DODGE_2,
- SFX_STEWARD_MALE_VOICE_1_DODGE_3,
- SFX_STEWARD_MALE_VOICE_1_FIGHT_1,
- SFX_STEWARD_MALE_VOICE_1_FIGHT_2,
- SFX_STEWARD_MALE_VOICE_1_FIGHT_3,
- SFX_STEWARD_MALE_VOICE_1_FIGHT_4,
- SFX_STEWARD_MALE_VOICE_1_GUN_PANIC_1,
- SFX_STEWARD_MALE_VOICE_1_GUN_PANIC_2,
- SFX_STEWARD_MALE_VOICE_1_GUN_PANIC_3,
- SFX_STEWARD_FEMALE_VOICE_1_DRIVER_ABUSE_1,
- SFX_STEWARD_FEMALE_VOICE_1_DRIVER_ABUSE_2,
- SFX_STEWARD_FEMALE_VOICE_1_DRIVER_ABUSE_3,
- SFX_STEWARD_FEMALE_VOICE_1_DRIVER_ABUSE_4,
- SFX_STEWARD_FEMALE_VOICE_1_DRIVER_ABUSE_5,
- SFX_STEWARD_FEMALE_VOICE_1_CHAT_1,
- SFX_STEWARD_FEMALE_VOICE_1_CHAT_2,
- SFX_STEWARD_FEMALE_VOICE_1_CHAT_3,
- SFX_STEWARD_FEMALE_VOICE_1_CHAT_4,
- SFX_STEWARD_FEMALE_VOICE_1_CHAT_5,
- SFX_STEWARD_FEMALE_VOICE_1_DODGE_1,
- SFX_STEWARD_FEMALE_VOICE_1_DODGE_2,
- SFX_STEWARD_FEMALE_VOICE_1_DODGE_3,
- SFX_STEWARD_FEMALE_VOICE_1_DODGE_4,
- SFX_STEWARD_FEMALE_VOICE_1_DODGE_5,
- SFX_STEWARD_FEMALE_VOICE_1_GUN_PANIC_1,
- SFX_STEWARD_FEMALE_VOICE_1_GUN_PANIC_2,
- SFX_STEWARD_FEMALE_VOICE_1_GUN_PANIC_3,
- SFX_STEWARD_FEMALE_VOICE_2_DRIVER_ABUSE_1,
- SFX_STEWARD_FEMALE_VOICE_2_DRIVER_ABUSE_2,
- SFX_STEWARD_FEMALE_VOICE_2_DRIVER_ABUSE_3,
- SFX_STEWARD_FEMALE_VOICE_2_DRIVER_ABUSE_4,
- SFX_STEWARD_FEMALE_VOICE_2_DRIVER_ABUSE_5,
- SFX_STEWARD_FEMALE_VOICE_2_CHAT_1,
- SFX_STEWARD_FEMALE_VOICE_2_CHAT_2,
- SFX_STEWARD_FEMALE_VOICE_2_CHAT_3,
- SFX_STEWARD_FEMALE_VOICE_2_CHAT_4,
- SFX_STEWARD_FEMALE_VOICE_2_CHAT_5,
- SFX_STEWARD_FEMALE_VOICE_2_DODGE_1,
- SFX_STEWARD_FEMALE_VOICE_2_DODGE_2,
- SFX_STEWARD_FEMALE_VOICE_2_DODGE_3,
- SFX_STEWARD_FEMALE_VOICE_2_DODGE_4,
- SFX_STEWARD_FEMALE_VOICE_2_DODGE_5,
- SFX_STEWARD_FEMALE_VOICE_2_GUN_PANIC_1,
- SFX_STEWARD_FEMALE_VOICE_2_GUN_PANIC_2,
- SFX_STEWARD_FEMALE_VOICE_2_GUN_PANIC_3,
- SFX_CHINATOWN_MALE_OLD_VOICE_1_DRIVER_ABUSE_1,
- SFX_CHINATOWN_MALE_OLD_VOICE_1_DRIVER_ABUSE_2,
- SFX_CHINATOWN_MALE_OLD_VOICE_1_DRIVER_ABUSE_3,
- SFX_CHINATOWN_MALE_OLD_VOICE_1_DRIVER_ABUSE_4,
- SFX_CHINATOWN_MALE_OLD_VOICE_1_DRIVER_ABUSE_5,
- SFX_CHINATOWN_MALE_OLD_VOICE_1_DRIVER_ABUSE_6,
- SFX_CHINATOWN_MALE_OLD_VOICE_1_CHAT_1,
- SFX_CHINATOWN_MALE_OLD_VOICE_1_CHAT_2,
- SFX_CHINATOWN_MALE_OLD_VOICE_1_CHAT_3,
- SFX_CHINATOWN_MALE_OLD_VOICE_1_CHAT_4,
- SFX_CHINATOWN_MALE_OLD_VOICE_1_CHAT_5,
- SFX_CHINATOWN_MALE_OLD_VOICE_1_CHAT_6,
- SFX_CHINATOWN_MALE_OLD_VOICE_1_CHAT_7,
- SFX_CHINATOWN_MALE_OLD_VOICE_1_DODGE_1,
- SFX_CHINATOWN_MALE_OLD_VOICE_1_DODGE_2,
- SFX_CHINATOWN_MALE_OLD_VOICE_1_DODGE_3,
- SFX_CHINATOWN_MALE_OLD_VOICE_1_DODGE_4,
- SFX_CHINATOWN_MALE_OLD_VOICE_1_DODGE_5,
- SFX_CHINATOWN_MALE_OLD_VOICE_1_DODGE_6,
- SFX_CHINATOWN_MALE_OLD_VOICE_1_EYING_1,
- SFX_CHINATOWN_MALE_OLD_VOICE_1_EYING_2,
- SFX_CHINATOWN_MALE_OLD_VOICE_1_EYING_3,
- SFX_CHINATOWN_MALE_OLD_VOICE_1_FIGHT_1,
- SFX_CHINATOWN_MALE_OLD_VOICE_1_FIGHT_2,
- SFX_CHINATOWN_MALE_OLD_VOICE_1_FIGHT_3,
- SFX_CHINATOWN_MALE_OLD_VOICE_1_FIGHT_4,
- SFX_CHINATOWN_MALE_OLD_VOICE_1_FIGHT_5,
- SFX_CHINATOWN_MALE_OLD_VOICE_1_GUN_PANIC_1,
- SFX_CHINATOWN_MALE_OLD_VOICE_1_GUN_PANIC_2,
- SFX_CHINATOWN_MALE_OLD_VOICE_1_GUN_PANIC_3,
- SFX_CHINATOWN_MALE_OLD_VOICE_1_CARJACKED_1,
- SFX_CHINATOWN_MALE_OLD_VOICE_1_CARJACKED_2,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_1_DRIVER_ABUSE_1,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_1_DRIVER_ABUSE_2,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_1_DRIVER_ABUSE_3,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_1_DRIVER_ABUSE_4,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_1_DRIVER_ABUSE_5,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_1_CHAT_1,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_1_CHAT_2,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_1_CHAT_3,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_1_CHAT_4,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_1_CHAT_5,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_1_CHAT_6,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_1_CHAT_7,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_1_DODGE_1,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_1_DODGE_2,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_1_DODGE_3,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_1_DODGE_4,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_1_DODGE_5,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_1_DODGE_6,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_1_GUN_PANIC_1,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_1_GUN_PANIC_2,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_1_GUN_PANIC_3,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_1_GUN_PANIC_4,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_1_CARJACKED_1,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_1_CARJACKED_2,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_1_MUGGED_1,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_1_MUGGED_2,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_1_RUN_FROM_FIGHT_1,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_1_RUN_FROM_FIGHT_2,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_1_RUN_FROM_FIGHT_3,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_1_RUN_FROM_FIGHT_4,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_1_SHOCKED_1,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_1_SHOCKED_2,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_1_SHOCKED_3,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_1_SHOCKED_4,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_2_DRIVER_ABUSE_1,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_2_DRIVER_ABUSE_2,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_2_DRIVER_ABUSE_3,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_2_DRIVER_ABUSE_4,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_2_DRIVER_ABUSE_5,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_2_CHAT_1,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_2_CHAT_2,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_2_CHAT_3,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_2_CHAT_4,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_2_CHAT_5,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_2_CHAT_6,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_2_CHAT_7,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_2_DODGE_1,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_2_DODGE_2,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_2_DODGE_3,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_2_DODGE_4,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_2_DODGE_5,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_2_DODGE_6,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_2_GUN_PANIC_1,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_2_GUN_PANIC_2,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_2_GUN_PANIC_3,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_2_GUN_PANIC_4,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_2_CARJACKED_1,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_2_CARJACKED_2,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_2_MUGGED_1,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_2_MUGGED_2,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_2_RUN_FROM_FIGHT_1,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_2_RUN_FROM_FIGHT_2,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_2_RUN_FROM_FIGHT_3,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_2_RUN_FROM_FIGHT_4,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_2_SHOCKED_1,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_2_SHOCKED_2,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_2_SHOCKED_3,
- SFX_WHITE_BUSINESS_FEMALE_VOICE_2_SHOCKED_4,
- SFX_BLACK_FAT_MALE_VOICE_1_DRIVER_ABUSE_1,
- SFX_BLACK_FAT_MALE_VOICE_1_DRIVER_ABUSE_2,
- SFX_BLACK_FAT_MALE_VOICE_1_DRIVER_ABUSE_3,
- SFX_BLACK_FAT_MALE_VOICE_1_DRIVER_ABUSE_4,
- SFX_BLACK_FAT_MALE_VOICE_1_DRIVER_ABUSE_5,
- SFX_BLACK_FAT_MALE_VOICE_1_DRIVER_ABUSE_6,
- SFX_BLACK_FAT_MALE_VOICE_1_CHAT_1,
- SFX_BLACK_FAT_MALE_VOICE_1_CHAT_2,
- SFX_BLACK_FAT_MALE_VOICE_1_CHAT_3,
- SFX_BLACK_FAT_MALE_VOICE_1_CHAT_4,
- SFX_BLACK_FAT_MALE_VOICE_1_CHAT_5,
- SFX_BLACK_FAT_MALE_VOICE_1_CHAT_6,
- SFX_BLACK_FAT_MALE_VOICE_1_CHAT_7,
- SFX_BLACK_FAT_MALE_VOICE_1_CHAT_8,
- SFX_BLACK_FAT_MALE_VOICE_1_DODGE_1,
- SFX_BLACK_FAT_MALE_VOICE_1_DODGE_2,
- SFX_BLACK_FAT_MALE_VOICE_1_DODGE_3,
- SFX_BLACK_FAT_MALE_VOICE_1_DODGE_4,
- SFX_BLACK_FAT_MALE_VOICE_1_DODGE_5,
- SFX_BLACK_FAT_MALE_VOICE_1_DODGE_6,
- SFX_BLACK_FAT_MALE_VOICE_1_DODGE_7,
- SFX_BLACK_FAT_MALE_VOICE_1_CARJACKED_1,
- SFX_BLACK_FAT_MALE_VOICE_1_CARJACKED_2,
- SFX_BLACK_FAT_MALE_VOICE_1_CARJACKED_3,
- SFX_BLACK_FAT_MALE_VOICE_1_CARJACKED_4,
- SFX_BLACK_FAT_MALE_VOICE_1_LOST_1,
- SFX_BLACK_FAT_MALE_VOICE_1_LOST_2,
- SFX_BLACK_FAT_MALE_VOICE_1_LOST_3,
- SFX_BLACK_FAT_MALE_VOICE_1_MUGGED_1,
- SFX_BLACK_FAT_MALE_VOICE_1_MUGGED_2,
- SFX_BLACK_FAT_MALE_VOICE_1_MUGGED_3,
- SFX_BLACK_PROJECT_MALE_VOICE_1_DRIVER_ABUSE_1,
- SFX_BLACK_PROJECT_MALE_VOICE_1_DRIVER_ABUSE_2,
- SFX_BLACK_PROJECT_MALE_VOICE_1_DRIVER_ABUSE_3,
- SFX_BLACK_PROJECT_MALE_VOICE_1_DRIVER_ABUSE_4,
- SFX_BLACK_PROJECT_MALE_VOICE_1_DRIVER_ABUSE_5,
- SFX_BLACK_PROJECT_MALE_VOICE_1_DRIVER_ABUSE_6,
- SFX_BLACK_PROJECT_MALE_VOICE_1_DRIVER_ABUSE_7,
- SFX_BLACK_PROJECT_MALE_VOICE_1_CHAT_1,
- SFX_BLACK_PROJECT_MALE_VOICE_1_CHAT_2,
- SFX_BLACK_PROJECT_MALE_VOICE_1_CHAT_3,
- SFX_BLACK_PROJECT_MALE_VOICE_1_CHAT_4,
- SFX_BLACK_PROJECT_MALE_VOICE_1_CHAT_5,
- SFX_BLACK_PROJECT_MALE_VOICE_1_CHAT_6,
- SFX_BLACK_PROJECT_MALE_VOICE_1_DODGE_1,
- SFX_BLACK_PROJECT_MALE_VOICE_1_DODGE_2,
- SFX_BLACK_PROJECT_MALE_VOICE_1_DODGE_3,
- SFX_BLACK_PROJECT_MALE_VOICE_1_DODGE_4,
- SFX_BLACK_PROJECT_MALE_VOICE_1_DODGE_5,
- SFX_BLACK_PROJECT_MALE_VOICE_1_EYING_1,
- SFX_BLACK_PROJECT_MALE_VOICE_1_EYING_2,
- SFX_BLACK_PROJECT_MALE_VOICE_1_EYING_3,
- SFX_BLACK_PROJECT_MALE_VOICE_1_FIGHT_1,
- SFX_BLACK_PROJECT_MALE_VOICE_1_FIGHT_2,
- SFX_BLACK_PROJECT_MALE_VOICE_1_FIGHT_3,
- SFX_BLACK_PROJECT_MALE_VOICE_1_FIGHT_4,
- SFX_BLACK_PROJECT_MALE_VOICE_1_FIGHT_5,
- SFX_BLACK_PROJECT_MALE_VOICE_1_FIGHT_6,
- SFX_BLACK_PROJECT_MALE_VOICE_1_GUN_COOL_1,
- SFX_BLACK_PROJECT_MALE_VOICE_1_GUN_COOL_2,
- SFX_BLACK_PROJECT_MALE_VOICE_1_GUN_COOL_3,
- SFX_BLACK_PROJECT_MALE_VOICE_1_CARJACKED_1,
- SFX_BLACK_PROJECT_MALE_VOICE_1_CARJACKED_2,
- SFX_BLACK_PROJECT_MALE_VOICE_1_MUGGED_1,
- SFX_BLACK_PROJECT_MALE_VOICE_1_MUGGED_2,
- SFX_BLACK_PROJECT_MALE_VOICE_2_DRIVER_ABUSE_1,
- SFX_BLACK_PROJECT_MALE_VOICE_2_DRIVER_ABUSE_2,
- SFX_BLACK_PROJECT_MALE_VOICE_2_DRIVER_ABUSE_3,
- SFX_BLACK_PROJECT_MALE_VOICE_2_DRIVER_ABUSE_4,
- SFX_BLACK_PROJECT_MALE_VOICE_2_DRIVER_ABUSE_5,
- SFX_BLACK_PROJECT_MALE_VOICE_2_DRIVER_ABUSE_6,
- SFX_BLACK_PROJECT_MALE_VOICE_2_DRIVER_ABUSE_7,
- SFX_BLACK_PROJECT_MALE_VOICE_2_CHAT_1,
- SFX_BLACK_PROJECT_MALE_VOICE_2_CHAT_2,
- SFX_BLACK_PROJECT_MALE_VOICE_2_CHAT_3,
- SFX_BLACK_PROJECT_MALE_VOICE_2_CHAT_4,
- SFX_BLACK_PROJECT_MALE_VOICE_2_CHAT_5,
- SFX_BLACK_PROJECT_MALE_VOICE_2_CHAT_6,
- SFX_BLACK_PROJECT_MALE_VOICE_2_DODGE_1,
- SFX_BLACK_PROJECT_MALE_VOICE_2_DODGE_2,
- SFX_BLACK_PROJECT_MALE_VOICE_2_DODGE_3,
- SFX_BLACK_PROJECT_MALE_VOICE_2_DODGE_4,
- SFX_BLACK_PROJECT_MALE_VOICE_2_DODGE_5,
- SFX_BLACK_PROJECT_MALE_VOICE_2_EYING_1,
- SFX_BLACK_PROJECT_MALE_VOICE_2_EYING_2,
- SFX_BLACK_PROJECT_MALE_VOICE_2_EYING_3,
- SFX_BLACK_PROJECT_MALE_VOICE_2_FIGHT_1,
- SFX_BLACK_PROJECT_MALE_VOICE_2_FIGHT_2,
- SFX_BLACK_PROJECT_MALE_VOICE_2_FIGHT_3,
- SFX_BLACK_PROJECT_MALE_VOICE_2_FIGHT_4,
- SFX_BLACK_PROJECT_MALE_VOICE_2_FIGHT_5,
- SFX_BLACK_PROJECT_MALE_VOICE_2_FIGHT_6,
- SFX_BLACK_PROJECT_MALE_VOICE_2_GUN_COOL_1,
- SFX_BLACK_PROJECT_MALE_VOICE_2_GUN_COOL_2,
- SFX_BLACK_PROJECT_MALE_VOICE_2_GUN_COOL_3,
- SFX_BLACK_PROJECT_MALE_VOICE_2_CARJACKED_1,
- SFX_BLACK_PROJECT_MALE_VOICE_2_CARJACKED_2,
- SFX_BLACK_PROJECT_MALE_VOICE_2_MUGGED_1,
- SFX_BLACK_PROJECT_MALE_VOICE_2_MUGGED_2,
- SFX_BLACK_WORKER_MALE_VOICE_1_DRIVER_ABUSE_1,
- SFX_BLACK_WORKER_MALE_VOICE_1_DRIVER_ABUSE_2,
- SFX_BLACK_WORKER_MALE_VOICE_1_DRIVER_ABUSE_3,
- SFX_BLACK_WORKER_MALE_VOICE_1_DRIVER_ABUSE_4,
- SFX_BLACK_WORKER_MALE_VOICE_1_CHAT_1,
- SFX_BLACK_WORKER_MALE_VOICE_1_CHAT_2,
- SFX_BLACK_WORKER_MALE_VOICE_1_CHAT_3,
- SFX_BLACK_WORKER_MALE_VOICE_1_CHAT_4,
- SFX_BLACK_WORKER_MALE_VOICE_1_DODGE_1,
- SFX_BLACK_WORKER_MALE_VOICE_1_DODGE_2,
- SFX_BLACK_WORKER_MALE_VOICE_1_DODGE_3,
- SFX_BLACK_WORKER_MALE_VOICE_1_EYING_1,
- SFX_BLACK_WORKER_MALE_VOICE_1_EYING_2,
- SFX_BLACK_WORKER_MALE_VOICE_1_EYING_3,
- SFX_BLACK_WORKER_MALE_VOICE_1_FIGHT_1,
- SFX_BLACK_WORKER_MALE_VOICE_1_FIGHT_2,
- SFX_BLACK_WORKER_MALE_VOICE_1_FIGHT_3,
- SFX_BLACK_WORKER_MALE_VOICE_1_GUN_PANIC_1,
- SFX_BLACK_WORKER_MALE_VOICE_1_GUN_PANIC_2,
- SFX_BLACK_WORKER_MALE_VOICE_1_GUN_PANIC_3,
- SFX_BLACK_WORKER_MALE_VOICE_1_GUN_PANIC_4,
- SFX_SHOPPER_VOICE_1_DRIVER_ABUSE_1,
- SFX_SHOPPER_VOICE_1_DRIVER_ABUSE_2,
- SFX_SHOPPER_VOICE_1_DRIVER_ABUSE_3,
- SFX_SHOPPER_VOICE_1_DRIVER_ABUSE_4,
- SFX_SHOPPER_VOICE_1_DRIVER_ABUSE_5,
- SFX_SHOPPER_VOICE_1_DRIVER_ABUSE_6,
- SFX_SHOPPER_VOICE_1_DRIVER_ABUSE_7,
- SFX_SHOPPER_VOICE_1_CHAT_1,
- SFX_SHOPPER_VOICE_1_CHAT_2,
- SFX_SHOPPER_VOICE_1_CHAT_3,
- SFX_SHOPPER_VOICE_1_CHAT_4,
- SFX_SHOPPER_VOICE_1_CHAT_5,
- SFX_SHOPPER_VOICE_1_CHAT_6,
- SFX_SHOPPER_VOICE_1_CHAT_7,
- SFX_SHOPPER_VOICE_1_DODGE_1,
- SFX_SHOPPER_VOICE_1_DODGE_2,
- SFX_SHOPPER_VOICE_1_DODGE_3,
- SFX_SHOPPER_VOICE_1_DODGE_4,
- SFX_SHOPPER_VOICE_1_DODGE_5,
- SFX_SHOPPER_VOICE_1_DODGE_6,
- SFX_SHOPPER_VOICE_1_CARJACKED_1,
- SFX_SHOPPER_VOICE_1_CARJACKED_2,
- SFX_SHOPPER_VOICE_1_MUGGED_1,
- SFX_SHOPPER_VOICE_1_MUGGED_2,
- SFX_SHOPPER_VOICE_1_SHOCKED_1,
- SFX_SHOPPER_VOICE_1_SHOCKED_2,
- SFX_SHOPPER_VOICE_1_SHOCKED_3,
- SFX_SHOPPER_VOICE_1_SHOCKED_4,
- SFX_SHOPPER_VOICE_2_DRIVER_ABUSE_1,
- SFX_SHOPPER_VOICE_2_DRIVER_ABUSE_2,
- SFX_SHOPPER_VOICE_2_DRIVER_ABUSE_3,
- SFX_SHOPPER_VOICE_2_DRIVER_ABUSE_4,
- SFX_SHOPPER_VOICE_2_DRIVER_ABUSE_5,
- SFX_SHOPPER_VOICE_2_DRIVER_ABUSE_6,
- SFX_SHOPPER_VOICE_2_DRIVER_ABUSE_7,
- SFX_SHOPPER_VOICE_2_CHAT_1,
- SFX_SHOPPER_VOICE_2_CHAT_2,
- SFX_SHOPPER_VOICE_2_CHAT_3,
- SFX_SHOPPER_VOICE_2_CHAT_4,
- SFX_SHOPPER_VOICE_2_CHAT_5,
- SFX_SHOPPER_VOICE_2_CHAT_6,
- SFX_SHOPPER_VOICE_2_CHAT_7,
- SFX_SHOPPER_VOICE_2_DODGE_1,
- SFX_SHOPPER_VOICE_2_DODGE_2,
- SFX_SHOPPER_VOICE_2_DODGE_3,
- SFX_SHOPPER_VOICE_2_DODGE_4,
- SFX_SHOPPER_VOICE_2_DODGE_5,
- SFX_SHOPPER_VOICE_2_DODGE_6,
- SFX_SHOPPER_VOICE_2_CARJACKED_1,
- SFX_SHOPPER_VOICE_2_CARJACKED_2,
- SFX_SHOPPER_VOICE_2_MUGGED_1,
- SFX_SHOPPER_VOICE_2_MUGGED_2,
- SFX_SHOPPER_VOICE_2_SHOCKED_1,
- SFX_SHOPPER_VOICE_2_SHOCKED_2,
- SFX_SHOPPER_VOICE_2_SHOCKED_3,
- SFX_SHOPPER_VOICE_2_SHOCKED_4,
- SFX_SHOPPER_VOICE_3_DRIVER_ABUSE_1,
- SFX_SHOPPER_VOICE_3_DRIVER_ABUSE_2,
- SFX_SHOPPER_VOICE_3_DRIVER_ABUSE_3,
- SFX_SHOPPER_VOICE_3_DRIVER_ABUSE_4,
- SFX_SHOPPER_VOICE_3_DRIVER_ABUSE_5,
- SFX_SHOPPER_VOICE_3_DRIVER_ABUSE_6,
- SFX_SHOPPER_VOICE_3_DRIVER_ABUSE_7,
- SFX_SHOPPER_VOICE_3_CHAT_1,
- SFX_SHOPPER_VOICE_3_CHAT_2,
- SFX_SHOPPER_VOICE_3_CHAT_3,
- SFX_SHOPPER_VOICE_3_CHAT_4,
- SFX_SHOPPER_VOICE_3_CHAT_5,
- SFX_SHOPPER_VOICE_3_CHAT_6,
- SFX_SHOPPER_VOICE_3_CHAT_7,
- SFX_SHOPPER_VOICE_3_DODGE_1,
- SFX_SHOPPER_VOICE_3_DODGE_2,
- SFX_SHOPPER_VOICE_3_DODGE_3,
- SFX_SHOPPER_VOICE_3_DODGE_4,
- SFX_SHOPPER_VOICE_3_DODGE_5,
- SFX_SHOPPER_VOICE_3_DODGE_6,
- SFX_SHOPPER_VOICE_3_CARJACKED_1,
- SFX_SHOPPER_VOICE_3_CARJACKED_2,
- SFX_SHOPPER_VOICE_3_MUGGED_1,
- SFX_SHOPPER_VOICE_3_MUGGED_2,
- SFX_SHOPPER_VOICE_3_SHOCKED_1,
- SFX_SHOPPER_VOICE_3_SHOCKED_2,
- SFX_SHOPPER_VOICE_3_SHOCKED_3,
- SFX_SHOPPER_VOICE_3_SHOCKED_4,
- SFX_COLUMBIAN_MALE_VOICE_1_DRIVER_ABUSE_1,
- SFX_COLUMBIAN_MALE_VOICE_1_DRIVER_ABUSE_2,
- SFX_COLUMBIAN_MALE_VOICE_1_DRIVER_ABUSE_3,
- SFX_COLUMBIAN_MALE_VOICE_1_DRIVER_ABUSE_4,
- SFX_COLUMBIAN_MALE_VOICE_1_DRIVER_ABUSE_5,
- SFX_COLUMBIAN_MALE_VOICE_1_DRIVER_ABUSE_6,
- SFX_COLUMBIAN_MALE_VOICE_1_CHAT_1,
- SFX_COLUMBIAN_MALE_VOICE_1_CHAT_2,
- SFX_COLUMBIAN_MALE_VOICE_1_CHAT_3,
- SFX_COLUMBIAN_MALE_VOICE_1_CHAT_4,
- SFX_COLUMBIAN_MALE_VOICE_1_CHAT_5,
- SFX_COLUMBIAN_MALE_VOICE_1_DODGE_1,
- SFX_COLUMBIAN_MALE_VOICE_1_DODGE_2,
- SFX_COLUMBIAN_MALE_VOICE_1_DODGE_3,
- SFX_COLUMBIAN_MALE_VOICE_1_DODGE_4,
- SFX_COLUMBIAN_MALE_VOICE_1_DODGE_5,
- SFX_COLUMBIAN_MALE_VOICE_1_EYING_1,
- SFX_COLUMBIAN_MALE_VOICE_1_EYING_2,
- SFX_COLUMBIAN_MALE_VOICE_1_FIGHT_1,
- SFX_COLUMBIAN_MALE_VOICE_1_FIGHT_2,
- SFX_COLUMBIAN_MALE_VOICE_1_FIGHT_3,
- SFX_COLUMBIAN_MALE_VOICE_1_FIGHT_4,
- SFX_COLUMBIAN_MALE_VOICE_1_FIGHT_5,
- SFX_COLUMBIAN_MALE_VOICE_1_CARJACKED_1,
- SFX_COLUMBIAN_MALE_VOICE_1_CARJACKED_2,
- SFX_COLUMBIAN_MALE_VOICE_1_CARJACKING_1,
- SFX_COLUMBIAN_MALE_VOICE_1_CARJACKING_2,
- SFX_COLUMBIAN_MALE_VOICE_2_DRIVER_ABUSE_1,
- SFX_COLUMBIAN_MALE_VOICE_2_DRIVER_ABUSE_2,
- SFX_COLUMBIAN_MALE_VOICE_2_DRIVER_ABUSE_3,
- SFX_COLUMBIAN_MALE_VOICE_2_DRIVER_ABUSE_4,
- SFX_COLUMBIAN_MALE_VOICE_2_DRIVER_ABUSE_5,
- SFX_COLUMBIAN_MALE_VOICE_2_DRIVER_ABUSE_6,
- SFX_COLUMBIAN_MALE_VOICE_2_CHAT_1,
- SFX_COLUMBIAN_MALE_VOICE_2_CHAT_2,
- SFX_COLUMBIAN_MALE_VOICE_2_CHAT_3,
- SFX_COLUMBIAN_MALE_VOICE_2_CHAT_4,
- SFX_COLUMBIAN_MALE_VOICE_2_CHAT_5,
- SFX_COLUMBIAN_MALE_VOICE_2_DODGE_1,
- SFX_COLUMBIAN_MALE_VOICE_2_DODGE_2,
- SFX_COLUMBIAN_MALE_VOICE_2_DODGE_3,
- SFX_COLUMBIAN_MALE_VOICE_2_DODGE_4,
- SFX_COLUMBIAN_MALE_VOICE_2_DODGE_5,
- SFX_COLUMBIAN_MALE_VOICE_2_EYING_1,
- SFX_COLUMBIAN_MALE_VOICE_2_EYING_2,
- SFX_COLUMBIAN_MALE_VOICE_2_FIGHT_1,
- SFX_COLUMBIAN_MALE_VOICE_2_FIGHT_2,
- SFX_COLUMBIAN_MALE_VOICE_2_FIGHT_3,
- SFX_COLUMBIAN_MALE_VOICE_2_FIGHT_4,
- SFX_COLUMBIAN_MALE_VOICE_2_FIGHT_5,
- SFX_COLUMBIAN_MALE_VOICE_2_CARJACKED_1,
- SFX_COLUMBIAN_MALE_VOICE_2_CARJACKED_2,
- SFX_COLUMBIAN_MALE_VOICE_2_CARJACKING_1,
- SFX_COLUMBIAN_MALE_VOICE_2_CARJACKING_2,
- SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_DRIVER_ABUSE_1,
- SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_DRIVER_ABUSE_2,
- SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_DRIVER_ABUSE_3,
- SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_DRIVER_ABUSE_4,
- SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_DRIVER_ABUSE_5,
- SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_DRIVER_ABUSE_6,
- SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_DRIVER_ABUSE_7,
- SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_CHAT_1,
- SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_CHAT_2,
- SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_CHAT_3,
- SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_CHAT_4,
- SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_CHAT_5,
- SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_CHAT_6,
- SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_CHAT_7,
- SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_DODGE_1,
- SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_DODGE_2,
- SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_DODGE_3,
- SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_DODGE_4,
- SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_DODGE_5,
- SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_DODGE_6,
- SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_CARJACKED_1,
- SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_CARJACKED_2,
- SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_MUGGED_1,
- SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_MUGGED_2,
- SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_SHOCKED_1,
- SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_SHOCKED_2,
- SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_SHOCKED_3,
- SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_SHOCKED_4,
- SFX_CHINATOWN_OLD_FEMALE_VOICE_1_DRIVER_ABUSE_1,
- SFX_CHINATOWN_OLD_FEMALE_VOICE_1_DRIVER_ABUSE_2,
- SFX_CHINATOWN_OLD_FEMALE_VOICE_1_DRIVER_ABUSE_3,
- SFX_CHINATOWN_OLD_FEMALE_VOICE_1_DRIVER_ABUSE_4,
- SFX_CHINATOWN_OLD_FEMALE_VOICE_1_DRIVER_ABUSE_5,
- SFX_CHINATOWN_OLD_FEMALE_VOICE_1_CHAT_1,
- SFX_CHINATOWN_OLD_FEMALE_VOICE_1_CHAT_2,
- SFX_CHINATOWN_OLD_FEMALE_VOICE_1_CHAT_3,
- SFX_CHINATOWN_OLD_FEMALE_VOICE_1_CHAT_4,
- SFX_CHINATOWN_OLD_FEMALE_VOICE_1_CHAT_5,
- SFX_CHINATOWN_OLD_FEMALE_VOICE_1_CHAT_6,
- SFX_CHINATOWN_OLD_FEMALE_VOICE_1_DODGE_1,
- SFX_CHINATOWN_OLD_FEMALE_VOICE_1_DODGE_2,
- SFX_CHINATOWN_OLD_FEMALE_VOICE_1_DODGE_3,
- SFX_CHINATOWN_OLD_FEMALE_VOICE_1_DODGE_4,
- SFX_CHINATOWN_OLD_FEMALE_VOICE_1_DODGE_5,
- SFX_CHINATOWN_OLD_FEMALE_VOICE_1_GUN_PANIC_1,
- SFX_CHINATOWN_OLD_FEMALE_VOICE_1_GUN_PANIC_2,
- SFX_CHINATOWN_OLD_FEMALE_VOICE_1_GUN_PANIC_3,
- SFX_CHINATOWN_OLD_FEMALE_VOICE_1_MUGGED_1,
- SFX_CHINATOWN_OLD_FEMALE_VOICE_1_MUGGED_2,
- SFX_CHINATOWN_OLD_FEMALE_VOICE_1_SHOCKED_1,
+ SFX_VICE_VOICE_6_ARREST_1,
+ SFX_VICE_VOICE_6_ARREST_2,
+ SFX_VICE_VOICE_6_ARREST_3,
+ SFX_VICE_VOICE_6_MIAMIVICE_EXITING_CAR_1,
+
+ SFX_DEFAULT_VOICE_BLOCKED_1,
+ SFX_DEFAULT_VOICE_BLOCKED_2,
+ SFX_DEFAULT_VOICE_BLOCKED_3,
+ SFX_DEFAULT_VOICE_BLOCKED_4,
+ SFX_DEFAULT_VOICE_BLOCKED_5,
+ SFX_DEFAULT_VOICE_BLOCKED_6,
+ SFX_DEFAULT_VOICE_BLOCKED_7,
+ SFX_DEFAULT_VOICE_BLOCKED_8,
+ SFX_DEFAULT_VOICE_BLOCKED_9,
+ SFX_DEFAULT_VOICE_BLOCKED_10,
+ SFX_DEFAULT_VOICE_BLOCKED_11,
+ SFX_DEFAULT_VOICE_BLOCKED_12,
+ SFX_DEFAULT_VOICE_BLOCKED_13,
+ SFX_DEFAULT_VOICE_BLOCKED_14,
+ SFX_DEFAULT_VOICE_BLOCKED_15,
+ SFX_DEFAULT_VOICE_BLOCKED_16,
+ SFX_DEFAULT_VOICE_BUMP_1,
+ SFX_DEFAULT_VOICE_BUMP_2,
+ SFX_DEFAULT_VOICE_BUMP_3,
+ SFX_DEFAULT_VOICE_BUMP_4,
+ SFX_DEFAULT_VOICE_BUMP_5,
+ SFX_DEFAULT_VOICE_BUMP_6,
+ SFX_DEFAULT_VOICE_BUMP_7,
+ SFX_DEFAULT_VOICE_BUMP_8,
+ SFX_DEFAULT_VOICE_BUMP_9,
+ SFX_DEFAULT_VOICE_BUMP_10,
+ SFX_DEFAULT_VOICE_BUMP_11,
+ SFX_DEFAULT_VOICE_BUMP_12,
+ SFX_DEFAULT_VOICE_BUMP_13,
+ SFX_DEFAULT_VOICE_BUMP_14,
+ SFX_DEFAULT_VOICE_BUMP_15,
+ SFX_DEFAULT_VOICE_BUMP_16,
+ SFX_DEFAULT_VOICE_BUMP_17,
+ SFX_DEFAULT_VOICE_BUMP_18,
+ SFX_DEFAULT_VOICE_BUMP_19,
+ SFX_DEFAULT_VOICE_BUMP_20,
+ SFX_DEFAULT_VOICE_BUMP_21,
+ SFX_DEFAULT_VOICE_BUMP_22,
+ SFX_DEFAULT_VOICE_BUMP_23,
+ SFX_DEFAULT_VOICE_BUMP_24,
+ SFX_DEFAULT_VOICE_BUMP_25,
+ SFX_DEFAULT_VOICE_CAR_CRASH_1,
+ SFX_DEFAULT_VOICE_CAR_CRASH_2,
+ SFX_DEFAULT_VOICE_CAR_CRASH_3,
+ SFX_DEFAULT_VOICE_CAR_CRASH_4,
+ SFX_DEFAULT_VOICE_CAR_CRASH_5,
+ SFX_DEFAULT_VOICE_CAR_CRASH_6,
+ SFX_DEFAULT_VOICE_CAR_CRASH_7,
+ SFX_DEFAULT_VOICE_CAR_CRASH_8,
+ SFX_DEFAULT_VOICE_CAR_CRASH_9,
+ SFX_DEFAULT_VOICE_CAR_CRASH_10,
+ SFX_DEFAULT_VOICE_CAR_CRASH_11,
+ SFX_DEFAULT_VOICE_CAR_CRASH_12,
+ SFX_DEFAULT_VOICE_CAR_CRASH_13,
+ SFX_DEFAULT_VOICE_CAR_CRASH_14,
+ SFX_DEFAULT_VOICE_CAR_CRASH_15,
+ SFX_DEFAULT_VOICE_CHAT_1,
+ SFX_DEFAULT_VOICE_CHAT_2,
+ SFX_DEFAULT_VOICE_CHAT_3,
+ SFX_DEFAULT_VOICE_CHAT_4,
+ SFX_DEFAULT_VOICE_CHAT_5,
+ SFX_DEFAULT_VOICE_CHAT_6,
+ SFX_DEFAULT_VOICE_CHAT_7,
+ SFX_DEFAULT_VOICE_CHAT_8,
+ SFX_DEFAULT_VOICE_CHAT_9,
+ SFX_DEFAULT_VOICE_CHAT_10,
+ SFX_DEFAULT_VOICE_CHAT_11,
+ SFX_DEFAULT_VOICE_CHAT_12,
+ SFX_DEFAULT_VOICE_CHAT_13,
+ SFX_DEFAULT_VOICE_CHAT_14,
+ SFX_DEFAULT_VOICE_CHAT_15,
+ SFX_DEFAULT_VOICE_CHAT_16,
+ SFX_DEFAULT_VOICE_CHAT_17,
+ SFX_DEFAULT_VOICE_CHAT_18,
+ SFX_DEFAULT_VOICE_CHAT_19,
+ SFX_DEFAULT_VOICE_CHAT_20,
+ SFX_DEFAULT_VOICE_CHAT_21,
+ SFX_DEFAULT_VOICE_CHAT_22,
+ SFX_DEFAULT_VOICE_CHAT_23,
+ SFX_DEFAULT_VOICE_CHAT_24,
+ SFX_DEFAULT_VOICE_CHAT_25,
+ SFX_DEFAULT_VOICE_DODGE_1,
+ SFX_DEFAULT_VOICE_DODGE_2,
+ SFX_DEFAULT_VOICE_DODGE_3,
+ SFX_DEFAULT_VOICE_DODGE_4,
+ SFX_DEFAULT_VOICE_DODGE_5,
+ SFX_DEFAULT_VOICE_DODGE_6,
+ SFX_DEFAULT_VOICE_DODGE_7,
+ SFX_DEFAULT_VOICE_DODGE_8,
+ SFX_DEFAULT_VOICE_DODGE_9,
+ SFX_DEFAULT_VOICE_DODGE_10,
+ SFX_DEFAULT_VOICE_DODGE_11,
+ SFX_DEFAULT_VOICE_DODGE_12,
+ SFX_DEFAULT_VOICE_DODGE_13,
+ SFX_DEFAULT_VOICE_DODGE_14,
+ SFX_DEFAULT_VOICE_DODGE_15,
+ SFX_DEFAULT_VOICE_DODGE_16,
+ SFX_DEFAULT_VOICE_DODGE_17,
+ SFX_DEFAULT_VOICE_DODGE_18,
+ SFX_DEFAULT_VOICE_DODGE_19,
+ SFX_DEFAULT_VOICE_EYEING_1,
+ SFX_DEFAULT_VOICE_EYEING_2,
+ SFX_DEFAULT_VOICE_EYEING_3,
+ SFX_DEFAULT_VOICE_EYEING_4,
+ SFX_DEFAULT_VOICE_EYEING_5,
+ SFX_DEFAULT_VOICE_EYEING_6,
+ SFX_DEFAULT_VOICE_FIGHT_1,
+ SFX_DEFAULT_VOICE_FIGHT_2,
+ SFX_DEFAULT_VOICE_FIGHT_3,
+ SFX_DEFAULT_VOICE_FIGHT_4,
+ SFX_DEFAULT_VOICE_FIGHT_5,
+ SFX_DEFAULT_VOICE_FIGHT_6,
+ SFX_DEFAULT_VOICE_FIGHT_7,
+ SFX_DEFAULT_VOICE_FIGHT_8,
+ SFX_DEFAULT_VOICE_FIGHT_9,
+ SFX_DEFAULT_VOICE_FIGHT_10,
+ SFX_DEFAULT_VOICE_FIGHT_11,
+ SFX_DEFAULT_VOICE_FIGHT_12,
+ SFX_DEFAULT_VOICE_FIGHT_13,
+ SFX_DEFAULT_VOICE_FIGHT_14,
+ SFX_DEFAULT_VOICE_FIGHT_15,
+ SFX_DEFAULT_VOICE_FIGHT_16,
+ SFX_DEFAULT_VOICE_GENERIC_CRASH_1,
+ SFX_DEFAULT_VOICE_GENERIC_CRASH_2,
+ SFX_DEFAULT_VOICE_GENERIC_CRASH_3,
+ SFX_DEFAULT_VOICE_GENERIC_CRASH_4,
+ SFX_DEFAULT_VOICE_GENERIC_CRASH_5,
+ SFX_DEFAULT_VOICE_GENERIC_CRASH_6,
+ SFX_DEFAULT_VOICE_GENERIC_CRASH_7,
+ SFX_DEFAULT_VOICE_GENERIC_CRASH_8,
+ SFX_DEFAULT_VOICE_GENERIC_CRASH_9,
+ SFX_DEFAULT_VOICE_GENERIC_CRASH_10,
+ SFX_DEFAULT_VOICE_GENERIC_CRASH_11,
+ SFX_DEFAULT_VOICE_GENERIC_CRASH_12,
+ SFX_DEFAULT_VOICE_GENERIC_CRASH_13,
+ SFX_DEFAULT_VOICE_GUN_PANIC_1,
+ SFX_DEFAULT_VOICE_GUN_PANIC_2,
+ SFX_DEFAULT_VOICE_GUN_PANIC_3,
+ SFX_DEFAULT_VOICE_GUN_PANIC_4,
+ SFX_DEFAULT_VOICE_GUN_PANIC_5,
+ SFX_DEFAULT_VOICE_GUN_PANIC_6,
+ SFX_DEFAULT_VOICE_GUN_PANIC_7,
+ SFX_DEFAULT_VOICE_GUN_PANIC_8,
+ SFX_DEFAULT_VOICE_GUN_PANIC_9,
+ SFX_DEFAULT_VOICE_GUN_PANIC_10,
+ SFX_DEFAULT_VOICE_GUN_PANIC_11,
+ SFX_DEFAULT_VOICE_GUN_PANIC_12,
+ SFX_DEFAULT_VOICE_JACKED_1,
+ SFX_DEFAULT_VOICE_JACKED_2,
+ SFX_DEFAULT_VOICE_JACKED_3,
+ SFX_DEFAULT_VOICE_JACKED_4,
+ SFX_DEFAULT_VOICE_JACKED_5,
+ SFX_DEFAULT_VOICE_JACKED_6,
+ SFX_DEFAULT_VOICE_JACKED_7,
+ SFX_DEFAULT_VOICE_JACKED_8,
+ SFX_DEFAULT_VOICE_JACKED_9,
+ SFX_DEFAULT_VOICE_JACKED_10,
+ SFX_DEFAULT_VOICE_JACKED_11,
+ SFX_DEFAULT_VOICE_JACKED_12,
+ SFX_DEFAULT_VOICE_JACKING_1,
+ SFX_DEFAULT_VOICE_JACKING_2,
+ SFX_DEFAULT_VOICE_JACKING_3,
+ SFX_DEFAULT_VOICE_JACKING_4,
+ SFX_DEFAULT_VOICE_JACKING_5,
+ SFX_DEFAULT_VOICE_JACKING_6,
+ SFX_DEFAULT_VOICE_JACKING_7,
+ SFX_DEFAULT_VOICE_JACKING_8,
+ SFX_DEFAULT_VOICE_JACKING_9,
+ SFX_DEFAULT_VOICE_JACKING_10,
+ SFX_DEFAULT_VOICE_JACKING_11,
+ SFX_DEFAULT_VOICE_JACKING_12,
+ SFX_DEFAULT_VOICE_JACKING_13,
+ SFX_DEFAULT_VOICE_LOST_1,
+ SFX_DEFAULT_VOICE_LOST_2,
+ SFX_DEFAULT_VOICE_LOST_3,
+ SFX_DEFAULT_VOICE_LOST_4,
+ SFX_DEFAULT_VOICE_LOST_5,
+ SFX_DEFAULT_VOICE_MUGGED_1,
+ SFX_DEFAULT_VOICE_MUGGED_2,
+ SFX_DEFAULT_VOICE_MUGGED_3,
+ SFX_DEFAULT_VOICE_MUGGED_4,
+ SFX_DEFAULT_VOICE_RUN_1,
+ SFX_DEFAULT_VOICE_RUN_2,
+ SFX_DEFAULT_VOICE_RUN_3,
+ SFX_DEFAULT_VOICE_RUN_4,
+ SFX_DEFAULT_VOICE_RUN_5,
+ SFX_DEFAULT_VOICE_RUN_6,
+ SFX_DEFAULT_VOICE_RUN_7,
+ SFX_DEFAULT_VOICE_RUN_8,
+ SFX_DEFAULT_VOICE_RUN_9,
+ SFX_DEFAULT_VOICE_RUN_10,
+ SFX_DEFAULT_VOICE_RUN_11,
+ SFX_DEFAULT_VOICE_RUN_12,
+ SFX_DEFAULT_VOICE_RUN_13,
+ SFX_DEFAULT_VOICE_RUN_14,
+ SFX_DEFAULT_VOICE_RUN_15,
+ SFX_DEFAULT_VOICE_RUN_16,
+ SFX_DEFAULT_VOICE_RUN_17,
+ SFX_DEFAULT_VOICE_RUN_18,
+ SFX_DEFAULT_VOICE_RUN_19,
+ SFX_DEFAULT_VOICE_SAVED_1,
+ SFX_DEFAULT_VOICE_SAVED_2,
+ SFX_DEFAULT_VOICE_SAVED_3,
+ SFX_DEFAULT_VOICE_SAVED_4,
+ SFX_DEFAULT_VOICE_SHOCKED_1,
+ SFX_DEFAULT_VOICE_SHOCKED_2,
+ SFX_DEFAULT_VOICE_SHOCKED_3,
+ SFX_DEFAULT_VOICE_SHOCKED_4,
+ SFX_DEFAULT_VOICE_SHOCKED_5,
+ SFX_DEFAULT_VOICE_SHOCKED_6,
+ SFX_DEFAULT_VOICE_TAXI_1,
+ SFX_DEFAULT_VOICE_TAXI_2,
+ SFX_DEFAULT_VOICE_TAXI_3,
+ SFX_DEFAULT_VOICE_TAXI_4,
+ SFX_DEFAULT_VOICE_TAXI_5,
+
+ SFX_CUBAN_GANG_1_BLOCKED_1,
+ SFX_CUBAN_GANG_1_BLOCKED_2,
+ SFX_CUBAN_GANG_1_BLOCKED_3,
+ SFX_CUBAN_GANG_1_BLOCKED_4,
+ SFX_CUBAN_GANG_1_BLOCKED_5,
+ SFX_CUBAN_GANG_1_BLOCKED_6,
+ SFX_CUBAN_GANG_1_BLOCKED_7,
+ SFX_CUBAN_GANG_1_BLOCKED_8,
+ SFX_CUBAN_GANG_1_BUMP_1,
+ SFX_CUBAN_GANG_1_BUMP_2,
+ SFX_CUBAN_GANG_1_BUMP_3,
+ SFX_CUBAN_GANG_1_BUMP_4,
+ SFX_CUBAN_GANG_1_BUMP_5,
+ SFX_CUBAN_GANG_1_BUMP_6,
+ SFX_CUBAN_GANG_1_BUMP_7,
+ SFX_CUBAN_GANG_1_BUMP_8,
+ SFX_CUBAN_GANG_1_BUMP_9,
+ SFX_CUBAN_GANG_1_BUMP_10,
+ SFX_CUBAN_GANG_1_BUMP_11,
+ SFX_CUBAN_GANG_1_CAR_CRASH_1,
+ SFX_CUBAN_GANG_1_CAR_CRASH_2,
+ SFX_CUBAN_GANG_1_CAR_CRASH_3,
+ SFX_CUBAN_GANG_1_CAR_CRASH_4,
+ SFX_CUBAN_GANG_1_CAR_CRASH_5,
+ SFX_CUBAN_GANG_1_CAR_CRASH_6,
+ SFX_CUBAN_GANG_1_CAR_CRASH_7,
+ SFX_CUBAN_GANG_1_CAR_CRASH_8,
+ SFX_CUBAN_GANG_1_CHAT_1,
+ SFX_CUBAN_GANG_1_CHAT_2,
+ SFX_CUBAN_GANG_1_CHAT_3,
+ SFX_CUBAN_GANG_1_CHAT_4,
+ SFX_CUBAN_GANG_1_CHAT_5,
+ SFX_CUBAN_GANG_1_CHAT_6,
+ SFX_CUBAN_GANG_1_CHAT_7,
+ SFX_CUBAN_GANG_1_CHAT_8,
+ SFX_CUBAN_GANG_1_CHAT_9,
+ SFX_CUBAN_GANG_1_CHAT_10,
+ SFX_CUBAN_GANG_1_DODGE_1,
+ SFX_CUBAN_GANG_1_DODGE_2,
+ SFX_CUBAN_GANG_1_DODGE_3,
+ SFX_CUBAN_GANG_1_DODGE_4,
+ SFX_CUBAN_GANG_1_DODGE_5,
+ SFX_CUBAN_GANG_1_DODGE_6,
+ SFX_CUBAN_GANG_1_DODGE_7,
+ SFX_CUBAN_GANG_1_DODGE_8,
+ SFX_CUBAN_GANG_1_DODGE_9,
+ SFX_CUBAN_GANG_1_EYEING_1,
+ SFX_CUBAN_GANG_1_EYEING_2,
+ SFX_CUBAN_GANG_1_FIGHT_1,
+ SFX_CUBAN_GANG_1_FIGHT_2,
+ SFX_CUBAN_GANG_1_FIGHT_3,
+ SFX_CUBAN_GANG_1_FIGHT_4,
+ SFX_CUBAN_GANG_1_FIGHT_5,
+ SFX_CUBAN_GANG_1_FIGHT_6,
+ SFX_CUBAN_GANG_1_FIGHT_7,
+ SFX_CUBAN_GANG_1_FIGHT_8,
+ SFX_CUBAN_GANG_1_FIGHT_9,
+ SFX_CUBAN_GANG_1_GENERIC_CRASH_1,
+ SFX_CUBAN_GANG_1_GENERIC_CRASH_2,
+ SFX_CUBAN_GANG_1_GENERIC_CRASH_3,
+ SFX_CUBAN_GANG_1_GENERIC_CRASH_4,
+ SFX_CUBAN_GANG_1_GENERIC_CRASH_5,
+ SFX_CUBAN_GANG_1_GENERIC_CRASH_6,
+ SFX_CUBAN_GANG_1_GENERIC_CRASH_7,
+ SFX_CUBAN_GANG_1_GENERIC_CRASH_8,
+ SFX_CUBAN_GANG_1_GUN_COOL_1,
+ SFX_CUBAN_GANG_1_GUN_COOL_2,
+ SFX_CUBAN_GANG_1_GUN_COOL_3,
+ SFX_CUBAN_GANG_1_GUN_COOL_4,
+ SFX_CUBAN_GANG_1_GUN_COOL_5,
+ SFX_CUBAN_GANG_1_JACKED_1,
+ SFX_CUBAN_GANG_1_JACKED_2,
+ SFX_CUBAN_GANG_1_JACKED_3,
+ SFX_CUBAN_GANG_1_JACKED_4,
+ SFX_CUBAN_GANG_1_JACKING_1,
+ SFX_CUBAN_GANG_1_JACKING_2,
+ SFX_CUBAN_GANG_1_JACKING_3,
+ SFX_CUBAN_GANG_1_JACKING_4,
+ SFX_CUBAN_GANG_1_JACKING_5,
+ SFX_CUBAN_GANG_1_LOST_1,
+ SFX_CUBAN_GANG_1_LOST_2,
+ SFX_CUBAN_GANG_1_MUGGED_1,
+ SFX_CUBAN_GANG_1_MUGGED_2,
+ SFX_CUBAN_GANG_1_SAVED_1,
+ SFX_CUBAN_GANG_1_TAXI_1,
+ SFX_CUBAN_GANG_1_TAXI_2,
+ SFX_CUBAN_GANG_2_BLOCKED_1,
+ SFX_CUBAN_GANG_2_BLOCKED_2,
+ SFX_CUBAN_GANG_2_BLOCKED_3,
+ SFX_CUBAN_GANG_2_BLOCKED_4,
+ SFX_CUBAN_GANG_2_BLOCKED_5,
+ SFX_CUBAN_GANG_2_BLOCKED_6,
+ SFX_CUBAN_GANG_2_BLOCKED_7,
+ SFX_CUBAN_GANG_2_BLOCKED_8,
+ SFX_CUBAN_GANG_2_BUMP_1,
+ SFX_CUBAN_GANG_2_BUMP_2,
+ SFX_CUBAN_GANG_2_BUMP_3,
+ SFX_CUBAN_GANG_2_BUMP_4,
+ SFX_CUBAN_GANG_2_BUMP_5,
+ SFX_CUBAN_GANG_2_BUMP_6,
+ SFX_CUBAN_GANG_2_BUMP_7,
+ SFX_CUBAN_GANG_2_BUMP_8,
+ SFX_CUBAN_GANG_2_BUMP_9,
+ SFX_CUBAN_GANG_2_BUMP_10,
+ SFX_CUBAN_GANG_2_BUMP_11,
+ SFX_CUBAN_GANG_2_CAR_CRASH_1,
+ SFX_CUBAN_GANG_2_CAR_CRASH_2,
+ SFX_CUBAN_GANG_2_CAR_CRASH_3,
+ SFX_CUBAN_GANG_2_CAR_CRASH_4,
+ SFX_CUBAN_GANG_2_CAR_CRASH_5,
+ SFX_CUBAN_GANG_2_CAR_CRASH_6,
+ SFX_CUBAN_GANG_2_CAR_CRASH_7,
+ SFX_CUBAN_GANG_2_CAR_CRASH_8,
+ SFX_CUBAN_GANG_2_CHAT_1,
+ SFX_CUBAN_GANG_2_CHAT_2,
+ SFX_CUBAN_GANG_2_CHAT_3,
+ SFX_CUBAN_GANG_2_CHAT_4,
+ SFX_CUBAN_GANG_2_CHAT_5,
+ SFX_CUBAN_GANG_2_CHAT_6,
+ SFX_CUBAN_GANG_2_CHAT_7,
+ SFX_CUBAN_GANG_2_CHAT_8,
+ SFX_CUBAN_GANG_2_CHAT_9,
+ SFX_CUBAN_GANG_2_CHAT_10,
+ SFX_CUBAN_GANG_2_DODGE_1,
+ SFX_CUBAN_GANG_2_DODGE_2,
+ SFX_CUBAN_GANG_2_DODGE_3,
+ SFX_CUBAN_GANG_2_DODGE_4,
+ SFX_CUBAN_GANG_2_DODGE_5,
+ SFX_CUBAN_GANG_2_DODGE_6,
+ SFX_CUBAN_GANG_2_DODGE_7,
+ SFX_CUBAN_GANG_2_DODGE_8,
+ SFX_CUBAN_GANG_2_DODGE_9,
+ SFX_CUBAN_GANG_2_EYEING_1,
+ SFX_CUBAN_GANG_2_EYEING_2,
+ SFX_CUBAN_GANG_2_FIGHT_1,
+ SFX_CUBAN_GANG_2_FIGHT_2,
+ SFX_CUBAN_GANG_2_FIGHT_3,
+ SFX_CUBAN_GANG_2_FIGHT_4,
+ SFX_CUBAN_GANG_2_FIGHT_5,
+ SFX_CUBAN_GANG_2_FIGHT_6,
+ SFX_CUBAN_GANG_2_FIGHT_7,
+ SFX_CUBAN_GANG_2_FIGHT_8,
+ SFX_CUBAN_GANG_2_FIGHT_9,
+ SFX_CUBAN_GANG_2_GENERIC_CRASH_1,
+ SFX_CUBAN_GANG_2_GENERIC_CRASH_2,
+ SFX_CUBAN_GANG_2_GENERIC_CRASH_3,
+ SFX_CUBAN_GANG_2_GENERIC_CRASH_4,
+ SFX_CUBAN_GANG_2_GENERIC_CRASH_5,
+ SFX_CUBAN_GANG_2_GENERIC_CRASH_6,
+ SFX_CUBAN_GANG_2_GENERIC_CRASH_7,
+ SFX_CUBAN_GANG_2_GENERIC_CRASH_8,
+ SFX_CUBAN_GANG_2_GUN_COOL_1,
+ SFX_CUBAN_GANG_2_GUN_COOL_2,
+ SFX_CUBAN_GANG_2_GUN_COOL_3,
+ SFX_CUBAN_GANG_2_GUN_COOL_4,
+ SFX_CUBAN_GANG_2_GUN_COOL_5,
+ SFX_CUBAN_GANG_2_JACKED_1,
+ SFX_CUBAN_GANG_2_JACKED_2,
+ SFX_CUBAN_GANG_2_JACKED_3,
+ SFX_CUBAN_GANG_2_JACKED_4,
+ SFX_CUBAN_GANG_2_JACKING_1,
+ SFX_CUBAN_GANG_2_JACKING_2,
+ SFX_CUBAN_GANG_2_JACKING_3,
+ SFX_CUBAN_GANG_2_JACKING_4,
+ SFX_CUBAN_GANG_2_JACKING_5,
+ SFX_CUBAN_GANG_2_LOST_1,
+ SFX_CUBAN_GANG_2_LOST_2,
+ SFX_CUBAN_GANG_2_MUGGED_1,
+ SFX_CUBAN_GANG_2_MUGGED_2,
+ SFX_CUBAN_GANG_2_SAVED_1,
+ SFX_CUBAN_GANG_2_TAXI_1,
+ SFX_CUBAN_GANG_2_TAXI_2,
+ SFX_CUBAN_GANG_3_BLOCKED_1,
+ SFX_CUBAN_GANG_3_BLOCKED_2,
+ SFX_CUBAN_GANG_3_BLOCKED_3,
+ SFX_CUBAN_GANG_3_BLOCKED_4,
+ SFX_CUBAN_GANG_3_BLOCKED_5,
+ SFX_CUBAN_GANG_3_BLOCKED_6,
+ SFX_CUBAN_GANG_3_BLOCKED_7,
+ SFX_CUBAN_GANG_3_BLOCKED_8,
+ SFX_CUBAN_GANG_3_BUMP_1,
+ SFX_CUBAN_GANG_3_BUMP_2,
+ SFX_CUBAN_GANG_3_BUMP_3,
+ SFX_CUBAN_GANG_3_BUMP_4,
+ SFX_CUBAN_GANG_3_BUMP_5,
+ SFX_CUBAN_GANG_3_BUMP_6,
+ SFX_CUBAN_GANG_3_BUMP_7,
+ SFX_CUBAN_GANG_3_BUMP_8,
+ SFX_CUBAN_GANG_3_BUMP_9,
+ SFX_CUBAN_GANG_3_BUMP_10,
+ SFX_CUBAN_GANG_3_BUMP_11,
+ SFX_CUBAN_GANG_3_CAR_CRASH_1,
+ SFX_CUBAN_GANG_3_CAR_CRASH_2,
+ SFX_CUBAN_GANG_3_CAR_CRASH_3,
+ SFX_CUBAN_GANG_3_CAR_CRASH_4,
+ SFX_CUBAN_GANG_3_CAR_CRASH_5,
+ SFX_CUBAN_GANG_3_CAR_CRASH_6,
+ SFX_CUBAN_GANG_3_CAR_CRASH_7,
+ SFX_CUBAN_GANG_3_CAR_CRASH_8,
+ SFX_CUBAN_GANG_3_CHAT_1,
+ SFX_CUBAN_GANG_3_CHAT_2,
+ SFX_CUBAN_GANG_3_CHAT_3,
+ SFX_CUBAN_GANG_3_CHAT_4,
+ SFX_CUBAN_GANG_3_CHAT_5,
+ SFX_CUBAN_GANG_3_CHAT_6,
+ SFX_CUBAN_GANG_3_CHAT_7,
+ SFX_CUBAN_GANG_3_CHAT_8,
+ SFX_CUBAN_GANG_3_CHAT_9,
+ SFX_CUBAN_GANG_3_CHAT_10,
+ SFX_CUBAN_GANG_3_DODGE_1,
+ SFX_CUBAN_GANG_3_DODGE_2,
+ SFX_CUBAN_GANG_3_DODGE_3,
+ SFX_CUBAN_GANG_3_DODGE_4,
+ SFX_CUBAN_GANG_3_DODGE_5,
+ SFX_CUBAN_GANG_3_DODGE_6,
+ SFX_CUBAN_GANG_3_DODGE_7,
+ SFX_CUBAN_GANG_3_DODGE_8,
+ SFX_CUBAN_GANG_3_DODGE_9,
+ SFX_CUBAN_GANG_3_EYEING_1,
+ SFX_CUBAN_GANG_3_EYEING_2,
+ SFX_CUBAN_GANG_3_FIGHT_1,
+ SFX_CUBAN_GANG_3_FIGHT_2,
+ SFX_CUBAN_GANG_3_FIGHT_3,
+ SFX_CUBAN_GANG_3_FIGHT_4,
+ SFX_CUBAN_GANG_3_FIGHT_5,
+ SFX_CUBAN_GANG_3_FIGHT_6,
+ SFX_CUBAN_GANG_3_FIGHT_7,
+ SFX_CUBAN_GANG_3_FIGHT_8,
+ SFX_CUBAN_GANG_3_FIGHT_9,
+ SFX_CUBAN_GANG_3_GENERIC_CRASH_1,
+ SFX_CUBAN_GANG_3_GENERIC_CRASH_2,
+ SFX_CUBAN_GANG_3_GENERIC_CRASH_3,
+ SFX_CUBAN_GANG_3_GENERIC_CRASH_4,
+ SFX_CUBAN_GANG_3_GENERIC_CRASH_5,
+ SFX_CUBAN_GANG_3_GENERIC_CRASH_6,
+ SFX_CUBAN_GANG_3_GENERIC_CRASH_7,
+ SFX_CUBAN_GANG_3_GENERIC_CRASH_8,
+ SFX_CUBAN_GANG_3_GUN_COOL_1,
+ SFX_CUBAN_GANG_3_GUN_COOL_2,
+ SFX_CUBAN_GANG_3_GUN_COOL_3,
+ SFX_CUBAN_GANG_3_GUN_COOL_4,
+ SFX_CUBAN_GANG_3_GUN_COOL_5,
+ SFX_CUBAN_GANG_3_JACKED_1,
+ SFX_CUBAN_GANG_3_JACKED_2,
+ SFX_CUBAN_GANG_3_JACKED_3,
+ SFX_CUBAN_GANG_3_JACKED_4,
+ SFX_CUBAN_GANG_3_JACKING_1,
+ SFX_CUBAN_GANG_3_JACKING_2,
+ SFX_CUBAN_GANG_3_JACKING_3,
+ SFX_CUBAN_GANG_3_JACKING_4,
+ SFX_CUBAN_GANG_3_JACKING_5,
+ SFX_CUBAN_GANG_3_LOST_1,
+ SFX_CUBAN_GANG_3_LOST_2,
+ SFX_CUBAN_GANG_3_MUGGED_1,
+ SFX_CUBAN_GANG_3_MUGGED_2,
+ SFX_CUBAN_GANG_3_SAVED_1,
+ SFX_CUBAN_GANG_3_TAXI_1,
+ SFX_CUBAN_GANG_3_TAXI_2,
+
+ SFX_BIKER_GANG_1_BLOCKED_1,
+ SFX_BIKER_GANG_1_BLOCKED_2,
+ SFX_BIKER_GANG_1_BLOCKED_3,
+ SFX_BIKER_GANG_1_BLOCKED_4,
+ SFX_BIKER_GANG_1_BLOCKED_5,
+ SFX_BIKER_GANG_1_BLOCKED_6,
+ SFX_BIKER_GANG_1_BLOCKED_7,
+ SFX_BIKER_GANG_1_BLOCKED_8,
+ SFX_BIKER_GANG_1_BLOCKED_9,
+ SFX_BIKER_GANG_1_BLOCKED_10,
+ SFX_BIKER_GANG_1_BUMP_1,
+ SFX_BIKER_GANG_1_BUMP_2,
+ SFX_BIKER_GANG_1_BUMP_3,
+ SFX_BIKER_GANG_1_BUMP_4,
+ SFX_BIKER_GANG_1_BUMP_5,
+ SFX_BIKER_GANG_1_BUMP_6,
+ SFX_BIKER_GANG_1_BUMP_7,
+ SFX_BIKER_GANG_1_BUMP_8,
+ SFX_BIKER_GANG_1_BUMP_9,
+ SFX_BIKER_GANG_1_BUMP_10,
+ SFX_BIKER_GANG_1_CHAT_1,
+ SFX_BIKER_GANG_1_CHAT_2,
+ SFX_BIKER_GANG_1_CHAT_3,
+ SFX_BIKER_GANG_1_CHAT_4,
+ SFX_BIKER_GANG_1_CHAT_5,
+ SFX_BIKER_GANG_1_CHAT_6,
+ SFX_BIKER_GANG_1_CHAT_7,
+ SFX_BIKER_GANG_1_CHAT_8,
+ SFX_BIKER_GANG_1_CHAT_9,
+ SFX_BIKER_GANG_1_CHAT_10,
+ SFX_BIKER_GANG_1_CHAT_11,
+ SFX_BIKER_GANG_1_CHAT_12,
+ SFX_BIKER_GANG_1_DODGE_1,
+ SFX_BIKER_GANG_1_DODGE_2,
+ SFX_BIKER_GANG_1_DODGE_3,
+ SFX_BIKER_GANG_1_DODGE_4,
+ SFX_BIKER_GANG_1_DODGE_5,
+ SFX_BIKER_GANG_1_DODGE_6,
+ SFX_BIKER_GANG_1_DODGE_7,
+ SFX_BIKER_GANG_1_DODGE_8,
+ SFX_BIKER_GANG_1_DODGE_9,
+ SFX_BIKER_GANG_1_FIGHT_1,
+ SFX_BIKER_GANG_1_FIGHT_2,
+ SFX_BIKER_GANG_1_FIGHT_3,
+ SFX_BIKER_GANG_1_FIGHT_4,
+ SFX_BIKER_GANG_1_FIGHT_5,
+ SFX_BIKER_GANG_1_FIGHT_6,
+ SFX_BIKER_GANG_1_FIGHT_7,
+ SFX_BIKER_GANG_1_FIGHT_8,
+ SFX_BIKER_GANG_1_FIGHT_9,
+ SFX_BIKER_GANG_1_GENERIC_CRASH_1,
+ SFX_BIKER_GANG_1_GENERIC_CRASH_2,
+ SFX_BIKER_GANG_1_GENERIC_CRASH_3,
+ SFX_BIKER_GANG_1_GENERIC_CRASH_4,
+ SFX_BIKER_GANG_1_GENERIC_CRASH_5,
+ SFX_BIKER_GANG_1_GENERIC_CRASH_6,
+ SFX_BIKER_GANG_1_GENERIC_CRASH_7,
+ SFX_BIKER_GANG_1_GENERIC_CRASH_8,
+ SFX_BIKER_GANG_1_GUN_COOL_1,
+ SFX_BIKER_GANG_1_GUN_COOL_2,
+ SFX_BIKER_GANG_1_GUN_COOL_3,
+ SFX_BIKER_GANG_1_GUN_COOL_4,
+ SFX_BIKER_GANG_1_GUN_COOL_5,
+ SFX_BIKER_GANG_1_JACKED_1,
+ SFX_BIKER_GANG_1_JACKED_2,
+ SFX_BIKER_GANG_1_JACKED_3,
+ SFX_BIKER_GANG_1_JACKED_4,
+ SFX_BIKER_GANG_1_JACKED_5,
+ SFX_BIKER_GANG_1_JACKED_6,
+ SFX_BIKER_GANG_1_JACKED_7,
+ SFX_BIKER_GANG_1_JACKED_8,
+ SFX_BIKER_GANG_1_JACKING_1,
+ SFX_BIKER_GANG_1_JACKING_2,
+ SFX_BIKER_GANG_1_JACKING_3,
+ SFX_BIKER_GANG_1_JACKING_4,
+ SFX_BIKER_GANG_1_LOST_1,
+ SFX_BIKER_GANG_1_LOST_2,
+ SFX_BIKER_GANG_1_MUGGED_1,
+ SFX_BIKER_GANG_1_MUGGED_2,
+ SFX_BIKER_GANG_1_SAVED_1,
+ SFX_BIKER_GANG_1_TAXI_1,
+ SFX_BIKER_GANG_1_TAXI_2,
+
+ SFX_BIKER_GANG_2_BLOCKED_1,
+ SFX_BIKER_GANG_2_BLOCKED_2,
+ SFX_BIKER_GANG_2_BLOCKED_3,
+ SFX_BIKER_GANG_2_BLOCKED_4,
+ SFX_BIKER_GANG_2_BLOCKED_5,
+ SFX_BIKER_GANG_2_BLOCKED_6,
+ SFX_BIKER_GANG_2_BLOCKED_7,
+ SFX_BIKER_GANG_2_BLOCKED_8,
+ SFX_BIKER_GANG_2_BLOCKED_9,
+ SFX_BIKER_GANG_2_BLOCKED_10,
+ SFX_BIKER_GANG_2_BUMP_1,
+ SFX_BIKER_GANG_2_BUMP_2,
+ SFX_BIKER_GANG_2_BUMP_3,
+ SFX_BIKER_GANG_2_BUMP_4,
+ SFX_BIKER_GANG_2_BUMP_5,
+ SFX_BIKER_GANG_2_BUMP_6,
+ SFX_BIKER_GANG_2_BUMP_7,
+ SFX_BIKER_GANG_2_BUMP_8,
+ SFX_BIKER_GANG_2_BUMP_9,
+ SFX_BIKER_GANG_2_BUMP_10,
+ SFX_BIKER_GANG_2_CHAT_1,
+ SFX_BIKER_GANG_2_CHAT_2,
+ SFX_BIKER_GANG_2_CHAT_3,
+ SFX_BIKER_GANG_2_CHAT_4,
+ SFX_BIKER_GANG_2_CHAT_5,
+ SFX_BIKER_GANG_2_CHAT_6,
+ SFX_BIKER_GANG_2_CHAT_7,
+ SFX_BIKER_GANG_2_CHAT_8,
+ SFX_BIKER_GANG_2_CHAT_9,
+ SFX_BIKER_GANG_2_CHAT_10,
+ SFX_BIKER_GANG_2_CHAT_11,
+ SFX_BIKER_GANG_2_CHAT_12,
+ SFX_BIKER_GANG_2_DODGE_1,
+ SFX_BIKER_GANG_2_DODGE_2,
+ SFX_BIKER_GANG_2_DODGE_3,
+ SFX_BIKER_GANG_2_DODGE_4,
+ SFX_BIKER_GANG_2_DODGE_5,
+ SFX_BIKER_GANG_2_DODGE_6,
+ SFX_BIKER_GANG_2_DODGE_7,
+ SFX_BIKER_GANG_2_DODGE_8,
+ SFX_BIKER_GANG_2_DODGE_9,
+ SFX_BIKER_GANG_2_FIGHT_1,
+ SFX_BIKER_GANG_2_FIGHT_2,
+ SFX_BIKER_GANG_2_FIGHT_3,
+ SFX_BIKER_GANG_2_FIGHT_4,
+ SFX_BIKER_GANG_2_FIGHT_5,
+ SFX_BIKER_GANG_2_FIGHT_6,
+ SFX_BIKER_GANG_2_FIGHT_7,
+ SFX_BIKER_GANG_2_FIGHT_8,
+ SFX_BIKER_GANG_2_FIGHT_9,
+ SFX_BIKER_GANG_2_GENERIC_CRASH_1,
+ SFX_BIKER_GANG_2_GENERIC_CRASH_2,
+ SFX_BIKER_GANG_2_GENERIC_CRASH_3,
+ SFX_BIKER_GANG_2_GENERIC_CRASH_4,
+ SFX_BIKER_GANG_2_GENERIC_CRASH_5,
+ SFX_BIKER_GANG_2_GENERIC_CRASH_6,
+ SFX_BIKER_GANG_2_GENERIC_CRASH_7,
+ SFX_BIKER_GANG_2_GENERIC_CRASH_8,
+ SFX_BIKER_GANG_2_GUN_COOL_1,
+ SFX_BIKER_GANG_2_GUN_COOL_2,
+ SFX_BIKER_GANG_2_GUN_COOL_3,
+ SFX_BIKER_GANG_2_GUN_COOL_4,
+ SFX_BIKER_GANG_2_GUN_COOL_5,
+ SFX_BIKER_GANG_2_JACKED_1,
+ SFX_BIKER_GANG_2_JACKED_2,
+ SFX_BIKER_GANG_2_JACKED_3,
+ SFX_BIKER_GANG_2_JACKED_4,
+ SFX_BIKER_GANG_2_JACKED_5,
+ SFX_BIKER_GANG_2_JACKED_6,
+ SFX_BIKER_GANG_2_JACKED_7,
+ SFX_BIKER_GANG_2_JACKED_8,
+ SFX_BIKER_GANG_2_JACKING_1,
+ SFX_BIKER_GANG_2_JACKING_2,
+ SFX_BIKER_GANG_2_JACKING_3,
+ SFX_BIKER_GANG_2_JACKING_4,
+ SFX_BIKER_GANG_2_LOST_1,
+ SFX_BIKER_GANG_2_LOST_2,
+ SFX_BIKER_GANG_2_MUGGED_1,
+ SFX_BIKER_GANG_2_MUGGED_2,
+ SFX_BIKER_GANG_2_SAVED_1,
+ SFX_BIKER_GANG_2_TAXI_1,
+ SFX_BIKER_GANG_2_TAXI_2,
+
+ SFX_BIKER_GANG_3_BLOCKED_1,
+ SFX_BIKER_GANG_3_BLOCKED_2,
+ SFX_BIKER_GANG_3_BLOCKED_3,
+ SFX_BIKER_GANG_3_BLOCKED_4,
+ SFX_BIKER_GANG_3_BLOCKED_5,
+ SFX_BIKER_GANG_3_BLOCKED_6,
+ SFX_BIKER_GANG_3_BLOCKED_7,
+ SFX_BIKER_GANG_3_BLOCKED_8,
+ SFX_BIKER_GANG_3_BLOCKED_9,
+ SFX_BIKER_GANG_3_BLOCKED_10,
+ SFX_BIKER_GANG_3_BUMP_1,
+ SFX_BIKER_GANG_3_BUMP_2,
+ SFX_BIKER_GANG_3_BUMP_3,
+ SFX_BIKER_GANG_3_BUMP_4,
+ SFX_BIKER_GANG_3_BUMP_5,
+ SFX_BIKER_GANG_3_BUMP_6,
+ SFX_BIKER_GANG_3_BUMP_7,
+ SFX_BIKER_GANG_3_BUMP_8,
+ SFX_BIKER_GANG_3_BUMP_9,
+ SFX_BIKER_GANG_3_BUMP_10,
+ SFX_BIKER_GANG_3_CHAT_1,
+ SFX_BIKER_GANG_3_CHAT_2,
+ SFX_BIKER_GANG_3_CHAT_3,
+ SFX_BIKER_GANG_3_CHAT_4,
+ SFX_BIKER_GANG_3_CHAT_5,
+ SFX_BIKER_GANG_3_CHAT_6,
+ SFX_BIKER_GANG_3_CHAT_7,
+ SFX_BIKER_GANG_3_CHAT_8,
+ SFX_BIKER_GANG_3_CHAT_9,
+ SFX_BIKER_GANG_3_CHAT_10,
+ SFX_BIKER_GANG_3_CHAT_11,
+ SFX_BIKER_GANG_3_CHAT_12,
+ SFX_BIKER_GANG_3_DODGE_1,
+ SFX_BIKER_GANG_3_DODGE_2,
+ SFX_BIKER_GANG_3_DODGE_3,
+ SFX_BIKER_GANG_3_DODGE_4,
+ SFX_BIKER_GANG_3_DODGE_5,
+ SFX_BIKER_GANG_3_DODGE_6,
+ SFX_BIKER_GANG_3_DODGE_7,
+ SFX_BIKER_GANG_3_DODGE_8,
+ SFX_BIKER_GANG_3_DODGE_9,
+ SFX_BIKER_GANG_3_FIGHT_1,
+ SFX_BIKER_GANG_3_FIGHT_2,
+ SFX_BIKER_GANG_3_FIGHT_3,
+ SFX_BIKER_GANG_3_FIGHT_4,
+ SFX_BIKER_GANG_3_FIGHT_5,
+ SFX_BIKER_GANG_3_FIGHT_6,
+ SFX_BIKER_GANG_3_FIGHT_7,
+ SFX_BIKER_GANG_3_FIGHT_8,
+ SFX_BIKER_GANG_3_FIGHT_9,
+ SFX_BIKER_GANG_3_GENERIC_CRASH_1,
+ SFX_BIKER_GANG_3_GENERIC_CRASH_2,
+ SFX_BIKER_GANG_3_GENERIC_CRASH_3,
+ SFX_BIKER_GANG_3_GENERIC_CRASH_4,
+ SFX_BIKER_GANG_3_GENERIC_CRASH_5,
+ SFX_BIKER_GANG_3_GENERIC_CRASH_6,
+ SFX_BIKER_GANG_3_GENERIC_CRASH_7,
+ SFX_BIKER_GANG_3_GENERIC_CRASH_8,
+ SFX_BIKER_GANG_3_GUN_COOL_1,
+ SFX_BIKER_GANG_3_GUN_COOL_2,
+ SFX_BIKER_GANG_3_GUN_COOL_3,
+ SFX_BIKER_GANG_3_GUN_COOL_4,
+ SFX_BIKER_GANG_3_GUN_COOL_5,
+ SFX_BIKER_GANG_3_JACKED_1,
+ SFX_BIKER_GANG_3_JACKED_2,
+ SFX_BIKER_GANG_3_JACKED_3,
+ SFX_BIKER_GANG_3_JACKED_4,
+ SFX_BIKER_GANG_3_JACKED_5,
+ SFX_BIKER_GANG_3_JACKED_6,
+ SFX_BIKER_GANG_3_JACKED_7,
+ SFX_BIKER_GANG_3_JACKED_8,
+ SFX_BIKER_GANG_3_JACKING_1,
+ SFX_BIKER_GANG_3_JACKING_2,
+ SFX_BIKER_GANG_3_JACKING_3,
+ SFX_BIKER_GANG_3_JACKING_4,
+ SFX_BIKER_GANG_3_LOST_1,
+ SFX_BIKER_GANG_3_LOST_2,
+ SFX_BIKER_GANG_3_MUGGED_1,
+ SFX_BIKER_GANG_3_MUGGED_2,
+ SFX_BIKER_GANG_3_SAVED_1,
+ SFX_BIKER_GANG_3_TAXI_1,
+ SFX_BIKER_GANG_3_TAXI_2,
+
+ SFX_HAITIAN_GANG_1_BLOCKED_1,
+ SFX_HAITIAN_GANG_1_BLOCKED_2,
+ SFX_HAITIAN_GANG_1_BLOCKED_3,
+ SFX_HAITIAN_GANG_1_BLOCKED_4,
+ SFX_HAITIAN_GANG_1_BLOCKED_5,
+ SFX_HAITIAN_GANG_1_BLOCKED_6,
+ SFX_HAITIAN_GANG_1_BLOCKED_7,
+ SFX_HAITIAN_GANG_1_BLOCKED_8,
+ SFX_HAITIAN_GANG_1_BLOCKED_9,
+ SFX_HAITIAN_GANG_1_BUMP_1,
+ SFX_HAITIAN_GANG_1_BUMP_2,
+ SFX_HAITIAN_GANG_1_BUMP_3,
+ SFX_HAITIAN_GANG_1_BUMP_4,
+ SFX_HAITIAN_GANG_1_BUMP_5,
+ SFX_HAITIAN_GANG_1_BUMP_6,
+ SFX_HAITIAN_GANG_1_BUMP_7,
+ SFX_HAITIAN_GANG_1_BUMP_8,
+ SFX_HAITIAN_GANG_1_BUMP_9,
+ SFX_HAITIAN_GANG_1_BUMP_10,
+ SFX_HAITIAN_GANG_1_BUMP_11,
+ SFX_HAITIAN_GANG_1_BUMP_12,
+ SFX_HAITIAN_GANG_1_CAR_CRASH_1,
+ SFX_HAITIAN_GANG_1_CAR_CRASH_2,
+ SFX_HAITIAN_GANG_1_CAR_CRASH_3,
+ SFX_HAITIAN_GANG_1_CAR_CRASH_4,
+ SFX_HAITIAN_GANG_1_CAR_CRASH_5,
+ SFX_HAITIAN_GANG_1_CAR_CRASH_6,
+ SFX_HAITIAN_GANG_1_CAR_CRASH_7,
+ SFX_HAITIAN_GANG_1_CAR_CRASH_8,
+ SFX_HAITIAN_GANG_1_CAR_CRASH_9,
+ SFX_HAITIAN_GANG_1_CHAT_1,
+ SFX_HAITIAN_GANG_1_CHAT_2,
+ SFX_HAITIAN_GANG_1_CHAT_3,
+ SFX_HAITIAN_GANG_1_CHAT_4,
+ SFX_HAITIAN_GANG_1_CHAT_5,
+ SFX_HAITIAN_GANG_1_CHAT_6,
+ SFX_HAITIAN_GANG_1_CHAT_7,
+ SFX_HAITIAN_GANG_1_CHAT_8,
+ SFX_HAITIAN_GANG_1_CHAT_9,
+ SFX_HAITIAN_GANG_1_CHAT_10,
+ SFX_HAITIAN_GANG_1_CHAT_11,
+ SFX_HAITIAN_GANG_1_CHAT_12,
+ SFX_HAITIAN_GANG_1_CHAT_13,
+ SFX_HAITIAN_GANG_1_CHAT_14,
+ SFX_HAITIAN_GANG_1_DODGE_1,
+ SFX_HAITIAN_GANG_1_DODGE_2,
+ SFX_HAITIAN_GANG_1_DODGE_3,
+ SFX_HAITIAN_GANG_1_DODGE_4,
+ SFX_HAITIAN_GANG_1_DODGE_5,
+ SFX_HAITIAN_GANG_1_DODGE_6,
+ SFX_HAITIAN_GANG_1_DODGE_7,
+ SFX_HAITIAN_GANG_1_DODGE_8,
+ SFX_HAITIAN_GANG_1_DODGE_9,
+ SFX_HAITIAN_GANG_1_DODGE_10,
+ SFX_HAITIAN_GANG_1_EYEING_1,
+ SFX_HAITIAN_GANG_1_EYEING_2,
+ SFX_HAITIAN_GANG_1_FIGHT_1,
+ SFX_HAITIAN_GANG_1_FIGHT_2,
+ SFX_HAITIAN_GANG_1_FIGHT_3,
+ SFX_HAITIAN_GANG_1_FIGHT_4,
+ SFX_HAITIAN_GANG_1_FIGHT_5,
+ SFX_HAITIAN_GANG_1_FIGHT_6,
+ SFX_HAITIAN_GANG_1_FIGHT_7,
+ SFX_HAITIAN_GANG_1_FIGHT_8,
+ SFX_HAITIAN_GANG_1_FIGHT_9,
+ SFX_HAITIAN_GANG_1_FIGHT_10,
+ SFX_HAITIAN_GANG_1_GENERIC_CRASH_1,
+ SFX_HAITIAN_GANG_1_GENERIC_CRASH_2,
+ SFX_HAITIAN_GANG_1_GENERIC_CRASH_3,
+ SFX_HAITIAN_GANG_1_GENERIC_CRASH_4,
+ SFX_HAITIAN_GANG_1_GENERIC_CRASH_5,
+ SFX_HAITIAN_GANG_1_GENERIC_CRASH_6,
+ SFX_HAITIAN_GANG_1_GENERIC_CRASH_7,
+ SFX_HAITIAN_GANG_1_GENERIC_CRASH_8,
+ SFX_HAITIAN_GANG_1_GENERIC_CRASH_9,
+ SFX_HAITIAN_GANG_1_GUN_COOL_1,
+ SFX_HAITIAN_GANG_1_GUN_COOL_2,
+ SFX_HAITIAN_GANG_1_GUN_COOL_3,
+ SFX_HAITIAN_GANG_1_GUN_COOL_4,
+ SFX_HAITIAN_GANG_1_GUN_COOL_5,
+ SFX_HAITIAN_GANG_1_JACKED_1,
+ SFX_HAITIAN_GANG_1_JACKED_2,
+ SFX_HAITIAN_GANG_1_JACKED_3,
+ SFX_HAITIAN_GANG_1_JACKED_4,
+ SFX_HAITIAN_GANG_1_JACKED_5,
+ SFX_HAITIAN_GANG_1_JACKED_6,
+ SFX_HAITIAN_GANG_1_JACKING_1,
+ SFX_HAITIAN_GANG_1_JACKING_2,
+ SFX_HAITIAN_GANG_1_JACKING_3,
+ SFX_HAITIAN_GANG_1_JACKING_4,
+ SFX_HAITIAN_GANG_1_LOST_1,
+ SFX_HAITIAN_GANG_1_LOST_2,
+ SFX_HAITIAN_GANG_1_LOST_3,
+ SFX_HAITIAN_GANG_1_LOST_4,
+ SFX_HAITIAN_GANG_1_MUGGED_1,
+ SFX_HAITIAN_GANG_1_MUGGED_2,
+ SFX_HAITIAN_GANG_1_MUGGED_3,
+ SFX_HAITIAN_GANG_1_SAVED_1,
+ SFX_HAITIAN_GANG_1_TAXI_1,
+
+
+ SFX_HAITIAN_GANG_2_BLOCKED_1,
+ SFX_HAITIAN_GANG_2_BLOCKED_2,
+ SFX_HAITIAN_GANG_2_BLOCKED_3,
+ SFX_HAITIAN_GANG_2_BLOCKED_4,
+ SFX_HAITIAN_GANG_2_BLOCKED_5,
+ SFX_HAITIAN_GANG_2_BLOCKED_6,
+ SFX_HAITIAN_GANG_2_BLOCKED_7,
+ SFX_HAITIAN_GANG_2_BLOCKED_8,
+ SFX_HAITIAN_GANG_2_BLOCKED_9,
+ SFX_HAITIAN_GANG_2_BUMP_1,
+ SFX_HAITIAN_GANG_2_BUMP_2,
+ SFX_HAITIAN_GANG_2_BUMP_3,
+ SFX_HAITIAN_GANG_2_BUMP_4,
+ SFX_HAITIAN_GANG_2_BUMP_5,
+ SFX_HAITIAN_GANG_2_BUMP_6,
+ SFX_HAITIAN_GANG_2_BUMP_7,
+ SFX_HAITIAN_GANG_2_BUMP_8,
+ SFX_HAITIAN_GANG_2_BUMP_9,
+ SFX_HAITIAN_GANG_2_BUMP_10,
+ SFX_HAITIAN_GANG_2_BUMP_11,
+ SFX_HAITIAN_GANG_2_BUMP_12,
+ SFX_HAITIAN_GANG_2_CAR_CRASH_1,
+ SFX_HAITIAN_GANG_2_CAR_CRASH_2,
+ SFX_HAITIAN_GANG_2_CAR_CRASH_3,
+ SFX_HAITIAN_GANG_2_CAR_CRASH_4,
+ SFX_HAITIAN_GANG_2_CAR_CRASH_5,
+ SFX_HAITIAN_GANG_2_CAR_CRASH_6,
+ SFX_HAITIAN_GANG_2_CAR_CRASH_7,
+ SFX_HAITIAN_GANG_2_CAR_CRASH_8,
+ SFX_HAITIAN_GANG_2_CAR_CRASH_9,
+ SFX_HAITIAN_GANG_2_CHAT_1,
+ SFX_HAITIAN_GANG_2_CHAT_2,
+ SFX_HAITIAN_GANG_2_CHAT_3,
+ SFX_HAITIAN_GANG_2_CHAT_4,
+ SFX_HAITIAN_GANG_2_CHAT_5,
+ SFX_HAITIAN_GANG_2_CHAT_6,
+ SFX_HAITIAN_GANG_2_CHAT_7,
+ SFX_HAITIAN_GANG_2_CHAT_8,
+ SFX_HAITIAN_GANG_2_CHAT_9,
+ SFX_HAITIAN_GANG_2_CHAT_10,
+ SFX_HAITIAN_GANG_2_CHAT_11,
+ SFX_HAITIAN_GANG_2_CHAT_12,
+ SFX_HAITIAN_GANG_2_CHAT_13,
+ SFX_HAITIAN_GANG_2_CHAT_14,
+ SFX_HAITIAN_GANG_2_DODGE_1,
+ SFX_HAITIAN_GANG_2_DODGE_2,
+ SFX_HAITIAN_GANG_2_DODGE_3,
+ SFX_HAITIAN_GANG_2_DODGE_4,
+ SFX_HAITIAN_GANG_2_DODGE_5,
+ SFX_HAITIAN_GANG_2_DODGE_6,
+ SFX_HAITIAN_GANG_2_DODGE_7,
+ SFX_HAITIAN_GANG_2_DODGE_8,
+ SFX_HAITIAN_GANG_2_DODGE_9,
+ SFX_HAITIAN_GANG_2_DODGE_10,
+ SFX_HAITIAN_GANG_2_EYEING_1,
+ SFX_HAITIAN_GANG_2_EYEING_2,
+ SFX_HAITIAN_GANG_2_FIGHT_1,
+ SFX_HAITIAN_GANG_2_FIGHT_2,
+ SFX_HAITIAN_GANG_2_FIGHT_3,
+ SFX_HAITIAN_GANG_2_FIGHT_4,
+ SFX_HAITIAN_GANG_2_FIGHT_5,
+ SFX_HAITIAN_GANG_2_FIGHT_6,
+ SFX_HAITIAN_GANG_2_FIGHT_7,
+ SFX_HAITIAN_GANG_2_FIGHT_8,
+ SFX_HAITIAN_GANG_2_FIGHT_9,
+ SFX_HAITIAN_GANG_2_FIGHT_10,
+ SFX_HAITIAN_GANG_2_GENERIC_CRASH_1,
+ SFX_HAITIAN_GANG_2_GENERIC_CRASH_2,
+ SFX_HAITIAN_GANG_2_GENERIC_CRASH_3,
+ SFX_HAITIAN_GANG_2_GENERIC_CRASH_4,
+ SFX_HAITIAN_GANG_2_GENERIC_CRASH_5,
+ SFX_HAITIAN_GANG_2_GENERIC_CRASH_6,
+ SFX_HAITIAN_GANG_2_GENERIC_CRASH_7,
+ SFX_HAITIAN_GANG_2_GENERIC_CRASH_8,
+ SFX_HAITIAN_GANG_2_GENERIC_CRASH_9,
+ SFX_HAITIAN_GANG_2_GUN_COOL_1,
+ SFX_HAITIAN_GANG_2_GUN_COOL_2,
+ SFX_HAITIAN_GANG_2_GUN_COOL_3,
+ SFX_HAITIAN_GANG_2_GUN_COOL_4,
+ SFX_HAITIAN_GANG_2_GUN_COOL_5,
+ SFX_HAITIAN_GANG_2_JACKED_1,
+ SFX_HAITIAN_GANG_2_JACKED_2,
+ SFX_HAITIAN_GANG_2_JACKED_3,
+ SFX_HAITIAN_GANG_2_JACKED_4,
+ SFX_HAITIAN_GANG_2_JACKED_5,
+ SFX_HAITIAN_GANG_2_JACKED_6,
+ SFX_HAITIAN_GANG_2_JACKING_1,
+ SFX_HAITIAN_GANG_2_JACKING_2,
+ SFX_HAITIAN_GANG_2_JACKING_3,
+ SFX_HAITIAN_GANG_2_JACKING_4,
+ SFX_HAITIAN_GANG_2_LOST_1,
+ SFX_HAITIAN_GANG_2_LOST_2,
+ SFX_HAITIAN_GANG_2_LOST_3,
+ SFX_HAITIAN_GANG_2_LOST_4,
+ SFX_HAITIAN_GANG_2_MUGGED_1,
+ SFX_HAITIAN_GANG_2_MUGGED_2,
+ SFX_HAITIAN_GANG_2_MUGGED_3,
+ SFX_HAITIAN_GANG_2_SAVED_1,
+ SFX_HAITIAN_GANG_2_TAXI_1,
+
+ SFX_HAITIAN_GANG_3_BLOCKED_1,
+ SFX_HAITIAN_GANG_3_BLOCKED_2,
+ SFX_HAITIAN_GANG_3_BLOCKED_3,
+ SFX_HAITIAN_GANG_3_BLOCKED_4,
+ SFX_HAITIAN_GANG_3_BLOCKED_5,
+ SFX_HAITIAN_GANG_3_BLOCKED_6,
+ SFX_HAITIAN_GANG_3_BLOCKED_7,
+ SFX_HAITIAN_GANG_3_BLOCKED_8,
+ SFX_HAITIAN_GANG_3_BLOCKED_9,
+ SFX_HAITIAN_GANG_3_BUMP_1,
+ SFX_HAITIAN_GANG_3_BUMP_2,
+ SFX_HAITIAN_GANG_3_BUMP_3,
+ SFX_HAITIAN_GANG_3_BUMP_4,
+ SFX_HAITIAN_GANG_3_BUMP_5,
+ SFX_HAITIAN_GANG_3_BUMP_6,
+ SFX_HAITIAN_GANG_3_BUMP_7,
+ SFX_HAITIAN_GANG_3_BUMP_8,
+ SFX_HAITIAN_GANG_3_BUMP_9,
+ SFX_HAITIAN_GANG_3_BUMP_10,
+ SFX_HAITIAN_GANG_3_BUMP_11,
+ SFX_HAITIAN_GANG_3_BUMP_12,
+ SFX_HAITIAN_GANG_3_CAR_CRASH_1,
+ SFX_HAITIAN_GANG_3_CAR_CRASH_2,
+ SFX_HAITIAN_GANG_3_CAR_CRASH_3,
+ SFX_HAITIAN_GANG_3_CAR_CRASH_4,
+ SFX_HAITIAN_GANG_3_CAR_CRASH_5,
+ SFX_HAITIAN_GANG_3_CAR_CRASH_6,
+ SFX_HAITIAN_GANG_3_CAR_CRASH_7,
+ SFX_HAITIAN_GANG_3_CAR_CRASH_8,
+ SFX_HAITIAN_GANG_3_CAR_CRASH_9,
+ SFX_HAITIAN_GANG_3_CHAT_1,
+ SFX_HAITIAN_GANG_3_CHAT_2,
+ SFX_HAITIAN_GANG_3_CHAT_3,
+ SFX_HAITIAN_GANG_3_CHAT_4,
+ SFX_HAITIAN_GANG_3_CHAT_5,
+ SFX_HAITIAN_GANG_3_CHAT_6,
+ SFX_HAITIAN_GANG_3_CHAT_7,
+ SFX_HAITIAN_GANG_3_CHAT_8,
+ SFX_HAITIAN_GANG_3_CHAT_9,
+ SFX_HAITIAN_GANG_3_CHAT_10,
+ SFX_HAITIAN_GANG_3_CHAT_11,
+ SFX_HAITIAN_GANG_3_CHAT_12,
+ SFX_HAITIAN_GANG_3_CHAT_13,
+ SFX_HAITIAN_GANG_3_CHAT_14,
+ SFX_HAITIAN_GANG_3_DODGE_1,
+ SFX_HAITIAN_GANG_3_DODGE_2,
+ SFX_HAITIAN_GANG_3_DODGE_3,
+ SFX_HAITIAN_GANG_3_DODGE_4,
+ SFX_HAITIAN_GANG_3_DODGE_5,
+ SFX_HAITIAN_GANG_3_DODGE_6,
+ SFX_HAITIAN_GANG_3_DODGE_7,
+ SFX_HAITIAN_GANG_3_DODGE_8,
+ SFX_HAITIAN_GANG_3_DODGE_9,
+ SFX_HAITIAN_GANG_3_DODGE_10,
+ SFX_HAITIAN_GANG_3_EYEING_1,
+ SFX_HAITIAN_GANG_3_EYEING_2,
+ SFX_HAITIAN_GANG_3_FIGHT_1,
+ SFX_HAITIAN_GANG_3_FIGHT_2,
+ SFX_HAITIAN_GANG_3_FIGHT_3,
+ SFX_HAITIAN_GANG_3_FIGHT_4,
+ SFX_HAITIAN_GANG_3_FIGHT_5,
+ SFX_HAITIAN_GANG_3_FIGHT_6,
+ SFX_HAITIAN_GANG_3_FIGHT_7,
+ SFX_HAITIAN_GANG_3_FIGHT_8,
+ SFX_HAITIAN_GANG_3_FIGHT_9,
+ SFX_HAITIAN_GANG_3_FIGHT_10,
+ SFX_HAITIAN_GANG_3_GENERIC_CRASH_1,
+ SFX_HAITIAN_GANG_3_GENERIC_CRASH_2,
+ SFX_HAITIAN_GANG_3_GENERIC_CRASH_3,
+ SFX_HAITIAN_GANG_3_GENERIC_CRASH_4,
+ SFX_HAITIAN_GANG_3_GENERIC_CRASH_5,
+ SFX_HAITIAN_GANG_3_GENERIC_CRASH_6,
+ SFX_HAITIAN_GANG_3_GENERIC_CRASH_7,
+ SFX_HAITIAN_GANG_3_GENERIC_CRASH_8,
+ SFX_HAITIAN_GANG_3_GENERIC_CRASH_9,
+ SFX_HAITIAN_GANG_3_GUN_COOL_1,
+ SFX_HAITIAN_GANG_3_GUN_COOL_2,
+ SFX_HAITIAN_GANG_3_GUN_COOL_3,
+ SFX_HAITIAN_GANG_3_GUN_COOL_4,
+ SFX_HAITIAN_GANG_3_GUN_COOL_5,
+ SFX_HAITIAN_GANG_3_JACKED_1,
+ SFX_HAITIAN_GANG_3_JACKED_2,
+ SFX_HAITIAN_GANG_3_JACKED_3,
+ SFX_HAITIAN_GANG_3_JACKED_4,
+ SFX_HAITIAN_GANG_3_JACKED_5,
+ SFX_HAITIAN_GANG_3_JACKED_6,
+ SFX_HAITIAN_GANG_3_JACKING_1,
+ SFX_HAITIAN_GANG_3_JACKING_2,
+ SFX_HAITIAN_GANG_3_JACKING_3,
+ SFX_HAITIAN_GANG_3_JACKING_4,
+ SFX_HAITIAN_GANG_3_LOST_1,
+ SFX_HAITIAN_GANG_3_LOST_2,
+ SFX_HAITIAN_GANG_3_LOST_3,
+ SFX_HAITIAN_GANG_3_LOST_4,
+ SFX_HAITIAN_GANG_3_MUGGED_1,
+ SFX_HAITIAN_GANG_3_MUGGED_2,
+ SFX_HAITIAN_GANG_3_MUGGED_3,
+ SFX_HAITIAN_GANG_3_SAVED_1,
+ SFX_HAITIAN_GANG_3_TAXI_1,
+
+ SFX_GENERIC_FEMALE_FIRE_1,
+ SFX_GENERIC_FEMALE_FIRE_2,
+ SFX_GENERIC_FEMALE_FIRE_3,
+ SFX_GENERIC_FEMALE_FIRE_4,
+ SFX_GENERIC_FEMALE_FIRE_5,
+ SFX_GENERIC_FEMALE_FIRE_6,
+ SFX_GENERIC_FEMALE_FIRE_7,
+ SFX_GENERIC_FEMALE_FIRE_8,
+ SFX_GENERIC_FEMALE_FIRE_9,
+ SFX_GENERIC_FEMALE_FIRE_10,
+ SFX_GENERIC_FEMALE_FIRE_11,
+ SFX_GENERIC_FEMALE_FIRE_12,
+ SFX_GENERIC_FEMALE_FIRE_13,
+ SFX_GENERIC_FEMALE_FIRE_14,
+ SFX_GENERIC_FEMALE_FIRE_15,
+ SFX_GENERIC_FEMALE_FIRE_16,
+ SFX_GENERIC_FEMALE_FIRE_17,
SFX_GENERIC_FEMALE_DEATH_1,
SFX_GENERIC_FEMALE_DEATH_2,
SFX_GENERIC_FEMALE_DEATH_3,
@@ -2389,15 +3025,18 @@ enum eSfxSample
SFX_GENERIC_FEMALE_DEATH_8,
SFX_GENERIC_FEMALE_DEATH_9,
SFX_GENERIC_FEMALE_DEATH_10,
- SFX_GENERIC_FEMALE_FIRE_1,
- SFX_GENERIC_FEMALE_FIRE_2,
- SFX_GENERIC_FEMALE_FIRE_3,
- SFX_GENERIC_FEMALE_FIRE_4,
- SFX_GENERIC_FEMALE_FIRE_5,
- SFX_GENERIC_FEMALE_FIRE_6,
- SFX_GENERIC_FEMALE_FIRE_7,
- SFX_GENERIC_FEMALE_FIRE_8,
- SFX_GENERIC_FEMALE_FIRE_9,
+ SFX_GENERIC_FEMALE_DEATH_11,
+ SFX_GENERIC_FEMALE_DEATH_12,
+ SFX_GENERIC_FEMALE_DEATH_13,
+ SFX_GENERIC_FEMALE_DEATH_14,
+ SFX_GENERIC_FEMALE_DEATH_15,
+ SFX_GENERIC_FEMALE_DEATH_16,
+ SFX_GENERIC_FEMALE_DEATH_17,
+ SFX_GENERIC_FEMALE_DEATH_18,
+ SFX_GENERIC_FEMALE_DEATH_19,
+ SFX_GENERIC_FEMALE_DEATH_20,
+ SFX_GENERIC_FEMALE_DEATH_21,
+ SFX_GENERIC_FEMALE_DEATH_22,
SFX_GENERIC_FEMALE_GRUNT_1,
SFX_GENERIC_FEMALE_GRUNT_2,
SFX_GENERIC_FEMALE_GRUNT_3,
@@ -2409,6 +3048,28 @@ enum eSfxSample
SFX_GENERIC_FEMALE_GRUNT_9,
SFX_GENERIC_FEMALE_GRUNT_10,
SFX_GENERIC_FEMALE_GRUNT_11,
+ SFX_GENERIC_FEMALE_GRUNT_12,
+ SFX_GENERIC_FEMALE_GRUNT_13,
+ SFX_GENERIC_FEMALE_GRUNT_14,
+ SFX_GENERIC_FEMALE_GRUNT_15,
+ SFX_GENERIC_FEMALE_GRUNT_16,
+ SFX_GENERIC_FEMALE_GRUNT_17,
+ SFX_GENERIC_FEMALE_GRUNT_18,
+ SFX_GENERIC_FEMALE_GRUNT_19,
+ SFX_GENERIC_FEMALE_GRUNT_20,
+ SFX_GENERIC_FEMALE_GRUNT_21,
+ SFX_GENERIC_FEMALE_GRUNT_22,
+ SFX_GENERIC_FEMALE_GRUNT_23,
+ SFX_GENERIC_FEMALE_GRUNT_24,
+ SFX_GENERIC_FEMALE_GRUNT_25,
+ SFX_GENERIC_FEMALE_GRUNT_26,
+ SFX_GENERIC_FEMALE_GRUNT_27,
+ SFX_GENERIC_FEMALE_GRUNT_28,
+ SFX_GENERIC_FEMALE_GRUNT_29,
+ SFX_GENERIC_FEMALE_GRUNT_30,
+ SFX_GENERIC_FEMALE_GRUNT_31,
+ SFX_GENERIC_FEMALE_GRUNT_32,
+ SFX_GENERIC_FEMALE_GRUNT_33,
SFX_GENERIC_FEMALE_PANIC_1,
SFX_GENERIC_FEMALE_PANIC_2,
SFX_GENERIC_FEMALE_PANIC_3,
@@ -2417,546 +3078,26 @@ enum eSfxSample
SFX_GENERIC_FEMALE_PANIC_6,
SFX_GENERIC_FEMALE_PANIC_7,
SFX_GENERIC_FEMALE_PANIC_8,
- SFX_BLACK_CRIMINAL_VOICE_1_DRIVER_ABUSE_1,
- SFX_BLACK_CRIMINAL_VOICE_1_DRIVER_ABUSE_2,
- SFX_BLACK_CRIMINAL_VOICE_1_DRIVER_ABUSE_3,
- SFX_BLACK_CRIMINAL_VOICE_1_DRIVER_ABUSE_4,
- SFX_BLACK_CRIMINAL_VOICE_1_DRIVER_ABUSE_5,
- SFX_BLACK_CRIMINAL_VOICE_1_DODGE_1,
- SFX_BLACK_CRIMINAL_VOICE_1_DODGE_2,
- SFX_BLACK_CRIMINAL_VOICE_1_DODGE_3,
- SFX_BLACK_CRIMINAL_VOICE_1_DODGE_4,
- SFX_BLACK_CRIMINAL_VOICE_1_DODGE_5,
- SFX_BLACK_CRIMINAL_VOICE_1_DODGE_6,
- SFX_BLACK_CRIMINAL_VOICE_1_FIGHT_1,
- SFX_BLACK_CRIMINAL_VOICE_1_FIGHT_2,
- SFX_BLACK_CRIMINAL_VOICE_1_FIGHT_3,
- SFX_BLACK_CRIMINAL_VOICE_1_FIGHT_4,
- SFX_BLACK_CRIMINAL_VOICE_1_FIGHT_5,
- SFX_BLACK_CRIMINAL_VOICE_1_GUN_COOL_1,
- SFX_BLACK_CRIMINAL_VOICE_1_GUN_COOL_2,
- SFX_BLACK_CRIMINAL_VOICE_1_GUN_COOL_3,
- SFX_BLACK_CRIMINAL_VOICE_1_GUN_COOL_4,
- SFX_BLACK_CRIMINAL_VOICE_1_CARJACKING_1,
- SFX_BLACK_CRIMINAL_VOICE_1_MUGGING_1,
- SFX_BLACK_CRIMINAL_VOICE_1_MUGGING_2,
- SFX_WHITE_CRIMINAL_VOICE_1_DRIVER_ABUSE_1,
- SFX_WHITE_CRIMINAL_VOICE_1_DRIVER_ABUSE_2,
- SFX_WHITE_CRIMINAL_VOICE_1_DRIVER_ABUSE_3,
- SFX_WHITE_CRIMINAL_VOICE_1_DRIVER_ABUSE_4,
- SFX_WHITE_CRIMINAL_VOICE_1_DODGE_1,
- SFX_WHITE_CRIMINAL_VOICE_1_DODGE_2,
- SFX_WHITE_CRIMINAL_VOICE_1_DODGE_3,
- SFX_WHITE_CRIMINAL_VOICE_1_DODGE_4,
- SFX_WHITE_CRIMINAL_VOICE_1_DODGE_5,
- SFX_WHITE_CRIMINAL_VOICE_1_FIGHT_1,
- SFX_WHITE_CRIMINAL_VOICE_1_FIGHT_2,
- SFX_WHITE_CRIMINAL_VOICE_1_FIGHT_3,
- SFX_WHITE_CRIMINAL_VOICE_1_FIGHT_4,
- SFX_WHITE_CRIMINAL_VOICE_1_GUN_COOL_1,
- SFX_WHITE_CRIMINAL_VOICE_1_GUN_COOL_2,
- SFX_WHITE_CRIMINAL_VOICE_1_GUN_COOL_3,
- SFX_WHITE_CRIMINAL_VOICE_1_CARJACKING_1,
- SFX_WHITE_CRIMINAL_VOICE_1_MUGGING_1,
- SFX_WHITE_CRIMINAL_VOICE_1_MUGGING_2,
- SFX_BUSINESS_MALE_OLD_VOICE_1_DRIVER_ABUSE_1,
- SFX_BUSINESS_MALE_OLD_VOICE_1_DRIVER_ABUSE_2,
- SFX_BUSINESS_MALE_OLD_VOICE_1_DRIVER_ABUSE_3,
- SFX_BUSINESS_MALE_OLD_VOICE_1_DRIVER_ABUSE_4,
- SFX_BUSINESS_MALE_OLD_VOICE_1_DRIVER_ABUSE_5,
- SFX_BUSINESS_MALE_OLD_VOICE_1_CHAT_1,
- SFX_BUSINESS_MALE_OLD_VOICE_1_CHAT_2,
- SFX_BUSINESS_MALE_OLD_VOICE_1_CHAT_3,
- SFX_BUSINESS_MALE_OLD_VOICE_1_CHAT_4,
- SFX_BUSINESS_MALE_OLD_VOICE_1_CHAT_5,
- SFX_BUSINESS_MALE_OLD_VOICE_1_DODGE_1,
- SFX_BUSINESS_MALE_OLD_VOICE_1_DODGE_2,
- SFX_BUSINESS_MALE_OLD_VOICE_1_DODGE_3,
- SFX_BUSINESS_MALE_OLD_VOICE_1_DODGE_4,
- SFX_BUSINESS_MALE_OLD_VOICE_1_FIGHT_1,
- SFX_BUSINESS_MALE_OLD_VOICE_1_FIGHT_2,
- SFX_BUSINESS_MALE_OLD_VOICE_1_FIGHT_3,
- SFX_BUSINESS_MALE_OLD_VOICE_1_FIGHT_4,
- SFX_BUSINESS_MALE_OLD_VOICE_1_FIGHT_5,
- SFX_BUSINESS_MALE_OLD_VOICE_1_GUN_PANIC_1,
- SFX_BUSINESS_MALE_OLD_VOICE_1_GUN_PANIC_2,
- SFX_BUSINESS_MALE_OLD_VOICE_1_GUN_PANIC_3,
- SFX_BUSINESS_MALE_OLD_VOICE_1_CARJACKED_1,
- SFX_BUSINESS_MALE_OLD_VOICE_1_CARJACKED_2,
- SFX_BUSINESS_MALE_OLD_VOICE_1_MUGGED_1,
- SFX_BUSINESS_MALE_OLD_VOICE_1_MUGGED_2,
- SFX_BUSINESS_MALE_OLD_VOICE_1_MRUN_FROM_FIGHT_1,
- SFX_BUSINESS_MALE_OLD_VOICE_1_MRUN_FROM_FIGHT_2,
- SFX_BUSINESS_MALE_OLD_VOICE_1_MRUN_FROM_FIGHT_3,
- SFX_BUSINESS_MALE_OLD_VOICE_1_MRUN_FROM_FIGHT_4,
- SFX_BUSINESS_MALE_OLD_VOICE_1_MRUN_FROM_FIGHT_5,
- SFX_LITTLE_ITALY_MALE_VOICE_1_DRIVER_ABUSE_1,
- SFX_LITTLE_ITALY_MALE_VOICE_1_DRIVER_ABUSE_2,
- SFX_LITTLE_ITALY_MALE_VOICE_1_DRIVER_ABUSE_3,
- SFX_LITTLE_ITALY_MALE_VOICE_1_DRIVER_ABUSE_4,
- SFX_LITTLE_ITALY_MALE_VOICE_1_DRIVER_ABUSE_5,
- SFX_LITTLE_ITALY_MALE_VOICE_1_DRIVER_ABUSE_6,
- SFX_LITTLE_ITALY_MALE_VOICE_1_DRIVER_ABUSE_7,
- SFX_LITTLE_ITALY_MALE_VOICE_1_CHAT_1,
- SFX_LITTLE_ITALY_MALE_VOICE_1_CHAT_2,
- SFX_LITTLE_ITALY_MALE_VOICE_1_CHAT_3,
- SFX_LITTLE_ITALY_MALE_VOICE_1_CHAT_4,
- SFX_LITTLE_ITALY_MALE_VOICE_1_CHAT_5,
- SFX_LITTLE_ITALY_MALE_VOICE_1_CHAT_6,
- SFX_LITTLE_ITALY_MALE_VOICE_1_DODGE_1,
- SFX_LITTLE_ITALY_MALE_VOICE_1_DODGE_2,
- SFX_LITTLE_ITALY_MALE_VOICE_1_DODGE_3,
- SFX_LITTLE_ITALY_MALE_VOICE_1_DODGE_4,
- SFX_LITTLE_ITALY_MALE_VOICE_1_DODGE_5,
- SFX_LITTLE_ITALY_MALE_VOICE_1_FIGHT_1,
- SFX_LITTLE_ITALY_MALE_VOICE_1_FIGHT_2,
- SFX_LITTLE_ITALY_MALE_VOICE_1_FIGHT_3,
- SFX_LITTLE_ITALY_MALE_VOICE_1_FIGHT_4,
- SFX_LITTLE_ITALY_MALE_VOICE_1_FIGHT_5,
- SFX_LITTLE_ITALY_MALE_VOICE_1_GUN_PANIC_1,
- SFX_LITTLE_ITALY_MALE_VOICE_1_GUN_PANIC_2,
- SFX_LITTLE_ITALY_MALE_VOICE_1_GUN_PANIC_3,
- SFX_LITTLE_ITALY_MALE_VOICE_1_CARJACKED_1,
- SFX_LITTLE_ITALY_MALE_VOICE_1_CARJACKED_2,
- SFX_LITTLE_ITALY_MALE_VOICE_1_MUGGED_1,
- SFX_LITTLE_ITALY_MALE_VOICE_1_MUGGED_2,
- SFX_LITTLE_ITALY_MALE_VOICE_2_DRIVER_ABUSE_1,
- SFX_LITTLE_ITALY_MALE_VOICE_2_DRIVER_ABUSE_2,
- SFX_LITTLE_ITALY_MALE_VOICE_2_DRIVER_ABUSE_3,
- SFX_LITTLE_ITALY_MALE_VOICE_2_DRIVER_ABUSE_4,
- SFX_LITTLE_ITALY_MALE_VOICE_2_DRIVER_ABUSE_5,
- SFX_LITTLE_ITALY_MALE_VOICE_2_DRIVER_ABUSE_6,
- SFX_LITTLE_ITALY_MALE_VOICE_2_DRIVER_ABUSE_7,
- SFX_LITTLE_ITALY_MALE_VOICE_2_CHAT_1,
- SFX_LITTLE_ITALY_MALE_VOICE_2_CHAT_2,
- SFX_LITTLE_ITALY_MALE_VOICE_2_CHAT_3,
- SFX_LITTLE_ITALY_MALE_VOICE_2_CHAT_4,
- SFX_LITTLE_ITALY_MALE_VOICE_2_CHAT_5,
- SFX_LITTLE_ITALY_MALE_VOICE_2_CHAT_6,
- SFX_LITTLE_ITALY_MALE_VOICE_2_DODGE_1,
- SFX_LITTLE_ITALY_MALE_VOICE_2_DODGE_2,
- SFX_LITTLE_ITALY_MALE_VOICE_2_DODGE_3,
- SFX_LITTLE_ITALY_MALE_VOICE_2_DODGE_4,
- SFX_LITTLE_ITALY_MALE_VOICE_2_DODGE_5,
- SFX_LITTLE_ITALY_MALE_VOICE_2_FIGHT_1,
- SFX_LITTLE_ITALY_MALE_VOICE_2_FIGHT_2,
- SFX_LITTLE_ITALY_MALE_VOICE_2_FIGHT_3,
- SFX_LITTLE_ITALY_MALE_VOICE_2_FIGHT_4,
- SFX_LITTLE_ITALY_MALE_VOICE_2_FIGHT_5,
- SFX_LITTLE_ITALY_MALE_VOICE_2_GUN_PANIC_1,
- SFX_LITTLE_ITALY_MALE_VOICE_2_GUN_PANIC_2,
- SFX_LITTLE_ITALY_MALE_VOICE_2_GUN_PANIC_3,
- SFX_LITTLE_ITALY_MALE_VOICE_2_CARJACKED_1,
- SFX_LITTLE_ITALY_MALE_VOICE_2_CARJACKED_2,
- SFX_LITTLE_ITALY_MALE_VOICE_2_MUGGED_1,
- SFX_LITTLE_ITALY_MALE_VOICE_2_MUGGED_2,
- SFX_TRIAD_MALE_VOICE_1_DRIVER_ABUSE_1,
- SFX_TRIAD_MALE_VOICE_1_DRIVER_ABUSE_2,
- SFX_TRIAD_MALE_VOICE_1_DRIVER_ABUSE_3,
- SFX_TRIAD_MALE_VOICE_1_DRIVER_ABUSE_4,
- SFX_TRIAD_MALE_VOICE_1_DRIVER_ABUSE_5,
- SFX_TRIAD_MALE_VOICE_1_DRIVER_ABUSE_6,
- SFX_TRIAD_MALE_VOICE_1_DRIVER_ABUSE_7,
- SFX_TRIAD_MALE_VOICE_1_CHAT_1,
- SFX_TRIAD_MALE_VOICE_1_CHAT_2,
- SFX_TRIAD_MALE_VOICE_1_CHAT_3,
- SFX_TRIAD_MALE_VOICE_1_CHAT_4,
- SFX_TRIAD_MALE_VOICE_1_CHAT_5,
- SFX_TRIAD_MALE_VOICE_1_CHAT_6,
- SFX_TRIAD_MALE_VOICE_1_CHAT_7,
- SFX_TRIAD_MALE_VOICE_1_CHAT_8,
- SFX_TRIAD_MALE_VOICE_1_DODGE_1,
- SFX_TRIAD_MALE_VOICE_1_DODGE_2,
- SFX_TRIAD_MALE_VOICE_1_DODGE_3,
- SFX_TRIAD_MALE_VOICE_1_DODGE_4,
- SFX_TRIAD_MALE_VOICE_1_EYING_1,
- SFX_TRIAD_MALE_VOICE_1_EYING_2,
- SFX_TRIAD_MALE_VOICE_1_EYING_3,
- SFX_TRIAD_MALE_VOICE_1_FIGHT_1,
- SFX_TRIAD_MALE_VOICE_1_FIGHT_2,
- SFX_TRIAD_MALE_VOICE_1_FIGHT_3,
- SFX_TRIAD_MALE_VOICE_1_FIGHT_4,
- SFX_TRIAD_MALE_VOICE_1_FIGHT_5,
- SFX_TRIAD_MALE_VOICE_1_GUN_COOL_1,
- SFX_TRIAD_MALE_VOICE_1_GUN_COOL_2,
- SFX_TRIAD_MALE_VOICE_1_GUN_COOL_3,
- SFX_TRIAD_MALE_VOICE_1_CARJACKED_1,
- SFX_TRIAD_MALE_VOICE_1_CARJACKED_2,
- SFX_TRIAD_MALE_VOICE_1_CARJACKING_1,
- SFX_TRIAD_MALE_VOICE_1_CARJACKING_2,
- SFX_MAFIA_MALE_VOICE_1_DRIVER_ABUSE_1,
- SFX_MAFIA_MALE_VOICE_1_DRIVER_ABUSE_2,
- SFX_MAFIA_MALE_VOICE_1_DRIVER_ABUSE_3,
- SFX_MAFIA_MALE_VOICE_1_DRIVER_ABUSE_4,
- SFX_MAFIA_MALE_VOICE_1_DRIVER_ABUSE_5,
- SFX_MAFIA_MALE_VOICE_1_DRIVER_ABUSE_6,
- SFX_MAFIA_MALE_VOICE_1_CHAT_1,
- SFX_MAFIA_MALE_VOICE_1_CHAT_2,
- SFX_MAFIA_MALE_VOICE_1_CHAT_3,
- SFX_MAFIA_MALE_VOICE_1_CHAT_4,
- SFX_MAFIA_MALE_VOICE_1_CHAT_5,
- SFX_MAFIA_MALE_VOICE_1_CHAT_6,
- SFX_MAFIA_MALE_VOICE_1_CHAT_7,
- SFX_MAFIA_MALE_VOICE_1_DODGE_1,
- SFX_MAFIA_MALE_VOICE_1_DODGE_2,
- SFX_MAFIA_MALE_VOICE_1_DODGE_3,
- SFX_MAFIA_MALE_VOICE_1_DODGE_4,
- SFX_MAFIA_MALE_VOICE_1_DODGE_5,
- SFX_MAFIA_MALE_VOICE_1_EYING_1,
- SFX_MAFIA_MALE_VOICE_1_EYING_2,
- SFX_MAFIA_MALE_VOICE_1_EYING_3,
- SFX_MAFIA_MALE_VOICE_1_FIGHT_1,
- SFX_MAFIA_MALE_VOICE_1_FIGHT_2,
- SFX_MAFIA_MALE_VOICE_1_FIGHT_3,
- SFX_MAFIA_MALE_VOICE_1_FIGHT_4,
- SFX_MAFIA_MALE_VOICE_1_FIGHT_5,
- SFX_MAFIA_MALE_VOICE_1_CARJACKED_1,
- SFX_MAFIA_MALE_VOICE_1_CARJACKED_2,
- SFX_MAFIA_MALE_VOICE_1_CARJACKING_1,
- SFX_MAFIA_MALE_VOICE_1_CARJACKING_2,
- SFX_MAFIA_MALE_VOICE_2_DRIVER_ABUSE_1,
- SFX_MAFIA_MALE_VOICE_2_DRIVER_ABUSE_2,
- SFX_MAFIA_MALE_VOICE_2_DRIVER_ABUSE_3,
- SFX_MAFIA_MALE_VOICE_2_DRIVER_ABUSE_4,
- SFX_MAFIA_MALE_VOICE_2_DRIVER_ABUSE_5,
- SFX_MAFIA_MALE_VOICE_2_DRIVER_ABUSE_6,
- SFX_MAFIA_MALE_VOICE_2_CHAT_1,
- SFX_MAFIA_MALE_VOICE_2_CHAT_2,
- SFX_MAFIA_MALE_VOICE_2_CHAT_3,
- SFX_MAFIA_MALE_VOICE_2_CHAT_4,
- SFX_MAFIA_MALE_VOICE_2_CHAT_5,
- SFX_MAFIA_MALE_VOICE_2_CHAT_6,
- SFX_MAFIA_MALE_VOICE_2_CHAT_7,
- SFX_MAFIA_MALE_VOICE_2_DODGE_1,
- SFX_MAFIA_MALE_VOICE_2_DODGE_2,
- SFX_MAFIA_MALE_VOICE_2_DODGE_3,
- SFX_MAFIA_MALE_VOICE_2_DODGE_4,
- SFX_MAFIA_MALE_VOICE_2_DODGE_5,
- SFX_MAFIA_MALE_VOICE_2_EYING_1,
- SFX_MAFIA_MALE_VOICE_2_EYING_2,
- SFX_MAFIA_MALE_VOICE_2_EYING_3,
- SFX_MAFIA_MALE_VOICE_2_FIGHT_1,
- SFX_MAFIA_MALE_VOICE_2_FIGHT_2,
- SFX_MAFIA_MALE_VOICE_2_FIGHT_3,
- SFX_MAFIA_MALE_VOICE_2_FIGHT_4,
- SFX_MAFIA_MALE_VOICE_2_FIGHT_5,
- SFX_MAFIA_MALE_VOICE_2_CARJACKED_1,
- SFX_MAFIA_MALE_VOICE_2_CARJACKED_2,
- SFX_MAFIA_MALE_VOICE_2_CARJACKING_1,
- SFX_MAFIA_MALE_VOICE_2_CARJACKING_2,
- SFX_MAFIA_MALE_VOICE_3_DRIVER_ABUSE_1,
- SFX_MAFIA_MALE_VOICE_3_DRIVER_ABUSE_2,
- SFX_MAFIA_MALE_VOICE_3_DRIVER_ABUSE_3,
- SFX_MAFIA_MALE_VOICE_3_DRIVER_ABUSE_4,
- SFX_MAFIA_MALE_VOICE_3_DRIVER_ABUSE_5,
- SFX_MAFIA_MALE_VOICE_3_DRIVER_ABUSE_6,
- SFX_MAFIA_MALE_VOICE_3_CHAT_1,
- SFX_MAFIA_MALE_VOICE_3_CHAT_2,
- SFX_MAFIA_MALE_VOICE_3_CHAT_3,
- SFX_MAFIA_MALE_VOICE_3_CHAT_4,
- SFX_MAFIA_MALE_VOICE_3_CHAT_5,
- SFX_MAFIA_MALE_VOICE_3_CHAT_6,
- SFX_MAFIA_MALE_VOICE_3_CHAT_7,
- SFX_MAFIA_MALE_VOICE_3_DODGE_1,
- SFX_MAFIA_MALE_VOICE_3_DODGE_2,
- SFX_MAFIA_MALE_VOICE_3_DODGE_3,
- SFX_MAFIA_MALE_VOICE_3_DODGE_4,
- SFX_MAFIA_MALE_VOICE_3_DODGE_5,
- SFX_MAFIA_MALE_VOICE_3_EYING_1,
- SFX_MAFIA_MALE_VOICE_3_EYING_2,
- SFX_MAFIA_MALE_VOICE_3_EYING_3,
- SFX_MAFIA_MALE_VOICE_3_FIGHT_1,
- SFX_MAFIA_MALE_VOICE_3_FIGHT_2,
- SFX_MAFIA_MALE_VOICE_3_FIGHT_3,
- SFX_MAFIA_MALE_VOICE_3_FIGHT_4,
- SFX_MAFIA_MALE_VOICE_3_FIGHT_5,
- SFX_MAFIA_MALE_VOICE_3_CARJACKED_1,
- SFX_MAFIA_MALE_VOICE_3_CARJACKED_2,
- SFX_MAFIA_MALE_VOICE_3_CARJACKING_1,
- SFX_MAFIA_MALE_VOICE_3_CARJACKING_2,
- SFX_YAKUZA_MALE_VOICE_1_DRIVER_ABUSE_1,
- SFX_YAKUZA_MALE_VOICE_1_DRIVER_ABUSE_2,
- SFX_YAKUZA_MALE_VOICE_1_DRIVER_ABUSE_3,
- SFX_YAKUZA_MALE_VOICE_1_DRIVER_ABUSE_4,
- SFX_YAKUZA_MALE_VOICE_1_DRIVER_ABUSE_5,
- SFX_YAKUZA_MALE_VOICE_1_DRIVER_ABUSE_6,
- SFX_YAKUZA_MALE_VOICE_1_CHAT_1,
- SFX_YAKUZA_MALE_VOICE_1_CHAT_2,
- SFX_YAKUZA_MALE_VOICE_1_CHAT_3,
- SFX_YAKUZA_MALE_VOICE_1_CHAT_4,
- SFX_YAKUZA_MALE_VOICE_1_CHAT_5,
- SFX_YAKUZA_MALE_VOICE_1_DODGE_1,
- SFX_YAKUZA_MALE_VOICE_1_DODGE_2,
- SFX_YAKUZA_MALE_VOICE_1_DODGE_3,
- SFX_YAKUZA_MALE_VOICE_1_DODGE_4,
- SFX_YAKUZA_MALE_VOICE_1_FIGHT_1,
- SFX_YAKUZA_MALE_VOICE_1_FIGHT_2,
- SFX_YAKUZA_MALE_VOICE_1_FIGHT_3,
- SFX_YAKUZA_MALE_VOICE_1_FIGHT_4,
- SFX_YAKUZA_MALE_VOICE_1_FIGHT_5,
- SFX_YAKUZA_MALE_VOICE_1_CARJACKED_1,
- SFX_YAKUZA_MALE_VOICE_1_CARJACKED_2,
- SFX_YAKUZA_MALE_VOICE_1_CARJACKING_1,
- SFX_YAKUZA_MALE_VOICE_1_CARJACKING_2,
- SFX_YAKUZA_MALE_VOICE_2_DRIVER_ABUSE_1,
- SFX_YAKUZA_MALE_VOICE_2_DRIVER_ABUSE_2,
- SFX_YAKUZA_MALE_VOICE_2_DRIVER_ABUSE_3,
- SFX_YAKUZA_MALE_VOICE_2_DRIVER_ABUSE_4,
- SFX_YAKUZA_MALE_VOICE_2_DRIVER_ABUSE_5,
- SFX_YAKUZA_MALE_VOICE_2_DRIVER_ABUSE_6,
- SFX_YAKUZA_MALE_VOICE_2_CHAT_1,
- SFX_YAKUZA_MALE_VOICE_2_CHAT_2,
- SFX_YAKUZA_MALE_VOICE_2_CHAT_3,
- SFX_YAKUZA_MALE_VOICE_2_CHAT_4,
- SFX_YAKUZA_MALE_VOICE_2_CHAT_5,
- SFX_YAKUZA_MALE_VOICE_2_DODGE_1,
- SFX_YAKUZA_MALE_VOICE_2_DODGE_2,
- SFX_YAKUZA_MALE_VOICE_2_DODGE_3,
- SFX_YAKUZA_MALE_VOICE_2_DODGE_4,
- SFX_YAKUZA_MALE_VOICE_2_FIGHT_1,
- SFX_YAKUZA_MALE_VOICE_2_FIGHT_2,
- SFX_YAKUZA_MALE_VOICE_2_FIGHT_3,
- SFX_YAKUZA_MALE_VOICE_2_FIGHT_4,
- SFX_YAKUZA_MALE_VOICE_2_FIGHT_5,
- SFX_YAKUZA_MALE_VOICE_2_CARJACKED_1,
- SFX_YAKUZA_MALE_VOICE_2_CARJACKED_2,
- SFX_YAKUZA_MALE_VOICE_2_CARJACKING_1,
- SFX_YAKUZA_MALE_VOICE_2_CARJACKING_2,
- SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_DRIVER_ABUSE_1,
- SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_DRIVER_ABUSE_2,
- SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_DRIVER_ABUSE_3,
- SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_DRIVER_ABUSE_4,
- SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_CHAT_1,
- SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_CHAT_2,
- SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_CHAT_3,
- SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_CHAT_4,
- SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_CHAT_5,
- SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_CHAT_6,
- SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_CHAT_7,
- SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_DODGE_1,
- SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_DODGE_2,
- SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_DODGE_3,
- SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_DODGE_4,
- SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_DODGE_5,
- SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_EYING_1,
- SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_EYING_2,
- SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_EYING_3,
- SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_FIGHT_1,
- SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_FIGHT_2,
- SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_FIGHT_3,
- SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_FIGHT_4,
- SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_FIGHT_5,
- SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_GUN_PANIC_1,
- SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_GUN_PANIC_2,
- SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_GUN_PANIC_3,
- SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_CARJACKED_1,
- SFX_ASIAN_TAXI_DRIVER_VOICE_1_DRIVER_ABUSE_1,
- SFX_ASIAN_TAXI_DRIVER_VOICE_1_DRIVER_ABUSE_2,
- SFX_ASIAN_TAXI_DRIVER_VOICE_1_DRIVER_ABUSE_3,
- SFX_ASIAN_TAXI_DRIVER_VOICE_1_DRIVER_ABUSE_4,
- SFX_ASIAN_TAXI_DRIVER_VOICE_1_DRIVER_ABUSE_5,
- SFX_ASIAN_TAXI_DRIVER_VOICE_1_DRIVER_ABUSE_6,
- SFX_ASIAN_TAXI_DRIVER_VOICE_1_CARJACKED_1,
- SFX_ASIAN_TAXI_DRIVER_VOICE_1_CARJACKED_2,
- SFX_ASIAN_TAXI_DRIVER_VOICE_1_CARJACKED_3,
- SFX_ASIAN_TAXI_DRIVER_VOICE_1_CARJACKED_4,
- SFX_ASIAN_TAXI_DRIVER_VOICE_1_CARJACKED_5,
- SFX_ASIAN_TAXI_DRIVER_VOICE_1_CARJACKED_6,
- SFX_ASIAN_TAXI_DRIVER_VOICE_1_CARJACKED_7,
- SFX_ASIAN_TAXI_DRIVER_VOICE_2_DRIVER_ABUSE_1,
- SFX_ASIAN_TAXI_DRIVER_VOICE_2_DRIVER_ABUSE_2,
- SFX_ASIAN_TAXI_DRIVER_VOICE_2_DRIVER_ABUSE_3,
- SFX_ASIAN_TAXI_DRIVER_VOICE_2_DRIVER_ABUSE_4,
- SFX_ASIAN_TAXI_DRIVER_VOICE_2_DRIVER_ABUSE_5,
- SFX_ASIAN_TAXI_DRIVER_VOICE_2_DRIVER_ABUSE_6,
- SFX_ASIAN_TAXI_DRIVER_VOICE_2_CARJACKED_1,
- SFX_ASIAN_TAXI_DRIVER_VOICE_2_CARJACKED_2,
- SFX_ASIAN_TAXI_DRIVER_VOICE_2_CARJACKED_3,
- SFX_ASIAN_TAXI_DRIVER_VOICE_2_CARJACKED_4,
- SFX_ASIAN_TAXI_DRIVER_VOICE_2_CARJACKED_5,
- SFX_ASIAN_TAXI_DRIVER_VOICE_2_CARJACKED_6,
- SFX_ASIAN_TAXI_DRIVER_VOICE_2_CARJACKED_7,
- SFX_SECURITY_GUARD_VOICE_1_DRIVER_ABUSE_1,
- SFX_SECURITY_GUARD_VOICE_1_DRIVER_ABUSE_2,
- SFX_SECURITY_GUARD_VOICE_1_DRIVER_ABUSE_3,
- SFX_SECURITY_GUARD_VOICE_1_DRIVER_ABUSE_4,
- SFX_SECURITY_GUARD_VOICE_1_DRIVER_ABUSE_5,
- SFX_SECURITY_GUARD_VOICE_1_DRIVER_ABUSE_6,
- SFX_SECURITY_GUARD_VOICE_1_FIGHT_1,
- SFX_SECURITY_GUARD_VOICE_1_FIGHT_2,
- SFX_SECURITY_GUARD_VOICE_1_GUN_COOL_1,
- SFX_SECURITY_GUARD_VOICE_1_GUN_COOL_2,
- SFX_SECURITY_GUARD_VOICE_1_GUN_PANIC_1,
- SFX_SECURITY_GUARD_VOICE_1_RUN_FROM_FIGHT_1,
- SFX_BLACK_PROSTITUTE_VOICE_1_CHAT_1,
- SFX_BLACK_PROSTITUTE_VOICE_1_CHAT_2,
- SFX_BLACK_PROSTITUTE_VOICE_1_CHAT_3,
- SFX_BLACK_PROSTITUTE_VOICE_1_CHAT_4,
- SFX_BLACK_PROSTITUTE_VOICE_1_DODGE_1,
- SFX_BLACK_PROSTITUTE_VOICE_1_DODGE_2,
- SFX_BLACK_PROSTITUTE_VOICE_1_DODGE_3,
- SFX_BLACK_PROSTITUTE_VOICE_1_MUGGED_1,
- SFX_BLACK_PROSTITUTE_VOICE_1_DRIVER_ABUSE_1,
- SFX_BLACK_PROSTITUTE_VOICE_1_DRIVER_ABUSE_2,
- SFX_BLACK_PROSTITUTE_VOICE_1_DRIVER_ABUSE_3,
- SFX_BLACK_PROSTITUTE_VOICE_1_DRIVER_ABUSE_4,
- SFX_BLACK_PROSTITUTE_VOICE_1_FIGHT_1,
- SFX_BLACK_PROSTITUTE_VOICE_1_FIGHT_2,
- SFX_BLACK_PROSTITUTE_VOICE_1_FIGHT_3,
- SFX_BLACK_PROSTITUTE_VOICE_1_FIGHT_4,
- SFX_BLACK_PROSTITUTE_VOICE_1_SOLICIT_1,
- SFX_BLACK_PROSTITUTE_VOICE_1_SOLICIT_2,
- SFX_BLACK_PROSTITUTE_VOICE_1_SOLICIT_3,
- SFX_BLACK_PROSTITUTE_VOICE_1_SOLICIT_4,
- SFX_BLACK_PROSTITUTE_VOICE_1_SOLICIT_5,
- SFX_BLACK_PROSTITUTE_VOICE_1_SOLICIT_6,
- SFX_BLACK_PROSTITUTE_VOICE_1_SOLICIT_7,
- SFX_BLACK_PROSTITUTE_VOICE_1_SOLICIT_8,
- SFX_BLACK_PROSTITUTE_VOICE_1_GUN_COOL_1,
- SFX_BLACK_PROSTITUTE_VOICE_1_GUN_COOL_2,
- SFX_BLACK_PROSTITUTE_VOICE_1_GUN_COOL_3,
- SFX_BLACK_PROSTITUTE_VOICE_1_GUN_COOL_4,
- SFX_BLACK_PROSTITUTE_VOICE_2_CHAT_1,
- SFX_BLACK_PROSTITUTE_VOICE_2_CHAT_2,
- SFX_BLACK_PROSTITUTE_VOICE_2_CHAT_3,
- SFX_BLACK_PROSTITUTE_VOICE_2_CHAT_4,
- SFX_BLACK_PROSTITUTE_VOICE_2_DODGE_1,
- SFX_BLACK_PROSTITUTE_VOICE_2_DODGE_2,
- SFX_BLACK_PROSTITUTE_VOICE_2_DODGE_3,
- SFX_BLACK_PROSTITUTE_VOICE_2_MUGGED_1,
- SFX_BLACK_PROSTITUTE_VOICE_2_DRIVER_ABUSE_1,
- SFX_BLACK_PROSTITUTE_VOICE_2_DRIVER_ABUSE_2,
- SFX_BLACK_PROSTITUTE_VOICE_2_DRIVER_ABUSE_3,
- SFX_BLACK_PROSTITUTE_VOICE_2_DRIVER_ABUSE_4,
- SFX_BLACK_PROSTITUTE_VOICE_2_FIGHT_1,
- SFX_BLACK_PROSTITUTE_VOICE_2_FIGHT_2,
- SFX_BLACK_PROSTITUTE_VOICE_2_FIGHT_3,
- SFX_BLACK_PROSTITUTE_VOICE_2_FIGHT_4,
- SFX_BLACK_PROSTITUTE_VOICE_2_SOLICIT_1,
- SFX_BLACK_PROSTITUTE_VOICE_2_SOLICIT_2,
- SFX_BLACK_PROSTITUTE_VOICE_2_SOLICIT_3,
- SFX_BLACK_PROSTITUTE_VOICE_2_SOLICIT_4,
- SFX_BLACK_PROSTITUTE_VOICE_2_SOLICIT_5,
- SFX_BLACK_PROSTITUTE_VOICE_2_SOLICIT_6,
- SFX_BLACK_PROSTITUTE_VOICE_2_SOLICIT_7,
- SFX_BLACK_PROSTITUTE_VOICE_2_SOLICIT_8,
- SFX_BLACK_PROSTITUTE_VOICE_2_GUN_COOL_1,
- SFX_BLACK_PROSTITUTE_VOICE_2_GUN_COOL_2,
- SFX_BLACK_PROSTITUTE_VOICE_2_GUN_COOL_3,
- SFX_BLACK_PROSTITUTE_VOICE_2_GUN_COOL_4,
- SFX_WHITE_PROSTITUTE_VOICE_1_CHAT_1,
- SFX_WHITE_PROSTITUTE_VOICE_1_CHAT_2,
- SFX_WHITE_PROSTITUTE_VOICE_1_CHAT_3,
- SFX_WHITE_PROSTITUTE_VOICE_1_CHAT_4,
- SFX_WHITE_PROSTITUTE_VOICE_1_DODGE_1,
- SFX_WHITE_PROSTITUTE_VOICE_1_DODGE_2,
- SFX_WHITE_PROSTITUTE_VOICE_1_DODGE_3,
- SFX_WHITE_PROSTITUTE_VOICE_1_MUGGED_1,
- SFX_WHITE_PROSTITUTE_VOICE_1_MUGGED_2,
- SFX_WHITE_PROSTITUTE_VOICE_1_DRIVER_ABUSE_1,
- SFX_WHITE_PROSTITUTE_VOICE_1_DRIVER_ABUSE_2,
- SFX_WHITE_PROSTITUTE_VOICE_1_DRIVER_ABUSE_3,
- SFX_WHITE_PROSTITUTE_VOICE_1_DRIVER_ABUSE_4,
- SFX_WHITE_PROSTITUTE_VOICE_1_FIGHT_1,
- SFX_WHITE_PROSTITUTE_VOICE_1_FIGHT_2,
- SFX_WHITE_PROSTITUTE_VOICE_1_FIGHT_3,
- SFX_WHITE_PROSTITUTE_VOICE_1_FIGHT_4,
- SFX_WHITE_PROSTITUTE_VOICE_1_SOLICIT_1,
- SFX_WHITE_PROSTITUTE_VOICE_1_SOLICIT_2,
- SFX_WHITE_PROSTITUTE_VOICE_1_SOLICIT_3,
- SFX_WHITE_PROSTITUTE_VOICE_1_SOLICIT_4,
- SFX_WHITE_PROSTITUTE_VOICE_1_SOLICIT_5,
- SFX_WHITE_PROSTITUTE_VOICE_1_SOLICIT_6,
- SFX_WHITE_PROSTITUTE_VOICE_1_SOLICIT_7,
- SFX_WHITE_PROSTITUTE_VOICE_1_SOLICIT_8,
- SFX_WHITE_PROSTITUTE_VOICE_2_CHAT_1,
- SFX_WHITE_PROSTITUTE_VOICE_2_CHAT_2,
- SFX_WHITE_PROSTITUTE_VOICE_2_CHAT_3,
- SFX_WHITE_PROSTITUTE_VOICE_2_CHAT_4,
- SFX_WHITE_PROSTITUTE_VOICE_2_DODGE_1,
- SFX_WHITE_PROSTITUTE_VOICE_2_DODGE_2,
- SFX_WHITE_PROSTITUTE_VOICE_2_DODGE_3,
- SFX_WHITE_PROSTITUTE_VOICE_2_MUGGED_1,
- SFX_WHITE_PROSTITUTE_VOICE_2_MUGGED_2,
- SFX_WHITE_PROSTITUTE_VOICE_2_DRIVER_ABUSE_1,
- SFX_WHITE_PROSTITUTE_VOICE_2_DRIVER_ABUSE_2,
- SFX_WHITE_PROSTITUTE_VOICE_2_DRIVER_ABUSE_3,
- SFX_WHITE_PROSTITUTE_VOICE_2_DRIVER_ABUSE_4,
- SFX_WHITE_PROSTITUTE_VOICE_2_FIGHT_1,
- SFX_WHITE_PROSTITUTE_VOICE_2_FIGHT_2,
- SFX_WHITE_PROSTITUTE_VOICE_2_FIGHT_3,
- SFX_WHITE_PROSTITUTE_VOICE_2_FIGHT_4,
- SFX_WHITE_PROSTITUTE_VOICE_2_SOLICIT_1,
- SFX_WHITE_PROSTITUTE_VOICE_2_SOLICIT_2,
- SFX_WHITE_PROSTITUTE_VOICE_2_SOLICIT_3,
- SFX_WHITE_PROSTITUTE_VOICE_2_SOLICIT_4,
- SFX_WHITE_PROSTITUTE_VOICE_2_SOLICIT_5,
- SFX_WHITE_PROSTITUTE_VOICE_2_SOLICIT_6,
- SFX_WHITE_PROSTITUTE_VOICE_2_SOLICIT_7,
- SFX_WHITE_PROSTITUTE_VOICE_2_SOLICIT_8,
- SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_CHAT_1,
- SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_CHAT_2,
- SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_CHAT_3,
- SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_CHAT_4,
- SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_CHAT_5,
- SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_CHAT_6,
- SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_DODGE_1,
- SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_DODGE_2,
- SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_DODGE_3,
- SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_DODGE_4,
- SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_DODGE_5,
- SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_DODGE_6,
- SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_DODGE_7,
- SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_CARJACKED_1,
- SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_CARJACKED_2,
- SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_MUGGED_1,
- SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_MUGGED_2,
- SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_DRIVER_ABUSE_1,
- SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_DRIVER_ABUSE_2,
- SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_DRIVER_ABUSE_3,
- SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_DRIVER_ABUSE_4,
- SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_DRIVER_ABUSE_5,
- SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_DRIVER_ABUSE_6,
- SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_SHOCKED_1,
- SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_SHOCKED_2,
- SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_SHOCKED_3,
- SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_SHOCKED_4,
- SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_CHAT_1,
- SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_CHAT_2,
- SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_CHAT_3,
- SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_CHAT_4,
- SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_CHAT_5,
- SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_CHAT_6,
- SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_CHAT_7,
- SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_DODGE_1,
- SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_DODGE_2,
- SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_DODGE_3,
- SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_DODGE_4,
- SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_DODGE_5,
- SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_DODGE_6,
- SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_CARJACKED_1,
- SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_CARJACKED_2,
- SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_MUGGED_1,
- SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_MUGGED_2,
- SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_DRIVER_ABUSE_1,
- SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_DRIVER_ABUSE_2,
- SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_DRIVER_ABUSE_3,
- SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_DRIVER_ABUSE_4,
- SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_DRIVER_ABUSE_5,
- SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_DRIVER_ABUSE_6,
- SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_DRIVER_ABUSE_7,
- SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_SHOCKED_1,
- SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_SHOCKED_2,
- SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_SHOCKED_3,
- SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_SHOCKED_4,
- SFX_GENERIC_MALE_DEATH_1,
- SFX_GENERIC_MALE_DEATH_2,
- SFX_GENERIC_MALE_DEATH_3,
- SFX_GENERIC_MALE_DEATH_4,
- SFX_GENERIC_MALE_DEATH_5,
- SFX_GENERIC_MALE_DEATH_6,
- SFX_GENERIC_MALE_DEATH_7,
- SFX_GENERIC_MALE_DEATH_8,
+ SFX_GENERIC_FEMALE_PANIC_9,
+ SFX_GENERIC_FEMALE_PANIC_10,
+ SFX_GENERIC_FEMALE_PANIC_11,
+ SFX_GENERIC_FEMALE_PANIC_12,
+ SFX_GENERIC_FEMALE_PANIC_13,
+ SFX_GENERIC_FEMALE_PANIC_14,
+ SFX_GENERIC_FEMALE_PANIC_15,
+ SFX_GENERIC_FEMALE_PANIC_16,
+ SFX_GENERIC_FEMALE_PANIC_17,
+ SFX_GENERIC_FEMALE_PANIC_18,
+ SFX_GENERIC_FEMALE_PANIC_19,
+ SFX_GENERIC_FEMALE_PANIC_20,
+ SFX_GENERIC_FEMALE_PANIC_21,
+ SFX_GENERIC_FEMALE_PANIC_22,
+ SFX_GENERIC_FEMALE_PANIC_23,
+ SFX_GENERIC_FEMALE_PANIC_24,
+ SFX_GENERIC_FEMALE_PANIC_25,
+ SFX_GENERIC_FEMALE_PANIC_26,
+ SFX_GENERIC_FEMALE_PANIC_27,
+
SFX_GENERIC_MALE_FIRE_1,
SFX_GENERIC_MALE_FIRE_2,
SFX_GENERIC_MALE_FIRE_3,
@@ -2965,6 +3106,71 @@ enum eSfxSample
SFX_GENERIC_MALE_FIRE_6,
SFX_GENERIC_MALE_FIRE_7,
SFX_GENERIC_MALE_FIRE_8,
+ SFX_GENERIC_MALE_FIRE_9,
+ SFX_GENERIC_MALE_FIRE_10,
+ SFX_GENERIC_MALE_FIRE_11,
+ SFX_GENERIC_MALE_FIRE_12,
+ SFX_GENERIC_MALE_FIRE_13,
+ SFX_GENERIC_MALE_FIRE_14,
+ SFX_GENERIC_MALE_FIRE_15,
+ SFX_GENERIC_MALE_FIRE_16,
+ SFX_GENERIC_MALE_FIRE_17,
+ SFX_GENERIC_MALE_FIRE_18,
+ SFX_GENERIC_MALE_FIRE_19,
+ SFX_GENERIC_MALE_FIRE_20,
+ SFX_GENERIC_MALE_FIRE_21,
+ SFX_GENERIC_MALE_FIRE_22,
+ SFX_GENERIC_MALE_FIRE_23,
+ SFX_GENERIC_MALE_FIRE_24,
+ SFX_GENERIC_MALE_FIRE_25,
+ SFX_GENERIC_MALE_FIRE_26,
+ SFX_GENERIC_MALE_FIRE_27,
+ SFX_GENERIC_MALE_FIRE_28,
+ SFX_GENERIC_MALE_FIRE_29,
+ SFX_GENERIC_MALE_FIRE_30,
+ SFX_GENERIC_MALE_FIRE_31,
+ SFX_GENERIC_MALE_FIRE_32,
+ SFX_GENERIC_MALE_DEATH_1,
+ SFX_GENERIC_MALE_DEATH_2,
+ SFX_GENERIC_MALE_DEATH_3,
+ SFX_GENERIC_MALE_DEATH_4,
+ SFX_GENERIC_MALE_DEATH_5,
+ SFX_GENERIC_MALE_DEATH_6,
+ SFX_GENERIC_MALE_DEATH_7,
+ SFX_GENERIC_MALE_DEATH_8,
+ SFX_GENERIC_MALE_DEATH_9,
+ SFX_GENERIC_MALE_DEATH_10,
+ SFX_GENERIC_MALE_DEATH_11,
+ SFX_GENERIC_MALE_DEATH_12,
+ SFX_GENERIC_MALE_DEATH_13,
+ SFX_GENERIC_MALE_DEATH_14,
+ SFX_GENERIC_MALE_DEATH_15,
+ SFX_GENERIC_MALE_DEATH_16,
+ SFX_GENERIC_MALE_DEATH_17,
+ SFX_GENERIC_MALE_DEATH_18,
+ SFX_GENERIC_MALE_DEATH_19,
+ SFX_GENERIC_MALE_DEATH_20,
+ SFX_GENERIC_MALE_DEATH_21,
+ SFX_GENERIC_MALE_DEATH_22,
+ SFX_GENERIC_MALE_DEATH_23,
+ SFX_GENERIC_MALE_DEATH_24,
+ SFX_GENERIC_MALE_DEATH_25,
+ SFX_GENERIC_MALE_DEATH_26,
+ SFX_GENERIC_MALE_DEATH_27,
+ SFX_GENERIC_MALE_DEATH_28,
+ SFX_GENERIC_MALE_DEATH_29,
+ SFX_GENERIC_MALE_DEATH_30,
+ SFX_GENERIC_MALE_DEATH_31,
+ SFX_GENERIC_MALE_DEATH_32,
+ SFX_GENERIC_MALE_DEATH_33,
+ SFX_GENERIC_MALE_DEATH_34,
+ SFX_GENERIC_MALE_DEATH_35,
+ SFX_GENERIC_MALE_DEATH_36,
+ SFX_GENERIC_MALE_DEATH_37,
+ SFX_GENERIC_MALE_DEATH_38,
+ SFX_GENERIC_MALE_DEATH_39,
+ SFX_GENERIC_MALE_DEATH_40,
+ SFX_GENERIC_MALE_DEATH_41,
SFX_GENERIC_MALE_GRUNT_1,
SFX_GENERIC_MALE_GRUNT_2,
SFX_GENERIC_MALE_GRUNT_3,
@@ -2980,174 +3186,6942 @@ enum eSfxSample
SFX_GENERIC_MALE_GRUNT_13,
SFX_GENERIC_MALE_GRUNT_14,
SFX_GENERIC_MALE_GRUNT_15,
+ SFX_GENERIC_MALE_GRUNT_16,
+ SFX_GENERIC_MALE_GRUNT_17,
+ SFX_GENERIC_MALE_GRUNT_18,
+ SFX_GENERIC_MALE_GRUNT_19,
+ SFX_GENERIC_MALE_GRUNT_20,
+ SFX_GENERIC_MALE_GRUNT_21,
+ SFX_GENERIC_MALE_GRUNT_22,
+ SFX_GENERIC_MALE_GRUNT_23,
+ SFX_GENERIC_MALE_GRUNT_24,
+ SFX_GENERIC_MALE_GRUNT_25,
+ SFX_GENERIC_MALE_GRUNT_26,
+ SFX_GENERIC_MALE_GRUNT_27,
+ SFX_GENERIC_MALE_GRUNT_28,
+ SFX_GENERIC_MALE_GRUNT_29,
+ SFX_GENERIC_MALE_GRUNT_30,
+ SFX_GENERIC_MALE_GRUNT_31,
+ SFX_GENERIC_MALE_GRUNT_32,
+ SFX_GENERIC_MALE_GRUNT_33,
+ SFX_GENERIC_MALE_GRUNT_34,
+ SFX_GENERIC_MALE_GRUNT_35,
+ SFX_GENERIC_MALE_GRUNT_36,
+ SFX_GENERIC_MALE_GRUNT_37,
+ SFX_GENERIC_MALE_GRUNT_38,
+ SFX_GENERIC_MALE_GRUNT_39,
+ SFX_GENERIC_MALE_GRUNT_40,
+ SFX_GENERIC_MALE_GRUNT_41,
SFX_GENERIC_MALE_PANIC_1,
SFX_GENERIC_MALE_PANIC_2,
SFX_GENERIC_MALE_PANIC_3,
SFX_GENERIC_MALE_PANIC_4,
SFX_GENERIC_MALE_PANIC_5,
SFX_GENERIC_MALE_PANIC_6,
- SFX_WHITE_FAT_MALE_VOICE_1_CHAT_1,
- SFX_WHITE_FAT_MALE_VOICE_1_CHAT_2,
- SFX_WHITE_FAT_MALE_VOICE_1_CHAT_3,
- SFX_WHITE_FAT_MALE_VOICE_1_CHAT_4,
- SFX_WHITE_FAT_MALE_VOICE_1_CHAT_5,
- SFX_WHITE_FAT_MALE_VOICE_1_CHAT_6,
- SFX_WHITE_FAT_MALE_VOICE_1_CHAT_7,
- SFX_WHITE_FAT_MALE_VOICE_1_CHAT_8,
- SFX_WHITE_FAT_MALE_VOICE_1_CHAT_9,
- SFX_WHITE_FAT_MALE_VOICE_1_DODGE_1,
- SFX_WHITE_FAT_MALE_VOICE_1_DODGE_2,
- SFX_WHITE_FAT_MALE_VOICE_1_DODGE_3,
- SFX_WHITE_FAT_MALE_VOICE_1_DODGE_4,
- SFX_WHITE_FAT_MALE_VOICE_1_DODGE_5,
- SFX_WHITE_FAT_MALE_VOICE_1_DODGE_6,
- SFX_WHITE_FAT_MALE_VOICE_1_DODGE_7,
- SFX_WHITE_FAT_MALE_VOICE_1_DODGE_8,
- SFX_WHITE_FAT_MALE_VOICE_1_DODGE_9,
- SFX_WHITE_FAT_MALE_VOICE_1_CARJACKED_1,
- SFX_WHITE_FAT_MALE_VOICE_1_CARJACKED_2,
- SFX_WHITE_FAT_MALE_VOICE_1_CARJACKED_3,
- SFX_WHITE_FAT_MALE_VOICE_1_MUGGED_1,
- SFX_WHITE_FAT_MALE_VOICE_1_MUGGED_2,
- SFX_WHITE_FAT_MALE_VOICE_1_MUGGED_3,
- SFX_WHITE_FAT_MALE_VOICE_1_LOST_1,
- SFX_WHITE_FAT_MALE_VOICE_1_LOST_2,
- SFX_WHITE_FAT_MALE_VOICE_1_DRIVER_ABUSE_1,
- SFX_WHITE_FAT_MALE_VOICE_1_DRIVER_ABUSE_2,
- SFX_WHITE_FAT_MALE_VOICE_1_DRIVER_ABUSE_3,
- SFX_WHITE_FAT_MALE_VOICE_1_DRIVER_ABUSE_4,
- SFX_WHITE_FAT_MALE_VOICE_1_DRIVER_ABUSE_5,
- SFX_WHITE_FAT_MALE_VOICE_1_DRIVER_ABUSE_6,
- SFX_WHITE_FAT_MALE_VOICE_1_DRIVER_ABUSE_7,
- SFX_WHITE_FAT_MALE_VOICE_1_DRIVER_ABUSE_8,
- SFX_WHITE_FAT_MALE_VOICE_1_DRIVER_ABUSE_9,
- SFX_WHITE_FAT_FEMALE_VOICE_1_CHAT_1,
- SFX_WHITE_FAT_FEMALE_VOICE_1_CHAT_2,
- SFX_WHITE_FAT_FEMALE_VOICE_1_CHAT_3,
- SFX_WHITE_FAT_FEMALE_VOICE_1_CHAT_4,
- SFX_WHITE_FAT_FEMALE_VOICE_1_CHAT_5,
- SFX_WHITE_FAT_FEMALE_VOICE_1_CHAT_6,
- SFX_WHITE_FAT_FEMALE_VOICE_1_CHAT_7,
- SFX_WHITE_FAT_FEMALE_VOICE_1_CHAT_8,
- SFX_WHITE_FAT_FEMALE_VOICE_1_DODGE_1,
- SFX_WHITE_FAT_FEMALE_VOICE_1_DODGE_2,
- SFX_WHITE_FAT_FEMALE_VOICE_1_DODGE_3,
- SFX_WHITE_FAT_FEMALE_VOICE_1_DODGE_4,
- SFX_WHITE_FAT_FEMALE_VOICE_1_DODGE_5,
- SFX_WHITE_FAT_FEMALE_VOICE_1_DODGE_6,
- SFX_WHITE_FAT_FEMALE_VOICE_1_CARJACKED_1,
- SFX_WHITE_FAT_FEMALE_VOICE_1_CARJACKED_2,
- SFX_WHITE_FAT_FEMALE_VOICE_1_MUGGED_1,
- SFX_WHITE_FAT_FEMALE_VOICE_1_MUGGED_2,
- SFX_WHITE_FAT_FEMALE_VOICE_1_LOST_1,
- SFX_WHITE_FAT_FEMALE_VOICE_1_LOST_2,
- SFX_WHITE_FAT_FEMALE_VOICE_1_DRIVER_ABUSE_1,
- SFX_WHITE_FAT_FEMALE_VOICE_1_DRIVER_ABUSE_2,
- SFX_WHITE_FAT_FEMALE_VOICE_1_DRIVER_ABUSE_3,
- SFX_WHITE_FAT_FEMALE_VOICE_1_DRIVER_ABUSE_4,
- SFX_WHITE_FAT_FEMALE_VOICE_1_DRIVER_ABUSE_5,
- SFX_WHITE_FAT_FEMALE_VOICE_1_DRIVER_ABUSE_6,
- SFX_WHITE_FAT_FEMALE_VOICE_1_DRIVER_ABUSE_7,
- SFX_WHITE_FAT_FEMALE_VOICE_1_DRIVER_ABUSE_8,
- SFX_WHITE_FAT_FEMALE_VOICE_1_SHOCKED_1,
- SFX_WHITE_FAT_FEMALE_VOICE_1_SHOCKED_2,
- SFX_WHITE_FAT_FEMALE_VOICE_1_SHOCKED_3,
- SFX_WHITE_FAT_FEMALE_VOICE_1_SHOCKED_4,
- SFX_WHITE_CASUAL_FEMALE_VOICE_1_CHAT_1,
- SFX_WHITE_CASUAL_FEMALE_VOICE_1_CHAT_2,
- SFX_WHITE_CASUAL_FEMALE_VOICE_1_CHAT_3,
- SFX_WHITE_CASUAL_FEMALE_VOICE_1_CHAT_4,
- SFX_WHITE_CASUAL_FEMALE_VOICE_1_DODGE_1,
- SFX_WHITE_CASUAL_FEMALE_VOICE_1_DODGE_2,
- SFX_WHITE_CASUAL_FEMALE_VOICE_1_DODGE_3,
- SFX_WHITE_CASUAL_FEMALE_VOICE_1_CARJACKED_1,
- SFX_WHITE_CASUAL_FEMALE_VOICE_1_CARJACKED_2,
- SFX_WHITE_CASUAL_FEMALE_VOICE_1_MUGGED_1,
- SFX_WHITE_CASUAL_FEMALE_VOICE_1_DRIVER_ABUSE_1,
- SFX_WHITE_CASUAL_FEMALE_VOICE_1_DRIVER_ABUSE_2,
- SFX_WHITE_CASUAL_FEMALE_VOICE_1_DRIVER_ABUSE_3,
- SFX_WHITE_CASUAL_FEMALE_VOICE_1_DRIVER_ABUSE_4,
- SFX_WHITE_CASUAL_FEMALE_VOICE_1_DRIVER_ABUSE_5,
- SFX_WHITE_CASUAL_FEMALE_VOICE_1_DRIVER_ABUSE_6,
- SFX_WHITE_CASUAL_FEMALE_VOICE_1_DRIVER_ABUSE_7,
- SFX_WHITE_CASUAL_FEMALE_VOICE_1_DRIVER_ABUSE_8,
- SFX_WHITE_CASUAL_FEMALE_VOICE_1_SHOCKED_1,
- SFX_WHITE_CASUAL_FEMALE_VOICE_1_SHOCKED_2,
- SFX_WHITE_CASUAL_FEMALE_VOICE_1_GUN_PANIC_1,
- SFX_WHITE_CASUAL_FEMALE_VOICE_1_GUN_PANIC_2,
- SFX_WHITE_CASUAL_FEMALE_VOICE_1_RUN_FROM_FIGHT_1,
- SFX_WHITE_CASUAL_FEMALE_VOICE_1_RUN_FROM_FIGHT_2,
- SFX_DIABLO_MALE_VOICE_1_CHAT_1,
- SFX_DIABLO_MALE_VOICE_1_CHAT_2,
- SFX_DIABLO_MALE_VOICE_1_CHAT_3,
- SFX_DIABLO_MALE_VOICE_1_CHAT_4,
- SFX_DIABLO_MALE_VOICE_1_CHAT_5,
- SFX_DIABLO_MALE_VOICE_1_DODGE_1,
- SFX_DIABLO_MALE_VOICE_1_DODGE_2,
- SFX_DIABLO_MALE_VOICE_1_DODGE_3,
- SFX_DIABLO_MALE_VOICE_1_DODGE_4,
- SFX_DIABLO_MALE_VOICE_1_CARJACKED_1,
- SFX_DIABLO_MALE_VOICE_1_CARJACKED_2,
- SFX_DIABLO_MALE_VOICE_1_CARJACKING_1,
- SFX_DIABLO_MALE_VOICE_1_CARJACKING_2,
- SFX_DIABLO_MALE_VOICE_1_FIGHT_1,
- SFX_DIABLO_MALE_VOICE_1_FIGHT_2,
- SFX_DIABLO_MALE_VOICE_1_FIGHT_3,
- SFX_DIABLO_MALE_VOICE_1_FIGHT_4,
- SFX_DIABLO_MALE_VOICE_1_EYING_1,
- SFX_DIABLO_MALE_VOICE_1_EYING_2,
- SFX_DIABLO_MALE_VOICE_1_EYING_3,
- SFX_DIABLO_MALE_VOICE_1_EYING_4,
- SFX_DIABLO_MALE_VOICE_1_GUN_COOL_1,
- SFX_DIABLO_MALE_VOICE_1_GUN_COOL_2,
- SFX_DIABLO_MALE_VOICE_1_GUN_COOL_3,
- SFX_DIABLO_MALE_VOICE_1_GUN_COOL_4,
- SFX_DIABLO_MALE_VOICE_1_DRIVER_ABUSE_1,
- SFX_DIABLO_MALE_VOICE_1_DRIVER_ABUSE_2,
- SFX_DIABLO_MALE_VOICE_1_DRIVER_ABUSE_3,
- SFX_DIABLO_MALE_VOICE_1_DRIVER_ABUSE_4,
- SFX_DIABLO_MALE_VOICE_1_DRIVER_ABUSE_5,
- SFX_DIABLO_MALE_VOICE_2_CHAT_1,
- SFX_DIABLO_MALE_VOICE_2_CHAT_2,
- SFX_DIABLO_MALE_VOICE_2_CHAT_3,
- SFX_DIABLO_MALE_VOICE_2_CHAT_4,
- SFX_DIABLO_MALE_VOICE_2_CHAT_5,
- SFX_DIABLO_MALE_VOICE_2_DODGE_1,
- SFX_DIABLO_MALE_VOICE_2_DODGE_2,
- SFX_DIABLO_MALE_VOICE_2_DODGE_3,
- SFX_DIABLO_MALE_VOICE_2_DODGE_4,
- SFX_DIABLO_MALE_VOICE_2_CARJACKED_1,
- SFX_DIABLO_MALE_VOICE_2_CARJACKED_2,
- SFX_DIABLO_MALE_VOICE_2_CARJACKING_1,
- SFX_DIABLO_MALE_VOICE_2_CARJACKING_2,
- SFX_DIABLO_MALE_VOICE_2_FIGHT_1,
- SFX_DIABLO_MALE_VOICE_2_FIGHT_2,
- SFX_DIABLO_MALE_VOICE_2_FIGHT_3,
- SFX_DIABLO_MALE_VOICE_2_FIGHT_4,
- SFX_DIABLO_MALE_VOICE_2_EYING_1,
- SFX_DIABLO_MALE_VOICE_2_EYING_2,
- SFX_DIABLO_MALE_VOICE_2_EYING_3,
- SFX_DIABLO_MALE_VOICE_2_EYING_4,
- SFX_DIABLO_MALE_VOICE_2_GUN_COOL_1,
- SFX_DIABLO_MALE_VOICE_2_GUN_COOL_2,
- SFX_DIABLO_MALE_VOICE_2_GUN_COOL_3,
- SFX_DIABLO_MALE_VOICE_2_GUN_COOL_4,
- SFX_DIABLO_MALE_VOICE_2_DRIVER_ABUSE_1,
- SFX_DIABLO_MALE_VOICE_2_DRIVER_ABUSE_2,
- SFX_DIABLO_MALE_VOICE_2_DRIVER_ABUSE_3,
- SFX_DIABLO_MALE_VOICE_2_DRIVER_ABUSE_4,
- SFX_DIABLO_MALE_VOICE_2_DRIVER_ABUSE_5,
- SFX_AMMU_D,
- SFX_AMMU_E,
- SFX_AMMU_F,
+ SFX_GENERIC_MALE_PANIC_7,
+ SFX_GENERIC_MALE_PANIC_8,
+ SFX_GENERIC_MALE_PANIC_9,
+ SFX_GENERIC_MALE_PANIC_10,
+ SFX_GENERIC_MALE_PANIC_11,
+ SFX_GENERIC_MALE_PANIC_12,
+ SFX_GENERIC_MALE_PANIC_13,
+ SFX_GENERIC_MALE_PANIC_14,
+ SFX_GENERIC_MALE_PANIC_15,
+ SFX_GENERIC_MALE_PANIC_16,
+ SFX_GENERIC_MALE_PANIC_17,
+ SFX_GENERIC_MALE_PANIC_18,
+ SFX_GENERIC_MALE_PANIC_19,
+ SFX_GENERIC_MALE_PANIC_20,
+ SFX_GENERIC_MALE_PANIC_21,
+ SFX_GENERIC_MALE_PANIC_22,
+ SFX_GENERIC_MALE_PANIC_23,
+ SFX_GENERIC_MALE_PANIC_24,
+ SFX_GENERIC_MALE_PANIC_25,
+ SFX_GENERIC_MALE_PANIC_26,
+ SFX_GENERIC_MALE_PANIC_27,
+ SFX_GENERIC_MALE_PANIC_28,
+ SFX_GENERIC_MALE_PANIC_29,
+ SFX_GENERIC_MALE_PANIC_30,
+ SFX_GENERIC_MALE_PANIC_31,
+ SFX_GENERIC_MALE_PANIC_32,
+ SFX_GENERIC_MALE_PANIC_33,
+ SFX_GENERIC_MALE_PANIC_34,
+ SFX_GENERIC_MALE_PANIC_35,
+
+ SFX_MEDIC_VOICE_1_FIGHT_1,
+ SFX_MEDIC_VOICE_1_FIGHT_2,
+ SFX_MEDIC_VOICE_1_FIGHT_3,
+ SFX_MEDIC_VOICE_1_FIGHT_4,
+ SFX_MEDIC_VOICE_1_FIGHT_5,
+ SFX_MEDIC_VOICE_1_FIGHT_6,
+ SFX_MEDIC_VOICE_1_GET_OUT_VAN_CHAT_1,
+ SFX_MEDIC_VOICE_1_GET_OUT_VAN_CHAT_2,
+ SFX_MEDIC_VOICE_1_GET_OUT_VAN_CHAT_3,
+ SFX_MEDIC_VOICE_1_GET_OUT_VAN_CHAT_4,
+ SFX_MEDIC_VOICE_1_GET_OUT_VAN_CHAT_5,
+ SFX_MEDIC_VOICE_1_GET_OUT_VAN_CHAT_6,
+ SFX_MEDIC_VOICE_1_GET_OUT_VAN_CHAT_7,
+ SFX_MEDIC_VOICE_1_GET_OUT_VAN_CHAT_8,
+ SFX_MEDIC_VOICE_1_GET_OUT_VAN_CHAT_9,
+ SFX_MEDIC_VOICE_1_GET_OUT_VAN_CHAT_10,
+ SFX_MEDIC_VOICE_1_AT_VICTIM_1,
+ SFX_MEDIC_VOICE_1_AT_VICTIM_2,
+ SFX_MEDIC_VOICE_1_AT_VICTIM_3,
+ SFX_MEDIC_VOICE_1_AT_VICTIM_4,
+ SFX_MEDIC_VOICE_1_AT_VICTIM_5,
+ SFX_MEDIC_VOICE_1_AT_VICTIM_6,
+ SFX_MEDIC_VOICE_1_AT_VICTIM_7,
+ SFX_MEDIC_VOICE_1_AT_VICTIM_8,
+ SFX_MEDIC_VOICE_1_AT_VICTIM_9,
+ SFX_MEDIC_VOICE_1_AT_VICTIM_10,
+ SFX_MEDIC_VOICE_1_AT_VICTIM_11,
+ SFX_MEDIC_VOICE_1_AT_VICTIM_12,
+ SFX_MEDIC_VOICE_1_AT_VICTIM_13,
+ SFX_MEDIC_VOICE_1_AT_VICTIM_14,
+ SFX_MEDIC_VOICE_1_AT_VICTIM_15,
+ SFX_MEDIC_VOICE_1_AT_VICTIM_16,
+ SFX_MEDIC_VOICE_1_AT_VICTIM_17,
+
+ SFX_MEDIC_VOICE_2_FIGHT_1,
+ SFX_MEDIC_VOICE_2_FIGHT_2,
+ SFX_MEDIC_VOICE_2_FIGHT_3,
+ SFX_MEDIC_VOICE_2_FIGHT_4,
+ SFX_MEDIC_VOICE_2_FIGHT_5,
+ SFX_MEDIC_VOICE_2_FIGHT_6,
+ SFX_MEDIC_VOICE_2_GET_OUT_VAN_CHAT_1,
+ SFX_MEDIC_VOICE_2_GET_OUT_VAN_CHAT_2,
+ SFX_MEDIC_VOICE_2_GET_OUT_VAN_CHAT_3,
+ SFX_MEDIC_VOICE_2_GET_OUT_VAN_CHAT_4,
+ SFX_MEDIC_VOICE_2_GET_OUT_VAN_CHAT_5,
+ SFX_MEDIC_VOICE_2_GET_OUT_VAN_CHAT_6,
+ SFX_MEDIC_VOICE_2_GET_OUT_VAN_CHAT_7,
+ SFX_MEDIC_VOICE_2_GET_OUT_VAN_CHAT_8,
+ SFX_MEDIC_VOICE_2_GET_OUT_VAN_CHAT_9,
+ SFX_MEDIC_VOICE_2_GET_OUT_VAN_CHAT_10,
+ SFX_MEDIC_VOICE_2_AT_VICTIM_1,
+ SFX_MEDIC_VOICE_2_AT_VICTIM_2,
+ SFX_MEDIC_VOICE_2_AT_VICTIM_3,
+ SFX_MEDIC_VOICE_2_AT_VICTIM_4,
+ SFX_MEDIC_VOICE_2_AT_VICTIM_5,
+ SFX_MEDIC_VOICE_2_AT_VICTIM_6,
+ SFX_MEDIC_VOICE_2_AT_VICTIM_7,
+ SFX_MEDIC_VOICE_2_AT_VICTIM_8,
+ SFX_MEDIC_VOICE_2_AT_VICTIM_9,
+ SFX_MEDIC_VOICE_2_AT_VICTIM_10,
+ SFX_MEDIC_VOICE_2_AT_VICTIM_11,
+ SFX_MEDIC_VOICE_2_AT_VICTIM_12,
+ SFX_MEDIC_VOICE_2_AT_VICTIM_13,
+ SFX_MEDIC_VOICE_2_AT_VICTIM_14,
+ SFX_MEDIC_VOICE_2_AT_VICTIM_15,
+ SFX_MEDIC_VOICE_2_AT_VICTIM_16,
+ SFX_MEDIC_VOICE_2_AT_VICTIM_17,
+
+ SFX_FBI_VOICE_1_GUNAIMEDAT3_1,
+ SFX_FBI_VOICE_1_GUNAIMEDAT3_2,
+ SFX_FBI_VOICE_1_GUNAIMEDAT3_3,
+ SFX_FBI_VOICE_1_GUNAIMEDAT3_4,
+ SFX_FBI_VOICE_1_CAR_CRASH_1,
+ SFX_FBI_VOICE_1_CAR_CRASH_2,
+ SFX_FBI_VOICE_1_CAR_CRASH_3,
+ SFX_FBI_VOICE_1_CAR_CRASH_4,
+ SFX_FBI_VOICE_1_GUNAIMEDAT2_1,
+ SFX_FBI_VOICE_1_COP_MANYCOPSAROUND_1,
+ SFX_FBI_VOICE_1_COP_MANYCOPSAROUND_2,
+ SFX_FBI_VOICE_1_COP_MANYCOPSAROUND_3,
+ SFX_FBI_VOICE_1_COP_TARGETING_1,
+ SFX_FBI_VOICE_1_COP_TARGETING_2,
+ SFX_FBI_VOICE_1_COP_TARGETING_3,
+ SFX_FBI_VOICE_1_COP_TARGETING_4,
+ SFX_FBI_VOICE_1_COP_TARGETING_5,
+ SFX_FBI_VOICE_1_COP_TARGETING_6,
+
+ SFX_FBI_VOICE_2_GUNAIMEDAT3_1,
+ SFX_FBI_VOICE_2_GUNAIMEDAT3_2,
+ SFX_FBI_VOICE_2_GUNAIMEDAT3_3,
+ SFX_FBI_VOICE_2_GUNAIMEDAT3_4,
+ SFX_FBI_VOICE_2_CAR_CRASH_1,
+ SFX_FBI_VOICE_2_CAR_CRASH_2,
+ SFX_FBI_VOICE_2_CAR_CRASH_3,
+ SFX_FBI_VOICE_2_CAR_CRASH_4,
+ SFX_FBI_VOICE_2_GUNAIMEDAT2_1,
+ SFX_FBI_VOICE_2_COP_MANYCOPSAROUND_1,
+ SFX_FBI_VOICE_2_COP_MANYCOPSAROUND_2,
+ SFX_FBI_VOICE_2_COP_MANYCOPSAROUND_3,
+ SFX_FBI_VOICE_2_COP_TARGETING_1,
+ SFX_FBI_VOICE_2_COP_TARGETING_2,
+ SFX_FBI_VOICE_2_COP_TARGETING_3,
+ SFX_FBI_VOICE_2_COP_TARGETING_4,
+ SFX_FBI_VOICE_2_COP_TARGETING_5,
+ SFX_FBI_VOICE_2_COP_TARGETING_6,
+
+ SFX_FBI_VOICE_3_GUNAIMEDAT3_1,
+ SFX_FBI_VOICE_3_GUNAIMEDAT3_2,
+ SFX_FBI_VOICE_3_GUNAIMEDAT3_3,
+ SFX_FBI_VOICE_3_GUNAIMEDAT3_4,
+ SFX_FBI_VOICE_3_CAR_CRASH_1,
+ SFX_FBI_VOICE_3_CAR_CRASH_2,
+ SFX_FBI_VOICE_3_CAR_CRASH_3,
+ SFX_FBI_VOICE_3_CAR_CRASH_4,
+ SFX_FBI_VOICE_3_GUNAIMEDAT2_1,
+ SFX_FBI_VOICE_3_COP_MANYCOPSAROUND_1,
+ SFX_FBI_VOICE_3_COP_MANYCOPSAROUND_2,
+ SFX_FBI_VOICE_3_COP_MANYCOPSAROUND_3,
+ SFX_FBI_VOICE_3_COP_TARGETING_1,
+ SFX_FBI_VOICE_3_COP_TARGETING_2,
+ SFX_FBI_VOICE_3_COP_TARGETING_3,
+ SFX_FBI_VOICE_3_COP_TARGETING_4,
+ SFX_FBI_VOICE_3_COP_TARGETING_5,
+ SFX_FBI_VOICE_3_COP_TARGETING_6,
+
+ SFX_SWAT_VOICE_1_DODGE_1,
+ SFX_SWAT_VOICE_1_DODGE_2,
+ SFX_SWAT_VOICE_1_DODGE_3,
+ SFX_SWAT_VOICE_1_COP_HELIPILOTPHRASE_1,
+ SFX_SWAT_VOICE_1_COP_HELIPILOTPHRASE_2,
+ SFX_SWAT_VOICE_1_COP_HELIPILOTPHRASE_3,
+ SFX_SWAT_VOICE_1_COP_HELIPILOTPHRASE_4,
+ SFX_SWAT_VOICE_1_COP_HELIPILOTPHRASE_5,
+ SFX_SWAT_VOICE_1_COP_HELIPILOTPHRASE_6,
+ SFX_SWAT_VOICE_1_COP_HELIPILOTPHRASE_7,
+ SFX_SWAT_VOICE_1_COP_TARGETING_1,
+ SFX_SWAT_VOICE_1_COP_TARGETING_2,
+ SFX_SWAT_VOICE_1_COP_TARGETING_3,
+ SFX_SWAT_VOICE_1_COP_TARGETING_4,
+
+ SFX_SWAT_VOICE_2_DODGE_1,
+ SFX_SWAT_VOICE_2_DODGE_2,
+ SFX_SWAT_VOICE_2_DODGE_3,
+ SFX_SWAT_VOICE_2_COP_HELIPILOTPHRASE_1,
+ SFX_SWAT_VOICE_2_COP_HELIPILOTPHRASE_2,
+ SFX_SWAT_VOICE_2_COP_HELIPILOTPHRASE_3,
+ SFX_SWAT_VOICE_2_COP_HELIPILOTPHRASE_4,
+ SFX_SWAT_VOICE_2_COP_HELIPILOTPHRASE_5,
+ SFX_SWAT_VOICE_2_COP_HELIPILOTPHRASE_6,
+ SFX_SWAT_VOICE_2_COP_HELIPILOTPHRASE_7,
+ SFX_SWAT_VOICE_2_COP_TARGETING_1,
+ SFX_SWAT_VOICE_2_COP_TARGETING_2,
+ SFX_SWAT_VOICE_2_COP_TARGETING_3,
+ SFX_SWAT_VOICE_2_COP_TARGETING_4,
+
+ SFX_SWAT_VOICE_3_DODGE_1,
+ SFX_SWAT_VOICE_3_DODGE_2,
+ SFX_SWAT_VOICE_3_DODGE_3,
+ SFX_SWAT_VOICE_3_COP_HELIPILOTPHRASE_1,
+ SFX_SWAT_VOICE_3_COP_HELIPILOTPHRASE_2,
+ SFX_SWAT_VOICE_3_COP_HELIPILOTPHRASE_3,
+ SFX_SWAT_VOICE_3_COP_HELIPILOTPHRASE_4,
+ SFX_SWAT_VOICE_3_COP_HELIPILOTPHRASE_5,
+ SFX_SWAT_VOICE_3_COP_HELIPILOTPHRASE_6,
+ SFX_SWAT_VOICE_3_COP_HELIPILOTPHRASE_7,
+ SFX_SWAT_VOICE_3_COP_TARGETING_1,
+ SFX_SWAT_VOICE_3_COP_TARGETING_2,
+ SFX_SWAT_VOICE_3_COP_TARGETING_3,
+ SFX_SWAT_VOICE_3_COP_TARGETING_4,
+
+
+ SFX_WFYG1_BLOCKED_1,
+ SFX_WFYG1_BLOCKED_2,
+ SFX_WFYG1_BLOCKED_3,
+ SFX_WFYG1_BLOCKED_4,
+ SFX_WFYG1_BLOCKED_5,
+ SFX_WFYG1_BLOCKED_6,
+ SFX_WFYG1_BLOCKED_7,
+ SFX_WFYG1_BUMP_1,
+ SFX_WFYG1_BUMP_2,
+ SFX_WFYG1_BUMP_3,
+ SFX_WFYG1_BUMP_4,
+ SFX_WFYG1_BUMP_5,
+ SFX_WFYG1_BUMP_6,
+ SFX_WFYG1_BUMP_7,
+ SFX_WFYG1_BUMP_8,
+ SFX_WFYG1_BUMP_9,
+ SFX_WFYG1_BUMP_10,
+ SFX_WFYG1_BUMP_11,
+ SFX_WFYG1_CAR_CRASH_1,
+ SFX_WFYG1_CAR_CRASH_2,
+ SFX_WFYG1_CAR_CRASH_3,
+ SFX_WFYG1_CAR_CRASH_4,
+ SFX_WFYG1_CAR_CRASH_5,
+ SFX_WFYG1_CAR_CRASH_6,
+ SFX_WFYG1_CAR_CRASH_7,
+ SFX_WFYG1_CAR_CRASH_8,
+ SFX_WFYG1_CAR_CRASH_9,
+ SFX_WFYG1_CHAT_1,
+ SFX_WFYG1_CHAT_2,
+ SFX_WFYG1_CHAT_3,
+ SFX_WFYG1_CHAT_4,
+ SFX_WFYG1_CHAT_5,
+ SFX_WFYG1_CHAT_6,
+ SFX_WFYG1_CHAT_7,
+ SFX_WFYG1_CHAT_8,
+ SFX_WFYG1_CHAT_9,
+ SFX_WFYG1_CHAT_10,
+ SFX_WFYG1_DODGE_1,
+ SFX_WFYG1_DODGE_2,
+ SFX_WFYG1_DODGE_3,
+ SFX_WFYG1_DODGE_4,
+ SFX_WFYG1_DODGE_5,
+ SFX_WFYG1_DODGE_6,
+ SFX_WFYG1_DODGE_7,
+ SFX_WFYG1_DODGE_8,
+ SFX_WFYG1_DODGE_9,
+ SFX_WFYG1_EYEING_1,
+ SFX_WFYG1_EYEING_2,
+ SFX_WFYG1_FIGHT_1,
+ SFX_WFYG1_FIGHT_2,
+ SFX_WFYG1_FIGHT_3,
+ SFX_WFYG1_FIGHT_4,
+ SFX_WFYG1_GENERIC_CRASH_1,
+ SFX_WFYG1_GENERIC_CRASH_2,
+ SFX_WFYG1_GENERIC_CRASH_3,
+ SFX_WFYG1_GENERIC_CRASH_4,
+ SFX_WFYG1_GENERIC_CRASH_5,
+ SFX_WFYG1_GENERIC_CRASH_6,
+ SFX_WFYG1_GENERIC_CRASH_7,
+ SFX_WFYG1_GUN_COOL_1,
+ SFX_WFYG1_GUN_COOL_2,
+ SFX_WFYG1_GUN_COOL_3,
+ SFX_WFYG1_GUN_COOL_4,
+ SFX_WFYG1_GUN_COOL_5,
+ SFX_WFYG1_GUN_COOL_6,
+ SFX_WFYG1_JACKED_1,
+ SFX_WFYG1_JACKED_2,
+ SFX_WFYG1_JACKED_3,
+ SFX_WFYG1_JACKED_4,
+ SFX_WFYG1_JACKED_5,
+ SFX_WFYG1_LOST_1,
+ SFX_WFYG1_LOST_2,
+ SFX_WFYG1_LOST_3,
+ SFX_WFYG1_MUGGED_1,
+ SFX_WFYG1_MUGGED_2,
+ SFX_WFYG1_MUGGING_1,
+ SFX_WFYG1_MUGGING_2,
+ SFX_WFYG1_RUN_1,
+ SFX_WFYG1_RUN_2,
+ SFX_WFYG1_SAVED_1,
+ SFX_WFYG1_SHOCKED_1,
+ SFX_WFYG1_TAXI_1,
+
+ SFX_WFYG2_BLOCKED_1,
+ SFX_WFYG2_BLOCKED_2,
+ SFX_WFYG2_BLOCKED_3,
+ SFX_WFYG2_BLOCKED_4,
+ SFX_WFYG2_BLOCKED_5,
+ SFX_WFYG2_BUMP_1,
+ SFX_WFYG2_BUMP_2,
+ SFX_WFYG2_BUMP_3,
+ SFX_WFYG2_BUMP_4,
+ SFX_WFYG2_BUMP_5,
+ SFX_WFYG2_BUMP_6,
+ SFX_WFYG2_BUMP_7,
+ SFX_WFYG2_BUMP_8,
+ SFX_WFYG2_BUMP_9,
+ SFX_WFYG2_BUMP_10,
+ SFX_WFYG2_BUMP_11,
+ SFX_WFYG2_CAR_CRASH_1,
+ SFX_WFYG2_CAR_CRASH_2,
+ SFX_WFYG2_CAR_CRASH_3,
+ SFX_WFYG2_CAR_CRASH_4,
+ SFX_WFYG2_CAR_CRASH_5,
+ SFX_WFYG2_CAR_CRASH_6,
+ SFX_WFYG2_CAR_CRASH_7,
+ SFX_WFYG2_CAR_CRASH_8,
+ SFX_WFYG2_CAR_CRASH_9,
+ SFX_WFYG2_CHAT_1,
+ SFX_WFYG2_CHAT_2,
+ SFX_WFYG2_CHAT_3,
+ SFX_WFYG2_CHAT_4,
+ SFX_WFYG2_CHAT_5,
+ SFX_WFYG2_CHAT_6,
+ SFX_WFYG2_CHAT_7,
+ SFX_WFYG2_CHAT_8,
+ SFX_WFYG2_CHAT_9,
+ SFX_WFYG2_DODGE_1,
+ SFX_WFYG2_DODGE_2,
+ SFX_WFYG2_DODGE_3,
+ SFX_WFYG2_DODGE_4,
+ SFX_WFYG2_DODGE_5,
+ SFX_WFYG2_DODGE_6,
+ SFX_WFYG2_DODGE_7,
+ SFX_WFYG2_DODGE_8,
+ SFX_WFYG2_EYEING_1,
+ SFX_WFYG2_EYEING_2,
+ SFX_WFYG2_EYEING_3,
+ SFX_WFYG2_EYEING_4,
+ SFX_WFYG2_FIGHT_1,
+ SFX_WFYG2_FIGHT_2,
+ SFX_WFYG2_FIGHT_3,
+ SFX_WFYG2_FIGHT_4,
+ SFX_WFYG2_FIGHT_5,
+ SFX_WFYG2_GENERIC_CRASH_1,
+ SFX_WFYG2_GENERIC_CRASH_2,
+ SFX_WFYG2_GENERIC_CRASH_3,
+ SFX_WFYG2_GENERIC_CRASH_4,
+ SFX_WFYG2_GENERIC_CRASH_5,
+ SFX_WFYG2_GENERIC_CRASH_6,
+ SFX_WFYG2_GENERIC_CRASH_7,
+ SFX_WFYG2_GUN_COOL_1,
+ SFX_WFYG2_GUN_COOL_2,
+ SFX_WFYG2_GUN_COOL_3,
+ SFX_WFYG2_JACKED_1,
+ SFX_WFYG2_JACKED_2,
+ SFX_WFYG2_JACKED_3,
+ SFX_WFYG2_JACKED_4,
+ SFX_WFYG2_JACKED_5,
+ SFX_WFYG2_LOST_1,
+ SFX_WFYG2_MUGGED_1,
+ SFX_WFYG2_MUGGED_2,
+ SFX_WFYG2_SHOCKED_1,
+ SFX_WFYG2_TAXI_1,
+ SFX_WFYG2_TAXI_2, // unused
+
+ SFX_HMOCA_BLOCKED_1,
+ SFX_HMOCA_BLOCKED_2,
+ SFX_HMOCA_BLOCKED_3,
+ SFX_HMOCA_BLOCKED_4,
+ SFX_HMOCA_BLOCKED_5,
+ SFX_HMOCA_BLOCKED_6,
+ SFX_HMOCA_BLOCKED_7,
+ SFX_HMOCA_BLOCKED_8,
+ SFX_HMOCA_CAR_CRASH_1,
+ SFX_HMOCA_CAR_CRASH_2,
+ SFX_HMOCA_CAR_CRASH_3,
+ SFX_HMOCA_CAR_CRASH_4,
+ SFX_HMOCA_CAR_CRASH_5,
+ SFX_HMOCA_CAR_CRASH_6,
+ SFX_HMOCA_CAR_CRASH_7,
+ SFX_HMOCA_CAR_CRASH_8,
+ SFX_HMOCA_CHAT_1,
+ SFX_HMOCA_CHAT_2,
+ SFX_HMOCA_CHAT_3,
+ SFX_HMOCA_CHAT_4,
+ SFX_HMOCA_CHAT_5,
+ SFX_HMOCA_CHAT_6,
+ SFX_HMOCA_CHAT_7,
+ SFX_HMOCA_CHAT_8,
+ SFX_HMOCA_CHAT_9,
+ SFX_HMOCA_CHAT_10,
+ SFX_HMOCA_EYEING_1,
+ SFX_HMOCA_EYEING_2,
+ SFX_HMOCA_GUN_PANIC_1,
+ SFX_HMOCA_GUN_PANIC_2,
+ SFX_HMOCA_GUN_PANIC_3,
+ SFX_HMOCA_GUN_PANIC_4,
+ SFX_HMOCA_GUN_PANIC_5,
+ SFX_HMOCA_JACKED_1,
+ SFX_HMOCA_JACKED_2,
+ SFX_HMOCA_JACKED_3,
+ SFX_HMOCA_JACKED_4,
+ SFX_HMOCA_JACKED_5,
+ SFX_HMOCA_JACKED_6,
+ SFX_HMOCA_JACKED_7,
+ SFX_HMOCA_JACKED_8,
+ SFX_HMOCA_JACKED_9,
+ SFX_HMOCA_JACKED_10,
+ SFX_HMOCA_JACKING_1,
+ SFX_HMOCA_JACKING_2,
+ SFX_HMOCA_JACKING_3,
+ SFX_HMOCA_JACKING_4,
+ SFX_HMOCA_JACKING_5,
+ SFX_HMOCA_JACKING_6,
+ SFX_HMOCA_JACKING_7,
+ SFX_HMOCA_JACKING_8,
+ SFX_HMOCA_JACKING_9,
+ SFX_HMOCA_JACKING_10,
+ SFX_HMOCA_JACKING_11,
+ SFX_HMOCA_MUGGED_1,
+ SFX_HMOCA_MUGGED_2,
+ SFX_HMOCA_MUGGED_3,
+ SFX_HMOCA_MUGGED_4,
+ SFX_HMOCA_MUGGED_5,
+ SFX_HMOCA_MUGGED_6,
+ SFX_HMOCA_MUGGED_7,
+ SFX_HMOCA_RUN_1,
+ SFX_HMOCA_RUN_2,
+ SFX_HMOCA_TAXI_1,
+
+ SFX_WFOSH_BUMP_1,
+ SFX_WFOSH_BUMP_2,
+ SFX_WFOSH_BUMP_3,
+ SFX_WFOSH_BUMP_4,
+ SFX_WFOSH_BUMP_5,
+ SFX_WFOSH_BUMP_6,
+ SFX_WFOSH_BUMP_7,
+ SFX_WFOSH_BUMP_8,
+ SFX_WFOSH_BUMP_9,
+ SFX_WFOSH_BUMP_10,
+ SFX_WFOSH_CHAT_1,
+ SFX_WFOSH_CHAT_2,
+ SFX_WFOSH_CHAT_3,
+ SFX_WFOSH_CHAT_4,
+ SFX_WFOSH_CHAT_5,
+ SFX_WFOSH_CHAT_6,
+ SFX_WFOSH_CHAT_7,
+ SFX_WFOSH_CHAT_8,
+ SFX_WFOSH_CHAT_9,
+ SFX_WFOSH_DODGE_1,
+ SFX_WFOSH_DODGE_2,
+ SFX_WFOSH_DODGE_3,
+ SFX_WFOSH_DODGE_4,
+ SFX_WFOSH_DODGE_5,
+ SFX_WFOSH_DODGE_6,
+ SFX_WFOSH_DODGE_7,
+ SFX_WFOSH_DODGE_8,
+ SFX_WFOSH_DODGE_9,
+ SFX_WFOSH_DODGE_10,
+ SFX_WFOSH_GUN_COOL_1,
+ SFX_WFOSH_GUN_COOL_2,
+ SFX_WFOSH_GUN_COOL_3,
+ SFX_WFOSH_GUN_COOL_4,
+ SFX_WFOSH_GUN_COOL_5,
+ SFX_WFOSH_GUN_COOL_6,
+ SFX_WFOSH_GUN_COOL_7,
+ SFX_WFOSH_GUN_COOL_8,
+ SFX_WFOSH_GUN_COOL_9,
+ SFX_WFOSH_GUN_COOL_10,
+ SFX_WFOSH_LOST_1,
+ SFX_WFOSH_LOST_2,
+ SFX_WFOSH_MUGGED_1,
+ SFX_WFOSH_MUGGED_2,
+ SFX_WFOSH_RUN_1,
+ SFX_WFOSH_RUN_2,
+ SFX_WFOSH_RUN_3,
+ SFX_WFOSH_RUN_4,
+ SFX_WFOSH_RUN_5,
+ SFX_WFOSH_RUN_6,
+ SFX_WFOSH_RUN_7,
+ SFX_WFOSH_RUN_8,
+ SFX_WFOSH_RUN_9,
+ SFX_WFOSH_SAVED_1,
+ SFX_WFOSH_SAVED_2,
+ SFX_WFOSH_SAVED_3,
+ SFX_WFOSH_SHOCKED_1,
+ SFX_WFOSH_SHOCKED_2,
+ SFX_WFOSH_SHOCKED_3,
+ SFX_WFOSH_SHOCKED_4,
+ SFX_WFOSH_SHOCKED_5,
+ SFX_WFOSH_TAXI_1,
+ SFX_WFYSK_BLOCKED_1,
+ SFX_WFYSK_BLOCKED_2,
+ SFX_WFYSK_BLOCKED_3,
+ SFX_WFYSK_BLOCKED_4,
+ SFX_WFYSK_BLOCKED_5,
+ SFX_WFYSK_BLOCKED_6,
+ SFX_WFYSK_BLOCKED_7,
+ SFX_WFYSK_BLOCKED_8,
+ SFX_WFYSK_BLOCKED_9,
+ SFX_WFYSK_BLOCKED_10,
+ SFX_WFYSK_BLOCKED_11,
+ SFX_WFYSK_BUMP_1,
+ SFX_WFYSK_BUMP_2,
+ SFX_WFYSK_BUMP_3,
+ SFX_WFYSK_BUMP_4,
+ SFX_WFYSK_BUMP_5,
+ SFX_WFYSK_BUMP_6,
+ SFX_WFYSK_BUMP_7,
+ SFX_WFYSK_BUMP_8,
+ SFX_WFYSK_BUMP_9,
+ SFX_WFYSK_BUMP_10,
+ SFX_WFYSK_BUMP_11,
+ SFX_WFYSK_BUMP_12,
+ SFX_WFYSK_BUMP_13,
+ SFX_WFYSK_BUMP_14,
+ SFX_WFYSK_BUMP_15,
+ SFX_WFYSK_BUMP_16,
+ SFX_WFYSK_BUMP_17,
+ SFX_WFYSK_BUMP_18,
+ SFX_WFYSK_DODGE_1,
+ SFX_WFYSK_DODGE_2,
+ SFX_WFYSK_DODGE_3,
+ SFX_WFYSK_DODGE_4,
+ SFX_WFYSK_DODGE_5,
+ SFX_WFYSK_DODGE_6,
+ SFX_WFYSK_DODGE_7,
+ SFX_WFYSK_DODGE_8,
+ SFX_WFYSK_DODGE_9,
+ SFX_WFYSK_FIGHT_1,
+ SFX_WFYSK_FIGHT_2,
+ SFX_WFYSK_FIGHT_3,
+ SFX_WFYSK_FIGHT_4,
+ SFX_WFYSK_FIGHT_5,
+ SFX_WFYSK_FIGHT_6,
+ SFX_WFYSK_FIGHT_7,
+ SFX_WFYSK_FIGHT_8,
+ SFX_WFYSK_FIGHT_9,
+ SFX_WFYSK_FIGHT_10,
+ SFX_WFYSK_FIGHT_11,
+ SFX_WFYSK_GUN_PANIC_1,
+ SFX_WFYSK_GUN_PANIC_2,
+ SFX_WFYSK_GUN_PANIC_3,
+ SFX_WFYSK_GUN_PANIC_4,
+ SFX_WFYSK_GUN_PANIC_5,
+ SFX_WFYSK_MUGGED_1,
+ SFX_WFYSK_MUGGED_2,
+ SFX_WFYSK_SAVED_1,
+ SFX_WFYSK_SAVED_2,
+ SFX_WFYSK_TAXI_1,
+ SFX_WMYLG_BUMP_1,
+ SFX_WMYLG_BUMP_2,
+ SFX_WMYLG_BUMP_3,
+ SFX_WMYLG_BUMP_4,
+ SFX_WMYLG_BUMP_5,
+ SFX_WMYLG_BUMP_6,
+ SFX_WMYLG_BUMP_7,
+ SFX_WMYLG_BUMP_8,
+ SFX_WMYLG_BUMP_9,
+ SFX_WMYLG_BUMP_10,
+ SFX_WMYLG_CHAT_1,
+ SFX_WMYLG_CHAT_2,
+ SFX_WMYLG_CHAT_3,
+ SFX_WMYLG_CHAT_4,
+ SFX_WMYLG_CHAT_5,
+ SFX_WMYLG_CHAT_6,
+ SFX_WMYLG_CHAT_7,
+ SFX_WMYLG_CHAT_8,
+ SFX_WMYLG_CHAT_9,
+ SFX_WMYLG_CHAT_10,
+ SFX_WMYLG_DODGE_1,
+ SFX_WMYLG_DODGE_2,
+ SFX_WMYLG_DODGE_3,
+ SFX_WMYLG_DODGE_4,
+ SFX_WMYLG_DODGE_5,
+ SFX_WMYLG_DODGE_6,
+ SFX_WMYLG_DODGE_7,
+ SFX_WMYLG_DODGE_8,
+ SFX_WMYLG_DODGE_9,
+ SFX_WMYLG_FIGHT_1,
+ SFX_WMYLG_FIGHT_2,
+ SFX_WMYLG_FIGHT_3,
+ SFX_WMYLG_FIGHT_4,
+ SFX_WMYLG_FIGHT_5,
+ SFX_WMYLG_FIGHT_6,
+ SFX_WMYLG_FIGHT_7,
+ SFX_WMYLG_GUN_COOL_1,
+ SFX_WMYLG_GUN_COOL_2,
+ SFX_WMYLG_GUN_COOL_3,
+ SFX_WMYLG_GUN_COOL_4,
+ SFX_WMYLG_GUN_COOL_5,
+ SFX_WMYLG_GUN_COOL_6,
+ SFX_WMYLG_SAVED_1,
+ SFX_WMYLG_TAXI_1,
+
+ SFX_WMOBE_BLOCKED_1,
+ SFX_WMOBE_BLOCKED_2,
+ SFX_WMOBE_BLOCKED_3,
+ SFX_WMOBE_BLOCKED_4,
+ SFX_WMOBE_BLOCKED_5,
+ SFX_WMOBE_BLOCKED_6,
+ SFX_WMOBE_BUMP_1,
+ SFX_WMOBE_BUMP_2,
+ SFX_WMOBE_BUMP_3,
+ SFX_WMOBE_BUMP_4,
+ SFX_WMOBE_BUMP_5,
+ SFX_WMOBE_BUMP_6,
+ SFX_WMOBE_BUMP_7,
+ SFX_WMOBE_BUMP_8,
+ SFX_WMOBE_BUMP_9,
+ SFX_WMOBE_BUMP_10,
+ SFX_WMOBE_BUMP_11,
+ SFX_WMOBE_BUMP_12,
+ SFX_WMOBE_CAR_CRASH_1,
+ SFX_WMOBE_CAR_CRASH_2,
+ SFX_WMOBE_CAR_CRASH_3,
+ SFX_WMOBE_CAR_CRASH_4,
+ SFX_WMOBE_CAR_CRASH_5,
+ SFX_WMOBE_CAR_CRASH_6,
+ SFX_WMOBE_CAR_CRASH_7,
+ SFX_WMOBE_CAR_CRASH_8,
+ SFX_WMOBE_CHAT_1,
+ SFX_WMOBE_CHAT_2,
+ SFX_WMOBE_CHAT_3,
+ SFX_WMOBE_CHAT_4,
+ SFX_WMOBE_CHAT_5,
+ SFX_WMOBE_CHAT_6,
+ SFX_WMOBE_CHAT_7,
+ SFX_WMOBE_CHAT_8,
+ SFX_WMOBE_CHAT_9,
+ SFX_WMOBE_CHAT_10,
+ SFX_WMOBE_DODGE_1,
+ SFX_WMOBE_DODGE_2,
+ SFX_WMOBE_DODGE_3,
+ SFX_WMOBE_DODGE_4,
+ SFX_WMOBE_DODGE_5,
+ SFX_WMOBE_DODGE_6,
+ SFX_WMOBE_DODGE_7,
+ SFX_WMOBE_DODGE_8,
+ SFX_WMOBE_EYEING_1,
+ SFX_WMOBE_EYEING_2,
+ SFX_WMOBE_GENERIC_CRASH_1,
+ SFX_WMOBE_GENERIC_CRASH_2,
+ SFX_WMOBE_GENERIC_CRASH_3,
+ SFX_WMOBE_GENERIC_CRASH_4,
+ SFX_WMOBE_GENERIC_CRASH_5,
+ SFX_WMOBE_GENERIC_CRASH_6,
+ SFX_WMOBE_GENERIC_CRASH_7,
+ SFX_WMOBE_GUN_PANIC_1,
+ SFX_WMOBE_GUN_PANIC_2,
+ SFX_WMOBE_GUN_PANIC_3,
+ SFX_WMOBE_GUN_PANIC_4,
+ SFX_WMOBE_GUN_PANIC_5,
+ SFX_WMOBE_JACKED_1,
+ SFX_WMOBE_JACKED_2,
+ SFX_WMOBE_JACKED_3,
+ SFX_WMOBE_JACKED_4,
+ SFX_WMOBE_JACKED_5,
+ SFX_WMOBE_JACKED_6,
+ SFX_WMOBE_JACKED_7,
+ SFX_WMOBE_JACKED_8,
+ SFX_WMOBE_JACKING_1,
+ SFX_WMOBE_JACKING_2,
+ SFX_WMOBE_JACKING_3,
+ SFX_WMOBE_JACKING_4,
+ SFX_WMOBE_JEER_1,
+ SFX_WMOBE_JEER_2,
+ SFX_WMOBE_JEER_3,
+ SFX_WMOBE_JEER_4,
+ SFX_WMOBE_JEER_5,
+ SFX_WMOBE_JEER_6,
+ SFX_WMOBE_JEER_7,
+ SFX_WMOBE_JEER_8,
+ SFX_WMOBE_JEER_9,
+ SFX_WMOBE_JEER_10,
+ SFX_WMOBE_JEER_11,
+ SFX_WMOBE_JEER_12,
+ SFX_WMOBE_JEER_13,
+ SFX_WMOBE_JEER_14,
+ SFX_WMOBE_JEER_15,
+ SFX_WMOBE_JEER_16,
+ SFX_WMOBE_MUGGING_1,
+ SFX_WMOBE_MUGGING_2,
+ SFX_WMOBE_MUGGING_3,
+ SFX_WMOBE_MUGGING_4,
+ SFX_WMOBE_MUGGING_5,
+ SFX_WMOBE_MUGGING_6,
+ SFX_WMOBE_RUN_1,
+ SFX_WMOBE_RUN_2,
+ SFX_WMOBE_RUN_3,
+ SFX_WMOBE_RUN_4,
+ SFX_WMOBE_SAVED_1,
+ SFX_WMOBE_SAVED_2,
+ SFX_WMOBE_SHOCKED_1,
+ SFX_WMOBE_SHOCKED_2,
+
+
+
+ SFX_WMYBU_BLOCKED_1,
+ SFX_WMYBU_BLOCKED_2,
+ SFX_WMYBU_BLOCKED_3,
+ SFX_WMYBU_BLOCKED_4,
+ SFX_WMYBU_BLOCKED_5,
+ SFX_WMYBU_BLOCKED_6,
+ SFX_WMYBU_BLOCKED_7,
+ SFX_WMYBU_BLOCKED_8,
+ SFX_WMYBU_BLOCKED_9,
+ SFX_WMYBU_BUMP_1,
+ SFX_WMYBU_BUMP_2,
+ SFX_WMYBU_BUMP_3,
+ SFX_WMYBU_BUMP_4,
+ SFX_WMYBU_BUMP_5,
+ SFX_WMYBU_BUMP_6,
+ SFX_WMYBU_BUMP_7,
+ SFX_WMYBU_BUMP_8,
+ SFX_WMYBU_BUMP_9,
+ SFX_WMYBU_BUMP_10,
+ SFX_WMYBU_BUMP_11,
+ SFX_WMYBU_CAR_CRASH_1,
+ SFX_WMYBU_CAR_CRASH_2,
+ SFX_WMYBU_CAR_CRASH_3,
+ SFX_WMYBU_CAR_CRASH_4,
+ SFX_WMYBU_CAR_CRASH_5,
+ SFX_WMYBU_CAR_CRASH_6,
+ SFX_WMYBU_CAR_CRASH_7,
+ SFX_WMYBU_CAR_CRASH_8,
+ SFX_WMYBU_CAR_CRASH_9,
+ SFX_WMYBU_CHAT_1,
+ SFX_WMYBU_CHAT_2,
+ SFX_WMYBU_CHAT_3,
+ SFX_WMYBU_CHAT_4,
+ SFX_WMYBU_CHAT_5,
+ SFX_WMYBU_CHAT_6,
+ SFX_WMYBU_CHAT_7,
+ SFX_WMYBU_CHAT_8,
+ SFX_WMYBU_CHAT_9,
+ SFX_WMYBU_CHAT_10,
+ SFX_WMYBU_DODGE_1,
+ SFX_WMYBU_DODGE_2,
+ SFX_WMYBU_DODGE_3,
+ SFX_WMYBU_DODGE_4,
+ SFX_WMYBU_DODGE_5,
+ SFX_WMYBU_DODGE_6,
+ SFX_WMYBU_DODGE_7,
+ SFX_WMYBU_DODGE_8,
+ SFX_WMYBU_DODGE_9,
+ SFX_WMYBU_DODGE_10,
+ SFX_WMYBU_EYEING_1,
+ SFX_WMYBU_EYEING_2,
+ SFX_WMYBU_GENERIC_CRASH_1,
+ SFX_WMYBU_GENERIC_CRASH_2,
+ SFX_WMYBU_GENERIC_CRASH_3,
+ SFX_WMYBU_GENERIC_CRASH_4,
+ SFX_WMYBU_GENERIC_CRASH_5,
+ SFX_WMYBU_GUN_PANIC_1,
+ SFX_WMYBU_GUN_PANIC_2,
+ SFX_WMYBU_GUN_PANIC_3,
+ SFX_WMYBU_GUN_PANIC_4,
+ SFX_WMYBU_GUN_PANIC_5,
+ SFX_WMYBU_GUN_PANIC_6,
+ SFX_WMYBU_INNOCENT_1,
+ SFX_WMYBU_INNOCENT_2,
+ SFX_WMYBU_JACKED_1,
+ SFX_WMYBU_JACKED_2,
+ SFX_WMYBU_JACKED_3,
+ SFX_WMYBU_JACKED_4,
+ SFX_WMYBU_JACKED_5,
+ SFX_WMYBU_LOST_1,
+ SFX_WMYBU_LOST_2,
+ SFX_WMYBU_LOST_3,
+ SFX_WMYBU_LOST_4,
+ SFX_WMYBU_LOST_5,
+ SFX_WMYBU_MUGGED_1,
+ SFX_WMYBU_RUN_1,
+ SFX_WMYBU_RUN_2,
+ SFX_WMYBU_RUN_3,
+ SFX_WMYBU_SAVED_1,
+ SFX_WMYBU_SAVED_2,
+ SFX_WMYBU_SHOCKED_1,
+ SFX_WMYBU_SHOCKED_2,
+ SFX_WMYBU_SHOCKED_3,
+ SFX_WMYBU_SHOCKED_4,
+ SFX_WMYBU_SHOCKED_5,
+ SFX_WMYBU_TAXI_1,
+ SFX_WMYBU_TAXI_2,
+
+ SFX_WMYST_BLOCKED_1,
+ SFX_WMYST_BLOCKED_2,
+ SFX_WMYST_BLOCKED_3,
+ SFX_WMYST_BLOCKED_4,
+ SFX_WMYST_BLOCKED_5,
+ SFX_WMYST_BLOCKED_6,
+ SFX_WMYST_BLOCKED_7,
+ SFX_WMYST_BLOCKED_8,
+ SFX_WMYST_BUMP_1,
+ SFX_WMYST_BUMP_2,
+ SFX_WMYST_BUMP_3,
+ SFX_WMYST_BUMP_4,
+ SFX_WMYST_BUMP_5,
+ SFX_WMYST_BUMP_6,
+ SFX_WMYST_BUMP_7,
+ SFX_WMYST_BUMP_8,
+ SFX_WMYST_BUMP_9,
+ SFX_WMYST_BUMP_10,
+ SFX_WMYST_BUMP_11,
+ SFX_WMYST_CAR_CRASH_1,
+ SFX_WMYST_CAR_CRASH_2,
+ SFX_WMYST_CAR_CRASH_3,
+ SFX_WMYST_CAR_CRASH_4,
+ SFX_WMYST_CAR_CRASH_5,
+ SFX_WMYST_CAR_CRASH_6,
+ SFX_WMYST_CAR_CRASH_7,
+ SFX_WMYST_CAR_CRASH_8,
+ SFX_WMYST_CHAT_1,
+ SFX_WMYST_CHAT_2,
+ SFX_WMYST_CHAT_3,
+ SFX_WMYST_CHAT_4,
+ SFX_WMYST_CHAT_5,
+ SFX_WMYST_CHAT_6,
+ SFX_WMYST_CHAT_7,
+ SFX_WMYST_CHAT_8,
+ SFX_WMYST_CHAT_9,
+ SFX_WMYST_CHAT_10,
+ SFX_WMYST_DODGE_1,
+ SFX_WMYST_DODGE_2,
+ SFX_WMYST_DODGE_3,
+ SFX_WMYST_DODGE_4,
+ SFX_WMYST_DODGE_5,
+ SFX_WMYST_DODGE_6,
+ SFX_WMYST_DODGE_7,
+ SFX_WMYST_DODGE_8,
+ SFX_WMYST_DODGE_9,
+ SFX_WMYST_DODGE_10,
+ SFX_WMYST_EYEING_1,
+ SFX_WMYST_EYEING_2,
+ SFX_WMYST_GENERIC_CRASH_1,
+ SFX_WMYST_GENERIC_CRASH_2,
+ SFX_WMYST_GENERIC_CRASH_3,
+ SFX_WMYST_GENERIC_CRASH_4,
+ SFX_WMYST_GENERIC_CRASH_5,
+ SFX_WMYST_GUN_PANIC_1,
+ SFX_WMYST_GUN_PANIC_2,
+ SFX_WMYST_GUN_PANIC_3,
+ SFX_WMYST_GUN_PANIC_4,
+ SFX_WMYST_GUN_PANIC_5,
+ SFX_WMYST_INNOCENT_1,
+ SFX_WMYST_INNOCENT_2,
+ SFX_WMYST_INNOCENT_3,
+ SFX_WMYST_JACKED_1,
+ SFX_WMYST_JACKED_2,
+ SFX_WMYST_JACKED_3,
+ SFX_WMYST_JACKED_4,
+ SFX_WMYST_JACKED_5,
+ SFX_WMYST_LOST_1,
+ SFX_WMYST_LOST_2,
+ SFX_WMYST_MUGGED_1,
+ SFX_WMYST_MUGGING_1,
+ SFX_WMYST_MUGGING_2,
+ SFX_WMYST_MUGGING_3,
+ SFX_WMYST_MUGGING_4,
+ SFX_WMYST_MUGGING_5,
+ SFX_WMYST_RUN_1,
+ SFX_WMYST_RUN_2,
+ SFX_WMYST_RUN_3,
+ SFX_WMYST_RUN_4,
+ SFX_WMYST_RUN_5,
+ SFX_WMYST_RUN_6,
+ SFX_WMYST_RUN_7,
+ SFX_WMYST_SAVED_1,
+ SFX_WMYST_TAXI_1,
+ SFX_WMYST_TAXI_2,
+
+ SFX_BMYPI_BLOCKED_1,
+ SFX_BMYPI_BLOCKED_2,
+ SFX_BMYPI_BLOCKED_3,
+ SFX_BMYPI_BLOCKED_4,
+ SFX_BMYPI_BLOCKED_5,
+ SFX_BMYPI_BLOCKED_6,
+ SFX_BMYPI_BUMP_1,
+ SFX_BMYPI_BUMP_2,
+ SFX_BMYPI_BUMP_3,
+ SFX_BMYPI_BUMP_4,
+ SFX_BMYPI_BUMP_5,
+ SFX_BMYPI_BUMP_6,
+ SFX_BMYPI_BUMP_7,
+ SFX_BMYPI_BUMP_8,
+ SFX_BMYPI_BUMP_9,
+ SFX_BMYPI_CAR_CRASH_1,
+ SFX_BMYPI_CAR_CRASH_2,
+ SFX_BMYPI_CAR_CRASH_3,
+ SFX_BMYPI_CAR_CRASH_4,
+ SFX_BMYPI_CAR_CRASH_5,
+ SFX_BMYPI_DODGE_1,
+ SFX_BMYPI_DODGE_2,
+ SFX_BMYPI_DODGE_3,
+ SFX_BMYPI_DODGE_4,
+ SFX_BMYPI_DODGE_5,
+ SFX_BMYPI_DODGE_6,
+ SFX_BMYPI_DODGE_7,
+ SFX_BMYPI_DODGE_8,
+ SFX_BMYPI_DODGE_9,
+ SFX_BMYPI_DODGE_10,
+ SFX_BMYPI_EYEING_1,
+ SFX_BMYPI_EYEING_2,
+ SFX_BMYPI_EYEING_3,
+ SFX_BMYPI_EYEING_4,
+ SFX_BMYPI_FIGHT_1,
+ SFX_BMYPI_FIGHT_2,
+ SFX_BMYPI_FIGHT_3,
+ SFX_BMYPI_FIGHT_4,
+ SFX_BMYPI_FIGHT_5,
+ SFX_BMYPI_FIGHT_6,
+ SFX_BMYPI_FIGHT_7,
+ SFX_BMYPI_FIGHT_8,
+ SFX_BMYPI_GENERIC_CRASH_1,
+ SFX_BMYPI_GENERIC_CRASH_2,
+ SFX_BMYPI_GENERIC_CRASH_3,
+ SFX_BMYPI_GENERIC_CRASH_4,
+ SFX_BMYPI_GENERIC_CRASH_5,
+ SFX_BMYPI_GENERIC_CRASH_6,
+ SFX_BMYPI_GENERIC_CRASH_7,
+ SFX_BMYPI_GENERIC_CRASH_8,
+ SFX_BMYPI_GENERIC_CRASH_9,
+ SFX_BMYPI_GENERIC_CRASH_10,
+ SFX_BMYPI_GENERIC_CRASH_11,
+ SFX_BMYPI_GENERIC_CRASH_12,
+ SFX_BMYPI_GENERIC_CRASH_13,
+ SFX_BMYPI_GUN_COOL_1,
+ SFX_BMYPI_GUN_COOL_2,
+ SFX_BMYPI_GUN_COOL_3,
+ SFX_BMYPI_GUN_COOL_4,
+ SFX_BMYPI_GUN_COOL_5,
+ SFX_BMYPI_JACKED_1,
+ SFX_BMYPI_JACKED_2,
+ SFX_BMYPI_JACKED_3,
+ SFX_BMYPI_JACKED_4,
+ SFX_BMYPI_JACKED_5,
+ SFX_BMYPI_JACKED_6,
+ SFX_BMYPI_JACKING_1,
+ SFX_BMYPI_JACKING_2,
+ SFX_BMYPI_JACKING_3,
+ SFX_BMYPI_JACKING_4,
+ SFX_BMYPI_MUGGED_1,
+ SFX_BMYPI_SAVED_1,
+ SFX_BMYPI_TAXI_1,
+ SFX_BMYPI_TAXI_2,
+
+ SFX_WFYPR_BUMP_1,
+ SFX_WFYPR_BUMP_2,
+ SFX_WFYPR_BUMP_3,
+ SFX_WFYPR_BUMP_4,
+ SFX_WFYPR_BUMP_5,
+ SFX_WFYPR_BUMP_6,
+ SFX_WFYPR_BUMP_7,
+ SFX_WFYPR_BUMP_8,
+ SFX_WFYPR_BUMP_9,
+ SFX_WFYPR_BUMP_10,
+ SFX_WFYPR_BUMP_11,
+ SFX_WFYPR_CHAT_1,
+ SFX_WFYPR_CHAT_2,
+ SFX_WFYPR_CHAT_3,
+ SFX_WFYPR_CHAT_4,
+ SFX_WFYPR_CHAT_5,
+ SFX_WFYPR_CHAT_6,
+ SFX_WFYPR_CHAT_7,
+ SFX_WFYPR_CHAT_8,
+ SFX_WFYPR_CHAT_9,
+ SFX_WFYPR_CHAT_10,
+ SFX_WFYPR_CHAT_11,
+ SFX_WFYPR_CHAT_12,
+ SFX_WFYPR_CHAT_13,
+ SFX_WFYPR_CHAT_14,
+ SFX_WFYPR_DODGE_1,
+ SFX_WFYPR_DODGE_2,
+ SFX_WFYPR_DODGE_3,
+ SFX_WFYPR_DODGE_4,
+ SFX_WFYPR_DODGE_5,
+ SFX_WFYPR_DODGE_6,
+ SFX_WFYPR_DODGE_7,
+ SFX_WFYPR_DODGE_8,
+ SFX_WFYPR_DODGE_9,
+ SFX_WFYPR_DODGE_10,
+ SFX_WFYPR_FIGHT_1,
+ SFX_WFYPR_FIGHT_2,
+ SFX_WFYPR_FIGHT_3,
+ SFX_WFYPR_FIGHT_4,
+ SFX_WFYPR_FIGHT_5,
+ SFX_WFYPR_FIGHT_6,
+ SFX_WFYPR_FIGHT_7,
+ SFX_WFYPR_FIGHT_8,
+ SFX_WFYPR_FIGHT_9,
+ SFX_WFYPR_FUCKING_1,
+ SFX_WFYPR_FUCKING_2,
+ SFX_WFYPR_FUCKING_3,
+ SFX_WFYPR_FUCKING_4,
+ SFX_WFYPR_FUCKING_5,
+ SFX_WFYPR_GUN_COOL_1,
+ SFX_WFYPR_GUN_COOL_2,
+ SFX_WFYPR_GUN_COOL_3,
+ SFX_WFYPR_GUN_COOL_4,
+ SFX_WFYPR_GUN_COOL_5,
+ SFX_WFYPR_GUN_COOL_6,
+ SFX_WFYPR_MUGGED_1,
+ SFX_WFYPR_MUGGED_2,
+ SFX_WFYPR_SAVED_1,
+ SFX_WFYPR_SOLICIT_1,
+ SFX_WFYPR_SOLICIT_2,
+ SFX_WFYPR_SOLICIT_3,
+ SFX_WFYPR_SOLICIT_4,
+ SFX_WFYPR_SOLICIT_5,
+ SFX_WFYPR_SOLICIT_6,
+ SFX_WFYPR_SOLICIT_7,
+ SFX_WFYPR_SOLICIT_8,
+ SFX_WFYPR_SOLICIT_9,
+ SFX_WFYPR_SOLICIT_10,
+ SFX_WFYPR_SOLICIT_11,
+ SFX_WFYPR_SOLICIT_12,
+ SFX_WFYPR_SOLICIT_13,
+ SFX_WFYPR_SOLICIT_14,
+ SFX_WFYPR_SOLICIT_15,
+ SFX_WFYPR_TAXI_1,
+
+ SFX_WMYRI_BLOCKED_1,
+ SFX_WMYRI_BLOCKED_2,
+ SFX_WMYRI_BLOCKED_3,
+ SFX_WMYRI_BLOCKED_4,
+ SFX_WMYRI_BLOCKED_5,
+ SFX_WMYRI_BLOCKED_6,
+ SFX_WMYRI_BLOCKED_7,
+ SFX_WMYRI_BLOCKED_8,
+ SFX_WMYRI_BLOCKED_9,
+ SFX_WMYRI_BLOCKED_10,
+ SFX_WMYRI_BUMP_1,
+ SFX_WMYRI_BUMP_2,
+ SFX_WMYRI_BUMP_3,
+ SFX_WMYRI_BUMP_4,
+ SFX_WMYRI_BUMP_5,
+ SFX_WMYRI_BUMP_6,
+ SFX_WMYRI_BUMP_7,
+ SFX_WMYRI_BUMP_8,
+ SFX_WMYRI_CAR_CRASH_1,
+ SFX_WMYRI_CAR_CRASH_2,
+ SFX_WMYRI_CAR_CRASH_3,
+ SFX_WMYRI_CAR_CRASH_4,
+ SFX_WMYRI_CAR_CRASH_5,
+ SFX_WMYRI_CAR_CRASH_6,
+ SFX_WMYRI_CAR_CRASH_7,
+ SFX_WMYRI_CAR_CRASH_8,
+ SFX_WMYRI_CAR_CRASH_9,
+ SFX_WMYRI_CHAT_1,
+ SFX_WMYRI_CHAT_2,
+ SFX_WMYRI_CHAT_3,
+ SFX_WMYRI_CHAT_4,
+ SFX_WMYRI_CHAT_5,
+ SFX_WMYRI_CHAT_6,
+ SFX_WMYRI_CHAT_7,
+ SFX_WMYRI_CHAT_8,
+ SFX_WMYRI_CHAT_9,
+ SFX_WMYRI_CHAT_10,
+ SFX_WMYRI_DODGE_1,
+ SFX_WMYRI_DODGE_2,
+ SFX_WMYRI_DODGE_3,
+ SFX_WMYRI_DODGE_4,
+ SFX_WMYRI_DODGE_5,
+ SFX_WMYRI_DODGE_6,
+ SFX_WMYRI_DODGE_7,
+ SFX_WMYRI_DODGE_8,
+ SFX_WMYRI_DODGE_9,
+ SFX_WMYRI_EYEING_1,
+ SFX_WMYRI_EYEING_2,
+ SFX_WMYRI_EYEING_3,
+ SFX_WMYRI_GENERIC_CRASH_1,
+ SFX_WMYRI_GENERIC_CRASH_2,
+ SFX_WMYRI_GENERIC_CRASH_3,
+ SFX_WMYRI_GENERIC_CRASH_4,
+ SFX_WMYRI_GENERIC_CRASH_5,
+ SFX_WMYRI_GENERIC_CRASH_6,
+ SFX_WMYRI_GENERIC_CRASH_7,
+ SFX_WMYRI_GENERIC_CRASH_8,
+ SFX_WMYRI_GENERIC_CRASH_9,
+ SFX_WMYRI_GENERIC_CRASH_10,
+ SFX_WMYRI_GENERIC_CRASH_11,
+ SFX_WMYRI_GUN_PANIC_1,
+ SFX_WMYRI_GUN_PANIC_2,
+ SFX_WMYRI_GUN_PANIC_3,
+ SFX_WMYRI_GUN_PANIC_4,
+ SFX_WMYRI_GUN_PANIC_5,
+ SFX_WMYRI_GUN_PANIC_6,
+ SFX_WMYRI_GUN_PANIC_7,
+ SFX_WMYRI_GUN_PANIC_8,
+ SFX_WMYRI_JACKED_1,
+ SFX_WMYRI_JACKED_2,
+ SFX_WMYRI_JACKED_3,
+ SFX_WMYRI_JACKED_4,
+ SFX_WMYRI_JACKED_5,
+ SFX_WMYRI_JACKED_6,
+ SFX_WMYRI_JACKED_7,
+ SFX_WMYRI_JACKED_8,
+ SFX_WMYRI_LOST_1,
+ SFX_WMYRI_RUN_1,
+ SFX_WMYRI_RUN_2,
+ SFX_WMYRI_RUN_3,
+ SFX_WMYRI_RUN_4,
+ SFX_WMYRI_RUN_5,
+ SFX_WMYRI_SAVED_1,
+ SFX_WMYRI_SHOCKED_1,
+ SFX_WMYRI_SHOCKED_2,
+ SFX_WMYRI_SHOCKED_3,
+ SFX_WMYRI_SHOCKED_4,
+ SFX_WMYRI_TAXI_1,
+ SFX_WMYRI_TAXI_2,
+
+ SFX_BMOST_BUMP_1,
+ SFX_BMOST_BUMP_2,
+ SFX_BMOST_BUMP_3,
+ SFX_BMOST_BUMP_4,
+ SFX_BMOST_BUMP_5,
+ SFX_BMOST_BUMP_6,
+ SFX_BMOST_BUMP_7,
+ SFX_BMOST_BUMP_8,
+ SFX_BMOST_BUMP_9,
+ SFX_BMOST_BUMP_10,
+ SFX_BMOST_BUMP_11,
+ SFX_BMOST_BUMP_12,
+ SFX_BMOST_BUMP_13,
+ SFX_BMOST_BUMP_14,
+ SFX_BMOST_BUMP_15,
+ SFX_BMOST_BUMP_16,
+ SFX_BMOST_BUMP_17,
+ SFX_BMOST_CAR_CRASH_1,
+ SFX_BMOST_CAR_CRASH_2,
+ SFX_BMOST_CAR_CRASH_3,
+ SFX_BMOST_CAR_CRASH_4,
+ SFX_BMOST_CAR_CRASH_5,
+ SFX_BMOST_CAR_CRASH_6,
+ SFX_BMOST_CAR_CRASH_7,
+ SFX_BMOST_CAR_CRASH_8,
+ SFX_BMOST_CHAT_1,
+ SFX_BMOST_CHAT_2,
+ SFX_BMOST_CHAT_3,
+ SFX_BMOST_CHAT_4,
+ SFX_BMOST_CHAT_5,
+ SFX_BMOST_CHAT_6,
+ SFX_BMOST_CHAT_7,
+ SFX_BMOST_CHAT_8,
+ SFX_BMOST_CHAT_9,
+ SFX_BMOST_CHAT_10,
+ SFX_BMOST_CHAT_11,
+ SFX_BMOST_CHAT_12,
+ SFX_BMOST_CHAT_13,
+ SFX_BMOST_CHAT_14,
+ SFX_BMOST_CHAT_15,
+ SFX_BMOST_CHAT_16,
+ SFX_BMOST_CHAT_17,
+ SFX_BMOST_CHAT_18,
+ SFX_BMOST_DODGE_1,
+ SFX_BMOST_DODGE_2,
+ SFX_BMOST_DODGE_3,
+ SFX_BMOST_DODGE_4,
+ SFX_BMOST_DODGE_5,
+ SFX_BMOST_DODGE_6,
+ SFX_BMOST_DODGE_7,
+ SFX_BMOST_DODGE_8,
+ SFX_BMOST_EYEING_1,
+ SFX_BMOST_EYEING_2,
+ SFX_BMOST_EYEING_3,
+ SFX_BMOST_EYEING_4,
+ SFX_BMOST_EYEING_5,
+ SFX_BMOST_EYEING_6,
+ SFX_BMOST_FIGHT_1,
+ SFX_BMOST_FIGHT_2,
+ SFX_BMOST_FIGHT_3,
+ SFX_BMOST_FIGHT_4,
+ SFX_BMOST_FIGHT_5,
+ SFX_BMOST_FIGHT_6,
+ SFX_BMOST_FIGHT_7,
+ SFX_BMOST_GENERIC_CRASH_1,
+ SFX_BMOST_GENERIC_CRASH_2,
+ SFX_BMOST_GENERIC_CRASH_3,
+ SFX_BMOST_GENERIC_CRASH_4,
+ SFX_BMOST_GENERIC_CRASH_5,
+ SFX_BMOST_GENERIC_CRASH_6,
+ SFX_BMOST_GENERIC_CRASH_7,
+ SFX_BMOST_GENERIC_CRASH_8,
+ SFX_BMOST_GENERIC_CRASH_9,
+ SFX_BMOST_GENERIC_CRASH_10,
+ SFX_BMOST_GENERIC_CRASH_11,
+ SFX_BMOST_GENERIC_CRASH_12,
+ SFX_BMOST_GENERIC_CRASH_13,
+ SFX_BMOST_GUN_PANIC_1,
+ SFX_BMOST_GUN_PANIC_2,
+ SFX_BMOST_GUN_PANIC_3,
+ SFX_BMOST_GUN_PANIC_4,
+ SFX_BMOST_GUN_PANIC_5,
+ SFX_BMOST_GUN_PANIC_6,
+ SFX_BMOST_GUN_PANIC_7,
+ SFX_BMOST_GUN_PANIC_8,
+ SFX_BMOST_GUN_PANIC_9,
+ SFX_BMOST_LOST_1,
+ SFX_BMOST_LOST_2,
+ SFX_BMOST_LOST_3,
+ SFX_BMOST_LOST_4,
+ SFX_BMOST_LOST_5,
+ SFX_BMOST_LOST_6,
+ SFX_BMOST_MUGGED_1,
+ SFX_BMOST_MUGGED_2,
+ SFX_BMOST_MUGGED_3,
+ SFX_BMOST_MUGGED_4,
+ SFX_BMOST_SAVED_1,
+ SFX_BMOST_TAXI_1,
+
+ SFX_HFOST_BLOCKED_1,
+ SFX_HFOST_BLOCKED_2,
+ SFX_HFOST_BLOCKED_3,
+ SFX_HFOST_BLOCKED_4,
+ SFX_HFOST_BLOCKED_5,
+ SFX_HFOST_BLOCKED_6,
+ SFX_HFOST_BLOCKED_7,
+ SFX_HFOST_BLOCKED_8,
+ SFX_HFOST_BLOCKED_9,
+ SFX_HFOST_BUMP_1,
+ SFX_HFOST_BUMP_2,
+ SFX_HFOST_BUMP_3,
+ SFX_HFOST_BUMP_4,
+ SFX_HFOST_BUMP_5,
+ SFX_HFOST_BUMP_6,
+ SFX_HFOST_BUMP_7,
+ SFX_HFOST_BUMP_8,
+ SFX_HFOST_BUMP_9,
+ SFX_HFOST_BUMP_10,
+ SFX_HFOST_BUMP_11,
+ SFX_HFOST_BUMP_12,
+ SFX_HFOST_CAR_CRASH_1,
+ SFX_HFOST_CAR_CRASH_2,
+ SFX_HFOST_CAR_CRASH_3,
+ SFX_HFOST_CAR_CRASH_4,
+ SFX_HFOST_CAR_CRASH_5,
+ SFX_HFOST_CAR_CRASH_6,
+ SFX_HFOST_CAR_CRASH_7,
+ SFX_HFOST_CAR_CRASH_8,
+ SFX_HFOST_CHAT_1,
+ SFX_HFOST_CHAT_2,
+ SFX_HFOST_CHAT_3,
+ SFX_HFOST_CHAT_4,
+ SFX_HFOST_CHAT_5,
+ SFX_HFOST_CHAT_6,
+ SFX_HFOST_CHAT_7,
+ SFX_HFOST_CHAT_8,
+ SFX_HFOST_CHAT_9,
+ SFX_HFOST_CHAT_10,
+ SFX_HFOST_CHAT_11,
+ SFX_HFOST_DODGE_1,
+ SFX_HFOST_DODGE_2,
+ SFX_HFOST_DODGE_3,
+ SFX_HFOST_DODGE_4,
+ SFX_HFOST_DODGE_5,
+ SFX_HFOST_DODGE_6,
+ SFX_HFOST_DODGE_7,
+ SFX_HFOST_DODGE_8,
+ SFX_HFOST_DODGE_9,
+ SFX_HFOST_DODGE_10,
+ SFX_HFOST_FIGHT_1,
+ SFX_HFOST_FIGHT_2,
+ SFX_HFOST_FIGHT_3,
+ SFX_HFOST_FIGHT_4,
+ SFX_HFOST_FIGHT_5,
+ SFX_HFOST_FIGHT_6,
+ SFX_HFOST_FIGHT_7,
+ SFX_HFOST_FIGHT_8,
+ SFX_HFOST_GENERIC_CRASH_1,
+ SFX_HFOST_GENERIC_CRASH_2,
+ SFX_HFOST_GENERIC_CRASH_3,
+ SFX_HFOST_GENERIC_CRASH_4,
+ SFX_HFOST_GENERIC_CRASH_5,
+ SFX_HFOST_GENERIC_CRASH_6,
+ SFX_HFOST_GENERIC_CRASH_7,
+ SFX_HFOST_GENERIC_CRASH_8,
+ SFX_HFOST_GENERIC_CRASH_9,
+ SFX_HFOST_GENERIC_CRASH_10,
+ SFX_HFOST_GENERIC_CRASH_11,
+ SFX_HFOST_GUN_COOL_1,
+ SFX_HFOST_GUN_COOL_2,
+ SFX_HFOST_GUN_COOL_3,
+ SFX_HFOST_GUN_COOL_4,
+ SFX_HFOST_GUN_COOL_5,
+ SFX_HFOST_GUN_COOL_6,
+ SFX_HFOST_JACKED_1,
+ SFX_HFOST_JACKED_2,
+ SFX_HFOST_JACKED_3,
+ SFX_HFOST_JACKED_4,
+ SFX_HFOST_JACKED_5,
+ SFX_HFOST_JACKED_6,
+ SFX_HFOST_JACKED_7,
+ SFX_HFOST_JACKED_8,
+ SFX_HFOST_LOST_1,
+ SFX_HFOST_LOST_2,
+ SFX_HFOST_MUGGED_1,
+ SFX_HFOST_MUGGED_2,
+ SFX_HFOST_MUGGED_3,
+ SFX_HFOST_TAXI_1,
+ SFX_HFOST_TAXI_2,
+
+ SFX_HMORI_BLOCKED_1,
+ SFX_HMORI_BLOCKED_2,
+ SFX_HMORI_BLOCKED_3,
+ SFX_HMORI_BLOCKED_4,
+ SFX_HMORI_BLOCKED_5,
+ SFX_HMORI_BLOCKED_6,
+ SFX_HMORI_BLOCKED_7,
+ SFX_HMORI_BLOCKED_8,
+ SFX_HMORI_BUMP_1,
+ SFX_HMORI_BUMP_2,
+ SFX_HMORI_BUMP_3,
+ SFX_HMORI_BUMP_4,
+ SFX_HMORI_BUMP_5,
+ SFX_HMORI_BUMP_6,
+ SFX_HMORI_BUMP_7,
+ SFX_HMORI_BUMP_8,
+ SFX_HMORI_BUMP_9,
+ SFX_HMORI_BUMP_10,
+ SFX_HMORI_BUMP_11,
+ SFX_HMORI_CAR_CRASH_1,
+ SFX_HMORI_CAR_CRASH_2,
+ SFX_HMORI_CAR_CRASH_3,
+ SFX_HMORI_CAR_CRASH_4,
+ SFX_HMORI_CAR_CRASH_5,
+ SFX_HMORI_CAR_CRASH_6,
+ SFX_HMORI_CHAT_1,
+ SFX_HMORI_CHAT_2,
+ SFX_HMORI_CHAT_3,
+ SFX_HMORI_CHAT_4,
+ SFX_HMORI_CHAT_5,
+ SFX_HMORI_CHAT_6,
+ SFX_HMORI_CHAT_7,
+ SFX_HMORI_CHAT_8,
+ SFX_HMORI_DODGE_1,
+ SFX_HMORI_DODGE_2,
+ SFX_HMORI_DODGE_3,
+ SFX_HMORI_DODGE_4,
+ SFX_HMORI_DODGE_5,
+ SFX_HMORI_DODGE_6,
+ SFX_HMORI_DODGE_7,
+ SFX_HMORI_GENERIC_CRASH_1,
+ SFX_HMORI_GENERIC_CRASH_2,
+ SFX_HMORI_GENERIC_CRASH_3,
+ SFX_HMORI_GENERIC_CRASH_4,
+ SFX_HMORI_GENERIC_CRASH_5,
+ SFX_HMORI_GENERIC_CRASH_6,
+ SFX_HMORI_GENERIC_CRASH_7,
+ SFX_HMORI_GENERIC_CRASH_8,
+ SFX_HMORI_GENERIC_CRASH_9,
+ SFX_HMORI_GENERIC_CRASH_10,
+ SFX_HMORI_GENERIC_CRASH_11,
+ SFX_HMORI_GUN_PANIC_1,
+ SFX_HMORI_GUN_PANIC_2,
+ SFX_HMORI_GUN_PANIC_3,
+ SFX_HMORI_GUN_PANIC_4,
+ SFX_HMORI_GUN_PANIC_5,
+ SFX_HMORI_JACKED_1,
+ SFX_HMORI_JACKED_2,
+ SFX_HMORI_JACKED_3,
+ SFX_HMORI_JACKED_4,
+ SFX_HMORI_JACKED_5,
+ SFX_HMORI_JACKED_6,
+ SFX_HMORI_JACKED_7,
+ SFX_HMORI_JACKED_8,
+ SFX_HMORI_LOST_1,
+ SFX_HMORI_LOST_2,
+ SFX_HMORI_MUGGED_1,
+ SFX_HMORI_MUGGED_2,
+ SFX_HMORI_MUGGED_3,
+ SFX_HMORI_RUN_1,
+ SFX_HMORI_RUN_2,
+ SFX_HMORI_RUN_3,
+ SFX_HMORI_RUN_4,
+ SFX_HMORI_RUN_5,
+ SFX_HMORI_RUN_6,
+ SFX_HMORI_TAXI_1,
+ SFX_HMORI_TAXI_2,
+
+ SFX_HMOTR_BUMP_1,
+ SFX_HMOTR_BUMP_2,
+ SFX_HMOTR_BUMP_3,
+ SFX_HMOTR_BUMP_4,
+ SFX_HMOTR_BUMP_5,
+ SFX_HMOTR_BUMP_6,
+ SFX_HMOTR_BUMP_7,
+ SFX_HMOTR_BUMP_8,
+ SFX_HMOTR_CHAT_1,
+ SFX_HMOTR_CHAT_2,
+ SFX_HMOTR_CHAT_3,
+ SFX_HMOTR_CHAT_4,
+ SFX_HMOTR_CHAT_5,
+ SFX_HMOTR_CHAT_6,
+ SFX_HMOTR_CHAT_7,
+ SFX_HMOTR_CHAT_8,
+ SFX_HMOTR_CHAT_9,
+ SFX_HMOTR_DODGE_1,
+ SFX_HMOTR_DODGE_2,
+ SFX_HMOTR_DODGE_3,
+ SFX_HMOTR_DODGE_4,
+ SFX_HMOTR_DODGE_5,
+ SFX_HMOTR_DODGE_6,
+ SFX_HMOTR_DODGE_7,
+ SFX_HMOTR_DODGE_8,
+ SFX_HMOTR_DODGE_9,
+ SFX_HMOTR_DODGE_10,
+ SFX_HMOTR_DODGE_11,
+ SFX_HMOTR_FIGHT_1,
+ SFX_HMOTR_FIGHT_2,
+ SFX_HMOTR_FIGHT_3,
+ SFX_HMOTR_FIGHT_4,
+ SFX_HMOTR_FIGHT_5,
+ SFX_HMOTR_FIGHT_6,
+ SFX_HMOTR_FIGHT_7,
+ SFX_HMOTR_GUN_COOL_1,
+ SFX_HMOTR_GUN_COOL_2,
+ SFX_HMOTR_GUN_COOL_3,
+ SFX_HMOTR_GUN_COOL_4,
+ SFX_HMOTR_GUN_COOL_5,
+ SFX_HMOTR_GUN_COOL_6,
+ SFX_HMOTR_SAVED_1,
+ SFX_HMOTR_SAVED_2,
+ SFX_HMOTR_SHOCKED_1,
+ SFX_HMOTR_SHOCKED_2,
+ SFX_HMOTR_SHOCKED_3,
+ SFX_HMOTR_SOLICIT_1,
+ SFX_HMOTR_SOLICIT_2,
+ SFX_HMOTR_SOLICIT_3,
+ SFX_HMOTR_SOLICIT_4,
+ SFX_HMOTR_SOLICIT_5,
+ SFX_HMOTR_SOLICIT_6,
+ SFX_HMOTR_SOLICIT_7,
+ SFX_HMOTR_SOLICIT_8,
+ SFX_HMOTR_TAXI_1,
+
+ SFX_HMYAP_BLOCKED_1,
+ SFX_HMYAP_BLOCKED_2,
+ SFX_HMYAP_BLOCKED_3,
+ SFX_HMYAP_BLOCKED_4,
+ SFX_HMYAP_BLOCKED_5,
+ SFX_HMYAP_BLOCKED_6,
+ SFX_HMYAP_BLOCKED_7,
+ SFX_HMYAP_BLOCKED_8,
+ SFX_HMYAP_BLOCKED_9,
+ SFX_HMYAP_BUMP_1,
+ SFX_HMYAP_BUMP_2,
+ SFX_HMYAP_BUMP_3,
+ SFX_HMYAP_BUMP_4,
+ SFX_HMYAP_BUMP_5,
+ SFX_HMYAP_BUMP_6,
+ SFX_HMYAP_BUMP_7,
+ SFX_HMYAP_BUMP_8,
+ SFX_HMYAP_BUMP_9,
+ SFX_HMYAP_BUMP_10,
+ SFX_HMYAP_BUMP_11,
+ SFX_HMYAP_CAR_CRASH_1,
+ SFX_HMYAP_CAR_CRASH_2,
+ SFX_HMYAP_CAR_CRASH_3,
+ SFX_HMYAP_CAR_CRASH_4,
+ SFX_HMYAP_CAR_CRASH_5,
+ SFX_HMYAP_CAR_CRASH_6,
+ SFX_HMYAP_CAR_CRASH_7,
+ SFX_HMYAP_CAR_CRASH_8,
+ SFX_HMYAP_CAR_CRASH_9,
+ SFX_HMYAP_CHAT_1,
+ SFX_HMYAP_CHAT_2,
+ SFX_HMYAP_CHAT_3,
+ SFX_HMYAP_CHAT_4,
+ SFX_HMYAP_CHAT_5,
+ SFX_HMYAP_CHAT_6,
+ SFX_HMYAP_CHAT_7,
+ SFX_HMYAP_CHAT_8,
+ SFX_HMYAP_CHAT_9,
+ SFX_HMYAP_DODGE_1,
+ SFX_HMYAP_DODGE_2,
+ SFX_HMYAP_DODGE_3,
+ SFX_HMYAP_DODGE_4,
+ SFX_HMYAP_DODGE_5,
+ SFX_HMYAP_DODGE_6,
+ SFX_HMYAP_DODGE_7,
+ SFX_HMYAP_DODGE_8,
+ SFX_HMYAP_DODGE_9,
+ SFX_HMYAP_EYEING_1,
+ SFX_HMYAP_EYEING_2,
+ SFX_HMYAP_EYEING_3,
+ SFX_HMYAP_GENERIC_CRASH_1,
+ SFX_HMYAP_GENERIC_CRASH_2,
+ SFX_HMYAP_GENERIC_CRASH_3,
+ SFX_HMYAP_GENERIC_CRASH_4,
+ SFX_HMYAP_GENERIC_CRASH_5,
+ SFX_HMYAP_GENERIC_CRASH_6,
+ SFX_HMYAP_GUN_PANIC_1,
+ SFX_HMYAP_GUN_PANIC_2,
+ SFX_HMYAP_GUN_PANIC_3,
+ SFX_HMYAP_GUN_PANIC_4,
+ SFX_HMYAP_GUN_PANIC_5,
+ SFX_HMYAP_GUN_PANIC_6,
+ SFX_HMYAP_GUN_PANIC_7,
+ SFX_HMYAP_JACKED_1,
+ SFX_HMYAP_JACKED_2,
+ SFX_HMYAP_JACKED_3,
+ SFX_HMYAP_JACKED_4,
+ SFX_HMYAP_JACKED_5,
+ SFX_HMYAP_JACKED_6,
+ SFX_HMYAP_JACKED_7,
+ SFX_HMYAP_JACKING_1,
+ SFX_HMYAP_JACKING_2,
+ SFX_HMYAP_JACKING_3,
+ SFX_HMYAP_JACKING_4,
+ SFX_HMYAP_LOST_1,
+ SFX_HMYAP_LOST_2,
+ SFX_HMYAP_MUGGED_1,
+ SFX_HMYAP_MUGGED_2,
+ SFX_HMYAP_RUN_1,
+ SFX_HMYAP_RUN_2,
+ SFX_HMYAP_RUN_3,
+ SFX_HMYAP_RUN_4,
+ SFX_HMYAP_RUN_5,
+ SFX_HMYAP_RUN_6,
+ SFX_HMYAP_SAVED_1,
+ SFX_HMYAP_SAVED_2,
+ SFX_HMYAP_TAXI_1,
+ SFX_HMYAP_TAXI_2,
+
+ SFX_HFOTR_BUMP_1,
+ SFX_HFOTR_BUMP_2,
+ SFX_HFOTR_BUMP_3,
+ SFX_HFOTR_BUMP_4,
+ SFX_HFOTR_BUMP_5,
+ SFX_HFOTR_BUMP_6,
+ SFX_HFOTR_BUMP_7,
+ SFX_HFOTR_BUMP_8,
+ SFX_HFOTR_BUMP_9,
+ SFX_HFOTR_BUMP_10,
+ SFX_HFOTR_BUMP_11,
+ SFX_HFOTR_CHAT_1,
+ SFX_HFOTR_CHAT_2,
+ SFX_HFOTR_CHAT_3,
+ SFX_HFOTR_CHAT_4,
+ SFX_HFOTR_CHAT_5,
+ SFX_HFOTR_CHAT_6,
+ SFX_HFOTR_CHAT_7,
+ SFX_HFOTR_CHAT_8,
+ SFX_HFOTR_CHAT_9,
+ SFX_HFOTR_CHAT_10,
+ SFX_HFOTR_CHAT_11,
+ SFX_HFOTR_CHAT_12,
+ SFX_HFOTR_DODGE_1,
+ SFX_HFOTR_DODGE_2,
+ SFX_HFOTR_DODGE_3,
+ SFX_HFOTR_DODGE_4,
+ SFX_HFOTR_DODGE_5,
+ SFX_HFOTR_DODGE_6,
+ SFX_HFOTR_DODGE_7,
+ SFX_HFOTR_DODGE_8,
+ SFX_HFOTR_FIGHT_1,
+ SFX_HFOTR_FIGHT_2,
+ SFX_HFOTR_FIGHT_3,
+ SFX_HFOTR_FIGHT_4,
+ SFX_HFOTR_FIGHT_5,
+ SFX_HFOTR_FIGHT_6,
+ SFX_HFOTR_GUN_COOL_1,
+ SFX_HFOTR_GUN_COOL_2,
+ SFX_HFOTR_GUN_COOL_3,
+ SFX_HFOTR_GUN_COOL_4,
+ SFX_HFOTR_GUN_COOL_5,
+ SFX_HFOTR_MUGGED_1,
+ SFX_HFOTR_MUGGED_2,
+ SFX_HFOTR_SAVED_1,
+ SFX_HFOTR_SHOCKED_1,
+ SFX_HFOTR_SHOCKED_2,
+ SFX_HFOTR_TAXI_1,
+ SFX_HFOTR_TAXI_2,
+
+ SFX_HMOBE_BLOCKED_1,
+ SFX_HMOBE_BLOCKED_2,
+ SFX_HMOBE_BLOCKED_3,
+ SFX_HMOBE_BLOCKED_4,
+ SFX_HMOBE_BLOCKED_5,
+ SFX_HMOBE_BLOCKED_6,
+ SFX_HMOBE_BLOCKED_7,
+ SFX_HMOBE_BLOCKED_8,
+ SFX_HMOBE_BLOCKED_9,
+ SFX_HMOBE_BLOCKED_10,
+ SFX_HMOBE_BUMP_1,
+ SFX_HMOBE_BUMP_2,
+ SFX_HMOBE_BUMP_3,
+ SFX_HMOBE_BUMP_4,
+ SFX_HMOBE_BUMP_5,
+ SFX_HMOBE_BUMP_6,
+ SFX_HMOBE_BUMP_7,
+ SFX_HMOBE_BUMP_8,
+ SFX_HMOBE_DODGE_1,
+ SFX_HMOBE_DODGE_2,
+ SFX_HMOBE_DODGE_3,
+ SFX_HMOBE_DODGE_4,
+ SFX_HMOBE_DODGE_5,
+ SFX_HMOBE_DODGE_6,
+ SFX_HMOBE_DODGE_7,
+ SFX_HMOBE_DODGE_8,
+ SFX_HMOBE_DODGE_9,
+ SFX_HMOBE_EYEING_1,
+ SFX_HMOBE_EYEING_2,
+ SFX_HMOBE_EYEING_3,
+ SFX_HMOBE_EYEING_4,
+ SFX_HMOBE_GUN_PANIC_1,
+ SFX_HMOBE_GUN_PANIC_2,
+ SFX_HMOBE_GUN_PANIC_3,
+ SFX_HMOBE_INNOCENT_1,
+ SFX_HMOBE_INNOCENT_2,
+ SFX_HMOBE_INNOCENT_3,
+ SFX_HMOBE_JACKED_1,
+ SFX_HMOBE_JACKED_2,
+ SFX_HMOBE_JACKED_3,
+ SFX_HMOBE_JACKED_4,
+ SFX_HMOBE_JACKED_5,
+ SFX_HMOBE_JACKED_6,
+
+ SFX_HFYBU_BLOCKED_1,
+ SFX_HFYBU_BLOCKED_2,
+ SFX_HFYBU_BLOCKED_3,
+ SFX_HFYBU_BLOCKED_4,
+ SFX_HFYBU_BLOCKED_5,
+ SFX_HFYBU_BLOCKED_6,
+ SFX_HFYBU_BLOCKED_7,
+ SFX_HFYBU_BLOCKED_8,
+ SFX_HFYBU_BUMP_1,
+ SFX_HFYBU_BUMP_2,
+ SFX_HFYBU_BUMP_3,
+ SFX_HFYBU_BUMP_4,
+ SFX_HFYBU_BUMP_5,
+ SFX_HFYBU_BUMP_6,
+ SFX_HFYBU_BUMP_7,
+ SFX_HFYBU_BUMP_8,
+ SFX_HFYBU_BUMP_9,
+ SFX_HFYBU_BUMP_10,
+ SFX_HFYBU_BUMP_11,
+ SFX_HFYBU_CAR_CRASH_1,
+ SFX_HFYBU_CAR_CRASH_2,
+ SFX_HFYBU_CAR_CRASH_3,
+ SFX_HFYBU_CAR_CRASH_4,
+ SFX_HFYBU_CAR_CRASH_5,
+ SFX_HFYBU_CAR_CRASH_6,
+ SFX_HFYBU_CAR_CRASH_7,
+ SFX_HFYBU_CAR_CRASH_8,
+ SFX_HFYBU_DODGE_1,
+ SFX_HFYBU_DODGE_2,
+ SFX_HFYBU_DODGE_3,
+ SFX_HFYBU_DODGE_4,
+ SFX_HFYBU_DODGE_5,
+ SFX_HFYBU_DODGE_6,
+ SFX_HFYBU_DODGE_7,
+ SFX_HFYBU_DODGE_8,
+ SFX_HFYBU_DODGE_9,
+ SFX_HFYBU_DODGE_10,
+ SFX_HFYBU_FIGHT_1,
+ SFX_HFYBU_FIGHT_2,
+ SFX_HFYBU_FIGHT_3,
+ SFX_HFYBU_FIGHT_4,
+ SFX_HFYBU_FIGHT_5,
+ SFX_HFYBU_FIGHT_6,
+ SFX_HFYBU_FIGHT_7,
+ SFX_HFYBU_GENERIC_CRASH_1,
+ SFX_HFYBU_GENERIC_CRASH_2,
+ SFX_HFYBU_GENERIC_CRASH_3,
+ SFX_HFYBU_GENERIC_CRASH_4,
+ SFX_HFYBU_GENERIC_CRASH_5,
+ SFX_HFYBU_GENERIC_CRASH_6,
+ SFX_HFYBU_GENERIC_CRASH_7,
+ SFX_HFYBU_GENERIC_CRASH_8,
+ SFX_HFYBU_GENERIC_CRASH_9,
+ SFX_HFYBU_GENERIC_CRASH_10,
+ SFX_HFYBU_GENERIC_CRASH_11,
+ SFX_HFYBU_GENERIC_CRASH_12,
+ SFX_HFYBU_GUN_PANIC_1,
+ SFX_HFYBU_GUN_PANIC_2,
+ SFX_HFYBU_GUN_PANIC_3,
+ SFX_HFYBU_GUN_PANIC_4,
+ SFX_HFYBU_GUN_PANIC_5,
+ SFX_HFYBU_JACKED_1,
+ SFX_HFYBU_JACKED_2,
+ SFX_HFYBU_JACKED_3,
+ SFX_HFYBU_JACKED_4,
+ SFX_HFYBU_JACKED_5,
+ SFX_HFYBU_JACKED_6,
+ SFX_HFYBU_JACKING_1,
+ SFX_HFYBU_JACKING_2,
+ SFX_HFYBU_JACKING_3,
+ SFX_HFYBU_LOST_1,
+ SFX_HFYBU_LOST_2,
+ SFX_HFYBU_MUGGED_1,
+ SFX_HFYBU_MUGGED_2,
+ SFX_HFYBU_SAVED_1,
+ SFX_HFYBU_TAXI_1,
+
+ SFX_HFYCG_BUMP_1,
+ SFX_HFYCG_BUMP_2,
+ SFX_HFYCG_BUMP_3,
+ SFX_HFYCG_BUMP_4,
+ SFX_HFYCG_BUMP_5,
+ SFX_HFYCG_BUMP_6,
+ SFX_HFYCG_BUMP_7,
+ SFX_HFYCG_BUMP_8,
+ SFX_HFYCG_BUMP_9,
+ SFX_HFYCG_DODGE_1,
+ SFX_HFYCG_DODGE_2,
+ SFX_HFYCG_DODGE_3,
+ SFX_HFYCG_DODGE_4,
+ SFX_HFYCG_DODGE_5,
+ SFX_HFYCG_DODGE_6,
+ SFX_HFYCG_DODGE_7,
+ SFX_HFYCG_DODGE_8,
+ SFX_HFYCG_GUN_PANIC_1,
+ SFX_HFYCG_GUN_PANIC_2,
+ SFX_HFYCG_GUN_PANIC_3,
+ SFX_HFYCG_GUN_PANIC_4,
+ SFX_HFYCG_GUN_PANIC_5,
+ SFX_HFYCG_MUGGED_1,
+ SFX_HFYCG_MUGGED_2,
+ SFX_HFYCG_RUN_1,
+ SFX_HFYCG_RUN_2,
+ SFX_HFYCG_RUN_3,
+ SFX_HFYCG_RUN_4,
+ SFX_HFYCG_SAVED_1,
+ SFX_HFYCG_SOLICIT_1,
+ SFX_HFYCG_SOLICIT_2,
+ SFX_HFYCG_SOLICIT_3,
+ SFX_HFYCG_SOLICIT_4,
+ SFX_HFYCG_SOLICIT_5,
+ SFX_HFYCG_SOLICIT_6,
+ SFX_HFYCG_SOLICIT_7,
+ SFX_HFYCG_SOLICIT_8,
+ SFX_HFYCG_SOLICIT_9,
+ SFX_HFYCG_SOLICIT_10,
+ SFX_HFYCG_SOLICIT_11,
+ SFX_HFYCG_SOLICIT_12,
+ SFX_HFYCG_SOLICIT_13,
+ SFX_HFYCG_SOLICIT_14,
+ SFX_HFYCG_TAXI_1,
+
+ SFX_HMYBE_BUMP_1,
+ SFX_HMYBE_BUMP_2,
+ SFX_HMYBE_BUMP_3,
+ SFX_HMYBE_BUMP_4,
+ SFX_HMYBE_BUMP_5,
+ SFX_HMYBE_BUMP_6,
+ SFX_HMYBE_BUMP_7,
+ SFX_HMYBE_BUMP_8,
+ SFX_HMYBE_BUMP_9,
+ SFX_HMYBE_BUMP_10,
+ SFX_HMYBE_CAR_CRASH_1,
+ SFX_HMYBE_CAR_CRASH_2,
+ SFX_HMYBE_CAR_CRASH_3,
+ SFX_HMYBE_CAR_CRASH_4,
+ SFX_HMYBE_CAR_CRASH_5,
+ SFX_HMYBE_CAR_CRASH_6,
+ SFX_HMYBE_CAR_CRASH_7,
+ SFX_HMYBE_CHAT_1,
+ SFX_HMYBE_CHAT_2,
+ SFX_HMYBE_CHAT_3,
+ SFX_HMYBE_CHAT_4,
+ SFX_HMYBE_CHAT_5,
+ SFX_HMYBE_CHAT_6,
+ SFX_HMYBE_CHAT_7,
+ SFX_HMYBE_CHAT_8,
+ SFX_HMYBE_CHAT_9,
+ SFX_HMYBE_CHAT_10,
+ SFX_HMYBE_DODGE_1,
+ SFX_HMYBE_DODGE_2,
+ SFX_HMYBE_DODGE_3,
+ SFX_HMYBE_DODGE_4,
+ SFX_HMYBE_DODGE_5,
+ SFX_HMYBE_DODGE_6,
+ SFX_HMYBE_DODGE_7,
+ SFX_HMYBE_EYEING_1,
+ SFX_HMYBE_EYEING_2,
+ SFX_HMYBE_EYEING_3,
+ SFX_HMYBE_EYEING_4,
+ SFX_HMYBE_EYEING_5,
+ SFX_HMYBE_FIGHT_1,
+ SFX_HMYBE_FIGHT_2,
+ SFX_HMYBE_FIGHT_3,
+ SFX_HMYBE_FIGHT_4,
+ SFX_HMYBE_FIGHT_5,
+ SFX_HMYBE_FIGHT_6,
+ SFX_HMYBE_FIGHT_7,
+ SFX_HMYBE_FIGHT_8,
+ SFX_HMYBE_GENERIC_CRASH_1,
+ SFX_HMYBE_GENERIC_CRASH_2,
+ SFX_HMYBE_GENERIC_CRASH_3,
+ SFX_HMYBE_GENERIC_CRASH_4,
+ SFX_HMYBE_GENERIC_CRASH_5,
+ SFX_HMYBE_GENERIC_CRASH_6,
+ SFX_HMYBE_GENERIC_CRASH_7,
+ SFX_HMYBE_GENERIC_CRASH_8,
+ SFX_HMYBE_GENERIC_CRASH_9,
+ SFX_HMYBE_GENERIC_CRASH_10,
+ SFX_HMYBE_GUN_PANIC_1,
+ SFX_HMYBE_GUN_PANIC_2,
+ SFX_HMYBE_GUN_PANIC_3,
+ SFX_HMYBE_GUN_PANIC_4,
+ SFX_HMYBE_GUN_PANIC_5,
+ SFX_HMYBE_GUN_PANIC_6,
+ SFX_HMYBE_INNOCENT_1,
+ SFX_HMYBE_INNOCENT_2,
+ SFX_HMYBE_INNOCENT_3,
+ SFX_HMYBE_INNOCENT_4,
+ SFX_HMYBE_JACKED_1,
+ SFX_HMYBE_JACKED_2,
+ SFX_HMYBE_JACKED_3,
+ SFX_HMYBE_JACKED_4,
+ SFX_HMYBE_JACKED_5,
+ SFX_HMYBE_JACKED_6,
+ SFX_HMYBE_JACKED_7,
+ SFX_HMYBE_JACKED_8,
+ SFX_HMYBE_JACKED_9,
+ SFX_HMYBE_JACKED_10,
+ SFX_HMYBE_JACKED_11,
+ SFX_HMYBE_JACKED_12,
+ SFX_HMYBE_LOST_1,
+ SFX_HMYBE_LOST_2,
+ SFX_HMYBE_LOST_3,
+ SFX_HMYBE_SAVED_1,
+ SFX_HMYBE_SHOCKED_1,
+ SFX_HMYBE_SHOCKED_2,
+ SFX_HMYBE_TAXI_1,
+
+ SFX_WMOGO_BUMP_1,
+ SFX_WMOGO_BUMP_2,
+ SFX_WMOGO_BUMP_3,
+ SFX_WMOGO_BUMP_4,
+ SFX_WMOGO_BUMP_5,
+ SFX_WMOGO_BUMP_6,
+ SFX_WMOGO_BUMP_7,
+ SFX_WMOGO_BUMP_8,
+ SFX_WMOGO_CAR_CRASH_1,
+ SFX_WMOGO_CAR_CRASH_2,
+ SFX_WMOGO_CAR_CRASH_3,
+ SFX_WMOGO_CAR_CRASH_4,
+ SFX_WMOGO_CAR_CRASH_5,
+ SFX_WMOGO_CAR_CRASH_6,
+ SFX_WMOGO_CAR_CRASH_7,
+ SFX_WMOGO_CAR_CRASH_8,
+ SFX_WMOGO_CAR_CRASH_9,
+ SFX_WMOGO_CHAT_1,
+ SFX_WMOGO_CHAT_2,
+ SFX_WMOGO_CHAT_3,
+ SFX_WMOGO_CHAT_4,
+ SFX_WMOGO_CHAT_5,
+ SFX_WMOGO_CHAT_6,
+ SFX_WMOGO_CHAT_7,
+ SFX_WMOGO_CHAT_8,
+ SFX_WMOGO_CHAT_9,
+ SFX_WMOGO_DODGE_1,
+ SFX_WMOGO_DODGE_2,
+ SFX_WMOGO_DODGE_3,
+ SFX_WMOGO_DODGE_4,
+ SFX_WMOGO_DODGE_5,
+ SFX_WMOGO_DODGE_6,
+ SFX_WMOGO_DODGE_7,
+ SFX_WMOGO_DODGE_8,
+ SFX_WMOGO_DODGE_9,
+ SFX_WMOGO_DODGE_10,
+ SFX_WMOGO_DODGE_11,
+ SFX_WMOGO_DODGE_12,
+ SFX_WMOGO_EYEING_1,
+ SFX_WMOGO_EYEING_2,
+ SFX_WMOGO_FIGHT_1,
+ SFX_WMOGO_FIGHT_2,
+ SFX_WMOGO_FIGHT_3,
+ SFX_WMOGO_FIGHT_4,
+ SFX_WMOGO_FIGHT_5,
+ SFX_WMOGO_FIGHT_6,
+ SFX_WMOGO_FIGHT_7,
+ SFX_WMOGO_FIGHT_8,
+ SFX_WMOGO_FIGHT_9,
+ SFX_WMOGO_FIGHT_10,
+ SFX_WMOGO_FIGHT_11,
+ SFX_WMOGO_FIGHT_12,
+ SFX_WMOGO_FIGHT_13,
+ SFX_WMOGO_GENERIC_CRASH_1,
+ SFX_WMOGO_GENERIC_CRASH_2,
+ SFX_WMOGO_GENERIC_CRASH_3,
+ SFX_WMOGO_GENERIC_CRASH_4,
+ SFX_WMOGO_GENERIC_CRASH_5,
+ SFX_WMOGO_GENERIC_CRASH_6,
+ SFX_WMOGO_GENERIC_CRASH_7,
+ SFX_WMOGO_GENERIC_CRASH_8,
+ SFX_WMOGO_GUN_PANIC_1,
+ SFX_WMOGO_GUN_PANIC_2,
+ SFX_WMOGO_GUN_PANIC_3,
+ SFX_WMOGO_GUN_PANIC_4,
+ SFX_WMOGO_GUN_PANIC_5,
+ SFX_WMOGO_JACKED_1,
+ SFX_WMOGO_JACKED_2,
+ SFX_WMOGO_JACKED_3,
+ SFX_WMOGO_JACKED_4,
+ SFX_WMOGO_JACKED_5,
+ SFX_WMOGO_JACKED_6,
+ SFX_WMOGO_RUN_1,
+ SFX_WMOGO_RUN_2,
+ SFX_WMOGO_RUN_3,
+ SFX_WMOGO_RUN_4,
+ SFX_WMOGO_RUN_5,
+ SFX_WMOGO_SAVED_1,
+ SFX_WMOGO_SHOCKED_1,
+ SFX_WMOGO_SHOCKED_2,
+ SFX_WMOGO_SHOCKED_3,
+ SFX_WMOGO_TAXI_1,
+
+ SFX_WMYCR_BUMP_1,
+ SFX_WMYCR_BUMP_2,
+ SFX_WMYCR_BUMP_3,
+ SFX_WMYCR_BUMP_4,
+ SFX_WMYCR_BUMP_5,
+ SFX_WMYCR_BUMP_6,
+ SFX_WMYCR_BUMP_7,
+ SFX_WMYCR_BUMP_8,
+ SFX_WMYCR_BUMP_9,
+ SFX_WMYCR_BUMP_10,
+ SFX_WMYCR_BUMP_11,
+ SFX_WMYCR_BUMP_12,
+ SFX_WMYCR_BUMP_13,
+ SFX_WMYCR_BUMP_14,
+ SFX_WMYCR_BUMP_15,
+ SFX_WMYCR_BUMP_16,
+ SFX_WMYCR_BUMP_17,
+ SFX_WMYCR_BUMP_18,
+ SFX_WMYCR_CAR_CRASH_1,
+ SFX_WMYCR_CAR_CRASH_2,
+ SFX_WMYCR_CAR_CRASH_3,
+ SFX_WMYCR_CAR_CRASH_4,
+ SFX_WMYCR_CAR_CRASH_5,
+ SFX_WMYCR_CAR_CRASH_6,
+ SFX_WMYCR_CAR_CRASH_7,
+ SFX_WMYCR_CAR_CRASH_8,
+ SFX_WMYCR_CAR_CRASH_9,
+ SFX_WMYCR_DODGE_1,
+ SFX_WMYCR_DODGE_2,
+ SFX_WMYCR_DODGE_3,
+ SFX_WMYCR_DODGE_4,
+ SFX_WMYCR_DODGE_5,
+ SFX_WMYCR_DODGE_6,
+ SFX_WMYCR_DODGE_7,
+ SFX_WMYCR_DODGE_8,
+ SFX_WMYCR_DODGE_9,
+ SFX_WMYCR_DODGE_10,
+ SFX_WMYCR_FIGHT_1,
+ SFX_WMYCR_FIGHT_2,
+ SFX_WMYCR_FIGHT_3,
+ SFX_WMYCR_FIGHT_4,
+ SFX_WMYCR_FIGHT_5,
+ SFX_WMYCR_FIGHT_6,
+ SFX_WMYCR_FIGHT_7,
+ SFX_WMYCR_GENERIC_CRASH_1,
+ SFX_WMYCR_GENERIC_CRASH_2,
+ SFX_WMYCR_GENERIC_CRASH_3,
+ SFX_WMYCR_GENERIC_CRASH_4,
+ SFX_WMYCR_GENERIC_CRASH_5,
+ SFX_WMYCR_GENERIC_CRASH_6,
+ SFX_WMYCR_GENERIC_CRASH_7,
+ SFX_WMYCR_GENERIC_CRASH_8,
+ SFX_WMYCR_GENERIC_CRASH_9,
+ SFX_WMYCR_GUN_COOL_1,
+ SFX_WMYCR_GUN_COOL_2,
+ SFX_WMYCR_GUN_COOL_3,
+ SFX_WMYCR_GUN_COOL_4,
+ SFX_WMYCR_GUN_COOL_5,
+ SFX_WMYCR_JACKING_1,
+ SFX_WMYCR_JACKING_2,
+ SFX_WMYCR_JACKING_3,
+ SFX_WMYCR_JACKING_4,
+ SFX_WMYCR_JACKING_5,
+ SFX_WMYCR_JACKING_6,
+ SFX_WMYCR_MUGGED_1,
+ SFX_WMYCR_MUGGED_2,
+ SFX_WMYCR_MUGGED_3,
+ SFX_WMYCR_MUGGING_1,
+ SFX_WMYCR_MUGGING_2,
+ SFX_WMYCR_MUGGING_3,
+ SFX_WMYCR_MUGGING_4,
+ SFX_WMYCR_MUGGING_5,
+ SFX_WMYCR_TAXI_1,
+
+ SFX_WMYJG_BLOCKED_1,
+ SFX_WMYJG_BLOCKED_2,
+ SFX_WMYJG_BLOCKED_3,
+ SFX_WMYJG_BLOCKED_4,
+ SFX_WMYJG_BLOCKED_5,
+ SFX_WMYJG_BLOCKED_6,
+ SFX_WMYJG_BLOCKED_7,
+ SFX_WMYJG_BLOCKED_8,
+ SFX_WMYJG_BLOCKED_9,
+ SFX_WMYJG_BLOCKED_10,
+ SFX_WMYJG_BUMP_1,
+ SFX_WMYJG_BUMP_2,
+ SFX_WMYJG_BUMP_3,
+ SFX_WMYJG_BUMP_4,
+ SFX_WMYJG_BUMP_5,
+ SFX_WMYJG_BUMP_6,
+ SFX_WMYJG_BUMP_7,
+ SFX_WMYJG_BUMP_8,
+ SFX_WMYJG_BUMP_9,
+ SFX_WMYJG_BUMP_10,
+ SFX_WMYJG_EYEING_1,
+ SFX_WMYJG_EYEING_2,
+ SFX_WMYJG_GUN_PANIC_1,
+ SFX_WMYJG_GUN_PANIC_2,
+ SFX_WMYJG_GUN_PANIC_3,
+ SFX_WMYJG_GUN_PANIC_4,
+ SFX_WMYJG_MUGGED_1,
+ SFX_WMYJG_MUGGED_2,
+ SFX_WMYJG_RUN_1,
+ SFX_WMYJG_RUN_2,
+ SFX_WMYJG_RUN_3,
+ SFX_WMYJG_RUN_4,
+ SFX_WMYJG_RUN_5,
+ SFX_WMYJG_SAVED_1,
+ SFX_WMYJG_TAXI_1,
+
+ SFX_WMOST_BLOCKED_1,
+ SFX_WMOST_BLOCKED_2,
+ SFX_WMOST_BLOCKED_3,
+ SFX_WMOST_BLOCKED_4,
+ SFX_WMOST_BLOCKED_5,
+ SFX_WMOST_BLOCKED_6,
+ SFX_WMOST_BLOCKED_7,
+ SFX_WMOST_BLOCKED_8,
+ SFX_WMOST_BUMP_1,
+ SFX_WMOST_BUMP_2,
+ SFX_WMOST_BUMP_3,
+ SFX_WMOST_BUMP_4,
+ SFX_WMOST_BUMP_5,
+ SFX_WMOST_BUMP_6,
+ SFX_WMOST_BUMP_7,
+ SFX_WMOST_BUMP_8,
+ SFX_WMOST_BUMP_9,
+ SFX_WMOST_BUMP_10,
+ SFX_WMOST_CAR_CRASH_1,
+ SFX_WMOST_CAR_CRASH_2,
+ SFX_WMOST_CAR_CRASH_3,
+ SFX_WMOST_CAR_CRASH_4,
+ SFX_WMOST_CAR_CRASH_5,
+ SFX_WMOST_CAR_CRASH_6,
+ SFX_WMOST_CAR_CRASH_7,
+ SFX_WMOST_CHAT_1,
+ SFX_WMOST_CHAT_2,
+ SFX_WMOST_CHAT_3,
+ SFX_WMOST_CHAT_4,
+ SFX_WMOST_CHAT_5,
+ SFX_WMOST_CHAT_6,
+ SFX_WMOST_CHAT_7,
+ SFX_WMOST_CHAT_8,
+ SFX_WMOST_CHAT_9,
+ SFX_WMOST_DODGE_1,
+ SFX_WMOST_DODGE_2,
+ SFX_WMOST_DODGE_3,
+ SFX_WMOST_DODGE_4,
+ SFX_WMOST_DODGE_5,
+ SFX_WMOST_DODGE_6,
+ SFX_WMOST_DODGE_7,
+ SFX_WMOST_DODGE_8,
+ SFX_WMOST_EYEING_1,
+ SFX_WMOST_EYEING_2,
+ SFX_WMOST_FIGHT_1,
+ SFX_WMOST_FIGHT_2,
+ SFX_WMOST_FIGHT_3,
+ SFX_WMOST_FIGHT_4,
+ SFX_WMOST_FIGHT_5,
+ SFX_WMOST_FIGHT_6,
+ SFX_WMOST_FIGHT_7,
+ SFX_WMOST_FIGHT_8,
+ SFX_WMOST_GENERIC_CRASH_1,
+ SFX_WMOST_GENERIC_CRASH_2,
+ SFX_WMOST_GENERIC_CRASH_3,
+ SFX_WMOST_GENERIC_CRASH_4,
+ SFX_WMOST_GENERIC_CRASH_5,
+ SFX_WMOST_GENERIC_CRASH_6,
+ SFX_WMOST_GENERIC_CRASH_7,
+ SFX_WMOST_GUN_COOL_1,
+ SFX_WMOST_GUN_COOL_2,
+ SFX_WMOST_GUN_COOL_3,
+ SFX_WMOST_GUN_COOL_4,
+ SFX_WMOST_GUN_COOL_5,
+ SFX_WMOST_INNOCENT_1,
+ SFX_WMOST_INNOCENT_2,
+ SFX_WMOST_INNOCENT_3,
+ SFX_WMOST_JACKED_1,
+ SFX_WMOST_JACKED_2,
+ SFX_WMOST_JACKED_3,
+ SFX_WMOST_JACKED_4,
+ SFX_WMOST_JEER_1,
+ SFX_WMOST_JEER_2,
+ SFX_WMOST_JEER_3,
+ SFX_WMOST_JEER_4,
+ SFX_WMOST_LOST_1,
+ SFX_WMOST_LOST_2,
+ SFX_WMOST_MUGGED_1,
+ SFX_WMOST_MUGGED_2,
+ SFX_WMOST_SAVED_1,
+ SFX_WMOST_TAXI_1,
+
+ SFX_BFOTR_BUMP_1,
+ SFX_BFOTR_BUMP_2,
+ SFX_BFOTR_BUMP_3,
+ SFX_BFOTR_BUMP_4,
+ SFX_BFOTR_BUMP_5,
+ SFX_BFOTR_BUMP_6,
+ SFX_BFOTR_BUMP_7,
+ SFX_BFOTR_BUMP_8,
+ SFX_BFOTR_BUMP_9,
+ SFX_BFOTR_BUMP_10,
+ SFX_BFOTR_CHAT_1,
+ SFX_BFOTR_CHAT_2,
+ SFX_BFOTR_CHAT_3,
+ SFX_BFOTR_CHAT_4,
+ SFX_BFOTR_CHAT_5,
+ SFX_BFOTR_CHAT_6,
+ SFX_BFOTR_CHAT_7,
+ SFX_BFOTR_CHAT_8,
+ SFX_BFOTR_CHAT_9,
+ SFX_BFOTR_CHAT_10,
+ SFX_BFOTR_CHAT_11,
+ SFX_BFOTR_CHAT_12,
+ SFX_BFOTR_CHAT_13,
+ SFX_BFOTR_CHAT_14,
+ SFX_BFOTR_CHAT_15,
+ SFX_BFOTR_DODGE_1,
+ SFX_BFOTR_DODGE_2,
+ SFX_BFOTR_DODGE_3,
+ SFX_BFOTR_DODGE_4,
+ SFX_BFOTR_DODGE_5,
+ SFX_BFOTR_DODGE_6,
+ SFX_BFOTR_DODGE_7,
+ SFX_BFOTR_DODGE_8,
+ SFX_BFOTR_DODGE_9,
+ SFX_BFOTR_FIGHT_1,
+ SFX_BFOTR_FIGHT_2,
+ SFX_BFOTR_FIGHT_3,
+ SFX_BFOTR_FIGHT_4,
+ SFX_BFOTR_FIGHT_5,
+ SFX_BFOTR_FIGHT_6,
+ SFX_BFOTR_GUN_COOL_1,
+ SFX_BFOTR_GUN_COOL_2,
+ SFX_BFOTR_GUN_COOL_3,
+ SFX_BFOTR_GUN_COOL_4,
+ SFX_BFOTR_GUN_COOL_5,
+ SFX_BFOTR_GUN_COOL_6,
+ SFX_BFOTR_MUGGED_1,
+ SFX_BFOTR_MUGGED_2,
+ SFX_BFOTR_MUGGING_1,
+ SFX_BFOTR_MUGGING_2,
+ SFX_BFOTR_MUGGING_3,
+ SFX_BFOTR_SAVED_1,
+ SFX_BFOTR_SHOCKED_1,
+ SFX_BFOTR_SHOCKED_2,
+ SFX_BFOTR_SHOCKED_3,
+ SFX_BFOTR_SOLICIT_1,
+ SFX_BFOTR_SOLICIT_2,
+ SFX_BFOTR_SOLICIT_3,
+ SFX_BFOTR_SOLICIT_4,
+ SFX_BFOTR_SOLICIT_5,
+ SFX_BFOTR_TAXI_1,
+
+ SFX_WFYRI_BLOCKED_1,
+ SFX_WFYRI_BLOCKED_2,
+ SFX_WFYRI_BLOCKED_3,
+ SFX_WFYRI_BLOCKED_4,
+ SFX_WFYRI_BLOCKED_5,
+ SFX_WFYRI_BLOCKED_6,
+ SFX_WFYRI_BLOCKED_7,
+ SFX_WFYRI_BLOCKED_8,
+ SFX_WFYRI_BUMP_1,
+ SFX_WFYRI_BUMP_2,
+ SFX_WFYRI_BUMP_3,
+ SFX_WFYRI_BUMP_4,
+ SFX_WFYRI_BUMP_5,
+ SFX_WFYRI_BUMP_6,
+ SFX_WFYRI_BUMP_7,
+ SFX_WFYRI_BUMP_8,
+ SFX_WFYRI_BUMP_9,
+ SFX_WFYRI_BUMP_10,
+ SFX_WFYRI_CAR_CRASH_1,
+ SFX_WFYRI_CAR_CRASH_2,
+ SFX_WFYRI_CAR_CRASH_3,
+ SFX_WFYRI_CAR_CRASH_4,
+ SFX_WFYRI_CAR_CRASH_5,
+ SFX_WFYRI_CAR_CRASH_6,
+ SFX_WFYRI_CAR_CRASH_7,
+ SFX_WFYRI_CAR_CRASH_8,
+ SFX_WFYRI_CAR_CRASH_9,
+ SFX_WFYRI_DODGE_1,
+ SFX_WFYRI_DODGE_2,
+ SFX_WFYRI_DODGE_3,
+ SFX_WFYRI_DODGE_4,
+ SFX_WFYRI_DODGE_5,
+ SFX_WFYRI_DODGE_6,
+ SFX_WFYRI_DODGE_7,
+ SFX_WFYRI_DODGE_8,
+ SFX_WFYRI_DODGE_9,
+ SFX_WFYRI_EYEING_1,
+ SFX_WFYRI_EYEING_2,
+ SFX_WFYRI_GENERIC_CRASH_1,
+ SFX_WFYRI_GENERIC_CRASH_2,
+ SFX_WFYRI_GENERIC_CRASH_3,
+ SFX_WFYRI_GENERIC_CRASH_4,
+ SFX_WFYRI_GENERIC_CRASH_5,
+ SFX_WFYRI_GENERIC_CRASH_6,
+ SFX_WFYRI_GENERIC_CRASH_7,
+ SFX_WFYRI_GENERIC_CRASH_8,
+ SFX_WFYRI_GUN_PANIC_1,
+ SFX_WFYRI_GUN_PANIC_2,
+ SFX_WFYRI_GUN_PANIC_3,
+ SFX_WFYRI_GUN_PANIC_4,
+ SFX_WFYRI_GUN_PANIC_5,
+ SFX_WFYRI_JACKED_1,
+ SFX_WFYRI_JACKED_2,
+ SFX_WFYRI_JACKED_3,
+ SFX_WFYRI_JACKED_4,
+ SFX_WFYRI_JACKED_5,
+ SFX_WFYRI_JACKED_6,
+ SFX_WFYRI_JACKED_7,
+ SFX_WFYRI_LOST_1,
+ SFX_WFYRI_LOST_2,
+ SFX_WFYRI_MUGGED_1,
+ SFX_WFYRI_MUGGED_2,
+ SFX_WFYRI_RUN_1,
+ SFX_WFYRI_RUN_2,
+ SFX_WFYRI_RUN_3,
+ SFX_WFYRI_RUN_4,
+ SFX_WFYRI_RUN_5,
+ SFX_WFYRI_SAVED_1,
+ SFX_WFYRI_SHOCKED_1,
+ SFX_WFYRI_SHOCKED_2,
+ SFX_WFYRI_TAXI_1,
+ SFX_BFYPR_BUMP_1,
+ SFX_BFYPR_BUMP_2,
+ SFX_BFYPR_BUMP_3,
+ SFX_BFYPR_BUMP_4,
+ SFX_BFYPR_BUMP_5,
+ SFX_BFYPR_BUMP_6,
+ SFX_BFYPR_BUMP_7,
+ SFX_BFYPR_BUMP_8,
+ SFX_BFYPR_BUMP_9,
+ SFX_BFYPR_BUMP_10,
+ SFX_BFYPR_BUMP_11,
+ SFX_BFYPR_CHAT_1,
+ SFX_BFYPR_CHAT_2,
+ SFX_BFYPR_CHAT_3,
+ SFX_BFYPR_CHAT_4,
+ SFX_BFYPR_CHAT_5,
+ SFX_BFYPR_CHAT_6,
+ SFX_BFYPR_CHAT_7,
+ SFX_BFYPR_CHAT_8,
+ SFX_BFYPR_CHAT_9,
+ SFX_BFYPR_CHAT_10,
+ SFX_BFYPR_CHAT_11,
+ SFX_BFYPR_CHAT_12,
+ SFX_BFYPR_CHAT_13,
+ SFX_BFYPR_DODGE_1,
+ SFX_BFYPR_DODGE_2,
+ SFX_BFYPR_DODGE_3,
+ SFX_BFYPR_DODGE_4,
+ SFX_BFYPR_DODGE_5,
+ SFX_BFYPR_DODGE_6,
+ SFX_BFYPR_DODGE_7,
+ SFX_BFYPR_FIGHT_1,
+ SFX_BFYPR_FIGHT_2,
+ SFX_BFYPR_FIGHT_3,
+ SFX_BFYPR_FIGHT_4,
+ SFX_BFYPR_FIGHT_5,
+ SFX_BFYPR_FIGHT_6,
+ SFX_BFYPR_FIGHT_7,
+ SFX_BFYPR_FUCKING_1,
+ SFX_BFYPR_FUCKING_2,
+ SFX_BFYPR_FUCKING_3,
+ SFX_BFYPR_FUCKING_4,
+ SFX_BFYPR_FUCKING_5,
+ SFX_BFYPR_FUCKING_6,
+ SFX_BFYPR_FUCKING_7,
+ SFX_BFYPR_GUN_COOL_1,
+ SFX_BFYPR_GUN_COOL_2,
+ SFX_BFYPR_GUN_COOL_3,
+ SFX_BFYPR_GUN_COOL_4,
+ SFX_BFYPR_GUN_COOL_5,
+ SFX_BFYPR_MUGGED_1,
+ SFX_BFYPR_MUGGED_2,
+ SFX_BFYPR_SAVED_1,
+ SFX_BFYPR_SHOCKED_1,
+ SFX_BFYPR_SHOCKED_2,
+ SFX_BFYPR_SOLICIT_1,
+ SFX_BFYPR_SOLICIT_2,
+ SFX_BFYPR_SOLICIT_3,
+ SFX_BFYPR_SOLICIT_4,
+ SFX_BFYPR_SOLICIT_5,
+ SFX_BFYPR_SOLICIT_6,
+ SFX_BFYPR_SOLICIT_7,
+ SFX_BFYPR_SOLICIT_8,
+ SFX_BFYPR_SOLICIT_9,
+ SFX_BFYPR_SOLICIT_10,
+ SFX_BFYPR_SOLICIT_11,
+ SFX_BFYPR_SOLICIT_12,
+ SFX_BFYPR_SOLICIT_13,
+ SFX_BFYPR_TAXI_1,
+ SFX_BFYPR_TAXI_2,
+
+ SFX_BMYRI_BLOCKED_1,
+ SFX_BMYRI_BLOCKED_2,
+ SFX_BMYRI_BLOCKED_3,
+ SFX_BMYRI_BLOCKED_4,
+ SFX_BMYRI_BLOCKED_5,
+ SFX_BMYRI_BLOCKED_6,
+ SFX_BMYRI_BUMP_1,
+ SFX_BMYRI_BUMP_2,
+ SFX_BMYRI_BUMP_3,
+ SFX_BMYRI_BUMP_4,
+ SFX_BMYRI_BUMP_5,
+ SFX_BMYRI_BUMP_6,
+ SFX_BMYRI_BUMP_7,
+ SFX_BMYRI_CAR_CRASH_1,
+ SFX_BMYRI_CAR_CRASH_2,
+ SFX_BMYRI_CAR_CRASH_3,
+ SFX_BMYRI_CAR_CRASH_4,
+ SFX_BMYRI_CAR_CRASH_5,
+ SFX_BMYRI_CAR_CRASH_6,
+ SFX_BMYRI_CAR_CRASH_7,
+ SFX_BMYRI_DODGE_1,
+ SFX_BMYRI_DODGE_2,
+ SFX_BMYRI_DODGE_3,
+ SFX_BMYRI_DODGE_4,
+ SFX_BMYRI_DODGE_5,
+ SFX_BMYRI_DODGE_6,
+ SFX_BMYRI_DODGE_7,
+ SFX_BMYRI_DODGE_8,
+ SFX_BMYRI_EYEING_1,
+ SFX_BMYRI_GENERIC_CRASH_1,
+ SFX_BMYRI_GENERIC_CRASH_2,
+ SFX_BMYRI_GENERIC_CRASH_3,
+ SFX_BMYRI_GENERIC_CRASH_4,
+ SFX_BMYRI_GENERIC_CRASH_5,
+ SFX_BMYRI_GENERIC_CRASH_6,
+ SFX_BMYRI_GENERIC_CRASH_7,
+ SFX_BMYRI_GUN_PANIC_1,
+ SFX_BMYRI_GUN_PANIC_2,
+ SFX_BMYRI_GUN_PANIC_3,
+ SFX_BMYRI_GUN_PANIC_4,
+ SFX_BMYRI_GUN_PANIC_5,
+ SFX_BMYRI_GUN_PANIC_6,
+ SFX_BMYRI_GUN_PANIC_7,
+ SFX_BMYRI_JACKED_1,
+ SFX_BMYRI_JACKED_2,
+ SFX_BMYRI_JACKED_3,
+ SFX_BMYRI_JACKED_4,
+ SFX_BMYRI_LOST_1,
+ SFX_BMYRI_LOST_2,
+ SFX_BMYRI_MUGGED_1,
+ SFX_BMYRI_MUGGED_2,
+ SFX_BMYRI_RUN_1,
+ SFX_BMYRI_RUN_2,
+ SFX_BMYRI_RUN_3,
+ SFX_BMYRI_RUN_4,
+ SFX_BMYRI_SAVED_1,
+ SFX_BMYRI_SHOCKED_1,
+ SFX_BMYRI_SHOCKED_2,
+ SFX_BMYRI_SHOCKED_3,
+ SFX_BMYRI_TAXI_1,
+ SFX_BMYBU_BLOCKED_1,
+ SFX_BMYBU_BLOCKED_2,
+ SFX_BMYBU_BLOCKED_3,
+ SFX_BMYBU_BLOCKED_4,
+ SFX_BMYBU_BLOCKED_5,
+ SFX_BMYBU_BLOCKED_6,
+ SFX_BMYBU_BLOCKED_7,
+ SFX_BMYBU_BLOCKED_8,
+ SFX_BMYBU_BUMP_1,
+ SFX_BMYBU_BUMP_2,
+ SFX_BMYBU_BUMP_3,
+ SFX_BMYBU_BUMP_4,
+ SFX_BMYBU_BUMP_5,
+ SFX_BMYBU_BUMP_6,
+ SFX_BMYBU_BUMP_7,
+ SFX_BMYBU_CAR_CRASH_1,
+ SFX_BMYBU_CAR_CRASH_2,
+ SFX_BMYBU_CAR_CRASH_3,
+ SFX_BMYBU_CAR_CRASH_4,
+ SFX_BMYBU_CAR_CRASH_5,
+ SFX_BMYBU_CAR_CRASH_6,
+ SFX_BMYBU_CAR_CRASH_7,
+ SFX_BMYBU_DODGE_1,
+ SFX_BMYBU_DODGE_2,
+ SFX_BMYBU_DODGE_3,
+ SFX_BMYBU_DODGE_4,
+ SFX_BMYBU_DODGE_5,
+ SFX_BMYBU_DODGE_6,
+ SFX_BMYBU_DODGE_7,
+ SFX_BMYBU_DODGE_8,
+ SFX_BMYBU_DODGE_9,
+ SFX_BMYBU_DODGE_10,
+ SFX_BMYBU_EYEING_1,
+ SFX_BMYBU_EYEING_2,
+ SFX_BMYBU_FIGHT_1,
+ SFX_BMYBU_FIGHT_2,
+ SFX_BMYBU_FIGHT_3,
+ SFX_BMYBU_FIGHT_4,
+ SFX_BMYBU_FIGHT_5,
+ SFX_BMYBU_GENERIC_CRASH_1,
+ SFX_BMYBU_GENERIC_CRASH_2,
+ SFX_BMYBU_GENERIC_CRASH_3,
+ SFX_BMYBU_GENERIC_CRASH_4,
+ SFX_BMYBU_GENERIC_CRASH_5,
+ SFX_BMYBU_GENERIC_CRASH_6,
+ SFX_BMYBU_GENERIC_CRASH_7,
+ SFX_BMYBU_GUN_PANIC_1,
+ SFX_BMYBU_GUN_PANIC_2,
+ SFX_BMYBU_GUN_PANIC_3,
+ SFX_BMYBU_GUN_PANIC_4,
+ SFX_BMYBU_GUN_PANIC_5,
+ SFX_BMYBU_INNOCENT_1,
+ SFX_BMYBU_INNOCENT_2,
+ SFX_BMYBU_JACKED_1,
+ SFX_BMYBU_JACKED_2,
+ SFX_BMYBU_JACKED_3,
+ SFX_BMYBU_JACKED_4,
+ SFX_BMYBU_JACKED_5,
+ SFX_BMYBU_JACKED_6,
+ SFX_BMYBU_MUGGED_1,
+ SFX_BMYBU_MUGGED_2,
+ SFX_BMYBU_SAVED_1,
+ SFX_BMYBU_SHOCKED_1,
+ SFX_BMYBU_SHOCKED_2,
+ SFX_BMYBU_TAXI_1,
+
+ SFX_WMYSK_BUMP_1,
+ SFX_WMYSK_BUMP_2,
+ SFX_WMYSK_BUMP_3,
+ SFX_WMYSK_BUMP_4,
+ SFX_WMYSK_BUMP_5,
+ SFX_WMYSK_BUMP_6,
+ SFX_WMYSK_BUMP_7,
+ SFX_WMYSK_BUMP_8,
+ SFX_WMYSK_BUMP_9,
+ SFX_WMYSK_BUMP_10,
+ SFX_WMYSK_BUMP_11,
+ SFX_WMYSK_BUMP_12,
+ SFX_WMYSK_BUMP_13,
+ SFX_WMYSK_BUMP_14,
+ SFX_WMYSK_CHAT_1,
+ SFX_WMYSK_CHAT_2,
+ SFX_WMYSK_CHAT_3,
+ SFX_WMYSK_CHAT_4,
+ SFX_WMYSK_CHAT_5,
+ SFX_WMYSK_CHAT_6,
+ SFX_WMYSK_CHAT_7,
+ SFX_WMYSK_CHAT_8,
+ SFX_WMYSK_CHAT_9,
+ SFX_WMYSK_CHAT_10,
+ SFX_WMYSK_CHAT_11,
+ SFX_WMYSK_CHAT_12,
+ SFX_WMYSK_CHAT_13,
+ SFX_WMYSK_DODGE_1,
+ SFX_WMYSK_DODGE_2,
+ SFX_WMYSK_DODGE_3,
+ SFX_WMYSK_DODGE_4,
+ SFX_WMYSK_DODGE_5,
+ SFX_WMYSK_DODGE_6,
+ SFX_WMYSK_DODGE_7,
+ SFX_WMYSK_DODGE_8,
+ SFX_WMYSK_DODGE_9,
+ SFX_WMYSK_DODGE_10,
+ SFX_WMYSK_EYEING_1,
+ SFX_WMYSK_EYEING_2,
+ SFX_WMYSK_FIGHT_1,
+ SFX_WMYSK_FIGHT_2,
+ SFX_WMYSK_FIGHT_3,
+ SFX_WMYSK_FIGHT_4,
+ SFX_WMYSK_FIGHT_5,
+ SFX_WMYSK_GUN_PANIC_1,
+ SFX_WMYSK_GUN_PANIC_2,
+ SFX_WMYSK_GUN_PANIC_3,
+ SFX_WMYSK_GUN_PANIC_4,
+ SFX_WMYSK_GUN_PANIC_5,
+ SFX_WMYSK_INNOCENT_1,
+ SFX_WMYSK_INNOCENT_2,
+ SFX_WMYSK_INNOCENT_3,
+ SFX_WMYSK_LOST_1,
+ SFX_WMYSK_LOST_2,
+ SFX_WMYSK_MUGGED_1,
+ SFX_WMYSK_MUGGED_2,
+ SFX_WMYSK_SAVED_1,
+ SFX_WMYSK_SAVED_2,
+ SFX_WMYSK_SHOCKED_1,
+ SFX_WMYSK_SHOCKED_2,
+ SFX_WMYSK_TAXI_1,
+
+ SFX_WMYCW_BLOCKED_1,
+ SFX_WMYCW_BLOCKED_2,
+ SFX_WMYCW_BLOCKED_3,
+ SFX_WMYCW_BLOCKED_4,
+ SFX_WMYCW_BLOCKED_5,
+ SFX_WMYCW_BLOCKED_6,
+ SFX_WMYCW_BLOCKED_7,
+ SFX_WMYCW_BLOCKED_8,
+ SFX_WMYCW_BLOCKED_9,
+ SFX_WMYCW_BUMP_1,
+ SFX_WMYCW_BUMP_2,
+ SFX_WMYCW_BUMP_3,
+ SFX_WMYCW_BUMP_4,
+ SFX_WMYCW_BUMP_5,
+ SFX_WMYCW_BUMP_6,
+ SFX_WMYCW_BUMP_7,
+ SFX_WMYCW_BUMP_8,
+ SFX_WMYCW_BUMP_9,
+ SFX_WMYCW_CAR_CRASH_1,
+ SFX_WMYCW_CAR_CRASH_2,
+ SFX_WMYCW_CAR_CRASH_3,
+ SFX_WMYCW_CAR_CRASH_4,
+ SFX_WMYCW_CAR_CRASH_5,
+ SFX_WMYCW_CAR_CRASH_6,
+ SFX_WMYCW_CAR_CRASH_7,
+ SFX_WMYCW_CAR_CRASH_8,
+ SFX_WMYCW_CAR_CRASH_9,
+ SFX_WMYCW_CHAT_1,
+ SFX_WMYCW_CHAT_2,
+ SFX_WMYCW_CHAT_3,
+ SFX_WMYCW_CHAT_4,
+ SFX_WMYCW_CHAT_5,
+ SFX_WMYCW_CHAT_6,
+ SFX_WMYCW_CHAT_7,
+ SFX_WMYCW_CHAT_8,
+ SFX_WMYCW_CHAT_9,
+ SFX_WMYCW_CHAT_10,
+ SFX_WMYCW_CHAT_11,
+ SFX_WMYCW_CHAT_12,
+ SFX_WMYCW_CHAT_13,
+ SFX_WMYCW_CHAT_14,
+ SFX_WMYCW_CHAT_15,
+ SFX_WMYCW_DODGE_1,
+ SFX_WMYCW_DODGE_2,
+ SFX_WMYCW_DODGE_3,
+ SFX_WMYCW_DODGE_4,
+ SFX_WMYCW_DODGE_5,
+ SFX_WMYCW_DODGE_6,
+ SFX_WMYCW_DODGE_7,
+ SFX_WMYCW_DODGE_8,
+ SFX_WMYCW_DODGE_9,
+ SFX_WMYCW_DODGE_10,
+ SFX_WMYCW_EYEING_1,
+ SFX_WMYCW_EYEING_2,
+ SFX_WMYCW_EYEING_3,
+ SFX_WMYCW_FIGHT_1,
+ SFX_WMYCW_FIGHT_2,
+ SFX_WMYCW_FIGHT_3,
+ SFX_WMYCW_FIGHT_4,
+ SFX_WMYCW_FIGHT_5,
+ SFX_WMYCW_FIGHT_6,
+ SFX_WMYCW_FIGHT_7,
+ SFX_WMYCW_FIGHT_8,
+ SFX_WMYCW_GENERIC_CRASH_1,
+ SFX_WMYCW_GENERIC_CRASH_2,
+ SFX_WMYCW_GENERIC_CRASH_3,
+ SFX_WMYCW_GENERIC_CRASH_4,
+ SFX_WMYCW_GENERIC_CRASH_5,
+ SFX_WMYCW_GENERIC_CRASH_6,
+ SFX_WMYCW_GENERIC_CRASH_7,
+ SFX_WMYCW_GUN_PANIC_1,
+ SFX_WMYCW_GUN_PANIC_2,
+ SFX_WMYCW_GUN_PANIC_3,
+ SFX_WMYCW_GUN_PANIC_4,
+ SFX_WMYCW_GUN_PANIC_5,
+ SFX_WMYCW_GUN_PANIC_6,
+ SFX_WMYCW_INNOCENT_1,
+ SFX_WMYCW_INNOCENT_2,
+ SFX_WMYCW_INNOCENT_3,
+ SFX_WMYCW_JACKED_1,
+ SFX_WMYCW_JACKED_2,
+ SFX_WMYCW_JACKED_3,
+ SFX_WMYCW_JACKED_4,
+ SFX_WMYCW_JACKED_5,
+ SFX_WMYCW_JACKED_6,
+ SFX_WMYCW_JEER_1,
+ SFX_WMYCW_JEER_2,
+ SFX_WMYCW_JEER_3,
+ SFX_WMYCW_JEER_4,
+ SFX_WMYCW_JEER_5,
+ SFX_WMYCW_JACKING_1,
+ SFX_WMYCW_JACKING_2,
+ SFX_WMYCW_JACKING_3,
+ SFX_WMYCW_JACKING_4,
+ SFX_WMYCW_LOST_1,
+ SFX_WMYCW_LOST_2,
+ SFX_WMYCW_MUGGED_1,
+ SFX_WMYCW_TAXI_1,
+
+ SFX_HFYST_BLOCKED_1,
+ SFX_HFYST_BLOCKED_2,
+ SFX_HFYST_BLOCKED_3,
+ SFX_HFYST_BLOCKED_4,
+ SFX_HFYST_BLOCKED_5,
+ SFX_HFYST_BLOCKED_6,
+ SFX_HFYST_BLOCKED_7,
+ SFX_HFYST_BUMP_1,
+ SFX_HFYST_BUMP_2,
+ SFX_HFYST_BUMP_3,
+ SFX_HFYST_BUMP_4,
+ SFX_HFYST_BUMP_5,
+ SFX_HFYST_BUMP_6,
+ SFX_HFYST_BUMP_7,
+ SFX_HFYST_BUMP_8,
+ SFX_HFYST_BUMP_9,
+ SFX_HFYST_BUMP_10,
+ SFX_HFYST_CAR_CRASH_1,
+ SFX_HFYST_CAR_CRASH_2,
+ SFX_HFYST_CAR_CRASH_3,
+ SFX_HFYST_CAR_CRASH_4,
+ SFX_HFYST_CAR_CRASH_5,
+ SFX_HFYST_CAR_CRASH_6,
+ SFX_HFYST_CAR_CRASH_7,
+ SFX_HFYST_CAR_CRASH_8,
+ SFX_HFYST_CHAT_1,
+ SFX_HFYST_CHAT_2,
+ SFX_HFYST_CHAT_3,
+ SFX_HFYST_CHAT_4,
+ SFX_HFYST_CHAT_5,
+ SFX_HFYST_CHAT_6,
+ SFX_HFYST_CHAT_7,
+ SFX_HFYST_CHAT_8,
+ SFX_HFYST_CHAT_9,
+ SFX_HFYST_DODGE_1,
+ SFX_HFYST_DODGE_2,
+ SFX_HFYST_DODGE_3,
+ SFX_HFYST_DODGE_4,
+ SFX_HFYST_DODGE_5,
+ SFX_HFYST_DODGE_6,
+ SFX_HFYST_DODGE_7,
+ SFX_HFYST_DODGE_8,
+ SFX_HFYST_DODGE_9,
+ SFX_HFYST_DODGE_10,
+ SFX_HFYST_FIGHT_1,
+ SFX_HFYST_FIGHT_2,
+ SFX_HFYST_FIGHT_3,
+ SFX_HFYST_FIGHT_4,
+ SFX_HFYST_FIGHT_5,
+ SFX_HFYST_FIGHT_6,
+ SFX_HFYST_FIGHT_7,
+ SFX_HFYST_GENERIC_CRASH_1,
+ SFX_HFYST_GENERIC_CRASH_2,
+ SFX_HFYST_GENERIC_CRASH_3,
+ SFX_HFYST_GENERIC_CRASH_4,
+ SFX_HFYST_GENERIC_CRASH_5,
+ SFX_HFYST_GENERIC_CRASH_6,
+ SFX_HFYST_GENERIC_CRASH_7,
+ SFX_HFYST_GUN_COOL_1,
+ SFX_HFYST_GUN_COOL_2,
+ SFX_HFYST_GUN_COOL_3,
+ SFX_HFYST_GUN_COOL_4,
+ SFX_HFYST_GUN_COOL_5,
+ SFX_HFYST_JACKED_1,
+ SFX_HFYST_JACKED_2,
+ SFX_HFYST_JACKED_3,
+ SFX_HFYST_JACKED_4,
+ SFX_HFYST_JACKED_5,
+ SFX_HFYST_JACKED_6,
+ SFX_HFYST_JACKING_1,
+ SFX_HFYST_JACKING_2,
+ SFX_HFYST_JACKING_3,
+ SFX_HFYST_JACKING_4,
+ SFX_HFYST_LOST_1,
+ SFX_HFYST_LOST_2,
+ SFX_HFYST_MUGGED_1,
+ SFX_HFYST_MUGGED_2,
+ SFX_HFYST_MUGGING_1,
+ SFX_HFYST_MUGGING_2,
+ SFX_HFYST_MUGGING_3,
+ SFX_HFYST_MUGGING_4,
+ SFX_HFYST_TAXI_1,
+
+ SFX_HMOST_BLOCKED_1,
+ SFX_HMOST_BLOCKED_2,
+ SFX_HMOST_BLOCKED_3,
+ SFX_HMOST_BLOCKED_4,
+ SFX_HMOST_BLOCKED_5,
+ SFX_HMOST_BLOCKED_6,
+ SFX_HMOST_BLOCKED_7,
+ SFX_HMOST_BUMP_1,
+ SFX_HMOST_BUMP_2,
+ SFX_HMOST_BUMP_3,
+ SFX_HMOST_BUMP_4,
+ SFX_HMOST_BUMP_5,
+ SFX_HMOST_BUMP_6,
+ SFX_HMOST_BUMP_7,
+ SFX_HMOST_BUMP_8,
+ SFX_HMOST_BUMP_9,
+ SFX_HMOST_BUMP_10,
+ SFX_HMOST_CAR_CRASH_1,
+ SFX_HMOST_CAR_CRASH_2,
+ SFX_HMOST_CAR_CRASH_3,
+ SFX_HMOST_CAR_CRASH_4,
+ SFX_HMOST_CAR_CRASH_5,
+ SFX_HMOST_CAR_CRASH_6,
+ SFX_HMOST_CAR_CRASH_7,
+ SFX_HMOST_CHAT_1,
+ SFX_HMOST_CHAT_2,
+ SFX_HMOST_CHAT_3,
+ SFX_HMOST_CHAT_4,
+ SFX_HMOST_CHAT_5,
+ SFX_HMOST_CHAT_6,
+ SFX_HMOST_CHAT_7,
+ SFX_HMOST_CHAT_8,
+ SFX_HMOST_CHAT_9,
+ SFX_HMOST_CHAT_10,
+ SFX_HMOST_CHAT_11,
+ SFX_HMOST_DODGE_1,
+ SFX_HMOST_DODGE_2,
+ SFX_HMOST_DODGE_3,
+ SFX_HMOST_DODGE_4,
+ SFX_HMOST_DODGE_5,
+ SFX_HMOST_DODGE_6,
+ SFX_HMOST_DODGE_7,
+ SFX_HMOST_DODGE_8,
+ SFX_HMOST_DODGE_9,
+ SFX_HMOST_EYEING_1,
+ SFX_HMOST_FIGHT_1,
+ SFX_HMOST_FIGHT_2,
+ SFX_HMOST_FIGHT_3,
+ SFX_HMOST_FIGHT_4,
+ SFX_HMOST_FIGHT_5,
+ SFX_HMOST_FIGHT_6,
+ SFX_HMOST_FIGHT_7,
+ SFX_HMOST_FIGHT_8,
+ SFX_HMOST_GENERIC_CRASH_1,
+ SFX_HMOST_GENERIC_CRASH_2,
+ SFX_HMOST_GENERIC_CRASH_3,
+ SFX_HMOST_GENERIC_CRASH_4,
+ SFX_HMOST_GENERIC_CRASH_5,
+ SFX_HMOST_GENERIC_CRASH_6,
+ SFX_HMOST_GENERIC_CRASH_7,
+ SFX_HMOST_GUN_COOL_1,
+ SFX_HMOST_GUN_COOL_2,
+ SFX_HMOST_GUN_COOL_3,
+ SFX_HMOST_GUN_COOL_4,
+ SFX_HMOST_GUN_COOL_5,
+ SFX_HMOST_JACKED_1,
+ SFX_HMOST_JACKED_2,
+ SFX_HMOST_JACKED_3,
+ SFX_HMOST_JACKED_4,
+ SFX_HMOST_JACKED_5,
+ SFX_HMOST_JACKED_6,
+ SFX_HMOST_JACKING_1,
+ SFX_HMOST_JACKING_2,
+ SFX_HMOST_JACKING_3,
+ SFX_HMOST_LOST_1,
+ SFX_HMOST_LOST_2,
+ SFX_HMOST_MUGGED_1,
+ SFX_HMOST_MUGGED_2,
+ SFX_HMOST_TAXI_1,
+
+ SFX_HMYRI_BLOCKED_1,
+ SFX_HMYRI_BLOCKED_2,
+ SFX_HMYRI_BLOCKED_3,
+ SFX_HMYRI_BLOCKED_4,
+ SFX_HMYRI_BLOCKED_5,
+ SFX_HMYRI_BLOCKED_6,
+ SFX_HMYRI_BLOCKED_7,
+ SFX_HMYRI_BUMP_1,
+ SFX_HMYRI_BUMP_2,
+ SFX_HMYRI_BUMP_3,
+ SFX_HMYRI_BUMP_4,
+ SFX_HMYRI_BUMP_5,
+ SFX_HMYRI_BUMP_6,
+ SFX_HMYRI_BUMP_7,
+ SFX_HMYRI_BUMP_8,
+ SFX_HMYRI_BUMP_9,
+ SFX_HMYRI_BUMP_10,
+ SFX_HMYRI_CAR_CRASH_1,
+ SFX_HMYRI_CAR_CRASH_2,
+ SFX_HMYRI_CAR_CRASH_3,
+ SFX_HMYRI_CAR_CRASH_4,
+ SFX_HMYRI_CAR_CRASH_5,
+ SFX_HMYRI_CAR_CRASH_6,
+ SFX_HMYRI_CAR_CRASH_7,
+ SFX_HMYRI_CAR_CRASH_8,
+ SFX_HMYRI_DODGE_1,
+ SFX_HMYRI_DODGE_2,
+ SFX_HMYRI_DODGE_3,
+ SFX_HMYRI_DODGE_4,
+ SFX_HMYRI_DODGE_5,
+ SFX_HMYRI_DODGE_6,
+ SFX_HMYRI_DODGE_7,
+ SFX_HMYRI_DODGE_8,
+ SFX_HMYRI_DODGE_9,
+ SFX_HMYRI_FIGHT_1,
+ SFX_HMYRI_FIGHT_2,
+ SFX_HMYRI_FIGHT_3,
+ SFX_HMYRI_FIGHT_4,
+ SFX_HMYRI_FIGHT_5,
+ SFX_HMYRI_GENERIC_CRASH_1,
+ SFX_HMYRI_GENERIC_CRASH_2,
+ SFX_HMYRI_GENERIC_CRASH_3,
+ SFX_HMYRI_GENERIC_CRASH_4,
+ SFX_HMYRI_GENERIC_CRASH_5,
+ SFX_HMYRI_GENERIC_CRASH_6,
+ SFX_HMYRI_GENERIC_CRASH_7,
+ SFX_HMYRI_GENERIC_CRASH_8,
+ SFX_HMYRI_GENERIC_CRASH_9,
+ SFX_HMYRI_GENERIC_CRASH_10,
+ SFX_HMYRI_GENERIC_CRASH_11,
+ SFX_HMYRI_GENERIC_CRASH_12,
+ SFX_HMYRI_GUN_PANIC_1,
+ SFX_HMYRI_GUN_PANIC_2,
+ SFX_HMYRI_GUN_PANIC_3,
+ SFX_HMYRI_GUN_PANIC_4,
+ SFX_HMYRI_GUN_PANIC_5,
+ SFX_HMYRI_GUN_PANIC_6,
+ SFX_HMYRI_GUN_PANIC_7,
+ SFX_HMYRI_JACKED_1,
+ SFX_HMYRI_JACKED_2,
+ SFX_HMYRI_JACKED_3,
+ SFX_HMYRI_JACKED_4,
+ SFX_HMYRI_JACKED_5,
+ SFX_HMYRI_JACKED_6,
+ SFX_HMYRI_JACKED_7,
+ SFX_HMYRI_JACKED_8,
+ SFX_HMYRI_JACKING_1,
+ SFX_HMYRI_JACKING_2,
+ SFX_HMYRI_JACKING_3,
+ SFX_HMYRI_MUGGED_1,
+ SFX_HMYRI_SHOCKED_1,
+ SFX_HMYRI_SHOCKED_2,
+ SFX_HMYRI_SHOCKED_3,
+
+ SFX_HFYPR_BUMP_1,
+ SFX_HFYPR_BUMP_2,
+ SFX_HFYPR_BUMP_3,
+ SFX_HFYPR_BUMP_4,
+ SFX_HFYPR_BUMP_5,
+ SFX_HFYPR_BUMP_6,
+ SFX_HFYPR_BUMP_7,
+ SFX_HFYPR_BUMP_8,
+ SFX_HFYPR_BUMP_9,
+ SFX_HFYPR_BUMP_10,
+ SFX_HFYPR_CHAT_1,
+ SFX_HFYPR_CHAT_2,
+ SFX_HFYPR_CHAT_3,
+ SFX_HFYPR_CHAT_4,
+ SFX_HFYPR_CHAT_5,
+ SFX_HFYPR_CHAT_6,
+ SFX_HFYPR_CHAT_7,
+ SFX_HFYPR_CHAT_8,
+ SFX_HFYPR_CHAT_9,
+ SFX_HFYPR_CHAT_10,
+ SFX_HFYPR_CHAT_11,
+ SFX_HFYPR_CHAT_12,
+ SFX_HFYPR_DODGE_1,
+ SFX_HFYPR_DODGE_2,
+ SFX_HFYPR_DODGE_3,
+ SFX_HFYPR_DODGE_4,
+ SFX_HFYPR_DODGE_5,
+ SFX_HFYPR_DODGE_6,
+ SFX_HFYPR_DODGE_7,
+ SFX_HFYPR_DODGE_8,
+ SFX_HFYPR_DODGE_9,
+ SFX_HFYPR_EYEING_1,
+ SFX_HFYPR_EYEING_2,
+ SFX_HFYPR_EYEING_3,
+ SFX_HFYPR_FIGHT_1,
+ SFX_HFYPR_FIGHT_2,
+ SFX_HFYPR_FIGHT_3,
+ SFX_HFYPR_FIGHT_4,
+ SFX_HFYPR_FIGHT_5,
+ SFX_HFYPR_FIGHT_6,
+ SFX_HFYPR_FIGHT_7,
+ SFX_HFYPR_FIGHT_8,
+ SFX_HFYPR_FIGHT_9,
+ SFX_HFYPR_FIGHT_10,
+ SFX_HFYPR_FUCKING_1,
+ SFX_HFYPR_FUCKING_2,
+ SFX_HFYPR_FUCKING_3,
+ SFX_HFYPR_FUCKING_4,
+ SFX_HFYPR_FUCKING_5,
+ SFX_HFYPR_FUCKING_6,
+ SFX_HFYPR_FUCKING_7,
+ SFX_HFYPR_FUCKING_8,
+ SFX_HFYPR_GUN_COOL_1,
+ SFX_HFYPR_GUN_COOL_2,
+ SFX_HFYPR_GUN_COOL_3,
+ SFX_HFYPR_GUN_COOL_4,
+ SFX_HFYPR_GUN_COOL_5,
+ SFX_HFYPR_GUN_COOL_6,
+ SFX_HFYPR_MUGGED_1,
+ SFX_HFYPR_MUGGED_2,
+ SFX_HFYPR_SAVED_1,
+ SFX_HFYPR_SOLICIT_1,
+ SFX_HFYPR_SOLICIT_2,
+ SFX_HFYPR_SOLICIT_3,
+ SFX_HFYPR_SOLICIT_4,
+ SFX_HFYPR_SOLICIT_5,
+ SFX_HFYPR_SOLICIT_6,
+ SFX_HFYPR_SOLICIT_7,
+ SFX_HFYPR_SOLICIT_8,
+ SFX_HFYPR_SOLICIT_9,
+ SFX_HFYPR_SOLICIT_10,
+ SFX_HFYPR_SOLICIT_11,
+ SFX_HFYPR_SOLICIT_12,
+ SFX_HFYPR_SOLICIT_13,
+ SFX_HFYPR_SOLICIT_14,
+ SFX_HFYPR_TAXI_1,
+
+ SFX_HFYMD_BUMP_1,
+ SFX_HFYMD_BUMP_2,
+ SFX_HFYMD_BUMP_3,
+ SFX_HFYMD_BUMP_4,
+ SFX_HFYMD_BUMP_5,
+ SFX_HFYMD_BUMP_6,
+ SFX_HFYMD_BUMP_7,
+ SFX_HFYMD_BUMP_8,
+ SFX_HFYMD_BUMP_9,
+ SFX_HFYMD_DODGE_1,
+ SFX_HFYMD_DODGE_2,
+ SFX_HFYMD_DODGE_3,
+ SFX_HFYMD_DODGE_4,
+ SFX_HFYMD_DODGE_5,
+ SFX_HFYMD_DODGE_6,
+ SFX_HFYMD_DODGE_7,
+ SFX_HFYMD_DODGE_8,
+ SFX_HFYMD_FIGHT_1,
+ SFX_HFYMD_FIGHT_2,
+ SFX_HFYMD_FIGHT_3,
+ SFX_HFYMD_FIGHT_4,
+ SFX_HFYMD_FIGHT_5,
+ SFX_HFYMD_FIGHT_6,
+ SFX_HFYMD_FIGHT_7,
+ SFX_HFYMD_FIGHT_8,
+ SFX_HFYMD_FIGHT_9,
+ SFX_HFYMD_GUN_PANIC_1,
+ SFX_HFYMD_GUN_PANIC_2,
+ SFX_HFYMD_GUN_PANIC_3,
+ SFX_HFYMD_GUN_PANIC_4,
+ SFX_HFYMD_GUN_PANIC_5,
+ SFX_HFYMD_MUGGED_1,
+ SFX_HFYMD_MUGGED_2,
+ SFX_HFYMD_SAVED_1,
+ SFX_HFYMD_SAVED_2,
+ SFX_HFYMD_SAVED_3,
+ SFX_HFYMD_SOLICIT_1,
+ SFX_HFYMD_SOLICIT_2,
+ SFX_HFYMD_SOLICIT_3,
+ SFX_HFYMD_SOLICIT_4,
+ SFX_HFYMD_SOLICIT_5,
+ SFX_HFYMD_SOLICIT_6,
+ SFX_HFYMD_SOLICIT_7,
+ SFX_HFYMD_SOLICIT_8,
+ SFX_HFYMD_SOLICIT_9,
+ SFX_HFYMD_SOLICIT_10,
+ SFX_HFYMD_SOLICIT_11,
+ SFX_HFYMD_SOLICIT_12,
+ SFX_HFYMD_SOLICIT_13,
+ SFX_HFYMD_SOLICIT_14,
+ SFX_HFYMD_SOLICIT_15,
+ SFX_HFYMD_TAXI_1,
+
+ SFX_WFOBE_BLOCKED_1,
+ SFX_WFOBE_BLOCKED_2,
+ SFX_WFOBE_BLOCKED_3,
+ SFX_WFOBE_BLOCKED_4,
+ SFX_WFOBE_BLOCKED_5,
+ SFX_WFOBE_BLOCKED_6,
+ SFX_WFOBE_BLOCKED_7,
+ SFX_WFOBE_BLOCKED_8,
+ SFX_WFOBE_BUMP_1,
+ SFX_WFOBE_BUMP_2,
+ SFX_WFOBE_BUMP_3,
+ SFX_WFOBE_BUMP_4,
+ SFX_WFOBE_BUMP_5,
+ SFX_WFOBE_BUMP_6,
+ SFX_WFOBE_BUMP_7,
+ SFX_WFOBE_BUMP_8,
+ SFX_WFOBE_BUMP_9,
+ SFX_WFOBE_BUMP_10,
+ SFX_WFOBE_CAR_CRASH_1,
+ SFX_WFOBE_CAR_CRASH_2,
+ SFX_WFOBE_CAR_CRASH_3,
+ SFX_WFOBE_CAR_CRASH_4,
+ SFX_WFOBE_CAR_CRASH_5,
+ SFX_WFOBE_CAR_CRASH_6,
+ SFX_WFOBE_CAR_CRASH_7,
+ SFX_WFOBE_CHAT_1,
+ SFX_WFOBE_CHAT_2,
+ SFX_WFOBE_CHAT_3,
+ SFX_WFOBE_CHAT_4,
+ SFX_WFOBE_CHAT_5,
+ SFX_WFOBE_CHAT_6,
+ SFX_WFOBE_CHAT_7,
+ SFX_WFOBE_CHAT_8,
+ SFX_WFOBE_CHAT_9,
+ SFX_WFOBE_CHAT_10,
+ SFX_WFOBE_DODGE_1,
+ SFX_WFOBE_DODGE_2,
+ SFX_WFOBE_DODGE_3,
+ SFX_WFOBE_DODGE_4,
+ SFX_WFOBE_DODGE_5,
+ SFX_WFOBE_DODGE_6,
+ SFX_WFOBE_DODGE_7,
+ SFX_WFOBE_DODGE_8,
+ SFX_WFOBE_GENERIC_CRASH_1,
+ SFX_WFOBE_GENERIC_CRASH_2,
+ SFX_WFOBE_GENERIC_CRASH_3,
+ SFX_WFOBE_GENERIC_CRASH_4,
+ SFX_WFOBE_GENERIC_CRASH_5,
+ SFX_WFOBE_GENERIC_CRASH_6,
+ SFX_WFOBE_GENERIC_CRASH_7,
+ SFX_WFOBE_GENERIC_CRASH_8,
+ SFX_WFOBE_GENERIC_CRASH_9,
+ SFX_WFOBE_GENERIC_CRASH_10,
+ SFX_WFOBE_GUN_PANIC_1,
+ SFX_WFOBE_GUN_PANIC_2,
+ SFX_WFOBE_GUN_PANIC_3,
+ SFX_WFOBE_GUN_PANIC_4,
+ SFX_WFOBE_GUN_PANIC_5,
+ SFX_WFOBE_JACKED_1,
+ SFX_WFOBE_JACKED_2,
+ SFX_WFOBE_JACKED_3,
+ SFX_WFOBE_JACKED_4,
+ SFX_WFOBE_RUN_1,
+ SFX_WFOBE_RUN_2,
+ SFX_WFOBE_RUN_3,
+ SFX_WFOBE_RUN_4,
+ SFX_WFOBE_RUN_5,
+ SFX_WFOBE_RUN_6,
+ SFX_WFOBE_RUN_7,
+ SFX_WFOBE_SAVED_1,
+ SFX_WFOBE_SAVED_2,
+ SFX_WFOBE_SAVED_3,
+ SFX_WFOBE_SHOCKED_1,
+ SFX_WFOBE_SHOCKED_2,
+ SFX_WFOBE_SHOCKED_3,
+ SFX_WFOBE_TAXI_1,
+ SFX_WFOBE_TAXI_2,
+
+ SFX_BFYRI_BLOCKED_1,
+ SFX_BFYRI_BLOCKED_2,
+ SFX_BFYRI_BLOCKED_3,
+ SFX_BFYRI_BLOCKED_4,
+ SFX_BFYRI_BLOCKED_5,
+ SFX_BFYRI_BLOCKED_6,
+ SFX_BFYRI_BLOCKED_7,
+ SFX_BFYRI_BLOCKED_8,
+ SFX_BFYRI_BLOCKED_9,
+ SFX_BFYRI_BUMP_1,
+ SFX_BFYRI_BUMP_2,
+ SFX_BFYRI_BUMP_3,
+ SFX_BFYRI_BUMP_4,
+ SFX_BFYRI_BUMP_5,
+ SFX_BFYRI_BUMP_6,
+ SFX_BFYRI_BUMP_7,
+ SFX_BFYRI_BUMP_8,
+ SFX_BFYRI_BUMP_9,
+ SFX_BFYRI_CAR_CRASH_1,
+ SFX_BFYRI_CAR_CRASH_2,
+ SFX_BFYRI_CAR_CRASH_3,
+ SFX_BFYRI_CAR_CRASH_4,
+ SFX_BFYRI_CAR_CRASH_5,
+ SFX_BFYRI_CAR_CRASH_6,
+ SFX_BFYRI_CAR_CRASH_7,
+ SFX_BFYRI_CAR_CRASH_8,
+ SFX_BFYRI_DODGE_1,
+ SFX_BFYRI_DODGE_2,
+ SFX_BFYRI_DODGE_3,
+ SFX_BFYRI_DODGE_4,
+ SFX_BFYRI_DODGE_5,
+ SFX_BFYRI_DODGE_6,
+ SFX_BFYRI_DODGE_7,
+ SFX_BFYRI_DODGE_8,
+ SFX_BFYRI_EYEING_1,
+ SFX_BFYRI_EYEING_2,
+ SFX_BFYRI_EYEING_3,
+ SFX_BFYRI_GENERIC_CRASH_1,
+ SFX_BFYRI_GENERIC_CRASH_2,
+ SFX_BFYRI_GENERIC_CRASH_3,
+ SFX_BFYRI_GENERIC_CRASH_4,
+ SFX_BFYRI_GENERIC_CRASH_5,
+ SFX_BFYRI_GENERIC_CRASH_6,
+ SFX_BFYRI_GENERIC_CRASH_7,
+ SFX_BFYRI_GUN_PANIC_1,
+ SFX_BFYRI_GUN_PANIC_2,
+ SFX_BFYRI_GUN_PANIC_3,
+ SFX_BFYRI_GUN_PANIC_4,
+ SFX_BFYRI_JACKED_1,
+ SFX_BFYRI_JACKED_2,
+ SFX_BFYRI_JACKED_3,
+ SFX_BFYRI_JACKED_4,
+ SFX_BFYRI_JACKED_5,
+ SFX_BFYRI_JACKED_6,
+ SFX_BFYRI_JACKED_7,
+ SFX_BFYRI_JACKED_8,
+ SFX_BFYRI_JACKING_1,
+ SFX_BFYRI_JACKING_2,
+ SFX_BFYRI_JACKING_3,
+ SFX_BFYRI_JACKING_4,
+ SFX_BFYRI_LOST_1,
+ SFX_BFYRI_LOST_2,
+ SFX_BFYRI_MUGGED_1,
+ SFX_BFYRI_MUGGED_2,
+ SFX_BFYRI_MUGGED_3,
+ SFX_BFYRI_RUN_1,
+ SFX_BFYRI_RUN_2,
+ SFX_BFYRI_RUN_3,
+ SFX_BFYRI_RUN_4,
+ SFX_BFYRI_RUN_5,
+ SFX_BFYRI_RUN_6,
+ SFX_BFYRI_SAVED_1,
+ SFX_BFYRI_SAVED_2,
+ SFX_BFYRI_SHOCKED_1,
+ SFX_BFYRI_SHOCKED_2,
+ SFX_BFYRI_SHOCKED_3,
+ SFX_BFYRI_SHOCKED_4,
+ SFX_BFYRI_TAXI_1,
+
+ SFX_BFYBE_BLOCKED_1,
+ SFX_BFYBE_BLOCKED_2,
+ SFX_BFYBE_BLOCKED_3,
+ SFX_BFYBE_BLOCKED_4,
+ SFX_BFYBE_BLOCKED_5,
+ SFX_BFYBE_BLOCKED_6,
+ SFX_BFYBE_BLOCKED_7,
+ SFX_BFYBE_BLOCKED_8,
+ SFX_BFYBE_BLOCKED_9,
+ SFX_BFYBE_BLOCKED_10,
+ SFX_BFYBE_BLOCKED_11,
+ SFX_BFYBE_BLOCKED_12,
+ SFX_BFYBE_CAR_CRASH_1,
+ SFX_BFYBE_CAR_CRASH_2,
+ SFX_BFYBE_CAR_CRASH_3,
+ SFX_BFYBE_CAR_CRASH_4,
+ SFX_BFYBE_CAR_CRASH_5,
+ SFX_BFYBE_CAR_CRASH_6,
+ SFX_BFYBE_CAR_CRASH_7,
+ SFX_BFYBE_CAR_CRASH_8,
+ SFX_BFYBE_CAR_CRASH_9,
+ SFX_BFYBE_CAR_CRASH_10,
+ SFX_BFYBE_CHAT_1,
+ SFX_BFYBE_CHAT_2,
+ SFX_BFYBE_CHAT_3,
+ SFX_BFYBE_CHAT_4,
+ SFX_BFYBE_CHAT_5,
+ SFX_BFYBE_CHAT_6,
+ SFX_BFYBE_CHAT_7,
+ SFX_BFYBE_CHAT_8,
+ SFX_BFYBE_CHAT_9,
+ SFX_BFYBE_CHAT_10,
+ SFX_BFYBE_CHAT_11,
+ SFX_BFYBE_CHAT_12,
+ SFX_BFYBE_CHAT_13,
+ SFX_BFYBE_CHAT_14,
+ SFX_BFYBE_CHAT_15,
+ SFX_BFYBE_CHAT_16,
+ SFX_BFYBE_DODGE_1,
+ SFX_BFYBE_DODGE_2,
+ SFX_BFYBE_DODGE_3,
+ SFX_BFYBE_DODGE_4,
+ SFX_BFYBE_DODGE_5,
+ SFX_BFYBE_DODGE_6,
+ SFX_BFYBE_DODGE_7,
+ SFX_BFYBE_DODGE_8,
+ SFX_BFYBE_DODGE_9,
+ SFX_BFYBE_DODGE_10,
+ SFX_BFYBE_EYEING_1,
+ SFX_BFYBE_EYEING_2,
+ SFX_BFYBE_EYEING_3,
+ SFX_BFYBE_EYEING_4,
+ SFX_BFYBE_GENERIC_CRASH_1,
+ SFX_BFYBE_GENERIC_CRASH_2,
+ SFX_BFYBE_GENERIC_CRASH_3,
+ SFX_BFYBE_GENERIC_CRASH_4,
+ SFX_BFYBE_GENERIC_CRASH_5,
+ SFX_BFYBE_GENERIC_CRASH_6,
+ SFX_BFYBE_GENERIC_CRASH_7,
+ SFX_BFYBE_GENERIC_CRASH_8,
+ SFX_BFYBE_GUN_COOL_1,
+ SFX_BFYBE_GUN_COOL_2,
+ SFX_BFYBE_GUN_COOL_3,
+ SFX_BFYBE_GUN_COOL_4,
+ SFX_BFYBE_GUN_COOL_5,
+ SFX_BFYBE_GUN_COOL_6,
+ SFX_BFYBE_JACKED_1,
+ SFX_BFYBE_JACKED_2,
+ SFX_BFYBE_JACKED_3,
+ SFX_BFYBE_JACKED_4,
+ SFX_BFYBE_JACKED_5,
+ SFX_BFYBE_JACKED_6,
+ SFX_BFYBE_JACKED_7,
+ SFX_BFYBE_JACKED_8,
+ SFX_BFYBE_LOST_1,
+ SFX_BFYBE_LOST_2,
+ SFX_BFYBE_LOST_3,
+ SFX_BFYBE_LOST_4,
+ SFX_BFYBE_MUGGED_1,
+ SFX_BFYBE_MUGGED_2,
+ SFX_BFYBE_MUGGED_3,
+ SFX_BFYBE_MUGGED_4,
+ SFX_BFYBE_MUGGED_5,
+ SFX_BFYBE_RUN_1,
+ SFX_BFYBE_RUN_2,
+ SFX_BFYBE_RUN_3,
+ SFX_BFYBE_RUN_4,
+ SFX_BFYBE_RUN_5,
+ SFX_BFYBE_RUN_6,
+ SFX_BFYBE_SAVED_1,
+ SFX_BFYBE_SAVED_2,
+ SFX_BFYBE_SHOCKED_1,
+ SFX_BFYBE_SHOCKED_2,
+ SFX_BFYBE_SHOCKED_3,
+ SFX_BFYBE_SHOCKED_4,
+ SFX_BFYBE_TAXI_1,
+ SFX_BFYBE_TAXI_2,
+ SFX_BFYBE_TAXI_3,
+
+ SFX_BMOTR_BUMP_1,
+ SFX_BMOTR_BUMP_2,
+ SFX_BMOTR_BUMP_3,
+ SFX_BMOTR_BUMP_4,
+ SFX_BMOTR_BUMP_5,
+ SFX_BMOTR_BUMP_6,
+ SFX_BMOTR_BUMP_7,
+ SFX_BMOTR_BUMP_8,
+ SFX_BMOTR_BUMP_9,
+ SFX_BMOTR_BUMP_10,
+ SFX_BMOTR_CHAT_1,
+ SFX_BMOTR_CHAT_2,
+ SFX_BMOTR_CHAT_3,
+ SFX_BMOTR_CHAT_4,
+ SFX_BMOTR_CHAT_5,
+ SFX_BMOTR_CHAT_6,
+ SFX_BMOTR_CHAT_7,
+ SFX_BMOTR_CHAT_8,
+ SFX_BMOTR_CHAT_9,
+ SFX_BMOTR_CHAT_10,
+ SFX_BMOTR_DODGE_1,
+ SFX_BMOTR_DODGE_2,
+ SFX_BMOTR_DODGE_3,
+ SFX_BMOTR_DODGE_4,
+ SFX_BMOTR_DODGE_5,
+ SFX_BMOTR_DODGE_6,
+ SFX_BMOTR_DODGE_7,
+ SFX_BMOTR_DODGE_8,
+ SFX_BMOTR_DODGE_9,
+ SFX_BMOTR_DODGE_10,
+ SFX_BMOTR_DODGE_11,
+ SFX_BMOTR_EYEING_1,
+ SFX_BMOTR_EYEING_2,
+ SFX_BMOTR_EYEING_3,
+ SFX_BMOTR_GUN_COOL_1,
+ SFX_BMOTR_GUN_COOL_2,
+ SFX_BMOTR_GUN_COOL_3,
+ SFX_BMOTR_GUN_COOL_4,
+ SFX_BMOTR_GUN_COOL_5,
+ SFX_BMOTR_INNOCENT_1,
+ SFX_BMOTR_INNOCENT_2,
+ SFX_BMOTR_INNOCENT_3,
+ SFX_BMOTR_INNOCENT_4,
+ SFX_BMOTR_RUN_1,
+ SFX_BMOTR_RUN_2,
+ SFX_BMOTR_RUN_3,
+ SFX_BMOTR_RUN_4,
+ SFX_BMOTR_RUN_5,
+ SFX_BMOTR_RUN_6,
+ SFX_BMOTR_RUN_7,
+ SFX_BMOTR_SAVED_1,
+ SFX_BMOTR_SOLICIT_1,
+ SFX_BMOTR_SOLICIT_2,
+ SFX_BMOTR_SOLICIT_3,
+ SFX_BMOTR_SOLICIT_4,
+ SFX_BMOTR_SOLICIT_5,
+ SFX_BMOTR_SOLICIT_6,
+ SFX_BMOTR_SOLICIT_7,
+ SFX_BMOTR_TAXI_1,
+
+ SFX_BMYST_BLOCKED_1,
+ SFX_BMYST_BLOCKED_2,
+ SFX_BMYST_BLOCKED_3,
+ SFX_BMYST_BLOCKED_4,
+ SFX_BMYST_BLOCKED_5,
+ SFX_BMYST_BLOCKED_6,
+ SFX_BMYST_BLOCKED_7,
+ SFX_BMYST_BLOCKED_8,
+ SFX_BMYST_BUMP_1,
+ SFX_BMYST_BUMP_2,
+ SFX_BMYST_BUMP_3,
+ SFX_BMYST_BUMP_4,
+ SFX_BMYST_BUMP_5,
+ SFX_BMYST_BUMP_6,
+ SFX_BMYST_BUMP_7,
+ SFX_BMYST_BUMP_8,
+ SFX_BMYST_BUMP_9,
+ SFX_BMYST_BUMP_10,
+ SFX_BMYST_BUMP_11,
+ SFX_BMYST_CAR_CRASH_1,
+ SFX_BMYST_CAR_CRASH_2,
+ SFX_BMYST_CAR_CRASH_3,
+ SFX_BMYST_CAR_CRASH_4,
+ SFX_BMYST_CAR_CRASH_5,
+ SFX_BMYST_CAR_CRASH_6,
+ SFX_BMYST_CAR_CRASH_7,
+ SFX_BMYST_CAR_CRASH_8,
+ SFX_BMYST_CAR_CRASH_9,
+ SFX_BMYST_CHAT_1,
+ SFX_BMYST_CHAT_2,
+ SFX_BMYST_CHAT_3,
+ SFX_BMYST_CHAT_4,
+ SFX_BMYST_CHAT_5,
+ SFX_BMYST_CHAT_6,
+ SFX_BMYST_CHAT_7,
+ SFX_BMYST_CHAT_8,
+ SFX_BMYST_CHAT_9,
+ SFX_BMYST_CHAT_10,
+ SFX_BMYST_CHAT_11,
+ SFX_BMYST_CHAT_12,
+ SFX_BMYST_DODGE_1,
+ SFX_BMYST_DODGE_2,
+ SFX_BMYST_DODGE_3,
+ SFX_BMYST_DODGE_4,
+ SFX_BMYST_DODGE_5,
+ SFX_BMYST_DODGE_6,
+ SFX_BMYST_DODGE_7,
+ SFX_BMYST_DODGE_8,
+ SFX_BMYST_FIGHT_1,
+ SFX_BMYST_FIGHT_2,
+ SFX_BMYST_FIGHT_3,
+ SFX_BMYST_FIGHT_4,
+ SFX_BMYST_FIGHT_5,
+ SFX_BMYST_FIGHT_6,
+ SFX_BMYST_GENERIC_CRASH_1,
+ SFX_BMYST_GENERIC_CRASH_2,
+ SFX_BMYST_GENERIC_CRASH_3,
+ SFX_BMYST_GENERIC_CRASH_4,
+ SFX_BMYST_GENERIC_CRASH_5,
+ SFX_BMYST_GENERIC_CRASH_6,
+ SFX_BMYST_GENERIC_CRASH_7,
+ SFX_BMYST_GUN_COOL_1,
+ SFX_BMYST_GUN_COOL_2,
+ SFX_BMYST_GUN_COOL_3,
+ SFX_BMYST_GUN_COOL_4,
+ SFX_BMYST_GUN_COOL_5,
+ SFX_BMYST_GUN_COOL_6,
+ SFX_BMYST_JACKED_1,
+ SFX_BMYST_JACKED_2,
+ SFX_BMYST_JACKED_3,
+ SFX_BMYST_JACKED_4,
+ SFX_BMYST_JACKED_5,
+ SFX_BMYST_JACKED_6,
+ SFX_BMYST_JACKED_7,
+ SFX_BMYST_JACKED_8,
+ SFX_BMYST_JACKING_1,
+ SFX_BMYST_JACKING_2,
+ SFX_BMYST_JACKING_3,
+ SFX_BMYST_JACKING_4,
+ SFX_BMYST_MUGGED_1,
+ SFX_BMYST_MUGGED_2,
+ SFX_BMYST_MUGGING_1,
+ SFX_BMYST_MUGGING_2,
+ SFX_BMYST_MUGGING_3,
+ SFX_BMYST_MUGGING_4,
+ SFX_BMYST_TAXI_1,
+ SFX_BMYST_TAXI_2,
+
+ SFX_WMYPI_BLOCKED_1,
+ SFX_WMYPI_BLOCKED_2,
+ SFX_WMYPI_BLOCKED_3,
+ SFX_WMYPI_BLOCKED_4,
+ SFX_WMYPI_BLOCKED_5,
+ SFX_WMYPI_BLOCKED_6,
+ SFX_WMYPI_BLOCKED_7,
+ SFX_WMYPI_BLOCKED_8,
+ SFX_WMYPI_BUMP_1,
+ SFX_WMYPI_BUMP_2,
+ SFX_WMYPI_BUMP_3,
+ SFX_WMYPI_BUMP_4,
+ SFX_WMYPI_BUMP_5,
+ SFX_WMYPI_BUMP_6,
+ SFX_WMYPI_BUMP_7,
+ SFX_WMYPI_BUMP_8,
+ SFX_WMYPI_BUMP_9,
+ SFX_WMYPI_BUMP_10,
+ SFX_WMYPI_CAR_CRASH_1,
+ SFX_WMYPI_CAR_CRASH_2,
+ SFX_WMYPI_CAR_CRASH_3,
+ SFX_WMYPI_CAR_CRASH_4,
+ SFX_WMYPI_CAR_CRASH_5,
+ SFX_WMYPI_CAR_CRASH_6,
+ SFX_WMYPI_CAR_CRASH_7,
+ SFX_WMYPI_CAR_CRASH_8,
+ SFX_WMYPI_DODGE_1,
+ SFX_WMYPI_DODGE_2,
+ SFX_WMYPI_DODGE_3,
+ SFX_WMYPI_DODGE_4,
+ SFX_WMYPI_DODGE_5,
+ SFX_WMYPI_DODGE_6,
+ SFX_WMYPI_DODGE_7,
+ SFX_WMYPI_DODGE_8,
+ SFX_WMYPI_EYEING_1,
+ SFX_WMYPI_EYEING_2,
+ SFX_WMYPI_EYEING_3,
+ SFX_WMYPI_EYEING_4,
+ SFX_WMYPI_EYEING_5,
+ SFX_WMYPI_EYEING_6,
+ SFX_WMYPI_FIGHT_1,
+ SFX_WMYPI_FIGHT_2,
+ SFX_WMYPI_FIGHT_3,
+ SFX_WMYPI_FIGHT_4,
+ SFX_WMYPI_FIGHT_5,
+ SFX_WMYPI_FIGHT_6,
+ SFX_WMYPI_FIGHT_7,
+ SFX_WMYPI_FIGHT_8,
+ SFX_WMYPI_FIGHT_9,
+ SFX_WMYPI_GENERIC_CRASH_1,
+ SFX_WMYPI_GENERIC_CRASH_2,
+ SFX_WMYPI_GENERIC_CRASH_3,
+ SFX_WMYPI_GENERIC_CRASH_4,
+ SFX_WMYPI_GENERIC_CRASH_5,
+ SFX_WMYPI_GENERIC_CRASH_6,
+ SFX_WMYPI_GENERIC_CRASH_7,
+ SFX_WMYPI_GENERIC_CRASH_8,
+ SFX_WMYPI_GUN_COOL_1,
+ SFX_WMYPI_GUN_COOL_2,
+ SFX_WMYPI_GUN_COOL_3,
+ SFX_WMYPI_GUN_COOL_4,
+ SFX_WMYPI_GUN_COOL_5,
+ SFX_WMYPI_INNOCENT_1,
+ SFX_WMYPI_INNOCENT_2,
+ SFX_WMYPI_JACKED_1,
+ SFX_WMYPI_JACKED_2,
+ SFX_WMYPI_JACKED_3,
+ SFX_WMYPI_JACKED_4,
+ SFX_WMYPI_JACKED_5,
+ SFX_WMYPI_JACKED_6,
+ SFX_WMYPI_JACKING_1,
+ SFX_WMYPI_JACKING_2,
+ SFX_WMYPI_JACKING_3,
+ SFX_WMYPI_JACKING_4,
+ SFX_WMYPI_MUGGED_1,
+ SFX_WMYPI_MUGGED_2,
+ SFX_WMYPI_SAVED_1,
+ SFX_WMYPI_SAVED_2,
+ SFX_WMYPI_TAXI_1,
+ SFX_WMYPI_TAXI_2,
+ SFX_WMYPI_TAXI_3,
+ SFX_WMYPI_TAXI_4,
+
+ SFX_BMYCR_BLOCKED_1,
+ SFX_BMYCR_BLOCKED_2,
+ SFX_BMYCR_BLOCKED_3,
+ SFX_BMYCR_BLOCKED_4,
+ SFX_BMYCR_BLOCKED_5,
+ SFX_BMYCR_BLOCKED_6,
+ SFX_BMYCR_BLOCKED_7,
+ SFX_BMYCR_BLOCKED_8,
+ SFX_BMYCR_BLOCKED_9,
+ SFX_BMYCR_BLOCKED_10,
+ SFX_BMYCR_BLOCKED_11,
+ SFX_BMYCR_BLOCKED_12,
+ SFX_BMYCR_BUMP_1,
+ SFX_BMYCR_BUMP_2,
+ SFX_BMYCR_BUMP_3,
+ SFX_BMYCR_BUMP_4,
+ SFX_BMYCR_BUMP_5,
+ SFX_BMYCR_BUMP_6,
+ SFX_BMYCR_BUMP_7,
+ SFX_BMYCR_BUMP_8,
+ SFX_BMYCR_BUMP_9,
+ SFX_BMYCR_BUMP_10,
+ SFX_BMYCR_BUMP_11,
+ SFX_BMYCR_CAR_CRASH_1,
+ SFX_BMYCR_CAR_CRASH_2,
+ SFX_BMYCR_CAR_CRASH_3,
+ SFX_BMYCR_CAR_CRASH_4,
+ SFX_BMYCR_CAR_CRASH_5,
+ SFX_BMYCR_CAR_CRASH_6,
+ SFX_BMYCR_CAR_CRASH_7,
+ SFX_BMYCR_CAR_CRASH_8,
+ SFX_BMYCR_CAR_CRASH_9,
+ SFX_BMYCR_DODGE_1,
+ SFX_BMYCR_DODGE_2,
+ SFX_BMYCR_DODGE_3,
+ SFX_BMYCR_DODGE_4,
+ SFX_BMYCR_DODGE_5,
+ SFX_BMYCR_DODGE_6,
+ SFX_BMYCR_DODGE_7,
+ SFX_BMYCR_DODGE_8,
+ SFX_BMYCR_EYEING_1,
+ SFX_BMYCR_EYEING_2,
+ SFX_BMYCR_FIGHT_1,
+ SFX_BMYCR_FIGHT_2,
+ SFX_BMYCR_FIGHT_3,
+ SFX_BMYCR_FIGHT_4,
+ SFX_BMYCR_FIGHT_5,
+ SFX_BMYCR_FIGHT_6,
+ SFX_BMYCR_FIGHT_7,
+ SFX_BMYCR_FIGHT_8,
+ SFX_BMYCR_GENERIC_CRASH_1,
+ SFX_BMYCR_GENERIC_CRASH_2,
+ SFX_BMYCR_GENERIC_CRASH_3,
+ SFX_BMYCR_GENERIC_CRASH_4,
+ SFX_BMYCR_GENERIC_CRASH_5,
+ SFX_BMYCR_GENERIC_CRASH_6,
+ SFX_BMYCR_GENERIC_CRASH_7,
+ SFX_BMYCR_GUN_COOL_1,
+ SFX_BMYCR_GUN_COOL_2,
+ SFX_BMYCR_GUN_COOL_3,
+ SFX_BMYCR_GUN_COOL_4,
+ SFX_BMYCR_GUN_COOL_5,
+ SFX_BMYCR_GUN_COOL_6,
+ SFX_BMYCR_INNOCENT_1,
+ SFX_BMYCR_INNOCENT_2,
+ SFX_BMYCR_INNOCENT_3,
+ SFX_BMYCR_INNOCENT_4,
+ SFX_BMYCR_JACKED_1,
+ SFX_BMYCR_JACKED_2,
+ SFX_BMYCR_JACKED_3,
+ SFX_BMYCR_JACKED_4,
+ SFX_BMYCR_JACKED_5,
+ SFX_BMYCR_JACKED_6,
+ SFX_BMYCR_JACKING_1,
+ SFX_BMYCR_JACKING_2,
+ SFX_BMYCR_JACKING_3,
+ SFX_BMYCR_JACKING_4,
+ SFX_BMYCR_JACKING_5,
+ SFX_BMYCR_JACKING_6,
+ SFX_BMYCR_JACKING_7,
+ SFX_BMYCR_JACKING_8,
+ SFX_BMYCR_JACKING_9,
+ SFX_BMYCR_JACKING_10,
+ SFX_BMYCR_JACKING_11,
+ SFX_BMYCR_JACKING_12,
+ SFX_BMYCR_MUGGED_1,
+ SFX_BMYCR_MUGGED_2,
+ SFX_BMYCR_MUGGED_3,
+ SFX_BMYCR_MUGGING_1,
+ SFX_BMYCR_MUGGING_2,
+ SFX_BMYCR_MUGGING_3,
+ SFX_BMYCR_MUGGING_4,
+ SFX_BMYCR_MUGGING_5,
+ SFX_BMYCR_MUGGING_6,
+ SFX_BMYCR_SAVED_1,
+ SFX_BMYCR_SAVED_2,
+
+ SFX_WMORI_BLOCKED_1,
+ SFX_WMORI_BLOCKED_2,
+ SFX_WMORI_BLOCKED_3,
+ SFX_WMORI_BLOCKED_4,
+ SFX_WMORI_BLOCKED_5,
+ SFX_WMORI_BLOCKED_6,
+ SFX_WMORI_BLOCKED_7,
+ SFX_WMORI_BLOCKED_8,
+ SFX_WMORI_BLOCKED_9,
+ SFX_WMORI_BLOCKED_10,
+ SFX_WMORI_BUMP_1,
+ SFX_WMORI_BUMP_2,
+ SFX_WMORI_BUMP_3,
+ SFX_WMORI_BUMP_4,
+ SFX_WMORI_BUMP_5,
+ SFX_WMORI_BUMP_6,
+ SFX_WMORI_BUMP_7,
+ SFX_WMORI_BUMP_8,
+ SFX_WMORI_BUMP_9,
+ SFX_WMORI_BUMP_10,
+ SFX_WMORI_BUMP_11,
+ SFX_WMORI_BUMP_12,
+ SFX_WMORI_BUMP_13,
+ SFX_WMORI_BUMP_14,
+ SFX_WMORI_CAR_CRASH_1,
+ SFX_WMORI_CAR_CRASH_2,
+ SFX_WMORI_CAR_CRASH_3,
+ SFX_WMORI_CAR_CRASH_4,
+ SFX_WMORI_CAR_CRASH_5,
+ SFX_WMORI_CAR_CRASH_6,
+ SFX_WMORI_DODGE_1,
+ SFX_WMORI_DODGE_2,
+ SFX_WMORI_DODGE_3,
+ SFX_WMORI_DODGE_4,
+ SFX_WMORI_DODGE_5,
+ SFX_WMORI_DODGE_6,
+ SFX_WMORI_DODGE_7,
+ SFX_WMORI_DODGE_8,
+ SFX_WMORI_DODGE_9,
+ SFX_WMORI_DODGE_10,
+ SFX_WMORI_EYEING_1,
+ SFX_WMORI_EYEING_2,
+ SFX_WMORI_EYEING_3,
+ SFX_WMORI_GENERIC_CRASH_1,
+ SFX_WMORI_GENERIC_CRASH_2,
+ SFX_WMORI_GENERIC_CRASH_3,
+ SFX_WMORI_GENERIC_CRASH_4,
+ SFX_WMORI_GENERIC_CRASH_5,
+ SFX_WMORI_GENERIC_CRASH_6,
+ SFX_WMORI_GENERIC_CRASH_7,
+ SFX_WMORI_GENERIC_CRASH_8,
+ SFX_WMORI_GUN_PANIC_1,
+ SFX_WMORI_GUN_PANIC_2,
+ SFX_WMORI_GUN_PANIC_3,
+ SFX_WMORI_GUN_PANIC_4,
+ SFX_WMORI_GUN_PANIC_5,
+ SFX_WMORI_GUN_PANIC_6,
+ SFX_WMORI_GUN_PANIC_7,
+ SFX_WMORI_GUN_PANIC_8,
+ SFX_WMORI_GUN_PANIC_9,
+ SFX_WMORI_JACKED_1,
+ SFX_WMORI_JACKED_2,
+ SFX_WMORI_JACKED_3,
+ SFX_WMORI_JACKED_4,
+ SFX_WMORI_JACKED_5,
+ SFX_WMORI_JACKED_6,
+ SFX_WMORI_LOST_1,
+ SFX_WMORI_LOST_2,
+ SFX_WMORI_MUGGED_1,
+ SFX_WMORI_MUGGED_2,
+ SFX_WMORI_MUGGED_3,
+ SFX_WMORI_MUGGED_4,
+ SFX_WMORI_RUN_1,
+ SFX_WMORI_RUN_2,
+ SFX_WMORI_RUN_3,
+ SFX_WMORI_RUN_4,
+ SFX_WMORI_RUN_5,
+ SFX_WMORI_RUN_6,
+ SFX_WMORI_RUN_7,
+ SFX_WMORI_RUN_8,
+ SFX_WMORI_RUN_9,
+ SFX_WMORI_RUN_10,
+ SFX_WMORI_RUN_11,
+ SFX_WMORI_RUN_12,
+ SFX_WMORI_SAVED_1,
+ SFX_WMORI_SAVED_2,
+ SFX_WMORI_SHOCKED_1,
+ SFX_WMORI_SHOCKED_2,
+ SFX_WMORI_SHOCKED_3,
+ SFX_WMORI_SHOCKED_4,
+ SFX_WMORI_TAXI_1,
+ SFX_WMORI_TAXI_2,
+
+ SFX_WMOBU_BLOCKED_1,
+ SFX_WMOBU_BLOCKED_2,
+ SFX_WMOBU_BLOCKED_3,
+ SFX_WMOBU_BLOCKED_4,
+ SFX_WMOBU_BLOCKED_5,
+ SFX_WMOBU_BLOCKED_6,
+ SFX_WMOBU_BLOCKED_7,
+ SFX_WMOBU_BUMP_1,
+ SFX_WMOBU_BUMP_2,
+ SFX_WMOBU_BUMP_3,
+ SFX_WMOBU_BUMP_4,
+ SFX_WMOBU_BUMP_5,
+ SFX_WMOBU_BUMP_6,
+ SFX_WMOBU_BUMP_7,
+ SFX_WMOBU_BUMP_8,
+ SFX_WMOBU_BUMP_9,
+ SFX_WMOBU_BUMP_10,
+ SFX_WMOBU_CAR_CRASH_1,
+ SFX_WMOBU_CAR_CRASH_2,
+ SFX_WMOBU_CAR_CRASH_3,
+ SFX_WMOBU_CAR_CRASH_4,
+ SFX_WMOBU_CAR_CRASH_5,
+ SFX_WMOBU_CAR_CRASH_6,
+ SFX_WMOBU_CAR_CRASH_7,
+ SFX_WMOBU_DODGE_1,
+ SFX_WMOBU_DODGE_2,
+ SFX_WMOBU_DODGE_3,
+ SFX_WMOBU_DODGE_4,
+ SFX_WMOBU_DODGE_5,
+ SFX_WMOBU_DODGE_6,
+ SFX_WMOBU_DODGE_7,
+ SFX_WMOBU_DODGE_8,
+ SFX_WMOBU_EYEING_1,
+ SFX_WMOBU_EYEING_2,
+ SFX_WMOBU_FIGHT_1,
+ SFX_WMOBU_FIGHT_2,
+ SFX_WMOBU_FIGHT_3,
+ SFX_WMOBU_GENERIC_CRASH_1,
+ SFX_WMOBU_GENERIC_CRASH_2,
+ SFX_WMOBU_GENERIC_CRASH_3,
+ SFX_WMOBU_GENERIC_CRASH_4,
+ SFX_WMOBU_GENERIC_CRASH_5,
+ SFX_WMOBU_GENERIC_CRASH_6,
+ SFX_WMOBU_GENERIC_CRASH_7,
+ SFX_WMOBU_GUN_PANIC_1,
+ SFX_WMOBU_GUN_PANIC_2,
+ SFX_WMOBU_GUN_PANIC_3,
+ SFX_WMOBU_GUN_PANIC_4,
+ SFX_WMOBU_GUN_PANIC_5,
+ SFX_WMOBU_GUN_PANIC_6,
+ SFX_WMOBU_JACKED_1,
+ SFX_WMOBU_JACKED_2,
+ SFX_WMOBU_JACKED_3,
+ SFX_WMOBU_JACKED_4,
+ SFX_WMOBU_JACKED_5,
+ SFX_WMOBU_JACKED_6,
+ SFX_WMOBU_JACKED_7,
+ SFX_WMOBU_LOST_1,
+ SFX_WMOBU_LOST_2,
+ SFX_WMOBU_LOST_3,
+ SFX_WMOBU_MUGGED_1,
+ SFX_WMOBU_MUGGED_2,
+ SFX_WMOBU_SAVED_1,
+ SFX_WMOBU_SAVED_2,
+ SFX_WMOBU_SAVED_3,
+ SFX_WMOBU_TAXI_1,
+ SFX_WMOBU_TAXI_2,
+
+ SFX_BMODK_BLOCKED_1,
+ SFX_BMODK_BLOCKED_2,
+ SFX_BMODK_BLOCKED_3,
+ SFX_BMODK_BLOCKED_4,
+ SFX_BMODK_BLOCKED_5,
+ SFX_BMODK_BLOCKED_6,
+ SFX_BMODK_BLOCKED_7,
+ SFX_BMODK_BLOCKED_8,
+ SFX_BMODK_BUMP_1,
+ SFX_BMODK_BUMP_2,
+ SFX_BMODK_BUMP_3,
+ SFX_BMODK_BUMP_4,
+ SFX_BMODK_BUMP_5,
+ SFX_BMODK_BUMP_6,
+ SFX_BMODK_BUMP_7,
+ SFX_BMODK_BUMP_8,
+ SFX_BMODK_BUMP_9,
+ SFX_BMODK_BUMP_10,
+ SFX_BMODK_CAR_CRASH_1,
+ SFX_BMODK_CAR_CRASH_2,
+ SFX_BMODK_CAR_CRASH_3,
+ SFX_BMODK_CAR_CRASH_4,
+ SFX_BMODK_CAR_CRASH_5,
+ SFX_BMODK_CAR_CRASH_6,
+ SFX_BMODK_CAR_CRASH_7,
+ SFX_BMODK_CAR_CRASH_8,
+ SFX_BMODK_CAR_CRASH_9,
+ SFX_BMODK_CAR_CRASH_10,
+ SFX_BMODK_UNK, // UNUSED
+ SFX_BMODK_UNK_147_1,
+ SFX_BMODK_UNK_147_2,
+ SFX_BMODK_UNK_147_3,
+ SFX_BMODK_UNK_147_4,
+ SFX_BMODK_UNK_147_5,
+ SFX_BMODK_UNK_147_6,
+ SFX_BMODK_UNK_147_7,
+ SFX_BMODK_UNK_147_8,
+ SFX_BMODK_UNK_147_9,
+ SFX_BMODK_UNK_147_10,
+ SFX_BMODK_UNK_147_11,
+ SFX_BMODK_UNK_147_12,
+ SFX_BMODK_DODGE_1,
+ SFX_BMODK_DODGE_2,
+ SFX_BMODK_DODGE_3,
+ SFX_BMODK_DODGE_4,
+ SFX_BMODK_DODGE_5,
+ SFX_BMODK_DODGE_6,
+ SFX_BMODK_DODGE_7,
+ SFX_BMODK_GENERIC_CRASH_1,
+ SFX_BMODK_GENERIC_CRASH_2,
+ SFX_BMODK_GENERIC_CRASH_3,
+ SFX_BMODK_GENERIC_CRASH_4,
+ SFX_BMODK_GENERIC_CRASH_5,
+ SFX_BMODK_GENERIC_CRASH_6,
+ SFX_BMODK_GENERIC_CRASH_7,
+ SFX_BMODK_GUN_PANIC_1,
+ SFX_BMODK_GUN_PANIC_2,
+ SFX_BMODK_GUN_PANIC_3,
+ SFX_BMODK_GUN_PANIC_4,
+ SFX_BMODK_INNOCENT_1,
+ SFX_BMODK_INNOCENT_2,
+ SFX_BMODK_INNOCENT_3,
+ SFX_BMODK_JACKED_1,
+ SFX_BMODK_JACKED_2,
+ SFX_BMODK_JACKED_3,
+ SFX_BMODK_JACKED_4,
+ SFX_BMODK_JACKED_5,
+ SFX_BMODK_JACKED_6,
+ SFX_BMODK_JACKED_7,
+ SFX_BMODK_JACKED_8,
+ SFX_BMODK_JACKED_9,
+ SFX_BMODK_MUGGED_1,
+ SFX_BMODK_MUGGED_2,
+ SFX_BMODK_RUN_1,
+ SFX_BMODK_RUN_2,
+ SFX_BMODK_RUN_3,
+ SFX_BMODK_RUN_4,
+ SFX_BMODK_TAXI_1,
+
+ SFX_HFYBE_BUMP_1,
+ SFX_HFYBE_BUMP_2,
+ SFX_HFYBE_BUMP_3,
+ SFX_HFYBE_BUMP_4,
+ SFX_HFYBE_BUMP_5,
+ SFX_HFYBE_BUMP_6,
+ SFX_HFYBE_BUMP_7,
+ SFX_HFYBE_BUMP_8,
+ SFX_HFYBE_CAR_CRASH_1,
+ SFX_HFYBE_CAR_CRASH_2,
+ SFX_HFYBE_CAR_CRASH_3,
+ SFX_HFYBE_CAR_CRASH_4,
+ SFX_HFYBE_CAR_CRASH_5,
+ SFX_HFYBE_CAR_CRASH_6,
+ SFX_HFYBE_CHAT_1,
+ SFX_HFYBE_CHAT_2,
+ SFX_HFYBE_CHAT_3,
+ SFX_HFYBE_CHAT_4,
+ SFX_HFYBE_CHAT_5,
+ SFX_HFYBE_CHAT_6,
+ SFX_HFYBE_CHAT_7,
+ SFX_HFYBE_CHAT_8,
+ SFX_HFYBE_CHAT_9,
+ SFX_HFYBE_CHAT_10,
+ SFX_HFYBE_DODGE_1,
+ SFX_HFYBE_DODGE_2,
+ SFX_HFYBE_DODGE_3,
+ SFX_HFYBE_DODGE_4,
+ SFX_HFYBE_DODGE_5,
+ SFX_HFYBE_DODGE_6,
+ SFX_HFYBE_DODGE_7,
+ SFX_HFYBE_DODGE_8,
+ SFX_HFYBE_DODGE_9,
+ SFX_HFYBE_DODGE_10,
+ SFX_HFYBE_DODGE_11,
+ SFX_HFYBE_GENERIC_CRASH_1,
+ SFX_HFYBE_GENERIC_CRASH_2,
+ SFX_HFYBE_GENERIC_CRASH_3,
+ SFX_HFYBE_GENERIC_CRASH_4,
+ SFX_HFYBE_GENERIC_CRASH_5,
+ SFX_HFYBE_GENERIC_CRASH_6,
+ SFX_HFYBE_GENERIC_CRASH_7,
+ SFX_HFYBE_GENERIC_CRASH_8,
+ SFX_HFYBE_GUN_PANIC_1,
+ SFX_HFYBE_GUN_PANIC_2,
+ SFX_HFYBE_GUN_PANIC_3,
+ SFX_HFYBE_GUN_PANIC_4,
+ SFX_HFYBE_GUN_PANIC_5,
+ SFX_HFYBE_GUN_PANIC_6,
+ SFX_HFYBE_GUN_PANIC_7,
+ SFX_HFYBE_JACKED_1,
+ SFX_HFYBE_JACKED_2,
+ SFX_HFYBE_JACKED_3,
+ SFX_HFYBE_JACKED_4,
+ SFX_HFYBE_JACKED_5,
+ SFX_HFYBE_JACKED_6,
+ SFX_HFYBE_JACKED_7,
+ SFX_HFYBE_LOST_1,
+ SFX_HFYBE_LOST_2,
+
+ // this is a guess, idk what she's saying
+ SFX_HFYBE_RUN_1,
+ SFX_HFYBE_RUN_2,
+ SFX_HFYBE_RUN_3,
+ SFX_HFYBE_RUN_4,
+ SFX_HFYBE_RUN_5,
+ SFX_HFYBE_RUN_6,
+ SFX_HFYBE_RUN_7,
+
+ SFX_HFYBE_SHOCKED_1,
+ SFX_HFYBE_SHOCKED_2,
+ SFX_HFYBE_TAXI_1,
+
+ SFX_HFYRI_BLOCKED_1,
+ SFX_HFYRI_BLOCKED_2,
+ SFX_HFYRI_BLOCKED_3,
+ SFX_HFYRI_BLOCKED_4,
+ SFX_HFYRI_BLOCKED_5,
+ SFX_HFYRI_BLOCKED_6,
+ SFX_HFYRI_BLOCKED_7,
+ SFX_HFYRI_BLOCKED_8,
+ SFX_HFYRI_BUMP_1,
+ SFX_HFYRI_BUMP_2,
+ SFX_HFYRI_BUMP_3,
+ SFX_HFYRI_BUMP_4,
+ SFX_HFYRI_BUMP_5,
+ SFX_HFYRI_BUMP_6,
+ SFX_HFYRI_BUMP_7,
+ SFX_HFYRI_BUMP_8,
+ SFX_HFYRI_BUMP_9,
+ SFX_HFYRI_CAR_CRASH_1,
+ SFX_HFYRI_CAR_CRASH_2,
+ SFX_HFYRI_CAR_CRASH_3,
+ SFX_HFYRI_CAR_CRASH_4,
+ SFX_HFYRI_CAR_CRASH_5,
+ SFX_HFYRI_CAR_CRASH_6,
+ SFX_HFYRI_CAR_CRASH_7,
+ SFX_HFYRI_CAR_CRASH_8,
+ SFX_HFYRI_DODGE_1,
+ SFX_HFYRI_DODGE_2,
+ SFX_HFYRI_DODGE_3,
+ SFX_HFYRI_DODGE_4,
+ SFX_HFYRI_DODGE_5,
+ SFX_HFYRI_DODGE_6,
+ SFX_HFYRI_DODGE_7,
+ SFX_HFYRI_DODGE_8,
+ SFX_HFYRI_DODGE_9,
+ SFX_HFYRI_DODGE_10,
+ SFX_HFYRI_GENERIC_CRASH_1,
+ SFX_HFYRI_GENERIC_CRASH_2,
+ SFX_HFYRI_GENERIC_CRASH_3,
+ SFX_HFYRI_GENERIC_CRASH_4,
+ SFX_HFYRI_GENERIC_CRASH_5,
+ SFX_HFYRI_GENERIC_CRASH_6,
+ SFX_HFYRI_GENERIC_CRASH_7,
+ SFX_HFYRI_GUN_PANIC_1,
+ SFX_HFYRI_GUN_PANIC_2,
+ SFX_HFYRI_GUN_PANIC_3,
+ SFX_HFYRI_GUN_PANIC_4,
+ SFX_HFYRI_GUN_PANIC_5,
+ SFX_HFYRI_JACKED_1,
+ SFX_HFYRI_JACKED_2,
+ SFX_HFYRI_JACKED_3,
+ SFX_HFYRI_JACKED_4,
+ SFX_HFYRI_JACKED_5,
+ SFX_HFYRI_JACKED_6,
+ SFX_HFYRI_LOST_1,
+ SFX_HFYRI_LOST_2,
+ SFX_HFYRI_MUGGED_1,
+ SFX_HFYRI_MUGGED_2,
+ SFX_HFYRI_MUGGED_3,
+ SFX_HFYRI_MUGGED_4,
+ SFX_HFYRI_RUN_1,
+ SFX_HFYRI_RUN_2,
+ SFX_HFYRI_RUN_3,
+ SFX_HFYRI_RUN_4,
+ SFX_HFYRI_SAVED_1,
+ SFX_HFYRI_SAVED_2,
+ SFX_HFYRI_SHOCKED_1,
+ SFX_HFYRI_SHOCKED_2,
+ SFX_HFYRI_SHOCKED_3,
+ SFX_HFYRI_TAXI_1,
+ SFX_BFOST_BLOCKED_1,
+ SFX_BFOST_BLOCKED_2,
+ SFX_BFOST_BLOCKED_3,
+ SFX_BFOST_BLOCKED_4,
+ SFX_BFOST_BLOCKED_5,
+ SFX_BFOST_BLOCKED_6,
+ SFX_BFOST_BLOCKED_7,
+ SFX_BFOST_BUMP_1,
+ SFX_BFOST_BUMP_2,
+ SFX_BFOST_BUMP_3,
+ SFX_BFOST_BUMP_4,
+ SFX_BFOST_BUMP_5,
+ SFX_BFOST_BUMP_6,
+ SFX_BFOST_BUMP_7,
+ SFX_BFOST_BUMP_8,
+ SFX_BFOST_BUMP_9,
+ SFX_BFOST_BUMP_10,
+ SFX_BFOST_CAR_CRASH_1,
+ SFX_BFOST_CAR_CRASH_2,
+ SFX_BFOST_CAR_CRASH_3,
+ SFX_BFOST_CAR_CRASH_4,
+ SFX_BFOST_CAR_CRASH_5,
+ SFX_BFOST_CAR_CRASH_6,
+ SFX_BFOST_CAR_CRASH_7,
+ SFX_BFOST_CAR_CRASH_8,
+ SFX_BFOST_CHAT_1,
+ SFX_BFOST_CHAT_2,
+ SFX_BFOST_CHAT_3,
+ SFX_BFOST_CHAT_4,
+ SFX_BFOST_CHAT_5,
+ SFX_BFOST_CHAT_6,
+ SFX_BFOST_CHAT_7,
+ SFX_BFOST_CHAT_8,
+ SFX_BFOST_CHAT_9,
+ SFX_BFOST_CHAT_10,
+ SFX_BFOST_DODGE_1,
+ SFX_BFOST_DODGE_2,
+ SFX_BFOST_DODGE_3,
+ SFX_BFOST_DODGE_4,
+ SFX_BFOST_DODGE_5,
+ SFX_BFOST_DODGE_6,
+ SFX_BFOST_DODGE_7,
+ SFX_BFOST_DODGE_8,
+ SFX_BFOST_DODGE_9,
+ SFX_BFOST_DODGE_10,
+ SFX_BFOST_DODGE_11,
+ SFX_BFOST_GENERIC_CRASH_1,
+ SFX_BFOST_GENERIC_CRASH_2,
+ SFX_BFOST_GENERIC_CRASH_3,
+ SFX_BFOST_GENERIC_CRASH_4,
+ SFX_BFOST_GENERIC_CRASH_5,
+ SFX_BFOST_GENERIC_CRASH_6,
+ SFX_BFOST_GENERIC_CRASH_7,
+ SFX_BFOST_GENERIC_CRASH_8,
+ SFX_BFOST_GUN_PANIC_1,
+ SFX_BFOST_GUN_PANIC_2,
+ SFX_BFOST_GUN_PANIC_3,
+ SFX_BFOST_GUN_PANIC_4,
+ SFX_BFOST_GUN_PANIC_5,
+ SFX_BFOST_JACKED_1,
+ SFX_BFOST_JACKED_2,
+ SFX_BFOST_JACKED_3,
+ SFX_BFOST_JACKED_4,
+ SFX_BFOST_JACKED_5,
+ SFX_BFOST_JACKED_6,
+ SFX_BFOST_JACKED_7,
+ SFX_BFOST_JACKED_8,
+ SFX_BFOST_LOST_1,
+ SFX_BFOST_LOST_2,
+ SFX_BFOST_MUGGED_1,
+ SFX_BFOST_MUGGED_2,
+ SFX_BFOST_RUN_1,
+ SFX_BFOST_RUN_2,
+ SFX_BFOST_RUN_3,
+ SFX_BFOST_RUN_4,
+ SFX_BFOST_SAVED_1,
+ SFX_BFOST_SAVED_2,
+ SFX_BFOST_TAXI_1,
+ SFX_BFORI_BLOCKED_1,
+ SFX_BFORI_BLOCKED_2,
+ SFX_BFORI_BLOCKED_3,
+ SFX_BFORI_BLOCKED_4,
+ SFX_BFORI_BLOCKED_5,
+ SFX_BFORI_BLOCKED_6,
+ SFX_BFORI_BLOCKED_7,
+ SFX_BFORI_BLOCKED_8,
+ SFX_BFORI_BUMP_1,
+ SFX_BFORI_BUMP_2,
+ SFX_BFORI_BUMP_3,
+ SFX_BFORI_BUMP_4,
+ SFX_BFORI_BUMP_5,
+ SFX_BFORI_BUMP_6,
+ SFX_BFORI_BUMP_7,
+ SFX_BFORI_BUMP_8,
+ SFX_BFORI_BUMP_9,
+ SFX_BFORI_CAR_CRASH_1,
+ SFX_BFORI_CAR_CRASH_2,
+ SFX_BFORI_CAR_CRASH_3,
+ SFX_BFORI_CAR_CRASH_4,
+ SFX_BFORI_CAR_CRASH_5,
+ SFX_BFORI_CAR_CRASH_6,
+ SFX_BFORI_CAR_CRASH_7,
+ SFX_BFORI_DODGE_1,
+ SFX_BFORI_DODGE_2,
+ SFX_BFORI_DODGE_3,
+ SFX_BFORI_DODGE_4,
+ SFX_BFORI_DODGE_5,
+ SFX_BFORI_DODGE_6,
+ SFX_BFORI_DODGE_7,
+ SFX_BFORI_DODGE_8,
+ SFX_BFORI_DODGE_9,
+ SFX_BFORI_GENERIC_CRASH_1,
+ SFX_BFORI_GENERIC_CRASH_2,
+ SFX_BFORI_GENERIC_CRASH_3,
+ SFX_BFORI_GENERIC_CRASH_4,
+ SFX_BFORI_GENERIC_CRASH_5,
+ SFX_BFORI_GENERIC_CRASH_6,
+ SFX_BFORI_GENERIC_CRASH_7,
+ SFX_BFORI_GUN_PANIC_1,
+ SFX_BFORI_GUN_PANIC_2,
+ SFX_BFORI_GUN_PANIC_3,
+ SFX_BFORI_GUN_PANIC_4,
+ SFX_BFORI_GUN_PANIC_5,
+ SFX_BFORI_JACKED_1,
+ SFX_BFORI_JACKED_2,
+ SFX_BFORI_JACKED_3,
+ SFX_BFORI_JACKED_4,
+ SFX_BFORI_LOST_1,
+ SFX_BFORI_LOST_2,
+ SFX_BFORI_MUGGED_1,
+ SFX_BFORI_MUGGED_2,
+ SFX_BFORI_RUN_1,
+ SFX_BFORI_RUN_2,
+ SFX_BFORI_RUN_3,
+ SFX_BFORI_RUN_4,
+ SFX_BFORI_SAVED_1,
+ SFX_BFORI_SHOCKED_1,
+ SFX_BFORI_SHOCKED_2,
+ SFX_BFORI_TAXI_1,
+ SFX_BFORI_TAXI_2,
+
+ SFX_BFYST_BLOCKED_1,
+ SFX_BFYST_BLOCKED_2,
+ SFX_BFYST_BLOCKED_3,
+ SFX_BFYST_BLOCKED_4,
+ SFX_BFYST_BLOCKED_5,
+ SFX_BFYST_BLOCKED_6,
+ SFX_BFYST_BLOCKED_7,
+ SFX_BFYST_BLOCKED_8,
+ SFX_BFYST_BUMP_1,
+ SFX_BFYST_BUMP_2,
+ SFX_BFYST_BUMP_3,
+ SFX_BFYST_BUMP_4,
+ SFX_BFYST_BUMP_5,
+ SFX_BFYST_BUMP_6,
+ SFX_BFYST_BUMP_7,
+ SFX_BFYST_BUMP_8,
+ SFX_BFYST_BUMP_9,
+ SFX_BFYST_CAR_CRASH_1,
+ SFX_BFYST_CAR_CRASH_2,
+ SFX_BFYST_CAR_CRASH_3,
+ SFX_BFYST_CAR_CRASH_4,
+ SFX_BFYST_CAR_CRASH_5,
+ SFX_BFYST_CAR_CRASH_6,
+ SFX_BFYST_CAR_CRASH_7,
+ SFX_BFYST_CAR_CRASH_8,
+ SFX_BFYST_CAR_CRASH_9,
+ SFX_BFYST_CHAT_1,
+ SFX_BFYST_CHAT_2,
+ SFX_BFYST_CHAT_3,
+ SFX_BFYST_CHAT_4,
+ SFX_BFYST_CHAT_5,
+ SFX_BFYST_CHAT_6,
+ SFX_BFYST_CHAT_7,
+ SFX_BFYST_CHAT_8,
+ SFX_BFYST_CHAT_9,
+ SFX_BFYST_DODGE_1,
+ SFX_BFYST_DODGE_2,
+ SFX_BFYST_DODGE_3,
+ SFX_BFYST_DODGE_4,
+ SFX_BFYST_DODGE_5,
+ SFX_BFYST_DODGE_6,
+ SFX_BFYST_DODGE_7,
+ SFX_BFYST_DODGE_8,
+ SFX_BFYST_DODGE_9,
+ SFX_BFYST_GENERIC_CRASH_1,
+ SFX_BFYST_GENERIC_CRASH_2,
+ SFX_BFYST_GENERIC_CRASH_3,
+ SFX_BFYST_GENERIC_CRASH_4,
+ SFX_BFYST_GENERIC_CRASH_5,
+ SFX_BFYST_GENERIC_CRASH_6,
+ SFX_BFYST_GENERIC_CRASH_7,
+ SFX_BFYST_GENERIC_CRASH_8,
+ SFX_BFYST_GUN_PANIC_1,
+ SFX_BFYST_GUN_PANIC_2,
+ SFX_BFYST_GUN_PANIC_3,
+ SFX_BFYST_GUN_PANIC_4,
+ SFX_BFYST_JACKED_1,
+ SFX_BFYST_JACKED_2,
+ SFX_BFYST_JACKED_3,
+ SFX_BFYST_JACKED_4,
+ SFX_BFYST_JACKED_5,
+ SFX_BFYST_LOST_1,
+ SFX_BFYST_LOST_2,
+ SFX_BFYST_MUGGED_1,
+ SFX_BFYST_MUGGED_2,
+ SFX_BFYST_RUN_1,
+ SFX_BFYST_RUN_2,
+ SFX_BFYST_RUN_3,
+ SFX_BFYST_RUN_4,
+ SFX_BFYST_RUN_5,
+ SFX_BFYST_RUN_6,
+ SFX_BFYST_SAVED_1,
+ SFX_BFYST_SAVED_2,
+ SFX_BFYST_TAXI_1,
+
+ SFX_HFORI_BLOCKED_1,
+ SFX_HFORI_BLOCKED_2,
+ SFX_HFORI_BLOCKED_3,
+ SFX_HFORI_BLOCKED_4,
+ SFX_HFORI_BLOCKED_5,
+ SFX_HFORI_BLOCKED_6,
+ SFX_HFORI_BUMP_1,
+ SFX_HFORI_BUMP_2,
+ SFX_HFORI_BUMP_3,
+ SFX_HFORI_BUMP_4,
+ SFX_HFORI_BUMP_5,
+ SFX_HFORI_BUMP_6,
+ SFX_HFORI_BUMP_7,
+ SFX_HFORI_BUMP_8,
+ SFX_HFORI_BUMP_9,
+ SFX_HFORI_BUMP_10,
+ SFX_HFORI_CAR_CRASH_1,
+ SFX_HFORI_CAR_CRASH_2,
+ SFX_HFORI_CAR_CRASH_3,
+ SFX_HFORI_CAR_CRASH_4,
+ SFX_HFORI_CAR_CRASH_5,
+ SFX_HFORI_CAR_CRASH_6,
+ SFX_HFORI_CAR_CRASH_7,
+ SFX_HFORI_DODGE_1,
+ SFX_HFORI_DODGE_2,
+ SFX_HFORI_DODGE_3,
+ SFX_HFORI_DODGE_4,
+ SFX_HFORI_DODGE_5,
+ SFX_HFORI_DODGE_6,
+ SFX_HFORI_EYEING_1,
+ SFX_HFORI_EYEING_2,
+ SFX_HFORI_GENERIC_CRASH_1,
+ SFX_HFORI_GENERIC_CRASH_2,
+ SFX_HFORI_GENERIC_CRASH_3,
+ SFX_HFORI_GENERIC_CRASH_4,
+ SFX_HFORI_GENERIC_CRASH_5,
+ SFX_HFORI_GENERIC_CRASH_6,
+ SFX_HFORI_GENERIC_CRASH_7,
+ SFX_HFORI_GUN_PANIC_1,
+ SFX_HFORI_GUN_PANIC_2,
+ SFX_HFORI_GUN_PANIC_3,
+ SFX_HFORI_GUN_PANIC_4,
+ SFX_HFORI_GUN_PANIC_5,
+ SFX_HFORI_GUN_PANIC_6,
+ SFX_HFORI_JACKED_1,
+ SFX_HFORI_JACKED_2,
+ SFX_HFORI_JACKED_3,
+ SFX_HFORI_JACKED_4,
+ SFX_HFORI_JACKED_5,
+ SFX_HFORI_JACKED_6,
+ SFX_HFORI_JACKED_7,
+ SFX_HFORI_JACKED_8,
+ SFX_HFORI_JACKED_9,
+ SFX_HFORI_LOST_1,
+ SFX_HFORI_LOST_2,
+ SFX_HFORI_MUGGED_1,
+ SFX_HFORI_MUGGED_2,
+ SFX_HFORI_RUN_1,
+ SFX_HFORI_RUN_2,
+ SFX_HFORI_RUN_3,
+ SFX_HFORI_RUN_4,
+ SFX_HFORI_SAVED_1,
+ SFX_HFORI_SHOCKED_1,
+ SFX_HFORI_SHOCKED_2,
+ SFX_HFORI_TAXI_1,
+
+ SFX_WFYBU_BUMP_1,
+ SFX_WFYBU_BUMP_2,
+ SFX_WFYBU_BUMP_3,
+ SFX_WFYBU_BUMP_4,
+ SFX_WFYBU_BUMP_5,
+ SFX_WFYBU_BUMP_6,
+ SFX_WFYBU_BUMP_7,
+ SFX_WFYBU_BUMP_8,
+ SFX_WFYBU_BUMP_9,
+ SFX_WFYBU_BUMP_10,
+ SFX_WFYBU_BUMP_11,
+ SFX_WFYBU_BUMP_12,
+ SFX_WFYBU_BUMP_13,
+ SFX_WFYBU_BUMP_14,
+ SFX_WFYBU_BUMP_15,
+ SFX_WFYBU_BUMP_16,
+ SFX_WFYBU_BUMP_17,
+ SFX_WFYBU_BUMP_18,
+ SFX_WFYBU_BUMP_19,
+ SFX_WFYBU_BUMP_20,
+ SFX_WFYBU_BUMP_21,
+ SFX_WFYBU_CAR_CRASH_1,
+ SFX_WFYBU_CAR_CRASH_2,
+ SFX_WFYBU_CAR_CRASH_3,
+ SFX_WFYBU_CAR_CRASH_4,
+ SFX_WFYBU_CAR_CRASH_5,
+ SFX_WFYBU_CAR_CRASH_6,
+ SFX_WFYBU_CAR_CRASH_7,
+ SFX_WFYBU_CAR_CRASH_8,
+ SFX_WFYBU_CAR_CRASH_9,
+ SFX_WFYBU_GENERIC_CRASH_1,
+ SFX_WFYBU_GENERIC_CRASH_2,
+ SFX_WFYBU_GENERIC_CRASH_3,
+ SFX_WFYBU_GENERIC_CRASH_4,
+ SFX_WFYBU_GENERIC_CRASH_5,
+ SFX_WFYBU_GENERIC_CRASH_6,
+ SFX_WFYBU_GENERIC_CRASH_7,
+ SFX_WFYBU_GENERIC_CRASH_8,
+ SFX_WFYBU_GUN_PANIC_1,
+ SFX_WFYBU_GUN_PANIC_2,
+ SFX_WFYBU_GUN_PANIC_3,
+ SFX_WFYBU_GUN_PANIC_4,
+ SFX_WFYBU_GUN_PANIC_5,
+ SFX_WFYBU_GUN_PANIC_6,
+ SFX_WFYBU_GUN_PANIC_7,
+ SFX_WFYBU_GUN_PANIC_8,
+ SFX_WFYBU_JACKED_1,
+ SFX_WFYBU_JACKED_2,
+ SFX_WFYBU_JACKED_3,
+ SFX_WFYBU_JACKED_4,
+ SFX_WFYBU_JACKED_5,
+ SFX_WFYBU_JACKED_6,
+ SFX_WFYBU_JACKED_7,
+ SFX_WFYBU_JACKED_8,
+ SFX_WFYBU_MUGGED_1,
+ SFX_WFYBU_MUGGED_2,
+ SFX_WFYBU_MUGGED_3,
+ SFX_WFYBU_MUGGED_4,
+ SFX_WFYBU_RUN_1,
+ SFX_WFYBU_RUN_2,
+ SFX_WFYBU_RUN_3,
+ SFX_WFYBU_RUN_4,
+ SFX_WFYBU_RUN_5,
+ SFX_WFYBU_RUN_6,
+ SFX_WFYBU_RUN_7,
+ SFX_WFYBU_RUN_8,
+ SFX_WFYBU_SHOCKED_1,
+ SFX_WFYBU_SHOCKED_2,
+ SFX_WFYBU_SHOCKED_3,
+ SFX_WFYBU_TAXI_1,
+ SFX_WFYBU_TAXI_2,
+
+ SFX_WFOTR_BUMP_1,
+ SFX_WFOTR_BUMP_2,
+ SFX_WFOTR_BUMP_3,
+ SFX_WFOTR_BUMP_4,
+ SFX_WFOTR_BUMP_5,
+ SFX_WFOTR_BUMP_6,
+ SFX_WFOTR_BUMP_7,
+ SFX_WFOTR_BUMP_8,
+ SFX_WFOTR_BUMP_9,
+ SFX_WFOTR_BUMP_10,
+ SFX_WFOTR_BUMP_11,
+ SFX_WFOTR_CHAT_1,
+ SFX_WFOTR_CHAT_2,
+ SFX_WFOTR_CHAT_3,
+ SFX_WFOTR_CHAT_4,
+ SFX_WFOTR_CHAT_5,
+ SFX_WFOTR_CHAT_6,
+ SFX_WFOTR_CHAT_7,
+ SFX_WFOTR_CHAT_8,
+ SFX_WFOTR_CHAT_9,
+ SFX_WFOTR_DODGE_1,
+ SFX_WFOTR_DODGE_2,
+ SFX_WFOTR_DODGE_3,
+ SFX_WFOTR_DODGE_4,
+ SFX_WFOTR_DODGE_5,
+ SFX_WFOTR_DODGE_6,
+ SFX_WFOTR_DODGE_7,
+ SFX_WFOTR_DODGE_8,
+ SFX_WFOTR_DODGE_9,
+ SFX_WFOTR_GUN_COOL_1,
+ SFX_WFOTR_GUN_COOL_2,
+ SFX_WFOTR_GUN_COOL_3,
+ SFX_WFOTR_GUN_COOL_4,
+ SFX_WFOTR_GUN_COOL_5,
+ SFX_WFOTR_GUN_COOL_6,
+ SFX_WFOTR_RUN_1,
+ SFX_WFOTR_RUN_2,
+ SFX_WFOTR_RUN_3,
+ SFX_WFOTR_RUN_4,
+ SFX_WFOTR_RUN_5,
+ SFX_WFOTR_RUN_6,
+ SFX_WFOTR_SAVED_1,
+ SFX_WFOTR_SOLICIT_1,
+ SFX_WFOTR_SOLICIT_2,
+ SFX_WFOTR_SOLICIT_3,
+ SFX_WFOTR_SOLICIT_4,
+ SFX_WFOTR_SOLICIT_5,
+ SFX_WFOTR_SOLICIT_6,
+ SFX_WFOTR_SOLICIT_7,
+ SFX_WFOTR_SOLICIT_8,
+ SFX_WFOTR_SOLICIT_9,
+ SFX_WFOTR_TAXI_1,
+
+ SFX_WFYJG_BUMP_1,
+ SFX_WFYJG_BUMP_2,
+ SFX_WFYJG_BUMP_3,
+ SFX_WFYJG_BUMP_4,
+ SFX_WFYJG_BUMP_5,
+ SFX_WFYJG_BUMP_6,
+ SFX_WFYJG_BUMP_7,
+ SFX_WFYJG_BUMP_8,
+ SFX_WFYJG_BUMP_9,
+ SFX_WFYJG_BUMP_10,
+ SFX_WFYJG_BUMP_11,
+ SFX_WFYJG_BUMP_12,
+ SFX_WFYJG_DODGE_1,
+ SFX_WFYJG_DODGE_2,
+ SFX_WFYJG_DODGE_3,
+ SFX_WFYJG_DODGE_4,
+ SFX_WFYJG_DODGE_5,
+ SFX_WFYJG_DODGE_6,
+ SFX_WFYJG_DODGE_7,
+ SFX_WFYJG_DODGE_8,
+ SFX_WFYJG_GUN_PANIC_1,
+ SFX_WFYJG_GUN_PANIC_2,
+ SFX_WFYJG_GUN_PANIC_3,
+ SFX_WFYJG_GUN_PANIC_4,
+ SFX_WFYJG_RUN_1,
+ SFX_WFYJG_RUN_2,
+ SFX_WFYJG_RUN_3,
+ SFX_WFYJG_RUN_4,
+ SFX_WFYJG_RUN_5,
+ SFX_WFYJG_RUN_6,
+ SFX_WFYJG_SAVED_1,
+ SFX_WFYJG_TAXI_1,
+
+ SFX_WFYSH_BUMP_1,
+ SFX_WFYSH_BUMP_2,
+ SFX_WFYSH_BUMP_3,
+ SFX_WFYSH_BUMP_4,
+ SFX_WFYSH_BUMP_5,
+ SFX_WFYSH_BUMP_6,
+ SFX_WFYSH_BUMP_7,
+ SFX_WFYSH_BUMP_8,
+ SFX_WFYSH_BUMP_9,
+ SFX_WFYSH_BUMP_10,
+ SFX_WFYSH_BUMP_11,
+ SFX_WFYSH_BUMP_12,
+ SFX_WFYSH_CHAT_1,
+ SFX_WFYSH_CHAT_2,
+ SFX_WFYSH_CHAT_3,
+ SFX_WFYSH_CHAT_4,
+ SFX_WFYSH_CHAT_5,
+ SFX_WFYSH_CHAT_6,
+ SFX_WFYSH_CHAT_7,
+ SFX_WFYSH_CHAT_8,
+ SFX_WFYSH_CHAT_9,
+ SFX_WFYSH_CHAT_10,
+ SFX_WFYSH_DODGE_1,
+ SFX_WFYSH_DODGE_2,
+ SFX_WFYSH_DODGE_3,
+ SFX_WFYSH_DODGE_4,
+ SFX_WFYSH_DODGE_5,
+ SFX_WFYSH_DODGE_6,
+ SFX_WFYSH_DODGE_7,
+ SFX_WFYSH_DODGE_8,
+ SFX_WFYSH_DODGE_9,
+ SFX_WFYSH_DODGE_10,
+ SFX_WFYSH_DODGE_11,
+ SFX_WFYSH_GUN_COOL_1,
+ SFX_WFYSH_GUN_COOL_2,
+ SFX_WFYSH_GUN_COOL_3,
+ SFX_WFYSH_GUN_COOL_4,
+ SFX_WFYSH_GUN_COOL_5,
+ SFX_WFYSH_GUN_COOL_6,
+ SFX_WFYSH_GUN_COOL_7,
+ SFX_WFYSH_GUN_COOL_8,
+ SFX_WFYSH_GUN_COOL_9,
+ SFX_WFYSH_LOST_1,
+ SFX_WFYSH_LOST_2,
+ SFX_WFYSH_MUGGED_1,
+ SFX_WFYSH_MUGGED_2,
+ SFX_WFYSH_RUN_1,
+ SFX_WFYSH_RUN_2,
+ SFX_WFYSH_RUN_3,
+ SFX_WFYSH_RUN_4,
+ SFX_WFYSH_RUN_5,
+ SFX_WFYSH_RUN_6,
+ SFX_WFYSH_RUN_7,
+ SFX_WFYSH_RUN_8,
+ SFX_WFYSH_RUN_9,
+ SFX_WFYSH_RUN_10,
+ SFX_WFYSH_RUN_11,
+ SFX_WFYSH_SAVED_1,
+ SFX_WFYSH_SAVED_2,
+ SFX_WFYSH_SAVED_3,
+ SFX_WFYSH_SAVED_4,
+ SFX_WFYSH_SHOCKED_1,
+ SFX_WFYSH_SHOCKED_2,
+ SFX_WFYSH_SHOCKED_3,
+ SFX_WFYSH_SHOCKED_4,
+ SFX_WFYSH_SHOCKED_5,
+ SFX_WFYSH_TAXI_1,
+ SFX_WFYSH_TAXI_2,
+
+ SFX_WMOTR_BUMP_1,
+ SFX_WMOTR_BUMP_2,
+ SFX_WMOTR_BUMP_3,
+ SFX_WMOTR_BUMP_4,
+ SFX_WMOTR_BUMP_5,
+ SFX_WMOTR_BUMP_6,
+ SFX_WMOTR_BUMP_7,
+ SFX_WMOTR_BUMP_8,
+ SFX_WMOTR_BUMP_9,
+ SFX_WMOTR_BUMP_10,
+ SFX_WMOTR_CHAT_1,
+ SFX_WMOTR_CHAT_2,
+ SFX_WMOTR_CHAT_3,
+ SFX_WMOTR_CHAT_4,
+ SFX_WMOTR_CHAT_5,
+ SFX_WMOTR_CHAT_6,
+ SFX_WMOTR_CHAT_7,
+ SFX_WMOTR_CHAT_8,
+ SFX_WMOTR_CHAT_9,
+ SFX_WMOTR_CHAT_10,
+ SFX_WMOTR_CHAT_11,
+ SFX_WMOTR_CHAT_12,
+ SFX_WMOTR_CHAT_13,
+ SFX_WMOTR_DODGE_1,
+ SFX_WMOTR_DODGE_2,
+ SFX_WMOTR_DODGE_3,
+ SFX_WMOTR_DODGE_4,
+ SFX_WMOTR_DODGE_5,
+ SFX_WMOTR_DODGE_6,
+ SFX_WMOTR_DODGE_7,
+ SFX_WMOTR_DODGE_8,
+ SFX_WMOTR_DODGE_9,
+ SFX_WMOTR_DODGE_10,
+ SFX_WMOTR_DODGE_11,
+ SFX_WMOTR_DODGE_12,
+ SFX_WMOTR_DODGE_13,
+ SFX_WMOTR_DODGE_14,
+ SFX_WMOTR_DODGE_15,
+ SFX_WMOTR_DODGE_16,
+ SFX_WMOTR_DODGE_17,
+ SFX_WMOTR_EYEING_1,
+ SFX_WMOTR_EYEING_2,
+ SFX_WMOTR_FIGHT_1,
+ SFX_WMOTR_FIGHT_2,
+ SFX_WMOTR_FIGHT_3,
+ SFX_WMOTR_FIGHT_4,
+ SFX_WMOTR_FIGHT_5,
+ SFX_WMOTR_FIGHT_6,
+ SFX_WMOTR_GUN_COOL_1,
+ SFX_WMOTR_GUN_COOL_2,
+ SFX_WMOTR_GUN_COOL_3,
+ SFX_WMOTR_GUN_COOL_4,
+ SFX_WMOTR_GUN_COOL_5,
+ SFX_WMOTR_SAVED_1,
+ SFX_WMOTR_SHOCKED_1,
+ SFX_WMOTR_SHOCKED_2,
+ SFX_WMOTR_SHOCKED_3,
+ SFX_WMOTR_SOLICIT_1,
+ SFX_WMOTR_SOLICIT_2,
+ SFX_WMOTR_SOLICIT_3,
+ SFX_WMOTR_SOLICIT_4,
+ SFX_WMOTR_SOLICIT_5,
+ SFX_WMOTR_SOLICIT_6,
+ SFX_WMOTR_SOLICIT_7,
+ SFX_WMOTR_TAXI_1,
+
+ SFX_BMOBE_BUMP_1,
+ SFX_BMOBE_BUMP_2,
+ SFX_BMOBE_BUMP_3,
+ SFX_BMOBE_BUMP_4,
+ SFX_BMOBE_BUMP_5,
+ SFX_BMOBE_CAR_CRASH_1,
+ SFX_BMOBE_CAR_CRASH_2,
+ SFX_BMOBE_CAR_CRASH_3,
+ SFX_BMOBE_CAR_CRASH_4,
+ SFX_BMOBE_CAR_CRASH_5,
+ SFX_BMOBE_CAR_CRASH_6,
+ SFX_BMOBE_CAR_CRASH_7,
+ SFX_BMOBE_CAR_CRASH_8,
+ SFX_BMOBE_CAR_CRASH_9,
+ SFX_BMOBE_CHAT_1,
+ SFX_BMOBE_CHAT_2,
+ SFX_BMOBE_CHAT_3,
+ SFX_BMOBE_CHAT_4,
+ SFX_BMOBE_CHAT_5,
+ SFX_BMOBE_CHAT_6,
+ SFX_BMOBE_CHAT_7,
+ SFX_BMOBE_CHAT_8,
+ SFX_BMOBE_CHAT_9,
+ SFX_BMOBE_CHAT_10,
+ SFX_BMOBE_DODGE_1,
+ SFX_BMOBE_DODGE_2,
+ SFX_BMOBE_DODGE_3,
+ SFX_BMOBE_DODGE_4,
+ SFX_BMOBE_DODGE_5,
+ SFX_BMOBE_DODGE_6,
+ SFX_BMOBE_DODGE_7,
+ SFX_BMOBE_DODGE_8,
+ SFX_BMOBE_DODGE_9,
+ SFX_BMOBE_DODGE_10,
+ SFX_BMOBE_DODGE_11,
+ SFX_BMOBE_FIGHT_1,
+ SFX_BMOBE_FIGHT_2,
+ SFX_BMOBE_FIGHT_3,
+ SFX_BMOBE_FIGHT_4,
+ SFX_BMOBE_FIGHT_5,
+ SFX_BMOBE_FIGHT_6,
+ SFX_BMOBE_FIGHT_7,
+ SFX_BMOBE_FIGHT_8,
+ SFX_BMOBE_FIGHT_9,
+ SFX_BMOBE_FIGHT_10,
+ SFX_BMOBE_GENERIC_CRASH_1,
+ SFX_BMOBE_GENERIC_CRASH_2,
+ SFX_BMOBE_GENERIC_CRASH_3,
+ SFX_BMOBE_GENERIC_CRASH_4,
+ SFX_BMOBE_GENERIC_CRASH_5,
+ SFX_BMOBE_GENERIC_CRASH_6,
+ SFX_BMOBE_GENERIC_CRASH_7,
+ SFX_BMOBE_GUN_PANIC_1,
+ SFX_BMOBE_GUN_PANIC_2,
+ SFX_BMOBE_GUN_PANIC_3,
+ SFX_BMOBE_GUN_PANIC_4,
+ SFX_BMOBE_GUN_PANIC_5,
+ SFX_BMOBE_JACKED_1,
+ SFX_BMOBE_JACKED_2,
+ SFX_BMOBE_JACKED_3,
+ SFX_BMOBE_JACKED_4,
+ SFX_BMOBE_JACKED_5,
+ SFX_BMOBE_JACKED_6,
+ SFX_BMOBE_MUGGED_1,
+ SFX_BMOBE_MUGGED_2,
+ SFX_BMOBE_MUGGED_3,
+ SFX_BMOBE_MUGGED_4,
+ SFX_BMOBE_SAVED_1,
+ SFX_BMOBE_SAVED_2,
+ SFX_BMOBE_SAVED_3,
+ SFX_BMOBE_SHOCKED_1,
+ SFX_BMOBE_SHOCKED_2,
+ SFX_BMOBE_SHOCKED_3,
+ SFX_BMOBE_TAXI_1,
+
+ SFX_WMYGO_BUMP_1,
+ SFX_WMYGO_BUMP_2,
+ SFX_WMYGO_BUMP_3,
+ SFX_WMYGO_BUMP_4,
+ SFX_WMYGO_BUMP_5,
+ SFX_WMYGO_BUMP_6,
+ SFX_WMYGO_BUMP_7,
+ SFX_WMYGO_BUMP_8,
+ SFX_WMYGO_BUMP_9,
+ SFX_WMYGO_CAR_CRASH_1,
+ SFX_WMYGO_CAR_CRASH_2,
+ SFX_WMYGO_CAR_CRASH_3,
+ SFX_WMYGO_CAR_CRASH_4,
+ SFX_WMYGO_CAR_CRASH_5,
+ SFX_WMYGO_CAR_CRASH_6,
+ SFX_WMYGO_CAR_CRASH_7,
+ SFX_WMYGO_CHAT_1,
+ SFX_WMYGO_CHAT_2,
+ SFX_WMYGO_CHAT_3,
+ SFX_WMYGO_CHAT_4,
+ SFX_WMYGO_CHAT_5,
+ SFX_WMYGO_CHAT_6,
+ SFX_WMYGO_CHAT_7,
+ SFX_WMYGO_CHAT_8,
+ SFX_WMYGO_CHAT_9,
+ SFX_WMYGO_CHAT_10,
+ SFX_WMYGO_DODGE_1,
+ SFX_WMYGO_DODGE_2,
+ SFX_WMYGO_DODGE_3,
+ SFX_WMYGO_DODGE_4,
+ SFX_WMYGO_DODGE_5,
+ SFX_WMYGO_DODGE_6,
+ SFX_WMYGO_DODGE_7,
+ SFX_WMYGO_DODGE_8,
+ SFX_WMYGO_DODGE_9,
+ SFX_WMYGO_DODGE_10,
+ SFX_WMYGO_DODGE_11,
+ SFX_WMYGO_EYEING_1,
+ SFX_WMYGO_EYEING_2,
+ SFX_WMYGO_GENERIC_CRASH_1,
+ SFX_WMYGO_GENERIC_CRASH_2,
+ SFX_WMYGO_GENERIC_CRASH_3,
+ SFX_WMYGO_GENERIC_CRASH_4,
+ SFX_WMYGO_GENERIC_CRASH_5,
+ SFX_WMYGO_GENERIC_CRASH_6,
+ SFX_WMYGO_GENERIC_CRASH_7,
+ SFX_WMYGO_GUN_PANIC_1,
+ SFX_WMYGO_GUN_PANIC_2,
+ SFX_WMYGO_GUN_PANIC_3,
+ SFX_WMYGO_GUN_PANIC_4,
+ SFX_WMYGO_GUN_PANIC_5,
+ SFX_WMYGO_JACKED_1,
+ SFX_WMYGO_JACKED_2,
+ SFX_WMYGO_JACKED_3,
+ SFX_WMYGO_JACKED_4,
+ SFX_WMYGO_JACKED_5,
+ SFX_WMYGO_JACKED_6,
+ SFX_WMYGO_MUGGED_1,
+ SFX_WMYGO_MUGGED_2,
+ SFX_WMYGO_RUN_1,
+ SFX_WMYGO_RUN_2,
+ SFX_WMYGO_RUN_3,
+ SFX_WMYGO_RUN_4,
+ SFX_WMYGO_RUN_5,
+ SFX_WMYGO_RUN_6,
+ SFX_WMYGO_SAVED_1,
+ SFX_WMYGO_SHOCKED_1,
+ SFX_WMYGO_SHOCKED_2,
+ SFX_WMYGO_TAXI_1,
+ SFX_WMYGO_TAXI_2,
+ SFX_WMYGO_TAXI_3,
+
+ SFX_WFYBE_BLOCKED_1,
+ SFX_WFYBE_BLOCKED_2,
+ SFX_WFYBE_BLOCKED_3,
+ SFX_WFYBE_BLOCKED_4,
+ SFX_WFYBE_BLOCKED_5,
+ SFX_WFYBE_BLOCKED_6,
+ SFX_WFYBE_BLOCKED_7,
+ SFX_WFYBE_BUMP_1,
+ SFX_WFYBE_BUMP_2,
+ SFX_WFYBE_BUMP_3,
+ SFX_WFYBE_BUMP_4,
+ SFX_WFYBE_BUMP_5,
+ SFX_WFYBE_BUMP_6,
+ SFX_WFYBE_BUMP_7,
+ SFX_WFYBE_BUMP_8,
+ SFX_WFYBE_BUMP_9,
+ SFX_WFYBE_BUMP_10,
+ SFX_WFYBE_BUMP_11,
+ SFX_WFYBE_CAR_CRASH_1,
+ SFX_WFYBE_CAR_CRASH_2,
+ SFX_WFYBE_CAR_CRASH_3,
+ SFX_WFYBE_CAR_CRASH_4,
+ SFX_WFYBE_CAR_CRASH_5,
+ SFX_WFYBE_CAR_CRASH_6,
+ SFX_WFYBE_CHAT_1,
+ SFX_WFYBE_CHAT_2,
+ SFX_WFYBE_CHAT_3,
+ SFX_WFYBE_CHAT_4,
+ SFX_WFYBE_CHAT_5,
+ SFX_WFYBE_CHAT_6,
+ SFX_WFYBE_CHAT_7,
+ SFX_WFYBE_CHAT_8,
+ SFX_WFYBE_CHAT_9,
+ SFX_WFYBE_CHAT_10,
+ SFX_WFYBE_DODGE_1,
+ SFX_WFYBE_DODGE_2,
+ SFX_WFYBE_DODGE_3,
+ SFX_WFYBE_DODGE_4,
+ SFX_WFYBE_DODGE_5,
+ SFX_WFYBE_DODGE_6,
+ SFX_WFYBE_DODGE_7,
+ SFX_WFYBE_DODGE_8,
+ SFX_WFYBE_GENERIC_CRASH_1,
+ SFX_WFYBE_GENERIC_CRASH_2,
+ SFX_WFYBE_GENERIC_CRASH_3,
+ SFX_WFYBE_GENERIC_CRASH_4,
+ SFX_WFYBE_GENERIC_CRASH_5,
+ SFX_WFYBE_GENERIC_CRASH_6,
+ SFX_WFYBE_GUN_PANIC_1,
+ SFX_WFYBE_GUN_PANIC_2,
+ SFX_WFYBE_GUN_PANIC_3,
+ SFX_WFYBE_GUN_PANIC_4,
+ SFX_WFYBE_GUN_PANIC_5,
+ SFX_WFYBE_JACKED_1,
+ SFX_WFYBE_JACKED_2,
+ SFX_WFYBE_JACKED_3,
+ SFX_WFYBE_JACKED_4,
+ SFX_WFYBE_RUN_1,
+ SFX_WFYBE_RUN_2,
+ SFX_WFYBE_RUN_3,
+ SFX_WFYBE_RUN_4,
+ SFX_WFYBE_RUN_5,
+ SFX_WFYBE_SAVED_1,
+ SFX_WFYBE_SHOCKED_1,
+ SFX_WFYBE_SHOCKED_2,
+ SFX_WFYBE_SHOCKED_3,
+ SFX_WFYBE_TAXI_1,
+
+ SFX_WFORI_BLOCKED_1,
+ SFX_WFORI_BLOCKED_2,
+ SFX_WFORI_BLOCKED_3,
+ SFX_WFORI_BLOCKED_4,
+ SFX_WFORI_BLOCKED_5,
+ SFX_WFORI_BLOCKED_6,
+ SFX_WFORI_BLOCKED_7,
+ SFX_WFORI_BUMP_1,
+ SFX_WFORI_BUMP_2,
+ SFX_WFORI_BUMP_3,
+ SFX_WFORI_BUMP_4,
+ SFX_WFORI_BUMP_5,
+ SFX_WFORI_BUMP_6,
+ SFX_WFORI_BUMP_7,
+ SFX_WFORI_BUMP_8,
+ SFX_WFORI_BUMP_9,
+ SFX_WFORI_BUMP_10,
+ SFX_WFORI_BUMP_11,
+ SFX_WFORI_CAR_CRASH_1,
+ SFX_WFORI_CAR_CRASH_2,
+ SFX_WFORI_CAR_CRASH_3,
+ SFX_WFORI_CAR_CRASH_4,
+ SFX_WFORI_CAR_CRASH_5,
+ SFX_WFORI_CAR_CRASH_6,
+ SFX_WFORI_CAR_CRASH_7,
+ SFX_WFORI_CAR_CRASH_8,
+ SFX_WFORI_CAR_CRASH_9,
+ SFX_WFORI_CAR_CRASH_10,
+ SFX_WFORI_DODGE_1,
+ SFX_WFORI_DODGE_2,
+ SFX_WFORI_DODGE_3,
+ SFX_WFORI_DODGE_4,
+ SFX_WFORI_DODGE_5,
+ SFX_WFORI_DODGE_6,
+ SFX_WFORI_DODGE_7,
+ SFX_WFORI_DODGE_8,
+ SFX_WFORI_DODGE_9,
+ SFX_WFORI_DODGE_10,
+ SFX_WFORI_DODGE_11,
+ SFX_WFORI_FIGHT_1,
+ SFX_WFORI_FIGHT_2,
+ SFX_WFORI_FIGHT_3,
+ SFX_WFORI_FIGHT_4,
+ SFX_WFORI_FIGHT_5,
+ SFX_WFORI_FIGHT_6,
+ SFX_WFORI_FIGHT_7,
+ SFX_WFORI_GENERIC_CRASH_1,
+ SFX_WFORI_GENERIC_CRASH_2,
+ SFX_WFORI_GENERIC_CRASH_3,
+ SFX_WFORI_GENERIC_CRASH_4,
+ SFX_WFORI_GENERIC_CRASH_5,
+ SFX_WFORI_GENERIC_CRASH_6,
+ SFX_WFORI_GENERIC_CRASH_7,
+ SFX_WFORI_GENERIC_CRASH_8,
+ SFX_WFORI_GUN_PANIC_1,
+ SFX_WFORI_GUN_PANIC_2,
+ SFX_WFORI_GUN_PANIC_3,
+ SFX_WFORI_GUN_PANIC_4,
+ SFX_WFORI_GUN_PANIC_5,
+ SFX_WFORI_GUN_PANIC_6,
+ SFX_WFORI_JACKED_1,
+ SFX_WFORI_JACKED_2,
+ SFX_WFORI_JACKED_3,
+ SFX_WFORI_JACKED_4,
+ SFX_WFORI_JACKED_5,
+ SFX_WFORI_JACKED_6,
+ SFX_WFORI_LOST_1,
+ SFX_WFORI_LOST_2,
+ SFX_WFORI_MUGGED_1,
+ SFX_WFORI_MUGGED_2,
+ SFX_WFORI_MUGGED_3,
+ SFX_WFORI_SAVED_1,
+ SFX_WFORI_SHOCKED_1,
+ SFX_WFORI_SHOCKED_2,
+ SFX_WFORI_SHOCKED_3,
+ SFX_WFORI_TAXI_1,
+
+ SFX_WFOGO_BUMP_1,
+ SFX_WFOGO_BUMP_2,
+ SFX_WFOGO_BUMP_3,
+ SFX_WFOGO_BUMP_4,
+ SFX_WFOGO_BUMP_5,
+ SFX_WFOGO_BUMP_6,
+ SFX_WFOGO_BUMP_7,
+ SFX_WFOGO_BUMP_8,
+ SFX_WFOGO_CAR_CRASH_1,
+ SFX_WFOGO_CAR_CRASH_2,
+ SFX_WFOGO_CAR_CRASH_3,
+ SFX_WFOGO_CAR_CRASH_4,
+ SFX_WFOGO_CAR_CRASH_5,
+ SFX_WFOGO_CAR_CRASH_6,
+ SFX_WFOGO_CAR_CRASH_7,
+ SFX_WFOGO_CAR_CRASH_8,
+ SFX_WFOGO_CHAT_1,
+ SFX_WFOGO_CHAT_2,
+ SFX_WFOGO_CHAT_3,
+ SFX_WFOGO_CHAT_4,
+ SFX_WFOGO_CHAT_5,
+ SFX_WFOGO_CHAT_6,
+ SFX_WFOGO_CHAT_7,
+ SFX_WFOGO_CHAT_8,
+ SFX_WFOGO_CHAT_9,
+ SFX_WFOGO_CHAT_10,
+ SFX_WFOGO_CHAT_11,
+ SFX_WFOGO_DODGE_1,
+ SFX_WFOGO_DODGE_2,
+ SFX_WFOGO_DODGE_3,
+ SFX_WFOGO_DODGE_4,
+ SFX_WFOGO_DODGE_5,
+ SFX_WFOGO_DODGE_6,
+ SFX_WFOGO_DODGE_7,
+ SFX_WFOGO_DODGE_8,
+ SFX_WFOGO_DODGE_9,
+ SFX_WFOGO_FIGHT_1,
+ SFX_WFOGO_FIGHT_2,
+ SFX_WFOGO_FIGHT_3,
+ SFX_WFOGO_FIGHT_4,
+ SFX_WFOGO_FIGHT_5,
+ SFX_WFOGO_FIGHT_6,
+ SFX_WFOGO_FIGHT_7,
+ SFX_WFOGO_FIGHT_8,
+ SFX_WFOGO_FIGHT_9,
+ SFX_WFOGO_FIGHT_10,
+ SFX_WFOGO_FIGHT_11,
+ SFX_WFOGO_FIGHT_12,
+ SFX_WFOGO_FIGHT_13,
+ SFX_WFOGO_FIGHT_14,
+ SFX_WFOGO_GENERIC_CRASH_1,
+ SFX_WFOGO_GENERIC_CRASH_2,
+ SFX_WFOGO_GENERIC_CRASH_3,
+ SFX_WFOGO_GENERIC_CRASH_4,
+ SFX_WFOGO_GENERIC_CRASH_5,
+ SFX_WFOGO_GENERIC_CRASH_6,
+ SFX_WFOGO_GENERIC_CRASH_7,
+ SFX_WFOGO_GUN_PANIC_1,
+ SFX_WFOGO_GUN_PANIC_2,
+ SFX_WFOGO_GUN_PANIC_3,
+ SFX_WFOGO_GUN_PANIC_4,
+ SFX_WFOGO_GUN_PANIC_5,
+ SFX_WFOGO_JACKED_1,
+ SFX_WFOGO_JACKED_2,
+ SFX_WFOGO_JACKED_3,
+ SFX_WFOGO_JACKED_4,
+ SFX_WFOGO_JACKED_5,
+ SFX_WFOGO_JACKED_6,
+ SFX_WFOGO_MUGGED_1,
+ SFX_WFOGO_MUGGED_2,
+ SFX_WFOGO_RUN_1,
+ SFX_WFOGO_RUN_2,
+ SFX_WFOGO_SAVED_1,
+ SFX_WFOGO_SHOCKED_1,
+ SFX_WFOGO_SHOCKED_2,
+
+ SFX_HMYST_BUMP_1,
+ SFX_HMYST_BUMP_2,
+ SFX_HMYST_BUMP_3,
+ SFX_HMYST_BUMP_4,
+ SFX_HMYST_BUMP_5,
+ SFX_HMYST_BUMP_6,
+ SFX_HMYST_BUMP_7,
+ SFX_HMYST_BUMP_8,
+ SFX_HMYST_BUMP_9,
+ SFX_HMYST_BUMP_10,
+ SFX_HMYST_BUMP_11,
+ SFX_HMYST_BUMP_12,
+ SFX_HMYST_BUMP_13,
+ SFX_HMYST_CHAT_1,
+ SFX_HMYST_CHAT_2,
+ SFX_HMYST_CHAT_3,
+ SFX_HMYST_CHAT_4,
+ SFX_HMYST_CHAT_5,
+ SFX_HMYST_CHAT_6,
+ SFX_HMYST_CHAT_7,
+ SFX_HMYST_CHAT_8,
+ SFX_HMYST_CHAT_9,
+ SFX_HMYST_CHAT_10,
+ SFX_HMYST_CHAT_11,
+ SFX_HMYST_DODGE_1,
+ SFX_HMYST_DODGE_2,
+ SFX_HMYST_DODGE_3,
+ SFX_HMYST_DODGE_4,
+ SFX_HMYST_DODGE_5,
+ SFX_HMYST_DODGE_6,
+ SFX_HMYST_EYEING_1,
+ SFX_HMYST_EYEING_2,
+ SFX_HMYST_GENERIC_CRASH_1,
+ SFX_HMYST_GENERIC_CRASH_2,
+ SFX_HMYST_GENERIC_CRASH_3,
+ SFX_HMYST_GENERIC_CRASH_4,
+ SFX_HMYST_GENERIC_CRASH_5,
+ SFX_HMYST_GENERIC_CRASH_6,
+ SFX_HMYST_GENERIC_CRASH_7,
+ SFX_HMYST_GUN_PANIC_1,
+ SFX_HMYST_GUN_PANIC_2,
+ SFX_HMYST_GUN_PANIC_3,
+ SFX_HMYST_GUN_PANIC_4,
+ SFX_HMYST_GUN_PANIC_5,
+ SFX_HMYST_GUN_PANIC_6,
+ SFX_HMYST_RUN_1,
+ SFX_HMYST_RUN_2,
+ SFX_HMYST_RUN_3,
+ SFX_HMYST_RUN_4,
+ SFX_HMYST_SAVED_1,
+ SFX_HMYST_SHOCKED_1,
+ SFX_HMYST_SHOCKED_2,
+ SFX_HMYST_TAXI_1,
+
+ SFX_WMOCA_BLOCKED_1,
+ SFX_WMOCA_BLOCKED_2,
+ SFX_WMOCA_BLOCKED_3,
+ SFX_WMOCA_BLOCKED_4,
+ SFX_WMOCA_BLOCKED_5,
+ SFX_WMOCA_BLOCKED_6,
+ SFX_WMOCA_BLOCKED_7,
+ SFX_WMOCA_BLOCKED_8,
+ SFX_WMOCA_BLOCKED_9,
+ SFX_WMOCA_BLOCKED_10,
+ SFX_WMOCA_BLOCKED_11,
+ SFX_WMOCA_BLOCKED_12,
+ SFX_WMOCA_BUMP_1,
+ SFX_WMOCA_BUMP_2,
+ SFX_WMOCA_BUMP_3,
+ SFX_WMOCA_BUMP_4,
+ SFX_WMOCA_BUMP_5,
+ SFX_WMOCA_BUMP_6,
+ SFX_WMOCA_CAR_CRASH_1,
+ SFX_WMOCA_CAR_CRASH_2,
+ SFX_WMOCA_CAR_CRASH_3,
+ SFX_WMOCA_CAR_CRASH_4,
+ SFX_WMOCA_CAR_CRASH_5,
+ SFX_WMOCA_CAR_CRASH_6,
+ SFX_WMOCA_CAR_CRASH_7,
+ SFX_WMOCA_CAR_CRASH_8,
+ SFX_WMOCA_CAR_CRASH_9,
+ SFX_WMOCA_CAR_CRASH_10,
+ SFX_WMOCA_DODGE_1,
+ SFX_WMOCA_DODGE_2,
+ SFX_WMOCA_DODGE_3,
+ SFX_WMOCA_DODGE_4,
+ SFX_WMOCA_DODGE_5,
+ SFX_WMOCA_DODGE_6,
+ SFX_WMOCA_DODGE_7,
+ SFX_WMOCA_DODGE_8,
+ SFX_WMOCA_DODGE_9,
+ SFX_WMOCA_DODGE_10,
+ SFX_WMOCA_EYEING_1,
+ SFX_WMOCA_EYEING_2,
+ SFX_WMOCA_FIGHT_1,
+ SFX_WMOCA_FIGHT_2,
+ SFX_WMOCA_FIGHT_3,
+ SFX_WMOCA_FIGHT_4,
+ SFX_WMOCA_FIGHT_5,
+ SFX_WMOCA_FIGHT_6,
+ SFX_WMOCA_FIGHT_7,
+ SFX_WMOCA_FIGHT_8,
+ SFX_WMOCA_GENERIC_CRASH_1,
+ SFX_WMOCA_GENERIC_CRASH_2,
+ SFX_WMOCA_GENERIC_CRASH_3,
+ SFX_WMOCA_GENERIC_CRASH_4,
+ SFX_WMOCA_GENERIC_CRASH_5,
+ SFX_WMOCA_GENERIC_CRASH_6,
+ SFX_WMOCA_GENERIC_CRASH_7,
+ SFX_WMOCA_GENERIC_CRASH_8,
+ SFX_WMOCA_GENERIC_CRASH_9,
+ SFX_WMOCA_GUN_PANIC_1,
+ SFX_WMOCA_GUN_PANIC_2,
+ SFX_WMOCA_GUN_PANIC_3,
+ SFX_WMOCA_GUN_PANIC_4,
+ SFX_WMOCA_GUN_PANIC_5,
+ SFX_WMOCA_GUN_PANIC_6,
+ SFX_WMOCA_JACKED_1,
+ SFX_WMOCA_JACKED_2,
+ SFX_WMOCA_JACKED_3,
+ SFX_WMOCA_JACKED_4,
+ SFX_WMOCA_JACKED_5,
+ SFX_WMOCA_JACKED_6,
+ SFX_WMOCA_JACKED_7,
+ SFX_WMOCA_JACKED_8,
+ SFX_WMOCA_JACKED_9,
+ SFX_WMOCA_JACKED_10,
+ SFX_WMOCA_JACKING_1,
+ SFX_WMOCA_JACKING_2,
+ SFX_WMOCA_JACKING_3,
+ SFX_WMOCA_JACKING_4,
+ SFX_WMOCA_JACKING_5,
+ SFX_WMOCA_JACKING_6,
+ SFX_WMOCA_JACKING_7,
+ SFX_WMOCA_JACKING_8,
+ SFX_WMOCA_JACKING_9,
+ SFX_WMOCA_JACKING_10,
+ SFX_WMOCA_JACKING_11,
+ SFX_WMOCA_MUGGED_1,
+ SFX_WMOCA_MUGGED_2,
+ SFX_WMOCA_SAVED_1,
+ SFX_WMOCA_TAXI_1,
+
+ SFX_WMYBE_BLOCKED_1,
+ SFX_WMYBE_BLOCKED_2,
+ SFX_WMYBE_BLOCKED_3,
+ SFX_WMYBE_BLOCKED_4,
+ SFX_WMYBE_BLOCKED_5,
+ SFX_WMYBE_BLOCKED_6,
+ SFX_WMYBE_BLOCKED_7,
+ SFX_WMYBE_BLOCKED_8,
+ SFX_WMYBE_BLOCKED_9,
+ SFX_WMYBE_BUMP_1,
+ SFX_WMYBE_BUMP_2,
+ SFX_WMYBE_BUMP_3,
+ SFX_WMYBE_BUMP_4,
+ SFX_WMYBE_BUMP_5,
+ SFX_WMYBE_BUMP_6,
+ SFX_WMYBE_BUMP_7,
+ SFX_WMYBE_BUMP_8,
+ SFX_WMYBE_BUMP_9,
+ SFX_WMYBE_BUMP_10,
+ SFX_WMYBE_BUMP_11,
+ SFX_WMYBE_BUMP_12,
+ SFX_WMYBE_BUMP_13,
+ SFX_WMYBE_BUMP_14,
+ SFX_WMYBE_CAR_CRASH_1,
+ SFX_WMYBE_CAR_CRASH_2,
+ SFX_WMYBE_CAR_CRASH_3,
+ SFX_WMYBE_CAR_CRASH_4,
+ SFX_WMYBE_CAR_CRASH_5,
+ SFX_WMYBE_CAR_CRASH_6,
+ SFX_WMYBE_CAR_CRASH_7,
+ SFX_WMYBE_CAR_CRASH_8,
+ SFX_WMYBE_CHAT_1,
+ SFX_WMYBE_CHAT_2,
+ SFX_WMYBE_CHAT_3,
+ SFX_WMYBE_CHAT_4,
+ SFX_WMYBE_CHAT_5,
+ SFX_WMYBE_CHAT_6,
+ SFX_WMYBE_CHAT_7,
+ SFX_WMYBE_CHAT_8,
+ SFX_WMYBE_CHAT_9,
+ SFX_WMYBE_CHAT_10,
+ SFX_WMYBE_CHAT_11,
+ SFX_WMYBE_DODGE_1,
+ SFX_WMYBE_DODGE_2,
+ SFX_WMYBE_DODGE_3,
+ SFX_WMYBE_DODGE_4,
+ SFX_WMYBE_DODGE_5,
+ SFX_WMYBE_DODGE_6,
+ SFX_WMYBE_DODGE_7,
+ SFX_WMYBE_DODGE_8,
+ SFX_WMYBE_DODGE_9,
+ SFX_WMYBE_DODGE_10,
+ SFX_WMYBE_DODGE_11,
+ SFX_WMYBE_DODGE_12,
+ SFX_WMYBE_EYEING_1,
+ SFX_WMYBE_EYEING_2,
+ SFX_WMYBE_GENERIC_CRASH_1,
+ SFX_WMYBE_GENERIC_CRASH_2,
+ SFX_WMYBE_GENERIC_CRASH_3,
+ SFX_WMYBE_GENERIC_CRASH_4,
+ SFX_WMYBE_GENERIC_CRASH_5,
+ SFX_WMYBE_GENERIC_CRASH_6,
+ SFX_WMYBE_GENERIC_CRASH_7,
+ SFX_WMYBE_GENERIC_CRASH_8,
+ SFX_WMYBE_GUN_PANIC_1,
+ SFX_WMYBE_GUN_PANIC_2,
+ SFX_WMYBE_GUN_PANIC_3,
+ SFX_WMYBE_GUN_PANIC_4,
+ SFX_WMYBE_GUN_PANIC_5,
+ SFX_WMYBE_GUN_PANIC_6,
+ SFX_WMYBE_GUN_PANIC_7,
+ SFX_WMYBE_GUN_PANIC_8,
+ SFX_WMYBE_JACKED_1,
+ SFX_WMYBE_JACKED_2,
+ SFX_WMYBE_JACKED_3,
+ SFX_WMYBE_JACKED_4,
+ SFX_WMYBE_JACKED_5,
+ SFX_WMYBE_JACKED_6,
+ SFX_WMYBE_JACKED_7,
+ SFX_WMYBE_JACKING_1,
+ SFX_WMYBE_JACKING_2,
+ SFX_WMYBE_JACKING_3,
+ SFX_WMYBE_JEER_1,
+ SFX_WMYBE_JEER_2,
+ SFX_WMYBE_JEER_3,
+ SFX_WMYBE_JEER_4,
+ SFX_WMYBE_JEER_5,
+ SFX_WMYBE_JEER_6,
+ SFX_WMYBE_JEER_7,
+ SFX_WMYBE_LOST_1,
+ SFX_WMYBE_LOST_2,
+ SFX_WMYBE_LOST_3,
+ SFX_WMYBE_RUN_1,
+ SFX_WMYBE_RUN_2,
+ SFX_WMYBE_RUN_3,
+ SFX_WMYBE_RUN_4,
+ SFX_WMYBE_RUN_5,
+ SFX_WMYBE_SHOCKED_1,
+ SFX_WMYBE_SHOCKED_2,
+ SFX_WMYBE_SHOCKED_3,
+ SFX_WMYBE_SHOCKED_4,
+ SFX_WMYBE_SHOCKED_5,
+ SFX_WMYBE_SHOCKED_6,
+
+ SFX_BFOBE_BLOCKED_1,
+ SFX_BFOBE_BLOCKED_2,
+ SFX_BFOBE_BLOCKED_3,
+ SFX_BFOBE_BLOCKED_4,
+ SFX_BFOBE_BLOCKED_5,
+ SFX_BFOBE_BLOCKED_6,
+ SFX_BFOBE_BLOCKED_7,
+ SFX_BFOBE_BLOCKED_8,
+ SFX_BFOBE_BUMP_1,
+ SFX_BFOBE_BUMP_2,
+ SFX_BFOBE_BUMP_3,
+ SFX_BFOBE_BUMP_4,
+ SFX_BFOBE_BUMP_5,
+ SFX_BFOBE_BUMP_6,
+ SFX_BFOBE_BUMP_7,
+ SFX_BFOBE_BUMP_8,
+ SFX_BFOBE_CAR_CRASH_1,
+ SFX_BFOBE_CAR_CRASH_2,
+ SFX_BFOBE_CAR_CRASH_3,
+ SFX_BFOBE_CAR_CRASH_4,
+ SFX_BFOBE_CAR_CRASH_5,
+ SFX_BFOBE_CAR_CRASH_6,
+ SFX_BFOBE_CAR_CRASH_7,
+ SFX_BFOBE_CHAT_1,
+ SFX_BFOBE_CHAT_2,
+ SFX_BFOBE_CHAT_3,
+ SFX_BFOBE_CHAT_4,
+ SFX_BFOBE_CHAT_5,
+ SFX_BFOBE_CHAT_6,
+ SFX_BFOBE_CHAT_7,
+ SFX_BFOBE_CHAT_8,
+ SFX_BFOBE_DODGE_1,
+ SFX_BFOBE_DODGE_2,
+ SFX_BFOBE_DODGE_3,
+ SFX_BFOBE_DODGE_4,
+ SFX_BFOBE_DODGE_5,
+ SFX_BFOBE_DODGE_6,
+ SFX_BFOBE_DODGE_7,
+ SFX_BFOBE_DODGE_8,
+ SFX_BFOBE_DODGE_9,
+ SFX_BFOBE_GENERIC_CRASH_1,
+ SFX_BFOBE_GENERIC_CRASH_2,
+ SFX_BFOBE_GENERIC_CRASH_3,
+ SFX_BFOBE_GENERIC_CRASH_4,
+ SFX_BFOBE_GENERIC_CRASH_5,
+ SFX_BFOBE_GENERIC_CRASH_6,
+ SFX_BFOBE_GENERIC_CRASH_7,
+ SFX_BFOBE_GUN_PANIC_1,
+ SFX_BFOBE_GUN_PANIC_2,
+ SFX_BFOBE_GUN_PANIC_3,
+ SFX_BFOBE_GUN_PANIC_4,
+ SFX_BFOBE_GUN_PANIC_5,
+ SFX_BFOBE_JACKED_1,
+ SFX_BFOBE_JACKED_2,
+ SFX_BFOBE_JACKED_3,
+ SFX_BFOBE_JACKED_4,
+ SFX_BFOBE_JACKED_5,
+ SFX_BFOBE_JACKING_1,
+ SFX_BFOBE_JACKING_2,
+ SFX_BFOBE_JACKING_3,
+ SFX_BFOBE_JACKING_4,
+ SFX_BFOBE_MUGGED_1,
+ SFX_BFOBE_MUGGED_2,
+ SFX_BFOBE_SHOCKED_1,
+ SFX_BFOBE_SHOCKED_2,
+ SFX_BFOBE_TAXI_1,
+
+ SFX_WFYLG_BUMP_1,
+ SFX_WFYLG_BUMP_2,
+ SFX_WFYLG_BUMP_3,
+ SFX_WFYLG_BUMP_4,
+ SFX_WFYLG_BUMP_5,
+ SFX_WFYLG_BUMP_6,
+ SFX_WFYLG_BUMP_7,
+ SFX_WFYLG_BUMP_8,
+ SFX_WFYLG_BUMP_9,
+ SFX_WFYLG_BUMP_10,
+ SFX_WFYLG_CHAT_1,
+ SFX_WFYLG_CHAT_2,
+ SFX_WFYLG_CHAT_3,
+ SFX_WFYLG_CHAT_4,
+ SFX_WFYLG_CHAT_5,
+ SFX_WFYLG_CHAT_6,
+ SFX_WFYLG_CHAT_7,
+ SFX_WFYLG_CHAT_8,
+ SFX_WFYLG_CHAT_9,
+ SFX_WFYLG_CHAT_10,
+ SFX_WFYLG_DODGE_1,
+ SFX_WFYLG_DODGE_2,
+ SFX_WFYLG_DODGE_3,
+ SFX_WFYLG_DODGE_4,
+ SFX_WFYLG_DODGE_5,
+ SFX_WFYLG_DODGE_6,
+ SFX_WFYLG_DODGE_7,
+ SFX_WFYLG_DODGE_8,
+ SFX_WFYLG_FIGHT_1,
+ SFX_WFYLG_FIGHT_2,
+ SFX_WFYLG_FIGHT_3,
+ SFX_WFYLG_FIGHT_4,
+ SFX_WFYLG_FIGHT_5,
+ SFX_WFYLG_FIGHT_6,
+ SFX_WFYLG_FIGHT_7,
+ SFX_WFYLG_GUN_COOL_1,
+ SFX_WFYLG_GUN_COOL_2,
+ SFX_WFYLG_GUN_COOL_3,
+ SFX_WFYLG_GUN_COOL_4,
+ SFX_WFYLG_GUN_COOL_5,
+ SFX_WFYLG_SAVED_1,
+ SFX_WFYLG_TAXI_1,
+
+ SFX_WFOST_BLOCKED_1,
+ SFX_WFOST_BLOCKED_2,
+ SFX_WFOST_BLOCKED_3,
+ SFX_WFOST_BLOCKED_4,
+ SFX_WFOST_BLOCKED_5,
+ SFX_WFOST_BLOCKED_6,
+ SFX_WFOST_BLOCKED_7,
+ SFX_WFOST_BLOCKED_8,
+ SFX_WFOST_BLOCKED_9,
+ SFX_WFOST_BLOCKED_10,
+ SFX_WFOST_BLOCKED_11,
+ SFX_WFOST_BLOCKED_12,
+ SFX_WFOST_BUMP_1,
+ SFX_WFOST_BUMP_2,
+ SFX_WFOST_BUMP_3,
+ SFX_WFOST_BUMP_4,
+ SFX_WFOST_BUMP_5,
+ SFX_WFOST_BUMP_6,
+ SFX_WFOST_BUMP_7,
+ SFX_WFOST_BUMP_8,
+ SFX_WFOST_BUMP_9,
+ SFX_WFOST_BUMP_10,
+ SFX_WFOST_BUMP_11,
+ SFX_WFOST_BUMP_12,
+ SFX_WFOST_BUMP_13,
+ SFX_WFOST_BUMP_14,
+ SFX_WFOST_BUMP_15,
+ SFX_WFOST_BUMP_16,
+ SFX_WFOST_BUMP_17,
+ SFX_WFOST_BUMP_18,
+ SFX_WFOST_BUMP_19,
+ SFX_WFOST_CAR_CRASH_1,
+ SFX_WFOST_CAR_CRASH_2,
+ SFX_WFOST_CAR_CRASH_3,
+ SFX_WFOST_CAR_CRASH_4,
+ SFX_WFOST_CAR_CRASH_5,
+ SFX_WFOST_CAR_CRASH_6,
+ SFX_WFOST_CAR_CRASH_7,
+ SFX_WFOST_CAR_CRASH_8,
+ SFX_WFOST_CAR_CRASH_9,
+ SFX_WFOST_CAR_CRASH_10,
+ SFX_WFOST_CAR_CRASH_11,
+ SFX_WFOST_CHAT_1,
+ SFX_WFOST_CHAT_2,
+ SFX_WFOST_CHAT_3,
+ SFX_WFOST_CHAT_4,
+ SFX_WFOST_CHAT_5,
+ SFX_WFOST_CHAT_6,
+ SFX_WFOST_CHAT_7,
+ SFX_WFOST_CHAT_8,
+ SFX_WFOST_CHAT_9,
+ SFX_WFOST_CHAT_10,
+ SFX_WFOST_CHAT_11,
+ SFX_WFOST_CHAT_12,
+ SFX_WFOST_CHAT_13,
+ SFX_WFOST_CHAT_14,
+ SFX_WFOST_CHAT_15,
+ SFX_WFOST_CHAT_16,
+ SFX_WFOST_DODGE_1,
+ SFX_WFOST_DODGE_2,
+ SFX_WFOST_DODGE_3,
+ SFX_WFOST_DODGE_4,
+ SFX_WFOST_DODGE_5,
+ SFX_WFOST_DODGE_6,
+ SFX_WFOST_DODGE_7,
+ SFX_WFOST_DODGE_8,
+ SFX_WFOST_DODGE_9,
+ SFX_WFOST_DODGE_10,
+ SFX_WFOST_DODGE_11,
+ SFX_WFOST_DODGE_12,
+ SFX_WFOST_GENERIC_CRASH_1,
+ SFX_WFOST_GENERIC_CRASH_2,
+ SFX_WFOST_GENERIC_CRASH_3,
+ SFX_WFOST_GENERIC_CRASH_4,
+ SFX_WFOST_GENERIC_CRASH_5,
+ SFX_WFOST_GENERIC_CRASH_6,
+ SFX_WFOST_GENERIC_CRASH_7,
+ SFX_WFOST_GENERIC_CRASH_8,
+ SFX_WFOST_GENERIC_CRASH_9,
+ SFX_WFOST_GENERIC_CRASH_10,
+ SFX_WFOST_GUN_PANIC_1,
+ SFX_WFOST_GUN_PANIC_2,
+ SFX_WFOST_GUN_PANIC_3,
+ SFX_WFOST_GUN_PANIC_4,
+ SFX_WFOST_JACKED_1,
+ SFX_WFOST_JACKED_2,
+ SFX_WFOST_JACKED_3,
+ SFX_WFOST_JACKED_4,
+ SFX_WFOST_JACKED_5,
+ SFX_WFOST_JACKED_6,
+ SFX_WFOST_JACKED_7,
+ SFX_WFOST_JACKED_8,
+ SFX_WFOST_LOST_1,
+ SFX_WFOST_LOST_2,
+ SFX_WFOST_LOST_3,
+ SFX_WFOST_MUGGED_1,
+ SFX_WFOST_MUGGED_2,
+ SFX_WFOST_MUGGED_3,
+ SFX_WFOST_MUGGED_4,
+ SFX_WFOST_MUGGED_5,
+ SFX_WFOST_RUN_1,
+ SFX_WFOST_RUN_2,
+ SFX_WFOST_RUN_3,
+ SFX_WFOST_RUN_4,
+ SFX_WFOST_RUN_5,
+ SFX_WFOST_RUN_6,
+ SFX_WFOST_RUN_7,
+ SFX_WFOST_SAVED_1,
+ SFX_WFOST_SAVED_2,
+ SFX_WFOST_SAVED_3,
+ SFX_WFOST_SAVED_4,
+ SFX_WFOST_TAXI_1,
+
+ SFX_WFYST_BLOCKED_1,
+ SFX_WFYST_BLOCKED_2,
+ SFX_WFYST_BLOCKED_3,
+ SFX_WFYST_BLOCKED_4,
+ SFX_WFYST_BLOCKED_5,
+ SFX_WFYST_BLOCKED_6,
+ SFX_WFYST_BUMP_1,
+ SFX_WFYST_BUMP_2,
+ SFX_WFYST_BUMP_3,
+ SFX_WFYST_BUMP_4,
+ SFX_WFYST_BUMP_5,
+ SFX_WFYST_BUMP_6,
+ SFX_WFYST_BUMP_7,
+ SFX_WFYST_BUMP_8,
+ SFX_WFYST_BUMP_9,
+ SFX_WFYST_BUMP_10,
+ SFX_WFYST_CAR_CRASH_1,
+ SFX_WFYST_CAR_CRASH_2,
+ SFX_WFYST_CAR_CRASH_3,
+ SFX_WFYST_CAR_CRASH_4,
+ SFX_WFYST_CAR_CRASH_5,
+ SFX_WFYST_CAR_CRASH_6,
+ SFX_WFYST_CAR_CRASH_7,
+ SFX_WFYST_CAR_CRASH_8,
+ SFX_WFYST_CHAT_1,
+ SFX_WFYST_CHAT_2,
+ SFX_WFYST_CHAT_3,
+ SFX_WFYST_CHAT_4,
+ SFX_WFYST_CHAT_5,
+ SFX_WFYST_CHAT_6,
+ SFX_WFYST_CHAT_7,
+ SFX_WFYST_CHAT_8,
+ SFX_WFYST_CHAT_9,
+ SFX_WFYST_CHAT_10,
+ SFX_WFYST_DODGE_1,
+ SFX_WFYST_DODGE_2,
+ SFX_WFYST_DODGE_3,
+ SFX_WFYST_DODGE_4,
+ SFX_WFYST_DODGE_5,
+ SFX_WFYST_DODGE_6,
+ SFX_WFYST_DODGE_7,
+ SFX_WFYST_DODGE_8,
+ SFX_WFYST_DODGE_9,
+ SFX_WFYST_DODGE_10,
+ SFX_WFYST_FIGHT_1,
+ SFX_WFYST_FIGHT_2,
+ SFX_WFYST_FIGHT_3,
+ SFX_WFYST_FIGHT_4,
+ SFX_WFYST_FIGHT_5,
+ SFX_WFYST_FIGHT_6,
+ SFX_WFYST_FIGHT_7,
+ SFX_WFYST_GENERIC_CRASH_1,
+ SFX_WFYST_GENERIC_CRASH_2,
+ SFX_WFYST_GENERIC_CRASH_3,
+ SFX_WFYST_GENERIC_CRASH_4,
+ SFX_WFYST_GENERIC_CRASH_5,
+ SFX_WFYST_GENERIC_CRASH_6,
+ SFX_WFYST_GENERIC_CRASH_7,
+ SFX_WFYST_GENERIC_CRASH_8,
+ SFX_WFYST_GUN_COOL_1,
+ SFX_WFYST_GUN_COOL_2,
+ SFX_WFYST_GUN_COOL_3,
+ SFX_WFYST_GUN_COOL_4,
+ SFX_WFYST_GUN_COOL_5,
+ SFX_WFYST_JACKED_1,
+ SFX_WFYST_JACKED_2,
+ SFX_WFYST_JACKED_3,
+ SFX_WFYST_JACKED_4,
+ SFX_WFYST_JACKED_5,
+ SFX_WFYST_JACKED_6,
+ SFX_WFYST_JACKING_1,
+ SFX_WFYST_JACKING_2,
+ SFX_WFYST_JACKING_3,
+ SFX_WFYST_JACKING_4,
+ SFX_WFYST_LOST_1,
+ SFX_WFYST_MUGGED_1,
+ SFX_WFYST_MUGGED_2,
+ SFX_WFYST_MUGGING_1,
+ SFX_WFYST_MUGGING_2,
+ SFX_WFYST_MUGGING_3,
+ SFX_WFYST_MUGGING_4,
+ SFX_WFYST_SAVED_1,
+ SFX_WFYST_TAXI_1,
+
+ SFX_COP_VOICE_1_ARREST_1,
+ SFX_COP_VOICE_1_ARREST_2,
+ SFX_COP_VOICE_1_ARREST_3,
+ SFX_COP_VOICE_1_ARREST_4,
+ SFX_COP_VOICE_1_PULLOUTWEAPON_1,
+ SFX_COP_VOICE_1_PULLOUTWEAPON_2,
+ SFX_COP_VOICE_1_PULLOUTWEAPON_3,
+ SFX_COP_VOICE_1_BUMP_1,
+ SFX_COP_VOICE_1_BUMP_2,
+ SFX_COP_VOICE_1_BUMP_3,
+ SFX_COP_VOICE_1_BUMP_4,
+ SFX_COP_VOICE_1_BUMP_5,
+ SFX_COP_VOICE_1_COP_LITTLECOPSAROUND_1,
+ SFX_COP_VOICE_1_COP_LITTLECOPSAROUND_2,
+ SFX_COP_VOICE_1_COP_LITTLECOPSAROUND_3,
+ SFX_COP_VOICE_1_COP_LITTLECOPSAROUND_4,
+ SFX_COP_VOICE_1_GUNAIMEDAT3_1,
+ SFX_COP_VOICE_1_GUNAIMEDAT3_2,
+ SFX_COP_VOICE_1_CAR_CRASH_1,
+ SFX_COP_VOICE_1_CAR_CRASH_2,
+ SFX_COP_VOICE_1_CAR_CRASH_3,
+ SFX_COP_VOICE_1_CAR_CRASH_4,
+ SFX_COP_VOICE_1_DODGE_1,
+ SFX_COP_VOICE_1_DODGE_2,
+ SFX_COP_VOICE_1_DODGE_3,
+ SFX_COP_VOICE_1_FIGHT_1,
+ SFX_COP_VOICE_1_FIGHT_2,
+ SFX_COP_VOICE_1_FIGHT_3,
+ SFX_COP_VOICE_1_FIGHT_4,
+ SFX_COP_VOICE_1_GUNAIMEDAT2_1,
+ SFX_COP_VOICE_1_GUNAIMEDAT2_2,
+ SFX_COP_VOICE_1_SAVED_1,
+ SFX_COP_VOICE_1_SAVED_2,
+ SFX_COP_VOICE_1_COP_ASK_FOR_ID_1,
+ SFX_COP_VOICE_1_COP_ASK_FOR_ID_2,
+ SFX_COP_VOICE_1_COP_ALONE_1,
+ SFX_COP_VOICE_1_COP_ALONE_2,
+ SFX_COP_VOICE_1_COP_ALONE_3,
+ SFX_COP_VOICE_1_COP_ALONE_4,
+ SFX_COP_VOICE_1_COP_MANYCOPSAROUND_1,
+ SFX_COP_VOICE_1_COP_MANYCOPSAROUND_2,
+ SFX_COP_VOICE_1_COP_TARGETING_1,
+ SFX_COP_VOICE_1_COP_TARGETING_2,
+ SFX_COP_VOICE_1_COP_TARGETING_3,
+ SFX_COP_VOICE_1_COP_TARGETING_4,
+
+ SFX_COP_VOICE_2_ARREST_1,
+ SFX_COP_VOICE_2_ARREST_2,
+ SFX_COP_VOICE_2_ARREST_3,
+ SFX_COP_VOICE_2_ARREST_4,
+ SFX_COP_VOICE_2_PULLOUTWEAPON_1,
+ SFX_COP_VOICE_2_PULLOUTWEAPON_2,
+ SFX_COP_VOICE_2_PULLOUTWEAPON_3,
+ SFX_COP_VOICE_2_BUMP_1,
+ SFX_COP_VOICE_2_BUMP_2,
+ SFX_COP_VOICE_2_BUMP_3,
+ SFX_COP_VOICE_2_BUMP_4,
+ SFX_COP_VOICE_2_BUMP_5,
+ SFX_COP_VOICE_2_COP_LITTLECOPSAROUND_1,
+ SFX_COP_VOICE_2_COP_LITTLECOPSAROUND_2,
+ SFX_COP_VOICE_2_COP_LITTLECOPSAROUND_3,
+ SFX_COP_VOICE_2_COP_LITTLECOPSAROUND_4,
+ SFX_COP_VOICE_2_GUNAIMEDAT3_1,
+ SFX_COP_VOICE_2_GUNAIMEDAT3_2,
+ SFX_COP_VOICE_2_CAR_CRASH_1,
+ SFX_COP_VOICE_2_CAR_CRASH_2,
+ SFX_COP_VOICE_2_CAR_CRASH_3,
+ SFX_COP_VOICE_2_CAR_CRASH_4,
+ SFX_COP_VOICE_2_DODGE_1,
+ SFX_COP_VOICE_2_DODGE_2,
+ SFX_COP_VOICE_2_DODGE_3,
+ SFX_COP_VOICE_2_FIGHT_1,
+ SFX_COP_VOICE_2_FIGHT_2,
+ SFX_COP_VOICE_2_FIGHT_3,
+ SFX_COP_VOICE_2_FIGHT_4,
+ SFX_COP_VOICE_2_GUNAIMEDAT2_1,
+ SFX_COP_VOICE_2_GUNAIMEDAT2_2,
+ SFX_COP_VOICE_2_SAVED_1,
+ SFX_COP_VOICE_2_SAVED_2,
+ SFX_COP_VOICE_2_COP_ASK_FOR_ID_1,
+ SFX_COP_VOICE_2_COP_ASK_FOR_ID_2,
+ SFX_COP_VOICE_2_COP_ALONE_1,
+ SFX_COP_VOICE_2_COP_ALONE_2,
+ SFX_COP_VOICE_2_COP_ALONE_3,
+ SFX_COP_VOICE_2_COP_ALONE_4,
+ SFX_COP_VOICE_2_COP_MANYCOPSAROUND_1,
+ SFX_COP_VOICE_2_COP_MANYCOPSAROUND_2,
+ SFX_COP_VOICE_2_COP_TARGETING_1,
+ SFX_COP_VOICE_2_COP_TARGETING_2,
+ SFX_COP_VOICE_2_COP_TARGETING_3,
+ SFX_COP_VOICE_2_COP_TARGETING_4,
+
+ SFX_COP_VOICE_3_ARREST_1,
+ SFX_COP_VOICE_3_ARREST_2,
+ SFX_COP_VOICE_3_ARREST_3,
+ SFX_COP_VOICE_3_ARREST_4,
+ SFX_COP_VOICE_3_PULLOUTWEAPON_1,
+ SFX_COP_VOICE_3_PULLOUTWEAPON_2,
+ SFX_COP_VOICE_3_PULLOUTWEAPON_3,
+ SFX_COP_VOICE_3_BUMP_1,
+ SFX_COP_VOICE_3_BUMP_2,
+ SFX_COP_VOICE_3_BUMP_3,
+ SFX_COP_VOICE_3_BUMP_4,
+ SFX_COP_VOICE_3_BUMP_5,
+ SFX_COP_VOICE_3_COP_LITTLECOPSAROUND_1,
+ SFX_COP_VOICE_3_COP_LITTLECOPSAROUND_2,
+ SFX_COP_VOICE_3_COP_LITTLECOPSAROUND_3,
+ SFX_COP_VOICE_3_COP_LITTLECOPSAROUND_4,
+ SFX_COP_VOICE_3_GUNAIMEDAT3_1,
+ SFX_COP_VOICE_3_GUNAIMEDAT3_2,
+ SFX_COP_VOICE_3_CAR_CRASH_1,
+ SFX_COP_VOICE_3_CAR_CRASH_2,
+ SFX_COP_VOICE_3_CAR_CRASH_3,
+ SFX_COP_VOICE_3_CAR_CRASH_4,
+ SFX_COP_VOICE_3_DODGE_1,
+ SFX_COP_VOICE_3_DODGE_2,
+ SFX_COP_VOICE_3_DODGE_3,
+ SFX_COP_VOICE_3_FIGHT_1,
+ SFX_COP_VOICE_3_FIGHT_2,
+ SFX_COP_VOICE_3_FIGHT_3,
+ SFX_COP_VOICE_3_FIGHT_4,
+ SFX_COP_VOICE_3_GUNAIMEDAT2_1,
+ SFX_COP_VOICE_3_GUNAIMEDAT2_2,
+ SFX_COP_VOICE_3_SAVED_1,
+ SFX_COP_VOICE_3_SAVED_2,
+ SFX_COP_VOICE_3_COP_ASK_FOR_ID_1,
+ SFX_COP_VOICE_3_COP_ASK_FOR_ID_2,
+ SFX_COP_VOICE_3_COP_ALONE_1,
+ SFX_COP_VOICE_3_COP_ALONE_2,
+ SFX_COP_VOICE_3_COP_ALONE_3,
+ SFX_COP_VOICE_3_COP_ALONE_4,
+ SFX_COP_VOICE_3_COP_MANYCOPSAROUND_1,
+ SFX_COP_VOICE_3_COP_MANYCOPSAROUND_2,
+ SFX_COP_VOICE_3_COP_TARGETING_1,
+ SFX_COP_VOICE_3_COP_TARGETING_2,
+ SFX_COP_VOICE_3_COP_TARGETING_3,
+ SFX_COP_VOICE_3_COP_TARGETING_4,
+
+ SFX_COP_VOICE_4_ARREST_1,
+ SFX_COP_VOICE_4_ARREST_2,
+ SFX_COP_VOICE_4_ARREST_3,
+ SFX_COP_VOICE_4_ARREST_4,
+ SFX_COP_VOICE_4_PULLOUTWEAPON_1,
+ SFX_COP_VOICE_4_PULLOUTWEAPON_2,
+ SFX_COP_VOICE_4_PULLOUTWEAPON_3,
+ SFX_COP_VOICE_4_BUMP_1,
+ SFX_COP_VOICE_4_BUMP_2,
+ SFX_COP_VOICE_4_BUMP_3,
+ SFX_COP_VOICE_4_BUMP_4,
+ SFX_COP_VOICE_4_BUMP_5,
+ SFX_COP_VOICE_4_COP_LITTLECOPSAROUND_1,
+ SFX_COP_VOICE_4_COP_LITTLECOPSAROUND_2,
+ SFX_COP_VOICE_4_COP_LITTLECOPSAROUND_3,
+ SFX_COP_VOICE_4_COP_LITTLECOPSAROUND_4,
+ SFX_COP_VOICE_4_GUNAIMEDAT3_1,
+ SFX_COP_VOICE_4_GUNAIMEDAT3_2,
+ SFX_COP_VOICE_4_CAR_CRASH_1,
+ SFX_COP_VOICE_4_CAR_CRASH_2,
+ SFX_COP_VOICE_4_CAR_CRASH_3,
+ SFX_COP_VOICE_4_CAR_CRASH_4,
+ SFX_COP_VOICE_4_DODGE_1,
+ SFX_COP_VOICE_4_DODGE_2,
+ SFX_COP_VOICE_4_DODGE_3,
+ SFX_COP_VOICE_4_FIGHT_1,
+ SFX_COP_VOICE_4_FIGHT_2,
+ SFX_COP_VOICE_4_FIGHT_3,
+ SFX_COP_VOICE_4_FIGHT_4,
+ SFX_COP_VOICE_4_GUNAIMEDAT2_1,
+ SFX_COP_VOICE_4_GUNAIMEDAT2_2,
+ SFX_COP_VOICE_4_SAVED_1,
+ SFX_COP_VOICE_4_SAVED_2,
+ SFX_COP_VOICE_4_COP_ASK_FOR_ID_1,
+ SFX_COP_VOICE_4_COP_ASK_FOR_ID_2,
+ SFX_COP_VOICE_4_COP_ALONE_1,
+ SFX_COP_VOICE_4_COP_ALONE_2,
+ SFX_COP_VOICE_4_COP_ALONE_3,
+ SFX_COP_VOICE_4_COP_ALONE_4,
+ SFX_COP_VOICE_4_COP_MANYCOPSAROUND_1,
+ SFX_COP_VOICE_4_COP_MANYCOPSAROUND_2,
+ SFX_COP_VOICE_4_COP_TARGETING_1,
+ SFX_COP_VOICE_4_COP_TARGETING_2,
+ SFX_COP_VOICE_4_COP_TARGETING_3,
+ SFX_COP_VOICE_4_COP_TARGETING_4,
+
+ SFX_COP_VOICE_5_ARREST_1,
+ SFX_COP_VOICE_5_ARREST_2,
+ SFX_COP_VOICE_5_ARREST_3,
+ SFX_COP_VOICE_5_ARREST_4,
+ SFX_COP_VOICE_5_PULLOUTWEAPON_1,
+ SFX_COP_VOICE_5_PULLOUTWEAPON_2,
+ SFX_COP_VOICE_5_PULLOUTWEAPON_3,
+ SFX_COP_VOICE_5_BUMP_1,
+ SFX_COP_VOICE_5_BUMP_2,
+ SFX_COP_VOICE_5_BUMP_3,
+ SFX_COP_VOICE_5_BUMP_4,
+ SFX_COP_VOICE_5_BUMP_5,
+ SFX_COP_VOICE_5_COP_LITTLECOPSAROUND_1,
+ SFX_COP_VOICE_5_COP_LITTLECOPSAROUND_2,
+ SFX_COP_VOICE_5_COP_LITTLECOPSAROUND_3,
+ SFX_COP_VOICE_5_COP_LITTLECOPSAROUND_4,
+ SFX_COP_VOICE_5_GUNAIMEDAT3_1,
+ SFX_COP_VOICE_5_GUNAIMEDAT3_2,
+ SFX_COP_VOICE_5_CAR_CRASH_1,
+ SFX_COP_VOICE_5_CAR_CRASH_2,
+ SFX_COP_VOICE_5_CAR_CRASH_3,
+ SFX_COP_VOICE_5_CAR_CRASH_4,
+ SFX_COP_VOICE_5_DODGE_1,
+ SFX_COP_VOICE_5_DODGE_2,
+ SFX_COP_VOICE_5_DODGE_3,
+ SFX_COP_VOICE_5_FIGHT_1,
+ SFX_COP_VOICE_5_FIGHT_2,
+ SFX_COP_VOICE_5_FIGHT_3,
+ SFX_COP_VOICE_5_FIGHT_4,
+ SFX_COP_VOICE_5_GUNAIMEDAT2_1,
+ SFX_COP_VOICE_5_GUNAIMEDAT2_2,
+ SFX_COP_VOICE_5_SAVED_1,
+ SFX_COP_VOICE_5_SAVED_2,
+ SFX_COP_VOICE_5_COP_ASK_FOR_ID_1,
+ SFX_COP_VOICE_5_COP_ASK_FOR_ID_2,
+ SFX_COP_VOICE_5_COP_ALONE_1,
+ SFX_COP_VOICE_5_COP_ALONE_2,
+ SFX_COP_VOICE_5_COP_ALONE_3,
+ SFX_COP_VOICE_5_COP_ALONE_4,
+ SFX_COP_VOICE_5_COP_MANYCOPSAROUND_1,
+ SFX_COP_VOICE_5_COP_MANYCOPSAROUND_2,
+ SFX_COP_VOICE_5_COP_TARGETING_1,
+ SFX_COP_VOICE_5_COP_TARGETING_2,
+ SFX_COP_VOICE_5_COP_TARGETING_3,
+ SFX_COP_VOICE_5_COP_TARGETING_4,
+
+ SFX_PLAYER_ANGRY_BUSTED_1,
+ SFX_PLAYER_ANGRY_BUSTED_2,
+ SFX_PLAYER_ANGRY_BUSTED_3,
+ SFX_PLAYER_ANGRY_BUSTED_4,
+ SFX_PLAYER_ANGRY_BUSTED_5,
+ SFX_PLAYER_ANGRY_BUSTED_6,
+ SFX_PLAYER_ANGRY_BUSTED_7,
+ SFX_PLAYER_ANGRY_BUSTED_8,
+ SFX_PLAYER_ANGRY_BUSTED_9,
+ SFX_PLAYER_ANGRY_BUSTED_10,
+ SFX_PLAYER_ANGRY_BUSTED_11,
+ SFX_PLAYER_ANGRY_BUSTED_12,
+ SFX_PLAYER_ANGRY_BUSTED_13,
+ SFX_PLAYER_ANGRY_BUSTED_14,
+ SFX_PLAYER_ANGRY_BUSTED_15,
+ SFX_PLAYER_ANGRY_BUSTED_16,
+ SFX_PLAYER_ANGRY_BUSTED_17,
+ SFX_PLAYER_ANGRY_BUSTED_18,
+ SFX_PLAYER_ANGRY_BUSTED_19,
+ SFX_PLAYER_ANGRY_BUSTED_20,
+ SFX_PLAYER_ANGRY_BUSTED_21,
+ SFX_PLAYER_ANGRY_BUSTED_22,
+ SFX_PLAYER_ANGRY_BUSTED_23,
+ SFX_PLAYER_ANGRY_BUSTED_24,
+ SFX_PLAYER_ANGRY_BUSTED_25,
+ SFX_PLAYER_ANGRY_BUSTED_26,
+ SFX_PLAYER_ANGRY_BUSTED_27,
+ SFX_PLAYER_ANGRY_BUSTED_28,
+ SFX_PLAYER_ANGRY_BUSTED_29,
+ SFX_PLAYER_ANGRY_BUSTED_30,
+ SFX_PLAYER_ANGRY_BUSTED_31,
+ SFX_PLAYER_ANGRY_BUSTED_32,
+ SFX_PLAYER_ANGRY_BUSTED_33,
+ SFX_PLAYER_ANGRY_BUSTED_34,
+ SFX_PLAYER_ANGRY_BUSTED_35,
+ SFX_PLAYER_ANGRY_BUSTED_36,
+ SFX_PLAYER_ANGRY_BUSTED_37,
+ SFX_PLAYER_ANGRY_BUSTED_38,
+ SFX_PLAYER_ANGRY_CHASED_1,
+ SFX_PLAYER_ANGRY_CHASED_2,
+ SFX_PLAYER_ANGRY_CHASED_3,
+ SFX_PLAYER_ANGRY_CHASED_4,
+ SFX_PLAYER_ANGRY_CHASED_5,
+ SFX_PLAYER_ANGRY_CHASED_6,
+ SFX_PLAYER_ANGRY_CHASED_7,
+ SFX_PLAYER_ANGRY_CHASED_8,
+ SFX_PLAYER_ANGRY_CHASED_9,
+ SFX_PLAYER_ANGRY_CRASH_1,
+ SFX_PLAYER_ANGRY_CRASH_2,
+ SFX_PLAYER_ANGRY_CRASH_3,
+ SFX_PLAYER_ANGRY_CRASH_4,
+ SFX_PLAYER_ANGRY_CRASH_5,
+ SFX_PLAYER_ANGRY_CRASH_6,
+ SFX_PLAYER_ANGRY_CRASH_7,
+ SFX_PLAYER_ANGRY_CRASH_8,
+ SFX_PLAYER_ANGRY_CRASH_9,
+ SFX_PLAYER_ANGRY_CRASH_10,
+ SFX_PLAYER_ANGRY_CRASH_11,
+ SFX_PLAYER_ANGRY_CRASH_12,
+ SFX_PLAYER_ANGRY_CRASH_13,
+ SFX_PLAYER_ANGRY_CRASH_14,
+ SFX_PLAYER_ANGRY_CRASH_15,
+ SFX_PLAYER_ANGRY_CRASH_16,
+ SFX_PLAYER_ANGRY_CRASH_17,
+ SFX_PLAYER_ANGRY_CRASH_18,
+ SFX_PLAYER_ANGRY_CRASH_19,
+ SFX_PLAYER_ANGRY_CRASH_20,
+ SFX_PLAYER_ANGRY_CRASH_21,
+ SFX_PLAYER_ANGRY_CRASH_22,
+ SFX_PLAYER_ANGRY_CRASH_23,
+ SFX_PLAYER_ANGRY_CRASH_24,
+ SFX_PLAYER_ANGRY_CRASH_25,
+ SFX_PLAYER_ANGRY_CRASH_26,
+ SFX_PLAYER_ANGRY_CRASH_27,
+ SFX_PLAYER_ANGRY_CRASH_28,
+ SFX_PLAYER_ANGRY_CRASH_29,
+ SFX_PLAYER_ANGRY_CRASH_30,
+ SFX_PLAYER_ANGRY_CRASH_31,
+ SFX_PLAYER_ANGRY_CRASH_32,
+ SFX_PLAYER_ANGRY_CRASH_33,
+ SFX_PLAYER_ANGRY_CRASH_34,
+ SFX_PLAYER_ANGRY_CRASH_35,
+ SFX_PLAYER_ANGRY_CRASH_36,
+ SFX_PLAYER_ANGRY_CRASH_37,
+ SFX_PLAYER_ANGRY_CRASH_38,
+ SFX_PLAYER_ANGRY_CRASH_39,
+ SFX_PLAYER_ANGRY_CRASH_40,
+ SFX_PLAYER_ANGRY_CRASH_41,
+ SFX_PLAYER_ANGRY_FIGHT_1,
+ SFX_PLAYER_ANGRY_FIGHT_2,
+ SFX_PLAYER_ANGRY_FIGHT_3,
+ SFX_PLAYER_ANGRY_FIGHT_4,
+ SFX_PLAYER_ANGRY_FIGHT_5,
+ SFX_PLAYER_ANGRY_FIGHT_6,
+ SFX_PLAYER_ANGRY_FIGHT_7,
+ SFX_PLAYER_ANGRY_FIGHT_8,
+ SFX_PLAYER_ANGRY_FIGHT_9,
+ SFX_PLAYER_ANGRY_FIGHT_10,
+ SFX_PLAYER_ANGRY_FIGHT_11,
+ SFX_PLAYER_ANGRY_FIGHT_12,
+ SFX_PLAYER_ANGRY_FIGHT_13,
+ SFX_PLAYER_ANGRY_FIGHT_14,
+ SFX_PLAYER_ANGRY_FIGHT_15,
+ SFX_PLAYER_ANGRY_FIGHT_16,
+ SFX_PLAYER_ANGRY_FIGHT_17,
+ SFX_PLAYER_ANGRY_FIGHT_18,
+ SFX_PLAYER_ANGRY_FIGHT_19,
+ SFX_PLAYER_ANGRY_FIGHT_20,
+ SFX_PLAYER_ANGRY_FIGHT_21,
+ SFX_PLAYER_ANGRY_FIGHT_22,
+ SFX_PLAYER_ANGRY_FIGHT_23,
+ SFX_PLAYER_ANGRY_FIGHT_24,
+ SFX_PLAYER_ANGRY_FIGHT_25,
+ SFX_PLAYER_ANGRY_FIGHT_26,
+ SFX_PLAYER_ANGRY_FIGHT_27,
+ SFX_PLAYER_ANGRY_FIGHT_28,
+ SFX_PLAYER_ANGRY_FIGHT_29,
+ SFX_PLAYER_ANGRY_FIGHT_30,
+ SFX_PLAYER_ANGRY_FIGHT_31,
+ SFX_PLAYER_ANGRY_FIGHT_32,
+ SFX_PLAYER_ANGRY_FIGHT_33,
+ SFX_PLAYER_ANGRY_FIGHT_34,
+ SFX_PLAYER_ANGRY_FIGHT_35,
+ SFX_PLAYER_ANGRY_FIGHT_36,
+ SFX_PLAYER_ANGRY_FIGHT_37,
+ SFX_PLAYER_ANGRY_FIGHT_38,
+ SFX_PLAYER_ANGRY_FIGHT_39,
+ SFX_PLAYER_ANGRY_FIGHT_40,
+ SFX_PLAYER_ANGRY_FIGHT_41,
+ SFX_PLAYER_ANGRY_FIGHT_42,
+ SFX_PLAYER_ANGRY_FIGHT_43,
+ SFX_PLAYER_ANGRY_FIGHT_44,
+ SFX_PLAYER_ANGRY_FIGHT_45,
+ SFX_PLAYER_ANGRY_FIGHT_46,
+ SFX_PLAYER_ANGRY_FIGHT_47,
+ SFX_PLAYER_ANGRY_FIGHT_48,
+ SFX_PLAYER_ANGRY_FIGHT_49,
+ SFX_PLAYER_ANGRY_FIGHT_50,
+ SFX_PLAYER_ANGRY_FIGHT_51,
+ SFX_PLAYER_ANGRY_FIGHT_52,
+ SFX_PLAYER_ANGRY_FIGHT_53,
+ SFX_PLAYER_ANGRY_FIGHT_54,
+ SFX_PLAYER_ANGRY_FIGHT_55,
+ SFX_PLAYER_ANGRY_FIGHT_56,
+ SFX_PLAYER_ANGRY_FIGHT_57,
+ SFX_PLAYER_ANGRY_FIGHT_58,
+ SFX_PLAYER_ANGRY_FIGHT_59,
+ SFX_PLAYER_ANGRY_FIGHT_60,
+ SFX_PLAYER_ANGRY_FIGHT_61,
+ SFX_PLAYER_ANGRY_JACKED_1,
+ SFX_PLAYER_ANGRY_JACKED_2,
+ SFX_PLAYER_ANGRY_JACKED_3,
+ SFX_PLAYER_ANGRY_JACKED_4,
+ SFX_PLAYER_ANGRY_JACKED_5,
+ SFX_PLAYER_ANGRY_JACKED_6,
+ SFX_PLAYER_ANGRY_JACKED_7,
+ SFX_PLAYER_ANGRY_JACKED_8,
+ SFX_PLAYER_ANGRY_JACKED_9,
+ SFX_PLAYER_ANGRY_JACKED_10,
+ SFX_PLAYER_ANGRY_JACKED_11,
+ SFX_PLAYER_ANGRY_JACKED_12,
+ SFX_PLAYER_ANGRY_JACKED_13,
+ SFX_PLAYER_ANGRY_JACKED_14,
+ SFX_PLAYER_ANGRY_JACKED_15,
+ SFX_PLAYER_ANGRY_JACKED_16,
+ SFX_PLAYER_ANGRY_JACKED_17,
+ SFX_PLAYER_ANGRY_JACKED_18,
+ SFX_PLAYER_ANGRY_JACKED_19,
+ SFX_PLAYER_ANGRY_JACKED_20,
+ SFX_PLAYER_ANGRY_JACKED_21,
+ SFX_PLAYER_ANGRY_JACKED_22,
+ SFX_PLAYER_ANGRY_JACKED_23,
+ SFX_PLAYER_ANGRY_JACKED_24,
+ SFX_PLAYER_ANGRY_JACKED_25,
+ SFX_PLAYER_ANGRY_JACKED_26,
+ SFX_PLAYER_ANGRY_JACKED_27,
+ SFX_PLAYER_ANGRY_JACKED_28,
+ SFX_PLAYER_ANGRY_JACKED_29,
+ SFX_PLAYER_ANGRY_JACKED_30,
+ SFX_PLAYER_ANGRY_JACKED_31,
+ SFX_PLAYER_ANGRY_JACKED_32,
+ SFX_PLAYER_ANGRY_JACKED_33,
+ SFX_PLAYER_ANGRY_JACKING_1,
+ SFX_PLAYER_ANGRY_JACKING_2,
+ SFX_PLAYER_ANGRY_JACKING_3,
+ SFX_PLAYER_ANGRY_JACKING_4,
+ SFX_PLAYER_ANGRY_JACKING_5,
+ SFX_PLAYER_ANGRY_JACKING_6,
+ SFX_PLAYER_ANGRY_JACKING_7,
+ SFX_PLAYER_ANGRY_JACKING_8,
+ SFX_PLAYER_ANGRY_JACKING_9,
+ SFX_PLAYER_ANGRY_JACKING_10,
+ SFX_PLAYER_ANGRY_JACKING_11,
+ SFX_PLAYER_ANGRY_JACKING_12,
+ SFX_PLAYER_ANGRY_JACKING_13,
+ SFX_PLAYER_ANGRY_JACKING_14,
+ SFX_PLAYER_ANGRY_JACKING_15,
+ SFX_PLAYER_ANGRY_JACKING_16,
+ SFX_PLAYER_ANGRY_JACKING_17,
+ SFX_PLAYER_ANGRY_JACKING_18,
+ SFX_PLAYER_ANGRY_JACKING_19,
+ SFX_PLAYER_ANGRY_JACKING_20,
+ SFX_PLAYER_ANGRY_JACKING_21,
+ SFX_PLAYER_ANGRY_JACKING_22,
+ SFX_PLAYER_ANGRY_JACKING_23,
+ SFX_PLAYER_ANGRY_JACKING_24,
+ SFX_PLAYER_ANGRY_JACKING_25,
+ SFX_PLAYER_ANGRY_JACKING_26,
+ SFX_PLAYER_ANGRY_JACKING_27,
+ SFX_PLAYER_ANGRY_JACKING_28,
+ SFX_PLAYER_ANGRY_JACKING_29,
+ SFX_PLAYER_ANGRY_JACKING_30,
+ SFX_PLAYER_ANGRY_JACKING_31,
+ SFX_PLAYER_ANGRY_JACKING_32,
+ SFX_PLAYER_ANGRY_JACKING_33,
+ SFX_PLAYER_ANGRY_JACKING_34,
+ SFX_PLAYER_ANGRY_JACKING_35,
+ SFX_PLAYER_ANGRY_JACKING_36,
+ SFX_PLAYER_ANGRY_JACKING_37,
+ SFX_PLAYER_ANGRY_JACKING_38,
+ SFX_PLAYER_ANGRY_JACKING_39,
+ SFX_PLAYER_ANGRY_JACKING_40,
+ SFX_PLAYER_ANGRY_JACKING_41,
+ SFX_PLAYER_ANGRY_JACKING_42,
+ SFX_PLAYER_ANGRY_JACKING_43,
+ SFX_PLAYER_ANGRY_PICK_UP_CASH_1,
+ SFX_PLAYER_ANGRY_PICK_UP_CASH_2,
+ SFX_PLAYER_ANGRY_PICK_UP_CASH_3,
+ SFX_PLAYER_ANGRY_PICK_UP_CASH_4,
+ SFX_PLAYER_ANGRY_PICK_UP_CASH_5,
+ SFX_PLAYER_ANGRY_PICK_UP_CASH_6,
+ SFX_PLAYER_ANGRY_PICK_UP_CASH_7,
+ SFX_PLAYER_ANGRY_PICK_UP_CASH_8,
+ SFX_PLAYER_ANGRY_PICK_UP_CASH_9,
+ SFX_PLAYER_ANGRY_PICK_UP_CASH_10,
+ SFX_PLAYER_ANGRY_PICK_UP_CASH_11,
+ SFX_PLAYER_ANGRY_PICK_UP_CASH_12,
+ SFX_PLAYER_ANGRY_PICK_UP_HOOKER_1,
+ SFX_PLAYER_ANGRY_PICK_UP_HOOKER_2,
+ SFX_PLAYER_ANGRY_PICK_UP_HOOKER_3,
+ SFX_PLAYER_ANGRY_PICK_UP_HOOKER_4,
+ SFX_PLAYER_ANGRY_PICK_UP_HOOKER_5,
+ SFX_PLAYER_ANGRY_PICK_UP_HOOKER_6,
+ SFX_PLAYER_ANGRY_PULL_GUN_1,
+ SFX_PLAYER_ANGRY_PULL_GUN_2,
+ SFX_PLAYER_ANGRY_PULL_GUN_3,
+ SFX_PLAYER_ANGRY_PULL_GUN_4,
+ SFX_PLAYER_ANGRY_PULL_GUN_5,
+ SFX_PLAYER_ANGRY_PULL_GUN_6,
+ SFX_PLAYER_ANGRY_PULL_GUN_7,
+ SFX_PLAYER_ANGRY_PULL_GUN_8,
+ SFX_PLAYER_ANGRY_PULL_GUN_9,
+ SFX_PLAYER_ANGRY_PULL_GUN_10,
+ SFX_PLAYER_ANGRY_PULL_GUN_11,
+ SFX_PLAYER_ANGRY_PULL_GUN_12,
+ SFX_PLAYER_ANGRY_PULL_GUN_13,
+ SFX_PLAYER_ANGRY_PULL_GUN_14,
+ SFX_PLAYER_ANGRY_PULL_GUN_15,
+ SFX_PLAYER_ANGRY_PULL_GUN_16,
+ SFX_PLAYER_ANGRY_PULL_GUN_17,
+ SFX_PLAYER_ANGRY_PULL_GUN_18,
+ SFX_PLAYER_ANGRY_PULL_GUN_19,
+ SFX_PLAYER_ANGRY_PULL_GUN_20,
+ SFX_PLAYER_ANGRY_PULL_GUN_21,
+ SFX_PLAYER_ANGRY_PULL_GUN_22,
+ SFX_PLAYER_ANGRY_PULL_GUN_23,
+ SFX_PLAYER_ANGRY_PULL_GUN_24,
+ SFX_PLAYER_ANGRY_PULL_GUN_25,
+ SFX_PLAYER_ANGRY_PULL_GUN_26,
+ SFX_PLAYER_ANGRY_PULL_GUN_27,
+ SFX_PLAYER_ANGRY_PULL_GUN_28,
+ SFX_PLAYER_ANGRY_PULL_GUN_29,
+ SFX_PLAYER_ANGRY_PULL_GUN_30,
+ SFX_PLAYER_ANGRY_PULL_GUN_31,
+ SFX_PLAYER_ANGRY_PULL_GUN_32,
+ SFX_PLAYER_ANGRY_PULL_GUN_33,
+ SFX_PLAYER_ANGRY_PULL_GUN_34,
+ SFX_PLAYER_ANGRY_PULL_GUN_35,
+ SFX_PLAYER_ANGRY_PULL_GUN_36,
+ SFX_PLAYER_ANGRY_PULL_GUN_37,
+ SFX_PLAYER_ANGRY_PULL_GUN_38,
+ SFX_PLAYER_ANGRY_PULL_GUN_39,
+ SFX_PLAYER_ANGRY_PULL_GUN_40,
+ SFX_PLAYER_ANGRY_PULL_GUN_41,
+ SFX_PLAYER_ANGRY_PULL_GUN_42,
+ SFX_PLAYER_ANGRY_PULL_GUN_43,
+ SFX_PLAYER_ANGRY_PULL_GUN_44,
+ SFX_PLAYER_ANGRY_PULL_GUN_45,
+ SFX_PLAYER_ANGRY_PULL_GUN_46,
+ SFX_PLAYER_ANGRY_PULL_GUN_47,
+ SFX_PLAYER_ANGRY_PULL_GUN_48,
+ SFX_PLAYER_ANGRY_PULL_GUN_49,
+ SFX_PLAYER_ANGRY_PULL_GUN_50,
+ SFX_PLAYER_ANGRY_PULL_GUN_51,
+ SFX_PLAYER_ANGRY_PULL_GUN_52,
+ SFX_PLAYER_ANGRY_SEX_1,
+ SFX_PLAYER_ANGRY_SEX_2,
+ SFX_PLAYER_ANGRY_SEX_3,
+ SFX_PLAYER_ANGRY_SEX_4,
+ SFX_PLAYER_ANGRY_SEX_5,
+ SFX_PLAYER_ANGRY_SEX_6,
+ SFX_PLAYER_ANGRY_SEX_7,
+ SFX_PLAYER_ANGRY_SEX_8,
+ SFX_PLAYER_ANGRY_SEX_9,
+ SFX_PLAYER_ANGRY_SEX_10,
+ SFX_PLAYER_ANGRY_SEX_11,
+ SFX_PLAYER_ANGRY_SEX_12,
+ SFX_PLAYER_ANGRY_SEX_13,
+ SFX_PLAYER_ANGRY_SEX_14,
+ SFX_PLAYER_ANGRY_SEX_15,
+ SFX_PLAYER_ANGRY_SEX_16,
+ SFX_PLAYER_ANGRY_SEX_17,
+ SFX_PLAYER_ANGRY_SEX_18,
+ SFX_PLAYER_ANGRY_SHOOT_1,
+ SFX_PLAYER_ANGRY_SHOOT_2,
+ SFX_PLAYER_ANGRY_SHOOT_3,
+ SFX_PLAYER_ANGRY_SHOOT_4,
+ SFX_PLAYER_ANGRY_SHOOT_5,
+ SFX_PLAYER_ANGRY_SHOOT_6,
+ SFX_PLAYER_ANGRY_SHOOT_7,
+ SFX_PLAYER_ANGRY_SHOOT_8,
+ SFX_PLAYER_ANGRY_SHOOT_9,
+ SFX_PLAYER_ANGRY_SHOOT_10,
+ SFX_PLAYER_ANGRY_SHOOT_11,
+ SFX_PLAYER_ANGRY_SHOOT_12,
+ SFX_PLAYER_ANGRY_SHOOT_13,
+ SFX_PLAYER_ANGRY_SHOOT_14,
+ SFX_PLAYER_ANGRY_SHOOT_15,
+ SFX_PLAYER_ANGRY_SHOOT_16,
+ SFX_PLAYER_ANGRY_SHOOT_17,
+ SFX_PLAYER_ANGRY_SHOOT_18,
+ SFX_PLAYER_ANGRY_SHOOT_19,
+ SFX_PLAYER_ANGRY_SHOOT_20,
+ SFX_PLAYER_ANGRY_SHOOT_21,
+ SFX_PLAYER_ANGRY_SHOOT_22,
+ SFX_PLAYER_ANGRY_SHOOT_23,
+ SFX_PLAYER_ANGRY_SHOOT_24,
+ SFX_PLAYER_ANGRY_SHOOT_25,
+ SFX_PLAYER_ANGRY_SHOOT_26,
+ SFX_PLAYER_ANGRY_SHOOT_27,
+ SFX_PLAYER_ANGRY_SHOOT_28,
+ SFX_PLAYER_ANGRY_SHOOT_29,
+ SFX_PLAYER_ANGRY_SHOOT_30,
+ SFX_PLAYER_ANGRY_SHOOT_31,
+ SFX_PLAYER_ANGRY_SHOOT_32,
+ SFX_PLAYER_ANGRY_SHOOT_33,
+ SFX_PLAYER_ANGRY_SHOOT_34,
+ SFX_PLAYER_ANGRY_SHOOT_35,
+ SFX_PLAYER_ANGRY_SHOOT_36,
+ SFX_PLAYER_ANGRY_SHOOT_37,
+ SFX_PLAYER_ANGRY_SHOOT_38,
+ SFX_PLAYER_ANGRY_SHOOT_39,
+
+ SFX_PLAYER_CALM_BUSTED_1,
+ SFX_PLAYER_CALM_BUSTED_2,
+ SFX_PLAYER_CALM_BUSTED_3,
+ SFX_PLAYER_CALM_BUSTED_4,
+ SFX_PLAYER_CALM_BUSTED_5,
+ SFX_PLAYER_CALM_BUSTED_6,
+ SFX_PLAYER_CALM_BUSTED_7,
+ SFX_PLAYER_CALM_BUSTED_8,
+ SFX_PLAYER_CALM_BUSTED_9,
+ SFX_PLAYER_CALM_BUSTED_10,
+ SFX_PLAYER_CALM_BUSTED_11,
+ SFX_PLAYER_CALM_BUSTED_12,
+ SFX_PLAYER_CALM_BUSTED_13,
+ SFX_PLAYER_CALM_BUSTED_14,
+ SFX_PLAYER_CALM_BUSTED_15,
+ SFX_PLAYER_CALM_BUSTED_16,
+ SFX_PLAYER_CALM_BUSTED_17,
+ SFX_PLAYER_CALM_BUSTED_18,
+ SFX_PLAYER_CALM_BUSTED_19,
+ SFX_PLAYER_CALM_BUSTED_20,
+ SFX_PLAYER_CALM_BUSTED_21,
+ SFX_PLAYER_CALM_BUSTED_22,
+ SFX_PLAYER_CALM_CHASED_1,
+ SFX_PLAYER_CALM_CHASED_2,
+ SFX_PLAYER_CALM_CHASED_3,
+ SFX_PLAYER_CALM_CHASED_4,
+ SFX_PLAYER_CALM_CHASED_5,
+ SFX_PLAYER_CALM_CHASED_6,
+ SFX_PLAYER_CALM_CHASED_7,
+ SFX_PLAYER_CALM_CHASED_8,
+ SFX_PLAYER_CALM_CHASED_9,
+ SFX_PLAYER_CALM_CHASED_10,
+ SFX_PLAYER_CALM_CHASED_11,
+ SFX_PLAYER_CALM_CHASED_12,
+ SFX_PLAYER_CALM_CHASED_13,
+ SFX_PLAYER_CALM_CHASED_14,
+ SFX_PLAYER_CALM_CHASED_15,
+ SFX_PLAYER_CALM_CHASED_16,
+ SFX_PLAYER_CALM_CHASED_17,
+ SFX_PLAYER_CALM_CHASED_18,
+ SFX_PLAYER_CALM_CHASED_19,
+ SFX_PLAYER_CALM_CHASED_20,
+ SFX_PLAYER_CALM_CRASH_1,
+ SFX_PLAYER_CALM_CRASH_2,
+ SFX_PLAYER_CALM_CRASH_3,
+ SFX_PLAYER_CALM_CRASH_4,
+ SFX_PLAYER_CALM_CRASH_5,
+ SFX_PLAYER_CALM_CRASH_6,
+ SFX_PLAYER_CALM_CRASH_7,
+ SFX_PLAYER_CALM_CRASH_8,
+ SFX_PLAYER_CALM_CRASH_9,
+ SFX_PLAYER_CALM_CRASH_10,
+ SFX_PLAYER_CALM_CRASH_11,
+ SFX_PLAYER_CALM_CRASH_12,
+ SFX_PLAYER_CALM_CRASH_13,
+ SFX_PLAYER_CALM_CRASH_14,
+ SFX_PLAYER_CALM_CRASH_15,
+ SFX_PLAYER_CALM_CRASH_16,
+ SFX_PLAYER_CALM_CRASH_17,
+ SFX_PLAYER_CALM_CRASH_18,
+ SFX_PLAYER_CALM_CRASH_19,
+ SFX_PLAYER_CALM_CRASH_20,
+ SFX_PLAYER_CALM_CRASH_21,
+ SFX_PLAYER_CALM_CRASH_22,
+ SFX_PLAYER_CALM_CRASH_23,
+ SFX_PLAYER_CALM_CRASH_24,
+ SFX_PLAYER_CALM_CRASH_25,
+ SFX_PLAYER_CALM_CRASH_26,
+ SFX_PLAYER_CALM_CRASH_27,
+ SFX_PLAYER_CALM_CRASH_28,
+ SFX_PLAYER_CALM_CRASH_29,
+ SFX_PLAYER_CALM_CRASH_30,
+ SFX_PLAYER_CALM_CRASH_31,
+ SFX_PLAYER_CALM_CRASH_32,
+ SFX_PLAYER_CALM_CRASH_33,
+ SFX_PLAYER_CALM_CRASH_34,
+ SFX_PLAYER_CALM_CRASH_35,
+ SFX_PLAYER_CALM_CRASH_36,
+ SFX_PLAYER_CALM_CRASH_37,
+ SFX_PLAYER_CALM_CRASH_38,
+ SFX_PLAYER_CALM_CRASH_39,
+ SFX_PLAYER_CALM_CRASH_40,
+ SFX_PLAYER_CALM_CRASH_41,
+ SFX_PLAYER_CALM_CRASH_42,
+ SFX_PLAYER_CALM_CRASH_43,
+ SFX_PLAYER_CALM_FIGHT_1,
+ SFX_PLAYER_CALM_FIGHT_2,
+ SFX_PLAYER_CALM_FIGHT_3,
+ SFX_PLAYER_CALM_FIGHT_4,
+ SFX_PLAYER_CALM_FIGHT_5,
+ SFX_PLAYER_CALM_FIGHT_6,
+ SFX_PLAYER_CALM_FIGHT_7,
+ SFX_PLAYER_CALM_FIGHT_8,
+ SFX_PLAYER_CALM_FIGHT_9,
+ SFX_PLAYER_CALM_FIGHT_10,
+ SFX_PLAYER_CALM_FIGHT_11,
+ SFX_PLAYER_CALM_FIGHT_12,
+ SFX_PLAYER_CALM_FIGHT_13,
+ SFX_PLAYER_CALM_FIGHT_14,
+ SFX_PLAYER_CALM_FIGHT_15,
+ SFX_PLAYER_CALM_FIGHT_16,
+ SFX_PLAYER_CALM_FIGHT_17,
+ SFX_PLAYER_CALM_FIGHT_18,
+ SFX_PLAYER_CALM_FIGHT_19,
+ SFX_PLAYER_CALM_FIGHT_20,
+ SFX_PLAYER_CALM_FIGHT_21,
+ SFX_PLAYER_CALM_FIGHT_22,
+ SFX_PLAYER_CALM_FIGHT_23,
+ SFX_PLAYER_CALM_FIGHT_24,
+ SFX_PLAYER_CALM_FIGHT_25,
+ SFX_PLAYER_CALM_FIGHT_26,
+ SFX_PLAYER_CALM_FIGHT_27,
+ SFX_PLAYER_CALM_FIGHT_28,
+ SFX_PLAYER_CALM_FIGHT_29,
+ SFX_PLAYER_CALM_FIGHT_30,
+ SFX_PLAYER_CALM_FIGHT_31,
+ SFX_PLAYER_CALM_FIGHT_32,
+ SFX_PLAYER_CALM_FIGHT_33,
+ SFX_PLAYER_CALM_FIGHT_34,
+ SFX_PLAYER_CALM_FIGHT_35,
+ SFX_PLAYER_CALM_FIGHT_36,
+ SFX_PLAYER_CALM_FIGHT_37,
+ SFX_PLAYER_CALM_FIGHT_38,
+ SFX_PLAYER_CALM_FIGHT_39,
+ SFX_PLAYER_CALM_FIGHT_40,
+ SFX_PLAYER_CALM_FIGHT_41,
+ SFX_PLAYER_CALM_FIGHT_42,
+ SFX_PLAYER_CALM_FIGHT_43,
+ SFX_PLAYER_CALM_FIGHT_44,
+ SFX_PLAYER_CALM_FIGHT_45,
+ SFX_PLAYER_CALM_FIGHT_46,
+ SFX_PLAYER_CALM_FIGHT_47,
+ SFX_PLAYER_CALM_JACKED_1,
+ SFX_PLAYER_CALM_JACKED_2,
+ SFX_PLAYER_CALM_JACKED_3,
+ SFX_PLAYER_CALM_JACKED_4,
+ SFX_PLAYER_CALM_JACKED_5,
+ SFX_PLAYER_CALM_JACKED_6,
+ SFX_PLAYER_CALM_JACKED_7,
+ SFX_PLAYER_CALM_JACKED_8,
+ SFX_PLAYER_CALM_JACKED_9,
+ SFX_PLAYER_CALM_JACKED_10,
+ SFX_PLAYER_CALM_JACKED_11,
+ SFX_PLAYER_CALM_JACKED_12,
+ SFX_PLAYER_CALM_JACKED_13,
+ SFX_PLAYER_CALM_JACKED_14,
+ SFX_PLAYER_CALM_JACKED_15,
+ SFX_PLAYER_CALM_JACKED_16,
+ SFX_PLAYER_CALM_JACKED_17,
+ SFX_PLAYER_CALM_JACKED_18,
+ SFX_PLAYER_CALM_JACKED_19,
+ SFX_PLAYER_CALM_JACKED_20,
+ SFX_PLAYER_CALM_JACKED_21,
+ SFX_PLAYER_CALM_JACKED_22,
+ SFX_PLAYER_CALM_JACKED_23,
+ SFX_PLAYER_CALM_JACKED_24,
+ SFX_PLAYER_CALM_JACKING_1,
+ SFX_PLAYER_CALM_JACKING_2,
+ SFX_PLAYER_CALM_JACKING_3,
+ SFX_PLAYER_CALM_JACKING_4,
+ SFX_PLAYER_CALM_JACKING_5,
+ SFX_PLAYER_CALM_JACKING_6,
+ SFX_PLAYER_CALM_JACKING_7,
+ SFX_PLAYER_CALM_JACKING_8,
+ SFX_PLAYER_CALM_JACKING_9,
+ SFX_PLAYER_CALM_JACKING_10,
+ SFX_PLAYER_CALM_JACKING_11,
+ SFX_PLAYER_CALM_JACKING_12,
+ SFX_PLAYER_CALM_JACKING_13,
+ SFX_PLAYER_CALM_JACKING_14,
+ SFX_PLAYER_CALM_JACKING_15,
+ SFX_PLAYER_CALM_JACKING_16,
+ SFX_PLAYER_CALM_JACKING_17,
+ SFX_PLAYER_CALM_JACKING_18,
+ SFX_PLAYER_CALM_JACKING_19,
+ SFX_PLAYER_CALM_JACKING_20,
+ SFX_PLAYER_CALM_JACKING_21,
+ SFX_PLAYER_CALM_JACKING_22,
+ SFX_PLAYER_CALM_JACKING_23,
+ SFX_PLAYER_CALM_JACKING_24,
+ SFX_PLAYER_CALM_JACKING_25,
+ SFX_PLAYER_CALM_JACKING_26,
+ SFX_PLAYER_CALM_JACKING_27,
+ SFX_PLAYER_CALM_JACKING_28,
+ SFX_PLAYER_CALM_JACKING_29,
+ SFX_PLAYER_CALM_JACKING_30,
+ SFX_PLAYER_CALM_JACKING_31,
+ SFX_PLAYER_CALM_JACKING_32,
+ SFX_PLAYER_CALM_JACKING_33,
+ SFX_PLAYER_CALM_JACKING_34,
+ SFX_PLAYER_CALM_JACKING_35,
+ SFX_PLAYER_CALM_JACKING_36,
+ SFX_PLAYER_CALM_JACKING_37,
+ SFX_PLAYER_CALM_JACKING_38,
+ SFX_PLAYER_CALM_JACKING_39,
+ SFX_PLAYER_CALM_JACKING_40,
+ SFX_PLAYER_CALM_PICK_UP_CASH_1,
+ SFX_PLAYER_CALM_PICK_UP_CASH_2,
+ SFX_PLAYER_CALM_PICK_UP_CASH_3,
+ SFX_PLAYER_CALM_PICK_UP_CASH_4,
+ SFX_PLAYER_CALM_PICK_UP_CASH_5,
+ SFX_PLAYER_CALM_PICK_UP_CASH_6,
+ SFX_PLAYER_CALM_PICK_UP_CASH_7,
+ SFX_PLAYER_CALM_PICK_UP_CASH_8,
+ SFX_PLAYER_CALM_PICK_UP_CASH_9,
+ SFX_PLAYER_CALM_PICK_UP_CASH_10,
+ SFX_PLAYER_CALM_PICK_UP_CASH_11,
+ SFX_PLAYER_CALM_PICK_UP_HOOKER_1,
+ SFX_PLAYER_CALM_PICK_UP_HOOKER_2,
+ SFX_PLAYER_CALM_PICK_UP_HOOKER_3,
+ SFX_PLAYER_CALM_PICK_UP_HOOKER_4,
+ SFX_PLAYER_CALM_PICK_UP_HOOKER_5,
+ SFX_PLAYER_CALM_PICK_UP_HOOKER_6,
+ SFX_PLAYER_CALM_PICK_UP_HOOKER_7,
+ SFX_PLAYER_CALM_PICK_UP_HOOKER_8,
+ SFX_PLAYER_CALM_PICK_UP_HOOKER_9,
+ SFX_PLAYER_CALM_PICK_UP_HOOKER_10,
+ SFX_PLAYER_CALM_PICK_UP_HOOKER_11,
+ SFX_PLAYER_CALM_PICK_UP_HOOKER_12,
+ SFX_PLAYER_CALM_PICK_UP_HOOKER_13,
+ SFX_PLAYER_CALM_PICK_UP_HOOKER_14,
+ SFX_PLAYER_CALM_PICK_UP_HOOKER_15,
+ SFX_PLAYER_CALM_PICK_UP_HOOKER_16,
+ SFX_PLAYER_CALM_PICK_UP_HOOKER_17,
+ SFX_PLAYER_CALM_PICK_UP_HOOKER_18,
+ SFX_PLAYER_CALM_PICK_UP_HOOKER_19,
+ SFX_PLAYER_CALM_PICK_UP_HOOKER_20,
+ SFX_PLAYER_CALM_PICK_UP_HOOKER_21,
+ SFX_PLAYER_CALM_PICK_UP_HOOKER_22,
+ SFX_PLAYER_CALM_PULL_GUN_1,
+ SFX_PLAYER_CALM_PULL_GUN_2,
+ SFX_PLAYER_CALM_PULL_GUN_3,
+ SFX_PLAYER_CALM_PULL_GUN_4,
+ SFX_PLAYER_CALM_PULL_GUN_5,
+ SFX_PLAYER_CALM_PULL_GUN_6,
+ SFX_PLAYER_CALM_PULL_GUN_7,
+ SFX_PLAYER_CALM_PULL_GUN_8,
+ SFX_PLAYER_CALM_PULL_GUN_9,
+ SFX_PLAYER_CALM_PULL_GUN_10,
+ SFX_PLAYER_CALM_PULL_GUN_11,
+ SFX_PLAYER_CALM_PULL_GUN_12,
+ SFX_PLAYER_CALM_PULL_GUN_13,
+ SFX_PLAYER_CALM_PULL_GUN_14,
+ SFX_PLAYER_CALM_PULL_GUN_15,
+ SFX_PLAYER_CALM_PULL_GUN_16,
+ SFX_PLAYER_CALM_PULL_GUN_17,
+ SFX_PLAYER_CALM_PULL_GUN_18,
+ SFX_PLAYER_CALM_PULL_GUN_19,
+ SFX_PLAYER_CALM_PULL_GUN_20,
+ SFX_PLAYER_CALM_PULL_GUN_21,
+ SFX_PLAYER_CALM_PULL_GUN_22,
+ SFX_PLAYER_CALM_PULL_GUN_23,
+ SFX_PLAYER_CALM_PULL_GUN_24,
+ SFX_PLAYER_CALM_PULL_GUN_25,
+ SFX_PLAYER_CALM_PULL_GUN_26,
+ SFX_PLAYER_CALM_PULL_GUN_27,
+ SFX_PLAYER_CALM_PULL_GUN_28,
+ SFX_PLAYER_CALM_PULL_GUN_29,
+ SFX_PLAYER_CALM_PULL_GUN_30,
+ SFX_PLAYER_CALM_PULL_GUN_31,
+ SFX_PLAYER_CALM_PULL_GUN_32,
+ SFX_PLAYER_CALM_PULL_GUN_33,
+ SFX_PLAYER_CALM_PULL_GUN_34,
+ SFX_PLAYER_CALM_PULL_GUN_35,
+ SFX_PLAYER_CALM_PULL_GUN_36,
+ SFX_PLAYER_CALM_PULL_GUN_37,
+ SFX_PLAYER_CALM_PULL_GUN_38,
+ SFX_PLAYER_CALM_PULL_GUN_39,
+ SFX_PLAYER_CALM_SEX_1,
+ SFX_PLAYER_CALM_SEX_2,
+ SFX_PLAYER_CALM_SEX_3,
+ SFX_PLAYER_CALM_SEX_4,
+ SFX_PLAYER_CALM_SEX_5,
+ SFX_PLAYER_CALM_SEX_6,
+ SFX_PLAYER_CALM_SEX_7,
+ SFX_PLAYER_CALM_SEX_8,
+ SFX_PLAYER_CALM_SHOOT_1,
+ SFX_PLAYER_CALM_SHOOT_2,
+ SFX_PLAYER_CALM_SHOOT_3,
+ SFX_PLAYER_CALM_SHOOT_4,
+ SFX_PLAYER_CALM_SHOOT_5,
+ SFX_PLAYER_CALM_SHOOT_6,
+ SFX_PLAYER_CALM_SHOOT_7,
+ SFX_PLAYER_CALM_SHOOT_8,
+ SFX_PLAYER_CALM_SHOOT_9,
+ SFX_PLAYER_CALM_SHOOT_10,
+ SFX_PLAYER_CALM_SHOOT_11,
+ SFX_PLAYER_CALM_SHOOT_12,
+ SFX_PLAYER_CALM_SHOOT_13,
+ SFX_PLAYER_CALM_SHOOT_14,
+ SFX_PLAYER_CALM_SHOOT_15,
+ SFX_PLAYER_CALM_SHOOT_16,
+ SFX_PLAYER_CALM_SHOOT_17,
+ SFX_PLAYER_CALM_SHOOT_18,
+ SFX_PLAYER_CALM_SHOOT_19,
+ SFX_PLAYER_CALM_SHOOT_20,
+ SFX_PLAYER_CALM_SHOOT_21,
+ SFX_PLAYER_CALM_SHOOT_22,
+ SFX_PLAYER_CALM_SHOOT_23,
+ SFX_PLAYER_CALM_SHOOT_24,
+ SFX_PLAYER_CALM_SHOOT_25,
+ SFX_PLAYER_CALM_SHOOT_26,
+ SFX_PLAYER_CALM_SHOOT_27,
+ SFX_PLAYER_CALM_SHOOT_28,
+ SFX_PLAYER_CALM_SHOOT_29,
+ SFX_PLAYER_CALM_SHOOT_30,
+ SFX_PLAYER_CALM_SHOOT_31,
+ SFX_PLAYER_CALM_SHOOT_32,
+ SFX_PLAYER_CALM_SHOOT_33,
+ SFX_PLAYER_CALM_SHOOT_34,
+ SFX_PLAYER_CALM_SHOOT_35,
+
+ SFX_PLAYER_PISSED_OFF_CRASH_1,
+ SFX_PLAYER_PISSED_OFF_CRASH_2,
+ SFX_PLAYER_PISSED_OFF_CRASH_3,
+ SFX_PLAYER_PISSED_OFF_CRASH_4,
+ SFX_PLAYER_PISSED_OFF_CRASH_5,
+ SFX_PLAYER_PISSED_OFF_CRASH_6,
+ SFX_PLAYER_PISSED_OFF_CRASH_7,
+ SFX_PLAYER_PISSED_OFF_CRASH_8,
+ SFX_PLAYER_PISSED_OFF_CRASH_9,
+ SFX_PLAYER_PISSED_OFF_CRASH_10,
+ SFX_PLAYER_PISSED_OFF_CRASH_11,
+ SFX_PLAYER_PISSED_OFF_CRASH_12,
+ SFX_PLAYER_PISSED_OFF_CRASH_13,
+ SFX_PLAYER_PISSED_OFF_CRASH_14,
+ SFX_PLAYER_PISSED_OFF_CRASH_15,
+ SFX_PLAYER_PISSED_OFF_CRASH_16,
+ SFX_PLAYER_PISSED_OFF_CRASH_17,
+ SFX_PLAYER_PISSED_OFF_CRASH_18,
+ SFX_PLAYER_PISSED_OFF_CRASH_19,
+ SFX_PLAYER_PISSED_OFF_CRASH_20,
+ SFX_PLAYER_PISSED_OFF_CRASH_21,
+ SFX_PLAYER_PISSED_OFF_CRASH_22,
+ SFX_PLAYER_PISSED_OFF_CRASH_23,
+ SFX_PLAYER_PISSED_OFF_CRASH_24,
+ SFX_PLAYER_PISSED_OFF_CRASH_25,
+ SFX_PLAYER_PISSED_OFF_CRASH_26,
+ SFX_PLAYER_PISSED_OFF_CRASH_27,
+ SFX_PLAYER_PISSED_OFF_CRASH_28,
+ SFX_PLAYER_PISSED_OFF_CRASH_29,
+ SFX_PLAYER_PISSED_OFF_CRASH_30,
+ SFX_PLAYER_PISSED_OFF_CRASH_31,
+ SFX_PLAYER_PISSED_OFF_CRASH_32,
+ SFX_PLAYER_PISSED_OFF_CRASH_33,
+ SFX_PLAYER_PISSED_OFF_CRASH_34,
+ SFX_PLAYER_PISSED_OFF_CRASH_35,
+ SFX_PLAYER_PISSED_OFF_CRASH_36,
+ SFX_PLAYER_PISSED_OFF_CRASH_37,
+ SFX_PLAYER_PISSED_OFF_CRASH_38,
+ SFX_PLAYER_PISSED_OFF_CRASH_39,
+ SFX_PLAYER_PISSED_OFF_CRASH_40,
+ SFX_PLAYER_PISSED_OFF_CRASH_41,
+ SFX_PLAYER_PISSED_OFF_CRASH_42,
+ SFX_PLAYER_PISSED_OFF_CRASH_43,
+ SFX_PLAYER_PISSED_OFF_CRASH_44,
+ SFX_PLAYER_PISSED_OFF_FIGHT_1,
+ SFX_PLAYER_PISSED_OFF_FIGHT_2,
+ SFX_PLAYER_PISSED_OFF_FIGHT_3,
+ SFX_PLAYER_PISSED_OFF_FIGHT_4,
+ SFX_PLAYER_PISSED_OFF_FIGHT_5,
+ SFX_PLAYER_PISSED_OFF_FIGHT_6,
+ SFX_PLAYER_PISSED_OFF_FIGHT_7,
+ SFX_PLAYER_PISSED_OFF_FIGHT_8,
+ SFX_PLAYER_PISSED_OFF_FIGHT_9,
+ SFX_PLAYER_PISSED_OFF_FIGHT_10,
+ SFX_PLAYER_PISSED_OFF_FIGHT_11,
+ SFX_PLAYER_PISSED_OFF_FIGHT_12,
+ SFX_PLAYER_PISSED_OFF_FIGHT_13,
+ SFX_PLAYER_PISSED_OFF_FIGHT_14,
+ SFX_PLAYER_PISSED_OFF_FIGHT_15,
+ SFX_PLAYER_PISSED_OFF_FIGHT_16,
+ SFX_PLAYER_PISSED_OFF_FIGHT_17,
+ SFX_PLAYER_PISSED_OFF_FIGHT_18,
+ SFX_PLAYER_PISSED_OFF_FIGHT_19,
+ SFX_PLAYER_PISSED_OFF_FIGHT_20,
+ SFX_PLAYER_PISSED_OFF_FIGHT_21,
+ SFX_PLAYER_PISSED_OFF_FIGHT_22,
+ SFX_PLAYER_PISSED_OFF_FIGHT_23,
+ SFX_PLAYER_PISSED_OFF_FIGHT_24,
+ SFX_PLAYER_PISSED_OFF_FIGHT_25,
+ SFX_PLAYER_PISSED_OFF_FIGHT_26,
+ SFX_PLAYER_PISSED_OFF_FIGHT_27,
+ SFX_PLAYER_PISSED_OFF_FIGHT_28,
+ SFX_PLAYER_PISSED_OFF_FIGHT_29,
+ SFX_PLAYER_PISSED_OFF_FIGHT_30,
+ SFX_PLAYER_PISSED_OFF_FIGHT_31,
+ SFX_PLAYER_PISSED_OFF_FIGHT_32,
+ SFX_PLAYER_PISSED_OFF_FIGHT_33,
+ SFX_PLAYER_PISSED_OFF_FIGHT_34,
+ SFX_PLAYER_PISSED_OFF_FIGHT_35,
+ SFX_PLAYER_PISSED_OFF_FIGHT_36,
+ SFX_PLAYER_PISSED_OFF_FIGHT_37,
+ SFX_PLAYER_PISSED_OFF_FIGHT_38,
+ SFX_PLAYER_PISSED_OFF_FIGHT_39,
+ SFX_PLAYER_PISSED_OFF_FIGHT_40,
+ SFX_PLAYER_PISSED_OFF_FIGHT_41,
+ SFX_PLAYER_PISSED_OFF_FIGHT_42,
+ SFX_PLAYER_PISSED_OFF_FIGHT_43,
+ SFX_PLAYER_PISSED_OFF_FIGHT_44,
+ SFX_PLAYER_PISSED_OFF_FIGHT_45,
+ SFX_PLAYER_PISSED_OFF_FIGHT_46,
+ SFX_PLAYER_PISSED_OFF_FIGHT_47,
+ SFX_PLAYER_PISSED_OFF_FIGHT_48,
+ SFX_PLAYER_PISSED_OFF_FIGHT_49,
+ SFX_PLAYER_PISSED_OFF_FIGHT_50,
+ SFX_PLAYER_PISSED_OFF_FIGHT_51,
+ SFX_PLAYER_PISSED_OFF_FIGHT_52,
+ SFX_PLAYER_PISSED_OFF_FIGHT_53,
+ SFX_PLAYER_PISSED_OFF_FIGHT_54,
+ SFX_PLAYER_PISSED_OFF_FIGHT_55,
+ SFX_PLAYER_PISSED_OFF_FIGHT_56,
+ SFX_PLAYER_PISSED_OFF_FIGHT_57,
+ SFX_PLAYER_PISSED_OFF_FIGHT_58,
+ SFX_PLAYER_PISSED_OFF_FIGHT_59,
+ SFX_PLAYER_PISSED_OFF_FIGHT_60,
+ SFX_PLAYER_PISSED_OFF_FIGHT_61,
+ SFX_PLAYER_PISSED_OFF_JACKED_1,
+ SFX_PLAYER_PISSED_OFF_JACKED_2,
+ SFX_PLAYER_PISSED_OFF_JACKED_3,
+ SFX_PLAYER_PISSED_OFF_JACKED_4,
+ SFX_PLAYER_PISSED_OFF_JACKED_5,
+ SFX_PLAYER_PISSED_OFF_JACKED_6,
+ SFX_PLAYER_PISSED_OFF_JACKED_7,
+ SFX_PLAYER_PISSED_OFF_JACKED_8,
+ SFX_PLAYER_PISSED_OFF_JACKED_9,
+ SFX_PLAYER_PISSED_OFF_JACKED_10,
+ SFX_PLAYER_PISSED_OFF_JACKED_11,
+ SFX_PLAYER_PISSED_OFF_JACKED_12,
+ SFX_PLAYER_PISSED_OFF_JACKED_13,
+ SFX_PLAYER_PISSED_OFF_JACKED_14,
+ SFX_PLAYER_PISSED_OFF_JACKED_15,
+ SFX_PLAYER_PISSED_OFF_JACKED_16,
+ SFX_PLAYER_PISSED_OFF_JACKED_17,
+ SFX_PLAYER_PISSED_OFF_JACKED_18,
+ SFX_PLAYER_PISSED_OFF_JACKED_19,
+ SFX_PLAYER_PISSED_OFF_JACKED_20,
+ SFX_PLAYER_PISSED_OFF_JACKED_21,
+ SFX_PLAYER_PISSED_OFF_JACKING_1,
+ SFX_PLAYER_PISSED_OFF_JACKING_2,
+ SFX_PLAYER_PISSED_OFF_JACKING_3,
+ SFX_PLAYER_PISSED_OFF_JACKING_4,
+ SFX_PLAYER_PISSED_OFF_JACKING_5,
+ SFX_PLAYER_PISSED_OFF_JACKING_6,
+ SFX_PLAYER_PISSED_OFF_JACKING_7,
+ SFX_PLAYER_PISSED_OFF_JACKING_8,
+ SFX_PLAYER_PISSED_OFF_JACKING_9,
+ SFX_PLAYER_PISSED_OFF_JACKING_10,
+ SFX_PLAYER_PISSED_OFF_JACKING_11,
+ SFX_PLAYER_PISSED_OFF_JACKING_12,
+ SFX_PLAYER_PISSED_OFF_JACKING_13,
+ SFX_PLAYER_PISSED_OFF_JACKING_14,
+ SFX_PLAYER_PISSED_OFF_JACKING_15,
+ SFX_PLAYER_PISSED_OFF_JACKING_16,
+ SFX_PLAYER_PISSED_OFF_JACKING_17,
+ SFX_PLAYER_PISSED_OFF_JACKING_18,
+ SFX_PLAYER_PISSED_OFF_JACKING_19,
+ SFX_PLAYER_PISSED_OFF_JACKING_20,
+ SFX_PLAYER_PISSED_OFF_JACKING_21,
+ SFX_PLAYER_PISSED_OFF_JACKING_22,
+ SFX_PLAYER_PISSED_OFF_JACKING_23,
+ SFX_PLAYER_PISSED_OFF_JACKING_24,
+ SFX_PLAYER_PISSED_OFF_JACKING_25,
+ SFX_PLAYER_PISSED_OFF_JACKING_26,
+ SFX_PLAYER_PISSED_OFF_JACKING_27,
+ SFX_PLAYER_PISSED_OFF_JACKING_28,
+ SFX_PLAYER_PISSED_OFF_JACKING_29,
+ SFX_PLAYER_PISSED_OFF_JACKING_30,
+ SFX_PLAYER_PISSED_OFF_JACKING_31,
+ SFX_PLAYER_PISSED_OFF_JACKING_32,
+ SFX_PLAYER_PISSED_OFF_JACKING_33,
+ SFX_PLAYER_PISSED_OFF_JACKING_34,
+ SFX_PLAYER_PISSED_OFF_JACKING_35,
+ SFX_PLAYER_PISSED_OFF_JACKING_36,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_CASH_1,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_CASH_2,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_CASH_3,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_CASH_4,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_CASH_5,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_CASH_6,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_CASH_7,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_CASH_8,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_CASH_9,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_CASH_10,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_CASH_11,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_CASH_12,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_CASH_13,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_CASH_14,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_CASH_15,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_CASH_16,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_CASH_17,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_CASH_18,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_CASH_19,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_CASH_20,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_CASH_21,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_CASH_22,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_CASH_23,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_CASH_24,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_CASH_25,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_HOOKER_1,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_HOOKER_2,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_HOOKER_3,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_HOOKER_4,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_HOOKER_5,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_HOOKER_6,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_HOOKER_7,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_HOOKER_8,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_HOOKER_9,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_HOOKER_10,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_HOOKER_11,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_HOOKER_12,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_HOOKER_13,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_HOOKER_14,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_HOOKER_15,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_HOOKER_16,
+ SFX_PLAYER_PISSED_OFF_PICK_UP_HOOKER_17,
+ SFX_PLAYER_PISSED_OFF_PULL_GUN_1,
+ SFX_PLAYER_PISSED_OFF_PULL_GUN_2,
+ SFX_PLAYER_PISSED_OFF_PULL_GUN_3,
+ SFX_PLAYER_PISSED_OFF_PULL_GUN_4,
+ SFX_PLAYER_PISSED_OFF_PULL_GUN_5,
+ SFX_PLAYER_PISSED_OFF_PULL_GUN_6,
+ SFX_PLAYER_PISSED_OFF_PULL_GUN_7,
+ SFX_PLAYER_PISSED_OFF_PULL_GUN_8,
+ SFX_PLAYER_PISSED_OFF_PULL_GUN_9,
+ SFX_PLAYER_PISSED_OFF_PULL_GUN_10,
+ SFX_PLAYER_PISSED_OFF_PULL_GUN_11,
+ SFX_PLAYER_PISSED_OFF_PULL_GUN_12,
+ SFX_PLAYER_PISSED_OFF_PULL_GUN_13,
+ SFX_PLAYER_PISSED_OFF_PULL_GUN_14,
+ SFX_PLAYER_PISSED_OFF_PULL_GUN_15,
+ SFX_PLAYER_PISSED_OFF_PULL_GUN_16,
+ SFX_PLAYER_PISSED_OFF_PULL_GUN_17,
+ SFX_PLAYER_PISSED_OFF_PULL_GUN_18,
+ SFX_PLAYER_PISSED_OFF_PULL_GUN_19,
+ SFX_PLAYER_PISSED_OFF_PULL_GUN_20,
+ SFX_PLAYER_PISSED_OFF_PULL_GUN_21,
+ SFX_PLAYER_PISSED_OFF_PULL_GUN_22,
+ SFX_PLAYER_PISSED_OFF_PULL_GUN_23,
+ SFX_PLAYER_PISSED_OFF_PULL_GUN_24,
+ SFX_PLAYER_PISSED_OFF_PULL_GUN_25,
+ SFX_PLAYER_PISSED_OFF_SHOOT_1,
+ SFX_PLAYER_PISSED_OFF_SHOOT_2,
+ SFX_PLAYER_PISSED_OFF_SHOOT_3,
+ SFX_PLAYER_PISSED_OFF_SHOOT_4,
+ SFX_PLAYER_PISSED_OFF_SHOOT_5,
+ SFX_PLAYER_PISSED_OFF_SHOOT_6,
+ SFX_PLAYER_PISSED_OFF_SHOOT_7,
+ SFX_PLAYER_PISSED_OFF_SHOOT_8,
+ SFX_PLAYER_PISSED_OFF_SHOOT_9,
+ SFX_PLAYER_PISSED_OFF_SHOOT_10,
+ SFX_PLAYER_PISSED_OFF_SHOOT_11,
+ SFX_PLAYER_PISSED_OFF_SHOOT_12,
+ SFX_PLAYER_PISSED_OFF_SHOOT_13,
+ SFX_PLAYER_PISSED_OFF_SHOOT_14,
+ SFX_PLAYER_PISSED_OFF_SHOOT_15,
+ SFX_PLAYER_PISSED_OFF_SHOOT_16,
+ SFX_PLAYER_PISSED_OFF_SHOOT_17,
+ SFX_PLAYER_PISSED_OFF_SHOOT_18,
+ SFX_PLAYER_PISSED_OFF_SHOOT_19,
+ SFX_PLAYER_PISSED_OFF_SHOOT_20,
+ SFX_PLAYER_PISSED_OFF_SHOOT_21,
+ SFX_PLAYER_PISSED_OFF_SHOOT_22,
+ SFX_PLAYER_PISSED_OFF_SHOOT_23,
+ SFX_PLAYER_PISSED_OFF_SHOOT_24,
+ SFX_PLAYER_PISSED_OFF_SHOOT_25,
+ SFX_PLAYER_PISSED_OFF_SHOOT_26,
+ SFX_PLAYER_PISSED_OFF_SHOOT_27,
+ SFX_PLAYER_PISSED_OFF_SHOOT_28,
+ SFX_PLAYER_PISSED_OFF_SHOOT_29,
+
+ SFX_PLAYER_WISECRACKING_BUSTED_1,
+ SFX_PLAYER_WISECRACKING_BUSTED_2,
+ SFX_PLAYER_WISECRACKING_BUSTED_3,
+ SFX_PLAYER_WISECRACKING_BUSTED_4,
+ SFX_PLAYER_WISECRACKING_BUSTED_5,
+ SFX_PLAYER_WISECRACKING_BUSTED_6,
+ SFX_PLAYER_WISECRACKING_BUSTED_7,
+ SFX_PLAYER_WISECRACKING_BUSTED_8,
+ SFX_PLAYER_WISECRACKING_BUSTED_9,
+ SFX_PLAYER_WISECRACKING_BUSTED_10,
+ SFX_PLAYER_WISECRACKING_BUSTED_11,
+ SFX_PLAYER_WISECRACKING_BUSTED_12,
+ SFX_PLAYER_WISECRACKING_BUSTED_13,
+ SFX_PLAYER_WISECRACKING_BUSTED_14,
+ SFX_PLAYER_WISECRACKING_BUSTED_15,
+ SFX_PLAYER_WISECRACKING_BUSTED_16,
+ SFX_PLAYER_WISECRACKING_BUSTED_17,
+ SFX_PLAYER_WISECRACKING_BUSTED_18,
+ SFX_PLAYER_WISECRACKING_BUSTED_19,
+ SFX_PLAYER_WISECRACKING_BUSTED_20,
+ SFX_PLAYER_WISECRACKING_CHASED_1,
+ SFX_PLAYER_WISECRACKING_CHASED_2,
+ SFX_PLAYER_WISECRACKING_CHASED_3,
+ SFX_PLAYER_WISECRACKING_CHASED_4,
+ SFX_PLAYER_WISECRACKING_CHASED_5,
+ SFX_PLAYER_WISECRACKING_CHASED_6,
+ SFX_PLAYER_WISECRACKING_CHASED_7,
+ SFX_PLAYER_WISECRACKING_CRASH_1,
+ SFX_PLAYER_WISECRACKING_CRASH_2,
+ SFX_PLAYER_WISECRACKING_CRASH_3,
+ SFX_PLAYER_WISECRACKING_CRASH_4,
+ SFX_PLAYER_WISECRACKING_CRASH_5,
+ SFX_PLAYER_WISECRACKING_CRASH_6,
+ SFX_PLAYER_WISECRACKING_CRASH_7,
+ SFX_PLAYER_WISECRACKING_CRASH_8,
+ SFX_PLAYER_WISECRACKING_CRASH_9,
+ SFX_PLAYER_WISECRACKING_CRASH_10,
+ SFX_PLAYER_WISECRACKING_CRASH_11,
+ SFX_PLAYER_WISECRACKING_CRASH_12,
+ SFX_PLAYER_WISECRACKING_CRASH_13,
+ SFX_PLAYER_WISECRACKING_CRASH_14,
+ SFX_PLAYER_WISECRACKING_CRASH_15,
+ SFX_PLAYER_WISECRACKING_CRASH_16,
+ SFX_PLAYER_WISECRACKING_CRASH_17,
+ SFX_PLAYER_WISECRACKING_CRASH_18,
+ SFX_PLAYER_WISECRACKING_CRASH_19,
+ SFX_PLAYER_WISECRACKING_FIGHT_1,
+ SFX_PLAYER_WISECRACKING_FIGHT_2,
+ SFX_PLAYER_WISECRACKING_FIGHT_3,
+ SFX_PLAYER_WISECRACKING_FIGHT_4,
+ SFX_PLAYER_WISECRACKING_FIGHT_5,
+ SFX_PLAYER_WISECRACKING_FIGHT_6,
+ SFX_PLAYER_WISECRACKING_FIGHT_7,
+ SFX_PLAYER_WISECRACKING_FIGHT_8,
+ SFX_PLAYER_WISECRACKING_FIGHT_9,
+ SFX_PLAYER_WISECRACKING_FIGHT_10,
+ SFX_PLAYER_WISECRACKING_FIGHT_11,
+ SFX_PLAYER_WISECRACKING_FIGHT_12,
+ SFX_PLAYER_WISECRACKING_FIGHT_13,
+ SFX_PLAYER_WISECRACKING_FIGHT_14,
+ SFX_PLAYER_WISECRACKING_FIGHT_15,
+ SFX_PLAYER_WISECRACKING_FIGHT_16,
+ SFX_PLAYER_WISECRACKING_FIGHT_17,
+ SFX_PLAYER_WISECRACKING_FIGHT_18,
+ SFX_PLAYER_WISECRACKING_FIGHT_19,
+ SFX_PLAYER_WISECRACKING_FIGHT_20,
+ SFX_PLAYER_WISECRACKING_FIGHT_21,
+ SFX_PLAYER_WISECRACKING_FIGHT_22,
+ SFX_PLAYER_WISECRACKING_FIGHT_23,
+ SFX_PLAYER_WISECRACKING_FIGHT_24,
+ SFX_PLAYER_WISECRACKING_FIGHT_25,
+ SFX_PLAYER_WISECRACKING_FIGHT_26,
+ SFX_PLAYER_WISECRACKING_FIGHT_27,
+ SFX_PLAYER_WISECRACKING_JACKED_1,
+ SFX_PLAYER_WISECRACKING_JACKED_2,
+ SFX_PLAYER_WISECRACKING_JACKED_3,
+ SFX_PLAYER_WISECRACKING_JACKED_4,
+ SFX_PLAYER_WISECRACKING_JACKED_5,
+ SFX_PLAYER_WISECRACKING_JACKED_6,
+ SFX_PLAYER_WISECRACKING_JACKED_7,
+ SFX_PLAYER_WISECRACKING_JACKED_8,
+ SFX_PLAYER_WISECRACKING_JACKED_9,
+ SFX_PLAYER_WISECRACKING_JACKED_10,
+ SFX_PLAYER_WISECRACKING_JACKED_11,
+ SFX_PLAYER_WISECRACKING_JACKED_12,
+ SFX_PLAYER_WISECRACKING_JACKED_13,
+ SFX_PLAYER_WISECRACKING_JACKED_14,
+ SFX_PLAYER_WISECRACKING_JACKED_15,
+ SFX_PLAYER_WISECRACKING_JACKED_16,
+ SFX_PLAYER_WISECRACKING_JACKED_17,
+ SFX_PLAYER_WISECRACKING_JACKED_18,
+ SFX_PLAYER_WISECRACKING_JACKING_1,
+ SFX_PLAYER_WISECRACKING_JACKING_2,
+ SFX_PLAYER_WISECRACKING_JACKING_3,
+ SFX_PLAYER_WISECRACKING_JACKING_4,
+ SFX_PLAYER_WISECRACKING_JACKING_5,
+ SFX_PLAYER_WISECRACKING_JACKING_6,
+ SFX_PLAYER_WISECRACKING_JACKING_7,
+ SFX_PLAYER_WISECRACKING_JACKING_8,
+ SFX_PLAYER_WISECRACKING_JACKING_9,
+ SFX_PLAYER_WISECRACKING_JACKING_10,
+ SFX_PLAYER_WISECRACKING_JACKING_11,
+ SFX_PLAYER_WISECRACKING_JACKING_12,
+ SFX_PLAYER_WISECRACKING_JACKING_13,
+ SFX_PLAYER_WISECRACKING_JACKING_14,
+ SFX_PLAYER_WISECRACKING_JACKING_15,
+ SFX_PLAYER_WISECRACKING_JACKING_16,
+ SFX_PLAYER_WISECRACKING_JACKING_17,
+ SFX_PLAYER_WISECRACKING_JACKING_18,
+ SFX_PLAYER_WISECRACKING_PICK_UP_CASH_1,
+ SFX_PLAYER_WISECRACKING_PICK_UP_CASH_2,
+ SFX_PLAYER_WISECRACKING_PICK_UP_CASH_3,
+ SFX_PLAYER_WISECRACKING_PICK_UP_CASH_4,
+ SFX_PLAYER_WISECRACKING_PICK_UP_CASH_5,
+ SFX_PLAYER_WISECRACKING_PICK_UP_CASH_6,
+ SFX_PLAYER_WISECRACKING_PICK_UP_CASH_7,
+ SFX_PLAYER_WISECRACKING_PICK_UP_CASH_8,
+ SFX_PLAYER_WISECRACKING_PICK_UP_CASH_9,
+ SFX_PLAYER_WISECRACKING_PICK_UP_CASH_10,
+ SFX_PLAYER_WISECRACKING_PICK_UP_CASH_11,
+ SFX_PLAYER_WISECRACKING_PICK_UP_CASH_12,
+ SFX_PLAYER_WISECRACKING_PICK_UP_CASH_13,
+ SFX_PLAYER_WISECRACKING_PICK_UP_CASH_14,
+ SFX_PLAYER_WISECRACKING_PICK_UP_CASH_15,
+ SFX_PLAYER_WISECRACKING_PICK_UP_CASH_16,
+ SFX_PLAYER_WISECRACKING_PICK_UP_CASH_17,
+ SFX_PLAYER_WISECRACKING_PICK_UP_CASH_18,
+ SFX_PLAYER_WISECRACKING_PICK_UP_CASH_19,
+ SFX_PLAYER_WISECRACKING_PICK_UP_CASH_20,
+ SFX_PLAYER_WISECRACKING_PICK_UP_CASH_21,
+ SFX_PLAYER_WISECRACKING_PICK_UP_CASH_22,
+ SFX_PLAYER_WISECRACKING_PICK_UP_CASH_23,
+ SFX_PLAYER_WISECRACKING_PICK_UP_HOOKER_1,
+ SFX_PLAYER_WISECRACKING_PICK_UP_HOOKER_2,
+ SFX_PLAYER_WISECRACKING_PICK_UP_HOOKER_3,
+ SFX_PLAYER_WISECRACKING_PICK_UP_HOOKER_4,
+ SFX_PLAYER_WISECRACKING_PICK_UP_HOOKER_5,
+ SFX_PLAYER_WISECRACKING_PICK_UP_HOOKER_6,
+ SFX_PLAYER_WISECRACKING_PICK_UP_HOOKER_7,
+ SFX_PLAYER_WISECRACKING_PICK_UP_HOOKER_8,
+ SFX_PLAYER_WISECRACKING_PICK_UP_HOOKER_9,
+ SFX_PLAYER_WISECRACKING_PICK_UP_HOOKER_10,
+ SFX_PLAYER_WISECRACKING_PICK_UP_HOOKER_11,
+ SFX_PLAYER_WISECRACKING_PULL_GUN_1,
+ SFX_PLAYER_WISECRACKING_PULL_GUN_2,
+ SFX_PLAYER_WISECRACKING_PULL_GUN_3,
+ SFX_PLAYER_WISECRACKING_PULL_GUN_4,
+ SFX_PLAYER_WISECRACKING_PULL_GUN_5,
+ SFX_PLAYER_WISECRACKING_PULL_GUN_6,
+ SFX_PLAYER_WISECRACKING_PULL_GUN_7,
+ SFX_PLAYER_WISECRACKING_PULL_GUN_8,
+ SFX_PLAYER_WISECRACKING_PULL_GUN_9,
+ SFX_PLAYER_WISECRACKING_PULL_GUN_10,
+ SFX_PLAYER_WISECRACKING_PULL_GUN_11,
+ SFX_PLAYER_WISECRACKING_PULL_GUN_12,
+ SFX_PLAYER_WISECRACKING_PULL_GUN_13,
+ SFX_PLAYER_WISECRACKING_PULL_GUN_14,
+ SFX_PLAYER_WISECRACKING_PULL_GUN_15,
+ SFX_PLAYER_WISECRACKING_PULL_GUN_16,
+ SFX_PLAYER_WISECRACKING_PULL_GUN_17,
+ SFX_PLAYER_WISECRACKING_PULL_GUN_18,
+ SFX_PLAYER_WISECRACKING_PULL_GUN_19,
+ SFX_PLAYER_WISECRACKING_SEX_1,
+ SFX_PLAYER_WISECRACKING_SEX_2,
+ SFX_PLAYER_WISECRACKING_SEX_3,
+ SFX_PLAYER_WISECRACKING_SEX_4,
+ SFX_PLAYER_WISECRACKING_SEX_5,
+ SFX_PLAYER_WISECRACKING_SEX_6,
+ SFX_PLAYER_WISECRACKING_SEX_7,
+ SFX_PLAYER_WISECRACKING_SEX_8,
+ SFX_PLAYER_WISECRACKING_SEX_9,
+ SFX_PLAYER_WISECRACKING_SEX_10,
+ SFX_PLAYER_WISECRACKING_SHOOT_1,
+ SFX_PLAYER_WISECRACKING_SHOOT_2,
+ SFX_PLAYER_WISECRACKING_SHOOT_3,
+ SFX_PLAYER_WISECRACKING_SHOOT_4,
+ SFX_PLAYER_WISECRACKING_SHOOT_5,
+ SFX_PLAYER_WISECRACKING_SHOOT_6,
+ SFX_PLAYER_WISECRACKING_SHOOT_7,
+ SFX_PLAYER_WISECRACKING_SHOOT_8,
+ SFX_PLAYER_WISECRACKING_SHOOT_9,
+ SFX_PLAYER_DEATH,
+ SFX_PLAYER_AFTERSEX_1,
+ SFX_PLAYER_AFTERSEX_2,
+ SFX_PLAYER_AFTERSEX_3,
+ SFX_PLAYER_AFTERSEX_4,
+ SFX_PLAYER_AFTERSEX_5,
+ SFX_PLAYER_AFTERSEX_6,
+ SFX_PLAYER_AFTERSEX_7,
+ SFX_PLAYER_AFTERSEX_8,
+ SFX_PLAYER_AFTERSEX_9,
+ SFX_PLAYER_AFTERSEX_10,
+ SFX_PLAYER_AFTERSEX_11,
+ SFX_PLAYER_AFTERSEX_12,
+ SFX_PLAYER_AFTERSEX_13,
+ SFX_PLAYER_AFTERSEX_14,
+ SFX_PLAYER_AFTERSEX_15,
+ SFX_PLAYER_AFTERSEX_16,
+ SFX_PLAYER_AFTERSEX_17,
+ SFX_PLAYER_AFTERSEX_18,
+ SFX_PLAYER_HIT_BULLET_1,
+ SFX_PLAYER_HIT_BULLET_2,
+ SFX_PLAYER_HIT_BULLET_3,
+ SFX_PLAYER_HIT_BULLET_4,
+ SFX_PLAYER_HIT_BULLET_5,
+ SFX_PLAYER_HIT_BULLET_6,
+ SFX_PLAYER_HIT_BULLET_7,
+ SFX_PLAYER_HIT_BULLET_8,
+ SFX_PLAYER_HIT_BULLET_9,
+ SFX_PLAYER_HIT_BULLET_10,
+ SFX_PLAYER_HIT_BULLET_11,
+ SFX_PLAYER_HIT_BULLET_12,
+ SFX_PLAYER_HIT_BULLET_13,
+ SFX_PLAYER_HIT_BULLET_14,
+ SFX_PLAYER_HIT_BULLET_15,
+ SFX_PLAYER_HIT_BULLET_16,
+ SFX_PLAYER_HIT_BULLET_17,
+ SFX_PLAYER_HIT_BULLET_18,
+ SFX_PLAYER_HIT_BULLET_19,
+ SFX_PLAYER_HIT_BULLET_20,
+ SFX_PLAYER_HIT_BULLET_21,
+ SFX_PLAYER_HIT_BULLET_22,
+ SFX_PLAYER_HIT_BULLET_23,
+ SFX_PLAYER_HIT_BULLET_24,
+ SFX_PLAYER_HIT_BULLET_25,
+ SFX_PLAYER_HIT_BULLET_26,
+ SFX_PLAYER_HIT_BULLET_27,
+ SFX_PLAYER_HIT_BULLET_28,
+ SFX_PLAYER_HIT_BULLET_29,
+ SFX_PLAYER_HIT_BULLET_30,
+ SFX_PLAYER_HIT_BULLET_31,
+ SFX_PLAYER_HIT_BULLET_32,
+ SFX_PLAYER_HIT_BULLET_33,
+ SFX_PLAYER_HIT_GROUND_1,
+ SFX_PLAYER_HIT_GROUND_2,
+ SFX_PLAYER_HIT_GROUND_3,
+ SFX_PLAYER_HIT_GROUND_4,
+ SFX_PLAYER_HIT_GROUND_5,
+ SFX_PLAYER_HIT_GROUND_6,
+ SFX_PLAYER_HIT_GROUND_7,
+ SFX_PLAYER_HIT_GROUND_8,
+ SFX_PLAYER_HIT_GROUND_9,
+ SFX_PLAYER_HIT_GROUND_10,
+ SFX_PLAYER_HIT_GROUND_11,
+ SFX_PLAYER_HIT_GROUND_12,
+ SFX_PLAYER_HIT_GROUND_13,
+ SFX_PLAYER_HIT_GROUND_14,
+ SFX_PLAYER_HIT_GROUND_15,
+ SFX_PLAYER_HIT_GROUND_16,
+ SFX_PLAYER_HIT_GROUND_17,
+ SFX_PLAYER_HIT_GROUND_18,
+ SFX_PLAYER_HIT_GROUND_19,
+ SFX_PLAYER_HIT_GROUND_20,
+ SFX_PLAYER_HIT_GROUND_21,
+ SFX_PLAYER_HIT_GROUND_22,
+ SFX_PLAYER_HIT_GROUND_23,
+ SFX_PLAYER_HIT_GROUND_24,
+ SFX_PLAYER_HIT_GROUND_25,
+ SFX_PLAYER_HIT_GROUND_26,
+ SFX_PLAYER_HIT_GROUND_27,
+ SFX_PLAYER_HIT_GROUND_28,
+ SFX_PLAYER_HIT_GROUND_29,
+ SFX_PLAYER_HIT_GROUND_30,
+ SFX_PLAYER_HIT_GROUND_31,
+ SFX_PLAYER_HIT_GROUND_32,
+ SFX_PLAYER_HIT_GROUND_33,
+ SFX_PLAYER_HIT_GROUND_34,
+ SFX_PLAYER_HIT_GROUND_35,
+ SFX_PLAYER_HIT_FIST_1,
+ SFX_PLAYER_HIT_FIST_2,
+ SFX_PLAYER_HIT_FIST_3,
+ SFX_PLAYER_HIT_FIST_4,
+ SFX_PLAYER_HIT_FIST_5,
+ SFX_PLAYER_HIT_FIST_6,
+ SFX_PLAYER_HIT_FIST_7,
+ SFX_PLAYER_HIT_FIST_8,
+ SFX_PLAYER_HIT_FIST_9,
+ SFX_PLAYER_HIT_FIST_10,
+ SFX_PLAYER_HIT_FIST_11,
+ SFX_PLAYER_HIT_FIST_12,
+ SFX_PLAYER_HIT_FIST_13,
+ SFX_PLAYER_HIT_FIST_14,
+ SFX_PLAYER_HIT_FIST_15,
+ SFX_PLAYER_HIT_FIST_16,
+ SFX_PLAYER_HIT_FIST_17,
+ SFX_PLAYER_HIT_FIST_18,
+ SFX_PLAYER_HIT_FIST_19,
+ SFX_PLAYER_HIT_FIST_20,
+ SFX_PLAYER_HIT_FIST_21,
+ SFX_PLAYER_HIT_FIST_22,
+ SFX_PLAYER_HIT_FIST_23,
+ SFX_PLAYER_HIT_FIST_24,
+ SFX_PLAYER_HIT_FIST_25,
+ SFX_PLAYER_HIT_FIST_26,
+ SFX_PLAYER_HIT_FIST_27,
+ SFX_PLAYER_HIT_FIST_28,
+ SFX_PLAYER_HIT_FIST_29,
+ SFX_PLAYER_HIT_FIST_30,
+ SFX_PLAYER_HIT_FIST_31,
+ SFX_PLAYER_HIT_FIST_32,
+ SFX_PLAYER_HIT_FIST_33,
+ SFX_PLAYER_HIT_FIST_34,
+ SFX_PLAYER_HIT_FIST_35,
+ SFX_PLAYER_HIT_FIST_36,
+ SFX_PLAYER_HIT_FIST_37,
+ SFX_PLAYER_HIT_FIST_38,
+ SFX_PLAYER_HIT_FIST_39,
+ SFX_PLAYER_HIT_FIST_40,
+ SFX_PLAYER_HIT_FIST_41,
+ SFX_PLAYER_HIT_FIST_42,
+ SFX_PLAYER_ON_FIRE_1,
+ SFX_PLAYER_ON_FIRE_2,
+ SFX_PLAYER_ON_FIRE_3,
+ SFX_PLAYER_ON_FIRE_4,
+ SFX_PLAYER_ON_FIRE_5,
+ SFX_PLAYER_ON_FIRE_6,
+ SFX_PLAYER_ON_FIRE_7,
+ SFX_PLAYER_ON_FIRE_8,
+ SFX_PLAYER_ON_FIRE_9,
+ SFX_PLAYER_ON_FIRE_10,
+ SFX_PLAYER_ON_FIRE_11,
+ SFX_PLAYER_ON_FIRE_12,
+ SFX_PLAYER_ON_FIRE_13,
+ SFX_PLAYER_ON_FIRE_14,
+ SFX_PLAYER_ON_FIRE_15,
+ SFX_PLAYER_ON_FIRE_16,
TOTAL_AUDIO_SAMPLES,
NO_SAMPLE,
// shorthands
SAMPLEBANK_START = SFX_CAR_HORN_JEEP,
- SAMPLEBANK_END = SFX_PAGER,
- SAMPLEBANK_MAX = SFX_PAGER + 1,
- SAMPLEBANK_PED_START = SFX_COP_VOICE_1_ARREST_1,
- SAMPLEBANK_PED_END = SFX_AMMU_F,
- SAMPLEBANK_PED_MAX = SFX_AMMU_F + 1,
+ SAMPLEBANK_END = SFX_FOOTSTEP_SAND_4,
+ SAMPLEBANK_MAX = SFX_FOOTSTEP_SAND_4 + 1,
+ SAMPLEBANK_PED_START = SFX_FOOTSTEP_SAND_4 + 1,
+ SAMPLEBANK_PED_END = 9940,
+ SAMPLEBANK_PED_MAX = SAMPLEBANK_PED_END + 1,
};
diff --git a/src/audio/AudioScriptObject.cpp b/src/audio/AudioScriptObject.cpp
index 03efdea9..ac4bebcb 100644
--- a/src/audio/AudioScriptObject.cpp
+++ b/src/audio/AudioScriptObject.cpp
@@ -93,6 +93,8 @@ cAudioScriptObject::SaveAllAudioScriptObjects(uint8 *buf, uint32 *size)
void
PlayOneShotScriptObject(uint8 id, CVector const &pos)
{
+ if (!DMAudio.IsAudioInitialised()) return;
+
cAudioScriptObject *audioScriptObject = new cAudioScriptObject();
audioScriptObject->Posn = pos;
audioScriptObject->AudioId = id;
diff --git a/src/audio/DMAudio.cpp b/src/audio/DMAudio.cpp
index 688da201..3843007d 100644
--- a/src/audio/DMAudio.cpp
+++ b/src/audio/DMAudio.cpp
@@ -63,9 +63,18 @@ cDMAudio::DestroyAllGameCreatedEntities(void)
}
void
-cDMAudio::SetMonoMode(bool8 mono)
+cDMAudio::SetOutputMode(bool8 surround)
{
- AudioManager.SetMonoMode(mono);
+ AudioManager.SetOutputMode(surround);
+}
+
+void
+cDMAudio::SetMP3BoostVolume(uint8 volume)
+{
+ uint8 vol = volume;
+ if (vol > MAX_VOLUME) vol = MAX_VOLUME;
+
+ AudioManager.SetMP3BoostVolume(vol);
}
void
@@ -116,6 +125,11 @@ cDMAudio::Get3DProviderName(uint8 id)
return AudioManager.Get3DProviderName(id);
}
+int8 cDMAudio::AutoDetect3DProviders(void)
+{
+ return AudioManager.AutoDetect3DProviders();
+}
+
int8
cDMAudio::GetCurrent3DProviderIndex(void)
{
@@ -236,13 +250,13 @@ cDMAudio::PlayFrontEndSound(uint16 frontend, uint32 volume)
}
void
-cDMAudio::PlayRadioAnnouncement(uint8 announcement)
+cDMAudio::PlayRadioAnnouncement(uint32 announcement)
{
MusicManager.PlayAnnouncement(announcement);
}
void
-cDMAudio::PlayFrontEndTrack(uint8 track, bool8 frontendFlag)
+cDMAudio::PlayFrontEndTrack(uint32 track, bool8 frontendFlag)
{
MusicManager.PlayFrontEndTrack(track, frontendFlag);
}
@@ -266,7 +280,7 @@ cDMAudio::ChangeMusicMode(uint8 mode)
}
void
-cDMAudio::PreloadCutSceneMusic(uint8 track)
+cDMAudio::PreloadCutSceneMusic(uint32 track)
{
MusicManager.PreloadCutSceneMusic(track);
}
@@ -284,39 +298,51 @@ cDMAudio::StopCutSceneMusic(void)
}
void
-cDMAudio::PreloadMissionAudio(Const char *missionAudio)
+cDMAudio::PreloadMissionAudio(uint8 slot, Const char *missionAudio)
{
- AudioManager.PreloadMissionAudio(missionAudio);
+ AudioManager.PreloadMissionAudio(slot, missionAudio);
}
uint8
-cDMAudio::GetMissionAudioLoadingStatus(void)
+cDMAudio::GetMissionAudioLoadingStatus(uint8 slot)
{
- return AudioManager.GetMissionAudioLoadingStatus();
+ return AudioManager.GetMissionAudioLoadingStatus(slot);
}
void
-cDMAudio::SetMissionAudioLocation(float x, float y, float z)
+cDMAudio::SetMissionAudioLocation(uint8 slot, float x, float y, float z)
{
- AudioManager.SetMissionAudioLocation(x, y, z);
+ AudioManager.SetMissionAudioLocation(slot, x, y, z);
}
void
-cDMAudio::PlayLoadedMissionAudio(void)
+cDMAudio::PlayLoadedMissionAudio(uint8 slot)
{
- AudioManager.PlayLoadedMissionAudio();
+ AudioManager.PlayLoadedMissionAudio(slot);
}
bool8
-cDMAudio::IsMissionAudioSampleFinished(void)
+cDMAudio::IsMissionAudioSamplePlaying(uint8 slot)
{
- return AudioManager.IsMissionAudioSampleFinished();
+ return AudioManager.IsMissionAudioSamplePlaying(slot);
+}
+
+bool8
+cDMAudio::IsMissionAudioSampleFinished(uint8 slot)
+{
+ return AudioManager.IsMissionAudioSampleFinished(slot);
}
void
-cDMAudio::ClearMissionAudio(void)
+cDMAudio::ClearMissionAudio(uint8 slot)
+{
+ AudioManager.ClearMissionAudio(slot);
+}
+
+const char *
+cDMAudio::GetMissionAudioLoadedLabel(uint8 slot)
{
- AudioManager.ClearMissionAudio();
+ return AudioManager.GetMissionAudioLoadedLabel(slot);
}
uint8
@@ -332,7 +358,49 @@ cDMAudio::SetRadioInCar(uint32 radio)
}
void
-cDMAudio::SetRadioChannel(uint8 radio, int32 pos)
+cDMAudio::SetRadioChannel(uint32 radio, int32 pos)
{
MusicManager.SetRadioChannelByScript(radio, pos);
}
+
+void
+cDMAudio::SetStartingTrackPositions(bool8 isStartGame)
+{
+ MusicManager.SetStartingTrackPositions(isStartGame);
+}
+
+float *
+cDMAudio::GetListenTimeArray()
+{
+ return MusicManager.GetListenTimeArray();
+}
+
+uint32
+cDMAudio::GetFavouriteRadioStation()
+{
+ return MusicManager.GetFavouriteRadioStation();
+}
+
+int32
+cDMAudio::GetRadioPosition(uint32 station)
+{
+ return MusicManager.GetRadioPosition(station);
+}
+
+void
+cDMAudio::SetPedTalkingStatus(CPed *ped, bool8 status)
+{
+ return AudioManager.SetPedTalkingStatus(ped, status);
+}
+
+void
+cDMAudio::SetPlayersMood(uint8 mood, uint32 time)
+{
+ return AudioManager.SetPlayersMood(mood, time);
+}
+
+void
+cDMAudio::ShutUpPlayerTalking(bool8 state)
+{
+ AudioManager.m_bIsPlayerShutUp = state;
+} \ No newline at end of file
diff --git a/src/audio/DMAudio.h b/src/audio/DMAudio.h
index 9f427272..110cb2db 100644
--- a/src/audio/DMAudio.h
+++ b/src/audio/DMAudio.h
@@ -7,6 +7,9 @@
#define AEHANDLE_IS_FAILED(h) ((h)<0)
#define AEHANDLE_IS_OK(h) ((h)>=0)
+#define NO_AUDIO_PROVIDER -3
+#define AUDIO_PROVIDER_NOT_DETERMINED -99
+
class cAudioScriptObject;
class CEntity;
@@ -27,7 +30,8 @@ public:
void PlayOneShot(int32 audioEntity, uint16 oneShot, float volume);
void DestroyAllGameCreatedEntities(void);
- void SetMonoMode(bool8 mono);
+ void SetOutputMode(bool8 surround);
+ void SetMP3BoostVolume(uint8 volume);
void SetEffectsMasterVolume(uint8 volume);
void SetMusicMasterVolume(uint8 volume);
void SetEffectsFadeVol(uint8 volume);
@@ -36,6 +40,8 @@ public:
uint8 GetNum3DProvidersAvailable(void);
char *Get3DProviderName(uint8 id);
+ int8 AutoDetect3DProviders(void);
+
int8 GetCurrent3DProviderIndex(void);
int8 SetCurrent3DProvider(uint8 which);
@@ -65,27 +71,37 @@ public:
void ReportCollision(CEntity *entityA, CEntity *entityB, uint8 surfaceTypeA, uint8 surfaceTypeB, float collisionPower, float velocity);
void PlayFrontEndSound(uint16 frontend, uint32 volume);
- void PlayRadioAnnouncement(uint8 announcement);
- void PlayFrontEndTrack(uint8 track, bool8 frontendFlag);
+ void PlayRadioAnnouncement(uint32 announcement);
+ void PlayFrontEndTrack(uint32 track, bool8 frontendFlag);
void StopFrontEndTrack(void);
void ResetTimers(uint32 time);
void ChangeMusicMode(uint8 mode);
- void PreloadCutSceneMusic(uint8 track);
+ void PreloadCutSceneMusic(uint32 track);
void PlayPreloadedCutSceneMusic(void);
void StopCutSceneMusic(void);
- void PreloadMissionAudio(Const char *missionAudio);
- uint8 GetMissionAudioLoadingStatus(void);
- void SetMissionAudioLocation(float x, float y, float z);
- void PlayLoadedMissionAudio(void);
- bool8 IsMissionAudioSampleFinished(void);
- void ClearMissionAudio(void);
+ void PreloadMissionAudio(uint8 slot, Const char *missionAudio);
+ uint8 GetMissionAudioLoadingStatus(uint8 slot);
+ void SetMissionAudioLocation(uint8 slot, float x, float y, float z);
+ void PlayLoadedMissionAudio(uint8 slot);
+ bool8 IsMissionAudioSamplePlaying(uint8 slot);
+ bool8 IsMissionAudioSampleFinished(uint8 slot);
+ void ClearMissionAudio(uint8 slot);
+ const char *GetMissionAudioLoadedLabel(uint8 slot);
uint8 GetRadioInCar(void);
void SetRadioInCar(uint32 radio);
- void SetRadioChannel(uint8 radio, int32 pos);
+ void SetRadioChannel(uint32 radio, int32 pos);
+
+ void SetStartingTrackPositions(bool8 isStartGame);
+ float *GetListenTimeArray();
+ uint32 GetFavouriteRadioStation();
+ int32 GetRadioPosition(uint32 station);
+ void SetPedTalkingStatus(class CPed *ped, bool8 status);
+ void SetPlayersMood(uint8 mood, uint32 time);
+ void ShutUpPlayerTalking(bool8 state);
};
extern cDMAudio DMAudio;
diff --git a/src/audio/MusicManager.cpp b/src/audio/MusicManager.cpp
index 9872589a..a099f10d 100644
--- a/src/audio/MusicManager.cpp
+++ b/src/audio/MusicManager.cpp
@@ -14,231 +14,127 @@
#include "Timer.h"
#include "World.h"
#include "sampman.h"
+#include "Stats.h"
+#include "Script.h"
+#include "ZoneCull.h"
+#include "Weather.h"
+#include "DMAudio.h"
+#include "GenericGameStorage.h"
#if !defined FIX_BUGS && (defined RADIO_SCROLL_TO_PREV_STATION || defined RADIO_OFF_TEXT)
-static_assert(false, "RADIO_SCROLL_TO_PREV_STATION and RADIO_OFF_TEXT won't work correctly without FIX_BUGS");
+static_assert(false, "R*'s radio implementation is quite buggy, RADIO_SCROLL_TO_PREV_STATION and RADIO_OFF_TEXT won't work without FIX_BUGS");
#endif
cMusicManager MusicManager;
int32 gNumRetunePresses;
int32 gRetuneCounter;
-bool8 bHasStarted;
+bool8 g_bAnnouncementReadPosAlready;
+uint8 RadioStaticCounter = 5;
+uint32 RadioStaticTimer;
+
+CVector vecRiotPosition(300.7f, -322.0f, 12.0f);
+
+uint32 NewGameRadioTimers[10] =
+{
+ 948160,
+ 452150,
+ 2438150,
+ 3538230,
+ 3513100,
+ 4246050,
+ 1418050,
+ 3178240,
+ 471210,
+ 0
+};
cMusicManager::cMusicManager()
{
m_bIsInitialised = FALSE;
m_bDisabled = FALSE;
- m_nMusicMode = MUSICMODE_DISABLED;
- m_nNextTrack = NO_TRACK;
+ m_nFrontendTrack = NO_TRACK;
m_nPlayingTrack = NO_TRACK;
- m_bFrontendTrackFinished = FALSE;
- m_bPlayInFrontend = FALSE;
+ m_nUpcomingMusicMode = MUSICMODE_DISABLED;
+ m_nMusicMode = MUSICMODE_DISABLED;
m_bSetNextStation = FALSE;
- m_nAnnouncement = NO_TRACK;
- m_bPreviousPlayerInCar = FALSE;
- m_bPlayerInCar = FALSE;
- m_bAnnouncementInProgress = FALSE;
- m_bVerifyAmbienceTrackStartedToPlay = FALSE;
- bHasStarted = FALSE;
-}
-bool8
-cMusicManager::PlayerInCar()
-{
- if(!FindPlayerVehicle())
- return FALSE;
-
- int32 State = FindPlayerPed()->m_nPedState;
-
- if(State == PED_DRAG_FROM_CAR || State == PED_EXIT_CAR || State == PED_ARRESTED)
- return FALSE;
+ for (int i = 0; i < NUM_RADIOS; i++)
+ aListenTimeArray[i] = 0.0f;
- if (!FindPlayerVehicle())
- return TRUE;
-
- if (FindPlayerVehicle()->GetStatus() == STATUS_WRECKED)
- return FALSE;
-
- switch (FindPlayerVehicle()->GetModelIndex()) {
- case MI_FIRETRUCK:
- case MI_AMBULAN:
- case MI_MRWHOOP:
- case MI_PREDATOR:
- case MI_TRAIN:
- case MI_SPEEDER:
- case MI_REEFER:
- case MI_GHOST: return FALSE;
- default: return TRUE;
- }
+ m_nLastTrackServiceTime = 0.0f;
+ m_nVolumeLatency = 0;
+ m_nCurrentVolume = 0;
+ m_nMaxVolume = 0;
+ m_nAnnouncement = NO_TRACK;
+ m_bAnnouncementInProgress = FALSE;
}
void
-cMusicManager::DisplayRadioStationName()
+cMusicManager::ResetMusicAfterReload()
{
- int8 pRetune;
- int8 gStreamedSound;
- int8 gRetuneCounter;
- static wchar *pCurrentStation = nil;
- static uint8 cDisplay = 0;
-
- if(!CTimer::GetIsPaused() && !TheCamera.m_WideScreenOn && PlayerInCar() &&
- !CReplay::IsPlayingBack()) {
- if(m_bPlayerInCar && !m_bPreviousPlayerInCar)
- pCurrentStation = nil;
-
-#ifdef FIX_BUGS
- const int curRadio = GetCarTuning();
-#else
- const int curRadio = m_nNextTrack;
-#endif
-
-#ifdef RADIO_SCROLL_TO_PREV_STATION
- if(gNumRetunePresses < 0) {
- gStreamedSound = curRadio;
-
- gRetuneCounter = gNumRetunePresses;
- pRetune = gStreamedSound;
-
- while(gRetuneCounter < 0) {
- if(pRetune == HEAD_RADIO) {
- pRetune = RADIO_OFF;
- } else if(pRetune == RADIO_OFF || pRetune == NUM_RADIOS) {
- pRetune = SampleManager.IsMP3RadioChannelAvailable() ? USERTRACK : USERTRACK - 1;
- } else
- pRetune--;
+ float afRadioTime[NUM_RADIOS];
- ++gRetuneCounter;
- }
- } else
-#endif
- if(SampleManager.IsMP3RadioChannelAvailable()) {
- gStreamedSound = curRadio;
-
- if(gStreamedSound == STREAMED_SOUND_CITY_AMBIENT ||
- gStreamedSound == STREAMED_SOUND_WATER_AMBIENT) { // which means OFF
- gStreamedSound = NUM_RADIOS;
- } else if(gStreamedSound > STREAMED_SOUND_RADIO_MP3_PLAYER)
- return;
-
- pRetune = gNumRetunePresses + gStreamedSound;
-
-#ifdef FIX_BUGS
- while(pRetune > NUM_RADIOS)
- pRetune -= (NUM_RADIOS + 1);
-#endif
- if(pRetune == NUM_RADIOS) {
- pRetune = RADIO_OFF;
- }
-#ifndef FIX_BUGS
- else if(pRetune > NUM_RADIOS) {
- pRetune = pRetune - (NUM_RADIOS + 1);
- }
-#endif
- } else {
- gStreamedSound = curRadio;
- pRetune = gNumRetunePresses + gStreamedSound;
-
- if(pRetune >= USERTRACK) {
- gRetuneCounter = gNumRetunePresses;
- pRetune = curRadio;
-
- if(gStreamedSound == STREAMED_SOUND_WATER_AMBIENT)
- pRetune = STREAMED_SOUND_CITY_AMBIENT; // which is RADIO_OFF
-
- while(gRetuneCounter) {
- if(pRetune == RADIO_OFF) {
- pRetune = HEAD_RADIO;
- } else if(pRetune < USERTRACK) {
- pRetune = pRetune + 1;
- }
- if(pRetune == USERTRACK) pRetune = RADIO_OFF;
-
- --gRetuneCounter;
- }
- }
- }
+ m_bRadioSetByScript = FALSE;
+ m_nRadioStationScript = WILDSTYLE;
+ m_nRadioPosition = -1;
+ m_nAnnouncement = NO_TRACK;
+ m_bAnnouncementInProgress = FALSE;
+ m_bSetNextStation = FALSE;
+ RadioStaticTimer = 0;
+ gNumRetunePresses = 0;
+ gRetuneCounter = 0;
+ m_nFrontendTrack = NO_TRACK;
+ m_nPlayingTrack = NO_TRACK;
+ m_FrontendLoopFlag = FALSE;
+ m_bTrackChangeStarted = FALSE;
+ m_nNextTrack = NO_TRACK;
+ m_nNextLoopFlag = FALSE;
+ m_bVerifyNextTrackStartedToPlay = FALSE;
+ m_bGameplayAllowsRadio = FALSE;
+ m_bRadioStreamReady = FALSE;
+ nFramesSinceCutsceneEnded = -1;
+ m_bUserResumedGame = FALSE;
+ m_bMusicModeChangeStarted = FALSE;
+ m_bEarlyFrontendTrack = FALSE;
+ m_nVolumeLatency = 0;
+ m_nCurrentVolume = 0;
+ m_nMaxVolume = 0;
+
+ bool8 bRadioWasEverListened = FALSE;
+
+ for (int i = 0; i < NUM_RADIOS; i++) {
+ afRadioTime[i] = CStats::GetFavoriteRadioStationList(i);
+ if (!bRadioWasEverListened && afRadioTime[i] != 0.0f)
+ bRadioWasEverListened = TRUE;
+ }
- wchar *string;
-
- switch(pRetune) {
- case HEAD_RADIO: string = TheText.Get("FEA_FM0"); break;
- case DOUBLE_CLEF: string = TheText.Get("FEA_FM1"); break;
- case JAH_RADIO: string = TheText.Get("FEA_FM2"); break;
- case RISE_FM: string = TheText.Get("FEA_FM3"); break;
- case LIPS_106: string = TheText.Get("FEA_FM4"); break;
- case GAME_FM: string = TheText.Get("FEA_FM5"); break;
- case MSX_FM: string = TheText.Get("FEA_FM6"); break;
- case FLASHBACK: string = TheText.Get("FEA_FM7"); break;
- case CHATTERBOX: string = TheText.Get("FEA_FM8"); break;
- case USERTRACK:
- if (!SampleManager.IsMP3RadioChannelAvailable())
- return;
- string = TheText.Get("FEA_FM9"); break;
-#ifdef RADIO_OFF_TEXT
- case RADIO_OFF: {
- extern wchar WideErrorString[];
+ if (!bRadioWasEverListened) return;
- string = TheText.Get("FEA_FMN");
- if(string == WideErrorString) {
- pCurrentStation = nil;
- return;
+ for (int i = 0; i < NUM_RADIOS; i++) {
+ aListenTimeArray[i] = afRadioTime[i];
+ int32 trackPos = GetSavedRadioStationPosition(i);
+ if (trackPos != -1) {
+ if (trackPos > m_aTracks[i].m_nLength) {
+ debug("Radio Track %d saved position is %d, Length is only %d\n", i, trackPos, m_aTracks[i].m_nLength);
+ trackPos %= m_aTracks[i].m_nLength;
}
- break;
- }
-#endif
- default: return;
- };
-
- if(pCurrentStation != string ||
- m_nNextTrack == STREAMED_SOUND_RADIO_MP3_PLAYER && m_nPlayingTrack != STREAMED_SOUND_RADIO_MP3_PLAYER) {
- pCurrentStation = string;
- cDisplay = 60;
- } else {
- if(cDisplay == 0) return;
-#ifdef FIX_BUGS
- cDisplay -= CTimer::GetLogicalFramesPassed();
-#else
- cDisplay--;
-#endif
+ m_aTracks[i].m_nPosition = trackPos;
+ m_aTracks[i].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
}
-
- CFont::SetJustifyOff();
- CFont::SetBackgroundOff();
- CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f));
- CFont::SetPropOn();
- CFont::SetFontStyle(FONT_HEADING);
- CFont::SetCentreOn();
- // Reminder: Game doesn't have "scaling" at all, it just stretches, and it's team's decision here to not let centered text occupy all the screen.
- // Disable ASPECT_RATIO_SCALE and it'll go back to default behaviour; stretching.
- CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH));
- CFont::SetColor(CRGBA(0, 0, 0, 255));
-#ifdef FIX_BUGS
- CFont::PrintString(SCREEN_WIDTH / 2 + SCREEN_SCALE_X(2.0f), SCREEN_SCALE_Y(22.0f) + SCREEN_SCALE_Y(2.0f), pCurrentStation);
-#else
- CFont::PrintString(SCREEN_WIDTH / 2 + 2.0f, SCREEN_SCALE_Y(22.0f) + 2.0f, pCurrentStation);
-#endif
-
- if(gNumRetunePresses)
- CFont::SetColor(CRGBA(102, 133, 143, 255));
- else
- CFont::SetColor(CRGBA(147, 196, 211, 255));
-
- CFont::PrintString(SCREEN_WIDTH / 2, SCREEN_SCALE_Y(22.0f), pCurrentStation);
- CFont::DrawFonts();
}
}
-bool8
-cMusicManager::Initialise()
+void
+cMusicManager::SetStartingTrackPositions(bool8 isNewGameTimer)
{
int pos;
- if (!IsInitialised()) {
+ if (IsInitialised()) {
time_t timevalue = time(0);
if (timevalue == -1) {
pos = AudioManager.m_anRandomTable[0];
} else {
- tm *pTm = localtime(&timevalue);
+ tm* pTm = localtime(&timevalue);
if (pTm->tm_sec == 0)
pTm->tm_sec = AudioManager.m_anRandomTable[0];
if (pTm->tm_min == 0)
@@ -265,22 +161,52 @@ cMusicManager::Initialise()
for (int i = 0; i < TOTAL_STREAMED_SOUNDS; i++) {
m_aTracks[i].m_nLength = SampleManager.GetStreamedFileLength(i);
- m_aTracks[i].m_nPosition = pos * AudioManager.m_anRandomTable[i % 5] % m_aTracks[i].m_nLength;
+
+ if (i < STREAMED_SOUND_CITY_AMBIENT && isNewGameTimer)
+ m_aTracks[i].m_nPosition = NewGameRadioTimers[i];
+ else if (i < STREAMED_SOUND_ANNOUNCE_BRIDGE_CLOSED)
+ m_aTracks[i].m_nPosition = (pos * AudioManager.m_anRandomTable[i % 5]) % m_aTracks[i].m_nLength;
+ else
+ m_aTracks[i].m_nPosition = 0;
+
m_aTracks[i].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
}
+ }
+}
+bool8
+cMusicManager::Initialise()
+{
+ if (!IsInitialised()) {
+ m_bIsInitialised = TRUE;
+ SetStartingTrackPositions(FALSE);
m_bResetTimers = FALSE;
m_nResetTime = 0;
- m_nTimer = m_nLastTrackServiceTime = CTimer::GetTimeInMillisecondsPauseMode();
- m_bDoTrackService = FALSE;
- m_bIgnoreTimeDelay = FALSE;
m_bRadioSetByScript = FALSE;
- m_nRadioStationScript = HEAD_RADIO;
+ m_nRadioStationScript = WILDSTYLE;
m_nRadioPosition = -1;
m_nRadioInCar = NO_TRACK;
- gNumRetunePresses = 0;
gRetuneCounter = 0;
- m_bIsInitialised = TRUE;
+ gNumRetunePresses = 0;
+ m_nFrontendTrack = NO_TRACK;
+ m_nPlayingTrack = NO_TRACK;
+ m_nUpcomingMusicMode = MUSICMODE_DISABLED;
+ m_nMusicMode = MUSICMODE_DISABLED;
+ m_FrontendLoopFlag = FALSE;
+ m_bTrackChangeStarted = FALSE;
+ m_nNextTrack = NO_TRACK;
+ m_nNextLoopFlag = FALSE;
+ m_bVerifyNextTrackStartedToPlay = FALSE;
+ m_bGameplayAllowsRadio = FALSE;
+ m_bRadioStreamReady = FALSE;
+ nFramesSinceCutsceneEnded = -1;
+ m_bUserResumedGame = FALSE;
+ m_bMusicModeChangeStarted = FALSE;
+ m_nMusicModeToBeSet = MUSICMODE_DISABLED;
+ m_bEarlyFrontendTrack = FALSE;
+ m_nVolumeLatency = 0;
+ m_nCurrentVolume = 0;
+ m_nMaxVolume = 0;
}
return m_bIsInitialised;
}
@@ -292,81 +218,56 @@ cMusicManager::Terminate()
if (SampleManager.IsStreamPlaying()) {
SampleManager.StopStreamedFile();
- m_nNextTrack = NO_TRACK;
m_nPlayingTrack = NO_TRACK;
}
m_bIsInitialised = FALSE;
}
void
-cMusicManager::ChangeMusicMode(uint8 mode)
+cMusicManager::SetRadioChannelByScript(uint32 station, int32 pos)
{
- if (!IsInitialised()) return;
-
- uint8 mode2;
- switch (mode)
- {
- case MUSICMODE_FRONTEND:
- mode2 = MUSICMODE_FRONTEND;
-#ifdef PAUSE_RADIO_IN_FRONTEND
- // rewind those streams we weren't listening right now
- for (uint32 i = STREAMED_SOUND_RADIO_HEAD; i < STREAMED_SOUND_CUTSCENE_LUIGI1_LG; i++) {
- m_aTracks[i].m_nPosition = GetTrackStartPos(i);
- m_aTracks[i].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
+ if (m_bIsInitialised) {
+ if (station == STREAMED_SOUND_RADIO_MP3_PLAYER)
+ station = STREAMED_SOUND_CITY_AMBIENT;
+ if (station <= STREAMED_SOUND_RADIO_POLICE) {
+ m_bRadioSetByScript = TRUE;
+ m_nRadioStationScript = station;
+ m_nRadioPosition = pos == -1 ? -1 : pos % m_aTracks[station].m_nLength;
}
-#endif
- break;
- case MUSICMODE_GAME: mode2 = MUSICMODE_GAME; break;
- case MUSICMODE_CUTSCENE: mode2 = MUSICMODE_CUTSCENE; break;
- case MUSICMODE_DISABLE: mode2 = MUSICMODE_DISABLED; break;
- default: return;
}
+}
- if (mode2 != m_nMusicMode || mode == MUSICMODE_FRONTEND && mode2 == MUSICMODE_FRONTEND) {
- switch (mode)
- {
- case MUSICMODE_FRONTEND:
- case MUSICMODE_GAME:
- case MUSICMODE_CUTSCENE:
- case MUSICMODE_DISABLED:
- if (SampleManager.IsStreamPlaying()) {
- if (m_nNextTrack < TOTAL_STREAMED_SOUNDS) {
- m_aTracks[m_nNextTrack].m_nPosition = SampleManager.GetStreamedFilePosition();
- m_aTracks[m_nNextTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
- }
- SampleManager.StopStreamedFile();
- }
- m_nNextTrack = NO_TRACK;
- m_nPlayingTrack = NO_TRACK;
- m_bFrontendTrackFinished = FALSE;
- m_bPlayInFrontend = FALSE;
- m_bSetNextStation = FALSE;
- m_bPreviousPlayerInCar = FALSE;
- m_bPlayerInCar = FALSE;
- m_bAnnouncementInProgress = FALSE;
- m_nTimer = m_nLastTrackServiceTime = CTimer::GetTimeInMillisecondsPauseMode();
- m_bDoTrackService = FALSE;
- m_bIgnoreTimeDelay = TRUE;
- m_bVerifyAmbienceTrackStartedToPlay = FALSE;
- m_nMusicMode = mode2;
- break;
- default: return;
- }
- }
+bool8
+cMusicManager::PlayerInCar()
+{
+ CVehicle *vehicle = AudioManager.FindVehicleOfPlayer();
+ if(!vehicle)
+ return FALSE;
+
+ int32 State = FindPlayerPed()->m_nPedState;
+
+ if(State == PED_DRAG_FROM_CAR || State == PED_EXIT_CAR || State == PED_ARRESTED)
+ return FALSE;
+
+ if (vehicle->GetStatus() == STATUS_WRECKED)
+ return FALSE;
+
+ return TRUE;
}
-uint8
+uint32
cMusicManager::GetRadioInCar(void)
{
- if (!m_bIsInitialised) return HEAD_RADIO;
+ if (!m_bIsInitialised) return WILDSTYLE;
if (PlayerInCar()) {
- CVehicle *veh = FindPlayerVehicle();
- if (veh != nil){
- if (UsesPoliceRadio(veh)) {
+ CVehicle* veh = AudioManager.FindVehicleOfPlayer();
+ if (veh != nil) {
+ if (UsesPoliceRadio(veh) || UsesTaxiRadio(veh)) {
if (m_nRadioInCar == NO_TRACK || (CReplay::IsPlayingBack() && AudioManager.m_nUserPause == 0))
- return POLICE_RADIO;
+ return STREAMED_SOUND_RADIO_POLICE;
return m_nRadioInCar;
- } else return veh->m_nRadioStation;
+ }
+ else return veh->m_nRadioStation;
}
}
@@ -383,9 +284,9 @@ cMusicManager::SetRadioInCar(uint32 station)
m_nRadioInCar = station;
return;
}
- CVehicle *veh = FindPlayerVehicle();
+ CVehicle* veh = AudioManager.FindVehicleOfPlayer();
if (veh == nil) return;
- if (UsesPoliceRadio(veh))
+ if (UsesPoliceRadio(veh) || UsesTaxiRadio(veh))
m_nRadioInCar = station;
else
veh->m_nRadioStation = station;
@@ -393,29 +294,63 @@ cMusicManager::SetRadioInCar(uint32 station)
}
void
-cMusicManager::SetRadioChannelByScript(uint8 station, int32 pos)
+cMusicManager::RecordRadioStats()
{
- if (m_bIsInitialised && station < RADIO_OFF) {
- m_bRadioSetByScript = TRUE;
- m_nRadioStationScript = station;
- m_nRadioPosition = pos == -1 ? -1 : pos % m_aTracks[station].m_nLength;
+ if (m_nPlayingTrack < NUM_RADIOS) {
+ double time /*Rusty*/ = CTimer::GetTimeInMillisecondsPauseMode();
+ if (time > m_nLastTrackServiceTime)
+ aListenTimeArray[m_nPlayingTrack] += time - m_nLastTrackServiceTime;
}
}
-
void
-cMusicManager::ResetMusicAfterReload()
+cMusicManager::ChangeMusicMode(uint8 mode)
{
- m_bRadioSetByScript = FALSE;
- m_nRadioStationScript = 0;
- m_nRadioPosition = -1;
- m_nAnnouncement = NO_TRACK;
- m_bAnnouncementInProgress = FALSE;
- m_bSetNextStation = FALSE;
- gRetuneCounter = 0;
- gNumRetunePresses = 0;
-}
+ if (!IsInitialised()) return;
+
+ switch (mode)
+ {
+ case MUSICMODE_FRONTEND:
+ m_nUpcomingMusicMode = MUSICMODE_FRONTEND;
+#ifdef PAUSE_RADIO_IN_FRONTEND
+ // rewind those streams we weren't listening right now
+ for( uint32 i = STREAMED_SOUND_RADIO_WILD; i < STREAMED_SOUND_CUTSCENE_ASS_1; i++ ) {
+ m_aTracks[i].m_nPosition = GetTrackStartPos(i);
+ m_aTracks[i].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
+ }
+#endif
+
+ break;
+ case MUSICMODE_GAME: m_nUpcomingMusicMode = MUSICMODE_GAME; break;
+ case MUSICMODE_CUTSCENE:
+ m_nUpcomingMusicMode = MUSICMODE_CUTSCENE;
+ if (SampleManager.IsStreamPlaying()) {
+ if (m_nPlayingTrack != NO_TRACK) {
+ RecordRadioStats();
+ m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition();
+ m_aTracks[m_nPlayingTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
+ }
+ }
+ SampleManager.StopStreamedFile();
+ while (SampleManager.IsStreamPlaying())
+ SampleManager.StopStreamedFile();
+ m_nMusicMode = m_nUpcomingMusicMode;
+ m_bMusicModeChangeStarted = FALSE;
+ m_bTrackChangeStarted = FALSE;
+ m_nNextTrack = NO_TRACK;
+ m_nNextLoopFlag = FALSE;
+ m_bVerifyNextTrackStartedToPlay = FALSE;
+ m_nPlayingTrack = NO_TRACK;
+ m_nFrontendTrack = NO_TRACK;
+ m_bAnnouncementInProgress = FALSE;
+ m_nAnnouncement = NO_TRACK;
+ g_bAnnouncementReadPosAlready = FALSE;
+ break;
+ case MUSICMODE_DISABLE: m_nUpcomingMusicMode = MUSICMODE_DISABLED; break;
+ default: return;
+ }
+}
void
cMusicManager::ResetTimers(int32 time)
@@ -432,338 +367,724 @@ cMusicManager::Service()
m_nLastTrackServiceTime = m_nResetTime;
}
- if (!m_bIsInitialised || m_bDisabled) return;
-
- if (m_nMusicMode == MUSICMODE_CUTSCENE) {
- SampleManager.SetStreamedVolumeAndPan(MAX_VOLUME, 63, TRUE);
- return;
- }
+ static bool8 bRadioStatsRecorded = FALSE;
- m_nTimer = CTimer::GetTimeInMillisecondsPauseMode();
- if (m_nTimer > (m_nLastTrackServiceTime + 2000) || m_bIgnoreTimeDelay) {
- m_bIgnoreTimeDelay = FALSE;
- m_bDoTrackService = TRUE;
- m_nLastTrackServiceTime = m_nTimer;
- } else m_bDoTrackService = FALSE;
+ if (!m_bIsInitialised || m_bDisabled) return;
- if (m_nNextTrack == NO_TRACK && SampleManager.IsStreamPlaying())
- SampleManager.StopStreamedFile();
- else switch (m_nMusicMode) {
- case MUSICMODE_FRONTEND: ServiceFrontEndMode(); break;
- case MUSICMODE_GAME: ServiceGameMode(); break;
+ if (!m_bMusicModeChangeStarted)
+ m_nMusicModeToBeSet = m_nUpcomingMusicMode;
+ if (m_nMusicModeToBeSet == m_nMusicMode) {
+ if (!AudioManager.m_nUserPause || AudioManager.m_nPreviousUserPause || m_nMusicMode != MUSICMODE_FRONTEND)
+ {
+ switch (m_nMusicMode)
+ {
+ case MUSICMODE_FRONTEND: ServiceFrontEndMode(); break;
+ case MUSICMODE_GAME: ServiceGameMode(); break;
+ case MUSICMODE_CUTSCENE: SampleManager.SetStreamedVolumeAndPan(MAX_VOLUME, 63, TRUE); break;
+ }
}
+ else
+ m_nMusicMode = MUSICMODE_DISABLED;
+ } else {
+ m_bMusicModeChangeStarted = TRUE;
+ if (!m_bUserResumedGame && !AudioManager.m_nUserPause && AudioManager.m_nPreviousUserPause)
+ m_bUserResumedGame = TRUE;
+ if (AudioManager.m_FrameCounter % 4 == 0) {
+ gNumRetunePresses = 0;
+ gRetuneCounter = 0;
+ m_bSetNextStation = FALSE;
+ if (SampleManager.IsStreamPlaying()) {
+ if (m_nPlayingTrack != NO_TRACK && !bRadioStatsRecorded)
+ {
+ RecordRadioStats();
+ m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition();
+ m_aTracks[m_nPlayingTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
+ bRadioStatsRecorded = TRUE;
+ }
+ SampleManager.StopStreamedFile();
+ } else {
+ bRadioStatsRecorded = FALSE;
+ m_nMusicMode = m_nMusicModeToBeSet;
+ m_bMusicModeChangeStarted = FALSE;
+ m_bTrackChangeStarted = FALSE;
+ m_nNextTrack = NO_TRACK;
+ m_nNextLoopFlag = FALSE;
+ m_bVerifyNextTrackStartedToPlay = FALSE;
+ m_nPlayingTrack = NO_TRACK;
+ if (m_bEarlyFrontendTrack)
+ m_bEarlyFrontendTrack = FALSE;
+ else
+ m_nFrontendTrack = NO_TRACK;
+ }
+ }
+ }
}
void
cMusicManager::ServiceFrontEndMode()
{
+ static bool8 bRadioStatsRecorded = FALSE;
+
#ifdef PAUSE_RADIO_IN_FRONTEND
// pause radio
- for (uint32 i = STREAMED_SOUND_RADIO_HEAD; i < STREAMED_SOUND_CUTSCENE_LUIGI1_LG; i++)
+ for (uint32 i = STREAMED_SOUND_RADIO_WILD; i < STREAMED_SOUND_CUTSCENE_ASS_1; i++)
m_aTracks[i].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
#endif
- if (m_nNextTrack < TOTAL_STREAMED_SOUNDS) {
- if (m_bFrontendTrackFinished) {
- if (!SampleManager.IsStreamPlaying()) {
- switch (m_nNextTrack)
- {
- case STREAMED_SOUND_MISSION_COMPLETED:
- if (!AudioManager.m_nUserPause)
- ChangeMusicMode(MUSICMODE_GAME);
- break;
- case STREAMED_SOUND_GAME_COMPLETED:
- ChangeMusicMode(MUSICMODE_GAME);
- break;
- default:
- break;
+ if (m_bAnnouncementInProgress) {
+ SampleManager.StopStreamedFile();
+ if (SampleManager.IsStreamPlaying())
+ return;
+ g_bAnnouncementReadPosAlready = FALSE;
+ m_nAnnouncement = NO_TRACK;
+ m_bAnnouncementInProgress = FALSE;
+ m_nNextTrack = NO_TRACK;
+ m_nFrontendTrack = NO_TRACK;
+ m_nPlayingTrack = NO_TRACK;
+ }
+
+ if (AudioManager.m_FrameCounter % 4 != 0) return;
+
+ if (!m_bTrackChangeStarted && !m_bVerifyNextTrackStartedToPlay) {
+ m_nNextTrack = m_nFrontendTrack;
+ m_nNextLoopFlag = m_FrontendLoopFlag;
+ }
+
+ if (m_nNextTrack == m_nPlayingTrack) {
+ if (SampleManager.IsStreamPlaying()) {
+ if (m_nVolumeLatency > 0) m_nVolumeLatency--;
+ else {
+ if (m_nCurrentVolume < m_nMaxVolume)
+ m_nCurrentVolume = Min(m_nMaxVolume, m_nCurrentVolume + 6);
+ SampleManager.SetStreamedVolumeAndPan(m_nCurrentVolume, 63, FALSE);
+ }
+ } else {
+ if (m_nPlayingTrack == STREAMED_SOUND_RADIO_MP3_PLAYER)
+ SampleManager.StartStreamedFile(STREAMED_SOUND_RADIO_MP3_PLAYER, 0);
+ else if (m_nPlayingTrack == STREAMED_SOUND_MISSION_COMPLETED && AudioManager.m_nUserPause == 0)
+ ChangeMusicMode(MUSICMODE_GAME);
+ }
+ } else {
+ m_bTrackChangeStarted = TRUE;
+ if (m_bVerifyNextTrackStartedToPlay || !SampleManager.IsStreamPlaying()) {
+ bRadioStatsRecorded = FALSE;
+ if (SampleManager.IsStreamPlaying() || m_nNextTrack == NO_TRACK) {
+ m_nPlayingTrack = m_nNextTrack;
+ m_bVerifyNextTrackStartedToPlay = FALSE;
+ m_bTrackChangeStarted = FALSE;
+ } else {
+ uint32 trackStartPos = (m_nNextTrack > STREAMED_SOUND_RADIO_POLICE) ? 0 : GetTrackStartPos(m_nNextTrack);
+ if (m_nNextTrack != NO_TRACK) {
+ SampleManager.SetStreamedFileLoopFlag(m_nNextLoopFlag);
+ SampleManager.StartStreamedFile(m_nNextTrack, trackStartPos);
+ m_nVolumeLatency = 3;
+ m_nCurrentVolume = 0;
+ m_nMaxVolume = 100;
+ SampleManager.SetStreamedVolumeAndPan(m_nCurrentVolume, 63, FALSE);
+ if (m_nNextTrack < STREAMED_SOUND_CITY_AMBIENT)
+ m_nLastTrackServiceTime = CTimer::GetTimeInMillisecondsPauseMode();
+ m_bVerifyNextTrackStartedToPlay = TRUE;
}
- m_nNextTrack = NO_TRACK;
- m_nPlayingTrack = NO_TRACK;
}
- } else if (bHasStarted) {
- if (!SampleManager.IsStreamPlaying())
- SampleManager.StartStreamedFile(m_nNextTrack, 0);
} else {
+ if (m_nPlayingTrack != NO_TRACK && !bRadioStatsRecorded) {
+ m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition();
+ m_aTracks[m_nPlayingTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
+ RecordRadioStats();
+ bRadioStatsRecorded = TRUE;
+ }
SampleManager.SetStreamedVolumeAndPan(0, 63, FALSE);
- if (!SampleManager.StartStreamedFile(m_nNextTrack, m_nNextTrack < NUM_RADIOS ? GetTrackStartPos(m_nNextTrack) : 0))
- return;
- SampleManager.SetStreamedVolumeAndPan(100, 63, FALSE);
- if (m_bPlayInFrontend) bHasStarted = TRUE;
- else m_bFrontendTrackFinished = TRUE;
+ SampleManager.StopStreamedFile();
}
}
- if (SampleManager.IsStreamPlaying())
- SampleManager.SetStreamedVolumeAndPan((CPad::GetPad(0)->bDisplayNoControllerMessage || CPad::GetPad(0)->bObsoleteControllerMessage) ? 0 : 100, 63, FALSE);
}
void
cMusicManager::ServiceGameMode()
{
- bool8 bRadioOff = FALSE;
- static int8 nFramesSinceCutsceneEnded = -1;
- uint8 volume;
+ CPed *ped = FindPlayerPed();
+ CVehicle *vehicle = AudioManager.FindVehicleOfPlayer();
+ m_bRadioStreamReady = m_bGameplayAllowsRadio;
+ m_bGameplayAllowsRadio = FALSE;
- m_bPreviousPlayerInCar = m_bPlayerInCar;
- m_bPlayerInCar = PlayerInCar();
- m_nPlayingTrack = m_nNextTrack;
- if (m_bPlayerInCar) {
- if (FindPlayerPed() != nil
- && !FindPlayerPed()->DyingOrDead()
- && !CReplay::IsPlayingBack()
- && FindPlayerVehicle() != nil
- && !UsesPoliceRadio(FindPlayerVehicle())) {
-
- if (CPad::GetPad(0)->ChangeStationJustDown()) {
- gRetuneCounter = 30;
- gNumRetunePresses++;
- AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_FRONTEND_RADIO_CHANGE, 1.0f);
- // This needs loop, and this is not the right place. Now done elsewhere.
-#ifndef FIX_BUGS
- if (SampleManager.IsMP3RadioChannelAvailable()) {
- if (gNumRetunePresses > RADIO_OFF)
- gNumRetunePresses -= RADIO_OFF;
+ switch (CGame::currArea)
+ {
+ case AREA_HOTEL:
+ case AREA_MALL:
+ case AREA_STRIP_CLUB:
+ case AREA_DIRT:
+ case AREA_BLOOD:
+ case AREA_OVALRING:
+ case AREA_MALIBU_CLUB:
+ m_bGameplayAllowsRadio = FALSE;
+ break;
+ default:
+ if (SampleManager.GetMusicVolume()) {
+ if (PlayerInCar())
+ m_bGameplayAllowsRadio = TRUE;
+ } else
+ m_bGameplayAllowsRadio = FALSE;
+ break;
+ }
+
+ if (!m_bGameplayAllowsRadio) {
+ nFramesSinceCutsceneEnded = -1;
+ gNumRetunePresses = 0;
+ gRetuneCounter = 0;
+ m_bSetNextStation = FALSE;
+ } else if (ped) {
+ if(!ped->DyingOrDead() && vehicle) {
+#ifdef GTA_PC
+ if (SampleManager.IsMP3RadioChannelAvailable()
+ && vehicle->m_nRadioStation < USERTRACK
+ && ControlsManager.GetIsKeyboardKeyJustDown(rsF9))
+ {
+ if (!UsesPoliceRadio(vehicle) && !UsesTaxiRadio(vehicle)) {
+ gNumRetunePresses = 0;
+ gRetuneCounter = 20;
+ RadioStaticCounter = 0;
+ if (vehicle->m_nRadioStation < USERTRACK)
+ {
+ do
+ ++gNumRetunePresses;
+ while (gNumRetunePresses + vehicle->m_nRadioStation < USERTRACK);
}
+ }
+ }
#endif
+ if (CPad::GetPad(0)->ChangeStationJustDown())
+ {
+ if (!UsesPoliceRadio(vehicle) && !UsesTaxiRadio(vehicle)) {
+ gNumRetunePresses++;
+ gRetuneCounter = 20;
+ RadioStaticCounter = 0;
}
+ }
#ifdef RADIO_SCROLL_TO_PREV_STATION
- else if(!CPad::GetPad(0)->ArePlayerControlsDisabled() && (CPad::GetPad(0)->GetMouseWheelDownJustDown() || CPad::GetPad(0)->GetMouseWheelUpJustDown())) {
+ else if(!CPad::GetPad(0)->ArePlayerControlsDisabled() && (CPad::GetPad(0)->GetMouseWheelDownJustDown() || CPad::GetPad(0)->GetMouseWheelUpJustDown())) {
+ if(!UsesPoliceRadio(vehicle) && !UsesTaxiRadio(vehicle)) {
int scrollNext = ControlsManager.GetControllerKeyAssociatedWithAction(VEHICLE_CHANGE_RADIO_STATION, MOUSE);
- int scrollPrev = scrollNext == rsMOUSEWHEELUPBUTTON ? rsMOUSEWHEELDOWNBUTTON : scrollNext == rsMOUSEWHEELDOWNBUTTON ? rsMOUSEWHEELUPBUTTON : -1;
+ int scrollPrev = scrollNext == rsMOUSEWHEELUPBUTTON ? rsMOUSEWHEELDOWNBUTTON
+ : scrollNext == rsMOUSEWHEELDOWNBUTTON ? rsMOUSEWHEELUPBUTTON : -1;
- if (scrollPrev != -1 && !ControlsManager.IsAnyVehicleActionAssignedToMouseKey(scrollPrev)) {
- gRetuneCounter = 30;
+ if(scrollPrev != -1 && !ControlsManager.IsAnyVehicleActionAssignedToMouseKey(scrollPrev)) {
gNumRetunePresses--;
- AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_FRONTEND_RADIO_CHANGE, 1.0f);
+ gRetuneCounter = 20;
+ RadioStaticCounter = 0;
+ int track = gNumRetunePresses + vehicle->m_nRadioStation;
+ while(track < 0) track += NUM_RADIOS + 1;
+ while(track >= NUM_RADIOS + 1) track -= NUM_RADIOS + 1;
+ if(!DMAudio.IsMP3RadioChannelAvailable() && track == USERTRACK) gNumRetunePresses--;
}
}
+ }
#endif
}
- } else {
- nFramesSinceCutsceneEnded = -1;
}
- if (AudioManager.m_nPreviousUserPause)
- m_bPreviousPlayerInCar = FALSE;
- if (!m_bPlayerInCar) {
- if (m_bPreviousPlayerInCar) {
- if (m_nNextTrack != STREAMED_SOUND_RADIO_POLICE)
- m_nRadioInCar = m_nNextTrack;
- }
- ServiceAmbience();
- return;
+ if (m_bUserResumedGame)
+ {
+ m_bRadioStreamReady = FALSE;
+ m_bUserResumedGame = FALSE;
}
+ if (m_nPlayingTrack == NO_TRACK && m_nFrontendTrack == NO_TRACK)
+ m_bRadioStreamReady = FALSE;
- if (m_bPreviousPlayerInCar) {
- if (m_nAnnouncement < TOTAL_STREAMED_SOUNDS
- && (m_nNextTrack < RADIO_OFF || m_bAnnouncementInProgress)
- && ServiceAnnouncement())
+ if (m_bGameplayAllowsRadio)
+ {
+ if (!m_bRadioStreamReady)
{
- if (m_bAnnouncementInProgress) {
- m_bSetNextStation = FALSE;
+ if(vehicle == nil) {
+ m_nFrontendTrack = STREAMED_SOUND_RADIO_WAVE; // huh?
return;
}
- m_nPlayingTrack = m_nNextTrack;
- m_nNextTrack = GetCarTuning();
+ if(m_bRadioSetByScript) {
+ if(UsesPoliceRadio(vehicle))
+ m_nFrontendTrack = STREAMED_SOUND_RADIO_POLICE;
+ else if(UsesTaxiRadio(vehicle))
+ m_nFrontendTrack = STREAMED_SOUND_RADIO_TAXI;
+ else {
+ m_nFrontendTrack = m_nRadioStationScript;
+ vehicle->m_nRadioStation = m_nRadioStationScript;
+ }
+ if(m_nRadioPosition != -1) {
+ m_aTracks[m_nFrontendTrack].m_nPosition = m_nRadioPosition;
+ m_aTracks[m_nFrontendTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
+ }
+ m_bRadioSetByScript = FALSE;
+ return;
+ }
+
+ // This starts the radio when you enter the car.
+ m_nFrontendTrack = GetCarTuning();
+ return;
+ }
+ if (m_nAnnouncement < NO_TRACK) {
+ if ((m_bAnnouncementInProgress || m_nFrontendTrack == m_nPlayingTrack) && ServiceAnnouncement()) {
+ if (m_bAnnouncementInProgress) {
+ m_bSetNextStation = FALSE;
+ gNumRetunePresses = 0;
+ gRetuneCounter = 0;
+ return;
+ }
+ if(m_nAnnouncement == NO_TRACK) {
+ m_nNextTrack = NO_TRACK;
+ m_nFrontendTrack = GetCarTuning();
+ m_bSetNextStation = FALSE;
+ gRetuneCounter = 0;
+ gNumRetunePresses = 0;
+ }
+ }
}
- if (SampleManager.IsMP3RadioChannelAvailable()
- && m_nNextTrack != STREAMED_SOUND_RADIO_MP3_PLAYER
- && ControlsManager.GetIsKeyboardKeyJustDown(rsF9))
+ if (!m_bAnnouncementInProgress
+ && m_nAnnouncement == NO_TRACK
+ && m_nPlayingTrack == STREAMED_SOUND_RADIO_MP3_PLAYER
+ && !SampleManager.IsStreamPlaying())
{
- m_nPlayingTrack = m_nNextTrack;
- m_nNextTrack = STREAMED_SOUND_RADIO_MP3_PLAYER;
- if (FindPlayerVehicle() != nil)
- FindPlayerVehicle()->m_nRadioStation = STREAMED_SOUND_RADIO_MP3_PLAYER;
- AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_FRONTEND_RADIO_CHANGE, 1.0f);
- gRetuneCounter = 0;
- gNumRetunePresses = 0;
- m_bSetNextStation = FALSE;
+ SampleManager.StartStreamedFile(STREAMED_SOUND_RADIO_MP3_PLAYER, 0);
}
- // Because when you switch radio back and forth, gNumRetunePresses will be 0 but gRetuneCounter won't.
+
+ if (!m_bRadioSetByScript)
+ {
+ // Because when you switch radio back and forth, gNumRetunePresses will be 0 but gRetuneCounter won't.
#ifdef RADIO_SCROLL_TO_PREV_STATION
- if (gRetuneCounter != 0) {
- if (gRetuneCounter > 1) gRetuneCounter--;
- else if (gRetuneCounter == 1) gRetuneCounter = -1;
- else if (gRetuneCounter == -1) {
- m_bSetNextStation = TRUE;
- gRetuneCounter = 0;
+ if(gRetuneCounter != 0) {
+ if(gRetuneCounter > 1)
+ gRetuneCounter--;
+ else if(gRetuneCounter == 1) {
+ m_bSetNextStation = TRUE;
+ gRetuneCounter = 0;
+ }
}
- }
#else
- if (gNumRetunePresses) {
- if (gRetuneCounter != 0) gRetuneCounter--;
- else m_bSetNextStation = TRUE;
- }
+ if (gNumRetunePresses != 0)
+ {
+ if (--gRetuneCounter == 0)
+ {
+ m_bSetNextStation = TRUE;
+ gRetuneCounter = 0;
+ }
+ }
#endif
- if (gRetuneCounter)
- AudioManager.DoPoliceRadioCrackle();
- if (m_bSetNextStation) {
- m_bSetNextStation = FALSE;
- m_nPlayingTrack = m_nNextTrack;
- m_nNextTrack = GetNextCarTuning();
- if (m_nNextTrack == STREAMED_SOUND_CITY_AMBIENT || m_nNextTrack == STREAMED_SOUND_WATER_AMBIENT)
- bRadioOff = TRUE;
+ if (gRetuneCounter)
+ {
+ int32 station = gNumRetunePresses + vehicle->m_nRadioStation;
+#ifdef RADIO_SCROLL_TO_PREV_STATION
+ while (station < 0) station += NUM_RADIOS + 1;
+#endif
+ while (station >= NUM_RADIOS + 1) station -= NUM_RADIOS + 1;
- if (m_nPlayingTrack == STREAMED_SOUND_CITY_AMBIENT || m_nPlayingTrack == STREAMED_SOUND_WATER_AMBIENT)
- AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_FRONTEND_RADIO_CHANGE, 0.0f);
- }
- if (m_nNextTrack < RADIO_OFF) {
- if (ChangeRadioChannel()) {
- ServiceTrack();
- } else {
- m_bPlayerInCar = FALSE;
- if (FindPlayerVehicle())
- FindPlayerVehicle()->m_nRadioStation = m_nNextTrack;
- m_nNextTrack = NO_TRACK;
- }
- if (CTimer::GetIsSlowMotionActive()) {
- if (TheCamera.pTargetEntity != nil) {
- float DistToTargetSq = (TheCamera.pTargetEntity->GetPosition() - TheCamera.GetPosition()).MagnitudeSqr();
- if (DistToTargetSq >= SQR(55.0f)) {
- SampleManager.SetStreamedVolumeAndPan(0, 63, FALSE);
- } else if (DistToTargetSq >= SQR(10.0f)) {
- volume = ((45.0f - (Sqrt(DistToTargetSq) - 10.0f)) / 45.0f * 100.0f);
- uint8 pan;
- if (AudioManager.ShouldDuckMissionAudio())
- volume /= 4;
- if (volume > 0) {
- CVector panVec;
- AudioManager.TranslateEntity(&TheCamera.pTargetEntity->GetPosition(), &panVec);
- pan = AudioManager.ComputePan(55.0f, &panVec);
- } else {
- pan = 0;
- }
- if (gRetuneCounter)
- volume /= 4;
- SampleManager.SetStreamedVolumeAndPan(volume, pan, FALSE);
- } else if (AudioManager.ShouldDuckMissionAudio()) {
- SampleManager.SetStreamedVolumeAndPan(25, 63, FALSE);
- } else if (gRetuneCounter) {
- SampleManager.SetStreamedVolumeAndPan(25, 63, FALSE);
- } else {
- SampleManager.SetStreamedVolumeAndPan(100, 63, FALSE);
+ // Scrolling back won't hit here, so increasing isn't problem
+ if (!DMAudio.IsMP3RadioChannelAvailable() && station == USERTRACK)
+ {
+ ++gNumRetunePresses;
+ station = RADIO_OFF;
+ }
+ if (station == RADIO_OFF)
+ {
+ if (gRetuneCounter == 19) // One less then what switching radio sets, so runs right after turning off radio
+ {
+ AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_FRONTEND_RADIO_TURN_OFF, 0.0f);
+ RadioStaticCounter = 5;
}
}
- } else if (AudioManager.ShouldDuckMissionAudio()) {
- SampleManager.SetStreamedVolumeAndPan(25, 63, FALSE);
- nFramesSinceCutsceneEnded = 0;
- } else {
- if (nFramesSinceCutsceneEnded == -1) {
- volume = 100;
- } else if (nFramesSinceCutsceneEnded < 20) {
- nFramesSinceCutsceneEnded++;
- volume = 25;
- } else if (nFramesSinceCutsceneEnded < 40) {
- volume = 3 * (nFramesSinceCutsceneEnded - 20) + 25;
- nFramesSinceCutsceneEnded++;
- } else {
- nFramesSinceCutsceneEnded = -1;
- volume = 100;
+ else
+ {
+#ifdef RADIO_SCROLL_TO_PREV_STATION
+ if (vehicle->m_nRadioStation == RADIO_OFF && gRetuneCounter == 19) // Right after turning on the radio
+#else
+ if (station == 0 && gRetuneCounter == 19) // Right after turning on the radio
+#endif
+ AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_FRONTEND_RADIO_TURN_ON, 0.0f);
+ AudioManager.DoPoliceRadioCrackle();
}
- if (gRetuneCounter != 0)
- volume /= 4;
- SampleManager.SetStreamedVolumeAndPan(volume, 63, FALSE);
}
+ if (RadioStaticCounter < 2 && CTimer::GetTimeInMilliseconds() > RadioStaticTimer + 800)
+ {
+ AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_RADIO_CHANGE, 0.0f);
+ RadioStaticCounter++;
+ RadioStaticTimer = CTimer::GetTimeInMilliseconds();
+ }
+ if (m_bSetNextStation)
+ m_nFrontendTrack = GetNextCarTuning();
+ if (m_nFrontendTrack >= STREAMED_SOUND_CITY_AMBIENT && m_nFrontendTrack <= STREAMED_SOUND_AMBSIL_AMBIENT)
+ SetUpCorrectAmbienceTrack();
+ ServiceTrack(vehicle, ped);
+ if (m_bSetNextStation)
+ m_bSetNextStation = FALSE;
return;
}
- if (bRadioOff) {
- m_nNextTrack = m_nPlayingTrack;
- if (FindPlayerVehicle() != nil)
- FindPlayerVehicle()->m_nRadioStation = RADIO_OFF;
- AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_FRONTEND_RADIO_TURN_OFF, 0.0f);
+ if (UsesPoliceRadio(vehicle))
+ m_nFrontendTrack = STREAMED_SOUND_RADIO_POLICE;
+ else if (UsesTaxiRadio(vehicle))
+ m_nFrontendTrack = STREAMED_SOUND_RADIO_TAXI;
+ else {
+ m_nFrontendTrack = m_nRadioStationScript;
+ vehicle->m_nRadioStation = m_nRadioStationScript;
}
- ServiceAmbience();
+
+ if (m_nRadioPosition != -1) {
+ m_aTracks[m_nFrontendTrack].m_nPosition = m_nRadioPosition;
+ m_aTracks[m_nFrontendTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
+ }
+
+ gRetuneCounter = 0;
+ gNumRetunePresses = 0;
+ m_bSetNextStation = FALSE;
+ m_bRadioSetByScript = FALSE;
+ if (m_nFrontendTrack >= STREAMED_SOUND_CITY_AMBIENT && m_nFrontendTrack <= STREAMED_SOUND_AMBSIL_AMBIENT)
+ SetUpCorrectAmbienceTrack();
+ ServiceTrack(vehicle, ped);
+ if (m_bSetNextStation)
+ m_bSetNextStation = FALSE;
return;
}
- if (m_bRadioSetByScript) {
- if (UsesPoliceRadio(FindPlayerVehicle())) {
- m_nNextTrack = STREAMED_SOUND_RADIO_POLICE;
- } else {
- m_nNextTrack = m_nRadioStationScript;
- if (FindPlayerVehicle()->m_nRadioStation == m_nNextTrack) {
- m_nPlayingTrack = NO_TRACK;
- SampleManager.SetStreamedVolumeAndPan(0, 63, FALSE);
- SampleManager.StopStreamedFile();
- }
- if (m_nRadioPosition != -1) {
- m_aTracks[m_nNextTrack].m_nPosition = m_nRadioPosition;
- m_aTracks[m_nNextTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
+
+ if (m_bAnnouncementInProgress)
+ {
+ SampleManager.StopStreamedFile();
+ if (SampleManager.IsStreamPlaying())
+ return;
+ g_bAnnouncementReadPosAlready = FALSE;
+ m_nAnnouncement = NO_TRACK;
+ m_bAnnouncementInProgress = FALSE;
+ m_nNextTrack = NO_TRACK;
+ m_nFrontendTrack = NO_TRACK;
+ m_nPlayingTrack = NO_TRACK;
+ }
+ SetUpCorrectAmbienceTrack();
+ ServiceTrack(nil, ped);
+}
+
+void
+cMusicManager::SetUpCorrectAmbienceTrack()
+{
+ switch (CGame::currArea)
+ {
+ case AREA_MAIN_MAP:
+ case AREA_EVERYWHERE:
+ if (CTheScripts::RiotIntensity != 0 && ((TheCamera.GetPosition() - vecRiotPosition).MagnitudeSqr() < SQR(65.0f)))
+ m_nFrontendTrack = STREAMED_SOUND_LAW4RIOT_AMBIENT;
+ else if (TheCamera.DistanceToWater <= 90.0f) {
+ if (CCullZones::bAtBeachForAudio) {
+ if (CWeather::OldWeatherType != WEATHER_HURRICANE && CWeather::NewWeatherType != WEATHER_HURRICANE || CWeather::Wind <= 1.0f)
+ m_nFrontendTrack = STREAMED_SOUND_BEACH_AMBIENT;
+ else
+ m_nFrontendTrack = STREAMED_SOUND_HAVANA_BEACH_AMBIENT;
}
+ else if (CWeather::OldWeatherType != WEATHER_HURRICANE && CWeather::NewWeatherType != WEATHER_HURRICANE || CWeather::Wind <= 1.0f)
+ m_nFrontendTrack = STREAMED_SOUND_WATER_AMBIENT;
+ else
+ m_nFrontendTrack = STREAMED_SOUND_HAVANA_WATER_AMBIENT;
}
- } else {
- m_nNextTrack = GetCarTuning();
+ else if (CWeather::OldWeatherType != WEATHER_HURRICANE && CWeather::NewWeatherType != WEATHER_HURRICANE || CWeather::Wind <= 1.0f)
+ m_nFrontendTrack = STREAMED_SOUND_CITY_AMBIENT;
+ else
+ m_nFrontendTrack = STREAMED_SOUND_HAVANA_CITY_AMBIENT;
+ break;
+ case AREA_HOTEL:
+ m_nFrontendTrack = STREAMED_SOUND_HOTEL_AMBIENT;
+ break;
+ case AREA_MALL:
+ m_nFrontendTrack = STREAMED_SOUND_MALL_AMBIENT;
+ break;
+ case AREA_STRIP_CLUB:
+ m_nFrontendTrack = STREAMED_SOUND_STRIPCLUB_AMBIENT;
+ break;
+ case AREA_DIRT:
+ case AREA_BLOOD:
+ case AREA_OVALRING:
+ m_nFrontendTrack = STREAMED_SOUND_DIRTRING_AMBIENT;
+ break;
+ case AREA_MALIBU_CLUB:
+ m_nFrontendTrack = STREAMED_SOUND_MALIBU_AMBIENT;
+ break;
+ case AREA_MANSION:
+ case AREA_BANK:
+ case AREA_LAWYERS:
+ case AREA_COFFEE_SHOP:
+ case AREA_CONCERT_HALL:
+ case AREA_STUDIO:
+ case AREA_RIFLE_RANGE:
+ case AREA_BIKER_BAR:
+ case AREA_POLICE_STATION:
+ m_nFrontendTrack = STREAMED_SOUND_AMBSIL_AMBIENT;
+ break;
}
- if (m_nNextTrack >= RADIO_OFF) {
- ServiceAmbience();
+}
+
+float
+GetHeightScale()
+{
+ if (TheCamera.GetPosition().z > 20.0f) {
+ if (TheCamera.GetPosition().z < 50.0f)
+ return 1.0f - (TheCamera.GetPosition().z - 20.0f) / 30.0f;
+ return 0.0f;
+ }
+ return 1.0f;
+}
+
+void
+cMusicManager::ComputeAmbienceVol(bool8 reset, uint8& outVolume)
+{
+ static float fVol = 0.0f;
+
+ float fHeightScale = GetHeightScale();
+
+ if (CTheScripts::RiotIntensity > 0) {
+ float distToRiotSq = (TheCamera.GetPosition() - vecRiotPosition).MagnitudeSqr();
+ if (distToRiotSq < SQR(100.0f)) {
+ if (distToRiotSq >= SQR(65.0f))
+ outVolume = (Sqrt(distToRiotSq) - 65.0f) / 35.0f * (127.0f * fHeightScale);
+ else if (distToRiotSq >= SQR(20.0f))
+ outVolume = (CTheScripts::RiotIntensity * (1.0f - (Sqrt(distToRiotSq) - 20.0f) / 45.0f) * (127.0f * fHeightScale)) / MAX_VOLUME;
+ else
+ outVolume = (CTheScripts::RiotIntensity * (127.0f * fHeightScale)) / MAX_VOLUME;
+ return;
+ }
+ }
+
+ if (reset)
+ fVol = 0.0f;
+ else if (fVol < 60.0f) {
+ if ((m_nPlayingTrack >= STREAMED_SOUND_HAVANA_CITY_AMBIENT) && (m_nPlayingTrack <= STREAMED_SOUND_HAVANA_BEACH_AMBIENT))
+ fVol += 20.0f;
+ else
+ fVol += 1.0f;
+ fVol = Min(fVol, 60.0f);
+ }
+
+ if ((m_nPlayingTrack >= STREAMED_SOUND_MALL_AMBIENT) && (m_nPlayingTrack <= STREAMED_SOUND_AMBSIL_AMBIENT)) {
+ outVolume = fVol;
return;
}
- if (ChangeRadioChannel()) {
- if (m_bRadioSetByScript) {
- m_bRadioSetByScript = FALSE;
- FindPlayerVehicle()->m_nRadioStation = m_nNextTrack;
+
+ if (CWeather::OldWeatherType == WEATHER_HURRICANE || CWeather::NewWeatherType == WEATHER_HURRICANE) {
+ if (CWeather::Wind > 1.0f) {
+ outVolume = (CWeather::Wind - 1.0f) * fVol;
+ return;
}
- } else {
- m_bPlayerInCar = FALSE;
- m_nNextTrack = NO_TRACK;
+ fVol = (1.0f - CWeather::Wind) * fVol;
+ }
+
+ if (TheCamera.DistanceToWater > 140.0f) {
+ outVolume = fVol;
+ return;
+ }
+
+ if (TheCamera.DistanceToWater > 90.0f) {
+ outVolume = ((TheCamera.DistanceToWater - 90.0f) / 50.0f * fVol * fHeightScale);
+ return;
}
+
+ if (TheCamera.DistanceToWater > 40.0f) {
+ outVolume = fVol;
+ return;
+ }
+
+ outVolume = (90.0f - fHeightScale) / 50.0f * fVol;
}
-void
-cMusicManager::StopFrontEndTrack()
+bool8
+cMusicManager::ServiceAnnouncement()
{
- if (IsInitialised() && !m_bDisabled && m_nMusicMode == MUSICMODE_FRONTEND && m_nNextTrack != NO_TRACK) {
- m_aTracks[m_nNextTrack].m_nPosition = SampleManager.GetStreamedFilePosition();
- m_aTracks[m_nNextTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
+ if (m_bAnnouncementInProgress) {
+ if (SampleManager.IsStreamPlaying())
+ m_nPlayingTrack = m_nNextTrack;
+ else if (m_nPlayingTrack != NO_TRACK) {
+ m_nAnnouncement = NO_TRACK;
+ m_bAnnouncementInProgress = FALSE;
+ m_nPlayingTrack = NO_TRACK;
+ }
+ return TRUE;
+ } else if (SampleManager.IsStreamPlaying()) {
+ if (m_nPlayingTrack != NO_TRACK && !g_bAnnouncementReadPosAlready) {
+ RecordRadioStats();
+ m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition();
+ g_bAnnouncementReadPosAlready = TRUE;
+ m_aTracks[m_nPlayingTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
+ }
SampleManager.StopStreamedFile();
+ } else {
+ g_bAnnouncementReadPosAlready = FALSE;
m_nPlayingTrack = NO_TRACK;
- m_nNextTrack = NO_TRACK;
+ m_nNextTrack = m_nAnnouncement;
+ SampleManager.SetStreamedFileLoopFlag(FALSE);
+ SampleManager.StartStreamedFile(m_nNextTrack, 0);
+ SampleManager.SetStreamedVolumeAndPan(MAX_VOLUME, 63, FALSE);
+ m_bAnnouncementInProgress = TRUE;
}
-}
-void
-cMusicManager::PlayAnnouncement(uint8 announcement)
-{
- if (IsInitialised() && !m_bDisabled && !m_bAnnouncementInProgress)
- m_nAnnouncement = announcement;
+ return TRUE;
}
void
-cMusicManager::PlayFrontEndTrack(uint8 track, bool8 bPlayInFrontend)
+cMusicManager::ServiceTrack(CVehicle *veh, CPed *ped)
{
- if (IsInitialised() && !m_bDisabled && track < TOTAL_STREAMED_SOUNDS) {
- if (m_nMusicMode == MUSICMODE_GAME) {
- if (m_nNextTrack != NO_TRACK) {
- if (m_bAnnouncementInProgress) {
- m_nAnnouncement = NO_TRACK;
- m_bAnnouncementInProgress = FALSE;
- }
- m_aTracks[m_nNextTrack].m_nPosition = SampleManager.GetStreamedFilePosition();
- m_aTracks[m_nNextTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
+ static bool8 bRadioStatsRecorded = FALSE;
+ static bool8 bRadioStatsRecorded2 = FALSE;
+ uint8 volume;
+ if (!m_bTrackChangeStarted)
+ m_nNextTrack = m_nFrontendTrack;
+ if (gRetuneCounter != 0 || m_bSetNextStation) {
+ if (SampleManager.IsStreamPlaying()) {
+ if (m_nPlayingTrack != NO_TRACK && !bRadioStatsRecorded) {
+ m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition();
+ m_aTracks[m_nPlayingTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
+ RecordRadioStats();
+ bRadioStatsRecorded = TRUE;
}
+ SampleManager.SetStreamedVolumeAndPan(0, 63, FALSE);
SampleManager.StopStreamedFile();
- } else if (m_nMusicMode == MUSICMODE_FRONTEND) {
- if (m_nNextTrack != NO_TRACK) {
- m_aTracks[m_nNextTrack].m_nPosition = SampleManager.GetStreamedFilePosition();
- m_aTracks[m_nNextTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
+ }
+ return;
+ }
+
+ if (bRadioStatsRecorded) {
+ bRadioStatsRecorded = FALSE;
+ m_nPlayingTrack = NO_TRACK;
+ }
+
+ if (m_nNextTrack != m_nPlayingTrack)
+ {
+ m_bTrackChangeStarted = TRUE;
+ SampleManager.SetStreamedVolumeAndPan(0, 63, FALSE);
+ if (!(AudioManager.m_FrameCounter & 1)) {
+ if (m_bVerifyNextTrackStartedToPlay || !SampleManager.IsStreamPlaying()) {
+ bRadioStatsRecorded2 = FALSE;
+ if (SampleManager.IsStreamPlaying()) {
+ m_nPlayingTrack = m_nNextTrack;
+ m_bVerifyNextTrackStartedToPlay = FALSE;
+ m_bTrackChangeStarted = FALSE;
+ if (veh) {
+#ifdef FIX_BUGS
+ if (m_nPlayingTrack >= STREAMED_SOUND_CITY_AMBIENT && m_nPlayingTrack <= STREAMED_SOUND_AMBSIL_AMBIENT)
+ veh->m_nRadioStation = RADIO_OFF;
+ else if (m_nPlayingTrack < STREAMED_SOUND_CITY_AMBIENT)
+ veh->m_nRadioStation = m_nPlayingTrack;
+#else
+ if (veh->m_nRadioStation >= STREAMED_SOUND_CITY_AMBIENT && veh->m_nRadioStation <= STREAMED_SOUND_AMBSIL_AMBIENT)
+ veh->m_nRadioStation = RADIO_OFF;
+ else
+ veh->m_nRadioStation = m_nPlayingTrack;
+#endif
+ }
+ } else {
+ uint32 pos = GetTrackStartPos(m_nNextTrack);
+ if (m_nNextTrack != NO_TRACK) {
+ SampleManager.SetStreamedFileLoopFlag(TRUE);
+ SampleManager.StartStreamedFile(m_nNextTrack, pos);
+ if (m_nFrontendTrack < STREAMED_SOUND_CITY_AMBIENT || m_nFrontendTrack > STREAMED_SOUND_AMBSIL_AMBIENT)
+ {
+ m_nVolumeLatency = 10;
+ m_nCurrentVolume = 0;
+ m_nMaxVolume = 100;
+ SampleManager.SetStreamedVolumeAndPan(m_nCurrentVolume, 63, FALSE);
+ }
+ else
+ {
+ ComputeAmbienceVol(TRUE, volume);
+ SampleManager.SetStreamedVolumeAndPan(volume, 63, TRUE);
+ }
+ if (m_nNextTrack < STREAMED_SOUND_CITY_AMBIENT)
+ m_nLastTrackServiceTime = CTimer::GetTimeInMillisecondsPauseMode();
+ m_bVerifyNextTrackStartedToPlay = TRUE;
+ }
+ }
+ } else {
+ if (m_nPlayingTrack == NO_TRACK)
+ debug("m_nPlayingTrack == NO_TRACK, yet track playing - tidying up\n");
+ else if (!bRadioStatsRecorded2)
+ {
+ m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition();
+ m_aTracks[m_nPlayingTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
+ bRadioStatsRecorded2 = TRUE;
+ RecordRadioStats();
+ if (m_nPlayingTrack >= STREAMED_SOUND_HAVANA_CITY_AMBIENT && m_nPlayingTrack <= STREAMED_SOUND_HAVANA_BEACH_AMBIENT)
+ {
+ if (m_nNextTrack >= STREAMED_SOUND_HAVANA_CITY_AMBIENT && m_nNextTrack <= STREAMED_SOUND_HAVANA_BEACH_AMBIENT)
+ AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_FRONTEND_HURRICANE, 0.0);
+ }
+ }
+ SampleManager.SetStreamedVolumeAndPan(0, 63, FALSE);
+ SampleManager.StopStreamedFile();
}
- SampleManager.StopStreamedFile();
}
+ return;
+ }
- m_nPlayingTrack = m_nNextTrack;
- m_nNextTrack = track;
- m_bPlayInFrontend = bPlayInFrontend;
- m_bFrontendTrackFinished = FALSE;
- m_bDoTrackService = TRUE;
- bHasStarted = FALSE;
- if (m_nNextTrack < NUM_RADIOS) {
- gRetuneCounter = 0;
- gNumRetunePresses = 0;
+ if (m_nPlayingTrack >= STREAMED_SOUND_CITY_AMBIENT && m_nPlayingTrack <= STREAMED_SOUND_AMBSIL_AMBIENT)
+ {
+ ComputeAmbienceVol(FALSE, volume);
+ SampleManager.SetStreamedVolumeAndPan(volume, 63, TRUE);
+ return;
+ }
+ if (CTimer::GetIsSlowMotionActive())
+ {
+ if (TheCamera.pTargetEntity)
+ {
+ float DistToTargetSq = (TheCamera.pTargetEntity->GetPosition() - TheCamera.GetPosition()).MagnitudeSqr();
+ if (DistToTargetSq >= SQR(55.0f))
+ {
+ SampleManager.SetStreamedVolumeAndPan(0, 63, FALSE);
+ }
+ else if (DistToTargetSq >= SQR(10.0f))
+ {
+ volume = (45.0f - (Sqrt(DistToTargetSq) - 10.0f)) / 45.0f * m_nCurrentVolume;
+ if (AudioManager.ShouldDuckMissionAudio(0) || AudioManager.ShouldDuckMissionAudio(1))
+ volume /= 4;
+
+ uint8 pan = 0;
+ if (volume > 0)
+ {
+ CVector panVec;
+ AudioManager.TranslateEntity(&TheCamera.pTargetEntity->GetPosition(), &panVec);
+ pan = AudioManager.ComputePan(55.0f, &panVec);
+ }
+ if (gRetuneCounter != 0)
+ volume = 0;
+ SampleManager.SetStreamedVolumeAndPan(volume, pan, FALSE);
+ }
+ else if (AudioManager.ShouldDuckMissionAudio(0) || AudioManager.ShouldDuckMissionAudio(1))
+ SampleManager.SetStreamedVolumeAndPan(m_nCurrentVolume, 63, FALSE);
+ else if (gRetuneCounter != 0)
+ SampleManager.SetStreamedVolumeAndPan(0, 63, FALSE);
+ else
+ SampleManager.SetStreamedVolumeAndPan(m_nCurrentVolume, 63, FALSE);
+ }
+ } else if (AudioManager.ShouldDuckMissionAudio(0) || AudioManager.ShouldDuckMissionAudio(1)) {
+ SampleManager.SetStreamedVolumeAndPan(Min(m_nCurrentVolume, 25), 63, FALSE);
+ nFramesSinceCutsceneEnded = 0;
+ } else {
+ if (nFramesSinceCutsceneEnded == -1)
+ volume = m_nCurrentVolume;
+ else if (nFramesSinceCutsceneEnded < 20)
+ {
+ volume = Min(m_nCurrentVolume, 25);
+ nFramesSinceCutsceneEnded++;
}
+ else if (nFramesSinceCutsceneEnded < 40)
+ {
+ volume = Min(m_nCurrentVolume, 3 * (nFramesSinceCutsceneEnded - 20) + 25);
+ nFramesSinceCutsceneEnded++;
+ }
+ else
+ {
+ volume = m_nCurrentVolume;
+ nFramesSinceCutsceneEnded = -1;
+ }
+ if (gRetuneCounter != 0)
+ volume = 0;
+ SampleManager.SetStreamedVolumeAndPan(volume, 63, FALSE);
}
+ if (m_nVolumeLatency > 0)
+ m_nVolumeLatency--;
+ else if (m_nCurrentVolume < m_nMaxVolume)
+ m_nCurrentVolume = Min(m_nMaxVolume, m_nCurrentVolume + 6);
}
void
-cMusicManager::PreloadCutSceneMusic(uint8 track)
+cMusicManager::PreloadCutSceneMusic(uint32 track)
{
if (IsInitialised() && !m_bDisabled && track < TOTAL_STREAMED_SOUNDS && m_nMusicMode == MUSICMODE_CUTSCENE) {
AudioManager.ResetPoliceRadio();
@@ -771,7 +1092,7 @@ cMusicManager::PreloadCutSceneMusic(uint8 track)
SampleManager.StopStreamedFile();
SampleManager.PreloadStreamedFile(track);
SampleManager.SetStreamedVolumeAndPan(MAX_VOLUME, 63, TRUE);
- m_nNextTrack = track;
+ m_nPlayingTrack = track;
}
}
@@ -787,16 +1108,87 @@ cMusicManager::StopCutSceneMusic(void)
{
if (IsInitialised() && !m_bDisabled && m_nMusicMode == MUSICMODE_CUTSCENE) {
SampleManager.StopStreamedFile();
- m_nNextTrack = NO_TRACK;
+ m_nPlayingTrack = NO_TRACK;
+ }
+}
+
+void
+cMusicManager::PlayFrontEndTrack(uint32 track, bool8 loopFlag)
+{
+ if (IsInitialised() && !m_bDisabled && track < TOTAL_STREAMED_SOUNDS && (m_nUpcomingMusicMode == MUSICMODE_FRONTEND || m_nMusicMode == MUSICMODE_FRONTEND))
+ {
+ m_nFrontendTrack = track;
+ m_FrontendLoopFlag = loopFlag;
+ if (m_nMusicMode != MUSICMODE_FRONTEND)
+ m_bEarlyFrontendTrack = TRUE;
+ }
+}
+
+void
+cMusicManager::StopFrontEndTrack()
+{
+ if (m_nUpcomingMusicMode == MUSICMODE_FRONTEND || m_nMusicMode == MUSICMODE_FRONTEND)
+ m_nFrontendTrack = NO_TRACK;
+}
+
+void
+cMusicManager::PlayAnnouncement(uint32 announcement)
+{
+ if (IsInitialised() && !m_bDisabled && !m_bAnnouncementInProgress)
+ m_nAnnouncement = announcement;
+}
+
+uint32
+cMusicManager::GetNextCarTuning()
+{
+ CVehicle *veh = AudioManager.FindVehicleOfPlayer();
+ if (veh == nil) return STREAMED_SOUND_CITY_AMBIENT;
+ if (UsesPoliceRadio(veh)) return STREAMED_SOUND_RADIO_POLICE;
+ if (UsesTaxiRadio(veh)) return STREAMED_SOUND_RADIO_TAXI;
+ if (gNumRetunePresses != 0) {
+#ifdef RADIO_SCROLL_TO_PREV_STATION
+ // m_nRadioStation is unsigned, so...
+ int station = veh->m_nRadioStation + gNumRetunePresses;
+ while(station < 0) station += NUM_RADIOS + 1;
+ while(station >= NUM_RADIOS + 1) station -= NUM_RADIOS + 1;
+ veh->m_nRadioStation = station;
+#else
+ veh->m_nRadioStation += gNumRetunePresses;
+ while(veh->m_nRadioStation >= NUM_RADIOS + 1)
+ veh->m_nRadioStation -= NUM_RADIOS + 1;
+#endif
+ DMAudio.IsMP3RadioChannelAvailable(); // woof, just call and do nothing =P they manipulate gNumRetunePresses on DisplayRadioStationName in this case
+ gNumRetunePresses = 0;
}
+ return veh->m_nRadioStation;
}
uint32
-cMusicManager::GetTrackStartPos(uint8 track)
+cMusicManager::GetCarTuning()
{
+ CVehicle* veh = AudioManager.FindVehicleOfPlayer();
+ if (veh == nil) return STREAMED_SOUND_CITY_AMBIENT;
+ if (UsesPoliceRadio(veh)) return STREAMED_SOUND_RADIO_POLICE;
+ if (UsesTaxiRadio(veh)) return STREAMED_SOUND_RADIO_TAXI;
+ if (veh->m_nRadioStation == USERTRACK && !SampleManager.IsMP3RadioChannelAvailable())
+ veh->m_nRadioStation = AudioManager.m_anRandomTable[2] % USERTRACK;
+ return veh->m_nRadioStation;
+}
+
+float*
+cMusicManager::GetListenTimeArray()
+{
+ return aListenTimeArray;
+}
+
+uint32
+cMusicManager::GetTrackStartPos(uint32 track)
+{
+ if (!IsInitialised()) return 0;
+
uint32 pos = m_aTracks[track].m_nPosition;
if (CTimer::GetTimeInMillisecondsPauseMode() > m_aTracks[track].m_nLastPosCheckTimer)
- pos += Min(CTimer::GetTimeInMillisecondsPauseMode() - m_aTracks[track].m_nLastPosCheckTimer, 90000);
+ pos += Min(CTimer::GetTimeInMillisecondsPauseMode() - m_aTracks[track].m_nLastPosCheckTimer, 270000);
else
m_aTracks[track].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
@@ -805,222 +1197,227 @@ cMusicManager::GetTrackStartPos(uint8 track)
return pos;
}
-
-bool8
-cMusicManager::UsesPoliceRadio(CVehicle *veh)
+uint32
+cMusicManager::GetRadioPosition(uint32 station)
{
- switch (veh->GetModelIndex())
- {
- case MI_FBICAR:
- case MI_POLICE:
- case MI_ENFORCER:
- case MI_PREDATOR:
- case MI_RHINO:
- case MI_BARRACKS:
- return TRUE;
- }
- return FALSE;
+ if (station < NUM_RADIOS)
+ return GetTrackStartPos(station);
+ return 0;
}
-void
-cMusicManager::ServiceAmbience()
+uint32
+cMusicManager::GetFavouriteRadioStation()
{
- uint8 volume;
+ uint32 favstation = 0;
- if (m_bAnnouncementInProgress) {
- m_nAnnouncement = NO_TRACK;
- m_bAnnouncementInProgress = FALSE;
- }
- if (m_nNextTrack < RADIO_OFF) {
- if (SampleManager.IsStreamPlaying()) {
- m_aTracks[m_nNextTrack].m_nPosition = SampleManager.GetStreamedFilePosition();
- m_aTracks[m_nNextTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
- SampleManager.StopStreamedFile();
- m_nNextTrack = NO_TRACK;
- return;
- }
- m_nNextTrack = RADIO_OFF;
+ for (int i = 1; i < NUM_RADIOS; i++) {
+ if (aListenTimeArray[i] > aListenTimeArray[favstation])
+ favstation = i;
}
- if (CWorld::Players[CWorld::PlayerInFocus].m_WBState != WBSTATE_PLAYING && !SampleManager.IsStreamPlaying()) {
- m_nNextTrack = NO_TRACK;
- return;
- }
-
- m_nPlayingTrack = m_nNextTrack;
- m_nNextTrack = TheCamera.DistanceToWater <= 45.0f ? STREAMED_SOUND_WATER_AMBIENT : STREAMED_SOUND_CITY_AMBIENT;
- if (m_nNextTrack == m_nPlayingTrack) {
- ComputeAmbienceVol(FALSE, volume);
- SampleManager.SetStreamedVolumeAndPan(volume, 63, TRUE);
- if (m_bVerifyAmbienceTrackStartedToPlay) {
- if (SampleManager.IsStreamPlaying())
- m_bVerifyAmbienceTrackStartedToPlay = FALSE;
- } else ServiceTrack();
- } else {
- if (m_nPlayingTrack < TOTAL_STREAMED_SOUNDS) {
- m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition();
- m_aTracks[m_nPlayingTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
- SampleManager.StopStreamedFile();
- }
- uint32 pos = GetTrackStartPos(m_nNextTrack);
- SampleManager.SetStreamedVolumeAndPan(0, 63, TRUE);
- if (SampleManager.StartStreamedFile(m_nNextTrack, pos)) {
- ComputeAmbienceVol(TRUE, volume);
- SampleManager.SetStreamedVolumeAndPan(volume, 63, TRUE);
- m_bVerifyAmbienceTrackStartedToPlay = TRUE;
- } else
- m_nNextTrack = NO_TRACK;
- }
+ return favstation;
}
-void
-cMusicManager::ComputeAmbienceVol(bool8 reset, uint8 &outVolume)
+bool8
+cMusicManager::CheckForMusicInterruptions()
{
- static float fVol = 0.0f;
-
- if (reset)
- fVol = 0.0f;
- else if (fVol < 60.0f)
- fVol += 1.0f;
-
- if (TheCamera.DistanceToWater > 70.0f)
- outVolume = fVol;
- else if (TheCamera.DistanceToWater > 45.0f)
- outVolume = (TheCamera.DistanceToWater - 45.0f) / 25.0f * fVol;
- else if (TheCamera.DistanceToWater > 20.0f)
- outVolume = (45.0f - TheCamera.DistanceToWater) / 25.0f * fVol;
- else
- outVolume = fVol;
+ return (m_nPlayingTrack == STREAMED_SOUND_MISSION_COMPLETED) || (m_nPlayingTrack == STREAMED_SOUND_CUTSCENE_FINALE);
}
void
-cMusicManager::ServiceTrack()
+cMusicManager::SetMalibuClubTrackPos(uint8 scriptObject)
{
- if (m_bDoTrackService) {
- if (!SampleManager.IsStreamPlaying())
- SampleManager.StartStreamedFile(m_nNextTrack, 0);
+ if (!IsInitialised())
+ m_aTracks[STREAMED_SOUND_MALIBU_AMBIENT].m_nPosition = 8640;
+ if (m_nNextTrack != STREAMED_SOUND_MALIBU_AMBIENT && m_nPlayingTrack != STREAMED_SOUND_MALIBU_AMBIENT) {
+ switch (scriptObject)
+ {
+ case SCRIPT_SOUND_NEW_BUILDING_MALIBU_1:
+ m_aTracks[STREAMED_SOUND_MALIBU_AMBIENT].m_nPosition = (AudioManager.m_anRandomTable[0] % 128) + 8640;
+ break;
+ case SCRIPT_SOUND_NEW_BUILDING_MALIBU_2:
+ m_aTracks[STREAMED_SOUND_MALIBU_AMBIENT].m_nPosition = (AudioManager.m_anRandomTable[0] % 128) + 286720;
+ break;
+ case SCRIPT_SOUND_NEW_BUILDING_MALIBU_3:
+ m_aTracks[STREAMED_SOUND_MALIBU_AMBIENT].m_nPosition = (AudioManager.m_anRandomTable[0] % 128) + 509120;
+ break;
+ }
+ m_aTracks[STREAMED_SOUND_MALIBU_AMBIENT].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
}
}
-bool8
-cMusicManager::ServiceAnnouncement()
+void
+cMusicManager::SetStripClubTrackPos(uint8 scriptObject)
{
- static int8 cCheck = 0;
- if (m_bAnnouncementInProgress) {
- if (!SampleManager.IsStreamPlaying()) {
- m_nAnnouncement = NO_TRACK;
- m_bAnnouncementInProgress = FALSE;
+ if (!IsInitialised())
+ m_aTracks[STREAMED_SOUND_STRIPCLUB_AMBIENT].m_nPosition = 0;
+ if (m_nNextTrack != STREAMED_SOUND_STRIPCLUB_AMBIENT && m_nPlayingTrack != STREAMED_SOUND_STRIPCLUB_AMBIENT)
+ {
+ switch (scriptObject)
+ {
+ case SCRIPT_SOUND_NEW_BUILDING_STRIP_1:
+ m_aTracks[STREAMED_SOUND_STRIPCLUB_AMBIENT].m_nPosition = AudioManager.m_anRandomTable[0] % 128;
+ break;
+ case SCRIPT_SOUND_NEW_BUILDING_STRIP_2:
+ m_aTracks[STREAMED_SOUND_STRIPCLUB_AMBIENT].m_nPosition = (AudioManager.m_anRandomTable[0] % 128) + 320200;
+ break;
+ case SCRIPT_SOUND_NEW_BUILDING_STRIP_3:
+ m_aTracks[STREAMED_SOUND_STRIPCLUB_AMBIENT].m_nPosition = (AudioManager.m_anRandomTable[0] % 128) + 672000;
+ break;
}
- return TRUE;
+ m_aTracks[STREAMED_SOUND_STRIPCLUB_AMBIENT].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
}
+}
- if (++cCheck >= 30) {
- cCheck = 0;
- int pos = SampleManager.GetStreamedFilePosition();
- if (SampleManager.IsStreamPlaying()) {
- if (m_nNextTrack != NO_TRACK) {
- m_aTracks[m_nNextTrack].m_nPosition = pos;
- m_aTracks[m_nNextTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
- SampleManager.StopStreamedFile();
+void
+cMusicManager::DisplayRadioStationName()
+{
+ uint8 gStreamedSound;
+ static wchar *pCurrentStation = nil;
+ static uint8 cDisplay = 0;
+
+ if(!CTimer::GetIsPaused() && !TheCamera.m_WideScreenOn && PlayerInCar() &&
+ !CReplay::IsPlayingBack()) {
+ CVehicle *vehicle = AudioManager.FindVehicleOfPlayer();
+
+ if (vehicle)
+ {
+ // Prev scroll needs it to be signed, and m_nFrontendTrack can be NO_TRACK thus FIX_BUGS
+#if defined RADIO_SCROLL_TO_PREV_STATION || defined FIX_BUGS
+ int track;
+#else
+ uint8 track;
+#endif
+ gStreamedSound = vehicle->m_nRadioStation;
+ if (gStreamedSound >= STREAMED_SOUND_CITY_AMBIENT && gStreamedSound <= STREAMED_SOUND_AMBSIL_AMBIENT)
+ gStreamedSound = RADIO_OFF;
+ if (gNumRetunePresses != 0)
+ {
+ track = gNumRetunePresses + gStreamedSound;
+#ifdef RADIO_SCROLL_TO_PREV_STATION
+ while (track < 0) track += NUM_RADIOS + 1;
+#endif
+ while (track >= NUM_RADIOS + 1) track -= NUM_RADIOS + 1;
+
+ // On scrolling back we handle this condition on key press. No need to change this.
+ if (!DMAudio.IsMP3RadioChannelAvailable() && track == USERTRACK)
+ gNumRetunePresses++;
}
- }
+ else
+#ifdef RADIO_OFF_TEXT
+ track = GetCarTuning(); // gStreamedSound or veh->m_nRadioStation would also work, but these don't cover police/taxi radios
+#else
+ track = m_nFrontendTrack;
+#endif
+ wchar* string = nil;
+ switch (track) {
+ case WILDSTYLE: string = TheText.Get("FEA_FM0"); break;
+ case FLASH_FM: string = TheText.Get("FEA_FM1"); break;
+ case KCHAT: string = TheText.Get("FEA_FM2"); break;
+ case FEVER: string = TheText.Get("FEA_FM3"); break;
+ case V_ROCK: string = TheText.Get("FEA_FM4"); break;
+ case VCPR: string = TheText.Get("FEA_FM5"); break;
+ case RADIO_ESPANTOSO: string = TheText.Get("FEA_FM6"); break;
+ case EMOTION: string = TheText.Get("FEA_FM7"); break;
+ case WAVE: string = TheText.Get("FEA_FM8"); break;
+ case USERTRACK:
+ if (!SampleManager.IsMP3RadioChannelAvailable())
+ return;
+ string = TheText.Get("FEA_MP3"); break;
+#ifdef RADIO_OFF_TEXT
+ case RADIO_OFF: {
+ // Otherwise RADIO OFF will be seen after pausing-resuming game and Mission Complete text
+ if (!m_bRadioStreamReady || !m_bGameplayAllowsRadio)
+ return;
- SampleManager.SetStreamedVolumeAndPan(0, 63, FALSE);
- if (SampleManager.StartStreamedFile(m_nAnnouncement, 0)) {
- SampleManager.SetStreamedVolumeAndPan(AudioManager.ShouldDuckMissionAudio() ? 25 : 100, 63, FALSE);
- m_bAnnouncementInProgress = TRUE;
- m_nPlayingTrack = m_nNextTrack;
- m_nNextTrack = m_nAnnouncement;
- return TRUE;
+ extern wchar WideErrorString[];
+
+ string = TheText.Get("FEA_NON");
+ if (string == WideErrorString) {
+ pCurrentStation = nil;
+ return;
+ }
+ break;
+ }
+#endif
+ default: return;
+ };
+
+ if (pCurrentStation != string) {
+ pCurrentStation = string;
+ cDisplay = 60;
+ }
+ else {
+ if (cDisplay == 0) return;
+#ifdef FIX_BUGS
+ cDisplay -= CTimer::GetLogicalFramesPassed();
+#else
+ cDisplay--;
+#endif
+ }
+
+ CFont::SetJustifyOff();
+ CFont::SetBackgroundOff();
+ CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f));
+ CFont::SetPropOn();
+ CFont::SetFontStyle(FONT_STANDARD);
+ CFont::SetCentreOn();
+ CFont::SetCentreSize(SCREEN_STRETCH_X(DEFAULT_SCREEN_WIDTH));
+ CFont::SetColor(CRGBA(0, 0, 0, 255));
+ CFont::PrintString(SCREEN_WIDTH / 2 + SCREEN_SCALE_X(2.0f), SCREEN_SCALE_Y(22.0f) + SCREEN_SCALE_Y(2.0f), pCurrentStation);
+
+ if (gNumRetunePresses)
+ CFont::SetColor(CRGBA(102, 133, 143, 255));
+ else
+ CFont::SetColor(CRGBA(147, 196, 211, 255));
+
+ CFont::PrintString(SCREEN_WIDTH / 2, SCREEN_SCALE_Y(22.0f), pCurrentStation);
+ CFont::DrawFonts();
}
+ }
+ // Always show station text after entering car. Same behaviour as III and SA.
+#ifdef FIX_BUGS
+ else
+ pCurrentStation = nil;
+#endif
+}
- if (cCheck != 0) cCheck--;
- else cCheck = 30;
+bool8
+cMusicManager::UsesPoliceRadio(CVehicle *veh)
+{
+ switch (veh->GetModelIndex())
+ {
+ case MI_VCNMAV:
+ case MI_POLMAV:
+ case MI_COASTG:
+ case MI_RHINO:
+ case MI_BARRACKS:
+ return TRUE;
+ case MI_MRWHOOP:
+ case MI_HUNTER:
return FALSE;
}
-
- return FALSE;
+ return veh->UsesSiren();
}
-uint8
-cMusicManager::GetCarTuning()
+bool8
+cMusicManager::UsesTaxiRadio(CVehicle *veh)
{
- CVehicle *veh = FindPlayerVehicle();
- if (veh == nil) return RADIO_OFF;
- if (UsesPoliceRadio(veh)) return POLICE_RADIO;
- if (veh->m_nRadioStation == USERTRACK && !SampleManager.IsMP3RadioChannelAvailable())
- veh->m_nRadioStation = AudioManager.m_anRandomTable[2] % USERTRACK;
- return veh->m_nRadioStation;
+ if (veh->GetModelIndex() != MI_KAUFMAN) return FALSE;
+ return CTheScripts::bPlayerHasMetDebbieHarry;
}
-uint8
-cMusicManager::GetNextCarTuning()
+void
+cMusicManager::ServiceAmbience()
{
- CVehicle *veh = FindPlayerVehicle();
- if (veh == nil) return RADIO_OFF;
- if (UsesPoliceRadio(veh)) return POLICE_RADIO;
- if (gNumRetunePresses != 0) {
-#ifdef RADIO_SCROLL_TO_PREV_STATION
- if (gNumRetunePresses < 0) {
- while (gNumRetunePresses < 0) {
- if(veh->m_nRadioStation == HEAD_RADIO) {
- veh->m_nRadioStation = RADIO_OFF;
- } else if(veh->m_nRadioStation == RADIO_OFF || veh->m_nRadioStation == NUM_RADIOS) {
- veh->m_nRadioStation = SampleManager.IsMP3RadioChannelAvailable() ? USERTRACK : USERTRACK - 1;
- } else
- veh->m_nRadioStation--;
-
- ++gNumRetunePresses;
- }
- } else
-#endif
- if (SampleManager.IsMP3RadioChannelAvailable()) {
- if (veh->m_nRadioStation == RADIO_OFF)
- veh->m_nRadioStation = NUM_RADIOS;
- veh->m_nRadioStation += gNumRetunePresses;
-#ifdef FIX_BUGS
- while (veh->m_nRadioStation > NUM_RADIOS)
- veh->m_nRadioStation -= (NUM_RADIOS + 1);
-#endif
- if (veh->m_nRadioStation == NUM_RADIOS)
- veh->m_nRadioStation = RADIO_OFF;
-#ifndef FIX_BUGS
- else if (veh->m_nRadioStation > NUM_RADIOS)
- veh->m_nRadioStation -= (NUM_RADIOS + 1);
-#endif
- } else if (gNumRetunePresses + veh->m_nRadioStation >= USERTRACK) {
- while (gNumRetunePresses) {
- if (veh->m_nRadioStation == RADIO_OFF)
- veh->m_nRadioStation = HEAD_RADIO;
- else if (veh->m_nRadioStation < USERTRACK)
- ++veh->m_nRadioStation;
-
- if (veh->m_nRadioStation == USERTRACK)
- veh->m_nRadioStation = RADIO_OFF;
- --gNumRetunePresses;
- }
- } else
- veh->m_nRadioStation += gNumRetunePresses;
- gNumRetunePresses = 0;
- }
- return veh->m_nRadioStation;
}
bool8
cMusicManager::ChangeRadioChannel()
{
- if (m_nNextTrack != m_nPlayingTrack) {
- if (m_nPlayingTrack < TOTAL_STREAMED_SOUNDS) {
- m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition();
- m_aTracks[m_nPlayingTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
- SampleManager.SetStreamedVolumeAndPan(0, 63, FALSE);
- SampleManager.StopStreamedFile();
- }
- if (SampleManager.IsStreamPlaying())
- return FALSE;
- if (!SampleManager.StartStreamedFile(m_nNextTrack, GetTrackStartPos(m_nNextTrack)))
- return FALSE;
- SampleManager.SetStreamedVolumeAndPan(AudioManager.ShouldDuckMissionAudio() ? 25 : 100, 63, FALSE);
- }
return TRUE;
}
+
+// these two are empty
+void cMusicManager::Enable() {}
+void cMusicManager::Disable() {}
diff --git a/src/audio/MusicManager.h b/src/audio/MusicManager.h
index 4c4447fe..3d2b7cee 100644
--- a/src/audio/MusicManager.h
+++ b/src/audio/MusicManager.h
@@ -11,41 +11,53 @@ public:
};
class CVehicle;
+class CPed;
class cMusicManager
{
public:
bool8 m_bIsInitialised;
bool8 m_bDisabled;
- uint8 m_nMusicMode;
- uint8 m_nNextTrack;
- uint8 m_nPlayingTrack;
- bool8 m_bFrontendTrackFinished;
- bool8 m_bPlayInFrontend;
bool8 m_bSetNextStation;
- uint8 m_nAnnouncement;
- bool8 m_bPreviousPlayerInCar;
- bool8 m_bPlayerInCar;
+ uint8 m_nVolumeLatency;
+ uint8 m_nCurrentVolume;
+ uint8 m_nMaxVolume;
+ uint32 m_nAnnouncement;
bool8 m_bAnnouncementInProgress;
tStreamedSample m_aTracks[TOTAL_STREAMED_SOUNDS];
bool8 m_bResetTimers;
uint32 m_nResetTime;
- uint32 m_nLastTrackServiceTime;
- uint32 m_nTimer;
- bool8 m_bDoTrackService;
- bool8 m_bIgnoreTimeDelay;
- bool8 m_bVerifyAmbienceTrackStartedToPlay;
bool8 m_bRadioSetByScript;
uint8 m_nRadioStationScript;
int32 m_nRadioPosition;
- uint8 m_nRadioInCar;
+ uint32 m_nRadioInCar;
+ uint32 m_nFrontendTrack;
+ uint32 m_nPlayingTrack;
+ uint8 m_nUpcomingMusicMode;
+ uint8 m_nMusicMode;
+ bool8 m_FrontendLoopFlag;
+ bool8 m_bTrackChangeStarted;
+ uint32 m_nNextTrack;
+ bool8 m_nNextLoopFlag;
+ bool8 m_bVerifyNextTrackStartedToPlay;
+ bool8 m_bGameplayAllowsRadio;
+ bool8 m_bRadioStreamReady;
+ int8 nFramesSinceCutsceneEnded;
+ bool8 m_bUserResumedGame;
+ bool8 m_bMusicModeChangeStarted;
+ uint8 m_nMusicModeToBeSet;
+ bool8 m_bEarlyFrontendTrack;
+ float aListenTimeArray[NUM_RADIOS];
+ float m_nLastTrackServiceTime;
public:
cMusicManager();
bool8 IsInitialised() { return m_bIsInitialised; }
- uint32 GetMusicMode() { return m_nMusicMode; }
- uint8 GetNextTrack() { return m_nNextTrack; }
+ uint8 GetMusicMode() { return m_nMusicMode; }
+ uint32 GetCurrentTrack() { return m_nPlayingTrack; }
+ void ResetMusicAfterReload();
+ void SetStartingTrackPositions(bool8 isNewGameTimer);
bool8 Initialise();
void Terminate();
@@ -55,35 +67,47 @@ public:
bool8 PlayerInCar();
void DisplayRadioStationName();
- void PlayAnnouncement(uint8);
- void PlayFrontEndTrack(uint8, bool8);
- void PreloadCutSceneMusic(uint8);
+ void PlayAnnouncement(uint32);
+ void PlayFrontEndTrack(uint32, bool8);
+ void PreloadCutSceneMusic(uint32);
void PlayPreloadedCutSceneMusic(void);
void StopCutSceneMusic(void);
- uint8 GetRadioInCar(void);
+ uint32 GetRadioInCar(void);
void SetRadioInCar(uint32);
- void SetRadioChannelByScript(uint8, int32);
-
- void ResetMusicAfterReload();
+ void SetRadioChannelByScript(uint32, int32);
void ResetTimers(int32);
void Service();
void ServiceFrontEndMode();
void ServiceGameMode();
void ServiceAmbience();
- void ServiceTrack();
+ void ServiceTrack(CVehicle *veh, CPed *ped);
bool8 UsesPoliceRadio(CVehicle *veh);
- uint32 GetTrackStartPos(uint8);
+ bool8 UsesTaxiRadio(CVehicle *veh);
+ uint32 GetTrackStartPos(uint32 track);
void ComputeAmbienceVol(bool8 reset, uint8& outVolume);
bool8 ServiceAnnouncement();
- uint8 GetCarTuning();
- uint8 GetNextCarTuning();
+ uint32 GetCarTuning();
+ uint32 GetNextCarTuning();
bool8 ChangeRadioChannel();
+ void RecordRadioStats();
+ void SetUpCorrectAmbienceTrack();
+ float *GetListenTimeArray();
+ uint32 GetRadioPosition(uint32 station);
+ uint32 GetFavouriteRadioStation();
+ void SetMalibuClubTrackPos(uint8 pos);
+ void SetStripClubTrackPos(uint8 pos);
+ bool8 CheckForMusicInterruptions();
+
+ void Enable();
+ void Disable();
};
VALIDATE_SIZE(cMusicManager, 0x95C);
extern cMusicManager MusicManager;
+extern bool8 g_bAnnouncementReadPosAlready; // we have a symbol of this so it was declared in .h
+float GetHeightScale();
diff --git a/src/audio/PolRadio.cpp b/src/audio/PolRadio.cpp
index 742e5ea5..b19886f5 100644
--- a/src/audio/PolRadio.cpp
+++ b/src/audio/PolRadio.cpp
@@ -22,8 +22,6 @@ struct tPoliceRadioZone {
};
tPoliceRadioZone ZoneSfx[NUMAUDIOZONES];
-char SubZo2Label[8];
-char SubZo3Label[8];
uint32 g_nMissionAudioSfx = TOTAL_AUDIO_SAMPLES;
int8 g_nMissionAudioPlayingStatus = 2;
@@ -40,46 +38,22 @@ cAudioManager::InitialisePoliceRadioZones()
strcpy(ZoneSfx[i].m_aName, name); \
ZoneSfx[i].m_nSampleIndex = sample;
- SETZONESFX(0, "HOSPI_2", SFX_POLICE_RADIO_ROCKFORD);
- SETZONESFX(1, "CONSTRU", SFX_POLICE_RADIO_FORT_STAUNTON);
- SETZONESFX(2, "STADIUM", SFX_POLICE_RADIO_ASPATRIA);
- SETZONESFX(3, "YAKUSA", SFX_POLICE_RADIO_TORRINGTON);
- SETZONESFX(4, "SHOPING", SFX_POLICE_RADIO_BEDFORD_POINT);
- SETZONESFX(5, "COM_EAS", SFX_POLICE_RADIO_NEWPORT);
- SETZONESFX(6, "PARK", SFX_POLICE_RADIO_BELLEVILLE_PARK);
- SETZONESFX(7, "UNIVERS", SFX_POLICE_RADIO_LIBERTY_CAMPUS);
- SETZONESFX(8, "BIG_DAM", SFX_POLICE_RADIO_COCHRANE_DAM);
- SETZONESFX(9, "SUB_IND", SFX_POLICE_RADIO_PIKE_CREEK);
- SETZONESFX(10, "SWANKS", SFX_POLICE_RADIO_CEDAR_GROVE);
- SETZONESFX(11, "PROJECT", SFX_POLICE_RADIO_WICHITA_GARDENS);
- SETZONESFX(12, "AIRPORT", SFX_POLICE_RADIO_FRANCIS_INTERNATIONAL_AIRPORT);
- SETZONESFX(13, "PORT_W", SFX_POLICE_RADIO_CALLAHAN_POINT);
- SETZONESFX(14, "PORT_S", SFX_POLICE_RADIO_ATLANTIC_QUAYS);
- SETZONESFX(15, "PORT_E", SFX_POLICE_RADIO_PORTLAND_HARBOUR);
- SETZONESFX(16, "PORT_I", SFX_POLICE_RADIO_TRENTON);
- SETZONESFX(17, "CHINA", SFX_POLICE_RADIO_CHINATOWN);
- SETZONESFX(18, "REDLIGH", SFX_POLICE_RADIO_RED_LIGHT_DISTRICT);
- SETZONESFX(19, "TOWERS", SFX_POLICE_RADIO_HEPBURN_HEIGHTS);
- SETZONESFX(20, "LITTLEI", SFX_POLICE_RADIO_SAINT_MARKS);
- SETZONESFX(21, "HARWOOD", SFX_POLICE_RADIO_HARWOOD);
- SETZONESFX(22, "EASTBAY", SFX_POLICE_RADIO_PORTLAND_BEACH);
- SETZONESFX(23, "S_VIEW", SFX_POLICE_RADIO_PORTLAND_STRAIGHTS);
- SETZONESFX(24, "CITYZON", SFX_POLICE_RADIO_LIBERTY_CITY);
- SETZONESFX(25, "IND_ZON", SFX_POLICE_RADIO_PORTLAND);
- SETZONESFX(26, "COM_ZON", SFX_POLICE_RADIO_STAUNTON_ISLAND);
- SETZONESFX(27, "SUB_ZON", SFX_POLICE_RADIO_SHORESIDE_VALE);
- SETZONESFX(28, "SUB_ZO2", SFX_POLICE_RADIO_SHORESIDE_VALE);
- SETZONESFX(29, "SUB_ZO3", SFX_POLICE_RADIO_SHORESIDE_VALE);
- SETZONESFX(30, "A", SFX_POLICE_RADIO_ROCKFORD);
- SETZONESFX(31, "A", SFX_POLICE_RADIO_ROCKFORD);
- SETZONESFX(32, "A", SFX_POLICE_RADIO_ROCKFORD);
- SETZONESFX(33, "A", SFX_POLICE_RADIO_ROCKFORD);
- SETZONESFX(34, "A", SFX_POLICE_RADIO_ROCKFORD);
+ SETZONESFX(0, "VICE_C", SFX_POLICE_RADIO_VICE_CITY);
+ SETZONESFX(1, "IND_ZON", SFX_POLICE_RADIO_VICE_CITY_BEACH);
+ SETZONESFX(2, "COM_ZON", SFX_POLICE_RADIO_VICE_CITY_MAINLAND);
+ SETZONESFX(3, "BEACH1", SFX_POLICE_RADIO_OCEAN_BEACH);
+ SETZONESFX(4, "BEACH2", SFX_POLICE_RADIO_WASHINGTON_BEACH);
+ SETZONESFX(5, "BEACH3", SFX_POLICE_RADIO_VICE_POINT);
+ SETZONESFX(6, "GOLFC", SFX_POLICE_RADIO_LEAF_LINKS);
+ SETZONESFX(7, "STARI", SFX_POLICE_RADIO_STARFISH_ISLAND);
+ SETZONESFX(8, "DOCKS", SFX_POLICE_RADIO_VICEPORT);
+ SETZONESFX(9, "HAVANA", SFX_POLICE_RADIO_LITTLE_HAVANA);
+ SETZONESFX(10, "HAITI", SFX_POLICE_RADIO_LITTLE_HAITI);
+ SETZONESFX(11, "PORNI", SFX_POLICE_RADIO_PRAWN_ISLAND);
+ SETZONESFX(12, "DTOWN", SFX_POLICE_RADIO_DOWNTOWN);
+ SETZONESFX(13, "A_PORT", SFX_POLICE_RADIO_ESCOBAR_INTERNATIONAL);
#undef SETZONESFX
-
- strcpy(SubZo2Label, "SUB_ZO2");
- strcpy(SubZo3Label, "SUB_ZO3");
}
void
@@ -157,18 +131,21 @@ cAudioManager::ServicePoliceRadio()
if(CReplay::IsPlayingBack() || !FindPlayerPed() || !FindPlayerPed()->m_pWanted)
return;
#endif
- wantedLevel = FindPlayerPed()->m_pWanted->GetWantedLevel();
- if(!crimeReport) {
- if(wantedLevel != 0) {
- if(nLastSeen != 0) {
+ CPlayerPed *playerPed = FindPlayerPed();
+ if (playerPed) {
+ wantedLevel = playerPed->m_pWanted->GetWantedLevel();
+ if (!crimeReport) {
+ if (wantedLevel != 0) {
+ if (nLastSeen != 0)
#ifdef FIX_BUGS
- nLastSeen -= CTimer::GetLogicalFramesPassed();
+ nLastSeen -= CTimer::GetLogicalFramesPassed();
#else
- --nLastSeen;
+ --nLastSeen;
#endif
- } else {
- nLastSeen = m_anRandomTable[1] % 1000 + 2000;
- SetupSuspectLastSeenReport();
+ else {
+ nLastSeen = m_anRandomTable[1] % 1000 + 2000;
+ SetupSuspectLastSeenReport();
+ }
}
}
}
@@ -186,18 +163,18 @@ cAudioManager::ServicePoliceRadioChannel(uint8 wantedLevel)
static int cWait = 0;
static bool8 bChannelOpen = FALSE;
static uint8 bMissionAudioPhysicalPlayingStatus = 0;
- static int32 PoliceChannelFreq = 5500;
+ static int32 PoliceChannelFreq = 22050;
if (!m_bIsInitialised) return;
if (m_nUserPause != 0) {
if (SampleManager.GetChannelUsedFlag(CHANNEL_POLICE_RADIO)) SampleManager.StopChannel(CHANNEL_POLICE_RADIO);
- if (g_nMissionAudioSfx != TOTAL_AUDIO_SAMPLES && bMissionAudioPhysicalPlayingStatus == 1 &&
+ if (g_nMissionAudioSfx != NO_SAMPLE && bMissionAudioPhysicalPlayingStatus == 1 &&
SampleManager.IsStreamPlaying(1)) {
SampleManager.PauseStream(TRUE, 1);
}
} else {
- if (m_nPreviousUserPause && g_nMissionAudioSfx != TOTAL_AUDIO_SAMPLES &&
+ if (m_nPreviousUserPause && g_nMissionAudioSfx != NO_SAMPLE &&
bMissionAudioPhysicalPlayingStatus == 1) {
SampleManager.PauseStream(FALSE, 1);
}
@@ -210,7 +187,7 @@ cAudioManager::ServicePoliceRadioChannel(uint8 wantedLevel)
#endif
return;
}
- if (g_nMissionAudioSfx != TOTAL_AUDIO_SAMPLES && !bChannelOpen) {
+ if (g_nMissionAudioSfx != NO_SAMPLE && !bChannelOpen) {
if (g_nMissionAudioPlayingStatus) {
if (g_nMissionAudioPlayingStatus == 1 && !bMissionAudioPhysicalPlayingStatus &&
SampleManager.IsStreamPlaying(1)) {
@@ -222,7 +199,7 @@ cAudioManager::ServicePoliceRadioChannel(uint8 wantedLevel)
} else {
bMissionAudioPhysicalPlayingStatus = 2;
g_nMissionAudioPlayingStatus = 2;
- g_nMissionAudioSfx = TOTAL_AUDIO_SAMPLES;
+ g_nMissionAudioSfx = NO_SAMPLE;
cWait = 30;
}
return;
@@ -237,31 +214,29 @@ cAudioManager::ServicePoliceRadioChannel(uint8 wantedLevel)
}
}
if (bChannelOpen) DoPoliceRadioCrackle();
- if ((g_nMissionAudioSfx == TOTAL_AUDIO_SAMPLES || g_nMissionAudioPlayingStatus != 1) &&
+ if ((g_nMissionAudioSfx == NO_SAMPLE || g_nMissionAudioPlayingStatus != 1) &&
!SampleManager.GetChannelUsedFlag(CHANNEL_POLICE_RADIO) && m_sPoliceRadioQueue.policeChannelTimer) {
if (m_sPoliceRadioQueue.policeChannelTimer) {
sample = m_sPoliceRadioQueue.crimesSamples[m_sPoliceRadioQueue.policeChannelCounterSeconds];
m_sPoliceRadioQueue.policeChannelTimer--;
m_sPoliceRadioQueue.policeChannelCounterSeconds = (m_sPoliceRadioQueue.policeChannelCounterSeconds + 1) % 60;
} else {
- sample = TOTAL_AUDIO_SAMPLES;
+ sample = NO_SAMPLE;
}
if (wantedLevel == 0) {
if (gSpecialSuspectLastSeenReport) {
gSpecialSuspectLastSeenReport = 0;
- } else if (((sample >= SFX_POLICE_RADIO_MESSAGE_NOISE_1) && (sample <= SFX_POLICE_RADIO_MESSAGE_NOISE_3)) || sample == TOTAL_AUDIO_SAMPLES) {
+ } else if (sample == SFX_POLICE_RADIO_MESSAGE_NOISE_1) {
bChannelOpen = FALSE;
processed = TRUE;
}
}
- if (sample == TOTAL_AUDIO_SAMPLES) {
+ if (sample == NO_SAMPLE) {
if (!processed) cWait = 30;
} else {
SampleManager.InitialiseChannel(CHANNEL_POLICE_RADIO, sample, SFX_BANK_0);
switch (sample) {
case SFX_POLICE_RADIO_MESSAGE_NOISE_1:
- case SFX_POLICE_RADIO_MESSAGE_NOISE_2:
- case SFX_POLICE_RADIO_MESSAGE_NOISE_3:
freq = m_anRandomTable[4] % 2000 + 10025;
bChannelOpen = bChannelOpen == FALSE;
break;
@@ -314,49 +289,54 @@ cAudioManager::SetupCrimeReport()
for (int j = 0; j < NUMAUDIOZONES; j++) {
if (strcmp(zone->name, ZoneSfx[j].m_aName) == 0) {
sampleIndex = ZoneSfx[j].m_nSampleIndex;
- m_sPoliceRadioQueue.Add(m_anRandomTable[4] % 3 + SFX_POLICE_RADIO_MESSAGE_NOISE_1);
+ m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_MESSAGE_NOISE_1);
m_sPoliceRadioQueue.Add(m_anRandomTable[0] % 3 + SFX_WEVE_GOT);
- m_sPoliceRadioQueue.Add(m_anRandomTable[1] % 2 + SFX_A_10_1);
+ m_sPoliceRadioQueue.Add(SFX_A_10);
switch (m_sPoliceRadioQueue.crimes[i].type) {
- case CRIME_PED_BURNED: m_sPoliceRadioQueue.crimes[i].type = CRIME_HIT_PED; break;
- case CRIME_COP_BURNED: m_sPoliceRadioQueue.crimes[i].type = CRIME_HIT_COP; break;
+ case CRIME_PED_BURNED:
+ case CRIME_HIT_PED_NASTYWEAPON:
+ m_sPoliceRadioQueue.crimes[i].type = CRIME_HIT_PED;
+ break;
+ case CRIME_COP_BURNED:
+ case CRIME_HIT_COP_NASTYWEAPON:
+ m_sPoliceRadioQueue.crimes[i].type = CRIME_HIT_COP;
+ break;
case CRIME_VEHICLE_BURNED: m_sPoliceRadioQueue.crimes[i].type = CRIME_STEAL_CAR; break;
case CRIME_DESTROYED_CESSNA: m_sPoliceRadioQueue.crimes[i].type = CRIME_SHOOT_HELI; break;
+ case CRIME_EXPLOSION: m_sPoliceRadioQueue.crimes[i].type = CRIME_STEAL_CAR; break; // huh?
default: break;
}
+#ifdef FIX_BUGS
m_sPoliceRadioQueue.Add(m_sPoliceRadioQueue.crimes[i].type + SFX_CRIME_1 - 1);
+#else
+ m_sPoliceRadioQueue.Add(m_sPoliceRadioQueue.crimes[i].type + SFX_CRIME_1);
+#endif
m_sPoliceRadioQueue.Add(SFX_IN);
- if (sampleIndex == SFX_POLICE_RADIO_SHORESIDE_VALE &&
- (strcmp(zone->name, SubZo2Label) == 0 || strcmp(zone->name, SubZo3Label) == 0)) {
+ rangeX = zone->maxx - zone->minx;
+ rangeY = zone->maxy - zone->miny;
+ halfX = 0.5f * rangeX + zone->minx;
+ halfY = 0.5f * rangeY + zone->miny;
+ quarterX = 0.25f * rangeX;
+ quarterY = 0.25f * rangeY;
+
+ if (m_sPoliceRadioQueue.crimes[i].position.y > halfY + quarterY) {
m_sPoliceRadioQueue.Add(SFX_NORTH);
- m_sPoliceRadioQueue.Add(SFX_EAST);
- } else {
- rangeX = zone->maxx - zone->minx;
- rangeY = zone->maxy - zone->miny;
- halfX = 0.5f * rangeX + zone->minx;
- halfY = 0.5f * rangeY + zone->miny;
- quarterX = 0.25f * rangeX;
- quarterY = 0.25f * rangeY;
-
- if (m_sPoliceRadioQueue.crimes[i].position.y > halfY + quarterY) {
- m_sPoliceRadioQueue.Add(SFX_NORTH);
- processed = TRUE;
- } else if (m_sPoliceRadioQueue.crimes[i].position.y < halfY - quarterY) {
- m_sPoliceRadioQueue.Add(SFX_SOUTH);
- processed = TRUE;
- }
-
- if (m_sPoliceRadioQueue.crimes[i].position.x > halfX + quarterX)
- m_sPoliceRadioQueue.Add(SFX_EAST);
- else if (m_sPoliceRadioQueue.crimes[i].position.x < halfX - quarterX)
- m_sPoliceRadioQueue.Add(SFX_WEST);
- else if (!processed)
- m_sPoliceRadioQueue.Add(SFX_CENTRAL);
-
- m_sPoliceRadioQueue.Add(sampleIndex);
- m_sPoliceRadioQueue.Add(m_anRandomTable[2] % 3 + SFX_POLICE_RADIO_MESSAGE_NOISE_1);
- m_sPoliceRadioQueue.Add(TOTAL_AUDIO_SAMPLES);
+ processed = TRUE;
+ } else if (m_sPoliceRadioQueue.crimes[i].position.y < halfY - quarterY) {
+ m_sPoliceRadioQueue.Add(SFX_SOUTH);
+ processed = TRUE;
}
+
+ if (m_sPoliceRadioQueue.crimes[i].position.x > halfX + quarterX)
+ m_sPoliceRadioQueue.Add(SFX_EAST);
+ else if (m_sPoliceRadioQueue.crimes[i].position.x < halfX - quarterX)
+ m_sPoliceRadioQueue.Add(SFX_WEST);
+ else if (!processed)
+ m_sPoliceRadioQueue.Add(SFX_CENTRAL);
+
+ m_sPoliceRadioQueue.Add(sampleIndex);
+ m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_MESSAGE_NOISE_1);
+ m_sPoliceRadioQueue.Add(NO_SAMPLE);
break;
}
}
@@ -378,161 +358,105 @@ cAudioManager::SetupSuspectLastSeenReport()
int32 color_post_modifier;
const int32 gCarColourTable[][3] = {
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLACK, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_WHITE, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_BRIGHT, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
+ {NO_SAMPLE, SFX_POLICE_RADIO_BLACK, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_WHITE, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_BLUE, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_RED, NO_SAMPLE},
+ {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_BLUE, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_PURPLE, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_YELLOW, NO_SAMPLE},
+ {SFX_POLICE_RADIO_BRIGHT, SFX_POLICE_RADIO_BLUE, NO_SAMPLE},
{SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_BLUE, SFX_POLICE_RADIO_GREY},
-#ifdef FIX_BUGS
- {SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
-#else
- {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
-#endif
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
-#ifdef FIX_BUGS
- {SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
-#else
- {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
-#endif
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
-#ifdef FIX_BUGS
- {SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
-#else
- {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
-#endif
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
-#ifdef FIX_BUGS
- {SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
-#else
- {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
-#endif
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
-#ifdef FIX_BUGS
- {SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
-#else
- {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
-#endif
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
-#ifdef FIX_BUGS
- {SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_PURPLE, SFX_POLICE_RADIO_BLUE},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
-#else
- {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
-#endif
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
-#ifdef FIX_BUGS
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, SFX_POLICE_RADIO_GREY},
-#else
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
-#endif
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
-#ifdef FIX_BUGS
- {SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
-#else
- {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
-#endif
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
-#ifdef FIX_BUGS
- {SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
-#else
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
-#endif
- {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}
+ {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_RED, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_RED, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_RED, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_RED, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_RED, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_RED, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_RED, NO_SAMPLE},
+ {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_ORANGE, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_ORANGE, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_ORANGE, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_ORANGE, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_ORANGE, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_ORANGE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_YELLOW, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_YELLOW, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_YELLOW, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_YELLOW, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_YELLOW, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_YELLOW, NO_SAMPLE},
+ {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_GREEN, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_GREEN, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_GREEN, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_GREEN, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_GREEN, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_GREEN, NO_SAMPLE},
+ {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_BLUE, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_BLUE, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_BLUE, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_BLUE, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_BLUE, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_BLUE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_PURPLE, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_PURPLE, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_PURPLE, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_PURPLE, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_PURPLE, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_PURPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_SILVER, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_SILVER, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_SILVER, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_SILVER, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_SILVER, NO_SAMPLE},
+ {NO_SAMPLE, SFX_POLICE_RADIO_SILVER, NO_SAMPLE},
+ {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_LIGHT, NO_SAMPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE},
+ {SFX_POLICE_RADIO_DARK, NO_SAMPLE, NO_SAMPLE}
};
if (MusicManager.m_nMusicMode != MUSICMODE_CUTSCENE) {
- veh = FindPlayerVehicle();
+ veh = FindVehicleOfPlayer();
if (veh != nil) {
if (60 - m_sPoliceRadioQueue.policeChannelTimer > 9) {
color1 = veh->m_currentColour1;
@@ -543,136 +467,189 @@ cAudioManager::SetupSuspectLastSeenReport()
color_pre_modifier = gCarColourTable[color1][0];
color_post_modifier = gCarColourTable[color1][2];
switch (veh->GetModelIndex()) {
-#ifdef FIX_BUGS
- case MI_COLUMB:
- main_color = SFX_POLICE_RADIO_BLUE;
- color_pre_modifier = color_post_modifier = TOTAL_AUDIO_SAMPLES;
-#endif
case MI_LANDSTAL:
- case MI_BLISTA: sample = SFX_POLICE_RADIO_CRUISER; break;
-#ifdef FIX_BUGS
- case MI_YARDIE:
- color_pre_modifier = TOTAL_AUDIO_SAMPLES;
- main_color = SFX_POLICE_RADIO_RED;
- color_post_modifier = SFX_POLICE_RADIO_YELLOW;
- sample = SFX_POLICE_RADIO_CONVERTIBLE; break;
- case MI_DIABLOS:
- main_color = SFX_POLICE_RADIO_BLACK;
-#endif
+ case MI_PATRIOT:
+ case MI_RANCHER:
+ case MI_FBIRANCH:
+ case MI_SANDKING:
+ sample = SFX_POLICE_RADIO_OFFROAD;
+ break;
case MI_IDAHO:
- case MI_STALLION: sample = SFX_POLICE_RADIO_CONVERTIBLE; break;
-#ifdef FIX_BUGS
- case MI_YAKUZA:
- color_pre_modifier = TOTAL_AUDIO_SAMPLES;
- main_color = SFX_POLICE_RADIO_SILVER;
- color_post_modifier = SFX_POLICE_RADIO_RED;
-#endif
+ case MI_MANANA:
+ case MI_ESPERANT:
+ case MI_CUBAN:
+ case MI_STALLION:
+ case MI_SABRE:
+ case MI_SABRETUR:
+ case MI_VIRGO:
+ case MI_BLISTAC:
+ sample = SFX_POLICE_RADIO_TUDOOR;
+ break;
case MI_STINGER:
case MI_INFERNUS:
case MI_CHEETAH:
- case MI_BANSHEE: sample = SFX_POLICE_RADIO_SPORTS_CAR; break;
-#ifdef FIX_BUGS
- case MI_MAFIA:
- color_pre_modifier = color_post_modifier = TOTAL_AUDIO_SAMPLES;
- main_color = SFX_POLICE_RADIO_GREY;
- case MI_KURUMA:
-#endif
+ case MI_BANSHEE:
+ case MI_PHEONIX:
+ case MI_COMET:
+ case MI_DELUXO:
+ case MI_HOTRING:
+ sample = SFX_POLICE_RADIO_SPORTS_CAR;
+ break;
+ case MI_LINERUN:
+ sample = SFX_POLICE_RADIO_RIG;
+ break;
case MI_PEREN:
+ case MI_REGINA:
+ sample = SFX_POLICE_RADIO_STATION_WAGON;
+ break;
case MI_SENTINEL:
- case MI_FBICAR: sample = SFX_POLICE_RADIO_SALOON; break;
- case MI_PATRIOT:
- case MI_BOBCAT: sample = SFX_POLICE_RADIO_PICKUP; break;
- case MI_FIRETRUCK: sample = SFX_POLICE_RADIO_FIRE_TRUCK; break;
-#ifdef FIX_BUGS
- case MI_LINERUN:
- case MI_FLATBED:
-#endif
+ case MI_FBICAR:
+ case MI_WASHING:
+ case MI_SENTXS:
+ case MI_ADMIRAL:
+ case MI_GLENDALE:
+ case MI_OCEANIC:
+ case MI_HERMES:
+ case MI_GREENWOO:
+ sample = SFX_POLICE_RADIO_SEDAN;
+ break;
+ case MI_RIO:
+ sample = SFX_POLICE_RADIO_CRUISER;
+ break;
+ case MI_FIRETRUCK:
+ sample = SFX_POLICE_RADIO_FIRE_TRUCK;
+ break;
case MI_TRASH:
- case MI_BARRACKS: sample = SFX_POLICE_RADIO_TRUCK; break;
- case MI_STRETCH: sample = SFX_POLICE_RADIO_LIMO; break;
-#ifdef FIX_BUGS
- case MI_CORPSE:
-#endif
- case MI_MANANA:
- case MI_ESPERANT: sample = SFX_POLICE_RADIO_2_DOOR; break;
-#ifdef FIX_BUGS
- case MI_HOODS:
- color_pre_modifier = TOTAL_AUDIO_SAMPLES;
- main_color = SFX_POLICE_RADIO_BLUE;
- color_post_modifier = SFX_POLICE_RADIO_GREEN;
- case MI_BELLYUP:
- case MI_YANKEE:
- case MI_TOYZ:
- case MI_MRWONGS:
- case MI_PANLANT:
-#endif
+ sample = SFX_POLICE_RADIO_GARBAGE_TRUCK;
+ break;
+ case MI_STRETCH:
+ case MI_LOVEFIST:
+ sample = SFX_POLICE_RADIO_STRETCH;
+ break;
+ case MI_VOODOO:
+ sample = SFX_POLICE_RADIO_LOWRIDER;
+ break;
case MI_PONY:
- case MI_MULE:
case MI_MOONBEAM:
- case MI_ENFORCER:
case MI_SECURICA:
- case MI_RUMPO: sample = SFX_POLICE_RADIO_VAN; break;
- case MI_AMBULAN: sample = SFX_POLICE_RADIO_AMBULANCE; break;
+ case MI_RUMPO:
+ case MI_GANGBUR:
+ case MI_YANKEE:
+ case MI_TOPFUN:
+ case MI_BURRITO:
+ case MI_SPAND:
+ sample = SFX_POLICE_RADIO_VAN;
+ break;
+ case MI_MULE:
+ case MI_BARRACKS:
+ case MI_PACKER:
+ case MI_FLATBED:
+ sample = SFX_POLICE_RADIO_TRUCK;
+ break;
+ case MI_AMBULAN:
+ sample = SFX_POLICE_RADIO_AMBULANCE;
+ break;
case MI_TAXI:
case MI_CABBIE:
- case MI_BORGNINE: sample = SFX_POLICE_RADIO_TAXI; break;
+ case MI_ZEBRA:
+ case MI_KAUFMAN:
+ sample = SFX_POLICE_RADIO_TAXI;
+ break;
+ case MI_BOBCAT:
+ case MI_WALTON:
+ sample = SFX_POLICE_RADIO_PICKUP;
+ break;
case MI_MRWHOOP:
sample = SFX_POLICE_RADIO_ICE_CREAM_VAN;
break;
- case MI_BFINJECT: sample = SFX_POLICE_RADIO_BUGGY; break;
- case MI_POLICE: sample = SFX_POLICE_RADIO_POLICE_CAR; break;
-#ifdef FIX_BUGS
+ case MI_BFINJECT:
+ sample = SFX_POLICE_RADIO_BUGGY;
+ break;
+ case MI_HUNTER:
+ case MI_CHOPPER:
+ case MI_SEASPAR:
+ case MI_SPARROW:
+ case MI_MAVERICK:
+ case MI_VCNMAV:
+ case MI_POLMAV:
+ sample = SFX_POLICE_RADIO_HELICOPTER;
+ break;
+ case MI_POLICE:
+ sample = SFX_POLICE_RADIO_POLICE_CAR;
+ break;
+ case MI_ENFORCER:
+ sample = SFX_POLICE_RADIO_SWAT_VAN;
+ break;
+ case MI_PREDATOR:
+ case MI_SQUALO:
case MI_SPEEDER:
- case MI_REEFER:
- case MI_GHOST:
-#endif
- case MI_PREDATOR: sample = SFX_POLICE_RADIO_BOAT; break;
+ sample = SFX_POLICE_RADIO_SPEEDBOAT;
+ break;
case MI_BUS:
- case MI_COACH: sample = SFX_POLICE_RADIO_BUS; break;
+ sample = SFX_POLICE_RADIO_BUS;
+ break;
case MI_RHINO:
sample = SFX_POLICE_RADIO_TANK;
- main_color = TOTAL_AUDIO_SAMPLES;
- color_post_modifier = TOTAL_AUDIO_SAMPLES;
break;
- case MI_TRAIN:
- sample = SFX_POLICE_RADIO_SUBWAY_CAR;
- main_color = TOTAL_AUDIO_SAMPLES;
- color_post_modifier = TOTAL_AUDIO_SAMPLES;
-
+ case MI_ANGEL:
+ case MI_PCJ600:
+ case MI_FREEWAY:
+ case MI_SANCHEZ:
+ sample = SFX_POLICE_RADIO_MOTOBIKE;
+ break;
+ case MI_COACH:
+ sample = SFX_POLICE_RADIO_COACH;
+ break;
+ case MI_ROMERO:
+ sample = SFX_POLICE_RADIO_HEARSE;
+ break;
+ case MI_PIZZABOY:
+ case MI_FAGGIO:
+ sample = SFX_POLICE_RADIO_MOPED;
+ break;
+ case MI_DEADDODO:
+ case MI_SKIMMER:
+ sample = SFX_POLICE_RADIO_PLANE;
+ break;
+ case MI_REEFER:
+ case MI_TROPIC:
+ case MI_COASTG:
+ case MI_MARQUIS:
+ case MI_JETMAX:
+ sample = SFX_POLICE_RADIO_BOAT;
+ break;
+ case MI_CADDY:
+ sample = SFX_POLICE_RADIO_GOLF_CART;
+ break;
+ case MI_DINGHY:
+ sample = SFX_POLICE_RADIO_DINGHY;
break;
default:
- debug("\n *** UNKNOWN CAR MODEL INDEX %d *** ", veh->GetModelIndex());
+ //debug("\n *** UNKNOWN CAR MODEL INDEX %d *** ", veh->GetModelIndex());
return;
}
- m_sPoliceRadioQueue.Add(m_anRandomTable[4] % 3 + SFX_POLICE_RADIO_MESSAGE_NOISE_1);
+ m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_MESSAGE_NOISE_1);
m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_SUSPECT);
if (m_anRandomTable[3] % 2)
m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_LAST_SEEN);
-#ifdef FIX_BUGS
- if (main_color == SFX_POLICE_RADIO_ORANGE && color_pre_modifier == TOTAL_AUDIO_SAMPLES)
-#else
- if (main_color == SFX_POLICE_RADIO_ORANGE)
-#endif
- m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_IN_AN);
- else
- m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_IN_A);
- if (color_pre_modifier != TOTAL_AUDIO_SAMPLES)
+ m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_IN_A);
+ if (color_pre_modifier != NO_SAMPLE)
m_sPoliceRadioQueue.Add(color_pre_modifier);
- if (main_color != TOTAL_AUDIO_SAMPLES)
+ if (main_color != NO_SAMPLE)
m_sPoliceRadioQueue.Add(main_color);
- if (color_post_modifier != TOTAL_AUDIO_SAMPLES)
+ if (color_post_modifier != NO_SAMPLE)
m_sPoliceRadioQueue.Add(color_post_modifier);
m_sPoliceRadioQueue.Add(sample);
- m_sPoliceRadioQueue.Add(m_anRandomTable[0] % 3 + SFX_POLICE_RADIO_MESSAGE_NOISE_1);
- m_sPoliceRadioQueue.Add(TOTAL_AUDIO_SAMPLES);
+ m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_MESSAGE_NOISE_1);
+ m_sPoliceRadioQueue.Add(NO_SAMPLE);
}
}
} else if (60 - m_sPoliceRadioQueue.policeChannelTimer > 4) {
m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_MESSAGE_NOISE_1);
m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_SUSPECT);
m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_ON_FOOT);
- m_sPoliceRadioQueue.Add(m_anRandomTable[0] % 3 + SFX_POLICE_RADIO_MESSAGE_NOISE_1);
- m_sPoliceRadioQueue.Add(TOTAL_AUDIO_SAMPLES);
+ m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_MESSAGE_NOISE_1);
+ m_sPoliceRadioQueue.Add(NO_SAMPLE);
}
}
}
@@ -684,15 +661,14 @@ cAudioManager::ReportCrime(eCrimeType type, const CVector &pos)
if (m_bIsInitialised && MusicManager.m_nMusicMode != MUSICMODE_CUTSCENE && FindPlayerPed()->m_pWanted->GetWantedLevel() > 0 &&
(type > CRIME_NONE || type < NUM_CRIME_TYPES) && m_FrameCounter >= gMinTimeToNextReport[type]) {
for (int32 i = 0; i < ARRAY_SIZE(m_sPoliceRadioQueue.crimes); i++) {
- if (m_sPoliceRadioQueue.crimes[i].type) {
+ if (m_sPoliceRadioQueue.crimes[i].type != CRIME_NONE) {
if (m_sPoliceRadioQueue.crimes[i].type == type) {
m_sPoliceRadioQueue.crimes[i].position = pos;
m_sPoliceRadioQueue.crimes[i].timer = 0;
return;
}
- } else {
+ } else
lastCrime = i;
- }
}
if (lastCrime < ARRAY_SIZE(m_sPoliceRadioQueue.crimes)) {
@@ -716,7 +692,7 @@ cAudioManager::PlaySuspectLastSeen(float x, float y, float z)
float quarterX;
float quarterY;
int32 sample;
- bool8 processed = false;
+ bool8 processed = FALSE;
CVector vec = CVector(x, y, z);
if (!m_bIsInitialised) return;
@@ -728,41 +704,34 @@ cAudioManager::PlaySuspectLastSeen(float x, float y, float z)
for (int i = 0; i < NUMAUDIOZONES; i++) {
if (strcmp(zone->name, ZoneSfx[i].m_aName) == 0) {
sample = ZoneSfx[i].m_nSampleIndex;
- m_sPoliceRadioQueue.Add(m_anRandomTable[4] % 3 + SFX_POLICE_RADIO_MESSAGE_NOISE_1);
+ m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_MESSAGE_NOISE_1);
m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_SUSPECT);
m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_LAST_SEEN);
m_sPoliceRadioQueue.Add(SFX_IN);
- if (sample == SFX_POLICE_RADIO_SHORESIDE_VALE &&
- (strcmp(zone->name, SubZo2Label) == 0 ||
- strcmp(zone->name, SubZo3Label) == 0)) {
+ rangeX = zone->maxx - zone->minx;
+ rangeY = zone->maxy - zone->miny;
+ halfX = 0.5f * rangeX + zone->minx;
+ halfY = 0.5f * rangeY + zone->miny;
+ quarterX = 0.25f * rangeX;
+ quarterY = 0.25f * rangeY;
+
+ if (vec.y > halfY + quarterY) {
m_sPoliceRadioQueue.Add(SFX_NORTH);
- m_sPoliceRadioQueue.Add(SFX_EAST);
- } else {
- rangeX = zone->maxx - zone->minx;
- rangeY = zone->maxy - zone->miny;
- halfX = 0.5f * rangeX + zone->minx;
- halfY = 0.5f * rangeY + zone->miny;
- quarterX = 0.25f * rangeX;
- quarterY = 0.25f * rangeY;
-
- if (vec.y > halfY + quarterY) {
- m_sPoliceRadioQueue.Add(SFX_NORTH);
- processed = TRUE;
- } else if (vec.y < halfY - quarterY) {
- m_sPoliceRadioQueue.Add(SFX_SOUTH);
- processed = TRUE;
- }
-
- if (vec.x > halfX + quarterX)
- m_sPoliceRadioQueue.Add(SFX_EAST);
- else if (vec.x < halfX - quarterX)
- m_sPoliceRadioQueue.Add(SFX_WEST);
- else if (!processed)
- m_sPoliceRadioQueue.Add(SFX_CENTRAL);
+ processed = TRUE;
+ } else if (vec.y < halfY - quarterY) {
+ m_sPoliceRadioQueue.Add(SFX_SOUTH);
+ processed = TRUE;
}
+
+ if (vec.x > halfX + quarterX)
+ m_sPoliceRadioQueue.Add(SFX_EAST);
+ else if (vec.x < halfX - quarterX)
+ m_sPoliceRadioQueue.Add(SFX_WEST);
+ else if (!processed)
+ m_sPoliceRadioQueue.Add(SFX_CENTRAL);
m_sPoliceRadioQueue.Add(sample);
- m_sPoliceRadioQueue.Add(m_anRandomTable[2] % 3 + SFX_POLICE_RADIO_MESSAGE_NOISE_1);
- m_sPoliceRadioQueue.Add(TOTAL_AUDIO_SAMPLES);
+ m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_MESSAGE_NOISE_1);
+ m_sPoliceRadioQueue.Add(NO_SAMPLE);
gSpecialSuspectLastSeenReport = TRUE;
break;
}
@@ -776,7 +745,7 @@ cAudioManager::AgeCrimes()
{
for (uint8 i = 0; i < ARRAY_SIZE(m_sPoliceRadioQueue.crimes); i++) {
if (m_sPoliceRadioQueue.crimes[i].type != CRIME_NONE) {
- if (++m_sPoliceRadioQueue.crimes[i].timer > 1500) m_sPoliceRadioQueue.crimes[i].type = CRIME_NONE;
+ if (++m_sPoliceRadioQueue.crimes[i].timer > 1200) m_sPoliceRadioQueue.crimes[i].type = CRIME_NONE;
}
}
}
diff --git a/src/audio/PolRadio.h b/src/audio/PolRadio.h
index 368708b6..d7c928e2 100644
--- a/src/audio/PolRadio.h
+++ b/src/audio/PolRadio.h
@@ -43,4 +43,4 @@ public:
}
};
-VALIDATE_SIZE(cPoliceRadioQueue, 444);
+VALIDATE_SIZE(cPoliceRadioQueue, 0x1BC);
diff --git a/src/audio/audio_enums.h b/src/audio/audio_enums.h
index 69d37a64..5a14d312 100644
--- a/src/audio/audio_enums.h
+++ b/src/audio/audio_enums.h
@@ -2,19 +2,20 @@
enum eRadioStation
{
- HEAD_RADIO,
- DOUBLE_CLEF,
- JAH_RADIO,
- RISE_FM,
- LIPS_106,
- GAME_FM,
- MSX_FM,
- FLASHBACK,
- CHATTERBOX,
+ WILDSTYLE,
+ FLASH_FM,
+ KCHAT,
+ FEVER,
+ V_ROCK,
+ VCPR,
+ RADIO_ESPANTOSO,
+ EMOTION,
+ WAVE,
USERTRACK,
- POLICE_RADIO = 10,
NUM_RADIOS = 10,
- RADIO_OFF = 11,
+ POLICE_RADIO = 10,
+ RADIO_OFF = 10,
+ //TAXI_RADIO,
};
enum eMusicMode
@@ -26,204 +27,1241 @@ enum eMusicMode
MUSICMODE_DISABLED,
};
+enum ePlayerMood
+{
+ PLAYER_MOOD_CALM = 0,
+ PLAYER_MOOD_PISSED_OFF,
+ PLAYER_MOOD_ANGRY,
+ PLAYER_MOOD_WISECRACKING,
+ MAX_PLAYER_MOODS,
+};
+
enum eStreamedSounds
{
- STREAMED_SOUND_RADIO_HEAD,
- STREAMED_SOUND_RADIO_CLASSIC,
- STREAMED_SOUND_RADIO_KJAH,
- STREAMED_SOUND_RADIO_RISE,
- STREAMED_SOUND_RADIO_LIPS,
- STREAMED_SOUND_RADIO_GAME,
- STREAMED_SOUND_RADIO_MSX,
+ STREAMED_SOUND_RADIO_WILD,
STREAMED_SOUND_RADIO_FLASH,
- STREAMED_SOUND_RADIO_CHAT,
+ STREAMED_SOUND_RADIO_KCHAT,
+ STREAMED_SOUND_RADIO_FEVER,
+ STREAMED_SOUND_RADIO_VROCK,
+ STREAMED_SOUND_RADIO_VCPR,
+ STREAMED_SOUND_RADIO_ESPANTOSO,
+ STREAMED_SOUND_RADIO_EMOTION,
+ STREAMED_SOUND_RADIO_WAVE,
STREAMED_SOUND_RADIO_MP3_PLAYER,
- STREAMED_SOUND_RADIO_POLICE,
STREAMED_SOUND_CITY_AMBIENT,
STREAMED_SOUND_WATER_AMBIENT,
- STREAMED_SOUND_ANNOUNCE_COMMERCIAL_OPEN,
- STREAMED_SOUND_ANNOUNCE_SUBURBAN_OPEN,
- STREAMED_SOUND_NEWS_INTRO,
- STREAMED_SOUND_BANK_INTRO,
- STREAMED_SOUND_CUTSCENE_LUIGI1_LG,
- STREAMED_SOUND_CUTSCENE_LUIGI2_DSB,
- STREAMED_SOUND_CUTSCENE_LUIGI3_DM,
- STREAMED_SOUND_CUTSCENE_LUIGI4_PAP,
- STREAMED_SOUND_CUTSCENE_LUIGI5_TFB,
- STREAMED_SOUND_CUTSCENE_JOEY0_DM2,
- STREAMED_SOUND_CUTSCENE_JOEY1_LFL,
- STREAMED_SOUND_CUTSCENE_JOEY2_KCL,
- STREAMED_SOUND_CUTSCENE_JOEY3_VH,
- STREAMED_SOUND_CUTSCENE_JOEY4_ETH,
- STREAMED_SOUND_CUTSCENE_JOEY5_DST,
- STREAMED_SOUND_CUTSCENE_JOEY6_TBJ,
- STREAMED_SOUND_CUTSCENE_TONI1_TOL,
- STREAMED_SOUND_CUTSCENE_TONI2_TPU,
- STREAMED_SOUND_CUTSCENE_TONI3_MAS,
- STREAMED_SOUND_CUTSCENE_TONI4_TAT,
- STREAMED_SOUND_CUTSCENE_TONI5_BF,
- STREAMED_SOUND_CUTSCENE_SAL0_MAS,
- STREAMED_SOUND_CUTSCENE_SAL1_PF,
- STREAMED_SOUND_CUTSCENE_SAL2_CTG,
- STREAMED_SOUND_CUTSCENE_SAL3_RTC,
- STREAMED_SOUND_CUTSCENE_SAL5_LRQ,
- STREAMED_SOUND_CUTSCENE_SAL4_BDBA,
- STREAMED_SOUND_CUTSCENE_SAL4_BDBB,
- STREAMED_SOUND_CUTSCENE_SAL2_CTG2,
- STREAMED_SOUND_CUTSCENE_SAL4_BDBD,
- STREAMED_SOUND_CUTSCENE_SAL5_LRQB,
- STREAMED_SOUND_CUTSCENE_SAL5_LRQC,
- STREAMED_SOUND_CUTSCENE_ASUKA_1_SSO,
- STREAMED_SOUND_CUTSCENE_ASUKA_2_PP,
- STREAMED_SOUND_CUTSCENE_ASUKA_3_SS,
- STREAMED_SOUND_CUTSCENE_ASUKA_4_PDR,
- STREAMED_SOUND_CUTSCENE_ASUKA_5_K2FT,
- STREAMED_SOUND_CUTSCENE_KENJI1_KBO,
- STREAMED_SOUND_CUTSCENE_KENJI2_GIS,
- STREAMED_SOUND_CUTSCENE_KENJI3_DS,
- STREAMED_SOUND_CUTSCENE_KENJI4_SHI,
- STREAMED_SOUND_CUTSCENE_KENJI5_SD,
- STREAMED_SOUND_CUTSCENE_RAY0_PDR2,
- STREAMED_SOUND_CUTSCENE_RAY1_SW,
- STREAMED_SOUND_CUTSCENE_RAY2_AP,
- STREAMED_SOUND_CUTSCENE_RAY3_ED,
- STREAMED_SOUND_CUTSCENE_RAY4_GF,
- STREAMED_SOUND_CUTSCENE_RAY5_PB,
- STREAMED_SOUND_CUTSCENE_RAY6_MM,
- STREAMED_SOUND_CUTSCENE_DONALD1_STOG,
- STREAMED_SOUND_CUTSCENE_DONALD2_KK,
- STREAMED_SOUND_CUTSCENE_DONALD3_ADO,
- STREAMED_SOUND_CUTSCENE_DONALD5_ES,
- STREAMED_SOUND_CUTSCENE_DONALD7_MLD,
- STREAMED_SOUND_CUTSCENE_DONALD4_GTA,
- STREAMED_SOUND_CUTSCENE_DONALD4_GTA2,
- STREAMED_SOUND_CUTSCENE_DONALD6_STS,
- STREAMED_SOUND_CUTSCENE_ASUKA6_BAIT,
- STREAMED_SOUND_CUTSCENE_ASUKA7_ETG,
- STREAMED_SOUND_CUTSCENE_ASUKA8_PS,
- STREAMED_SOUND_CUTSCENE_ASUKA9_ASD,
- STREAMED_SOUND_CUTSCENE_KENJI4_SHI2,
- STREAMED_SOUND_CUTSCENE_CATALINA1_TEX,
+ STREAMED_SOUND_BEACH_AMBIENT,
+ STREAMED_SOUND_HAVANA_CITY_AMBIENT,
+ STREAMED_SOUND_HAVANA_WATER_AMBIENT,
+ STREAMED_SOUND_HAVANA_BEACH_AMBIENT,
+ STREAMED_SOUND_MALL_AMBIENT,
+ STREAMED_SOUND_STRIPCLUB_AMBIENT,
+ STREAMED_SOUND_MALIBU_AMBIENT,
+ STREAMED_SOUND_HOTEL_AMBIENT,
+ STREAMED_SOUND_DIRTRING_AMBIENT,
+ STREAMED_SOUND_LAW4RIOT_AMBIENT,
+ STREAMED_SOUND_AMBSIL_AMBIENT,
+ STREAMED_SOUND_RADIO_POLICE,
+ STREAMED_SOUND_RADIO_TAXI,
+ STREAMED_SOUND_ANNOUNCE_BRIDGE_CLOSED,
+ STREAMED_SOUND_ANNOUNCE_BRIDGE_OPEN,
+ STREAMED_SOUND_CUTSCENE_ASS_1,
+ STREAMED_SOUND_CUTSCENE_ASS_2,
+ STREAMED_SOUND_CUTSCENE_BANK_1,
+ STREAMED_SOUND_CUTSCENE_BANK_2A,
+ STREAMED_SOUND_CUTSCENE_BANK_2B,
+ STREAMED_SOUND_CUTSCENE_BANK_3A,
+ STREAMED_SOUND_CUTSCENE_BANK_3B,
+ STREAMED_SOUND_CUTSCENE_BANK_4,
+ STREAMED_SOUND_CUTSCENE_BIKE_1,
+ STREAMED_SOUND_CUTSCENE_BIKE_2,
+ STREAMED_SOUND_CUTSCENE_BIKE_3,
+ STREAMED_SOUND_CUTSCENE_BUD_1,
+ STREAMED_SOUND_CUTSCENE_BUD_2,
+ STREAMED_SOUND_CUTSCENE_BUD_3,
+ STREAMED_SOUND_CUTSCENE_CAP_1,
+ STREAMED_SOUND_CUTSCENE_CAR_1,
+ STREAMED_SOUND_CUTSCENE_CNT_1A,
+ STREAMED_SOUND_CUTSCENE_CNT_1B,
+ STREAMED_SOUND_CUTSCENE_CNT_2,
+ STREAMED_SOUND_CUTSCENE_COK_1,
+ STREAMED_SOUND_CUTSCENE_COK_2A,
+ STREAMED_SOUND_CUTSCENE_COK_2B,
+ STREAMED_SOUND_CUTSCENE_COK_3,
+ STREAMED_SOUND_CUTSCENE_COK_4A,
+ STREAMED_SOUND_CUTSCENE_COK_4A2,
+ STREAMED_SOUND_CUTSCENE_COK_4B,
+ STREAMED_SOUND_CUTSCENE_COL_1,
+ STREAMED_SOUND_CUTSCENE_COL_2,
+ STREAMED_SOUND_CUTSCENE_COL_3A,
+ STREAMED_SOUND_CUTSCENE_COL_4A,
+ STREAMED_SOUND_CUTSCENE_COL_5A,
+ STREAMED_SOUND_CUTSCENE_COL_5B,
+ STREAMED_SOUND_CUTSCENE_CUB_1,
+ STREAMED_SOUND_CUTSCENE_CUB_2,
+ STREAMED_SOUND_CUTSCENE_CUB_3,
+ STREAMED_SOUND_CUTSCENE_CUB_4,
+ STREAMED_SOUND_CUTSCENE_DRUG_1,
+ STREAMED_SOUND_CUTSCENE_FIN,
+ STREAMED_SOUND_CUTSCENE_FIN2,
+ STREAMED_SOUND_CUTSCENE_FINALE,
+ STREAMED_SOUND_CUTSCENE_HAT_1,
+ STREAMED_SOUND_CUTSCENE_HAT_2,
+ STREAMED_SOUND_CUTSCENE_HAT_3,
+ STREAMED_SOUND_CUTSCENE_ICE_1,
+ STREAMED_SOUND_CUTSCENE_INT_A,
+ STREAMED_SOUND_CUTSCENE_INT_B,
+ STREAMED_SOUND_CUTSCENE_INT_D,
+ STREAMED_SOUND_CUTSCENE_INT_M,
+ STREAMED_SOUND_CUTSCENE_LAW_1A,
+ STREAMED_SOUND_CUTSCENE_LAW_1B,
+ STREAMED_SOUND_CUTSCENE_LAW_2A,
+ STREAMED_SOUND_CUTSCENE_LAW_2B,
+ STREAMED_SOUND_CUTSCENE_LAW_2C,
+ STREAMED_SOUND_CUTSCENE_LAW_3,
+ STREAMED_SOUND_CUTSCENE_LAW_4,
+ STREAMED_SOUND_CUTSCENE_PHIL_1,
+ STREAMED_SOUND_CUTSCENE_PHIL_2,
+ STREAMED_SOUND_CUTSCENE_PORN_1,
+ STREAMED_SOUND_CUTSCENE_PORN_2,
+ STREAMED_SOUND_CUTSCENE_PORN_3,
+ STREAMED_SOUND_CUTSCENE_PORN_4,
+ STREAMED_SOUND_CUTSCENE_RESC_1A,
+ STREAMED_SOUND_CUTSCENE_ROK_1,
+ STREAMED_SOUND_CUTSCENE_ROK_2,
+ STREAMED_SOUND_CUTSCENE_ROK_3A,
+ STREAMED_SOUND_CUTSCENE_STRIPA,
+ STREAMED_SOUND_CUTSCENE_TAX_1,
+ STREAMED_SOUND_CUTSCENE_TEX_1,
+ STREAMED_SOUND_CUTSCENE_TEX_2,
+ STREAMED_SOUND_CUTSCENE_TEX_3,
+ STREAMED_SOUND_CUTSCENE_GLIGHT,
+ STREAMED_SOUND_CUTSCENE_FIST,
STREAMED_SOUND_CUTSCENE_ELBURRO1_PH1,
STREAMED_SOUND_CUTSCENE_ELBURRO2_PH2,
- STREAMED_SOUND_CUTSCENE_ELBURRO3_PH3,
- STREAMED_SOUND_CUTSCENE_ELBURRO4_PH4,
- STREAMED_SOUND_CUTSCENE_YARDIE_PH1,
- STREAMED_SOUND_CUTSCENE_YARDIE_PH2,
- STREAMED_SOUND_CUTSCENE_YARDIE_PH3,
- STREAMED_SOUND_CUTSCENE_YARDIE_PH4,
- STREAMED_SOUND_CUTSCENE_HOODS_PH1,
- STREAMED_SOUND_CUTSCENE_HOODS_PH2,
- STREAMED_SOUND_CUTSCENE_HOODS_PH3,
- STREAMED_SOUND_CUTSCENE_HOODS_PH4,
- STREAMED_SOUND_CUTSCENE_HOODS_PH5,
- STREAMED_SOUND_CUTSCENE_MARTY_PH1,
- STREAMED_SOUND_CUTSCENE_MARTY_PH2,
- STREAMED_SOUND_CUTSCENE_MARTY_PH3,
- STREAMED_SOUND_CUTSCENE_MARTY_PH4,
STREAMED_SOUND_MISSION_COMPLETED,
- STREAMED_SOUND_GAME_COMPLETED,
- STREAMED_SOUND_MISSION_LIB_A1,
- STREAMED_SOUND_MISSION_LIB_A2,
- STREAMED_SOUND_MISSION_LIB_A,
- STREAMED_SOUND_MISSION_LIB_B,
- STREAMED_SOUND_MISSION_LIB_C,
- STREAMED_SOUND_MISSION_LIB_D,
- STREAMED_SOUND_MISSION_L2_A,
- STREAMED_SOUND_MISSION_J4T_1,
- STREAMED_SOUND_MISSION_J4T_2,
- STREAMED_SOUND_MISSION_J4T_3,
- STREAMED_SOUND_MISSION_J4T_4,
- STREAMED_SOUND_MISSION_J4_A,
- STREAMED_SOUND_MISSION_J4_B,
- STREAMED_SOUND_MISSION_J4_C,
- STREAMED_SOUND_MISSION_J4_D,
- STREAMED_SOUND_MISSION_J4_E,
- STREAMED_SOUND_MISSION_J4_F,
- STREAMED_SOUND_MISSION_J6_1,
- STREAMED_SOUND_MISSION_J6_A,
- STREAMED_SOUND_MISSION_J6_B,
- STREAMED_SOUND_MISSION_J6_C,
- STREAMED_SOUND_MISSION_J6_D,
- STREAMED_SOUND_MISSION_T4_A,
- STREAMED_SOUND_MISSION_S1_A,
- STREAMED_SOUND_MISSION_S1_A1,
- STREAMED_SOUND_MISSION_S1_B,
- STREAMED_SOUND_MISSION_S1_C,
- STREAMED_SOUND_MISSION_S1_C1,
- STREAMED_SOUND_MISSION_S1_D,
- STREAMED_SOUND_MISSION_S1_E,
- STREAMED_SOUND_MISSION_S1_F,
- STREAMED_SOUND_MISSION_S1_G,
- STREAMED_SOUND_MISSION_S1_H,
- STREAMED_SOUND_MISSION_S1_I,
- STREAMED_SOUND_MISSION_S1_J,
- STREAMED_SOUND_MISSION_S1_K,
- STREAMED_SOUND_MISSION_S1_L,
- STREAMED_SOUND_MISSION_S3_A,
- STREAMED_SOUND_MISSION_S3_B,
- STREAMED_SOUND_MISSION_EL3_A,
- STREAMED_SOUND_MISSION_MF1_A,
- STREAMED_SOUND_MISSION_MF2_A,
- STREAMED_SOUND_MISSION_MF3_A,
- STREAMED_SOUND_MISSION_MF3_B,
- STREAMED_SOUND_MISSION_MF3_B1,
- STREAMED_SOUND_MISSION_MF3_C,
- STREAMED_SOUND_MISSION_MF4_A,
- STREAMED_SOUND_MISSION_MF4_B,
- STREAMED_SOUND_MISSION_MF4_C,
- STREAMED_SOUND_MISSION_A1_A,
- STREAMED_SOUND_MISSION_A3_A,
- STREAMED_SOUND_MISSION_A5_A,
- STREAMED_SOUND_MISSION_A4_A,
- STREAMED_SOUND_MISSION_A4_B,
- STREAMED_SOUND_MISSION_A4_C,
- STREAMED_SOUND_MISSION_A4_D,
- STREAMED_SOUND_MISSION_K1_A,
- STREAMED_SOUND_MISSION_K3_A,
- STREAMED_SOUND_MISSION_R1_A,
- STREAMED_SOUND_MISSION_R2_A,
- STREAMED_SOUND_MISSION_R2_B,
- STREAMED_SOUND_MISSION_R2_C,
- STREAMED_SOUND_MISSION_R2_D,
- STREAMED_SOUND_MISSION_R2_E,
- STREAMED_SOUND_MISSION_R2_F,
- STREAMED_SOUND_MISSION_R2_G,
- STREAMED_SOUND_MISSION_R2_H,
- STREAMED_SOUND_MISSION_R5_A,
- STREAMED_SOUND_MISSION_R6_A,
- STREAMED_SOUND_MISSION_R6_A1,
- STREAMED_SOUND_MISSION_R6_B,
- STREAMED_SOUND_MISSION_LO2_A,
- STREAMED_SOUND_MISSION_LO6_A,
- STREAMED_SOUND_MISSION_YD2_A,
- STREAMED_SOUND_MISSION_YD2_B,
- STREAMED_SOUND_MISSION_YD2_C,
- STREAMED_SOUND_MISSION_YD2_C1,
- STREAMED_SOUND_MISSION_YD2_D,
- STREAMED_SOUND_MISSION_YD2_E,
- STREAMED_SOUND_MISSION_YD2_F,
- STREAMED_SOUND_MISSION_YD2_G,
- STREAMED_SOUND_MISSION_YD2_H,
- STREAMED_SOUND_MISSION_YD2_ASS,
- STREAMED_SOUND_MISSION_YD2_OK,
- STREAMED_SOUND_MISSION_H5_A,
- STREAMED_SOUND_MISSION_H5_B,
- STREAMED_SOUND_MISSION_H5_C,
- STREAMED_SOUND_MISSION_AMMU_A,
- STREAMED_SOUND_MISSION_AMMU_B,
- STREAMED_SOUND_MISSION_AMMU_C,
- STREAMED_SOUND_MISSION_DOOR_1,
- STREAMED_SOUND_MISSION_DOOR_2,
- STREAMED_SOUND_MISSION_DOOR_3,
- STREAMED_SOUND_MISSION_DOOR_4,
- STREAMED_SOUND_MISSION_DOOR_5,
- STREAMED_SOUND_MISSION_DOOR_6,
- STREAMED_SOUND_MISSION_T3_A,
- STREAMED_SOUND_MISSION_T3_B,
- STREAMED_SOUND_MISSION_T3_C,
- STREAMED_SOUND_MISSION_K1_B,
- STREAMED_SOUND_MISSION_CAT1,
+ STREAMED_SOUND_MISSION_COMPLETED4,
+ STREAMED_SOUND_MISSION_MOBR1,
+ STREAMED_SOUND_MISSION_PAGER,
+ STREAMED_SOUND_MISSION_CARREV,
+ STREAMED_SOUND_MISSION_BIKEREV,
+ STREAMED_SOUND_MISSION_LIFTOP,
+ STREAMED_SOUND_MISSION_LIFTCL,
+ STREAMED_SOUND_MISSION_LIFTRUN,
+ STREAMED_SOUND_MISSION_LIFTBEL,
+ STREAMED_SOUND_MISSION_INLIFT,
+ STREAMED_SOUND_MISSION_SFX_01,
+ STREAMED_SOUND_MISSION_SFX_02,
+ STREAMED_SOUND_MISSION_CAMERAL,
+ STREAMED_SOUND_MISSION_CAMERAR,
+ STREAMED_SOUND_MISSION_CHEER1,
+ STREAMED_SOUND_MISSION_CHEER2,
+ STREAMED_SOUND_MISSION_CHEER3,
+ STREAMED_SOUND_MISSION_CHEER4,
+ STREAMED_SOUND_MISSION_OOH1,
+ STREAMED_SOUND_MISSION_OOH2,
+ STREAMED_SOUND_MISSION_RACE1,
+ STREAMED_SOUND_MISSION_RACE2,
+ STREAMED_SOUND_MISSION_RACE3,
+ STREAMED_SOUND_MISSION_RACE4,
+ STREAMED_SOUND_MISSION_RACE5,
+ STREAMED_SOUND_MISSION_RACE6,
+ STREAMED_SOUND_MISSION_RACE7,
+ STREAMED_SOUND_MISSION_RACE8,
+ STREAMED_SOUND_MISSION_RACE9,
+ STREAMED_SOUND_MISSION_RACE10,
+ STREAMED_SOUND_MISSION_RACE11,
+ STREAMED_SOUND_MISSION_RACE12,
+ STREAMED_SOUND_MISSION_RACE13,
+ STREAMED_SOUND_MISSION_RACE14,
+ STREAMED_SOUND_MISSION_RACE15,
+ STREAMED_SOUND_MISSION_HOT1,
+ STREAMED_SOUND_MISSION_HOT2,
+ STREAMED_SOUND_MISSION_HOT3,
+ STREAMED_SOUND_MISSION_HOT4,
+ STREAMED_SOUND_MISSION_HOT5,
+ STREAMED_SOUND_MISSION_HOT6,
+ STREAMED_SOUND_MISSION_HOT7,
+ STREAMED_SOUND_MISSION_HOT8,
+ STREAMED_SOUND_MISSION_HOT9,
+ STREAMED_SOUND_MISSION_HOT10,
+ STREAMED_SOUND_MISSION_HOT11,
+ STREAMED_SOUND_MISSION_HOT12,
+ STREAMED_SOUND_MISSION_HOT13,
+ STREAMED_SOUND_MISSION_HOT14,
+ STREAMED_SOUND_MISSION_HOT15,
+ STREAMED_SOUND_MISSION_LANSTP1,
+ STREAMED_SOUND_MISSION_LANSTP2,
+ STREAMED_SOUND_MISSION_LANAMU1,
+ STREAMED_SOUND_MISSION_LANAMU2,
+ STREAMED_SOUND_MISSION_AIRHORNL,
+ STREAMED_SOUND_MISSION_AIRHORNR,
+ STREAMED_SOUND_MISSION_SNIPSCRL,
+ STREAMED_SOUND_MISSION_SNIPSHORT,
+ STREAMED_SOUND_MISSION_BLOWROOF,
+ STREAMED_SOUND_MISSION_ASS_1,
+ STREAMED_SOUND_MISSION_ASS_2,
+ STREAMED_SOUND_MISSION_ASS_3,
+ STREAMED_SOUND_MISSION_ASS_4,
+ STREAMED_SOUND_MISSION_ASS_5,
+ STREAMED_SOUND_MISSION_ASS_6,
+ STREAMED_SOUND_MISSION_ASS_7,
+ STREAMED_SOUND_MISSION_ASS_8,
+ STREAMED_SOUND_MISSION_ASS_9,
+ STREAMED_SOUND_MISSION_ASS_10,
+ STREAMED_SOUND_MISSION_ASS_11,
+ STREAMED_SOUND_MISSION_ASS_12,
+ STREAMED_SOUND_MISSION_ASS_13,
+ STREAMED_SOUND_MISSION_ASS_14,
+ STREAMED_SOUND_MISSION_BIKE1_1,
+ STREAMED_SOUND_MISSION_BIKE1_2,
+ STREAMED_SOUND_MISSION_BIKE1_3,
+ STREAMED_SOUND_MISSION_BNK1_1,
+ STREAMED_SOUND_MISSION_BNK1_2,
+ STREAMED_SOUND_MISSION_BNK1_3,
+ STREAMED_SOUND_MISSION_BNK1_4,
+ STREAMED_SOUND_MISSION_BNK1_5,
+ STREAMED_SOUND_MISSION_BNK1_6,
+ STREAMED_SOUND_MISSION_BNK1_7,
+ STREAMED_SOUND_MISSION_BNK1_8,
+ STREAMED_SOUND_MISSION_BNK1_10,
+ STREAMED_SOUND_MISSION_BNK1_11,
+ STREAMED_SOUND_MISSION_BNK1_12,
+ STREAMED_SOUND_MISSION_BNK1_13,
+ STREAMED_SOUND_MISSION_BNK1_14,
+ STREAMED_SOUND_MISSION_BNK2_1,
+ STREAMED_SOUND_MISSION_BNK2_2,
+ STREAMED_SOUND_MISSION_BNK2_3,
+ STREAMED_SOUND_MISSION_BNK2_4,
+ STREAMED_SOUND_MISSION_BNK2_5,
+ STREAMED_SOUND_MISSION_BNK2_6,
+ STREAMED_SOUND_MISSION_BNK2_7,
+ STREAMED_SOUND_MISSION_BNK2_8,
+ STREAMED_SOUND_MISSION_BNK2_9,
+ STREAMED_SOUND_MISSION_BNK3_1,
+ STREAMED_SOUND_MISSION_BNK3_2,
+ STREAMED_SOUND_MISSION_BNK3_3A,
+ STREAMED_SOUND_MISSION_BNK3_3B,
+ STREAMED_SOUND_MISSION_BNK3_3C,
+ STREAMED_SOUND_MISSION_BNK3_4A,
+ STREAMED_SOUND_MISSION_BNK3_4B,
+ STREAMED_SOUND_MISSION_BNK3_4C,
+ STREAMED_SOUND_MISSION_BNK4_1,
+ STREAMED_SOUND_MISSION_BNK4_2,
+ STREAMED_SOUND_MISSION_BNK4_3A,
+ STREAMED_SOUND_MISSION_BNK4_3B,
+ STREAMED_SOUND_MISSION_BNK4_3C,
+ STREAMED_SOUND_MISSION_BNK4_3D,
+ STREAMED_SOUND_MISSION_BNK4_3E,
+ STREAMED_SOUND_MISSION_BNK4_3F,
+ STREAMED_SOUND_MISSION_BNK4_3G,
+ STREAMED_SOUND_MISSION_BNK4_3H,
+ STREAMED_SOUND_MISSION_BNK4_3I,
+ STREAMED_SOUND_MISSION_BNK4_3J,
+ STREAMED_SOUND_MISSION_BNK4_3K,
+ STREAMED_SOUND_MISSION_BNK4_3M,
+ STREAMED_SOUND_MISSION_BNK4_3O,
+ STREAMED_SOUND_MISSION_BNK4_3P,
+ STREAMED_SOUND_MISSION_BNK4_3Q,
+ STREAMED_SOUND_MISSION_BNK4_3R,
+ STREAMED_SOUND_MISSION_BNK4_3S,
+ STREAMED_SOUND_MISSION_BNK4_3T,
+ STREAMED_SOUND_MISSION_BNK4_3U,
+ STREAMED_SOUND_MISSION_BNK4_3V,
+ STREAMED_SOUND_MISSION_BNK4_4A,
+ STREAMED_SOUND_MISSION_BNK4_4B,
+ STREAMED_SOUND_MISSION_BNK4_5,
+ STREAMED_SOUND_MISSION_BNK4_6,
+ STREAMED_SOUND_MISSION_BNK4_7,
+ STREAMED_SOUND_MISSION_BNK4_8,
+ STREAMED_SOUND_MISSION_BNK4_9,
+ STREAMED_SOUND_MISSION_BNK4_10,
+ STREAMED_SOUND_MISSION_BNK4_11,
+ STREAMED_SOUND_MISSION_BK4_12A,
+ STREAMED_SOUND_MISSION_BK4_12B,
+ STREAMED_SOUND_MISSION_BK4_12C,
+ STREAMED_SOUND_MISSION_BNK4_13,
+ STREAMED_SOUND_MISSION_BK4_14A,
+ STREAMED_SOUND_MISSION_BK4_14B,
+ STREAMED_SOUND_MISSION_BNK4_15,
+ STREAMED_SOUND_MISSION_BNK4_16,
+ STREAMED_SOUND_MISSION_BNK4_17,
+ STREAMED_SOUND_MISSION_BNK4_18,
+ STREAMED_SOUND_MISSION_BK4_19A,
+ STREAMED_SOUND_MISSION_BK4_19B,
+ STREAMED_SOUND_MISSION_BK4_20A,
+ STREAMED_SOUND_MISSION_BK4_20B,
+ STREAMED_SOUND_MISSION_BNK4_21,
+ STREAMED_SOUND_MISSION_BNK422A,
+ STREAMED_SOUND_MISSION_BNK422B,
+ STREAMED_SOUND_MISSION_BK4_23A,
+ STREAMED_SOUND_MISSION_BK4_23B,
+ STREAMED_SOUND_MISSION_BK4_23C,
+ STREAMED_SOUND_MISSION_BK4_23D,
+ STREAMED_SOUND_MISSION_BK4_24A,
+ STREAMED_SOUND_MISSION_BK4_24B,
+ STREAMED_SOUND_MISSION_BNK4_25,
+ STREAMED_SOUND_MISSION_BNK4_26,
+ STREAMED_SOUND_MISSION_BNK4_27,
+ STREAMED_SOUND_MISSION_BNK4_28,
+ STREAMED_SOUND_MISSION_BNK4_29,
+ STREAMED_SOUND_MISSION_BNK4_30,
+ STREAMED_SOUND_MISSION_BK4_31A,
+ STREAMED_SOUND_MISSION_BK4_31B,
+ STREAMED_SOUND_MISSION_BNK4_32,
+ STREAMED_SOUND_MISSION_BK4_34A,
+ STREAMED_SOUND_MISSION_BK4_34B,
+ STREAMED_SOUND_MISSION_BK4_35A,
+ STREAMED_SOUND_MISSION_BK4_35B,
+ STREAMED_SOUND_MISSION_BNK4_36,
+ STREAMED_SOUND_MISSION_BNK4_37,
+ STREAMED_SOUND_MISSION_BNK4_38,
+ STREAMED_SOUND_MISSION_BNK4_39,
+ STREAMED_SOUND_MISSION_BK4_40A,
+ STREAMED_SOUND_MISSION_BK4_40B,
+ STREAMED_SOUND_MISSION_BNK4_41,
+ STREAMED_SOUND_MISSION_BNK4_42,
+ STREAMED_SOUND_MISSION_BNK4_43,
+ STREAMED_SOUND_MISSION_BNK4_44,
+ STREAMED_SOUND_MISSION_BNK4_45,
+ STREAMED_SOUND_MISSION_BNK4_46,
+ STREAMED_SOUND_MISSION_BNK4_47,
+ STREAMED_SOUND_MISSION_BNK4_48,
+ STREAMED_SOUND_MISSION_BNK4_49,
+ STREAMED_SOUND_MISSION_BNK450A,
+ STREAMED_SOUND_MISSION_BNK450B,
+ STREAMED_SOUND_MISSION_BNK4_51,
+ STREAMED_SOUND_MISSION_BNK4_94,
+ STREAMED_SOUND_MISSION_BNK4_95,
+ STREAMED_SOUND_MISSION_BNK4_96,
+ STREAMED_SOUND_MISSION_BNK4_97,
+ STREAMED_SOUND_MISSION_BNK4_98,
+ STREAMED_SOUND_MISSION_BNK4_99,
+ STREAMED_SOUND_MISSION_BUD1_1,
+ STREAMED_SOUND_MISSION_BUD1_2,
+ STREAMED_SOUND_MISSION_BUD1_3,
+ STREAMED_SOUND_MISSION_BUD1_4,
+ STREAMED_SOUND_MISSION_BUD1_5,
+ STREAMED_SOUND_MISSION_BUD1_9,
+ STREAMED_SOUND_MISSION_BUD1_10,
+ STREAMED_SOUND_MISSION_BUD2_1,
+ STREAMED_SOUND_MISSION_BUD2_2,
+ STREAMED_SOUND_MISSION_BUD2_3,
+ STREAMED_SOUND_MISSION_BUD2_4,
+ STREAMED_SOUND_MISSION_BUD2_5,
+ STREAMED_SOUND_MISSION_BUD2_6,
+ STREAMED_SOUND_MISSION_BUD2_7,
+ STREAMED_SOUND_MISSION_BUD3_1,
+ STREAMED_SOUND_MISSION_BUD3_1A,
+ STREAMED_SOUND_MISSION_BUD3_1B,
+ STREAMED_SOUND_MISSION_BUD3_1C,
+ STREAMED_SOUND_MISSION_BUD3_2,
+ STREAMED_SOUND_MISSION_BUD3_3,
+ STREAMED_SOUND_MISSION_BUD3_4,
+ STREAMED_SOUND_MISSION_BUD3_5,
+ STREAMED_SOUND_MISSION_BUD3_6,
+ STREAMED_SOUND_MISSION_BUD3_7,
+ STREAMED_SOUND_MISSION_BUD3_8A,
+ STREAMED_SOUND_MISSION_BUD3_8B,
+ STREAMED_SOUND_MISSION_BUD3_8C,
+ STREAMED_SOUND_MISSION_BUD3_9A,
+ STREAMED_SOUND_MISSION_BUD3_9B,
+ STREAMED_SOUND_MISSION_BUD3_9C,
+ STREAMED_SOUND_MISSION_CAP1_2,
+ STREAMED_SOUND_MISSION_CAP1_3,
+ STREAMED_SOUND_MISSION_CAP1_4,
+ STREAMED_SOUND_MISSION_CAP1_5,
+ STREAMED_SOUND_MISSION_CAP1_6,
+ STREAMED_SOUND_MISSION_CAP1_7,
+ STREAMED_SOUND_MISSION_CAP1_8,
+ STREAMED_SOUND_MISSION_CAP1_9,
+ STREAMED_SOUND_MISSION_CAP1_10,
+ STREAMED_SOUND_MISSION_CAP1_11,
+ STREAMED_SOUND_MISSION_CAP1_12,
+ STREAMED_SOUND_MISSION_CNT1_1,
+ STREAMED_SOUND_MISSION_CNT1_2,
+ STREAMED_SOUND_MISSION_CNT1_3,
+ STREAMED_SOUND_MISSION_CNT1_4,
+ STREAMED_SOUND_MISSION_CNT1_5,
+ STREAMED_SOUND_MISSION_CNT2_1,
+ STREAMED_SOUND_MISSION_CNT2_2,
+ STREAMED_SOUND_MISSION_CNT2_3,
+ STREAMED_SOUND_MISSION_CNT2_4,
+ STREAMED_SOUND_MISSION_COK1_1,
+ STREAMED_SOUND_MISSION_COK1_2,
+ STREAMED_SOUND_MISSION_COK1_3,
+ STREAMED_SOUND_MISSION_COK1_4,
+ STREAMED_SOUND_MISSION_COK1_5,
+ STREAMED_SOUND_MISSION_COK1_6,
+ STREAMED_SOUND_MISSION_COK2_1,
+ STREAMED_SOUND_MISSION_COK2_2,
+ STREAMED_SOUND_MISSION_COK2_3,
+ STREAMED_SOUND_MISSION_COK2_4,
+ STREAMED_SOUND_MISSION_COK2_5,
+ STREAMED_SOUND_MISSION_COK2_6,
+ STREAMED_SOUND_MISSION_COK2_7A,
+ STREAMED_SOUND_MISSION_COK2_7B,
+ STREAMED_SOUND_MISSION_COK2_7C,
+ STREAMED_SOUND_MISSION_COK2_8A,
+ STREAMED_SOUND_MISSION_COK2_8B,
+ STREAMED_SOUND_MISSION_COK2_8C,
+ STREAMED_SOUND_MISSION_COK2_8D,
+ STREAMED_SOUND_MISSION_COK2_9,
+ STREAMED_SOUND_MISSION_COK210A,
+ STREAMED_SOUND_MISSION_COK210B,
+ STREAMED_SOUND_MISSION_COK210C,
+ STREAMED_SOUND_MISSION_COK212A,
+ STREAMED_SOUND_MISSION_COK212B,
+ STREAMED_SOUND_MISSION_COK2_13,
+ STREAMED_SOUND_MISSION_COK2_14,
+ STREAMED_SOUND_MISSION_COK2_15,
+ STREAMED_SOUND_MISSION_COK2_16,
+ STREAMED_SOUND_MISSION_COK2_20,
+ STREAMED_SOUND_MISSION_COK2_21,
+ STREAMED_SOUND_MISSION_COK2_22,
+ STREAMED_SOUND_MISSION_COK3_1,
+ STREAMED_SOUND_MISSION_COK3_2,
+ STREAMED_SOUND_MISSION_COK3_3,
+ STREAMED_SOUND_MISSION_COK3_4,
+ STREAMED_SOUND_MISSION_COK4_1,
+ STREAMED_SOUND_MISSION_COK4_2,
+ STREAMED_SOUND_MISSION_COK4_3,
+ STREAMED_SOUND_MISSION_COK4_4,
+ STREAMED_SOUND_MISSION_COK4_5,
+ STREAMED_SOUND_MISSION_COK4_6,
+ STREAMED_SOUND_MISSION_COK4_7,
+ STREAMED_SOUND_MISSION_COK4_8,
+ STREAMED_SOUND_MISSION_COK4_9,
+ STREAMED_SOUND_MISSION_COK4_9A,
+ STREAMED_SOUND_MISSION_COK4_10,
+ STREAMED_SOUND_MISSION_COK4_11,
+ STREAMED_SOUND_MISSION_COK4_12,
+ STREAMED_SOUND_MISSION_COK4_13,
+ STREAMED_SOUND_MISSION_COK4_14,
+ STREAMED_SOUND_MISSION_COK4_15,
+ STREAMED_SOUND_MISSION_COK4_16,
+ STREAMED_SOUND_MISSION_COK4_17,
+ STREAMED_SOUND_MISSION_COK4_18,
+ STREAMED_SOUND_MISSION_COK4_19,
+ STREAMED_SOUND_MISSION_COK4_20,
+ STREAMED_SOUND_MISSION_COK4_21,
+ STREAMED_SOUND_MISSION_COK4_22,
+ STREAMED_SOUND_MISSION_COK4_23,
+ STREAMED_SOUND_MISSION_COK4_24,
+ STREAMED_SOUND_MISSION_COK4_25,
+ STREAMED_SOUND_MISSION_COK4_26,
+ STREAMED_SOUND_MISSION_COK4_27,
+ STREAMED_SOUND_MISSION_COL1_1,
+ STREAMED_SOUND_MISSION_COL1_2,
+ STREAMED_SOUND_MISSION_COL1_3,
+ STREAMED_SOUND_MISSION_COL1_4,
+ STREAMED_SOUND_MISSION_COL1_5,
+ STREAMED_SOUND_MISSION_COL1_6,
+ STREAMED_SOUND_MISSION_COL1_7,
+ STREAMED_SOUND_MISSION_COL1_8,
+ STREAMED_SOUND_MISSION_COL2_1,
+ STREAMED_SOUND_MISSION_COL2_2,
+ STREAMED_SOUND_MISSION_COL2_3,
+ STREAMED_SOUND_MISSION_COL2_4,
+ STREAMED_SOUND_MISSION_COL2_5,
+ STREAMED_SOUND_MISSION_COL2_6A,
+ STREAMED_SOUND_MISSION_COL2_7,
+ STREAMED_SOUND_MISSION_COL2_8,
+ STREAMED_SOUND_MISSION_COL2_9,
+ STREAMED_SOUND_MISSION_COL2_10,
+ STREAMED_SOUND_MISSION_COL2_11,
+ STREAMED_SOUND_MISSION_COL2_12,
+ STREAMED_SOUND_MISSION_COL2_13,
+ STREAMED_SOUND_MISSION_COL2_14,
+ STREAMED_SOUND_MISSION_COL2_15,
+ STREAMED_SOUND_MISSION_COL2_16,
+ STREAMED_SOUND_MISSION_COL3_1,
+ STREAMED_SOUND_MISSION_COL3_2,
+ STREAMED_SOUND_MISSION_COL3_2A,
+ STREAMED_SOUND_MISSION_COL3_2B,
+ STREAMED_SOUND_MISSION_COL3_3,
+ STREAMED_SOUND_MISSION_COL3_4,
+ STREAMED_SOUND_MISSION_COL3_5,
+ STREAMED_SOUND_MISSION_COL3_6,
+ STREAMED_SOUND_MISSION_COL3_7,
+ STREAMED_SOUND_MISSION_COL3_8,
+ STREAMED_SOUND_MISSION_COL3_9,
+ STREAMED_SOUND_MISSION_COL3_10,
+ STREAMED_SOUND_MISSION_COL3_11,
+ STREAMED_SOUND_MISSION_COL3_12,
+ STREAMED_SOUND_MISSION_COL3_13,
+ STREAMED_SOUND_MISSION_COL3_14,
+ STREAMED_SOUND_MISSION_COL3_15,
+ STREAMED_SOUND_MISSION_COL3_16,
+ STREAMED_SOUND_MISSION_COL3_17,
+ STREAMED_SOUND_MISSION_COL3_18,
+ STREAMED_SOUND_MISSION_COL3_19,
+ STREAMED_SOUND_MISSION_COL3_20,
+ STREAMED_SOUND_MISSION_COL3_21,
+ STREAMED_SOUND_MISSION_COL3_23,
+ STREAMED_SOUND_MISSION_COL3_24,
+ STREAMED_SOUND_MISSION_COL3_25,
+ STREAMED_SOUND_MISSION_COL4_1,
+ STREAMED_SOUND_MISSION_COL4_2,
+ STREAMED_SOUND_MISSION_COL4_3,
+ STREAMED_SOUND_MISSION_COL4_4,
+ STREAMED_SOUND_MISSION_COL4_5,
+ STREAMED_SOUND_MISSION_COL4_6,
+ STREAMED_SOUND_MISSION_COL4_7,
+ STREAMED_SOUND_MISSION_COL4_8,
+ STREAMED_SOUND_MISSION_COL4_9,
+ STREAMED_SOUND_MISSION_COL4_10,
+ STREAMED_SOUND_MISSION_COL4_11,
+ STREAMED_SOUND_MISSION_COL4_12,
+ STREAMED_SOUND_MISSION_COL4_13,
+ STREAMED_SOUND_MISSION_COL4_14,
+ STREAMED_SOUND_MISSION_COL4_15,
+ STREAMED_SOUND_MISSION_COL4_16,
+ STREAMED_SOUND_MISSION_COL4_17,
+ STREAMED_SOUND_MISSION_COL4_18,
+ STREAMED_SOUND_MISSION_COL4_19,
+ STREAMED_SOUND_MISSION_COL4_20,
+ STREAMED_SOUND_MISSION_COL4_21,
+ STREAMED_SOUND_MISSION_COL4_22,
+ STREAMED_SOUND_MISSION_COL4_23,
+ STREAMED_SOUND_MISSION_COL4_24,
+ STREAMED_SOUND_MISSION_COL4_25,
+ STREAMED_SOUND_MISSION_COL4_26,
+ STREAMED_SOUND_MISSION_COL5_1,
+ STREAMED_SOUND_MISSION_COL5_2,
+ STREAMED_SOUND_MISSION_COL5_3,
+ STREAMED_SOUND_MISSION_COL5_4,
+ STREAMED_SOUND_MISSION_COL5_5,
+ STREAMED_SOUND_MISSION_COL5_6,
+ STREAMED_SOUND_MISSION_COL5_7,
+ STREAMED_SOUND_MISSION_COL5_8,
+ STREAMED_SOUND_MISSION_COL5_9,
+ STREAMED_SOUND_MISSION_COL5_10,
+ STREAMED_SOUND_MISSION_COL5_11,
+ STREAMED_SOUND_MISSION_COL5_12,
+ STREAMED_SOUND_MISSION_COL5_13,
+ STREAMED_SOUND_MISSION_COL5_14,
+ STREAMED_SOUND_MISSION_COL5_15,
+ STREAMED_SOUND_MISSION_COL5_16,
+ STREAMED_SOUND_MISSION_COL5_17,
+ STREAMED_SOUND_MISSION_COL5_18,
+ STREAMED_SOUND_MISSION_COL5_19,
+ STREAMED_SOUND_MISSION_COL5_20,
+ STREAMED_SOUND_MISSION_COL5_21,
+ STREAMED_SOUND_MISSION_COL5_22,
+ STREAMED_SOUND_MISSION_CUB1_1,
+ STREAMED_SOUND_MISSION_CUB1_2,
+ STREAMED_SOUND_MISSION_CUB1_3,
+ STREAMED_SOUND_MISSION_CUB1_4,
+ STREAMED_SOUND_MISSION_CUB1_5,
+ STREAMED_SOUND_MISSION_CUB1_6,
+ STREAMED_SOUND_MISSION_CUB1_7,
+ STREAMED_SOUND_MISSION_CUB1_8,
+ STREAMED_SOUND_MISSION_CUB1_9,
+ STREAMED_SOUND_MISSION_CUB1_10,
+ STREAMED_SOUND_MISSION_CUB2_1,
+ STREAMED_SOUND_MISSION_CUB2_2,
+ STREAMED_SOUND_MISSION_CUB2_3A,
+ STREAMED_SOUND_MISSION_CUB2_3B,
+ STREAMED_SOUND_MISSION_CUB2_3C,
+ STREAMED_SOUND_MISSION_CUB2_4A,
+ STREAMED_SOUND_MISSION_CUB2_5,
+ STREAMED_SOUND_MISSION_CUB2_6,
+ STREAMED_SOUND_MISSION_CUB2_7,
+ STREAMED_SOUND_MISSION_CUB2_8,
+ STREAMED_SOUND_MISSION_CUB2_9,
+ STREAMED_SOUND_MISSION_CUB2_10,
+ STREAMED_SOUND_MISSION_CUB2_11,
+ STREAMED_SOUND_MISSION_CUB3_1,
+ STREAMED_SOUND_MISSION_CUB3_2,
+ STREAMED_SOUND_MISSION_CUB3_3,
+ STREAMED_SOUND_MISSION_CUB3_4,
+ STREAMED_SOUND_MISSION_CUB4_1,
+ STREAMED_SOUND_MISSION_CUB4_2,
+ STREAMED_SOUND_MISSION_CUB4_3,
+ STREAMED_SOUND_MISSION_CUB4_4,
+ STREAMED_SOUND_MISSION_CUB4_5,
+ STREAMED_SOUND_MISSION_CUB4_5A,
+ STREAMED_SOUND_MISSION_CUB4_6,
+ STREAMED_SOUND_MISSION_CUB4_7,
+ STREAMED_SOUND_MISSION_CUB4_8,
+ STREAMED_SOUND_MISSION_CUB4_9,
+ STREAMED_SOUND_MISSION_CUB4_10,
+ STREAMED_SOUND_MISSION_CUB4_11,
+ STREAMED_SOUND_MISSION_CUB4_12,
+ STREAMED_SOUND_MISSION_CUB4_13,
+ STREAMED_SOUND_MISSION_CUB4_14,
+ STREAMED_SOUND_MISSION_CUB4_15,
+ STREAMED_SOUND_MISSION_CUB4_16,
+ STREAMED_SOUND_MISSION_GOLF_1,
+ STREAMED_SOUND_MISSION_GOLF_2,
+ STREAMED_SOUND_MISSION_GOLF_3,
+ STREAMED_SOUND_MISSION_BAR_1,
+ STREAMED_SOUND_MISSION_BAR_2,
+ STREAMED_SOUND_MISSION_BAR_3,
+ STREAMED_SOUND_MISSION_BAR_4,
+ STREAMED_SOUND_MISSION_BAR_5,
+ STREAMED_SOUND_MISSION_BAR_6,
+ STREAMED_SOUND_MISSION_BAR_7,
+ STREAMED_SOUND_MISSION_BAR_8,
+ STREAMED_SOUND_MISSION_STRIP_1,
+ STREAMED_SOUND_MISSION_STRIP_2,
+ STREAMED_SOUND_MISSION_STRIP_3,
+ STREAMED_SOUND_MISSION_STRIP_4,
+ STREAMED_SOUND_MISSION_STRIP_5,
+ STREAMED_SOUND_MISSION_STRIP_6,
+ STREAMED_SOUND_MISSION_STRIP_7,
+ STREAMED_SOUND_MISSION_STRIP_8,
+ STREAMED_SOUND_MISSION_STRIP_9,
+ STREAMED_SOUND_MISSION_STAR_1,
+ STREAMED_SOUND_MISSION_STAR_2,
+ STREAMED_SOUND_MISSION_STAR_3,
+ STREAMED_SOUND_MISSION_STAR_4,
+ STREAMED_SOUND_MISSION_FIN_1A,
+ STREAMED_SOUND_MISSION_FIN_1B,
+ STREAMED_SOUND_MISSION_FIN_1C,
+ STREAMED_SOUND_MISSION_FIN_2B,
+ STREAMED_SOUND_MISSION_FIN_2C,
+ STREAMED_SOUND_MISSION_FIN_3,
+ STREAMED_SOUND_MISSION_FIN_4,
+ STREAMED_SOUND_MISSION_FIN_5,
+ STREAMED_SOUND_MISSION_FIN_6,
+ STREAMED_SOUND_MISSION_FIN_10,
+ STREAMED_SOUND_MISSION_FIN_11A,
+ STREAMED_SOUND_MISSION_FIN_11B,
+ STREAMED_SOUND_MISSION_FIN_12A,
+ STREAMED_SOUND_MISSION_FIN_12B,
+ STREAMED_SOUND_MISSION_FIN_12C,
+ STREAMED_SOUND_MISSION_FIN_13,
+ STREAMED_SOUND_MISSION_FINKILL,
+ STREAMED_SOUND_MISSION_LAW1_1,
+ STREAMED_SOUND_MISSION_LAW1_2,
+ STREAMED_SOUND_MISSION_LAW1_3,
+ STREAMED_SOUND_MISSION_LAW1_4,
+ STREAMED_SOUND_MISSION_LAW1_5,
+ STREAMED_SOUND_MISSION_LAW1_6,
+ STREAMED_SOUND_MISSION_LAW1_7,
+ STREAMED_SOUND_MISSION_LAW1_8,
+ STREAMED_SOUND_MISSION_LAW1_9,
+ STREAMED_SOUND_MISSION_LAW1_10,
+ STREAMED_SOUND_MISSION_LAW2_1,
+ STREAMED_SOUND_MISSION_LAW2_2,
+ STREAMED_SOUND_MISSION_LAW2_3,
+ STREAMED_SOUND_MISSION_LAW2_4,
+ STREAMED_SOUND_MISSION_LAW2_5,
+ STREAMED_SOUND_MISSION_LAW2_6,
+ STREAMED_SOUND_MISSION_LAW2_7,
+ STREAMED_SOUND_MISSION_LAW2_8,
+ STREAMED_SOUND_MISSION_LAW2_9,
+ STREAMED_SOUND_MISSION_LAW2_10,
+ STREAMED_SOUND_MISSION_LAW3_1,
+ STREAMED_SOUND_MISSION_LAW3_2,
+ STREAMED_SOUND_MISSION_LAW3_3,
+ STREAMED_SOUND_MISSION_LAW3_4,
+ STREAMED_SOUND_MISSION_LAW3_5,
+ STREAMED_SOUND_MISSION_LAW3_6,
+ STREAMED_SOUND_MISSION_LAW3_10,
+ STREAMED_SOUND_MISSION_LAW3_11,
+ STREAMED_SOUND_MISSION_LAW3_12,
+ STREAMED_SOUND_MISSION_LAW3_13,
+ STREAMED_SOUND_MISSION_LAW3_14,
+ STREAMED_SOUND_MISSION_LAW3_16,
+ STREAMED_SOUND_MISSION_LAW3_17,
+ STREAMED_SOUND_MISSION_LAW3_18,
+ STREAMED_SOUND_MISSION_LAW3_19,
+ STREAMED_SOUND_MISSION_LAW3_20,
+ STREAMED_SOUND_MISSION_LAW3_21,
+ STREAMED_SOUND_MISSION_LAW3_22,
+ STREAMED_SOUND_MISSION_LAW3_23,
+ STREAMED_SOUND_MISSION_LAW3_24,
+ STREAMED_SOUND_MISSION_LAW3_25,
+ STREAMED_SOUND_MISSION_LAW4_1A,
+ STREAMED_SOUND_MISSION_LAW4_1B,
+ STREAMED_SOUND_MISSION_LAW4_1C,
+ STREAMED_SOUND_MISSION_LAW4_1D,
+ STREAMED_SOUND_MISSION_LAW4_10,
+ STREAMED_SOUND_MISSION_LAW4_3,
+ STREAMED_SOUND_MISSION_LAW4_4,
+ STREAMED_SOUND_MISSION_LAW4_5,
+ STREAMED_SOUND_MISSION_LAW4_6,
+ STREAMED_SOUND_MISSION_LAW4_7,
+ STREAMED_SOUND_MISSION_LAW4_8,
+ STREAMED_SOUND_MISSION_LAW4_9,
+ STREAMED_SOUND_MISSION_PHIL1_2,
+ STREAMED_SOUND_MISSION_PHIL1_3,
+ STREAMED_SOUND_MISSION_PHIL2_1,
+ STREAMED_SOUND_MISSION_PHIL2_2,
+ STREAMED_SOUND_MISSION_PHIL2_3,
+ STREAMED_SOUND_MISSION_PHIL2_4,
+ STREAMED_SOUND_MISSION_PHIL2_5,
+ STREAMED_SOUND_MISSION_PHIL2_6,
+ STREAMED_SOUND_MISSION_PHIL2_7,
+ STREAMED_SOUND_MISSION_PHIL2_8,
+ STREAMED_SOUND_MISSION_PHIL2_9,
+ STREAMED_SOUND_MISSION_PHIL210,
+ STREAMED_SOUND_MISSION_PHIL211,
+ STREAMED_SOUND_MISSION_PORN1_1,
+ STREAMED_SOUND_MISSION_PORN1_2,
+ STREAMED_SOUND_MISSION_PORN1_3,
+ STREAMED_SOUND_MISSION_PRN1_3A,
+ STREAMED_SOUND_MISSION_PORN1_4,
+ STREAMED_SOUND_MISSION_PORN1_5,
+ STREAMED_SOUND_MISSION_PORN1_6,
+ STREAMED_SOUND_MISSION_PORN1_7,
+ STREAMED_SOUND_MISSION_PORN1_8,
+ STREAMED_SOUND_MISSION_PORN1_9,
+ STREAMED_SOUND_MISSION_PRN1_10,
+ STREAMED_SOUND_MISSION_PRN1_11,
+ STREAMED_SOUND_MISSION_PRN1_12,
+ STREAMED_SOUND_MISSION_PRN1_13,
+ STREAMED_SOUND_MISSION_PRN1_14,
+ STREAMED_SOUND_MISSION_PRN1_15,
+ STREAMED_SOUND_MISSION_PRN1_16,
+ STREAMED_SOUND_MISSION_PRN1_17,
+ STREAMED_SOUND_MISSION_PRN1_18,
+ STREAMED_SOUND_MISSION_PRN1_19,
+ STREAMED_SOUND_MISSION_PRN1_20,
+ STREAMED_SOUND_MISSION_PRN1_21,
+ STREAMED_SOUND_MISSION_PORN3_1,
+ STREAMED_SOUND_MISSION_PORN3_2,
+ STREAMED_SOUND_MISSION_PORN3_3,
+ STREAMED_SOUND_MISSION_PORN3_4,
+ STREAMED_SOUND_MISSION_PSYCH_1,
+ STREAMED_SOUND_MISSION_PSYCH_2,
+ STREAMED_SOUND_MISSION_ROK2_01,
+ STREAMED_SOUND_MISSION_ROK3_1,
+ STREAMED_SOUND_MISSION_ROK3_2,
+ STREAMED_SOUND_MISSION_ROK3_3,
+ STREAMED_SOUND_MISSION_ROK3_4,
+ STREAMED_SOUND_MISSION_ROK3_5,
+ STREAMED_SOUND_MISSION_ROK3_6,
+ STREAMED_SOUND_MISSION_ROK3_7,
+ STREAMED_SOUND_MISSION_ROK3_8,
+ STREAMED_SOUND_MISSION_ROK3_9,
+ STREAMED_SOUND_MISSION_ROK3_10,
+ STREAMED_SOUND_MISSION_ROK3_11,
+ STREAMED_SOUND_MISSION_ROK3_12,
+ STREAMED_SOUND_MISSION_ROK3_13,
+ STREAMED_SOUND_MISSION_ROK3_14,
+ STREAMED_SOUND_MISSION_ROK3_15,
+ STREAMED_SOUND_MISSION_ROK3_16,
+ STREAMED_SOUND_MISSION_ROK3_17,
+ STREAMED_SOUND_MISSION_ROK3_18,
+ STREAMED_SOUND_MISSION_ROK3_19,
+ STREAMED_SOUND_MISSION_ROK3_20,
+ STREAMED_SOUND_MISSION_ROK3_21,
+ STREAMED_SOUND_MISSION_ROK3_22,
+ STREAMED_SOUND_MISSION_ROK3_23,
+ STREAMED_SOUND_MISSION_ROK3_24,
+ STREAMED_SOUND_MISSION_ROK3_25,
+ STREAMED_SOUND_MISSION_ROK3_26,
+ STREAMED_SOUND_MISSION_ROK3_27,
+ STREAMED_SOUND_MISSION_ROK3_62,
+ STREAMED_SOUND_MISSION_ROK3_63,
+ STREAMED_SOUND_MISSION_ROK3_64,
+ STREAMED_SOUND_MISSION_ROK3_65,
+ STREAMED_SOUND_MISSION_ROK3_66,
+ STREAMED_SOUND_MISSION_ROK3_67,
+ STREAMED_SOUND_MISSION_ROK3_68,
+ STREAMED_SOUND_MISSION_ROK3_69,
+ STREAMED_SOUND_MISSION_ROK3_70,
+ STREAMED_SOUND_MISSION_ROK3_71,
+ STREAMED_SOUND_MISSION_ROK3_73,
+ STREAMED_SOUND_MISSION_RESC_1,
+ STREAMED_SOUND_MISSION_RESC_2,
+ STREAMED_SOUND_MISSION_RESC_3,
+ STREAMED_SOUND_MISSION_RESC_4,
+ STREAMED_SOUND_MISSION_RESC_5,
+ STREAMED_SOUND_MISSION_RESC_6,
+ STREAMED_SOUND_MISSION_RESC_7,
+ STREAMED_SOUND_MISSION_RESC_8,
+ STREAMED_SOUND_MISSION_RESC_9,
+ STREAMED_SOUND_MISSION_RESC_10,
+ STREAMED_SOUND_MISSION_ROK1_1A,
+ STREAMED_SOUND_MISSION_ROK1_1B,
+ STREAMED_SOUND_MISSION_ROK1_5,
+ STREAMED_SOUND_MISSION_ROK1_6,
+ STREAMED_SOUND_MISSION_ROK1_7,
+ STREAMED_SOUND_MISSION_ROK1_8,
+ STREAMED_SOUND_MISSION_ROK1_9,
+ STREAMED_SOUND_MISSION_TAX1_1,
+ STREAMED_SOUND_MISSION_TAX1_2,
+ STREAMED_SOUND_MISSION_TAX1_3,
+ STREAMED_SOUND_MISSION_TAX1_4,
+ STREAMED_SOUND_MISSION_TAX1_5,
+ STREAMED_SOUND_MISSION_TAX2_1,
+ STREAMED_SOUND_MISSION_TAX2_2,
+ STREAMED_SOUND_MISSION_TAX2_3,
+ STREAMED_SOUND_MISSION_TAX2_4,
+ STREAMED_SOUND_MISSION_TAX2_5,
+ STREAMED_SOUND_MISSION_TAX2_6,
+ STREAMED_SOUND_MISSION_TAX2_7,
+ STREAMED_SOUND_MISSION_TAX3_1,
+ STREAMED_SOUND_MISSION_TAX3_2,
+ STREAMED_SOUND_MISSION_TAX3_3,
+ STREAMED_SOUND_MISSION_TAX3_4,
+ STREAMED_SOUND_MISSION_TAX3_5,
+ STREAMED_SOUND_MISSION_TEX1_1,
+ STREAMED_SOUND_MISSION_TEX1_2,
+ STREAMED_SOUND_MISSION_TEX1_3,
+ STREAMED_SOUND_MISSION_TEX1_4,
+ STREAMED_SOUND_MISSION_TEX1_5,
+ STREAMED_SOUND_MISSION_TEX1_6,
+ STREAMED_SOUND_MISSION_TEX2_1,
+ STREAMED_SOUND_MISSION_TEX3_1,
+ STREAMED_SOUND_MISSION_TEX3_2,
+ STREAMED_SOUND_MISSION_TEX3_3,
+ STREAMED_SOUND_MISSION_TEX3_4,
+ STREAMED_SOUND_MISSION_TEX3_5,
+ STREAMED_SOUND_MISSION_TEX3_6,
+ STREAMED_SOUND_MISSION_TEX3_7,
+ STREAMED_SOUND_MISSION_TEX3_8,
+ STREAMED_SOUND_MISSION_HAT_1A,
+ STREAMED_SOUND_MISSION_INTRO1,
+ STREAMED_SOUND_MISSION_INTRO2,
+ STREAMED_SOUND_MISSION_INTRO3,
+ STREAMED_SOUND_MISSION_INTRO4,
+ STREAMED_SOUND_MISSION_MOB_01A,
+ STREAMED_SOUND_MISSION_MOB_01B,
+ STREAMED_SOUND_MISSION_MOB_01C,
+ STREAMED_SOUND_MISSION_MOB_02A,
+ STREAMED_SOUND_MISSION_MOB_02B,
+ STREAMED_SOUND_MISSION_MOB_02C,
+ STREAMED_SOUND_MISSION_MOB_03A,
+ STREAMED_SOUND_MISSION_MOB_03B,
+ STREAMED_SOUND_MISSION_MOB_03C,
+ STREAMED_SOUND_MISSION_MOB_03D,
+ STREAMED_SOUND_MISSION_MOB_03E,
+ STREAMED_SOUND_MISSION_SHARK_1,
+ STREAMED_SOUND_MISSION_SHARK_2,
+ STREAMED_SOUND_MISSION_SHARK_3,
+ STREAMED_SOUND_MISSION_SHARK_4,
+ STREAMED_SOUND_MISSION_SHARK_5,
+ STREAMED_SOUND_MISSION_MOB_04A,
+ STREAMED_SOUND_MISSION_MOB_04B,
+ STREAMED_SOUND_MISSION_MOB_04C,
+ STREAMED_SOUND_MISSION_MOB_04D,
+ STREAMED_SOUND_MISSION_MOB_05A,
+ STREAMED_SOUND_MISSION_MOB_05B,
+ STREAMED_SOUND_MISSION_MOB_05C,
+ STREAMED_SOUND_MISSION_MOB_05D,
+ STREAMED_SOUND_MISSION_MOB_06A,
+ STREAMED_SOUND_MISSION_MOB_06B,
+ STREAMED_SOUND_MISSION_MOB_06C,
+ STREAMED_SOUND_MISSION_MOB_07A,
+ STREAMED_SOUND_MISSION_MOB_07B,
+ STREAMED_SOUND_MISSION_MOB_08A,
+ STREAMED_SOUND_MISSION_MOB_08B,
+ STREAMED_SOUND_MISSION_MOB_08C,
+ STREAMED_SOUND_MISSION_MOB_08D,
+ STREAMED_SOUND_MISSION_MOB_08E,
+ STREAMED_SOUND_MISSION_MOB_08F,
+ STREAMED_SOUND_MISSION_MOB_08G,
+ STREAMED_SOUND_MISSION_MOB_09A,
+ STREAMED_SOUND_MISSION_MOB_09B,
+ STREAMED_SOUND_MISSION_MOB_09C,
+ STREAMED_SOUND_MISSION_MOB_09D,
+ STREAMED_SOUND_MISSION_MOB_09E,
+ STREAMED_SOUND_MISSION_MOB_09F,
+ STREAMED_SOUND_MISSION_MOB_10A,
+ STREAMED_SOUND_MISSION_MOB_10B,
+ STREAMED_SOUND_MISSION_MOB_10C,
+ STREAMED_SOUND_MISSION_MOB_10D,
+ STREAMED_SOUND_MISSION_MOB_10E,
+ STREAMED_SOUND_MISSION_MOB_11A,
+ STREAMED_SOUND_MISSION_MOB_11B,
+ STREAMED_SOUND_MISSION_MOB_11C,
+ STREAMED_SOUND_MISSION_MOB_11D,
+ STREAMED_SOUND_MISSION_MOB_11E,
+ STREAMED_SOUND_MISSION_MOB_11F,
+ STREAMED_SOUND_MISSION_MOB_14A,
+ STREAMED_SOUND_MISSION_MOB_14B,
+ STREAMED_SOUND_MISSION_MOB_14C,
+ STREAMED_SOUND_MISSION_MOB_14D,
+ STREAMED_SOUND_MISSION_MOB_14E,
+ STREAMED_SOUND_MISSION_MOB_14F,
+ STREAMED_SOUND_MISSION_MOB_14G,
+ STREAMED_SOUND_MISSION_MOB_14H,
+ STREAMED_SOUND_MISSION_MOB_16A,
+ STREAMED_SOUND_MISSION_MOB_16B,
+ STREAMED_SOUND_MISSION_MOB_16C,
+ STREAMED_SOUND_MISSION_MOB_16D,
+ STREAMED_SOUND_MISSION_MOB_16E,
+ STREAMED_SOUND_MISSION_MOB_16F,
+ STREAMED_SOUND_MISSION_MOB_16G,
+ STREAMED_SOUND_MISSION_MOB_17A,
+ STREAMED_SOUND_MISSION_MOB_17B,
+ STREAMED_SOUND_MISSION_MOB_17C,
+ STREAMED_SOUND_MISSION_MOB_17D,
+ STREAMED_SOUND_MISSION_MOB_17E,
+ STREAMED_SOUND_MISSION_MOB_17G,
+ STREAMED_SOUND_MISSION_MOB_17H,
+ STREAMED_SOUND_MISSION_MOB_17I,
+ STREAMED_SOUND_MISSION_MOB_17J,
+ STREAMED_SOUND_MISSION_MOB_17K,
+ STREAMED_SOUND_MISSION_MOB_17L,
+ STREAMED_SOUND_MISSION_MOB_18A,
+ STREAMED_SOUND_MISSION_MOB_18B,
+ STREAMED_SOUND_MISSION_MOB_18C,
+ STREAMED_SOUND_MISSION_MOB_18D,
+ STREAMED_SOUND_MISSION_MOB_18E,
+ STREAMED_SOUND_MISSION_MOB_18F,
+ STREAMED_SOUND_MISSION_MOB_18G,
+ STREAMED_SOUND_MISSION_MOB_20A,
+ STREAMED_SOUND_MISSION_MOB_20B,
+ STREAMED_SOUND_MISSION_MOB_20C,
+ STREAMED_SOUND_MISSION_MOB_20D,
+ STREAMED_SOUND_MISSION_MOB_20E,
+ STREAMED_SOUND_MISSION_MOB_24A,
+ STREAMED_SOUND_MISSION_MOB_24B,
+ STREAMED_SOUND_MISSION_MOB_24C,
+ STREAMED_SOUND_MISSION_MOB_24D,
+ STREAMED_SOUND_MISSION_MOB_24E,
+ STREAMED_SOUND_MISSION_MOB_24F,
+ STREAMED_SOUND_MISSION_MOB_24G,
+ STREAMED_SOUND_MISSION_MOB_24H,
+ STREAMED_SOUND_MISSION_MOB_25A,
+ STREAMED_SOUND_MISSION_MOB_25B,
+ STREAMED_SOUND_MISSION_MOB_25C,
+ STREAMED_SOUND_MISSION_MOB_25D,
+ STREAMED_SOUND_MISSION_MOB_26A,
+ STREAMED_SOUND_MISSION_MOB_26B,
+ STREAMED_SOUND_MISSION_MOB_26C,
+ STREAMED_SOUND_MISSION_MOB_26D,
+ STREAMED_SOUND_MISSION_MOB_26E,
+ STREAMED_SOUND_MISSION_MOB_29A,
+ STREAMED_SOUND_MISSION_MOB_29B,
+ STREAMED_SOUND_MISSION_MOB_29C,
+ STREAMED_SOUND_MISSION_MOB_29D,
+ STREAMED_SOUND_MISSION_MOB_29E,
+ STREAMED_SOUND_MISSION_MOB_29F,
+ STREAMED_SOUND_MISSION_MOB_29G,
+ STREAMED_SOUND_MISSION_MOB_30A,
+ STREAMED_SOUND_MISSION_MOB_30B,
+ STREAMED_SOUND_MISSION_MOB_30C,
+ STREAMED_SOUND_MISSION_MOB_30D,
+ STREAMED_SOUND_MISSION_MOB_30E,
+ STREAMED_SOUND_MISSION_MOB_30F,
+ STREAMED_SOUND_MISSION_MOB_33A,
+ STREAMED_SOUND_MISSION_MOB_33B,
+ STREAMED_SOUND_MISSION_MOB_33C,
+ STREAMED_SOUND_MISSION_MOB_33D,
+ STREAMED_SOUND_MISSION_MOB_34A,
+ STREAMED_SOUND_MISSION_MOB_34B,
+ STREAMED_SOUND_MISSION_MOB_34C,
+ STREAMED_SOUND_MISSION_MOB_34D,
+ STREAMED_SOUND_MISSION_MOB_35A,
+ STREAMED_SOUND_MISSION_MOB_35B,
+ STREAMED_SOUND_MISSION_MOB_35C,
+ STREAMED_SOUND_MISSION_MOB_35D,
+ STREAMED_SOUND_MISSION_MOB_36A,
+ STREAMED_SOUND_MISSION_MOB_36B,
+ STREAMED_SOUND_MISSION_MOB_36C,
+ STREAMED_SOUND_MISSION_MOB_40A,
+ STREAMED_SOUND_MISSION_MOB_40B,
+ STREAMED_SOUND_MISSION_MOB_40C,
+ STREAMED_SOUND_MISSION_MOB_40D,
+ STREAMED_SOUND_MISSION_MOB_40E,
+ STREAMED_SOUND_MISSION_MOB_40F,
+ STREAMED_SOUND_MISSION_MOB_40G,
+ STREAMED_SOUND_MISSION_MOB_40H,
+ STREAMED_SOUND_MISSION_MOB_40I,
+ STREAMED_SOUND_MISSION_MOB_41A,
+ STREAMED_SOUND_MISSION_MOB_41B,
+ STREAMED_SOUND_MISSION_MOB_41C,
+ STREAMED_SOUND_MISSION_MOB_41D,
+ STREAMED_SOUND_MISSION_MOB_41E,
+ STREAMED_SOUND_MISSION_MOB_41F,
+ STREAMED_SOUND_MISSION_MOB_41G,
+ STREAMED_SOUND_MISSION_MOB_41H,
+ STREAMED_SOUND_MISSION_MOB_42A,
+ STREAMED_SOUND_MISSION_MOB_42B,
+ STREAMED_SOUND_MISSION_MOB_42C,
+ STREAMED_SOUND_MISSION_MOB_42D,
+ STREAMED_SOUND_MISSION_MOB_42E,
+ STREAMED_SOUND_MISSION_MOB_43A,
+ STREAMED_SOUND_MISSION_MOB_43B,
+ STREAMED_SOUND_MISSION_MOB_43C,
+ STREAMED_SOUND_MISSION_MOB_43D,
+ STREAMED_SOUND_MISSION_MOB_43E,
+ STREAMED_SOUND_MISSION_MOB_43F,
+ STREAMED_SOUND_MISSION_MOB_43G,
+ STREAMED_SOUND_MISSION_MOB_43H,
+ STREAMED_SOUND_MISSION_MOB_45A,
+ STREAMED_SOUND_MISSION_MOB_45B,
+ STREAMED_SOUND_MISSION_MOB_45C,
+ STREAMED_SOUND_MISSION_MOB_45D,
+ STREAMED_SOUND_MISSION_MOB_45E,
+ STREAMED_SOUND_MISSION_MOB_45F,
+ STREAMED_SOUND_MISSION_MOB_45G,
+ STREAMED_SOUND_MISSION_MOB_45H,
+ STREAMED_SOUND_MISSION_MOB_45I,
+ STREAMED_SOUND_MISSION_MOB_45J,
+ STREAMED_SOUND_MISSION_MOB_45K,
+ STREAMED_SOUND_MISSION_MOB_45L,
+ STREAMED_SOUND_MISSION_MOB_45M,
+ STREAMED_SOUND_MISSION_MOB_45N,
+ STREAMED_SOUND_MISSION_MOB_46A,
+ STREAMED_SOUND_MISSION_MOB_46B,
+ STREAMED_SOUND_MISSION_MOB_46C,
+ STREAMED_SOUND_MISSION_MOB_46D,
+ STREAMED_SOUND_MISSION_MOB_46E,
+ STREAMED_SOUND_MISSION_MOB_46F,
+ STREAMED_SOUND_MISSION_MOB_46G,
+ STREAMED_SOUND_MISSION_MOB_46H,
+ STREAMED_SOUND_MISSION_MOB_47A,
+ STREAMED_SOUND_MISSION_MOB_52A,
+ STREAMED_SOUND_MISSION_MOB_52B,
+ STREAMED_SOUND_MISSION_MOB_52C,
+ STREAMED_SOUND_MISSION_MOB_52D,
+ STREAMED_SOUND_MISSION_MOB_52E,
+ STREAMED_SOUND_MISSION_MOB_52F,
+ STREAMED_SOUND_MISSION_MOB_52G,
+ STREAMED_SOUND_MISSION_MOB_52H,
+ STREAMED_SOUND_MISSION_MOB_54A,
+ STREAMED_SOUND_MISSION_MOB_54B,
+ STREAMED_SOUND_MISSION_MOB_54C,
+ STREAMED_SOUND_MISSION_MOB_54D,
+ STREAMED_SOUND_MISSION_MOB_54E,
+ STREAMED_SOUND_MISSION_MOB_55A,
+ STREAMED_SOUND_MISSION_MOB_55B,
+ STREAMED_SOUND_MISSION_MOB_55C,
+ STREAMED_SOUND_MISSION_MOB_55D,
+ STREAMED_SOUND_MISSION_MOB_55E,
+ STREAMED_SOUND_MISSION_MOB_55F,
+ STREAMED_SOUND_MISSION_MOB_56A,
+ STREAMED_SOUND_MISSION_MOB_56B,
+ STREAMED_SOUND_MISSION_MOB_56C,
+ STREAMED_SOUND_MISSION_MOB_56D,
+ STREAMED_SOUND_MISSION_MOB_56E,
+ STREAMED_SOUND_MISSION_MOB_56F,
+ STREAMED_SOUND_MISSION_MOB_57A,
+ STREAMED_SOUND_MISSION_MOB_57B,
+ STREAMED_SOUND_MISSION_MOB_57C,
+ STREAMED_SOUND_MISSION_MOB_57D,
+ STREAMED_SOUND_MISSION_MOB_57E,
+ STREAMED_SOUND_MISSION_MOB_58A,
+ STREAMED_SOUND_MISSION_MOB_58B,
+ STREAMED_SOUND_MISSION_MOB_58C,
+ STREAMED_SOUND_MISSION_MOB_58D,
+ STREAMED_SOUND_MISSION_MOB_58E,
+ STREAMED_SOUND_MISSION_MOB_58F,
+ STREAMED_SOUND_MISSION_MOB_58G,
+ STREAMED_SOUND_MISSION_MOB_61A,
+ STREAMED_SOUND_MISSION_MOB_61B,
+ STREAMED_SOUND_MISSION_MOB_62A,
+ STREAMED_SOUND_MISSION_MOB_62B,
+ STREAMED_SOUND_MISSION_MOB_62C,
+ STREAMED_SOUND_MISSION_MOB_62D,
+ STREAMED_SOUND_MISSION_MOB_63A,
+ STREAMED_SOUND_MISSION_MOB_63B,
+ STREAMED_SOUND_MISSION_MOB_63C,
+ STREAMED_SOUND_MISSION_MOB_63D,
+ STREAMED_SOUND_MISSION_MOB_63E,
+ STREAMED_SOUND_MISSION_MOB_63F,
+ STREAMED_SOUND_MISSION_MOB_63G,
+ STREAMED_SOUND_MISSION_MOB_63H,
+ STREAMED_SOUND_MISSION_MOB_63I,
+ STREAMED_SOUND_MISSION_MOB_63J,
+ STREAMED_SOUND_MISSION_MOB_66A,
+ STREAMED_SOUND_MISSION_MOB_66B,
+ STREAMED_SOUND_MISSION_MOB_68A,
+ STREAMED_SOUND_MISSION_MOB_68B,
+ STREAMED_SOUND_MISSION_MOB_68C,
+ STREAMED_SOUND_MISSION_MOB_68D,
+ STREAMED_SOUND_MISSION_MOB_70A,
+ STREAMED_SOUND_MISSION_MOB_70B,
+ STREAMED_SOUND_MISSION_MOB_71A,
+ STREAMED_SOUND_MISSION_MOB_71B,
+ STREAMED_SOUND_MISSION_MOB_71C,
+ STREAMED_SOUND_MISSION_MOB_71D,
+ STREAMED_SOUND_MISSION_MOB_71E,
+ STREAMED_SOUND_MISSION_MOB_71F,
+ STREAMED_SOUND_MISSION_MOB_71G,
+ STREAMED_SOUND_MISSION_MOB_71H,
+ STREAMED_SOUND_MISSION_MOB_71I,
+ STREAMED_SOUND_MISSION_MOB_71J,
+ STREAMED_SOUND_MISSION_MOB_71K,
+ STREAMED_SOUND_MISSION_MOB_71L,
+ STREAMED_SOUND_MISSION_MOB_71M,
+ STREAMED_SOUND_MISSION_MOB_71N,
+ STREAMED_SOUND_MISSION_MOB_72A,
+ STREAMED_SOUND_MISSION_MOB_72B,
+ STREAMED_SOUND_MISSION_MOB_72C,
+ STREAMED_SOUND_MISSION_MOB_72D,
+ STREAMED_SOUND_MISSION_MOB_72E,
+ STREAMED_SOUND_MISSION_MOB_72F,
+ STREAMED_SOUND_MISSION_MOB_72G,
+ STREAMED_SOUND_MISSION_MOB_73A,
+ STREAMED_SOUND_MISSION_MOB_73C,
+ STREAMED_SOUND_MISSION_MOB_73D,
+ STREAMED_SOUND_MISSION_MOB_73F,
+ STREAMED_SOUND_MISSION_MOB_73G,
+ STREAMED_SOUND_MISSION_MOB_73I,
+ STREAMED_SOUND_MISSION_MOB_95A,
+ STREAMED_SOUND_MISSION_MOB_96A,
+ STREAMED_SOUND_MISSION_MOB_98A,
+ STREAMED_SOUND_MISSION_MOB_99A,
+ STREAMED_SOUND_MISSION_JOB1_1B,
+ STREAMED_SOUND_MISSION_JOB1_1C,
+ STREAMED_SOUND_MISSION_JOB1_1D,
+ STREAMED_SOUND_MISSION_JOB2_1B,
+ STREAMED_SOUND_MISSION_JOB2_2,
+ STREAMED_SOUND_MISSION_JOB2_3,
+ STREAMED_SOUND_MISSION_JOB2_4,
+ STREAMED_SOUND_MISSION_JOB2_5,
+ STREAMED_SOUND_MISSION_JOB2_6,
+ STREAMED_SOUND_MISSION_JOB2_7,
+ STREAMED_SOUND_MISSION_JOB2_8,
+ STREAMED_SOUND_MISSION_JOB2_9,
+ STREAMED_SOUND_MISSION_JOB3_1,
+ STREAMED_SOUND_MISSION_JOB3_2,
+ STREAMED_SOUND_MISSION_JOB3_3,
+ STREAMED_SOUND_MISSION_JOB4_1,
+ STREAMED_SOUND_MISSION_JOB4_2,
+ STREAMED_SOUND_MISSION_JOB4_3,
+ STREAMED_SOUND_MISSION_JOB5_1,
+ STREAMED_SOUND_MISSION_JOB5_2,
+ STREAMED_SOUND_MISSION_JOB5_3,
+ STREAMED_SOUND_MISSION_BJM1_20,
+ STREAMED_SOUND_MISSION_BJM1_4,
+ STREAMED_SOUND_MISSION_BJM1_5,
+ STREAMED_SOUND_MISSION_MERC_39,
+ STREAMED_SOUND_MISSION_MONO_1,
+ STREAMED_SOUND_MISSION_MONO_2,
+ STREAMED_SOUND_MISSION_MONO_3,
+ STREAMED_SOUND_MISSION_MONO_4,
+ STREAMED_SOUND_MISSION_MONO_5,
+ STREAMED_SOUND_MISSION_MONO_6,
+ STREAMED_SOUND_MISSION_MONO_7,
+ STREAMED_SOUND_MISSION_MONO_8,
+ STREAMED_SOUND_MISSION_MONO_9,
+ STREAMED_SOUND_MISSION_MONO10,
+ STREAMED_SOUND_MISSION_MONO11,
+ STREAMED_SOUND_MISSION_MONO12,
+ STREAMED_SOUND_MISSION_MONO13,
+ STREAMED_SOUND_MISSION_MONO14,
+ STREAMED_SOUND_MISSION_MONO15,
+ STREAMED_SOUND_MISSION_MONO16,
+ STREAMED_SOUND_MISSION_FUD_01,
+ STREAMED_SOUND_MISSION_FUD_02,
+ STREAMED_SOUND_MISSION_FUD_03,
+ STREAMED_SOUND_MISSION_FUD_04,
+ STREAMED_SOUND_MISSION_FUD_05,
+ STREAMED_SOUND_MISSION_FUD_06,
+ STREAMED_SOUND_MISSION_FUD_07,
+ STREAMED_SOUND_MISSION_FUD_08,
+ STREAMED_SOUND_MISSION_FUD_09,
+ STREAMED_SOUND_MISSION_FUD_10,
+ STREAMED_SOUND_MISSION_FUD_11,
+ STREAMED_SOUND_MISSION_FUD_12,
+ STREAMED_SOUND_MISSION_FUD_13,
+ STREAMED_SOUND_MISSION_FUD_14,
+ STREAMED_SOUND_MISSION_FUD_15,
+ STREAMED_SOUND_MISSION_FUD_16,
+ STREAMED_SOUND_MISSION_FUD_17,
+ STREAMED_SOUND_MISSION_FUD_18,
+ STREAMED_SOUND_MISSION_FUD_19,
+ STREAMED_SOUND_MISSION_FUD_20,
+ STREAMED_SOUND_MISSION_BURG_01,
+ STREAMED_SOUND_MISSION_BURG_02,
+ STREAMED_SOUND_MISSION_BURG_03,
+ STREAMED_SOUND_MISSION_BURG_04,
+ STREAMED_SOUND_MISSION_BURG_05,
+ STREAMED_SOUND_MISSION_BURG_06,
+ STREAMED_SOUND_MISSION_BURG_07,
+ STREAMED_SOUND_MISSION_BURG_08,
+ STREAMED_SOUND_MISSION_BURG_09,
+ STREAMED_SOUND_MISSION_BURG_10,
+ STREAMED_SOUND_MISSION_BURG_11,
+ STREAMED_SOUND_MISSION_BURG_12,
+ STREAMED_SOUND_MISSION_CRUST01,
+ STREAMED_SOUND_MISSION_CRUST02,
+ STREAMED_SOUND_MISSION_CRUST03,
+ STREAMED_SOUND_MISSION_CRUST04,
+ STREAMED_SOUND_MISSION_CRUST05,
+ STREAMED_SOUND_MISSION_CRUST06,
+ STREAMED_SOUND_MISSION_CRUST07,
+ STREAMED_SOUND_MISSION_CRUST08,
+ STREAMED_SOUND_MISSION_CRUST09,
+ STREAMED_SOUND_MISSION_BAND_01,
+ STREAMED_SOUND_MISSION_BAND_02,
+ STREAMED_SOUND_MISSION_BAND_03,
+ STREAMED_SOUND_MISSION_BAND_04,
+ STREAMED_SOUND_MISSION_BAND_05,
+ STREAMED_SOUND_MISSION_BAND_06,
+ STREAMED_SOUND_MISSION_BAND_07,
+ STREAMED_SOUND_MISSION_BAND_08,
+ STREAMED_SOUND_MISSION_SHAFT01,
+ STREAMED_SOUND_MISSION_SHAFT02,
+ STREAMED_SOUND_MISSION_SHAFT03,
+ STREAMED_SOUND_MISSION_SHAFT04,
+ STREAMED_SOUND_MISSION_SHAFT05,
+ STREAMED_SOUND_MISSION_SHAFT06,
+ STREAMED_SOUND_MISSION_SHAFT07,
+ STREAMED_SOUND_MISSION_SHAFT08,
+ STREAMED_SOUND_MISSION_PISS_01,
+ STREAMED_SOUND_MISSION_PISS_02,
+ STREAMED_SOUND_MISSION_PISS_03,
+ STREAMED_SOUND_MISSION_PISS_04,
+ STREAMED_SOUND_MISSION_PISS_05,
+ STREAMED_SOUND_MISSION_PISS_06,
+ STREAMED_SOUND_MISSION_PISS_07,
+ STREAMED_SOUND_MISSION_PISS_08,
+ STREAMED_SOUND_MISSION_PISS_09,
+ STREAMED_SOUND_MISSION_PISS_10,
+ STREAMED_SOUND_MISSION_PISS_11,
+ STREAMED_SOUND_MISSION_PISS_12,
+ STREAMED_SOUND_MISSION_PISS_13,
+ STREAMED_SOUND_MISSION_PISS_14,
+ STREAMED_SOUND_MISSION_PISS_15,
+ STREAMED_SOUND_MISSION_PISS_16,
+ STREAMED_SOUND_MISSION_PISS_17,
+ STREAMED_SOUND_MISSION_PISS_18,
+ STREAMED_SOUND_MISSION_PISS_19,
+ STREAMED_SOUND_MISSION_GIMME01,
+ STREAMED_SOUND_MISSION_GIMME02,
+ STREAMED_SOUND_MISSION_GIMME03,
+ STREAMED_SOUND_MISSION_GIMME04,
+ STREAMED_SOUND_MISSION_GIMME05,
+ STREAMED_SOUND_MISSION_GIMME06,
+ STREAMED_SOUND_MISSION_GIMME07,
+ STREAMED_SOUND_MISSION_GIMME08,
+ STREAMED_SOUND_MISSION_GIMME09,
+ STREAMED_SOUND_MISSION_GIMME10,
+ STREAMED_SOUND_MISSION_GIMME11,
+ STREAMED_SOUND_MISSION_GIMME12,
+ STREAMED_SOUND_MISSION_GIMME13,
+ STREAMED_SOUND_MISSION_GIMME14,
+ STREAMED_SOUND_MISSION_GIMME15,
+ STREAMED_SOUND_MISSION_BUST_01,
+ STREAMED_SOUND_MISSION_BUST_02,
+ STREAMED_SOUND_MISSION_BUST_03,
+ STREAMED_SOUND_MISSION_BUST_04,
+ STREAMED_SOUND_MISSION_BUST_05,
+ STREAMED_SOUND_MISSION_BUST_06,
+ STREAMED_SOUND_MISSION_BUST_07,
+ STREAMED_SOUND_MISSION_BUST_08,
+ STREAMED_SOUND_MISSION_BUST_09,
+ STREAMED_SOUND_MISSION_BUST_10,
+ STREAMED_SOUND_MISSION_BUST_11,
+ STREAMED_SOUND_MISSION_BUST_12,
+ STREAMED_SOUND_MISSION_BUST_13,
+ STREAMED_SOUND_MISSION_BUST_14,
+ STREAMED_SOUND_MISSION_BUST_15,
+ STREAMED_SOUND_MISSION_BUST_16,
+ STREAMED_SOUND_MISSION_BUST_17,
+ STREAMED_SOUND_MISSION_BUST_18,
+ STREAMED_SOUND_MISSION_BUST_19,
+ STREAMED_SOUND_MISSION_BUST_20,
+ STREAMED_SOUND_MISSION_BUST_21,
+ STREAMED_SOUND_MISSION_BUST_22,
+ STREAMED_SOUND_MISSION_BUST_23,
+ STREAMED_SOUND_MISSION_BUST_24,
+ STREAMED_SOUND_MISSION_BUST_25,
+ STREAMED_SOUND_MISSION_BUST_26,
+ STREAMED_SOUND_MISSION_BUST_27,
+ STREAMED_SOUND_MISSION_BUST_28,
TOTAL_STREAMED_SOUNDS,
NO_TRACK,
};
@@ -242,15 +1280,18 @@ enum eAudioType
AUDIOTYPE_EXPLOSION,
AUDIOTYPE_FIRE,
AUDIOTYPE_WEATHER,
- AUDIOTYPE_CRANE,
AUDIOTYPE_SCRIPTOBJECT,
+#ifdef GTA_BRIDGE
AUDIOTYPE_BRIDGE,
+#endif
AUDIOTYPE_COLLISION,
AUDIOTYPE_FRONTEND,
AUDIOTYPE_PROJECTILE,
AUDIOTYPE_GARAGE,
AUDIOTYPE_FIREHYDRANT,
AUDIOTYPE_WATERCANNON,
+ AUDIOTYPE_ESCALATOR,
+ AUDIOTYPE_EXTRA_SOUNDS,
AUDIOTYPE_POLICERADIO,
TOTAL_AUDIO_TYPES,
};
@@ -258,9 +1299,10 @@ enum eAudioType
#ifdef GTA_PS2
enum
{
- NUM_CHANNELS_GENERIC = 43,
+ NUM_CHANNELS_GENERIC = 42,
CHANNEL_POLICE_RADIO = NUM_CHANNELS_GENERIC,
- CHANNEL_MISSION_AUDIO,
+ CHANNEL_MISSION_AUDIO_1,
+ CHANNEL_MISSION_AUDIO_2,
CHANNEL_PLAYER_VEHICLE_ENGINE,
NUM_CHANNELS
};
@@ -268,7 +1310,7 @@ enum
enum
{
#ifdef PS2_AUDIO_CHANNELS
- NUM_CHANNELS_GENERIC = 43,
+ NUM_CHANNELS_GENERIC = 42,
#else
NUM_CHANNELS_GENERIC = 27,
#endif
diff --git a/src/audio/oal/stream.cpp b/src/audio/oal/stream.cpp
index 6afe8e30..3789573e 100644
--- a/src/audio/oal/stream.cpp
+++ b/src/audio/oal/stream.cpp
@@ -511,6 +511,13 @@ protected:
uint32 m_nChannels;
const char* m_pPath;
bool m_bFileNotOpenedYet;
+
+ CMP3File() :
+ m_pMH(nil),
+ m_bOpened(false),
+ m_nRate(0),
+ m_bFileNotOpenedYet(false),
+ m_nChannels(0) {}
public:
CMP3File(const char *path) :
m_pMH(nil),
@@ -618,6 +625,69 @@ public:
}
};
+class CADFFile : public CMP3File
+{
+ static ssize_t r_read(void* fh, void* buf, size_t size)
+ {
+ size_t bytesRead = fread(buf, 1, size, (FILE*)fh);
+ uint8* _buf = (uint8*)buf;
+ for (size_t i = 0; i < size; i++)
+ _buf[i] ^= 0x22;
+ return bytesRead;
+ }
+ static off_t r_seek(void* fh, off_t pos, int seekType)
+ {
+ fseek((FILE*)fh, pos, seekType);
+ return ftell((FILE*)fh);
+ }
+ static void r_close(void* fh)
+ {
+ fclose((FILE*)fh);
+ }
+public:
+ CADFFile(const char* path)
+ {
+ m_pMH = mpg123_new(nil, nil);
+ if (m_pMH)
+ {
+ mpg123_param(m_pMH, MPG123_FLAGS, MPG123_SEEKBUFFER | MPG123_GAPLESS, 0.0);
+
+ m_bOpened = true;
+ m_bFileNotOpenedYet = true;
+ m_pPath = path;
+ // It's possible to move this to audioFileOpsThread(), but effect isn't noticable + probably not compatible with our current cutscene audio handling
+#if 1
+ FileOpen();
+#endif
+
+ }
+ }
+
+ void FileOpen()
+ {
+ if(!m_bFileNotOpenedYet) return;
+
+ long rate = 0;
+ int channels = 0;
+ int encoding = 0;
+
+ FILE *f = fopen(m_pPath, "rb");
+
+ m_bOpened = f && mpg123_replace_reader_handle(m_pMH, r_read, r_seek, r_close) == MPG123_OK
+ && mpg123_open_handle(m_pMH, f) == MPG123_OK && mpg123_getformat(m_pMH, &rate, &channels, &encoding) == MPG123_OK;
+
+ m_nRate = rate;
+ m_nChannels = channels;
+
+ if(IsOpened()) {
+ mpg123_format_none(m_pMH);
+ mpg123_format(m_pMH, rate, channels, encoding);
+ }
+
+ m_bFileNotOpenedYet = false;
+ }
+};
+
#endif
#define VAG_LINE_SIZE (0x10)
#define VAG_SAMPLES_IN_LINE (28)
@@ -1208,6 +1278,8 @@ bool CStream::Open(const char* filename, uint32 overrideSampleRate)
#ifdef AUDIO_OAL_USE_MPG123
else if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".mp3")], ".mp3"))
m_pSoundFile = new CMP3File(m_aFilename);
+ else if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".adf")], ".adf"))
+ m_pSoundFile = new CADFFile(m_aFilename);
#endif
else if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".vb")], ".VB"))
m_pSoundFile = new CVbFile(m_aFilename, overrideSampleRate);
@@ -1500,7 +1572,7 @@ int32 CStream::FillBuffers()
void CStream::ClearBuffers()
{
if ( !HasSource() ) return;
-
+
ALint buffersQueued[2];
alGetSourcei(m_pAlSources[0], AL_BUFFERS_QUEUED, &buffersQueued[0]);
alGetSourcei(m_pAlSources[1], AL_BUFFERS_QUEUED, &buffersQueued[1]);
diff --git a/src/audio/sampman.h b/src/audio/sampman.h
index 16e1a1bb..3af2c51f 100644
--- a/src/audio/sampman.h
+++ b/src/audio/sampman.h
@@ -23,78 +23,94 @@ struct tSample {
enum
{
SFX_BANK_0,
+#ifdef GTA_PS2
+ SFX_BANK_GENERIC_EXTRA,
+ SFX_BANK_PED_COMMENTS,
+ SFX_BANK_FRONT_END_MENU,
+#else
+ SFX_BANK_GENERIC_EXTRA = SFX_BANK_0,
+ SFX_BANK_FRONT_END_MENU = SFX_BANK_0,
+
+ SFX_BANK_PED_COMMENTS,
+ MAX_SFX_BANKS,
+ INVALID_SFX_BANK,
+#endif
CAR_SFX_BANKS_OFFSET,
- SFX_BANK_PACARD = CAR_SFX_BANKS_OFFSET,
- SFX_BANK_PATHFINDER,
+ SFX_BANK_PONTIAC = CAR_SFX_BANKS_OFFSET,
SFX_BANK_PORSCHE,
SFX_BANK_SPIDER,
SFX_BANK_MERC,
SFX_BANK_TRUCK,
SFX_BANK_HOTROD,
SFX_BANK_COBRA,
- SFX_BANK_NONE,
+ SFX_BANK_PONTIAC_SLOW,
+ SFX_BANK_CADILLAC,
+ SFX_BANK_PATHFINDER,
+ SFX_BANK_PACARD,
+ SFX_BANK_GOLF_CART,
+ SFX_BANK_CAR_CHAINSAW,
+ SFX_BANK_RC,
+ SFX_BANK_RC_HELI,
+ SFX_BANK_CAR_UNUSED_4,
- PS2BANK(SFX_BANK_FRONT_END_MENU),
+ // bikes
+ SFX_BANK_VTWIN,
+ SFX_BANK_MOPED,
+ SFX_BANK_HONDA250,
+ SFX_BANK_SPORTS_BIKE,
+ SFX_BANK_BIKE_UNUSED_1,
+ SFX_BANK_BIKE_UNUSED_2,
+ SFX_BANK_BIKE_UNUSED_3,
+ SFX_BANK_BIKE_UNUSED_4,
+ SFX_BANK_BIKE_UNUSED_5,
+ SFX_BANK_BIKE_UNUSED_6,
- PS2BANK(SFX_BANK_TRAIN),
+ // heli
+ SFX_BANK_HELI_APACHE,
+ SFX_BANK_HELI_UNUSED_1,
+ SFX_BANK_HELI_UNUSED_2,
+ SFX_BANK_HELI_UNUSED_3,
+ SFX_BANK_HELI_UNUSED_4,
- PS2BANK(SFX_BANK_BUILDING_CLUB_1),
- PS2BANK(SFX_BANK_BUILDING_CLUB_2),
- PS2BANK(SFX_BANK_BUILDING_CLUB_3),
- PS2BANK(SFX_BANK_BUILDING_CLUB_4),
- PS2BANK(SFX_BANK_BUILDING_CLUB_5),
- PS2BANK(SFX_BANK_BUILDING_CLUB_6),
- PS2BANK(SFX_BANK_BUILDING_CLUB_7),
- PS2BANK(SFX_BANK_BUILDING_CLUB_8),
- PS2BANK(SFX_BANK_BUILDING_CLUB_9),
- PS2BANK(SFX_BANK_BUILDING_CLUB_10),
- PS2BANK(SFX_BANK_BUILDING_CLUB_11),
- PS2BANK(SFX_BANK_BUILDING_CLUB_12),
- PS2BANK(SFX_BANK_BUILDING_CLUB_RAGGA),
- PS2BANK(SFX_BANK_BUILDING_STRIP_CLUB_1),
- PS2BANK(SFX_BANK_BUILDING_STRIP_CLUB_2),
- PS2BANK(SFX_BANK_BUILDING_WORKSHOP),
- PS2BANK(SFX_BANK_BUILDING_PIANO_BAR),
- PS2BANK(SFX_BANK_BUILDING_SAWMILL),
- PS2BANK(SFX_BANK_BUILDING_DOG_FOOD_FACTORY),
- PS2BANK(SFX_BANK_BUILDING_LAUNDERETTE),
- PS2BANK(SFX_BANK_BUILDING_RESTAURANT_CHINATOWN),
- PS2BANK(SFX_BANK_BUILDING_RESTAURANT_ITALY),
- PS2BANK(SFX_BANK_BUILDING_RESTAURANT_GENERIC_1),
- PS2BANK(SFX_BANK_BUILDING_RESTAURANT_GENERIC_2),
- PS2BANK(SFX_BANK_BUILDING_AIRPORT),
- PS2BANK(SFX_BANK_BUILDING_SHOP),
- PS2BANK(SFX_BANK_BUILDING_CINEMA),
- PS2BANK(SFX_BANK_BUILDING_DOCKS),
- PS2BANK(SFX_BANK_BUILDING_HOME),
- PS2BANK(SFX_BANK_BUILDING_PORN_1),
- PS2BANK(SFX_BANK_BUILDING_PORN_2),
- PS2BANK(SFX_BANK_BUILDING_PORN_3),
- PS2BANK(SFX_BANK_BUILDING_POLICE_BALL),
+ // plane
+ SFX_BANK_PLANE_SEAPLANE,
+ SFX_BANK_PLANE_UNUSED_1,
+ SFX_BANK_PLANE_UNUSED_2,
+ SFX_BANK_PLANE_UNUSED_3,
+ SFX_BANK_PLANE_UNUSED_4,
PS2BANK(SFX_BANK_BUILDING_BANK_ALARM),
- PS2BANK(SFX_BANK_BUILDING_RAVE_INDUSTRIAL),
- PS2BANK(SFX_BANK_BUILDING_RAVE_COMMERCIAL),
- PS2BANK(SFX_BANK_BUILDING_RAVE_SUBURBAN),
- PS2BANK(SFX_BANK_BUILDING_RAVE_COMMERCIAL_2),
-
- PS2BANK(SFX_BANK_BUILDING_39),
- PS2BANK(SFX_BANK_BUILDING_40),
- PS2BANK(SFX_BANK_BUILDING_41),
- PS2BANK(SFX_BANK_BUILDING_42),
- PS2BANK(SFX_BANK_BUILDING_43),
- PS2BANK(SFX_BANK_BUILDING_44),
- PS2BANK(SFX_BANK_BUILDING_45),
- PS2BANK(SFX_BANK_BUILDING_46),
- PS2BANK(SFX_BANK_BUILDING_47),
-
- PS2BANK(SFX_BANK_GENERIC_EXTRA),
-
- SFX_BANK_PED_COMMENTS,
+ PS2BANK(SFX_BANK_BUILDING_SNORING),
+ PS2BANK(SFX_BANK_BUILDING_BAR_1),
+ PS2BANK(SFX_BANK_BUILDING_BAR_2),
+ PS2BANK(SFX_BANK_BUILDING_BAR_3),
+ PS2BANK(SFX_BANK_BUILDING_BAR_4),
+ PS2BANK(SFX_BANK_BUILDING_MALIBU_1),
+ PS2BANK(SFX_BANK_BUILDING_MALIBU_2),
+ PS2BANK(SFX_BANK_BUILDING_MALIBU_3),
+ PS2BANK(SFX_BANK_BUILDING_STRIP_1),
+ PS2BANK(SFX_BANK_BUILDING_STRIP_2),
+ PS2BANK(SFX_BANK_BUILDING_STRIP_3),
+ PS2BANK(SFX_BANK_BUILDING_CHURCH),
+ PS2BANK(SFX_BANK_BUILDING_FAN_1),
+ PS2BANK(SFX_BANK_BUILDING_FAN_2),
+ PS2BANK(SFX_BANK_BUILDING_INSECT_1),
+ PS2BANK(SFX_BANK_BUILDING_INSECT_2),
+ PS2BANK(SFX_BANK_BUILDING_18),
+ PS2BANK(SFX_BANK_BUILDING_19),
+ PS2BANK(SFX_BANK_BUILDING_20),
+ PS2BANK(SFX_BANK_BUILDING_21),
+ PS2BANK(SFX_BANK_FOOTSTEPS_GRASS),
+ PS2BANK(SFX_BANK_FOOTSTEPS_GRAVEL),
+ PS2BANK(SFX_BANK_FOOTSTEPS_WOOD),
+ PS2BANK(SFX_BANK_FOOTSTEPS_METAL),
+ PS2BANK(SFX_BANK_FOOTSTEPS_WATER),
+ PS2BANK(SFX_BANK_FOOTSTEPS_SAND),
+#ifdef GTA_PS2
MAX_SFX_BANKS,
INVALID_SFX_BANK
+#endif
};
-
#define MAX_PEDSFX 7
#define PED_BLOCKSIZE 79000
@@ -110,7 +126,7 @@ enum
#define MAX2DCHANNELS NUM_CHANNELS
#endif
-#define MAX_STREAMS 2
+#define MAX_STREAMS 3
#define DIGITALRATE 32000
#define DIGITALBITS 16
@@ -120,7 +136,7 @@ enum
#define MAX_DIGITAL_MIXER_CHANNELS (MAXCHANNELS+MAX_STREAMS*2+MAX2DCHANNELS)
#else
#define MAX_DIGITAL_MIXER_CHANNELS (MAXCHANNELS+MAX_STREAMS*2)
-#endif
+#endif
static_assert( NUM_CHANNELS == MAXCHANNELS + MAX2DCHANNELS, "The number of channels doesn't match with an enum" );
@@ -128,15 +144,19 @@ class cSampleManager
{
uint8 m_nEffectsVolume;
uint8 m_nMusicVolume;
+ uint8 m_nMP3BoostVolume;
uint8 m_nEffectsFadeVolume;
uint8 m_nMusicFadeVolume;
bool8 m_nMonoMode;
- char unk;
char m_szCDRomRootPath[80];
bool8 m_bInitialised;
uint8 m_nNumberOfProviders;
char *m_aAudioProviders[MAXPROVIDERS];
tSample m_aSamples[TOTAL_AUDIO_SAMPLES];
+ char m_MiscomPath[260];
+ char m_WavFilesPath[260];
+ char m_MP3FilesPath[188];
+ void *m_aChannels[18];
public:
@@ -157,8 +177,10 @@ public:
int8 GetCurrent3DProviderIndex(void);
int8 SetCurrent3DProvider(uint8 which);
+
+ int8 AutoDetect3DProviders();
#endif
-
+
bool8 IsMP3RadioChannelAvailable(void);
void ReleaseDigitalHandle (void);
@@ -174,6 +196,7 @@ public:
void SetEffectsMasterVolume(uint8 nVolume);
void SetMusicMasterVolume (uint8 nVolume);
+ void SetMP3BoostVolume (uint8 nVolume);
void SetEffectsFadeVolume (uint8 nVolume);
void SetMusicFadeVolume (uint8 nVolume);
void SetMonoMode (bool8 nMode);
@@ -193,7 +216,7 @@ public:
int32 GetSampleLoopEndOffset (uint32 nSample);
uint32 GetSampleLength (uint32 nSample);
- bool8 UpdateReverb(void);
+ bool8 UpdateReverb(void);
void SetChannelReverbFlag (uint32 nChannel, bool8 nReverbFlag);
bool8 InitialiseChannel (uint32 nChannel, uint32 nSfx, uint8 nBank);
@@ -211,463 +234,2481 @@ public:
void StartChannel (uint32 nChannel);
void StopChannel (uint32 nChannel);
- void PreloadStreamedFile (uint8 nFile, uint8 nStream = 0);
+ void PreloadStreamedFile (uint32 nFile, uint8 nStream = 0);
void PauseStream (bool8 nPauseFlag, uint8 nStream = 0);
void StartPreloadedStreamedFile (uint8 nStream = 0);
- bool8 StartStreamedFile (uint8 nFile, uint32 nPos, uint8 nStream = 0);
+ bool8 StartStreamedFile (uint32 nFile, uint32 nPos, uint8 nStream = 0);
void StopStreamedFile (uint8 nStream = 0);
int32 GetStreamedFilePosition (uint8 nStream = 0);
void SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, bool8 nEffectFlag, uint8 nStream = 0);
int32 GetStreamedFileLength (uint8 nStream = 0);
bool8 IsStreamPlaying (uint8 nStream = 0);
+ void SetStreamedFileLoopFlag (bool8 nLoopFlag, uint8 nStream = 0);
#ifdef AUDIO_OAL
void Service(void);
#endif
bool8 InitialiseSampleBanks(void);
+
+ uint8 GetMusicVolume() const { return m_nMusicVolume; }
};
extern cSampleManager SampleManager;
extern uint32 BankStartOffset[MAX_SFX_BANKS];
-#ifdef AUDIO_OAL
-extern int defaultProvider;
-#endif
-
-#if defined(OPUS_AUDIO_PATHS)
-static char StreamedNameTable[][25] = {
- "AUDIO\\HEAD.OPUS", "AUDIO\\CLASS.OPUS", "AUDIO\\KJAH.OPUS", "AUDIO\\RISE.OPUS", "AUDIO\\LIPS.OPUS", "AUDIO\\GAME.OPUS",
- "AUDIO\\MSX.OPUS", "AUDIO\\FLASH.OPUS", "AUDIO\\CHAT.OPUS", "AUDIO\\HEAD.OPUS", "AUDIO\\POLICE.OPUS", "AUDIO\\CITY.OPUS",
- "AUDIO\\WATER.OPUS", "AUDIO\\COMOPEN.OPUS", "AUDIO\\SUBOPEN.OPUS", "AUDIO\\JB.OPUS", "AUDIO\\BET.OPUS", "AUDIO\\L1_LG.OPUS",
- "AUDIO\\L2_DSB.OPUS", "AUDIO\\L3_DM.OPUS", "AUDIO\\L4_PAP.OPUS", "AUDIO\\L5_TFB.OPUS", "AUDIO\\J0_DM2.OPUS", "AUDIO\\J1_LFL.OPUS",
- "AUDIO\\J2_KCL.OPUS", "AUDIO\\J3_VH.OPUS", "AUDIO\\J4_ETH.OPUS", "AUDIO\\J5_DST.OPUS", "AUDIO\\J6_TBJ.OPUS", "AUDIO\\T1_TOL.OPUS",
- "AUDIO\\T2_TPU.OPUS", "AUDIO\\T3_MAS.OPUS", "AUDIO\\T4_TAT.OPUS", "AUDIO\\T5_BF.OPUS", "AUDIO\\S0_MAS.OPUS", "AUDIO\\S1_PF.OPUS",
- "AUDIO\\S2_CTG.OPUS", "AUDIO\\S3_RTC.OPUS", "AUDIO\\S5_LRQ.OPUS", "AUDIO\\S4_BDBA.OPUS", "AUDIO\\S4_BDBB.OPUS", "AUDIO\\S2_CTG2.OPUS",
- "AUDIO\\S4_BDBD.OPUS", "AUDIO\\S5_LRQB.OPUS", "AUDIO\\S5_LRQC.OPUS", "AUDIO\\A1_SSO.OPUS", "AUDIO\\A2_PP.OPUS", "AUDIO\\A3_SS.OPUS",
- "AUDIO\\A4_PDR.OPUS", "AUDIO\\A5_K2FT.OPUS", "AUDIO\\K1_KBO.OPUS", "AUDIO\\K2_GIS.OPUS", "AUDIO\\K3_DS.OPUS", "AUDIO\\K4_SHI.OPUS",
- "AUDIO\\K5_SD.OPUS", "AUDIO\\R0_PDR2.OPUS", "AUDIO\\R1_SW.OPUS", "AUDIO\\R2_AP.OPUS", "AUDIO\\R3_ED.OPUS", "AUDIO\\R4_GF.OPUS",
- "AUDIO\\R5_PB.OPUS", "AUDIO\\R6_MM.OPUS", "AUDIO\\D1_STOG.OPUS", "AUDIO\\D2_KK.OPUS", "AUDIO\\D3_ADO.OPUS", "AUDIO\\D5_ES.OPUS",
- "AUDIO\\D7_MLD.OPUS", "AUDIO\\D4_GTA.OPUS", "AUDIO\\D4_GTA2.OPUS", "AUDIO\\D6_STS.OPUS", "AUDIO\\A6_BAIT.OPUS", "AUDIO\\A7_ETG.OPUS",
- "AUDIO\\A8_PS.OPUS", "AUDIO\\A9_ASD.OPUS", "AUDIO\\K4_SHI2.OPUS", "AUDIO\\C1_TEX.OPUS", "AUDIO\\EL_PH1.OPUS", "AUDIO\\EL_PH2.OPUS",
- "AUDIO\\EL_PH3.OPUS", "AUDIO\\EL_PH4.OPUS", "AUDIO\\YD_PH1.OPUS", "AUDIO\\YD_PH2.OPUS", "AUDIO\\YD_PH3.OPUS", "AUDIO\\YD_PH4.OPUS",
- "AUDIO\\HD_PH1.OPUS", "AUDIO\\HD_PH2.OPUS", "AUDIO\\HD_PH3.OPUS", "AUDIO\\HD_PH4.OPUS", "AUDIO\\HD_PH5.OPUS", "AUDIO\\MT_PH1.OPUS",
- "AUDIO\\MT_PH2.OPUS", "AUDIO\\MT_PH3.OPUS", "AUDIO\\MT_PH4.OPUS", "AUDIO\\MISCOM.OPUS", "AUDIO\\END.OPUS", "AUDIO\\lib_a1.OPUS",
- "AUDIO\\lib_a2.OPUS", "AUDIO\\lib_a.OPUS", "AUDIO\\lib_b.OPUS", "AUDIO\\lib_c.OPUS", "AUDIO\\lib_d.OPUS", "AUDIO\\l2_a.OPUS",
- "AUDIO\\j4t_1.OPUS", "AUDIO\\j4t_2.OPUS", "AUDIO\\j4t_3.OPUS", "AUDIO\\j4t_4.OPUS", "AUDIO\\j4_a.OPUS", "AUDIO\\j4_b.OPUS",
- "AUDIO\\j4_c.OPUS", "AUDIO\\j4_d.OPUS", "AUDIO\\j4_e.OPUS", "AUDIO\\j4_f.OPUS", "AUDIO\\j6_1.OPUS", "AUDIO\\j6_a.OPUS",
- "AUDIO\\j6_b.OPUS", "AUDIO\\j6_c.OPUS", "AUDIO\\j6_d.OPUS", "AUDIO\\t4_a.OPUS", "AUDIO\\s1_a.OPUS", "AUDIO\\s1_a1.OPUS",
- "AUDIO\\s1_b.OPUS", "AUDIO\\s1_c.OPUS", "AUDIO\\s1_c1.OPUS", "AUDIO\\s1_d.OPUS", "AUDIO\\s1_e.OPUS", "AUDIO\\s1_f.OPUS",
- "AUDIO\\s1_g.OPUS", "AUDIO\\s1_h.OPUS", "AUDIO\\s1_i.OPUS", "AUDIO\\s1_j.OPUS", "AUDIO\\s1_k.OPUS", "AUDIO\\s1_l.OPUS",
- "AUDIO\\s3_a.OPUS", "AUDIO\\s3_b.OPUS", "AUDIO\\el3_a.OPUS", "AUDIO\\mf1_a.OPUS", "AUDIO\\mf2_a.OPUS", "AUDIO\\mf3_a.OPUS",
- "AUDIO\\mf3_b.OPUS", "AUDIO\\mf3_b1.OPUS", "AUDIO\\mf3_c.OPUS", "AUDIO\\mf4_a.OPUS", "AUDIO\\mf4_b.OPUS", "AUDIO\\mf4_c.OPUS",
- "AUDIO\\a1_a.OPUS", "AUDIO\\a3_a.OPUS", "AUDIO\\a5_a.OPUS", "AUDIO\\a4_a.OPUS", "AUDIO\\a4_b.OPUS", "AUDIO\\a4_c.OPUS",
- "AUDIO\\a4_d.OPUS", "AUDIO\\k1_a.OPUS", "AUDIO\\k3_a.OPUS", "AUDIO\\r1_a.OPUS", "AUDIO\\r2_a.OPUS", "AUDIO\\r2_b.OPUS",
- "AUDIO\\r2_c.OPUS", "AUDIO\\r2_d.OPUS", "AUDIO\\r2_e.OPUS", "AUDIO\\r2_f.OPUS", "AUDIO\\r2_g.OPUS", "AUDIO\\r2_h.OPUS",
- "AUDIO\\r5_a.OPUS", "AUDIO\\r6_a.OPUS", "AUDIO\\r6_a1.OPUS", "AUDIO\\r6_b.OPUS", "AUDIO\\lo2_a.OPUS", "AUDIO\\lo6_a.OPUS",
- "AUDIO\\yd2_a.OPUS", "AUDIO\\yd2_b.OPUS", "AUDIO\\yd2_c.OPUS", "AUDIO\\yd2_c1.OPUS", "AUDIO\\yd2_d.OPUS", "AUDIO\\yd2_e.OPUS",
- "AUDIO\\yd2_f.OPUS", "AUDIO\\yd2_g.OPUS", "AUDIO\\yd2_h.OPUS", "AUDIO\\yd2_ass.OPUS", "AUDIO\\yd2_ok.OPUS", "AUDIO\\h5_a.OPUS",
- "AUDIO\\h5_b.OPUS", "AUDIO\\h5_c.OPUS", "AUDIO\\ammu_a.OPUS", "AUDIO\\ammu_b.OPUS", "AUDIO\\ammu_c.OPUS", "AUDIO\\door_1.OPUS",
- "AUDIO\\door_2.OPUS", "AUDIO\\door_3.OPUS", "AUDIO\\door_4.OPUS", "AUDIO\\door_5.OPUS", "AUDIO\\door_6.OPUS", "AUDIO\\t3_a.OPUS",
- "AUDIO\\t3_b.OPUS", "AUDIO\\t3_c.OPUS", "AUDIO\\k1_b.OPUS", "AUDIO\\cat1.OPUS"};
-#else
#ifdef PS2_AUDIO_PATHS
-static char PS2StreamedNameTable[][25]=
+static char PS2StreamedNameTable[][40] =
{
- "AUDIO\\MUSIC\\HEAD.VB",
- "AUDIO\\MUSIC\\CLASS.VB",
- "AUDIO\\MUSIC\\KJAH.VB",
- "AUDIO\\MUSIC\\RISE.VB",
- "AUDIO\\MUSIC\\LIPS.VB",
- "AUDIO\\MUSIC\\GAME.VB",
- "AUDIO\\MUSIC\\MSX.VB",
+ "AUDIO\\MUSIC\\WILD.VB",
"AUDIO\\MUSIC\\FLASH.VB",
- "AUDIO\\MUSIC\\CHAT.VB",
- "AUDIO\\MUSIC\\HEAD.VB",
- "AUDIO\\MUSIC\\POLICE.VB",
+ "AUDIO\\MUSIC\\KCHAT.VB", // 16 khz
+ "AUDIO\\MUSIC\\FEVER.VB",
+ "AUDIO\\MUSIC\\VROCK.VB",
+ "AUDIO\\MUSIC\\VCPR.VB", // 16 khz
+ "AUDIO\\MUSIC\\ESPANT.VB",
+ "AUDIO\\MUSIC\\EMOTION.VB",
+ "AUDIO\\MUSIC\\WAVE.VB",
+ "AUDIO\\MUSIC\\MISCOM.VB",
"AUDIO\\MUSIC\\CITY.VB",
"AUDIO\\MUSIC\\WATER.VB",
- "AUDIO\\MUSIC\\COMOPEN.VB",
- "AUDIO\\MUSIC\\SUBOPEN.VB",
- "AUDIO\\OTHER\\JB.VB",
- "AUDIO\\OTHER\\BET.VB",
- "AUDIO\\LUIGI\\L1_LG.VB",
- "AUDIO\\LUIGI\\L2_DSB.VB",
- "AUDIO\\LUIGI\\L3_DM.VB",
- "AUDIO\\LUIGI\\L4_PAP.VB",
- "AUDIO\\LUIGI\\L5_TFB.VB",
- "AUDIO\\JOEY\\J0_DM2.VB",
- "AUDIO\\JOEY\\J1_LFL.VB",
- "AUDIO\\JOEY\\J2_KCL.VB",
- "AUDIO\\JOEY\\J3_VH.VB",
- "AUDIO\\JOEY\\J4_ETH.VB",
- "AUDIO\\JOEY\\J5_DST.VB",
- "AUDIO\\JOEY\\J6_TBJ.VB",
- "AUDIO\\TONI\\T1_TOL.VB",
- "AUDIO\\TONI\\T2_TPU.VB",
- "AUDIO\\TONI\\T3_MAS.VB",
- "AUDIO\\TONI\\T4_TAT.VB",
- "AUDIO\\TONI\\T5_BF.VB",
- "AUDIO\\SAL\\S0_MAS.VB",
- "AUDIO\\SAL\\S1_PF.VB",
- "AUDIO\\SAL\\S2_CTG.VB",
- "AUDIO\\SAL\\S3_RTC.VB",
- "AUDIO\\SAL\\S5_LRQ.VB",
- "AUDIO\\EBALL\\S4_BDBA.VB",
- "AUDIO\\EBALL\\S4_BDBB.VB",
- "AUDIO\\SAL\\S2_CTG2.VB",
- "AUDIO\\SAL\\S4_BDBD.VB",
- "AUDIO\\SAL\\S5_LRQB.VB",
- "AUDIO\\SAL\\S5_LRQC.VB",
- "AUDIO\\ASUKA\\A1_SSO.VB",
- "AUDIO\\ASUKA\\A2_PP.VB",
- "AUDIO\\ASUKA\\A3_SS.VB",
- "AUDIO\\ASUKA\\A4_PDR.VB",
- "AUDIO\\ASUKA\\A5_K2FT.VB",
- "AUDIO\\KENJI\\K1_KBO.VB",
- "AUDIO\\KENJI\\K2_GIS.VB",
- "AUDIO\\KENJI\\K3_DS.VB",
- "AUDIO\\KENJI\\K4_SHI.VB",
- "AUDIO\\KENJI\\K5_SD.VB",
- "AUDIO\\RAY\\R0_PDR2.VB",
- "AUDIO\\RAY\\R1_SW.VB",
- "AUDIO\\RAY\\R2_AP.VB",
- "AUDIO\\RAY\\R3_ED.VB",
- "AUDIO\\RAY\\R4_GF.VB",
- "AUDIO\\RAY\\R5_PB.VB",
- "AUDIO\\RAY\\R6_MM.VB",
- "AUDIO\\LOVE\\D1_STOG.VB",
- "AUDIO\\LOVE\\D2_KK.VB",
- "AUDIO\\LOVE\\D3_ADO.VB",
- "AUDIO\\LOVE\\D5_ES.VB",
- "AUDIO\\LOVE\\D7_MLD.VB",
- "AUDIO\\LOVE\\D4_GTA.VB",
- "AUDIO\\LOVE\\D4_GTA2.VB",
- "AUDIO\\LOVE\\D6_STS.VB",
- "AUDIO\\ASUKA\\A6_BAIT.VB",
- "AUDIO\\ASUKA\\A7_ETG.VB",
- "AUDIO\\ASUKA\\A8_PS.VB",
- "AUDIO\\ASUKA\\A9_ASD.VB",
- "AUDIO\\SHOP\\K4_SHI2.VB",
- "AUDIO\\OTHER\\C1_TEX.VB",
- "AUDIO\\PHONE\\EL_PH1.VB",
- "AUDIO\\PHONE\\EL_PH2.VB",
- "AUDIO\\PHONE\\EL_PH3.VB",
- "AUDIO\\PHONE\\EL_PH4.VB",
- "AUDIO\\PHONE\\YD_PH1.VB",
- "AUDIO\\PHONE\\YD_PH2.VB",
- "AUDIO\\PHONE\\YD_PH3.VB",
- "AUDIO\\PHONE\\YD_PH4.VB",
- "AUDIO\\PHONE\\HD_PH1.VB",
- "AUDIO\\PHONE\\HD_PH2.VB",
- "AUDIO\\PHONE\\HD_PH3.VB",
- "AUDIO\\PHONE\\HD_PH4.VB",
- "AUDIO\\PHONE\\HD_PH5.VB",
- "AUDIO\\PHONE\\MT_PH1.VB",
- "AUDIO\\PHONE\\MT_PH2.VB",
- "AUDIO\\PHONE\\MT_PH3.VB",
- "AUDIO\\PHONE\\MT_PH4.VB",
+ "AUDIO\\MUSIC\\BEACHAMB.VB",
+ "AUDIO\\MUSIC\\HCITY.VB",
+ "AUDIO\\MUSIC\\HWATER.VB",
+ "AUDIO\\MUSIC\\HBEACH.VB",
+ "AUDIO\\MUSIC\\MALLAMB.VB",
+ "AUDIO\\MUSIC\\STRIP.VB",
+ "AUDIO\\MUSIC\\MALIBU.VB",
+ "AUDIO\\MUSIC\\HOTEL.VB",
+ "AUDIO\\MUSIC\\DIRTRING.VB",
+ "AUDIO\\MUSIC\\LAW4RIOT.VB",
+ "AUDIO\\MUSIC\\AMBSIL.VB",
+ "AUDIO\\MUSIC\\POLICE.VB", // 16 khz
+ "AUDIO\\MUSIC\\TAXI.VB",
+ "AUDIO\\MUSIC\\BCLOSED.VB",
+ "AUDIO\\MUSIC\\BOPEN.VB",
+ "AUDIO\\CUTSCENE\\ASS\\ASS_1.VB",
+ "AUDIO\\CUTSCENE\\ASS\\ASS_2.VB",
+ "AUDIO\\CUTSCENE\\BANK\\BANK_1.VB",
+ "AUDIO\\CUTSCENE\\BANK\\BANK_2A.VB",
+ "AUDIO\\CUTSCENE\\BANK\\BANK_2B.VB",
+ "AUDIO\\CUTSCENE\\BANK\\BANK_3A.VB",
+ "AUDIO\\CUTSCENE\\BANK\\BANK_3B.VB",
+ "AUDIO\\CUTSCENE\\BANK\\BANK_4.VB",
+ "AUDIO\\CUTSCENE\\BIKE\\BIKE_1.VB",
+ "AUDIO\\CUTSCENE\\BIKE\\BIKE_2.VB",
+ "AUDIO\\CUTSCENE\\BIKE\\BIKE_3.VB",
+ "AUDIO\\CUTSCENE\\BUD\\BUD_1.VB",
+ "AUDIO\\CUTSCENE\\BUD\\BUD_2.VB",
+ "AUDIO\\CUTSCENE\\BUD\\BUD_3.VB",
+ "AUDIO\\CUTSCENE\\CAP\\CAP_1.VB",
+ "AUDIO\\CUTSCENE\\CAR\\CAR_1.VB",
+ "AUDIO\\CUTSCENE\\CNT\\CNT_1A.VB",
+ "AUDIO\\CUTSCENE\\CNT\\CNT_1B.VB",
+ "AUDIO\\CUTSCENE\\CNT\\CNT_2.VB",
+ "AUDIO\\CUTSCENE\\COK\\COK_1.VB",
+ "AUDIO\\CUTSCENE\\COK\\COK_2A.VB",
+ "AUDIO\\CUTSCENE\\COK\\COK_2B.VB",
+ "AUDIO\\CUTSCENE\\COK\\COK_3.VB",
+ "AUDIO\\CUTSCENE\\COK\\COK_4A.VB",
+ "AUDIO\\CUTSCENE\\COK\\COK_4A2.VB",
+ "AUDIO\\CUTSCENE\\COK\\COK_4B.VB",
+ "AUDIO\\CUTSCENE\\COL\\COL_1.VB",
+ "AUDIO\\CUTSCENE\\COL\\COL_2.VB",
+ "AUDIO\\CUTSCENE\\COL\\COL_3A.VB",
+ "AUDIO\\CUTSCENE\\COL\\COL_4A.VB",
+ "AUDIO\\CUTSCENE\\COL\\COL_5A.VB",
+ "AUDIO\\CUTSCENE\\COL\\COL_5B.VB",
+ "AUDIO\\CUTSCENE\\CUB\\CUB_1.VB",
+ "AUDIO\\CUTSCENE\\CUB\\CUB_2.VB",
+ "AUDIO\\CUTSCENE\\CUB\\CUB_3.VB",
+ "AUDIO\\CUTSCENE\\CUB\\CUB_4.VB",
+ "AUDIO\\CUTSCENE\\DRUG\\DRUG_1.VB",
+ "AUDIO\\CUTSCENE\\FIN\\FIN.VB",
+ "AUDIO\\CUTSCENE\\FIN\\FIN2.VB",
+ "AUDIO\\CUTSCENE\\FINALE\\FINALE.VB",
+ "AUDIO\\CUTSCENE\\HAT\\HAT_1.VB",
+ "AUDIO\\CUTSCENE\\HAT\\HAT_2.VB",
+ "AUDIO\\CUTSCENE\\HAT\\HAT_3.VB",
+ "AUDIO\\CUTSCENE\\ICE\\ICE_1.VB",
+ "AUDIO\\CUTSCENE\\INT\\INT_A.VB",
+ "AUDIO\\CUTSCENE\\INT\\INT_B.VB",
+ "AUDIO\\CUTSCENE\\INT\\INT_D.VB",
+ "AUDIO\\CUTSCENE\\INT\\INT_M.VB",
+ "AUDIO\\CUTSCENE\\LAW\\LAW_1A.VB",
+ "AUDIO\\CUTSCENE\\LAW\\LAW_1B.VB",
+ "AUDIO\\CUTSCENE\\LAW\\LAW_2A.VB",
+ "AUDIO\\CUTSCENE\\LAW\\LAW_2B.VB",
+ "AUDIO\\CUTSCENE\\LAW\\LAW_2C.VB",
+ "AUDIO\\CUTSCENE\\LAW\\LAW_3.VB",
+ "AUDIO\\CUTSCENE\\LAW\\LAW_4.VB",
+ "AUDIO\\CUTSCENE\\PHIL\\PHIL_1.VB",
+ "AUDIO\\CUTSCENE\\PHIL\\PHIL_2.VB",
+ "AUDIO\\CUTSCENE\\PORN\\PORN_1.VB",
+ "AUDIO\\CUTSCENE\\PORN\\PORN_2.VB",
+ "AUDIO\\CUTSCENE\\PORN\\PORN_3.VB",
+ "AUDIO\\CUTSCENE\\PORN\\PORN_4.VB",
+ "AUDIO\\CUTSCENE\\RESC\\RESC_1A.VB",
+ "AUDIO\\CUTSCENE\\ROK\\ROK_1.VB",
+ "AUDIO\\CUTSCENE\\ROK\\ROK_2.VB",
+ "AUDIO\\CUTSCENE\\ROK\\ROK_3A.VB",
+ "AUDIO\\CUTSCENE\\STRIPA\\STRIPA.VB",
+ "AUDIO\\CUTSCENE\\TAX\\TAX_1.VB",
+ "AUDIO\\CUTSCENE\\TEX\\TEX_1.VB",
+ "AUDIO\\CUTSCENE\\TEX\\TEX_2.VB",
+ "AUDIO\\CUTSCENE\\TEX\\TEX_3.VB",
+ "AUDIO\\MUSIC\\GLIGHT.VB",
+ "AUDIO\\MUSIC\\FIST.VB",
+ "AUDIO\\MUSIC\\MISCOM.VB",
"AUDIO\\MUSIC\\MISCOM.VB",
- "AUDIO\\MUSIC\\END.VB",
- "AUDIO\\lib_a1.WAV",
- "AUDIO\\lib_a2.WAV",
- "AUDIO\\lib_a.WAV",
- "AUDIO\\lib_b.WAV",
- "AUDIO\\lib_c.WAV",
- "AUDIO\\lib_d.WAV",
- "AUDIO\\l2_a.WAV",
- "AUDIO\\j4t_1.WAV",
- "AUDIO\\j4t_2.WAV",
- "AUDIO\\j4t_3.WAV",
- "AUDIO\\j4t_4.WAV",
- "AUDIO\\j4_a.WAV",
- "AUDIO\\j4_b.WAV",
- "AUDIO\\j4_c.WAV",
- "AUDIO\\j4_d.WAV",
- "AUDIO\\j4_e.WAV",
- "AUDIO\\j4_f.WAV",
- "AUDIO\\j6_1.WAV",
- "AUDIO\\j6_a.WAV",
- "AUDIO\\j6_b.WAV",
- "AUDIO\\j6_c.WAV",
- "AUDIO\\j6_d.WAV",
- "AUDIO\\t4_a.WAV",
- "AUDIO\\s1_a.WAV",
- "AUDIO\\s1_a1.WAV",
- "AUDIO\\s1_b.WAV",
- "AUDIO\\s1_c.WAV",
- "AUDIO\\s1_c1.WAV",
- "AUDIO\\s1_d.WAV",
- "AUDIO\\s1_e.WAV",
- "AUDIO\\s1_f.WAV",
- "AUDIO\\s1_g.WAV",
- "AUDIO\\s1_h.WAV",
- "AUDIO\\s1_i.WAV",
- "AUDIO\\s1_j.WAV",
- "AUDIO\\s1_k.WAV",
- "AUDIO\\s1_l.WAV",
- "AUDIO\\s3_a.WAV",
- "AUDIO\\s3_b.WAV",
- "AUDIO\\el3_a.WAV",
- "AUDIO\\mf1_a.WAV",
- "AUDIO\\mf2_a.WAV",
- "AUDIO\\mf3_a.WAV",
- "AUDIO\\mf3_b.WAV",
- "AUDIO\\mf3_b1.WAV",
- "AUDIO\\mf3_c.WAV",
- "AUDIO\\mf4_a.WAV",
- "AUDIO\\mf4_b.WAV",
- "AUDIO\\mf4_c.WAV",
- "AUDIO\\a1_a.WAV",
- "AUDIO\\a3_a.WAV",
- "AUDIO\\a5_a.WAV",
- "AUDIO\\a4_a.WAV",
- "AUDIO\\a4_b.WAV",
- "AUDIO\\a4_c.WAV",
- "AUDIO\\a4_d.WAV",
- "AUDIO\\k1_a.WAV",
- "AUDIO\\k3_a.WAV",
- "AUDIO\\r1_a.WAV",
- "AUDIO\\r2_a.WAV",
- "AUDIO\\r2_b.WAV",
- "AUDIO\\r2_c.WAV",
- "AUDIO\\r2_d.WAV",
- "AUDIO\\r2_e.WAV",
- "AUDIO\\r2_f.WAV",
- "AUDIO\\r2_g.WAV",
- "AUDIO\\r2_h.WAV",
- "AUDIO\\r5_a.WAV",
- "AUDIO\\r6_a.WAV",
- "AUDIO\\r6_a1.WAV",
- "AUDIO\\r6_b.WAV",
- "AUDIO\\lo2_a.WAV",
- "AUDIO\\lo6_a.WAV",
- "AUDIO\\yd2_a.WAV",
- "AUDIO\\yd2_b.WAV",
- "AUDIO\\yd2_c.WAV",
- "AUDIO\\yd2_c1.WAV",
- "AUDIO\\yd2_d.WAV",
- "AUDIO\\yd2_e.WAV",
- "AUDIO\\yd2_f.WAV",
- "AUDIO\\yd2_g.WAV",
- "AUDIO\\yd2_h.WAV",
- "AUDIO\\yd2_ass.WAV",
- "AUDIO\\yd2_ok.WAV",
- "AUDIO\\h5_a.WAV",
- "AUDIO\\h5_b.WAV",
- "AUDIO\\h5_c.WAV",
- "AUDIO\\ammu_a.WAV",
- "AUDIO\\ammu_b.WAV",
- "AUDIO\\ammu_c.WAV",
- "AUDIO\\door_1.WAV",
- "AUDIO\\door_2.WAV",
- "AUDIO\\door_3.WAV",
- "AUDIO\\door_4.WAV",
- "AUDIO\\door_5.WAV",
- "AUDIO\\door_6.WAV",
- "AUDIO\\t3_a.WAV",
- "AUDIO\\t3_b.WAV",
- "AUDIO\\t3_c.WAV",
- "AUDIO\\k1_b.WAV",
- "AUDIO\\cat1.WAV"
+ "AUDIO\\MUSIC\\MISCOM.VB",
+ "AUDIO\\MUSIC\\MISCOM.VB",
+ "AUDIO\\MOBR1.WAV",
+ "AUDIO\\PAGER.WAV",
+ "AUDIO\\CARREV.WAV",
+ "AUDIO\\BIKEREV.WAV",
+ "AUDIO\\LIFTOP.WAV",
+ "AUDIO\\LIFTCL.WAV",
+ "AUDIO\\LIFTRUN.WAV",
+ "AUDIO\\LIFTBEL.WAV",
+ "AUDIO\\INLIFT.WAV",
+ "AUDIO\\SFX_01.WAV",
+ "AUDIO\\SFX_02.WAV",
+ "AUDIO\\CAMERAL.WAV",
+ "AUDIO\\CAMERAR.WAV",
+ "AUDIO\\CHEER1.WAV",
+ "AUDIO\\CHEER2.WAV",
+ "AUDIO\\CHEER3.WAV",
+ "AUDIO\\CHEER4.WAV",
+ "AUDIO\\OOH1.WAV",
+ "AUDIO\\OOH2.WAV",
+ "AUDIO\\RACE1.WAV",
+ "AUDIO\\RACE2.WAV",
+ "AUDIO\\RACE3.WAV",
+ "AUDIO\\RACE4.WAV",
+ "AUDIO\\RACE5.WAV",
+ "AUDIO\\RACE6.WAV",
+ "AUDIO\\RACE7.WAV",
+ "AUDIO\\RACE8.WAV",
+ "AUDIO\\RACE9.WAV",
+ "AUDIO\\RACE10.WAV",
+ "AUDIO\\RACE11.WAV",
+ "AUDIO\\RACE12.WAV",
+ "AUDIO\\RACE13.WAV",
+ "AUDIO\\RACE14.WAV",
+ "AUDIO\\RACE15.WAV",
+ "AUDIO\\HOT1.WAV",
+ "AUDIO\\HOT2.WAV",
+ "AUDIO\\HOT3.WAV",
+ "AUDIO\\HOT4.WAV",
+ "AUDIO\\HOT5.WAV",
+ "AUDIO\\HOT6.WAV",
+ "AUDIO\\HOT7.WAV",
+ "AUDIO\\HOT8.WAV",
+ "AUDIO\\HOT9.WAV",
+ "AUDIO\\HOT10.WAV",
+ "AUDIO\\HOT11.WAV",
+ "AUDIO\\HOT12.WAV",
+ "AUDIO\\HOT13.WAV",
+ "AUDIO\\HOT14.WAV",
+ "AUDIO\\HOT15.WAV",
+ "AUDIO\\LANSTP1.WAV",
+ "AUDIO\\LANSTP2.WAV",
+ "AUDIO\\LANAMU1.WAV",
+ "AUDIO\\LANAMU2.WAV",
+ "AUDIO\\AIRHORNL.WAV",
+ "AUDIO\\AIRHORNR.WAV",
+ "AUDIO\\SNIPSCRL.WAV",
+ "AUDIO\\SNIPSHORT.WAV",
+ "AUDIO\\BLOWROOF.WAV",
+ "AUDIO\\ASS_1.WAV",
+ "AUDIO\\ASS_2.WAV",
+ "AUDIO\\ASS_3.WAV",
+ "AUDIO\\ASS_4.WAV",
+ "AUDIO\\ASS_5.WAV",
+ "AUDIO\\ASS_6.WAV",
+ "AUDIO\\ASS_7.WAV",
+ "AUDIO\\ASS_8.WAV",
+ "AUDIO\\ASS_9.WAV",
+ "AUDIO\\ASS_10.WAV",
+ "AUDIO\\ASS_11.WAV",
+ "AUDIO\\ASS_12.WAV",
+ "AUDIO\\ASS_13.WAV",
+ "AUDIO\\ASS_14.WAV",
+ "AUDIO\\BIKE1_1.WAV",
+ "AUDIO\\BIKE1_2.WAV",
+ "AUDIO\\BIKE1_3.WAV",
+ "AUDIO\\BNK1_1.WAV",
+ "AUDIO\\BNK1_2.WAV",
+ "AUDIO\\BNK1_3.WAV",
+ "AUDIO\\BNK1_4.WAV",
+ "AUDIO\\BNK1_5.WAV",
+ "AUDIO\\BNK1_6.WAV",
+ "AUDIO\\BNK1_7.WAV",
+ "AUDIO\\BNK1_8.WAV",
+ "AUDIO\\BNK1_10.WAV",
+ "AUDIO\\BNK1_11.WAV",
+ "AUDIO\\BNK1_12.WAV",
+ "AUDIO\\BNK1_13.WAV",
+ "AUDIO\\BNK1_14.WAV",
+ "AUDIO\\BNK2_1.WAV",
+ "AUDIO\\BNK2_2.WAV",
+ "AUDIO\\BNK2_3.WAV",
+ "AUDIO\\BNK2_4.WAV",
+ "AUDIO\\BNK2_5.WAV",
+ "AUDIO\\BNK2_6.WAV",
+ "AUDIO\\BNK2_7.WAV",
+ "AUDIO\\BNK2_8.WAV",
+ "AUDIO\\BNK2_9.WAV",
+ "AUDIO\\BNK3_1.WAV",
+ "AUDIO\\BNK3_2.WAV",
+ "AUDIO\\BNK3_3A.WAV",
+ "AUDIO\\BNK3_3B.WAV",
+ "AUDIO\\BNK3_3C.WAV",
+ "AUDIO\\BNK3_4A.WAV",
+ "AUDIO\\BNK3_4B.WAV",
+ "AUDIO\\BNK3_4C.WAV",
+ "AUDIO\\BNK4_1.WAV",
+ "AUDIO\\BNK4_2.WAV",
+ "AUDIO\\BNK4_3A.WAV",
+ "AUDIO\\BNK4_3B.WAV",
+ "AUDIO\\BNK4_3C.WAV",
+ "AUDIO\\BNK4_3D.WAV",
+ "AUDIO\\BNK4_3E.WAV",
+ "AUDIO\\BNK4_3F.WAV",
+ "AUDIO\\BNK4_3G.WAV",
+ "AUDIO\\BNK4_3H.WAV",
+ "AUDIO\\BNK4_3I.WAV",
+ "AUDIO\\BNK4_3J.WAV",
+ "AUDIO\\BNK4_3K.WAV",
+ "AUDIO\\BNK4_3M.WAV",
+ "AUDIO\\BNK4_3O.WAV",
+ "AUDIO\\BNK4_3P.WAV",
+ "AUDIO\\BNK4_3Q.WAV",
+ "AUDIO\\BNK4_3R.WAV",
+ "AUDIO\\BNK4_3S.WAV",
+ "AUDIO\\BNK4_3T.WAV",
+ "AUDIO\\BNK4_3U.WAV",
+ "AUDIO\\BNK4_3V.WAV",
+ "AUDIO\\BNK4_4A.WAV",
+ "AUDIO\\BNK4_4B.WAV",
+ "AUDIO\\BNK4_5.WAV",
+ "AUDIO\\BNK4_6.WAV",
+ "AUDIO\\BNK4_7.WAV",
+ "AUDIO\\BNK4_8.WAV",
+ "AUDIO\\BNK4_9.WAV",
+ "AUDIO\\BNK4_10.WAV",
+ "AUDIO\\BNK4_11.WAV",
+ "AUDIO\\BK4_12A.WAV",
+ "AUDIO\\BK4_12B.WAV",
+ "AUDIO\\BK4_12C.WAV",
+ "AUDIO\\BNK4_13.WAV",
+ "AUDIO\\BK4_14A.WAV",
+ "AUDIO\\BK4_14B.WAV",
+ "AUDIO\\BNK4_15.WAV",
+ "AUDIO\\BNK4_16.WAV",
+ "AUDIO\\BNK4_17.WAV",
+ "AUDIO\\BNK4_18.WAV",
+ "AUDIO\\BK4_19A.WAV",
+ "AUDIO\\BK4_19B.WAV",
+ "AUDIO\\BK4_20A.WAV",
+ "AUDIO\\BK4_20B.WAV",
+ "AUDIO\\BNK4_21.WAV",
+ "AUDIO\\BNK422A.WAV",
+ "AUDIO\\BNK422B.WAV",
+ "AUDIO\\BK4_23A.WAV",
+ "AUDIO\\BK4_23B.WAV",
+ "AUDIO\\BK4_23C.WAV",
+ "AUDIO\\BK4_23D.WAV",
+ "AUDIO\\BK4_24A.WAV",
+ "AUDIO\\BK4_24B.WAV",
+ "AUDIO\\BNK4_25.WAV",
+ "AUDIO\\BNK4_26.WAV",
+ "AUDIO\\BNK4_27.WAV",
+ "AUDIO\\BNK4_28.WAV",
+ "AUDIO\\BNK4_29.WAV",
+ "AUDIO\\BNK4_30.WAV",
+ "AUDIO\\BK4_31A.WAV",
+ "AUDIO\\BK4_31B.WAV",
+ "AUDIO\\BNK4_32.WAV",
+ "AUDIO\\BK4_34A.WAV",
+ "AUDIO\\BK4_34B.WAV",
+ "AUDIO\\BK4_35A.WAV",
+ "AUDIO\\BK4_35B.WAV",
+ "AUDIO\\BNK4_36.WAV",
+ "AUDIO\\BNK4_37.WAV",
+ "AUDIO\\BNK4_38.WAV",
+ "AUDIO\\BNK4_39.WAV",
+ "AUDIO\\BK4_40A.WAV",
+ "AUDIO\\BK4_40B.WAV",
+ "AUDIO\\BNK4_41.WAV",
+ "AUDIO\\BNK4_42.WAV",
+ "AUDIO\\BNK4_43.WAV",
+ "AUDIO\\BNK4_44.WAV",
+ "AUDIO\\BNK4_45.WAV",
+ "AUDIO\\BNK4_46.WAV",
+ "AUDIO\\BNK4_47.WAV",
+ "AUDIO\\BNK4_48.WAV",
+ "AUDIO\\BNK4_49.WAV",
+ "AUDIO\\BNK450A.WAV",
+ "AUDIO\\BNK450B.WAV",
+ "AUDIO\\BNK4_51.WAV",
+ "AUDIO\\BNK4_94.WAV",
+ "AUDIO\\BNK4_95.WAV",
+ "AUDIO\\BNK4_96.WAV",
+ "AUDIO\\BNK4_97.WAV",
+ "AUDIO\\BNK4_98.WAV",
+ "AUDIO\\BNK4_99.WAV",
+ "AUDIO\\BUD1_1.WAV",
+ "AUDIO\\BUD1_2.WAV",
+ "AUDIO\\BUD1_3.WAV",
+ "AUDIO\\BUD1_4.WAV",
+ "AUDIO\\BUD1_5.WAV",
+ "AUDIO\\BUD1_9.WAV",
+ "AUDIO\\BUD1_10.WAV",
+ "AUDIO\\BUD2_1.WAV",
+ "AUDIO\\BUD2_2.WAV",
+ "AUDIO\\BUD2_3.WAV",
+ "AUDIO\\BUD2_4.WAV",
+ "AUDIO\\BUD2_5.WAV",
+ "AUDIO\\BUD2_6.WAV",
+ "AUDIO\\BUD2_7.WAV",
+ "AUDIO\\BUD3_1.WAV",
+ "AUDIO\\BUD3_1A.WAV",
+ "AUDIO\\BUD3_1B.WAV",
+ "AUDIO\\BUD3_1C.WAV",
+ "AUDIO\\BUD3_2.WAV",
+ "AUDIO\\BUD3_3.WAV",
+ "AUDIO\\BUD3_4.WAV",
+ "AUDIO\\BUD3_5.WAV",
+ "AUDIO\\BUD3_6.WAV",
+ "AUDIO\\BUD3_7.WAV",
+ "AUDIO\\BUD3_8A.WAV",
+ "AUDIO\\BUD3_8B.WAV",
+ "AUDIO\\BUD3_8C.WAV",
+ "AUDIO\\BUD3_9A.WAV",
+ "AUDIO\\BUD3_9B.WAV",
+ "AUDIO\\BUD3_9C.WAV",
+ "AUDIO\\CAP1_2.WAV",
+ "AUDIO\\CAP1_3.WAV",
+ "AUDIO\\CAP1_4.WAV",
+ "AUDIO\\CAP1_5.WAV",
+ "AUDIO\\CAP1_6.WAV",
+ "AUDIO\\CAP1_7.WAV",
+ "AUDIO\\CAP1_8.WAV",
+ "AUDIO\\CAP1_9.WAV",
+ "AUDIO\\CAP1_10.WAV",
+ "AUDIO\\CAP1_11.WAV",
+ "AUDIO\\CAP1_12.WAV",
+ "AUDIO\\CNT1_1.WAV",
+ "AUDIO\\CNT1_2.WAV",
+ "AUDIO\\CNT1_3.WAV",
+ "AUDIO\\CNT1_4.WAV",
+ "AUDIO\\CNT1_5.WAV",
+ "AUDIO\\CNT2_1.WAV",
+ "AUDIO\\CNT2_2.WAV",
+ "AUDIO\\CNT2_3.WAV",
+ "AUDIO\\CNT2_4.WAV",
+ "AUDIO\\COK1_1.WAV",
+ "AUDIO\\COK1_2.WAV",
+ "AUDIO\\COK1_3.WAV",
+ "AUDIO\\COK1_4.WAV",
+ "AUDIO\\COK1_5.WAV",
+ "AUDIO\\COK1_6.WAV",
+ "AUDIO\\COK2_1.WAV",
+ "AUDIO\\COK2_2.WAV",
+ "AUDIO\\COK2_3.WAV",
+ "AUDIO\\COK2_4.WAV",
+ "AUDIO\\COK2_5.WAV",
+ "AUDIO\\COK2_6.WAV",
+ "AUDIO\\COK2_7A.WAV",
+ "AUDIO\\COK2_7B.WAV",
+ "AUDIO\\COK2_7C.WAV",
+ "AUDIO\\COK2_8A.WAV",
+ "AUDIO\\COK2_8B.WAV",
+ "AUDIO\\COK2_8C.WAV",
+ "AUDIO\\COK2_8D.WAV",
+ "AUDIO\\COK2_9.WAV",
+ "AUDIO\\COK210A.WAV",
+ "AUDIO\\COK210B.WAV",
+ "AUDIO\\COK210C.WAV",
+ "AUDIO\\COK212A.WAV",
+ "AUDIO\\COK212B.WAV",
+ "AUDIO\\COK2_13.WAV",
+ "AUDIO\\COK2_14.WAV",
+ "AUDIO\\COK2_15.WAV",
+ "AUDIO\\COK2_16.WAV",
+ "AUDIO\\COK2_20.WAV",
+ "AUDIO\\COK2_21.WAV",
+ "AUDIO\\COK2_2.WAV", // this is probably a typo of COK2_22
+ "AUDIO\\COK3_1.WAV",
+ "AUDIO\\COK3_2.WAV",
+ "AUDIO\\COK3_3.WAV",
+ "AUDIO\\COK3_4.WAV",
+ "AUDIO\\COK4_1.WAV",
+ "AUDIO\\COK4_2.WAV",
+ "AUDIO\\COK4_3.WAV",
+ "AUDIO\\COK4_4.WAV",
+ "AUDIO\\COK4_5.WAV",
+ "AUDIO\\COK4_6.WAV",
+ "AUDIO\\COK4_7.WAV",
+ "AUDIO\\COK4_8.WAV",
+ "AUDIO\\COK4_9.WAV",
+ "AUDIO\\COK4_9A.WAV",
+ "AUDIO\\COK4_10.WAV",
+ "AUDIO\\COK4_11.WAV",
+ "AUDIO\\COK4_12.WAV",
+ "AUDIO\\COK4_13.WAV",
+ "AUDIO\\COK4_14.WAV",
+ "AUDIO\\COK4_15.WAV",
+ "AUDIO\\COK4_16.WAV",
+ "AUDIO\\COK4_17.WAV",
+ "AUDIO\\COK4_18.WAV",
+ "AUDIO\\COK4_19.WAV",
+ "AUDIO\\COK4_20.WAV",
+ "AUDIO\\COK4_21.WAV",
+ "AUDIO\\COK4_22.WAV",
+ "AUDIO\\COK4_23.WAV",
+ "AUDIO\\COK4_24.WAV",
+ "AUDIO\\COK4_25.WAV",
+ "AUDIO\\COK4_26.WAV",
+ "AUDIO\\COK4_27.WAV",
+ "AUDIO\\COL1_1.WAV",
+ "AUDIO\\COL1_2.WAV",
+ "AUDIO\\COL1_3.WAV",
+ "AUDIO\\COL1_4.WAV",
+ "AUDIO\\COL1_5.WAV",
+ "AUDIO\\COL1_6.WAV",
+ "AUDIO\\COL1_7.WAV",
+ "AUDIO\\COL1_8.WAV",
+ "AUDIO\\COL2_1.WAV",
+ "AUDIO\\COL2_2.WAV",
+ "AUDIO\\COL2_3.WAV",
+ "AUDIO\\COL2_4.WAV",
+ "AUDIO\\COL2_5.WAV",
+ "AUDIO\\COL2_6A.WAV",
+ "AUDIO\\COL2_7.WAV",
+ "AUDIO\\COL2_8.WAV",
+ "AUDIO\\COL2_9.WAV",
+ "AUDIO\\COL2_10.WAV",
+ "AUDIO\\COL2_11.WAV",
+ "AUDIO\\COL2_12.WAV",
+ "AUDIO\\COL2_13.WAV",
+ "AUDIO\\COL2_14.WAV",
+ "AUDIO\\COL2_15.WAV",
+ "AUDIO\\COL2_16.WAV",
+ "AUDIO\\COL3_1.WAV",
+ "AUDIO\\COL3_2.WAV",
+ "AUDIO\\COL3_2A.WAV",
+ "AUDIO\\COL3_2B.WAV",
+ "AUDIO\\COL3_3.WAV",
+ "AUDIO\\COL3_4.WAV",
+ "AUDIO\\COL3_5.WAV",
+ "AUDIO\\COL3_6.WAV",
+ "AUDIO\\COL3_7.WAV",
+ "AUDIO\\COL3_8.WAV",
+ "AUDIO\\COL3_9.WAV",
+ "AUDIO\\COL3_10.WAV",
+ "AUDIO\\COL3_11.WAV",
+ "AUDIO\\COL3_12.WAV",
+ "AUDIO\\COL3_13.WAV",
+ "AUDIO\\COL3_14.WAV",
+ "AUDIO\\COL3_15.WAV",
+ "AUDIO\\COL3_16.WAV",
+ "AUDIO\\COL3_17.WAV",
+ "AUDIO\\COL3_18.WAV",
+ "AUDIO\\COL3_19.WAV",
+ "AUDIO\\COL3_20.WAV",
+ "AUDIO\\COL3_21.WAV",
+ "AUDIO\\COL3_23.WAV",
+ "AUDIO\\COL3_24.WAV",
+ "AUDIO\\COL3_25.WAV",
+ "AUDIO\\COL4_1.WAV",
+ "AUDIO\\COL4_2.WAV",
+ "AUDIO\\COL4_3.WAV",
+ "AUDIO\\COL4_4.WAV",
+ "AUDIO\\COL4_5.WAV",
+ "AUDIO\\COL4_6.WAV",
+ "AUDIO\\COL4_7.WAV",
+ "AUDIO\\COL4_8.WAV",
+ "AUDIO\\COL4_9.WAV",
+ "AUDIO\\COL4_10.WAV",
+ "AUDIO\\COL4_11.WAV",
+ "AUDIO\\COL4_12.WAV",
+ "AUDIO\\COL4_13.WAV",
+ "AUDIO\\COL4_14.WAV",
+ "AUDIO\\COL4_15.WAV",
+ "AUDIO\\COL4_16.WAV",
+ "AUDIO\\COL4_17.WAV",
+ "AUDIO\\COL4_18.WAV",
+ "AUDIO\\COL4_19.WAV",
+ "AUDIO\\COL4_20.WAV",
+ "AUDIO\\COL4_21.WAV",
+ "AUDIO\\COL4_22.WAV",
+ "AUDIO\\COL4_23.WAV",
+ "AUDIO\\COL4_24.WAV",
+ "AUDIO\\COL4_25.WAV",
+ "AUDIO\\COL4_26.WAV",
+ "AUDIO\\COL5_1.WAV",
+ "AUDIO\\COL5_2.WAV",
+ "AUDIO\\COL5_3.WAV",
+ "AUDIO\\COL5_4.WAV",
+ "AUDIO\\COL5_5.WAV",
+ "AUDIO\\COL5_6.WAV",
+ "AUDIO\\COL5_7.WAV",
+ "AUDIO\\COL5_8.WAV",
+ "AUDIO\\COL5_9.WAV",
+ "AUDIO\\COL5_10.WAV",
+ "AUDIO\\COL5_11.WAV",
+ "AUDIO\\COL5_12.WAV",
+ "AUDIO\\COL5_13.WAV",
+ "AUDIO\\COL5_14.WAV",
+ "AUDIO\\COL5_15.WAV",
+ "AUDIO\\COL5_16.WAV",
+ "AUDIO\\COL5_17.WAV",
+ "AUDIO\\COL5_18.WAV",
+ "AUDIO\\COL5_19.WAV",
+ "AUDIO\\COL5_20.WAV",
+ "AUDIO\\COL5_21.WAV",
+ "AUDIO\\COL5_22.WAV",
+ "AUDIO\\CUB1_1.WAV",
+ "AUDIO\\CUB1_2.WAV",
+ "AUDIO\\CUB1_3.WAV",
+ "AUDIO\\CUB1_4.WAV",
+ "AUDIO\\CUB1_5.WAV",
+ "AUDIO\\CUB1_6.WAV",
+ "AUDIO\\CUB1_7.WAV",
+ "AUDIO\\CUB1_8.WAV",
+ "AUDIO\\CUB1_9.WAV",
+ "AUDIO\\CUB1_10.WAV",
+ "AUDIO\\CUB2_1.WAV",
+ "AUDIO\\CUB2_2.WAV",
+ "AUDIO\\CUB2_3A.WAV",
+ "AUDIO\\CUB2_3B.WAV",
+ "AUDIO\\CUB2_3C.WAV",
+ "AUDIO\\CUB2_4A.WAV",
+ "AUDIO\\CUB2_5.WAV",
+ "AUDIO\\CUB2_6.WAV",
+ "AUDIO\\CUB2_7.WAV",
+ "AUDIO\\CUB2_8.WAV",
+ "AUDIO\\CUB2_9.WAV",
+ "AUDIO\\CUB2_10.WAV",
+ "AUDIO\\CUB2_11.WAV",
+ "AUDIO\\CUB3_1.WAV",
+ "AUDIO\\CUB3_2.WAV",
+ "AUDIO\\CUB3_3.WAV",
+ "AUDIO\\CUB3_4.WAV",
+ "AUDIO\\CUB4_1.WAV",
+ "AUDIO\\CUB4_2.WAV",
+ "AUDIO\\CUB4_3.WAV",
+ "AUDIO\\CUB4_4.WAV",
+ "AUDIO\\CUB4_5.WAV",
+ "AUDIO\\CUB4_5A.WAV",
+ "AUDIO\\CUB4_6.WAV",
+ "AUDIO\\CUB4_7.WAV",
+ "AUDIO\\CUB4_8.WAV",
+ "AUDIO\\CUB4_9.WAV",
+ "AUDIO\\CUB4_10.WAV",
+ "AUDIO\\CUB4_11.WAV",
+ "AUDIO\\CUB4_12.WAV",
+ "AUDIO\\CUB4_13.WAV",
+ "AUDIO\\CUB4_14.WAV",
+ "AUDIO\\CUB4_15.WAV",
+ "AUDIO\\CUB4_16.WAV",
+ "AUDIO\\GOLF_1.WAV",
+ "AUDIO\\GOLF_2.WAV",
+ "AUDIO\\GOLF_3.WAV",
+ "AUDIO\\BAR_1.WAV",
+ "AUDIO\\BAR_2.WAV",
+ "AUDIO\\BAR_3.WAV",
+ "AUDIO\\BAR_4.WAV",
+ "AUDIO\\BAR_5.WAV",
+ "AUDIO\\BAR_6.WAV",
+ "AUDIO\\BAR_7.WAV",
+ "AUDIO\\BAR_8.WAV",
+ "AUDIO\\STRIP_1.WAV",
+ "AUDIO\\STRIP_2.WAV",
+ "AUDIO\\STRIP_3.WAV",
+ "AUDIO\\STRIP_4.WAV",
+ "AUDIO\\STRIP_5.WAV",
+ "AUDIO\\STRIP_6.WAV",
+ "AUDIO\\STRIP_7.WAV",
+ "AUDIO\\STRIP_8.WAV",
+ "AUDIO\\STRIP_9.WAV",
+ "AUDIO\\STAR_1.WAV",
+ "AUDIO\\STAR_2.WAV",
+ "AUDIO\\STAR_3.WAV",
+ "AUDIO\\STAR_4.WAV",
+ "AUDIO\\FIN_1A.WAV",
+ "AUDIO\\FIN_1B.WAV",
+ "AUDIO\\FIN_1C.WAV",
+ "AUDIO\\FIN_2B.WAV",
+ "AUDIO\\FIN_2C.WAV",
+ "AUDIO\\FIN_3.WAV",
+ "AUDIO\\FIN_4.WAV",
+ "AUDIO\\FIN_5.WAV",
+ "AUDIO\\FIN_6.WAV",
+ "AUDIO\\FIN_10.WAV",
+ "AUDIO\\FIN_11A.WAV",
+ "AUDIO\\FIN_11B.WAV",
+ "AUDIO\\FIN_12A.WAV",
+ "AUDIO\\FIN_12B.WAV",
+ "AUDIO\\FIN_12C.WAV",
+ "AUDIO\\FIN_13.WAV",
+ "AUDIO\\FINKILL.WAV",
+ "AUDIO\\LAW1_1.WAV",
+ "AUDIO\\LAW1_2.WAV",
+ "AUDIO\\LAW1_3.WAV",
+ "AUDIO\\LAW1_4.WAV",
+ "AUDIO\\LAW1_5.WAV",
+ "AUDIO\\LAW1_6.WAV",
+ "AUDIO\\LAW1_7.WAV",
+ "AUDIO\\LAW1_8.WAV",
+ "AUDIO\\LAW1_9.WAV",
+ "AUDIO\\LAW1_10.WAV",
+ "AUDIO\\LAW2_1.WAV",
+ "AUDIO\\LAW2_2.WAV",
+ "AUDIO\\LAW2_3.WAV",
+ "AUDIO\\LAW2_4.WAV",
+ "AUDIO\\LAW2_5.WAV",
+ "AUDIO\\LAW2_6.WAV",
+ "AUDIO\\LAW2_7.WAV",
+ "AUDIO\\LAW2_8.WAV",
+ "AUDIO\\LAW2_9.WAV",
+ "AUDIO\\LAW2_10.WAV",
+ "AUDIO\\LAW3_1.WAV",
+ "AUDIO\\LAW3_2.WAV",
+ "AUDIO\\LAW3_3.WAV",
+ "AUDIO\\LAW3_4.WAV",
+ "AUDIO\\LAW3_5.WAV",
+ "AUDIO\\LAW3_6.WAV",
+ "AUDIO\\LAW3_10.WAV",
+ "AUDIO\\LAW3_11.WAV",
+ "AUDIO\\LAW3_12.WAV",
+ "AUDIO\\LAW3_13.WAV",
+ "AUDIO\\LAW3_14.WAV",
+ "AUDIO\\LAW3_16.WAV",
+ "AUDIO\\LAW3_17.WAV",
+ "AUDIO\\LAW3_18.WAV",
+ "AUDIO\\LAW3_19.WAV",
+ "AUDIO\\LAW3_20.WAV",
+ "AUDIO\\LAW3_21.WAV",
+ "AUDIO\\LAW3_22.WAV",
+ "AUDIO\\LAW3_23.WAV",
+ "AUDIO\\LAW3_24.WAV",
+ "AUDIO\\LAW3_25.WAV",
+ "AUDIO\\LAW4_1A.WAV",
+ "AUDIO\\LAW4_1B.WAV",
+ "AUDIO\\LAW4_1C.WAV",
+ "AUDIO\\LAW4_1D.WAV",
+ "AUDIO\\LAW4_10.WAV",
+ "AUDIO\\LAW4_3.WAV",
+ "AUDIO\\LAW4_4.WAV",
+ "AUDIO\\LAW4_5.WAV",
+ "AUDIO\\LAW4_6.WAV",
+ "AUDIO\\LAW4_7.WAV",
+ "AUDIO\\LAW4_8.WAV",
+ "AUDIO\\LAW4_9.WAV",
+ "AUDIO\\PHIL1_2.WAV",
+ "AUDIO\\PHIL1_3.WAV",
+ "AUDIO\\PHIL2_1.WAV",
+ "AUDIO\\PHIL2_2.WAV",
+ "AUDIO\\PHIL2_3.WAV",
+ "AUDIO\\PHIL2_4.WAV",
+ "AUDIO\\PHIL2_5.WAV",
+ "AUDIO\\PHIL2_6.WAV",
+ "AUDIO\\PHIL2_7.WAV",
+ "AUDIO\\PHIL2_8.WAV",
+ "AUDIO\\PHIL2_9.WAV",
+ "AUDIO\\PHIL210.WAV",
+ "AUDIO\\PHIL211.WAV",
+ "AUDIO\\PORN1_1.WAV",
+ "AUDIO\\PORN1_2.WAV",
+ "AUDIO\\PORN1_3.WAV",
+ "AUDIO\\PRN1_3A.WAV",
+ "AUDIO\\PORN1_4.WAV",
+ "AUDIO\\PORN1_5.WAV",
+ "AUDIO\\PORN1_6.WAV",
+ "AUDIO\\PORN1_7.WAV",
+ "AUDIO\\PORN1_8.WAV",
+ "AUDIO\\PORN1_9.WAV",
+ "AUDIO\\PRN1_10.WAV",
+ "AUDIO\\PRN1_11.WAV",
+ "AUDIO\\PRN1_12.WAV",
+ "AUDIO\\PRN1_13.WAV",
+ "AUDIO\\PRN1_14.WAV",
+ "AUDIO\\PRN1_15.WAV",
+ "AUDIO\\PRN1_16.WAV",
+ "AUDIO\\PRN1_17.WAV",
+ "AUDIO\\PRN1_18.WAV",
+ "AUDIO\\PRN1_19.WAV",
+ "AUDIO\\PRN1_20.WAV",
+ "AUDIO\\PRN1_21.WAV",
+ "AUDIO\\PORN3_1.WAV",
+ "AUDIO\\PORN3_2.WAV",
+ "AUDIO\\PORN3_3.WAV",
+ "AUDIO\\PORN3_4.WAV",
+ "AUDIO\\PSYCH_1.WAV",
+ "AUDIO\\PSYCH_2.WAV",
+ "AUDIO\\ROK2_01.WAV",
+ "AUDIO\\ROK3_1.WAV",
+ "AUDIO\\ROK3_2.WAV",
+ "AUDIO\\ROK3_3.WAV",
+ "AUDIO\\ROK3_4.WAV",
+ "AUDIO\\ROK3_5.WAV",
+ "AUDIO\\ROK3_6.WAV",
+ "AUDIO\\ROK3_7.WAV",
+ "AUDIO\\ROK3_8.WAV",
+ "AUDIO\\ROK3_9.WAV",
+ "AUDIO\\ROK3_10.WAV",
+ "AUDIO\\ROK3_11.WAV",
+ "AUDIO\\ROK3_12.WAV",
+ "AUDIO\\ROK3_13.WAV",
+ "AUDIO\\ROK3_14.WAV",
+ "AUDIO\\ROK3_15.WAV",
+ "AUDIO\\ROK3_16.WAV",
+ "AUDIO\\ROK3_17.WAV",
+ "AUDIO\\ROK3_18.WAV",
+ "AUDIO\\ROK3_19.WAV",
+ "AUDIO\\ROK3_20.WAV",
+ "AUDIO\\ROK3_21.WAV",
+ "AUDIO\\ROK3_22.WAV",
+ "AUDIO\\ROK3_23.WAV",
+ "AUDIO\\ROK3_24.WAV",
+ "AUDIO\\ROK3_25.WAV",
+ "AUDIO\\ROK3_26.WAV",
+ "AUDIO\\ROK3_27.WAV",
+ "AUDIO\\ROK3_62.WAV",
+ "AUDIO\\ROK3_63.WAV",
+ "AUDIO\\ROK3_64.WAV",
+ "AUDIO\\ROK3_65.WAV",
+ "AUDIO\\ROK3_66.WAV",
+ "AUDIO\\ROK3_67.WAV",
+ "AUDIO\\ROK3_68.WAV",
+ "AUDIO\\ROK3_69.WAV",
+ "AUDIO\\ROK3_70.WAV",
+ "AUDIO\\ROK3_71.WAV",
+ "AUDIO\\ROK3_73.WAV",
+ "AUDIO\\RESC_1.WAV",
+ "AUDIO\\RESC_2.WAV",
+ "AUDIO\\RESC_3.WAV",
+ "AUDIO\\RESC_4.WAV",
+ "AUDIO\\RESC_5.WAV",
+ "AUDIO\\RESC_6.WAV",
+ "AUDIO\\RESC_7.WAV",
+ "AUDIO\\RESC_8.WAV",
+ "AUDIO\\RESC_9.WAV",
+ "AUDIO\\RESC_10.WAV",
+ "AUDIO\\ROK1_1A.WAV",
+ "AUDIO\\ROK1_1B.WAV",
+ "AUDIO\\ROK1_5.WAV",
+ "AUDIO\\ROK1_6.WAV",
+ "AUDIO\\ROK1_7.WAV",
+ "AUDIO\\ROK1_8.WAV",
+ "AUDIO\\ROK1_9.WAV",
+ "AUDIO\\TAX1_1.WAV",
+ "AUDIO\\TAX1_2.WAV",
+ "AUDIO\\TAX1_3.WAV",
+ "AUDIO\\TAX1_4.WAV",
+ "AUDIO\\TAX1_5.WAV",
+ "AUDIO\\TAX2_1.WAV",
+ "AUDIO\\TAX2_2.WAV",
+ "AUDIO\\TAX2_3.WAV",
+ "AUDIO\\TAX2_4.WAV",
+ "AUDIO\\TAX2_5.WAV",
+ "AUDIO\\TAX2_6.WAV",
+ "AUDIO\\TAX2_7.WAV",
+ "AUDIO\\TAX3_1.WAV",
+ "AUDIO\\TAX3_2.WAV",
+ "AUDIO\\TAX3_3.WAV",
+ "AUDIO\\TAX3_4.WAV",
+ "AUDIO\\TAX3_5.WAV",
+ "AUDIO\\TEX1_1.WAV",
+ "AUDIO\\TEX1_2.WAV",
+ "AUDIO\\TEX1_3.WAV",
+ "AUDIO\\TEX1_4.WAV",
+ "AUDIO\\TEX1_5.WAV",
+ "AUDIO\\TEX1_6.WAV",
+ "AUDIO\\TEX2_1.WAV",
+ "AUDIO\\TEX3_1.WAV",
+ "AUDIO\\TEX3_2.WAV",
+ "AUDIO\\TEX3_3.WAV",
+ "AUDIO\\TEX3_4.WAV",
+ "AUDIO\\TEX3_5.WAV",
+ "AUDIO\\TEX3_6.WAV",
+ "AUDIO\\TEX3_7.WAV",
+ "AUDIO\\TEX3_8.WAV",
+ "AUDIO\\HAT_1A.WAV",
+ "AUDIO\\INTRO1.WAV",
+ "AUDIO\\INTRO2.WAV",
+ "AUDIO\\INTRO3.WAV",
+ "AUDIO\\INTRO4.WAV",
+ "AUDIO\\MOB_01A.WAV",
+ "AUDIO\\MOB_01B.WAV",
+ "AUDIO\\MOB_01C.WAV",
+ "AUDIO\\MOB_02A.WAV",
+ "AUDIO\\MOB_02B.WAV",
+ "AUDIO\\MOB_02C.WAV",
+ "AUDIO\\MOB_03A.WAV",
+ "AUDIO\\MOB_03B.WAV",
+ "AUDIO\\MOB_03C.WAV",
+ "AUDIO\\MOB_03D.WAV",
+ "AUDIO\\MOB_03E.WAV",
+ "AUDIO\\SHARK_1.WAV",
+ "AUDIO\\SHARK_2.WAV",
+ "AUDIO\\SHARK_3.WAV",
+ "AUDIO\\SHARK_4.WAV",
+ "AUDIO\\SHARK_5.WAV",
+ "AUDIO\\MOB_04A.WAV",
+ "AUDIO\\MOB_04B.WAV",
+ "AUDIO\\MOB_04C.WAV",
+ "AUDIO\\MOB_04D.WAV",
+ "AUDIO\\MOB_05A.WAV",
+ "AUDIO\\MOB_05B.WAV",
+ "AUDIO\\MOB_05C.WAV",
+ "AUDIO\\MOB_05D.WAV",
+ "AUDIO\\MOB_06A.WAV",
+ "AUDIO\\MOB_06B.WAV",
+ "AUDIO\\MOB_06C.WAV",
+ "AUDIO\\MOB_07A.WAV",
+ "AUDIO\\MOB_07B.WAV",
+ "AUDIO\\MOB_08A.WAV",
+ "AUDIO\\MOB_08B.WAV",
+ "AUDIO\\MOB_08C.WAV",
+ "AUDIO\\MOB_08D.WAV",
+ "AUDIO\\MOB_08E.WAV",
+ "AUDIO\\MOB_08F.WAV",
+ "AUDIO\\MOB_08G.WAV",
+ "AUDIO\\MOB_09A.WAV",
+ "AUDIO\\MOB_09B.WAV",
+ "AUDIO\\MOB_09C.WAV",
+ "AUDIO\\MOB_09D.WAV",
+ "AUDIO\\MOB_09E.WAV",
+ "AUDIO\\MOB_09F.WAV",
+ "AUDIO\\MOB_10A.WAV",
+ "AUDIO\\MOB_10B.WAV",
+ "AUDIO\\MOB_10C.WAV",
+ "AUDIO\\MOB_10D.WAV",
+ "AUDIO\\MOB_10E.WAV",
+ "AUDIO\\MOB_11A.WAV",
+ "AUDIO\\MOB_11B.WAV",
+ "AUDIO\\MOB_11C.WAV",
+ "AUDIO\\MOB_11D.WAV",
+ "AUDIO\\MOB_11E.WAV",
+ "AUDIO\\MOB_11F.WAV",
+ "AUDIO\\MOB_14A.WAV",
+ "AUDIO\\MOB_14B.WAV",
+ "AUDIO\\MOB_14C.WAV",
+ "AUDIO\\MOB_14D.WAV",
+ "AUDIO\\MOB_14E.WAV",
+ "AUDIO\\MOB_14F.WAV",
+ "AUDIO\\MOB_14G.WAV",
+ "AUDIO\\MOB_14H.WAV",
+ "AUDIO\\MOB_16A.WAV",
+ "AUDIO\\MOB_16B.WAV",
+ "AUDIO\\MOB_16C.WAV",
+ "AUDIO\\MOB_16D.WAV",
+ "AUDIO\\MOB_16E.WAV",
+ "AUDIO\\MOB_16F.WAV",
+ "AUDIO\\MOB_16G.WAV",
+ "AUDIO\\MOB_17A.WAV",
+ "AUDIO\\MOB_17B.WAV",
+ "AUDIO\\MOB_17C.WAV",
+ "AUDIO\\MOB_17D.WAV",
+ "AUDIO\\MOB_17E.WAV",
+ "AUDIO\\MOB_17G.WAV",
+ "AUDIO\\MOB_17H.WAV",
+ "AUDIO\\MOB_17I.WAV",
+ "AUDIO\\MOB_17J.WAV",
+ "AUDIO\\MOB_17K.WAV",
+ "AUDIO\\MOB_17L.WAV",
+ "AUDIO\\MOB_18A.WAV",
+ "AUDIO\\MOB_18B.WAV",
+ "AUDIO\\MOB_18C.WAV",
+ "AUDIO\\MOB_18D.WAV",
+ "AUDIO\\MOB_18E.WAV",
+ "AUDIO\\MOB_18F.WAV",
+ "AUDIO\\MOB_18G.WAV",
+ "AUDIO\\MOB_20A.WAV",
+ "AUDIO\\MOB_20B.WAV",
+ "AUDIO\\MOB_20C.WAV",
+ "AUDIO\\MOB_20D.WAV",
+ "AUDIO\\MOB_20E.WAV",
+ "AUDIO\\MOB_24A.WAV",
+ "AUDIO\\MOB_24B.WAV",
+ "AUDIO\\MOB_24C.WAV",
+ "AUDIO\\MOB_24D.WAV",
+ "AUDIO\\MOB_24E.WAV",
+ "AUDIO\\MOB_24F.WAV",
+ "AUDIO\\MOB_24G.WAV",
+ "AUDIO\\MOB_24H.WAV",
+ "AUDIO\\MOB_25A.WAV",
+ "AUDIO\\MOB_25B.WAV",
+ "AUDIO\\MOB_25C.WAV",
+ "AUDIO\\MOB_25D.WAV",
+ "AUDIO\\MOB_26A.WAV",
+ "AUDIO\\MOB_26B.WAV",
+ "AUDIO\\MOB_26C.WAV",
+ "AUDIO\\MOB_26D.WAV",
+ "AUDIO\\MOB_26E.WAV",
+ "AUDIO\\MOB_29A.WAV",
+ "AUDIO\\MOB_29B.WAV",
+ "AUDIO\\MOB_29C.WAV",
+ "AUDIO\\MOB_29D.WAV",
+ "AUDIO\\MOB_29E.WAV",
+ "AUDIO\\MOB_29F.WAV",
+ "AUDIO\\MOB_29G.WAV",
+ "AUDIO\\MOB_30A.WAV",
+ "AUDIO\\MOB_30B.WAV",
+ "AUDIO\\MOB_30C.WAV",
+ "AUDIO\\MOB_30D.WAV",
+ "AUDIO\\MOB_30E.WAV",
+ "AUDIO\\MOB_30F.WAV",
+ "AUDIO\\MOB_33A.WAV",
+ "AUDIO\\MOB_33B.WAV",
+ "AUDIO\\MOB_33C.WAV",
+ "AUDIO\\MOB_33D.WAV",
+ "AUDIO\\MOB_34A.WAV",
+ "AUDIO\\MOB_34B.WAV",
+ "AUDIO\\MOB_34C.WAV",
+ "AUDIO\\MOB_34D.WAV",
+ "AUDIO\\MOB_35A.WAV",
+ "AUDIO\\MOB_35B.WAV",
+ "AUDIO\\MOB_35C.WAV",
+ "AUDIO\\MOB_35D.WAV",
+ "AUDIO\\MOB_36A.WAV",
+ "AUDIO\\MOB_36B.WAV",
+ "AUDIO\\MOB_36C.WAV",
+ "AUDIO\\MOB_40A.WAV",
+ "AUDIO\\MOB_40B.WAV",
+ "AUDIO\\MOB_40C.WAV",
+ "AUDIO\\MOB_40D.WAV",
+ "AUDIO\\MOB_40E.WAV",
+ "AUDIO\\MOB_40F.WAV",
+ "AUDIO\\MOB_40G.WAV",
+ "AUDIO\\MOB_40H.WAV",
+ "AUDIO\\MOB_40I.WAV",
+ "AUDIO\\MOB_41A.WAV",
+ "AUDIO\\MOB_41B.WAV",
+ "AUDIO\\MOB_41C.WAV",
+ "AUDIO\\MOB_41D.WAV",
+ "AUDIO\\MOB_41E.WAV",
+ "AUDIO\\MOB_41F.WAV",
+ "AUDIO\\MOB_41G.WAV",
+ "AUDIO\\MOB_41H.WAV",
+ "AUDIO\\MOB_42A.WAV",
+ "AUDIO\\MOB_42B.WAV",
+ "AUDIO\\MOB_42C.WAV",
+ "AUDIO\\MOB_42D.WAV",
+ "AUDIO\\MOB_42E.WAV",
+ "AUDIO\\MOB_43A.WAV",
+ "AUDIO\\MOB_43B.WAV",
+ "AUDIO\\MOB_43C.WAV",
+ "AUDIO\\MOB_43D.WAV",
+ "AUDIO\\MOB_43E.WAV",
+ "AUDIO\\MOB_43F.WAV",
+ "AUDIO\\MOB_43G.WAV",
+ "AUDIO\\MOB_43H.WAV",
+ "AUDIO\\MOB_45A.WAV",
+ "AUDIO\\MOB_45B.WAV",
+ "AUDIO\\MOB_45C.WAV",
+ "AUDIO\\MOB_45D.WAV",
+ "AUDIO\\MOB_45E.WAV",
+ "AUDIO\\MOB_45F.WAV",
+ "AUDIO\\MOB_45G.WAV",
+ "AUDIO\\MOB_45H.WAV",
+ "AUDIO\\MOB_45I.WAV",
+ "AUDIO\\MOB_45J.WAV",
+ "AUDIO\\MOB_45K.WAV",
+ "AUDIO\\MOB_45L.WAV",
+ "AUDIO\\MOB_45M.WAV",
+ "AUDIO\\MOB_45N.WAV",
+ "AUDIO\\MOB_46A.WAV",
+ "AUDIO\\MOB_46B.WAV",
+ "AUDIO\\MOB_46C.WAV",
+ "AUDIO\\MOB_46D.WAV",
+ "AUDIO\\MOB_46E.WAV",
+ "AUDIO\\MOB_46F.WAV",
+ "AUDIO\\MOB_46G.WAV",
+ "AUDIO\\MOB_46H.WAV",
+ "AUDIO\\MOB_47A.WAV",
+ "AUDIO\\MOB_52A.WAV",
+ "AUDIO\\MOB_52B.WAV",
+ "AUDIO\\MOB_52C.WAV",
+ "AUDIO\\MOB_52D.WAV",
+ "AUDIO\\MOB_52E.WAV",
+ "AUDIO\\MOB_52F.WAV",
+ "AUDIO\\MOB_52G.WAV",
+ "AUDIO\\MOB_52H.WAV",
+ "AUDIO\\MOB_54A.WAV",
+ "AUDIO\\MOB_54B.WAV",
+ "AUDIO\\MOB_54C.WAV",
+ "AUDIO\\MOB_54D.WAV",
+ "AUDIO\\MOB_54E.WAV",
+ "AUDIO\\MOB_55A.WAV",
+ "AUDIO\\MOB_55B.WAV",
+ "AUDIO\\MOB_55C.WAV",
+ "AUDIO\\MOB_55D.WAV",
+ "AUDIO\\MOB_55E.WAV",
+ "AUDIO\\MOB_55F.WAV",
+ "AUDIO\\MOB_56A.WAV",
+ "AUDIO\\MOB_56B.WAV",
+ "AUDIO\\MOB_56C.WAV",
+ "AUDIO\\MOB_56D.WAV",
+ "AUDIO\\MOB_56E.WAV",
+ "AUDIO\\MOB_56F.WAV",
+ "AUDIO\\MOB_57A.WAV",
+ "AUDIO\\MOB_57B.WAV",
+ "AUDIO\\MOB_57C.WAV",
+ "AUDIO\\MOB_57D.WAV",
+ "AUDIO\\MOB_57E.WAV",
+ "AUDIO\\MOB_58A.WAV",
+ "AUDIO\\MOB_58B.WAV",
+ "AUDIO\\MOB_58C.WAV",
+ "AUDIO\\MOB_58D.WAV",
+ "AUDIO\\MOB_58E.WAV",
+ "AUDIO\\MOB_58F.WAV",
+ "AUDIO\\MOB_58G.WAV",
+ "AUDIO\\MOB_61A.WAV",
+ "AUDIO\\MOB_61B.WAV",
+ "AUDIO\\MOB_62A.WAV",
+ "AUDIO\\MOB_62B.WAV",
+ "AUDIO\\MOB_62C.WAV",
+ "AUDIO\\MOB_62D.WAV",
+ "AUDIO\\MOB_63A.WAV",
+ "AUDIO\\MOB_63B.WAV",
+ "AUDIO\\MOB_63C.WAV",
+ "AUDIO\\MOB_63D.WAV",
+ "AUDIO\\MOB_63E.WAV",
+ "AUDIO\\MOB_63F.WAV",
+ "AUDIO\\MOB_63G.WAV",
+ "AUDIO\\MOB_63H.WAV",
+ "AUDIO\\MOB_63I.WAV",
+ "AUDIO\\MOB_63J.WAV",
+ "AUDIO\\MOB_66A.WAV",
+ "AUDIO\\MOB_66B.WAV",
+ "AUDIO\\MOB_68A.WAV",
+ "AUDIO\\MOB_68B.WAV",
+ "AUDIO\\MOB_68C.WAV",
+ "AUDIO\\MOB_68D.WAV",
+ "AUDIO\\MOB_70A.WAV",
+ "AUDIO\\MOB_70B.WAV",
+ "AUDIO\\MOB_71A.WAV",
+ "AUDIO\\MOB_71B.WAV",
+ "AUDIO\\MOB_71C.WAV",
+ "AUDIO\\MOB_71D.WAV",
+ "AUDIO\\MOB_71E.WAV",
+ "AUDIO\\MOB_71F.WAV",
+ "AUDIO\\MOB_71G.WAV",
+ "AUDIO\\MOB_71H.WAV",
+ "AUDIO\\MOB_71I.WAV",
+ "AUDIO\\MOB_71J.WAV",
+ "AUDIO\\MOB_71K.WAV",
+ "AUDIO\\MOB_71L.WAV",
+ "AUDIO\\MOB_71M.WAV",
+ "AUDIO\\MOB_71N.WAV",
+ "AUDIO\\MOB_72A.WAV",
+ "AUDIO\\MOB_72B.WAV",
+ "AUDIO\\MOB_72C.WAV",
+ "AUDIO\\MOB_72D.WAV",
+ "AUDIO\\MOB_72E.WAV",
+ "AUDIO\\MOB_72F.WAV",
+ "AUDIO\\MOB_72G.WAV",
+ "AUDIO\\MOB_73A.WAV",
+ "AUDIO\\MOB_73C.WAV",
+ "AUDIO\\MOB_73D.WAV",
+ "AUDIO\\MOB_73F.WAV",
+ "AUDIO\\MOB_73G.WAV",
+ "AUDIO\\MOB_73I.WAV",
+ "AUDIO\\MOB_95A.WAV",
+ "AUDIO\\MOB_96A.WAV",
+ "AUDIO\\MOB_98A.WAV",
+ "AUDIO\\MOB_99A.WAV",
+ "AUDIO\\JOB1_1B.WAV",
+ "AUDIO\\JOB1_1C.WAV",
+ "AUDIO\\JOB1_1D.WAV",
+ "AUDIO\\JOB2_1B.WAV",
+ "AUDIO\\JOB2_2.WAV",
+ "AUDIO\\JOB2_3.WAV",
+ "AUDIO\\JOB2_4.WAV",
+ "AUDIO\\JOB2_5.WAV",
+ "AUDIO\\JOB2_6.WAV",
+ "AUDIO\\JOB2_7.WAV",
+ "AUDIO\\JOB2_8.WAV",
+ "AUDIO\\JOB2_9.WAV",
+ "AUDIO\\JOB3_1.WAV",
+ "AUDIO\\JOB3_2.WAV",
+ "AUDIO\\JOB3_3.WAV",
+ "AUDIO\\JOB4_1.WAV",
+ "AUDIO\\JOB4_2.WAV",
+ "AUDIO\\JOB4_3.WAV",
+ "AUDIO\\JOB5_1.WAV",
+ "AUDIO\\JOB5_2.WAV",
+ "AUDIO\\JOB5_3.WAV",
+ "AUDIO\\BJM1_20.WAV",
+ "AUDIO\\BJM1_4.WAV",
+ "AUDIO\\BJM1_5.WAV",
+ "AUDIO\\MERC_39.WAV",
+ "AUDIO\\MONO_1.WAV",
+ "AUDIO\\MONO_2.WAV",
+ "AUDIO\\MONO_3.WAV",
+ "AUDIO\\MONO_4.WAV",
+ "AUDIO\\MONO_5.WAV",
+ "AUDIO\\MONO_6.WAV",
+ "AUDIO\\MONO_7.WAV",
+ "AUDIO\\MONO_8.WAV",
+ "AUDIO\\MONO_9.WAV",
+ "AUDIO\\MONO10.WAV",
+ "AUDIO\\MONO11.WAV",
+ "AUDIO\\MONO12.WAV",
+ "AUDIO\\MONO13.WAV",
+ "AUDIO\\MONO14.WAV",
+ "AUDIO\\MONO15.WAV",
+ "AUDIO\\MONO16.WAV",
+ "AUDIO\\FUD_01.WAV",
+ "AUDIO\\FUD_02.WAV",
+ "AUDIO\\FUD_03.WAV",
+ "AUDIO\\FUD_04.WAV",
+ "AUDIO\\FUD_05.WAV",
+ "AUDIO\\FUD_06.WAV",
+ "AUDIO\\FUD_07.WAV",
+ "AUDIO\\FUD_08.WAV",
+ "AUDIO\\FUD_09.WAV",
+ "AUDIO\\FUD_10.WAV",
+ "AUDIO\\FUD_11.WAV",
+ "AUDIO\\FUD_12.WAV",
+ "AUDIO\\FUD_13.WAV",
+ "AUDIO\\FUD_14.WAV",
+ "AUDIO\\FUD_15.WAV",
+ "AUDIO\\FUD_16.WAV",
+ "AUDIO\\FUD_17.WAV",
+ "AUDIO\\FUD_18.WAV",
+ "AUDIO\\FUD_19.WAV",
+ "AUDIO\\FUD_20.WAV",
+ "AUDIO\\BURG_01.WAV",
+ "AUDIO\\BURG_02.WAV",
+ "AUDIO\\BURG_03.WAV",
+ "AUDIO\\BURG_04.WAV",
+ "AUDIO\\BURG_05.WAV",
+ "AUDIO\\BURG_06.WAV",
+ "AUDIO\\BURG_07.WAV",
+ "AUDIO\\BURG_08.WAV",
+ "AUDIO\\BURG_09.WAV",
+ "AUDIO\\BURG_10.WAV",
+ "AUDIO\\BURG_11.WAV",
+ "AUDIO\\BURG_12.WAV",
+ "AUDIO\\CRUST01.WAV",
+ "AUDIO\\CRUST02.WAV",
+ "AUDIO\\CRUST03.WAV",
+ "AUDIO\\CRUST04.WAV",
+ "AUDIO\\CRUST05.WAV",
+ "AUDIO\\CRUST06.WAV",
+ "AUDIO\\CRUST07.WAV",
+ "AUDIO\\CRUST08.WAV",
+ "AUDIO\\CRUST09.WAV",
+ "AUDIO\\BAND_01.WAV",
+ "AUDIO\\BAND_02.WAV",
+ "AUDIO\\BAND_03.WAV",
+ "AUDIO\\BAND_04.WAV",
+ "AUDIO\\BAND_05.WAV",
+ "AUDIO\\BAND_06.WAV",
+ "AUDIO\\BAND_07.WAV",
+ "AUDIO\\BAND_08.WAV",
+ "AUDIO\\SHAFT01.WAV",
+ "AUDIO\\SHAFT02.WAV",
+ "AUDIO\\SHAFT03.WAV",
+ "AUDIO\\SHAFT04.WAV",
+ "AUDIO\\SHAFT05.WAV",
+ "AUDIO\\SHAFT06.WAV",
+ "AUDIO\\SHAFT07.WAV",
+ "AUDIO\\SHAFT08.WAV",
+ "AUDIO\\PISS_01.WAV",
+ "AUDIO\\PISS_02.WAV",
+ "AUDIO\\PISS_03.WAV",
+ "AUDIO\\PISS_04.WAV",
+ "AUDIO\\PISS_05.WAV",
+ "AUDIO\\PISS_06.WAV",
+ "AUDIO\\PISS_07.WAV",
+ "AUDIO\\PISS_08.WAV",
+ "AUDIO\\PISS_09.WAV",
+ "AUDIO\\PISS_10.WAV",
+ "AUDIO\\PISS_11.WAV",
+ "AUDIO\\PISS_12.WAV",
+ "AUDIO\\PISS_13.WAV",
+ "AUDIO\\PISS_14.WAV",
+ "AUDIO\\PISS_15.WAV",
+ "AUDIO\\PISS_16.WAV",
+ "AUDIO\\PISS_17.WAV",
+ "AUDIO\\PISS_18.WAV",
+ "AUDIO\\PISS_19.WAV",
+ "AUDIO\\GIMME01.WAV",
+ "AUDIO\\GIMME02.WAV",
+ "AUDIO\\GIMME03.WAV",
+ "AUDIO\\GIMME04.WAV",
+ "AUDIO\\GIMME05.WAV",
+ "AUDIO\\GIMME06.WAV",
+ "AUDIO\\GIMME07.WAV",
+ "AUDIO\\GIMME08.WAV",
+ "AUDIO\\GIMME09.WAV",
+ "AUDIO\\GIMME10.WAV",
+ "AUDIO\\GIMME11.WAV",
+ "AUDIO\\GIMME12.WAV",
+ "AUDIO\\GIMME13.WAV",
+ "AUDIO\\GIMME14.WAV",
+ "AUDIO\\GIMME15.WAV",
+ "AUDIO\\BUST_01.WAV",
+ "AUDIO\\BUST_02.WAV",
+ "AUDIO\\BUST_03.WAV",
+ "AUDIO\\BUST_04.WAV",
+ "AUDIO\\BUST_05.WAV",
+ "AUDIO\\BUST_06.WAV",
+ "AUDIO\\BUST_07.WAV",
+ "AUDIO\\BUST_08.WAV",
+ "AUDIO\\BUST_09.WAV",
+ "AUDIO\\BUST_10.WAV",
+ "AUDIO\\BUST_11.WAV",
+ "AUDIO\\BUST_12.WAV",
+ "AUDIO\\BUST_13.WAV",
+ "AUDIO\\BUST_14.WAV",
+ "AUDIO\\BUST_15.WAV",
+ "AUDIO\\BUST_16.WAV",
+ "AUDIO\\BUST_17.WAV",
+ "AUDIO\\BUST_18.WAV",
+ "AUDIO\\BUST_19.WAV",
+ "AUDIO\\BUST_20.WAV",
+ "AUDIO\\BUST_21.WAV",
+ "AUDIO\\BUST_22.WAV",
+ "AUDIO\\BUST_23.WAV",
+ "AUDIO\\BUST_24.WAV",
+ "AUDIO\\BUST_25.WAV",
+ "AUDIO\\BUST_26.WAV",
+ "AUDIO\\BUST_27.WAV",
+ "AUDIO\\BUST_28.WAV",
};
#endif
static char StreamedNameTable[][25] =
{
- "AUDIO\\HEAD.WAV",
- "AUDIO\\CLASS.WAV",
- "AUDIO\\KJAH.WAV",
- "AUDIO\\RISE.WAV",
- "AUDIO\\LIPS.WAV",
- "AUDIO\\GAME.WAV",
- "AUDIO\\MSX.WAV",
- "AUDIO\\FLASH.WAV",
- "AUDIO\\CHAT.WAV",
- "AUDIO\\HEAD.WAV",
- "AUDIO\\POLICE.WAV",
- "AUDIO\\CITY.WAV",
- "AUDIO\\WATER.WAV",
- "AUDIO\\COMOPEN.WAV",
- "AUDIO\\SUBOPEN.WAV",
- "AUDIO\\JB.MP3",
- "AUDIO\\BET.MP3",
- "AUDIO\\L1_LG.MP3",
- "AUDIO\\L2_DSB.MP3",
- "AUDIO\\L3_DM.MP3",
- "AUDIO\\L4_PAP.MP3",
- "AUDIO\\L5_TFB.MP3",
- "AUDIO\\J0_DM2.MP3",
- "AUDIO\\J1_LFL.MP3",
- "AUDIO\\J2_KCL.MP3",
- "AUDIO\\J3_VH.MP3",
- "AUDIO\\J4_ETH.MP3",
- "AUDIO\\J5_DST.MP3",
- "AUDIO\\J6_TBJ.MP3",
- "AUDIO\\T1_TOL.MP3",
- "AUDIO\\T2_TPU.MP3",
- "AUDIO\\T3_MAS.MP3",
- "AUDIO\\T4_TAT.MP3",
- "AUDIO\\T5_BF.MP3",
- "AUDIO\\S0_MAS.MP3",
- "AUDIO\\S1_PF.MP3",
- "AUDIO\\S2_CTG.MP3",
- "AUDIO\\S3_RTC.MP3",
- "AUDIO\\S5_LRQ.MP3",
- "AUDIO\\S4_BDBA.MP3",
- "AUDIO\\S4_BDBB.MP3",
- "AUDIO\\S2_CTG2.MP3",
- "AUDIO\\S4_BDBD.MP3",
- "AUDIO\\S5_LRQB.MP3",
- "AUDIO\\S5_LRQC.MP3",
- "AUDIO\\A1_SSO.WAV",
- "AUDIO\\A2_PP.WAV",
- "AUDIO\\A3_SS.WAV",
- "AUDIO\\A4_PDR.WAV",
- "AUDIO\\A5_K2FT.WAV",
- "AUDIO\\K1_KBO.MP3",
- "AUDIO\\K2_GIS.MP3",
- "AUDIO\\K3_DS.MP3",
- "AUDIO\\K4_SHI.MP3",
- "AUDIO\\K5_SD.MP3",
- "AUDIO\\R0_PDR2.MP3",
- "AUDIO\\R1_SW.MP3",
- "AUDIO\\R2_AP.MP3",
- "AUDIO\\R3_ED.MP3",
- "AUDIO\\R4_GF.MP3",
- "AUDIO\\R5_PB.MP3",
- "AUDIO\\R6_MM.MP3",
- "AUDIO\\D1_STOG.MP3",
- "AUDIO\\D2_KK.MP3",
- "AUDIO\\D3_ADO.MP3",
- "AUDIO\\D5_ES.MP3",
- "AUDIO\\D7_MLD.MP3",
- "AUDIO\\D4_GTA.MP3",
- "AUDIO\\D4_GTA2.MP3",
- "AUDIO\\D6_STS.MP3",
- "AUDIO\\A6_BAIT.WAV",
- "AUDIO\\A7_ETG.WAV",
- "AUDIO\\A8_PS.WAV",
- "AUDIO\\A9_ASD.WAV",
- "AUDIO\\K4_SHI2.MP3",
- "AUDIO\\C1_TEX.MP3",
- "AUDIO\\EL_PH1.MP3",
- "AUDIO\\EL_PH2.MP3",
- "AUDIO\\EL_PH3.MP3",
- "AUDIO\\EL_PH4.MP3",
- "AUDIO\\YD_PH1.MP3",
- "AUDIO\\YD_PH2.MP3",
- "AUDIO\\YD_PH3.MP3",
- "AUDIO\\YD_PH4.MP3",
- "AUDIO\\HD_PH1.MP3",
- "AUDIO\\HD_PH2.MP3",
- "AUDIO\\HD_PH3.MP3",
- "AUDIO\\HD_PH4.MP3",
- "AUDIO\\HD_PH5.MP3",
- "AUDIO\\MT_PH1.MP3",
- "AUDIO\\MT_PH2.MP3",
- "AUDIO\\MT_PH3.MP3",
- "AUDIO\\MT_PH4.MP3",
- "AUDIO\\MISCOM.WAV",
- "AUDIO\\END.MP3",
- "AUDIO\\lib_a1.WAV",
- "AUDIO\\lib_a2.WAV",
- "AUDIO\\lib_a.WAV",
- "AUDIO\\lib_b.WAV",
- "AUDIO\\lib_c.WAV",
- "AUDIO\\lib_d.WAV",
- "AUDIO\\l2_a.WAV",
- "AUDIO\\j4t_1.WAV",
- "AUDIO\\j4t_2.WAV",
- "AUDIO\\j4t_3.WAV",
- "AUDIO\\j4t_4.WAV",
- "AUDIO\\j4_a.WAV",
- "AUDIO\\j4_b.WAV",
- "AUDIO\\j4_c.WAV",
- "AUDIO\\j4_d.WAV",
- "AUDIO\\j4_e.WAV",
- "AUDIO\\j4_f.WAV",
- "AUDIO\\j6_1.WAV",
- "AUDIO\\j6_a.WAV",
- "AUDIO\\j6_b.WAV",
- "AUDIO\\j6_c.WAV",
- "AUDIO\\j6_d.WAV",
- "AUDIO\\t4_a.WAV",
- "AUDIO\\s1_a.WAV",
- "AUDIO\\s1_a1.WAV",
- "AUDIO\\s1_b.WAV",
- "AUDIO\\s1_c.WAV",
- "AUDIO\\s1_c1.WAV",
- "AUDIO\\s1_d.WAV",
- "AUDIO\\s1_e.WAV",
- "AUDIO\\s1_f.WAV",
- "AUDIO\\s1_g.WAV",
- "AUDIO\\s1_h.WAV",
- "AUDIO\\s1_i.WAV",
- "AUDIO\\s1_j.WAV",
- "AUDIO\\s1_k.WAV",
- "AUDIO\\s1_l.WAV",
- "AUDIO\\s3_a.WAV",
- "AUDIO\\s3_b.WAV",
- "AUDIO\\el3_a.WAV",
- "AUDIO\\mf1_a.WAV",
- "AUDIO\\mf2_a.WAV",
- "AUDIO\\mf3_a.WAV",
- "AUDIO\\mf3_b.WAV",
- "AUDIO\\mf3_b1.WAV",
- "AUDIO\\mf3_c.WAV",
- "AUDIO\\mf4_a.WAV",
- "AUDIO\\mf4_b.WAV",
- "AUDIO\\mf4_c.WAV",
- "AUDIO\\a1_a.WAV",
- "AUDIO\\a3_a.WAV",
- "AUDIO\\a5_a.WAV",
- "AUDIO\\a4_a.WAV",
- "AUDIO\\a4_b.WAV",
- "AUDIO\\a4_c.WAV",
- "AUDIO\\a4_d.WAV",
- "AUDIO\\k1_a.WAV",
- "AUDIO\\k3_a.WAV",
- "AUDIO\\r1_a.WAV",
- "AUDIO\\r2_a.WAV",
- "AUDIO\\r2_b.WAV",
- "AUDIO\\r2_c.WAV",
- "AUDIO\\r2_d.WAV",
- "AUDIO\\r2_e.WAV",
- "AUDIO\\r2_f.WAV",
- "AUDIO\\r2_g.WAV",
- "AUDIO\\r2_h.WAV",
- "AUDIO\\r5_a.WAV",
- "AUDIO\\r6_a.WAV",
- "AUDIO\\r6_a1.WAV",
- "AUDIO\\r6_b.WAV",
- "AUDIO\\lo2_a.WAV",
- "AUDIO\\lo6_a.WAV",
- "AUDIO\\yd2_a.WAV",
- "AUDIO\\yd2_b.WAV",
- "AUDIO\\yd2_c.WAV",
- "AUDIO\\yd2_c1.WAV",
- "AUDIO\\yd2_d.WAV",
- "AUDIO\\yd2_e.WAV",
- "AUDIO\\yd2_f.WAV",
- "AUDIO\\yd2_g.WAV",
- "AUDIO\\yd2_h.WAV",
- "AUDIO\\yd2_ass.WAV",
- "AUDIO\\yd2_ok.WAV",
- "AUDIO\\h5_a.WAV",
- "AUDIO\\h5_b.WAV",
- "AUDIO\\h5_c.WAV",
- "AUDIO\\ammu_a.WAV",
- "AUDIO\\ammu_b.WAV",
- "AUDIO\\ammu_c.WAV",
- "AUDIO\\door_1.WAV",
- "AUDIO\\door_2.WAV",
- "AUDIO\\door_3.WAV",
- "AUDIO\\door_4.WAV",
- "AUDIO\\door_5.WAV",
- "AUDIO\\door_6.WAV",
- "AUDIO\\t3_a.WAV",
- "AUDIO\\t3_b.WAV",
- "AUDIO\\t3_c.WAV",
- "AUDIO\\k1_b.WAV",
- "AUDIO\\cat1.WAV"
-};
-#endif \ No newline at end of file
+ "AUDIO\\WILD.ADF",
+ "AUDIO\\FLASH.ADF",
+ "AUDIO\\KCHAT.ADF",
+ "AUDIO\\FEVER.ADF",
+ "AUDIO\\VROCK.ADF",
+ "AUDIO\\VCPR.ADF",
+ "AUDIO\\ESPANT.ADF",
+ "AUDIO\\EMOTION.ADF",
+ "AUDIO\\WAVE.ADF",
+ "AUDIO\\MISCOM.MP3",
+ "AUDIO\\CITY.MP3",
+ "AUDIO\\WATER.MP3",
+ "AUDIO\\BEACHAMB.MP3",
+ "AUDIO\\HCITY.MP3",
+ "AUDIO\\HWATER.MP3",
+ "AUDIO\\HBEACH.MP3",
+ "AUDIO\\MALLAMB.MP3",
+ "AUDIO\\STRIP.MP3",
+ "AUDIO\\MALIBU.MP3",
+ "AUDIO\\HOTEL.MP3",
+ "AUDIO\\DIRTRING.MP3",
+ "AUDIO\\LAW4RIOT.MP3",
+ "AUDIO\\AMBSIL.MP3",
+ "AUDIO\\POLICE.MP3",
+ "AUDIO\\TAXI.MP3",
+ "AUDIO\\BCLOSED.MP3",
+ "AUDIO\\BOPEN.MP3",
+ "AUDIO\\ASS_1.MP3",
+ "AUDIO\\ASS_2.MP3",
+ "AUDIO\\BANK_1.MP3",
+ "AUDIO\\BANK_2A.MP3",
+ "AUDIO\\BANK_2B.MP3",
+ "AUDIO\\BANK_3A.MP3",
+ "AUDIO\\BANK_3B.MP3",
+ "AUDIO\\BANK_4.MP3",
+ "AUDIO\\BIKE_1.MP3",
+ "AUDIO\\BIKE_2.MP3",
+ "AUDIO\\BIKE_3.MP3",
+ "AUDIO\\BUD_1.MP3",
+ "AUDIO\\BUD_2.MP3",
+ "AUDIO\\BUD_3.MP3",
+ "AUDIO\\CAP_1.MP3",
+ "AUDIO\\CAR_1.MP3",
+ "AUDIO\\CNT_1A.MP3",
+ "AUDIO\\CNT_1B.MP3",
+ "AUDIO\\CNT_2.MP3",
+ "AUDIO\\COK_1.MP3",
+ "AUDIO\\COK_2A.MP3",
+ "AUDIO\\COK_2B.MP3",
+ "AUDIO\\COK_3.MP3",
+ "AUDIO\\COK_4A.MP3",
+ "AUDIO\\COK_4A2.MP3",
+ "AUDIO\\COK_4B.MP3",
+ "AUDIO\\COL_1.MP3",
+ "AUDIO\\COL_2.MP3",
+ "AUDIO\\COL_3A.MP3",
+ "AUDIO\\COL_4A.MP3",
+ "AUDIO\\COL_5A.MP3",
+ "AUDIO\\COL_5B.MP3",
+ "AUDIO\\CUB_1.MP3",
+ "AUDIO\\CUB_2.MP3",
+ "AUDIO\\CUB_3.MP3",
+ "AUDIO\\CUB_4.MP3",
+ "AUDIO\\DRUG_1.MP3",
+ "AUDIO\\FIN.MP3",
+ "AUDIO\\FIN2.MP3",
+ "AUDIO\\FINALE.MP3",
+ "AUDIO\\HAT_1.MP3",
+ "AUDIO\\HAT_2.MP3",
+ "AUDIO\\HAT_3.MP3",
+ "AUDIO\\ICE_1.MP3",
+ "AUDIO\\INT_A.MP3",
+ "AUDIO\\INT_B.MP3",
+ "AUDIO\\INT_D.MP3",
+ "AUDIO\\INT_M.MP3",
+ "AUDIO\\LAW_1A.MP3",
+ "AUDIO\\LAW_1B.MP3",
+ "AUDIO\\LAW_2A.MP3",
+ "AUDIO\\LAW_2B.MP3",
+ "AUDIO\\LAW_2C.MP3",
+ "AUDIO\\LAW_3.MP3",
+ "AUDIO\\LAW_4.MP3",
+ "AUDIO\\PHIL_1.MP3",
+ "AUDIO\\PHIL_2.MP3",
+ "AUDIO\\PORN_1.MP3",
+ "AUDIO\\PORN_2.MP3",
+ "AUDIO\\PORN_3.MP3",
+ "AUDIO\\PORN_4.MP3",
+ "AUDIO\\RESC_1A.MP3",
+ "AUDIO\\ROK_1.MP3",
+ "AUDIO\\ROK_2.MP3",
+ "AUDIO\\ROK_3A.MP3",
+ "AUDIO\\STRIPA.MP3",
+ "AUDIO\\TAX_1.MP3",
+ "AUDIO\\TEX_1.MP3",
+ "AUDIO\\TEX_2.MP3",
+ "AUDIO\\TEX_3.MP3",
+ "AUDIO\\GLIGHT.MP3",
+ "AUDIO\\FIST.MP3",
+ "AUDIO\\MISCOM.MP3",
+ "AUDIO\\MISCOM.MP3",
+ "AUDIO\\MISCOM.MP3",
+ "AUDIO\\MISCOM.MP3",
+ "AUDIO\\MOBR1.WAV",
+ "AUDIO\\PAGER.WAV",
+ "AUDIO\\CARREV.WAV",
+ "AUDIO\\BIKEREV.WAV",
+ "AUDIO\\LIFTOP.WAV",
+ "AUDIO\\LIFTCL.WAV",
+ "AUDIO\\LIFTRUN.WAV",
+ "AUDIO\\LIFTBEL.WAV",
+ "AUDIO\\INLIFT.WAV",
+ "AUDIO\\SFX_01.WAV",
+ "AUDIO\\SFX_02.WAV",
+ "AUDIO\\CAMERAL.WAV",
+ "AUDIO\\CAMERAR.WAV",
+ "AUDIO\\CHEER1.WAV",
+ "AUDIO\\CHEER2.WAV",
+ "AUDIO\\CHEER3.WAV",
+ "AUDIO\\CHEER4.WAV",
+ "AUDIO\\OOH1.WAV",
+ "AUDIO\\OOH2.WAV",
+ "AUDIO\\RACE1.WAV",
+ "AUDIO\\RACE2.WAV",
+ "AUDIO\\RACE3.WAV",
+ "AUDIO\\RACE4.WAV",
+ "AUDIO\\RACE5.WAV",
+ "AUDIO\\RACE6.WAV",
+ "AUDIO\\RACE7.WAV",
+ "AUDIO\\RACE8.WAV",
+ "AUDIO\\RACE9.WAV",
+ "AUDIO\\RACE10.WAV",
+ "AUDIO\\RACE11.WAV",
+ "AUDIO\\RACE12.WAV",
+ "AUDIO\\RACE13.WAV",
+ "AUDIO\\RACE14.WAV",
+ "AUDIO\\RACE15.WAV",
+ "AUDIO\\HOT1.WAV",
+ "AUDIO\\HOT2.WAV",
+ "AUDIO\\HOT3.WAV",
+ "AUDIO\\HOT4.WAV",
+ "AUDIO\\HOT5.WAV",
+ "AUDIO\\HOT6.WAV",
+ "AUDIO\\HOT7.WAV",
+ "AUDIO\\HOT8.WAV",
+ "AUDIO\\HOT9.WAV",
+ "AUDIO\\HOT10.WAV",
+ "AUDIO\\HOT11.WAV",
+ "AUDIO\\HOT12.WAV",
+ "AUDIO\\HOT13.WAV",
+ "AUDIO\\HOT14.WAV",
+ "AUDIO\\HOT15.WAV",
+ "AUDIO\\LANSTP1.WAV",
+ "AUDIO\\LANSTP2.WAV",
+ "AUDIO\\LANAMU1.WAV",
+ "AUDIO\\LANAMU2.WAV",
+ "AUDIO\\AIRHORNL.WAV",
+ "AUDIO\\AIRHORNR.WAV",
+ "AUDIO\\SNIPSCRL.WAV",
+ "AUDIO\\SNIPSHORT.WAV",
+ "AUDIO\\BLOWROOF.WAV",
+ "AUDIO\\ASS_1.WAV",
+ "AUDIO\\ASS_2.WAV",
+ "AUDIO\\ASS_3.WAV",
+ "AUDIO\\ASS_4.WAV",
+ "AUDIO\\ASS_5.WAV",
+ "AUDIO\\ASS_6.WAV",
+ "AUDIO\\ASS_7.WAV",
+ "AUDIO\\ASS_8.WAV",
+ "AUDIO\\ASS_9.WAV",
+ "AUDIO\\ASS_10.WAV",
+ "AUDIO\\ASS_11.WAV",
+ "AUDIO\\ASS_12.WAV",
+ "AUDIO\\ASS_13.WAV",
+ "AUDIO\\ASS_14.WAV",
+ "AUDIO\\BIKE1_1.WAV",
+ "AUDIO\\BIKE1_2.WAV",
+ "AUDIO\\BIKE1_3.WAV",
+ "AUDIO\\BNK1_1.WAV",
+ "AUDIO\\BNK1_2.WAV",
+ "AUDIO\\BNK1_3.WAV",
+ "AUDIO\\BNK1_4.WAV",
+ "AUDIO\\BNK1_5.WAV",
+ "AUDIO\\BNK1_6.WAV",
+ "AUDIO\\BNK1_7.WAV",
+ "AUDIO\\BNK1_8.WAV",
+ "AUDIO\\BNK1_10.WAV",
+ "AUDIO\\BNK1_11.WAV",
+ "AUDIO\\BNK1_12.WAV",
+ "AUDIO\\BNK1_13.WAV",
+ "AUDIO\\BNK1_14.WAV",
+ "AUDIO\\BNK2_1.WAV",
+ "AUDIO\\BNK2_2.WAV",
+ "AUDIO\\BNK2_3.WAV",
+ "AUDIO\\BNK2_4.WAV",
+ "AUDIO\\BNK2_5.WAV",
+ "AUDIO\\BNK2_6.WAV",
+ "AUDIO\\BNK2_7.WAV",
+ "AUDIO\\BNK2_8.WAV",
+ "AUDIO\\BNK2_9.WAV",
+ "AUDIO\\BNK3_1.WAV",
+ "AUDIO\\BNK3_2.WAV",
+ "AUDIO\\BNK3_3A.WAV",
+ "AUDIO\\BNK3_3B.WAV",
+ "AUDIO\\BNK3_3C.WAV",
+ "AUDIO\\BNK3_4A.WAV",
+ "AUDIO\\BNK3_4B.WAV",
+ "AUDIO\\BNK3_4C.WAV",
+ "AUDIO\\BNK4_1.WAV",
+ "AUDIO\\BNK4_2.WAV",
+ "AUDIO\\BNK4_3A.WAV",
+ "AUDIO\\BNK4_3B.WAV",
+ "AUDIO\\BNK4_3C.WAV",
+ "AUDIO\\BNK4_3D.WAV",
+ "AUDIO\\BNK4_3E.WAV",
+ "AUDIO\\BNK4_3F.WAV",
+ "AUDIO\\BNK4_3G.WAV",
+ "AUDIO\\BNK4_3H.WAV",
+ "AUDIO\\BNK4_3I.WAV",
+ "AUDIO\\BNK4_3J.WAV",
+ "AUDIO\\BNK4_3K.WAV",
+ "AUDIO\\BNK4_3M.WAV",
+ "AUDIO\\BNK4_3O.WAV",
+ "AUDIO\\BNK4_3P.WAV",
+ "AUDIO\\BNK4_3Q.WAV",
+ "AUDIO\\BNK4_3R.WAV",
+ "AUDIO\\BNK4_3S.WAV",
+ "AUDIO\\BNK4_3T.WAV",
+ "AUDIO\\BNK4_3U.WAV",
+ "AUDIO\\BNK4_3V.WAV",
+ "AUDIO\\BNK4_4A.WAV",
+ "AUDIO\\BNK4_4B.WAV",
+ "AUDIO\\BNK4_5.WAV",
+ "AUDIO\\BNK4_6.WAV",
+ "AUDIO\\BNK4_7.WAV",
+ "AUDIO\\BNK4_8.WAV",
+ "AUDIO\\BNK4_9.WAV",
+ "AUDIO\\BNK4_10.WAV",
+ "AUDIO\\BNK4_11.WAV",
+ "AUDIO\\BK4_12A.WAV",
+ "AUDIO\\BK4_12B.WAV",
+ "AUDIO\\BK4_12C.WAV",
+ "AUDIO\\BNK4_13.WAV",
+ "AUDIO\\BK4_14A.WAV",
+ "AUDIO\\BK4_14B.WAV",
+ "AUDIO\\BNK4_15.WAV",
+ "AUDIO\\BNK4_16.WAV",
+ "AUDIO\\BNK4_17.WAV",
+ "AUDIO\\BNK4_18.WAV",
+ "AUDIO\\BK4_19A.WAV",
+ "AUDIO\\BK4_19B.WAV",
+ "AUDIO\\BK4_20A.WAV",
+ "AUDIO\\BK4_20B.WAV",
+ "AUDIO\\BNK4_21.WAV",
+ "AUDIO\\BNK422A.WAV",
+ "AUDIO\\BNK422B.WAV",
+ "AUDIO\\BK4_23A.WAV",
+ "AUDIO\\BK4_23B.WAV",
+ "AUDIO\\BK4_23C.WAV",
+ "AUDIO\\BK4_23D.WAV",
+ "AUDIO\\BK4_24A.WAV",
+ "AUDIO\\BK4_24B.WAV",
+ "AUDIO\\BNK4_25.WAV",
+ "AUDIO\\BNK4_26.WAV",
+ "AUDIO\\BNK4_27.WAV",
+ "AUDIO\\BNK4_28.WAV",
+ "AUDIO\\BNK4_29.WAV",
+ "AUDIO\\BNK4_30.WAV",
+ "AUDIO\\BK4_31A.WAV",
+ "AUDIO\\BK4_31B.WAV",
+ "AUDIO\\BNK4_32.WAV",
+ "AUDIO\\BK4_34A.WAV",
+ "AUDIO\\BK4_34B.WAV",
+ "AUDIO\\BK4_35A.WAV",
+ "AUDIO\\BK4_35B.WAV",
+ "AUDIO\\BNK4_36.WAV",
+ "AUDIO\\BNK4_37.WAV",
+ "AUDIO\\BNK4_38.WAV",
+ "AUDIO\\BNK4_39.WAV",
+ "AUDIO\\BK4_40A.WAV",
+ "AUDIO\\BK4_40B.WAV",
+ "AUDIO\\BNK4_41.WAV",
+ "AUDIO\\BNK4_42.WAV",
+ "AUDIO\\BNK4_43.WAV",
+ "AUDIO\\BNK4_44.WAV",
+ "AUDIO\\BNK4_45.WAV",
+ "AUDIO\\BNK4_46.WAV",
+ "AUDIO\\BNK4_47.WAV",
+ "AUDIO\\BNK4_48.WAV",
+ "AUDIO\\BNK4_49.WAV",
+ "AUDIO\\BNK450A.WAV",
+ "AUDIO\\BNK450B.WAV",
+ "AUDIO\\BNK4_51.WAV",
+ "AUDIO\\BNK4_94.WAV",
+ "AUDIO\\BNK4_95.WAV",
+ "AUDIO\\BNK4_96.WAV",
+ "AUDIO\\BNK4_97.WAV",
+ "AUDIO\\BNK4_98.WAV",
+ "AUDIO\\BNK4_99.WAV",
+ "AUDIO\\BUD1_1.WAV",
+ "AUDIO\\BUD1_2.WAV",
+ "AUDIO\\BUD1_3.WAV",
+ "AUDIO\\BUD1_4.WAV",
+ "AUDIO\\BUD1_5.WAV",
+ "AUDIO\\BUD1_9.WAV",
+ "AUDIO\\BUD1_10.WAV",
+ "AUDIO\\BUD2_1.WAV",
+ "AUDIO\\BUD2_2.WAV",
+ "AUDIO\\BUD2_3.WAV",
+ "AUDIO\\BUD2_4.WAV",
+ "AUDIO\\BUD2_5.WAV",
+ "AUDIO\\BUD2_6.WAV",
+ "AUDIO\\BUD2_7.WAV",
+ "AUDIO\\BUD3_1.WAV",
+ "AUDIO\\BUD3_1A.WAV",
+ "AUDIO\\BUD3_1B.WAV",
+ "AUDIO\\BUD3_1C.WAV",
+ "AUDIO\\BUD3_2.WAV",
+ "AUDIO\\BUD3_3.WAV",
+ "AUDIO\\BUD3_4.WAV",
+ "AUDIO\\BUD3_5.WAV",
+ "AUDIO\\BUD3_6.WAV",
+ "AUDIO\\BUD3_7.WAV",
+ "AUDIO\\BUD3_8A.WAV",
+ "AUDIO\\BUD3_8B.WAV",
+ "AUDIO\\BUD3_8C.WAV",
+ "AUDIO\\BUD3_9A.WAV",
+ "AUDIO\\BUD3_9B.WAV",
+ "AUDIO\\BUD3_9C.WAV",
+ "AUDIO\\CAP1_2.WAV",
+ "AUDIO\\CAP1_3.WAV",
+ "AUDIO\\CAP1_4.WAV",
+ "AUDIO\\CAP1_5.WAV",
+ "AUDIO\\CAP1_6.WAV",
+ "AUDIO\\CAP1_7.WAV",
+ "AUDIO\\CAP1_8.WAV",
+ "AUDIO\\CAP1_9.WAV",
+ "AUDIO\\CAP1_10.WAV",
+ "AUDIO\\CAP1_11.WAV",
+ "AUDIO\\CAP1_12.WAV",
+ "AUDIO\\CNT1_1.WAV",
+ "AUDIO\\CNT1_2.WAV",
+ "AUDIO\\CNT1_3.WAV",
+ "AUDIO\\CNT1_4.WAV",
+ "AUDIO\\CNT1_5.WAV",
+ "AUDIO\\CNT2_1.WAV",
+ "AUDIO\\CNT2_2.WAV",
+ "AUDIO\\CNT2_3.WAV",
+ "AUDIO\\CNT2_4.WAV",
+ "AUDIO\\COK1_1.WAV",
+ "AUDIO\\COK1_2.WAV",
+ "AUDIO\\COK1_3.WAV",
+ "AUDIO\\COK1_4.WAV",
+ "AUDIO\\COK1_5.WAV",
+ "AUDIO\\COK1_6.WAV",
+ "AUDIO\\COK2_1.WAV",
+ "AUDIO\\COK2_2.WAV",
+ "AUDIO\\COK2_3.WAV",
+ "AUDIO\\COK2_4.WAV",
+ "AUDIO\\COK2_5.WAV",
+ "AUDIO\\COK2_6.WAV",
+ "AUDIO\\COK2_7A.WAV",
+ "AUDIO\\COK2_7B.WAV",
+ "AUDIO\\COK2_7C.WAV",
+ "AUDIO\\COK2_8A.WAV",
+ "AUDIO\\COK2_8B.WAV",
+ "AUDIO\\COK2_8C.WAV",
+ "AUDIO\\COK2_8D.WAV",
+ "AUDIO\\COK2_9.WAV",
+ "AUDIO\\COK210A.WAV",
+ "AUDIO\\COK210B.WAV",
+ "AUDIO\\COK210C.WAV",
+ "AUDIO\\COK212A.WAV",
+ "AUDIO\\COK212B.WAV",
+ "AUDIO\\COK2_13.WAV",
+ "AUDIO\\COK2_14.WAV",
+ "AUDIO\\COK2_15.WAV",
+ "AUDIO\\COK2_16.WAV",
+ "AUDIO\\COK2_20.WAV",
+ "AUDIO\\COK2_21.WAV",
+ "AUDIO\\COK2_2.WAV", // this is probably a typo of COK2_22
+ "AUDIO\\COK3_1.WAV",
+ "AUDIO\\COK3_2.WAV",
+ "AUDIO\\COK3_3.WAV",
+ "AUDIO\\COK3_4.WAV",
+ "AUDIO\\COK4_1.WAV",
+ "AUDIO\\COK4_2.WAV",
+ "AUDIO\\COK4_3.WAV",
+ "AUDIO\\COK4_4.WAV",
+ "AUDIO\\COK4_5.WAV",
+ "AUDIO\\COK4_6.WAV",
+ "AUDIO\\COK4_7.WAV",
+ "AUDIO\\COK4_8.WAV",
+ "AUDIO\\COK4_9.WAV",
+ "AUDIO\\COK4_9A.WAV",
+ "AUDIO\\COK4_10.WAV",
+ "AUDIO\\COK4_11.WAV",
+ "AUDIO\\COK4_12.WAV",
+ "AUDIO\\COK4_13.WAV",
+ "AUDIO\\COK4_14.WAV",
+ "AUDIO\\COK4_15.WAV",
+ "AUDIO\\COK4_16.WAV",
+ "AUDIO\\COK4_17.WAV",
+ "AUDIO\\COK4_18.WAV",
+ "AUDIO\\COK4_19.WAV",
+ "AUDIO\\COK4_20.WAV",
+ "AUDIO\\COK4_21.WAV",
+ "AUDIO\\COK4_22.WAV",
+ "AUDIO\\COK4_23.WAV",
+ "AUDIO\\COK4_24.WAV",
+ "AUDIO\\COK4_25.WAV",
+ "AUDIO\\COK4_26.WAV",
+ "AUDIO\\COK4_27.WAV",
+ "AUDIO\\COL1_1.WAV",
+ "AUDIO\\COL1_2.WAV",
+ "AUDIO\\COL1_3.WAV",
+ "AUDIO\\COL1_4.WAV",
+ "AUDIO\\COL1_5.WAV",
+ "AUDIO\\COL1_6.WAV",
+ "AUDIO\\COL1_7.WAV",
+ "AUDIO\\COL1_8.WAV",
+ "AUDIO\\COL2_1.WAV",
+ "AUDIO\\COL2_2.WAV",
+ "AUDIO\\COL2_3.WAV",
+ "AUDIO\\COL2_4.WAV",
+ "AUDIO\\COL2_5.WAV",
+ "AUDIO\\COL2_6A.WAV",
+ "AUDIO\\COL2_7.WAV",
+ "AUDIO\\COL2_8.WAV",
+ "AUDIO\\COL2_9.WAV",
+ "AUDIO\\COL2_10.WAV",
+ "AUDIO\\COL2_11.WAV",
+ "AUDIO\\COL2_12.WAV",
+ "AUDIO\\COL2_13.WAV",
+ "AUDIO\\COL2_14.WAV",
+ "AUDIO\\COL2_15.WAV",
+ "AUDIO\\COL2_16.WAV",
+ "AUDIO\\COL3_1.WAV",
+ "AUDIO\\COL3_2.WAV",
+ "AUDIO\\COL3_2A.WAV",
+ "AUDIO\\COL3_2B.WAV",
+ "AUDIO\\COL3_3.WAV",
+ "AUDIO\\COL3_4.WAV",
+ "AUDIO\\COL3_5.WAV",
+ "AUDIO\\COL3_6.WAV",
+ "AUDIO\\COL3_7.WAV",
+ "AUDIO\\COL3_8.WAV",
+ "AUDIO\\COL3_9.WAV",
+ "AUDIO\\COL3_10.WAV",
+ "AUDIO\\COL3_11.WAV",
+ "AUDIO\\COL3_12.WAV",
+ "AUDIO\\COL3_13.WAV",
+ "AUDIO\\COL3_14.WAV",
+ "AUDIO\\COL3_15.WAV",
+ "AUDIO\\COL3_16.WAV",
+ "AUDIO\\COL3_17.WAV",
+ "AUDIO\\COL3_18.WAV",
+ "AUDIO\\COL3_19.WAV",
+ "AUDIO\\COL3_20.WAV",
+ "AUDIO\\COL3_21.WAV",
+ "AUDIO\\COL3_23.WAV",
+ "AUDIO\\COL3_24.WAV",
+ "AUDIO\\COL3_25.WAV",
+ "AUDIO\\COL4_1.WAV",
+ "AUDIO\\COL4_2.WAV",
+ "AUDIO\\COL4_3.WAV",
+ "AUDIO\\COL4_4.WAV",
+ "AUDIO\\COL4_5.WAV",
+ "AUDIO\\COL4_6.WAV",
+ "AUDIO\\COL4_7.WAV",
+ "AUDIO\\COL4_8.WAV",
+ "AUDIO\\COL4_9.WAV",
+ "AUDIO\\COL4_10.WAV",
+ "AUDIO\\COL4_11.WAV",
+ "AUDIO\\COL4_12.WAV",
+ "AUDIO\\COL4_13.WAV",
+ "AUDIO\\COL4_14.WAV",
+ "AUDIO\\COL4_15.WAV",
+ "AUDIO\\COL4_16.WAV",
+ "AUDIO\\COL4_17.WAV",
+ "AUDIO\\COL4_18.WAV",
+ "AUDIO\\COL4_19.WAV",
+ "AUDIO\\COL4_20.WAV",
+ "AUDIO\\COL4_21.WAV",
+ "AUDIO\\COL4_22.WAV",
+ "AUDIO\\COL4_23.WAV",
+ "AUDIO\\COL4_24.WAV",
+ "AUDIO\\COL4_25.WAV",
+ "AUDIO\\COL4_26.WAV",
+ "AUDIO\\COL5_1.WAV",
+ "AUDIO\\COL5_2.WAV",
+ "AUDIO\\COL5_3.WAV",
+ "AUDIO\\COL5_4.WAV",
+ "AUDIO\\COL5_5.WAV",
+ "AUDIO\\COL5_6.WAV",
+ "AUDIO\\COL5_7.WAV",
+ "AUDIO\\COL5_8.WAV",
+ "AUDIO\\COL5_9.WAV",
+ "AUDIO\\COL5_10.WAV",
+ "AUDIO\\COL5_11.WAV",
+ "AUDIO\\COL5_12.WAV",
+ "AUDIO\\COL5_13.WAV",
+ "AUDIO\\COL5_14.WAV",
+ "AUDIO\\COL5_15.WAV",
+ "AUDIO\\COL5_16.WAV",
+ "AUDIO\\COL5_17.WAV",
+ "AUDIO\\COL5_18.WAV",
+ "AUDIO\\COL5_19.WAV",
+ "AUDIO\\COL5_20.WAV",
+ "AUDIO\\COL5_21.WAV",
+ "AUDIO\\COL5_22.WAV",
+ "AUDIO\\CUB1_1.WAV",
+ "AUDIO\\CUB1_2.WAV",
+ "AUDIO\\CUB1_3.WAV",
+ "AUDIO\\CUB1_4.WAV",
+ "AUDIO\\CUB1_5.WAV",
+ "AUDIO\\CUB1_6.WAV",
+ "AUDIO\\CUB1_7.WAV",
+ "AUDIO\\CUB1_8.WAV",
+ "AUDIO\\CUB1_9.WAV",
+ "AUDIO\\CUB1_10.WAV",
+ "AUDIO\\CUB2_1.WAV",
+ "AUDIO\\CUB2_2.WAV",
+ "AUDIO\\CUB2_3A.WAV",
+ "AUDIO\\CUB2_3B.WAV",
+ "AUDIO\\CUB2_3C.WAV",
+ "AUDIO\\CUB2_4A.WAV",
+ "AUDIO\\CUB2_5.WAV",
+ "AUDIO\\CUB2_6.WAV",
+ "AUDIO\\CUB2_7.WAV",
+ "AUDIO\\CUB2_8.WAV",
+ "AUDIO\\CUB2_9.WAV",
+ "AUDIO\\CUB2_10.WAV",
+ "AUDIO\\CUB2_11.WAV",
+ "AUDIO\\CUB3_1.WAV",
+ "AUDIO\\CUB3_2.WAV",
+ "AUDIO\\CUB3_3.WAV",
+ "AUDIO\\CUB3_4.WAV",
+ "AUDIO\\CUB4_1.WAV",
+ "AUDIO\\CUB4_2.WAV",
+ "AUDIO\\CUB4_3.WAV",
+ "AUDIO\\CUB4_4.WAV",
+ "AUDIO\\CUB4_5.WAV",
+ "AUDIO\\CUB4_5A.WAV",
+ "AUDIO\\CUB4_6.WAV",
+ "AUDIO\\CUB4_7.WAV",
+ "AUDIO\\CUB4_8.WAV",
+ "AUDIO\\CUB4_9.WAV",
+ "AUDIO\\CUB4_10.WAV",
+ "AUDIO\\CUB4_11.WAV",
+ "AUDIO\\CUB4_12.WAV",
+ "AUDIO\\CUB4_13.WAV",
+ "AUDIO\\CUB4_14.WAV",
+ "AUDIO\\CUB4_15.WAV",
+ "AUDIO\\CUB4_16.WAV",
+ "AUDIO\\GOLF_1.WAV",
+ "AUDIO\\GOLF_2.WAV",
+ "AUDIO\\GOLF_3.WAV",
+ "AUDIO\\BAR_1.WAV",
+ "AUDIO\\BAR_2.WAV",
+ "AUDIO\\BAR_3.WAV",
+ "AUDIO\\BAR_4.WAV",
+ "AUDIO\\BAR_5.WAV",
+ "AUDIO\\BAR_6.WAV",
+ "AUDIO\\BAR_7.WAV",
+ "AUDIO\\BAR_8.WAV",
+ "AUDIO\\STRIP_1.WAV",
+ "AUDIO\\STRIP_2.WAV",
+ "AUDIO\\STRIP_3.WAV",
+ "AUDIO\\STRIP_4.WAV",
+ "AUDIO\\STRIP_5.WAV",
+ "AUDIO\\STRIP_6.WAV",
+ "AUDIO\\STRIP_7.WAV",
+ "AUDIO\\STRIP_8.WAV",
+ "AUDIO\\STRIP_9.WAV",
+ "AUDIO\\STAR_1.WAV",
+ "AUDIO\\STAR_2.WAV",
+ "AUDIO\\STAR_3.WAV",
+ "AUDIO\\STAR_4.WAV",
+ "AUDIO\\FIN_1A.WAV",
+ "AUDIO\\FIN_1B.WAV",
+ "AUDIO\\FIN_1C.WAV",
+ "AUDIO\\FIN_2B.WAV",
+ "AUDIO\\FIN_2C.WAV",
+ "AUDIO\\FIN_3.WAV",
+ "AUDIO\\FIN_4.WAV",
+ "AUDIO\\FIN_5.WAV",
+ "AUDIO\\FIN_6.WAV",
+ "AUDIO\\FIN_10.WAV",
+ "AUDIO\\FIN_11A.WAV",
+ "AUDIO\\FIN_11B.WAV",
+ "AUDIO\\FIN_12A.WAV",
+ "AUDIO\\FIN_12B.WAV",
+ "AUDIO\\FIN_12C.WAV",
+ "AUDIO\\FIN_13.WAV",
+ "AUDIO\\FINKILL.WAV",
+ "AUDIO\\LAW1_1.WAV",
+ "AUDIO\\LAW1_2.WAV",
+ "AUDIO\\LAW1_3.WAV",
+ "AUDIO\\LAW1_4.WAV",
+ "AUDIO\\LAW1_5.WAV",
+ "AUDIO\\LAW1_6.WAV",
+ "AUDIO\\LAW1_7.WAV",
+ "AUDIO\\LAW1_8.WAV",
+ "AUDIO\\LAW1_9.WAV",
+ "AUDIO\\LAW1_10.WAV",
+ "AUDIO\\LAW2_1.WAV",
+ "AUDIO\\LAW2_2.WAV",
+ "AUDIO\\LAW2_3.WAV",
+ "AUDIO\\LAW2_4.WAV",
+ "AUDIO\\LAW2_5.WAV",
+ "AUDIO\\LAW2_6.WAV",
+ "AUDIO\\LAW2_7.WAV",
+ "AUDIO\\LAW2_8.WAV",
+ "AUDIO\\LAW2_9.WAV",
+ "AUDIO\\LAW2_10.WAV",
+ "AUDIO\\LAW3_1.WAV",
+ "AUDIO\\LAW3_2.WAV",
+ "AUDIO\\LAW3_3.WAV",
+ "AUDIO\\LAW3_4.WAV",
+ "AUDIO\\LAW3_5.WAV",
+ "AUDIO\\LAW3_6.WAV",
+ "AUDIO\\LAW3_10.WAV",
+ "AUDIO\\LAW3_11.WAV",
+ "AUDIO\\LAW3_12.WAV",
+ "AUDIO\\LAW3_13.WAV",
+ "AUDIO\\LAW3_14.WAV",
+ "AUDIO\\LAW3_16.WAV",
+ "AUDIO\\LAW3_17.WAV",
+ "AUDIO\\LAW3_18.WAV",
+ "AUDIO\\LAW3_19.WAV",
+ "AUDIO\\LAW3_20.WAV",
+ "AUDIO\\LAW3_21.WAV",
+ "AUDIO\\LAW3_22.WAV",
+ "AUDIO\\LAW3_23.WAV",
+ "AUDIO\\LAW3_24.WAV",
+ "AUDIO\\LAW3_25.WAV",
+ "AUDIO\\LAW4_1A.WAV",
+ "AUDIO\\LAW4_1B.WAV",
+ "AUDIO\\LAW4_1C.WAV",
+ "AUDIO\\LAW4_1D.WAV",
+ "AUDIO\\LAW4_10.WAV",
+ "AUDIO\\LAW4_3.WAV",
+ "AUDIO\\LAW4_4.WAV",
+ "AUDIO\\LAW4_5.WAV",
+ "AUDIO\\LAW4_6.WAV",
+ "AUDIO\\LAW4_7.WAV",
+ "AUDIO\\LAW4_8.WAV",
+ "AUDIO\\LAW4_9.WAV",
+ "AUDIO\\PHIL1_2.WAV",
+ "AUDIO\\PHIL1_3.WAV",
+ "AUDIO\\PHIL2_1.WAV",
+ "AUDIO\\PHIL2_2.WAV",
+ "AUDIO\\PHIL2_3.WAV",
+ "AUDIO\\PHIL2_4.WAV",
+ "AUDIO\\PHIL2_5.WAV",
+ "AUDIO\\PHIL2_6.WAV",
+ "AUDIO\\PHIL2_7.WAV",
+ "AUDIO\\PHIL2_8.WAV",
+ "AUDIO\\PHIL2_9.WAV",
+ "AUDIO\\PHIL210.WAV",
+ "AUDIO\\PHIL211.WAV",
+ "AUDIO\\PORN1_1.WAV",
+ "AUDIO\\PORN1_2.WAV",
+ "AUDIO\\PORN1_3.WAV",
+ "AUDIO\\PRN1_3A.WAV",
+ "AUDIO\\PORN1_4.WAV",
+ "AUDIO\\PORN1_5.WAV",
+ "AUDIO\\PORN1_6.WAV",
+ "AUDIO\\PORN1_7.WAV",
+ "AUDIO\\PORN1_8.WAV",
+ "AUDIO\\PORN1_9.WAV",
+ "AUDIO\\PRN1_10.WAV",
+ "AUDIO\\PRN1_11.WAV",
+ "AUDIO\\PRN1_12.WAV",
+ "AUDIO\\PRN1_13.WAV",
+ "AUDIO\\PRN1_14.WAV",
+ "AUDIO\\PRN1_15.WAV",
+ "AUDIO\\PRN1_16.WAV",
+ "AUDIO\\PRN1_17.WAV",
+ "AUDIO\\PRN1_18.WAV",
+ "AUDIO\\PRN1_19.WAV",
+ "AUDIO\\PRN1_20.WAV",
+ "AUDIO\\PRN1_21.WAV",
+ "AUDIO\\PORN3_1.WAV",
+ "AUDIO\\PORN3_2.WAV",
+ "AUDIO\\PORN3_3.WAV",
+ "AUDIO\\PORN3_4.WAV",
+ "AUDIO\\PSYCH_1.WAV",
+ "AUDIO\\PSYCH_2.WAV",
+ "AUDIO\\ROK2_01.WAV",
+ "AUDIO\\ROK3_1.WAV",
+ "AUDIO\\ROK3_2.WAV",
+ "AUDIO\\ROK3_3.WAV",
+ "AUDIO\\ROK3_4.WAV",
+ "AUDIO\\ROK3_5.WAV",
+ "AUDIO\\ROK3_6.WAV",
+ "AUDIO\\ROK3_7.WAV",
+ "AUDIO\\ROK3_8.WAV",
+ "AUDIO\\ROK3_9.WAV",
+ "AUDIO\\ROK3_10.WAV",
+ "AUDIO\\ROK3_11.WAV",
+ "AUDIO\\ROK3_12.WAV",
+ "AUDIO\\ROK3_13.WAV",
+ "AUDIO\\ROK3_14.WAV",
+ "AUDIO\\ROK3_15.WAV",
+ "AUDIO\\ROK3_16.WAV",
+ "AUDIO\\ROK3_17.WAV",
+ "AUDIO\\ROK3_18.WAV",
+ "AUDIO\\ROK3_19.WAV",
+ "AUDIO\\ROK3_20.WAV",
+ "AUDIO\\ROK3_21.WAV",
+ "AUDIO\\ROK3_22.WAV",
+ "AUDIO\\ROK3_23.WAV",
+ "AUDIO\\ROK3_24.WAV",
+ "AUDIO\\ROK3_25.WAV",
+ "AUDIO\\ROK3_26.WAV",
+ "AUDIO\\ROK3_27.WAV",
+ "AUDIO\\ROK3_62.WAV",
+ "AUDIO\\ROK3_63.WAV",
+ "AUDIO\\ROK3_64.WAV",
+ "AUDIO\\ROK3_65.WAV",
+ "AUDIO\\ROK3_66.WAV",
+ "AUDIO\\ROK3_67.WAV",
+ "AUDIO\\ROK3_68.WAV",
+ "AUDIO\\ROK3_69.WAV",
+ "AUDIO\\ROK3_70.WAV",
+ "AUDIO\\ROK3_71.WAV",
+ "AUDIO\\ROK3_73.WAV",
+ "AUDIO\\RESC_1.WAV",
+ "AUDIO\\RESC_2.WAV",
+ "AUDIO\\RESC_3.WAV",
+ "AUDIO\\RESC_4.WAV",
+ "AUDIO\\RESC_5.WAV",
+ "AUDIO\\RESC_6.WAV",
+ "AUDIO\\RESC_7.WAV",
+ "AUDIO\\RESC_8.WAV",
+ "AUDIO\\RESC_9.WAV",
+ "AUDIO\\RESC_10.WAV",
+ "AUDIO\\ROK1_1A.WAV",
+ "AUDIO\\ROK1_1B.WAV",
+ "AUDIO\\ROK1_5.WAV",
+ "AUDIO\\ROK1_6.WAV",
+ "AUDIO\\ROK1_7.WAV",
+ "AUDIO\\ROK1_8.WAV",
+ "AUDIO\\ROK1_9.WAV",
+ "AUDIO\\TAX1_1.WAV",
+ "AUDIO\\TAX1_2.WAV",
+ "AUDIO\\TAX1_3.WAV",
+ "AUDIO\\TAX1_4.WAV",
+ "AUDIO\\TAX1_5.WAV",
+ "AUDIO\\TAX2_1.WAV",
+ "AUDIO\\TAX2_2.WAV",
+ "AUDIO\\TAX2_3.WAV",
+ "AUDIO\\TAX2_4.WAV",
+ "AUDIO\\TAX2_5.WAV",
+ "AUDIO\\TAX2_6.WAV",
+ "AUDIO\\TAX2_7.WAV",
+ "AUDIO\\TAX3_1.WAV",
+ "AUDIO\\TAX3_2.WAV",
+ "AUDIO\\TAX3_3.WAV",
+ "AUDIO\\TAX3_4.WAV",
+ "AUDIO\\TAX3_5.WAV",
+ "AUDIO\\TEX1_1.WAV",
+ "AUDIO\\TEX1_2.WAV",
+ "AUDIO\\TEX1_3.WAV",
+ "AUDIO\\TEX1_4.WAV",
+ "AUDIO\\TEX1_5.WAV",
+ "AUDIO\\TEX1_6.WAV",
+ "AUDIO\\TEX2_1.WAV",
+ "AUDIO\\TEX3_1.WAV",
+ "AUDIO\\TEX3_2.WAV",
+ "AUDIO\\TEX3_3.WAV",
+ "AUDIO\\TEX3_4.WAV",
+ "AUDIO\\TEX3_5.WAV",
+ "AUDIO\\TEX3_6.WAV",
+ "AUDIO\\TEX3_7.WAV",
+ "AUDIO\\TEX3_8.WAV",
+ "AUDIO\\HAT_1A.WAV",
+ "AUDIO\\INTRO1.WAV",
+ "AUDIO\\INTRO2.WAV",
+ "AUDIO\\INTRO3.WAV",
+ "AUDIO\\INTRO4.WAV",
+ "AUDIO\\MOB_01A.WAV",
+ "AUDIO\\MOB_01B.WAV",
+ "AUDIO\\MOB_01C.WAV",
+ "AUDIO\\MOB_02A.WAV",
+ "AUDIO\\MOB_02B.WAV",
+ "AUDIO\\MOB_02C.WAV",
+ "AUDIO\\MOB_03A.WAV",
+ "AUDIO\\MOB_03B.WAV",
+ "AUDIO\\MOB_03C.WAV",
+ "AUDIO\\MOB_03D.WAV",
+ "AUDIO\\MOB_03E.WAV",
+ "AUDIO\\SHARK_1.WAV",
+ "AUDIO\\SHARK_2.WAV",
+ "AUDIO\\SHARK_3.WAV",
+ "AUDIO\\SHARK_4.WAV",
+ "AUDIO\\SHARK_5.WAV",
+ "AUDIO\\MOB_04A.WAV",
+ "AUDIO\\MOB_04B.WAV",
+ "AUDIO\\MOB_04C.WAV",
+ "AUDIO\\MOB_04D.WAV",
+ "AUDIO\\MOB_05A.WAV",
+ "AUDIO\\MOB_05B.WAV",
+ "AUDIO\\MOB_05C.WAV",
+ "AUDIO\\MOB_05D.WAV",
+ "AUDIO\\MOB_06A.WAV",
+ "AUDIO\\MOB_06B.WAV",
+ "AUDIO\\MOB_06C.WAV",
+ "AUDIO\\MOB_07A.WAV",
+ "AUDIO\\MOB_07B.WAV",
+ "AUDIO\\MOB_08A.WAV",
+ "AUDIO\\MOB_08B.WAV",
+ "AUDIO\\MOB_08C.WAV",
+ "AUDIO\\MOB_08D.WAV",
+ "AUDIO\\MOB_08E.WAV",
+ "AUDIO\\MOB_08F.WAV",
+ "AUDIO\\MOB_08G.WAV",
+ "AUDIO\\MOB_09A.WAV",
+ "AUDIO\\MOB_09B.WAV",
+ "AUDIO\\MOB_09C.WAV",
+ "AUDIO\\MOB_09D.WAV",
+ "AUDIO\\MOB_09E.WAV",
+ "AUDIO\\MOB_09F.WAV",
+ "AUDIO\\MOB_10A.WAV",
+ "AUDIO\\MOB_10B.WAV",
+ "AUDIO\\MOB_10C.WAV",
+ "AUDIO\\MOB_10D.WAV",
+ "AUDIO\\MOB_10E.WAV",
+ "AUDIO\\MOB_11A.WAV",
+ "AUDIO\\MOB_11B.WAV",
+ "AUDIO\\MOB_11C.WAV",
+ "AUDIO\\MOB_11D.WAV",
+ "AUDIO\\MOB_11E.WAV",
+ "AUDIO\\MOB_11F.WAV",
+ "AUDIO\\MOB_14A.WAV",
+ "AUDIO\\MOB_14B.WAV",
+ "AUDIO\\MOB_14C.WAV",
+ "AUDIO\\MOB_14D.WAV",
+ "AUDIO\\MOB_14E.WAV",
+ "AUDIO\\MOB_14F.WAV",
+ "AUDIO\\MOB_14G.WAV",
+ "AUDIO\\MOB_14H.WAV",
+ "AUDIO\\MOB_16A.WAV",
+ "AUDIO\\MOB_16B.WAV",
+ "AUDIO\\MOB_16C.WAV",
+ "AUDIO\\MOB_16D.WAV",
+ "AUDIO\\MOB_16E.WAV",
+ "AUDIO\\MOB_16F.WAV",
+ "AUDIO\\MOB_16G.WAV",
+ "AUDIO\\MOB_17A.WAV",
+ "AUDIO\\MOB_17B.WAV",
+ "AUDIO\\MOB_17C.WAV",
+ "AUDIO\\MOB_17D.WAV",
+ "AUDIO\\MOB_17E.WAV",
+ "AUDIO\\MOB_17G.WAV",
+ "AUDIO\\MOB_17H.WAV",
+ "AUDIO\\MOB_17I.WAV",
+ "AUDIO\\MOB_17J.WAV",
+ "AUDIO\\MOB_17K.WAV",
+ "AUDIO\\MOB_17L.WAV",
+ "AUDIO\\MOB_18A.WAV",
+ "AUDIO\\MOB_18B.WAV",
+ "AUDIO\\MOB_18C.WAV",
+ "AUDIO\\MOB_18D.WAV",
+ "AUDIO\\MOB_18E.WAV",
+ "AUDIO\\MOB_18F.WAV",
+ "AUDIO\\MOB_18G.WAV",
+ "AUDIO\\MOB_20A.WAV",
+ "AUDIO\\MOB_20B.WAV",
+ "AUDIO\\MOB_20C.WAV",
+ "AUDIO\\MOB_20D.WAV",
+ "AUDIO\\MOB_20E.WAV",
+ "AUDIO\\MOB_24A.WAV",
+ "AUDIO\\MOB_24B.WAV",
+ "AUDIO\\MOB_24C.WAV",
+ "AUDIO\\MOB_24D.WAV",
+ "AUDIO\\MOB_24E.WAV",
+ "AUDIO\\MOB_24F.WAV",
+ "AUDIO\\MOB_24G.WAV",
+ "AUDIO\\MOB_24H.WAV",
+ "AUDIO\\MOB_25A.WAV",
+ "AUDIO\\MOB_25B.WAV",
+ "AUDIO\\MOB_25C.WAV",
+ "AUDIO\\MOB_25D.WAV",
+ "AUDIO\\MOB_26A.WAV",
+ "AUDIO\\MOB_26B.WAV",
+ "AUDIO\\MOB_26C.WAV",
+ "AUDIO\\MOB_26D.WAV",
+ "AUDIO\\MOB_26E.WAV",
+ "AUDIO\\MOB_29A.WAV",
+ "AUDIO\\MOB_29B.WAV",
+ "AUDIO\\MOB_29C.WAV",
+ "AUDIO\\MOB_29D.WAV",
+ "AUDIO\\MOB_29E.WAV",
+ "AUDIO\\MOB_29F.WAV",
+ "AUDIO\\MOB_29G.WAV",
+ "AUDIO\\MOB_30A.WAV",
+ "AUDIO\\MOB_30B.WAV",
+ "AUDIO\\MOB_30C.WAV",
+ "AUDIO\\MOB_30D.WAV",
+ "AUDIO\\MOB_30E.WAV",
+ "AUDIO\\MOB_30F.WAV",
+ "AUDIO\\MOB_33A.WAV",
+ "AUDIO\\MOB_33B.WAV",
+ "AUDIO\\MOB_33C.WAV",
+ "AUDIO\\MOB_33D.WAV",
+ "AUDIO\\MOB_34A.WAV",
+ "AUDIO\\MOB_34B.WAV",
+ "AUDIO\\MOB_34C.WAV",
+ "AUDIO\\MOB_34D.WAV",
+ "AUDIO\\MOB_35A.WAV",
+ "AUDIO\\MOB_35B.WAV",
+ "AUDIO\\MOB_35C.WAV",
+ "AUDIO\\MOB_35D.WAV",
+ "AUDIO\\MOB_36A.WAV",
+ "AUDIO\\MOB_36B.WAV",
+ "AUDIO\\MOB_36C.WAV",
+ "AUDIO\\MOB_40A.WAV",
+ "AUDIO\\MOB_40B.WAV",
+ "AUDIO\\MOB_40C.WAV",
+ "AUDIO\\MOB_40D.WAV",
+ "AUDIO\\MOB_40E.WAV",
+ "AUDIO\\MOB_40F.WAV",
+ "AUDIO\\MOB_40G.WAV",
+ "AUDIO\\MOB_40H.WAV",
+ "AUDIO\\MOB_40I.WAV",
+ "AUDIO\\MOB_41A.WAV",
+ "AUDIO\\MOB_41B.WAV",
+ "AUDIO\\MOB_41C.WAV",
+ "AUDIO\\MOB_41D.WAV",
+ "AUDIO\\MOB_41E.WAV",
+ "AUDIO\\MOB_41F.WAV",
+ "AUDIO\\MOB_41G.WAV",
+ "AUDIO\\MOB_41H.WAV",
+ "AUDIO\\MOB_42A.WAV",
+ "AUDIO\\MOB_42B.WAV",
+ "AUDIO\\MOB_42C.WAV",
+ "AUDIO\\MOB_42D.WAV",
+ "AUDIO\\MOB_42E.WAV",
+ "AUDIO\\MOB_43A.WAV",
+ "AUDIO\\MOB_43B.WAV",
+ "AUDIO\\MOB_43C.WAV",
+ "AUDIO\\MOB_43D.WAV",
+ "AUDIO\\MOB_43E.WAV",
+ "AUDIO\\MOB_43F.WAV",
+ "AUDIO\\MOB_43G.WAV",
+ "AUDIO\\MOB_43H.WAV",
+ "AUDIO\\MOB_45A.WAV",
+ "AUDIO\\MOB_45B.WAV",
+ "AUDIO\\MOB_45C.WAV",
+ "AUDIO\\MOB_45D.WAV",
+ "AUDIO\\MOB_45E.WAV",
+ "AUDIO\\MOB_45F.WAV",
+ "AUDIO\\MOB_45G.WAV",
+ "AUDIO\\MOB_45H.WAV",
+ "AUDIO\\MOB_45I.WAV",
+ "AUDIO\\MOB_45J.WAV",
+ "AUDIO\\MOB_45K.WAV",
+ "AUDIO\\MOB_45L.WAV",
+ "AUDIO\\MOB_45M.WAV",
+ "AUDIO\\MOB_45N.WAV",
+ "AUDIO\\MOB_46A.WAV",
+ "AUDIO\\MOB_46B.WAV",
+ "AUDIO\\MOB_46C.WAV",
+ "AUDIO\\MOB_46D.WAV",
+ "AUDIO\\MOB_46E.WAV",
+ "AUDIO\\MOB_46F.WAV",
+ "AUDIO\\MOB_46G.WAV",
+ "AUDIO\\MOB_46H.WAV",
+ "AUDIO\\MOB_47A.WAV",
+ "AUDIO\\MOB_52A.WAV",
+ "AUDIO\\MOB_52B.WAV",
+ "AUDIO\\MOB_52C.WAV",
+ "AUDIO\\MOB_52D.WAV",
+ "AUDIO\\MOB_52E.WAV",
+ "AUDIO\\MOB_52F.WAV",
+ "AUDIO\\MOB_52G.WAV",
+ "AUDIO\\MOB_52H.WAV",
+ "AUDIO\\MOB_54A.WAV",
+ "AUDIO\\MOB_54B.WAV",
+ "AUDIO\\MOB_54C.WAV",
+ "AUDIO\\MOB_54D.WAV",
+ "AUDIO\\MOB_54E.WAV",
+ "AUDIO\\MOB_55A.WAV",
+ "AUDIO\\MOB_55B.WAV",
+ "AUDIO\\MOB_55C.WAV",
+ "AUDIO\\MOB_55D.WAV",
+ "AUDIO\\MOB_55E.WAV",
+ "AUDIO\\MOB_55F.WAV",
+ "AUDIO\\MOB_56A.WAV",
+ "AUDIO\\MOB_56B.WAV",
+ "AUDIO\\MOB_56C.WAV",
+ "AUDIO\\MOB_56D.WAV",
+ "AUDIO\\MOB_56E.WAV",
+ "AUDIO\\MOB_56F.WAV",
+ "AUDIO\\MOB_57A.WAV",
+ "AUDIO\\MOB_57B.WAV",
+ "AUDIO\\MOB_57C.WAV",
+ "AUDIO\\MOB_57D.WAV",
+ "AUDIO\\MOB_57E.WAV",
+ "AUDIO\\MOB_58A.WAV",
+ "AUDIO\\MOB_58B.WAV",
+ "AUDIO\\MOB_58C.WAV",
+ "AUDIO\\MOB_58D.WAV",
+ "AUDIO\\MOB_58E.WAV",
+ "AUDIO\\MOB_58F.WAV",
+ "AUDIO\\MOB_58G.WAV",
+ "AUDIO\\MOB_61A.WAV",
+ "AUDIO\\MOB_61B.WAV",
+ "AUDIO\\MOB_62A.WAV",
+ "AUDIO\\MOB_62B.WAV",
+ "AUDIO\\MOB_62C.WAV",
+ "AUDIO\\MOB_62D.WAV",
+ "AUDIO\\MOB_63A.WAV",
+ "AUDIO\\MOB_63B.WAV",
+ "AUDIO\\MOB_63C.WAV",
+ "AUDIO\\MOB_63D.WAV",
+ "AUDIO\\MOB_63E.WAV",
+ "AUDIO\\MOB_63F.WAV",
+ "AUDIO\\MOB_63G.WAV",
+ "AUDIO\\MOB_63H.WAV",
+ "AUDIO\\MOB_63I.WAV",
+ "AUDIO\\MOB_63J.WAV",
+ "AUDIO\\MOB_66A.WAV",
+ "AUDIO\\MOB_66B.WAV",
+ "AUDIO\\MOB_68A.WAV",
+ "AUDIO\\MOB_68B.WAV",
+ "AUDIO\\MOB_68C.WAV",
+ "AUDIO\\MOB_68D.WAV",
+ "AUDIO\\MOB_70A.WAV",
+ "AUDIO\\MOB_70B.WAV",
+ "AUDIO\\MOB_71A.WAV",
+ "AUDIO\\MOB_71B.WAV",
+ "AUDIO\\MOB_71C.WAV",
+ "AUDIO\\MOB_71D.WAV",
+ "AUDIO\\MOB_71E.WAV",
+ "AUDIO\\MOB_71F.WAV",
+ "AUDIO\\MOB_71G.WAV",
+ "AUDIO\\MOB_71H.WAV",
+ "AUDIO\\MOB_71I.WAV",
+ "AUDIO\\MOB_71J.WAV",
+ "AUDIO\\MOB_71K.WAV",
+ "AUDIO\\MOB_71L.WAV",
+ "AUDIO\\MOB_71M.WAV",
+ "AUDIO\\MOB_71N.WAV",
+ "AUDIO\\MOB_72A.WAV",
+ "AUDIO\\MOB_72B.WAV",
+ "AUDIO\\MOB_72C.WAV",
+ "AUDIO\\MOB_72D.WAV",
+ "AUDIO\\MOB_72E.WAV",
+ "AUDIO\\MOB_72F.WAV",
+ "AUDIO\\MOB_72G.WAV",
+ "AUDIO\\MOB_73A.WAV",
+ "AUDIO\\MOB_73C.WAV",
+ "AUDIO\\MOB_73D.WAV",
+ "AUDIO\\MOB_73F.WAV",
+ "AUDIO\\MOB_73G.WAV",
+ "AUDIO\\MOB_73I.WAV",
+ "AUDIO\\MOB_95A.WAV",
+ "AUDIO\\MOB_96A.WAV",
+ "AUDIO\\MOB_98A.WAV",
+ "AUDIO\\MOB_99A.WAV",
+ "AUDIO\\JOB1_1B.WAV",
+ "AUDIO\\JOB1_1C.WAV",
+ "AUDIO\\JOB1_1D.WAV",
+ "AUDIO\\JOB2_1B.WAV",
+ "AUDIO\\JOB2_2.WAV",
+ "AUDIO\\JOB2_3.WAV",
+ "AUDIO\\JOB2_4.WAV",
+ "AUDIO\\JOB2_5.WAV",
+ "AUDIO\\JOB2_6.WAV",
+ "AUDIO\\JOB2_7.WAV",
+ "AUDIO\\JOB2_8.WAV",
+ "AUDIO\\JOB2_9.WAV",
+ "AUDIO\\JOB3_1.WAV",
+ "AUDIO\\JOB3_2.WAV",
+ "AUDIO\\JOB3_3.WAV",
+ "AUDIO\\JOB4_1.WAV",
+ "AUDIO\\JOB4_2.WAV",
+ "AUDIO\\JOB4_3.WAV",
+ "AUDIO\\JOB5_1.WAV",
+ "AUDIO\\JOB5_2.WAV",
+ "AUDIO\\JOB5_3.WAV",
+ "AUDIO\\BJM1_20.WAV",
+ "AUDIO\\BJM1_4.WAV",
+ "AUDIO\\BJM1_5.WAV",
+ "AUDIO\\MERC_39.WAV",
+ "AUDIO\\MONO_1.WAV",
+ "AUDIO\\MONO_2.WAV",
+ "AUDIO\\MONO_3.WAV",
+ "AUDIO\\MONO_4.WAV",
+ "AUDIO\\MONO_5.WAV",
+ "AUDIO\\MONO_6.WAV",
+ "AUDIO\\MONO_7.WAV",
+ "AUDIO\\MONO_8.WAV",
+ "AUDIO\\MONO_9.WAV",
+ "AUDIO\\MONO10.WAV",
+ "AUDIO\\MONO11.WAV",
+ "AUDIO\\MONO12.WAV",
+ "AUDIO\\MONO13.WAV",
+ "AUDIO\\MONO14.WAV",
+ "AUDIO\\MONO15.WAV",
+ "AUDIO\\MONO16.WAV",
+ "AUDIO\\FUD_01.WAV",
+ "AUDIO\\FUD_02.WAV",
+ "AUDIO\\FUD_03.WAV",
+ "AUDIO\\FUD_04.WAV",
+ "AUDIO\\FUD_05.WAV",
+ "AUDIO\\FUD_06.WAV",
+ "AUDIO\\FUD_07.WAV",
+ "AUDIO\\FUD_08.WAV",
+ "AUDIO\\FUD_09.WAV",
+ "AUDIO\\FUD_10.WAV",
+ "AUDIO\\FUD_11.WAV",
+ "AUDIO\\FUD_12.WAV",
+ "AUDIO\\FUD_13.WAV",
+ "AUDIO\\FUD_14.WAV",
+ "AUDIO\\FUD_15.WAV",
+ "AUDIO\\FUD_16.WAV",
+ "AUDIO\\FUD_17.WAV",
+ "AUDIO\\FUD_18.WAV",
+ "AUDIO\\FUD_19.WAV",
+ "AUDIO\\FUD_20.WAV",
+ "AUDIO\\BURG_01.WAV",
+ "AUDIO\\BURG_02.WAV",
+ "AUDIO\\BURG_03.WAV",
+ "AUDIO\\BURG_04.WAV",
+ "AUDIO\\BURG_05.WAV",
+ "AUDIO\\BURG_06.WAV",
+ "AUDIO\\BURG_07.WAV",
+ "AUDIO\\BURG_08.WAV",
+ "AUDIO\\BURG_09.WAV",
+ "AUDIO\\BURG_10.WAV",
+ "AUDIO\\BURG_11.WAV",
+ "AUDIO\\BURG_12.WAV",
+ "AUDIO\\CRUST01.WAV",
+ "AUDIO\\CRUST02.WAV",
+ "AUDIO\\CRUST03.WAV",
+ "AUDIO\\CRUST04.WAV",
+ "AUDIO\\CRUST05.WAV",
+ "AUDIO\\CRUST06.WAV",
+ "AUDIO\\CRUST07.WAV",
+ "AUDIO\\CRUST08.WAV",
+ "AUDIO\\CRUST09.WAV",
+ "AUDIO\\BAND_01.WAV",
+ "AUDIO\\BAND_02.WAV",
+ "AUDIO\\BAND_03.WAV",
+ "AUDIO\\BAND_04.WAV",
+ "AUDIO\\BAND_05.WAV",
+ "AUDIO\\BAND_06.WAV",
+ "AUDIO\\BAND_07.WAV",
+ "AUDIO\\BAND_08.WAV",
+ "AUDIO\\SHAFT01.WAV",
+ "AUDIO\\SHAFT02.WAV",
+ "AUDIO\\SHAFT03.WAV",
+ "AUDIO\\SHAFT04.WAV",
+ "AUDIO\\SHAFT05.WAV",
+ "AUDIO\\SHAFT06.WAV",
+ "AUDIO\\SHAFT07.WAV",
+ "AUDIO\\SHAFT08.WAV",
+ "AUDIO\\PISS_01.WAV",
+ "AUDIO\\PISS_02.WAV",
+ "AUDIO\\PISS_03.WAV",
+ "AUDIO\\PISS_04.WAV",
+ "AUDIO\\PISS_05.WAV",
+ "AUDIO\\PISS_06.WAV",
+ "AUDIO\\PISS_07.WAV",
+ "AUDIO\\PISS_08.WAV",
+ "AUDIO\\PISS_09.WAV",
+ "AUDIO\\PISS_10.WAV",
+ "AUDIO\\PISS_11.WAV",
+ "AUDIO\\PISS_12.WAV",
+ "AUDIO\\PISS_13.WAV",
+ "AUDIO\\PISS_14.WAV",
+ "AUDIO\\PISS_15.WAV",
+ "AUDIO\\PISS_16.WAV",
+ "AUDIO\\PISS_17.WAV",
+ "AUDIO\\PISS_18.WAV",
+ "AUDIO\\PISS_19.WAV",
+ "AUDIO\\GIMME01.WAV",
+ "AUDIO\\GIMME02.WAV",
+ "AUDIO\\GIMME03.WAV",
+ "AUDIO\\GIMME04.WAV",
+ "AUDIO\\GIMME05.WAV",
+ "AUDIO\\GIMME06.WAV",
+ "AUDIO\\GIMME07.WAV",
+ "AUDIO\\GIMME08.WAV",
+ "AUDIO\\GIMME09.WAV",
+ "AUDIO\\GIMME10.WAV",
+ "AUDIO\\GIMME11.WAV",
+ "AUDIO\\GIMME12.WAV",
+ "AUDIO\\GIMME13.WAV",
+ "AUDIO\\GIMME14.WAV",
+ "AUDIO\\GIMME15.WAV",
+ "AUDIO\\BUST_01.WAV",
+ "AUDIO\\BUST_02.WAV",
+ "AUDIO\\BUST_03.WAV",
+ "AUDIO\\BUST_04.WAV",
+ "AUDIO\\BUST_05.WAV",
+ "AUDIO\\BUST_06.WAV",
+ "AUDIO\\BUST_07.WAV",
+ "AUDIO\\BUST_08.WAV",
+ "AUDIO\\BUST_09.WAV",
+ "AUDIO\\BUST_10.WAV",
+ "AUDIO\\BUST_11.WAV",
+ "AUDIO\\BUST_12.WAV",
+ "AUDIO\\BUST_13.WAV",
+ "AUDIO\\BUST_14.WAV",
+ "AUDIO\\BUST_15.WAV",
+ "AUDIO\\BUST_16.WAV",
+ "AUDIO\\BUST_17.WAV",
+ "AUDIO\\BUST_18.WAV",
+ "AUDIO\\BUST_19.WAV",
+ "AUDIO\\BUST_20.WAV",
+ "AUDIO\\BUST_21.WAV",
+ "AUDIO\\BUST_22.WAV",
+ "AUDIO\\BUST_23.WAV",
+ "AUDIO\\BUST_24.WAV",
+ "AUDIO\\BUST_25.WAV",
+ "AUDIO\\BUST_26.WAV",
+ "AUDIO\\BUST_27.WAV",
+ "AUDIO\\BUST_28.WAV",
+}; \ No newline at end of file
diff --git a/src/audio/sampman_miles.cpp b/src/audio/sampman_miles.cpp
index 0ba6b544..7636ceb3 100644
--- a/src/audio/sampman_miles.cpp
+++ b/src/audio/sampman_miles.cpp
@@ -16,7 +16,7 @@
#include "MusicManager.h"
#include "Frontend.h"
#include "Timer.h"
-
+#include "crossplatform.h"
#pragma comment( lib, "mss32.lib" )
@@ -61,14 +61,10 @@ char _mp3DirectoryPath[MAX_PATH];
HSTREAM mp3Stream [MAX_STREAMS];
int8 nStreamPan [MAX_STREAMS];
int8 nStreamVolume[MAX_STREAMS];
+bool8 nStreamLoopedFlag[MAX_STREAMS];
uint32 _CurMP3Index;
int32 _CurMP3Pos;
bool8 _bIsMp3Active;
-
-#if GTA_VERSION >= GTA3_PC_11 || defined(NO_CDCHECK)
-bool8 _bUseHDDAudio;
-char _aHDDPath[MAX_PATH];
-#endif
///////////////////////////////////////////////////////////////
@@ -98,6 +94,7 @@ HSAMPLE opened_2dsamples[MAX2DCHANNELS] = {0};
HDIGDRIVER DIG;
#ifdef EXTERNAL_3D_SOUND
S32 speaker_type=0;
+
U32 _maxSamples;
float _fPrevEaxRatioDestination;
bool8 _usingMilesFast2D;
@@ -266,10 +263,63 @@ set_new_provider(S32 index)
}
#endif
+U32 RadioHandlers[9];
+
+U32 WINAPI vfs_open_callback(char const* Filename, U32* FileHandle)
+{
+ *FileHandle = (U32)fopen(Filename, "rb");
+
+ // couldn't they just use stricmp once? and strlen? this is very inefficient
+ if ((strcmp(Filename + strlen(Filename) - 4, ".adf") == 0) || (strcmp(Filename + strlen(Filename) - 4, ".ADF") == 0)) {
+ for (int i = 0; i < ARRAY_SIZE(RadioHandlers); i++) {
+ if (RadioHandlers[i] == NULL) {
+ RadioHandlers[i] = *FileHandle;
+ break;
+ }
+ }
+ strcpy((char*)Filename + strlen(Filename) - 4, ".mp3");
+ }
+ return *FileHandle;
+}
+
+void WINAPI vfs_close_callback(U32 FileHandle)
+{
+ for (int i = 0; i < ARRAY_SIZE(RadioHandlers); i++) {
+ if (RadioHandlers[i] == FileHandle) {
+ RadioHandlers[i] = NULL;
+ break;
+ }
+ }
+ fclose((FILE*)FileHandle);
+}
+
+S32 WINAPI vfs_seek_callback(U32 FileHandle, S32 Offset, U32 Type)
+{
+ fseek((FILE*)FileHandle, Offset, Type);
+ return ftell((FILE*)FileHandle);
+}
+
+U32 WINAPI vfs_read_callback(U32 FileHandle, void* Buffer, U32 Bytes)
+{
+ fread(Buffer, Bytes, 1, (FILE*)FileHandle);
+ uint8* _Buffer = (uint8*)Buffer;
+
+ for (int i = 0; i < ARRAY_SIZE(RadioHandlers); i++) {
+ if (FileHandle == RadioHandlers[i]) {
+ for (U32 k = 0; k < Bytes; k++)
+ _Buffer[k] ^= 0x22;
+ break;
+ }
+ }
+ return Bytes;
+}
+
cSampleManager::cSampleManager(void) :
m_nNumberOfProviders(0)
{
;
+
+ AIL_set_file_callbacks(vfs_open_callback, vfs_close_callback, vfs_seek_callback, vfs_read_callback);
}
cSampleManager::~cSampleManager(void)
@@ -356,6 +406,63 @@ cSampleManager::SetCurrent3DProvider(uint8 nProvider)
else
return curprovider;
}
+
+int8
+cSampleManager::AutoDetect3DProviders()
+{
+ if (!AudioManager.IsAudioInitialised())
+ return -1;
+
+ int eax = -1, eax2 = -1, eax3 = -1, ds3dh = -1, ds3ds = -1;
+
+ for (uint32 i = 0; i < GetNum3DProvidersAvailable(); i++)
+ {
+ char* providername = Get3DProviderName(i);
+
+ if (!strcasecmp(providername, "CREATIVE LABS EAX (TM)")) {
+ AudioManager.SetCurrent3DProvider(i);
+ if (GetCurrent3DProviderIndex() == i)
+ eax = i;
+ }
+
+ if (!strcasecmp(providername, "CREATIVE LABS EAX 2 (TM)")) {
+ AudioManager.SetCurrent3DProvider(i);
+ if (GetCurrent3DProviderIndex() == i)
+ eax2 = i;
+ }
+
+ if (!strcasecmp(providername, "CREATIVE LABS EAX 3 (TM)")) {
+ AudioManager.SetCurrent3DProvider(i);
+ if (GetCurrent3DProviderIndex() == i) {
+ eax3 = i;
+ }
+ }
+
+ if (!strcasecmp(providername, "DIRECTSOUND3D HARDWARE SUPPORT")) {
+ AudioManager.SetCurrent3DProvider(i);
+ if (GetCurrent3DProviderIndex() == i)
+ ds3dh = i;
+ }
+
+ if (!strcasecmp(providername, "DIRECTSOUND3D SOFTWARE EMULATION")) {
+ AudioManager.SetCurrent3DProvider(i);
+ if (GetCurrent3DProviderIndex() == i)
+ ds3ds = i;
+ }
+ }
+
+ if (eax3 != -1)
+ return eax3;
+ if (eax2 != -1)
+ return eax2;
+ if (eax != -1)
+ return eax;
+ if (ds3dh != -1)
+ return ds3dh;
+ if (ds3ds != -1)
+ return ds3ds;
+ return -1;
+}
#endif
static bool8
@@ -453,15 +560,6 @@ _FindMP3s(void)
FindClose(hFind);
return;
}
-
- FILE *f = fopen("MP3\\MP3Report.txt", "w");
-
- if ( f )
- {
- fprintf(f, "MP3 Report File\n\n");
- fprintf(f, "\"%s\"", fd.cFileName);
- }
-
if ( filepathlen > 4 )
{
@@ -471,12 +569,6 @@ _FindMP3s(void)
{
OutputDebugString("Resolving Link");
OutputDebugString(filepath);
-
- if ( f ) fprintf(f, " - shortcut to \"%s\"", filepath);
- }
- else
- {
- if ( f ) fprintf(f, " - couldn't resolve shortcut");
}
bShortcut = TRUE;
@@ -500,10 +592,6 @@ _FindMP3s(void)
if ( _pMP3List == NULL )
{
FindClose(hFind);
-
- if ( f )
- fclose(f);
-
return;
}
@@ -526,9 +614,6 @@ _FindMP3s(void)
{
_pMP3List->pLinkPath = NULL;
}
-
- if ( f ) fprintf(f, " - OK\n");
-
bInitFirstEntry = FALSE;
}
else
@@ -537,8 +622,6 @@ _FindMP3s(void)
OutputDebugString(filepath);
- if ( f ) fprintf(f, " - not an MP3 or supported MP3 type\n");
-
bInitFirstEntry = TRUE;
}
@@ -554,8 +637,6 @@ _FindMP3s(void)
int32 filepathlen = strlen(filepath);
- if ( f ) fprintf(f, "\"%s\"", fd.cFileName);
-
if ( filepathlen > 0 )
{
if ( filepathlen > 4 )
@@ -566,12 +647,6 @@ _FindMP3s(void)
{
OutputDebugString("Resolving Link");
OutputDebugString(filepath);
-
- if ( f ) fprintf(f, " - shortcut to \"%s\"", filepath);
- }
- else
- {
- if ( f ) fprintf(f, " - couldn't resolve shortcut");
}
bShortcut = TRUE;
@@ -582,8 +657,6 @@ _FindMP3s(void)
if ( filepathlen > MAX_PATH )
{
- if ( f ) fprintf(f, " - Filename and path too long - %s - IGNORED)\n", filepath);
-
continue;
}
}
@@ -622,17 +695,13 @@ _FindMP3s(void)
}
pList = _pMP3List;
-
- if ( f ) fprintf(f, " - OK\n");
-
+
bInitFirstEntry = FALSE;
}
else
{
strcat(filepath, " - NOT A VALID MP3");
OutputDebugString(filepath);
-
- if ( f ) fprintf(f, " - not an MP3 or supported MP3 type\n");
}
}
}
@@ -645,8 +714,6 @@ _FindMP3s(void)
if ( filepathlen > 0 )
{
- if ( f ) fprintf(f, "\"%s\"", fd.cFileName);
-
if ( filepathlen > 4 )
{
if ( !strcmp(&filepath[filepathlen - 4], ".lnk") )
@@ -655,12 +722,6 @@ _FindMP3s(void)
{
OutputDebugString("Resolving Link");
OutputDebugString(filepath);
-
- if ( f ) fprintf(f, " - shortcut to \"%s\"", filepath);
- }
- else
- {
- if ( f ) fprintf(f, " - couldn't resolve shortcut");
}
bShortcut = TRUE;
@@ -705,26 +766,16 @@ _FindMP3s(void)
nNumMP3s++;
OutputDebugString(fd.cFileName);
-
- if ( f ) fprintf(f, " - OK\n");
}
else
{
strcat(filepath, " - NOT A VALID MP3");
OutputDebugString(filepath);
-
- if ( f ) fprintf(f, " - not an MP3 or supported MP3 type\n");
}
}
}
}
-
- if ( f )
- {
- fprintf(f, "\nTOTAL SUPPORTED MP3s: %d\n", nNumMP3s);
- fclose(f);
- }
-
+
FindClose(hFind);
}
@@ -897,7 +948,7 @@ cSampleManager::Initialise(void)
opened_samples[i] = NULL;
}
#endif
-
+
// banks
TRACE("banks");
{
@@ -942,56 +993,37 @@ cSampleManager::Initialise(void)
AIL_set_preference(DIG_MIXER_CHANNELS, MAX_DIGITAL_MIXER_CHANNELS);
- DIG = AIL_open_digital_driver(DIGITALRATE, DIGITALBITS, DIGITALCHANNELS, 0);
- if ( DIG == NULL )
- {
- OutputDebugString(AIL_last_error());
- Terminate();
- return FALSE;
- }
-
-#ifdef EXTERNAL_3D_SOUND
- add_providers();
-#endif
-
- if ( !InitialiseSampleBanks() )
- {
- Terminate();
- return FALSE;
- }
-
- nSampleBankMemoryStartAddress[SFX_BANK_0] = (int32)AIL_mem_alloc_lock(nSampleBankSize[SFX_BANK_0]);
- if ( !nSampleBankMemoryStartAddress[SFX_BANK_0] )
- {
- Terminate();
- return FALSE;
- }
-
- nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] = (int32)AIL_mem_alloc_lock(PED_BLOCKSIZE*MAX_PEDSFX);
+ DIG = AIL_open_digital_driver(DIGITALRATE, DIGITALBITS, DIGITALCHANNELS, 0);
}
#ifdef AUDIO_CACHE
TRACE("cache");
- FILE *cacheFile = fopen("audio\\sound.cache", "rb");
+ FILE *cacheFile = fcaseopen("audio\\sound.cache", "rb");
+ bool8 CreateCache = FALSE;
if (cacheFile) {
fread(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile);
fclose(cacheFile);
- m_bInitialised = TRUE;
- }else {
+ }else
+ CreateCache = TRUE;
#endif
- TRACE("cdrom");
- S32 tatalms;
char filepath[MAX_PATH];
+ bool8 bFileNotFound;
+ S32 tatalms;
+ TRACE("cdrom");
{
m_bInitialised = FALSE;
+
while (TRUE)
{
+
+ // Find path of WAVs (originally in HDD)
int32 drive = 'C';
+#ifndef NO_CDCHECK
do
{
char latter[2];
@@ -1021,122 +1053,51 @@ cSampleManager::Initialise(void)
if ( f )
{
fclose(f);
-
- bool8 bFileNotFound = FALSE;
-
- for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
- {
-#ifdef PS2_AUDIO_PATHS
- strcpy(filepath, m_szCDRomRootPath);
- strcat(filepath, PS2StreamedNameTable[i]);
-
- mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
- if ( !mp3Stream[0] )
-#endif
- {
- strcpy(filepath, m_szCDRomRootPath);
- strcat(filepath, StreamedNameTable[i]);
-
- mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
- }
-
- if ( mp3Stream[0] )
- {
- AIL_stream_ms_position(mp3Stream[0], &tatalms, NULL);
-
- AIL_close_stream(mp3Stream[0]);
- mp3Stream[0] = NULL;
-
- nStreamLength[i] = tatalms;
- }
- else
- {
- bFileNotFound = TRUE;
- break;
- }
- }
-
- if ( !bFileNotFound )
- {
- m_bInitialised = TRUE;
- break;
- }
- else
- {
- m_bInitialised = FALSE;
- continue;
- }
+ strcpy(m_MiscomPath, m_szCDRomRootPath);
+ break;
}
}
-
+
} while ( ++drive <= 'Z' );
-
- if ( !m_bInitialised )
- {
-#if GTA_VERSION < GTA3_PC_STEAM && !defined(NO_CDCHECK)
- FrontEndMenuManager.WaitForUserCD();
- if ( FrontEndMenuManager.m_bQuitGameNoCD )
- {
- Terminate();
- return FALSE;
- }
- continue;
#else
- m_bInitialised = TRUE;
+ m_MiscomPath[0] = '\0';
#endif
- }
-
- break;
- }
- }
-#if GTA_VERSION >= GTA3_PC_11 || defined(NO_CDCHECK)
- // hddaudio
- /**
- Option for user to play audio files directly from hard disk.
- Copy the contents of the PLAY discs Audio directory into your installed Grand Theft Auto III Audio directory.
- Grand Theft Auto III still requires the presence of the PLAY disc when started.
- This may give better performance on some machines (though worse on others).
- **/
- TRACE("hddaudio 1.1 patch");
- {
- int32 streamLength[TOTAL_STREAMED_SOUNDS];
-
- bool8 bFileNotFound = FALSE;
- char rootpath[MAX_PATH];
-
- strcpy(_aHDDPath, m_szCDRomRootPath);
- rootpath[0] = '\0';
-
- FILE *f;
+ if ( DIG == NULL )
+ {
+ OutputDebugString(AIL_last_error());
+ Terminate();
+ return FALSE;
+ }
-#ifdef PS2_AUDIO_PATHS
- f = fopen(PS2StreamedNameTable[0], "rb");
- if (!f)
+#ifdef EXTERNAL_3D_SOUND
+ add_providers();
#endif
- f = fopen(StreamedNameTable[0], "rb");
-
- if ( f )
- {
- fclose(f);
-
- for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
+ m_szCDRomRootPath[0] = '\0';
+
+ strcpy(m_WavFilesPath, m_szCDRomRootPath);
+
+#ifdef AUDIO_CACHE
+ if ( CreateCache )
+#endif
+ for ( int32 i = STREAMED_SOUND_MISSION_MOBR1; i < TOTAL_STREAMED_SOUNDS; i++ )
{
#ifdef PS2_AUDIO_PATHS
- strcpy(filepath, rootpath);
+ strcpy(filepath, m_szCDRomRootPath);
strcat(filepath, PS2StreamedNameTable[i]);
mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
+
if ( !mp3Stream[0] )
#endif
{
- strcpy(filepath, rootpath);
+ strcpy(filepath, m_szCDRomRootPath);
strcat(filepath, StreamedNameTable[i]);
mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
}
-
+
if ( mp3Stream[0] )
{
AIL_stream_ms_position(mp3Stream[0], &tatalms, NULL);
@@ -1144,39 +1105,169 @@ cSampleManager::Initialise(void)
AIL_close_stream(mp3Stream[0]);
mp3Stream[0] = NULL;
- streamLength[i] = tatalms;
+ nStreamLength[i] = tatalms;
}
else
{
- bFileNotFound = TRUE;
+ m_bInitialised = FALSE;
+ Terminate();
+ return FALSE;
+ }
+ }
+
+ // Find path of MP3s (originally in CD-Rom)
+ // if NO_CDCHECK is NOT defined but AUDIO_CACHE is defined, we still need to find MP3s' path, but will exit after the first file
+#ifndef NO_CDCHECK
+ int32 drive = 'C';
+ do
+ {
+ latter[0] = drive;
+ latter[1] = '\0';
+
+ strcpy(m_szCDRomRootPath, latter);
+ strcat(m_szCDRomRootPath, ":");
+ strcat(m_MP3FilesPath, m_szCDRomRootPath);
+#else
+ m_MP3FilesPath[0] = '\0';
+ {
+#endif
+
+ for (int32 i = 0; i < STREAMED_SOUND_MISSION_MOBR1; i++)
+ {
+#ifdef PS2_AUDIO_PATHS
+ strcpy(filepath, m_MP3FilesPath);
+ strcat(filepath, PS2StreamedNameTable[i]);
+
+ mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
+
+ if ( !mp3Stream[0] )
+#endif
+ {
+ strcpy(filepath, m_MP3FilesPath);
+ strcat(filepath, StreamedNameTable[i]);
+
+ mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
+ }
+
+ if (mp3Stream[0])
+ {
+ AIL_stream_ms_position(mp3Stream[0], &tatalms, NULL);
+
+ AIL_close_stream(mp3Stream[0]);
+ mp3Stream[0] = NULL;
+
+ bFileNotFound = FALSE;
+#ifdef AUDIO_CACHE
+ if (!CreateCache)
+ break;
+ else
+#endif
+ nStreamLength[i] = tatalms;
+
+ }
+ else
+ {
+ bFileNotFound = TRUE;
+ break;
+ }
+ }
+
+#ifndef NO_CDCHECK
+ if (!bFileNotFound) // otherwise try next drive
break;
+
+ }
+ while (++drive <= 'Z');
+#else
+ }
+#endif
+
+ if ( !bFileNotFound ) {
+
+#ifdef AUDIO_CACHE
+ if ( CreateCache )
+#endif
+ for ( int32 i = STREAMED_SOUND_MISSION_COMPLETED4; i < STREAMED_SOUND_MISSION_PAGER; i++ )
+ {
+#ifdef PS2_AUDIO_PATHS
+ strcpy(filepath, m_MiscomPath);
+ strcat(filepath, PS2StreamedNameTable[i]);
+
+ mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
+
+ if ( !mp3Stream[0] )
+#endif
+ {
+ strcpy(filepath, m_MiscomPath);
+ strcat(filepath, StreamedNameTable[i]);
+
+ mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
+ }
+
+ if ( mp3Stream[0] )
+ {
+ AIL_stream_ms_position(mp3Stream[0], &tatalms, NULL);
+
+ AIL_close_stream(mp3Stream[0]);
+ mp3Stream[0] = NULL;
+
+ nStreamLength[i] = tatalms;
+ bFileNotFound = FALSE;
+ }
+ else
+ {
+ bFileNotFound = TRUE;
+ break;
+ }
}
}
-
- }
- else
- bFileNotFound = TRUE;
-
- if ( !bFileNotFound )
- {
- strcpy(m_szCDRomRootPath, rootpath);
- for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
- nStreamLength[i] = streamLength[i];
+ m_bInitialised = !bFileNotFound;
+
+ if ( !m_bInitialised )
+ {
+#if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK)
+ FrontEndMenuManager.WaitForUserCD();
+ if ( FrontEndMenuManager.m_bQuitGameNoCD )
+ {
+ Terminate();
+ return FALSE;
+ }
+ continue;
+#else
+ m_bInitialised = TRUE;
+#endif
+ }
- _bUseHDDAudio = TRUE;
+ break;
}
- else
- _bUseHDDAudio = FALSE;
}
-#endif
+
#ifdef AUDIO_CACHE
- cacheFile = fopen("audio\\sound.cache", "wb");
- fwrite(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile);
- fclose(cacheFile);
+ if (CreateCache) {
+ cacheFile = fcaseopen("audio\\sound.cache", "wb");
+ fwrite(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile);
+ fclose(cacheFile);
}
#endif
+ if ( !InitialiseSampleBanks() )
+ {
+ Terminate();
+ return FALSE;
+ }
+
+ nSampleBankMemoryStartAddress[SFX_BANK_0] = (int32)AIL_mem_alloc_lock(nSampleBankSize[SFX_BANK_0]);
+ if ( !nSampleBankMemoryStartAddress[SFX_BANK_0] )
+ {
+ Terminate();
+ return FALSE;
+ }
+
+ nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] = (int32)AIL_mem_alloc_lock(PED_BLOCKSIZE*MAX_PEDSFX);
+
+ LoadSampleBank(SFX_BANK_0);
+
TRACE("stream");
{
for ( int32 i = 0; i < MAX_STREAMS; i++ )
@@ -1206,7 +1297,7 @@ cSampleManager::Initialise(void)
while ( n < m_nNumberOfProviders )
{
- if ( !strcmp(providers[n].name, "Miles Fast 2D Positional Audio") )
+ if ( !strcmp(strupr(providers[n].name), "DIRECTSOUND3D SOFTWARE EMULATION") )
{
set_new_provider(n);
break;
@@ -1222,10 +1313,6 @@ cSampleManager::Initialise(void)
#endif
}
- TRACE("bank");
-
- LoadSampleBank(SFX_BANK_0);
-
// mp3
TRACE("mp3");
{
@@ -1347,77 +1434,43 @@ cSampleManager::Terminate(void)
bool8
cSampleManager::CheckForAnAudioFileOnCD(void)
{
-#if GTA_VERSION < GTA3_PC_STEAM && !defined(NO_CDCHECK)
+#if !defined(NO_CDCHECK) // TODO: check steam, probably GTAVC_STEAM_PATCH needs to be added
char filepath[MAX_PATH];
FILE *f;
-#ifdef PS2_AUDIO_PATHS
-#if GTA_VERSION >= GTA3_PC_11
- if(_bUseHDDAudio)
- strcpy(filepath, _aHDDPath);
- else
- strcpy(filepath, m_szCDRomRootPath);
-#else
- strcpy(filepath, m_szCDRomRootPath);
-#endif // #if GTA_VERSION >= GTA3_PC_11
+ strcpy(filepath, m_MiscomPath);
+ strcat(filepath, StreamedNameTable[STREAMED_SOUND_MISSION_COMPLETED4]);
- strcat(filepath, PS2StreamedNameTable[AudioManager.m_anRandomTable[1] % TOTAL_STREAMED_SOUNDS]);
+ FILE *f = fopen(filepath, "rb");
- f = fopen(filepath, "rb");
- if ( !f )
-#endif // PS2_AUDIO_PATHS
- {
-#if GTA_VERSION >= GTA3_PC_11
- if (_bUseHDDAudio)
- strcpy(filepath, _aHDDPath);
- else
- strcpy(filepath, m_szCDRomRootPath);
-#else
- strcpy(filepath, m_szCDRomRootPath);
-#endif // #if GTA_VERSION >= GTA3_PC_11
-
- strcat(filepath, StreamedNameTable[AudioManager.m_anRandomTable[1] % TOTAL_STREAMED_SOUNDS]);
-
- f = fopen(filepath, "rb");
- }
if ( f )
{
fclose(f);
+ DMAudio.SetMusicMasterVolume(FrontEndMenuManager.m_PrefsMusicVolume);
+ DMAudio.SetEffectsMasterVolume(FrontEndMenuManager.m_PrefsSfxVolume);
+ DMAudio.Service();
return TRUE;
}
-
+
+ DMAudio.SetMusicMasterVolume(0);
+ DMAudio.SetEffectsMasterVolume(0);
+ DMAudio.Service();
+
return FALSE;
#else
return TRUE;
-#endif // #if GTA_VERSION < GTA3_PC_STEAM && !defined(NO_CDCHECK)
+#endif // #if !defined(NO_CDCHECK)
}
char
cSampleManager::GetCDAudioDriveLetter(void)
{
-#if GTA_VERSION >= GTA3_PC_11 || defined(NO_CDCHECK)
- if (_bUseHDDAudio)
- {
- if ( strlen(_aHDDPath) != 0 )
- return _aHDDPath[0];
- else
- return '\0';
- }
- else
- {
- if ( strlen(m_szCDRomRootPath) != 0 )
- return m_szCDRomRootPath[0];
- else
- return '\0';
- }
-#else
- if ( strlen(m_szCDRomRootPath) != 0 )
- return m_szCDRomRootPath[0];
+ if ( strlen(m_MiscomPath) != 0 )
+ return m_MiscomPath[0];
else
return '\0';
-#endif
}
void
@@ -1472,6 +1525,12 @@ cSampleManager::SetMusicMasterVolume(uint8 nVolume)
}
void
+cSampleManager::SetMP3BoostVolume(uint8 nVolume)
+{
+ m_nMP3BoostVolume = nVolume;
+}
+
+void
cSampleManager::SetEffectsFadeVolume(uint8 nVolume)
{
m_nEffectsFadeVolume = nVolume;
@@ -1581,14 +1640,6 @@ cSampleManager::LoadPedComment(uint32 nComment)
break;
}
-
- case MUSICMODE_FRONTEND:
- {
- if ( MusicManager.GetNextTrack() == STREAMED_SOUND_GAME_COMPLETED )
- return FALSE;
-
- break;
- }
}
}
@@ -1652,69 +1703,45 @@ cSampleManager::UpdateReverb(void)
if ( AudioManager.m_FrameCounter & 15 )
return FALSE;
-
- float y = AudioManager.m_afReflectionsDistances[REFLECTION_TOP] + AudioManager.m_afReflectionsDistances[REFLECTION_BOTTOM];
- float x = AudioManager.m_afReflectionsDistances[REFLECTION_LEFT] + AudioManager.m_afReflectionsDistances[REFLECTION_RIGHT];
- float z = AudioManager.m_afReflectionsDistances[REFLECTION_UP];
-
- float normy = norm(y, 5.0f, 40.0f);
- float normx = norm(x, 5.0f, 40.0f);
- float normz = norm(z, 5.0f, 40.0f);
- float fRatio;
-
- if ( normy == 0.0f )
- {
- if ( normx == 0.0f )
- {
- if ( normz == 0.0f )
- fRatio = 0.3f;
- else
- fRatio = 0.5f;
- }
- else
- {
- fRatio = 0.3f;
- }
- }
- else
- {
- if ( normx == 0.0f )
- {
- if ( normz == 0.0f )
- fRatio = 0.3f;
- else
- fRatio = 0.5f;
- }
- else
- {
- if ( normz == 0.0f )
- fRatio = 0.3f;
- else
- fRatio = (normy+normx+normz) / 3.0f;
- }
- }
+ float fRatio = 0.0f;
+
+#define MIN_DIST 0.5f
+#define CALCULATE_RATIO(value, maxDist, maxRatio) (value > MIN_DIST && value < maxDist ? value / maxDist * maxRatio : 0)
+
+ fRatio += CALCULATE_RATIO(AudioManager.m_afReflectionsDistances[REFLECTION_CEIL_NORTH], 10.0f, 1/2.f);
+ fRatio += CALCULATE_RATIO(AudioManager.m_afReflectionsDistances[REFLECTION_CEIL_SOUTH], 10.0f, 1/2.f);
+ fRatio += CALCULATE_RATIO(AudioManager.m_afReflectionsDistances[REFLECTION_CEIL_WEST], 10.0f, 1/2.f);
+ fRatio += CALCULATE_RATIO(AudioManager.m_afReflectionsDistances[REFLECTION_CEIL_EAST], 10.0f, 1/2.f);
+
+ fRatio += CALCULATE_RATIO((AudioManager.m_afReflectionsDistances[REFLECTION_NORTH] + AudioManager.m_afReflectionsDistances[REFLECTION_SOUTH]) / 2.f, 4.0f, 1/3.f);
+ fRatio += CALCULATE_RATIO((AudioManager.m_afReflectionsDistances[REFLECTION_WEST] + AudioManager.m_afReflectionsDistances[REFLECTION_EAST]) / 2.f, 4.0f, 1/3.f);
+
+#undef CALCULATE_RATIO
+#undef MIN_DIST
- fRatio = Clamp(fRatio, usingEAX3==1 ? 0.0f : 0.30f, 1.0f);
+ fRatio = Clamp(fRatio, 0.0f, 0.6f);
if ( fRatio == _fPrevEaxRatioDestination )
return FALSE;
if ( usingEAX3 )
{
+ fRatio = Min(fRatio * 1.67f, 1.0f);
if ( EAX3ListenerInterpolate(&StartEAX3, &FinishEAX3, fRatio, &EAX3Params, false) )
{
AIL_set_3D_provider_preference(opened_provider, "EAX all parameters", &EAX3Params);
- _fEffectsLevel = 1.0f - fRatio * 0.5f;
+ _fEffectsLevel = fRatio * 0.75f;
}
}
else
{
if ( _usingMilesFast2D )
- _fEffectsLevel = (1.0f - fRatio) * 0.4f;
+ _fEffectsLevel = fRatio * 0.8f;
else
- _fEffectsLevel = (1.0f - fRatio) * 0.7f;
+ _fEffectsLevel = fRatio * 0.22f;
}
+ _fEffectsLevel = Min(_fEffectsLevel, 1.0f);
_fPrevEaxRatioDestination = fRatio;
@@ -1834,11 +1861,11 @@ cSampleManager::SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume)
nChannelVolume[nChannel] = vol;
// increase the volume for JB.MP3 and S4_BDBD.MP3
- if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE
- && MusicManager.GetNextTrack() != STREAMED_SOUND_NEWS_INTRO
- && MusicManager.GetNextTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD )
- {
- nChannelVolume[nChannel] >>= 2;
+ if (MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE ) {
+ if (MusicManager.GetCurrentTrack() == STREAMED_SOUND_CUTSCENE_FINALE)
+ nChannelVolume[nChannel] = 0;
+ else
+ nChannelVolume[nChannel] >>= 2;
}
if ( opened_samples[nChannel] )
@@ -1877,8 +1904,7 @@ cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume)
// increase the volume for JB.MP3 and S4_BDBD.MP3
if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE
- && MusicManager.GetNextTrack() != STREAMED_SOUND_NEWS_INTRO
- && MusicManager.GetNextTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD )
+ && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_FINALE )
{
nChannelVolume[nChannel] >>= 2;
}
@@ -2108,7 +2134,7 @@ cSampleManager::StopChannel(uint32 nChannel)
}
void
-cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream)
+cSampleManager::PreloadStreamedFile(uint32 nFile, uint8 nStream)
{
if ( m_bInitialised )
{
@@ -2122,16 +2148,17 @@ cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream)
char filepath[MAX_PATH];
#ifdef PS2_AUDIO_PATHS
- strcpy(filepath, m_szCDRomRootPath);
+ strcpy(filepath, nFile < STREAMED_SOUND_MISSION_COMPLETED4 ? m_MP3FilesPath : (nFile < STREAMED_SOUND_MISSION_MOBR1 ? m_MiscomPath : m_WavFilesPath));
strcat(filepath, PS2StreamedNameTable[nFile]);
mp3Stream[nStream] = AIL_open_stream(DIG, filepath, 0);
+
if ( !mp3Stream[nStream] )
#endif
{
- strcpy(filepath, m_szCDRomRootPath);
+ strcpy(filepath, nFile < STREAMED_SOUND_MISSION_COMPLETED4 ? m_MP3FilesPath : (nFile < STREAMED_SOUND_MISSION_MOBR1 ? m_MiscomPath : m_WavFilesPath));
strcat(filepath, StreamedNameTable[nFile]);
-
+
mp3Stream[nStream] = AIL_open_stream(DIG, filepath, 0);
}
@@ -2167,7 +2194,7 @@ cSampleManager::StartPreloadedStreamedFile(uint8 nStream)
}
bool8
-cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
+cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream)
{
int i = 0;
uint32 position = nPos;
@@ -2196,21 +2223,22 @@ cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
if(!_GetMP3PosFromStreamPos(&position, &e) && !e) {
nFile = 0;
#ifdef PS2_AUDIO_PATHS
- strcpy(filename, m_szCDRomRootPath);
+ strcpy(filename, m_MiscomPath);
strcat(filename, PS2StreamedNameTable[nFile]);
mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0);
+
if ( !mp3Stream[nStream] )
#endif
{
- strcpy(filename, m_szCDRomRootPath);
+ strcpy(filename, m_MiscomPath);
strcat(filename, StreamedNameTable[nFile]);
-
- mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0);
+ mp3Stream[nStream] =
+ AIL_open_stream(DIG, filename, 0);
}
- if ( mp3Stream[nStream] )
- {
- AIL_set_stream_loop_count(mp3Stream[nStream], 1);
+ if(mp3Stream[nStream]) {
+ AIL_set_stream_loop_count(mp3Stream[nStream], nStreamLoopedFlag[nStream] ? 0 : 1);
+ nStreamLoopedFlag[nStream] = TRUE;
AIL_set_stream_ms_position(mp3Stream[nStream], position);
AIL_pause_stream(mp3Stream[nStream], 0);
return TRUE;
@@ -2252,23 +2280,27 @@ cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
nFile = 0;
_bIsMp3Active = 0;
#ifdef PS2_AUDIO_PATHS
- strcpy(filename, m_szCDRomRootPath);
+ strcpy(filename, m_MiscomPath);
strcat(filename, PS2StreamedNameTable[nFile]);
mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0);
+
if ( !mp3Stream[nStream] )
#endif
{
- strcpy(filename, m_szCDRomRootPath);
+ strcpy(filename, m_MiscomPath);
strcat(filename, StreamedNameTable[nFile]);
-
- mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0);
+ mp3Stream[nStream] =
+ AIL_open_stream(DIG, filename, 0);
}
- if ( mp3Stream[nStream] )
- {
- AIL_set_stream_loop_count(mp3Stream[nStream], 1);
- AIL_set_stream_ms_position(mp3Stream[nStream], position);
- AIL_pause_stream(mp3Stream[nStream], 0);
+ if(mp3Stream[nStream]) {
+ AIL_set_stream_loop_count(
+ mp3Stream[nStream], nStreamLoopedFlag[nStream] ? 0 : 1);
+ nStreamLoopedFlag[nStream] = TRUE;
+ AIL_set_stream_ms_position(
+ mp3Stream[nStream], position);
+ AIL_pause_stream(mp3Stream[nStream],
+ 0);
return TRUE;
}
return FALSE;
@@ -2302,21 +2334,23 @@ cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
nFile = 0;
}
#ifdef PS2_AUDIO_PATHS
- strcpy(filename, m_szCDRomRootPath);
+ strcpy(filename, m_MiscomPath);
strcat(filename, PS2StreamedNameTable[nFile]);
mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0);
+
if ( !mp3Stream[nStream] )
#endif
{
- strcpy(filename, m_szCDRomRootPath);
+ strcpy(filename, m_MiscomPath);
strcat(filename, StreamedNameTable[nFile]);
-
mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0);
}
+
if ( mp3Stream[nStream] )
{
- AIL_set_stream_loop_count(mp3Stream[nStream], 1);
+ AIL_set_stream_loop_count(mp3Stream[nStream], nStreamLoopedFlag[nStream] ? 0 : 1);
+ nStreamLoopedFlag[nStream] = TRUE;
AIL_set_stream_ms_position(mp3Stream[nStream], position);
AIL_pause_stream(mp3Stream[nStream], 0);
return TRUE;
@@ -2378,11 +2412,14 @@ void
cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, bool8 nEffectFlag, uint8 nStream)
{
uint8 vol = nVolume;
+ float boostMult = 0.0f;
if ( m_bInitialised )
{
if ( vol > MAX_VOLUME ) vol = MAX_VOLUME;
- if ( vol > MAX_VOLUME ) vol = MAX_VOLUME;
+
+ if ( MusicManager.GetRadioInCar() == USERTRACK && !MusicManager.CheckForMusicInterruptions() )
+ boostMult = m_nMP3BoostVolume / 64.f;
nStreamVolume[nStream] = vol;
nStreamPan[nStream] = nPan;
@@ -2390,9 +2427,14 @@ cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, bool8 nEffect
if ( mp3Stream[nStream] )
{
if ( nEffectFlag )
- AIL_set_stream_volume(mp3Stream[nStream], m_nEffectsFadeVolume*vol*m_nEffectsVolume >> 14);
+ {
+ if ( nStream == 1 || nStream == 2 )
+ AIL_set_stream_volume(mp3Stream[nStream], 128*vol*m_nEffectsVolume >> 14);
+ else
+ AIL_set_stream_volume(mp3Stream[nStream], m_nEffectsFadeVolume*vol*m_nEffectsVolume >> 14);
+ }
else
- AIL_set_stream_volume(mp3Stream[nStream], m_nMusicFadeVolume*vol*m_nMusicVolume >> 14);
+ AIL_set_stream_volume(mp3Stream[nStream], (m_nMusicFadeVolume*vol*(uint32)(m_nMusicVolume * boostMult + m_nMusicVolume)) >> 14);
AIL_set_stream_pan(mp3Stream[nStream], nPan);
}
@@ -2470,4 +2512,12 @@ cSampleManager::InitialiseSampleBanks(void)
return TRUE;
}
+
+void
+cSampleManager::SetStreamedFileLoopFlag(bool8 nLoopFlag, uint8 nChannel)
+{
+ if (m_bInitialised)
+ nStreamLoopedFlag[nChannel] = nLoopFlag;
+}
+
#endif
diff --git a/src/audio/sampman_null.cpp b/src/audio/sampman_null.cpp
index 6d16e286..627d122b 100644
--- a/src/audio/sampman_null.cpp
+++ b/src/audio/sampman_null.cpp
@@ -116,6 +116,11 @@ cSampleManager::SetMusicMasterVolume(uint8 nVolume)
}
void
+cSampleManager::SetMP3BoostVolume(uint8 nVolume)
+{
+}
+
+void
cSampleManager::SetEffectsFadeVolume(uint8 nVolume)
{
}
@@ -126,7 +131,7 @@ cSampleManager::SetMusicFadeVolume(uint8 nVolume)
}
void
-cSampleManager::SetMonoMode(uint8 nMode)
+cSampleManager::SetMonoMode(bool8 nMode)
{
}
@@ -301,7 +306,7 @@ cSampleManager::StopChannel(uint32 nChannel)
}
void
-cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream)
+cSampleManager::PreloadStreamedFile(uint32 nFile, uint8 nStream)
{
ASSERT( nStream < MAX_STREAMS );
}
@@ -319,7 +324,7 @@ cSampleManager::StartPreloadedStreamedFile(uint8 nStream)
}
bool8
-cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
+cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream)
{
ASSERT( nStream < MAX_STREAMS );
@@ -341,7 +346,7 @@ cSampleManager::GetStreamedFilePosition(uint8 nStream)
}
void
-cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream)
+cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, bool8 nEffectFlag, uint8 nStream)
{
ASSERT( nStream < MAX_STREAMS );
}
@@ -369,4 +374,14 @@ cSampleManager::InitialiseSampleBanks(void)
return TRUE;
}
+void
+cSampleManager::SetStreamedFileLoopFlag(bool8 nLoopFlag, uint8 nChannel)
+{
+}
+
+int8 cSampleManager::AutoDetect3DProviders()
+{
+ return -1;
+}
+
#endif
diff --git a/src/audio/sampman_oal.cpp b/src/audio/sampman_oal.cpp
index 17776347..8a9379ea 100644
--- a/src/audio/sampman_oal.cpp
+++ b/src/audio/sampman_oal.cpp
@@ -66,14 +66,14 @@ int usingEAX3=0;
ALCdevice *ALDevice = NULL;
ALCcontext *ALContext = NULL;
unsigned int _maxSamples;
-float _fPrevEaxRatioDestination;
+float _fPrevEaxRatioDestination;
bool _effectsSupported = false;
bool _usingEFX;
float _fEffectsLevel;
ALuint ALEffect = AL_EFFECT_NULL;
ALuint ALEffectSlot = AL_EFFECTSLOT_NULL;
struct
-{
+{
const char *id;
char name[256];
int sources;
@@ -92,7 +92,7 @@ OggOpusFile *fpSampleDataHandle;
#else
FILE *fpSampleDataHandle;
#endif
-bool8 bSampleBankLoaded [MAX_SFX_BANKS];
+bool8 bSampleBankLoaded [MAX_SFX_BANKS];
int32 nSampleBankDiscStartOffset [MAX_SFX_BANKS];
int32 nSampleBankSize [MAX_SFX_BANKS];
uintptr nSampleBankMemoryStartAddress[MAX_SFX_BANKS];
@@ -126,6 +126,7 @@ char _mp3DirectoryPath[MAX_PATH];
CStream *aStream[MAX_STREAMS];
uint8 nStreamPan [MAX_STREAMS];
uint8 nStreamVolume[MAX_STREAMS];
+bool8 nStreamLoopedFlag[MAX_STREAMS];
uint32 _CurMP3Index;
int32 _CurMP3Pos;
bool8 _bIsMp3Active;
@@ -157,7 +158,7 @@ static void
add_providers()
{
SampleManager.SetNum3DProvidersAvailable(0);
-
+
static ALDeviceList DeviceList;
ALDeviceList *pDeviceList = &DeviceList;
@@ -170,7 +171,7 @@ add_providers()
int i = pDeviceList->GetDefaultDevice();
{
if ( n < MAXPROVIDERS )
- {
+ {
providers[n].id = pDeviceList->GetDeviceName(i);
strcpy(providers[n].name, "OPENAL SOFT");
providers[n].sources = pDeviceList->GetMaxNumSources(i);
@@ -183,10 +184,10 @@ add_providers()
|| pDeviceList->IsExtensionSupported(i, ADEXT_EAX3)
|| pDeviceList->IsExtensionSupported(i, ADEXT_EAX4)
|| pDeviceList->IsExtensionSupported(i, ADEXT_EAX5) )
- {
+ {
providers[n - 1].bSupportsFx = true;
if ( n < MAXPROVIDERS )
- {
+ {
providers[n].id = pDeviceList->GetDeviceName(i);
strcpy(providers[n].name, "OPENAL SOFT EAX");
providers[n].sources = pDeviceList->GetMaxNumSources(i);
@@ -196,7 +197,7 @@ add_providers()
}
if ( n < MAXPROVIDERS )
- {
+ {
providers[n].id = pDeviceList->GetDeviceName(i);
strcpy(providers[n].name, "OPENAL SOFT EAX3");
providers[n].sources = pDeviceList->GetMaxNumSources(i);
@@ -210,7 +211,7 @@ add_providers()
for(int j=n;j<MAXPROVIDERS;j++)
SampleManager.Set3DProviderName(j, NULL);
-
+
// devices are gone now
//defaultProvider = pDeviceList->GetDefaultDevice();
//if ( defaultProvider > MAXPROVIDERS )
@@ -233,7 +234,7 @@ release_existing()
alAuxiliaryEffectSloti(ALEffectSlot, AL_EFFECTSLOT_EFFECT, AL_EFFECT_NULL);
}
}
-
+
DEV("release_existing()\n");
}
@@ -284,7 +285,7 @@ set_new_provider(int index)
}
//SampleManager.SetSpeakerConfig(speaker_type);
-
+
if ( IsFXSupported() )
{
for ( int32 i = 0; i < MAXCHANNELS; i++ )
@@ -300,7 +301,7 @@ set_new_provider(int index)
static bool8
IsThisTrackAt16KHz(uint32 track)
{
- return track == STREAMED_SOUND_RADIO_CHAT;
+ return track == STREAMED_SOUND_RADIO_KCHAT || track == STREAMED_SOUND_RADIO_VCPR || track == STREAMED_SOUND_RADIO_POLICE;
}
cSampleManager::cSampleManager(void)
@@ -365,6 +366,31 @@ int8 cSampleManager::SetCurrent3DProvider(uint8 nProvider)
return curprovider;
}
+int8
+cSampleManager::AutoDetect3DProviders()
+{
+ if (!AudioManager.IsAudioInitialised())
+ return -1;
+
+ if (defaultProvider >= 0 && defaultProvider < m_nNumberOfProviders) {
+ if (set_new_provider(defaultProvider))
+ return defaultProvider;
+ }
+
+ for (uint32 i = 0; i < GetNum3DProvidersAvailable(); i++)
+ {
+ char* providername = Get3DProviderName(i);
+
+ if (!strcasecmp(providername, "OPENAL SOFT")) {
+ SetCurrent3DProvider(i);
+ if (GetCurrent3DProviderIndex() == i)
+ return i;
+ }
+ }
+
+ return -1;
+}
+
static bool8
_ResolveLink(char const *path, char *out)
{
@@ -840,7 +866,7 @@ cSampleManager::Initialise(void)
alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
if ( alcIsExtensionPresent(ALDevice, (ALCchar*)ALC_EXT_EFX_NAME) )
- {
+ {
_effectsSupported = providers[index].bSupportsFx;
alGenAuxiliaryEffectSlots(1, &ALEffectSlot);
alGenEffects(1, &ALEffect);
@@ -849,14 +875,14 @@ cSampleManager::Initialise(void)
alGenSources(MAX_STREAMS*2, ALStreamSources[0]);
for ( int32 i = 0; i < MAX_STREAMS; i++ )
{
- alGenBuffers(NUM_STREAMBUFFERS, ALStreamBuffers[i]);
+ alGenBuffers(NUM_STREAMBUFFERS, ALStreamBuffers[i]);
alSourcei(ALStreamSources[i][0], AL_SOURCE_RELATIVE, AL_TRUE);
alSource3f(ALStreamSources[i][0], AL_POSITION, 0.0f, 0.0f, 0.0f);
alSourcef(ALStreamSources[i][0], AL_GAIN, 1.0f);
alSourcei(ALStreamSources[i][1], AL_SOURCE_RELATIVE, AL_TRUE);
alSource3f(ALStreamSources[i][1], AL_POSITION, 0.0f, 0.0f, 0.0f);
alSourcef(ALStreamSources[i][1], AL_GAIN, 1.0f);
- }
+ }
CChannel::InitChannels();
@@ -875,7 +901,7 @@ cSampleManager::Initialise(void)
aChannel[i].SetReverbMix(ALEffectSlot, 0.0f);
}
}
-
+
{
for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
nStreamLength[i] = 0;
@@ -894,14 +920,15 @@ cSampleManager::Initialise(void)
for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
{
- if(aStream[0] && (
+ if ( aStream[0] && (
#ifdef PS2_AUDIO_PATHS
aStream[0]->Open(PS2StreamedNameTable[i], IsThisTrackAt16KHz(i) ? 16000 : 32000) ||
#endif
- aStream[0]->Open(StreamedNameTable[i], IsThisTrackAt16KHz(i) ? 16000 : 32000)))
+ aStream[0]->Open(StreamedNameTable[i], IsThisTrackAt16KHz(i) ? 16000 : 32000)) )
{
uint32 tatalms = aStream[0]->GetLengthMS();
aStream[0]->Close();
+
nStreamLength[i] = tatalms;
} else
USERERROR("Can't open '%s'\n", StreamedNameTable[i]);
@@ -1035,7 +1062,7 @@ cSampleManager::Terminate(void)
for ( int32 i = 0; i < NUM_CHANNELS; i++ )
aChannel[i].Term();
-
+
if ( IsFXSupported() )
{
if ( alIsEffect(ALEffect) )
@@ -1053,7 +1080,7 @@ cSampleManager::Terminate(void)
ALEffectSlot = AL_EFFECTSLOT_NULL;
}
}
-
+
for ( int32 i = 0; i < MAX_STREAMS; i++ )
{
alDeleteBuffers(NUM_STREAMBUFFERS, ALStreamBuffers[i]);
@@ -1077,7 +1104,7 @@ cSampleManager::Terminate(void)
_fPrevEaxRatioDestination = 0.0f;
_usingEFX = false;
_fEffectsLevel = 0.0f;
-
+
_DeleteMP3Entries();
CStream::Terminate();
@@ -1140,6 +1167,12 @@ cSampleManager::SetMusicMasterVolume(uint8 nVolume)
}
void
+cSampleManager::SetMP3BoostVolume(uint8 nVolume)
+{
+ m_nMP3BoostVolume = nVolume;
+}
+
+void
cSampleManager::SetEffectsFadeVolume(uint8 nVolume)
{
m_nEffectsFadeVolume = nVolume;
@@ -1153,7 +1186,7 @@ cSampleManager::SetMusicFadeVolume(uint8 nVolume)
}
void
-cSampleManager::SetMonoMode(uint8 nMode)
+cSampleManager::SetMonoMode(bool8 nMode)
{
m_nMonoMode = nMode;
}
@@ -1275,14 +1308,6 @@ cSampleManager::LoadPedComment(uint32 nComment)
break;
}
-
- case MUSICMODE_FRONTEND:
- {
- if ( MusicManager.GetNextTrack() == STREAMED_SOUND_GAME_COMPLETED )
- return FALSE;
-
- break;
- }
}
}
@@ -1291,7 +1316,7 @@ cSampleManager::LoadPedComment(uint32 nComment)
int samplesSize = m_aSamples[nComment].nSize / 2;
op_pcm_seek(fpSampleDataHandle, m_aSamples[nComment].nOffset / 2);
while (samplesSize > 0) {
- int size = op_read(fpSampleDataHandle, (opus_int16 *)(nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] + PED_BLOCKSIZE * nCurrentPedSlot + samplesRead),
+ int size = op_read(fpSampleDataHandle, (opus_int16 *)(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] + PED_BLOCKSIZE * nCurrentPedSlot + samplesRead),
samplesSize, NULL);
if (size <= 0) {
return FALSE;
@@ -1362,24 +1387,24 @@ bool8 cSampleManager::UpdateReverb(void)
if ( AudioManager.m_FrameCounter & 15 )
return FALSE;
-
- float y = AudioManager.m_afReflectionsDistances[REFLECTION_TOP] + AudioManager.m_afReflectionsDistances[REFLECTION_BOTTOM];
- float x = AudioManager.m_afReflectionsDistances[REFLECTION_LEFT] + AudioManager.m_afReflectionsDistances[REFLECTION_RIGHT];
- float z = AudioManager.m_afReflectionsDistances[REFLECTION_UP];
-
- float normy = norm(y, 5.0f, 40.0f);
- float normx = norm(x, 5.0f, 40.0f);
- float normz = norm(z, 5.0f, 40.0f);
-
- #define ZR(v, a, b) (((v)==0)?(a):(b))
- #define CALCRATIO(x,y,z,min,max,val) (ZR(y, ZR(x, ZR(z, min, max), min), ZR(x, ZR(z, min, max), ZR(z, min, val))))
-
- float fRatio = CALCRATIO(normx, normy, normz, 0.3f, 0.5f, (normy+normx+normz)/3.0f);
-
- #undef CALCRATIO
- #undef ZR
+
+ float fRatio = 0.0f;
+
+#define MIN_DIST 0.5f
+#define CALCULATE_RATIO(value, maxDist, maxRatio) (value > MIN_DIST && value < maxDist ? value / maxDist * maxRatio : 0)
+
+ fRatio += CALCULATE_RATIO(AudioManager.m_afReflectionsDistances[REFLECTION_CEIL_NORTH], 10.0f, 1/2.f);
+ fRatio += CALCULATE_RATIO(AudioManager.m_afReflectionsDistances[REFLECTION_CEIL_SOUTH], 10.0f, 1/2.f);
+ fRatio += CALCULATE_RATIO(AudioManager.m_afReflectionsDistances[REFLECTION_CEIL_WEST], 10.0f, 1/2.f);
+ fRatio += CALCULATE_RATIO(AudioManager.m_afReflectionsDistances[REFLECTION_CEIL_EAST], 10.0f, 1/2.f);
+
+ fRatio += CALCULATE_RATIO((AudioManager.m_afReflectionsDistances[REFLECTION_NORTH] + AudioManager.m_afReflectionsDistances[REFLECTION_SOUTH]) / 2.f, 4.0f, 1/3.f);
+ fRatio += CALCULATE_RATIO((AudioManager.m_afReflectionsDistances[REFLECTION_WEST] + AudioManager.m_afReflectionsDistances[REFLECTION_EAST]) / 2.f, 4.0f, 1/3.f);
+
+#undef CALCULATE_RATIO
+#undef MIN_DIST
- fRatio = Clamp(fRatio, usingEAX3==1 ? 0.0f : 0.30f, 1.0f);
+ fRatio = Clamp(fRatio, 0.0f, 0.6f);
if ( fRatio == _fPrevEaxRatioDestination )
return FALSE;
@@ -1390,6 +1415,7 @@ bool8 cSampleManager::UpdateReverb(void)
if ( usingEAX3 )
#endif
{
+ fRatio = Min(fRatio * 1.67f, 1.0f);
if ( EAX3ListenerInterpolate(&StartEAX3, &FinishEAX3, fRatio, &EAX3Params, false) )
{
EAX_SetAll(&EAX3Params);
@@ -1404,16 +1430,17 @@ bool8 cSampleManager::UpdateReverb(void)
}
*/
- _fEffectsLevel = 1.0f - fRatio * 0.5f;
+ _fEffectsLevel = fRatio * 0.75f;
}
}
else
{
if ( _usingEFX )
- _fEffectsLevel = (1.0f - fRatio) * 0.4f;
+ _fEffectsLevel = fRatio * 0.8f;
else
- _fEffectsLevel = (1.0f - fRatio) * 0.7f;
+ _fEffectsLevel = fRatio * 0.22f;
}
+ _fEffectsLevel = Min(_fEffectsLevel, 1.0f);
_fPrevEaxRatioDestination = fRatio;
@@ -1490,12 +1517,11 @@ cSampleManager::SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume)
nChannelVolume[nChannel] = vol;
- // reduce channel volume when JB.MP3 or S4_BDBD.MP3 playing
- if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE
- && MusicManager.GetNextTrack() != STREAMED_SOUND_NEWS_INTRO
- && MusicManager.GetNextTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD )
- {
- nChannelVolume[nChannel] = vol / 4;
+ if (MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE ) {
+ if (MusicManager.GetCurrentTrack() == STREAMED_SOUND_CUTSCENE_FINALE)
+ nChannelVolume[nChannel] = 0;
+ else
+ nChannelVolume[nChannel] >>= 2;
}
// no idea, does this one looks like a bug or it's SetChannelVolume ?
@@ -1530,14 +1556,14 @@ cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume)
nChannelVolume[nChannel] = vol;
- // reduce the volume for JB.MP3 and S4_BDBD.MP3
- if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE
- && MusicManager.GetNextTrack() != STREAMED_SOUND_NEWS_INTRO
- && MusicManager.GetNextTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD )
- {
- nChannelVolume[nChannel] = vol / 4;
+ // increase the volume for JB.MP3 and S4_BDBD.MP3
+ if (MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE ) {
+ if (MusicManager.GetCurrentTrack() == STREAMED_SOUND_CUTSCENE_FINALE)
+ nChannelVolume[nChannel] = 0;
+ else
+ nChannelVolume[nChannel] >>= 2;
}
-
+
aChannel[nChannel].SetVolume(m_nEffectsFadeVolume*vol*m_nEffectsVolume >> 14);
}
}
@@ -1603,8 +1629,8 @@ cSampleManager::StopChannel(uint32 nChannel)
}
void
-cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream)
-{
+cSampleManager::PreloadStreamedFile(uint32 nFile, uint8 nStream)
+{
ASSERT( nStream < MAX_STREAMS );
if ( nFile < TOTAL_STREAMED_SOUNDS )
@@ -1612,7 +1638,6 @@ cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream)
CStream *stream = aStream[nStream];
stream->Close();
-
#ifdef PS2_AUDIO_PATHS
if(!stream->Open(PS2StreamedNameTable[nFile], IsThisTrackAt16KHz(nFile) ? 16000 : 32000))
#endif
@@ -1651,12 +1676,12 @@ cSampleManager::StartPreloadedStreamedFile(uint8 nStream)
}
bool8
-cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
+cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream)
{
int i = 0;
uint32 position = nPos;
char filename[MAX_PATH];
-
+
if ( nFile >= TOTAL_STREAMED_SOUNDS )
return FALSE;
@@ -1666,7 +1691,7 @@ cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
{
do
{
- // Switched to MP3 player just now
+ // Just switched to MP3 player
if ( !_bIsMp3Active && i == 0 )
{
if ( nPos > nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] )
@@ -1676,12 +1701,15 @@ cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
// Try to continue from previous song, if already started
if(!_GetMP3PosFromStreamPos(&position, &e) && !e) {
nFile = 0;
+
CStream *stream = aStream[nStream];
#ifdef PS2_AUDIO_PATHS
if(!stream->Open(PS2StreamedNameTable[nFile], IsThisTrackAt16KHz(nFile) ? 16000 : 32000))
#endif
stream->Open(StreamedNameTable[nFile], IsThisTrackAt16KHz(nFile) ? 16000 : 32000);
if ( stream->Setup() ) {
+ stream->SetLoopCount(nStreamLoopedFlag[nStream] ? 0 : 1);
+ nStreamLoopedFlag[nStream] = TRUE;
if (position != 0)
stream->SetPosMS(position);
@@ -1694,6 +1722,7 @@ cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
return FALSE;
} else {
+
if (e->pLinkPath != NULL)
aStream[nStream]->Open(e->pLinkPath, IsThisTrackAt16KHz(nFile) ? 16000 : 32000);
else {
@@ -1702,7 +1731,7 @@ cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
aStream[nStream]->Open(filename);
}
-
+
if (aStream[nStream]->Setup()) {
if (position != 0)
aStream[nStream]->SetPosMS(position);
@@ -1729,6 +1758,7 @@ cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
{
nFile = 0;
_bIsMp3Active = 0;
+
CStream *stream = aStream[nStream];
#ifdef PS2_AUDIO_PATHS
if(!stream->Open(PS2StreamedNameTable[nFile], IsThisTrackAt16KHz(nFile) ? 16000 : 32000))
@@ -1736,6 +1766,8 @@ cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
stream->Open(StreamedNameTable[nFile], IsThisTrackAt16KHz(nFile) ? 16000 : 32000);
if (stream->Setup()) {
+ stream->SetLoopCount(nStreamLoopedFlag[nStream] ? 0 : 1);
+ nStreamLoopedFlag[nStream] = TRUE;
if (position != 0)
stream->SetPosMS(position);
@@ -1753,6 +1785,7 @@ cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
else {
strcpy(filename, _mp3DirectoryPath);
strcat(filename, mp3->aFilename);
+
aStream[nStream]->Open(filename, IsThisTrackAt16KHz(nFile) ? 16000 : 32000);
}
@@ -1773,13 +1806,18 @@ cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
position = 0;
nFile = 0;
}
+ strcpy(filename, StreamedNameTable[nFile]);
+
CStream *stream = aStream[nStream];
+
#ifdef PS2_AUDIO_PATHS
if(!stream->Open(PS2StreamedNameTable[nFile], IsThisTrackAt16KHz(nFile) ? 16000 : 32000))
#endif
stream->Open(StreamedNameTable[nFile], IsThisTrackAt16KHz(nFile) ? 16000 : 32000);
if ( stream->Setup() ) {
+ stream->SetLoopCount(nStreamLoopedFlag[nStream] ? 0 : 1);
+ nStreamLoopedFlag[nStream] = TRUE;
if (position != 0)
stream->SetPosMS(position);
@@ -1835,15 +1873,20 @@ cSampleManager::GetStreamedFilePosition(uint8 nStream)
}
void
-cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream)
+cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, bool8 nEffectFlag, uint8 nStream)
{
ASSERT( nStream < MAX_STREAMS );
+ float boostMult = 0.0f;
+
if ( nVolume > MAX_VOLUME )
nVolume = MAX_VOLUME;
if ( nPan > MAX_VOLUME )
nPan = MAX_VOLUME;
+
+ if ( MusicManager.GetRadioInCar() == USERTRACK && !MusicManager.CheckForMusicInterruptions() )
+ boostMult = m_nMP3BoostVolume / 64.f;
nStreamVolume[nStream] = nVolume;
nStreamPan [nStream] = nPan;
@@ -1852,10 +1895,14 @@ cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffect
if ( stream->IsOpened() )
{
- if ( nEffectFlag )
- stream->SetVolume(m_nEffectsFadeVolume*nVolume*m_nEffectsVolume >> 14);
+ if ( nEffectFlag ) {
+ if ( nStream == 1 || nStream == 2 )
+ stream->SetVolume(128*nVolume*m_nEffectsVolume >> 14);
+ else
+ stream->SetVolume(m_nEffectsFadeVolume*nVolume*m_nEffectsVolume >> 14);
+ }
else
- stream->SetVolume(m_nMusicFadeVolume*nVolume*m_nMusicVolume >> 14);
+ stream->SetVolume((m_nMusicFadeVolume*nVolume*(uint32)(m_nMusicVolume * boostMult + m_nMusicVolume)) >> 14);
stream->SetPan(nPan);
}
@@ -1952,4 +1999,11 @@ cSampleManager::InitialiseSampleBanks(void)
return TRUE;
}
+
+void
+cSampleManager::SetStreamedFileLoopFlag(bool8 nLoopFlag, uint8 nChannel)
+{
+ nStreamLoopedFlag[nChannel] = nLoopFlag;
+}
+
#endif
diff --git a/src/audio/soundlist.h b/src/audio/soundlist.h
index 4bbc3dde..c6dbb634 100644
--- a/src/audio/soundlist.h
+++ b/src/audio/soundlist.h
@@ -16,8 +16,10 @@ enum eSound
SOUND_CAR_DOOR_OPEN_BACK_RIGHT,
SOUND_CAR_WINDSHIELD_CRACK,
SOUND_CAR_JUMP,
- SOUND_E,
- SOUND_F,
+ SOUND_CAR_JUMP_2,
+ SOUND_CAR_TYRE_POP,
+ SOUND_16,
+ SOUND_17,
SOUND_CAR_ENGINE_START,
SOUND_CAR_LIGHT_BREAK,
SOUND_CAR_HYDRAULIC_1,
@@ -31,29 +33,33 @@ enum eSound
SOUND_CAR_TANK_TURRET_ROTATE,
SOUND_CAR_BOMB_TICK,
SOUND_PLANE_ON_GROUND,
+ SOUND_HELI_BLADE,
+ SOUND_32,
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_FIGHT_37,
+ SOUND_FIGHT_38,
+ SOUND_FIGHT_39,
+ SOUND_FIGHT_40,
+ SOUND_FIGHT_41,
+ SOUND_FIGHT_42,
+ SOUND_FIGHT_43,
+ SOUND_FIGHT_44,
+ SOUND_FIGHT_45,
+ SOUND_FIGHT_46,
+ SOUND_FIGHT_47,
+ SOUND_FIGHT_48,
+ SOUND_49,
SOUND_WEAPON_BAT_ATTACK,
+ SOUND_WEAPON_KNIFE_ATTACK,
+ SOUND_WEAPON_CHAINSAW_IDLE,
+ SOUND_WEAPON_CHAINSAW_ATTACK,
+ SOUND_WEAPON_CHAINSAW_MADECONTACT,
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,
@@ -66,8 +72,8 @@ enum eSound
SOUND_GARAGE_BOMB1_SET,
SOUND_GARAGE_BOMB2_SET,
SOUND_GARAGE_BOMB3_SET,
- SOUND_40,
- SOUND_41,
+ SOUND_70,
+ SOUND_71,
SOUND_GARAGE_VEHICLE_DECLINED,
SOUND_GARAGE_VEHICLE_ACCEPTED,
SOUND_GARAGE_DOOR_CLOSED,
@@ -76,8 +82,8 @@ enum eSound
SOUND_PICKUP_WEAPON_BOUGHT,
SOUND_PICKUP_WEAPON,
SOUND_PICKUP_HEALTH,
- SOUND_PICKUP_ERROR,
- SOUND_4B,
+ SOUND_80,
+ SOUND_81,
SOUND_PICKUP_ADRENALINE,
SOUND_PICKUP_ARMOUR,
SOUND_PICKUP_BONUS,
@@ -87,7 +93,7 @@ enum eSound
SOUND_PICKUP_PACMAN_PACKAGE,
SOUND_PICKUP_FLOAT_PACKAGE,
SOUND_BOMB_TIMED_ACTIVATED,
- SOUND_55,
+ SOUND_91,
SOUND_BOMB_ONIGNITION_ACTIVATED,
SOUND_BOMB_TICK,
SOUND_RAMPAGE_START,
@@ -104,12 +110,16 @@ enum eSound
SOUND_PED_HIT,
SOUND_PED_LAND,
SOUND_PED_BULLET_HIT,
- SOUND_PED_BOMBER,
SOUND_PED_BURNING,
- SOUND_PED_ARREST_FBI,
- SOUND_PED_ARREST_SWAT,
+ SOUND_PED_PLAYER_REACTTOCOP,
SOUND_PED_ARREST_COP,
+ SOUND_PED_MIAMIVICE_EXITING_CAR,
+ SOUND_PED_COP_HELIPILOTPHRASE,
+ SOUND_PED_PULLOUTWEAPON,
SOUND_PED_HELI_PLAYER_FOUND,
+ SOUND_PED_VCPA_PLAYER_FOUND,
+ SOUND_PED_ON_FIRE,
+ SOUND_PED_AIMING,
SOUND_PED_HANDS_UP,
SOUND_PED_HANDS_COWER,
SOUND_PED_FLEE_SPRINT,
@@ -117,30 +127,40 @@ enum eSound
SOUND_PED_MUGGING,
SOUND_PED_CAR_JACKED,
SOUND_PED_ROBBED,
+ SOUND_PED_ACCIDENTREACTION1,
+ SOUND_PED_INNOCENT,
+ SOUND_PED_PLAYER_AFTERSEX,
+ SOUND_PED_PLAYER_BEFORESEX,
+ SOUND_PED_COP_TARGETING, // also used for medics
+ SOUND_PED_COP_MANYCOPSAROUND, // also used for medics
+ SOUND_PED_GUNAIMEDAT2,
+ SOUND_PED_COP_ALONE, // also used for medics
+ SOUND_PED_GUNAIMEDAT3,
+ SOUND_PED_COP_ASK_FOR_ID,
+ SOUND_PED_COP_LITTLECOPSAROUND, // also used for medics
+ SOUND_PED_PLAYER_FARFROMCOPS, // also used for medics
SOUND_PED_TAXI_WAIT,
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,
SOUND_PED_FLEE_RUN,
+ SOUND_PED_CRASH_VEHICLE,
+ SOUND_PED_CRASH_CAR,
SOUND_PED_ANNOYED_DRIVER,
+ SOUND_PED_147,
SOUND_PED_SOLICIT,
+ SOUND_PED_JEER,
+ SOUND_PED_150,
SOUND_PED_EXTINGUISHING_FIRE,
SOUND_PED_WAIT_DOUBLEBACK,
- SOUND_PED_CHAT_SEXY,
+ SOUND_PED_CHAT_SEXY_FEMALE,
+ SOUND_PED_CHAT_SEXY_MALE,
SOUND_PED_CHAT_EVENT,
+ SOUND_PED_PED_COLLISION,
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,
@@ -151,143 +171,101 @@ enum eSound
SOUND_CAR_PED_COLLISION,
SOUND_CLOCK_TICK,
SOUND_PART_MISSION_COMPLETE,
- SOUND_FRONTEND_MENU_STARTING,
- SOUND_FRONTEND_MENU_NEW_PAGE,
- SOUND_FRONTEND_MENU_NAVIGATION,
- SOUND_FRONTEND_MENU_SETTING_CHANGE,
- SOUND_FRONTEND_MENU_BACK,
- SOUND_FRONTEND_STEREO,
- SOUND_FRONTEND_MONO,
- SOUND_FRONTEND_AUDIO_TEST,
- SOUND_FRONTEND_FAIL,
- SOUND_FRONTEND_RADIO_TURN_OFF,
- SOUND_FRONTEND_RADIO_CHANGE,
+ SOUND_FRONTEND_MENU_STARTING, // same sound as SOUND_HUD
+
+ // TODO(Miami): What are 170-175??
+
+ SOUND_FRONTEND_RADIO_TURN_OFF = 176, // those 2 are same sound
+ SOUND_FRONTEND_RADIO_TURN_ON,
+ SOUND_FRONTEND_HURRICANE, // yes, frontend
SOUND_HUD,
- SOUND_AMMUNATION_WELCOME_1,
- SOUND_AMMUNATION_WELCOME_2,
- SOUND_AMMUNATION_WELCOME_3,
+ SOUND_180,
+ SOUND_181,
+ SOUND_182,
SOUND_LIGHTNING,
- SOUND_A5,
- SOUND_TOTAL_SOUNDS,
- SOUND_NO_SOUND,
+ SOUND_BULLETTRACE_1,
+ SOUND_BULLETTRACE_2,
+ SOUND_186, // makes same sound as 40
+ SOUND_187, // makes same sound as 46
+ SOUND_MELEE_ATTACK_START,
+ SOUND_SKATING,
+ SOUND_WEAPON_MINIGUN_ATTACK,
+ SOUND_WEAPON_MINIGUN_2,
+ SOUND_WEAPON_MINIGUN_3,
+ SOUND_AMMUNATION_IMRAN_ARM_BOMB,
+ SOUND_RADIO_CHANGE,
+ SOUND_FRONTEND_HIGHLIGHT_OPTION,
+ SOUND_FRONTEND_ENTER_OR_ADJUST,
+ SOUND_FRONTEND_BACK,
+ SOUND_FRONTEND_FAIL,
+ SOUND_FRONTEND_AUDIO_TEST,
+ SOUND_INJURED_PED_MALE_OUCH,
+ SOUND_INJURED_PED_FEMALE,
+ SOUND_SHIRT_WIND_FLAP,
+ SOUND_SET_203,
+ SOUND_TOTAL_SOUNDS = 204,
+ SOUND_NO_SOUND = 205,
};
enum eScriptSounds {
- SCRIPT_SOUND_0 = 0,
- 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_BANK_ALARM_LOOP = 0,
SCRIPT_SOUND_PART_MISSION_COMPLETE,
- SCRIPT_SOUND_CHUNKY_RUN_SHOUT,
- SCRIPT_SOUND_SECURITY_GUARD_AWAY_SHOUT,
+ SCRIPT_SOUND_POLICE_CELL_DOOR_SLIDING_LOOP,
+ SCRIPT_SOUND_POLICE_CELL_DOOR_CLUNK,
+ SCRIPT_SOUND_GARAGE_DOOR_SLIDING_LOOP,
+ SCRIPT_SOUND_GARAGE_DOOR_CLUNK,
+ SCRIPT_SOUND_SNORING_LOOP,
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_SHOOTING_RANGE_TARGET_MOVING_LOOP,
+ SCRIPT_SOUND_SHOOTING_RANGE_TARGET_HIT,
+ SCRIPT_SOUND_AMMUNATION_BUY_WEAPON,
+ SCRIPT_SOUND_AMMUNATION_BUY_WEAPON_DENIED,
+ SCRIPT_SOUND_WMYCW_TICKET_SPEECH,
+ SCRIPT_SOUND_IMRAN_ARM_BOMB,
+ SCRIPT_SOUND_ANDY_SNIPER_SHOT,
+ SCRIPT_SOUND_WILLIE_CARD_SWIPE,
+ SCRIPT_SOUND_MALE_AMBULANCE_OUCH,
+ SCRIPT_SOUND_FEMALE_AMBULANCE_OUCH,
+ SCRIPT_SOUND_BUILDING_BAR_1,
+ SCRIPT_SOUND_BUILDING_BAR_2,
+ SCRIPT_SOUND_BUILDING_BAR_3,
+ SCRIPT_SOUND_BUILDING_BAR_4,
+ SCRIPT_SOUND_BUILDING_BIKER_BAR,
+ SCRIPT_SOUND_BUILDING_CHURCH,
+ SCRIPT_SOUND_BUILDING_CLUB,
+ SCRIPT_SOUND_BUILDING_CUBA_1,
+ SCRIPT_SOUND_BUILDING_CUBA_2,
+ SCRIPT_SOUND_BUILDING_VOODOO,
+ SCRIPT_SOUND_BUILDING_MUSIC_SHOP,
+ SCRIPT_SOUND_BUILDING_STRIPCLUB_1,
+ SCRIPT_SOUND_BUILDING_STRIPCLUB_2,
+ SCRIPT_SOUND_BUILDING_SUPERSWEEP,
+ SCRIPT_SOUND_SEAPLANE_LOW_FUEL,
+ SCRIPT_SOUND_NEW_BUILDING_BAR_1,
+ SCRIPT_SOUND_NEW_BUILDING_BAR_2,
+ SCRIPT_SOUND_NEW_BUILDING_BAR_3,
+ SCRIPT_SOUND_NEW_BUILDING_BAR_4,
+ SCRIPT_SOUND_NEW_BUILDING_MALIBU_1,
+ SCRIPT_SOUND_NEW_BUILDING_MALIBU_2,
+ SCRIPT_SOUND_NEW_BUILDING_MALIBU_3,
+ SCRIPT_SOUND_NEW_BUILDING_STRIP_1,
+ SCRIPT_SOUND_NEW_BUILDING_STRIP_2,
+ SCRIPT_SOUND_NEW_BUILDING_STRIP_3,
+ SCRIPT_SOUND_NEW_BUILDING_CHURCH,
+ SCRIPT_SOUND_NEW_BUILDING_FAN_1,
+ SCRIPT_SOUND_NEW_BUILDING_FAN_2,
+ SCRIPT_SOUND_NEW_BUILDING_INSECT_1,
+ SCRIPT_SOUND_NEW_BUILDING_INSECT_2,
+ SCRIPT_SOUND_NEW_WATERFALL,
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_TRAIN_ANNOUNCEMENT_1,
- SCRIPT_SOUND_TRAIN_ANNOUNCEMENT_2,
SCRIPT_SOUND_PAYPHONE_RINGING,
- SCRIPT_SOUND_113,
SCRIPT_SOUND_GLASS_BREAK_L,
SCRIPT_SOUND_GLASS_BREAK_S,
SCRIPT_SOUND_GLASS_CRACK,
@@ -296,6 +274,7 @@ enum eScriptSounds {
SCRIPT_SOUND_BOX_DESTROYED_2,
SCRIPT_SOUND_METAL_COLLISION,
SCRIPT_SOUND_TIRE_COLLISION,
+ SCRIPT_SOUND_HIT_BALL,
SCRIPT_SOUND_GUNSHELL_DROP,
SCRIPT_SOUND_GUNSHELL_DROP_SOFT,
SCRIPT_SOUND_TOTAL,
diff --git a/src/buildings/Building.cpp b/src/buildings/Building.cpp
index e4475ae6..92c787e5 100644
--- a/src/buildings/Building.cpp
+++ b/src/buildings/Building.cpp
@@ -20,3 +20,25 @@ CBuilding::ReplaceWithNewModel(int32 id)
if(m_level == LEVEL_GENERIC || 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_NoFreeAssert((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_NoFreeAssert(pBuilding);
+#ifdef FIX_BUGS
+ return index >= 0 && index < CPools::GetBuildingPool()->GetSize();
+#else
+ return index >= 0 && index <= CPools::GetBuildingPool()->GetSize();
+#endif
+ }
+}
diff --git a/src/buildings/Building.h b/src/buildings/Building.h
index 94e66c89..f8ddfa46 100644
--- a/src/buildings/Building.h
+++ b/src/buildings/Building.h
@@ -17,5 +17,4 @@ public:
virtual bool GetIsATreadable(void) { return false; }
};
-VALIDATE_SIZE(CBuilding, 0x64);
-
+bool IsBuildingPointerValid(CBuilding*);
diff --git a/src/buildings/Treadable.h b/src/buildings/Treadable.h
index 9e895969..6a183c63 100644
--- a/src/buildings/Treadable.h
+++ b/src/buildings/Treadable.h
@@ -8,10 +8,5 @@ public:
static void *operator new(size_t) throw();
static void operator delete(void*, size_t) throw();
- int16 m_nodeIndices[2][12]; // first car, then ped
-
bool GetIsATreadable(void) { return true; }
};
-
-VALIDATE_SIZE(CTreadable, 0x94);
-
diff --git a/src/collision/ColBox.h b/src/collision/ColBox.h
index ac2cd675..0df55925 100644
--- a/src/collision/ColBox.h
+++ b/src/collision/ColBox.h
@@ -2,15 +2,21 @@
#include "SurfaceTable.h"
-struct CColBox
+struct CBox
{
CVector min;
CVector max;
+ CVector GetSize(void) { return max - min; }
+ void Set(const CVector &min, const CVector &max) { this->min = min; this->max = max; }
+};
+
+struct CColBox : public CBox
+{
uint8 surface;
uint8 piece;
- void Set(const CVector &min, const CVector &max, uint8 surf = SURFACE_DEFAULT, uint8 piece = 0);
- CVector GetSize(void) { return max - min; }
+ void Set(const CVector &min, const CVector &max, uint8 surf, uint8 piece);
+ using CBox::Set;
CColBox& operator=(const CColBox &other);
}; \ No newline at end of file
diff --git a/src/collision/ColModel.cpp b/src/collision/ColModel.cpp
index fb90e7dd..2224a804 100644
--- a/src/collision/ColModel.cpp
+++ b/src/collision/ColModel.cpp
@@ -1,7 +1,9 @@
#include "common.h"
#include "ColModel.h"
+#include "Collision.h"
#include "Game.h"
#include "MemoryHeap.h"
+#include "Pools.h"
CColModel::CColModel(void)
{
@@ -15,14 +17,27 @@ CColModel::CColModel(void)
vertices = nil;
triangles = nil;
trianglePlanes = nil;
- level = CGame::currLevel;
+ level = LEVEL_GENERIC; // generic col slot
ownsCollisionVolumes = true;
}
CColModel::~CColModel(void)
{
RemoveCollisionVolumes();
- RemoveTrianglePlanes();
+}
+
+void*
+CColModel::operator new(size_t) throw()
+{
+ CColModel* node = CPools::GetColModelPool()->New();
+ assert(node);
+ return node;
+}
+
+void
+CColModel::operator delete(void *p, size_t) throw()
+{
+ CPools::GetColModelPool()->Delete((CColModel*)p);
}
void
@@ -34,6 +49,7 @@ CColModel::RemoveCollisionVolumes(void)
RwFree(boxes);
RwFree(vertices);
RwFree(triangles);
+ CCollision::RemoveTrianglePlanes(this);
}
numSpheres = 0;
numLines = 0;
diff --git a/src/collision/ColModel.h b/src/collision/ColModel.h
index 7dcdfa4d..64f05f76 100644
--- a/src/collision/ColModel.h
+++ b/src/collision/ColModel.h
@@ -9,14 +9,14 @@
struct CColModel
{
- CColSphere boundingSphere;
- CColBox boundingBox;
+ CSphere boundingSphere;
+ CBox boundingBox;
int16 numSpheres;
- int16 numLines;
int16 numBoxes;
int16 numTriangles;
- int32 level;
- bool ownsCollisionVolumes; // missing on PS2
+ int8 numLines;
+ uint8 level; // colstore slot but probably still named level
+ bool ownsCollisionVolumes;
CColSphere *spheres;
CColLine *lines;
CColBox *boxes;
@@ -33,5 +33,7 @@ struct CColModel
void SetLinkPtr(CLink<CColModel*>*);
void GetTrianglePoint(CVector &v, int i) const;
+ void *operator new(size_t) throw();
+ void operator delete(void *p, size_t) throw();
CColModel& operator=(const CColModel& other);
}; \ No newline at end of file
diff --git a/src/collision/ColSphere.cpp b/src/collision/ColSphere.cpp
index 9aac01e0..65f02860 100644
--- a/src/collision/ColSphere.cpp
+++ b/src/collision/ColSphere.cpp
@@ -1,5 +1,6 @@
#include "common.h"
#include "ColSphere.h"
+#include "General.h"
void
CColSphere::Set(float radius, const CVector &center, uint8 surf, uint8 piece)
@@ -8,4 +9,19 @@ CColSphere::Set(float radius, const CVector &center, uint8 surf, uint8 piece)
this->center = center;
this->surface = surf;
this->piece = piece;
+}
+
+bool
+CColSphere::IntersectRay(CVector const& from, CVector const& dir, CVector &entry, CVector &exit)
+{
+ CVector distToCenter = from - center;
+ float distToTouchSqr = distToCenter.MagnitudeSqr() - sq(radius);
+ float root1, root2;
+
+ if (!CGeneral::SolveQuadratic(1.0f, DotProduct(distToCenter, dir) * 2.f, distToTouchSqr, root1, root2))
+ return false;
+
+ entry = from + dir * root1;
+ exit = from + dir * root2;
+ return true;
} \ No newline at end of file
diff --git a/src/collision/ColSphere.h b/src/collision/ColSphere.h
index 70e29763..f86b282a 100644
--- a/src/collision/ColSphere.h
+++ b/src/collision/ColSphere.h
@@ -2,12 +2,20 @@
#include "SurfaceTable.h"
-struct CColSphere
+struct CSphere
{
// NB: this has to be compatible with a CVuVector
CVector center;
float radius;
+ void Set(float radius, const CVector &center) { this->center = center; this->radius = radius; }
+};
+
+struct CColSphere : public CSphere
+{
uint8 surface;
uint8 piece;
- void Set(float radius, const CVector &center, uint8 surf = SURFACE_DEFAULT, uint8 piece = 0);
+
+ void Set(float radius, const CVector &center, uint8 surf, uint8 piece);
+ bool IntersectRay(CVector const &from, CVector const &dir, CVector &entry, CVector &exit);
+ using CSphere::Set;
}; \ No newline at end of file
diff --git a/src/collision/ColStore.cpp b/src/collision/ColStore.cpp
new file mode 100644
index 00000000..c74bf5ba
--- /dev/null
+++ b/src/collision/ColStore.cpp
@@ -0,0 +1,255 @@
+#include "common.h"
+
+#include "templates.h"
+#include "General.h"
+#include "ModelInfo.h"
+#include "Streaming.h"
+#include "FileLoader.h"
+#include "Script.h"
+#include "Timer.h"
+#include "Camera.h"
+#include "Frontend.h"
+#include "Physical.h"
+#include "ColStore.h"
+#include "VarConsole.h"
+#include "Pools.h"
+
+CPool<ColDef,ColDef> *CColStore::ms_pColPool;
+#ifndef MASTER
+bool bDispColInMem;
+#endif
+
+void
+CColStore::Initialise(void)
+{
+ if(ms_pColPool == nil)
+ ms_pColPool = new CPool<ColDef,ColDef>(COLSTORESIZE, "CollisionFiles");
+ AddColSlot("generic"); // slot 0. not streamed
+#ifndef MASTER
+ VarConsole.Add("Display collision in memory", &bDispColInMem, true);
+#endif
+}
+
+void
+CColStore::Shutdown(void)
+{
+ int i;
+ for(i = 0; i < COLSTORESIZE; i++)
+ RemoveColSlot(i);
+ if(ms_pColPool)
+ delete ms_pColPool;
+ ms_pColPool = nil;
+}
+
+int
+CColStore::AddColSlot(const char *name)
+{
+ ColDef *def = ms_pColPool->New();
+ assert(def);
+ def->isLoaded = false;
+ def->unused = 0;
+ def->bounds.left = 1000000.0f;
+ def->bounds.top = 1000000.0f;
+ def->bounds.right = -1000000.0f;
+ def->bounds.bottom = -1000000.0f;
+ def->minIndex = INT16_MAX;
+ def->maxIndex = INT16_MIN;
+ strcpy(def->name, name);
+ return ms_pColPool->GetJustIndex(def);
+}
+
+void
+CColStore::RemoveColSlot(int slot)
+{
+ if(GetSlot(slot)){
+ if(GetSlot(slot)->isLoaded)
+ RemoveCol(slot);
+ ms_pColPool->Delete(GetSlot(slot));
+ }
+}
+
+int
+CColStore::FindColSlot(const char *name)
+{
+ ColDef *def;
+ int size = ms_pColPool->GetSize();
+ for(int i = 0; i < size; i++){
+ def = GetSlot(i);
+ if(def && !CGeneral::faststricmp(def->name, name))
+ return i;
+ }
+ return -1;
+}
+
+char*
+CColStore::GetColName(int32 slot)
+{
+ return GetSlot(slot)->name;
+}
+
+CRect&
+CColStore::GetBoundingBox(int32 slot)
+{
+ return GetSlot(slot)->bounds;
+}
+
+void
+CColStore::IncludeModelIndex(int32 slot, int32 modelIndex)
+{
+ ColDef *def = GetSlot(slot);
+ if(modelIndex < def->minIndex)
+ def->minIndex = modelIndex;
+ if(modelIndex > def->maxIndex)
+ def->maxIndex = modelIndex;
+}
+
+bool
+CColStore::LoadCol(int32 slot, uint8 *buffer, int32 bufsize)
+{
+ bool success;
+ ColDef *def = GetSlot(slot);
+ if(def->minIndex > def->maxIndex)
+ success = CFileLoader::LoadCollisionFileFirstTime(buffer, bufsize, slot);
+ else
+ success = CFileLoader::LoadCollisionFile(buffer, bufsize, slot);
+ if(success)
+ def->isLoaded = true;
+ else
+ debug("Failed to load Collision\n");
+ return success;
+}
+
+void
+CColStore::RemoveCol(int32 slot)
+{
+ int id;
+ GetSlot(slot)->isLoaded = false;
+ for(id = 0; id < MODELINFOSIZE; id++){
+ CBaseModelInfo *mi = CModelInfo::GetModelInfo(id);
+ if(mi){
+ CColModel *col = mi->GetColModel();
+ if(col && col->level == slot)
+ col->RemoveCollisionVolumes();
+ }
+ }
+}
+
+void
+CColStore::LoadAllCollision(void)
+{
+ int i;
+ for(i = 1; i < COLSTORESIZE; i++)
+ if(GetSlot(i))
+ CStreaming::RequestCol(i, 0);
+
+ CStreaming::LoadAllRequestedModels(false);
+}
+
+void
+CColStore::RemoveAllCollision(void)
+{
+ int i;
+ for(i = 1; i < COLSTORESIZE; i++)
+ if(GetSlot(i))
+ if(CStreaming::CanRemoveCol(i))
+ CStreaming::RemoveCol(i);
+}
+
+static bool bLoadAtSecondPosition;
+static CVector2D secondPosition;
+
+void
+CColStore::AddCollisionNeededAtPosn(const CVector2D &pos)
+{
+ bLoadAtSecondPosition = true;
+ secondPosition = pos;
+}
+
+void
+CColStore::LoadCollision(const CVector2D &pos)
+{
+ int i;
+
+ if(CStreaming::ms_disableStreaming)
+ return;
+
+ for(i = 1; i < COLSTORESIZE; i++){
+ if(GetSlot(i) == nil)
+ continue;
+
+ bool wantThisOne = false;
+
+ if(GetBoundingBox(i).IsPointInside(pos) ||
+ bLoadAtSecondPosition && GetBoundingBox(i).IsPointInside(secondPosition, -119.0f) ||
+ strcmp(GetColName(i), "yacht") == 0){
+ wantThisOne = true;
+ }else{
+ for (int j = 0; j < MAX_CLEANUP; j++) {
+ CPhysical* pEntity = nil;
+ cleanup_entity_struct* pCleanup = &CTheScripts::MissionCleanUp.m_sEntities[j];
+ if (pCleanup->type == CLEANUP_CAR) {
+ pEntity = CPools::GetVehiclePool()->GetAt(pCleanup->id);
+ if (!pEntity || pEntity->GetStatus() == STATUS_WRECKED)
+ continue;
+ }
+ else if (pCleanup->type == CLEANUP_CHAR) {
+ pEntity = CPools::GetPedPool()->GetAt(pCleanup->id);
+ if (!pEntity || ((CPed*)pEntity)->DyingOrDead())
+ continue;
+ }
+ if (pEntity && !pEntity->bDontLoadCollision && !pEntity->bIsFrozen) {
+ if (GetBoundingBox(i).IsPointInside(pEntity->GetPosition(), -80.0f))
+ wantThisOne = true;
+ }
+ }
+ }
+
+ if(wantThisOne)
+ CStreaming::RequestCol(i, STREAMFLAGS_PRIORITY);
+ else
+ CStreaming::RemoveCol(i);
+ }
+ bLoadAtSecondPosition = false;
+}
+
+void
+CColStore::RequestCollision(const CVector2D &pos)
+{
+ int i;
+
+ for(i = 1; i < COLSTORESIZE; i++)
+ if(GetSlot(i) && GetBoundingBox(i).IsPointInside(pos, -115.0f))
+ CStreaming::RequestCol(i, STREAMFLAGS_PRIORITY);
+}
+
+void
+CColStore::EnsureCollisionIsInMemory(const CVector2D &pos)
+{
+ int i;
+
+ if(CStreaming::ms_disableStreaming)
+ return;
+
+ for(i = 1; i < COLSTORESIZE; i++)
+ if(GetSlot(i) && GetBoundingBox(i).IsPointInside(pos, -110.0f) &&
+ !CStreaming::HasColLoaded(i)){
+ CStreaming::RequestCol(i, 0);
+ if(TheCamera.GetScreenFadeStatus() == FADE_0)
+ FrontEndMenuManager.MessageScreen("LOADCOL", false);
+ CTimer::Suspend();
+ CStreaming::LoadAllRequestedModels(false);
+ CTimer::Resume();
+ }
+}
+
+bool
+CColStore::HasCollisionLoaded(const CVector2D &pos)
+{
+ int i;
+
+ for(i = 1; i < COLSTORESIZE; i++)
+ if(GetSlot(i) && GetBoundingBox(i).IsPointInside(pos, -115.0f) &&
+ !GetSlot(i)->isLoaded)
+ return false;
+ return true;
+}
diff --git a/src/collision/ColStore.h b/src/collision/ColStore.h
new file mode 100644
index 00000000..8e2a3a70
--- /dev/null
+++ b/src/collision/ColStore.h
@@ -0,0 +1,43 @@
+#pragma once
+
+#include "templates.h"
+
+struct ColDef { // made up name
+ int32 unused;
+ bool isLoaded;
+ CRect bounds;
+ char name[20];
+ int16 minIndex;
+ int16 maxIndex;
+};
+
+class CColStore
+{
+ static CPool<ColDef,ColDef> *ms_pColPool;
+
+public:
+ static void Initialise(void);
+ static void Shutdown(void);
+ static int AddColSlot(const char *name);
+ static void RemoveColSlot(int32 slot);
+ static int FindColSlot(const char *name);
+ static char *GetColName(int32 slot);
+ static CRect &GetBoundingBox(int32 slot);
+ static void IncludeModelIndex(int32 slot, int32 modelIndex);
+ static bool LoadCol(int32 storeID, uint8 *buffer, int32 bufsize);
+ static void RemoveCol(int32 slot);
+ static void AddCollisionNeededAtPosn(const CVector2D &pos);
+ static void LoadAllCollision(void);
+ static void RemoveAllCollision(void);
+ static void LoadCollision(const CVector2D &pos);
+ static void RequestCollision(const CVector2D &pos);
+ static void EnsureCollisionIsInMemory(const CVector2D &pos);
+ static bool HasCollisionLoaded(const CVector2D &pos);
+
+ static ColDef *GetSlot(int slot) {
+ assert(slot >= 0);
+ assert(ms_pColPool);
+ assert(slot < ms_pColPool->GetSize());
+ return ms_pColPool->GetSlot(slot);
+ }
+};
diff --git a/src/collision/ColTriangle.cpp b/src/collision/ColTriangle.cpp
index 9120fcff..843fb93f 100644
--- a/src/collision/ColTriangle.cpp
+++ b/src/collision/ColTriangle.cpp
@@ -1,15 +1,6 @@
#include "common.h"
#include "ColTriangle.h"
-void
-CColTriangle::Set(const CompressedVector *, int a, int b, int c, uint8 surf, uint8 piece)
-{
- this->a = a;
- this->b = b;
- this->c = c;
- this->surface = surf;
-}
-
#ifdef VU_COLLISION
void
CColTrianglePlane::Set(const CVector &va, const CVector &vb, const CVector &vc)
diff --git a/src/collision/ColTriangle.h b/src/collision/ColTriangle.h
index 9e918e38..a2580c58 100644
--- a/src/collision/ColTriangle.h
+++ b/src/collision/ColTriangle.h
@@ -18,7 +18,13 @@ struct CColTriangle
uint16 c;
uint8 surface;
- void Set(const CompressedVector *v, int a, int b, int c, uint8 surf, uint8 piece);
+ void Set(int a, int b, int c, uint8 surf)
+ {
+ this->a = a;
+ this->b = b;
+ this->c = c;
+ this->surface = surf;
+ }
};
struct CColTrianglePlane
@@ -63,6 +69,9 @@ struct CColTrianglePlane
void Set(const CVector &va, const CVector &vb, const CVector &vc);
void Set(const CompressedVector *v, CColTriangle &tri) { Set(v[tri.a].Get(), v[tri.b].Get(), v[tri.c].Get()); }
void GetNormal(CVector &n) const { n = normal; }
+ float GetNormalX() const { return normal.x; }
+ float GetNormalY() const { return normal.y; }
+ float GetNormalZ() const { return normal.z; }
float CalcPoint(const CVector &v) const { return DotProduct(normal, v) - dist; };
#endif
}; \ No newline at end of file
diff --git a/src/collision/Collision.cpp b/src/collision/Collision.cpp
index 832d773e..f39f3f35 100644
--- a/src/collision/Collision.cpp
+++ b/src/collision/Collision.cpp
@@ -21,7 +21,8 @@
#include "SurfaceTable.h"
#include "Lines.h"
#include "Collision.h"
-#include "Frontend.h"
+#include "Camera.h"
+#include "ColStore.h"
#ifdef VU_COLLISION
#include "VuCollision.h"
@@ -75,52 +76,22 @@ CCollision::Init(void)
{
ms_colModelCache.Init(NUMCOLCACHELINKS);
ms_collisionInMemory = LEVEL_GENERIC;
+ CColStore::Initialise();
}
void
CCollision::Shutdown(void)
{
ms_colModelCache.Shutdown();
+ CColStore::Shutdown();
}
void
CCollision::Update(void)
{
- CVector playerCoors;
- playerCoors = FindPlayerCoors();
- eLevelName level = CTheZones::m_CurrLevel;
- bool forceLevelChange = false;
-
- if(CTimer::GetTimeInMilliseconds() < 2000 || CCutsceneMgr::IsCutsceneProcessing())
- return;
-
- // hardcode a level if there are no zones
- if(level == LEVEL_GENERIC){
- if(CGame::currLevel == LEVEL_INDUSTRIAL &&
- playerCoors.x < 400.0f){
- level = LEVEL_COMMERCIAL;
- forceLevelChange = true;
- }else if(CGame::currLevel == LEVEL_SUBURBAN &&
- playerCoors.x > -450.0f && playerCoors.y < -1400.0f){
- level = LEVEL_COMMERCIAL;
- forceLevelChange = true;
- }else{
- if(playerCoors.x > 800.0f){
- level = LEVEL_INDUSTRIAL;
- forceLevelChange = true;
- }else if(playerCoors.x < -800.0f){
- level = LEVEL_SUBURBAN;
- forceLevelChange = true;
- }
- }
- }
- if(level != LEVEL_GENERIC && level != CGame::currLevel)
- CGame::currLevel = level;
- if(ms_collisionInMemory != CGame::currLevel)
- LoadCollisionWhenINeedIt(forceLevelChange);
- CStreaming::HaveAllBigBuildingsLoaded(CGame::currLevel);
}
+// unused
eLevelName
GetCollisionInSectorList(CPtrList &list)
{
@@ -137,6 +108,7 @@ GetCollisionInSectorList(CPtrList &list)
return LEVEL_GENERIC;
}
+// unused
// Get a level this sector is in based on collision models
eLevelName
GetCollisionInSector(CSector &sect)
@@ -160,165 +132,22 @@ GetCollisionInSector(CSector &sect)
void
CCollision::LoadCollisionWhenINeedIt(bool forceChange)
{
- eLevelName level, l;
- bool multipleLevels;
- CVector playerCoors;
- CVehicle *veh;
- CEntryInfoNode *ei;
- int sx, sy;
- int xmin, xmax, ymin, ymax;
- int x, y;
-
- level = LEVEL_GENERIC;
-
- playerCoors = FindPlayerCoors();
- sx = CWorld::GetSectorIndexX(playerCoors.x);
- sy = CWorld::GetSectorIndexY(playerCoors.y);
- multipleLevels = false;
-
- veh = FindPlayerVehicle();
- if(veh && veh->IsTrain()){
- if(((CTrain*)veh)->m_nDoorState != TRAIN_DOOR_OPEN)
- return;
- }else if(playerCoors.z < -4.0f && !CCullZones::DoINeedToLoadCollision())
- return;
-
- // Figure out whose level's collisions we're most likely to be interested in
- if(!forceChange){
- if(veh && veh->IsBoat()){
- // on water we expect to be between levels
- multipleLevels = true;
- }else{
- xmin = Max(sx - 1, 0);
- xmax = Min(sx + 1, NUMSECTORS_X-1);
- ymin = Max(sy - 1, 0);
- ymax = Min(sy + 1, NUMSECTORS_Y-1);
-
- for(x = xmin; x <= xmax; x++)
- for(y = ymin; y <= ymax; y++){
- l = GetCollisionInSector(*CWorld::GetSector(x, y));
- if(l != LEVEL_GENERIC){
- if(level == LEVEL_GENERIC)
- level = l;
- if(level != l)
- multipleLevels = true;
- }
- }
- }
-
- if(multipleLevels && veh && veh->IsBoat())
- for(ei = veh->m_entryInfoList.first; ei; ei = ei->next){
- level = GetCollisionInSector(*ei->sector);
- if(level != LEVEL_GENERIC)
- break;
- }
- }
-
- if (level == CGame::currLevel || forceChange) {
-#ifdef FIX_BUGS
- CTimer::Suspend();
-#else
- CTimer::Stop();
-#endif
- ISLAND_LOADING_IS(LOW)
- {
- DMAudio.SetEffectsFadeVol(0);
- CPad::StopPadsShaking();
- LoadCollisionScreen(CGame::currLevel);
- DMAudio.Service();
- }
-
- CPopulation::DealWithZoneChange(ms_collisionInMemory, CGame::currLevel, false);
-
- ISLAND_LOADING_ISNT(HIGH)
- {
- CStreaming::RemoveIslandsNotUsed(LEVEL_INDUSTRIAL);
- CStreaming::RemoveIslandsNotUsed(LEVEL_COMMERCIAL);
- CStreaming::RemoveIslandsNotUsed(LEVEL_SUBURBAN);
- }
- ISLAND_LOADING_IS(LOW)
- {
- CStreaming::RemoveBigBuildings(LEVEL_INDUSTRIAL);
- CStreaming::RemoveBigBuildings(LEVEL_COMMERCIAL);
- CStreaming::RemoveBigBuildings(LEVEL_SUBURBAN);
- CModelInfo::RemoveColModelsFromOtherLevels(CGame::currLevel);
- CStreaming::RemoveUnusedModelsInLoadedList();
- CGame::TidyUpMemory(true, true);
- CFileLoader::LoadCollisionFromDatFile(CGame::currLevel);
- }
-
- ms_collisionInMemory = CGame::currLevel;
- CReplay::EmptyReplayBuffer();
- ISLAND_LOADING_IS(LOW)
- {
- if (CGame::currLevel != LEVEL_GENERIC)
- LoadSplash(GetLevelSplashScreen(CGame::currLevel));
- CStreaming::RemoveUnusedBigBuildings(CGame::currLevel);
- CStreaming::RemoveUnusedBuildings(CGame::currLevel);
- CStreaming::RequestBigBuildings(CGame::currLevel);
- }
-#ifdef NO_ISLAND_LOADING
- else if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_MEDIUM)
- CStreaming::RequestIslands(CGame::currLevel);
-#endif
- CStreaming::LoadAllRequestedModels(true);
-
- ISLAND_LOADING_IS(LOW)
- {
- CStreaming::HaveAllBigBuildingsLoaded(CGame::currLevel);
-
- CGame::TidyUpMemory(true, true);
- }
-#ifdef FIX_BUGS
- CTimer::Resume();
-#else
- CTimer::Update();
-#endif
- ISLAND_LOADING_IS(LOW)
- DMAudio.SetEffectsFadeVol(127);
- }
}
-#ifdef NO_ISLAND_LOADING
-bool CCollision::bAlreadyLoaded = false;
-#endif
void
CCollision::SortOutCollisionAfterLoad(void)
{
- if(ms_collisionInMemory == CGame::currLevel)
- return;
- ISLAND_LOADING_IS(LOW)
- CModelInfo::RemoveColModelsFromOtherLevels(CGame::currLevel);
-
- if (CGame::currLevel != LEVEL_GENERIC) {
-#ifdef NO_ISLAND_LOADING
- if (CMenuManager::m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_LOW) {
- if (bAlreadyLoaded) {
- ms_collisionInMemory = CGame::currLevel;
- return;
- }
- bAlreadyLoaded = true;
- CFileLoader::LoadCollisionFromDatFile(LEVEL_INDUSTRIAL);
- CFileLoader::LoadCollisionFromDatFile(LEVEL_COMMERCIAL);
- CFileLoader::LoadCollisionFromDatFile(LEVEL_SUBURBAN);
- } else
-#endif
- CFileLoader::LoadCollisionFromDatFile(CGame::currLevel);
- if(!CGame::playingIntro)
- LoadSplash(GetLevelSplashScreen(CGame::currLevel));
- }
- ms_collisionInMemory = CGame::currLevel;
- CGame::TidyUpMemory(true, false);
+ CColStore::LoadCollision(TheCamera.GetPosition());
+ CStreaming::LoadAllRequestedModels(false);
}
void
CCollision::LoadCollisionScreen(eLevelName level)
{
- static Const char *levelNames[4] = {
+ static Const char *levelNames[] = {
"",
"IND_ZON",
"COM_ZON",
- "SUB_ZON"
};
// Why twice?
@@ -332,14 +161,14 @@ CCollision::LoadCollisionScreen(eLevelName level)
bool
-CCollision::TestSphereSphere(const CColSphere &s1, const CColSphere &s2)
+CCollision::TestSphereSphere(const CSphere &s1, const CSphere &s2)
{
float d = s1.radius + s2.radius;
return (s1.center - s2.center).MagnitudeSqr() < d*d;
}
bool
-CCollision::TestSphereBox(const CColSphere &sph, const CColBox &box)
+CCollision::TestSphereBox(const CSphere &sph, const CBox &box)
{
if(sph.center.x + sph.radius < box.min.x) return false;
if(sph.center.x - sph.radius > box.max.x) return false;
@@ -351,7 +180,7 @@ CCollision::TestSphereBox(const CColSphere &sph, const CColBox &box)
}
bool
-CCollision::TestLineBox(const CColLine &line, const CColBox &box)
+CCollision::TestLineBox(const CColLine &line, const CBox &box)
{
float t, x, y, z;
// If either line point is in the box, we have a collision
@@ -436,7 +265,7 @@ CCollision::TestLineBox(const CColLine &line, const CColBox &box)
}
bool
-CCollision::TestVerticalLineBox(const CColLine &line, const CColBox &box)
+CCollision::TestVerticalLineBox(const CColLine &line, const CBox &box)
{
if(line.p0.x <= box.min.x) return false;
if(line.p0.y <= box.min.y) return false;
@@ -636,6 +465,8 @@ CCollision::TestSphereTriangle(const CColSphere &sphere,
int testcase = insideAB + insideAC + insideBC;
float dist = 0.0f;
switch(testcase){
+ case 0:
+ return false; // shouldn't happen
case 1:
// closest to a vertex
if(insideAB) dist = (sphere.center - vc).Magnitude();
@@ -664,7 +495,7 @@ CCollision::TestSphereTriangle(const CColSphere &sphere,
}
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)
{
#ifdef VU_COLLISION
CMatrix matTransform;
@@ -681,12 +512,14 @@ CCollision::TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColMod
for(i = 0; i < model.numSpheres; i++){
if(ignoreSeeThrough && IsSeeThrough(model.spheres[i].surface)) continue;
+ if(ignoreShootThrough && IsShootThrough(model.spheres[i].surface)) continue;
if(TestLineSphere(*(CColLine*)newline, model.spheres[i]))
return true;
}
for(i = 0; i < model.numBoxes; i++){
if(ignoreSeeThrough && IsSeeThrough(model.boxes[i].surface)) continue;
+ if(ignoreShootThrough && IsShootThrough(model.boxes[i].surface)) continue;
if(TestLineBox(*(CColLine*)newline, model.boxes[i]))
return true;
}
@@ -696,6 +529,7 @@ CCollision::TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColMod
VuTriangle vutri;
for(i = 0; i < model.numTriangles; i++){
if(ignoreSeeThrough && IsSeeThrough(model.triangles[i].surface)) continue;
+ if(ignoreShootThrough && IsShootThrough(model.triangles[i].surface)) continue;
CColTriangle *tri = &model.triangles[i];
model.vertices[tri->a].Unpack(vutri.v0);
@@ -713,6 +547,7 @@ CCollision::TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColMod
#endif
for(; i < model.numTriangles; i++){
if(ignoreSeeThrough && IsSeeThrough(model.triangles[i].surface)) continue;
+ if(ignoreShootThrough && IsShootThrough(model.triangles[i].surface)) continue;
CColTriangle *tri = &model.triangles[i];
model.vertices[tri->a].Unpack(vutri.v0);
@@ -745,12 +580,14 @@ CCollision::TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColMod
for(i = 0; i < model.numSpheres; i++){
if(ignoreSeeThrough && IsSeeThrough(model.spheres[i].surface)) continue;
+ if(ignoreShootThrough && IsShootThrough(model.spheres[i].surface)) continue;
if(TestLineSphere(newline, model.spheres[i]))
return true;
}
for(i = 0; i < model.numBoxes; i++){
if(ignoreSeeThrough && IsSeeThrough(model.boxes[i].surface)) continue;
+ if(ignoreShootThrough && IsShootThrough(model.boxes[i].surface)) continue;
if(TestLineBox(newline, model.boxes[i]))
return true;
}
@@ -758,6 +595,7 @@ CCollision::TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColMod
CalculateTrianglePlanes(&model);
for(i = 0; i < model.numTriangles; i++){
if(ignoreSeeThrough && IsSeeThrough(model.triangles[i].surface)) continue;
+ if(ignoreShootThrough && IsShootThrough(model.triangles[i].surface)) continue;
if(TestLineTriangle(newline, model.vertices, model.triangles[i], model.trianglePlanes[i]))
return true;
}
@@ -766,6 +604,7 @@ CCollision::TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColMod
#endif
}
+// TODO: TestPillWithSpheresInColModel, but only called from overloaded CWeapon::FireMelee which isn't used
//
// Process
@@ -1046,6 +885,7 @@ CCollision::ProcessLineSphere(const CColLine &line, const CColSphere &sphere, CC
return true;
}
+// unused
bool
CCollision::ProcessVerticalLineTriangle(const CColLine &line,
const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane,
@@ -1262,7 +1102,7 @@ CCollision::IsStoredPolyStillValidVerticalLine(const CVector &pos, float z, CCol
bool
CCollision::ProcessLineTriangle(const CColLine &line,
const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane,
- CColPoint &point, float &mindist)
+ CColPoint &point, float &mindist, CStoredCollPoly *poly)
{
#ifdef VU_COLLISION
// not used in favour of optimized loops
@@ -1366,6 +1206,12 @@ CCollision::ProcessLineTriangle(const CColLine &line,
point.pieceA = 0;
point.surfaceB = tri.surface;
point.pieceB = 0;
+ if(poly){
+ poly->verts[0] = va;
+ poly->verts[1] = vb;
+ poly->verts[2] = vc;
+ poly->valid = true;
+ }
mindist = t;
return true;
#endif
@@ -1436,6 +1282,8 @@ CCollision::ProcessSphereTriangle(const CColSphere &sphere,
float dist = 0.0f;
CVector p;
switch(testcase){
+ case 0:
+ return false; // shouldn't happen
case 1:
// closest to a vertex
if(insideAB) p = vc;
@@ -1482,7 +1330,7 @@ CCollision::ProcessSphereTriangle(const CColSphere &sphere,
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)
{
#ifdef VU_COLLISION
CMatrix matTransform;
@@ -1503,6 +1351,7 @@ CCollision::ProcessLineOfSight(const CColLine &line,
float coldist = 1.0f;
for(i = 0; i < model.numSpheres; i++){
if(ignoreSeeThrough && IsSeeThrough(model.spheres[i].surface)) continue;
+ if(ignoreShootThrough && IsShootThrough(model.spheres[i].surface)) continue;
if(ProcessLineSphere(*(CColLine*)newline, model.spheres[i], point, coldist))
point.Set(0, 0, model.spheres[i].surface, model.spheres[i].piece);
}
@@ -1518,6 +1367,7 @@ CCollision::ProcessLineOfSight(const CColLine &line,
CColTriangle *lasttri = nil;
for(i = 0; i < model.numTriangles; i++){
if(ignoreSeeThrough && IsSeeThrough(model.triangles[i].surface)) continue;
+ if(ignoreShootThrough && IsShootThrough(model.triangles[i].surface)) continue;
CColTriangle *tri = &model.triangles[i];
model.vertices[tri->a].Unpack(vutri.v0);
@@ -1537,6 +1387,7 @@ CCollision::ProcessLineOfSight(const CColLine &line,
float dist;
for(; i < model.numTriangles; i++){
if(ignoreSeeThrough && IsSeeThrough(model.triangles[i].surface)) continue;
+ if(ignoreShootThrough && IsShootThrough(model.triangles[i].surface)) continue;
CColTriangle *tri = &model.triangles[i];
model.vertices[tri->a].Unpack(vutri.v0);
@@ -1586,17 +1437,20 @@ CCollision::ProcessLineOfSight(const CColLine &line,
float coldist = mindist;
for(i = 0; i < model.numSpheres; i++){
if(ignoreSeeThrough && IsSeeThrough(model.spheres[i].surface)) continue;
+ if(ignoreShootThrough && IsShootThrough(model.spheres[i].surface)) continue;
ProcessLineSphere(newline, model.spheres[i], point, coldist);
}
for(i = 0; i < model.numBoxes; i++){
if(ignoreSeeThrough && IsSeeThrough(model.boxes[i].surface)) continue;
+ if(ignoreShootThrough && IsShootThrough(model.boxes[i].surface)) continue;
ProcessLineBox(newline, model.boxes[i], point, coldist);
}
CalculateTrianglePlanes(&model);
for(i = 0; i < model.numTriangles; i++){
if(ignoreSeeThrough && IsSeeThrough(model.triangles[i].surface)) continue;
+ if(ignoreShootThrough && IsShootThrough(model.triangles[i].surface)) continue;
ProcessLineTriangle(newline, model.vertices, model.triangles[i], model.trianglePlanes[i], point, coldist);
}
@@ -1613,7 +1467,7 @@ CCollision::ProcessLineOfSight(const CColLine &line,
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)
{
#ifdef VU_COLLISION
static CStoredCollPoly TempStoredPoly;
@@ -1633,13 +1487,13 @@ CCollision::ProcessVerticalLine(const CColLine &line,
float coldist = 1.0f;
for(i = 0; i < model.numSpheres; i++){
- if(ignoreSeeThrough && IsSeeThrough(model.spheres[i].surface)) continue;
+ if(ignoreSeeThrough && IsSeeThroughVertical(model.spheres[i].surface)) continue;
if(ProcessLineSphere(*(CColLine*)newline, model.spheres[i], point, coldist))
point.Set(0, 0, model.spheres[i].surface, model.spheres[i].piece);
}
for(i = 0; i < model.numBoxes; i++){
- if(ignoreSeeThrough && IsSeeThrough(model.boxes[i].surface)) continue;
+ if(ignoreSeeThrough && IsSeeThroughVertical(model.boxes[i].surface)) continue;
if(ProcessLineBox(*(CColLine*)newline, model.boxes[i], point, coldist))
point.Set(0, 0, model.boxes[i].surface, model.boxes[i].piece);
}
@@ -1651,7 +1505,7 @@ CCollision::ProcessVerticalLine(const CColLine &line,
CColTriangle *lasttri = nil;
VuTriangle vutri;
for(i = 0; i < model.numTriangles; i++){
- if(ignoreSeeThrough && IsSeeThrough(model.triangles[i].surface)) continue;
+ if(ignoreSeeThrough && IsSeeThroughVertical(model.triangles[i].surface)) continue;
CColTriangle *tri = &model.triangles[i];
model.vertices[tri->a].Unpack(vutri.v0);
@@ -1670,7 +1524,7 @@ CCollision::ProcessVerticalLine(const CColLine &line,
CVuVector pnt, normal;
float dist;
for(; i < model.numTriangles; i++){
- if(ignoreSeeThrough && IsSeeThrough(model.triangles[i].surface)) continue;
+ if(ignoreSeeThrough && IsSeeThroughVertical(model.triangles[i].surface)) continue;
CColTriangle *tri = &model.triangles[i];
model.vertices[tri->a].Unpack(vutri.v0);
@@ -1740,28 +1594,27 @@ CCollision::ProcessVerticalLine(const CColLine &line,
// transform line to model space
// Why does the game seem to do this differently than above?
CColLine newline(MultiplyInverse(matrix, line.p0), MultiplyInverse(matrix, line.p1));
- newline.p1.x = newline.p0.x;
- newline.p1.y = newline.p0.y;
- if(!TestVerticalLineBox(newline, model.boundingBox))
+ if(!TestLineBox(newline, model.boundingBox))
return false;
+ // BUG? is IsSeeThroughVertical really the right thing? also not checking shoot through
float coldist = mindist;
for(i = 0; i < model.numSpheres; i++){
- if(ignoreSeeThrough && IsSeeThrough(model.spheres[i].surface)) continue;
+ if(ignoreSeeThrough && IsSeeThroughVertical(model.spheres[i].surface)) continue;
ProcessLineSphere(newline, model.spheres[i], point, coldist);
}
for(i = 0; i < model.numBoxes; i++){
- if(ignoreSeeThrough && IsSeeThrough(model.boxes[i].surface)) continue;
+ if(ignoreSeeThrough && IsSeeThroughVertical(model.boxes[i].surface)) continue;
ProcessLineBox(newline, model.boxes[i], point, coldist);
}
CalculateTrianglePlanes(&model);
TempStoredPoly.valid = false;
for(i = 0; i < model.numTriangles; i++){
- if(ignoreSeeThrough && IsSeeThrough(model.triangles[i].surface)) continue;
- ProcessVerticalLineTriangle(newline, model.vertices, model.triangles[i], model.trianglePlanes[i], point, coldist, &TempStoredPoly);
+ if(ignoreSeeThrough && IsSeeThroughVertical(model.triangles[i].surface)) continue;
+ ProcessLineTriangle(newline, model.vertices, model.triangles[i], model.trianglePlanes[i], point, coldist, &TempStoredPoly);
}
if(coldist < mindist){
@@ -2319,6 +2172,15 @@ CCollision::CalculateTrianglePlanes(CColModel *model)
}
void
+CCollision::RemoveTrianglePlanes(CColModel *model)
+{
+ if(model->trianglePlanes){
+ ms_colModelCache.Remove(model->GetLinkPtr());
+ model->RemoveTrianglePlanes();
+ }
+}
+
+void
CCollision::DrawColModel(const CMatrix &mat, const CColModel &colModel)
{
int i;
@@ -2540,15 +2402,75 @@ CCollision::DrawColModel(const CMatrix &mat, const CColModel &colModel)
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
}
+static void
+GetSurfaceColor(uint8 surf, uint8 &r, uint8 &g, uint8 &b)
+{
+ // game doesn't do this
+ r = 255;
+ g = 128;
+ b = 0;
+
+ switch(CSurfaceTable::GetAdhesionGroup(surf)){
+ case ADHESIVE_RUBBER:
+ r = 255;
+ g = 0;
+ b = 0;
+ break;
+ case ADHESIVE_HARD:
+ r = 255;
+ g = 255;
+ b = 128;
+ break;
+ case ADHESIVE_ROAD:
+ r = 128;
+ g = 128;
+ b = 128;
+ break;
+ case ADHESIVE_LOOSE:
+ r = 0;
+ g = 255;
+ b = 0;
+ break;
+ case ADHESIVE_SAND:
+ r = 255;
+ g = 128;
+ b = 128;
+ break;
+ case ADHESIVE_WET:
+ r = 0;
+ g = 0;
+ b = 255;
+ break;
+ }
+
+ if(surf == SURFACE_SAND || surf == SURFACE_SAND_BEACH){
+ r = 255;
+ g = 255;
+ b = 0;
+ }
+
+ float f = (surf & 0xF)/32.0f + 0.5f;
+ r *= f;
+ g *= f;
+ b *= f;
+
+ if(surf == SURFACE_TRANSPARENT_CLOTH || surf == SURFACE_METAL_CHAIN_FENCE ||
+ surf == SURFACE_TRANSPARENT_STONE || surf == SURFACE_SCAFFOLD_POLE)
+ if(CTimer::GetFrameCounter() & 1){
+ r = 0;
+ g = 0;
+ b = 0;
+ }
+}
+
void
CCollision::DrawColModel_Coloured(const CMatrix &mat, const CColModel &colModel, int32 id)
{
int i;
int s;
- float f;
CVector verts[8];
CVector min, max;
- int r, g, b;
+ uint8 r, g, b;
RwImVertexIndex *iptr;
RwIm3DVertex *vptr;
@@ -2567,53 +2489,8 @@ CCollision::DrawColModel_Coloured(const CMatrix &mat, const CColModel &colModel,
verts[1] = mat * verts[1];
verts[2] = mat * verts[2];
- // game doesn't do this
- r = 255;
- g = 128;
- b = 0;
-
s = colModel.triangles[i].surface;
- f = (s & 0xF)/32.0f + 0.5f;
- switch(CSurfaceTable::GetAdhesionGroup(s)){
- case ADHESIVE_RUBBER:
- r = f * 255.0f;
- g = 0;
- b = 0;
- break;
- case ADHESIVE_HARD:
- r = f*255.0f;
- g = f*255.0f;
- b = f*128.0f;
- break;
- case ADHESIVE_ROAD:
- r = f*128.0f;
- g = f*128.0f;
- b = f*128.0f;
- break;
- case ADHESIVE_LOOSE:
- r = 0;
- g = f * 255.0f;
- b = 0;
- break;
- case ADHESIVE_WET:
- r = 0;
- g = 0;
- b = f * 255.0f;
- break;
- default:
- // this doesn't make much sense
- r *= f;
- g *= f;
- b *= f;
- }
-
- 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;
- }
+ GetSurfaceColor(s, r, g, b);
if(s > SURFACE_METAL_GATE){
r = CGeneral::GetRandomNumber();
@@ -2654,47 +2531,7 @@ CCollision::DrawColModel_Coloured(const CMatrix &mat, const CColModel &colModel,
verts[7] = mat * CVector(max.x, max.y, max.z);
s = colModel.boxes[i].surface;
- f = (s & 0xF)/32.0f + 0.5f;
- switch(CSurfaceTable::GetAdhesionGroup(s)){
- case ADHESIVE_RUBBER:
- r = f * 255.0f;
- g = 0;
- b = 0;
- break;
- case ADHESIVE_HARD:
- r = f*255.0f;
- g = f*255.0f;
- b = f*128.0f;
- break;
- case ADHESIVE_ROAD:
- r = f*128.0f;
- g = f*128.0f;
- b = f*128.0f;
- break;
- case ADHESIVE_LOOSE:
- r = 0;
- g = f * 255.0f;
- b = 0;
- break;
- case ADHESIVE_WET:
- r = 0;
- g = 0;
- b = f * 255.0f;
- break;
- default:
- // this doesn't make much sense
- r *= f;
- g *= f;
- b *= f;
- }
-
- 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;
- }
+ GetSurfaceColor(s, r, g, b);
RenderBuffer::StartStoring(36, 8, &iptr, &vptr);
RwIm3DVertexSetRGBA(&vptr[0], r, g, b, 255);
diff --git a/src/collision/Collision.h b/src/collision/Collision.h
index f4270bc5..57f5f86e 100644
--- a/src/collision/Collision.h
+++ b/src/collision/Collision.h
@@ -28,9 +28,6 @@ class CCollision
public:
static eLevelName ms_collisionInMemory;
static CLinkList<CColModel*> ms_colModelCache;
-#ifdef NO_ISLAND_LOADING
- static bool bAlreadyLoaded;
-#endif
static void Init(void);
static void Shutdown(void);
@@ -42,26 +39,27 @@ public:
static void DrawColModel_Coloured(const CMatrix &mat, const CColModel &colModel, int32 id);
static void CalculateTrianglePlanes(CColModel *model);
+ static void RemoveTrianglePlanes(CColModel *model);
// all these return true if there's a collision
- static bool TestSphereSphere(const CColSphere &s1, const CColSphere &s2);
- static bool TestSphereBox(const CColSphere &sph, const CColBox &box);
- static bool TestLineBox(const CColLine &line, const CColBox &box);
- static bool TestVerticalLineBox(const CColLine &line, const CColBox &box);
+ static bool TestSphereSphere(const CSphere &s1, const CSphere &s2);
+ static bool TestSphereBox(const CSphere &sph, const CBox &box);
+ static bool TestLineBox(const CColLine &line, const CBox &box);
+ static bool TestVerticalLineBox(const CColLine &line, const CBox &box);
static bool TestLineTriangle(const CColLine &line, const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane);
static bool TestLineSphere(const CColLine &line, const CColSphere &sph);
static bool TestSphereTriangle(const CColSphere &sphere, const CompressedVector *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);
static bool ProcessLineBox(const CColLine &line, const CColBox &box, CColPoint &point, float &mindist);
static bool ProcessVerticalLineTriangle(const CColLine &line, const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindist, CStoredCollPoly *poly);
- static bool ProcessLineTriangle(const CColLine &line , const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindist);
+ static bool ProcessLineTriangle(const CColLine &line , const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindist, CStoredCollPoly *poly = nil);
static bool ProcessLineSphere(const CColLine &line, const CColSphere &sphere, CColPoint &point, float &mindist);
static bool ProcessSphereTriangle(const CColSphere &sph, const CompressedVector *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/collision/TempColModels.cpp b/src/collision/TempColModels.cpp
index 494c148d..0c0d4376 100644
--- a/src/collision/TempColModels.cpp
+++ b/src/collision/TempColModels.cpp
@@ -16,6 +16,7 @@ CColModel CTempColModels::ms_colModelPedGroundHit;
CColModel CTempColModels::ms_colModelBoot1;
CColModel CTempColModels::ms_colModelDoor1;
CColModel CTempColModels::ms_colModelBonnet1;
+CColModel CTempColModels::ms_colModelWeapon;
CColSphere s_aPedSpheres[3];
@@ -293,5 +294,13 @@ CTempColModels::Initialise(void)
SET_COLMODEL_SPHERES(ms_colModelBodyPart2, s_aBodyPartSpheres2);
+ ms_colModelWeapon.boundingSphere.radius = 0.25f;
+ ms_colModelWeapon.boundingBox.min.x = -0.25f;
+ ms_colModelWeapon.boundingBox.min.y = -0.25f;
+ ms_colModelWeapon.boundingBox.min.z = -0.25f;
+ ms_colModelWeapon.boundingBox.max.x = 0.25f;
+ ms_colModelWeapon.boundingBox.max.y = 0.25f;
+ ms_colModelWeapon.boundingBox.max.z = 0.25f;
+
#undef SET_COLMODEL_SPHERES
}
diff --git a/src/collision/TempColModels.h b/src/collision/TempColModels.h
index 057728af..1a888723 100644
--- a/src/collision/TempColModels.h
+++ b/src/collision/TempColModels.h
@@ -18,6 +18,7 @@ public:
static CColModel ms_colModelBoot1;
static CColModel ms_colModelDoor1;
static CColModel ms_colModelBonnet1;
+ static CColModel ms_colModelWeapon;
static void Initialise(void);
};
diff --git a/src/control/AutoPilot.cpp b/src/control/AutoPilot.cpp
index 5af4071a..d7c17a68 100644
--- a/src/control/AutoPilot.cpp
+++ b/src/control/AutoPilot.cpp
@@ -71,6 +71,9 @@ void CAutoPilot::Save(uint8*& buf)
WriteSaveBuf(buf, m_nTimeTempAction);
WriteSaveBuf(buf, m_fMaxTrafficSpeed);
WriteSaveBuf(buf, m_nCruiseSpeed);
+ WriteSaveBuf(buf, m_nCruiseSpeedMultiplierType);
+ ZeroSaveBuf(buf, 2);
+ WriteSaveBuf(buf, m_fCruiseSpeedMultiplier);
uint8 flags = 0;
if (m_bSlowedDownBecauseOfCars) flags |= BIT(0);
if (m_bSlowedDownBecauseOfPeds) flags |= BIT(1);
@@ -78,6 +81,7 @@ void CAutoPilot::Save(uint8*& buf)
if (m_bStayInFastLane) flags |= BIT(3);
if (m_bIgnorePathfinding) flags |= BIT(4);
WriteSaveBuf(buf, flags);
+ WriteSaveBuf(buf, m_nSwitchDistance);
ZeroSaveBuf(buf, 2);
WriteSaveBuf(buf, m_vecDestinationCoors.x);
WriteSaveBuf(buf, m_vecDestinationCoors.y);
@@ -110,6 +114,9 @@ void CAutoPilot::Load(uint8*& buf)
ReadSaveBuf(&m_nTimeTempAction, buf);
ReadSaveBuf(&m_fMaxTrafficSpeed, buf);
ReadSaveBuf(&m_nCruiseSpeed, buf);
+ ReadSaveBuf(&m_nCruiseSpeedMultiplierType, buf);
+ SkipSaveBuf(buf, 2);
+ ReadSaveBuf(&m_fCruiseSpeedMultiplier, buf);
uint8 flags;
ReadSaveBuf(&flags, buf);
m_bSlowedDownBecauseOfCars = !!(flags & BIT(0));
@@ -117,6 +124,7 @@ void CAutoPilot::Load(uint8*& buf)
m_bStayInCurrentLevel = !!(flags & BIT(2));
m_bStayInFastLane = !!(flags & BIT(3));
m_bIgnorePathfinding = !!(flags & BIT(4));
+ ReadSaveBuf(&m_nSwitchDistance, buf);
SkipSaveBuf(buf, 2);
ReadSaveBuf(&m_vecDestinationCoors.x, buf);
ReadSaveBuf(&m_vecDestinationCoors.y, buf);
diff --git a/src/control/AutoPilot.h b/src/control/AutoPilot.h
index c7707ed6..ec3bb8d8 100644
--- a/src/control/AutoPilot.h
+++ b/src/control/AutoPilot.h
@@ -26,6 +26,13 @@ enum eCarMission
MISSION_BLOCKCAR_FARAWAY,
MISSION_BLOCKCAR_CLOSE,
MISSION_BLOCKCAR_HANDBRAKESTOP,
+ MISSION_HELI_FLYTOCOORS,
+ MISSION_ATTACKPLAYER,
+ MISSION_PLANE_FLYTOCOORS,
+ MISSION_HELI_LAND,
+ MISSION_SLOWLY_DRIVE_TOWARDS_PLAYER_1,
+ MISSION_SLOWLY_DRIVE_TOWARDS_PLAYER_2,
+ MISSION_BLOCKPLAYER_FORWARDANDBACK
};
enum eCarTempAction
@@ -75,11 +82,14 @@ public:
uint32 m_nTimeTempAction;
float m_fMaxTrafficSpeed;
uint8 m_nCruiseSpeed;
+ uint8 m_nCruiseSpeedMultiplierType;
+ float m_fCruiseSpeedMultiplier;
uint8 m_bSlowedDownBecauseOfCars : 1;
uint8 m_bSlowedDownBecauseOfPeds : 1;
uint8 m_bStayInCurrentLevel : 1;
uint8 m_bStayInFastLane : 1;
uint8 m_bIgnorePathfinding : 1;
+ uint8 m_nSwitchDistance;
CVector m_vecDestinationCoors;
CPathNode *m_aPathFindNodesInfo[NUM_PATH_NODES_IN_AUTOPILOT];
int16 m_nPathFindNodesCount;
@@ -109,6 +119,8 @@ public:
m_nTimeToStartMission = CTimer::GetTimeInMilliseconds();
m_nAntiReverseTimer = m_nTimeToStartMission;
m_bStayInFastLane = false;
+ m_nCruiseSpeedMultiplierType = 0;
+ m_fCruiseSpeedMultiplier = 1.0f;
}
void ModifySpeed(float);
@@ -118,6 +130,8 @@ public:
void Load(uint8*& buf);
#endif
+ float GetCruiseSpeed(void) { return m_nCruiseSpeed * m_fCruiseSpeedMultiplier; }
+
};
VALIDATE_SIZE(CAutoPilot, 0x70);
diff --git a/src/control/Bridge.cpp b/src/control/Bridge.cpp
index e873062b..1e63cf30 100644
--- a/src/control/Bridge.cpp
+++ b/src/control/Bridge.cpp
@@ -23,6 +23,7 @@ uint32 CBridge::TimeOfBridgeBecomingOperational;
void CBridge::Init()
{
+#ifdef GTA_BRIDGE
FindBridgeEntities();
OldLift = -1.0f;
if (pLiftPart && pWeight)
@@ -35,10 +36,12 @@ void CBridge::Init()
ThePaths.SetLinksBridgeLights(-330.0, -230.0, -700.0, -588.0, true);
}
+#endif
}
void CBridge::Update()
{
+#ifdef GTA_BRIDGE
if (!pLiftPart || !pWeight)
return;
@@ -113,15 +116,21 @@ void CBridge::Update()
ThePaths.SetLinksBridgeLights(-330.0, -230.0, -700.0, -588.0, true);
else if (State == STATE_LIFT_PART_IS_DOWN && OldState == STATE_LIFT_PART_MOVING_DOWN)
ThePaths.SetLinksBridgeLights(-330.0, -230.0, -700.0, -588.0, false);
+#endif
}
bool CBridge::ShouldLightsBeFlashing()
{
+#ifdef GTA_BRIDGE
return State != STATE_LIFT_PART_IS_DOWN;
+#else
+ return false;
+#endif
}
void CBridge::FindBridgeEntities()
{
+#ifdef GTA_BRIDGE
pWeight = nil;
pLiftRoad = nil;
pLiftPart = nil;
@@ -138,12 +147,17 @@ void CBridge::FindBridgeEntities()
pWeight = entry;
}
}
+#endif
}
bool CBridge::ThisIsABridgeObjectMovingUp(int index)
{
+#ifdef GTA_BRIDGE
if (index != MI_BRIDGEROADSEGMENT && index != MI_BRIDGELIFT)
return false;
return State == STATE_LIFT_PART_ABOUT_TO_MOVE_UP || State == STATE_LIFT_PART_MOVING_UP;
+#else
+ return false;
+#endif
}
diff --git a/src/control/CarAI.cpp b/src/control/CarAI.cpp
index ffde7aba..c8230d4d 100644
--- a/src/control/CarAI.cpp
+++ b/src/control/CarAI.cpp
@@ -13,6 +13,7 @@
#include "DMAudio.h"
#include "Fire.h"
#include "Pools.h"
+#include "Population.h"
#include "Timer.h"
#include "TrafficLights.h"
#include "Vehicle.h"
@@ -23,7 +24,7 @@
float CCarAI::FindSwitchDistanceClose(CVehicle* pVehicle)
{
- return 30.0f;
+ return pVehicle->AutoPilot.m_nSwitchDistance;
}
float CCarAI::FindSwitchDistanceFarNormalVehicle(CVehicle* pVehicle)
@@ -38,6 +39,19 @@ float CCarAI::FindSwitchDistanceFar(CVehicle* pVehicle)
return FindSwitchDistanceFarNormalVehicle(pVehicle);
}
+void CCarAI::BackToCruisingIfNoWantedLevel(CVehicle* pVehicle)
+{
+ if (FindPlayerPed()->m_pWanted->m_bIgnoredByEveryone || pVehicle->bIsLawEnforcer &&
+ (FindPlayerPed()->m_pWanted->GetWantedLevel() == 0 || FindPlayerPed()->m_pWanted->m_bIgnoredByCops || CCullZones::NoPolice())) {
+ CCarCtrl::JoinCarWithRoadSystem(pVehicle);
+ pVehicle->AutoPilot.m_nCarMission = MISSION_CRUISE;
+ pVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_STOP_FOR_CARS;
+ pVehicle->m_bSirenOrAlarm = false;
+ if (CCullZones::NoPolice())
+ pVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
+ }
+}
+
void CCarAI::UpdateCarAI(CVehicle* pVehicle)
{
if (pVehicle->bIsLawEnforcer){
@@ -64,18 +78,10 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle)
if (FindSwitchDistanceClose(pVehicle) > (FindPlayerCoors() - pVehicle->GetPosition()).Magnitude2D() ||
pVehicle->AutoPilot.m_bIgnorePathfinding) {
pVehicle->AutoPilot.m_nCarMission = MISSION_RAMPLAYER_CLOSE;
- if (pVehicle->UsesSiren(pVehicle->GetModelIndex()))
+ if (pVehicle->UsesSiren())
pVehicle->m_bSirenOrAlarm = true;
}
- if (FindPlayerPed()->m_pWanted->m_bIgnoredByEveryone || pVehicle->bIsLawEnforcer &&
- (FindPlayerPed()->m_pWanted->GetWantedLevel() == 0 || FindPlayerPed()->m_pWanted->m_bIgnoredByCops || CCullZones::NoPolice())) {
- CCarCtrl::JoinCarWithRoadSystem(pVehicle);
- pVehicle->AutoPilot.m_nCarMission = MISSION_CRUISE;
- pVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_STOP_FOR_CARS;
- pVehicle->m_bSirenOrAlarm = false;
- if (CCullZones::NoPolice())
- pVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
- }
+ BackToCruisingIfNoWantedLevel(pVehicle);
break;
case MISSION_RAMPLAYER_CLOSE:
if (FindSwitchDistanceFar(pVehicle) >= (FindPlayerCoors() - pVehicle->GetPosition()).Magnitude2D() ||
@@ -120,40 +126,23 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle)
pVehicle->m_bSirenOrAlarm = false;
pVehicle->m_nCarHornTimer = 0;
}
- if (FindPlayerPed()->m_pWanted->m_bIgnoredByEveryone || pVehicle->bIsLawEnforcer &&
- (FindPlayerPed()->m_pWanted->GetWantedLevel() == 0 || FindPlayerPed()->m_pWanted->m_bIgnoredByCops || CCullZones::NoPolice())){
- CCarCtrl::JoinCarWithRoadSystem(pVehicle);
- pVehicle->AutoPilot.m_nCarMission = MISSION_CRUISE;
- pVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_STOP_FOR_CARS;
- pVehicle->m_bSirenOrAlarm = false;
- if (CCullZones::NoPolice())
- pVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
- }
-
- else if (pVehicle->bIsLawEnforcer)
+ if (pVehicle->bIsLawEnforcer)
MellowOutChaseSpeed(pVehicle);
+ BackToCruisingIfNoWantedLevel(pVehicle);
break;
case MISSION_BLOCKPLAYER_FARAWAY:
if (FindSwitchDistanceClose(pVehicle) > (FindPlayerCoors() - pVehicle->GetPosition()).Magnitude2D() ||
pVehicle->AutoPilot.m_bIgnorePathfinding) {
pVehicle->AutoPilot.m_nCarMission = MISSION_BLOCKPLAYER_CLOSE;
- if (pVehicle->UsesSiren(pVehicle->GetModelIndex()))
+ if (pVehicle->UsesSiren())
pVehicle->m_bSirenOrAlarm = true;
}
- if (FindPlayerPed()->m_pWanted->m_bIgnoredByEveryone || pVehicle->bIsLawEnforcer &&
- (FindPlayerPed()->m_pWanted->GetWantedLevel() == 0 || FindPlayerPed()->m_pWanted->m_bIgnoredByCops || CCullZones::NoPolice())) {
- CCarCtrl::JoinCarWithRoadSystem(pVehicle);
- pVehicle->AutoPilot.m_nCarMission = MISSION_CRUISE;
- pVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_STOP_FOR_CARS;
- pVehicle->m_bSirenOrAlarm = false;
- if (CCullZones::NoPolice())
- pVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
- }
+ BackToCruisingIfNoWantedLevel(pVehicle);
break;
case MISSION_BLOCKPLAYER_CLOSE:
if (FindSwitchDistanceFar(pVehicle) >= (FindPlayerCoors() - pVehicle->GetPosition()).Magnitude2D() ||
pVehicle->AutoPilot.m_bIgnorePathfinding) {
- if (FindPlayerVehicle() && FindPlayerVehicle()->GetMoveSpeed().Magnitude() < 0.05f)
+ if (FindPlayerVehicle() && FindPlayerVehicle()->GetMoveSpeed().Magnitude() < 0.04f)
#ifdef FIX_BUGS
pVehicle->m_nTimeBlocked += CTimer::GetTimeStepInMilliseconds();
#else
@@ -162,7 +151,7 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle)
else
pVehicle->m_nTimeBlocked = 0;
if (!FindPlayerVehicle() || FindPlayerVehicle()->IsUpsideDown() ||
- FindPlayerVehicle()->GetMoveSpeed().Magnitude() < 0.05f && pVehicle->m_nTimeBlocked > TIME_COPS_WAIT_TO_EXIT_AFTER_STOPPING) {
+ FindPlayerVehicle()->GetMoveSpeed().Magnitude() < 0.04f && pVehicle->m_nTimeBlocked > TIME_COPS_WAIT_TO_EXIT_AFTER_STOPPING) {
if (pVehicle->bIsLawEnforcer &&
(pVehicle->GetModelIndex() != MI_RHINO || pVehicle->m_randomSeed > 10000) &&
(FindPlayerCoors() - pVehicle->GetPosition()).Magnitude2D() < 10.0f) {
@@ -178,20 +167,12 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle)
pVehicle->m_bSirenOrAlarm = false;
pVehicle->m_nCarHornTimer = 0;
}
- if (FindPlayerPed()->m_pWanted->m_bIgnoredByEveryone || pVehicle->bIsLawEnforcer &&
- (FindPlayerPed()->m_pWanted->GetWantedLevel() == 0 || FindPlayerPed()->m_pWanted->m_bIgnoredByCops || CCullZones::NoPolice())) {
- CCarCtrl::JoinCarWithRoadSystem(pVehicle);
- pVehicle->AutoPilot.m_nCarMission = MISSION_CRUISE;
- pVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_STOP_FOR_CARS;
- pVehicle->m_bSirenOrAlarm = false;
- if (CCullZones::NoPolice())
- pVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
- }
if (pVehicle->bIsLawEnforcer)
MellowOutChaseSpeed(pVehicle);
+ BackToCruisingIfNoWantedLevel(pVehicle);
break;
case MISSION_GOTOCOORDS:
- if ((pVehicle->AutoPilot.m_vecDestinationCoors - pVehicle->GetPosition()).Magnitude2D() < DISTANCE_TO_SWITCH_DISTANCE_GOTO ||
+ if ((pVehicle->AutoPilot.m_vecDestinationCoors - pVehicle->GetPosition()).Magnitude2D() < FindSwitchDistanceClose(pVehicle) ||
pVehicle->AutoPilot.m_bIgnorePathfinding)
pVehicle->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS_STRAIGHT;
break;
@@ -200,9 +181,13 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle)
float distance = (pVehicle->AutoPilot.m_vecDestinationCoors - pVehicle->GetPosition()).Magnitude2D();
if ((pVehicle->bIsAmbulanceOnDuty || pVehicle->bIsFireTruckOnDuty) && distance < 20.0f)
pVehicle->AutoPilot.m_nCarMission = MISSION_EMERGENCYVEHICLE_STOP;
- if (distance < 5.0f){
+ if (distance < 3.0f){
pVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE;
+ if (pVehicle->bParking) {
+ TellOccupantsToLeaveCar(pVehicle);
+ pVehicle->bParking = false;
+ }
}
else if (distance > FindSwitchDistanceFarNormalVehicle(pVehicle) && !pVehicle->AutoPilot.m_bIgnorePathfinding && (CTimer::GetFrameCounter() & 7) == 0){
pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE;
@@ -249,8 +234,8 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle)
}
break;
case MISSION_GOTOCOORDS_ACCURATE:
- if ((pVehicle->AutoPilot.m_vecDestinationCoors - pVehicle->GetPosition()).Magnitude2D() < 20.0f ||
- pVehicle->AutoPilot.m_bIgnorePathfinding)
+ if ((pVehicle->AutoPilot.m_vecDestinationCoors - pVehicle->GetPosition()).Magnitude2D() < FindSwitchDistanceClose(pVehicle) ||
+ pVehicle->AutoPilot.m_bIgnorePathfinding)
pVehicle->AutoPilot.m_nCarMission = MISSION_GOTO_COORDS_STRAIGHT_ACCURATE;
break;
case MISSION_GOTO_COORDS_STRAIGHT_ACCURATE:
@@ -259,6 +244,10 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle)
if (distance < 1.0f) {
pVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE;
+ if (pVehicle->bParking) {
+ TellOccupantsToLeaveCar(pVehicle);
+ pVehicle->bParking = false;
+ }
}
else if (distance > FindSwitchDistanceFarNormalVehicle(pVehicle) && !pVehicle->AutoPilot.m_bIgnorePathfinding && (CTimer::GetFrameCounter() & 7) == 0) {
pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE;
@@ -278,23 +267,10 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle)
break;
case MISSION_RAMCAR_CLOSE:
if (pVehicle->AutoPilot.m_pTargetCar){
- if
-#ifdef FIX_BUGS
- (FindPlayerVehicle() == pVehicle->AutoPilot.m_pTargetCar &&
+#ifdef FIX_BUGS // btw fixed in SA
+ if (FindPlayerVehicle() == pVehicle->AutoPilot.m_pTargetCar)
#endif
- (FindPlayerPed()->m_pWanted->m_bIgnoredByEveryone || pVehicle->bIsLawEnforcer &&
- (FindPlayerPed()->m_pWanted->GetWantedLevel() == 0 || FindPlayerPed()->m_pWanted->m_bIgnoredByCops || CCullZones::NoPolice()))
-#ifdef FIX_BUGS
- )
-#endif
- {
- CCarCtrl::JoinCarWithRoadSystem(pVehicle);
- pVehicle->AutoPilot.m_nCarMission = MISSION_CRUISE;
- pVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_STOP_FOR_CARS;
- pVehicle->m_bSirenOrAlarm = false;
- if (CCullZones::NoPolice())
- pVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
- }
+ BackToCruisingIfNoWantedLevel(pVehicle);
if ((pVehicle->AutoPilot.m_pTargetCar->GetPosition() - pVehicle->GetPosition()).Magnitude2D() <= FindSwitchDistanceFar(pVehicle) ||
pVehicle->AutoPilot.m_bIgnorePathfinding){
if (pVehicle->GetHasCollidedWith(pVehicle->AutoPilot.m_pTargetCar)){
@@ -316,7 +292,7 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle)
if ((pVehicle->AutoPilot.m_pTargetCar->GetPosition() - pVehicle->GetPosition()).Magnitude2D() < FindSwitchDistanceClose(pVehicle) ||
pVehicle->AutoPilot.m_bIgnorePathfinding){
pVehicle->AutoPilot.m_nCarMission = MISSION_BLOCKCAR_CLOSE;
- if (pVehicle->UsesSiren(pVehicle->GetModelIndex()))
+ if (pVehicle->UsesSiren())
pVehicle->m_bSirenOrAlarm = true;
}
}else{
@@ -336,6 +312,41 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle)
pVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
}
break;
+ case MISSION_ATTACKPLAYER:
+ if (pVehicle->bIsLawEnforcer)
+ MellowOutChaseSpeedBoat(pVehicle);
+ BackToCruisingIfNoWantedLevel(pVehicle);
+ break;
+ case MISSION_SLOWLY_DRIVE_TOWARDS_PLAYER_1:
+ if (((CVector2D)(pVehicle->AutoPilot.m_vecDestinationCoors) - pVehicle->GetPosition()).Magnitude() < 1.5f)
+ pVehicle->AutoPilot.m_nCarMission = MISSION_SLOWLY_DRIVE_TOWARDS_PLAYER_2;
+ BackToCruisingIfNoWantedLevel(pVehicle);
+ break;
+ case MISSION_SLOWLY_DRIVE_TOWARDS_PLAYER_2:
+ {
+ float distance = ((CVector2D)FindPlayerCoors() - pVehicle->GetPosition()).Magnitude();
+ if (distance < 13.0f) {
+ TellOccupantsToLeaveCar(pVehicle);
+ pVehicle->AutoPilot.m_nCruiseSpeed = 0;
+ pVehicle->AutoPilot.m_nCarMission = MISSION_STOP_FOREVER;
+ }
+ if (distance > 70.0f || FindPlayerPed()->m_pWanted->m_bIgnoredByEveryone ||
+ (FindPlayerPed()->m_pWanted->GetWantedLevel() == 0 || FindPlayerPed()->m_pWanted->m_bIgnoredByCops || CCullZones::NoPolice())) {
+ TellOccupantsToLeaveCar(pVehicle);
+ pVehicle->AutoPilot.m_nCruiseSpeed = 0;
+ pVehicle->AutoPilot.m_nCarMission = MISSION_STOP_FOREVER;
+ }
+ break;
+ }
+ case MISSION_BLOCKPLAYER_FORWARDANDBACK:
+ {
+ CVector2D diff = (CVector2D)FindPlayerCoors() - pVehicle->GetPosition();
+ float distance = Max(0.001f, diff.Magnitude());
+ 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->GetWantedLevel() > 0 && !CCullZones::NoPolice()){
if (ABS(FindPlayerCoors().x - pVehicle->GetPosition().x) > 10.0f ||
@@ -343,7 +354,7 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle)
pVehicle->AutoPilot.m_nCruiseSpeed = FindPoliceCarSpeedForWantedLevel(pVehicle);
pVehicle->SetStatus(STATUS_PHYSICS);
pVehicle->AutoPilot.m_nCarMission =
- 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){
@@ -364,6 +375,11 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle)
pVehicle->AutoPilot.m_nCruiseSpeed = 0;
break;
}
+ if (pVehicle->bIsLawEnforcer && FindPlayerPed()->m_pWanted->GetWantedLevel() >= 1 && CCullZones::PoliceAbandonCars()) {
+ TellOccupantsToLeaveCar(pVehicle);
+ pVehicle->AutoPilot.m_nCruiseSpeed = 0;
+ pVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
+ }
float flatSpeed = pVehicle->GetMoveSpeed().MagnitudeSqr2D();
if (flatSpeed > SQR(0.018f)){
pVehicle->AutoPilot.m_nTimeToStartMission = CTimer::GetTimeInMilliseconds();
@@ -372,9 +388,12 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle)
if (pVehicle->GetStatus() == STATUS_PHYSICS && pVehicle->AutoPilot.m_nTempAction == TEMPACT_NONE){
if (pVehicle->AutoPilot.m_nCarMission != MISSION_NONE){
if (pVehicle->AutoPilot.m_nCarMission != MISSION_STOP_FOREVER &&
+ pVehicle->AutoPilot.m_nCarMission != MISSION_BLOCKPLAYER_HANDBRAKESTOP &&
pVehicle->AutoPilot.m_nCruiseSpeed != 0 &&
(pVehicle->VehicleCreatedBy != RANDOM_VEHICLE || pVehicle->AutoPilot.m_nCarMission != MISSION_CRUISE)){
if (pVehicle->AutoPilot.m_nDrivingStyle != DRIVINGSTYLE_STOP_FOR_CARS
+ && pVehicle->AutoPilot.m_nDrivingStyle != DRIVINGSTYLE_STOP_FOR_CARS_IGNORE_LIGHTS ||
+ pVehicle->VehicleCreatedBy == MISSION_VEHICLE
) {
if (CTimer::GetTimeInMilliseconds() - pVehicle->m_nLastTimeCollided > 500)
pVehicle->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds();
@@ -406,6 +425,13 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle)
pVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 400;
}
}
+ if (pVehicle->bIsLawEnforcer) {
+ if (pVehicle->AutoPilot.m_nCarMission == MISSION_RAMPLAYER_FARAWAY ||
+ pVehicle->AutoPilot.m_nCarMission == MISSION_RAMPLAYER_CLOSE) {
+ if (FindPlayerVehicle() && FindPlayerVehicle()->GetVehicleAppearance() == VEHICLE_APPEARANCE_BIKE)
+ pVehicle->AutoPilot.m_nCarMission = MISSION_BLOCKPLAYER_FARAWAY;
+ }
+ }
if (pVehicle->GetUp().z < -0.7f){
pVehicle->AutoPilot.m_nTempAction = TEMPACT_WAIT;
pVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 1000;
@@ -446,6 +472,34 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle)
if ((uint8)(pVehicle->m_randomSeed ^ CGeneral::GetRandomNumber()) == 0xAD)
pVehicle->m_nCarHornTimer = 45;
}
+ float target = 1.0f;
+ if (pVehicle->AutoPilot.m_nCarMission == MISSION_CRUISE)
+ target = CCarCtrl::FindSpeedMultiplierWithSpeedFromNodes(pVehicle->AutoPilot.m_nCruiseSpeedMultiplierType);
+ float change = CTimer::GetTimeStep() * 0.01f;
+ if (Abs(pVehicle->AutoPilot.m_fCruiseSpeedMultiplier - target) < change)
+ pVehicle->AutoPilot.m_fCruiseSpeedMultiplier = target;
+ else if (pVehicle->AutoPilot.m_fCruiseSpeedMultiplier > target)
+ pVehicle->AutoPilot.m_fCruiseSpeedMultiplier -= change;
+ else
+ pVehicle->AutoPilot.m_fCruiseSpeedMultiplier += change;
+
+ if (pVehicle->bIsLawEnforcer && FindPlayerPed()->m_pWanted->GetWantedLevel() > 0) {
+ if (!FindPlayerVehicle() ||
+ 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_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;
+ }
+ }
+ }
}
void CCarAI::CarHasReasonToStop(CVehicle* pVehicle)
@@ -470,13 +524,21 @@ float CCarAI::GetCarToGoToCoors(CVehicle* pVehicle, CVector* pTarget)
return (pVehicle->GetPosition() - *pTarget).Magnitude2D();
}
+float CCarAI::GetCarToParkAtCoors(CVehicle* pVehicle, CVector* pTarget)
+{
+ GetCarToGoToCoors(pVehicle, pTarget);
+ pVehicle->bParking = true;
+ pVehicle->AutoPilot.m_nCruiseSpeed = 10;
+ return (pVehicle->GetPosition() - *pTarget).Magnitude2D();
+}
+
void CCarAI::AddPoliceCarOccupants(CVehicle* pVehicle)
{
if (pVehicle->bOccupantsHaveBeenGenerated)
return;
pVehicle->bOccupantsHaveBeenGenerated = true;
switch (pVehicle->GetModelIndex()){
- case MI_FBICAR:
+ case MI_FBIRANCH:
case MI_ENFORCER:
pVehicle->SetUpDriver();
for (int i = 0; i < 3; i++)
@@ -489,6 +551,18 @@ void CCarAI::AddPoliceCarOccupants(CVehicle* pVehicle)
if (FindPlayerPed()->m_pWanted->GetWantedLevel() > 1)
pVehicle->SetupPassenger(0);
return;
+ case MI_PREDATOR:
+ pVehicle->SetUpDriver();
+ return;
+ case MI_VICECHEE:
+ {
+ pVehicle->SetUpDriver()->bMiamiViceCop = true;
+ pVehicle->SetupPassenger(0)->bMiamiViceCop = true;
+ CPopulation::NumMiamiViceCops += 2;
+ CCarCtrl::MiamiViceCycle = (CCarCtrl::MiamiViceCycle + 1) % 4;
+ CCarCtrl::LastTimeMiamiViceGenerated = CTimer::GetTimeInMilliseconds();
+ return;
+ }
default:
return;
}
@@ -526,7 +600,36 @@ void CCarAI::TellOccupantsToLeaveCar(CVehicle* pVehicle)
int timer = 100;
for (int i = 0; i < pVehicle->m_nNumMaxPassengers; i++){
if (pVehicle->pPassengers[i]) {
+ pVehicle->pPassengers[i]->m_leaveCarTimer = timer;
pVehicle->pPassengers[i]->SetObjective(OBJECTIVE_LEAVE_CAR, pVehicle);
+ timer += CGeneral::GetRandomNumberInRange(200, 400);
+ }
+ }
+}
+
+void CCarAI::TellOccupantsToFleeCar(CVehicle* pVehicle)
+{
+ if (pVehicle->pDriver && !pVehicle->pDriver->IsPlayer()) {
+ pVehicle->pDriver->SetObjective(OBJECTIVE_FLEE_ON_FOOT_TILL_SAFE);
+ switch (pVehicle->GetModelIndex()) {
+ case MI_FIRETRUCK:
+ case MI_FBIRANCH:
+ case MI_ENFORCER:
+ case MI_BARRACKS:
+ case MI_RHINO:
+ case MI_POLICE:
+ break;
+ case MI_AMBULAN:
+ pVehicle->pDriver->Say(SOUND_PED_LEAVE_VEHICLE);
+ break;
+ }
+ }
+ int timer = 100;
+ for (int i = 0; i < pVehicle->m_nNumMaxPassengers; i++) {
+ if (pVehicle->pPassengers[i]) {
+ pVehicle->pPassengers[i]->m_leaveCarTimer = timer;
+ pVehicle->pPassengers[i]->SetObjective(OBJECTIVE_FLEE_ON_FOOT_TILL_SAFE);
+ timer += CGeneral::GetRandomNumberInRange(200, 400);
}
}
}
@@ -563,6 +666,20 @@ uint8 CCarAI::FindPoliceCarMissionForWantedLevel()
}
}
+uint8 CCarAI::FindPoliceBoatMissionForWantedLevel()
+{
+ switch (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted->GetWantedLevel()) {
+ case 0:
+ case 1: return MISSION_BLOCKPLAYER_FARAWAY;
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6: return MISSION_ATTACKPLAYER;
+ default: return MISSION_BLOCKPLAYER_FARAWAY;
+ }
+}
+
int32 CCarAI::FindPoliceCarSpeedForWantedLevel(CVehicle* pVehicle)
{
switch (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted->GetWantedLevel()) {
@@ -615,6 +732,23 @@ void CCarAI::MellowOutChaseSpeed(CVehicle* pVehicle)
pVehicle->AutoPilot.m_nCruiseSpeed = 34;
}
}
+ if (!FindPlayerVehicle() && FindPlayerPed()->GetMoveSpeed().Magnitude() < 0.07f) {
+ if ((FindPlayerCoors() - pVehicle->GetPosition()).Magnitude() < 30.0f)
+ pVehicle->AutoPilot.m_nCruiseSpeed = Min(10, pVehicle->AutoPilot.m_nCruiseSpeed);
+ }
+}
+
+void CCarAI::MellowOutChaseSpeedBoat(CVehicle* pVehicle)
+{
+ switch (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted->GetWantedLevel()) {
+ case 0: pVehicle->AutoPilot.m_nCruiseSpeed = 8; break;
+ case 1: pVehicle->AutoPilot.m_nCruiseSpeed = 10; break;
+ case 2: pVehicle->AutoPilot.m_nCruiseSpeed = 15; break;
+ case 3: pVehicle->AutoPilot.m_nCruiseSpeed = 20; break;
+ case 4: pVehicle->AutoPilot.m_nCruiseSpeed = 25; break;
+ case 5: pVehicle->AutoPilot.m_nCruiseSpeed = 30; break;
+ case 6: pVehicle->AutoPilot.m_nCruiseSpeed = 40; break;
+ }
}
void CCarAI::MakeWayForCarWithSiren(CVehicle *pVehicle)
@@ -639,6 +773,8 @@ void CCarAI::MakeWayForCarWithSiren(CVehicle *pVehicle)
continue;
if (vehicle == pVehicle)
continue;
+ if (vehicle->AutoPilot.m_nDrivingStyle == DRIVINGSTYLE_AVOID_CARS)
+ return;
if (Abs(pVehicle->GetPosition().z - vehicle->GetPosition().z) >= 5.0f)
continue;
CVector2D distance = vehicle->GetPosition() - pVehicle->GetPosition();
diff --git a/src/control/CarAI.h b/src/control/CarAI.h
index 9b731ad5..dcd76d78 100644
--- a/src/control/CarAI.h
+++ b/src/control/CarAI.h
@@ -10,17 +10,22 @@ public:
static float FindSwitchDistanceClose(CVehicle*);
static float FindSwitchDistanceFarNormalVehicle(CVehicle*);
static float FindSwitchDistanceFar(CVehicle*);
+ static void BackToCruisingIfNoWantedLevel(CVehicle*);
static void UpdateCarAI(CVehicle*);
static void CarHasReasonToStop(CVehicle*);
static float GetCarToGoToCoors(CVehicle*, CVector*);
+ static float GetCarToParkAtCoors(CVehicle*, CVector*);
static void AddPoliceCarOccupants(CVehicle*);
static void AddAmbulanceOccupants(CVehicle*);
static void AddFiretruckOccupants(CVehicle*);
static void TellOccupantsToLeaveCar(CVehicle*);
+ static void TellOccupantsToFleeCar(CVehicle*);
static void TellCarToRamOtherCar(CVehicle*, CVehicle*);
static void TellCarToBlockOtherCar(CVehicle*, CVehicle*);
static uint8 FindPoliceCarMissionForWantedLevel();
+ static uint8 FindPoliceBoatMissionForWantedLevel();
static int32 FindPoliceCarSpeedForWantedLevel(CVehicle*);
static void MellowOutChaseSpeed(CVehicle*);
+ static void MellowOutChaseSpeedBoat(CVehicle*);
static void MakeWayForCarWithSiren(CVehicle *veh);
};
diff --git a/src/control/CarCtrl.cpp b/src/control/CarCtrl.cpp
index ca83603f..fa5ac1fe 100644
--- a/src/control/CarCtrl.cpp
+++ b/src/control/CarCtrl.cpp
@@ -4,6 +4,7 @@
#include "Accident.h"
#include "Automobile.h"
+#include "Bike.h"
#include "Camera.h"
#include "CarAI.h"
#include "CarGen.h"
@@ -11,6 +12,7 @@
#include "Curves.h"
#include "CutsceneMgr.h"
#include "Gangs.h"
+#include "Game.h"
#include "Garages.h"
#include "General.h"
#include "IniFile.h"
@@ -19,6 +21,7 @@
#include "Ped.h"
#include "PlayerInfo.h"
#include "PlayerPed.h"
+#include "Population.h"
#include "Wanted.h"
#include "Pools.h"
#include "Renderer.h"
@@ -29,44 +32,58 @@
#include "VisibilityPlugins.h"
#include "Vehicle.h"
#include "Fire.h"
+#include "WaterLevel.h"
#include "World.h"
#include "Zones.h"
-
-#define DISTANCE_TO_SPAWN_ROADBLOCK_PEDS 51.0f
-#define DISTANCE_TO_SCAN_FOR_DANGER 11.0f
-#define SAFE_DISTANCE_TO_PED 3.0f
-#define INFINITE_Z 1000000000.0f
-
-#define VEHICLE_HEIGHT_DIFF_TO_CONSIDER_WEAVING 4.0f
-#define PED_HEIGHT_DIFF_TO_CONSIDER_WEAVING 4.0f
-#define OBJECT_HEIGHT_DIFF_TO_CONSIDER_WEAVING 8.0f
-#define WIDTH_COEF_TO_WEAVE_SAFELY 1.2f
-#define OBJECT_WIDTH_TO_WEAVE 0.3f
-#define PED_WIDTH_TO_WEAVE 0.8f
-
-#define PATH_DIRECTION_NONE 0
-#define PATH_DIRECTION_STRAIGHT 1
-#define PATH_DIRECTION_RIGHT 2
-#define PATH_DIRECTION_LEFT 4
-
-#define ATTEMPTS_TO_FIND_NEXT_NODE 15
-
-#define DISTANCE_TO_SWITCH_FROM_BLOCK_TO_STOP 5.0f
-#define DISTANCE_TO_SWITCH_FROM_STOP_TO_BLOCK 10.0f
-#define MAX_SPEED_TO_ACCOUNT_IN_INTERCEPTING 0.13f
-#define DISTANCE_TO_NEXT_NODE_TO_CONSIDER_SLOWING_DOWN 40.0f
-#define MAX_ANGLE_TO_STEER_AT_HIGH_SPEED 0.2f
-#define MIN_SPEED_TO_START_LIMITING_STEER 0.45f
-#define DISTANCE_TO_NEXT_NODE_TO_SELECT_NEW 5.0f
-#define DISTANCE_TO_FACING_NEXT_NODE_TO_SELECT_NEW 8.0f
-#define DEFAULT_MAX_STEER_ANGLE 0.5f
-#define MIN_LOWERING_SPEED_COEFFICIENT 0.4f
-#define MAX_ANGLE_FOR_SPEED_LIMITING 1.2f
-#define MIN_ANGLE_FOR_SPEED_LIMITING 0.4f
-#define MIN_ANGLE_FOR_SPEED_LIMITING_BETWEEN_NODES 0.1f
-#define MIN_ANGLE_TO_APPLY_HANDBRAKE 0.7f
-#define MIN_SPEED_TO_APPLY_HANDBRAKE 0.3f
-
+#include "Pickups.h"
+
+#define DISTANCE_TO_SPAWN_ROADBLOCK_PEDS (51.0f)
+#define DISTANCE_TO_SCAN_FOR_DANGER (14.0f)
+#define DISTANCE_TO_SCAN_FOR_PED_DANGER (11.0f)
+#define SAFE_DISTANCE_TO_PED (3.0f)
+#define INFINITE_Z (1000000000.0f)
+
+#define VEHICLE_HEIGHT_DIFF_TO_CONSIDER_WEAVING (4.0f)
+#define PED_HEIGHT_DIFF_TO_CONSIDER_WEAVING (4.0f)
+#define OBJECT_HEIGHT_DIFF_TO_CONSIDER_WEAVING (8.0f)
+#define WIDTH_COEF_TO_WEAVE_SAFELY (1.2f)
+#define OBJECT_WIDTH_TO_WEAVE (0.3f)
+#define PED_WIDTH_TO_WEAVE (0.8f)
+
+#define PATH_DIRECTION_NONE (0)
+#define PATH_DIRECTION_STRAIGHT (1)
+#define PATH_DIRECTION_RIGHT (2)
+#define PATH_DIRECTION_LEFT (4)
+
+#define ATTEMPTS_TO_FIND_NEXT_NODE (15)
+
+#define DISTANCE_TO_SWITCH_FROM_BLOCK_TO_STOP (5.0f)
+#define DISTANCE_TO_SWITCH_FROM_STOP_TO_BLOCK (10.0f)
+#define MAX_SPEED_TO_ACCOUNT_IN_INTERCEPTING (0.13f)
+#define DISTANCE_TO_NEXT_NODE_TO_CONSIDER_SLOWING_DOWN (40.0f)
+#define MAX_ANGLE_TO_STEER_AT_HIGH_SPEED (0.2f)
+#define MIN_SPEED_TO_START_LIMITING_STEER (0.45f)
+#define DISTANCE_TO_NEXT_NODE_TO_SELECT_NEW (5.0f)
+#define DISTANCE_TO_FACING_NEXT_NODE_TO_SELECT_NEW (8.0f)
+#define DEFAULT_MAX_STEER_ANGLE (0.5f)
+#define MIN_LOWERING_SPEED_COEFFICIENT (0.4f)
+#define MAX_ANGLE_FOR_SPEED_LIMITING (1.2f)
+#define MIN_ANGLE_FOR_SPEED_LIMITING (0.4f)
+#define MIN_ANGLE_FOR_SPEED_LIMITING_BETWEEN_NODES (0.1f)
+#define MIN_ANGLE_TO_APPLY_HANDBRAKE (0.7f)
+#define MIN_SPEED_TO_APPLY_HANDBRAKE (0.3f)
+
+#define PROBABILITY_OF_DEAD_PED_ACCIDENT (0.005f)
+#define DISTANCE_BETWEEN_CAR_AND_DEAD_PED (6.0f)
+#define PROBABILITY_OF_PASSENGER_IN_VEHICLE (0.125f)
+
+#define ONSCREEN_DESPAWN_RANGE (120.0f)
+#define MINIMAL_DISTANCE_TO_SPAWN_ONSCREEN (100.0f)
+#define REQUEST_ONSCREEN_DISTANCE ((ONSCREEN_DESPAWN_RANGE + MINIMAL_DISTANCE_TO_SPAWN_ONSCREEN) / 2)
+#define OFFSCREEN_DESPAWN_RANGE (40.0f)
+#define EXTENDED_RANGE_DESPAWN_MULTIPLIER (1.5f)
+
+bool CCarCtrl::bMadDriversCheat;
int CCarCtrl::NumLawEnforcerCars;
int CCarCtrl::NumAmbulancesOnDuty;
int CCarCtrl::NumFiretrucksOnDuty;
@@ -81,23 +98,29 @@ int32 CCarCtrl::MaxNumberOfCarsInUse = DEFAULT_MAX_NUMBER_OF_CARS;
uint32 CCarCtrl::LastTimeLawEnforcerCreated;
uint32 CCarCtrl::LastTimeFireTruckCreated;
uint32 CCarCtrl::LastTimeAmbulanceCreated;
+int32 CCarCtrl::MiamiViceCycle;
+uint32 CCarCtrl::LastTimeMiamiViceGenerated;
int32 CCarCtrl::TotalNumOfCarsOfRating[TOTAL_CUSTOM_CLASSES];
-int32 CCarCtrl::NextCarOfRating[TOTAL_CUSTOM_CLASSES];
int32 CCarCtrl::CarArrays[TOTAL_CUSTOM_CLASSES][MAX_CAR_MODELS_IN_ARRAY];
+int32 CCarCtrl::NumRequestsOfCarRating[TOTAL_CUSTOM_CLASSES];
+int32 CCarCtrl::NumOfLoadedCarsOfRating[TOTAL_CUSTOM_CLASSES];
+int32 CCarCtrl::CarFreqArrays[TOTAL_CUSTOM_CLASSES][MAX_CAR_MODELS_IN_ARRAY];
+int32 CCarCtrl::LoadedCarsArray[TOTAL_CUSTOM_CLASSES][MAX_CAR_MODELS_IN_ARRAY];
CVehicle* apCarsToKeep[MAX_CARS_TO_KEEP];
uint32 aCarsToKeepTime[MAX_CARS_TO_KEEP];
void
CCarCtrl::GenerateRandomCars()
{
- if (CCutsceneMgr::IsRunning())
+ if (CCutsceneMgr::IsRunning()) {
+ CountDownToCarsAtStart = 2;
return;
+ }
if (NumRandomCars < 30){
- if (CountDownToCarsAtStart == 0){
+ if (CountDownToCarsAtStart == 0)
GenerateOneRandomCar();
- }
else if (--CountDownToCarsAtStart == 0) {
- for (int i = 0; i < 50; i++)
+ for (int i = 0; i < 100; i++)
GenerateOneRandomCar();
CTheCarGenerators::GenerateEvenIfPlayerIsCloseCounter = 20;
}
@@ -111,6 +134,7 @@ void
CCarCtrl::GenerateOneRandomCar()
{
static int32 unk = 0;
+ bool bTopDownCamera = false;
CPlayerInfo* pPlayer = &CWorld::Players[CWorld::PlayerInFocus];
CVector vecTargetPos = FindPlayerCentreOfWorld(CWorld::PlayerInFocus);
CVector2D vecPlayerSpeed = FindPlayerSpeed();
@@ -125,7 +149,7 @@ CCarCtrl::GenerateOneRandomCar()
int carClass;
int carModel;
if (pWanted->GetWantedLevel() > 1 && NumLawEnforcerCars < pWanted->m_MaximumLawEnforcerVehicles &&
- pWanted->m_CurrentCops < pWanted->m_MaxCops && (
+ pWanted->m_CurrentCops < pWanted->m_MaxCops && !CGame::IsInInterior() && (
pWanted->GetWantedLevel() > 3 ||
pWanted->GetWantedLevel() > 2 && CTimer::GetTimeInMilliseconds() > LastTimeLawEnforcerCreated + 5000 ||
pWanted->GetWantedLevel() > 1 && CTimer::GetTimeInMilliseconds() > LastTimeLawEnforcerCreated + 8000)) {
@@ -134,8 +158,8 @@ CCarCtrl::GenerateOneRandomCar()
carClass = COPS;
carModel = ChoosePoliceCarModel();
}else{
- carModel = ChooseModel(&zone, &vecTargetPos, &carClass);
- if (carClass == COPS && pWanted->GetWantedLevel() >= 1)
+ carModel = ChooseModel(&zone, &carClass);
+ if (carModel == -1 || (carClass == COPS && pWanted->GetWantedLevel() >= 1))
/* All cop spawns with wanted level are handled by condition above. */
/* In particular it means that cop cars never spawn if player has wanted level of 1. */
return;
@@ -159,8 +183,9 @@ CCarCtrl::GenerateOneRandomCar()
/* Spawn essentially anywhere. */
frontX = frontY = 0.707f; /* 45 degrees */
angleLimit = -1.0f;
+ bTopDownCamera = true;
invertAngleLimitTest = true;
- preferredDistance = 40.0f;
+ preferredDistance = OFFSCREEN_DESPAWN_RANGE + 15.0f;
/* BUG: testForCollision not initialized in original game. */
testForCollision = false;
}else if (!pPlayerVehicle){
@@ -174,14 +199,14 @@ CCarCtrl::GenerateOneRandomCar()
/* Forward to his current direction (camera direction). */
angleLimit = 0.707f; /* 45 degrees */
invertAngleLimitTest = true;
- preferredDistance = 120.0f * TheCamera.GenerationDistMultiplier;
+ preferredDistance = REQUEST_ONSCREEN_DISTANCE * TheCamera.GenerationDistMultiplier;
break;
case 1:
/* Spawn a vehicle close to player to his side. */
/* Kinda not within camera angle. */
angleLimit = 0.707f; /* 45 degrees */
invertAngleLimitTest = false;
- preferredDistance = 40.0f;
+ preferredDistance = OFFSCREEN_DESPAWN_RANGE;
break;
}
}else if (fPlayerVehicleSpeed > 0.4f){ /* 72 km/h */
@@ -196,21 +221,21 @@ CCarCtrl::GenerateOneRandomCar()
/* Spawn a vehicle in a very narrow gap in front of a player */
angleLimit = 0.85f; /* approx 30 degrees */
invertAngleLimitTest = true;
- preferredDistance = 120.0f * TheCamera.GenerationDistMultiplier;
+ preferredDistance = REQUEST_ONSCREEN_DISTANCE * TheCamera.GenerationDistMultiplier;
break;
case 2:
/* Spawn a vehicle relatively far away from player. */
/* Forward to his current direction (camera direction). */
angleLimit = 0.707f; /* 45 degrees */
invertAngleLimitTest = true;
- preferredDistance = 120.0f * TheCamera.GenerationDistMultiplier;
+ preferredDistance = REQUEST_ONSCREEN_DISTANCE * TheCamera.GenerationDistMultiplier;
break;
case 3:
/* Spawn a vehicle close to player to his side. */
/* Kinda not within camera angle. */
angleLimit = 0.707f; /* 45 degrees */
invertAngleLimitTest = false;
- preferredDistance = 40.0f;
+ preferredDistance = OFFSCREEN_DESPAWN_RANGE;
break;
}
}else if (fPlayerVehicleSpeed > 0.1f){ /* 18 km/h */
@@ -224,14 +249,14 @@ CCarCtrl::GenerateOneRandomCar()
/* Spawn a vehicle in a very narrow gap in front of a player */
angleLimit = 0.85f; /* approx 30 degrees */
invertAngleLimitTest = true;
- preferredDistance = 120.0f * TheCamera.GenerationDistMultiplier;
+ preferredDistance = REQUEST_ONSCREEN_DISTANCE * TheCamera.GenerationDistMultiplier;
break;
case 1:
/* Spawn a vehicle relatively far away from player. */
/* Forward to his current direction (camera direction). */
angleLimit = 0.707f; /* 45 degrees */
invertAngleLimitTest = true;
- preferredDistance = 120.0f * TheCamera.GenerationDistMultiplier;
+ preferredDistance = REQUEST_ONSCREEN_DISTANCE * TheCamera.GenerationDistMultiplier;
break;
case 2:
case 3:
@@ -239,7 +264,7 @@ CCarCtrl::GenerateOneRandomCar()
/* Kinda not within camera angle. */
angleLimit = 0.707f; /* 45 degrees */
invertAngleLimitTest = false;
- preferredDistance = 40.0f;
+ preferredDistance = OFFSCREEN_DESPAWN_RANGE;
break;
}
}else{
@@ -254,32 +279,60 @@ CCarCtrl::GenerateOneRandomCar()
/* Forward to his current direction (camera direction). */
angleLimit = 0.707f; /* 45 degrees */
invertAngleLimitTest = true;
- preferredDistance = 120.0f * TheCamera.GenerationDistMultiplier;
+ preferredDistance = REQUEST_ONSCREEN_DISTANCE * TheCamera.GenerationDistMultiplier;
break;
case 1:
/* Spawn a vehicle close to player to his side. */
/* Kinda not within camera angle. */
angleLimit = 0.707f; /* 45 degrees */
invertAngleLimitTest = false;
- preferredDistance = 40.0f;
+ preferredDistance = OFFSCREEN_DESPAWN_RANGE;
break;
}
}
- if (!ThePaths.NewGenerateCarCreationCoors(vecTargetPos.x, vecTargetPos.y, frontX, frontY,
+ if (!ThePaths.GenerateCarCreationCoors(vecTargetPos.x, vecTargetPos.y, frontX, frontY,
preferredDistance, angleLimit, invertAngleLimitTest, &spawnPosition, &curNodeId, &nextNodeId,
&positionBetweenNodes, carClass == COPS && pWanted->GetWantedLevel() >= 1))
return;
+ CPathNode* pCurNode = &ThePaths.m_pathNodes[curNodeId];
+ CPathNode* pNextNode = &ThePaths.m_pathNodes[nextNodeId];
+ bool bBoatGenerated = false;
+ if ((CGeneral::GetRandomNumber() & 0xF) > Min(pCurNode->spawnRate, pNextNode->spawnRate))
+ return;
+ if (pCurNode->bWaterPath) {
+ bBoatGenerated = true;
+ if (carClass == COPS) {
+ carModel = MI_PREDATOR;
+ carClass = COPS_BOAT;
+ if (!CStreaming::HasModelLoaded(MI_PREDATOR)) {
+ CStreaming::RequestModel(MI_PREDATOR, STREAMFLAGS_DEPENDENCY);
+ return;
+ }
+ }
+ else {
+ int i;
+ carModel = -1;
+ for (i = 10; i > 0 && (carModel == -1 || !CStreaming::HasModelLoaded(carModel)); i--) {
+ carModel = ChooseBoatModel(ChooseBoatRating(&zone));
+ }
+ if (i == 0)
+ return;
+ }
+ if (pCurNode->bOnlySmallBoats || pNextNode->bOnlySmallBoats) {
+ if (BoatWithTallMast(carModel))
+ return;
+ }
+ }
int16 colliding;
- CWorld::FindObjectsKindaColliding(spawnPosition, 10.0f, true, &colliding, 2, nil, false, true, true, false, false);
+ CWorld::FindObjectsKindaColliding(spawnPosition, bBoatGenerated ? 40.0f : 10.0f, true, &colliding, 2, nil, false, true, true, false, false);
if (colliding)
/* If something is already present in spawn position, do not create vehicle*/
return;
- if (!ThePaths.TestCoorsCloseness(vecTargetPos, false, spawnPosition))
+ if (!bBoatGenerated && !ThePaths.TestCoorsCloseness(vecTargetPos, false, spawnPosition))
/* Testing if spawn position can reach target position via valid path. */
return;
int16 idInNode = 0;
- CPathNode* pCurNode = &ThePaths.m_pathNodes[curNodeId];
- CPathNode* pNextNode = &ThePaths.m_pathNodes[nextNodeId];
+
while (idInNode < pCurNode->numLinks &&
ThePaths.ConnectedNode(idInNode + pCurNode->firstLink) != nextNodeId)
idInNode++;
@@ -287,48 +340,20 @@ CCarCtrl::GenerateOneRandomCar()
CCarPathLink* pPathLink = &ThePaths.m_carPathLinks[connectionId];
int16 lanesOnCurrentRoad = pPathLink->pathNodeIndex == nextNodeId ? pPathLink->numLeftLanes : pPathLink->numRightLanes;
CVehicleModelInfo* pModelInfo = (CVehicleModelInfo*)CModelInfo::GetModelInfo(carModel);
- if (lanesOnCurrentRoad == 0 || pModelInfo->m_vehicleType == VEHICLE_TYPE_BIKE)
+ if (lanesOnCurrentRoad == 0)
/* Not spawning vehicle if road is one way and intended direction is opposide to that way. */
- /* Also not spawning bikes but they don't exist in final game. */
return;
- CAutomobile* pVehicle = new CAutomobile(carModel, RANDOM_VEHICLE);
+ CVehicle* pVehicle;
+ if (CModelInfo::IsBoatModel(carModel))
+ pVehicle = new CBoat(carModel, RANDOM_VEHICLE);
+ else if (CModelInfo::IsBikeModel(carModel))
+ pVehicle = new CBike(carModel, RANDOM_VEHICLE);
+ else
+ pVehicle = new CAutomobile(carModel, RANDOM_VEHICLE);
pVehicle->AutoPilot.m_nPrevRouteNode = 0;
pVehicle->AutoPilot.m_nCurrentRouteNode = curNodeId;
pVehicle->AutoPilot.m_nNextRouteNode = nextNodeId;
switch (carClass) {
- case POOR:
- case RICH:
- case EXEC:
- case WORKER:
- case SPECIAL:
- case BIG:
- case TAXI:
- case MAFIA:
- case TRIAD:
- case DIABLO:
- case YAKUZA:
- case YARDIE:
- case COLOMB:
- case NINES:
- case GANG8:
- case GANG9:
- {
- pVehicle->AutoPilot.m_nCruiseSpeed = CGeneral::GetRandomNumberInRange(9, 14);
- if (carClass == EXEC)
- pVehicle->AutoPilot.m_nCruiseSpeed = CGeneral::GetRandomNumberInRange(12, 18);
- else if (carClass == POOR || carClass == SPECIAL)
- pVehicle->AutoPilot.m_nCruiseSpeed = CGeneral::GetRandomNumberInRange(7, 10);
- CVehicleModelInfo* pVehicleInfo = pVehicle->GetModelInfo();
- if (pVehicleInfo->GetColModel()->boundingBox.max.y - pVehicle->GetModelInfo()->GetColModel()->boundingBox.min.y > 10.0f || carClass == BIG) {
- pVehicle->AutoPilot.m_nCruiseSpeed *= 3;
- pVehicle->AutoPilot.m_nCruiseSpeed /= 4;
- }
- pVehicle->AutoPilot.m_fMaxTrafficSpeed = pVehicle->AutoPilot.m_nCruiseSpeed;
- pVehicle->AutoPilot.m_nCarMission = MISSION_CRUISE;
- pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE;
- pVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_STOP_FOR_CARS;
- break;
- }
case COPS:
pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE;
if (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted->GetWantedLevel() != 0){
@@ -342,19 +367,40 @@ CCarCtrl::GenerateOneRandomCar()
pVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_STOP_FOR_CARS;
pVehicle->AutoPilot.m_nCarMission = MISSION_CRUISE;
}
- if (carModel == MI_FBICAR){
+ if (carModel == MI_FBIRANCH){
pVehicle->m_currentColour1 = 0;
pVehicle->m_currentColour2 = 0;
- /* FBI cars are gray in carcols, but we want them black if they going after player. */
}
+ pVehicle->bCreatedAsPoliceVehicle = true;
+ break;
+ case COPS_BOAT:
+ pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE;
+ pVehicle->AutoPilot.m_nCruiseSpeed = CGeneral::GetRandomNumberInRange(4, 16);
+ pVehicle->AutoPilot.m_fMaxTrafficSpeed = pVehicle->AutoPilot.m_nCruiseSpeed;
+ pVehicle->AutoPilot.m_nCarMission = CCarAI::FindPoliceBoatMissionForWantedLevel();
+ pVehicle->bCreatedAsPoliceVehicle = true;
+ break;
default:
+ pVehicle->AutoPilot.m_nCruiseSpeed = CGeneral::GetRandomNumberInRange(9, 14);
+ if (carClass == EXEC)
+ pVehicle->AutoPilot.m_nCruiseSpeed = CGeneral::GetRandomNumberInRange(12, 18);
+ else if (carClass == POOR)
+ pVehicle->AutoPilot.m_nCruiseSpeed = CGeneral::GetRandomNumberInRange(7, 10);
+ if (pVehicle->GetColModel()->boundingBox.max.y - pVehicle->GetColModel()->boundingBox.min.y > 10.0f || carClass == BIG) {
+ pVehicle->AutoPilot.m_nCruiseSpeed *= 3;
+ pVehicle->AutoPilot.m_nCruiseSpeed /= 4;
+ }
+ pVehicle->AutoPilot.m_fMaxTrafficSpeed = pVehicle->AutoPilot.m_nCruiseSpeed;
+ pVehicle->AutoPilot.m_nCarMission = MISSION_CRUISE;
+ pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE;
+ pVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_STOP_FOR_CARS;
break;
}
if (pVehicle && pVehicle->GetModelIndex() == MI_MRWHOOP)
pVehicle->m_bSirenOrAlarm = true;
pVehicle->AutoPilot.m_nNextPathNodeInfo = connectionId;
pVehicle->AutoPilot.m_nNextLane = pVehicle->AutoPilot.m_nCurrentLane = CGeneral::GetRandomNumber() % lanesOnCurrentRoad;
- CColBox* boundingBox = &CModelInfo::GetColModel(pVehicle->GetModelIndex())->boundingBox;
+ CBox* boundingBox = &CModelInfo::GetColModel(pVehicle->GetModelIndex())->boundingBox;
float carLength = 1.0f + (boundingBox->max.y - boundingBox->min.y) / 2;
float distanceBetweenNodes = (pCurNode->GetPosition() - pNextNode->GetPosition()).Magnitude2D();
/* If car is so long that it doesn't fit between two car nodes, place it directly in the middle. */
@@ -478,6 +524,7 @@ CCarCtrl::GenerateOneRandomCar()
pVehicle->AutoPilot.m_nTimeEnteredCurve = CTimer::GetTimeInMilliseconds() -
(0.5f + positionBetweenNodes) * pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve;
#endif
+
CVector directionCurrentLink(directionCurrentLinkX, directionCurrentLinkY, 0.0f);
CVector directionNextLink(directionNextLinkX, directionNextLinkY, 0.0f);
CVector positionIncludingCurve;
@@ -499,62 +546,69 @@ CCarCtrl::GenerateOneRandomCar()
float groundZ = INFINITE_Z;
CColPoint colPoint;
CEntity* pEntity;
- if (CWorld::ProcessVerticalLine(finalPosition, 1000.0f, colPoint, pEntity, true, false, false, false, true, false, nil))
- groundZ = colPoint.point.z;
- if (CWorld::ProcessVerticalLine(finalPosition, -1000.0f, colPoint, pEntity, true, false, false, false, true, false, nil)){
- if (ABS(colPoint.point.z - finalPosition.z) < ABS(groundZ - finalPosition.z))
+ if (bBoatGenerated) {
+ if (!CWaterLevel::GetWaterLevel(finalPosition, &groundZ, true)) {
+ delete pVehicle;
+ return;
+ }
+ }
+ else {
+ if (CWorld::ProcessVerticalLine(finalPosition, 1000.0f, colPoint, pEntity, true, false, false, false, true, false, nil))
groundZ = colPoint.point.z;
+ if (CWorld::ProcessVerticalLine(finalPosition, -1000.0f, colPoint, pEntity, true, false, false, false, true, false, nil)) {
+ if (ABS(colPoint.point.z - finalPosition.z) < ABS(groundZ - finalPosition.z))
+ groundZ = colPoint.point.z;
+ }
}
if (groundZ == INFINITE_Z || ABS(groundZ - finalPosition.z) > 7.0f) {
/* Failed to find ground or too far from expected position. */
delete pVehicle;
return;
}
- finalPosition.z = groundZ + pVehicle->GetHeightAboveRoad();
+ if (CModelInfo::IsBoatModel(carModel)) {
+ finalPosition.z = groundZ;
+ pVehicle->bExtendedRange = true;
+ }
+ else
+ finalPosition.z = groundZ + pVehicle->GetHeightAboveRoad();
pVehicle->SetPosition(finalPosition);
pVehicle->SetMoveSpeed(directionIncludingCurve / GAME_SPEED_TO_CARAI_SPEED);
CVector2D speedDifferenceWithTarget = (CVector2D)pVehicle->GetMoveSpeed() - vecPlayerSpeed;
CVector2D distanceToTarget = positionIncludingCurve - vecTargetPos;
switch (carClass) {
- case POOR:
- case RICH:
- case EXEC:
- case WORKER:
- case SPECIAL:
- case BIG:
- case TAXI:
- case MAFIA:
- case TRIAD:
- case DIABLO:
- case YAKUZA:
- case YARDIE:
- case COLOMB:
- case NINES:
- case GANG8:
- case GANG9:
- pVehicle->SetStatus(STATUS_SIMPLE);
- break;
case COPS:
pVehicle->SetStatus((pVehicle->AutoPilot.m_nCarMission == MISSION_CRUISE) ? STATUS_SIMPLE : STATUS_PHYSICS);
pVehicle->ChangeLawEnforcerState(1);
break;
+ case COPS_BOAT:
+ pVehicle->ChangeLawEnforcerState(1);
+ pVehicle->SetStatus(STATUS_PHYSICS);
+ break;
default:
+ bBoatGenerated ? pVehicle->SetStatus(STATUS_PHYSICS) : pVehicle->SetStatus(STATUS_SIMPLE);
break;
}
CVisibilityPlugins::SetClumpAlpha(pVehicle->GetClump(), 0);
if (!pVehicle->GetIsOnScreen()){
- if ((vecTargetPos - pVehicle->GetPosition()).Magnitude2D() > 50.0f) {
+ if ((vecTargetPos - pVehicle->GetPosition()).Magnitude2D() > OFFSCREEN_DESPAWN_RANGE * (pVehicle->bExtendedRange ? EXTENDED_RANGE_DESPAWN_MULTIPLIER : 1.0f)) {
/* Too far away cars that are not visible aren't needed. */
delete pVehicle;
return;
}
- }else if((vecTargetPos - pVehicle->GetPosition()).Magnitude2D() > TheCamera.GenerationDistMultiplier * 130.0f ||
- (vecTargetPos - pVehicle->GetPosition()).Magnitude2D() < TheCamera.GenerationDistMultiplier * 110.0f){
- delete pVehicle;
- return;
- }else if((TheCamera.GetPosition() - pVehicle->GetPosition()).Magnitude2D() < 90.0f * TheCamera.GenerationDistMultiplier){
- delete pVehicle;
- return;
+ }else{
+ if ((vecTargetPos - pVehicle->GetPosition()).Magnitude2D() > TheCamera.GenerationDistMultiplier * (pVehicle->bExtendedRange ? EXTENDED_RANGE_DESPAWN_MULTIPLIER : 1.0f) * ONSCREEN_DESPAWN_RANGE ||
+ (vecTargetPos - pVehicle->GetPosition()).Magnitude2D() < TheCamera.GenerationDistMultiplier * MINIMAL_DISTANCE_TO_SPAWN_ONSCREEN) {
+ delete pVehicle;
+ return;
+ }
+ if ((TheCamera.GetPosition() - pVehicle->GetPosition()).Magnitude2D() < 82.5f * TheCamera.GenerationDistMultiplier || bTopDownCamera) {
+ delete pVehicle;
+ return;
+ }
+ if (pVehicle->GetModelIndex() == MI_MARQUIS) { // so marquis can only spawn if player doesn't see it?
+ delete pVehicle;
+ return;
+ }
}
CVehicleModelInfo* pVehicleModel = pVehicle->GetModelInfo();
float radiusToTest = pVehicleModel->GetColModel()->boundingSphere.radius;
@@ -577,59 +631,156 @@ CCarCtrl::GenerateOneRandomCar()
}
pVehicleModel->AvoidSameVehicleColour(&pVehicle->m_currentColour1, &pVehicle->m_currentColour2);
CWorld::Add(pVehicle);
- if (carClass == COPS)
+ if (carClass == COPS || carClass == COPS_BOAT)
CCarAI::AddPoliceCarOccupants(pVehicle);
- else
+ else {
pVehicle->SetUpDriver();
- if ((CGeneral::GetRandomNumber() & 0x3F) == 0){ /* 1/64 probability */
+ int32 passengers = 0;
+ for (int i = 0; i < pVehicle->m_nNumMaxPassengers; i++)
+ passengers += (CGeneral::GetRandomNumberInRange(0.0f, 1.0f) < PROBABILITY_OF_PASSENGER_IN_VEHICLE) ? 1 : 0;
+ if (CModelInfo::IsCarModel(carModel) && (CModelInfo::GetModelInfo(carModel)->GetAnimFileIndex() == CAnimManager::GetAnimationBlockIndex("van") && passengers >= 1))
+ passengers = 1;
+ for (int i = 0; i < passengers; i++) {
+ CPed* pPassenger = pVehicle->SetupPassenger(i);
+ if (pPassenger) {
+ ++CPopulation::ms_nTotalCarPassengerPeds;
+ pPassenger->bCarPassenger = true;
+ }
+ }
+ }
+ int nMadDrivers;
+ switch (pVehicle->GetVehicleAppearance()) {
+ case VEHICLE_APPEARANCE_BIKE:
+ nMadDrivers = 30;
+ break;
+ case VEHICLE_APPEARANCE_BOAT:
+ nMadDrivers = 40;
+ break;
+ default:
+ nMadDrivers = 6;
+ break;
+ }
+ if ((CGeneral::GetRandomNumber() & 0x7F) < nMadDrivers || bMadDriversCheat) {
pVehicle->SetStatus(STATUS_PHYSICS);
pVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS;
pVehicle->AutoPilot.m_nCruiseSpeed += 10;
}
if (carClass == COPS)
LastTimeLawEnforcerCreated = CTimer::GetTimeInMilliseconds();
+ if (pVehicle->GetModelIndex() == MI_CADDY) {
+ pVehicle->SetStatus(STATUS_PHYSICS);
+ pVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS;
+ }
+ if (carClass == COPS && pVehicle->GetModelIndex() == MI_VICECHEE) {
+ CVehicleModelInfo* pVehicleModel = (CVehicleModelInfo*)CModelInfo::GetModelInfo(MI_VICECHEE);
+ switch (MiamiViceCycle) {
+ case 0:
+ pVehicleModel->SetVehicleColour(53, 77);
+ break;
+ case 1:
+ pVehicleModel->SetVehicleColour(15, 77);
+ break;
+ case 2:
+ pVehicleModel->SetVehicleColour(41, 77);
+ break;
+ case 3:
+ pVehicleModel->SetVehicleColour(61, 77);
+ break;
+ default:
+ break;
+ }
+ }
+ if (CGeneral::GetRandomNumberInRange(0.0f, 1.0f) >= (1 - PROBABILITY_OF_DEAD_PED_ACCIDENT)) {
+ if (CModelInfo::IsCarModel(pVehicle->GetModelIndex()) && !pVehicle->bIsLawEnforcer) {
+ if (CPopulation::AddDeadPedInFrontOfCar(pVehicle->GetPosition() + pVehicle->GetForward() * DISTANCE_BETWEEN_CAR_AND_DEAD_PED, pVehicle)) {
+ pVehicle->AutoPilot.m_nCruiseSpeed = 0;
+ pVehicle->SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ for (int i = 0; i < pVehicle->m_nNumPassengers; i++) {
+ if (pVehicle->pPassengers[i]) {
+ pVehicle->pPassengers[i]->SetObjective(OBJECTIVE_LEAVE_CAR, pVehicle);
+ pVehicle->pPassengers[i]->m_nLastPedState = PED_WANDER_PATH;
+ pVehicle->pPassengers[i]->m_vehicleInAccident = pVehicle;
+ pVehicle->pPassengers[i]->bDeadPedInFrontOfCar = true;
+ pVehicle->RegisterReference((CEntity**)&pVehicle->pPassengers[i]->m_vehicleInAccident);
+ }
+ }
+ if (pVehicle->pDriver) {
+ pVehicle->pDriver->SetObjective(OBJECTIVE_LEAVE_CAR, pVehicle);
+ pVehicle->pDriver->m_nLastPedState = PED_WANDER_PATH;
+ pVehicle->pDriver->m_vehicleInAccident = pVehicle;
+ pVehicle->pDriver->bDeadPedInFrontOfCar = true;
+ pVehicle->RegisterReference((CEntity**)&pVehicle->pDriver->m_vehicleInAccident);
+ }
+ }
+ }
+ }
+}
+
+bool
+CCarCtrl::BoatWithTallMast(int32 mi)
+{
+ return mi == MI_RIO || mi == MI_TROPIC || mi == MI_MARQUIS;
+}
+
+int32
+CCarCtrl::ChooseBoatModel(int32 rating)
+{
+ ++NumRequestsOfCarRating[rating];
+ return ChooseCarModel(rating);
+}
+
+int32
+CCarCtrl::ChooseBoatRating(CZoneInfo* pZoneInfo)
+{
+ int rnd = CGeneral::GetRandomNumberInRange(0, 1000);
+ for (int i = 0; i < NUM_BOAT_CLASSES - 1; i++) {
+ if (rnd < pZoneInfo->boatThreshold[i])
+ return FIRST_BOAT_RATING + i;
+ }
+ return FIRST_BOAT_RATING + NUM_BOAT_CLASSES - 1;
}
int32
-CCarCtrl::ChooseModel(CZoneInfo* pZone, CVector* pPos, int* pClass) {
+CCarCtrl::ChooseCarRating(CZoneInfo* pZoneInfo)
+{
+ int rnd = CGeneral::GetRandomNumberInRange(0, 1000);
+ for (int i = 0; i < NUM_CAR_CLASSES - 1; i++) {
+ if (rnd < pZoneInfo->carThreshold[i])
+ return i;
+ }
+ return FIRST_CAR_RATING + NUM_CAR_CLASSES - 1;
+}
+
+int32
+CCarCtrl::ChooseModel(CZoneInfo* pZone, int* pClass) {
int32 model = -1;
- while (model == -1 || !CStreaming::HasModelLoaded(model)){
+ int32 i;
+ for (i = 10; i > 0 && (model == -1 || !CStreaming::HasModelLoaded(model)); i--) {
int rnd = CGeneral::GetRandomNumberInRange(0, 1000);
- if (rnd < pZone->carThreshold[0])
- model = CCarCtrl::ChooseCarModel((*pClass = POOR));
- else if (rnd < pZone->carThreshold[1])
- model = CCarCtrl::ChooseCarModel((*pClass = RICH));
- else if (rnd < pZone->carThreshold[2])
- model = CCarCtrl::ChooseCarModel((*pClass = EXEC));
- else if (rnd < pZone->carThreshold[3])
- model = CCarCtrl::ChooseCarModel((*pClass = WORKER));
- else if (rnd < pZone->carThreshold[4])
- model = CCarCtrl::ChooseCarModel((*pClass = SPECIAL));
- else if (rnd < pZone->carThreshold[5])
- model = CCarCtrl::ChooseCarModel((*pClass = BIG));
- else if (rnd < pZone->copThreshold)
- *pClass = COPS, model = CCarCtrl::ChoosePoliceCarModel();
- else if (rnd < pZone->gangThreshold[0])
- model = CCarCtrl::ChooseGangCarModel((*pClass = MAFIA) - MAFIA);
- else if (rnd < pZone->gangThreshold[1])
- model = CCarCtrl::ChooseGangCarModel((*pClass = TRIAD) - MAFIA);
- else if (rnd < pZone->gangThreshold[2])
- model = CCarCtrl::ChooseGangCarModel((*pClass = DIABLO) - MAFIA);
- else if (rnd < pZone->gangThreshold[3])
- model = CCarCtrl::ChooseGangCarModel((*pClass = YAKUZA) - MAFIA);
- else if (rnd < pZone->gangThreshold[4])
- model = CCarCtrl::ChooseGangCarModel((*pClass = YARDIE) - MAFIA);
- else if (rnd < pZone->gangThreshold[5])
- model = CCarCtrl::ChooseGangCarModel((*pClass = COLOMB) - MAFIA);
- else if (rnd < pZone->gangThreshold[6])
- model = CCarCtrl::ChooseGangCarModel((*pClass = NINES) - MAFIA);
- else if (rnd < pZone->gangThreshold[7])
- model = CCarCtrl::ChooseGangCarModel((*pClass = GANG8) - MAFIA);
- else if (rnd < pZone->gangThreshold[8])
- model = CCarCtrl::ChooseGangCarModel((*pClass = GANG9) - MAFIA);
- else
- model = CCarCtrl::ChooseCarModel((*pClass = TAXI));
+
+ if (rnd < pZone->copThreshold) {
+ *pClass = COPS;
+ model = ChoosePoliceCarModel();
+ continue;
+ }
+
+ int32 j;
+ for (j = 0; j < NUM_GANG_CAR_CLASSES; j++) {
+ if (rnd < pZone->gangThreshold[j]) {
+ *pClass = j + FIRST_GANG_CAR_RATING;
+ model = ChooseGangCarModel(j);
+ break;
+ }
+ }
+
+ if (j != NUM_GANG_CAR_CLASSES)
+ continue;
+
+ *pClass = ChooseCarRating(pZone);
+ model = ChooseCarModel(*pClass);
}
+ if (i == 0)
+ return -1;
return model;
}
@@ -637,42 +788,94 @@ int32
CCarCtrl::ChooseCarModel(int32 vehclass)
{
int32 model = -1;
- switch (vehclass) {
- case POOR:
- case RICH:
- case EXEC:
- case WORKER:
- case SPECIAL:
- case BIG:
- case TAXI:
- {
- if (TotalNumOfCarsOfRating[vehclass] == 0)
- debug("ChooseCarModel : No cars of type %d have been declared\n", vehclass);
- model = CarArrays[vehclass][NextCarOfRating[vehclass]];
- int32 total = TotalNumOfCarsOfRating[vehclass];
- NextCarOfRating[vehclass] += CGeneral::GetRandomNumberInRange(1, total);
- while (NextCarOfRating[vehclass] >= total)
- NextCarOfRating[vehclass] -= total;
- //NextCarOfRating[vehclass] %= total;
- TotalNumOfCarsOfRating[vehclass] = total; /* why... */
- }
- default:
- break;
- }
- return model;
+ ++NumRequestsOfCarRating[vehclass];
+ if (NumOfLoadedCarsOfRating[vehclass] == 0)
+ return -1;
+ int32 rnd = CGeneral::GetRandomNumberInRange(0, CarFreqArrays[vehclass][NumOfLoadedCarsOfRating[vehclass] - 1]);
+ int32 index = 0;
+ while (rnd > CarFreqArrays[vehclass][index])
+ index++;
+ assert(LoadedCarsArray[vehclass][index]);
+ return LoadedCarsArray[vehclass][index];
+}
+
+void
+CCarCtrl::AddToLoadedVehicleArray(int32 mi, int32 rating, int32 freq)
+{
+ LoadedCarsArray[rating][NumOfLoadedCarsOfRating[rating]] = mi;
+ assert(mi >= 130);
+ CarFreqArrays[rating][NumOfLoadedCarsOfRating[rating]] = freq;
+ if (NumOfLoadedCarsOfRating[rating])
+ CarFreqArrays[rating][NumOfLoadedCarsOfRating[rating]] += CarFreqArrays[rating][NumOfLoadedCarsOfRating[rating] - 1];
+ NumOfLoadedCarsOfRating[rating]++;
+}
+
+void
+CCarCtrl::RemoveFromLoadedVehicleArray(int mi, int32 rating)
+{
+ int index = 0;
+ while (LoadedCarsArray[rating][index] != -1) {
+ if (LoadedCarsArray[rating][index] == mi)
+ break;
+ index++;
+ }
+ assert(LoadedCarsArray[rating][index] == mi);
+ int32 freq = CarFreqArrays[rating][index];
+ if (index > 0)
+ freq -= CarFreqArrays[rating][index - 1];
+ while (LoadedCarsArray[rating][index + 1] != -1) {
+ LoadedCarsArray[rating][index] = LoadedCarsArray[rating][index + 1];
+ CarFreqArrays[rating][index] = CarFreqArrays[rating][index + 1] - freq;
+ index++;
+ }
+ --NumOfLoadedCarsOfRating[rating];
+}
+
+int32
+CCarCtrl::ChooseCarModelToLoad(int rating)
+{
+ return CarArrays[rating][CGeneral::GetRandomNumberInRange(0, TotalNumOfCarsOfRating[rating])];
}
int32
CCarCtrl::ChoosePoliceCarModel(void)
{
+ if (FindPlayerPed()->m_pWanted->AreMiamiViceRequired() &&
+#ifdef FIX_BUGS
+ (CTimer::GetTimeInMilliseconds() > LastTimeMiamiViceGenerated + 120000 || LastTimeMiamiViceGenerated == 0) &&
+#else
+ CTimer::GetTimeInMilliseconds() > LastTimeMiamiViceGenerated + 120000 &&
+#endif
+ CStreaming::HasModelLoaded(MI_VICECHEE)) {
+ switch (MiamiViceCycle) {
+ case 0:
+ if (CStreaming::HasModelLoaded(MI_VICE1) && CStreaming::HasModelLoaded(MI_VICE2))
+ return MI_VICECHEE;
+ break;
+ case 1:
+ if (CStreaming::HasModelLoaded(MI_VICE3) && CStreaming::HasModelLoaded(MI_VICE4))
+ return MI_VICECHEE;
+ break;
+ case 2:
+ if (CStreaming::HasModelLoaded(MI_VICE5) && CStreaming::HasModelLoaded(MI_VICE6))
+ return MI_VICECHEE;
+ break;
+ case 3:
+ if (CStreaming::HasModelLoaded(MI_VICE7) && CStreaming::HasModelLoaded(MI_VICE8))
+ return MI_VICECHEE;
+ break;
+ default:
+ break;
+ }
+ }
if (FindPlayerPed()->m_pWanted->AreSwatRequired() &&
CStreaming::HasModelLoaded(MI_ENFORCER) &&
CStreaming::HasModelLoaded(MI_POLICE))
return ((CGeneral::GetRandomNumber() & 0xF) == 0) ? MI_ENFORCER : MI_POLICE;
if (FindPlayerPed()->m_pWanted->AreFbiRequired() &&
- CStreaming::HasModelLoaded(MI_FBICAR) &&
+ CStreaming::HasModelLoaded(MI_FBIRANCH) &&
CStreaming::HasModelLoaded(MI_FBI))
- return MI_FBICAR;
+ return MI_FBIRANCH;
if (FindPlayerPed()->m_pWanted->AreArmyRequired() &&
CStreaming::HasModelLoaded(MI_RHINO) &&
CStreaming::HasModelLoaded(MI_BARRACKS) &&
@@ -684,8 +887,7 @@ CCarCtrl::ChoosePoliceCarModel(void)
int32
CCarCtrl::ChooseGangCarModel(int32 gang)
{
- if (CStreaming::HasModelLoaded(MI_GANG01 + 2 * gang) &&
- CStreaming::HasModelLoaded(MI_GANG02 + 2 * gang))
+ if (CGangs::HaveGangModelsLoaded(gang))
return CGangs::GetGangVehicleModel(gang);
return -1;
}
@@ -693,6 +895,7 @@ CCarCtrl::ChooseGangCarModel(int32 gang)
void
CCarCtrl::AddToCarArray(int32 id, int32 vehclass)
{
+ assert(TotalNumOfCarsOfRating[vehclass] < MAX_CAR_MODELS_IN_ARRAY);
CarArrays[vehclass][TotalNumOfCarsOfRating[vehclass]++] = id;
}
@@ -706,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;
}
}
@@ -714,6 +917,36 @@ CCarCtrl::RemoveDistantCars()
}
void
+CCarCtrl::RemoveCarsIfThePoolGetsFull(void)
+{
+ if ((CTimer::GetFrameCounter() & 7) != 3)
+ return;
+ if (CPools::GetVehiclePool()->GetNoOfFreeSpaces() >= 8)
+ return;
+ int i = CPools::GetVehiclePool()->GetSize();
+ float md = 10000000.f;
+ CVehicle* pClosestVehicle = nil;
+ while (i--) {
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
+ if (!pVehicle)
+ continue;
+ if (IsThisVehicleInteresting(pVehicle) || pVehicle->bIsLocked)
+ continue;
+ if (!pVehicle->CanBeDeleted() || CCranes::IsThisCarBeingTargettedByAnyCrane(pVehicle))
+ continue;
+ float distance = (TheCamera.GetPosition() - pVehicle->GetPosition()).Magnitude();
+ if (distance < md) {
+ md = distance;
+ pClosestVehicle = pVehicle;
+ }
+ }
+ if (pClosestVehicle) {
+ CWorld::Remove(pClosestVehicle);
+ delete pClosestVehicle;
+ }
+}
+
+void
CCarCtrl::PossiblyRemoveVehicle(CVehicle* pVehicle)
{
#ifdef FIX_BUGS
@@ -730,7 +963,7 @@ CCarCtrl::PossiblyRemoveVehicle(CVehicle* pVehicle)
return;
}
float distanceToPlayer = (pVehicle->GetPosition() - vecPlayerPos).Magnitude2D();
- float threshold = 50.0f;
+ float threshold = OFFSCREEN_DESPAWN_RANGE;
#ifndef EXTENDED_OFFSCREEN_DESPAWN_RANGE
if (pVehicle->GetIsOnScreen() ||
TheCamera.Cams[TheCamera.ActiveCam].LookingLeft ||
@@ -741,16 +974,21 @@ CCarCtrl::PossiblyRemoveVehicle(CVehicle* pVehicle)
pVehicle->GetModelIndex() == MI_AMBULAN ||
pVehicle->GetModelIndex() == MI_FIRETRUCK ||
pVehicle->bIsLawEnforcer ||
- pVehicle->bIsCarParkVehicle
+ pVehicle->bIsCarParkVehicle ||
+ CTimer::GetTimeInMilliseconds() < pVehicle->m_nSetPieceExtendedRangeTime
)
#endif
{
- threshold = 130.0f * TheCamera.GenerationDistMultiplier;
+ threshold = ONSCREEN_DESPAWN_RANGE * TheCamera.GenerationDistMultiplier;
}
+#ifndef EXTENDED_OFFSCREEN_DESPAWN_RANGE
+ if (TheCamera.GetForward().z < -0.9f)
+ threshold = 70.0f;
+#endif
if (pVehicle->bExtendedRange)
- threshold *= 1.5f;
+ threshold *= EXTENDED_RANGE_DESPAWN_MULTIPLIER;
if (distanceToPlayer > threshold && !CGarages::IsPointWithinHideOutGarage(pVehicle->GetPosition())){
- if (pVehicle->GetIsOnScreen() && CRenderer::IsEntityCullZoneVisible(pVehicle)) {
+ if (pVehicle->GetIsOnScreen()){
pVehicle->bFadeOut = true;
}else{
CWorld::Remove(pVehicle);
@@ -759,10 +997,11 @@ CCarCtrl::PossiblyRemoveVehicle(CVehicle* pVehicle)
return;
}
}
- if ((pVehicle->GetStatus() == STATUS_SIMPLE || pVehicle->GetStatus() == STATUS_PHYSICS && pVehicle->AutoPilot.m_nDrivingStyle == DRIVINGSTYLE_STOP_FOR_CARS) &&
+ if ((pVehicle->GetStatus() == STATUS_SIMPLE || pVehicle->GetStatus() == STATUS_PHYSICS &&
+ (pVehicle->AutoPilot.m_nDrivingStyle == DRIVINGSTYLE_STOP_FOR_CARS || pVehicle->AutoPilot.m_nDrivingStyle == DRIVINGSTYLE_STOP_FOR_CARS_IGNORE_LIGHTS)) &&
CTimer::GetTimeInMilliseconds() - pVehicle->AutoPilot.m_nTimeToStartMission > 5000 &&
!pVehicle->GetIsOnScreen() &&
- (pVehicle->GetPosition() - vecPlayerPos).Magnitude2D() > 25.0f &&
+ (pVehicle->GetPosition() - vecPlayerPos).Magnitude2D() > 22.0f &&
!IsThisVehicleInteresting(pVehicle) &&
!pVehicle->bIsLocked &&
pVehicle->CanBeDeleted() &&
@@ -776,7 +1015,7 @@ CCarCtrl::PossiblyRemoveVehicle(CVehicle* pVehicle)
if (pVehicle->GetStatus() != STATUS_WRECKED || pVehicle->m_nTimeOfDeath == 0)
return;
if (CTimer::GetTimeInMilliseconds() > pVehicle->m_nTimeOfDeath + 60000 &&
- !(pVehicle->GetIsOnScreen() && CRenderer::IsEntityCullZoneVisible(pVehicle)) ){
+ !pVehicle->GetIsOnScreen()){
if ((pVehicle->GetPosition() - vecPlayerPos).MagnitudeSqr() > SQR(7.5f)){
if (!CGarages::IsPointWithinHideOutGarage(pVehicle->GetPosition())){
CWorld::Remove(pVehicle);
@@ -800,6 +1039,16 @@ CCarCtrl::CountCarsOfType(int32 mi)
return total;
}
+static CVector GetRandomOffsetForVehicle(CVehicle* pVehicle, bool bNext)
+{
+ CVector offset;
+ int32 seed = ((bNext ? pVehicle->AutoPilot.m_nNextPathNodeInfo : pVehicle->AutoPilot.m_nCurrentPathNodeInfo) + pVehicle->m_randomSeed) & 7;
+ offset.x = (seed - 3) * 0.009f;
+ offset.y = ((seed >> 3) - 3) * 0.009f;
+ offset.z = 0.0f;
+ return offset;
+}
+
void
CCarCtrl::UpdateCarOnRails(CVehicle* pVehicle)
{
@@ -832,8 +1081,12 @@ CCarCtrl::UpdateCarOnRails(CVehicle* pVehicle)
pNextLink->GetX() + ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardY,
pNextLink->GetY() - ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardX,
0.0f);
- CVector directionCurrentLink(currentPathLinkForwardX, currentPathLinkForwardY, 0.0f);
- CVector directionNextLink(nextPathLinkForwardX, nextPathLinkForwardY, 0.0f);
+ CVector directionCurrentLink = GetRandomOffsetForVehicle(pVehicle, false);
+ directionCurrentLink += CVector(currentPathLinkForwardX, currentPathLinkForwardY, 0.0f);
+ directionCurrentLink.Normalise();
+ CVector directionNextLink = GetRandomOffsetForVehicle(pVehicle, true);
+ directionNextLink += CVector(nextPathLinkForwardX, nextPathLinkForwardY, 0.0f);
+ directionNextLink.Normalise();
CVector positionIncludingCurve;
CVector directionIncludingCurve;
CCurves::CalcCurvePoint(
@@ -856,7 +1109,7 @@ CCarCtrl::FindMaximumSpeedForThisCarInTraffic(CVehicle* pVehicle)
{
if (pVehicle->AutoPilot.m_nDrivingStyle == DRIVINGSTYLE_AVOID_CARS ||
pVehicle->AutoPilot.m_nDrivingStyle == DRIVINGSTYLE_PLOUGH_THROUGH)
- return pVehicle->AutoPilot.m_nCruiseSpeed;
+ return pVehicle->AutoPilot.GetCruiseSpeed();
float left = pVehicle->GetPosition().x - DISTANCE_TO_SCAN_FOR_DANGER;
float right = pVehicle->GetPosition().x + DISTANCE_TO_SCAN_FOR_DANGER;
float top = pVehicle->GetPosition().y - DISTANCE_TO_SCAN_FOR_DANGER;
@@ -868,33 +1121,33 @@ CCarCtrl::FindMaximumSpeedForThisCarInTraffic(CVehicle* pVehicle)
assert(xstart <= xend);
assert(ystart <= yend);
- float maxSpeed = pVehicle->AutoPilot.m_nCruiseSpeed;
+ float maxSpeed = pVehicle->AutoPilot.GetCruiseSpeed();
CWorld::AdvanceCurrentScanCode();
for (int y = ystart; y <= yend; y++){
for (int x = xstart; x <= xend; x++){
CSector* s = CWorld::GetSector(x, y);
- SlowCarDownForCarsSectorList(s->m_lists[ENTITYLIST_VEHICLES], pVehicle, left, top, right, bottom, &maxSpeed, pVehicle->AutoPilot.m_nCruiseSpeed);
- SlowCarDownForCarsSectorList(s->m_lists[ENTITYLIST_VEHICLES_OVERLAP], pVehicle, left, top, right, bottom, &maxSpeed, pVehicle->AutoPilot.m_nCruiseSpeed);
- SlowCarDownForPedsSectorList(s->m_lists[ENTITYLIST_PEDS], pVehicle, left, top, right, bottom, &maxSpeed, pVehicle->AutoPilot.m_nCruiseSpeed);
- SlowCarDownForPedsSectorList(s->m_lists[ENTITYLIST_PEDS_OVERLAP], pVehicle, left, top, right, bottom, &maxSpeed, pVehicle->AutoPilot.m_nCruiseSpeed);
+ SlowCarDownForCarsSectorList(s->m_lists[ENTITYLIST_VEHICLES], pVehicle, left, top, right, bottom, &maxSpeed, pVehicle->AutoPilot.GetCruiseSpeed());
+ SlowCarDownForCarsSectorList(s->m_lists[ENTITYLIST_VEHICLES_OVERLAP], pVehicle, left, top, right, bottom, &maxSpeed, pVehicle->AutoPilot.GetCruiseSpeed());
+ SlowCarDownForPedsSectorList(s->m_lists[ENTITYLIST_PEDS], pVehicle, left, top, right, bottom, &maxSpeed, pVehicle->AutoPilot.GetCruiseSpeed());
+ SlowCarDownForPedsSectorList(s->m_lists[ENTITYLIST_PEDS_OVERLAP], pVehicle, left, top, right, bottom, &maxSpeed, pVehicle->AutoPilot.GetCruiseSpeed());
}
}
pVehicle->bWarnedPeds = true;
- if (pVehicle->AutoPilot.m_nDrivingStyle == DRIVINGSTYLE_STOP_FOR_CARS)
+ if (pVehicle->AutoPilot.m_nDrivingStyle == DRIVINGSTYLE_STOP_FOR_CARS || pVehicle->AutoPilot.m_nDrivingStyle == DRIVINGSTYLE_STOP_FOR_CARS_IGNORE_LIGHTS)
return maxSpeed;
- return (maxSpeed + pVehicle->AutoPilot.m_nCruiseSpeed) / 2;
+ return (maxSpeed + pVehicle->AutoPilot.GetCruiseSpeed()) / 2;
}
void
CCarCtrl::ScanForPedDanger(CVehicle* pVehicle)
{
bool storedSlowDownFlag = pVehicle->AutoPilot.m_bSlowedDownBecauseOfPeds;
- float left = pVehicle->GetPosition().x - DISTANCE_TO_SCAN_FOR_DANGER;
- float right = pVehicle->GetPosition().x + DISTANCE_TO_SCAN_FOR_DANGER;
- float top = pVehicle->GetPosition().y - DISTANCE_TO_SCAN_FOR_DANGER;
- float bottom = pVehicle->GetPosition().y + DISTANCE_TO_SCAN_FOR_DANGER;
+ float left = pVehicle->GetPosition().x - DISTANCE_TO_SCAN_FOR_PED_DANGER;
+ float right = pVehicle->GetPosition().x + DISTANCE_TO_SCAN_FOR_PED_DANGER;
+ float top = pVehicle->GetPosition().y - DISTANCE_TO_SCAN_FOR_PED_DANGER;
+ float bottom = pVehicle->GetPosition().y + DISTANCE_TO_SCAN_FOR_PED_DANGER;
int xstart = Max(0, CWorld::GetSectorIndexX(left));
int xend = Min(NUMSECTORS_X - 1, CWorld::GetSectorIndexX(right));
int ystart = Max(0, CWorld::GetSectorIndexY(top));
@@ -935,7 +1188,7 @@ CCarCtrl::SlowCarOnRailsDownForTrafficAndLights(CVehicle* pVehicle)
if (curSpeed < 0.1f)
pVehicle->AutoPilot.ModifySpeed(0.0f);
else
- pVehicle->AutoPilot.ModifySpeed(Max(maxSpeed, curSpeed - 0.5f * CTimer::GetTimeStep()));
+ pVehicle->AutoPilot.ModifySpeed(Max(maxSpeed, curSpeed - 0.7f * CTimer::GetTimeStep()));
}
}
@@ -981,14 +1234,12 @@ void CCarCtrl::SlowCarDownForPedsSectorList(CPtrList& lst, CVehicle* pVehicle, f
if (pVehicle->GetModelIndex() == MI_RCBANDIT){
if (dotVelocity * GAME_SPEED_TO_METERS_PER_SECOND / 2 > distanceUntilHit)
pPed->SetEvasiveStep(pVehicle, 0);
- }
- else if (dotVelocity > 0.3f) {
+ }else if (dotVelocity > 0.3f) {
if (sideLength + 0.1f < sidewaysDistance)
pPed->SetEvasiveStep(pVehicle, 0);
else
pPed->SetEvasiveDive(pVehicle, 0);
- }
- else if (dotVelocity > 0.1f) {
+ }else if (dotVelocity > 0.1f) {
if (sideLength - 0.5f < sidewaysDistance)
pPed->SetEvasiveStep(pVehicle, 0);
else
@@ -1038,7 +1289,7 @@ void CCarCtrl::SlowCarDownForPedsSectorList(CPtrList& lst, CVehicle* pVehicle, f
if (distanceUntilHit < 10.0f){
if (pVehicle->AutoPilot.m_nDrivingStyle == DRIVINGSTYLE_STOP_FOR_CARS ||
pVehicle->AutoPilot.m_nDrivingStyle == DRIVINGSTYLE_SLOW_DOWN_FOR_CARS){
- *pSpeed = Min(*pSpeed, ABS(distanceUntilHit - 1.0f) * 0.1f * curSpeed);
+ *pSpeed = Min(*pSpeed, ABS(distanceUntilHit - 1.0f) / 10.0f * curSpeed);
pVehicle->AutoPilot.m_bSlowedDownBecauseOfPeds = true;
if (distanceUntilHit < 2.0f){
pVehicle->AutoPilot.m_nTempAction = TEMPACT_WAIT;
@@ -1073,11 +1324,11 @@ void CCarCtrl::SlowCarDownForCarsSectorList(CPtrList& lst, CVehicle* pVehicle, f
void CCarCtrl::SlowCarDownForOtherCar(CEntity* pOtherEntity, CVehicle* pVehicle, float* pSpeed, float curSpeed)
{
CVector forwardA = pVehicle->GetForward();
- ((CVector2D)forwardA).NormaliseSafe();
+ ((CVector2D)forwardA).Normalise();
if (DotProduct2D(pOtherEntity->GetPosition() - pVehicle->GetPosition(), forwardA) < 0.0f)
return;
CVector forwardB = pOtherEntity->GetForward();
- ((CVector2D)forwardB).NormaliseSafe();
+ ((CVector2D)forwardB).Normalise();
forwardA.z = forwardB.z = 0.0f;
CVehicle* pOtherVehicle = (CVehicle*)pOtherEntity;
/* why is the argument CEntity if it's always CVehicle anyway and is casted? */
@@ -1088,8 +1339,8 @@ void CCarCtrl::SlowCarDownForOtherCar(CEntity* pOtherEntity, CVehicle* pVehicle,
float proximityA = TestCollisionBetween2MovingRects(pOtherVehicle, pVehicle, projectionX, projectionY, &forwardA, &forwardB, 0);
float proximityB = TestCollisionBetween2MovingRects(pVehicle, pOtherVehicle, -projectionX, -projectionY, &forwardB, &forwardA, 1);
float minProximity = Min(proximityA, proximityB);
- if (minProximity >= 0.0f && minProximity < 1.0f){
- minProximity = Max(0.0f, (minProximity - 0.2f) * 1.25f);
+ if (minProximity >= 0.0f && minProximity < 1.5f){
+ minProximity = Max(0.0f, (minProximity - 0.2f) / 1.3f);
pVehicle->AutoPilot.m_bSlowedDownBecauseOfCars = true;
*pSpeed = Min(*pSpeed, minProximity * curSpeed);
}
@@ -1236,7 +1487,7 @@ float CCarCtrl::TestCollisionBetween2MovingRects(CVehicle* pVehicleA, CVehicle*
float CCarCtrl::FindAngleToWeaveThroughTraffic(CVehicle* pVehicle, CPhysical* pTarget, float angleToTarget, float angleForward)
{
- float distanceToTest = Min(2.0f, pVehicle->GetMoveSpeed().Magnitude2D() * 2.5f + 1.0f) * 12.0f;
+ float distanceToTest = Min(2.0f, pVehicle->GetMoveSpeed().Magnitude2D() / 0.4f + 1.0f) * 12.0f;
float left = pVehicle->GetPosition().x - distanceToTest;
float right = pVehicle->GetPosition().x + distanceToTest;
float top = pVehicle->GetPosition().y - distanceToTest;
@@ -1308,29 +1559,29 @@ void CCarCtrl::WeaveThroughCarsSectorList(CPtrList& lst, CVehicle* pVehicle, CPh
continue;
if (Abs(pTestVehicle->GetPosition().z - pVehicle->GetPosition().z) >= VEHICLE_HEIGHT_DIFF_TO_CONSIDER_WEAVING)
continue;
- if (pTestVehicle != pVehicle)
+ if (pTestVehicle != pVehicle && (!pVehicle->bPartOfConvoy || !pTestVehicle->bPartOfConvoy))
WeaveForOtherCar(pTestVehicle, pVehicle, pAngleToWeaveLeft, pAngleToWeaveRight);
}
}
void CCarCtrl::WeaveForOtherCar(CEntity* pOtherEntity, CVehicle* pVehicle, float* pAngleToWeaveLeft, float* pAngleToWeaveRight)
{
+ CVehicle* pOtherCar = (CVehicle*)pOtherEntity;
if (pVehicle->AutoPilot.m_nCarMission == MISSION_RAMPLAYER_CLOSE && pOtherEntity == FindPlayerVehicle())
return;
if (pVehicle->AutoPilot.m_nCarMission == MISSION_RAMCAR_CLOSE && pOtherEntity == pVehicle->AutoPilot.m_pTargetCar)
return;
- CVehicle* pOtherCar = (CVehicle*)pOtherEntity;
CVector2D vecDiff = pOtherCar->GetPosition() - pVehicle->GetPosition();
float angleBetweenVehicles = CGeneral::GetATanOfXY(vecDiff.x, vecDiff.y);
float distance = vecDiff.Magnitude();
if (distance < 1.0f)
return;
if (DotProduct2D(pVehicle->GetMoveSpeed() - pOtherCar->GetMoveSpeed(), vecDiff) * 110.0f -
- pOtherCar->GetModelInfo()->GetColModel()->boundingSphere.radius -
- pVehicle->GetModelInfo()->GetColModel()->boundingSphere.radius < distance)
+ pOtherCar->GetColModel()->boundingSphere.radius -
+ pVehicle->GetColModel()->boundingSphere.radius < distance)
return;
CVector2D forward = pVehicle->GetForward();
- forward.NormaliseSafe();
+ forward.Normalise();
float forwardAngle = CGeneral::GetATanOfXY(forward.x, forward.y);
float angleDiff = angleBetweenVehicles - forwardAngle;
float lenProjection = ABS(pOtherCar->GetColModel()->boundingBox.max.y * Sin(angleDiff));
@@ -1370,7 +1621,7 @@ void CCarCtrl::WeaveThroughPedsSectorList(CPtrList& lst, CVehicle* pVehicle, CPh
continue;
if (Abs(pPed->GetPosition().z - pVehicle->GetPosition().z) >= PED_HEIGHT_DIFF_TO_CONSIDER_WEAVING)
continue;
- if (pPed->m_pCurSurface != pVehicle)
+ if (pPed->m_pCurSurface != pVehicle && pPed->m_attachedTo != pVehicle)
WeaveForPed(pPed, pVehicle, pAngleToWeaveLeft, pAngleToWeaveRight);
}
@@ -1475,6 +1726,7 @@ void CCarCtrl::WeaveForObject(CEntity* pOtherEntity, CVehicle* pVehicle, float*
bool CCarCtrl::PickNextNodeAccordingStrategy(CVehicle* pVehicle)
{
+ pVehicle->AutoPilot.m_nCruiseSpeedMultiplierType = ThePaths.m_pathNodes[pVehicle->AutoPilot.m_nNextRouteNode].speedLimit;
switch (pVehicle->AutoPilot.m_nCarMission){
case MISSION_RAMPLAYER_FARAWAY:
case MISSION_BLOCKPLAYER_FARAWAY:
@@ -1501,23 +1753,30 @@ bool CCarCtrl::PickNextNodeAccordingStrategy(CVehicle* pVehicle)
return false;
default:
PickNextNodeRandomly(pVehicle);
+ if (ThePaths.GetNode(pVehicle->AutoPilot.m_nNextRouteNode)->bOnlySmallBoats && BoatWithTallMast(pVehicle->GetModelIndex()))
+ pVehicle->AutoPilot.m_nCruiseSpeed = 0;
return false;
}
}
void CCarCtrl::PickNextNodeRandomly(CVehicle* pVehicle)
{
+ if (pVehicle->m_nRouteSeed)
+ CGeneral::SetRandomSeed(pVehicle->m_nRouteSeed);
int32 prevNode = pVehicle->AutoPilot.m_nCurrentRouteNode;
int32 curNode = pVehicle->AutoPilot.m_nNextRouteNode;
uint8 totalLinks = ThePaths.m_pathNodes[curNode].numLinks;
CCarPathLink* pCurLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo];
-#ifdef FIX_BUGS
- uint8 lanesOnCurrentPath = pCurLink->pathNodeIndex == curNode ?
- pCurLink->numLeftLanes : pCurLink->numRightLanes;
-#else
- uint8 lanesOnCurrentPath = pCurLink->pathNodeIndex == curNode ?
- pCurLink->numRightLanes : pCurLink->numLeftLanes;
-#endif
+ uint8 lanesOnCurrentPath;
+ bool isOnOneWayRoad;
+ if (pCurLink->pathNodeIndex == curNode) {
+ lanesOnCurrentPath = pCurLink->numLeftLanes;
+ isOnOneWayRoad = pCurLink->numRightLanes == 0;
+ }
+ else {
+ lanesOnCurrentPath = pCurLink->numRightLanes;
+ isOnOneWayRoad = pCurLink->numLeftLanes == 0;
+ }
uint8 allowedDirections = PATH_DIRECTION_NONE;
uint8 nextLane = pVehicle->AutoPilot.m_nNextLane;
if (nextLane == 0)
@@ -1539,6 +1798,7 @@ void CCarCtrl::PickNextNodeRandomly(CVehicle* pVehicle)
CCarPathLink* pNextLink;
CPathNode* pNextPathNode;
bool goingAgainstOneWayRoad;
+ bool nextNodeIsOneWayRoad;
uint8 direction;
for(attempt = 0; attempt < ATTEMPTS_TO_FIND_NEXT_NODE; attempt++){
if (attempt != 0){
@@ -1548,7 +1808,7 @@ void CCarCtrl::PickNextNodeRandomly(CVehicle* pVehicle)
if ((!pNextPathNode->bDeadEnd || pPrevPathNode->bDeadEnd) &&
(!pNextPathNode->bDisabled || pPrevPathNode->bDisabled) &&
(!pNextPathNode->bBetweenLevels || pPrevPathNode->bBetweenLevels || !pVehicle->AutoPilot.m_bStayInCurrentLevel) &&
- !goingAgainstOneWayRoad)
+ !goingAgainstOneWayRoad && (!isOnOneWayRoad || !nextNodeIsOneWayRoad))
break;
}
}
@@ -1558,9 +1818,10 @@ void CCarCtrl::PickNextNodeRandomly(CVehicle* pVehicle)
direction = FindPathDirection(prevNode, curNode, pVehicle->AutoPilot.m_nNextRouteNode);
pNextLink = &ThePaths.m_carPathLinks[ThePaths.m_carPathConnections[nextLink + pCurPathNode->firstLink]];
goingAgainstOneWayRoad = pNextLink->pathNodeIndex == curNode ? pNextLink->numRightLanes == 0 : pNextLink->numLeftLanes == 0;
+ nextNodeIsOneWayRoad = pNextLink->pathNodeIndex == curNode ? pNextLink->numLeftLanes == 0 : pNextLink->numRightLanes == 0;
}
if (attempt >= ATTEMPTS_TO_FIND_NEXT_NODE) {
- /* If we failed 15 times, then remove dead end and current lane limitations */
+ /* If we failed 15 times, then remove dead end, one way road and current lane limitations */
for (attempt = 0; attempt < ATTEMPTS_TO_FIND_NEXT_NODE; attempt++) {
if (attempt != 0) {
if (pVehicle->AutoPilot.m_nNextRouteNode != prevNode) {
@@ -1705,74 +1966,57 @@ void CCarCtrl::PickNextNodeToChaseCar(CVehicle* pVehicle, float targetX, float t
void CCarCtrl::PickNextNodeToChaseCar(CVehicle* pVehicle, float targetX, float targetY, CVehicle* pTarget)
#endif
{
+ if (pVehicle->m_nRouteSeed)
+ CGeneral::SetRandomSeed(pVehicle->m_nRouteSeed);
int prevNode = pVehicle->AutoPilot.m_nCurrentRouteNode;
int curNode = pVehicle->AutoPilot.m_nNextRouteNode;
CPathNode* pPrevNode = &ThePaths.m_pathNodes[prevNode];
CPathNode* pCurNode = &ThePaths.m_pathNodes[curNode];
- CPathNode* pTargetNode;
+ CPathNode* pTargetNode[2];
int16 numNodes;
float distanceToTargetNode;
- if (pTarget && pTarget->m_pCurGroundEntity &&
- pTarget->m_pCurGroundEntity->IsBuilding() &&
- ((CBuilding*)pTarget->m_pCurGroundEntity)->GetIsATreadable() &&
- ((CTreadable*)pTarget->m_pCurGroundEntity)->m_nodeIndices[0][0] >= 0){
- CTreadable* pCurrentMapObject = (CTreadable*)pTarget->m_pCurGroundEntity;
- int closestNode = -1;
- float minDist = 100000.0f;
- for (int i = 0; i < 12; i++){
- int node = pCurrentMapObject->m_nodeIndices[0][i];
- if (node < 0)
- break;
- float dist = (ThePaths.m_pathNodes[node].GetPosition() - pTarget->GetPosition()).Magnitude();
- if (dist < minDist){
- minDist = dist;
- closestNode = node;
- }
- }
- ThePaths.DoPathSearch(0, pCurNode->GetPosition(), curNode,
-#ifdef FIX_PATHFIND_BUG
- CVector(targetX, targetY, targetZ),
-#else
- CVector(targetX, targetY, 0.0f),
-#endif
- &pTargetNode, &numNodes, 1, pVehicle, &distanceToTargetNode, 999999.9f, closestNode);
- }else
- {
-
- ThePaths.DoPathSearch(0, pCurNode->GetPosition(), curNode,
+ ThePaths.DoPathSearch(0, pCurNode->GetPosition(), curNode,
#ifdef FIX_PATHFIND_BUG
- CVector(targetX, targetY, targetZ),
+ CVector(targetX, targetY, targetZ),
#else
- CVector(targetX, targetY, 0.0f),
+ CVector(targetX, targetY, 0.0f),
#endif
- &pTargetNode, &numNodes, 1, pVehicle, &distanceToTargetNode, 999999.9f, -1);
- }
+ pTargetNode, &numNodes, 2, pVehicle, &distanceToTargetNode, 999999.9f, -1);
int newNextNode;
int nextLink;
- if (numNodes != 1 || pTargetNode == pCurNode){
- float currentAngle = CGeneral::GetATanOfXY(targetX - pVehicle->GetPosition().x, targetY - pVehicle->GetPosition().y);
- nextLink = 0;
- float lowestAngleChange = 10.0f;
- int numLinks = pCurNode->numLinks;
- newNextNode = 0;
- for (int i = 0; i < numLinks; i++){
- int conNode = ThePaths.ConnectedNode(i + pCurNode->firstLink);
- if (conNode == prevNode && i > 1)
- continue;
- CPathNode* pTestNode = &ThePaths.m_pathNodes[conNode];
- float angle = CGeneral::GetATanOfXY(pTestNode->GetX() - pCurNode->GetX(), pTestNode->GetY() - pCurNode->GetY());
- angle = LimitRadianAngle(angle - currentAngle);
- angle = ABS(angle);
- if (angle < lowestAngleChange){
- lowestAngleChange = angle;
- newNextNode = conNode;
- nextLink = i;
+ if (numNodes != 1 && numNodes != 2 || pTargetNode[0] == pCurNode){
+ if (numNodes != 2 || pTargetNode[1] == pCurNode) {
+ float currentAngle = CGeneral::GetATanOfXY(targetX - pVehicle->GetPosition().x, targetY - pVehicle->GetPosition().y);
+ nextLink = 0;
+ float lowestAngleChange = 10.0f;
+ int numLinks = pCurNode->numLinks;
+ newNextNode = 0;
+ for (int i = 0; i < numLinks; i++) {
+ int conNode = ThePaths.ConnectedNode(i + pCurNode->firstLink);
+ if (conNode == prevNode && i > 1)
+ continue;
+ CPathNode* pTestNode = &ThePaths.m_pathNodes[conNode];
+ float angle = CGeneral::GetATanOfXY(pTestNode->GetX() - pCurNode->GetX(), pTestNode->GetY() - pCurNode->GetY());
+ angle = LimitRadianAngle(angle - currentAngle);
+ angle = ABS(angle);
+ if (angle < lowestAngleChange) {
+ lowestAngleChange = angle;
+ newNextNode = conNode;
+ nextLink = i;
+ }
}
}
- }else{
+ else {
+ nextLink = 0;
+ newNextNode = pTargetNode[1] - ThePaths.m_pathNodes;
+ for (int i = pCurNode->firstLink; ThePaths.ConnectedNode(i) != newNextNode; i++, nextLink++)
+ ;
+ }
+ }
+ else {
nextLink = 0;
- newNextNode = pTargetNode - ThePaths.m_pathNodes;
+ newNextNode = pTargetNode[0] - ThePaths.m_pathNodes;
for (int i = pCurNode->firstLink; ThePaths.ConnectedNode(i) != newNextNode; i++, nextLink++)
;
}
@@ -1792,11 +2036,11 @@ void CCarCtrl::PickNextNodeToChaseCar(CVehicle* pVehicle, float targetX, float t
int8 lanesOnNextNode;
if (curNode >= pVehicle->AutoPilot.m_nNextRouteNode) {
pVehicle->AutoPilot.m_nNextDirection = 1;
- lanesOnNextNode = pNextLink->numLeftLanes;
+ lanesOnNextNode = pNextLink->numRightLanes;
}
else {
pVehicle->AutoPilot.m_nNextDirection = -1;
- lanesOnNextNode = pNextLink->numRightLanes;
+ lanesOnNextNode = pNextLink->numLeftLanes;
}
float currentPathLinkForwardX = pVehicle->AutoPilot.m_nCurrentDirection * pCurLink->GetDirX();
float currentPathLinkForwardY = pVehicle->AutoPilot.m_nCurrentDirection * pCurLink->GetDirY();
@@ -1851,6 +2095,8 @@ void CCarCtrl::PickNextNodeToChaseCar(CVehicle* pVehicle, float targetX, float t
bool CCarCtrl::PickNextNodeToFollowPath(CVehicle* pVehicle)
{
+ if (pVehicle->m_nRouteSeed)
+ CGeneral::SetRandomSeed(pVehicle->m_nRouteSeed);
int curNode = pVehicle->AutoPilot.m_nNextRouteNode;
CPathNode* pCurNode = &ThePaths.m_pathNodes[curNode];
if (pVehicle->AutoPilot.m_nPathFindNodesCount == 0){
@@ -1858,8 +2104,9 @@ bool CCarCtrl::PickNextNodeToFollowPath(CVehicle* pVehicle)
pVehicle->AutoPilot.m_vecDestinationCoors, pVehicle->AutoPilot.m_aPathFindNodesInfo,
&pVehicle->AutoPilot.m_nPathFindNodesCount, NUM_PATH_NODES_IN_AUTOPILOT,
pVehicle, nil, 999999.9f, -1);
- if (pVehicle->AutoPilot.m_nPathFindNodesCount < 1)
+ if (pVehicle->AutoPilot.m_nPathFindNodesCount < 2)
return true;
+ pVehicle->AutoPilot.RemoveOnePathNode();
}
CPathNode* pNextPathNode = &ThePaths.m_pathNodes[pVehicle->AutoPilot.m_nNextRouteNode];
CCarPathLink* pCurLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo];
@@ -1943,6 +2190,7 @@ void CCarCtrl::Init(void)
LastTimeAmbulanceCreated = 0;
#ifdef FIX_BUGS
LastTimeLawEnforcerCreated = 0;
+ LastTimeMiamiViceGenerated = 0;
#endif
bCarsGeneratedAroundCamera = false;
CountDownToCarsAtStart = 2;
@@ -1950,9 +2198,11 @@ void CCarCtrl::Init(void)
for (int i = 0; i < MAX_CARS_TO_KEEP; i++)
apCarsToKeep[i] = nil;
for (int i = 0; i < TOTAL_CUSTOM_CLASSES; i++){
- for (int j = 0; j < MAX_CAR_MODELS_IN_ARRAY; j++)
- CarArrays[i][j] = 0;
- NextCarOfRating[i] = 0;
+ for (int j = 0; j < MAX_CAR_MODELS_IN_ARRAY; j++) {
+ LoadedCarsArray[i][j] = -1;
+ }
+ NumOfLoadedCarsOfRating[i] = 0;
+ NumRequestsOfCarRating[i] = 0;
TotalNumOfCarsOfRating[i] = 0;
}
}
@@ -1970,13 +2220,14 @@ void CCarCtrl::ReInit(void)
LastTimeFireTruckCreated = 0;
LastTimeAmbulanceCreated = 0;
LastTimeLawEnforcerCreated = 0;
+ LastTimeMiamiViceGenerated = 0;
#endif
CountDownToCarsAtStart = 2;
CarDensityMultiplier = 1.0f;
for (int i = 0; i < MAX_CARS_TO_KEEP; i++)
apCarsToKeep[i] = nil;
for (int i = 0; i < TOTAL_CUSTOM_CLASSES; i++)
- NextCarOfRating[i] = 0;
+ NumRequestsOfCarRating[i] = 0;
}
void CCarCtrl::DragCarToPoint(CVehicle* pVehicle, CVector* pPoint)
@@ -2086,7 +2337,7 @@ void CCarCtrl::SteerAICarWithPhysics(CVehicle* pVehicle)
pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE;
break;
case TEMPACT_HANDBRAKETURNLEFT:
- swerve = -1.0f; // It seems like this should be swerve = 1.0f (fixed in VC)
+ swerve = 1.0f;
accel = 0.0f;
brake = 0.0f;
handbrake = true;
@@ -2094,7 +2345,7 @@ void CCarCtrl::SteerAICarWithPhysics(CVehicle* pVehicle)
pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE;
break;
case TEMPACT_HANDBRAKETURNRIGHT:
- swerve = 1.0f; // It seems like this should be swerve = -1.0f (fixed in VC)
+ swerve = -1.0f;
accel = 0.0f;
brake = 0.0f;
handbrake = true;
@@ -2170,7 +2421,13 @@ void CCarCtrl::SteerAICarWithPhysics_OnlyMission(CVehicle* pVehicle, float* pSwe
case MISSION_GOTOCOORDS_ACCURATE:
case MISSION_RAMCAR_FARAWAY:
case MISSION_BLOCKCAR_FARAWAY:
- SteerAICarWithPhysicsFollowPath(pVehicle, pSwerve, pAccel, pBrake, pHandbrake);
+ if (pVehicle->AutoPilot.m_bIgnorePathfinding) {
+ *pSwerve = 0.0f;
+ *pAccel = 1.0f;
+ *pBrake = 0.0f;
+ *pHandbrake = false;
+ }else
+ SteerAICarWithPhysicsFollowPath(pVehicle, pSwerve, pAccel, pBrake, pHandbrake);
return;
case MISSION_RAMPLAYER_CLOSE:
{
@@ -2205,6 +2462,9 @@ void CCarCtrl::SteerAICarWithPhysics_OnlyMission(CVehicle* pVehicle, float* pSwe
SteerAICarWithPhysicsTryingToBlockTarget_Stop(pVehicle, FindPlayerCoors().x, FindPlayerCoors().y,
FindPlayerSpeed().x, FindPlayerSpeed().y, pSwerve, pAccel, pBrake, pHandbrake);
return;
+ case MISSION_WAITFORDELETION:
+ case MISSION_HELI_LAND:
+ return;
case MISSION_GOTOCOORDS_STRAIGHT:
case MISSION_GOTO_COORDS_STRAIGHT_ACCURATE:
SteerAICarWithPhysicsHeadingForTarget(pVehicle, nil,
@@ -2218,6 +2478,12 @@ void CCarCtrl::SteerAICarWithPhysics_OnlyMission(CVehicle* pVehicle, float* pSwe
*pHandbrake = true;
*pBrake = 0.5f;
return;
+ case MISSION_GOTOCOORDS_ASTHECROWSWIMS:
+ SteerAIBoatWithPhysicsHeadingForTarget(pVehicle,
+ pVehicle->AutoPilot.m_vecDestinationCoors.x, pVehicle->AutoPilot.m_vecDestinationCoors.y,
+ pSwerve, pAccel, pBrake);
+ *pHandbrake = false;
+ return;
case MISSION_RAMCAR_CLOSE:
SteerAICarWithPhysicsHeadingForTarget(pVehicle, pVehicle->AutoPilot.m_pTargetCar,
pVehicle->AutoPilot.m_pTargetCar->GetPosition().x, pVehicle->AutoPilot.m_pTargetCar->GetPosition().y,
@@ -2239,26 +2505,132 @@ void CCarCtrl::SteerAICarWithPhysics_OnlyMission(CVehicle* pVehicle, float* pSwe
pVehicle->AutoPilot.m_pTargetCar->GetMoveSpeed().y,
pSwerve, pAccel, pBrake, pHandbrake);
return;
+ case MISSION_HELI_FLYTOCOORS:
+ SteerAIHeliTowardsTargetCoors((CAutomobile*)pVehicle);
+ return;
+ case MISSION_ATTACKPLAYER:
+ SteerAIBoatWithPhysicsAttackingPlayer(pVehicle, pSwerve, pAccel, pBrake, pHandbrake);
+ return;
+ case MISSION_PLANE_FLYTOCOORS:
+ SteerAIPlaneTowardsTargetCoors((CAutomobile*)pVehicle);
+ return;
+ case MISSION_SLOWLY_DRIVE_TOWARDS_PLAYER_1:
+ SteerAICarWithPhysicsHeadingForTarget(pVehicle, nil,
+ pVehicle->AutoPilot.m_vecDestinationCoors.x, pVehicle->AutoPilot.m_vecDestinationCoors.y,
+ pSwerve, pAccel, pBrake, pHandbrake);
+ return;
+ case MISSION_SLOWLY_DRIVE_TOWARDS_PLAYER_2:
+ SteerAICarWithPhysicsHeadingForTarget(pVehicle, nil, FindPlayerCoors().x, FindPlayerCoors().y,
+ pSwerve, pAccel, pBrake, pHandbrake);
+ return;
+ case MISSION_BLOCKPLAYER_FORWARDANDBACK:
+ SteerAICarBlockingPlayerForwardAndBack(pVehicle, pSwerve, pAccel, pBrake, pHandbrake);
+ return;
default:
+ assert(0);
+ return;
+ }
+}
+
+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();
+ forward.Normalise();
+ float angleToTarget = CGeneral::GetATanOfXY(targetX - pVehicle->GetPosition().x, targetY - pVehicle->GetPosition().y);
+ float angleForward = CGeneral::GetATanOfXY(forward.x, forward.y);
+ float steerAngle = LimitRadianAngle(angleToTarget - angleForward);
+ steerAngle = Clamp(steerAngle, -DEFAULT_MAX_STEER_ANGLE, DEFAULT_MAX_STEER_ANGLE);
+#ifdef FIX_BUGS
+ float speedTarget = pVehicle->AutoPilot.GetCruiseSpeed();
+#else
+ float speedTarget = pVehicle->AutoPilot.m_nCruiseSpeed;
+#endif
+ float currentSpeed = pVehicle->GetMoveSpeed().Magnitude() * GAME_SPEED_TO_CARAI_SPEED;
+ float speedDiff = speedTarget - currentSpeed;
+ if (speedDiff <= 0.0f) {
+ speedDiff < -5.0f ? *pAccel = -0.2f : *pAccel = -0.1f;
+ steerAngle *= -1;
+ }
+ else if (speedDiff / currentSpeed > 0.25f) {
+ *pAccel = 1.0f;
+ }
+ else {
+ *pAccel = 1.0f - (0.25f - speedDiff / currentSpeed) * 4.0f;
+ }
+ *pBrake = 0.0f;
+ *pSwerve = steerAngle;
}
-void CCarCtrl::SteerAIBoatWithPhysics(CBoat* pBoat)
+void CCarCtrl::SteerAIBoatWithPhysicsAttackingPlayer(CVehicle* pVehicle, float* pSwerve, float* pAccel, float* pBrake, bool* pHandbrake)
{
- if (pBoat->AutoPilot.m_nCarMission == MISSION_GOTOCOORDS_ASTHECROWSWIMS){
- SteerAIBoatWithPhysicsHeadingForTarget(pBoat,
- pBoat->AutoPilot.m_vecDestinationCoors.x, pBoat->AutoPilot.m_vecDestinationCoors.y,
- &pBoat->m_fSteeringLeftRight, &pBoat->m_fAccelerate, &pBoat->m_fBrake);
- }else if (pBoat->AutoPilot.m_nCarMission == MISSION_NONE){
- pBoat->m_fSteeringLeftRight = 0.0f;
- pBoat->m_fAccelerate = 0.0f;
- pBoat->m_fBrake = 0.0f;
+ float distanceToPlayer = (FindPlayerCoors() - pVehicle->GetPosition()).Magnitude();
+ float projection = Min(distanceToPlayer / 20.0f, 2.0f);
+ CVector2D forward = pVehicle->GetForward();
+ forward.Normalise();
+ CVector2D vecToProjection = FindPlayerCoors() + FindPlayerSpeed() * projection * GAME_SPEED_TO_CARAI_SPEED;
+ float angleToTarget = CGeneral::GetATanOfXY(vecToProjection.x - pVehicle->GetPosition().x, vecToProjection.y - pVehicle->GetPosition().y);
+ float angleForward = CGeneral::GetATanOfXY(forward.x, forward.y);
+ float steerAngle = LimitRadianAngle(angleToTarget - angleForward);
+#ifdef FIX_BUGS
+ float speedTarget = pVehicle->AutoPilot.GetCruiseSpeed();
+#else
+ float speedTarget = pVehicle->AutoPilot.m_nCruiseSpeed;
+#endif
+ float currentSpeed = pVehicle->GetMoveSpeed().Magnitude() * GAME_SPEED_TO_CARAI_SPEED;
+ float speedDiff = speedTarget - currentSpeed;
+ if (speedDiff <= 0.0f) {
+ speedDiff < -5.0f ? *pAccel = -0.2f : *pAccel = -0.1f;
}
- pBoat->m_fSteerAngle = pBoat->m_fSteeringLeftRight;
- pBoat->m_fGasPedal = pBoat->m_fAccelerate;
- pBoat->m_fBrakePedal = pBoat->m_fBrake;
- pBoat->bIsHandbrakeOn = false;
+ else if (speedDiff / currentSpeed > 0.25f) {
+ *pAccel = 1.0f;
+ }
+ else {
+ *pAccel = 1.0f - (0.25f - speedDiff / currentSpeed) * 4.0f;
+ }
+ *pBrake = 0.0f;
+ *pSwerve = steerAngle;
+ *pHandbrake = false;
+ if (pVehicle->GetModelIndex() == MI_PREDATOR && distanceToPlayer < 40.0f && steerAngle < 0.15f)
+ pVehicle->FireFixedMachineGuns();
}
float CCarCtrl::FindMaxSteerAngle(CVehicle* pVehicle)
@@ -2266,10 +2638,151 @@ float CCarCtrl::FindMaxSteerAngle(CVehicle* pVehicle)
return pVehicle->GetModelIndex() == MI_ENFORCER ? 0.7f : DEFAULT_MAX_STEER_ANGLE;
}
+void CCarCtrl::SteerAIHeliTowardsTargetCoors(CAutomobile* pHeli)
+{
+ if (pHeli->m_aWheelSpeed[1] < 0.22f)
+ pHeli->m_aWheelSpeed[1] += 0.001f;
+ if (pHeli->m_aWheelSpeed[1] < 0.15f)
+ return;
+ CVector2D vecToTarget = pHeli->AutoPilot.m_vecDestinationCoors - pHeli->GetPosition();
+ float distanceToTarget = vecToTarget.Magnitude();
+#ifdef FIX_BUGS
+ float speed = pHeli->AutoPilot.GetCruiseSpeed() * 0.01f;
+#else
+ float speed = pHeli->AutoPilot.m_nCruiseSpeed * 0.01f;
+#endif
+ if (distanceToTarget <= 100.0f)
+ {
+ if (distanceToTarget > 75.0f)
+ speed *= 0.7f;
+ else if (distanceToTarget > 10.0f)
+ speed *= 0.4f;
+ else
+ speed *= 0.2f;
+ }
+ vecToTarget.Normalise();
+ CVector2D vecAdvanceThisFrame(vecToTarget * speed);
+ float resistance = Pow(0.997f, CTimer::GetTimeStep());
+ pHeli->m_vecMoveSpeed.x *= resistance;
+ pHeli->m_vecMoveSpeed.y *= resistance;
+ CVector2D vecSpeedDirection = vecAdvanceThisFrame - pHeli->m_vecMoveSpeed;
+ float vecSpeedChangeLength = vecSpeedDirection.Magnitude();
+ vecSpeedDirection.Normalise();
+ float changeMultiplier = 0.002f * CTimer::GetTimeStep();
+ if (distanceToTarget < 5.0f)
+ changeMultiplier /= 5.0f;
+ if (vecSpeedChangeLength < changeMultiplier)
+ pHeli->SetMoveSpeed(vecAdvanceThisFrame.x, vecAdvanceThisFrame.y, pHeli->GetMoveSpeed().z);
+ else
+ pHeli->AddToMoveSpeed(vecSpeedDirection * changeMultiplier);
+ pHeli->GetMatrix().Translate(CTimer::GetTimeStep() * pHeli->GetMoveSpeed().x, CTimer::GetTimeStep() * pHeli->GetMoveSpeed().y, 0.0f);
+ float ZTarget = pHeli->AutoPilot.m_vecDestinationCoors.z;
+ if (CTimer::GetTimeInMilliseconds() & 0x800) // switch every ~2 seconds
+ ZTarget += 2.0f;
+ float ZSpeedTarget = (ZTarget - pHeli->GetPosition().z) * 0.01f;
+ float ZSpeedChangeTarget = ZSpeedTarget - pHeli->GetMoveSpeed().z;
+ float ZSpeedChangeMax = 0.001f * CTimer::GetTimeStep();
+ if (!pHeli->bHeliDestroyed) {
+ if (Abs(ZSpeedChangeTarget) < ZSpeedChangeMax)
+ pHeli->SetMoveSpeed(pHeli->GetMoveSpeed().x, pHeli->GetMoveSpeed().y, ZSpeedTarget);
+ else if (ZSpeedChangeTarget < 0.0f)
+ pHeli->AddToMoveSpeed(0.0f, 0.0f, -ZSpeedChangeMax);
+ else
+ pHeli->AddToMoveSpeed(0.0f, 0.0f, 1.5f * ZSpeedChangeMax);
+ }
+ pHeli->GetMatrix().Translate(0.0f, 0.0f, CTimer::GetTimeStep() * pHeli->GetMoveSpeed().z);
+ pHeli->m_vecTurnSpeed.z *= Pow(0.99f, CTimer::GetTimeStep());
+ float ZTurnSpeedTarget;
+ if (distanceToTarget < 8.0f && pHeli->m_fHeliOrientation < 0.0f)
+ ZTurnSpeedTarget = 0.0f;
+ else {
+ float fAngleTarget = CGeneral::GetATanOfXY(vecToTarget.x, vecToTarget.y) + PI;
+ if (pHeli->m_fHeliOrientation >= 0.0f)
+ fAngleTarget = pHeli->m_fHeliOrientation;
+ fAngleTarget -= pHeli->m_fOrientation;
+ while (fAngleTarget < -PI)
+ fAngleTarget += TWOPI;
+ while (fAngleTarget > PI)
+ fAngleTarget -= TWOPI;
+ if (Abs(fAngleTarget) <= 0.4f)
+ ZTurnSpeedTarget = 0.0f;
+ else if (fAngleTarget < 0.0f)
+ ZTurnSpeedTarget = -0.03f;
+ else
+ ZTurnSpeedTarget = 0.03f;
+ }
+ float ZTurnSpeedChangeTarget = ZTurnSpeedTarget - pHeli->GetTurnSpeed().z;
+ float ZTurnSpeedLimit = 0.0002f * CTimer::GetTimeStep();
+ if (Abs(ZTurnSpeedChangeTarget) < ZTurnSpeedLimit)
+ pHeli->m_vecTurnSpeed.z = ZTurnSpeedTarget;
+ else if (ZTurnSpeedChangeTarget < 0.0f)
+ pHeli->m_vecTurnSpeed.z -= ZTurnSpeedLimit;
+ else
+ pHeli->m_vecTurnSpeed.z += ZTurnSpeedLimit;
+ pHeli->m_fOrientation += pHeli->GetTurnSpeed().z * CTimer::GetTimeStep();
+ CVector up;
+ if (pHeli->bHeliMinimumTilt)
+ up = CVector(0.5f * pHeli->GetMoveSpeed().x, 0.5f * pHeli->GetMoveSpeed().y, 1.0f);
+ else
+ up = CVector(3.0f * pHeli->GetMoveSpeed().x, 3.0f * pHeli->GetMoveSpeed().y, 1.0f);
+ up.Normalise();
+ CVector forward(Cos(pHeli->m_fOrientation), Sin(pHeli->m_fOrientation), 0.0f);
+ CVector right = CrossProduct(up, forward);
+ forward = CrossProduct(up, right);
+ pHeli->GetMatrix().GetRight() = right;
+ pHeli->GetMatrix().GetForward() = forward;
+ pHeli->GetMatrix().GetUp() = up;
+}
+
+void CCarCtrl::SteerAIPlaneTowardsTargetCoors(CAutomobile* pPlane)
+{
+ CVector2D vecToTarget = pPlane->AutoPilot.m_vecDestinationCoors - pPlane->GetPosition();
+ float fForwardZ = (pPlane->AutoPilot.m_vecDestinationCoors.z - pPlane->GetPosition().z) / vecToTarget.Magnitude();
+ fForwardZ = Clamp(fForwardZ, -0.3f, 0.3f);
+ float angle = CGeneral::GetATanOfXY(vecToTarget.x, vecToTarget.y);
+ while (angle > TWOPI)
+ angle -= TWOPI;
+ float difference = LimitRadianAngle(angle - pPlane->m_fOrientation);
+ float steer = difference > 0.0f ? 0.04f : -0.04f;
+ if (Abs(difference) < 0.2f)
+ steer *= 5.0f * Abs(difference);
+ pPlane->m_fPlaneSteer *= Pow(0.96f, CTimer::GetTimeStep());
+ float steerChange = steer - pPlane->m_fPlaneSteer;
+ float maxChange = 0.003f * CTimer::GetTimeStep();
+ if (Abs(steerChange) < maxChange)
+ pPlane->m_fPlaneSteer = steer;
+ else if (steerChange < 0.0f)
+ pPlane->m_fPlaneSteer -= maxChange;
+ else
+ pPlane->m_fPlaneSteer += maxChange;
+ pPlane->m_fOrientation += pPlane->m_fPlaneSteer * CTimer::GetTimeStep();
+ CVector up(0.0f, 0.0f, 1.0f);
+ up.Normalise();
+ CVector forward(Cos(pPlane->m_fOrientation), Sin(pPlane->m_fOrientation), fForwardZ);
+ forward.Normalise();
+ CVector right = CrossProduct(up, forward);
+ right.z -= 5.0f * pPlane->m_fPlaneSteer;
+ right.Normalise();
+ up = CrossProduct(forward, right);
+ up.Normalise();
+ right = CrossProduct(forward, up);
+ pPlane->GetMatrix().GetRight() = right;
+ pPlane->GetMatrix().GetForward() = forward;
+ pPlane->GetMatrix().GetUp() = up;
+ float newSplit = 1.0f - Pow(0.95f, CTimer::GetTimeStep());
+ float oldSplit = 1.0f - newSplit;
+#ifdef FIX_BUGS
+ pPlane->m_vecMoveSpeed = pPlane->m_vecMoveSpeed * oldSplit + pPlane->AutoPilot.GetCruiseSpeed() * 0.01f * forward * newSplit;
+#else
+ pPlane->m_vecMoveSpeed = pPlane->m_vecMoveSpeed * oldSplit + pPlane->AutoPilot.m_nCruiseSpeed * 0.01f * forward * newSplit;
+#endif
+ pPlane->m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f);
+}
+
void CCarCtrl::SteerAICarWithPhysicsFollowPath(CVehicle* pVehicle, float* pSwerve, float* pAccel, float* pBrake, bool* pHandbrake)
{
CVector2D forward = pVehicle->GetForward();
- forward.NormaliseSafe();
+ forward.Normalise();
CCarPathLink* pCurrentLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo];
CCarPathLink* pNextLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo];
CVector2D currentPathLinkForward(pCurrentLink->GetDirX() * pVehicle->AutoPilot.m_nCurrentDirection,
@@ -2294,17 +2807,13 @@ void CCarCtrl::SteerAICarWithPhysicsFollowPath(CVehicle* pVehicle, float* pSwerv
switch (pVehicle->AutoPilot.m_nCarMission){
case MISSION_GOTOCOORDS:
pVehicle->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS_STRAIGHT;
- *pSwerve = 0.0f;
- *pAccel = 0.0f;
- *pBrake = 0.0f;
- *pHandbrake = false;
+ SteerAICarWithPhysicsHeadingForTarget(pVehicle, nil, pVehicle->AutoPilot.m_vecDestinationCoors.x,
+ pVehicle->AutoPilot.m_vecDestinationCoors.y, pSwerve, pAccel, pBrake, pHandbrake);
return;
case MISSION_GOTOCOORDS_ACCURATE:
pVehicle->AutoPilot.m_nCarMission = MISSION_GOTO_COORDS_STRAIGHT_ACCURATE;
- *pSwerve = 0.0f;
- *pAccel = 0.0f;
- *pBrake = 0.0f;
- *pHandbrake = false;
+ SteerAICarWithPhysicsHeadingForTarget(pVehicle, nil, pVehicle->AutoPilot.m_vecDestinationCoors.x,
+ pVehicle->AutoPilot.m_vecDestinationCoors.y, pSwerve, pAccel, pBrake, pHandbrake);
return;
default: break;
}
@@ -2341,11 +2850,14 @@ void CCarCtrl::SteerAICarWithPhysicsFollowPath(CVehicle* pVehicle, float* pSwerv
switch (pVehicle->AutoPilot.m_nDrivingStyle) {
case DRIVINGSTYLE_STOP_FOR_CARS:
case DRIVINGSTYLE_SLOW_DOWN_FOR_CARS:
+ case DRIVINGSTYLE_STOP_FOR_CARS_IGNORE_LIGHTS:
speedStyleMultiplier = FindMaximumSpeedForThisCarInTraffic(pVehicle);
#ifdef FIX_BUGS
- if (pVehicle->AutoPilot.m_nCruiseSpeed != 0)
+ if (pVehicle->AutoPilot.GetCruiseSpeed() != 0)
+ speedStyleMultiplier /= pVehicle->AutoPilot.GetCruiseSpeed();
+#else
+ speedStyleMultiplier /= pVehicle->AutoPilot.m_nCruiseSpeed;
#endif
- speedStyleMultiplier /= pVehicle->AutoPilot.m_nCruiseSpeed;
break;
default:
speedStyleMultiplier = 1.0f;
@@ -2407,7 +2919,7 @@ void CCarCtrl::SteerAICarWithPhysicsHeadingForTarget(CVehicle* pVehicle, CPhysic
{
*pHandbrake = false;
CVector2D forward = pVehicle->GetForward();
- forward.NormaliseSafe();
+ forward.Normalise();
float angleToTarget = CGeneral::GetATanOfXY(targetX - pVehicle->GetPosition().x, targetY - pVehicle->GetPosition().y);
float angleForward = CGeneral::GetATanOfXY(forward.x, forward.y);
if (pVehicle->AutoPilot.m_nDrivingStyle == DRIVINGSTYLE_AVOID_CARS)
@@ -2425,7 +2937,7 @@ void CCarCtrl::SteerAICarWithPhysicsHeadingForTarget(CVehicle* pVehicle, CPhysic
float speedDiff = speedTarget - currentSpeed;
if (speedDiff <= 0.0f){
*pAccel = 0.0f;
- *pBrake = Min(0.5f, -speedDiff * 0.05f);
+ *pBrake = Min(0.5f, -speedDiff / 20.0f);
}else if (currentSpeed < 25.0f){
*pAccel = Min(1.0f, speedDiff * 0.1f);
*pBrake = 0.0f;
@@ -2450,6 +2962,7 @@ void CCarCtrl::SteerAICarWithPhysicsTryingToBlockTarget(CVehicle* pVehicle, floa
pVehicle->AutoPilot.m_nCarMission = (pVehicle->AutoPilot.m_nCarMission == MISSION_BLOCKCAR_CLOSE) ?
MISSION_BLOCKCAR_HANDBRAKESTOP : MISSION_BLOCKPLAYER_HANDBRAKESTOP;
}
+
void CCarCtrl::SteerAICarWithPhysicsTryingToBlockTarget_Stop(CVehicle* pVehicle, float targetX, float targetY, float targetSpeedX, float targetSpeedY, float* pSwerve, float* pAccel, float* pBrake, bool* pHandbrake)
{
*pSwerve = 0.0f;
@@ -2491,26 +3004,6 @@ void CCarCtrl::SteerAICarWithPhysicsTryingToBlockTarget_Stop(CVehicle* pVehicle,
}
}
-void CCarCtrl::SteerAIBoatWithPhysicsHeadingForTarget(CBoat* pBoat, float targetX, float targetY, float* pSwerve, float* pAccel, float* pBrake)
-{
- CVector2D forward(pBoat->GetForward());
- forward.NormaliseSafe();
- CVector2D distanceToTarget = CVector2D(targetX, targetY) - pBoat->GetPosition();
- float angleToTarget = CGeneral::GetATanOfXY(distanceToTarget.x, distanceToTarget.y);
- float angleForward = CGeneral::GetATanOfXY(forward.x, forward.y);
- float angleDiff = LimitRadianAngle(angleToTarget - angleForward);
- angleDiff = Min(DEFAULT_MAX_STEER_ANGLE, Max(-DEFAULT_MAX_STEER_ANGLE, angleDiff));
- float currentSpeed = pBoat->GetMoveSpeed().Magnitude2D(); // +0.0f for some reason
- float speedDiff = pBoat->AutoPilot.m_nCruiseSpeed - currentSpeed * 60.0f;
- if (speedDiff > 0.0f){
- float accRemaining = speedDiff / pBoat->AutoPilot.m_nCruiseSpeed;
- *pAccel = (accRemaining > 0.25f) ? 1.0f : 1.0f - (0.25f - accRemaining) * 4.0f;
- }else
- *pAccel = (speedDiff < -5.0f) ? -0.2f : -0.1f;
- *pBrake = 0.0f;
- *pSwerve = angleDiff;
-}
-
void
CCarCtrl::RegisterVehicleOfInterest(CVehicle* pVehicle)
{
@@ -2618,6 +3111,7 @@ bool CCarCtrl::JoinCarWithRoadSystemGotoCoors(CVehicle* pVehicle, CVector vecTar
pVehicle->AutoPilot.m_aPathFindNodesInfo, &pVehicle->AutoPilot.m_nPathFindNodesCount);
if (pVehicle->AutoPilot.m_nPathFindNodesCount < 2){
pVehicle->AutoPilot.m_nPrevRouteNode = pVehicle->AutoPilot.m_nCurrentRouteNode = pVehicle->AutoPilot.m_nNextRouteNode = 0;
+ pVehicle->AutoPilot.m_nPathFindNodesCount = 0;
return true;
}
pVehicle->AutoPilot.m_nPrevRouteNode = 0;
@@ -2632,6 +3126,8 @@ bool CCarCtrl::JoinCarWithRoadSystemGotoCoors(CVehicle* pVehicle, CVector vecTar
void CCarCtrl::FindLinksToGoWithTheseNodes(CVehicle* pVehicle)
{
+ if (pVehicle->m_nRouteSeed)
+ CGeneral::SetRandomSeed(pVehicle->m_nRouteSeed);
int nextLink;
CPathNode* pCurNode = &ThePaths.m_pathNodes[pVehicle->AutoPilot.m_nCurrentRouteNode];
for (nextLink = 0; nextLink < 12; nextLink++)
@@ -2645,11 +3141,23 @@ void CCarCtrl::FindLinksToGoWithTheseNodes(CVehicle* pVehicle)
curLink = 0;
curConnection = ThePaths.m_carPathConnections[pCurNode->firstLink];
}else{
- curConnection = pVehicle->AutoPilot.m_nNextPathNodeInfo;
- while (curConnection == pVehicle->AutoPilot.m_nNextPathNodeInfo){
- curLink = CGeneral::GetRandomNumber() % pCurNode->numLinks;
- curConnection = ThePaths.m_carPathConnections[curLink + pCurNode->firstLink];
+ int closestLink = -1;
+ float md = 999999.9f;
+
+ for (curLink = 0; curLink < pCurNode->numLinks; curLink++) {
+ int node = ThePaths.ConnectedNode(curLink + pCurNode->firstLink);
+ CPathNode* pNode = &ThePaths.m_pathNodes[node];
+ if (node == pVehicle->AutoPilot.m_nNextRouteNode)
+ continue;
+ CVector vCurPos = pCurNode->GetPosition();
+ CVector vNextPos = pNode->GetPosition();
+ float dist = CCollision::DistToLine(&vCurPos, &vNextPos, &pVehicle->GetPosition());
+ if (dist < md) {
+ md = dist;
+ closestLink = curLink;
+ }
}
+ curConnection = ThePaths.m_carPathConnections[closestLink + pCurNode->firstLink];
}
pVehicle->AutoPilot.m_nCurrentPathNodeInfo = curConnection;
pVehicle->AutoPilot.m_nCurrentDirection = (ThePaths.ConnectedNode(curLink + pCurNode->firstLink) >= pVehicle->AutoPilot.m_nCurrentRouteNode) ? 1 : -1;
@@ -2659,6 +3167,8 @@ void CCarCtrl::GenerateEmergencyServicesCar(void)
{
if (FindPlayerPed()->m_pWanted->GetWantedLevel() > 3)
return;
+ if (CGame::IsInInterior())
+ return;
if (NumFiretrucksOnDuty + NumAmbulancesOnDuty + NumParkedCars + NumMissionCars +
NumLawEnforcerCars + NumRandomCars > MaxNumberOfCarsInUse)
return;
@@ -2674,8 +3184,9 @@ void CCarCtrl::GenerateEmergencyServicesCar(void)
CStreaming::RequestModel(MI_AMBULAN, STREAMFLAGS_DEPENDENCY);
CStreaming::RequestModel(MI_MEDIC, STREAMFLAGS_DONT_REMOVE);
if (CStreaming::HasModelLoaded(MI_AMBULAN) && CStreaming::HasModelLoaded(MI_MEDIC)){
- if (GenerateOneEmergencyServicesCar(MI_AMBULAN, pNearestAccident->m_pVictim->GetPosition()))
+ if (GenerateOneEmergencyServicesCar(MI_AMBULAN, pNearestAccident->m_pVictim->GetPosition())){
LastTimeAmbulanceCreated = CTimer::GetTimeInMilliseconds();
+ }
}
}
}
@@ -2693,8 +3204,15 @@ void CCarCtrl::GenerateEmergencyServicesCar(void)
CStreaming::RequestModel(MI_FIRETRUCK, STREAMFLAGS_DEPENDENCY);
CStreaming::RequestModel(MI_FIREMAN, STREAMFLAGS_DONT_REMOVE);
if (CStreaming::HasModelLoaded(MI_FIRETRUCK) && CStreaming::HasModelLoaded(MI_FIREMAN)){
- if (GenerateOneEmergencyServicesCar(MI_FIRETRUCK, pNearestFire->m_vecPos))
+ if (GenerateOneEmergencyServicesCar(MI_FIRETRUCK, pNearestFire->m_vecPos)){
LastTimeFireTruckCreated = CTimer::GetTimeInMilliseconds();
+#ifdef SECUROM
+ if ((myrand() & 7) == 5){
+ // if pirated game
+ CPickups::Init();
+ }
+#endif
+ }
}
}
}
@@ -2711,12 +3229,14 @@ bool CCarCtrl::GenerateOneEmergencyServicesCar(uint32 mi, CVector vecPos)
int curNode, nextNode;
float posBetweenNodes;
while (!created && attempts < 5){
- if (ThePaths.NewGenerateCarCreationCoors(pPlayerPos.x, pPlayerPos.y, 0.707f, 0.707f,
- 120.0f, -1.0f, true, &spawnPos, &curNode, &nextNode, &posBetweenNodes, false)){
+ if (ThePaths.GenerateCarCreationCoors(pPlayerPos.x, pPlayerPos.y, 0.707f, 0.707f,
+ REQUEST_ONSCREEN_DISTANCE, -1.0f, true, &spawnPos, &curNode, &nextNode, &posBetweenNodes, false)){
int16 colliding[2];
- CWorld::FindObjectsKindaColliding(spawnPos, 10.0f, true, colliding, 2, nil, false, true, true, false, false);
- if (colliding[0] == 0)
- created = true;
+ if (!ThePaths.GetNode(curNode)->bWaterPath) {
+ CWorld::FindObjectsKindaColliding(spawnPos, 10.0f, true, colliding, 2, nil, false, true, true, false, false);
+ if (colliding[0] == 0)
+ created = true;
+ }
}
attempts += 1;
}
@@ -2730,7 +3250,7 @@ bool CCarCtrl::GenerateOneEmergencyServicesCar(uint32 mi, CVector vecPos)
pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE;
pVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS;
CVector2D direction = vecPos - spawnPos;
- direction.NormaliseSafe();
+ direction.Normalise();
pVehicle->GetForward() = CVector(direction.x, direction.y, 0.0f);
pVehicle->GetRight() = CVector(direction.y, -direction.x, 0.0f);
pVehicle->GetUp() = CVector(0.0f, 0.0f, 1.0f);
@@ -2775,18 +3295,24 @@ void CCarCtrl::UpdateCarCount(CVehicle* pVehicle, bool remove)
if (remove){
switch (pVehicle->VehicleCreatedBy){
case RANDOM_VEHICLE:
- if (pVehicle->bIsLawEnforcer)
- --NumLawEnforcerCars;
- --NumRandomCars;
+ if (pVehicle->bIsLawEnforcer) {
+ if (--NumLawEnforcerCars < 0)
+ NumLawEnforcerCars = 0;
+ }
+ if (--NumRandomCars < 0)
+ NumRandomCars = 0;
return;
case MISSION_VEHICLE:
- --NumMissionCars;
+ if (--NumMissionCars < 0)
+ NumMissionCars = 0;
return;
case PARKED_VEHICLE:
- --NumParkedCars;
+ if (--NumParkedCars < 0)
+ NumParkedCars = 0;
return;
case PERMANENT_VEHICLE:
- --NumPermanentCars;;
+ if (--NumPermanentCars < 0)
+ NumPermanentCars = 0;
return;
}
}
@@ -2804,7 +3330,7 @@ void CCarCtrl::UpdateCarCount(CVehicle* pVehicle, bool remove)
++NumParkedCars;
return;
case PERMANENT_VEHICLE:
- ++NumPermanentCars;;
+ ++NumPermanentCars;
return;
}
}
@@ -2812,12 +3338,30 @@ void CCarCtrl::UpdateCarCount(CVehicle* pVehicle, bool remove)
bool CCarCtrl::ThisRoadObjectCouldMove(int16 mi)
{
+#ifdef GTA_BRIDGE
return mi == MI_BRIDGELIFT || mi == MI_BRIDGEROADSEGMENT;
+#else
+ return false;
+#endif
}
bool CCarCtrl::MapCouldMoveInThisArea(float x, float y)
{
+#ifdef GTA_BRIDGE // actually they forgot that in VC...
// bridge moves up and down
return x > -342.0f && x < -219.0f &&
y > -677.0f && y < -580.0f;
+#else
+ return false;
+#endif
+}
+
+float CCarCtrl::FindSpeedMultiplierWithSpeedFromNodes(int8 type)
+{
+ switch (type)
+ {
+ case 1: return 1.5f;
+ case 2: return 2.0f;
+ }
+ return 1.0f;
}
diff --git a/src/control/CarCtrl.h b/src/control/CarCtrl.h
index 457224fb..5efbe275 100644
--- a/src/control/CarCtrl.h
+++ b/src/control/CarCtrl.h
@@ -9,14 +9,13 @@
#define TIME_COPS_WAIT_TO_EXIT_AFTER_STOPPING 2500
class CZoneInfo;
+class CAutomobile;
enum{
MAX_CARS_TO_KEEP = 2,
- MAX_CAR_MODELS_IN_ARRAY = 256,
+ MAX_CAR_MODELS_IN_ARRAY = 25,
};
-#define LANE_WIDTH 5.0f
-
#ifdef FIX_BUGS
#define FIX_PATHFIND_BUG
#endif
@@ -25,24 +24,37 @@ class CCarCtrl
{
public:
enum eCarClass {
- POOR = 0,
+ NORMAL = 0,
+ POOR,
RICH,
EXEC,
WORKER,
- SPECIAL,
BIG,
TAXI,
- TOTAL_CUSTOM_CLASSES,
- MAFIA,
- TRIAD,
- DIABLO,
- YAKUZA,
- YARDIE,
- COLOMB,
- NINES,
- GANG8,
+ MOPED,
+ MOTORBIKE,
+
+ LEISUREBOAT,
+ WORKERBOAT,
+
+ COPS,
+ CUBAN,
+ HAITIAN,
+ STREET,
+ DIAZ,
+ BIKER,
+ SECURITY,
+ PLAYER,
+ GOLFERS,
GANG9,
- COPS
+ COPS_BOAT,
+ FIRST_CAR_RATING = NORMAL,
+ FIRST_BOAT_RATING = LEISUREBOAT,
+ 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,
+ TOTAL_CUSTOM_CLASSES = NUM_CAR_CLASSES + NUM_BOAT_CLASSES
};
static void SwitchVehicleToRealPhysics(CVehicle*);
@@ -58,7 +70,7 @@ public:
static void GenerateRandomCars(void);
static void GenerateOneRandomCar(void);
static void GenerateEmergencyServicesCar(void);
- static int32 ChooseModel(CZoneInfo*, CVector*, int*);
+ static int32 ChooseModel(CZoneInfo*, int*);
static int32 ChoosePoliceCarModel(void);
static int32 ChooseGangCarModel(int32 gang);
static void RemoveDistantCars(void);
@@ -94,17 +106,29 @@ public:
static float FindSpeedMultiplier(float, float, float, float);
static void SteerAICarWithPhysics(CVehicle*);
static void SteerAICarWithPhysics_OnlyMission(CVehicle*, float*, float*, float*, bool*);
- static void SteerAIBoatWithPhysics(CBoat*);
static float FindMaxSteerAngle(CVehicle*);
static void SteerAICarWithPhysicsFollowPath(CVehicle*, float*, float*, float*, bool*);
static void SteerAICarWithPhysicsHeadingForTarget(CVehicle*, CPhysical*, float, float, float*, float*, float*, bool*);
static void SteerAICarWithPhysicsTryingToBlockTarget(CVehicle*, float, float, float, float, float*, float*, float*, bool*);
static void SteerAICarWithPhysicsTryingToBlockTarget_Stop(CVehicle*, float, float, float, float, float*, float*, float*, bool*);
- static void SteerAIBoatWithPhysicsHeadingForTarget(CBoat*, float, float, float*, float*, float*);
static bool ThisRoadObjectCouldMove(int16);
static void ClearInterestingVehicleList();
static void FindLinksToGoWithTheseNodes(CVehicle*);
static bool GenerateOneEmergencyServicesCar(uint32, CVector);
+ static float FindSpeedMultiplierWithSpeedFromNodes(int8);
+ static int32 ChooseBoatModel(int32);
+ static int32 ChooseBoatRating(CZoneInfo* pZoneInfo);
+ static int32 ChooseCarRating(CZoneInfo* pZoneInfo);
+ static void AddToLoadedVehicleArray(int32 mi, int32 rating, int32 freq);
+ static void RemoveFromLoadedVehicleArray(int32 mi, int32 rating);
+ static int32 ChooseCarModelToLoad(int32 rating);
+ static bool BoatWithTallMast(int32 mi);
+ static void RemoveCarsIfThePoolGetsFull(void);
+ static void SteerAIBoatWithPhysicsHeadingForTarget(CVehicle*, float, float, float*, float*, float*);
+ static void SteerAIHeliTowardsTargetCoors(CAutomobile*);
+ static void SteerAIPlaneTowardsTargetCoors(CAutomobile*);
+ static void SteerAIBoatWithPhysicsAttackingPlayer(CVehicle*, float*, float*, float*, bool*);
+ static void SteerAICarBlockingPlayerForwardAndBack(CVehicle*, float*, float*, float*, bool*);
static float GetPositionAlongCurrentCurve(CVehicle* pVehicle)
{
@@ -121,6 +145,7 @@ public:
return angle;
}
+ static bool bMadDriversCheat;
static int32 NumLawEnforcerCars;
static int32 NumAmbulancesOnDuty;
static int32 NumFiretrucksOnDuty;
@@ -136,8 +161,14 @@ public:
static uint32 LastTimeFireTruckCreated;
static uint32 LastTimeAmbulanceCreated;
static int32 TotalNumOfCarsOfRating[TOTAL_CUSTOM_CLASSES];
- static int32 NextCarOfRating[TOTAL_CUSTOM_CLASSES];
static int32 CarArrays[TOTAL_CUSTOM_CLASSES][MAX_CAR_MODELS_IN_ARRAY];
+
+ static int32 MiamiViceCycle;
+ static uint32 LastTimeMiamiViceGenerated;
+ static int32 NumRequestsOfCarRating[TOTAL_CUSTOM_CLASSES];
+ static int32 NumOfLoadedCarsOfRating[TOTAL_CUSTOM_CLASSES];
+ static int32 CarFreqArrays[TOTAL_CUSTOM_CLASSES][MAX_CAR_MODELS_IN_ARRAY];
+ static int32 LoadedCarsArray[TOTAL_CUSTOM_CLASSES][MAX_CAR_MODELS_IN_ARRAY];
};
extern CVehicle* apCarsToKeep[MAX_CARS_TO_KEEP]; \ No newline at end of file
diff --git a/src/control/Curves.cpp b/src/control/Curves.cpp
index 0a01a7aa..5b590440 100644
--- a/src/control/Curves.cpp
+++ b/src/control/Curves.cpp
@@ -11,7 +11,7 @@ float CCurves::CalcSpeedScaleFactor(CVector* pPoint1, CVector* pPoint2, float di
if (dp > 0.9f)
return distance + Abs((pPoint1->x * dir1Y - pPoint1->y * dir1X) - (pPoint2->x * dir1Y - pPoint2->y * dir1X));
else
- return ((1.0f - dp) * 0.2f + 1.0f) * distance;
+ return ((1.0f - dp) * 0.25f + 1.0f) * distance;
}
void CCurves::CalcCurvePoint(CVector* pPos1, CVector* pPos2, CVector* pDir1, CVector* pDir2, float between, int32 timeOnCurve, CVector* pOutPos, CVector* pOutDir)
@@ -19,7 +19,31 @@ void CCurves::CalcCurvePoint(CVector* pPos1, CVector* pPos2, CVector* pDir1, CVe
float actualFactor = CalcSpeedScaleFactor(pPos1, pPos2, pDir1->x, pDir1->y, pDir2->x, pDir2->y);
CVector2D dir1 = *pDir1 * actualFactor;
CVector2D dir2 = *pDir2 * actualFactor;
- float curveCoef = 0.5f - 0.5f * Cos(3.1415f * between);
+ float t1 = Abs(DotProduct2D(*pPos2 - *pPos1, *pDir1));
+ float t2 = Abs(DotProduct2D(*pPos1 - *pPos2, *pDir2));
+ float curveCoef;
+ if (t1 > t2) {
+ float coef = (t1 - t2) / (t1 + t2);
+#ifdef FIX_BUGS
+ if (between <= coef)
+#else
+ if (between < coef)
+#endif
+ curveCoef = 0.0f;
+ else
+ curveCoef = 0.5f - 0.5f * Cos(3.1415f * (between - coef) * (t1 + t2) / (2 * t2));
+ }
+ else {
+ float coef = 2 * t1 / (t1 + t2);
+#ifdef FIX_BUGS
+ if (coef <= between)
+#else
+ if (coef < between)
+#endif
+ curveCoef = 1.0f;
+ else
+ curveCoef = 0.5f - 0.5f * Cos(3.1415f * between * (t1 + t2) / (2 * t1));
+ }
*pOutPos = CVector(
(pPos1->x + between * dir1.x) * (1.0f - curveCoef) + (pPos2->x - (1 - between) * dir2.x) * curveCoef,
(pPos1->y + between * dir1.y) * (1.0f - curveCoef) + (pPos2->y - (1 - between) * dir2.y) * curveCoef,
diff --git a/src/control/Darkel.cpp b/src/control/Darkel.cpp
index 9f6809df..a6aca57e 100644
--- a/src/control/Darkel.cpp
+++ b/src/control/Darkel.cpp
@@ -7,15 +7,14 @@
#include "Timer.h"
#include "DMAudio.h"
#include "Population.h"
+#include "Replay.h"
#include "Weapon.h"
#include "World.h"
#include "Stats.h"
#include "Font.h"
#include "Text.h"
#include "Vehicle.h"
-#ifdef FIX_BUGS
-#include "Replay.h"
-#endif
+#include "GameLogic.h"
#define FRENZY_ANY_PED -1
#define FRENZY_ANY_CAR -2
@@ -26,9 +25,11 @@ int32 CDarkel::TimeOfFrenzyStart;
int32 CDarkel::WeaponType;
int32 CDarkel::AmmoInterruptedWeapon;
int32 CDarkel::KillsNeeded;
-int8 CDarkel::InterruptedWeapon;
+int32 CDarkel::InterruptedWeaponType;
+int32 CDarkel::InterruptedWeaponSelected;
/*
+ * TODO: Collect timer/kill counter RGBA colors on top like in Hud/Frontend.
* bStandardSoundAndMessages is a completely beta thing,
* makes game handle sounds & messages instead of SCM (just like in GTA2)
* but it's never been used in the game. Has unused sliding text when frenzy completed etc.
@@ -59,14 +60,12 @@ CDarkel::CalcFade(uint32 time, uint32 start, uint32 end)
return 0;
}
-// Screen positions taken from VC
void
CDarkel::DrawMessages()
{
-#ifdef FIX_BUGS
if (CReplay::IsPlayingBack())
return;
-#endif
+
switch (Status) {
case KILLFRENZY_ONGOING:
{
@@ -79,8 +78,8 @@ CDarkel::DrawMessages()
#endif
CFont::SetCentreOn();
CFont::SetPropOn();
- uint32 timePassedSinceStart = CTimer::GetTimeInMilliseconds() - CDarkel::TimeOfFrenzyStart;
- if (CDarkel::bStandardSoundAndMessages) {
+ uint32 timePassedSinceStart = CTimer::GetTimeInMilliseconds() - TimeOfFrenzyStart;
+ if (bStandardSoundAndMessages) {
if (timePassedSinceStart >= 3000 && timePassedSinceStart < 11000) {
#ifdef FIX_BUGS
CFont::SetScale(SCREEN_SCALE_X(1.3f), SCREEN_SCALE_Y(1.3f));
@@ -89,7 +88,7 @@ CDarkel::DrawMessages()
#endif
CFont::SetJustifyOff();
CFont::SetColor(CRGBA(255, 255, 128, CalcFade(timePassedSinceStart, 3000, 11000)));
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
if (pStartMessage) {
CFont::PrintString(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, pStartMessage);
}
@@ -103,7 +102,7 @@ CDarkel::DrawMessages()
#endif
CFont::SetJustifyOff();
CFont::SetColor(CRGBA(255, 255, 128, CalcFade(timePassedSinceStart, 0, 8000)));
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
if (pStartMessage) {
CFont::PrintString(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, pStartMessage);
}
@@ -117,53 +116,30 @@ CDarkel::DrawMessages()
CFont::SetCentreOff();
CFont::SetRightJustifyOn();
CFont::SetFontStyle(FONT_HEADING);
- if (CDarkel::TimeLimit >= 0) {
- uint32 timeLeft = CDarkel::TimeLimit - (CTimer::GetTimeInMilliseconds() - CDarkel::TimeOfFrenzyStart);
+ if (TimeLimit >= 0) {
+ uint32 timeLeft = TimeLimit - (CTimer::GetTimeInMilliseconds() - TimeOfFrenzyStart);
sprintf(gString, "%d:%02d", timeLeft / 60000, timeLeft % 60000 / 1000);
AsciiToUnicode(gString, gUString);
if (timeLeft > 4000 || CTimer::GetFrameCounter() & 1) {
CFont::SetColor(CRGBA(0, 0, 0, 255));
-#if defined(PS2_HUD) || defined(FIX_BUGS)
- #ifdef FIX_BUGS
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(34.0f - 1.0f), SCREEN_SCALE_Y(108.0f + 1.0f), gUString);
- #else
- CFont::PrintString(SCREEN_WIDTH-(34.0f - 1.0f), 108.0f + 1.0f, gUString);
- #endif
-#else
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(34.0f + 1.0f), SCREEN_SCALE_Y(108.0f + 1.0f), gUString);
-#endif
- CFont::SetColor(CRGBA(150, 100, 255, 255));
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(35.0f), SCREEN_SCALE_Y(109.0f), gUString);
+ CFont::SetColor(CRGBA(0, 207, 133, 255));
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(34.0f), SCREEN_SCALE_Y(108.0f), gUString);
}
}
- sprintf(gString, "%d", (CDarkel::KillsNeeded >= 0 ? CDarkel::KillsNeeded : 0));
+ sprintf(gString, "%d", (KillsNeeded >= 0 ? KillsNeeded : 0));
AsciiToUnicode(gString, gUString);
CFont::SetColor(CRGBA(0, 0, 0, 255));
-#ifdef FIX_BUGS
-#define DARKEL_COUNTER_HEIGHT 143.0f
-#else
-#define DARKEL_COUNTER_HEIGHT 128.0f
-#endif
-
-#if defined(PS2_HUD) || defined(FIX_BUGS)
- #ifdef FIX_BUGS
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(34.0f - 1.0f), SCREEN_SCALE_Y(DARKEL_COUNTER_HEIGHT + 1.0f), gUString);
- #else
- CFont::PrintString(SCREEN_WIDTH-(34.0f - 1.0f), DARKEL_COUNTER_HEIGHT + 1.0f, gUString);
- #endif
-#else
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(34.0f + 1.0f), SCREEN_SCALE_Y(DARKEL_COUNTER_HEIGHT + 1.0f), gUString);
-#endif
- CFont::SetColor(CRGBA(255, 128, 128, 255));
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(34.0f), SCREEN_SCALE_Y(DARKEL_COUNTER_HEIGHT), gUString);
-#undef DARKEL_COUNTER_HEIGHT
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(35.0f), SCREEN_SCALE_Y(144.0f), gUString);
+ CFont::SetColor(CRGBA(156, 91, 40, 255));
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(34.0f), SCREEN_SCALE_Y(143.0f), gUString);
break;
}
case KILLFRENZY_PASSED:
{
- if (CDarkel::bStandardSoundAndMessages) {
- uint32 timePassedSinceStart = CTimer::GetTimeInMilliseconds() - CDarkel::TimeOfFrenzyStart;
- if (CTimer::GetTimeInMilliseconds() - CDarkel::TimeOfFrenzyStart < 5000) {
+ if (bStandardSoundAndMessages) {
+ uint32 timePassedSinceStart = CTimer::GetTimeInMilliseconds() - TimeOfFrenzyStart;
+ if (CTimer::GetTimeInMilliseconds() - TimeOfFrenzyStart < 5000) {
CFont::SetBackgroundOff();
#ifdef FIX_BUGS
CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH - 20));
@@ -178,7 +154,7 @@ CDarkel::DrawMessages()
#endif
CFont::SetJustifyOff();
CFont::SetColor(CRGBA(128, 255, 128, CalcFade(timePassedSinceStart, 0, 5000)));
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
#ifdef FIX_BUGS
int y = SCREEN_HEIGHT / 2 + SCREEN_SCALE_Y(25.0f - timePassedSinceStart * 0.01f);
#else
@@ -235,7 +211,20 @@ CDarkel::RegisterCarBlownUpByPlayer(CVehicle *vehicle)
}
}
RegisteredKills[vehicle->GetModelIndex()]++;
- CStats::CarsExploded++;
+ switch (vehicle->GetVehicleAppearance()) {
+ case VEHICLE_APPEARANCE_CAR:
+ case VEHICLE_APPEARANCE_BIKE:
+ CStats::CarsExploded++;;
+ break;
+ case VEHICLE_APPEARANCE_HELI:
+ case VEHICLE_APPEARANCE_PLANE:
+ CStats::HelisDestroyed++;
+ break;
+ case VEHICLE_APPEARANCE_BOAT:
+ CStats::BoatsExploded++;
+ break;
+ }
+
}
void
@@ -294,28 +283,14 @@ CDarkel::ResetOnPlayerDeath()
Status = KILLFRENZY_FAILED;
TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds();
- eWeaponType fixedWeapon;
- if (WeaponType == WEAPONTYPE_UZI_DRIVEBY)
- fixedWeapon = WEAPONTYPE_UZI;
- else
- fixedWeapon = (eWeaponType)WeaponType;
-
- CPlayerPed *player = FindPlayerPed();
- if (fixedWeapon < WEAPONTYPE_TOTALWEAPONS) {
- player->m_nSelectedWepSlot = InterruptedWeapon;
- player->GetWeapon(player->GetWeaponSlot(fixedWeapon)).m_nAmmoTotal = CDarkel::AmmoInterruptedWeapon;
- }
-
- if (FindPlayerVehicle()) {
- player->RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(player->GetWeapon()->m_eWeaponType)->m_nModelId);
- player->m_currentWeapon = player->m_nSelectedWepSlot;
- player->MakeChangesForNewWeapon(player->m_currentWeapon);
- }
+ DealWithWeaponChangeAtEndOfFrenzy();
}
void
CDarkel::StartFrenzy(eWeaponType weaponType, int32 time, uint16 kill, int32 modelId0, wchar *text, int32 modelId2, int32 modelId3, int32 modelId4, bool standardSound, bool needHeadShot)
{
+ CGameLogic::ClearShortCut();
+ CGameLogic::RemoveShortCutDropOffPointForMission();
eWeaponType fixedWeapon;
if (weaponType == WEAPONTYPE_UZI_DRIVEBY)
fixedWeapon = WEAPONTYPE_UZI;
@@ -345,16 +320,24 @@ CDarkel::StartFrenzy(eWeaponType weaponType, int32 time, uint16 kill, int32 mode
CPlayerPed *player = FindPlayerPed();
if (fixedWeapon < WEAPONTYPE_TOTALWEAPONS) {
- InterruptedWeapon = player->m_currentWeapon;
- player->GiveWeapon(fixedWeapon, 0);
+ InterruptedWeaponSelected = player->GetWeapon()->m_eWeaponType;
+#if (defined FIX_BUGS || !defined GTA_PS2)
+ player->RemoveWeaponAnims(InterruptedWeaponSelected, -1000.0f);
+#endif
+ InterruptedWeaponType = player->GetWeapon(player->GetWeaponSlot(fixedWeapon)).m_eWeaponType;
AmmoInterruptedWeapon = player->GetWeapon(player->GetWeaponSlot(fixedWeapon)).m_nAmmoTotal;
+ if (InterruptedWeaponType)
+ CModelInfo::GetModelInfo(CWeaponInfo::GetWeaponInfo((eWeaponType)InterruptedWeaponType)->m_nModelId)->AddRef();
+#if (!defined FIX_BUGS && defined GTA_PS2)
+ player->RemoveWeaponAnims(InterruptedWeaponSelected, -1000.0f);
+#endif
player->GiveWeapon(fixedWeapon, 30000);
- player->m_nSelectedWepSlot = player->GetWeaponSlot(fixedWeapon);
+ player->SetCurrentWeapon(fixedWeapon);
player->MakeChangesForNewWeapon(player->m_nSelectedWepSlot);
if (FindPlayerVehicle()) {
- player->m_currentWeapon = player->m_nSelectedWepSlot;
- player->GetWeapon()->m_nAmmoInClip = Min(player->GetWeapon()->m_nAmmoTotal, CWeaponInfo::GetWeaponInfo(player->GetWeapon()->m_eWeaponType)->m_nAmountofAmmunition);
+ player->SetCurrentWeapon(FindPlayerPed()->m_nSelectedWepSlot);
+ player->SetAmmo(fixedWeapon, Min(player->GetWeapon()->m_nAmmoTotal, CWeaponInfo::GetWeaponInfo(player->GetWeapon()->m_eWeaponType)->m_nAmountofAmmunition));
player->ClearWeaponTarget();
}
}
@@ -390,24 +373,7 @@ CDarkel::Update()
CPopulation::m_AllRandomPedsThisType = -1;
Status = KILLFRENZY_FAILED;
TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds();
-
- eWeaponType fixedWeapon;
- if (WeaponType == WEAPONTYPE_UZI_DRIVEBY)
- fixedWeapon = WEAPONTYPE_UZI;
- else
- fixedWeapon = (eWeaponType)WeaponType;
-
- CPlayerPed *player = FindPlayerPed();
- if (fixedWeapon < WEAPONTYPE_TOTALWEAPONS) {
- player->m_nSelectedWepSlot = InterruptedWeapon;
- player->GetWeapon(player->GetWeaponSlot(fixedWeapon)).m_nAmmoTotal = CDarkel::AmmoInterruptedWeapon;
- }
-
- if (FindPlayerVehicle()) {
- player->RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(player->GetWeapon()->m_eWeaponType)->m_nModelId);
- player->m_currentWeapon = player->m_nSelectedWepSlot;
- player->MakeChangesForNewWeapon(player->m_currentWeapon);
- }
+ DealWithWeaponChangeAtEndOfFrenzy();
if (bStandardSoundAndMessages)
DMAudio.PlayFrontEndSound(SOUND_RAMPAGE_FAILED, 0);
@@ -424,25 +390,50 @@ CDarkel::Update()
FindPlayerPed()->m_pWanted->SetWantedLevel(0);
- eWeaponType fixedWeapon;
- if (WeaponType == WEAPONTYPE_UZI_DRIVEBY)
- fixedWeapon = WEAPONTYPE_UZI;
- else
- fixedWeapon = (eWeaponType)WeaponType;
-
- CPlayerPed* player = FindPlayerPed();
- if (fixedWeapon < WEAPONTYPE_TOTALWEAPONS) {
- player->m_nSelectedWepSlot = InterruptedWeapon;
- player->GetWeapon(player->GetWeaponSlot(fixedWeapon)).m_nAmmoTotal = CDarkel::AmmoInterruptedWeapon;
- }
-
- if (FindPlayerVehicle()) {
- player->RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(player->GetWeapon()->m_eWeaponType)->m_nModelId);
- player->m_currentWeapon = player->m_nSelectedWepSlot;
- player->MakeChangesForNewWeapon(player->m_currentWeapon);
- }
+ DealWithWeaponChangeAtEndOfFrenzy();
if (bStandardSoundAndMessages)
DMAudio.PlayFrontEndSound(SOUND_RAMPAGE_PASSED, 0);
}
}
+
+void
+CDarkel::DealWithWeaponChangeAtEndOfFrenzy()
+{
+ eWeaponType fixedWeapon;
+ if (WeaponType == WEAPONTYPE_UZI_DRIVEBY)
+ fixedWeapon = WEAPONTYPE_UZI;
+ else
+ fixedWeapon = (eWeaponType)WeaponType;
+
+ if (fixedWeapon < WEAPONTYPE_TOTALWEAPONS && InterruptedWeaponType)
+ CModelInfo::GetModelInfo(CWeaponInfo::GetWeaponInfo((eWeaponType)InterruptedWeaponType)->m_nModelId)->RemoveRef();
+
+ if (fixedWeapon < WEAPONTYPE_TOTALWEAPONS) {
+ int slot = CWeaponInfo::GetWeaponInfo(fixedWeapon)->m_nWeaponSlot;
+ FindPlayerPed()->RemoveWeaponModel(FindPlayerPed()->GetWeapon(slot).GetInfo()->m_nModelId);
+ FindPlayerPed()->GetWeapon(slot).m_eWeaponType = WEAPONTYPE_UNARMED;
+ FindPlayerPed()->GetWeapon(slot).m_nAmmoTotal = 0;
+ FindPlayerPed()->GetWeapon(slot).m_nAmmoInClip = 0;
+ FindPlayerPed()->GetWeapon(slot).m_eWeaponState = WEAPONSTATE_READY;
+ FindPlayerPed()->RemoveWeaponAnims(fixedWeapon, -1000.0f);
+ CModelInfo::GetModelInfo(CWeaponInfo::GetWeaponInfo(fixedWeapon)->m_nModelId)->RemoveRef();
+ }
+
+ CPlayerPed* player = FindPlayerPed();
+ if (fixedWeapon < WEAPONTYPE_TOTALWEAPONS) {
+ player->m_nSelectedWepSlot = CWeaponInfo::GetWeaponInfo((eWeaponType)InterruptedWeaponSelected)->m_nWeaponSlot;
+ player->GiveWeapon((eWeaponType)InterruptedWeaponType, AmmoInterruptedWeapon, true);
+ }
+
+ if (FindPlayerVehicle()) {
+ player->RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(player->GetWeapon()->m_eWeaponType)->m_nModelId);
+ if (FindPlayerPed()->GetWeapon(WEAPONSLOT_SUBMACHINEGUN).m_eWeaponType)
+ FindPlayerPed()->m_nSelectedWepSlot = WEAPONSLOT_SUBMACHINEGUN;
+ else
+ FindPlayerPed()->m_nSelectedWepSlot = WEAPONSLOT_UNARMED;
+ player->SetCurrentWeapon(FindPlayerPed()->m_nSelectedWepSlot);
+ player->MakeChangesForNewWeapon(player->m_currentWeapon);
+ player->RemoveDrivebyAnims();
+ }
+}
diff --git a/src/control/Darkel.h b/src/control/Darkel.h
index 0f5c2329..91955479 100644
--- a/src/control/Darkel.h
+++ b/src/control/Darkel.h
@@ -23,7 +23,8 @@ private:
static int32 WeaponType;
static int32 AmmoInterruptedWeapon;
static int32 KillsNeeded;
- static int8 InterruptedWeapon;
+ static int32 InterruptedWeaponType;
+ static int32 InterruptedWeaponSelected;
static bool bStandardSoundAndMessages;
static bool bNeedHeadShot;
static bool bProperKillFrenzy;
@@ -49,5 +50,6 @@ public:
static void ResetOnPlayerDeath();
static void StartFrenzy(eWeaponType weaponType, int32 time, uint16 kill, int32 modelId0, wchar *text, int32 modelId2, int32 modelId3, int32 modelId4, bool standardSound, bool needHeadShot);
static void Update();
+ static void DealWithWeaponChangeAtEndOfFrenzy();
};
diff --git a/src/control/GameLogic.cpp b/src/control/GameLogic.cpp
index 19e0f83d..63c685d1 100644
--- a/src/control/GameLogic.cpp
+++ b/src/control/GameLogic.cpp
@@ -19,14 +19,44 @@
#include "Fire.h"
#include "Script.h"
#include "Garages.h"
+#include "Population.h"
+#include "General.h"
+#include "DMAudio.h"
+#include "Radar.h"
+#include "Pools.h"
+#include "Hud.h"
+#include "Particle.h"
+#include "ColStore.h"
+#include "Automobile.h"
+#include "MBlur.h"
#include "screendroplets.h"
+#include "SaveBuf.h"
uint8 CGameLogic::ActivePlayers;
+uint8 CGameLogic::ShortCutState;
+CAutomobile* CGameLogic::pShortCutTaxi;
+uint32 CGameLogic::NumAfterDeathStartPoints;
+CVector CGameLogic::ShortCutStart;
+float CGameLogic::ShortCutStartOrientation;
+CVector CGameLogic::ShortCutDestination;
+float CGameLogic::ShortCutDestinationOrientation;
+uint32 CGameLogic::ShortCutTimer;
+CVector CGameLogic::AfterDeathStartPoints[NUM_SHORTCUT_START_POINTS];
+float CGameLogic::AfterDeathStartPointOrientation[NUM_SHORTCUT_START_POINTS];
+CVector CGameLogic::ShortCutDropOffForMission;
+float CGameLogic::ShortCutDropOffOrientationForMission;
+bool CGameLogic::MissionDropOffReadyToBeUsed;
+
+#define SHORTCUT_TAXI_COST (9)
+#define TOTAL_BUSTED_AUDIO (28)
void
CGameLogic::InitAtStartOfGame()
{
ActivePlayers = 1;
+ ShortCutState = SHORTCUT_NONE;
+ pShortCutTaxi = nil;
+ NumAfterDeathStartPoints = 0;
}
void
@@ -59,7 +89,10 @@ CGameLogic::SortOutStreamingAndMemory(const CVector &pos)
CStreaming::DeleteRwObjectsAfterDeath(pos);
CStreaming::RemoveUnusedModelsInLoadedList();
CGame::DrasticTidyUpMemory(true);
+ CWorld::Players[CWorld::PlayerInFocus].m_pPed->Undress("player");
+ CStreaming::LoadSceneCollision(pos);
CStreaming::LoadScene(pos);
+ CWorld::Players[CWorld::PlayerInFocus].m_pPed->Dress();
CTimer::Update();
}
@@ -69,9 +102,20 @@ CGameLogic::Update()
CVector vecRestartPos;
float fRestartFloat;
+#ifdef MISSION_REPLAY
+ // what a place to check!
+ if (gbTryingPorn4Again) {
+ CRunningScript* pScript = CTheScripts::pActiveScripts;
+ if (pScript && !CGeneral::faststricmp(pScript->m_abScriptName, "porno4"))
+ gbTryingPorn4Again = false;
+ }
+#endif
+
if (CCutsceneMgr::IsCutsceneProcessing()) return;
+ UpdateShortCut();
CPlayerInfo &pPlayerInfo = CWorld::Players[CWorld::PlayerInFocus];
+
switch (pPlayerInfo.m_WBState) {
case WBSTATE_PLAYING:
if (pPlayerInfo.m_pPed->m_nPedState == PED_DEAD) {
@@ -102,7 +146,7 @@ CGameLogic::Update()
if (pPlayerInfo.m_bGetOutOfHospitalFree) {
pPlayerInfo.m_bGetOutOfHospitalFree = false;
} else {
- pPlayerInfo.m_nMoney = Max(0, pPlayerInfo.m_nMoney - 1000);
+ pPlayerInfo.m_nMoney = Max(0, pPlayerInfo.m_nMoney - 100);
pPlayerInfo.m_pPed->ClearWeapons();
}
@@ -123,23 +167,26 @@ CGameLogic::Update()
#endif
CMessages::ClearMessages();
CCarCtrl::ClearInterestingVehicleList();
- CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
+ CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, true);
CRestart::FindClosestHospitalRestartPoint(pPlayerInfo.GetPos(), &vecRestartPos, &fRestartFloat);
CRestart::OverrideHospitalLevel = LEVEL_GENERIC;
CRestart::OverridePoliceStationLevel = LEVEL_GENERIC;
PassTime(720);
RestorePlayerStuffDuringResurrection(pPlayerInfo.m_pPed, vecRestartPos, fRestartFloat);
+ AfterDeathArrestSetUpShortCutTaxi();
SortOutStreamingAndMemory(pPlayerInfo.GetPos());
TheCamera.m_fCamShakeForce = 0.0f;
TheCamera.SetMotionBlur(0, 0, 0, 0, MOTION_BLUR_NONE);
CPad::GetPad(0)->StopShaking(0);
CReferences::RemoveReferencesToPlayer();
- CCarCtrl::CountDownToCarsAtStart = 2;
+ CPopulation::m_CountDownToPedsAtStart = 10;
+ CCarCtrl::CountDownToCarsAtStart = 10;
CPad::GetPad(CWorld::PlayerInFocus)->DisablePlayerControls = PLAYERCONTROL_ENABLED;
if (CRestart::bFadeInAfterNextDeath) {
TheCamera.SetFadeColour(200, 200, 200);
TheCamera.Fade(4.0f, FADE_IN);
- } else CRestart::bFadeInAfterNextDeath = true;
+ } else
+ CRestart::bFadeInAfterNextDeath = true;
}
break;
case WBSTATE_BUSTED:
@@ -151,11 +198,35 @@ CGameLogic::Update()
TheCamera.SetFadeColour(0, 0, 0);
TheCamera.Fade(2.0f, FADE_OUT);
}
+
+
+ if (!CTheScripts::IsPlayerOnAMission() && pPlayerInfo.m_nBustedAudioStatus == BUSTEDAUDIO_NONE) {
+ if (CGeneral::GetRandomNumberInRange(0, 4) == 0)
+ pPlayerInfo.m_nBustedAudioStatus = BUSTEDAUDIO_DONE;
+ else {
+ pPlayerInfo.m_nBustedAudioStatus = BUSTEDAUDIO_LOADING;
+ char name[12];
+ sprintf(name, pPlayerInfo.m_nCurrentBustedAudio >= 10 ? "bust_%d" : "bust_0%d", pPlayerInfo.m_nCurrentBustedAudio);
+ DMAudio.ClearMissionAudio(0);
+ DMAudio.PreloadMissionAudio(0, name);
+ pPlayerInfo.m_nCurrentBustedAudio = pPlayerInfo.m_nCurrentBustedAudio % TOTAL_BUSTED_AUDIO + 1;
+ }
+ }
+ if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > 4000 &&
+ pPlayerInfo.m_nBustedAudioStatus == BUSTEDAUDIO_LOADING &&
+ DMAudio.GetMissionAudioLoadingStatus(0) == 1) {
+ DMAudio.PlayLoadedMissionAudio(0);
+ pPlayerInfo.m_nBustedAudioStatus = BUSTEDAUDIO_DONE;
+ }
+
#ifdef MISSION_REPLAY
if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime >= AddExtraDeathDelay() + 0x1000) {
#else
if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime >= 0x1000) {
#endif
+#ifdef FIX_BUGS
+ pPlayerInfo.m_nBustedAudioStatus = BUSTEDAUDIO_NONE;
+#endif
pPlayerInfo.m_WBState = WBSTATE_PLAYING;
int takeMoney;
@@ -205,24 +276,27 @@ CGameLogic::Update()
#endif
CMessages::ClearMessages();
CCarCtrl::ClearInterestingVehicleList();
- CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
+ CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, true);
CRestart::FindClosestPoliceRestartPoint(pPlayerInfo.GetPos(), &vecRestartPos, &fRestartFloat);
CRestart::OverrideHospitalLevel = LEVEL_GENERIC;
CRestart::OverridePoliceStationLevel = LEVEL_GENERIC;
PassTime(720);
RestorePlayerStuffDuringResurrection(pPlayerInfo.m_pPed, vecRestartPos, fRestartFloat);
+ AfterDeathArrestSetUpShortCutTaxi();
pPlayerInfo.m_pPed->ClearWeapons();
SortOutStreamingAndMemory(pPlayerInfo.GetPos());
TheCamera.m_fCamShakeForce = 0.0f;
TheCamera.SetMotionBlur(0, 0, 0, 0, MOTION_BLUR_NONE);
CPad::GetPad(0)->StopShaking(0);
CReferences::RemoveReferencesToPlayer();
- CCarCtrl::CountDownToCarsAtStart = 2;
+ CPopulation::m_CountDownToPedsAtStart = 10;
+ CCarCtrl::CountDownToCarsAtStart = 10;
CPad::GetPad(CWorld::PlayerInFocus)->DisablePlayerControls = PLAYERCONTROL_ENABLED;
if (CRestart::bFadeInAfterNextArrest) {
TheCamera.SetFadeColour(0, 0, 0);
TheCamera.Fade(4.0f, FADE_IN);
- } else CRestart::bFadeInAfterNextArrest = true;
+ } else
+ CRestart::bFadeInAfterNextArrest = true;
}
break;
case WBSTATE_FAILED_CRITICAL_MISSION:
@@ -257,7 +331,7 @@ CGameLogic::Update()
#endif
CMessages::ClearMessages();
CCarCtrl::ClearInterestingVehicleList();
- CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
+ CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, true);
CRestart::FindClosestPoliceRestartPoint(pPlayerInfo.GetPos(), &vecRestartPos, &fRestartFloat);
CRestart::OverridePoliceStationLevel = LEVEL_GENERIC;
CRestart::OverrideHospitalLevel = LEVEL_GENERIC;
@@ -267,7 +341,8 @@ CGameLogic::Update()
TheCamera.SetMotionBlur(0, 0, 0, 0, MOTION_BLUR_NONE);
CPad::GetPad(0)->StopShaking(0);
CReferences::RemoveReferencesToPlayer();
- CCarCtrl::CountDownToCarsAtStart = 2;
+ CPopulation::m_CountDownToPedsAtStart = 10;
+ CCarCtrl::CountDownToCarsAtStart = 10;
CPad::GetPad(CWorld::PlayerInFocus)->DisablePlayerControls = PLAYERCONTROL_ENABLED;
TheCamera.SetFadeColour(0, 0, 0);
TheCamera.Fade(4.0f, FADE_IN);
@@ -281,11 +356,17 @@ CGameLogic::Update()
void
CGameLogic::RestorePlayerStuffDuringResurrection(CPlayerPed *pPlayerPed, CVector pos, float angle)
{
- pPlayerPed->m_fHealth = 100.0f;
+ ClearShortCut();
+ CPlayerInfo* pPlayerInfo = pPlayerPed->GetPlayerInfoForThisPlayerPed();
+ pPlayerPed->m_fHealth = pPlayerInfo->m_nMaxHealth;
pPlayerPed->m_fArmour = 0.0f;
pPlayerPed->bIsVisible = true;
pPlayerPed->m_bloodyFootprintCountOrDeathTime = 0;
pPlayerPed->bDoBloodyFootprints = false;
+ pPlayerPed->m_nDrunkenness = 0;
+ pPlayerPed->m_nFadeDrunkenness = 0;
+ CMBlur::ClearDrunkBlur();
+ pPlayerPed->m_nDrunkCountdown = 0;
pPlayerPed->ClearAdrenaline();
pPlayerPed->m_fCurrentStamina = pPlayerPed->m_fMaxStamina;
if (pPlayerPed->m_pFire)
@@ -294,27 +375,258 @@ CGameLogic::RestorePlayerStuffDuringResurrection(CPlayerPed *pPlayerPed, CVector
pPlayerPed->m_pMyVehicle = nil;
pPlayerPed->m_pVehicleAnim = nil;
pPlayerPed->m_pWanted->Reset();
+ pPlayerPed->bCancelEnteringCar = false;
pPlayerPed->RestartNonPartialAnims();
- pPlayerPed->GetPlayerInfoForThisPlayerPed()->MakePlayerSafe(false);
+ pPlayerInfo->MakePlayerSafe(false);
pPlayerPed->bRemoveFromWorld = false;
pPlayerPed->ClearWeaponTarget();
pPlayerPed->SetInitialState();
CCarCtrl::ClearInterestingVehicleList();
-
- pos.z += 1.0f;
- pPlayerPed->Teleport(pos);
- pPlayerPed->SetMoveSpeed(CVector(0.0f, 0.0f, 0.0f));
-
+ pPlayerPed->Teleport(pos + CVector(0.0f, 0.0f, 1.0f));
+ pPlayerPed->SetMoveSpeed(0.0f, 0.0f, 0.0f);
pPlayerPed->m_fRotationCur = DEGTORAD(angle);
pPlayerPed->m_fRotationDest = pPlayerPed->m_fRotationCur;
pPlayerPed->SetHeading(pPlayerPed->m_fRotationCur);
CTheScripts::ClearSpaceForMissionEntity(pos, pPlayerPed);
- CWorld::ClearExcitingStuffFromArea(pos, 4000.0, 1);
+ CWorld::ClearExcitingStuffFromArea(pos, 4000.0f, true);
pPlayerPed->RestoreHeadingRate();
+ CGame::currArea = AREA_MAIN_MAP;
+ CStreaming::RemoveBuildingsNotInArea(AREA_MAIN_MAP);
TheCamera.SetCameraDirectlyInFrontForFollowPed_CamOnAString();
+ TheCamera.Restore();
CReferences::RemoveReferencesToPlayer();
CGarages::PlayerArrestedOrDied();
CStats::CheckPointReachedUnsuccessfully();
CWorld::Remove(pPlayerPed);
CWorld::Add(pPlayerPed);
+ CHud::ResetWastedText();
+ CStreaming::StreamZoneModels(pos);
+ clearWaterDrop = true;
+}
+
+void
+CGameLogic::ClearShortCut()
+{
+ if (pShortCutTaxi) {
+ if (pShortCutTaxi->VehicleCreatedBy == MISSION_VEHICLE) {
+ pShortCutTaxi->VehicleCreatedBy = RANDOM_VEHICLE;
+ --CCarCtrl::NumMissionCars;
+ ++CCarCtrl::NumRandomCars;
+ }
+ CRadar::ClearBlipForEntity(BLIP_CAR, CPools::GetVehiclePool()->GetIndex(pShortCutTaxi));
+ pShortCutTaxi = nil;
+ }
+ CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_SHORTCUT_TAXI);
+}
+
+void
+CGameLogic::SetUpShortCut(CVector vStartPos, float fStartAngle, CVector vEndPos, float fEndAngle)
+{
+ ClearShortCut();
+ ShortCutState = SHORTCUT_INIT;
+ ShortCutStart = vStartPos;
+ ShortCutStartOrientation = fStartAngle;
+ ShortCutDestination = vEndPos;
+ ShortCutDestinationOrientation = fEndAngle;
+ CStreaming::RequestModel(MI_KAUFMAN, 0);
+}
+
+void
+CGameLogic::AbandonShortCutIfTaxiHasBeenMessedWith()
+{
+ if (!pShortCutTaxi)
+ return;
+ if (pShortCutTaxi->pDriver == nil ||
+ pShortCutTaxi->pDriver->DyingOrDead() ||
+ pShortCutTaxi->pDriver->GetPedState() == PED_DRAG_FROM_CAR ||
+ pShortCutTaxi->pDriver->GetPedState() == PED_ON_FIRE ||
+ pShortCutTaxi->pDriver->m_objective == OBJECTIVE_LEAVE_CAR_AND_DIE ||
+ pShortCutTaxi->m_fHealth < 250.0f ||
+ pShortCutTaxi->bRenderScorched)
+ ClearShortCut();
+}
+
+void
+CGameLogic::AbandonShortCutIfPlayerMilesAway()
+{
+ if (!pShortCutTaxi)
+ return;
+ if ((FindPlayerCoors() - pShortCutTaxi->GetPosition()).Magnitude() > 120.0f)
+ ClearShortCut();
+}
+
+void
+CGameLogic::UpdateShortCut()
+{
+ switch (ShortCutState) {
+ case SHORTCUT_INIT:
+ if (!CStreaming::HasModelLoaded(MI_KAUFMAN)) {
+ CStreaming::RequestModel(MI_KAUFMAN, 0);
+ return;
+ }
+ pShortCutTaxi = new CAutomobile(MI_KAUFMAN, RANDOM_VEHICLE);
+ if (!pShortCutTaxi)
+ return;
+ pShortCutTaxi->SetPosition(ShortCutStart);
+ pShortCutTaxi->SetHeading(DEGTORAD(ShortCutStartOrientation));
+ pShortCutTaxi->PlaceOnRoadProperly();
+ pShortCutTaxi->SetStatus(STATUS_PHYSICS);
+ pShortCutTaxi->AutoPilot.m_nCarMission = MISSION_STOP_FOREVER;
+ pShortCutTaxi->AutoPilot.m_nCruiseSpeed = 0;
+ pShortCutTaxi->SetUpDriver();
+ pShortCutTaxi->VehicleCreatedBy = MISSION_VEHICLE;
+ ++CCarCtrl::NumMissionCars;
+ --CCarCtrl::NumRandomCars;
+ CTheScripts::ClearSpaceForMissionEntity(ShortCutStart, pShortCutTaxi);
+ CWorld::Add(pShortCutTaxi);
+ CRadar::SetEntityBlip(BLIP_CAR, CPools::GetVehiclePool()->GetIndex(pShortCutTaxi), 0, BLIP_DISPLAY_MARKER_ONLY);
+ ShortCutState = SHORTCUT_IDLE;
+ break;
+ case SHORTCUT_IDLE:
+ if (FindPlayerPed()->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER && FindPlayerPed()->m_carInObjective == pShortCutTaxi) {
+ CPad::GetPad(0)->SetDisablePlayerControls(PLAYERCONTROL_SHORTCUT_TAXI);
+ FindPlayerPed()->SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, pShortCutTaxi);
+ ShortCutState = SHORTCUT_GETTING_IN;
+ }
+ AbandonShortCutIfTaxiHasBeenMessedWith();
+ AbandonShortCutIfPlayerMilesAway();
+ break;
+ case SHORTCUT_GETTING_IN:
+ if (pShortCutTaxi->pPassengers[0] == FindPlayerPed() ||
+ pShortCutTaxi->pPassengers[1] == FindPlayerPed() ||
+ pShortCutTaxi->pPassengers[2] == FindPlayerPed()) {
+ pShortCutTaxi->AutoPilot.m_nTempAction = TEMPACT_GOFORWARD;
+ pShortCutTaxi->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 2500;
+ TheCamera.SetFadeColour(0, 0, 0);
+ TheCamera.Fade(2.5f, FADE_OUT);
+ ShortCutState = SHORTCUT_TRANSITION;
+ ShortCutTimer = CTimer::GetTimeInMilliseconds() + 3000;
+ CMessages::AddBigMessage(TheText.Get("TAXI"), 4500, 1);
+ }
+ AbandonShortCutIfTaxiHasBeenMessedWith();
+ break;
+ case SHORTCUT_TRANSITION:
+ if (CTimer::GetTimeInMilliseconds() > ShortCutTimer) {
+ CTimer::Suspend();
+ CColStore::RequestCollision(ShortCutDestination);
+ CStreaming::LoadSceneCollision(ShortCutDestination);
+ CStreaming::LoadScene(ShortCutDestination);
+ CTheScripts::ClearSpaceForMissionEntity(ShortCutDestination, pShortCutTaxi);
+ pShortCutTaxi->Teleport(ShortCutDestination);
+ pShortCutTaxi->SetHeading(DEGTORAD(ShortCutDestinationOrientation));
+ pShortCutTaxi->PlaceOnRoadProperly();
+ pShortCutTaxi->SetMoveSpeed(pShortCutTaxi->GetForward() * 0.4f);
+ ShortCutTimer = CTimer::GetTimeInMilliseconds() + 1500;
+ TheCamera.SetFadeColour(0, 0, 0);
+ TheCamera.Fade(1.0f, FADE_IN);
+ ShortCutState = SHORTCUT_ARRIVING;
+ CTimer::Resume();
+ }
+ break;
+ case SHORTCUT_ARRIVING:
+ if (CTimer::GetTimeInMilliseconds() > ShortCutTimer) {
+ CWorld::Players[CWorld::PlayerInFocus].m_nMoney = Max(0, CWorld::Players[CWorld::PlayerInFocus].m_nMoney - SHORTCUT_TAXI_COST);
+ FindPlayerPed()->SetObjective(OBJECTIVE_LEAVE_CAR, pShortCutTaxi);
+ FindPlayerPed()->m_carInObjective = pShortCutTaxi;
+ ShortCutState = SHORTCUT_GETTING_OUT;
+ }
+ AbandonShortCutIfTaxiHasBeenMessedWith();
+ break;
+ case SHORTCUT_GETTING_OUT:
+ if (pShortCutTaxi->pPassengers[0] != FindPlayerPed() &&
+ pShortCutTaxi->pPassengers[1] != FindPlayerPed() &&
+ pShortCutTaxi->pPassengers[2] != FindPlayerPed()) {
+ CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_SHORTCUT_TAXI);
+ pShortCutTaxi->AutoPilot.m_nCarMission = MISSION_CRUISE;
+ pShortCutTaxi->AutoPilot.m_nCruiseSpeed = 18;
+ CCarCtrl::JoinCarWithRoadSystem(pShortCutTaxi);
+ pShortCutTaxi->VehicleCreatedBy = RANDOM_VEHICLE;
+ ++CCarCtrl::NumRandomCars;
+ --CCarCtrl::NumMissionCars;
+ CRadar::ClearBlipForEntity(BLIP_CAR, CPools::GetVehiclePool()->GetIndex(pShortCutTaxi));
+ ShortCutState = SHORTCUT_NONE;
+ pShortCutTaxi = nil;
+ }
+ AbandonShortCutIfTaxiHasBeenMessedWith();
+ break;
+ }
+}
+
+void
+CGameLogic::AddShortCutPointAfterDeath(CVector point, float angle)
+{
+ if (NumAfterDeathStartPoints >= NUM_SHORTCUT_START_POINTS)
+ return;
+ AfterDeathStartPoints[NumAfterDeathStartPoints] = point;
+ AfterDeathStartPointOrientation[NumAfterDeathStartPoints] = angle;
+ NumAfterDeathStartPoints++;
+}
+
+void
+CGameLogic::AddShortCutDropOffPointForMission(CVector point, float angle)
+{
+ ShortCutDropOffForMission = point;
+ ShortCutDropOffOrientationForMission = angle;
+ MissionDropOffReadyToBeUsed = true;
+}
+
+void
+CGameLogic::RemoveShortCutDropOffPointForMission()
+{
+ MissionDropOffReadyToBeUsed = false;
+}
+
+void
+CGameLogic::AfterDeathArrestSetUpShortCutTaxi()
+{
+ if (!MissionDropOffReadyToBeUsed)
+ return;
+ int nClosestPoint = -1;
+ float fDistanceToPoint = 999999.9f;
+ for (int i = 0; i < NUM_SHORTCUT_START_POINTS; i++) {
+ float dist = (AfterDeathStartPoints[i] - FindPlayerCoors()).Magnitude();
+ if (dist < fDistanceToPoint) {
+ fDistanceToPoint = dist;
+ nClosestPoint = i;
+ }
+ }
+ if (fDistanceToPoint < 100.0f)
+ SetUpShortCut(AfterDeathStartPoints[nClosestPoint],
+ AfterDeathStartPointOrientation[nClosestPoint],
+ ShortCutDropOffForMission,
+ ShortCutDropOffOrientationForMission);
+ MissionDropOffReadyToBeUsed = false;
+}
+
+void
+CGameLogic::Save(uint8* buf, uint32* size)
+{
+INITSAVEBUF
+ WriteSaveBuf(buf, NumAfterDeathStartPoints);
+ *size += sizeof(NumAfterDeathStartPoints);
+ for (int i = 0; i < NUM_SHORTCUT_START_POINTS; i++) {
+ WriteSaveBuf(buf, AfterDeathStartPoints[i].x);
+ *size += sizeof(AfterDeathStartPoints[i].x);
+ WriteSaveBuf(buf, AfterDeathStartPoints[i].y);
+ *size += sizeof(AfterDeathStartPoints[i].y);
+ WriteSaveBuf(buf, AfterDeathStartPoints[i].z);
+ *size += sizeof(AfterDeathStartPoints[i].z);
+ WriteSaveBuf(buf, AfterDeathStartPointOrientation[i]);
+ *size += sizeof(AfterDeathStartPointOrientation[i]);
+ }
+VALIDATESAVEBUF(*size)
+}
+
+void
+CGameLogic::Load(uint8* buf, uint32 size)
+{
+INITSAVEBUF
+ ReadSaveBuf(&NumAfterDeathStartPoints, buf);
+ for (int i = 0; i < NUM_SHORTCUT_START_POINTS; i++) {
+ ReadSaveBuf(&AfterDeathStartPoints[i].x, buf);
+ ReadSaveBuf(&AfterDeathStartPoints[i].y, buf);
+ ReadSaveBuf(&AfterDeathStartPoints[i].z, buf);
+ ReadSaveBuf(&AfterDeathStartPointOrientation[i], buf);
+ }
+VALIDATESAVEBUF(size)
}
diff --git a/src/control/GameLogic.h b/src/control/GameLogic.h
index 43e244a3..9b774cc7 100644
--- a/src/control/GameLogic.h
+++ b/src/control/GameLogic.h
@@ -1,13 +1,51 @@
#pragma once
+class CAutomobile;
+
class CGameLogic
{
public:
+ enum {
+ SHORTCUT_NONE = 0,
+ SHORTCUT_INIT,
+ SHORTCUT_IDLE,
+ SHORTCUT_GETTING_IN,
+ SHORTCUT_TRANSITION,
+ SHORTCUT_ARRIVING,
+ SHORTCUT_GETTING_OUT
+ };
+
static void InitAtStartOfGame();
static void PassTime(uint32 time);
static void SortOutStreamingAndMemory(const CVector &pos);
static void Update();
static void RestorePlayerStuffDuringResurrection(class CPlayerPed *pPlayerPed, CVector pos, float angle);
+ static void ClearShortCut();
+ static void SetUpShortCut(CVector, float, CVector, float);
+ static void AbandonShortCutIfTaxiHasBeenMessedWith();
+ static void AbandonShortCutIfPlayerMilesAway();
+ static void UpdateShortCut();
+ static void AddShortCutPointAfterDeath(CVector, float);
+ static void AddShortCutDropOffPointForMission(CVector, float);
+ static void RemoveShortCutDropOffPointForMission();
+ static void AfterDeathArrestSetUpShortCutTaxi();
+
+ static void Save(uint8*, uint32*);
+ static void Load(uint8*, uint32);
+
static uint8 ActivePlayers;
+ static uint8 ShortCutState;
+ static CAutomobile* pShortCutTaxi;
+ static uint32 NumAfterDeathStartPoints;
+ static CVector ShortCutStart;
+ static float ShortCutStartOrientation;
+ static CVector ShortCutDestination;
+ static float ShortCutDestinationOrientation;
+ static uint32 ShortCutTimer;
+ static CVector AfterDeathStartPoints[NUM_SHORTCUT_START_POINTS];
+ static float AfterDeathStartPointOrientation[NUM_SHORTCUT_START_POINTS];
+ static CVector ShortCutDropOffForMission;
+ static float ShortCutDropOffOrientationForMission;
+ static bool MissionDropOffReadyToBeUsed;
}; \ No newline at end of file
diff --git a/src/control/Garages.cpp b/src/control/Garages.cpp
index bb919eae..b24c9122 100644
--- a/src/control/Garages.cpp
+++ b/src/control/Garages.cpp
@@ -3,9 +3,8 @@
#include "Garages.h"
#include "main.h"
-#ifdef FIX_BUGS
+#include "Bike.h"
#include "Boat.h"
-#endif
#include "DMAudio.h"
#include "General.h"
#include "Font.h"
@@ -24,6 +23,7 @@
#include "Vehicle.h"
#include "Wanted.h"
#include "World.h"
+#include "VarConsole.h"
#include "SaveBuf.h"
#define ROTATED_DOOR_OPEN_SPEED (0.015f)
@@ -33,21 +33,21 @@
#define CRUSHER_CRANE_SPEED (0.005f)
// Prices
-#define BOMB_PRICE (1000)
-#define RESPRAY_PRICE (1000)
+#define BOMB_PRICE (500)
+#define RESPRAY_PRICE (100)
// Distances
#define DISTANCE_TO_CALL_OFF_CHASE (10.0f)
-#define DISTANCE_FOR_MRWHOOP_HACK (4.0f)
+#define DISTANCE_FOR_MRWHOOP_HACK (0.5f)
#define DISTANCE_TO_ACTIVATE_GARAGE (8.0f)
#define DISTANCE_TO_ACTIVATE_KEEPCAR_GARAGE (17.0f)
#define DISTANCE_TO_CLOSE_MISSION_GARAGE (30.0f)
#define DISTANCE_TO_CLOSE_COLLECTSPECIFICCARS_GARAGE (25.0f)
#define DISTANCE_TO_CLOSE_COLLECTCARS_GARAGE (40.0f)
-#define DISTANCE_TO_CLOSE_HIDEOUT_GARAGE_ON_FOOT (2.2f)
+#define DISTANCE_TO_CLOSE_HIDEOUT_GARAGE_ON_FOOT (3.2f)
#define DISTANCE_TO_CLOSE_HIDEOUT_GARAGE_IN_CAR (15.0f)
#define DISTANCE_TO_FORCE_CLOSE_HIDEOUT_GARAGE (70.0f)
-#define DISTANCE_TO_OPEN_HIDEOUT_GARAGE_ON_FOOT (1.7f)
+#define DISTANCE_TO_OPEN_HIDEOUT_GARAGE_ON_FOOT (2.8f)
#define DISTANCE_TO_OPEN_HIDEOUT_GARAGE_IN_CAR (10.0f)
#define DISTANCE_TO_SHOW_HIDEOUT_MESSAGE (5.0f)
@@ -62,7 +62,7 @@
// Respray stuff
#define FREE_RESPRAY_HEALTH_THRESHOLD (970.0f)
#define NUM_PARTICLES_IN_RESPRAY (200)
-#define RESPRAY_CENTERING_COEFFICIENT (0.75f)
+#define RESPRAY_CENTERING_COEFFICIENT (0.4f)
// Bomb stuff
#define KGS_OF_EXPLOSIVES_IN_BOMB (10)
@@ -75,8 +75,8 @@
// Collect cars stuff
#define MAX_SPEED_TO_SHOW_COLLECTED_MESSAGE (0.03f)
-#define IMPORT_REWARD (1000)
-#define IMPORT_ALLCARS_REWARD (200000)
+#define IMPORT_REWARD (500)
+#define IMPORT_ALLCARS_REWARD (20500)
// Crusher stuff
#define CRUSHER_VEHICLE_TEST_SPAN (8)
@@ -85,24 +85,19 @@
#define CRUSHER_REWARD_COEFFICIENT (1.0f/500000)
// Hideout stuff
-#define MAX_STORED_CARS_IN_INDUSTRIAL (1)
-#define MAX_STORED_CARS_IN_COMMERCIAL (NUM_GARAGE_STORED_CARS)
-#define MAX_STORED_CARS_IN_SUBURBAN (NUM_GARAGE_STORED_CARS)
-#define LIMIT_CARS_IN_INDUSTRIAL (1)
-#define LIMIT_CARS_IN_COMMERCIAL (2)
-#define LIMIT_CARS_IN_SUBURBAN (3)
#define HIDEOUT_DOOR_SPEED_COEFFICIENT (1.7f)
#define TIME_BETWEEN_HIDEOUT_MESSAGES (18000)
// Camera stuff
-#define MARGIN_FOR_CAMERA_COLLECTCARS (1.3f)
-#define MARGIN_FOR_CAMERA_DEFAULT (4.0f)
+#define MARGIN_FOR_CAMERA_COLLECTCARS (0.5f)
+#define MARGIN_FOR_CAMERA_DEFAULT (0.5f)
const int32 gaCarsToCollectInCraigsGarages[TOTAL_COLLECTCARS_GARAGES][TOTAL_COLLECTCARS_CARS] =
{
- { MI_SECURICA, MI_MOONBEAM, MI_COACH, MI_FLATBED, MI_LINERUN, MI_TRASH, MI_PATRIOT, MI_MRWHOOP, MI_BLISTA, MI_MULE, MI_YANKEE, MI_BOBCAT, MI_DODO, MI_BUS, MI_RUMPO, MI_PONY },
- { MI_SENTINEL, MI_CHEETAH, MI_BANSHEE, MI_IDAHO, MI_INFERNUS, MI_TAXI, MI_KURUMA, MI_STRETCH, MI_PEREN, MI_STINGER, MI_MANANA, MI_LANDSTAL, MI_STALLION, MI_BFINJECT, MI_CABBIE, MI_ESPERANT },
- { MI_LANDSTAL, MI_LANDSTAL, MI_LANDSTAL, MI_LANDSTAL, MI_LANDSTAL, MI_LANDSTAL, MI_LANDSTAL, MI_LANDSTAL, MI_LANDSTAL, MI_LANDSTAL, MI_LANDSTAL, MI_CHEETAH, MI_TAXI, MI_ESPERANT, MI_SENTINEL, MI_IDAHO }
+ { MI_LANDSTAL, MI_IDAHO, MI_ESPERANT, MI_STALLION, MI_RANCHER, MI_BLISTAC },
+ { MI_SABRE, MI_VIRGO, MI_SENTINEL, MI_STRETCH, MI_WASHING, MI_ADMIRAL },
+ { MI_CHEETAH, MI_INFERNUS, MI_BANSHEE, MI_PHEONIX, MI_COMET, MI_STINGER },
+ { MI_VOODOO, MI_CUBAN, MI_CADDY, MI_BAGGAGE, MI_MRWHOOP, MI_PIZZABOY }
};
const int32 gaCarsToCollectIn60Seconds[] = { MI_CHEETAH, MI_TAXI, MI_ESPERANT, MI_SENTINEL, MI_IDAHO };
@@ -122,15 +117,20 @@ uint32 CGarages::MessageEndTime;
uint32 CGarages::NumGarages;
bool CGarages::PlayerInGarage;
int32 CGarages::PoliceCarsCollected;
-CStoredCar CGarages::aCarsInSafeHouse1[NUM_GARAGE_STORED_CARS];
-CStoredCar CGarages::aCarsInSafeHouse2[NUM_GARAGE_STORED_CARS];
-CStoredCar CGarages::aCarsInSafeHouse3[NUM_GARAGE_STORED_CARS];
+CStoredCar CGarages::aCarsInSafeHouses[TOTAL_HIDEOUT_GARAGES][NUM_GARAGE_STORED_CARS];
int32 hGarages = AEHANDLE_NONE;
CGarage CGarages::aGarages[NUM_GARAGES];
bool CGarages::bCamShouldBeOutisde;
+#ifndef MASTER
+bool bPrintNearestObject;
+#endif
+
void CGarages::Init(void)
{
+#ifndef MASTER
+ VarConsole.Add("Print nearest object", &bPrintNearestObject, true);
+#endif
CrushedCarId = -1;
NumGarages = 0;
MessageEndTime = 0;
@@ -146,22 +146,15 @@ void CGarages::Init(void)
for (int i = 0; i < TOTAL_COLLECTCARS_GARAGES; i++)
CarTypesCollected[i] = 0;
LastTimeHelpMessage = 0;
- for (int i = 0; i < NUM_GARAGE_STORED_CARS; i++)
- aCarsInSafeHouse1[i].Init();
- for (int i = 0; i < NUM_GARAGE_STORED_CARS; i++)
- aCarsInSafeHouse2[i].Init();
- for (int i = 0; i < NUM_GARAGE_STORED_CARS; i++)
- aCarsInSafeHouse3[i].Init();
+ for (int i = 0; i < NUM_GARAGE_STORED_CARS; i++) {
+ for (int j = 0; j < TOTAL_HIDEOUT_GARAGES; j++)
+ aCarsInSafeHouses[j][i].Init();
+ }
hGarages = DMAudio.CreateEntity(AUDIOTYPE_GARAGE, (void*)1);
if (hGarages >= 0)
DMAudio.SetEntityStatus(hGarages, TRUE);
- AddOne(
- CVector(CRUSHER_GARAGE_X1, CRUSHER_GARAGE_Y1, CRUSHER_GARAGE_Z1),
- CVector(CRUSHER_GARAGE_X2, CRUSHER_GARAGE_Y2, CRUSHER_GARAGE_Z2),
- GARAGE_CRUSHER, 0);
}
-#ifndef PS2
void CGarages::Shutdown(void)
{
NumGarages = 0;
@@ -170,23 +163,34 @@ void CGarages::Shutdown(void)
DMAudio.DestroyEntity(hGarages);
hGarages = AEHANDLE_NONE;
}
-#endif
void CGarages::Update(void)
{
- static int GarageToBeTidied = 0;
+ static uint32 GarageToBeTidied = 0;
if (CReplay::IsPlayingBack())
return;
+#ifdef SECUROM
+ extern uint8 gameProcessPirateCheck;
+ if (gameProcessPirateCheck == 2) return;
+#endif
bCamShouldBeOutisde = false;
TheCamera.pToGarageWeAreIn = nil;
TheCamera.pToGarageWeAreInForHackAvoidFirstPerson = nil;
+#ifdef FIX_BUGS
+ for (uint32 i = 0; i < NumGarages; i++) {
+#else
for (int i = 0; i < NUM_GARAGES; i++) {
+#endif
if (aGarages[i].IsUsed())
aGarages[i].Update();
}
if ((CTimer::GetFrameCounter() & 0xF) != 0xC)
return;
+#ifdef FIX_BUGS
+ if (++GarageToBeTidied >= NumGarages)
+#else
if (++GarageToBeTidied >= NUM_GARAGES)
+#endif
GarageToBeTidied = 0;
if (!aGarages[GarageToBeTidied].IsUsed())
return;
@@ -196,23 +200,31 @@ void CGarages::Update(void)
aGarages[GarageToBeTidied].TidyUpGarage();
}
-int16 CGarages::AddOne(CVector p1, CVector p2, uint8 type, int32 targetId)
+int16 CGarages::AddOne(float X1, float Y1, float Z1, float X2, float Y2, float X3, float Y3, float Z2, uint8 type, int32 targetId)
{
if (NumGarages >= NUM_GARAGES) {
assert(0);
return NumGarages++;
}
CGarage* pGarage = &aGarages[NumGarages];
- pGarage->m_fX1 = Min(p1.x, p2.x);
- pGarage->m_fX2 = Max(p1.x, p2.x);
- pGarage->m_fY1 = Min(p1.y, p2.y);
- pGarage->m_fY2 = Max(p1.y, p2.y);
- pGarage->m_fZ1 = Min(p1.z, p2.z);
- pGarage->m_fZ2 = Max(p1.z, p2.z);
+ pGarage->m_fInfX = Min(Min(Min(X1, X2), X3), X2 + X3 - X1);
+ pGarage->m_fSupX = Max(Max(X1, X2), X3);
+ pGarage->m_fInfY = Min(Min(Min(Y1, Y2), Y3), Y2 + Y3 - Y1);
+ pGarage->m_fSupY = Max(Max(Y1, Y2), Y3);
+ pGarage->m_vecCorner1 = CVector(X1, Y1, Z1);
+ pGarage->m_fInfZ = Z1;
+ pGarage->m_vDir1 = CVector2D(X2 - X1, Y2 - Y1);
+ pGarage->m_vDir2 = CVector2D(X3 - X1, Y3 - Y1);
+ pGarage->m_fSupZ = Z2;
+ pGarage->m_nMaxStoredCars = NUM_GARAGE_STORED_CARS;
+ pGarage->m_fDir1Len = pGarage->m_vDir1.Magnitude();
+ pGarage->m_fDir2Len = pGarage->m_vDir2.Magnitude();
+ pGarage->m_vDir1 /= pGarage->m_fDir1Len;
+ pGarage->m_vDir2 /= pGarage->m_fDir2Len;
pGarage->m_pDoor1 = nil;
pGarage->m_pDoor2 = nil;
- pGarage->m_fDoor1Z = p1.z;
- pGarage->m_fDoor2Z = p1.z;
+ pGarage->m_fDoor1Z = Z1;
+ pGarage->m_fDoor2Z = Z1;
pGarage->m_eGarageType = type;
pGarage->m_bRecreateDoorOnNextRefresh = false;
pGarage->m_bRotatedDoor = false;
@@ -234,7 +246,6 @@ int16 CGarages::AddOne(CVector p1, CVector p2, uint8 type, int32 targetId)
pGarage->m_nTimeToStartAction = 0;
pGarage->field_2 = false;
pGarage->m_nTargetModelIndex = targetId;
- pGarage->field_96 = nil;
pGarage->m_bCollectedCarsState = 0;
pGarage->m_bDeactivated = false;
pGarage->m_bResprayHappened = false;
@@ -255,6 +266,17 @@ int16 CGarages::AddOne(CVector p1, CVector p2, uint8 type, int32 targetId)
case GARAGE_FOR_SCRIPT_TO_OPEN_AND_CLOSE:
case GARAGE_KEEPS_OPENING_FOR_SPECIFIC_CAR:
case GARAGE_MISSION_KEEPCAR_REMAINCLOSED:
+ case GARAGE_COLLECTCARS_4:
+ case GARAGE_FOR_SCRIPT_TO_OPEN_FOR_CAR:
+ case GARAGE_HIDEOUT_FOUR:
+ case GARAGE_HIDEOUT_FIVE:
+ case GARAGE_HIDEOUT_SIX:
+ case GARAGE_HIDEOUT_SEVEN:
+ case GARAGE_HIDEOUT_EIGHT:
+ case GARAGE_HIDEOUT_NINE:
+ case GARAGE_HIDEOUT_TEN:
+ case GARAGE_HIDEOUT_ELEVEN:
+ case GARAGE_HIDEOUT_TWELVE:
pGarage->m_eGarageState = GS_FULLYCLOSED;
pGarage->m_fDoorPos = 0.0f;
break;
@@ -308,10 +330,10 @@ void CGarage::Update()
TheCamera.pToGarageWeAreInForHackAvoidFirstPerson = this;
if (pVehicle->GetModelIndex() == MI_MRWHOOP) {
if (pVehicle->IsWithinArea(
- m_fX1 - DISTANCE_FOR_MRWHOOP_HACK,
- m_fY1 + DISTANCE_FOR_MRWHOOP_HACK,
- m_fX2 - DISTANCE_FOR_MRWHOOP_HACK,
- m_fY2 + DISTANCE_FOR_MRWHOOP_HACK)) {
+ m_fInfX - DISTANCE_FOR_MRWHOOP_HACK,
+ m_fInfY - DISTANCE_FOR_MRWHOOP_HACK,
+ m_fSupX + DISTANCE_FOR_MRWHOOP_HACK,
+ m_fSupY + DISTANCE_FOR_MRWHOOP_HACK)) {
TheCamera.pToGarageWeAreIn = this;
CGarages::bCamShouldBeOutisde = true;
}
@@ -325,11 +347,48 @@ void CGarage::Update()
}
if (m_bDeactivated && m_eGarageState == GS_FULLYCLOSED)
return;
+ if (m_bRotatedDoor) {
+#ifdef GTA_PS2
+ if (m_eGarageState == GS_OPENING) {
+ if (m_pDoor1) {
+ if (FindPlayerPed()->m_pCurrentPhysSurface == m_pDoor1)
+ m_pDoor1->bUsesCollision = false;
+ }
+ if (m_pDoor2) {
+ if (FindPlayerPed()->m_pCurrentPhysSurface == m_pDoor2)
+ m_pDoor2->bUsesCollision = false;
+ }
+ }
+ else if (m_eGarageState == GS_OPENED) {
+ if (m_pDoor1)
+ m_pDoor1->bUsesCollision = true;
+ if (m_pDoor2)
+ m_pDoor2->bUsesCollision = true;
+ }
+#else
+ if (m_eGarageState == GS_OPENING || m_eGarageState == GS_OPENED) {
+ if (m_pDoor1) {
+ if (FindPlayerPed()->m_pCurrentPhysSurface == m_pDoor1 || FindPlayerPed()->GetPedState() == PED_JUMP || FindPlayerPed()->GetPedState() == PED_FALL || !FindPlayerPed()->bIsStanding)
+ m_pDoor1->bUsesCollision = false;
+ }
+ if (m_pDoor2) {
+ if (FindPlayerPed()->m_pCurrentPhysSurface == m_pDoor2 || FindPlayerPed()->GetPedState() == PED_JUMP || FindPlayerPed()->GetPedState() == PED_FALL || !FindPlayerPed()->bIsStanding)
+ m_pDoor2->bUsesCollision = false;
+ }
+ }
+ else {
+ if (m_pDoor1)
+ m_pDoor1->bUsesCollision = true;
+ if (m_pDoor2)
+ m_pDoor2->bUsesCollision = true;
+ }
+#endif
+ }
switch (m_eGarageType) {
case GARAGE_RESPRAY:
switch (m_eGarageState) {
case GS_OPENED:
- if (IsStaticPlayerCarEntirelyInside() && !IsAnyOtherCarTouchingGarage(FindPlayerVehicle())) {
+ if (IsStaticPlayerCarEntirelyInside()) {
if (CGarages::IsCarSprayable(FindPlayerVehicle())) {
if (CWorld::Players[CWorld::PlayerInFocus].m_nMoney >= RESPRAY_PRICE || CGarages::RespraysAreFree) {
m_eGarageState = GS_CLOSING;
@@ -337,7 +396,7 @@ void CGarage::Update()
FindPlayerPed()->m_pWanted->m_bIgnoredByCops = true;
}
else {
- CGarages::TriggerMessage("GA_3", -1, 4000, -1); // No more freebies. $1000 to respray!
+ CGarages::TriggerMessage("GA_3", -1, 4000, -1); // No more freebies. $100 to respray!
m_eGarageState = GS_OPENEDCONTAINSCAR;
DMAudio.PlayFrontEndSound(SOUND_GARAGE_NO_MONEY, 1);
}
@@ -351,13 +410,15 @@ void CGarage::Update()
if (FindPlayerVehicle()) {
if (CalcDistToGarageRectangleSquared(FindPlayerVehicle()->GetPosition().x, FindPlayerVehicle()->GetPosition().y) < SQR(DISTANCE_TO_ACTIVATE_GARAGE))
CWorld::CallOffChaseForArea(
- m_fX1 - DISTANCE_TO_CALL_OFF_CHASE,
- m_fY1 - DISTANCE_TO_CALL_OFF_CHASE,
- m_fX2 + DISTANCE_TO_CALL_OFF_CHASE,
- m_fY2 + DISTANCE_TO_CALL_OFF_CHASE);
+ m_fInfX - DISTANCE_TO_CALL_OFF_CHASE,
+ m_fInfY - DISTANCE_TO_CALL_OFF_CHASE,
+ m_fSupX + DISTANCE_TO_CALL_OFF_CHASE,
+ m_fSupY + DISTANCE_TO_CALL_OFF_CHASE);
}
break;
case GS_CLOSING:
+ if (FindPlayerVehicle())
+ ThrowCarsNearDoorOutOfGarage(FindPlayerVehicle());
m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) {
m_eGarageState = GS_FULLYCLOSED;
@@ -373,19 +434,20 @@ void CGarage::Update()
#endif
((CAutomobile*)(FindPlayerVehicle()))->m_fFireBlowUpTimer = 0.0f;
CWorld::CallOffChaseForArea(
- m_fX1 - DISTANCE_TO_CALL_OFF_CHASE,
- m_fY1 - DISTANCE_TO_CALL_OFF_CHASE,
- m_fX2 + DISTANCE_TO_CALL_OFF_CHASE,
- m_fY2 + DISTANCE_TO_CALL_OFF_CHASE);
+ m_fInfX - DISTANCE_TO_CALL_OFF_CHASE,
+ m_fInfY - DISTANCE_TO_CALL_OFF_CHASE,
+ m_fSupX + DISTANCE_TO_CALL_OFF_CHASE,
+ m_fSupY + DISTANCE_TO_CALL_OFF_CHASE);
break;
case GS_FULLYCLOSED:
if (CTimer::GetTimeInMilliseconds() > m_nTimeToStartAction) {
m_eGarageState = GS_OPENING;
DMAudio.PlayFrontEndSound(SOUND_GARAGE_OPENING, 1);
bool bTakeMoney = false;
- if (FindPlayerPed()->m_pWanted->GetWantedLevel() != 0)
+ if (FindPlayerPed()->m_pWanted->GetWantedLevel() != 0) {
bTakeMoney = true;
- FindPlayerPed()->m_pWanted->Reset();
+ FindPlayerPed()->m_pWanted->Suspend();
+ }
CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_GARAGE);
FindPlayerPed()->m_pWanted->m_bIgnoredByCops = false;
#ifdef FIX_BUGS
@@ -393,18 +455,30 @@ void CGarage::Update()
#else
bool bChangedColour;
#endif
- if (FindPlayerVehicle() && FindPlayerVehicle()->IsCar()) {
+ if (FindPlayerVehicle() && (FindPlayerVehicle()->IsCar() || FindPlayerVehicle()->IsBike())) {
if (FindPlayerVehicle()->m_fHealth < FREE_RESPRAY_HEALTH_THRESHOLD)
bTakeMoney = true;
FindPlayerVehicle()->m_fHealth = 1000.0f;
- ((CAutomobile*)(FindPlayerVehicle()))->m_fFireBlowUpTimer = 0.0f;
- ((CAutomobile*)(FindPlayerVehicle()))->Fix();
+ if (FindPlayerVehicle()->IsCar()) {
+ ((CAutomobile*)(FindPlayerVehicle()))->m_fFireBlowUpTimer = 0.0f;
+ ((CAutomobile*)(FindPlayerVehicle()))->Fix();
+ }
+ else {
+ ((CBike*)(FindPlayerVehicle()))->m_fFireBlowUpTimer = 0.0f;
+ ((CBike*)(FindPlayerVehicle()))->Fix();
+ }
+ FindPlayerVehicle()->m_nDoorLock = CARLOCK_UNLOCKED;
+ ++CStats::Sprayings;
if (FindPlayerVehicle()->GetUp().z < 0.0f) {
FindPlayerVehicle()->GetUp() = -FindPlayerVehicle()->GetUp();
FindPlayerVehicle()->GetRight() = -FindPlayerVehicle()->GetRight();
}
bChangedColour = false;
+#ifdef FIX_BUGS
+ if (!FindPlayerVehicle()->IsCar() || !((CAutomobile*)(FindPlayerVehicle()))->bFixedColour) {
+#else
if (!((CAutomobile*)(FindPlayerVehicle()))->bFixedColour) {
+#endif
uint8 colour1, colour2;
uint16 attempt;
FindPlayerVehicle()->GetModelInfo()->ChooseVehicleColour(colour1, colour2);
@@ -419,16 +493,9 @@ void CGarage::Update()
if (bChangedColour) {
for (int i = 0; i < NUM_PARTICLES_IN_RESPRAY; i++) {
CVector pos;
-#ifdef FIX_BUGS
- pos.x = CGeneral::GetRandomNumberInRange(m_fX1 + 0.5f, m_fX2 - 0.5f);
- pos.y = CGeneral::GetRandomNumberInRange(m_fY1 + 0.5f, m_fY2 - 0.5f);
+ pos.x = CGeneral::GetRandomNumberInRange(m_fInfX + 0.5f, m_fSupX - 0.5f);
+ pos.y = CGeneral::GetRandomNumberInRange(m_fInfY + 0.5f, m_fSupY - 0.5f);
pos.z = CGeneral::GetRandomNumberInRange(m_fDoor1Z - 3.0f, m_fDoor1Z + 1.0f);
-#else
- // wtf is this
- pos.x = m_fX1 + 0.5f + (uint8)(CGeneral::GetRandomNumber()) / 256.0f * (m_fX2 - m_fX1 - 1.0f);
- pos.y = m_fY1 + 0.5f + (uint8)(CGeneral::GetRandomNumber()) / 256.0f * (m_fY2 - m_fY1 - 1.0f);
- pos.z = m_fDoor1Z - 3.0f + (uint8)(CGeneral::GetRandomNumber()) / 256.0f * 4.0f;
-#endif
CParticle::AddParticle(PARTICLE_GARAGEPAINT_SPRAY, pos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, CVehicleModelInfo::ms_vehicleColourTable[colour1]);
}
}
@@ -436,8 +503,10 @@ void CGarage::Update()
CenterCarInGarage(FindPlayerVehicle());
}
if (bTakeMoney) {
- if (!CGarages::RespraysAreFree)
+ if (!CGarages::RespraysAreFree) {
CWorld::Players[CWorld::PlayerInFocus].m_nMoney = Max(0, CWorld::Players[CWorld::PlayerInFocus].m_nMoney - RESPRAY_PRICE);
+ CStats::AutoPaintingBudget += RESPRAY_PRICE;
+ }
CGarages::TriggerMessage("GA_2", -1, 4000, -1); // New engine and paint job. The cops won't recognize you!
}
else if (bChangedColour) {
@@ -449,10 +518,10 @@ void CGarage::Update()
m_bResprayHappened = true;
}
CWorld::CallOffChaseForArea(
- m_fX1 - DISTANCE_TO_CALL_OFF_CHASE,
- m_fY1 - DISTANCE_TO_CALL_OFF_CHASE,
- m_fX2 + DISTANCE_TO_CALL_OFF_CHASE,
- m_fY2 + DISTANCE_TO_CALL_OFF_CHASE);
+ m_fInfX - DISTANCE_TO_CALL_OFF_CHASE,
+ m_fInfY - DISTANCE_TO_CALL_OFF_CHASE,
+ m_fSupX + DISTANCE_TO_CALL_OFF_CHASE,
+ m_fSupY + DISTANCE_TO_CALL_OFF_CHASE);
break;
case GS_OPENING:
m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
@@ -477,12 +546,8 @@ void CGarage::Update()
case GARAGE_BOMBSHOP3:
switch (m_eGarageState) {
case GS_OPENED:
- if (IsStaticPlayerCarEntirelyInside() && !IsAnyOtherCarTouchingGarage(FindPlayerVehicle())) {
-#ifdef FIX_BUGS // FindPlayerVehicle() can never be NULL here because IsStaticPlayerCarEntirelyInside() is true, and there is no IsCar() check
- if (FindPlayerVehicle()->IsCar() && ((CAutomobile*)FindPlayerVehicle())->m_bombType) {
-#else
- if (!FindPlayerVehicle() || ((CAutomobile*)FindPlayerVehicle())->m_bombType) {
-#endif
+ if (IsStaticPlayerCarEntirelyInside()) {
+ if (!FindPlayerVehicle() || FindPlayerVehicle()->m_bombType) {
CGarages::TriggerMessage("GA_5", -1, 4000, -1); //"Your car is already fitted with a bomb"
m_eGarageState = GS_OPENEDCONTAINSCAR;
DMAudio.PlayFrontEndSound(SOUND_GARAGE_BOMB_ALREADY_SET, 1);
@@ -500,6 +565,8 @@ void CGarage::Update()
}
break;
case GS_CLOSING:
+ if (FindPlayerVehicle())
+ ThrowCarsNearDoorOutOfGarage(FindPlayerVehicle());
m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) {
m_eGarageState = GS_FULLYCLOSED;
@@ -507,62 +574,72 @@ void CGarage::Update()
DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
}
UpdateDoorsHeight();
+ if (m_eGarageType == GARAGE_BOMBSHOP3)
+ CStreaming::RequestModel(MI_BOMB, STREAMFLAGS_DONT_REMOVE);
break;
case GS_FULLYCLOSED:
if (CTimer::GetTimeInMilliseconds() > m_nTimeToStartAction) {
- switch (m_eGarageType) {
- case GARAGE_BOMBSHOP1: DMAudio.PlayFrontEndSound(SOUND_GARAGE_BOMB1_SET, 1); break;
- case GARAGE_BOMBSHOP2: DMAudio.PlayFrontEndSound(SOUND_GARAGE_BOMB2_SET, 1); break;
- case GARAGE_BOMBSHOP3: DMAudio.PlayFrontEndSound(SOUND_GARAGE_BOMB3_SET, 1); break;
- default: break;
- }
- m_eGarageState = GS_OPENING;
- if (!CGarages::BombsAreFree)
- CWorld::Players[CWorld::PlayerInFocus].m_nMoney = Max(0, CWorld::Players[CWorld::PlayerInFocus].m_nMoney - BOMB_PRICE);
- if (FindPlayerVehicle() && FindPlayerVehicle()->IsCar()) {
- ((CAutomobile*)(FindPlayerVehicle()))->m_bombType = CGarages::GetBombTypeForGarageType(m_eGarageType);
- ((CAutomobile*)(FindPlayerVehicle()))->m_pBombRigger = FindPlayerPed();
- if (m_eGarageType == GARAGE_BOMBSHOP3)
- CGarages::GivePlayerDetonator();
- CStats::KgsOfExplosivesUsed += KGS_OF_EXPLOSIVES_IN_BOMB;
- }
+ if (m_eGarageType != GARAGE_BOMBSHOP3 || CStreaming::HasModelLoaded(MI_BOMB)) {
+ switch (m_eGarageType) {
+ case GARAGE_BOMBSHOP1: DMAudio.PlayFrontEndSound(SOUND_GARAGE_BOMB1_SET, 1); break;
+ case GARAGE_BOMBSHOP2: DMAudio.PlayFrontEndSound(SOUND_GARAGE_BOMB2_SET, 1); break;
+ case GARAGE_BOMBSHOP3: DMAudio.PlayFrontEndSound(SOUND_GARAGE_BOMB3_SET, 1); break;
+ }
+ m_eGarageState = GS_OPENING;
+ if (!CGarages::BombsAreFree)
+ CWorld::Players[CWorld::PlayerInFocus].m_nMoney = Max(0, CWorld::Players[CWorld::PlayerInFocus].m_nMoney - BOMB_PRICE);
+ if (FindPlayerVehicle() && (FindPlayerVehicle()->IsCar() || FindPlayerVehicle()->IsBike())) {
+#if (!defined GTA_PS2 || defined FIX_BUGS)
+ FindPlayerVehicle()->m_bombType = CGarages::GetBombTypeForGarageType(m_eGarageType);
+ FindPlayerVehicle()->m_pBombRigger = FindPlayerPed();
+#else // PS2 version contained a bug: CBike was casted to CAutomobile, but due to coincidence it didn't corrupt memory
+ ((CAutomobile*)(FindPlayerVehicle()))->m_bombType = CGarages::GetBombTypeForGarageType(m_eGarageType);
+ ((CAutomobile*)(FindPlayerVehicle()))->m_pBombRigger = FindPlayerPed();
+#endif
+ if (m_eGarageType == GARAGE_BOMBSHOP3)
+ CGarages::GivePlayerDetonator();
+ CStats::KgsOfExplosivesUsed += KGS_OF_EXPLOSIVES_IN_BOMB;
+ }
#ifdef DETECT_PAD_INPUT_SWITCH
- int16 Mode = CPad::IsAffectedByController ? CPad::GetPad(0)->Mode : 0;
+ int16 Mode = CPad::IsAffectedByController ? CPad::GetPad(0)->Mode : 0;
#else
- int16 Mode = CPad::GetPad(0)->Mode;
+ int16 Mode = CPad::GetPad(0)->Mode;
#endif
- switch (m_eGarageType) {
- case GARAGE_BOMBSHOP1:
- switch (Mode) {
- case 0:
- case 1:
- case 2:
- CHud::SetHelpMessage(TheText.Get("GA_6"), false); // Arm with ~h~~k~~PED_FIREWEAPON~ button~w~. Bomb will go off when engine is started.
- break;
- case 3:
- CHud::SetHelpMessage(TheText.Get("GA_6B"), false); // Arm with ~h~~k~~PED_FIREWEAPON~ button~w~. Bomb will go off when engine is started.
+ switch (m_eGarageType) {
+ case GARAGE_BOMBSHOP1:
+ switch (Mode) {
+ case 0:
+ case 1:
+ case 2:
+ CHud::SetHelpMessage(TheText.Get("GA_6"), false); // Arm with ~h~~k~~PED_FIREWEAPON~ button~w~. Bomb will go off when engine is started.
+ break;
+ case 3:
+ CHud::SetHelpMessage(TheText.Get("GA_6B"), false); // Arm with ~h~~k~~PED_FIREWEAPON~ button~w~. Bomb will go off when engine is started.
+ break;
+ }
break;
- }
- break;
- case GARAGE_BOMBSHOP2:
- switch (Mode) {
- case 0:
- case 1:
- case 2:
- CHud::SetHelpMessage(TheText.Get("GA_7"), false); // Park it, prime it by pressing the ~h~~k~~PED_FIREWEAPON~ button~w~ and LEG IT!
+ case GARAGE_BOMBSHOP2:
+ switch (Mode) {
+ case 0:
+ case 1:
+ case 2:
+ CHud::SetHelpMessage(TheText.Get("GA_7"), false); // Park it, prime it by pressing the ~h~~k~~PED_FIREWEAPON~ button~w~ and LEG IT!
+ break;
+ case 3:
+ CHud::SetHelpMessage(TheText.Get("GA_7B"), false); // Park it, prime it by pressing the ~h~~k~~PED_FIREWEAPON~ button~w~ and LEG IT!
+ break;
+ }
break;
- case 3:
- CHud::SetHelpMessage(TheText.Get("GA_7B"), false); // Park it, prime it by pressing the ~h~~k~~PED_FIREWEAPON~ button~w~ and LEG IT!
+ case GARAGE_BOMBSHOP3:
+ CHud::SetHelpMessage(TheText.Get("GA_8"), false); // Use the detonator to activate the bomb.
break;
}
- break;
- case GARAGE_BOMBSHOP3:
- CHud::SetHelpMessage(TheText.Get("GA_8"), false); // Use the detonator to activate the bomb.
- break;
- default: break;
+ CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_GARAGE);
+ FindPlayerPed()->m_pWanted->m_bIgnoredByCops = false;
+ }
+ else {
+ CStreaming::RequestModel(MI_BOMB, STREAMFLAGS_DONT_REMOVE);
}
- CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_GARAGE);
- FindPlayerPed()->m_pWanted->m_bIgnoredByCops = false;
}
break;
case GS_OPENING:
@@ -587,14 +664,17 @@ void CGarage::Update()
switch (m_eGarageState) {
case GS_OPENED:
if (((CVector2D)FindPlayerCoors() - CVector2D(GetGarageCenterX(), GetGarageCenterY())).MagnitudeSqr() > SQR(DISTANCE_TO_CLOSE_MISSION_GARAGE)) {
- if ((CTimer::GetFrameCounter() & 0x1F) == 0 && !IsAnyOtherCarTouchingGarage(nil)) {
+ if ((CTimer::GetFrameCounter() & 0x1F) == 0
+#ifndef GTA_PS2
+ && (!m_pTarget || IsEntityTouching3D(m_pTarget))
+#endif
+ ) {
m_eGarageState = GS_CLOSING;
m_bClosingWithoutTargetCar = true;
}
}
else if (!FindPlayerVehicle() && m_pTarget && IsEntityEntirelyInside3D(m_pTarget, 0.0f) &&
- !IsAnyOtherCarTouchingGarage(m_pTarget) && IsEntityEntirelyOutside(FindPlayerPed(), 2.0f) &&
- !IsAnyOtherCarTouchingGarage(m_pTarget)) {
+ IsEntityEntirelyOutside(FindPlayerVehicle() ? (CEntity*)FindPlayerVehicle() : (CEntity*)FindPlayerPed(), 2.0f)) {
CPad::GetPad(0)->SetDisablePlayerControls(PLAYERCONTROL_GARAGE);
FindPlayerPed()->m_pWanted->m_bIgnoredByCops = true;
m_eGarageState = GS_CLOSING;
@@ -602,6 +682,8 @@ void CGarage::Update()
}
break;
case GS_CLOSING:
+ if (m_pTarget)
+ ThrowCarsNearDoorOutOfGarage(m_pTarget);
m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) {
DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
@@ -646,92 +728,10 @@ void CGarage::Update()
}
break;
case GARAGE_COLLECTSPECIFICCARS:
- switch (m_eGarageState) {
- case GS_OPENED:
- if (FindPlayerVehicle() && m_nTargetModelIndex == FindPlayerVehicle()->GetModelIndex()) {
- m_pTarget = FindPlayerVehicle();
- m_pTarget->RegisterReference((CEntity**)&m_pTarget);
- }
- if (!FindPlayerVehicle()) {
- if (m_pTarget && IsEntityEntirelyInside3D(m_pTarget, 0.0f) && !IsAnyOtherCarTouchingGarage(m_pTarget)) {
- if (IsEntityEntirelyOutside(FindPlayerPed(), 2.0f)) {
- CPad::GetPad(0)->SetDisablePlayerControls(PLAYERCONTROL_GARAGE);
- FindPlayerPed()->m_pWanted->m_bIgnoredByCops = true;
- m_eGarageState = GS_CLOSING;
- }
- }
- else if (Abs(FindPlayerCoors().x - GetGarageCenterX()) > DISTANCE_TO_CLOSE_COLLECTSPECIFICCARS_GARAGE ||
- Abs(FindPlayerCoors().y - GetGarageCenterY()) > DISTANCE_TO_CLOSE_COLLECTSPECIFICCARS_GARAGE) {
- m_eGarageState = GS_CLOSING;
- m_pTarget = nil;
- }
- }
- break;
- case GS_CLOSING:
- m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
- if (m_fDoorPos == 0.0f) {
- m_eGarageState = GS_FULLYCLOSED;
- DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
- if (m_pTarget) {
- DestroyVehicleAndDriverAndPassengers(m_pTarget);
- m_pTarget = nil;
- CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_GARAGE);
- FindPlayerPed()->m_pWanted->m_bIgnoredByCops = false;
- int16 reward;
- switch (m_nTargetModelIndex) {
- case MI_POLICE:
- reward = REWARD_FOR_FIRST_POLICE_CAR * (MAX_POLICE_CARS_TO_COLLECT - CGarages::PoliceCarsCollected++) / MAX_POLICE_CARS_TO_COLLECT;
- break;
- case MI_SECURICA:
- reward = REWARD_FOR_FIRST_BANK_VAN * (MAX_BANK_VANS_TO_COLLECT - CGarages::BankVansCollected++) / MAX_BANK_VANS_TO_COLLECT;
- break;
-#ifdef FIX_BUGS // not possible though
- default:
- reward = 0;
- break;
-#endif
- }
- if (reward > 0) {
- CWorld::Players[CWorld::PlayerInFocus].m_nMoney += reward;
- CGarages::TriggerMessage("GA_10", reward, 4000, -1); // Nice one. Here's your $~1~
- DMAudio.PlayFrontEndSound(SOUND_GARAGE_VEHICLE_ACCEPTED, 1);
- }
- else {
- CGarages::TriggerMessage("GA_11", -1, 4000, -1); // We got these wheels already. It's worthless to us!
- DMAudio.PlayFrontEndSound(SOUND_GARAGE_VEHICLE_DECLINED, 1);
- }
- }
- }
- UpdateDoorsHeight();
- break;
- case GS_FULLYCLOSED:
- if (FindPlayerVehicle() && m_nTargetModelIndex == FindPlayerVehicle()->GetModelIndex()) {
- if (CalcDistToGarageRectangleSquared(FindPlayerVehicle()->GetPosition().x, FindPlayerVehicle()->GetPosition().y) < SQR(DISTANCE_TO_ACTIVATE_GARAGE))
- m_eGarageState = GS_OPENING;
- }
- break;
- case GS_OPENING:
- if (FindPlayerVehicle() && m_nTargetModelIndex == FindPlayerVehicle()->GetModelIndex()) {
- m_pTarget = FindPlayerVehicle();
- m_pTarget->RegisterReference((CEntity**)&m_pTarget);
- }
- m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
- if (m_fDoorPos == m_fDoorHeight) {
- m_eGarageState = GS_OPENED;
- DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f);
- }
- UpdateDoorsHeight();
- break;
- //case GS_OPENEDCONTAINSCAR:
- //case GS_CLOSEDCONTAINSCAR:
- //case GS_AFTERDROPOFF:
- default:
- break;
- }
- break;
case GARAGE_COLLECTCARS_1:
case GARAGE_COLLECTCARS_2:
case GARAGE_COLLECTCARS_3:
+ case GARAGE_COLLECTCARS_4:
switch (m_eGarageState) {
case GS_OPENED:
if (FindPlayerVehicle() && DoesCraigNeedThisCar(FindPlayerVehicle()->GetModelIndex())) {
@@ -764,6 +764,8 @@ void CGarage::Update()
}
break;
case GS_CLOSING:
+ if (m_pTarget)
+ ThrowCarsNearDoorOutOfGarage(m_pTarget);
m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) {
m_eGarageState = GS_FULLYCLOSED;
@@ -851,75 +853,6 @@ void CGarage::Update()
}
break;
case GARAGE_CRUSHER:
- switch (m_eGarageState) {
- case GS_OPENED:
- {
- int i = CPools::GetVehiclePool()->GetSize() * (CTimer::GetFrameCounter() % CRUSHER_VEHICLE_TEST_SPAN) / CRUSHER_VEHICLE_TEST_SPAN;
- int end = CPools::GetVehiclePool()->GetSize() * (CTimer::GetFrameCounter() % CRUSHER_VEHICLE_TEST_SPAN + 1) / CRUSHER_VEHICLE_TEST_SPAN;
- for (; i < end; i++) {
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
- if (!pVehicle)
- continue;
- if (pVehicle->IsCar() && IsEntityEntirelyInside3D(pVehicle, 0.0f)) {
- m_eGarageState = GS_CLOSING;
- m_pTarget = pVehicle;
- m_pTarget->RegisterReference((CEntity**)&m_pTarget);
- }
- }
- break;
- }
- case GS_CLOSING:
- if (m_pTarget) {
- m_fDoorPos = Max(0.0f, m_fDoorPos - CRUSHER_CRANE_SPEED * CTimer::GetTimeStep());
- if (m_fDoorPos < TWOPI / 5) {
- m_pTarget->bUsesCollision = false;
- m_pTarget->bAffectedByGravity = false;
- m_pTarget->SetMoveSpeed(0.0f, 0.0f, 0.0f);
- }
- else {
- m_pTarget->SetMoveSpeed(m_pTarget->GetMoveSpeed() * Pow(0.8f, CTimer::GetTimeStep()));
- }
- if (m_fDoorPos == 0.0f) {
- CGarages::CrushedCarId = CPools::GetVehiclePool()->GetIndex(m_pTarget);
- float reward = Min(CRUSHER_MAX_REWARD, CRUSHER_MIN_REWARD + m_pTarget->pHandling->nMonetaryValue * m_pTarget->m_fHealth * CRUSHER_REWARD_COEFFICIENT);
- CWorld::Players[CWorld::PlayerInFocus].m_nMoney += reward;
- DestroyVehicleAndDriverAndPassengers(m_pTarget);
- ++CStats::CarsCrushed;
- m_pTarget = nil;
- m_eGarageState = GS_AFTERDROPOFF;
- m_nTimeToStartAction = CTimer::GetTimeInMilliseconds() + TIME_TO_CRUSH_CAR;
- DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
- }
- }
- else
- m_eGarageState = GS_OPENING;
- UpdateCrusherAngle();
- break;
- case GS_AFTERDROPOFF:
- if (CTimer::GetTimeInMilliseconds() <= m_nTimeToStartAction) {
- UpdateCrusherShake((myrand() & 0xFF - 128) * 0.0002f, (myrand() & 0xFF - 128) * 0.0002f);
- }
- else {
- UpdateCrusherShake(0.0f, 0.0f);
- m_eGarageState = GS_OPENING;
- }
- break;
- case GS_OPENING:
- m_fDoorPos = Min(HALFPI, m_fDoorPos + CTimer::GetTimeStep() * CRUSHER_CRANE_SPEED);
- if (m_fDoorPos == HALFPI) {
- m_eGarageState = GS_OPENED;
- DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f);
- }
- UpdateCrusherAngle();
- break;
- //case GS_FULLYCLOSED:
- //case GS_CLOSEDCONTAINSCAR:
- //case GS_OPENEDCONTAINSCAR:
- default:
- break;
- }
- if (!FindPlayerVehicle() && (CTimer::GetFrameCounter() & 0x1F) == 0x17 && IsEntityEntirelyInside(FindPlayerPed()))
- FindPlayerPed()->InflictDamage(nil, WEAPONTYPE_RAMMEDBYCAR, 300.0f, PEDPIECE_TORSO, 0);
break;
case GARAGE_MISSION_KEEPCAR:
case GARAGE_MISSION_KEEPCAR_REMAINCLOSED:
@@ -938,6 +871,8 @@ void CGarage::Update()
}
break;
case GS_CLOSING:
+ if (m_pTarget)
+ ThrowCarsNearDoorOutOfGarage(m_pTarget);
m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) {
DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
@@ -1033,6 +968,15 @@ void CGarage::Update()
case GARAGE_HIDEOUT_ONE:
case GARAGE_HIDEOUT_TWO:
case GARAGE_HIDEOUT_THREE:
+ case GARAGE_HIDEOUT_FOUR:
+ case GARAGE_HIDEOUT_FIVE:
+ case GARAGE_HIDEOUT_SIX:
+ case GARAGE_HIDEOUT_SEVEN:
+ case GARAGE_HIDEOUT_EIGHT:
+ case GARAGE_HIDEOUT_NINE:
+ case GARAGE_HIDEOUT_TEN:
+ case GARAGE_HIDEOUT_ELEVEN:
+ case GARAGE_HIDEOUT_TWELVE:
switch (m_eGarageState) {
case GS_OPENED:
{
@@ -1045,7 +989,7 @@ void CGarage::Update()
m_eGarageState = GS_CLOSING;
else if (FindPlayerVehicle() &&
CountCarsWithCenterPointWithinGarage(FindPlayerVehicle()) >=
- CGarages::FindMaxNumStoredCarsForGarage(m_eGarageType)) {
+ FindMaxNumStoredCarsForGarage()) {
m_eGarageState = GS_CLOSING;
}
else if (distance > SQR(DISTANCE_TO_FORCE_CLOSE_HIDEOUT_GARAGE)) {
@@ -1061,12 +1005,7 @@ void CGarage::Update()
else if (m_fDoorPos == 0.0f) {
DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
m_eGarageState = GS_FULLYCLOSED;
- switch (m_eGarageType) {
- case GARAGE_HIDEOUT_ONE: StoreAndRemoveCarsForThisHideout(CGarages::aCarsInSafeHouse1, MAX_STORED_CARS_IN_INDUSTRIAL); break;
- case GARAGE_HIDEOUT_TWO: StoreAndRemoveCarsForThisHideout(CGarages::aCarsInSafeHouse2, MAX_STORED_CARS_IN_COMMERCIAL); break;
- case GARAGE_HIDEOUT_THREE: StoreAndRemoveCarsForThisHideout(CGarages::aCarsInSafeHouse3, MAX_STORED_CARS_IN_SUBURBAN); break;
- default: break;
- }
+ StoreAndRemoveCarsForThisHideout(CGarages::aCarsInSafeHouses[CGarages::FindSafeHouseIndexForGarageType(m_eGarageType)], NUM_GARAGE_STORED_CARS);
}
UpdateDoorsHeight();
break;
@@ -1075,30 +1014,19 @@ void CGarage::Update()
float distance = CalcDistToGarageRectangleSquared(FindPlayerCoors().x, FindPlayerCoors().y);
if (distance < SQR(DISTANCE_TO_OPEN_HIDEOUT_GARAGE_ON_FOOT) ||
distance < SQR(DISTANCE_TO_OPEN_HIDEOUT_GARAGE_IN_CAR) && FindPlayerVehicle()) {
- if (FindPlayerVehicle() && CGarages::CountCarsInHideoutGarage(m_eGarageType) >= CGarages::FindMaxNumStoredCarsForGarage(m_eGarageType)) {
+ if (FindPlayerVehicle() && CGarages::CountCarsInHideoutGarage(m_eGarageType) >= FindMaxNumStoredCarsForGarage()) {
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) {
- CHud::SetHelpMessage(TheText.Get("GA_21"), false); // You cannot store any more cars in this garage.
- CGarages::LastTimeHelpMessage = CTimer::GetTimeInMilliseconds();
+ 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();
+ }
}
}
}
- else {
-#ifdef FIX_BUGS
- bool bCreatedAllCars = false;
-#else
- bool bCreatedAllCars;
-#endif
- switch (m_eGarageType) {
- case GARAGE_HIDEOUT_ONE: bCreatedAllCars = RestoreCarsForThisHideout(CGarages::aCarsInSafeHouse1); break;
- case GARAGE_HIDEOUT_TWO: bCreatedAllCars = RestoreCarsForThisHideout(CGarages::aCarsInSafeHouse2); break;
- case GARAGE_HIDEOUT_THREE: bCreatedAllCars = RestoreCarsForThisHideout(CGarages::aCarsInSafeHouse3); break;
- default: break;
- }
- if (bCreatedAllCars)
- m_eGarageState = GS_OPENING;
- }
+ else if (RestoreCarsForThisHideout(CGarages::aCarsInSafeHouses[CGarages::FindSafeHouseIndexForGarageType(m_eGarageType)]))
+ m_eGarageState = GS_OPENING;
}
break;
}
@@ -1128,6 +1056,8 @@ void CGarage::Update()
}
break;
case GS_CLOSING:
+ if (m_pTarget)
+ ThrowCarsNearDoorOutOfGarage(m_pTarget);
m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) {
m_eGarageState = GS_FULLYCLOSED;
@@ -1158,8 +1088,42 @@ void CGarage::Update()
break;
}
break;
- //case GARAGE_COLLECTORSITEMS:
- //case GARAGE_60SECONDS:
+ //case GARAGE_COLLECTORSITEMS:
+ //case GARAGE_60SECONDS:
+ case GARAGE_FOR_SCRIPT_TO_OPEN_FOR_CAR:
+ switch (m_eGarageState) {
+ case GS_OPENED:
+ if (m_pTarget && IsEntityEntirelyInside3D(m_pTarget, 0.0f) && !IsAnyCarBlockingDoor() && IsPlayerOutsideGarage()) {
+ CPad::GetPad(0)->SetDisablePlayerControls(PLAYERCONTROL_GARAGE);
+ m_eGarageState = GS_CLOSING;
+ m_bClosingWithoutTargetCar = false;
+ }
+ break;
+ case GS_CLOSING:
+ m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
+ if (m_fDoorPos == 0.0f) {
+ m_eGarageState = GS_FULLYCLOSED;
+ DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
+ CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_GARAGE);
+ }
+ UpdateDoorsHeight();
+ break;
+ case GS_FULLYCLOSED:
+ break;
+ case GS_OPENING:
+ m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
+ if (m_fDoorPos == m_fDoorHeight) {
+ m_eGarageState = GS_OPENED;
+ DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f);
+ }
+ UpdateDoorsHeight();
+ break;
+ //case GS_OPENEDCONTAINSCAR:
+ //case GS_CLOSEDCONTAINSCAR:
+ //case GS_AFTERDROPOFF:
+ default:
+ break;
+ }
default:
break;
}
@@ -1169,15 +1133,15 @@ bool CGarage::IsStaticPlayerCarEntirelyInside()
{
if (!FindPlayerVehicle())
return false;
- if (!FindPlayerVehicle()->IsCar())
+ if (!FindPlayerVehicle()->IsCar() && !FindPlayerVehicle()->IsBike())
return false;
if (FindPlayerPed()->GetPedState() != PED_DRIVING)
return false;
if (FindPlayerPed()->m_objective == OBJECTIVE_LEAVE_CAR)
return false;
CVehicle* pVehicle = FindPlayerVehicle();
- if (pVehicle->GetPosition().x < m_fX1 || pVehicle->GetPosition().x > m_fX2 ||
- pVehicle->GetPosition().y < m_fY1 || pVehicle->GetPosition().y > m_fY2)
+ if (pVehicle->GetPosition().x < m_fInfX || pVehicle->GetPosition().x > m_fSupX ||
+ pVehicle->GetPosition().y < m_fInfY || pVehicle->GetPosition().y > m_fSupY)
return false;
if (Abs(pVehicle->GetSpeed().x) > 0.01f ||
Abs(pVehicle->GetSpeed().y) > 0.01f ||
@@ -1188,35 +1152,58 @@ bool CGarage::IsStaticPlayerCarEntirelyInside()
return IsEntityEntirelyInside3D(pVehicle, 0.0f);
}
-bool CGarage::IsEntityEntirelyInside(CEntity * pEntity)
+bool CGarage::IsPointInsideGarage(CVector pos)
{
- if (pEntity->GetPosition().x < m_fX1 || pEntity->GetPosition().x > m_fX2 ||
- pEntity->GetPosition().y < m_fY1 || pEntity->GetPosition().y > m_fY2)
+ // is it IsPointInsideGarage(pos, 0.0f)?
+ if (pos.z < m_fInfZ)
+ return false;
+ if (pos.z > m_fSupZ)
+ return false;
+ CVector2D vecToTarget((CVector2D)pos - m_vecCorner1);
+ float dp = DotProduct2D(m_vDir1, vecToTarget);
+ if (dp < 0.0f)
+ return false;
+ if (m_fDir1Len < dp)
+ return false;
+ dp = DotProduct2D(m_vDir2, vecToTarget);
+ if (dp < 0.0f)
+ return false;
+ if (m_fDir2Len < dp)
return false;
- CColModel* pColModel = pEntity->GetColModel();
- for (int i = 0; i < pColModel->numSpheres; i++) {
- CVector pos = pEntity->GetMatrix() * pColModel->spheres[i].center;
- float radius = pColModel->spheres[i].radius;
- if (pos.x - radius < m_fX1 || pos.x + radius > m_fX2 ||
- pos.y - radius < m_fY1 || pos.y + radius > m_fY2)
- return false;
- }
return true;
}
-bool CGarage::IsEntityEntirelyInside3D(CEntity * pEntity, float fMargin)
+bool CGarage::IsPointInsideGarage(CVector pos, float m_fMargin)
{
- if (pEntity->GetPosition().x < m_fX1 - fMargin || pEntity->GetPosition().x > m_fX2 + fMargin ||
- pEntity->GetPosition().y < m_fY1 - fMargin || pEntity->GetPosition().y > m_fY2 + fMargin ||
- pEntity->GetPosition().z < m_fZ1 - fMargin || pEntity->GetPosition().z > m_fZ2 + fMargin)
+ if (pos.z < m_fInfZ - m_fMargin)
+ return false;
+ if (pos.z > m_fSupZ + m_fMargin)
+ return false;
+ CVector2D vecToTarget((CVector2D)pos - m_vecCorner1);
+ float dp = DotProduct2D(m_vDir1, vecToTarget);
+ if (dp < -m_fMargin)
+ return false;
+ if (m_fDir1Len + m_fMargin < dp)
+ return false;
+ dp = DotProduct2D(m_vDir2, vecToTarget);
+ if (dp < -m_fMargin)
+ return false;
+ if (m_fDir2Len + m_fMargin < dp)
+ return false;
+ return true;
+}
+
+bool CGarage::IsEntityEntirelyInside3D(CEntity* pEntity, float fMargin)
+{
+ if (pEntity->GetPosition().x < m_fInfX - fMargin || pEntity->GetPosition().x > m_fSupX + fMargin ||
+ pEntity->GetPosition().y < m_fInfY - fMargin || pEntity->GetPosition().y > m_fSupY + fMargin ||
+ pEntity->GetPosition().z < m_fInfZ - fMargin || pEntity->GetPosition().z > m_fSupZ + fMargin)
return false;
CColModel* pColModel = pEntity->GetColModel();
for (int i = 0; i < pColModel->numSpheres; i++) {
CVector pos = pEntity->GetMatrix() * pColModel->spheres[i].center;
float radius = pColModel->spheres[i].radius;
- if (pos.x + radius < m_fX1 - fMargin || pos.x - radius > m_fX2 + fMargin ||
- pos.y + radius < m_fY1 - fMargin || pos.y - radius > m_fY2 + fMargin ||
- pos.z + radius < m_fZ1 - fMargin || pos.z - radius > m_fZ2 + fMargin)
+ if (!IsPointInsideGarage(pos, fMargin - radius))
return false;
}
return true;
@@ -1224,15 +1211,14 @@ bool CGarage::IsEntityEntirelyInside3D(CEntity * pEntity, float fMargin)
bool CGarage::IsEntityEntirelyOutside(CEntity * pEntity, float fMargin)
{
- if (pEntity->GetPosition().x > m_fX1 - fMargin && pEntity->GetPosition().x < m_fX2 + fMargin &&
- pEntity->GetPosition().y > m_fY1 - fMargin && pEntity->GetPosition().y < m_fY2 + fMargin)
+ if (pEntity->GetPosition().x > m_fInfX - fMargin && pEntity->GetPosition().x < m_fSupX + fMargin &&
+ pEntity->GetPosition().y > m_fInfY - fMargin && pEntity->GetPosition().y < m_fSupY + fMargin)
return false;
CColModel* pColModel = pEntity->GetColModel();
for (int i = 0; i < pColModel->numSpheres; i++) {
CVector pos = pEntity->GetMatrix() * pColModel->spheres[i].center;
float radius = pColModel->spheres[i].radius;
- if (pos.x + radius > m_fX1 - fMargin && pos.x - radius < m_fX2 + fMargin &&
- pos.y + radius > m_fY1 - fMargin && pos.y - radius < m_fY2 + fMargin)
+ if (IsPointInsideGarage(pos, fMargin + radius))
return false;
}
return true;
@@ -1241,8 +1227,15 @@ bool CGarage::IsEntityEntirelyOutside(CEntity * pEntity, float fMargin)
bool CGarage::IsGarageEmpty()
{
int16 num;
- CWorld::FindObjectsIntersectingCube(CVector(m_fX1, m_fY1, m_fZ1), CVector(m_fX2, m_fY2, m_fZ2), &num, 2, nil, false, true, true, false, false);
- return num == 0;
+ CEntity* pEntities[16];
+ CWorld::FindObjectsIntersectingCube(CVector(m_fInfX, m_fInfY, m_fInfZ), CVector(m_fSupX, m_fSupY, m_fSupZ), &num, 16, pEntities, false, true, true, false, false);
+ if (num <= 0)
+ return true;
+ for (int i = 0; i < 16; i++) {
+ if (IsEntityTouching3D(pEntities[i]))
+ return false;
+ }
+ return true;
}
bool CGarage::IsPlayerOutsideGarage()
@@ -1252,20 +1245,18 @@ bool CGarage::IsPlayerOutsideGarage()
return IsEntityEntirelyOutside(FindPlayerPed(), 0.0f);
}
-bool CGarage::IsEntityTouching3D(CEntity * pEntity)
+bool CGarage::IsEntityTouching3D(CEntity* pEntity)
{
float radius = pEntity->GetBoundRadius();
- if (m_fX1 - radius > pEntity->GetPosition().x || m_fX2 + radius < pEntity->GetPosition().x ||
- m_fY1 - radius > pEntity->GetPosition().y || m_fY2 + radius < pEntity->GetPosition().y ||
- m_fZ1 - radius > pEntity->GetPosition().z || m_fZ2 + radius < pEntity->GetPosition().z)
+ if (m_fInfX - radius > pEntity->GetPosition().x || m_fSupX + radius < pEntity->GetPosition().x ||
+ m_fInfY - radius > pEntity->GetPosition().y || m_fSupY + radius < pEntity->GetPosition().y ||
+ m_fInfZ - radius > pEntity->GetPosition().z || m_fSupZ + radius < pEntity->GetPosition().z)
return false;
CColModel* pColModel = pEntity->GetColModel();
for (int i = 0; i < pColModel->numSpheres; i++) {
CVector pos = pEntity->GetMatrix() * pColModel->spheres[i].center;
radius = pColModel->spheres[i].radius;
- if (pos.x + radius > m_fX1 && pos.x - radius < m_fX2 &&
- pos.y + radius > m_fY1 && pos.y - radius < m_fY2 &&
- pos.z + radius > m_fZ1 && pos.z - radius < m_fZ2)
+ if (IsPointInsideGarage(pos, radius))
return true;
}
return false;
@@ -1277,9 +1268,7 @@ bool CGarage::EntityHasASphereWayOutsideGarage(CEntity * pEntity, float fMargin)
for (int i = 0; i < pColModel->numSpheres; i++) {
CVector pos = pEntity->GetMatrix() * pColModel->spheres[i].center;
float radius = pColModel->spheres[i].radius;
- if (pos.x + radius + fMargin < m_fX1 || pos.x - radius - fMargin > m_fX2 ||
- pos.y + radius + fMargin < m_fY1 || pos.y - radius - fMargin > m_fY2 ||
- pos.z + radius + fMargin < m_fZ1 || pos.z - radius - fMargin > m_fZ2)
+ if (!IsPointInsideGarage(pos, fMargin + radius))
return true;
}
return false;
@@ -1290,7 +1279,7 @@ bool CGarage::IsAnyOtherCarTouchingGarage(CVehicle * pException)
uint32 i = CPools::GetVehiclePool()->GetSize();
while (i--) {
CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
- if (!pVehicle || pVehicle == pException)
+ if (!pVehicle || pVehicle == pException || pVehicle->GetStatus() == STATUS_WRECKED)
continue;
if (!IsEntityTouching3D(pVehicle))
continue;
@@ -1298,15 +1287,35 @@ bool CGarage::IsAnyOtherCarTouchingGarage(CVehicle * pException)
for (int i = 0; i < pColModel->numSpheres; i++) {
CVector pos = pVehicle->GetMatrix() * pColModel->spheres[i].center;
float radius = pColModel->spheres[i].radius;
- if (pos.x + radius > m_fX1 && pos.x - radius < m_fX2 &&
- pos.y + radius > m_fY1 && pos.y - radius < m_fY2 &&
- pos.z + radius > m_fZ1 && pos.z - radius < m_fZ2)
+ if (IsPointInsideGarage(pos, radius))
return true;
}
}
return false;
}
+void CGarage::ThrowCarsNearDoorOutOfGarage(CVehicle* pException)
+{
+ uint32 i = CPools::GetVehiclePool()->GetSize();
+ while (i--) {
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
+ if (!pVehicle || pVehicle == pException)
+ continue;
+ if (!IsEntityTouching3D(pVehicle))
+ continue;
+ CColModel* pColModel = pVehicle->GetColModel();
+ for (int i = 0; i < pColModel->numSpheres; i++) {
+ CVector pos = pVehicle->GetMatrix() * pColModel->spheres[i].center;
+ float radius = pColModel->spheres[i].radius;
+ if (!IsPointInsideGarage(pos, 0.0f)) {
+ CVector vecDirectionAway(pVehicle->GetPosition().x - GetGarageCenterX(), pVehicle->GetPosition().y - GetGarageCenterY(), 0.0f);
+ vecDirectionAway.Normalise();
+ pVehicle->AddToMoveSpeed(vecDirectionAway * CTimer::GetTimeStepInSeconds());
+ }
+ }
+ }
+}
+
bool CGarage::IsAnyOtherPedTouchingGarage(CPed * pException)
{
uint32 i = CPools::GetPedPool()->GetSize();
@@ -1320,9 +1329,7 @@ bool CGarage::IsAnyOtherPedTouchingGarage(CPed * pException)
for (int i = 0; i < pColModel->numSpheres; i++) {
CVector pos = pPed->GetMatrix() * pColModel->spheres[i].center;
float radius = pColModel->spheres[i].radius;
- if (pos.x + radius > m_fX1 && pos.x - radius < m_fX2 &&
- pos.y + radius > m_fY1 && pos.y - radius < m_fY2 &&
- pos.z + radius > m_fZ1 && pos.z - radius < m_fZ2)
+ if (IsPointInsideGarage(pos, radius))
return true;
}
}
@@ -1342,9 +1349,7 @@ bool CGarage::IsAnyCarBlockingDoor()
for (int i = 0; i < pColModel->numSpheres; i++) {
CVector pos = pVehicle->GetMatrix() * pColModel->spheres[i].center;
float radius = pColModel->spheres[i].radius;
- if (pos.x + radius < m_fX1 || pos.x - radius > m_fX2 ||
- pos.y + radius < m_fY1 || pos.y - radius > m_fY2 ||
- pos.z + radius < m_fZ1 || pos.z - radius > m_fZ2)
+ if (!IsPointInsideGarage(pos, radius))
return true;
}
}
@@ -1359,9 +1364,7 @@ int32 CGarage::CountCarsWithCenterPointWithinGarage(CEntity * pException)
CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
if (!pVehicle || pVehicle == pException)
continue;
- if (pVehicle->GetPosition().x > m_fX1 && pVehicle->GetPosition().x < m_fX2 &&
- pVehicle->GetPosition().y > m_fY1 && pVehicle->GetPosition().y < m_fY2 &&
- pVehicle->GetPosition().z > m_fZ1 && pVehicle->GetPosition().z < m_fZ2)
+ if (IsPointInsideGarage(pVehicle->GetPosition()))
total++;
}
return total;
@@ -1376,14 +1379,12 @@ void CGarage::RemoveCarsBlockingDoorNotInside()
continue;
if (!IsEntityTouching3D(pVehicle))
continue;
- if (pVehicle->GetPosition().x < m_fX1 || pVehicle->GetPosition().x > m_fX2 ||
- pVehicle->GetPosition().y < m_fY1 || pVehicle->GetPosition().y > m_fY2 ||
- pVehicle->GetPosition().z < m_fZ1 || pVehicle->GetPosition().z > m_fZ2) {
+ if (!IsPointInsideGarage(pVehicle->GetPosition())) {
if (!pVehicle->bIsLocked && pVehicle->CanBeDeleted()) {
CWorld::Remove(pVehicle);
delete pVehicle;
#ifndef FIX_BUGS
- return; // makes no sense
+ return;
#endif
}
}
@@ -1393,11 +1394,8 @@ void CGarage::RemoveCarsBlockingDoorNotInside()
void CGarages::PrintMessages()
{
if (CTimer::GetTimeInMilliseconds() > MessageStartTime && CTimer::GetTimeInMilliseconds() < MessageEndTime) {
-#ifdef FIX_BUGS
+ CFont::DrawFonts();
CFont::SetScale(SCREEN_SCALE_X(1.2f), SCREEN_SCALE_Y(1.5f));
-#else
- CFont::SetScale(1.2f, 1.5f);
-#endif
CFont::SetPropOn();
CFont::SetJustifyOff();
CFont::SetBackgroundOff();
@@ -1407,52 +1405,22 @@ void CGarages::PrintMessages()
CFont::SetCentreSize(SCREEN_WIDTH - 50);
#endif
CFont::SetCentreOn();
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
- CFont::SetColor(CRGBA(0, 0, 0, 255));
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
+ CFont::SetColor(CRGBA(27, 89, 130, 255));
+ CFont::SetDropShadowPosition(2);
+ CFont::SetDropColor(CRGBA(0, 0, 0, 255));
-#if defined(PS2_HUD) || defined (FIX_BUGS)
- float y_offset = SCREEN_HEIGHT / 3; // THIS is PS2 calculation
-#else
- float y_offset = SCREEN_HEIGHT / 2 - SCREEN_SCALE_Y(84.0f); // This is PC and results in text being written over some HUD elements
-#endif
+ float y_offset = SCREEN_SCALE_Y(140.0f);
if (MessageNumberInString2 >= 0) {
CMessages::InsertNumberInString(TheText.Get(MessageIDString), MessageNumberInString, MessageNumberInString2, -1, -1, -1, -1, gUString);
-#ifdef FIX_BUGS
- CFont::PrintString(SCREEN_WIDTH / 2 + SCREEN_SCALE_X(2.0f), y_offset - SCREEN_SCALE_Y(40.0f) + SCREEN_SCALE_Y(2.0f), gUString);
-#else
- CFont::PrintString(SCREEN_WIDTH / 2 + 2.0f, y_offset - 40.0f + 2.0f, gUString);
-#endif
- CFont::SetColor(CRGBA(89, 115, 150, 255));
-#ifdef FIX_BUGS
- CFont::PrintString(SCREEN_WIDTH / 2, y_offset - SCREEN_SCALE_Y(40.0f), gUString);
-#else
- CFont::PrintString(SCREEN_WIDTH / 2, y_offset - 40.0f, gUString);
-#endif
+ CFont::PrintString(SCREEN_WIDTH / 2, y_offset - SCREEN_SCALE_Y(30.0f), gUString);
}
else if (MessageNumberInString >= 0) {
CMessages::InsertNumberInString(TheText.Get(MessageIDString), MessageNumberInString, -1, -1, -1, -1, -1, gUString);
-#ifdef FIX_BUGS
- CFont::PrintString(SCREEN_WIDTH / 2 + SCREEN_SCALE_X(2.0f), y_offset - SCREEN_SCALE_Y(40.0f) + SCREEN_SCALE_Y(2.0f), gUString);
-#else
- CFont::PrintString(SCREEN_WIDTH / 2 + 2.0f, y_offset - 40.0f + 2.0f, gUString);
-#endif
-
- CFont::SetColor(CRGBA(89, 115, 150, 255));
-
-#ifdef FIX_BUGS
- CFont::PrintString(SCREEN_WIDTH / 2, y_offset - SCREEN_SCALE_Y(40.0f), gUString);
-#else
- CFont::PrintString(SCREEN_WIDTH / 2, y_offset - 40.0f, gUString);
-#endif
+ CFont::PrintString(SCREEN_WIDTH / 2, y_offset - SCREEN_SCALE_Y(30.0f), gUString);
}
else {
-#ifdef FIX_BUGS
- CFont::PrintString(SCREEN_WIDTH / 2 - SCREEN_SCALE_X(2.0f), y_offset - SCREEN_SCALE_Y(2.0f), TheText.Get(MessageIDString));
-#else
- CFont::PrintString(SCREEN_WIDTH / 2 - 2.0f, y_offset - 2.0f, TheText.Get(MessageIDString));
-#endif
- CFont::SetColor(CRGBA(89, 115, 150, 255));
CFont::PrintString(SCREEN_WIDTH / 2, y_offset, TheText.Get(MessageIDString));
}
}
@@ -1470,6 +1438,9 @@ bool CGarages::IsCarSprayable(CVehicle * pVehicle)
case MI_BARRACKS:
case MI_DODO:
case MI_COACH:
+#ifndef GTA_PS2
+ case MI_FBIRANCH:
+#endif
return false;
default:
break;
@@ -1482,15 +1453,27 @@ void CGarage::UpdateDoorsHeight()
RefreshDoorPointers(false);
if (m_pDoor1) {
m_pDoor1->GetMatrix().GetPosition().z = m_fDoorPos + m_fDoor1Z;
- if (m_bRotatedDoor)
+ if (m_bRotatedDoor) {
+ CVector pos;
+ pos.x = m_fDoor1X + m_fDoorPos * m_pDoor1->GetForward().y * 5.0f / 6.0f;
+ pos.y = m_fDoor1Y - m_fDoorPos * m_pDoor1->GetForward().x * 5.0f / 6.0f;
+ pos.z = m_pDoor1->GetPosition().z;
+ m_pDoor1->SetPosition(pos);
BuildRotatedDoorMatrix(m_pDoor1, m_fDoorPos / m_fDoorHeight);
+ }
m_pDoor1->GetMatrix().UpdateRW();
m_pDoor1->UpdateRwFrame();
}
if (m_pDoor2) {
m_pDoor2->GetMatrix().GetPosition().z = m_fDoorPos + m_fDoor2Z;
- if (m_bRotatedDoor)
+ if (m_bRotatedDoor) {
+ CVector pos;
+ pos.x = m_fDoor2X + m_fDoorPos * m_pDoor2->GetForward().y * 5.0f / 6.0f;
+ pos.y = m_fDoor2Y - m_fDoorPos * m_pDoor2->GetForward().x * 5.0f / 6.0f;
+ pos.z = m_pDoor2->GetPosition().z;
+ m_pDoor2->SetPosition(pos);
BuildRotatedDoorMatrix(m_pDoor2, m_fDoorPos / m_fDoorHeight);
+ }
m_pDoor2->GetMatrix().UpdateRW();
m_pDoor2->UpdateRwFrame();
}
@@ -1600,11 +1583,12 @@ void CGarages::TriggerMessage(const char* text, int16 num1, uint16 time, int16 n
MessageNumberInString2 = num2;
}
-void CGarages::SetTargetCarForMissonGarage(int16 garage, CVehicle * pVehicle)
+void CGarages::SetTargetCarForMissonGarage(int16 garage, CVehicle* pVehicle)
{
assert(garage >= 0 && garage < NUM_GARAGES);
if (pVehicle) {
aGarages[garage].m_pTarget = pVehicle;
+ aGarages[garage].m_pTarget->RegisterReference((CEntity**)&aGarages[garage].m_pTarget);
if (aGarages[garage].m_eGarageState == GS_CLOSEDCONTAINSCAR)
aGarages[garage].m_eGarageState = GS_FULLYCLOSED;
}
@@ -1656,11 +1640,9 @@ bool CGarages::HasThisCarBeenCollected(int16 garage, uint8 id)
bool CGarage::DoesCraigNeedThisCar(int32 mi)
{
- if (mi == MI_CORPSE)
- mi = MI_MANANA;
int ct = CGarages::GetCarsCollectedIndexForGarageType(m_eGarageType);
for (int i = 0; i < TOTAL_COLLECTCARS_CARS; i++) {
- if (mi == gaCarsToCollectInCraigsGarages[ct][i])
+ if (mi == gaCarsToCollectInCraigsGarages[ct][i] || (gaCarsToCollectInCraigsGarages[ct][i] == MI_CHEETAH && mi == MI_VICECHEE))
return (CGarages::CarTypesCollected[ct] & BIT(i)) == 0;
}
return false;
@@ -1668,11 +1650,9 @@ bool CGarage::DoesCraigNeedThisCar(int32 mi)
bool CGarage::HasCraigCollectedThisCar(int32 mi)
{
- if (mi == MI_CORPSE)
- mi = MI_MANANA;
int ct = CGarages::GetCarsCollectedIndexForGarageType(m_eGarageType);
for (int i = 0; i < TOTAL_COLLECTCARS_CARS; i++) {
- if (mi == gaCarsToCollectInCraigsGarages[ct][i])
+ if (mi == gaCarsToCollectInCraigsGarages[ct][i] || (gaCarsToCollectInCraigsGarages[ct][i] == MI_CHEETAH && mi == MI_VICECHEE))
return CGarages::CarTypesCollected[ct] & BIT(i);
}
return false;
@@ -1680,12 +1660,10 @@ bool CGarage::HasCraigCollectedThisCar(int32 mi)
bool CGarage::MarkThisCarAsCollectedForCraig(int32 mi)
{
- if (mi == MI_CORPSE)
- mi = MI_MANANA;
int ct = CGarages::GetCarsCollectedIndexForGarageType(m_eGarageType);
int index;
for (index = 0; index < TOTAL_COLLECTCARS_CARS; index++) {
- if (mi == gaCarsToCollectInCraigsGarages[ct][index])
+ if (mi == gaCarsToCollectInCraigsGarages[ct][index] || (gaCarsToCollectInCraigsGarages[ct][index] == MI_CHEETAH && mi == MI_VICECHEE))
break;
}
if (index >= TOTAL_COLLECTCARS_CARS)
@@ -1718,16 +1696,16 @@ void CGarage::CloseThisGarage()
float CGarage::CalcDistToGarageRectangleSquared(float X, float Y)
{
float distX, distY;
- if (X < m_fX1)
- distX = m_fX1 - X;
- else if (X > m_fX2)
- distX = X - m_fX2;
+ if (X < m_fInfX)
+ distX = m_fInfX - X;
+ else if (X > m_fSupX)
+ distX = X - m_fSupX;
else
distX = 0.0f;
- if (Y < m_fY1)
- distY = m_fY1 - Y;
- else if (Y > m_fY2)
- distY = Y - m_fY2;
+ if (Y < m_fInfY)
+ distY = m_fInfY - Y;
+ else if (Y > m_fSupY)
+ distY = Y - m_fSupY;
else
distY = 0.0f;
return SQR(distX) + SQR(distY);
@@ -1748,10 +1726,10 @@ void CGarage::FindDoorsEntities()
{
m_pDoor1 = nil;
m_pDoor2 = nil;
- int xstart = Max(0, CWorld::GetSectorIndexX(m_fX1));
- int xend = Min(NUMSECTORS_X - 1, CWorld::GetSectorIndexX(m_fX2));
- int ystart = Max(0, CWorld::GetSectorIndexY(m_fY1));
- int yend = Min(NUMSECTORS_Y - 1, CWorld::GetSectorIndexY(m_fY2));
+ int xstart = Max(0, CWorld::GetSectorIndexX(GetGarageCenterX() - 100.0f));
+ int xend = Min(NUMSECTORS_X - 1, CWorld::GetSectorIndexX(GetGarageCenterX() + 100.0f));
+ int ystart = Max(0, CWorld::GetSectorIndexY(GetGarageCenterY() - 100.0f));
+ int yend = Min(NUMSECTORS_Y - 1, CWorld::GetSectorIndexY(GetGarageCenterY() + 100.0f));
assert(xstart <= xend);
assert(ystart <= yend);
@@ -1766,20 +1744,22 @@ void CGarage::FindDoorsEntities()
FindDoorsEntitiesSectorList(s->m_lists[ENTITYLIST_DUMMIES_OVERLAP], true);
}
}
- if (!m_pDoor1 || !m_pDoor2)
- return;
- if (m_pDoor1->GetModelIndex() == MI_CRUSHERBODY || m_pDoor1->GetModelIndex() == MI_CRUSHERLID)
- return;
- CVector2D vecDoor1ToGarage(m_pDoor1->GetPosition().x - GetGarageCenterX(), m_pDoor1->GetPosition().y - GetGarageCenterY());
- CVector2D vecDoor2ToGarage(m_pDoor2->GetPosition().x - GetGarageCenterX(), m_pDoor2->GetPosition().y - GetGarageCenterY());
- if (DotProduct2D(vecDoor1ToGarage, vecDoor2ToGarage) > 0.0f) {
- if (vecDoor1ToGarage.MagnitudeSqr() >= vecDoor2ToGarage.MagnitudeSqr()) {
- m_pDoor1 = m_pDoor2;
- m_bDoor1IsDummy = m_bDoor2IsDummy;
+ if (m_pDoor1 && m_pDoor2) {
+ CVector2D vecDoor1ToGarage(m_pDoor1->GetPosition().x - GetGarageCenterX(), m_pDoor1->GetPosition().y - GetGarageCenterY());
+ CVector2D vecDoor2ToGarage(m_pDoor2->GetPosition().x - GetGarageCenterX(), m_pDoor2->GetPosition().y - GetGarageCenterY());
+ if (DotProduct2D(vecDoor1ToGarage, vecDoor2ToGarage) > 0.0f) {
+ if (vecDoor1ToGarage.MagnitudeSqr() >= vecDoor2ToGarage.MagnitudeSqr()) {
+ m_pDoor1 = m_pDoor2;
+ m_bDoor1IsDummy = m_bDoor2IsDummy;
+ }
+ m_pDoor2 = nil;
+ m_bDoor2IsDummy = false;
}
- m_pDoor2 = nil;
- m_bDoor2IsDummy = false;
}
+ if (m_pDoor1)
+ m_pDoor1->bUsesCollision = true;
+ if (m_pDoor2)
+ m_pDoor2->bUsesCollision = true;
}
void CGarage::FindDoorsEntitiesSectorList(CPtrList& list, bool dummy)
@@ -1792,29 +1772,8 @@ void CGarage::FindDoorsEntitiesSectorList(CPtrList& list, bool dummy)
pEntity->m_scanCode = CWorld::GetCurrentScanCode();
if (!pEntity || !CGarages::IsModelIndexADoor(pEntity->GetModelIndex()))
continue;
- if (Abs(pEntity->GetPosition().x - GetGarageCenterX()) >= DISTANCE_TO_CONSIDER_DOOR_FOR_GARAGE)
- continue;
- if (Abs(pEntity->GetPosition().y - GetGarageCenterY()) >= DISTANCE_TO_CONSIDER_DOOR_FOR_GARAGE)
- continue;
- if (pEntity->GetModelIndex() == MI_CRUSHERBODY) {
- m_pDoor1 = pEntity;
- m_bDoor1IsDummy = dummy;
- // very odd pool operations, they could have used GetJustIndex
- if (dummy)
- m_bDoor1PoolIndex = (CPools::GetDummyPool()->GetIndex((CDummy*)pEntity)) & 0x7F;
- else
- m_bDoor1PoolIndex = (CPools::GetObjectPool()->GetIndex((CObject*)pEntity)) & 0x7F;
- continue;
- }
- if (pEntity->GetModelIndex() == MI_CRUSHERLID) {
- m_pDoor2 = pEntity;
- m_bDoor2IsDummy = dummy;
- if (dummy)
- m_bDoor2PoolIndex = (CPools::GetDummyPool()->GetIndex((CDummy*)pEntity)) & 0x7F;
- else
- m_bDoor2PoolIndex = (CPools::GetObjectPool()->GetIndex((CObject*)pEntity)) & 0x7F;
+ if (!IsPointInsideGarage(pEntity->GetPosition(), 2.0f))
continue;
- }
if (!m_pDoor1) {
m_pDoor1 = pEntity;
m_bDoor1IsDummy = dummy;
@@ -1849,6 +1808,8 @@ void CGarages::SetGarageDoorToRotate(int16 garage)
aGarages[garage].m_bRotatedDoor = true;
aGarages[garage].m_fDoorHeight /= 2.0f;
aGarages[garage].m_fDoorHeight -= 0.1f;
+ aGarages[garage].m_fDoorPos = Min(aGarages[garage].m_fDoorHeight, aGarages[garage].m_fDoorPos);
+ aGarages[garage].UpdateDoorsHeight();
}
void CGarages::SetLeaveCameraForThisGarage(int16 garage)
@@ -1882,8 +1843,8 @@ void CStoredCar::StoreCar(CVehicle* pVehicle)
if (pVehicle->bExplosionProof) m_nFlags |= FLAG_EXPLOSIONPROOF;
if (pVehicle->bCollisionProof) m_nFlags |= FLAG_COLLISIONPROOF;
if (pVehicle->bMeleeProof) m_nFlags |= FLAG_MELEEPROOF;
- if (pVehicle->IsCar())
- m_nCarBombType = ((CAutomobile*)pVehicle)->m_bombType;
+ if (pVehicle->IsCar() || pVehicle->IsBike())
+ m_nCarBombType = ((CAutomobile*)pVehicle)->m_bombType; // NB: cast to CAutomobile is original behaviour
}
CVehicle* CStoredCar::RestoreCar()
@@ -1899,15 +1860,17 @@ CVehicle* CStoredCar::RestoreCar()
{
CVehicleModelInfo::SetComponentsToUse(m_nVariationA, m_nVariationB);
}
-#ifdef FIX_BUGS
CVehicle* pVehicle;
if (CModelInfo::IsBoatModel(m_nModelIndex))
pVehicle = new CBoat(m_nModelIndex, RANDOM_VEHICLE);
+ else if (CModelInfo::IsBikeModel(m_nModelIndex))
+ {
+ CBike* pBike = new CBike(m_nModelIndex, RANDOM_VEHICLE);
+ pBike->bIsStanding = true;
+ pVehicle = pBike;
+ }
else
pVehicle = new CAutomobile(m_nModelIndex, RANDOM_VEHICLE);
-#else
- CVehicle* pVehicle = new CAutomobile(m_nModelIndex, RANDOM_VEHICLE);
-#endif
pVehicle->SetPosition(m_vecPos);
pVehicle->SetStatus(STATUS_ABANDONED);
pVehicle->GetForward() = m_vecAngle;
@@ -1918,9 +1881,7 @@ CVehicle* CStoredCar::RestoreCar()
pVehicle->m_currentColour2 = m_nSecondaryColor;
pVehicle->m_nRadioStation = m_nRadioStation;
pVehicle->bFreebies = false;
-#ifdef FIX_BUGS
if (pVehicle->IsCar())
-#endif
{
((CAutomobile*)pVehicle)->m_bombType = m_nCarBombType;
#ifdef FIX_BUGS
@@ -1948,9 +1909,7 @@ void CGarage::StoreAndRemoveCarsForThisHideout(CStoredCar* aCars, int32 nMax)
CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
if (!pVehicle)
continue;
- if (pVehicle->GetPosition().x > m_fX1 && pVehicle->GetPosition().x < m_fX2 &&
- pVehicle->GetPosition().y > m_fY1 && pVehicle->GetPosition().y < m_fY2 &&
- pVehicle->GetPosition().z > m_fZ1 && pVehicle->GetPosition().z < m_fZ2) {
+ if (IsPointInsideGarage(pVehicle->GetPosition())) {
if (pVehicle->VehicleCreatedBy != MISSION_VEHICLE) {
if (index < Max(NUM_GARAGE_STORED_CARS, nMax) && !EntityHasASphereWayOutsideGarage(pVehicle, 1.0f))
aCars[index++].StoreCar(pVehicle);
@@ -1985,24 +1944,23 @@ bool CGarage::RestoreCarsForThisHideout(CStoredCar* aCars)
bool CGarages::IsPointInAGarageCameraZone(CVector point)
{
+#ifdef FIX_BUGS
+ for (uint32 i = 0; i < NumGarages; i++) {
+#else
for (int i = 0; i < NUM_GARAGES; i++) {
+#endif
switch (aGarages[i].m_eGarageType) {
case GARAGE_NONE:
break;
case GARAGE_COLLECTCARS_1:
case GARAGE_COLLECTCARS_2:
case GARAGE_COLLECTCARS_3:
- if (aGarages[i].m_fX1 - MARGIN_FOR_CAMERA_COLLECTCARS <= point.x &&
- aGarages[i].m_fX2 + MARGIN_FOR_CAMERA_COLLECTCARS >= point.x &&
- aGarages[i].m_fY1 - MARGIN_FOR_CAMERA_COLLECTCARS <= point.y &&
- aGarages[i].m_fY2 + MARGIN_FOR_CAMERA_COLLECTCARS >= point.y)
+ case GARAGE_COLLECTCARS_4:
+ if (aGarages[i].IsPointInsideGarage(point, MARGIN_FOR_CAMERA_COLLECTCARS))
return true;
break;
default:
- if (aGarages[i].m_fX1 - MARGIN_FOR_CAMERA_DEFAULT <= point.x &&
- aGarages[i].m_fX2 + MARGIN_FOR_CAMERA_DEFAULT >= point.x &&
- aGarages[i].m_fY1 - MARGIN_FOR_CAMERA_DEFAULT <= point.y &&
- aGarages[i].m_fY2 + MARGIN_FOR_CAMERA_DEFAULT >= point.y)
+ if (aGarages[i].IsPointInsideGarage(point, MARGIN_FOR_CAMERA_DEFAULT))
return true;
break;
}
@@ -2017,8 +1975,13 @@ bool CGarages::CameraShouldBeOutside()
void CGarages::GivePlayerDetonator()
{
- FindPlayerPed()->GiveWeapon(WEAPONTYPE_DETONATOR, 1);
- FindPlayerPed()->GetWeapon(FindPlayerPed()->GetWeaponSlot(WEAPONTYPE_DETONATOR)).m_eWeaponState = WEAPONSTATE_READY;
+ CPlayerPed* pPed = FindPlayerPed();
+ int slot = CWeaponInfo::GetWeaponInfo(WEAPONTYPE_DETONATOR)->m_nWeaponSlot;
+ pPed->GiveWeapon(WEAPONTYPE_DETONATOR, 1);
+ pPed->GetWeapon(pPed->GetWeaponSlot(WEAPONTYPE_DETONATOR)).m_eWeaponState = WEAPONSTATE_READY;
+ pPed->m_nSelectedWepSlot = slot;
+ if (pPed->m_storedWeapon != WEAPONTYPE_UNIDENTIFIED)
+ pPed->m_storedWeapon = WEAPONTYPE_DETONATOR;
}
float CGarages::FindDoorHeightForMI(int32 mi)
@@ -2035,14 +1998,12 @@ void CGarage::TidyUpGarage()
while (--i) {
#endif
CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
- if (!pVehicle || !pVehicle->IsCar())
- continue;
- if (pVehicle->GetPosition().x > m_fX1 && pVehicle->GetPosition().x < m_fX2 &&
- pVehicle->GetPosition().y > m_fY1 && pVehicle->GetPosition().y < m_fY2 &&
- pVehicle->GetPosition().z > m_fZ1 && pVehicle->GetPosition().z < m_fZ2) {
- if (pVehicle->GetStatus() == STATUS_WRECKED || pVehicle->GetUp().z < 0.5f) {
- CWorld::Remove(pVehicle);
- delete pVehicle;
+ if (pVehicle && (pVehicle->IsCar() || pVehicle->IsBike())) {
+ if (IsPointInsideGarage(pVehicle->GetPosition())) {
+ if (pVehicle->GetStatus() == STATUS_WRECKED || pVehicle->GetUp().z < 0.5f) {
+ CWorld::Remove(pVehicle);
+ delete pVehicle;
+ }
}
}
}
@@ -2057,9 +2018,9 @@ void CGarage::TidyUpGarageClose()
while (--i) {
#endif
CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
- if (!pVehicle || !pVehicle->IsCar())
+ if (!pVehicle)
continue;
- if (!pVehicle->IsCar() || pVehicle->GetStatus() != STATUS_WRECKED || !IsEntityTouching3D(pVehicle))
+ if ((!pVehicle->IsCar() && !pVehicle->IsBike()) || pVehicle->GetStatus() != STATUS_WRECKED || !IsEntityTouching3D(pVehicle))
continue;
bool bRemove = false;
if (m_eGarageState != GS_FULLYCLOSED) {
@@ -2067,11 +2028,8 @@ void CGarage::TidyUpGarageClose()
for (int i = 0; i < pColModel->numSpheres; i++) {
CVector pos = pVehicle->GetMatrix() * pColModel->spheres[i].center;
float radius = pColModel->spheres[i].radius;
- if (pos.x + radius < m_fX1 || pos.x - radius > m_fX2 ||
- pos.y + radius < m_fY1 || pos.y - radius > m_fY2 ||
- pos.z + radius < m_fZ1 || pos.z - radius > m_fZ2) {
+ if (!IsPointInsideGarage(pos, radius))
bRemove = true;
- }
}
}
else
@@ -2087,7 +2045,11 @@ void CGarage::TidyUpGarageClose()
void CGarages::PlayerArrestedOrDied()
{
static int GarageToBeTidied = 0; // lol
+#ifdef FIX_BUGS
+ for (uint32 i = 0; i < NumGarages; i++) {
+#else
for (int i = 0; i < NUM_GARAGES; i++) {
+#endif
if (aGarages[i].m_eGarageType != GARAGE_NONE)
aGarages[i].PlayerArrestedOrDied();
}
@@ -2114,6 +2076,17 @@ void CGarage::PlayerArrestedOrDied()
case GARAGE_FOR_SCRIPT_TO_OPEN_AND_CLOSE:
case GARAGE_KEEPS_OPENING_FOR_SPECIFIC_CAR:
case GARAGE_MISSION_KEEPCAR_REMAINCLOSED:
+ case GARAGE_COLLECTCARS_4:
+ case GARAGE_FOR_SCRIPT_TO_OPEN_FOR_CAR:
+ case GARAGE_HIDEOUT_FOUR:
+ case GARAGE_HIDEOUT_FIVE:
+ case GARAGE_HIDEOUT_SIX:
+ case GARAGE_HIDEOUT_SEVEN:
+ case GARAGE_HIDEOUT_EIGHT:
+ case GARAGE_HIDEOUT_NINE:
+ case GARAGE_HIDEOUT_TEN:
+ case GARAGE_HIDEOUT_ELEVEN:
+ case GARAGE_HIDEOUT_TWELVE:
switch (m_eGarageState) {
case GS_OPENED:
case GS_CLOSING:
@@ -2165,39 +2138,26 @@ void CGarage::CenterCarInGarage(CVehicle* pVehicle)
pVehicle->GetMatrix().GetPosition().x += offsetX * RESPRAY_CENTERING_COEFFICIENT / distance;
pVehicle->GetMatrix().GetPosition().y += offsetY * RESPRAY_CENTERING_COEFFICIENT / distance;
}
- if (!IsEntityEntirelyInside3D(pVehicle, 0.1f))
+ if (!IsEntityEntirelyInside3D(pVehicle, 0.3f))
pVehicle->SetPosition(pos);
}
void CGarages::CloseHideOutGaragesBeforeSave()
{
+#ifdef FIX_BUGS
+ for (uint32 i = 0; i < NumGarages; i++) {
+#else
for (int i = 0; i < NUM_GARAGES; i++) {
- if (aGarages[i].m_eGarageType != GARAGE_HIDEOUT_ONE &&
- aGarages[i].m_eGarageType != GARAGE_HIDEOUT_TWO &&
- aGarages[i].m_eGarageType != GARAGE_HIDEOUT_THREE)
+#endif
+ if (!IsThisGarageTypeSafehouse(aGarages[i].m_eGarageType))
continue;
- if (aGarages[i].m_eGarageState != GS_FULLYCLOSED &&
- (aGarages[i].m_eGarageType != GARAGE_HIDEOUT_ONE || !aGarages[i].IsAnyCarBlockingDoor())) {
+ if (aGarages[i].m_eGarageState != GS_FULLYCLOSED) {
aGarages[i].m_eGarageState = GS_FULLYCLOSED;
- switch (aGarages[i].m_eGarageType) {
- case GARAGE_HIDEOUT_ONE:
- aGarages[i].StoreAndRemoveCarsForThisHideout(aCarsInSafeHouse1, NUM_GARAGE_STORED_CARS);
- aGarages[i].RemoveCarsBlockingDoorNotInside();
- break;
- case GARAGE_HIDEOUT_TWO:
- aGarages[i].StoreAndRemoveCarsForThisHideout(aCarsInSafeHouse2, NUM_GARAGE_STORED_CARS);
- aGarages[i].RemoveCarsBlockingDoorNotInside();
- break;
- case GARAGE_HIDEOUT_THREE:
- aGarages[i].StoreAndRemoveCarsForThisHideout(aCarsInSafeHouse3, NUM_GARAGE_STORED_CARS);
- aGarages[i].RemoveCarsBlockingDoorNotInside();
- break;
- default:
- break;
- }
+ aGarages[i].StoreAndRemoveCarsForThisHideout(aCarsInSafeHouses[FindSafeHouseIndexForGarageType(aGarages[i].m_eGarageType)], NUM_GARAGE_STORED_CARS);
+ aGarages[i].RemoveCarsBlockingDoorNotInside();
+ aGarages[i].m_fDoorPos = 0.0f;
+ aGarages[i].UpdateDoorsHeight();
}
- aGarages[i].m_fDoorPos = 0.0f;
- aGarages[i].UpdateDoorsHeight();
}
}
@@ -2205,46 +2165,32 @@ int32 CGarages::CountCarsInHideoutGarage(uint8 type)
{
int32 total = 0;
for (int i = 0; i < NUM_GARAGE_STORED_CARS; i++) {
- switch (type) {
- case GARAGE_HIDEOUT_ONE:
- total += (aCarsInSafeHouse1[i].HasCar());
- break;
- case GARAGE_HIDEOUT_TWO:
- total += (aCarsInSafeHouse2[i].HasCar());
- break;
- case GARAGE_HIDEOUT_THREE:
- total += (aCarsInSafeHouse3[i].HasCar());
- break;
- default: break;
- }
+ total += aCarsInSafeHouses[FindSafeHouseIndexForGarageType(type)][i].HasCar();
}
return total;
}
-int32 CGarages::FindMaxNumStoredCarsForGarage(uint8 type)
-{
- switch (type) {
- case GARAGE_HIDEOUT_ONE:
- return LIMIT_CARS_IN_INDUSTRIAL;
- case GARAGE_HIDEOUT_TWO:
- return LIMIT_CARS_IN_COMMERCIAL;
- case GARAGE_HIDEOUT_THREE:
- return LIMIT_CARS_IN_SUBURBAN;
- default: break;
- }
- return 0;
-}
-
bool CGarages::IsPointWithinHideOutGarage(Const CVector& point)
{
+#ifdef FIX_BUGS
+ for (uint32 i = 0; i < NumGarages; i++) {
+#else
for (int i = 0; i < NUM_GARAGES; i++) {
+#endif
switch (aGarages[i].m_eGarageType) {
case GARAGE_HIDEOUT_ONE:
case GARAGE_HIDEOUT_TWO:
case GARAGE_HIDEOUT_THREE:
- if (point.x > aGarages[i].m_fX1 && point.x < aGarages[i].m_fX2 &&
- point.y > aGarages[i].m_fY1 && point.y < aGarages[i].m_fY2 &&
- point.z > aGarages[i].m_fZ1 && point.z < aGarages[i].m_fZ2)
+ case GARAGE_HIDEOUT_FOUR:
+ case GARAGE_HIDEOUT_FIVE:
+ case GARAGE_HIDEOUT_SIX:
+ case GARAGE_HIDEOUT_SEVEN:
+ case GARAGE_HIDEOUT_EIGHT:
+ case GARAGE_HIDEOUT_NINE:
+ case GARAGE_HIDEOUT_TEN:
+ case GARAGE_HIDEOUT_ELEVEN:
+ case GARAGE_HIDEOUT_TWELVE:
+ if (aGarages[i].IsPointInsideGarage(point))
return true;
default: break;
}
@@ -2254,14 +2200,16 @@ bool CGarages::IsPointWithinHideOutGarage(Const CVector& point)
bool CGarages::IsPointWithinAnyGarage(Const CVector& point)
{
+#ifdef FIX_BUGS
+ for (uint32 i = 0; i < NumGarages; i++) {
+#else
for (int i = 0; i < NUM_GARAGES; i++) {
+#endif
switch (aGarages[i].m_eGarageType) {
case GARAGE_NONE:
continue;
default:
- if (point.x > aGarages[i].m_fX1 && point.x < aGarages[i].m_fX2 &&
- point.y > aGarages[i].m_fY1 && point.y < aGarages[i].m_fY2 &&
- point.z > aGarages[i].m_fZ1 && point.z < aGarages[i].m_fZ2)
+ if (aGarages[i].IsPointInsideGarage(point))
return true;
}
}
@@ -2270,13 +2218,19 @@ bool CGarages::IsPointWithinAnyGarage(Const CVector& point)
void CGarages::SetAllDoorsBackToOriginalHeight()
{
+#ifdef FIX_BUGS
+ for (uint32 i = 0; i < NumGarages; i++) {
+#else
for (int i = 0; i < NUM_GARAGES; i++) {
+#endif
switch (aGarages[i].m_eGarageType) {
case GARAGE_NONE:
continue;
default:
aGarages[i].RefreshDoorPointers(true);
if (aGarages[i].m_pDoor1) {
+ aGarages[i].m_pDoor1->GetMatrix().GetPosition().x = aGarages[i].m_fDoor1X;
+ aGarages[i].m_pDoor1->GetMatrix().GetPosition().y = aGarages[i].m_fDoor1Y;
aGarages[i].m_pDoor1->GetMatrix().GetPosition().z = aGarages[i].m_fDoor1Z;
if (aGarages[i].m_pDoor1->IsObject())
((CObject*)aGarages[i].m_pDoor1)->m_objectMatrix.GetPosition().z = aGarages[i].m_fDoor1Z;
@@ -2286,6 +2240,8 @@ void CGarages::SetAllDoorsBackToOriginalHeight()
aGarages[i].m_pDoor1->UpdateRwFrame();
}
if (aGarages[i].m_pDoor2) {
+ aGarages[i].m_pDoor2->GetMatrix().GetPosition().x = aGarages[i].m_fDoor2X;
+ aGarages[i].m_pDoor2->GetMatrix().GetPosition().y = aGarages[i].m_fDoor2Y;
aGarages[i].m_pDoor2->GetMatrix().GetPosition().z = aGarages[i].m_fDoor2Z;
if (aGarages[i].m_pDoor2->IsObject())
((CObject*)aGarages[i].m_pDoor2)->m_objectMatrix.GetPosition().z = aGarages[i].m_fDoor2Z;
@@ -2300,14 +2256,11 @@ void CGarages::SetAllDoorsBackToOriginalHeight()
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
-#if !defined THIS_IS_STUPID && !defined FIX_GARAGE_SIZE && defined COMPATIBLE_SAVES
- memset(buf + 5240, 0, *size - 5240); // garbage data is written otherwise
+//INITSAVEBUF
+ *size = 7876; // for some reason it's not actual size again
+ //*size = (6 * sizeof(uint32) + TOTAL_COLLECTCARS_GARAGES * sizeof(*CarTypesCollected) + sizeof(uint32) + TOTAL_HIDEOUT_GARAGES * NUM_GARAGE_STORED_CARS * sizeof(CStoredCar) + NUM_GARAGES * sizeof(CGarage));
+#if !defined THIS_IS_STUPID && defined COMPATIBLE_SAVES
+ memset(buf + 7340, 0, *size - 7340); // garbage data is written otherwise
#endif
CloseHideOutGaragesBeforeSave();
WriteSaveBuf(buf, NumGarages);
@@ -2320,19 +2273,20 @@ void CGarages::Save(uint8 * buf, uint32 * size)
WriteSaveBuf(buf, CarTypesCollected[i]);
WriteSaveBuf(buf, LastTimeHelpMessage);
for (int i = 0; i < NUM_GARAGE_STORED_CARS; i++) {
- WriteSaveBuf(buf, aCarsInSafeHouse1[i]);
- WriteSaveBuf(buf, aCarsInSafeHouse2[i]);
- WriteSaveBuf(buf, aCarsInSafeHouse3[i]);
+ for (int j = 0; j < TOTAL_HIDEOUT_GARAGES; j++) {
+ WriteSaveBuf(buf, aCarsInSafeHouses[j][i]);
+ }
}
for (int i = 0; i < NUM_GARAGES; i++) {
#ifdef COMPATIBLE_SAVES
WriteSaveBuf(buf, aGarages[i].m_eGarageType);
WriteSaveBuf(buf, aGarages[i].m_eGarageState);
+ WriteSaveBuf(buf, aGarages[i].m_nMaxStoredCars);
WriteSaveBuf(buf, aGarages[i].field_2);
WriteSaveBuf(buf, aGarages[i].m_bClosingWithoutTargetCar);
WriteSaveBuf(buf, aGarages[i].m_bDeactivated);
WriteSaveBuf(buf, aGarages[i].m_bResprayHappened);
- ZeroSaveBuf(buf, 2);
+ ZeroSaveBuf(buf, 1);
WriteSaveBuf(buf, aGarages[i].m_nTargetModelIndex);
ZeroSaveBuf(buf, 4 + 4);
WriteSaveBuf(buf, aGarages[i].m_bDoor1PoolIndex);
@@ -2343,12 +2297,17 @@ void CGarages::Save(uint8 * buf, uint32 * size)
WriteSaveBuf(buf, aGarages[i].m_bRotatedDoor);
WriteSaveBuf(buf, aGarages[i].m_bCameraFollowsPlayer);
ZeroSaveBuf(buf, 1);
- WriteSaveBuf(buf, aGarages[i].m_fX1);
- WriteSaveBuf(buf, aGarages[i].m_fX2);
- WriteSaveBuf(buf, aGarages[i].m_fY1);
- WriteSaveBuf(buf, aGarages[i].m_fY2);
- WriteSaveBuf(buf, aGarages[i].m_fZ1);
- WriteSaveBuf(buf, aGarages[i].m_fZ2);
+ WriteSaveBuf(buf, aGarages[i].m_vecCorner1);
+ WriteSaveBuf(buf, aGarages[i].m_fInfZ);
+ WriteSaveBuf(buf, aGarages[i].m_vDir1);
+ WriteSaveBuf(buf, aGarages[i].m_vDir2);
+ WriteSaveBuf(buf, aGarages[i].m_fSupZ);
+ WriteSaveBuf(buf, aGarages[i].m_fDir1Len);
+ WriteSaveBuf(buf, aGarages[i].m_fDir2Len);
+ WriteSaveBuf(buf, aGarages[i].m_fInfX);
+ WriteSaveBuf(buf, aGarages[i].m_fSupX);
+ WriteSaveBuf(buf, aGarages[i].m_fInfY);
+ WriteSaveBuf(buf, aGarages[i].m_fSupY);
WriteSaveBuf(buf, aGarages[i].m_fDoorPos);
WriteSaveBuf(buf, aGarages[i].m_fDoorHeight);
WriteSaveBuf(buf, aGarages[i].m_fDoor1X);
@@ -2359,15 +2318,13 @@ void CGarages::Save(uint8 * buf, uint32 * size)
WriteSaveBuf(buf, aGarages[i].m_fDoor2Z);
WriteSaveBuf(buf, aGarages[i].m_nTimeToStartAction);
WriteSaveBuf(buf, aGarages[i].m_bCollectedCarsState);
- ZeroSaveBuf(buf, 3 + 4 + 4);
+ ZeroSaveBuf(buf, 3 + 4);
ZeroSaveBuf(buf, sizeof(aGarages[i].m_sStoredCar));
#else
WriteSaveBuf(buf, aGarages[i]);
#endif
}
-#ifdef FIX_GARAGE_SIZE
- VALIDATESAVEBUF(*size);
-#endif
+//VALIDATESAVEBUF(*size);
}
const CStoredCar &CStoredCar::operator=(const CStoredCar & other)
@@ -2387,12 +2344,9 @@ const CStoredCar &CStoredCar::operator=(const CStoredCar & other)
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 == 7876);
+ //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();
ReadSaveBuf(&NumGarages, buf);
int32 tempInt;
@@ -2407,46 +2361,52 @@ void CGarages::Load(uint8* buf, uint32 size)
ReadSaveBuf(&CarTypesCollected[i], buf);
ReadSaveBuf(&LastTimeHelpMessage, buf);
for (int i = 0; i < NUM_GARAGE_STORED_CARS; i++) {
- ReadSaveBuf(&aCarsInSafeHouse1[i], buf);
- ReadSaveBuf(&aCarsInSafeHouse2[i], buf);
- ReadSaveBuf(&aCarsInSafeHouse3[i], buf);
+ for (int j = 0; j < TOTAL_HIDEOUT_GARAGES; j++) {
+ ReadSaveBuf(&aCarsInSafeHouses[j][i], buf);
+ }
}
for (int i = 0; i < NUM_GARAGES; i++) {
#ifdef COMPATIBLE_SAVES
ReadSaveBuf(&aGarages[i].m_eGarageType, buf);
ReadSaveBuf(&aGarages[i].m_eGarageState, buf);
+ ReadSaveBuf(&aGarages[i].m_nMaxStoredCars, buf);
ReadSaveBuf(&aGarages[i].field_2, buf);
ReadSaveBuf(&aGarages[i].m_bClosingWithoutTargetCar, buf);
ReadSaveBuf(&aGarages[i].m_bDeactivated, buf);
ReadSaveBuf(&aGarages[i].m_bResprayHappened, buf);
- SkipSaveBuf(buf, 2);
+ SkipSaveBuf(buf, 1);
ReadSaveBuf(&aGarages[i].m_nTargetModelIndex, buf);
SkipSaveBuf(buf, 4 + 4);
- ReadSaveBuf(&aGarages[i].m_bDoor1PoolIndex, buf);
- ReadSaveBuf(&aGarages[i].m_bDoor2PoolIndex, buf);
- ReadSaveBuf(&aGarages[i].m_bDoor1IsDummy, buf);
- ReadSaveBuf(&aGarages[i].m_bDoor2IsDummy, buf);
- ReadSaveBuf(&aGarages[i].m_bRecreateDoorOnNextRefresh, buf);
- ReadSaveBuf(&aGarages[i].m_bRotatedDoor, buf);
+ ReadSaveBuf(&aGarages[i].m_bDoor1PoolIndex, buf);
+ ReadSaveBuf(&aGarages[i].m_bDoor2PoolIndex, buf);
+ ReadSaveBuf(&aGarages[i].m_bDoor1IsDummy, buf);
+ ReadSaveBuf(&aGarages[i].m_bDoor2IsDummy, buf);
+ ReadSaveBuf(&aGarages[i].m_bRecreateDoorOnNextRefresh, buf);
+ ReadSaveBuf(&aGarages[i].m_bRotatedDoor, buf);
ReadSaveBuf(&aGarages[i].m_bCameraFollowsPlayer, buf);
SkipSaveBuf(buf, 1);
- ReadSaveBuf(&aGarages[i].m_fX1, buf);
- ReadSaveBuf(&aGarages[i].m_fX2, buf);
- ReadSaveBuf(&aGarages[i].m_fY1, buf);
- ReadSaveBuf(&aGarages[i].m_fY2, buf);
- ReadSaveBuf(&aGarages[i].m_fZ1, buf);
- ReadSaveBuf(&aGarages[i].m_fZ2, buf);
- ReadSaveBuf(&aGarages[i].m_fDoorPos, buf);
- ReadSaveBuf(&aGarages[i].m_fDoorHeight, buf);
- ReadSaveBuf(&aGarages[i].m_fDoor1X, buf);
- ReadSaveBuf(&aGarages[i].m_fDoor1Y, buf);
- ReadSaveBuf(&aGarages[i].m_fDoor2X, buf);
- ReadSaveBuf(&aGarages[i].m_fDoor2Y, buf);
- ReadSaveBuf(&aGarages[i].m_fDoor1Z, buf);
- ReadSaveBuf(&aGarages[i].m_fDoor2Z, buf);
- ReadSaveBuf(&aGarages[i].m_nTimeToStartAction, buf);
+ ReadSaveBuf(&aGarages[i].m_vecCorner1, buf);
+ ReadSaveBuf(&aGarages[i].m_fInfZ, buf);
+ ReadSaveBuf(&aGarages[i].m_vDir1, buf);
+ ReadSaveBuf(&aGarages[i].m_vDir2, buf);
+ ReadSaveBuf(&aGarages[i].m_fSupZ, buf);
+ ReadSaveBuf(&aGarages[i].m_fDir1Len, buf);
+ ReadSaveBuf(&aGarages[i].m_fDir2Len, buf);
+ ReadSaveBuf(&aGarages[i].m_fInfX, buf);
+ ReadSaveBuf(&aGarages[i].m_fSupX, buf);
+ ReadSaveBuf(&aGarages[i].m_fInfY, buf);
+ ReadSaveBuf(&aGarages[i].m_fSupY, buf);
+ ReadSaveBuf(&aGarages[i].m_fDoorPos, buf);
+ ReadSaveBuf(&aGarages[i].m_fDoorHeight, buf);
+ ReadSaveBuf(&aGarages[i].m_fDoor1X, buf);
+ ReadSaveBuf(&aGarages[i].m_fDoor1Y, buf);
+ ReadSaveBuf(&aGarages[i].m_fDoor2X, buf);
+ ReadSaveBuf(&aGarages[i].m_fDoor2Y, buf);
+ ReadSaveBuf(&aGarages[i].m_fDoor1Z, buf);
+ ReadSaveBuf(&aGarages[i].m_fDoor2Z, buf);
+ ReadSaveBuf(&aGarages[i].m_nTimeToStartAction, buf);
ReadSaveBuf(&aGarages[i].m_bCollectedCarsState, buf);
- SkipSaveBuf(buf, 3 + 4 + 4);
+ SkipSaveBuf(buf, 3 + 4);
SkipSaveBuf(buf, sizeof(aGarages[i].m_sStoredCar));
#else
ReadSaveBuf(&aGarages[i], buf);
@@ -2454,7 +2414,6 @@ void CGarages::Load(uint8* buf, uint32 size)
aGarages[i].m_pDoor1 = nil;
aGarages[i].m_pDoor2 = nil;
aGarages[i].m_pTarget = nil;
- aGarages[i].field_96 = nil;
aGarages[i].m_bRecreateDoorOnNextRefresh = true;
aGarages[i].RefreshDoorPointers(true);
if (aGarages[i].m_eGarageType == GARAGE_CRUSHER)
@@ -2462,9 +2421,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;
@@ -2474,8 +2431,7 @@ void CGarages::Load(uint8* buf, uint32 size)
bool
CGarages::IsModelIndexADoor(uint32 id)
{
- return id == MI_GARAGEDOOR1 ||
- id == MI_GARAGEDOOR2 ||
+ return id == MI_GARAGEDOOR2 ||
id == MI_GARAGEDOOR3 ||
id == MI_GARAGEDOOR4 ||
id == MI_GARAGEDOOR5 ||
@@ -2489,7 +2445,6 @@ CGarages::IsModelIndexADoor(uint32 id)
id == MI_GARAGEDOOR14 ||
id == MI_GARAGEDOOR15 ||
id == MI_GARAGEDOOR16 ||
- id == MI_GARAGEDOOR17 ||
id == MI_GARAGEDOOR18 ||
id == MI_GARAGEDOOR19 ||
id == MI_GARAGEDOOR20 ||
@@ -2498,15 +2453,7 @@ CGarages::IsModelIndexADoor(uint32 id)
id == MI_GARAGEDOOR23 ||
id == MI_GARAGEDOOR24 ||
id == MI_GARAGEDOOR25 ||
- id == MI_GARAGEDOOR26 ||
- id == MI_GARAGEDOOR27 ||
- id == MI_GARAGEDOOR28 ||
- id == MI_GARAGEDOOR29 ||
- id == MI_GARAGEDOOR30 ||
- id == MI_GARAGEDOOR31 ||
- id == MI_GARAGEDOOR32 ||
- id == MI_CRUSHERBODY ||
- id == MI_CRUSHERLID;
+ id == MI_GARAGEDOOR26;
}
void CGarages::StopCarFromBlowingUp(CAutomobile* pCar)
diff --git a/src/control/Garages.h b/src/control/Garages.h
index 8a9fd1b6..358d404d 100644
--- a/src/control/Garages.h
+++ b/src/control/Garages.h
@@ -41,12 +41,24 @@ enum eGarageType
GARAGE_FOR_SCRIPT_TO_OPEN_AND_CLOSE,
GARAGE_KEEPS_OPENING_FOR_SPECIFIC_CAR,
GARAGE_MISSION_KEEPCAR_REMAINCLOSED,
+ GARAGE_COLLECTCARS_4,
+ GARAGE_FOR_SCRIPT_TO_OPEN_FOR_CAR,
+ GARAGE_HIDEOUT_FOUR,
+ GARAGE_HIDEOUT_FIVE,
+ GARAGE_HIDEOUT_SIX,
+ GARAGE_HIDEOUT_SEVEN,
+ GARAGE_HIDEOUT_EIGHT,
+ GARAGE_HIDEOUT_NINE,
+ GARAGE_HIDEOUT_TEN,
+ GARAGE_HIDEOUT_ELEVEN,
+ GARAGE_HIDEOUT_TWELVE
};
enum
{
- TOTAL_COLLECTCARS_GARAGES = GARAGE_COLLECTCARS_3 - GARAGE_COLLECTCARS_1 + 1,
- TOTAL_COLLECTCARS_CARS = 16
+ TOTAL_COLLECTCARS_GARAGES = 4,
+ TOTAL_HIDEOUT_GARAGES = 12,
+ TOTAL_COLLECTCARS_CARS = 6
};
class CStoredCar
@@ -81,18 +93,12 @@ VALIDATE_SIZE(CStoredCar, 0x28);
#define SWITCH_GARAGE_DISTANCE_CLOSE 40.0f
-#define CRUSHER_GARAGE_X1 (1135.5f)
-#define CRUSHER_GARAGE_Y1 (57.0f)
-#define CRUSHER_GARAGE_Z1 (-1.0f)
-#define CRUSHER_GARAGE_X2 (1149.5f)
-#define CRUSHER_GARAGE_Y2 (63.7f)
-#define CRUSHER_GARAGE_Z2 (3.5f)
-
class CGarage
{
public:
uint8 m_eGarageType;
uint8 m_eGarageState;
+ uint8 m_nMaxStoredCars;
bool field_2; // unused
bool m_bClosingWithoutTargetCar;
bool m_bDeactivated;
@@ -107,12 +113,17 @@ public:
bool m_bRecreateDoorOnNextRefresh;
bool m_bRotatedDoor;
bool m_bCameraFollowsPlayer;
- float m_fX1;
- float m_fX2;
- float m_fY1;
- float m_fY2;
- float m_fZ1;
- float m_fZ2;
+ CVector2D m_vecCorner1;
+ float m_fInfZ;
+ CVector2D m_vDir1;
+ CVector2D m_vDir2;
+ float m_fSupZ;
+ float m_fDir1Len;
+ float m_fDir2Len;
+ float m_fInfX;
+ float m_fSupX;
+ float m_fInfY;
+ float m_fSupY;
float m_fDoorPos;
float m_fDoorHeight;
float m_fDoor1X;
@@ -124,7 +135,6 @@ public:
uint32 m_nTimeToStartAction;
uint8 m_bCollectedCarsState;
CVehicle *m_pTarget;
- void* field_96; // unused
CStoredCar m_sStoredCar; // not needed
void OpenThisGarage();
@@ -133,16 +143,16 @@ public:
bool IsClosed() { return m_eGarageState == GS_FULLYCLOSED; }
bool IsUsed() { return m_eGarageType != GARAGE_NONE; }
void Update();
- float GetGarageCenterX() { return (m_fX1 + m_fX2) / 2; }
- float GetGarageCenterY() { return (m_fY1 + m_fY2) / 2; }
+ float GetGarageCenterX() { return (m_fInfX + m_fSupX) / 2; }
+ float GetGarageCenterY() { return (m_fInfY + m_fSupY) / 2; }
bool IsFar()
{
#ifdef FIX_BUGS
return Abs(TheCamera.GetPosition().x - GetGarageCenterX()) > SWITCH_GARAGE_DISTANCE_CLOSE ||
Abs(TheCamera.GetPosition().y - GetGarageCenterY()) > SWITCH_GARAGE_DISTANCE_CLOSE;
#else
- return Abs(TheCamera.GetPosition().x - m_fX1) > SWITCH_GARAGE_DISTANCE_CLOSE ||
- Abs(TheCamera.GetPosition().y - m_fY1) > SWITCH_GARAGE_DISTANCE_CLOSE;
+ return Abs(TheCamera.GetPosition().x - m_fInfX) > SWITCH_GARAGE_DISTANCE_CLOSE ||
+ Abs(TheCamera.GetPosition().y - m_fInfY) > SWITCH_GARAGE_DISTANCE_CLOSE;
#endif
}
void TidyUpGarageClose();
@@ -152,7 +162,6 @@ public:
void UpdateDoorsHeight();
bool IsEntityEntirelyInside3D(CEntity*, float);
bool IsEntityEntirelyOutside(CEntity*, float);
- bool IsEntityEntirelyInside(CEntity*);
float CalcDistToGarageRectangleSquared(float, float);
float CalcSmallestDistToGarageDoorSquared(float, float);
bool IsAnyOtherCarTouchingGarage(CVehicle* pException);
@@ -181,14 +190,18 @@ public:
void MarkThisCarAsCollectedFor60Seconds(int mi);
bool IsPlayerEntirelyInsideGarage();
-};
+ bool IsPointInsideGarage(CVector);
+ bool IsPointInsideGarage(CVector, float);
+ void ThrowCarsNearDoorOutOfGarage(CVehicle*);
+
+ int32 FindMaxNumStoredCarsForGarage() { return Min(NUM_GARAGE_STORED_CARS, m_nMaxStoredCars); }
-VALIDATE_SIZE(CGarage, 140);
+};
class CGarages
{
enum {
- MESSAGE_LENGTH = 8
+ MESSAGE_LENGTH = 8,
};
public:
static int32 BankVansCollected;
@@ -207,9 +220,7 @@ public:
static bool PlayerInGarage;
static int32 PoliceCarsCollected;
static CGarage aGarages[NUM_GARAGES];
- static CStoredCar aCarsInSafeHouse1[NUM_GARAGE_STORED_CARS];
- static CStoredCar aCarsInSafeHouse2[NUM_GARAGE_STORED_CARS];
- static CStoredCar aCarsInSafeHouse3[NUM_GARAGE_STORED_CARS];
+ static CStoredCar aCarsInSafeHouses[TOTAL_HIDEOUT_GARAGES][NUM_GARAGE_STORED_CARS];
static bool bCamShouldBeOutisde;
static void Init(void);
@@ -218,7 +229,7 @@ public:
#endif
static void Update(void);
- static int16 AddOne(CVector pos1, CVector pos2, uint8 type, int32 targetId);
+ static int16 AddOne(float X1, float Y1, float Z1, float X2, float Y2, float X3, float Y3, float Z2, uint8 type, int32 targetId);
static void ChangeGarageType(int16, uint8, int32);
static void PrintMessages(void);
static void TriggerMessage(const char* text, int16, uint16 time, int16);
@@ -251,13 +262,42 @@ public:
static void SetFreeBombs(bool bValue) { BombsAreFree = bValue; }
static void SetFreeResprays(bool bValue) { RespraysAreFree = bValue; }
static void StopCarFromBlowingUp(CAutomobile*);
+ static void SetMaxNumStoredCarsForGarage(int16 garage, uint8 num) { aGarages[garage].m_nMaxStoredCars = num; }
static bool IsCarSprayable(CVehicle*);
static float FindDoorHeightForMI(int32);
static void CloseHideOutGaragesBeforeSave(void);
static int32 CountCarsInHideoutGarage(uint8);
- static int32 FindMaxNumStoredCarsForGarage(uint8);
static int32 GetBombTypeForGarageType(uint8 type) { return type - GARAGE_BOMBSHOP1 + 1; }
- static int32 GetCarsCollectedIndexForGarageType(uint8 type) { return type - GARAGE_COLLECTCARS_1; }
+ static int32 GetCarsCollectedIndexForGarageType(uint8 type)
+ {
+ switch (type) {
+ case GARAGE_COLLECTCARS_1: return 0;
+ case GARAGE_COLLECTCARS_2: return 1;
+ case GARAGE_COLLECTCARS_3: return 2;
+ case GARAGE_COLLECTCARS_4: return 3;
+ default: assert(0);
+ }
+ return 0;
+ }
+ static int32 FindSafeHouseIndexForGarageType(uint8 type)
+ {
+ switch (type) {
+ case GARAGE_HIDEOUT_ONE: return 0;
+ case GARAGE_HIDEOUT_TWO: return 1;
+ case GARAGE_HIDEOUT_THREE: return 2;
+ case GARAGE_HIDEOUT_FOUR: return 3;
+ case GARAGE_HIDEOUT_FIVE: return 4;
+ case GARAGE_HIDEOUT_SIX: return 5;
+ case GARAGE_HIDEOUT_SEVEN: return 6;
+ case GARAGE_HIDEOUT_EIGHT: return 7;
+ case GARAGE_HIDEOUT_NINE: return 8;
+ case GARAGE_HIDEOUT_TEN: return 9;
+ case GARAGE_HIDEOUT_ELEVEN: return 10;
+ case GARAGE_HIDEOUT_TWELVE: return 11;
+ }
+ return -1;
+ }
+ static bool IsThisGarageTypeSafehouse(uint8 type) { return FindSafeHouseIndexForGarageType(type) >= 0; }
};
diff --git a/src/control/OnscreenTimer.cpp b/src/control/OnscreenTimer.cpp
index 08c68cb5..5045c1e0 100644
--- a/src/control/OnscreenTimer.cpp
+++ b/src/control/OnscreenTimer.cpp
@@ -7,23 +7,29 @@
#include "Timer.h"
#include "Script.h"
#include "OnscreenTimer.h"
+#include "Camera.h"
void
COnscreenTimer::Init()
{
m_bDisabled = false;
- for(uint32 i = 0; i < NUMONSCREENTIMERENTRIES; i++) {
- m_sEntries[i].m_nTimerOffset = 0;
- m_sEntries[i].m_nCounterOffset = 0;
+ for(uint32 i = 0; i < NUMONSCREENCOUNTERS; i++) {
+ m_sCounters[i].m_nCounterOffset = 0;
- for(uint32 j = 0; j < 10; j++) {
- m_sEntries[i].m_aTimerText[j] = '\0';
- m_sEntries[i].m_aCounterText[j] = '\0';
- }
+ for(uint32 j = 0; j < ARRAY_SIZE(m_sCounters[0].m_aCounterText); j++)
+ m_sCounters[i].m_aCounterText[j] = '\0';
+
+ m_sCounters[i].m_nType = COUNTER_DISPLAY_NUMBER;
+ m_sCounters[i].m_bCounterProcessed = false;
+ }
+ for(uint32 i = 0; i < NUMONSCREENCLOCKS; i++) {
+ m_sClocks[i].m_nClockOffset = 0;
- m_sEntries[i].m_nType = COUNTER_DISPLAY_NUMBER;
- m_sEntries[i].m_bTimerProcessed = false;
- m_sEntries[i].m_bCounterProcessed = false;
+ for(uint32 j = 0; j < ARRAY_SIZE(m_sClocks[0].m_aClockText); j++)
+ m_sClocks[i].m_aClockText[j] = '\0';
+
+ m_sClocks[i].m_bClockProcessed = false;
+ m_sClocks[i].m_bClockGoingDown = true;
}
}
@@ -31,8 +37,8 @@ void
COnscreenTimer::Process()
{
if(!CReplay::IsPlayingBack() && !m_bDisabled)
- for(uint32 i = 0; i < NUMONSCREENTIMERENTRIES; i++)
- m_sEntries[i].Process();
+ for(uint32 i = 0; i < NUMONSCREENCLOCKS; i++)
+ m_sClocks[i].Process();
}
void
@@ -40,21 +46,34 @@ COnscreenTimer::ProcessForDisplay()
{
if(CHud::m_Wants_To_Draw_Hud) {
m_bProcessed = false;
- for(uint32 i = 0; i < NUMONSCREENTIMERENTRIES; i++)
- if(m_sEntries[i].ProcessForDisplay())
+ for(uint32 i = 0; i < NUMONSCREENCLOCKS; i++) {
+ m_sClocks[i].m_bClockProcessed = false;
+ if (m_sClocks[i].m_nClockOffset != 0) {
+ m_sClocks[i].ProcessForDisplayClock();
+ m_sClocks[i].m_bClockProcessed = true;
+ m_bProcessed = true;
+ }
+ }
+ for(uint32 i = 0; i < NUMONSCREENCOUNTERS; i++) {
+ m_sCounters[i].m_bCounterProcessed = false;
+ if (m_sCounters[i].m_nCounterOffset != 0) {
+ m_sCounters[i].ProcessForDisplayCounter();
+ m_sCounters[i].m_bCounterProcessed = true;
m_bProcessed = true;
+ }
+ }
}
}
void
COnscreenTimer::ClearCounter(uint32 offset)
{
- for(uint32 i = 0; i < NUMONSCREENTIMERENTRIES; i++) {
- if(offset == m_sEntries[i].m_nCounterOffset) {
- m_sEntries[i].m_nCounterOffset = 0;
- m_sEntries[i].m_aCounterText[0] = '\0';
- m_sEntries[i].m_nType = COUNTER_DISPLAY_NUMBER;
- m_sEntries[i].m_bCounterProcessed = false;
+ for(uint32 i = 0; i < NUMONSCREENCOUNTERS; i++) {
+ if(offset == m_sCounters[i].m_nCounterOffset) {
+ m_sCounters[i].m_nCounterOffset = 0;
+ m_sCounters[i].m_aCounterText[0] = '\0';
+ m_sCounters[i].m_nType = COUNTER_DISPLAY_NUMBER;
+ m_sCounters[i].m_bCounterProcessed = false;
}
}
}
@@ -62,98 +81,85 @@ COnscreenTimer::ClearCounter(uint32 offset)
void
COnscreenTimer::ClearClock(uint32 offset)
{
- for(uint32 i = 0; i < NUMONSCREENTIMERENTRIES; i++)
- if(offset == m_sEntries[i].m_nTimerOffset) {
- m_sEntries[i].m_nTimerOffset = 0;
- m_sEntries[i].m_aTimerText[0] = '\0';
- m_sEntries[i].m_bTimerProcessed = false;
+ for(uint32 i = 0; i < NUMONSCREENCLOCKS; i++)
+ if(offset == m_sClocks[i].m_nClockOffset) {
+ m_sClocks[i].m_nClockOffset = 0;
+ m_sClocks[i].m_aClockText[0] = '\0';
+ m_sClocks[i].m_bClockProcessed = false;
+ m_sClocks[i].m_bClockGoingDown = true;
}
}
void
-COnscreenTimer::AddCounter(uint32 offset, uint16 type, char* text)
+COnscreenTimer::AddCounter(uint32 offset, uint16 type, char* text, uint16 pos)
{
- for(uint32 i = 0; i < NUMONSCREENTIMERENTRIES; i++)
- if(m_sEntries[i].m_nCounterOffset == 0) {
- m_sEntries[i].m_nCounterOffset = offset;
- if (text)
- strncpy(m_sEntries[i].m_aCounterText, text, 10);
- else
- m_sEntries[i].m_aCounterText[0] = '\0';
- m_sEntries[i].m_nType = type;
- break;
- }
+ if (m_sCounters[pos].m_aCounterText[0] != '\0')
+ return;
+
+ m_sCounters[pos].m_nCounterOffset = offset;
+ if(text)
+ strncpy(m_sCounters[pos].m_aCounterText, text, ARRAY_SIZE(m_sCounters[0].m_aCounterText));
+ else
+ m_sCounters[pos].m_aCounterText[0] = '\0';
+
+ m_sCounters[pos].m_nType = type;
}
void
-COnscreenTimer::AddClock(uint32 offset, char* text)
+COnscreenTimer::AddClock(uint32 offset, char* text, bool bGoingDown)
{
- for(uint32 i = 0; i < NUMONSCREENTIMERENTRIES; i++)
- if(m_sEntries[i].m_nTimerOffset == 0) {
- m_sEntries[i].m_nTimerOffset = offset;
- if (text)
- strncpy(m_sEntries[i].m_aTimerText, text, 10);
+ for(uint32 i = 0; i < NUMONSCREENCLOCKS; i++) {
+ if(m_sClocks[i].m_nClockOffset == 0) {
+ m_sClocks[i].m_nClockOffset = offset;
+ m_sClocks[i].m_bClockGoingDown = bGoingDown;
+ if(text)
+ strncpy(m_sClocks[i].m_aClockText, text, ARRAY_SIZE(m_sClocks[0].m_aClockText));
else
- m_sEntries[i].m_aTimerText[0] = '\0';
+ m_sClocks[i].m_aClockText[0] = '\0';
break;
}
+ }
}
void
COnscreenTimerEntry::Process()
{
- if(m_nTimerOffset == 0)
+ if(m_nClockOffset == 0)
return;
- int32* timerPtr = CTheScripts::GetPointerToScriptVariable(m_nTimerOffset);
+ int32* timerPtr = CTheScripts::GetPointerToScriptVariable(m_nClockOffset);
int32 oldTime = *timerPtr;
- int32 newTime = oldTime - int32(CTimer::GetTimeStepInMilliseconds());
- if(newTime < 0) {
- *timerPtr = 0;
- m_bTimerProcessed = false;
- m_nTimerOffset = 0;
- m_aTimerText[0] = '\0';
- } else {
+ if (m_bClockGoingDown) {
+ int32 newTime = oldTime - int32(CTimer::GetTimeStepInMilliseconds());
*timerPtr = newTime;
- int32 oldTimeSeconds = oldTime / 1000;
- if(oldTimeSeconds < 12 && newTime / 1000 != oldTimeSeconds) {
- DMAudio.PlayFrontEndSound(SOUND_CLOCK_TICK, newTime / 1000);
+ if (newTime < 0) {
+ *timerPtr = 0;
+ m_bClockProcessed = 0;
+ m_nClockOffset = 0;
+ m_aClockText[0] = 0;
+ }
+ else {
+ int32 oldTimeSeconds = oldTime / 1000;
+ if (oldTimeSeconds < 12 && newTime / 1000 != oldTimeSeconds && !TheCamera.m_WideScreenOn) {
+ DMAudio.PlayFrontEndSound(SOUND_CLOCK_TICK, newTime / 1000);
+ }
}
}
-}
-
-bool
-COnscreenTimerEntry::ProcessForDisplay()
-{
- m_bTimerProcessed = false;
- m_bCounterProcessed = false;
-
- if(m_nTimerOffset == 0 && m_nCounterOffset == 0)
- return false;
-
- if(m_nTimerOffset != 0) {
- m_bTimerProcessed = true;
- ProcessForDisplayClock();
- }
-
- if(m_nCounterOffset != 0) {
- m_bCounterProcessed = true;
- ProcessForDisplayCounter();
- }
- return true;
+ else
+ *timerPtr = oldTime + int32(CTimer::GetTimeStepInMilliseconds());
}
void
COnscreenTimerEntry::ProcessForDisplayClock()
{
- uint32 time = *CTheScripts::GetPointerToScriptVariable(m_nTimerOffset);
- sprintf(m_bTimerBuffer, "%02d:%02d", time / 1000 / 60,
+ uint32 time = *CTheScripts::GetPointerToScriptVariable(m_nClockOffset);
+ sprintf(m_aClockBuffer, "%02d:%02d", time / 1000 / 60 % 100,
time / 1000 % 60);
}
void
-COnscreenTimerEntry::ProcessForDisplayCounter()
+COnscreenCounterEntry::ProcessForDisplayCounter()
{
uint32 counter = *CTheScripts::GetPointerToScriptVariable(m_nCounterOffset);
- sprintf(m_bCounterBuffer, "%d", counter);
+ sprintf(m_aCounterBuffer, "%d", counter);
}
diff --git a/src/control/OnscreenTimer.h b/src/control/OnscreenTimer.h
index 3ef7764a..8c049d7d 100644
--- a/src/control/OnscreenTimer.h
+++ b/src/control/OnscreenTimer.h
@@ -9,29 +9,37 @@ enum
class COnscreenTimerEntry
{
public:
- uint32 m_nTimerOffset;
+ uint32 m_nClockOffset;
+ char m_aClockText[10];
+ char m_aClockBuffer[40];
+ bool m_bClockProcessed;
+ bool m_bClockGoingDown;
+
+ void Process();
+ void ProcessForDisplayClock();
+};
+
+VALIDATE_SIZE(COnscreenTimerEntry, 0x3C);
+
+class COnscreenCounterEntry
+{
+public:
uint32 m_nCounterOffset;
- char m_aTimerText[10];
char m_aCounterText[10];
uint16 m_nType;
- char m_bCounterBuffer[42];
- char m_bTimerBuffer[42];
- bool m_bTimerProcessed;
+ char m_aCounterBuffer[40];
bool m_bCounterProcessed;
- void Process();
- bool ProcessForDisplay();
-
- void ProcessForDisplayClock();
void ProcessForDisplayCounter();
};
-VALIDATE_SIZE(COnscreenTimerEntry, 0x74);
+VALIDATE_SIZE(COnscreenCounterEntry, 0x3C);
class COnscreenTimer
{
public:
- COnscreenTimerEntry m_sEntries[NUMONSCREENTIMERENTRIES];
+ COnscreenTimerEntry m_sClocks[NUMONSCREENCLOCKS];
+ COnscreenCounterEntry m_sCounters[NUMONSCREENCOUNTERS];
bool m_bProcessed;
bool m_bDisabled;
@@ -42,8 +50,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);
+VALIDATE_SIZE(COnscreenTimer, 0xF4);
diff --git a/src/control/PathFind.cpp b/src/control/PathFind.cpp
index c6407820..80d40b45 100644
--- a/src/control/PathFind.cpp
+++ b/src/control/PathFind.cpp
@@ -18,21 +18,20 @@ CPathFind ThePaths;
#define MIN_PED_ROUTE_DISTANCE 23.8f
-#define NUMTEMPNODES 4000
-#define NUMDETACHED_CARS 100
-#define NUMDETACHED_PEDS 50
-
-
-// object flags:
-// 1 UseInRoadBlock
-// 2 east/west road(?)
+#define NUMTEMPNODES 5000
+#define NUMDETACHED_CARS 1024
+#define NUMDETACHED_PEDS 1214
+#define NUMTEMPEXTERNALNODES 4600
CPathInfoForObject *InfoForTileCars;
CPathInfoForObject *InfoForTilePeds;
-// unused
-CTempDetachedNode *DetachedNodesCars;
-CTempDetachedNode *DetachedNodesPeds;
+CPathInfoForObject *DetachedInfoForTileCars;
+CPathInfoForObject *DetachedInfoForTilePeds;
+CTempNodeExternal *TempExternalNodes;
+int32 NumTempExternalNodes;
+int32 NumDetachedPedNodeGroups;
+int32 NumDetachedCarNodeGroups;
bool
CPedPath::CalcPedRoute(int8 pathType, CVector position, CVector destination, CVector *pointPoses, int16 *pointsFound, int16 maxPoints)
@@ -197,7 +196,7 @@ CPedPath::AddBlockadeSectorList(CPtrList& list, CPedPathNode(*pathNodes)[40], CV
void
CPedPath::AddBlockade(CEntity *pEntity, CPedPathNode(*pathNodes)[40], CVector *pPosition)
{
- const CColBox& boundingBox = pEntity->GetColModel()->boundingBox;
+ const CBox& boundingBox = pEntity->GetColModel()->boundingBox;
const float fBoundMaxY = boundingBox.max.y + 0.3f;
const float fBoundMinY = boundingBox.min.y - 0.3f;
const float fBoundMaxX = boundingBox.max.x + 0.3f;
@@ -227,6 +226,25 @@ CPedPath::AddBlockade(CEntity *pEntity, CPedPathNode(*pathNodes)[40], CVector *p
}
}
+// Make sure all externals link TO an internal
+void
+CPathInfoForObject::SwapConnectionsToBeRightWayRound(void)
+{
+ int e, i;
+ CPathInfoForObject *tile = this;
+
+ for(e = 0; e < 12; e++)
+ if(tile[e].type == NodeTypeExtern && tile[e].next < 0)
+ for(i = 0; i < 12; i++)
+ if(tile[i].type == NodeTypeIntern && tile[i].next == e){
+ tile[e].next = i;
+ tile[i].next = -1;
+ bool tmp = !!tile[e].crossing;
+ tile[e].crossing = tile[i].crossing;
+ tile[i].crossing = tmp;
+ }
+}
+
void
CPathFind::Init(void)
{
@@ -237,6 +255,7 @@ CPathFind::Init(void)
m_numConnections = 0;
m_numCarPathLinks = 0;
unk = 0;
+ NumTempExternalNodes = 0;
for(i = 0; i < NUM_PATHNODES; i++)
m_pathNodes[i].distance = MAX_DIST;
@@ -250,21 +269,28 @@ CPathFind::AllocatePathFindInfoMem(int16 numPathGroups)
delete[] InfoForTilePeds;
InfoForTilePeds = nil;
- // NB: MIAMI doesn't use numPathGroups here but hardcodes 4500
- InfoForTileCars = new CPathInfoForObject[12*numPathGroups];
- memset(InfoForTileCars, 0, 12*numPathGroups*sizeof(CPathInfoForObject));
- InfoForTilePeds = new CPathInfoForObject[12*numPathGroups];
- memset(InfoForTilePeds, 0, 12*numPathGroups*sizeof(CPathInfoForObject));
-
- // unused
- delete[] DetachedNodesCars;
- DetachedNodesCars = nil;
- delete[] DetachedNodesPeds;
- DetachedNodesPeds = nil;
- DetachedNodesCars = new CTempDetachedNode[NUMDETACHED_CARS];
- memset(DetachedNodesCars, 0, NUMDETACHED_CARS*sizeof(CTempDetachedNode));
- DetachedNodesPeds = new CTempDetachedNode[NUMDETACHED_PEDS];
- memset(DetachedNodesPeds, 0, NUMDETACHED_PEDS*sizeof(CTempDetachedNode));
+ // NB: MIAMI doesn't use numPathGroups here but hardcodes PATHNODESIZE
+ InfoForTileCars = new CPathInfoForObject[12*PATHNODESIZE];
+ memset(InfoForTileCars, 0, 12*PATHNODESIZE*sizeof(CPathInfoForObject));
+ InfoForTilePeds = new CPathInfoForObject[12*PATHNODESIZE];
+ memset(InfoForTilePeds, 0, 12*PATHNODESIZE*sizeof(CPathInfoForObject));
+
+ delete[] DetachedInfoForTileCars;
+ DetachedInfoForTileCars = nil;
+ delete[] DetachedInfoForTilePeds;
+ DetachedInfoForTilePeds = nil;
+ DetachedInfoForTileCars = new CPathInfoForObject[12*NUMDETACHED_CARS];
+ memset(DetachedInfoForTileCars, 0, 12*NUMDETACHED_CARS*sizeof(CPathInfoForObject));
+ DetachedInfoForTilePeds = new CPathInfoForObject[12*NUMDETACHED_PEDS];
+ memset(DetachedInfoForTilePeds, 0, 12*NUMDETACHED_PEDS*sizeof(CPathInfoForObject));
+
+ delete[] TempExternalNodes;
+ TempExternalNodes = nil;
+ TempExternalNodes = new CTempNodeExternal[NUMTEMPEXTERNALNODES];
+ memset(TempExternalNodes, 0, NUMTEMPEXTERNALNODES*sizeof(CTempNodeExternal));
+ NumTempExternalNodes = 0;
+ NumDetachedPedNodeGroups = 0;
+ NumDetachedCarNodeGroups = 0;
}
void
@@ -274,66 +300,133 @@ CPathFind::RegisterMapObject(CTreadable *mapObject)
}
void
-CPathFind::StoreNodeInfoPed(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, int16 width, bool crossing)
+CPathFind::StoreNodeInfoPed(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, float width, bool crossing, uint8 spawnRate)
{
- int i, j;
+ int i;
i = id*12 + node;
InfoForTilePeds[i].type = type;
InfoForTilePeds[i].next = next;
- InfoForTilePeds[i].x = x;
- InfoForTilePeds[i].y = y;
- InfoForTilePeds[i].z = z;
+ InfoForTilePeds[i].x = x/16.0f;
+ InfoForTilePeds[i].y = y/16.0f;
+ InfoForTilePeds[i].z = z/16.0f;
+ InfoForTilePeds[i].width = 8.0f*Min(width, 15.0f);
InfoForTilePeds[i].numLeftLanes = 0;
InfoForTilePeds[i].numRightLanes = 0;
InfoForTilePeds[i].crossing = crossing;
-
- if(type)
- for(i = 0; i < node; i++){
- j = id*12 + i;
- if(x == InfoForTilePeds[j].x && y == InfoForTilePeds[j].y){
- printf("^^^^^^^^^^^^^ AARON IS TOO CHICKEN TO EAT MEAT!\n");
- printf("Several ped nodes on one road segment have identical coordinates (%d==%d && %d==%d)\n",
- x, InfoForTilePeds[j].x, y, InfoForTilePeds[j].y);
- printf("Modelindex of cullprit: %d\n\n", id);
- }
- }
+ InfoForTilePeds[i].speedLimit = 0;
+ InfoForTilePeds[i].roadBlock = false;
+ InfoForTilePeds[i].disabled = false;
+ InfoForTilePeds[i].waterPath = false;
+ InfoForTilePeds[i].onlySmallBoats = false;
+ InfoForTilePeds[i].betweenLevels = false;
+ InfoForTilePeds[i].spawnRate = Min(spawnRate, 15);
+
+ if(node == 11)
+ InfoForTilePeds[id*12].SwapConnectionsToBeRightWayRound();
}
void
-CPathFind::StoreNodeInfoCar(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, int16 width, int8 numLeft, int8 numRight)
+CPathFind::StoreNodeInfoCar(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, float width, int8 numLeft, int8 numRight,
+ bool disabled, bool betweenLevels, uint8 speedLimit, bool roadBlock, bool waterPath, uint8 spawnRate)
{
- int i, j;
+ int i;
i = id*12 + node;
InfoForTileCars[i].type = type;
InfoForTileCars[i].next = next;
- InfoForTileCars[i].x = x;
- InfoForTileCars[i].y = y;
- InfoForTileCars[i].z = z;
+ InfoForTileCars[i].x = x/16.0f;
+ InfoForTileCars[i].y = y/16.0f;
+ InfoForTileCars[i].z = z/16.0f;
+ InfoForTileCars[i].width = 8.0f*Min(width, 15.0f);
InfoForTileCars[i].numLeftLanes = numLeft;
InfoForTileCars[i].numRightLanes = numRight;
+ InfoForTileCars[i].crossing = false;
+ InfoForTileCars[i].speedLimit = 0;
+ InfoForTileCars[i].roadBlock = false;
+ InfoForTileCars[i].disabled = false;
+ InfoForTileCars[i].waterPath = false;
+ InfoForTileCars[i].onlySmallBoats = false;
+ InfoForTileCars[i].betweenLevels = false;
+ InfoForTileCars[i].spawnRate = Min(spawnRate, 15);
+
+ if(node == 11)
+ InfoForTileCars[id*12].SwapConnectionsToBeRightWayRound();
+}
+void
+CPathFind::StoreDetachedNodeInfoPed(int32 node, int8 type, int32 next, float x, float y, float z, float width, bool crossing,
+ bool disabled, bool betweenLevels, uint8 spawnRate)
+{
+ int i;
- if(type)
- for(i = 0; i < node; i++){
- j = id*12 + i;
- if(x == InfoForTileCars[j].x && y == InfoForTileCars[j].y){
- printf("^^^^^^^^^^^^^ AARON IS TOO CHICKEN TO EAT MEAT!\n");
- printf("Several car nodes on one road segment have identical coordinates (%d==%d && %d==%d)\n",
- x, InfoForTileCars[j].x, y, InfoForTileCars[j].y);
- printf("Modelindex of cullprit: %d\n\n", id);
- }
- }
+ if(NumDetachedPedNodeGroups >= NUMDETACHED_PEDS)
+ return;
+
+ i = NumDetachedPedNodeGroups*12 + node;
+ DetachedInfoForTilePeds[i].type = type;
+ DetachedInfoForTilePeds[i].next = next;
+ DetachedInfoForTilePeds[i].x = x/16.0f;
+ DetachedInfoForTilePeds[i].y = y/16.0f;
+ DetachedInfoForTilePeds[i].z = z/16.0f;
+ DetachedInfoForTilePeds[i].width = 8.0f*Min(width, 31.0f);
+ DetachedInfoForTilePeds[i].numLeftLanes = 0;
+ DetachedInfoForTilePeds[i].numRightLanes = 0;
+ DetachedInfoForTilePeds[i].crossing = crossing;
+ DetachedInfoForTilePeds[i].speedLimit = 0;
+ DetachedInfoForTilePeds[i].roadBlock = false;
+ DetachedInfoForTilePeds[i].disabled = disabled;
+ DetachedInfoForTilePeds[i].waterPath = false;
+ DetachedInfoForTilePeds[i].onlySmallBoats = false;
+ DetachedInfoForTilePeds[i].betweenLevels = betweenLevels;
+ DetachedInfoForTilePeds[i].spawnRate = Min(spawnRate, 15);
+
+ if(node == 11){
+ DetachedInfoForTilePeds[NumDetachedPedNodeGroups*12].SwapConnectionsToBeRightWayRound();
+ NumDetachedPedNodeGroups++;
+ }
}
void
-CPathFind::CalcNodeCoors(int16 x, int16 y, int16 z, int id, CVector *out)
+CPathFind::StoreDetachedNodeInfoCar(int32 node, int8 type, int32 next, float x, float y, float z, float width, int8 numLeft, int8 numRight,
+ bool disabled, bool betweenLevels, uint8 speedLimit, bool roadBlock, bool waterPath, uint8 spawnRate, bool onlySmallBoats)
+{
+ int i;
+
+ if(NumDetachedCarNodeGroups >= NUMDETACHED_CARS)
+ return;
+
+ i = NumDetachedCarNodeGroups*12 + node;
+ DetachedInfoForTileCars[i].type = type;
+ DetachedInfoForTileCars[i].next = next;
+ DetachedInfoForTileCars[i].x = x/16.0f;
+ DetachedInfoForTileCars[i].y = y/16.0f;
+ DetachedInfoForTileCars[i].z = z/16.0f;
+ DetachedInfoForTileCars[i].width = 8.0f*Min(width, 15.0f);
+ DetachedInfoForTileCars[i].numLeftLanes = numLeft;
+ DetachedInfoForTileCars[i].numRightLanes = numRight;
+ DetachedInfoForTileCars[i].crossing = false;
+ DetachedInfoForTileCars[i].speedLimit = speedLimit;
+ DetachedInfoForTileCars[i].roadBlock = roadBlock;
+ DetachedInfoForTileCars[i].disabled = disabled;
+ DetachedInfoForTileCars[i].waterPath = waterPath;
+ DetachedInfoForTileCars[i].onlySmallBoats = onlySmallBoats;
+ DetachedInfoForTileCars[i].betweenLevels = betweenLevels;
+ DetachedInfoForTileCars[i].spawnRate = Min(spawnRate, 15);
+
+ if(node == 11){
+ DetachedInfoForTileCars[NumDetachedCarNodeGroups*12].SwapConnectionsToBeRightWayRound();
+ NumDetachedCarNodeGroups++;
+ }
+}
+
+void
+CPathFind::CalcNodeCoors(float x, float y, float z, int id, CVector *out)
{
CVector pos;
- pos.x = x / 16.0f;
- pos.y = y / 16.0f;
- pos.z = z / 16.0f;
+ pos.x = x;
+ pos.y = y;
+ pos.z = z;
*out = m_mapObjects[id]->GetMatrix() * pos;
}
@@ -347,23 +440,18 @@ CPathFind::LoadPathFindData(void)
void
CPathFind::PreparePathData(void)
{
- int i, j, k;
- int numExtern, numIntern, numLanes;
- float maxX, maxY;
+ int i, j;
+ int numExtern, numIntern;
CTempNode *tempNodes;
printf("PreparePathData\n");
if(!CPathFind::LoadPathFindData() && // empty
InfoForTileCars && InfoForTilePeds &&
- DetachedNodesCars && DetachedNodesPeds
- ){
+ DetachedInfoForTileCars && DetachedInfoForTilePeds && TempExternalNodes){
tempNodes = new CTempNode[NUMTEMPNODES];
m_numConnections = 0;
- for(i = 0; i < PATHNODESIZE; i++)
- m_pathNodes[i].unkBits = 0;
-
for(i = 0; i < PATHNODESIZE; i++){
numExtern = 0;
numIntern = 0;
@@ -377,6 +465,19 @@ CPathFind::PreparePathData(void)
printf("ILLEGAL BLOCK. MORE THAN 1 INTERNALS AND NOT 2 EXTERNALS (Modelindex:%d)\n", i);
}
+ int numExternDetached, numInternDetached;
+ for(i = 0; i < NUMDETACHED_CARS; i++){
+ numExternDetached = 0;
+ numInternDetached = 0;
+ for(j = 0; j < 12; j++){
+ if(DetachedInfoForTileCars[i*12 + j].type == NodeTypeExtern)
+ numExternDetached++;
+ if(DetachedInfoForTilePeds[i*12 + j].type == NodeTypeIntern)
+ numInternDetached++;
+ }
+ // no diagnostic here
+ }
+
for(i = 0; i < PATHNODESIZE; i++)
for(j = 0; j < 12; j++)
if(InfoForTileCars[i*12 + j].type == NodeTypeExtern){
@@ -388,51 +489,24 @@ CPathFind::PreparePathData(void)
if(InfoForTileCars[i*12 + j].numLeftLanes + InfoForTileCars[i*12 + j].numRightLanes <= 0)
printf("ILLEGAL BLOCK. NO LANES IN NODE (Obj:%d)\n", i);
}
+ for(i = 0; i < NUMDETACHED_CARS; i++)
+ for(j = 0; j < 12; j++)
+ if(DetachedInfoForTileCars[i*12 + j].type == NodeTypeExtern){
+ // MI:%d here but no argument for it
+ if(DetachedInfoForTileCars[i*12 + j].numLeftLanes < 0)
+ printf("ILLEGAL BLOCK. NEGATIVE NUMBER OF LANES (Obj:%d)\n", i);
+ if(DetachedInfoForTileCars[i*12 + j].numRightLanes < 0)
+ printf("ILLEGAL BLOCK. NEGATIVE NUMBER OF LANES (Obj:%d)\n", i);
+ if(DetachedInfoForTileCars[i*12 + j].numLeftLanes + DetachedInfoForTileCars[i*12 + j].numRightLanes <= 0)
+ printf("ILLEGAL BLOCK. NO LANES IN NODE (Obj:%d)\n", i);
+ }
m_numPathNodes = 0;
- PreparePathDataForType(PATH_CAR, tempNodes, InfoForTileCars, 1.0f, DetachedNodesCars, NUMDETACHED_CARS);
+ PreparePathDataForType(PATH_CAR, tempNodes, InfoForTileCars, 1.0f, DetachedInfoForTileCars, NumDetachedCarNodeGroups);
m_numCarPathNodes = m_numPathNodes;
- PreparePathDataForType(PATH_PED, tempNodes, InfoForTilePeds, 1.0f, DetachedNodesPeds, NUMDETACHED_PEDS);
+ PreparePathDataForType(PATH_PED, tempNodes, InfoForTilePeds, 1.0f, DetachedInfoForTilePeds, NumDetachedPedNodeGroups);
m_numPedPathNodes = m_numPathNodes - m_numCarPathNodes;
- // TODO: figure out what exactly is going on here
- // Some roads seem to get a west/east flag
- for(i = 0; i < m_numMapObjects; i++){
- numExtern = 0;
- numIntern = 0;
- numLanes = 0;
- maxX = 0.0f;
- maxY = 0.0f;
- for(j = 0; j < 12; j++){
- k = m_mapObjects[i]->GetModelIndex()*12 + j;
- if(InfoForTileCars[k].type == NodeTypeExtern){
- numExtern++;
- numLanes = Max(numLanes, InfoForTileCars[k].numLeftLanes + InfoForTileCars[k].numRightLanes);
- maxX = Max(maxX, Abs(InfoForTileCars[k].x));
- maxY = Max(maxY, Abs(InfoForTileCars[k].y));
- }else if(InfoForTileCars[k].type == NodeTypeIntern)
- numIntern++;
- }
-
- if(numIntern == 1 && numExtern == 2){
- if(numLanes < 4){
- if((i & 7) == 4){ // 1/8 probability
- m_objectFlags[i] |= UseInRoadBlock;
- if(maxX > maxY)
- m_objectFlags[i] |= ObjectEastWest;
- else
- m_objectFlags[i] &= ~ObjectEastWest;
- }
- }else{
- m_objectFlags[i] |= UseInRoadBlock;
- if(maxX > maxY)
- m_objectFlags[i] |= ObjectEastWest;
- else
- m_objectFlags[i] &= ~ObjectEastWest;
- }
- }
- }
-
delete[] tempNodes;
CountFloodFillGroups(PATH_CAR);
@@ -443,10 +517,12 @@ CPathFind::PreparePathData(void)
delete[] InfoForTilePeds;
InfoForTilePeds = nil;
- delete[] DetachedNodesCars;
- DetachedNodesCars = nil;
- delete[] DetachedNodesPeds;
- DetachedNodesPeds = nil;
+ delete[] DetachedInfoForTileCars;
+ DetachedInfoForTileCars = nil;
+ delete[] DetachedInfoForTilePeds;
+ DetachedInfoForTilePeds = nil;
+ delete[] TempExternalNodes;
+ TempExternalNodes = nil;
}
printf("Done with PreparePathData\n");
}
@@ -493,8 +569,8 @@ CPathFind::CountFloodFillGroups(uint8 type)
if(node->numLinks == 0){
if(type == PATH_CAR)
- printf("Single car node: %f %f %f (%d)\n",
- node->GetX(), node->GetY(), node->GetZ(), m_mapObjects[node->objectIndex]->GetModelIndex());
+ printf("Single car node: %f %f %f\n",
+ node->GetX(), node->GetY(), node->GetZ());
else
printf("Single ped node: %f %f %f\n",
node->GetX(), node->GetY(), node->GetZ());
@@ -524,48 +600,28 @@ int32 TempListLength;
void
CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoForObject *objectpathinfo,
- float maxdist, CTempDetachedNode *detachednodes, int numDetached)
+ float maxdist, CPathInfoForObject *detachednodes, int numDetached)
{
static CVector CoorsXFormed;
- int i, j, k, l;
+ int i, j, k;
int l1, l2;
int start;
float posx, posy;
float dx, dy, mag;
float nearestDist;
int nearestId;
- int next;
int oldNumPathNodes, oldNumLinks;
float dist;
int iseg, jseg;
- int istart, jstart;
int done, cont;
int tileStart;
-#ifndef MASTER
- for (i = 0; i < m_numMapObjects-1; i++)
- for (j = i+1; j < m_numMapObjects; j++) {
- CTreadable *obj1 = m_mapObjects[i];
- CTreadable *obj2 = m_mapObjects[j];
- if (obj1->GetModelIndex() == obj2->GetModelIndex() &&
- obj1->GetPosition().x == obj2->GetPosition().x && obj1->GetPosition().y == obj2->GetPosition().y && obj1->GetPosition().z == obj2->GetPosition().z &&
- obj1->GetRight().x == obj2->GetRight().x && obj1->GetForward().x == obj2->GetForward().x && obj1->GetUp().x == obj2->GetUp().x &&
- obj1->GetRight().y == obj2->GetRight().y && obj1->GetForward().y == obj2->GetForward().y && obj1->GetUp().y == obj2->GetUp().y &&
- obj1->GetRight().z == obj2->GetRight().z && obj1->GetForward().z == obj2->GetForward().z && obj1->GetUp().z == obj2->GetUp().z) {
- printf("THIS IS VERY BAD INDEED. FIX IMMEDIATELY!!!\n");
- printf("Double road objects at the following coors: %f %f %f\n", obj1->GetPosition().x, obj1->GetPosition().y, obj1->GetPosition().z);
- }
- }
-#endif // !MASTER
-
oldNumPathNodes = m_numPathNodes;
oldNumLinks = m_numConnections;
-#define OBJECTINDEX(n) (m_pathNodes[(n)].objectIndex)
- // Initialize map objects
- for(i = 0; i < m_numMapObjects; i++)
- for(j = 0; j < 12; j++)
- m_mapObjects[i]->m_nodeIndices[type][j] = -1;
+#define OBJECTINDEX(n) (mapObjIndices[(n)])
+ int16 *mapObjIndices = new int16[NUM_PATHNODES];
+ NumTempExternalNodes = 0;
// Calculate internal nodes, store them and connect them to defining object
for(i = 0; i < m_numMapObjects; i++){
@@ -581,89 +637,125 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor
&CoorsXFormed);
m_pathNodes[m_numPathNodes].SetPosition(CoorsXFormed);
OBJECTINDEX(m_numPathNodes) = i;
- m_pathNodes[m_numPathNodes].unkBits = 1;
- m_mapObjects[i]->m_nodeIndices[type][j] = m_numPathNodes;
+ m_pathNodes[m_numPathNodes].width = objectpathinfo[start + j].width;
+ m_pathNodes[m_numPathNodes].speedLimit = objectpathinfo[start + j].speedLimit;
+ m_pathNodes[m_numPathNodes].spawnRate = objectpathinfo[start + j].spawnRate;
+ m_pathNodes[m_numPathNodes].bUseInRoadBlock = objectpathinfo[start + j].roadBlock;
+ m_pathNodes[m_numPathNodes].bDisabled = objectpathinfo[start + j].disabled;
+ m_pathNodes[m_numPathNodes].bWaterPath = objectpathinfo[start + j].waterPath;
+ m_pathNodes[m_numPathNodes].bOnlySmallBoats = objectpathinfo[start + j].onlySmallBoats;
+ m_pathNodes[m_numPathNodes].bBetweenLevels = objectpathinfo[start + j].betweenLevels;
m_numPathNodes++;
}
+ else if(objectpathinfo[start + j].type == NodeTypeExtern){
+ CalcNodeCoors(
+ objectpathinfo[start + j].x,
+ objectpathinfo[start + j].y,
+ objectpathinfo[start + j].z,
+ i,
+ &CoorsXFormed);
+ TempExternalNodes[NumTempExternalNodes].pos = CoorsXFormed;
+ assert(objectpathinfo[start + j].next >= 0);
+ TempExternalNodes[NumTempExternalNodes].next = tileStart + objectpathinfo[start + j].next;
+ TempExternalNodes[NumTempExternalNodes].numLeftLanes = objectpathinfo[start + j].numLeftLanes;
+ TempExternalNodes[NumTempExternalNodes].numRightLanes = objectpathinfo[start + j].numRightLanes;
+ TempExternalNodes[NumTempExternalNodes].width = objectpathinfo[start + j].width;
+ TempExternalNodes[NumTempExternalNodes].isCross = !!objectpathinfo[start + j].crossing;
+ NumTempExternalNodes++;
+ }
}
}
+ // Same thing for detached nodes
+ for(i = 0; i < numDetached; i++){
+ tileStart = m_numPathNodes;
+ start = 12*i;
+ for(j = 0; j < 12; j++){
+ if(detachednodes[start + j].type == NodeTypeIntern){
+ CVector pos;
+ pos.x = detachednodes[start + j].x;
+ pos.y = detachednodes[start + j].y;
+ pos.z = detachednodes[start + j].z;
+ m_pathNodes[m_numPathNodes].SetPosition(pos);
+ mapObjIndices[m_numPathNodes] = -(i+1);
+ m_pathNodes[m_numPathNodes].width = detachednodes[start + j].width;
+ m_pathNodes[m_numPathNodes].speedLimit = detachednodes[start + j].speedLimit;
+ m_pathNodes[m_numPathNodes].spawnRate = detachednodes[start + j].spawnRate;
+ m_pathNodes[m_numPathNodes].bUseInRoadBlock = detachednodes[start + j].roadBlock;
+ m_pathNodes[m_numPathNodes].bDisabled = detachednodes[start + j].disabled;
+ m_pathNodes[m_numPathNodes].bWaterPath = detachednodes[start + j].waterPath;
+ m_pathNodes[m_numPathNodes].bOnlySmallBoats = detachednodes[start + j].onlySmallBoats;
+ m_pathNodes[m_numPathNodes].bBetweenLevels = detachednodes[start + j].betweenLevels;
+ m_numPathNodes++;
+ }else if(detachednodes[start + j].type == NodeTypeExtern){
+ TempExternalNodes[NumTempExternalNodes].pos.x = detachednodes[start + j].x;
+ TempExternalNodes[NumTempExternalNodes].pos.y = detachednodes[start + j].y;
+ TempExternalNodes[NumTempExternalNodes].pos.z = detachednodes[start + j].z;
+ assert(detachednodes[start + j].next >= 0);
+ TempExternalNodes[NumTempExternalNodes].next = tileStart + detachednodes[start + j].next;
+ TempExternalNodes[NumTempExternalNodes].numLeftLanes = detachednodes[start + j].numLeftLanes;
+ TempExternalNodes[NumTempExternalNodes].numRightLanes = detachednodes[start + j].numRightLanes;
+ TempExternalNodes[NumTempExternalNodes].width = detachednodes[start + j].width;
+ TempExternalNodes[NumTempExternalNodes].isCross = !!detachednodes[start + j].crossing;
+ NumTempExternalNodes++;
+ }
+ }
+ }
// Insert external nodes into TempList
TempListLength = 0;
- for(i = 0; i < m_numMapObjects; i++){
- start = 12 * m_mapObjects[i]->GetModelIndex();
- for(j = 0; j < 12; j++){
- if(objectpathinfo[start + j].type != NodeTypeExtern)
+ for(i = 0; i < NumTempExternalNodes; i++){
+ // find closest unconnected node
+ nearestId = -1;
+ nearestDist = maxdist;
+ for(k = 0; k < TempListLength; k++){
+ if(tempnodes[k].linkState != 1)
continue;
- CalcNodeCoors(
- objectpathinfo[start + j].x,
- objectpathinfo[start + j].y,
- objectpathinfo[start + j].z,
- i,
- &CoorsXFormed);
-
- // find closest unconnected node
- nearestId = -1;
- nearestDist = maxdist;
- for(k = 0; k < TempListLength; k++){
- if(tempnodes[k].linkState != 1)
- continue;
- dx = tempnodes[k].pos.x - CoorsXFormed.x;
- if(Abs(dx) < nearestDist){
- dy = tempnodes[k].pos.y - CoorsXFormed.y;
- if(Abs(dy) < nearestDist){
- nearestDist = Max(Abs(dx), Abs(dy));
- nearestId = k;
- }
+ dx = tempnodes[k].pos.x - TempExternalNodes[i].pos.x;
+ if(Abs(dx) < nearestDist){
+ dy = tempnodes[k].pos.y - TempExternalNodes[i].pos.y;
+ if(Abs(dy) < nearestDist){
+ nearestDist = Max(Abs(dx), Abs(dy));
+ nearestId = k;
}
}
+ }
- if(nearestId < 0){
- // None found, add this one to temp list
- tempnodes[TempListLength].pos = CoorsXFormed;
- next = objectpathinfo[start + j].next;
- if(next < 0){
- // no link from this node, find link to this node
- next = 0;
- for(k = start; j != objectpathinfo[k].next; k++)
- next++;
- }
- // link to connecting internal node
- tempnodes[TempListLength].link1 = m_mapObjects[i]->m_nodeIndices[type][next];
- if(type == PATH_CAR){
- tempnodes[TempListLength].numLeftLanes = objectpathinfo[start + j].numLeftLanes;
- tempnodes[TempListLength].numRightLanes = objectpathinfo[start + j].numRightLanes;
- }
- tempnodes[TempListLength++].linkState = 1;
- }else{
- // Found nearest, connect it to our neighbour
- next = objectpathinfo[start + j].next;
- if(next < 0){
- // no link from this node, find link to this node
- next = 0;
- for(k = start; j != objectpathinfo[k].next; k++)
- next++;
- }
- tempnodes[nearestId].link2 = m_mapObjects[i]->m_nodeIndices[type][next];
- tempnodes[nearestId].linkState = 2;
-
- // collapse this node with nearest we found
- dx = m_pathNodes[tempnodes[nearestId].link1].GetX() - m_pathNodes[tempnodes[nearestId].link2].GetX();
- dy = m_pathNodes[tempnodes[nearestId].link1].GetY() - m_pathNodes[tempnodes[nearestId].link2].GetY();
- tempnodes[nearestId].pos = (tempnodes[nearestId].pos + CoorsXFormed)*0.5f;
- mag = Sqrt(dx*dx + dy*dy);
- tempnodes[nearestId].dirX = dx/mag;
- tempnodes[nearestId].dirY = dy/mag;
- // do something when number of lanes doesn't agree
- if(type == PATH_CAR)
- if(tempnodes[nearestId].numLeftLanes != 0 && tempnodes[nearestId].numRightLanes != 0 &&
- (objectpathinfo[start + j].numLeftLanes == 0 || objectpathinfo[start + j].numRightLanes == 0)){
- // why switch left and right here?
- tempnodes[nearestId].numLeftLanes = objectpathinfo[start + j].numRightLanes;
- tempnodes[nearestId].numRightLanes = objectpathinfo[start + j].numLeftLanes;
- }
+ if(nearestId < 0){
+ // None found, add this one to temp list
+ tempnodes[TempListLength].pos = TempExternalNodes[i].pos;
+ // link to connecting internal node
+ tempnodes[TempListLength].link1 = TempExternalNodes[i].next;
+ if(type == PATH_CAR){
+ tempnodes[TempListLength].numLeftLanes = TempExternalNodes[i].numLeftLanes;
+ tempnodes[TempListLength].numRightLanes = TempExternalNodes[i].numRightLanes;
}
+ tempnodes[TempListLength].width = TempExternalNodes[i].width;
+ tempnodes[TempListLength].isCross = TempExternalNodes[i].isCross;
+ tempnodes[TempListLength++].linkState = 1;
+ }else{
+ // Found nearest, connect it to our neighbour
+ tempnodes[nearestId].link2 = TempExternalNodes[i].next;
+ tempnodes[nearestId].linkState = 2;
+
+ // collapse this node with nearest we found
+ dx = m_pathNodes[tempnodes[nearestId].link1].GetX() - m_pathNodes[tempnodes[nearestId].link2].GetX();
+ dy = m_pathNodes[tempnodes[nearestId].link1].GetY() - m_pathNodes[tempnodes[nearestId].link2].GetY();
+ tempnodes[nearestId].pos = (tempnodes[nearestId].pos + TempExternalNodes[i].pos)*0.5f;
+ mag = Sqrt(dx*dx + dy*dy);
+ tempnodes[nearestId].dirX = dx/mag * 100;
+ tempnodes[nearestId].dirY = dy/mag * 100;
+ tempnodes[nearestId].width = Max(tempnodes[nearestId].width, TempExternalNodes[i].width);
+ if(TempExternalNodes[i].isCross)
+ tempnodes[nearestId].isCross = true; // TODO: is this guaranteed to be false otherwise?
+ // do something when number of lanes doesn't agree
+ if(type == PATH_CAR)
+ if(tempnodes[nearestId].numLeftLanes != 0 && tempnodes[nearestId].numRightLanes != 0 &&
+ (TempExternalNodes[i].numLeftLanes == 0 || TempExternalNodes[i].numRightLanes == 0)){
+ // why switch left and right here?
+ tempnodes[nearestId].numLeftLanes = TempExternalNodes[i].numRightLanes;
+ tempnodes[nearestId].numRightLanes = TempExternalNodes[i].numLeftLanes;
+ }
}
}
@@ -688,27 +780,30 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor
continue;
dist = (m_pathNodes[i].GetPosition() - m_pathNodes[ConnectedNode(m_numConnections)].GetPosition()).Magnitude();
- m_distances[m_numConnections] = dist;
- m_connectionFlags[m_numConnections].flags = 0;
+ m_distances[m_numConnections] = Min(dist, 255);
+ if(tempnodes[j].isCross)
+ m_connections[j] |= 0x8000; // crosses road flag
if(type == PATH_CAR){
// IMPROVE: use a goto here
// Find existing car path link
for(k = 0; k < m_numCarPathLinks; k++){
- if(m_carPathLinks[k].dir.x == tempnodes[j].dirX &&
- m_carPathLinks[k].dir.y == tempnodes[j].dirY &&
- m_carPathLinks[k].pos.x == tempnodes[j].pos.x &&
- m_carPathLinks[k].pos.y == tempnodes[j].pos.y){
+ if(m_carPathLinks[k].dirX == tempnodes[j].dirX &&
+ m_carPathLinks[k].dirY == tempnodes[j].dirY &&
+ m_carPathLinks[k].x == (int)(tempnodes[j].pos.x*8.0f) &&
+ m_carPathLinks[k].y == (int)(tempnodes[j].pos.y*8.0f)){
m_carPathConnections[m_numConnections] = k;
k = m_numCarPathLinks;
}
}
// k is m_numCarPathLinks+1 if we found one
if(k == m_numCarPathLinks){
- m_carPathLinks[m_numCarPathLinks].dir.x = tempnodes[j].dirX;
- m_carPathLinks[m_numCarPathLinks].dir.y = tempnodes[j].dirY;
- m_carPathLinks[m_numCarPathLinks].pos.x = tempnodes[j].pos.x;
- m_carPathLinks[m_numCarPathLinks].pos.y = tempnodes[j].pos.y;
+ m_carPathLinks[m_numCarPathLinks].dirX = tempnodes[j].dirX;
+ m_carPathLinks[m_numCarPathLinks].dirY = tempnodes[j].dirY;
+ m_carPathLinks[m_numCarPathLinks].x = tempnodes[j].pos.x*8.0f;
+ m_carPathLinks[m_numCarPathLinks].y = tempnodes[j].pos.y*8.0f;
+ m_carPathLinks[m_numCarPathLinks].trafficLightDirection = false;
+ m_carPathLinks[m_numCarPathLinks].width = tempnodes[j].width;
m_carPathLinks[m_numCarPathLinks].pathNodeIndex = i;
m_carPathLinks[m_numCarPathLinks].numLeftLanes = tempnodes[j].numLeftLanes;
m_carPathLinks[m_numCarPathLinks].numRightLanes = tempnodes[j].numRightLanes;
@@ -722,6 +817,18 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor
m_numConnections++;
}
+ CPathInfoForObject *tile;
+ if(mapObjIndices[i] < 0){
+ if(type == PATH_CAR)
+ tile = &DetachedInfoForTileCars[12 * (-1 - mapObjIndices[i])];
+ else
+ tile = &DetachedInfoForTilePeds[12 * (-1 - mapObjIndices[i])];
+ }else{
+ if(type == PATH_CAR)
+ tile = &InfoForTileCars[12 * m_mapObjects[mapObjIndices[i]]->GetModelIndex()];
+ else
+ tile = &InfoForTilePeds[12 * m_mapObjects[mapObjIndices[i]]->GetModelIndex()];
+ }
// Find i inside path segment
iseg = 0;
@@ -729,7 +836,6 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor
if(OBJECTINDEX(j) == OBJECTINDEX(i))
iseg++;
- istart = 12 * m_mapObjects[m_pathNodes[i].objectIndex]->GetModelIndex();
// Add links to other internal nodes
for(j = Max(oldNumPathNodes, i-12); j < Min(m_numPathNodes, i+12); j++){
if(OBJECTINDEX(i) != OBJECTINDEX(j) || i == j)
@@ -737,14 +843,13 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor
// N.B.: in every path segment, the externals have to be at the end
jseg = j-i + iseg;
- jstart = 12 * m_mapObjects[m_pathNodes[j].objectIndex]->GetModelIndex();
- if(objectpathinfo[istart + iseg].next == jseg ||
- objectpathinfo[jstart + jseg].next == iseg){
+ if(tile[iseg].next == jseg ||
+ tile[jseg].next == iseg){
// Found a link between i and jConnectionSetCrossesRoad
// NB this clears the flags in MIAMI
m_connections[m_numConnections] = j;
dist = (m_pathNodes[i].GetPosition() - m_pathNodes[j].GetPosition()).Magnitude();
- m_distances[m_numConnections] = dist;
+ m_distances[m_numConnections] = Min(dist, 255);
if(type == PATH_CAR){
posx = (m_pathNodes[i].GetX() + m_pathNodes[j].GetX())*0.5f;
@@ -754,6 +859,7 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor
mag = Sqrt(dx*dx + dy*dy);
dx /= mag;
dy /= mag;
+ uint8 width = Max(m_pathNodes[i].width, m_pathNodes[j].width);
if(i < j){
dx = -dx;
dy = -dy;
@@ -761,20 +867,22 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor
// IMPROVE: use a goto here
// Find existing car path link
for(k = 0; k < m_numCarPathLinks; k++){
- if(m_carPathLinks[k].dir.x == dx &&
- m_carPathLinks[k].dir.y == dy &&
- m_carPathLinks[k].pos.x == posx &&
- m_carPathLinks[k].pos.y == posy){
+ if(m_carPathLinks[k].dirX == (int)(dx*100.0f) &&
+ m_carPathLinks[k].dirY == (int)(dy*100.0f) &&
+ m_carPathLinks[k].x == (int)(posx*8.0f) &&
+ m_carPathLinks[k].y == (int)(posy*8.0f)){
m_carPathConnections[m_numConnections] = k;
k = m_numCarPathLinks;
}
}
// k is m_numCarPathLinks+1 if we found one
if(k == m_numCarPathLinks){
- m_carPathLinks[m_numCarPathLinks].dir.x = dx;
- m_carPathLinks[m_numCarPathLinks].dir.y = dy;
- m_carPathLinks[m_numCarPathLinks].pos.x = posx;
- m_carPathLinks[m_numCarPathLinks].pos.y = posy;
+ m_carPathLinks[m_numCarPathLinks].dirX = dx*100.0f;
+ m_carPathLinks[m_numCarPathLinks].dirY = dy*100.0f;
+ m_carPathLinks[m_numCarPathLinks].x = posx*8.0f;
+ m_carPathLinks[m_numCarPathLinks].y = posy*8.0f;
+ m_carPathLinks[m_numCarPathLinks].trafficLightDirection = false;
+ m_carPathLinks[m_numCarPathLinks].width = width;
m_carPathLinks[m_numCarPathLinks].pathNodeIndex = i;
m_carPathLinks[m_numCarPathLinks].numLeftLanes = -1;
m_carPathLinks[m_numCarPathLinks].numRightLanes = -1;
@@ -784,11 +892,9 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor
}
}else{
// Crosses road
- if(objectpathinfo[istart + iseg].next == jseg && objectpathinfo[istart + iseg].crossing ||
- objectpathinfo[jstart + jseg].next == iseg && objectpathinfo[jstart + jseg].crossing)
- m_connectionFlags[m_numConnections].bCrossesRoad = true;
- else
- m_connectionFlags[m_numConnections].bCrossesRoad = false;
+ if(tile[iseg].next == jseg && tile[iseg].crossing ||
+ tile[jseg].next == iseg && tile[jseg].crossing)
+ m_connections[m_numConnections] |= 0x8000; // crosses road flag
}
m_pathNodes[i].numLinks++;
@@ -801,7 +907,7 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor
done = 0;
// Set number of lanes for all nodes somehow
// very strange code
- for(k = 0; !done && k < 10; k++){
+ for(k = 0; !done && k < 12; k++){
done = 1;
for(i = 0; i < m_numPathNodes; i++){
if(m_pathNodes[i].numLinks != 2)
@@ -809,33 +915,50 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor
l1 = m_carPathConnections[m_pathNodes[i].firstLink];
l2 = m_carPathConnections[m_pathNodes[i].firstLink+1];
- if(m_carPathLinks[l1].numLeftLanes == -1 &&
- m_carPathLinks[l2].numLeftLanes != -1){
+ int8 l1Left = m_carPathLinks[l1].numLeftLanes;
+ int8 l1Right = m_carPathLinks[l1].numRightLanes;
+ int8 l2Left = m_carPathLinks[l2].numLeftLanes;
+ int8 l2Right = m_carPathLinks[l2].numRightLanes;
+ int8 *l1Leftp, *l1Rightp;
+ int8 *l2Leftp, *l2Rightp;
+ if(m_carPathLinks[l1].pathNodeIndex == i){
+ l1Leftp = &l1Left;
+ l1Rightp = &l1Right;
+ }else{
+ l1Leftp = &l1Right;
+ l1Rightp = &l1Left;
+ }
+ if(m_carPathLinks[l2].pathNodeIndex == i){
+ l2Leftp = &l2Left;
+ l2Rightp = &l2Right;
+ }else{
+ l2Leftp = &l2Right;
+ l2Rightp = &l2Left;
+ }
+ if(*l1Leftp == -1 && *l2Rightp != -1){
+ *l1Leftp = *l2Rightp;
done = 0;
- if(m_carPathLinks[l2].pathNodeIndex == i){
- // why switch left and right here?
- m_carPathLinks[l1].numLeftLanes = m_carPathLinks[l2].numRightLanes;
- m_carPathLinks[l1].numRightLanes = m_carPathLinks[l2].numLeftLanes;
- }else{
- m_carPathLinks[l1].numLeftLanes = m_carPathLinks[l2].numLeftLanes;
- m_carPathLinks[l1].numRightLanes = m_carPathLinks[l2].numRightLanes;
- }
- m_carPathLinks[l1].pathNodeIndex = i;
- }else if(m_carPathLinks[l1].numLeftLanes != -1 &&
- m_carPathLinks[l2].numLeftLanes == -1){
+ }
+ if(*l1Rightp == -1 && *l2Leftp != -1){
+ *l1Rightp = *l2Leftp;
done = 0;
- if(m_carPathLinks[l1].pathNodeIndex == i){
- // why switch left and right here?
- m_carPathLinks[l2].numLeftLanes = m_carPathLinks[l1].numRightLanes;
- m_carPathLinks[l2].numRightLanes = m_carPathLinks[l1].numLeftLanes;
- }else{
- m_carPathLinks[l2].numLeftLanes = m_carPathLinks[l1].numLeftLanes;
- m_carPathLinks[l2].numRightLanes = m_carPathLinks[l1].numRightLanes;
- }
- m_carPathLinks[l2].pathNodeIndex = i;
- }else if(m_carPathLinks[l1].numLeftLanes == -1 &&
- m_carPathLinks[l2].numLeftLanes == -1)
+ }
+ if(*l2Leftp == -1 && *l1Rightp != -1){
+ *l2Leftp = *l1Rightp;
+ done = 0;
+ }
+ if(*l2Rightp == -1 && *l1Leftp != -1){
+ *l2Rightp = *l1Leftp;
+ done = 0;
+ }
+ if(*l1Leftp == -1 && *l2Rightp == -1)
+ done = 0;
+ if(*l2Leftp == -1 && *l1Rightp == -1)
done = 0;
+ m_carPathLinks[l1].numLeftLanes = l1Left;
+ m_carPathLinks[l1].numRightLanes = l1Right;
+ m_carPathLinks[l2].numLeftLanes = l2Left;
+ m_carPathLinks[l2].numRightLanes = l2Right;
}
}
@@ -843,10 +966,10 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor
for(i = 0; i < m_numPathNodes; i++)
for(j = 0; j < m_pathNodes[i].numLinks; j++){
k = m_carPathConnections[m_pathNodes[i].firstLink + j];
- if(m_carPathLinks[k].numLeftLanes < 0)
- m_carPathLinks[k].numLeftLanes = 1;
- if(m_carPathLinks[k].numRightLanes < 0)
- m_carPathLinks[k].numRightLanes = 1;
+ if(m_carPathLinks[k].numLeftLanes == -1)
+ m_carPathLinks[k].numLeftLanes = 0;
+ if(m_carPathLinks[k].numRightLanes == -1)
+ m_carPathLinks[k].numRightLanes = 0;
}
}
@@ -855,8 +978,6 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor
do{
cont = 0;
for(i = 0; i < m_numPathNodes; i++){
- m_pathNodes[i].bDisabled = false;
- m_pathNodes[i].bBetweenLevels = false;
// See if node is a dead end, if so, we're not done yet
if(!m_pathNodes[i].bDeadEnd){
k = 0;
@@ -889,21 +1010,11 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor
m_connections[j] = node-1;
}
- // Also in treadables
- for(j = 0; j < m_numMapObjects; j++)
- for(k = 0; k < 12; k++){
- if(m_mapObjects[j]->m_nodeIndices[PATH_PED][k] == i){
- // remove this one
- for(l = k; l < 12-1; l++)
- m_mapObjects[j]->m_nodeIndices[PATH_PED][l] = m_mapObjects[j]->m_nodeIndices[PATH_PED][l+1];
- m_mapObjects[j]->m_nodeIndices[PATH_PED][11] = -1;
- }else if(m_mapObjects[j]->m_nodeIndices[PATH_PED][k] > i)
- m_mapObjects[j]->m_nodeIndices[PATH_PED][k]--;
- }
-
i--;
m_numPathNodes--;
}
+
+ delete[] mapObjIndices;
}
float
@@ -922,15 +1033,6 @@ CPathFind::CalcRoadDensity(float x, float y)
next = m_carPathConnections[m_pathNodes[i].firstLink + j];
density += m_carPathLinks[next].numLeftLanes * dist;
density += m_carPathLinks[next].numRightLanes * dist;
-
- if(m_carPathLinks[next].numLeftLanes < 0)
- printf("Link from object %d to %d (MIs)\n",
- m_mapObjects[m_pathNodes[i].objectIndex]->GetModelIndex(),
- m_mapObjects[m_pathNodes[ConnectedNode(m_pathNodes[i].firstLink + j)].objectIndex]->GetModelIndex());
- if(m_carPathLinks[next].numRightLanes < 0)
- printf("Link from object %d to %d (MIs)\n",
- m_mapObjects[m_pathNodes[i].objectIndex]->GetModelIndex(),
- m_mapObjects[m_pathNodes[ConnectedNode(m_pathNodes[i].firstLink + j)].objectIndex]->GetModelIndex());
}
}
}
@@ -990,6 +1092,7 @@ CPathFind::RemoveBadStartNode(CVector pos, CPathNode **nodes, int16 *n)
}
}
+#ifdef GTA_BRIDGE
void
CPathFind::SetLinksBridgeLights(float x1, float x2, float y1, float y2, bool enable)
{
@@ -1001,6 +1104,7 @@ CPathFind::SetLinksBridgeLights(float x1, float x2, float y1, float y2, bool ena
m_carPathLinks[i].bBridgeLights = enable;
}
}
+#endif
void
CPathFind::SwitchOffNodeAndNeighbours(int32 nodeId, bool disable)
@@ -1142,7 +1246,7 @@ CPathFind::PedMarkRoadsBetweenLevelsInArea(float x1, float x2, float y1, float y
}
int32
-CPathFind::FindNodeClosestToCoors(CVector coors, uint8 type, float distLimit, bool ignoreDisabled, bool ignoreBetweenLevels)
+CPathFind::FindNodeClosestToCoors(CVector coors, uint8 type, float distLimit, bool ignoreDisabled, bool ignoreBetweenLevels, bool ignoreSelected, bool bWaterPath)
{
int i;
int firstNode, lastNode;
@@ -1164,17 +1268,14 @@ CPathFind::FindNodeClosestToCoors(CVector coors, uint8 type, float distLimit, bo
for(i = firstNode; i < lastNode; i++){
if(ignoreDisabled && m_pathNodes[i].bDisabled) continue;
if(ignoreBetweenLevels && m_pathNodes[i].bBetweenLevels) continue;
- switch(m_pathNodes[i].unkBits){
- case 1:
- case 2:
- dist = Abs(m_pathNodes[i].GetX() - coors.x) +
- Abs(m_pathNodes[i].GetY() - coors.y) +
- 3.0f*Abs(m_pathNodes[i].GetZ() - coors.z);
- if(dist < closestDist){
- closestDist = dist;
- closestNode = i;
- }
- break;
+ if(ignoreSelected && m_pathNodes[i].bSelected) continue;
+ if(bWaterPath != m_pathNodes[i].bWaterPath) continue;
+ dist = Abs(m_pathNodes[i].GetX() - coors.x) +
+ Abs(m_pathNodes[i].GetY() - coors.y) +
+ 3.0f*Abs(m_pathNodes[i].GetZ() - coors.z);
+ if(dist < closestDist){
+ closestDist = dist;
+ closestNode = i;
}
}
return closestDist < distLimit ? closestNode : -1;
@@ -1202,25 +1303,116 @@ CPathFind::FindNodeClosestToCoorsFavourDirection(CVector coors, uint8 type, floa
}
for(i = firstNode; i < lastNode; i++){
- switch(m_pathNodes[i].unkBits){
- case 1:
- case 2:
- dX = m_pathNodes[i].GetX() - coors.x;
- dY = m_pathNodes[i].GetY() - coors.y;
- dist = Abs(dX) + Abs(dY) +
- 3.0f*Abs(m_pathNodes[i].GetZ() - coors.z);
+ dX = m_pathNodes[i].GetX() - coors.x;
+ dY = m_pathNodes[i].GetY() - coors.y;
+ dist = Abs(dX) + Abs(dY) +
+ 3.0f*Abs(m_pathNodes[i].GetZ() - coors.z);
+ if(dist < closestDist){
+ NormalizeXY(dX, dY);
+ dist -= (dX*dirX + dY*dirY - 1.0f)*20.0f;
if(dist < closestDist){
- NormalizeXY(dX, dY);
- dist -= (dX*dirX + dY*dirY - 1.0f)*20.0f;
- if(dist < closestDist){
+ closestDist = dist;
+ closestNode = i;
+ }
+ }
+ }
+ return closestNode;
+}
+
+void
+CPathFind::FindNodePairClosestToCoors(CVector coors, uint8 type, int* node1, int* node2, float* angle, float minDist, float maxDist, bool ignoreDisabled, bool ignoreBetweenLevels, bool bWaterPath)
+{
+ int i, j;
+ int firstNode, lastNode, connectedNode;
+ float dist;
+ float closestDist = 10000.0f;
+ int closestNode = 0, closestConnectedNode = 0;
+
+ switch (type) {
+ case PATH_CAR:
+ firstNode = 0;
+ lastNode = m_numCarPathNodes;
+ break;
+ case PATH_PED:
+ firstNode = m_numCarPathNodes;
+ lastNode = m_numPathNodes;
+ break;
+ }
+
+ for (i = firstNode; i < lastNode; i++) {
+ if (ignoreDisabled && m_pathNodes[i].bDisabled) continue;
+ if (ignoreBetweenLevels && m_pathNodes[i].bBetweenLevels) continue;
+ if (bWaterPath != m_pathNodes[i].bWaterPath) continue;
+ dist = Abs(m_pathNodes[i].GetX() - coors.x) +
+ Abs(m_pathNodes[i].GetY() - coors.y) +
+ 3.0f * Abs(m_pathNodes[i].GetZ() - coors.z);
+ if (dist < closestDist) {
+ for (j = 0; j < m_pathNodes[i].numLinks; j++) {
+ connectedNode = ConnectedNode(m_pathNodes[i].firstLink + j);
+ if (ignoreDisabled && m_pathNodes[connectedNode].bDisabled) continue;
+ if (ignoreBetweenLevels && m_pathNodes[connectedNode].bBetweenLevels) continue;
+ if (bWaterPath != m_pathNodes[connectedNode].bWaterPath) continue;
+ if ((m_pathNodes[connectedNode].GetPosition() - m_pathNodes[i].GetPosition()).Magnitude() > minDist) {
closestDist = dist;
closestNode = i;
+ closestConnectedNode = connectedNode;
}
}
- break;
}
}
- return closestNode;
+ if (closestDist < maxDist) {
+ *node1 = closestNode;
+ *node2 = closestConnectedNode;
+ CVector dir(m_pathNodes[*node2].GetX() - m_pathNodes[*node1].GetX(), m_pathNodes[*node2].GetY() - m_pathNodes[*node1].GetY(), 0.0f);
+ dir.Normalise();
+ *angle = RADTODEG(Atan2(-dir.x, dir.y));
+ }
+ else {
+ *node1 = -1;
+ *node2 = -1;
+ *angle = 0.0f;
+ }
+}
+
+int32
+CPathFind::FindNthNodeClosestToCoors(CVector coors, uint8 type, float distLimit, bool ignoreDisabled, bool ignoreBetweenLevels, int N, bool bWaterPath)
+{
+ int i;
+ int firstNode, lastNode;
+ switch (type) {
+ case PATH_CAR:
+ firstNode = 0;
+ lastNode = m_numCarPathNodes;
+ break;
+ case PATH_PED:
+ firstNode = m_numCarPathNodes;
+ lastNode = m_numPathNodes;
+ break;
+ }
+ for (i = firstNode; i < lastNode; i++)
+ m_pathNodes[i].bSelected = false;
+
+ for (; N > 0; N--) {
+ i = FindNodeClosestToCoors(coors, type, distLimit, ignoreDisabled, ignoreBetweenLevels, true, bWaterPath);
+ if (i < 0)
+ return -1;
+ m_pathNodes[i].bSelected = true;
+ }
+ return FindNodeClosestToCoors(coors, type, distLimit, ignoreDisabled, ignoreBetweenLevels, true, bWaterPath);
+}
+
+CVector
+CPathFind::FindNodeCoorsForScript(int32 id)
+{
+ // the point is to return valid position in case there is a divider in the middle of the road
+ if (!m_pathNodes[id].HasDivider() || m_pathNodes[id].numLinks == 0)
+ return m_pathNodes[id].GetPosition();
+ CVector2D dir(m_pathNodes[ConnectedNode(m_pathNodes[id].firstLink)].GetX() - m_pathNodes[id].GetX(),
+ m_pathNodes[ConnectedNode(m_pathNodes[id].firstLink)].GetY() - m_pathNodes[id].GetY());
+ dir.Normalise();
+ if (dir.x < 0)
+ dir = -dir;
+ return m_pathNodes[id].GetPosition() + CVector(-dir.y, dir.x, 0.0f) * (LANE_WIDTH / 2 + m_pathNodes[id].GetDividerWidth());
}
float
@@ -1278,7 +1470,7 @@ CPathFind::FindNodeOrientationForCarPlacementFacingDestination(int32 nodeId, flo
}
bool
-CPathFind::NewGenerateCarCreationCoors(float x, float y, float dirX, float dirY, float spawnDist, float angleLimit, bool forward, CVector *pPosition, int32 *pNode1, int32 *pNode2, float *pPositionBetweenNodes, bool ignoreDisabled)
+CPathFind::GenerateCarCreationCoors(float x, float y, float dirX, float dirY, float spawnDist, float angleLimit, bool forward, CVector *pPosition, int32 *pNode1, int32 *pNode2, float *pPositionBetweenNodes, bool ignoreDisabled)
{
int i, j;
int node1, node2;
@@ -1292,14 +1484,14 @@ CPathFind::NewGenerateCarCreationCoors(float x, float y, float dirX, float dirY,
if(m_pathNodes[node1].bDisabled && !ignoreDisabled)
continue;
dist1 = Distance2D(m_pathNodes[node1].GetPosition(), x, y);
- if(dist1 < spawnDist + 60.0f){
- d1 = dist1 - spawnDist;
+ if(dist1 < Max(spawnDist + 70.0f, spawnDist * 1.7f)){
+ d1 = m_pathNodes[node1].bWaterPath ? (dist1 - spawnDist * 1.5f) : (dist1 - spawnDist);
for(j = 0; j < m_pathNodes[node1].numLinks; j++){
node2 = ConnectedNode(m_pathNodes[node1].firstLink + j);
if(m_pathNodes[node2].bDisabled && !ignoreDisabled)
continue;
dist2 = Distance2D(m_pathNodes[node2].GetPosition(), x, y);
- d2 = dist2 - spawnDist;
+ d2 = m_pathNodes[node2].bWaterPath ? (dist2 - spawnDist * 1.5f) : (dist2 - spawnDist);
if(d1*d2 < 0.0f){
// nodes are on different sides of spawn distance
float f2 = Abs(d1)/(Abs(d1) + Abs(d2));
@@ -1336,94 +1528,76 @@ CPathFind::GeneratePedCreationCoors(float x, float y, float minDist, float maxDi
{
int i;
int node1, node2;
+ float node1_dist, node2_dist;
+ static int32 node_cnt;
if(m_numPedPathNodes == 0)
return false;
- for(i = 0; i < 400; i++){
- node1 = m_numCarPathNodes + CGeneral::GetRandomNumber() % m_numPedPathNodes;
- if(DistanceSqr2D(m_pathNodes[node1].GetPosition(), x, y) < sq(maxDist+30.0f)){
- if(m_pathNodes[node1].numLinks == 0)
- continue;
- int link = m_pathNodes[node1].firstLink + CGeneral::GetRandomNumber() % m_pathNodes[node1].numLinks;
- if(ConnectionCrossesRoad(link))
- continue;
- node2 = ConnectedNode(link);
- if(m_pathNodes[node1].bDisabled || m_pathNodes[node2].bDisabled)
- continue;
-
- float f2 = (CGeneral::GetRandomNumber()&0xFF)/256.0f;
- float f1 = 1.0f - f2;
- *pPositionBetweenNodes = f2;
- CVector pos = m_pathNodes[node1].GetPosition()*f1 + m_pathNodes[node2].GetPosition()*f2;
- if(Distance2D(pos, x, y) < maxDist+20.0f){
- pos.x += ((CGeneral::GetRandomNumber()&0xFF)-128)*0.01f;
- pos.y += ((CGeneral::GetRandomNumber()&0xFF)-128)*0.01f;
- float dist = Distance2D(pos, x, y);
-
- bool visible;
- if(camMatrix)
- visible = TheCamera.IsSphereVisible(pos, 2.0f, camMatrix);
- else
- visible = TheCamera.IsSphereVisible(pos, 2.0f);
- if(!visible){
- minDist = minDistOffScreen;
- maxDist = maxDistOffScreen;
- }
- if(minDist < dist && dist < maxDist){
- *pNode1 = node1;
- *pNode2 = node2;
- *pPosition = pos;
-
- bool found;
- float groundZ = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z+2.0f, &found);
- if(!found)
- return false;
- if(Abs(groundZ - pos.z) > 3.0f)
- return false;
- pPosition->z = groundZ;
- return true;
- }
- }
+ for(i = 0; i < 230; i++){
+ if (node_cnt++ >= m_numPedPathNodes)
+ node_cnt = 0;
+ node1 = node_cnt + m_numCarPathNodes;
+ node1_dist = Distance2D(m_pathNodes[node1].GetPosition(), x, y);
+ if(node1_dist < maxDist+30.0f){
+ if(m_pathNodes[node1].numLinks != 0)
+ break;
}
}
- return false;
-}
-
-CTreadable*
-CPathFind::FindRoadObjectClosestToCoors(CVector coors, uint8 type)
-{
- int i, j, k;
- int node1, node2;
- CTreadable *closestMapObj = nil;
- float closestDist = 10000.0f;
+ if (i >= 230)
+ return false;
- for(i = 0; i < m_numMapObjects; i++){
- CTreadable *mapObj = m_mapObjects[i];
- if(mapObj->m_nodeIndices[type][0] < 0)
+ for(i = 0; i < m_pathNodes[node1].numLinks; i++){
+ int link = m_pathNodes[node1].firstLink + i;
+ if(ConnectionCrossesRoad(link))
continue;
- CVector vDist = mapObj->GetPosition() - coors;
- float fDist = Abs(vDist.x) + Abs(vDist.y) + Abs(vDist.z);
- if(fDist < 200.0f || fDist < closestDist)
- for(j = 0; j < 12; j++){
- node1 = mapObj->m_nodeIndices[type][j];
- if(node1 < 0)
- break;
- // FIX: game uses ThePaths here explicitly
- for(k = 0; k < m_pathNodes[node1].numLinks; k++){
- node2 = ConnectedNode(m_pathNodes[node1].firstLink + k);
- float lineDist = CCollision::DistToLine(&m_pathNodes[node1].GetPosition(), &m_pathNodes[node2].GetPosition(), &coors);
- if(lineDist < closestDist){
- closestDist = lineDist;
- if((coors - m_pathNodes[node1].GetPosition()).MagnitudeSqr() < (coors - m_pathNodes[node2].GetPosition()).MagnitudeSqr())
- closestMapObj = m_mapObjects[m_pathNodes[node1].objectIndex];
- else
- closestMapObj = m_mapObjects[m_pathNodes[node2].objectIndex];
- }
- }
+ node2 = ConnectedNode(link);
+ if(m_pathNodes[node1].bDisabled || m_pathNodes[node2].bDisabled)
+ continue;
+ node2_dist = Distance2D(m_pathNodes[node2].GetPosition(), x, y);
+ if ((node1_dist < maxDist || node2_dist < maxDist) && (node1_dist > minDistOffScreen || node2_dist > minDistOffScreen))
+ break;
+ }
+ if(i >= m_pathNodes[node1].numLinks)
+ return false;
+
+ for(i = 0; i < 5; i++){
+ float f2 = (CGeneral::GetRandomNumber()&0xFF)/256.0f;
+ float f1 = 1.0f - f2;
+ *pPositionBetweenNodes = f2;
+ CVector pos = m_pathNodes[node1].GetPosition()*f1 + m_pathNodes[node2].GetPosition()*f2;
+ if(Distance2D(pos, x, y) < maxDist+20.0f){
+ pos.x += ((CGeneral::GetRandomNumber()&0xFF)-128)*0.01f;
+ pos.y += ((CGeneral::GetRandomNumber()&0xFF)-128)*0.01f;
+ float dist = Distance2D(pos, x, y);
+
+ bool visible;
+ if(camMatrix)
+ visible = TheCamera.IsSphereVisible(pos, 2.0f, camMatrix);
+ else
+ visible = TheCamera.IsSphereVisible(pos, 2.0f);
+ if(!visible){
+ minDist = minDistOffScreen;
+ maxDist = maxDistOffScreen;
+ }
+ if(visible && (minDist < dist && dist < maxDist) ||
+ !visible && (minDistOffScreen < dist && dist < maxDistOffScreen)){
+ *pNode1 = node1;
+ *pNode2 = node2;
+ *pPosition = pos;
+
+ bool found;
+ float groundZ = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z+2.0f, &found);
+ if(!found)
+ return false;
+ if(Abs(groundZ - pos.z) > 3.0f)
+ return false;
+ pPosition->z = groundZ;
+ return true;
}
+ }
}
- return closestMapObj;
+ return false;
}
void
@@ -1433,19 +1607,8 @@ CPathFind::FindNextNodeWandering(uint8 type, CVector coors, CPathNode **lastNode
CPathNode *node;
if(lastNode == nil || (node = *lastNode) == nil || (coors - (*lastNode)->GetPosition()).MagnitudeSqr() > 7.0f){
- // need to find the node we're coming from
- node = nil;
- CTreadable *obj = FindRoadObjectClosestToCoors(coors, type);
- float nodeDist = 1000000000.0f;
- for(i = 0; i < 12; i++){
- if(obj->m_nodeIndices[type][i] < 0)
- break;
- float dist = (coors - m_pathNodes[obj->m_nodeIndices[type][i]].GetPosition()).MagnitudeSqr();
- if(dist < nodeDist){
- nodeDist = dist;
- node = &m_pathNodes[obj->m_nodeIndices[type][i]];
- }
- }
+ int32 nodeIdx = FindNodeClosestToCoors(coors, type, 999999.88f);
+ node = &m_pathNodes[nodeIdx];
}
CVector2D vCurDir(Sin(curDir*PI/4.0f), Cos(curDir * PI / 4.0f));
@@ -1501,7 +1664,7 @@ CPathFind::FindNextNodeWandering(uint8 type, CVector coors, CPathNode **lastNode
}
}
-static CPathNode *apNodesToBeCleared[4995];
+static CPathNode *apNodesToBeCleared[6525];
void
CPathFind::DoPathSearch(uint8 type, CVector start, int32 startNodeId, CVector target, CPathNode **nodes, int16 *pNumNodes, int16 maxNumNodes, CVehicle *vehicle, float *pDist, float distLimit, int32 targetNodeId)
@@ -1518,42 +1681,22 @@ CPathFind::DoPathSearch(uint8 type, CVector start, int32 startNodeId, CVector ta
}
// Find start
- int numPathsToTry;
- CTreadable *startObj;
- if(startNodeId < 0){
- if(vehicle == nil || (startObj = vehicle->m_treadable[type]) == nil)
- startObj = FindRoadObjectClosestToCoors(start, type);
- numPathsToTry = 0;
- for(i = 0; i < 12; i++){
- if(startObj->m_nodeIndices[type][i] < 0)
- break;
- if(m_pathNodes[startObj->m_nodeIndices[type][i]].group == m_pathNodes[targetNodeId].group)
- numPathsToTry++;
- }
- }else{
- numPathsToTry = 1;
- startObj = m_mapObjects[m_pathNodes[startNodeId].objectIndex];
- }
- if(numPathsToTry == 0) {
+ if(startNodeId < 0)
+ startNodeId = FindNodeClosestToCoors(start, type, 999999.88f);
+ if(startNodeId < 0) {
*pNumNodes = 0;
if(pDist) *pDist = 100000.0f;
return;
}
-
- if(startNodeId < 0){
- // why only check node 0?
- if(m_pathNodes[startObj->m_nodeIndices[type][0]].group !=
- m_pathNodes[targetNodeId].group) {
- *pNumNodes = 0;
- if(pDist) *pDist = 100000.0f;
- return;
- }
- }else{
- if(m_pathNodes[startNodeId].group != m_pathNodes[targetNodeId].group) {
- *pNumNodes = 0;
- if(pDist) *pDist = 100000.0f;
- return;
- }
+ if(startNodeId == targetNodeId){
+ *pNumNodes = 0;
+ if(pDist) *pDist = 0.0f;
+ return;
+ }
+ if(m_pathNodes[startNodeId].group != m_pathNodes[targetNodeId].group) {
+ *pNumNodes = 0;
+ if(pDist) *pDist = 100000.0f;
+ return;
}
for(i = 0; i < ARRAY_SIZE(m_searchNodes); i++)
@@ -1565,14 +1708,11 @@ CPathFind::DoPathSearch(uint8 type, CVector start, int32 startNodeId, CVector ta
// Dijkstra's algorithm
// Find distances
int numPathsFound = 0;
- if(startNodeId < 0 && m_mapObjects[m_pathNodes[targetNodeId].objectIndex] == startObj)
- numPathsFound++;
- for(i = 0; numPathsFound < numPathsToTry; i = (i+1) & 0x1FF){
+ for(i = 0; numPathsFound == 0; i = (i+1) & 0x1FF){
CPathNode *node;
for(node = m_searchNodes[i].GetNext(); node; node = node->GetNext()){
- if(m_mapObjects[node->objectIndex] == startObj &&
- (startNodeId < 0 || node == &m_pathNodes[startNodeId]))
- numPathsFound++;
+ if(node == &m_pathNodes[startNodeId])
+ numPathsFound = 1;
for(j = 0; j < node->numLinks; j++){
int next = ConnectedNode(node->firstLink + j);
@@ -1592,34 +1732,12 @@ CPathFind::DoPathSearch(uint8 type, CVector start, int32 startNodeId, CVector ta
// Find out whence to start tracing back
CPathNode *curNode;
- if(startNodeId < 0){
- int minDist = MAX_DIST;
- *pNumNodes = 1;
- for(i = 0; i < 12; i++){
- if(startObj->m_nodeIndices[type][i] < 0)
- break;
- int dist = (m_pathNodes[startObj->m_nodeIndices[type][i]].GetPosition() - start).Magnitude();
- if(m_pathNodes[startObj->m_nodeIndices[type][i]].distance + dist < minDist){
- minDist = m_pathNodes[startObj->m_nodeIndices[type][i]].distance + dist;
- curNode = &m_pathNodes[startObj->m_nodeIndices[type][i]];
- }
- }
- if(maxNumNodes == 0){
- *pNumNodes = 0;
- }else{
- nodes[0] = curNode;
- *pNumNodes = 1;
- }
- if(pDist)
- *pDist = minDist;
- }else
- {
- curNode = &m_pathNodes[startNodeId];
- *pNumNodes = 0;
- if(pDist)
- *pDist = m_pathNodes[startNodeId].distance;
- }
+ curNode = &m_pathNodes[startNodeId];
+ *pNumNodes = 0;
+ if(pDist)
+ *pDist = m_pathNodes[startNodeId].distance;
+ nodes[(*pNumNodes)++] = curNode;
// Trace back to target and update list of nodes
while(*pNumNodes < maxNumNodes && curNode != &m_pathNodes[targetNodeId])
for(i = 0; i < curNode->numLinks; i++){
@@ -1633,7 +1751,6 @@ CPathFind::DoPathSearch(uint8 type, CVector start, int32 startNodeId, CVector ta
for(i = 0; i < numNodesToBeCleared; i++)
apNodesToBeCleared[i]->distance = MAX_DIST;
- return;
}
static CPathNode *pNodeList[32];
@@ -1652,12 +1769,12 @@ CPathFind::TestCoorsCloseness(CVector target, uint8 type, CVector start)
#ifdef FIX_BUGS
// dist has GenerationDistMultiplier as a factor, so our reference dist should have it too
if(type == PATH_CAR)
- return dist < 160.0f*TheCamera.GenerationDistMultiplier;
+ return dist < 150.0f*TheCamera.GenerationDistMultiplier;
else
return dist < 100.0f*TheCamera.GenerationDistMultiplier;
#else
if(type == PATH_CAR)
- return dist < 160.0f;
+ return dist < 150.0f;
else
return dist < 100.0f;
#endif
@@ -1701,6 +1818,12 @@ CPathFind::Load(uint8 *buf, uint32 size)
m_pathNodes[i].bBetweenLevels = true;
else
m_pathNodes[i].bBetweenLevels = false;
+
+#ifdef SECUROM
+ // if pirated game
+ for(i = 0; i < m_numPathNodes; i++)
+ m_pathNodes[i].bDisabled = true;
+#endif
}
void
@@ -1828,3 +1951,39 @@ CPathFind::DisplayPathData(void)
}
}
}
+
+CVector
+CPathFind::TakeWidthIntoAccountForWandering(CPathNode* nextNode, uint16 random)
+{
+ CVector pos = nextNode->GetPosition();
+ float newX = (nextNode->GetPedNodeWidth() * ((random % 16) - 7)) + pos.x;
+ float newY = (nextNode->GetPedNodeWidth() * (((random / 16) % 16) - 7)) + pos.y;
+ return CVector(newX, newY, pos.z);
+}
+
+void
+CPathFind::TakeWidthIntoAccountForCoors(CPathNode* node1, CPathNode* node2, uint16 random, float* x, float* y)
+{
+ *x += (Min(node1->width, node2->width) * WIDTH_TO_PED_NODE_WIDTH * ((random % 16) - 7));
+ *y += (Min(node1->width, node2->width) * WIDTH_TO_PED_NODE_WIDTH * (((random / 16) % 16) - 7));
+}
+
+CPathNode*
+CPathFind::GetNode(int16 index)
+{
+ if(index < 0)
+ return nil;
+ if(index < ARRAY_SIZE(ThePaths.m_searchNodes))
+ return &ThePaths.m_searchNodes[index];
+ return &ThePaths.m_pathNodes[index - ARRAY_SIZE(ThePaths.m_searchNodes)];
+}
+int16
+CPathFind::GetIndex(CPathNode *node)
+{
+ if(node == nil)
+ return -1;
+ if(node >= &ThePaths.m_searchNodes[0] && node < &ThePaths.m_searchNodes[ARRAY_SIZE(ThePaths.m_searchNodes)])
+ return node - ThePaths.m_searchNodes;
+ else
+ return (node - ThePaths.m_pathNodes) + ARRAY_SIZE(ThePaths.m_searchNodes);
+}
diff --git a/src/control/PathFind.h b/src/control/PathFind.h
index bbfdf7b7..99759590 100644
--- a/src/control/PathFind.h
+++ b/src/control/PathFind.h
@@ -5,13 +5,13 @@
class CVehicle;
class CPtrList;
+#define LANE_WIDTH 5.0f
+#define WIDTH_TO_PED_NODE_WIDTH (31.f/(500.f * 8.f))
+
enum
{
NodeTypeExtern = 1,
NodeTypeIntern = 2,
-
- UseInRoadBlock = 1,
- ObjectEastWest = 2,
};
enum
@@ -52,35 +52,51 @@ public:
static void AddNodeToList(CPedPathNode *pNode, int16 index, CPedPathNode *pList);
static void AddBlockade(CEntity *pEntity, CPedPathNode(*pathNodes)[40], CVector *pPosition);
static void AddBlockadeSectorList(CPtrList& list, CPedPathNode(*pathNodes)[40], CVector *pPosition);
+ static void AddBuildingBlockade(CEntity*, CPedPathNode(*)[40], CVector*);
+ static void AddBuildingBlockadeSectorList(CPtrList&, CPedPathNode(*)[40], CVector*);
};
struct CPathNode
{
- CVector pos;
- CPathNode *prev;
- CPathNode *next;
+ int16 prevIndex;
+ int16 nextIndex;
+ int16 x;
+ int16 y;
+ int16 z;
int16 distance; // in path search
- int16 objectIndex;
int16 firstLink;
- uint8 numLinks;
+ uint8 width;
+ int8 group;
- uint8 unkBits : 2;
+ uint8 numLinks : 4;
uint8 bDeadEnd : 1;
uint8 bDisabled : 1;
uint8 bBetweenLevels : 1;
-
- int8 group;
-
- CVector &GetPosition(void) { return pos; }
- void SetPosition(const CVector &p) { pos = p; }
- float GetX(void) { return pos.x; }
- float GetY(void) { return pos.y; }
- float GetZ(void) { return pos.z; }
-
- CPathNode *GetPrev(void) { return prev; }
- CPathNode *GetNext(void) { return next; }
- void SetPrev(CPathNode *node) { prev = node; }
- void SetNext(CPathNode *node) { next = node; }
+ uint8 bUseInRoadBlock : 1;
+
+ uint8 bWaterPath : 1;
+ uint8 bOnlySmallBoats : 1;
+ uint8 bSelected : 1;
+ uint8 speedLimit : 2;
+ //uint8 flagB20 : 1;
+ //uint8 flagB40 : 1;
+ //uint8 flagB80 : 1;
+
+ uint8 spawnRate : 4;
+ uint8 flagsC : 4;
+
+ CVector GetPosition(void) { return CVector(x/8.0f, y/8.0f, z/8.0f); }
+ void SetPosition(const CVector &p) { x = p.x*8.0f; y = p.y*8.0f; z = p.z*8.0f; }
+ float GetX(void) { return x/8.0f; }
+ float GetY(void) { return y/8.0f; }
+ float GetZ(void) { return z/8.0f; }
+ bool HasDivider(void) { return width != 0; }
+ float GetDividerWidth(void) { return width/(2*8.0f); }
+ float GetPedNodeWidth(void) { return width*WIDTH_TO_PED_NODE_WIDTH; }
+ CPathNode *GetPrev(void);
+ CPathNode *GetNext(void);
+ void SetPrev(CPathNode *node);
+ void SetNext(CPathNode *node);
};
union CConnectionFlags
@@ -94,22 +110,25 @@ union CConnectionFlags
struct CCarPathLink
{
- CVector2D pos;
- CVector2D dir;
+ int16 x;
+ int16 y;
int16 pathNodeIndex;
- int8 numLeftLanes;
- int8 numRightLanes;
- uint8 trafficLightType;
-
- uint8 bBridgeLights : 1;
- // more?
-
- CVector2D &GetPosition(void) { return pos; }
- CVector2D &GetDirection(void) { return dir; }
- float GetX(void) { return pos.x; }
- float GetY(void) { return pos.y; }
- float GetDirX(void) { return dir.x; }
- float GetDirY(void) { return dir.y; }
+ int8 dirX;
+ int8 dirY;
+ int8 numLeftLanes : 3;
+ int8 numRightLanes : 3;
+ uint8 trafficLightDirection : 1;
+ uint8 trafficLightType : 2;
+ uint8 bBridgeLights : 1; // at least in LCS...
+ uint8 width;
+
+ CVector2D GetPosition(void) { return CVector2D(x/8.0f, y/8.0f); }
+ CVector2D GetDirection(void) { return CVector2D(dirX/100.0f, dirY/100.0f); }
+ float GetX(void) { return x/8.0f; }
+ float GetY(void) { return y/8.0f; }
+ float GetDirX(void) { return dirX/100.0f; }
+ float GetDirY(void) { return dirY/100.0f; }
+ float GetLaneOffset(void) { return width/(2*8.0f*LANE_WIDTH); }
float OneWayLaneOffset()
{
@@ -117,21 +136,34 @@ struct CCarPathLink
return 0.5f - 0.5f * numRightLanes;
if (numRightLanes == 0)
return 0.5f - 0.5f * numLeftLanes;
- return 0.5f;
+ return 0.5f + GetLaneOffset();
}
};
// This is what we're reading from the files, only temporary
struct CPathInfoForObject
{
- int16 x;
- int16 y;
- int16 z;
+ float x;
+ float y;
+ float z;
int8 type;
int8 next;
int8 numLeftLanes;
int8 numRightLanes;
+ int8 speedLimit;
+ uint8 width;
+
uint8 crossing : 1;
+ uint8 onlySmallBoats : 1;
+ uint8 roadBlock : 1;
+ uint8 disabled : 1;
+ uint8 waterPath : 1;
+ uint8 betweenLevels : 1;
+
+ uint8 spawnRate : 4;
+
+ void CheckIntegrity(void);
+ void SwapConnectionsToBeRightWayRound(void);
};
extern CPathInfoForObject *InfoForTileCars;
extern CPathInfoForObject *InfoForTilePeds;
@@ -139,30 +171,43 @@ extern CPathInfoForObject *InfoForTilePeds;
struct CTempNode
{
CVector pos;
- float dirX;
- float dirY;
+ int8 dirX; // *100
+ int8 dirY;
int16 link1;
int16 link2;
int8 numLeftLanes;
int8 numRightLanes;
+ uint8 width;
+ bool isCross;
int8 linkState;
};
-struct CTempDetachedNode // unused
+struct CTempNodeExternal // made up name
+{
+ CVector pos;
+ int16 next;
+ int8 numLeftLanes;
+ int8 numRightLanes;
+ uint8 width;
+ bool isCross;
+};
+
+// from mobile
+template<typename T>
+class CRoute
{
- uint8 foo[20];
+ T m_node[8];
};
+
class CPathFind
{
public:
CPathNode m_pathNodes[NUM_PATHNODES];
CCarPathLink m_carPathLinks[NUM_CARPATHLINKS];
CTreadable *m_mapObjects[NUM_MAPOBJECTS];
- uint8 m_objectFlags[NUM_MAPOBJECTS];
- int16 m_connections[NUM_PATHCONNECTIONS];
- int16 m_distances[NUM_PATHCONNECTIONS];
- CConnectionFlags m_connectionFlags[NUM_PATHCONNECTIONS];
+ uint16 m_connections[NUM_PATHCONNECTIONS]; // and flags
+ uint8 m_distances[NUM_PATHCONNECTIONS];
int16 m_carPathConnections[NUM_PATHCONNECTIONS];
int32 m_numPathNodes;
@@ -178,14 +223,19 @@ public:
void Init(void);
void AllocatePathFindInfoMem(int16 numPathGroups);
void RegisterMapObject(CTreadable *mapObject);
- void StoreNodeInfoPed(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, int16 width, bool crossing);
- void StoreNodeInfoCar(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, int16 width, int8 numLeft, int8 numRight);
- void CalcNodeCoors(int16 x, int16 y, int16 z, int32 id, CVector *out);
+ void StoreNodeInfoPed(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, float width, bool crossing, uint8 spawnRate);
+ void StoreNodeInfoCar(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, float width, int8 numLeft, int8 numRight,
+ bool disabled, bool betweenLevels, uint8 speedLimit, bool roadBlock, bool waterPath, uint8 spawnRate);
+ void StoreDetachedNodeInfoPed(int32 node, int8 type, int32 next, float x, float y, float z, float width, bool crossing,
+ bool disabled, bool betweenLevels, uint8 spawnRate);
+ void StoreDetachedNodeInfoCar(int32 node, int8 type, int32 next, float x, float y, float z, float width, int8 numLeft, int8 numRight,
+ bool disabled, bool betweenLevels, uint8 speedLimit, bool roadBlock, bool waterPath, uint8 spawnRate, bool unk);
+ void CalcNodeCoors(float x, float y, float z, int32 id, CVector *out);
bool LoadPathFindData(void);
void PreparePathData(void);
void CountFloodFillGroups(uint8 type);
void PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoForObject *objectpathinfo,
- float maxdist, CTempDetachedNode *detachednodes, int32 numDetached);
+ float maxdist, CPathInfoForObject *detachednodes, int32 numDetached);
bool IsPathObject(int id) { return id < PATHNODESIZE && (InfoForTileCars[id*12].type != 0 || InfoForTilePeds[id*12].type != 0); }
@@ -203,30 +253,52 @@ public:
void MarkRoadsBetweenLevelsNodeAndNeighbours(int32 nodeId);
void MarkRoadsBetweenLevelsInArea(float x1, float x2, float y1, float y2, float z1, float z2);
void PedMarkRoadsBetweenLevelsInArea(float x1, float x2, float y1, float y2, float z1, float z2);
- int32 FindNodeClosestToCoors(CVector coors, uint8 type, float distLimit, bool ignoreDisabled = false, bool ignoreBetweenLevels = false);
+ int32 FindNodeClosestToCoors(CVector coors, uint8 type, float distLimit, bool ignoreDisabled = false, bool ignoreBetweenLevels = false, bool ignoreSelected = false, bool bWaterPath = false);
int32 FindNodeClosestToCoorsFavourDirection(CVector coors, uint8 type, float dirX, float dirY);
+ void FindNodePairClosestToCoors(CVector coors, uint8 type, int* node1, int* node2, float* angle, float minDist, float maxDist, bool ignoreDisabled = false, bool ignoreBetweenLevels = false, bool bWaterPath = false);
+ int32 FindNthNodeClosestToCoors(CVector coors, uint8 type, float distLimit, bool ignoreDisabled, bool ignoreBetweenLevels, int N, bool bWaterPath = false);
+ CVector FindNodeCoorsForScript(int32 id);
float FindNodeOrientationForCarPlacement(int32 nodeId);
float FindNodeOrientationForCarPlacementFacingDestination(int32 nodeId, float x, float y, bool towards);
- bool NewGenerateCarCreationCoors(float x, float y, float dirX, float dirY, float spawnDist, float angleLimit, bool forward, CVector *pPosition, int32 *pNode1, int32 *pNode2, float *pPositionBetweenNodes, bool ignoreDisabled = false);
+ bool GenerateCarCreationCoors(float x, float y, float dirX, float dirY, float spawnDist, float angleLimit, bool forward, CVector *pPosition, int32 *pNode1, int32 *pNode2, float *pPositionBetweenNodes, bool ignoreDisabled = false);
bool GeneratePedCreationCoors(float x, float y, float minDist, float maxDist, float minDistOffScreen, float maxDistOffScreen, CVector *pPosition, int32 *pNode1, int32 *pNode2, float *pPositionBetweenNodes, CMatrix *camMatrix);
- CTreadable *FindRoadObjectClosestToCoors(CVector coors, uint8 type);
void FindNextNodeWandering(uint8, CVector, CPathNode**, CPathNode**, uint8, uint8*);
void DoPathSearch(uint8 type, CVector start, int32 startNodeId, CVector target, CPathNode **nodes, int16 *numNodes, int16 maxNumNodes, CVehicle *vehicle, float *dist, float distLimit, int32 forcedTargetNode);
bool TestCoorsCloseness(CVector target, uint8 type, CVector start);
void Save(uint8 *buf, uint32 *size);
void Load(uint8 *buf, uint32 size);
- uint16 ConnectedNode(int id) { return m_connections[id]; }
- bool ConnectionCrossesRoad(int id) { return m_connectionFlags[id].bCrossesRoad; }
- bool ConnectionHasTrafficLight(int id) { return m_connectionFlags[id].bTrafficLight; }
- void ConnectionSetTrafficLight(int id) { m_connectionFlags[id].bTrafficLight = true; }
+
+ static CVector TakeWidthIntoAccountForWandering(CPathNode*, uint16);
+ static void TakeWidthIntoAccountForCoors(CPathNode*, CPathNode*, uint16, float*, float*);
+
+ CPathNode *GetNode(int16 index);
+ int16 GetIndex(CPathNode *node);
+
+ uint16 ConnectedNode(int id) { return m_connections[id] & 0x3FFF; }
+ bool ConnectionCrossesRoad(int id) { return !!(m_connections[id] & 0x8000); }
+ bool ConnectionHasTrafficLight(int id) { return !!(m_connections[id] & 0x4000); }
+ void ConnectionSetTrafficLight(int id) { m_connections[id] |= 0x4000; }
void DisplayPathData(void);
-};
-VALIDATE_SIZE(CPathFind, 0x49bf4);
+ // Following methods are present on mobile but are unused. TODO: implement them
+ void SavePathFindData(void);
+ void ComputeRoute(uint8, const CVector&, const CVector&, CRoute<CPathNode*>&);
+ void RecordNodesClosestToCoors(CVector, uint8, int, CPathNode**, float, bool, bool, bool);
+ void RecordNodesInCircle(const CVector&, float, uint8, int, CPathNode**, bool, bool, bool, bool);
+ void ArrangeOneNodeList(CPathInfoForObject*, int16);
+ void ArrangeNodes(int16);
+ void RegisterMarker(CVector*);
+ void Shutdown(void);
+};
extern CPathFind ThePaths;
+inline CPathNode *CPathNode::GetPrev(void) { return ThePaths.GetNode(prevIndex); }
+inline CPathNode *CPathNode::GetNext(void) { return ThePaths.GetNode(nextIndex); }
+inline void CPathNode::SetPrev(CPathNode *node) { prevIndex = ThePaths.GetIndex(node); }
+inline void CPathNode::SetNext(CPathNode *node) { nextIndex = ThePaths.GetIndex(node); }
+
extern bool gbShowPedPaths;
extern bool gbShowCarPaths;
extern bool gbShowCarPathsLinks;
diff --git a/src/control/Phones.cpp b/src/control/Phones.cpp
index 7632cfa3..41f9d766 100644
--- a/src/control/Phones.cpp
+++ b/src/control/Phones.cpp
@@ -41,16 +41,6 @@ CPed *CPhoneInfo::pCallBackPed; // ped who picking up the phone (reset after pic
after 60 seconds of last phone pick-up.
*/
-#ifdef PEDS_REPORT_CRIMES_ON_PHONE
-CPed* crimeReporters[NUMPHONES] = {};
-bool
-isPhoneAvailable(int m_phoneId)
-{
- return crimeReporters[m_phoneId] == nil || !crimeReporters[m_phoneId]->IsPointerValid() || crimeReporters[m_phoneId]->m_objective > OBJECTIVE_WAIT_ON_FOOT ||
- (crimeReporters[m_phoneId]->m_nPedState != PED_MAKE_CALL && crimeReporters[m_phoneId]->m_nPedState != PED_FACE_PHONE && crimeReporters[m_phoneId]->m_nPedState != PED_SEEK_POS);
-}
-#endif
-
void
CPhoneInfo::Update(void)
{
@@ -167,14 +157,9 @@ CPhoneInfo::FindNearestFreePhone(CVector *pos)
int nearestPhoneId = -1;
float nearestPhoneDist = 60.0f;
- for (int phoneId = 0; phoneId < m_nMax; phoneId++) {
+ for (int phoneId = 0; phoneId < m_nMax; phoneId++) {
-#ifdef PEDS_REPORT_CRIMES_ON_PHONE
- if (isPhoneAvailable(phoneId))
-#else
- if (gPhoneInfo.m_aPhones[phoneId].m_nState == PHONE_STATE_FREE)
-#endif
- {
+ if (gPhoneInfo.m_aPhones[phoneId].m_nState == PHONE_STATE_FREE) {
float phoneDist = (m_aPhones[phoneId].m_vecPos - *pos).Magnitude2D();
if (phoneDist < nearestPhoneDist) {
@@ -215,81 +200,32 @@ CPhoneInfo::IsMessageBeingDisplayed(int phoneId)
return pPhoneDisplayingMessages == &m_aPhones[phoneId];
}
-#ifdef COMPATIBLE_SAVES
-static inline void
-LoadPhone(CPhone &phone, uint8 *&buf)
-{
- ReadSaveBuf(&phone.m_vecPos, buf);
- SkipSaveBuf(buf, 6 * 4);
- ReadSaveBuf<uint32>(&phone.m_repeatedMessagePickupStart, buf);
- uint32 tmp;
- ReadSaveBuf(&tmp, buf);
- phone.m_pEntity = (CEntity*)(uintptr)tmp;
- ReadSaveBuf<PhoneState>(&phone.m_nState, buf);
- ReadSaveBuf<bool>(&phone.m_visibleToCam, buf);
- SkipSaveBuf(buf, 3);
-}
-#endif
-
void
CPhoneInfo::Load(uint8 *buf, uint32 size)
{
INITSAVEBUF
- int32 max, scriptPhonesMax;
- ReadSaveBuf(&max, buf);
- ReadSaveBuf(&scriptPhonesMax, buf);
-
-#ifdef PEDS_REPORT_CRIMES_ON_PHONE
- m_nMax = Min(NUMPHONES, max);
- m_nScriptPhonesMax = 0;
-
- bool ignoreOtherPhones = false;
-
- // We can do it without touching saves. We'll only load script phones, others are already loaded in Initialise
- for (int i = 0; i < 50; i++) {
- CPhone phoneToLoad;
-#ifdef COMPATIBLE_SAVES
- phoneToLoad.m_apMessages[0]=phoneToLoad.m_apMessages[1]=phoneToLoad.m_apMessages[2]=phoneToLoad.m_apMessages[3]=phoneToLoad.m_apMessages[4]=phoneToLoad.m_apMessages[5] = nil;
- LoadPhone(phoneToLoad, buf);
-#else
- ReadSaveBuf(&phoneToLoad, buf);
-#endif
-
- if (ignoreOtherPhones)
- continue;
-
- if (i < scriptPhonesMax) {
- if (i >= m_nMax) {
- assert(0 && "Number of phones used by script exceeds the NUMPHONES or the stored phones in save file. Ignoring some phones");
- ignoreOtherPhones = true;
- continue;
- }
- SwapPhone(phoneToLoad.m_vecPos.x, phoneToLoad.m_vecPos.y, i);
-
- m_aPhones[i] = phoneToLoad;
- // It's saved as building pool index in save file, convert it to true entity
- if (m_aPhones[i].m_pEntity) {
- m_aPhones[i].m_pEntity = CPools::GetBuildingPool()->GetSlot((uintptr)m_aPhones[i].m_pEntity - 1);
- }
- } else
- ignoreOtherPhones = true;
- }
-#else
- m_nMax = max;
- m_nScriptPhonesMax = scriptPhonesMax;
-
+ ReadSaveBuf(&m_nMax, buf);
+ ReadSaveBuf(&m_nScriptPhonesMax, buf);
for (int i = 0; i < NUMPHONES; i++) {
#ifdef COMPATIBLE_SAVES
- LoadPhone(m_aPhones[i], buf);
+ ReadSaveBuf(&m_aPhones[i].m_vecPos, buf);
+ SkipSaveBuf(buf, 6 * 4);
+ ReadSaveBuf(&m_aPhones[i].m_repeatedMessagePickupStart, buf);
+ int32 tmp;
+ ReadSaveBuf(&tmp, buf);
+ // It's saved as building pool index in save file, convert it to true entity
+ m_aPhones[i].m_pEntity = tmp != 0 ? CPools::GetBuildingPool()->GetSlot(tmp - 1) : nil;
+ ReadSaveBuf(&m_aPhones[i].m_nState, buf);
+ ReadSaveBuf(&m_aPhones[i].m_visibleToCam, buf);
+ SkipSaveBuf(buf, 3);
#else
ReadSaveBuf(&m_aPhones[i], buf);
-#endif
// It's saved as building pool index in save file, convert it to true entity
if (m_aPhones[i].m_pEntity) {
m_aPhones[i].m_pEntity = CPools::GetBuildingPool()->GetSlot((uintptr)m_aPhones[i].m_pEntity - 1);
}
- }
#endif
+ }
VALIDATESAVEBUF(size)
}
@@ -327,31 +263,6 @@ CPhoneInfo::SetPhoneMessage_Repeatedly(int phoneId, wchar *msg1, wchar *msg2, wc
}
}
-#ifdef PEDS_REPORT_CRIMES_ON_PHONE
-void
-CPhoneInfo::SwapPhone(float xPos, float yPos, int into)
-{
- // "into" should be in 0 - m_nScriptPhonesMax range
- int nearestPhoneId = -1;
- CVector pos(xPos, yPos, 0.0f);
- float nearestPhoneDist = 1.0f;
-
- for (int phoneId = m_nScriptPhonesMax; phoneId < m_nMax; phoneId++) {
- float phoneDistance = (m_aPhones[phoneId].m_vecPos - pos).Magnitude2D();
- if (phoneDistance < nearestPhoneDist) {
- nearestPhoneDist = phoneDistance;
- nearestPhoneId = phoneId;
- }
- }
- m_aPhones[nearestPhoneId].m_nState = PHONE_STATE_MESSAGE_REMOVED;
-
- CPhone oldPhone = m_aPhones[into];
- m_aPhones[into] = m_aPhones[nearestPhoneId];
- m_aPhones[nearestPhoneId] = oldPhone;
- m_nScriptPhonesMax++;
-}
-#endif
-
int
CPhoneInfo::GrabPhone(float xPos, float yPos)
{
@@ -411,11 +322,7 @@ CPhoneInfo::Save(uint8 *buf, uint32 *size)
INITSAVEBUF
WriteSaveBuf(buf, m_nMax);
WriteSaveBuf(buf, m_nScriptPhonesMax);
-#ifdef PEDS_REPORT_CRIMES_ON_PHONE
- for (int phoneId = 0; phoneId < 50; phoneId++) { // We can do it without touching saves
-#else
- for (int phoneId = 0; phoneId < NUMPHONES; phoneId++) {
-#endif
+ for(int phoneId = 0; phoneId < NUMPHONES; phoneId++) {
#ifdef COMPATIBLE_SAVES
WriteSaveBuf(buf, m_aPhones[phoneId].m_vecPos);
ZeroSaveBuf(buf, 6 * 4);
diff --git a/src/control/Phones.h b/src/control/Phones.h
index 02c9a928..81b40dc2 100644
--- a/src/control/Phones.h
+++ b/src/control/Phones.h
@@ -61,17 +61,9 @@ public:
void Initialise(void);
void Shutdown(void);
void Update(void);
-#ifdef PEDS_REPORT_CRIMES_ON_PHONE
- void SwapPhone(float xPos, float yPos, int into);
-#endif
};
extern CPhoneInfo gPhoneInfo;
void PhonePutDownCB(CAnimBlendAssociation *assoc, void *arg);
-void PhonePickUpCB(CAnimBlendAssociation *assoc, void *arg);
-
-#ifdef PEDS_REPORT_CRIMES_ON_PHONE
-extern CPed *crimeReporters[NUMPHONES];
-bool isPhoneAvailable(int);
-#endif
+void PhonePickUpCB(CAnimBlendAssociation *assoc, void *arg); \ No newline at end of file
diff --git a/src/control/Pickups.cpp b/src/control/Pickups.cpp
index 8d3472ea..f6b1a9b9 100644
--- a/src/control/Pickups.cpp
+++ b/src/control/Pickups.cpp
@@ -31,9 +31,13 @@
#include "Timer.h"
#include "WaterLevel.h"
#include "World.h"
+#include "Hud.h"
+#include "Messages.h"
+#include "Streaming.h"
+#include "SaveBuf.h"
#ifdef COMPATIBLE_SAVES
-#define PICKUPS_SAVE_SIZE 0x24C0
+#define PICKUPS_SAVE_SIZE 0x4440
#else
#define PICKUPS_SAVE_SIZE sizeof(aPickUps)
#endif
@@ -43,6 +47,9 @@ int16 CPickups::NumMessages;
int32 CPickups::aPickUpsCollected[NUMCOLLECTEDPICKUPS];
int16 CPickups::CollectedPickUpIndex;
+int32 CPickups::PlayerOnWeaponPickup;
+int32 CollectPickupBuffer;
+
// unused
bool CPickups::bPickUpcamActivated;
CVehicle *CPickups::pPlayerVehicle;
@@ -51,38 +58,154 @@ uint32 CPickups::StaticCamStartTime;
tPickupMessage CPickups::aMessages[NUMPICKUPMESSAGES];
-// 20 ?! Some Miami leftover? (Originally at 0x5ED8D4)
-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 };
-uint16 CostOfWeapon[20] = { 0, 10, 250, 800, 1500, 3000, 5000, 10000, 25000, 25000, 2000, 2000, 0, 50000, 0, 3000, 0, 0, 0, 0 };
+uint16 AmmoForWeapon[WEAPONTYPE_TOTALWEAPONS + 1] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 8, 8, 8, 68, 24,
+ 32, 28, 20, 200, 120, 120, 120, 120, 120, 40, 28, 8, 300, 200, 1000, 1, 400, 36, 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 };
+uint16 AmmoForWeapon_OnStreet[WEAPONTYPE_TOTALWEAPONS + 1] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 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[WEAPONTYPE_TOTALWEAPONS + 3] = { 0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 1000, 1000,
+ 1000, 500, 8000, 250, 400, 1200, 1250, 1250, 800, 800, 650, 1200, 5000, 400,
+ 10000, 10000, 8000, 8000, 8000, 10000, 1000, 11000, 500, 20, 10, 0 };
-inline void
-CPickup::Remove()
+struct
+{
+ uint8 r,g,b;
+ float unk;
+} aPickupColors[] = {
+ { 128, 128, 128, 1.0f },
+ { 128, 128, 128, 1.0f },
+ { 97, 194, 247, 1.0f },
+ { 97, 194, 247, 1.0f },
+ { 97, 194, 247, 1.0f },
+ { 97, 194, 247, 1.0f },
+ { 97, 194, 247, 1.0f },
+ { 97, 194, 247, 1.0f },
+ { 97, 194, 247, 1.0f },
+ { 97, 194, 247, 1.0f },
+ { 97, 194, 247, 1.0f },
+ { 97, 194, 247, 1.0f },
+ { 27, 89, 130, 1.0f },
+ { 27, 89, 130, 1.0f },
+ { 27, 89, 130, 1.0f },
+ { 27, 89, 130, 1.0f },
+ { 27, 89, 130, 1.0f },
+ { 149, 194, 24, 1.0f },
+ { 149, 194, 24, 1.0f },
+ { 45, 155, 90, 1.0f },
+ { 45, 155, 90, 1.0f },
+ { 45, 155, 90, 1.0f },
+ { 255, 227, 79, 1.0f },
+ { 255, 227, 79, 1.0f },
+ { 255, 227, 79, 1.0f },
+ { 255, 227, 79, 1.0f },
+ { 254, 137, 0, 1.0f },
+ { 254, 137, 0, 1.0f },
+ { 249, 131, 215, 1.0f },
+ { 249, 131, 215, 1.0f },
+ { 164, 40, 178, 1.0f },
+ { 164, 40, 178, 1.0f },
+ { 164, 40, 178, 1.0f },
+ { 164, 40, 178, 1.0f },
+ { 69, 69, 69, 1.0f },
+ { 69, 69, 69, 1.0f },
+ { 69, 69, 69, 1.0f },
+ { 255, 100, 100, 1.0f },
+ { 128, 255, 128, 1.0f },
+ { 100, 100, 255, 1.0f },
+ { 255, 255, 100, 1.0f },
+ { 255, 100, 100, 1.0f },
+ { 100, 255, 100, 1.0f },
+ { 255, 255, 255, 1.0f }
+};
+
+
+void
+ModifyStringLabelForControlSetting(char *str)
+{
+ int len = (int)strlen(str);
+ if (len <= 2)
+ return;
+
+ if (str[len - 2] != '_')
+ return;
+
+ switch (CPad::GetPad(0)->Mode) {
+ case 0:
+ case 1:
+ str[len - 1] = 'L';
+ break;
+ case 2:
+ str[len - 1] = 'T';
+ break;
+ case 3:
+ str[len - 1] = 'C';
+ break;
+ default:
+ return;
+ }
+}
+
+void
+CPickup::ExtractAmmoFromPickup(CPlayerPed *player)
{
- CWorld::Remove(m_pObject);
- delete m_pObject;
+ eWeaponType weaponType = CPickups::WeaponForModel(m_pObject->GetModelIndex());
+
+ if (m_eType == PICKUP_IN_SHOP || !CWeaponInfo::IsWeaponSlotAmmoMergeable(CWeaponInfo::GetWeaponInfo(weaponType)->m_nWeaponSlot))
+ return;
+ uint32 ammo = m_nQuantity;
+ if (ammo == 0) {
+ if (!m_bWasAmmoCollected)
+ ammo = AmmoForWeapon_OnStreet[weaponType];
+ else
+ goto removeAmmo;
+ }
+ player->GrantAmmo(weaponType, ammo);
+ DMAudio.PlayOneShot(player->m_audioEntityId, SOUND_WEAPON_RELOAD, weaponType); // BUG? weapon type as volume, wtf?
+removeAmmo:
+ m_nQuantity = 0;
+ m_bWasAmmoCollected = true;
+}
+
+void
+CPickup::Remove()
+{
+ GetRidOfObjects();
m_bRemoved = true;
- m_pObject = nil;
m_eType = PICKUP_NONE;
}
CObject *
-CPickup::GiveUsAPickUpObject(int32 handle)
+CPickup::GiveUsAPickUpObject(CObject **ppObject, CObject **ppExtraObject, int32 handle, int32 extraHandle)
{
- CObject *object;
+ CObject *&object = *ppObject;
+ CObject *&extraObject = *ppExtraObject;
+
+ object = extraObject = nil;
+
+ int32 modelId = -1;
+ if (CModelInfo::GetModelInfo(m_eModelIndex)->GetModelType() == MITYPE_WEAPON) {
+ CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(((CWeaponModelInfo*)CModelInfo::GetModelInfo(m_eModelIndex))->GetWeaponInfo());
+ modelId = weaponInfo->m_nModelId;
+ if (modelId == m_eModelIndex)
+ modelId = weaponInfo->m_nModel2Id;
+ }
if (handle >= 0) {
CPools::MakeSureSlotInObjectPoolIsEmpty(handle);
- object = new (handle) CObject(m_eModelIndex, false);
- } else
+ if (extraHandle >= 0)
+ CPools::MakeSureSlotInObjectPoolIsEmpty(extraHandle);
+ if (object == nil)
+ object = new(handle) CObject(m_eModelIndex, false);
+
+ if (extraHandle >= 0 && modelId != -1 && extraObject == nil)
+ extraObject = new(extraHandle) CObject(modelId, false);
+ } else {
object = new CObject(m_eModelIndex, false);
+ if (modelId != -1)
+ extraObject = new CObject(modelId, false);
+ }
if (object == nil) return nil;
object->ObjectCreatedBy = MISSION_OBJECT;
@@ -95,14 +218,38 @@ CPickup::GiveUsAPickUpObject(int32 handle)
object->bExplosionProof = true;
object->bUsesCollision = false;
object->bIsPickup = true;
+ object->bAmmoCollected = m_bWasAmmoCollected;
+ object->bHasPreRenderEffects = true;
+
+ if (extraObject) {
+ extraObject->ObjectCreatedBy = MISSION_OBJECT;
+ extraObject->SetPosition(m_vecPos);
+ extraObject->SetOrientation(0.0f, 0.0f, -HALFPI);
+ extraObject->GetMatrix().UpdateRW();
+ extraObject->UpdateRwFrame();
+
+ extraObject->bAffectedByGravity = false;
+ extraObject->bExplosionProof = true;
+ extraObject->bUsesCollision = false;
+ extraObject->bIsPickup = true;
+ extraObject->bAmmoCollected = true;
+ extraObject->bHasPreRenderEffects = true;
+ extraObject->m_nBonusValue = 0;
+ extraObject->bPickupObjWithMessage = false;
+ extraObject->bOutOfStock = false;
+ }
- object->m_nBonusValue = m_eModelIndex == MI_PICKUP_BONUS ? m_nQuantity : 0;
+ object->m_nBonusValue = (m_eModelIndex == MI_PICKUP_BONUS || m_eModelIndex == MI_PICKUP_CLOTHES) ? m_nQuantity : 0;
switch (m_eType)
{
case PICKUP_IN_SHOP:
object->bPickupObjWithMessage = true;
object->bOutOfStock = false;
+ if (m_eModelIndex == MI_PICKUP_HEALTH || m_eModelIndex == MI_PICKUP_ADRENALINE)
+ object->m_nCostValue = 0;
+ else
+ object->m_nCostValue = CostOfWeapon[CPickups::WeaponForModel(m_eModelIndex)];
break;
case PICKUP_ON_STREET:
case PICKUP_ONCE:
@@ -131,28 +278,47 @@ 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.2f)
+ || (m_pObject->GetModelIndex() == MI_PICKUP_HEALTH && player->m_fHealth > CWorld::Players[playerId].m_nMaxHealth - 0.2f)
|| (m_pObject->GetModelIndex() == MI_PICKUP_BRIBE && player->m_pWanted->GetWantedLevel() == 0)
- || (m_pObject->GetModelIndex() == MI_PICKUP_KILLFRENZY && (CTheScripts::IsPlayerOnAMission() || CDarkel::FrenzyOnGoing() || !CGame::nastyGame));
+ || (m_pObject->GetModelIndex() == MI_PICKUP_KILLFRENZY && (CTheScripts::IsPlayerOnAMission() || CDarkel::FrenzyOnGoing() || !CGame::nastyGame))
+ || (m_eType == PICKUP_ASSET_REVENUE && m_fRevenue < 10.0f);
return !cannotBePickedUp;
}
bool
CPickup::Update(CPlayerPed *player, CVehicle *vehicle, int playerId)
{
- float waterLevel;
bool result = false;
+ float waterLevel;
+
+ if (m_pObject) {
+ m_pObject->GetMatrix().GetPosition() = m_vecPos;
+ if (m_pExtraObject)
+ m_pExtraObject->GetMatrix().GetPosition() = m_vecPos;
+ }
+ if (m_eType == PICKUP_ASSET_REVENUE) {
+ uint32 timePassed = CTimer::GetTimeInMilliseconds() - m_nTimer;
+ m_nTimer = CTimer::GetTimeInMilliseconds();
+
+ if (Distance(FindPlayerCoors(), m_vecPos) > 10.0f)
+ m_fRevenue += float(timePassed * m_nMoneySpeed) / SQR(1200.0f);
+
+ m_fRevenue = Min(m_fRevenue, m_nQuantity);
+
+ m_pObject->m_nCostValue = m_fRevenue < 10 ? 0 : m_fRevenue;
+ }
if (m_bRemoved) {
if (CTimer::GetTimeInMilliseconds() > m_nTimer) {
// respawn pickup if we're far enough
float dist = (FindPlayerCoors().x - m_vecPos.x) * (FindPlayerCoors().x - m_vecPos.x) + (FindPlayerCoors().y - m_vecPos.y) * (FindPlayerCoors().y - m_vecPos.y);
if (dist > 100.0f || m_eType == PICKUP_IN_SHOP && dist > 2.4f) {
- m_pObject = GiveUsAPickUpObject(-1);
+ m_pObject = GiveUsAPickUpObject(&m_pObject, &m_pExtraObject, -1, -1);
if (m_pObject) {
CWorld::Add(m_pObject);
m_bRemoved = false;
@@ -162,6 +328,14 @@ CPickup::Update(CPlayerPed *player, CVehicle *vehicle, int playerId)
return false;
}
+ if (!m_pObject) {
+ GiveUsAPickUpObject(&m_pObject, &m_pExtraObject, -1, -1);
+ if (m_pObject)
+ CWorld::Add(m_pObject);
+ if (m_pExtraObject)
+ CWorld::Add(m_pExtraObject);
+ }
+
if (!m_pObject) return false;
if (!IsMine()) {
@@ -191,37 +365,94 @@ CPickup::Update(CPlayerPed *player, CVehicle *vehicle, int playerId)
}
}
+ if (isPickupTouched) {
+ eWeaponType weaponType = CPickups::WeaponForModel(m_pObject->GetModelIndex());
+ if (weaponType < WEAPONTYPE_TOTALWEAPONS && CDarkel::FrenzyOnGoing()) {
+ isPickupTouched = false;
+ m_bWasControlMessageShown = false;
+ } else if (weaponType < WEAPONTYPE_TOTALWEAPONS && weaponType != WEAPONTYPE_UNARMED) {
+ uint32 slot = CWeaponInfo::GetWeaponInfo(weaponType)->m_nWeaponSlot;
+ eWeaponType plrWeaponSlot = FindPlayerPed()->GetWeapon(slot).m_eWeaponType;
+ if (plrWeaponSlot != weaponType) {
+ if (CStreaming::ms_aInfoForModel[m_pObject->GetModelIndex()].m_loadState == STREAMSTATE_LOADED) {
+ if (plrWeaponSlot == WEAPONTYPE_UNARMED || (FindPlayerPed()->GetWeapon(slot).m_nAmmoTotal == 0 && !CWeaponInfo::IsWeaponSlotAmmoMergeable(slot))) {
+ if (CTimer::GetTimeInMilliseconds() - FindPlayerPed()->m_nPadDownPressedInMilliseconds < 1500) {
+ CPickups::PlayerOnWeaponPickup = 6;
+ isPickupTouched = false;
+ }
+ } else {
+ CPickups::PlayerOnWeaponPickup = 6;
+ if (CWeaponInfo::IsWeaponSlotAmmoMergeable(slot)) {
+ if (m_eType == PICKUP_ONCE_TIMEOUT || m_eType == PICKUP_ONCE || m_eType == PICKUP_ON_STREET) {
+ ExtractAmmoFromPickup(player);
+ FindPlayerPed()->GetWeapon(slot).Reload();
+ }
+ }
+ if (!m_bWasControlMessageShown) {
+ switch (CPad::GetPad(0)->Mode)
+ {
+ case 0:
+ case 1:
+ CHud::SetHelpMessage(TheText.Get("PU_CF1"), false);
+ break;
+ case 2:
+ CHud::SetHelpMessage(TheText.Get("PU_CF3"), false);
+ break;
+ case 3:
+ CHud::SetHelpMessage(TheText.Get("PU_CF4"), false);
+ break;
+ default:
+ break;
+ }
+ m_bWasControlMessageShown = true;
+ }
+ if (CollectPickupBuffer == 0)
+ isPickupTouched = false;
+ if (CTimer::GetTimeInMilliseconds() - FindPlayerPed()->m_nPadDownPressedInMilliseconds < 1500)
+ isPickupTouched = false;
+ }
+ } else
+ isPickupTouched = false;
+ }
+ }
+ } else
+ m_bWasControlMessageShown = false;
+
// if we didn't then we've got nothing to do
- if (isPickupTouched && CanBePickedUp(player)) {
- CPad::GetPad(0)->StartShake(120, 100);
+ if (isPickupTouched && CanBePickedUp(player, playerId)) {
+ if (m_pObject->GetModelIndex() != MI_PICKUP_PROPERTY && m_pObject->GetModelIndex() != MI_PICKUP_PROPERTY_FORSALE)
+ CPad::GetPad(0)->StartShake(120, 100);
+
+ eWeaponType weaponType = CPickups::WeaponForModel(m_pObject->GetModelIndex());
switch (m_eType)
{
case PICKUP_IN_SHOP:
- if (CWorld::Players[playerId].m_nMoney < CostOfWeapon[CPickups::WeaponForModel(m_pObject->GetModelIndex())]) {
+ if (CWorld::Players[playerId].m_nMoney < CostOfWeapon[weaponType])
CGarages::TriggerMessage("PU_MONY", -1, 6000, -1);
- } else {
- CWorld::Players[playerId].m_nMoney -= CostOfWeapon[CPickups::WeaponForModel(m_pObject->GetModelIndex())];
+ else {
+ CWorld::Players[playerId].m_nMoney -= CostOfWeapon[weaponType];
if (!CPickups::GivePlayerGoodiesWithPickUpMI(m_pObject->GetModelIndex(), playerId)) {
- player->GiveWeapon(CPickups::WeaponForModel(m_pObject->GetModelIndex()), AmmoForWeapon[CPickups::WeaponForModel(m_pObject->GetModelIndex())]);
- player->m_nSelectedWepSlot = player->GetWeaponSlot(CPickups::WeaponForModel(m_pObject->GetModelIndex()));
+ if (!player->DoesPlayerWantNewWeapon(weaponType, false))
+ break;
+ player->GiveWeapon(weaponType, AmmoForWeapon[weaponType]);
+ player->m_nSelectedWepSlot = player->GetWeaponSlot(weaponType);
DMAudio.PlayFrontEndSound(SOUND_PICKUP_WEAPON_BOUGHT, m_pObject->GetModelIndex() - MI_GRENADE);
}
result = true;
- CWorld::Remove(m_pObject);
- delete m_pObject;
- m_pObject = nil;
- m_nTimer = CTimer::GetTimeInMilliseconds() + 5000;
- m_bRemoved = true;
+ Remove();
}
break;
case PICKUP_ON_STREET:
case PICKUP_ON_STREET_SLOW:
if (!CPickups::GivePlayerGoodiesWithPickUpMI(m_pObject->GetModelIndex(), playerId)) {
- if (CPickups::WeaponForModel(m_pObject->GetModelIndex())) {
- player->GiveWeapon(CPickups::WeaponForModel(m_pObject->GetModelIndex()), m_nQuantity != 0 ? m_nQuantity : AmmoForWeapon_OnStreet[CPickups::WeaponForModel(m_pObject->GetModelIndex())]);
- if (player->m_nSelectedWepSlot == player->GetWeaponSlot(WEAPONTYPE_UNARMED)) {
- player->m_nSelectedWepSlot = player->GetWeaponSlot(CPickups::WeaponForModel(m_pObject->GetModelIndex()));
- }
+ if (!player->DoesPlayerWantNewWeapon(weaponType, false))
+ break;
+ if (weaponType != WEAPONTYPE_UNARMED) {
+ player->GiveWeapon(weaponType, m_nQuantity != 0 ? m_nQuantity : (m_bWasAmmoCollected ? 0 : AmmoForWeapon_OnStreet[weaponType]), true);
+
+ if (player->m_nSelectedWepSlot == player->GetWeaponSlot(WEAPONTYPE_UNARMED))
+ player->m_nSelectedWepSlot = player->GetWeaponSlot(weaponType);
+
DMAudio.PlayFrontEndSound(SOUND_PICKUP_WEAPON, m_pObject->GetModelIndex() - MI_GRENADE);
} else if (m_pObject->GetModelIndex() == MI_PICKUP_CAMERA && vehicle != nil) {
DMAudio.PlayFrontEndSound(SOUND_PICKUP_BONUS, 0);
@@ -231,9 +462,9 @@ CPickup::Update(CPlayerPed *player, CVehicle *vehicle, int playerId)
CPickups::StaticCamStartTime = CTimer::GetTimeInMilliseconds();
}
}
- if (m_eType == PICKUP_ON_STREET) {
+ if (m_eType == PICKUP_ON_STREET)
m_nTimer = CTimer::GetTimeInMilliseconds() + 30000;
- } else if (m_eType == PICKUP_ON_STREET_SLOW) {
+ else if (m_eType == PICKUP_ON_STREET_SLOW) {
if (MI_PICKUP_BRIBE == m_pObject->GetModelIndex())
m_nTimer = CTimer::GetTimeInMilliseconds() + 300000;
else
@@ -241,32 +472,37 @@ CPickup::Update(CPlayerPed *player, CVehicle *vehicle, int playerId)
}
result = true;
- CWorld::Remove(m_pObject);
- delete m_pObject;
- m_pObject = nil;
+ GetRidOfObjects();
m_bRemoved = true;
break;
case PICKUP_ONCE:
case PICKUP_ONCE_TIMEOUT:
+ case PICKUP_ONCE_TIMEOUT_SLOW:
if (!CPickups::GivePlayerGoodiesWithPickUpMI(m_pObject->GetModelIndex(), playerId)) {
- if (CPickups::WeaponForModel(m_pObject->GetModelIndex())) {
- player->GiveWeapon(CPickups::WeaponForModel(m_pObject->GetModelIndex()), m_nQuantity != 0 ? m_nQuantity : AmmoForWeapon[CPickups::WeaponForModel(m_pObject->GetModelIndex())]);
+ if (!player->DoesPlayerWantNewWeapon(weaponType, false)) {
+ ExtractAmmoFromPickup(player);
+ break;
+ }
+
+ if (weaponType != WEAPONTYPE_UNARMED) {
+ player->GiveWeapon(weaponType, m_nQuantity != 0 ? m_nQuantity : (m_bWasAmmoCollected ? 0 : AmmoForWeapon[weaponType]), true);
if (player->m_nSelectedWepSlot == player->GetWeaponSlot(WEAPONTYPE_UNARMED))
- player->m_nSelectedWepSlot = player->GetWeaponSlot(CPickups::WeaponForModel(m_pObject->GetModelIndex()));
+ player->m_nSelectedWepSlot = player->GetWeaponSlot(weaponType);
}
- DMAudio.PlayFrontEndSound(SOUND_PICKUP_WEAPON, m_pObject->GetModelIndex() - MI_GRENADE);
+ if (MI_PICKUP_SAVEGAME != m_pObject->GetModelIndex())
+ DMAudio.PlayFrontEndSound(SOUND_PICKUP_WEAPON, m_pObject->GetModelIndex() - MI_GRENADE);
}
result = true;
Remove();
break;
case PICKUP_COLLECTABLE1:
CWorld::Players[playerId].m_nCollectedPackages++;
- CWorld::Players[playerId].m_nMoney += 1000;
+ CWorld::Players[playerId].m_nMoney += 100;
if (CWorld::Players[playerId].m_nCollectedPackages == CWorld::Players[playerId].m_nTotalPackages) {
printf("All collectables have been picked up\n");
CGarages::TriggerMessage("CO_ALL", -1, 5000, -1);
- CWorld::Players[CWorld::PlayerInFocus].m_nMoney += 1000000;
+ CWorld::Players[CWorld::PlayerInFocus].m_nMoney += 100000;
} else
CGarages::TriggerMessage("CO_ONE", CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages, 5000, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages);
@@ -283,6 +519,39 @@ CPickup::Update(CPlayerPed *player, CVehicle *vehicle, int playerId)
result = true;
Remove();
DMAudio.PlayFrontEndSound(SOUND_PICKUP_MONEY, 0);
+ player->Say(SOUND_PED_MUGGING);
+ break;
+ case PICKUP_ASSET_REVENUE:
+ CWorld::Players[CWorld::PlayerInFocus].m_nMoney += m_fRevenue;
+ m_fRevenue = 0.0f;
+ DMAudio.PlayFrontEndSound(SOUND_PICKUP_MONEY, 0);
+ break;
+ case PICKUP_PROPERTY_LOCKED:
+ if (!m_bWasControlMessageShown) {
+ m_bWasControlMessageShown = true;
+ CHud::SetHelpMessage(TheText.Get(m_sTextKey), false);
+ }
+ break;
+ case PICKUP_PROPERTY_FORSALE:
+ ModifyStringLabelForControlSetting(m_sTextKey);
+ CMessages::InsertNumberInString(TheText.Get(m_sTextKey), m_nQuantity,
+ 0, 0, 0, 0, 0, gUString);
+ if (!CHud::IsHelpMessageBeingDisplayed())
+ CHud::SetHelpMessage(gUString, false);
+ if (CollectPickupBuffer == 0)
+ break;
+ if (CTheScripts::IsPlayerOnAMission())
+ CHud::SetHelpMessage(TheText.Get("PROP_2"), true);
+ else {
+ if (CWorld::Players[CWorld::PlayerInFocus].m_nMoney >= m_nQuantity) {
+ CWorld::Players[CWorld::PlayerInFocus].m_nMoney -= m_nQuantity;
+ CHud::SetHelpMessage(nil, true);
+ result = true;
+ Remove();
+ break;
+ }
+ CHud::SetHelpMessage(TheText.Get("PROP_1"), true);
+ }
break;
default:
break;
@@ -311,7 +580,7 @@ CPickup::Update(CPlayerPed *player, CVehicle *vehicle, int playerId)
if (vehicle != nil && vehicle->IsSphereTouchingVehicle(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z, 1.5f)) {
touched = true;
#ifdef FIX_BUGS
- break;
+ break; // added break here
#endif
}
}
@@ -343,7 +612,7 @@ CPickup::Update(CPlayerPed *player, CVehicle *vehicle, int playerId)
if (vehicle != nil && vehicle->IsSphereTouchingVehicle(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z, 1.5f)) {
explode = true;
#ifdef FIX_BUGS
- break;
+ break; // added break here
#endif
}
}
@@ -378,12 +647,48 @@ CPickup::Update(CPlayerPed *player, CVehicle *vehicle, int playerId)
default: break;
}
}
- if (!m_bRemoved && (m_eType == PICKUP_ONCE_TIMEOUT || m_eType == PICKUP_MONEY) && CTimer::GetTimeInMilliseconds() > m_nTimer)
+
+ if (!m_bRemoved && (m_eType == PICKUP_ONCE_TIMEOUT || m_eType == PICKUP_ONCE_TIMEOUT_SLOW || m_eType == PICKUP_MONEY) && CTimer::GetTimeInMilliseconds() > m_nTimer)
Remove();
+
return result;
}
void
+CPickup::ProcessGunShot(CVector *vec1, CVector *vec2)
+{
+ CColLine line(*vec1, *vec2);
+ if (m_pObject) {
+ CColSphere sphere;
+ sphere.radius = 4.0f;
+ sphere.center = m_pObject->GetPosition();
+ if (CCollision::TestLineSphere(line, sphere)) {
+ CExplosion::AddExplosion(nil, nil, EXPLOSION_MINE, m_pObject->GetPosition(), 0);
+ CWorld::Remove(m_pObject);
+ delete m_pObject;
+ m_pObject = nil;
+ m_bRemoved = true;
+ m_eType = PICKUP_NONE;
+ }
+ }
+}
+
+void
+CPickup::GetRidOfObjects()
+{
+ if (m_pObject) {
+ CWorld::Remove(m_pObject);
+ delete m_pObject;
+ m_pObject = nil;
+ }
+ if (m_pExtraObject) {
+ CWorld::Remove(m_pExtraObject);
+ delete m_pExtraObject;
+ m_pExtraObject = nil;
+ }
+}
+
+void
CPickups::Init(void)
{
NumMessages = 0;
@@ -391,6 +696,7 @@ CPickups::Init(void)
aPickUps[i].m_eType = PICKUP_NONE;
aPickUps[i].m_nIndex = 1;
aPickUps[i].m_pObject = nil;
+ aPickUps[i].m_pExtraObject = nil;
}
for (int i = 0; i < NUMCOLLECTEDPICKUPS; i++)
@@ -400,6 +706,28 @@ CPickups::Init(void)
}
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;
+}
+
+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)
{
for (int i = 0; i < NUMCOLLECTEDPICKUPS; i++) {
@@ -415,7 +743,7 @@ void
CPickups::PassTime(uint32 time)
{
for (int i = 0; i < NUMPICKUPS; i++) {
- if (aPickUps[i].m_eType != PICKUP_NONE) {
+ if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].m_eType != PICKUP_ASSET_REVENUE) {
if (aPickUps[i].m_nTimer <= time)
aPickUps[i].m_nTimer = 0;
else
@@ -449,22 +777,21 @@ 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) {
DMAudio.PlayFrontEndSound(SOUND_PICKUP_BONUS, 0);
return true;
} else if (modelIndex == MI_PICKUP_BRIBE) {
- int32 level = FindPlayerPed()->m_pWanted->GetWantedLevel() - 1;
- if (level < 0) level = 0;
+ int32 level = Max(FindPlayerPed()->m_pWanted->GetWantedLevel() - 1, 0);
player->SetWantedLevel(level);
DMAudio.PlayFrontEndSound(SOUND_PICKUP_BONUS, 0);
return true;
@@ -476,23 +803,9 @@ CPickups::GivePlayerGoodiesWithPickUpMI(int16 modelIndex, int playerIndex)
}
void
-CPickups::RemoveAllFloatingPickups()
-{
- for (int i = 0; i < NUMPICKUPS; i++) {
- if (aPickUps[i].m_eType == PICKUP_FLOATINGPACKAGE || aPickUps[i].m_eType == PICKUP_FLOATINGPACKAGE_FLOATING) {
- if (aPickUps[i].m_pObject) {
- CWorld::Remove(aPickUps[i].m_pObject);
- delete aPickUps[i].m_pObject;
- aPickUps[i].m_pObject = nil;
- }
- }
- }
-}
-
-void
CPickups::RemovePickUp(int32 pickupIndex)
{
- int32 index = CPickups::GetActualPickupIndex(pickupIndex);
+ int32 index = GetActualPickupIndex(pickupIndex);
if (index == -1) return;
if (aPickUps[index].m_pObject) {
@@ -500,24 +813,30 @@ CPickups::RemovePickUp(int32 pickupIndex)
delete aPickUps[index].m_pObject;
aPickUps[index].m_pObject = nil;
}
+ if (aPickUps[index].m_pExtraObject) {
+ CWorld::Remove(aPickUps[index].m_pExtraObject);
+ delete aPickUps[index].m_pExtraObject;
+ aPickUps[index].m_pExtraObject = nil;
+ }
aPickUps[index].m_eType = PICKUP_NONE;
aPickUps[index].m_bRemoved = true;
}
int32
-CPickups::GenerateNewOne(CVector pos, uint32 modelIndex, uint8 type, uint32 quantity)
+CPickups::GenerateNewOne(CVector pos, uint32 modelIndex, uint8 type, uint32 quantity, uint32 rate, bool highPriority, char* pText)
{
bool bFreeFound = false;
int32 slot = 0;
- if (type == PICKUP_FLOATINGPACKAGE || type == PICKUP_NAUTICAL_MINE_INACTIVE) {
+ if (type == PICKUP_FLOATINGPACKAGE || type == PICKUP_NAUTICAL_MINE_INACTIVE || highPriority) {
for (slot = NUMPICKUPS-1; slot >= 0; slot--) {
if (aPickUps[slot].m_eType == PICKUP_NONE) {
bFreeFound = true;
break;
}
}
- } else {
+ }
+ if (!bFreeFound) {
for (slot = 0; slot < NUMGENERALPICKUPS; slot++) {
if (aPickUps[slot].m_eType == PICKUP_NONE) {
bFreeFound = true;
@@ -533,10 +852,11 @@ CPickups::GenerateNewOne(CVector pos, uint32 modelIndex, uint8 type, uint32 quan
if (slot >= NUMGENERALPICKUPS) {
for (slot = 0; slot < NUMGENERALPICKUPS; slot++) {
- if (aPickUps[slot].m_eType == PICKUP_ONCE_TIMEOUT) break;
+ if (aPickUps[slot].m_eType == PICKUP_ONCE_TIMEOUT || aPickUps[slot].m_eType == PICKUP_ONCE_TIMEOUT_SLOW) break;
}
if (slot >= NUMGENERALPICKUPS) return -1;
+ aPickUps[slot].GetRidOfObjects();
}
}
@@ -545,8 +865,15 @@ CPickups::GenerateNewOne(CVector pos, uint32 modelIndex, uint8 type, uint32 quan
aPickUps[slot].m_eType = type;
aPickUps[slot].m_bRemoved = false;
aPickUps[slot].m_nQuantity = quantity;
+ aPickUps[slot].m_nMoneySpeed = rate;
+ aPickUps[slot].m_fRevenue = 0.0f;
+ aPickUps[slot].m_nTimer = CTimer::GetTimeInMilliseconds();
+ aPickUps[slot].m_bWasAmmoCollected = highPriority;
+ aPickUps[slot].m_bWasControlMessageShown = false;
if (type == PICKUP_ONCE_TIMEOUT)
aPickUps[slot].m_nTimer = CTimer::GetTimeInMilliseconds() + 20000;
+ else if (type == PICKUP_ONCE_TIMEOUT_SLOW)
+ aPickUps[slot].m_nTimer = CTimer::GetTimeInMilliseconds() + 120000;
else if (type == PICKUP_MONEY)
aPickUps[slot].m_nTimer = CTimer::GetTimeInMilliseconds() + 30000;
else if (type == PICKUP_MINE_INACTIVE || type == PICKUP_MINE_ARMED) {
@@ -557,10 +884,17 @@ CPickups::GenerateNewOne(CVector pos, uint32 modelIndex, uint8 type, uint32 quan
aPickUps[slot].m_nTimer = CTimer::GetTimeInMilliseconds() + 1500;
}
aPickUps[slot].m_eModelIndex = modelIndex;
+ if (pText)
+ strncpy(aPickUps[slot].m_sTextKey, pText, 8);
+ else
+ aPickUps[slot].m_sTextKey[0] = '\0';
+
aPickUps[slot].m_vecPos = pos;
- aPickUps[slot].m_pObject = aPickUps[slot].GiveUsAPickUpObject(-1);
+ aPickUps[slot].m_pObject = aPickUps[slot].GiveUsAPickUpObject(&aPickUps[slot].m_pObject, &aPickUps[slot].m_pExtraObject, -1, -1);
if (aPickUps[slot].m_pObject)
CWorld::Add(aPickUps[slot].m_pObject);
+ if (aPickUps[slot].m_pExtraObject)
+ CWorld::Add(aPickUps[slot].m_pExtraObject);
return GetNewUniquePickupIndex(slot);
}
@@ -583,50 +917,17 @@ CPickups::GetNewUniquePickupIndex(int32 slot)
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;
}
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 ((CWeaponModelInfo*)CModelInfo::GetModelInfo(model))->GetWeaponInfo();
}
void
@@ -671,69 +972,159 @@ CPickups::Update()
}
}
#endif
+ if (CPad::GetPad(0)->CollectPickupJustDown())
+ CollectPickupBuffer = 6;
+ else
+ CollectPickupBuffer = Max(0, CollectPickupBuffer - 1);
+
+ if (PlayerOnWeaponPickup)
+ PlayerOnWeaponPickup = Max(0, PlayerOnWeaponPickup - 1);
+
#define PICKUPS_FRAME_SPAN (6)
#ifdef FIX_BUGS
for (uint32 i = NUMGENERALPICKUPS * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN) / PICKUPS_FRAME_SPAN; i < NUMGENERALPICKUPS * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN + 1) / PICKUPS_FRAME_SPAN; i++) {
#else // BUG: this code can only reach 318 out of 320 pickups
for (uint32 i = NUMGENERALPICKUPS / PICKUPS_FRAME_SPAN * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN); i < NUMGENERALPICKUPS / PICKUPS_FRAME_SPAN * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN + 1); i++) {
#endif
- if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].Update(FindPlayerPed(), FindPlayerVehicle(), CWorld::PlayerInFocus)) {
+ if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].Update(FindPlayerPed(), FindPlayerVehicle(), CWorld::PlayerInFocus))
AddToCollectedPickupsArray(i);
- }
}
#undef PICKUPS_FRAME_SPAN
for (uint32 i = NUMGENERALPICKUPS; i < NUMPICKUPS; i++) {
- if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].Update(FindPlayerPed(), FindPlayerVehicle(), CWorld::PlayerInFocus)) {
+ if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].Update(FindPlayerPed(), FindPlayerVehicle(), CWorld::PlayerInFocus))
AddToCollectedPickupsArray(i);
+ }
+}
+
+CPickup*
+CPickups::FindPickUpForThisObject(CEntity *object)
+{
+ for (uint32 i = 0; i < NUMPICKUPS; i++) {
+ if (aPickUps[i].m_eType != PICKUP_NONE && (aPickUps[i].m_pObject == object || aPickUps[i].m_pExtraObject == object)) {
+ return &aPickUps[i];
}
}
+ return &aPickUps[0];
}
void
CPickups::DoPickUpEffects(CEntity *entity)
{
+ CPickup *pickup = FindPickUpForThisObject(entity);
+
if (entity->GetModelIndex() == MI_PICKUP_KILLFRENZY)
entity->bDoNotRender = CTheScripts::IsPlayerOnAMission() || CDarkel::FrenzyOnGoing() || !CGame::nastyGame;
if (!entity->bDoNotRender) {
float modifiedSin = 0.3f * (Sin((float)((CTimer::GetTimeInMilliseconds() + (uintptr)entity) & 0x7FF) * DEGTORAD(360.0f / 0x800)) + 1.0f);
-
+#ifdef FIX_BUGS
+ int16 colorId = 0;
+#else
int16 colorId;
+#endif
+ bool doInnerGlow = false;
+ bool doOuterGlow = true;
+
+ if (entity->GetModelIndex() == MI_PICKUP_ADRENALINE || entity->GetModelIndex() == MI_PICKUP_CAMERA) {
+ colorId = WEAPONTYPE_TOTALWEAPONS;
+ doInnerGlow = true;
+ doOuterGlow = false;
+ } else if (entity->GetModelIndex() == MI_PICKUP_BODYARMOUR) {
+ colorId = WEAPONTYPE_ARMOUR;
+ } else if (entity->GetModelIndex() == MI_PICKUP_BRIBE) {
+ doInnerGlow = true;
+ doOuterGlow = false;
+ } else if (entity->GetModelIndex() == MI_PICKUP_INFO || entity->GetModelIndex() == MI_PICKUP_KILLFRENZY) {
+ doInnerGlow = true;
+ doOuterGlow = false;
+ } else if (entity->GetModelIndex() == MI_PICKUP_HEALTH || entity->GetModelIndex() == MI_PICKUP_BONUS) {
+ colorId = WEAPONTYPE_HEALTH;
+ doInnerGlow = true;
+ doOuterGlow = false;
+ } else if (entity->GetModelIndex() == MI_PICKUP_PROPERTY) {
+ doInnerGlow = true;
+ doOuterGlow = false;
+ } else if (entity->GetModelIndex() == MI_PICKUP_PROPERTY_FORSALE) {
+ doInnerGlow = true;
+ doOuterGlow = false;
+ } else if (entity->GetModelIndex() == MI_PICKUP_REVENUE) {
+ doInnerGlow = true;
+ doOuterGlow = false;
+ } else if (entity->GetModelIndex() == MI_PICKUP_SAVEGAME) {
+ doInnerGlow = true;
+ doOuterGlow = false;
+ } else if (entity->GetModelIndex() == MI_PICKUP_CLOTHES) {
+ colorId = WEAPONTYPE_TOTALWEAPONS;
+ doOuterGlow = false;
+ doInnerGlow = true;
+ } else
+ colorId = WeaponForModel(entity->GetModelIndex());
+
+ const CVector& pos = pickup->m_vecPos;
+ if (doOuterGlow) {
+ bool corona1 = false;
+ bool corona2 = false;
+ int timerVal = (CTimer::GetTimeInMilliseconds() >> 9) & 7;
+
+ if (timerVal < 3)
+ corona1 = false;
+ else if (timerVal == 3)
+ corona1 = (CGeneral::GetRandomNumber() & 3) != 0;
+ else
+ corona1 = true;
- if (entity->GetModelIndex() == MI_PICKUP_ADRENALINE || entity->GetModelIndex() == MI_PICKUP_CAMERA)
- colorId = 11;
- else if (entity->GetModelIndex() == MI_PICKUP_BODYARMOUR || entity->GetModelIndex() == MI_PICKUP_BRIBE)
- colorId = 12;
- else if (entity->GetModelIndex() == MI_PICKUP_INFO || entity->GetModelIndex() == MI_PICKUP_KILLFRENZY)
- colorId = 13;
- else if (entity->GetModelIndex() == MI_PICKUP_HEALTH || entity->GetModelIndex() == MI_PICKUP_BONUS)
- colorId = 14;
- else
- colorId = FindColourIndexForWeaponMI(entity->GetModelIndex());
-
- assert(colorId >= 0);
-
- const CVector &pos = entity->GetPosition();
+ timerVal = (timerVal - 1) & 7;
+ if (timerVal < 3)
+ corona2 = false;
+ else if (timerVal == 3)
+ corona2 = (CGeneral::GetRandomNumber() & 3) != 0;
+ else
+ corona2 = true;
- float colorModifier = ((CGeneral::GetRandomNumber() & 0x1F) * 0.015f + 1.0f) * modifiedSin * 0.15f;
- CShadows::StoreStaticShadow((uintptr)entity, SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &pos, 2.0f, 0.0f, 0.0f, -2.0f, 0,
- aWeaponReds[colorId] * colorModifier, aWeaponGreens[colorId] * colorModifier, aWeaponBlues[colorId] * colorModifier, 4.0f,
- 1.0f, 40.0f, false, 0.0f);
+ if (((CObject*)entity)->bAmmoCollected) {
+ corona2 = false;
+ corona1 = false;
+ }
- float radius = (CGeneral::GetRandomNumber() & 0xF) * 0.1f + 3.0f;
- CPointLights::AddLight(CPointLights::LIGHT_POINT, pos, CVector(0.0f, 0.0f, 0.0f), radius, aWeaponReds[colorId] * modifiedSin / 256.0f, aWeaponGreens[colorId] * modifiedSin / 256.0f, aWeaponBlues[colorId] * modifiedSin / 256.0f, CPointLights::FOG_NONE, true);
- float size = (CGeneral::GetRandomNumber() & 0xF) * 0.0005f + 0.6f;
- CCoronas::RegisterCorona( (uintptr)entity,
- aWeaponReds[colorId] * modifiedSin / 2.0f, aWeaponGreens[colorId] * modifiedSin / 2.0f, aWeaponBlues[colorId] * modifiedSin / 2.0f,
- 255,
- pos,
- size, 65.0f, CCoronas::TYPE_RING, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
+ if (corona1) {
+ CCoronas::RegisterCorona((uintptr)entity,
+ aPickupColors[colorId].r * 0.45f, aPickupColors[colorId].g * 0.45f, aPickupColors[colorId].b * 0.45f,
+ 255, pos, 0.76f, 65.0f,
+ CCoronas::TYPE_RING, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF,
+ 0.0f, false, -0.4f);
+ CShadows::StoreStaticShadow((uintptr)entity,
+ SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &pos, 2.0f, 0.0f, 0.0f, -2.0f, 0,
+ aPickupColors[colorId].r * 0.3f, aPickupColors[colorId].g * 0.3f, aPickupColors[colorId].b * 0.3f,
+ 4.0f, 1.0f, 40.0f, false, 0.0f);
+ float radius = (CGeneral::GetRandomNumber() & 0xF) * 0.1f + 3.0f;
+ CPointLights::AddLight(CPointLights::LIGHT_POINT, pos, CVector(0.0f, 0.0f, 0.0f), radius, aPickupColors[colorId].r / 256.0f, aPickupColors[colorId].g / 256.0f, aPickupColors[colorId].b / 256.0f, CPointLights::FOG_NONE, true);
+ } else
+ CCoronas::RegisterCorona((uintptr)entity, 0, 0, 0, 255, pos, 0.57f, 65.0f, CCoronas::TYPE_RING, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
+
+ if (corona2) {
+ CCoronas::RegisterCorona(
+ (uintptr)entity + 1,
+ aPickupColors[colorId].r * 0.55f, aPickupColors[colorId].g * 0.55f, aPickupColors[colorId].b * 0.55f,
+ 255,
+ pos,
+ 0.6f,
+ 65.0f,
+ CCoronas::TYPE_RING, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF,
+ 0.0f, false, -0.4f);
+ if (!corona1)
+ CShadows::StoreStaticShadow((uintptr)entity, SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &pos, 2.0f, 0.0f, 0.0f, -2.0f, 0,
+ aPickupColors[colorId].r * 0.25f, aPickupColors[colorId].g * 0.25f, aPickupColors[colorId].b * 0.25f,
+ 4.0f, 1.0f, 40.0f, false, 0.0f);
+ } else
+ CCoronas::RegisterCorona((uintptr)entity + 1, 0, 0, 0, 255, pos, 0.45f, 65.0f, CCoronas::TYPE_RING, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
+ }
CObject *object = (CObject*)entity;
- if (object->bPickupObjWithMessage || object->bOutOfStock || object->m_nBonusValue) {
+ if (object->bPickupObjWithMessage || object->bOutOfStock || object->m_nBonusValue || object->m_nCostValue) {
+
float dist = Distance2D(pos, TheCamera.GetPosition());
- const float MAXDIST = 12.0f;
+ const float MAXDIST = 14.0f;
if (dist < MAXDIST && NumMessages < NUMPICKUPMESSAGES) {
RwV3d vecOut;
@@ -744,20 +1135,30 @@ CPickups::DoPickUpEffects(CEntity *entity)
aMessages[NumMessages].m_dist.x = fDistX;
aMessages[NumMessages].m_dist.y = fDistY;
aMessages[NumMessages].m_weaponType = WeaponForModel(entity->GetModelIndex());
- aMessages[NumMessages].m_color.red = aWeaponReds[colorId];
- aMessages[NumMessages].m_color.green = aWeaponGreens[colorId];
- aMessages[NumMessages].m_color.blue = aWeaponBlues[colorId];
+ aMessages[NumMessages].m_color.red = aPickupColors[colorId].r;
+ aMessages[NumMessages].m_color.green = aPickupColors[colorId].g;
+ aMessages[NumMessages].m_color.blue = aPickupColors[colorId].b;
aMessages[NumMessages].m_color.alpha = (1.0f - dist / MAXDIST) * 128.0f;
aMessages[NumMessages].m_bOutOfStock = object->bOutOfStock;
aMessages[NumMessages].m_quantity = object->m_nBonusValue;
+ aMessages[NumMessages].money = object->m_nCostValue;
NumMessages++;
}
}
}
+ uint32 model = entity->GetModelIndex();
+ CColModel *colModel = entity->GetColModel();
+ CVector colLength = colModel->boundingBox.max - colModel->boundingBox.min;
+ float maxDimension = Max(colLength.x, Max(colLength.y, colLength.z));
+
+ float scale = (Max(1.f, 1.2f / maxDimension) - 1.0f) * 0.6f + 1.0f;
+ if (model == MI_MINIGUN || model == MI_MINIGUN2)
+ scale = 1.2f;
+
float angle = (float)(CTimer::GetTimeInMilliseconds() & 0x7FF) * DEGTORAD(360.0f / 0x800);
- float c = Cos(angle) * aWeaponScale[colorId];
- float s = Sin(angle) * aWeaponScale[colorId];
+ float c = Cos(angle) * scale;
+ float s = Sin(angle) * scale;
// we know from SA they were setting each field manually like this
entity->GetMatrix().rx = c;
@@ -768,7 +1169,57 @@ CPickups::DoPickUpEffects(CEntity *entity)
entity->GetMatrix().fz = 0.0f;
entity->GetMatrix().ux = 0.0f;
entity->GetMatrix().uy = 0.0f;
- entity->GetMatrix().uz = aWeaponScale[colorId];
+ entity->GetMatrix().uz = scale;
+
+ if (entity->GetModelIndex() == MI_MINIGUN2) {
+ CMatrix matrix1;
+ CMatrix matrix2; // unused
+ entity->SetPosition(pickup->m_vecPos);
+ matrix1.SetRotateX(0.0f);
+ matrix1.Rotate(DEGTORAD(4.477f), DEGTORAD(-29.731f), DEGTORAD(-1.064f));
+ matrix1.Translate(CVector(0.829f, -0.001f, 0.226f));
+ entity->GetMatrix() *= matrix1;
+ }
+
+ if (doOuterGlow) {
+ CVector scale(0.0f, 0.0f, 0.0f);
+ if (colLength.x == maxDimension)
+ scale.x = colLength.x;
+ else if (colLength.y == maxDimension)
+ scale.y = colLength.y;
+ else
+ scale.z = colLength.z;
+
+ for (int i = 0; i < 4; i++) {
+ CVector pos = entity->GetMatrix() * (scale * ((float)i / 3.0f));
+ CCoronas::RegisterCorona(
+ (uintptr)entity + 8 + i,
+ aPickupColors[colorId].r * 0.15f,
+ aPickupColors[colorId].g * 0.15f,
+ aPickupColors[colorId].b * 0.15f,
+ 255,
+ pos,
+ 1.0f,
+ 65.0f,
+ CCoronas::TYPE_STAR, CCoronas::FLARE_NONE,
+ CCoronas::REFLECTION_OFF,
+ CCoronas::LOSCHECK_OFF,
+ CCoronas::STREAK_OFF,
+ 0.0f,
+ false,
+ -0.5f);
+ }
+ }
+
+ if (doInnerGlow)
+ CCoronas::RegisterCorona(
+#ifdef FIX_BUGS
+ (uintptr)entity + 8 + 4,
+#else
+ (uintptr)entity + 9,
+#endif
+ 126, 69, 121, 255, entity->GetPosition(), 1.2f, 50.0f,
+ CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, 0.0f);
}
}
@@ -823,7 +1274,7 @@ CPickups::DoCollectableEffects(CEntity *entity)
int32 color = (MAXDIST - dist) * (0.5f * s + 0.5f) / MAXDIST * 255.0f;
CShadows::StoreStaticShadow((uintptr)entity, SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &pos, 2.0f, 0.0f, 0.0f, -2.0f, 0, color, color, color, 4.0f,
1.0f, 40.0f, false, 0.0f);
- CCoronas::RegisterCorona((uintptr)entity, color, color, color, 255, pos, 0.6f, 40.0f, CCoronas::TYPE_RING, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
+ CCoronas::RegisterCorona((uintptr)entity, color, color, color, 255, pos, 0.6f, 40.0f, CCoronas::TYPE_HEX, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
}
entity->GetMatrix().SetRotateZOnly((float)(CTimer::GetTimeInMilliseconds() & 0xFFF) * DEGTORAD(360.0f / 0x1000));
@@ -834,13 +1285,17 @@ CPickups::RenderPickUpText()
{
wchar *strToPrint;
for (int32 i = 0; i < NumMessages; i++) {
- if (aMessages[i].m_quantity <= 39) {
+
+ if (aMessages[i].money != 0) {
+ sprintf(gString, "$%d", aMessages[i].money);
+ AsciiToUnicode(gString, gUString);
+ strToPrint = gUString;
+ } else {
switch (aMessages[i].m_quantity) // could use some enum maybe
{
case 0:
- if (aMessages[i].m_weaponType == WEAPONTYPE_TOTALWEAPONS) { // unreachable code?
- // what is this??
- sprintf(gString, "%d/%d", CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages, 2903);
+ if (aMessages[i].m_weaponType == WEAPONTYPE_HEALTH || aMessages[i].m_weaponType == WEAPONTYPE_ARMOUR) {
+ strToPrint = nil;
} else {
if (aMessages[i].m_bOutOfStock)
strToPrint = TheText.Get("STOCK");
@@ -852,176 +1307,181 @@ CPickups::RenderPickUpText()
}
break;
case 1:
- strToPrint = TheText.Get("SECURI");
+ strToPrint = TheText.Get("OUTFT1");
break;
case 2:
- strToPrint = TheText.Get("MOONBM");
+ strToPrint = TheText.Get("OUTFT2");
break;
case 3:
- strToPrint = TheText.Get("COACH");
+ strToPrint = TheText.Get("OUTFT3");
break;
case 4:
- strToPrint = TheText.Get("FLATBED");
+ strToPrint = TheText.Get("OUTFT4");
break;
case 5:
- strToPrint = TheText.Get("LINERUN");
+ strToPrint = TheText.Get("OUTFT5");
break;
case 6:
- strToPrint = TheText.Get("TRASHM");
+ strToPrint = TheText.Get("OUTFT6");
break;
case 7:
- strToPrint = TheText.Get("PATRIOT");
+ strToPrint = TheText.Get("OUTFT7");
break;
case 8:
- strToPrint = TheText.Get("WHOOPEE");
+ strToPrint = TheText.Get("OUTFT8");
break;
case 9:
- strToPrint = TheText.Get("BLISTA");
+ strToPrint = TheText.Get("OUTFT9");
break;
case 10:
- strToPrint = TheText.Get("MULE");
+ strToPrint = TheText.Get("OUTFT10");
break;
case 11:
- strToPrint = TheText.Get("YANKEE");
+ strToPrint = TheText.Get("OUTFT11");
break;
case 12:
- strToPrint = TheText.Get("BOBCAT");
+ strToPrint = TheText.Get("OUTFT12");
break;
case 13:
- strToPrint = TheText.Get("DODO");
- break;
- case 14:
- strToPrint = TheText.Get("BUS");
- break;
- case 15:
- strToPrint = TheText.Get("RUMPO");
- break;
- case 16:
- strToPrint = TheText.Get("PONY");
- break;
- case 17:
- strToPrint = TheText.Get("SENTINL");
- break;
- case 18:
- strToPrint = TheText.Get("CHEETAH");
- break;
- case 19:
- strToPrint = TheText.Get("BANSHEE");
- break;
- case 20:
- strToPrint = TheText.Get("IDAHO");
- break;
- case 21:
- strToPrint = TheText.Get("INFERNS");
- break;
- case 22:
- strToPrint = TheText.Get("TAXI");
- break;
- case 23:
- strToPrint = TheText.Get("KURUMA");
- break;
- case 24:
- strToPrint = TheText.Get("STRETCH");
- break;
- case 25:
- strToPrint = TheText.Get("PEREN");
- break;
- case 26:
- strToPrint = TheText.Get("STINGER");
- break;
- case 27:
- strToPrint = TheText.Get("MANANA");
- break;
- case 28:
- strToPrint = TheText.Get("LANDSTK");
- break;
- case 29:
- strToPrint = TheText.Get("STALION");
- break;
- case 30:
- strToPrint = TheText.Get("BFINJC");
- break;
- case 31:
- strToPrint = TheText.Get("CABBIE");
- break;
- case 32:
- strToPrint = TheText.Get("ESPERAN");
- break;
- case 33:
- strToPrint = TheText.Get("FIRETRK");
- break;
- case 34:
- strToPrint = TheText.Get("AMBULAN");
- break;
- case 35:
- strToPrint = TheText.Get("ENFORCR");
- break;
- case 36:
- strToPrint = TheText.Get("FBICAR");
- break;
- case 37:
- strToPrint = TheText.Get("RHINO");
- break;
- case 38:
- strToPrint = TheText.Get("BARRCKS");
- break;
- case 39:
- strToPrint = TheText.Get("POLICAR");
+ strToPrint = TheText.Get("OUTFT13");
break;
default:
break;
}
}
+ if (strToPrint == nil)
+ continue;
CFont::SetPropOn();
CFont::SetBackgroundOff();
- const float MAX_SCALE = 1.0f;
+#ifdef FIX_BUGS
+ const float MAX_SCALE = SCREEN_WIDTH / DEFAULT_SCREEN_WIDTH;
+#else
+ float MAX_SCALE = RsGlobal.width / DEFAULT_SCREEN_WIDTH;
+#endif
- float fScaleY = aMessages[i].m_dist.y / 100.0f;
+ float fScaleY = aMessages[i].m_dist.y / 30.0f;
if (fScaleY > MAX_SCALE) fScaleY = MAX_SCALE;
- float fScaleX = aMessages[i].m_dist.x / 100.0f;
+ float fScaleX = aMessages[i].m_dist.x / 30.0f;
if (fScaleX > MAX_SCALE) fScaleX = MAX_SCALE;
-#ifdef FIX_BUGS
- CFont::SetScale(SCREEN_SCALE_X(fScaleX), SCREEN_SCALE_Y(fScaleY));
-#else
- CFont::SetScale(fScaleX, fScaleY);
-#endif
+ CFont::SetScale(fScaleX, fScaleY); // this shouldn't be scaled
CFont::SetCentreOn();
CFont::SetCentreSize(SCREEN_WIDTH);
CFont::SetJustifyOff();
CFont::SetColor(CRGBA(aMessages[i].m_color.red, aMessages[i].m_color.green, aMessages[i].m_color.blue, aMessages[i].m_color.alpha));
CFont::SetBackGroundOnlyTextOff();
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
CFont::PrintString(aMessages[i].m_pos.x, aMessages[i].m_pos.y, strToPrint);
}
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::RemoveAllPickupsOfACertainWeaponGroupWithNoAmmo(eWeaponType weaponType)
+{
+ uint32 weaponSlot = CWeaponInfo::GetWeaponInfo(weaponType)->m_nWeaponSlot;
+ if (CWeaponInfo::IsWeaponSlotAmmoMergeable(weaponSlot)) {
+ for (int slot = 0; slot < NUMPICKUPS; slot++) {
+ if (aPickUps[slot].m_eType == PICKUP_ONCE || aPickUps[slot].m_eType == PICKUP_ONCE_TIMEOUT || aPickUps[slot].m_eType == PICKUP_ONCE_TIMEOUT_SLOW) {
+ if (aPickUps[slot].m_pObject) {
+ if (CWeaponInfo::GetWeaponInfo(WeaponForModel(aPickUps[slot].m_pObject->GetModelIndex()))->m_nWeaponSlot == weaponSlot &&
+ aPickUps[slot].m_nQuantity == 0) {
+ CWorld::Remove(aPickUps[slot].m_pObject);
+ delete aPickUps[slot].m_pObject;
+ aPickUps[slot].m_bRemoved = true;
+ aPickUps[slot].m_pObject = nil;
+ aPickUps[slot].m_eType = PICKUP_NONE;
+ }
+ }
+ }
+ }
+ }
+}
+
+void
+CPickups::DetonateMinesHitByGunShot(CVector *vec1, CVector *vec2)
+{
+ for (int i = 0; i < NUMGENERALPICKUPS; i++) {
+ if (aPickUps[i].m_eType == PICKUP_NAUTICAL_MINE_ARMED)
+ aPickUps[i].ProcessGunShot(vec1, vec2);
+ }
+}
+
+void
+CPickups::RemoveUnnecessaryPickups(const CVector& center, float radius)
+{
+ for (int i = 0; i < NUMPICKUPS; i++) {
+ if (aPickUps[i].m_eType == PICKUP_ONCE_TIMEOUT || aPickUps[i].m_eType == PICKUP_MONEY) {
+ if (Distance(center, aPickUps[i].m_vecPos) < radius) {
+ aPickUps[i].GetRidOfObjects();
+ aPickUps[i].m_bRemoved = true;
+ aPickUps[i].m_eType = PICKUP_NONE;
+ }
+ }
+ }
+}
+
+void
CPickups::Load(uint8 *buf, uint32 size)
{
INITSAVEBUF
for (int32 i = 0; i < NUMPICKUPS; i++) {
#ifdef COMPATIBLE_SAVES
- ReadSaveBuf(&aPickUps[i].m_eType, buf);
- ReadSaveBuf(&aPickUps[i].m_bRemoved, buf);
+ ReadSaveBuf(&aPickUps[i].m_vecPos, buf);
+ ReadSaveBuf(&aPickUps[i].m_fRevenue, buf);
+ int32 tmp_pObject;
+ ReadSaveBuf(&tmp_pObject, buf);
+ int32 tmp_pExtraObject;
+ ReadSaveBuf(&tmp_pExtraObject, buf);
ReadSaveBuf(&aPickUps[i].m_nQuantity, buf);
- int32 tmp;
- ReadSaveBuf(&tmp, buf);
- aPickUps[i].m_pObject = aPickUps[i].m_eType != PICKUP_NONE && tmp != 0 ? CPools::GetObjectPool()->GetSlot(tmp - 1) : nil;
ReadSaveBuf(&aPickUps[i].m_nTimer, buf);
+ ReadSaveBuf(&aPickUps[i].m_nMoneySpeed, buf);
ReadSaveBuf(&aPickUps[i].m_eModelIndex, buf);
ReadSaveBuf(&aPickUps[i].m_nIndex, buf);
- ReadSaveBuf(&aPickUps[i].m_vecPos, buf);
+ memcpy(aPickUps[i].m_sTextKey, buf, sizeof(aPickUps[i].m_sTextKey));
+ SkipSaveBuf(buf, sizeof(aPickUps[i].m_sTextKey));
+ ReadSaveBuf(&aPickUps[i].m_eType, buf);
+ ReadSaveBuf(&aPickUps[i].m_bRemoved, buf);
+ uint8 flags;
+ ReadSaveBuf(&flags, buf);
+ aPickUps[i].m_bWasAmmoCollected = !!(flags & BIT(0));
+ aPickUps[i].m_bWasControlMessageShown = !!(flags & BIT(1));
+ SkipSaveBuf(buf, 3);
+
+ aPickUps[i].m_pObject = aPickUps[i].m_eType != PICKUP_NONE && tmp_pObject != 0 ? CPools::GetObjectPool()->GetSlot(tmp_pObject - 1) : nil;
+ aPickUps[i].m_pExtraObject = aPickUps[i].m_eType != PICKUP_NONE && tmp_pExtraObject != 0 ? CPools::GetObjectPool()->GetSlot(tmp_pExtraObject - 1) : nil;
#else
ReadSaveBuf(&aPickUps[i], buf);
- if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].m_pObject != nil)
- aPickUps[i].m_pObject = CPools::GetObjectPool()->GetSlot((uintptr)aPickUps[i].m_pObject - 1);
+ if (aPickUps[i].m_eType != PICKUP_NONE) {
+ if (aPickUps[i].m_pObject != nil)
+ aPickUps[i].m_pObject = CPools::GetObjectPool()->GetSlot((uintptr)aPickUps[i].m_pObject - 1);
+ if (aPickUps[i].m_pExtraObject != nil)
+ aPickUps[i].m_pExtraObject = CPools::GetObjectPool()->GetSlot((uintptr)aPickUps[i].m_pExtraObject - 1);
+ }
#endif
}
@@ -1038,25 +1498,41 @@ VALIDATESAVEBUF(size)
void
CPickups::Save(uint8 *buf, uint32 *size)
{
- *size = PICKUPS_SAVE_SIZE + sizeof(uint16) + sizeof(uint16) + sizeof(aPickUpsCollected);
+ *size = PICKUPS_SAVE_SIZE;
+ *size += sizeof(uint16) + sizeof(uint16) + sizeof(aPickUpsCollected);
INITSAVEBUF
for (int32 i = 0; i < NUMPICKUPS; i++) {
#ifdef COMPATIBLE_SAVES
- WriteSaveBuf(buf, aPickUps[i].m_eType);
- WriteSaveBuf(buf, aPickUps[i].m_bRemoved);
- WriteSaveBuf(buf, aPickUps[i].m_nQuantity);
+ WriteSaveBuf(buf, aPickUps[i].m_vecPos);
+ WriteSaveBuf(buf, aPickUps[i].m_fRevenue);
int32 tmp = aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].m_pObject != nil ? CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(aPickUps[i].m_pObject) + 1 : 0;
WriteSaveBuf(buf, tmp);
+ tmp = aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].m_pExtraObject != nil ? CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(aPickUps[i].m_pExtraObject) + 1 : 0;
+ WriteSaveBuf(buf, tmp);
+ WriteSaveBuf(buf, aPickUps[i].m_nQuantity);
WriteSaveBuf(buf, aPickUps[i].m_nTimer);
+ WriteSaveBuf(buf, aPickUps[i].m_nMoneySpeed);
WriteSaveBuf(buf, aPickUps[i].m_eModelIndex);
WriteSaveBuf(buf, aPickUps[i].m_nIndex);
- WriteSaveBuf(buf, aPickUps[i].m_vecPos);
+ memcpy(buf, aPickUps[i].m_sTextKey, sizeof(aPickUps[i].m_sTextKey));
+ SkipSaveBuf(buf, sizeof(aPickUps[i].m_sTextKey));
+ WriteSaveBuf(buf, aPickUps[i].m_eType);
+ WriteSaveBuf(buf, aPickUps[i].m_bRemoved);
+ uint8 flags = 0;
+ if (aPickUps[i].m_bWasAmmoCollected) flags |= BIT(0);
+ if (aPickUps[i].m_bWasControlMessageShown) flags |= BIT(1);
+ WriteSaveBuf(buf, flags);
+ ZeroSaveBuf(buf, 3);
#else
CPickup *buf_pickup = WriteSaveBuf(buf, aPickUps[i]);
- if (buf_pickup->m_eType != PICKUP_NONE && buf_pickup->m_pObject != nil)
- buf_pickup->m_pObject = (CObject*)(CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(buf_pickup->m_pObject) + 1);
+ if (buf_pickup->m_eType != PICKUP_NONE) {
+ if (buf_pickup->m_pObject != nil)
+ buf_pickup->m_pObject = (CObject*)(CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(buf_pickup->m_pObject) + 1);
+ if (buf_pickup->m_pExtraObject != nil)
+ buf_pickup->m_pExtraObject = (CObject*)(CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(buf_pickup->m_pExtraObject) + 1);
+ }
#endif
}
@@ -1072,40 +1548,6 @@ VALIDATESAVEBUF(*size)
void
CPacManPickup::Update()
{
- if (FindPlayerVehicle() == nil) return;
-
- CVehicle *veh = FindPlayerVehicle();
-
- if (DistanceSqr2D(FindPlayerVehicle()->GetPosition(), m_vecPosn.x, m_vecPosn.y) < 100.0f && veh->IsSphereTouchingVehicle(m_vecPosn.x, m_vecPosn.y, m_vecPosn.z, 1.5f)) {
- switch (m_eType)
- {
- case PACMAN_SCRAMBLE:
- {
- veh->m_nPacManPickupsCarried++;
- veh->m_vecMoveSpeed *= 0.65f;
- float massMult = (veh->m_fMass + 250.0f) / veh->m_fMass;
- veh->m_fMass *= massMult;
- veh->m_fTurnMass *= massMult;
- veh->m_fForceMultiplier *= massMult;
- FindPlayerPed()->m_pWanted->m_nChaos += 10;
- FindPlayerPed()->m_pWanted->UpdateWantedLevel();
- DMAudio.PlayFrontEndSound(SOUND_PICKUP_PACMAN_PACKAGE, 0);
- break;
- }
- case PACMAN_RACE:
- CPacManPickups::PillsEatenInRace++;
- DMAudio.PlayFrontEndSound(SOUND_PICKUP_PACMAN_PILL, 0);
- break;
- default:
- break;
- }
- m_eType = PACMAN_NONE;
- if (m_pObject != nil) {
- CWorld::Remove(m_pObject);
- delete m_pObject;
- m_pObject = nil;
- }
- }
}
int32 CollectGameState;
@@ -1119,96 +1561,16 @@ bool CPacManPickups::bPMActive;
void
CPacManPickups::Init()
{
- for (int i = 0; i < NUMPACMANPICKUPS; i++)
- aPMPickUps[i].m_eType = PACMAN_NONE;
- bPMActive = false;
}
void
CPacManPickups::Update()
{
- if (FindPlayerVehicle()) {
- float dist = Distance(FindPlayerCoors(), CVector(1072.0f, -948.0f, 14.5f));
- switch (CollectGameState) {
- case 1:
- if (dist < 10.0f) {
- ThingsToCollect -= FindPlayerVehicle()->m_nPacManPickupsCarried;
- FindPlayerVehicle()->m_nPacManPickupsCarried = 0;
- FindPlayerVehicle()->m_fMass /= FindPlayerVehicle()->m_fForceMultiplier;
- FindPlayerVehicle()->m_fTurnMass /= FindPlayerVehicle()->m_fForceMultiplier;
- FindPlayerVehicle()->m_fForceMultiplier = 1.0f;
- }
- if (ThingsToCollect <= 0) {
- CollectGameState = 2;
- ClearPMPickUps();
- }
- break;
- case 2:
- if (dist > 11.0f)
- CollectGameState = 0;
- break;
- case 20:
- if (Distance(FindPlayerCoors(), LastPickUpCoors) > 30.0f) {
- LastPickUpCoors = FindPlayerCoors();
- printf("%f, %f, %f,\n", LastPickUpCoors.x, LastPickUpCoors.y, LastPickUpCoors.z);
- }
- break;
- default:
- break;
- }
- }
- if (bPMActive) {
-#define PACMANPICKUPS_FRAME_SPAN (4)
- for (uint32 i = (CTimer::GetFrameCounter() % PACMANPICKUPS_FRAME_SPAN) * (NUMPACMANPICKUPS / PACMANPICKUPS_FRAME_SPAN); i < ((CTimer::GetFrameCounter() % PACMANPICKUPS_FRAME_SPAN) + 1) * (NUMPACMANPICKUPS / PACMANPICKUPS_FRAME_SPAN); i++) {
- if (aPMPickUps[i].m_eType != PACMAN_NONE)
- aPMPickUps[i].Update();
- }
-#undef PACMANPICKUPS_FRAME_SPAN
- }
}
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
@@ -1218,271 +1580,69 @@ static const CVector aRacePoints1[] = {
CVector(913.27899f, -93.524231f, 7.4325991f),
CVector(912.60852f, -63.15905f, 7.4533591f),
CVector(934.22144f, -42.049122f, 7.4511471f),
- CVector(958.88092f, -23.863735f, 7.4652338f),
- CVector(978.50812f, -0.78458798f, 5.13515f),
- CVector(1009.4175f, -2.1041219f, 2.4461579f),
- CVector(1040.6313f, -2.0793829f, 2.293175f),
- CVector(1070.7863f, -2.084095f, 2.2789791f),
- CVector(1100.5773f, -8.468729f, 5.3248072f),
- CVector(1119.9341f, -31.738031f, 7.1913071f),
- CVector(1122.1664f, -62.762737f, 7.4703908f),
- CVector(1122.814f, -93.650566f, 8.5577497f),
- CVector(1125.8253f, -124.26616f, 9.9803305f),
- CVector(1153.8727f, -135.47169f, 14.150617f),
- CVector(1184.0831f, -135.82845f, 14.973998f),
- CVector(1192.0432f, -164.57816f, 19.18627f),
- CVector(1192.7761f, -194.28871f, 24.799675f),
- CVector(1215.1527f, -215.0714f, 25.74975f),
- CVector(1245.79f, -215.39304f, 28.70726f),
- CVector(1276.2477f, -216.39485f, 33.71236f),
- CVector(1306.5535f, -216.71007f, 39.711472f),
- CVector(1335.0244f, -224.59329f, 46.474979f),
- CVector(1355.4879f, -246.27664f, 49.934841f),
- CVector(1362.6003f, -276.47064f, 49.96265f),
- CVector(1363.027f, -307.30847f, 49.969173f),
- CVector(1365.343f, -338.08609f, 49.967789f),
- CVector(1367.5957f, -368.01105f, 50.092304f),
- CVector(1368.2749f, -398.38049f, 50.061268f),
- CVector(1366.9034f, -429.98483f, 50.057545f),
- CVector(1356.8534f, -459.09259f, 50.035545f),
- CVector(1335.5819f, -481.13544f, 47.217903f),
- CVector(1306.7552f, -491.07443f, 40.202629f),
- CVector(1275.5978f, -491.33194f, 33.969223f),
- CVector(1244.702f, -491.46451f, 29.111021f),
- CVector(1213.2222f, -491.8754f, 25.771168f),
- CVector(1182.7729f, -492.19995f, 24.749964f),
- CVector(1152.6874f, -491.42221f, 21.70038f),
- CVector(1121.5352f, -491.94604f, 20.075182f),
- CVector(1090.7056f, -492.63751f, 17.585758f),
- CVector(1059.6008f, -491.65762f, 14.848632f),
- CVector(1029.113f, -489.66031f, 14.918498f),
- CVector(998.20679f, -486.78107f, 14.945688f),
- CVector(968.00555f, -484.91266f, 15.001229f),
- CVector(937.74939f, -492.09015f, 14.958629f),
- CVector(927.17352f, -520.97736f, 14.972308f),
- CVector(929.29749f, -552.08643f, 14.978855f),
- CVector(950.69525f, -574.47778f, 14.972788f),
- CVector(974.02826f, -593.56024f, 14.966445f),
- CVector(989.04779f, -620.12854f, 14.951016f),
- CVector(1014.1639f, -637.3905f, 14.966736f),
- CVector(1017.5961f, -667.3736f, 14.956415f),
- CVector(1041.9735f, -685.94391f, 15.003841f),
- CVector(1043.3064f, -716.11298f, 14.974236f),
- CVector(1043.5337f, -746.63855f, 14.96919f),
- CVector(1044.142f, -776.93823f, 14.965424f),
- CVector(1044.2657f, -807.29395f, 14.97171f),
- CVector(1017.0797f, -820.1076f, 14.975431f),
- CVector(986.23865f, -820.37103f, 14.972883f),
- CVector(956.10065f, -820.23291f, 14.981133f),
- CVector(925.86914f, -820.19049f, 14.976553f),
- CVector(897.69702f, -831.08734f, 14.962709f),
- CVector(868.06586f, -835.99237f, 14.970685f),
- CVector(836.93054f, -836.84387f, 14.965049f),
- CVector(811.63586f, -853.7915f, 15.067576f),
- CVector(811.46344f, -884.27368f, 12.247812f),
- CVector(811.60651f, -914.70959f, 9.2393751f),
- CVector(811.10425f, -945.16272f, 5.817255f),
- CVector(816.54584f, -975.64587f, 4.998558f),
- CVector(828.2951f, -1003.3685f, 5.0471172f),
- CVector(852.28839f, -1021.5963f, 4.9371028f),
- CVector(882.50067f, -1025.4459f, 5.14077f),
- CVector(912.84821f, -1026.7874f, 8.3415451f),
- CVector(943.68274f, -1026.6914f, 11.341879f),
- CVector(974.4129f, -1027.3682f, 14.410345f),
- CVector(1004.1079f, -1036.0778f, 14.92961f),
- CVector(1030.1144f, -1051.1224f, 14.850387f),
- CVector(1058.7585f, -1060.342f, 14.821624f),
- CVector(1087.7797f, -1068.3263f, 14.800561f),
- CVector(1099.8807f, -1095.656f, 11.877907f),
- CVector(1130.0005f, -1101.994f, 11.853914f),
- CVector(1160.3809f, -1101.6355f, 11.854824f),
- CVector(1191.8524f, -1102.1577f, 11.853843f),
- CVector(1223.3307f, -1102.7448f, 11.852233f),
- CVector(1253.564f, -1098.1045f, 11.853944f),
- CVector(1262.0203f, -1069.1785f, 14.8147f),
- CVector(1290.9998f, -1059.1882f, 14.816016f),
- CVector(1316.246f, -1041.0635f, 14.81109f),
- CVector(1331.7539f, -1013.835f, 14.81207f),
- CVector(1334.0579f, -983.55402f, 14.827253f),
- CVector(1323.2429f, -954.23083f, 14.954678f),
- CVector(1302.7495f, -932.21216f, 14.962917f),
- CVector(1317.418f, -905.89325f, 14.967506f),
- CVector(1337.9503f, -883.5025f, 14.969675f),
- CVector(1352.6929f, -855.96954f, 14.967854f),
- CVector(1357.2388f, -826.26971f, 14.97295f),
- CVector(1384.8668f, -812.47693f, 12.907736f),
- CVector(1410.8983f, -795.39056f, 12.052228f),
- CVector(1433.901f, -775.55811f, 11.96265f),
- CVector(1443.8615f, -746.92511f, 11.976114f),
- CVector(1457.7015f, -720.00903f, 11.971177f),
- CVector(1481.5685f, -701.30237f, 11.977908f),
- CVector(1511.4004f, -696.83295f, 11.972709f),
- CVector(1542.1796f, -695.61676f, 11.970441f),
- CVector(1570.3301f, -684.6239f, 11.969202f),
CVector(0.0f, 0.0f, 0.0f),
};
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
CPacManPickups::GenerateOnePMPickUp(CVector pos)
{
- bPMActive = true;
- aPMPickUps[0].m_eType = PACMAN_RACE;
- aPMPickUps[0].m_vecPosn = pos;
}
void
CPacManPickups::Render()
{
- if (!bPMActive) return;
-
- PUSH_RENDERGROUP("CPacManPickups::Render");
-
- RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, FALSE);
- RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
- RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
- RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
- RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[6]));
-
- RwV3d pos;
- float w, h;
-
- for (int i = 0; i < NUMPACMANPICKUPS; i++) {
- switch (aPMPickUps[i].m_eType)
- {
- case PACMAN_SCRAMBLE:
- case PACMAN_RACE:
- if (CSprite::CalcScreenCoors(aPMPickUps[i].m_vecPosn, &pos, &w, &h, true) && pos.z < 100.0f) {
- if (aPMPickUps[i].m_pObject != nil) {
- aPMPickUps[i].m_pObject->GetMatrix().SetRotateZOnly((CTimer::GetTimeInMilliseconds() % 1024) * TWOPI / 1024.0f);
- aPMPickUps[i].m_pObject->GetMatrix().UpdateRW();
- aPMPickUps[i].m_pObject->UpdateRwFrame();
- }
- float fsin = Sin((CTimer::GetTimeInMilliseconds() % 1024) * 6.28f / 1024.0f); // yes, it is 6.28f when it was TWOPI just now...
- CSprite::RenderOneXLUSprite(pos.x, pos.y, pos.z, 0.8f * w * fsin, 0.8f * h, 100, 50, 5, 255, 1.0f / pos.z, 255);
- }
- break;
- default:
- break;
- }
- }
-
- RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
- RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
- RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
- RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, FALSE);
-
- POP_RENDERGROUP();
}
void
CPacManPickups::ClearPMPickUps()
{
- bPMActive = false;
-
- for (int i = 0; i < NUMPACMANPICKUPS; i++) {
- if (aPMPickUps[i].m_pObject != nil) {
- CWorld::Remove(aPMPickUps[i].m_pObject);
- delete aPMPickUps[i].m_pObject;
- aPMPickUps[i].m_pObject = nil;
- }
- aPMPickUps[i].m_eType = PACMAN_NONE;
- }
}
void
CPacManPickups::StartPacManRace(int32 race)
{
- GeneratePMPickUpsForRace(race);
- PillsEatenInRace = 0;
}
void
CPacManPickups::StartPacManRecord()
{
- CollectGameState = 20;
- LastPickUpCoors = FindPlayerCoors();
}
uint32
CPacManPickups::QueryPowerPillsEatenInRace()
{
- return PillsEatenInRace;
+ return 0;
}
void
CPacManPickups::ResetPowerPillsEatenInRace()
{
- PillsEatenInRace = 0;
}
void
CPacManPickups::CleanUpPacManStuff()
{
- ClearPMPickUps();
}
void
CPacManPickups::StartPacManScramble(CVector pos, float scrambleMult, int16 count)
{
- GeneratePMPickUps(pos, scrambleMult, count, PACMAN_SCRAMBLE);
}
uint32
CPacManPickups::QueryPowerPillsCarriedByPlayer()
{
- if (FindPlayerVehicle())
- return FindPlayerVehicle()->m_nPacManPickupsCarried;
return 0;
}
void
CPacManPickups::ResetPowerPillsCarriedByPlayer()
{
- if (FindPlayerVehicle() != nil) {
- FindPlayerVehicle()->m_nPacManPickupsCarried = 0;
- FindPlayerVehicle()->m_fMass /= FindPlayerVehicle()->m_fForceMultiplier;
- FindPlayerVehicle()->m_fTurnMass /= FindPlayerVehicle()->m_fForceMultiplier;
- FindPlayerVehicle()->m_fForceMultiplier = 1.0f;
- }
}
void
@@ -1493,54 +1653,60 @@ CPed::CreateDeadPedMoney(void)
int mi = GetModelIndex();
- if ((mi >= MI_COP && mi <= MI_FIREMAN) || CharCreatedBy == MISSION_CHAR || bInVehicle)
+ if ((mi >= MI_COP && mi <= MI_FIREMAN) || (CharCreatedBy == MISSION_CHAR && !bMoneyHasBeenGivenByScript) || bInVehicle)
return;
- int money = CGeneral::GetRandomNumber() % 60;
+ int money = m_nPedMoney;
if (money < 10)
return;
- if (money == 43)
- money = 700;
-
- int pickupCount = money / 40 + 1;
- int moneyPerPickup = money / pickupCount;
-
- 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));
- }
- }
+ CVector pickupPos = GetPosition();
+ CPickups::CreateSomeMoney(pickupPos, money);
+ m_nPedMoney = 0;
}
void
CPed::CreateDeadPedWeaponPickups(void)
{
- bool found = false;
- float angleToPed;
CVector pickupPos;
if (bInVehicle)
return;
- for(int i = 0; i < WEAPONTYPE_TOTAL_INVENTORY_WEAPONS; i++) {
+ for(int i = 0; i < TOTAL_WEAPON_SLOTS; i++) {
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;
+ int quantity = Min(weaponAmmo, AmmoForWeapon_OnStreet[weapon] / 2);
+ CreateDeadPedPickupCoors(&pickupPos.x, &pickupPos.y, &pickupPos.z);
+ pickupPos.z += 0.3f;
+ if (!CPickups::TryToMerge_WeaponType(pickupPos, weapon, PICKUP_ONCE_TIMEOUT, quantity, false)) {
+ CPickups::GenerateNewOne_WeaponType(pickupPos, weapon, PICKUP_ONCE_TIMEOUT, Min(weaponAmmo, quantity));
+ }
+ }
+ ClearWeapons();
+}
+
+void
+CPed::CreateDeadPedPickupCoors(float *x, float *y, float *z)
+{
+ bool found = false;
+ CVector pickupPos;
+
+#define NUMBER_OF_ATTEMPTS 32
+ for (int i = 0; i < NUMBER_OF_ATTEMPTS; i++) {
+
pickupPos = GetPosition();
- pickupPos.x += 1.5f * Sin(angleToPed);
- pickupPos.y += 1.5f * Cos(angleToPed);
+ pickupPos.x = 1.5f * Sin((CGeneral::GetRandomNumber() % 256)/256.0f * TWOPI) + GetPosition().x;
+ pickupPos.y = 1.5f * Cos((CGeneral::GetRandomNumber() % 256)/256.0f * TWOPI) + 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;
@@ -1548,21 +1714,29 @@ CPed::CreateDeadPedWeaponPickups(void)
float distance = pedToPickup.Magnitude();
// outer edge of pickup
- distance = (distance + 0.3f) / distance;
+ distance = (distance + 0.4f) / 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;
+ 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;
+ }
+ }
+ }
}
- if (found)
- CPickups::GenerateNewOne_WeaponType(pickupPos, weapon, PICKUP_ONCE_TIMEOUT, Min(weaponAmmo, AmmoForWeapon_OnStreet[weapon]));
}
- ClearWeapons();
+ *x = GetPosition().x;
+ *y = GetPosition().y;
+ *z = GetPosition().z + 0.4f;
+#undef NUMBER_OF_ATTEMPTS
} \ No newline at end of file
diff --git a/src/control/Pickups.h b/src/control/Pickups.h
index 4e1c7643..0de7f827 100644
--- a/src/control/Pickups.h
+++ b/src/control/Pickups.h
@@ -8,6 +8,7 @@ enum ePickupType
PICKUP_ON_STREET,
PICKUP_ONCE,
PICKUP_ONCE_TIMEOUT,
+ PICKUP_ONCE_TIMEOUT_SLOW,
PICKUP_COLLECTABLE1,
PICKUP_IN_SHOP_OUT_OF_STOCK,
PICKUP_MONEY,
@@ -18,6 +19,9 @@ enum ePickupType
PICKUP_FLOATINGPACKAGE,
PICKUP_FLOATINGPACKAGE_FLOATING,
PICKUP_ON_STREET_SLOW,
+ PICKUP_ASSET_REVENUE,
+ PICKUP_PROPERTY_LOCKED,
+ PICKUP_PROPERTY_FORSALE,
PICKUP_NUMOFTYPES
};
@@ -29,20 +33,29 @@ class CPlayerPed;
class CPickup
{
public:
- uint8 m_eType;
- bool m_bRemoved;
- uint16 m_nQuantity;
+ CVector m_vecPos;
+ float m_fRevenue;
CObject *m_pObject;
+ CObject *m_pExtraObject;
+ uint32 m_nQuantity;
uint32 m_nTimer;
+ uint16 m_nMoneySpeed;
int16 m_eModelIndex;
uint16 m_nIndex;
- CVector m_vecPos;
+ char m_sTextKey[8];
+ uint8 m_eType;
+ bool m_bRemoved;
+ uint8 m_bWasAmmoCollected:1;
+ uint8 m_bWasControlMessageShown:1;
- CObject *GiveUsAPickUpObject(int32 handle);
+ CObject *GiveUsAPickUpObject(CObject **object, CObject **extraObject, int32 handle, int32 extraHandle);
bool Update(CPlayerPed *player, CVehicle *vehicle, int playerId);
+ void GetRidOfObjects();
+ void ExtractAmmoFromPickup(CPlayerPed *player);
+ void ProcessGunShot(CVector *vec1, CVector *vec2);
private:
inline 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);
inline void Remove();
};
@@ -54,8 +67,9 @@ struct tPickupMessage
eWeaponType m_weaponType;
CVector2D m_dist;
CRGBA m_color;
- uint8 m_bOutOfStock : 1;
+ uint8 m_bOutOfStock;
uint8 m_quantity;
+ uint16 money;
};
class CPickups
@@ -65,6 +79,8 @@ class CPickups
static int16 NumMessages;
static tPickupMessage aMessages[NUMPICKUPMESSAGES];
public:
+ static int32 PlayerOnWeaponPickup;
+
static void Init();
static void Update();
static void RenderPickUpText();
@@ -72,19 +88,22 @@ public:
static void DoMoneyEffects(CEntity *ent);
static void DoMineEffects(CEntity *ent);
static void DoPickUpEffects(CEntity *ent);
- static int32 GenerateNewOne(CVector pos, uint32 modelIndex, uint8 type, uint32 quantity);
+ static int32 GenerateNewOne(CVector pos, uint32 modelIndex, uint8 type, uint32 quantity, uint32 rate = 0, bool highPriority = false, char* pText = nil);
static int32 GenerateNewOne_WeaponType(CVector pos, eWeaponType weaponType, uint8 type, uint32 quantity);
static void RemovePickUp(int32 pickupIndex);
- static void RemoveAllFloatingPickups();
static void AddToCollectedPickupsArray(int32 index);
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 DetonateMinesHitByGunShot(CVector *vec1, CVector *vec2);
+ static void RemoveUnnecessaryPickups(const CVector& center, float radius);
static void Load(uint8 *buf, uint32 size);
static void Save(uint8 *buf, uint32 *size);
@@ -95,11 +114,16 @@ public:
static CVehicle *pPlayerVehicle;
static CVector StaticCamCoors;
static uint32 StaticCamStartTime;
+
+ static void RemoveAllPickupsOfACertainWeaponGroupWithNoAmmo(eWeaponType);
+ static CPickup *FindPickUpForThisObject(CEntity*);
};
-extern uint16 AmmoForWeapon[20];
-extern uint16 AmmoForWeapon_OnStreet[20];
-extern uint16 CostOfWeapon[20];
+extern uint16 AmmoForWeapon[WEAPONTYPE_TOTALWEAPONS + 1];
+extern uint16 AmmoForWeapon_OnStreet[WEAPONTYPE_TOTALWEAPONS + 1];
+extern uint16 CostOfWeapon[WEAPONTYPE_TOTALWEAPONS + 3];
+
+extern int32 CollectPickupBuffer;
enum ePacmanPickupType
{
diff --git a/src/control/Record.cpp b/src/control/Record.cpp
index 7f636ec2..5e6c7cdb 100644
--- a/src/control/Record.cpp
+++ b/src/control/Record.cpp
@@ -9,521 +9,99 @@
#include "Timer.h"
#include "VehicleModelInfo.h"
#include "World.h"
-#include "Frontend.h"
uint16 CRecordDataForGame::RecordingState;
-uint8* CRecordDataForGame::pDataBuffer;
-uint8* CRecordDataForGame::pDataBufferPointer;
-int CRecordDataForGame::FId;
-tGameBuffer CRecordDataForGame::pDataBufferForFrame;
-
-#define MEMORY_FOR_GAME_RECORD (150000)
void CRecordDataForGame::Init(void)
{
RecordingState = STATE_NONE;
- delete[] pDataBuffer;
- pDataBufferPointer = nil;
- pDataBuffer = nil;
-#ifndef GTA_PS2 // this stuff is not present on PS2
- FId = CFileMgr::OpenFile("playback.dat", "r");
- if (FId <= 0) {
- if ((FId = CFileMgr::OpenFile("record.dat", "r")) <= 0)
- RecordingState = STATE_NONE;
- else {
- CFileMgr::CloseFile(FId);
- FId = CFileMgr::OpenFileForWriting("record.dat");
- RecordingState = STATE_RECORD;
- }
- }
- else {
- RecordingState = STATE_PLAYBACK;
- }
- if (RecordingState == STATE_PLAYBACK) {
- pDataBufferPointer = new uint8[MEMORY_FOR_GAME_RECORD];
- pDataBuffer = pDataBufferPointer;
- pDataBuffer[CFileMgr::Read(FId, (char*)pDataBufferPointer, MEMORY_FOR_GAME_RECORD) + 8] = (uint8)-1;
- CFileMgr::CloseFile(FId);
- }
-#else
- RecordingState = STATE_NONE; // second time to make sure
-#endif
}
void CRecordDataForGame::SaveOrRetrieveDataForThisFrame(void)
{
- switch (RecordingState) {
- case STATE_RECORD:
- {
- pDataBufferForFrame.m_fTimeStep = CTimer::GetTimeStep();
- pDataBufferForFrame.m_nTimeInMilliseconds = CTimer::GetTimeInMilliseconds();
- pDataBufferForFrame.m_nSizeOfPads[0] = 0;
- pDataBufferForFrame.m_nSizeOfPads[1] = 0;
- pDataBufferForFrame.m_nChecksum = CalcGameChecksum();
- uint8* pController1 = PackCurrentPadValues(pDataBufferForFrame.m_ControllerBuffer, &CPad::GetPad(0)->OldState, &CPad::GetPad(0)->NewState);
- pDataBufferForFrame.m_nSizeOfPads[0] = (pController1 - pDataBufferForFrame.m_ControllerBuffer) / 2;
- uint8* pController2 = PackCurrentPadValues(pController1, &CPad::GetPad(1)->OldState, &CPad::GetPad(1)->NewState);
- pDataBufferForFrame.m_nSizeOfPads[1] = (pController2 - pController1) / 2;
- uint8* pEndPtr = pController2;
- if ((pDataBufferForFrame.m_nSizeOfPads[0] + pDataBufferForFrame.m_nSizeOfPads[1]) & 1)
- pEndPtr += 2;
- CFileMgr::Write(FId, (char*)&pDataBufferForFrame, pEndPtr - (uint8*)&pDataBufferForFrame);
- break;
- }
- case STATE_PLAYBACK:
- if (pDataBufferPointer[8] == (uint8)-1)
- CPad::GetPad(0)->NewState.Clear();
- else {
- tGameBuffer* pData = (tGameBuffer*)pDataBufferPointer;
- CTimer::SetTimeInMilliseconds(pData->m_nTimeInMilliseconds);
- CTimer::SetTimeStep(pData->m_fTimeStep);
- uint8 size1 = pData->m_nSizeOfPads[0];
- uint8 size2 = pData->m_nSizeOfPads[1];
- pDataBufferPointer = (uint8*)&pData->m_ControllerBuffer;
- pDataBufferPointer = UnPackCurrentPadValues(pDataBufferPointer, size1, &CPad::GetPad(0)->NewState);
- pDataBufferPointer = UnPackCurrentPadValues(pDataBufferPointer, size2, &CPad::GetPad(1)->NewState);
- if ((size1 + size2) & 1)
- pDataBufferPointer += 2;
- if (pData->m_nChecksum != CalcGameChecksum())
- printf("Playback out of sync\n");
- }
- }
}
-#define PROCESS_BUTTON_STATE_STORE(buf, os, ns, field, id) \
- do { \
- if (os->field != ns->field){ \
- *buf++ = id; \
- *buf++ = ns->field; \
- } \
- } while (0);
-
uint8* CRecordDataForGame::PackCurrentPadValues(uint8* buf, CControllerState* os, CControllerState* ns)
{
- PROCESS_BUTTON_STATE_STORE(buf, os, ns, LeftStickX, 0);
- PROCESS_BUTTON_STATE_STORE(buf, os, ns, LeftStickY, 1);
- PROCESS_BUTTON_STATE_STORE(buf, os, ns, RightStickX, 2);
- PROCESS_BUTTON_STATE_STORE(buf, os, ns, RightStickY, 3);
- PROCESS_BUTTON_STATE_STORE(buf, os, ns, LeftShoulder1, 4);
- PROCESS_BUTTON_STATE_STORE(buf, os, ns, LeftShoulder2, 5);
- PROCESS_BUTTON_STATE_STORE(buf, os, ns, RightShoulder1, 6);
- PROCESS_BUTTON_STATE_STORE(buf, os, ns, RightShoulder2, 7);
- PROCESS_BUTTON_STATE_STORE(buf, os, ns, DPadUp, 8);
- PROCESS_BUTTON_STATE_STORE(buf, os, ns, DPadDown, 9);
- PROCESS_BUTTON_STATE_STORE(buf, os, ns, DPadLeft, 10);
- PROCESS_BUTTON_STATE_STORE(buf, os, ns, DPadRight, 11);
- PROCESS_BUTTON_STATE_STORE(buf, os, ns, Start, 12);
- PROCESS_BUTTON_STATE_STORE(buf, os, ns, Select, 13);
- PROCESS_BUTTON_STATE_STORE(buf, os, ns, Square, 14);
- PROCESS_BUTTON_STATE_STORE(buf, os, ns, Triangle, 15);
- PROCESS_BUTTON_STATE_STORE(buf, os, ns, Cross, 16);
- PROCESS_BUTTON_STATE_STORE(buf, os, ns, Circle, 17);
- PROCESS_BUTTON_STATE_STORE(buf, os, ns, LeftShock, 18);
- PROCESS_BUTTON_STATE_STORE(buf, os, ns, RightShock, 19);
- return buf;
+ return nil;
}
-#undef PROCESS_BUTTON_STATE_STORE
-
-#define PROCESS_BUTTON_STATE_RESTORE(buf, state, field, id) case id: state->field = *buf++; break;
uint8* CRecordDataForGame::UnPackCurrentPadValues(uint8* buf, uint8 total, CControllerState* state)
{
- for (uint8 i = 0; i < total; i++) {
- switch (*buf++) {
- PROCESS_BUTTON_STATE_RESTORE(buf, state, LeftStickX, 0);
- PROCESS_BUTTON_STATE_RESTORE(buf, state, LeftStickY, 1);
- PROCESS_BUTTON_STATE_RESTORE(buf, state, RightStickX, 2);
- PROCESS_BUTTON_STATE_RESTORE(buf, state, RightStickY, 3);
- PROCESS_BUTTON_STATE_RESTORE(buf, state, LeftShoulder1, 4);
- PROCESS_BUTTON_STATE_RESTORE(buf, state, LeftShoulder2, 5);
- PROCESS_BUTTON_STATE_RESTORE(buf, state, RightShoulder1, 6);
- PROCESS_BUTTON_STATE_RESTORE(buf, state, RightShoulder2, 7);
- PROCESS_BUTTON_STATE_RESTORE(buf, state, DPadUp, 8);
- PROCESS_BUTTON_STATE_RESTORE(buf, state, DPadDown, 9);
- PROCESS_BUTTON_STATE_RESTORE(buf, state, DPadLeft, 10);
- PROCESS_BUTTON_STATE_RESTORE(buf, state, DPadRight, 11);
- PROCESS_BUTTON_STATE_RESTORE(buf, state, Start, 12);
- PROCESS_BUTTON_STATE_RESTORE(buf, state, Select, 13);
- PROCESS_BUTTON_STATE_RESTORE(buf, state, Square, 14);
- PROCESS_BUTTON_STATE_RESTORE(buf, state, Triangle, 15);
- PROCESS_BUTTON_STATE_RESTORE(buf, state, Cross, 16);
- PROCESS_BUTTON_STATE_RESTORE(buf, state, Circle, 17);
- PROCESS_BUTTON_STATE_RESTORE(buf, state, LeftShock, 18);
- PROCESS_BUTTON_STATE_RESTORE(buf, state, RightShock, 19);
- }
- }
- return buf;
+ return nil;
}
-#undef PROCESS_BUTTON_STATE_RESTORE
-
uint16 CRecordDataForGame::CalcGameChecksum(void)
{
- uint32 checksum = 0;
- int i = CPools::GetPedPool()->GetSize();
- while (i--) {
- CPed* pPed = CPools::GetPedPool()->GetSlot(i);
- if (!pPed)
- continue;
- checksum ^= pPed->GetModelIndex() ^ *(uint32*)&pPed->GetPosition().z ^ *(uint32*)&pPed->GetPosition().y ^ *(uint32*)&pPed->GetPosition().x;
- }
- i = CPools::GetVehiclePool()->GetSize();
- while (i--) {
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
- if (!pVehicle)
- continue;
- checksum ^= pVehicle->GetModelIndex() ^ *(uint32*)&pVehicle->GetPosition().z ^ *(uint32*)&pVehicle->GetPosition().y ^ *(uint32*)&pVehicle->GetPosition().x;
- }
- return checksum ^ checksum >> 16;
+ return 0;
}
uint8 CRecordDataForChase::Status;
-int CRecordDataForChase::PositionChanges;
-uint8 CRecordDataForChase::CurrentCar;
-CAutomobile* CRecordDataForChase::pChaseCars[NUM_CHASE_CARS];
-uint32 CRecordDataForChase::AnimStartTime;
-float CRecordDataForChase::AnimTime;
-CCarStateEachFrame* CRecordDataForChase::pBaseMemForCar[NUM_CHASE_CARS];
-float CRecordDataForChase::TimeMultiplier;
-int CRecordDataForChase::FId2;
-
-#define CHASE_SCENE_LENGTH_IN_SECONDS (80)
-#define CHASE_SCENE_FRAMES_PER_SECOND (15) // skipping every second frame
-#define CHASE_SCENE_FRAMES_IN_RECORDING (CHASE_SCENE_LENGTH_IN_SECONDS * CHASE_SCENE_FRAMES_PER_SECOND)
-#define CHASE_SCENE_LENGTH_IN_FRAMES (CHASE_SCENE_FRAMES_IN_RECORDING * 2)
void CRecordDataForChase::Init(void)
{
Status = STATE_NONE;
- PositionChanges = 0;
- CurrentCar = 0;
- for (int i = 0; i < NUM_CHASE_CARS; i++)
- pChaseCars[i] = nil;
- AnimStartTime = 0;
}
void CRecordDataForChase::SaveOrRetrieveDataForThisFrame(void)
{
- switch (Status) {
- case STATE_NONE:
- return;
- case STATE_RECORD:
- {
- if ((CTimer::GetFrameCounter() & 1) == 0)
- StoreInfoForCar(pChaseCars[CurrentCar], &pBaseMemForCar[CurrentCar][CTimer::GetFrameCounter() / 2]);
- if (CTimer::GetFrameCounter() < CHASE_SCENE_LENGTH_IN_FRAMES * 2)
- return;
- CFileMgr::SetDir("data\\paths");
- sprintf(gString, "chase%d.dat", CurrentCar);
- int fid = CFileMgr::OpenFileForWriting(gString);
- uint32 fs = CHASE_SCENE_LENGTH_IN_FRAMES * sizeof(CCarStateEachFrame);
- printf("FileSize:%d\n", fs);
- CFileMgr::Write(fid, (char*)pBaseMemForCar[CurrentCar], fs);
- CFileMgr::CloseFile(fid);
- CFileMgr::SetDir("");
- sprintf(gString, "car%d.max", CurrentCar);
- int fid2 = CFileMgr::OpenFileForWriting(gString);
- for (int i = 0; i < CHASE_SCENE_FRAMES_IN_RECORDING; i++) {
- // WTF? Was it ever used?
-#ifdef FIX_BUGS
- CCarStateEachFrame* pState = pBaseMemForCar[CurrentCar];
-#else
- CCarStateEachFrame* pState = (CCarStateEachFrame*)pChaseCars[CurrentCar];
-#endif
- CVector right = CVector(pState->rightX, pState->rightY, pState->rightZ) / INT8_MAX;
- CVector forward = CVector(pState->forwardX, pState->forwardY, pState->forwardZ) / INT8_MAX;
- CVector up = CrossProduct(right, forward);
- sprintf(gString, "%f %f %f\n", pState->pos.x, pState->pos.y, pState->pos.z);
- CFileMgr::Write(fid2, gString, strlen(gString) - 1);
- sprintf(gString, "%f %f %f\n", right.x, right.y, right.z);
- CFileMgr::Write(fid2, gString, strlen(gString) - 1);
- sprintf(gString, "%f %f %f\n", forward.x, forward.y, forward.z);
- CFileMgr::Write(fid2, gString, strlen(gString) - 1);
- sprintf(gString, "%f %f %f\n", up.x, up.y, up.z);
- CFileMgr::Write(fid2, gString, strlen(gString) - 1);
- }
- CFileMgr::CloseFile(fid2);
- }
- case STATE_PLAYBACK:
- case STATE_PLAYBACK_BEFORE_RECORDING:
- case STATE_PLAYBACK_INIT:
- break;
- }
}
-struct tCoors {
- CVector pos;
- float angle;
-};
-
-// I guess developer was filling this with actual data before running the game
-tCoors NewCoorsForRecordedCars[7];
-
void CRecordDataForChase::SaveOrRetrieveCarPositions(void)
{
- switch (Status) {
- case STATE_NONE:
- return;
- case STATE_RECORD:
- case STATE_PLAYBACK_BEFORE_RECORDING:
- for (int i = 0; i < NUM_CHASE_CARS; i++) {
- if (i != CurrentCar && CTimer::GetFrameCounter()) {
- RestoreInfoForCar(pChaseCars[i], &pBaseMemForCar[i][CTimer::GetFrameCounter() / 2], false);
- pChaseCars[i]->GetMatrix().UpdateRW();
- pChaseCars[i]->UpdateRwFrame();
- }
- }
- if (Status == STATE_PLAYBACK_BEFORE_RECORDING && CTimer::GetFrameCounter()) {
- RestoreInfoForCar(pChaseCars[CurrentCar], &pBaseMemForCar[CurrentCar][CTimer::GetFrameCounter() / 2], false);
- pChaseCars[CurrentCar]->GetMatrix().UpdateRW();
- pChaseCars[CurrentCar]->UpdateRwFrame();
- }
- if (CPad::GetPad(0)->GetLeftShockJustDown() && CPad::GetPad(0)->GetRightShockJustDown()) {
- if (!CPad::GetPad(0)->GetRightShockJustDown()) {
- pChaseCars[CurrentCar]->SetPosition(NewCoorsForRecordedCars[PositionChanges].pos);
- pChaseCars[CurrentCar]->SetMoveSpeed(0.0f, 0.0f, 0.0f);
- pChaseCars[CurrentCar]->GetMatrix().SetRotateZOnly(DEGTORAD(NewCoorsForRecordedCars[PositionChanges].angle));
- ++PositionChanges;
- }
- if (Status == STATE_PLAYBACK_BEFORE_RECORDING) {
- Status = STATE_RECORD;
- pChaseCars[CurrentCar]->SetStatus(STATUS_PLAYER);
- }
- }
- break;
- case STATE_PLAYBACK_INIT:
- Status = STATE_PLAYBACK;
- break;
- case STATE_PLAYBACK:
- {
- TimeMultiplier += CTimer::GetTimeStepNonClippedInSeconds();
- float EndOfFrameTime = CHASE_SCENE_FRAMES_PER_SECOND * Min(CHASE_SCENE_LENGTH_IN_SECONDS, TimeMultiplier);
- for (int i = 0; i < NUM_CHASE_CARS; i++) {
- if (!pBaseMemForCar[i])
- continue;
- if (!pChaseCars[i])
- continue;
- if (EndOfFrameTime < CHASE_SCENE_FRAMES_IN_RECORDING - 1) {
- int FlooredEOFTime = EndOfFrameTime;
- RestoreInfoForCar(pChaseCars[i], &pBaseMemForCar[i][FlooredEOFTime], false);
- CMatrix tmp;
- float dp = EndOfFrameTime - FlooredEOFTime;
- RestoreInfoForMatrix(tmp, &pBaseMemForCar[i][FlooredEOFTime + 1]);
- pChaseCars[i]->GetRight() += (tmp.GetRight() - pChaseCars[i]->GetRight()) * dp;
- pChaseCars[i]->GetForward() += (tmp.GetForward() - pChaseCars[i]->GetForward()) * dp;
- pChaseCars[i]->GetUp() += (tmp.GetUp() - pChaseCars[i]->GetUp()) * dp;
- pChaseCars[i]->GetMatrix().GetPosition() += (tmp.GetPosition() - pChaseCars[i]->GetPosition()) * dp;
- }
- else{
- RestoreInfoForCar(pChaseCars[i], &pBaseMemForCar[i][CHASE_SCENE_FRAMES_IN_RECORDING - 1], true);
- if (i == 0)
- pChaseCars[i]->GetMatrix().GetPosition().z += 0.2f;
- }
- pChaseCars[i]->GetMatrix().UpdateRW();
- pChaseCars[i]->UpdateRwFrame();
- pChaseCars[i]->RemoveAndAdd();
- }
- break;
- }
- }
}
void CRecordDataForChase::StoreInfoForCar(CAutomobile* pCar, CCarStateEachFrame* pState)
{
- pState->rightX = INT8_MAX * pCar->GetRight().x;
- pState->rightY = INT8_MAX * pCar->GetRight().y;
- pState->rightZ = INT8_MAX * pCar->GetRight().z;
- pState->forwardX = INT8_MAX * pCar->GetForward().x;
- pState->forwardY = INT8_MAX * pCar->GetForward().y;
- pState->forwardZ = INT8_MAX * pCar->GetForward().z;
- pState->pos = pCar->GetPosition();
- pState->velX = 0.5f * INT16_MAX * pCar->GetMoveSpeed().x;
- pState->velY = 0.5f * INT16_MAX * pCar->GetMoveSpeed().y;
- pState->velZ = 0.5f * INT16_MAX * pCar->GetMoveSpeed().z;
- pState->wheel = 20 * pCar->m_fSteerAngle;
- pState->gas = 100 * pCar->m_fGasPedal;
- pState->brake = 100 * pCar->m_fBrakePedal;
- pState->handbrake = pCar->bIsHandbrakeOn;
}
void CRecordDataForChase::RestoreInfoForMatrix(CMatrix& matrix, CCarStateEachFrame* pState)
{
- matrix.GetRight() = CVector(pState->rightX, pState->rightY, pState->rightZ) / INT8_MAX;
- matrix.GetForward() = CVector(pState->forwardX, pState->forwardY, pState->forwardZ) / INT8_MAX;
- matrix.GetUp() = CrossProduct(matrix.GetRight(), matrix.GetForward());
- matrix.GetPosition() = pState->pos;
}
void CRecordDataForChase::RestoreInfoForCar(CAutomobile* pCar, CCarStateEachFrame* pState, bool stop)
{
- CVector oldPos = pCar->GetPosition();
- RestoreInfoForMatrix(pCar->GetMatrix(), pState);
- pCar->SetMoveSpeed(CVector(pState->velX, pState->velY, pState->velZ) / INT16_MAX / 0.5f);
- pCar->SetTurnSpeed(0.0f, 0.0f, 0.0f);
- pCar->m_fSteerAngle = pState->wheel / 20.0f;
- pCar->m_fGasPedal = pState->gas / 100.0f;
- pCar->m_fBrakePedal = pState->brake / 100.0f;
- pCar->bIsHandbrakeOn = pState->handbrake;
- if ((oldPos - pCar->GetPosition()).Magnitude() > 15.0f) {
- if (pCar == pChaseCars[14]) {
- pCar->m_currentColour1 = 58;
- pCar->m_currentColour2 = 1;
- }
- else
- pCar->GetModelInfo()->ChooseVehicleColour(pCar->m_currentColour1, pCar->m_currentColour2);
- }
- pCar->m_fHealth = Min(pCar->m_fHealth, 500.0f);
- if (stop) {
- pCar->m_fGasPedal = 0.0f;
- pCar->m_fBrakePedal = 0.0f;
- pCar->SetMoveSpeed(0.0f, 0.0f, 0.0f);
- pCar->bIsHandbrakeOn = false;
- }
}
void CRecordDataForChase::ProcessControlCars(void)
{
- if (Status != STATE_PLAYBACK)
- return;
- for (int i = 0; i < NUM_CHASE_CARS; i++) {
- if (pChaseCars[i])
- pChaseCars[i]->ProcessControl();
- }
}
bool CRecordDataForChase::ShouldThisPadBeLeftAlone(uint8 pad)
{
- // may be wrong
- if (Status == STATE_PLAYBACK_INIT) // this is useless but ps2 def checks if it's STATE_PLAYBACK_INIT
- return false;
-
- if (Status == STATE_RECORD)
- return pad != 0;
-
return false;
}
void CRecordDataForChase::GiveUsACar(int32 mi, CVector pos, float angle, CAutomobile** ppCar, uint8 colour1, uint8 colour2)
{
- CStreaming::RequestModel(mi, STREAMFLAGS_DEPENDENCY);
- CStreaming::LoadAllRequestedModels(false);
- if (!CStreaming::HasModelLoaded(mi))
- return;
- CAutomobile* pCar = new CAutomobile(mi, MISSION_VEHICLE);
- pCar->SetPosition(pos);
- pCar->SetStatus(STATUS_PLAYER_PLAYBACKFROMBUFFER);
- pCar->GetMatrix().SetRotateZOnly(DEGTORAD(angle));
- pCar->pDriver = nil;
- pCar->m_currentColour1 = colour1;
- pCar->m_currentColour2 = colour2;
- CWorld::Add(pCar);
- *ppCar = pCar;
}
void RemoveUnusedCollision(void)
{
- static const char* dontDeleteArray[] = {
- "rd_SrRoad2A50", "rd_SrRoad2A20", "rd_CrossRda1w22", "rd_CrossRda1rw22",
- "road_broadway02", "road_broadway01", "com_21way5", "com_21way50",
- "cm1waycrosscom", "com_21way20", "com_21way10", "road_broadway04",
- "com_rvroads52", "com_roadsrv", "com_roadkb23", "com_roadkb22"
- };
- for (int i = 0; i < ARRAY_SIZE(dontDeleteArray); i++)
- CModelInfo::GetModelInfo(dontDeleteArray[i], nil)->GetColModel()->level = LEVEL_GENERIC;
- CModelInfo::RemoveColModelsFromOtherLevels(LEVEL_GENERIC);
- for (int i = 0; i < ARRAY_SIZE(dontDeleteArray); i++)
- CModelInfo::GetModelInfo(dontDeleteArray[i], nil)->GetColModel()->level = LEVEL_COMMERCIAL;
}
void CRecordDataForChase::StartChaseScene(float startTime)
{
- char filename[28];
- SetUpCarsForChaseScene();
- Status = STATE_PLAYBACK;
- AnimTime = startTime;
- AnimStartTime = CTimer::GetTimeInMilliseconds();
-#ifdef NO_ISLAND_LOADING
- if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_LOW)
-#endif
- RemoveUnusedCollision();
- CStreaming::RemoveIslandsNotUsed(LEVEL_SUBURBAN);
- CGame::TidyUpMemory(true, true);
- CStreaming::ImGonnaUseStreamingMemory();
- CFileMgr::SetDir("data\\paths");
- for (int i = 0; i < NUM_CHASE_CARS; i++) {
- if (!pChaseCars[i]) {
- pBaseMemForCar[i] = nil;
- continue;
- }
- sprintf(filename, "chase%d.dat", i);
- FId2 = CFileMgr::OpenFile(filename, "rb");
- if (FId2 <= 0) {
- pBaseMemForCar[i] = nil;
- continue;
- }
- pBaseMemForCar[i] = new CCarStateEachFrame[CHASE_SCENE_FRAMES_IN_RECORDING];
- for (int j = 0; j < CHASE_SCENE_FRAMES_IN_RECORDING; j++) {
- CFileMgr::Read(FId2, (char*)&pBaseMemForCar[i][j], sizeof(CCarStateEachFrame));
- CFileMgr::Seek(FId2, sizeof(CCarStateEachFrame), 1);
- }
- CFileMgr::CloseFile(FId2);
- }
- CFileMgr::SetDir("");
- CStreaming::IHaveUsedStreamingMemory();
- TimeMultiplier = 0.0f;
}
void CRecordDataForChase::CleanUpChaseScene(void)
{
- if (Status != STATE_PLAYBACK_INIT && Status != STATE_PLAYBACK)
- return;
- Status = STATE_NONE;
- CleanUpCarsForChaseScene();
- for (int i = 0; i < NUM_CHASE_CARS; i++) {
- if (pBaseMemForCar[i]) {
- delete[] pBaseMemForCar[i];
- pBaseMemForCar[i] = nil;
- }
- }
}
void CRecordDataForChase::SetUpCarsForChaseScene(void)
{
- GiveUsACar(MI_POLICE, CVector(273.54221f, -1167.1907f, 24.880601f), 63.0f, &pChaseCars[0], 2, 1);
- GiveUsACar(MI_ENFORCER, CVector(231.1783f, -1388.8322f, 25.978201f), 90.0f, &pChaseCars[1], 2, 1);
- GiveUsACar(MI_TAXI, CVector(184.3156f, -1473.251f, 25.978201f), 0.0f, &pChaseCars[4], 6, 6);
- GiveUsACar(MI_CHEETAH, CVector(173.8868f, -1377.6514f, 25.978201f), 0.0f, &pChaseCars[6], 4, 5);
- GiveUsACar(MI_STINGER, CVector(102.5946f, -943.93628f, 25.9781f), 270.0f, &pChaseCars[7], 53, 53);
- GiveUsACar(MI_CHEETAH, CVector(-177.7157f, -862.18652f, 25.978201f), 155.0f, &pChaseCars[10], 41, 1);
- GiveUsACar(MI_STINGER, CVector(-170.56979f, -889.02362f, 25.978201f), 154.0f, &pChaseCars[11], 10, 10);
- GiveUsACar(MI_KURUMA, CVector(402.60809f, -917.49628f, 37.381001f), 90.0f, &pChaseCars[14], 34, 1);
- GiveUsACar(MI_TAXI, CVector(-33.496201f, -938.4563f, 25.9781f), 266.0f, &pChaseCars[16], 6, 6);
- GiveUsACar(MI_KURUMA, CVector(49.363098f, -987.60498f, 25.9781f), 0.0f, &pChaseCars[18], 51, 1);
- GiveUsACar(MI_TAXI, CVector(179.0049f, -1154.6686f, 25.9781f), 0.0f, &pChaseCars[19], 6, 76);
- GiveUsACar(MI_RUMPO, CVector(-28.9762f, -1031.3367f, 25.990601f), 242.0f, &pChaseCars[2], 1, 75);
- GiveUsACar(MI_PATRIOT, CVector(114.1564f, -796.69379f, 24.978201f), 180.0f, &pChaseCars[3], 0, 0);
}
void CRecordDataForChase::CleanUpCarsForChaseScene(void)
{
- for (int i = 0; i < NUM_CHASE_CARS; i++)
- RemoveCarFromChase(i);
}
void CRecordDataForChase::RemoveCarFromChase(int32 i)
{
- if (!pChaseCars[i])
- return;
- CWorld::Remove(pChaseCars[i]);
- delete pChaseCars[i];
- pChaseCars[i] = nil;
}
CVehicle* CRecordDataForChase::TurnChaseCarIntoScriptCar(int32 i)
{
- CVehicle* pVehicle = pChaseCars[i];
- pChaseCars[i] = nil;
- pVehicle->SetStatus(STATUS_PHYSICS);
- return pVehicle;
+ return nil;
}
diff --git a/src/control/Remote.cpp b/src/control/Remote.cpp
index 904e9023..047b19f3 100644
--- a/src/control/Remote.cpp
+++ b/src/control/Remote.cpp
@@ -35,17 +35,24 @@ CRemote::GivePlayerRemoteControlledCar(float x, float y, float z, float rot, uin
CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle = car;
CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->RegisterReference((CEntity**)&CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle);
- TheCamera.TakeControl(car, CCam::MODE_BEHINDCAR, INTERPOLATION, CAMCONTROL_SCRIPT);
+ if (car->GetVehicleAppearance() == VEHICLE_APPEARANCE_PLANE || car->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI) {
+ TheCamera.TakeControl(car, CCam::MODE_CAM_ON_A_STRING, INTERPOLATION, CAMCONTROL_SCRIPT);
+ TheCamera.SetZoomValueCamStringScript(0);
+ } else
+ TheCamera.TakeControl(car, CCam::MODE_BEHINDCAR, INTERPOLATION, CAMCONTROL_SCRIPT);
}
void
-CRemote::TakeRemoteControlledCarFromPlayer(void)
+CRemote::TakeRemoteControlledCarFromPlayer(bool blowUp)
{
- CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->VehicleCreatedBy = RANDOM_VEHICLE;
- CCarCtrl::NumMissionCars--;
- CCarCtrl::NumRandomCars++;
+ if (CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->VehicleCreatedBy == MISSION_VEHICLE) {
+ CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->VehicleCreatedBy = RANDOM_VEHICLE;
+ CCarCtrl::NumMissionCars--;
+ CCarCtrl::NumRandomCars++;
+ }
CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->bIsLocked = false;
CWorld::Players[CWorld::PlayerInFocus].m_nTimeLostRemoteCar = CTimer::GetTimeInMilliseconds();
CWorld::Players[CWorld::PlayerInFocus].m_bInRemoteMode = true;
- CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->bRemoveFromWorld = true;
+ CWorld::Players[CWorld::PlayerInFocus].field_D5 = blowUp;
+ CWorld::Players[CWorld::PlayerInFocus].field_D6 = true;
}
diff --git a/src/control/Remote.h b/src/control/Remote.h
index 5e474586..72cabb7c 100644
--- a/src/control/Remote.h
+++ b/src/control/Remote.h
@@ -4,5 +4,5 @@ class CRemote
{
public:
static void GivePlayerRemoteControlledCar(float, float, float, float, uint16);
- static void TakeRemoteControlledCarFromPlayer(void);
+ static void TakeRemoteControlledCarFromPlayer(bool blowUp = true);
};
diff --git a/src/control/Replay.cpp b/src/control/Replay.cpp
index b9b5530c..71b28f7a 100644
--- a/src/control/Replay.cpp
+++ b/src/control/Replay.cpp
@@ -1,19 +1,22 @@
#include "common.h"
#ifdef GTA_REPLAY
+#include "AnimBlendAssocGroup.h"
#include "AnimBlendAssociation.h"
+#include "Bike.h"
#include "Boat.h"
#include "SpecialFX.h"
#include "CarCtrl.h"
#include "CivilianPed.h"
+#include "CopPed.h"
#include "Wanted.h"
#include "Clock.h"
#include "DMAudio.h"
#include "Draw.h"
+#include "Explosion.h"
#include "FileMgr.h"
-#ifdef FIX_BUGS
#include "Fire.h"
+#include "Frontend.h"
#include "Garages.h"
-#endif
#include "Heli.h"
#include "main.h"
#include "Matrix.h"
@@ -21,15 +24,15 @@
#include "ModelInfo.h"
#include "Object.h"
#include "Pad.h"
+#include "Particle.h"
+#include "PedAttractor.h"
#include "Phones.h"
#include "Pickups.h"
#include "Plane.h"
#include "Pools.h"
#include "Population.h"
-#ifdef FIX_BUGS
#include "Projectile.h"
#include "ProjectileInfo.h"
-#endif
#include "Replay.h"
#include "References.h"
#include "Pools.h"
@@ -37,6 +40,7 @@
#include "RwHelper.h"
#include "CutsceneMgr.h"
#include "Skidmarks.h"
+#include "Stinger.h"
#include "Streaming.h"
#include "Timer.h"
#include "Train.h"
@@ -46,6 +50,8 @@
#include "Text.h"
#include "Camera.h"
#include "Radar.h"
+#include "Fluff.h"
+#include "WaterCreatures.h"
uint8 CReplay::Mode;
CAddressInReplayBuffer CReplay::Record;
@@ -55,7 +61,7 @@ CAutomobile *CReplay::pBuf1;
uint8 *CReplay::pBuf2;
CPlayerPed *CReplay::pBuf3;
uint8 *CReplay::pBuf4;
-CCutsceneHead *CReplay::pBuf5;
+CCutsceneObject *CReplay::pBuf5;
uint8 *CReplay::pBuf6;
CPtrNode *CReplay::pBuf7;
uint8 *CReplay::pBuf8;
@@ -109,12 +115,32 @@ bool CReplay::bPlayerInRCBuggy;
float CReplay::fDistanceLookAroundCam;
float CReplay::fBetaAngleLookAroundCam;
float CReplay::fAlphaAngleLookAroundCam;
-#ifdef FIX_BUGS
+int CReplay::ms_nNumCivMale_Stored;
+int CReplay::ms_nNumCivFemale_Stored;
+int CReplay::ms_nNumCop_Stored;
+int CReplay::ms_nNumEmergency_Stored;
+int CReplay::ms_nNumGang1_Stored;
+int CReplay::ms_nNumGang2_Stored;
+int CReplay::ms_nNumGang3_Stored;
+int CReplay::ms_nNumGang4_Stored;
+int CReplay::ms_nNumGang5_Stored;
+int CReplay::ms_nNumGang6_Stored;
+int CReplay::ms_nNumGang7_Stored;
+int CReplay::ms_nNumGang8_Stored;
+int CReplay::ms_nNumGang9_Stored;
+int CReplay::ms_nNumDummy_Stored;
+int CReplay::ms_nTotalCarPassengerPeds_Stored;
+int CReplay::ms_nTotalCivPeds_Stored;
+int CReplay::ms_nTotalGangPeds_Stored;
+int CReplay::ms_nTotalPeds_Stored;
+int CReplay::ms_nTotalMissionPeds_Stored;
uint8* CReplay::pGarages;
CFire* CReplay::FireArray;
uint32 CReplay::NumOfFires;
uint8* CReplay::paProjectileInfo;
uint8* CReplay::paProjectiles;
+uint8 CReplay::CurrArea;
+#ifdef FIX_BUGS
int CReplay::nHandleOfPlayerPed[NUMPLAYERS];
#endif
@@ -123,9 +149,15 @@ static void(*CBArray[])(CAnimBlendAssociation*, void*) =
nil, &CPed::PedGetupCB, &CPed::PedStaggerCB, &CPed::PedEvadeCB, &CPed::FinishDieAnimCB,
&CPed::FinishedWaitCB, &CPed::FinishLaunchCB, &CPed::FinishHitHeadCB, &CPed::PedAnimGetInCB, &CPed::PedAnimDoorOpenCB,
&CPed::PedAnimPullPedOutCB, &CPed::PedAnimDoorCloseCB, &CPed::PedSetInCarCB, &CPed::PedSetOutCarCB, &CPed::PedAnimAlignCB,
- &CPed::PedSetDraggedOutCarCB, &CPed::PedAnimStepOutCarCB, &CPed::PedSetInTrainCB, &CPed::PedSetOutTrainCB, &CPed::FinishedAttackCB,
+ &CPed::PedSetDraggedOutCarCB, &CPed::PedAnimStepOutCarCB, &CPed::PedSetInTrainCB,
+#ifdef GTA_TRAIN
+ &CPed::PedSetOutTrainCB,
+#endif
+ &CPed::FinishedAttackCB,
&CPed::FinishFightMoveCB, &PhonePutDownCB, &PhonePickUpCB, &CPed::PedAnimDoorCloseRollingCB, &CPed::FinishJumpCB,
- &CPed::PedLandCB, &FinishFuckUCB, &CPed::RestoreHeadingRateCB, &CPed::PedSetQuickDraggedOutCarPositionCB, &CPed::PedSetDraggedOutCarPositionCB
+ &CPed::PedLandCB, &CPed::RestoreHeadingRateCB, &CPed::PedSetQuickDraggedOutCarPositionCB, &CPed::PedSetDraggedOutCarPositionCB,
+ &CPed::PedSetPreviousStateCB, &CPed::FinishedReloadCB, &CPed::PedSetGetInCarPositionCB,
+ &CPed::PedAnimShuffleCB, &CPed::DeleteSunbatheIdleAnimCB, &StartTalkingOnMobileCB, &FinishTalkingOnMobileCB
};
static uint8 FindCBFunctionID(void(*f)(CAnimBlendAssociation*, void*))
@@ -221,6 +253,7 @@ void CReplay::Init(void)
SlowMotion = 1;
FramesActiveLookAroundCam = 0;
bDoLoadSceneWhenDone = false;
+ MarkEverythingAsNew();
}
void CReplay::DisableReplays(void)
@@ -236,8 +269,10 @@ void CReplay::EnableReplays(void)
void PlayReplayFromHD(void);
void CReplay::Update(void)
{
- if (CCutsceneMgr::IsCutsceneProcessing() || CTimer::GetIsPaused())
+ if (CCutsceneMgr::IsCutsceneProcessing() || CPad::GetPad(0)->ArePlayerControlsDisabled() || CScriptPaths::IsOneActive() || FrontEndMenuManager.GetIsMenuActive()) {
+ Init();
return;
+ }
switch (Mode){
case MODE_RECORD:
RecordThisFrame();
@@ -268,13 +303,16 @@ void CReplay::Update(void)
void CReplay::RecordThisFrame(void)
{
-#ifdef FIX_REPLAY_BUGS
- uint32 memory_required = sizeof(tGeneralPacket) + sizeof(tClockPacket) + sizeof(tWeatherPacket) + sizeof(tTimerPacket);
+ uint32 memory_required = sizeof(tGeneralPacket) + sizeof(tClockPacket) + sizeof(tWeatherPacket) + sizeof(tTimerPacket) + sizeof(tMiscPacket);
CVehiclePool* vehiclesT = CPools::GetVehiclePool();
for (int i = 0; i < vehiclesT->GetSize(); i++) {
CVehicle* v = vehiclesT->GetSlot(i);
- if (v && v->m_rwObject && v->GetModelIndex() != MI_AIRTRAIN && v->GetModelIndex() != MI_TRAIN)
- memory_required += sizeof(tVehicleUpdatePacket);
+ if (v && v->m_rwObject && v->GetModelIndex() != MI_AIRTRAIN && v->GetModelIndex() != MI_TRAIN) {
+ if (v->IsBike())
+ memory_required += sizeof(tBikeUpdatePacket);
+ else
+ memory_required += sizeof(tVehicleUpdatePacket);
+ }
}
CPedPool* pedsT = CPools::GetPedPool();
for (int i = 0; i < pedsT->GetSize(); i++) {
@@ -292,17 +330,8 @@ void CReplay::RecordThisFrame(void)
memory_required += sizeof(tBulletTracePacket);
}
memory_required += sizeof(tEndOfFramePacket) + 1; // 1 for Record.m_pBase[Record.m_nOffset] = REPLAYPACKET_END;
- if (Record.m_nOffset + memory_required > REPLAYBUFFERSIZE) {
- Record.m_pBase[Record.m_nOffset] = REPLAYPACKET_END;
- BufferStatus[Record.m_bSlot] = REPLAYBUFFER_PLAYBACK;
- Record.m_bSlot = (Record.m_bSlot + 1) % NUM_REPLAYBUFFERS;
- BufferStatus[Record.m_bSlot] = REPLAYBUFFER_RECORD;
- Record.m_pBase = Buffers[Record.m_bSlot];
- Record.m_nOffset = 0;
- *Record.m_pBase = REPLAYPACKET_END;
- MarkEverythingAsNew();
- }
-#endif
+ if (Record.m_nOffset + memory_required > REPLAYBUFFERSIZE - 16)
+ GoToNextBlock();
tGeneralPacket* general = (tGeneralPacket*)&Record.m_pBase[Record.m_nOffset];
general->type = REPLAYPACKET_GENERAL;
general->camera_pos.CopyOnlyMatrix(TheCamera.GetMatrix());
@@ -327,8 +356,12 @@ void CReplay::RecordThisFrame(void)
CVehiclePool* vehicles = CPools::GetVehiclePool();
for (int i = 0; i < vehicles->GetSize(); i++){
CVehicle* v = vehicles->GetSlot(i);
- if (v && v->m_rwObject && v->GetModelIndex() != MI_AIRTRAIN && v->GetModelIndex() != MI_TRAIN)
- StoreCarUpdate(v, i);
+ if (v && v->m_rwObject && v->GetModelIndex() != MI_AIRTRAIN && v->GetModelIndex() != MI_TRAIN) {
+ if (v->IsBike())
+ StoreBikeUpdate(v, i);
+ else
+ StoreCarUpdate(v, i);
+ }
}
CPedPool* peds = CPools::GetPedPool();
for (int i = 0; i < peds->GetSize(); i++) {
@@ -352,23 +385,27 @@ void CReplay::RecordThisFrame(void)
tBulletTracePacket* bt = (tBulletTracePacket*)&Record.m_pBase[Record.m_nOffset];
bt->type = REPLAYPACKET_BULLET_TRACES;
bt->index = i;
- bt->frames = CBulletTraces::aTraces[i].m_framesInUse;
- bt->lifetime = CBulletTraces::aTraces[i].m_lifeTime;
- bt->inf = CBulletTraces::aTraces[i].m_vecCurrentPos;
- bt->sup = CBulletTraces::aTraces[i].m_vecTargetPos;
+ bt->inf = CBulletTraces::aTraces[i].m_vecStartPos;
+ bt->sup = CBulletTraces::aTraces[i].m_vecEndPos;
Record.m_nOffset += sizeof(*bt);
}
+ tMiscPacket* misc = (tMiscPacket*)&Record.m_pBase[Record.m_nOffset];
+ misc->type = REPLAYPACKET_MISC;
+ misc->cam_shake_start = TheCamera.m_uiCamShakeStart;
+ misc->cam_shake_strength = TheCamera.m_fCamShakeForce;
+ misc->cur_area = CGame::currArea;
+ misc->video_cam = CSpecialFX::bVideoCam;
+ misc->lift_cam = CSpecialFX::bLiftCam;
+ Record.m_nOffset += sizeof(*misc);
tEndOfFramePacket* eof = (tEndOfFramePacket*)&Record.m_pBase[Record.m_nOffset];
eof->type = REPLAYPACKET_ENDOFFRAME;
Record.m_nOffset += sizeof(*eof);
Record.m_pBase[Record.m_nOffset] = REPLAYPACKET_END;
-#ifndef FIX_REPLAY_BUGS
- if (Record.m_nOffset <= REPLAYBUFFERSIZE - 3000){
- /* Unsafe assumption which can cause buffer overflow
- * if size of next frame exceeds 3000 bytes.
- * Most notably it causes various timecyc errors. */
- return;
- }
+}
+
+void CReplay::GoToNextBlock(void)
+{
+ Record.m_pBase[Record.m_nOffset] = REPLAYPACKET_END;
BufferStatus[Record.m_bSlot] = REPLAYBUFFER_PLAYBACK;
Record.m_bSlot = (Record.m_bSlot + 1) % NUM_REPLAYBUFFERS;
BufferStatus[Record.m_bSlot] = REPLAYBUFFER_RECORD;
@@ -376,7 +413,28 @@ void CReplay::RecordThisFrame(void)
Record.m_nOffset = 0;
*Record.m_pBase = REPLAYPACKET_END;
MarkEverythingAsNew();
-#endif
+}
+
+void CReplay::RecordParticle(tParticleType type, const CVector& vecPos, const CVector& vecDir, float fSize, const RwRGBA& color)
+{
+ if (Record.m_nOffset > REPLAYBUFFERSIZE - 16 - sizeof(tParticlePacket))
+ GoToNextBlock();
+ tParticlePacket* pp = (tParticlePacket*)&Record.m_pBase[Record.m_nOffset];
+ pp->type = REPLAYPACKET_PARTICLE;
+ pp->particle_type = type;
+ pp->pos_x = 4.0f * vecPos.x;
+ pp->pos_y = 4.0f * vecPos.y;
+ pp->pos_z = 4.0f * vecPos.z;
+ pp->dir_x = 120.0f * Clamp(vecDir.x, -1.0f, 1.0f);
+ pp->dir_y = 120.0f * Clamp(vecDir.y, -1.0f, 1.0f);
+ pp->dir_z = 120.0f * Clamp(vecDir.z, -1.0f, 1.0f);
+ pp->size = fSize;
+ pp->r = color.red;
+ pp->g = color.green;
+ pp->b = color.blue;
+ pp->a = color.alpha;
+ Record.m_nOffset += sizeof(tParticlePacket);
+ Record.m_pBase[Record.m_nOffset] = REPLAYPACKET_END;
}
void CReplay::StorePedUpdate(CPed *ped, int id)
@@ -387,6 +445,7 @@ void CReplay::StorePedUpdate(CPed *ped, int id)
pp->heading = 128.0f / PI * ped->m_fRotationCur;
pp->matrix.CompressFromFullMatrix(ped->GetMatrix());
pp->assoc_group_id = ped->m_animGroup;
+ pp->is_visible = ped->bIsVisible;
/* Would be more sane to use GetJustIndex(ped->m_pMyVehicle) in following assignment */
if (ped->InVehicle())
pp->vehicle_index = (CPools::GetVehiclePool()->GetIndex(ped->m_pMyVehicle) >> 8) + 1;
@@ -406,21 +465,25 @@ void CReplay::StorePedAnimation(CPed *ped, CStoredAnimationState *state)
state->animId = main->animId;
state->time = 255.0f / 4.0f * Clamp(main->currentTime, 0.0f, 4.0f);
state->speed = 255.0f / 3.0f * Clamp(main->speed, 0.0f, 3.0f);
+ state->groupId = main->groupId;
}else{
state->animId = 3;
state->time = 0;
state->speed = 85;
+ state->groupId = 0;
}
if (second) {
state->secAnimId = second->animId;
state->secTime = 255.0f / 4.0f * Clamp(second->currentTime, 0.0f, 4.0f);
state->secSpeed = 255.0f / 3.0f * Clamp(second->speed, 0.0f, 3.0f);
state->blendAmount = 255.0f / 2.0f * Clamp(blend_amount, 0.0f, 2.0f);
+ state->secGroupId = second->groupId;
}else{
state->secAnimId = 0;
state->secTime = 0;
state->secSpeed = 0;
state->blendAmount = 0;
+ state->secGroupId = 0;
}
CAnimBlendAssociation* partial = RpAnimBlendClumpGetMainPartialAssociation((RpClump*)ped->m_rwObject);
if (partial) {
@@ -428,11 +491,13 @@ void CReplay::StorePedAnimation(CPed *ped, CStoredAnimationState *state)
state->partAnimTime = 255.0f / 4.0f * Clamp(partial->currentTime, 0.0f, 4.0f);
state->partAnimSpeed = 255.0f / 3.0f * Clamp(partial->speed, 0.0f, 3.0f);
state->partBlendAmount = 255.0f / 2.0f * Clamp(partial->blendAmount, 0.0f, 2.0f);
+ state->partGroupId = partial->groupId;
}else{
state->partAnimId = 0;
state->partAnimTime = 0;
state->partAnimSpeed = 0;
state->partBlendAmount = 0;
+ state->partGroupId = 0;
}
}
@@ -445,10 +510,9 @@ void CReplay::StoreDetailedPedAnimation(CPed *ped, CStoredDetailedAnimationState
state->aCurTime[i] = 255.0f / 4.0f * Clamp(assoc->currentTime, 0.0f, 4.0f);
state->aSpeed[i] = 255.0f / 3.0f * Clamp(assoc->speed, 0.0f, 3.0f);
state->aBlendAmount[i] = 255.0f / 2.0f * Clamp(assoc->blendAmount, 0.0f, 2.0f);
-#ifdef FIX_REPLAY_BUGS
state->aBlendDelta[i] = 127.0f / 32.0f * Clamp(assoc->blendDelta, -16.0f, 16.0f);
-#endif
state->aFlags[i] = assoc->flags;
+ state->aGroupId[i] = assoc->groupId;
if (assoc->callbackType == CAnimBlendAssociation::CB_FINISH || assoc->callbackType == CAnimBlendAssociation::CB_DELETE) {
state->aFunctionCallbackID[i] = FindCBFunctionID(assoc->callback);
if (assoc->callbackType == CAnimBlendAssociation::CB_FINISH)
@@ -462,6 +526,7 @@ void CReplay::StoreDetailedPedAnimation(CPed *ped, CStoredDetailedAnimationState
state->aSpeed[i] = 85;
state->aFunctionCallbackID[i] = 0;
state->aFlags[i] = 0;
+ state->aGroupId[i] = 0;
}
}
for (int i = 0; i < NUM_PARTIAL_ANIMS_IN_REPLAY; i++) {
@@ -471,10 +536,9 @@ void CReplay::StoreDetailedPedAnimation(CPed *ped, CStoredDetailedAnimationState
state->aCurTime2[i] = 255.0f / 4.0f * Clamp(assoc->currentTime, 0.0f, 4.0f);
state->aSpeed2[i] = 255.0f / 3.0f * Clamp(assoc->speed, 0.0f, 3.0f);
state->aBlendAmount2[i] = 255.0f / 2.0f * Clamp(assoc->blendAmount, 0.0f, 2.0f);
-#ifdef FIX_REPLAY_BUGS
state->aBlendDelta2[i] = 127.0f / 16.0f * Clamp(assoc->blendDelta, -16.0f, 16.0f);
-#endif
state->aFlags2[i] = assoc->flags;
+ state->aGroupId2[i] = assoc->groupId;
if (assoc->callbackType == CAnimBlendAssociation::CB_FINISH || assoc->callbackType == CAnimBlendAssociation::CB_DELETE) {
state->aFunctionCallbackID2[i] = FindCBFunctionID(assoc->callback);
if (assoc->callbackType == CAnimBlendAssociation::CB_FINISH)
@@ -489,6 +553,7 @@ void CReplay::StoreDetailedPedAnimation(CPed *ped, CStoredDetailedAnimationState
state->aSpeed2[i] = 85;
state->aFunctionCallbackID2[i] = 0;
state->aFlags2[i] = 0;
+ state->aGroupId2[i] = 0;
}
}
}
@@ -510,7 +575,7 @@ void CReplay::ProcessPedUpdate(CPed *ped, float interpolation, CAddressInReplayB
ped->GetMatrix() += CMatrix(interpolation) * ped_matrix;
if (pp->vehicle_index) {
ped->m_pMyVehicle = CPools::GetVehiclePool()->GetSlot(pp->vehicle_index - 1);
- ped->bInVehicle = pp->vehicle_index;
+ ped->bInVehicle = true;
}
else {
ped->m_pMyVehicle = nil;
@@ -521,21 +586,39 @@ void CReplay::ProcessPedUpdate(CPed *ped, float interpolation, CAddressInReplayB
if (ped == FindPlayerPed())
((CPlayerPed*)ped)->ReApplyMoveAnims();
}
+ ped->bIsVisible = pp->is_visible;
+ if (FramesActiveLookAroundCam && ped->m_nPedType == PEDTYPE_PLAYER1)
+ ped->bIsVisible = true;
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);
}
+bool HasAnimGroupLoaded(uint8 group)
+{
+ CAnimBlendAssocGroup* pGroup = &CAnimManager::GetAnimAssocGroups()[group];
+ return pGroup->animBlock && pGroup->animBlock->isLoaded;
+}
+
void CReplay::RetrievePedAnimation(CPed *ped, CStoredAnimationState *state)
{
- CAnimBlendAssociation* anim1 = CAnimManager::BlendAnimation(
- (RpClump*)ped->m_rwObject,
- (state->animId > 3) ? ASSOCGRP_STD : ped->m_animGroup,
- (AnimationId)state->animId, 100.0f);
+ CAnimBlendAssociation* anim1;
+ if (state->animId <= ANIM_STD_IDLE)
+ anim1 = CAnimManager::BlendAnimation(
+ (RpClump*)ped->m_rwObject, ped->m_animGroup, (AnimationId)state->animId, 100.0f);
+ else if (HasAnimGroupLoaded(state->groupId))
+ anim1 = CAnimManager::BlendAnimation((RpClump*)ped->m_rwObject, (AssocGroupId)state->groupId, (AnimationId)state->animId, 100.0f);
+ else
+ anim1 = CAnimManager::BlendAnimation((RpClump*)ped->m_rwObject, ASSOCGRP_STD, ANIM_STD_WALK, 100.0f);
+
anim1->SetCurrentTime(state->time * 4.0f / 255.0f);
anim1->speed = state->speed * 3.0f / 255.0f;
anim1->SetBlend(1.0f, 1.0f);
@@ -546,7 +629,7 @@ void CReplay::RetrievePedAnimation(CPed *ped, CStoredAnimationState *state)
float blend = state->blendAmount * 2.0f / 255.0f;
CAnimBlendAssociation* anim2 = CAnimManager::BlendAnimation(
(RpClump*)ped->m_rwObject,
- (state->secAnimId > 3) ? ASSOCGRP_STD : ped->m_animGroup,
+ (state->secAnimId > ANIM_STD_IDLE) ? (AssocGroupId)state->secGroupId : ped->m_animGroup,
(AnimationId)state->secAnimId, 100.0f);
anim2->SetCurrentTime(time);
anim2->speed = speed;
@@ -558,9 +641,9 @@ void CReplay::RetrievePedAnimation(CPed *ped, CStoredAnimationState *state)
float time = state->partAnimTime * 4.0f / 255.0f;
float speed = state->partAnimSpeed * 3.0f / 255.0f;
float blend = state->partBlendAmount * 2.0f / 255.0f;
- if (blend > 0.0f && state->partAnimId != ANIM_STD_IDLE){
+ if (blend > 0.0f && state->partAnimId != ANIM_STD_IDLE && HasAnimGroupLoaded(state->partGroupId)){
CAnimBlendAssociation* anim3 = CAnimManager::BlendAnimation(
- (RpClump*)ped->m_rwObject, ASSOCGRP_STD, (AnimationId)state->partAnimId, 1000.0f);
+ (RpClump*)ped->m_rwObject, (AssocGroupId)state->partGroupId, (AnimationId)state->partAnimId, 1000.0f);
anim3->SetCurrentTime(time);
anim3->speed = speed;
anim3->SetBlend(blend, 0.0f);
@@ -570,33 +653,20 @@ void CReplay::RetrievePedAnimation(CPed *ped, CStoredAnimationState *state)
void CReplay::RetrieveDetailedPedAnimation(CPed *ped, CStoredDetailedAnimationState *state)
{
-#ifdef FIX_REPLAY_BUGS
CAnimBlendAssociation* assoc;
for (int i = 0; ((assoc = RpAnimBlendClumpGetMainAssociation_N(ped->GetClump(), i))); i++)
assoc->SetBlend(0.0f, -1.0f);
for (int i = 0; ((assoc = RpAnimBlendClumpGetMainPartialAssociation_N(ped->GetClump(), i))); i++)
assoc->SetBlend(0.0f, -1.0f);
-#endif
for (int i = 0; i < NUM_MAIN_ANIMS_IN_REPLAY; i++) {
if (state->aAnimId[i] == ANIM_STD_NUM)
continue;
-#ifdef FIX_REPLAY_BUGS
CAnimBlendAssociation* anim = CAnimManager::AddAnimation(ped->GetClump(),
- state->aAnimId[i] > 3 ? ASSOCGRP_STD : ped->m_animGroup,
+ state->aAnimId[i] > ANIM_STD_IDLE ? (AssocGroupId)state->aGroupId[i] : ped->m_animGroup,
(AnimationId)state->aAnimId[i]);
-#else
- CAnimBlendAssociation* anim = CAnimManager::BlendAnimation(
- (RpClump*)ped->m_rwObject,
- state->aAnimId[i] > 3 ? ASSOCGRP_STD : ped->m_animGroup,
- (AnimationId)state->aAnimId[i], 100.0f);
-#endif
anim->SetCurrentTime(state->aCurTime[i] * 4.0f / 255.0f);
anim->speed = state->aSpeed[i] * 3.0f / 255.0f;
-#ifdef FIX_REPLAY_BUGS
anim->SetBlend(state->aBlendAmount[i] * 2.0f / 255.0f, state->aBlendDelta[i] * 16.0f / 127.0f);
-#else
- anim->SetBlend(state->aBlendAmount[i], 1.0f);
-#endif
anim->flags = state->aFlags[i];
uint8 callback = state->aFunctionCallbackID[i];
if (!callback)
@@ -609,23 +679,12 @@ void CReplay::RetrieveDetailedPedAnimation(CPed *ped, CStoredDetailedAnimationSt
for (int i = 0; i < NUM_PARTIAL_ANIMS_IN_REPLAY; i++) {
if (state->aAnimId2[i] == ANIM_STD_NUM)
continue;
-#ifdef FIX_REPLAY_BUGS
CAnimBlendAssociation* anim = CAnimManager::AddAnimation(ped->GetClump(),
- state->aAnimId2[i] > 3 ? ASSOCGRP_STD : ped->m_animGroup,
+ state->aAnimId2[i] > ANIM_STD_IDLE ? (AssocGroupId)state->aGroupId2[i] : ped->m_animGroup,
(AnimationId)state->aAnimId2[i]);
-#else
- CAnimBlendAssociation* anim = CAnimManager::BlendAnimation(
- (RpClump*)ped->m_rwObject,
- state->aAnimId2[i] > 3 ? ASSOCGRP_STD : ped->m_animGroup,
- (AnimationId)state->aAnimId2[i], 100.0f);
-#endif
anim->SetCurrentTime(state->aCurTime2[i] * 4.0f / 255.0f);
anim->speed = state->aSpeed2[i] * 3.0f / 255.0f;
-#ifdef FIX_REPLAY_BUGS
anim->SetBlend(state->aBlendAmount2[i] * 2.0f / 255.0f, state->aBlendDelta2[i] * 16.0f / 127.0f);
-#else
- anim->SetBlend(state->aBlendAmount2[i], 1.0f);
-#endif
anim->flags = state->aFlags2[i];
uint8 callback = state->aFunctionCallbackID2[i];
if (!callback)
@@ -664,7 +723,6 @@ void CReplay::PlaybackThisFrame(void)
// next two functions are only found in mobile version
// most likely they were optimized out for being unused
-
void CReplay::TriggerPlaybackLastCoupleOfSeconds(uint32 start, uint8 cam_mode, float cam_x, float cam_y, float cam_z, uint32 slomo)
{
if (Mode != MODE_RECORD)
@@ -718,9 +776,47 @@ void CReplay::StoreCarUpdate(CVehicle *vehicle, int id)
vp->door_status |= BIT(i);
}
}
+ if (vehicle->GetModelIndex() == MI_SKIMMER)
+ vp->skimmer_speed = 50.0f * ((CBoat*)vehicle)->m_fMovingSpeed;
+ vp->render_scorched = vehicle->bRenderScorched;
+ vp->vehicle_type = vehicle->m_vehType;
Record.m_nOffset += sizeof(tVehicleUpdatePacket);
}
+void CReplay::StoreBikeUpdate(CVehicle* vehicle, int id)
+{
+ CBike* bike = (CBike*)vehicle;
+ tBikeUpdatePacket* vp = (tBikeUpdatePacket*)&Record.m_pBase[Record.m_nOffset];
+ vp->type = REPLAYPACKET_BIKE;
+ vp->index = id;
+ vp->matrix.CompressFromFullMatrix(vehicle->GetMatrix());
+ vp->health = vehicle->m_fHealth / 4.0f; /* Not anticipated that health can be > 1000. */
+ vp->acceleration = vehicle->m_fGasPedal * 100.0f;
+#ifdef FIX_BUGS // originally it's undefined behaviour - different fields are copied on PC and mobile
+ for (int i = 0; i < 2; i++)
+ vp->wheel_rotation[i] = 128.0f / PI * bike->m_aWheelRotation[i];
+ for (int i = 0; i < 2; i++)
+ vp->wheel_rotation[i + 2] = 128.0f / PI * bike->m_aWheelSpeed[i];
+ for (int i = 0; i < 4; i++)
+ vp->wheel_susp_dist[i] = 50.0f * bike->m_aSuspensionSpringRatio[i];
+#else
+ for (int i = 0; i < 4; i++) {
+ vp->wheel_susp_dist[i] = 50.0f * bike->m_aSuspensionSpringRatio[i];
+ vp->wheel_rotation[i] = 128.0f / PI * bike->m_aWheelRotation[i];
+ }
+#endif
+ vp->velocityX = 8000.0f * Max(-4.0f, Min(4.0f, vehicle->GetMoveSpeed().x)); /* 8000!? */
+ vp->velocityY = 8000.0f * Max(-4.0f, Min(4.0f, vehicle->GetMoveSpeed().y));
+ vp->velocityZ = 8000.0f * Max(-4.0f, Min(4.0f, vehicle->GetMoveSpeed().z));
+ vp->mi = vehicle->GetModelIndex();
+ vp->primary_color = vehicle->m_currentColour1;
+ vp->secondary_color = vehicle->m_currentColour2;
+ vp->wheel_state = 50.0f * vehicle->m_fSteerAngle;
+ vp->lean_angle = 50.0f * bike->m_fLeanLRAngle;
+ vp->wheel_angle = 50.0f * bike->m_fWheelAngle;
+ Record.m_nOffset += sizeof(tBikeUpdatePacket);
+}
+
void CReplay::ProcessCarUpdate(CVehicle *vehicle, float interpolation, CAddressInReplayBuffer *buffer)
{
tVehicleUpdatePacket* vp = (tVehicleUpdatePacket*)&buffer->m_pBase[buffer->m_nOffset];
@@ -789,20 +885,53 @@ void CReplay::ProcessCarUpdate(CVehicle *vehicle, float interpolation, CAddressI
CWorld::Add(vehicle);
if (vehicle->IsBoat())
((CBoat*)vehicle)->m_bIsAnchored = false;
+ vehicle->bRenderScorched = vp->render_scorched;
+ if (vehicle->GetModelIndex() == MI_SKIMMER)
+ ((CBoat*)vehicle)->m_fMovingSpeed = vp->skimmer_speed / 50.0f;
}
-bool CReplay::PlayBackThisFrameInterpolation(CAddressInReplayBuffer *buffer, float interpolation, uint32 *pTimer){
- /* Mistake. Not even sure what this is even doing here...
- * PlayerWanted is a backup to restore at the end of replay.
- * Setting current wanted pointer to it makes it useless.
- * Causes picking up bribes in replays reducing wanted level bug.
- * Obviously fact of picking them up is a bug on its own,
- * but it doesn't cancel this one.
- */
-#ifndef FIX_REPLAY_BUGS
- FindPlayerPed()->m_pWanted = &PlayerWanted;
+void CReplay::ProcessBikeUpdate(CVehicle* vehicle, float interpolation, CAddressInReplayBuffer* buffer)
+{
+ CBike* bike = (CBike*)vehicle;
+ tBikeUpdatePacket* vp = (tBikeUpdatePacket*)&buffer->m_pBase[buffer->m_nOffset];
+ if (!vehicle) {
+ printf("Replay:Car wasn't there");
+ return;
+ }
+ CMatrix vehicle_matrix;
+ vp->matrix.DecompressIntoFullMatrix(vehicle_matrix);
+ vehicle->GetMatrix() = vehicle->GetMatrix() * CMatrix(1.0f - interpolation);
+ vehicle->GetMatrix().GetPosition() *= (1.0f - interpolation);
+ vehicle->GetMatrix() += CMatrix(interpolation) * vehicle_matrix;
+ vehicle->m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f);
+ vehicle->m_fHealth = 4 * vp->health;
+ vehicle->m_fGasPedal = vp->acceleration / 100.0f;
+ vehicle->m_vecMoveSpeed = CVector(vp->velocityX / 8000.0f, vp->velocityY / 8000.0f, vp->velocityZ / 8000.0f);
+ vehicle->m_fSteerAngle = vp->wheel_state / 50.0f;
+ vehicle->bEngineOn = true;
+#ifdef FIX_BUGS
+ for (int i = 0; i < 2; i++)
+ bike->m_aWheelRotation[i] = vp->wheel_rotation[i] / (128.0f / PI);
+ for (int i = 0; i < 2; i++)
+ bike->m_aWheelSpeed[i] = vp->wheel_rotation[i + 2] / (128.0f / PI);
+ for (int i = 0; i < 4; i++)
+ bike->m_aSuspensionSpringRatio[i] = vp->wheel_susp_dist[i] / 50.0f;
+#else
+ for (int i = 0; i < 4; i++) {
+ bike->m_aSuspensionSpringRatio[i] = vp->wheel_susp_dist[i] / 50.0f;
+ bike->m_aWheelRotation[i] = vp->wheel_rotation[i] / (128.0f / PI);
+ }
#endif
+ bike->m_fLeanLRAngle = vp->lean_angle / 50.0f;
+ bike->m_fWheelAngle = vp->wheel_angle / 50.0f;
+ bike->bLeanMatrixClean = false;
+ bike->CalculateLeanMatrix();
+ CWorld::Remove(vehicle);
+ CWorld::Add(vehicle);
+}
+bool CReplay::PlayBackThisFrameInterpolation(CAddressInReplayBuffer *buffer, float interpolation, uint32 *pTimer)
+{
CBulletTraces::Init();
float split = 1.0f - interpolation;
int ped_min_index = 0; /* Optimization due to peds and vehicles placed in buffer sequentially. */
@@ -848,20 +977,25 @@ bool CReplay::PlayBackThisFrameInterpolation(CAddressInReplayBuffer *buffer, flo
CStreaming::RequestModel(mi, 0);
}
else {
- if (mi == MI_DEADDODO || mi == MI_AIRTRAIN) {
- new_v = new(vp->index << 8) CPlane(mi, 2);
- }
- else if (mi == MI_TRAIN) {
+ switch (vp->vehicle_type) {
+ case VEHICLE_TYPE_CAR:
+ new_v = new(vp->index << 8) CAutomobile(mi, 2);
+ break;
+ case VEHICLE_TYPE_BOAT:
+ new_v = new(vp->index << 8) CBoat(mi, 2);
+ break;
+ case VEHICLE_TYPE_TRAIN:
new_v = new(vp->index << 8) CTrain(mi, 2);
- }
- else if (mi == MI_CHOPPER || mi == MI_ESCAPE) {
+ break;
+ case VEHICLE_TYPE_HELI:
new_v = new(vp->index << 8) CHeli(mi, 2);
- }
- else if (CModelInfo::IsBoatModel(mi)){
- new_v = new(vp->index << 8) CBoat(mi, 2);
- }
- else{
- new_v = new(vp->index << 8) CAutomobile(mi, 2);
+ break;
+ case VEHICLE_TYPE_PLANE:
+ new_v = new(vp->index << 8) CPlane(mi, 2);
+ break;
+ case VEHICLE_TYPE_BIKE: // not possible
+ new_v = new(vp->index << 8) CBike(mi, 2);
+ break;
}
new_v->SetStatus(STATUS_PLAYER_PLAYBACKFROMBUFFER);
vp->matrix.DecompressIntoFullMatrix(new_v->GetMatrix());
@@ -874,15 +1008,51 @@ bool CReplay::PlayBackThisFrameInterpolation(CAddressInReplayBuffer *buffer, flo
buffer->m_nOffset += sizeof(tVehicleUpdatePacket);
break;
}
+ case REPLAYPACKET_BIKE:
+ {
+ tBikeUpdatePacket* vp = (tBikeUpdatePacket*)&ptr[offset];
+ for (int i = vehicle_min_index; i < vp->index; i++) {
+ CVehicle* v = CPools::GetVehiclePool()->GetSlot(i);
+ if (!v)
+ continue;
+ /* Removing vehicles not present in this frame. */
+ CWorld::Remove(v);
+ delete v;
+ }
+ vehicle_min_index = vp->index + 1;
+ CVehicle* v = CPools::GetVehiclePool()->GetSlot(vp->index);
+ CVehicle* new_v;
+ if (!v) {
+ int mi = vp->mi;
+ if (CStreaming::ms_aInfoForModel[mi].m_loadState != 1) {
+ CStreaming::RequestModel(mi, 0);
+ }
+ else {
+ new_v = new(vp->index << 8) CBike(mi, 2);
+ new_v->SetStatus(STATUS_PLAYER_PLAYBACKFROMBUFFER);
+ vp->matrix.DecompressIntoFullMatrix(new_v->GetMatrix());
+ new_v->m_currentColour1 = vp->primary_color;
+ new_v->m_currentColour2 = vp->secondary_color;
+ CWorld::Add(new_v);
+ }
+ }
+ ProcessBikeUpdate(CPools::GetVehiclePool()->GetSlot(vp->index), interpolation, buffer);
+ buffer->m_nOffset += sizeof(tBikeUpdatePacket);
+ break;
+ }
case REPLAYPACKET_PED_HEADER:
{
tPedHeaderPacket* ph = (tPedHeaderPacket*)&ptr[offset];
if (!CPools::GetPedPool()->GetSlot(ph->index)) {
- if (CStreaming::ms_aInfoForModel[ph->mi].m_loadState != 1) {
+ if (!CStreaming::HasModelLoaded(ph->mi) || (ph->mi >= MI_SPECIAL01 && ph->mi < MI_LAST_PED)) {
CStreaming::RequestModel(ph->mi, 0);
}
else {
- CPed* new_p = new(ph->index << 8) CCivilianPed((ePedType)ph->pedtype, ph->mi);
+ CPed* new_p;
+ if (ph->pedtype != PEDTYPE_PLAYER1)
+ new_p = new(ph->index << 8) CCivilianPed((ePedType)ph->pedtype, ph->mi);
+ else
+ new_p = new(ph->index << 8) CPlayerPed();
new_p->SetStatus(STATUS_PLAYER_PLAYBACKFROMBUFFER);
new_p->GetMatrix().SetUnity();
CWorld::Add(new_p);
@@ -960,11 +1130,35 @@ bool CReplay::PlayBackThisFrameInterpolation(CAddressInReplayBuffer *buffer, flo
{
tBulletTracePacket* pb = (tBulletTracePacket*)&ptr[offset];
CBulletTraces::aTraces[pb->index].m_bInUse = true;
- CBulletTraces::aTraces[pb->index].m_framesInUse = pb->frames;
- CBulletTraces::aTraces[pb->index].m_lifeTime = pb->lifetime;
- CBulletTraces::aTraces[pb->index].m_vecCurrentPos = pb->inf;
- CBulletTraces::aTraces[pb->index].m_vecTargetPos = pb->sup;
+ CBulletTraces::aTraces[pb->index].m_vecStartPos = pb->inf;
+ CBulletTraces::aTraces[pb->index].m_vecEndPos = pb->sup;
buffer->m_nOffset += sizeof(tBulletTracePacket);
+ break;
+ }
+ case REPLAYPACKET_PARTICLE:
+ {
+ tParticlePacket* pp = (tParticlePacket*)&ptr[offset];
+ CVector pos(pp->pos_x / 4.0f, pp->pos_y / 4.0f, pp->pos_z / 4.0f);
+ CVector dir(pp->dir_x / 120.0f, pp->dir_y / 120.0f, pp->dir_z / 120.0f);
+ RwRGBA color;
+ color.red = pp->r;
+ color.green = pp->g;
+ color.blue = pp->b;
+ color.alpha = pp->a;
+ CParticle::AddParticle((tParticleType)pp->particle_type, pos, dir, nil, pp->size, color);
+ buffer->m_nOffset += sizeof(tParticlePacket);
+ break;
+ }
+ case REPLAYPACKET_MISC:
+ {
+ tMiscPacket* pm = (tMiscPacket*)&ptr[offset];
+ TheCamera.m_uiCamShakeStart = pm->cam_shake_start;
+ TheCamera.m_fCamShakeForce = pm->cam_shake_strength;
+ CSpecialFX::bVideoCam = pm->video_cam;
+ CSpecialFX::bLiftCam = pm->lift_cam;
+ CGame::currArea = pm->cur_area;
+ buffer->m_nOffset += sizeof(tMiscPacket);
+ break;
}
default:
break;
@@ -1072,6 +1266,8 @@ void CReplay::ProcessReplayCamera(void)
RwFrameUpdateObjects(RwCameraGetFrame(TheCamera.m_pRwCamera));
}
+extern CWeaponEffects gCrossHair;
+
void CReplay::TriggerPlayback(uint8 cam_mode, float cam_x, float cam_y, float cam_z, bool load_scene)
{
if (Mode != MODE_RECORD)
@@ -1088,6 +1284,8 @@ void CReplay::TriggerPlayback(uint8 cam_mode, float cam_x, float cam_y, float ca
DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND);
DMAudio.SetEffectsFadeVol(0);
DMAudio.SetMusicFadeVol(0);
+ CEscalators::Shutdown();
+ CWaterCreatures::RemoveAll();
int current;
for (current = 0; current < NUM_REPLAYBUFFERS; current++)
if (BufferStatus[current] == REPLAYBUFFER_RECORD)
@@ -1120,6 +1318,13 @@ void CReplay::TriggerPlayback(uint8 cam_mode, float cam_x, float cam_y, float ca
}
if (cam_mode == REPLAYCAMMODE_ASSTORED)
TheCamera.CarZoomIndicator = CAM_ZOOM_CINEMATIC;
+ gCrossHair.m_bActive = false;
+ CExplosion::ClearAllExplosions();
+ CPlaneBanners::Init();
+#ifndef FIX_BUGS // this doesn't do anything useful and accesses destroyed player ped
+ TheCamera.Restore();
+#endif
+ CDraw::SetFOV(70.0f);
}
void CReplay::StoreStuffInMem(void)
@@ -1128,6 +1333,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);
@@ -1159,9 +1372,28 @@ void CReplay::StoreStuffInMem(void)
OldWeatherType = CWeather::OldWeatherType;
NewWeatherType = CWeather::NewWeatherType;
WeatherInterpolationValue = CWeather::InterpolationValue;
+ CurrArea = CGame::currArea;
TimeStepNonClipped = CTimer::GetTimeStepNonClipped();
TimeStep = CTimer::GetTimeStep();
TimeScale = CTimer::GetTimeScale();
+ ms_nNumCivMale_Stored = CPopulation::ms_nNumCivMale;
+ ms_nNumCivFemale_Stored = CPopulation::ms_nNumCivFemale;
+ ms_nNumCop_Stored = CPopulation::ms_nNumCop;
+ ms_nNumEmergency_Stored = CPopulation::ms_nNumEmergency;
+ ms_nNumGang1_Stored = CPopulation::ms_nNumGang1;
+ ms_nNumGang2_Stored = CPopulation::ms_nNumGang2;
+ ms_nNumGang3_Stored = CPopulation::ms_nNumGang3;
+ ms_nNumGang4_Stored = CPopulation::ms_nNumGang4;
+ ms_nNumGang5_Stored = CPopulation::ms_nNumGang5;
+ ms_nNumGang6_Stored = CPopulation::ms_nNumGang6;
+ ms_nNumGang7_Stored = CPopulation::ms_nNumGang7;
+ ms_nNumGang8_Stored = CPopulation::ms_nNumGang8;
+ ms_nNumGang9_Stored = CPopulation::ms_nNumGang9;
+ ms_nNumDummy_Stored = CPopulation::ms_nNumDummy;
+ ms_nTotalCivPeds_Stored = CPopulation::ms_nTotalCivPeds;
+ ms_nTotalGangPeds_Stored = CPopulation::ms_nTotalGangPeds;
+ ms_nTotalPeds_Stored = CPopulation::ms_nTotalPeds;
+ ms_nTotalMissionPeds_Stored = CPopulation::ms_nTotalMissionPeds;
int size = CPools::GetPedPool()->GetSize();
pPedAnims = new CStoredDetailedAnimationState[size];
for (int i = 0; i < size; i++) {
@@ -1169,7 +1401,6 @@ void CReplay::StoreStuffInMem(void)
if (ped)
StoreDetailedPedAnimation(ped, &pPedAnims[i]);
}
-#ifdef FIX_BUGS
pGarages = new uint8[sizeof(CGarages::aGarages)];
memcpy(pGarages, CGarages::aGarages, sizeof(CGarages::aGarages));
FireArray = new CFire[NUM_FIRES];
@@ -1179,7 +1410,7 @@ void CReplay::StoreStuffInMem(void)
memcpy(paProjectileInfo, gaProjectileInfo, sizeof(gaProjectileInfo));
paProjectiles = new uint8[sizeof(CProjectileInfo::ms_apProjectile)];
memcpy(paProjectiles, CProjectileInfo::ms_apProjectile, sizeof(CProjectileInfo::ms_apProjectile));
-#endif
+ CScriptPaths::Save_ForReplay();
}
void CReplay::RestoreStuffFromMem(void)
@@ -1234,8 +1465,24 @@ 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);
- if (ped->m_wepModelID >= 0)
+ 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->m_pWeaponModel = nil;
+ if (ped->IsPlayer())
+ ((CPlayerPed*)ped)->m_pMinigunTopAtomic = nil;
ped->AddWeaponModel(ped->m_wepModelID);
+ }
+ if (ped->m_nPedType == PEDTYPE_COP)
+ ((CCopPed*)ped)->m_pStinger = new CStinger;
}
i = CPools::GetVehiclePool()->GetSize();
while (--i >= 0) {
@@ -1248,14 +1495,26 @@ void CReplay::RestoreStuffFromMem(void)
vehicle->m_rwObject = nil;
vehicle->m_modelIndex = -1;
vehicle->SetModelIndex(mi);
- if (mi == MI_DODO){
- CAutomobile* dodo = (CAutomobile*)vehicle;
- RpAtomicSetFlags((RpAtomic*)GetFirstObject(dodo->m_aCarNodes[CAR_WHEEL_LF]), 0);
- CMatrix tmp1;
- tmp1.Attach(RwFrameGetMatrix(dodo->m_aCarNodes[CAR_WHEEL_RF]), false);
- CMatrix tmp2(RwFrameGetMatrix(dodo->m_aCarNodes[CAR_WHEEL_LF]), false);
- tmp1.GetPosition() += CVector(tmp2.GetPosition().x + 0.1f, 0.0f, tmp2.GetPosition().z);
- tmp1.UpdateRW();
+ if (vehicle->IsCar()) {
+ CAutomobile* car = (CAutomobile*)vehicle;
+ if (mi == MI_DODO) {
+ RpAtomicSetFlags((RpAtomic*)GetFirstObject(car->m_aCarNodes[CAR_WHEEL_LF]), 0);
+ CMatrix tmp1;
+ tmp1.Attach(RwFrameGetMatrix(car->m_aCarNodes[CAR_WHEEL_RF]), false);
+ CMatrix tmp2(RwFrameGetMatrix(car->m_aCarNodes[CAR_WHEEL_LF]), false);
+ tmp1.GetPosition() += CVector(tmp2.GetPosition().x + 0.1f, 0.0f, tmp2.GetPosition().z);
+ tmp1.UpdateRW();
+ }
+ else if (mi == MI_HUNTER) {
+ RpAtomicSetFlags((RpAtomic*)GetFirstObject(car->m_aCarNodes[CAR_WHEEL_LB]), 0);
+ RpAtomicSetFlags((RpAtomic*)GetFirstObject(car->m_aCarNodes[CAR_WHEEL_RB]), 0);
+ }
+ else if (vehicle->IsRealHeli()) {
+ RpAtomicSetFlags((RpAtomic*)GetFirstObject(car->m_aCarNodes[CAR_WHEEL_LF]), 0);
+ RpAtomicSetFlags((RpAtomic*)GetFirstObject(car->m_aCarNodes[CAR_WHEEL_RF]), 0);
+ RpAtomicSetFlags((RpAtomic*)GetFirstObject(car->m_aCarNodes[CAR_WHEEL_LB]), 0);
+ RpAtomicSetFlags((RpAtomic*)GetFirstObject(car->m_aCarNodes[CAR_WHEEL_RB]), 0);
+ }
}
if (vehicle->IsCar()){
CAutomobile* car = (CAutomobile*)vehicle;
@@ -1302,14 +1561,10 @@ void CReplay::RestoreStuffFromMem(void)
if (!object)
continue;
int mi = object->GetModelIndex();
- CStreaming::RequestModel(mi, 0);
- CStreaming::LoadAllRequestedModels(false);
object->m_rwObject = nil;
object->m_modelIndex = -1;
- object->SetModelIndex(mi);
+ object->SetModelIndexNoCreate(mi);
object->GetMatrix().m_attachment = nil;
- if (RwObjectGetType(object->m_rwObject) == rpATOMIC)
- object->GetMatrix().AttachRW(RwFrameGetMatrix(RpAtomicGetFrame((RpAtomic*)object->m_rwObject)), false);
}
i = CPools::GetDummyPool()->GetSize();
while (--i >= 0) {
@@ -1317,15 +1572,12 @@ void CReplay::RestoreStuffFromMem(void)
if (!dummy)
continue;
int mi = dummy->GetModelIndex();
- CStreaming::RequestModel(mi, 0);
- CStreaming::LoadAllRequestedModels(false);
dummy->m_rwObject = nil;
dummy->m_modelIndex = -1;
- dummy->SetModelIndex(mi);
+ dummy->SetModelIndexNoCreate(mi);
dummy->GetMatrix().m_attachment = nil;
- if (RwObjectGetType(dummy->m_rwObject) == rpATOMIC)
- dummy->GetMatrix().AttachRW(RwFrameGetMatrix(RpAtomicGetFrame((RpAtomic*)dummy->m_rwObject)), false);
}
+ ++ClockMinutes;
CTimer::SetTimeInMilliseconds(Time1);
CTimer::SetTimeInMillisecondsNonClipped(Time2);
CTimer::SetPreviousTimeInMilliseconds(Time3);
@@ -1338,6 +1590,25 @@ void CReplay::RestoreStuffFromMem(void)
CWeather::OldWeatherType = OldWeatherType;
CWeather::NewWeatherType = NewWeatherType;
CWeather::InterpolationValue = WeatherInterpolationValue;
+ CGame::currArea = CurrArea;
+ CPopulation::ms_nNumCivMale = ms_nNumCivMale_Stored;
+ CPopulation::ms_nNumCivFemale = ms_nNumCivFemale_Stored;
+ CPopulation::ms_nNumCop = ms_nNumCop_Stored;
+ CPopulation::ms_nNumEmergency = ms_nNumEmergency_Stored;
+ CPopulation::ms_nNumGang1 = ms_nNumGang1_Stored;
+ CPopulation::ms_nNumGang2 = ms_nNumGang2_Stored;
+ CPopulation::ms_nNumGang3 = ms_nNumGang3_Stored;
+ CPopulation::ms_nNumGang4 = ms_nNumGang4_Stored;
+ CPopulation::ms_nNumGang5 = ms_nNumGang5_Stored;
+ CPopulation::ms_nNumGang6 = ms_nNumGang6_Stored;
+ CPopulation::ms_nNumGang7 = ms_nNumGang7_Stored;
+ CPopulation::ms_nNumGang8 = ms_nNumGang8_Stored;
+ CPopulation::ms_nNumGang9 = ms_nNumGang9_Stored;
+ CPopulation::ms_nNumDummy = ms_nNumDummy_Stored;
+ CPopulation::ms_nTotalCivPeds = ms_nTotalCivPeds_Stored;
+ CPopulation::ms_nTotalGangPeds = ms_nTotalGangPeds_Stored;
+ CPopulation::ms_nTotalPeds = ms_nTotalPeds_Stored;
+ CPopulation::ms_nTotalMissionPeds = ms_nTotalMissionPeds_Stored;
for (int i = 0; i < CPools::GetPedPool()->GetSize(); i++) {
CPed* ped = CPools::GetPedPool()->GetSlot(i);
if (!ped)
@@ -1346,7 +1617,6 @@ void CReplay::RestoreStuffFromMem(void)
}
delete[] pPedAnims;
pPedAnims = nil;
-#ifdef FIX_BUGS
memcpy(CGarages::aGarages, pGarages, sizeof(CGarages::aGarages));
delete[] pGarages;
pGarages = nil;
@@ -1360,8 +1630,8 @@ void CReplay::RestoreStuffFromMem(void)
memcpy(CProjectileInfo::ms_apProjectile, paProjectiles, sizeof(CProjectileInfo::ms_apProjectile));
delete[] paProjectiles;
paProjectiles = nil;
- //CExplosion::ClearAllExplosions(); not in III
-#endif
+ CScriptPaths::Load_ForReplay();
+ CExplosion::ClearAllExplosions();
DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND);
DMAudio.SetRadioInCar(OldRadioStation);
DMAudio.ChangeMusicMode(MUSICMODE_GAME);
@@ -1499,6 +1769,9 @@ void CReplay::StreamAllNecessaryCarsAndPeds(void)
case REPLAYPACKET_VEHICLE:
CStreaming::RequestModel(((tVehicleUpdatePacket*)&Buffers[slot][offset])->mi, 0);
break;
+ case REPLAYPACKET_BIKE:
+ CStreaming::RequestModel(((tBikeUpdatePacket*)&Buffers[slot][offset])->mi, 0);
+ break;
case REPLAYPACKET_PED_HEADER:
CStreaming::RequestModel(((tPedHeaderPacket*)&Buffers[slot][offset])->mi, 0);
break;
@@ -1595,6 +1868,7 @@ size_t CReplay::FindSizeOfPacket(uint8 type)
switch (type) {
case REPLAYPACKET_END: return 4;
case REPLAYPACKET_VEHICLE: return sizeof(tVehicleUpdatePacket);
+ case REPLAYPACKET_BIKE: return sizeof(tBikeUpdatePacket);
case REPLAYPACKET_PED_HEADER: return sizeof(tPedHeaderPacket);
case REPLAYPACKET_PED_UPDATE: return sizeof(tPedUpdatePacket);
case REPLAYPACKET_GENERAL: return sizeof(tGeneralPacket);
@@ -1603,6 +1877,8 @@ size_t CReplay::FindSizeOfPacket(uint8 type)
case REPLAYPACKET_ENDOFFRAME: return 4;
case REPLAYPACKET_TIMER: return sizeof(tTimerPacket);
case REPLAYPACKET_BULLET_TRACES:return sizeof(tBulletTracePacket);
+ case REPLAYPACKET_PARTICLE: return sizeof(tParticlePacket);
+ case REPLAYPACKET_MISC: return sizeof(tMiscPacket);
default: assert(false); break;
}
return 0;
@@ -1628,7 +1904,7 @@ void CReplay::Display()
CFont::SetCentreOff();
CFont::SetPropOn();
CFont::SetColor(CRGBA(255, 255, 200, 200));
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
if (Mode == MODE_PLAYBACK)
CFont::PrintString(SCREEN_WIDTH/15, SCREEN_HEIGHT/10, TheText.Get("REPLAY"));
}
diff --git a/src/control/Replay.h b/src/control/Replay.h
index 68da9cc3..5dd8b651 100644
--- a/src/control/Replay.h
+++ b/src/control/Replay.h
@@ -2,6 +2,8 @@
#include "Pools.h"
#include "World.h"
+#include "WeaponEffects.h"
+#include "ParticleType.h"
#ifdef FIX_BUGS
#ifndef DONT_FIX_REPLAY_BUGS
@@ -24,14 +26,17 @@ struct CStoredAnimationState
uint8 animId;
uint8 time;
uint8 speed;
+ uint8 groupId;
uint8 secAnimId;
uint8 secTime;
uint8 secSpeed;
+ uint8 secGroupId;
uint8 blendAmount;
uint8 partAnimId;
uint8 partAnimTime;
uint8 partAnimSpeed;
uint8 partBlendAmount;
+ uint8 partGroupId;
};
enum {
@@ -45,20 +50,18 @@ struct CStoredDetailedAnimationState
uint8 aCurTime[NUM_MAIN_ANIMS_IN_REPLAY];
uint8 aSpeed[NUM_MAIN_ANIMS_IN_REPLAY];
uint8 aBlendAmount[NUM_MAIN_ANIMS_IN_REPLAY];
-#ifdef FIX_REPLAY_BUGS
int8 aBlendDelta[NUM_MAIN_ANIMS_IN_REPLAY];
-#endif
uint8 aFunctionCallbackID[NUM_MAIN_ANIMS_IN_REPLAY];
uint16 aFlags[NUM_MAIN_ANIMS_IN_REPLAY];
+ uint8 aGroupId[NUM_MAIN_ANIMS_IN_REPLAY];
uint8 aAnimId2[NUM_PARTIAL_ANIMS_IN_REPLAY];
uint8 aCurTime2[NUM_PARTIAL_ANIMS_IN_REPLAY];
uint8 aSpeed2[NUM_PARTIAL_ANIMS_IN_REPLAY];
uint8 aBlendAmount2[NUM_PARTIAL_ANIMS_IN_REPLAY];
-#ifdef FIX_REPLAY_BUGS
int8 aBlendDelta2[NUM_PARTIAL_ANIMS_IN_REPLAY];
-#endif
uint8 aFunctionCallbackID2[NUM_PARTIAL_ANIMS_IN_REPLAY];
uint16 aFlags2[NUM_PARTIAL_ANIMS_IN_REPLAY];
+ uint8 aGroupId2[NUM_PARTIAL_ANIMS_IN_REPLAY];
};
#ifdef GTA_REPLAY
@@ -76,21 +79,24 @@ class CReplay
enum {
REPLAYCAMMODE_ASSTORED = 0,
- REPLAYCAMMODE_TOPDOWN = 1,
- REPLAYCAMMODE_FIXED = 2
+ REPLAYCAMMODE_TOPDOWN,
+ REPLAYCAMMODE_FIXED
};
enum {
REPLAYPACKET_END = 0,
- REPLAYPACKET_VEHICLE = 1,
- REPLAYPACKET_PED_HEADER = 2,
- REPLAYPACKET_PED_UPDATE = 3,
- REPLAYPACKET_GENERAL = 4,
- REPLAYPACKET_CLOCK = 5,
- REPLAYPACKET_WEATHER = 6,
- REPLAYPACKET_ENDOFFRAME = 7,
- REPLAYPACKET_TIMER = 8,
- REPLAYPACKET_BULLET_TRACES = 9
+ REPLAYPACKET_VEHICLE,
+ REPLAYPACKET_BIKE,
+ REPLAYPACKET_PED_HEADER,
+ REPLAYPACKET_PED_UPDATE,
+ REPLAYPACKET_GENERAL,
+ REPLAYPACKET_CLOCK,
+ REPLAYPACKET_WEATHER,
+ REPLAYPACKET_ENDOFFRAME,
+ REPLAYPACKET_TIMER,
+ REPLAYPACKET_BULLET_TRACES,
+ REPLAYPACKET_PARTICLE,
+ REPLAYPACKET_MISC
};
enum {
@@ -179,8 +185,9 @@ class CReplay
int8 vehicle_index;
CStoredAnimationState anim_state;
CCompressedMatrixNotAligned matrix;
+ uint16 weapon_model;
int8 assoc_group_id;
- uint8 weapon_model;
+ bool is_visible;
};
VALIDATE_SIZE(tPedUpdatePacket, 40);
@@ -206,8 +213,65 @@ class CReplay
uint8 door_status;
uint8 primary_color;
uint8 secondary_color;
+ bool render_scorched;
+ int8 skimmer_speed;
+ int8 vehicle_type;
+
+ };
+ VALIDATE_SIZE(tVehicleUpdatePacket, 52);
+
+ struct tBikeUpdatePacket
+ {
+ uint8 type;
+ uint8 index;
+ uint8 health;
+ uint8 acceleration;
+ CCompressedMatrixNotAligned matrix;
+ int8 door_angles[2];
+ uint16 mi;
+ int8 velocityX;
+ int8 velocityY;
+ int8 velocityZ;
+ int8 wheel_state;
+ uint8 wheel_susp_dist[4];
+ uint8 wheel_rotation[4];
+ uint8 primary_color;
+ uint8 secondary_color;
+ int8 lean_angle;
+ int8 wheel_angle;
+
+ };
+ VALIDATE_SIZE(tBikeUpdatePacket, 44);
+
+ struct tParticlePacket
+ {
+ uint8 type;
+ uint8 particle_type;
+ int8 dir_x;
+ int8 dir_y;
+ int8 dir_z;
+ uint8 r;
+ uint8 g;
+ uint8 b;
+ uint8 a;
+ int16 pos_x;
+ int16 pos_y;
+ int16 pos_z;
+ float size;
+ };
+ VALIDATE_SIZE(tParticlePacket, 20);
+
+ struct tMiscPacket
+ {
+ uint8 type;
+ uint32 cam_shake_start;
+ float cam_shake_strength;
+ uint8 cur_area;
+ uint8 video_cam : 1;
+ uint8 lift_cam : 1;
};
- VALIDATE_SIZE(tVehicleUpdatePacket, 48);
+
+ VALIDATE_SIZE(tMiscPacket, 16);
private:
static uint8 Mode;
@@ -218,7 +282,7 @@ private:
static uint8* pBuf2;
static CPlayerPed* pBuf3;
static uint8* pBuf4;
- static CCutsceneHead* pBuf5;
+ static CCutsceneObject* pBuf5;
static uint8* pBuf6;
static CPtrNode* pBuf7;
static uint8* pBuf8;
@@ -272,12 +336,32 @@ private:
static float fDistanceLookAroundCam;
static float fAlphaAngleLookAroundCam;
static float fBetaAngleLookAroundCam;
-#ifdef FIX_BUGS
+ static int ms_nNumCivMale_Stored;
+ static int ms_nNumCivFemale_Stored;
+ static int ms_nNumCop_Stored;
+ static int ms_nNumEmergency_Stored;
+ static int ms_nNumGang1_Stored;
+ static int ms_nNumGang2_Stored;
+ static int ms_nNumGang3_Stored;
+ static int ms_nNumGang4_Stored;
+ static int ms_nNumGang5_Stored;
+ static int ms_nNumGang6_Stored;
+ static int ms_nNumGang7_Stored;
+ static int ms_nNumGang8_Stored;
+ static int ms_nNumGang9_Stored;
+ static int ms_nNumDummy_Stored;
+ static int ms_nTotalCarPassengerPeds_Stored;
+ static int ms_nTotalCivPeds_Stored;
+ static int ms_nTotalGangPeds_Stored;
+ static int ms_nTotalPeds_Stored;
+ static int ms_nTotalMissionPeds_Stored;
static uint8* pGarages;
static CFire* FireArray;
static uint32 NumOfFires;
static uint8* paProjectileInfo;
static uint8* paProjectiles;
+ static uint8 CurrArea;
+#ifdef FIX_BUGS
static int nHandleOfPlayerPed[NUMPLAYERS];
#endif
@@ -291,6 +375,7 @@ public:
static void Display(void) REPLAY_STUB;
static void TriggerPlayback(uint8 cam_mode, float cam_x, float cam_y, float cam_z, bool load_scene) REPLAY_STUB;
static void StreamAllNecessaryCarsAndPeds(void) REPLAY_STUB;
+ static void RecordParticle(tParticleType type, CVector const& vecPos, CVector const& vecDir, float fSize, RwRGBA const& color) REPLAY_STUB;
#ifndef GTA_REPLAY
static bool ShouldStandardCameraBeProcessed(void) { return true; }
@@ -312,7 +397,9 @@ private:
static void TriggerPlaybackLastCoupleOfSeconds(uint32, uint8, float, float, float, uint32);
static bool FastForwardToTime(uint32);
static void StoreCarUpdate(CVehicle *vehicle, int id);
+ static void StoreBikeUpdate(CVehicle* vehicle, int id);
static void ProcessCarUpdate(CVehicle *vehicle, float interpolation, CAddressInReplayBuffer *buffer);
+ static void ProcessBikeUpdate(CVehicle* vehicle, float interpolation, CAddressInReplayBuffer* buffer);
static bool PlayBackThisFrameInterpolation(CAddressInReplayBuffer *buffer, float interpolation, uint32 *pTimer);
static void ProcessReplayCamera(void);
static void StoreStuffInMem(void);
@@ -325,5 +412,6 @@ private:
static void FindFirstFocusCoordinate(CVector *coord);
static void ProcessLookAroundCam(void);
static size_t FindSizeOfPacket(uint8);
+ static void GoToNextBlock(void);
#endif
};
diff --git a/src/control/Restart.cpp b/src/control/Restart.cpp
index 2f5e3d45..af38537d 100644
--- a/src/control/Restart.cpp
+++ b/src/control/Restart.cpp
@@ -4,6 +4,7 @@
#include "SaveBuf.h"
#include "Zones.h"
#include "PathFind.h"
+#include "SaveBuf.h"
uint8 CRestart::OverrideHospitalLevel;
uint8 CRestart::OverridePoliceStationLevel;
@@ -81,13 +82,13 @@ CRestart::FindClosestHospitalRestartPoint(const CVector &pos, CVector *outPos, f
return;
}
- eLevelName curlevel = CTheZones::FindZoneForPoint(pos);
+ eLevelName curlevel = CTheZones::GetLevelFromPosition(&pos);
float fMinDist = SQR(4000.0f);
int closestPoint = NUM_RESTART_POINTS;
// find closest point on this level
for (int i = 0; i < NumberOfHospitalRestarts; i++) {
- if (CTheZones::FindZoneForPoint(HospitalRestartPoints[i]) == (OverrideHospitalLevel != LEVEL_GENERIC ? OverrideHospitalLevel : curlevel)) {
+ if (CTheZones::GetLevelFromPosition(&HospitalRestartPoints[i]) == (OverrideHospitalLevel != LEVEL_GENERIC ? OverrideHospitalLevel : curlevel)) {
float dist = (pos - HospitalRestartPoints[i]).MagnitudeSqr();
if (fMinDist >= dist) {
fMinDist = dist;
@@ -128,13 +129,13 @@ CRestart::FindClosestPoliceRestartPoint(const CVector &pos, CVector *outPos, flo
return;
}
- eLevelName curlevel = CTheZones::FindZoneForPoint(pos);
+ eLevelName curlevel = CTheZones::GetLevelFromPosition(&pos);
float fMinDist = SQR(4000.0f);
int closestPoint = NUM_RESTART_POINTS;
// find closest point on this level
for (int i = 0; i < NumberOfPoliceRestarts; i++) {
- if (CTheZones::FindZoneForPoint(PoliceRestartPoints[i]) == (OverridePoliceStationLevel != LEVEL_GENERIC ? OverridePoliceStationLevel : curlevel)) {
+ if (CTheZones::GetLevelFromPosition(&PoliceRestartPoints[i]) == (OverridePoliceStationLevel != LEVEL_GENERIC ? OverridePoliceStationLevel : curlevel)) {
float dist = (pos - PoliceRestartPoints[i]).MagnitudeSqr();
if (fMinDist >= dist) {
fMinDist = dist;
diff --git a/src/control/RoadBlocks.cpp b/src/control/RoadBlocks.cpp
index 4c3307c5..e30313bf 100644
--- a/src/control/RoadBlocks.cpp
+++ b/src/control/RoadBlocks.cpp
@@ -14,23 +14,30 @@
#include "Camera.h"
#include "CarCtrl.h"
#include "General.h"
+#include "Object.h"
-#define ROADBLOCKDIST (80.0f)
+#define ROADBLOCKDIST (90.0f)
+#define ROADBLOCK_OBJECT_WIDTH (4.0f)
int16 CRoadBlocks::NumRoadBlocks;
-int16 CRoadBlocks::RoadBlockObjects[NUMROADBLOCKS];
+int16 CRoadBlocks::RoadBlockNodes[NUMROADBLOCKS];
bool CRoadBlocks::InOrOut[NUMROADBLOCKS];
+CScriptRoadblock CRoadBlocks::aScriptRoadBlocks[NUM_SCRIPT_ROADBLOCKS];
+
+#ifdef SECUROM
+uint8 roadBlocksPirateCheck = 0;
+#endif
void
CRoadBlocks::Init(void)
{
int i;
NumRoadBlocks = 0;
- for (i = 0; i < ThePaths.m_numMapObjects; i++) {
- if (ThePaths.m_objectFlags[i] & UseInRoadBlock) {
+ for(i = 0; i < ThePaths.m_numCarPathNodes; i++){
+ if(ThePaths.m_pathNodes[i].bUseInRoadBlock && ThePaths.m_pathNodes[i].numLinks == 2){
if (NumRoadBlocks < NUMROADBLOCKS) {
InOrOut[NumRoadBlocks] = true;
- RoadBlockObjects[NumRoadBlocks] = i;
+ RoadBlockNodes[NumRoadBlocks] = i;
NumRoadBlocks++;
} else {
#ifndef MASTER
@@ -41,10 +48,12 @@ CRoadBlocks::Init(void)
}
}
}
+
+ ClearScriptRoadBlocks();
}
void
-CRoadBlocks::GenerateRoadBlockCopsForCar(CVehicle* pVehicle, int32 roadBlockType, int16 roadBlockNode)
+CRoadBlocks::GenerateRoadBlockCopsForCar(CVehicle* pVehicle, int32 roadBlockType)
{
static const CVector vecRoadBlockOffets[6] = { CVector(-1.5, 1.8f, 0.0f), CVector(-1.5f, -1.8f, 0.0f), CVector(1.5f, 1.8f, 0.0f),
CVector(1.5f, -1.8f, 0.0f), CVector(-1.5f, 0.0f, 0.0f), CVector(1.5, 0.0, 0.0) };
@@ -60,7 +69,7 @@ CRoadBlocks::GenerateRoadBlockCopsForCar(CVehicle* pVehicle, int32 roadBlockType
eCopType copType = COP_STREET;
switch (pVehicle->GetModelIndex())
{
- case MI_FBICAR:
+ case MI_FBIRANCH:
modelInfoId = MI_FBI;
copType = COP_FBI;
break;
@@ -85,8 +94,10 @@ CRoadBlocks::GenerateRoadBlockCopsForCar(CVehicle* pVehicle, int32 roadBlockType
pCopPed->SetIdle();
pCopPed->bKindaStayInSamePlace = true;
pCopPed->bNotAllowedToDuck = false;
- pCopPed->m_nRoadblockNode = roadBlockNode;
- pCopPed->bCrouchWhenShooting = roadBlockType != 2;
+ pCopPed->m_nExtendedRangeTimer = CTimer::GetTimeInMilliseconds() + 10000;
+ pCopPed->m_nRoadblockVeh = pVehicle;
+ pCopPed->m_nRoadblockVeh->RegisterReference((CEntity**)&pCopPed->m_nRoadblockVeh);
+ pCopPed->bCrouchWhenShooting = roadBlockType == 2 ? false : true;
if (pEntityToAttack) {
pCopPed->SetWeaponLockOnTarget(pEntityToAttack);
pCopPed->SetAttack(pEntityToAttack);
@@ -102,96 +113,186 @@ CRoadBlocks::GenerateRoadBlockCopsForCar(CVehicle* pVehicle, int32 roadBlockType
void
CRoadBlocks::GenerateRoadBlocks(void)
{
+ CMatrix tmp1, tmp2;
+ static int16 unk;
#ifdef SQUEEZE_PERFORMANCE
if (FindPlayerPed()->m_pWanted->m_RoadblockDensity == 0)
return;
#endif
- CMatrix offsetMatrix;
uint32 frame = CTimer::GetFrameCounter() & 0xF;
int16 nRoadblockNode = (int16)(NUMROADBLOCKS * frame) / 16;
const int16 maxRoadBlocks = (int16)(NUMROADBLOCKS * (frame + 1)) / 16;
for (; nRoadblockNode < Min(NumRoadBlocks, maxRoadBlocks); nRoadblockNode++) {
- CTreadable *mapObject = ThePaths.m_mapObjects[RoadBlockObjects[nRoadblockNode]];
- CVector2D vecDistance = FindPlayerCoors() - mapObject->GetPosition();
+ int16 node = RoadBlockNodes[nRoadblockNode];
+ CVector2D vecDistance = FindPlayerCoors() - ThePaths.m_pathNodes[node].GetPosition();
if (vecDistance.x > -ROADBLOCKDIST && vecDistance.x < ROADBLOCKDIST &&
vecDistance.y > -ROADBLOCKDIST && vecDistance.y < ROADBLOCKDIST &&
vecDistance.Magnitude() < ROADBLOCKDIST) {
if (!InOrOut[nRoadblockNode]) {
InOrOut[nRoadblockNode] = true;
if (FindPlayerVehicle() && (CGeneral::GetRandomNumber() & 0x7F) < FindPlayerPed()->m_pWanted->m_RoadblockDensity) {
- CWanted *pPlayerWanted = FindPlayerPed()->m_pWanted;
- float fMapObjectRadius = 2.0f * mapObject->GetColModel()->boundingBox.max.x;
- int32 vehicleId = MI_POLICE;
- if (pPlayerWanted->AreArmyRequired())
- vehicleId = MI_BARRACKS;
- else if (pPlayerWanted->AreFbiRequired())
- vehicleId = MI_FBICAR;
- else if (pPlayerWanted->AreSwatRequired())
- vehicleId = MI_ENFORCER;
- if (!CStreaming::HasModelLoaded(vehicleId))
- vehicleId = MI_POLICE;
- CColModel *pVehicleColModel = CModelInfo::GetColModel(vehicleId);
- float fModelRadius = 2.0f * pVehicleColModel->boundingSphere.radius + 0.25f;
- int16 radius = (int16)(fMapObjectRadius / fModelRadius);
- if (radius >= 6)
- continue;
- CVector2D vecDistanceToCamera = TheCamera.GetPosition() - mapObject->GetPosition();
- float fDotProduct = DotProduct2D(vecDistanceToCamera, mapObject->GetForward());
- float fOffset = 0.5f * fModelRadius * (float)(radius - 1);
- for (int16 i = 0; i < radius; i++) {
- uint8 nRoadblockType = fDotProduct < 0.0f;
- if (CGeneral::GetRandomNumber() & 1) {
- offsetMatrix.SetRotateZ(((CGeneral::GetRandomNumber() & 0xFF) - 128.0f) * 0.003f + HALFPI);
- }
- else {
- nRoadblockType = !nRoadblockType;
- offsetMatrix.SetRotateZ(((CGeneral::GetRandomNumber() & 0xFF) - 128.0f) * 0.003f - HALFPI);
- }
- if (ThePaths.m_objectFlags[RoadBlockObjects[nRoadblockNode]] & ObjectEastWest)
- offsetMatrix.GetPosition() = CVector(0.0f, i * fModelRadius - fOffset, 0.6f);
- else
- offsetMatrix.GetPosition() = CVector(i * fModelRadius - fOffset, 0.0f, 0.6f);
- CMatrix vehicleMatrix = mapObject->GetMatrix() * offsetMatrix;
- float fModelRadius = CModelInfo::GetColModel(vehicleId)->boundingSphere.radius - 0.25f;
- int16 colliding = 0;
- CWorld::FindObjectsKindaColliding(vehicleMatrix.GetPosition(), fModelRadius, 0, &colliding, 2, nil, false, true, true, false, false);
- if (!colliding) {
- CAutomobile *pVehicle = new CAutomobile(vehicleId, RANDOM_VEHICLE);
- pVehicle->SetStatus(STATUS_ABANDONED);
- // pVehicle->GetHeightAboveRoad(); // called but return value is ignored?
- vehicleMatrix.GetPosition().z += fModelRadius - 0.6f;
- pVehicle->SetMatrix(vehicleMatrix);
- pVehicle->PlaceOnRoadProperly();
- pVehicle->SetIsStatic(false);
- pVehicle->GetMatrix().UpdateRW();
- pVehicle->m_nDoorLock = CARLOCK_UNLOCKED;
- CCarCtrl::JoinCarWithRoadSystem(pVehicle);
- pVehicle->bIsLocked = false;
- pVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
- pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE;
- pVehicle->AutoPilot.m_nCurrentLane = 0;
- pVehicle->AutoPilot.m_nNextLane = 0;
- pVehicle->AutoPilot.m_fMaxTrafficSpeed = 0.0f;
- pVehicle->AutoPilot.m_nCruiseSpeed = 0.0f;
- pVehicle->bExtendedRange = true;
- if (pVehicle->UsesSiren(pVehicle->GetModelIndex()) && CGeneral::GetRandomNumber() & 1)
- pVehicle->m_bSirenOrAlarm = true;
- if (pVehicle->GetUp().z > 0.94f) {
- CVisibilityPlugins::SetClumpAlpha(pVehicle->GetClump(), 0);
- CWorld::Add(pVehicle);
- pVehicle->bCreateRoadBlockPeds = true;
- pVehicle->m_nRoadblockType = nRoadblockType;
- pVehicle->m_nRoadblockNode = nRoadblockNode;
- }
- else {
- delete pVehicle;
- }
- }
+ CCarPathLink* pLink1 = &ThePaths.m_carPathLinks[ThePaths.m_carPathConnections[ThePaths.m_pathNodes[node].firstLink]];
+ CCarPathLink* pLink2 = &ThePaths.m_carPathLinks[ThePaths.m_carPathConnections[ThePaths.m_pathNodes[node].firstLink + 1]];
+ int lanes = Min(pLink1->numRightLanes + pLink1->numLeftLanes, pLink2->numLeftLanes + pLink2->numRightLanes);
+ float length = LANE_WIDTH * (lanes + 1);
+ CVector forward(pLink2->GetY() - pLink1->GetY(), -(pLink2->GetX() - pLink1->GetX()), 0.0f);
+ forward.Normalise();
+ if (ThePaths.m_pathNodes[node].HasDivider()) {
+ CreateRoadBlockBetween2Points(
+ ThePaths.m_pathNodes[node].GetPosition() + (length * 0.5f + ThePaths.m_pathNodes[node].GetDividerWidth()) * forward,
+ ThePaths.m_pathNodes[node].GetPosition() + ThePaths.m_pathNodes[node].GetDividerWidth() * forward);
+ CreateRoadBlockBetween2Points(
+ ThePaths.m_pathNodes[node].GetPosition() - ThePaths.m_pathNodes[node].GetDividerWidth() * forward,
+ ThePaths.m_pathNodes[node].GetPosition() - (length * 0.5f + ThePaths.m_pathNodes[node].GetDividerWidth()) * forward);
+ }
+ else {
+ CreateRoadBlockBetween2Points(
+ ThePaths.m_pathNodes[node].GetPosition() + (length * 0.5f) * forward,
+ ThePaths.m_pathNodes[node].GetPosition() - (length * 0.5f) * forward);
}
}
}
- } else {
+ }
+ else {
InOrOut[nRoadblockNode] = false;
}
}
+ int i = CTimer::GetFrameCounter() & 0xF;
+ if (!aScriptRoadBlocks[i].m_bInUse)
+ return;
+ if ((aScriptRoadBlocks[i].GetPosition() - FindPlayerCoors()).Magnitude() < 100.0f) {
+ CreateRoadBlockBetween2Points(aScriptRoadBlocks[i].m_vInf, aScriptRoadBlocks[i].m_vSup);
+ aScriptRoadBlocks[i].m_bInUse = false;
+ }
+}
+
+void
+CRoadBlocks::ClearScriptRoadBlocks(void)
+{
+ for (int i = 0; i < NUM_SCRIPT_ROADBLOCKS; i++)
+ aScriptRoadBlocks[i].m_bInUse = false;
+}
+
+void
+CRoadBlocks::RegisterScriptRoadBlock(CVector vInf, CVector vSup)
+{
+ int32 i;
+ for (i = 0; i < NUM_SCRIPT_ROADBLOCKS; i++) {
+ if (!aScriptRoadBlocks[i].m_bInUse)
+ break;
+ }
+ if (i == NUM_SCRIPT_ROADBLOCKS)
+ return;
+ aScriptRoadBlocks[i].m_bInUse = true;
+ aScriptRoadBlocks[i].m_vInf = vInf;
+ aScriptRoadBlocks[i].m_vSup = vSup;
+}
+
+void
+CRoadBlocks::CreateRoadBlockBetween2Points(CVector point1, CVector point2)
+{
+#ifdef SECUROM
+ if (roadBlocksPirateCheck == 0)
+ // if not pirated game
+ // roadBlocksPirateCheck = 1;
+ // else
+ roadBlocksPirateCheck = 2;
+#endif
+ CMatrix tmp;
+ CVector forward = (point2 - point1);
+ float distBetween = forward.Magnitude();
+ CVector pos = (point1 + point2) / 2;
+ CVector right(forward.y, -forward.x, 0.0f);
+ forward.Normalise();
+ right.Normalise();
+ if (DotProduct(FindPlayerCoors() - pos, right) < 0.0f) {
+ right *= -1.0f;
+ }
+ int32 vehicleId = MI_POLICE;
+ if (FindPlayerPed()->m_pWanted->AreArmyRequired())
+ vehicleId = MI_BARRACKS;
+ else if (FindPlayerPed()->m_pWanted->AreFbiRequired())
+ vehicleId = MI_FBICAR;
+ else if (FindPlayerPed()->m_pWanted->AreSwatRequired())
+ vehicleId = MI_ENFORCER;
+ if (!CStreaming::HasModelLoaded(vehicleId))
+ vehicleId = MI_POLICE;
+ CColModel *pVehicleColModel = CModelInfo::GetColModel(vehicleId);
+ float fModelRadius = 2.0f * pVehicleColModel->boundingSphere.radius + 0.25f;
+ int16 numRoadblockVehicles = Min(6, (int16)(distBetween / fModelRadius));
+ for (int16 i = 0; i < numRoadblockVehicles; i++) {
+ float offset = fModelRadius * (i - numRoadblockVehicles / 2);
+ tmp.SetTranslate(0.0f, 0.0f, 0.0f);
+ tmp.GetRight() = CVector(forward.y, -forward.x, 0.0f);
+ tmp.GetForward() = forward;
+ tmp.GetUp() = CVector(0.0f, 0.0f, 1.0f);
+ tmp.RotateZ(((CGeneral::GetRandomNumber() & 0xFF) - 128.0f) * 0.003f);
+ if (CGeneral::GetRandomNumber() & 1)
+ tmp.RotateZ(((CGeneral::GetRandomNumber() & 0xFF) - 128.0f) * 0.003f + 3.1416f);
+ tmp.SetTranslateOnly(offset * forward + pos);
+ tmp.GetPosition().z += 0.6f;
+ float fModelRadius = CModelInfo::GetColModel(vehicleId)->boundingSphere.radius - 0.25f;
+ int16 colliding = 0;
+ CWorld::FindObjectsKindaColliding(tmp.GetPosition(), fModelRadius, 0, &colliding, 2, nil, false, true, true, false, false);
+ if (!colliding) {
+ CAutomobile* pVehicle = new CAutomobile(vehicleId, RANDOM_VEHICLE);
+ pVehicle->SetStatus(STATUS_ABANDONED);
+ // pVehicle->GetHeightAboveRoad(); // called but return value is ignored?
+ tmp.GetPosition().z += fModelRadius - 0.6f;
+ pVehicle->SetMatrix(tmp);
+ pVehicle->PlaceOnRoadProperly();
+ pVehicle->SetIsStatic(false);
+ pVehicle->GetMatrix().UpdateRW();
+ pVehicle->m_nDoorLock = CARLOCK_UNLOCKED;
+ CCarCtrl::JoinCarWithRoadSystem(pVehicle);
+ pVehicle->bIsLocked = false;
+ pVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
+ pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE;
+ pVehicle->AutoPilot.m_nNextLane = pVehicle->AutoPilot.m_nCurrentLane = 0;
+ pVehicle->AutoPilot.m_nCruiseSpeed = pVehicle->AutoPilot.m_fMaxTrafficSpeed = 0;
+ pVehicle->bExtendedRange = true;
+ if (pVehicle->UsesSiren() && CGeneral::GetRandomNumber() & 1)
+ pVehicle->m_bSirenOrAlarm = true;
+ if (pVehicle->GetUp().z > 0.94f) {
+ CVisibilityPlugins::SetClumpAlpha(pVehicle->GetClump(), 0);
+ CWorld::Add(pVehicle);
+ pVehicle->bCreateRoadBlockPeds = true;
+ pVehicle->m_nRoadblockType = DotProduct(pVehicle->GetRight(), pVehicle->GetPosition() - FindPlayerCoors()) >= 0.0f;
+ pVehicle->m_nSetPieceExtendedRangeTime = CTimer::GetTimeInMilliseconds() + 7000;
+ }
+ else {
+ delete pVehicle;
+ }
+ }
+ }
+ int numBarriers = distBetween / ROADBLOCK_OBJECT_WIDTH;
+ CStreaming::RequestModel(MI_ROADWORKBARRIER1, STREAMFLAGS_DONT_REMOVE);
+ if (!CStreaming::HasModelLoaded(MI_ROADWORKBARRIER1))
+ return;
+ for (int i = 0; i < numBarriers; i++) {
+ float offset = ROADBLOCK_OBJECT_WIDTH * (i - numBarriers / 2);
+ tmp.SetTranslate(0.0f, 0.0f, 0.0f);
+ tmp.GetRight() = CVector(forward.y, -forward.x, 0.0f);
+ tmp.GetForward() = forward;
+ tmp.GetUp() = CVector(0.0f, 0.0f, 1.0f);
+ tmp.RotateZ(((CGeneral::GetRandomNumber() & 0xFF) - 128.0f) * 0.003f);
+ tmp.SetTranslateOnly(5.0f * right + offset * forward + pos);
+ tmp.GetPosition().x += (CGeneral::GetRandomNumber() & 0xF) * 0.1f;
+ tmp.GetPosition().y += (CGeneral::GetRandomNumber() & 0xF) * 0.1f;
+ bool found;
+ tmp.GetPosition().z = CWorld::FindGroundZFor3DCoord(tmp.GetPosition().x, tmp.GetPosition().y, tmp.GetPosition().z + 2.0f, &found);
+ if (!found)
+ continue;
+ int16 colliding = 0;
+ CBaseModelInfo* pMI = CModelInfo::GetModelInfo(MI_ROADWORKBARRIER1);
+ tmp.GetPosition().z -= pMI->GetColModel()->boundingBox.min.z;
+ CWorld::FindObjectsKindaColliding(tmp.GetPosition(), pMI->GetColModel()->boundingSphere.radius, 0, &colliding, 2, nil, false, true, true, false, false);
+ if (colliding == 0) {
+ CObject* pObject = new CObject(MI_ROADWORKBARRIER1, true);
+ pObject->GetMatrix() = tmp;
+ pObject->ObjectCreatedBy = TEMP_OBJECT;
+ pObject->m_nEndOfLifeTime = CTimer::GetTimeInMilliseconds() + 600000;
+ CWorld::Add(pObject);
+ }
+ }
}
diff --git a/src/control/RoadBlocks.h b/src/control/RoadBlocks.h
index 0f0c1882..ef614950 100644
--- a/src/control/RoadBlocks.h
+++ b/src/control/RoadBlocks.h
@@ -3,14 +3,28 @@
class CVehicle;
+class CScriptRoadblock
+{
+public:
+ CVector m_vInf;
+ CVector m_vSup;
+ bool m_bInUse;
+ CVector GetPosition() { return (m_vInf + m_vSup) / 2; }
+};
+
class CRoadBlocks
{
public:
static int16 NumRoadBlocks;
- static int16 RoadBlockObjects[NUMROADBLOCKS];
+ static int16 RoadBlockNodes[NUMROADBLOCKS];
static bool InOrOut[NUMROADBLOCKS];
+ static CScriptRoadblock aScriptRoadBlocks[NUM_SCRIPT_ROADBLOCKS];
static void Init(void);
- static void GenerateRoadBlockCopsForCar(CVehicle* pVehicle, int32 roadBlockType, int16 roadBlockNode);
+ static void GenerateRoadBlockCopsForCar(CVehicle* pVehicle, int32 roadBlockType);
static void GenerateRoadBlocks(void);
+
+ static void CreateRoadBlockBetween2Points(CVector, CVector);
+ static void RegisterScriptRoadBlock(CVector, CVector);
+ static void ClearScriptRoadBlocks();
};
diff --git a/src/control/SceneEdit.cpp b/src/control/SceneEdit.cpp
index 42dadee0..74d81327 100644
--- a/src/control/SceneEdit.cpp
+++ b/src/control/SceneEdit.cpp
@@ -88,7 +88,7 @@ static int32 NextValidModelId(int32 mi, int32 step)
continue;
if (pInfo->GetModelType() == MITYPE_PED
#ifdef FIX_BUGS
- && !(i >= MI_SPECIAL01 && i <= MI_SPECIAL04)
+ && !(i >= MI_SPECIAL01 && i <= MI_SPECIAL21)
#endif
|| pInfo->GetModelType() == MITYPE_VEHICLE &&
#ifdef FIX_BUGS
@@ -269,7 +269,7 @@ void CSceneEdit::Draw(void)
CFont::SetRightJustifyWrap(0.0f);
CFont::SetBackGroundOnlyTextOff();
#ifdef FIX_BUGS
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
CFont::SetPropOn();
CFont::SetDropColor(CRGBA(0, 0, 0, 255));
CFont::SetDropShadowPosition(1);
@@ -312,7 +312,7 @@ void CSceneEdit::Draw(void)
CFont::SetScale(0.7f, 0.7f);
#endif
#ifdef FIX_BUGS
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
#else
CFont::SetFontStyle(FONT_HEADING);
#endif
@@ -1098,7 +1098,7 @@ bool CSceneEdit::SelectWeapon(void)
}
if (CPad::GetPad(1)->GetLeftShoulder1JustDown()) {
if (++m_nWeaponType >= WEAPONTYPE_DETONATOR)
- m_nWeaponType = WEAPONTYPE_BASEBALLBAT;
+ m_nWeaponType = WEAPONTYPE_BRASSKNUCKLE;
pActors[m_nActor]->ClearWeapons();
pActors[m_nActor]->GiveWeapon((eWeaponType)m_nWeaponType, 1000);
pActors[m_nActor]->AddWeaponModel(CWeaponInfo::GetWeaponInfo(pActors[m_nActor]->GetWeapon()->m_eWeaponType)->m_nModelId);
@@ -1106,7 +1106,7 @@ bool CSceneEdit::SelectWeapon(void)
}
else if (CPad::GetPad(1)->GetRightShoulder1JustDown()){
if (--m_nWeaponType <= WEAPONTYPE_UNARMED)
- m_nWeaponType = WEAPONTYPE_GRENADE;
+ m_nWeaponType = WEAPONTYPE_MINIGUN;
pActors[m_nActor]->ClearWeapons();
pActors[m_nActor]->GiveWeapon((eWeaponType)m_nWeaponType, 1000);
pActors[m_nActor]->AddWeaponModel(CWeaponInfo::GetWeaponInfo(pActors[m_nActor]->GetWeapon()->m_eWeaponType)->m_nModelId);
diff --git a/src/control/Script.cpp b/src/control/Script.cpp
index f1c8b348..a2dd8512 100644
--- a/src/control/Script.cpp
+++ b/src/control/Script.cpp
@@ -37,16 +37,28 @@
#include "Wanted.h"
#include "Weather.h"
#include "Zones.h"
+#include "main.h"
+#include "Ropes.h"
+#include "ColStore.h"
+#include "Fluff.h"
+#include "GameLogic.h"
+#include "MBlur.h"
+#include "PedRoutes.h"
+#include "RoadBlocks.h"
+#include "SpecialFX.h"
+#include "Timecycle.h"
+#include "TxdStore.h"
+#include "Bike.h"
+#ifdef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
+#include <stdarg.h>
+#endif
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];
@@ -67,8 +79,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;
@@ -79,6 +89,15 @@ 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;
+#if (defined GTA_PC && !defined GTAVC_JP_PATCH || defined GTA_XBOX || defined SUPPORT_XBOX_SCRIPT || defined GTA_MOBILE || defined SUPPORT_MOBILE_SCRIPT)
+int16 CTheScripts::CardStack[CARDS_IN_DECK * MAX_DECKS];
+int16 CTheScripts::CardStackPosition;
+#endif
#ifdef MISSION_REPLAY
@@ -97,7 +116,97 @@ static const char* nonMissionScripts[] = {
"rc4",
"hj",
"usj",
- "mayhem"
+ "mayhem",
+ "range",
+ "race",
+ "pizza",
+ "rcheli",
+ "rcplne1",
+ "rcrace1",
+ "cokerun",
+ "buypro1",
+ "carbuy1",
+ "buypro2",
+ "icecut",
+ "icecre1",
+ "buypro3",
+ "buypro4",
+ "buypro5",
+ "buypro6",
+ "buypro7",
+ "buypro8",
+ "buypro9",
+ "buypro10",
+ "buypro11",
+ "ovalrng",
+ "mm",
+ "kickst",
+ "heli1sc",
+ "heli2sc",
+ "heli3sc",
+ "heli4sc",
+ "carpark_1",
+ "bmx_1",
+ "bmx_2"
+};
+
+static const char* MissionScripts[] = {
+ "LAWYER1",
+ "LAWYER2",
+ "LAWYER3",
+ "LAWYER4",
+ "GENERL1",
+ "COL2",
+ "GENERL3",
+ "COL_4",
+ "COL_5",
+ "baron1",
+ "baron2",
+ "baron3",
+ "baron4",
+ "kent1",
+ "baron5",
+ "serg1",
+ "serg2",
+ "serg3",
+ "bankjo1",
+ "bankjo2",
+ "bankjo3",
+ "bankjo4",
+ "phil1",
+ "phil2",
+ "porno1",
+ "porno2",
+ "porno3",
+ "porno4",
+ "protec1",
+ "protec2",
+ "protec3",
+ "count1",
+ "count2",
+ "CAP_1",
+ "FIN_1",
+ "bike1",
+ "bike2",
+ "bike3",
+ "rockb1",
+ "rockb2",
+ "rockb3",
+ "cuban1",
+ "cuban2",
+ "cuban3",
+ "cuban4",
+ "hait1",
+ "hait2",
+ "hait3",
+ "assin1",
+ "assin2",
+ "assin3",
+ "assin4",
+ "assin5",
+ "taxwar1",
+ "taxwar2",
+ "taxwar3"
};
int AllowMissionReplay;
@@ -109,6 +218,14 @@ float oldTargetX;
float oldTargetY;
int missionRetryScriptIndex;
bool doingMissionRetry;
+bool gbTryingPorn4Again;
+int IsInAmmunation;
+int MissionSkipLevel;
+
+#ifdef USE_MISSION_REPLAY_OVERRIDE_FOR_NON_MOBILE_SCRIPT
+bool UsingMobileScript;
+bool AlreadySavedGame;
+#endif
#endif
@@ -157,6 +274,46 @@ void CMissionCleanup::RemoveEntityFromList(int32 id, uint8 type)
{
for (int i = 0; i < MAX_CLEANUP; i++){
if (m_sEntities[i].type == type && m_sEntities[i].id == id){
+ switch (m_sEntities[i].type) {
+ case CLEANUP_CAR:
+ {
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(m_sEntities[i].id);
+ if (pVehicle) {
+ if (pVehicle->bIsStaticWaitingForCollision) {
+ pVehicle->bIsStaticWaitingForCollision = false;
+ if (!pVehicle->GetIsStatic())
+ pVehicle->AddToMovingList();
+ }
+ }
+ break;
+ }
+ case CLEANUP_CHAR:
+ {
+ CPed* pPed = CPools::GetPedPool()->GetAt(m_sEntities[i].id);
+ if (pPed) {
+ if (pPed->bIsStaticWaitingForCollision) {
+ pPed->bIsStaticWaitingForCollision = false;
+ if (!pPed->GetIsStatic())
+ pPed->AddToMovingList();
+ }
+ }
+ break;
+ }
+ case CLEANUP_OBJECT:
+ {
+ CObject* pObject = CPools::GetObjectPool()->GetAt(m_sEntities[i].id);
+ if (pObject) {
+ if (pObject->bIsStaticWaitingForCollision) {
+ pObject->bIsStaticWaitingForCollision = false;
+ if (!pObject->GetIsStatic())
+ pObject->AddToMovingList();
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
m_sEntities[i].id = 0;
m_sEntities[i].type = CLEANUP_UNUSED;
m_nCount--;
@@ -164,15 +321,76 @@ void CMissionCleanup::RemoveEntityFromList(int32 id, uint8 type)
}
}
+void CMissionCleanup::CheckIfCollisionHasLoadedForMissionObjects()
+{
+ for (int i = 0; i < MAX_CLEANUP; i++) {
+ switch (m_sEntities[i].type) {
+ case CLEANUP_CAR:
+ {
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(m_sEntities[i].id);
+ if (pVehicle) {
+ if (pVehicle->bIsStaticWaitingForCollision) {
+ if (CColStore::HasCollisionLoaded(pVehicle->GetPosition())) {
+ pVehicle->bIsStaticWaitingForCollision = false;
+ if (!pVehicle->GetIsStatic())
+ pVehicle->AddToMovingList();
+ }
+ }
+ }
+ break;
+ }
+ case CLEANUP_CHAR:
+ {
+ CPed* pPed = CPools::GetPedPool()->GetAt(m_sEntities[i].id);
+ if (pPed) {
+ if (pPed->bIsStaticWaitingForCollision) {
+ if (CColStore::HasCollisionLoaded(pPed->GetPosition())) {
+ pPed->bIsStaticWaitingForCollision = false;
+ if (!pPed->GetIsStatic())
+ pPed->AddToMovingList();
+ }
+ }
+ }
+ break;
+ }
+ case CLEANUP_OBJECT:
+ {
+ CObject* pObject = CPools::GetObjectPool()->GetAt(m_sEntities[i].id);
+ if (pObject) {
+ if (pObject->bIsStaticWaitingForCollision) {
+ if (CColStore::HasCollisionLoaded(pObject->GetPosition())) {
+ pObject->bIsStaticWaitingForCollision = false;
+ if (!pObject->GetIsStatic())
+ pObject->AddToMovingList();
+ }
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+}
+
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();
+ CRouteNode::Initialise();
+ if (!CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle)
+ TheCamera.Restore();
TheCamera.SetWideScreenOff();
- DMAudio.ClearMissionAudio();
+ CSpecialFX::bLiftCam = false;
+ CSpecialFX::bVideoCam = false;
+ CTimeCycle::StopExtraColour(0);
+ for (int i = 0; i < MISSION_AUDIO_SLOTS; i++)
+ DMAudio.ClearMissionAudio(i);
CWeather::ReleaseWeather();
for (int i = 0; i < NUM_OF_SPECIAL_CHARS; i++)
CStreaming::SetMissionDoesntRequireSpecialChar(i);
@@ -182,9 +400,19 @@ void CMissionCleanup::Process()
CHud::m_ItemToFlash = -1;
CHud::SetHelpMessage(nil, 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);
+ CWorld::Players[0].m_pPed->m_nFadeDrunkenness = 1;
+ CWorld::Players[0].m_pPed->m_nDrunkCountdown = 0;
+ CPad::GetPad(0)->SetDrunkInputDelay(0);
+ CWorld::Players[0].m_bDriveByAllowed = true;
+ DMAudio.ShutUpPlayerTalking(FALSE);
+ CVehicle::bDisableRemoteDetonation = false;
+ CVehicle::bDisableRemoteDetonationOnContact = false;
+ CGameLogic::ClearShortCut();
+ CTheScripts::RiotIntensity = 0;
CTheScripts::StoreVehicleIndex = -1;
CTheScripts::StoreVehicleWasRandom = true;
CTheScripts::UpsideDownCars.Init();
@@ -217,10 +445,14 @@ void CMissionCleanup::Process()
default:
break;
}
- m_sEntities[i].id = 0;
- m_sEntities[i].type = CLEANUP_UNUSED;
- m_nCount--;
+ RemoveEntityFromList(m_sEntities[i].id, m_sEntities[i].type);
}
+#ifdef SECUROM
+ if ((myrand() & 3) == 2){
+ // if pirated game
+ CWeather::ForceHurricaneWeather();
+ }
+#endif
}
/* NB: CUpsideDownCarCheck is not used by actual script at all
@@ -385,11 +617,11 @@ bool CStuckCarCheck::HasCarBeenStuckForAWhile(int32 id)
void CRunningScript::CollectParameters(uint32* pIp, int16 total)
{
for (int16 i = 0; i < total; i++){
- float tmp;
uint16 varIndex;
switch (CTheScripts::Read1ByteFromScript(pIp))
{
case ARGUMENT_INT32:
+ case ARGUMENT_FLOAT:
ScriptParams[i] = CTheScripts::Read4BytesFromScript(pIp);
break;
case ARGUMENT_GLOBALVAR:
@@ -408,10 +640,6 @@ void CRunningScript::CollectParameters(uint32* pIp, int16 total)
case ARGUMENT_INT16:
ScriptParams[i] = CTheScripts::Read2BytesFromScript(pIp);
break;
- case ARGUMENT_FLOAT:
- tmp = CTheScripts::ReadFloatFromScript(pIp);
- ScriptParams[i] = *(int32*)&tmp;
- break;
default:
script_assert(0);
break;
@@ -422,7 +650,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:
@@ -436,8 +663,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:
script_assert(0);
}
@@ -485,6 +711,7 @@ void CRunningScript::Init()
m_anStack[i] = 0;
m_nStackPointer = 0;
m_nWakeTime = 0;
+ m_bIsActive = false;
m_bCondResult = false;
m_bIsMissionScript = false;
m_bSkipWakeTime = false;
@@ -505,7 +732,7 @@ int CTheScripts::OpenScript()
CFileMgr::ChangeDir("\\");
switch (ScriptToLoad) {
case 0: return CFileMgr::OpenFile("data\\main.scm", "rb");
- case 1: return CFileMgr::OpenFile("data\\main_freeroam.scm", "rb");
+ case 1: return CFileMgr::OpenFile("data\\freeroam_miami.scm", "rb");
case 2: return CFileMgr::OpenFile("data\\main_d.scm", "rb");
}
return CFileMgr::OpenFile("data\\main.scm", "rb");
@@ -542,15 +769,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].colIndex = -1;
- CollectiveArray[i].pedIndex = 0;
- }
- NextFreeCollectiveIndex = 0;
+ LastMissionPassedTime = (uint32)-1;
LastRandomPedId = -1;
for (int i = 0; i < MAX_NUM_USED_OBJECTS; i++){
memset(&UsedObjectArray[i].name, 0, sizeof(UsedObjectArray[i].name));
@@ -563,15 +782,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;
@@ -592,6 +813,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;
@@ -603,6 +825,19 @@ void CTheScripts::Init()
#ifdef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
LogAfterScriptInitializing();
#endif
+#ifdef USE_MISSION_REPLAY_OVERRIDE_FOR_NON_MOBILE_SCRIPT
+ UsingMobileScript = false;
+ AlreadySavedGame = false;
+#endif
+}
+
+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)
@@ -632,6 +867,7 @@ CRunningScript* CTheScripts::StartNewScript(uint32 ip)
pNew->Init();
pNew->SetIP(ip);
pNew->AddScriptToList(&pActiveScripts);
+ pNew->m_bIsActive = true;
return pNew;
}
@@ -644,13 +880,10 @@ void CTheScripts::Process()
float timeStep = CTimer::GetTimeStepInMilliseconds();
UpsideDownCars.UpdateTimers();
StuckCars.Process();
+ MissionCleanUp.CheckIfCollisionHasLoadedForMissionObjects();
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();
@@ -666,6 +899,7 @@ void CTheScripts::Process()
#ifdef MISSION_REPLAY
static uint32 TimeToWaitTill;
+ static bool AlreadyResetHealth;
switch (AllowMissionReplay) {
case MISSION_RETRY_STAGE_START_PROCESSING:
AllowMissionReplay = MISSION_RETRY_STAGE_WAIT_FOR_DELAY;
@@ -681,9 +915,19 @@ void CTheScripts::Process()
break;
case MISSION_RETRY_STAGE_START_RESTARTING:
AllowMissionReplay = MISSION_RETRY_STAGE_WAIT_FOR_TIMER_AFTER_RESTART;
+ AlreadyResetHealth = false;
TimeToWaitTill = CTimer::GetTimeInMilliseconds() + 500;
break;
case MISSION_RETRY_STAGE_WAIT_FOR_TIMER_AFTER_RESTART:
+ if (!AlreadyResetHealth) {
+ AlreadyResetHealth = true;
+ CPlayerPed* pPlayerPed = FindPlayerPed();
+ if (pPlayerPed) {
+ CPlayerInfo* pPlayerInfo = pPlayerPed->GetPlayerInfoForThisPlayerPed();
+ if (pPlayerInfo)
+ pPlayerPed->m_fHealth = pPlayerInfo->m_nMaxHealth;
+ }
+ }
if (TimeToWaitTill < CTimer::GetTimeInMilliseconds()) {
AllowMissionReplay = MISSION_RETRY_STAGE_NORMAL;
return;
@@ -711,6 +955,8 @@ void CTheScripts::Process()
script->UpdateTimers(timeStep);
script->Process();
script = next;
+ if (script && !script->m_bIsActive)
+ script = nil;
}
DbgFlag = false;
@@ -786,24 +1032,30 @@ int8 CRunningScript::ProcessOneCommand()
retval = ProcessCommands800To899(command);
else if (command < 1000)
retval = ProcessCommands900To999(command);
-#if GTA_VERSION <= GTA3_PS2_160
- else if (command < 1200)
- retval = ProcessCommands1000To1099(command);
-#else
else if (command < 1100)
retval = ProcessCommands1000To1099(command);
else if (command < 1200)
retval = ProcessCommands1100To1199(command);
+ else if (command < 1300)
+ retval = ProcessCommands1200To1299(command);
+ else if (command < 1400)
+ retval = ProcessCommands1300To1399(command);
+ else if (command < 1500)
+ retval = ProcessCommands1400To1499(command);
+#ifdef USE_MISSION_REPLAY_OVERRIDE_FOR_NON_MOBILE_SCRIPT
+ if (!AlreadySavedGame) // we need to ignore first "fake" command which actually just saves the game
#endif
+ {
#ifdef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
- LogAfterProcessingCommand(command);
+ LogAfterProcessingCommand(command);
#elif defined USE_BASIC_SCRIPT_DEBUG_OUTPUT
- if (m_bMissionFlag) {
- char tmp[128];
- sprintf(tmp, "Comm %d Cmp %d", command, m_bCondResult);
- CDebug::DebugAddText(tmp);
- }
+ if (m_bMissionFlag) {
+ char tmp[128];
+ sprintf(tmp, "Comm %d Cmp %d", command, m_bCondResult);
+ CDebug::DebugAddText(tmp);
+ }
#endif
+ }
return retval;
}
@@ -1231,13 +1483,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);
@@ -1273,19 +1523,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)
@@ -1297,6 +1546,7 @@ int8 CRunningScript::ProcessCommands0To99(int32 command)
CTheScripts::bAlreadyRunningAMissionScript = false;
RemoveScriptFromList(&CTheScripts::pActiveScripts);
AddScriptToList(&CTheScripts::pIdleScripts);
+ m_bIsActive = false;
#ifdef MISSION_REPLAY
if (m_bMissionFlag) {
CPlayerInfo* pPlayerInfo = &CWorld::Players[CWorld::PlayerInFocus];
@@ -1316,6 +1566,7 @@ int8 CRunningScript::ProcessCommands0To99(int32 command)
CollectParameters(&m_nIp, 1);
script_assert(ScriptParams[0] >= 0);
CRunningScript* pNew = CTheScripts::StartNewScript(ScriptParams[0]);
+ pNew->m_bIsActive = true;
int8 type = CTheScripts::Read1ByteFromScript(&m_nIp);
float tmp;
for (int i = 0; type != ARGUMENT_END; type = CTheScripts::Read1ByteFromScript(&m_nIp), i++) {
@@ -1363,7 +1614,7 @@ int8 CRunningScript::ProcessCommands0To99(int32 command)
{
CollectParameters(&m_nIp, 4);
int32 index = ScriptParams[0];
- script_assert(index < 1); /* Constant? Also no more double player glitch */
+ script_assert(index < NUMPLAYERS);
printf("&&&&&&&&&&&&&Creating player: %d\n", index);
if (!CStreaming::HasModelLoaded(MI_PLAYER)) {
CStreaming::RequestSpecialModel(MI_PLAYER, "player", STREAMFLAGS_DONT_REMOVE | STREAMFLAGS_DEPENDENCY);
@@ -1403,20 +1654,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 == OBJECTIVE_FOLLOW_CHAR_IN_FORMATION) {
+ 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:
@@ -1852,6 +2132,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);
@@ -1859,6 +2140,8 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
ped->SetPosition(pos);
ped->SetOrientation(0.0f, 0.0f, 0.0f);
CTheScripts::ClearSpaceForMissionEntity(pos, ped);
+ if (m_bIsMissionScript)
+ ped->bIsStaticWaitingForCollision = true;
CWorld::Add(ped);
ped->m_nZoneLevel = CTheZones::GetLevelFromPosition(&pos);
CPopulation::ms_nTotalMissionPeds++;
@@ -1872,24 +2155,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;
@@ -1908,22 +2174,31 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
#else
path = CGeneral::GetRandomNumberInRange(0, 7);
#endif
+
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]);
script_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_RUN; break;
+ default: assert(0);
+ }
ped->ClearAll();
- ped->SetFollowPath(pos);
+ ped->m_pathNodeTimer = 0;
+ ped->SetFollowPath(pos, radius, state, nil, nil, 999999);
return 0;
}
case COMMAND_CHAR_SET_IDLE:
@@ -1968,44 +2243,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->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]);
- * script_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);
@@ -2013,6 +2271,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);
@@ -2078,15 +2337,22 @@ 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;
CWorld::Add(boat);
handle = CPools::GetVehiclePool()->GetIndex(boat);
}
else {
CVehicle* car;
+
if (!CModelInfo::IsBikeModel(ScriptParams[0]))
car = new CAutomobile(ScriptParams[0], MISSION_VEHICLE);
+ else {
+ car = new CBike(ScriptParams[0], MISSION_VEHICLE);
+ ((CBike*)(car))->bIsStanding = true;
+ }
CVector pos = *(CVector*)&ScriptParams[1];
if (pos.z <= MAP_Z_LOW_LIMIT)
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
@@ -2097,13 +2363,15 @@ 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;
car->bEngineOn = false;
car->m_nZoneLevel = CTheZones::GetLevelFromPosition(&pos);
car->bHasBeenOwnedByPlayer = true;
+ if (m_bIsMissionScript)
+ car->bIsStaticWaitingForCollision = true;
CWorld::Add(car);
handle = CPools::GetVehiclePool()->GetIndex(car);
}
@@ -2141,7 +2409,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
car->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS;
car->SetStatus(STATUS_PHYSICS);
car->bEngineOn = true;
- car->AutoPilot.m_nCruiseSpeed = Max(6, car->AutoPilot.m_nCruiseSpeed);
+ car->AutoPilot.m_nCruiseSpeed = Max(1, car->AutoPilot.m_nCruiseSpeed);
car->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds();
return 0;
}
@@ -2153,7 +2421,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
CCarCtrl::JoinCarWithRoadSystem(car);
car->AutoPilot.m_nCarMission = MISSION_CRUISE;
car->bEngineOn = true;
- car->AutoPilot.m_nCruiseSpeed = Max(6, car->AutoPilot.m_nCruiseSpeed);
+ car->AutoPilot.m_nCruiseSpeed = Max(1, car->AutoPilot.m_nCruiseSpeed);
car->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds();
return 0;
}
@@ -2225,6 +2493,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
}
return 0;
}
+ /*
case COMMAND_IS_CAR_STILL_ALIVE:
{
CollectParameters(&m_nIp, 1);
@@ -2232,19 +2501,13 @@ 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);
CVehicle* car = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
script_assert(car);
-#if defined MISSION_REPLAY && defined SIMPLIER_MISSIONS
- car->AutoPilot.m_nCruiseSpeed = *(float*)&ScriptParams[1];
- if (missionRetryScriptIndex == 40 && car->GetModelIndex() == MI_CHEETAH) // Turismo
- car->AutoPilot.m_nCruiseSpeed = 8 * car->AutoPilot.m_nCruiseSpeed / 10;
- car->AutoPilot.m_nCruiseSpeed = Min(car->AutoPilot.m_nCruiseSpeed, 60.0f * car->pHandling->Transmission.fMaxCruiseVelocity);
-#else
car->AutoPilot.m_nCruiseSpeed = Min(*(float*)&ScriptParams[1], 60.0f * car->pHandling->Transmission.fMaxCruiseVelocity);
-#endif
return 0;
}
case COMMAND_SET_CAR_DRIVING_STYLE:
@@ -2311,40 +2574,42 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
return 0;
case COMMAND_PRINT_BIG:
{
- wchar* key = TheText.Get((char*)&CTheScripts::ScriptSpace[m_nIp]);
+ wchar* key = CTheScripts::GetTextByKeyFromScript(&m_nIp);
#ifdef MISSION_REPLAY
- if (strcmp((char*)&CTheScripts::ScriptSpace[m_nIp], "M_FAIL") == 0 && CanAllowMissionReplay())
- AllowMissionReplay = MISSION_RETRY_STAGE_WAIT_FOR_SCRIPT_TO_TERMINATE;
+ if (strcmp((char*)&CTheScripts::ScriptSpace[m_nIp - KEY_LENGTH_IN_SCRIPT], "M_FAIL") == 0) {
+ if (AllowMissionReplay == MISSION_RETRY_STAGE_WAIT_FOR_TIMER_AFTER_RESTART)
+ AllowMissionReplay = MISSION_RETRY_STAGE_NORMAL;
+ if (CanAllowMissionReplay())
+ AllowMissionReplay = MISSION_RETRY_STAGE_WAIT_FOR_SCRIPT_TO_TERMINATE;
+ }
#endif
- m_nIp += KEY_LENGTH_IN_SCRIPT;
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;
}
+ */
case COMMAND_CLEAR_PRINTS:
CMessages::ClearMessages();
return 0;
@@ -2377,15 +2642,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:
script_assert(0);
break;
@@ -2438,8 +2703,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;
}
@@ -2582,29 +2845,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);
@@ -2612,6 +2869,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:
@@ -2678,6 +2936,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);
@@ -2702,6 +2963,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);
@@ -2744,12 +3007,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);
@@ -2758,10 +3023,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);
@@ -2770,14 +3033,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:
@@ -2788,9 +3051,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);
@@ -2800,23 +3061,21 @@ 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);
CPlayerInfo* pPlayer = &CWorld::Players[ScriptParams[0]];
char label[12];
CTheScripts::ReadTextLabelFromScript(&m_nIp, label);
- int zoneToCheck = CTheZones::FindZoneByLabelAndReturnIndex(label);
+ int zoneToCheck = CTheZones::FindZoneByLabelAndReturnIndex(label, ZONE_DEFAULT);
if (zoneToCheck != -1)
m_nIp += KEY_LENGTH_IN_SCRIPT; /* why only if zone != -1? */
CVector pos = pPlayer->GetPos();
- CZone* pZone = CTheZones::GetZone(zoneToCheck);
+ CZone* pZone = CTheZones::GetNavigationZone(zoneToCheck);
UpdateCompareFlag(CTheZones::PointLiesWithinZone(&pos, pZone));
return 0;
}
@@ -2824,8 +3083,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:
{
@@ -2835,10 +3092,14 @@ 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:
- */
+#ifdef SUPPORT_GINPUT_SCRIPT
+ case COMMAND_HAS_PAD_IN_HANDS:
+ UpdateCompareFlag(CPad::GetPad(0)->IsAffectedByController);
+ return 0;
+#else
+ //case COMMAND_ORDER_CHAR_TO_BACKDOOR:
+#endif
+ //case COMMAND_ADD_CHAR_TO_GANG:
case COMMAND_IS_CHAR_OBJECTIVE_PASSED:
{
CollectParameters(&m_nIp, 1);
@@ -2894,6 +3155,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);
@@ -2909,13 +3173,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_STD_CAR_SIT_LO : ANIM_STD_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);
@@ -2944,18 +3202,18 @@ int8 CRunningScript::ProcessCommands200To299(int32 command)
pPlayer->m_pPed->m_pMyVehicle->RemovePassenger(pPlayer->m_pPed);
}
}
+ pPlayer->m_pPed->RemoveInCarAnims();
pPlayer->m_pPed->bInVehicle = false;
pPlayer->m_pPed->m_pMyVehicle = nil;
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->RemoveInCarAnims();
+ pPlayer->m_pPed->ReplaceWeaponWhenExitingVehicle();
if (pPlayer->m_pPed->m_pVehicleAnim)
pPlayer->m_pPed->m_pVehicleAnim->blendDelta = -1000.0f;
pPlayer->m_pPed->m_pVehicleAnim = nil;
pPlayer->m_pPed->SetMoveState(PEDMOVE_NONE);
- CAnimManager::BlendAnimation(pPlayer->m_pPed->GetClump(), pPlayer->m_pPed->m_animGroup, ANIM_STD_IDLE, 100.0f);
+ CAnimManager::BlendAnimation(pPlayer->m_pPed->GetClump(), pPlayer->m_pPed->m_animGroup, ANIM_STD_IDLE, 1000.0f);
pPlayer->m_pPed->RestartNonPartialAnims();
AudioManager.PlayerJustLeftCar();
pos.z += pPlayer->m_pPed->GetDistanceFromCentreOfMassToBaseOfModel();
@@ -2963,9 +3221,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:
script_assert(0);
break;
@@ -2979,21 +3235,15 @@ bool CRunningScript::CanAllowMissionReplay()
{
if (AllowMissionReplay != MISSION_RETRY_STAGE_NORMAL)
return false;
- if (CStats::LastMissionPassedName[0] == '\0')
- return false;
- for (int i = 0; i < ARRAY_SIZE(nonMissionScripts); i++) {
- if (strcmp(m_abScriptName, nonMissionScripts[i]) == 0)
- return false;
+ for (int i = 0; i < ARRAY_SIZE(MissionScripts); i++) {
+ if (!CGeneral::faststricmp(m_abScriptName, MissionScripts[i]))
+ return true;
}
- return true;
+ return false;
}
uint32 AddExtraDeathDelay()
{
- if (missionRetryScriptIndex == 63)
- return 7000;
- if (missionRetryScriptIndex == 64)
- return 4000;
return 1000;
}
@@ -3002,6 +3252,7 @@ void RetryMission(int type, int unk)
if (type == MISSION_RETRY_TYPE_SUGGEST_TO_PLAYER) {
doingMissionRetry = true;
FrontEndMenuManager.m_nCurrScreen = MENUPAGE_MISSION_RETRY;
+ FrontEndMenuManager.m_bAttemptingMissionRetry = true;
FrontEndMenuManager.RequestFrontEndStartUp();
}
else if (type == MISSION_RETRY_TYPE_BEGIN_RESTARTING) {
diff --git a/src/control/Script.h b/src/control/Script.h
index eedf17d4..7f9a7717 100644
--- a/src/control/Script.h
+++ b/src/control/Script.h
@@ -6,6 +6,7 @@
class CEntity;
class CBuilding;
+class CPhysical;
class CVehicle;
class CPed;
class CObject;
@@ -20,18 +21,19 @@ void FlushLog();
#define PICKUP_PLACEMENT_OFFSET (0.5f)
#define PED_FIND_Z_OFFSET (5.0f)
+#define COP_PED_FIND_Z_OFFSET (10.0f)
#define UPSIDEDOWN_UP_THRESHOLD (-0.97f)
#define UPSIDEDOWN_MOVE_SPEED_THRESHOLD (0.01f)
#define UPSIDEDOWN_TURN_SPEED_THRESHOLD (0.02f)
#define UPSIDEDOWN_TIMER_THRESHOLD (1000)
-#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 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
#ifdef USE_PRECISE_MEASUREMENT_CONVERTION
#define MILES_IN_METER (0.000621371192f)
@@ -45,9 +47,7 @@ void FlushLog();
#define KEY_LENGTH_IN_SCRIPT (8)
-#if GTA_VERSION <= GTA3_PS2_160
-#define GTA_SCRIPT_COLLECTIVE
-#endif
+//#define GTA_SCRIPT_COLLECTIVE
struct intro_script_rectangle
{
@@ -64,7 +64,7 @@ struct intro_script_rectangle
VALIDATE_SIZE(intro_script_rectangle, 0x18);
enum {
- SCRIPT_TEXT_MAX_LENGTH = 500
+ SCRIPT_TEXT_MAX_LENGTH = 100
};
struct intro_text_line
@@ -105,7 +105,7 @@ struct intro_text_line
m_sBackgroundColor = CRGBA(128, 128, 128, 128);
m_bTextProportional = true;
m_bTextBeforeFade = false;
- m_nFont = FONT_HEADING;
+ m_nFont = FONT_STANDARD;
m_fAtX = 0.0f;
m_fAtY = 0.0f;
memset(&m_Text, 0, sizeof(m_Text));
@@ -149,7 +149,7 @@ struct cleanup_entity_struct
enum {
MAX_CLEANUP = 50,
MAX_UPSIDEDOWN_CAR_CHECKS = 6,
- MAX_STUCK_CAR_CHECKS = 6
+ MAX_STUCK_CAR_CHECKS = 16
};
class CMissionCleanup
@@ -165,6 +165,7 @@ public:
void AddEntityToList(int32, uint8);
void RemoveEntityFromList(int32, uint8);
void Process();
+ void CheckIfCollisionHasLoadedForMissionObjects();
};
struct upsidedown_car_data
@@ -248,11 +249,7 @@ struct tBuildingSwap
enum {
-#if GTA_VERSION > GTA3_PS2_160
MAX_STACK_DEPTH = 6,
-#else
- MAX_STACK_DEPTH = 4,
-#endif
NUM_LOCAL_VARS = 16,
NUM_TIMERS = 2
};
@@ -287,6 +284,7 @@ public:
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;
@@ -338,9 +336,11 @@ public:
int8 ProcessCommands800To899(int32);
int8 ProcessCommands900To999(int32);
int8 ProcessCommands1000To1099(int32);
-#if GTA_VERSION > GTA3_PS2_160
int8 ProcessCommands1100To1199(int32);
-#endif
+ int8 ProcessCommands1200To1299(int32);
+ int8 ProcessCommands1300To1399(int32);
+ int8 ProcessCommands1400To1499(int32);
+
void LocatePlayerCommand(int32, uint32*);
void LocatePlayerCharCommand(int32, uint32*);
void LocatePlayerCarCommand(int32, uint32*);
@@ -354,6 +354,8 @@ public:
void PlayerInAngledAreaCheckCommand(int32, uint32*);
void CharInAreaCheckCommand(int32, uint32*);
void CarInAreaCheckCommand(int32, uint32*);
+ void LocateObjectCommand(int32, uint32*);
+ void ObjectInAreaCheckCommand(int32, uint32*);
#ifdef GTA_SCRIPT_COLLECTIVE
void LocateCollectiveCommand(int32, uint32*);
@@ -381,26 +383,11 @@ public:
float LimitAngleOnCircle(float angle) { return angle < 0.0f ? angle + 360.0f : angle; }
- bool ThisIsAValidRandomPed(uint32 pedtype) {
- switch (pedtype) {
- case PEDTYPE_CIVMALE:
- case PEDTYPE_CIVFEMALE:
- case PEDTYPE_GANG1:
- case PEDTYPE_GANG2:
- case PEDTYPE_GANG3:
- case PEDTYPE_GANG4:
- case PEDTYPE_GANG5:
- case PEDTYPE_GANG6:
- case PEDTYPE_GANG7:
- case PEDTYPE_GANG8:
- case PEDTYPE_GANG9:
- case PEDTYPE_CRIMINAL:
- case PEDTYPE_PROSTITUTE:
- return true;
- default:
- return false;
- }
- }
+ bool ThisIsAValidRandomCop(uint32 mi, int cop, int swat, int fbi, int army, int miami);
+ bool ThisIsAValidRandomPed(uint32 pedtype, int civ, int gang, int criminal);
+
+ bool CheckDamagedWeaponType(int32 actual, int32 type);
+
};
@@ -410,20 +397,22 @@ enum {
};
enum {
- SIZE_MAIN_SCRIPT = 128 * 1024,
- SIZE_MISSION_SCRIPT = 32 * 1024,
+#ifdef PS2
+ SIZE_MAIN_SCRIPT = 205512,
+#else
+ SIZE_MAIN_SCRIPT = 225512,
+#endif
+ 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_TEXT_LINES = 48,
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,
@@ -435,13 +424,10 @@ class CTheScripts
public:
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];
@@ -465,14 +451,26 @@ public:
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 uint32 LastMissionPassedTime;
+ static uint16 NumberOfExclusiveMissionScripts;
+#if (defined GTA_PC && !defined GTAVC_JP_PATCH || defined GTA_XBOX || defined SUPPORT_XBOX_SCRIPT || defined GTA_MOBILE || defined SUPPORT_MOBILE_SCRIPT)
+#define CARDS_IN_SUIT (13)
+#define NUM_SUITS (4)
+#define MAX_DECKS (6)
+#define CARDS_IN_DECK (CARDS_IN_SUIT * NUM_SUITS)
+#define CARDS_IN_STACK (CARDS_IN_DECK * MAX_DECKS)
+ static int16 CardStack[CARDS_IN_STACK];
+ static int16 CardStackPosition;
+#endif
+ static bool bPlayerIsInTheStatium;
+ static uint8 RiotIntensity;
+ static bool bPlayerHasMetDebbieHarry;
static void Init();
static void Process();
@@ -495,9 +493,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;
@@ -559,6 +554,14 @@ public:
static int32 AddScriptSphere(int32 id, CVector pos, float radius);
static int32 GetNewUniqueScriptSphereIndex(int32 index);
static void RemoveScriptSphere(int32 index);
+ static void RemoveScriptTextureDictionary();
+public:
+ static void RemoveThisPed(CPed* pPed);
+
+ static uint32& GetLastMissionPassedTime() { return LastMissionPassedTime; }
+#ifdef MISSION_SWITCHER
+ static void SwitchToMission(int32 mission);
+#endif
#ifdef GTA_SCRIPT_COLLECTIVE
static void AdvanceCollectiveIndex()
@@ -579,9 +582,11 @@ public:
static void SetObjectiveForAllPedsInCollective(int, eObjective);
#endif
-#ifdef MISSION_SWITCHER
-public:
- static void SwitchToMission(int32 mission);
+#ifdef USE_MISSION_REPLAY_OVERRIDE_FOR_NON_MOBILE_SCRIPT
+ static bool MissionSupportsMissionReplay(int index)
+ {
+ return index >= 3 && index <= 35 || index >= 51 && index <= 65 || index >= 67 && index <= 74 || index >= 83 && index <= 87;
+ }
#endif
#ifdef USE_DEBUG_SCRIPT_LOADER
@@ -603,6 +608,14 @@ extern uint32 WaitForSave;
extern uint32 MissionStartTime;
extern int missionRetryScriptIndex;
extern bool doingMissionRetry;
+extern bool gbTryingPorn4Again;
+extern int IsInAmmunation;
+extern int MissionSkipLevel;
+
+#ifdef USE_MISSION_REPLAY_OVERRIDE_FOR_NON_MOBILE_SCRIPT
+extern bool UsingMobileScript;
+extern bool AlreadySavedGame;
+#endif
uint32 AddExtraDeathDelay();
void RetryMission(int, int unk = 0);
diff --git a/src/control/Script2.cpp b/src/control/Script2.cpp
index d3ab2af7..4e7a1c3e 100644
--- a/src/control/Script2.cpp
+++ b/src/control/Script2.cpp
@@ -31,22 +31,21 @@
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);
@@ -62,6 +61,7 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
*(float*)&ScriptParams[2],
*(float*)&ScriptParams[3]);
return 0;
+ */
case COMMAND_IS_CAR_MODEL:
{
CollectParameters(&m_nIp, 2);
@@ -70,11 +70,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);
@@ -111,35 +110,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);
@@ -154,6 +157,7 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
}
return 0;
}
+ /*
case COMMAND_ADD_PAGER_MESSAGE:
{
wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
@@ -161,11 +165,14 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
CUserDisplay::Pager.AddMessage(text, ScriptParams[0], ScriptParams[1], ScriptParams[2]);
return 0;
}
+ */
case COMMAND_DISPLAY_ONSCREEN_TIMER:
{
script_assert(CTheScripts::ScriptSpace[m_nIp] == ARGUMENT_GLOBALVAR);
m_nIp++;
- CUserDisplay::OnscnTimer.AddClock((uint16)CTheScripts::Read2BytesFromScript(&m_nIp), nil);
+ uint16 offset = CTheScripts::Read2BytesFromScript(&m_nIp);
+ CollectParameters(&m_nIp, 1);
+ CUserDisplay::OnscnTimer.AddClock(offset, nil, ScriptParams[0] != 0);
return 0;
}
case COMMAND_CLEAR_ONSCREEN_TIMER:
@@ -179,9 +186,9 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
{
script_assert(CTheScripts::ScriptSpace[m_nIp] == ARGUMENT_GLOBALVAR);
m_nIp++;
- uint16 counter = CTheScripts::Read2BytesFromScript(&m_nIp);
+ int16 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:
@@ -194,23 +201,30 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
case COMMAND_SET_ZONE_CAR_INFO:
{
char label[12];
+ int16 gangDensities[NUM_GANGS] = { 0 };
+ int i;
+
CTheScripts::ReadTextLabelFromScript(&m_nIp, label);
m_nIp += KEY_LENGTH_IN_SCRIPT;
- CollectParameters(&m_nIp, 16);
- int zone = CTheZones::FindZoneByLabelAndReturnIndex(label);
+ CollectParameters(&m_nIp, 12);
+ for (i = 0; i < NUM_GANGS; i++)
+ gangDensities[i] = ScriptParams[i + 2];
+ int zone = CTheZones::FindZoneByLabelAndReturnIndex(label, ZONE_INFO);
+ for (int i = 0; i < NUM_GANGS; i++) {
+ if (gangDensities[i] != 0 && CGangs::GetGangInfo(i)->m_nVehicleMI == -1)
+ debug("SET_ZONE_CAR_INFO - Gang %d car ratio should be 0 in %s zone\n", i + 1, label);
+ }
if (zone < 0) {
debug("Couldn't find zone - %s\n", label);
return 0;
}
- CTheZones::SetZoneCarInfo(zone, ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3],
- ScriptParams[4], ScriptParams[5], ScriptParams[6], ScriptParams[7], ScriptParams[8], 0, 0,
- ScriptParams[9], ScriptParams[10], ScriptParams[11], ScriptParams[12],
- ScriptParams[13], ScriptParams[14], ScriptParams[15]);
+ while (zone >= 0) {
+ CTheZones::SetZoneCarInfo(zone, ScriptParams[0], ScriptParams[1], ScriptParams[11], gangDensities);
+ zone = CTheZones::FindNextZoneByLabelAndReturnIndex(label, ZONE_INFO);
+ }
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);
@@ -218,41 +232,15 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
script_assert(pPed);
char label[12];
CTheScripts::ReadTextLabelFromScript(&m_nIp, label);
- int zone = CTheZones::FindZoneByLabelAndReturnIndex(label);
+ int zone = CTheZones::FindZoneByLabelAndReturnIndex(label, ZONE_DEFAULT);
if (zone != -1)
m_nIp += KEY_LENGTH_IN_SCRIPT;
CVector pos = pPed->bInVehicle ? pPed->m_pMyVehicle->GetPosition() : pPed->GetPosition();
- UpdateCompareFlag(CTheZones::PointLiesWithinZone(&pos, CTheZones::GetZone(zone)));
- return 0;
- }
- case COMMAND_SET_CAR_DENSITY:
- {
- char label[12];
- CTheScripts::ReadTextLabelFromScript(&m_nIp, label);
- int16 zone = CTheZones::FindZoneByLabelAndReturnIndex(label);
- m_nIp += 8;
- CollectParameters(&m_nIp, 2);
- if (zone < 0) {
- debug("Couldn't find zone - %s\n", label);
- return 0;
- }
- CTheZones::SetCarDensity(zone, ScriptParams[0], ScriptParams[1]);
- return 0;
- }
- case COMMAND_SET_PED_DENSITY:
- {
- char label[12];
- CTheScripts::ReadTextLabelFromScript(&m_nIp, label);
- int16 zone = CTheZones::FindZoneByLabelAndReturnIndex(label);
- m_nIp += KEY_LENGTH_IN_SCRIPT;
- CollectParameters(&m_nIp, 2);
- if (zone < 0) {
- debug("Couldn't find zone - %s\n", label);
- return 0;
- }
- CTheZones::SetPedDensity(zone, ScriptParams[0], ScriptParams[1]);
+ UpdateCompareFlag(CTheZones::PointLiesWithinZone(&pos, CTheZones::GetNavigationZone(zone)));
return 0;
}
+ //case COMMAND_SET_CAR_DENSITY:
+ //case COMMAND_SET_PED_DENSITY:
case COMMAND_POINT_CAMERA_AT_PLAYER:
{
CollectParameters(&m_nIp, 3);
@@ -264,43 +252,49 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
{
CollectParameters(&m_nIp, 3);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_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]);
- script_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];
CTheScripts::ReadTextLabelFromScript(&m_nIp, label);
m_nIp += KEY_LENGTH_IN_SCRIPT;
- CollectParameters(&m_nIp, 10);
- int16 zone = CTheZones::FindZoneByLabelAndReturnIndex(label);
+ CollectParameters(&m_nIp, 12);
+ int16 zone = CTheZones::FindZoneByLabelAndReturnIndex(label, ZONE_INFO);
if (zone < 0) {
debug("Couldn't find zone - %s\n", label);
return 0;
}
- CTheZones::SetZonePedInfo(zone, ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3],
- ScriptParams[4], ScriptParams[5], ScriptParams[6], ScriptParams[7], ScriptParams[8], 0, 0, ScriptParams[9]);
+ while (zone >= 0) {
+ CTheZones::SetZonePedInfo(zone, ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3],
+ ScriptParams[4], ScriptParams[5], ScriptParams[6], ScriptParams[7], ScriptParams[8], ScriptParams[9], ScriptParams[10], ScriptParams[11]);
+ zone = CTheZones::FindNextZoneByLabelAndReturnIndex(label, ZONE_INFO);
+ }
return 0;
}
case COMMAND_SET_TIME_SCALE:
CollectParameters(&m_nIp, 1);
CTimer::SetTimeScale(*(float*)&ScriptParams[0]);
return 0;
+ /*
case COMMAND_IS_CAR_IN_AIR:
{
CollectParameters(&m_nIp, 1);
@@ -310,6 +304,7 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
UpdateCompareFlag(pCar->GetAllWheelsOffGround());
return 0;
}
+ */
case COMMAND_SET_FIXED_CAMERA_POSITION:
{
CollectParameters(&m_nIp, 6);
@@ -332,7 +327,6 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
CollectParameters(&m_nIp, 3);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
script_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);
@@ -343,23 +337,23 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
CollectParameters(&m_nIp, 3);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
script_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]);
script_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]);
@@ -378,7 +372,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);
@@ -429,6 +422,7 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
CRestart::OverrideNextRestart(pos, angle);
return 0;
}
+ /*
case COMMAND_DRAW_SHADOW:
{
CollectParameters(&m_nIp, 10);
@@ -447,17 +441,22 @@ 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);
CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
float angle = pPed->bInVehicle ? pPed->m_pMyVehicle->GetForward().Heading() : pPed->GetForward().Heading();
- *(float*)&ScriptParams[0] = CGeneral::LimitAngle(RADTODEG(angle));
+ angle = RADTODEG(angle);
+ if (angle < 0.0f)
+ angle += 360.0f;
+ if (angle > 360.0f)
+ angle -= 360.0f;
+ *(float*)&ScriptParams[0] = angle;
StoreParameters(&m_nIp, 1);
return 0;
}
@@ -465,10 +464,9 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- if (pPed->bInVehicle){
- // Is script_assertion required?
+ script_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;
@@ -479,7 +477,12 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
script_assert(pPed);
float angle = pPed->bInVehicle ? pPed->m_pMyVehicle->GetForward().Heading() : pPed->GetForward().Heading();
- *(float*)&ScriptParams[0] = CGeneral::LimitAngle(RADTODEG(angle));
+ angle = RADTODEG(angle);
+ if (angle < 0.0f)
+ angle += 360.0f;
+ if (angle > 360.0f)
+ angle -= 360.0f;
+ *(float*)&ScriptParams[0] = angle;
StoreParameters(&m_nIp, 1);
return 0;
}
@@ -488,10 +491,8 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
CollectParameters(&m_nIp, 2);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
script_assert(pPed);
- if (pPed->bInVehicle) {
- // Is script_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;
@@ -502,7 +503,12 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
script_assert(pVehicle);
float angle = pVehicle->GetForward().Heading();
- *(float*)&ScriptParams[0] = CGeneral::LimitAngle(RADTODEG(angle));
+ angle = RADTODEG(angle);
+ if (angle < 0.0f)
+ angle += 360.0f;
+ if (angle > 360.0f)
+ angle -= 360.0f;
+ *(float*)&ScriptParams[0] = angle;
StoreParameters(&m_nIp, 1);
return 0;
}
@@ -520,7 +526,12 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
script_assert(pObject);
float angle = pObject->GetForward().Heading();
- *(float*)&ScriptParams[0] = CGeneral::LimitAngle(RADTODEG(angle));
+ angle = RADTODEG(angle);
+ if (angle < 0.0f)
+ angle += 360.0f;
+ if (angle > 360.0f)
+ angle -= 360.0f;
+ *(float*)&ScriptParams[0] = angle;
StoreParameters(&m_nIp, 1);
return 0;
}
@@ -536,6 +547,7 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
CWorld::Add(pObject);
return 0;
}
+ /*
case COMMAND_IS_PLAYER_TOUCHING_OBJECT:
{
CollectParameters(&m_nIp, 2);
@@ -557,12 +569,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);
@@ -570,23 +584,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 = (uint16)CTheScripts::Read2BytesFromScript(&++m_nIp);
return 0;
case COMMAND_DECLARE_MISSION_FLAG_FOR_CONTACT:
- CollectParameters(&m_nIp, 1);
- CTheScripts::OnAMissionForContactFlag[ScriptParams[0]] = (uint16)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);
@@ -615,7 +623,6 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
CollectParameters(&m_nIp, 1);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
script_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);
@@ -628,7 +635,6 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
CollectParameters(&m_nIp, 1);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
script_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);
@@ -641,7 +647,6 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
CollectParameters(&m_nIp, 1);
CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
script_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);
@@ -655,7 +660,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_CONTACT_POINT, pos, 2, BLIP_DISPLAY_BOTH);
CRadar::ChangeBlipScale(handle, 3);
@@ -669,7 +673,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);
@@ -685,12 +688,6 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
{
CollectParameters(&m_nIp, 4);
switch (ScriptParams[3]) {
- case SCRIPT_SOUND_EVIDENCE_PICKUP:
- DMAudio.PlayFrontEndSound(SOUND_EVIDENCE_PICKUP, 0);
- return 0;
- case SCRIPT_SOUND_UNLOAD_GOLD:
- DMAudio.PlayFrontEndSound(SOUND_UNLOAD_GOLD, 0);
- return 0;
case SCRIPT_SOUND_PART_MISSION_COMPLETE:
DMAudio.PlayFrontEndSound(SOUND_PART_MISSION_COMPLETE, 0);
return 0;
@@ -706,14 +703,20 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
case SCRIPT_SOUND_RACE_START_GO:
DMAudio.PlayFrontEndSound(SOUND_RACE_START_GO, 0);
return 0;
+ case SCRIPT_SOUND_AMMUNATION_BUY_WEAPON:
+ DMAudio.PlayFrontEndSound(SOUND_PICKUP_WEAPON_BOUGHT, 0);
+ return 0;
+ case SCRIPT_SOUND_AMMUNATION_BUY_WEAPON_DENIED:
+ DMAudio.PlayFrontEndSound(SOUND_GARAGE_NO_MONEY, 0);
+ return 0;
+ case SCRIPT_SOUND_IMRAN_ARM_BOMB:
+ DMAudio.PlayFrontEndSound(SOUND_AMMUNATION_IMRAN_ARM_BOMB, 0);
+ return 0;
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];
@@ -724,11 +727,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;
}
@@ -773,7 +780,6 @@ int8 CRunningScript::ProcessCommands400To499(int32 command)
{
CollectParameters(&m_nIp, 1);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
CTheScripts::UpsideDownCars.RemoveCarFromCheck(ScriptParams[0]);
return 0;
}
@@ -807,6 +813,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);
@@ -842,6 +849,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:
@@ -890,31 +898,21 @@ int8 CRunningScript::ProcessCommands400To499(int32 command)
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
script_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_STD_IDLE, 1000.0f);
- }
}
return 0;
}
@@ -933,7 +931,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command)
{
CollectParameters(&m_nIp, 2);
CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- for (int i = 0; i < WEAPONTYPE_TOTAL_INVENTORY_WEAPONS; i++){
+ for (int i = 0; i < TOTAL_WEAPON_SLOTS; i++){
if (pPed->m_weapons[i].m_eWeaponType == ScriptParams[1])
pPed->m_nSelectedWepSlot = i;
}
@@ -943,13 +941,12 @@ int8 CRunningScript::ProcessCommands400To499(int32 command)
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- for (int i = 0; i < WEAPONTYPE_TOTAL_INVENTORY_WEAPONS; i++) {
+ for (int i = 0; i < TOTAL_WEAPON_SLOTS; i++) {
if (pPed->m_weapons[i].m_eWeaponType == ScriptParams[1])
pPed->SetCurrentWeapon(i);
}
return 0;
}
- /* Not implemented */
//case COMMAND_SET_CURRENT_CAR_WEAPON:
case COMMAND_GET_OBJECT_COORDINATES:
{
@@ -1139,10 +1136,13 @@ 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++;
+ CWorld::Add(pPed);
if (ScriptParams[3] >= 0)
pVehicle->AddPassenger(pPed, ScriptParams[3]);
else
@@ -1151,17 +1151,9 @@ int8 CRunningScript::ProcessCommands400To499(int32 command)
pPed->m_pMyVehicle->RegisterReference((CEntity**)&pPed->m_pMyVehicle);
pPed->bInVehicle = true;
pPed->SetPedState(PED_DRIVING);
- pVehicle->SetStatus(STATUS_PHYSICS);
pPed->bUsesCollision = false;
-#ifdef FIX_BUGS
- AnimationId anim = pVehicle->GetDriverAnim();
-#else
- AnimationId anim = pVehicle->bLowVehicle ? ANIM_STD_CAR_SIT_LO : ANIM_STD_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);
StoreParameters(&m_nIp, 1);
if (m_bIsMissionScript)
@@ -1208,6 +1200,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);
@@ -1218,6 +1211,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);
@@ -1298,11 +1292,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]);
+ script_assert(pPed);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[1]);
+ pPed->bScriptObjectiveCompleted = false;
+ pPed->SetObjective(OBJECTIVE_DESTROY_OBJECT, pObject);
+ return 0;
+ }
case COMMAND_SET_CHAR_OBJ_DESTROY_CAR:
{
CollectParameters(&m_nIp, 2);
@@ -1313,6 +1314,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);
@@ -1339,11 +1341,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);
@@ -1406,9 +1407,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);
@@ -1486,7 +1485,16 @@ int8 CRunningScript::ProcessCommands400To499(int32 command)
CollectParameters(&m_nIp, 2);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
script_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:
@@ -1497,6 +1505,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command)
pPed->m_fearFlags = 0;
return 0;
}
+ /*
case COMMAND_ACTIVATE_CRANE:
{
CollectParameters(&m_nIp, 10);
@@ -1524,28 +1533,21 @@ 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);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
script_assert(pVehicle);
-#ifdef FIX_BUGS
- // don't wanna get stuck in unique stunt jump cam forever
- bool usj_with_dodo = strcmp(m_abScriptName, "usj") == 0 && pVehicle->GetModelIndex() == MI_DODO;
- UpdateCompareFlag(pVehicle->m_nCollisionRecords == 0 && !usj_with_dodo);
-#else
UpdateCompareFlag(pVehicle->m_nCollisionRecords == 0);
-#endif
return 0;
}
default:
diff --git a/src/control/Script3.cpp b/src/control/Script3.cpp
index ac88347b..f831645e 100644
--- a/src/control/Script3.cpp
+++ b/src/control/Script3.cpp
@@ -32,6 +32,8 @@
#include "WaterLevel.h"
#include "Weather.h"
#include "Zones.h"
+#include "GameLogic.h"
+#include "Bike.h"
#include "Wanted.h"
int8 CRunningScript::ProcessCommands500To599(int32 command)
@@ -71,6 +73,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
}
return 0;
}
+ /*
case COMMAND_ADD_PAGER_MESSAGE_WITH_NUMBER:
{
wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
@@ -79,6 +82,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);
@@ -145,7 +149,12 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
}
case COMMAND_ADD_EXPLOSION:
CollectParameters(&m_nIp, 4);
- CExplosion::AddExplosion(nil, nil, (eExplosionType)ScriptParams[3], *(CVector*)&ScriptParams[0], 0);
+#ifdef SIMPLER_MISSIONS
+ if (!CGeneral::faststricmp(m_abScriptName, "hait2"))
+ CExplosion::AddExplosion(nil, nil, (eExplosionType)ScriptParams[3], *(CVector*)&ScriptParams[0], 0, true, 11.25f);
+ else
+#endif
+ CExplosion::AddExplosion(nil, nil, (eExplosionType)ScriptParams[3], *(CVector*)&ScriptParams[0], 0, true);
return 0;
case COMMAND_IS_CAR_UPRIGHT:
@@ -223,7 +232,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:
{
@@ -263,6 +271,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);
@@ -271,56 +280,39 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
ScriptParams[0], -1, -1, -1, -1, -1);
return 0;
}
+ */
case COMMAND_SET_GARAGE:
{
- CollectParameters(&m_nIp, 7);
+ CollectParameters(&m_nIp, 9);
float infX = *(float*)&ScriptParams[0];
float infY = *(float*)&ScriptParams[1];
float infZ = *(float*)&ScriptParams[2];
- float supX = *(float*)&ScriptParams[3];
- float supY = *(float*)&ScriptParams[4];
- float supZ = *(float*)&ScriptParams[5];
- if (infX > supX) {
- infX = *(float*)&ScriptParams[3];
- supX = *(float*)&ScriptParams[0];
- }
- if (infY > supY) {
- infY = *(float*)&ScriptParams[4];
- supY = *(float*)&ScriptParams[1];
- }
- if (infZ > supZ) {
- infZ = *(float*)&ScriptParams[5];
- supZ = *(float*)&ScriptParams[2];
- }
- ScriptParams[0] = CGarages::AddOne(CVector(infX, infY, infZ), CVector(supX, supY, supZ), ScriptParams[6], 0);
+ float X2 = *(float*)&ScriptParams[3];
+ float Y2 = *(float*)&ScriptParams[4];
+ float supX = *(float*)&ScriptParams[5];
+ float supY = *(float*)&ScriptParams[6];
+ float supZ = *(float*)&ScriptParams[7];
+ ScriptParams[0] = CGarages::AddOne(infX, infY, infZ, X2, Y2, supX, supY, supZ, ScriptParams[8], 0);
StoreParameters(&m_nIp, 1);
return 0;
}
+ /*
case COMMAND_SET_GARAGE_WITH_CAR_MODEL:
{
- CollectParameters(&m_nIp, 8);
+ CollectParameters(&m_nIp, 10);
float infX = *(float*)&ScriptParams[0];
float infY = *(float*)&ScriptParams[1];
float infZ = *(float*)&ScriptParams[2];
- float supX = *(float*)&ScriptParams[3];
- float supY = *(float*)&ScriptParams[4];
- float supZ = *(float*)&ScriptParams[5];
- if (infX > supX) {
- infX = *(float*)&ScriptParams[3];
- supX = *(float*)&ScriptParams[0];
- }
- if (infY > supY) {
- infY = *(float*)&ScriptParams[4];
- supY = *(float*)&ScriptParams[1];
- }
- if (infZ > supZ) {
- infZ = *(float*)&ScriptParams[5];
- supZ = *(float*)&ScriptParams[2];
- }
- ScriptParams[0] = CGarages::AddOne(CVector(infX, infY, infZ), CVector(supX, supY, supZ), ScriptParams[6], ScriptParams[7]);
+ float X2 = *(float*)&ScriptParams[3];
+ float Y2 = *(float*)&ScriptParams[4];
+ float supX = *(float*)&ScriptParams[5];
+ float supY = *(float*)&ScriptParams[6];
+ float supZ = *(float*)&ScriptParams[7];
+ ScriptParams[0] = CGarages::AddOne(infX, infY, infZ, X2, Y2, supX, supY, supZ, ScriptParams[8], ScriptParams[9]);
StoreParameters(&m_nIp, 1);
return 0;
}
+ */
case COMMAND_SET_TARGET_CAR_FOR_MISSION_GARAGE:
{
CollectParameters(&m_nIp, 2);
@@ -339,11 +331,11 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
CollectParameters(&m_nIp, 1);
UpdateCompareFlag(CGarages::HasCarBeenDroppedOffYet(ScriptParams[0]));
return 0;
+/*
case COMMAND_SET_FREE_BOMBS:
CollectParameters(&m_nIp, 1);
CGarages::SetFreeBombs(ScriptParams[0] != 0);
return 0;
-#if GTA_VERSION <= GTA3_PS2_160
case COMMAND_SET_POWERPOINT:
{
CollectParameters(&m_nIp, 7);
@@ -377,7 +369,6 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
return 0;
}
-#endif // GTA_VERSION <= GTA3_PS2_160
case COMMAND_SET_ALL_TAXI_LIGHTS:
CollectParameters(&m_nIp, 1);
CAutomobile::SetAllTaxiLights(ScriptParams[0] != 0);
@@ -391,6 +382,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);
@@ -400,7 +392,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
CollectParameters(&m_nIp, 2);
CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
script_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:
@@ -417,7 +409,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
pPed->FlagToDestroyWhenNextProcessed();
}
else {
- pPed->SetDie(ANIM_STD_KO_FRONT, 4.0f, 0.0f);
+ pPed->SetDie();
}
return 0;
}
@@ -434,7 +426,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
CollectParameters(&m_nIp, 1);
CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
script_assert(pPed);
- ScriptParams[0] = pPed->m_fHealth; // correct cast float to int
+ ScriptParams[0] = pPed->m_fHealth;
StoreParameters(&m_nIp, 1);
return 0;
}
@@ -443,7 +435,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
CollectParameters(&m_nIp, 1);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
script_assert(pPed);
- ScriptParams[0] = pPed->m_fHealth; // correct cast float to int
+ ScriptParams[0] = pPed->m_fHealth;
StoreParameters(&m_nIp, 1);
return 0;
}
@@ -452,19 +444,21 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
CollectParameters(&m_nIp, 1);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
script_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]);
script_assert(pCar);
script_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);
@@ -578,15 +572,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]);
@@ -595,6 +593,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);
@@ -621,6 +620,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);
@@ -634,6 +634,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);
@@ -662,6 +663,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
UpdateCompareFlag(isTouching);
return 0;
}
+ */
case COMMAND_LOAD_SPECIAL_CHARACTER:
{
CollectParameters(&m_nIp, 1);
@@ -679,6 +681,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
UpdateCompareFlag(CStreaming::HasSpecialCharLoaded(ScriptParams[0] - 1));
return 0;
}
+ /*
case COMMAND_FLASH_CAR:
{
CollectParameters(&m_nIp, 2);
@@ -703,10 +706,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);
@@ -717,6 +722,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
((CAutomobile*)pVehicle)->m_pBombRigger = FindPlayerPed();
return 0;
}
+ */
case COMMAND_SET_CHAR_PERSONALITY:
{
CollectParameters(&m_nIp, 2);
@@ -737,6 +743,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);
@@ -745,6 +752,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
pPed->m_animGroup = (AssocGroupId)ScriptParams[1];
return 0;
}
+ */
case COMMAND_REQUEST_MODEL:
{
CollectParameters(&m_nIp, 1);
@@ -779,6 +787,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
StoreParameters(&m_nIp, 1);
return 0;
}
+ /*
case COMMAND_SET_REPEATED_PHONE_MESSAGE:
{
CollectParameters(&m_nIp, 1);
@@ -799,6 +808,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
UpdateCompareFlag(gPhoneInfo.HasMessageBeenDisplayed(ScriptParams[0]));
return 0;
}
+ */
case COMMAND_TURN_PHONE_OFF:
{
CollectParameters(&m_nIp, 1);
@@ -812,7 +822,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], 450.0f, ScriptParams[4], ScriptParams[5], 1, 0, 0, 0.0f);
return 0;
}
case COMMAND_DRAW_LIGHT:
@@ -824,18 +834,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);
@@ -848,6 +855,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
CWorld::Players[CWorld::PlayerInFocus].PlayerFailedCriticalMission();
return 0;
}
+ */
case COMMAND_IS_PLAYER_PLAYING:
{
CollectParameters(&m_nIp, 1);
@@ -1206,19 +1214,25 @@ int8 CRunningScript::ProcessCommands600To699(int32 command)
CollectParameters(&m_nIp, 2);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
script_assert(pVehicle);
- script_assert(pVehicle->m_vehType == VEHICLE_TYPE_CAR);
- ((CAutomobile*)pVehicle)->bFixedColour = (ScriptParams[1] == 0);
+ //assert(pVehicle->m_vehType == VEHICLE_TYPE_CAR);
+ // they DO call this for bikes, we don't really want to destroy the structure...
+#ifdef FIX_BUGS
+ if (pVehicle->m_vehType == VEHICLE_TYPE_CAR)
+#endif
+ ((CAutomobile*)pVehicle)->bFixedColour = (ScriptParams[1] == 0);
+
return 0;
}
+ /*
case COMMAND_IS_TAXI:
{
CollectParameters(&m_nIp, 1);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
script_assert(pVehicle);
- int mi = pVehicle->GetModelIndex();
- UpdateCompareFlag(mi == MI_TAXI || mi == MI_CABBIE || mi == MI_BORGNINE);
+ UpdateCompareFlag(pVehicle->IsTaxi());
return 0;
}
+ */
case COMMAND_UNLOAD_SPECIAL_CHARACTER:
CollectParameters(&m_nIp, 1);
CStreaming::SetMissionDoesntRequireSpecialChar(ScriptParams[0] - 1);
@@ -1231,6 +1245,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]);
@@ -1246,12 +1261,13 @@ int8 CRunningScript::ProcessCommands600To699(int32 command)
}
return 0;
}
+ */
case COMMAND_CREATE_OBJECT_NO_OFFSET:
{
CollectParameters(&m_nIp, 4);
int mi = ScriptParams[0] >= 0 ? ScriptParams[0] : CTheScripts::UsedObjectArray[-ScriptParams[0]].index;
CObject* pObj = new CObject(mi, false);
- pObj->ObjectCreatedBy = MISSION_OBJECT;
+; pObj->ObjectCreatedBy = MISSION_OBJECT;
CVector pos = *(CVector*)&ScriptParams[1];
if (pos.z <= MAP_Z_LOW_LIMIT)
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
@@ -1259,6 +1275,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);
@@ -1267,6 +1286,7 @@ int8 CRunningScript::ProcessCommands600To699(int32 command)
CTheScripts::MissionCleanUp.AddEntityToList(ScriptParams[0], CLEANUP_OBJECT);
return 0;
}
+ /*
case COMMAND_IS_BOAT:
{
CollectParameters(&m_nIp, 1);
@@ -1301,6 +1321,7 @@ int8 CRunningScript::ProcessCommands600To699(int32 command)
pPed->SetObjective(OBJECTIVE_GOTO_AREA_ANY_MEANS, pos, radius);
return 0;
}
+ */
#ifdef GTA_SCRIPT_COLLECTIVE
case COMMAND_SET_COLL_OBJ_GOTO_AREA_ANY_MEANS:
{
@@ -1332,7 +1353,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);
@@ -1355,6 +1378,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)
@@ -1362,6 +1386,7 @@ int8 CRunningScript::ProcessCommands600To699(int32 command)
else
TheCamera.SetWideScreenOff();
return 0;
+ /*
case COMMAND_ADD_SPRITE_BLIP_FOR_CAR:
{
CollectParameters(&m_nIp, 2);
@@ -1398,6 +1423,7 @@ int8 CRunningScript::ProcessCommands600To699(int32 command)
StoreParameters(&m_nIp, 1);
return 0;
}
+ */
case COMMAND_ADD_SPRITE_BLIP_FOR_CONTACT_POINT:
{
CollectParameters(&m_nIp, 4);
@@ -1478,6 +1504,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]);
@@ -1491,6 +1518,7 @@ int8 CRunningScript::ProcessCommands600To699(int32 command)
CollectParameters(&m_nIp, 2);
UpdateCompareFlag(CGarages::HasThisCarBeenCollected(ScriptParams[0], ScriptParams[1] - 1));
return 0;
+ */
default:
script_assert(0);
}
@@ -1500,6 +1528,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);
@@ -1512,6 +1541,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);
@@ -1525,7 +1555,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
CVector pos = *(CVector*)&ScriptParams[0];
if (pos.z <= MAP_Z_LOW_LIMIT)
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
- CPathNode* pNode = &ThePaths.m_pathNodes[ThePaths.FindNodeClosestToCoors(pos, 1, 999999.9f)];
+ CPathNode* pNode = &ThePaths.m_pathNodes[ThePaths.FindNodeClosestToCoors(pos, 1, 999999.9f, true)];
*(CVector*)&ScriptParams[0] = pNode->GetPosition();
StoreParameters(&m_nIp, 3);
return 0;
@@ -1536,8 +1566,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
CVector pos = *(CVector*)&ScriptParams[0];
if (pos.z <= MAP_Z_LOW_LIMIT)
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
- CPathNode* pNode = &ThePaths.m_pathNodes[ThePaths.FindNodeClosestToCoors(pos, 0, 999999.9f)];
- *(CVector*)&ScriptParams[0] = pNode->GetPosition();
+ *(CVector*)&ScriptParams[0] = ThePaths.FindNodeCoorsForScript(ThePaths.FindNodeClosestToCoors(pos, 0, 999999.9f, true, true));
StoreParameters(&m_nIp, 3);
return 0;
}
@@ -1556,10 +1585,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]);
@@ -1590,6 +1620,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);
@@ -1614,6 +1645,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
UpdateCompareFlag(TheCamera.IsSphereVisible(pObject->GetBoundCentre(), pObject->GetBoundRadius()));
return 0;
}
+ /*
case COMMAND_GOSUB_FILE:
{
CollectParameters(&m_nIp, 2);
@@ -1623,6 +1655,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
// ScriptParams[1] == filename
return 0;
}
+ */
case COMMAND_GET_GROUND_Z_FOR_3D_COORD:
{
CollectParameters(&m_nIp, 3);
@@ -1650,6 +1683,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);
@@ -1658,6 +1692,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
pVehicle->bComedyControls = (ScriptParams[1] != 0);
return 0;
}
+ */
case COMMAND_BOAT_GOTO_COORDS:
{
CollectParameters(&m_nIp, 4);
@@ -1672,7 +1707,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
pBoat->AutoPilot.m_vecDestinationCoors = pos;
pBoat->SetStatus(STATUS_PHYSICS);
pBoat->bEngineOn = true;
- 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;
}
@@ -1726,7 +1761,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
CollectParameters(&m_nIp, 2);
CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
script_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:
@@ -1734,9 +1769,10 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
CollectParameters(&m_nIp, 2);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
script_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;
@@ -1749,6 +1785,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
CPacManPickups::GenerateOnePMPickUp(pos);
return 0;
}
+ */
case COMMAND_SET_BOAT_CRUISE_SPEED:
{
CollectParameters(&m_nIp, 2);
@@ -1759,6 +1796,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);
@@ -1783,8 +1821,8 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
continue;
if (pPed->bFadeOut)
continue;
- if (pPed->GetModelIndex() == MI_SCUM_WOM || pPed->GetModelIndex() == MI_SCUM_MAN)
- continue;
+// if (pPed->GetModelIndex() == MI_SCUM_WOM || pPed->GetModelIndex() == MI_SCUM_MAN)
+// continue;
if (!ThisIsAValidRandomPed(pPed->m_nPedType))
continue;
if (pPed->bIsLeader || pPed->m_leader)
@@ -1807,14 +1845,16 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
StoreParameters(&m_nIp, 1);
return 0;
}
+ */
case COMMAND_GET_RANDOM_CHAR_IN_ZONE:
{
char zone[KEY_LENGTH_IN_SCRIPT];
strncpy(zone, (const char*)&CTheScripts::ScriptSpace[m_nIp], KEY_LENGTH_IN_SCRIPT);
- int nZone = CTheZones::FindZoneByLabelAndReturnIndex(zone);
+ int nZone = CTheZones::FindZoneByLabelAndReturnIndex(zone, ZONE_DEFAULT);
if (nZone != -1)
m_nIp += KEY_LENGTH_IN_SCRIPT;
- CZone* pZone = CTheZones::GetZone(nZone);
+ CZone* pZone = CTheZones::GetNavigationZone(nZone);
+ CollectParameters(&m_nIp, 3);
int ped_handle = -1;
CVector pos = FindPlayerCoors();
int i = CPools::GetPedPool()->GetSize();
@@ -1832,9 +1872,9 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
continue;
if (pPed->bFadeOut)
continue;
- if (pPed->GetModelIndex() == MI_SCUM_WOM || pPed->GetModelIndex() == MI_SCUM_MAN)
+ if (pPed->m_nWaitState != WAITSTATE_FALSE)
continue;
- if (!ThisIsAValidRandomPed(pPed->m_nPedType))
+ if (!ThisIsAValidRandomPed(pPed->m_nPedType, ScriptParams[0], ScriptParams[1], ScriptParams[2]))
continue;
if (pPed->bIsLeader || pPed->m_leader)
continue;
@@ -1844,6 +1884,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;
@@ -1964,6 +2008,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);
@@ -2034,6 +2079,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);
@@ -2053,29 +2099,8 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
m_nIp += KEY_LENGTH_IN_SCRIPT;
return 0;
}
- case COMMAND_CREATE_CUTSCENE_HEAD:
- {
- CollectParameters(&m_nIp, 2);
- CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
- script_assert(pObject);
- CCutsceneHead* pCutHead = CCutsceneMgr::AddCutsceneHead(pObject, ScriptParams[1]);
- ScriptParams[0] = CPools::GetObjectPool()->GetIndex(pCutHead);
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_SET_CUTSCENE_HEAD_ANIM:
- {
- CollectParameters(&m_nIp, 1);
- CObject* pCutHead = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
- script_assert(pCutHead);
- char name[KEY_LENGTH_IN_SCRIPT];
- strncpy(name, (const char*)&CTheScripts::ScriptSpace[m_nIp], KEY_LENGTH_IN_SCRIPT);
- m_nIp += KEY_LENGTH_IN_SCRIPT;
- CTimer::Stop();
- CCutsceneMgr::SetHeadAnim(name, pCutHead);
- CTimer::Update();
- 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]));
@@ -2108,6 +2133,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
CollectParameters(&m_nIp, 2);
CGarages::ChangeGarageType(ScriptParams[0], ScriptParams[1], 0);
return 0;
+ /*
case COMMAND_ACTIVATE_CRUSHER_CRANE:
{
CollectParameters(&m_nIp, 10);
@@ -2136,6 +2162,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);
@@ -2143,6 +2170,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);
@@ -2150,6 +2178,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);
@@ -2157,6 +2186,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);
@@ -2171,6 +2201,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);
@@ -2178,6 +2209,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);
@@ -2213,6 +2245,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);
@@ -2220,6 +2253,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);
@@ -2245,6 +2279,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];
@@ -2252,6 +2287,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);
@@ -2298,6 +2335,8 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
strncpy(CStats::LastMissionPassedName, name, KEY_LENGTH_IN_SCRIPT);
++CStats::MissionsPassed;
CStats::CheckPointReachedSuccessfully();
+ CTheScripts::LastMissionPassedTime = CTimer::GetTimeInMilliseconds();
+ CGameLogic::RemoveShortCutDropOffPointForMission();
return 0;
}
case COMMAND_SET_CHAR_RUNNING:
@@ -2311,6 +2350,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);
@@ -2327,22 +2367,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:
@@ -2352,7 +2407,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
CPed* pLeader = CPools::GetPedPool()->GetAt(ScriptParams[1]);
script_assert(pPed);
script_assert(pLeader);
- UpdateCompareFlag(pPed->m_leader == pLeader);
+ UpdateCompareFlag(pPed->m_leader == pLeader && !pPed->bWaitForLeaderToComeCloser);
return 0;
}
default:
diff --git a/src/control/Script4.cpp b/src/control/Script4.cpp
index 4e798be3..ac632b15 100644
--- a/src/control/Script4.cpp
+++ b/src/control/Script4.cpp
@@ -38,8 +38,26 @@
#include "WaterLevel.h"
#include "World.h"
#include "Zones.h"
+#include "Bike.h"
#include "Wanted.h"
+#ifdef FIX_BUGS
+static bool IsSlideObjectUsedWrongByScript(const CVector& posTarget, const CVector& slideBy)
+{
+ if (posTarget == CVector(-559.476f, 784.807f, 23.279f) && slideBy == CVector(0.0f, 10.0f, 0.0f))
+ return true; // G-Spotlight bottom elevator, east side
+ if (posTarget == CVector(-559.476f, 779.64f, 23.279f) && slideBy == CVector(0.0f, 10.0f, 0.0f))
+ return true; // G-Spotlight bottom elevator, west side
+ if (posTarget == CVector(-553.563f, 790.595f, 97.917f) && slideBy == CVector(0.0f, 10.0f, 0.0f))
+ return true; // G-Spotlight top elevator, east side
+ if (posTarget == CVector(-553.563f, 785.427f, 97.917f) && slideBy == CVector(0.0f, 10.0f, 0.0f))
+ return true; // G-Spotlight top elevator, west side
+ if (posTarget == CVector(-866.689f, -572.095f, 15.573f) && slideBy == CVector(0.0f, 0.0f, 4.5f))
+ return true; // Cherry Popper garage door
+ return false;
+}
+#endif
+
int8 CRunningScript::ProcessCommands800To899(int32 command)
{
CMatrix tmp_matrix;
@@ -51,7 +69,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
CPed* pLeader = CWorld::Players[ScriptParams[1]].m_pPed;
script_assert(pPed);
script_assert(pLeader);
- UpdateCompareFlag(pPed->m_leader == pLeader);
+ UpdateCompareFlag(pPed->m_leader == pLeader && !pPed->bWaitForLeaderToComeCloser);
return 0;
}
case COMMAND_EXPLODE_CHAR_HEAD:
@@ -59,17 +77,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
CollectParameters(&m_nIp, 1);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
script_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_STD_KO_FRONT, 4.0f, 0.0f);
- }
+ pPed->InflictDamage(nil, WEAPONTYPE_SNIPERRIFLE, 1000.0f, PEDPIECE_HEAD, 0);
return 0;
}
case COMMAND_EXPLODE_PLAYER_HEAD:
@@ -77,12 +85,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
CollectParameters(&m_nIp, 1);
CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
script_assert(pPed);
- if (CGame::nastyGame) {
- pPed->ApplyHeadShot(WEAPONTYPE_SNIPERRIFLE, pPed->GetNodePosition(PED_HEAD), true);
- }
- else {
- pPed->SetDie(ANIM_STD_KO_FRONT, 4.0f, 0.0f);
- }
+ pPed->InflictDamage(nil, WEAPONTYPE_SNIPERRIFLE, 1000.0f, PEDPIECE_HEAD, 0);
return 0;
}
case COMMAND_ANCHOR_BOAT:
@@ -99,12 +102,15 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
CTheScripts::ReadTextLabelFromScript(&m_nIp, zone);
m_nIp += KEY_LENGTH_IN_SCRIPT;
CollectParameters(&m_nIp, 2);
- int zone_id = CTheZones::FindZoneByLabelAndReturnIndex(zone);
+ int zone_id = CTheZones::FindZoneByLabelAndReturnIndex(zone, ZONE_INFO);
if (zone_id < 0) {
printf("Couldn't find zone - %s\n", zone);
return 0;
}
- CTheZones::SetPedGroup(zone_id, ScriptParams[0], ScriptParams[1]);
+ while (zone_id >= 0) {
+ CTheZones::SetPedGroup(zone_id, ScriptParams[0], ScriptParams[1]);
+ zone_id = CTheZones::FindNextZoneByLabelAndReturnIndex(zone, ZONE_INFO);
+ }
return 0;
}
case COMMAND_START_CAR_FIRE:
@@ -138,6 +144,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)
@@ -155,14 +165,15 @@ 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);
- int zone_id = CTheZones::FindZoneByLabelAndReturnIndex(zone);
+ int zone_id = CTheZones::FindZoneByLabelAndReturnIndex(zone, ZONE_DEFAULT);
if (zone_id != -1)
m_nIp += KEY_LENGTH_IN_SCRIPT;
- CZone* pZone = CTheZones::GetZone(zone_id);
+ CZone* pZone = CTheZones::GetNavigationZone(zone_id);
CollectParameters(&m_nIp, 1);
int handle = -1;
uint32 i = CPools::GetVehiclePool()->GetSize();
@@ -187,6 +198,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
StoreParameters(&m_nIp, 1);
return 0;
}
+ */
case COMMAND_HAS_RESPRAY_HAPPENED:
{
CollectParameters(&m_nIp, 1);
@@ -226,6 +238,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
CCarAI::TellCarToRamOtherCar(pVehicle, pTarget);
return 0;
}
+ /*
case COMMAND_SET_CAR_BLOCK_CAR:
{
CollectParameters(&m_nIp, 2);
@@ -245,6 +258,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
pPed->SetObjective(OBJECTIVE_CATCH_TRAIN);
return 0;
}
+ */
#ifdef GTA_SCRIPT_COLLECTIVE
case COMMAND_SET_COLL_OBJ_CATCH_TRAIN:
CollectParameters(&m_nIp, 1);
@@ -273,6 +287,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
pPed->bPedIsBleeding = (ScriptParams[1] != 0);
return 0;
}
+ /*
case COMMAND_SET_CAR_FUNNY_SUSPENSION:
{
CollectParameters(&m_nIp, 2);
@@ -291,6 +306,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);
@@ -311,6 +327,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
pPed->bIsVisible = (ScriptParams[1] != 0);
return 0;
}
+ /*
case COMMAND_SET_CAR_VISIBLE:
{
CollectParameters(&m_nIp, 2);
@@ -319,6 +336,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
pVehicle->bIsVisible = (ScriptParams[1] != 0);
return 0;
}
+ */
case COMMAND_IS_AREA_OCCUPIED:
{
CollectParameters(&m_nIp, 11);
@@ -346,6 +364,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
UpdateCompareFlag(total > 0);
return 0;
}
+ /*
case COMMAND_START_DRUG_RUN:
CPlane::CreateIncomingCesna();
return 0;
@@ -359,6 +378,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);
@@ -405,18 +425,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);
@@ -430,12 +453,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);
@@ -453,6 +478,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
case COMMAND_SUBURBAN_PASSED:
CStats::SuburbanPassed = true;
return 0;
+ */
case COMMAND_ROTATE_OBJECT:
{
CollectParameters(&m_nIp, 4);
@@ -514,10 +540,14 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
script_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];
+#ifdef FIX_BUGS
+ // the check is a hack for original script, where some objects are moved
+ // via SLIDE_OBJECT instead of SET_OBJECT_POSITION
+ // assuming the slide will take exactly one frame, which is true
+ // only without accounting time step (which is a bug)
+ if (!IsSlideObjectUsedWrongByScript(posTarget, slideBy))
+ slideBy *= CTimer::GetTimeStepFix();
#endif
if (posTarget == pos) { // using direct comparasion here is fine
UpdateCompareFlag(true);
@@ -570,28 +600,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)
@@ -606,9 +624,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);
@@ -618,13 +638,8 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
CTheScripts::ReadTextLabelFromScript(&m_nIp, name);
for (int i = 0; i < KEY_LENGTH_IN_SCRIPT; i++)
name[i] = tolower(name[i]);
- int mi = pPed->GetModelIndex();
- pPed->DeleteRwObject();
- if (pPed->IsPlayer())
- mi = 0;
- CStreaming::RequestSpecialModel(mi, name, STREAMFLAGS_DEPENDENCY | STREAMFLAGS_SCRIPTOWNED);
m_nIp += KEY_LENGTH_IN_SCRIPT;
- CWorld::Remove(pPed);
+ pPed->Undress(name);
return 0;
}
case COMMAND_DRESS_CHAR:
@@ -632,12 +647,10 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
CollectParameters(&m_nIp, 1);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
script_assert(pPed);
- int mi = pPed->GetModelIndex();
- pPed->m_modelIndex = -1;
- pPed->SetModelIndex(mi);
- CWorld::Add(pPed);
+ pPed->Dress();
return 0;
}
+ /*
case COMMAND_START_CHASE_SCENE:
CollectParameters(&m_nIp, 1);
CTimer::Suspend();
@@ -678,10 +691,10 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
CollectParameters(&m_nIp, 1);
char zone[KEY_LENGTH_IN_SCRIPT];
CTheScripts::ReadTextLabelFromScript(&m_nIp, zone);
- int zone_id = CTheZones::FindZoneByLabelAndReturnIndex(zone);
+ int zone_id = CTheZones::FindZoneByLabelAndReturnIndex(zone, ZONE_DEFAULT);
if (zone_id != -1)
m_nIp += KEY_LENGTH_IN_SCRIPT;
- CZone* pZone = CTheZones::GetZone(zone_id);
+ CZone* pZone = CTheZones::GetNavigationZone(zone_id);
UpdateCompareFlag(CExplosion::TestForExplosionInArea((eExplosionType)ScriptParams[0],
pZone->minx, pZone->maxx, pZone->miny, pZone->maxy, pZone->minz, pZone->maxz));
return 0;
@@ -709,6 +722,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
StoreParameters(&m_nIp, 1);
return 0;
}
+ */
case COMMAND_PLACE_OBJECT_RELATIVE_TO_CAR:
{
CollectParameters(&m_nIp, 5);
@@ -735,7 +749,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
CollectParameters(&m_nIp, 2);
CPlayerPed* pPlayerPed = CWorld::Players[ScriptParams[0]].m_pPed;
script_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:
@@ -761,7 +775,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]);
script_assert(pPed);
CVector pos = *(CVector*)&ScriptParams[1];
if (pos.z <= MAP_Z_LOW_LIMIT)
@@ -774,26 +788,58 @@ 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_vehDoor) {
+ if (pPed->GetPedState() == PED_EXIT_CAR || pPed->GetPedState() == PED_DRAG_FROM_CAR) {
+ uint8 flags = 0;
+ if (pPed->m_pMyVehicle->IsBike()) {
+ if (pPed->m_vehDoor == CAR_DOOR_LF ||
+ pPed->m_vehDoor == CAR_DOOR_RF ||
+ pPed->m_vehDoor == CAR_WINDSCREEN)
+ flags = CAR_DOOR_FLAG_LF | CAR_DOOR_FLAG_RF;
+ else if (pPed->m_vehDoor == CAR_DOOR_LR ||
+ pPed->m_vehDoor == CAR_DOOR_RR)
+ flags = CAR_DOOR_FLAG_LR | CAR_DOOR_FLAG_RR;
+ }
+ else {
+ switch (pPed->m_vehDoor) {
+ case CAR_DOOR_LF:
+ flags = pPed->m_pMyVehicle->m_nNumMaxPassengers != 0 ? CAR_DOOR_FLAG_LF : CAR_DOOR_FLAG_LF | CAR_DOOR_FLAG_LR;
+ break;
+ case CAR_DOOR_LR:
+ flags = pPed->m_pMyVehicle->m_nNumMaxPassengers != 0 ? CAR_DOOR_FLAG_RF : CAR_DOOR_FLAG_LF | CAR_DOOR_FLAG_LR;
+ break;
+ case CAR_DOOR_RF:
+ flags = CAR_DOOR_FLAG_RF;
+ break;
+ case CAR_DOOR_RR:
+ flags = CAR_DOOR_FLAG_RR;
+ break;
+ }
+ }
+ pPed->m_pMyVehicle->m_nGettingOutFlags &= ~flags;
+ pPed->m_pMyVehicle->ProcessOpenDoor(pPed->m_vehDoor, ANIM_STD_NUM, 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_STD_IDLE, 100.0f);
+ CAnimManager::BlendAnimation(pPed->GetClump(), pPed->m_animGroup, ANIM_STD_IDLE, 1000.0f);
pos.z += pPed->GetDistanceFromCentreOfMassToBaseOfModel();
pPed->Teleport(pos);
CTheScripts::ClearSpaceForMissionEntity(pos, pPed);
@@ -813,7 +859,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
if (total == 0)
CWorld::FindObjectsOfTypeInRangeSectorList(mi, CWorld::GetBigBuildingList(LEVEL_GENERIC), pos, range, true, &total, 16, apEntities);
if (total == 0)
- CWorld::FindObjectsOfTypeInRangeSectorList(mi, CWorld::GetBigBuildingList(CTheZones::FindZoneForPoint(pos)), pos, range, true, &total, 16, apEntities);
+ CWorld::FindObjectsOfTypeInRangeSectorList(mi, CWorld::GetBigBuildingList(CTheZones::GetLevelFromPosition(&pos)), pos, range, true, &total, 16, apEntities);
CEntity* pClosestEntity = nil;
float min_dist = 2.0f * range;
for (int i = 0; i < total; i++) {
@@ -829,6 +875,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
}
return 0;
}
+ /*
case COMMAND_HAS_CHAR_SPOTTED_CHAR:
{
CollectParameters(&m_nIp, 2);
@@ -839,6 +886,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
UpdateCompareFlag(pPed->OurPedCanSeeThisOne(pTarget));
return 0;
}
+ */
case COMMAND_SET_CHAR_OBJ_HAIL_TAXI:
{
CollectParameters(&m_nIp, 1);
@@ -856,6 +904,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);
@@ -886,6 +935,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
*(float*)&ScriptParams[0], *(float*)&ScriptParams[1]);
return 0;
}
+ */
case COMMAND_WARP_PLAYER_INTO_CAR:
{
CollectParameters(&m_nIp, 2);
@@ -917,6 +967,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);
@@ -945,6 +996,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);
@@ -956,6 +1008,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]);
@@ -968,6 +1021,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);
@@ -990,6 +1044,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);
@@ -997,6 +1052,8 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
ped->SetPosition(pos);
ped->SetOrientation(0.0f, 0.0f, 0.0f);
CTheScripts::ClearSpaceForMissionEntity(pos, ped);
+ if (m_bIsMissionScript)
+ ped->bIsStaticWaitingForCollision = true;
CWorld::Add(ped);
ped->m_nZoneLevel = CTheZones::GetLevelFromPosition(&pos);
CPopulation::ms_nTotalMissionPeds++;
@@ -1015,6 +1072,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);
@@ -1069,6 +1127,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);
@@ -1093,9 +1152,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;
+ */
#ifdef GTA_SCRIPT_COLLECTIVE
case COMMAND_SET_COLL_OBJ_STEAL_ANY_CAR:
CollectParameters(&m_nIp, 1);
@@ -1150,6 +1211,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);
@@ -1196,6 +1258,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);
@@ -1226,16 +1289,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]);
script_assert(pObject);
- pObject->SetMoveSpeed(pObject->GetMoveSpeed() + METERS_PER_SECOND_TO_GAME_SPEED * *(CVector*)&ScriptParams[1]);
+ pObject->AddToMoveSpeed(*(CVector*)&ScriptParams[1] * METERS_PER_SECOND_TO_GAME_SPEED);
return 0;
}
case COMMAND_DRAW_SPRITE:
@@ -1289,9 +1360,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:
@@ -1313,6 +1382,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
}
return 0;
}
+ /*
case COMMAND_SET_CHAR_ANIM_SPEED:
{
CollectParameters(&m_nIp, 2);
@@ -1323,6 +1393,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
pAssoc->speed = *(float*)&ScriptParams[1];
return 0;
}
+ */
case COMMAND_PLAY_MISSION_PASSED_TUNE:
{
CollectParameters(&m_nIp, 1);
@@ -1351,6 +1422,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);
@@ -1373,14 +1445,20 @@ 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]);
script_assert(pVehicle);
- script_assert(pVehicle->m_vehType == VEHICLE_TYPE_CAR);
- CAutomobile* pCar = (CAutomobile*)pVehicle;
- pCar->bWaterTight = ScriptParams[1] != 0;
+ if (pVehicle->IsBike()) {
+ CBike* pBike = (CBike*)pVehicle;
+ pBike->bWaterTight = ScriptParams[1] != 0;
+ }
+ else if (pVehicle->IsCar()) {
+ CAutomobile* pCar = (CAutomobile*)pVehicle;
+ pCar->bWaterTight = ScriptParams[1] != 0;
+ }
return 0;
}
case COMMAND_ADD_MOVING_PARTICLE_EFFECT:
@@ -1424,6 +1502,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
pVehicle->SetHeading(heading);
return 0;
}
+ /*
case COMMAND_IS_CRANE_LIFTING_CAR:
{
CollectParameters(&m_nIp, 3);
@@ -1431,6 +1510,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);
@@ -1467,6 +1547,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);
@@ -1477,6 +1558,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);
@@ -1504,7 +1586,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:
{
@@ -1543,6 +1625,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;
@@ -1555,6 +1638,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);
@@ -1570,7 +1654,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
if (total == 0)
CWorld::FindObjectsOfTypeInRangeSectorList(mi1, CWorld::GetBigBuildingList(LEVEL_GENERIC), pos, radius, true, &total, 16, apEntities);
if (total == 0)
- CWorld::FindObjectsOfTypeInRangeSectorList(mi1, CWorld::GetBigBuildingList(CTheZones::FindZoneForPoint(pos)), pos, radius, true, &total, 16, apEntities);
+ CWorld::FindObjectsOfTypeInRangeSectorList(mi1, CWorld::GetBigBuildingList(CTheZones::GetLevelFromPosition(&pos)), pos, radius, true, &total, 16, apEntities);
CEntity* pClosestEntity = nil;
float min_dist = 2.0f * radius;
for (int i = 0; i < total; i++) {
@@ -1601,6 +1685,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
pPed->ClearWeapons();
return 0;
}
+ /*
case COMMAND_GRAB_CATALINA_HELI:
{
CHeli* pHeli = CHeli::FindPointerToCatalinasHeli();
@@ -1608,6 +1693,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
StoreParameters(&m_nIp, 1);
return 0;
}
+ */
case COMMAND_CLEAR_AREA_OF_CARS:
{
CollectParameters(&m_nIp, 6);
@@ -1652,9 +1738,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);
@@ -1689,18 +1777,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:
{
script_assert(CTheScripts::ScriptSpace[m_nIp++] == ARGUMENT_GLOBALVAR);
uint16 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:
@@ -1711,7 +1802,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:
@@ -1721,30 +1812,28 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
return 0;
int attempts;
int model = -1;
- int index = CGeneral::GetRandomNumberInRange(0, 50);
- for (attempts = 0; attempts < 50; attempts++) {
+ int index = CGeneral::GetRandomNumberInRange(0, MAXVEHICLESLOADED);
+ for (attempts = 0; attempts < MAXVEHICLESLOADED; attempts++) {
if (model != -1)
break;
model = CStreaming::ms_vehiclesLoaded[index];
if (model == -1)
continue;
- // desperatly want to believe this was inlined :|
- CBaseModelInfo* pInfo = CModelInfo::GetModelInfo(model);
- script_assert(pInfo->GetModelType() == MITYPE_VEHICLE);
- CVehicleModelInfo* pVehicleInfo = (CVehicleModelInfo*)pInfo;
- if (pVehicleInfo->m_vehicleType == VEHICLE_TYPE_CAR) {
+ if (CModelInfo::IsCarModel(model) || CModelInfo::IsBikeModel(model)) {
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:
@@ -1752,56 +1841,95 @@ 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_YARDIE:
- 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_BORGNINE:
- case MI_TOYZ:
- case MI_GHOST:
- case MI_MIAMI_RCBARON:
- case MI_MIAMI_RCRAIDER:
+ case MI_CADDY:
+ case MI_ZEBRA:
+ case MI_TOPFUN:
+ 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:
case MI_ESPERANT:
case MI_TAXI:
- case MI_KURUMA:
+ case MI_WASHING:
case MI_BOBCAT:
case MI_BANSHEE:
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]);
@@ -1817,7 +1945,11 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
if (model == -1)
return 0;
CVehicle* car;
- if (!CModelInfo::IsBikeModel(model))
+ if (CModelInfo::IsBikeModel(model)) {
+ car = new CBike(model, RANDOM_VEHICLE);
+ ((CBike*)(car))->bIsStanding = true;
+ }
+ else
car = new CAutomobile(model, RANDOM_VEHICLE);
CVector pos = *(CVector*)&ScriptParams[0];
pos.z += car->GetDistanceFromCentreOfMassToBaseOfModel();
@@ -1838,10 +1970,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];
@@ -1849,6 +1983,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);
@@ -1857,6 +1992,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]));
@@ -1865,9 +2001,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:
@@ -1889,21 +2033,31 @@ 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]);
m_nIp += KEY_LENGTH_IN_SCRIPT;
- DMAudio.PreloadMissionAudio(str);
+ DMAudio.PreloadMissionAudio(ScriptParams[0] - 1, str);
return 0;
+ }
case COMMAND_HAS_MISSION_AUDIO_LOADED:
- UpdateCompareFlag(DMAudio.GetMissionAudioLoadingStatus() == 1);
+ {
+ CollectParameters(&m_nIp, 1);
+ UpdateCompareFlag(DMAudio.GetMissionAudioLoadingStatus(ScriptParams[0] - 1) == 1);
return 0;
+ }
case COMMAND_PLAY_MISSION_AUDIO:
- DMAudio.PlayLoadedMissionAudio();
+ CollectParameters(&m_nIp, 1);
+ DMAudio.PlayLoadedMissionAudio(ScriptParams[0] - 1);
return 0;
case COMMAND_HAS_MISSION_AUDIO_FINISHED:
- UpdateCompareFlag(DMAudio.IsMissionAudioSampleFinished());
+ {
+ CollectParameters(&m_nIp, 1);
+ UpdateCompareFlag(DMAudio.IsMissionAudioSampleFinished(ScriptParams[0] - 1));
return 0;
+ }
case COMMAND_GET_CLOSEST_CAR_NODE_WITH_HEADING:
{
CollectParameters(&m_nIp, 3);
@@ -1911,7 +2065,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);
- *(CVector*)&ScriptParams[0] = ThePaths.m_pathNodes[node].GetPosition();
+ *(CVector*)&ScriptParams[0] = ThePaths.FindNodeCoorsForScript(node);
*(float*)&ScriptParams[3] = ThePaths.FindNodeOrientationForCarPlacement(node);
StoreParameters(&m_nIp, 4);
return 0;
@@ -1936,21 +2090,27 @@ 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];
+ DMAudio.SetMissionAudioLocation(ScriptParams[0] - 1, 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);
@@ -1960,6 +2120,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
StoreParameters(&m_nIp, 1);
return 0;
}
+ */
case COMMAND_ADD_BLIP_FOR_PICKUP:
{
CollectParameters(&m_nIp, 1);
@@ -1971,6 +2132,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
StoreParameters(&m_nIp, 1);
return 0;
}
+ /*
case COMMAND_ADD_SPRITE_BLIP_FOR_PICKUP:
{
CollectParameters(&m_nIp, 2);
@@ -1982,6 +2144,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];
@@ -1990,18 +2153,25 @@ 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);
return 0;
- case COMMAND_REGISTER_EL_BURRO_TIME:
+ case COMMAND_SET_CHAR_OBJ_LEAVE_ANY_CAR:
+ {
CollectParameters(&m_nIp, 1);
- CStats::RegisterElBurroTime(ScriptParams[0]);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ pPed->bScriptObjectiveCompleted = false;
+ pPed->SetObjective(OBJECTIVE_LEAVE_CAR, pPed->m_pMyVehicle);
return 0;
+ }
case COMMAND_SET_SPRITES_DRAW_BEFORE_FADE:
CollectParameters(&m_nIp, 1);
CTheScripts::IntroRectangles[CTheScripts::NumberOfIntroRectanglesThisFrame].m_bBeforeFade = ScriptParams[0] != 0;
@@ -2015,8 +2185,8 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
if (CCamera::m_bUseMouse3rdPerson && (
strcmp((char*)&CTheScripts::ScriptSpace[m_nIp], "HELP15") == 0 ||
strcmp((char*)&CTheScripts::ScriptSpace[m_nIp], "GUN_2A") == 0 ||
- strcmp((char*)&CTheScripts::ScriptSpace[m_nIp], "GUN_3A") == 0 ||
- strcmp((char*)&CTheScripts::ScriptSpace[m_nIp], "GUN_4A") == 0)) {
+ strcmp((char*)&CTheScripts::ScriptSpace[m_nIp], "GUN_2C") == 0 ||
+ strcmp((char*)&CTheScripts::ScriptSpace[m_nIp], "GUN_2D") == 0)) {
m_nIp += KEY_LENGTH_IN_SCRIPT;
return 0;
}
diff --git a/src/control/Script5.cpp b/src/control/Script5.cpp
index 76aa2442..e9f0967e 100644
--- a/src/control/Script5.cpp
+++ b/src/control/Script5.cpp
@@ -17,6 +17,7 @@
#include "SpecialFX.h"
#include "World.h"
#include "main.h"
+#include "SaveBuf.h"
void CRunningScript::UpdateCompareFlag(bool flag)
{
@@ -331,7 +332,7 @@ void CRunningScript::LocateCharCommand(int32 command, uint32* pIp)
CollectParameters(pIp, b3D ? 8 : 6);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
script_assert(pPed);
- CVector pos = pPed->bInVehicle ? pPed->m_pMyVehicle->GetPosition() : pPed->GetPosition();
+ CVector pos = pPed->InVehicle() ? pPed->m_pMyVehicle->GetPosition() : pPed->GetPosition();
switch (command) {
case COMMAND_LOCATE_STOPPED_CHAR_ANY_MEANS_2D:
case COMMAND_LOCATE_STOPPED_CHAR_ANY_MEANS_3D:
@@ -732,6 +733,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]);
+ script_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;
@@ -1033,7 +1092,7 @@ void CRunningScript::CharInAreaCheckCommand(int32 command, uint32* pIp)
CollectParameters(pIp, b3D ? 8 : 6);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
script_assert(pPed);
- CVector pos = pPed->bInVehicle ? pPed->m_pMyVehicle->GetPosition() : pPed->GetPosition();
+ CVector pos = pPed->InVehicle() ? pPed->m_pMyVehicle->GetPosition() : pPed->GetPosition();
switch (command) {
case COMMAND_IS_CHAR_STOPPED_IN_AREA_3D:
case COMMAND_IS_CHAR_STOPPED_IN_AREA_ON_FOOT_3D:
@@ -1229,6 +1288,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]);
+ script_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:
+ script_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)
@@ -1236,11 +1377,13 @@ void CRunningScript::DoDeatharrestCheck()
if (!CTheScripts::IsPlayerOnAMission())
return;
CPlayerInfo* pPlayer = &CWorld::Players[CWorld::PlayerInFocus];
- if (!pPlayer->IsRestartingAfterDeath() && !pPlayer->IsRestartingAfterArrest() && !CTheScripts::UpsideDownCars.AreAnyCarsUpsideDown())
+ if (!pPlayer->IsRestartingAfterDeath() && !pPlayer->IsRestartingAfterArrest())
return;
#ifdef MISSION_REPLAY
- if (AllowMissionReplay != MISSION_RETRY_STAGE_NORMAL)
+ if (AllowMissionReplay != MISSION_RETRY_STAGE_WAIT_FOR_TIMER_AFTER_RESTART && AllowMissionReplay != MISSION_RETRY_STAGE_NORMAL)
return;
+ if (AllowMissionReplay == MISSION_RETRY_STAGE_WAIT_FOR_TIMER_AFTER_RESTART)
+ AllowMissionReplay = MISSION_RETRY_STAGE_NORMAL;
if (CanAllowMissionReplay())
AllowMissionReplay = MISSION_RETRY_STAGE_WAIT_FOR_SCRIPT_TO_TERMINATE;
#endif
@@ -1248,29 +1391,7 @@ 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;
@@ -1787,6 +1908,76 @@ void CRunningScript::CollectiveInAreaCheckCommand(int32 command, uint32* pIp)
}
#endif
+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 && actual <= WEAPONTYPE_UNIDENTIFIED)
+ 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;
+}
+
void CTheScripts::PrintListSizes()
{
int active = 0;
@@ -1909,8 +2100,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)
{
@@ -1930,13 +2121,7 @@ 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);
+ WriteSaveBuf(buf, LastMissionPassedTime);
for (uint32 i = 0; i < MAX_NUM_BUILDING_SWAPS; i++) {
CBuilding* pBuilding = BuildingSwapArray[i].m_pBuilding;
uint32 type, handle;
@@ -1986,12 +2171,12 @@ INITSAVEBUF
WriteSaveBuf(buf, handle);
}
WriteSaveBuf(buf, bUsingAMultiScriptFile);
- WriteSaveBuf(buf, (uint8)0);
+ WriteSaveBuf(buf, bPlayerHasMetDebbieHarry);
WriteSaveBuf(buf, (uint16)0);
WriteSaveBuf(buf, MainScriptSize);
WriteSaveBuf(buf, LargestMissionScriptSize);
WriteSaveBuf(buf, NumberOfMissionScripts);
- WriteSaveBuf(buf, (uint16)0);
+ WriteSaveBuf(buf, NumberOfExclusiveMissionScripts);
WriteSaveBuf(buf, runningScripts);
for (CRunningScript* pScript = pActiveScripts; pScript; pScript = pScript->GetNext())
pScript->Save(buf);
@@ -2012,13 +2197,7 @@ INITSAVEBUF
ReadSaveBuf(&tmp, buf);
script_assert(tmp == SCRIPT_DATA_SIZE);
ReadSaveBuf(&OnAMissionFlag, buf);
- for (uint32 i = 0; i < MAX_NUM_CONTACTS; i++) {
- ReadSaveBuf(&OnAMissionForContactFlag[i], buf);
- ReadSaveBuf(&BaseBriefIdForContact[i], buf);
- }
- for (uint32 i = 0; i < MAX_NUM_COLLECTIVES; i++)
- ReadSaveBuf(&CollectiveArray[i], buf);
- ReadSaveBuf(&NextFreeCollectiveIndex, buf);
+ ReadSaveBuf(&LastMissionPassedTime, buf);
for (uint32 i = 0; i < MAX_NUM_BUILDING_SWAPS; i++) {
ReadSaveBuf(&type, buf);
ReadSaveBuf(&handle, buf);
@@ -2068,7 +2247,8 @@ INITSAVEBUF
bool tmpBool;
ReadSaveBuf(&tmpBool, buf);
script_assert(tmpBool == bUsingAMultiScriptFile);
- SkipSaveBuf(buf, 3);
+ ReadSaveBuf(&bPlayerHasMetDebbieHarry, buf);
+ SkipSaveBuf(buf, 2);
ReadSaveBuf(&tmp, buf);
script_assert(tmp == MainScriptSize);
ReadSaveBuf(&tmp, buf);
@@ -2076,7 +2256,8 @@ INITSAVEBUF
uint16 tmp16;
ReadSaveBuf(&tmp16, buf);
script_assert(tmp16 == NumberOfMissionScripts);
- SkipSaveBuf(buf, 2);
+ ReadSaveBuf(&tmp16, buf);
+ script_assert(tmp16 == NumberOfExclusiveMissionScripts);
uint32 runningScripts;
ReadSaveBuf(&runningScripts, buf);
for (uint32 i = 0; i < runningScripts; i++)
@@ -2105,10 +2286,10 @@ void CRunningScript::Save(uint8*& buf)
#endif
for (int i = 0; i < NUM_LOCAL_VARS + NUM_TIMERS; i++)
WriteSaveBuf(buf, m_anLocalVariables[i]);
+ WriteSaveBuf(buf, m_bIsActive);
WriteSaveBuf(buf, m_bCondResult);
WriteSaveBuf(buf, m_bIsMissionScript);
WriteSaveBuf(buf, m_bSkipWakeTime);
- ZeroSaveBuf(buf, 1);
WriteSaveBuf(buf, m_nWakeTime);
WriteSaveBuf(buf, m_nAndOrState);
WriteSaveBuf(buf, m_bNotFlag);
@@ -2140,10 +2321,10 @@ void CRunningScript::Load(uint8*& buf)
#endif
for (int i = 0; i < NUM_LOCAL_VARS + NUM_TIMERS; i++)
ReadSaveBuf(&m_anLocalVariables[i], buf);
+ ReadSaveBuf(&m_bIsActive, buf);
ReadSaveBuf(&m_bCondResult, buf);
ReadSaveBuf(&m_bIsMissionScript, buf);
ReadSaveBuf(&m_bSkipWakeTime, buf);
- SkipSaveBuf(buf, 1);
ReadSaveBuf(&m_nWakeTime, buf);
ReadSaveBuf(&m_nAndOrState, buf);
ReadSaveBuf(&m_bNotFlag, buf);
@@ -2451,22 +2632,24 @@ void CTheScripts::SetObjectiveForAllPedsInCollective(int colIndex, eObjective ob
bool CTheScripts::IsPedStopped(CPed* pPed)
{
- if (pPed->bInVehicle)
+ if (pPed->InVehicle())
return IsVehicleStopped(pPed->m_pMyVehicle);
- return pPed->m_nMoveState == PEDMOVE_NONE || pPed->m_nMoveState == PEDMOVE_STILL;
+ return (pPed->m_nMoveState == PEDMOVE_NONE || pPed->m_nMoveState == PEDMOVE_STILL) &&
+ !pPed->bIsInTheAir && !pPed->bIsLanding && pPed->bIsStanding && pPed->m_vecAnimMoveDelta.x == 0.0f && pPed->m_vecAnimMoveDelta.y == 0.0f;
}
bool CTheScripts::IsPlayerStopped(CPlayerInfo* pPlayer)
{
CPed* pPed = pPlayer->m_pPed;
- if (pPed->bInVehicle)
+ if (pPed->InVehicle())
return IsVehicleStopped(pPed->m_pMyVehicle);
if (RpAnimBlendClumpGetAssociation(pPed->GetClump(), ANIM_STD_RUNSTOP1) ||
RpAnimBlendClumpGetAssociation(pPed->GetClump(), ANIM_STD_RUNSTOP2) ||
RpAnimBlendClumpGetAssociation(pPed->GetClump(), ANIM_STD_JUMP_LAUNCH) ||
RpAnimBlendClumpGetAssociation(pPed->GetClump(), ANIM_STD_JUMP_GLIDE))
return false;
- return pPed->m_nMoveState == PEDMOVE_NONE || pPed->m_nMoveState == PEDMOVE_STILL;
+ return (pPed->m_nMoveState == PEDMOVE_NONE || pPed->m_nMoveState == PEDMOVE_STILL) &&
+ !pPed->bIsInTheAir && !pPed->bIsLanding && pPed->bIsStanding && pPed->m_vecAnimMoveDelta.x == 0.0f && pPed->m_vecAnimMoveDelta.y == 0.0f;
}
bool CTheScripts::IsVehicleStopped(CVehicle* pVehicle)
@@ -2474,6 +2657,30 @@ bool CTheScripts::IsVehicleStopped(CVehicle* pVehicle)
return 0.01f * CTimer::GetTimeStep() >= pVehicle->m_fDistanceTravelled;
}
+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;
+ }
+}
+
void CTheScripts::CleanUpThisPed(CPed* pPed)
{
if (!pPed)
@@ -2483,7 +2690,7 @@ void CTheScripts::CleanUpThisPed(CPed* pPed)
pPed->CharCreatedBy = RANDOM_CHAR;
if (pPed->m_nPedType == PEDTYPE_PROSTITUTE)
pPed->m_objectiveTimer = CTimer::GetTimeInMilliseconds() + 30000;
- if (pPed->bInVehicle) {
+ if (pPed->InVehicle()) {
if (pPed->m_pMyVehicle->pDriver == pPed) {
if (pPed->m_pMyVehicle->m_vehType == VEHICLE_TYPE_CAR) {
CCarCtrl::JoinCarWithRoadSystem(pPed->m_pMyVehicle);
@@ -2508,6 +2715,7 @@ void CTheScripts::CleanUpThisPed(CPed* pPed)
pPed->ClearObjective();
pPed->bRespondsToThreats = true;
pPed->bScriptObjectiveCompleted = false;
+ pPed->bKindaStayInSamePlace = false;
pPed->ClearLeader();
if (pPed->IsPedInControl())
pPed->SetWanderPath(CGeneral::GetRandomNumber() & 7);
@@ -2538,7 +2746,7 @@ void CTheScripts::CleanUpThisObject(CObject* pObject)
if (pObject->ObjectCreatedBy != MISSION_OBJECT)
return;
pObject->ObjectCreatedBy = TEMP_OBJECT;
- pObject->m_nEndOfLifeTime = CTimer::GetTimeInMilliseconds() + 20000;
+ pObject->m_nEndOfLifeTime = CTimer::GetTimeInMilliseconds() + 20000000;
pObject->m_nRefModelIndex = -1;
pObject->bUseVehicleColours = false;
++CObject::nNoTempObjects;
@@ -2595,7 +2803,7 @@ void CTheScripts::ReadMultiScriptFileOffsetsFromScript()
MainScriptSize = Read4BytesFromScript(&ip);
LargestMissionScriptSize = Read4BytesFromScript(&ip);
NumberOfMissionScripts = Read2BytesFromScript(&ip);
- ip += 2;
+ NumberOfExclusiveMissionScripts = Read2BytesFromScript(&ip);
for (int i = 0; i < NumberOfMissionScripts; i++) {
MultiScriptArray[i] = Read4BytesFromScript(&ip);
}
diff --git a/src/control/Script6.cpp b/src/control/Script6.cpp
index 0a2248f8..8af32f57 100644
--- a/src/control/Script6.cpp
+++ b/src/control/Script6.cpp
@@ -32,17 +32,58 @@
#include "Weather.h"
#include "Zones.h"
#include "main.h"
+#include "GameLogic.h"
+#include "Sprite.h"
+#include "CarAI.h"
+#include "Pickups.h"
+#include "Fluff.h"
-// NB: on PS2 this file did not exist; ProcessCommands1000To1099 was in Script5.cpp and ProcessCommands1100To1199 was only added on PC
-// however to avoid redundant copies of code, Script6.cpp is used with PS2 defines
+#ifdef USE_DEBUG_SCRIPT_LOADER
+extern const char* scriptfile;
+#endif
+
+bool CRunningScript::ThisIsAValidRandomCop(uint32 mi, int cop, int swat, int fbi, int army, int miami)
+{
+ switch (mi)
+ {
+ case MI_COP: if (cop) return true; break;
+ case MI_SWAT: if (swat) return true; break;
+ case MI_FBI: if (fbi) return true; break;
+ case MI_ARMY: if (army) return true; break;
+ default: if (mi >= MI_VICE1 && mi <= MI_VICE8 && miami) return true; break;
+ }
+ return false;
+}
+
+bool CRunningScript::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:
+ case PEDTYPE_GANG4:
+ case PEDTYPE_GANG5:
+ case PEDTYPE_GANG6:
+ case PEDTYPE_GANG7:
+ case PEDTYPE_GANG8:
+ case PEDTYPE_GANG9:
+ return gang;
+ case PEDTYPE_CRIMINAL:
+ case PEDTYPE_PROSTITUTE:
+ return criminal;
+ default:
+ return false;
+ }
+}
int8 CRunningScript::ProcessCommands1000To1099(int32 command)
{
-#if GTA_VERSION <= GTA3_PS2_160
- char tmp[48];
-#endif
switch (command) {
//case COMMAND_FLASH_RADAR_BLIP:
+ /*
case COMMAND_IS_CHAR_IN_CONTROL:
{
CollectParameters(&m_nIp, 1);
@@ -50,6 +91,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);
@@ -57,9 +99,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);
@@ -81,10 +125,6 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
case COMMAND_MAKE_PLAYER_SAFE_FOR_CUTSCENE:
{
CollectParameters(&m_nIp, 1);
-#ifdef MISSION_REPLAY
- AllowMissionReplay = MISSION_RETRY_STAGE_NORMAL;
- SaveGameForPause(SAVE_TYPE_QUICKSAVE_FOR_MISSION_REPLAY);
-#endif
CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
CPad::GetPad(ScriptParams[0])->SetDisablePlayerControls(PLAYERCONTROL_CUTSCENE);
pPlayerInfo->MakePlayerSafe(true);
@@ -129,6 +169,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
return 0;
}
//case COMMAND_MAKE_PLAYER_UNSAFE:
+ /*
case COMMAND_LOAD_COLLISION:
{
CollectParameters(&m_nIp, 1);
@@ -149,9 +190,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);
@@ -163,6 +205,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);
@@ -185,22 +228,34 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
pPed->m_nZoneLevel = LEVEL_GENERIC;
return 0;
}
- case COMMAND_REGISTER_4X4_ONE_TIME:
- CollectParameters(&m_nIp, 1);
- CStats::Register4x4OneTime(ScriptParams[0]);
- return 0;
- case COMMAND_REGISTER_4X4_TWO_TIME:
- CollectParameters(&m_nIp, 1);
- CStats::Register4x4TwoTime(ScriptParams[0]);
+ */
+ case COMMAND_SET_DRUNK_INPUT_DELAY:
+ {
+ CollectParameters(&m_nIp, 2);
+ assert(ScriptParams[1] < CPad::DRUNK_STEERING_BUFFER_SIZE);
+ CPad::GetPad(ScriptParams[0])->SetDrunkInputDelay(ScriptParams[1]);
return 0;
- case COMMAND_REGISTER_4X4_THREE_TIME:
- CollectParameters(&m_nIp, 1);
- CStats::Register4x4ThreeTime(ScriptParams[0]);
+ }
+ case COMMAND_SET_CHAR_MONEY:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ pPed->m_nPedMoney = ScriptParams[1];
+ pPed->bMoneyHasBeenGivenByScript = true;
return 0;
- case COMMAND_REGISTER_4X4_MAYHEM_TIME:
- CollectParameters(&m_nIp, 1);
- CStats::Register4x4MayhemTime(ScriptParams[0]);
+ }
+ //case COMMAND_INCREASE_CHAR_MONEY:
+ case COMMAND_GET_OFFSET_FROM_OBJECT_IN_WORLD_COORDS:
+ {
+ CollectParameters(&m_nIp, 4);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ script_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;
@@ -218,25 +273,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_REGISTER_DEFUSE_BOMB_TIME:
- CollectParameters(&m_nIp, 1);
- CStats::RegisterTimeTakenDefuseMission(ScriptParams[0]);
+ */
+ case COMMAND_GET_OFFSET_FROM_CAR_IN_WORLD_COORDS:
+ {
+ CollectParameters(&m_nIp, 4);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_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;
@@ -244,8 +309,10 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
UpdateCompareFlag(CGame::germanGame);
return 0;
case COMMAND_CLEAR_MISSION_AUDIO:
- DMAudio.ClearMissionAudio();
+ CollectParameters(&m_nIp, 1);
+ DMAudio.ClearMissionAudio(ScriptParams[0] - 1);
return 0;
+ /*
case COMMAND_SET_FADE_IN_AFTER_NEXT_ARREST:
CollectParameters(&m_nIp, 1);
CRestart::bFadeInAfterNextArrest = !!ScriptParams[0];
@@ -258,6 +325,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);
@@ -268,6 +336,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
pPed->bUsePedNodeSeek = !!ScriptParams[1];
return 0;
}
+ /*
case COMMAND_SWITCH_VEHICLE_WEAPONS:
{
CollectParameters(&m_nIp, 2);
@@ -280,10 +349,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);
@@ -292,15 +363,33 @@ 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:
{
+#ifdef USE_MISSION_REPLAY_OVERRIDE_FOR_NON_MOBILE_SCRIPT
+ uint32 oldIp = m_nIp;
+#endif
CollectParameters(&m_nIp, 1);
+
+ if (CTheScripts::NumberOfExclusiveMissionScripts > 0 && ScriptParams[0] <= UINT16_MAX - 2)
+ return 0;
#ifdef MISSION_REPLAY
missionRetryScriptIndex = ScriptParams[0];
- if (missionRetryScriptIndex == 19)
- CStats::LastMissionPassedName[0] = '\0';
+#ifdef USE_MISSION_REPLAY_OVERRIDE_FOR_NON_MOBILE_SCRIPT
+ if (!UsingMobileScript && CTheScripts::MissionSupportsMissionReplay(missionRetryScriptIndex)){
+ if (!AlreadySavedGame) {
+ m_nIp = oldIp - 2;
+ SaveGameForPause(SAVE_TYPE_QUICKSAVE_FOR_SCRIPT);
+ AlreadySavedGame = true;
+ return 0;
+ }
+ else {
+ AlreadySavedGame = false;
+ }
+ }
+#endif
#endif
CTimer::Suspend();
int offset = CTheScripts::MultiScriptArray[ScriptParams[0]];
@@ -318,6 +407,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
pMissionScript->m_bIsMissionScript = true;
pMissionScript->m_bMissionFlag = true;
CTheScripts::bAlreadyRunningAMissionScript = true;
+ CGameLogic::ClearShortCut();
return 0;
}
case COMMAND_SET_OBJECT_DRAW_LAST:
@@ -333,14 +423,15 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
CollectParameters(&m_nIp, 2);
CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
script_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);
@@ -385,6 +476,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
}
return 0;
}
+ */
case COMMAND_SET_NEAR_CLIP:
CollectParameters(&m_nIp, 1);
TheCamera.SetNearClipScript(*(float*)&ScriptParams[0]);
@@ -393,6 +485,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];
@@ -413,6 +506,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
UpdateCompareFlag(CGarages::IsThisCarWithinGarageArea(ScriptParams[0], pVehicle));
return 0;
}
+ */
case COMMAND_SET_CAR_TRACTION:
{
CollectParameters(&m_nIp, 2);
@@ -422,7 +516,6 @@ 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
((CBike*)pVehicle)->m_fTraction = fTraction;
return 0;
}
@@ -442,6 +535,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
StoreParameters(&m_nIp, 1);
return 0;
}
+ /*
case COMMAND_MARK_ROADS_BETWEEN_LEVELS:
{
CollectParameters(&m_nIp, 6);
@@ -490,6 +584,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);
@@ -498,6 +593,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);
@@ -510,6 +606,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);
@@ -536,7 +633,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);
@@ -560,6 +657,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
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);
@@ -571,6 +669,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
StoreParameters(&m_nIp, 1);
return 0;
}
+ */
case COMMAND_SET_CHAR_IS_CHRIS_CRIMINAL:
{
CollectParameters(&m_nIp, 2);
@@ -593,6 +692,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);
@@ -625,10 +725,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]) {
@@ -643,6 +745,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
CStreaming::LoadAllRequestedModels(false);
}
return 0;
+ */
case COMMAND_SET_PLAYER_HOOKER:
{
CollectParameters(&m_nIp, 2);
@@ -655,6 +758,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
CPed* pHooker = CPools::GetPedPool()->GetAt(ScriptParams[1]);
script_assert(pHooker);
pPlayerInfo->m_pHooker = (CCivilianPed*)pHooker;
+ pPlayerInfo->m_nSexFrequency = 1000;
pPlayerInfo->m_nNextSexFrequencyUpdateTime = CTimer::GetTimeInMilliseconds() + 1000;
pPlayerInfo->m_nNextSexMoneyUpdateTime = CTimer::GetTimeInMilliseconds() + 3000;
}
@@ -682,8 +786,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
script_assert(pPed);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
- script_assert(pVehicle);
- UpdateCompareFlag(pPed->GetPedState() == PED_DRIVING && pPed->m_pMyVehicle == pVehicle);
+ UpdateCompareFlag(pPed->GetPedState() == PED_DRIVING && pPed->m_objective != OBJECTIVE_LEAVE_CAR && pPed->m_pMyVehicle == pVehicle);
return 0;
}
case COMMAND_IS_PLAYER_SITTING_IN_ANY_CAR:
@@ -691,24 +794,27 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
CollectParameters(&m_nIp, 1);
CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
script_assert(pPed);
- UpdateCompareFlag(pPed->GetPedState() == PED_DRIVING);
+ UpdateCompareFlag(pPed->GetPedState() == PED_DRIVING && pPed->m_objective != OBJECTIVE_LEAVE_CAR);
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 || CVehicle::bHoverCheat || CVehicle::bCheat8 || CVehicle::bCheat9);
return 0;
case COMMAND_SET_CHAR_SUFFERS_CRITICAL_HITS:
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
script_assert(pPed);
- pPed->bNoCriticalHits = (ScriptParams[0] == 0);
+ pPed->bNoCriticalHits = (ScriptParams[1] == 0);
return 0;
}
+ /*
case COMMAND_IS_PLAYER_LIFTING_A_PHONE:
{
CollectParameters(&m_nIp, 1);
@@ -717,6 +823,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);
@@ -724,7 +831,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
script_assert(pPed);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
script_assert(pVehicle);
- UpdateCompareFlag(pPed->GetPedState() == PED_DRIVING && pPed->m_pMyVehicle == pVehicle);
+ UpdateCompareFlag(pPed->GetPedState() == PED_DRIVING && pPed->m_objective != OBJECTIVE_LEAVE_CAR && pPed->m_pMyVehicle == pVehicle);
return 0;
}
case COMMAND_IS_CHAR_SITTING_IN_ANY_CAR:
@@ -732,7 +839,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
CollectParameters(&m_nIp, 1);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
script_assert(pPed);
- UpdateCompareFlag(pPed->GetPedState() == PED_DRIVING);
+ UpdateCompareFlag(pPed->GetPedState() == PED_DRIVING && pPed->m_objective != OBJECTIVE_LEAVE_CAR);
return 0;
}
case COMMAND_IS_PLAYER_ON_FOOT:
@@ -753,7 +860,6 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
pPed->m_objective != OBJECTIVE_ENTER_CAR_AS_DRIVER);
return 0;
}
-#if GTA_VERSION > GTA3_PS2_160
default:
script_assert(0);
}
@@ -764,7 +870,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
{
char tmp[48];
switch (command) {
-#endif
+ /*
case COMMAND_LOAD_COLLISION_WITH_SCREEN:
CollectParameters(&m_nIp, 1);
CTimer::Stop();
@@ -800,6 +906,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++)
@@ -807,6 +914,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
m_nIp += 8;
LoadSplash(tmp);
return 0;
+ /*
case COMMAND_SET_CAR_IGNORE_LEVEL_TRANSITIONS:
{
CollectParameters(&m_nIp, 2);
@@ -828,6 +936,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);
@@ -839,14 +948,14 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
case COMMAND_LOAD_END_OF_GAME_TUNE:
DMAudio.ChangeMusicMode(MUSICMODE_CUTSCENE);
printf("Start preload end of game audio\n");
- DMAudio.PreloadCutSceneMusic(STREAMED_SOUND_GAME_COMPLETED);
+ DMAudio.PreloadCutSceneMusic(STREAMED_SOUND_CUTSCENE_FINALE);
printf("End preload end of game audio\n");
return 0;
+ /*
case COMMAND_ENABLE_PLAYER_CONTROL_CAMERA:
CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_CAMERA);
return 0;
-#if GTA_VERSION > GTA3_PS2_160
- // These are "beta" VC commands (with bugs)
+ */
case COMMAND_SET_OBJECT_ROTATION:
{
CollectParameters(&m_nIp, 4);
@@ -866,6 +975,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);
@@ -879,6 +989,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
UpdateCompareFlag(pTarget && pTarget->IsPed());
return 0;
}
+ */
case COMMAND_IS_PLAYER_TARGETTING_CHAR:
{
CollectParameters(&m_nIp, 2);
@@ -887,9 +998,38 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
CPed* pTestedPed = CPools::GetPedPool()->GetAt(ScriptParams[1]);
script_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);
@@ -901,6 +1041,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);
@@ -942,9 +1083,14 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
}
case COMMAND_FAIL_CURRENT_MISSION:
CTheScripts::FailCurrentMission = 2;
+#ifdef MISSION_REPLAY
+ MissionSkipLevel = 0;
+#endif
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)
@@ -988,7 +1134,9 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
}
StoreParameters(&m_nIp, 1);
return 0;
+*/
}
+ /*
case COMMAND_PLACE_OBJECT_RELATIVE_TO_OBJECT:
{
CollectParameters(&m_nIp, 5);
@@ -1000,28 +1148,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]);
script_assert(pVehicle);
- if (pVehicle->pDriver) {
- pVehicle->pDriver->bScriptObjectiveCompleted = false;
- pVehicle->pDriver->SetObjective(OBJECTIVE_LEAVE_CAR, 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_CAR, 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);
@@ -1052,16 +1192,27 @@ 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
+ {
+ CollectParameters(&m_nIp, 8);
+ CPed *pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ CVehicle *pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
+ pPed->AttachPedToEntity(pVehicle, *(CVector*)&ScriptParams[2], ScriptParams[5], DEGTORAD(*(float*)&ScriptParams[6]), (eWeaponType)ScriptParams[7]);
return 0;
+ }
case COMMAND_DETACH_CHAR_FROM_CAR:
- // empty implementation
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed *pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ if (pPed && pPed->m_attachedTo)
+ pPed->DettachPedFromEntity();
return 0;
+ }
case COMMAND_SET_CAR_CHANGE_LANE: // for some reason changed in SA
{
CollectParameters(&m_nIp, 2);
@@ -1074,20 +1225,25 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
{
CollectParameters(&m_nIp, 1);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_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:
{
- CollectParameters(&m_nIp, 4);
+ CollectParameters(&m_nIp, 9);
int ped_handle = -1;
CVector pos = FindPlayerCoors();
float x1 = *(float*)&ScriptParams[0];
@@ -1103,9 +1259,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_ABSEIL)
continue;
if (pPed->bRemoveFromWorld)
continue;
@@ -1115,9 +1273,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;
@@ -1131,14 +1289,15 @@ 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);
- int nZone = CTheZones::FindZoneByLabelAndReturnIndex(zone);
+ int nZone = CTheZones::FindZoneByLabelAndReturnIndex(zone, ZONE_DEFAULT);
if (nZone != -1)
m_nIp += KEY_LENGTH_IN_SCRIPT;
- CZone* pZone = CTheZones::GetZone(nZone);
+ CZone* pZone = CTheZones::GetNavigationZone(nZone);
int ped_handle = -1;
CVector pos = FindPlayerCoors();
int i = CPools::GetPedPool()->GetSize();
@@ -1162,9 +1321,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;
@@ -1178,6 +1337,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
StoreParameters(&m_nIp, 1);
return 0;
}
+ */
case COMMAND_SET_CHAR_OBJ_FLEE_CAR:
{
CollectParameters(&m_nIp, 2);
@@ -1234,7 +1394,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
CollectParameters(&m_nIp, 1);
CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
script_assert(pPed);
- ScriptParams[0] = pPed->m_weapons[pPed->m_currentWeapon].m_eWeaponType;
+ ScriptParams[0] = pPed->GetWeapon()->m_eWeaponType;
StoreParameters(&m_nIp, 1);
return 0;
}
@@ -1243,7 +1403,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
CollectParameters(&m_nIp, 1);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
script_assert(pPed);
- ScriptParams[0] = pPed->m_weapons[pPed->m_currentWeapon].m_eWeaponType;
+ ScriptParams[0] = pPed->GetWeapon()->m_eWeaponType;
StoreParameters(&m_nIp, 1);
return 0;
}
@@ -1255,15 +1415,16 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
case COMMAND_LOCATE_CHAR_IN_CAR_OBJECT_3D:
LocateCharObjectCommand(command, &m_nIp);
return 0;
- case COMMAND_SET_CAR_HANDBRAKE_TURN_LEFT: // this will be changed in final VC version to a more general SET_TEMP_ACTION
+ case COMMAND_SET_CAR_TEMP_ACTION:
{
- CollectParameters(&m_nIp, 2);
+ CollectParameters(&m_nIp, 3);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
script_assert(pVehicle);
- pVehicle->AutoPilot.m_nTempAction = TEMPACT_HANDBRAKETURNLEFT;
- pVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + ScriptParams[1];
+ pVehicle->AutoPilot.m_nTempAction = (uint8)ScriptParams[1];
+ pVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + ScriptParams[2];
return 0;
}
+ /*
case COMMAND_SET_CAR_HANDBRAKE_TURN_RIGHT:
{
CollectParameters(&m_nIp, 2);
@@ -1282,18 +1443,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]);
script_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;
@@ -1304,9 +1468,10 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
CollectParameters(&m_nIp, 1);
CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
script_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);
@@ -1315,6 +1480,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
UpdateCompareFlag(pPed->bFallenDown);
return 0;
}
+ */
case COMMAND_CAN_CHAR_SEE_DEAD_CHAR:
{
CollectParameters(&m_nIp, 2);
@@ -1332,23 +1498,315 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
}
case COMMAND_SET_ENTER_CAR_RANGE_MULTIPLIER:
CollectParameters(&m_nIp, 1);
-#ifdef FIX_BUGS
CPed::nEnterCarRangeMultiplier = *(float*)&ScriptParams[0];
-#else
- CPed::nEnterCarRangeMultiplier = (float)ScriptParams[0];
-#endif
return 0;
-#endif
-#if GTA_VERSION < GTA3_PC_11
case COMMAND_SET_THREAT_REACTION_RANGE_MULTIPLIER:
CollectParameters(&m_nIp, 1);
-#ifdef FIX_BUGS
CPed::nThreatReactionRangeMultiplier = *(float*)&ScriptParams[0];
-#else
- CPed::nThreatReactionRangeMultiplier = (float)ScriptParams[0];
-#endif
return 0;
-#endif
+ case COMMAND_SET_CHAR_CEASE_ATTACK_TIMER:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_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:
+ 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);
+ DMAudio.SetPedTalkingStatus(CPools::GetPedPool()->GetAt(ScriptParams[0]), ScriptParams[1] == 0);
+ return 0;
+ case COMMAND_SET_ENABLE_RC_DETONATE:
+ CollectParameters(&m_nIp, 1);
+ CVehicle::bDisableRemoteDetonation = !ScriptParams[0];
+ return 0;
+ case COMMAND_SET_CAR_RANDOM_ROUTE_SEED:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ pVehicle->m_nRouteSeed = ScriptParams[1];
+ 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]);
+ script_assert(pPed);
+ pPed->ClearWeapons();
+ return 0;
+ }
+ case COMMAND_HAS_PLAYER_GOT_WEAPON:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_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]);
+ script_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]);
+ script_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:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ bool bIsBurst = false;
+ CBike* pBike = (CBike*)pVehicle;
+ if (pVehicle->IsBike()) {
+ if (ScriptParams[1] == 4) {
+ for (int i = 0; i < 2; i++) {
+ if (pBike->m_wheelStatus[i] == WHEEL_STATUS_BURST)
+ bIsBurst = true;
+ }
+ }
+ else {
+ if (ScriptParams[1] == 2)
+ ScriptParams[1] = 0;
+ if (ScriptParams[1] == 3)
+ ScriptParams[1] = 1;
+ bIsBurst = pBike->m_wheelStatus[ScriptParams[1]] == WHEEL_STATUS_BURST;
+ }
+ }
+ 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);
+ return 0;
+ }
+ //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: {
+ CollectParameters(&m_nIp, 2);
+ int32 counter = 0;
+ while (counter < 3 && CScriptPaths::aArray[counter].m_state != SCRIPT_PATH_DISABLED) {
+ counter++;
+ }
+ CScriptPaths::aArray[counter].InitialiseOne(ScriptParams[0], *(float*)&ScriptParams[1]);
+ ScriptParams[0] = counter;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_START_OBJECT_ON_PATH:
+ {
+ CollectParameters(&m_nIp, 2);
+ CObject *pObj = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ assert(pObj);
+ CScriptPaths::aArray[ScriptParams[1]].SetObjectToControl(pObj);
+ return 0;
+ }
+ case COMMAND_SET_OBJECT_PATH_SPEED:
+ {
+ CollectParameters(&m_nIp, 2);
+ CScriptPaths::aArray[ScriptParams[0]].m_fSpeed = *(float*)&ScriptParams[1];
+ return 0;
+ }
+ case COMMAND_SET_OBJECT_PATH_POSITION:
+ {
+ CollectParameters(&m_nIp, 2);
+ CScriptPaths::aArray[ScriptParams[0]].m_fPosition = *(float*)&ScriptParams[1];
+ return 0;
+ }
+ //case COMMAND_GET_OBJECT_DISTANCE_ALONG_PATH:
+ case COMMAND_CLEAR_OBJECT_PATH:
+ {
+ CollectParameters(&m_nIp, 1);
+ CScriptPaths::aArray[ScriptParams[0]].Clear();
+ return 0;
+ }
+ case COMMAND_HELI_GOTO_COORDS:
+ {
+ CollectParameters(&m_nIp, 5);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_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;
+ CPickups::GetActualPickupIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
+ 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]);
+ script_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;
+ script_assert(pPed);
+ UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_BOAT);
+ return 0;
+ }
+ case COMMAND_IS_CHAR_IN_ANY_HELI:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_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;
+ script_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]);
+ script_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;
+ script_assert(pPed);
+ UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI);
+ return 0;
+ }
+ case COMMAND_IS_CHAR_IN_WATER:
+ {
+ 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);
+ CollectParameters(&m_nIp, 1);
+ *ptr = ScriptParams[0];
+ return 0;
+ }
+ case COMMAND_SET_LVAR_INT_TO_CONSTANT:
+ {
+ int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL);
+ CollectParameters(&m_nIp, 1);
+ *ptr = ScriptParams[0];
+ return 0;
+ }
default:
script_assert(0);
}
diff --git a/src/control/Script7.cpp b/src/control/Script7.cpp
new file mode 100644
index 00000000..71099cc4
--- /dev/null
+++ b/src/control/Script7.cpp
@@ -0,0 +1,1404 @@
+#include "common.h"
+
+#include "Script.h"
+#include "ScriptCommands.h"
+
+#include "CarCtrl.h"
+#include "ColStore.h"
+#include "Coronas.h"
+#include "CutsceneMgr.h"
+#include "DMAudio.h"
+#include "Explosion.h"
+#include "GameLogic.h"
+#include "General.h"
+#include "Glass.h"
+#include "Fluff.h"
+#include "Hud.h"
+#include "MBlur.h"
+#include "Pad.h"
+#include "Pickups.h"
+#include "Pools.h"
+#include "Population.h"
+#include "Radar.h"
+#include "RoadBlocks.h"
+#include "Ropes.h"
+#include "SetPieces.h"
+#include "SpecialFX.h"
+#include "Stats.h"
+#include "Streaming.h"
+#include "Timecycle.h"
+#include "User.h"
+#include "World.h"
+#include "Zones.h"
+
+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_GLOBAL);
+ 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]);
+ script_assert(pPed);
+ ScriptParams[0] = pPed->GetWeapon(ScriptParams[1] - 1).m_eWeaponType;
+ ScriptParams[1] = pPed->GetWeapon(ScriptParams[1] - 1).m_nAmmoTotal;
+ ScriptParams[2] = CPickups::ModelForWeapon((eWeaponType)ScriptParams[0]);
+ StoreParameters(&m_nIp, 3);
+ return 0;
+ }
+ case COMMAND_GET_CLOSEST_STRAIGHT_ROAD:
+ {
+ CollectParameters(&m_nIp, 5);
+ int node1, node2;
+ float angle;
+ ThePaths.FindNodePairClosestToCoors(*(CVector*)&ScriptParams[0], PATH_CAR, &node1, &node2, &angle,
+ *(float*)&ScriptParams[3], *(float*)&ScriptParams[4], true, true);
+ if (node1 == -1) {
+ for (int i = 0; i < 7; i++)
+ ScriptParams[i] = 0;
+ }
+ else {
+ *(CVector*)&ScriptParams[0] = ThePaths.FindNodeCoorsForScript(node1);
+ *(CVector*)&ScriptParams[3] = ThePaths.FindNodeCoorsForScript(node2);
+ *(float*)&ScriptParams[6] = angle;
+ }
+ StoreParameters(&m_nIp, 7);
+ return 0;
+ }
+ case COMMAND_SET_CAR_FORWARD_SPEED:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ float speed = *(float*)&ScriptParams[1] / GAME_SPEED_TO_CARAI_SPEED;
+ pVehicle->SetMoveSpeed(pVehicle->GetForward() * speed);
+ if (pVehicle->IsRealHeli() && pVehicle->IsCar())
+ ((CAutomobile*)pVehicle)->m_aWheelSpeed[1] = 0.22f;
+ return 0;
+ }
+ case COMMAND_SET_AREA_VISIBLE:
+ CollectParameters(&m_nIp, 1);
+ CGame::currArea = ScriptParams[0];
+ CStreaming::RemoveBuildingsNotInArea(ScriptParams[0]);
+ return 0;
+ case COMMAND_SET_CUTSCENE_ANIM_TO_LOOP:
+ {
+ char key[KEY_LENGTH_IN_SCRIPT];
+ CTheScripts::ReadTextLabelFromScript(&m_nIp, key);
+ m_nIp += KEY_LENGTH_IN_SCRIPT;
+ CCutsceneMgr::SetCutsceneAnimToLoop(key);
+ return 0;
+ }
+ case COMMAND_MARK_CAR_AS_CONVOY_CAR:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ pVehicle->bPartOfConvoy = ScriptParams[1];
+ 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);
+ CRoadBlocks::RegisterScriptRoadBlock(*(CVector*)&ScriptParams[0], *(CVector*)&ScriptParams[3]);
+ return 0;
+ }
+ case COMMAND_CLEAR_ALL_SCRIPT_ROADBLOCKS:
+ {
+ CRoadBlocks::ClearScriptRoadBlocks();
+ return 0;
+ }
+ case COMMAND_SET_CHAR_OBJ_WALK_TO_CHAR:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ CPed* pTargetPed = CPools::GetPedPool()->GetAt(ScriptParams[1]);
+ script_assert(pTargetPed);
+ pPed->bScriptObjectiveCompleted = false;
+ pPed->SetObjective(OBJECTIVE_GOTO_CHAR_ON_FOOT_WALKING, pTargetPed);
+ 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]);
+ script_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]);
+ script_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]);
+ script_assert(pPed);
+ CPed* pTargetPed = CPools::GetPedPool()->GetAt(ScriptParams[1]);
+ script_assert(pTargetPed);
+ pPed->bScriptObjectiveCompleted = false;
+ pPed->SetObjective(OBJECTIVE_AIM_GUN_AT, pTargetPed);
+ return 0;
+ }
+ case COMMAND_SWITCH_SECURITY_CAMERA:
+ {
+ CollectParameters(&m_nIp, 1);
+ CSpecialFX::bVideoCam = ScriptParams[0] != 0;
+ return 0;
+ }
+ //case COMMAND_IS_CHAR_IN_FLYING_VEHICLE:
+ case COMMAND_IS_PLAYER_IN_FLYING_VEHICLE:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_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);
+ CVector pos = *(CVector*)&ScriptParams[0];
+ if (pos.z <= MAP_Z_LOW_LIMIT)
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
+ CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
+ int id = CRadar::SetShortRangeCoordBlip(BLIP_COORD, pos, 5, BLIP_DISPLAY_BOTH);
+ CRadar::SetBlipSprite(id, ScriptParams[3]);
+ ScriptParams[0] = id;
+ StoreParameters(&m_nIp, 1);
+ 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);
+ CAutomobile* pHeli = (CAutomobile*)CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pHeli && pHeli->IsCar() && pHeli->IsRealHeli());
+ float fAngle = DEGTORAD(*(float*)&ScriptParams[1] - 90.0f);
+ while (fAngle < 0.0f)
+ fAngle += TWOPI;
+ while (fAngle > TWOPI)
+ fAngle -= TWOPI;
+ pHeli->SetHeliOrientation(fAngle);
+ return 0;
+ }
+ case COMMAND_CLEAR_HELI_ORIENTATION:
+ {
+ CollectParameters(&m_nIp, 1);
+ CAutomobile* pHeli = (CAutomobile*)CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pHeli && pHeli->IsCar() && pHeli->IsRealHeli());
+ pHeli->ClearHeliOrientation();
+ return 0;
+ }
+ case COMMAND_PLANE_GOTO_COORDS:
+ {
+ CollectParameters(&m_nIp, 5);
+ CAutomobile* pPlane = (CAutomobile*)CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pPlane && pPlane->IsCar() && pPlane->IsRealPlane());
+ pPlane->TellPlaneToGoToCoors(*(float*)&ScriptParams[1], *(float*)&ScriptParams[2], *(float*)&ScriptParams[3], ScriptParams[4]);
+ return 0;
+ }
+ case COMMAND_GET_NTH_CLOSEST_CAR_NODE:
+ {
+ CollectParameters(&m_nIp, 4);
+ CVector pos = *(CVector*)&ScriptParams[0];
+ if (pos.z <= MAP_Z_LOW_LIMIT)
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
+ *(CVector*)&ScriptParams[0] = ThePaths.FindNodeCoorsForScript(ThePaths.FindNthNodeClosestToCoors(pos, 0, 999999.9f, true, true, ScriptParams[3] - 1));
+ StoreParameters(&m_nIp, 3);
+ 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]);
+ script_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]);
+ script_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]);
+ script_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]);
+ script_assert(pObject);
+ UpdateCompareFlag(pObject->m_nCollisionRecords != 0);
+ return 0;
+ }
+ case COMMAND_REMOVE_RC_BUGGY:
+ {
+ CWorld::Players[CWorld::PlayerInFocus].BlowUpRCBuggy(false);
+ return 0;
+ }
+ //case COMMAND_HAS_PHOTOGRAPH_BEEN_TAKEN:
+ case COMMAND_GET_CHAR_ARMOUR:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_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]);
+ script_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]);
+ script_assert(pVehicle);
+ pVehicle->AutoPilot.m_nSwitchDistance = ScriptParams[1];
+ return 0;
+ }
+ case COMMAND_POP_CAR_BOOT:
+ {
+ CollectParameters(&m_nIp, 1);
+ CAutomobile* pCar = (CAutomobile*)CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pCar&& pCar->IsCar());
+ pCar->PopBoot();
+ return 0;
+ }
+ case COMMAND_SHUT_PLAYER_UP:
+ {
+ CollectParameters(&m_nIp, 2);
+ DMAudio.ShutUpPlayerTalking(!!ScriptParams[1]);
+ return 0;
+ }
+ case COMMAND_SET_PLAYER_MOOD:
+ {
+ CollectParameters(&m_nIp, 3);
+ DMAudio.SetPlayersMood(ScriptParams[1], ScriptParams[2]);
+ return 0;
+ }
+ case COMMAND_REQUEST_COLLISION:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVector2D pos;
+ pos.x = *(float*)&ScriptParams[0];
+ pos.y = *(float*)&ScriptParams[1];
+ CColStore::RequestCollision(pos);
+ return 0;
+ }
+ case COMMAND_LOCATE_OBJECT_2D:
+ case COMMAND_LOCATE_OBJECT_3D:
+ LocateObjectCommand(command, &m_nIp);
+ return 0;
+ case COMMAND_IS_OBJECT_IN_WATER:
+ {
+ CollectParameters(&m_nIp, 1);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ script_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_SET_CHAR_CROUCH:
+ {
+ CollectParameters(&m_nIp, 3);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ if (ScriptParams[1]) {
+ pPed->bCrouchWhenShooting = true;
+ pPed->SetDuck(ScriptParams[2], true);
+ }
+ else {
+ pPed->ClearDuck(true);
+ pPed->bCrouchWhenShooting = false;
+ }
+ return 0;
+ }
+ case COMMAND_SET_ZONE_CIVILIAN_CAR_INFO:
+ {
+ char label[12];
+ int16 carDensities[CCarCtrl::NUM_CAR_CLASSES] = { 0 };
+ int16 boatDensities[CCarCtrl::NUM_BOAT_CLASSES] = { 0 };
+ int i;
+
+ CTheScripts::ReadTextLabelFromScript(&m_nIp, label);
+ m_nIp += KEY_LENGTH_IN_SCRIPT;
+ CollectParameters(&m_nIp, 12);
+ for (i = 0; i < CCarCtrl::NUM_CAR_CLASSES; i++)
+ carDensities[i] = ScriptParams[i + 1];
+ for (i = 0; i < CCarCtrl::NUM_BOAT_CLASSES; i++)
+ boatDensities[i] = ScriptParams[i + 1 + CCarCtrl::NUM_CAR_CLASSES];
+ int zone = CTheZones::FindZoneByLabelAndReturnIndex(label, ZONE_INFO);
+ if (zone < 0) {
+ debug("Couldn't find zone - %s\n", label);
+ return 0;
+ }
+ while (zone >= 0) {
+ CTheZones::SetZoneCivilianCarInfo(zone, ScriptParams[0], carDensities, boatDensities);
+ zone = CTheZones::FindNextZoneByLabelAndReturnIndex(label, ZONE_INFO);
+ }
+ 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]);
+ script_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]);
+ script_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]);
+ script_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]);
+ pPed->PedShuffle();
+ return 0;
+ }
+ case COMMAND_ATTACH_CHAR_TO_OBJECT:
+ {
+ CollectParameters(&m_nIp, 8);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[1]);
+ pPed->AttachPedToEntity(pObject, *(CVector*)&ScriptParams[2], ScriptParams[5], DEGTORAD(ScriptParams[6]), (eWeaponType)ScriptParams[7]);
+ return 0;
+ }
+ case COMMAND_SET_CHAR_AS_PLAYER_FRIEND:
+ {
+ CollectParameters(&m_nIp, 3);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_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];
+ script_assert(CTheScripts::ScriptSpace[m_nIp++] == ARGUMENT_GLOBALVAR);
+ uint16 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);
+ CTimeCycle::StartExtraColour(ScriptParams[0]-1, ScriptParams[1] != 0);
+ return 0;
+ }
+ case COMMAND_CLEAR_EXTRA_COLOURS:
+ {
+ CollectParameters(&m_nIp, 1);
+ CTimeCycle::StopExtraColour(ScriptParams[0]);
+ return 0;
+ }
+ //case COMMAND_CLOSE_CAR_BOOT:
+ case COMMAND_GET_WHEELIE_STATS:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
+ ScriptParams[0] = pPlayerInfo->m_nLastTimeCarSpentOnTwoWheels;
+ *(float*)&ScriptParams[1] = pPlayerInfo->m_nLastDistanceCarTravelledOnTwoWheels;
+ ScriptParams[2] = pPlayerInfo->m_nLastTimeSpentOnWheelie;
+ *(float*)&ScriptParams[3] = pPlayerInfo->m_nLastDistanceTravelledOnWheelie;
+ ScriptParams[4] = pPlayerInfo->m_nLastTimeSpentOnStoppie;
+ *(float*)&ScriptParams[5] = pPlayerInfo->m_nLastDistanceTravelledOnStoppie;
+ StoreParameters(&m_nIp, 6);
+ pPlayerInfo->m_nLastTimeCarSpentOnTwoWheels = 0;
+ pPlayerInfo->m_nLastDistanceCarTravelledOnTwoWheels = 0.0f;
+ pPlayerInfo->m_nLastTimeSpentOnWheelie = 0;
+ pPlayerInfo->m_nLastDistanceTravelledOnWheelie = 0.0f;
+ pPlayerInfo->m_nLastTimeSpentOnStoppie = 0;
+ pPlayerInfo->m_nLastDistanceTravelledOnStoppie = 0.0f;
+ 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);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_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;
+ script_assert(pPed);
+ UpdateCompareFlag(strcmp(key, CModelInfo::GetModelInfo(pPed->GetModelIndex())->GetModelName()) == 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]);
+ script_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;
+ pPed->SetObjective(OBJECTIVE_SPRINT_TO_AREA, pos);
+ return 0;
+ }
+ case COMMAND_CREATE_SWAT_ROPE:
+ {
+ CollectParameters(&m_nIp, 3);
+ CRopes::CreateRopeWithSwatComingDown(*(CVector*)&ScriptParams[0]);
+ 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);
+ CSpecialFX::bLiftCam = ScriptParams[0] != 0;
+ return 0;
+ }
+ case COMMAND_CLOSE_ALL_CAR_DOORS:
+ {
+ CollectParameters(&m_nIp, 1);
+ CAutomobile* pCar = (CAutomobile*)CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pCar&& pCar->IsCar());
+ pCar->CloseAllDoors();
+ 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:
+ {
+ CollectParameters(&m_nIp, 1);
+ CAutomobile* pCar = (CAutomobile*)CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pCar && pCar->IsCar());
+ pCar->PopBootUsingPhysics();
+ 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]);
+ script_assert(pPed);
+ UpdateCompareFlag(pPed->m_objective == OBJECTIVE_LEAVE_CAR_AND_DIE);
+ return 0;
+ }
+ case COMMAND_SORT_OUT_OBJECT_COLLISION_WITH_CAR:
+ {
+ CollectParameters(&m_nIp, 2);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ script_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:
+ {
+ CollectParameters(&m_nIp, 5);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_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:
+ {
+ wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ CHud::SetHelpMessage(text, false, true);
+ return 0;
+ }
+ //case COMMAND_PRINT_HELP_FOREVER_WITH_NUMBER:
+ default:
+ script_assert(0);
+ }
+ return -1;
+}
+
+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]);
+ script_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:
+ return 0;
+ //case COMMAND_IS_MISSION_AUDIO_PLAYING:
+ case COMMAND_CREATE_LOCKED_PROPERTY_PICKUP:
+ {
+ CollectParameters(&m_nIp, 3);
+ CVector pos = *(CVector*)&ScriptParams[0];
+ if (pos.z <= MAP_Z_LOW_LIMIT)
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y) + PICKUP_PLACEMENT_OFFSET;
+ char key[KEY_LENGTH_IN_SCRIPT];
+ CTheScripts::ReadTextLabelFromScript(&m_nIp, key);
+ m_nIp += KEY_LENGTH_IN_SCRIPT;
+ // TheText.Get(key);
+ CPickups::GetActualPickupIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
+ ScriptParams[0] = CPickups::GenerateNewOne(pos, MI_PICKUP_PROPERTY, PICKUP_PROPERTY_LOCKED, 0, 0, false, key);
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_CREATE_FORSALE_PROPERTY_PICKUP:
+ {
+ 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;
+ char key[KEY_LENGTH_IN_SCRIPT];
+ CTheScripts::ReadTextLabelFromScript(&m_nIp, key);
+ m_nIp += KEY_LENGTH_IN_SCRIPT;
+ // TheText.Get(key);
+ CPickups::GetActualPickupIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
+ ScriptParams[0] = CPickups::GenerateNewOne(pos, MI_PICKUP_PROPERTY_FORSALE, PICKUP_PROPERTY_FORSALE, ScriptParams[3], 0, false, key);
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_FREEZE_CAR_POSITION:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ pVehicle->bIsFrozen = ScriptParams[1];
+ pVehicle->bInfiniteMass = ScriptParams[1];
+ return 0;
+ }
+ case COMMAND_HAS_CHAR_BEEN_DAMAGED_BY_CHAR:
+ {
+ 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:
+ {
+ CCutsceneMgr::DisableCutsceneShadows();
+ return 0;
+ }
+ case COMMAND_HAS_GLASS_BEEN_SHATTERED_NEARBY:
+ {
+ CollectParameters(&m_nIp, 3);
+
+ bool shattered = false;
+ if ( CGlass::HasGlassBeenShatteredAtCoors(*(float*)&ScriptParams[0], *(float*)&ScriptParams[1], *(float*)&ScriptParams[2]) )
+ shattered = true;
+
+ UpdateCompareFlag(shattered);
+ return 0;
+ }
+ case COMMAND_ATTACH_CUTSCENE_OBJECT_TO_BONE:
+ {
+ CollectParameters(&m_nIp, 3);
+ CCutsceneMgr::AttachObjectToBone(CPools::GetObjectPool()->GetAt(ScriptParams[0]), CPools::GetObjectPool()->GetAt(ScriptParams[1]), ScriptParams[2]);
+ return 0;
+ }
+ case COMMAND_ATTACH_CUTSCENE_OBJECT_TO_COMPONENT:
+ {
+ CollectParameters(&m_nIp, 2);
+ CObject *obj1 = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ CObject *obj2 = CPools::GetObjectPool()->GetAt(ScriptParams[1]);
+
+ char key[KEY_LENGTH_IN_SCRIPT];
+ CTheScripts::ReadTextLabelFromScript(&m_nIp, key);
+ m_nIp += KEY_LENGTH_IN_SCRIPT;
+
+ CCutsceneMgr::AttachObjectToFrame(obj1, obj2, key);
+ return 0;
+ }
+ case COMMAND_SET_CHAR_STAY_IN_CAR_WHEN_JACKED:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_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);
+ CStats::MoneySpentOnWeapons(ScriptParams[0]);
+ return 0;
+ case COMMAND_ADD_MONEY_SPENT_ON_PROPERTY:
+ CollectParameters(&m_nIp, 1);
+ CStats::MoneySpentOnProperty(ScriptParams[0]);
+ return 0;
+ //case COMMAND_ADD_MONEY_SPENT_ON_AUTO_PAINTING:
+ case COMMAND_SET_CHAR_ANSWERING_MOBILE:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ if (ScriptParams[1])
+ pPed->SetAnswerMobile();
+ else
+ pPed->ClearAnswerMobile();
+ return 0;
+ }
+ case COMMAND_SET_PLAYER_DRUNKENNESS:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
+ pPlayerInfo->m_pPed->m_nDrunkenness = ScriptParams[1];
+ pPlayerInfo->m_pPed->m_nFadeDrunkenness = 0;
+ if (pPlayerInfo->m_pPed->m_nDrunkenness == 0)
+ CMBlur::ClearDrunkBlur();
+ 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:
+ CollectParameters(&m_nIp, 1);
+ CStats::NumOfStoresKnockedOff(ScriptParams[0]);
+ return 0;
+ //case COMMAND_ADD_MOVIE_STUNTS:
+ case COMMAND_ADD_NUMBER_OF_ASSASSINATIONS:
+ CollectParameters(&m_nIp, 1);
+ CStats::NumOfAssassinations(ScriptParams[0]);
+ return 0;
+ case COMMAND_ADD_PIZZAS_DELIVERED:
+ CollectParameters(&m_nIp, 1);
+ CStats::NumOfPizzasDelivered(ScriptParams[0]);
+ return 0;
+ //case COMMAND_ADD_GARBAGE_PICKUPS:
+ case COMMAND_ADD_ICE_CREAMS_SOLD:
+ CollectParameters(&m_nIp, 1);
+ CStats::NumOfIceCreamSold(ScriptParams[0]);
+ 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]);
+ script_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]);
+ script_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]);
+ script_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;
+ script_assert(pPed);
+ pPed->bDoomAim = ScriptParams[1];
+ return 0;
+ }
+ case COMMAND_FIRE_HUNTER_GUN:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle *pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ if (CTimer::GetTimeInMilliseconds() > pVehicle->m_nGunFiringTime + 150) {
+ CWeapon gun(WEAPONTYPE_HELICANNON, 5000);
+ CVector worldGunPos = (pVehicle->GetMatrix() * vecHunterGunPos) + (CTimer::GetTimeStep() * pVehicle->m_vecMoveSpeed);
+ gun.FireInstantHit(pVehicle, &worldGunPos);
+ gun.AddGunshell(pVehicle, worldGunPos, CVector2D(0.f, 0.1f), 0.025f);
+ DMAudio.PlayOneShot(pVehicle->m_audioEntityId, SOUND_WEAPON_SHOT_FIRED, 0.f);
+ pVehicle->m_nGunFiringTime = CTimer::GetTimeInMilliseconds();
+ }
+ return 0;
+ }
+ case COMMAND_SET_PROPERTY_AS_OWNED:
+ CollectParameters(&m_nIp, 1);
+ CStats::AddPropertyAsOwned(ScriptParams[0]);
+ return 0;
+ case COMMAND_ADD_BLOOD_RING_KILLS:
+ CollectParameters(&m_nIp, 1);
+ CStats::AddNumBloodRingKills(ScriptParams[0]);
+ return 0;
+ case COMMAND_SET_LONGEST_TIME_IN_BLOOD_RING:
+ CollectParameters(&m_nIp, 1);
+ CStats::LongestTimeInBloodRing(ScriptParams[0]);
+ return 0;
+ case COMMAND_REMOVE_EVERYTHING_FOR_HUGE_CUTSCENE:
+ {
+ CCutsceneMgr::RemoveEverythingFromTheWorldForTheBiggestFuckoffCutsceneEver();
+ return 0;
+ }
+ case COMMAND_IS_PLAYER_TOUCHING_VEHICLE:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_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, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_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]);
+ script_assert(pPed);
+ pPed->bCanBeShotInVehicle = ScriptParams[1];
+ return 0;
+ }
+ case COMMAND_ATTACH_CUTSCENE_OBJECT_TO_VEHICLE:
+ {
+ CollectParameters(&m_nIp, 2);
+ CCutsceneMgr::AttachObjectToParent(CPools::GetObjectPool()->GetAt(ScriptParams[0]), CPools::GetVehiclePool()->GetAt(ScriptParams[1]));
+ 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);
+ CScrollBar::TonightsEvent = ScriptParams[0];
+ return 0;
+ }
+ case COMMAND_CLEAR_CHAR_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]);
+ script_assert(pObject);
+ pObject->bIsFrozen = ScriptParams[1];
+ pObject->bInfiniteMass = 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:
+ {
+ 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);
+ CGameLogic::SetUpShortCut(
+ *(CVector*)&ScriptParams[0], *(float*)&ScriptParams[3],
+ *(CVector*)&ScriptParams[4], *(float*)&ScriptParams[7]);
+ return 0;
+ }
+ case COMMAND_CLEAR_TAXI_SHORTCUT:
+ CGameLogic::ClearShortCut();
+ return 0;
+ //case COMMAND_SET_CHAR_OBJ_GOTO_CAR_ON_FOOT:
+ //case COMMAND_GET_CLOSEST_WATER_NODE:
+ case COMMAND_ADD_PORN_LEAFLET_TO_RUBBISH:
+ CollectParameters(&m_nIp, 1);
+ CStats::PamphletMissionPassed = ScriptParams[0];
+ return 0;
+ case COMMAND_CREATE_CLOTHES_PICKUP:
+ {
+ 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 = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_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;
+ script_assert(pPed);
+ if (pPed->bInVehicle) {
+ if (pPed->GetWeapon(WEAPONSLOT_SUBMACHINEGUN).m_eWeaponType) {
+ if (pPed->GetWeapon(WEAPONSLOT_SUBMACHINEGUN).m_nAmmoTotal < ScriptParams[1])
+ pPed->SetAmmo(pPed->GetWeapon(WEAPONSLOT_SUBMACHINEGUN).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);
+ CAutomobile* pHeli = (CAutomobile*)CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pHeli && pHeli->IsCar() && pHeli->IsRealHeli());
+ pHeli->bHeliDestroyed = true;
+ return 0;
+ }
+ case COMMAND_ADD_EXPLOSION_NO_SOUND:
+ {
+ CollectParameters(&m_nIp, 4);
+ CExplosion::AddExplosion(nil, nil, (eExplosionType)ScriptParams[3], *(CVector*)&ScriptParams[0], 0, false);
+ return 0;
+ }
+ case COMMAND_SET_OBJECT_AREA_VISIBLE:
+ {
+ CollectParameters(&m_nIp, 2);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ script_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]);
+ script_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;
+ CCutsceneMgr::LoadAnimationUncompressed(key);
+ return 0;
+ }
+ case COMMAND_WAS_CUTSCENE_SKIPPED:
+ {
+ UpdateCompareFlag(CCutsceneMgr::WasCutsceneSkipped());
+ return 0;
+ }
+ case COMMAND_SET_CHAR_CROUCH_WHEN_THREATENED:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ pPed->bCrouchWhenScared = true;
+ return 0;
+ }
+ case COMMAND_IS_CHAR_IN_ANY_POLICE_VEHICLE:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle &&
+ pPed->m_pMyVehicle->IsLawEnforcementVehicle() &&
+ pPed->m_pMyVehicle->GetModelIndex() != MI_PREDATOR);
+ return 0;
+ }
+ case COMMAND_DOES_CHAR_EXIST:
+ 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);
+ CVector pos = *(CVector*)&ScriptParams[0];
+ if (pos.z <= MAP_Z_LOW_LIMIT)
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
+ CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
+ int id = CRadar::SetShortRangeCoordBlip(BLIP_COORD, pos, 2, BLIP_DISPLAY_BOTH);
+ CRadar::SetBlipSprite(id, ScriptParams[3]);
+ ScriptParams[0] = id;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_IS_CHAR_STUCK:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ UpdateCompareFlag(pPed->m_nWaitState == WAITSTATE_STUCK);
+ return 0;
+ }
+ case COMMAND_SET_ALL_TAXIS_HAVE_NITRO:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle::bAllTaxisHaveNitro = ScriptParams[0] != 0;
+ return 0;
+ }
+ case COMMAND_SET_CHAR_STOP_SHOOT_DONT_SEEK_ENTITY:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ if (ScriptParams[1]) {
+ pPed->bKindaStayInSamePlace = true;
+ pPed->bStopAndShoot = true;
+ }
+ else {
+ pPed->bKindaStayInSamePlace = false;
+ pPed->bStopAndShoot = false;
+ }
+ pPed->m_nLastPedState = PED_NONE;
+ return 0;
+ }
+ case COMMAND_FREEZE_CAR_POSITION_AND_DONT_LOAD_COLLISION:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_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:
+ script_assert(0);
+ }
+ return -1;
+}
diff --git a/src/control/Script8.cpp b/src/control/Script8.cpp
new file mode 100644
index 00000000..98f69737
--- /dev/null
+++ b/src/control/Script8.cpp
@@ -0,0 +1,618 @@
+#include "common.h"
+
+#include "Script.h"
+#include "ScriptCommands.h"
+
+#include "DMAudio.h"
+#if ((defined GTAVC_JP_PATCH || defined SUPPORT_JAPANESE_SCRIPT) && defined MORE_LANGUAGES)
+#include "Frontend.h"
+#endif
+#include "GameLogic.h"
+#include "Garages.h"
+#ifdef MISSION_REPLAY
+#include "GenericGameStorage.h"
+#endif
+#if (defined GTA_PC && !defined GTAVC_JP_PATCH || defined GTA_XBOX || defined SUPPORT_XBOX_SCRIPT || defined GTA_MOBILE || defined SUPPORT_MOBILE_SCRIPT)
+#include "General.h"
+#include "maths.h"
+#endif
+#include "Hud.h"
+#include "Pad.h"
+#include "PedAttractor.h"
+#include "Population.h"
+#include "Pools.h"
+#include "RpAnimBlend.h"
+#include "Stats.h"
+#include "VisibilityPlugins.h"
+#include "Wanted.h"
+#include "WaterLevel.h"
+#include "World.h"
+#include "Zones.h"
+
+int8 CRunningScript::ProcessCommands1400To1499(int32 command)
+{
+ switch (command) {
+ case COMMAND_REGISTER_VIGILANTE_LEVEL:
+ CollectParameters(&m_nIp, 1);
+ CStats::RegisterLevelVigilanteMission(ScriptParams[0]);
+ return 0;
+ case COMMAND_CLEAR_ALL_CHAR_ANIMS:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_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_STD_IDLE);
+ pPed->bIsPedDieAnimPlaying = false;
+ }
+ return 0;
+ }
+ case COMMAND_SET_MAXIMUM_NUMBER_OF_CARS_IN_GARAGE:
+ CollectParameters(&m_nIp, 2);
+ CGarages::SetMaxNumStoredCarsForGarage(ScriptParams[0], ScriptParams[1]);
+ return 0;
+ case COMMAND_WANTED_STARS_ARE_FLASHING:
+ {
+ CWanted* pWanted = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted;
+ UpdateCompareFlag(pWanted->m_nMinWantedLevel - pWanted->GetWantedLevel() > 0);
+ 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);
+ DMAudio.PlayRadioAnnouncement(ScriptParams[0] + STREAMED_SOUND_ANNOUNCE_BRIDGE_CLOSED);
+ 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);
+ CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
+ ScriptParams[0] = pPlayerInfo->m_pPed->m_nLastBusFareCollected;
+ pPlayerInfo->m_pPed->m_nLastBusFareCollected = 0;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_SET_CHAR_OBJ_BUY_ICE_CREAM:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
+ script_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 (pEffect) {
+ CVector pos;
+ CPedAttractorManager::ComputeEffectPos(pEffect, pVehicle->GetMatrix(), pos);
+ if ((pPed->GetPosition() - 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);
+ CHud::m_HideRadar = ScriptParams[0] == 0;
+ return 0;
+ case COMMAND_REGISTER_BEST_POSITION:
+ CollectParameters(&m_nIp, 2);
+ CStats::RegisterBestPosition(ScriptParams[0], ScriptParams[1]);
+ return 0;
+ case COMMAND_IS_PLAYER_IN_INFO_ZONE:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
+ char key[KEY_LENGTH_IN_SCRIPT];
+ memset(key, 0, KEY_LENGTH_IN_SCRIPT);
+ CTheScripts::ReadTextLabelFromScript(&m_nIp, key);
+ m_nIp += KEY_LENGTH_IN_SCRIPT;
+ CVector pos = pPlayerInfo->GetPos();
+ CZone* infoZone = CTheZones::FindInformationZoneForPosition(&pos);
+ UpdateCompareFlag(strncmp(key, infoZone->name, 8) == 0); // original code doesn't seem to be using strncmp in here and compare 2 ints instead
+ return 0;
+ }
+ case COMMAND_CLEAR_CHAR_ICE_CREAM_PURCHASE:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_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]);
+ script_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]);
+ script_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->GetIsStatic())
+ pVehicle->AddToMovingList();
+ }
+ }
+ return 0;
+ }
+ case COMMAND_SET_LOAD_COLLISION_FOR_CHAR_FLAG:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_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->GetIsStatic())
+ pPed->AddToMovingList();
+ }
+ }
+ return 0;
+ }
+ //case COMMAND_SET_LOAD_COLLISION_FOR_OBJECT_FLAG:
+ case COMMAND_ADD_BIG_GUN_FLASH:
+ {
+ CollectParameters(&m_nIp, 6);
+ CWeapon::AddGunFlashBigGuns(*(CVector*)&ScriptParams[0], *(CVector*)&ScriptParams[3]);
+ return 0;
+ }
+ case COMMAND_HAS_CHAR_BOUGHT_ICE_CREAM:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_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);
+ CGameLogic::AddShortCutPointAfterDeath(*(CVector*)&ScriptParams[0], *(float*)&ScriptParams[3]);
+ return 0;
+ }
+ case COMMAND_SET_SHORTCUT_DROPOFF_POINT_FOR_MISSION:
+ {
+ CollectParameters(&m_nIp, 4);
+ CGameLogic::AddShortCutDropOffPointForMission(*(CVector*)&ScriptParams[0], *(float*)&ScriptParams[3]);
+ return 0;
+ }
+ case COMMAND_GET_RANDOM_ICE_CREAM_CUSTOMER_IN_AREA:
+ {
+ CollectParameters(&m_nIp, 7);
+ int ped_handle = -1;
+ CVector pos = FindPlayerCoors();
+ float x1 = *(float*)&ScriptParams[0];
+ float y1 = *(float*)&ScriptParams[1];
+ float x2 = *(float*)&ScriptParams[2];
+ float y2 = *(float*)&ScriptParams[3];
+ int i = CPools::GetPedPool()->GetSize();
+ while (--i && ped_handle == -1) {
+ CPed* pPed = CPools::GetPedPool()->GetSlot(i);
+ if (!pPed)
+ continue;
+ if (CTheScripts::LastRandomPedId == CPools::GetPedPool()->GetIndex(pPed))
+ continue;
+ if (pPed->CharCreatedBy != RANDOM_CHAR)
+ continue;
+ if (!pPed->IsPedInControl())
+ continue;
+ if (pPed->bRemoveFromWorld)
+ continue;
+ if (pPed->bFadeOut)
+ continue;
+ if (pPed->m_nWaitState != WAITSTATE_FALSE)
+ continue;
+ if (pPed->bHasAlreadyUsedAttractor)
+ continue;
+ if (pPed->m_attractor)
+ continue;
+ if (!ThisIsAValidRandomPed(pPed->m_nPedType, ScriptParams[4], ScriptParams[5], ScriptParams[6]))
+ continue;
+ if (pPed->bIsLeader || pPed->m_leader)
+ continue;
+ if (!pPed->IsWithinArea(x1, y1, x2, y2))
+ continue;
+ if (pos.z - PED_FIND_Z_OFFSET > pPed->GetPosition().z)
+ continue;
+ if (pos.z + PED_FIND_Z_OFFSET < pPed->GetPosition().z)
+ continue;
+ ped_handle = CPools::GetPedPool()->GetIndex(pPed);
+ CTheScripts::LastRandomPedId = ped_handle;
+ pPed->CharCreatedBy = MISSION_CHAR;
+ pPed->bRespondsToThreats = false;
+ ++CPopulation::ms_nTotalMissionPeds;
+ if (m_bIsMissionScript)
+ CTheScripts::MissionCleanUp.AddEntityToList(ped_handle, CLEANUP_CHAR);
+ }
+ ScriptParams[0] = ped_handle;
+ 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);
+ 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->IsWithinArea(infX, infY, supX, supY))
+ pVehicle->m_nDoorLock = CARLOCK_UNLOCKED;
+ }
+ 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:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ pPed->bHeldHostageInCar = ScriptParams[1];
+ return 0;
+ }
+ case COMMAND_SET_VEHICLE_TO_FADE_IN:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_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();
+ return 0;
+ case COMMAND_IS_PLAYER_IN_SHORTCUT_TAXI:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_assert(pPed);
+ UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle && pPed->m_pMyVehicle == CGameLogic::pShortCutTaxi);
+ return 0;
+ }
+ case COMMAND_IS_CHAR_DUCKING:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ UpdateCompareFlag(RpAnimBlendClumpGetAssociation(pPed->GetClump(), ANIM_STD_DUCK_DOWN) != nil);
+ return 0;
+ }
+ case COMMAND_CREATE_DUST_EFFECT_FOR_CUTSCENE_HELI:
+ {
+ CollectParameters(&m_nIp, 3);
+ CObject* pHeli = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ bool found = false;
+ float waterLevel = -1000.0f;
+ CVector pos = pHeli->GetPosition();
+ float radius = *(float*)&ScriptParams[1];
+ float ground = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z, &found);
+ if (!CWaterLevel::GetWaterLevel(pos.x, pos.y, pos.z, &waterLevel, false))
+ waterLevel = 0.0f;
+ if (waterLevel > ground)
+ ground = waterLevel;
+ if (ScriptParams[2] > 8)
+ ScriptParams[2] = 8;
+ CVehicle::HeliDustGenerate(pHeli, (pos.z - ground - 1.0f - radius) * 0.3 + radius, ground, ScriptParams[2]);
+ return 0;
+ }
+ case COMMAND_REGISTER_FIRE_LEVEL:
+ CollectParameters(&m_nIp, 1);
+ CStats::RegisterLevelFireMission(ScriptParams[0]);
+ return 0;
+ case COMMAND_IS_AUSTRALIAN_GAME:
+ UpdateCompareFlag(false); // should we make some check?
+ return 0;
+ 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;
+ }
+#if (defined GTAVC_JP_PATCH || defined SUPPORT_JAPANESE_SCRIPT)
+ case COMMAND_IS_JAPANESE_GAME:
+#ifdef MORE_LANGUAGES
+ UpdateCompareFlag(FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_JAPANESE);
+#elif (defined GTAVC_JP_PATCH)
+ UpdateCompareFlag(true);
+#else
+ UpdateCompareFlag(false);
+#endif
+ return 0;
+#elif (!defined GTA_PS2)
+ case COMMAND_SET_ONSCREEN_COUNTER_FLASH_WHEN_FIRST_DISPLAYED:
+ {
+ script_assert(CTheScripts::ScriptSpace[m_nIp++] == ARGUMENT_GLOBALVAR);
+ uint16 var = CTheScripts::Read2BytesFromScript(&m_nIp);
+ CollectParameters(&m_nIp, 1);
+ //CUserDisplay::OnscnTimer.SetCounterFlashWhenFirstDisplayed(var, ScriptParams[0]);
+ return 0;
+ }
+#endif
+#if (defined GTA_PC && !defined GTAVC_JP_PATCH || defined GTA_XBOX || defined SUPPORT_XBOX_SCRIPT || defined GTA_MOBILE || defined SUPPORT_MOBILE_SCRIPT)
+ case COMMAND_SHUFFLE_CARD_DECKS:
+ {
+ CollectParameters(&m_nIp, 1);
+ script_assert(ScriptParams[0] >= 0 && ScriptParams[0] <= 6);
+ for (int i = 0; i < CARDS_IN_STACK; i++)
+ CTheScripts::CardStack[i] = 0;
+ int16 seq[CARDS_IN_STACK];
+ for (int i = 0; i < MAX_DECKS * CARDS_IN_DECK; i++)
+ seq[i] = i;
+ int cards_left = CARDS_IN_DECK * ScriptParams[0];
+ for (int k = 1; k < CARDS_IN_DECK + 1; k++) {
+ for (int deck = 0; deck < ScriptParams[0]; deck++) {
+ int index = CGeneral::GetRandomNumberInRange(0, cards_left);
+ CTheScripts::CardStack[seq[index]] = k;
+ for (int l = index; l < cards_left; l++) {
+ if (l + 1 < CARDS_IN_STACK)
+ seq[l] = seq[l + 1];
+ else
+ seq[l] = 0;
+ }
+ --cards_left;
+ }
+ }
+ CTheScripts::CardStackPosition = 0;
+ return 0;
+ }
+ case COMMAND_FETCH_NEXT_CARD:
+ {
+ if (CTheScripts::CardStack[CTheScripts::CardStackPosition] == 0)
+ CTheScripts::CardStackPosition = 0;
+ ScriptParams[0] = CTheScripts::CardStack[CTheScripts::CardStackPosition++];
+ if (CTheScripts::CardStackPosition == CARDS_IN_DECK * MAX_DECKS)
+ CTheScripts::CardStackPosition = 0;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_GET_OBJECT_VELOCITY:
+ {
+ CollectParameters(&m_nIp, 1);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ *(CVector*)&ScriptParams[0] = GAME_SPEED_TO_METERS_PER_SECOND * pObject->GetMoveSpeed();
+ StoreParameters(&m_nIp, 3);
+ return 0;
+ }
+ case COMMAND_IS_DEBUG_CAMERA_ON:
+ UpdateCompareFlag(TheCamera.WorldViewerBeingUsed);
+ return 0;
+ case COMMAND_ADD_TO_OBJECT_ROTATION_VELOCITY:
+ {
+ CollectParameters(&m_nIp, 4);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ CVector newSpeed = pObject->GetTurnSpeed() + *(CVector*)&ScriptParams[1] / GAME_SPEED_TO_METERS_PER_SECOND;
+ if (pObject->bIsStatic) {
+ pObject->SetIsStatic(false);
+ pObject->AddToMovingList();
+ }
+ pObject->SetTurnSpeed(newSpeed.x, newSpeed.y, newSpeed.z);
+ return 0;
+ }
+ case COMMAND_SET_OBJECT_ROTATION_VELOCITY:
+ {
+ CollectParameters(&m_nIp, 4);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ CVector newSpeed = *(CVector*)&ScriptParams[1] / GAME_SPEED_TO_METERS_PER_SECOND;
+ if (pObject->bIsStatic) {
+ pObject->SetIsStatic(false);
+ pObject->AddToMovingList();
+ }
+ pObject->SetTurnSpeed(newSpeed.x, newSpeed.y, newSpeed.z);
+ return 0;
+ }
+ case COMMAND_IS_OBJECT_STATIC:
+ {
+ CollectParameters(&m_nIp, 1);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ UpdateCompareFlag(pObject->GetIsStatic());
+ return 0;
+ }
+ case COMMAND_GET_ANGLE_BETWEEN_2D_VECTORS:
+ {
+ CollectParameters(&m_nIp, 4);
+ CVector2D v1 = *(CVector2D*)&ScriptParams[0];
+ CVector2D v2 = *(CVector2D*)&ScriptParams[2];
+ float c = DotProduct2D(v1, v2) / (v1.Magnitude() * v2.Magnitude());
+#ifdef FIX_BUGS // command is a SA leftover where it was fixed to this
+ *(float*)&ScriptParams[0] = RADTODEG(Acos(c));
+#else
+ *(float*)&ScriptParams[0] = Acos(c);
+#endif
+ return 0;
+ }
+ case COMMAND_DO_2D_RECTANGLES_COLLIDE:
+ {
+ CollectParameters(&m_nIp, 8);
+ float infX1 = *(float*)&ScriptParams[0] - *(float*)&ScriptParams[2] * 0.5; // NB: not float
+ float supX1 = *(float*)&ScriptParams[0] + *(float*)&ScriptParams[2] * 0.5;
+ float infX2 = *(float*)&ScriptParams[4] - *(float*)&ScriptParams[6] * 0.5;
+ float supX2 = *(float*)&ScriptParams[4] + *(float*)&ScriptParams[6] * 0.5;
+ float infY1 = *(float*)&ScriptParams[1] - *(float*)&ScriptParams[3] * 0.5;
+ float supY1 = *(float*)&ScriptParams[1] + *(float*)&ScriptParams[3] * 0.5;
+ float infY2 = *(float*)&ScriptParams[5] - *(float*)&ScriptParams[7] * 0.5;
+ float supY2 = *(float*)&ScriptParams[5] + *(float*)&ScriptParams[7] * 0.5;
+ bool collide = true;
+ if (infY2 > supY1)
+ collide = false;
+ if (infY1 > supY2)
+ collide = false;
+ if (infX2 > supX1)
+ collide = false;
+ if (infX1 > supX2)
+ collide = false;
+ UpdateCompareFlag(collide);
+ return 0;
+ }
+ case COMMAND_GET_OBJECT_ROTATION_VELOCITY:
+ {
+ CollectParameters(&m_nIp, 1);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ *(CVector*)&ScriptParams[0] = pObject->GetTurnSpeed() * GAME_SPEED_TO_METERS_PER_SECOND;
+ StoreParameters(&m_nIp, 3);
+ return 0;
+ }
+ case COMMAND_ADD_VELOCITY_RELATIVE_TO_OBJECT_VELOCITY:
+ {
+ CollectParameters(&m_nIp, 4);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ CVector vecAddition = *(CVector*)&ScriptParams[1] * CTimer::GetTimeStep() / GAME_SPEED_TO_METERS_PER_SECOND;
+ if (!pObject->bIsStatic) {
+ CVector vecCurrSpeed = pObject->GetSpeed();
+ vecCurrSpeed.Normalise();
+ if (vecCurrSpeed.z != 1.0) { // NB: not float!
+ CVector vx = CrossProduct(vecCurrSpeed, CVector(0.0f, 0.0f, 1.0f));
+ vx.Normalise();
+ CVector vz = CrossProduct(vx, vecCurrSpeed);
+ vz.Normalise();
+ CVector vecNewSpeed = pObject->GetSpeed() + vecAddition.x * vx + vecAddition.y * vecCurrSpeed + vecAddition.z * vecCurrSpeed;
+ if (pObject->bIsStatic) {
+ pObject->SetIsStatic(false);
+ pObject->AddToMovingList();
+ }
+ pObject->SetMoveSpeed(vecNewSpeed);
+ }
+ }
+ return 0;
+ }
+ case COMMAND_GET_OBJECT_SPEED:
+ {
+ CollectParameters(&m_nIp, 1);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ *(float*)&ScriptParams[0] = pObject->GetMoveSpeed().Magnitude() * GAME_SPEED_TO_METERS_PER_SECOND;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+#endif
+#if (defined GTA_MOBILE || defined SUPPORT_MOBILE_SCRIPT)
+ case COMMAND_IS_MISSION_SKIP:
+#ifdef MISSION_REPLAY
+ ScriptParams[0] = MissionSkipLevel;
+#else
+ ScriptParams[0] = 0;
+#endif
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ case COMMAND_SET_IN_AMMUNATION:
+ CollectParameters(&m_nIp, 1);
+#ifdef MISSION_REPLAY
+ IsInAmmunation = ScriptParams[0];
+#endif
+ return 0;
+ case COMMAND_DO_SAVE_GAME:
+ CollectParameters(&m_nIp, 1);
+#ifdef USE_MISSION_REPLAY_OVERRIDE_FOR_NON_MOBILE_SCRIPT
+ UsingMobileScript = true;
+#endif
+#ifdef MISSION_REPLAY
+ SaveGameForPause(ScriptParams[0]);
+#endif
+ return 0;
+ case COMMAND_IS_RETRY:
+#ifdef MISSION_REPLAY
+ if (strcmp(m_abScriptName, "porno4") != 0)
+ ScriptParams[0] = AllowMissionReplay;
+#ifdef FIX_BUGS
+ else
+ ScriptParams[0] = gbTryingPorn4Again;
+#else
+ else if (gbTryingPorn4Again)
+ ScriptParams[0] = 1;
+#endif
+#else
+ ScriptParams[0] = 0;
+#endif
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ case COMMAND_DUMMY:
+ return 0;
+#endif
+#if (defined GTA_XBOX || defined SUPPORT_XBOX_SCRIPT || defined GTA_MOBILE || defined SUPPORT_MOBILE_SCRIPT)
+ // it is unknown what these commands do but they don't take parameters
+ case COMMAND_MARK_CUTSCENE_START:
+ return 0;
+ case COMMAND_MARK_CUTSCENE_END:
+ return 0;
+ case COMMAND_CUTSCENE_SCROLL:
+ return 0;
+#endif
+ default:
+ script_assert(0);
+ }
+ return -1;
+}
diff --git a/src/control/ScriptCommands.h b/src/control/ScriptCommands.h
index a33275f7..9cb39e23 100644
--- a/src/control/ScriptCommands.h
+++ b/src/control/ScriptCommands.h
@@ -293,7 +293,11 @@ enum {
COMMAND_IS_PLAYER_IN_ZONE,
COMMAND_IS_PLAYER_PRESSING_HORN,
COMMAND_HAS_CHAR_SPOTTED_PLAYER,
+#ifdef SUPPORT_GINPUT_SCRIPT
+ COMMAND_HAS_PAD_IN_HANDS,
+#else
COMMAND_ORDER_CHAR_TO_BACKDOOR,
+#endif
COMMAND_ADD_CHAR_TO_GANG,
COMMAND_IS_CHAR_OBJECTIVE_PASSED,
COMMAND_SET_CHAR_DRIVE_AGGRESSION,
@@ -995,7 +999,7 @@ enum {
COMMAND_FORCE_RANDOM_PED_TYPE,
COMMAND_SET_TEXT_DRAW_BEFORE_FADE,
COMMAND_GET_COLLECTABLE1S_COLLECTED,
- COMMAND_REGISTER_EL_BURRO_TIME,
+ COMMAND_SET_CHAR_OBJ_LEAVE_ANY_CAR,
COMMAND_SET_SPRITES_DRAW_BEFORE_FADE,
COMMAND_SET_TEXT_RIGHT_JUSTIFY,
COMMAND_PRINT_HELP,
@@ -1022,17 +1026,17 @@ enum {
COMMAND_MAKE_PLAYER_SAFE,
COMMAND_SET_CAR_STAYS_IN_CURRENT_LEVEL,
COMMAND_SET_CHAR_STAYS_IN_CURRENT_LEVEL,
- COMMAND_REGISTER_4X4_ONE_TIME,
- COMMAND_REGISTER_4X4_TWO_TIME,
- COMMAND_REGISTER_4X4_THREE_TIME,
- COMMAND_REGISTER_4X4_MAYHEM_TIME,
+ COMMAND_SET_DRUNK_INPUT_DELAY,
+ COMMAND_SET_CHAR_MONEY,
+ COMMAND_INCREASE_CHAR_MONEY,
+ COMMAND_GET_OFFSET_FROM_OBJECT_IN_WORLD_COORDS,
COMMAND_REGISTER_LIFE_SAVED,
COMMAND_REGISTER_CRIMINAL_CAUGHT,
COMMAND_REGISTER_AMBULANCE_LEVEL,
COMMAND_REGISTER_FIRE_EXTINGUISHED,
COMMAND_TURN_PHONE_ON,
COMMAND_REGISTER_LONGEST_DODO_FLIGHT,
- COMMAND_REGISTER_DEFUSE_BOMB_TIME,
+ COMMAND_GET_OFFSET_FROM_CAR_IN_WORLD_COORDS,
COMMAND_SET_TOTAL_NUMBER_OF_KILL_FRENZIES,
COMMAND_BLOW_UP_RC_BUGGY,
COMMAND_REMOVE_CAR_FROM_CHASE,
@@ -1108,7 +1112,6 @@ enum {
COMMAND_SET_JAMES_CAR_ON_PATH_TO_PLAYER,
COMMAND_LOAD_END_OF_GAME_TUNE,
COMMAND_ENABLE_PLAYER_CONTROL_CAMERA,
-#if GTA_VERSION > GTA3_PS2_160
COMMAND_SET_OBJECT_ROTATION,
COMMAND_GET_DEBUG_CAMERA_COORDINATES,
COMMAND_GET_DEBUG_CAMERA_FRONT_VECTOR,
@@ -1145,7 +1148,7 @@ enum {
COMMAND_LOCATE_CHAR_ANY_MEANS_OBJECT_3D,
COMMAND_LOCATE_CHAR_ON_FOOT_OBJECT_3D,
COMMAND_LOCATE_CHAR_IN_CAR_OBJECT_3D,
- COMMAND_SET_CAR_HANDBRAKE_TURN_LEFT,
+ COMMAND_SET_CAR_TEMP_ACTION,
COMMAND_SET_CAR_HANDBRAKE_TURN_RIGHT,
COMMAND_SET_CAR_HANDBRAKE_STOP,
COMMAND_IS_CHAR_ON_ANY_BIKE,
@@ -1156,13 +1159,324 @@ enum {
COMMAND_IS_CHAR_LYING_DOWN,
COMMAND_CAN_CHAR_SEE_DEAD_CHAR,
COMMAND_SET_ENTER_CAR_RANGE_MULTIPLIER,
-#if GTA_VERSION < GTA3_PC_11
COMMAND_SET_THREAT_REACTION_RANGE_MULTIPLIER,
+ COMMAND_SET_CHAR_CEASE_ATTACK_TIMER,
+ COMMAND_GET_REMOTE_CONTROLLED_CAR,
+ COMMAND_IS_PC_VERSION,
+ COMMAND_REPLAY,
+ COMMAND_IS_REPLAY_PLAYING,
+ COMMAND_IS_MODEL_AVAILABLE,
+ COMMAND_SHUT_CHAR_UP,
+ COMMAND_SET_ENABLE_RC_DETONATE,
+ COMMAND_SET_CAR_RANDOM_ROUTE_SEED,
+ COMMAND_IS_ANY_PICKUP_AT_COORDS,
+ COMMAND_GET_FIRST_PICKUP_COORDS,
+ COMMAND_GET_NEXT_PICKUP_COORDS,
+ COMMAND_REMOVE_ALL_CHAR_WEAPONS,
+ COMMAND_HAS_PLAYER_GOT_WEAPON,
+ COMMAND_HAS_CHAR_GOT_WEAPON,
+ COMMAND_IS_PLAYER_FACING_CHAR,
+ COMMAND_SET_TANK_DETONATE_CARS,
+ COMMAND_GET_POSITION_OF_ANALOGUE_STICKS,
+ COMMAND_IS_CAR_ON_FIRE,
+ COMMAND_IS_CAR_TYRE_BURST,
+ COMMAND_SET_CAR_DRIVE_STRAIGHT_AHEAD,
+ COMMAND_SET_CAR_WAIT,
+ COMMAND_IS_PLAYER_STANDING_ON_A_VEHICLE,
+ COMMAND_IS_PLAYER_FOOT_DOWN,
+ COMMAND_IS_CHAR_FOOT_DOWN,
+ COMMAND_INITIALISE_OBJECT_PATH,
+ COMMAND_START_OBJECT_ON_PATH,
+ COMMAND_SET_OBJECT_PATH_SPEED,
+ COMMAND_SET_OBJECT_PATH_POSITION,
+ COMMAND_GET_OBJECT_DISTANCE_ALONG_PATH,
+ COMMAND_CLEAR_OBJECT_PATH,
+ COMMAND_HELI_GOTO_COORDS,
+ COMMAND_IS_INT_VAR_EQUAL_TO_CONSTANT,
+ COMMAND_IS_INT_LVAR_EQUAL_TO_CONSTANT,
+ COMMAND_GET_DEAD_CHAR_PICKUP_COORDS,
+ COMMAND_CREATE_PROTECTION_PICKUP,
+ COMMAND_IS_CHAR_IN_ANY_BOAT,
+ COMMAND_IS_PLAYER_IN_ANY_BOAT,
+ COMMAND_IS_CHAR_IN_ANY_HELI,
+ COMMAND_IS_PLAYER_IN_ANY_HELI,
+ COMMAND_IS_CHAR_IN_ANY_PLANE,
+ COMMAND_IS_PLAYER_IN_ANY_PLANE,
+ COMMAND_IS_CHAR_IN_WATER,
+ COMMAND_SET_VAR_INT_TO_CONSTANT,
+ COMMAND_SET_LVAR_INT_TO_CONSTANT,
+ COMMAND_IS_INT_VAR_GREATER_THAN_CONSTANT,
+ COMMAND_IS_INT_LVAR_GREATER_THAN_CONSTANT,
+ COMMAND_IS_CONSTANT_GREATER_THAN_INT_VAR,
+ COMMAND_IS_CONSTANT_GREATER_THAN_INT_LVAR,
+ COMMAND_IS_INT_VAR_GREATER_OR_EQUAL_TO_CONSTANT,
+ COMMAND_IS_INT_LVAR_GREATER_OR_EQUAL_TO_CONSTANT,
+ COMMAND_IS_CONSTANT_GREATER_OR_EQUAL_TO_INT_VAR,
+ COMMAND_IS_CONSTANT_GREATER_OR_EQUAL_TO_INT_LVAR,
+ COMMAND_GET_CHAR_WEAPON_IN_SLOT,
+ COMMAND_GET_CLOSEST_STRAIGHT_ROAD,
+ COMMAND_SET_CAR_FORWARD_SPEED,
+ COMMAND_SET_AREA_VISIBLE,
+ COMMAND_SET_CUTSCENE_ANIM_TO_LOOP,
+ COMMAND_MARK_CAR_AS_CONVOY_CAR,
+ COMMAND_RESET_HAVOC_CAUSED_BY_PLAYER,
+ COMMAND_GET_HAVOC_CAUSED_BY_PLAYER,
+ COMMAND_CREATE_SCRIPT_ROADBLOCK,
+ COMMAND_CLEAR_ALL_SCRIPT_ROADBLOCKS,
+ COMMAND_SET_CHAR_OBJ_WALK_TO_CHAR,
+ COMMAND_IS_PICKUP_IN_ZONE,
+ COMMAND_GET_OFFSET_FROM_CHAR_IN_WORLD_COORDS,
+ COMMAND_HAS_CHAR_BEEN_PHOTOGRAPHED,
+ COMMAND_SET_CHAR_OBJ_AIM_GUN_AT_CHAR,
+ COMMAND_SWITCH_SECURITY_CAMERA,
+ COMMAND_IS_CHAR_IN_FLYING_VEHICLE,
+ COMMAND_IS_PLAYER_IN_FLYING_VEHICLE,
+ COMMAND_HAS_SONY_CD_BEEN_READ,
+ COMMAND_GET_NUMBER_OF_SONY_CDS_READ,
+ COMMAND_ADD_SHORT_RANGE_BLIP_FOR_COORD_OLD,
+ COMMAND_ADD_SHORT_RANGE_BLIP_FOR_COORD,
+ COMMAND_ADD_SHORT_RANGE_SPRITE_BLIP_FOR_COORD,
+ COMMAND_ADD_MONEY_SPENT_ON_CLOTHES,
+ COMMAND_SET_HELI_ORIENTATION,
+ COMMAND_CLEAR_HELI_ORIENTATION,
+ COMMAND_PLANE_GOTO_COORDS,
+ COMMAND_GET_NTH_CLOSEST_CAR_NODE,
+ COMMAND_GET_NTH_CLOSEST_CHAR_NODE,
+ COMMAND_DRAW_WEAPONSHOP_CORONA,
+ COMMAND_SET_ENABLE_RC_DETONATE_ON_CONTACT,
+ COMMAND_FREEZE_CHAR_POSITION,
+ COMMAND_SET_CHAR_DROWNS_IN_WATER,
+ COMMAND_SET_OBJECT_RECORDS_COLLISIONS,
+ COMMAND_HAS_OBJECT_COLLIDED_WITH_ANYTHING,
+ COMMAND_REMOVE_RC_BUGGY,
+ COMMAND_HAS_PHOTOGRAPH_BEEN_TAKEN,
+ COMMAND_GET_CHAR_ARMOUR,
+ COMMAND_SET_CHAR_ARMOUR,
+ COMMAND_SET_HELI_STABILISER,
+ COMMAND_SET_CAR_STRAIGHT_LINE_DISTANCE,
+ COMMAND_POP_CAR_BOOT,
+ COMMAND_SHUT_PLAYER_UP,
+ COMMAND_SET_PLAYER_MOOD,
+ COMMAND_REQUEST_COLLISION,
+ COMMAND_LOCATE_OBJECT_2D,
+ COMMAND_LOCATE_OBJECT_3D,
+ COMMAND_IS_OBJECT_IN_WATER,
+ COMMAND_SET_CHAR_OBJ_STEAL_ANY_CAR_EVEN_MISSION_CAR,
+ COMMAND_IS_OBJECT_IN_AREA_2D,
+ COMMAND_IS_OBJECT_IN_AREA_3D,
+ COMMAND_SET_CHAR_CROUCH,
+ COMMAND_SET_ZONE_CIVILIAN_CAR_INFO,
+ COMMAND_REQUEST_ANIMATION,
+ COMMAND_HAS_ANIMATION_LOADED,
+ COMMAND_REMOVE_ANIMATION,
+ COMMAND_IS_CHAR_WAITING_FOR_WORLD_COLLISION,
+ COMMAND_IS_CAR_WAITING_FOR_WORLD_COLLISION,
+ COMMAND_IS_OBJECT_WAITING_FOR_WORLD_COLLISION,
+ COMMAND_SET_CHAR_SHUFFLE_INTO_DRIVERS_SEAT,
+ COMMAND_ATTACH_CHAR_TO_OBJECT,
+ COMMAND_SET_CHAR_AS_PLAYER_FRIEND,
+ COMMAND_DISPLAY_NTH_ONSCREEN_COUNTER,
+ COMMAND_DISPLAY_NTH_ONSCREEN_COUNTER_WITH_STRING,
+ COMMAND_ADD_SET_PIECE,
+ COMMAND_SET_EXTRA_COLOURS,
+ COMMAND_CLEAR_EXTRA_COLOURS,
+ COMMAND_CLOSE_CAR_BOOT,
+ COMMAND_GET_WHEELIE_STATS,
+ COMMAND_DISARM_CHAR,
+ COMMAND_BURST_CAR_TYRE,
+ COMMAND_IS_CHAR_OBJ_NO_OBJ,
+ COMMAND_IS_PLAYER_WEARING,
+ COMMAND_SET_PLAYER_CAN_DO_DRIVE_BY,
+ COMMAND_SET_CHAR_OBJ_SPRINT_TO_COORD,
+ COMMAND_CREATE_SWAT_ROPE,
+ COMMAND_SET_FIRST_PERSON_CONTROL_CAMERA,
+ COMMAND_GET_NEAREST_TYRE_TO_POINT,
+ COMMAND_SET_CAR_MODEL_COMPONENTS,
+ COMMAND_SWITCH_LIFT_CAMERA,
+ COMMAND_CLOSE_ALL_CAR_DOORS,
+ COMMAND_GET_DISTANCE_BETWEEN_COORDS_2D,
+ COMMAND_GET_DISTANCE_BETWEEN_COORDS_3D,
+ COMMAND_POP_CAR_BOOT_USING_PHYSICS,
+ COMMAND_SET_FIRST_PERSON_WEAPON_CAMERA,
+ COMMAND_IS_CHAR_LEAVING_VEHICLE_TO_DIE,
+ COMMAND_SORT_OUT_OBJECT_COLLISION_WITH_CAR,
+ COMMAND_GET_MAX_WANTED_LEVEL,
+ COMMAND_IS_CHAR_WANDER_PATH_CLEAR,
+ COMMAND_PRINT_HELP_WITH_NUMBER,
+ COMMAND_PRINT_HELP_FOREVER,
+ COMMAND_PRINT_HELP_FOREVER_WITH_NUMBER,
+ COMMAND_SET_CHAR_CAN_BE_DAMAGED_BY_MEMBERS_OF_GANG,
+ COMMAND_LOAD_AND_LAUNCH_MISSION_EXCLUSIVE,
+ COMMAND_IS_MISSION_AUDIO_PLAYING,
+ COMMAND_CREATE_LOCKED_PROPERTY_PICKUP,
+ COMMAND_CREATE_FORSALE_PROPERTY_PICKUP,
+ COMMAND_FREEZE_CAR_POSITION,
+ COMMAND_HAS_CHAR_BEEN_DAMAGED_BY_CHAR,
+ COMMAND_HAS_CHAR_BEEN_DAMAGED_BY_CAR,
+ COMMAND_HAS_CAR_BEEN_DAMAGED_BY_CHAR,
+ COMMAND_HAS_CAR_BEEN_DAMAGED_BY_CAR,
+ COMMAND_GET_RADIO_CHANNEL,
+ COMMAND_DISPLAY_TEXT_WITH_3_NUMBERS,
+ COMMAND_IS_CAR_DROWNING_IN_WATER,
+ COMMAND_IS_CHAR_DROWNING_IN_WATER,
+ COMMAND_DISABLE_CUTSCENE_SHADOWS,
+ COMMAND_HAS_GLASS_BEEN_SHATTERED_NEARBY,
+ COMMAND_ATTACH_CUTSCENE_OBJECT_TO_BONE,
+ COMMAND_ATTACH_CUTSCENE_OBJECT_TO_COMPONENT,
+ COMMAND_SET_CHAR_STAY_IN_CAR_WHEN_JACKED,
+ COMMAND_IS_MISSION_AUDIO_LOADING,
+ COMMAND_ADD_MONEY_SPENT_ON_WEAPONS,
+ COMMAND_ADD_MONEY_SPENT_ON_PROPERTY,
+ COMMAND_ADD_MONEY_SPENT_ON_AUTO_PAINTING,
+ COMMAND_SET_CHAR_ANSWERING_MOBILE,
+ COMMAND_SET_PLAYER_DRUNKENNESS,
+ COMMAND_GET_PLAYER_DRUNKENNESS,
+ COMMAND_SET_PLAYER_DRUG_LEVEL,
+ COMMAND_GET_PLAYER_DRUG_LEVEL,
+ COMMAND_ADD_LOAN_SHARK_VISITS,
+ COMMAND_ADD_STORES_KNOCKED_OFF,
+ COMMAND_ADD_MOVIE_STUNTS,
+ COMMAND_ADD_NUMBER_OF_ASSASSINATIONS,
+ COMMAND_ADD_PIZZAS_DELIVERED,
+ COMMAND_ADD_GARBAGE_PICKUPS,
+ COMMAND_ADD_ICE_CREAMS_SOLD,
+ COMMAND_SET_TOP_SHOOTING_RANGE_SCORE,
+ COMMAND_ADD_SHOOTING_RANGE_RANK,
+ COMMAND_ADD_MONEY_SPENT_ON_GAMBLING,
+ COMMAND_ADD_MONEY_WON_ON_GAMBLING,
+ COMMAND_SET_LARGEST_GAMBLING_WIN,
+ COMMAND_SET_CHAR_IN_PLAYERS_GROUP_CAN_FIGHT,
+ COMMAND_CLEAR_CHAR_WAIT_STATE,
+ COMMAND_GET_RANDOM_CAR_OF_TYPE_IN_AREA_NO_SAVE,
+ COMMAND_SET_CAN_BURST_CAR_TYRES,
+ COMMAND_SET_PLAYER_AUTO_AIM,
+ COMMAND_FIRE_HUNTER_GUN,
+ COMMAND_SET_PROPERTY_AS_OWNED,
+ COMMAND_ADD_BLOOD_RING_KILLS,
+ COMMAND_SET_LONGEST_TIME_IN_BLOOD_RING,
+ COMMAND_REMOVE_EVERYTHING_FOR_HUGE_CUTSCENE,
+ COMMAND_IS_PLAYER_TOUCHING_VEHICLE,
+ COMMAND_IS_CHAR_TOUCHING_VEHICLE,
+ COMMAND_CHECK_FOR_PED_MODEL_AROUND_PLAYER,
+ COMMAND_CLEAR_CHAR_FOLLOW_PATH,
+ COMMAND_SET_CHAR_CAN_BE_SHOT_IN_VEHICLE,
+ COMMAND_ATTACH_CUTSCENE_OBJECT_TO_VEHICLE,
+ COMMAND_LOAD_MISSION_TEXT,
+ COMMAND_SET_TONIGHTS_EVENT,
+ COMMAND_CLEAR_CHAR_LAST_DAMAGE_ENTITY,
+ COMMAND_CLEAR_CAR_LAST_DAMAGE_ENTITY,
+ COMMAND_FREEZE_OBJECT_POSITION,
+ COMMAND_SET_PLAYER_HAS_MET_DEBBIE_HARRY,
+ COMMAND_SET_RIOT_INTENSITY,
+ COMMAND_IS_CAR_IN_ANGLED_AREA_2D,
+ COMMAND_IS_CAR_IN_ANGLED_AREA_3D,
+ COMMAND_REMOVE_WEAPON_FROM_CHAR,
+ COMMAND_SET_UP_TAXI_SHORTCUT,
+ COMMAND_CLEAR_TAXI_SHORTCUT,
+ COMMAND_SET_CHAR_OBJ_GOTO_CAR_ON_FOOT,
+ COMMAND_GET_CLOSEST_WATER_NODE,
+ COMMAND_ADD_PORN_LEAFLET_TO_RUBBISH,
+ COMMAND_CREATE_CLOTHES_PICKUP,
+ COMMAND_CHANGE_BLIP_THRESHOLD,
+ COMMAND_MAKE_PLAYER_FIRE_PROOF,
+ COMMAND_INCREASE_PLAYER_MAX_HEALTH,
+ COMMAND_INCREASE_PLAYER_MAX_ARMOUR,
+ COMMAND_CREATE_RANDOM_CHAR_AS_DRIVER,
+ COMMAND_CREATE_RANDOM_CHAR_AS_PASSENGER,
+ COMMAND_SET_CHAR_IGNORE_THREATS_BEHIND_OBJECTS,
+ COMMAND_ENSURE_PLAYER_HAS_DRIVE_BY_WEAPON,
+ COMMAND_MAKE_HELI_COME_CRASHING_DOWN,
+ COMMAND_ADD_EXPLOSION_NO_SOUND,
+ COMMAND_SET_OBJECT_AREA_VISIBLE,
+ COMMAND_WAS_VEHICLE_EVER_POLICE,
+ COMMAND_SET_CHAR_NEVER_TARGETTED,
+ COMMAND_LOAD_UNCOMPRESSED_ANIM,
+ COMMAND_WAS_CUTSCENE_SKIPPED,
+ COMMAND_SET_CHAR_CROUCH_WHEN_THREATENED,
+ COMMAND_IS_CHAR_IN_ANY_POLICE_VEHICLE,
+ COMMAND_DOES_CHAR_EXIST,
+ COMMAND_DOES_VEHICLE_EXIST,
+ COMMAND_ADD_SHORT_RANGE_BLIP_FOR_CONTACT_POINT,
+ COMMAND_ADD_SHORT_RANGE_SPRITE_BLIP_FOR_CONTACT_POINT,
+ COMMAND_IS_CHAR_STUCK,
+ COMMAND_SET_ALL_TAXIS_HAVE_NITRO,
+ COMMAND_SET_CHAR_STOP_SHOOT_DONT_SEEK_ENTITY,
+ COMMAND_FREEZE_CAR_POSITION_AND_DONT_LOAD_COLLISION,
+ COMMAND_FREEZE_CHAR_POSITION_AND_DONT_LOAD_COLLISION,
+ COMMAND_FREEZE_OBJECT_POSITION_AND_DONT_LOAD_COLLISION,
+ COMMAND_SET_FADE_AND_JUMPCUT_AFTER_RC_EXPLOSION,
+ COMMAND_REGISTER_VIGILANTE_LEVEL,
+ COMMAND_CLEAR_ALL_CHAR_ANIMS,
+ COMMAND_SET_MAXIMUM_NUMBER_OF_CARS_IN_GARAGE,
+ COMMAND_WANTED_STARS_ARE_FLASHING,
+ COMMAND_SET_ALLOW_HURRICANES,
+ COMMAND_PLAY_ANNOUNCEMENT,
+ COMMAND_SET_PLAYER_IS_IN_STADIUM,
+ COMMAND_GET_BUS_FARES_COLLECTED_BY_PLAYER,
+ COMMAND_SET_CHAR_OBJ_BUY_ICE_CREAM,
+ COMMAND_DISPLAY_RADAR,
+ COMMAND_REGISTER_BEST_POSITION,
+ COMMAND_IS_PLAYER_IN_INFO_ZONE,
+ COMMAND_CLEAR_CHAR_ICE_CREAM_PURCHASE,
+ COMMAND_IS_IN_CAR_FIRE_BUTTON_PRESSED,
+ COMMAND_HAS_CHAR_ATTEMPTED_ATTRACTOR,
+ COMMAND_SET_LOAD_COLLISION_FOR_CAR_FLAG,
+ COMMAND_SET_LOAD_COLLISION_FOR_CHAR_FLAG,
+ COMMAND_SET_LOAD_COLLISION_FOR_OBJECT_FLAG,
+ COMMAND_ADD_BIG_GUN_FLASH,
+ COMMAND_HAS_CHAR_BOUGHT_ICE_CREAM,
+ COMMAND_GET_PROGRESS_PERCENTAGE,
+ COMMAND_SET_SHORTCUT_PICKUP_POINT,
+ COMMAND_SET_SHORTCUT_DROPOFF_POINT_FOR_MISSION,
+ COMMAND_GET_RANDOM_ICE_CREAM_CUSTOMER_IN_AREA,
+ COMMAND_GET_RANDOM_ICE_CREAM_CUSTOMER_IN_ZONE,
+ COMMAND_UNLOCK_ALL_CAR_DOORS_IN_AREA,
+ COMMAND_SET_GANG_ATTACK_PLAYER_WITH_COPS,
+ COMMAND_SET_CHAR_FRIGHTENED_IN_JACKED_CAR,
+ COMMAND_SET_VEHICLE_TO_FADE_IN,
+ COMMAND_REGISTER_ODDJOB_MISSION_PASSED,
+ COMMAND_IS_PLAYER_IN_SHORTCUT_TAXI,
+ COMMAND_IS_CHAR_DUCKING,
+ COMMAND_CREATE_DUST_EFFECT_FOR_CUTSCENE_HELI,
+ COMMAND_REGISTER_FIRE_LEVEL,
+ COMMAND_IS_AUSTRALIAN_GAME,
+ COMMAND_DISARM_CAR_BOMB,
+#if (defined GTAVC_JP_PATCH || defined SUPPORT_JAPANESE_SCRIPT)
+ COMMAND_IS_JAPANESE_GAME,
+#elif (!defined GTA_PS2)
+ COMMAND_SET_ONSCREEN_COUNTER_FLASH_WHEN_FIRST_DISPLAYED,
+#endif
+#if (defined GTA_PC && !defined GTAVC_JP_PATCH || defined GTA_XBOX || defined SUPPORT_XBOX_SCRIPT || defined GTA_MOBILE || defined SUPPORT_MOBILE_SCRIPT)
+ COMMAND_SHUFFLE_CARD_DECKS,
+ COMMAND_FETCH_NEXT_CARD,
+ COMMAND_GET_OBJECT_VELOCITY,
+ COMMAND_IS_DEBUG_CAMERA_ON,
+ COMMAND_ADD_TO_OBJECT_ROTATION_VELOCITY,
+ COMMAND_SET_OBJECT_ROTATION_VELOCITY,
+ COMMAND_IS_OBJECT_STATIC,
+ COMMAND_GET_ANGLE_BETWEEN_2D_VECTORS,
+ COMMAND_DO_2D_RECTANGLES_COLLIDE,
+ COMMAND_GET_OBJECT_ROTATION_VELOCITY,
+ COMMAND_ADD_VELOCITY_RELATIVE_TO_OBJECT_VELOCITY,
+ COMMAND_GET_OBJECT_SPEED,
+#endif
+#if (defined GTA_XBOX || defined SUPPORT_XBOX_SCRIPT)
+ COMMAND_MARK_CUTSCENE_START,
+ COMMAND_MARK_CUTSCENE_END,
+ COMMAND_CUTSCENE_SCROLL,
+#elif (defined GTA_MOBILE || defined SUPPORT_MOBILE_SCRIPT)
+ COMMAND_IS_MISSION_SKIP,
+ COMMAND_SET_IN_AMMUNATION,
+ COMMAND_DO_SAVE_GAME,
+ COMMAND_IS_RETRY,
+ COMMAND_DUMMY,
+ COMMAND_MARK_CUTSCENE_START,
+ COMMAND_MARK_CUTSCENE_END,
+ COMMAND_CUTSCENE_SCROLL,
#endif
#ifdef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
LAST_SCRIPT_COMMAND
#endif
-#endif
};
#ifdef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
diff --git a/src/control/ScriptDebug.cpp b/src/control/ScriptDebug.cpp
index 63508217..1ca5f588 100644
--- a/src/control/ScriptDebug.cpp
+++ b/src/control/ScriptDebug.cpp
@@ -5,6 +5,10 @@
#include "Debug.h"
#include "FileMgr.h"
+#include "GameLogic.h"
+#ifdef MISSION_REPLAY
+#include "GenericGameStorage.h"
+#endif
#include "Messages.h"
#include "Timer.h"
#include "Stats.h"
@@ -104,7 +108,7 @@ const tScriptCommandData commands[] = {
REGISTER_COMMAND(COMMAND_GOSUB, INPUT_ARGUMENTS(ARGTYPE_LABEL,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_RETURN, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_LINE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_CREATE_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CREATE_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
REGISTER_COMMAND(COMMAND_GET_PLAYER_COORDINATES, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), false, -1, ""),
REGISTER_COMMAND(COMMAND_SET_PLAYER_COORDINATES, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_IS_PLAYER_IN_AREA_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_BOOL,), OUTPUT_ARGUMENTS(), true, -1, ""),
@@ -169,10 +173,10 @@ const tScriptCommandData commands[] = {
REGISTER_COMMAND(COMMAND_CSET_VAR_FLOAT_TO_LVAR_INT, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, 0, " =#"),
REGISTER_COMMAND(COMMAND_CSET_LVAR_INT_TO_LVAR_FLOAT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " =#"),
REGISTER_COMMAND(COMMAND_CSET_LVAR_FLOAT_TO_LVAR_INT, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, 0, " =#"),
- REGISTER_COMMAND(COMMAND_ABS_VAR_INT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, 0, " ABS"),
- REGISTER_COMMAND(COMMAND_ABS_LVAR_INT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, 0, " ABS"),
- REGISTER_COMMAND(COMMAND_ABS_VAR_FLOAT, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " ABS"),
- REGISTER_COMMAND(COMMAND_ABS_VAR_FLOAT, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " ABS"),
+ REGISTER_COMMAND(COMMAND_ABS_VAR_INT, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, 0, " ABS"),
+ REGISTER_COMMAND(COMMAND_ABS_LVAR_INT, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, 0, " ABS"),
+ REGISTER_COMMAND(COMMAND_ABS_VAR_FLOAT, INPUT_ARGUMENTS(ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " ABS"),
+ REGISTER_COMMAND(COMMAND_ABS_LVAR_FLOAT, INPUT_ARGUMENTS(ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " ABS"),
REGISTER_COMMAND(COMMAND_GENERATE_RANDOM_FLOAT, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT,), false, -1, ""),
REGISTER_COMMAND(COMMAND_GENERATE_RANDOM_INT, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
REGISTER_COMMAND(COMMAND_CREATE_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_PED_HANDLE,), false, -1, ""),
@@ -284,7 +288,7 @@ const tScriptCommandData commands[] = {
REGISTER_COMMAND(COMMAND_LOCATE_CHAR_ANY_MEANS_CHAR_3D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
REGISTER_COMMAND(COMMAND_LOCATE_CHAR_ON_FOOT_CHAR_3D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
REGISTER_COMMAND(COMMAND_LOCATE_CHAR_IN_CAR_CHAR_3D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_CREATE_OBJECT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_CREATE_OBJECT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
REGISTER_COMMAND(COMMAND_DELETE_OBJECT, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_ADD_SCORE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_IS_SCORE_GREATER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
@@ -313,7 +317,11 @@ const tScriptCommandData commands[] = {
REGISTER_COMMAND(COMMAND_IS_PLAYER_IN_ZONE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), true, -1, ""),
REGISTER_COMMAND(COMMAND_IS_PLAYER_PRESSING_HORN, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
REGISTER_COMMAND(COMMAND_HAS_CHAR_SPOTTED_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+#ifdef SUPPORT_GINPUT_SCRIPT
+ REGISTER_COMMAND(COMMAND_HAS_PAD_IN_HANDS, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), true, -1, ""),
+#else
REGISTER_COMMAND(COMMAND_ORDER_CHAR_TO_BACKDOOR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+#endif
REGISTER_COMMAND(COMMAND_ADD_CHAR_TO_GANG, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_IS_CHAR_OBJECTIVE_PASSED, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
REGISTER_COMMAND(COMMAND_SET_CHAR_DRIVE_AGGRESSION, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
@@ -354,12 +362,12 @@ const tScriptCommandData commands[] = {
REGISTER_COMMAND(COMMAND_CREATE_GANG_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
REGISTER_COMMAND(COMMAND_CREATE_CAR_GENERATOR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
REGISTER_COMMAND(COMMAND_SWITCH_CAR_GENERATOR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_PAGER_MESSAGE, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_DISPLAY_ONSCREEN_TIMER, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_PAGER_MESSAGE, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_DISPLAY_ONSCREEN_TIMER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_CLEAR_ONSCREEN_TIMER, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_DISPLAY_ONSCREEN_COUNTER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_CLEAR_ONSCREEN_COUNTER, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_ZONE_CAR_INFO, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_ZONE_CAR_INFO, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_IS_CHAR_IN_GANG_ZONE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
REGISTER_COMMAND(COMMAND_IS_CHAR_IN_ZONE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), true, -1, ""),
REGISTER_COMMAND(COMMAND_SET_CAR_DENSITY, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
@@ -369,7 +377,7 @@ const tScriptCommandData commands[] = {
REGISTER_COMMAND(COMMAND_POINT_CAMERA_AT_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_RESTORE_CAMERA, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_SHAKE_PAD, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_ZONE_PED_INFO, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_ZONE_PED_INFO, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_SET_TIME_SCALE, INPUT_ARGUMENTS(ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_IS_CAR_IN_AIR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
REGISTER_COMMAND(COMMAND_SET_FIXED_CAMERA_POSITION, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
@@ -558,8 +566,8 @@ const tScriptCommandData commands[] = {
REGISTER_COMMAND(COMMAND_SET_TAXI_LIGHTS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_PRINT_BIG_Q, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_PRINT_WITH_NUMBER_BIG_Q, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_GARAGE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_GARAGE_WITH_CAR_MODEL, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_GARAGE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_GARAGE_WITH_CAR_MODEL, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
REGISTER_COMMAND(COMMAND_SET_TARGET_CAR_FOR_MISSION_GARAGE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_IS_CAR_IN_MISSION_GARAGE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
REGISTER_COMMAND(COMMAND_SET_FREE_BOMBS, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
@@ -738,7 +746,7 @@ const tScriptCommandData commands[] = {
REGISTER_COMMAND(COMMAND_IS_CAR_ON_SCREEN, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
REGISTER_COMMAND(COMMAND_IS_CHAR_ON_SCREEN, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
REGISTER_COMMAND(COMMAND_IS_OBJECT_ON_SCREEN, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_GOSUB_FILE, INPUT_ARGUMENTS(ARGTYPE_LABEL, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GOSUB_FILE, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_GET_GROUND_Z_FOR_3D_COORD, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT,), false, -1, ""),
REGISTER_COMMAND(COMMAND_START_SCRIPT_FIRE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
REGISTER_COMMAND(COMMAND_IS_SCRIPT_FIRE_EXTINGUISHED, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
@@ -753,8 +761,8 @@ const tScriptCommandData commands[] = {
REGISTER_COMMAND(COMMAND_CLEAR_NUMBER_OF_POWER_PILLS_EATEN, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_ADD_POWER_PILL, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_SET_BOAT_CRUISE_SPEED, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_RANDOM_CHAR_IN_AREA, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_RANDOM_CHAR_IN_ZONE, INPUT_ARGUMENTS(ARGTYPE_STRING,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_RANDOM_CHAR_IN_AREA, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_RANDOM_CHAR_IN_ZONE, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
REGISTER_COMMAND(COMMAND_IS_PLAYER_IN_TAXI, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
REGISTER_COMMAND(COMMAND_IS_PLAYER_SHOOTING, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
REGISTER_COMMAND(COMMAND_IS_CHAR_SHOOTING, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
@@ -766,7 +774,7 @@ const tScriptCommandData commands[] = {
REGISTER_COMMAND(COMMAND_SET_CUTSCENE_ANIM, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_START_CUTSCENE, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_GET_CUTSCENE_TIME, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_HAS_CUTSCENE_FINISHED, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_HAS_CUTSCENE_FINISHED, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_CLEAR_CUTSCENE, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_RESTORE_CAMERA_JUMPCUT, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_CREATE_COLLECTABLE1, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
@@ -818,8 +826,8 @@ const tScriptCommandData commands[] = {
REGISTER_COMMAND(COMMAND_REMOVE_ALL_SCRIPT_FIRES, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_IS_FIRST_CAR_COLOUR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
REGISTER_COMMAND(COMMAND_IS_SECOND_CAR_COLOUR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_HAS_CHAR_BEEN_DAMAGED_BY_WEAPON, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_HAS_CAR_BEEN_DAMAGED_BY_WEAPON, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_HAS_CHAR_BEEN_DAMAGED_BY_WEAPON, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_HAS_CAR_BEEN_DAMAGED_BY_WEAPON, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
REGISTER_COMMAND(COMMAND_IS_CHAR_IN_CHARS_GROUP, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
REGISTER_COMMAND(COMMAND_IS_CHAR_IN_PLAYERS_GROUP, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
REGISTER_COMMAND(COMMAND_EXPLODE_CHAR_HEAD, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
@@ -830,7 +838,7 @@ const tScriptCommandData commands[] = {
REGISTER_COMMAND(COMMAND_START_CHAR_FIRE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
REGISTER_COMMAND(COMMAND_GET_RANDOM_CAR_OF_TYPE_IN_AREA, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
REGISTER_COMMAND(COMMAND_GET_RANDOM_CAR_OF_TYPE_IN_ZONE, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_HAS_RESPRAY_HAPPENED, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_HAS_RESPRAY_HAPPENED, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_SET_CAMERA_ZOOM, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_CREATE_PICKUP_WITH_AMMO, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
REGISTER_COMMAND(COMMAND_SET_CAR_RAM_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
@@ -848,8 +856,8 @@ const tScriptCommandData commands[] = {
REGISTER_COMMAND(COMMAND_SET_CAR_VISIBLE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_IS_AREA_OCCUPIED, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
REGISTER_COMMAND(COMMAND_START_DRUG_RUN, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_HAS_DRUG_RUN_BEEN_COMPLETED, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_HAS_DRUG_PLANE_BEEN_SHOT_DOWN, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_HAS_DRUG_RUN_BEEN_COMPLETED, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_HAS_DRUG_PLANE_BEEN_SHOT_DOWN, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), true, -1, ""),
REGISTER_COMMAND(COMMAND_SAVE_PLAYER_FROM_FIRES, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_DISPLAY_TEXT, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_SET_TEXT_SCALE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
@@ -878,7 +886,7 @@ const tScriptCommandData commands[] = {
REGISTER_COMMAND(COMMAND_IS_EXPLOSION_IN_AREA, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), true, -1, ""),
REGISTER_COMMAND(COMMAND_IS_EXPLOSION_IN_ZONE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), true, -1, ""),
REGISTER_COMMAND(COMMAND_START_DRUG_DROP_OFF, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_HAS_DROP_OFF_PLANE_BEEN_SHOT_DOWN, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_HAS_DROP_OFF_PLANE_BEEN_SHOT_DOWN, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), true, -1, ""),
REGISTER_COMMAND(COMMAND_FIND_DROP_OFF_PLANE_COORDINATES, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), false, -1, ""),
REGISTER_COMMAND(COMMAND_CREATE_FLOATING_PACKAGE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
REGISTER_COMMAND(COMMAND_PLACE_OBJECT_RELATIVE_TO_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
@@ -984,7 +992,7 @@ const tScriptCommandData commands[] = {
REGISTER_COMMAND(COMMAND_STORE_CAR_CHAR_IS_IN_NO_SAVE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
REGISTER_COMMAND(COMMAND_STORE_CAR_PLAYER_IS_IN_NO_SAVE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
REGISTER_COMMAND(COMMAND_IS_PHONE_DISPLAYING_MESSAGE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_DISPLAY_ONSCREEN_TIMER_WITH_STRING, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_DISPLAY_ONSCREEN_TIMER_WITH_STRING, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_DISPLAY_ONSCREEN_COUNTER_WITH_STRING, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_CREATE_RANDOM_CAR_FOR_CAR_PARK, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_IS_COLLISION_IN_MEMORY, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
@@ -996,15 +1004,15 @@ const tScriptCommandData commands[] = {
REGISTER_COMMAND(COMMAND_ADD_STUCK_CAR_CHECK, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_REMOVE_STUCK_CAR_CHECK, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_IS_CAR_STUCK, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOAD_MISSION_AUDIO, INPUT_ARGUMENTS(ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_HAS_MISSION_AUDIO_LOADED, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_PLAY_MISSION_AUDIO, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_HAS_MISSION_AUDIO_FINISHED, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOAD_MISSION_AUDIO, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_HAS_MISSION_AUDIO_LOADED, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_PLAY_MISSION_AUDIO, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_HAS_MISSION_AUDIO_FINISHED, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
REGISTER_COMMAND(COMMAND_GET_CLOSEST_CAR_NODE_WITH_HEADING, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), false, -1, ""),
REGISTER_COMMAND(COMMAND_HAS_IMPORT_GARAGE_SLOT_BEEN_FILLED, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
REGISTER_COMMAND(COMMAND_CLEAR_THIS_PRINT, INPUT_ARGUMENTS(ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_CLEAR_THIS_BIG_PRINT, INPUT_ARGUMENTS(ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_MISSION_AUDIO_POSITION, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_MISSION_AUDIO_POSITION, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_ACTIVATE_SAVE_MENU, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_HAS_SAVE_GAME_FINISHED, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), true, -1, ""),
REGISTER_COMMAND(COMMAND_NO_SPECIAL_CAMERA_FOR_THIS_GARAGE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
@@ -1015,7 +1023,7 @@ const tScriptCommandData commands[] = {
REGISTER_COMMAND(COMMAND_FORCE_RANDOM_PED_TYPE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_SET_TEXT_DRAW_BEFORE_FADE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_GET_COLLECTABLE1S_COLLECTED, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_REGISTER_EL_BURRO_TIME, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_LEAVE_ANY_CAR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_SET_SPRITES_DRAW_BEFORE_FADE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_SET_TEXT_RIGHT_JUSTIFY, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_PRINT_HELP, INPUT_ARGUMENTS(ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
@@ -1032,7 +1040,7 @@ const tScriptCommandData commands[] = {
REGISTER_COMMAND(COMMAND_USE_TEXT_COMMANDS, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_SET_THREAT_FOR_PED_TYPE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_CLEAR_THREAT_FOR_PED_TYPE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_CAR_COLOURS, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_CAR_COLOURS, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), true, -1, ""),
REGISTER_COMMAND(COMMAND_SET_ALL_CARS_CAN_BE_DAMAGED, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_SET_CAR_CAN_BE_DAMAGED, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_MAKE_PLAYER_UNSAFE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
@@ -1042,23 +1050,23 @@ const tScriptCommandData commands[] = {
REGISTER_COMMAND(COMMAND_MAKE_PLAYER_SAFE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_SET_CAR_STAYS_IN_CURRENT_LEVEL, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_SET_CHAR_STAYS_IN_CURRENT_LEVEL, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_REGISTER_4X4_ONE_TIME, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_REGISTER_4X4_TWO_TIME, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_REGISTER_4X4_THREE_TIME, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_REGISTER_4X4_MAYHEM_TIME, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_DRUNK_INPUT_DELAY, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_MONEY, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_INCREASE_CHAR_MONEY, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_OFFSET_FROM_OBJECT_IN_WORLD_COORDS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), false, -1, ""),
REGISTER_COMMAND(COMMAND_REGISTER_LIFE_SAVED, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_REGISTER_CRIMINAL_CAUGHT, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_REGISTER_AMBULANCE_LEVEL, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_REGISTER_FIRE_EXTINGUISHED, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_TURN_PHONE_ON, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_REGISTER_LONGEST_DODO_FLIGHT, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_REGISTER_DEFUSE_BOMB_TIME, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_OFFSET_FROM_CAR_IN_WORLD_COORDS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), false, -1, ""),
REGISTER_COMMAND(COMMAND_SET_TOTAL_NUMBER_OF_KILL_FRENZIES, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_BLOW_UP_RC_BUGGY, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_REMOVE_CAR_FROM_CHASE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_IS_FRENCH_GAME, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), true, -1, ""),
REGISTER_COMMAND(COMMAND_IS_GERMAN_GAME, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_CLEAR_MISSION_AUDIO, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CLEAR_MISSION_AUDIO, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_SET_FADE_IN_AFTER_NEXT_ARREST, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_SET_FADE_IN_AFTER_NEXT_DEATH, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_SET_GANG_PED_MODEL_PREFERENCE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
@@ -1128,7 +1136,6 @@ const tScriptCommandData commands[] = {
REGISTER_COMMAND(COMMAND_SET_JAMES_CAR_ON_PATH_TO_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_LOAD_END_OF_GAME_TUNE, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_ENABLE_PLAYER_CONTROL_CAMERA, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
-#if GTA_VERSION > GTA3_PS2_160
REGISTER_COMMAND(COMMAND_SET_OBJECT_ROTATION, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_GET_DEBUG_CAMERA_COORDINATES, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), false, -1, ""),
REGISTER_COMMAND(COMMAND_GET_DEBUG_CAMERA_FRONT_VECTOR, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), false, -1, ""),
@@ -1165,20 +1172,331 @@ const tScriptCommandData commands[] = {
REGISTER_COMMAND(COMMAND_LOCATE_CHAR_ANY_MEANS_OBJECT_3D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
REGISTER_COMMAND(COMMAND_LOCATE_CHAR_ON_FOOT_OBJECT_3D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
REGISTER_COMMAND(COMMAND_LOCATE_CHAR_IN_CAR_OBJECT_3D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CAR_HANDBRAKE_TURN_LEFT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CAR_TEMP_ACTION, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_SET_CAR_HANDBRAKE_TURN_RIGHT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_SET_CAR_HANDBRAKE_STOP, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_IS_CHAR_ON_ANY_BIKE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_SNIPER_BULLET_2D, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_SNIPER_BULLET_3D, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_SNIPER_BULLET_2D, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_SNIPER_BULLET_3D, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
REGISTER_COMMAND(COMMAND_GET_NUMBER_OF_SEATS_IN_MODEL, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
REGISTER_COMMAND(COMMAND_IS_PLAYER_ON_ANY_BIKE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
REGISTER_COMMAND(COMMAND_IS_CHAR_LYING_DOWN, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
REGISTER_COMMAND(COMMAND_CAN_CHAR_SEE_DEAD_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
REGISTER_COMMAND(COMMAND_SET_ENTER_CAR_RANGE_MULTIPLIER, INPUT_ARGUMENTS(ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
-#if GTA_VERSION < GTA3_PC_11
REGISTER_COMMAND(COMMAND_SET_THREAT_REACTION_RANGE_MULTIPLIER, INPUT_ARGUMENTS(ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_CEASE_ATTACK_TIMER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_REMOTE_CONTROLLED_CAR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PC_VERSION, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_REPLAY, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_REPLAY_PLAYING, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_MODEL_AVAILABLE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_SHUT_CHAR_UP, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_ENABLE_RC_DETONATE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CAR_RANDOM_ROUTE_SEED, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_ANY_PICKUP_AT_COORDS, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_FIRST_PICKUP_COORDS, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_NEXT_PICKUP_COORDS, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_REMOVE_ALL_CHAR_WEAPONS, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_HAS_PLAYER_GOT_WEAPON, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_HAS_CHAR_GOT_WEAPON, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_FACING_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_TANK_DETONATE_CARS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_POSITION_OF_ANALOGUE_STICKS, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CAR_ON_FIRE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CAR_TYRE_BURST, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CAR_DRIVE_STRAIGHT_AHEAD, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CAR_WAIT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_STANDING_ON_A_VEHICLE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_FOOT_DOWN, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CHAR_FOOT_DOWN, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_INITIALISE_OBJECT_PATH, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_START_OBJECT_ON_PATH, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_OBJECT_PATH_SPEED, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_OBJECT_PATH_POSITION, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_OBJECT_DISTANCE_ALONG_PATH, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CLEAR_OBJECT_PATH, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_HELI_GOTO_COORDS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_INT_VAR_EQUAL_TO_CONSTANT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_INT_LVAR_EQUAL_TO_CONSTANT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_DEAD_CHAR_PICKUP_COORDS, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CREATE_PROTECTION_PICKUP, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CHAR_IN_ANY_BOAT, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_IN_ANY_BOAT, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CHAR_IN_ANY_HELI, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_IN_ANY_HELI, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CHAR_IN_ANY_PLANE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_IN_ANY_PLANE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CHAR_IN_WATER, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_VAR_INT_TO_CONSTANT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, 0, " ="),
+ REGISTER_COMMAND(COMMAND_SET_LVAR_INT_TO_CONSTANT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, 0, " ="),
+ REGISTER_COMMAND(COMMAND_IS_INT_VAR_GREATER_THAN_CONSTANT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, 0, " >"),
+ REGISTER_COMMAND(COMMAND_IS_INT_LVAR_GREATER_THAN_CONSTANT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, 0, " >"),
+ REGISTER_COMMAND(COMMAND_IS_CONSTANT_GREATER_THAN_INT_VAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, 0, " >"),
+ REGISTER_COMMAND(COMMAND_IS_CONSTANT_GREATER_THAN_INT_LVAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, 0, " >"),
+ REGISTER_COMMAND(COMMAND_IS_INT_VAR_GREATER_OR_EQUAL_TO_CONSTANT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, 0, " >="),
+ REGISTER_COMMAND(COMMAND_IS_INT_LVAR_GREATER_OR_EQUAL_TO_CONSTANT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, 0, " >="),
+ REGISTER_COMMAND(COMMAND_IS_CONSTANT_GREATER_OR_EQUAL_TO_INT_VAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, 0, " >="),
+ REGISTER_COMMAND(COMMAND_IS_CONSTANT_GREATER_OR_EQUAL_TO_INT_LVAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, 0, " >="),
+ REGISTER_COMMAND(COMMAND_GET_CHAR_WEAPON_IN_SLOT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_CLOSEST_STRAIGHT_ROAD, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CAR_FORWARD_SPEED, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_AREA_VISIBLE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CUTSCENE_ANIM_TO_LOOP, INPUT_ARGUMENTS(ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_MARK_CAR_AS_CONVOY_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_RESET_HAVOC_CAUSED_BY_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_HAVOC_CAUSED_BY_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CREATE_SCRIPT_ROADBLOCK, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CLEAR_ALL_SCRIPT_ROADBLOCKS, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_WALK_TO_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PICKUP_IN_ZONE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_OFFSET_FROM_CHAR_IN_WORLD_COORDS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_HAS_CHAR_BEEN_PHOTOGRAPHED, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_AIM_GUN_AT_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SWITCH_SECURITY_CAMERA, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CHAR_IN_FLYING_VEHICLE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_IN_FLYING_VEHICLE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_HAS_SONY_CD_BEEN_READ, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_NUMBER_OF_SONY_CDS_READ, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_SHORT_RANGE_BLIP_FOR_COORD_OLD, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_SHORT_RANGE_BLIP_FOR_COORD, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_SHORT_RANGE_SPRITE_BLIP_FOR_COORD, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_MONEY_SPENT_ON_CLOTHES, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_HELI_ORIENTATION, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CLEAR_HELI_ORIENTATION, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_PLANE_GOTO_COORDS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_NTH_CLOSEST_CAR_NODE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_NTH_CLOSEST_CHAR_NODE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_DRAW_WEAPONSHOP_CORONA, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_ENABLE_RC_DETONATE_ON_CONTACT, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_FREEZE_CHAR_POSITION, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_DROWNS_IN_WATER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_OBJECT_RECORDS_COLLISIONS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_HAS_OBJECT_COLLIDED_WITH_ANYTHING, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_REMOVE_RC_BUGGY, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_HAS_PHOTOGRAPH_BEEN_TAKEN, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_CHAR_ARMOUR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_ARMOUR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_HELI_STABILISER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CAR_STRAIGHT_LINE_DISTANCE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_POP_CAR_BOOT, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SHUT_PLAYER_UP, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_PLAYER_MOOD, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_REQUEST_COLLISION, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_OBJECT_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_OBJECT_3D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_OBJECT_IN_WATER, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_STEAL_ANY_CAR_EVEN_MISSION_CAR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_OBJECT_IN_AREA_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_OBJECT_IN_AREA_3D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_CROUCH, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_ZONE_CIVILIAN_CAR_INFO, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_REQUEST_ANIMATION, INPUT_ARGUMENTS(ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_HAS_ANIMATION_LOADED, INPUT_ARGUMENTS(ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_REMOVE_ANIMATION, INPUT_ARGUMENTS(ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CHAR_WAITING_FOR_WORLD_COLLISION, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CAR_WAITING_FOR_WORLD_COLLISION, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_OBJECT_WAITING_FOR_WORLD_COLLISION, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_SHUFFLE_INTO_DRIVERS_SEAT, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ATTACH_CHAR_TO_OBJECT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_AS_PLAYER_FRIEND, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_DISPLAY_NTH_ONSCREEN_COUNTER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_DISPLAY_NTH_ONSCREEN_COUNTER_WITH_STRING, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_SET_PIECE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_EXTRA_COLOURS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CLEAR_EXTRA_COLOURS, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CLOSE_CAR_BOOT, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_WHEELIE_STATS, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_INT, ARGTYPE_FLOAT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_DISARM_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_BURST_CAR_TYRE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CHAR_OBJ_NO_OBJ, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_WEARING, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_PLAYER_CAN_DO_DRIVE_BY, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_SPRINT_TO_COORD, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CREATE_SWAT_ROPE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_FIRST_PERSON_CONTROL_CAMERA, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_NEAREST_TYRE_TO_POINT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CAR_MODEL_COMPONENTS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SWITCH_LIFT_CAMERA, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CLOSE_ALL_CAR_DOORS, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_DISTANCE_BETWEEN_COORDS_2D, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_DISTANCE_BETWEEN_COORDS_3D, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_POP_CAR_BOOT_USING_PHYSICS, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_FIRST_PERSON_WEAPON_CAMERA, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CHAR_LEAVING_VEHICLE_TO_DIE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_SORT_OUT_OBJECT_COLLISION_WITH_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_MAX_WANTED_LEVEL, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CHAR_WANDER_PATH_CLEAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_PRINT_HELP_WITH_NUMBER, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_PRINT_HELP_FOREVER, INPUT_ARGUMENTS(ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_PRINT_HELP_FOREVER_WITH_NUMBER, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_CAN_BE_DAMAGED_BY_MEMBERS_OF_GANG, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOAD_AND_LAUNCH_MISSION_EXCLUSIVE, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_MISSION_AUDIO_PLAYING, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_CREATE_LOCKED_PROPERTY_PICKUP, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_STRING,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CREATE_FORSALE_PROPERTY_PICKUP, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ARGTYPE_STRING,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_FREEZE_CAR_POSITION, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_HAS_CHAR_BEEN_DAMAGED_BY_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_HAS_CHAR_BEEN_DAMAGED_BY_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_HAS_CAR_BEEN_DAMAGED_BY_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_HAS_CAR_BEEN_DAMAGED_BY_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_RADIO_CHANNEL, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_DISPLAY_TEXT_WITH_3_NUMBERS, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CAR_DROWNING_IN_WATER, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CHAR_DROWNING_IN_WATER, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_DISABLE_CUTSCENE_SHADOWS, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_HAS_GLASS_BEEN_SHATTERED_NEARBY, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_ATTACH_CUTSCENE_OBJECT_TO_BONE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ATTACH_CUTSCENE_OBJECT_TO_COMPONENT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_STAY_IN_CAR_WHEN_JACKED, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_MISSION_AUDIO_LOADING, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_MONEY_SPENT_ON_WEAPONS, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_MONEY_SPENT_ON_PROPERTY, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_MONEY_SPENT_ON_AUTO_PAINTING, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_ANSWERING_MOBILE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_PLAYER_DRUNKENNESS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_PLAYER_DRUNKENNESS, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_PLAYER_DRUG_LEVEL, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_PLAYER_DRUG_LEVEL, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_LOAN_SHARK_VISITS, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_STORES_KNOCKED_OFF, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_MOVIE_STUNTS, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_NUMBER_OF_ASSASSINATIONS, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_PIZZAS_DELIVERED, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_GARBAGE_PICKUPS, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_ICE_CREAMS_SOLD, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_TOP_SHOOTING_RANGE_SCORE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_SHOOTING_RANGE_RANK, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_MONEY_SPENT_ON_GAMBLING, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_MONEY_WON_ON_GAMBLING, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_LARGEST_GAMBLING_WIN, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_IN_PLAYERS_GROUP_CAN_FIGHT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CLEAR_CHAR_WAIT_STATE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_RANDOM_CAR_OF_TYPE_IN_AREA_NO_SAVE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CAN_BURST_CAR_TYRES, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_PLAYER_AUTO_AIM, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_FIRE_HUNTER_GUN, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_PROPERTY_AS_OWNED, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_BLOOD_RING_KILLS, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_LONGEST_TIME_IN_BLOOD_RING, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_REMOVE_EVERYTHING_FOR_HUGE_CUTSCENE, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_TOUCHING_VEHICLE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CHAR_TOUCHING_VEHICLE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_CHECK_FOR_PED_MODEL_AROUND_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_CLEAR_CHAR_FOLLOW_PATH, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_CAN_BE_SHOT_IN_VEHICLE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ATTACH_CUTSCENE_OBJECT_TO_VEHICLE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOAD_MISSION_TEXT, INPUT_ARGUMENTS(ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_TONIGHTS_EVENT, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CLEAR_CHAR_LAST_DAMAGE_ENTITY, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CLEAR_CAR_LAST_DAMAGE_ENTITY, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_FREEZE_OBJECT_POSITION, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_PLAYER_HAS_MET_DEBBIE_HARRY, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_RIOT_INTENSITY, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CAR_IN_ANGLED_AREA_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CAR_IN_ANGLED_AREA_3D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_REMOVE_WEAPON_FROM_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_UP_TAXI_SHORTCUT, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CLEAR_TAXI_SHORTCUT, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_GOTO_CAR_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_CLOSEST_WATER_NODE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_PORN_LEAFLET_TO_RUBBISH, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CREATE_CLOTHES_PICKUP, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CHANGE_BLIP_THRESHOLD, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_MAKE_PLAYER_FIRE_PROOF, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_INCREASE_PLAYER_MAX_HEALTH, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_INCREASE_PLAYER_MAX_ARMOUR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CREATE_RANDOM_CHAR_AS_DRIVER, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CREATE_RANDOM_CHAR_AS_PASSENGER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_IGNORE_THREATS_BEHIND_OBJECTS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ENSURE_PLAYER_HAS_DRIVE_BY_WEAPON, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_MAKE_HELI_COME_CRASHING_DOWN, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_EXPLOSION_NO_SOUND, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_OBJECT_AREA_VISIBLE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_WAS_VEHICLE_EVER_POLICE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_NEVER_TARGETTED, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOAD_UNCOMPRESSED_ANIM, INPUT_ARGUMENTS(ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_WAS_CUTSCENE_SKIPPED, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_CROUCH_WHEN_THREATENED, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CHAR_IN_ANY_POLICE_VEHICLE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_DOES_CHAR_EXIST, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_DOES_VEHICLE_EXIST, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_SHORT_RANGE_BLIP_FOR_CONTACT_POINT, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_SHORT_RANGE_SPRITE_BLIP_FOR_CONTACT_POINT, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CHAR_STUCK, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_ALL_TAXIS_HAVE_NITRO, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_STOP_SHOOT_DONT_SEEK_ENTITY, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_FREEZE_CAR_POSITION_AND_DONT_LOAD_COLLISION, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_FREEZE_CHAR_POSITION_AND_DONT_LOAD_COLLISION, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_FREEZE_OBJECT_POSITION_AND_DONT_LOAD_COLLISION, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_FADE_AND_JUMPCUT_AFTER_RC_EXPLOSION, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_REGISTER_VIGILANTE_LEVEL, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CLEAR_ALL_CHAR_ANIMS, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_MAXIMUM_NUMBER_OF_CARS_IN_GARAGE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_WANTED_STARS_ARE_FLASHING, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_ALLOW_HURRICANES, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_PLAY_ANNOUNCEMENT, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_PLAYER_IS_IN_STADIUM, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_BUS_FARES_COLLECTED_BY_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_BUY_ICE_CREAM, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_DISPLAY_RADAR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_REGISTER_BEST_POSITION, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_IN_INFO_ZONE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_CLEAR_CHAR_ICE_CREAM_PURCHASE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_IN_CAR_FIRE_BUTTON_PRESSED, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_HAS_CHAR_ATTEMPTED_ATTRACTOR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_LOAD_COLLISION_FOR_CAR_FLAG, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_LOAD_COLLISION_FOR_CHAR_FLAG, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_LOAD_COLLISION_FOR_OBJECT_FLAG, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_BIG_GUN_FLASH, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_HAS_CHAR_BOUGHT_ICE_CREAM, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_PROGRESS_PERCENTAGE, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_SHORTCUT_PICKUP_POINT, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_SHORTCUT_DROPOFF_POINT_FOR_MISSION, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_RANDOM_ICE_CREAM_CUSTOMER_IN_AREA, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_RANDOM_ICE_CREAM_CUSTOMER_IN_ZONE, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_UNLOCK_ALL_CAR_DOORS_IN_AREA, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_GANG_ATTACK_PLAYER_WITH_COPS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_FRIGHTENED_IN_JACKED_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_VEHICLE_TO_FADE_IN, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_REGISTER_ODDJOB_MISSION_PASSED, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_IN_SHORTCUT_TAXI, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CHAR_DUCKING, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_CREATE_DUST_EFFECT_FOR_CUTSCENE_HELI, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_REGISTER_FIRE_LEVEL, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_AUSTRALIAN_GAME, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_DISARM_CAR_BOMB, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+#if (defined GTAVC_JP_PATCH || defined SUPPORT_JAPANESE_SCRIPT)
+ REGISTER_COMMAND(COMMAND_IS_JAPANESE_GAME, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), true, -1, ""),
+#elif (!defined GTA_PS2)
+ REGISTER_COMMAND(COMMAND_SET_ONSCREEN_COUNTER_FLASH_WHEN_FIRST_DISPLAYED, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+#endif
+#if (defined GTA_PC && !defined GTAVC_JP_PATCH || defined GTA_XBOX || defined SUPPORT_XBOX_SCRIPT || defined GTA_MOBILE || defined SUPPORT_MOBILE_SCRIPT)
+ REGISTER_COMMAND(COMMAND_SHUFFLE_CARD_DECKS, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_FETCH_NEXT_CARD, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_OBJECT_VELOCITY, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_DEBUG_CAMERA_ON, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_TO_OBJECT_ROTATION_VELOCITY, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_OBJECT_ROTATION_VELOCITY, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_OBJECT_STATIC, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_ANGLE_BETWEEN_2D_VECTORS, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_DO_2D_RECTANGLES_COLLIDE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_OBJECT_ROTATION_VELOCITY, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_VELOCITY_RELATIVE_TO_OBJECT_VELOCITY, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_OBJECT_SPEED, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT,), false, -1, ""),
#endif
+#if (defined GTA_XBOX || defined SUPPORT_XBOX_SCRIPT)
+ REGISTER_COMMAND(COMMAND_MARK_CUTSCENE_START, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_MARK_CUTSCENE_END, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CUTSCENE_SCROLL, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
+#elif (defined GTA_MOBILE || defined SUPPORT_MOBILE_SCRIPT)
+ REGISTER_COMMAND(COMMAND_IS_MISSION_SKIP, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_IN_AMMUNATION, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_DO_SAVE_GAME, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_RETRY, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_DUMMY, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_MARK_CUTSCENE_START, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_MARK_CUTSCENE_END, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CUTSCENE_SCROLL, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
#endif
};
#undef REGISTER_COMMAND
@@ -1209,15 +1527,28 @@ static void PrintToLog(const char* format, ...)
#endif
}
+#endif
+
+void FlushLog()
+{
+#ifdef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
+#if SCRIPT_LOG_FILE_LEVEL == 1 || SCRIPT_LOG_FILE_LEVEL == 2
+ if (dbg_log)
+ fflush(dbg_log);
+#endif
+#endif
+}
+
+#ifdef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
int CRunningScript::CollectParameterForDebug(char* buf, bool& var)
{
- float tmp;
uint16 varIndex;
char tmpstr[24];
var = false;
switch (CTheScripts::Read1ByteFromScript(&m_nIp))
{
case ARGUMENT_INT32:
+ case ARGUMENT_FLOAT:
return CTheScripts::Read4BytesFromScript(&m_nIp);
case ARGUMENT_GLOBALVAR:
varIndex = CTheScripts::Read2BytesFromScript(&m_nIp);
@@ -1237,9 +1568,6 @@ int CRunningScript::CollectParameterForDebug(char* buf, bool& var)
return CTheScripts::Read1ByteFromScript(&m_nIp);
case ARGUMENT_INT16:
return CTheScripts::Read2BytesFromScript(&m_nIp);
- case ARGUMENT_FLOAT:
- tmp = CTheScripts::ReadFloatFromScript(&m_nIp);
- return *(int32*)&tmp;
default:
PrintToLog("%s - script assertion failed in CollectParameterForDebug", buf);
script_assert(0);
@@ -1384,17 +1712,6 @@ void CRunningScript::LogAfterProcessingCommand(int32 command)
#endif
-void FlushLog()
-{
-#ifdef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
-#if SCRIPT_LOG_FILE_LEVEL == 1 || SCRIPT_LOG_FILE_LEVEL == 2
- if (dbg_log)
- fflush(dbg_log);
-#endif
-#endif
-}
-
-
#ifdef MISSION_SWITCHER
void
CTheScripts::SwitchToMission(int32 mission)
@@ -1416,10 +1733,16 @@ CTheScripts::SwitchToMission(int32 mission)
CMessages::ClearMessages();
}
+ if (CTheScripts::NumberOfExclusiveMissionScripts > 0 && mission <= UINT16_MAX - 2)
+ return;
+
#ifdef MISSION_REPLAY
missionRetryScriptIndex = mission;
- if (missionRetryScriptIndex == 19)
- CStats::LastMissionPassedName[0] = '\0';
+#ifdef USE_MISSION_REPLAY_OVERRIDE_FOR_NON_MOBILE_SCRIPT
+ if (CTheScripts::MissionSupportsMissionReplay(missionRetryScriptIndex)) {
+ SaveGameForPause(SAVE_TYPE_QUICKSAVE_FOR_SCRIPT);
+ }
+#endif
#endif
CTimer::Suspend();
int offset = CTheScripts::MultiScriptArray[mission];
@@ -1437,5 +1760,6 @@ CTheScripts::SwitchToMission(int32 mission)
pMissionScript->m_bIsMissionScript = true;
pMissionScript->m_bMissionFlag = true;
CTheScripts::bAlreadyRunningAMissionScript = true;
+ CGameLogic::ClearShortCut();
}
#endif
diff --git a/src/control/SetPieces.cpp b/src/control/SetPieces.cpp
new file mode 100644
index 00000000..5edcd335
--- /dev/null
+++ b/src/control/SetPieces.cpp
@@ -0,0 +1,325 @@
+#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"
+#include "VarConsole.h"
+#include "SaveBuf.h"
+
+#define TIME_BETWEEN_SETPIECE_SPAWNS 20000
+
+bool CSetPieces::bDebug;
+uint32 CSetPieces::NumSetPieces;
+CSetPiece CSetPieces::aSetPieces[NUM_SETPIECES];
+
+void CSetPieces::Init(void)
+{
+ bDebug = false;
+ NumSetPieces = 0;
+#ifndef MASTER
+ VarConsole.Add("Show set pieces", &bDebug, true);
+#endif
+}
+
+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 = 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();
+#ifndef MASTER
+ // TODO: debug code from mobile
+#endif // !MASTER
+}
+
+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
+ ReadSaveBuf(&NumSetPieces, buf);
+ for (int i = 0; i < NUM_SETPIECES; i++)
+ ReadSaveBuf(&aSetPieces[i], 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->GetWantedLevel() < 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->GetWantedLevel() < 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->GetWantedLevel() < 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->GetWantedLevel() < 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->GetWantedLevel() < 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->GetWantedLevel() < 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->GetWantedLevel() < 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(pVehicle1);
+ delete pVehicle1;
+ 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..5c228d4c
--- /dev/null
+++ b/src/control/SetPieces.h
@@ -0,0 +1,48 @@
+#pragma once
+
+#include "config.h"
+
+class CVehicle;
+class CCopPed;
+
+enum eSetPieceType
+{
+ SETPIECE_NONE = 0,
+ SETPIECE_TWOCOPCARSINALLEY,
+ SETPIECE_CARBLOCKINGPLAYERFROMSIDE,
+ SETPIECE_CARRAMMINGPLAYERFROMSIDE,
+ SETPIECE_CREATECOPPERONFOOT,
+ SETPIECE_CREATETWOCOPPERSONFOOT,
+ SETPIECE_TWOCARSBLOCKINGPLAYERFROMSIDE,
+ SETPIECE_TWOCARSRAMMINGPLAYERFROMSIDE
+};
+
+class CSetPiece
+{
+public:
+ uint8 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 278366a3..e484d3be 100644
--- a/src/control/TrafficLights.cpp
+++ b/src/control/TrafficLights.cpp
@@ -15,8 +15,7 @@
#include "Weather.h"
#include "World.h"
-// TODO: figure out the meaning of this
-enum { SOME_FLAG = 0x80 };
+bool CTrafficLights::bGreenLightsCheat;
void
CTrafficLights::DisplayActualLight(CEntity *ent)
@@ -26,113 +25,288 @@ CTrafficLights::DisplayActualLight(CEntity *ent)
int phase;
if(FindTrafficLightType(ent) == 1)
- phase = LightForCars1();
+ phase = LightForCars1_Visual();
else
- phase = LightForCars2();
-
- int i;
- CBaseModelInfo *mi = CModelInfo::GetModelInfo(ent->GetModelIndex());
- float x = mi->Get2dEffect(0)->pos.x;
- float yMin = mi->Get2dEffect(0)->pos.y;
- float yMax = mi->Get2dEffect(0)->pos.y;
- float zMin = mi->Get2dEffect(0)->pos.z;
- float zMax = mi->Get2dEffect(0)->pos.z;
- for(i = 1; i < 6; i++){
- assert(mi->Get2dEffect(i));
- yMin = Min(yMin, mi->Get2dEffect(i)->pos.y);
- yMax = Max(yMax, mi->Get2dEffect(i)->pos.y);
- zMin = Min(zMin, mi->Get2dEffect(i)->pos.z);
- zMax = Max(zMax, mi->Get2dEffect(i)->pos.z);
+ phase = LightForCars2_Visual();
+
+ int i, m = ent->GetModelIndex();
+ if (MI_TRAFFICLIGHTS == m) {
+ CBaseModelInfo* mi = CModelInfo::GetModelInfo(ent->GetModelIndex());
+ float x = mi->Get2dEffect(0)->pos.x;
+ float yMin = mi->Get2dEffect(0)->pos.y;
+ float yMax = mi->Get2dEffect(0)->pos.y;
+ float zMin = mi->Get2dEffect(0)->pos.z;
+ float zMax = mi->Get2dEffect(0)->pos.z;
+ for (i = 1; i < 6; i++) {
+ assert(mi->Get2dEffect(i));
+ yMin = Min(yMin, mi->Get2dEffect(i)->pos.y);
+ yMax = Max(yMax, mi->Get2dEffect(i)->pos.y);
+ zMin = Min(zMin, mi->Get2dEffect(i)->pos.z);
+ zMax = Max(zMax, mi->Get2dEffect(i)->pos.z);
+ }
+
+ CVector pos1, pos2;
+ uint8 r, g;
+ int id;
+ switch (phase) {
+ case CAR_LIGHTS_GREEN:
+ r = 0;
+ g = 255;
+ pos1 = ent->GetMatrix() * CVector(x, yMax, zMin);
+ pos2 = ent->GetMatrix() * CVector(x, yMin, zMin);
+ id = 0;
+ break;
+ case CAR_LIGHTS_YELLOW:
+ r = 255;
+ g = 128;
+ pos1 = ent->GetMatrix() * CVector(x, yMax, (zMin + zMax) / 2.0f);
+ pos2 = ent->GetMatrix() * CVector(x, yMin, (zMin + zMax) / 2.0f);
+ id = 1;
+ break;
+ case CAR_LIGHTS_RED:
+ r = 255;
+ g = 0;
+ pos1 = ent->GetMatrix() * CVector(x, yMax, zMax);
+ pos2 = ent->GetMatrix() * CVector(x, yMin, zMax);
+ id = 2;
+ break;
+ default:
+ r = 0;
+ g = 0;
+ pos1 = ent->GetMatrix() * CVector(x, yMax, (zMin + zMax) / 2.0f);
+ pos2 = ent->GetMatrix() * CVector(x, yMin, (zMin + zMax) / 2.0f);
+ id = -1;
+ break;
+ }
+
+ if (CWeather::TrafficLightBrightness > 0.5f)
+ CPointLights::AddLight(CPointLights::LIGHT_POINT,
+ pos1, CVector(0.0f, 0.0f, 0.0f), 8.0f,
+ r / 255.0f, g / 255.0f, 0 / 255.0f, CPointLights::FOG_NORMAL, true);
+
+ if (CWeather::TrafficLightBrightness > 0.05f)
+ CShadows::StoreStaticShadow((uintptr)ent,
+ SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &pos1,
+ 8.0f, 0.0f, 0.0f, -8.0f, 128,
+ r * CTimeCycle::GetLightOnGroundBrightness() * CWeather::TrafficLightBrightness / 8.0f,
+ g * CTimeCycle::GetLightOnGroundBrightness() * CWeather::TrafficLightBrightness / 8.0f,
+ 0 * CTimeCycle::GetLightOnGroundBrightness() * CWeather::TrafficLightBrightness / 8.0f,
+ 12.0f, 1.0f, 40.0f, false, 0.0f);
+
+ if (DotProduct(TheCamera.GetForward(), ent->GetForward()) < 0.0f)
+ CCoronas::RegisterCorona((uintptr)ent + id,
+ r * CTimeCycle::GetSpriteBrightness() * 0.7f,
+ g * CTimeCycle::GetSpriteBrightness() * 0.7f,
+ 0 * CTimeCycle::GetSpriteBrightness() * 0.7f,
+ 255,
+ pos1, 1.75f * CTimeCycle::GetSpriteSize(), 50.0f,
+ CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON,
+ CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
+ else
+ CCoronas::RegisterCorona((uintptr)ent + id + 3,
+ r * CTimeCycle::GetSpriteBrightness() * 0.7f,
+ g * CTimeCycle::GetSpriteBrightness() * 0.7f,
+ 0 * CTimeCycle::GetSpriteBrightness() * 0.7f,
+ 255,
+ pos2, 1.75f * CTimeCycle::GetSpriteSize(), 50.0f,
+ CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON,
+ CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
+
+ 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);
}
+ else if (MI_TRAFFICLIGHTS_VERTICAL == m) {
+ CBaseModelInfo* mi = CModelInfo::GetModelInfo(ent->GetModelIndex());
+ float x = mi->Get2dEffect(0)->pos.x;
+ float yMin = mi->Get2dEffect(0)->pos.y;
+ float yMax = mi->Get2dEffect(0)->pos.y;
+ float zMin = mi->Get2dEffect(0)->pos.z;
+ float zMax = mi->Get2dEffect(0)->pos.z;
+ for (i = 1; i < 6; i++) {
+ assert(mi->Get2dEffect(i));
+ yMin = Min(yMin, mi->Get2dEffect(i)->pos.y);
+ yMax = Max(yMax, mi->Get2dEffect(i)->pos.y);
+ zMin = Min(zMin, mi->Get2dEffect(i)->pos.z);
+ zMax = Max(zMax, mi->Get2dEffect(i)->pos.z);
+ }
+
+ CVector pos1;
+ uint8 r, g;
+ int id;
+ switch (phase) {
+ case CAR_LIGHTS_GREEN:
+ r = 0;
+ g = 255;
+ pos1 = ent->GetMatrix() * mi->Get2dEffect(2)->pos;
+ id = 0;
+ break;
+ case CAR_LIGHTS_YELLOW:
+ r = 255;
+ g = 128;
+ pos1 = ent->GetMatrix() * mi->Get2dEffect(1)->pos;
+ id = 1;
+ break;
+ case CAR_LIGHTS_RED:
+ r = 255;
+ g = 0;
+ pos1 = ent->GetMatrix() * mi->Get2dEffect(0)->pos;
+ id = 2;
+ break;
+ default:
+ r = 0;
+ g = 0;
+ pos1 = ent->GetMatrix() * mi->Get2dEffect(1)->pos;
+ id = -1;
+ break;
+ }
+
+ CBrightLights::RegisterOne(pos1, ent->GetUp(), ent->GetRight(), CVector(0.0f, 0.0f, 0.0f), id + BRIGHTLIGHT_TRAFFIC_GREEN);
- CVector pos1, pos2;
- uint8 r, g;
- int id;
- switch(phase){
- case CAR_LIGHTS_GREEN:
- r = 0;
- g = 255;
- pos1 = ent->GetMatrix() * CVector(x, yMax, zMin);
- pos2 = ent->GetMatrix() * CVector(x, yMin, zMin);
- id = 0;
- break;
- case CAR_LIGHTS_YELLOW:
- r = 255;
- g = 128;
- pos1 = ent->GetMatrix() * CVector(x, yMax, (zMin+zMax)/2.0f);
- pos2 = ent->GetMatrix() * CVector(x, yMin, (zMin+zMax)/2.0f);
- id = 1;
- break;
- case CAR_LIGHTS_RED:
- default:
- r = 255;
- g = 0;
- pos1 = ent->GetMatrix() * CVector(x, yMax, zMax);
- pos2 = ent->GetMatrix() * CVector(x, yMin, zMax);
- id = 2;
- break;
+ if (CWeather::TrafficLightBrightness > 0.5f)
+ CPointLights::AddLight(CPointLights::LIGHT_POINT,
+ pos1, CVector(0.0f, 0.0f, 0.0f), 8.0f,
+ r / 255.0f, g / 255.0f, 0 / 255.0f, CPointLights::FOG_NORMAL, true);
+
+ if (CWeather::TrafficLightBrightness > 0.05f)
+ CShadows::StoreStaticShadow((uintptr)ent,
+ SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &pos1,
+ 8.0f, 0.0f, 0.0f, -8.0f, 128,
+ r * CTimeCycle::GetLightOnGroundBrightness() * CWeather::TrafficLightBrightness / 8.0f,
+ g * CTimeCycle::GetLightOnGroundBrightness() * CWeather::TrafficLightBrightness / 8.0f,
+ 0 * CTimeCycle::GetLightOnGroundBrightness() * CWeather::TrafficLightBrightness / 8.0f,
+ 12.0f, 1.0f, 40.0f, false, 0.0f);
+
+ if (DotProduct(TheCamera.GetForward(), ent->GetForward()) < 0.0f)
+ CCoronas::RegisterCorona((uintptr)ent + id,
+ r * CTimeCycle::GetSpriteBrightness() * 0.7f,
+ g * CTimeCycle::GetSpriteBrightness() * 0.7f,
+ 0 * CTimeCycle::GetSpriteBrightness() * 0.7f,
+ 255,
+ pos1, 1.75f * CTimeCycle::GetSpriteSize(), 50.0f,
+ CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON,
+ CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
}
+ else if (MI_TRAFFICLIGHTS_MIAMI == m || MI_TRAFFICLIGHTS_TWOVERTICAL == m) {
+ CBaseModelInfo* mi = CModelInfo::GetModelInfo(ent->GetModelIndex());
+ CVector pos1, pos2;
+ uint8 r, g;
+ int id;
+ if (MI_TRAFFICLIGHTS_MIAMI == m) {
+ switch (phase) {
+ case CAR_LIGHTS_GREEN:
+ r = 0;
+ g = 255;
+ pos1 = ent->GetMatrix() * mi->Get2dEffect(4)->pos;
+ pos2 = ent->GetMatrix() * mi->Get2dEffect(5)->pos;
+ id = 0;
+ break;
+ case CAR_LIGHTS_YELLOW:
+ r = 255;
+ g = 128;
+ pos1 = ent->GetMatrix() * mi->Get2dEffect(2)->pos;
+ pos2 = ent->GetMatrix() * mi->Get2dEffect(3)->pos;
+ id = 1;
+ break;
+ case CAR_LIGHTS_RED:
+ r = 255;
+ g = 0;
+ pos1 = ent->GetMatrix() * mi->Get2dEffect(0)->pos;
+ pos2 = ent->GetMatrix() * mi->Get2dEffect(1)->pos;
+ id = 2;
+ break;
+ default:
+ r = 0;
+ g = 0;
+ pos1 = ent->GetMatrix() * mi->Get2dEffect(2)->pos;
+ pos2 = ent->GetMatrix() * mi->Get2dEffect(3)->pos;
+ id = -1;
+ break;
+ }
+ }
+ else {
+ switch (phase) {
+ case CAR_LIGHTS_GREEN:
+ r = 0;
+ g = 255;
+ pos1 = ent->GetMatrix() * mi->Get2dEffect(2)->pos;
+ pos2 = ent->GetMatrix() * mi->Get2dEffect(5)->pos;
+ id = 0;
+ break;
+ case CAR_LIGHTS_YELLOW:
+ r = 255;
+ g = 128;
+ pos1 = ent->GetMatrix() * mi->Get2dEffect(1)->pos;
+ pos2 = ent->GetMatrix() * mi->Get2dEffect(4)->pos;
+ id = 1;
+ break;
+ case CAR_LIGHTS_RED:
+ r = 255;
+ g = 0;
+ pos1 = ent->GetMatrix() * mi->Get2dEffect(0)->pos;
+ pos2 = ent->GetMatrix() * mi->Get2dEffect(3)->pos;
+ id = 2;
+ break;
+ default:
+ r = 0;
+ g = 0;
+ pos1 = ent->GetMatrix() * mi->Get2dEffect(1)->pos;
+ pos2 = ent->GetMatrix() * mi->Get2dEffect(4)->pos;
+ id = -1;
+ break;
+ }
+ }
- if(CClock::GetHours() > 19 || CClock::GetHours() < 6 || CWeather::Foggyness > 0.05f)
- CPointLights::AddLight(CPointLights::LIGHT_POINT,
- pos1, CVector(0.0f, 0.0f, 0.0f), 8.0f,
- r/255.0f, g/255.0f, 0/255.0f, CPointLights::FOG_NORMAL, true);
-
- CShadows::StoreStaticShadow((uintptr)ent,
- SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &pos1,
- 8.0f, 0.0f, 0.0f, -8.0f, 128,
- r*CTimeCycle::GetLightOnGroundBrightness()/8.0f,
- g*CTimeCycle::GetLightOnGroundBrightness()/8.0f,
- 0*CTimeCycle::GetLightOnGroundBrightness()/8.0f,
- 12.0f, 1.0f, 40.0f, false, 0.0f);
-
- if(DotProduct(TheCamera.GetForward(), ent->GetForward()) < 0.0f)
- CCoronas::RegisterCorona((uintptr)ent + id,
- r*CTimeCycle::GetSpriteBrightness()*0.7f,
- g*CTimeCycle::GetSpriteBrightness()*0.7f,
- 0*CTimeCycle::GetSpriteBrightness()*0.7f,
- 255,
- pos1, 1.75f*CTimeCycle::GetSpriteSize(), 50.0f,
- CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON,
- CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
- else
- CCoronas::RegisterCorona((uintptr)ent + id + 3,
- r*CTimeCycle::GetSpriteBrightness()*0.7f,
- g*CTimeCycle::GetSpriteBrightness()*0.7f,
- 0*CTimeCycle::GetSpriteBrightness()*0.7f,
- 255,
- pos2, 1.75f*CTimeCycle::GetSpriteSize(), 50.0f,
- CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON,
- CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
-
- 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;
- static const float left = 1.256f;
- static const float right = 0.706f;
- phase = CTrafficLights::LightForPeds();
- if(phase == PED_LIGHTS_DONT_WALK){
- CVector p0(2.7f, right, top);
- CVector p1(2.7f, left, top);
- CVector p2(2.7f, right, mid);
- CVector p3(2.7f, left, mid);
- CShinyTexts::RegisterOne(ent->GetMatrix()*p0, ent->GetMatrix()*p1, ent->GetMatrix()*p2, ent->GetMatrix()*p3,
- 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
- SHINYTEXT_WALK, 255, 0, 0, 60.0f);
- }else if(phase == PED_LIGHTS_WALK || CTimer::GetTimeInMilliseconds() & 0x100){
- CVector p0(2.7f, right, mid);
- CVector p1(2.7f, left, mid);
- CVector p2(2.7f, right, bot);
- CVector p3(2.7f, left, bot);
- CShinyTexts::RegisterOne(ent->GetMatrix()*p0, ent->GetMatrix()*p1, ent->GetMatrix()*p2, ent->GetMatrix()*p3,
- 1.0f, 0.5f, 0.0f, 0.5f, 1.0f, 1.0f, 0.0f, 1.0f,
- SHINYTEXT_WALK, 255, 255, 255, 60.0f);
+ CVector pos = (pos1 + pos2) / 2;
+ if (id >= 0) {
+ 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);
+ }
+
+ if (CWeather::TrafficLightBrightness > 0.5f)
+ CPointLights::AddLight(CPointLights::LIGHT_POINT,
+ pos, CVector(0.0f, 0.0f, 0.0f), 8.0f,
+ r / 255.0f, g / 255.0f, 0 / 255.0f, CPointLights::FOG_NORMAL, true);
+
+ if (CWeather::TrafficLightBrightness > 0.05f)
+ CShadows::StoreStaticShadow((uintptr)ent,
+ SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &pos,
+ 8.0f, 0.0f, 0.0f, -8.0f, 128,
+ r * CTimeCycle::GetLightOnGroundBrightness() * CWeather::TrafficLightBrightness / 8.0f,
+ g * CTimeCycle::GetLightOnGroundBrightness() * CWeather::TrafficLightBrightness / 8.0f,
+ 0 * CTimeCycle::GetLightOnGroundBrightness() * CWeather::TrafficLightBrightness / 8.0f,
+ 12.0f, 1.0f, 40.0f, false, 0.0f);
+
+ if (id >= 0) {
+ if (DotProduct(TheCamera.GetForward(), ent->GetForward()) > 0.0f)
+ CCoronas::RegisterCorona((uintptr)ent + id,
+ r * CTimeCycle::GetSpriteBrightness() * 0.7f,
+ g * CTimeCycle::GetSpriteBrightness() * 0.7f,
+ 0 * CTimeCycle::GetSpriteBrightness() * 0.7f,
+ 255,
+ pos1, 1.75f * CTimeCycle::GetSpriteSize(), 50.0f,
+ CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON,
+ CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
+ else
+ CCoronas::RegisterCorona((uintptr)ent + id,
+ r * CTimeCycle::GetSpriteBrightness() * 0.7f,
+ g * CTimeCycle::GetSpriteBrightness() * 0.7f,
+ 0 * CTimeCycle::GetSpriteBrightness() * 0.7f,
+ 255,
+ pos2, 1.75f * CTimeCycle::GetSpriteSize(), 50.0f,
+ CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON,
+ CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
+ }
}
}
+bool DoesLineSegmentIntersect(float l1x1, float l1y1, float l1x2, float l1y2, float l2x1, float l2y1, float l2x2, float l2y2)
+{
+ return ((l2y2 - l1y1) * (l1x2 - l1x1) + (l1x1 - l2x2) * (l1y2 - l1y1)) *
+ ((l2y1 - l1y1) * (l1x2 - l1x1) + (l1x1 - l2x1) * (l1y2 - l1y1)) <= 0.0f &&
+ ((l1y2 - l2y1) * (l2x2 - l2x1) + (l2y2 - l2y1) * (l2x1 - l1x2)) *
+ ((l1y1 - l2y1) * (l2x2 - l2x1) + (l2y2 - l2y1) * (l2x1 - l1x1)) <= 0.0f;
+}
+
void
CTrafficLights::ScanForLightsOnMap(void)
{
@@ -145,36 +319,31 @@ 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;
+ CVector pos1 = light->GetMatrix() * CVector(17.0f, 0.0f, 0.0f);
+ CVector pos2 = light->GetMatrix() * CVector(-15.0f, 0.0f, 0.0f);
+
// Check cars
- for(i = 0; i < ThePaths.m_numCarPathLinks; i++){
- CVector2D dist = ThePaths.m_carPathLinks[i].GetPosition() - light->GetPosition();
- float dotY = Abs(DotProduct2D(dist, light->GetForward())); // forward is direction of car light
- float dotX = DotProduct2D(dist, light->GetRight()); // towards base of light
- // it has to be on the correct side of the node and also not very far away
- if(dotX < 0.0f && dotX > -15.0f && dotY < 3.0f){
- float dz = ThePaths.m_pathNodes[ThePaths.m_carPathLinks[i].pathNodeIndex].GetZ() -
- light->GetPosition().z;
- if(dz < 15.0f){
- ThePaths.m_carPathLinks[i].trafficLightType = FindTrafficLightType(light);
- // Find two neighbour nodes of this one
- int n1 = -1;
- int n2 = -1;
- for(j = 0; j < ThePaths.m_numPathNodes; j++)
- for(l = 0; l < ThePaths.m_pathNodes[j].numLinks; l++)
- if(ThePaths.m_carPathConnections[ThePaths.m_pathNodes[j].firstLink + l] == i){
- if(n1 == -1)
- n1 = j;
- else
- n2 = j;
- }
- // What's going on here?
- if(ThePaths.m_pathNodes[n1].numLinks <= ThePaths.m_pathNodes[n2].numLinks)
- n1 = n2;
- if(ThePaths.m_carPathLinks[i].pathNodeIndex != n1)
- ThePaths.m_carPathLinks[i].trafficLightType |= SOME_FLAG;
+ for(i = 0; i < ThePaths.m_numCarPathNodes; i++){
+ if ((ThePaths.m_pathNodes[i].GetPosition() - pos1).MagnitudeSqr() >= SQR(100.0f))
+ continue;
+ for (j = 0; j < ThePaths.m_pathNodes[i].numLinks; j++){
+ int con = ThePaths.ConnectedNode(ThePaths.m_pathNodes[i].firstLink + j);
+ if (i < con) {
+ CVector i_pos = ThePaths.m_pathNodes[i].GetPosition();
+ CVector con_pos = ThePaths.m_pathNodes[con].GetPosition();
+ if (Abs(pos1.z - (i_pos.z + con_pos.z) / 2) < 10.0f &&
+ DoesLineSegmentIntersect(pos1.x, pos1.y, pos2.x, pos2.y, i_pos.x, i_pos.y, con_pos.x, con_pos.y)) {
+ //debug("Setting up light: nodes %f %f %f - %f %f %f, light %f %f %f - %f %f %f\n", i_pos.x, i_pos.y, i_pos.z, con_pos.x, con_pos.y, con_pos.z, pos1.x, pos1.y, pos1.z, pos2.x, pos2.y, pos2.z);
+ int link = ThePaths.m_carPathConnections[ThePaths.m_pathNodes[i].firstLink + j];
+ ThePaths.m_carPathLinks[link].trafficLightType = FindTrafficLightType(light);
+ if (ThePaths.m_pathNodes[i].numLinks > ThePaths.m_pathNodes[con].numLinks)
+ con = i;
+ if (ThePaths.m_carPathLinks[link].pathNodeIndex != con)
+ ThePaths.m_carPathLinks[link].trafficLightDirection = true;
+ }
}
}
}
@@ -205,15 +374,18 @@ bool
CTrafficLights::ShouldCarStopForLight(CVehicle *vehicle, bool alwaysStop)
{
int node, type;
+ bool direction;
node = vehicle->AutoPilot.m_nNextPathNodeInfo;
type = ThePaths.m_carPathLinks[node].trafficLightType;
+ direction = ThePaths.m_carPathLinks[node].trafficLightDirection;
+
if(type){
- if((type & SOME_FLAG || ThePaths.m_carPathLinks[node].pathNodeIndex == vehicle->AutoPilot.m_nNextRouteNode) &&
- (!(type & SOME_FLAG) || ThePaths.m_carPathLinks[node].pathNodeIndex != vehicle->AutoPilot.m_nNextRouteNode))
+ if((direction || ThePaths.m_carPathLinks[node].pathNodeIndex == vehicle->AutoPilot.m_nNextRouteNode) &&
+ (!direction || ThePaths.m_carPathLinks[node].pathNodeIndex != vehicle->AutoPilot.m_nNextRouteNode))
if(alwaysStop ||
- (type&~SOME_FLAG) == 1 && LightForCars1() != CAR_LIGHTS_GREEN ||
- (type&~SOME_FLAG) == 2 && LightForCars2() != CAR_LIGHTS_GREEN){
+ type == 1 && LightForCars1() != CAR_LIGHTS_GREEN ||
+ type == 2 && LightForCars2() != CAR_LIGHTS_GREEN){
float dist = DotProduct2D(CVector2D(vehicle->GetPosition()) - ThePaths.m_carPathLinks[node].GetPosition(),
ThePaths.m_carPathLinks[node].GetDirection());
if(vehicle->AutoPilot.m_nNextDirection == -1){
@@ -228,12 +400,13 @@ CTrafficLights::ShouldCarStopForLight(CVehicle *vehicle, bool alwaysStop)
node = vehicle->AutoPilot.m_nCurrentPathNodeInfo;
type = ThePaths.m_carPathLinks[node].trafficLightType;
+ direction = ThePaths.m_carPathLinks[node].trafficLightDirection;
if(type){
- if((type & SOME_FLAG || ThePaths.m_carPathLinks[node].pathNodeIndex == vehicle->AutoPilot.m_nCurrentRouteNode) &&
- (!(type & SOME_FLAG) || ThePaths.m_carPathLinks[node].pathNodeIndex != vehicle->AutoPilot.m_nCurrentRouteNode))
+ if((direction || ThePaths.m_carPathLinks[node].pathNodeIndex == vehicle->AutoPilot.m_nCurrentRouteNode) &&
+ (!direction || ThePaths.m_carPathLinks[node].pathNodeIndex != vehicle->AutoPilot.m_nCurrentRouteNode))
if(alwaysStop ||
- (type&~SOME_FLAG) == 1 && LightForCars1() != CAR_LIGHTS_GREEN ||
- (type&~SOME_FLAG) == 2 && LightForCars2() != CAR_LIGHTS_GREEN){
+ type == 1 && LightForCars1() != CAR_LIGHTS_GREEN ||
+ type == 2 && LightForCars2() != CAR_LIGHTS_GREEN){
float dist = DotProduct2D(CVector2D(vehicle->GetPosition()) - ThePaths.m_carPathLinks[node].GetPosition(),
ThePaths.m_carPathLinks[node].GetDirection());
if(vehicle->AutoPilot.m_nCurrentDirection == -1){
@@ -249,12 +422,13 @@ CTrafficLights::ShouldCarStopForLight(CVehicle *vehicle, bool alwaysStop)
if(vehicle->GetStatus() == STATUS_PHYSICS){
node = vehicle->AutoPilot.m_nPreviousPathNodeInfo;
type = ThePaths.m_carPathLinks[node].trafficLightType;
+ direction = ThePaths.m_carPathLinks[node].trafficLightDirection;
if(type){
- if((type & SOME_FLAG || ThePaths.m_carPathLinks[node].pathNodeIndex == vehicle->AutoPilot.m_nPrevRouteNode) &&
- (!(type & SOME_FLAG) || ThePaths.m_carPathLinks[node].pathNodeIndex != vehicle->AutoPilot.m_nPrevRouteNode))
+ if((direction || ThePaths.m_carPathLinks[node].pathNodeIndex == vehicle->AutoPilot.m_nPrevRouteNode) &&
+ (!direction || ThePaths.m_carPathLinks[node].pathNodeIndex != vehicle->AutoPilot.m_nPrevRouteNode))
if(alwaysStop ||
- (type&~SOME_FLAG) == 1 && LightForCars1() != CAR_LIGHTS_GREEN ||
- (type&~SOME_FLAG) == 2 && LightForCars2() != CAR_LIGHTS_GREEN){
+ type == 1 && LightForCars1() != CAR_LIGHTS_GREEN ||
+ type == 2 && LightForCars2() != CAR_LIGHTS_GREEN){
float dist = DotProduct2D(CVector2D(vehicle->GetPosition()) - ThePaths.m_carPathLinks[node].GetPosition(),
ThePaths.m_carPathLinks[node].GetDirection());
if(vehicle->AutoPilot.m_nPreviousDirection == -1){
@@ -274,8 +448,12 @@ CTrafficLights::ShouldCarStopForLight(CVehicle *vehicle, bool alwaysStop)
bool
CTrafficLights::ShouldCarStopForBridge(CVehicle *vehicle)
{
+#ifdef GTA_BRIDGE
return ThePaths.m_carPathLinks[vehicle->AutoPilot.m_nNextPathNodeInfo].bBridgeLights &&
!ThePaths.m_carPathLinks[vehicle->AutoPilot.m_nCurrentPathNodeInfo].bBridgeLights;
+#else
+ return false;
+#endif
}
int
@@ -304,6 +482,12 @@ CTrafficLights::LightForPeds(void)
uint8
CTrafficLights::LightForCars1(void)
{
+ if (CWeather::Wind > 1.1f)
+ return CAR_LIGHTS_GREEN;
+
+ if (bGreenLightsCheat)
+ return CAR_LIGHTS_GREEN;
+
uint32 period = CTimer::GetTimeInMilliseconds() % 16384;
if(period < 5000)
@@ -317,6 +501,12 @@ CTrafficLights::LightForCars1(void)
uint8
CTrafficLights::LightForCars2(void)
{
+ if (CWeather::Wind > 1.1f)
+ return CAR_LIGHTS_GREEN;
+
+ if (bGreenLightsCheat)
+ return CAR_LIGHTS_GREEN;
+
uint32 period = CTimer::GetTimeInMilliseconds() % 16384;
if(period < 6000)
@@ -328,3 +518,19 @@ CTrafficLights::LightForCars2(void)
else
return CAR_LIGHTS_RED;
}
+
+uint8
+CTrafficLights::LightForCars1_Visual(void)
+{
+ if (CWeather::Wind <= 1.1f)
+ return LightForCars1();
+ return (CTimer::GetTimeInMilliseconds() & 0x400 ? CAR_LIGHTS_NONE : CAR_LIGHTS_YELLOW);
+}
+
+uint8
+CTrafficLights::LightForCars2_Visual(void)
+{
+ if (CWeather::Wind <= 1.1f)
+ return LightForCars2();
+ return (CTimer::GetTimeInMilliseconds() & 0x400 ? CAR_LIGHTS_NONE : CAR_LIGHTS_YELLOW);
+}
diff --git a/src/control/TrafficLights.h b/src/control/TrafficLights.h
index f3df6cd5..8dba45e1 100644
--- a/src/control/TrafficLights.h
+++ b/src/control/TrafficLights.h
@@ -10,18 +10,23 @@ enum {
CAR_LIGHTS_GREEN = 0,
CAR_LIGHTS_YELLOW,
- CAR_LIGHTS_RED
+ CAR_LIGHTS_RED,
+ CAR_LIGHTS_NONE
};
class CTrafficLights
{
public:
+ static bool bGreenLightsCheat;
+
static void DisplayActualLight(CEntity *ent);
static void ScanForLightsOnMap(void);
static int FindTrafficLightType(CEntity *light);
static uint8 LightForPeds(void);
static uint8 LightForCars1(void);
static uint8 LightForCars2(void);
+ static uint8 LightForCars1_Visual(void);
+ static uint8 LightForCars2_Visual(void);
static bool ShouldCarStopForLight(CVehicle*, bool);
static bool ShouldCarStopForBridge(CVehicle*);
};
diff --git a/src/core/AnimViewer.cpp b/src/core/AnimViewer.cpp
index 946693a7..562b9c15 100644
--- a/src/core/AnimViewer.cpp
+++ b/src/core/AnimViewer.cpp
@@ -12,11 +12,13 @@
#include "General.h"
#include "Camera.h"
#include "Vehicle.h"
+#include "Bike.h"
#include "PlayerSkin.h"
#include "PlayerInfo.h"
#include "World.h"
#include "Renderer.h"
#include "AnimManager.h"
+#include "AnimBlendAssocGroup.h"
#include "AnimViewer.h"
#include "PlayerPed.h"
#include "Pools.h"
@@ -45,14 +47,11 @@ CEntity *CAnimViewer::pTarget = nil;
void
CAnimViewer::Render(void) {
if (pTarget) {
-// pTarget->GetPosition() = CVector(0.0f, 0.0f, 0.0f); // Only on Mobile
if (pTarget) {
#ifdef FIX_BUGS
-#ifdef PED_SKIN
- if(pTarget->IsPed() && IsClumpSkinned(pTarget->GetClump()))
+ if(pTarget->IsPed())
((CPed*)pTarget)->UpdateRpHAnim();
#endif
-#endif
pTarget->Render();
CRenderer::RenderOneNonRoad(pTarget);
}
@@ -61,13 +60,14 @@ CAnimViewer::Render(void) {
void
CAnimViewer::Initialise(void) {
- // we need messages, messages needs hud, hud needs this
+
+ // we need messages, messages needs hud, hud needs those
+ int hudSlot = CTxdStore::AddTxdSlot("hud");
+ CTxdStore::LoadTxd(hudSlot, "MODELS/HUD.TXD");
CHud::m_Wants_To_Draw_Hud = false;
animTxdSlot = CTxdStore::AddTxdSlot("generic");
CTxdStore::Create(animTxdSlot);
- int hudSlot = CTxdStore::AddTxdSlot("hud");
- CTxdStore::LoadTxd(hudSlot, "MODELS/HUD.TXD");
int particleSlot = CTxdStore::AddTxdSlot("particle");
CTxdStore::LoadTxd(particleSlot, "MODELS/PARTICLE.TXD");
CTxdStore::SetCurrentTxd(animTxdSlot);
@@ -76,7 +76,6 @@ CAnimViewer::Initialise(void) {
TheCamera.Init();
TheCamera.SetRwCamera(Scene.camera);
TheCamera.Cams[TheCamera.ActiveCam].Distance = 5.0f;
-
ThePaths.Init();
ThePaths.AllocatePathFindInfoMem(4500);
CCollision::Init();
@@ -90,14 +89,16 @@ CAnimViewer::Initialise(void) {
CPedStats::Initialise();
CMessages::Init();
CdStreamAddImage("MODELS\\GTA3.IMG");
+ CFileLoader::LoadLevel("DATA\\DEFAULT.DAT");
CFileLoader::LoadLevel("DATA\\ANIMVIEWER.DAT");
CStreaming::Init();
+ for(int i = 0; i < MODELINFOSIZE; i++)
+ if(CModelInfo::GetModelInfo(i))
+ CModelInfo::GetModelInfo(i)->ConvertAnimFileIndex();
CStreaming::LoadInitialPeds();
CStreaming::RequestSpecialModel(MI_PLAYER, "player", STREAMFLAGS_DONT_REMOVE);
CStreaming::LoadAllRequestedModels(false);
CRenderer::Init();
- CRadar::Initialise();
- CRadar::LoadTextures();
CVehicleModelInfo::LoadVehicleColours();
#ifdef FIX_BUGS
CVehicleModelInfo::LoadEnvironmentMaps();
@@ -105,14 +106,13 @@ CAnimViewer::Initialise(void) {
CAnimManager::LoadAnimFiles();
CWorld::PlayerInFocus = 0;
CWeapon::InitialiseWeapons();
- CShadows::Init();
CPed::Initialise();
CTimer::Initialise();
CClock::Initialise(60000);
CTimeCycle::Initialise();
CCarCtrl::Init();
CPlayerPed *player = new CPlayerPed();
- player->SetPosition(0.0f, 0.0f, 0.0f); // This is 1000.f for all axes on Xbox, but 0.f on mobile?
+ player->SetPosition(1000.0f, 1000.0f, 1000.0f);
CWorld::Players[0].m_pPed = player;
CDraw::SetFOV(120.0f);
CDraw::ms_fLODDistance = 500.0f;
@@ -138,12 +138,27 @@ CAnimViewer::Initialise(void) {
}
CFileMgr::CloseFile(fd);
} else {
- // From xbox
- CStreaming::RequestSpecialChar(0, "luigi", STREAMFLAGS_DONT_REMOVE);
- CStreaming::RequestSpecialChar(1, "joey", STREAMFLAGS_DONT_REMOVE);
- CStreaming::RequestSpecialChar(2, "tony", STREAMFLAGS_DONT_REMOVE);
- CStreaming::RequestSpecialChar(3, "curly", STREAMFLAGS_DONT_REMOVE);
+ // TODO? maybe request some special models here so the thing doesn't crash
}
+
+ // From LCS. idk if needed
+ int vanBlock = CAnimManager::GetAnimationBlockIndex("van");
+ int bikesBlock = CAnimManager::GetAnimationBlockIndex("bikes");
+ int bikevBlock = CAnimManager::GetAnimationBlockIndex("bikev");
+ int bikehBlock = CAnimManager::GetAnimationBlockIndex("bikeh");
+ int bikedBlock = CAnimManager::GetAnimationBlockIndex("biked");
+ CStreaming::FlushRequestList();
+ CStreaming::RequestAnim(vanBlock, STREAMFLAGS_DEPENDENCY);
+ CStreaming::RequestAnim(bikesBlock, STREAMFLAGS_DEPENDENCY);
+ CStreaming::RequestAnim(bikevBlock, STREAMFLAGS_DEPENDENCY);
+ CStreaming::RequestAnim(bikehBlock, STREAMFLAGS_DEPENDENCY);
+ CStreaming::RequestAnim(bikedBlock, STREAMFLAGS_DEPENDENCY);
+ CStreaming::LoadAllRequestedModels(false);
+ CAnimManager::AddAnimBlockRef(vanBlock);
+ CAnimManager::AddAnimBlockRef(bikesBlock);
+ CAnimManager::AddAnimBlockRef(bikevBlock);
+ CAnimManager::AddAnimBlockRef(bikehBlock);
+ CAnimManager::AddAnimBlockRef(bikedBlock);
}
int
@@ -270,6 +285,8 @@ CAnimViewer::Update(void)
pTarget = new CAutomobile(modelId, RANDOM_VEHICLE);
} else if (veh->m_vehicleType == VEHICLE_TYPE_BOAT) {
pTarget = new CBoat(modelId, RANDOM_VEHICLE);
+ } else if (veh->m_vehicleType == VEHICLE_TYPE_BIKE) {
+ pTarget = new CBike(modelId, RANDOM_VEHICLE);
} else {
pTarget = new CObject(modelId, true);
if (!modelInfo->GetColModel()) {
@@ -300,7 +317,6 @@ CAnimViewer::Update(void)
pTarget->GetMatrix().GetPosition().z = 10.0f;
#else
pTarget->GetMatrix().GetPosition().z = 0.0f;
-
#endif
if (modelInfo->GetModelType() == MITYPE_PED) {
@@ -349,16 +365,15 @@ CAnimViewer::Update(void)
CMessages::AddMessage(gUString, 1000, 0);
// Originally it was GetPad(1)->LeftShoulder2
} else if (pad->NewState.Triangle) {
-#ifdef PED_SKIN
- if(IsClumpSkinned(pTarget->GetClump()))
- ((CPedModelInfo *)CModelInfo::GetModelInfo(pTarget->GetModelIndex()))->AnimatePedColModelSkinned(pTarget->GetClump());
- else
-#endif
- CPedModelInfo::AnimatePedColModel(((CPedModelInfo *)CModelInfo::GetModelInfo(pTarget->GetModelIndex()))->GetHitColModel(),
- RpClumpGetFrame(pTarget->GetClump()));
+ ((CPedModelInfo *)CModelInfo::GetModelInfo(pTarget->GetModelIndex()))->AnimatePedColModelSkinned(pTarget->GetClump());
AsciiToUnicode("Ped Col model will be animated as long as you hold the button", gUString);
CMessages::AddMessage(gUString, 100, 0);
}
+
+ // From LCS
+ if (CAnimManager::GetAnimAssocGroups()[animGroup].numAssociations <= animId)
+ animId = 0;
+
} else if (modelInfo->GetModelType() == MITYPE_VEHICLE) {
if (pad->GetLeftShoulder1JustDown()) {
diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp
index ecfade74..89a48438 100644
--- a/src/core/Cam.cpp
+++ b/src/core/Cam.cpp
@@ -6,6 +6,7 @@
#include "Vehicle.h"
#include "Automobile.h"
#include "Boat.h"
+#include "Bones.h"
#include "Ped.h"
#include "PlayerPed.h"
#include "CopPed.h"
@@ -14,6 +15,7 @@
#include "Pad.h"
#include "Frontend.h"
#include "General.h"
+#include "Timecycle.h"
#include "Renderer.h"
#include "Shadows.h"
#include "Hud.h"
@@ -25,10 +27,15 @@
#include "Debug.h"
#include "Camera.h"
#include "DMAudio.h"
+#include "Bike.h"
+#include "Pickups.h"
bool PrintDebugCode = false;
int16 DebugCamMode;
+extern float fRangePlayerRadius;
+extern float fCloseNearClipLimit;
+
#ifdef FREE_CAM
bool CCamera::bFreeCam = false;
int nPreviousMode = -1;
@@ -56,6 +63,8 @@ CCam::Init(void)
m_pLastPedLookedAt = nil;
ResetStatics = true;
Beta = 0.0f;
+ m_fTilt = 0.0f;
+ m_fTiltSpeed = 0.0f;
m_bFixingBeta = false;
CA_MIN_DISTANCE = 0.0f;
CA_MAX_DISTANCE = 0.0f;
@@ -79,9 +88,11 @@ CCam::Init(void)
m_fBufferedTargetOrientation = 0.0f;
m_fBufferedTargetOrientationSpeed = 0.0f;
m_fDimensionOfHighestNearCar = 0.0f;
- m_fRoadOffSet = 0.0f;
}
+float PLAYERPED_LEVEL_SMOOTHING_CONST_INV = 0.6f;
+float PLAYERPED_TREND_SMOOTHING_CONST_INV = 0.8f;
+
void
CCam::Process(void)
{
@@ -89,6 +100,9 @@ CCam::Process(void)
float TargetSpeedVar = 0.0f;
float TargetOrientation = 0.0f;
+ static CVector SmoothedPos(0.0f, 0.0f, 10000.0f);
+ static CVector SmoothedSpeed(0.0f, 0.0f, 0.0f);
+
if(CamTargetEntity == nil)
CamTargetEntity = TheCamera.pTargetEntity;
@@ -125,7 +139,27 @@ CCam::Process(void)
TargetSpeedVar = -Min(Sqrt(SQR(FwdSpeedX) + SQR(FwdSpeedY))/1.8f, 0.5f);
SpeedVar = 0.895f*SpeedVar + 0.105*TargetSpeedVar;
}else{
- CameraTarget = CamTargetEntity->GetPosition();
+ if(CamTargetEntity == FindPlayerPed()){
+ // Some fancy smoothing of player position and speed
+ float LevelSmoothing = 1.0f - Pow(PLAYERPED_LEVEL_SMOOTHING_CONST_INV, CTimer::GetTimeStep());
+ float TrendSmoothing = 1.0f - Pow(PLAYERPED_TREND_SMOOTHING_CONST_INV, CTimer::GetTimeStep());
+
+ CVector NewSmoothedPos, NewSmoothedSpeed;
+ if((SmoothedPos - CamTargetEntity->GetPosition()).MagnitudeSqr() > SQR(3.0f) ||
+ CTimer::GetTimeStep() < 0.2f || Using3rdPersonMouseCam()){
+ // Reset values
+ NewSmoothedPos = CamTargetEntity->GetPosition();
+ NewSmoothedSpeed = CVector(0.0f, 0.0f, 0.0f);
+ }else{
+ NewSmoothedPos = LevelSmoothing*CamTargetEntity->GetPosition() + (1.0f-LevelSmoothing)*(SmoothedPos + SmoothedSpeed*CTimer::GetTimeStep());
+ NewSmoothedSpeed = TrendSmoothing*(NewSmoothedPos-SmoothedPos)/CTimer::GetTimeStep() + (1.0f-TrendSmoothing)*SmoothedSpeed;
+ }
+
+ CameraTarget = NewSmoothedPos;
+ SmoothedPos = NewSmoothedPos;
+ SmoothedSpeed = NewSmoothedSpeed;
+ }else
+ CameraTarget = CamTargetEntity->GetPosition();
if(CamTargetEntity->GetForward().x == 0.0f && CamTargetEntity->GetForward().y == 0.0f)
TargetOrientation = 0.0f;
@@ -138,7 +172,7 @@ CCam::Process(void)
switch(Mode){
case MODE_TOPDOWN:
case MODE_GTACLASSIC:
- Process_TopDown(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
+ // Process_TopDown(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
break;
case MODE_BEHINDCAR:
Process_BehindCar(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
@@ -161,6 +195,7 @@ CCam::Process(void)
Process_Debug(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
break;
case MODE_SNIPER:
+ case MODE_CAMERA:
Process_Sniper(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
break;
case MODE_ROCKETLAUNCHER:
@@ -169,14 +204,12 @@ CCam::Process(void)
case MODE_MODELVIEW:
Process_ModelView(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
break;
- case MODE_BILL:
- Process_Bill(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
- break;
+// case MODE_BILL:
case MODE_SYPHON:
Process_Syphon(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
break;
case MODE_CIRCLE:
- Process_Circle(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
+// Process_Circle(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
break;
// case MODE_CHEESYZOOM:
case MODE_WHEELCAM:
@@ -199,15 +232,9 @@ CCam::Process(void)
#endif
Process_Cam_On_A_String(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
break;
- case MODE_REACTION:
- Process_ReactionCam(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
- break;
- case MODE_FOLLOW_PED_WITH_BIND:
- Process_FollowPed_WithBinding(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
- break;
- case MODE_CHRIS:
- Process_Chris_With_Binding_PlusRotation(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
- break;
+// case MODE_REACTION:
+// case MODE_FOLLOW_PED_WITH_BIND:
+// case MODE_CHRIS:
case MODE_BEHINDBOAT:
#ifdef FREE_CAM
if (CCamera::bFreeCam)
@@ -219,18 +246,10 @@ CCam::Process(void)
case MODE_PLAYER_FALLEN_WATER:
Process_Player_Fallen_Water(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
break;
- case MODE_CAM_ON_TRAIN_ROOF:
- Process_Cam_On_Train_Roof(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
- break;
- case MODE_CAM_RUNNING_SIDE_TRAIN:
- Process_Cam_Running_Side_Train(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
- break;
- case MODE_BLOOD_ON_THE_TRACKS:
- Process_Blood_On_The_Tracks(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
- break;
- case MODE_IM_THE_PASSENGER_WOOWOO:
- Process_Im_The_Passenger_Woo_Woo(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
- break;
+// case MODE_CAM_ON_TRAIN_ROOF:
+// case MODE_CAM_RUNNING_SIDE_TRAIN:
+// case MODE_BLOOD_ON_THE_TRACKS:
+// case MODE_IM_THE_PASSENGER_WOOWOO:
case MODE_SYPHON_CRIM_IN_FRONT:
Process_Syphon_Crim_In_Front(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
break;
@@ -246,7 +265,7 @@ CCam::Process(void)
ProcessArrestCamTwo();
break;
case MODE_M16_1STPERSON:
- case MODE_HELICANNON_1STPERSON: // miami
+ case MODE_HELICANNON_1STPERSON:
Process_M16_1stPerson(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
break;
case MODE_SPECIAL_FIXED_FOR_SYPHON:
@@ -255,8 +274,11 @@ CCam::Process(void)
case MODE_FIGHT_CAM:
Process_Fight_Cam(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
break;
+ case MODE_LIGHTHOUSE:
+ Process_LightHouse(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
+ break;
case MODE_TOP_DOWN_PED:
- Process_TopDownPed(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
+ // Process_TopDownPed(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
break;
case MODE_SNIPER_RUNABOUT:
case MODE_ROCKETLAUNCHER_RUNABOUT:
@@ -292,13 +314,19 @@ CCam::Process(void)
LookingRight = false;
SourceBeforeLookBehind = Source;
if(&TheCamera.Cams[TheCamera.ActiveCam] == this){
- if((Mode == MODE_CAM_ON_A_STRING || Mode == MODE_1STPERSON || Mode == MODE_BEHINDBOAT) &&
+ if((Mode == MODE_CAM_ON_A_STRING || Mode == MODE_1STPERSON || Mode == MODE_BEHINDBOAT || Mode == MODE_BEHINDCAR) &&
CamTargetEntity->IsVehicle()){
+ bool bDisableLR = CamTargetEntity &&
+ (((CVehicle*)CamTargetEntity)->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI || CamTargetEntity->GetModelIndex() == MI_RCBARON);
if(CPad::GetPad(0)->GetLookBehindForCar()){
LookBehind();
if(DirectionWasLooking != LOOKING_BEHIND)
TheCamera.m_bJust_Switched = true;
DirectionWasLooking = LOOKING_BEHIND;
+ }else if(bDisableLR){
+ if(DirectionWasLooking != LOOKING_FORWARD)
+ TheCamera.m_bJust_Switched = true;
+ DirectionWasLooking = LOOKING_FORWARD;
}else if(CPad::GetPad(0)->GetLookLeft()){
LookLeft();
if(DirectionWasLooking != LOOKING_LEFT)
@@ -327,7 +355,7 @@ CCam::Process(void)
}
if(Mode == MODE_SNIPER || Mode == MODE_ROCKETLAUNCHER || Mode == MODE_M16_1STPERSON ||
- Mode == MODE_1STPERSON || Mode == MODE_HELICANNON_1STPERSON || GetWeaponFirstPersonOn())
+ Mode == MODE_1STPERSON || Mode == MODE_HELICANNON_1STPERSON || Mode == MODE_CAMERA || GetWeaponFirstPersonOn())
ClipIfPedInFrontOfPlayer();
}
@@ -371,22 +399,19 @@ MakeAngleLessThan180(float &Angle)
void
CCam::ProcessSpecialHeightRoutines(void)
{
- int i = 0;
+ int i;
bool StandingOnBoat = false;
static bool PreviouslyFailedRoadHeightCheck = false;
CVector CamToTarget, CamToPed;
float DistOnGround, BetaAngle;
CPed *Player;
- int ClosestPed = 0;
- bool FoundPed = false;
- float ClosestPedDist, PedZDist;
+ float PedZDist;
CColPoint colPoint;
CamToTarget = TheCamera.pTargetEntity->GetPosition() - TheCamera.GetGameCamPosition();
DistOnGround = CamToTarget.Magnitude2D();
BetaAngle = CGeneral::GetATanOfXY(CamToTarget.x, CamToTarget.y);
m_bTheHeightFixerVehicleIsATrain = false;
- ClosestPedDist = 0.0f;
// CGeneral::GetATanOfXY(TheCamera.GetForward().x, TheCamera.GetForward().y);
Player = CWorld::Players[CWorld::PlayerInFocus].m_pPed;
@@ -398,65 +423,61 @@ CCam::ProcessSpecialHeightRoutines(void)
((CVehicle*)FindPlayerPed()->m_pCurSurface)->IsBoat())
StandingOnBoat = true;
+ float FoundPedZ = -100.0f;
+
// Move up the camera if there is a ped close to it
- if(Mode == MODE_FOLLOWPED || Mode == MODE_FIGHT_CAM){
- // Find ped closest to camera
- while(i < Player->m_numNearPeds){
- if(Player->m_nearPeds[i] && Player->m_nearPeds[i]->GetPedState() != PED_DEAD){
- CamToPed = Player->m_nearPeds[i]->GetPosition() - TheCamera.GetGameCamPosition();
- if(FoundPed){
- if(CamToPed.Magnitude2D() < ClosestPedDist){
- ClosestPed = i;
- ClosestPedDist = CamToPed.Magnitude2D();
+ if(Mode == MODE_FOLLOWPED || Mode == MODE_FIGHT_CAM || Mode == MODE_PILLOWS_PAPS){
+ // Find highest ped close to camera
+ for(i = 0; i < Player->m_numNearPeds; i++){
+ CPed *nearPed = Player->m_nearPeds[i];
+ if(nearPed && nearPed->GetPedState() != PED_DEAD){
+ CamToPed = nearPed->GetPosition() - TheCamera.GetGameCamPosition();
+ if(Abs(CamToPed.z) < 1.0f){
+ float DistSq = CamToPed.MagnitudeSqr();
+ if(DistSq < SQR(2.1f)){
+ if(nearPed->GetPosition().z > FoundPedZ)
+ FoundPedZ = nearPed->GetPosition().z;
+ }else{
+ float Dist = Sqrt(DistSq);
+ CamToPed /= Dist;
+ // strange calculation
+ CVector PlayerCamSpeed = DotProduct(Front, Player->m_vecMoveSpeed)*Front;
+ float SpeedDiff = DotProduct(PlayerCamSpeed - nearPed->m_vecMoveSpeed, CamToPed);
+ if(SpeedDiff > 0.01f &&
+ (m_fPedBetweenCameraHeightOffset > 0.0f && (Dist-2.1f)/SpeedDiff < 75.0f ||
+ m_fPedBetweenCameraHeightOffset <= 0.0f && (Dist-2.1f)/SpeedDiff < 75.0f * 0.1f))
+ if(nearPed->GetPosition().z > FoundPedZ)
+ FoundPedZ = nearPed->GetPosition().z;
}
- }else{
- FoundPed = true;
- ClosestPed = i;
- ClosestPedDist = CamToPed.Magnitude2D();
}
}
- i++;
}
- if(FoundPed){
+ if(FoundPedZ > -99.0f){
float Offset = 0.0f;
- CPed *Ped = Player->m_nearPeds[ClosestPed];
- CamToPed = Ped->GetPosition() - TheCamera.GetGameCamPosition();
PedZDist = 0.0f;
- float dist = CamToPed.Magnitude2D(); // should be same as ClosestPedDist
- if(dist < 2.1f){
- // Ped is close to camera, move up
-
- // Z Distance between player and close ped
- PedZDist = 0.0f;
- if(Ped->bIsStanding)
- PedZDist = Ped->GetPosition().z - Player->GetPosition().z;
- // Ignore if too distant
- if(PedZDist > 1.2f || PedZDist < -1.2f)
- PedZDist = 0.0f;
-
- float DistScale = (2.1f - dist)/2.1f;
- if(Mode == MODE_FOLLOWPED){
- if(TheCamera.PedZoomIndicator == CAM_ZOOM_1)
- Offset = 0.45f*DistScale + PedZDist;
- if(TheCamera.PedZoomIndicator == CAM_ZOOM_2)
- Offset = 0.35f*DistScale + PedZDist;
- if(TheCamera.PedZoomIndicator == CAM_ZOOM_3)
- Offset = 0.25f*DistScale + PedZDist;
- if(Abs(CGeneral::GetRadianAngleBetweenPoints(CamToPed.x, CamToPed.y, CamToTarget.x, CamToTarget.y)) > HALFPI)
- Offset += 0.3f;
- m_fPedBetweenCameraHeightOffset = Offset + 1.3f;
- PedZDist = 0.0f;
- }else if(Mode == MODE_FIGHT_CAM)
- m_fPedBetweenCameraHeightOffset = PedZDist + 1.3f + 0.5f;
- }else
- m_fPedBetweenCameraHeightOffset = 0.0f;
+ if(FoundPedZ > Player->GetPosition().z)
+ PedZDist = FoundPedZ - Player->GetPosition().z;
+
+ if(Mode == MODE_FOLLOWPED){
+ if(TheCamera.PedZoomIndicator == CAM_ZOOM_1 &&
+ ((CPed*)CamTargetEntity)->GetPedState() != PED_ENTER_CAR &&
+ ((CPed*)CamTargetEntity)->GetPedState() != PED_CARJACK)
+ Offset = 0.45f + PedZDist;
+ // BUG: overrides this ^ case
+ if(TheCamera.PedZoomIndicator == CAM_ZOOM_2 || TheCamera.PedZoomIndicator == CAM_ZOOM_1)
+ Offset = 0.35f + PedZDist;
+ if(TheCamera.PedZoomIndicator == CAM_ZOOM_3)
+ Offset = 0.25f + PedZDist;
+ m_fPedBetweenCameraHeightOffset = Offset + 1.3f;
+ }else if(Mode == MODE_FIGHT_CAM)
+ m_fPedBetweenCameraHeightOffset = PedZDist + 1.3f + 0.5f;
+ else if(Mode == MODE_PILLOWS_PAPS)
+ m_fPedBetweenCameraHeightOffset = PedZDist + 1.3f + 0.45f;
}else{
- PedZDist = 0.0f;
m_fPedBetweenCameraHeightOffset = 0.0f;
}
- }else
- PedZDist = 0.0f;
+ }
// Move camera up for vehicles in the way
@@ -465,6 +486,8 @@ CCam::ProcessSpecialHeightRoutines(void)
CEntity *vehicle = nil;
float TestDist = DistOnGround + 1.25f;
float HighestCar = 0.0f;
+ if(m_fDimensionOfHighestNearCar > 0.0f)
+ TestDist += 0.3f;
CVector TestBase = CamTargetEntity->GetPosition();
CVector TestPoint;
TestBase.z -= 0.15f;
@@ -514,96 +537,9 @@ CCam::ProcessSpecialHeightRoutines(void)
}else
m_fDimensionOfHighestNearCar = 0.0f;
}
-
- // Move up for road
- if(Mode == MODE_FOLLOWPED || Mode == MODE_FIGHT_CAM ||
- Mode == MODE_SYPHON || Mode == MODE_SYPHON_CRIM_IN_FRONT || Mode == MODE_SPECIAL_FIXED_FOR_SYPHON){
- bool Inside = false;
- bool OnRoad = false;
-
- switch(((CPhysical*)CamTargetEntity)->m_nSurfaceTouched)
- case SURFACE_GRASS:
- case SURFACE_GRAVEL:
- case SURFACE_MUD_DRY:
- case SURFACE_THICK_METAL_PLATE:
- case SURFACE_RUBBER:
- case SURFACE_STEEP_CLIFF:
- OnRoad = true;
-
- if(CCullZones::PlayerNoRain())
- Inside = true;
-
- if((m_bCollisionChecksOn || PreviouslyFailedRoadHeightCheck || OnRoad) &&
- m_fCloseInPedHeightOffset < 0.0001f && !Inside){
- CVector TestPoint;
- CEntity *road;
- float GroundZ = 0.0f;
- bool FoundGround = false;
- float RoofZ = 0.0f;
- bool FoundRoof = false;
- static float MinHeightAboveRoad = 0.9f;
-
- TestPoint = CamTargetEntity->GetPosition() - DistOnGround * CVector(Cos(BetaAngle), Sin(BetaAngle), 0.0f);
- m_fRoadOffSet = 0.0f;
-
- if(CWorld::ProcessVerticalLine(TestPoint, -1000.0f, colPoint, road, true, false, false, false, false, false, nil)){
- FoundGround = true;
- GroundZ = colPoint.point.z;
- }
- // Move up if too close to ground
- if(FoundGround){
- if(TestPoint.z - GroundZ < MinHeightAboveRoad){
- m_fRoadOffSet = GroundZ + MinHeightAboveRoad - TestPoint.z;
- PreviouslyFailedRoadHeightCheck = true;
- }else{
- if(m_bCollisionChecksOn)
- PreviouslyFailedRoadHeightCheck = false;
- else
- m_fRoadOffSet = 0.0f;
- }
- }else{
- if(CWorld::ProcessVerticalLine(TestPoint, 1000.0f, colPoint, road, true, false, false, false, false, false, nil)){
- FoundRoof = true;
- RoofZ = colPoint.point.z;
- }
- if(FoundRoof){
- if(TestPoint.z - RoofZ < MinHeightAboveRoad){
- m_fRoadOffSet = RoofZ + MinHeightAboveRoad - TestPoint.z;
- PreviouslyFailedRoadHeightCheck = true;
- }else{
- if(m_bCollisionChecksOn)
- PreviouslyFailedRoadHeightCheck = false;
- else
- m_fRoadOffSet = 0.0f;
- }
- }
- }
- }
- }
-
- if(PreviouslyFailedRoadHeightCheck && m_fCloseInPedHeightOffset < 0.0001f){
- if(colPoint.surfaceB != SURFACE_TARMAC &&
- colPoint.surfaceB != SURFACE_GRASS &&
- colPoint.surfaceB != SURFACE_GRAVEL &&
- colPoint.surfaceB != SURFACE_MUD_DRY &&
- colPoint.surfaceB != SURFACE_STEEP_CLIFF){
- if(m_fRoadOffSet > 1.4f)
- m_fRoadOffSet = 1.4f;
- }else{
- if(Mode == MODE_FOLLOWPED){
- if(TheCamera.PedZoomIndicator == CAM_ZOOM_1)
- m_fRoadOffSet += 0.2f;
- if(TheCamera.PedZoomIndicator == CAM_ZOOM_2)
- m_fRoadOffSet += 0.5f;
- if(TheCamera.PedZoomIndicator == CAM_ZOOM_3)
- m_fRoadOffSet += 0.95f;
- }
- }
- }
}
if(StandingOnBoat){
- m_fRoadOffSet = 0.0f;
m_fDimensionOfHighestNearCar = 1.0f;
m_fPedBetweenCameraHeightOffset = 0.0f;
}
@@ -624,18 +560,30 @@ CCam::GetVectorsReadyForRW(void)
Up = CrossProduct(right, Front);
}
+bool
+CCam::GetBoatLook_L_R_HeightOffset(float &Offset)
+{
+ if(CamTargetEntity == nil)
+ return false;
+ CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(CamTargetEntity->GetModelIndex());
+ tBoatHandlingData *handling = mod_HandlingManager.GetBoatPointer(mi->m_handlingId);
+ if(handling){
+ Offset = handling->fLook_L_R_BehindCamHeight;
+ return true;
+ }
+ return false; // can't happen, we always get a boat pointer back
+}
+
void
CCam::LookBehind(void)
{
float Dist, DeltaBeta, TargetOrientation, Angle;
CVector TargetCoors, TargetFwd, TestCoors;
- CColPoint colPoint;
- CEntity *entity;
TargetCoors = CamTargetEntity->GetPosition();
Front = CamTargetEntity->GetPosition() - Source;
- if((Mode == MODE_CAM_ON_A_STRING || Mode == MODE_BEHINDBOAT) && CamTargetEntity->IsVehicle()){
+ if((Mode == MODE_CAM_ON_A_STRING || Mode == MODE_BEHINDBOAT || Mode == MODE_BEHINDCAR) && CamTargetEntity->IsVehicle()){
LookingBehind = true;
Dist = Mode == MODE_CAM_ON_A_STRING ? CA_MAX_DISTANCE : 15.5f;
TargetFwd = CamTargetEntity->GetForward();
@@ -650,12 +598,8 @@ CCam::LookBehind(void)
TargetOrientation += PI;
Source.x = Dist*Cos(TargetOrientation) + TargetCoors.x;
Source.y = Dist*Sin(TargetOrientation) + TargetCoors.y;
- Source.z -= 1.0f;
- if(CWorld::ProcessLineOfSight(TargetCoors, Source, colPoint, entity, true, false, false, true, false, true, true)){
- RwCameraSetNearClipPlane(Scene.camera, DEFAULT_NEAR);
- Source = colPoint.point;
- }
- Source.z += 1.0f;
+ CVector OrigSource = Source;
+ TheCamera.AvoidTheGeometry(OrigSource, TargetCoors, Source, FOV);
Front = CamTargetEntity->GetPosition() - Source;
GetVectorsReadyForRW();
}
@@ -666,55 +610,76 @@ CCam::LookBehind(void)
Front.Normalise();
if(((CVehicle*)CamTargetEntity)->IsBoat())
Source.z -= 0.5f;
- Source += 0.25f*Front;
- Front = -Front;
-#ifdef FIX_BUGS
- // not sure if this is a bug...
- GetVectorsReadyForRW();
-#endif
+ if(((CVehicle*)CamTargetEntity)->GetVehicleAppearance() == VEHICLE_APPEARANCE_BIKE){
+ float FrontDist = 1.1f;
+ if(((CVehicle*)CamTargetEntity)->pDriver){
+ CVector ExtraFwd(0.0f, 0.0f, 0.0f);
+ ((CVehicle*)CamTargetEntity)->pDriver->m_pedIK.GetComponentPosition(ExtraFwd, PED_HEAD);
+ ExtraFwd += ((CVehicle*)CamTargetEntity)->m_vecMoveSpeed*CTimer::GetTimeStep() - CamTargetEntity->GetPosition();
+ FrontDist += 0.2f + Max(DotProduct(ExtraFwd, CamTargetEntity->GetForward()), 0.0f);
+ }
+ Source += FrontDist*Front;
+ Front = -Front;
+ }else if(((CVehicle*)CamTargetEntity)->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI){
+ Front = -1.0f*CamTargetEntity->GetUp();
+ Up = CamTargetEntity->GetForward();
+ Source += 0.25f*Front;
+ }else{
+ Source += 0.25f*Front;
+ Front = -Front;
+ }
}
if(CamTargetEntity->IsPed()){
Angle = CGeneral::GetATanOfXY(Source.x - TargetCoors.x, Source.y - TargetCoors.y) + PI;
Source.x = 4.5f*Cos(Angle) + TargetCoors.x;
Source.y = 4.5f*Sin(Angle) + TargetCoors.y;
Source.z = 1.15f + TargetCoors.z;
- TestCoors = TargetCoors;
- TestCoors.z = Source.z;
- if(CWorld::ProcessLineOfSight(TestCoors, Source, colPoint, entity, true, true, false, true, false, true, true)){
- Source.x = colPoint.point.x;
- Source.y = colPoint.point.y;
- if((TargetCoors - Source).Magnitude2D() < 1.15f)
- RwCameraSetNearClipPlane(Scene.camera, 0.05f);
- }
+ CVector OrigSource = Source;
+ TheCamera.AvoidTheGeometry(OrigSource, TargetCoors, Source, FOV);
Front = TargetCoors - Source;
GetVectorsReadyForRW();
}
}
+float BOAT_1STPERSON_L_OFFSETX = 0.7f;
+float BOAT_1STPERSON_R_OFFSETX = 0.3f;
+float BOAT_1STPERSON_LR_OFFSETZ = 0.2f;
+
void
CCam::LookLeft(void)
{
float Dist, TargetOrientation;
CVector TargetCoors, TargetFwd;
- CColPoint colPoint;
- CEntity *entity;
- if((Mode == MODE_CAM_ON_A_STRING || Mode == MODE_BEHINDBOAT) && CamTargetEntity->IsVehicle()){
+ if((Mode == MODE_CAM_ON_A_STRING || Mode == MODE_BEHINDBOAT || Mode == MODE_BEHINDCAR) && CamTargetEntity->IsVehicle()){
LookingLeft = true;
TargetCoors = CamTargetEntity->GetPosition();
Front = CamTargetEntity->GetPosition() - Source;
- Dist = Mode == MODE_CAM_ON_A_STRING ? CA_MAX_DISTANCE : 9.0f;
+ if(Mode == MODE_CAM_ON_A_STRING)
+ Dist = CA_MAX_DISTANCE;
+ else if(Mode == MODE_BEHINDBOAT){
+ Dist = 9.0f;
+ float Offset = 0.0f;
+ if(GetBoatLook_L_R_HeightOffset(Offset) && !CCullZones::Cam1stPersonForPlayer())
+ Source.z = TargetCoors.z + Offset;
+ }else
+ Dist = 9.0f;
TargetFwd = CamTargetEntity->GetForward();
TargetFwd.Normalise();
TargetOrientation = CGeneral::GetATanOfXY(TargetFwd.x, TargetFwd.y);
Source.x = Dist*Cos(TargetOrientation - HALFPI) + TargetCoors.x;
Source.y = Dist*Sin(TargetOrientation - HALFPI) + TargetCoors.y;
- Source.z -= 1.0f;
- if(CWorld::ProcessLineOfSight(TargetCoors, Source, colPoint, entity, true, false, false, true, false, true, true)){
- RwCameraSetNearClipPlane(Scene.camera, 0.4f);
- Source = colPoint.point;
- }
- Source.z += 1.0f;
+
+ CColModel *colModel = CamTargetEntity->GetColModel();
+ CVector OrigSource = Source;
+ TheCamera.AvoidTheGeometry(OrigSource, TargetCoors, Source, FOV);
+
+ CVector TopRight = CamTargetEntity->GetPosition() +
+ CamTargetEntity->GetRight()*colModel->boundingBox.max.x +
+ CamTargetEntity->GetUp()*colModel->boundingBox.max.z;
+ float Height = Min(Max(m_cvecTargetCoorsForFudgeInter.z, TopRight.z)+0.1f, OrigSource.z);
+ Source.z = Max(Height, Source.z);
+
Front = CamTargetEntity->GetPosition() - Source;
Front.z += 1.1f;
if(Mode == MODE_BEHINDBOAT)
@@ -724,8 +689,21 @@ CCam::LookLeft(void)
if(Mode == MODE_1STPERSON && CamTargetEntity->IsVehicle()){
LookingLeft = true;
RwCameraSetNearClipPlane(Scene.camera, 0.25f);
- if(((CVehicle*)CamTargetEntity)->IsBoat())
- Source.z -= 0.5f;
+ if(((CVehicle*)CamTargetEntity)->IsBoat()){
+ if(((CVehicle*)CamTargetEntity)->pDriver){
+ CVector neck(0.0f, 0.0f, 0.0f);
+ CPed *driver = ((CVehicle*)CamTargetEntity)->pDriver;
+ driver->SetPedPositionInCar();
+ driver->GetMatrix().UpdateRW();
+ driver->UpdateRwFrame();
+ driver->UpdateRpHAnim();
+ driver->m_pedIK.GetComponentPosition(neck, PED_NECK);
+ Source = neck +
+ BOAT_1STPERSON_L_OFFSETX*CamTargetEntity->GetRight() +
+ BOAT_1STPERSON_LR_OFFSETZ*CamTargetEntity->GetUp();
+ }else
+ Source.z -= 0.5f;
+ }
Up = CamTargetEntity->GetUp();
Up.Normalise();
@@ -733,10 +711,8 @@ CCam::LookLeft(void)
Front.Normalise();
Front = -CrossProduct(Front, Up);
Front.Normalise();
-#ifdef FIX_BUGS
- // not sure if this is a bug...
- GetVectorsReadyForRW();
-#endif
+ if(((CVehicle*)CamTargetEntity)->GetVehicleAppearance() == VEHICLE_APPEARANCE_BIKE)
+ Source -= 1.45f*Front;
}
}
@@ -746,24 +722,36 @@ CCam::LookRight(void)
float Dist, TargetOrientation;
CVector TargetCoors, TargetFwd;
CColPoint colPoint;
- CEntity *entity;
if((Mode == MODE_CAM_ON_A_STRING || Mode == MODE_BEHINDBOAT) && CamTargetEntity->IsVehicle()){
LookingRight = true;
TargetCoors = CamTargetEntity->GetPosition();
Front = CamTargetEntity->GetPosition() - Source;
- Dist = Mode == MODE_CAM_ON_A_STRING ? CA_MAX_DISTANCE : 9.0f;
+ if(Mode == MODE_CAM_ON_A_STRING)
+ Dist = CA_MAX_DISTANCE;
+ else if(Mode == MODE_BEHINDBOAT){
+ Dist = 9.0f;
+ float Offset = 0.0f;
+ if(GetBoatLook_L_R_HeightOffset(Offset) && !CCullZones::Cam1stPersonForPlayer())
+ Source.z = TargetCoors.z + Offset;
+ }else
+ Dist = 9.0f;
TargetFwd = CamTargetEntity->GetForward();
TargetFwd.Normalise();
TargetOrientation = CGeneral::GetATanOfXY(TargetFwd.x, TargetFwd.y);
Source.x = Dist*Cos(TargetOrientation + HALFPI) + TargetCoors.x;
Source.y = Dist*Sin(TargetOrientation + HALFPI) + TargetCoors.y;
- Source.z -= 1.0f;
- if(CWorld::ProcessLineOfSight(TargetCoors, Source, colPoint, entity, true, false, false, true, false, true, true)){
- RwCameraSetNearClipPlane(Scene.camera, 0.4f);
- Source = colPoint.point;
- }
- Source.z += 1.0f;
+
+ CColModel *colModel = CamTargetEntity->GetColModel();
+ CVector OrigSource = Source;
+ TheCamera.AvoidTheGeometry(OrigSource, TargetCoors, Source, FOV);
+
+ CVector TopLeft = CamTargetEntity->GetPosition() +
+ CamTargetEntity->GetRight()*colModel->boundingBox.min.x +
+ CamTargetEntity->GetUp()*colModel->boundingBox.max.z;
+ float Height = Min(Max(m_cvecTargetCoorsForFudgeInter.z, TopLeft.z)+0.1f, OrigSource.z);
+ Source.z = Max(Height, Source.z);
+
Front = CamTargetEntity->GetPosition() - Source;
Front.z += 1.1f;
if(Mode == MODE_BEHINDBOAT)
@@ -773,8 +761,21 @@ CCam::LookRight(void)
if(Mode == MODE_1STPERSON && CamTargetEntity->IsVehicle()){
LookingRight = true;
RwCameraSetNearClipPlane(Scene.camera, 0.25f);
- if(((CVehicle*)CamTargetEntity)->IsBoat())
- Source.z -= 0.5f;
+ if(((CVehicle*)CamTargetEntity)->IsBoat()){
+ if(((CVehicle*)CamTargetEntity)->pDriver){
+ CVector neck(0.0f, 0.0f, 0.0f);
+ CPed *driver = ((CVehicle*)CamTargetEntity)->pDriver;
+ driver->SetPedPositionInCar();
+ driver->GetMatrix().UpdateRW();
+ driver->UpdateRwFrame();
+ driver->UpdateRpHAnim();
+ driver->m_pedIK.GetComponentPosition(neck, PED_NECK);
+ Source = neck +
+ BOAT_1STPERSON_R_OFFSETX*CamTargetEntity->GetRight() +
+ BOAT_1STPERSON_LR_OFFSETZ*CamTargetEntity->GetUp();
+ }else
+ Source.z -= 0.5f;
+ }
Up = CamTargetEntity->GetUp();
Up.Normalise();
@@ -782,10 +783,8 @@ CCam::LookRight(void)
Front.Normalise();
Front = CrossProduct(Front, Up);
Front.Normalise();
-#ifdef FIX_BUGS
- // not sure if this is a bug...
- GetVectorsReadyForRW();
-#endif
+ if(((CVehicle*)CamTargetEntity)->GetVehicleAppearance() == VEHICLE_APPEARANCE_BIKE)
+ Source -= 1.45f*Front;
}
}
@@ -861,11 +860,7 @@ CCam::KeepTrackOfTheSpeed(const CVector &source, const CVector &target, const CV
bool
CCam::Using3rdPersonMouseCam(void)
{
- return CCamera::m_bUseMouse3rdPerson &&
- (Mode == MODE_FOLLOWPED ||
- TheCamera.m_bPlayerIsInGarage &&
- FindPlayerPed() && FindPlayerPed()->m_nPedState != PED_DRIVING &&
- Mode != MODE_TOPDOWN && CamTargetEntity == FindPlayerPed());
+ return CCamera::m_bUseMouse3rdPerson && Mode == MODE_FOLLOWPED;
}
bool
@@ -877,16 +872,22 @@ CCam::GetWeaponFirstPersonOn(void)
bool
CCam::IsTargetInWater(const CVector &CamCoors)
{
- if(CamTargetEntity == nil)
- return false;
- if(CamTargetEntity->IsPed()){
- if(!((CPed*)CamTargetEntity)->bIsInWater)
- return false;
- if(!((CPed*)CamTargetEntity)->bIsStanding)
- return true;
- return false;
+ if(CamTargetEntity){
+ float WaterZ = -6000.0f;
+ CWaterLevel::GetWaterLevel(CamTargetEntity->GetPosition(), &WaterZ, false);
+ if(CamTargetEntity->IsPed()){
+ if(((CPed*)CamTargetEntity)->bIsDrowning ||
+ ((CPed*)CamTargetEntity)->bIsInWater && CamTargetEntity->GetPosition().z < WaterZ)
+ return true;
+ }else{
+ assert(CamTargetEntity->IsVehicle());
+ if(((CVehicle*)CamTargetEntity)->bIsDrowning ||
+ ((CVehicle*)CamTargetEntity)->bIsInWater && CamTargetEntity->GetPosition().z < WaterZ)
+ return true;
+ }
}
- return ((CPhysical*)CamTargetEntity)->bIsInWater;
+ m_vecLastAboveWaterCamPosition = Source;
+ return false;
}
void
@@ -910,10 +911,10 @@ CCam::PrintMode(void)
"Blood on the tracks", "Passenger", "Syphon Crim in Front",
"Dead Baby", "Pillow Paps", "Look at Cars", "Arrest One",
"Arrest Two", "M16", "Special fixed for Syphon", "Fight",
- "Top Down Ped",
+ "Top Down Ped", "Lighthouse",
"Sniper run about", "Rocket run about",
"1st Person run about", "M16 run about", "Fight run about",
- "Editor"
+ "Editor", "Helicannon", "Camera"
};
sprintf(buf, "Cam: %s", modes[TheCamera.Cams[TheCamera.ActiveCam].Mode]);
CDebug::PrintAt(buf, 2, 5);
@@ -946,7 +947,7 @@ CVector
CCam::DoAverageOnVector(const CVector &vec)
{
int i;
- CVector Average(0.0f, 0.0f, 0.0f);
+ CVector Average = CVector(0.0f, 0.0f, 0.0f);
if(ResetStatics){
m_iRunningVectorArrayPos = 0;
@@ -974,41 +975,16 @@ CCam::DoAverageOnVector(const CVector &vec)
return Average;
}
-// Rotate Beta in direction opposite of BetaOffset in 5 deg. steps.
-// Return the first angle for which Beta + BetaOffset + Angle has a clear view.
-// i.e. BetaOffset is a safe zone so that Beta + Angle is really clear.
-// If BetaOffset == 0, try both directions.
-float
-CCam::GetPedBetaAngleForClearView(const CVector &Target, float Dist, float BetaOffset, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies)
-{
- CColPoint point;
- CEntity *ent = nil;
- CVector ToSource;
- float a;
-
- // This would be so much nicer if we just got the step variable before the loop...R*
-
- for(a = 0.0f; a <= PI; a += DEGTORAD(5.0f)){
- if(BetaOffset <= 0.0f){
- ToSource = CVector(Cos(Beta + BetaOffset + a), Sin(Beta + BetaOffset + a), 0.0f)*Dist;
- if(!CWorld::ProcessLineOfSight(Target, Target + ToSource,
- point, ent, checkBuildings, checkVehicles, checkPeds,
- checkObjects, checkDummies, true, true))
- return a;
- }
- if(BetaOffset >= 0.0f){
- ToSource = CVector(Cos(Beta + BetaOffset - a), Sin(Beta + BetaOffset - a), 0.0f)*Dist;
- if(!CWorld::ProcessLineOfSight(Target, Target + ToSource,
- point, ent, checkBuildings, checkVehicles, checkPeds,
- checkObjects, checkDummies, true, true))
- return -a;
- }
- }
- return 0.0f;
-}
-
float DefaultAcceleration = 0.045f;
float DefaultMaxStep = 0.15f;
+float fDefaultSpeedStep = 0.025f;
+float fDefaultSpeedMultiplier = 0.09f;
+float fDefaultSpeedLimit = 0.15f;
+float fDefaultSpeedStep4Avoid = 0.02f;
+float fDefaultSpeedMultiplier4Avoid = 0.05f;
+float fDefaultSpeedLimit4Avoid = 0.25f;
+float fAvoidGeomThreshhold = 1.5f;
+float fMiniGunBetaOffset = 0.3f;
void
CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, float, float)
@@ -1016,85 +992,72 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl
if(!CamTargetEntity->IsPed())
return;
- const float GroundDist = 1.85f;
-
CVector TargetCoors, Dist, IdealSource;
float Length = 0.0f;
- float LateralLeft = 0.0f;
- float LateralRight = 0.0f;
- float Center = 0.0f;
- static bool PreviouslyObscured;
static bool PickedASide;
static float FixedTargetOrientation = 0.0f;
float AngleToGoTo = 0.0f;
- float BetaOffsetAvoidBuildings = 0.45f; // ~25 deg
- float BetaOffsetGoingBehind = 0.45f;
- bool GoingBehind = false;
- bool Obscured = false;
- bool BuildingCheckObscured = false;
bool StandingInTrain = false;
+ float ZoomGroundTarget = 0.0f;
+ float ZoomZTarget = 0.0f;
static int TimeIndicatedWantedToGoDown = 0;
static bool StartedCountingForGoDown = false;
+ static float ZoomGround = 0.0f;
+ static float ZoomGroundSpeed = 0.0f;
+ static float ZoomZ = 0.0f;
+ static float ZoomZSpeed = 0.0f;
float DeltaBeta;
m_bFixingBeta = false;
bBelowMinDist = false;
bBehindPlayerDesired = false;
- // CenterDist should be > LateralDist because we don't have an angle for safety in this case
- float CenterDist, LateralDist;
- float AngleToGoToSpeed;
- if(m_fCloseInPedHeightOffset > 0.00001f){
- LateralDist = 0.55f;
- CenterDist = 1.25f;
- BetaOffsetAvoidBuildings = 0.9f; // ~50 deg
- BetaOffsetGoingBehind = 0.9f;
- AngleToGoToSpeed = 0.88254666f;
- }else{
- LateralDist = 0.8f;
- CenterDist = 1.35f;
- if(TheCamera.PedZoomIndicator == CAM_ZOOM_1 || TheCamera.PedZoomIndicator == CAM_ZOOM_TOPDOWN){
- LateralDist = 1.25f;
- CenterDist = 1.6f;
- }
- AngleToGoToSpeed = 0.43254671f;
- }
-
FOV = DefaultFOV;
if(ResetStatics){
Rotating = false;
m_bCollisionChecksOn = true;
FixedTargetOrientation = 0.0f;
- PreviouslyObscured = false;
PickedASide = false;
StartedCountingForGoDown = false;
AngleToGoTo = 0.0f;
- // unused LastAngleWithNoPickedASide
+ ZoomGround = 0.0f;
+ ZoomGroundSpeed = 0.0f;
+ ZoomZ = 0.0f;
+ ZoomZSpeed = 0.0f;
+ Distance = 500.0f;
}
TargetCoors = CameraTarget;
+
+ // Take speed of thing we're standing on into account
+ CVector GroundMovement(0.0f, 0.0f, 0.0f);
+ CPhysical *ground = (CPhysical*)((CPed*)CamTargetEntity)->m_pCurSurface;
+ if(ground && (ground->IsVehicle() || ground->IsObject()))
+ GroundMovement += ground->GetSpeed(CamTargetEntity->GetPosition() - ground->GetPosition()) * CTimer::GetTimeStep();
+
+ Source += GroundMovement;
IdealSource = Source;
TargetCoors.z += m_fSyphonModeTargetZOffSet;
- TargetCoors = DoAverageOnVector(TargetCoors);
- TargetCoors.z += m_fRoadOffSet;
+ TargetCoors.z = DoAverageOnVector(TargetCoors).z;
Dist.x = IdealSource.x - TargetCoors.x;
Dist.y = IdealSource.y - TargetCoors.y;
Length = Dist.Magnitude2D();
// Cam on a string. With a fixed distance. Zoom in/out is done later.
- if(Length != 0.0f)
- IdealSource = TargetCoors + CVector(Dist.x, Dist.y, 0.0f)/Length * GroundDist;
- else
+ if(Length != 0.0f){
+ IdealSource = TargetCoors + CVector(Dist.x, Dist.y, 0.0f)/Length * m_fMinRealGroundDist;
+ IdealSource.z += GroundMovement.z;
+ }else
IdealSource = TargetCoors + CVector(1.0f, 1.0f, 0.0f);
if(TheCamera.m_bUseTransitionBeta && ResetStatics){
CVector VecDistance;
- IdealSource.x = TargetCoors.x + GroundDist*Cos(m_fTransitionBeta);
- IdealSource.y = TargetCoors.y + GroundDist*Sin(m_fTransitionBeta);
+ IdealSource.x = TargetCoors.x + m_fMinRealGroundDist*Cos(m_fTransitionBeta);
+ IdealSource.y = TargetCoors.y + m_fMinRealGroundDist*Sin(m_fTransitionBeta);
Beta = CGeneral::GetATanOfXY(IdealSource.x - TargetCoors.x, IdealSource.y - TargetCoors.y);
}else
Beta = CGeneral::GetATanOfXY(Source.x - TargetCoors.x, Source.y - TargetCoors.y);
@@ -1116,24 +1079,30 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl
while(Beta >= PI) Beta -= 2.0f * PI;
while(Beta < -PI) Beta += 2.0f * PI;
- // BUG? is this ever used?
- // The values seem to be roughly m_fPedZoomValueSmooth + 1.85
+ if(TheCamera.PedZoomIndicator == CAM_ZOOM_1 &&
+ ((CPed*)CamTargetEntity)->GetPedState() != PED_ENTER_CAR &&
+ ((CPed*)CamTargetEntity)->GetPedState() != PED_CARJACK){
+ ZoomGroundTarget = m_fTargetZoomGroundOne;
+ ZoomZTarget = m_fTargetZoomOneZExtra;
+ }else if(TheCamera.PedZoomIndicator == CAM_ZOOM_2 || TheCamera.PedZoomIndicator == CAM_ZOOM_1){
+ ZoomGroundTarget = m_fTargetZoomGroundTwo;
+ ZoomZTarget = m_fTargetZoomTwoZExtra;
+ }else if(TheCamera.PedZoomIndicator == CAM_ZOOM_3){
+ ZoomGroundTarget = m_fTargetZoomGroundThree;
+ ZoomZTarget = m_fTargetZoomThreeZExtra;
+ }
+ if(m_fCloseInPedHeightOffset > 0.00001f){
+ ZoomGroundTarget = m_fTargetCloseInDist;
+ ZoomZTarget = m_fTargetZoomZCloseIn;
+ }
if(ResetStatics){
- if(TheCamera.PedZoomIndicator == CAM_ZOOM_1) m_fRealGroundDist = 2.090556f;
- if(TheCamera.PedZoomIndicator == CAM_ZOOM_2) m_fRealGroundDist = 3.34973f;
- if(TheCamera.PedZoomIndicator == CAM_ZOOM_3) m_fRealGroundDist = 4.704914f;
- if(TheCamera.PedZoomIndicator == CAM_ZOOM_TOPDOWN) m_fRealGroundDist = 2.090556f;
+ ZoomGround = ZoomGroundTarget;
+ ZoomZ = ZoomZTarget;
}
- // And what is this? It's only used for collision and rotation it seems
- float RealGroundDist;
- if(TheCamera.PedZoomIndicator == CAM_ZOOM_1) RealGroundDist = 2.090556f;
- if(TheCamera.PedZoomIndicator == CAM_ZOOM_2) RealGroundDist = 3.34973f;
- if(TheCamera.PedZoomIndicator == CAM_ZOOM_3) RealGroundDist = 4.704914f;
- if(TheCamera.PedZoomIndicator == CAM_ZOOM_TOPDOWN) RealGroundDist = 2.090556f;
- if(m_fCloseInPedHeightOffset > 0.00001f)
- RealGroundDist = 1.7016f;
-
+ float SpeedStep = fDefaultSpeedStep;
+ float SpeedMultiplier = fDefaultSpeedMultiplier;
+ float SpeedLimit = fDefaultSpeedLimit;
bool Shooting = false;
CPed *ped = (CPed*)CamTargetEntity;
if(ped->GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED)
@@ -1144,166 +1113,52 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl
Shooting = false;
- if(m_fCloseInPedHeightOffset > 0.00001f)
- TargetCoors.z -= m_fRoadOffSet;
-
// Figure out if and where we want to rotate
- if(CPad::GetPad(0)->ForceCameraBehindPlayer() || Shooting){
+ if(CPad::GetPad(0)->ForceCameraBehindPlayer() && !CPickups::PlayerOnWeaponPickup || Shooting){
// Center cam behind player
- GoingBehind = true;
- m_bCollisionChecksOn = true;
- float OriginalBeta = Beta;
- // Set Beta behind player
- Beta = TargetOrientation + PI;
- TargetCoors.z -= 0.1f;
-
- AngleToGoTo = GetPedBetaAngleForClearView(TargetCoors, CenterDist * RealGroundDist, 0.0f, true, false, false, true, false);
- if(AngleToGoTo != 0.0f){
- if(AngleToGoTo < 0.0f)
- AngleToGoTo -= AngleToGoToSpeed;
- else
- AngleToGoTo += AngleToGoToSpeed;
- }else{
- float LateralLeft = GetPedBetaAngleForClearView(TargetCoors, LateralDist * RealGroundDist, BetaOffsetGoingBehind, true, false, false, true, false);
- float LateralRight = GetPedBetaAngleForClearView(TargetCoors, LateralDist * RealGroundDist, -BetaOffsetGoingBehind, true, false, false, true, false);
- if(LateralLeft == 0.0f && LateralRight != 0.0f)
- AngleToGoTo += LateralRight;
- else if(LateralLeft != 0.0f && LateralRight == 0.0f)
- AngleToGoTo += LateralLeft;
- }
-
- TargetCoors.z += 0.1f;
- Beta = OriginalBeta;
-
if(PickedASide){
- if(AngleToGoTo == 0.0f)
+ if(AngleToGoTo == 0.0f){
FixedTargetOrientation = TargetOrientation + PI;
+ if(Shooting && ped->GetWeapon()->m_eWeaponType == WEAPONTYPE_MINIGUN)
+ FixedTargetOrientation -= fMiniGunBetaOffset;
+ }
Rotating = true;
}else{
- FixedTargetOrientation = TargetOrientation + PI + AngleToGoTo;
+ FixedTargetOrientation = TargetOrientation + PI;
Rotating = true;
PickedASide = true;
+ if(Shooting && ped->GetWeapon()->m_eWeaponType == WEAPONTYPE_MINIGUN)
+ FixedTargetOrientation -= fMiniGunBetaOffset;
}
- }else{
-
- // Rotate cam to avoid clipping into buildings
+ }else if(Abs(TheCamera.m_fAvoidTheGeometryProbsTimer) > fAvoidGeomThreshhold && !Rotating ){
- TargetCoors.z -= 0.1f;
-
- Center = GetPedBetaAngleForClearView(TargetCoors, CenterDist * RealGroundDist, 0.0f, true, false, false, true, false);
- if(m_bCollisionChecksOn || PreviouslyObscured || Center != 0.0f || m_fCloseInPedHeightOffset > 0.00001f){
- if(Center != 0.0f){
- AngleToGoTo = Center;
- }else{
- LateralLeft = GetPedBetaAngleForClearView(TargetCoors, LateralDist * RealGroundDist, BetaOffsetAvoidBuildings, true, false, false, true, false);
- LateralRight = GetPedBetaAngleForClearView(TargetCoors, LateralDist * RealGroundDist, -BetaOffsetAvoidBuildings, true, false, false, true, false);
- if(LateralLeft == 0.0f && LateralRight != 0.0f){
- AngleToGoTo += LateralRight;
- if(m_fCloseInPedHeightOffset > 0.0f)
- RwCameraSetNearClipPlane(Scene.camera, 0.7f);
- }else if(LateralLeft != 0.0f && LateralRight == 0.0f){
- AngleToGoTo += LateralLeft;
- if(m_fCloseInPedHeightOffset > 0.0f)
- RwCameraSetNearClipPlane(Scene.camera, 0.7f);
- }
- }
- if(LateralLeft != 0.0f || LateralRight != 0.0f || Center != 0.0f)
- BuildingCheckObscured = true;
- }
-
- TargetCoors.z += 0.1f;
- }
-
- if(m_fCloseInPedHeightOffset > 0.00001f)
- TargetCoors.z += m_fRoadOffSet;
-
-
- // Have to fix to avoid collision
-
- if(AngleToGoTo != 0.0f){
- Obscured = true;
- Rotating = true;
- if(CPad::GetPad(0)->ForceCameraBehindPlayer() || Shooting){
- if(!PickedASide)
- FixedTargetOrientation = Beta + AngleToGoTo; // can this even happen?
- }else
- FixedTargetOrientation = Beta + AngleToGoTo;
-
- // This calculation is only really used to figure out how fast to rotate out of collision
-
- m_fAmountFractionObscured = 1.0f;
- CVector PlayerPos = FindPlayerPed()->GetPosition();
- float RotationDist = (AngleToGoTo == Center ? CenterDist : LateralDist) * RealGroundDist;
- // What's going on here? - AngleToGoTo?
- CVector RotatedSource = PlayerPos + CVector(Cos(Beta - AngleToGoTo), Sin(Beta - AngleToGoTo), 0.0f) * RotationDist;
-
- CColPoint colpoint;
- CEntity *entity;
- if(CWorld::ProcessLineOfSight(PlayerPos, RotatedSource, colpoint, entity, true, false, false, true, false, false, false)){
- if((PlayerPos - RotatedSource).Magnitude() != 0.0f)
- m_fAmountFractionObscured = (PlayerPos - colpoint.point).Magnitude() / (PlayerPos - RotatedSource).Magnitude();
- else
- m_fAmountFractionObscured = 1.0f;
- }
- }
- if(m_fAmountFractionObscured < 0.0f) m_fAmountFractionObscured = 0.0f;
- if(m_fAmountFractionObscured > 1.0f) m_fAmountFractionObscured = 1.0f;
-
-
-
- // Figure out speed values for Beta rotation
-
- float Acceleration, MaxSpeed;
- static float AccelerationMult = 0.35f;
- static float MaxSpeedMult = 0.85f;
- static float AccelerationMultClose = 0.7f;
- static float MaxSpeedMultClose = 1.6f;
- float BaseAcceleration = 0.025f;
- float BaseMaxSpeed = 0.09f;
- if(m_fCloseInPedHeightOffset > 0.00001f){
- if(AngleToGoTo == 0.0f){
- BaseAcceleration = 0.022f;
- BaseMaxSpeed = 0.04f;
- }else{
- BaseAcceleration = DefaultAcceleration;
- BaseMaxSpeed = DefaultMaxStep;
- }
- }
- if(AngleToGoTo == 0.0f){
- Acceleration = BaseAcceleration;
- MaxSpeed = BaseMaxSpeed;
- }else if(CPad::GetPad(0)->ForceCameraBehindPlayer() && !Shooting){
- Acceleration = 0.051f;
- MaxSpeed = 0.18f;
- }else if(m_fCloseInPedHeightOffset > 0.00001f){
- Acceleration = BaseAcceleration + AccelerationMultClose*sq(m_fAmountFractionObscured - 1.05f);
- MaxSpeed = BaseMaxSpeed + MaxSpeedMultClose*sq(m_fAmountFractionObscured - 1.05f);
- }else{
- Acceleration = DefaultAcceleration + AccelerationMult*sq(m_fAmountFractionObscured - 1.05f);
- MaxSpeed = DefaultMaxStep + MaxSpeedMult*sq(m_fAmountFractionObscured - 1.05f);
+ if(TheCamera.m_fAvoidTheGeometryProbsTimer < 0.0f)
+ FixedTargetOrientation = TargetOrientation;
+ else
+ FixedTargetOrientation = TargetOrientation + PI;
+ float dist = (Source - TargetCoors).Magnitude();
+ float mult = dist > 0.1f ? 1.0f/dist : 10.0f;
+ SpeedStep = mult * fDefaultSpeedStep4Avoid;
+ SpeedMultiplier = mult * fDefaultSpeedMultiplier4Avoid;
+ SpeedLimit = mult * fDefaultSpeedLimit4Avoid;
}
- static float AccelerationLimit = 0.3f;
- static float MaxSpeedLimit = 0.65f;
- if(Acceleration > AccelerationLimit) Acceleration = AccelerationLimit;
- if(MaxSpeed > MaxSpeedLimit) MaxSpeed = MaxSpeedLimit;
-
int MoveState = ((CPed*)CamTargetEntity)->m_nMoveState;
if(MoveState != PEDMOVE_NONE && MoveState != PEDMOVE_STILL &&
- !CPad::GetPad(0)->ForceCameraBehindPlayer() && !Obscured && !Shooting){
+ !(CPad::GetPad(0)->ForceCameraBehindPlayer() && !CPickups::PlayerOnWeaponPickup) && !Shooting){
Rotating = false;
- BetaSpeed = 0.0f;
+ if(TheCamera.m_fAvoidTheGeometryProbsTimer <= fAvoidGeomThreshhold)
+ BetaSpeed = 0.0f;
}
// Now do the Beta rotation
- float RotDistance = (IdealSource - TargetCoors).Magnitude2D();
- m_fDistanceBeforeChanges = RotDistance;
+ float RotDistance = m_fMinRealGroundDist;
- if(Rotating){
+ if(Rotating || TheCamera.m_fAvoidTheGeometryProbsTimer > fAvoidGeomThreshhold){
m_bFixingBeta = true;
while(FixedTargetOrientation >= PI) FixedTargetOrientation -= 2*PI;
@@ -1313,13 +1168,23 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl
while(Beta < -PI) Beta += 2*PI;
-/*
- // This is inlined WellBufferMe
+ // This is inlined WellBufferMe - unfortunately modified so we can't just call it
+ {
DeltaBeta = FixedTargetOrientation - Beta;
while(DeltaBeta >= PI) DeltaBeta -= 2*PI;
while(DeltaBeta < -PI) DeltaBeta += 2*PI;
- float ReqSpeed = DeltaBeta * MaxSpeed;
+ // this is the added bit
+ if(!Rotating){
+ if(TheCamera.m_nAvoidTheGeometryProbsDirn == -1 && DeltaBeta > 0.0f ||
+ TheCamera.m_nAvoidTheGeometryProbsDirn == 1 && DeltaBeta < 0.0f)
+ DeltaBeta *= -1.0f;
+ }
+
+ float ReqSpeed = DeltaBeta * SpeedMultiplier;
+ // this is also added
+ ReqSpeed = Clamp(ReqSpeed, -SpeedLimit, SpeedLimit);
+
// Add or subtract absolute depending on sign, genius!
if(ReqSpeed - BetaSpeed > 0.0f)
BetaSpeed += SpeedStep * Abs(ReqSpeed - BetaSpeed) * CTimer::GetTimeStep();
@@ -1334,8 +1199,7 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl
BetaSpeed = ReqSpeed;
Beta += BetaSpeed * Min(10.0f, CTimer::GetTimeStep());
-*/
- WellBufferMe(FixedTargetOrientation, &Beta, &BetaSpeed, MaxSpeed, Acceleration, true);
+ }
if(ResetStatics){
Beta = FixedTargetOrientation;
@@ -1359,7 +1223,14 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl
if(TheCamera.m_bCamDirectlyBehind || TheCamera.m_bCamDirectlyInFront ||
- StandingInTrain || Rotating){
+ StandingInTrain || Rotating ||
+ TheCamera.m_bUseTransitionBeta && ResetStatics ||
+ Abs(TheCamera.m_fAvoidTheGeometryProbsTimer) > fAvoidGeomThreshhold){
+ if(TheCamera.m_bUseTransitionBeta){
+ Beta = m_fTransitionBeta;
+ Source.x = TargetCoors.x + RotDistance * Cos(m_fTransitionBeta);
+ Source.y = TargetCoors.y + RotDistance * Sin(m_fTransitionBeta);
+ }
if(TheCamera.m_bCamDirectlyBehind){
Beta = TargetOrientation + PI;
Source.x = TargetCoors.x + RotDistance * Cos(Beta);
@@ -1378,59 +1249,42 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl
m_fCamBufferedHeight = 0.0f;
m_fCamBufferedHeightSpeed = 0.0f;
}
+ if(StandingInTrain){
+ Beta = TargetOrientation + PI;
+ Source.x = TargetCoors.x + RotDistance * Cos(Beta);
+ Source.y = TargetCoors.y + RotDistance * Sin(Beta);
+ m_fDimensionOfHighestNearCar = 0.0f;
+ m_fCamBufferedHeight = 0.0f;
+ m_fCamBufferedHeightSpeed = 0.0f;
+ }
+
// Beta and Source already set in the rotation code
}else{
Source = IdealSource;
BetaSpeed = 0.0f;
}
+ Source.z = IdealSource.z;
- // Subtract m_fRoadOffSet from both?
- TargetCoors.z -= m_fRoadOffSet;
- Source.z = IdealSource.z - m_fRoadOffSet;
-
- // Apply zoom now
- // m_fPedZoomValueSmooth makes the cam go down the further out it is
- // 0.25 -> 0.20 for nearest dist
- // 1.50 -> -0.05 for mid dist
- // 2.90 -> -0.33 for far dist
- Source.z += (2.5f - TheCamera.m_fPedZoomValueSmooth)*0.2f - 0.25f;
// Zoom out camera
Front = TargetCoors - Source;
Front.Normalise();
- Source -= Front * TheCamera.m_fPedZoomValueSmooth;
- // and then we move up again
- // -0.375
- // 0.25
- // 0.95
- Source.z += (TheCamera.m_fPedZoomValueSmooth - 1.0f)*0.5f + m_fCloseInPedHeightOffset;
+ WellBufferMe(ZoomGroundTarget, &ZoomGround, &ZoomGroundSpeed, 0.2f, 0.07f, false);
+ WellBufferMe(ZoomZTarget, &ZoomZ, &ZoomZSpeed, 0.2f, 0.07f, false);
+ Source.x -= Front.x*ZoomGround;
+ Source.y -= Front.y*ZoomGround;
+ Source.z += ZoomZ;
// Process height offset to avoid peds and cars
- float TargetZOffSet = m_fRoadOffSet + m_fDimensionOfHighestNearCar;
- TargetZOffSet = Max(TargetZOffSet, m_fPedBetweenCameraHeightOffset);
+ float TargetZOffSet = Max(m_fDimensionOfHighestNearCar, m_fPedBetweenCameraHeightOffset);
float TargetHeight = CameraTarget.z + TargetZOffSet - Source.z;
if(TargetHeight > m_fCamBufferedHeight){
// Have to go up
if(TargetZOffSet == m_fPedBetweenCameraHeightOffset && TargetZOffSet > m_fCamBufferedHeight)
WellBufferMe(TargetHeight, &m_fCamBufferedHeight, &m_fCamBufferedHeightSpeed, 0.2f, 0.04f, false);
- else if(TargetZOffSet == m_fRoadOffSet && TargetZOffSet > m_fCamBufferedHeight){
- // TODO: figure this out
- bool foo = false;
- switch(((CPhysical*)CamTargetEntity)->m_nSurfaceTouched)
- case SURFACE_GRASS:
- case SURFACE_GRAVEL:
- case SURFACE_PAVEMENT:
- 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);
- else
- WellBufferMe(TargetHeight, &m_fCamBufferedHeight, &m_fCamBufferedHeightSpeed, 0.2f, 0.025f, false);
- }else
+ else
WellBufferMe(TargetHeight, &m_fCamBufferedHeight, &m_fCamBufferedHeightSpeed, 0.2f, 0.025f, false);
StartedCountingForGoDown = false;
}else{
@@ -1449,24 +1303,24 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl
}
Source.z += m_fCamBufferedHeight;
-
-
- // Clip Source if necessary
-
- bool ClipSource = m_fCloseInPedHeightOffset > 0.00001f && m_fCamBufferedHeight > 0.001f;
- if(GoingBehind || ResetStatics || ClipSource){
- CColPoint colpoint;
- CEntity *entity;
- if(CWorld::ProcessLineOfSight(TargetCoors, Source, colpoint, entity, true, false, false, true, false, true, true)){
- Source = colpoint.point;
- if((TargetCoors - Source).Magnitude2D() < 1.0f)
- RwCameraSetNearClipPlane(Scene.camera, 0.05f);
- }
- }
-
TargetCoors.z += Min(1.0f, m_fCamBufferedHeight/2.0f);
m_cvecTargetCoorsForFudgeInter = TargetCoors;
+ CVector OrigSource = Source;
+ TheCamera.AvoidTheGeometry(OrigSource, TargetCoors, Source, FOV);
+ float TargetDist = (TargetCoors - Source).Magnitude();
+ if(TargetDist < Distance)
+ Distance = TargetDist;
+ else{
+ float f = Pow(0.97f, CTimer::GetTimeStep());
+ Distance = (1.0f - f)*TargetDist + f*Distance;
+ if(TargetDist > 0.05f)
+ Source = TargetCoors + (Source-TargetCoors)*Distance/TargetDist;
+ float clip = Distance-fRangePlayerRadius;
+ if(clip < RwCameraGetNearClipPlane(Scene.camera))
+ RwCameraSetNearClipPlane(Scene.camera, Max(clip, fCloseNearClipLimit));
+ }
+
Front = TargetCoors - Source;
m_fRealGroundDist = Front.Magnitude2D();
m_fMinDistAwayFromCamWhenInterPolating = m_fRealGroundDist;
@@ -1474,7 +1328,6 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl
GetVectorsReadyForRW();
TheCamera.m_bCamDirectlyBehind = false;
TheCamera.m_bCamDirectlyInFront = false;
- PreviouslyObscured = BuildingCheckObscured;
ResetStatics = false;
}
@@ -1483,10 +1336,11 @@ float fBaseDist = 1.7f;
float fAngleDist = 2.0f;
float fFalloff = 3.0f;
float fStickSens = 0.01f;
-float fTweakFOV = 1.05f;
+float fTweakFOV = 1.1f;
float fTranslateCamUp = 0.8f;
int16 nFadeControlThreshhold = 45;
float fDefaultAlphaOrient = -0.22f;
+float fMouseAvoidGeomReturnRate = 0.92f;
void
CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrientation, float, float)
@@ -1510,30 +1364,45 @@ CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrient
bool OnTrain = FindPlayerVehicle() && FindPlayerVehicle()->IsTrain();
- // Look around
- bool UseMouse = false;
- float MouseX = CPad::GetPad(0)->GetMouseX();
- float MouseY = CPad::GetPad(0)->GetMouseY();
- float LookLeftRight, LookUpDown;
- if((MouseX != 0.0f || MouseY != 0.0f) && !CPad::GetPad(0)->ArePlayerControlsDisabled()){
- UseMouse = true;
- LookLeftRight = -2.5f*MouseX;
- LookUpDown = 4.0f*MouseY;
- }else{
- LookLeftRight = -CPad::GetPad(0)->LookAroundLeftRight();
- LookUpDown = CPad::GetPad(0)->LookAroundUpDown();
- }
+ TargetCoors = CameraTarget;
+ TargetCoors.z += fTranslateCamUp;
+
float AlphaOffset, BetaOffset;
- if(UseMouse){
- BetaOffset = LookLeftRight * TheCamera.m_fMouseAccelHorzntl * FOV/80.0f;
- AlphaOffset = LookUpDown * TheCamera.m_fMouseAccelVertical * FOV/80.0f;
+ if(CPad::GetPad(0)->IsPlayerControlsDisabledBy(PLAYERCONTROL_PLAYERINFO)){
+ CVector ToCam = Source - TargetCoors;
+ ToCam.Normalise();
+ if(ToCam.z < -0.9f)
+ BetaOffset = TargetOrientation + PI;
+ else
+ BetaOffset = Atan2(ToCam.y, ToCam.x);
+ BetaOffset -= Beta;
+ AlphaOffset = 0.0f;
}else{
- BetaOffset = LookLeftRight * fStickSens * (1.0f/14.0f) * FOV/80.0f * CTimer::GetTimeStep();
- AlphaOffset = LookUpDown * fStickSens * (0.6f/14.0f) * FOV/80.0f * CTimer::GetTimeStep();
+ // Look around
+ bool UseMouse = false;
+ float MouseX = CPad::GetPad(0)->GetMouseX();
+ float MouseY = CPad::GetPad(0)->GetMouseY();
+ float LookLeftRight, LookUpDown;
+ if((MouseX != 0.0f || MouseY != 0.0f) && !CPad::GetPad(0)->ArePlayerControlsDisabled()){
+ UseMouse = true;
+ LookLeftRight = -2.5f*MouseX;
+ LookUpDown = 4.0f*MouseY;
+ }else{
+ LookLeftRight = -CPad::GetPad(0)->LookAroundLeftRight();
+ LookUpDown = CPad::GetPad(0)->LookAroundUpDown();
+ }
+ if(UseMouse){
+ BetaOffset = LookLeftRight * TheCamera.m_fMouseAccelHorzntl * FOV/80.0f;
+ AlphaOffset = LookUpDown * TheCamera.m_fMouseAccelVertical * FOV/80.0f;
+ }else{
+ BetaOffset = LookLeftRight * fStickSens * (1.0f/14.0f) * FOV/80.0f * CTimer::GetTimeStep();
+ AlphaOffset = LookUpDown * fStickSens * (0.6f/14.0f) * FOV/80.0f * CTimer::GetTimeStep();
+ }
}
if(TheCamera.GetFading() && TheCamera.GetFadingDirection() == FADE_IN && nFadeControlThreshhold < CDraw::FadeValue ||
- CDraw::FadeValue > 200){
+ CDraw::FadeValue > 200 ||
+ CPad::GetPad(0)->IsPlayerControlsDisabledBy(PLAYERCONTROL_PLAYERINFO)){
if(Alpha < fDefaultAlphaOrient-0.05f)
AlphaOffset = 0.05f;
else if(Alpha < fDefaultAlphaOrient)
@@ -1553,10 +1422,6 @@ CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrient
if(Alpha > DEGTORAD(45.0f)) Alpha = DEGTORAD(45.0f);
else if(Alpha < -DEGTORAD(89.5f)) Alpha = -DEGTORAD(89.5f);
- TargetCoors = CameraTarget;
- TargetCoors.z += fTranslateCamUp;
- TargetCoors = DoAverageOnVector(TargetCoors);
-
// SA code
#ifdef FREE_CAM
if((CCamera::bFreeCam && Alpha > 0.0f) || (!CCamera::bFreeCam && Alpha > fBaseDist))
@@ -1568,17 +1433,17 @@ CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrient
CamDist = fBaseDist + Cos(Alpha)*fAngleDist;
if(TheCamera.m_bUseTransitionBeta)
- Beta = CGeneral::GetATanOfXY(-Cos(m_fTransitionBeta), -Sin(m_fTransitionBeta));
+ Beta = m_fTransitionBeta;
if(TheCamera.m_bCamDirectlyBehind)
- Beta = TheCamera.m_PedOrientForBehindOrInFront;
- if(TheCamera.m_bCamDirectlyInFront)
Beta = TheCamera.m_PedOrientForBehindOrInFront + PI;
+ if(TheCamera.m_bCamDirectlyInFront)
+ Beta = TheCamera.m_PedOrientForBehindOrInFront;
if(OnTrain)
Beta = TargetOrientation;
- Front.x = Cos(Alpha) * Cos(Beta);
- Front.y = Cos(Alpha) * Sin(Beta);
+ Front.x = Cos(Alpha) * -Cos(Beta);
+ Front.y = Cos(Alpha) * -Sin(Beta);
Front.z = Sin(Alpha);
Source = TargetCoors - Front*CamDist;
m_cvecTargetCoorsForFudgeInter = TargetCoors;
@@ -1608,7 +1473,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);
@@ -1629,8 +1494,8 @@ CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrient
Near = RwCameraGetNearClipPlane(Scene.camera);
#ifndef FIX_BUGS
- // this is totally wrong...
- radius = Tan(FOV / 2.0f) * Near;
+ // this is wrong...DEGTORAD missing
+ radius = Tan(FOV / 2.0f) * CDraw::CalculateAspectRatio() * fTweakFOV * Near;
#else
radius = ViewPlaneWidth*Near;
#endif
@@ -1642,18 +1507,17 @@ CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrient
entity = nil;
}
- if(CamTargetEntity->m_rwObject){
- // what's going on here?
- if(RpAnimBlendClumpGetAssociation(CamTargetEntity->GetClump(), ANIM_STD_WEAPON_PUMP) ||
- RpAnimBlendClumpGetAssociation(CamTargetEntity->GetClump(), ANIM_STD_WEAPON_THROW) ||
- RpAnimBlendClumpGetAssociation(CamTargetEntity->GetClump(), ANIM_STD_THROW_UNDER) ||
- RpAnimBlendClumpGetAssociation(CamTargetEntity->GetClump(), ANIM_STD_START_THROW)){
- CPed *player = FindPlayerPed();
- float PlayerDist = (Source - player->GetPosition()).Magnitude();
- if(PlayerDist < 2.75f)
- Near = PlayerDist/2.75f * DEFAULT_NEAR - 0.3f;
- RwCameraSetNearClipPlane(Scene.camera, Max(Near, 0.1f));
- }
+ float TargetDist = (TargetCoors - Source).Magnitude();
+ if(TargetDist < Distance)
+ Distance = TargetDist;
+ else{
+ float f = Pow(fMouseAvoidGeomReturnRate, CTimer::GetTimeStep());
+ Distance = (1.0f - f)*TargetDist + f*Distance;
+ if(TargetDist > 0.05f)
+ Source = TargetCoors + (Source-TargetCoors)*Distance/TargetDist;
+ float clip = Distance-fRangePlayerRadius;
+ if(clip < RwCameraGetNearClipPlane(Scene.camera))
+ RwCameraSetNearClipPlane(Scene.camera, Max(clip, fCloseNearClipLimit));
}
TheCamera.m_bCamDirectlyInFront = false;
@@ -1662,7 +1526,8 @@ CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrient
GetVectorsReadyForRW();
if(((CPed*)CamTargetEntity)->CanStrafeOrMouseControl() && CDraw::FadeValue < 250 &&
- (TheCamera.GetFadingDirection() != FADE_OUT || CDraw::FadeValue <= 100)){
+ (TheCamera.GetFadingDirection() != FADE_OUT || CDraw::FadeValue <= 100) &&
+ !CPad::GetPad(0)->IsPlayerControlsDisabledBy(PLAYERCONTROL_PLAYERINFO)){
float Heading = Front.Heading();
((CPed*)TheCamera.pTargetEntity)->m_fRotationCur = Heading;
((CPed*)TheCamera.pTargetEntity)->m_fRotationDest = Heading;
@@ -1692,7 +1557,7 @@ CCam::Process_BehindCar(const CVector &CameraTarget, float TargetOrientation, fl
if(Length < 0.002f)
Length = 0.002f;
Beta = CGeneral::GetATanOfXY(TargetCoors.x - Source.x, TargetCoors.y - Source.y);
-#if 1
+#ifdef TOGGLEABLE_BETA_FEATURES
// This is completely made up but Bill's cam manipulates an angle before calling this
// and otherwise calculating Beta doesn't make much sense.
Beta += fBillsBetaOffset;
@@ -1710,303 +1575,171 @@ CCam::Process_BehindCar(const CVector &CameraTarget, float TargetOrientation, fl
}
TargetCoors.z += 0.8f;
- WorkOutCamHeightWeeCar(TargetCoors, TargetOrientation);
+ Alpha = DEGTORAD(25.0f);
+ Source.z = TargetCoors.z + CA_MAX_DISTANCE*Sin(Alpha);
+
RotCamIfInFrontCar(TargetCoors, TargetOrientation);
- FixCamIfObscured(TargetCoors, 1.2f, TargetOrientation);
+ m_cvecTargetCoorsForFudgeInter = TargetCoors;
+ CVector OrigSource = Source;
+ TheCamera.AvoidTheGeometry(OrigSource, m_cvecTargetCoorsForFudgeInter, Source, FOV);
Front = TargetCoors - Source;
- m_cvecTargetCoorsForFudgeInter = TargetCoors;
ResetStatics = false;
GetVectorsReadyForRW();
}
-void
-CCam::WorkOutCamHeightWeeCar(CVector &TargetCoors, float TargetOrientation)
-{
- CColPoint colpoint;
- CEntity *ent;
- float TargetZOffSet = 0.0f;
- static bool PreviouslyFailedRoadHeightCheck = false;
- static float RoadHeightFix = 0.0f;
- static float RoadHeightFixSpeed = 0.0f;
-
- if(ResetStatics){
- RoadHeightFix = 0.0f;
- RoadHeightFixSpeed = 0.0f;
- Alpha = DEGTORAD(25.0f);
- AlphaSpeed = 0.0f;
- }
- float AlphaTarget = DEGTORAD(25.0f);
- if(CCullZones::CamNoRain() || CCullZones::PlayerNoRain())
- AlphaTarget = DEGTORAD(14.0f);
- WellBufferMe(AlphaTarget, &Alpha, &AlphaSpeed, 0.1f, 0.05f, true);
- Source.z = TargetCoors.z + CA_MAX_DISTANCE*Sin(Alpha);
-
- if(FindPlayerVehicle()){
- m_fRoadOffSet = 0.0f;
- bool FoundRoad = false;
- bool FoundRoof = false;
- float RoadZ = 0.0f;
- float RoofZ = 0.0f;
-
- if(CWorld::ProcessVerticalLine(Source, -1000.0f, colpoint, ent, true, false, false, false, false, false, nil) &&
- ent->IsBuilding()){
- FoundRoad = true;
- RoadZ = colpoint.point.z;
- }
-
- if(FoundRoad){
- if(Source.z - RoadZ < 0.9f){
- PreviouslyFailedRoadHeightCheck = true;
- TargetZOffSet = RoadZ + 0.9f - Source.z;
- }else{
- if(m_bCollisionChecksOn)
- PreviouslyFailedRoadHeightCheck = false;
- else
- TargetZOffSet = 0.0f;
- }
- }else{
- if(CWorld::ProcessVerticalLine(Source, 1000.0f, colpoint, ent, true, false, false, false, false, false, nil) &&
- ent->IsBuilding()){
- FoundRoof = true;
- RoofZ = colpoint.point.z;
- }
- if(FoundRoof){
- if(Source.z - RoofZ < 0.9f){
- PreviouslyFailedRoadHeightCheck = true;
- TargetZOffSet = RoofZ + 0.9f - Source.z;
- }else{
- if(m_bCollisionChecksOn)
- PreviouslyFailedRoadHeightCheck = false;
- else
- TargetZOffSet = 0.0f;
- }
- }
- }
- }
-
- if(TargetZOffSet > RoadHeightFix)
- RoadHeightFix = TargetZOffSet;
- else
- WellBufferMe(TargetZOffSet, &RoadHeightFix, &RoadHeightFixSpeed, 0.27f, 0.1f, false);
-
- if(colpoint.surfaceB != SURFACE_TARMAC &&
- colpoint.surfaceB != SURFACE_GRASS &&
- colpoint.surfaceB != SURFACE_GRAVEL &&
- colpoint.surfaceB != SURFACE_MUD_DRY &&
- colpoint.surfaceB != SURFACE_PAVEMENT &&
- colpoint.surfaceB != SURFACE_THICK_METAL_PLATE &&
- colpoint.surfaceB != SURFACE_STEEP_CLIFF &&
- RoadHeightFix > 1.4f)
- RoadHeightFix = 1.4f;
-
- Source.z += RoadHeightFix;
-}
+float ZmOneAlphaOffset[] = { -0.01f, 0.1f, 0.125f, -0.1f, -0.06f };
+float ZmTwoAlphaOffset[] = { 0.045f, 0.12f, 0.045f, 0.045f, -0.035f };
+float ZmThreeAlphaOffset[] = { 0.005f, 0.005f, 0.15f, 0.005f, 0.12f };
+float INIT_RC_HELI_HORI_EXTRA = 6.0f;
+float INIT_RC_PLANE_HORI_EXTRA = 9.5f;
+float INIT_RC_HELI_ALPHA_EXTRA = 0.2f;
+float INIT_RC_PLANE_ALPHA_EXTRA = 0.295f;
void
CCam::WorkOutCamHeight(const CVector &TargetCoors, float TargetOrientation, float TargetHeight)
{
- float AlphaOffset = 0.0f;
- bool CamClear = true;
+ if(!CamTargetEntity->IsVehicle())
+ return;
- static float LastTargetAlphaWithCollisionOn = 0.0f;
- static float LastTopAlphaSpeed = 0.0f;
- static float LastAlphaSpeedStep = 0.0f;
- static bool PreviousNearCheckNearClipSmall = false;
+ static float AlphaOffset = 0.0;
+ static float AlphaOffsetSpeed = 0.0;
+ static float AlphaDec = 0.0f;
+
+ bool isHeli = false;
+ bool isBike = false;
+ int appearance = ((CVehicle*)CamTargetEntity)->GetVehicleAppearance();
+ if(appearance == VEHICLE_APPEARANCE_BIKE)
+ isBike = true;
+ if(appearance == VEHICLE_APPEARANCE_HELI)
+ isHeli = true;
+ int index = 0;
+ TheCamera.GetArrPosForVehicleType(appearance, index);
+
+ float ExtraOffset = 0.0f;
+ int id = CamTargetEntity->GetModelIndex();
+ if(id == MI_RCRAIDER || id == MI_RCGOBLIN)
+ ExtraOffset = INIT_RC_HELI_ALPHA_EXTRA;
+ else if(id == MI_RCBARON)
+ ExtraOffset = INIT_RC_PLANE_ALPHA_EXTRA;
if(ResetStatics){
- LastTargetAlphaWithCollisionOn = 0.0f;
- LastTopAlphaSpeed = 0.0f;
- LastAlphaSpeedStep = 0.0f;
- PreviousNearCheckNearClipSmall = false;
- }
+ AlphaOffset = 0.0f;
+ AlphaOffsetSpeed = 0.0f;
+ AlphaDec = 0.0f;
- float TopAlphaSpeed = 0.15f;
- float AlphaSpeedStep = 0.015f;
+ if(TheCamera.CarZoomIndicator == CAM_ZOOM_1)
+ AlphaOffset = ZmOneAlphaOffset[index] + ExtraOffset;
+ else if(TheCamera.CarZoomIndicator == CAM_ZOOM_2)
+ AlphaOffset = ZmTwoAlphaOffset[index] + ExtraOffset;
+ else if(TheCamera.CarZoomIndicator == CAM_ZOOM_3)
+ AlphaOffset = ZmThreeAlphaOffset[index] + ExtraOffset;
+ }
- float zoomvalue = TheCamera.CarZoomValueSmooth;
- if(zoomvalue < 0.1f)
- zoomvalue = 0.1f;
if(TheCamera.CarZoomIndicator == CAM_ZOOM_1)
- AlphaOffset = CGeneral::GetATanOfXY(23.0f, zoomvalue); // near
+ WellBufferMe(ZmOneAlphaOffset[index] + ExtraOffset, &AlphaOffset, &AlphaOffsetSpeed, 0.17f, 0.08f, false);
else if(TheCamera.CarZoomIndicator == CAM_ZOOM_2)
- AlphaOffset = CGeneral::GetATanOfXY(10.8f, zoomvalue); // mid
+ WellBufferMe(ZmTwoAlphaOffset[index] + ExtraOffset, &AlphaOffset, &AlphaOffsetSpeed, 0.17f, 0.08f, false);
else if(TheCamera.CarZoomIndicator == CAM_ZOOM_3)
- AlphaOffset = CGeneral::GetATanOfXY(7.0f, zoomvalue); // far
-
+ WellBufferMe(ZmThreeAlphaOffset[index] + ExtraOffset, &AlphaOffset, &AlphaOffsetSpeed, 0.17f, 0.08f, false);
float Length = (Source - TargetCoors).Magnitude2D();
- if(m_bCollisionChecksOn){ // there's another variable (on PC) but it's uninitialised
- float CarAlpha = CGeneral::GetATanOfXY(CamTargetEntity->GetForward().Magnitude2D(), CamTargetEntity->GetForward().z);
- // this shouldn't be necessary....
- while(CarAlpha >= PI) CarAlpha -= 2*PI;
- while(CarAlpha < -PI) CarAlpha += 2*PI;
-
- while(Beta >= PI) Beta -= 2*PI;
- while(Beta < -PI) Beta += 2*PI;
-
- float DeltaBeta = Beta - TargetOrientation;
- while(DeltaBeta >= PI) DeltaBeta -= 2*PI;
- while(DeltaBeta < -PI) DeltaBeta += 2*PI;
-
- float BehindCarNess = Cos(DeltaBeta); // 1 if behind car, 0 if side, -1 if in front
- CarAlpha = -CarAlpha * BehindCarNess;
- if(CarAlpha < -0.01f)
- CarAlpha = -0.01f;
-
- float DeltaAlpha = CarAlpha - Alpha;
- while(DeltaAlpha >= PI) DeltaAlpha -= 2*PI;
- while(DeltaAlpha < -PI) DeltaAlpha += 2*PI;
- // What's this?? wouldn't it make more sense to clamp?
- float AngleLimit = DEGTORAD(1.8f);
- if(DeltaAlpha > AngleLimit)
- DeltaAlpha -= AngleLimit;
- else if(DeltaAlpha < -AngleLimit)
- DeltaAlpha += AngleLimit;
- else
- DeltaAlpha = 0.0f;
-
- // Now the collision
-
- float TargetAlpha = 0.0f;
- bool FoundRoofCenter = false;
- bool FoundRoofSide1 = false;
- bool FoundRoofSide2 = false;
- bool FoundCamRoof = false;
- bool FoundCamGround = false;
- float CamRoof = 0.0f;
- float CarBottom = TargetCoors.z - TargetHeight/2.0f;
- // Check car center
- float CarRoof = CWorld::FindRoofZFor3DCoord(TargetCoors.x, TargetCoors.y, CarBottom, &FoundRoofCenter);
+ CVector Forward = CamTargetEntity->GetForward();
+ float CarAlpha = CGeneral::GetATanOfXY(Forward.Magnitude2D(), Forward.z);
+ // this shouldn't be necessary....
+ while(CarAlpha >= PI) CarAlpha -= 2*PI;
+ while(CarAlpha < -PI) CarAlpha += 2*PI;
- // Check sides of the car
- CVector Forward = CamTargetEntity->GetForward();
- Forward.Normalise(); // shouldn't be necessary
- float CarSideAngle = CGeneral::GetATanOfXY(Forward.x, Forward.y) + PI/2.0f;
- float SideX = 2.5f * Cos(CarSideAngle);
- float SideY = 2.5f * Sin(CarSideAngle);
- CWorld::FindRoofZFor3DCoord(TargetCoors.x + SideX, TargetCoors.y + SideY, CarBottom, &FoundRoofSide1);
- CWorld::FindRoofZFor3DCoord(TargetCoors.x - SideX, TargetCoors.y - SideY, CarBottom, &FoundRoofSide2);
-
- // Now find out at what height we'd like to place the camera
- float CamGround = CWorld::FindGroundZFor3DCoord(Source.x, Source.y, TargetCoors.z + Length*Sin(Alpha + AlphaOffset) + m_fCloseInCarHeightOffset, &FoundCamGround);
- float CamTargetZ = 0.0f;
- if(FoundCamGround){
- // This is the normal case
- CamRoof = CWorld::FindRoofZFor3DCoord(Source.x, Source.y, CamGround + TargetHeight, &FoundCamRoof);
- CamTargetZ = CamGround + TargetHeight*1.5f + 0.1f;
- }else{
- FoundCamRoof = false;
- CamTargetZ = TargetCoors.z;
- }
+ while(Beta >= PI) Beta -= 2*PI;
+ while(Beta < -PI) Beta += 2*PI;
- if(FoundRoofCenter && !FoundCamRoof && (FoundRoofSide1 || FoundRoofSide2)){
- // Car is under something but camera isn't
- // This seems weird...
- TargetAlpha = CGeneral::GetATanOfXY(CA_MAX_DISTANCE, CarRoof - CamTargetZ - 1.5f);
- CamClear = false;
- }
- if(FoundCamRoof){
- // Camera is under something
- float roof = FoundRoofCenter ? Min(CamRoof, CarRoof) : CamRoof;
- // Same weirdness again?
- TargetAlpha = CGeneral::GetATanOfXY(CA_MAX_DISTANCE, roof - CamTargetZ - 1.5f);
- CamClear = false;
- }
- while(TargetAlpha >= PI) TargetAlpha -= 2*PI;
- while(TargetAlpha < -PI) TargetAlpha += 2*PI;
- if(TargetAlpha < DEGTORAD(-7.0f))
- TargetAlpha = DEGTORAD(-7.0f);
-
- // huh?
- if(TargetAlpha > AlphaOffset)
- CamClear = true;
- // Camera is constrained by collision in some way
- PreviousNearCheckNearClipSmall = false;
- if(!CamClear){
- PreviousNearCheckNearClipSmall = true;
- RwCameraSetNearClipPlane(Scene.camera, DEFAULT_NEAR);
-
- DeltaAlpha = TargetAlpha - (Alpha + AlphaOffset);
- while(DeltaAlpha >= PI) DeltaAlpha -= 2*PI;
- while(DeltaAlpha < -PI) DeltaAlpha += 2*PI;
-
- TopAlphaSpeed = 0.3f;
- AlphaSpeedStep = 0.03f;
- }
+ float DeltaBeta = Beta - TargetOrientation;
+ while(DeltaBeta >= PI) DeltaBeta -= 2*PI;
+ while(DeltaBeta < -PI) DeltaBeta += 2*PI;
- // Now do things if CamClear...but what is that anyway?
- float CamZ = TargetCoors.z + Length*Sin(Alpha + DeltaAlpha + AlphaOffset) + m_fCloseInCarHeightOffset;
- bool FoundGround, FoundRoof;
- float CamGround2 = CWorld::FindGroundZFor3DCoord(Source.x, Source.y, CamZ, &FoundGround);
- if(FoundGround && CamClear){
- if(CamZ - CamGround2 < 1.5f){
- PreviousNearCheckNearClipSmall = true;
- RwCameraSetNearClipPlane(Scene.camera, DEFAULT_NEAR);
-
- float dz = CamGround2 + 1.5f - TargetCoors.z;
- float a;
- if(Length == 0.0f || dz == 0.0f)
- a = Alpha;
- else
- a = CGeneral::GetATanOfXY(Length, dz);
- while(a > PI) a -= 2*PI;
- while(a < -PI) a += 2*PI;
- DeltaAlpha = a - Alpha;
- }
- }else if(CamClear){
- float CamRoof2 = CWorld::FindRoofZFor3DCoord(Source.x, Source.y, CamZ, &FoundRoof);
- if(FoundRoof && CamZ - CamRoof2 < 1.5f){
- PreviousNearCheckNearClipSmall = true;
- RwCameraSetNearClipPlane(Scene.camera, DEFAULT_NEAR);
-
- if(CamRoof2 > TargetCoors.z + 3.5f)
- CamRoof2 = TargetCoors.z + 3.5f;
-
- float dz = CamRoof2 + 1.5f - TargetCoors.z;
- float a;
- if(Length == 0.0f || dz == 0.0f)
- a = Alpha;
- else
- a = CGeneral::GetATanOfXY(Length, dz);
- while(a > PI) a -= 2*PI;
- while(a < -PI) a += 2*PI;
- DeltaAlpha = a - Alpha;
- }
- }
+ float BehindCarNess = Cos(DeltaBeta); // 1 if behind car, 0 if side, -1 if in front
+ CarAlpha = -CarAlpha * BehindCarNess;
+
+ float fwdSpeed = DotProduct(((CPhysical*)CamTargetEntity)->m_vecMoveSpeed, CamTargetEntity->GetForward())*180.0f;
+ if(CamTargetEntity->GetModelIndex() == MI_FIRETRUCK && CPad::GetPad(0)->GetCarGunFired()){
+ CarAlpha = DEGTORAD(10.0f);
+ }else if(isHeli){
+ CarAlpha = 0.0f;
+ float heliFwdZ = CamTargetEntity->GetForward().z;
+ float heliFwdXY = CamTargetEntity->GetForward().Magnitude2D();
+ float alphaAmount = Min(Abs(fwdSpeed/90.0f), 1.0f);
+ if(heliFwdXY != 0.0f || heliFwdZ != 0.0f)
+ CarAlpha = CGeneral::GetATanOfXY(heliFwdXY, Abs(heliFwdZ)) * alphaAmount;
+
+ CColPoint point;
+ CEntity *entity = nil;
+ CVector Test = Source;
+ Test.z = TargetCoors.z + 0.2f + Length*Sin(CarAlpha+AlphaOffset) + m_fCloseInCarHeightOffset;
+ if(CWorld::ProcessVerticalLine(Test, CamTargetEntity->GetPosition().z, point, entity, true, false, false, false, false, false, nil)){
+ float sin = (point.point.z - TargetCoors.z - 0.2f - m_fCloseInCarHeightOffset)/Length;
+ CarAlpha = Asin(Clamp(sin, -1.0f, 1.0f)) - AlphaOffset;
+ if(CarAlpha < 0.0f)
+ AlphaOffset += CarAlpha;
+ }
+ }
+
+ CarAlpha = CGeneral::LimitRadianAngle(CarAlpha);
+ if(CarAlpha < 0.0f) CarAlpha = 0.0f;
+ if(CarAlpha > DEGTORAD(89.0f)) CarAlpha = DEGTORAD(89.0f);
- LastTargetAlphaWithCollisionOn = DeltaAlpha + Alpha;
- LastTopAlphaSpeed = TopAlphaSpeed;
- LastAlphaSpeedStep = AlphaSpeedStep;
- }else{
- if(PreviousNearCheckNearClipSmall)
- RwCameraSetNearClipPlane(Scene.camera, DEFAULT_NEAR);
- }
+ if(ResetStatics)
+ Alpha = CarAlpha;
- WellBufferMe(LastTargetAlphaWithCollisionOn, &Alpha, &AlphaSpeed, LastTopAlphaSpeed, LastAlphaSpeedStep, true);
+ float TargetAlpha = Alpha;
+ float DeltaAlpha = CarAlpha - TargetAlpha;
+ while(DeltaAlpha >= PI) DeltaAlpha -= 2*PI;
+ while(DeltaAlpha < -PI) DeltaAlpha += 2*PI;
+ if(Abs(DeltaAlpha) > 0.0f && !TheCamera.m_bVehicleSuspenHigh)
+ TargetAlpha = CarAlpha;
+
+ if(isBike)
+ WellBufferMe(TargetAlpha, &Alpha, &AlphaSpeed, 0.09f, 0.04f, true);
+ else if(isHeli)
+ WellBufferMe(TargetAlpha, &Alpha, &AlphaSpeed, 0.09f, 0.04f, true);
+ else
+ WellBufferMe(TargetAlpha, &Alpha, &AlphaSpeed, 0.15f, 0.07f, true);
Source.z = TargetCoors.z + Sin(Alpha + AlphaOffset)*Length + m_fCloseInCarHeightOffset;
+ AlphaOffset -= AlphaDec;
}
// Rotate cam behind the car when the car is moving forward
bool
CCam::RotCamIfInFrontCar(CVector &TargetCoors, float TargetOrientation)
{
+ float BetaMaxSpeed = 0.15f;
+ float BetaAcceleration = 0.007f;
bool MovingForward = false;
+ float MaxDiffBeta = DEGTORAD(160.0f);
CPhysical *phys = (CPhysical*)CamTargetEntity;
float ForwardSpeed = DotProduct(phys->GetForward(), phys->GetSpeed(CVector(0.0f, 0.0f, 0.0f)));
if(ForwardSpeed > 0.02f)
MovingForward = true;
+ if(phys->IsVehicle() && (phys->GetModelIndex() == MI_SPARROW || phys->GetModelIndex() == MI_HUNTER)){
+ MaxDiffBeta = DEGTORAD(160.0f);
+ BetaMaxSpeed = 0.1f;
+ BetaAcceleration = 0.003f;
+ CVector speed = phys->GetSpeed(CVector(0.0f, 0.0f, 0.0f));
+ speed.z = 0.0f;
+ if(50.0f*speed.Magnitude() > 3.13f)
+ TargetOrientation = CGeneral::GetATanOfXY(speed.x, speed.y);
+ }
+
float Dist = (Source - TargetCoors).Magnitude2D();
float DeltaBeta = TargetOrientation - Beta;
while(DeltaBeta >= PI) DeltaBeta -= 2*PI;
while(DeltaBeta < -PI) DeltaBeta += 2*PI;
- if(Abs(DeltaBeta) > DEGTORAD(20.0f) && MovingForward && TheCamera.m_uiTransitionState == 0)
+ if(Abs(DeltaBeta) > PI-MaxDiffBeta && MovingForward && TheCamera.m_uiTransitionState == 0)
m_bFixingBeta = true;
CPad *pad = CPad::GetPad(0);
@@ -2023,7 +1756,7 @@ CCam::RotCamIfInFrontCar(CVector &TargetCoors, float TargetOrientation)
SetBeta = true;
if(m_bFixingBeta || SetBeta){
- WellBufferMe(TargetOrientation, &Beta, &BetaSpeed, 0.15f, 0.007f, true);
+ WellBufferMe(TargetOrientation, &Beta, &BetaSpeed, BetaMaxSpeed, BetaAcceleration, true);
if(TheCamera.m_bCamDirectlyBehind && &TheCamera.Cams[TheCamera.ActiveCam] == this)
Beta = TargetOrientation;
@@ -2047,78 +1780,11 @@ CCam::RotCamIfInFrontCar(CVector &TargetCoors, float TargetOrientation)
return true;
}
-// Move the cam to avoid clipping through buildings
-bool
-CCam::FixCamIfObscured(CVector &TargetCoors, float TargetHeight, float TargetOrientation)
-{
- CVector Target = TargetCoors;
- bool UseEntityPos = false;
- CVector EntityPos;
- static CColPoint colPoint;
- static bool LastObscured = false;
-
- if(Mode == MODE_BEHINDCAR)
- Target.z += TargetHeight/2.0f;
- if(Mode == MODE_CAM_ON_A_STRING){
- UseEntityPos = true;
- Target.z += TargetHeight/2.0f;
- EntityPos = CamTargetEntity->GetPosition();
- }
-
- CVector TempSource = Source;
-
- bool Obscured1 = false;
- bool Obscured2 = false;
- bool Fix1 = false;
- float Dist1 = 0.0f;
- float Dist2 = 0.0f;
- CEntity *ent;
- if(m_bCollisionChecksOn || LastObscured){
- Obscured1 = CWorld::ProcessLineOfSight(Target, TempSource, colPoint, ent, true, false, false, true, false, true, true);
- if(Obscured1){
- Dist1 = (Target - colPoint.point).Magnitude2D();
- Fix1 = true;
- if(UseEntityPos)
- Obscured1 = CWorld::ProcessLineOfSight(EntityPos, TempSource, colPoint, ent, true, false, false, true, false, true, true);
- }else if(m_bFixingBeta){
- float d = (TempSource - Target).Magnitude();
- TempSource.x = Target.x - d*Cos(TargetOrientation);
- TempSource.y = Target.y - d*Sin(TargetOrientation);
-
- // same check again
- Obscured2 = CWorld::ProcessLineOfSight(Target, TempSource, colPoint, ent, true, false, false, true, false, true, true);
- if(Obscured2){
- Dist2 = (Target - colPoint.point).Magnitude2D();
- if(UseEntityPos)
- Obscured2 = CWorld::ProcessLineOfSight(EntityPos, TempSource, colPoint, ent, true, false, false, true, false, true, true);
- }
- }
- LastObscured = Obscured1 || Obscured2;
- }
-
- // nothing to do
- if(!LastObscured)
- return false;
-
- if(Fix1){
- Source.x = Target.x - Cos(Beta)*Dist1;
- Source.y = Target.y - Sin(Beta)*Dist1;
- if(Mode == MODE_BEHINDCAR)
- Source = colPoint.point;
- }else{
- WellBufferMe(Dist2, &m_fDistanceBeforeChanges, &DistanceSpeed, 0.2f, 0.025f, false);
- Source.x = Target.x - Cos(Beta)*m_fDistanceBeforeChanges;
- Source.y = Target.y - Sin(Beta)*m_fDistanceBeforeChanges;
- }
-
- if(ResetStatics){
- m_fDistanceBeforeChanges = (Source - Target).Magnitude2D();
- DistanceSpeed = 0.0f;
- Source.x = colPoint.point.x;
- Source.y = colPoint.point.y;
- }
- return true;
-}
+float FIRETRUCK_TRACKING_MULT = 0.1f;
+float fTestShiftHeliCamTarget = 0.6f;
+float TiltTopSpeed[] = { 0.035f, 0.035f, 0.001f, 0.005f, 0.035f };
+float TiltSpeedStep[] = { 0.016f, 0.016f, 0.0002f, 0.0014f, 0.016f };
+float TiltOverShoot[] = { 1.05f, 1.05f, 0.0f, 0.0f, 1.0f };
void
CCam::Process_Cam_On_A_String(const CVector &CameraTarget, float TargetOrientation, float, float)
@@ -2126,38 +1792,117 @@ CCam::Process_Cam_On_A_String(const CVector &CameraTarget, float TargetOrientati
if(!CamTargetEntity->IsVehicle())
return;
+ // unused
+ // ((CVehicle*)CamTargetEntity)->GetVehicleAppearance();
+
FOV = DefaultFOV;
if(ResetStatics){
AlphaSpeed = 0.0f;
- if(TheCamera.m_bIdleOn)
- TheCamera.m_uiTimeWeEnteredIdle = CTimer::GetTimeInMilliseconds();
+ m_fTilt = 0.0f;
+ m_fTiltSpeed = 0.0;
}
CBaseModelInfo *mi = CModelInfo::GetModelInfo(CamTargetEntity->GetModelIndex());
CVector Dimensions = mi->GetColModel()->boundingBox.max - mi->GetColModel()->boundingBox.min;
CVector TargetCoors = CameraTarget;
- float BaseDist = Dimensions.Magnitude2D();
+ float BaseDist = Dimensions.Magnitude();
+
+ if(((CVehicle*)CamTargetEntity)->IsBike())
+ BaseDist *= 1.45f;
+ if(((CVehicle*)CamTargetEntity)->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI &&
+ CamTargetEntity->GetStatus() != STATUS_PLAYER_REMOTE)
+ TargetCoors += fTestShiftHeliCamTarget * CamTargetEntity->GetUp() * Dimensions.z;
+ else
+ TargetCoors.z += 0.8f*Dimensions.z;
- TargetCoors.z += Dimensions.z - 0.1f; // final
Beta = CGeneral::GetATanOfXY(TargetCoors.x - Source.x, TargetCoors.y - Source.y);
- while(Alpha >= PI) Alpha -= 2*PI;
- while(Alpha < -PI) Alpha += 2*PI;
- while(Beta >= PI) Beta -= 2*PI;
- while(Beta < -PI) Beta += 2*PI;
+ Alpha = CGeneral::LimitRadianAngle(Alpha);
+ Beta = CGeneral::LimitRadianAngle(Beta);
+
+ if(CamTargetEntity->GetModelIndex() == MI_FIRETRUCK && CPad::GetPad(0)->GetCarGunFired() &&
+ ((CVehicle*)CamTargetEntity)->m_vecMoveSpeed.Magnitude2D() < 0.01f){
+ float TargetBeta = CamTargetEntity->GetForward().Heading() - ((CAutomobile*)CamTargetEntity)->m_fCarGunLR + HALFPI;
+ TargetBeta = CGeneral::LimitRadianAngle(TargetBeta);
+ float DeltaBeta = TargetBeta - Beta;
+ if(DeltaBeta > PI) DeltaBeta -= TWOPI;
+ else if(DeltaBeta < -PI) DeltaBeta += TWOPI;
+ float dist = (TargetCoors - Source).Magnitude();
+ dist = FIRETRUCK_TRACKING_MULT*dist*Clamp(DeltaBeta, -0.8f, 0.8f);
+ Source += dist*CrossProduct(Front, CVector(0.0f, 0.0f, 1.0f));
+ }
m_fDistanceBeforeChanges = (Source - TargetCoors).Magnitude2D();
Cam_On_A_String_Unobscured(TargetCoors, BaseDist);
WorkOutCamHeight(TargetCoors, TargetOrientation, Dimensions.z);
RotCamIfInFrontCar(TargetCoors, TargetOrientation);
- FixCamIfObscured(TargetCoors, Dimensions.z, TargetOrientation);
FixCamWhenObscuredByVehicle(TargetCoors);
m_cvecTargetCoorsForFudgeInter = TargetCoors;
+ CVector OrigSource = Source;
+ if(CWorld::GetIsLineOfSightClear(CamTargetEntity->GetPosition(), m_cvecTargetCoorsForFudgeInter, true, false, false, true, false, false, true))
+ TheCamera.AvoidTheGeometry(OrigSource, m_cvecTargetCoorsForFudgeInter, Source, FOV);
+ else
+ TheCamera.AvoidTheGeometry(OrigSource, CamTargetEntity->GetPosition(), Source, FOV);
+
Front = TargetCoors - Source;
Front.Normalise();
- GetVectorsReadyForRW();
+
+ int appearance = ((CVehicle*)CamTargetEntity)->GetVehicleAppearance();
+ int index = 0;
+ TheCamera.GetArrPosForVehicleType(appearance, index);
+
+ if(appearance == VEHICLE_APPEARANCE_HELI){
+ float TargetTilt = DotProduct(Front, ((CVehicle*)CamTargetEntity)->GetSpeed(CVector(0.0f, 0.0f, 0.0f)));
+ CVector UpTarget = CamTargetEntity->GetUp();
+ UpTarget.Normalise();
+ int dir = TargetTilt < 0.0f ? -1 : 1;
+ if(m_fTilt != 0.0f)
+ TargetTilt += TiltOverShoot[index]*TargetTilt/m_fTilt * dir;
+ WellBufferMe(TargetTilt, &m_fTilt, &m_fTiltSpeed, TiltTopSpeed[index], TiltSpeedStep[index], false);
+
+ Up = CVector(0.0f, 0.0f, 1.0f) - (CVector(0.0f, 0.0f, 1.0f) - UpTarget)*m_fTilt;
+ Up.Normalise();
+ Front.Normalise();
+ CVector Left = CrossProduct(Up, Front);
+ Up = CrossProduct(Front, Left);
+ Up.Normalise();
+ }else{
+ float TargetRoll;
+ if(CPad::GetPad(0)->GetDPadLeft() || CPad::GetPad(0)->GetDPadRight()){
+ float fwdSpeed = 180.0f*DotProduct(((CVehicle*)CamTargetEntity)->m_vecMoveSpeed, CamTargetEntity->GetForward());
+ if(fwdSpeed > 210.0f) fwdSpeed = 210.0f;
+ if(CPad::GetPad(0)->GetDPadLeft())
+ TargetRoll = DEGTORAD(10.0f)*TiltOverShoot[index] + f_max_role_angle;
+ else
+ TargetRoll = -(DEGTORAD(10.0f)*TiltOverShoot[index] + f_max_role_angle);
+ CVector FwdTarget = CamTargetEntity->GetForward();
+ FwdTarget.Normalise();
+ float AngleDiff = DotProduct(FwdTarget, Front);
+ AngleDiff = Acos(Min(Abs(AngleDiff), 1.0f));
+ TargetRoll *= fwdSpeed/210.0f * Sin(AngleDiff);
+ }else{
+ float fwdSpeed = 180.0f*DotProduct(((CVehicle*)CamTargetEntity)->m_vecMoveSpeed, CamTargetEntity->GetForward());
+ if(fwdSpeed > 210.0f) fwdSpeed = 210.0f;
+ TargetRoll = CPad::GetPad(0)->GetLeftStickX()/128.0f * fwdSpeed/210.0f;
+ CVector FwdTarget = CamTargetEntity->GetForward();
+ FwdTarget.Normalise();
+ float AngleDiff = DotProduct(FwdTarget, Front);
+ AngleDiff = Acos(Min(Abs(AngleDiff), 1.0f));
+ TargetRoll *= (DEGTORAD(10.0f)*TiltOverShoot[index] + f_max_role_angle) * Sin(AngleDiff);
+ }
+
+ WellBufferMe(TargetRoll, &f_Roll, &f_rollSpeed, 0.15f, 0.07f, false);
+ Up = CVector(Cos(f_Roll + HALFPI), 0.0f, Sin(f_Roll + HALFPI));
+ Up.Normalise();
+ Front.Normalise();
+ CVector Left = CrossProduct(Up, Front);
+ Left.Normalise();
+ Up = CrossProduct(Front, Left);
+ Up.Normalise();
+ }
+
ResetStatics = false;
}
@@ -2165,8 +1910,17 @@ CCam::Process_Cam_On_A_String(const CVector &CameraTarget, float TargetOrientati
void
CCam::Cam_On_A_String_Unobscured(const CVector &TargetCoors, float BaseDist)
{
- CA_MAX_DISTANCE = BaseDist + 0.1f + TheCamera.CarZoomValueSmooth;
+ int id = CamTargetEntity->GetModelIndex();
+ float ExtraDist = 0.0f;
+ if(id == MI_RCRAIDER || id == MI_RCGOBLIN)
+ ExtraDist = INIT_RC_HELI_HORI_EXTRA;
+ else if(id == MI_RCBARON)
+ ExtraDist = INIT_RC_PLANE_HORI_EXTRA;
+
+ CA_MAX_DISTANCE = BaseDist + 0.1f + TheCamera.CarZoomValueSmooth + ExtraDist;
CA_MIN_DISTANCE = Min(BaseDist*0.6f, 3.5f);
+ if(CA_MIN_DISTANCE > CA_MAX_DISTANCE)
+ CA_MIN_DISTANCE = CA_MAX_DISTANCE - 0.05f;
CVector Dist = Source - TargetCoors;
@@ -2449,13 +2203,13 @@ CCam::Process_TopDownPed(const CVector &CameraTarget, float TargetOrientation, f
ResetStatics = false;
}
-// Identical to M16
void
CCam::Process_Rocket(const CVector &CameraTarget, float, float, float)
{
if(!CamTargetEntity->IsPed())
return;
+ float BackOffset = 0.19f;
static bool FailedTestTwelveFramesAgo = false;
RwV3d HeadPos;
CVector TargetCoors;
@@ -2474,11 +2228,16 @@ CCam::Process_Rocket(const CVector &CameraTarget, float, float, float)
ResetStatics = false;
}
+ if(((CPed*)CamTargetEntity)->bIsDucking)
+ BackOffset = 0.8f;
+ CamTargetEntity->GetMatrix().UpdateRW();
+ CamTargetEntity->UpdateRwFrame();
+ CamTargetEntity->UpdateRpHAnim();
((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(HeadPos, PED_HEAD);
Source = HeadPos;
Source.z += 0.1f;
- Source.x -= 0.19f*Cos(m_fInitialPlayerOrientation);
- Source.y -= 0.19f*Sin(m_fInitialPlayerOrientation);
+ Source.x -= BackOffset*Cos(m_fInitialPlayerOrientation);
+ Source.y -= BackOffset*Sin(m_fInitialPlayerOrientation);
// Look around
bool UseMouse = false;
@@ -2505,7 +2264,7 @@ CCam::Process_Rocket(const CVector &CameraTarget, float, float, float)
while(Beta >= PI) Beta -= 2*PI;
while(Beta < -PI) Beta += 2*PI;
if(Alpha > DEGTORAD(60.0f)) Alpha = DEGTORAD(60.0f);
- if(Alpha < -DEGTORAD(89.5f)) Alpha = -DEGTORAD(89.5f);
+ else if(Alpha < -DEGTORAD(89.5f)) Alpha = -DEGTORAD(89.5f);
TargetCoors.x = 3.0f * Cos(Alpha) * Cos(Beta) + Source.x;
TargetCoors.y = 3.0f * Cos(Alpha) * Sin(Beta) + Source.y;
@@ -2549,22 +2308,30 @@ CCam::Process_Rocket(const CVector &CameraTarget, float, float, float)
((CPed*)TheCamera.pTargetEntity)->m_fRotationDest = Rotation;
}
-// Identical to Rocket
+float fDuckingBackOffset = 0.5f;
+float fDuckingRightOffset = 0.18f;
+
void
CCam::Process_M16_1stPerson(const CVector &CameraTarget, float, float, float)
{
if(!CamTargetEntity->IsPed())
return;
+ float BackOffset = 0.3f;
static bool FailedTestTwelveFramesAgo = false;
RwV3d HeadPos;
CVector TargetCoors;
+ bool isAttached = ((CPed*)CamTargetEntity)->IsPlayer() && ((CPed*)CamTargetEntity)->m_attachedTo;
+
FOV = DefaultFOV;
TargetCoors = CameraTarget;
if(ResetStatics){
- Beta = ((CPed*)CamTargetEntity)->m_fRotationCur + HALFPI;
+ if(isAttached)
+ Beta = 0.0f;
+ else
+ Beta = ((CPed*)CamTargetEntity)->m_fRotationCur + HALFPI;
Alpha = 0.0f;
m_fInitialPlayerOrientation = ((CPed*)CamTargetEntity)->m_fRotationCur + HALFPI;
FailedTestTwelveFramesAgo = false;
@@ -2574,14 +2341,6 @@ CCam::Process_M16_1stPerson(const CVector &CameraTarget, float, float, float)
ResetStatics = false;
}
-#if GTA_VERSION < GTA3_PC_11
- ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(HeadPos, PED_HEAD);
- Source = HeadPos;
- Source.z += 0.1f;
- Source.x -= 0.19f*Cos(m_fInitialPlayerOrientation);
- Source.y -= 0.19f*Sin(m_fInitialPlayerOrientation);
-#endif
-
// Look around
bool UseMouse = false;
float MouseX = CPad::GetPad(0)->GetMouseX();
@@ -2598,73 +2357,153 @@ CCam::Process_M16_1stPerson(const CVector &CameraTarget, float, float, float)
if(UseMouse){
Beta += TheCamera.m_fMouseAccelHorzntl * LookLeftRight * FOV/80.0f;
Alpha += TheCamera.m_fMouseAccelVertical * LookUpDown * FOV/80.0f;
+ }else if(Mode == MODE_HELICANNON_1STPERSON){
+ LookLeftRight /= 128.0f;
+ LookUpDown /= 128.0f;
+ Beta += LookLeftRight*Abs(LookLeftRight)*0.56f/14.0f * FOV/80.0f * CTimer::GetTimeStep();
+ Alpha += LookUpDown*Abs(LookUpDown)*0.48f/14.0f * FOV/80.0f * CTimer::GetTimeStep();
}else{
float xdir = LookLeftRight < 0.0f ? -1.0f : 1.0f;
float ydir = LookUpDown < 0.0f ? -1.0f : 1.0f;
Beta += SQR(LookLeftRight/100.0f)*xdir*0.8f/14.0f * FOV/80.0f * CTimer::GetTimeStep();
Alpha += SQR(LookUpDown/150.0f)*ydir*1.0f/14.0f * FOV/80.0f * CTimer::GetTimeStep();
}
- while(Beta >= PI) Beta -= 2*PI;
- while(Beta < -PI) Beta += 2*PI;
+ if (!isAttached) {
+ while(Beta >= TWOPI) Beta -= TWOPI;
+ while(Beta < 0) Beta += TWOPI;
+ }
if(Alpha > DEGTORAD(60.0f)) Alpha = DEGTORAD(60.0f);
else if(Alpha < -DEGTORAD(89.5f)) Alpha = -DEGTORAD(89.5f);
-#if GTA_VERSION >= GTA3_PC_11
- HeadPos.x = 0.0f;
- HeadPos.y = 0.0f;
- HeadPos.z = 0.0f;
- ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(HeadPos, PED_HEAD);
- Source = HeadPos;
- Source.z += 0.1f;
- Source.x -= 0.19f * Cos(m_fInitialPlayerOrientation);
- Source.y -= 0.19f * Sin(m_fInitialPlayerOrientation);
-#endif
+ if(((CPed*)CamTargetEntity)->bIsDucking)
+ BackOffset = 0.8f;
+ if(isAttached){
+ CMatrix mat, rot;
+ CPed *TargetPed = (CPed*)CamTargetEntity;
+ TargetPed->PositionAttachedPed();
+ CamTargetEntity->GetMatrix().UpdateRW();
+ CamTargetEntity->UpdateRwFrame();
+ CamTargetEntity->UpdateRpHAnim();
+
+ HeadPos.x = 0.0f;
+ HeadPos.y = 0.0f;
+ HeadPos.z = 0.0f;
+ TargetPed->m_pedIK.GetComponentPosition(HeadPos, PED_HEAD);
+ Source = HeadPos;
+ Source += 0.1f*CamTargetEntity->GetUp();
+ Source -= BackOffset*CamTargetEntity->GetForward();
+
+ if(TargetPed->m_attachRotStep < PI){
+ if(Beta > TargetPed->m_attachRotStep){
+ Beta = TargetPed->m_attachRotStep;
+ CAutomobile *heli = (CAutomobile*)TargetPed->m_attachedTo;
+ if(heli->IsVehicle() && heli->IsCar() && heli->IsRealHeli() && heli->m_fHeliOrientation > 0.0f){
+ float heliOrient = heli->m_fHeliOrientation + CTimer::GetTimeStep()*0.01f;
+ if(heliOrient < 0.0f) heliOrient += TWOPI;
+ else if(heliOrient > TWOPI) heliOrient -= TWOPI;
+ heli->SetHeliOrientation(heliOrient);
+ }
+ }else if(Beta < -TargetPed->m_attachRotStep){
+ Beta = -TargetPed->m_attachRotStep;
+ CAutomobile *heli = (CAutomobile*)TargetPed->m_attachedTo;
+ if(heli->IsVehicle() && heli->IsCar() && heli->IsRealHeli() && heli->m_fHeliOrientation > 0.0f){
+ float heliOrient = heli->m_fHeliOrientation - CTimer::GetTimeStep()*0.01f;
+ if(heliOrient < 0.0f) heliOrient += TWOPI;
+ else if(heliOrient > TWOPI) heliOrient -= TWOPI;
+ heli->SetHeliOrientation(heliOrient);
+ }
+ }
+ }else{
+ while(Beta < -PI) Beta += TWOPI;
+ while(Beta >= PI) Beta -= TWOPI;
+ }
- TargetCoors.x = 3.0f * Cos(Alpha) * Cos(Beta) + Source.x;
- TargetCoors.y = 3.0f * Cos(Alpha) * Sin(Beta) + Source.y;
- TargetCoors.z = 3.0f * Sin(Alpha) + Source.z;
- Front = TargetCoors - Source;
- Front.Normalise();
- Source += Front*0.4f;
+ mat = TargetPed->m_attachedTo->GetMatrix();
+ rot.SetRotateX(Alpha);
+ switch(TargetPed->m_attachType){
+ case 0: rot.RotateZ(Beta); break;
+ case 1: rot.RotateZ(Beta + HALFPI); break;
+ case 2: rot.RotateZ(Beta + PI); break;
+ case 3: rot.RotateZ(Beta - HALFPI); break;
+ }
+ mat = mat * rot;
+ Front = mat.GetForward();
+ Up = mat.GetUp();
+ TargetCoors = Source + 3.0f*Front;
+ RwCameraSetNearClipPlane(Scene.camera, 0.4f);
- if(m_bCollisionChecksOn){
- if(!CWorld::GetIsLineOfSightClear(TargetCoors, Source, true, true, false, true, false, true, true)){
- RwCameraSetNearClipPlane(Scene.camera, 0.4f);
- FailedTestTwelveFramesAgo = true;
+ float Rotation = CGeneral::GetATanOfXY(Front.x, Front.y) - HALFPI;
+ ((CPed*)TheCamera.pTargetEntity)->m_fRotationCur = Rotation;
+ ((CPed*)TheCamera.pTargetEntity)->m_fRotationDest = Rotation;
+ }else{
+ CamTargetEntity->GetMatrix().UpdateRW();
+ CamTargetEntity->UpdateRwFrame();
+ CamTargetEntity->UpdateRpHAnim();
+ HeadPos.x = 0.0f;
+ HeadPos.y = 0.0f;
+ HeadPos.z = 0.0f;
+ ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(HeadPos, PED_HEAD);
+ Source = HeadPos;
+ Source.z += 0.1f;
+ if(((CPed*)CamTargetEntity)->bIsDucking){
+ Source.x -= fDuckingBackOffset*CamTargetEntity->GetForward().x;
+ Source.y -= fDuckingBackOffset*CamTargetEntity->GetForward().y;
+ Source.x -= fDuckingRightOffset*CamTargetEntity->GetRight().x;
+ Source.y -= fDuckingRightOffset*CamTargetEntity->GetRight().y;
}else{
- CVector TestPoint;
- TestPoint.x = 3.0f * Cos(Alpha - DEGTORAD(20.0f)) * Cos(Beta + DEGTORAD(35.0f)) + Source.x;
- TestPoint.y = 3.0f * Cos(Alpha - DEGTORAD(20.0f)) * Sin(Beta + DEGTORAD(35.0f)) + Source.y;
- TestPoint.z = 3.0f * Sin(Alpha - DEGTORAD(20.0f)) + Source.z;
- if(!CWorld::GetIsLineOfSightClear(TestPoint, Source, true, true, false, true, false, true, true)){
+ Source.x -= BackOffset*CamTargetEntity->GetForward().x;
+ Source.y -= BackOffset*CamTargetEntity->GetForward().y;
+ }
+
+ TargetCoors.x = 3.0f * Cos(Alpha) * Cos(Beta) + Source.x;
+ TargetCoors.y = 3.0f * Cos(Alpha) * Sin(Beta) + Source.y;
+ TargetCoors.z = 3.0f * Sin(Alpha) + Source.z;
+ Front = TargetCoors - Source;
+ Front.Normalise();
+ Source += Front*0.4f;
+
+ if(m_bCollisionChecksOn){
+ if(!CWorld::GetIsLineOfSightClear(TargetCoors, Source, true, true, false, true, false, true, true)){
RwCameraSetNearClipPlane(Scene.camera, 0.4f);
FailedTestTwelveFramesAgo = true;
}else{
- TestPoint.x = 3.0f * Cos(Alpha - DEGTORAD(20.0f)) * Cos(Beta - DEGTORAD(35.0f)) + Source.x;
- TestPoint.y = 3.0f * Cos(Alpha - DEGTORAD(20.0f)) * Sin(Beta - DEGTORAD(35.0f)) + Source.y;
+ CVector TestPoint;
+ TestPoint.x = 3.0f * Cos(Alpha - DEGTORAD(20.0f)) * Cos(Beta + DEGTORAD(35.0f)) + Source.x;
+ TestPoint.y = 3.0f * Cos(Alpha - DEGTORAD(20.0f)) * Sin(Beta + DEGTORAD(35.0f)) + Source.y;
TestPoint.z = 3.0f * Sin(Alpha - DEGTORAD(20.0f)) + Source.z;
if(!CWorld::GetIsLineOfSightClear(TestPoint, Source, true, true, false, true, false, true, true)){
RwCameraSetNearClipPlane(Scene.camera, 0.4f);
FailedTestTwelveFramesAgo = true;
- }else
- FailedTestTwelveFramesAgo = false;
+ }else{
+ TestPoint.x = 3.0f * Cos(Alpha - DEGTORAD(20.0f)) * Cos(Beta - DEGTORAD(35.0f)) + Source.x;
+ TestPoint.y = 3.0f * Cos(Alpha - DEGTORAD(20.0f)) * Sin(Beta - DEGTORAD(35.0f)) + Source.y;
+ TestPoint.z = 3.0f * Sin(Alpha - DEGTORAD(20.0f)) + Source.z;
+ if(!CWorld::GetIsLineOfSightClear(TestPoint, Source, true, true, false, true, false, true, true)){
+ RwCameraSetNearClipPlane(Scene.camera, 0.4f);
+ FailedTestTwelveFramesAgo = true;
+ }else
+ FailedTestTwelveFramesAgo = false;
+ }
}
}
- }
- if(FailedTestTwelveFramesAgo)
- RwCameraSetNearClipPlane(Scene.camera, 0.4f);
- Source -= Front*0.4f;
+ if(FailedTestTwelveFramesAgo)
+ RwCameraSetNearClipPlane(Scene.camera, 0.4f);
+ Source -= Front*0.4f;
- GetVectorsReadyForRW();
- float Rotation = CGeneral::GetATanOfXY(Front.x, Front.y) - HALFPI;
- ((CPed*)TheCamera.pTargetEntity)->m_fRotationCur = Rotation;
- ((CPed*)TheCamera.pTargetEntity)->m_fRotationDest = Rotation;
+ GetVectorsReadyForRW();
+ float Rotation = CGeneral::GetATanOfXY(Front.x, Front.y) - HALFPI;
+ ((CPed*)TheCamera.pTargetEntity)->m_fRotationCur = Rotation;
+ ((CPed*)TheCamera.pTargetEntity)->m_fRotationDest = Rotation;
+ }
}
+float fBike1stPersonOffsetZ = 0.15f;
+
void
-CCam::Process_1stPerson(const CVector &CameraTarget, float TargetOrientation, float, float)
+CCam::Process_1stPerson(const CVector &CameraTarget, float TargetOrientation, float SpeedVar, float TargetSpeedVar)
{
+ float BackOffset = 0.3f;
static float DontLookThroughWorldFixer = 0.0f;
CVector TargetCoors;
@@ -2682,6 +2521,7 @@ CCam::Process_1stPerson(const CVector &CameraTarget, float TargetOrientation, fl
Alpha = 0.0f;
m_fInitialPlayerOrientation = ((CPed*)CamTargetEntity)->m_fRotationCur + HALFPI;
}
+ TheCamera.m_fAvoidTheGeometryProbsTimer = 0.0f;
DontLookThroughWorldFixer = 0.0f;
}
@@ -2702,11 +2542,22 @@ CCam::Process_1stPerson(const CVector &CameraTarget, float TargetOrientation, fl
ResetStatics = false;
}
+ CamTargetEntity->GetMatrix().UpdateRW();
+ CamTargetEntity->UpdateRwFrame();
+ CamTargetEntity->UpdateRpHAnim();
+
((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(HeadPos, PED_HEAD);
Source = HeadPos;
Source.z += 0.1f;
- Source.x -= 0.19f*Cos(m_fInitialPlayerOrientation);
- Source.y -= 0.19f*Sin(m_fInitialPlayerOrientation);
+ if(((CPed*)CamTargetEntity)->bIsDucking){
+ Source.x -= fDuckingBackOffset*CamTargetEntity->GetForward().x;
+ Source.y -= fDuckingBackOffset*CamTargetEntity->GetForward().y;
+ Source.x -= fDuckingRightOffset*CamTargetEntity->GetRight().x;
+ Source.y -= fDuckingRightOffset*CamTargetEntity->GetRight().y;
+ }else{
+ Source.x -= BackOffset*CamTargetEntity->GetForward().x;
+ Source.y -= BackOffset*CamTargetEntity->GetForward().y;
+ }
float LookLeftRight, LookUpDown;
LookLeftRight = -CPad::GetPad(0)->LookAroundLeftRight();
@@ -2762,16 +2613,48 @@ CCam::Process_1stPerson(const CVector &CameraTarget, float TargetOrientation, fl
((CPed*)TheCamera.pTargetEntity)->m_fRotationDest = Rotation;
}else{
assert(CamTargetEntity->IsVehicle());
+
+ if(((CVehicle*)CamTargetEntity)->IsBike() &&
+ (((CBike*)CamTargetEntity)->bWheelieCam || TheCamera.m_fAvoidTheGeometryProbsTimer > 0.0f)){
+ if(CPad::GetPad(0)->GetLeftShoulder2() || CPad::GetPad(0)->GetRightShoulder2()){
+ TheCamera.m_fAvoidTheGeometryProbsTimer = 0.0f;
+ ((CBike*)CamTargetEntity)->bWheelieCam = false;
+ }else if(Process_WheelCam(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar)){
+ if(((CBike*)CamTargetEntity)->bWheelieCam)
+ TheCamera.m_fAvoidTheGeometryProbsTimer = 50.0f;
+ else{
+ TheCamera.m_fAvoidTheGeometryProbsTimer -= CTimer::GetTimeStep();
+ ((CBike*)CamTargetEntity)->bWheelieCam = true;
+ }
+ return;
+ }else{
+ TheCamera.m_fAvoidTheGeometryProbsTimer = 0.0f;
+ ((CBike*)CamTargetEntity)->bWheelieCam = false;
+ }
+ }
+
+ CMatrix *matrix = &CamTargetEntity->GetMatrix();
+ if(((CVehicle*)CamTargetEntity)->IsBike()){
+ ((CBike*)CamTargetEntity)->CalculateLeanMatrix();
+ matrix = &((CBike*)CamTargetEntity)->m_leanMatrix;
+ }
+
CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(CamTargetEntity->GetModelIndex());
CVector CamPos = mi->GetFrontSeatPosn();
CamPos.x = 0.0f;
CamPos.y += 0.08f;
CamPos.z += 0.62f;
FOV = 60.0f;
- Source = Multiply3x3(CamTargetEntity->GetMatrix(), CamPos);
+ Source = Multiply3x3(*matrix, CamPos);
Source += CamTargetEntity->GetPosition();
if(((CVehicle*)CamTargetEntity)->IsBoat())
Source.z += 0.5f;
+ else if(((CVehicle*)CamTargetEntity)->IsBike() && ((CVehicle*)CamTargetEntity)->pDriver){
+ CVector Neck(0.0f, 0.0f, 0.0f);
+ ((CVehicle*)CamTargetEntity)->pDriver->m_pedIK.GetComponentPosition(Neck, PED_NECK);
+ Neck += ((CVehicle*)CamTargetEntity)->m_vecMoveSpeed * CTimer::GetTimeStep();
+ Source.z = Neck.z + fBike1stPersonOffsetZ;
+ }
if(((CVehicle*)CamTargetEntity)->IsUpsideDown()){
if(DontLookThroughWorldFixer < 0.5f)
@@ -2789,9 +2672,9 @@ CCam::Process_1stPerson(const CVector &CameraTarget, float TargetOrientation, fl
DontLookThroughWorldFixer = 0.0f;
}
Source.z += DontLookThroughWorldFixer;
- Front = CamTargetEntity->GetForward();
+ Front = matrix->GetForward();
Front.Normalise();
- Up = CamTargetEntity->GetUp();
+ Up = matrix->GetUp();
Up.Normalise();
CVector Right = CrossProduct(Front, Up);
Right.Normalise();
@@ -2822,16 +2705,12 @@ CCam::Process_1rstPersonPedOnPC(const CVector&, float TargetOrientation, float,
CVector TargetCoors;
((CPed*)CamTargetEntity)->TransformToNode(HeadPos, PED_HEAD);
- // This is done on PC, but checking for the clump frame is not necessary apparently
-/*
- RwFrame *frm = ((CPed*)CamTargetEntity)->m_pFrames[PED_HEAD]->frame;
- while(frm){
- RwV3dTransformPoints(&HeadPos, &HeadPos, 1, RwFrameGetMatrix(frm));
- frm = RwFrameGetParent(frm);
- if(frm == RpClumpGetFrame(CamTargetEntity->GetClump()))
- frm = nil;
- }
-*/
+ RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(CamTargetEntity->GetClump());
+ int32 idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_HEAD));
+ RwMatrix *mats = RpHAnimHierarchyGetMatrixArray(hier);
+ RwV3dTransformPoints(&HeadPos, &HeadPos, 1, &mats[idx]);
+ RwV3d scl = { 0.0f, 0.0f, 0.0f };
+ RwMatrixScale(&mats[idx], &scl, rwCOMBINEPRECONCAT);
if(ResetStatics){
Beta = TargetOrientation;
@@ -2900,6 +2779,32 @@ CCam::Process_1rstPersonPedOnPC(const CVector&, float TargetOrientation, float,
if(Alpha > DEGTORAD(60.0f)) Alpha = DEGTORAD(60.0f);
else if(Alpha < -DEGTORAD(89.5f)) Alpha = -DEGTORAD(89.5f);
+ if(((CPed*)CamTargetEntity)->IsPlayer() && ((CPed*)CamTargetEntity)->m_attachedTo){
+ CPed *pedTarget = ((CPed*)CamTargetEntity);
+ float NewBeta;
+ switch(pedTarget->m_attachType){
+ case 0:
+ NewBeta = pedTarget->GetForward().Heading() + HALFPI;
+ break;
+ case 1:
+ NewBeta = pedTarget->GetForward().Heading() + PI;
+ break;
+ case 2:
+ NewBeta = pedTarget->GetForward().Heading() - HALFPI;
+ break;
+ case 3:
+ NewBeta = pedTarget->GetForward().Heading();
+ break;
+ }
+
+ float BetaOffset = Beta - NewBeta;
+ if(BetaOffset > PI) BetaOffset -= TWOPI;
+ else if(BetaOffset < PI) BetaOffset += TWOPI;
+
+ BetaOffset = Clamp(BetaOffset, -pedTarget->m_attachRotStep, pedTarget->m_attachRotStep);
+ Beta = NewBeta + BetaOffset;
+ }
+
TargetCoors.x = 3.0f * Cos(Alpha) * Cos(Beta) + Source.x;
TargetCoors.y = 3.0f * Cos(Alpha) * Sin(Beta) + Source.y;
TargetCoors.z = 3.0f * Sin(Alpha) + Source.z;
@@ -2939,12 +2844,15 @@ CCam::Process_1rstPersonPedOnPC(const CVector&, float TargetOrientation, float,
RwCameraSetNearClipPlane(Scene.camera, 0.05f);
}
+float fCameraNearClipMult = 0.15f;
+
void
CCam::Process_Sniper(const CVector &CameraTarget, float TargetOrientation, float, float)
{
if(!CamTargetEntity->IsPed())
return;
+ float BackOffset = 0.19f;
static bool FailedTestTwelveFramesAgo = false;
RwV3d HeadPos;
CVector TargetCoors;
@@ -2965,11 +2873,23 @@ CCam::Process_Sniper(const CVector &CameraTarget, float TargetOrientation, float
ResetStatics = false;
}
+ if(((CPed*)CamTargetEntity)->bIsDucking)
+ BackOffset = 0.8f;
+ CamTargetEntity->GetMatrix().UpdateRW();
+ CamTargetEntity->UpdateRwFrame();
+ CamTargetEntity->UpdateRpHAnim();
((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(HeadPos, PED_HEAD);
Source = HeadPos;
Source.z += 0.1f;
- Source.x -= 0.19f*Cos(m_fInitialPlayerOrientation);
- Source.y -= 0.19f*Sin(m_fInitialPlayerOrientation);
+ if(((CPed*)CamTargetEntity)->bIsDucking){
+ Source.x -= fDuckingBackOffset*CamTargetEntity->GetForward().x;
+ Source.y -= fDuckingBackOffset*CamTargetEntity->GetForward().y;
+ Source.x -= fDuckingRightOffset*CamTargetEntity->GetRight().x;
+ Source.y -= fDuckingRightOffset*CamTargetEntity->GetRight().y;
+ }else{
+ Source.x -= BackOffset*CamTargetEntity->GetForward().x;
+ Source.y -= BackOffset*CamTargetEntity->GetForward().y;
+ }
// Look around
bool UseMouse = false;
@@ -3038,8 +2958,13 @@ CCam::Process_Sniper(const CVector &CameraTarget, float TargetOrientation, float
if(FOV > DefaultFOV)
FOV = DefaultFOV;
- if(FOV < 15.0f)
- FOV = 15.0f;
+ if(Mode == MODE_CAMERA){
+ if(FOV < 3.0f)
+ FOV = 3.0f;
+ }else{
+ if(FOV < 15.0f)
+ FOV = 15.0f;
+ }
Front = TargetCoors - Source;
Front.Normalise();
@@ -3072,6 +2997,8 @@ CCam::Process_Sniper(const CVector &CameraTarget, float TargetOrientation, float
if(FailedTestTwelveFramesAgo)
RwCameraSetNearClipPlane(Scene.camera, 0.4f);
+ else if(Mode == MODE_CAMERA)
+ RwCameraSetNearClipPlane(Scene.camera, ((15.0f - Min(FOV, 15.0f))*fCameraNearClipMult + 1.0f)*DEFAULT_NEAR);
Source -= Front*0.4f;
GetVectorsReadyForRW();
@@ -3080,6 +3007,12 @@ CCam::Process_Sniper(const CVector &CameraTarget, float TargetOrientation, float
((CPed*)TheCamera.pTargetEntity)->m_fRotationDest = Rotation;
}
+float INIT_SYPHON_GROUND_DIST = 2.419f;
+float INIT_SYPHON_ALPHA_OFFSET = -DEGTORAD(3.0f);
+float INIT_SYPHON_DEGREE_OFFSET = -DEGTORAD(30.0f);
+float FrontOffsetSyphon = -DEGTORAD(25.5f); // unused
+float INIT_SYPHON_Z_OFFSET = -0.5f;
+
void
CCam::Process_Syphon(const CVector &CameraTarget, float, float, float)
{
@@ -3090,82 +3023,123 @@ CCam::Process_Syphon(const CVector &CameraTarget, float, float, float)
static bool CameraObscured = false;
// unused FailedClippingTestPrevously
- static float BetaOffset = DEGTORAD(18.0f);
+ static float BetaOffset = INIT_SYPHON_DEGREE_OFFSET;
// unused AngleToGoTo
// unused AngleToGoToSpeed
// unused DistBetweenPedAndPlayerPreviouslyOn
- static float HeightDown = -0.5f;
- static float PreviousDistForInter;
+ static float HeightDown = INIT_SYPHON_Z_OFFSET;
+ static float AlphaOffset = INIT_SYPHON_ALPHA_OFFSET;
+ static bool NegateBetaOffset = true;
CVector TargetCoors;
- CVector2D vDist;
- float fDist, fAimingDist;
+ float fAimingDist;
float TargetAlpha;
- CColPoint colPoint;
- CEntity *entity;
+ bool StandingOnMovingThing = false;
TargetCoors = CameraTarget;
+ AlphaOffset = INIT_SYPHON_ALPHA_OFFSET;
+ float GroundDist = INIT_SYPHON_GROUND_DIST;
- if(TheCamera.Cams[TheCamera.ActiveCam].Mode != MODE_SYPHON)
- return;
-
- vDist = Source - TargetCoors;
- fDist = vDist.Magnitude();
- if(fDist == 0.0f)
- Source = TargetCoors + CVector(1.0f, 1.0f, 0.0f);
- else
- Source = TargetCoors + CVector(vDist.x/fDist * 1.7f, vDist.y/fDist * 1.7f, 0.0f);
- if(fDist > 1.7f)
- fDist = 1.7f;
-
- Beta = CGeneral::GetATanOfXY(Source.x - TargetCoors.x, Source.y - TargetCoors.y);
while(Beta >= PI) Beta -= 2*PI;
while(Beta < -PI) Beta += 2*PI;
float NewBeta = CGeneral::GetATanOfXY(TheCamera.m_cvecAimingTargetCoors.x - TargetCoors.x, TheCamera.m_cvecAimingTargetCoors.y - TargetCoors.y) + PI;
if(ResetStatics){
- CameraObscured = false;
- float TestBeta1 = NewBeta - BetaOffset - Beta;
- float TestBeta2 = NewBeta + BetaOffset - Beta;
- MakeAngleLessThan180(TestBeta1);
- MakeAngleLessThan180(TestBeta2);
- if(Abs(TestBeta1) < Abs(TestBeta2))
- BetaOffset = -BetaOffset;
+ BetaOffset = INIT_SYPHON_DEGREE_OFFSET;
+ Beta = CGeneral::GetATanOfXY(Source.x - TargetCoors.x, Source.y - TargetCoors.y);
// some unuseds
ResetStatics = false;
}
+ if(NegateBetaOffset)
+ BetaOffset = -INIT_SYPHON_DEGREE_OFFSET;
Beta = NewBeta + BetaOffset;
Source = TargetCoors;
- Source.x += 1.7f*Cos(Beta);
- Source.y += 1.7f*Sin(Beta);
+ Source.x += GroundDist*Cos(Beta);
+ Source.y += GroundDist*Sin(Beta);
+ CPhysical *ground = (CPhysical*)((CPed*)CamTargetEntity)->m_pCurSurface;
+ if(ground && (ground->IsVehicle() || ground->IsObject()))
+ StandingOnMovingThing = true;
TargetCoors.z += m_fSyphonModeTargetZOffSet;
+
+ bool PlayerTooClose = false;
fAimingDist = (TheCamera.m_cvecAimingTargetCoors - TargetCoors).Magnitude2D();
- if(fAimingDist < 6.5f)
+ if(fAimingDist < 6.5f){
fAimingDist = 6.5f;
+ PlayerTooClose = true;
+ }
TargetAlpha = CGeneral::GetATanOfXY(fAimingDist, TheCamera.m_cvecAimingTargetCoors.z - TargetCoors.z);
+ if(ResetStatics) // BUG: can never happen
+ Alpha = -TargetAlpha;
while(TargetAlpha >= PI) TargetAlpha -= 2*PI;
while(TargetAlpha < -PI) TargetAlpha += 2*PI;
+ while(Alpha >= PI) Alpha -= 2*PI;
+ while(Alpha < -PI) Alpha += 2*PI;
// inlined
- WellBufferMe(-TargetAlpha, &Alpha, &AlphaSpeed, 0.07f, 0.015f, true);
+ if(StandingOnMovingThing)
+ WellBufferMe(-TargetAlpha, &Alpha, &AlphaSpeed, 0.07f/2.0f, 0.015f/2.0f, true);
+ else
+ WellBufferMe(-TargetAlpha, &Alpha, &AlphaSpeed, 0.07f, 0.015f, true);
- Source.z += fDist*Sin(Alpha) + fDist*0.2f;
+ Source.z += GroundDist*Sin(Alpha+AlphaOffset) + GroundDist*0.2f;
if(Source.z < TargetCoors.z + HeightDown)
Source.z = TargetCoors.z + HeightDown;
- CameraObscured = CWorld::ProcessLineOfSight(TargetCoors, Source, colPoint, entity, true, false, false, true, false, true, true);
- // PreviousDistForInter unused
- if(CameraObscured){
- PreviousDistForInter = (TargetCoors - colPoint.point).Magnitude2D();
- Source = colPoint.point;
- }else
- PreviousDistForInter = 1.7f;
+ if(!PlayerTooClose){
+ CColPoint point;
+ CEntity *entity = nil;
+ CWorld::pIgnoreEntity = CamTargetEntity;
+ if(CWorld::ProcessLineOfSight(TheCamera.m_cvecAimingTargetCoors, Source, point, entity, true, false, false, true, false, false, true)){
+ CVector TestFront = TheCamera.m_cvecAimingTargetCoors - Source;
+ TestFront.Normalise();
+ CVector CamToPlayer = CameraTarget - Source;
+ CVector CamToCol = point.point - Source;
+ if(DotProduct(TestFront, CamToCol) > DotProduct(TestFront, CamToPlayer)){
+ // collision is beyond player
+ float ColDist = (TheCamera.m_cvecAimingTargetCoors - point.point).Magnitude();
+ CVector PlayerToTarget = TheCamera.m_cvecAimingTargetCoors - CameraTarget;
+ float PlayerToTargetDist = PlayerToTarget.Magnitude();
+ PlayerToTarget.Normalise();
+ CVector Center = TheCamera.m_cvecAimingTargetCoors - ColDist*PlayerToTarget;
+ float Radius = (point.point - Center).Magnitude();
+ if(CWorld::TestSphereAgainstWorld(Center, Radius, nil, true, false, false, true, false, true)){
+ CVector LineToCol = gaTempSphereColPoints[0].point - Center;
+ LineToCol -= DotProduct(LineToCol, PlayerToTarget)*PlayerToTarget;
+ // unused
+ CVector LineToPrevCol = point.point - Center;
+ LineToPrevCol -= DotProduct(LineToPrevCol, PlayerToTarget)*PlayerToTarget;
+ float LineDist = LineToCol.Magnitude();
+ float NewBetaOffset = 0.0f;
+ if(LineDist > 0.0f && ColDist > 0.1f){
+ // scale offset at center to offset at player
+ float DistOffset = LineDist/ColDist * PlayerToTargetDist;
+ // turn into an angle
+ NewBetaOffset = 0.9f*Asin(Min(DistOffset/GroundDist, 1.0f));
+ }
+ if(NewBetaOffset < BetaOffset){
+ float Ratio = NewBetaOffset / BetaOffset;
+ BetaOffset = NewBetaOffset;
+ Beta = NewBeta + NewBetaOffset;
+ GroundDist *= Max(Ratio, 0.5f);
+ Source.x = TargetCoors.x + GroundDist*Cos(Beta);
+ Source.y = TargetCoors.y + GroundDist*Sin(Beta);
+ Source.z += (1.0f-Ratio)*0.5f;
+ }
+ }
+ }
+ }
+ CWorld::pIgnoreEntity = nil;
+ }
- m_cvecTargetCoorsForFudgeInter = TargetCoors;
- Front = TargetCoors - Source;
- m_fMinDistAwayFromCamWhenInterPolating = Front.Magnitude2D();
- if(m_fMinDistAwayFromCamWhenInterPolating < 1.1f)
- RwCameraSetNearClipPlane(Scene.camera, Max(m_fMinDistAwayFromCamWhenInterPolating - 0.35f, 0.05f));
+ Front = TheCamera.m_cvecAimingTargetCoors - Source;
+ float TargetDistGround = Front.Magnitude2D();
Front.Normalise();
+ m_cvecTargetCoorsForFudgeInter = Source + TargetDistGround*Front;
+ m_cvecTargetCoorsForFudgeInter.z = TargetCoors.z;
+
+ CVector OrigSource = Source;
+ TheCamera.AvoidTheGeometry(OrigSource, CameraTarget + CVector(0.0f, 0.0f, 0.75f), Source, FOV);
+ Source.z = OrigSource.z;
+
GetVectorsReadyForRW();
}
@@ -3182,8 +3156,6 @@ CCam::Process_Syphon_Crim_In_Front(const CVector &CameraTarget, float, float, fl
float fDist, TargetDist;
float zOffset;
float AimingAngle;
- CColPoint colPoint;
- CEntity *entity;
TargetDist = TheCamera.m_fPedZoomValueSmooth * 0.5f + 4.0f;
vDist = Source - TargetCoors;
@@ -3214,22 +3186,24 @@ CCam::Process_Syphon_Crim_In_Front(const CVector &CameraTarget, float, float, fl
Source.x += Cos(Beta) * TargetDist;
Source.y += Sin(Beta) * TargetDist;
- if(CWorld::ProcessLineOfSight(TargetCoors, Source, colPoint, entity, true, false, false, true, false, true, true)){
- Beta = CGeneral::GetATanOfXY(Source.x - TargetCoors.x, Source.y - TargetCoors.y);
- fDist = (TargetCoors - colPoint.point).Magnitude2D();
- Source.x = TargetCoors.x;
- Source.y = TargetCoors.y;
- Source.x += Cos(Beta) * fDist;
- Source.y += Sin(Beta) * fDist;
- }
-
TargetCoors = CameraTarget;
TargetCoors.z += m_fSyphonModeTargetZOffSet;
m_cvecTargetCoorsForFudgeInter = TargetCoors;
+
+ CVector OrigSource = Source;
+ TheCamera.AvoidTheGeometry(OrigSource, TargetCoors, Source, FOV);
+
Front = TargetCoors - Source;
GetVectorsReadyForRW();
}
+float MAX_HEIGHT_UP = 15.0f;
+float WATER_Z_ADDITION = 2.75f;
+float WATER_Z_ADDITION_MIN = 1.5f;
+float SMALLBOAT_CLOSE_ALPHA_MINUS = 0.2f;
+float afBoatBetaDiffMult[3] = { 0.15f, 0.07f, 0.01f };
+float afBoatBetaSpeedDiffMult[3] = { 0.02f, 0.015f, 0.005f };
+
void
CCam::Process_BehindBoat(const CVector &CameraTarget, float TargetOrientation, float, float)
{
@@ -3240,118 +3214,135 @@ CCam::Process_BehindBoat(const CVector &CameraTarget, float TargetOrientation, f
CVector TargetCoors = CameraTarget;
float DeltaBeta = 0.0f;
- static CColPoint colPoint;
- CEntity *entity;
static float TargetWhenChecksWereOn = 0.0f;
static float CenterObscuredWhenChecksWereOn = 0.0f;
static float WaterZAddition = 2.75f;
float WaterLevel = 0.0f;
- float s, c;
+ float MaxHeightUp = MAX_HEIGHT_UP;
+ static float WaterLevelBuffered = 0.0f;
+ static float WaterLevelSpeed = 0.0f;
+ float BetaDiffMult = 0.0f;
+ float BetaSpeedDiffMult = 0.0f;
Beta = CGeneral::GetATanOfXY(TargetCoors.x - Source.x, TargetCoors.y - Source.y);
FOV = DefaultFOV;
+ float TargetAlpha = 0.0f;
if(ResetStatics){
CenterObscuredWhenChecksWereOn = 0.0f;
TargetWhenChecksWereOn = 0.0f;
- Beta = TargetOrientation + PI;
+ }else if(DirectionWasLooking != LOOKING_FORWARD)
+ Beta = TargetOrientation;
+
+ if(!CWaterLevel::GetWaterLevelNoWaves(TargetCoors.x, TargetCoors.y, TargetCoors.z, &WaterLevel))
+ WaterLevel = TargetCoors.z - 0.5f;
+ if(ResetStatics){
+ WaterLevelBuffered = WaterLevel;
+ WaterLevelSpeed = 0.0f;
}
+ WellBufferMe(WaterLevel, &WaterLevelBuffered, &WaterLevelSpeed, 0.2f, 0.07f, false);
- CWaterLevel::GetWaterLevelNoWaves(TargetCoors.x, TargetCoors.y, TargetCoors.z, &WaterLevel);
- WaterLevel += WaterZAddition;
static float FixerForGoingBelowGround = 0.4f;
- if(-FixerForGoingBelowGround < TargetCoors.z-WaterLevel)
- WaterLevel += TargetCoors.z-WaterLevel - FixerForGoingBelowGround;
-
- bool Obscured;
- if(m_bCollisionChecksOn || ResetStatics){
- CVector TestPoint;
- // Weird calculations here, also casting bool to float...
- c = Cos(TargetOrientation);
- s = Sin(TargetOrientation);
- TestPoint = TheCamera.CarZoomValueSmooth * CVector(-c, -s, 0.0f) +
- (TheCamera.CarZoomValueSmooth+7.0f) * CVector(-c, -s, 0.0f) +
- TargetCoors;
- TestPoint.z = WaterLevel + TheCamera.CarZoomValueSmooth;
- float Test1 = CWorld::GetIsLineOfSightClear(TestPoint, TargetCoors, true, false, false, true, false, true, true);
-
- c = Cos(TargetOrientation + 0.8f);
- s = Sin(TargetOrientation + DEGTORAD(40.0f));
- TestPoint = TheCamera.CarZoomValueSmooth * CVector(-c, -s, 0.0f) +
- (TheCamera.CarZoomValueSmooth+7.0f) * CVector(-c, -s, 0.0f) +
- TargetCoors;
- TestPoint.z = WaterLevel + TheCamera.CarZoomValueSmooth;
- float Test2 = CWorld::GetIsLineOfSightClear(TestPoint, TargetCoors, true, false, false, true, false, true, true);
-
- c = Cos(TargetOrientation - 0.8);
- s = Sin(TargetOrientation - DEGTORAD(40.0f));
- TestPoint = TheCamera.CarZoomValueSmooth * CVector(-c, -s, 0.0f) +
- (TheCamera.CarZoomValueSmooth+7.0f) * CVector(-c, -s, 0.0f) +
- TargetCoors;
- TestPoint.z = WaterLevel + TheCamera.CarZoomValueSmooth;
- float Test3 = CWorld::GetIsLineOfSightClear(TestPoint, TargetCoors, true, false, false, true, false, true, true);
-
- if(Test2 == 0.0f){
- DeltaBeta = TargetOrientation - Beta - DEGTORAD(40.0f);
- if(ResetStatics)
- Beta = TargetOrientation - DEGTORAD(40.0f);
- }else if(Test3 == 0.0f){
- DeltaBeta = TargetOrientation - Beta + DEGTORAD(40.0f);
- if(ResetStatics)
- Beta = TargetOrientation + DEGTORAD(40.0f);
- }else if(Test1 == 0.0f){
- DeltaBeta = 0.0f;
- }else if(Test2 != 0.0f && Test3 != 0.0f && Test1 != 0.0f){
- if(ResetStatics)
- Beta = TargetOrientation;
- DeltaBeta = TargetOrientation - Beta;
- }
-
- c = Cos(Beta);
- s = Sin(Beta);
- TestPoint.x = TheCamera.CarZoomValueSmooth * -c +
- (TheCamera.CarZoomValueSmooth + 7.0f) * -c +
- TargetCoors.x;
- TestPoint.y = TheCamera.CarZoomValueSmooth * -s +
- (TheCamera.CarZoomValueSmooth + 7.0f) * -s +
- TargetCoors.y;
- TestPoint.z = WaterLevel + TheCamera.CarZoomValueSmooth;
- Obscured = CWorld::ProcessLineOfSight(TestPoint, TargetCoors, colPoint, entity, true, false, false, true, false, true, true);
- CenterObscuredWhenChecksWereOn = Obscured;
-
- // now DeltaBeta == TargetWhenChecksWereOn - Beta, which we need for WellBufferMe below
- TargetWhenChecksWereOn = DeltaBeta + Beta;
- }else{
- // DeltaBeta = TargetWhenChecksWereOn - Beta; // unneeded since we don't inline WellBufferMe
- Obscured = CenterObscuredWhenChecksWereOn != 0.0f;
+ if(-FixerForGoingBelowGround < TargetCoors.z-WaterLevelBuffered+WATER_Z_ADDITION)
+ WaterLevelBuffered += TargetCoors.z-WaterLevelBuffered+WATER_Z_ADDITION - FixerForGoingBelowGround;
+
+ CVector BoatDimensions = CamTargetEntity->GetColModel()->boundingBox.GetSize();
+ float BoatSize = BoatDimensions.Magnitude2D();
+ int index = 0;
+ TheCamera.GetArrPosForVehicleType(((CVehicle*)CamTargetEntity)->GetVehicleAppearance(), index);
+ if(TheCamera.CarZoomIndicator == CAM_ZOOM_1){
+ TargetAlpha = ZmOneAlphaOffset[index];
+ BetaDiffMult = afBoatBetaDiffMult[0];
+ BetaSpeedDiffMult = afBoatBetaSpeedDiffMult[0];
+ }else if(TheCamera.CarZoomIndicator == CAM_ZOOM_2){
+ TargetAlpha = ZmTwoAlphaOffset[index];
+ BetaDiffMult = afBoatBetaDiffMult[1];
+ BetaSpeedDiffMult = afBoatBetaSpeedDiffMult[1];
+ }else if(TheCamera.CarZoomIndicator == CAM_ZOOM_3){
+ TargetAlpha = ZmThreeAlphaOffset[index];
+ BetaDiffMult = afBoatBetaDiffMult[2];
+ BetaSpeedDiffMult = afBoatBetaSpeedDiffMult[2];
+ }
+ if(TheCamera.CarZoomIndicator == CAM_ZOOM_1 && BoatSize < 10.0f){
+ TargetAlpha -= SMALLBOAT_CLOSE_ALPHA_MINUS;
+ BoatSize = 10.0f;
+ }else if(CCullZones::Cam1stPersonForPlayer()){
+ float Water = 0.0f;
+ // useless call
+ //CWaterLevel::GetWaterLevelNoWaves(TargetCoors.x, TargetCoors.y, TargetCoors.z, &Water);
+ Water = (WaterLevel + WATER_Z_ADDITION_MIN - WaterLevelBuffered - WATER_Z_ADDITION)/(BoatDimensions.z/2.0f + MaxHeightUp);
+ TargetAlpha = Asin(Clamp(Water, -1.0f, 1.0f));
}
- if(Obscured){
- CWorld::ProcessLineOfSight(Source, TargetCoors, colPoint, entity, true, false, false, true, false, true, true);
- Source = colPoint.point;
- }else{
- // inlined
- WellBufferMe(TargetWhenChecksWereOn, &Beta, &BetaSpeed, 0.07f, 0.015f, true);
-
- s = Sin(Beta);
- c = Cos(Beta);
- Source = TheCamera.CarZoomValueSmooth * CVector(-c, -s, 0.0f) +
- (TheCamera.CarZoomValueSmooth+7.0f) * CVector(-c, -s, 0.0f) +
- TargetCoors;
- Source.z = WaterLevel + TheCamera.CarZoomValueSmooth;
+ if(ResetStatics){
+ Alpha = TargetAlpha;
+ AlphaSpeed = 0.0f;
}
+ WellBufferMe(TargetAlpha, &Alpha, &AlphaSpeed, 0.15f, 0.07f, true);
- if(TheCamera.CarZoomValueSmooth < 0.05f){
- static float AmountUp = 2.2f;
- TargetCoors.z += AmountUp * (0.0f - TheCamera.CarZoomValueSmooth);
+ if(ResetStatics){
+ Beta = TargetOrientation;
+ DeltaBeta = 0.0f;
}
- TargetCoors.z += TheCamera.CarZoomValueSmooth + 0.5f;
+ // inlined
+ WellBufferMe(TargetOrientation, &Beta, &BetaSpeed, BetaDiffMult * ((CVehicle*)CamTargetEntity)->m_vecMoveSpeed.Magnitude(), BetaSpeedDiffMult, true);
+
+ Source = (TheCamera.CarZoomValueSmooth+BoatSize) * CVector(-Cos(Beta), -Sin(Beta), 0.0f) + TargetCoors;
+ Source.z = WaterLevelBuffered + WATER_Z_ADDITION + (BoatDimensions.z/2.0f + MaxHeightUp) * Sin(Alpha);
+
m_cvecTargetCoorsForFudgeInter = TargetCoors;
+ CVector OrigSource = Source;
+ TheCamera.AvoidTheGeometry(OrigSource, TargetCoors, Source, FOV);
Front = TargetCoors - Source;
- GetVectorsReadyForRW();
+ Front.Normalise();
+
+
+ float TargetRoll;
+ if(CPad::GetPad(0)->GetDPadLeft() || CPad::GetPad(0)->GetDPadRight()){
+#ifdef FIX_BUGS
+ float fwdSpeed = 180.0f*DotProduct(((CVehicle*)CamTargetEntity)->m_vecMoveSpeed, CamTargetEntity->GetForward());
+ if(fwdSpeed > 210.0f) fwdSpeed = 210.0f;
+#endif
+ if(CPad::GetPad(0)->GetDPadLeft())
+ TargetRoll = DEGTORAD(10.0f)*TiltOverShoot[index] + f_max_role_angle;
+ else
+ TargetRoll = -(DEGTORAD(10.0f)*TiltOverShoot[index] + f_max_role_angle);
+ CVector FwdTarget = CamTargetEntity->GetForward();
+ FwdTarget.Normalise();
+ float AngleDiff = DotProduct(FwdTarget, Front);
+ AngleDiff = Acos(Min(Abs(AngleDiff), 1.0f));
+#ifdef FIX_BUGS
+ TargetRoll *= fwdSpeed/210.0f * Sin(AngleDiff);
+#else
+ TargetRoll *= Sin(AngleDiff);
+#endif
+ }else{
+ float fwdSpeed = 180.0f*DotProduct(((CVehicle*)CamTargetEntity)->m_vecMoveSpeed, CamTargetEntity->GetForward());
+ if(fwdSpeed > 210.0f) fwdSpeed = 210.0f;
+ TargetRoll = CPad::GetPad(0)->GetLeftStickX()/128.0f * fwdSpeed/210.0f;
+ CVector FwdTarget = CamTargetEntity->GetForward();
+ FwdTarget.Normalise();
+ float AngleDiff = DotProduct(FwdTarget, Front);
+ AngleDiff = Acos(Min(Abs(AngleDiff), 1.0f));
+ TargetRoll *= (DEGTORAD(10.0f)*TiltOverShoot[index] + f_max_role_angle) * Sin(AngleDiff);
+ }
+
+ WellBufferMe(TargetRoll, &f_Roll, &f_rollSpeed, 0.15f, 0.07f, false);
+ Up = CVector(Cos(f_Roll + HALFPI), 0.0f, Sin(f_Roll + HALFPI));
+ Up.Normalise();
+ Front.Normalise();
+ CVector Left = CrossProduct(Up, Front);
+ Left.Normalise();
+ Up = CrossProduct(Front, Left);
+ Up.Normalise();
+
ResetStatics = false;
}
+float FIGHT_HORIZ_DIST = 3.0f;
+float FIGHT_VERT_DIST = 1.0f;
+float FIGHT_BETA_ANGLE = 125.0f;
+
void
CCam::Process_Fight_Cam(const CVector &CameraTarget, float TargetOrientation, float, float)
{
@@ -3359,26 +3350,25 @@ CCam::Process_Fight_Cam(const CVector &CameraTarget, float TargetOrientation, fl
return;
FOV = DefaultFOV;
+ float HorizDist = FIGHT_HORIZ_DIST;
+ float VertDist = FIGHT_VERT_DIST;
float BetaLeft, BetaRight, DeltaBetaLeft, DeltaBetaRight;
- float BetaFix;
- float Dist;
- float BetaMaxSpeed = 0.015f;
- float BetaAcceleration = 0.007f;
static bool PreviouslyFailedBuildingChecks = false;
float TargetCamHeight;
CVector TargetCoors;
- m_fMinDistAwayFromCamWhenInterPolating = 4.0f;
+ m_fMinDistAwayFromCamWhenInterPolating = FIGHT_HORIZ_DIST;
Front = Source - CameraTarget;
- Beta = CGeneral::GetATanOfXY(Front.x, Front.y);
+ if(ResetStatics)
+ Beta = CGeneral::GetATanOfXY(Front.x, Front.y);
while(TargetOrientation >= PI) TargetOrientation -= 2*PI;
while(TargetOrientation < -PI) TargetOrientation += 2*PI;
while(Beta >= PI) Beta -= 2*PI;
while(Beta < -PI) Beta += 2*PI;
// Figure out Beta
- BetaLeft = TargetOrientation - HALFPI;
- BetaRight = TargetOrientation + HALFPI;
+ BetaLeft = TargetOrientation - DEGTORAD(FIGHT_BETA_ANGLE);
+ BetaRight = TargetOrientation + DEGTORAD(FIGHT_BETA_ANGLE);
DeltaBetaLeft = Beta - BetaLeft;
DeltaBetaRight = Beta - BetaRight;
while(DeltaBetaLeft >= PI) DeltaBetaLeft -= 2*PI;
@@ -3402,32 +3392,15 @@ CCam::Process_Fight_Cam(const CVector &CameraTarget, float TargetOrientation, fl
m_fTargetBeta = DeltaBetaRight;
}
- // Check collisions
- BetaFix = 0.0f;
- Dist = Front.Magnitude2D();
- if(m_bCollisionChecksOn || PreviouslyFailedBuildingChecks){
- BetaFix = GetPedBetaAngleForClearView(CameraTarget, Dist+0.25f, 0.0f, true, false, false, true, false);
- if(BetaFix == 0.0f){
- BetaFix = GetPedBetaAngleForClearView(CameraTarget, Dist+0.5f, DEGTORAD(24.0f), true, false, false, true, false);
- if(BetaFix == 0.0f)
- BetaFix = GetPedBetaAngleForClearView(CameraTarget, Dist+0.5f, -DEGTORAD(24.0f), true, false, false, true, false);
- }
- }
- if(BetaFix != 0.0f){
- BetaMaxSpeed = 0.1f;
- PreviouslyFailedBuildingChecks = true;
- BetaAcceleration = 0.025f;
- m_fTargetBeta = Beta + BetaFix;
- }
- WellBufferMe(m_fTargetBeta, &Beta, &BetaSpeed, BetaMaxSpeed, BetaAcceleration, true);
+ WellBufferMe(m_fTargetBeta, &Beta, &BetaSpeed, 0.015f, 0.007f, true);
- Source = CameraTarget + 4.0f*CVector(Cos(Beta), Sin(Beta), 0.0f);
- Source.z -= 0.5f;
+ Source = CameraTarget + HorizDist*CVector(Cos(Beta), Sin(Beta), 0.0f);
+ Source.z += VertDist;
WellBufferMe(TargetOrientation, &m_fBufferedTargetOrientation, &m_fBufferedTargetOrientationSpeed, 0.07f, 0.004f, true);
- TargetCoors = CameraTarget + 0.5f*CVector(Cos(m_fBufferedTargetOrientation), Sin(m_fBufferedTargetOrientation), 0.0f);
+ TargetCoors = CameraTarget + 0.1f*CVector(Cos(m_fBufferedTargetOrientation), Sin(m_fBufferedTargetOrientation), 0.0f);
- TargetCamHeight = CameraTarget.z - Source.z + Max(m_fPedBetweenCameraHeightOffset, m_fRoadOffSet + m_fDimensionOfHighestNearCar) - 0.5f;
+ TargetCamHeight = CameraTarget.z - Source.z + Max(m_fPedBetweenCameraHeightOffset, m_fDimensionOfHighestNearCar) + VertDist;
if(TargetCamHeight > m_fCamBufferedHeight)
WellBufferMe(TargetCamHeight, &m_fCamBufferedHeight, &m_fCamBufferedHeightSpeed, 0.15f, 0.04f, false);
else
@@ -3435,6 +3408,8 @@ CCam::Process_Fight_Cam(const CVector &CameraTarget, float TargetOrientation, fl
Source.z += m_fCamBufferedHeight;
m_cvecTargetCoorsForFudgeInter = TargetCoors;
+ CVector OrigSource = Source;
+ TheCamera.AvoidTheGeometry(OrigSource, TargetCoors, Source, FOV);
Front = TargetCoors - Source;
Front.Normalise();
GetVectorsReadyForRW();
@@ -3553,6 +3528,11 @@ CCam::Process_FlyBy(const CVector&, float, float, float)
if(TheCamera.m_bcutsceneFinished)
return;
+#ifdef FIX_BUGS
+ // this would crash, not nice when cycling debug mode
+ if(TheCamera.m_arrPathArray[0].m_arr_PathData == nil)
+ return;
+#endif
Up = CVector(0.0f, 0.0f, 1.0f);
if(TheCamera.m_bStartingSpline)
@@ -3631,37 +3611,105 @@ CCam::Process_FlyBy(const CVector&, float, float, float)
FOV = PsuedoFOV;
}
-void
+CVector vecWheelCamBoatOffset(-0.5f, -0.8f, 0.3f);
+CVector vecWheelCamBoatOffsetAlt(0.2f, -0.2f, -0.3f);
+float fWheelCamCarXOffset = 0.33f;
+float fWheelCamBikeXOffset = 0.2f;
+
+bool
CCam::Process_WheelCam(const CVector&, float, float, float)
{
FOV = DefaultFOV;
+ CVector WheelPos;
if(CamTargetEntity->IsPed()){
// what? ped with wheels or what?
Source = Multiply3x3(CamTargetEntity->GetMatrix(), CVector(-0.3f, -0.5f, 0.1f));
Source += CamTargetEntity->GetPosition();
Front = CVector(1.0f, 0.0f, 0.0f);
}else{
- Source = Multiply3x3(CamTargetEntity->GetMatrix(), CVector(-1.4f, -2.3f, 0.3f));
- Source += CamTargetEntity->GetPosition();
+ WheelPos = CamTargetEntity->GetColModel()->boundingBox.min;
+ WheelPos.x -= 0.33f;
+ WheelPos.y = -2.3f;
+ WheelPos.z = 0.3f;
+ Source = CamTargetEntity->GetMatrix() * WheelPos;
Front = CamTargetEntity->GetForward();
}
- CVector NewUp(0.0f, 0.0f, 1.0f);
- CVector Right = CrossProduct(Front, NewUp);
- Right.Normalise();
- NewUp = CrossProduct(Right, Front);
- NewUp.Normalise();
+ CVector NewUp, Right;
+ if(CamTargetEntity->IsVehicle() &&
+ (((CVehicle*)CamTargetEntity)->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI ||
+ ((CVehicle*)CamTargetEntity)->GetVehicleAppearance() == VEHICLE_APPEARANCE_PLANE)){
+ WheelPos.x = -1.55f;
+ Right = CamTargetEntity->GetRight();
+ NewUp = CamTargetEntity->GetUp();
+ Source = CamTargetEntity->GetMatrix() * WheelPos;
+ }else if(CamTargetEntity->IsVehicle() && ((CVehicle*)CamTargetEntity)->IsBoat()){
+ NewUp = CVector(0.0f, 0.0f, 1.0f);
+ Right = CrossProduct(Front, NewUp);
+ Right.Normalise();
+ NewUp = CrossProduct(Right, Front);
+ NewUp.Normalise();
+
+ CVector BoatCamPos(0.0f, 0.0f, 0.0f);
+ if(((CVehicle*)CamTargetEntity)->pDriver){
+ ((CVehicle*)CamTargetEntity)->pDriver->m_pedIK.GetComponentPosition(BoatCamPos, PED_HEAD);
+ BoatCamPos += ((CVehicle*)CamTargetEntity)->m_vecMoveSpeed * CTimer::GetTimeStep();
+ BoatCamPos += vecWheelCamBoatOffset.x * Right;
+ BoatCamPos += vecWheelCamBoatOffset.y * CamTargetEntity->GetForward();
+ BoatCamPos.z += vecWheelCamBoatOffset.z;
+ if(CamTargetEntity->GetModelIndex() == MI_PREDATOR){
+ BoatCamPos += vecWheelCamBoatOffsetAlt.x * Right;
+ BoatCamPos += vecWheelCamBoatOffsetAlt.y * CamTargetEntity->GetForward();
+ BoatCamPos.z += vecWheelCamBoatOffsetAlt.z;
+ }
+ Source = BoatCamPos;
+ }else
+ Source.z += 2.0f*vecWheelCamBoatOffset.z;
+ }else if(CamTargetEntity->IsVehicle() && ((CVehicle*)CamTargetEntity)->IsBike()){
+ NewUp = CVector(0.0f, 0.0f, 1.0f);
+ Right = CrossProduct(Front, NewUp);
+ Right.Normalise();
+ NewUp = CrossProduct(Right, Front);
+ NewUp.Normalise();
+
+ WheelPos.z += fWheelCamCarXOffset - fWheelCamBikeXOffset;
+ Source = CamTargetEntity->GetPosition();
+ Source += WheelPos.x * CamTargetEntity->GetRight();
+ Source += WheelPos.y * Front;
+ Source += WheelPos.z * Up;
+ }else{
+ NewUp = CVector(0.0f, 0.0f, 1.0f);
+ Right = CrossProduct(Front, NewUp);
+ Right.Normalise();
+ NewUp = CrossProduct(Right, Front);
+ NewUp.Normalise();
+ }
float Roll = Cos((CTimer::GetTimeInMilliseconds()&0x1FFFF)/(float)0x1FFFF * TWOPI);
Up = Cos(Roll*0.4f)*NewUp + Sin(Roll*0.4f)*Right;
+
+ CEntity *entity = nil;
+ CColPoint point;
+ CWorld::pIgnoreEntity = CamTargetEntity;
+ bool blocked = CWorld::ProcessLineOfSight(Source, CamTargetEntity->GetPosition(), point, entity, true, false, false, true, false, false, true);
+ CWorld::pIgnoreEntity = nil;
+ return !blocked;
}
+int BOAT_UNDERWATER_CAM_BLUR = 20;
+float BOAT_UNDERWATER_CAM_COLORMAG_LIMIT = 10.0f;
+
+//--MIAIM: done
void
CCam::Process_Fixed(const CVector &CameraTarget, float, float, float)
{
+ if(DirectionWasLooking != LOOKING_FORWARD)
+ DirectionWasLooking = LOOKING_FORWARD;
+
Source = m_cvecCamFixedModeSource;
Front = CameraTarget - Source;
+ Front.Normalise();
m_cvecTargetCoorsForFudgeInter = CameraTarget;
GetVectorsReadyForRW();
@@ -3675,8 +3723,23 @@ CCam::Process_Fixed(const CVector &CameraTarget, float, float, float)
if(TheCamera.m_bUseSpecialFovTrain)
FOV = TheCamera.m_fFovForTrain;
+ float WaterZ = 0.0f;
+ if(CWaterLevel::GetWaterLevel(Source, &WaterZ, true) && Source.z < WaterZ){
+ float WaterLum = Sqrt(SQR(CTimeCycle::GetWaterRed()) + SQR(CTimeCycle::GetWaterGreen()) + SQR(CTimeCycle::GetWaterBlue()));
+ if(WaterLum > BOAT_UNDERWATER_CAM_COLORMAG_LIMIT){
+ float f = BOAT_UNDERWATER_CAM_COLORMAG_LIMIT/WaterLum;
+ TheCamera.SetMotionBlur(CTimeCycle::GetWaterRed()*f,
+ CTimeCycle::GetWaterGreen()*f,
+ CTimeCycle::GetWaterBlue()*f, BOAT_UNDERWATER_CAM_BLUR, MOTION_BLUR_LIGHT_SCENE);
+ }else{
+ TheCamera.SetMotionBlur(CTimeCycle::GetWaterRed(),
+ CTimeCycle::GetWaterGreen(),
+ CTimeCycle::GetWaterBlue(), BOAT_UNDERWATER_CAM_BLUR, MOTION_BLUR_LIGHT_SCENE);
+ }
+ }
+
#ifdef PC_PLAYER_CONTROLS
- if(CMenuManager::m_ControlMethod == CONTROL_STANDARD && Using3rdPersonMouseCam()){
+ if(FrontEndMenuManager.m_ControlMethod == CONTROL_STANDARD && Using3rdPersonMouseCam()){
CPed *player = FindPlayerPed();
if(player && player->CanStrafeOrMouseControl()){
float Heading = Front.Heading();
@@ -3690,16 +3753,81 @@ CCam::Process_Fixed(const CVector &CameraTarget, float, float, float)
}
void
+CCam::Process_LightHouse(const CVector &CameraTarget, float, float, float)
+{
+ static float Timer;
+
+ Source = CameraTarget;
+ Source.x = 474.3f;
+ Source.y = -1717.6f;
+
+ int CamMode;
+ if(CameraTarget.z > 57.0f && (CameraTarget-Source).Magnitude2D() > 3.2f){
+ // Outside at top
+ if(Timer > 0.0f){
+ Timer -= CTimer::GetTimeStep();
+ CamMode = 1;
+ }else{
+ Timer = -24.0f;
+ CamMode = 2;
+ }
+ }else if(CameraTarget.z > 57.0f){
+ // Inside at top
+ if(Timer < 0.0f){
+ Timer += CTimer::GetTimeStep();
+ CamMode = 2;
+ }else{
+ Timer = 24.0f;
+ CamMode = 1;
+ }
+ }else{
+ Timer = 0.0f;
+ CamMode = 0;
+ }
+
+ if(CamMode == 2){
+ Source.z = 57.5f;
+ Front = Source - CameraTarget;
+ Front.Normalise();
+ Source.x = CameraTarget.x - 5.0f*Front.x;
+ Source.y = CameraTarget.y - 5.0f*Front.y;
+ }else if(CamMode == 1){
+ Front = CameraTarget - Source;
+ Front.Normalise();
+ Source.x = CameraTarget.x - 2.0f*Front.x;
+ Source.y = CameraTarget.y - 2.0f*Front.y;
+ }else{
+ Source.z += 4.0f;
+ Front = CameraTarget - Source;
+ Front.Normalise();
+ Source -= 4.0f*Front;
+ Source.z = Min(Source.z, 55.0f);
+ Front = CameraTarget - Source;
+ }
+
+ m_cvecTargetCoorsForFudgeInter = CameraTarget;
+ GetVectorsReadyForRW();
+
+ Up = CVector(0.0f, 0.0f, 1.0f) + m_cvecCamFixedModeUpOffSet;
+ Up.Normalise();
+ CVector Right = CrossProduct(Front, Up);
+ Right.Normalise();
+ Up = CrossProduct(Right, Front);
+
+ FOV = DefaultFOV;
+ if(TheCamera.m_bUseSpecialFovTrain) // uh, sure...
+ FOV = TheCamera.m_fFovForTrain;
+}
+
+void
CCam::Process_Player_Fallen_Water(const CVector &CameraTarget, float TargetOrientation, float, float)
{
CColPoint colPoint;
CEntity *entity = nil;
FOV = DefaultFOV;
- Source = CameraTarget;
- Source.x += -4.5f*Cos(TargetOrientation);
- Source.y += -4.5f*Sin(TargetOrientation);
- Source.z = m_vecLastAboveWaterCamPosition.z + 4.0f;
+ Source = m_vecLastAboveWaterCamPosition;
+ Source.z += 4.0f;
m_cvecTargetCoorsForFudgeInter = CameraTarget;
Front = CameraTarget - Source;
@@ -3711,20 +3839,6 @@ CCam::Process_Player_Fallen_Water(const CVector &CameraTarget, float TargetOrien
Front.Normalise();
}
-// unused
-void
-CCam::Process_Circle(const CVector &CameraTarget, float, float, float)
-{
- FOV = DefaultFOV;
-
- Front.x = Cos(0.7f) * Cos((CTimer::GetTimeInMilliseconds()&0xFFF)/(float)0xFFF * TWOPI);
- Front.y = Cos(0.7f) * Sin((CTimer::GetTimeInMilliseconds()&0xFFF)/(float)0xFFF * TWOPI);
- Front.z = -Sin(0.7f);
- Source = CameraTarget - 4.0f*Front;
- Source.z += 1.0f;
- GetVectorsReadyForRW();
-}
-
void
CCam::Process_SpecialFixedForSyphon(const CVector &CameraTarget, float, float, float)
{
@@ -3732,6 +3846,8 @@ CCam::Process_SpecialFixedForSyphon(const CVector &CameraTarget, float, float, f
m_cvecTargetCoorsForFudgeInter = CameraTarget;
m_cvecTargetCoorsForFudgeInter.z += m_fSyphonModeTargetZOffSet;
Front = CameraTarget - Source;
+ CVector OrigSource = Source;
+ TheCamera.AvoidTheGeometry(OrigSource, m_cvecTargetCoorsForFudgeInter, Source, FOV);
Front.z += m_fSyphonModeTargetZOffSet;
GetVectorsReadyForRW();
@@ -3848,7 +3964,7 @@ CCam::Process_Debug(const CVector&, float, float, float)
if(CPad::GetPad(1)->GetLeftShockJustDown() && gbBigWhiteDebugLightSwitchedOn)
CShadows::StoreShadowToBeRendered(SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &Source,
12.0f, 0.0f, 0.0f, -12.0f,
- 128, 128, 128, 128, 1000.0f, false, 1.0f);
+ 128, 128, 128, 128, 1000.0f, false, 1.0f, nil, false);
if(CHud::m_Wants_To_Draw_Hud){
char str[256];
@@ -3913,7 +4029,7 @@ CCam::Process_Debug(const CVector&, float, float, float)
if(CPad::GetPad(1)->GetLeftShockJustDown() && gbBigWhiteDebugLightSwitchedOn)
CShadows::StoreShadowToBeRendered(SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &Source,
12.0f, 0.0f, 0.0f, -12.0f,
- 128, 128, 128, 128, 1000.0f, false, 1.0f);
+ 128, 128, 128, 128, 1000.0f, false, 1.0f, nil, 1.0f);
if(CHud::m_Wants_To_Draw_Hud){
char str[256];
@@ -3994,7 +4110,7 @@ CCam::Process_Editor(const CVector&, float, float, float)
if(CPad::GetPad(1)->GetLeftShockJustDown() && gbBigWhiteDebugLightSwitchedOn)
CShadows::StoreShadowToBeRendered(SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &Source,
12.0f, 0.0f, 0.0f, -12.0f,
- 128, 128, 128, 128, 1000.0f, false, 1.0f);
+ 128, 128, 128, 128, 1000.0f, false, 1.0f, nil, false);
if(CHud::m_Wants_To_Draw_Hud){
char str[256];
@@ -4034,109 +4150,374 @@ CCam::Process_ModelView(const CVector &CameraTarget, float, float, float)
GetVectorsReadyForRW();
}
+float DEADCAM_HEIGHT_START = 2.0f;
+float DEADCAM_HEIGHT_RATE = 0.04f;
+float DEADCAM_WAFT_AMPLITUDE = 2.0f;
+float DEADCAM_WAFT_RATE = 600.0f;
+float DEADCAM_WAFT_TILT_AMP = -0.35f;
+
void
CCam::ProcessPedsDeadBaby(void)
{
- float Distance = 0.0f;
- static bool SafeToRotate = false;
- CVector TargetDist, TestPoint;
+ CVector TargetCoors;
+ CVector CamPos;
- FOV = DefaultFOV;
- TargetDist = Source - CamTargetEntity->GetPosition();
- Distance = TargetDist.Magnitude();
- Beta = CGeneral::GetATanOfXY(TargetDist.x, TargetDist.y);
- while(Beta >= PI) Beta -= 2*PI;
- while(Beta < -PI) Beta += 2*PI;
+ if(TheCamera.pTargetEntity->IsPed())
+ ((CPed*)TheCamera.pTargetEntity)->m_pedIK.GetComponentPosition(TargetCoors, PED_MID);
+ else if(TheCamera.pTargetEntity->IsVehicle()){
+ TargetCoors = TheCamera.pTargetEntity->GetPosition();
+ TargetCoors.z += TheCamera.pTargetEntity->GetColModel()->boundingBox.max.z;
+ }else
+ return;
if(ResetStatics){
- TestPoint = CamTargetEntity->GetPosition() +
- CVector(4.0f * Cos(Alpha) * Cos(Beta),
- 4.0f * Cos(Alpha) * Sin(Beta),
- 4.0f * Sin(Alpha));
- bool Safe1 = CWorld::GetIsLineOfSightClear(TestPoint, CamTargetEntity->GetPosition(), true, false, false, true, false, true, true);
-
- TestPoint = CamTargetEntity->GetPosition() +
- CVector(4.0f * Cos(Alpha) * Cos(Beta + DEGTORAD(120.0f)),
- 4.0f * Cos(Alpha) * Sin(Beta + DEGTORAD(120.0f)),
- 4.0f * Sin(Alpha));
- bool Safe2 = CWorld::GetIsLineOfSightClear(TestPoint, CamTargetEntity->GetPosition(), true, false, false, true, false, true, true);
-
- TestPoint = CamTargetEntity->GetPosition() +
- CVector(4.0f * Cos(Alpha) * Cos(Beta - DEGTORAD(120.0f)),
- 4.0f * Cos(Alpha) * Sin(Beta - DEGTORAD(120.0f)),
- 4.0f * Sin(Alpha));
- bool Safe3 = CWorld::GetIsLineOfSightClear(TestPoint, CamTargetEntity->GetPosition(), true, false, false, true, false, true, true);
-
- SafeToRotate = Safe1 && Safe2 && Safe3;
-
+ TheCamera.m_uiTimeLastChange = CTimer::GetTimeInMilliseconds();
+ CamPos = TargetCoors;
+ CamPos.z += DEADCAM_HEIGHT_START;
+ float WaterZ = 0.0f;
+ if(CWaterLevel::GetWaterLevelNoWaves(TargetCoors.x, TargetCoors.y, TargetCoors.z, &WaterZ)){
+ if(WaterZ + 1.5f > CamPos.z)
+ CamPos.z = WaterZ + 1.5f;
+ }
+ CVector Right = CrossProduct(TheCamera.pTargetEntity->GetForward(), CVector(0.0f, 0.0f, 1.0f));
+ Right.z = 0.0f;
+ Right.Normalise();
+ Front = TargetCoors - CamPos;
+ Front.Normalise();
+ Up = CrossProduct(Right, Front);
+ Up.Normalise();
ResetStatics = false;
+ }else{
+ CamPos = Source;
+ if(CWorld::TestSphereAgainstWorld(CamPos+CVector(0.0f, 0.0f, 0.2f), 0.3f, TheCamera.pTargetEntity, true, true, false, true, false, true) == nil)
+ CamPos.z += DEADCAM_HEIGHT_RATE*CTimer::GetTimeStep();
+ CVector Right = CrossProduct(TheCamera.pTargetEntity->GetForward(), CVector(0.0f, 0.0f, 1.0f));
+ Right.z = 0.0f;
+ Right.Normalise();
+
+ float Time = CTimer::GetTimeInMilliseconds() - TheCamera.m_uiTimeLastChange;
+ CVector WaftOffset = DEADCAM_WAFT_AMPLITUDE * Min(1000.0f,Time)/1000.0f * Sin(Time/DEADCAM_WAFT_RATE) * Right;
+ CVector WaftPos = TargetCoors + WaftOffset;
+ WaftPos.z = CamPos.z;
+ CVector WaftFront = WaftPos - CamPos;
+ WaftFront.Normalise();
+ if(CWorld::TestSphereAgainstWorld(CamPos+0.2f*WaftFront, 0.3f, TheCamera.pTargetEntity, true, true, false, true, false, true) == nil)
+ CamPos = WaftPos;
+
+ Front = CVector(0.0f, 0.0f, -1.0f);
+ Front += Cos(Time/DEADCAM_WAFT_RATE) * DEADCAM_WAFT_TILT_AMP * Min(2000.0f,Time)/2000.0f * Right;
+
+ Front.Normalise();
+ Up = CrossProduct(Right, Front);
+ Up.Normalise();
}
- if(SafeToRotate)
- WellBufferMe(Beta + DEGTORAD(175.0f), &Beta, &BetaSpeed, 0.015f, 0.007f, true);
+ Source = CamPos;
+ CVector OrigSource = Source;
+ TheCamera.AvoidTheGeometry(OrigSource, TargetCoors, Source, FOV);
+ TheCamera.m_bMoveCamToAvoidGeom = false;
+}
- WellBufferMe(DEGTORAD(89.5f), &Alpha, &AlphaSpeed, 0.015f, 0.07f, true);
- WellBufferMe(35.0f, &Distance, &DistanceSpeed, 0.006f, 0.007f, false);
+float ARRESTDIST_BEHIND_COP = 5.0f;
+float ARRESTDIST_RIGHTOF_COP = 3.0f;
+float ARRESTDIST_ABOVE_COP = 1.4f; // unused
+float ARRESTDIST_MINFROM_PLAYER = 8.0f;
+float ARRESTCAM_LAMP_BEST_DIST = 17.0f;
+float ARRESTCAM_ROTATION_SPEED = 0.1f;
+float ARRESTCAM_ROTATION_UP = 0.05f;
+float ARRESTCAM_S_ROTATION_UP = 0.1f;
+float ARRESTDIST_ALONG_GROUND = 5.0f;
+float ARRESTDIST_SIDE_GROUND = 10.0f;
+float ARRESTDIST_ABOVE_GROUND = 0.7f;
+float ARRESTCAM_LAMPPOST_ROTATEDIST = 10.0f;
+float ARRESTCAM_LAMPPOST_TRANSLATE = 0.1f;
- Source = CamTargetEntity->GetPosition() +
- CVector(Distance * Cos(Alpha) * Cos(Beta),
- Distance * Cos(Alpha) * Sin(Beta),
- Distance * Sin(Alpha));
- m_cvecTargetCoorsForFudgeInter = CamTargetEntity->GetPosition();
- Front = CamTargetEntity->GetPosition() - Source;
- Front.Normalise();
- GetVectorsReadyForRW();
+bool
+CCam::GetLookAlongGroundPos(CEntity *Target, CPed *Cop, CVector &TargetCoors, CVector &SourceOut)
+{
+ if(Target == nil || Cop == nil)
+ return false;
+ CVector CopToTarget = TargetCoors - Cop->GetPosition();
+ CopToTarget.z = 0.0f;
+ CopToTarget.Normalise();
+ SourceOut = TargetCoors + ARRESTDIST_ALONG_GROUND*CopToTarget;
+ CVector Side = CrossProduct(CopToTarget, CVector(0.0f, 0.0f, 1.0f));
+ SourceOut += ARRESTDIST_SIDE_GROUND*Side;
+ SourceOut.z += 5.0f;
+ bool found = false;
+ float ground = CWorld::FindGroundZFor3DCoord(SourceOut.x, SourceOut.y, SourceOut.z, &found);
+ if(found)
+ SourceOut.z = ground + ARRESTDIST_ABOVE_GROUND;
+ return true;
}
bool
+CCam::GetLookFromLampPostPos(CEntity *Target, CPed *Cop, CVector &TargetCoors, CVector &SourceOut)
+{
+ int i;
+ int16 NumObjects;
+ CEntity *Objects[16];
+ CEntity *NearestLampPost = nil;
+ CWorld::FindObjectsInRange(TargetCoors, 30.0f, true, &NumObjects, 15, Objects, false, false, false, true, true);
+ float NearestDist = 10000.0f;
+ for(i = 0; i < NumObjects; i++){
+ if(Objects[i]->GetIsStatic() && Objects[i]->GetUp().z > 0.9f && IsLampPost(Objects[i]->GetModelIndex())){
+ float Dist = (Objects[i]->GetPosition() - TargetCoors).Magnitude2D();
+ if(Abs(ARRESTCAM_LAMP_BEST_DIST - Dist) < NearestDist){
+ CVector TestStart = Objects[i]->GetColModel()->boundingBox.max;
+ TestStart = Objects[i]->GetMatrix() * TestStart;
+ CVector TestEnd = TestStart - TargetCoors;
+ TestEnd.Normalise();
+ TestEnd += TargetCoors;
+ if(CWorld::GetIsLineOfSightClear(TestStart, TestEnd, true, false, false, false, false, true, true)){
+ NearestDist = Abs(ARRESTCAM_LAMP_BEST_DIST - Dist);
+ NearestLampPost = Objects[i];
+ SourceOut = TestStart;
+ }
+ }
+ }
+ }
+ return NearestLampPost != nil;
+}
+
+bool
+CCam::GetLookOverShoulderPos(CEntity *Target, CPed *Cop, CVector &TargetCoors, CVector &SourceOut)
+{
+ if(Target == nil || Cop == nil)
+ return false;
+ CVector CopCoors = Cop->GetPosition();
+ CVector CopToTarget = TargetCoors - CopCoors;
+ CVector Side = CrossProduct(CopToTarget, CVector(0.0f, 0.0f, 1.0f));
+ Side.Normalise();
+ CopCoors += ARRESTDIST_RIGHTOF_COP * Side;
+ CopToTarget.Normalise();
+ if(CopToTarget.z < -0.7071f){
+ CopToTarget.z = -0.7071f;
+ float GroundDist = CopToTarget.Magnitude2D();
+ if(GroundDist > 0.0f){
+ CopToTarget.x *= 0.7071f/GroundDist;
+ CopToTarget.y *= 0.7071f/GroundDist;
+ }
+ CopToTarget.Normalise();
+ }else{
+ if(CopToTarget.z > 0.0f){
+ CopToTarget.z = 0.0f;
+ CopToTarget.Normalise();
+ }
+ }
+ CopCoors -= ARRESTDIST_BEHIND_COP * CopToTarget;
+ CopToTarget = TargetCoors - CopCoors;
+ float Dist = CopToTarget.Magnitude();
+ if(Dist < ARRESTDIST_MINFROM_PLAYER && Dist > 0.0f)
+ CopToTarget *= ARRESTDIST_MINFROM_PLAYER/Dist;
+ SourceOut = TargetCoors - CopToTarget;
+ return true;
+}
+
+enum {
+ ARRESTCAM_OVERSHOULDER = 1,
+ ARRESTCAM_ALONGGROUND,
+ ARRESTCAM_ALONGGROUND_RIGHT,
+ ARRESTCAM_ALONGGROUND_RIGHT_UP,
+ ARRESTCAM_ALONGGROUND_LEFT,
+ ARRESTCAM_ALONGGROUND_LEFT_UP,
+ ARRESTCAM_LAMPPOST,
+};
+
+int nUsingWhichCamera;
+CPed *pStoredCopPed;
+
+bool
CCam::ProcessArrestCamOne(void)
{
+ CVector TargetPos;
+ CVector CamSource;
+ CPed *cop = nil;
FOV = 45.0f;
- if(!ResetStatics)
- return true;
+ bool foundPos = false;
+ int ArrestModes[5] = { -1, -1, -1, -1, -1 };
-#ifdef FIX_BUGS
- if(!CamTargetEntity->IsPed() || ((CPlayerPed*)TheCamera.pTargetEntity)->m_pArrestingCop == nil)
- return true;
-#endif
+ if(ResetStatics){
+ CPed *targetPed = (CPed*)TheCamera.pTargetEntity;
+ nUsingWhichCamera = 0;
+ if(TheCamera.pTargetEntity->IsPed()){
+ ((CPed*)TheCamera.pTargetEntity)->m_pedIK.GetComponentPosition(TargetPos, PED_MID);
+ if(FindPlayerPed() && FindPlayerPed()->m_pArrestingCop)
+ cop = FindPlayerPed()->m_pArrestingCop;
+ if(cop && CGeneral::GetRandomNumberInRange(0.0f, 1.0f) > 0.5f){
+ ArrestModes[0] = ARRESTCAM_OVERSHOULDER;
+ ArrestModes[1] = ARRESTCAM_ALONGGROUND;
+ ArrestModes[2] = ARRESTCAM_OVERSHOULDER;
+ ArrestModes[3] = ARRESTCAM_LAMPPOST;
+ }else{
+ ArrestModes[0] = ARRESTCAM_ALONGGROUND;
+ ArrestModes[1] = ARRESTCAM_OVERSHOULDER;
+ ArrestModes[2] = ARRESTCAM_LAMPPOST;
+ }
+ }else if(TheCamera.pTargetEntity->IsVehicle()){
+ CVehicle *targetVehicle = (CVehicle*)TheCamera.pTargetEntity;
+ if(targetVehicle->pDriver && targetVehicle->pDriver->IsPlayer()){
+ targetPed = targetVehicle->pDriver;
+ targetPed->m_pedIK.GetComponentPosition(TargetPos, PED_MID);
+ }else{
+ targetPed = nil;
+ TargetPos = targetVehicle->GetPosition();
+ }
- bool found;
- float Ground;
- CVector PlayerCoors = TheCamera.pTargetEntity->GetPosition();
- CVector CopCoors = ((CPlayerPed*)TheCamera.pTargetEntity)->m_pArrestingCop->GetPosition();
- Beta = CGeneral::GetATanOfXY(PlayerCoors.x - CopCoors.x, PlayerCoors.y - CopCoors.y);
-
- Source = PlayerCoors + 9.5f*CVector(Cos(Beta), Sin(Beta), 0.0f);
- Source.z += 6.0f;
- Ground = CWorld::FindGroundZFor3DCoord(Source.x, Source.y, Source.z, &found);
- if(!found){
- Ground = CWorld::FindRoofZFor3DCoord(Source.x, Source.y, Source.z, &found);
- if(!found)
+ if(FindPlayerPed() && FindPlayerPed()->m_pArrestingCop)
+ cop = FindPlayerPed()->m_pArrestingCop;
+ if(cop && CGeneral::GetRandomNumberInRange(0.0f, 1.0f) > 0.65f){
+ ArrestModes[0] = ARRESTCAM_OVERSHOULDER;
+ ArrestModes[1] = ARRESTCAM_LAMPPOST;
+ ArrestModes[2] = ARRESTCAM_ALONGGROUND;
+ ArrestModes[3] = ARRESTCAM_OVERSHOULDER;
+ }else{
+ ArrestModes[0] = ARRESTCAM_LAMPPOST;
+ ArrestModes[1] = ARRESTCAM_ALONGGROUND;
+ ArrestModes[2] = ARRESTCAM_OVERSHOULDER;
+ }
+ }else
return false;
+
+ for(int i = 0; nUsingWhichCamera == 0 && i < ARRAY_SIZE(ArrestModes) && ArrestModes[i] > 0; i++){
+ switch(ArrestModes[i]){
+ case ARRESTCAM_OVERSHOULDER:
+ if(cop){
+ foundPos = GetLookOverShoulderPos(TheCamera.pTargetEntity, cop, TargetPos, CamSource);
+ pStoredCopPed = cop;
+ cop = nil;
+ }else if(targetPed){
+ for(int j = 0; j < targetPed->m_numNearPeds; j++){
+ CPed *nearPed = targetPed->m_nearPeds[j];
+ if(nearPed->GetPedState() == PED_ARREST_PLAYER)
+ foundPos = GetLookOverShoulderPos(TheCamera.pTargetEntity, nearPed, TargetPos, CamSource);
+ if(foundPos){
+ pStoredCopPed = nearPed;
+ break;
+ }
+ }
+ }
+ break;
+ case ARRESTCAM_ALONGGROUND:
+ if(cop){
+ foundPos = GetLookAlongGroundPos(TheCamera.pTargetEntity, cop, TargetPos, CamSource);
+ pStoredCopPed = cop;
+ cop = nil;
+ }else if(targetPed){
+ for(int j = 0; j < targetPed->m_numNearPeds; j++){
+ CPed *nearPed = targetPed->m_nearPeds[j];
+ if(nearPed->GetPedState() == PED_ARREST_PLAYER)
+ foundPos = GetLookAlongGroundPos(TheCamera.pTargetEntity, nearPed, TargetPos, CamSource);
+ if(foundPos){
+ pStoredCopPed = nearPed;
+ break;
+ }
+ }
+ }
+ break;
+ case ARRESTCAM_LAMPPOST:
+ foundPos = GetLookFromLampPostPos(TheCamera.pTargetEntity, cop, TargetPos, CamSource);
+ break;
+ }
+
+ if(foundPos){
+ if(pStoredCopPed)
+ pStoredCopPed->RegisterReference((CEntity**)&pStoredCopPed);
+ nUsingWhichCamera = ArrestModes[i];
+ if(ArrestModes[i] == ARRESTCAM_ALONGGROUND){
+ float rnd = CGeneral::GetRandomNumberInRange(0.0f, 5.0f);
+ if(rnd < 1.0f) nUsingWhichCamera = ARRESTCAM_ALONGGROUND;
+ else if(rnd < 2.0f) nUsingWhichCamera = ARRESTCAM_ALONGGROUND_RIGHT;
+ else if(rnd < 3.0f) nUsingWhichCamera = ARRESTCAM_ALONGGROUND_RIGHT_UP;
+ else if(rnd < 4.0f) nUsingWhichCamera = ARRESTCAM_ALONGGROUND_LEFT;
+ else nUsingWhichCamera = ARRESTCAM_ALONGGROUND_LEFT_UP;
+ }
+ }else
+ pStoredCopPed = nil;
+ }
+
+ Source = CamSource;
+ CVector OrigSource = Source;
+ TheCamera.AvoidTheGeometry(OrigSource, TargetPos, Source, FOV);
+ Front = TargetPos - Source;
+ Front.Normalise();
+ Up = CVector(0.0f, 0.0f, 1.0f);
+ CVector Right = CrossProduct(Front, Up);
+ Right.Normalise();
+ Up = CrossProduct(Right, Front);
+ if(nUsingWhichCamera != 0)
+ ResetStatics = false;
+ return true;
}
- Source.z = Ground + 0.25f;
- if(!CWorld::GetIsLineOfSightClear(Source, CopCoors, true, true, false, true, false, true, true)){
- Beta += DEGTORAD(115.0f);
- Source = PlayerCoors + 9.5f*CVector(Cos(Beta), Sin(Beta), 0.0f);
- Source.z += 6.0f;
- Ground = CWorld::FindGroundZFor3DCoord(Source.x, Source.y, Source.z, &found);
- if(!found){
- Ground = CWorld::FindRoofZFor3DCoord(Source.x, Source.y, Source.z, &found);
- if(!found)
- return false;
+
+ if(TheCamera.pTargetEntity->IsPed()){
+ ((CPed*)TheCamera.pTargetEntity)->m_pedIK.GetComponentPosition(TargetPos, PED_MID);
+ }else if(TheCamera.pTargetEntity->IsVehicle()){
+ CPed *driver = ((CVehicle*)TheCamera.pTargetEntity)->pDriver;
+ if(driver && driver->IsPlayer())
+ driver->m_pedIK.GetComponentPosition(TargetPos, PED_MID);
+ else
+ TargetPos = TheCamera.pTargetEntity->GetPosition();
+ }else
+ return false;
+
+ if(nUsingWhichCamera == ARRESTCAM_OVERSHOULDER && pStoredCopPed){
+ foundPos = GetLookOverShoulderPos(TheCamera.pTargetEntity, pStoredCopPed, TargetPos, CamSource);
+ float newZ = Source.z + ARRESTCAM_S_ROTATION_UP*CTimer::GetTimeStep();
+ if(CamSource.z > newZ)
+ CamSource.z = newZ;
+ }else if(nUsingWhichCamera >= ARRESTCAM_ALONGGROUND_RIGHT && nUsingWhichCamera <= ARRESTCAM_ALONGGROUND_LEFT_UP){
+ CamSource = Source;
+ Front = TargetPos - CamSource;
+ Front.Normalise();
+ Up = CVector(0.0f, 0.0f, 1.0f);
+ CVector Right = CrossProduct(Front, Up);
+ if(nUsingWhichCamera == ARRESTCAM_ALONGGROUND_LEFT || nUsingWhichCamera == ARRESTCAM_ALONGGROUND_LEFT_UP)
+ Right *= -1.0f;
+ if(CWorld::TestSphereAgainstWorld(CamSource + 0.5f*Right, 0.4f, TheCamera.pTargetEntity, true, true, false, true, false, true) == nil){
+ foundPos = true;
+ CamSource += Right*ARRESTCAM_ROTATION_SPEED*CTimer::GetTimeStep();
+ if(nUsingWhichCamera == ARRESTCAM_ALONGGROUND_RIGHT_UP || nUsingWhichCamera == ARRESTCAM_ALONGGROUND_LEFT_UP){
+ CamSource.z += ARRESTCAM_ROTATION_UP*CTimer::GetTimeStep();
+ }else{
+ bool found = false;
+ float ground = CWorld::FindGroundZFor3DCoord(CamSource.x, CamSource.y, CamSource.z, &found);
+ if(found)
+ CamSource.z = ground + ARRESTDIST_ABOVE_GROUND;
+ }
}
- Source.z = Ground + 0.25f;
+ }else if(nUsingWhichCamera == ARRESTCAM_LAMPPOST){
+ CamSource = Source;
+ Front = TargetPos - CamSource;
+ Front.z = 0.0f;
+ Front.Normalise();
+ Up = CVector(0.0f, 0.0f, 1.0f);
+ CVector Right = CrossProduct(Front, Up);
+ Right.Normalise();
+ Front = TargetPos - CamSource + Right*ARRESTCAM_LAMPPOST_ROTATEDIST;
+ Front.z = 0.0f;
+ Front.Normalise();
+ if(CWorld::TestSphereAgainstWorld(CamSource + 0.5f*Front, 0.4f, TheCamera.pTargetEntity, true, true, false, true, false, true) == nil){
+ foundPos = true;
+ CamSource += Front*ARRESTCAM_LAMPPOST_TRANSLATE*CTimer::GetTimeStep();
+ }
+ }
- CopCoors.z += 0.35f;
- Front = CopCoors - Source;
- if(!CWorld::GetIsLineOfSightClear(Source, CopCoors, true, true, false, true, false, true, true))
- return false;
+ if(foundPos){
+ Source = CamSource;
+ CVector OrigSource = Source;
+ TheCamera.AvoidTheGeometry(OrigSource, TargetPos, Source, FOV);
+ Front = TargetPos - Source;
+ Front.Normalise();
+ Up = CVector(0.0f, 0.0f, 1.0f);
+ CVector Right = CrossProduct(Front, Up);
+ Right.Normalise();
+ Up = CrossProduct(Right, Front);
+ }else{
+ CVector OrigSource = Source;
+ TheCamera.AvoidTheGeometry(OrigSource, TargetPos, Source, FOV);
}
- CopCoors.z += 0.35f;
- m_cvecTargetCoorsForFudgeInter = CopCoors;
- Front = CopCoors - Source;
- ResetStatics = false;
- GetVectorsReadyForRW();
+
return true;
}
@@ -4186,376 +4567,6 @@ CCam::ProcessArrestCamTwo(void)
}
-/*
- * Unused PS2 cams
- */
-
-void
-CCam::Process_Chris_With_Binding_PlusRotation(const CVector &CameraTarget, float TargetOrientation, float, float)
-{
- static float AngleToBinned = 0.0f;
- static float StartingAngleLastChange = 0.0f;
- static float FixedTargetOrientation = 0.0f;
- static float DeadZoneReachedOnePrevious;
-
- FOV = DefaultFOV; // missing in game
-
- bool FixOrientation = true;
- if(ResetStatics){
- Rotating = false;
- DeadZoneReachedOnePrevious = 0.0f;
- FixedTargetOrientation = 0.0f;
- ResetStatics = false;
- }
-
- CVector TargetCoors = CameraTarget;
-
- float StickX = CPad::GetPad(0)->GetRightStickX();
- float StickY = CPad::GetPad(0)->GetRightStickY();
- float StickAngle;
- if(StickX != 0.0 || StickY != 0.0f) // BUG: game checks StickX twice
- StickAngle = CGeneral::GetATanOfXY(StickX, StickY); // result unused?
- else
- FixOrientation = false;
-
- CVector Dist = Source - TargetCoors;
- Source.z = TargetCoors.z + 0.75f;
- float Length = Dist.Magnitude2D();
- if(Length > 2.5f){
- Source.x = TargetCoors.x + Dist.x/Length * 2.5f;
- Source.y = TargetCoors.y + Dist.y/Length * 2.5f;
- }else if(Length < 2.4f){
- Source.x = TargetCoors.x + Dist.x/Length * 2.4f;
- Source.y = TargetCoors.y + Dist.y/Length * 2.4f;
- }
-
- Beta = CGeneral::GetATanOfXY(Dist.x, Dist.y);
- if(CPad::GetPad(0)->GetLeftShoulder1()){
- FixedTargetOrientation = TargetOrientation;
- Rotating = true;
- }
-
- if(FixOrientation){
- Rotating = true;
- FixedTargetOrientation = StickX/128.0f + Beta - PI;
- }
-
- if(Rotating){
- Dist = Source - TargetCoors;
- Length = Dist.Magnitude2D();
- // inlined
- WellBufferMe(FixedTargetOrientation+PI, &Beta, &BetaSpeed, 0.1f, 0.06f, true);
-
- Source.x = TargetCoors.x + Length*Cos(Beta);
- Source.y = TargetCoors.y + Length*Sin(Beta);
-
- float DeltaBeta = FixedTargetOrientation+PI - Beta;
- while(DeltaBeta >= PI) DeltaBeta -= 2*PI;
- while(DeltaBeta < -PI) DeltaBeta += 2*PI;
- if(Abs(DeltaBeta) < 0.06f)
- Rotating = false;
- }
-
- Front = TargetCoors - Source;
- Front.Normalise();
- CVector Front2 = Front;
- Front2.Normalise(); // What?
- // FIX: the meaning of this value must have changed somehow
- Source -= Front2 * TheCamera.m_fPedZoomValueSmooth*1.5f;
-// Source += Front2 * TheCamera.m_fPedZoomValueSmooth;
-
- GetVectorsReadyForRW();
-}
-
-void
-CCam::Process_ReactionCam(const CVector &CameraTarget, float TargetOrientation, float, float)
-{
- static float AngleToBinned = 0.0f;
- static float StartingAngleLastChange = 0.0f;
- static float FixedTargetOrientation;
- static float DeadZoneReachedOnePrevious;
- static uint32 TimeOfLastChange;
- uint32 Time;
- bool DontBind = false; // BUG: left uninitialized
-
- FOV = DefaultFOV; // missing in game
-
- if(ResetStatics){
- Rotating = false;
- DeadZoneReachedOnePrevious = 0.0f;
- FixedTargetOrientation = 0.0f;
- ResetStatics = false;
- DontBind = false;
- }
-
- CVector TargetCoors = CameraTarget;
-
- CVector Dist = Source - TargetCoors;
- Source.z = TargetCoors.z + 0.75f;
- float Length = Dist.Magnitude2D();
- if(Length > 2.5f){
- Source.x = TargetCoors.x + Dist.x/Length * 2.5f;
- Source.y = TargetCoors.y + Dist.y/Length * 2.5f;
- }else if(Length < 2.4f){
- Source.x = TargetCoors.x + Dist.x/Length * 2.4f;
- Source.y = TargetCoors.y + Dist.y/Length * 2.4f;
- }
-
- Beta = CGeneral::GetATanOfXY(Dist.x, Dist.y);
-
- float StickX = CPad::GetPad(0)->GetLeftStickX();
- float StickY = CPad::GetPad(0)->GetLeftStickY();
- float StickAngle;
- if(StickX != 0.0 || StickY != 0.0f){
- StickAngle = CGeneral::GetATanOfXY(StickX, StickY);
- while(StickAngle >= PI) StickAngle -= 2*PI;
- while(StickAngle < -PI) StickAngle += 2*PI;
- }else
- StickAngle = 1000.0f;
-
- if(Abs(StickAngle-AngleToBinned) > DEGTORAD(15.0f)){
- DontBind = true;
- Time = CTimer::GetTimeInMilliseconds();
- }
-
- if(CTimer::GetTimeInMilliseconds()-TimeOfLastChange > 200){
- if(Abs(HALFPI-StickAngle) > DEGTORAD(50.0f)){
- FixedTargetOrientation = TargetOrientation;
- Rotating = true;
- TimeOfLastChange = CTimer::GetTimeInMilliseconds();
- }
- }
-
- // These two together don't make much sense.
- // Only prevents rotation for one frame
- AngleToBinned = StickAngle;
- if(DontBind)
- TimeOfLastChange = Time;
-
- if(Rotating){
- Dist = Source - TargetCoors;
- Length = Dist.Magnitude2D();
- // inlined
- WellBufferMe(FixedTargetOrientation+PI, &Beta, &BetaSpeed, 0.1f, 0.06f, true);
-
- Source.x = TargetCoors.x + Length*Cos(Beta);
- Source.y = TargetCoors.y + Length*Sin(Beta);
-
- float DeltaBeta = FixedTargetOrientation+PI - Beta;
- while(DeltaBeta >= PI) DeltaBeta -= 2*PI;
- while(DeltaBeta < -PI) DeltaBeta += 2*PI;
- if(Abs(DeltaBeta) < 0.06f)
- Rotating = false;
- }
-
- Front = TargetCoors - Source;
- Front.Normalise();
- CVector Front2 = Front;
- Front2.Normalise(); // What?
- // FIX: the meaning of this value must have changed somehow
- Source -= Front2 * TheCamera.m_fPedZoomValueSmooth*1.5f;
-// Source += Front2 * TheCamera.m_fPedZoomValueSmooth;
-
- GetVectorsReadyForRW();
-}
-
-void
-CCam::Process_FollowPed_WithBinding(const CVector &CameraTarget, float TargetOrientation, float, float)
-{
- static float AngleToBinned = 0.0f;
- static float StartingAngleLastChange = 0.0f;
- static float FixedTargetOrientation;
- static float DeadZoneReachedOnePrevious;
- static uint32 TimeOfLastChange;
- uint32 Time;
- bool DontBind = false;
-
- FOV = DefaultFOV; // missing in game
-
- if(ResetStatics){
- Rotating = false;
- DeadZoneReachedOnePrevious = 0.0f;
- FixedTargetOrientation = 0.0f;
- ResetStatics = false;
- }
-
- CVector TargetCoors = CameraTarget;
-
- CVector Dist = Source - TargetCoors;
- Source.z = TargetCoors.z + 0.75f;
- float Length = Dist.Magnitude2D();
- if(Length > 2.5f){
- Source.x = TargetCoors.x + Dist.x/Length * 2.5f;
- Source.y = TargetCoors.y + Dist.y/Length * 2.5f;
- }else if(Length < 2.4f){
- Source.x = TargetCoors.x + Dist.x/Length * 2.4f;
- Source.y = TargetCoors.y + Dist.y/Length * 2.4f;
- }
-
- Beta = CGeneral::GetATanOfXY(Dist.x, Dist.y);
-
- float StickX = CPad::GetPad(0)->GetLeftStickX();
- float StickY = CPad::GetPad(0)->GetLeftStickY();
- float StickAngle;
- if(StickX != 0.0 || StickY != 0.0f){
- StickAngle = CGeneral::GetATanOfXY(StickX, StickY);
- while(StickAngle >= PI) StickAngle -= 2*PI;
- while(StickAngle < -PI) StickAngle += 2*PI;
- }else
- StickAngle = 1000.0f;
-
- if(Abs(StickAngle-AngleToBinned) > DEGTORAD(15.0f)){
- DontBind = true;
- Time = CTimer::GetTimeInMilliseconds();
- }
-
- if(CTimer::GetTimeInMilliseconds()-TimeOfLastChange > 200){
- if(Abs(HALFPI-StickAngle) > DEGTORAD(50.0f)){
- FixedTargetOrientation = TargetOrientation;
- Rotating = true;
- TimeOfLastChange = CTimer::GetTimeInMilliseconds();
- }
- }
-
- if(CPad::GetPad(0)->GetLeftShoulder1JustDown()){
- FixedTargetOrientation = TargetOrientation;
- Rotating = true;
- TimeOfLastChange = CTimer::GetTimeInMilliseconds();
- }
-
- // These two together don't make much sense.
- // Only prevents rotation for one frame
- AngleToBinned = StickAngle;
- if(DontBind)
- TimeOfLastChange = Time;
-
- if(Rotating){
- Dist = Source - TargetCoors;
- Length = Dist.Magnitude2D();
- // inlined
- WellBufferMe(FixedTargetOrientation+PI, &Beta, &BetaSpeed, 0.1f, 0.06f, true);
-
- Source.x = TargetCoors.x + Length*Cos(Beta);
- Source.y = TargetCoors.y + Length*Sin(Beta);
-
- float DeltaBeta = FixedTargetOrientation+PI - Beta;
- while(DeltaBeta >= PI) DeltaBeta -= 2*PI;
- while(DeltaBeta < -PI) DeltaBeta += 2*PI;
- if(Abs(DeltaBeta) < 0.06f)
- Rotating = false;
- }
-
- Front = TargetCoors - Source;
- Front.Normalise();
- CVector Front2 = Front;
- Front2.Normalise(); // What?
- // FIX: the meaning of this value must have changed somehow
- Source -= Front2 * TheCamera.m_fPedZoomValueSmooth*1.5f;
-// Source += Front2 * TheCamera.m_fPedZoomValueSmooth;
-
- GetVectorsReadyForRW();
-}
-
-void
-CCam::Process_Bill(const CVector &CameraTarget, float TargetOrientation, float SpeedVar, float TargetSpeedVar)
-{
-#ifdef FIX_BUGS
- fBillsBetaOffset += CPad::GetPad(0)->GetRightStickX()/1000.0f;
-#else
- // just wtf is this? this code must be ancient
- if(CPad::GetPad(0)->GetStart())
- fBillsBetaOffset += CPad::GetPad(0)->GetLeftStickX()/1000.0f;
-#endif
- while(fBillsBetaOffset > TWOPI) fBillsBetaOffset -= TWOPI;
- while(fBillsBetaOffset < 0.0f) fBillsBetaOffset += TWOPI;
- TargetOrientation += fBillsBetaOffset;
- while(TargetOrientation > TWOPI) TargetOrientation -= TWOPI;
- while(TargetOrientation < 0.0f) TargetOrientation += TWOPI;
- Process_BehindCar(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
-}
-
-void
-CCam::Process_Im_The_Passenger_Woo_Woo(const CVector &CameraTarget, float TargetOrientation, float, float)
-{
- FOV = 50.0f;
-
- Source = CamTargetEntity->GetPosition();
- Source.z += 2.5f;
- Front = CamTargetEntity->GetForward();
- Front.Normalise();
- Source += 1.35f*Front;
- float heading = CGeneral::GetATanOfXY(Front.x, Front.y) + DEGTORAD(45.0f);
- Front.x = Cos(heading);
- Front.y = Sin(heading);
- Up = CamTargetEntity->GetUp();
-
- GetVectorsReadyForRW();
-}
-
-void
-CCam::Process_Blood_On_The_Tracks(const CVector &CameraTarget, float TargetOrientation, float, float)
-{
- FOV = 50.0f;
-
- Source = CamTargetEntity->GetPosition();
- Source.z += 5.45f;
-
- static CVector Test = -CamTargetEntity->GetForward();
-#ifdef FIX_BUGS
- if(ResetStatics){
- Test = -CamTargetEntity->GetForward();
- ResetStatics = false;
- }
-#endif
-
- Source.x += 19.45*Test.x;
- Source.y += 19.45*Test.y;
- Front = Test;
- Front.Normalise();
- Up = CamTargetEntity->GetUp();
-
- GetVectorsReadyForRW();
-}
-
-void
-CCam::Process_Cam_Running_Side_Train(const CVector &CameraTarget, float TargetOrientation, float, float)
-{
- FOV = 60.0f;
-
- Source = CamTargetEntity->GetPosition();
- Source.z += 4.0f;
- CVector fwd = CamTargetEntity->GetForward();
- float heading = CGeneral::GetATanOfXY(fwd.x, fwd.y) - DEGTORAD(15.0f);
- Source.x -= Cos(heading)*10.0f;
- Source.y -= Sin(heading)*10.0f;
- heading -= DEGTORAD(5.0f);
- Front = fwd;
- Front.x += Cos(heading);
- Front.y += Sin(heading);
- Front.z -= 0.056f;
- Front.Normalise();
- Up = CamTargetEntity->GetUp();
-
- GetVectorsReadyForRW();
-}
-
-void
-CCam::Process_Cam_On_Train_Roof(const CVector &CameraTarget, float TargetOrientation, float, float)
-{
- static float RoofMultiplier = 1.5f;
-
- Source = CamTargetEntity->GetPosition();
- Source.z += 4.8f;
- Front = CamTargetEntity->GetForward();
- Front.Normalise();
- Source += Front*RoofMultiplier;
- Up = CamTargetEntity->GetUp();
- Up.Normalise();
-
- GetVectorsReadyForRW();
-}
-
-
#ifdef FREE_CAM
void
CCam::Process_FollowPed_Rotation(const CVector &CameraTarget, float TargetOrientation, float, float)
@@ -4683,6 +4694,8 @@ CCam::Process_FollowPed_Rotation(const CVector &CameraTarget, float TargetOrient
Rotating = false;
}
+ if(TheCamera.m_bUseTransitionBeta)
+ Beta = CGeneral::GetATanOfXY(-Cos(m_fTransitionBeta), -Sin(m_fTransitionBeta));
if(TheCamera.m_bUseTransitionBeta)
Beta = CGeneral::GetATanOfXY(-Cos(m_fTransitionBeta), -Sin(m_fTransitionBeta));
@@ -4730,7 +4743,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);
@@ -4786,9 +4799,9 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
uint8 camSetArrPos = 0;
// We may need those later
- bool isPlane = car->GetModelIndex() == MI_DODO;
- bool isHeli = false;
- bool isBike = false;
+ bool isPlane = car->GetVehicleAppearance() == VEHICLE_APPEARANCE_PLANE;
+ bool isHeli = car->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI;
+ bool isBike = car->GetVehicleAppearance() == VEHICLE_APPEARANCE_BIKE;
bool isCar = car->IsCar() && !isPlane && !isHeli && !isBike;
CPad* pad = CPad::GetPad(0);
@@ -4799,8 +4812,10 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
if (car->GetModelIndex() == MI_FIRETRUCK) {
camSetArrPos = 7;
- } else if (car->GetModelIndex() == MI_RCBANDIT) {
+ } else if (car->GetModelIndex() == MI_RCBANDIT || car->GetModelIndex() == MI_RCBARON) {
camSetArrPos = 5;
+ } else if (car->GetModelIndex() == MI_RCGOBLIN || car->GetModelIndex() == MI_RCRAIDER) {
+ camSetArrPos = 6;
} else if (car->IsBoat()) {
camSetArrPos = 4;
} else if (isBike) {
@@ -4857,6 +4872,14 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
float newDistance = TheCamera.CarZoomValueSmooth + CARCAM_SET[camSetArrPos][1] + approxCarLength;
+ // Taken from VC CCam::Cam_On_A_String_Unobscured. If we don't this, we will end up seeing the world from the inside of RC Goblin/Raider.
+ // I couldn't find where SA does that. It's possible that they've increased the size of these veh.'s collision bounding box.
+
+ if (car->m_modelIndex == MI_RCRAIDER || car->m_modelIndex == MI_RCGOBLIN)
+ newDistance += INIT_RC_HELI_HORI_EXTRA;
+ else if (car->m_modelIndex == MI_RCBARON)
+ newDistance += INIT_RC_PLANE_HORI_EXTRA;
+
float minDistForThisCar = approxCarLength * CARCAM_SET[camSetArrPos][3];
if (!isHeli || car->GetStatus() == STATUS_PLAYER_REMOTE) {
@@ -4871,6 +4894,9 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
TargetCoors += 0.6f * car->GetUp() * colMaxZ;
}
+ if (car->m_modelIndex == MI_RCGOBLIN)
+ zoomModeAlphaOffset += 0.178997f;
+
float minDistForVehType = CARCAM_SET[camSetArrPos][4];
if (TheCamera.CarZoomIndicator == CAM_ZOOM_1 && (camSetArrPos < 2 || camSetArrPos == 7)) {
@@ -4884,10 +4910,6 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
if (ResetStatics) {
FOV = DefaultFOV;
-
- // GTA 3 has this in veh. camera
- if (TheCamera.m_bIdleOn)
- TheCamera.m_uiTimeWeEnteredIdle = CTimer::GetTimeInMilliseconds();
} else {
if (isCar || isBike) {
// 0.4f: CAR_FOV_START_SPEED
@@ -4917,17 +4939,14 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
ResetStatics = false;
Rotating = false;
m_bCollisionChecksOn = true;
- // TheCamera.m_bResetOldMatrix = 1;
- // Garage exit cam is not working well in III...
- // if (!TheCamera.m_bJustCameOutOfGarage) // && !sthForScript)
- // {
- Alpha = 0.0f;
- Beta = car->GetForward().Heading() - HALFPI;
- if (TheCamera.m_bCamDirectlyInFront) {
- Beta += PI;
+ if (!TheCamera.m_bJustCameOutOfGarage) {
+ Alpha = 0.0f;
+ Beta = car->GetForward().Heading() - HALFPI;
+ if (TheCamera.m_bCamDirectlyInFront) {
+ Beta += PI;
+ }
}
- // }
BetaSpeed = 0.0;
AlphaSpeed = 0.0;
@@ -4942,7 +4961,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
m_aTargetHistoryPosTwo = TargetCoors - newDistance * Front;
m_nCurrentHistoryPoints = 0;
- if (!TheCamera.m_bJustCameOutOfGarage) // && !sthForScript)
+ if (!TheCamera.m_bJustCameOutOfGarage)
Alpha = -zoomModeAlphaOffset;
}
@@ -4994,9 +5013,9 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
// This is also original LCS and SA bug, or some attempt to fix lag. We'll never know
// if (car->m_vecMoveSpeed.MagnitudeSqr() < sq(0.2f))
- if (car->GetModelIndex() != MI_FIRETRUCK) {
- // if (!isBike || GetMysteriousWheelRelatedThingBike(car) > 3)
- // if (!isHeli && (!isPlane || car->GetWheelsOnGround())) {
+ if (car->GetModelIndex() != MI_FIRETRUCK)
+ if (!isBike || ((CBike*)car)->m_nWheelsOnGround > 3)
+ if (!isHeli && (!isPlane || ((CAutomobile*)car)->m_nWheelsOnGround)) {
CVector left = CrossProduct(car->GetForward(), CVector(0.0f, 0.0f, 1.0f));
left.Normalise();
@@ -5041,20 +5060,19 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
float stickX = -(pad->GetCarGunLeftRight());
float stickY = -pad->GetCarGunUpDown();
- // In SA this is for not let num2/num8 move camera when Keyboard & Mouse controls are used.
- // if (CCamera::m_bUseMouse3rdPerson)
- // stickY = 0.0f;
-#ifdef INVERT_LOOK_FOR_PAD
- if (CPad::bInvertLook4Pad)
+ // In SA this checks for m_bUseMouse3rdPerson so num2 / num8 do not move camera
+ // when Keyboard & Mouse controls are used. To make it work better with III/VC, check for actual pad state instead
+ if (!CPad::IsAffectedByController && !isCar)
+ stickY = 0.0f;
+ else if (CPad::bInvertLook4Pad)
stickY = -stickY;
-#endif
float xMovement = Abs(stickX) * (FOV / 80.0f * 5.f / 70.f) * stickX * 0.007f * 0.007f;
float yMovement = Abs(stickY) * (FOV / 80.0f * 3.f / 70.f) * stickY * 0.007f * 0.007f;
bool correctAlpha = true;
// if (SA checks if we aren't in work car, why?) {
- if (!isCar || car->GetModelIndex() != MI_YARDIE) {
+ if (!isCar || car->GetModelIndex() != MI_VOODOO) {
correctAlpha = false;
}
else {
@@ -5158,8 +5176,8 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
Beta += TWOPI;
if ((camSetArrPos <= 1 || camSetArrPos == 7) && targetAlpha < Alpha && carPosChange >= newDistance) {
- if (isCar && ((CAutomobile*)car)->m_nWheelsOnGround > 1)
- // || isBike && GetMysteriousWheelRelatedThingBike(car) > 1)
+ if (isCar && ((CAutomobile*)car)->m_nWheelsOnGround > 1 ||
+ isBike && ((CBike*)car)->m_nWheelsOnGround > 1)
alphaSpeedFromStickY += (targetAlpha - Alpha) * 0.075f;
}
@@ -5244,7 +5262,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
dontCollideWithCars = (timestepFactor * dontCollideWithCars) + ((1.0f - timestepFactor) * car->m_vecMoveSpeed.Magnitude());
// Our addition
-#define IS_TRAFFIC_LIGHT(ent) (ent->IsObject() && (IsStreetLight(ent->GetModelIndex())))
+#define IS_TRAFFIC_LIGHT(ent) (ent->IsObject() && IsLightObject(ent->GetModelIndex()))
// Clip Source and fix near clip
CColPoint colPoint;
@@ -5269,14 +5287,14 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
RwCameraSetNearClipPlane(Scene.camera, Max(PedColDist-0.3f, 0.05f));
}
}
-
+
CWorld::pIgnoreEntity = nil;
// If we're seeing blue hell due to camera intersects some surface, fix it.
// SA and LCS have this unrolled.
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, true);
@@ -5318,19 +5336,13 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
if (camSetArrPos == 5 && Source.z < 1.0f) // RC Bandit and Baron
Source.z = 1.0f;
- // Obviously some specific place in LC
- if (Source.x > 11.0f && Source.x < 91.0f) {
- if (Source.y > -680.0f && Source.y < -600.0f && Source.z < 24.4f)
- Source.z = 24.4f;
- }
-
// CCam::FixSourceAboveWaterLevel
if (CameraTarget.z >= -2.0f) {
float level = -6000.0;
- // +0.5f is needed for III
+
if (CWaterLevel::GetWaterLevelNoWaves(Source.x, Source.y, Source.z, &level)) {
- if (Source.z < level + 0.5f)
- Source.z = level + 0.5f;
+ if (Source.z < level)
+ Source.z = level;
}
}
Front = TargetCoors - Source;
@@ -5383,7 +5395,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
float alphaToFace = Atan2(hi.z, hi.Magnitude2D()) + DEGTORAD(15.0f);
float neededAlphaTurn = alphaToFace - carGunUD;
- float alphaTurnPerFrame = CTimer::GetTimeStep() * 0.02f;
+ float alphaTurnPerFrame = CTimer::GetTimeStepInSeconds();
if (neededAlphaTurn > alphaTurnPerFrame) {
neededTurn = alphaTurnPerFrame;
diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp
index f3b41655..e7cd65a0 100644
--- a/src/core/Camera.cpp
+++ b/src/core/Camera.cpp
@@ -14,12 +14,14 @@
#include "General.h"
#include "ZoneCull.h"
#include "SurfaceTable.h"
+#include "Particle.h"
#include "WaterLevel.h"
#include "World.h"
#include "Garages.h"
#include "Replay.h"
#include "CutsceneMgr.h"
#include "Renderer.h"
+#include "Timecycle.h"
#include "MBlur.h"
#include "Text.h"
#include "Hud.h"
@@ -30,7 +32,6 @@
#include "Pools.h"
#include "Debug.h"
#include "GenericGameStorage.h"
-#include "MemoryCard.h"
#include "Camera.h"
enum
@@ -51,6 +52,14 @@ enum
OBBE_11,
OBBE_12,
OBBE_13,
+ // heli
+ OBBE_14,
+ OBBE_15,
+ OBBE_16,
+ OBBE_17,
+ OBBE_18,
+ OBBE_19,
+ OBBE_ONSTRING_HELI,
OBBE_INVALID
};
@@ -66,6 +75,11 @@ bool CCamera::m_bUseMouse3rdPerson = true;
bool CCamera::m_bUseMouse3rdPerson = false;
#endif
bool bDidWeProcessAnyCinemaCam;
+static bool bSwitchedToObbeCam;
+float CCamera::m_fMouseAccelHorzntl;
+float CCamera::m_fMouseAccelVertical;
+float CCamera::m_f3rdPersonCHairMultX;
+float CCamera::m_f3rdPersonCHairMultY;
#ifdef IMPROVED_CAMERA
#define KEYJUSTDOWN(k) ControlsManager.GetIsKeyboardKeyJustDown((RsKeyCodes)k)
@@ -76,46 +90,27 @@ bool bDidWeProcessAnyCinemaCam;
#define CTRLDOWN(key) ((KEYDOWN(rsLCTRL) || KEYDOWN(rsRCTRL)) && KEYDOWN((RsKeyCodes)key))
#endif
-CCamera::CCamera(void)
-{
-#if GTA_VERSION >= GTA3_PC_11 || defined(FIX_BUGS)
- m_fMouseAccelHorzntl = 0.0025f;
- m_fMouseAccelVertical = 0.003f;
+const float ZOOM_ONE_DISTANCE[] = { -0.6f, 0.05f, -3.2f, 0.05f, -2.41f };
+const float ZOOM_TWO_DISTANCE[] = { 1.9f, 1.4f, 0.65f, 1.9f, 6.49f };
+const float ZOOM_THREE_DISTANCE[] = { 15.9f, 15.9f, 15.9f, 15.9f, 25.25f };
+
+#ifdef FREE_CAM
+const float LCS_ZOOM_ONE_DISTANCE[] = { -1.0f, -0.2f, -3.2f, 0.05f, -2.41f };
+const float LCS_ZOOM_TWO_DISTANCE[] = { 2.0f, 2.2f, 1.65f, 2.9f, 6.49f };
+const float LCS_ZOOM_THREE_DISTANCE[] = { 6.0f, 6.0f, 15.9f, 15.9f, 15.0f };
#endif
- Init();
-}
-CCamera::CCamera(float)
+CCamera::CCamera(void)
{
+ Init();
}
void
CCamera::Init(void)
{
-#if GTA_VERSION >= GTA3_PC_11 || defined(FIX_BUGS)
- float fMouseAccelHorzntl = m_fMouseAccelHorzntl;
- float fMouseAccelVertical = m_fMouseAccelVertical;
-#endif
-
-#ifdef PS2_MENU
- if ( !TheMemoryCard.m_bWantToLoad && !FrontEndMenuManager.m_bWantToRestart )
-#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
-
- #if GTA_VERSION >= GTA3_PC_11 || defined(FIX_BUGS)
- m_fMouseAccelHorzntl = fMouseAccelHorzntl;
- m_fMouseAccelVertical = fMouseAccelVertical;
- #endif
- m_pRwCamera = nil;
-
- }
-
+ memset(this, 0, sizeof(CCamera)); // this is fine, no vtable
+ m_pRwCamera = nil;
+ m_bPlayerWasOnBike = false;
m_1rstPersonRunCloseToAWall = false;
m_fPositionAlongSpline = 0.0f;
m_bCameraJustRestored = false;
@@ -124,8 +119,21 @@ CCamera::Init(void)
Cams[2].Init();
Cams[0].Mode = CCam::MODE_FOLLOWPED;
Cams[1].Mode = CCam::MODE_FOLLOWPED;
- unknown = 0;
- m_bUnknown = false;
+ m_bEnable1rstPersonCamCntrlsScript = false;
+ m_bAllow1rstPersonWeaponsCamera = false;
+ m_bVehicleSuspenHigh = false;
+ Cams[0].m_fMinRealGroundDist = 1.85f;
+ // TODO: what weird value is this?
+ Cams[0].m_fTargetCloseInDist = 2.0837801f - Cams[0].m_fMinRealGroundDist;
+ Cams[0].m_fTargetZoomGroundOne = 0.25f;
+ Cams[0].m_fTargetZoomGroundTwo = 1.5f;
+ Cams[0].m_fTargetZoomGroundThree = 4.0f;
+ Cams[0].m_fTargetZoomOneZExtra = -0.14f;
+ Cams[0].m_fTargetZoomTwoZExtra = 0.16f;
+ Cams[0].m_fTargetZoomThreeZExtra = 0.25f;
+ // TODO: another weird value
+ Cams[0].m_fTargetZoomZCloseIn = 0.90040702f;
+ m_bMoveCamToAvoidGeom = false;
ClearPlayerWeaponMode();
m_bInATunnelAndABigVehicle = false;
m_iModeObbeCamIsInForCar = OBBE_INVALID;
@@ -182,26 +190,18 @@ CCamera::Init(void)
PlayerExhaustion = 1.0f;
DebugCamMode = CCam::MODE_NONE;
m_PedOrientForBehindOrInFront = 0.0f;
-#ifdef PS2_MENU
- if ( !TheMemoryCard.m_bWantToLoad && !FrontEndMenuManager.m_bWantToRestart )
-#else
- if(!FrontEndMenuManager.m_bWantToRestart)
-#endif
- {
+ if(!FrontEndMenuManager.m_bWantToRestart){
m_bFading = false;
CDraw::FadeValue = 0;
m_fFLOATingFade = 0.0f;
m_bMusicFading = false;
m_fTimeToFadeMusic = 0.0f;
m_fFLOATingFadeMusic = 0.0f;
+ m_fMouseAccelVertical = 0.003f;
+ m_fMouseAccelHorzntl = 0.0025f;
}
- m_bMoveCamToAvoidGeom = false;
-#ifdef PS2_MENU
- if ( TheMemoryCard.m_bWantToLoad || FrontEndMenuManager.m_bWantToRestart )
-#else
if(FrontEndMenuManager.m_bWantToRestart)
-#endif
- m_bMoveCamToAvoidGeom = true;
+ m_fTimeToFadeMusic = 0.0f;
m_bStartingSpline = false;
m_iTypeOfSwitch = INTERPOLATION;
m_bUseScriptZoomValuePed = false;
@@ -220,6 +220,8 @@ CCamera::Init(void)
m_uiTimeLastChange = 0;
m_uiTimeWeEnteredIdle = 0;
m_bIdleOn = false;
+ m_uiTimeWeLeftIdle_StillNoInput = 0;
+ m_uiTimeWeEnteredIdle = 0;
LODDistMultiplier = 1.0f;
m_bCamDirectlyBehind = false;
m_bCamDirectlyInFront = false;
@@ -239,21 +241,18 @@ CCamera::Init(void)
m_uiTransitionState = 0;
m_uiTimeTransitionStart = 0;
m_bLookingAtPlayer = true;
-#if GTA_VERSION < GTA3_PC_11 && !defined(FIX_BUGS)
- m_fMouseAccelHorzntl = 0.0025f;
- m_fMouseAccelVertical = 0.003f;
-#endif
m_f3rdPersonCHairMultX = 0.53f;
m_f3rdPersonCHairMultY = 0.4f;
+ m_fAvoidTheGeometryProbsTimer = 0.0f;
+ m_nAvoidTheGeometryProbsDirn = 0;
}
void
CCamera::Process(void)
{
// static bool InterpolatorNotInitialised = true; // unused
- static CVector PreviousFudgedTargetCoors; // only PS2
- static float PlayerMinDist = 1.6f; // not on PS2
- static bool WasPreviouslyInterSyhonFollowPed = false; // only used on PS2
+ static float PlayerMinDist = 1.3f;
+ static bool WasPreviouslyInterSyhonFollowPed = false; // only written
float FOV = 0.0f;
float oldBeta, newBeta;
float deltaBeta = 0.0f;
@@ -281,6 +280,7 @@ CCamera::Process(void)
if(m_WideScreenOn)
ProcessWideScreenOn();
+#ifndef MASTER
#ifdef IMPROVED_CAMERA
if(CPad::GetPad(1)->GetCircleJustDown() || CTRLJUSTDOWN('B')){
#else
@@ -292,6 +292,7 @@ CCamera::Process(void)
else
CPad::m_bMapPadOneToPadTwo = false;
}
+#endif
RwCameraSetNearClipPlane(Scene.camera, DEFAULT_NEAR);
@@ -311,19 +312,11 @@ CCamera::Process(void)
// Stop transition when it's done
if(m_uiTransitionState != 0){
-#ifdef PS2_CAM_TRANSITION
- if(!m_bWaitForInterpolToFinish){
- Cams[(ActiveCam+1)%2].Process();
- Cams[(ActiveCam+1)%2].ProcessSpecialHeightRoutines();
- }
-#else
- // done in CamControl on PS2 it seems
if(CTimer::GetTimeInMilliseconds() > m_uiTransitionDuration+m_uiTimeTransitionStart){
m_uiTransitionState = 0;
m_vecDoingSpecialInterPolation = false;
m_bWaitForInterpolToFinish = false;
}
-#endif
}
if(m_bUseNearClipScript)
@@ -335,169 +328,50 @@ CCamera::Process(void)
if(Abs(deltaBeta) > 0.3f)
m_bJust_Switched = true;
+#ifndef MASTER
// Debug stuff
if(!gbModelViewer)
- Cams[ActiveCam].PrintMode();
+ Cams[ActiveCam].PrintMode(); // actually missing in VC
if(WorldViewerBeingUsed)
Cams[2].Process();
+#endif
if(Cams[ActiveCam].DirectionWasLooking != LOOKING_FORWARD && pTargetEntity->IsVehicle())
lookLRBVehicle = true;
if(m_uiTransitionState != 0 && !lookLRBVehicle){
// Process transition
-#ifdef PS2_CAM_TRANSITION
- bool lookingAtPlayerNow = false;
- bool wasLookingAtPlayer = false;
- bool transitionPedMode = false;
- bool setWait = false;
- if(Cams[ActiveCam].CamTargetEntity == Cams[(ActiveCam+1)%2].CamTargetEntity){
- if(Cams[ActiveCam].Mode == CCam::MODE_SYPHON ||
- Cams[ActiveCam].Mode == CCam::MODE_SYPHON_CRIM_IN_FRONT ||
- Cams[ActiveCam].Mode == CCam::MODE_FOLLOWPED ||
- Cams[ActiveCam].Mode == CCam::MODE_SPECIAL_FIXED_FOR_SYPHON)
- lookingAtPlayerNow = true;
- if(Cams[(ActiveCam+1)%2].Mode == CCam::MODE_SYPHON ||
- Cams[(ActiveCam+1)%2].Mode == CCam::MODE_SYPHON_CRIM_IN_FRONT ||
- Cams[(ActiveCam+1)%2].Mode == CCam::MODE_FOLLOWPED ||
- Cams[(ActiveCam+1)%2].Mode == CCam::MODE_SPECIAL_FIXED_FOR_SYPHON) // checked twice for some reason
- wasLookingAtPlayer = true;
-
- if(!m_vecDoingSpecialInterPolation &&
- (Cams[ActiveCam].Mode == CCam::MODE_FOLLOWPED || Cams[ActiveCam].Mode == CCam::MODE_FIGHT_CAM) &&
- (Cams[(ActiveCam+1)%2].Mode == CCam::MODE_FOLLOWPED || Cams[(ActiveCam+1)%2].Mode == CCam::MODE_FIGHT_CAM))
- transitionPedMode = true;
- }
-
- if(lookingAtPlayerNow && wasLookingAtPlayer){
- CVector playerDist;
- playerDist.x = FindPlayerPed()->GetPosition().x - GetPosition().x;
- playerDist.y = FindPlayerPed()->GetPosition().y - GetPosition().y;
- playerDist.z = FindPlayerPed()->GetPosition().z - GetPosition().z;
- if(playerDist.Magnitude() > 17.5f &&
- (Cams[ActiveCam].Mode == CCam::MODE_SYPHON || Cams[ActiveCam].Mode == CCam::MODE_SYPHON_CRIM_IN_FRONT))
- setWait = true;
- }
- if(setWait)
- m_bWaitForInterpolToFinish = true;
-
uint32 currentTime = CTimer::GetTimeInMilliseconds() - m_uiTimeTransitionStart;
if(currentTime >= m_uiTransitionDuration)
currentTime = m_uiTransitionDuration;
- float inter = (float) currentTime / m_uiTransitionDuration;
- inter = 0.5f - 0.5*Cos(inter*PI); // smooth it
-
- if(m_vecDoingSpecialInterPolation){
- Cams[(ActiveCam+1)%2].Source = m_vecOldSourceForInter;
- Cams[(ActiveCam+1)%2].Front = m_vecOldFrontForInter;
- Cams[(ActiveCam+1)%2].Up = m_vecOldUpForInter;
- Cams[(ActiveCam+1)%2].FOV = m_vecOldFOVForInter;
- if(WasPreviouslyInterSyhonFollowPed)
- Cams[(ActiveCam+1)%2].m_cvecTargetCoorsForFudgeInter.z = PreviousFudgedTargetCoors.z;
- }
+ float fractionInter = (float) currentTime / m_uiTransitionDuration;
+ float fractionInterTarget = (float) currentTime / m_uiTransitionDurationTargetCoors;
+ fractionInterTarget = Clamp(fractionInterTarget, 0.0f, 1.0f);
- CamSource = inter*Cams[ActiveCam].Source + (1.0f-inter)*Cams[(ActiveCam+1)%2].Source;
- FOV = inter*Cams[ActiveCam].FOV + (1.0f-inter)*Cams[(ActiveCam+1)%2].FOV;
-
- CVector tmpFront = Cams[(ActiveCam+1)%2].Front;
- float Alpha_other = CGeneral::GetATanOfXY(tmpFront.Magnitude2D(), tmpFront.z);
- if(Alpha_other > PI) Alpha_other -= TWOPI;
- float Beta_other = 0.0f;
- if(tmpFront.x != 0.0f || tmpFront.y != 0.0f)
- Beta_other = CGeneral::GetATanOfXY(-tmpFront.y, tmpFront.x);
- tmpFront = Cams[ActiveCam].Front;
- float Alpha_active = CGeneral::GetATanOfXY(tmpFront.Magnitude2D(), tmpFront.z);
- if(Alpha_active > PI) Alpha_active -= TWOPI;
- float Beta_active = 0.0f;
- if(tmpFront.x != 0.0f || tmpFront.y != 0.0f)
- Beta_active = CGeneral::GetATanOfXY(-tmpFront.y, tmpFront.x);
-
- float DeltaBeta = Beta_active - Beta_other;
- float Alpha = inter*Alpha_active + (1.0f-inter)*Alpha_other;
-
- if(m_uiTransitionJUSTStarted){
- while(DeltaBeta > PI) DeltaBeta -= TWOPI;
- while(DeltaBeta <= -PI) DeltaBeta += TWOPI;
- m_uiTransitionJUSTStarted = false;
- }else{
- if(DeltaBeta < m_fOldBetaDiff)
- while(Abs(DeltaBeta - m_fOldBetaDiff) > PI) DeltaBeta += TWOPI;
+ // Interpolate target separately
+ if(fractionInterTarget <= m_fFractionInterToStopMovingTarget){
+ float inter;
+ if(m_fFractionInterToStopMovingTarget == 0.0f)
+ inter = 0.0f;
else
- while(Abs(DeltaBeta - m_fOldBetaDiff) > PI) DeltaBeta -= TWOPI;
- }
- m_fOldBetaDiff = DeltaBeta;
- float Beta = inter*DeltaBeta + Beta_other;
-
- CVector FudgedTargetCoors;
- if(lookingAtPlayerNow && wasLookingAtPlayer){
- // BUG? how is this interpolation ever used when values are overwritten below?
- float PlayerDist = (pTargetEntity->GetPosition() - CamSource).Magnitude2D();
- float MinDist = Min(Cams[(ActiveCam+1)%2].m_fMinDistAwayFromCamWhenInterPolating, Cams[ActiveCam].m_fMinDistAwayFromCamWhenInterPolating);
- if(PlayerDist < MinDist){
- CamSource.x = pTargetEntity->GetPosition().x - MinDist*Cos(Beta - HALFPI);
- CamSource.y = pTargetEntity->GetPosition().y - MinDist*Sin(Beta - HALFPI);
- }else{
- CamSource.x = pTargetEntity->GetPosition().x - PlayerDist*Cos(Beta - HALFPI);
- CamSource.y = pTargetEntity->GetPosition().y - PlayerDist*Sin(Beta - HALFPI);
- }
-
- CColPoint colpoint;
- CEntity *entity = nil;
- if(CWorld::ProcessLineOfSight(pTargetEntity->GetPosition(), CamSource, colpoint, entity, true, false, false, true, false, true, true)){
- CamSource = colpoint.point;
- RwCameraSetNearClipPlane(Scene.camera, 0.05f);
- }
+ inter = (m_fFractionInterToStopMovingTarget - fractionInterTarget)/m_fFractionInterToStopMovingTarget;
+ inter = 0.5f - 0.5*Cos(inter*PI); // smooth it
- CamFront = pTargetEntity->GetPosition() - CamSource;
- FudgedTargetCoors = inter*Cams[ActiveCam].m_cvecTargetCoorsForFudgeInter + (1.0f-inter)*Cams[(ActiveCam+1)%2].m_cvecTargetCoorsForFudgeInter;
- PreviousFudgedTargetCoors = FudgedTargetCoors;
- CamFront.Normalise();
- CamUp = CVector(0.0f, 0.0f, 1.0f);
- CamRight = CrossProduct(CamFront, CamUp);
- CamRight.Normalise();
- CamUp = CrossProduct(CamRight, CamFront);
+ m_vecTargetWhenInterPol = m_cvecStartingTargetForInterPol + inter*m_cvecTargetSpeedAtStartInter;
+ Target = m_vecTargetWhenInterPol;
+ }else if(fractionInterTarget > m_fFractionInterToStopMovingTarget){
+ float inter;
+ if(m_fFractionInterToStopCatchUpTarget == 0.0f)
+ inter = 0.0f;
+ else
+ inter = (fractionInterTarget - m_fFractionInterToStopMovingTarget)/m_fFractionInterToStopCatchUpTarget;
+ inter = 0.5f - 0.5*Cos(inter*PI); // smooth it
- WasPreviouslyInterSyhonFollowPed = true;
- }else
- WasPreviouslyInterSyhonFollowPed = false;
-
- if(transitionPedMode){
- FudgedTargetCoors = inter*Cams[ActiveCam].m_cvecTargetCoorsForFudgeInter + (1.0f-inter)*Cams[(ActiveCam+1)%2].m_cvecTargetCoorsForFudgeInter;
- PreviousFudgedTargetCoors = FudgedTargetCoors;
- CVector CamToTarget = pTargetEntity->GetPosition() - CamSource;
- float tmpBeta = CGeneral::GetATanOfXY(CamToTarget.x, CamToTarget.y);
- float PlayerDist = (pTargetEntity->GetPosition() - CamSource).Magnitude2D();
- float MinDist = Min(Cams[(ActiveCam+1)%2].m_fMinDistAwayFromCamWhenInterPolating, Cams[ActiveCam].m_fMinDistAwayFromCamWhenInterPolating);
- if(PlayerDist < MinDist){
- CamSource.x = pTargetEntity->GetPosition().x - MinDist*Cos(tmpBeta - HALFPI);
- CamSource.y = pTargetEntity->GetPosition().y - MinDist*Sin(tmpBeta - HALFPI);
- }
- CamFront = FudgedTargetCoors - CamSource;
- CamFront.Normalise();
- CamUp = CVector(0.0f, 0.0f, 1.0f);
- CamUp.Normalise();
- CamRight = CrossProduct(CamFront, CamUp);
- CamRight.Normalise();
- CamUp = CrossProduct(CamRight, CamFront);
- CamUp.Normalise();
- }else{
- CamFront.x = Cos(Alpha) * Sin(Beta);
- CamFront.y = Cos(Alpha) * -Cos(Beta);
- CamFront.z = Sin(Alpha);
- CamFront.Normalise();
- CamUp = inter*Cams[ActiveCam].Up + (1.0f-inter)*Cams[(ActiveCam+1)%2].Up;
- CamUp.Normalise();
- CamRight = CrossProduct(CamFront, CamUp);
- CamRight.Normalise();
- CamUp = CrossProduct(CamRight, CamFront);
- CamUp.Normalise();
+ if(m_fFractionInterToStopMovingTarget == 0.0f)
+ m_vecTargetWhenInterPol = m_cvecStartingTargetForInterPol;
+ Target = m_vecTargetWhenInterPol + inter*(Cams[ActiveCam].m_cvecTargetCoorsForFudgeInter - m_vecTargetWhenInterPol);
}
-#else
- uint32 currentTime = CTimer::GetTimeInMilliseconds() - m_uiTimeTransitionStart;
- if(currentTime >= m_uiTransitionDuration)
- currentTime = m_uiTransitionDuration;
- float fractionInter = (float) currentTime / m_uiTransitionDuration;
if(fractionInter <= m_fFractionInterToStopMoving){
float inter;
@@ -508,37 +382,22 @@ CCamera::Process(void)
inter = 0.5f - 0.5*Cos(inter*PI); // smooth it
m_vecSourceWhenInterPol = m_cvecStartingSourceForInterPol + inter*m_cvecSourceSpeedAtStartInter;
- m_vecTargetWhenInterPol = m_cvecStartingTargetForInterPol + inter*m_cvecTargetSpeedAtStartInter;
- m_vecUpWhenInterPol = m_cvecStartingUpForInterPol + inter*m_cvecUpSpeedAtStartInter;
- m_fFOVWhenInterPol = m_fStartingFOVForInterPol + inter*m_fFOVSpeedAtStartInter;
- CamSource = m_vecSourceWhenInterPol;
-
- if(m_bItsOkToLookJustAtThePlayer){
- m_vecTargetWhenInterPol.x = FindPlayerPed()->GetPosition().x;
- m_vecTargetWhenInterPol.y = FindPlayerPed()->GetPosition().y;
- m_fBetaWhenInterPol = m_fStartingBetaForInterPol + inter*m_fBetaSpeedAtStartInter;
-
- float dist = (CamSource - m_vecTargetWhenInterPol).Magnitude2D();
- if(dist < PlayerMinDist){
- if(dist > 0.0f){
- CamSource.x = m_vecTargetWhenInterPol.x + PlayerMinDist*Cos(m_fBetaWhenInterPol);
- CamSource.y = m_vecTargetWhenInterPol.y + PlayerMinDist*Sin(m_fBetaWhenInterPol);
- }else{
- // can only be 0.0 now...
- float beta = CGeneral::GetATanOfXY(Cams[ActiveCam].Front.x, Cams[ActiveCam].Front.y);
- CamSource.x = m_vecTargetWhenInterPol.x + PlayerMinDist*Cos(beta);
- CamSource.y = m_vecTargetWhenInterPol.y + PlayerMinDist*Sin(beta);
- }
- }else{
- CamSource.x = m_vecTargetWhenInterPol.x + dist*Cos(m_fBetaWhenInterPol);
- CamSource.y = m_vecTargetWhenInterPol.y + dist*Sin(m_fBetaWhenInterPol);
+ if(m_bLookingAtPlayer){
+ CVector ToCam = m_vecSourceWhenInterPol - Target;
+ if(ToCam.Magnitude2D() < PlayerMinDist){
+ float beta = CGeneral::GetATanOfXY(ToCam.x, ToCam.y);
+ CamSource.x = Target.x + PlayerMinDist*Cos(beta);
+ CamSource.y = Target.y + PlayerMinDist*Sin(beta);
}
}
- CamFront = m_vecTargetWhenInterPol - CamSource;
+ m_vecUpWhenInterPol = m_cvecStartingUpForInterPol + inter*m_cvecUpSpeedAtStartInter;
+ m_fFOVWhenInterPol = m_fStartingFOVForInterPol + inter*m_fFOVSpeedAtStartInter;
+
+ CamSource = m_vecSourceWhenInterPol;
+ CamFront = Target - CamSource;
StoreValuesDuringInterPol(CamSource, m_vecTargetWhenInterPol, m_vecUpWhenInterPol, m_fFOVWhenInterPol);
- Target = m_vecTargetWhenInterPol;
CamFront.Normalise();
if(m_bLookingAtPlayer)
CamUp = CVector(0.0f, 0.0f, 1.0f);
@@ -569,33 +428,20 @@ CCamera::Process(void)
inter = 0.5f - 0.5*Cos(inter*PI); // smooth it
CamSource = m_vecSourceWhenInterPol + inter*(Cams[ActiveCam].Source - m_vecSourceWhenInterPol);
+
+ if(m_bLookingAtPlayer){
+ CVector ToCam = m_vecSourceWhenInterPol - Target;
+ if(ToCam.Magnitude2D() < PlayerMinDist){
+ float beta = CGeneral::GetATanOfXY(ToCam.x, ToCam.y);
+ CamSource.x = Target.x + PlayerMinDist*Cos(beta);
+ CamSource.y = Target.y + PlayerMinDist*Sin(beta);
+ }
+ }
+
FOV = m_fFOVWhenInterPol + inter*(Cams[ActiveCam].FOV - m_fFOVWhenInterPol);
- Target = m_vecTargetWhenInterPol + inter*(Cams[ActiveCam].m_cvecTargetCoorsForFudgeInter - m_vecTargetWhenInterPol);
CamUp = m_vecUpWhenInterPol + inter*(Cams[ActiveCam].Up - m_vecUpWhenInterPol);
deltaBeta = Cams[ActiveCam].m_fTrueBeta - m_fBetaWhenInterPol;
MakeAngleLessThan180(deltaBeta);
- float interpBeta = m_fBetaWhenInterPol + inter*deltaBeta;
-
- if(m_bItsOkToLookJustAtThePlayer){
- Target.x = FindPlayerPed()->GetPosition().x;
- Target.y = FindPlayerPed()->GetPosition().y;
-
- float dist = (CamSource - Target).Magnitude2D();
- if(dist < PlayerMinDist){
- if(dist > 0.0f){
- CamSource.x = Target.x + PlayerMinDist*Cos(interpBeta);
- CamSource.y = Target.y + PlayerMinDist*Sin(interpBeta);
- }else{
- // can only be 0.0 now...
- float beta = CGeneral::GetATanOfXY(Cams[ActiveCam].Front.x, Cams[ActiveCam].Front.y);
- CamSource.x = Target.x + PlayerMinDist*Cos(beta);
- CamSource.y = Target.y + PlayerMinDist*Sin(beta);
- }
- }else{
- CamSource.x = Target.x + dist*Cos(interpBeta);
- CamSource.y = Target.y + dist*Sin(interpBeta);
- }
- }
CamFront = Target - CamSource;
StoreValuesDuringInterPol(CamSource, Target, CamUp, FOV);
@@ -627,21 +473,34 @@ CCamera::Process(void)
float Alpha = CGeneral::GetATanOfXY(DistOnGround, Dist.z);
float Beta = CGeneral::GetATanOfXY(Dist.x, Dist.y);
Cams[ActiveCam].KeepTrackOfTheSpeed(CamSource, Target, CamUp, Alpha, Beta, FOV);
-#endif
}else{
// No transition, take Cam values directly
+#ifndef MASTER
if(WorldViewerBeingUsed){
CamSource = Cams[2].Source;
CamFront = Cams[2].Front;
CamUp = Cams[2].Up;
FOV = Cams[2].FOV;
- }else{
+ }else
+#endif
+ {
CamSource = Cams[ActiveCam].Source;
- CamFront = Cams[ActiveCam].Front;
CamUp = Cams[ActiveCam].Up;
+ if(m_bMoveCamToAvoidGeom){
+ CamSource += m_vecClearGeometryVec;
+ CamFront = Cams[ActiveCam].m_cvecTargetCoorsForFudgeInter - CamSource;
+ CamFront.Normalise();
+ CVector Right = CrossProduct(CamFront, CamUp);
+ Right.Normalise();
+ CamUp = CrossProduct(Right, CamFront);
+ CamUp.Normalise();
+ }else{
+ CamFront = Cams[ActiveCam].Front;
+ CamUp = Cams[ActiveCam].Up;
+ }
FOV = Cams[ActiveCam].FOV;
}
- WasPreviouslyInterSyhonFollowPed = false; // only used on PS2
+ WasPreviouslyInterSyhonFollowPed = false; // unused
}
if(m_uiTransitionState != 0)
@@ -654,6 +513,37 @@ CCamera::Process(void)
}
}
+ if(CMBlur::Drunkness > 0.0f){
+ static float DrunkAngle;
+
+ int tableIndex = (int)(DEGTORAD(DrunkAngle)/TWOPI * CParticle::SIN_COS_TABLE_SIZE) & CParticle::SIN_COS_TABLE_SIZE-1;
+ DrunkAngle += 5.0f;
+#ifndef FIX_BUGS
+ // This just messes up interpolation, probably not what they intended
+ // and multiplying the interpolated FOV is also a bit extreme
+ // so let's not do any of this nonsense
+ Cams[ActiveCam].FOV *= (1.0f + CMBlur::Drunkness);
+#endif
+
+ CamSource.x += -0.02f*CMBlur::Drunkness * CParticle::m_CosTable[tableIndex];
+ CamSource.y += -0.02f*CMBlur::Drunkness * CParticle::m_SinTable[tableIndex];
+
+ CamUp.Normalise();
+ CamUp.x += 0.05f*CMBlur::Drunkness * CParticle::m_CosTable[tableIndex];
+ CamUp.y += 0.05f*CMBlur::Drunkness * CParticle::m_SinTable[tableIndex];
+ CamUp.Normalise();
+
+ CamFront.Normalise();
+ CamFront.x += -0.1f*CMBlur::Drunkness * CParticle::m_CosTable[tableIndex];
+ CamFront.y += -0.1f*CMBlur::Drunkness * CParticle::m_SinTable[tableIndex];
+ CamFront.Normalise();
+
+ CamRight = CrossProduct(CamFront, CamUp);
+ CamRight.Normalise();
+ CamUp = CrossProduct(CamRight, CamFront);
+ CamUp.Normalise();
+ }
+
GetMatrix().GetRight() = CrossProduct(CamUp, CamFront); // actually Left
GetMatrix().GetForward() = CamFront;
GetMatrix().GetUp() = CamUp;
@@ -670,13 +560,21 @@ CCamera::Process(void)
if(shakeOffset > 0.0f && m_BlurType != MOTION_BLUR_SNIPER)
SetMotionBlurAlpha(Min((int)(shakeStrength*255.0f) + 25, 150));
- if(Cams[ActiveCam].Mode == CCam::MODE_1STPERSON && FindPlayerVehicle() && FindPlayerVehicle()->GetUp().z < 0.2f)
+
+ static bool bExtra1stPrsBlur = false;
+ if(Cams[ActiveCam].Mode == CCam::MODE_1STPERSON && FindPlayerVehicle() && FindPlayerVehicle()->GetUp().z < 0.2f){
SetMotionBlur(230, 230, 230, 215, MOTION_BLUR_LIGHT_SCENE);
+ bExtra1stPrsBlur = true;
+ }else if(bExtra1stPrsBlur){
+ SetMotionBlur(CTimeCycle::GetBlurRed(), CTimeCycle::GetBlurGreen(), CTimeCycle::GetBlurBlue(), m_motionBlur, MOTION_BLUR_LIGHT_SCENE);
+ bExtra1stPrsBlur = false;
+ }
CalculateDerivedValues();
CDraw::SetFOV(FOV);
// Set RW camera
+#ifndef MASTER
if(WorldViewerBeingUsed){
RwFrame *frame = RwCameraGetFrame(m_pRwCamera);
CVector Source = Cams[2].Source;
@@ -697,7 +595,9 @@ CCamera::Process(void)
*RwMatrixGetRight(RwFrameGetMatrix(frame)) = GetRight();
RwMatrixUpdate(RwFrameGetMatrix(frame));
RwFrameUpdateObjects(frame);
- }else{
+ }else
+#endif
+ {
RwFrame *frame = RwCameraGetFrame(m_pRwCamera);
m_vecGameCamPos = GetPosition();
*RwMatrixGetPos(RwFrameGetMatrix(frame)) = GetPosition();
@@ -706,11 +606,9 @@ CCamera::Process(void)
*RwMatrixGetRight(RwFrameGetMatrix(frame)) = GetRight();
RwMatrixUpdate(RwFrameGetMatrix(frame));
RwFrameUpdateObjects(frame);
+ RwFrameOrthoNormalize(frame);
}
- CDraw::SetNearClipZ(RwCameraGetNearClipPlane(m_pRwCamera));
- CDraw::SetFarClipZ(RwCameraGetFarClipPlane(m_pRwCamera));
-
UpdateSoundDistances();
if((CTimer::GetFrameCounter()&0xF) == 3)
@@ -719,16 +617,22 @@ CCamera::Process(void)
// LOD dist
if(!CCutsceneMgr::IsRunning() || CCutsceneMgr::UseLodMultiplier()){
LODDistMultiplier = 70.0f/CDraw::GetFOV();
-#ifndef FIX_BUGS
- // makes no sense and gone in VC
- LODDistMultiplier *= CDraw::GetAspectRatio()/(4.0f/3.0f);
-#endif
+
+ if(GetPosition().z > 55.0f && FindPlayerVehicle() && FindPlayerVehicle()->pHandling->Flags & (HANDLING_IS_HELI|HANDLING_IS_PLANE) ||
+ FindPlayerPed()->m_attachedTo){
+ LODDistMultiplier *= 1.0f + Max((GetPosition().z - 55.0f)/60.0f, 0.0f);
+ float NewNear = DEFAULT_NEAR * (1.0f + Max((GetPosition().z - 55.0f)/60.0f, 0.0f));
+ if(RwCameraGetNearClipPlane(Scene.camera) >= DEFAULT_NEAR)
+ RwCameraSetNearClipPlane(Scene.camera, NewNear);
+ }
+ if(LODDistMultiplier > 2.2f) LODDistMultiplier = 2.2f;
}else
LODDistMultiplier = 1.0f;
-#if GTA_VERSION > GTA3_PS2_160
GenerationDistMultiplier = LODDistMultiplier;
LODDistMultiplier *= CRenderer::ms_lodDistScale;
-#endif
+
+ CDraw::SetNearClipZ(RwCameraGetNearClipPlane(m_pRwCamera));
+ CDraw::SetFarClipZ(RwCameraGetFarClipPlane(m_pRwCamera));
// Keep track of speed
if(m_bJustInitalised || m_bJust_Switched){
@@ -744,8 +648,6 @@ CCamera::Process(void)
}
m_PreviousCameraPosition = GetPosition();
- // PS2 normalizes a CVector2D GetForward() here. is it used anywhere?
-
if(Cams[ActiveCam].DirectionWasLooking != LOOKING_FORWARD && Cams[ActiveCam].Mode != CCam::MODE_TOP_DOWN_PED){
Cams[ActiveCam].Source = Cams[ActiveCam].SourceBeforeLookBehind;
Orientation += PI;
@@ -763,6 +665,7 @@ CCamera::Process(void)
}
m_bCameraJustRestored = false;
+ m_bMoveCamToAvoidGeom = false;
}
void
@@ -770,10 +673,10 @@ CCamera::CamControl(void)
{
static bool PlaceForFixedWhenSniperFound = false;
static int16 ReqMode;
- bool disableGarageCam = false;
bool switchByJumpCut = false;
bool stairs = false;
bool boatTarget = false;
+ int PrevMode = Cams[ActiveCam].Mode;
CVector targetPos;
CVector garageCenter, garageDoorPos1, garageDoorPos2;
CVector garageCenterToDoor, garageCamPos;
@@ -786,20 +689,12 @@ CCamera::CamControl(void)
m_bJustCameOutOfGarage = false;
m_bTargetJustCameOffTrain = false;
m_bInATunnelAndABigVehicle = false;
+ m_bJustJumpedOutOf1stPersonBecauseOfTarget = false;
+ bSwitchedToObbeCam = false;
if(Cams[ActiveCam].CamTargetEntity == nil && pTargetEntity == nil)
pTargetEntity = PLAYER;
-#ifdef PS2_CAM_TRANSITION
- // Stop transition when it's done
- if(m_uiTransitionState != 0)
- if(CTimer::GetTimeInMilliseconds() > m_uiTransitionDuration+m_uiTimeTransitionStart){
- m_uiTransitionState = 0;
- m_vecDoingSpecialInterPolation = false;
- m_bWaitForInterpolToFinish = false;
- }
-#endif
-
m_iZoneCullFrameNumWereAt++;
if(m_iZoneCullFrameNumWereAt > m_iCheckCullZoneThisNumFrames)
m_iZoneCullFrameNumWereAt = 1;
@@ -808,11 +703,11 @@ CCamera::CamControl(void)
m_bFailedCullZoneTestPreviously = CCullZones::CamCloseInForPlayer();
if(m_bLookingAtPlayer){
- CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_CAMERA);
+ CPad::GetPad(0)->DisablePlayerControls &= ~PLAYERCONTROL_CAMERA;
FindPlayerPed()->bIsVisible = true;
}
- if(!CTimer::GetIsPaused()){
+ if(!CTimer::GetIsPaused() && !m_bIdleOn){
float CloseInCarHeightTarget = 0.0f;
float CloseInPedHeightTarget = 0.0f;
@@ -828,25 +723,35 @@ CCamera::CamControl(void)
// Vehicle target
if(pTargetEntity->IsVehicle()){
+#ifdef GTA_TRAIN
if(((CVehicle*)pTargetEntity)->IsTrain()){
if(!m_bTargetJustBeenOnTrain){
m_bInitialNodeFound = false;
m_bInitialNoNodeStaticsSet = false;
}
Process_Train_Camera_Control();
- }else{
- if(((CVehicle*)pTargetEntity)->IsBoat())
+ }else
+#endif
+ {
+ if(((CVehicle*)pTargetEntity)->IsBoat() && pTargetEntity->GetModelIndex() != MI_SKIMMER)
boatTarget = true;
// Change user selected mode
if(CPad::GetPad(0)->CycleCameraModeUpJustDown() && !CReplay::IsPlayingBack() &&
(m_bLookingAtPlayer || WhoIsInControlOfTheCamera == CAMCONTROL_OBBE) &&
- !m_WideScreenOn)
+ !m_WideScreenOn){
CarZoomIndicator--;
+ // disable topdown here
+ if(CarZoomIndicator == CAM_ZOOM_TOPDOWN)
+ CarZoomIndicator--;
+ }
if(CPad::GetPad(0)->CycleCameraModeDownJustDown() && !CReplay::IsPlayingBack() &&
(m_bLookingAtPlayer || WhoIsInControlOfTheCamera == CAMCONTROL_OBBE) &&
- !m_WideScreenOn)
+ !m_WideScreenOn){
CarZoomIndicator++;
+ if(CarZoomIndicator == CAM_ZOOM_TOPDOWN)
+ CarZoomIndicator++;
+ }
if(!m_bFailedCullZoneTestPreviously){
if(CarZoomIndicator < CAM_ZOOM_1STPRS) CarZoomIndicator = CAM_ZOOM_CINEMATIC;
else if(CarZoomIndicator > CAM_ZOOM_CINEMATIC) CarZoomIndicator = CAM_ZOOM_1STPRS;
@@ -856,45 +761,88 @@ CCamera::CamControl(void)
if(CarZoomIndicator != CAM_ZOOM_1STPRS && CarZoomIndicator != CAM_ZOOM_TOPDOWN)
ReqMode = CCam::MODE_CAM_ON_A_STRING;
- switch(((CVehicle*)pTargetEntity)->m_vehType){
+ int vehType = ((CVehicle*)pTargetEntity)->m_vehType;
+ if(((CVehicle*)pTargetEntity)->IsBoat() && pTargetEntity->GetModelIndex() == MI_SKIMMER)
+ vehType = VEHICLE_TYPE_CAR;
+
+ switch(vehType){
case VEHICLE_TYPE_CAR:
- case VEHICLE_TYPE_BIKE:
- if(CGarages::IsPointInAGarageCameraZone(pTargetEntity->GetPosition())){
+ case VEHICLE_TYPE_BIKE:{
+ CAttributeZone *stairsZone = nil;
+ if(vehType == VEHICLE_TYPE_BIKE && CCullZones::CamStairsForPlayer()){
+ stairsZone = CCullZones::FindZoneWithStairsAttributeForPlayer();
+ if(stairsZone)
+ stairs = true;
+ }
+ if(CGarages::IsPointInAGarageCameraZone(pTargetEntity->GetPosition()) || stairs){
if(!m_bGarageFixedCamPositionSet && m_bLookingAtPlayer ||
WhoIsInControlOfTheCamera == CAMCONTROL_OBBE){
- if(pToGarageWeAreIn){
+ if(pToGarageWeAreIn || stairsZone){
float ground;
bool foundGround;
- // This is all very strange....
- // targetPos = pTargetEntity->GetPosition(); // unused
- if(pToGarageWeAreIn->m_pDoor1){
- whichDoor = 1;
- garageDoorPos1.x = pToGarageWeAreIn->m_fDoor1X;
- garageDoorPos1.y = pToGarageWeAreIn->m_fDoor1Y;
- garageDoorPos1.z = 0.0f;
- // targetPos.z = 0.0f; // unused
- // (targetPos - doorPos1).Magnitude(); // unused
- }else if(pToGarageWeAreIn->m_pDoor2){
- whichDoor = 2;
+ if(pToGarageWeAreIn){
+ // This is all very strange....
+ // targetPos = pTargetEntity->GetPosition(); // unused
+ if(pToGarageWeAreIn->m_pDoor1){
+ whichDoor = 1;
+ garageDoorPos1.x = pToGarageWeAreIn->m_fDoor1X;
+ garageDoorPos1.y = pToGarageWeAreIn->m_fDoor1Y;
+ garageDoorPos1.z = 0.0f;
+ // targetPos.z = 0.0f; // unused
+ // (targetPos - doorPos1).Magnitude(); // unused
+ }else if(pToGarageWeAreIn->m_pDoor2){
+ whichDoor = 2;
#ifdef FIX_BUGS
- garageDoorPos2.x = pToGarageWeAreIn->m_fDoor2X;
- garageDoorPos2.y = pToGarageWeAreIn->m_fDoor2Y;
- garageDoorPos2.z = 0.0f;
+ garageDoorPos2.x = pToGarageWeAreIn->m_fDoor2X;
+ garageDoorPos2.y = pToGarageWeAreIn->m_fDoor2Y;
+ garageDoorPos2.z = 0.0f;
#endif
- }else{
- whichDoor = 1;
- garageDoorPos1.x = pTargetEntity->GetPosition().x;
- garageDoorPos1.y = pTargetEntity->GetPosition().y;
+ }else{
+ whichDoor = 1;
+ garageDoorPos1.x = pTargetEntity->GetPosition().x;
+ garageDoorPos1.y = pTargetEntity->GetPosition().y;
#ifdef FIX_BUGS
- garageDoorPos1.z = 0.0f;
+ garageDoorPos1.z = 0.0f;
#else
- garageDoorPos2.z = 0.0f;
+ garageDoorPos2.z = 0.0f;
#endif
+ }
+ }else{
+ assert(stairsZone);
+ whichDoor = 1;
+ garageDoorPos1 = Cams[ActiveCam].Source;
+ garageCenter = CVector((stairsZone->minx+stairsZone->maxx)/2.0f, (stairsZone->miny+stairsZone->maxy)/2.0f, 0.0f);
+ if((garageCenter-garageDoorPos1).Magnitude() > 15.0f){
+ bool bClearViewOutside = true;
+ CVector dirOutside = pTargetEntity->GetPosition() - garageCenter;
+ dirOutside.z = 0.0f;
+ dirOutside.Normalise();
+ float zoneDim = stairsZone->maxx - stairsZone->minx;
+ if(zoneDim < stairsZone->maxy - stairsZone->miny)
+ zoneDim = stairsZone->maxy - stairsZone->miny;
+ zoneDim *= 2.0f;
+ CVector posOutside = pTargetEntity->GetPosition() + zoneDim*dirOutside;
+ if(!CWorld::GetIsLineOfSightClear(pTargetEntity->GetPosition(), posOutside, true, false, false, false, false, false, true)){
+ posOutside = pTargetEntity->GetPosition() - zoneDim*dirOutside;
+ if(!CWorld::GetIsLineOfSightClear(pTargetEntity->GetPosition(), posOutside, true, false, false, false, false, false, true))
+ bClearViewOutside = false;
+ }
+ if(bClearViewOutside)
+ garageDoorPos1 = posOutside;
+ }
}
- garageCenter.x = (pToGarageWeAreIn->m_fX1 + pToGarageWeAreIn->m_fX2)/2.0f;
- garageCenter.y = (pToGarageWeAreIn->m_fY1 + pToGarageWeAreIn->m_fY2)/2.0f;
- garageCenter.z = 0.0f;
+
+ if(pToGarageWeAreIn){
+ garageCenter.x = pToGarageWeAreIn->GetGarageCenterX();
+ garageCenter.y = pToGarageWeAreIn->GetGarageCenterY();
+ garageCenter.z = 0.0f;
+ }else{
+ garageDoorPos1.z = 0.0f;
+ if(stairsZone == nil) // how can this be true?
+ garageCenter = CVector(pTargetEntity->GetPosition().x, pTargetEntity->GetPosition().y, 0.0f);
+ }
+
if(whichDoor == 1)
garageCenterToDoor = garageDoorPos1 - garageCenter;
else
@@ -905,9 +853,15 @@ CCamera::CamControl(void)
ground = targetPos.z - 0.2f;
garageCenterToDoor.z = 0.0f;
garageCenterToDoor.Normalise();
- if(whichDoor == 1)
- garageCamPos = garageDoorPos1 + 13.0f*garageCenterToDoor;
- else
+ if(whichDoor == 1){
+ if(pToGarageWeAreIn == nil && stairsZone){
+ float zoneDim = stairsZone->maxx - stairsZone->minx;
+ if(zoneDim < stairsZone->maxy - stairsZone->miny)
+ zoneDim = stairsZone->maxy - stairsZone->miny;
+ garageCamPos = garageCenter + (0.7f*zoneDim + 3.75f)*garageCenterToDoor;
+ }else
+ garageCamPos = garageDoorPos1 + 13.0f*garageCenterToDoor;
+ }else
garageCamPos = garageDoorPos2 + 13.0f*garageCenterToDoor;
garageCamPos.z = ground + 3.1f;
SetCamPositionForFixedMode(garageCamPos, CVector(0.0f, 0.0f, 0.0f));
@@ -937,33 +891,38 @@ CCamera::CamControl(void)
ReqMode = CCam::MODE_CAM_ON_A_STRING;
}
break;
+ }
case VEHICLE_TYPE_BOAT:
ReqMode = CCam::MODE_BEHINDBOAT;
break;
default: break;
}
+ int vehApp = ((CVehicle*)pTargetEntity)->GetVehicleAppearance();
+ int vehArrPos = 0;
+ GetArrPosForVehicleType(vehApp, vehArrPos);
+
// Car zoom value
- if(CarZoomIndicator == CAM_ZOOM_1STPRS && !m_bPlayerIsInGarage){
+ if (CarZoomIndicator == CAM_ZOOM_1STPRS && !m_bPlayerIsInGarage) {
CarZoomValue = 0.0f;
ReqMode = CCam::MODE_1STPERSON;
}
#ifdef FREE_CAM
else if (bFreeCam) {
if (CarZoomIndicator == CAM_ZOOM_1)
- CarZoomValue = ((CVehicle*)pTargetEntity)->IsBoat() ? FREE_BOAT_ZOOM_VALUE_1 : FREE_CAR_ZOOM_VALUE_1;
+ CarZoomValue = LCS_ZOOM_ONE_DISTANCE[vehArrPos];
else if (CarZoomIndicator == CAM_ZOOM_2)
- CarZoomValue = ((CVehicle*)pTargetEntity)->IsBoat() ? FREE_BOAT_ZOOM_VALUE_2 : FREE_CAR_ZOOM_VALUE_2;
+ CarZoomValue = LCS_ZOOM_TWO_DISTANCE[vehArrPos];
else if (CarZoomIndicator == CAM_ZOOM_3)
- CarZoomValue = ((CVehicle*)pTargetEntity)->IsBoat() ? FREE_BOAT_ZOOM_VALUE_3 : FREE_CAR_ZOOM_VALUE_3;
+ CarZoomValue = LCS_ZOOM_THREE_DISTANCE[vehArrPos];
}
#endif
- else if(CarZoomIndicator == CAM_ZOOM_1)
- CarZoomValue = DEFAULT_CAR_ZOOM_VALUE_1;
+ else if (CarZoomIndicator == CAM_ZOOM_1)
+ CarZoomValue = ZOOM_ONE_DISTANCE[vehArrPos];
else if(CarZoomIndicator == CAM_ZOOM_2)
- CarZoomValue = DEFAULT_CAR_ZOOM_VALUE_2;
+ CarZoomValue = ZOOM_TWO_DISTANCE[vehArrPos];
else if(CarZoomIndicator == CAM_ZOOM_3)
- CarZoomValue = DEFAULT_CAR_ZOOM_VALUE_3;
+ CarZoomValue = ZOOM_THREE_DISTANCE[vehArrPos];
if(CarZoomIndicator == CAM_ZOOM_TOPDOWN && !m_bPlayerIsInGarage){
CarZoomValue = 1.0f;
@@ -971,7 +930,7 @@ CCamera::CamControl(void)
}
// Check if we have to go into first person
- if(((CVehicle*)pTargetEntity)->IsCar() && !m_bPlayerIsInGarage){
+ if(vehType == VEHICLE_TYPE_CAR && !m_bPlayerIsInGarage){
if(CCullZones::Cam1stPersonForPlayer() &&
pTargetEntity->GetColModel()->boundingBox.GetSize().z >= 3.026f &&
pToGarageWeAreInForHackAvoidFirstPerson == nil){
@@ -1015,7 +974,8 @@ CCamera::CamControl(void)
// Fallen into water
if(Cams[ActiveCam].IsTargetInWater(Cams[ActiveCam].Source) && !boatTarget &&
- !Cams[ActiveCam].CamTargetEntity->IsPed())
+ !Cams[ActiveCam].CamTargetEntity->IsPed() &&
+ pTargetEntity->GetModelIndex() != MI_SKIMMER && pTargetEntity->GetModelIndex() != MI_SEASPAR)
ReqMode = CCam::MODE_PLAYER_FALLEN_WATER;
}
}
@@ -1025,49 +985,55 @@ CCamera::CamControl(void)
// Change user selected mode
if(CPad::GetPad(0)->CycleCameraModeUpJustDown() && !CReplay::IsPlayingBack() &&
(m_bLookingAtPlayer || WhoIsInControlOfTheCamera == CAMCONTROL_OBBE) &&
- !m_WideScreenOn && !m_bFailedCullZoneTestPreviously){
+ !m_WideScreenOn && !m_bFailedCullZoneTestPreviously && !m_bFirstPersonBeingUsed){
if(FrontEndMenuManager.m_ControlMethod == CONTROL_STANDARD){
- if(PedZoomIndicator == CAM_ZOOM_TOPDOWN)
+ if(PedZoomIndicator == CAM_ZOOM_3)
PedZoomIndicator = CAM_ZOOM_1;
else
- PedZoomIndicator = CAM_ZOOM_TOPDOWN;
+ PedZoomIndicator = CAM_ZOOM_3;
}else
PedZoomIndicator--;
}
if(CPad::GetPad(0)->CycleCameraModeDownJustDown() && !CReplay::IsPlayingBack() &&
(m_bLookingAtPlayer || WhoIsInControlOfTheCamera == CAMCONTROL_OBBE) &&
- !m_WideScreenOn && !m_bFailedCullZoneTestPreviously){
+ !m_WideScreenOn && !m_bFailedCullZoneTestPreviously && !m_bFirstPersonBeingUsed){
if(FrontEndMenuManager.m_ControlMethod == CONTROL_STANDARD){
- if(PedZoomIndicator == CAM_ZOOM_TOPDOWN)
+ if(PedZoomIndicator == CAM_ZOOM_3)
PedZoomIndicator = CAM_ZOOM_1;
else
- PedZoomIndicator = CAM_ZOOM_TOPDOWN;
+ PedZoomIndicator = CAM_ZOOM_3;
}else
PedZoomIndicator++;
}
- // disabled obbe's cam here
- if(PedZoomIndicator < CAM_ZOOM_1) PedZoomIndicator = CAM_ZOOM_TOPDOWN;
- else if(PedZoomIndicator > CAM_ZOOM_TOPDOWN) PedZoomIndicator = CAM_ZOOM_1;
+ // disabled top down and obbe's cam here
+ if(PedZoomIndicator < CAM_ZOOM_1) PedZoomIndicator = CAM_ZOOM_3;
+ else if(PedZoomIndicator > CAM_ZOOM_3) PedZoomIndicator = CAM_ZOOM_1;
ReqMode = CCam::MODE_FOLLOWPED;
// Check 1st person mode
- if(m_bLookingAtPlayer && pTargetEntity->IsPed() && !m_WideScreenOn && !Cams[0].Using3rdPersonMouseCam()
+ if((m_bLookingAtPlayer || m_bEnable1rstPersonCamCntrlsScript) && pTargetEntity->IsPed() &&
+ (!m_WideScreenOn || m_bEnable1rstPersonCamCntrlsScript) && !Cams[0].Using3rdPersonMouseCam()
#ifdef FREE_CAM
- && !CCamera::bFreeCam
+ && (!CCamera::bFreeCam || m_bEnable1rstPersonCamCntrlsScript)
#endif
){
// See if we want to enter first person mode
if(CPad::GetPad(0)->LookAroundLeftRight() || CPad::GetPad(0)->LookAroundUpDown()){
m_uiFirstPersonCamLastInputTime = CTimer::GetTimeInMilliseconds();
m_bFirstPersonBeingUsed = true;
- }else if(m_bFirstPersonBeingUsed){
+ }
+ if(m_bFirstPersonBeingUsed){
// Or if we want to go back to 3rd person
if(CPad::GetPad(0)->GetPedWalkLeftRight() || CPad::GetPad(0)->GetPedWalkUpDown() ||
CPad::GetPad(0)->GetSquare() || CPad::GetPad(0)->GetTriangle() ||
CPad::GetPad(0)->GetCross() || CPad::GetPad(0)->GetCircle() ||
- CTimer::GetTimeInMilliseconds() - m_uiFirstPersonCamLastInputTime > 2850.0f)
+ CTimer::GetTimeInMilliseconds() - m_uiFirstPersonCamLastInputTime > 2850.0f){
+ m_bFirstPersonBeingUsed = false;
+ }else if(CPad::GetPad(0)->TargetJustDown()){
m_bFirstPersonBeingUsed = false;
+ m_bJustJumpedOutOf1stPersonBecauseOfTarget = true;
+ }
}
}else
m_bFirstPersonBeingUsed = false;
@@ -1076,7 +1042,7 @@ CCamera::CamControl(void)
m_bFirstPersonBeingUsed = false;
if(m_bFirstPersonBeingUsed){
ReqMode = CCam::MODE_1STPERSON;
- CPad::GetPad(0)->SetDisablePlayerControls(PLAYERCONTROL_CAMERA);
+ CPad::GetPad(0)->DisablePlayerControls |= PLAYERCONTROL_CAMERA;
}
// Zoom value
@@ -1114,6 +1080,8 @@ CCamera::CamControl(void)
m_fPedZoomValueSmooth -= 0.12f * CTimer::GetTimeStep();
m_fPedZoomValueSmooth = Max(m_fPedZoomValueSmooth, m_fPedZoomValue);
}
+ if(PedZoomIndicator == CAM_ZOOM_3 && m_fPedZoomValue == 0.0f)
+ m_fPedZoomValueSmooth = m_fPedZoomValue;
}
WellBufferMe(CloseInPedHeightTarget, &Cams[ActiveCam].m_fCloseInPedHeightOffset, &Cams[ActiveCam].m_fCloseInPedHeightOffsetSpeed, 0.1f, 0.025f, false);
@@ -1128,15 +1096,13 @@ CCamera::CamControl(void)
}
// Garage cam
- if(CCullZones::CamStairsForPlayer() && CCullZones::FindZoneWithStairsAttributeForPlayer())
- stairs = true;
- // Some hack for Mr Whoopee in a bomb shop
- if(Cams[ActiveCam].Using3rdPersonMouseCam() && CCollision::ms_collisionInMemory == LEVEL_COMMERCIAL){
- if(pTargetEntity->GetPosition().x < 83.0f && pTargetEntity->GetPosition().x > 18.0f &&
- pTargetEntity->GetPosition().y < -305.0f && pTargetEntity->GetPosition().y > -390.0f)
- disableGarageCam = true;
+ CAttributeZone *stairsZone = nil;
+ if(CCullZones::CamStairsForPlayer()){
+ stairsZone = CCullZones::FindZoneWithStairsAttributeForPlayer();
+ if(stairsZone)
+ stairs = true;
}
- if(!disableGarageCam && (CGarages::IsPointInAGarageCameraZone(pTargetEntity->GetPosition()) || stairs)){
+ if(CGarages::IsPointInAGarageCameraZone(pTargetEntity->GetPosition()) && !m_bUseMouse3rdPerson || stairs){
if(!m_bGarageFixedCamPositionSet && m_bLookingAtPlayer){
if(pToGarageWeAreIn || stairs){
float ground;
@@ -1171,20 +1137,41 @@ CCamera::CamControl(void)
}else{
whichDoor = 1;
garageDoorPos1 = Cams[ActiveCam].Source;
+
+ if(stairsZone){ // always true
+ garageCenter = CVector((stairsZone->minx+stairsZone->maxx)/2, (stairsZone->miny+stairsZone->maxy)/2, 0.0f);
+ if(pTargetEntity->GetPosition().x > 376.0f && pTargetEntity->GetPosition().x < 383.0f &&
+ pTargetEntity->GetPosition().y > -496.0f && pTargetEntity->GetPosition().y < -489.0f &&
+ pTargetEntity->GetPosition().z > 11.6f && pTargetEntity->GetPosition().z < 13.6f){
+ garageDoorPos1 = CVector(382.6f, -489.6f, 13.1f);
+ }else{
+ bool bClearViewOutside = true;
+ CVector dirOutside = pTargetEntity->GetPosition() - garageCenter;
+ dirOutside.z = 0.0f;
+ dirOutside.Normalise();
+ float zoneDim = stairsZone->maxx - stairsZone->minx;
+ if(zoneDim < stairsZone->maxy - stairsZone->miny)
+ zoneDim = stairsZone->maxy - stairsZone->miny;
+ zoneDim *= 2.0f;
+ CVector posOutside = pTargetEntity->GetPosition() + zoneDim*dirOutside;
+ if(!CWorld::GetIsLineOfSightClear(pTargetEntity->GetPosition(), posOutside, true, false, false, false, false, false, true)){
+ posOutside = pTargetEntity->GetPosition() - zoneDim*dirOutside;
+ if(!CWorld::GetIsLineOfSightClear(pTargetEntity->GetPosition(), posOutside, true, false, false, false, false, false, true))
+ bClearViewOutside = false;
+ }
+ if(bClearViewOutside)
+ garageDoorPos1 = posOutside;
+ }
+ }
}
if(pToGarageWeAreIn){
- garageCenter.x = (pToGarageWeAreIn->m_fX1 + pToGarageWeAreIn->m_fX2)/2.0f;
- garageCenter.y = (pToGarageWeAreIn->m_fY1 + pToGarageWeAreIn->m_fY2)/2.0f;
+ garageCenter.x = pToGarageWeAreIn->GetGarageCenterX();
+ garageCenter.y = pToGarageWeAreIn->GetGarageCenterY();
garageCenter.z = 0.0f;
}else{
garageDoorPos1.z = 0.0f;
- if(stairs){
- CAttributeZone *az = CCullZones::FindZoneWithStairsAttributeForPlayer();
- garageCenter.x = (az->minx + az->maxx)/2.0f;
- garageCenter.y = (az->miny + az->maxy)/2.0f;
- garageCenter.z = 0.0f;
- }else
+ if(!stairs) // how can this be true?
garageCenter = CVector(pTargetEntity->GetPosition().x, pTargetEntity->GetPosition().y, 0.0f);
}
if(whichDoor == 1)
@@ -1198,9 +1185,15 @@ CCamera::CamControl(void)
garageCenterToDoor.z = 0.0f;
garageCenterToDoor.Normalise();
if(whichDoor == 1){
- if(pToGarageWeAreIn == nil && stairs)
- garageCamPos = garageDoorPos1 + 3.75f*garageCenterToDoor;
- else
+ if(pToGarageWeAreIn == nil && stairs){
+ if(stairsZone){
+ float zoneDim = stairsZone->maxx - stairsZone->minx;
+ if(zoneDim < stairsZone->maxy - stairsZone->miny)
+ zoneDim = stairsZone->maxy - stairsZone->miny;
+ garageCamPos = garageCenter + (0.7f*zoneDim + 3.75f)*garageCenterToDoor;
+ }else // how can this be true?
+ garageCamPos = garageDoorPos1 + 3.75f*garageCenterToDoor;
+ }else
garageCamPos = garageDoorPos1 + 13.0f*garageCenterToDoor;
}else{
garageCamPos = garageDoorPos2 + 13.0f*garageCenterToDoor;
@@ -1208,8 +1201,8 @@ CCamera::CamControl(void)
if(PedZoomIndicator == CAM_ZOOM_TOPDOWN && !stairs){
garageCamPos = garageCenter;
garageCamPos.z += FindPlayerPed()->GetPosition().z + 2.1f;
- if(pToGarageWeAreIn && garageCamPos.z > pToGarageWeAreIn->m_fX2) // What?
- garageCamPos.z = pToGarageWeAreIn->m_fX2;
+ if(pToGarageWeAreIn && garageCamPos.z > pToGarageWeAreIn->m_fSupX) // What?
+ garageCamPos.z = pToGarageWeAreIn->m_fSupX;
}else
garageCamPos.z = ground + 3.1f;
SetCamPositionForFixedMode(garageCamPos, CVector(0.0f, 0.0f, 0.0f));
@@ -1237,6 +1230,13 @@ CCamera::CamControl(void)
m_bGarageFixedCamPositionSet = false;
}
+ // Lighthouse
+ if(!m_bFirstPersonBeingUsed && (pTargetEntity->GetPosition() - CVector(474.3f, -1717.6f, 0.0f)).Magnitude2D() < 6.0f)
+ if((pTargetEntity->GetPosition() - CVector(474.3f, -1717.6f, 0.0f)).Magnitude2D() < 3.8f ||
+ pTargetEntity->GetPosition().z > 50.0f)
+ if(!Cams[ActiveCam].Using3rdPersonMouseCam())
+ ReqMode = CCam::MODE_LIGHTHOUSE;
+
// Fallen into water
if(Cams[ActiveCam].IsTargetInWater(Cams[ActiveCam].Source) &&
Cams[ActiveCam].CamTargetEntity->IsPed())
@@ -1259,8 +1259,10 @@ CCamera::CamControl(void)
if(PlayerWeaponMode.Mode != CCam::MODE_NONE && !stairs){
if(PlayerWeaponMode.Mode == CCam::MODE_SNIPER ||
PlayerWeaponMode.Mode == CCam::MODE_ROCKETLAUNCHER ||
+ // game also checks MODE_MODELVIEW here but that does make any sense...
PlayerWeaponMode.Mode == CCam::MODE_M16_1STPERSON ||
PlayerWeaponMode.Mode == CCam::MODE_HELICANNON_1STPERSON ||
+ PlayerWeaponMode.Mode == CCam::MODE_CAMERA ||
Cams[ActiveCam].GetWeaponFirstPersonOn()){
// First person weapon mode
if(PLAYER->GetPedState() == PED_SEEK_CAR){
@@ -1270,7 +1272,7 @@ CCamera::CamControl(void)
ReqMode = CCam::MODE_FOLLOWPED;
}else
ReqMode = PlayerWeaponMode.Mode;
- }else if(ReqMode != CCam::MODE_TOP_DOWN_PED){
+ }else if(ReqMode != CCam::MODE_TOP_DOWN_PED && PedZoomIndicator != CAM_ZOOM_3){
// Syphon mode
float playerTargetDist;
float deadPedDist = 4.0f;
@@ -1312,7 +1314,7 @@ CCamera::CamControl(void)
if(ReqMode == CCam::MODE_SYPHON_CRIM_IN_FRONT)
fixedModeDist = 5.0f;
else
- fixedModeDist = 3.0f;
+ fixedModeDist = 5.6f;
ReqMode = CCam::MODE_SPECIAL_FIXED_FOR_SYPHON;
}
if(ReqMode == CCam::MODE_SPECIAL_FIXED_FOR_SYPHON){
@@ -1338,8 +1340,6 @@ CCamera::CamControl(void)
}
}
- m_bIdleOn = false;
-
if(DebugCamMode)
ReqMode = DebugCamMode;
@@ -1348,56 +1348,66 @@ CCamera::CamControl(void)
static int ThePickedArrestMode;
static int LastPedState;
bool startArrestCam = false;
+ static bool beingArrested = false;
+ bool stopArrestCam = false;
+ if(PLAYER->GetPedState() == PED_ARRESTED)
+ beingArrested = true;
+ else if(beingArrested){
+ stopArrestCam = true;
+ beingArrested = false;
+ }
if(LastPedState != PED_ARRESTED && PLAYER->GetPedState() == PED_ARRESTED){
- if(CarZoomIndicator != CAM_ZOOM_1STPRS && pTargetEntity->IsVehicle())
+ if(CarZoomIndicator != CAM_ZOOM_1STPRS || !pTargetEntity->IsVehicle())
startArrestCam = true;
}else
startArrestCam = false;
LastPedState = PLAYER->GetPedState();
+
if(startArrestCam){
- if(m_uiTransitionState)
- ReqMode = Cams[ActiveCam].Mode;
- else{
- bool valid;
- if(pTargetEntity->IsPed()){
- // How can this happen if arrest cam is only done in cars?
- Cams[(ActiveCam+1)%2].ResetStatics = true;
- valid = Cams[(ActiveCam+1)%2].ProcessArrestCamOne();
- ReqMode = CCam::MODE_ARRESTCAM_ONE;
- }else{
- Cams[(ActiveCam+1)%2].ResetStatics = true;
- valid = Cams[(ActiveCam+1)%2].ProcessArrestCamTwo();
- ReqMode = CCam::MODE_ARRESTCAM_TWO;
- }
- if(!valid)
- ReqMode = Cams[ActiveCam].Mode;
- }
- }
- ThePickedArrestMode = ReqMode;
- if(PLAYER->GetPedState() == PED_ARRESTED)
- ReqMode = ThePickedArrestMode; // this is rather useless...
+ ThePickedArrestMode = CCam::MODE_ARRESTCAM_ONE;
+ ReqMode = CCam::MODE_ARRESTCAM_ONE;
+ Cams[ActiveCam].ResetStatics = true;
+ }else if(PLAYER->GetPedState() == PED_ARRESTED)
+ ReqMode = ThePickedArrestMode;
// Process dead player
if(PLAYER->GetPedState() == PED_DEAD){
if(Cams[ActiveCam].Mode == CCam::MODE_PED_DEAD_BABY)
ReqMode = CCam::MODE_PED_DEAD_BABY;
else{
- bool foundRoof;
- CVector pos = FindPlayerPed()->GetPosition();
- CWorld::FindRoofZFor3DCoord(pos.x, pos.y, pos.z, &foundRoof);
- if(!foundRoof)
+ bool useArrestCam = false;
+ if(pTargetEntity->IsPed()){
+ for(int i = 0; i < ((CPed*)pTargetEntity)->m_numNearPeds; i++){
+ CPed *ped = ((CPed*)pTargetEntity)->m_nearPeds[i];
+ if(ped && ped->GetPedState() == PED_ARREST_PLAYER)
+ if((ped->GetPosition() - pTargetEntity->GetPosition()).Magnitude() < 4.0f){
+ ReqMode = CCam::MODE_ARRESTCAM_ONE;
+ Cams[ActiveCam].ResetStatics = true;
+ useArrestCam = true;
+ break;
+ }
+ }
+ }
+ if(!useArrestCam){
ReqMode = CCam::MODE_PED_DEAD_BABY;
+ Cams[ActiveCam].ResetStatics = true;
+ }
}
}
// Restore with a jump cut
if(m_bRestoreByJumpCut){
- // PS2 just sets m_bCamDirectlyBehind here
if(ReqMode != CCam::MODE_FOLLOWPED &&
+ ReqMode != CCam::MODE_BEHINDCAR &&
+ ReqMode != CCam::MODE_CAM_ON_A_STRING &&
ReqMode != CCam::MODE_M16_1STPERSON &&
+ ReqMode != CCam::MODE_SYPHON &&
+ ReqMode != CCam::MODE_SYPHON_CRIM_IN_FRONT &&
+ ReqMode != CCam::MODE_SPECIAL_FIXED_FOR_SYPHON &&
ReqMode != CCam::MODE_SNIPER &&
- ReqMode != CCam::MODE_ROCKETLAUNCHER ||
+ ReqMode != CCam::MODE_ROCKETLAUNCHER &&
+ ReqMode != CCam::MODE_CAMERA &&
!m_bUseMouse3rdPerson)
SetCameraDirectlyBehindForFollowPed_CamOnAString();
@@ -1409,7 +1419,6 @@ CCamera::CamControl(void)
Cams[ActiveCam].CamTargetEntity = pTargetEntity;
Cams[ActiveCam].m_cvecCamFixedModeSource = m_vecFixedModeSource;
Cams[ActiveCam].m_cvecCamFixedModeUpOffSet = m_vecFixedModeUpOffSet;
- // PS2 sets this to m_bLookingAtVector
Cams[ActiveCam].m_bCamLookingAtVector = false;
Cams[ActiveCam].m_vecLastAboveWaterCamPosition = Cams[(ActiveCam+1)%2].m_vecLastAboveWaterCamPosition;
m_bRestoreByJumpCut = false;
@@ -1443,16 +1452,20 @@ CCamera::CamControl(void)
ReqMode == CCam::MODE_SNIPER || ReqMode == CCam::MODE_ROCKETLAUNCHER || ReqMode == CCam::MODE_M16_1STPERSON ||
ReqMode == CCam::MODE_SNIPER_RUNABOUT || ReqMode == CCam::MODE_ROCKETLAUNCHER_RUNABOUT ||
ReqMode == CCam::MODE_1STPERSON_RUNABOUT || ReqMode == CCam::MODE_M16_1STPERSON_RUNABOUT ||
- ReqMode == CCam::MODE_FIGHT_CAM_RUNABOUT || ReqMode == CCam::MODE_HELICANNON_1STPERSON ||
+ ReqMode == CCam::MODE_FIGHT_CAM_RUNABOUT || ReqMode == CCam::MODE_HELICANNON_1STPERSON || ReqMode == CCam::MODE_CAMERA ||
WhoIsInControlOfTheCamera == CAMCONTROL_SCRIPT ||
m_bJustCameOutOfGarage || m_bPlayerIsInGarage)
canUseObbeCam = false;
if(m_bObbeCinematicPedCamOn && canUseObbeCam)
ProcessObbeCinemaCameraPed();
- else if(m_bObbeCinematicCarCamOn && canUseObbeCam)
- ProcessObbeCinemaCameraCar();
- else{
+ else if(m_bObbeCinematicCarCamOn && canUseObbeCam){
+ if(pTargetEntity->IsVehicle() && ((CVehicle*)pTargetEntity)->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI ||
+ ((CVehicle*)pTargetEntity)->IsBoat())
+ ProcessObbeCinemaCameraHeli();
+ else
+ ProcessObbeCinemaCameraCar();
+ }else{
if(m_bPlayerIsInGarage && m_bObbeCinematicCarCamOn)
switchByJumpCut = true;
canUseObbeCam = false;
@@ -1476,6 +1489,10 @@ CCamera::CamControl(void)
switchByJumpCut = true;
}
+ // Going into Syphon mode
+ if(ReqMode == CCam::MODE_SYPHON || ReqMode == CCam::MODE_SYPHON_CRIM_IN_FRONT)
+ switchByJumpCut = true;
+
// Top down modes can interpolate between each other
if(ReqMode == CCam::MODE_TOPDOWN){
if(Cams[ActiveCam].Mode == CCam::MODE_TOP_DOWN_PED || Cams[ActiveCam].Mode == CCam::MODE_PED_DEAD_BABY)
@@ -1490,7 +1507,7 @@ CCamera::CamControl(void)
ReqMode == CCam::MODE_SNIPER_RUNABOUT || ReqMode == CCam::MODE_ROCKETLAUNCHER_RUNABOUT ||
ReqMode == CCam::MODE_1STPERSON_RUNABOUT || ReqMode == CCam::MODE_M16_1STPERSON_RUNABOUT ||
ReqMode == CCam::MODE_FIGHT_CAM_RUNABOUT ||
- ReqMode == CCam::MODE_HELICANNON_1STPERSON ||
+ ReqMode == CCam::MODE_HELICANNON_1STPERSON || ReqMode == CCam::MODE_CAMERA ||
ReqMode == CCam::MODE_ARRESTCAM_ONE || ReqMode == CCam::MODE_ARRESTCAM_TWO){
// Going into any 1st person mode is a jump cut
if(pTargetEntity->IsPed())
@@ -1508,11 +1525,16 @@ CCamera::CamControl(void)
Cams[ActiveCam].Mode == CCam::MODE_ROCKETLAUNCHER_RUNABOUT ||
Cams[ActiveCam].Mode == CCam::MODE_M16_1STPERSON_RUNABOUT ||
Cams[ActiveCam].Mode == CCam::MODE_FIGHT_CAM_RUNABOUT ||
- Cams[ActiveCam].Mode == CCam::MODE_1STPERSON_RUNABOUT){
+ Cams[ActiveCam].Mode == CCam::MODE_1STPERSON_RUNABOUT ||
+ Cams[ActiveCam].Mode == CCam::MODE_CAMERA){
if(pTargetEntity && pTargetEntity->IsVehicle())
switchByJumpCut = true;
}
}else if(ReqMode == CCam::MODE_FOLLOWPED){
+ bool syphonJumpCut = false;
+ if(Cams[ActiveCam].Mode == CCam::MODE_SYPHON || Cams[ActiveCam].Mode == CCam::MODE_SYPHON_CRIM_IN_FRONT)
+ if(!((CPed*)pTargetEntity)->CanWeRunAndFireWithWeapon())
+ syphonJumpCut = true;
if(Cams[ActiveCam].Mode == CCam::MODE_1STPERSON ||
Cams[ActiveCam].Mode == CCam::MODE_SNIPER ||
Cams[ActiveCam].Mode == CCam::MODE_ROCKETLAUNCHER ||
@@ -1527,8 +1549,10 @@ CCamera::CamControl(void)
Cams[ActiveCam].Mode == CCam::MODE_M16_1STPERSON_RUNABOUT ||
Cams[ActiveCam].Mode == CCam::MODE_FIGHT_CAM_RUNABOUT ||
Cams[ActiveCam].Mode == CCam::MODE_HELICANNON_1STPERSON ||
+ Cams[ActiveCam].Mode == CCam::MODE_CAMERA ||
Cams[ActiveCam].Mode == CCam::MODE_TOPDOWN ||
- Cams[ActiveCam].Mode == CCam::MODE_TOP_DOWN_PED){
+ Cams[ActiveCam].Mode == CCam::MODE_TOP_DOWN_PED ||
+ syphonJumpCut || stopArrestCam){
if(!m_bJustCameOutOfGarage){
if(Cams[ActiveCam].Mode == CCam::MODE_1STPERSON ||
Cams[ActiveCam].Mode == CCam::MODE_SNIPER ||
@@ -1539,7 +1563,8 @@ CCamera::CamControl(void)
Cams[ActiveCam].Mode == CCam::MODE_1STPERSON_RUNABOUT ||
Cams[ActiveCam].Mode == CCam::MODE_M16_1STPERSON_RUNABOUT ||
Cams[ActiveCam].Mode == CCam::MODE_FIGHT_CAM_RUNABOUT ||
- Cams[ActiveCam].Mode == CCam::MODE_HELICANNON_1STPERSON){
+ Cams[ActiveCam].Mode == CCam::MODE_HELICANNON_1STPERSON ||
+ Cams[ActiveCam].Mode == CCam::MODE_CAMERA){
float angle = CGeneral::GetATanOfXY(Cams[ActiveCam].Front.x, Cams[ActiveCam].Front.y) - HALFPI;
((CPed*)pTargetEntity)->m_fRotationCur = angle;
((CPed*)pTargetEntity)->m_fRotationDest = angle;
@@ -1548,7 +1573,7 @@ CCamera::CamControl(void)
switchByJumpCut = true;
if(Cams[ActiveCam].Mode == CCam::MODE_TOP_DOWN_PED){
CVector front = Cams[ActiveCam].Source - FindPlayerPed()->GetPosition();
- front.z = 0.0f; // missing on PS2
+ front.z = 0.0f;
front.Normalise();
#ifdef FIX_BUGS
// this is almost as bad as the bugged code
@@ -1567,7 +1592,12 @@ CCamera::CamControl(void)
}else if(ReqMode == CCam::MODE_FIGHT_CAM){
if(Cams[ActiveCam].Mode == CCam::MODE_1STPERSON)
switchByJumpCut = true;
- }
+ }else if(ReqMode == CCam::MODE_LIGHTHOUSE ||
+ ReqMode == CCam::MODE_ARRESTCAM_ONE || ReqMode == CCam::MODE_ARRESTCAM_TWO ||
+ ReqMode == CCam::MODE_PED_DEAD_BABY)
+ switchByJumpCut = true;
+ else if(Cams[ActiveCam].Mode == CCam::MODE_PED_DEAD_BABY && ReqMode != CCam::MODE_PED_DEAD_BABY)
+ switchByJumpCut = true;
if(ReqMode != Cams[ActiveCam].Mode && Cams[ActiveCam].CamTargetEntity == nil)
switchByJumpCut = true;
@@ -1587,12 +1617,11 @@ CCamera::CamControl(void)
if((m_uiTransitionState == 0 || switchByJumpCut) && ReqMode != Cams[ActiveCam].Mode){
if(switchByJumpCut){
- // PS2 just sets m_bCamDirectlyBehind here
if(!m_bPlayerIsInGarage || m_bJustCameOutOfGarage){
if(ReqMode != CCam::MODE_FOLLOWPED &&
ReqMode != CCam::MODE_M16_1STPERSON &&
ReqMode != CCam::MODE_SNIPER &&
- ReqMode != CCam::MODE_ROCKETLAUNCHER ||
+ ReqMode != CCam::MODE_ROCKETLAUNCHER &&
!m_bUseMouse3rdPerson)
SetCameraDirectlyBehindForFollowPed_CamOnAString();
}
@@ -1626,8 +1655,6 @@ CCamera::CamControl(void)
if(ReqMode == CCam::MODE_FOLLOWPED && Cams[ActiveCam].Mode == CCam::MODE_FIGHT_CAM)
startTransition = false;
-#ifndef PS2_CAM_TRANSITION
- // done in Process on PS2
if(!m_bWaitForInterpolToFinish && m_bLookingAtPlayer && m_uiTransitionState != 0){
CVector playerDist;
playerDist.x = FindPlayerPed()->GetPosition().x - GetPosition().x;
@@ -1640,7 +1667,6 @@ CCamera::CamControl(void)
m_bWaitForInterpolToFinish = true;
}
}
-#endif
if(m_bWaitForInterpolToFinish)
startTransition = false;
@@ -1650,19 +1676,32 @@ CCamera::CamControl(void)
Cams[ActiveCam].CamTargetEntity->RegisterReference(&Cams[ActiveCam].CamTargetEntity);
}
}else if(ReqMode == CCam::MODE_FIXED && pTargetEntity != Cams[ActiveCam].CamTargetEntity && m_bPlayerIsInGarage){
-#ifdef PS2_CAM_TRANSITION
- StartTransitionWhenNotFinishedInter(ReqMode);
-#else
if(m_uiTransitionState != 0)
StartTransitionWhenNotFinishedInter(ReqMode);
else
StartTransition(ReqMode);
-#endif
pTargetEntity->RegisterReference(&pTargetEntity);
Cams[ActiveCam].CamTargetEntity->RegisterReference(&Cams[ActiveCam].CamTargetEntity);
}
}else{
// not following player
+ bool useWeaponMode = false;
+ bool jumpCutTo1stPrs = false;
+ if(m_bEnable1rstPersonCamCntrlsScript || m_bAllow1rstPersonWeaponsCamera){
+ if(ReqMode == CCam::MODE_1STPERSON){
+ if(Cams[ActiveCam].Mode != ReqMode)
+ jumpCutTo1stPrs = true;
+ }else if((PlayerWeaponMode.Mode == CCam::MODE_SNIPER || PlayerWeaponMode.Mode == CCam::MODE_1STPERSON || PlayerWeaponMode.Mode == CCam::MODE_ROCKETLAUNCHER) &&
+ CPad::GetPad(0)->GetTarget() && m_bAllow1rstPersonWeaponsCamera){
+ useWeaponMode = true;
+ jumpCutTo1stPrs = true;
+ }else if(Cams[ActiveCam].Mode != m_iModeToGoTo){
+ m_bStartInterScript = true;
+ m_iTypeOfSwitch = JUMP_CUT;
+ CPad::GetPad(0)->DisablePlayerControls &= ~PLAYERCONTROL_CAMERA;
+ }
+ }
+
if(m_uiTransitionState == 0 && m_bStartInterScript && m_iTypeOfSwitch == INTERPOLATION){
ReqMode = m_iModeToGoTo;
StartTransition(ReqMode);
@@ -1673,10 +1712,15 @@ CCamera::CamControl(void)
StartTransitionWhenNotFinishedInter(ReqMode);
pTargetEntity->RegisterReference(&pTargetEntity);
Cams[ActiveCam].CamTargetEntity->RegisterReference(&Cams[ActiveCam].CamTargetEntity);
- }else if(m_bStartInterScript && m_iTypeOfSwitch == JUMP_CUT){
+ }else if(m_bStartInterScript && m_iTypeOfSwitch == JUMP_CUT || jumpCutTo1stPrs){
m_uiTransitionState = 0;
m_vecDoingSpecialInterPolation = false;
- Cams[ActiveCam].Mode = m_iModeToGoTo;
+ if(m_bEnable1rstPersonCamCntrlsScript && ReqMode == CCam::MODE_1STPERSON)
+ Cams[ActiveCam].Mode = ReqMode;
+ else if(useWeaponMode)
+ Cams[ActiveCam].Mode = PlayerWeaponMode.Mode;
+ else
+ Cams[ActiveCam].Mode = m_iModeToGoTo;
m_bJust_Switched = true;
Cams[ActiveCam].ResetStatics = true;
Cams[ActiveCam].m_cvecCamFixedModeVector = m_vecFixedModeVector;
@@ -1702,23 +1746,42 @@ CCamera::CamControl(void)
if((Cams[ActiveCam].Mode == CCam::MODE_1STPERSON ||
Cams[ActiveCam].Mode == CCam::MODE_SNIPER ||
Cams[ActiveCam].Mode == CCam::MODE_M16_1STPERSON ||
- Cams[ActiveCam].Mode == CCam::MODE_ROCKETLAUNCHER) && pTargetEntity->IsPed() ||
+ Cams[ActiveCam].Mode == CCam::MODE_ROCKETLAUNCHER ||
+ Cams[ActiveCam].Mode == CCam::MODE_HELICANNON_1STPERSON ||
+ Cams[ActiveCam].Mode == CCam::MODE_CAMERA) && pTargetEntity->IsPed() ||
Cams[ActiveCam].Mode == CCam::MODE_FLYBY)
FindPlayerPed()->bIsVisible = false;
else
FindPlayerPed()->bIsVisible = true;
- if(!canUseObbeCam && WhoIsInControlOfTheCamera == CAMCONTROL_OBBE)
- Restore();
+ bool switchedFromObbe = false;
+ if(!canUseObbeCam && WhoIsInControlOfTheCamera == CAMCONTROL_OBBE){
+ RestoreWithJumpCut();
+ switchedFromObbe = true;
+ SetCameraDirectlyBehindForFollowPed_CamOnAString();
+ }
+
+ if(PrevMode != Cams[ActiveCam].Mode || switchedFromObbe ||
+ Cams[ActiveCam].Mode == CCam::MODE_FOLLOWPED || Cams[ActiveCam].Mode == CCam::MODE_CAM_ON_A_STRING)
+ if(CPad::GetPad(0)->CycleCameraModeJustDown() &&
+ !CReplay::IsPlayingBack() &&
+ (m_bLookingAtPlayer || WhoIsInControlOfTheCamera == CAMCONTROL_OBBE) &&
+ !m_WideScreenOn &&
+ (WhoIsInControlOfTheCamera != CAMCONTROL_OBBE || bSwitchedToObbeCam))
+ DMAudio.PlayFrontEndSound(SOUND_HUD, 0);
}
// What a mess!
void
CCamera::UpdateTargetEntity(void)
{
- bool enteringCar = false; // not on PS2 but only used as && !enteringCar so we can keep it
+ bool enteringCar = false;
bool obbeCam = false;
+ m_bPlayerWasOnBike = false;
+ if(pTargetEntity && pTargetEntity->IsVehicle() && ((CVehicle*)pTargetEntity)->IsBike())
+ m_bPlayerWasOnBike = true;
+
if(WhoIsInControlOfTheCamera == CAMCONTROL_OBBE){
obbeCam = true;
if(m_iModeObbeCamIsInForCar == OBBE_COPCAR_WHEEL || m_iModeObbeCamIsInForCar == OBBE_COPCAR){
@@ -1736,7 +1799,6 @@ CCamera::UpdateTargetEntity(void)
pTargetEntity = FindPlayerVehicle();
else{
pTargetEntity = FindPlayerPed();
-#ifndef GTA_PS2_STUFF
// this keeps the camera on the player while entering cars
if(PLAYER->GetPedState() == PED_ENTER_CAR ||
PLAYER->GetPedState() == PED_CARJACK ||
@@ -1746,14 +1808,21 @@ CCamera::UpdateTargetEntity(void)
if(!enteringCar)
if(Cams[ActiveCam].CamTargetEntity != pTargetEntity)
Cams[ActiveCam].CamTargetEntity = pTargetEntity;
-#endif
}
bool cantOpen = true;
- if(PLAYER &&
- PLAYER->m_pMyVehicle &&
- PLAYER->m_pMyVehicle->CanPedOpenLocks(PLAYER))
- cantOpen = false;
+ if(PLAYER){
+ if(PLAYER->m_pMyVehicle){
+ if(FindPlayerPed()->m_pMyVehicle->CanPedOpenLocks(PLAYER))
+ cantOpen = false;
+ }else if(FindPlayerPed()->m_carInObjective &&
+ (FindPlayerPed()->GetPedState() == PED_ENTER_CAR ||
+ FindPlayerPed()->GetPedState() == PED_CARJACK ||
+ FindPlayerPed()->GetPedState() == PED_OPEN_DOOR)){
+ if(FindPlayerPed()->m_carInObjective->CanPedOpenLocks(FindPlayerPed()))
+ cantOpen = false;
+ }
+ }
if(PLAYER->GetPedState() == PED_ENTER_CAR && !cantOpen){
if(!enteringCar && CarZoomIndicator != CAM_ZOOM_1STPRS){
@@ -1765,16 +1834,9 @@ CCamera::UpdateTargetEntity(void)
if((PLAYER->GetPedState() == PED_CARJACK || PLAYER->GetPedState() == PED_OPEN_DOOR) && !cantOpen){
if(!enteringCar && CarZoomIndicator != CAM_ZOOM_1STPRS)
-#ifdef GTA_PS2_STUFF
-// dunno if this has any amazing effects
- {
-#endif
pTargetEntity = PLAYER->m_pMyVehicle;
if(PLAYER->m_pMyVehicle == nil)
pTargetEntity = PLAYER;
-#ifdef GTA_PS2_STUFF
- }
-#endif
}
if(PLAYER->GetPedState() == PED_EXIT_CAR)
@@ -1805,6 +1867,7 @@ CCamera::UpdateSoundDistances(void)
Cams[ActiveCam].Mode == CCam::MODE_M16_1STPERSON_RUNABOUT ||
Cams[ActiveCam].Mode == CCam::MODE_FIGHT_CAM_RUNABOUT ||
Cams[ActiveCam].Mode == CCam::MODE_HELICANNON_1STPERSON ||
+ Cams[ActiveCam].Mode == CCam::MODE_CAMERA ||
Cams[ActiveCam].Mode == CCam::MODE_M16_1STPERSON ||
Cams[ActiveCam].Mode == CCam::MODE_ROCKETLAUNCHER) &&
pTargetEntity->IsPed())
@@ -1823,33 +1886,6 @@ CCamera::UpdateSoundDistances(void)
}
f = (n + 1) / 6.0f;
SoundDistUp = (1.0f-f)*SoundDistUpAsReadOld + f*SoundDistUpAsRead;
-
- // check left
- n = (CTimer::GetFrameCounter()+2) % 12;
- if(n == 0){
- SoundDistLeftAsReadOld = SoundDistLeftAsRead;
- end = center + SOUND_DIST*GetRight();
- if(CWorld::ProcessLineOfSight(center, end, colPoint, entity, true, false, false, false, true, true, true))
- SoundDistLeftAsRead = (colPoint.point - center).Magnitude();
- else
- SoundDistLeftAsRead = SOUND_DIST;
- }
- f = (n + 1) / 6.0f;
- SoundDistLeft = (1.0f-f)*SoundDistLeftAsReadOld + f*SoundDistLeftAsRead;
-
- // check right
- // end = center - SOUND_DIST*GetRight(); // useless
- n = (CTimer::GetFrameCounter()+4) % 12;
- if(n == 0){
- SoundDistRightAsReadOld = SoundDistRightAsRead;
- end = center - SOUND_DIST*GetRight();
- if(CWorld::ProcessLineOfSight(center, end, colPoint, entity, true, false, false, false, true, true, true))
- SoundDistRightAsRead = (colPoint.point - center).Magnitude();
- else
- SoundDistRightAsRead = SOUND_DIST;
- }
- f = (n + 1) / 6.0f;
- SoundDistRight = (1.0f-f)*SoundDistRightAsReadOld + f*SoundDistRightAsRead;
}
void
@@ -1894,6 +1930,147 @@ CamShakeNoPos(CCamera *cam, float strength)
}
}
+bool bAvoidTest1 = false;
+bool bAvoidTest2 = false; // unused
+bool bAvoidTest3 = false; // unused
+float fRangePlayerRadius = 0.5f;
+float fCloseNearClipLimit = 0.15f;
+float fAvoidTweakFOV = 1.15f;
+float fAvoidProbTimerDamp = 0.9f;
+
+void
+CCamera::AvoidTheGeometry(const CVector &Source, const CVector &TargetPos, CVector &NewSource, float FOV)
+{
+ float Beta = 0.0f;
+ float Alpha = 0.0f;
+
+ CVector vDist = TargetPos - Source;
+ m_vecClearGeometryVec = CVector(0.0f, 0.0f, 0.0f);
+ float fDist = vDist.Magnitude();
+ float fDistOnGround = vDist.Magnitude2D();
+ if(vDist.x == 0.0f && vDist.y == 0.0f)
+ Beta = CGeneral::GetATanOfXY(GetForward().x, GetForward().y);
+ else
+ Beta = CGeneral::GetATanOfXY(vDist.x, vDist.y);
+ if(fDistOnGround != 0.0f || vDist.z != 0.0f)
+ Alpha = CGeneral::GetATanOfXY(fDistOnGround, vDist.z);
+ CVector Front(Cos(Alpha)*Cos(Beta), Cos(Alpha)*Sin(Beta), Sin(Alpha));
+ NewSource = TargetPos - Front*fDist;
+ Front.Normalise();
+
+ // Clip camera source
+ CColPoint point;
+ CEntity *entity = nil;
+ CWorld::pIgnoreEntity = pTargetEntity;
+ if(CWorld::ProcessLineOfSight(TargetPos, NewSource, point, entity, true, false, false, true, false, false, true)){
+ CVector ClipPoint1 = point.point;
+ NewSource = point.point;
+ if(!bAvoidTest1){
+ if(CWorld::ProcessLineOfSight(NewSource, TargetPos, point, entity, false, true, true, true, false, false, true)){
+ if((NewSource - point.point).Magnitude() < RwCameraGetNearClipPlane(Scene.camera))
+ NewSource = point.point;
+ else if((NewSource - ClipPoint1).Magnitude() < RwCameraGetNearClipPlane(Scene.camera))
+ NewSource = ClipPoint1;
+ }
+ }
+ }
+ CWorld::pIgnoreEntity = nil;
+
+
+ vDist = TargetPos - NewSource;
+ fDist = vDist.Magnitude();
+ if(FindPlayerPed())
+ if(fDist - fRangePlayerRadius < RwCameraGetNearClipPlane(Scene.camera))
+ RwCameraSetNearClipPlane(Scene.camera, Max(fDist - fRangePlayerRadius, fCloseNearClipLimit));
+
+
+ static float fClearGeomAmount;
+ static float fClearGeomAmountSpeed;
+ float Near = RwCameraGetNearClipPlane(Scene.camera);
+ float ViewPlaneHeight = Tan(DEGTORAD(FOV) / 2.0f);
+ float ViewPlaneWidth = ViewPlaneHeight * CDraw::CalculateAspectRatio() * fAvoidTweakFOV;
+ CVector Center = NewSource + Front*Near;
+ float fClearGeomTarget = 0.0f;
+ if(CWorld::TestSphereAgainstWorld(Center, ViewPlaneWidth, nil, true, false, false, true, false, true)){
+ CVector CamToCol = gaTempSphereColPoints[0].point - NewSource;
+ float FrontDist = DotProduct(CamToCol, Front);
+ CVector CenterToCol = gaTempSphereColPoints[0].point - Center;
+ if(FrontDist < DEFAULT_NEAR && FrontDist > fCloseNearClipLimit){
+ if(FrontDist < RwCameraGetNearClipPlane(Scene.camera))
+ RwCameraSetNearClipPlane(Scene.camera, FrontDist);
+ }else if(FrontDist < fCloseNearClipLimit)
+ RwCameraSetNearClipPlane(Scene.camera, fCloseNearClipLimit);
+
+ float ColDepth = ViewPlaneWidth - CenterToCol.Magnitude(); // amount of radius in collision
+ CenterToCol.Normalise();
+ CVector Normal = gaTempSphereColPoints[0].normal;
+ Normal.Normalise();
+ if(-DotProduct(CenterToCol, Normal) < 0.0f)
+ Normal = -Normal; // always push away from col surface
+ float DistToMove = DotProduct(-ColDepth*CenterToCol, Normal);
+ m_vecClearGeometryVec = DistToMove*Normal; // move source so this point is out of collision
+
+ if(pTargetEntity && pTargetEntity->IsPed() && RwCameraGetNearClipPlane(Scene.camera) < 2.0f*fCloseNearClipLimit){
+ float TargetNormalDir = DotProduct(Normal, pTargetEntity->GetForward());
+ if(TargetNormalDir < 0.0f){
+ // target looking towards collision
+ if(m_fAvoidTheGeometryProbsTimer < 0.0f)
+ m_fAvoidTheGeometryProbsTimer = 0.0f;
+ m_fAvoidTheGeometryProbsTimer += CTimer::GetTimeStep();
+ }else if(TargetNormalDir > 0.5f){
+ // target looking away from collision
+ if(m_fAvoidTheGeometryProbsTimer > 0.0f)
+ m_fAvoidTheGeometryProbsTimer = 0.0f;
+ m_fAvoidTheGeometryProbsTimer -= CTimer::GetTimeStep();
+ }
+
+ if(m_nAvoidTheGeometryProbsDirn == 0){
+ if(CrossProduct(pTargetEntity->GetPosition() - NewSource, Normal).z > 0.0f)
+ m_nAvoidTheGeometryProbsDirn = -1;
+ else
+ m_nAvoidTheGeometryProbsDirn = 1;
+ }
+ }
+
+ fClearGeomTarget = 1.0f;
+ }
+
+ m_fAvoidTheGeometryProbsTimer *= Pow(fAvoidProbTimerDamp, CTimer::GetTimeStep());
+ WellBufferMe(fClearGeomTarget, &fClearGeomAmount, &fClearGeomAmountSpeed, 0.2f, 0.05f, false);
+ m_vecClearGeometryVec *= fClearGeomAmount;
+ m_bMoveCamToAvoidGeom = true;
+}
+
+void
+CCamera::GetArrPosForVehicleType(int apperance, int &index)
+{
+ switch(apperance){
+ case VEHICLE_APPEARANCE_CAR: index = 0; break;
+ case VEHICLE_APPEARANCE_BIKE: index = 1; break;
+ case VEHICLE_APPEARANCE_HELI: index = 2; break;
+ case VEHICLE_APPEARANCE_PLANE: index = 3; break;
+ case VEHICLE_APPEARANCE_BOAT: index = 4; break;
+ }
+}
+
+void
+CCamera::GetScreenRect(CRect &rect)
+{
+ rect.left = 0.0f;
+ rect.right = SCREEN_WIDTH;
+ if(m_WideScreenOn
+#ifdef CUTSCENE_BORDERS_SWITCH
+ && CMenuManager::m_PrefsCutsceneBorders
+#endif
+ ){
+ float borderSize = (SCREEN_HEIGHT / 2) * (m_ScreenReductionPercentage / 100.f);
+ rect.top = borderSize - SCREEN_SCALE_Y(22.f);
+ rect.bottom = SCREEN_HEIGHT - borderSize - SCREEN_SCALE_Y(14.f);
+ }else{
+ rect.top = 0.0f;
+ rect.bottom = SCREEN_HEIGHT;
+ }
+}
void
@@ -1923,7 +2100,6 @@ CCamera::TakeControl(CEntity *target, int16 mode, int16 typeOfSwitch, int32 cont
m_iTypeOfSwitch = typeOfSwitch;
m_bLookingAtPlayer = false;
m_bStartInterScript = true;
- // FindPlayerPed(); // unused
}
}
@@ -1953,8 +2129,6 @@ CCamera::TakeControlWithSpline(int16 typeOfSwitch)
m_bcutsceneFinished = false;
m_iTypeOfSwitch = typeOfSwitch;
m_bStartInterScript = true;
-
- //FindPlayerPed(); // unused
};
void
@@ -1989,10 +2163,13 @@ CCamera::Restore(void)
pTargetEntity = PLAYER;
}
+ m_bEnable1rstPersonCamCntrlsScript = false;
+ m_bAllow1rstPersonWeaponsCamera = false;
m_bUseScriptZoomValuePed = false;
m_bUseScriptZoomValueCar = false;
m_bStartInterScript = true;
m_bCameraJustRestored = true;
+ m_fAvoidTheGeometryProbsTimer = 0.0f;
}
void
@@ -2009,6 +2186,8 @@ CCamera::RestoreWithJumpCut(void)
m_bScriptParametersSetForInterPol = false;
WhoIsInControlOfTheCamera = CAMCONTROL_GAME;
m_bCameraJustRestored = true;
+ m_bEnable1rstPersonCamCntrlsScript = false;
+ m_bAllow1rstPersonWeaponsCamera = false;
if(FindPlayerVehicle()){
m_iModeToGoTo = CCam::MODE_CAM_ON_A_STRING;
@@ -2038,27 +2217,25 @@ CCamera::SetCamPositionForFixedMode(const CVector &Source, const CVector &UpOffS
{
m_vecFixedModeSource = Source;
m_vecFixedModeUpOffSet = UpOffSet;
+ m_bGarageFixedCamPositionSet = false;
}
-
-/*
- * On PS2 the transition happens between Cams[0] and Cams[1].
- * On PC the whole system has been changed.
- */
void
CCamera::StartTransition(int16 newMode)
{
+ bool switchFromFixedSyphon = false;
bool switchSyphonMode = false;
+ bool switchPedMode = false;
bool switchPedToCar = false;
bool switchFromFight = false;
+ bool switchBikeToPed = false;
bool switchFromFixed = false;
bool switch1stPersonToVehicle = false;
float betaOffset, targetBeta, camBeta, deltaBeta;
int door;
bool vehicleVertical;
-#ifndef PS2_CAM_TRANSITION
m_bItsOkToLookJustAtThePlayer = false;
m_fFractionInterToStopMoving = 0.25f;
m_fFractionInterToStopCatchUp = 0.75f;
@@ -2071,20 +2248,21 @@ CCamera::StartTransition(int16 newMode)
newMode == CCam::MODE_FOLLOWPED ||
newMode == CCam::MODE_SYPHON ||
newMode == CCam::MODE_SPECIAL_FIXED_FOR_SYPHON)
- m_bItsOkToLookJustAtThePlayer = true;
+ switchPedMode = true;
if(newMode == CCam::MODE_CAM_ON_A_STRING)
switchPedToCar = true;
}
-#endif
+ if(Cams[ActiveCam].Mode == CCam::MODE_SPECIAL_FIXED_FOR_SYPHON)
+ switchFromFixedSyphon = true;
+ if(Cams[ActiveCam].Mode == CCam::MODE_CAM_ON_A_STRING && newMode == CCam::MODE_FOLLOWPED && m_bPlayerWasOnBike)
+ switchBikeToPed = true;
if(Cams[ActiveCam].Mode == CCam::MODE_SYPHON_CRIM_IN_FRONT && newMode == CCam::MODE_SYPHON)
switchSyphonMode = true;
if(Cams[ActiveCam].Mode == CCam::MODE_FIGHT_CAM && newMode == CCam::MODE_FOLLOWPED)
switchFromFight = true;
-#ifndef PS2_CAM_TRANSITION
if(Cams[ActiveCam].Mode == CCam::MODE_FIXED)
switchFromFixed = true;
-#endif
m_bUseTransitionBeta = false;
@@ -2096,6 +2274,7 @@ CCamera::StartTransition(int16 newMode)
Cams[ActiveCam].Mode == CCam::MODE_M16_1STPERSON_RUNABOUT ||
Cams[ActiveCam].Mode == CCam::MODE_FIGHT_CAM_RUNABOUT ||
Cams[ActiveCam].Mode == CCam::MODE_HELICANNON_1STPERSON ||
+ Cams[ActiveCam].Mode == CCam::MODE_CAMERA ||
Cams[ActiveCam].Mode == CCam::MODE_1STPERSON_RUNABOUT) &&
pTargetEntity->IsPed()){
float angle = CGeneral::GetATanOfXY(Cams[ActiveCam].Front.x, Cams[ActiveCam].Front.y) - HALFPI;
@@ -2103,12 +2282,6 @@ CCamera::StartTransition(int16 newMode)
((CPed*)pTargetEntity)->m_fRotationDest = angle;
}
-#ifdef PS2_CAM_TRANSITION
- ActiveCam = (ActiveCam+1)%2;
- Cams[ActiveCam].Init();
- Cams[ActiveCam].Mode = newMode;
-#endif
-
Cams[ActiveCam].m_cvecCamFixedModeVector = m_vecFixedModeVector;
Cams[ActiveCam].CamTargetEntity = pTargetEntity;
Cams[ActiveCam].m_cvecCamFixedModeSource = m_vecFixedModeSource;
@@ -2123,70 +2296,42 @@ CCamera::StartTransition(int16 newMode)
newMode == CCam::MODE_1STPERSON_RUNABOUT ||
newMode == CCam::MODE_M16_1STPERSON_RUNABOUT ||
newMode == CCam::MODE_FIGHT_CAM_RUNABOUT ||
- newMode == CCam::MODE_HELICANNON_1STPERSON)
+ newMode == CCam::MODE_HELICANNON_1STPERSON ||
+ newMode == CCam::MODE_CAMERA)
Cams[ActiveCam].Alpha = 0.0f;
- // PS2 also copies values to ActiveCam here
switch(Cams[ActiveCam].Mode)
case CCam::MODE_SNIPER_RUNABOUT:
case CCam::MODE_ROCKETLAUNCHER_RUNABOUT:
case CCam::MODE_1STPERSON_RUNABOUT:
case CCam::MODE_M16_1STPERSON_RUNABOUT:
case CCam::MODE_FIGHT_CAM_RUNABOUT:
+ case CCam::MODE_CAMERA:
if(newMode == CCam::MODE_CAM_ON_A_STRING || newMode == CCam::MODE_BEHINDBOAT)
switch1stPersonToVehicle = true;
switch(newMode){
case CCam::MODE_BEHINDCAR:
-#ifdef PS2_CAM_TRANSITION
- Cams[ActiveCam].Source = Cams[(ActiveCam+1)%2].Source;
- Cams[ActiveCam].Beta = Cams[(ActiveCam+1)%2].Beta;
-#endif
Cams[ActiveCam].BetaSpeed = 0.0f;
break;
case CCam::MODE_BEHINDBOAT:
-#ifdef PS2_CAM_TRANSITION
- Cams[ActiveCam].Source = Cams[(ActiveCam+1)%2].Source;
- Cams[ActiveCam].Beta = Cams[(ActiveCam+1)%2].Beta;
-#endif
Cams[ActiveCam].BetaSpeed = 0.0f;
break;
case CCam::MODE_FOLLOWPED:
// Getting out of vehicle normally
betaOffset = DEGTORAD(55.0f);
-#ifdef PS2_CAM_TRANSITION
- Cams[ActiveCam].Source = Cams[(ActiveCam+1)%2].Source;
-#endif
if(m_bJustCameOutOfGarage){
m_bUseTransitionBeta = true;
-/*
- // weird logic...
- if(CMenuManager::m_ControlMethod == CONTROL_CLASSIC)
- Cams[ActiveCam].m_fTransitionBeta = CGeneral::GetATanOfXY(Cams[ActiveCam].Front.x, Cams[ActiveCam].Front.y) + PI;
- else if(Cams[ActiveCam].Front.x != 0.0f && Cams[ActiveCam].Front.y != 0.0f) // && is wrong here
- Cams[ActiveCam].m_fTransitionBeta = CGeneral::GetATanOfXY(Cams[ActiveCam].Front.x, Cams[ActiveCam].Front.y) + PI;
- else
- Cams[ActiveCam].m_fTransitionBeta = 0.0f;
-*/
- // this is better:
if(Cams[ActiveCam].Front.x != 0.0f || Cams[ActiveCam].Front.y != 0.0f)
-#ifdef PS2_CAM_TRANSITION
- Cams[ActiveCam].m_fTransitionBeta = CGeneral::GetATanOfXY(Cams[(ActiveCam+1)%2].Front.x, Cams[(ActiveCam+1)%2].Front.y) + PI;
-#else
Cams[ActiveCam].m_fTransitionBeta = CGeneral::GetATanOfXY(Cams[ActiveCam].Front.x, Cams[ActiveCam].Front.y) + PI;
-#endif
else
Cams[ActiveCam].m_fTransitionBeta = 0.0f;
}
if(m_bTargetJustCameOffTrain)
m_bCamDirectlyInFront = true;
-#ifdef PS2_CAM_TRANSITION
- if(Cams[(ActiveCam+1)%2].Mode != CCam::MODE_CAM_ON_A_STRING)
-#else
if(Cams[ActiveCam].Mode != CCam::MODE_CAM_ON_A_STRING)
-#endif
break;
m_bUseTransitionBeta = true;
vehicleVertical = false;
@@ -2198,11 +2343,7 @@ CCamera::StartTransition(int16 newMode)
Cams[ActiveCam].m_fTransitionBeta = 0.0f;
break;
}
-#ifdef PS2_CAM_TRANSITION
- camBeta = CGeneral::GetATanOfXY(Cams[(ActiveCam+1)%2].Front.x, Cams[(ActiveCam+1)%2].Front.y);
-#else
camBeta = CGeneral::GetATanOfXY(Cams[ActiveCam].Front.x, Cams[ActiveCam].Front.y);
-#endif
if(((CPed*)pTargetEntity)->m_carInObjective)
targetBeta = CGeneral::GetATanOfXY(((CPed*)pTargetEntity)->m_carInObjective->GetForward().x, ((CPed*)pTargetEntity)->m_carInObjective->GetForward().y);
else
@@ -2251,6 +2392,7 @@ CCamera::StartTransition(int16 newMode)
case CCam::MODE_M16_1STPERSON_RUNABOUT:
case CCam::MODE_FIGHT_CAM_RUNABOUT:
case CCam::MODE_HELICANNON_1STPERSON:
+ case CCam::MODE_CAMERA:
if(FindPlayerVehicle())
Cams[ActiveCam].Beta = Atan2(FindPlayerVehicle()->GetForward().x, FindPlayerVehicle()->GetForward().y);
else
@@ -2258,10 +2400,6 @@ CCamera::StartTransition(int16 newMode)
break;
case CCam::MODE_SYPHON:
-#ifdef PS2_CAM_TRANSITION
- Cams[ActiveCam].Beta = Cams[(ActiveCam+1)%2].Beta;
- Cams[ActiveCam].Source = Cams[(ActiveCam+1)%2].Source;
-#endif
Cams[ActiveCam].Alpha = 0.0f;
Cams[ActiveCam].AlphaSpeed = 0.0f;
break;
@@ -2269,73 +2407,17 @@ CCamera::StartTransition(int16 newMode)
case CCam::MODE_CAM_ON_A_STRING:
// Get into vehicle
betaOffset = DEGTORAD(57.0f);
-#ifdef PS2_CAM_TRANSITION
- Cams[ActiveCam].Source = Cams[(ActiveCam+1)%2].Source;
-#endif
if(!m_bLookingAtPlayer || m_bJustCameOutOfGarage)
break;
m_bUseTransitionBeta = true;
- targetBeta = CGeneral::GetATanOfXY(pTargetEntity->GetForward().x, pTargetEntity->GetForward().y);
-#ifdef PS2_CAM_TRANSITION
- camBeta = CGeneral::GetATanOfXY(Cams[(ActiveCam+1)%2].Front.x, Cams[(ActiveCam+1)%2].Front.y);
-#else
- camBeta = CGeneral::GetATanOfXY(Cams[ActiveCam].Front.x, Cams[ActiveCam].Front.y);
-#endif
- deltaBeta = targetBeta - camBeta;
- while(deltaBeta >= PI) deltaBeta -= 2*PI;
- while(deltaBeta < -PI) deltaBeta += 2*PI;
- deltaBeta = Abs(deltaBeta);
-#ifndef PS2_CAM_TRANSITION
- switchFromFixed = Cams[ActiveCam].Mode == CCam::MODE_FIXED;
- if(switchFromFixed){
- Cams[ActiveCam].m_fTransitionBeta = CGeneral::GetATanOfXY(Cams[ActiveCam].Front.x, Cams[ActiveCam].Front.y);
- break;
- }
-#endif
-
- door = FindPlayerPed()->m_vehDoor;
- if(deltaBeta > HALFPI){
- if(((CVehicle*)pTargetEntity)->IsUpsideDown()){
- if(door == CAR_DOOR_LF || door == CAR_DOOR_LR) // BUG: game checks LF twice
- betaOffset = -DEGTORAD(57.0f);
- }else{
- if(door == CAR_DOOR_RF || door == CAR_DOOR_RR)
- betaOffset = -DEGTORAD(57.0f);
- }
- Cams[ActiveCam].m_fTransitionBeta = targetBeta + betaOffset + PI;
- }else{
- if(((CVehicle*)pTargetEntity)->IsUpsideDown()){
- if(door == CAR_DOOR_RF || door == CAR_DOOR_RR)
- betaOffset = -DEGTORAD(57.0f);
- else if(door == CAR_DOOR_LF || door == CAR_DOOR_LR)
- betaOffset = DEGTORAD(57.0f);
- }else{
- if(door == CAR_DOOR_LF || door == CAR_DOOR_LR)
- betaOffset = -DEGTORAD(57.0f);
- else if(door == CAR_DOOR_RF || door == CAR_DOOR_RR)
- betaOffset = DEGTORAD(57.0f);
- }
- Cams[ActiveCam].m_fTransitionBeta = targetBeta + betaOffset;
- }
+ Cams[ActiveCam].m_fTransitionBeta = CGeneral::GetATanOfXY(Cams[ActiveCam].Front.x, Cams[ActiveCam].Front.y);
break;
case CCam::MODE_PED_DEAD_BABY:
-#ifdef PS2_CAM_TRANSITION
- Cams[ActiveCam].Source = Cams[(ActiveCam+1)%2].Source;
-#endif
Cams[ActiveCam].Alpha = DEGTORAD(15.0f);
break;
-#ifdef PS2_CAM_TRANSITION
- case CCam::MODE_PLAYER_FALLEN_WATER:
- Cams[ActiveCam].m_vecLastAboveWaterCamPosition = Cams[(ActiveCam+1)%2].m_vecLastAboveWaterCamPosition;
- break;
-#endif
-
case CCam::MODE_FIGHT_CAM:
-#ifdef PS2_CAM_TRANSITION
- Cams[ActiveCam].Source = Cams[(ActiveCam+1)%2].Source;
-#endif
Cams[ActiveCam].Beta = 0.0f;
Cams[ActiveCam].BetaSpeed = 0.0f;
Cams[ActiveCam].Alpha = 0.0f;
@@ -2343,7 +2425,6 @@ CCamera::StartTransition(int16 newMode)
break;
}
-#ifndef PS2_CAM_TRANSITION
Cams[ActiveCam].Init();
Cams[ActiveCam].Mode = newMode;
@@ -2353,30 +2434,31 @@ CCamera::StartTransition(int16 newMode)
else if(switchFromFight)
m_uiTransitionDuration = 750;
else if(switchPedToCar){
- m_fFractionInterToStopMoving = 0.2f;
- m_fFractionInterToStopCatchUp = 0.8f;
- m_uiTransitionDuration = 950;
+ m_fFractionInterToStopMoving = 0.1f;
+ m_fFractionInterToStopCatchUp = 0.9f;
+ m_uiTransitionDuration = 750;
+ }else if(switchFromFixedSyphon){
+ m_fFractionInterToStopMoving = 0.0f;
+ m_fFractionInterToStopCatchUp = 1.0f;
+ m_uiTransitionDuration = 600;
}else if(switchFromFixed){
m_fFractionInterToStopMoving = 0.05f;
m_fFractionInterToStopCatchUp = 0.95f;
+ }else if(switchBikeToPed){
+ m_uiTransitionDuration = 800;
}else if(switch1stPersonToVehicle){
m_fFractionInterToStopMoving = 0.0f;
m_fFractionInterToStopCatchUp = 1.0f;
m_uiTransitionDuration = 1;
+ }else if(switchPedMode){
+ m_fFractionInterToStopMoving = 0.5f;
+ m_fFractionInterToStopCatchUp = 0.5f;
+ m_uiTransitionDuration = 350;
}else
m_uiTransitionDuration = 1350; // already set above
-#else
- if(switchSyphonMode)
- m_uiTransitionDuration = 1800;
- else if(switchFromFight)
- m_uiTransitionDuration = 750;
- else
- m_uiTransitionDuration = 1350;
-#endif
m_uiTransitionState = 1;
m_uiTimeTransitionStart = CTimer::GetTimeInMilliseconds();
m_uiTransitionJUSTStarted = 1;
-#ifndef PS2_CAM_TRANSITION
if(m_vecDoingSpecialInterPolation){
m_cvecStartingSourceForInterPol = SourceDuringInter;
m_cvecStartingTargetForInterPol = TargetDuringInter;
@@ -2407,28 +2489,32 @@ CCamera::StartTransition(int16 newMode)
m_fBetaSpeedAtStartInter = Cams[ActiveCam].m_fBetaSpeedOverOneFrame;
m_fFOVSpeedAtStartInter = Cams[ActiveCam].m_fFovSpeedOverOneFrame;
Cams[ActiveCam].ResetStatics = true;
- if(!m_bLookingAtPlayer && m_bScriptParametersSetForInterPol){
- m_fFractionInterToStopMoving = m_fScriptPercentageInterToStopMoving;
- m_fFractionInterToStopCatchUp = m_fScriptPercentageInterToCatchUp;
- m_uiTransitionDuration = m_fScriptTimeForInterPolation;
+ if(m_bLookingAtPlayer){
+ if(switchPedMode)
+ m_uiTransitionDurationTargetCoors = 350;
+ else
+ m_uiTransitionDurationTargetCoors = 600;
+ m_fFractionInterToStopMovingTarget = 0.0f;
+ m_fFractionInterToStopCatchUpTarget = 1.0f;
+ }else{
+ if(m_bScriptParametersSetForInterPol){
+ m_fFractionInterToStopMoving = m_fScriptPercentageInterToStopMoving;
+ m_fFractionInterToStopCatchUp = m_fScriptPercentageInterToCatchUp;
+ m_uiTransitionDuration = m_fScriptTimeForInterPolation;
+ }
+ m_uiTransitionDurationTargetCoors = m_uiTransitionDuration;
+ m_fFractionInterToStopMovingTarget = m_fFractionInterToStopMoving;
+ m_fFractionInterToStopCatchUpTarget = m_fFractionInterToStopCatchUp;
}
-#endif
}
void
CCamera::StartTransitionWhenNotFinishedInter(int16 mode)
{
-#ifdef PS2_CAM_TRANSITION
- m_vecOldSourceForInter = GetPosition();
- m_vecOldFrontForInter = GetForward();
- m_vecOldUpForInter = GetUp();
- m_vecOldFOVForInter = CDraw::GetFOV();
-#endif
m_vecDoingSpecialInterPolation = true;
StartTransition(mode);
}
-#ifndef PS2_CAM_TRANSITION
void
CCamera::StoreValuesDuringInterPol(CVector &source, CVector &target, CVector &up, float &FOV)
{
@@ -2441,7 +2527,7 @@ CCamera::StoreValuesDuringInterPol(CVector &source, CVector &target, CVector &up
m_fBetaDuringInterPol = CGeneral::GetATanOfXY(Dist.x, Dist.y);
m_fAlphaDuringInterPol = CGeneral::GetATanOfXY(DistOnGround, Dist.z);
}
-#endif
+
void
@@ -2475,26 +2561,24 @@ CCamera::ProcessWideScreenOn(void)
void
CCamera::DrawBordersForWideScreen(void)
{
+ float bottom, top;
+ if (m_WideScreenOn) {
+ float borderSize = (SCREEN_HEIGHT / 2) * (m_ScreenReductionPercentage / 100.f);
+ top = borderSize - SCREEN_SCALE_Y(22.f);
+ bottom = SCREEN_HEIGHT - borderSize - SCREEN_SCALE_Y(14.f);
+ } else {
+ top = 0.f;
+ bottom = SCREEN_HEIGHT;
+ }
+
if(m_BlurType == MOTION_BLUR_NONE || m_BlurType == MOTION_BLUR_LIGHT_SCENE)
SetMotionBlurAlpha(80);
- CSprite2d::DrawRect(
-#ifdef FIX_BUGS
- CRect(0.0f, (SCREEN_HEIGHT/2) * m_ScreenReductionPercentage/100.0f - SCREEN_SCALE_Y(8.0f),
-#else
- CRect(0.0f, (SCREEN_HEIGHT/2) * m_ScreenReductionPercentage/100.0f - 8.0f,
-#endif
- SCREEN_WIDTH, 0.0f),
- CRGBA(0, 0, 0, 255));
+ // top border
+ CSprite2d::DrawRect(CRect(0.0f, 0.0f, SCREEN_WIDTH, top), CRGBA(0, 0, 0, 255));
- CSprite2d::DrawRect(
- CRect(0.0f, SCREEN_HEIGHT,
-#ifdef FIX_BUGS
- SCREEN_WIDTH, SCREEN_HEIGHT - (SCREEN_HEIGHT/2) * m_ScreenReductionPercentage/100.0f - SCREEN_SCALE_Y(8.0f)),
-#else
- SCREEN_WIDTH, SCREEN_HEIGHT - (SCREEN_HEIGHT/2) * m_ScreenReductionPercentage/100.0f - 8.0f),
-#endif
- CRGBA(0, 0, 0, 255));
+ // bottom border
+ CSprite2d::DrawRect(CRect(0.0f, bottom, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(0, 0, 0, 255));
}
@@ -2512,7 +2596,9 @@ CCamera::IsItTimeForNewcam(int32 obbeMode, int32 time)
case OBBE_WHEEL:
veh = FindPlayerVehicle();
if(veh){
- if(veh->IsBoat() || veh->GetModelIndex() == MI_RHINO)
+ if(veh->IsBoat() && pTargetEntity->GetModelIndex() != MI_SKIMMER)
+ return true;
+ if(veh->GetModelIndex() == MI_RHINO)
return true;
if(!CWorld::GetIsLineOfSightClear(pTargetEntity->GetPosition(), Cams[ActiveCam].Source, true, false, false, false, false, false, false))
return true;
@@ -2522,7 +2608,7 @@ CCamera::IsItTimeForNewcam(int32 obbeMode, int32 time)
SetNearClipScript(0.6f);
return false;
case OBBE_1:
- if(FindPlayerVehicle() && FindPlayerVehicle()->IsBoat())
+ if(FindPlayerVehicle() && FindPlayerVehicle()->IsBoat() && pTargetEntity->GetModelIndex() != MI_SKIMMER)
return true;
if(!CWorld::GetIsLineOfSightClear(FindPlayerCoors(), m_vecFixedModeSource, true, false, false, false, false, false, false))
return true;
@@ -2531,14 +2617,14 @@ CCamera::IsItTimeForNewcam(int32 obbeMode, int32 time)
fwd.z = 0.0f;
// too far and driving away from cam
- if(fwd.Magnitude() > 20.0f && DotProduct(FindPlayerSpeed(), fwd) > 0.0f)
+ if(fwd.Magnitude() > 40.0f && DotProduct(FindPlayerSpeed(), fwd) > 0.0f)
return true;
// too close
if(fwd.Magnitude() < 1.6f)
return true;
return false;
case OBBE_2:
- if(FindPlayerVehicle() && FindPlayerVehicle()->IsBoat())
+ if(FindPlayerVehicle() && FindPlayerVehicle()->IsBoat() && pTargetEntity->GetModelIndex() != MI_SKIMMER)
return true;
if(!CWorld::GetIsLineOfSightClear(FindPlayerCoors(), m_vecFixedModeSource, true, false, false, false, false, false, false))
return true;
@@ -2550,10 +2636,10 @@ CCamera::IsItTimeForNewcam(int32 obbeMode, int32 time)
// very close, fix near clip
SetNearClipScript(Max(fwd.Magnitude()*0.5f, 0.05f));
// too far and driving away from cam
- if(fwd.Magnitude() > 19.0f && DotProduct(FindPlayerSpeed(), fwd) > 0.0f)
+ if(fwd.Magnitude() > 29.0f && DotProduct(FindPlayerSpeed(), fwd) > 0.0f)
return true;
// too close
- if(fwd.Magnitude() < 1.6f)
+ if(fwd.Magnitude() < 2.0f)
return true;
return false;
case OBBE_3:
@@ -2564,13 +2650,13 @@ CCamera::IsItTimeForNewcam(int32 obbeMode, int32 time)
fwd.z = 0.0f;
// too far and driving away from cam
- if(fwd.Magnitude() > 28.0f && DotProduct(FindPlayerSpeed(), fwd) > 0.0f)
+ if(fwd.Magnitude() > 48.0f && DotProduct(FindPlayerSpeed(), fwd) > 0.0f)
return true;
return false;
case OBBE_1STPERSON:
return CTimer::GetTimeInMilliseconds() > t+3000;
case OBBE_5:
- if(FindPlayerVehicle() && FindPlayerVehicle()->IsBoat())
+ if(FindPlayerVehicle() && FindPlayerVehicle()->IsBoat() && pTargetEntity->GetModelIndex() != MI_SKIMMER)
return true;
if(!CWorld::GetIsLineOfSightClear(FindPlayerCoors(), m_vecFixedModeSource, true, false, false, false, false, false, false))
return true;
@@ -2579,7 +2665,7 @@ CCamera::IsItTimeForNewcam(int32 obbeMode, int32 time)
fwd.z = 0.0f;
// too far and driving away from cam
- if(fwd.Magnitude() > 28.0f && DotProduct(FindPlayerSpeed(), fwd) > 0.0f)
+ if(fwd.Magnitude() > 38.0f && DotProduct(FindPlayerSpeed(), fwd) > 0.0f)
return true;
return false;
case OBBE_ONSTRING:
@@ -2643,6 +2729,90 @@ CCamera::IsItTimeForNewcam(int32 obbeMode, int32 time)
return false;
case OBBE_13:
return CTimer::GetTimeInMilliseconds() > t+5000;
+
+ // Heli modes
+ case OBBE_14:
+ if(FindPlayerVehicle())
+ if(!CWorld::GetIsLineOfSightClear(pTargetEntity->GetPosition(), Cams[ActiveCam].Source, true, false, false, false, false, false, false))
+ return true;
+ return CTimer::GetTimeInMilliseconds() > t+8000;
+ case OBBE_15:
+ if(FindPlayerVehicle()){
+ if(!CWorld::GetIsLineOfSightClear(FindPlayerCoors(), m_vecFixedModeSource, true, false, false, false, false, false, false))
+ return true;
+ fwd = FindPlayerCoors() - m_vecFixedModeSource;
+ fwd.z = 0.0f;
+
+ // too far and driving away from cam
+ if(fwd.Magnitude() > 44.0f && DotProduct(FindPlayerSpeed(), fwd) > 0.0f)
+ return true;
+ // too close
+ if(fwd.Magnitude() < 2.0f)
+ return true;
+ }
+ return false;
+ case OBBE_16:
+ if(FindPlayerVehicle()){
+ if(!CWorld::GetIsLineOfSightClear(FindPlayerCoors(), m_vecFixedModeSource, true, false, false, false, false, false, false))
+ return true;
+ fwd = FindPlayerCoors() - m_vecFixedModeSource;
+ fwd.z = 0.0f;
+
+ // too far and driving away from cam
+ if(fwd.Magnitude() > 50.0f && DotProduct(FindPlayerSpeed(), fwd) > 0.0f)
+ return true;
+ // too close
+ if(fwd.Magnitude() < 3.0f)
+ return true;
+ }
+ return false;
+ case OBBE_17:
+ if(FindPlayerVehicle()){
+ if(!CWorld::GetIsLineOfSightClear(FindPlayerCoors(), m_vecFixedModeSource, true, false, false, false, false, false, false))
+ return true;
+ fwd = FindPlayerCoors() - m_vecFixedModeSource;
+ fwd.z = 0.0f;
+
+ // too far
+ if(fwd.Magnitude() > 50.0f)
+ return true;
+ // too close
+ if(fwd.Magnitude() < 2.0f)
+ return true;
+ }
+ return false;
+ case OBBE_18:
+ if(FindPlayerVehicle()){
+ if(!CWorld::GetIsLineOfSightClear(FindPlayerCoors(), m_vecFixedModeSource, true, false, false, false, false, false, false))
+ return true;
+ fwd = FindPlayerCoors() - m_vecFixedModeSource;
+
+ // too far
+ if(fwd.Magnitude() > 57.0f)
+ return true;
+ // too close
+ if(fwd.Magnitude() < 1.0f)
+ return true;
+ }
+ return false;
+ case OBBE_19:
+ if(FindPlayerVehicle()){
+ if(!CWorld::GetIsLineOfSightClear(FindPlayerCoors(), m_vecFixedModeSource, true, false, false, false, false, false, false))
+ return true;
+ fwd = FindPlayerCoors() - m_vecFixedModeSource;
+ fwd.z = 0.0f;
+
+ // too far
+ if(fwd.Magnitude() > 36.0f)
+ return true;
+ // too close
+ if(fwd.Magnitude() < 2.0f)
+ return true;
+ }
+ return false;
+ case OBBE_ONSTRING_HELI:
+ return CTimer::GetTimeInMilliseconds() > t+5000;
+
default:
return false;
}
@@ -2652,7 +2822,8 @@ bool
CCamera::TryToStartNewCamMode(int obbeMode)
{
CVehicle *veh;
- CVector target, camPos, playerSpeed, fwd;
+ CVector target, camPos, playerSpeed, fwd, fwd2;
+ float angle;
float ground;
bool foundGround;
int i;
@@ -2662,7 +2833,7 @@ CCamera::TryToStartNewCamMode(int obbeMode)
switch(obbeMode){
case OBBE_WHEEL:
veh = FindPlayerVehicle();
- if(veh == nil || veh->IsBoat() || veh->GetModelIndex() == MI_RHINO)
+ if(veh == nil || (veh->IsBoat() && pTargetEntity->GetModelIndex() != MI_SKIMMER) || veh->GetModelIndex() == MI_RHINO)
return false;
target = Multiply3x3(FindPlayerVehicle()->GetMatrix(), CVector(-1.4f, -2.3f, 0.3f));
target += FindPlayerVehicle()->GetPosition();
@@ -2677,7 +2848,7 @@ CCamera::TryToStartNewCamMode(int obbeMode)
playerSpeed.Normalise();
camPos += 20.0f*playerSpeed;
camPos += 3.0f*CVector(playerSpeed.y, -playerSpeed.x, 0.0f);
- if(FindPlayerVehicle() && FindPlayerVehicle()->IsBoat())
+ if(FindPlayerVehicle() && FindPlayerVehicle()->IsBoat() && pTargetEntity->GetModelIndex() != MI_SKIMMER)
return false;
ground = CWorld::FindGroundZFor3DCoord(camPos.x, camPos.y, camPos.z+5.0f, &foundGround);
@@ -2694,17 +2865,17 @@ CCamera::TryToStartNewCamMode(int obbeMode)
fwd = FindPlayerCoors() - camPos;
fwd.z = 0.0f;
// too far and driving away from cam
- if(fwd.Magnitude() > 20.0f && DotProduct(FindPlayerSpeed(), fwd) > 0.0f)
+ if(fwd.Magnitude() > 40.0f && DotProduct(FindPlayerSpeed(), fwd) > 0.0f)
return false;
// too close
- if(fwd.Magnitude() < 1.6f)
+ if(fwd.Magnitude() < 2.5f)
return true;
SetCamPositionForFixedMode(camPos, CVector(0.0f, 0.0f, 0.0f));
TakeControl(FindPlayerEntity(), CCam::MODE_FIXED, JUMP_CUT, CAMCONTROL_OBBE);
return true;
case OBBE_2:
- if(FindPlayerVehicle() && FindPlayerVehicle()->IsBoat())
+ if(FindPlayerVehicle() && FindPlayerVehicle()->IsBoat() && pTargetEntity->GetModelIndex() != MI_SKIMMER)
return false;
camPos = FindPlayerCoors();
playerSpeed = FindPlayerSpeed();
@@ -2727,10 +2898,10 @@ CCamera::TryToStartNewCamMode(int obbeMode)
fwd = FindPlayerCoors() - camPos;
fwd.z = 0.0f;
// too far and driving away from cam
- if(fwd.Magnitude() > 19.0f && DotProduct(FindPlayerSpeed(), fwd) > 0.0f)
+ if(fwd.Magnitude() > 29.0f && DotProduct(FindPlayerSpeed(), fwd) > 0.0f)
return false;
// too close
- if(fwd.Magnitude() < 1.6f)
+ if(fwd.Magnitude() < 2.0f)
return true;
SetCamPositionForFixedMode(camPos, CVector(0.0f, 0.0f, 0.0f));
@@ -2787,7 +2958,7 @@ CCamera::TryToStartNewCamMode(int obbeMode)
return false;
if(FindPlayerVehicle() == nil)
return false;
- if(FindPlayerVehicle() && FindPlayerVehicle()->IsBoat())
+ if(FindPlayerVehicle() && FindPlayerVehicle()->IsBoat() && pTargetEntity->GetModelIndex() != MI_SKIMMER)
return false;
i = CPools::GetVehiclePool()->GetSize();
while(--i >= 0){
@@ -2815,7 +2986,7 @@ CCamera::TryToStartNewCamMode(int obbeMode)
return false;
if(FindPlayerVehicle() == nil)
return false;
- if(FindPlayerVehicle() && FindPlayerVehicle()->IsBoat())
+ if(FindPlayerVehicle() && FindPlayerVehicle()->IsBoat() && pTargetEntity->GetModelIndex() != MI_SKIMMER)
return false;
i = CPools::GetVehiclePool()->GetSize();
while(--i >= 0){
@@ -2910,12 +3081,219 @@ CCamera::TryToStartNewCamMode(int obbeMode)
TakeControl(FindPlayerEntity(), CCam::MODE_TOPDOWN, JUMP_CUT, CAMCONTROL_OBBE);
#endif
return true;
+
+ // Heli modes
+ case OBBE_14:
+ veh = FindPlayerVehicle();
+ if(veh == nil)
+ return false;
+ target = Multiply3x3(FindPlayerVehicle()->GetMatrix(), CVector(-1.4f, -2.3f, 0.3f));
+ target += FindPlayerVehicle()->GetPosition();
+ if(!veh->IsBoat() && !CWorld::GetIsLineOfSightClear(veh->GetPosition(), target, true, false, false, false, false, false, false))
+ return false;
+ TakeControl(veh, CCam::MODE_WHEELCAM, JUMP_CUT, CAMCONTROL_OBBE);
+ return true;
+ case OBBE_15:
+ if(FindPlayerVehicle() == nil)
+ return false;
+ camPos = FindPlayerCoors();
+ playerSpeed = FindPlayerSpeed();
+ playerSpeed.z = 0.0f;
+ playerSpeed.Normalise();
+ camPos += 34.0f*playerSpeed;
+ camPos.z = FindPlayerCoors().z + 0.5f;
+ if(FindPlayerVehicle()->IsBoat())
+ camPos.z += 1.0f;
+
+ if(!CWorld::GetIsLineOfSightClear(FindPlayerCoors(), camPos, true, false, false, false, false, false, false))
+ return false;
+
+ fwd = FindPlayerCoors() - camPos;
+ fwd2 = FindPlayerCoors() - camPos;
+ fwd2.z = 0.0f;
+ // too far and driving away from cam
+ if(fwd.Magnitude() > 44.0f && DotProduct(FindPlayerSpeed(), fwd2) > 0.0f)
+ return false;
+ // too close
+ if(fwd.Magnitude() < 3.0f)
+ return true;
+
+ SetCamPositionForFixedMode(camPos, CVector(0.0f, 0.0f, 0.0f));
+ TakeControl(FindPlayerEntity(), CCam::MODE_FIXED, JUMP_CUT, CAMCONTROL_OBBE);
+ return true;
+ case OBBE_16:
+ if(FindPlayerVehicle() == nil)
+ return false;
+ camPos = FindPlayerCoors();
+ playerSpeed = FindPlayerSpeed();
+ playerSpeed.z = 0.0f;
+ playerSpeed.Normalise();
+ angle = CGeneral::GetATanOfXY(playerSpeed.x, playerSpeed.y) + DEGTORAD(60.0f);
+ playerSpeed += CVector(Cos(angle), Sin(angle), 0.0f);
+ playerSpeed.Normalise();
+ camPos += 30.0f*playerSpeed;
+ camPos.z = FindPlayerCoors().z - 5.5f;
+
+ foundGround = false;
+ ground = CWorld::FindRoofZFor3DCoord(camPos.x, camPos.y, camPos.z+5.0f, &foundGround);
+ if(foundGround)
+ camPos.z = ground + 0.5f;
+ else if(CWaterLevel::GetWaterLevelNoWaves(camPos.x, camPos.y, camPos.z, &ground)){
+ float waterOffset = 1.0f;
+ if(FindPlayerVehicle() && FindPlayerVehicle()->IsBoat())
+ waterOffset = -2.0f;
+ if(camPos.z < ground + waterOffset)
+ camPos.z = ground + waterOffset;
+ }
+ if(!CWorld::GetIsLineOfSightClear(FindPlayerCoors(), camPos, true, false, false, false, false, false, false))
+ return false;
+
+ fwd = FindPlayerCoors() - camPos;
+ // too far
+ if(fwd.Magnitude() > 50.0f)
+ return false;
+ // too close
+ if(fwd.Magnitude() < 3.0f)
+ return true;
+
+ SetCamPositionForFixedMode(camPos, CVector(0.0f, 0.0f, 0.0f));
+ TakeControl(FindPlayerEntity(), CCam::MODE_FIXED, JUMP_CUT, CAMCONTROL_OBBE);
+ return true;
+ case OBBE_17:
+ if(FindPlayerVehicle() == nil)
+ return false;
+ camPos = FindPlayerCoors();
+ playerSpeed = FindPlayerSpeed();
+ playerSpeed.z = 0.0f;
+ playerSpeed.Normalise();
+ angle = CGeneral::GetATanOfXY(playerSpeed.x, playerSpeed.y) + DEGTORAD(190.0f);
+ playerSpeed += CVector(Cos(angle), Sin(angle), 0.0f);
+ playerSpeed.Normalise();
+ camPos += 25.0f*playerSpeed;
+ camPos.z = FindPlayerCoors().z - 1.0f;
+
+ foundGround = false;
+ ground = CWorld::FindRoofZFor3DCoord(camPos.x, camPos.y, camPos.z+5.0f, &foundGround);
+ if(foundGround)
+ camPos.z = ground + 0.5f;
+ else if(CWaterLevel::GetWaterLevelNoWaves(camPos.x, camPos.y, camPos.z, &ground)){
+ float waterOffset = 1.0f;
+ if(FindPlayerVehicle() && FindPlayerVehicle()->IsBoat())
+ waterOffset = -2.0f;
+ if(camPos.z < ground + waterOffset)
+ camPos.z = ground + waterOffset;
+ }
+ if(!CWorld::GetIsLineOfSightClear(FindPlayerCoors(), camPos, true, false, false, false, false, false, false))
+ return false;
+
+ fwd = FindPlayerCoors() - camPos;
+ fwd2 = FindPlayerCoors() - camPos;
+ fwd2.z = 0.0f;
+ // too far and driving away from cam
+ if(fwd.Magnitude() > 50.0f && DotProduct(FindPlayerSpeed(), fwd2) > 0.0f)
+ return false;
+ // too close
+ if(fwd.Magnitude() < 2.0f)
+ return true;
+
+ SetCamPositionForFixedMode(camPos, CVector(0.0f, 0.0f, 0.0f));
+ TakeControl(FindPlayerEntity(), CCam::MODE_FIXED, JUMP_CUT, CAMCONTROL_OBBE);
+ return true;
+ case OBBE_18:
+ camPos = FindPlayerCoors();
+ if(FindPlayerVehicle() && FindPlayerVehicle()->IsBoat())
+ camPos.z += 23.0f;
+ else
+ camPos.z -= 23.0f;
+ playerSpeed = FindPlayerSpeed();
+ angle = CGeneral::GetATanOfXY(playerSpeed.x, playerSpeed.y) + DEGTORAD(145.0f);
+ playerSpeed += CVector(Cos(angle), Sin(angle), 0.0f);
+ playerSpeed.Normalise();
+ camPos += 15.0f*playerSpeed;
+
+ foundGround = false;
+ ground = CWorld::FindGroundZFor3DCoord(camPos.x, camPos.y, camPos.z+5.0f, &foundGround);
+#ifdef FIX_BUGS
+ if(foundGround)
+#else
+ if(ground == true)
+#endif
+ {
+ if(camPos.z < ground)
+ camPos.z = ground + 0.5f;
+ }else if(CWaterLevel::GetWaterLevelNoWaves(camPos.x, camPos.y, camPos.z, &ground)){
+ float waterOffset = 1.0f;
+ if(FindPlayerVehicle() && FindPlayerVehicle()->IsBoat())
+ waterOffset = -2.0f;
+ if(camPos.z < ground + waterOffset)
+ camPos.z = ground + waterOffset;
+ }
+ if(!CWorld::GetIsLineOfSightClear(FindPlayerCoors(), camPos, true, false, false, false, false, false, false))
+ return false;
+
+ fwd = FindPlayerCoors() - camPos;
+ // too far
+ if(fwd.Magnitude() > 57.0f)
+ return false;
+ // too close
+ if(fwd.Magnitude() < 1.0f)
+ return true;
+
+ SetCamPositionForFixedMode(camPos, CVector(0.0f, 0.0f, 0.0f));
+ TakeControl(FindPlayerEntity(), CCam::MODE_FIXED, JUMP_CUT, CAMCONTROL_OBBE);
+ return true;
+ case OBBE_19:
+ camPos = FindPlayerCoors();
+ if(FindPlayerVehicle() && FindPlayerVehicle()->IsBoat())
+ camPos.z += 4.0f;
+ else
+ camPos.z -= 1.0f;
+ playerSpeed = FindPlayerSpeed();
+ angle = CGeneral::GetATanOfXY(playerSpeed.x, playerSpeed.y) + DEGTORAD(28.0f);
+ playerSpeed += CVector(Cos(angle), Sin(angle), 0.0f);
+ playerSpeed.Normalise();
+ camPos += 12.5f*playerSpeed;
+
+ foundGround = false;
+ ground = CWorld::FindGroundZFor3DCoord(camPos.x, camPos.y, camPos.z+5.0f, &foundGround);
+#ifdef FIX_BUGS
+ if(foundGround)
+#else
+ if(ground == true)
+#endif
+ {
+ if(camPos.z < ground)
+ camPos.z = ground + 0.5f;
+ }else if(CWaterLevel::GetWaterLevelNoWaves(camPos.x, camPos.y, camPos.z, &ground)){
+ float waterOffset = 1.0f;
+ if(FindPlayerVehicle() && FindPlayerVehicle()->IsBoat())
+ waterOffset = -2.0f;
+ if(camPos.z < ground + waterOffset)
+ camPos.z = ground + waterOffset;
+ }
+ if(!CWorld::GetIsLineOfSightClear(FindPlayerCoors(), camPos, true, false, false, false, false, false, false))
+ return false;
+
+ fwd = FindPlayerCoors() - camPos;
+ // too far
+ if(fwd.Magnitude() > 36.0f)
+ return false;
+ // too close
+ if(fwd.Magnitude() < 2.0f)
+ return true;
+
+ SetCamPositionForFixedMode(camPos, CVector(0.0f, 0.0f, 0.0f));
+ TakeControl(FindPlayerEntity(), CCam::MODE_FIXED, JUMP_CUT, CAMCONTROL_OBBE);
+ return true;
+ case OBBE_ONSTRING_HELI:
+ TakeControl(FindPlayerEntity(), CCam::MODE_CAM_ON_A_STRING, JUMP_CUT, CAMCONTROL_OBBE);
+ return true;
default:
return false;
}
}
-int32 SequenceOfCams[16] = {
+int32 SequenceOfCarCams[16] = {
OBBE_WHEEL, OBBE_COPCAR, OBBE_3, OBBE_1, OBBE_3, OBBE_COPCAR_WHEEL,
OBBE_2, OBBE_3, OBBE_COPCAR_WHEEL, OBBE_COPCAR, OBBE_2, OBBE_3,
OBBE_5, OBBE_3,
@@ -2931,19 +3309,19 @@ CCamera::ProcessObbeCinemaCameraCar(void)
if(!bDidWeProcessAnyCinemaCam){
OldMode = -1;
- CHud::SetHelpMessage(TheText.Get("CINCAM"), true);
+ bSwitchedToObbeCam = true;
}
- if(!bDidWeProcessAnyCinemaCam || IsItTimeForNewcam(SequenceOfCams[OldMode], TimeForNext)){
+ if(!bDidWeProcessAnyCinemaCam || IsItTimeForNewcam(SequenceOfCarCams[OldMode], TimeForNext)){
// This is very strange code...
for(OldMode = (OldMode+1) % 14;
- !TryToStartNewCamMode(SequenceOfCams[OldMode]) && i <= 14;
+ !TryToStartNewCamMode(SequenceOfCarCams[OldMode]) && i <= 14;
OldMode = (OldMode+1) % 14)
i++;
TimeForNext = CTimer::GetTimeInMilliseconds();
if(i >= 14){
OldMode = 14;
- TryToStartNewCamMode(SequenceOfCams[14]);
+ TryToStartNewCamMode(SequenceOfCarCams[14]);
}
}
@@ -2951,6 +3329,40 @@ CCamera::ProcessObbeCinemaCameraCar(void)
bDidWeProcessAnyCinemaCam = true;
}
+int32 SequenceOfHeliCams[6] = { OBBE_14, OBBE_15, OBBE_16, OBBE_17, OBBE_18, OBBE_19 };
+
+void
+CCamera::ProcessObbeCinemaCameraHeli(void)
+{
+ static int OldMode = -1;
+ static int32 TimeForNext = 0;
+ int i = 0;
+
+ if(!bDidWeProcessAnyCinemaCam){
+ OldMode = -1;
+ bSwitchedToObbeCam = true;
+ }
+
+ if(!bDidWeProcessAnyCinemaCam || IsItTimeForNewcam(SequenceOfHeliCams[OldMode], TimeForNext)){
+ // This is very strange code...
+ for(OldMode = (OldMode+1) % 6;
+ !TryToStartNewCamMode(SequenceOfCarCams[OldMode]) && i <= 6;
+ OldMode = (OldMode+1) % 6)
+ i++;
+ if(i >= 6){
+ OldMode = 6;
+ if(Cams[ActiveCam].Mode != CCam::MODE_CAM_ON_A_STRING){
+ TryToStartNewCamMode(OBBE_ONSTRING_HELI);
+ TimeForNext = CTimer::GetTimeInMilliseconds();
+ }
+ }else
+ TimeForNext = CTimer::GetTimeInMilliseconds();
+ }
+
+ m_iModeObbeCamIsInForCar = OldMode;
+ bDidWeProcessAnyCinemaCam = true;
+}
+
int32 SequenceOfPedCams[5] = { OBBE_9, OBBE_10, OBBE_11, OBBE_12, OBBE_13 };
void
@@ -2978,6 +3390,7 @@ CCamera::DontProcessObbeCinemaCamera(void)
bDidWeProcessAnyCinemaCam = false;
}
+#ifdef GTA_TRAIN
void
CCamera::LoadTrainCamNodes(char const *name)
{
@@ -3162,6 +3575,7 @@ CCamera::Process_Train_Camera_Control(void)
}
}
}
+#endif
void
@@ -3173,9 +3587,14 @@ CCamera::LoadPathSplines(int file)
n = 0;
+ DeleteCutSceneCamDataMemory();
for(i = 0; i < MAX_NUM_OF_SPLINETYPES; i++)
- for(j = 0; j < CCamPathSplines::MAXPATHLENGTH; j++)
- m_arrPathArray[i].m_arr_PathData[j] = 0.0f;
+ m_arrPathArray[i].m_arr_PathData = new float[CCamPathSplines::MAXPATHLENGTH];
+
+// Why is this gone?
+// for(i = 0; i < MAX_NUM_OF_SPLINETYPES; i++)
+// for(j = 0; j < CCamPathSplines::MAXPATHLENGTH; j++)
+// m_arrPathArray[i].m_arr_PathData[j] = 0.0f;
m_bStartingSpline = false;
@@ -3212,6 +3631,8 @@ CCamera::LoadPathSplines(int file)
m_arrPathArray[i].m_arr_PathData[j] = atof(token);
i++;
j = 0;
+ if (i == MAX_NUM_OF_SPLINETYPES)
+ reading = false;
memset(token, 0, 32);
n = 0;
}
@@ -3219,6 +3640,17 @@ CCamera::LoadPathSplines(int file)
}
void
+CCamera::DeleteCutSceneCamDataMemory(void)
+{
+ int i;
+ for(i = 0; i < MAX_NUM_OF_SPLINETYPES; i++)
+ if(m_arrPathArray[i].m_arr_PathData){
+ delete[] m_arrPathArray[i].m_arr_PathData;
+ m_arrPathArray[i].m_arr_PathData = nil;
+ }
+}
+
+void
CCamera::FinishCutscene(void)
{
SetPercentAlongCutScene(100.0f);
@@ -3279,26 +3711,42 @@ CCamera::SetZoomValueFollowPedScript(int16 dist)
void
CCamera::SetZoomValueCamStringScript(int16 dist)
{
+ if (Cams[ActiveCam].CamTargetEntity->IsVehicle()) {
+ int vehApp = ((CVehicle*)Cams[ActiveCam].CamTargetEntity)->GetVehicleAppearance();
+ int vehArrPos = 0;
+ GetArrPosForVehicleType(vehApp, vehArrPos);
+
#ifdef FREE_CAM
- if (bFreeCam) {
- switch (dist) {
- case 0: m_fCarZoomValueScript = ((CVehicle*)Cams[ActiveCam].CamTargetEntity)->IsBoat() ? FREE_BOAT_ZOOM_VALUE_1 : FREE_CAR_ZOOM_VALUE_1; break;
- case 1: m_fCarZoomValueScript = ((CVehicle*)Cams[ActiveCam].CamTargetEntity)->IsBoat() ? FREE_BOAT_ZOOM_VALUE_2 : FREE_CAR_ZOOM_VALUE_2; break;
- case 2: m_fCarZoomValueScript = ((CVehicle*)Cams[ActiveCam].CamTargetEntity)->IsBoat() ? FREE_BOAT_ZOOM_VALUE_3 : FREE_CAR_ZOOM_VALUE_3; break;
- default: break;
+ if (bFreeCam) {
+ switch (dist) {
+ case 0: m_fCarZoomValueScript = LCS_ZOOM_ONE_DISTANCE[vehArrPos]; break;
+ case 1: m_fCarZoomValueScript = LCS_ZOOM_TWO_DISTANCE[vehArrPos]; break;
+ case 2: m_fCarZoomValueScript = LCS_ZOOM_THREE_DISTANCE[vehArrPos]; break;
+ default: break;
+ }
}
- } else
+ else
#endif
- {
+ {
+ switch (dist) {
+ case 0: m_fCarZoomValueScript = ZOOM_ONE_DISTANCE[vehArrPos]; break;
+ case 1: m_fCarZoomValueScript = ZOOM_TWO_DISTANCE[vehArrPos]; break;
+ case 2: m_fCarZoomValueScript = ZOOM_THREE_DISTANCE[vehArrPos]; break;
+ default: break;
+ }
+ }
+
+ m_bUseScriptZoomValueCar = true;
+ } else {
switch (dist) {
- case 0: m_fCarZoomValueScript = DEFAULT_CAR_ZOOM_VALUE_1; break;
- case 1: m_fCarZoomValueScript = DEFAULT_CAR_ZOOM_VALUE_2; break;
- case 2: m_fCarZoomValueScript = DEFAULT_CAR_ZOOM_VALUE_3; break;
+ case 0: m_fPedZoomValueScript = 0.25f; break;
+ case 1: m_fPedZoomValueScript = 1.5f; break;
+ case 2: m_fPedZoomValueScript = 2.9f; break;
default: break;
}
- }
- m_bUseScriptZoomValueCar = true;
+ m_bUseScriptZoomValuePed = true;
+ }
}
void
@@ -3313,33 +3761,23 @@ 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;
- }
- }else{
+ if(m_fTimeToFadeOut != 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;
- }
- }else{
+ if(m_fTimeToFadeOut != 0.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;
}
}
@@ -3350,46 +3788,28 @@ CCamera::ProcessFade(void)
void
CCamera::ProcessMusicFade(void)
{
- float fade = (CTimer::GetTimeInMilliseconds() - m_uiFadeTimeStartedMusic)/1000.0f;
if(m_bMusicFading){
if(m_iMusicFadingDirection == FADE_IN){
if(m_fTimeToFadeMusic == 0.0f)
- m_fTimeToFadeMusic = 1.0f;
-
- m_fFLOATingFadeMusic = 255.0f*fade/m_fTimeToFadeMusic;
- if(m_fFLOATingFadeMusic > 255.0f){
+ m_fFLOATingFadeMusic = 0.0f;
+ else
+ m_fFLOATingFadeMusic -= 255.0f*CTimer::GetTimeStepInSeconds()/m_fTimeToFadeMusic;
+ if(m_fFLOATingFadeMusic <= 0.0f){
m_bMusicFading = false;
m_fFLOATingFadeMusic = 0.0f;
- DMAudio.SetEffectsFadeVol(127);
- DMAudio.SetMusicFadeVol(127);
- }else{
- DMAudio.SetEffectsFadeVol(m_fFLOATingFadeMusic/255.0f * 127);
- DMAudio.SetMusicFadeVol(m_fFLOATingFadeMusic/255.0f * 127);
}
}else if(m_iMusicFadingDirection == FADE_OUT){
if(m_fTimeToFadeMusic == 0.0f)
- m_fTimeToFadeMusic = 1.0f;
-
-#ifdef PS2_MENU
- if(m_bMoveCamToAvoidGeom || TheMemoryCard.StillToFadeOut){
-#else
- if(m_bMoveCamToAvoidGeom || StillToFadeOut){
-#endif
- m_fFLOATingFadeMusic = 256.0f;
- m_bMoveCamToAvoidGeom = false;
- }else
- m_fFLOATingFadeMusic = 255.0f*fade/m_fTimeToFadeMusic;
-
- if(m_fFLOATingFadeMusic > 255.0f){
+ m_fFLOATingFadeMusic = 255.0f;
+ else
+ m_fFLOATingFadeMusic += 255.0f*CTimer::GetTimeStepInSeconds()/m_fTimeToFadeMusic;
+ if(m_fFLOATingFadeMusic >= 255.0f){
m_bMusicFading = false;
m_fFLOATingFadeMusic = 255.0f;
- DMAudio.SetEffectsFadeVol(0);
- DMAudio.SetMusicFadeVol(0);
- }else{
- DMAudio.SetEffectsFadeVol(127 - m_fFLOATingFadeMusic/255.0f * 127);
- DMAudio.SetMusicFadeVol(127 - m_fFLOATingFadeMusic/255.0f * 127);
}
}
+ DMAudio.SetEffectsFadeVol(127 - m_fFLOATingFadeMusic/255.0f * 127);
+ DMAudio.SetMusicFadeVol(127 - m_fFLOATingFadeMusic/255.0f * 127);
}
}
@@ -3405,22 +3825,13 @@ CCamera::Fade(float timeout, int16 direction)
m_iMusicFadingDirection = direction;
m_fTimeToFadeMusic = timeout;
m_uiFadeTimeStartedMusic = CTimer::GetTimeInMilliseconds();
-// Not on PS2
- if(!m_bUnknown && m_iMusicFadingDirection == FADE_OUT){
- unknown++;
- if(unknown >= 2){
- m_bUnknown = true;
- unknown = 0;
- }else
- m_bMoveCamToAvoidGeom = true;
- }
}
}
void
CCamera::SetFadeColour(uint8 r, uint8 g, uint8 b)
{
- m_FadeTargetIsSplashScreen = r == 0 && g == 0 && b == 0;
+ m_FadeTargetIsSplashScreen = r == 2 && g == 2 && b == 2;
CDraw::FadeRed = r;
CDraw::FadeGreen = g;
CDraw::FadeBlue = b;
@@ -3527,6 +3938,7 @@ CCamera::SetCameraDirectlyInFrontForFollowPed_CamOnAString(void)
void
CCamera::SetNewPlayerWeaponMode(int16 mode, int16 minZoom, int16 maxZoom)
{
+ SetMotionBlur(CTimeCycle::GetBlurRed(), CTimeCycle::GetBlurGreen(), CTimeCycle::GetBlurBlue(), m_motionBlur, MOTION_BLUR_LIGHT_SCENE);
PlayerWeaponMode.Mode = mode;
PlayerWeaponMode.MaxZoom = maxZoom;
PlayerWeaponMode.MinZoom = minZoom;
@@ -3536,6 +3948,7 @@ CCamera::SetNewPlayerWeaponMode(int16 mode, int16 minZoom, int16 maxZoom)
void
CCamera::ClearPlayerWeaponMode(void)
{
+ SetMotionBlur(CTimeCycle::GetBlurRed(), CTimeCycle::GetBlurGreen(), CTimeCycle::GetBlurBlue(), m_motionBlur, MOTION_BLUR_LIGHT_SCENE);
PlayerWeaponMode.Mode = 0;
PlayerWeaponMode.MaxZoom = 1;
PlayerWeaponMode.MinZoom = -1;
@@ -3579,6 +3992,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
@@ -3603,8 +4028,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
@@ -3650,7 +4076,7 @@ CCamera::IsPointVisible(const CVector &center, const CMatrix *mat)
}
bool
-CCamera::IsSphereVisible(const CVector &center, float radius, Const CMatrix *mat)
+CCamera::IsSphereVisible(const CVector &center, float radius, const CMatrix *mat)
{
#ifdef GTA_PS2
CVuVector c;
@@ -3675,14 +4101,7 @@ CCamera::IsSphereVisible(const CVector &center, float radius, Const CMatrix *mat
bool
CCamera::IsSphereVisible(const CVector &center, float radius)
{
-#if GTA_VERSION < GTA3_PC_10 // not sure this condition is the right one
- // Maybe this was a copy of the other function with m_cameraMatrix
- return IsSphereVisible(center, radius, &m_cameraMatrix);
-#else
- // ...and on PC they decided to call the other one with a default matrix.
- CMatrix mat(GetCameraMatrix()); // this matrix construction is stupid and gone in VC
- return IsSphereVisible(center, radius, &mat);
-#endif
+ return IsSphereVisible(center, radius, &GetCameraMatrix());
}
bool
@@ -3720,7 +4139,5 @@ CCamera::IsBoxVisible(CVUVECTOR *box, const CMatrix *mat)
CCamPathSplines::CCamPathSplines(void)
{
- int i;
- for(i = 0; i < MAXPATHLENGTH; i++)
- m_arr_PathData[i] = 0.0f;
+ m_arr_PathData = nil;
}
diff --git a/src/core/Camera.h b/src/core/Camera.h
index 07a05cb4..39ecb760 100644
--- a/src/core/Camera.h
+++ b/src/core/Camera.h
@@ -26,20 +26,6 @@ enum
CAM_ZOOM_CINEMATIC,
};
-#ifdef FREE_CAM // LCS values
-#define FREE_CAR_ZOOM_VALUE_1 (-1.0f)
-#define FREE_CAR_ZOOM_VALUE_2 (2.0f)
-#define FREE_CAR_ZOOM_VALUE_3 (6.0f)
-
-#define FREE_BOAT_ZOOM_VALUE_1 (-2.41f)
-#define FREE_BOAT_ZOOM_VALUE_2 (6.49f)
-#define FREE_BOAT_ZOOM_VALUE_3 (15.0f)
-#endif
-
-#define DEFAULT_CAR_ZOOM_VALUE_1 (0.05f)
-#define DEFAULT_CAR_ZOOM_VALUE_2 (1.9f)
-#define DEFAULT_CAR_ZOOM_VALUE_3 (3.9f)
-
const float DefaultFOV = 70.0f; // beta: 80.0f
class CCam
@@ -85,13 +71,15 @@ public:
MODE_SPECIAL_FIXED_FOR_SYPHON,
MODE_FIGHT_CAM,
MODE_TOP_DOWN_PED,
+ MODE_LIGHTHOUSE,
MODE_SNIPER_RUNABOUT,
MODE_ROCKETLAUNCHER_RUNABOUT,
MODE_1STPERSON_RUNABOUT,
MODE_M16_1STPERSON_RUNABOUT,
MODE_FIGHT_CAM_RUNABOUT,
MODE_EDITOR,
- MODE_HELICANNON_1STPERSON, // vice city leftover
+ MODE_HELICANNON_1STPERSON,
+ MODE_CAMERA,
};
bool bBelowMinDist; //used for follow ped mode
@@ -121,7 +109,6 @@ public:
float f_Roll; //used for adding a slight roll to the camera in the
float f_rollSpeed;
float m_fSyphonModeTargetZOffSet;
- float m_fRoadOffSet;
float m_fAmountFractionObscured;
float m_fAlphaSpeedOverOneFrame;
float m_fBetaSpeedOverOneFrame;
@@ -144,7 +131,8 @@ public:
float m_fRealGroundDist; //used for follow ped mode
float m_fTargetBeta;
float m_fTimeElapsedFloat;
-
+ float m_fTilt;
+ float m_fTiltSpeed;
float m_fTransitionBeta;
float m_fTrueBeta;
float m_fTrueAlpha;
@@ -162,6 +150,16 @@ public:
float CA_MAX_DISTANCE;
float SpeedVar;
+ float m_fTargetZoomGroundOne;
+ float m_fTargetZoomGroundTwo;
+ float m_fTargetZoomGroundThree;
+ float m_fTargetZoomOneZExtra;
+ float m_fTargetZoomTwoZExtra;
+ float m_fTargetZoomThreeZExtra;
+ float m_fTargetZoomZCloseIn;
+ float m_fMinRealGroundDist;
+ float m_fTargetCloseInDist;
+
CVector m_cvecSourceSpeedOverOneFrame;
CVector m_cvecTargetSpeedOverOneFrame;
CVector m_cvecUpOverOneFrame;
@@ -194,13 +192,11 @@ public:
void ProcessSpecialHeightRoutines(void);
void GetVectorsReadyForRW(void);
CVector DoAverageOnVector(const CVector &vec);
- float GetPedBetaAngleForClearView(const CVector &Target, float Dist, float BetaOffset, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies);
- void WorkOutCamHeightWeeCar(CVector &TargetCoors, float TargetOrientation);
void WorkOutCamHeight(const CVector &TargetCoors, float TargetOrientation, float TargetHeight);
bool RotCamIfInFrontCar(CVector &TargetCoors, float TargetOrientation);
- bool FixCamIfObscured(CVector &TargetCoors, float TargetHeight, float TargetOrientation);
void Cam_On_A_String_Unobscured(const CVector &TargetCoors, float BaseDist);
void FixCamWhenObscuredByVehicle(const CVector &TargetCoors);
+ bool GetBoatLook_L_R_HeightOffset(float &Offset);
void LookBehind(void);
void LookLeft(void);
void LookRight(void);
@@ -233,42 +229,29 @@ public:
void Process_BehindBoat(const CVector &CameraTarget, float TargetOrientation, float, float);
void Process_Fight_Cam(const CVector &CameraTarget, float TargetOrientation, float, float);
void Process_FlyBy(const CVector&, float, float, float);
- void Process_WheelCam(const CVector&, float, float, float);
+ bool Process_WheelCam(const CVector&, float, float, float);
void Process_Fixed(const CVector &CameraTarget, float, float, float);
void Process_Player_Fallen_Water(const CVector &CameraTarget, float TargetOrientation, float, float);
- void Process_Circle(const CVector &CameraTarget, float, float, float);
void Process_SpecialFixedForSyphon(const CVector &CameraTarget, float, float, float);
+ void Process_LightHouse(const CVector &CameraTarget, float, float, float);
void ProcessPedsDeadBaby(void);
bool ProcessArrestCamOne(void);
bool ProcessArrestCamTwo(void);
-
- /* Some of the unused PS2 cams */
- void Process_Chris_With_Binding_PlusRotation(const CVector &CameraTarget, float, float, float);
- void Process_ReactionCam(const CVector &CameraTarget, float TargetOrientation, float, float);
- void Process_FollowPed_WithBinding(const CVector &CameraTarget, float TargetOrientation, float, float);
- // TODO:
- // CCam::Process_CushyPillows_Arse
- // CCam::Process_Look_At_Cars
- // CCam::Process_CheesyZoom
- // CCam::Process_Aiming
- void Process_Bill(const CVector &CameraTarget, float TargetOrientation, float SpeedVar, float TargetSpeedVar);
- void Process_Im_The_Passenger_Woo_Woo(const CVector &CameraTarget, float TargetOrientation, float, float);
- void Process_Blood_On_The_Tracks(const CVector &CameraTarget, float TargetOrientation, float, float);
- void Process_Cam_Running_Side_Train(const CVector &CameraTarget, float TargetOrientation, float, float);
- void Process_Cam_On_Train_Roof(const CVector &CameraTarget, float TargetOrientation, float, float);
+ bool GetLookAlongGroundPos(CEntity *Target, CPed *Cop, CVector &TargetCoors, CVector &SourceOut);
+ bool GetLookFromLampPostPos(CEntity *Target, CPed *Cop, CVector &TargetCoors, CVector &SourceOut);
+ bool GetLookOverShoulderPos(CEntity *Target, CPed *Cop, CVector &TargetCoors, CVector &SourceOut);
// custom stuff
void Process_FollowPed_Rotation(const CVector &CameraTarget, float TargetOrientation, float, float);
void Process_FollowCar_SA(const CVector &CameraTarget, float TargetOrientation, float, float);
};
-VALIDATE_SIZE(CCam, 0x1A4);
-
class CCamPathSplines
{
public:
enum {MAXPATHLENGTH=800};
- float m_arr_PathData[MAXPATHLENGTH];
+// float m_arr_PathData[MAXPATHLENGTH];
+ float *m_arr_PathData;
CCamPathSplines(void);
};
@@ -350,13 +333,14 @@ public:
bool m_bcutsceneFinished;
bool m_bCullZoneChecksOn;
bool m_bFirstPersonBeingUsed;
- bool m_bUnknown;
+ bool m_bJustJumpedOutOf1stPersonBecauseOfTarget;
bool m_bIdleOn;
bool m_bInATunnelAndABigVehicle;
bool m_bInitialNodeFound;
bool m_bInitialNoNodeStaticsSet;
bool m_bIgnoreFadingStuffForMusic;
bool m_bPlayerIsInGarage;
+ bool m_bPlayerWasOnBike;
bool m_bJustCameOutOfGarage;
bool m_bJustInitalised;
bool m_bJust_Switched;
@@ -381,6 +365,9 @@ public:
bool m_WideScreenOn;
bool m_1rstPersonRunCloseToAWall;
bool m_bHeadBob;
+ bool m_bVehicleSuspenHigh;
+ bool m_bEnable1rstPersonCamCntrlsScript;
+ bool m_bAllow1rstPersonWeaponsCamera;
bool m_bFailedCullZoneTestPreviously;
bool m_FadeTargetIsSplashScreen;
@@ -396,15 +383,16 @@ public:
uint8 m_uiTransitionState; // 0:one mode 1:transition
uint32 m_uiTimeLastChange;
+ uint32 m_uiTimeWeLeftIdle_StillNoInput;
uint32 m_uiTimeWeEnteredIdle;
uint32 m_uiTimeTransitionStart;
uint32 m_uiTransitionDuration;
+ uint32 m_uiTransitionDurationTargetCoors;
int m_BlurBlue;
int m_BlurGreen;
int m_BlurRed;
int m_BlurType;
- uint32 unknown; // some counter having to do with music
int m_iWorkOutSpeedThisNumFrames;
int m_iNumFramesSoFar;
@@ -427,12 +415,9 @@ public:
float CarZoomValueSmooth;
float DistanceToWater;
-#ifndef PS2_CAM_TRANSITION
float FOVDuringInter;
-#endif
float LODDistMultiplier;
float GenerationDistMultiplier;
-#ifndef PS2_CAM_TRANSITION
float m_fAlphaSpeedAtStartInter;
float m_fAlphaWhenInterPol;
float m_fAlphaDuringInterPol;
@@ -443,7 +428,6 @@ public:
float m_fFOVSpeedAtStartInter;
float m_fStartingBetaForInterPol;
float m_fStartingAlphaForInterPol;
-#endif
float m_PedOrientForBehindOrInFront;
float m_CameraAverageSpeed;
float m_CameraSpeedSoFar;
@@ -468,17 +452,18 @@ public:
float PedZoomIndicator;
#endif
float PlayerExhaustion;
- float SoundDistUp, SoundDistLeft, SoundDistRight;
- float SoundDistUpAsRead, SoundDistLeftAsRead, SoundDistRightAsRead;
- float SoundDistUpAsReadOld, SoundDistLeftAsReadOld, SoundDistRightAsReadOld;
+ float SoundDistUp;
+ float SoundDistUpAsRead;
+ float SoundDistUpAsReadOld;
+ float m_fAvoidTheGeometryProbsTimer;
+ int16 m_nAvoidTheGeometryProbsDirn;
float m_fWideScreenReductionAmount;
float m_fStartingFOVForInterPol;
- // 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_fMouseAccelHorzntl;// acceleration multiplier for 1st person controls
+ static float m_fMouseAccelVertical;// acceleration multiplier for 1st person controls
+ static float m_f3rdPersonCHairMultX;
+ static float m_f3rdPersonCHairMultY;
CCam Cams[3];
@@ -493,7 +478,7 @@ public:
CVector m_vecFixedModeSource;
CVector m_vecFixedModeUpOffSet;
CVector m_vecCutSceneOffset;
-#ifndef PS2_CAM_TRANSITION
+
CVector m_cvecStartingSourceForInterPol;
CVector m_cvecStartingTargetForInterPol;
CVector m_cvecStartingUpForInterPol;
@@ -503,17 +488,17 @@ public:
CVector m_vecSourceWhenInterPol;
CVector m_vecTargetWhenInterPol;
CVector m_vecUpWhenInterPol;
-#endif
+ CVector m_vecClearGeometryVec;
CVector m_vecGameCamPos;
-#ifndef PS2_CAM_TRANSITION
CVector SourceDuringInter;
CVector TargetDuringInter;
CVector UpDuringInter;
-#endif
RwCamera *m_pRwCamera;
CEntity *pTargetEntity;
CCamPathSplines m_arrPathArray[MAX_NUM_OF_SPLINETYPES];
+#ifdef GTA_TRAIN
CTrainCamNode m_arrTrainCamNode[MAX_NUM_OF_NODES];
+#endif
CMatrix m_cameraMatrix;
bool m_bGarageFixedCamPositionSet;
bool m_vecDoingSpecialInterPolation;
@@ -532,6 +517,8 @@ public:
float m_fTimeToFadeMusic;
float m_fFractionInterToStopMoving;
float m_fFractionInterToStopCatchUp;
+ float m_fFractionInterToStopMovingTarget;
+ float m_fFractionInterToStopCatchUpTarget;
float m_fGaitSwayBuffer;
float m_fScriptPercentageInterToStopMoving;
float m_fScriptPercentageInterToCatchUp;
@@ -555,7 +542,6 @@ public:
// High level and misc
CCamera(void);
- CCamera(float);
void Init(void);
void Process(void);
void CamControl(void);
@@ -564,6 +550,9 @@ public:
void InitialiseCameraForDebugMode(void);
void CamShake(float strength, float x, float y, float z);
bool Get_Just_Switched_Status() { return m_bJust_Switched; }
+ void AvoidTheGeometry(const CVector &Source, const CVector &TargetPos, CVector &NewSource, float FOV);
+ void GetArrPosForVehicleType(int apperance, int &index);
+ void GetScreenRect(CRect &rect);
// Who's in control
void TakeControl(CEntity *target, int16 mode, int16 typeOfSwitch, int32 controller);
@@ -589,6 +578,7 @@ public:
bool TryToStartNewCamMode(int32 obbeMode);
void DontProcessObbeCinemaCamera(void);
void ProcessObbeCinemaCameraCar(void);
+ void ProcessObbeCinemaCameraHeli(void);
void ProcessObbeCinemaCameraPed(void);
// Train
@@ -597,6 +587,7 @@ public:
// Script
void LoadPathSplines(int file);
+ void DeleteCutSceneCamDataMemory(void);
void FinishCutscene(void);
float GetPositionAlongSpline(void) { return m_fPositionAlongSpline; }
uint32 GetCutSceneFinishTime(void);
@@ -632,6 +623,7 @@ public:
void UpdateAimingCoors(CVector const &coors);
bool Find3rdPersonCamTargetVector(float dist, CVector pos, CVector &source, CVector &target);
float Find3rdPersonQuickAimPitch(void);
+ bool Using1stPersonWeaponMode(void);
// Physical camera
void SetRwCamera(RwCamera *cam);
@@ -639,7 +631,7 @@ public:
CVector &GetGameCamPosition(void) { return m_vecGameCamPos; }
void CalculateDerivedValues(void);
bool IsPointVisible(const CVector &center, const CMatrix *mat);
- bool IsSphereVisible(const CVector &center, float radius, Const CMatrix *mat);
+ bool IsSphereVisible(const CVector &center, float radius, const CMatrix *mat);
bool IsSphereVisible(const CVector &center, float radius);
bool IsBoxVisible(CVUVECTOR *box, const CMatrix *mat);
};
diff --git a/src/core/Clock.cpp b/src/core/Clock.cpp
index e4b908e0..a3298343 100644
--- a/src/core/Clock.cpp
+++ b/src/core/Clock.cpp
@@ -4,6 +4,7 @@
#include "Pad.h"
#include "Clock.h"
#include "Stats.h"
+#include "VarConsole.h"
_TODO("gbFastTime");
bool gbFastTime;
@@ -18,6 +19,10 @@ uint32 CClock::ms_nMillisecondsPerGameMinute;
uint32 CClock::ms_nLastClockTick;
bool CClock::ms_bClockHasBeenStored;
+#ifndef MASTER
+bool gbFreezeTime;
+#endif
+
void
CClock::Initialise(uint32 scale)
{
@@ -29,6 +34,10 @@ CClock::Initialise(uint32 scale)
ms_nLastClockTick = CTimer::GetTimeInMilliseconds();
ms_bClockHasBeenStored = false;
debug("CClock ready\n");
+#ifndef MASTER
+ VarConsole.Add("Time (hour of day)", &ms_nGameClockHours, 1, 0, 23, true);
+ VarConsole.Add("Freeze time", &gbFreezeTime, true);
+#endif
}
void
@@ -48,6 +57,10 @@ CClock::Update(void)
}
}
+#ifndef MASTER
+ else if (gbFreezeTime)
+ ms_nLastClockTick = CTimer::GetTimeInMilliseconds();
+#endif
else if(CTimer::GetTimeInMilliseconds() - ms_nLastClockTick > ms_nMillisecondsPerGameMinute || gbFastTime)
{
ms_nGameClockMinutes++;
@@ -73,8 +86,14 @@ CClock::Update(void)
void
CClock::SetGameClock(uint8 h, uint8 m)
{
- ms_nGameClockHours = h;
+ while (m >= 60) {
+ m -= 60;
+ h++;
+ }
ms_nGameClockMinutes = m;
+ while (h >= 24)
+ h -= 24;
+ ms_nGameClockHours = h;
ms_nGameClockSeconds = 0;
ms_nLastClockTick = CTimer::GetTimeInMilliseconds();
}
diff --git a/src/core/ControllerConfig.cpp b/src/core/ControllerConfig.cpp
index e72af7e4..dbb0bd87 100644
--- a/src/core/ControllerConfig.cpp
+++ b/src/core/ControllerConfig.cpp
@@ -130,7 +130,7 @@ void CControllerConfigManager::SaveSettings(int32 file)
void CControllerConfigManager::LoadSettings(int32 file)
{
bool bValid = true;
-
+ int nVersion = 0;
#ifdef BIND_VEHICLE_FIREWEAPON
bool skipVehicleFireWeapon = false;
#endif
@@ -144,35 +144,15 @@ void CControllerConfigManager::LoadSettings(int32 file)
bValid = false;
else {
CFileMgr::Seek(file, 0, 0);
-
-#ifdef BIND_VEHICLE_FIREWEAPON
- // HACK!
- // All of this is hacky as fuck.
- // We are checking the file size to read the .set file correctly.
- // But because .set file is opened in text mode we have to read
- // the WHOLE file to get the size we should be working with.
- // Joy, ain't it?
- char tempBuf[0x1000];
- size_t fileSize = 0, blockSize;
- do
- {
- blockSize = CFileMgr::Read(file, tempBuf, sizeof(tempBuf));
- fileSize += blockSize;
- } while (blockSize == sizeof(tempBuf));
-
- CFileMgr::Seek(file, 0, 0);
-
- if (fileSize == 0x671)
- skipVehicleFireWeapon = true;
-#endif
+ CFileMgr::Read(file, (char*)&nVersion, sizeof(nVersion));
}
}
- if (bValid)
+ if (bValid && nVersion >= 3)
{
ControlsManager.MakeControllerActionsBlank();
-
#ifdef BIND_VEHICLE_FIREWEAPON
+ skipVehicleFireWeapon = nVersion < 4;
// Set the default settings of VEHICLE_FIREWEAPON
if (skipVehicleFireWeapon) {
SetControllerKeyAssociatedWithAction(VEHICLE_FIREWEAPON, rsPADINS, KEYBOARD);
@@ -242,9 +222,13 @@ void CControllerConfigManager::InitDefaultControlConfiguration()
SetControllerKeyAssociatedWithAction (GO_BACK, rsDOWN, KEYBOARD);
SetControllerKeyAssociatedWithAction (GO_BACK, 'S', OPTIONAL_EXTRA);
+
+ SetControllerKeyAssociatedWithAction (NETWORK_TALK, 'T', KEYBOARD);
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);
@@ -260,6 +244,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 ?
@@ -302,7 +288,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++)
{
@@ -345,6 +331,10 @@ void CControllerConfigManager::InitDefaultControlConfigMouse(CMouseControllerSta
SetMouseButtonAssociatedWithAction(PED_CYCLE_WEAPON_RIGHT, 5);
SetMouseButtonAssociatedWithAction(VEHICLE_CHANGE_RADIO_STATION, 4);
+
+ SetMouseButtonAssociatedWithAction(PED_SNIPER_ZOOM_IN, 4);
+
+ SetMouseButtonAssociatedWithAction(PED_SNIPER_ZOOM_OUT, 5);
}
}
@@ -407,13 +397,14 @@ void CControllerConfigManager::InitDefaultControlConfigJoyPad(uint32 buttons)
SetControllerKeyAssociatedWithAction(TOGGLE_SUBMISSIONS, 11, JOYSTICK);
IF_BTN_IN_RANGE(10)
SetControllerKeyAssociatedWithAction(VEHICLE_HORN, 10, JOYSTICK);
+ SetControllerKeyAssociatedWithAction(PED_DUCK, 10, JOYSTICK);
IF_BTN_IN_RANGE(9)
SetControllerKeyAssociatedWithAction(CAMERA_CHANGE_VIEW_ALL_SITUATIONS, 9, JOYSTICK);
IF_BTN_IN_RANGE(8)
SetControllerKeyAssociatedWithAction(VEHICLE_HANDBRAKE, 8, JOYSTICK);
SetControllerKeyAssociatedWithAction(PED_LOCK_TARGET, 8, JOYSTICK);
IF_BTN_IN_RANGE(7)
- SetControllerKeyAssociatedWithAction(PED_CENTER_CAMERA_BEHIND_PLAYER, 7, JOYSTICK);
+ SetControllerKeyAssociatedWithAction(PED_ANSWER_PHONE, 7, JOYSTICK);
SetControllerKeyAssociatedWithAction(VEHICLE_CHANGE_RADIO_STATION, 7, JOYSTICK);
IF_BTN_IN_RANGE(6)
SetControllerKeyAssociatedWithAction(PED_CYCLE_WEAPON_RIGHT, 6, JOYSTICK);
@@ -458,13 +449,14 @@ void CControllerConfigManager::InitDefaultControlConfigJoyPad(uint32 buttons)
SetControllerKeyAssociatedWithAction(TOGGLE_SUBMISSIONS, 11, JOYSTICK);
IF_BTN_IN_RANGE(10)
SetControllerKeyAssociatedWithAction(VEHICLE_HORN, 10, JOYSTICK);
+ SetControllerKeyAssociatedWithAction(PED_DUCK, 10, JOYSTICK);
IF_BTN_IN_RANGE(9)
SetControllerKeyAssociatedWithAction(CAMERA_CHANGE_VIEW_ALL_SITUATIONS, 9, JOYSTICK);
IF_BTN_IN_RANGE(8)
SetControllerKeyAssociatedWithAction(VEHICLE_HANDBRAKE, 8, JOYSTICK);
SetControllerKeyAssociatedWithAction(PED_LOCK_TARGET, 8, JOYSTICK);
IF_BTN_IN_RANGE(7)
- SetControllerKeyAssociatedWithAction(PED_CENTER_CAMERA_BEHIND_PLAYER, 7, JOYSTICK);
+ SetControllerKeyAssociatedWithAction(PED_ANSWER_PHONE, 7, JOYSTICK);
SetControllerKeyAssociatedWithAction(VEHICLE_CHANGE_RADIO_STATION, 7, JOYSTICK);
IF_BTN_IN_RANGE(6)
SetControllerKeyAssociatedWithAction(PED_CYCLE_WEAPON_RIGHT, 6, JOYSTICK);
@@ -507,8 +499,11 @@ void CControllerConfigManager::InitialiseControllerActionNameArray()
SETACTIONNAME(PED_SPRINT);
SETACTIONNAME(PED_CYCLE_TARGET_LEFT);
SETACTIONNAME(PED_CYCLE_TARGET_RIGHT);
+ SETACTIONNAME(PED_LOCK_TARGET); // duplicate
SETACTIONNAME(PED_CENTER_CAMERA_BEHIND_PLAYER);
SETACTIONNAME(VEHICLE_LOOKBEHIND);
+ SETACTIONNAME(PED_DUCK);
+ SETACTIONNAME(PED_ANSWER_PHONE);
SETACTIONNAME(VEHICLE_LOOKLEFT);
SETACTIONNAME(VEHICLE_LOOKRIGHT);
SETACTIONNAME(VEHICLE_HORN);
@@ -534,6 +529,10 @@ void CControllerConfigManager::InitialiseControllerActionNameArray()
SETACTIONNAME(GO_RIGHT);
SETACTIONNAME(GO_FORWARD);
SETACTIONNAME(GO_BACK);
+ SETACTIONNAME(VEHICLE_TURRETLEFT);
+ SETACTIONNAME(VEHICLE_TURRETRIGHT);
+ SETACTIONNAME(VEHICLE_TURRETUP);
+ SETACTIONNAME(VEHICLE_TURRETDOWN);
SETACTIONNAME(NETWORK_TALK);
SETACTIONNAME(TOGGLE_DPAD);
SETACTIONNAME(SWITCH_DEBUG_CAM_ON);
@@ -563,11 +562,12 @@ void CControllerConfigManager::UpdateJoyInConfigMenus_ButtonDown(int32 button, i
case 13:
pad->PCTempJoyState.DPadUp = 255;
break;
-#ifdef REGISTER_START_BUTTON
case 12:
- pad->PCTempJoyState.Start = 255;
- break;
+#ifndef REGISTER_START_BUTTON
+ if (padnumber == 1)
#endif
+ pad->PCTempJoyState.Start = 255;
+ break;
case 11:
pad->PCTempJoyState.RightShock = 255;
break;
@@ -671,6 +671,7 @@ void CControllerConfigManager::AffectControllerStateOn_ButtonDown(int32 button,
if ( mode == CCam::MODE_1STPERSON
|| mode == CCam::MODE_SNIPER
|| mode == CCam::MODE_ROCKETLAUNCHER
+ || mode == CCam::MODE_CAMERA
|| mode == CCam::MODE_M16_1STPERSON)
{
firstPerson = true;
@@ -779,10 +780,7 @@ void CControllerConfigManager::AffectControllerStateOn_ButtonDown_Driving(int32
if (FindPlayerVehicle() && (FindPlayerVehicle()->IsVehicle() && (
FindPlayerVehicle()->GetModelIndex() == MI_DODO
#ifdef FIX_BUGS
- || CVehicle::bAllDodosCheat
-#ifdef ALLCARSHELI_CHEAT
- || bAllCarCheat
-#endif
+ || (CVehicle::bAllDodosCheat && !FindPlayerVehicle()->IsRealHeli())
#endif
)))
{
@@ -843,6 +841,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.LeftShock = 255;
}
void CControllerConfigManager::AffectControllerStateOn_ButtonDown_ThirdPersonOnly(int32 button, eControllerType type, CControllerState &state)
@@ -851,14 +851,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.LeftShock = 255;
- if (CMenuManager::m_ControlMethod == CONTROL_CLASSIC)
+ if (FrontEndMenuManager.m_ControlMethod == CONTROL_CLASSIC)
{
if (button == GetControllerKeyAssociatedWithAction(PED_CYCLE_TARGET_LEFT, type))
state.LeftShoulder2 = 255;
@@ -928,7 +932,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))
{
@@ -1686,12 +1690,12 @@ void CControllerConfigManager::DeleteMatchingCommonControls(e_ControllerAction a
{
if (!GetIsKeyBlank(key, type))
{
- CLEAR_ACTION_IF_NEEDED(CAMERA_CHANGE_VIEW_ALL_SITUATIONS);
#ifndef BIND_VEHICLE_FIREWEAPON
CLEAR_ACTION_IF_NEEDED(PED_FIREWEAPON);
#endif
CLEAR_ACTION_IF_NEEDED(GO_LEFT);
CLEAR_ACTION_IF_NEEDED(GO_RIGHT);
+ CLEAR_ACTION_IF_NEEDED(CAMERA_CHANGE_VIEW_ALL_SITUATIONS);
CLEAR_ACTION_IF_NEEDED(NETWORK_TALK);
CLEAR_ACTION_IF_NEEDED(SWITCH_DEBUG_CAM_ON);
CLEAR_ACTION_IF_NEEDED(TOGGLE_DPAD);
@@ -1704,13 +1708,15 @@ void CControllerConfigManager::DeleteMatching3rdPersonControls(e_ControllerActio
{
if (!GetIsKeyBlank(key, type))
{
- CLEAR_ACTION_IF_NEEDED(PED_LOOKBEHIND);
CLEAR_ACTION_IF_NEEDED(PED_CYCLE_WEAPON_LEFT);
CLEAR_ACTION_IF_NEEDED(PED_CYCLE_WEAPON_RIGHT);
CLEAR_ACTION_IF_NEEDED(PED_JUMPING);
CLEAR_ACTION_IF_NEEDED(PED_SPRINT);
+ CLEAR_ACTION_IF_NEEDED(PED_LOOKBEHIND);
+ CLEAR_ACTION_IF_NEEDED(PED_DUCK);
+ CLEAR_ACTION_IF_NEEDED(PED_ANSWER_PHONE);
- if (CMenuManager::m_ControlMethod == CONTROL_CLASSIC)
+ if (FrontEndMenuManager.m_ControlMethod == CONTROL_CLASSIC)
{
CLEAR_ACTION_IF_NEEDED(PED_CYCLE_TARGET_LEFT);
CLEAR_ACTION_IF_NEEDED(PED_CYCLE_TARGET_RIGHT);
@@ -1730,7 +1736,7 @@ void CControllerConfigManager::DeleteMatching1rst3rdPersonControls(e_ControllerA
CLEAR_ACTION_IF_NEEDED(GO_FORWARD);
CLEAR_ACTION_IF_NEEDED(GO_BACK);
- if (CMenuManager::m_ControlMethod == CONTROL_CLASSIC)
+ if (FrontEndMenuManager.m_ControlMethod == CONTROL_CLASSIC)
{
CLEAR_ACTION_IF_NEEDED(PED_1RST_PERSON_LOOK_LEFT);
CLEAR_ACTION_IF_NEEDED(PED_1RST_PERSON_LOOK_RIGHT);
@@ -1747,16 +1753,15 @@ void CControllerConfigManager::DeleteMatchingVehicleControls(e_ControllerAction
#ifdef BIND_VEHICLE_FIREWEAPON
CLEAR_ACTION_IF_NEEDED(VEHICLE_FIREWEAPON);
#endif
- CLEAR_ACTION_IF_NEEDED(VEHICLE_LOOKBEHIND);
- CLEAR_ACTION_IF_NEEDED(VEHICLE_LOOKLEFT);
- CLEAR_ACTION_IF_NEEDED(VEHICLE_LOOKRIGHT);
- CLEAR_ACTION_IF_NEEDED(VEHICLE_LOOKBEHIND); // note: duplicate
- CLEAR_ACTION_IF_NEEDED(VEHICLE_HORN);
- CLEAR_ACTION_IF_NEEDED(VEHICLE_HANDBRAKE);
CLEAR_ACTION_IF_NEEDED(VEHICLE_ACCELERATE);
CLEAR_ACTION_IF_NEEDED(VEHICLE_BRAKE);
CLEAR_ACTION_IF_NEEDED(VEHICLE_CHANGE_RADIO_STATION);
+ CLEAR_ACTION_IF_NEEDED(VEHICLE_HORN);
CLEAR_ACTION_IF_NEEDED(TOGGLE_SUBMISSIONS);
+ CLEAR_ACTION_IF_NEEDED(VEHICLE_HANDBRAKE);
+ CLEAR_ACTION_IF_NEEDED(VEHICLE_LOOKLEFT);
+ CLEAR_ACTION_IF_NEEDED(VEHICLE_LOOKRIGHT);
+ CLEAR_ACTION_IF_NEEDED(VEHICLE_LOOKBEHIND);
CLEAR_ACTION_IF_NEEDED(VEHICLE_TURRETLEFT);
CLEAR_ACTION_IF_NEEDED(VEHICLE_TURRETRIGHT);
CLEAR_ACTION_IF_NEEDED(VEHICLE_TURRETUP);
@@ -1799,7 +1804,6 @@ bool CControllerConfigManager::IsAnyVehicleActionAssignedToMouseKey(int32 key)
CHECK_ACTION(VEHICLE_LOOKBEHIND);
CHECK_ACTION(VEHICLE_LOOKLEFT);
CHECK_ACTION(VEHICLE_LOOKRIGHT);
- CHECK_ACTION(VEHICLE_LOOKBEHIND); // note: duplicate
CHECK_ACTION(VEHICLE_HORN);
CHECK_ACTION(VEHICLE_HANDBRAKE);
CHECK_ACTION(VEHICLE_ACCELERATE);
@@ -1841,36 +1845,36 @@ void CControllerConfigManager::DeleteMatchingActionInitiators(e_ControllerAction
DeleteMatching1rst3rdPersonControls (action, key, type);
break;
case ACTIONTYPE_3RDPERSON:
- DeleteMatching3rdPersonControls (action, key, type);
DeleteMatchingCommonControls (action, key, type);
- DeleteMatchingVehicle_3rdPersonControls(action, key, type);
DeleteMatching1rst3rdPersonControls (action, key, type);
+ DeleteMatching3rdPersonControls (action, key, type);
+ DeleteMatchingVehicle_3rdPersonControls(action, key, type);
break;
case ACTIONTYPE_VEHICLE:
- DeleteMatchingVehicleControls (action, key, type);
DeleteMatchingCommonControls (action, key, type);
+ DeleteMatchingVehicleControls (action, key, type);
DeleteMatchingVehicle_3rdPersonControls(action, key, type);
break;
case ACTIONTYPE_VEHICLE_3RDPERSON:
- DeleteMatching3rdPersonControls (action, key, type);
- DeleteMatchingVehicleControls (action, key, type);
DeleteMatchingCommonControls (action, key, type);
DeleteMatching1rst3rdPersonControls (action, key, type);
- break;
- case ACTIONTYPE_1RST3RDPERSON:
- DeleteMatching1rstPersonControls (action, key, type);
DeleteMatching3rdPersonControls (action, key, type);
- DeleteMatchingCommonControls (action, key, type);
- DeleteMatchingVehicle_3rdPersonControls(action, key, type);
- DeleteMatching1rst3rdPersonControls (action, key, type);
+ DeleteMatchingVehicleControls (action, key, type);
break;
case ACTIONTYPE_COMMON:
+ DeleteMatchingCommonControls (action, key, type);
DeleteMatching1rstPersonControls (action, key, type);
+ DeleteMatching1rst3rdPersonControls (action, key, type);
DeleteMatching3rdPersonControls (action, key, type);
DeleteMatchingVehicleControls (action, key, type);
DeleteMatchingVehicle_3rdPersonControls(action, key, type);
+ break;
+ case ACTIONTYPE_1RST3RDPERSON:
DeleteMatchingCommonControls (action, key, type);
+ DeleteMatching1rstPersonControls (action, key, type);
DeleteMatching1rst3rdPersonControls (action, key, type);
+ DeleteMatching3rdPersonControls (action, key, type);
+ DeleteMatchingVehicle_3rdPersonControls(action, key, type);
break;
default: break;
}
@@ -1906,25 +1910,27 @@ e_ControllerActionType CControllerConfigManager::GetActionType(e_ControllerActio
{
switch (action)
{
- case CAMERA_CHANGE_VIEW_ALL_SITUATIONS:
#ifndef BIND_VEHICLE_FIREWEAPON
case PED_FIREWEAPON:
#endif
case GO_LEFT:
case GO_RIGHT:
+ case CAMERA_CHANGE_VIEW_ALL_SITUATIONS:
case NETWORK_TALK:
- case SWITCH_DEBUG_CAM_ON:
case TOGGLE_DPAD:
+ case SWITCH_DEBUG_CAM_ON:
case TAKE_SCREEN_SHOT:
case SHOW_MOUSE_POINTER_TOGGLE:
return ACTIONTYPE_COMMON;
break;
- case PED_LOOKBEHIND:
- case PED_CYCLE_WEAPON_LEFT:
case PED_CYCLE_WEAPON_RIGHT:
+ case PED_CYCLE_WEAPON_LEFT:
case PED_JUMPING:
case PED_SPRINT:
+ case PED_LOOKBEHIND:
+ case PED_DUCK:
+ case PED_ANSWER_PHONE:
case PED_CYCLE_TARGET_LEFT:
case PED_CYCLE_TARGET_RIGHT:
case PED_CENTER_CAMERA_BEHIND_PLAYER:
@@ -1934,15 +1940,15 @@ e_ControllerActionType CControllerConfigManager::GetActionType(e_ControllerActio
#ifdef BIND_VEHICLE_FIREWEAPON
case VEHICLE_FIREWEAPON:
#endif
- case VEHICLE_LOOKBEHIND:
- case VEHICLE_LOOKLEFT:
- case VEHICLE_LOOKRIGHT:
- case VEHICLE_HORN:
- case VEHICLE_HANDBRAKE:
case VEHICLE_ACCELERATE:
case VEHICLE_BRAKE:
case VEHICLE_CHANGE_RADIO_STATION:
+ case VEHICLE_HORN:
case TOGGLE_SUBMISSIONS:
+ case VEHICLE_HANDBRAKE:
+ case VEHICLE_LOOKLEFT:
+ case VEHICLE_LOOKRIGHT:
+ case VEHICLE_LOOKBEHIND:
case VEHICLE_TURRETLEFT:
case VEHICLE_TURRETRIGHT:
case VEHICLE_TURRETUP:
@@ -1957,13 +1963,13 @@ e_ControllerActionType CControllerConfigManager::GetActionType(e_ControllerActio
#ifdef BIND_VEHICLE_FIREWEAPON
case PED_FIREWEAPON:
#endif
- case PED_LOCK_TARGET:
case GO_FORWARD:
case GO_BACK:
case PED_1RST_PERSON_LOOK_LEFT:
case PED_1RST_PERSON_LOOK_RIGHT:
- case PED_1RST_PERSON_LOOK_DOWN:
+ case PED_LOCK_TARGET:
case PED_1RST_PERSON_LOOK_UP:
+ case PED_1RST_PERSON_LOOK_DOWN:
return ACTIONTYPE_1RST3RDPERSON;
break;
@@ -2433,15 +2439,15 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act
#define VFB(b)
#endif
-#define CONTROLLER_BUTTONS(T, O, X, Q, L1, L2, L3, R1, R2, R3, SELECT) \
+#define CONTROLLER_BUTTONS(T, O, X, Q, L1, L2, L3, R1, R2, R3, SELECT, RSU, RSD, RSL, RSR) \
{{ \
O, /* PED_FIREWEAPON */ \
R2, /* PED_CYCLE_WEAPON_RIGHT */ \
L2, /* PED_CYCLE_WEAPON_LEFT */ \
nil, /* GO_FORWARD */ \
nil, /* GO_BACK */ \
- nil, /* GO_LEFT */ \
- nil, /* GO_RIGHT */ \
+ LEFT, /* GO_LEFT */ \
+ RIGHT, /* GO_RIGHT */ \
Q, /* PED_SNIPER_ZOOM_IN */ \
X, /* PED_SNIPER_ZOOM_OUT */ \
T, /* VEHICLE_ENTER_EXIT */ \
@@ -2449,6 +2455,8 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act
Q, /* PED_JUMPING */ \
X, /* PED_SPRINT */ \
R3, /* PED_LOOKBEHIND */ \
+ L3, /* PED_DUCK */ \
+ L1, /* PED_ANSWER_PHONE */ \
VFB(O) /* VEHICLE_FIREWEAPON */ \
X, /* VEHICLE_ACCELERATE */ \
Q, /* VEHICLE_BRAKE */ \
@@ -2461,10 +2469,10 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act
L2, /* VEHICLE_LOOKLEFT */ \
R2, /* VEHICLE_LOOKRIGHT */ \
nil, /* VEHICLE_LOOKBEHIND */ \
- nil, /* VEHICLE_TURRETLEFT */ \
- nil, /* VEHICLE_TURRETRIGHT */ \
- nil, /* VEHICLE_TURRETUP */ \
- nil, /* VEHICLE_TURRETDOWN */ \
+ RSL, /* VEHICLE_TURRETLEFT */ \
+ RSR, /* VEHICLE_TURRETRIGHT */ \
+ UP, /* VEHICLE_TURRETUP */ \
+ DOWN, /* VEHICLE_TURRETDOWN */ \
L2, /* PED_CYCLE_TARGET_LEFT */ \
R2, /* PED_CYCLE_TARGET_RIGHT */ \
L1, /* PED_CENTER_CAMERA_BEHIND_PLAYER */ \
@@ -2476,6 +2484,7 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act
nil, /* TOGGLE_DPAD */ \
nil, /* SWITCH_DEBUG_CAM_ON */ \
nil, /* TAKE_SCREEN_SHOT */ \
+ nil, /* UNKNOWN_ACTION */ \
nil, /* SHOW_MOUSE_POINTER_TOGGLE */ \
}, \
{ \
@@ -2484,8 +2493,8 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act
L2, /* PED_CYCLE_WEAPON_LEFT */ \
nil, /* GO_FORWARD */ \
nil, /* GO_BACK */ \
- nil, /* GO_LEFT */ \
- nil, /* GO_RIGHT */ \
+ LEFT, /* GO_LEFT */ \
+ RIGHT, /* GO_RIGHT */ \
Q, /* PED_SNIPER_ZOOM_IN */ \
X, /* PED_SNIPER_ZOOM_OUT */ \
T, /* VEHICLE_ENTER_EXIT */ \
@@ -2493,6 +2502,8 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act
Q, /* PED_JUMPING */ \
X, /* PED_SPRINT */ \
R3, /* PED_LOOKBEHIND */ \
+ L3, /* PED_DUCK */ \
+ L1, /* PED_ANSWER_PHONE */ \
VFB(O) /* VEHICLE_FIREWEAPON */ \
X, /* VEHICLE_ACCELERATE */ \
Q, /* VEHICLE_BRAKE */ \
@@ -2505,10 +2516,10 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act
L2, /* VEHICLE_LOOKLEFT */ \
R2, /* VEHICLE_LOOKRIGHT */ \
nil, /* VEHICLE_LOOKBEHIND */ \
- nil, /* VEHICLE_TURRETLEFT */ \
- nil, /* VEHICLE_TURRETRIGHT */ \
- nil, /* VEHICLE_TURRETUP */ \
- nil, /* VEHICLE_TURRETDOWN */ \
+ RSL, /* VEHICLE_TURRETLEFT */ \
+ RSR, /* VEHICLE_TURRETRIGHT */ \
+ UP, /* VEHICLE_TURRETUP */ \
+ DOWN, /* VEHICLE_TURRETDOWN */ \
L2, /* PED_CYCLE_TARGET_LEFT */ \
R2, /* PED_CYCLE_TARGET_RIGHT */ \
L1, /* PED_CENTER_CAMERA_BEHIND_PLAYER */ \
@@ -2520,6 +2531,7 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act
nil, /* TOGGLE_DPAD */ \
nil, /* SWITCH_DEBUG_CAM_ON */ \
nil, /* TAKE_SCREEN_SHOT */ \
+ nil, /* UNKNOWN_ACTION */ \
nil, /* SHOW_MOUSE_POINTER_TOGGLE */ \
}, \
{ \
@@ -2528,8 +2540,8 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act
L2, /* PED_CYCLE_WEAPON_LEFT */ \
nil, /* GO_FORWARD */ \
nil, /* GO_BACK */ \
- nil, /* GO_LEFT */ \
- nil, /* GO_RIGHT */ \
+ LEFT, /* GO_LEFT */ \
+ RIGHT, /* GO_RIGHT */ \
T, /* PED_SNIPER_ZOOM_IN */ \
Q, /* PED_SNIPER_ZOOM_OUT */ \
L1, /* VEHICLE_ENTER_EXIT */ \
@@ -2537,6 +2549,8 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act
Q, /* PED_JUMPING */ \
O, /* PED_SPRINT */ \
R3, /* PED_LOOKBEHIND */ \
+ L3, /* PED_DUCK */ \
+ T, /* PED_ANSWER_PHONE */ \
VFB(O) /* VEHICLE_FIREWEAPON */ \
X, /* VEHICLE_ACCELERATE */ \
Q, /* VEHICLE_BRAKE */ \
@@ -2549,10 +2563,10 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act
L2, /* VEHICLE_LOOKLEFT */ \
R2, /* VEHICLE_LOOKRIGHT */ \
nil, /* VEHICLE_LOOKBEHIND */ \
- nil, /* VEHICLE_TURRETLEFT */ \
- nil, /* VEHICLE_TURRETRIGHT */ \
- nil, /* VEHICLE_TURRETUP */ \
- nil, /* VEHICLE_TURRETDOWN */ \
+ RSL, /* VEHICLE_TURRETLEFT */ \
+ RSR, /* VEHICLE_TURRETRIGHT */ \
+ UP, /* VEHICLE_TURRETUP */ \
+ DOWN, /* VEHICLE_TURRETDOWN */ \
L2, /* PED_CYCLE_TARGET_LEFT */ \
R2, /* PED_CYCLE_TARGET_RIGHT */ \
T, /* PED_CENTER_CAMERA_BEHIND_PLAYER */ \
@@ -2564,6 +2578,7 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act
nil, /* TOGGLE_DPAD */ \
nil, /* SWITCH_DEBUG_CAM_ON */ \
nil, /* TAKE_SCREEN_SHOT */ \
+ nil, /* UNKNOWN_ACTION */ \
nil, /* SHOW_MOUSE_POINTER_TOGGLE */ \
}, \
{ \
@@ -2572,8 +2587,8 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act
L2, /* PED_CYCLE_WEAPON_LEFT */ \
nil, /* GO_FORWARD */ \
nil, /* GO_BACK */ \
- nil, /* GO_LEFT */ \
- nil, /* GO_RIGHT */ \
+ LEFT, /* GO_LEFT */ \
+ RIGHT, /* GO_RIGHT */ \
Q, /* PED_SNIPER_ZOOM_IN */ \
X, /* PED_SNIPER_ZOOM_OUT */ \
T, /* VEHICLE_ENTER_EXIT */ \
@@ -2581,9 +2596,11 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act
Q, /* PED_JUMPING */ \
X, /* PED_SPRINT */ \
R3, /* PED_LOOKBEHIND */ \
+ L3, /* PED_DUCK */ \
+ O, /* PED_ANSWER_PHONE */ \
VFB(R1) /* VEHICLE_FIREWEAPON */ \
- nil, /* VEHICLE_ACCELERATE */ \
- nil, /* VEHICLE_BRAKE */ \
+ RSU, /* VEHICLE_ACCELERATE */ \
+ RSD, /* VEHICLE_BRAKE */ \
O, /* VEHICLE_CHANGE_RADIO_STATION */ \
L3, /* VEHICLE_HORN */ \
Q, /* TOGGLE_SUBMISSIONS */ \
@@ -2593,10 +2610,10 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act
L2, /* VEHICLE_LOOKLEFT */ \
R2, /* VEHICLE_LOOKRIGHT */ \
nil, /* VEHICLE_LOOKBEHIND */ \
- nil, /* VEHICLE_TURRETLEFT */ \
- nil, /* VEHICLE_TURRETRIGHT */ \
- nil, /* VEHICLE_TURRETUP */ \
- nil, /* VEHICLE_TURRETDOWN */ \
+ RSL, /* VEHICLE_TURRETLEFT */ \
+ RSR, /* VEHICLE_TURRETRIGHT */ \
+ UP, /* VEHICLE_TURRETUP */ \
+ DOWN, /* VEHICLE_TURRETDOWN */ \
L2, /* PED_CYCLE_TARGET_LEFT */ \
R2, /* PED_CYCLE_TARGET_RIGHT */ \
O, /* PED_CENTER_CAMERA_BEHIND_PLAYER */ \
@@ -2608,14 +2625,26 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act
nil, /* TOGGLE_DPAD */ \
nil, /* SWITCH_DEBUG_CAM_ON */ \
nil, /* TAKE_SCREEN_SHOT */ \
+ nil, /* UNKNOWN_ACTION */ \
nil, /* SHOW_MOUSE_POINTER_TOGGLE */ \
}}
+#ifdef BUTTON_ICONS
+#define UP "~U~"
+#define DOWN "~D~"
+#define LEFT "~<~"
+#define RIGHT "~>~"
+#else
+#define UP "UP"
+#define DOWN "DOWN"
+#define LEFT "LEFT"
+#define RIGHT "RIGHT"
+#endif
-const char *XboxButtons_noIcons[][MAX_CONTROLLERACTIONS] = CONTROLLER_BUTTONS("Y", "B", "A", "X", "LB", "LT", "LS", "RB", "RT", "RS", "BACK");
+const char *XboxButtons_noIcons[][MAX_CONTROLLERACTIONS] = CONTROLLER_BUTTONS("Y", "B", "A", "X", "LB", "LT", "LS", "RB", "RT", "RS", "BACK", "right stick up", "right stick down", "right stick left", "right stick right");
#ifdef BUTTON_ICONS
-const char *XboxButtons[][MAX_CONTROLLERACTIONS] = CONTROLLER_BUTTONS("~T~", "~O~", "~X~", "~Q~", "~K~", "~M~", "~A~", "~J~", "~V~", "~C~", "BACK");
+const char *XboxButtons[][MAX_CONTROLLERACTIONS] = CONTROLLER_BUTTONS("~T~", "~O~", "~X~", "~Q~", "~K~", "~M~", "~A~", "~J~", "~V~", "~C~", "BACK", "~H~", "~L~", "~(~", "~)~");
#endif
@@ -2632,11 +2661,11 @@ const char *XboxButtons[][MAX_CONTROLLERACTIONS] = CONTROLLER_BUTTONS("~T~", "~O
#endif
const char *PlayStationButtons_noIcons[][MAX_CONTROLLERACTIONS] =
- CONTROLLER_BUTTONS(PS2_TRIANGLE, PS2_CIRCLE, PS2_CROSS, PS2_SQUARE, "L1", "L2", "L3", "R1", "R2", "R3", "SELECT");
+ CONTROLLER_BUTTONS(PS2_TRIANGLE, PS2_CIRCLE, PS2_CROSS, PS2_SQUARE, "L1", "L2", "L3", "R1", "R2", "R3", "SELECT", "right stick up", "right stick down", "right stick left", "right stick right");
#ifdef BUTTON_ICONS
const char *PlayStationButtons[][MAX_CONTROLLERACTIONS] =
- CONTROLLER_BUTTONS("~T~", "~O~", "~X~", "~Q~", "~K~", "~M~", "~A~", "~J~", "~V~", "~C~", "SELECT");
+ CONTROLLER_BUTTONS("~T~", "~O~", "~X~", "~Q~", "~K~", "~M~", "~A~", "~J~", "~V~", "~C~", "SELECT", "~H~", "~L~", "~(~", "~)~");
#endif
#undef PS2_TRIANGLE
@@ -2644,6 +2673,19 @@ const char *PlayStationButtons[][MAX_CONTROLLERACTIONS] =
#undef PS2_CROSS
#undef PS2_SQUARE
+const char *NintendoSwitchButtons_noIcons[][MAX_CONTROLLERACTIONS] =
+ CONTROLLER_BUTTONS("Y", "A", "B", "X", "L", "ZL", "LS", "R", "ZR", "RS", "BACK", "right stick up", "right stick down", "right stick left", "right stick right");
+
+#ifdef BUTTON_ICONS
+const char *NintendoSwitchButtons[][MAX_CONTROLLERACTIONS] =
+ CONTROLLER_BUTTONS("~T~", "~O~", "~X~", "~Q~", "~K~", "~M~", "~A~", "~J~", "~V~", "~C~", "BACK", "~H~", "~L~", "~(~", "~)~");
+#endif
+
+#undef UP
+#undef DOWN
+#undef LEFT
+#undef RIGHT
+
#undef CONTROLLER_BUTTONS
#undef VFB
@@ -2664,6 +2706,9 @@ void CControllerConfigManager::GetWideStringOfCommandKeys(uint16 action, wchar *
case CMenuManager::CONTROLLER_DUALSHOCK4:
Buttons = CFont::ButtonsSlot != -1 ? PlayStationButtons : PlayStationButtons_noIcons;
break;
+ case CMenuManager::CONTROLLER_NINTENDO_SWITCH:
+ Buttons = CFont::ButtonsSlot != -1 ? NintendoSwitchButtons : NintendoSwitchButtons_noIcons;
+ break;
default:
#endif
Buttons = CFont::ButtonsSlot != -1 ? XboxButtons : XboxButtons_noIcons;
@@ -2679,6 +2724,9 @@ void CControllerConfigManager::GetWideStringOfCommandKeys(uint16 action, wchar *
case CMenuManager::CONTROLLER_DUALSHOCK4:
Buttons = PlayStationButtons_noIcons;
break;
+ case CMenuManager::CONTROLLER_NINTENDO_SWITCH:
+ Buttons = NintendoSwitchButtons_noIcons;
+ break;
default:
Buttons = XboxButtons_noIcons;
break;
diff --git a/src/core/ControllerConfig.h b/src/core/ControllerConfig.h
index 295f03b9..d61e23e6 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,
#ifdef BIND_VEHICLE_FIREWEAPON
VEHICLE_FIREWEAPON,
#endif
@@ -62,6 +64,7 @@ enum e_ControllerAction
SWITCH_DEBUG_CAM_ON,
TAKE_SCREEN_SHOT,
SHOW_MOUSE_POINTER_TOGGLE,
+ UNKNOWN_ACTION,
MAX_CONTROLLERACTIONS,
};
diff --git a/src/core/Crime.h b/src/core/Crime.h
index 05829040..4c7ea315 100644
--- a/src/core/Crime.h
+++ b/src/core/Crime.h
@@ -18,6 +18,9 @@ enum eCrimeType {
CRIME_COP_BURNED,
CRIME_VEHICLE_BURNED,
CRIME_DESTROYED_CESSNA,
+ CRIME_EXPLOSION,
+ CRIME_HIT_PED_NASTYWEAPON,
+ CRIME_HIT_COP_NASTYWEAPON,
NUM_CRIME_TYPES
};
diff --git a/src/core/Debug.cpp b/src/core/Debug.cpp
index e794dcaf..e319388c 100644
--- a/src/core/Debug.cpp
+++ b/src/core/Debug.cpp
@@ -55,7 +55,7 @@ CDebug::DebugDisplayTextBuffer()
CFont::SetJustifyOn();
CFont::SetRightJustifyWrap(0.0f);
CFont::SetBackGroundOnlyTextOff();
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
#else
// this is not even readable
CFont::SetPropOff();
@@ -65,7 +65,7 @@ CDebug::DebugDisplayTextBuffer()
CFont::SetRightJustifyOn();
CFont::SetRightJustifyWrap(0.0f);
CFont::SetBackGroundOnlyTextOff();
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
CFont::SetPropOff();
#endif
do {
@@ -113,7 +113,7 @@ CDebug::DisplayScreenStrings()
CFont::SetRightJustifyWrap(0.0f);
CFont::SetWrapx(9999.0f);
CFont::SetBackGroundOnlyTextOff();
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
for(i = 0; i < ms_nScreenStrs; i++){
/*
diff --git a/src/core/EventList.cpp b/src/core/EventList.cpp
index 93f72d4e..b7f139b4 100644
--- a/src/core/EventList.cpp
+++ b/src/core/EventList.cpp
@@ -75,8 +75,6 @@ CEventList::RegisterEvent(eEventType type, eEventEntity entityType, CEntity *ent
switch(entityType){
case EVENT_ENTITY_PED:
ref = CPools::GetPedRef((CPed*)ent);
- if(ent->GetModelIndex() >= MI_GANG01 && ent->GetModelIndex() <= MI_CRIMINAL02)
- copsDontCare = true;
break;
case EVENT_ENTITY_VEHICLE:
ref = CPools::GetVehicleRef((CVehicle*)ent);
@@ -211,27 +209,43 @@ CEventList::ReportCrimeForEvent(eEventType type, intptr crimeId, bool copsDontCa
case EVENT_HIT_AND_RUN_COP: crime = CRIME_RUNOVER_COP; break;
case EVENT_SHOOT_PED: crime = CRIME_SHOOT_PED; break;
case EVENT_SHOOT_COP: crime = CRIME_SHOOT_COP; break;
+ case EVENT_EXPLOSION: crime = CRIME_EXPLOSION; break;
case EVENT_PED_SET_ON_FIRE: crime = CRIME_PED_BURNED; break;
case EVENT_COP_SET_ON_FIRE: crime = CRIME_COP_BURNED; break;
case EVENT_CAR_SET_ON_FIRE: crime = CRIME_VEHICLE_BURNED; break;
+ case EVENT_ASSAULT_NASTYWEAPON: crime = CRIME_HIT_PED_NASTYWEAPON; break;
+ case EVENT_ASSAULT_NASTYWEAPON_POLICE: crime = CRIME_HIT_COP_NASTYWEAPON; break;
default: crime = CRIME_NONE; break;
}
+ if (crime == CRIME_HIT_PED && IsPedPointerValid((CPed*)crimeId) && FindPlayerPed()->m_pWanted->GetWantedLevel() == 0 && ((CPed*)crimeId)->bBeingChasedByPolice) {
+ if (!((CPed*)crimeId)->DyingOrDead()) {
+ CMessages::AddBigMessage(TheText.Get("GOODBOY"), 5000, 0);
+ CWorld::Players[CWorld::PlayerInFocus].m_nMoney += 50;
+ }
+ return;
+ }
+
if(crime == CRIME_NONE)
return;
+#ifdef FIX_BUGS
+ CVector playerPedCoors = FindPlayerCoors();
+#else
CVector playerPedCoors = FindPlayerPed()->GetPosition();
+#endif
CVector playerCoors = FindPlayerCoors();
- if(CWanted::WorkOutPolicePresence(playerCoors, 14.0f) != 0){
- FindPlayerPed()->m_pWanted->RegisterCrime_Immediately(crime, playerPedCoors, crimeId, copsDontCare);
+ if(CWanted::WorkOutPolicePresence(playerCoors, 14.0f) != 0 ||
+ CGame::germanGame && (crime == CRIME_SHOOT_PED || crime == CRIME_SHOOT_COP || crime == CRIME_COP_BURNED || crime == CRIME_VEHICLE_BURNED)){
+ FindPlayerPed()->m_pWanted->RegisterCrime_Immediately(crime, playerPedCoors, (uint32)crimeId, copsDontCare);
FindPlayerPed()->m_pWanted->SetWantedLevelNoDrop(1);
}else
- FindPlayerPed()->m_pWanted->RegisterCrime(crime, playerPedCoors, crimeId, copsDontCare);
+ FindPlayerPed()->m_pWanted->RegisterCrime(crime, playerPedCoors, (uint32)crimeId, copsDontCare);
if(type == EVENT_ASSAULT_POLICE)
FindPlayerPed()->SetWantedLevelNoDrop(1);
- if(type == EVENT_SHOOT_COP)
+ if(type == EVENT_SHOOT_COP || type == EVENT_ASSAULT_NASTYWEAPON_POLICE)
FindPlayerPed()->SetWantedLevelNoDrop(2);
}
diff --git a/src/core/EventList.h b/src/core/EventList.h
index 4ced3a83..3e9d8fd4 100644
--- a/src/core/EventList.h
+++ b/src/core/EventList.h
@@ -22,10 +22,13 @@ 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_UNK, // Not on SA it seems
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 afa2a66f..dbf2cad9 100644
--- a/src/core/FileLoader.cpp
+++ b/src/core/FileLoader.cpp
@@ -1,4 +1,5 @@
#include "common.h"
+#include <ctype.h>
#include "main.h"
#include "General.h"
@@ -25,6 +26,9 @@
#include "CdStream.h"
#include "FileLoader.h"
#include "MemoryHeap.h"
+#include "Streaming.h"
+#include "ColStore.h"
+#include "Occlusion.h"
char CFileLoader::ms_line[256];
@@ -47,36 +51,24 @@ CFileLoader::LoadLevel(const char *filename)
{
int fd;
RwTexDictionary *savedTxd;
- eLevelName savedLevel;
bool objectsLoaded;
char *line;
char txdname[64];
savedTxd = RwTexDictionaryGetCurrent();
objectsLoaded = false;
- savedLevel = CGame::currLevel;
if(savedTxd == nil){
savedTxd = RwTexDictionaryCreate();
RwTexDictionarySetCurrent(savedTxd);
}
-#if GTA_VERSION <= GTA3_PS2_160
- CFileMgr::ChangeDir("\\DATA\\");
- fd = CFileMgr::OpenFile(filename, "r");
- CFileMgr::ChangeDir("\\");
-#else
fd = CFileMgr::OpenFile(filename, "r");
-#endif
assert(fd > 0);
for(line = LoadLine(fd); line; line = LoadLine(fd)){
if(*line == '#')
continue;
-#ifdef FIX_BUGS
if(strncmp(line, "EXIT", 4) == 0)
-#else
- if(strncmp(line, "EXIT", 9) == 0)
-#endif
break;
if(strncmp(line, "IMAGEPATH", 9) == 0){
@@ -90,12 +82,8 @@ CFileLoader::LoadLevel(const char *filename)
RwTexDictionaryDestroy(txd);
POP_MEMID();
}else if(strncmp(line, "COLFILE", 7) == 0){
- int level;
- sscanf(line+8, "%d", &level);
- CGame::currLevel = (eLevelName)level;
LoadingScreenLoadingFile(line+10);
- LoadCollisionFile(line+10);
- CGame::currLevel = savedLevel;
+ LoadCollisionFile(line+10, 0);
}else if(strncmp(line, "MODELFILE", 9) == 0){
LoadingScreenLoadingFile(line + 10);
LoadModelFile(line + 10);
@@ -107,19 +95,23 @@ CFileLoader::LoadLevel(const char *filename)
LoadObjectTypes(line + 4);
}else if(strncmp(line, "IPL", 3) == 0){
if(!objectsLoaded){
- PUSH_MEMID(MEMID_DEF_MODELS);
- CModelInfo::ConstructMloClumps();
- POP_MEMID();
+ LoadingScreenLoadingFile("Collision");
+ PUSH_MEMID(MEMID_WORLD);
CObjectData::Initialise("DATA\\OBJECT.DAT");
+ CStreaming::Init();
+ POP_MEMID();
+ PUSH_MEMID(MEMID_COLLISION);
+ CColStore::LoadAllCollision();
+ POP_MEMID();
+ for(int i = 0; i < MODELINFOSIZE; i++)
+ if(CModelInfo::GetModelInfo(i))
+ CModelInfo::GetModelInfo(i)->ConvertAnimFileIndex();
objectsLoaded = true;
}
PUSH_MEMID(MEMID_WORLD);
LoadingScreenLoadingFile(line + 4);
LoadScene(line + 4);
POP_MEMID();
- }else if(strncmp(line, "MAPZONE", 7) == 0){
- LoadingScreenLoadingFile(line + 8);
- LoadMapZones(line + 8);
}else if(strncmp(line, "SPLASH", 6) == 0){
#ifndef DISABLE_LOADING_SCREEN
LoadSplash(GetRandomSplashScreen());
@@ -133,30 +125,13 @@ CFileLoader::LoadLevel(const char *filename)
CFileMgr::CloseFile(fd);
RwTexDictionarySetCurrent(savedTxd);
-}
-void
-CFileLoader::LoadCollisionFromDatFile(int currlevel)
-{
- int fd;
- char *line;
-
- fd = CFileMgr::OpenFile(CGame::aDatFile, "r");
- assert(fd > 0);
-
- for(line = LoadLine(fd); line; line = LoadLine(fd)){
- if(*line == '#')
- continue;
-
- if(strncmp(line, "COLFILE", 7) == 0){
- int level;
- sscanf(line+8, "%d", &level);
- if(currlevel == level)
- LoadCollisionFile(line+10);
- }
- }
-
- CFileMgr::CloseFile(fd);
+ int i;
+ for(i = 1; i < COLSTORESIZE; i++)
+ if(CColStore::GetSlot(i))
+ CColStore::GetBoundingBox(i).Grow(120.0f);
+ CWorld::RepositionCertainDynamicObjects();
+ CColStore::RemoveAllCollision();
}
char*
@@ -200,7 +175,7 @@ struct ColHeader
};
void
-CFileLoader::LoadCollisionFile(const char *filename)
+CFileLoader::LoadCollisionFile(const char *filename, uint8 colSlot)
{
int fd;
char modelname[24];
@@ -211,6 +186,7 @@ CFileLoader::LoadCollisionFile(const char *filename)
debug("Loading collision file %s\n", filename);
fd = CFileMgr::OpenFile(filename, "rb");
+ assert(fd > 0);
while(CFileMgr::Read(fd, (char*)&header, sizeof(header))){
assert(header.ident == 'LLOC');
@@ -219,10 +195,11 @@ CFileLoader::LoadCollisionFile(const char *filename)
mi = CModelInfo::GetModelInfo(modelname, nil);
if(mi){
- if(mi->GetColModel()){
+ if(mi->GetColModel() && mi->DoesOwnColModel()){
LoadCollisionModel(work_buff+24, *mi->GetColModel(), modelname);
}else{
CColModel *model = new CColModel;
+ model->level = colSlot;
LoadCollisionModel(work_buff+24, *model, modelname);
mi->SetColModel(model, true);
}
@@ -236,6 +213,79 @@ CFileLoader::LoadCollisionFile(const char *filename)
POP_MEMID();
}
+
+bool
+CFileLoader::LoadCollisionFileFirstTime(uint8 *buffer, uint32 size, uint8 colSlot)
+{
+ uint32 modelsize;
+ char modelname[24];
+ CBaseModelInfo *mi;
+ ColHeader *header;
+ int modelIndex;
+
+ while(size > 8){
+ header = (ColHeader*)buffer;
+ modelsize = header->size;
+ if(header->ident != 'LLOC')
+ return size-8 < CDSTREAM_SECTOR_SIZE;
+ memcpy(modelname, buffer+8, 24);
+ memcpy(work_buff, buffer+32, modelsize-24);
+ size -= 32 + (modelsize-24);
+ buffer += 32 + (modelsize-24);
+ if(modelsize > 15*1024)
+ debug("colmodel %s is huge, size %d\n", modelname, modelsize);
+
+ mi = CModelInfo::GetModelInfo(modelname, &modelIndex);
+ if(mi){
+ CColStore::IncludeModelIndex(colSlot, modelIndex);
+ CColModel *model = new CColModel;
+ model->level = colSlot;
+ LoadCollisionModel(work_buff, *model, modelname);
+ mi->SetColModel(model, true);
+ }else{
+ debug("colmodel %s can't find a modelinfo\n", modelname);
+ }
+ }
+ return true;
+}
+
+bool
+CFileLoader::LoadCollisionFile(uint8 *buffer, uint32 size, uint8 colSlot)
+{
+ uint32 modelsize;
+ char modelname[24];
+ CBaseModelInfo *mi;
+ ColHeader *header;
+
+ while(size > 8){
+ header = (ColHeader*)buffer;
+ modelsize = header->size;
+ if(header->ident != 'LLOC')
+ return size-8 < CDSTREAM_SECTOR_SIZE;
+ memcpy(modelname, buffer+8, 24);
+ memcpy(work_buff, buffer+32, modelsize-24);
+ size -= 32 + (modelsize-24);
+ buffer += 32 + (modelsize-24);
+ if(modelsize > 15*1024)
+ debug("colmodel %s is huge, size %d\n", modelname, modelsize);
+
+ mi = CModelInfo::GetModelInfo(modelname, CColStore::GetSlot(colSlot)->minIndex, CColStore::GetSlot(colSlot)->maxIndex);
+ if(mi){
+ if(mi->GetColModel()){
+ LoadCollisionModel(work_buff, *mi->GetColModel(), modelname);
+ }else{
+ CColModel *model = new CColModel;
+ model->level = colSlot;
+ LoadCollisionModel(work_buff, *model, modelname);
+ mi->SetColModel(model, true);
+ }
+ }else{
+ debug("colmodel %s can't find a modelinfo\n", modelname);
+ }
+ }
+ return true;
+}
+
void
CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
{
@@ -266,14 +316,16 @@ 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));
REGISTER_MEMPTR(&model.lines);
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;
@@ -294,10 +346,12 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
REGISTER_MEMPTR(&model.vertices);
for(i = 0; i < numVertices; i++){
model.vertices[i].Set(*(float*)buf, *(float*)(buf+4), *(float*)(buf+8));
+#if 0
if(Abs(*(float*)buf) >= 256.0f ||
Abs(*(float*)(buf+4)) >= 256.0f ||
Abs(*(float*)(buf+8)) >= 256.0f)
printf("%s:Collision volume too big\n", modelname);
+#endif
buf += 12;
}
}else
@@ -309,7 +363,7 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
model.triangles = (CColTriangle*)RwMalloc(model.numTriangles*sizeof(CColTriangle));
REGISTER_MEMPTR(&model.triangles);
for(i = 0; i < model.numTriangles; i++){
- model.triangles[i].Set(model.vertices, *(int32*)buf, *(int32*)(buf+4), *(int32*)(buf+8), buf[12], buf[13]);
+ model.triangles[i].Set(*(int32*)buf, *(int32*)(buf+4), *(int32*)(buf+8), buf[12]);
buf += 16;
}
}else
@@ -321,7 +375,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){
@@ -347,11 +401,11 @@ CFileLoader::FindRelatedModelInfoCB(RpAtomic *atomic, void *data)
mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(name, nil);
if(mi){
assert(mi->IsSimple());
+ CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil);
mi->SetAtomic(n, atomic);
RpClumpRemoveAtomic(clump, atomic);
RpAtomicSetFrame(atomic, RwFrameCreate());
CVisibilityPlugins::SetAtomicModelInfo(atomic, mi);
- CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil);
}else{
debug("Can't find Atomic %s\n", name);
}
@@ -427,17 +481,9 @@ CFileLoader::LoadClumpFile(RwStream *stream, uint32 id)
clump = RpClumpStreamRead(stream);
if(clump == nil)
return false;
+ InitClump(clump);
mi = (CClumpModelInfo*)CModelInfo::GetModelInfo(id);
mi->SetClump(clump);
- if (mi->GetModelType() == MITYPE_PED && id != 0 && RwStreamFindChunk(stream, rwID_CLUMP, nil, nil)) {
- // Read LOD ped
- clump = RpClumpStreamRead(stream);
- InitClump(clump);
- if(clump){
- ((CPedModelInfo*)mi)->SetLowDetailClump(clump);
- RpClumpDestroy(clump);
- }
- }
return true;
}
@@ -492,425 +538,6 @@ CFileLoader::LoadAtomicFile(RwStream *stream, uint32 id)
return true;
}
-#ifdef HARDCODED_MODEL_FLAGS
-char *DoubleSidedNames[] = {
- "chnabankdoor",
- "Security_Hut",
- "Hospital_Sub",
- "phonebooth1",
- "trafficlight1",
- "sub_roadbarrier",
- "redlightbuild09",
- "doublestreetlght1",
- "doc_shedbig31",
- "com_land_128",
- "garage7",
- "proj_garage01",
- "buildingground2",
- "buildingground3",
- "ch_roof_kb",
- "overpassind",
- "casino",
- "ind_land100",
- "fuckedup_skewlbus",
- "Police_Station_ind",
- "flagsitaly",
- "sidebarrier_gaz1",
- "bar_barrier12",
- "bar_barrier10b",
- "sidebarrier_gaz2",
- "doc_shedbig3",
- "doc_shedbig4",
- "verticalift_bridge",
- "verticalift_bridg2",
- "usdcrdlrbuild01",
- "apairporthanger",
- "apairporthangerA",
- "porthangerclosed",
- "redlightbuild13",
- "doc_rave",
- "const_woodfence",
- "const_woodfence2",
- "const_woodfence3",
- "subfraightback01",
- "subfraightback02",
- "subfraightback03",
- "subfraightback04",
- "subind_build03",
- "chinabanner1",
- "chinabanner2",
- "chinabanner3",
- "chinabanner4",
- "Pumpfirescape",
- "Pumphouse",
- "amcounder",
- "barrel1",
- "barrel2",
- "barrel3",
- "barrel4",
- "com_1way50",
- "com_1way20",
- "overpasscom01",
- "overpasscom02",
- "overpasscom03",
- "overpasscom04",
- "overpass_comse",
- "newdockbuilding",
- "newdockbuilding2",
- "policeballhall",
- "fuzballdoor",
- "ind_land106",
- "PoliceBallSigns",
- "amcoudet",
- "rustship_structure",
- "impexpgrgesub",
- "ind_land128",
- "fshfctry_dstryd",
- "railtrax_bentl",
- "railtrax_lo4b",
- "railtrax_straight",
- "railtrax_bentrb",
- "railtrax_skew",
- "newtrackaaa",
- "railtrax_skew5",
- // these they forgot:
- "railtrax_skewp",
- "railtrax_ske2b",
- "railtrax_strtshort",
- "railtrax_2b",
- "railtrax_straightss",
- "railtrax_bentr",
- "ind_land125",
- "salvstrans",
- "bridge_liftsec",
- "subsign1",
- "carparkfence",
- "newairportwall4",
- "apair_terminal",
- "Helipad",
- "bar_barrier10",
- "damissionfence",
- "sub_floodlite",
- "suburbbridge1",
- "damfencing",
- "demfence08",
- "damfence07",
- "damfence06",
- "damfence05",
- "damfence04",
- "damfence03",
- "damfence02",
- "damfence01",
- "Dam_pod2",
- "Dam_pod1",
- "columansion_wall",
- "wrckdhse020",
- "wrckdhse01",
- "arc_bridge",
- "gRD_overpass19kbc",
- "gRD_overpass19bkb",
- "gRD_overpass19kb",
- "gRD_overpass18kb",
- "road_under",
- "com_roadkb23",
- "com_roadkb22",
- "nbbridgerda",
- "nbbridgerdb",
- "policetenkb1",
- "block3_scraper2",
- "Clnm_cthdrlfcde",
- "broadwaybuild",
- "combillboard03",
- "com_park3b",
- "com_docksaa",
- "newdockbuilding2",
- "com_roadkb22",
- "sidebarrier_gaz2",
- "tunnelsupport1",
- "skyscrpunbuilt2",
- "cons_buid02",
- "rail_platformw",
- "railtrax_bent1",
- "nrailstepswest",
- "building_fucked",
- "franksclb02",
- "salvsdetail",
- "crgoshp01",
- "shp_wlkway",
- "bar_barriergate1",
- "plnt_pylon01",
- "fishfctory",
- "doc_crane_cab",
- "nrailsteps",
- "iten_club01",
- "mak_Watertank",
- "basketballcourt"
- "carlift01",
- "carlift02",
- "iten_chinatown4",
- "iten_details7",
- "ind_customroad002"
- "ind_brgrd1way",
- "ind_customroad060",
- "ind_customroad002",
- "ind_land108",
- "ind_customroad004",
- "ind_customroad003",
- "nbbridgcabls01",
- "sbwy_tunl_bit",
- "sbwy_tunl_bend",
- "sbwy_tunl_cstm11",
- "sbwy_tunl_cstm10",
- "sbwy_tunl_cstm9",
- "sbwy_tunl_cstm8",
- "sbwy_tunl_cstm7",
- "sbwy_tunl_cstm6",
- "sbwy_tunl_cstm5",
- "sbwy_tunl_cstm4",
- "sbwy_tunl_cstm3",
- "sbwy_tunl_cstm2",
- "sbwy_tunl_cstm1",
- "tenmnt6ad",
- ""
-
-};
-char *TreeNames[] = {
- "coast_treepatch",
- "comparknewtrees",
- "comtreepatchprk",
- "condotree01",
- "condotree1",
- "indatree03",
- "indtreepatch5",
- "indtreepatch06f",
- "new_carprktrees",
- "new_carprktrees4",
- "newcoasttrees1",
- "newcoasttrees2",
- "newcoasttrees3",
- "newtreepatch_sub",
- "newtrees1_sub",
- "newunitrepatch",
- "pinetree_narrow",
- "pinetree_wide",
- "treencom2",
- "treepatch",
- "treepatch01_sub",
- "treepatch02_sub",
- "treepatch2",
- "treepatch2b",
- "treepatch03",
- "treepatch03_sub",
- "treepatch04_sub",
- "treepatch05_sub",
- "treepatch06_sub",
- "treepatch07_sub",
- "treepatch08_sub",
- "treepatch09_sub",
- "treepatch10_sub",
- "treepatch11_sub",
- "treepatch12_sub",
- "treepatch13_sub",
- "treepatch14_sub",
- "treepatch15_sub",
- "treepatch16_sub",
- "treepatch17_sub",
- "treepatch18_sub",
- "treepatch19_sub",
- "treepatch20_sub",
- "treepatch21_sub",
- "treepatch22_sub",
- "treepatch23_sub",
- "treepatch24_sub",
- "treepatch25_sub",
- "treepatch26_sub",
- "treepatch27_sub",
- "treepatch28_sub",
- "treepatch29_sub",
- "treepatch30_sub",
- "treepatch31_sub",
- "treepatch32_sub",
- "treepatch33_sub",
- "treepatch34_sub",
- "treepatch35_sub",
- "treepatch69",
- "treepatch152_sub",
- "treepatch153_sub",
- "treepatch171_sub",
- "treepatch172_sub",
- "treepatch173_sub",
- "treepatch212_sub",
- "treepatch213_sub",
- "treepatch214_sub",
- "treepatcha",
- "treepatchb",
- "treepatchcomtop1",
- "treepatchd",
- "treepatche",
- "treepatchh",
- "treepatchindaa2",
- "treepatchindnew",
- "treepatchindnew2",
- "treepatchk",
- "treepatchkb4",
- "treepatchkb5",
- "treepatchkb6",
- "treepatchkb7",
- "treepatchkb9",
- "treepatchl",
- "treepatchm",
- "treepatchnew_sub",
- "treepatchttwrs",
- "treesuni1",
- "trepatchindaa1",
- "veg_bush2",
- "veg_bush14",
- "veg_tree1",
- "veg_tree3",
- "veg_treea1",
- "veg_treea3",
- "veg_treeb1",
- "veg_treenew01",
- "veg_treenew03",
- "veg_treenew05",
- "veg_treenew06",
- "veg_treenew08",
- "veg_treenew09",
- "veg_treenew10",
- "veg_treenew16",
- "veg_treenew17",
- "vegclubtree01",
- "vegclubtree02",
- "vegclubtree03",
- "vegpathtree",
- ""
-};
-char *OptimizedNames[] = {
- "coast_treepatch",
- "comparknewtrees",
- "comtreepatchprk",
- "indtreepatch5",
- "indtreepatch06f",
- "new_carprktrees",
- "new_carprktrees4",
- "newcoasttrees1",
- "newcoasttrees2",
- "newcoasttrees3",
- "newtreepatch_sub",
- "newtrees1_sub",
- "newunitrepatch",
- "treepatch",
- "treepatch01_sub",
- "treepatch02_sub",
- "treepatch2",
- "treepatch2b",
- "treepatch03",
- "treepatch03_sub",
- "treepatch04_sub",
- "treepatch05_sub",
- "treepatch06_sub",
- "treepatch07_sub",
- "treepatch08_sub",
- "treepatch09_sub",
- "treepatch10_sub",
- "treepatch11_sub",
- "treepatch12_sub",
- "treepatch13_sub",
- "treepatch14_sub",
- "treepatch15_sub",
- "treepatch16_sub",
- "treepatch17_sub",
- "treepatch18_sub",
- "treepatch19_sub",
- "treepatch20_sub",
- "treepatch21_sub",
- "treepatch22_sub",
- "treepatch23_sub",
- "treepatch24_sub",
- "treepatch25_sub",
- "treepatch26_sub",
- "treepatch27_sub",
- "treepatch28_sub",
- "treepatch29_sub",
- "treepatch30_sub",
- "treepatch31_sub",
- "treepatch32_sub",
- "treepatch33_sub",
- "treepatch34_sub",
- "treepatch35_sub",
- "treepatch69",
- "treepatch152_sub",
- "treepatch153_sub",
- "treepatch171_sub",
- "treepatch172_sub",
- "treepatch173_sub",
- "treepatch212_sub",
- "treepatch213_sub",
- "treepatch214_sub",
- "treepatcha",
- "treepatchb",
- "treepatchcomtop1",
- "treepatchd",
- "treepatche",
- "treepatchh",
- "treepatchindaa2",
- "treepatchindnew",
- "treepatchindnew2",
- "treepatchk",
- "treepatchkb4",
- "treepatchkb5",
- "treepatchkb6",
- "treepatchkb7",
- "treepatchkb9",
- "treepatchl",
- "treepatchm",
- "treepatchnew_sub",
- "treepatchttwrs",
- "treesuni1",
- "trepatchindaa1",
- "combtm_treeshad01",
- "combtm_treeshad02",
- "combtm_treeshad03",
- "combtm_treeshad04",
- "combtm_treeshad05",
- "combtm_treeshad06",
- "comtop_tshad",
- "comtop_tshad2",
- "comtop_tshad3",
- "comtop_tshad4",
- "comtop_tshad5",
- "comtop_tshad6",
- "se_treeshad01",
- "se_treeshad02",
- "se_treeshad03",
- "se_treeshad04",
- "se_treeshad05",
- "se_treeshad06",
- "treeshads01",
- "treeshads02",
- "treeshads03",
- "treeshads04",
- "treeshads05",
- ""
-};
-// not from mobile
-static bool
-MatchModelName(char *name, char **list)
-{
- int i;
- char *s;
- for(i = 0; *list[i] != '\0'; i++)
- if(strncmp(name, "LOD", 3) == 0){
- if(!CGeneral::faststricmp(name+3, list[i]+3))
- return true;
- }else{
- if(!CGeneral::faststricmp(name, list[i]))
- return true;
- }
- return false;
-}
-#endif
-
RpAtomic*
CFileLoader::SetRelatedModelInfoCB(RpAtomic *atomic, void *data)
{
@@ -920,11 +547,11 @@ CFileLoader::SetRelatedModelInfoCB(RpAtomic *atomic, void *data)
nodename = GetFrameNodeName(RpAtomicGetFrame(atomic));
GetNameAndLOD(nodename, name, &n);
+ CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil);
gpRelatedModelInfo->SetAtomic(n, atomic);
RpClumpRemoveAtomic(clump, atomic);
RpAtomicSetFrame(atomic, RwFrameCreate());
CVisibilityPlugins::SetAtomicModelInfo(atomic, gpRelatedModelInfo);
- CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil);
return atomic;
}
@@ -967,8 +594,9 @@ CFileLoader::LoadObjectTypes(const char *filename)
enum {
NONE,
OBJS,
- MLO,
+ MLO, // unused but enum still has it
TOBJ,
+ WEAP,
HIER,
CARS,
PEDS,
@@ -979,16 +607,17 @@ CFileLoader::LoadObjectTypes(const char *filename)
int fd;
int section;
int pathIndex;
- char pathTypeStr[20];
int id, pathType;
- int mlo;
+ int minID, maxID;
section = NONE;
+ minID = INT32_MAX;
+ maxID = -1;
pathIndex = -1;
- mlo = 0;
debug("Loading object types from %s...\n", filename);
fd = CFileMgr::OpenFile(filename, "rb");
+ assert(fd > 0);
for(line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)){
if(*line == '\0' || *line == '#')
continue;
@@ -996,25 +625,27 @@ CFileLoader::LoadObjectTypes(const char *filename)
if(section == NONE){
if(isLine4(line, 'o','b','j','s')) section = OBJS;
else if(isLine4(line, 't','o','b','j')) section = TOBJ;
+ else if(isLine4(line, 'w','e','a','p')) section = WEAP;
else if(isLine4(line, 'h','i','e','r')) section = HIER;
else if(isLine4(line, 'c','a','r','s')) section = CARS;
else if(isLine4(line, 'p','e','d','s')) section = PEDS;
else if(isLine4(line, 'p','a','t','h')) section = PATH;
else if(isLine4(line, '2','d','f','x')) section = TWODFX;
}else if(isLine3(line, 'e','n','d')){
- section = section == MLO ? OBJS : NONE;
+ section = NONE;
}else switch(section){
case OBJS:
- if(isLine3(line, 's','t','a'))
- mlo = LoadMLO(line);
- else
- LoadObject(line);
- break;
- case MLO:
- LoadMLOInstance(mlo, line);
+ id = LoadObject(line);
+ if(id > maxID) maxID = id;
+ if(id < minID) minID = id;
break;
case TOBJ:
- LoadTimeObject(line);
+ id = LoadTimeObject(line);
+ if(id > maxID) maxID = id;
+ if(id < minID) minID = id;
+ break;
+ case WEAP:
+ LoadWeaponObject(line);
break;
case HIER:
LoadClumpObject(line);
@@ -1027,17 +658,15 @@ CFileLoader::LoadObjectTypes(const char *filename)
break;
case PATH:
if(pathIndex == -1){
- id = LoadPathHeader(line, pathTypeStr);
- if(strcmp(pathTypeStr, "ped") == 0)
- pathType = 1;
- else if(strcmp(pathTypeStr, "car") == 0)
- pathType = 0;
+ id = LoadPathHeader(line, pathType);
pathIndex = 0;
}else{
- if(pathType == 1)
+ if(pathType == 0)
LoadPedPathNode(line, id, pathIndex);
- else if(pathType == 0)
- LoadCarPathNode(line, id, pathIndex);
+ else if (pathType == 1)
+ LoadCarPathNode(line, id, pathIndex, false);
+ else if (pathType == 2)
+ LoadCarPathNode(line, id, pathIndex, true);
pathIndex++;
if(pathIndex == 12)
pathIndex = -1;
@@ -1050,41 +679,30 @@ CFileLoader::LoadObjectTypes(const char *filename)
}
CFileMgr::CloseFile(fd);
- for(id = 0; id < MODELINFOSIZE; id++){
+ for(id = minID; id <= maxID; id++){
CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(id);
- if(mi && mi->IsSimple())
- mi->SetupBigBuilding();
+ if(mi && mi->IsBuilding())
+ mi->SetupBigBuilding(minID, maxID);
}
}
void
SetModelInfoFlags(CSimpleModelInfo *mi, uint32 flags)
{
- mi->m_normalCull = !!(flags & 1);
+ mi->m_wetRoadReflection = !!(flags & 1);
mi->m_noFade = !!(flags & 2);
mi->m_drawLast = !!(flags & (4|8));
mi->m_additive = !!(flags & 8);
mi->m_isSubway = !!(flags & 0x10);
mi->m_ignoreLight = !!(flags & 0x20);
mi->m_noZwrite = !!(flags & 0x40);
-#ifdef EXTRA_MODEL_FLAGS
- // same flag values as SA
- mi->m_bIsTree = !!(flags & 0x2000);
- mi->m_bIsDoubleSided = !!(flags & 0x200000);
- // new value otherwise unused
- mi->m_bCanBeIgnored = !!(flags & 0x10000);
-
-#ifdef HARDCODED_MODEL_FLAGS
- // mobile sets these flags in CFileLoader::SetRelatedModelInfoCB, but that's stupid
- if(MatchModelName(mi->GetModelName(), DoubleSidedNames)) mi->m_bIsDoubleSided = true;
- if(MatchModelName(mi->GetModelName(), TreeNames)) mi->m_bIsTree = true;
- if(MatchModelName(mi->GetModelName(), OptimizedNames)) mi->m_bCanBeIgnored = true;
-#endif
-
-#endif
+ mi->m_noShadows = !!(flags & 0x80);
+ mi->m_ignoreDrawDist = !!(flags & 0x100);
+ mi->m_isCodeGlass = !!(flags & 0x200);
+ mi->m_isArtistGlass = !!(flags & 0x400);
}
-void
+int
CFileLoader::LoadObject(const char *line)
{
int id, numObjs;
@@ -1095,7 +713,7 @@ CFileLoader::LoadObject(const char *line)
CSimpleModelInfo *mi;
if(sscanf(line, "%d %s %s %d", &id, model, txd, &numObjs) != 4)
- return;
+ return 0; // game returns return value
switch(numObjs){
case 1:
@@ -1127,60 +745,11 @@ CFileLoader::LoadObject(const char *line)
mi->m_firstDamaged = damaged;
mi->SetTexDictionary(txd);
MatchModelString(model, id);
-}
-
-int
-CFileLoader::LoadMLO(const char *line)
-{
- char smth[8];
- char name[24];
- int modelIndex;
- float drawDist;
-
- sscanf(line, "%s %s %d %f", smth, name, &modelIndex, &drawDist);
- CMloModelInfo *minfo = CModelInfo::AddMloModel(modelIndex);
- minfo->SetModelName(name);
- minfo->drawDist = drawDist;
- int instId = CModelInfo::GetMloInstanceStore().allocPtr;
- minfo->firstInstance = instId;
- minfo->lastInstance = instId;
- minfo->SetTexDictionary("generic");
- return modelIndex;
-}
-
-void
-CFileLoader::LoadMLOInstance(int id, const char *line)
-{
- char name[24];
- RwV3d pos, scale, rot;
- float angle;
- int modelIndex;
-
- CMloModelInfo *minfo = (CMloModelInfo*)CModelInfo::GetModelInfo(id);
- sscanf(line, "%d %s %f %f %f %f %f %f %f %f %f %f",
- &modelIndex,
- name,
- &pos.x, &pos.y, &pos.z,
- &scale.x, &scale.y, &scale.z,
- &rot.x, &rot.y, &rot.z,
- &angle);
- float rad = Acos(angle) * 2.0f;
- CInstance *inst = CModelInfo::GetMloInstanceStore().Alloc();
- minfo->lastInstance++;
-
- RwMatrix *matrix = RwMatrixCreate();
- RwMatrixScale(matrix, &scale, rwCOMBINEREPLACE);
- RwMatrixRotate(matrix, &rot, -RADTODEG(rad), rwCOMBINEPOSTCONCAT);
- RwMatrixTranslate(matrix, &pos, rwCOMBINEPOSTCONCAT);
- inst->GetMatrix() = CMatrix(matrix);
- inst->GetMatrix().UpdateRW();
-
- inst->m_modelIndex = modelIndex;
- RwMatrixDestroy(matrix);
+ return id;
}
-void
+int
CFileLoader::LoadTimeObject(const char *line)
{
int id, numObjs;
@@ -1192,7 +761,7 @@ CFileLoader::LoadTimeObject(const char *line)
CTimeModelInfo *mi, *other;
if(sscanf(line, "%d %s %s %d", &id, model, txd, &numObjs) != 4)
- return;
+ return 0; // game returns return value
switch(numObjs){
case 1:
@@ -1228,6 +797,29 @@ CFileLoader::LoadTimeObject(const char *line)
if(other)
other->SetOtherTimeModel(id);
MatchModelString(model, id);
+
+ return id;
+}
+
+int
+CFileLoader::LoadWeaponObject(const char *line)
+{
+ int id, numObjs;
+ char model[24], txd[24], animFile[16];
+ float dist;
+ CWeaponModelInfo *mi;
+
+ sscanf(line, "%d %s %s %s %d %f", &id, model, txd, animFile, &numObjs, &dist);
+
+ mi = CModelInfo::AddWeaponModel(id);
+ mi->SetModelName(model);
+ mi->SetNumAtomics(1);
+ mi->m_lodDistances[0] = dist;
+ mi->SetTexDictionary(txd);
+ mi->SetAnimFile(animFile);
+ mi->SetColModel(&CTempColModels::ms_colModelWeapon);
+ MatchModelString(model, id);
+ return id;
}
void
@@ -1250,21 +842,22 @@ CFileLoader::LoadVehicleObject(const char *line)
{
int id;
char model[24], txd[24];
- char type[8], handlingId[16], gamename[32], vehclass[12];
+ char type[8], handlingId[16], gamename[32], animFile[16], vehclass[12];
uint32 frequency, comprules;
int32 level, misc;
float wheelScale;
CVehicleModelInfo *mi;
char *p;
- sscanf(line, "%d %s %s %s %s %s %s %d %d %x %d %f",
+ sscanf(line, "%d %s %s %s %s %s %s %s %d %d %x %d %f",
&id, model, txd,
- type, handlingId, gamename, vehclass,
+ type, handlingId, gamename, animFile, vehclass,
&frequency, &level, &comprules, &misc, &wheelScale);
mi = CModelInfo::AddVehicleModel(id);
mi->SetModelName(model);
mi->SetTexDictionary(txd);
+ mi->SetAnimFile(animFile);
for(p = gamename; *p; p++)
if(*p == '_') *p = ' ';
strcpy(mi->m_gameName, gamename);
@@ -1294,36 +887,34 @@ CFileLoader::LoadVehicleObject(const char *line)
mi->m_handlingId = mod_HandlingManager.GetHandlingId(handlingId);
- // Well this is kinda dumb....
- if(strcmp(vehclass, "poorfamily") == 0){
+ if(strcmp(vehclass, "normal") == 0)
+ mi->m_vehicleClass = CCarCtrl::NORMAL;
+ else if(strcmp(vehclass, "poorfamily") == 0)
mi->m_vehicleClass = CCarCtrl::POOR;
- while(frequency-- > 0)
- CCarCtrl::AddToCarArray(id, CCarCtrl::POOR);
- }else if(strcmp(vehclass, "richfamily") == 0){
+ else if(strcmp(vehclass, "richfamily") == 0)
mi->m_vehicleClass = CCarCtrl::RICH;
- while(frequency-- > 0)
- CCarCtrl::AddToCarArray(id, CCarCtrl::RICH);
- }else if(strcmp(vehclass, "executive") == 0){
+ else if(strcmp(vehclass, "executive") == 0)
mi->m_vehicleClass = CCarCtrl::EXEC;
- while(frequency-- > 0)
- CCarCtrl::AddToCarArray(id, CCarCtrl::EXEC);
- }else if(strcmp(vehclass, "worker") == 0){
+ else if(strcmp(vehclass, "worker") == 0)
mi->m_vehicleClass = CCarCtrl::WORKER;
- while(frequency-- > 0)
- CCarCtrl::AddToCarArray(id, CCarCtrl::WORKER);
- }else if(strcmp(vehclass, "special") == 0){
- mi->m_vehicleClass = CCarCtrl::SPECIAL;
- while(frequency-- > 0)
- CCarCtrl::AddToCarArray(id, CCarCtrl::SPECIAL);
- }else if(strcmp(vehclass, "big") == 0){
+ else if(strcmp(vehclass, "big") == 0)
mi->m_vehicleClass = CCarCtrl::BIG;
- while(frequency-- > 0)
- CCarCtrl::AddToCarArray(id, CCarCtrl::BIG);
- }else if(strcmp(vehclass, "taxi") == 0){
+ else if(strcmp(vehclass, "taxi") == 0)
mi->m_vehicleClass = CCarCtrl::TAXI;
- while(frequency-- > 0)
- CCarCtrl::AddToCarArray(id, CCarCtrl::TAXI);
+ else if(strcmp(vehclass, "moped") == 0)
+ mi->m_vehicleClass = CCarCtrl::MOPED;
+ else if(strcmp(vehclass, "motorbike") == 0)
+ mi->m_vehicleClass = CCarCtrl::MOTORBIKE;
+ else if(strcmp(vehclass, "leisureboat") == 0)
+ mi->m_vehicleClass = CCarCtrl::LEISUREBOAT;
+ else if(strcmp(vehclass, "workerboat") == 0)
+ mi->m_vehicleClass = CCarCtrl::WORKERBOAT;
+ else if(strcmp(vehclass, "ignore") == 0) {
+ mi->m_vehicleClass = -1;
+ return;
}
+ CCarCtrl::AddToCarArray(id, mi->m_vehicleClass);
+ mi->m_frequency = frequency;
}
void
@@ -1331,67 +922,87 @@ CFileLoader::LoadPedObject(const char *line)
{
int id;
char model[24], txd[24];
- char pedType[24], pedStats[24], animGroup[24];
+ char pedType[24], pedStats[24], animGroup[24], animFile[16];
int carsCanDrive;
CPedModelInfo *mi;
int animGroupId;
+ int radio1, radio2;
- if(sscanf(line, "%d %s %s %s %s %s %x",
+ sscanf(line, "%d %s %s %s %s %s %x %s %d %d",
&id, model, txd,
- pedType, pedStats, animGroup, &carsCanDrive) != 7)
- return;
+ pedType, pedStats, animGroup, &carsCanDrive,
+ animFile, &radio1, &radio2);
mi = CModelInfo::AddPedModel(id);
mi->SetModelName(model);
mi->SetTexDictionary(txd);
+ mi->SetAnimFile(animFile);
mi->SetColModel(&CTempColModels::ms_colModelPed1);
mi->m_pedType = CPedType::FindPedType(pedType);
mi->m_pedStatType = CPedStats::GetPedStatType(pedStats);
for(animGroupId = 0; animGroupId < NUM_ANIM_ASSOC_GROUPS; animGroupId++)
if(strcmp(animGroup, CAnimManager::GetAnimGroupName((AssocGroupId)animGroupId)) == 0)
break;
+ assert(animGroupId < NUM_ANIM_ASSOC_GROUPS);
mi->m_animGroup = animGroupId;
mi->m_carsCanDrive = carsCanDrive;
-
- // ???
- CModelInfo::GetModelInfo(MI_LOPOLYGUY)->SetColModel(&CTempColModels::ms_colModelPed1);
+ mi->radio1 = radio1;
+ mi->radio2 = radio2;
}
int
-CFileLoader::LoadPathHeader(const char *line, char *type)
+CFileLoader::LoadPathHeader(const char *line, int &type)
{
int id;
char modelname[32];
- sscanf(line, "%s %d %s", type, &id, modelname);
+ sscanf(line, "%d %d %s", &type, &id, modelname);
return id;
}
void
CFileLoader::LoadPedPathNode(const char *line, int id, int node)
{
- int type, next, cross;
- float x, y, z, width;
-
- sscanf(line, "%d %d %d %f %f %f %f", &type, &next, &cross, &x, &y, &z, &width);
- ThePaths.StoreNodeInfoPed(id, node, type, next, x, y, z, 0, !!cross);
+ int type, next, cross, numLeft, numRight, speed, flags;
+ float x, y, z, width, spawnRate;
+
+ if(sscanf(line, "%d %d %d %f %f %f %f %d %d %d %d %f",
+ &type, &next, &cross, &x, &y, &z, &width, &numLeft, &numRight,
+ &speed, &flags, &spawnRate) != 12)
+ spawnRate = 1.0f;
+
+ if(id == -1)
+ ThePaths.StoreDetachedNodeInfoPed(node, type, next, x, y, z,
+ width, !!cross, !!(flags&1), !!(flags&4), spawnRate*15.0f);
+ else
+ ThePaths.StoreNodeInfoPed(id, node, type, next, x, y, z,
+ width, !!cross, spawnRate*15.0f);
}
void
-CFileLoader::LoadCarPathNode(const char *line, int id, int node)
+CFileLoader::LoadCarPathNode(const char *line, int id, int node, bool waterPath)
{
- int type, next, cross, numLeft, numRight;
- float x, y, z, width;
-
- sscanf(line, "%d %d %d %f %f %f %f %d %d", &type, &next, &cross, &x, &y, &z, &width, &numLeft, &numRight);
- ThePaths.StoreNodeInfoCar(id, node, type, next, x, y, z, 0, numLeft, numRight);
+ int type, next, cross, numLeft, numRight, speed, flags;
+ float x, y, z, width, spawnRate;
+
+ if(sscanf(line, "%d %d %d %f %f %f %f %d %d %d %d %f",
+ &type, &next, &cross, &x, &y, &z, &width, &numLeft, &numRight,
+ &speed, &flags, &spawnRate) != 12)
+ spawnRate = 1.0f;
+
+ if(id == -1)
+ ThePaths.StoreDetachedNodeInfoCar(node, type, next, x, y, z, width, numLeft, numRight,
+ !!(flags&1), !!(flags&4), speed, !!(flags&2), waterPath, spawnRate * 15, false);
+ else
+ ThePaths.StoreNodeInfoCar(id, node, type, next, x, y, z, 0, numLeft, numRight,
+ !!(flags&1), !!(flags&4), speed, !!(flags&2), waterPath, spawnRate * 15);
}
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;
@@ -1468,6 +1079,18 @@ CFileLoader::Load2dEffect(const char *line)
effect->attractor.probability = probability;
#endif
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();
@@ -1481,20 +1104,21 @@ CFileLoader::LoadScene(const char *filename)
INST,
ZONE,
CULL,
+ OCCL,
PICK,
PATH,
};
char *line;
int fd;
int section;
- int pathIndex;
- char pathTypeStr[20];
+ int pathType, pathIndex;
section = NONE;
pathIndex = -1;
debug("Creating objects from %s...\n", filename);
fd = CFileMgr::OpenFile(filename, "rb");
+ assert(fd > 0);
for(line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)){
if(*line == '\0' || *line == '#')
continue;
@@ -1505,6 +1129,7 @@ CFileLoader::LoadScene(const char *filename)
else if(isLine4(line, 'c','u','l','l')) section = CULL;
else if(isLine4(line, 'p','i','c','k')) section = PICK;
else if(isLine4(line, 'p','a','t','h')) section = PATH;
+ else if(isLine4(line, 'o','c','c','l')) section = OCCL;
}else if(isLine3(line, 'e','n','d')){
section = NONE;
}else switch(section){
@@ -1517,19 +1142,24 @@ CFileLoader::LoadScene(const char *filename)
case CULL:
LoadCullZone(line);
break;
+ case OCCL:
+ LoadOcclusionVolume(line);
+ break;
case PICK:
// unused
LoadPickup(line);
break;
case PATH:
- // unfinished in the game
if(pathIndex == -1){
- LoadPathHeader(line, pathTypeStr);
- strcmp(pathTypeStr, "ped");
- // type not set
+ LoadPathHeader(line, pathType);
pathIndex = 0;
}else{
- // nodes not loaded
+ if(pathType == 0)
+ LoadPedPathNode(line, -1, pathIndex);
+ else if (pathType == 1)
+ LoadCarPathNode(line, -1, pathIndex, false);
+ else if (pathType == 2)
+ LoadCarPathNode(line, -1, pathIndex, true);
pathIndex++;
if(pathIndex == 12)
pathIndex = -1;
@@ -1552,19 +1182,31 @@ CFileLoader::LoadObjectInstance(const char *line)
CSimpleModelInfo *mi;
RwMatrix *xform;
CEntity *entity;
- if(sscanf(line, "%d %s %f %f %f %f %f %f %f %f %f %f",
- &id, name,
+ float area;
+
+ if(sscanf(line, "%d %s %f %f %f %f %f %f %f %f %f %f %f",
+ &id, name, &area,
&trans.x, &trans.y, &trans.z,
&scale.x, &scale.y, &scale.z,
- &axis.x, &axis.y, &axis.z, &angle) != 12)
- return;
+ &axis.x, &axis.y, &axis.z, &angle) != 13){
+ if(sscanf(line, "%d %s %f %f %f %f %f %f %f %f %f %f",
+ &id, name,
+ &trans.x, &trans.y, &trans.z,
+ &scale.x, &scale.y, &scale.z,
+ &axis.x, &axis.y, &axis.z, &angle) != 12)
+ return;
+ area = 0;
+ }
mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(id);
if(mi == nil)
return;
assert(mi->IsSimple());
- angle = -RADTODEG(2.0f * acosf(angle));
+ if(!CStreaming::IsObjectInCdImage(id))
+ debug("Not in cdimage %s\n", mi->GetModelName());
+
+ angle = -RADTODEG(2.0f * Acos(angle));
xform = RwMatrixCreate();
RwMatrixRotate(xform, &axis, angle, rwCOMBINEREPLACE);
RwMatrixTranslate(xform, &trans, rwCOMBINEPOSTCONCAT);
@@ -1578,7 +1220,8 @@ CFileLoader::LoadObjectInstance(const char *line)
entity->SetModelIndexNoCreate(id);
entity->GetMatrix() = CMatrix(xform);
entity->m_level = CTheZones::GetLevelFromPosition(&entity->GetPosition());
- if(mi->IsSimple()){
+ entity->m_area = area;
+ if(mi->IsBuilding()){
if(mi->m_isBigBuilding)
entity->SetupBigBuilding();
if(mi->m_isSubway)
@@ -1587,14 +1230,25 @@ CFileLoader::LoadObjectInstance(const char *line)
if(mi->GetLargestLodDistance() < 2.0f)
entity->bIsVisible = false;
CWorld::Add(entity);
+
+ CColModel *col = entity->GetColModel();
+ if(col->numSpheres || col->numBoxes || col->numTriangles){
+ if(col->level != 0)
+ CColStore::GetBoundingBox(col->level).ContainRect(entity->GetBoundRect());
+ }else
+ entity->bUsesCollision = false;
+
+ if(entity->GetPosition().z + col->boundingBox.min.z < 6.0f)
+ entity->bUnderwater = true;
}else{
entity = new CDummyObject;
entity->SetModelIndexNoCreate(id);
entity->GetMatrix() = CMatrix(xform);
CWorld::Add(entity);
- if(IsGlass(entity->GetModelIndex()))
+ if(IsGlass(entity->GetModelIndex()) && !mi->m_isArtistGlass)
entity->bIsVisible = false;
entity->m_level = CTheZones::GetLevelFromPosition(&entity->GetPosition());
+ entity->m_area = area;
}
RwMatrixDestroy(xform);
@@ -1640,53 +1294,21 @@ CFileLoader::LoadPickup(const char *line)
}
void
-CFileLoader::LoadMapZones(const char *filename)
+CFileLoader::LoadOcclusionVolume(const char *line)
{
- enum {
- NONE,
- INST,
- ZONE,
- CULL,
- PICK,
- PATH,
- };
- char *line;
- int fd;
- int section;
-
- section = NONE;
- debug("Creating zones from %s...\n", filename);
-
- fd = CFileMgr::OpenFile(filename, "rb");
- for(line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)){
- if(*line == '\0' || *line == '#')
- continue;
-
- if(section == NONE){
- if(isLine4(line, 'z','o','n','e')) section = ZONE;
- }else if(isLine3(line, 'e','n','d')){
- section = NONE;
- }else switch(section){
- case ZONE: {
- char name[24];
- int type, level;
- float minx, miny, minz;
- float maxx, maxy, maxz;
- if(sscanf(line, "%s %d %f %f %f %f %f %f %d",
- name, &type,
- &minx, &miny, &minz,
- &maxx, &maxy, &maxz,
- &level) == 9)
- CTheZones::CreateMapZone(name, (eZoneType)type, minx, miny, minz, maxx, maxy, maxz, (eLevelName)level);
- }
- break;
- }
- }
- CFileMgr::CloseFile(fd);
+ float x, y, z;
+ float width, length, height;
+ float angle;
- debug("Finished loading IPL\n");
+ sscanf(line, "%f %f %f %f %f %f %f",
+ &x, &y, &z,
+ &width, &length, &height,
+ &angle);
+ COcclusion::AddOne(x, y, z + height/2.0f, width, length, height, angle);
}
+
+// unused
void
CFileLoader::ReloadPaths(const char *filename)
{
@@ -1697,10 +1319,10 @@ CFileLoader::ReloadPaths(const char *filename)
char *line;
int section = NONE;
int id, pathType, pathIndex = -1;
- char pathTypeStr[20];
debug("Reloading paths from %s...\n", filename);
int fd = CFileMgr::OpenFile(filename, "r");
+ assert(fd > 0);
for (line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)) {
if (*line == '\0' || *line == '#')
continue;
@@ -1716,17 +1338,15 @@ CFileLoader::ReloadPaths(const char *filename)
switch (section) {
case PATH:
if (pathIndex == -1) {
- id = LoadPathHeader(line, pathTypeStr);
- if (strcmp(pathTypeStr, "ped") == 0)
- pathType = 1;
- else if (strcmp(pathTypeStr, "car") == 0)
- pathType = 0;
+ id = LoadPathHeader(line, pathType);
pathIndex = 0;
} else {
- if (pathType == 1)
+ if(pathType == 0)
LoadPedPathNode(line, id, pathIndex);
- else if (pathType == 0)
- LoadCarPathNode(line, id, pathIndex);
+ else if (pathType == 1)
+ LoadCarPathNode(line, id, pathIndex, false);
+ else if (pathType == 2)
+ LoadCarPathNode(line, id, pathIndex, true);
pathIndex++;
if (pathIndex == 12)
pathIndex = -1;
@@ -1756,6 +1376,7 @@ CFileLoader::ReloadObjectTypes(const char *filename)
CFileMgr::ChangeDir("\\DATA\\MAPS\\");
int fd = CFileMgr::OpenFile(filename, "r");
+ assert(fd > 0);
CFileMgr::ChangeDir("\\");
for (line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)) {
if (*line == '\0' || *line == '#')
@@ -1831,17 +1452,14 @@ CFileLoader::ReLoadScene(const char *filename)
char *line;
CFileMgr::ChangeDir("\\DATA\\");
int fd = CFileMgr::OpenFile(filename, "r");
+ assert(fd > 0);
CFileMgr::ChangeDir("\\");
for (line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)) {
if (*line == '#')
continue;
-#ifdef FIX_BUGS
if (strncmp(line, "EXIT", 4) == 0)
-#else
- if (strncmp(line, "EXIT", 9) == 0)
-#endif
break;
if (strncmp(line, "IDE", 3) == 0) {
diff --git a/src/core/FileLoader.h b/src/core/FileLoader.h
index 87b8fe61..077e7bdd 100644
--- a/src/core/FileLoader.h
+++ b/src/core/FileLoader.h
@@ -5,10 +5,11 @@ class CFileLoader
static char ms_line[256];
public:
static void LoadLevel(const char *filename);
- static void LoadCollisionFromDatFile(int currlevel);
static char *LoadLine(int fd);
static RwTexDictionary *LoadTexDictionary(const char *filename);
- static void LoadCollisionFile(const char *filename);
+ static void LoadCollisionFile(const char *filename, uint8 colSlot);
+ static bool LoadCollisionFileFirstTime(uint8 *buffer, uint32 size, uint8 colSlot);
+ static bool LoadCollisionFile(uint8 *buffer, uint32 size, uint8 colSlot);
static void LoadCollisionModel(uint8 *buf, struct CColModel &model, char *name);
static void LoadModelFile(const char *filename);
static RpAtomic *FindRelatedModelInfoCB(RpAtomic *atomic, void *data);
@@ -22,16 +23,15 @@ public:
static void AddTexDictionaries(RwTexDictionary *dst, RwTexDictionary *src);
static void LoadObjectTypes(const char *filename);
- static void LoadObject(const char *line);
- static int LoadMLO(const char *line);
- static void LoadMLOInstance(int id, const char *line);
- static void LoadTimeObject(const char *line);
+ static int LoadObject(const char *line);
+ static int LoadTimeObject(const char *line);
+ static int LoadWeaponObject(const char *line);
static void LoadClumpObject(const char *line);
static void LoadVehicleObject(const char *line);
static void LoadPedObject(const char *line);
- static int LoadPathHeader(const char *line, char *type);
+ static int LoadPathHeader(const char *line, int &type);
static void LoadPedPathNode(const char *line, int id, int node);
- static void LoadCarPathNode(const char *line, int id, int node);
+ static void LoadCarPathNode(const char *line, int id, int node, bool waterPath);
static void Load2dEffect(const char *line);
static void LoadScene(const char *filename);
@@ -39,8 +39,7 @@ public:
static void LoadZone(const char *line);
static void LoadCullZone(const char *line);
static void LoadPickup(const char *line);
-
- static void LoadMapZones(const char *filename);
+ static void LoadOcclusionVolume(const char *line);
static void ReloadPaths(const char *filename);
static void ReloadObjectTypes(const char *filename);
diff --git a/src/core/Fire.cpp b/src/core/Fire.cpp
index 8b184622..57315b15 100644
--- a/src/core/Fire.cpp
+++ b/src/core/Fire.cpp
@@ -15,6 +15,8 @@
#include "DamageManager.h"
#include "Ped.h"
#include "Fire.h"
+#include "GameLogic.h"
+#include "CarAI.h"
CFireManager gFireManager;
@@ -25,14 +27,13 @@ CFire::CFire()
m_bPropagationFlag = true;
m_bAudioSet = true;
m_vecPos = CVector(0.0f, 0.0f, 0.0f);
- m_pEntity = nil;
- m_pSource = nil;
- m_nFiremenPuttingOut = 0;
m_nExtinguishTime = 0;
m_nStartTime = 0;
- field_20 = 1;
- m_nNextTimeToAddFlames = 0;
+ m_pEntity = nil;
+ m_pSource = nil;
m_fStrength = 0.8f;
+ m_fWaterExtinguishCountdown = 1.0f;
+ m_bExtinguishedWithWater = false;
}
CFire::~CFire() {}
@@ -51,6 +52,8 @@ CFire::ProcessFire(void)
CPed *ped = (CPed *)m_pEntity;
CVehicle *veh = (CVehicle*)m_pEntity;
+ m_fWaterExtinguishCountdown = Min(1.0f, 0.002f * CTimer::GetTimeStep() + m_fWaterExtinguishCountdown);
+
if (m_pEntity) {
m_vecPos = m_pEntity->GetPosition();
@@ -59,6 +62,12 @@ CFire::ProcessFire(void)
Extinguish();
return;
}
+#if defined GTAVC_JP_PATCH && !defined FIX_BUGS
+ if (m_pEntity == CGameLogic::pShortCutTaxi && CGameLogic::ShortCutState == CGameLogic::SHORTCUT_TRANSITION) {
+ Extinguish();
+ return;
+ }
+#endif
if (ped->m_nMoveState != PEDMOVE_RUN)
m_vecPos.z -= 1.0f;
if (ped->bInVehicle && ped->m_pMyVehicle) {
@@ -84,6 +93,12 @@ CFire::ProcessFire(void)
Extinguish();
return;
}
+#ifdef FIX_BUGS
+ if (m_pEntity == CGameLogic::pShortCutTaxi && CGameLogic::ShortCutState == CGameLogic::SHORTCUT_TRANSITION) {
+ Extinguish();
+ return;
+ }
+#endif
if (!m_bIsScriptFire) {
fDamageVehicle = 1.2f * CTimer::GetTimeStep();
veh->InflictDamage((CVehicle *)m_pSource, WEAPONTYPE_FLAMETHROWER, fDamageVehicle);
@@ -92,7 +107,7 @@ CFire::ProcessFire(void)
}
if (!FindPlayerVehicle() &&
#ifdef FIX_BUGS
- FindPlayerPed() &&
+ FindPlayerPed() &&
#endif
!FindPlayerPed()->m_pFire && !(FindPlayerPed()->bFireProof)
&& ((FindPlayerPed()->GetPosition() - m_vecPos).MagnitudeSqr() < 2.0f)) {
@@ -100,7 +115,7 @@ CFire::ProcessFire(void)
gFireManager.StartFire(FindPlayerPed(), m_pSource, 0.8f, 1);
}
if (CTimer::GetTimeInMilliseconds() > m_nNextTimeToAddFlames) {
- m_nNextTimeToAddFlames = CTimer::GetTimeInMilliseconds() + 80;
+ m_nNextTimeToAddFlames = CTimer::GetTimeInMilliseconds() + (m_fWaterExtinguishCountdown < 0.3f ? 400 : (m_fWaterExtinguishCountdown < 0.7f ? 200 : 80));
firePos = m_vecPos;
if (veh && veh->IsVehicle() && veh->IsCar()) {
@@ -138,7 +153,7 @@ CFire::ProcessFire(void)
fGreen = nRandNumber / 128.f;
fRed = nRandNumber / 128.f;
- CPointLights::AddLight(CPointLights::LIGHT_POINT, m_vecPos, CVector(0.0f, 0.0f, 0.0f), 12.0f, fRed, fGreen, 0, 0, 0);
+ CPointLights::AddLight(CPointLights::LIGHT_POINT, m_vecPos, CVector(0.0f, 0.0f, 0.0f), 12.0f, fRed, fGreen, 0.0f, 0, 0);
} else {
Extinguish();
}
@@ -160,11 +175,23 @@ CFire::Extinguish(void)
m_nExtinguishTime = 0;
m_bIsOngoing = false;
+ m_bExtinguishedWithWater = false;
if (m_pEntity) {
if (m_pEntity->IsPed()) {
- ((CPed *)m_pEntity)->RestorePreviousState();
- ((CPed *)m_pEntity)->m_pFire = nil;
+ CPed *ped = (CPed*)m_pEntity;
+ if (ped->CanSetPedState()) {
+ if (ped->m_nPedState != PED_DRIVING && ped->m_nPedState != PED_FALL) {
+ if (ped->IsPlayer()) {
+ ped->SetIdle();
+ } else {
+ ped->m_nLastPedState = PED_NONE;
+ ped->SetWanderPath(0);
+ ped->SetWaitState(WAITSTATE_FINISH_FLEE, 0);
+ }
+ }
+ }
+ ped->m_pFire = nil;
} else if (m_pEntity->IsVehicle()) {
((CVehicle *)m_pEntity)->m_pCarFire = nil;
}
@@ -174,7 +201,7 @@ CFire::Extinguish(void)
}
void
-CFireManager::StartFire(CVector pos, float size, bool propagation)
+CFireManager::StartFire(CVector pos, float size, uint8 propagation)
{
CFire *fire = GetNextFreeFire();
@@ -191,11 +218,12 @@ CFireManager::StartFire(CVector pos, float size, bool propagation)
fire->m_nNextTimeToAddFlames = 0;
fire->ReportThisFire();
fire->m_fStrength = size;
+ fire->m_bExtinguishedWithWater = false;
}
}
CFire *
-CFireManager::StartFire(CEntity *entityOnFire, CEntity *fleeFrom, float strength, bool propagation)
+CFireManager::StartFire(CEntity *entityOnFire, CEntity *fleeFrom, float strength, uint8 propagation)
{
CPed *ped = (CPed *)entityOnFire;
CVehicle *veh = (CVehicle *)entityOnFire;
@@ -224,6 +252,7 @@ CFireManager::StartFire(CEntity *entityOnFire, CEntity *fleeFrom, float strength
ped->SetFlee(pos, 10000);
ped->m_fleeFrom = nil;
}
+ ped->m_fleeTimer = CTimer::GetTimeInMilliseconds() + 10000;
ped->bDrawLast = false;
ped->SetMoveState(PEDMOVE_SPRINT);
ped->SetMoveAnim();
@@ -241,6 +270,9 @@ CFireManager::StartFire(CEntity *entityOnFire, CEntity *fleeFrom, float strength
} else {
if (entityOnFire->IsVehicle()) {
veh->m_pCarFire = fire;
+ if (CModelInfo::IsBikeModel(veh->GetModelIndex()) || CModelInfo::IsCarModel(veh->GetModelIndex()))
+ CCarAI::TellOccupantsToFleeCar(veh);
+
if (fleeFrom) {
CEventList::RegisterEvent(EVENT_CAR_SET_ON_FIRE, EVENT_ENTITY_VEHICLE,
entityOnFire, (CPed *)fleeFrom, 10000);
@@ -249,6 +281,7 @@ CFireManager::StartFire(CEntity *entityOnFire, CEntity *fleeFrom, float strength
}
fire->m_bIsOngoing = true;
+ fire->m_bExtinguishedWithWater = false;
fire->m_bIsScriptFire = false;
fire->m_vecPos = entityOnFire->GetPosition();
@@ -287,26 +320,23 @@ CFireManager::Update(void)
CFire* CFireManager::FindNearestFire(CVector vecPos, float *pDistance)
{
- for (int i = 0; i < MAX_FIREMEN_ATTENDING; i++) {
- int fireId = -1;
- float minDistance = 999999;
- for (int j = 0; j < NUM_FIRES; j++) {
- if (!m_aFires[j].m_bIsOngoing)
- continue;
- if (m_aFires[j].m_bIsScriptFire)
- continue;
- if (m_aFires[j].m_nFiremenPuttingOut != i)
- continue;
- float distance = (m_aFires[j].m_vecPos - vecPos).Magnitude2D();
- if (distance < minDistance) {
- minDistance = distance;
- fireId = j;
- }
+ int fireId = -1;
+ float minDistance = 999999;
+ for (int j = 0; j < NUM_FIRES; j++) {
+ if (!m_aFires[j].m_bIsOngoing)
+ continue;
+ if (m_aFires[j].m_bIsScriptFire)
+ continue;
+ float distance = (m_aFires[j].m_vecPos - vecPos).Magnitude2D();
+ if (distance < minDistance) {
+ minDistance = distance;
+ fireId = j;
}
- *pDistance = minDistance;
- if (fireId != -1)
- return &m_aFires[fireId];
}
+ *pDistance = minDistance;
+ if (fireId != -1)
+ return &m_aFires[fireId];
+
return nil;
}
@@ -359,8 +389,36 @@ CFireManager::ExtinguishPoint(CVector point, float range)
}
}
+bool
+CFireManager::ExtinguishPointWithWater(CVector point, float range)
+{
+ int i;
+ for (i = 0; i < NUM_FIRES;) {
+ if (m_aFires[i].m_bIsOngoing && (point - m_aFires[i].m_vecPos).MagnitudeSqr() < sq(range)) {
+ break;
+ }
+ if (++i >= NUM_FIRES)
+ return false;
+ }
+
+ CFire *fireToExtinguish = &m_aFires[i];
+ fireToExtinguish->m_fWaterExtinguishCountdown -= 0.012f * CTimer::GetTimeStep();
+ CVector steamPos = fireToExtinguish->m_vecPos +
+ CVector((CGeneral::GetRandomNumber() - 128) * 3.1f / 200.f,
+ (CGeneral::GetRandomNumber() - 128) * 3.1f / 200.f,
+ CGeneral::GetRandomNumber() / 200.f);
+
+ CParticle::AddParticle(PARTICLE_STEAM_NY_SLOWMOTION, steamPos, CVector(0.f, 0.f, 0.2f), nil, 0.5f);
+ CParticle::AddParticle(PARTICLE_STEAM_NY_SLOWMOTION, steamPos, CVector(0.f, 0.f, 0.1f), nil, 0.8f);
+ fireToExtinguish->m_bExtinguishedWithWater = true;
+ if (fireToExtinguish->m_fWaterExtinguishCountdown < 0.0f )
+ fireToExtinguish->Extinguish();
+
+ return true;
+}
+
int32
-CFireManager::StartScriptFire(const CVector &pos, CEntity *target, float strength, bool propagation)
+CFireManager::StartScriptFire(const CVector &pos, CEntity *target, float strength, uint8 propagation)
{
CFire *fire;
CPed *ped = (CPed *)target;
@@ -387,12 +445,15 @@ CFireManager::StartScriptFire(const CVector &pos, CEntity *target, float strengt
fire->m_vecPos = pos;
fire->m_nStartTime = CTimer::GetTimeInMilliseconds() + 400;
fire->m_pEntity = target;
+ fire->m_bExtinguishedWithWater = false;
if (target)
target->RegisterReference(&fire->m_pEntity);
fire->m_pSource = nil;
fire->m_nNextTimeToAddFlames = 0;
fire->m_fStrength = strength;
+ fire->m_fWaterExtinguishCountdown = 1.0f;
+
if (target) {
if (target->IsPed()) {
ped->m_pFire = fire;
@@ -420,8 +481,7 @@ CFireManager::RemoveAllScriptFires(void)
{
for (int i = 0; i < NUM_FIRES; i++) {
if (m_aFires[i].m_bIsScriptFire) {
- m_aFires[i].Extinguish();
- m_aFires[i].m_bIsScriptFire = false;
+ RemoveScriptFire(i);
}
}
}
diff --git a/src/core/Fire.h b/src/core/Fire.h
index 85e53f61..8126f830 100644
--- a/src/core/Fire.h
+++ b/src/core/Fire.h
@@ -14,10 +14,10 @@ public:
CEntity *m_pSource;
uint32 m_nExtinguishTime;
uint32 m_nStartTime;
- int32 field_20;
uint32 m_nNextTimeToAddFlames;
- uint32 m_nFiremenPuttingOut;
float m_fStrength;
+ float m_fWaterExtinguishCountdown;
+ bool m_bExtinguishedWithWater;
CFire();
~CFire();
@@ -34,15 +34,17 @@ class CFireManager
public:
uint32 m_nTotalFires;
CFire m_aFires[NUM_FIRES];
- void StartFire(CVector pos, float size, bool propagation);
- CFire *StartFire(CEntity *entityOnFire, CEntity *fleeFrom, float strength, bool propagation);
+
+ void StartFire(CVector pos, float size, uint8 propagation);
+ CFire *StartFire(CEntity *entityOnFire, CEntity *fleeFrom, float strength, uint8 propagation);
void Update(void);
CFire *FindFurthestFire_NeverMindFireMen(CVector coords, float minRange, float maxRange);
CFire *FindNearestFire(CVector vecPos, float *pDistance);
CFire *GetNextFreeFire(void);
uint32 GetTotalActiveFires() const;
void ExtinguishPoint(CVector point, float range);
- int32 StartScriptFire(const CVector &pos, CEntity *target, float strength, bool propagation);
+ bool ExtinguishPointWithWater(CVector point, float range);
+ int32 StartScriptFire(const CVector &pos, CEntity *target, float strength, uint8 propagation);
bool IsScriptFireExtinguish(int16 index);
void RemoveAllScriptFires(void);
void RemoveScriptFire(int16 index);
diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp
index b5d12d58..875bb76b 100644
--- a/src/core/Frontend.cpp
+++ b/src/core/Frontend.cpp
@@ -33,47 +33,35 @@
#include "Stats.h"
#include "Messages.h"
#include "FileLoader.h"
-#include "frontendoption.h"
+#include "User.h"
+#include "sampman.h"
+// Similar story to Hud.cpp:
// Game has colors inlined in code.
// For easier modification we collect them here:
-const CRGBA LABEL_COLOR(235, 170, 50, 255);
-const CRGBA SELECTION_HIGHLIGHTBG_COLOR(100, 200, 50, 50);
+const CRGBA LABEL_COLOR(255, 150, 225, 255);
+const CRGBA SELECTIONBORDER_COLOR(25, 130, 70, 255);
const CRGBA MENUOPTION_COLOR = LABEL_COLOR;
-const CRGBA SELECTEDMENUOPTION_COLOR(255, 217, 106, 255);
-const CRGBA HEADER_COLOR(0, 0, 0, 255);
-const CRGBA DARKMENUOPTION_COLOR(155, 117, 6, 255);
-const CRGBA SLIDERON_COLOR = SELECTEDMENUOPTION_COLOR;
-const CRGBA SLIDEROFF_COLOR(185, 120, 0, 255);
-const CRGBA LIST_BACKGROUND_COLOR(200, 200, 50, 50);
+const CRGBA SELECTEDMENUOPTION_COLOR = LABEL_COLOR;
+const CRGBA HEADER_COLOR = LABEL_COLOR;
+const CRGBA DARKMENUOPTION_COLOR(195, 90, 165, 255);
+const CRGBA SLIDERON_COLOR(97, 194, 247, 255);
+const CRGBA SLIDEROFF_COLOR(27, 89, 130, 255);
+const CRGBA LIST_BACKGROUND_COLOR(49, 101, 148, 130);
const CRGBA LIST_OPTION_COLOR(155, 155, 155, 255);
-const CRGBA INACTIVE_RADIO_COLOR(225, 0, 0, 170);
+const CRGBA RADIO_SELECTOR_COLOR = SLIDEROFF_COLOR;
+const CRGBA INACTIVE_RADIO_COLOR(100, 100, 255, 100);
const CRGBA SCROLLBAR_COLOR = LABEL_COLOR;
-const CRGBA CONTSETUP_HIGHLIGHTBG_COLOR(SELECTEDMENUOPTION_COLOR.r, SELECTEDMENUOPTION_COLOR.g, SELECTEDMENUOPTION_COLOR.b, 210);
-const CRGBA CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, 150);
-// This is PS2 menu leftover, and variable name is original. They forgot it here and used in PrintBriefs once (but didn't use the output)
-#if defined(FIX_BUGS) && !defined(PS2_LIKE_MENU)
-const CRGBA TEXT_COLOR = LABEL_COLOR;
-#else
-const CRGBA TEXT_COLOR = CRGBA(150, 110, 30, 255); // PS2 option color
-#endif
+#define MAP_MIN_SIZE 162.f
+#define MAP_SIZE_TO_ALLOW_X_MOVE 297.f
-#define TIDY_UP_PBP // ProcessButtonPresses
#define MAX_VISIBLE_LIST_ROW 30
#define SCROLLBAR_MAX_HEIGHT 263.0f // not in end result
#define SCROLLABLE_PAGES
-#define RED_DELETE_BACKGROUND
-#ifdef SCROLLABLE_STATS_PAGE
-#define isPlainTextScreen(screen) (screen == MENUPAGE_BRIEFS)
-#else
-#define isPlainTextScreen(screen) (screen == MENUPAGE_BRIEFS || screen == MENUPAGE_STATS)
-#endif
+#define hasNativeList(screen) (screen == MENUPAGE_SKIN_SELECT || screen == MENUPAGE_KEYBOARD_CONTROLS)
-#define hasNativeList(screen) (screen == MENUPAGE_MULTIPLAYER_FIND_GAME || screen == MENUPAGE_SKIN_SELECT \
- || screen == MENUPAGE_KEYBOARD_CONTROLS)
-
#ifdef SCROLLABLE_PAGES
#define MAX_VISIBLE_OPTION 12
#define MAX_VISIBLE_OPTION_ON_SCREEN (hasNativeList(m_nCurrScreen) ? MAX_VISIBLE_LIST_ROW : MAX_VISIBLE_OPTION)
@@ -95,9 +83,12 @@ int GetOptionCount(int screen)
m_nScrollbarTopMargin = 0; \
} \
}
+
+#define MINUS_SCROLL_OFFSET - scrollOffset
#else
#define MAX_VISIBLE_OPTION_ON_SCREEN MAX_VISIBLE_LIST_ROW
#define SETUP_SCROLLING(screen)
+#define MINUS_SCROLL_OFFSET
#endif
#ifdef TRIANGLE_BACK_BUTTON
@@ -111,169 +102,67 @@ int GetOptionCount(int screen)
#define GetBackJustDown GetSquareJustDown
#endif
-#ifdef MENU_MAP
-bool CMenuManager::bMenuMapActive = false;
-float CMenuManager::fMapSize;
-float CMenuManager::fMapCenterY;
-float CMenuManager::fMapCenterX;
-#endif
-
-#ifdef PS2_LIKE_MENU
-BottomBarOption bbNames[8];
-int bbTabCount = 0;
-bool bottomBarActive = false;
-int pendingScreen = -1;
-int pendingOption = -1;
-int curBottomBarOption = -1;
-int hoveredBottomBarOption = -1;
+#ifdef MAP_ENHANCEMENTS
+CVector2D mapCrosshair;
#endif
#ifdef CUTSCENE_BORDERS_SWITCH
bool CMenuManager::m_PrefsCutsceneBorders = true;
#endif
-#ifdef MULTISAMPLING
-int8 CMenuManager::m_nPrefsMSAALevel = 0;
-int8 CMenuManager::m_nDisplayMSAALevel = 0;
-#endif
-
-#ifdef NO_ISLAND_LOADING
-int8 CMenuManager::m_PrefsIslandLoading = ISLAND_LOADING_LOW;
-#endif
-
-#ifdef GAMEPAD_MENU
-int8 CMenuManager::m_PrefsControllerType = CONTROLLER_XBOXONE;
-#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;
-
-#ifdef ASPECT_RATIO_SCALE
-int8 CMenuManager::m_PrefsUseWideScreen = AR_AUTO;
-#else
-int8 CMenuManager::m_PrefsUseWideScreen;
-#endif
-
-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;
-
-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);
#ifndef MASTER
bool CMenuManager::m_PrefsMarketing = false;
bool CMenuManager::m_PrefsDisableTutorials = false;
#endif // !MASTER
-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 GAMEPAD_MENU
+uint32 TimeToStopPadShaking;
+#endif
-#ifdef MENU_MAP
-const char* MapFilenames[][2] = {
+const char* FrontendFilenames[][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 GAMEPAD_MENU
+ {"fe_controller", "" },
+ {"fe_arrows1", "" },
+ {"fe_arrows2", "" },
+ {"fe_arrows3", "" },
+ {"fe_arrows4", "" },
+#endif
};
#define MENU_X_RIGHT_ALIGNED(x) SCALE_AND_CENTER_X(DEFAULT_SCREEN_WIDTH - (x))
@@ -289,31 +178,24 @@ const char* MenuFilenames[][2] = {
#define MENU_Y(y) StretchY(y)
#endif
-#ifdef PS2_LIKE_MENU
-#define PAGE_NAME_X MENU_X_RIGHT_ALIGNED
-#else
-#define PAGE_NAME_X SCREEN_SCALE_FROM_RIGHT
+#ifdef XBOX_MESSAGE_SCREEN
+bool CMenuManager::m_bDialogOpen = false;
+uint32 CMenuManager::m_nDialogHideTimer = 0;
+uint32 CMenuManager::m_nDialogHideTimerPauseMode = 0;
+bool CMenuManager::m_bSaveWasSuccessful = false;
+wchar* CMenuManager::m_pDialogText = nil;
#endif
-// Seperate func. in VC
-#define ChangeScreen(screen, option, updateDelay, clearAlpha) \
- do { \
- m_nPrevScreen = m_nCurrScreen; \
- int newOpt = option; \
- SETUP_SCROLLING(screen) \
- m_nCurrScreen = screen; \
- m_nCurrOption = newOpt; \
- if(updateDelay) \
- m_nScreenChangeDelayTimer = CTimer::GetTimeInMillisecondsPauseMode(); \
- if(clearAlpha) \
- m_nMenuFadeAlpha = 0; \
- } while(0)
-
#define SET_FONT_FOR_MENU_HEADER \
- CFont::SetColor(CRGBA(HEADER_COLOR.r, HEADER_COLOR.g, HEADER_COLOR.b, FadeIn(255))); \
CFont::SetRightJustifyOn(); \
+ CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); \
CFont::SetScale(MENU_X(MENUHEADER_WIDTH), MENU_Y(MENUHEADER_HEIGHT)); \
- CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING));
+ CFont::SetDropShadowPosition(0);
+
+#define SET_FONT_FOR_LIST_ITEM \
+ CFont::SetRightJustifyOff(); \
+ CFont::SetScale(MENU_X(LISTITEM_X_SCALE), MENU_Y(LISTITEM_Y_SCALE)); \
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
#define RESET_FONT_FOR_NEW_PAGE \
CFont::SetBackgroundOff(); \
@@ -324,47 +206,35 @@ const char* MenuFilenames[][2] = {
CFont::SetRightJustifyOff(); \
CFont::SetBackGroundOnlyTextOn(); \
CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN)); \
- CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_X_MARGIN - 2.0f));
-
-#define SET_FONT_FOR_HELPER_TEXT \
- CFont::SetCentreOn(); \
- CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); \
- CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING));
-
-#define SET_FONT_FOR_LIST_ITEM \
- CFont::SetRightJustifyOff(); \
- CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); \
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_X_MARGIN));
// value must be between 0.0-1.0
-#define ProcessSlider(value, increaseAction, decreaseAction, hoverStartX, hoverEndX) \
+#define ProcessSlider(value, origY, increaseAction, decreaseAction, hoverEndX, onlyWhenHoveringRow) \
do { \
- lastActiveBarX = DisplaySlider(MENU_X_RIGHT_ALIGNED(MENUSLIDER_X + columnWidth), MENU_Y(bitAboveNextItemY), MENU_Y(smallestSliderBar), MENU_Y(usableLineHeight), MENU_X(MENUSLIDER_UNK), value); \
+ float y = origY MINUS_SCROLL_OFFSET; \
+ lastActiveBarX = DisplaySlider(MENU_X_LEFT_ALIGNED(MENUSLIDER_X), MENU_Y(y), MENU_Y(MENUSLIDER_SMALLEST_BAR), MENU_Y(MENUSLIDER_BIGGEST_BAR), MENU_X(MENUSLIDER_UNK), value, MENU_X(3.0f)); \
if (i != m_nCurrOption || !itemsAreSelectable) \
break; \
\
- if (CheckHover(hoverStartX, lastActiveBarX - MENU_X(10.0f), MENU_Y(nextYToUse), MENU_Y(28.0f + nextYToUse))) \
+ if (CheckHover(0, lastActiveBarX - MENU_X(3.0f), MENU_Y(y), MENU_Y(MENUSLIDER_BIGGEST_BAR + y))) { \
m_nHoverOption = decreaseAction; \
- \
- if (!CheckHover(MENU_X(10.0f) + lastActiveBarX, hoverEndX, MENU_Y(nextYToUse), MENU_Y(28.0f + nextYToUse))) \
break; \
- \
+ } \
+ if (!CheckHover(MENU_X(3.0f) + lastActiveBarX, hoverEndX, MENU_Y(y), MENU_Y(MENUSLIDER_BIGGEST_BAR + y))) { \
+ m_nHoverOption = HOVEROPTION_NOT_HOVERING; \
+ break; \
+ } \
m_nHoverOption = increaseAction; \
- if (m_nMousePosX < MENU_X_RIGHT_ALIGNED(MENUSLIDER_X + columnWidth)) \
+ if (m_nMousePosX < MENU_X_LEFT_ALIGNED(MENUSLIDER_X)) \
+ m_nHoverOption = HOVEROPTION_NOT_HOVERING; \
+ \
+ if (onlyWhenHoveringRow && (m_nMousePosY < MENU_Y(y) || m_nMousePosY > MENU_Y(MENUSLIDER_BIGGEST_BAR + y))) \
m_nHoverOption = HOVEROPTION_NOT_HOVERING; \
} while(0)
-#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(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, INACTIVE_RADIO_COLOR.a)); \
- 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
-void
+inline void
CMenuManager::ScrollUpListByOne()
{
if (m_nSelectedListRow == m_nFirstVisibleRowOnList) {
@@ -378,7 +248,7 @@ CMenuManager::ScrollUpListByOne()
}
}
-void
+inline void
CMenuManager::ScrollDownListByOne()
{
if (m_nSelectedListRow == m_nFirstVisibleRowOnList + MAX_VISIBLE_OPTION_ON_SCREEN - 1) {
@@ -394,13 +264,13 @@ CMenuManager::ScrollDownListByOne()
}
}
-void
+inline void
CMenuManager::PageUpList(bool playSoundOnSuccess)
{
if (m_nTotalListRow > MAX_VISIBLE_OPTION_ON_SCREEN) {
if (m_nFirstVisibleRowOnList > 0) {
if(playSoundOnSuccess)
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0);
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_HIGHLIGHT_OPTION, 0);
m_nFirstVisibleRowOnList = Max(0, m_nFirstVisibleRowOnList - MAX_VISIBLE_OPTION_ON_SCREEN);
m_nSelectedListRow = Min(m_nSelectedListRow, m_nFirstVisibleRowOnList + MAX_VISIBLE_OPTION_ON_SCREEN - 1);
@@ -412,13 +282,13 @@ CMenuManager::PageUpList(bool playSoundOnSuccess)
}
}
-void
+inline void
CMenuManager::PageDownList(bool playSoundOnSuccess)
{
if (m_nTotalListRow > MAX_VISIBLE_OPTION_ON_SCREEN) {
if (m_nFirstVisibleRowOnList < m_nTotalListRow - MAX_VISIBLE_OPTION_ON_SCREEN) {
if(playSoundOnSuccess)
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0);
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_HIGHLIGHT_OPTION, 0);
m_nFirstVisibleRowOnList = Min(m_nFirstVisibleRowOnList + MAX_VISIBLE_OPTION_ON_SCREEN, m_nTotalListRow - MAX_VISIBLE_OPTION_ON_SCREEN);
m_nSelectedListRow = Max(m_nSelectedListRow, m_nFirstVisibleRowOnList);
@@ -431,6 +301,7 @@ CMenuManager::PageDownList(bool playSoundOnSuccess)
}
#ifdef CUSTOM_FRONTEND_OPTIONS
+#define PLUS_LINE_HEIGHT_ON_SCREEN + (aScreens[m_nCurrScreen].layout ? aScreens[m_nCurrScreen].layout->lineHeight : MENU_DEFAULT_LINE_HEIGHT)
bool ScreenHasOption(int screen, const char* gxtKey)
{
for (int i = 0; i < NUM_MENUROWS; i++) {
@@ -439,30 +310,21 @@ bool ScreenHasOption(int screen, const char* gxtKey)
}
return false;
}
-#endif
-void
-CMenuManager::ThingsToDoBeforeGoingBack()
+inline void
+CMenuManager::ThingsToDoBeforeLeavingPage()
{
if ((m_nCurrScreen == MENUPAGE_SKIN_SELECT) && strcmp(m_aSkinName, m_PrefsSkinFile) != 0) {
CWorld::Players[0].SetPlayerSkin(m_PrefsSkinFile);
-#ifdef CUSTOM_FRONTEND_OPTIONS
- } else if (ScreenHasOption(m_nCurrScreen, "FEA_RSS")) {
-#else
+
} else if (m_nCurrScreen == MENUPAGE_SOUND_SETTINGS) {
-#endif
- if (m_nPrefsAudio3DProviderIndex != -1)
+ if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER)
m_nPrefsAudio3DProviderIndex = DMAudio.GetCurrent3DProviderIndex();
-#ifdef TIDY_UP_PBP
+
DMAudio.StopFrontEndTrack();
OutputDebugString("FRONTEND AUDIO TRACK STOPPED");
-#endif
-#ifdef CUSTOM_FRONTEND_OPTIONS
} else if (ScreenHasOption(m_nCurrScreen, "FED_RES")) {
-#else
- } else if (m_nCurrScreen == MENUPAGE_DISPLAY_SETTINGS) {
-#endif
m_nDisplayVideoMode = m_nPrefsVideoMode;
}
@@ -470,10 +332,6 @@ CMenuManager::ThingsToDoBeforeGoingBack()
CPlayerSkin::EndFrontendSkinEdit();
}
- if ((m_nCurrScreen == MENUPAGE_SKIN_SELECT) || (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS)) {
- m_nTotalListRow = 0;
- }
-
#ifdef SCROLLABLE_PAGES
if (SCREEN_HAS_AUTO_SCROLLBAR) {
m_nSelectedListRow = 0;
@@ -482,7 +340,6 @@ CMenuManager::ThingsToDoBeforeGoingBack()
}
#endif
-#ifdef CUSTOM_FRONTEND_OPTIONS
CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption];
if (option.m_Action == MENUACTION_CFO_DYNAMIC)
@@ -495,16 +352,13 @@ CMenuManager::ThingsToDoBeforeGoingBack()
if (aScreens[m_nCurrScreen].returnPrevPageFunc) {
aScreens[m_nCurrScreen].returnPrevPageFunc();
}
-#endif
}
-int8
+inline int8
CMenuManager::GetPreviousPageOption()
{
-#ifndef CUSTOM_FRONTEND_OPTIONS
- return !m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_ParentEntry[1] : aScreens[m_nCurrScreen].m_ParentEntry[0];
-#else
- int8 prevPage = !m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_PreviousPage[1] : aScreens[m_nCurrScreen].m_PreviousPage[0];
+ int8 prevPage = !m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_PreviousPage :
+ (m_nCurrScreen == MENUPAGE_NEW_GAME || m_nCurrScreen == MENUPAGE_OPTIONS || m_nCurrScreen == MENUPAGE_EXIT ? MENUPAGE_START_MENU : aScreens[m_nCurrScreen].m_PreviousPage);
if (prevPage == -1) // Game also does same
return 0;
@@ -521,271 +375,252 @@ CMenuManager::GetPreviousPageOption()
// This shouldn't happen
return 0;
-#endif
}
-void
-CMenuManager::ProcessList(bool &goBack, bool &optionSelected)
+#else
+#define PLUS_LINE_HEIGHT_ON_SCREEN + MENU_DEFAULT_LINE_HEIGHT
+inline void
+CMenuManager::ThingsToDoBeforeLeavingPage()
{
- if (m_nCurrScreen == MENUPAGE_SKIN_SELECT) {
- m_nTotalListRow = m_nSkinsTotal;
- }
- if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) {
- // GetNumOptionsCntrlConfigScreens would have been a better choice
- m_nTotalListRow = m_ControlMethod == CONTROL_CLASSIC ? 30 : 25;
- if (m_nSelectedListRow > m_nTotalListRow)
- m_nSelectedListRow = m_nTotalListRow - 1;
+ switch (m_nCurrScreen) {
+ case MENUPAGE_SOUND_SETTINGS:
+ if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER)
+ m_nPrefsAudio3DProviderIndex = DMAudio.GetCurrent3DProviderIndex();
+
+ DMAudio.StopFrontEndTrack();
+ OutputDebugString("FRONTEND AUDIO TRACK STOPPED");
+ break;
+ case MENUPAGE_DISPLAY_SETTINGS:
+ m_nDisplayVideoMode = m_nPrefsVideoMode;
+ break;
+ case MENUPAGE_SKIN_SELECT:
+ if (strcmp(m_aSkinName, m_PrefsSkinFile) != 0)
+ CWorld::Players[0].SetPlayerSkin(m_PrefsSkinFile);
+
+ CPlayerSkin::EndFrontendSkinEdit();
+ break;
}
-#ifndef TIDY_UP_PBP
- if (CPad::GetPad(0)->GetEnterJustDown() || CPad::GetPad(0)->GetCrossJustDown()) {
- m_bShowMouse = 0;
- optionSelected = true;
+#ifdef SCROLLABLE_PAGES
+ if (SCREEN_HAS_AUTO_SCROLLBAR) {
+ m_nSelectedListRow = 0;
+ m_nFirstVisibleRowOnList = 0;
+ m_nScrollbarTopMargin = 0;
}
#endif
- if (CPad::GetPad(0)->GetBackspaceJustDown() && m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS && !field_535) {
- if (m_nCurrExLayer == HOVEROPTION_LIST) {
- m_nHoverOption = HOVEROPTION_NOT_HOVERING;
- m_bWaitingForNewKeyBind = true;
- m_bStartWaitingForKeyBind = true;
- m_bKeyChangeNotProcessed = true;
- pControlEdit = &m_KeyPressedCode;
- }
- } else {
- field_535 = false;
- }
+}
- static uint32 lastTimeClickedScrollButton = 0;
+inline int8
+CMenuManager::GetPreviousPageOption()
+{
+ return (!m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_ParentEntry :
+ (m_nCurrScreen == MENUPAGE_NEW_GAME ? 0 : (m_nCurrScreen == MENUPAGE_OPTIONS ? 1 : (m_nCurrScreen == MENUPAGE_EXIT ? 2 : aScreens[m_nCurrScreen].m_ParentEntry))));
+}
+#endif
- if (CTimer::GetTimeInMillisecondsPauseMode() - lastTimeClickedScrollButton >= 200) {
- m_bPressedPgUpOnList = false;
- m_bPressedPgDnOnList = false;
- m_bPressedUpOnList = false;
- m_bPressedDownOnList = false;
- m_bPressedScrollButton = false;
- lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
- }
+// ------ Functions not in the game/inlined ends
- if (CPad::GetPad(0)->GetTabJustDown()) {
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0);
- m_bShowMouse = false;
- switch (m_nCurrExLayer) {
- case HOVEROPTION_BACK:
- default:
- m_nCurrExLayer = HOVEROPTION_LIST;
- break;
- case HOVEROPTION_LIST:
- m_nCurrExLayer = HOVEROPTION_USESKIN;
- break;
- case HOVEROPTION_USESKIN:
- m_nCurrExLayer = HOVEROPTION_BACK;
- }
- if (((m_nCurrScreen == MENUPAGE_SKIN_SELECT) && (m_nCurrExLayer == HOVEROPTION_USESKIN)) && strcmp(m_aSkinName, m_PrefsSkinFile) == 0) {
- m_nCurrExLayer = HOVEROPTION_BACK;
- }
- if ((m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) && (m_nCurrExLayer == HOVEROPTION_USESKIN)) {
- m_nCurrExLayer = HOVEROPTION_BACK;
- }
- }
+bool DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha);
+void DoRWStuffEndOfFrame(void);
- bool pressed = false;
- if (CPad::GetPad(0)->GetUp() || CPad::GetPad(0)->GetAnaloguePadUp() || CPad::GetPad(0)->GetDPadUpJustDown()) {
- m_bShowMouse = false;
- pressed = true;
- } else if (CPad::GetPad(0)->GetMouseWheelUpJustUp()) {
- m_bShowMouse = true;
- pressed = true;
- }
+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();
- // Up
- if (pressed) {
- m_nCurrExLayer = HOVEROPTION_LIST;
- if (!m_bPressedUpOnList) {
- m_bPressedUpOnList = true;
- lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0);
- ScrollUpListByOne();
- }
- } else {
- m_bPressedUpOnList = false;
- }
+ ThingsToDoBeforeLeavingPage();
- pressed = false;
- if (CPad::GetPad(0)->GetDown() || CPad::GetPad(0)->GetAnaloguePadDown() || CPad::GetPad(0)->GetDPadDownJustDown()) {
- m_bShowMouse = false;
- pressed = true;
- } else if (CPad::GetPad(0)->GetMouseWheelDownJustDown()) {
- m_bShowMouse = true;
- pressed = true;
- }
+ if (screen == -2) {
+ int oldScreen = aScreens[m_nCurrScreen].m_PreviousPage;
+ int oldOption = GetPreviousPageOption();
- // Down
- if (pressed) {
- m_nCurrExLayer = HOVEROPTION_LIST;
- if (!m_bPressedDownOnList) {
- m_bPressedDownOnList = true;
- lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0);
- ScrollDownListByOne();
- }
+ 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_bPressedDownOnList = false;
+ m_nCurrOption = 0;
+ m_nCurrScreen = screen;
}
+ SETUP_SCROLLING(m_nCurrScreen)
+
+ if (hasNativeList(m_nPrevScreen))
+ m_nTotalListRow = 0;
- if (m_nCurrScreen != MENUPAGE_KEYBOARD_CONTROLS) {
- if (!CPad::GetPad(0)->GetPageUp()) {
- m_bPressedPgUpOnList = false;
- } else {
- m_nCurrExLayer = HOVEROPTION_LIST;
- if (!m_bPressedPgUpOnList) {
- m_bPressedPgUpOnList = true;
- lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
- m_bShowMouse = false;
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0);
- PageUpList(false);
- }
- }
- if (!CPad::GetPad(0)->GetPageDown()) {
- m_bPressedPgDnOnList = false;
- } else {
- m_nCurrExLayer = HOVEROPTION_LIST;
- if (!m_bPressedPgDnOnList) {
- m_bPressedPgDnOnList = true;
- lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
- m_bShowMouse = false;
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0);
- PageDownList(false);
- }
- }
- if (CPad::GetPad(0)->GetHome()) {
- m_nCurrExLayer = HOVEROPTION_LIST;
- m_bShowMouse = false;
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0);
- if (m_nTotalListRow >= MAX_VISIBLE_OPTION_ON_SCREEN) {
- m_nFirstVisibleRowOnList = 0;
- }
- m_nSelectedListRow = 0;
- m_nScrollbarTopMargin = (SCROLLBAR_MAX_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList;
- }
- if (CPad::GetPad(0)->GetEnd()) {
- m_nCurrExLayer = HOVEROPTION_LIST;
- m_bShowMouse = false;
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0);
- if (m_nTotalListRow >= MAX_VISIBLE_OPTION_ON_SCREEN) {
- m_nFirstVisibleRowOnList = m_nTotalListRow - MAX_VISIBLE_OPTION_ON_SCREEN;
- }
- m_nSelectedListRow = m_nTotalListRow - 1;
- m_nScrollbarTopMargin = (SCROLLBAR_MAX_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList;
- }
- }
+ if (m_nCurrScreen == MENUPAGE_CHOOSE_SAVE_SLOT)
+ m_nCurrOption = 8;
+ m_nMenuFadeAlpha = 0;
+ m_nOptionHighlightTransitionBlend = 0;
+ m_LastScreenSwitch = CTimer::GetTimeInMillisecondsPauseMode();
+}
-#ifndef TIDY_UP_PBP
- if (CPad::GetPad(0)->GetEscapeJustDown() || CPad::GetPad(0)->GetBackJustDown()) {
- m_bShowMouse = false;
- goBack = true;
- }
-#endif
+CMenuManager::CMenuManager()
+{
+ m_StatsScrollSpeed = 150.0f;
+ m_StatsScrollDirection = 1;
+ m_PrefsSfxVolume = 49;
+ m_PrefsMusicVolume = 49;
+ m_PrefsRadioStation = 0;
+ m_PrefsStereoMono = 1;
+ m_PrefsBrightness = 256;
+ m_PrefsLOD = CRenderer::ms_lodDistScale;
+ m_KeyPressedCode = -1;
+ m_bFrontEnd_ReloadObrTxtGxt = false;
+ m_PrefsMP3BoostVolume = 0;
+ m_PrefsShowSubtitles = 0;
+ m_PrefsShowLegends = 1;
+#ifdef ASPECT_RATIO_SCALE
+ m_PrefsUseWideScreen = AR_AUTO;
+#else
+ m_PrefsUseWideScreen = 0;
+#endif
+ 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;
+ m_DisplayControllerOnFoot = false;
+ m_bShutDownFrontEndRequested = false;
+ m_bStartUpFrontEndRequested = false;
+ pEditString = nil;
+ pControlEdit = nil;
+ DisplayComboButtonErrMsg = false;
+ m_PrefsDMA = 1;
+ OS_Language = LANG_ENGLISH;
+ m_ControlMethod = CONTROL_STANDARD;
+#ifdef PC_PLAYER_CONTROLS
+ CCamera::m_bUseMouse3rdPerson = true;
+#else
+ CCamera::m_bUseMouse3rdPerson = false;
+#endif
+ m_lastWorking3DAudioProvider = 0;
+ m_nFirstVisibleRowOnList = 0;
+ m_nScrollbarTopMargin = 0.0f;
+ m_nSelectedListRow = 0;
+ m_nSkinsTotal = 0;
+ m_nPrefsAudio3DProviderIndex = AUDIO_PROVIDER_NOT_DETERMINED;
+ 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;
- if (CPad::GetPad(0)->GetLeftMouseJustDown()) {
- switch (m_nHoverOption) {
- case HOVEROPTION_BACK:
- goBack = true;
- break;
- case HOVEROPTION_PAGEUP:
- PageUpList(true);
- break;
- case HOVEROPTION_PAGEDOWN:
- PageDownList(true);
- break;
- case HOVEROPTION_USESKIN:
- if (m_nSkinsTotal > 0) {
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- m_pSelectedSkin = m_pSkinListHead.nextSkin;
- strcpy(m_PrefsSkinFile, m_aSkinName);
- CWorld::Players[0].SetPlayerSkin(m_PrefsSkinFile);
- SaveSettings();
- }
- }
- }
+ DMAudio.SetMP3BoostVolume(m_PrefsMP3BoostVolume);
+ m_bMenuActive = false;
+ m_bActivateSaveMenu = false;
+ m_bWantToLoad = false;
+ m_nMenuFadeAlpha = 0;
+ m_OnlySaveMenu = false;
+ m_fMapSize = MENU_Y(162.0f); // Y because of HOR+
+ m_fMapCenterX = MENU_X_LEFT_ALIGNED(320.0f);
+ m_fMapCenterY = MENU_Y(225.0f);
+ DMAudio.SetMusicMasterVolume(m_PrefsMusicVolume);
+ DMAudio.SetEffectsMasterVolume(m_PrefsSfxVolume);
- if (CPad::GetPad(0)->GetLeftMouseJustDown()) {
- switch (m_nHoverOption) {
- case HOVEROPTION_OVER_SCROLL_UP:
- m_nHoverOption = HOVEROPTION_CLICKED_SCROLL_UP;
- break;
- case HOVEROPTION_OVER_SCROLL_DOWN:
- m_nHoverOption = HOVEROPTION_CLICKED_SCROLL_DOWN;
- break;
- case HOVEROPTION_LIST:
- m_nHoverOption = HOVEROPTION_SKIN;
- }
- } else if ((CPad::GetPad(0)->GetLeftMouseJustUp())
- && ((m_nHoverOption == HOVEROPTION_CLICKED_SCROLL_UP || (m_nHoverOption == HOVEROPTION_CLICKED_SCROLL_DOWN)))) {
- m_nHoverOption = HOVEROPTION_NOT_HOVERING;
- }
+#ifdef NO_ISLAND_LOADING
+ m_PrefsIslandLoading = ISLAND_LOADING_LOW;
+#endif
- if (!CPad::GetPad(0)->GetLeftMouse()) {
- holdingScrollBar = false;
- } else {
- if ((m_nHoverOption == HOVEROPTION_HOLDING_SCROLLBAR) || holdingScrollBar) {
- holdingScrollBar = true;
- // TODO: This part is a bit hard to reverse. Not much code tho
- assert(0 && "Holding scrollbar isn't done yet");
- } else {
- switch (m_nHoverOption) {
- case HOVEROPTION_OVER_SCROLL_UP:
- case HOVEROPTION_CLICKED_SCROLL_UP:
- if (!m_bPressedScrollButton) {
- m_bPressedScrollButton = true;
- lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
- ScrollUpListByOne();
- }
- break;
- case HOVEROPTION_OVER_SCROLL_DOWN:
- case HOVEROPTION_CLICKED_SCROLL_DOWN:
- if (!m_bPressedScrollButton) {
- m_bPressedScrollButton = true;
- lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
- ScrollDownListByOne();
- }
- break;
- default:
- m_bPressedScrollButton = false;
- }
- }
- }
+#ifdef GAMEPAD_MENU
+#ifdef __SWITCH__
+ m_PrefsControllerType = CONTROLLER_NINTENDO_SWITCH;
+#else
+ m_PrefsControllerType = CONTROLLER_XBOXONE;
+#endif
+#endif
+
+#ifdef MISSION_REPLAY
+ m_bAttemptingMissionRetry = false;
+#endif
}
-// ------ Functions not in the game/inlined ends
void
-CMenuManager::BuildStatLine(Const char *text, void *stat, bool itsFloat, void *stat2)
+CMenuManager::SetFrontEndRenderStates(void)
{
- if (!text)
- return;
+ 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);
+}
-#ifdef MORE_LANGUAGES
- if (CFont::IsJapanese() && stat2)
- if (itsFloat)
- sprintf(gString2, " %.2f/%.2f", *(float*)stat, *(float*)stat2);
- else
- sprintf(gString2, " %d/%d", *(int*)stat, *(int*)stat2);
- else
+void
+CMenuManager::Initialise(void)
+{
+ DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255);
+ DoRWStuffEndOfFrame();
+ m_AllowNavigation = false;
+ m_firstStartCounter = -50; // to start from black
+ m_nMenuFadeAlpha = 0;
+ m_nCurrOption = 0;
+ m_nOptionHighlightTransitionBlend = 0;
+ CentreMousePointer();
+#ifdef GTA_HANDHELD
+ m_bShowMouse = false;
+#else
+ m_bShowMouse = true;
#endif
- if (stat2) {
- if (itsFloat)
- sprintf(gString2, " %.2f %s %.2f", *(float*)stat, UnicodeToAscii(TheText.Get("FEST_OO")), *(float*)stat2);
- else
- sprintf(gString2, " %d %s %d", *(int*)stat, UnicodeToAscii(TheText.Get("FEST_OO")), *(int*)stat2);
- } else if (stat) {
- if (itsFloat)
- sprintf(gString2, " %.2f", *(float*)stat);
+ m_fMapSize = MENU_Y(162.0f); // Y because of HOR+
+ m_fMapCenterX = MENU_X_LEFT_ALIGNED(320.0f);
+ m_fMapCenterY = MENU_Y(225.0f);
+ CPad::StopPadsShaking();
+#ifdef MISSION_REPLAY
+ if (!m_OnlySaveMenu) {
+ if (m_nCurrScreen == MENUPAGE_MISSION_RETRY && m_bAttemptingMissionRetry)
+ m_bAttemptingMissionRetry = false;
else
- sprintf(gString2, " %d", *(int*)stat);
+ m_nCurrScreen = MENUPAGE_NONE;
+ }
+#else
+ if (!m_OnlySaveMenu)
+ m_nCurrScreen = MENUPAGE_NONE;
+#endif
+
+ DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND);
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_STARTING, 0);
+ DMAudio.Service();
+ DMAudio.SetMusicMasterVolume(m_PrefsMusicVolume);
+ DMAudio.SetEffectsMasterVolume(m_PrefsSfxVolume);
+#ifdef FIX_BUGS
+ static bool firstTime = true;
+ if (firstTime) {
+ DMAudio.SetRadioInCar(m_PrefsRadioStation);
+ firstTime = false;
} else
- gString2[0] = '\0';
+#endif
+ m_PrefsRadioStation = DMAudio.GetRadioInCar();
- UnicodeStrcpy(gUString, TheText.Get(text));
- AsciiToUnicode(gString2, gUString2);
+ DMAudio.SetMP3BoostVolume(m_PrefsMP3BoostVolume);
+ if (DMAudio.IsMP3RadioChannelAvailable()) {
+ if (m_PrefsRadioStation < WILDSTYLE || m_PrefsRadioStation > USERTRACK)
+ m_PrefsRadioStation = CGeneral::GetRandomNumber() % (USERTRACK + 1);
+ } else if (m_PrefsRadioStation < WILDSTYLE || m_PrefsRadioStation > WAVE)
+ m_PrefsRadioStation = CGeneral::GetRandomNumber() % (WAVE + 1);
+
+ CFileMgr::SetDir("");
+ //CFileMgr::SetDir("");
+ PcSaveHelper.PopulateSlotInfo();
+ CTimer::StartUserPause();
}
void
@@ -842,26 +677,23 @@ CMenuManager::CheckCodesForControls(int typeOfControl)
if(!escPressed && !invalidKey)
#endif
ControlsManager.ClearSettingsAssociatedWithAction(action, typeToSave);
+
if (!DisplayComboButtonErrMsg && !escPressed && !invalidKey) {
if (typeOfControl == KEYBOARD) {
ControlsManager.DeleteMatchingActionInitiators(action, *pControlEdit, KEYBOARD);
ControlsManager.DeleteMatchingActionInitiators(action, *pControlEdit, OPTIONAL_EXTRA);
- } else {
- if (typeOfControl == MOUSE) {
- ControlsManager.DeleteMatchingActionInitiators(action, MouseButtonJustClicked, MOUSE);
- } else if (typeOfControl == JOYSTICK) {
- ControlsManager.DeleteMatchingActionInitiators(action, JoyButtonJustClicked, JOYSTICK);
- }
+ } else if (typeOfControl == MOUSE) {
+ ControlsManager.DeleteMatchingActionInitiators(action, MouseButtonJustClicked, MOUSE);
+ } else if (typeOfControl == JOYSTICK) {
+ ControlsManager.DeleteMatchingActionInitiators(action, JoyButtonJustClicked, JOYSTICK);
}
+
if (typeOfControl == KEYBOARD) {
ControlsManager.SetControllerKeyAssociatedWithAction(action, *pControlEdit, typeToSave);
-
} else if (typeOfControl == MOUSE) {
ControlsManager.SetControllerKeyAssociatedWithAction(action, MouseButtonJustClicked, typeToSave);
- } else {
- if (typeOfControl == JOYSTICK) {
- ControlsManager.SetControllerKeyAssociatedWithAction(action, JoyButtonJustClicked, typeToSave);
- }
+ } else if (typeOfControl == JOYSTICK) {
+ ControlsManager.SetControllerKeyAssociatedWithAction(action, JoyButtonJustClicked, typeToSave);
}
pControlEdit = nil;
m_bWaitingForNewKeyBind = false;
@@ -873,18 +705,6 @@ CMenuManager::CheckCodesForControls(int typeOfControl)
SaveSettings();
#endif
}
-
- if (escPressed) {
- pControlEdit = nil;
- m_bWaitingForNewKeyBind = false;
- m_KeyPressedCode = -1;
- m_bStartWaitingForKeyBind = false;
-#ifdef LOAD_INI_SETTINGS
- SaveINIControllerSettings();
-#else
- SaveSettings();
-#endif
- }
}
bool
@@ -899,34 +719,51 @@ CMenuManager::CheckSliderMovement(int value)
{
switch (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action) {
case MENUACTION_BRIGHTNESS:
- m_PrefsBrightness += value * (512/MENUSLIDER_LOGICAL_BARS);
- m_PrefsBrightness = Clamp(m_PrefsBrightness, 0, 511);
+#ifdef FIX_BUGS
+ m_PrefsBrightness += value * (384 / MENUSLIDER_LOGICAL_BARS);
+#else
+ m_PrefsBrightness += value * 24.19f;
+#endif
+ m_PrefsBrightness = Clamp(m_PrefsBrightness, 0, 384);
break;
case MENUACTION_DRAWDIST:
if(value > 0)
- m_PrefsLOD += ((1.8f - 0.8f) / MENUSLIDER_LOGICAL_BARS);
+ m_PrefsLOD += ((1.8f - 0.925f) / MENUSLIDER_LOGICAL_BARS);
else
- m_PrefsLOD -= ((1.8f - 0.8f) / MENUSLIDER_LOGICAL_BARS);
- m_PrefsLOD = Clamp(m_PrefsLOD, 0.8f, 1.8f);
+ m_PrefsLOD -= ((1.8f - 0.925f) / MENUSLIDER_LOGICAL_BARS);
+ m_PrefsLOD = Clamp(m_PrefsLOD, 0.925f, 1.8f);
CRenderer::ms_lodDistScale = m_PrefsLOD;
break;
+
+ // I wonder the idea behind clamping those max to 65
case MENUACTION_MUSICVOLUME:
- m_PrefsMusicVolume += value * (128/MENUSLIDER_LOGICAL_BARS);
- m_PrefsMusicVolume = Clamp(m_PrefsMusicVolume, 0, 127);
- DMAudio.SetMusicMasterVolume(m_PrefsMusicVolume);
+ if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) {
+ m_PrefsMusicVolume += value * (64 / MENUSLIDER_LOGICAL_BARS);
+ m_PrefsMusicVolume = Clamp(m_PrefsMusicVolume, 0, 65);
+ DMAudio.SetMusicMasterVolume(m_PrefsMusicVolume);
+ }
break;
case MENUACTION_SFXVOLUME:
- m_PrefsSfxVolume += value * (128/MENUSLIDER_LOGICAL_BARS);
- m_PrefsSfxVolume = Clamp(m_PrefsSfxVolume, 0, 127);
- DMAudio.SetEffectsMasterVolume(m_PrefsSfxVolume);
+ if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) {
+ m_PrefsSfxVolume += value * (64 / MENUSLIDER_LOGICAL_BARS);
+ m_PrefsSfxVolume = Clamp(m_PrefsSfxVolume, 0, 65);
+ DMAudio.SetEffectsMasterVolume(m_PrefsSfxVolume);
+ }
+ break;
+ case MENUACTION_MP3VOLUMEBOOST:
+ if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) {
+ if (DMAudio.IsMP3RadioChannelAvailable()) {
+ m_PrefsMP3BoostVolume += value * (64 / MENUSLIDER_LOGICAL_BARS);
+ m_PrefsMP3BoostVolume = Clamp(m_PrefsMP3BoostVolume, 0, 65);
+ DMAudio.SetMP3BoostVolume(m_PrefsMP3BoostVolume);
+ }
+ }
break;
case MENUACTION_MOUSESENS:
TheCamera.m_fMouseAccelHorzntl += value * 1.0f/200.0f/15.0f; // probably because diving it to 15 instead of 16(MENUSLIDER_LOGICAL_BARS) had more accurate steps
TheCamera.m_fMouseAccelHorzntl = Clamp(TheCamera.m_fMouseAccelHorzntl, 1.0f/3200.0f, 1.0f/200.0f);
#ifdef FIX_BUGS
TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl + 0.0005f;
-#else
- TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl;
#endif
break;
#ifdef CUSTOM_FRONTEND_OPTIONS
@@ -950,72 +787,110 @@ CMenuManager::CheckSliderMovement(int value)
}
void
-CMenuManager::DisplayHelperText()
+CMenuManager::DisplayHelperText(char *text)
{
+ if (m_nMenuFadeAlpha != 255)
+ return;
+
// there was a unused static bool
static uint32 LastFlash = 0;
- int32 alpha;
+ int32 alpha = 255;
- if (m_nHelperTextMsgId != 0 && m_nHelperTextMsgId != 1) {
+ CFont::SetRightJustifyOn();
+ CFont::SetScale(SCREEN_SCALE_X(SMALLESTTEXT_X_SCALE), SCREEN_SCALE_Y(SMALLESTTEXT_Y_SCALE));
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
+ CFont::SetDropShadowPosition(0);
- // FIX: High fps bug
-#ifndef FIX_BUGS
+ // We're using SCREEN_STRETCH_FROM_RIGHT, because we also stretch black borders
+ if (text) {
+ CFont::SetColor(CRGBA(255, 255, 255, 255));
+ CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get(text));
+ return;
+ }
+
+ if (m_nHelperTextMsgId != 0 && m_nHelperTextMsgId != 1) {
if (CTimer::GetTimeInMillisecondsPauseMode() - LastFlash > 10) {
LastFlash = CTimer::GetTimeInMillisecondsPauseMode();
m_nHelperTextAlpha -= 2;
}
-#else
- m_nHelperTextAlpha -= 2 * CTimer::GetLogicalFramesPassed();
-#endif
+
if (m_nHelperTextAlpha < 1)
ResetHelperText();
alpha = m_nHelperTextAlpha > 255 ? 255 : m_nHelperTextAlpha;
}
- SET_FONT_FOR_HELPER_TEXT
+ CFont::SetColor(CRGBA(255, 255, 255, alpha));
// TODO: name this cases?
switch (m_nHelperTextMsgId) {
- case 0:
- {
- int action = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action;
- if (action != MENUACTION_CHANGEMENU && action != MENUACTION_KEYBOARDCTRLS && action != MENUACTION_RESTOREDEF) {
- CFont::SetColor(CRGBA(255, 255, 255, 255));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(HELPER_TEXT_LEFT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get("FET_MIG"));
- }
- break;
- }
case 1:
- CFont::SetColor(CRGBA(255, 255, 255, 255));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(HELPER_TEXT_LEFT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get("FET_APP"));
+ CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get("FET_APP"));
break;
case 2:
- CFont::SetColor(CRGBA(255, 255, 255, alpha));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(HELPER_TEXT_LEFT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get("FET_HRD"));
+ CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get("FET_HRD"));
break;
case 3:
- CFont::SetColor(CRGBA(255, 255, 255, alpha));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(HELPER_TEXT_LEFT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get("FET_RSO"));
+ CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get("FET_RSO"));
break;
case 4:
- CFont::SetColor(CRGBA(255, 255, 255, alpha));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(HELPER_TEXT_LEFT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get("FET_RSC"));
+ CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get("FET_STS"));
+ break;
+ case 5:
+ CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get("FET_RSC"));
break;
default:
+ if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_NO)
+ return;
+
+ if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_MUSICVOLUME ||
+ aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_SFXVOLUME) {
+
+ CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN),
+ m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER ? TheText.Get("FEH_NA") : TheText.Get("FET_MIG"));
+ return;
+ }
+
+ if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_KEYBOARDCTRLS)
+ return;
+
+ if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_SCREENRES) {
+ CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN),
+ m_bGameNotLoaded ? TheText.Get("FET_MIG") : TheText.Get("FEH_NA"));
+ return;
+ }
+
+ if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_AUDIOHW ||
+ aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_SPEAKERCONF) {
+
+ CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN),
+ m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER ? TheText.Get("FEH_NA") : TheText.Get("FET_MIG"));
+ return;
+ }
+
+ if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_RESTOREDEF)
+ return;
+
+ if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_MP3VOLUMEBOOST) {
+ CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN),
+ m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER ? TheText.Get("FEH_NA") : TheText.Get("FET_MIG"));
+ return;
+ }
+
+ CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN),
+ m_nCurrScreen != MENUPAGE_STATS ? TheText.Get("FET_MIG") : TheText.Get("FEH_SSA"));
+
break;
}
- CFont::SetRightJustifyOff();
}
int
-CMenuManager::DisplaySlider(float x, float y, float mostLeftBarSize, float mostRightBarSize, float rectSize, float progress)
+CMenuManager::DisplaySlider(float x, float y, float mostLeftBarSize, float mostRightBarSize, float rectSize, float progress, float spacing)
{
CRGBA color;
float maxBarHeight;
int lastActiveBarX = 0;
float curBarX = 0.0f;
- float spacing = SCREEN_SCALE_X(10.0f);
for (int i = 0; i < MENUSLIDER_BARS; i++) {
curBarX = i * rectSize/MENUSLIDER_BARS + x;
@@ -1042,82 +917,91 @@ CMenuManager::DisplaySlider(float x, float y, float mostLeftBarSize, float mostR
void
CMenuManager::DoSettingsBeforeStartingAGame()
{
-#ifdef PC_PLAYER_CONTROLS
- CCamera::m_bUseMouse3rdPerson = m_ControlMethod == CONTROL_STANDARD;
-#endif
+#ifdef LEGACY_MENU_OPTIONS
if (m_PrefsVsyncDisp != m_PrefsVsync)
m_PrefsVsync = m_PrefsVsyncDisp;
-
+#endif
+ DMAudio.DestroyAllGameCreatedEntities();
DMAudio.Service();
+ m_bShutDownFrontEndRequested = true;
m_bWantToRestart = true;
-
- ShutdownJustMenu();
- UnloadTextures();
DMAudio.SetEffectsFadeVol(0);
DMAudio.SetMusicFadeVol(0);
+ for (int i = 0; i < NUM_RADIOS; i++)
+ CStats::FavoriteRadioStationList[i] = 0.0f;
+
+ SwitchMenuOnAndOff();
DMAudio.ResetTimers(CTimer::GetTimeInMilliseconds());
}
void
-CMenuManager::Draw()
+CMenuManager::DrawStandardMenus(bool activeScreen)
{
+ float nextYToUse = 0.0f; // III leftover, set but unused in VC
+ bool itemsAreSelectable = true;
CFont::SetBackgroundOff();
CFont::SetPropOn();
CFont::SetCentreOff();
CFont::SetJustifyOn();
- CFont::SetBackGroundOnlyTextOn();
-#if GTA_VERSION >= GTA3_PC_11 && defined(DRAW_MENU_VERSION_TEXT)
- CFont::SetColor(CRGBA(LABEL_COLOR.r, LABEL_COLOR.g, LABEL_COLOR.b, 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);
+ CFont::SetBackGroundOnlyTextOff();
+
+#ifdef CUSTOM_FRONTEND_OPTIONS
+ const int xMargin = aScreens[m_nCurrScreen].layout && aScreens[m_nCurrScreen].layout->xMargin != 0 ? aScreens[m_nCurrScreen].layout->xMargin : MENU_X_MARGIN;
+#else
+ const int xMargin = MENU_X_MARGIN;
+#endif
+
+ CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(xMargin));
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(xMargin));
+#ifdef ASPECT_RATIO_SCALE
+ CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH));
+#else
+ CFont::SetCentreSize(SCREEN_WIDTH);
#endif
- CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN));
- CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_X_MARGIN - 2.0f));
switch (m_nCurrScreen) {
+ case MENUPAGE_CHOOSE_LOAD_SLOT:
+ case MENUPAGE_CHOOSE_DELETE_SLOT:
+ case MENUPAGE_CHOOSE_SAVE_SLOT:
+ CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(38.0f), MENU_Y(85.0f),
+ MENU_X_LEFT_ALIGNED(615.0f), MENU_Y(75.0f),
+ MENU_X_LEFT_ALIGNED(30.0f), MENU_Y(320.0f),
+ MENU_X_LEFT_ALIGNED(605.0f), MENU_Y(330.0f), CRGBA(LIST_BACKGROUND_COLOR.r, LIST_BACKGROUND_COLOR.g, LIST_BACKGROUND_COLOR.b, FadeIn(LIST_BACKGROUND_COLOR.a)));
+ break;
+ case MENUPAGE_SOUND_SETTINGS:
+ PrintRadioSelector();
+ break;
case MENUPAGE_STATS:
PrintStats();
break;
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') {
-
+
SET_FONT_FOR_MENU_HEADER
- CFont::PrintString(PAGE_NAME_X(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_STRETCH_FROM_RIGHT(MENUHEADER_POS_X) - MENU_X(7.f), SCREEN_SCALE_Y(MENUHEADER_POS_Y + 7.f), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName));
- // Weird place to put that.
- nextYToUse += 24.0f + 10.0f;
+ CFont::SetColor(CRGBA(HEADER_COLOR.r, HEADER_COLOR.g, HEADER_COLOR.b, FadeIn(255)));
+ CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_Y(MENUHEADER_POS_Y), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName));
}
- 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(LABEL_COLOR.r, LABEL_COLOR.g, LABEL_COLOR.b, FadeIn(255)));
-
// Label
wchar *str;
if (aScreens[m_nCurrScreen].m_aEntries[0].m_Action == MENUACTION_LABEL) {
+ CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENULABEL_X_MARGIN));
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENULABEL_X_MARGIN));
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
+ CFont::SetScale(MENU_X(BIGTEXT2_X_SCALE), MENU_Y(BIGTEXT2_Y_SCALE));
+ CFont::SetRightJustifyOff();
+ CFont::SetDropShadowPosition(2);
+ CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255)));
+ CFont::SetColor(CRGBA(LABEL_COLOR.r, LABEL_COLOR.g, LABEL_COLOR.b, FadeIn(255)));
+
switch (m_nCurrScreen) {
case MENUPAGE_LOAD_SLOT_CONFIRM:
if (m_bGameNotLoaded)
@@ -1125,8 +1009,13 @@ CMenuManager::Draw()
else
str = TheText.Get(aScreens[m_nCurrScreen].m_aEntries[0].m_EntryName);
break;
+ case MENUPAGE_DELETE_SLOT_CONFIRM:
+ str = TheText.Get(aScreens[MENUPAGE_DELETE_SLOT_CONFIRM].m_aEntries[0].m_EntryName);
+ break;
case MENUPAGE_SAVE_OVERWRITE_CONFIRM:
- if (Slots[m_nCurrSaveSlot + 1] == SLOT_EMPTY)
+ if (Slots[m_nCurrSaveSlot] == SLOT_OK)
+ str = TheText.Get("FESZ_QO");
+ else if (Slots[m_nCurrSaveSlot] == SLOT_CORRUPTED)
str = TheText.Get("FESZ_QZ");
else
str = TheText.Get(aScreens[m_nCurrScreen].m_aEntries[0].m_EntryName);
@@ -1142,735 +1031,591 @@ CMenuManager::Draw()
break;
}
-#ifdef FIX_BUGS
- // Label is wrapped from right by StretchX(40)px, but wrapped from left by 40px. And this is only place R* didn't use StretchX in here.
- CFont::PrintString(MENU_X_LEFT_ALIGNED(MENU_X_MARGIN), MENU_Y(MENUACTION_POS_Y), str);
-#else
- CFont::PrintString(MENU_X_MARGIN, MENUACTION_POS_Y, str);
-#endif
- }
-
- // Not a bug, we just want HFoV+ on menu
-#ifdef ASPECT_RATIO_SCALE
- CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH));
-#else
- CFont::SetCentreSize(SCREEN_WIDTH);
-#endif
-
-#ifdef PS2_LIKE_MENU
- bool itemsAreSelectable = !bottomBarActive;
-#else
- bool itemsAreSelectable = true;
-#endif
- int lineHeight;
- int headerHeight;
- int columnWidth;
- switch (m_nCurrScreen) {
- case MENUPAGE_STATS:
- case MENUPAGE_BRIEFS:
- columnWidth = 320;
- headerHeight = 240;
- 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));
- CFont::SetCentreOn();
- break;
-#ifdef FIX_BUGS
- case MENUPAGE_CONTROLLER_SETTINGS:
- columnWidth = 50;
- headerHeight = -50;
- lineHeight = 20;
- CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING));
- CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X = MEDIUMTEXT_X_SCALE), MENU_Y(MENU_TEXT_SIZE_Y = MEDIUMTEXT_Y_SCALE));
- CFont::SetRightJustifyOff();
- break;
-#endif
- case MENUPAGE_SOUND_SETTINGS:
- case MENUPAGE_DISPLAY_SETTINGS:
- case MENUPAGE_MULTIPLAYER_CREATE:
- case MENUPAGE_SKIN_SELECT_OLD:
- case MENUPAGE_CONTROLLER_PC_OLD1:
- case MENUPAGE_CONTROLLER_PC_OLD2:
- case MENUPAGE_CONTROLLER_PC_OLD3:
- case MENUPAGE_CONTROLLER_PC_OLD4:
- case MENUPAGE_CONTROLLER_DEBUG:
- case MENUPAGE_MOUSE_CONTROLS:
- columnWidth = 50;
- headerHeight = 0;
- lineHeight = 20;
- CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING));
- CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X = MEDIUMTEXT_X_SCALE), MENU_Y(MENU_TEXT_SIZE_Y = MEDIUMTEXT_Y_SCALE));
- CFont::SetRightJustifyOff();
- break;
- case MENUPAGE_CHOOSE_LOAD_SLOT:
- case MENUPAGE_CHOOSE_DELETE_SLOT:
- case MENUPAGE_CHOOSE_SAVE_SLOT:
- columnWidth = 120;
- headerHeight = 38;
- lineHeight = 20;
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
- CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X = SMALLTEXT_X_SCALE), MENU_Y(MENU_TEXT_SIZE_Y = SMALLTEXT_Y_SCALE));
- CFont::SetRightJustifyOff();
- break;
- case MENUPAGE_NEW_GAME_RELOAD:
- case MENUPAGE_LOAD_SLOT_CONFIRM:
- case MENUPAGE_DELETE_SLOT_CONFIRM:
- case MENUPAGE_SAVE_OVERWRITE_CONFIRM:
- case MENUPAGE_EXIT:
- columnWidth = 320;
- headerHeight = 60;
- 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));
- CFont::SetCentreOn();
- break;
- case MENUPAGE_START_MENU:
- columnWidth = 320;
- headerHeight = 140;
- 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));
- CFont::SetCentreOn();
- break;
- case MENUPAGE_PAUSE_MENU:
- columnWidth = 320;
- headerHeight = 117;
- 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));
- 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:
-#ifdef CUSTOM_FRONTEND_OPTIONS
- CCustomScreenLayout *custom = aScreens[m_nCurrScreen].layout;
- if (custom) {
- columnWidth = custom->columnWidth;
- headerHeight = custom->headerHeight;
- lineHeight = custom->lineHeight;
- CFont::SetFontStyle(FONT_LOCALE(custom->font));
- CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X = custom->fontScaleX), MENU_Y(MENU_TEXT_SIZE_Y = custom->fontScaleY));
- if (custom->alignment == FESCREEN_LEFT_ALIGN) {
- CFont::SetCentreOff();
- CFont::SetRightJustifyOff();
- } else if (custom->alignment == FESCREEN_RIGHT_ALIGN) {
- CFont::SetCentreOff();
- CFont::SetRightJustifyOn();
- } else {
- CFont::SetRightJustifyOff();
- CFont::SetCentreOn();
- }
- }
- if (!custom)
-#endif
- {
- columnWidth = 320;
- headerHeight = 40;
- 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));
- CFont::SetCentreOn();
- }
- break;
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(100.0f), MENU_Y(97.0f), str);
+ CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(xMargin));
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(xMargin));
}
-#ifdef PS2_LIKE_MENU
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
-#endif
-
- switch (m_nCurrScreen) {
- case MENUPAGE_CONTROLLER_PC_OLD1:
- case MENUPAGE_CONTROLLER_PC_OLD2:
- case MENUPAGE_CONTROLLER_PC_OLD3:
- case MENUPAGE_CONTROLLER_PC_OLD4:
- case MENUPAGE_CONTROLLER_DEBUG:
- if (m_bWaitingForNewKeyBind)
- itemsAreSelectable = false;
+ if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) {
+ if (m_bWaitingForNewKeyBind)
+ itemsAreSelectable = false;
- DrawControllerScreenExtraText(nextYToUse - 8.0f, MENU_X_LEFT_ALIGNED(350), lineHeight);
- break;
- default:
- break;
+ DrawControllerScreenExtraText(-8.0f, MENU_X_LEFT_ALIGNED(350), MENU_DEFAULT_LINE_HEIGHT);
}
- float usableLineHeight = lineHeight * 0.9f; // also height of biggest bar in slider
- float smallestSliderBar = lineHeight * 0.1f;
- bool foundTheHoveringItem = false;
wchar unicodeTemp[64];
#ifdef ASPECT_RATIO_SCALE
char asciiTemp[32];
#endif
-#ifdef MENU_MAP
- if (m_nCurrScreen == MENUPAGE_MAP) {
- // Back button
- wchar *backTx = TheText.Get("FEDS_TB");
- CFont::SetDropShadowPosition(1);
- CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255)));
- CFont::PrintString(MENU_X(60.0f), SCREEN_SCALE_FROM_BOTTOM(120.0f), backTx);
- CFont::SetDropShadowPosition(0);
- if (!CheckHover(MENU_X(30.0f), MENU_X(30.0f) + CFont::GetStringWidth(backTx), SCREEN_SCALE_FROM_BOTTOM(125.0f), SCREEN_SCALE_FROM_BOTTOM(105.0f))) {
- m_nHoverOption = HOVEROPTION_NOT_HOVERING;
- m_nCurrOption = m_nOptionMouseHovering = 0;
- } else {
- m_nHoverOption = HOVEROPTION_RANDOM_ITEM;
- m_nCurrOption = m_nOptionMouseHovering = 1;
- }
- return;
- }
-#endif
+ bool weHaveLabel = aScreens[m_nCurrScreen].m_aEntries[0].m_Action == MENUACTION_LABEL;
+ uint8 section = 0; // 0: highlight trapezoid 1: texts
-#ifdef CUSTOM_FRONTEND_OPTIONS
- // Thanks R*, for checking mouse hovering in Draw().
- static int lastSelectedOpt = m_nCurrOption;
+ while (section < 2) {
#endif
#ifdef SCROLLABLE_PAGES
- int firstOption = SCREEN_HAS_AUTO_SCROLLBAR ? m_nFirstVisibleRowOnList : 0;
- for (int i = firstOption; i < firstOption + MAX_VISIBLE_OPTION && i < NUM_MENUROWS; ++i) {
+ int firstOption = SCREEN_HAS_AUTO_SCROLLBAR ? m_nFirstVisibleRowOnList : 0;
+ int scrollOffset = aScreens[m_nCurrScreen].m_aEntries[firstOption].m_Y - aScreens[m_nCurrScreen].m_aEntries[0].m_Y;
+ for (int i = firstOption; i < firstOption + MAX_VISIBLE_OPTION && i < NUM_MENUROWS; ++i) {
#else
- for (int i = 0; i < NUM_MENUROWS; ++i) {
+ for (int i = 0; i < NUM_MENUROWS; ++i) {
#endif
-
+ wchar* rightText = nil;
+ wchar* leftText;
+ if (aScreens[m_nCurrScreen].m_aEntries[i].m_SaveSlot >= SAVESLOT_1 && aScreens[m_nCurrScreen].m_aEntries[i].m_SaveSlot <= SAVESLOT_8) {
+ CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255)));
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
+ CFont::SetScale(MENU_X(MEDIUMTEXT_X_SCALE), MENU_Y(MEDIUMTEXT_Y_SCALE));
+ CFont::SetDropShadowPosition(0);
+ } else {
+ CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING));
+ CFont::SetScale(MENU_X(BIGTEXT_X_SCALE), MENU_Y(BIGTEXT_Y_SCALE));
+ CFont::SetDropShadowPosition(2);
+ CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255)));
+ CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255)));
+ }
+ if (aScreens[m_nCurrScreen].m_aEntries[i].m_Align == MENUALIGN_LEFT) {
+ CFont::SetCentreOff();
+ CFont::SetRightJustifyOff();
+ } else if (aScreens[m_nCurrScreen].m_aEntries[i].m_Align == MENUALIGN_RIGHT) {
+ CFont::SetCentreOff();
+ CFont::SetRightJustifyOn();
+ } else {
+ CFont::SetRightJustifyOff();
+ CFont::SetCentreOn();
+ }
+ if (aScreens[m_nCurrScreen].m_aEntries[i].m_X == 0 && aScreens[m_nCurrScreen].m_aEntries[i].m_Y == 0) {
+ if (i == 0 || (i == 1 && weHaveLabel)) {
#ifdef CUSTOM_FRONTEND_OPTIONS
- bool isOptionDisabled = false;
+ aScreens[m_nCurrScreen].m_aEntries[i].m_X = (aScreens[m_nCurrScreen].layout ? aScreens[m_nCurrScreen].layout->startX : MENU_DEFAULT_CONTENT_X);
+ aScreens[m_nCurrScreen].m_aEntries[i].m_Y = (aScreens[m_nCurrScreen].layout ? aScreens[m_nCurrScreen].layout->startY : MENU_DEFAULT_CONTENT_Y);
+#else
+ aScreens[m_nCurrScreen].m_aEntries[i].m_X = MENU_DEFAULT_CONTENT_X;
+ aScreens[m_nCurrScreen].m_aEntries[i].m_Y = MENU_DEFAULT_CONTENT_Y;
#endif
- // Hide back button
-#ifdef PS2_LIKE_MENU
- if ((i == NUM_MENUROWS - 1 || aScreens[m_nCurrScreen].m_aEntries[i+1].m_EntryName[0] == '\0') && strcmp(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName, "FEDS_TB") == 0)
- break;
+
+ } else {
+ aScreens[m_nCurrScreen].m_aEntries[i].m_X = aScreens[m_nCurrScreen].m_aEntries[i-1].m_X;
+ aScreens[m_nCurrScreen].m_aEntries[i].m_Y = aScreens[m_nCurrScreen].m_aEntries[i-1].m_Y PLUS_LINE_HEIGHT_ON_SCREEN;
+ }
+ }
+#ifdef CUSTOM_FRONTEND_OPTIONS
+ else if (aScreens[m_nCurrScreen].m_aEntries[i].m_Y == 0) {
+ aScreens[m_nCurrScreen].m_aEntries[i].m_Y = aScreens[m_nCurrScreen].m_aEntries[i-1].m_Y PLUS_LINE_HEIGHT_ON_SCREEN;
+ }
#endif
- if (aScreens[m_nCurrScreen].m_aEntries[i].m_Action != MENUACTION_LABEL && aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName[0] != '\0') {
- wchar *rightText = nil;
- wchar *leftText;
- if (aScreens[m_nCurrScreen].m_aEntries[i].m_SaveSlot >= SAVESLOT_1 && aScreens[m_nCurrScreen].m_aEntries[i].m_SaveSlot <= SAVESLOT_8) {
- CFont::SetRightJustifyOff();
- leftText = GetNameOfSavedGame(i - 1);
+ if (aScreens[m_nCurrScreen].m_aEntries[i].m_Action != MENUACTION_LABEL && aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName[0] != '\0') {
- if (Slots[i] != SLOT_EMPTY)
- rightText = GetSavedGameDateAndTime(i - 1);
+ if (aScreens[m_nCurrScreen].m_aEntries[i].m_SaveSlot >= SAVESLOT_1 && aScreens[m_nCurrScreen].m_aEntries[i].m_SaveSlot <= SAVESLOT_8) {
+ CFont::SetRightJustifyOff();
- if (leftText[0] == '\0') {
- sprintf(gString, "FEM_SL%d", i);
- leftText = TheText.Get(gString);
+ leftText = nil;
+ if (Slots[i] == SLOT_OK) {
+ leftText = GetNameOfSavedGame(i);
+ rightText = GetSavedGameDateAndTime(i);
+ }
+
+ if (!leftText || leftText[0] == '\0') {
+ sprintf(gString, "FEM_SL%d", i + 1);
+ leftText = TheText.Get(gString);
+ }
+ } else {
+ leftText = TheText.Get(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName);
}
- } else {
- leftText = TheText.Get(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName);
- }
- 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;
- }
+ if (m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER) {
+ if (strcmp(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName, "FEO_AUD") == 0) {
+ CFont::SetColor(CRGBA(DARKMENUOPTION_COLOR.r, DARKMENUOPTION_COLOR.g, DARKMENUOPTION_COLOR.b, FadeIn(255)));
+ }
+ }
+
+ switch (aScreens[m_nCurrScreen].m_aEntries[i].m_Action) {
+#ifdef GAMEPAD_MENU
+ case MENUACTION_CTRLVIBRATION:
+ if (m_PrefsUseVibration)
+ rightText = TheText.Get("FEM_ON");
+ else
+ rightText = TheText.Get("FEM_OFF");
+ break;
+ case MENUACTION_CTRLCONFIG:
+ switch (CPad::GetPad(0)->Mode) {
+ case 0:
+ rightText = TheText.Get("FEC_CF1");
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;
- }
+ case 1:
+ rightText = TheText.Get("FEC_CF2");
break;
- default:
+ case 2:
+ rightText = TheText.Get("FEC_CF3");
break;
- }
- break;
- }
- case MENUACTION_CTRLVIBRATION:
- if (m_PrefsUseVibration)
- rightText = TheText.Get("FEM_ON");
- else
- rightText = TheText.Get("FEM_OFF");
- break;
- case MENUACTION_CTRLCONFIG:
- switch (CPad::GetPad(0)->Mode) {
- case 0:
- rightText = TheText.Get("FEC_CF1");
+ case 3:
+ rightText = TheText.Get("FEC_CF4");
+ break;
+ }
break;
- case 1:
- rightText = TheText.Get("FEC_CF2");
+ // This one is still in enum and ProcessOnOffMenuOptions, but removed from other places
+ case MENUACTION_CTRLDISPLAY:
+ if (m_DisplayControllerOnFoot)
+ rightText = TheText.Get("FEC_ONF");
+ else
+ rightText = TheText.Get("FEC_INC");
break;
- case 2:
- rightText = TheText.Get("FEC_CF3");
+#endif
+ case MENUACTION_FRAMESYNC:
+ rightText = TheText.Get(m_PrefsVsyncDisp ? "FEM_ON" : "FEM_OFF");
break;
- case 3:
- rightText = TheText.Get("FEC_CF4");
+ case MENUACTION_FRAMELIMIT:
+ rightText = TheText.Get(m_PrefsFrameLimiter ? "FEM_ON" : "FEM_OFF");
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;
- case MENUACTION_FRAMELIMIT:
- rightText = TheText.Get(m_PrefsFrameLimiter ? "FEM_ON" : "FEM_OFF");
- break;
- case MENUACTION_TRAILS:
- rightText = TheText.Get(CMBlur::BlurOn ? "FEM_ON" : "FEM_OFF");
- break;
- case MENUACTION_SUBTITLES:
- rightText = TheText.Get(m_PrefsShowSubtitles ? "FEM_ON" : "FEM_OFF");
- break;
- case MENUACTION_WIDESCREEN:
+ case MENUACTION_TRAILS:
+ rightText = TheText.Get(CMBlur::BlurOn ? "FEM_ON" : "FEM_OFF");
+ break;
+ case MENUACTION_SUBTITLES:
+ rightText = TheText.Get(m_PrefsShowSubtitles ? "FEM_ON" : "FEM_OFF");
+ break;
+ case MENUACTION_WIDESCREEN:
#ifndef ASPECT_RATIO_SCALE
- rightText = TheText.Get(m_PrefsUseWideScreen ? "FEM_ON" : "FEM_OFF");
+ rightText = TheText.Get(m_PrefsUseWideScreen ? "FEM_ON" : "FEM_OFF");
#else
- switch (m_PrefsUseWideScreen) {
- case AR_AUTO:
- rightText = TheText.Get("FEM_AUT");
+ switch (m_PrefsUseWideScreen) {
+ case AR_AUTO:
+ rightText = TheText.Get("FEM_AUT");
+ break;
+ case AR_4_3:
+ sprintf(asciiTemp, "4:3");
+ AsciiToUnicode(asciiTemp, unicodeTemp);
+ rightText = unicodeTemp;
+ break;
+ case AR_5_4:
+ sprintf(asciiTemp, "5:4");
+ AsciiToUnicode(asciiTemp, unicodeTemp);
+ rightText = unicodeTemp;
+ break;
+ case AR_16_10:
+ sprintf(asciiTemp, "16:10");
+ AsciiToUnicode(asciiTemp, unicodeTemp);
+ rightText = unicodeTemp;
+ break;
+ case AR_16_9:
+ sprintf(asciiTemp, "16:9");
+ AsciiToUnicode(asciiTemp, unicodeTemp);
+ rightText = unicodeTemp;
+ break;
+ case AR_21_9:
+ sprintf(asciiTemp, "21:9");
+ AsciiToUnicode(asciiTemp, unicodeTemp);
+ rightText = unicodeTemp;
+ break;
+ }
+#endif
break;
- case AR_4_3:
- sprintf(asciiTemp, "4:3");
- AsciiToUnicode(asciiTemp, unicodeTemp);
- rightText = unicodeTemp;
+
+ case MENUACTION_MUSICVOLUME:
+ case MENUACTION_SFXVOLUME:
+ if (m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER)
+ rightText = TheText.Get("FEA_NAH");
+
break;
- case AR_5_4:
- sprintf(asciiTemp, "5:4");
- AsciiToUnicode(asciiTemp, unicodeTemp);
- rightText = unicodeTemp;
+ case MENUACTION_RADIO:
+ switch (m_PrefsRadioStation) {
+ case WILDSTYLE:
+ rightText = TheText.Get("FEA_FM0");
+ break;
+ case FLASH_FM:
+ rightText = TheText.Get("FEA_FM1");
+ break;
+ case KCHAT:
+ rightText = TheText.Get("FEA_FM2");
+ break;
+ case FEVER:
+ rightText = TheText.Get("FEA_FM3");
+ break;
+ case V_ROCK:
+ rightText = TheText.Get("FEA_FM4");
+ break;
+ case VCPR:
+ rightText = TheText.Get("FEA_FM5");
+ break;
+ case RADIO_ESPANTOSO:
+ rightText = TheText.Get("FEA_FM6");
+ break;
+ case EMOTION:
+ rightText = TheText.Get("FEA_FM7");
+ break;
+ case WAVE:
+ rightText = TheText.Get("FEA_FM8");
+ break;
+ case USERTRACK:
+ rightText = TheText.Get("FEA_MP3");
+ break;
+ }
break;
- case AR_16_10:
- sprintf(asciiTemp, "16:10");
- AsciiToUnicode(asciiTemp, unicodeTemp);
- rightText = unicodeTemp;
+ case MENUACTION_LEGENDS:
+ rightText = TheText.Get(m_PrefsShowLegends ? "FEM_ON" : "FEM_OFF");
break;
- case AR_16_9:
- sprintf(asciiTemp, "16:9");
- AsciiToUnicode(asciiTemp, unicodeTemp);
- rightText = unicodeTemp;
+ case MENUACTION_RADARMODE:
+ switch (m_PrefsRadarMode) {
+ case 0:
+ rightText = TheText.Get("FED_RDM");
+ break;
+ case 1:
+ rightText = TheText.Get("FED_RDB");
+ break;
+ case 2:
+ rightText = TheText.Get("FEM_OFF");
+ break;
+ }
break;
- case AR_21_9:
- sprintf(asciiTemp, "21:9");
- AsciiToUnicode(asciiTemp, unicodeTemp);
- rightText = unicodeTemp;
+ case MENUACTION_HUD:
+ rightText = TheText.Get(m_PrefsShowHud ? "FEM_ON" : "FEM_OFF");
+ break;
+#ifdef LEGACY_MENU_OPTIONS
+ case MENUACTION_SETDBGFLAG:
+ rightText = TheText.Get(CTheScripts::IsDebugOn() ? "FEM_ON" : "FEM_OFF");
+ break;
+ case MENUACTION_SWITCHBIGWHITEDEBUGLIGHT:
+ rightText = TheText.Get(gbBigWhiteDebugLightSwitchedOn ? "FEM_ON" : "FEM_OFF");
+ break;
+ case MENUACTION_COLLISIONPOLYS:
+ rightText = TheText.Get(gbShowCollisionPolys ? "FEM_ON" : "FEM_OFF");
break;
- }
#endif
- break;
- case MENUACTION_RADIO:
- if (m_PrefsRadioStation > USERTRACK)
+ case MENUACTION_SHOWHEADBOB:
+ rightText = TheText.Get(TheCamera.m_bHeadBob ? "FEM_ON" : "FEM_OFF");
+ break;
+ case MENUACTION_INVVERT:
+ rightText = TheText.Get(MousePointerStateHelper.bInvertVertically ? "FEM_OFF" : "FEM_ON");
break;
+ case MENUACTION_SCREENRES:
+ AsciiToUnicode(_psGetVideoModeList()[m_nDisplayVideoMode], unicodeTemp);
+ rightText = unicodeTemp;
- sprintf(gString, "FEA_FM%d", m_PrefsRadioStation);
- rightText = TheText.Get(gString);
- break;
- case MENUACTION_SETDBGFLAG:
- rightText = TheText.Get(CTheScripts::IsDebugOn() ? "FEM_ON" : "FEM_OFF");
- break;
- case MENUACTION_SWITCHBIGWHITEDEBUGLIGHT:
- rightText = TheText.Get(gbBigWhiteDebugLightSwitchedOn ? "FEM_ON" : "FEM_OFF");
- break;
- case MENUACTION_PEDROADGROUPS:
- rightText = TheText.Get(gbShowPedRoadGroups ? "FEM_ON" : "FEM_OFF");
- break;
- case MENUACTION_CARROADGROUPS:
- rightText = TheText.Get(gbShowCarRoadGroups ? "FEM_ON" : "FEM_OFF");
- break;
- case MENUACTION_COLLISIONPOLYS:
- rightText = TheText.Get(gbShowCollisionPolys ? "FEM_ON" : "FEM_OFF");
- break;
- case MENUACTION_SHOWCULL:
- rightText = TheText.Get(gbShowCullZoneDebugStuff ? "FEM_ON" : "FEM_OFF");
- break;
- case MENUACTION_SHOWHEADBOB:
- rightText = TheText.Get(TheCamera.m_bHeadBob ? "FEM_ON" : "FEM_OFF");
- break;
- case MENUACTION_INVVERT:
- rightText = TheText.Get(MousePointerStateHelper.bInvertVertically ? "FEM_OFF" : "FEM_ON");
- break;
- case MENUACTION_SCREENRES:
- AsciiToUnicode(_psGetVideoModeList()[m_nDisplayVideoMode], unicodeTemp);
- rightText = unicodeTemp;
- break;
- case MENUACTION_AUDIOHW:
- if (m_nPrefsAudio3DProviderIndex == -1)
- rightText = TheText.Get("FEA_NAH");
- else {
- char *provider = DMAudio.Get3DProviderName(m_nPrefsAudio3DProviderIndex);
-
- if (!strcmp(strupr(provider), "DIRECTSOUND3D HARDWARE SUPPORT")) {
- strcpy(provider, "DSOUND3D HARDWARE SUPPORT");
- } else if (!strcmp(strupr(provider), "DIRECTSOUND3D SOFTWARE EMULATION")) {
- strcpy(provider, "DSOUND3D SOFTWARE EMULATION");
+ if (!m_bGameNotLoaded) {
+ CFont::SetColor(CRGBA(DARKMENUOPTION_COLOR.r, DARKMENUOPTION_COLOR.g, DARKMENUOPTION_COLOR.b, FadeIn(255)));
}
- AsciiToUnicode(provider, unicodeTemp);
- rightText = unicodeTemp;
+ break;
+ case MENUACTION_AUDIOHW:
+ if (m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER)
+ rightText = TheText.Get("FEA_NAH");
+ else if (m_nPrefsAudio3DProviderIndex == -1)
+ rightText = TheText.Get("FEA_ADP");
+ else {
+ char *rawProvider = DMAudio.Get3DProviderName(m_nPrefsAudio3DProviderIndex);
+ AsciiToUnicode(rawProvider, unicodeTemp);
+ char *provider = UnicodeToAscii(unicodeTemp); // genius
+ strupr(provider);
+ if (!strcmp(provider, "DIRECTSOUND3D HARDWARE SUPPORT")) {
+ strcpy(provider, "DSOUND3D HARDWARE SUPPORT");
+ } else if (!strcmp(provider, "DIRECTSOUND3D SOFTWARE EMULATION")) {
+ strcpy(provider, "DSOUND3D SOFTWARE EMULATION");
+ }
+ AsciiToUnicode(provider, unicodeTemp);
+ rightText = unicodeTemp;
+ }
+ break;
+ case MENUACTION_SPEAKERCONF: {
+ if (m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER)
+ rightText = TheText.Get("FEA_NAH");
+ else {
+ switch (m_PrefsSpeakers) {
+ case 0:
+ rightText = TheText.Get("FEA_2SP");
+ break;
+ case 1:
+ rightText = TheText.Get("FEA_EAR");
+ break;
+ case 2:
+ rightText = TheText.Get("FEA_4SP");
+ break;
+ }
+ }
+ break;
}
- break;
- case MENUACTION_SPEAKERCONF: {
- if (m_nPrefsAudio3DProviderIndex == -1)
- rightText = TheText.Get("FEA_NAH");
- else {
- switch (m_PrefsSpeakers) {
- case 0:
- rightText = TheText.Get("FEA_2SP");
+ case MENUACTION_CTRLMETHOD: {
+ switch (m_ControlMethod) {
+ case CONTROL_STANDARD:
+ leftText = TheText.Get("FET_STI");
break;
- case 1:
- rightText = TheText.Get("FEA_EAR");
- break;
- case 2:
- rightText = TheText.Get("FEA_4SP");
+ case CONTROL_CLASSIC:
+ leftText = TheText.Get("FET_CTI");
break;
}
+ break;
}
- break;
- }
- case MENUACTION_CTRLMETHOD: {
- switch (m_ControlMethod) {
- case 0:
- leftText = TheText.Get("FET_SCN");
+ case MENUACTION_DYNAMICACOUSTIC:
+ rightText = TheText.Get(m_PrefsDMA ? "FEM_ON" : "FEM_OFF");
break;
- case 1:
- leftText = TheText.Get("FET_CCN");
+ case MENUACTION_MOUSESTEER:
+ rightText = TheText.Get(CVehicle::m_bDisableMouseSteering ? "FEM_OFF" : "FEM_ON");
+ if (m_ControlMethod == CONTROL_CLASSIC) {
+ CFont::SetColor(CRGBA(DARKMENUOPTION_COLOR.r, DARKMENUOPTION_COLOR.g, DARKMENUOPTION_COLOR.b, FadeIn(255)));
+ }
+ break;
+ case MENUACTION_MP3VOLUMEBOOST:
+ if (!DMAudio.IsMP3RadioChannelAvailable()) {
+ rightText = TheText.Get("FEA_NM3");
+ }
break;
- }
- break;
- }
- case MENUACTION_DYNAMICACOUSTIC:
- rightText = TheText.Get(m_PrefsDMA ? "FEM_ON" : "FEM_OFF");
- break;
- case MENUACTION_MOUSESTEER:
- rightText = TheText.Get(CVehicle::m_bDisableMouseSteering ? "FEM_OFF" : "FEM_ON");
- break;
#ifdef CUSTOM_FRONTEND_OPTIONS
- case MENUACTION_CFO_DYNAMIC:
- case MENUACTION_CFO_SELECT:
- CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[i];
- if (option.m_Action == MENUACTION_CFO_SELECT) {
+ case MENUACTION_CFO_DYNAMIC:
+ case MENUACTION_CFO_SELECT:
+ CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[i];
+ if (option.m_Action == MENUACTION_CFO_SELECT) {
+ if (option.m_CFOSelect->disableIfGameLoaded && !m_bGameNotLoaded)
+ CFont::SetColor(CRGBA(DARKMENUOPTION_COLOR.r, DARKMENUOPTION_COLOR.g, DARKMENUOPTION_COLOR.b, FadeIn(255)));
+
+ // To whom manipulate option.m_CFO->value of static options externally (like RestoreDef functions)
+ if (*(int8*)option.m_CFO->value != option.m_CFOSelect->lastSavedValue)
+ option.m_CFOSelect->displayedValue = option.m_CFOSelect->lastSavedValue = *(int8*)option.m_CFO->value;
- isOptionDisabled = option.m_CFOSelect->disableIfGameLoaded && !m_bGameNotLoaded;
- if (option.m_CFOSelect->onlyApplyOnEnter){
- if (m_nCurrOption != i) {
- if (option.m_CFOSelect->displayedValue != option.m_CFOSelect->lastSavedValue)
- SetHelperText(3); // Restored original value
+ if (option.m_CFOSelect->displayedValue >= option.m_CFOSelect->numRightTexts || option.m_CFOSelect->displayedValue < 0)
+ option.m_CFOSelect->displayedValue = 0;
- // If that was previously selected option, restore it to default value.
- // if (m_nCurrOption != lastSelectedOpt && lastSelectedOpt == i)
- option.m_CFOSelect->displayedValue = option.m_CFOSelect->lastSavedValue = *(int8*)option.m_CFO->value;
+ rightText = TheText.Get(option.m_CFOSelect->rightTexts[option.m_CFOSelect->displayedValue]);
- } else {
- if (option.m_CFOSelect->displayedValue != *(int8*)option.m_CFO->value)
- SetHelperText(1); // Enter to apply
- else if (m_nHelperTextMsgId == 1)
- ResetHelperText(); // Applied
+ } else if (option.m_Action == MENUACTION_CFO_DYNAMIC) {
+ if (option.m_CFODynamic->drawFunc) {
+ bool isOptionDisabled = false;
+ rightText = option.m_CFODynamic->drawFunc(&isOptionDisabled, m_nCurrOption == i);
+ if (isOptionDisabled)
+ CFont::SetColor(CRGBA(DARKMENUOPTION_COLOR.r, DARKMENUOPTION_COLOR.g, DARKMENUOPTION_COLOR.b, FadeIn(255)));
}
}
+ break;
+#endif
+ }
- // To whom manipulate option.m_CFO->value of select options externally (like RestoreDef functions)
- if (*(int8*)option.m_CFO->value != option.m_CFOSelect->lastSavedValue)
- option.m_CFOSelect->displayedValue = option.m_CFOSelect->lastSavedValue = *(int8*)option.m_CFO->value;
+ // Highlight trapezoid
+ if (activeScreen && i == m_nCurrOption && itemsAreSelectable && section == 0) {
- if (option.m_CFOSelect->displayedValue >= option.m_CFOSelect->numRightTexts || option.m_CFOSelect->displayedValue < 0)
- option.m_CFOSelect->displayedValue = 0;
+ int leftXMax, rightXMin;
- rightText = TheText.Get(option.m_CFOSelect->rightTexts[option.m_CFOSelect->displayedValue]);
+ // FIX: Let's don't scale those so GetStringWidth can give us unscaled width, which will be handy to other calculations below that's done without scaling in mind,
+ // and scaling will be done eventually.
+ // CFont::SetScale(MENU_X(BIGTEXT_X_SCALE), MENU_Y(BIGTEXT_Y_SCALE));
+ CFont::SetScale(BIGTEXT_X_SCALE, BIGTEXT_Y_SCALE);
+
+ wchar *curOptionName = TheText.Get(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName);
+ float curOptionWidth = CFont::GetStringWidth(curOptionName, true);
- } else if (option.m_Action == MENUACTION_CFO_DYNAMIC) {
- if (m_nCurrOption != lastSelectedOpt && lastSelectedOpt == i) {
- if(option.m_CFODynamic->buttonPressFunc)
- option.m_CFODynamic->buttonPressFunc(FEOPTION_ACTION_FOCUSLOSS);
- }
+ if (CFont::Details.centre) {
+ leftXMax = Max(0, aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_X - curOptionWidth / 2.f);
+ rightXMin = Min(DEFAULT_SCREEN_WIDTH, curOptionWidth / 2.f + aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_X);
+
+ } else if (!CFont::Details.rightJustify) {
+ leftXMax = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_X;
+ rightXMin = Min(DEFAULT_SCREEN_WIDTH, curOptionWidth + aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_X);
- if (option.m_CFODynamic->drawFunc) {
- rightText = option.m_CFODynamic->drawFunc(&isOptionDisabled, m_nCurrOption == i);
+ } else {
+ leftXMax = Max(0, aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_X - curOptionWidth);
+ rightXMin = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_X;
}
- }
- break;
-#endif
- }
+ CFont::SetScale(MENU_X(BIGTEXT_X_SCALE), MENU_Y(BIGTEXT_Y_SCALE));
- float nextItemY = headerHeight + nextYToUse;
- float bitAboveNextItemY = nextItemY - 2.0f;
- int nextYToCheck = bitAboveNextItemY;
-
- if (!foundTheHoveringItem) {
-#ifdef SCROLLABLE_PAGES
- for (int rowToCheck = firstOption + (aScreens[m_nCurrScreen].m_aEntries[firstOption].m_Action == MENUACTION_LABEL); rowToCheck < firstOption + MAX_VISIBLE_OPTION && rowToCheck < NUM_MENUROWS; ++rowToCheck) {
-#else
- for (int rowToCheck = aScreens[m_nCurrScreen].m_aEntries[0].m_Action == MENUACTION_LABEL; rowToCheck < NUM_MENUROWS; ++rowToCheck) {
-#endif
- if(aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Action == MENUACTION_NOTHING)
- break;
-
- // Hide back button
-#ifdef PS2_LIKE_MENU
- if ((rowToCheck == NUM_MENUROWS - 1 || aScreens[m_nCurrScreen].m_aEntries[rowToCheck+1].m_EntryName[0] == '\0') &&
- strcmp(aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_EntryName, "FEDS_TB") == 0)
- break;
+ int action = aScreens[m_nCurrScreen].m_aEntries[i].m_Action;
+ int saveSlot = aScreens[m_nCurrScreen].m_aEntries[i].m_SaveSlot;
+ if (rightText || action == MENUACTION_DRAWDIST || action == MENUACTION_BRIGHTNESS || action == MENUACTION_MUSICVOLUME ||
+ action == MENUACTION_SFXVOLUME || action == MENUACTION_MP3VOLUMEBOOST || action == MENUACTION_MOUSESENS ||
+ saveSlot >= SAVESLOT_1 && saveSlot <= SAVESLOT_8
+#ifdef CUSTOM_FRONTEND_OPTIONS
+ || action == MENUACTION_CFO_SLIDER
#endif
+ ) {
+ rightXMin = 600;
+ leftXMax = 40;
+ }
- int extraOffset = 0;
- if (aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Action == MENUACTION_RADIO)
- extraOffset = MENURADIO_ICON_SCALE;
-
- // There were many unused codes in here to calculate how much space will texts gonna take.
-
- // FIX: nextYToCheck already starts with Y - 2, let's sync it with green bar bounds.
-#ifdef FIX_BUGS
- if (m_nMousePosY > MENU_Y(nextYToCheck) &&
-#else
- if (m_nMousePosY > MENU_Y(nextYToCheck - 2) &&
-#endif
- m_nMousePosY < MENU_Y((nextYToCheck + 2) + usableLineHeight)) {
+ int y = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Y MINUS_SCROLL_OFFSET;
+ int topYMax = y;
+ uint32 bottomYMin = y + MENU_DEFAULT_LINE_HEIGHT - 7; // Decreasing is not recommended. Because this actually is dependent to font scale, not line height.
- static int oldOption = -99;
- static int oldScreen = m_nCurrScreen;
+ // Actually bottomRight and bottomLeft should be exchanged here(although this is original code).
+ // So this shows us either R* didn't use same struct for menu BG and highlight, or they just kept fields as x1,y1 etc. Yikes.
- m_nOptionMouseHovering = rowToCheck;
- if (m_nMouseOldPosX != m_nMousePosX || m_nMouseOldPosY != m_nMousePosY) {
- m_nCurrOption = rowToCheck;
- m_bShowMouse = true;
+ if (m_nOptionHighlightTransitionBlend == 0) {
+ if (m_firstStartCounter == 255 && m_nMenuFadeAlpha == 255 && !bMenuChangeOngoing) {
+ CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(menuOptionHighlight.topLeft_x), MENU_Y(menuOptionHighlight.topLeft_y),
+ MENU_X_LEFT_ALIGNED(menuOptionHighlight.topRight_x), MENU_Y(menuOptionHighlight.topRight_y),
+ MENU_X_LEFT_ALIGNED(menuOptionHighlight.bottomRight_x), MENU_Y(menuOptionHighlight.bottomRight_y),
+ MENU_X_LEFT_ALIGNED(menuOptionHighlight.bottomLeft_x), MENU_Y(menuOptionHighlight.bottomLeft_y), SELECTIONBORDER_COLOR);
}
- if (oldOption != m_nCurrOption) {
- if (oldScreen == m_nCurrScreen && m_bShowMouse)
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0);
-
- oldOption = m_nCurrOption;
- oldScreen = m_nCurrScreen;
+ menuOptionHighlight.SaveCurrentCoors();
+ menuOptionHighlight.topLeft_x = leftXMax - 5 - CGeneral::GetRandomNumber() % 10;
+ menuOptionHighlight.topLeft_y = topYMax - CGeneral::GetRandomNumber() % 7;
+ menuOptionHighlight.topRight_x = rightXMin + 5 + CGeneral::GetRandomNumber() % 10;
+ menuOptionHighlight.topRight_y = topYMax - CGeneral::GetRandomNumber() % 7;
+ menuOptionHighlight.bottomLeft_x = rightXMin + 5 + CGeneral::GetRandomNumber() % 10;
+ menuOptionHighlight.bottomLeft_y = bottomYMin + CGeneral::GetRandomNumber() % 7;
+ menuOptionHighlight.bottomRight_x = leftXMax - 5 - CGeneral::GetRandomNumber() % 10;
+ menuOptionHighlight.bottomRight_y = bottomYMin + CGeneral::GetRandomNumber() % 7;
+ menuOptionHighlight.UpdateMultipliers();
+ menuOptionHighlight.Translate(m_nOptionHighlightTransitionBlend);
+
+ } else if (m_nOptionHighlightTransitionBlend < 255) {
+ menuOptionHighlight.Translate(m_nOptionHighlightTransitionBlend);
+ if (m_firstStartCounter == 255 && m_nMenuFadeAlpha == 255 && !bMenuChangeOngoing) {
+ CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(menuOptionHighlight.topLeft_x), MENU_Y(menuOptionHighlight.topLeft_y),
+ MENU_X_LEFT_ALIGNED(menuOptionHighlight.topRight_x), MENU_Y(menuOptionHighlight.topRight_y),
+ MENU_X_LEFT_ALIGNED(menuOptionHighlight.bottomRight_x), MENU_Y(menuOptionHighlight.bottomRight_y),
+ MENU_X_LEFT_ALIGNED(menuOptionHighlight.bottomLeft_x), MENU_Y(menuOptionHighlight.bottomLeft_y), SELECTIONBORDER_COLOR);
+ }
+ } else {
+ m_nOptionHighlightTransitionBlend = 255;
+ menuOptionHighlight.Translate(m_nOptionHighlightTransitionBlend);
+ if (m_firstStartCounter == 255 && m_nMenuFadeAlpha == 255 && !bMenuChangeOngoing) {
+ CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(menuOptionHighlight.topLeft_x), MENU_Y(menuOptionHighlight.topLeft_y),
+ MENU_X_LEFT_ALIGNED(menuOptionHighlight.topRight_x), MENU_Y(menuOptionHighlight.topRight_y),
+ MENU_X_LEFT_ALIGNED(menuOptionHighlight.bottomRight_x), MENU_Y(menuOptionHighlight.bottomRight_y),
+ MENU_X_LEFT_ALIGNED(menuOptionHighlight.bottomLeft_x), MENU_Y(menuOptionHighlight.bottomLeft_y), SELECTIONBORDER_COLOR);
}
- if (oldScreen == m_nPrevScreen)
- oldScreen = m_nCurrScreen;
-
- m_nHoverOption = HOVEROPTION_RANDOM_ITEM;
- foundTheHoveringItem = true;
- break;
}
- m_nHoverOption = HOVEROPTION_NOT_HOVERING;
- nextYToCheck += extraOffset + lineHeight;
- }
- }
- // Green bar behind selected option
-#ifdef PS2_SAVE_DIALOG
- if (!m_bRenderGameInMenu)
-#endif
- if (i == m_nCurrOption && itemsAreSelectable) {
-#ifdef PS2_LIKE_MENU
- CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(29.0f), MENU_Y(bitAboveNextItemY),
- MENU_X_RIGHT_ALIGNED(29.0f), MENU_Y(usableLineHeight + nextItemY)),
- CRGBA(SELECTION_HIGHLIGHTBG_COLOR.r, SELECTION_HIGHLIGHTBG_COLOR.g, SELECTION_HIGHLIGHTBG_COLOR.b, FadeIn(SELECTION_HIGHLIGHTBG_COLOR.a)));
+ static uint32 lastBlendChange = 0;
+ if (m_nOptionHighlightTransitionBlend <= 255) {
+ static uint32 blendChangeCounter = 0;
+ if (CTimer::GetTimeInMillisecondsPauseMode() - lastBlendChange > 20
+ || blendChangeCounter > 20
+ ) {
+ m_nOptionHighlightTransitionBlend += 50;
+ lastBlendChange = CTimer::GetTimeInMillisecondsPauseMode();
+ blendChangeCounter = 0;
+ }
+#ifdef FIX_BUGS
+ blendChangeCounter += CTimer::GetLogicalFramesPassed();
#else
- // 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(SELECTION_HIGHLIGHTBG_COLOR.r, SELECTION_HIGHLIGHTBG_COLOR.g, SELECTION_HIGHLIGHTBG_COLOR.b, FadeIn(SELECTION_HIGHLIGHTBG_COLOR.a)));
+ ++blendChangeCounter;
#endif
- }
-
- CFont::SetColor(CRGBA(0, 0, 0, FadeIn(90)));
+ }
+ }
- // Button and it's shadow
- for(int textLayer = 0; textLayer < 2; textLayer++) {
- if (!CFont::Details.centre)
- CFont::SetRightJustifyOff();
+ if (section == 1) {
+ if (leftText) {
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(aScreens[m_nCurrScreen].m_aEntries[i].m_X), MENU_Y(aScreens[m_nCurrScreen].m_aEntries[i].m_Y MINUS_SCROLL_OFFSET), leftText);
+ }
- float itemY = MENU_Y(textLayer + nextItemY);
- float itemX = MENU_X_LEFT_ALIGNED(textLayer + columnWidth);
- CFont::PrintString(itemX, itemY, leftText);
- if (rightText) {
- if (!CFont::Details.centre)
+ if (rightText) {
+ CFont::SetCentreOff();
CFont::SetRightJustifyOn();
-
- if(textLayer == 1)
- if (!strcmp(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName, "FED_RES") && !m_bGameNotLoaded
+ if (aScreens[m_nCurrScreen].m_aEntries[i].m_SaveSlot >= SAVESLOT_1 && aScreens[m_nCurrScreen].m_aEntries[i].m_SaveSlot <= SAVESLOT_8) {
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
+ CFont::SetScale(MENU_X(MEDIUMTEXT_X_SCALE), MENU_Y(MEDIUMTEXT_Y_SCALE));
+ } else {
+ CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING));
+ CFont::SetScale(MENU_X(BIGTEXT_X_SCALE), MENU_Y(BIGTEXT_Y_SCALE));
+ }
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(DEFAULT_SCREEN_WIDTH - RIGHT_ALIGNED_TEXT_RIGHT_MARGIN(xMargin)), MENU_Y(aScreens[m_nCurrScreen].m_aEntries[i].m_Y MINUS_SCROLL_OFFSET), rightText);
+ }
+
+ if (m_nPrefsAudio3DProviderIndex == DMAudio.GetCurrent3DProviderIndex()) {
+ if (!strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEA_3DH") && m_nHelperTextMsgId == 1)
+ ResetHelperText();
+ }
+ if (m_nDisplayVideoMode == m_nPrefsVideoMode) {
+ if (!strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FED_RES") && m_nHelperTextMsgId == 1)
+ ResetHelperText();
+ }
+ if (m_nPrefsAudio3DProviderIndex != DMAudio.GetCurrent3DProviderIndex()) {
+ if (!strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEA_3DH"))
+ SetHelperText(1);
+ }
+ if (m_nDisplayVideoMode != m_nPrefsVideoMode) {
+ if (!strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FED_RES"))
+ SetHelperText(1);
+ }
+ if (m_nPrefsAudio3DProviderIndex != DMAudio.GetCurrent3DProviderIndex()) {
+ if (strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEA_3DH") != 0
#ifdef CUSTOM_FRONTEND_OPTIONS
- || isOptionDisabled
+ && ScreenHasOption(m_nCurrScreen, "FEA_3DH")
+#else
+ && m_nCurrScreen == MENUPAGE_SOUND_SETTINGS
#endif
- )
- CFont::SetColor(CRGBA(DARKMENUOPTION_COLOR.r, DARKMENUOPTION_COLOR.g, DARKMENUOPTION_COLOR.b, FadeIn(255)));
+ && m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) {
- CFont::PrintString(MENU_X_RIGHT_ALIGNED(columnWidth - textLayer), itemY, rightText);
- }
- if (i == m_nCurrOption && itemsAreSelectable){
- CFont::SetColor(CRGBA(SELECTEDMENUOPTION_COLOR.r, SELECTEDMENUOPTION_COLOR.g, SELECTEDMENUOPTION_COLOR.b, FadeIn(255)));
- } else {
- CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255)));
- }
- }
-
- if (m_nPrefsAudio3DProviderIndex == DMAudio.GetCurrent3DProviderIndex()) {
- if(!strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEA_3DH") && m_nHelperTextMsgId == 1)
- ResetHelperText();
- }
- if (m_nDisplayVideoMode == m_nPrefsVideoMode) {
- if (!strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FED_RES") && m_nHelperTextMsgId == 1)
- ResetHelperText();
- }
- if (m_nPrefsAudio3DProviderIndex != DMAudio.GetCurrent3DProviderIndex()) {
- if (!strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEA_3DH"))
- SetHelperText(1);
- }
- if (m_nDisplayVideoMode != m_nPrefsVideoMode) {
- if (!strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FED_RES"))
- SetHelperText(1);
- }
- if (m_nPrefsAudio3DProviderIndex != DMAudio.GetCurrent3DProviderIndex()) {
- if (strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEA_3DH") != 0
- // To make assigning built-in actions to new custom options possible.
+ m_nPrefsAudio3DProviderIndex = DMAudio.GetCurrent3DProviderIndex();
+ SetHelperText(3);
+ }
+ }
+ if (m_nDisplayVideoMode != m_nPrefsVideoMode) {
+ if (strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FED_RES") != 0
#ifdef CUSTOM_FRONTEND_OPTIONS
- && ScreenHasOption(m_nCurrScreen, "FEA_3DH")
+ && ScreenHasOption(m_nCurrScreen, "FED_RES")) {
#else
- && m_nCurrScreen == MENUPAGE_SOUND_SETTINGS
+ && m_nCurrScreen == MENUPAGE_DISPLAY_SETTINGS) {
#endif
- && m_nPrefsAudio3DProviderIndex != -1) {
+ m_nDisplayVideoMode = m_nPrefsVideoMode;
+ SetHelperText(3);
+ }
+ }
- m_nPrefsAudio3DProviderIndex = DMAudio.GetCurrent3DProviderIndex();
- SetHelperText(3);
- }
- }
- if (m_nDisplayVideoMode != m_nPrefsVideoMode) {
- if (strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FED_RES") != 0
- // To make assigning built-in actions to new custom options possible.
#ifdef CUSTOM_FRONTEND_OPTIONS
- && ScreenHasOption(m_nCurrScreen, "FED_RES")
+#define SLIDER_Y(pos) (aScreens[m_nCurrScreen].m_aEntries[i].m_Y - 5.f)
#else
- && m_nCurrScreen == MENUPAGE_DISPLAY_SETTINGS
+#define SLIDER_Y(pos) pos
#endif
- ){
- m_nDisplayVideoMode = m_nPrefsVideoMode;
- SetHelperText(3);
- }
- }
-
- // Sliders
- int lastActiveBarX;
- switch (aScreens[m_nCurrScreen].m_aEntries[i].m_Action) {
- case MENUACTION_BRIGHTNESS:
- ProcessSlider(m_PrefsBrightness / 512.0f, HOVEROPTION_INCREASE_BRIGHTNESS, HOVEROPTION_DECREASE_BRIGHTNESS, MENU_X_LEFT_ALIGNED(170.0f), SCREEN_WIDTH);
- break;
- case MENUACTION_DRAWDIST:
- ProcessSlider((m_PrefsLOD - 0.8f) * 1.0f, HOVEROPTION_INCREASE_DRAWDIST, HOVEROPTION_DECREASE_DRAWDIST, MENU_X_LEFT_ALIGNED(170.0f), SCREEN_WIDTH);
- break;
- case MENUACTION_MUSICVOLUME:
- ProcessSlider(m_PrefsMusicVolume / 128.0f, HOVEROPTION_INCREASE_MUSICVOLUME, HOVEROPTION_DECREASE_MUSICVOLUME, MENU_X_LEFT_ALIGNED(170.0f), SCREEN_WIDTH);
- break;
- case MENUACTION_SFXVOLUME:
- ProcessSlider(m_PrefsSfxVolume / 128.0f, HOVEROPTION_INCREASE_SFXVOLUME, HOVEROPTION_DECREASE_SFXVOLUME, MENU_X_LEFT_ALIGNED(170.0f), SCREEN_WIDTH);
- break;
- case MENUACTION_MOUSESENS:
- ProcessSlider(TheCamera.m_fMouseAccelHorzntl * 200.0f, HOVEROPTION_INCREASE_MOUSESENS, HOVEROPTION_DECREASE_MOUSESENS, MENU_X_LEFT_ALIGNED(200.0f), SCREEN_WIDTH);
- break;
+ // Sliders
+ int lastActiveBarX;
+ switch (aScreens[m_nCurrScreen].m_aEntries[i].m_Action) {
+ case MENUACTION_BRIGHTNESS:
+ ProcessSlider(m_PrefsBrightness / 384.0f, SLIDER_Y(70.0f), HOVEROPTION_INCREASE_BRIGHTNESS, HOVEROPTION_DECREASE_BRIGHTNESS, SCREEN_WIDTH, true);
+ break;
+ case MENUACTION_DRAWDIST:
+ ProcessSlider((m_PrefsLOD - 0.925f) / 0.875f, SLIDER_Y(99.0f), HOVEROPTION_INCREASE_DRAWDIST, HOVEROPTION_DECREASE_DRAWDIST, SCREEN_WIDTH, true);
+ break;
+ case MENUACTION_MUSICVOLUME:
+ if(m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER)
+ ProcessSlider(m_PrefsMusicVolume / 64.0f, SLIDER_Y(70.0f), HOVEROPTION_INCREASE_MUSICVOLUME, HOVEROPTION_DECREASE_MUSICVOLUME, SCREEN_WIDTH, true);
+ break;
+ case MENUACTION_SFXVOLUME:
+ if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER)
+ ProcessSlider(m_PrefsSfxVolume / 64.0f, SLIDER_Y(99.0f), HOVEROPTION_INCREASE_SFXVOLUME, HOVEROPTION_DECREASE_SFXVOLUME, SCREEN_WIDTH, true);
+ break;
+ case MENUACTION_MOUSESENS:
+ ProcessSlider(TheCamera.m_fMouseAccelHorzntl * 200.0f, SLIDER_Y(170.0f), HOVEROPTION_INCREASE_MOUSESENS, HOVEROPTION_DECREASE_MOUSESENS, SCREEN_WIDTH, false);
+ break;
+ case MENUACTION_MP3VOLUMEBOOST:
+ if(m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER && DMAudio.IsMP3RadioChannelAvailable())
+ ProcessSlider(m_PrefsMP3BoostVolume / 64.f, SLIDER_Y(128.0f), HOVEROPTION_INCREASE_MP3BOOST, HOVEROPTION_DECREASE_MP3BOOST, SCREEN_WIDTH, true);
+ break;
#ifdef CUSTOM_FRONTEND_OPTIONS
- case MENUACTION_CFO_SLIDER:
- CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[i];
- ProcessSlider((*(float*)option.m_CFOSlider->value - option.m_CFOSlider->min) / (option.m_CFOSlider->max - option.m_CFOSlider->min), HOVEROPTION_INCREASE_CFO_SLIDER, HOVEROPTION_DECREASE_CFO_SLIDER, MENU_X_LEFT_ALIGNED(170.0f), SCREEN_WIDTH);
- break;
+ case MENUACTION_CFO_SLIDER:
+ CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[i];
+ ProcessSlider((*(float*)option.m_CFOSlider->value - option.m_CFOSlider->min) / (option.m_CFOSlider->max - option.m_CFOSlider->min), SLIDER_Y(0), HOVEROPTION_INCREASE_CFO_SLIDER, HOVEROPTION_DECREASE_CFO_SLIDER, SCREEN_WIDTH, true);
+ break;
#endif
- }
-
- // Needed after the bug fix in Font.cpp
-#ifdef FIX_BUGS
- if (!CFont::Details.centre)
- CFont::SetRightJustifyOff();
+ }
+
+ // Not just unused, but also collides with the bug fix in Font.cpp. Yikes.
+#ifndef FIX_BUGS
+ nextYToUse += MENU_DEFAULT_LINE_HEIGHT * CFont::GetNumberLines(MENU_X_LEFT_ALIGNED(60.0f), MENU_Y(nextYToUse), leftText);
#endif
- // 60.0 is silly
- nextYToUse += lineHeight * CFont::GetNumberLines(MENU_X_LEFT_ALIGNED(60.0f), MENU_Y(nextYToUse), leftText);
-
- // 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);
-
- if (DMAudio.IsMP3RadioChannelAvailable())
- ProcessRadioIcon(m_aMenuSprites[MENUSPRITE_MP3LOGO], MENU_X_LEFT_ALIGNED(540.0f), MENU_Y(nextYToUse), 9, HOVEROPTION_RADIO_9);
-
- nextYToUse += 70.0f;
+ if (aScreens[m_nCurrScreen].m_aEntries[i].m_Action == MENUACTION_RADIO) {
+ nextYToUse += MENURADIO_SELECTOR_HEIGHT + 5.f; // unused
+ }
+ }
}
}
+ section++;
}
-#ifdef CUSTOM_FRONTEND_OPTIONS
- lastSelectedOpt = m_nCurrOption;
-#endif
-
#ifdef SCROLLABLE_PAGES
- #define SCROLLBAR_BOTTOM_Y 125.0f // only for background, scrollbar's itself is calculated
- #define SCROLLBAR_RIGHT_X 36.0f
+ #define SCROLLBAR_BOTTOM_Y 105.0f // only for background, scrollbar's itself is calculated
+ #define SCROLLBAR_RIGHT_X 26.0f
#define SCROLLBAR_WIDTH 9.5f
- #define SCROLLBAR_TOP_Y 64
+ #define SCROLLBAR_TOP_Y 84
- if (SCREEN_HAS_AUTO_SCROLLBAR) {
+ if (activeScreen && SCREEN_HAS_AUTO_SCROLLBAR) {
// Scrollbar background
CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 2), MENU_Y(SCROLLBAR_TOP_Y),
- MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 2 - SCROLLBAR_WIDTH), SCREEN_SCALE_FROM_BOTTOM(SCROLLBAR_BOTTOM_Y)), CRGBA(100, 100, 66, FadeIn(205)));
+ MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 2 - SCROLLBAR_WIDTH), SCREEN_SCALE_FROM_BOTTOM(SCROLLBAR_BOTTOM_Y)), CRGBA(30, 30, 30, FadeIn(150)));
float scrollbarHeight = SCROLLBAR_MAX_HEIGHT / (m_nTotalListRow / (float) MAX_VISIBLE_OPTION);
float scrollbarBottom, scrollbarTop;
- scrollbarBottom = MENU_Y(SCROLLBAR_TOP_Y - 8 + m_nScrollbarTopMargin + scrollbarHeight);
- scrollbarTop = MENU_Y(SCROLLBAR_TOP_Y + m_nScrollbarTopMargin);
+ scrollbarBottom = MENU_Y(SCROLLBAR_TOP_Y - 6 + m_nScrollbarTopMargin + scrollbarHeight);
+ scrollbarTop = MENU_Y(SCROLLBAR_TOP_Y + 2 + m_nScrollbarTopMargin);
// Scrollbar shadow
CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 4), scrollbarTop,
MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 1 - SCROLLBAR_WIDTH), scrollbarBottom + MENU_Y(1.0f)),
@@ -1885,32 +1630,41 @@ CMenuManager::Draw()
#endif
switch (m_nCurrScreen) {
- case MENUPAGE_CONTROLLER_SETTINGS:
- case MENUPAGE_SOUND_SETTINGS:
- case MENUPAGE_DISPLAY_SETTINGS:
- case MENUPAGE_SKIN_SELECT:
- case MENUPAGE_CONTROLLER_PC:
- case MENUPAGE_MOUSE_CONTROLS:
- DisplayHelperText();
- break;
+#ifdef GAMEPAD_MENU
+ case MENUPAGE_CONTROLLER_SETTINGS:
+ PrintController();
+ break;
+#endif
+ case MENUPAGE_STATS:
+ case MENUPAGE_CONTROLLER_PC:
+ case MENUPAGE_SOUND_SETTINGS:
+ case MENUPAGE_DISPLAY_SETTINGS:
+ case MENUPAGE_MOUSE_CONTROLS:
+ DisplayHelperText(nil);
+ break;
+ case MENUPAGE_OPTIONS:
+ if (m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER && aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_LOADRADIO)
+ DisplayHelperText("FEA_NAH");
+ break;
#ifdef CUSTOM_FRONTEND_OPTIONS
- default:
- if (aScreens[m_nCurrScreen].layout) {
- if (aScreens[m_nCurrScreen].layout->showLeftRightHelper) {
- DisplayHelperText();
+ default:
+ if (aScreens[m_nCurrScreen].layout) {
+ if (aScreens[m_nCurrScreen].layout->showLeftRightHelper) {
+ DisplayHelperText(nil);
+ }
}
- }
- break;
+ break;
#endif
}
- 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)));
+ if (m_nCurrScreen == MENUPAGE_DELETING_IN_PROGRESS) {
+ SmallMessageScreen("FEDL_WR");
}
-
+#ifndef XBOX_MESSAGE_SCREEN
+ else if (m_nCurrScreen == MENUPAGE_SAVING_IN_PROGRESS) {
+ SmallMessageScreen("FESZ_WR");
+ }
+#endif
}
int
@@ -1918,19 +1672,21 @@ CMenuManager::GetNumOptionsCntrlConfigScreens(void)
{
int number = 0;
switch (m_nCurrScreen) {
+#ifdef LEGACY_MENU_OPTIONS
case MENUPAGE_CONTROLLER_PC_OLD3:
number = 2;
break;
case MENUPAGE_CONTROLLER_DEBUG:
number = 4;
break;
+#endif
case MENUPAGE_KEYBOARD_CONTROLS:
switch (m_ControlMethod) {
case CONTROL_STANDARD:
- number = 25;
+ number = 27;
break;
case CONTROL_CLASSIC:
- number = 30;
+ number = 32;
break;
}
break;
@@ -1958,12 +1714,11 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8
break;
}
- // MENU_Y(rowHeight * 0.0f + yStart);
for (int optionIdx = 0; optionIdx < numOptions; nextY = MENU_Y(++optionIdx * rowHeight + yStart)) {
int nextX = xStart;
int bindingsForThisOpt = 0;
int contSetOrder = SETORDER_1;
- CFont::SetColor(CRGBA(LIST_OPTION_COLOR.r, LIST_OPTION_COLOR.g, LIST_OPTION_COLOR.b, FadeIn(LIST_OPTION_COLOR.a)));
+ CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255)));
if (column == CONTSETUP_PED_COLUMN) {
switch (optionIdx) {
@@ -2001,10 +1756,10 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8
case 11:
case 12:
case 16:
- case 18:
- case 19:
case 20:
case 21:
+ case 22:
+ case 23:
controllerAction = -1;
break;
case 13:
@@ -2019,34 +1774,40 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8
case 17:
controllerAction = PED_LOCK_TARGET;
break;
- case 22:
+ case 18:
+ controllerAction = PED_DUCK;
+ break;
+ case 19:
+ controllerAction = PED_ANSWER_PHONE;
+ break;
+ case 24:
controllerAction = PED_LOOKBEHIND;
break;
- case 23:
+ case 25:
if (m_ControlMethod == CONTROL_STANDARD)
controllerAction = -1;
else
controllerAction = PED_1RST_PERSON_LOOK_LEFT;
break;
- case 24:
+ case 26:
if (m_ControlMethod == CONTROL_STANDARD)
controllerAction = -1;
else
controllerAction = PED_1RST_PERSON_LOOK_RIGHT;
break;
- case 25:
+ case 27:
controllerAction = PED_1RST_PERSON_LOOK_UP;
break;
- case 26:
+ case 28:
controllerAction = PED_1RST_PERSON_LOOK_DOWN;
break;
- case 27:
+ case 29:
controllerAction = PED_CYCLE_TARGET_LEFT;
break;
- case 28:
+ case 30:
controllerAction = PED_CYCLE_TARGET_RIGHT;
break;
- case 29:
+ case 31:
controllerAction = PED_CENTER_CAMERA_BEHIND_PLAYER;
break;
default:
@@ -2068,11 +1829,13 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8
case 14:
case 15:
case 17:
- case 25:
- case 26:
+ case 18:
+ case 19:
case 27:
case 28:
case 29:
+ case 30:
+ case 31:
controllerAction = -1;
break;
case 3:
@@ -2105,32 +1868,31 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8
case 16:
controllerAction = VEHICLE_HANDBRAKE;
break;
- case 18:
+ case 20:
controllerAction = VEHICLE_TURRETLEFT;
break;
- case 19:
+ case 21:
controllerAction = VEHICLE_TURRETRIGHT;
break;
- case 20:
+ case 22:
controllerAction = VEHICLE_TURRETUP;
break;
- case 21:
+ case 23:
controllerAction = VEHICLE_TURRETDOWN;
break;
- case 22:
+ case 24:
controllerAction = -2;
break;
- case 23:
+ case 25:
controllerAction = VEHICLE_LOOKLEFT;
break;
- case 24:
+ case 26:
controllerAction = VEHICLE_LOOKRIGHT;
break;
default:
break;
}
}
- int bindingWhite = 155;
// Highlight selected column(and make its text black)
if (m_nSelectedListRow == optionIdx) {
@@ -2139,49 +1901,31 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8
if (column == CONTSETUP_PED_COLUMN && m_nSelectedContSetupColumn == CONTSETUP_PED_COLUMN) {
#ifdef FIX_BUGS
- if (controllerAction == -1) {
- CSprite2d::DrawRect(CRect(nextX, MENU_Y(bgY), nextX + MENU_X(CONTSETUP_BOUND_COLUMN_WIDTH),
- MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.r, CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.g, CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.b, FadeIn(CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.a)));
- } else {
- CSprite2d::DrawRect(CRect(nextX, MENU_Y(bgY), nextX + MENU_X(CONTSETUP_BOUND_COLUMN_WIDTH),
- MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(CONTSETUP_HIGHLIGHTBG_COLOR.r, CONTSETUP_HIGHLIGHTBG_COLOR.g, CONTSETUP_HIGHLIGHTBG_COLOR.b, FadeIn(CONTSETUP_HIGHLIGHTBG_COLOR.a)));
- }
+ CSprite2d::DrawRect(CRect(nextX, MENU_Y(bgY), nextX + MENU_X(CONTSETUP_BOUND_COLUMN_WIDTH),
+ MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(SELECTIONBORDER_COLOR.r, SELECTIONBORDER_COLOR.g, SELECTIONBORDER_COLOR.b, FadeIn(255)));
#else
- if (controllerAction == -1) {
- CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(bgY),
- MENU_X_LEFT_ALIGNED(400.0f), MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.r, CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.g, CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.b, FadeIn(CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.a)));
- } else {
- CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(bgY),
- MENU_X_LEFT_ALIGNED(400.0f), MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(CONTSETUP_HIGHLIGHTBG_COLOR.r, CONTSETUP_HIGHLIGHTBG_COLOR.g, CONTSETUP_HIGHLIGHTBG_COLOR.b, FadeIn(CONTSETUP_HIGHLIGHTBG_COLOR.a)));
- }
+ CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(bgY),
+ MENU_X_LEFT_ALIGNED(400.0f), MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)),
+ CRGBA(SELECTIONBORDER_COLOR.r, SELECTIONBORDER_COLOR.g, SELECTIONBORDER_COLOR.b, FadeIn(255)));
#endif
- CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255)));
- bindingWhite = 0;
+ CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255)));
} else if (column == CONTSETUP_VEHICLE_COLUMN && m_nSelectedContSetupColumn == CONTSETUP_VEHICLE_COLUMN) {
#ifdef FIX_BUGS
- if (controllerAction == -1) {
- CSprite2d::DrawRect(CRect(nextX, MENU_Y(bgY), nextX + MENU_X(CONTSETUP_BOUND_COLUMN_WIDTH),
- MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.r, CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.g, CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.b, FadeIn(CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.a)));
- } else {
- CSprite2d::DrawRect(CRect(nextX, MENU_Y(bgY), nextX + MENU_X(CONTSETUP_BOUND_COLUMN_WIDTH),
- MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(CONTSETUP_HIGHLIGHTBG_COLOR.r, CONTSETUP_HIGHLIGHTBG_COLOR.g, CONTSETUP_HIGHLIGHTBG_COLOR.b, FadeIn(CONTSETUP_HIGHLIGHTBG_COLOR.a)));
- }
+ CSprite2d::DrawRect(CRect(nextX, MENU_Y(bgY), nextX + MENU_X(CONTSETUP_BOUND_COLUMN_WIDTH),
+ MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(SELECTIONBORDER_COLOR.r, SELECTIONBORDER_COLOR.g, SELECTIONBORDER_COLOR.b, FadeIn(255)));
#else
- if (controllerAction == -1) {
- CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(410.0f), MENU_Y(bgY), MENU_X_LEFT_ALIGNED(600.0f), MENU_Y(bgY + 10)), CRGBA(CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.r, CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.g, CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.b, FadeIn(CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.a)));
- } else {
- CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(410.0f), MENU_Y(bgY), MENU_X_LEFT_ALIGNED(600.0f), MENU_Y(bgY + 10)), CRGBA(CONTSETUP_HIGHLIGHTBG_COLOR.r, CONTSETUP_HIGHLIGHTBG_COLOR.g, CONTSETUP_HIGHLIGHTBG_COLOR.b, FadeIn(CONTSETUP_HIGHLIGHTBG_COLOR.a)));
- }
+ CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(410.0f), MENU_Y(bgY), MENU_X_LEFT_ALIGNED(600.0f), MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)),
+ CRGBA(SELECTIONBORDER_COLOR.r, SELECTIONBORDER_COLOR.g, SELECTIONBORDER_COLOR.b, FadeIn(255)));
#endif
- CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255)));
- bindingWhite = 0;
+ CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255)));
}
}
}
// Print bindings, including seperator (-) between them
- CFont::SetScale(MENU_X(0.25f), MENU_Y(SMALLESTTEXT_Y_SCALE));
+
+ CFont::SetScale(MENU_X(0.25f), MENU_Y(LISTITEM_Y_SCALE));
#ifdef FIX_BUGS
for (; contSetOrder < MAX_SETORDERS && controllerAction >= 0; contSetOrder++) {
#else
@@ -2192,9 +1936,8 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8
++bindingsForThisOpt;
if (bindingsForThisOpt > 1) {
wchar *seperator = TheText.Get("FEC_IBT");
- CFont::SetColor(CRGBA(20, 20, 20, FadeIn(80)));
+ CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255)));
CFont::PrintString(nextX, nextY, seperator);
- CFont::SetColor(CRGBA(bindingWhite, bindingWhite, bindingWhite, FadeIn(255)));
nextX += CFont::GetStringWidth(seperator, true) + bindingMargin;
}
CFont::PrintString(nextX, nextY, settingText);
@@ -2207,23 +1950,27 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8
}
}
if (controllerAction == -1) {
- CFont::SetColor(CRGBA(20, 20, 20, FadeIn(80)));
+ CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255)));
CFont::PrintString(nextX, nextY, TheText.Get("FEC_NUS")); // not used
+
} else if (controllerAction == -2) {
- CFont::SetColor(CRGBA(20, 20, 20, FadeIn(80)));
+ CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255)));
CFont::PrintString(nextX, nextY, TheText.Get("FEC_CMP")); // combo: l+r
+
} else if (bindingsForThisOpt == 0) {
+ m_NoEmptyBinding = false;
if (m_nSelectedListRow != optionIdx) {
- CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255)));
+ CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255)));
CFont::PrintString(nextX, nextY, TheText.Get("FEC_UNB")); // unbound
+
} else if (m_bWaitingForNewKeyBind) {
if (column != m_nSelectedContSetupColumn) {
- CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255)));
+ CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255)));
CFont::PrintString(nextX, nextY, TheText.Get("FEC_UNB")); // unbound
}
} else {
if (column != m_nSelectedContSetupColumn) {
- CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255)));
+ CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255)));
}
CFont::PrintString(nextX, nextY, TheText.Get("FEC_UNB")); // unbound
}
@@ -2247,34 +1994,26 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8
lastWaitingTextFlash = CTimer::GetTimeInMillisecondsPauseMode();
}
if (showWaitingText) {
- CFont::SetColor(CRGBA(55, 55, 55, FadeIn(255)));
+ CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255)));
CFont::PrintString(nextX, nextY, TheText.Get("FEC_QUE")); // "???"
}
- SET_FONT_FOR_HELPER_TEXT
- CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255)));
- if (m_bKeyChangeNotProcessed) {
- CFont::PrintString(MENU_X_LEFT_ALIGNED(275.0f), SCREEN_SCALE_FROM_BOTTOM(114.0f), TheText.Get("FET_CIG")); // BACKSPACE TO CLEAR - LMB,RETURN TO CHANGE
- } else {
- CFont::PrintString(MENU_X_LEFT_ALIGNED(275.0f), SCREEN_SCALE_FROM_BOTTOM(114.0f), TheText.Get("FET_RIG")); // SELECT A NEW CONTROL FOR THIS ACTION OR ESC TO CANCEL
- }
-
+ if (m_bKeyChangeNotProcessed)
+ DisplayHelperText("FET_CIG");
+ else
+ DisplayHelperText("FET_RIG");
+
SET_FONT_FOR_LIST_ITEM
- if (!m_bKeyIsOK)
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
m_bKeyIsOK = true;
} else {
- SET_FONT_FOR_HELPER_TEXT
- CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255)));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(275.0f), SCREEN_SCALE_FROM_BOTTOM(114.0f), TheText.Get("FET_CIG")); // BACKSPACE TO CLEAR - LMB,RETURN TO CHANGE
+ DisplayHelperText("FET_CIG");
SET_FONT_FOR_LIST_ITEM
+
m_bKeyIsOK = false;
m_bKeyChangeNotProcessed = false;
}
} else if (optionIdx == m_nSelectedListRow) {
- SET_FONT_FOR_HELPER_TEXT
- CFont::SetColor(CRGBA(55, 55, 55, FadeIn(255)));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(275.0f), SCREEN_SCALE_FROM_BOTTOM(114.0f), TheText.Get("FET_EIG")); // CANNOT SET A CONTROL FOR THIS ACTION
+ DisplayHelperText("FET_EIG");
SET_FONT_FOR_LIST_ITEM
}
}
@@ -2322,7 +2061,7 @@ CMenuManager::DrawControllerScreenExtraText(int yStart, int xStart, int lineHeig
if (waitingTextVisible) {
CFont::SetColor(CRGBA(255, 255, 0, FadeIn(255)));
CFont::PrintString(nextX, MENU_Y(yStart), TheText.Get("FEC_QUE"));
- CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255)));
+ CFont::SetColor(CRGBA(LABEL_COLOR.r, LABEL_COLOR.g, LABEL_COLOR.b, FadeIn(255)));
}
}
yStart += lineHeight;
@@ -2352,22 +2091,25 @@ CMenuManager::DrawControllerSetupScreen()
break;
}
RESET_FONT_FOR_NEW_PAGE
-
SET_FONT_FOR_MENU_HEADER
- switch (m_ControlMethod) {
- case CONTROL_STANDARD:
- CFont::PrintString(PAGE_NAME_X(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y),
- TheText.Get(aScreens[m_nCurrScreen].m_ScreenName));
- break;
- case CONTROL_CLASSIC:
- CFont::PrintString(PAGE_NAME_X(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y),
- TheText.Get("FET_CTI"));
- break;
- default:
- break;
- }
- wchar *actionTexts[31];
+ // Shadow
+ CFont::SetColor(CRGBA(30, 30, 30, FadeIn(255)));
+
+ if (m_ControlMethod == CONTROL_STANDARD)
+ CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(MENUHEADER_POS_X) - MENU_X(7.f), SCREEN_SCALE_Y(MENUHEADER_POS_Y + 7.f), TheText.Get("FET_STI"));
+ else if (m_ControlMethod == CONTROL_CLASSIC)
+ CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(MENUHEADER_POS_X) - MENU_X(7.f), SCREEN_SCALE_Y(MENUHEADER_POS_Y + 7.f), TheText.Get("FET_CTI"));
+
+ // Real header
+ CFont::SetColor(CRGBA(HEADER_COLOR.r, HEADER_COLOR.g, HEADER_COLOR.b, FadeIn(255)));
+
+ if (m_ControlMethod == CONTROL_STANDARD)
+ CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_Y(MENUHEADER_POS_Y), TheText.Get("FET_STI"));
+ else if (m_ControlMethod == CONTROL_CLASSIC)
+ CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_Y(MENUHEADER_POS_Y), TheText.Get("FET_CTI"));
+
+ wchar *actionTexts[33];
actionTexts[0] = TheText.Get("FEC_FIR");
actionTexts[1] = TheText.Get("FEC_NWE");
actionTexts[2] = TheText.Get("FEC_PWE");
@@ -2386,32 +2128,34 @@ CMenuManager::DrawControllerSetupScreen()
actionTexts[15] = TheText.Get("FEC_SPN");
actionTexts[16] = TheText.Get("FEC_HND");
actionTexts[17] = TheText.Get("FEC_TAR");
+ actionTexts[18] = TheText.Get("FEC_CRO");
+ actionTexts[19] = TheText.Get("FEC_ANS");
if (m_ControlMethod == CONTROL_CLASSIC) {
- actionTexts[18] = TheText.Get("FEC_TFL");
- actionTexts[19] = TheText.Get("FEC_TFR");
- actionTexts[20] = TheText.Get("FEC_TFU");
- actionTexts[21] = TheText.Get("FEC_TFD");
- actionTexts[22] = TheText.Get("FEC_LBA");
- actionTexts[23] = TheText.Get("FEC_LOL");
- actionTexts[24] = TheText.Get("FEC_LOR");
- actionTexts[25] = TheText.Get("FEC_LUD");
- actionTexts[26] = TheText.Get("FEC_LDU");
- actionTexts[27] = TheText.Get("FEC_NTR");
- actionTexts[28] = TheText.Get("FEC_PTT");
- actionTexts[29] = TheText.Get("FEC_CEN");
- actionTexts[30] = nil;
+ actionTexts[20] = TheText.Get("FEC_TFL");
+ actionTexts[21] = TheText.Get("FEC_TFR");
+ actionTexts[22] = TheText.Get("FEC_TFU");
+ actionTexts[23] = TheText.Get("FEC_TFD");
+ actionTexts[24] = TheText.Get("FEC_LBA");
+ actionTexts[25] = TheText.Get("FEC_LOL");
+ actionTexts[26] = TheText.Get("FEC_LOR");
+ actionTexts[27] = TheText.Get("FEC_LUD");
+ actionTexts[28] = TheText.Get("FEC_LDU");
+ actionTexts[29] = TheText.Get("FEC_NTR");
+ actionTexts[30] = TheText.Get("FEC_PTT");
+ actionTexts[31] = TheText.Get("FEC_CEN");
+ actionTexts[32] = nil;
} else {
- actionTexts[18] = TheText.Get("FEC_TFL");
- actionTexts[19] = TheText.Get("FEC_TFR");
- actionTexts[20] = TheText.Get("FEC_TFU");
- actionTexts[21] = TheText.Get("FEC_TFD");
- actionTexts[22] = TheText.Get("FEC_LBA");
- actionTexts[23] = TheText.Get("FEC_LOL");
- actionTexts[24] = TheText.Get("FEC_LOR");
- actionTexts[25] = nil;
+ actionTexts[20] = TheText.Get("FEC_TFL");
+ actionTexts[21] = TheText.Get("FEC_TFR");
+ actionTexts[22] = TheText.Get("FEC_TFU");
+ actionTexts[23] = TheText.Get("FEC_TFD");
+ actionTexts[24] = TheText.Get("FEC_LBA");
+ actionTexts[25] = TheText.Get("FEC_LOL");
+ actionTexts[26] = TheText.Get("FEC_LOR");
+ actionTexts[27] = nil;
}
- // Gray panel background
+ // Blue panel background
CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(CONTSETUP_LIST_LEFT), MENU_Y(CONTSETUP_LIST_TOP),
MENU_X_RIGHT_ALIGNED(CONTSETUP_LIST_RIGHT), SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_LIST_BOTTOM)),
CRGBA(LIST_BACKGROUND_COLOR.r, LIST_BACKGROUND_COLOR.g, LIST_BACKGROUND_COLOR.b, FadeIn(LIST_BACKGROUND_COLOR.a)));
@@ -2425,16 +2169,18 @@ CMenuManager::DrawControllerSetupScreen()
CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING));
CFont::SetScale(MENU_X(MENUACTION_SCALE_MULT), MENU_Y(MENUACTION_SCALE_MULT));
CFont::SetRightJustifyOff();
- CFont::PrintString(MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_1_X), MENU_Y(CONTSETUP_LIST_TOP), TheText.Get("FET_CAC"));
+ CFont::SetDropShadowPosition(2);
+ CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255)));
CFont::PrintString(MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_2_X), MENU_Y(CONTSETUP_LIST_TOP), TheText.Get("FET_CFT"));
CFont::PrintString(MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_3_X), MENU_Y(CONTSETUP_LIST_TOP), TheText.Get("FET_CCR"));
+ CFont::SetDropShadowPosition(0);
SET_FONT_FOR_LIST_ITEM
-
+
int yStart;
if (m_ControlMethod == CONTROL_CLASSIC)
- yStart = CONTSETUP_LIST_TOP + CONTSETUP_LIST_HEADER_HEIGHT + 1;
+ yStart = CONTSETUP_LIST_TOP + 18;
else
- yStart = CONTSETUP_LIST_TOP + CONTSETUP_LIST_HEADER_HEIGHT + 5;
+ yStart = CONTSETUP_LIST_TOP + 21;
float optionYBottom = yStart + rowHeight;
for (int i = 0; i < ARRAY_SIZE(actionTexts); ++i) {
@@ -2442,49 +2188,42 @@ CMenuManager::DrawControllerSetupScreen()
if (!actionText)
break;
- if (m_nMousePosX > MENU_X_LEFT_ALIGNED(CONTSETUP_LIST_LEFT + 2.0f) &&
- m_nMousePosX < MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_3_X + CONTSETUP_BOUND_COLUMN_WIDTH)) {
-
- if (m_nMousePosY > MENU_Y(i * rowHeight + yStart) && m_nMousePosY < MENU_Y(i * rowHeight + optionYBottom)) {
- if (m_nOptionMouseHovering != i && m_nCurrExLayer == HOVEROPTION_LIST)
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0);
+ if (!m_bWaitingForNewKeyBind) {
+ if (m_nMousePosX > MENU_X_LEFT_ALIGNED(CONTSETUP_LIST_LEFT - 10.0f) &&
+ m_nMousePosX < MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_3_X + CONTSETUP_BOUND_COLUMN_WIDTH)) {
- m_nOptionMouseHovering = i;
- if (m_nMouseOldPosX != m_nMousePosX || m_nMouseOldPosY != m_nMousePosY) {
- m_nCurrExLayer = HOVEROPTION_LIST;
- m_nSelectedListRow = i;
+ if (m_nMousePosY > MENU_Y(i * rowHeight + yStart) && m_nMousePosY < MENU_Y(i * rowHeight + optionYBottom)) {
+ m_nOptionMouseHovering = i;
+ if (m_nMouseOldPosX != m_nMousePosX || m_nMouseOldPosY != m_nMousePosY) {
+ m_nCurrExLayer = HOVEROPTION_LIST;
+ m_nSelectedListRow = i;
- // why different number for 3rd column hovering X?? this function is a mess
+ // why different number for 3rd column hovering X?? this function is a mess
#ifdef FIX_BUGS
- if (m_nMousePosX > MENU_X_LEFT_ALIGNED(0.0f) && m_nMousePosX < MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_2_X + CONTSETUP_BOUND_COLUMN_WIDTH)) {
+ if (m_nMousePosX > MENU_X_LEFT_ALIGNED(0.0f) && m_nMousePosX < MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_2_X + CONTSETUP_BOUND_COLUMN_WIDTH)) {
#else
- if (m_nMousePosX > MENU_X_LEFT_ALIGNED(0.0f) && m_nMousePosX < MENU_X_LEFT_ALIGNED(370.0f)) {
+ if (m_nMousePosX > MENU_X_LEFT_ALIGNED(0.0f) && m_nMousePosX < MENU_X_LEFT_ALIGNED(370.0f)) {
#endif
- if (m_nSelectedContSetupColumn != CONTSETUP_PED_COLUMN && m_nCurrExLayer == HOVEROPTION_LIST)
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0);
-
- m_nSelectedContSetupColumn = CONTSETUP_PED_COLUMN;
+ m_nSelectedContSetupColumn = CONTSETUP_PED_COLUMN;
#ifdef FIX_BUGS
- } else if (m_nMousePosX > MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_2_X + CONTSETUP_BOUND_COLUMN_WIDTH) && m_nMousePosX < SCREEN_WIDTH) {
+ } else if (m_nMousePosX > MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_2_X + CONTSETUP_BOUND_COLUMN_WIDTH) && m_nMousePosX < SCREEN_WIDTH) {
#else
- } else if (m_nMousePosX > MENU_X_LEFT_ALIGNED(370.0f) && m_nMousePosX < SCREEN_WIDTH) {
+ } else if (m_nMousePosX > MENU_X_LEFT_ALIGNED(370.0f) && m_nMousePosX < SCREEN_WIDTH) {
#endif
- if (m_nSelectedContSetupColumn != CONTSETUP_VEHICLE_COLUMN && m_nCurrExLayer == HOVEROPTION_LIST)
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0);
-
- m_nSelectedContSetupColumn = CONTSETUP_VEHICLE_COLUMN;
+ m_nSelectedContSetupColumn = CONTSETUP_VEHICLE_COLUMN;
+ }
}
- }
- // what??
- if (m_nHoverOption == HOVEROPTION_SKIN) {
- if (i == m_nSelectedListRow) {
+ // what??
+ if (m_nHoverOption == HOVEROPTION_SKIN) {
+ if (i == m_nSelectedListRow) {
+ m_nHoverOption = HOVEROPTION_NOT_HOVERING;
+ m_bWaitingForNewKeyBind = true;
+ m_bStartWaitingForKeyBind = true;
+ pControlEdit = &m_KeyPressedCode;
+ }
+ } else
m_nHoverOption = HOVEROPTION_NOT_HOVERING;
- m_bWaitingForNewKeyBind = true;
- m_bStartWaitingForKeyBind = true;
- pControlEdit = &m_KeyPressedCode;
- }
- } else
- m_nHoverOption = HOVEROPTION_NOT_HOVERING;
+ }
}
}
if (m_nSelectedListRow != i)
@@ -2493,578 +2232,318 @@ CMenuManager::DrawControllerSetupScreen()
CFont::SetColor(CRGBA(SELECTEDMENUOPTION_COLOR.r, SELECTEDMENUOPTION_COLOR.g, SELECTEDMENUOPTION_COLOR.b, FadeIn(255)));
CFont::SetRightJustifyOff();
- if (m_PrefsLanguage == LANGUAGE_GERMAN && (i == 20 || i == 21))
- CFont::SetScale(MENU_X(0.32f), MENU_Y(SMALLESTTEXT_Y_SCALE));
+ if (m_PrefsLanguage == LANGUAGE_GERMAN && (i == 20 || i == 21 || i == 22 || i == 23))
+ CFont::SetScale(MENU_X(0.32f), MENU_Y(LISTITEM_Y_SCALE));
else
- CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE));
+ CFont::SetScale(MENU_X(LISTITEM_X_SCALE), MENU_Y(LISTITEM_Y_SCALE));
CFont::PrintString(MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_1_X), MENU_Y(i * rowHeight + yStart), actionText);
}
DrawControllerBound(yStart, MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_2_X), rowHeight, CONTSETUP_PED_COLUMN);
DrawControllerBound(yStart, MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_3_X), rowHeight, CONTSETUP_VEHICLE_COLUMN);
- CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X), MENU_Y(MENU_TEXT_SIZE_Y));
- if ((m_nMousePosX > MENU_X_RIGHT_ALIGNED(CONTSETUP_BACK_RIGHT) - CFont::GetStringWidth(TheText.Get("FEDS_TB"), true)
- && m_nMousePosX < MENU_X_RIGHT_ALIGNED(CONTSETUP_BACK_RIGHT) && m_nMousePosY > SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_BACK_BOTTOM)
- && m_nMousePosY < SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_BACK_BOTTOM - CONTSETUP_BACK_HEIGHT)) || m_nCurrExLayer == HOVEROPTION_BACK) {
- m_nHoverOption = HOVEROPTION_BACK;
+ if (!m_bWaitingForNewKeyBind) {
+ CFont::SetScale(MENU_X(BIGTEXT_X_SCALE), MENU_Y(BIGTEXT_Y_SCALE));
+
+ if ((m_nMousePosX > MENU_X_RIGHT_ALIGNED(CONTSETUP_BACK_RIGHT) - CFont::GetStringWidth(TheText.Get("FEDS_TB"), true)
+ && m_nMousePosX < MENU_X_RIGHT_ALIGNED(CONTSETUP_BACK_RIGHT) && m_nMousePosY > SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_BACK_BOTTOM)
+ && m_nMousePosY < SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_BACK_BOTTOM - CONTSETUP_BACK_HEIGHT)) || m_nCurrExLayer == HOVEROPTION_BACK) {
+ m_nHoverOption = HOVEROPTION_BACK;
- } else if (m_nMousePosX > MENU_X_LEFT_ALIGNED(CONTSETUP_LIST_LEFT + 2.0f) && m_nMousePosX < MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_3_X + CONTSETUP_BOUND_COLUMN_WIDTH)
- && m_nMousePosY > MENU_Y(CONTSETUP_LIST_TOP + CONTSETUP_LIST_HEADER_HEIGHT) && m_nMousePosY < SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_LIST_BOTTOM + 5.0f)) {
- m_nHoverOption = HOVEROPTION_LIST;
+ } else if (m_nMousePosX > MENU_X_LEFT_ALIGNED(CONTSETUP_LIST_LEFT - 10.0f) && m_nMousePosX < MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_3_X + CONTSETUP_BOUND_COLUMN_WIDTH)
+ && m_nMousePosY > MENU_Y(CONTSETUP_LIST_TOP - 10.0f) && m_nMousePosY < SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_LIST_BOTTOM)) {
+ m_nHoverOption = HOVEROPTION_LIST;
- } else {
- m_nHoverOption = HOVEROPTION_NOT_HOVERING;
+ } else {
+ m_nHoverOption = HOVEROPTION_NOT_HOVERING;
+ }
}
// Back button and it's shadow
CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING));
- CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X), MENU_Y(MENU_TEXT_SIZE_Y));
+ CFont::SetScale(MENU_X(BIGTEXT_X_SCALE), MENU_Y(BIGTEXT_Y_SCALE));
CFont::SetRightJustifyOn();
- CFont::SetColor(CRGBA(0, 0, 0, FadeIn(90)));
- for (int i = 0; i < 2; i++) {
- CFont::PrintString(MENU_X_RIGHT_ALIGNED(CONTSETUP_BACK_RIGHT - 2.0f - i),
- SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_BACK_BOTTOM - 4.0f - i), TheText.Get("FEDS_TB"));
-
- if (m_nHoverOption == HOVEROPTION_BACK)
- CFont::SetColor(CRGBA(SELECTEDMENUOPTION_COLOR.r, SELECTEDMENUOPTION_COLOR.g, SELECTEDMENUOPTION_COLOR.b, FadeIn(255)));
- else
- CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255)));
- }
+ CFont::SetDropShadowPosition(2);
+ CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255)));
+ CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255)));
+ CFont::PrintString(MENU_X_RIGHT_ALIGNED(CONTSETUP_BACK_RIGHT - 2.0f), SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_BACK_BOTTOM - 4.0f), TheText.Get("FEDS_TB"));
}
void
CMenuManager::DrawFrontEnd()
{
CFont::SetAlphaFade(255.0f);
+ CSprite2d::InitPerFrame();
+ CFont::InitPerFrame();
+ SetFrontEndRenderStates();
+ m_NoEmptyBinding = true;
-#ifdef PS2_LIKE_MENU
- #define setBbItem(a, b, c) strcpy(a.name, b); a.screenId = c;
- if (m_nCurrScreen == MENUPAGE_NONE) {
- if (m_bGameNotLoaded) {
- if (bbTabCount != 6) {
- setBbItem(bbNames[0], "FEB_SAV",MENUPAGE_NEW_GAME)
- setBbItem(bbNames[1], "FEB_CON",MENUPAGE_CONTROLLER_PC)
- setBbItem(bbNames[2], "FEB_AUD",MENUPAGE_SOUND_SETTINGS)
- setBbItem(bbNames[3], "FEB_DIS",MENUPAGE_DISPLAY_SETTINGS)
- setBbItem(bbNames[4], "FEB_LAN",MENUPAGE_LANGUAGE_SETTINGS)
- setBbItem(bbNames[5], "FESZ_QU",MENUPAGE_EXIT)
- bbTabCount = 6;
- }
- } else {
- if (bbTabCount != 8) {
- setBbItem(bbNames[0], "FEB_STA",MENUPAGE_STATS)
- setBbItem(bbNames[1], "FEB_SAV",MENUPAGE_NEW_GAME)
- setBbItem(bbNames[2], "FEB_BRI",MENUPAGE_BRIEFS)
- setBbItem(bbNames[3], "FEB_CON",MENUPAGE_CONTROLLER_PC)
- setBbItem(bbNames[4], "FEB_AUD",MENUPAGE_SOUND_SETTINGS)
- setBbItem(bbNames[5], "FEB_DIS",MENUPAGE_DISPLAY_SETTINGS)
- setBbItem(bbNames[6], "FEB_LAN",MENUPAGE_LANGUAGE_SETTINGS)
- setBbItem(bbNames[7], "FESZ_QU",MENUPAGE_EXIT)
- bbTabCount = 8;
- }
- }
- m_nCurrScreen = bbNames[0].screenId;
- bottomBarActive = true;
- curBottomBarOption = 0;
- }
- #undef setBbItem
-#else
if (m_nCurrScreen == MENUPAGE_NONE) {
if (m_bGameNotLoaded) {
m_nCurrScreen = MENUPAGE_START_MENU;
} else {
m_nCurrScreen = MENUPAGE_PAUSE_MENU;
}
+ SETUP_SCROLLING(m_nCurrScreen)
}
-#endif
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_firstStartCounter == 255 && m_nMenuFadeAlpha == 255)
+ bMenuChangeOngoing = false;
- PrintErrorMessage();
+ DrawBackground(false);
}
-#ifdef PS2_SAVE_DIALOG
void
-CMenuManager::DrawFrontEndSaveZone()
+CMenuManager::DrawBackground(bool transitionCall)
{
- 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
+ if (!m_bSpritesLoaded)
+ return;
-#ifdef PS2_LIKE_MENU
-void
-CMenuManager::DrawFrontEndNormal()
-{
- CSprite2d::InitPerFrame();
- CFont::InitPerFrame();
- RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR);
+ SetFrontEndRenderStates();
- if (!m_bGameNotLoaded) {
- CSprite2d *bg = LoadSplash(nil);
- bg->Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(48, 48, 48, 255));
- } else {
+ if (m_firstStartCounter < 255) {
CSprite2d::DrawRect(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(0, 0, 0, 255));
}
- RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERNEAREST);
- RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
- RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
- RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
- m_aFrontEndSprites[FE2_MAINPANEL_UL].Draw(CRect(MENU_X_LEFT_ALIGNED(0.0f), 0.0f, SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2), CRGBA(255, 255, 255, 255));
- m_aFrontEndSprites[FE2_MAINPANEL_UR].Draw(CRect(SCREEN_WIDTH / 2, 0.0f, MENU_X_RIGHT_ALIGNED(0.0f), SCREEN_HEIGHT / 2), CRGBA(255, 255, 255, 255));
- m_aFrontEndSprites[FE2_MAINPANEL_DL].Draw(CRect(MENU_X_LEFT_ALIGNED(0.0f), SCREEN_HEIGHT / 2, SCREEN_WIDTH / 2, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255));
- m_aFrontEndSprites[FE2_MAINPANEL_DR].Draw(CRect(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, MENU_X_RIGHT_ALIGNED(0.0f), SCREEN_HEIGHT), CRGBA(255, 255, 255, 255));
-
- RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR);
- eFrontendSprites currentSprite;
- switch (m_nCurrScreen) {
- case MENUPAGE_STATS:
- case MENUPAGE_START_MENU:
- case MENUPAGE_PAUSE_MENU:
- case MENUPAGE_EXIT:
- currentSprite = FE_ICONSTATS;
- break;
- case MENUPAGE_LANGUAGE_SETTINGS:
- currentSprite = FE_ICONLANGUAGE;
- break;
- 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:
- currentSprite = FE_ICONSAVE;
- break;
- case MENUPAGE_DISPLAY_SETTINGS:
- currentSprite = FE_ICONDISPLAY;
- break;
- case MENUPAGE_SOUND_SETTINGS:
- currentSprite = FE_ICONAUDIO;
- break;
- case MENUPAGE_CONTROLLER_PC:
- case MENUPAGE_OPTIONS:
- case MENUPAGE_CONTROLLER_SETTINGS:
- case MENUPAGE_KEYBOARD_CONTROLS:
- case MENUPAGE_MOUSE_CONTROLS:
- currentSprite = FE_ICONCONTROLS;
- break;
- default:
- /*case MENUPAGE_NEW_GAME: */
- /*case MENUPAGE_BRIEFS: */
- currentSprite = FE_ICONBRIEF;
- break;
- }
-
- static float fadeAlpha = 0.0f;
-
- if (m_nMenuFadeAlpha < 255) {
- m_nMenuFadeAlpha += 20 * CTimer::GetLogicalFramesPassed();
- } else {
- // 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)
-
- field_518 = 2;
- else
- field_518 = 1;
- }
- }
-
- m_aFrontEndSprites[currentSprite].Draw(CRect(MENU_X_LEFT_ALIGNED(50.0f), MENU_Y(50.0f), MENU_X_RIGHT_ALIGNED(50.0f), SCREEN_SCALE_FROM_BOTTOM(95.0f)), CRGBA(255, 255, 255, m_nMenuFadeAlpha > 255 ? 255 : m_nMenuFadeAlpha));
-
- RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERNEAREST);
- RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP);
- RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
- switch (m_nCurrScreen) {
- case MENUPAGE_SKIN_SELECT:
- DrawPlayerSetupScreen();
- break;
- case MENUPAGE_KEYBOARD_CONTROLS:
- DrawControllerSetupScreen();
- break;
- default:
- Draw();
- break;
- }
-
- // Positions/style from PS2 menu, credits to Fire_Head
- /* Draw controller buttons */
- CFont::SetFontStyle(FONT_BANK);
- CFont::SetBackgroundOff();
- CFont::SetScale(SCREEN_SCALE_X(0.35f), SCREEN_SCALE_Y(0.64f));
- CFont::SetPropOn();
- CFont::SetCentreOff();
- CFont::SetJustifyOn();
- CFont::SetRightJustifyOff();
- CFont::SetBackGroundOnlyTextOn();
- CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN)); // 600.0f
- CFont::SetColor(CRGBA(16, 16, 16, 255));
- switch (m_nCurrScreen) {
-
- // Page names overlaps buttons on those.
- case MENUPAGE_MOUSE_CONTROLS:
- case MENUPAGE_KEYBOARD_CONTROLS:
- break;
-
- default:
- {
- CFont::PrintString(MENU_X_LEFT_ALIGNED(52.0f), MENU_Y(360.0f), TheText.Get("FEDS_SE"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(52.0f), MENU_Y(372.0f), TheText.Get("FEDS_BA"));
- if (!m_bGameNotLoaded)
- CFont::PrintString(MENU_X_LEFT_ALIGNED(52.0f), MENU_Y(384.0f), TheText.Get("FEDS_ST"));
-
- if (bottomBarActive)
- CFont::PrintString(MENU_X_LEFT_ALIGNED(242.0f), MENU_Y(372.0f), TheText.Get("FEDS_AM")); // <>-CHANGE MENU
- else if (m_nCurrScreen != MENUPAGE_STATS && m_nCurrScreen != MENUPAGE_BRIEFS) {
- CFont::PrintString(MENU_X_LEFT_ALIGNED(242.0f), MENU_Y(360.0f + 3.5f), TheText.Get("FEA_UP")); // ;
- CFont::PrintString(MENU_X_LEFT_ALIGNED(242.0f), MENU_Y(384.0f - 3.5f), TheText.Get("FEA_DO")); // =
- CFont::PrintString(MENU_X_LEFT_ALIGNED(242.0f - 10.0f), MENU_Y(372.0f), TheText.Get("FEA_LE")); // <
- CFont::PrintString(MENU_X_LEFT_ALIGNED(242.0f + 11.0f), MENU_Y(372.0f), TheText.Get("FEA_RI")); // >
- CFont::PrintString(MENU_X_LEFT_ALIGNED(242.0f + 20.0f), MENU_Y(372.0f), TheText.Get("FEDSAS3")); // - CHANGE SELECTION
- }
-
- break;
- }
- }
-
- #define optionWidth MENU_X(66.0f)
- #define rawOptionHeight 22.0f
- #define optionBottom SCREEN_SCALE_FROM_BOTTOM(20.0f)
- #define optionTop SCREEN_SCALE_FROM_BOTTOM(20.0f + rawOptionHeight)
- #define leftPadding MENU_X_LEFT_ALIGNED(90.0f)
- wchar *str;
- hoveredBottomBarOption = -1;
- if (curBottomBarOption != -1) {
+ if (m_nMenuFadeAlpha != 0) {
- // This active tab sprite is needlessly big
- m_aFrontEndSprites[FE2_TABACTIVE].Draw(CRect(leftPadding - MENU_X(2.0f) + (optionWidth) * curBottomBarOption, optionTop,
- leftPadding - MENU_X(5.0f) + optionWidth * (curBottomBarOption + 2), optionBottom + MENU_Y(rawOptionHeight - 9.0f)),
- CRGBA(CRGBA(255, 255, 255, 255)));
+ if (m_nMenuFadeAlpha < 255) {
- for (int i = 0; i < bbTabCount; i++) {
- float xStart = leftPadding + optionWidth * i;
- if (CheckHover(xStart, xStart + optionWidth, optionTop, optionBottom))
- hoveredBottomBarOption = i;
+ 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();
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
- CFont::SetScale(MENU_X(0.35f), MENU_Y(0.7f));
- CFont::SetRightJustifyOff();
- if (hoveredBottomBarOption == i && hoveredBottomBarOption != curBottomBarOption)
- CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, 255));
- else {
- if(bottomBarActive || curBottomBarOption == i)
- CFont::SetColor(CRGBA(HEADER_COLOR.r, HEADER_COLOR.g, HEADER_COLOR.b, 255));
- else
- CFont::SetColor(CRGBA(HEADER_COLOR.r, HEADER_COLOR.g, HEADER_COLOR.b, 110));
- }
+ // 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));
- str = TheText.Get(bbNames[i].name);
-
- CFont::PrintString(xStart + MENU_X(4.0f), SCREEN_SCALE_FROM_BOTTOM(39.0f), str);
-
- }
- }
- #undef optionBottom
- #undef optionTop
- #undef leftPadding
- #undef optionWidth
- #undef rawOptionHeight
-
- 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);
+ // 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));
- 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));
+ // 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));
- 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));
+ // 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_nMenuFadeAlpha = 255;
+ m_firstStartCounter = 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
-void
-CMenuManager::DrawFrontEndNormal()
-{
- CSprite2d::InitPerFrame();
- CFont::InitPerFrame();
- RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR);
-
- LoadSplash(nil);
-
- eMenuSprites previousSprite;
- if (m_nMenuFadeAlpha < 255) {
- switch (m_nPrevScreen) {
+ } else {
+ menuBg.SaveCurrentCoors();
+ switch (m_nCurrScreen) {
case MENUPAGE_STATS:
- case MENUPAGE_START_MENU:
- case MENUPAGE_PAUSE_MENU:
- previousSprite = MENUSPRITE_MAINMENU;
+ 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_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;
+ 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_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;
+ 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_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;
+ case MENUPAGE_BRIEFS:
+ case MENUPAGE_DISPLAY_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:
#ifdef CUSTOM_FRONTEND_OPTIONS
- CCustomScreenLayout *custom = aScreens[m_nPrevScreen].layout;
- if (custom) {
- previousSprite = custom->sprite;
+ if (aScreens[m_nCurrScreen].layout && aScreens[m_nCurrScreen].layout->noInvasiveBorders) {
+ // Taken from the case above
+ 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;
}
- if (!custom)
#endif
- previousSprite = MENUSPRITE_MAINMENU;
+ 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;
}
-
- 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));
- }
- RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
- RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
-
- 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;
-#ifdef CUSTOM_FRONTEND_OPTIONS
- default:
- CCustomScreenLayout *custom = aScreens[m_nCurrScreen].layout;
- if (custom) {
- previousSprite = custom->sprite;
- }
- break;
-#endif
+ menuBg.UpdateMultipliers();
+ if (m_firstStartCounter == 255)
+ m_nOptionHighlightTransitionBlend = 0;
}
- if (m_nMenuFadeAlpha < 255) {
-
- // Famous transparent menu bug
-#ifdef FIX_BUGS
- m_nMenuFadeAlpha += 20 * CTimer::GetLogicalFramesPassed();
-#else
- static uint32 LastFade = 0;
+ static uint32 LastFade = 0;
- if(CTimer::GetTimeInMillisecondsPauseMode() - LastFade > 10){
+ if (m_nMenuFadeAlpha < 255) {
+ static uint8 forceFadeInCounter = 0;
+ if (CTimer::GetTimeInMillisecondsPauseMode() - LastFade > 30
+ || forceFadeInCounter > 30
+ ) {
m_nMenuFadeAlpha += 20;
+ if (m_firstStartCounter < 255) {
+ m_firstStartCounter = Min(m_firstStartCounter + 20, 255);
+ }
LastFade = CTimer::GetTimeInMillisecondsPauseMode();
- }
+#ifdef FIX_BUGS
+ forceFadeInCounter = 0;
#endif
-
- if (m_nMenuFadeAlpha > 255){
- m_aMenuSprites[currentSprite].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 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));
}
- } 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)
-
- field_518 = 2;
- else
- field_518 = 1;
- }
- }
-
-#ifdef RED_DELETE_BACKGROUND
- if (m_nCurrScreen == MENUPAGE_CHOOSE_DELETE_SLOT || m_nCurrScreen == MENUPAGE_DELETE_SLOT_CONFIRM) {
- CSprite2d::Draw2DPolygon(0.0f, 0.0f,
- SCREEN_WIDTH, 0.0f,
- 0.0f, SCREEN_HEIGHT,
- SCREEN_WIDTH, SCREEN_HEIGHT,
- CRGBA(150, 0, 0, 80));
- }
+#ifdef FIX_BUGS
+ forceFadeInCounter += CTimer::GetLogicalFramesPassed();
+#else
+ forceFadeInCounter++;
#endif
+ } else if (m_nMenuFadeAlpha > 255)
+ m_nMenuFadeAlpha = 255;
- // 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)));
+ if (!transitionCall && m_firstStartCounter == 255) {
+ int actualAlpha = m_nMenuFadeAlpha;
+ if (actualAlpha < 255) {
+ int actualScreen = m_nCurrScreen;
+ SetFrontEndRenderStates();
+ m_nCurrScreen = m_nPrevScreen;
+ m_nMenuFadeAlpha = 255 - m_nMenuFadeAlpha;
+ switch (m_nCurrScreen) {
+ case MENUPAGE_SKIN_SELECT:
+ DrawPlayerSetupScreen(false);
+ break;
+ case MENUPAGE_KEYBOARD_CONTROLS:
+ DrawControllerSetupScreen();
+ break;
+ case MENUPAGE_OUTRO:
+ DrawQuitGameScreen();
+ break;
+ default:
+ DrawStandardMenus(false);
+ break;
+ }
+ m_nCurrScreen = actualScreen;
+ m_nMenuFadeAlpha = actualAlpha;
+ }
}
- RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERNEAREST);
- RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP);
- RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
switch (m_nCurrScreen) {
case MENUPAGE_SKIN_SELECT:
- DrawPlayerSetupScreen();
+ DrawPlayerSetupScreen(true);
break;
case MENUPAGE_KEYBOARD_CONTROLS:
DrawControllerSetupScreen();
break;
+ case MENUPAGE_OUTRO:
+ DrawQuitGameScreen();
+ break;
default:
- Draw();
+ DrawStandardMenus(true);
break;
}
CFont::DrawFonts();
+ SetFrontEndRenderStates();
- // 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);
+ if (m_nCurrScreen != MENUPAGE_OUTRO)
+ if (m_firstStartCounter == 255) {
+ m_aFrontEndSprites[MENUSPRITE_VCLOGO].Draw(CRect(SCREEN_STRETCH_X(27.0f), MENU_Y(8.0f), SCREEN_STRETCH_X(27.0f) + MENU_X(130.f), MENU_Y(138.0f)), CRGBA(255, 255, 255, 255));
+ } else {
+ m_aFrontEndSprites[MENUSPRITE_VCLOGO].Draw(CRect(SCREEN_STRETCH_X(27.0f), MENU_Y(8.0f), SCREEN_STRETCH_X(27.0f) + MENU_X(130.f), MENU_Y(138.0f)), CRGBA(255, 255, 255, FadeIn(255)));
+ }
+
+ if (m_ShowEmptyBindingError) {
+ static uint32 lastBindingError = CTimer::GetTimeInMillisecondsPauseMode();
+ static bool bindingErrorShown = false;
+ if (bindingErrorShown) {
+ lastBindingError = CTimer::GetTimeInMillisecondsPauseMode();
+ bindingErrorShown = false;
+ }
+ SmallMessageScreen("FEC_ERI");
+ CFont::DrawFonts();
+ if (CTimer::GetTimeInMillisecondsPauseMode() - lastBindingError > 4000) {
+ m_ShowEmptyBindingError = false;
+ bindingErrorShown = 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));
+ if (m_bShowMouse) {
+ CRect mouse(0.0f, 0.0f, MENU_X(35.0f), MENU_Y(35.0f));
+ CRect shad(MENU_X(10.0f), MENU_Y(3.0f), MENU_X(45.0f), MENU_Y(38.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
void
-CMenuManager::DrawPlayerSetupScreen()
+CMenuManager::DrawPlayerSetupScreen(bool activeScreen)
{
RESET_FONT_FOR_NEW_PAGE
- SET_FONT_FOR_MENU_HEADER
-
- CFont::PrintString(PAGE_NAME_X(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y), TheText.Get("FET_PS"));
-
// lstrcpy's changed with strcpy
-
if (!m_bSkinsEnumerated) {
OutputDebugString("Enumerating skin filenames from skins...");
m_pSkinListHead.nextSkin = nil;
@@ -3147,8 +2626,14 @@ CMenuManager::DrawPlayerSetupScreen()
m_bSkinsEnumerated = true;
}
CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(PLAYERSETUP_LIST_LEFT), MENU_Y(PLAYERSETUP_LIST_TOP),
- MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM)),
- CRGBA(LIST_BACKGROUND_COLOR.r, LIST_BACKGROUND_COLOR.g, LIST_BACKGROUND_COLOR.b, FadeIn(LIST_BACKGROUND_COLOR.a)));
+ MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM)), CRGBA(LIST_BACKGROUND_COLOR.r, LIST_BACKGROUND_COLOR.g, LIST_BACKGROUND_COLOR.b, FadeIn(LIST_BACKGROUND_COLOR.a)));
+
+ SET_FONT_FOR_MENU_HEADER
+ CFont::SetColor(CRGBA(30, 30, 30, FadeIn(255)));
+ CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(MENUHEADER_POS_X) - MENU_X(7.f), SCREEN_SCALE_Y(MENUHEADER_POS_Y + 7.f), TheText.Get("FET_PS"));
+
+ CFont::SetColor(CRGBA(HEADER_COLOR.r, HEADER_COLOR.g, HEADER_COLOR.b, FadeIn(255)));
+ CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_Y(MENUHEADER_POS_Y), TheText.Get("FET_PS"));
// Header (Skin - Date)
if (m_nCurrExLayer == HOVEROPTION_LIST) {
@@ -3156,7 +2641,8 @@ CMenuManager::DrawPlayerSetupScreen()
} else {
CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255)));
}
- CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING));
+ CFont::SetDropShadowPosition(2);
+ CFont::SetDropColor(CRGBA(0, 0, 0, 255));
CFont::SetScale(MENU_X(MENUACTION_SCALE_MULT), MENU_Y(MENUACTION_SCALE_MULT));
CFont::SetRightJustifyOn();
CFont::PrintString(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_DATE_COLUMN_RIGHT), MENU_Y(PLAYERSETUP_LIST_TOP), TheText.Get("FES_DAT"));
@@ -3171,6 +2657,7 @@ CMenuManager::DrawPlayerSetupScreen()
}
CFont::SetRightJustifyOff();
CFont::PrintString(MENU_X_LEFT_ALIGNED(PLAYERSETUP_SKIN_COLUMN_LEFT), MENU_Y(PLAYERSETUP_LIST_TOP), TheText.Get("FES_SKN"));
+ CFont::SetDropShadowPosition(0);
// Skin list
SET_FONT_FOR_LIST_ITEM
@@ -3195,13 +2682,11 @@ CMenuManager::DrawPlayerSetupScreen()
if (rowIdx == m_nSelectedListRow) {
m_nHoverOption = HOVEROPTION_NOT_HOVERING;
if (m_nSkinsTotal > 0) {
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
strcpy(m_PrefsSkinFile, m_aSkinName);
CWorld::Players[0].SetPlayerSkin(m_PrefsSkinFile);
SaveSettings();
}
} else {
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0);
m_nCurrExLayer = HOVEROPTION_LIST;
m_nSelectedListRow = rowIdx;
m_nHoverOption = HOVEROPTION_NOT_HOVERING;
@@ -3244,7 +2729,7 @@ CMenuManager::DrawPlayerSetupScreen()
++rowIdx;
m_pSelectedSkin = m_pSelectedSkin->nextSkin;
}
- // Scrollbar background
+ // Scrollbar background - it's unchanged since III and still yellowish...
CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), MENU_Y(PLAYERSETUP_LIST_TOP),
MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2 - PLAYERSETUP_SCROLLBAR_WIDTH), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM)), CRGBA(100, 100, 66, FadeIn(205)));
@@ -3281,21 +2766,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
@@ -3303,27 +2788,28 @@ 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
}
- CPlayerSkin::RenderFrontendSkinEdit();
+ if (activeScreen)
+ CPlayerSkin::RenderFrontendSkinEdit();
// Big apply button
if (strcmp(m_aSkinName, m_PrefsSkinFile) != 0) {
@@ -3343,35 +2829,29 @@ CMenuManager::DrawPlayerSetupScreen()
CFont::SetScale(MENU_X(1.9f), MENU_Y(1.9f));
break;
}
- CFont::SetColor(CRGBA(SELECTEDMENUOPTION_COLOR.r, SELECTEDMENUOPTION_COLOR.g, SELECTEDMENUOPTION_COLOR.b, FadeIn(120)));
+ CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(120)));
CFont::SetRightJustifyOff();
- CFont::PrintString(MENU_X_LEFT_ALIGNED(20.0f), MENU_Y(220.0f), TheText.Get("FET_APL"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(24.0f), MENU_Y(220.0f), TheText.Get("FET_APP"));
}
CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING));
- CFont::SetScale(MENU_X(SMALLTEXT_X_SCALE), MENU_Y(SMALLTEXT_Y_SCALE));
+ CFont::SetScale(MENU_X(BIGTEXT_X_SCALE), MENU_Y(BIGTEXT_Y_SCALE));
if ((m_nMousePosX > MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 1) - CFont::GetStringWidth(TheText.Get("FEDS_TB"), true)
&& m_nMousePosX < MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 1)
&& m_nMousePosY > SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM - 3)
&& m_nMousePosY < SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM - 26))
|| m_nCurrExLayer == HOVEROPTION_BACK) {
- if (m_nHoverOption != HOVEROPTION_BACK)
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0);
m_nHoverOption = HOVEROPTION_BACK;
-
} else if ((strcmp(m_aSkinName, m_PrefsSkinFile) != 0
&& m_nMousePosX > MENU_X_LEFT_ALIGNED(PLAYERSETUP_LIST_LEFT)
&& m_nMousePosX < MENU_X_LEFT_ALIGNED(PLAYERSETUP_LIST_LEFT) + CFont::GetStringWidth(TheText.Get("FES_SET"), true)
&& m_nMousePosY > SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM - 3)
&& m_nMousePosY < SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM - 26))
|| m_nCurrExLayer == HOVEROPTION_USESKIN) {
- if (m_nHoverOption != HOVEROPTION_USESKIN)
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0);
m_nHoverOption = HOVEROPTION_USESKIN;
-
} else if (m_nMousePosX > MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2)
&& m_nMousePosX < MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - PLAYERSETUP_SCROLLBAR_WIDTH - 2)
&& m_nMousePosY > MENU_Y(PLAYERSETUP_LIST_TOP)
@@ -3426,86 +2906,46 @@ CMenuManager::DrawPlayerSetupScreen()
}
}
CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING));
- CFont::SetScale(MENU_X(SMALLTEXT_X_SCALE), MENU_Y(SMALLTEXT_Y_SCALE));
+ CFont::SetScale(MENU_X(BIGTEXT_X_SCALE), MENU_Y(BIGTEXT_Y_SCALE));
CFont::SetRightJustifyOn();
- CFont::SetColor(CRGBA(0, 0, 0, FadeIn(90)));
+ CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255)));
+ CFont::SetDropShadowPosition(2);
+ CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255)));
// Back button
- for (int i = 0; i < 2; i++) {
- CFont::PrintString(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3 - i), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM - 5 - i), TheText.Get("FEDS_TB"));
- if (m_nHoverOption == HOVEROPTION_BACK) {
- CFont::SetColor(CRGBA(SELECTEDMENUOPTION_COLOR.r, SELECTEDMENUOPTION_COLOR.g, SELECTEDMENUOPTION_COLOR.b, FadeIn(255)));
- } else {
- CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255)));
- }
- }
+ CFont::PrintString(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM - 5), TheText.Get("FEDS_TB"));
CFont::SetRightJustifyOff();
- CFont::SetColor(CRGBA(0, 0, 0, FadeIn(90)));
- // Use skin button
- for (int i = 0; i < 2; i++) {
- CFont::PrintString(MENU_X_LEFT_ALIGNED(i + PLAYERSETUP_LIST_LEFT), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM - 5 - i), TheText.Get("FES_SET"));
- if (!strcmp(m_aSkinName, m_PrefsSkinFile)) {
- CFont::SetColor(CRGBA(DARKMENUOPTION_COLOR.r, DARKMENUOPTION_COLOR.g, DARKMENUOPTION_COLOR.b, FadeIn(255)));
- } else if (m_nHoverOption == HOVEROPTION_USESKIN) {
- CFont::SetColor(CRGBA(SELECTEDMENUOPTION_COLOR.r, SELECTEDMENUOPTION_COLOR.g, SELECTEDMENUOPTION_COLOR.b, FadeIn(255)));
- } else {
- CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255)));
- }
+ if (!strcmp(m_aSkinName, m_PrefsSkinFile)) {
+ CFont::SetColor(CRGBA(DARKMENUOPTION_COLOR.r, DARKMENUOPTION_COLOR.g, DARKMENUOPTION_COLOR.b, FadeIn(255)));
+ } else {
+ CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255)));
}
+ // Use skin button
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(PLAYERSETUP_LIST_LEFT), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM - 5), TheText.Get("FES_SET"));
+ CFont::SetDropShadowPosition(0);
}
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);
}
-void
-CMenuManager::FilterOutColorMarkersFromString(wchar *str, CRGBA &newColor)
-{
- int newIdx = 0;
- wchar copy[256], *c;
- UnicodeStrcpy(copy, str);
-
- for (c = copy; *c != '\0'; c++) {
- if (*c == '~') {
- c++;
- switch (*c) {
- case 'b': newColor = CRGBA(40, 40, 255, 255); break;
- case 'g': newColor = CRGBA(40, 235, 40, 255); break;
- // There is no case for "h", is that a mistake?
- case 'l': newColor = CRGBA(0, 0, 0, 255); break;
- case 'p': newColor = CRGBA(255, 0, 255, 255); break;
- case 'r': newColor = CRGBA(255, 0, 0, 255); break;
- case 'w': newColor = CRGBA(255, 255, 255, 255); break;
- case 'y': newColor = CRGBA(255, 255, 0, 255); break;
- }
- while (*c != '~') c++;
- } else {
- str[newIdx++] = *c;
- }
- }
- str[newIdx] = '\0';
-}
-
int
CMenuManager::GetStartOptionsCntrlConfigScreens()
{
int number = 0;
switch (m_nCurrScreen) {
+#ifdef LEGACY_MENU_OPTIONS
case MENUPAGE_CONTROLLER_PC_OLD3:
number = 34;
break;
case MENUPAGE_CONTROLLER_DEBUG:
number = 35;
break;
+#endif
case MENUPAGE_KEYBOARD_CONTROLS:
number = 0;
break;
@@ -3569,6 +3009,7 @@ CMenuManager::InitialiseChangedLanguageSettings()
default:
break;
}
+
}
}
@@ -3578,182 +3019,92 @@ CMenuManager::LoadAllTextures()
if (m_bSpritesLoaded)
return;
- CentreMousePointer();
- DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND);
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_STARTING, 0);
- m_nCurrOption = 0;
-
-#ifdef FIX_BUGS
- static bool firstTime = true;
- if (firstTime) {
- DMAudio.SetRadioInCar(m_PrefsRadioStation);
- firstTime = false;
- } else
-#endif
- m_PrefsRadioStation = DMAudio.GetRadioInCar();
-
- if (DMAudio.IsMP3RadioChannelAvailable()) {
- if (m_PrefsRadioStation > USERTRACK)
- m_PrefsRadioStation = CGeneral::GetRandomNumber() % (USERTRACK + 1);
- } else if (m_PrefsRadioStation > CHATTERBOX)
- m_PrefsRadioStation = CGeneral::GetRandomNumber() % (CHATTERBOX + 1);
-
- CFileMgr::SetDir("");
- //CFileMgr::SetDir("");
+ // First icon is hidden behind arrow
+ m_LeftMostRadioX = MENU_X_LEFT_ALIGNED(MENURADIO_ICON_FIRST_X - MENURADIO_ICON_SIZE);
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);
-#if GTA_VERSION < GTA3_PC_11
- 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);
}
-#ifdef GAMEPAD_MENU
- LoadController(m_PrefsControllerType);
-#endif
-
- 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
- static bool menuOptionAdded = false;
- for (int i = 0; i < ARRAY_SIZE(MapFilenames); i++) {
- RwTexture *firstTile;
- if (!menuOptionAdded && (firstTile = RwTextureRead(MapFilenames[i][0], MapFilenames[i][1]))) {
- RwTextureDestroy(firstTile);
- FrontendOptionSetCursor(MENUPAGE_PAUSE_MENU, 2, false);
- FrontendOptionAddBuiltinAction("FEG_MAP", MENUACTION_CHANGEMENU, MENUPAGE_MAP, SAVESLOT_NONE);
- menuOptionAdded = true;
- }
- m_aMapSprites[i].SetTexture(MapFilenames[i][0], MapFilenames[i][1]);
- m_aMapSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER);
- }
- fMapSize = SCREEN_HEIGHT * 2.0f;
- fMapCenterX = 0.0f;
- fMapCenterY = 0.0f;
-#endif
-#if GTA_VERSION >= GTA3_PC_11
- CStreaming::IHaveUsedStreamingMemory();
- CTimer::Update();
-#endif
- m_bSpritesLoaded = true;
CTxdStore::PopCurrentTxd();
-}
+ CStreaming::IHaveUsedStreamingMemory();
-#ifdef GAMEPAD_MENU
-const char* controllerTypesPaths[] = {
- nil,
- "MODELS/FRONTEND_DS3.TXD",
- "MODELS/FRONTEND_DS4.TXD",
- "MODELS/FRONTEND_X360.TXD",
- "MODELS/FRONTEND_XONE.TXD",
-};
+ if (!m_OnlySaveMenu) {
+ CStreaming::MakeSpaceFor(692 * CDSTREAM_SECTOR_SIZE); // twice of it in mobile
+ CStreaming::ImGonnaUseStreamingMemory();
+ CTxdStore::PushCurrentTxd();
-void
-CMenuManager::LoadController(int8 type)
-{
- switch (type)
- {
- case CONTROLLER_DUALSHOCK2:
- case CONTROLLER_DUALSHOCK3:
- case CONTROLLER_DUALSHOCK4:
- CFont::LoadButtons("MODELS/PS3BTNS.TXD");
- break;
- default:
- CFont::LoadButtons("MODELS/X360BTNS.TXD");
- break;
- }
+ int frontendTxdSlot2 = CTxdStore::FindTxdSlot("frontend2");
- // Unload current textures
- for (int i = FE_CONTROLLER; i <= FE_ARROWS4; i++)
- m_aFrontEndSprites[i].Delete();
+ if (frontendTxdSlot2 == -1)
+ frontendTxdSlot2 = CTxdStore::AddTxdSlot("frontend2");
- // Unload txd
- int frontend_controller = CTxdStore::FindTxdSlot("frontend_controller");
- if (frontend_controller != -1)
- CTxdStore::RemoveTxd(frontend_controller);
+ printf("LOAD frontend2\n");
+ CTxdStore::LoadTxd(frontendTxdSlot2, "MODELS/FRONTEN2.TXD");
+ CTxdStore::AddRef(frontendTxdSlot2);
+ CTxdStore::SetCurrentTxd(frontendTxdSlot2);
- // Find the new txd to load
- bool bTxdMissing = true;
- if (controllerTypesPaths[type])
- if (int file = CFileMgr::OpenFile(controllerTypesPaths[type])) {
- CFileMgr::CloseFile(file);
- bTxdMissing = false;
+#ifdef GAMEPAD_MENU
+ for (int i = 3; i < MENUSPRITE_CONTROLLER; i++) {
+#else
+ for (int i = 3; i < NUM_MENU_SPRITES; i++) {
+#endif
+ m_aFrontEndSprites[i].SetTexture(FrontendFilenames[i][0], FrontendFilenames[i][1]);
+ m_aFrontEndSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER);
}
- int txdSlot = -1;
-
- if (bTxdMissing)
- // Not found, fall back to original textures
- txdSlot = CTxdStore::FindTxdSlot("frontend");
- else {
- // Found, load txd
- txdSlot = frontend_controller;
- if (txdSlot == -1)
- txdSlot = CTxdStore::AddTxdSlot("frontend_controller");
- CTxdStore::LoadTxd(txdSlot, controllerTypesPaths[type]);
- CTxdStore::AddRef(txdSlot);
+ CTxdStore::PopCurrentTxd();
+#ifdef GAMEPAD_MENU
+ LoadController(m_PrefsControllerType);
+#endif
+ CStreaming::IHaveUsedStreamingMemory();
}
- assert(txdSlot != -1);
- // Load new textures
- CTxdStore::SetCurrentTxd(txdSlot);
- for (int i = FE_CONTROLLER; i <= FE_ARROWS4; i++) {
- m_aFrontEndSprites[i].SetTexture(FrontendFilenames[i][0], FrontendFilenames[i][1]);
- m_aFrontEndSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER);
- }
+ m_bSpritesLoaded = true;
+ CTimer::Update();
}
-#endif // GAMEPAD_MENU
void
CMenuManager::LoadSettings()
{
CFileMgr::SetDirMyDocuments();
- int fileHandle = CFileMgr::OpenFile("gta3.set", "r");
+ int fileHandle = CFileMgr::OpenFile("gta_vc.set", "r");
int32 prevLang = m_PrefsLanguage;
-#if GTA_VERSION >= GTA3_PC_11
- CMBlur::BlurOn = (_dwOperatingSystemVersion != OS_WIN98);
-#else
- CMBlur::BlurOn = true;
-#endif
MousePointerStateHelper.bInvertVertically = true;
+ CMBlur::BlurOn = false;
// 50 is silly
- char Ver[50];
+ char headerText[50];
+ int someVersion = 0;
+ bool fileIsValid = true;
if (fileHandle) {
- CFileMgr::Read(fileHandle, Ver, 29);
+ CFileMgr::Read(fileHandle, headerText, 29);
- if (strncmp(Ver, TopLineEmptyFile, sizeof(TopLineEmptyFile) - 1)) {
+ if (strncmp(headerText, TopLineEmptyFile, sizeof(TopLineEmptyFile) - 1) == 0) {
+ fileIsValid = false;
+ } else {
CFileMgr::Seek(fileHandle, 0, 0);
+ CFileMgr::Read(fileHandle, (char*)&someVersion, sizeof(someVersion));
+ }
+ if (fileIsValid && someVersion >= 3) {
ControlsManager.LoadSettings(fileHandle);
#ifdef IMPROVED_VIDEOMODE
CFileMgr::Read(fileHandle, (char*)&m_nPrefsWidth, sizeof(m_nPrefsWidth));
@@ -3778,30 +3129,36 @@ CMenuManager::LoadSettings()
CFileMgr::Read(fileHandle, gString, 4);
CFileMgr::Read(fileHandle, gString, 4);
CFileMgr::Read(fileHandle, gString, 1);
+#ifdef LEGACY_MENU_OPTIONS
+ CFileMgr::Read(fileHandle, (char*)&m_PrefsVsyncDisp, 1);
+ CFileMgr::Read(fileHandle, (char*)&CMBlur::BlurOn, 1);
+#else
CFileMgr::Read(fileHandle, gString, 1);
CFileMgr::Read(fileHandle, gString, 1);
+#endif
CFileMgr::Read(fileHandle, (char*)&TheCamera.m_bHeadBob, 1);
CFileMgr::Read(fileHandle, (char*)&TheCamera.m_fMouseAccelHorzntl, 4);
- CFileMgr::Read(fileHandle, (char*)&TheCamera.m_fMouseAccelVertical, 4);
CFileMgr::Read(fileHandle, (char*)&MousePointerStateHelper.bInvertVertically, 1);
CFileMgr::Read(fileHandle, (char*)&CVehicle::m_bDisableMouseSteering, 1);
CFileMgr::Read(fileHandle, (char*)&m_PrefsSfxVolume, 1);
CFileMgr::Read(fileHandle, (char*)&m_PrefsMusicVolume, 1);
+ CFileMgr::Read(fileHandle, (char*)&m_PrefsMP3BoostVolume, 1);
CFileMgr::Read(fileHandle, (char*)&m_PrefsRadioStation, 1);
CFileMgr::Read(fileHandle, (char*)&m_PrefsSpeakers, 1);
CFileMgr::Read(fileHandle, (char*)&m_nPrefsAudio3DProviderIndex, 1);
CFileMgr::Read(fileHandle, (char*)&m_PrefsDMA, 1);
- CFileMgr::Read(fileHandle, (char*)&m_PrefsBrightness, 1);
- CFileMgr::Read(fileHandle, (char*)&m_PrefsLOD, 4);
+ CFileMgr::Read(fileHandle, (char*)&m_PrefsBrightness, 2);
+ CFileMgr::Read(fileHandle, (char*)&m_PrefsLOD, sizeof(m_PrefsLOD));
CFileMgr::Read(fileHandle, (char*)&m_PrefsShowSubtitles, 1);
CFileMgr::Read(fileHandle, (char*)&m_PrefsUseWideScreen, 1);
- CFileMgr::Read(fileHandle, (char*)&m_PrefsVsyncDisp, 1);
CFileMgr::Read(fileHandle, (char*)&m_PrefsFrameLimiter, 1);
CFileMgr::Read(fileHandle, (char*)&m_nDisplayVideoMode, 1);
- CFileMgr::Read(fileHandle, (char*)&CMBlur::BlurOn, 1);
CFileMgr::Read(fileHandle, m_PrefsSkinFile, 256);
CFileMgr::Read(fileHandle, (char*)&m_ControlMethod, 1);
CFileMgr::Read(fileHandle, (char*)&m_PrefsLanguage, 1);
+ CFileMgr::Read(fileHandle, (char*)&m_PrefsShowHud, 1);
+ CFileMgr::Read(fileHandle, (char*)&m_PrefsRadarMode, 1);
+ CFileMgr::Read(fileHandle, (char*)&m_PrefsShowLegends, 1);
}
}
@@ -3814,21 +3171,28 @@ CMenuManager::LoadSettings()
}
#endif
+#ifdef FIX_BUGS
+ TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl + 0.0005f;
+#endif
+#ifdef PC_PLAYER_CONTROLS
+ CCamera::m_bUseMouse3rdPerson = m_ControlMethod == CONTROL_STANDARD;
+#endif
+#ifdef LEGACY_MENU_OPTIONS
m_PrefsVsync = m_PrefsVsyncDisp;
+#endif
CRenderer::ms_lodDistScale = m_PrefsLOD;
- if (m_nPrefsAudio3DProviderIndex == -1)
+ if (m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER)
m_nPrefsAudio3DProviderIndex = -2;
+ m_lastWorking3DAudioProvider = m_nPrefsAudio3DProviderIndex;
+
if (m_PrefsLanguage == prevLang)
m_bLanguageLoaded = false;
else {
m_bLanguageLoaded = true;
- // Already called in InitialiseChangedLanguageSettings
- /*
TheText.Unload();
TheText.Load();
- */
m_bFrontEnd_ReloadObrTxtGxt = true;
InitialiseChangedLanguageSettings();
@@ -3859,11 +3223,17 @@ CMenuManager::SaveSettings()
{
#ifndef LOAD_INI_SETTINGS
static char RubbishString[48] = "stuffmorestuffevenmorestuff etc";
+#ifdef BIND_VEHICLE_FIREWEAPON
+ static int SomeVersion = 4;
+#else
+ static int SomeVersion = 3;
+#endif
CFileMgr::SetDirMyDocuments();
- int fileHandle = CFileMgr::OpenFile("gta3.set", "w+");
+ int fileHandle = CFileMgr::OpenFile("gta_vc.set", "w+");
if (fileHandle) {
+ CFileMgr::Write(fileHandle, (char*)&SomeVersion, sizeof(SomeVersion));
ControlsManager.SaveSettings(fileHandle);
#ifdef IMPROVED_VIDEOMODE
CFileMgr::Write(fileHandle, (char*)&m_nPrefsWidth, sizeof(m_nPrefsWidth));
@@ -3878,45 +3248,50 @@ CMenuManager::SaveSettings()
CFileMgr::Write(fileHandle, RubbishString, 4);
CFileMgr::Write(fileHandle, RubbishString, 4);
CFileMgr::Write(fileHandle, RubbishString, 1);
+#ifdef LEGACY_MENU_OPTIONS
+ CFileMgr::Write(fileHandle, (char*)&m_PrefsVsyncDisp, 1);
+ CFileMgr::Write(fileHandle, (char*)&CMBlur::BlurOn, 1);
+#else
CFileMgr::Write(fileHandle, RubbishString, 1);
CFileMgr::Write(fileHandle, RubbishString, 1);
+#endif
CFileMgr::Write(fileHandle, (char*)&TheCamera.m_bHeadBob, 1);
CFileMgr::Write(fileHandle, (char*)&TheCamera.m_fMouseAccelHorzntl, 4);
- CFileMgr::Write(fileHandle, (char*)&TheCamera.m_fMouseAccelVertical, 4);
CFileMgr::Write(fileHandle, (char*)&MousePointerStateHelper.bInvertVertically, 1);
CFileMgr::Write(fileHandle, (char*)&CVehicle::m_bDisableMouseSteering, 1);
CFileMgr::Write(fileHandle, (char*)&m_PrefsSfxVolume, 1);
CFileMgr::Write(fileHandle, (char*)&m_PrefsMusicVolume, 1);
+ CFileMgr::Write(fileHandle, (char*)&m_PrefsMP3BoostVolume, 1);
CFileMgr::Write(fileHandle, (char*)&m_PrefsRadioStation, 1);
CFileMgr::Write(fileHandle, (char*)&m_PrefsSpeakers, 1);
CFileMgr::Write(fileHandle, (char*)&m_nPrefsAudio3DProviderIndex, 1);
CFileMgr::Write(fileHandle, (char*)&m_PrefsDMA, 1);
- CFileMgr::Write(fileHandle, (char*)&m_PrefsBrightness, 1);
+ CFileMgr::Write(fileHandle, (char*)&m_PrefsBrightness, 2);
CFileMgr::Write(fileHandle, (char*)&m_PrefsLOD, sizeof(m_PrefsLOD));
CFileMgr::Write(fileHandle, (char*)&m_PrefsShowSubtitles, 1);
CFileMgr::Write(fileHandle, (char*)&m_PrefsUseWideScreen, 1);
- CFileMgr::Write(fileHandle, (char*)&m_PrefsVsyncDisp, 1);
CFileMgr::Write(fileHandle, (char*)&m_PrefsFrameLimiter, 1);
CFileMgr::Write(fileHandle, (char*)&m_nPrefsVideoMode, 1);
- CFileMgr::Write(fileHandle, (char*)&CMBlur::BlurOn, 1);
CFileMgr::Write(fileHandle, m_PrefsSkinFile, 256);
CFileMgr::Write(fileHandle, (char*)&m_ControlMethod, 1);
CFileMgr::Write(fileHandle, (char*)&m_PrefsLanguage, 1);
+ CFileMgr::Write(fileHandle, (char*)&m_PrefsShowHud, 1);
+ CFileMgr::Write(fileHandle, (char*)&m_PrefsRadarMode, 1);
+ CFileMgr::Write(fileHandle, (char*)&m_PrefsShowLegends, 1);
}
+ m_lastWorking3DAudioProvider = m_nPrefsAudio3DProviderIndex;
CFileMgr::CloseFile(fileHandle);
CFileMgr::SetDir("");
-
+
#else
+ m_lastWorking3DAudioProvider = m_nPrefsAudio3DProviderIndex;
SaveINISettings();
#endif
}
-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)
+CMenuManager::MessageScreen(const char *text, bool blackBg)
{
CSprite2d *splash = LoadSplash(nil);
if (!DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255))
@@ -3926,54 +3301,58 @@ CMenuManager::MessageScreen(const char *text)
CSprite2d::InitPerFrame();
CFont::InitPerFrame();
DefinedState();
+ // CRGBA unused(255, 255, 255, 255);
+ if (blackBg) {
+ CSprite2d::DrawRect(CRect(0, SCREEN_HEIGHT, SCREEN_WIDTH, 0), CRGBA(0, 0, 0, 255));
+ }
- RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP);
- splash->Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255));
+ m_nMenuFadeAlpha = 255;
+ SmallMessageScreen(text);
+ CFont::DrawFonts();
+ DoRWStuffEndOfFrame();
+}
+void
+CMenuManager::SmallMessageScreen(const char* text)
+{
CFont::SetBackgroundOff();
CFont::SetPropOn();
CFont::SetJustifyOn();
CFont::SetBackGroundOnlyTextOn();
- CFont::SetWrapx(SCREEN_WIDTH - StretchX(170.0f)); // unused
- CFont::SetRightJustifyWrap(SCREEN_WIDTH - StretchX(170.0f)); // unused
- CSprite2d::DrawRect(CRect(StretchX(120.0f), StretchY(150.0f), SCREEN_WIDTH - StretchX(120.0f), SCREEN_HEIGHT - StretchY(220.0f)), CRGBA(50, 50, 50, 210));
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
- CFont::SetCentreSize(SCREEN_SCALE_X(380.0f));
+ CSprite2d::DrawRect(CRect(SCREEN_STRETCH_X(95.0f), SCREEN_SCALE_FROM_BOTTOM(165.0f), SCREEN_STRETCH_FROM_RIGHT(95.0f), SCREEN_SCALE_Y(115.0f)), CRGBA(50, 50, 50, FadeIn(210)));
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
+ CFont::SetCentreSize(SCREEN_SCALE_X(430.0f));
CFont::SetCentreOn();
- CFont::SetColor(CRGBA(SELECTEDMENUOPTION_COLOR.r, SELECTEDMENUOPTION_COLOR.g, SELECTEDMENUOPTION_COLOR.b, 255));
+ CFont::SetColor(CRGBA(LABEL_COLOR.r, LABEL_COLOR.g, LABEL_COLOR.b, FadeIn(255)));
+ CFont::SetDropShadowPosition(2);
+ CFont::SetDropColor(CRGBA(0, 0, 0, 255));
CFont::SetScale(SCREEN_SCALE_X(SMALLTEXT_X_SCALE), SCREEN_SCALE_Y(SMALLTEXT_Y_SCALE));
- CFont::PrintString(StretchX(320.0f), StretchY(170.0f), TheText.Get(text));
- CFont::DrawFonts();
- DoRWStuffEndOfFrame();
-}
+
+ int numOfLines = CFont::GetNumberLines(SCREEN_WIDTH / 2.f, SCREEN_SCALE_Y(135.f), TheText.Get(text));
+ float y;
+ if (numOfLines > 1)
+ y = SCREEN_SCALE_Y(192.f) - numOfLines * SCREEN_SCALE_Y(8.f);
+ else
+ y = SCREEN_SCALE_Y(182.f);
-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();
- }
+ CFont::PrintString(SCREEN_WIDTH / 2.f, y, TheText.Get(text));
}
void
CMenuManager::PrintBriefs()
{
- CFont::SetColor(CRGBA(LABEL_COLOR.r, LABEL_COLOR.g, LABEL_COLOR.b, FadeIn(255)));
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
+ CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255)));
CFont::SetRightJustifyOff();
- CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X * 0.7), MENU_Y(MENU_TEXT_SIZE_Y * 0.9)); // second mulipliers are double, idk why
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
+ CFont::SetScale(MENU_X(MEDIUMTEXT_X_SCALE), MENU_Y(MEDIUMTEXT_Y_SCALE));
+ CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(80.0f));
+ CFont::SetDropShadowPosition(0);
- float nextY = BRIEFS_TOP_MARGIN;
- CRGBA newColor;
+ float nextY = BRIEFS_BOTTOM_MARGIN;
for (int i = 4; i >= 0; i--) {
+ if (nextY < BRIEFS_TOP_MARGIN)
+ break;
+
tPreviousBrief &brief = CMessages::PreviousBriefs[i];
if (brief.m_pText) {
CMessages::InsertNumberInString(brief.m_pText,
@@ -3982,347 +3361,987 @@ CMenuManager::PrintBriefs()
brief.m_nNumber[4], brief.m_nNumber[5], gUString);
CMessages::InsertStringInString(gUString, brief.m_pString);
CMessages::InsertPlayerControlKeysInString(gUString);
- newColor = TEXT_COLOR;
- FilterOutColorMarkersFromString(gUString, newColor);
- if (newColor != TEXT_COLOR) {
- newColor.r /= 2;
- newColor.g /= 2;
- newColor.b /= 2;
- }
+ CFont::FilterOutTokensFromString(gUString);
-#ifdef PS2_LIKE_MENU
- CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255)));
- CFont::SetDropShadowPosition(1);
-#endif
-
-#if defined(FIX_BUGS) || defined(PS2_LIKE_MENU)
- newColor.a = FadeIn(255);
- CFont::SetColor(newColor);
-#endif
- CFont::PrintString(MENU_X_LEFT_ALIGNED(BRIEFS_LINE_X), nextY, gUString);
- nextY += MENU_Y(BRIEFS_LINE_HEIGHT);
+ nextY -= CFont::GetNumberLines(MENU_X_LEFT_ALIGNED(BRIEFS_LINE_X), nextY, gUString) * BRIEFS_LINE_HEIGHT + BRIEFS_LINE_SPACING;
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(BRIEFS_LINE_X), MENU_Y(nextY), gUString);
}
}
-
-#ifdef PS2_LIKE_MENU
- CFont::SetDropShadowPosition(0);
-#endif
}
-// Not sure about name. Not to be confused with CPad::PrintErrorMessage
void
-CMenuManager::PrintErrorMessage()
+CMenuManager::PrintStats()
{
- if (!CPad::bDisplayNoControllerMessage && !CPad::bObsoleteControllerMessage)
- return;
+#ifdef SECUROM
+ static uint8 statsPirateCheck = 0;
+#endif
+ static float scrollY = 0;
- 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();
+ int rowNum = CStats::ConstructStatLine(99999);
+ CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(90.0f), MENU_Y(142.0f),
+ MENU_X_LEFT_ALIGNED(543.0f), MENU_Y(142.f),
+ MENU_X_LEFT_ALIGNED(107.0f), MENU_Y(316.f),
+ MENU_X_LEFT_ALIGNED(531.f), MENU_Y(299.f), CRGBA(LIST_BACKGROUND_COLOR.r, LIST_BACKGROUND_COLOR.g, LIST_BACKGROUND_COLOR.b, FadeIn(LIST_BACKGROUND_COLOR.a)));
+
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
CFont::SetPropOn();
- CFont::SetCentreOff();
- CFont::SetJustifyOn();
- CFont::SetRightJustifyOff();
- CFont::SetBackGroundOnlyTextOn();
- CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(MENU_X_MARGIN));
-#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();
-}
+ CFont::SetDropShadowPosition(0);
-void
-CMenuManager::PrintStats()
-{
- int rowNum = ConstructStatLine(99999);
-#if GTA_VERSION >= GTA3_PC_11
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
+#ifdef SECUROM
+ if (statsPirateCheck == 0)
+ // if not pirated game
+ // statsPirateCheck = 46;
+ // else
+ statsPirateCheck = 45;
#endif
- CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X * 0.7), MENU_Y(MENU_TEXT_SIZE_Y * 0.9)); // second mulipliers are double, idk why
- float nextYChange, y, alphaMult;
- // Scroll stats with mouse
-#ifdef SCROLLABLE_STATS_PAGE
- static float scrollY = 0;
- static uint32 lastChange = m_nScreenChangeDelayTimer;
- if (CPad::GetPad(0)->GetLeftMouse()) {
- scrollY += (m_nMouseOldPosY - m_nMousePosY);
- lastChange = CTimer::GetTimeInMillisecondsPauseMode();
- } else {
- scrollY += MENU_Y(STATS_SLIDE_Y_PER_SECOND) / 1000.0f * (CTimer::GetTimeInMillisecondsPauseMode() - lastChange);
- lastChange = CTimer::GetTimeInMillisecondsPauseMode();
+ if (m_PrefsLanguage == LANGUAGE_AMERICAN)
+ CFont::SetScale(MENU_X(0.43f), MENU_Y(0.75f));
+ else
+ CFont::SetScale(MENU_X(0.37f), MENU_Y(0.75f));
+
+ static uint32 lastCheck = 0;
+
+ if (CTimer::GetTimeInMillisecondsPauseMode() - lastCheck > 40) {
+
+ if (m_StatsScrollSpeed > 0.f) {
+ if (m_StatsScrollDirection == 0)
+ scrollY -= MENU_Y(100.f) / m_StatsScrollSpeed;
+ else
+ scrollY += MENU_Y(100.f) / m_StatsScrollSpeed;
+ }
+ lastCheck = CTimer::GetTimeInMillisecondsPauseMode();
}
-#else
- // MENU_Y(30.0f) per second
- float scrollY = MENU_Y(STATS_SLIDE_Y_PER_SECOND) * (CTimer::GetTimeInMillisecondsPauseMode() - m_nScreenChangeDelayTimer) / 1000.0f;
+
+#ifdef SECUROM
+ if (statsPirateCheck == 45)
+ return;
#endif
+ float nextYChange, y, alpha;
+
+ float totalHeight = (rowNum + 7) * STATS_ROW_HEIGHT;
for (int row = 0; row < rowNum; ++row) {
- // Put just got hidden text at the top back to the bottom, in circular fashion
- for (y = MENU_Y(STATS_ROW_HEIGHT - 1) * row + SCREEN_HEIGHT - scrollY; MENU_Y(STATS_PUT_BACK_TO_BOTTOM_Y) > y; y += nextYChange) {
- nextYChange = (MENU_Y(STATS_ROW_HEIGHT) + rowNum) * MENU_Y(STATS_ROW_HEIGHT - 1);
+ // Put faded away text at the top back to the bottom, in circular fashion
+ for (y = MENU_Y(STATS_ROW_HEIGHT) * row + MENU_Y(100.f) - scrollY; MENU_Y(STATS_FADING_AREA_LENGTH) > y; y += nextYChange) {
+ nextYChange = MENU_Y(totalHeight);
}
+ // Put faded away text at the bottom back to the top
+ while (SCREEN_SCALE_FROM_BOTTOM(STATS_FADING_AREA_LENGTH) < y) {
+ y -= MENU_Y(totalHeight);
+ }
+ alpha = 0.f;
+
// If it's still on screen
- if (y > 0.0f && SCREEN_HEIGHT > y) {
- ConstructStatLine(row);
+ if (y > MENU_Y(STATS_VISIBLE_START_Y) && y < MENU_Y(STATS_VISIBLE_END_Y)) {
+ CStats::ConstructStatLine(row);
- // But about to dim from top
- if (y - MENU_Y(STATS_BOTTOM_MARGIN) < MENU_Y(STATS_TOP_DIMMING_AREA_LENGTH)) {
- if ((y - MENU_Y(STATS_BOTTOM_MARGIN)) / MENU_Y(STATS_TOP_DIMMING_AREA_LENGTH) < 0.0f)
- alphaMult = 0.0f;
- else
- alphaMult = (y - MENU_Y(STATS_BOTTOM_MARGIN)) / MENU_Y(STATS_TOP_DIMMING_AREA_LENGTH);
+ // But about to dim from bottom
+ if (y < MENU_Y(STATS_BOTTOM_Y)) {
+ if (y > MENU_Y(STATS_BOTTOM_Y - STATS_FADING_AREA_LENGTH))
+ alpha = (MENU_Y(STATS_BOTTOM_Y) - y) * 5.f;
+ }
- // About to dim from bottom
- } else if (y > SCREEN_SCALE_FROM_BOTTOM(STATS_TOP_DIMMING_AREA_LENGTH) - MENU_Y(STATS_BOTTOM_DIMMING_AREA_LENGTH)) {
- if ((SCREEN_SCALE_FROM_BOTTOM(STATS_BOTTOM_DIMMING_AREA_LENGTH) - y) / MENU_Y(STATS_TOP_DIMMING_AREA_LENGTH) < 0.0f)
- alphaMult = 0.0f;
- else
- alphaMult = (SCREEN_SCALE_FROM_BOTTOM(STATS_BOTTOM_DIMMING_AREA_LENGTH) - y) / MENU_Y(STATS_TOP_DIMMING_AREA_LENGTH);
- } else
- alphaMult = 1.0f;
+ // About to dim from top
+ if (y > MENU_Y(STATS_TOP_Y)) {
+ if (y < MENU_Y(STATS_TOP_Y + STATS_FADING_AREA_LENGTH))
+ alpha = (y - MENU_Y(STATS_TOP_Y)) * 5.f;
+ }
+
+ // Content
+ if (y >= MENU_Y(STATS_TOP_Y + STATS_FADING_AREA_LENGTH) && y <= MENU_Y(STATS_BOTTOM_Y - STATS_FADING_AREA_LENGTH))
+ alpha = 255.0f;
- CFont::SetColor(CRGBA(LABEL_COLOR.r, LABEL_COLOR.g, LABEL_COLOR.b, FadeIn(255.0f * alphaMult)));
+ CFont::SetColor(CRGBA(0, 0, 0, FadeIn(Min(255.f, alpha))));
CFont::SetRightJustifyOff();
- CFont::PrintString(MENU_X_LEFT_ALIGNED(STATS_ROW_X_MARGIN), y - MENU_Y(STATS_BOTTOM_MARGIN - STATS_TOP_MARGIN), gUString);
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(STATS_ROW_LEFT_MARGIN), y, gUString);
CFont::SetRightJustifyOn();
- CFont::PrintString(MENU_X_RIGHT_ALIGNED(STATS_ROW_X_MARGIN), y - MENU_Y(STATS_BOTTOM_MARGIN - STATS_TOP_MARGIN), gUString2);
+ CFont::PrintString(MENU_X_RIGHT_ALIGNED(STATS_ROW_RIGHT_MARGIN), y, gUString2);
}
}
- // Game doesn't do that, but it's better
- float nextX = MENU_X_LEFT_ALIGNED(STATS_RATING_X);
+ CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255)));
+ CFont::SetDropShadowPosition(2);
+ CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255)));
+ CFont::SetCentreOn();
+ CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING));
+ CFont::SetScale(MENU_X(0.65f), MENU_Y(1.05f));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(STATS_RATING_X), MENU_Y(STATS_RATING_Y_1), TheText.Get("CRIMRA"));
- CFont::SetColor(CRGBA(LABEL_COLOR.r, LABEL_COLOR.g, LABEL_COLOR.b, FadeIn(255)));
+ CFont::SetCentreOff();
CFont::SetRightJustifyOff();
- CFont::PrintString(nextX, MENU_Y(STATS_RATING_Y), TheText.Get("CRIMRA"));
-#ifdef MORE_LANGUAGES
- if (CFont::IsJapanese())
- nextX += MENU_X(10.0f) + CFont::GetStringWidth_Jap(TheText.Get("CRIMRA"));
- else
-#endif
- nextX += MENU_X(10.0f) + CFont::GetStringWidth(TheText.Get("CRIMRA"), true);
- UnicodeStrcpy(gUString, CStats::FindCriminalRatingString());
- CFont::PrintString(nextX, MENU_Y(STATS_RATING_Y), gUString);
-#ifdef MORE_LANGUAGES
- if (CFont::IsJapanese())
- nextX += MENU_X(6.0f) + CFont::GetStringWidth_Jap(gUString);
- else
-#endif
- nextX += MENU_X(6.0f) + CFont::GetStringWidth(gUString, true);
- sprintf(gString, "%d", CStats::FindCriminalRatingNumber());
+
+ // FIX: Game does that in a weird way, alignment and spacing is now ok
+
+ sprintf(gString, "(%d)", CStats::FindCriminalRatingNumber());
AsciiToUnicode(gString, gUString);
- CFont::PrintString(nextX, MENU_Y(STATS_RATING_Y), gUString);
- // ::Draw already does that.
- /*
- SET_FONT_FOR_MENU_HEADER
- CFont::PrintString(PAGE_NAME_X(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));
+ UnicodeStrcpy(gUString2, CStats::FindCriminalRatingString());
+ UnicodeStrcat(gUString2, gUString);
+
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
+#ifndef FIX_BUGS
+ CFont::SetScale(MENU_X(0.5f), MENU_Y(0.9f));
+#else
+ CFont::SetScale(MENU_X(SMALLTEXT_X_SCALE), MENU_Y(SMALLTEXT_Y_SCALE));
+#endif
+ CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255)));
+ CFont::SetDropShadowPosition(0);
+
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(STATS_RATING_X) - CFont::GetStringWidth(gUString2, true) / 2.f, MENU_Y(STATS_RATING_Y_2), gUString2);
}
void
CMenuManager::Process(void)
{
- m_bMenuStateChanged = false;
+#ifdef XBOX_MESSAGE_SCREEN
+ ProcessDialogTimer();
+#endif
- 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) {
+ UserInput();
+ ProcessFileActions();
+ DMAudio.Service();
+#ifdef USE_TEXTURE_POOL
+ // TODO
+#endif
+ }
SwitchMenuOnAndOff();
+}
- // Be able to re-open menu correctly.
- if (m_bMenuActive) {
+#ifdef MAP_ENHANCEMENTS
+#define ZOOM(x, y, in) \
+ do { \
+ if(m_fMapSize >= MENU_Y(1000.0f) && in) \
+ break; \
+ float z2 = in? 1.1f : 1.f/1.1f; \
+ m_fMapCenterX += (x - m_fMapCenterX) * (1.0f - z2); \
+ m_fMapCenterY += (y - m_fMapCenterY) * (1.0f - z2); \
+ \
+ if (m_fMapSize <= MENU_Y(MAP_MIN_SIZE) && !in) \
+ break; \
+ \
+ m_fMapSize *= z2; \
+ m_fMapCenterX = Clamp(m_fMapCenterX, SCREEN_WIDTH/2 - (m_fMapSize - MENU_X(MAP_MIN_SIZE)), m_fMapSize - MENU_X(MAP_MIN_SIZE) + SCREEN_WIDTH/2); \
+ m_fMapCenterY = Clamp(m_fMapCenterY, SCREEN_HEIGHT/2 - (m_fMapSize - MENU_Y(MAP_MIN_SIZE)), m_fMapSize - MENU_Y(MAP_MIN_SIZE) + SCREEN_HEIGHT/2); \
+ } while(0)
- // Load frontend textures.
- LoadAllTextures();
+#endif
+
+// Handles Map, Audio and Stats
+void
+CMenuManager::AdditionalOptionInput(bool &goBack)
+{
+ switch (m_nCurrScreen) {
+ case MENUPAGE_MAP:
+ {
+ static uint32 lastMapTick = 0;
- // Set save/delete game pages.
- if (m_nCurrScreen == MENUPAGE_DELETING) {
- bool SlotPopulated = false;
+ // FIX: All those macros were hardcoded values originally.
- if (PcSaveHelper.DeleteSlot(m_nCurrSaveSlot)) {
- PcSaveHelper.PopulateSlotInfo();
- SlotPopulated = true;
+#ifndef MAP_ENHANCEMENTS
+ if (CPad::GetPad(0)->GetMouseWheelUpJustDown() || CPad::GetPad(0)->GetMouseWheelUpJustUp() || CPad::GetPad(0)->GetPageUp() || CPad::GetPad(0)->GetRightShoulder1()) {
+ if (CTimer::GetTimeInMillisecondsPauseMode() - lastMapTick > 10) {
+ m_fMapSize = Min(MENU_Y(1000.0f), m_fMapSize + MENU_Y(15.f));
+ }
}
+ if (CPad::GetPad(0)->GetMouseWheelDownJustDown() || CPad::GetPad(0)->GetMouseWheelDownJustUp() || CPad::GetPad(0)->GetPageDown() || CPad::GetPad(0)->GetRightShoulder2()) {
+ if (CTimer::GetTimeInMillisecondsPauseMode() - lastMapTick > 10) {
+ if (m_fMapSize > MENU_Y(MAP_MIN_SIZE)) {
+ if (m_fMapCenterY > SCREEN_HEIGHT/2)
+ m_fMapCenterY -= (m_fMapCenterY - SCREEN_HEIGHT/2) / ((m_fMapSize - MENU_Y(MAP_MIN_SIZE)) * 1/15.f);
- 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) {
-#ifdef MISSION_REPLAY
- if (doingMissionRetry) {
- RetryMission(MISSION_RETRY_TYPE_BEGIN_RESTARTING);
- m_nCurrSaveSlot = SLOT_COUNT;
- doingMissionRetry = false;
+ if (m_fMapCenterY < SCREEN_HEIGHT/2)
+ m_fMapCenterY += (SCREEN_HEIGHT/2 - m_fMapCenterY) / ((m_fMapSize - MENU_Y(MAP_MIN_SIZE)) * 1/15.f);
+
+ if (m_fMapCenterX > SCREEN_WIDTH/2)
+ m_fMapCenterX -= (m_fMapCenterX - SCREEN_WIDTH/2) / ((m_fMapSize - MENU_X(MAP_MIN_SIZE)) * 1/15.f);
+
+ if (m_fMapCenterX < SCREEN_WIDTH/2)
+ m_fMapCenterX += (SCREEN_WIDTH/2 - m_fMapCenterX) / ((m_fMapSize - MENU_X(MAP_MIN_SIZE)) * 1/15.f);
+
+ m_fMapSize = Max(MENU_Y(MAP_MIN_SIZE), m_fMapSize - MENU_Y(15.f));
+ m_fMapCenterX = Clamp(m_fMapCenterX, SCREEN_WIDTH/2 - (m_fMapSize - MENU_X(MAP_MIN_SIZE)), m_fMapSize - MENU_X(MAP_MIN_SIZE) + SCREEN_WIDTH/2);
+ m_fMapCenterY = Clamp(m_fMapCenterY, SCREEN_HEIGHT/2 - (m_fMapSize - MENU_Y(MAP_MIN_SIZE)), m_fMapSize - MENU_Y(MAP_MIN_SIZE) + SCREEN_HEIGHT/2);
+ } else {
+ m_fMapSize = MENU_Y(MAP_MIN_SIZE);
+ }
+ }
+ }
+#else
+ // Adding marker
+ if (m_nMenuFadeAlpha == 255) {
+ if (CPad::GetPad(0)->GetRightMouseJustDown() || CPad::GetPad(0)->GetCrossJustDown()) {
+ if (mapCrosshair.y > m_fMapCenterY - m_fMapSize && mapCrosshair.y < m_fMapCenterY + m_fMapSize &&
+ mapCrosshair.x > m_fMapCenterX - m_fMapSize && mapCrosshair.x < m_fMapCenterX + m_fMapSize) {
+
+ // 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 = ((mapCrosshair.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) - ((mapCrosshair.y - diffY) / (m_fMapSize * 2)) * (WORLD_SIZE_Y / MENU_MAP_HEIGHT_SCALE);
+ CRadar::ToggleTargetMarker(x, y);
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_ENTER_OR_ADJUST, 0);
+ }
+ }
+ }
+
+ if (CPad::GetPad(0)->GetMouseWheelDown() || CPad::GetPad(0)->GetPageDown() || CPad::GetPad(0)->GetRightShoulder2()) {
+ if (CPad::GetPad(0)->GetMouseWheelDown() && m_fMapSize > MENU_X(MAP_SIZE_TO_ALLOW_X_MOVE))
+ ZOOM(mapCrosshair.x, mapCrosshair.y, false);
+ else
+ ZOOM(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, false);
+
+ } else if (CPad::GetPad(0)->GetMouseWheelUp() || CPad::GetPad(0)->GetPageUp() || CPad::GetPad(0)->GetRightShoulder1()) {
+ if (CPad::GetPad(0)->GetMouseWheelUp())
+ ZOOM(mapCrosshair.x, mapCrosshair.y, true);
+ else
+ ZOOM(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, true);
}
+
+ static bool justResetPointer = false;
+ if (CPad::GetPad(0)->GetLeftMouse()) {
+ if (!justResetPointer) {
+ m_fMapCenterX += m_nMousePosX - m_nMouseOldPosX;
+ m_fMapCenterY += m_nMousePosY - m_nMouseOldPosY;
+ m_fMapCenterX = Clamp(m_fMapCenterX, SCREEN_WIDTH/2 - (m_fMapSize - MENU_X(MAP_MIN_SIZE)), m_fMapSize - MENU_X(MAP_MIN_SIZE) + SCREEN_WIDTH/2);
+ m_fMapCenterY = Clamp(m_fMapCenterY, SCREEN_HEIGHT/2 - (m_fMapSize - MENU_Y(MAP_MIN_SIZE)), m_fMapSize - MENU_Y(MAP_MIN_SIZE) + SCREEN_HEIGHT/2);
+ }
+ justResetPointer = false;
+
+ } else
+#undef ZOOM
#endif
- if (CheckSlotDataValid(m_nCurrSaveSlot)) {
-#ifdef USE_DEBUG_SCRIPT_LOADER
- CTheScripts::ScriptToLoad = 0;
+
+ {
+ // This is else block of GetLeftMouse() if MAP_ENHANCEMENTS defined, so all of GetLeftMouse() conditions below being rendered useless.
+
+ if (CPad::GetPad(0)->GetLeftMouse() && m_nMousePosY < m_nMouseOldPosY || CPad::GetPad(0)->GetUp() ||
+ CPad::GetPad(0)->GetDPadUp() || CPad::GetPad(0)->GetAnalogueUpDown() < 0) {
+ if (CTimer::GetTimeInMillisecondsPauseMode() - lastMapTick > 10) {
+ if ((m_fMapSize - MENU_Y(MAP_MIN_SIZE)) + SCREEN_HEIGHT/2 > m_fMapCenterY)
+ m_fMapCenterY += MENU_Y(15.f);
+ m_bShowMouse = false;
+ }
+ }
+
+ if (CPad::GetPad(0)->GetLeftMouse() && m_nMousePosY > m_nMouseOldPosY || CPad::GetPad(0)->GetDown() ||
+ CPad::GetPad(0)->GetDPadDown() || CPad::GetPad(0)->GetAnalogueUpDown() > 0) {
+ if (CTimer::GetTimeInMillisecondsPauseMode() - lastMapTick > 10) {
+ if (SCREEN_HEIGHT/2 - (m_fMapSize - MENU_Y(MAP_MIN_SIZE)) < m_fMapCenterY)
+ m_fMapCenterY -= MENU_Y(15.f);
+ m_bShowMouse = false;
+ }
+ }
+
+ if (CPad::GetPad(0)->GetLeftMouse() && m_nMousePosX < m_nMouseOldPosX || CPad::GetPad(0)->GetLeft() ||
+ CPad::GetPad(0)->GetDPadLeft() || CPad::GetPad(0)->GetAnalogueLeftRight() < 0) {
+ if (CTimer::GetTimeInMillisecondsPauseMode() - lastMapTick > 10) {
+ if (m_fMapSize > MENU_X(MAP_SIZE_TO_ALLOW_X_MOVE) && m_fMapSize - MENU_X(MAP_MIN_SIZE) + SCREEN_WIDTH/2 > m_fMapCenterX)
+ m_fMapCenterX += MENU_X(15.f);
+ m_bShowMouse = false;
+ }
+ }
+
+ if (CPad::GetPad(0)->GetLeftMouseJustUp()) {
+ // The coordinates in aScreens->MENUPAGE_MAP.
+ if (m_nMousePosX > MENU_X_LEFT_ALIGNED(60.0f) && m_nMousePosX < MENU_X_LEFT_ALIGNED(140.0f)) {
+ if (m_nMousePosY > MENU_Y(375.0f) && m_nMousePosY < MENU_Y(400.0f)) {
+ m_nHoverOption = HOVEROPTION_RANDOM_ITEM;
+ goBack = true;
+ }
+ }
+ }
+
+ if (CPad::GetPad(0)->GetLeftMouse() && m_nMousePosX > m_nMouseOldPosX || CPad::GetPad(0)->GetRight() ||
+ CPad::GetPad(0)->GetDPadRight() || CPad::GetPad(0)->GetAnalogueLeftRight() > 0) {
+ if (CTimer::GetTimeInMillisecondsPauseMode() - lastMapTick > 10) {
+ if (m_fMapSize > MENU_X(MAP_SIZE_TO_ALLOW_X_MOVE) && SCREEN_WIDTH/2 - (m_fMapSize - MENU_X(MAP_MIN_SIZE)) < m_fMapCenterX)
+ m_fMapCenterX -= MENU_X(15.f);
+ m_bShowMouse = false;
+ }
+ }
+ }
+
+
+ if (CTimer::GetTimeInMillisecondsPauseMode() - lastMapTick > 10)
+ lastMapTick = CTimer::GetTimeInMillisecondsPauseMode();
+
+#ifndef MAP_ENHANCEMENTS
+ if (CPad::GetPad(0)->GetLeftMouseJustUp())
+ CentreMousePointer();
#endif
-#ifdef PC_PLAYER_CONTROLS
- TheCamera.m_bUseMouse3rdPerson = m_ControlMethod == CONTROL_STANDARD;
+
+ if (CPad::GetPad(0)->GetLeftMouse()) {
+ if (m_nMousePosX < SCREEN_STRETCH_X(20.0f) || m_nMousePosX > SCREEN_STRETCH_X(620.0f) || m_nMousePosY < SCREEN_STRETCH_Y(20.0f) || m_nMousePosY > SCREEN_STRETCH_Y(428.0f)) {
+#ifdef MAP_ENHANCEMENTS
+ justResetPointer = true;
#endif
- 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();
- }
+ CentreMousePointer();
+ }
+ }
+ if (!CPad::GetPad(0)->GetLeftMouse() && !m_bShowMouse && (m_nMouseOldPosX != m_nMousePosX || m_nMouseOldPosY != m_nMousePosY)) {
+ m_bShowMouse = true;
+ }
- ProcessButtonPresses();
+ static bool pressedL = false;
- // Set binding keys.
- if (pEditString && CPad::EditString(pEditString, 0) == nil) {
- if (*pEditString == 0)
- strcpy(pEditString, "NoName");
- pEditString = nil;
- SaveSettings();
+ if (!CPad::GetPad(0)->GetChar('L') && !CPad::GetPad(0)->GetChar('l')) {
+ pressedL = false;
+ }
+
+ if (!pressedL) {
+ if (CPad::GetPad(0)->GetChar('L') || CPad::GetPad(0)->GetChar('l')) {
+ m_PrefsShowLegends = !m_PrefsShowLegends;
+ pressedL = true;
+ }
+ }
+ break;
}
+ case MENUPAGE_SOUND_SETTINGS:
+ if (CheckHover(MENU_X_LEFT_ALIGNED(177.f), MENU_X_LEFT_ALIGNED(238.f), MENU_Y(MENURADIO_SELECTOR_START_Y - 13.f), MENU_Y(MENURADIO_SELECTOR_START_Y + MENURADIO_SELECTOR_HEIGHT - 8.f))) {
+ m_nHoverOption = HOVEROPTION_PREV_RADIO;
+ }
- 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 = rsMOUSELEFTBUTTON;
- else if (CPad::GetPad(0)->GetRightMouseJustUp())
- MouseButtonJustClicked = rsMOUSERIGHTBUTTON;
- else if (CPad::GetPad(0)->GetMiddleMouseJustUp())
- MouseButtonJustClicked = rsMOUSMIDDLEBUTTON;
- else if (CPad::GetPad(0)->GetMouseWheelUpJustUp())
- MouseButtonJustClicked = rsMOUSEWHEELUPBUTTON;
- else if (CPad::GetPad(0)->GetMouseWheelDownJustUp())
- MouseButtonJustClicked = rsMOUSEWHEELDOWNBUTTON;
- else if (CPad::GetPad(0)->GetMouseX1JustUp())
- MouseButtonJustClicked = rsMOUSEX1BUTTON;
- else if (CPad::GetPad(0)->GetMouseX2JustUp())
- MouseButtonJustClicked = rsMOUSEX2BUTTON;
-
- 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_SETTING_CHANGE, 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 (CheckHover(MENU_X_LEFT_ALIGNED(422.f), MENU_X_LEFT_ALIGNED(491.f), MENU_Y(MENURADIO_SELECTOR_START_Y - 13.f), MENU_Y(MENURADIO_SELECTOR_START_Y + MENURADIO_SELECTOR_HEIGHT - 8.f))) {
+ m_nHoverOption = HOVEROPTION_NEXT_RADIO;
+ }
+ break;
+ case MENUPAGE_STATS:
+ {
+ if (CPad::GetPad(0)->GetMouseWheelUpJustDown() || CPad::GetPad(0)->GetMouseWheelUpJustUp() || CPad::GetPad(0)->GetUp() ||
+ CPad::GetPad(0)->GetDPadUp() || CPad::GetPad(0)->GetAnalogueUpDown() < 0) {
+
+ m_StatsScrollSpeed = 20.0f;
+ m_StatsScrollDirection = 0;
+
+ } else if (CPad::GetPad(0)->GetMouseWheelDownJustDown() || CPad::GetPad(0)->GetMouseWheelDownJustUp() || CPad::GetPad(0)->GetDown() ||
+ CPad::GetPad(0)->GetDPadDown() || CPad::GetPad(0)->GetAnalogueUpDown() > 0) {
+
+ m_StatsScrollSpeed = 20.0f;
+ m_StatsScrollDirection = 1;
+
+ } else if (CPad::GetPad(0)->GetChar(' ')) {
+ m_StatsScrollSpeed = 0.0f;
+ } else
+ m_StatsScrollSpeed = 150.0f;
+
+ static bool pressedS = false;
+
+ if (!CPad::GetPad(0)->GetChar('S') && !CPad::GetPad(0)->GetChar('s')) {
+ pressedS = false;
+ }
+
+ if (!pressedS) {
+ if (CPad::GetPad(0)->GetChar('S') || CPad::GetPad(0)->GetChar('s')) {
+ ExportStats();
+ m_nHelperTextMsgId = 4;
+ m_nHelperTextAlpha = 300;
+ pressedS = true;
}
}
+ break;
}
+ }
+}
- if ((m_nCurrScreen == MENUPAGE_NO_MEMORY_CARD || m_nCurrScreen == MENUPAGE_PS2_LOAD_FAILED) && CTimer::GetTimeInMillisecondsPauseMode() > field_558) {
- m_nCurrScreen = m_nPrevScreen;
- m_nCurrOption = 0;
+// Not original name
+void
+CMenuManager::ExportStats()
+{
+ char date[10];
+ CFileMgr::SetDirMyDocuments();
+ _strdate(date);
+ wchar *lastMission = TheText.Get(CStats::LastMissionPassedName[0] == '\0' ? "ITBEG" : CStats::LastMissionPassedName);
+ FILE *txtFile = fopen("stats.txt", "w");
+
+ if (txtFile) {
+ int statLines = CStats::ConstructStatLine(99999);
+ fprintf(txtFile, "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n");
+ fprintf(txtFile, "\t\t\tGTA VICE CITY %s\n", UnicodeToAscii(TheText.Get("FEH_STA")));
+ fprintf(txtFile, "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n\n\n");
+ fprintf(txtFile, "%s: ", UnicodeToAscii(TheText.Get("FES_CMI")));
+ fprintf(txtFile, "%s\n", UnicodeToAscii(lastMission));
+ fprintf(txtFile, "%s: ", UnicodeToAscii(TheText.Get("FES_DAT")));
+ fprintf(txtFile, "%s\n\n\n", date);
+ fprintf(txtFile, "%s ", UnicodeToAscii(TheText.Get("CRIMRA")));
+ UnicodeStrcpy(gUString, CStats::FindCriminalRatingString());
+ fprintf(txtFile, "%s (%d)\n\n\n", UnicodeToAscii(gUString), CStats::FindCriminalRatingNumber());
+ for (int i = 0; i < statLines; ++i) {
+ CStats::ConstructStatLine(i);
+ char *statKey = UnicodeToAscii(gUString);
+ if (statKey[0] != '\0')
+ fprintf(txtFile, "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n%s\n", statKey);
+
+ char *statValue = UnicodeToAscii(gUString2);
+ for (int j = 0; statValue[j] != '\0'; ++j) {
+ if (statValue[j] == '_')
+ statValue[j] = '\xBA'; // This is degree symbol, but my editors keeps messing up with it so I wrote hex representation
+ }
+ if (statValue)
+ fprintf(txtFile, "%s\n\n", statValue);
}
+ fprintf(txtFile, "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n\n");
+ }
+ fclose(txtFile);
+ FILE *htmlFile = fopen("stats.html", "w");
+ if (htmlFile) {
+ int statLines = CStats::ConstructStatLine(99999);
+ fprintf(htmlFile, "<title>Grand Theft Auto Vice City Stats</title>\n");
+ fprintf(htmlFile, "<body bgcolor=\"#FF00CC\" leftmargin=\"10\" topmargin=\"10\" marginwidth=\"10\" marginheight=\"10\">\n");
+ fprintf(htmlFile, "<table width=\"560\" align=\"center\" border=\"0\" cellpadding=\"5\" cellspacing=\"0\">\n");
+ fprintf(htmlFile, "<tr align=\"center\" valign=\"top\"> \n");
+ fprintf(htmlFile, "<td height=\"59\" colspan=\"2\" bgcolor=\"#FFCCFF\"><div align=\"center\"><font color=\"#FF00CC\" size=\"3\" "
+ "face=\"Arial, \n");
+ fprintf(htmlFile, "Helvetica, sans-serif\">-------------------------------------------------------------------------</font><font \n");
+ fprintf(htmlFile, "size=\"3\" face=\"Arial, Helvetica, sans-serif\"><br>\n");
+ fprintf(htmlFile, "<strong><font color=\"#000000\">GRAND THEFT AUTO VICE CITY ");
+ fprintf(htmlFile, "%s</font></strong><br><font\n", UnicodeToAscii(TheText.Get("FEH_STA")));
+ fprintf(htmlFile, "color=\"#FF00CC\">-------------------------------------------------------------------------</font></font></div></td> </tr>\n");
+ fprintf(htmlFile, "<tr align=\"left\" valign=\"top\" bgcolor=\"#FFFFFF\"> <td height=\"22\" colspan=\"2\">&nbsp;</td> </tr>\n");
+ fprintf(htmlFile, "<tr align=\"left\" valign=\"top\" bgcolor=\"#FFFFFF\"> \n");
+ fprintf(htmlFile,
+ "<td height=\"40\" colspan=\"2\"> <p><font color=\"#00CC00\" size=\"2\" face=\"Arial, Helvetica, sans-serif\">"
+ "<strong><font color=\"#009900\" size=\"1\">%s: \n", UnicodeToAscii(TheText.Get("FES_DAT")));
+ fprintf(htmlFile, "%s</font><br> %s: </strong>", date, UnicodeToAscii(TheText.Get("FES_CMI")));
+ fprintf(htmlFile, "%s<strong><br></strong> </font></p></td></tr>\n", UnicodeToAscii(lastMission));
+ fprintf(htmlFile, "<tr align=\"left\" valign=\"top\" bgcolor=\"#CCCCCC\"> <td height=\"5\" colspan=\"2\"></td> </tr> <tr align=\""
+ "left\" valign=\"top\" bgcolor=\"#FFFFFF\"> \n");
+ fprintf(htmlFile, "<td height=\"10\" colspan=\"2\"></td> </tr> <tr align=\"left\" valign=\"top\" bgcolor=\"#FFFFFF\"> \n");
+ fprintf(htmlFile, "<td height=\"20\" colspan=\"2\"><font color=\"#FF00CC\" size=\"2\" face=\"Arial, Helvetica, sans-serif\"><str"
+ "ong>%s</strong>\n", UnicodeToAscii(TheText.Get("CRIMRA")));
+
+ UnicodeStrcpy(gUString, CStats::FindCriminalRatingString());
+ char *statKey = UnicodeToAscii(gUString);
+ int rating = CStats::FindCriminalRatingNumber();
+ fprintf(htmlFile, "%s (%d)</font></td> </tr> <tr align=\"left\" valign=\"top\" bgcolor=\"#FFFFFF\"><td height=\"10\" colspan=\""
+ "2\"></td> </tr>\n", statKey, rating);
+
+ for (int k = 0; k < statLines; ++k) {
+ CStats::ConstructStatLine(k);
+ statKey = UnicodeToAscii(gUString);
+ if (statKey[0] != '\0')
+ fprintf(htmlFile, "</font></strong></div></td> </tr> <tr align=\"left\" valign=\"top\" bgcolor=\"#FFFFFF\"> <td height=\"10"
+ "\" colspan=\"2\"></td> </tr>\n");
+
+ fprintf(htmlFile, "<tr align=\"left\" valign=\"top\"><td width=\"500\" height=\"22\" bgcolor=\"#FFCCFF\"><font color=\"#FF00CC"
+ "\" size=\"2\" face=\"Arial, Helvetica, sans-serif\"><strong>\n");
+
+ if (statKey[0] != '\0')
+ fprintf(htmlFile, "%s", statKey);
+ else
+ fprintf(htmlFile, " ");
+
+ fprintf(htmlFile, "</strong></font></td> <td width=\"500\" align=\"right\" valign=\"middle\" bgcolor=\"#FFCCFF\"> <div align=\""
+ "right\"><strong><font color=\"#FF00CC\">\n");
- // Reset pad shaking.
- if (TimeToStopPadShaking && TimeToStopPadShaking < CTimer::GetTimeInMillisecondsPauseMode()) {
- CPad::StopPadsShaking();
- TimeToStopPadShaking = 0;
+ char *statValue = UnicodeToAscii(gUString2);
+ for (int l = 0; statValue[l] != '\0'; ++l) {
+ if (statValue[l] == '_')
+ statValue[l] = '\xBA'; // This is degree symbol, but my editors keeps messing up with it so I wrote hex representation
+ }
+ if (statValue)
+ fprintf(htmlFile, "%s", statValue);
+ else
+ fprintf(htmlFile, " ");
}
+ fprintf(htmlFile, "</font></strong></div></td> </tr> <tr align=\"left\" valign=\"top\" bgcolor=\"#FFFFFF\"> <td height=\"10\" c"
+ "olspan=\"2\"></td> </tr>\n");
+ fprintf(htmlFile, "</table><br><table width=\"560\" border=\"0\" align=\"center\" cellspacing=\"0\" cellpadding=\"5\"><tr align"
+ "=\"center\" valign=\"middle\" bgcolor=\"#FFCCFF\">");
+ fprintf(htmlFile, "<td><font color=\"#000000\" size=\"2\" face=\"Arial, Helvetica, sans-serif\"><a href=\"http://www.rockstargam"
+ "es.com/vicecity\">rockstargames.com/vicecity</a></font></td>\n");
+ fprintf(htmlFile, "<td><font color=\"#000000\" size=\"2\" face=\"Arial, Helvetica, sans-serif\"><a href=\"http://www.rockstargam"
+ "es.com\">rockstargames.com</a></font></td>\n");
+ fprintf(htmlFile, "<td><font color=\"#000000\" size=\"2\" face=\"Arial, Helvetica, sans-serif\">&nbsp;<a href=\"http://www.rocks"
+ "tarnorth.com\">rockstarnorth.com</a></font></td></tr>\n");
+ fprintf(htmlFile, "</table>\n</body>\n");
+ }
+ fclose(htmlFile);
+ CFileMgr::SetDir("");
+}
+// Original name is unknown
+void
+CMenuManager::PrintRadioSelector(void)
+{
+ static uint32 lastRadioChange = 0;
+
+ CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(418.f), MENU_Y(MENURADIO_SELECTOR_START_Y + MENURADIO_SELECTOR_HEIGHT),
+ MENU_X_LEFT_ALIGNED(228.f), MENU_Y(MENURADIO_SELECTOR_START_Y + MENURADIO_SELECTOR_HEIGHT),
+ MENU_X_LEFT_ALIGNED(428.f), MENU_Y(MENURADIO_SELECTOR_START_Y),
+ MENU_X_LEFT_ALIGNED(238.f), MENU_Y(MENURADIO_SELECTOR_START_Y), CRGBA(RADIO_SELECTOR_COLOR.r, RADIO_SELECTOR_COLOR.g, RADIO_SELECTOR_COLOR.b, FadeIn(180)));
+
+ int rightMostSprite, rightMostStation;
+ if (DMAudio.IsMP3RadioChannelAvailable()) {
+ rightMostSprite = MENUSPRITE_MP3;
+ rightMostStation = USERTRACK;
} else {
- UnloadTextures();
- m_bRenderGameInMenu = false;
- // byte_5F33E4 = 1; // unused
- ChangeScreen(MENUPAGE_NONE, 0, false, false);
- pEditString = nil;
- m_bWaitingForNewKeyBind = false;
+ rightMostSprite = MENUSPRITE_WAVE;
+ rightMostStation = WAVE;
+ }
+ #ifdef THIS_IS_STUPID
+
+ // First radio
+ if (m_ScrollRadioBy == 1) {
+ if (m_PrefsRadioStation == 1) {
+ m_aFrontEndSprites[rightMostSprite].Draw(m_LeftMostRadioX, MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE),
+ CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a)));
+ } else if ( m_PrefsRadioStation == 0) {
+ m_aFrontEndSprites[rightMostSprite - 1].Draw(m_LeftMostRadioX, MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE),
+ CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a)));
+ } else {
+ m_aFrontEndSprites[m_PrefsRadioStation + MENUSPRITE_WILDSTYLE - 2].Draw(m_LeftMostRadioX, MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE),
+ CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a)));
+ }
+ }
+
+ // Second
+ if (m_PrefsRadioStation == 0) {
+ m_aFrontEndSprites[rightMostSprite].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE),
+ CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a)));
+ } else {
+ m_aFrontEndSprites[m_PrefsRadioStation + MENUSPRITE_WILDSTYLE - 1].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE),
+ MENU_Y(MENURADIO_ICON_SIZE), CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a)));
+ }
+
+ // Third (middle)
+ int prevStation = m_PrefsRadioStation - 1;
+ if (prevStation == rightMostStation) {
+ m_aFrontEndSprites[MENUSPRITE_WILDSTYLE + 1].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 3), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE),
+ CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a)));
+ } else if ( prevStation == rightMostStation - 1) {
+ m_aFrontEndSprites[MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 3), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE),
+ CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a)));
+ } else {
+ m_aFrontEndSprites[m_PrefsRadioStation + MENUSPRITE_WILDSTYLE + 1].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 3), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE),
+ CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a)));
+ }
+
+ // Fifth
+ if (m_ScrollRadioBy == -1) {
+ int prevStation = m_PrefsRadioStation - 1;
+ if (prevStation == rightMostStation) {
+ m_aFrontEndSprites[MENUSPRITE_WILDSTYLE + 4].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 4), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE),
+ CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a)));
+ } else if (prevStation == rightMostStation - 1) {
+ m_aFrontEndSprites[MENUSPRITE_WILDSTYLE + 1].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 4), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE),
+ CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a)));
+ } else if ( prevStation == rightMostStation - 2) {
+ m_aFrontEndSprites[MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 4), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE),
+ CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a)));
+ } else {
+ m_aFrontEndSprites[m_PrefsRadioStation + MENUSPRITE_WILDSTYLE + 2].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 4), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE),
+ CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a)));
+ }
+ }
+
+ // Fourth
+ if (m_ScrollRadioBy == 0) {
+ m_aFrontEndSprites[m_PrefsRadioStation + MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 2 - 10.f), MENU_Y(MENURADIO_ICON_Y - 10.f), MENU_X(MENURADIO_ICON_SIZE) + MENU_X(20.f), MENU_Y(MENURADIO_ICON_SIZE) + MENU_Y(20.f),
+ CRGBA(255, 255, 255, FadeIn(255)));
+ } else {
+ if (m_PrefsRadioStation - 1 == rightMostStation) {
+ m_aFrontEndSprites[MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 2), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE),
+ CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a)));
+ } else {
+ m_aFrontEndSprites[m_PrefsRadioStation + MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 2), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE),
+ CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a)));
+ }
+ }
+#else
+ int first = ((m_PrefsRadioStation - 2) + rightMostStation + 1) % (rightMostStation + 1);
+ int second = ((m_PrefsRadioStation - 1) + rightMostStation + 1) % (rightMostStation + 1);
+ int third = ((m_PrefsRadioStation) + rightMostStation + 1) % (rightMostStation + 1);
+ int fourth = ((m_PrefsRadioStation + 1) + rightMostStation + 1) % (rightMostStation + 1);
+ int fifth = ((m_PrefsRadioStation + 2) + rightMostStation + 1) % (rightMostStation + 1);
+
+ // First one is only drawn on transition to next
+ if (m_ScrollRadioBy == 1) {
+ m_aFrontEndSprites[first + MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX, MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE),
+ CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a)));
+ }
+
+ // Second
+ m_aFrontEndSprites[second + MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE),
+ CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a)));
+
+ // Fourth
+ m_aFrontEndSprites[fourth + MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 3), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE),
+ CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a)));
+
+ // Fifth one is only drawn on transition to prev.
+ if (m_ScrollRadioBy == -1) {
+ m_aFrontEndSprites[fifth + MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 4), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE),
+ CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a)));
}
- if (!m_bWantToRestart) {
- if (m_bGameNotLoaded)
- DMAudio.Service();
+ // Middle one(third) is colored differently depending on if it's in transition.
+ // If not in transition then this icon indicates selected radio, and should be on top of all icons. thus drawn last
+ if (m_ScrollRadioBy != 0) {
+ m_aFrontEndSprites[third + MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 2), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE),
+ CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a)));
+ } else {
+ m_aFrontEndSprites[third + MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 2 - 10.f), MENU_Y(MENURADIO_ICON_Y - 10.f), MENU_X(MENURADIO_ICON_SIZE) + MENU_X(20.f), MENU_Y(MENURADIO_ICON_SIZE) + MENU_Y(20.f),
+ CRGBA(255, 255, 255, FadeIn(255)));
+ }
+#endif
+
+ static bool radioChangeRequested = false;
+ static uint32 lastScrollCheck = 0;
+ if (CTimer::GetTimeInMillisecondsPauseMode() - lastScrollCheck > 17) {
+ if (m_ScrollRadioBy == 1) {
+ if (m_LeftMostRadioX > MENU_X_LEFT_ALIGNED(MENURADIO_ICON_FIRST_X - MENURADIO_ICON_SIZE)) {
+ m_LeftMostRadioX -= MENU_X(6.f);
+ } else {
+ m_ScrollRadioBy = 0;
+ lastRadioChange = CTimer::GetTimeInMillisecondsPauseMode();
+ radioChangeRequested = true;
+ }
+ }
+ if (m_ScrollRadioBy == -1) {
+ if (m_LeftMostRadioX < MENU_X_LEFT_ALIGNED(MENURADIO_ICON_FIRST_X - MENURADIO_ICON_SIZE)) {
+ m_LeftMostRadioX += MENU_X(6.f);
+ } else {
+ m_ScrollRadioBy = 0;
+ lastRadioChange = CTimer::GetTimeInMillisecondsPauseMode();
+ radioChangeRequested = true;
+ }
+ }
+ lastScrollCheck = CTimer::GetTimeInMillisecondsPauseMode();
+ }
+ // Background behind arrows
+ CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(228.f), MENU_Y(MENURADIO_SELECTOR_START_Y + MENURADIO_SELECTOR_HEIGHT),
+ MENU_X_LEFT_ALIGNED(168.f), MENU_Y(MENURADIO_SELECTOR_START_Y + MENURADIO_SELECTOR_HEIGHT),
+ MENU_X_LEFT_ALIGNED(238.f), MENU_Y(MENURADIO_SELECTOR_START_Y),
+ MENU_X_LEFT_ALIGNED(178.f), MENU_Y(MENURADIO_SELECTOR_START_Y),
+ CRGBA(RADIO_SELECTOR_COLOR.r, RADIO_SELECTOR_COLOR.g, RADIO_SELECTOR_COLOR.b, FadeIn(255)));
+
+ CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(478.f), MENU_Y(MENURADIO_SELECTOR_START_Y + MENURADIO_SELECTOR_HEIGHT),
+ MENU_X_LEFT_ALIGNED(418.f), MENU_Y(MENURADIO_SELECTOR_START_Y + MENURADIO_SELECTOR_HEIGHT),
+ MENU_X_LEFT_ALIGNED(488.f), MENU_Y(MENURADIO_SELECTOR_START_Y),
+ MENU_X_LEFT_ALIGNED(428.f), MENU_Y(MENURADIO_SELECTOR_START_Y),
+ CRGBA(RADIO_SELECTOR_COLOR.r, RADIO_SELECTOR_COLOR.g, RADIO_SELECTOR_COLOR.b, FadeIn(255)));
+
+ // Arrows and their shadows
+ CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(216.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 48.f), MENU_X_LEFT_ALIGNED(196.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 36.f), MENU_X_LEFT_ALIGNED(216.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 22.f), MENU_X_LEFT_ALIGNED(196.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 36.f), CRGBA(0, 0, 0, FadeIn(255)));
+ CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(213.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 45.f), MENU_X_LEFT_ALIGNED(193.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 33.f), MENU_X_LEFT_ALIGNED(213.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 19.f), MENU_X_LEFT_ALIGNED(193.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 33.f), CRGBA(97, 194, 247, FadeIn(255)));
+ CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(440.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 48.f), MENU_X_LEFT_ALIGNED(460.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 36.f), MENU_X_LEFT_ALIGNED(440.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 22.f), MENU_X_LEFT_ALIGNED(460.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 36.f), CRGBA(0, 0, 0, FadeIn(255)));
+ CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(443.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 45.f), MENU_X_LEFT_ALIGNED(463.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 33.f), MENU_X_LEFT_ALIGNED(443.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 19.f), MENU_X_LEFT_ALIGNED(463.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 33.f), CRGBA(97, 194, 247, FadeIn(255)));
+ if (radioChangeRequested) {
+ if (CTimer::GetTimeInMillisecondsPauseMode() - lastRadioChange > 50) {
+ DMAudio.SetRadioInCar(m_PrefsRadioStation);
+ DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
+ OutputDebugString("FRONTEND RADIO STATION CHANGED");
+ lastRadioChange = CTimer::GetTimeInMillisecondsPauseMode();
+ radioChangeRequested = false;
+ }
}
}
+// Original name is unknown
void
-CMenuManager::ProcessButtonPresses(void)
+CMenuManager::ProcessList(bool &optionSelected, bool &goBack)
{
- if (pEditString || pControlEdit)
+ if (m_bWaitingForNewKeyBind)
return;
+ if (m_nCurrScreen == MENUPAGE_SKIN_SELECT) {
+ m_nTotalListRow = m_nSkinsTotal;
+ }
+ if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) {
+ // GetNumOptionsCntrlConfigScreens would have been a better choice
+ m_nTotalListRow = m_ControlMethod == CONTROL_CLASSIC ? 32 : 27;
+ if (m_nSelectedListRow > m_nTotalListRow)
+ m_nSelectedListRow = m_nTotalListRow - 1;
+ }
+
+ if (CPad::GetPad(0)->GetEnterJustDown() || CPad::GetPad(0)->GetCrossJustDown()) {
+ m_bShowMouse = 0;
+ optionSelected = true;
+ }
+ 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;
+ m_bStartWaitingForKeyBind = true;
+ m_bKeyChangeNotProcessed = true;
+ pControlEdit = &m_KeyPressedCode;
+ }
+ } else {
+ field_159 = false;
+ }
+
+ static uint32 lastTimeClickedScrollButton = 0;
+
+ if (CTimer::GetTimeInMillisecondsPauseMode() - lastTimeClickedScrollButton >= 200) {
+ m_bPressedPgUpOnList = false;
+ m_bPressedPgDnOnList = false;
+ m_bPressedUpOnList = false;
+ m_bPressedDownOnList = false;
+ m_bPressedScrollButton = false;
+ lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
+ }
+
+ if (CPad::GetPad(0)->GetTabJustDown()) {
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_HIGHLIGHT_OPTION, 0);
+ m_bShowMouse = false;
+ switch (m_nCurrExLayer) {
+ case HOVEROPTION_BACK:
+ default:
+ m_nCurrExLayer = HOVEROPTION_LIST;
+ break;
+ case HOVEROPTION_LIST:
+ m_nCurrExLayer = HOVEROPTION_USESKIN;
+ break;
+ case HOVEROPTION_USESKIN:
+ m_nCurrExLayer = HOVEROPTION_BACK;
+ }
+ if (((m_nCurrScreen == MENUPAGE_SKIN_SELECT) && (m_nCurrExLayer == HOVEROPTION_USESKIN)) && strcmp(m_aSkinName, m_PrefsSkinFile) == 0) {
+ m_nCurrExLayer = HOVEROPTION_BACK;
+ }
+ if ((m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) && (m_nCurrExLayer == HOVEROPTION_USESKIN)) {
+ m_nCurrExLayer = HOVEROPTION_BACK;
+ }
+ }
+
+ bool pressed = false;
+ if (CPad::GetPad(0)->GetUp() || CPad::GetPad(0)->GetAnaloguePadUp() || CPad::GetPad(0)->GetDPadUpJustDown()) {
+ m_bShowMouse = false;
+ pressed = true;
+ } else if (CPad::GetPad(0)->GetMouseWheelUpJustUp()) {
+ m_bShowMouse = true;
+ pressed = true;
+ }
+
+ // Up
+ if (pressed) {
+ m_nCurrExLayer = HOVEROPTION_LIST;
+ if (!m_bPressedUpOnList) {
+ m_bPressedUpOnList = true;
+ lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_HIGHLIGHT_OPTION, 0);
+ ScrollUpListByOne();
+ }
+ } else {
+ m_bPressedUpOnList = false;
+ }
+
+ pressed = false;
+ if (CPad::GetPad(0)->GetDown() || CPad::GetPad(0)->GetAnaloguePadDown() || CPad::GetPad(0)->GetDPadDownJustDown()) {
+ m_bShowMouse = false;
+ pressed = true;
+ } else if (CPad::GetPad(0)->GetMouseWheelDownJustDown()) {
+ m_bShowMouse = true;
+ pressed = true;
+ }
+
+ // Down
+ if (pressed) {
+ m_nCurrExLayer = HOVEROPTION_LIST;
+ if (!m_bPressedDownOnList) {
+ m_bPressedDownOnList = true;
+ lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_HIGHLIGHT_OPTION, 0);
+ ScrollDownListByOne();
+ }
+ } else {
+ m_bPressedDownOnList = false;
+ }
+
+ if (m_nCurrScreen != MENUPAGE_KEYBOARD_CONTROLS) {
+ if (!CPad::GetPad(0)->GetPageUp()) {
+ m_bPressedPgUpOnList = false;
+ } else {
+ m_nCurrExLayer = HOVEROPTION_LIST;
+ if (!m_bPressedPgUpOnList) {
+ m_bPressedPgUpOnList = true;
+ lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
+ m_bShowMouse = false;
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_HIGHLIGHT_OPTION, 0);
+ PageUpList(false);
+ }
+ }
+ if (!CPad::GetPad(0)->GetPageDown()) {
+ m_bPressedPgDnOnList = false;
+ } else {
+ m_nCurrExLayer = HOVEROPTION_LIST;
+ if (!m_bPressedPgDnOnList) {
+ m_bPressedPgDnOnList = true;
+ lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
+ m_bShowMouse = false;
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_HIGHLIGHT_OPTION, 0);
+ PageDownList(false);
+ }
+ }
+ if (CPad::GetPad(0)->GetHome()) {
+ m_nCurrExLayer = HOVEROPTION_LIST;
+ m_bShowMouse = false;
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_HIGHLIGHT_OPTION, 0);
+ if (m_nTotalListRow >= MAX_VISIBLE_OPTION_ON_SCREEN) {
+ m_nFirstVisibleRowOnList = 0;
+ }
+ m_nSelectedListRow = 0;
+ m_nScrollbarTopMargin = (SCROLLBAR_MAX_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList;
+ }
+ if (CPad::GetPad(0)->GetEnd()) {
+ m_nCurrExLayer = HOVEROPTION_LIST;
+ m_bShowMouse = false;
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_HIGHLIGHT_OPTION, 0);
+ if (m_nTotalListRow >= MAX_VISIBLE_OPTION_ON_SCREEN) {
+ m_nFirstVisibleRowOnList = m_nTotalListRow - MAX_VISIBLE_OPTION_ON_SCREEN;
+ }
+ m_nSelectedListRow = m_nTotalListRow - 1;
+ m_nScrollbarTopMargin = (SCROLLBAR_MAX_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList;
+ }
+ }
+
+ if (CPad::GetPad(0)->GetEscapeJustDown() || CPad::GetPad(0)->GetBackJustDown()) {
+ m_bShowMouse = false;
+ goBack = true;
+ }
+
+ if (CPad::GetPad(0)->GetLeftMouseJustDown()) {
+ switch (m_nHoverOption) {
+ case HOVEROPTION_BACK:
+ goBack = true;
+ break;
+ case HOVEROPTION_PAGEUP:
+ PageUpList(true);
+ break;
+ case HOVEROPTION_PAGEDOWN:
+ PageDownList(true);
+ break;
+ case HOVEROPTION_USESKIN:
+ if (m_nSkinsTotal > 0) {
+ m_pSelectedSkin = m_pSkinListHead.nextSkin;
+ strcpy(m_PrefsSkinFile, m_aSkinName);
+ CWorld::Players[0].SetPlayerSkin(m_PrefsSkinFile);
+ SaveSettings();
+ }
+ }
+ }
+
+ if (CPad::GetPad(0)->GetLeftMouseJustDown()) {
+ switch (m_nHoverOption) {
+ case HOVEROPTION_OVER_SCROLL_UP:
+ m_nHoverOption = HOVEROPTION_CLICKED_SCROLL_UP;
+ break;
+ case HOVEROPTION_OVER_SCROLL_DOWN:
+ m_nHoverOption = HOVEROPTION_CLICKED_SCROLL_DOWN;
+ break;
+ case HOVEROPTION_LIST:
+ m_nHoverOption = HOVEROPTION_SKIN;
+ }
+ } else if ((CPad::GetPad(0)->GetLeftMouseJustUp())
+ && ((m_nHoverOption == HOVEROPTION_CLICKED_SCROLL_UP || (m_nHoverOption == HOVEROPTION_CLICKED_SCROLL_DOWN)))) {
+ m_nHoverOption = HOVEROPTION_NOT_HOVERING;
+ }
+
+ if (!CPad::GetPad(0)->GetLeftMouse()) {
+ holdingScrollBar = false;
+ } else {
+ if ((m_nHoverOption == HOVEROPTION_HOLDING_SCROLLBAR) || holdingScrollBar) {
+ holdingScrollBar = true;
+ // TODO: This part is a bit hard to reverse. Not much code tho
+ assert(0 && "Holding scrollbar isn't done yet");
+ } else {
+ switch (m_nHoverOption) {
+ case HOVEROPTION_OVER_SCROLL_UP:
+ case HOVEROPTION_CLICKED_SCROLL_UP:
+ if (!m_bPressedScrollButton) {
+ m_bPressedScrollButton = true;
+ lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
+ ScrollUpListByOne();
+ }
+ break;
+ case HOVEROPTION_OVER_SCROLL_DOWN:
+ case HOVEROPTION_CLICKED_SCROLL_DOWN:
+ if (!m_bPressedScrollButton) {
+ m_bPressedScrollButton = true;
+ lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
+ ScrollDownListByOne();
+ }
+ break;
+ default:
+ m_bPressedScrollButton = false;
+ }
+ }
+ }
+}
+
+void
+CMenuManager::UserInput(void)
+{
bool goBack = false;
bool optionSelected = false;
bool goUp = false;
bool goDown = false;
-#ifdef TIDY_UP_PBP
- bool assumeIncrease = false;
+ int8 changeValueBy;
+
+ if (!m_AllowNavigation && m_firstStartCounter == 255)
+ m_AllowNavigation = true;
+ if (!m_bShowMouse && m_nCurrScreen != MENUPAGE_MAP && (m_nMouseOldPosX != m_nMousePosX || m_nMouseOldPosY != m_nMousePosY)) {
+ m_bShowMouse = true;
+ }
+
+ static int oldOption = -99;
+ oldOption = m_nCurrOption;
+#ifdef SCROLLABLE_PAGES
+ int firstOption = SCREEN_HAS_AUTO_SCROLLBAR ? m_nFirstVisibleRowOnList : 0;
+ int scrollOffset = aScreens[m_nCurrScreen].m_aEntries[firstOption].m_Y - aScreens[m_nCurrScreen].m_aEntries[0].m_Y;
+ for (int rowToCheck = firstOption; rowToCheck < firstOption + MAX_VISIBLE_OPTION && rowToCheck < NUM_MENUROWS; ++rowToCheck) {
+#else
+ for (int rowToCheck = 0; rowToCheck < NUM_MENUROWS; ++rowToCheck) {
#endif
+ if (aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Action == MENUACTION_NOTHING ||
+ aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Action == MENUACTION_LABEL)
+ continue;
-#ifdef USE_DEBUG_SCRIPT_LOADER
- if (m_nCurrScreen == MENUPAGE_START_MENU || m_nCurrScreen == MENUPAGE_NEW_GAME || m_nCurrScreen == MENUPAGE_NEW_GAME_RELOAD) {
- if (CPad::GetPad(0)->GetChar('R')) {
- CTheScripts::ScriptToLoad = 1;
- DoSettingsBeforeStartingAGame();
- return;
+ // unused: CFont::GetStringWidth(TheText.Get(aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_EntryName), true);
+ // So they also wanted the compare X, but they abandoned the idea later on
+
+ if (m_nMousePosY > MENU_Y(aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Y MINUS_SCROLL_OFFSET) &&
+ m_nMousePosY < MENU_Y(aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Y MINUS_SCROLL_OFFSET PLUS_LINE_HEIGHT_ON_SCREEN)) {
+ static int oldScreen = m_nCurrScreen;
+
+ m_nOptionMouseHovering = rowToCheck;
+ if (m_nMouseOldPosX != m_nMousePosX || m_nMouseOldPosY != m_nMousePosY) {
+ m_nCurrOption = rowToCheck;
+ m_bShowMouse = true;
+ }
+
+ int action = aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Action;
+ if (action != MENUACTION_BRIGHTNESS && action != MENUACTION_DRAWDIST && action != MENUACTION_MUSICVOLUME
+ && action != MENUACTION_SFXVOLUME && action != MENUACTION_MOUSESENS && action != MENUACTION_MP3VOLUMEBOOST
+#ifdef CUSTOM_FRONTEND_OPTIONS
+ && action != MENUACTION_CFO_SLIDER
+#endif
+ )
+ m_nHoverOption = HOVEROPTION_RANDOM_ITEM;
+
+ break;
}
- if (CPad::GetPad(0)->GetChar('D')) {
- CTheScripts::ScriptToLoad = 2;
- DoSettingsBeforeStartingAGame();
- return;
+ if (m_bShowMouse && m_nMenuFadeAlpha == 255) {
+ m_nOptionMouseHovering = oldOption;
+ m_nCurrOption = oldOption;
}
}
-#endif
- if (!m_bShowMouse && (m_nMouseOldPosX != m_nMousePosX || m_nMouseOldPosY != m_nMousePosY)) {
- m_bShowMouse = true;
+ if (m_bShowMouse) {
+ if (oldOption != m_nCurrOption) {
+ if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_LABEL) {
+ ++m_nCurrOption;
+ ++m_nOptionMouseHovering;
+ }
+ m_nOptionHighlightTransitionBlend = 0;
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_HIGHLIGHT_OPTION, 0);
+ }
}
m_nMouseOldPosX = m_nMousePosX;
@@ -4335,33 +4354,25 @@ CMenuManager::ProcessButtonPresses(void)
if (m_nMousePosY < 0) m_nMousePosY = 0;
if (m_nMousePosY > SCREEN_HEIGHT) m_nMousePosY = SCREEN_HEIGHT;
+ changeValueBy = 0;
if (hasNativeList(m_nCurrScreen)) {
- // Not split to seperate function in III as in VC, but we need it for scrollable pages :)
- ProcessList(goBack, optionSelected);
-
- } else if (isPlainTextScreen(m_nCurrScreen)) {
-#ifndef TIDY_UP_PBP
- if (CPad::GetPad(0)->GetEnterJustDown() || CPad::GetPad(0)->GetCrossJustDown() || CPad::GetPad(0)->GetLeftMouseJustDown()) {
- optionSelected = true;
- }
- if (CPad::GetPad(0)->GetEscapeJustDown() || CPad::GetPad(0)->GetBackJustUp()) {
- if (m_nCurrScreen != MENUPAGE_START_MENU) {
- goBack = true;
- }
- }
-#endif
+ ProcessList(optionSelected, goBack);
} else {
- if (CPad::GetPad(0)->GetDownJustDown() || CPad::GetPad(0)->GetAnaloguePadDown() || CPad::GetPad(0)->GetDPadDownJustDown()) {
+ AdditionalOptionInput(goBack);
+
+ if (m_AllowNavigation &&
+ (CPad::GetPad(0)->GetDownJustDown() || CPad::GetPad(0)->GetAnaloguePadDown() || CPad::GetPad(0)->GetDPadDownJustDown())) {
m_bShowMouse = false;
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0);
goDown = true;
- } else if (CPad::GetPad(0)->GetUpJustDown() || CPad::GetPad(0)->GetAnaloguePadUp() || CPad::GetPad(0)->GetDPadUpJustDown()) {
+ m_nOptionHighlightTransitionBlend = 0;
+
+ } else if (m_AllowNavigation &&
+ (CPad::GetPad(0)->GetUpJustDown() || CPad::GetPad(0)->GetAnaloguePadUp() || CPad::GetPad(0)->GetDPadUpJustDown())) {
m_bShowMouse = false;
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0);
goUp = true;
+ m_nOptionHighlightTransitionBlend = 0;
}
-#ifndef TIDY_UP_PBP
if ((m_nCurrOption == 0) && (m_nCurrScreen == MENUPAGE_PAUSE_MENU)) {
if (CPad::GetPad(0)->GetEnterJustUp() || CPad::GetPad(0)->GetCrossJustUp()) {
m_bShowMouse = false;
@@ -4373,245 +4384,43 @@ CMenuManager::ProcessButtonPresses(void)
optionSelected = true;
}
}
-#endif
- if (CPad::GetPad(0)->GetLeftMouseJustUp()) {
-#ifndef TIDY_UP_PBP
- if (((m_nCurrOption == 0) && (m_nCurrScreen == MENUPAGE_PAUSE_MENU)) &&
-#else
- if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_RESUME &&
-#endif
- (m_nHoverOption == HOVEROPTION_RANDOM_ITEM)) {
- m_nCurrOption = m_nOptionMouseHovering;
- optionSelected = true;
- }
- } else if (CPad::GetPad(0)->GetLeftMouseJustDown()) {
-#ifdef TIDY_UP_PBP
- if (m_nHoverOption >= HOVEROPTION_RADIO_0 && m_nHoverOption <= HOVEROPTION_RADIO_9) {
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- m_PrefsRadioStation = m_nHoverOption - HOVEROPTION_RADIO_0;
- SaveSettings();
- DMAudio.SetRadioInCar(m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
- OutputDebugString("FRONTEND RADIO STATION CHANGED");
- } else if (m_nHoverOption == HOVEROPTION_RANDOM_ITEM
- && aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action != MENUACTION_RESUME) {
- m_nCurrOption = m_nOptionMouseHovering;
+ if (CPad::GetPad(0)->GetLeftMouseJustUp() && m_nCurrScreen != MENUPAGE_MAP) {
+ if (m_nHoverOption == HOVEROPTION_RANDOM_ITEM)
optionSelected = true;
- }
-#else
- switch (m_nHoverOption) {
- case HOVEROPTION_RADIO_0:
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- m_PrefsRadioStation = HEAD_RADIO;
- SaveSettings();
- DMAudio.SetRadioInCar(m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
- OutputDebugString("FRONTEND RADIO STATION CHANGED");
- break;
- case HOVEROPTION_RADIO_1:
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- m_PrefsRadioStation = DOUBLE_CLEF;
- SaveSettings();
- DMAudio.SetRadioInCar(m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
- OutputDebugString("FRONTEND RADIO STATION CHANGED");
- break;
- case HOVEROPTION_RADIO_2:
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- m_PrefsRadioStation = JAH_RADIO;
- SaveSettings();
- DMAudio.SetRadioInCar(m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
- OutputDebugString("FRONTEND RADIO STATION CHANGED");
- break;
- case HOVEROPTION_RADIO_3:
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- m_PrefsRadioStation = RISE_FM;
- SaveSettings();
- DMAudio.SetRadioInCar(m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
- OutputDebugString("FRONTEND RADIO STATION CHANGED");
- break;
- case HOVEROPTION_RADIO_4:
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- m_PrefsRadioStation = LIPS_106;
- SaveSettings();
- DMAudio.SetRadioInCar(m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
- OutputDebugString("FRONTEND RADIO STATION CHANGED");
- break;
- case HOVEROPTION_RADIO_5:
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- m_PrefsRadioStation = GAME_FM;
- SaveSettings();
- DMAudio.SetRadioInCar(m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
- OutputDebugString("FRONTEND RADIO STATION CHANGED");
- break;
- case HOVEROPTION_RADIO_6:
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- m_PrefsRadioStation = MSX_FM;
- SaveSettings();
- DMAudio.SetRadioInCar(m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
- OutputDebugString("FRONTEND RADIO STATION CHANGED");
- break;
- case HOVEROPTION_RADIO_7:
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- m_PrefsRadioStation = FLASHBACK;
- SaveSettings();
- DMAudio.SetRadioInCar(m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
- OutputDebugString("FRONTEND RADIO STATION CHANGED");
- break;
- case HOVEROPTION_RADIO_8:
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- m_PrefsRadioStation = CHATTERBOX;
- SaveSettings();
- DMAudio.SetRadioInCar(m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
- OutputDebugString("FRONTEND RADIO STATION CHANGED");
- break;
- case HOVEROPTION_RADIO_9:
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- m_PrefsRadioStation = USERTRACK;
- SaveSettings();
- DMAudio.SetRadioInCar(m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
- OutputDebugString("FRONTEND RADIO STATION CHANGED");
- break;
- case HOVEROPTION_RANDOM_ITEM:
- if (((m_nCurrOption != 0) || (m_nCurrScreen != MENUPAGE_PAUSE_MENU)) {
- m_nCurrOption = m_nOptionMouseHovering;
- optionSelected = true;
- }
- break;
- }
-#endif
+ else if (m_nHoverOption == HOVEROPTION_NEXT_RADIO)
+ ChangeRadioStation(1);
+ else if (m_nHoverOption == HOVEROPTION_PREV_RADIO)
+ ChangeRadioStation(-1);
}
if (CPad::GetPad(0)->GetLeftMouse()) {
-#ifndef TIDY_UP_PBP
switch (m_nHoverOption) {
case HOVEROPTION_INCREASE_BRIGHTNESS:
- m_PrefsBrightness = m_PrefsBrightness + (512 / MENUSLIDER_LOGICAL_BARS);
- if (m_PrefsBrightness < 0) {
- m_PrefsBrightness = 0;
- }
- if (510 < m_PrefsBrightness) {
- m_PrefsBrightness = 511;
- }
- SaveSettings();
- break;
- case HOVEROPTION_DECREASE_BRIGHTNESS:
- m_PrefsBrightness = m_PrefsBrightness - (512 / MENUSLIDER_LOGICAL_BARS);
- if (m_PrefsBrightness < 0) {
- m_PrefsBrightness = 0;
- }
- if (510 < m_PrefsBrightness) {
- m_PrefsBrightness = 511;
- }
- SaveSettings();
- break;
+ case HOVEROPTION_INCREASE_MP3BOOST:
case HOVEROPTION_INCREASE_DRAWDIST:
- m_PrefsLOD = m_PrefsLOD + (1.0f / MENUSLIDER_LOGICAL_BARS);
- m_PrefsLOD = min(1.8f, m_PrefsLOD);
- CRenderer::ms_lodDistScale = m_PrefsLOD;
- SaveSettings();
- break;
- case HOVEROPTION_DECREASE_DRAWDIST:
- m_PrefsLOD = m_PrefsLOD - (1.0f / MENUSLIDER_LOGICAL_BARS);
- m_PrefsLOD = max(0.8f, m_PrefsLOD);
- CRenderer::ms_lodDistScale = m_PrefsLOD;
- SaveSettings();
- break;
case HOVEROPTION_INCREASE_MUSICVOLUME:
- m_PrefsMusicVolume = m_PrefsMusicVolume + (128 / MENUSLIDER_LOGICAL_BARS);
- m_PrefsMusicVolume = Clamp(m_PrefsMusicVolume, 0, 127);
- DMAudio.SetMusicMasterVolume(uchar)(m_PrefsMusicVolume);
- SaveSettings();
- break;
- case HOVEROPTION_DECREASE_MUSICVOLUME:
- m_PrefsMusicVolume = m_PrefsMusicVolume - (128 / MENUSLIDER_LOGICAL_BARS);
- if (m_PrefsMusicVolume < 0) {
- m_PrefsMusicVolume = 0;
- }
- if (126 < m_PrefsMusicVolume) {
- m_PrefsMusicVolume = 127;
- }
- DMAudio.SetMusicMasterVolume(uchar)(m_PrefsMusicVolume);
- SaveSettings();
- break;
case HOVEROPTION_INCREASE_SFXVOLUME:
- m_PrefsSFXVolume = m_PrefsSFXVolume + (128 / MENUSLIDER_LOGICAL_BARS);
- if (m_PrefsSFXVolume < 0) {
- m_PrefsSFXVolume = 0;
- }
- if (126 < m_PrefsSFXVolume) {
- m_PrefsSFXVolume = 127;
- }
- DMAudio.SetEffectsMasterVolume(uchar)(m_PrefsSFXVolume);
- SaveSettings();
- break;
- case HOVEROPTION_DECREASE_SFXVOLUME:
- m_PrefsSFXVolume = m_PrefsSFXVolume - (128 / MENUSLIDER_LOGICAL_BARS);
- if (m_PrefsSFXVolume < 0) {
- m_PrefsSFXVolume = 0;
- }
- if (126 < m_PrefsSFXVolume) {
- m_PrefsSFXVolume = 127;
- }
- DMAudio.SetEffectsMasterVolume(uchar)(m_PrefsSFXVolume);
- SaveSettings();
- break;
case HOVEROPTION_INCREASE_MOUSESENS:
- TheCamera.m_fMouseAccelHorzntl += 1.0f/200.0f/15.0f; // probably because diving it to 15 instead of 16(MENUSLIDER_LOGICAL_BARS) had more accurate steps
- TheCamera.m_fMouseAccelHorzntl = Clamp(TheCamera.m_fMouseAccelHorzntl, 1.0f / 3200, 1.0f / 200);
-#ifdef FIX_BUGS
- TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl + 0.0005f;
-#else
- TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl;
+#ifdef CUSTOM_FRONTEND_OPTIONS
+ case HOVEROPTION_INCREASE_CFO_SLIDER:
#endif
- SaveSettings();
+ CheckSliderMovement(1);
break;
+ case HOVEROPTION_DECREASE_BRIGHTNESS:
+ case HOVEROPTION_DECREASE_MP3BOOST:
+ case HOVEROPTION_DECREASE_DRAWDIST:
+ case HOVEROPTION_DECREASE_MUSICVOLUME:
+ case HOVEROPTION_DECREASE_SFXVOLUME:
case HOVEROPTION_DECREASE_MOUSESENS:
- TheCamera.m_fMouseAccelHorzntl -= 1.0f/200.0f/15.0f; // probably because diving it to 15 instead of 16(MENUSLIDER_LOGICAL_BARS) had more accurate steps
- TheCamera.m_fMouseAccelHorzntl = Clamp(TheCamera.m_fMouseAccelHorzntl, 1.0f / 3200, 1.0f / 200);
-#ifdef FIX_BUGS
- TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl + 0.0005f;
-#else
- TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl;
-#endif
- SaveSettings();
- break;
- }
-#else
- switch (m_nHoverOption) {
- case HOVEROPTION_INCREASE_BRIGHTNESS:
- case HOVEROPTION_INCREASE_DRAWDIST:
- case HOVEROPTION_INCREASE_MUSICVOLUME:
- case HOVEROPTION_INCREASE_SFXVOLUME:
- case HOVEROPTION_INCREASE_MOUSESENS:
#ifdef CUSTOM_FRONTEND_OPTIONS
- case HOVEROPTION_INCREASE_CFO_SLIDER:
+ case HOVEROPTION_DECREASE_CFO_SLIDER:
#endif
- CheckSliderMovement(1);
- break;
- case HOVEROPTION_DECREASE_BRIGHTNESS:
- case HOVEROPTION_DECREASE_DRAWDIST:
- case HOVEROPTION_DECREASE_MUSICVOLUME:
- case HOVEROPTION_DECREASE_SFXVOLUME:
- case HOVEROPTION_DECREASE_MOUSESENS:
-#ifdef CUSTOM_FRONTEND_OPTIONS
- case HOVEROPTION_DECREASE_CFO_SLIDER:
-#endif
- CheckSliderMovement(-1);
- break;
+ CheckSliderMovement(-1);
+ break;
}
-#endif
}
-
+
#ifdef SCROLLABLE_PAGES
if (m_nTotalListRow > MAX_VISIBLE_OPTION) {
bool temp = false;
@@ -4625,40 +4434,40 @@ CMenuManager::ProcessButtonPresses(void)
goUp = false;
goDown = false;
m_nCurrOption = m_nSelectedListRow;
+
+ if (oldOption != m_nCurrOption)
+ m_nOptionHighlightTransitionBlend = 0;
}
// Prevent sound on scroll. Mouse wheel is now belongs to us!
if (!(m_nTotalListRow > MAX_VISIBLE_OPTION && (CPad::GetPad(0)->GetMouseWheelUpJustDown() || CPad::GetPad(0)->GetMouseWheelDownJustDown())))
#endif
-
if (CPad::GetPad(0)->GetLeftMouseJustUp() || CPad::GetPad(0)->GetLeftJustUp() || CPad::GetPad(0)->GetRightJustUp()
|| CPad::GetPad(0)->GetDPadLeftJustUp() || CPad::GetPad(0)->GetDPadRightJustUp()
|| CPad::GetPad(0)->GetAnaloguePadLeftJustUp() || CPad::GetPad(0)->GetAnaloguePadRightJustUp()
|| CPad::GetPad(0)->GetMouseWheelUpJustDown() || CPad::GetPad(0)->GetMouseWheelDownJustDown()) {
int option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action;
- if (option == MENUACTION_BRIGHTNESS || option == MENUACTION_DRAWDIST
+ if (option == MENUACTION_BRIGHTNESS
#ifdef CUSTOM_FRONTEND_OPTIONS
|| option == MENUACTION_CFO_SLIDER
#endif
)
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_ENTER_OR_ADJUST, 0);
else if (option == MENUACTION_SFXVOLUME)
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_AUDIO_TEST, 0);
- else if (option == MENUACTION_MOUSESENS)
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
+ else if (option == MENUACTION_DRAWDIST || option == MENUACTION_MOUSESENS)
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_ENTER_OR_ADJUST, 0);
}
-
-#ifndef TIDY_UP_PBP
- if (CPad::GetPad(0)->GetBackJustDown()) {
- if (m_nCurrScreen != MENUPAGE_START_MENU && m_nCurrScreen != MENUPAGE_PAUSE_MENU) {
- m_bShowMouse = false;
- goBack = true;
- }
- }
-
- if (CPad::GetPad(0)->GetEscapeJustDown()) {
- if (m_nCurrScreen != MENUPAGE_START_MENU) {
+ if (CPad::GetPad(0)->GetBackJustDown() || CPad::GetPad(0)->GetEscapeJustDown()) {
+ if (m_nCurrScreen != MENUPAGE_START_MENU && m_nCurrScreen != MENUPAGE_PAUSE_MENU && m_nCurrScreen != MENUPAGE_CHOOSE_SAVE_SLOT
+ && m_nCurrScreen != MENUPAGE_SAVE_CHEAT_WARNING && m_nCurrScreen != MENUPAGE_SAVING_IN_PROGRESS
+ && m_nCurrScreen != MENUPAGE_DELETING_IN_PROGRESS && m_nCurrScreen != MENUPAGE_OUTRO
+#ifdef MISSION_REPLAY
+ && m_nCurrScreen != MENUPAGE_MISSION_RETRY
+#endif
+ )
+ {
m_bShowMouse = false;
goBack = true;
}
@@ -4667,92 +4476,193 @@ CMenuManager::ProcessButtonPresses(void)
if (((goDown) || (goUp)) || (optionSelected)) {
goBack = false;
}
-#endif
+
}
- // Centralized enter/back (except some conditions)
-#ifdef TIDY_UP_PBP
- if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action != MENUACTION_RESUME) {
- if (CPad::GetPad(0)->GetEnterJustDown() || CPad::GetPad(0)->GetCrossJustDown() ||
- (isPlainTextScreen(m_nCurrScreen) && CPad::GetPad(0)->GetLeftMouseJustDown())) {
+ int curAction = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action;
+ if (CPad::GetPad(0)->GetLeft() || CPad::GetPad(0)->GetPedWalkLeftRight() < 0 || CPad::GetPad(0)->GetDPadLeft()) {
+ static uint32 lastSliderDecrease = 0;
+ if (CTimer::GetTimeInMillisecondsPauseMode() - lastSliderDecrease > 150) {
+ if (curAction == MENUACTION_BRIGHTNESS || curAction == MENUACTION_MUSICVOLUME ||
+ curAction == MENUACTION_SFXVOLUME || curAction == MENUACTION_RADIO ||
+ curAction == MENUACTION_DRAWDIST || curAction == MENUACTION_MOUSESENS ||
+ curAction == MENUACTION_MP3VOLUMEBOOST
+#ifdef CUSTOM_FRONTEND_OPTIONS
+ || curAction == MENUACTION_CFO_SLIDER
+#endif
+ )
+ changeValueBy = -1;
- if (!isPlainTextScreen(m_nCurrScreen))
- m_bShowMouse = false;
+ lastSliderDecrease = CTimer::GetTimeInMillisecondsPauseMode();
+ }
+ } else if (CPad::GetPad(0)->GetRight() || CPad::GetPad(0)->GetPedWalkLeftRight() > 0 || CPad::GetPad(0)->GetDPadRight()) {
+ static uint32 lastSliderIncrease = 0;
+ if (CTimer::GetTimeInMillisecondsPauseMode() - lastSliderIncrease > 150) {
+ if (curAction == MENUACTION_BRIGHTNESS || curAction == MENUACTION_MUSICVOLUME ||
+ curAction == MENUACTION_SFXVOLUME || curAction == MENUACTION_RADIO ||
+ curAction == MENUACTION_DRAWDIST || curAction == MENUACTION_MOUSESENS ||
+ curAction == MENUACTION_MP3VOLUMEBOOST
+#ifdef CUSTOM_FRONTEND_OPTIONS
+ || curAction == MENUACTION_CFO_SLIDER
+#endif
+ )
+ changeValueBy = 1;
+ lastSliderIncrease = CTimer::GetTimeInMillisecondsPauseMode();
+ }
+ }
- optionSelected = true;
+#ifdef SCROLLABLE_PAGES
+ if (!SCREEN_HAS_AUTO_SCROLLBAR)
+#endif
+ {
+ if (CPad::GetPad(0)->GetMouseWheelUpJustDown()) {
+ changeValueBy = 1;
+ } else if (CPad::GetPad(0)->GetMouseWheelDownJustDown()) {
+ changeValueBy = -1;
}
- } else {
- if (CPad::GetPad(0)->GetEnterJustUp() || CPad::GetPad(0)->GetCrossJustUp()) {
+ }
+
+ if (m_AllowNavigation) {
+ if (CPad::GetPad(0)->GetRightJustDown() || CPad::GetPad(0)->GetAnaloguePadRight() || CPad::GetPad(0)->GetDPadRightJustDown()) {
m_bShowMouse = false;
- optionSelected = true;
+ changeValueBy = 1;
}
}
- if (!goDown && !goUp && !optionSelected) {
- if (m_nCurrScreen != MENUPAGE_START_MENU) {
- if (isPlainTextScreen(m_nCurrScreen)) {
- if (CPad::GetPad(0)->GetEscapeJustDown() || CPad::GetPad(0)->GetBackJustUp()) {
- goBack = true;
- }
- } else {
- if (CPad::GetPad(0)->GetEscapeJustDown() || (m_nCurrScreen != MENUPAGE_PAUSE_MENU && CPad::GetPad(0)->GetBackJustDown())) {
- m_bShowMouse = false;
- goBack = true;
- }
+ if (m_AllowNavigation) {
+ if (CPad::GetPad(0)->GetLeftJustDown() || CPad::GetPad(0)->GetAnaloguePadLeft() || CPad::GetPad(0)->GetDPadLeftJustDown()) {
+ m_bShowMouse = false;
+ changeValueBy = -1;
+ }
+ }
+ if (changeValueBy != 0) {
+ if ((m_nCurrScreen == MENUPAGE_SOUND_SETTINGS || m_nCurrScreen == MENUPAGE_DISPLAY_SETTINGS || m_nCurrScreen == MENUPAGE_CONTROLLER_PC || m_nCurrScreen == MENUPAGE_MOUSE_CONTROLS)
+ && aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action != MENUACTION_NOTHING
+ && aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action != MENUACTION_LABEL
+ && aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action != MENUACTION_YES
+ && aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action != MENUACTION_NO
+ && aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action != MENUACTION_CHANGEMENU
+ && aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action != MENUACTION_KEYBOARDCTRLS
+ && aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action != MENUACTION_GOBACK
+ && aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action != MENUACTION_RESTOREDEF
+ && aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action != MENUACTION_DRAWDIST
+ && aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action != MENUACTION_MOUSESENS
+ && aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action != MENUACTION_MP3VOLUMEBOOST) {
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_ENTER_OR_ADJUST, 0);
+ }
+ }
+ ProcessUserInput(goDown, goUp, optionSelected, goBack, changeValueBy);
+#ifdef CUSTOM_FRONTEND_OPTIONS
+ if (aScreens[m_nCurrScreen].m_aEntries[oldOption].m_Action < MENUACTION_NOTHING) { // CFO check
+ CMenuScreenCustom::CMenuEntry &oldEntry = aScreens[m_nCurrScreen].m_aEntries[oldOption];
+ if (m_nCurrOption != oldOption) {
+ if (oldEntry.m_Action == MENUACTION_CFO_DYNAMIC)
+ if(oldEntry.m_CFODynamic->buttonPressFunc)
+ oldEntry.m_CFODynamic->buttonPressFunc(FEOPTION_ACTION_FOCUSLOSS);
+
+ if (oldEntry.m_Action == MENUACTION_CFO_SELECT && oldEntry.m_CFOSelect->onlyApplyOnEnter) {
+ if (oldEntry.m_CFOSelect->displayedValue != oldEntry.m_CFOSelect->lastSavedValue)
+ SetHelperText(3); // Restored original value
+
+ oldEntry.m_CFOSelect->displayedValue = oldEntry.m_CFOSelect->lastSavedValue = *(int8*)oldEntry.m_CFO->value;
}
+ } else if (oldEntry.m_Action == MENUACTION_CFO_SELECT && oldEntry.m_CFOSelect->onlyApplyOnEnter) {
+ if (oldEntry.m_CFOSelect->displayedValue != *(int8*)oldEntry.m_CFO->value)
+ SetHelperText(1); // Enter to apply
+ else if (m_nHelperTextMsgId == 1)
+ ResetHelperText(); // Applied
}
}
#endif
+}
-#ifdef PS2_LIKE_MENU
- if (CPad::GetPad(0)->GetLeftMouseJustDown() && hoveredBottomBarOption != -1) {
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0);
- bottomBarActive = false;
- curBottomBarOption = hoveredBottomBarOption;
- ChangeScreen(bbNames[curBottomBarOption].screenId, 0, true, false);
- if (bbNames[curBottomBarOption].screenId == MENUPAGE_SOUND_SETTINGS)
- DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
+void
+CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, uint8 goBack, int8 changeAmount)
+{
+ if (m_nCurrScreen == MENUPAGE_OUTRO)
return;
- } else if (bottomBarActive) {
- if (CPad::GetPad(0)->GetEnterJustDown() || CPad::GetPad(0)->GetCrossJustDown()) {
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0);
- bottomBarActive = false;
- if (bbNames[curBottomBarOption].screenId == MENUPAGE_SOUND_SETTINGS)
- DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
+ 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 = rsMOUSELEFTBUTTON;
+ else if (CPad::GetPad(0)->GetRightMouseJustUp())
+ MouseButtonJustClicked = rsMOUSERIGHTBUTTON;
+ else if (CPad::GetPad(0)->GetMiddleMouseJustUp())
+ MouseButtonJustClicked = rsMOUSMIDDLEBUTTON;
+ else if (CPad::GetPad(0)->GetMouseWheelUpJustUp())
+ MouseButtonJustClicked = rsMOUSEWHEELUPBUTTON;
+ else if (CPad::GetPad(0)->GetMouseWheelDownJustUp())
+ MouseButtonJustClicked = rsMOUSEWHEELDOWNBUTTON;
+ else if (CPad::GetPad(0)->GetMouseX1JustUp())
+ MouseButtonJustClicked = rsMOUSEX1BUTTON;
+ else if (CPad::GetPad(0)->GetMouseX2JustUp())
+ MouseButtonJustClicked = rsMOUSEX2BUTTON;
+
+ JoyButtonJustClicked = ControlsManager.GetJoyButtonJustDown();
+
+ int32 TypeOfControl = KEYBOARD;
+ if (JoyButtonJustClicked)
+ TypeOfControl = JOYSTICK;
+ if (MouseButtonJustClicked)
+ TypeOfControl = MOUSE;
+ if (*pControlEdit != rsNULL)
+ TypeOfControl = KEYBOARD;
+
+ if (!m_bKeyIsOK) {
+ pControlEdit = nil;
+ m_bWaitingForNewKeyBind = false;
+ m_KeyPressedCode = -1;
+ m_bStartWaitingForKeyBind = false;
+ } else if (!m_bKeyChangeNotProcessed) {
+ if (*pControlEdit != rsNULL || MouseButtonJustClicked || JoyButtonJustClicked)
+ CheckCodesForControls(TypeOfControl);
- return;
- } else if (CPad::GetPad(0)->GetLeftJustDown() || CPad::GetPad(0)->GetAnaloguePadLeft() || CPad::GetPad(0)->GetDPadLeftJustDown()
- || CPad::GetPad(0)->GetUpJustDown() || CPad::GetPad(0)->GetAnaloguePadUp() || CPad::GetPad(0)->GetDPadUpJustDown()) {
+ field_159 = true;
+ } else {
+ for (int i = 0; i < 4; i++)
+ ControlsManager.ClearSettingsAssociatedWithAction((e_ControllerAction)m_CurrCntrlAction, (eControllerType)i);
+ m_bKeyIsOK = false;
+ m_bKeyChangeNotProcessed = false;
+ }
+ }
+ }
- m_bShowMouse = false;
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0);
- curBottomBarOption = ((curBottomBarOption + bbTabCount) - 1) % bbTabCount;
- ChangeScreen(bbNames[curBottomBarOption].screenId, 0, true, true);
- return;
- } else if (CPad::GetPad(0)->GetRightJustDown() || CPad::GetPad(0)->GetAnaloguePadRight() || CPad::GetPad(0)->GetDPadRightJustDown()
- || CPad::GetPad(0)->GetDownJustDown() || CPad::GetPad(0)->GetAnaloguePadDown() || CPad::GetPad(0)->GetDPadDownJustDown()) {
+ if (pEditString || pControlEdit)
+ return;
- m_bShowMouse = false;
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0);
- curBottomBarOption = ((curBottomBarOption + bbTabCount) + 1) % bbTabCount;
- ChangeScreen(bbNames[curBottomBarOption].screenId, 0, true, true);
+#ifdef USE_DEBUG_SCRIPT_LOADER
+ if (m_nCurrScreen == MENUPAGE_START_MENU || m_nCurrScreen == MENUPAGE_NEW_GAME || m_nCurrScreen == MENUPAGE_NEW_GAME_RELOAD) {
+ if (CPad::GetPad(0)->GetChar('R')) {
+ CTheScripts::ScriptToLoad = 1;
+ DoSettingsBeforeStartingAGame();
return;
}
- optionSelected = false;
- goDown = false;
- goUp = false;
}
#endif
- int prevOption = m_nCurrOption;
- if (goDown && (m_nCurrScreen != MENUPAGE_MULTIPLAYER_FIND_GAME)) {
+ int oldOption = m_nCurrOption;
+ if (goDown) {
+ if (m_nCurrScreen != MENUPAGE_MAP)
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_HIGHLIGHT_OPTION, 0);
+
m_nCurrOption++;
if (m_nCurrOption == NUM_MENUROWS || (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_NOTHING)) {
m_nCurrOption = 0;
}
+ if (oldOption != m_nCurrOption)
+ m_nOptionHighlightTransitionBlend = 0;
}
- if (goUp && (m_nCurrScreen != MENUPAGE_MULTIPLAYER_FIND_GAME)) {
+ if (goUp) {
+ if (m_nCurrScreen != MENUPAGE_MAP)
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_HIGHLIGHT_OPTION, 0);
+
if (m_nCurrOption == (aScreens[m_nCurrScreen].m_aEntries[0].m_Action == MENUACTION_LABEL)) {
while (m_nCurrOption != NUM_MENUROWS - 1
&& aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption + 1].m_Action != MENUACTION_NOTHING) {
@@ -4761,634 +4671,418 @@ CMenuManager::ProcessButtonPresses(void)
} else {
m_nCurrOption--;
}
+ if (oldOption != m_nCurrOption)
+ m_nOptionHighlightTransitionBlend = 0;
}
- // Hide back button
-#ifdef PS2_LIKE_MENU
- if ((goUp || goDown) && m_nCurrScreen != MENUPAGE_MULTIPLAYER_FIND_GAME && strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEDS_TB") == 0)
- m_nCurrOption = goUp ? m_nCurrOption - 1 : (aScreens[m_nCurrScreen].m_aEntries[0].m_Action == MENUACTION_LABEL);
-#endif
-
- if (optionSelected) {
- int option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action;
- if ((option == MENUACTION_CHANGEMENU) || (option == MENUACTION_POPULATESLOTS_CHANGEMENU)) {
- if (strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEDS_TB") != 0 &&
- strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FESZ_CA") != 0) {
-
- if (m_nCurrScreen == MENUPAGE_CHOOSE_DELETE_SLOT) {
- if (Slots[aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_SaveSlot - 1] == SLOT_EMPTY)
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_FAIL, 0);
- else
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- } else
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0);
- } else {
- // This is duplicate, back button already processed below
-#ifndef TIDY_UP_PBP
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_EXIT, 0);
- if (m_nCurrScreen == MENUPAGE_SOUND_SETTINGS) {
- DMAudio.StopFrontEndTrack();
- OutputDebugString("FRONTEND AUDIO TRACK STOPPED");
- }
-#endif
- }
- } else if (option == MENUACTION_CHECKSAVE) {
- if (Slots[aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_SaveSlot - 1] == SLOT_EMPTY) {
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_FAIL, 0);
- } else {
- if (m_nCurrScreen != MENUPAGE_NEW_GAME_RELOAD) {
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- }
- }
- } else if (option != MENUACTION_CHANGEMENU && option != MENUACTION_BRIGHTNESS && option != MENUACTION_DRAWDIST
- && option != MENUACTION_MUSICVOLUME && option != MENUACTION_SFXVOLUME
- && option != MENUACTION_CHECKSAVE && option != MENUACTION_UNK24
- && option != MENUACTION_MOUSESENS && option != MENUACTION_SCREENRES
-#ifdef CUSTOM_FRONTEND_OPTIONS
- && option != MENUACTION_CFO_SLIDER
-#endif
- )
- {
-
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- }
-
- if ((m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) || (m_nCurrScreen == MENUPAGE_SKIN_SELECT)) {
+ if (optionSelected && m_nMenuFadeAlpha == 255) {
+ if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu == MENUPAGE_NEW_GAME_RELOAD && m_bGameNotLoaded) {
+ DoSettingsBeforeStartingAGame();
+ } else if (hasNativeList(m_nCurrScreen)) {
switch (m_nCurrExLayer) {
- default:
- goBack = true;
- break;
- case HOVEROPTION_LIST:
- if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) {
- m_bWaitingForNewKeyBind = true;
- m_bStartWaitingForKeyBind = true;
- pControlEdit = &m_KeyPressedCode;
- }
- if (m_nCurrScreen == MENUPAGE_SKIN_SELECT) {
- strcpy(m_PrefsSkinFile, m_aSkinName);
- CWorld::Players[0].SetPlayerSkin(m_PrefsSkinFile);
- m_nCurrExLayer = HOVEROPTION_BACK;
- SaveSettings();
- }
- m_nHoverOption = HOVEROPTION_NOT_HOVERING;
- break;
- case HOVEROPTION_USESKIN:
- m_nHoverOption = HOVEROPTION_NOT_HOVERING;
+ case HOVEROPTION_LIST:
+ if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) {
+ m_bWaitingForNewKeyBind = true;
+ m_bStartWaitingForKeyBind = true;
+ pControlEdit = &m_KeyPressedCode;
+ }
+ if (m_nCurrScreen == MENUPAGE_SKIN_SELECT) {
strcpy(m_PrefsSkinFile, m_aSkinName);
CWorld::Players[0].SetPlayerSkin(m_PrefsSkinFile);
m_nCurrExLayer = HOVEROPTION_BACK;
SaveSettings();
- break;
+ }
+ m_nHoverOption = HOVEROPTION_NOT_HOVERING;
+ break;
+ case HOVEROPTION_USESKIN:
+ m_nHoverOption = HOVEROPTION_NOT_HOVERING;
+ strcpy(m_PrefsSkinFile, m_aSkinName);
+ CWorld::Players[0].SetPlayerSkin(m_PrefsSkinFile);
+ m_nCurrExLayer = HOVEROPTION_BACK;
+ SaveSettings();
+ break;
+ case HOVEROPTION_BACK:
+ default:
+ goBack = true;
+ break;
}
- } else if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu == MENUPAGE_NEW_GAME_RELOAD && m_bGameNotLoaded) {
- DoSettingsBeforeStartingAGame();
-/* } else if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) {
- // .. either empty or there was some outer if. :shrug: pointless anyway, keyboard_controls is handled in first if.
-*/
- } else if (m_nCurrScreen == MENUPAGE_SKIN_SELECT) {
if (m_nSkinsTotal > 0) {
m_pSelectedSkin = m_pSkinListHead.nextSkin;
strcpy(m_PrefsSkinFile, m_aSkinName);
CWorld::Players[0].SetPlayerSkin(m_PrefsSkinFile);
SaveSettings();
- } else {
-#ifndef TIDY_UP_PBP
- ChangeScreen(!m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_PreviousPage[1] : aScreens[m_nCurrScreen].m_PreviousPage[0],
- GetPreviousPageOption(), true, true);
-#else
- goBack = true;
-#endif
}
- } else if (m_nCurrScreen != MENUPAGE_MULTIPLAYER_FIND_GAME) {
- option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action;
- switch (option) {
- case MENUACTION_RADIO:
-#ifdef TIDY_UP_PBP
- assumeIncrease = true;
-#else
- ++m_PrefsRadioStation;
- if (DMAudio.IsMP3RadioChannelAvailable()) {
- if (m_PrefsRadioStation > USERTRACK)
- m_PrefsRadioStation = HEAD_RADIO;
- } else if (m_PrefsRadioStation > CHATTERBOX) {
- m_PrefsRadioStation = USERTRACK;
- }
- SaveSettings();
- DMAudio.SetRadioInCar(m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
- OutputDebugString("FRONTEND RADIO STATION CHANGED");
-#endif
- break;
- case MENUACTION_LANG_ENG:
- m_PrefsLanguage = LANGUAGE_AMERICAN;
- m_bFrontEnd_ReloadObrTxtGxt = true;
- InitialiseChangedLanguageSettings();
- SaveSettings();
- break;
- case MENUACTION_LANG_FRE:
- m_PrefsLanguage = LANGUAGE_FRENCH;
- m_bFrontEnd_ReloadObrTxtGxt = true;
- InitialiseChangedLanguageSettings();
- SaveSettings();
- break;
- case MENUACTION_LANG_GER:
- m_PrefsLanguage = LANGUAGE_GERMAN;
- m_bFrontEnd_ReloadObrTxtGxt = true;
- InitialiseChangedLanguageSettings();
- SaveSettings();
- break;
- case MENUACTION_LANG_ITA:
- m_PrefsLanguage = LANGUAGE_ITALIAN;
- m_bFrontEnd_ReloadObrTxtGxt = true;
- InitialiseChangedLanguageSettings();
- SaveSettings();
- break;
- case MENUACTION_LANG_SPA:
- m_PrefsLanguage = LANGUAGE_SPANISH;
- m_bFrontEnd_ReloadObrTxtGxt = true;
- InitialiseChangedLanguageSettings();
- SaveSettings();
- break;
- case MENUACTION_POPULATESLOTS_CHANGEMENU:
- PcSaveHelper.PopulateSlotInfo();
-
- // fall through
- case MENUACTION_CHANGEMENU:
- {
- bool changeMenu = true;
- int saveSlot = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_SaveSlot;
-
- // This should be unused.
- if (saveSlot >= 2 && saveSlot <= 9) {
- m_nCurrSaveSlot = saveSlot - 2;
- switch (m_nCurrScreen) {
- case MENUPAGE_CHOOSE_LOAD_SLOT:
- if (Slots[m_nCurrSaveSlot + 1] != SLOT_EMPTY)
- changeMenu = false;
-
- break;
- case MENUPAGE_CHOOSE_DELETE_SLOT:
- if (Slots[m_nCurrSaveSlot + 1] == SLOT_EMPTY)
- changeMenu = false;
+ }
- break;
+ int option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action;
+#ifdef FIX_BUGS
+ int currScreen = m_nCurrScreen;
+ int currOption = m_nCurrOption;
+#endif
+ switch (option) {
+ case MENUACTION_CHANGEMENU:
+ case MENUACTION_YES:
+ case MENUACTION_NO:
+ SwitchToNewScreen(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu);
+ break;
+ case MENUACTION_RADIO:
+ ChangeRadioStation(1);
+ break;
+ case MENUACTION_LANG_ENG:
+ m_PrefsLanguage = LANGUAGE_AMERICAN;
+ m_bFrontEnd_ReloadObrTxtGxt = true;
+ InitialiseChangedLanguageSettings();
+ SaveSettings();
+ break;
+ case MENUACTION_LANG_FRE:
+ m_PrefsLanguage = LANGUAGE_FRENCH;
+ m_bFrontEnd_ReloadObrTxtGxt = true;
+ InitialiseChangedLanguageSettings();
+ SaveSettings();
+ break;
+ case MENUACTION_LANG_GER:
+ m_PrefsLanguage = LANGUAGE_GERMAN;
+ m_bFrontEnd_ReloadObrTxtGxt = true;
+ InitialiseChangedLanguageSettings();
+ SaveSettings();
+ break;
+ case MENUACTION_LANG_ITA:
+ m_PrefsLanguage = LANGUAGE_ITALIAN;
+ m_bFrontEnd_ReloadObrTxtGxt = true;
+ InitialiseChangedLanguageSettings();
+ SaveSettings();
+ break;
+ case MENUACTION_LANG_SPA:
+ m_PrefsLanguage = LANGUAGE_SPANISH;
+ m_bFrontEnd_ReloadObrTxtGxt = true;
+ InitialiseChangedLanguageSettings();
+ SaveSettings();
+ break;
+ case MENUACTION_CHECKSAVE:
+ {
+ int saveSlot = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_SaveSlot;
+
+ if (saveSlot >= SAVESLOT_1 && saveSlot <= SAVESLOT_8) {
+ m_nCurrSaveSlot = saveSlot - SAVESLOT_1;
+ if (Slots[m_nCurrSaveSlot] != SLOT_EMPTY && Slots[m_nCurrSaveSlot] != SLOT_CORRUPTED) {
+ if (m_nCurrScreen == MENUPAGE_CHOOSE_LOAD_SLOT) {
+ SwitchToNewScreen(MENUPAGE_LOAD_SLOT_CONFIRM);
+ } else if (m_nCurrScreen == MENUPAGE_CHOOSE_DELETE_SLOT) {
+ SwitchToNewScreen(MENUPAGE_DELETE_SLOT_CONFIRM);
}
}
- if (changeMenu) {
- if (strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEDS_TB") == 0) {
-#ifndef TIDY_UP_PBP
- ResetHelperText();
- ChangeScreen(!m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_PreviousPage[1] : aScreens[m_nCurrScreen].m_PreviousPage[0],
- GetPreviousPageOption(), true, true);
-#else
- goBack = true;
- break;
+ }
+ break;
+ }
+ case MENUACTION_NEWGAME:
+ DoSettingsBeforeStartingAGame();
+ break;
+#ifdef LEGACY_MENU_OPTIONS
+ case MENUACTION_RELOADIDE:
+ CFileLoader::ReloadObjectTypes("GTA3.IDE");
+ break;
#endif
- } else {
- ChangeScreen(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu, 0, true, true);
- }
- }
- break;
+ case MENUACTION_RESUME_FROM_SAVEZONE:
+ RequestFrontEndShutDown();
+ break;
+ case MENUACTION_LOADRADIO:
+ if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) {
+ SwitchToNewScreen(MENUPAGE_SOUND_SETTINGS);
+ DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
+ OutputDebugString("STARTED PLAYING FRONTEND AUDIO TRACK");
}
- case MENUACTION_CHECKSAVE:
- {
- int saveSlot = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_SaveSlot;
+ break;
+#ifdef MISSION_REPLAY
+ case MENUACTION_REJECT_RETRY:
+ doingMissionRetry = false;
+ AllowMissionReplay = MISSION_RETRY_STAGE_NORMAL;
+ RequestFrontEndShutDown();
+ break;
+ case MENUACTION_UNK114:
+ doingMissionRetry = false;
+ RequestFrontEndShutDown();
+ RetryMission(MISSION_RETRY_TYPE_BEGIN_RESTARTING);
+ return;
+#endif
+ case MENUACTION_SAVEGAME:
+ {
+ int saveSlot = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_SaveSlot;
- 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);
- }
- }
- break;
+ if (saveSlot >= 2 && saveSlot <= 9) {
+ m_nCurrSaveSlot = m_nCurrOption;
+ SwitchToNewScreen(MENUPAGE_SAVE_OVERWRITE_CONFIRM);
+ }
+ break;
+ }
+ case MENUACTION_RADARMODE:
+ if (++m_PrefsRadarMode > 2)
+ m_PrefsRadarMode = 0;
+ SaveSettings();
+ break;
+ case MENUACTION_GOBACK:
+ goBack = true;
+ break;
+ case MENUACTION_KEYBOARDCTRLS:
+ SwitchToNewScreen(MENUPAGE_KEYBOARD_CONTROLS);
+ m_nSelectedListRow = 0;
+ m_nCurrExLayer = HOVEROPTION_LIST;
+ break;
+ case MENUACTION_GETKEY:
+ m_CurrCntrlAction = GetStartOptionsCntrlConfigScreens() + m_nCurrOption;
+ m_bKeyIsOK = true;
+ m_bWaitingForNewKeyBind = true;
+ m_bStartWaitingForKeyBind = true;
+ pControlEdit = &m_KeyPressedCode;
+ break;
+ case MENUACTION_CANCELGAME:
+ DMAudio.Service();
+ SwitchToNewScreen(MENUPAGE_OUTRO);
+ break;
+ case MENUACTION_RESUME:
+#ifdef LEGACY_MENU_OPTIONS
+ if (m_PrefsVsyncDisp != m_PrefsVsync) {
+ m_PrefsVsync = m_PrefsVsyncDisp;
}
- case MENUACTION_NEWGAME:
- DoSettingsBeforeStartingAGame();
- break;
- case MENUACTION_RELOADIDE:
- CFileLoader::ReloadObjectTypes("GTA3.IDE");
- break;
- case MENUACTION_RELOADIPL:
- CGame::ReloadIPLs();
- break;
- case MENUACTION_SHOWCULL:
- gbShowCullZoneDebugStuff = !gbShowCullZoneDebugStuff;
- break;
- case MENUACTION_MEMCARDSAVECONFIRM:
- return;
- 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_KEYBOARDCTRLS:
- ChangeScreen(MENUPAGE_KEYBOARD_CONTROLS, 0, true, true);
- m_nSelectedListRow = 0;
- m_nCurrExLayer = HOVEROPTION_LIST;
- break;
- case MENUACTION_GETKEY:
- m_CurrCntrlAction = GetStartOptionsCntrlConfigScreens() + m_nCurrOption;
- m_bKeyIsOK = true;
- m_bWaitingForNewKeyBind = true;
- m_bStartWaitingForKeyBind = true;
- pControlEdit = &m_KeyPressedCode;
- break;
- case MENUACTION_CANCELGAME:
- DMAudio.Service();
- RsEventHandler(rsQUITAPP, nil);
- break;
- case MENUACTION_RESUME:
-#ifndef TIDY_UP_PBP
- if (m_PrefsVsyncDisp != m_PrefsVsync) {
- m_PrefsVsync = m_PrefsVsyncDisp;
- }
- RequestFrontEndShutDown();
-#else
- goBack = true;
#endif
- break;
- case MENUACTION_DONTCANCEL:
- ChangeScreen(!m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_PreviousPage[1] : aScreens[m_nCurrScreen].m_PreviousPage[0],
- GetPreviousPageOption(), true, true);
- break;
- case MENUACTION_SCREENRES:
- if (m_nDisplayVideoMode != m_nPrefsVideoMode) {
- m_nPrefsVideoMode = m_nDisplayVideoMode;
- _psSelectScreenVM(m_nPrefsVideoMode);
- SetHelperText(0);
- SaveSettings();
- }
- break;
- case MENUACTION_AUDIOHW:
- {
- int selectedProvider = m_nPrefsAudio3DProviderIndex;
- if (selectedProvider != -1) {
- m_nPrefsAudio3DProviderIndex = DMAudio.SetCurrent3DProvider(m_nPrefsAudio3DProviderIndex);
- if (selectedProvider == m_nPrefsAudio3DProviderIndex) {
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- SetHelperText(0);
- } else {
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_FAIL, 0);
- SetHelperText(4);
- }
- SaveSettings();
- }
- break;
+ RequestFrontEndShutDown();
+ break;
+ case MENUACTION_DONTCANCEL:
+ SwitchToNewScreen(-2);
+ break;
+ case MENUACTION_SCREENRES:
+ if (m_nDisplayVideoMode != m_nPrefsVideoMode) {
+ m_nPrefsVideoMode = m_nDisplayVideoMode;
+ _psSelectScreenVM(m_nPrefsVideoMode);
+ DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND);
+ DMAudio.Service();
+ CentreMousePointer();
+ m_bShowMouse = true;
+ m_nCurrOption = 5; // TODO(Miami): Because selected option is resetted after res. change. We'll need to revisit that.
+ m_nOptionHighlightTransitionBlend = 0;
+ SaveSettings();
}
- case MENUACTION_SPEAKERCONF:
-#ifndef TIDY_UP_PBP
- if (m_nPrefsAudio3DProviderIndex != -1) {
- if (--m_PrefsSpeakers < 0)
- m_PrefsSpeakers = 2;
- DMAudio.SetSpeakerConfig(m_PrefsSpeakers);
- SaveSettings();
+ break;
+ case MENUACTION_AUDIOHW:
+ {
+ int selectedProvider = m_nPrefsAudio3DProviderIndex;
+ if (selectedProvider != NO_AUDIO_PROVIDER) {
+ if (selectedProvider == -1)
+ selectedProvider = m_nPrefsAudio3DProviderIndex = DMAudio.AutoDetect3DProviders();
+
+ m_nPrefsAudio3DProviderIndex = DMAudio.SetCurrent3DProvider(m_nPrefsAudio3DProviderIndex);
+ if (selectedProvider != m_nPrefsAudio3DProviderIndex) {
+ SetHelperText(5);
}
-#else
- assumeIncrease = true;
-#endif
- break;
- case MENUACTION_PLAYERSETUP:
- CPlayerSkin::BeginFrontendSkinEdit();
- ChangeScreen(MENUPAGE_SKIN_SELECT, 0, true, true);
- m_nCurrExLayer = HOVEROPTION_LIST;
- m_bSkinsEnumerated = false;
- break;
- case MENUACTION_RESTOREDEF:
- if (m_nCurrScreen == MENUPAGE_SOUND_SETTINGS) {
- m_PrefsSfxVolume = 102;
- m_PrefsSpeakers = 0;
- m_PrefsMusicVolume = 102;
- m_PrefsStereoMono = 0;
- m_PrefsRadioStation = HEAD_RADIO;
- DMAudio.SetMusicMasterVolume(102);
- DMAudio.SetEffectsMasterVolume(m_PrefsSfxVolume);
- DMAudio.SetRadioInCar(m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
- SaveSettings();
- } else if (m_nCurrScreen == MENUPAGE_DISPLAY_SETTINGS) {
- m_PrefsFrameLimiter = true;
- m_PrefsBrightness = 256;
- m_PrefsVsyncDisp = true;
- m_PrefsLOD = 1.2f;
- m_PrefsVsync = true;
- CRenderer::ms_lodDistScale = 1.2f;
+ SaveSettings();
+ }
+ break;
+ }
+ case MENUACTION_SPEAKERCONF:
+ if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) {
+ if (--m_PrefsSpeakers < 0)
+ m_PrefsSpeakers = 2;
+ DMAudio.SetSpeakerConfig(m_PrefsSpeakers);
+ SaveSettings();
+ }
+ break;
+ case MENUACTION_PLAYERSETUP:
+ CPlayerSkin::BeginFrontendSkinEdit();
+ SwitchToNewScreen(MENUPAGE_SKIN_SELECT);
+ m_bSkinsEnumerated = false;
+ m_nCurrExLayer = HOVEROPTION_LIST;
+ break;
+ case MENUACTION_RESTOREDEF:
+ if (m_nCurrScreen == MENUPAGE_SOUND_SETTINGS) {
+ m_nPrefsAudio3DProviderIndex = DMAudio.AutoDetect3DProviders();
+ DMAudio.SetCurrent3DProvider(m_nPrefsAudio3DProviderIndex);
+ m_PrefsSfxVolume = 49;
+ m_PrefsMusicVolume = 49;
+ m_PrefsRadioStation = EMOTION;
+ m_PrefsMP3BoostVolume = 0;
+ m_PrefsStereoMono = 1;
+ m_PrefsSpeakers = 0;
+ DMAudio.SetMP3BoostVolume(m_PrefsMP3BoostVolume);
+ DMAudio.SetMusicMasterVolume(m_PrefsMusicVolume);
+ DMAudio.SetEffectsMasterVolume(m_PrefsSfxVolume);
+ DMAudio.SetRadioInCar(m_PrefsRadioStation);
+ DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
+ SaveSettings();
+ } else if (m_nCurrScreen == MENUPAGE_DISPLAY_SETTINGS) {
+ m_PrefsBrightness = 256;
+ m_PrefsLOD = 1.2f;
+#ifdef LEGACY_MENU_OPTIONS
+ m_PrefsVsync = true;
+#endif
+ CRenderer::ms_lodDistScale = m_PrefsLOD;
+ m_PrefsShowSubtitles = false;
#ifdef ASPECT_RATIO_SCALE
- m_PrefsUseWideScreen = AR_AUTO;
-#else
- m_PrefsUseWideScreen = false;
-#endif
- m_PrefsShowSubtitles = true;
- m_nDisplayVideoMode = m_nPrefsVideoMode;
-#if GTA_VERSION >= GTA3_PC_11
- if (_dwOperatingSystemVersion == OS_WIN98) {
- CMBlur::BlurOn = false;
- CMBlur::MotionBlurClose();
- } else {
- CMBlur::BlurOn = true;
- CMBlur::MotionBlurOpen(Scene.camera);
- }
+ m_PrefsUseWideScreen = AR_AUTO;
#else
- CMBlur::BlurOn = true;
+ m_PrefsUseWideScreen = false;
#endif
+ m_PrefsShowLegends = true;
+ m_PrefsVsyncDisp = true;
+ m_PrefsFrameLimiter = true;
+ m_PrefsRadarMode = 0;
+ m_PrefsShowHud = true;
+ m_nDisplayVideoMode = m_nPrefsVideoMode;
+ CMBlur::BlurOn = false;
#ifdef CUSTOM_FRONTEND_OPTIONS
- extern void RestoreDefGraphics(int8);
- extern void RestoreDefDisplay(int8);
+ extern void RestoreDefGraphics(int8);
+ extern void RestoreDefDisplay(int8);
- RestoreDefGraphics(FEOPTION_ACTION_SELECT);
- RestoreDefDisplay(FEOPTION_ACTION_SELECT);
+ RestoreDefGraphics(FEOPTION_ACTION_SELECT);
+ RestoreDefDisplay(FEOPTION_ACTION_SELECT);
#endif
- SaveSettings();
- } else if ((m_nCurrScreen != MENUPAGE_SKIN_SELECT_OLD) && (m_nCurrScreen == MENUPAGE_CONTROLLER_PC)) {
- ControlsManager.MakeControllerActionsBlank();
- ControlsManager.InitDefaultControlConfiguration();
- ControlsManager.InitDefaultControlConfigMouse(MousePointerStateHelper.GetMouseSetUp());
+ SaveSettings();
+ } else if (m_nCurrScreen == MENUPAGE_CONTROLLER_PC) {
+ ControlsManager.MakeControllerActionsBlank();
+ ControlsManager.InitDefaultControlConfiguration();
+ ControlsManager.InitDefaultControlConfigMouse(MousePointerStateHelper.GetMouseSetUp());
#if !defined RW_GL3
- if (AllValidWinJoys.m_aJoys[JOYSTICK1].m_bInitialised) {
- DIDEVCAPS devCaps;
- devCaps.dwSize = sizeof(DIDEVCAPS);
- PSGLOBAL(joy1)->GetCapabilities(&devCaps);
- ControlsManager.InitDefaultControlConfigJoyPad(devCaps.dwButtons);
- }
+ if (AllValidWinJoys.m_aJoys[JOYSTICK1].m_bInitialised) {
+ DIDEVCAPS devCaps;
+ devCaps.dwSize = sizeof(DIDEVCAPS);
+ PSGLOBAL(joy1)->GetCapabilities(&devCaps);
+ ControlsManager.InitDefaultControlConfigJoyPad(devCaps.dwButtons);
+ }
#else
- if (PSGLOBAL(joy1id) != -1 && glfwJoystickPresent(PSGLOBAL(joy1id))) {
- int count;
- glfwGetJoystickButtons(PSGLOBAL(joy1id), &count);
- ControlsManager.InitDefaultControlConfigJoyPad(count);
- }
+ if (PSGLOBAL(joy1id) != -1 && glfwJoystickPresent(PSGLOBAL(joy1id))) {
+ int count;
+ glfwGetJoystickButtons(PSGLOBAL(joy1id), &count);
+ ControlsManager.InitDefaultControlConfigJoyPad(count);
+ }
#endif
- m_ControlMethod = CONTROL_STANDARD;
+ MousePointerStateHelper.bInvertVertically = true;
+ TheCamera.m_bHeadBob = false;
#ifdef FIX_BUGS
- MousePointerStateHelper.bInvertVertically = true;
- TheCamera.m_fMouseAccelVertical = 0.003f;
-#else
- MousePointerStateHelper.bInvertVertically = false;
-#endif
- TheCamera.m_fMouseAccelHorzntl = 0.0025f;
- CVehicle::m_bDisableMouseSteering = true;
- TheCamera.m_bHeadBob = false;
- SaveSettings();
-#ifdef LOAD_INI_SETTINGS
- SaveINIControllerSettings();
+ TheCamera.m_fMouseAccelVertical = 0.003f;
#endif
- }
- SetHelperText(2);
- break;
- case MENUACTION_CTRLMETHOD:
-#ifndef TIDY_UP_PBP
- if (m_ControlMethod == CONTROL_CLASSIC) {
- CCamera::m_bUseMouse3rdPerson = true;
- m_ControlMethod = CONTROL_STANDARD;
- } else {
- CCamera::m_bUseMouse3rdPerson = false;
- m_ControlMethod = CONTROL_CLASSIC;
- }
- SaveSettings();
+ TheCamera.m_fMouseAccelHorzntl = 0.0025f;
+ CVehicle::m_bDisableMouseSteering = true;
+ m_ControlMethod = CONTROL_STANDARD;
+#ifdef PC_PLAYER_CONTROLS
+ TheCamera.m_bUseMouse3rdPerson = true;
#else
- assumeIncrease = true;
+ TheCamera.m_bUseMouse3rdPerson = false;
#endif
- break;
- case MENUACTION_LOADRADIO:
- ChangeScreen(MENUPAGE_SOUND_SETTINGS, 0, true, true);
- DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
- OutputDebugString("STARTED PLAYING FRONTEND AUDIO TRACK");
- break;
-#ifdef MISSION_REPLAY
- case MENUACTION_REJECT_RETRY:
- doingMissionRetry = false;
- AllowMissionReplay = 0;
- RequestFrontEndShutDown();
- break;
- case MENUACTION_UNK114:
- doingMissionRetry = false;
- RequestFrontEndShutDown();
- RetryMission(MISSION_RETRY_TYPE_BEGIN_RESTARTING);
- return;
+ SaveSettings();
+#ifdef LOAD_INI_SETTINGS
+ SaveINIControllerSettings();
#endif
+ }
+ SetHelperText(2);
+ break;
+ case MENUACTION_CTRLMETHOD:
+ if (m_ControlMethod == CONTROL_CLASSIC) {
+ CCamera::m_bUseMouse3rdPerson = true;
+ m_ControlMethod = CONTROL_STANDARD;
+ } else {
+ CCamera::m_bUseMouse3rdPerson = false;
+ m_ControlMethod = CONTROL_CLASSIC;
+ }
+ SaveSettings();
+ break;
#ifdef CUSTOM_FRONTEND_OPTIONS
- case MENUACTION_CFO_SELECT:
- case MENUACTION_CFO_DYNAMIC:
- CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption];
- if (option.m_Action == MENUACTION_CFO_SELECT) {
- if (option.m_CFOSelect->disableIfGameLoaded && !m_bGameNotLoaded)
+ case MENUACTION_CFO_SELECT:
+ case MENUACTION_CFO_DYNAMIC:
+ CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption];
+ if (option.m_Action == MENUACTION_CFO_SELECT) {
+ if (option.m_CFOSelect->disableIfGameLoaded && !m_bGameNotLoaded)
break;
- if (!option.m_CFOSelect->onlyApplyOnEnter) {
- option.m_CFOSelect->displayedValue++;
- if (option.m_CFOSelect->displayedValue >= option.m_CFOSelect->numRightTexts || option.m_CFOSelect->displayedValue < 0)
- option.m_CFOSelect->displayedValue = 0;
- }
- int8 oldValue = *(int8*)option.m_CFO->value;
-
- *(int8*)option.m_CFO->value = option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue;
-
- // Now everything is saved in .ini, and LOAD_INI_SETTINGS is fundamental for CFO
- // if (option.m_CFOSelect->save)
- SaveSettings();
+ if (!option.m_CFOSelect->onlyApplyOnEnter) {
+ option.m_CFOSelect->displayedValue++;
+ if (option.m_CFOSelect->displayedValue >= option.m_CFOSelect->numRightTexts || option.m_CFOSelect->displayedValue < 0)
+ option.m_CFOSelect->displayedValue = 0;
+ }
+ int8 oldValue = *(int8*)option.m_CFO->value;
- if (option.m_CFOSelect->displayedValue != oldValue && option.m_CFOSelect->changeFunc)
- option.m_CFOSelect->changeFunc(oldValue, option.m_CFOSelect->displayedValue);
+ *(int8*)option.m_CFO->value = option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue;
- } else if (option.m_Action == MENUACTION_CFO_DYNAMIC) {
- if (option.m_CFODynamic->buttonPressFunc)
- option.m_CFODynamic->buttonPressFunc(FEOPTION_ACTION_SELECT);
- }
+ // Now everything is saved in .ini, and LOAD_INI_SETTINGS is fundamental for CFO
+ // if (option.m_CFOSelect->save)
+ SaveSettings();
- break;
-#endif
- }
- }
- ProcessOnOffMenuOptions();
- }
+ if (option.m_CFOSelect->displayedValue != oldValue && option.m_CFOSelect->changeFunc)
+ option.m_CFOSelect->changeFunc(oldValue, option.m_CFOSelect->displayedValue);
- if (goBack) {
- ResetHelperText();
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_BACK, 0);
-#ifdef PS2_LIKE_MENU
- if (m_nCurrScreen == MENUPAGE_PAUSE_MENU || bottomBarActive) {
-#else
- if (m_nCurrScreen == MENUPAGE_PAUSE_MENU) {
-#endif
- if (!m_bGameNotLoaded && !m_bMenuStateChanged) {
- if (m_PrefsVsyncDisp != m_PrefsVsync) {
- m_PrefsVsync = m_PrefsVsyncDisp;
+ } else if (option.m_Action == MENUACTION_CFO_DYNAMIC) {
+ if (option.m_CFODynamic->buttonPressFunc)
+ option.m_CFODynamic->buttonPressFunc(FEOPTION_ACTION_SELECT);
}
- RequestFrontEndShutDown();
- }
- // We're already resuming, we don't need further processing.
-#if defined(FIX_BUGS) || defined(PS2_LIKE_MENU)
- return;
-#endif
- }
-#ifdef PS2_SAVE_DIALOG
- else if (m_nCurrScreen == MENUPAGE_CHOOSE_SAVE_SLOT || m_nCurrScreen == MENUPAGE_SAVE) {
-#else
- else if (m_nCurrScreen == MENUPAGE_CHOOSE_SAVE_SLOT) {
+ break;
#endif
- RequestFrontEndShutDown();
}
- // It's now in ThingsToDoBeforeGoingBack()
-#ifndef TIDY_UP_PBP
- else if (m_nCurrScreen == MENUPAGE_SOUND_SETTINGS) {
- DMAudio.StopFrontEndTrack();
- OutputDebugString("FRONTEND AUDIO TRACK STOPPED");
- }
-#endif
-
- int oldScreen = !m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_PreviousPage[1] : aScreens[m_nCurrScreen].m_PreviousPage[0];
- int oldOption = GetPreviousPageOption();
-
- if (oldScreen != -1) {
- ThingsToDoBeforeGoingBack();
-
-#ifdef PS2_LIKE_MENU
- if (!bottomBarActive &&
- (oldScreen == MENUPAGE_NONE || oldScreen == MENUPAGE_OPTIONS)) {
- bottomBarActive = true;
- } else
-#endif
- {
- ChangeScreen(oldScreen, oldOption, true, true);
- }
-
- // We will go back for sure at this point, why process other things?!
+ ProcessOnOffMenuOptions();
+ if (!goBack) {
#ifdef FIX_BUGS
- return;
-#endif
- }
- }
-
-#ifdef PS2_LIKE_MENU
- if (bottomBarActive)
- return;
-#endif
-
- int changeValueBy = 0;
- bool decrease = false;
-#ifdef TIDY_UP_PBP
- bool increase = assumeIncrease;
+ int saveSlot = aScreens[currScreen].m_aEntries[currOption].m_SaveSlot;
+ if (saveSlot >= SAVESLOT_1 && saveSlot <= SAVESLOT_8 && Slots[currOption] != SLOT_OK)
#else
- bool increase = false;
+ int saveSlot = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_SaveSlot;
+ if (saveSlot >= SAVESLOT_1 && saveSlot <= SAVESLOT_8 && Slots[m_nCurrOption] != SLOT_OK)
#endif
- if (CPad::GetPad(0)->GetLeft() || CPad::GetPad(0)->GetPedWalkLeftRight() < 0 || CPad::GetPad(0)->GetDPadLeft()) {
- static uint32 lastSliderDecrease = 0;
- if (CTimer::GetTimeInMillisecondsPauseMode() - lastSliderDecrease > 150) {
- CheckSliderMovement(-1);
- lastSliderDecrease = CTimer::GetTimeInMillisecondsPauseMode();
- }
- } else if (CPad::GetPad(0)->GetRight() || CPad::GetPad(0)->GetPedWalkLeftRight() > 0 || CPad::GetPad(0)->GetDPadRight()) {
- static uint32 lastSliderIncrease = 0;
- if (CTimer::GetTimeInMillisecondsPauseMode() - lastSliderIncrease > 150) {
- CheckSliderMovement(1);
- lastSliderIncrease = CTimer::GetTimeInMillisecondsPauseMode();
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_FAIL, 0);
+ else
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_ENTER_OR_ADJUST, 0);
}
}
- if (CPad::GetPad(0)->GetRightJustDown() || CPad::GetPad(0)->GetAnaloguePadRight() || CPad::GetPad(0)->GetDPadRightJustDown()) {
- m_bShowMouse = false;
- increase = true;
- } else if (
-#ifdef SCROLLABLE_PAGES
- !SCREEN_HAS_AUTO_SCROLLBAR &&
-#endif
- CPad::GetPad(0)->GetMouseWheelUpJustDown() && m_nCurrScreen != MENUPAGE_KEYBOARD_CONTROLS) {
- increase = true;
- CheckSliderMovement(1);
- m_bShowMouse = true;
- }
-
- if (CPad::GetPad(0)->GetLeftJustDown() || CPad::GetPad(0)->GetAnaloguePadLeft() || CPad::GetPad(0)->GetDPadLeftJustDown()) {
- m_bShowMouse = false;
- decrease = true;
- } else if (
-#ifdef SCROLLABLE_PAGES
- !SCREEN_HAS_AUTO_SCROLLBAR &&
-#endif
- CPad::GetPad(0)->GetMouseWheelDownJustDown() && m_nCurrScreen != MENUPAGE_KEYBOARD_CONTROLS) {
- decrease = true;
- CheckSliderMovement(-1);
- m_bShowMouse = true;
+ if (goBack) {
+ if (m_NoEmptyBinding) {
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_BACK, 0);
+ SwitchToNewScreen(-2);
+ if (hasNativeList(m_nCurrScreen)) {
+ m_nTotalListRow = 0;
+ }
+ } else {
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_FAIL, 0);
+ m_ShowEmptyBindingError = true;
+ }
}
- if (increase)
- changeValueBy++;
- else if (decrease)
- changeValueBy--;
-
- if (changeValueBy != 0) {
+ if (changeAmount != 0) {
switch (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action) {
-#ifdef FIX_BUGS
+#ifdef GAMEPAD_MENU
case MENUACTION_CTRLCONFIG:
- CPad::GetPad(0)->Mode += changeValueBy;
+ CPad::GetPad(0)->Mode += changeAmount;
if (CPad::GetPad(0)->Mode > 3)
CPad::GetPad(0)->Mode = 0;
else if (CPad::GetPad(0)->Mode < 0)
CPad::GetPad(0)->Mode = 3;
SaveSettings();
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
break;
#endif
case MENUACTION_RADIO:
- m_PrefsRadioStation += changeValueBy;
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- if (DMAudio.IsMP3RadioChannelAvailable()) {
- if (m_PrefsRadioStation < HEAD_RADIO)
- m_PrefsRadioStation = USERTRACK;
- if (m_PrefsRadioStation > USERTRACK)
- m_PrefsRadioStation = HEAD_RADIO;
- } else {
- if (m_PrefsRadioStation < HEAD_RADIO)
- m_PrefsRadioStation = CHATTERBOX;
- if (m_PrefsRadioStation > CHATTERBOX)
- m_PrefsRadioStation = HEAD_RADIO;
- }
- SaveSettings();
- DMAudio.SetRadioInCar(m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
- OutputDebugString("FRONTEND RADIO STATION CHANGED");
+ ChangeRadioStation(changeAmount);
+ break;
+ case MENUACTION_RADARMODE:
+ m_PrefsRadarMode += changeAmount;
+ if (m_PrefsRadarMode < 0)
+ m_PrefsRadarMode = 2;
+ if (m_PrefsRadarMode > 2)
+ m_PrefsRadarMode = 0;
break;
#ifdef ASPECT_RATIO_SCALE
case MENUACTION_WIDESCREEN:
- if (changeValueBy > 0) {
+ if (changeAmount > 0) {
m_PrefsUseWideScreen++;
- if (m_PrefsUseWideScreen > AR_MAX-1)
+ if (m_PrefsUseWideScreen > AR_MAX - 1)
m_PrefsUseWideScreen = 0;
} else {
m_PrefsUseWideScreen--;
if (m_PrefsUseWideScreen < 0)
- m_PrefsUseWideScreen = AR_MAX-1;
+ m_PrefsUseWideScreen = AR_MAX - 1;
}
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
SaveSettings();
break;
#endif
case MENUACTION_SCREENRES:
if (m_bGameNotLoaded) {
RwChar** videoMods = _psGetVideoModeList();
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0);
- if (changeValueBy > 0) {
+ if (changeAmount > 0) {
do {
++m_nDisplayVideoMode;
@@ -5406,25 +5100,49 @@ CMenuManager::ProcessButtonPresses(void)
}
break;
case MENUACTION_AUDIOHW:
- if (m_nPrefsAudio3DProviderIndex != -1) {
- m_nPrefsAudio3DProviderIndex += changeValueBy;
- m_nPrefsAudio3DProviderIndex = Clamp(m_nPrefsAudio3DProviderIndex, 0, DMAudio.GetNum3DProvidersAvailable() - 1);
+ if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) {
+ m_nPrefsAudio3DProviderIndex += changeAmount;
+
+ bool checkIfForbidden = true;
+ while (checkIfForbidden) {
+ checkIfForbidden = false;
+
+ if (m_nPrefsAudio3DProviderIndex < -1)
+ m_nPrefsAudio3DProviderIndex = DMAudio.GetNum3DProvidersAvailable() - 1;
+ else if (m_nPrefsAudio3DProviderIndex > DMAudio.GetNum3DProvidersAvailable() - 1)
+ m_nPrefsAudio3DProviderIndex = -1;
+
+ // what a retarded move...
+ if (m_nPrefsAudio3DProviderIndex != -1) {
+ char* provider = DMAudio.Get3DProviderName(m_nPrefsAudio3DProviderIndex);
+ strupr(provider);
+ if (!strcmp(provider, "MILES FAST 2D POSITIONAL AUDIO")) {
+ m_nPrefsAudio3DProviderIndex += changeAmount;
+ checkIfForbidden = true;
+
+ } else if (!strcmp(provider, "AUREAL A3D 2.0 (TM)")) {
+ m_nPrefsAudio3DProviderIndex += changeAmount;
+ checkIfForbidden = true;
+
+ } else if (!strcmp(provider, "AUREAL A3D INTERACTIVE (TM)")) {
+ m_nPrefsAudio3DProviderIndex += changeAmount;
+ checkIfForbidden = true;
+ }
+ }
+ }
}
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0);
break;
case MENUACTION_SPEAKERCONF:
- if (m_nPrefsAudio3DProviderIndex != -1) {
- m_PrefsSpeakers -= changeValueBy;
+ if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) {
+ m_PrefsSpeakers -= changeAmount;
m_PrefsSpeakers = Clamp(m_PrefsSpeakers, 0, 2);
DMAudio.SetSpeakerConfig(m_PrefsSpeakers);
SaveSettings();
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
}
break;
case MENUACTION_CTRLMETHOD:
m_ControlMethod = !m_ControlMethod;
CCamera::m_bUseMouse3rdPerson = !m_ControlMethod;
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
SaveSettings();
break;
#ifdef CUSTOM_FRONTEND_OPTIONS
@@ -5435,7 +5153,7 @@ CMenuManager::ProcessButtonPresses(void)
if (option.m_CFOSelect->disableIfGameLoaded && !m_bGameNotLoaded)
break;
- if (changeValueBy > 0) {
+ if (changeAmount > 0) {
option.m_CFOSelect->displayedValue++;
if (option.m_CFOSelect->displayedValue >= option.m_CFOSelect->numRightTexts)
option.m_CFOSelect->displayedValue = 0;
@@ -5457,21 +5175,19 @@ CMenuManager::ProcessButtonPresses(void)
option.m_CFOSelect->changeFunc(oldValue, option.m_CFOSelect->displayedValue);
}
} else if (option.m_Action == MENUACTION_CFO_DYNAMIC && option.m_CFODynamic->buttonPressFunc) {
- option.m_CFODynamic->buttonPressFunc(changeValueBy > 0 ? FEOPTION_ACTION_RIGHT : FEOPTION_ACTION_LEFT);
+ option.m_CFODynamic->buttonPressFunc(changeAmount > 0 ? FEOPTION_ACTION_RIGHT : FEOPTION_ACTION_LEFT);
}
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
-
break;
#endif
}
+ CheckSliderMovement(changeAmount);
ProcessOnOffMenuOptions();
if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) {
- if (changeValueBy < 1) {
+ if (changeAmount < 1) {
m_nSelectedContSetupColumn = CONTSETUP_PED_COLUMN;
} else {
m_nSelectedContSetupColumn = CONTSETUP_VEHICLE_COLUMN;
}
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0);
}
}
}
@@ -5480,106 +5196,81 @@ void
CMenuManager::ProcessOnOffMenuOptions()
{
switch (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action) {
+#ifdef GAMEPAD_MENU
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_SETTING_CHANGE, 0);
-#ifdef FIX_BUGS
SaveSettings();
-#endif // !FIX_BUGS
break;
-#ifndef FIX_BUGS
- case MENUACTION_CTRLCONFIG:
- CPad::GetPad(0)->Mode++;
- if (CPad::GetPad(0)->Mode > 3)
- CPad::GetPad(0)->Mode = 0;
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
+#endif
+ case MENUACTION_INVERTPADY:
+ CPad::bInvertLook4Pad = !CPad::bInvertLook4Pad;
+ SaveSettings(); // FIX: Why don't SaveSettings? Because of it's an hidden option? :(
break;
-#endif // !FIX_BUGS
case MENUACTION_CTRLDISPLAY:
m_DisplayControllerOnFoot = !m_DisplayControllerOnFoot;
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
break;
case MENUACTION_FRAMESYNC:
m_PrefsVsyncDisp = !m_PrefsVsyncDisp;
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- SaveSettings();
+ SaveSettings(); // FIX: Again... This makes me very unhappy
break;
case MENUACTION_FRAMELIMIT:
m_PrefsFrameLimiter = !m_PrefsFrameLimiter;
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
SaveSettings();
break;
case MENUACTION_TRAILS:
CMBlur::BlurOn = !CMBlur::BlurOn;
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
SaveSettings();
- if (CMBlur::BlurOn)
- CMBlur::MotionBlurOpen(Scene.camera);
- else
- CMBlur::MotionBlurClose();
break;
case MENUACTION_SUBTITLES:
m_PrefsShowSubtitles = !m_PrefsShowSubtitles;
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
SaveSettings();
break;
#ifndef ASPECT_RATIO_SCALE
case MENUACTION_WIDESCREEN:
m_PrefsUseWideScreen = !m_PrefsUseWideScreen;
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
SaveSettings();
break;
#endif
+ case MENUACTION_LEGENDS:
+ m_PrefsShowLegends = !m_PrefsShowLegends;
+ break;
+ case MENUACTION_HUD:
+ m_PrefsShowHud = !m_PrefsShowHud;
+ SaveSettings();
+ break;
+#ifdef LEGACY_MENU_OPTIONS
case MENUACTION_SETDBGFLAG:
CTheScripts::InvertDebugFlag();
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
break;
case MENUACTION_SWITCHBIGWHITEDEBUGLIGHT:
gbBigWhiteDebugLightSwitchedOn = !gbBigWhiteDebugLightSwitchedOn;
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- break;
- case MENUACTION_PEDROADGROUPS:
- gbShowPedRoadGroups = !gbShowPedRoadGroups;
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- break;
- case MENUACTION_CARROADGROUPS:
- gbShowCarRoadGroups = !gbShowCarRoadGroups;
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
break;
case MENUACTION_COLLISIONPOLYS:
gbShowCollisionPolys = !gbShowCollisionPolys;
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- break;
- case MENUACTION_MP_PLAYERCOLOR:
- PickNewPlayerColour();
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- SaveSettings();
break;
+#endif
case MENUACTION_SHOWHEADBOB:
TheCamera.m_bHeadBob = !TheCamera.m_bHeadBob;
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
SaveSettings();
break;
case MENUACTION_INVVERT:
MousePointerStateHelper.bInvertVertically = !MousePointerStateHelper.bInvertVertically;
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
SaveSettings();
break;
case MENUACTION_DYNAMICACOUSTIC:
m_PrefsDMA = !m_PrefsDMA;
DMAudio.SetDynamicAcousticModelingStatus(m_PrefsDMA);
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
SaveSettings();
break;
case MENUACTION_MOUSESTEER:
- CVehicle::m_bDisableMouseSteering = !CVehicle::m_bDisableMouseSteering;
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- SaveSettings();
+ if (m_ControlMethod == CONTROL_STANDARD) {
+ CVehicle::m_bDisableMouseSteering = !CVehicle::m_bDisableMouseSteering;
+ SaveSettings();
+ }
break;
}
}
@@ -5588,7 +5279,6 @@ void
CMenuManager::RequestFrontEndShutDown()
{
m_bShutDownFrontEndRequested = true;
- DMAudio.ChangeMusicMode(MUSICMODE_GAME);
}
void
@@ -5605,49 +5295,12 @@ CMenuManager::ResetHelperText()
}
void
-CMenuManager::SaveLoadFileError_SetUpErrorScreen()
-{
- switch (PcSaveHelper.nErrorCode) {
- case SAVESTATUS_ERR_SAVE_CREATE:
- case SAVESTATUS_ERR_SAVE_WRITE:
- case SAVESTATUS_ERR_SAVE_CLOSE:
- ChangeScreen(MENUPAGE_SAVE_FAILED, 0, true, false);
- break;
- case SAVESTATUS_ERR_LOAD_OPEN:
- case SAVESTATUS_ERR_LOAD_READ:
- case SAVESTATUS_ERR_LOAD_CLOSE:
- ChangeScreen(MENUPAGE_LOAD_FAILED, 0, true, false);
- break;
- case SAVESTATUS_ERR_DATA_INVALID:
- ChangeScreen(MENUPAGE_LOAD_FAILED_2, 0, true, false);
- break;
- case SAVESTATUS_DELETEFAILED8:
- case SAVESTATUS_DELETEFAILED9:
- case SAVESTATUS_DELETEFAILED10:
- ChangeScreen(MENUPAGE_DELETE_FAILED, 0, true, false);
- break;
- default: break;
- }
-}
-
-void
CMenuManager::SetHelperText(int text)
{
m_nHelperTextMsgId = text;
m_nHelperTextAlpha = 300;
}
-void
-CMenuManager::ShutdownJustMenu()
-{
- // In case we're windowed, keep mouse centered while in game. Done in main.cpp in other conditions.
-#if defined(RW_GL3) && defined(IMPROVED_VIDEOMODE)
- glfwSetInputMode(PSGLOBAL(window), GLFW_CURSOR, GLFW_CURSOR_DISABLED);
-#endif
- m_bMenuActive = false;
- CTimer::EndUserPause();
-}
-
float
CMenuManager::StretchX(float x)
{
@@ -5667,128 +5320,416 @@ float CMenuManager::StretchY(float y)
return SCREEN_STRETCH_Y(y);
}
+#ifdef XBOX_MESSAGE_SCREEN
+void
+CMenuManager::CloseDialog(void)
+{
+ // We don't have this on PC GXT :shrug:
+ static wchar* gameSaved = AllocUnicode("Game saved successfully!");
+
+ if (m_bSaveWasSuccessful && DialogTextCmp("FESZ_WR")) {
+ m_bSaveWasSuccessful = false; // i don't know where XBOX resets that
+ m_pDialogText = gameSaved;
+ SetDialogTimer(1000);
+ ProcessDialogTimer();
+ } else {
+ ToggleDialog(false);
+ }
+
+}
+
+void
+CMenuManager::ProcessDialogTimer(void)
+{
+ if (!m_bDialogOpen || m_nDialogHideTimer == 0)
+ return;
+
+ // Also XBOX has unified time source for in-game/menu, but we don't have that
+ if (m_bMenuActive && CTimer::GetTimeInMilliseconds() > m_nDialogHideTimer || !m_bMenuActive && CTimer::GetTimeInMillisecondsPauseMode() > m_nDialogHideTimerPauseMode) {
+
+ // This is originally activePage.funcs->closePage()
+ CloseDialog();
+ }
+}
+
+void
+CMenuManager::SetDialogTimer(uint32 timer)
+{
+ // XBOX iterates some page list(actives?) and then sets timer variable of specified page to specified value. We only have dialog right now.
+ // Also XBOX has unified time source for in-game/menu, but we don't have that, thus 2 timer variables...
+
+ m_nDialogHideTimer = CTimer::GetTimeInMilliseconds() + timer;
+ m_nDialogHideTimerPauseMode = CTimer::GetTimeInMillisecondsPauseMode() + timer;
+}
+
+void
+CMenuManager::SetDialogText(const char* key)
+{
+ // There are many things going around here, idk why
+ m_pDialogText = TheText.Get(key);
+}
+
+bool
+CMenuManager::DialogTextCmp(const char* key)
+{
+ wchar *value = TheText.Get(key);
+ wchar *i = m_pDialogText;
+ for (; *i != '\0' && *value != '\0'; i++, value++) {
+ if (*i != *value)
+ return false;
+ }
+ return *i == '\0' && *value == '\0';
+}
+
+void
+CMenuManager::ToggleDialog(bool toggle)
+{
+ // This originally calls some mysterious function on enable and close CB on disable, along with decreasing some counter. Which is no use for dialog
+
+ // XBOX doesn't do that
+ if (toggle)
+ m_nDialogHideTimer = 0;
+
+ m_bDialogOpen = toggle;
+}
+
+void
+DrawDialogBg(float offset, uint8 alpha)
+{
+ CSprite2d::Draw2DPolygon(SCALE_AND_CENTER_X(84.f + offset), MENU_Y(126.f + offset),
+ SCALE_AND_CENTER_X(512.f + offset), MENU_Y(109.f + offset),
+ SCALE_AND_CENTER_X(100.f + offset), MENU_Y(303.f + offset),
+ SCALE_AND_CENTER_X(474.f + offset), MENU_Y(311.f + offset), CRGBA(107, 193, 236, alpha));
+ CSprite2d::Draw2DPolygon(SCALE_AND_CENTER_X(523.f + offset), MENU_Y(108.f + offset),
+ SCALE_AND_CENTER_X(542.f + offset), MENU_Y(107.f + offset),
+ SCALE_AND_CENTER_X(485.f + offset), MENU_Y(310.f + offset),
+ SCALE_AND_CENTER_X(516.f + offset), MENU_Y(311.f + offset), CRGBA(107, 193, 236, alpha));
+}
+
+void
+CMenuManager::DrawOverlays(void)
+{
+ // This is stripped to show only Dialog box, XBOX does much more in here.
+
+ if (!m_bDialogOpen)
+ return;
+
+ DefinedState();
+
+ CSprite2d::DrawRect(CRect(0, SCREEN_HEIGHT, SCREEN_WIDTH, 0), CRGBA(0, 0, 0, 160));
+
+ // Ofc this is not hardcoded like that on Xbox, it should be a texture
+ DrawDialogBg(20.f, 160); // shadow
+ DrawDialogBg(0.f, 255);
+
+ CFont::SetBackgroundOff();
+ CFont::SetPropOn();
+ CFont::SetJustifyOn();
+ CFont::SetBackGroundOnlyTextOn();
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
+ CFont::SetCentreSize(SCREEN_SCALE_X(380.0f));
+ CFont::SetCentreOn();
+ CFont::SetColor(CRGBA(LABEL_COLOR.r, LABEL_COLOR.g, LABEL_COLOR.b, 255));
+ CFont::SetDropShadowPosition(2);
+ CFont::SetDropColor(CRGBA(0, 0, 0, 255));
+ // Both of those are 0.9 on Xbox, which is ofcouse wrong...
+ CFont::SetScale(SCREEN_SCALE_X(BIGTEXT_X_SCALE), SCREEN_SCALE_Y(BIGTEXT_Y_SCALE));
+
+ int x = SCREEN_WIDTH / 2.f - SCREEN_SCALE_X(30.0f);
+ int y = SCREEN_HEIGHT / 2.f - SCREEN_SCALE_Y(30.0f);
+ int numOfLines = CFont::GetNumberLines(x, y, m_pDialogText);
+ CFont::PrintString(x, y - SCREEN_SCALE_Y(numOfLines / 2.f), m_pDialogText);
+ CFont::DrawFonts();
+}
+#endif
+
+void
+CMenuManager::ProcessFileActions()
+{
+ switch (m_nCurrScreen) {
+ case MENUPAGE_LOADING_IN_PROGRESS:
+#ifdef MISSION_REPLAY
+ if (MissionSkipLevel) {
+ if (gGameState != GS_PLAYING_GAME)
+ DoSettingsBeforeStartingAGame();
+ RequestFrontEndShutDown();
+ break;
+ }
+ if (doingMissionRetry) {
+ RetryMission(MISSION_RETRY_TYPE_BEGIN_RESTARTING);
+ m_nCurrSaveSlot = SLOT_COUNT;
+ doingMissionRetry = false;
+ }
+#endif
+ if (CheckSlotDataValid(m_nCurrSaveSlot)) {
+#ifdef USE_DEBUG_SCRIPT_LOADER
+ CTheScripts::ScriptToLoad = 0;
+#endif
+
+#ifdef XBOX_MESSAGE_SCREEN
+ SetDialogText("FELD_WR");
+ ToggleDialog(true);
+#else
+ if (!m_bGameNotLoaded)
+ MessageScreen("FELD_WR", true);
+#endif
+ DoSettingsBeforeStartingAGame();
+ m_bWantToLoad = true;
+ } else
+ SwitchToNewScreen(MENUPAGE_NEW_GAME);
+
+ break;
+ case MENUPAGE_DELETING_IN_PROGRESS:
+ {
+ static bool waitedForScreen = false;
+
+ if (waitedForScreen) {
+ bool SlotPopulated = false;
+ if (PcSaveHelper.DeleteSlot(m_nCurrSaveSlot)) {
+ PcSaveHelper.PopulateSlotInfo();
+ SlotPopulated = true;
+ }
+
+ if (SlotPopulated) {
+ SwitchToNewScreen(MENUPAGE_DELETE_SUCCESSFUL);
+ } else {
+ SwitchToNewScreen(MENUPAGE_SAVE_CUSTOM_WARNING);
+ strncpy(aScreens[m_nCurrScreen].m_ScreenName, "FES_DEL", 8);
+ strncpy(aScreens[m_nCurrScreen].m_aEntries[0].m_EntryName, "FES_DEE", 8);
+ }
+ waitedForScreen = false;
+ } else if (m_nMenuFadeAlpha >= 255)
+ waitedForScreen = true;
+
+ break;
+ }
+ case MENUPAGE_SAVING_IN_PROGRESS:
+ {
+#ifdef XBOX_MESSAGE_SCREEN
+ if (m_bDialogOpen && DialogTextCmp("FESZ_WR")) {
+ uint32 startTime = CTimer::GetTimeInMillisecondsPauseMode();
+ int8 SaveSlot = PcSaveHelper.SaveSlot(m_nCurrSaveSlot);
+ PcSaveHelper.PopulateSlotInfo();
+
+ // Original code, but we don't want redundant saving text if it doesn't
+#if 0
+ CTimer::Update(); // not on Xbox, who updates it?
+
+ // it compensates the lag to show saving text always one second... how cute
+ int dialogDur = Max(1, startTime - CTimer::GetTimeInMillisecondsPauseMode() + 1000);
+#else
+ int dialogDur = 1;
+#endif
+
+ if (SaveSlot) {
+ // error. PC code
+ ToggleDialog(false);
+ SwitchToNewScreen(MENUPAGE_SAVE_CUSTOM_WARNING);
+ strncpy(aScreens[m_nCurrScreen].m_ScreenName, "FET_SG", 8);
+ strncpy(aScreens[m_nCurrScreen].m_aEntries[0].m_EntryName, "FES_CMP", 8);
+
+ } else {
+ m_bSaveWasSuccessful = true;
+ SetDialogTimer(dialogDur);
+ ProcessDialogTimer();
+ RequestFrontEndShutDown();
+ }
+
+ } else {
+ SetDialogText("FESZ_WR");
+ ToggleDialog(true);
+ }
+#else
+ static bool waitedForScreen = false;
+
+ if (waitedForScreen) {
+ int8 SaveSlot = PcSaveHelper.SaveSlot(m_nCurrSaveSlot);
+ PcSaveHelper.PopulateSlotInfo();
+ if (SaveSlot) {
+ SwitchToNewScreen(MENUPAGE_SAVE_CUSTOM_WARNING);
+ strncpy(aScreens[m_nCurrScreen].m_ScreenName, "FET_SG", 8);
+ strncpy(aScreens[m_nCurrScreen].m_aEntries[0].m_EntryName, "FES_CMP", 8);
+ } else
+ SwitchToNewScreen(MENUPAGE_SAVE_SUCCESSFUL);
+
+ waitedForScreen = false;
+ } else if (m_nMenuFadeAlpha >= 255)
+ waitedForScreen = true;
+#endif
+ break;
+ }
+ }
+}
+
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
+ // 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 == MENUPAGE_SAVE_CHEAT_WARNING)
+ || m_bShutDownFrontEndRequested || m_bStartUpFrontEndRequested
+#ifdef REGISTER_START_BUTTON
+ || CPad::GetPad(0)->GetStartJustDown() && !m_bGameNotLoaded
#endif
- || m_bShutDownFrontEndRequested || m_bStartUpFrontEndRequested) {
+ ) {
- m_bMenuActive = !m_bMenuActive;
-#ifdef FIX_BUGS
- CPad::StopPadsShaking();
+ if (m_nCurrScreen != MENUPAGE_LOADING_IN_PROGRESS
+#ifdef XBOX_MESSAGE_SCREEN
+ && m_nCurrScreen != MENUPAGE_SAVING_IN_PROGRESS
#endif
+ ) {
+ 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) {
- CTimer::StartUserPause();
- } else {
-#ifdef PS2_LIKE_MENU
- bottomBarActive = false;
+ if (m_bMenuActive) {
+ if (_InputMouseNeedsExclusive()) {
+ _InputShutdownMouse();
+ _InputInitialiseMouse(false);
+ }
+ Initialise();
+ LoadAllTextures();
+#ifdef FIX_BUGS
+ CPad::StopPadsShaking();
#endif
+ } else {
+#ifdef EXTENDED_COLOURFILTER
+ // we always expect CPostFX to be open
+ CMBlur::BlurOn = true;
+#endif
+ 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();
+ if (_InputMouseNeedsExclusive()) {
+ _InputShutdownMouse();
+ _InputInitialiseMouse(true);
+ }
+
+ m_StatsScrollSpeed = 150.0f;
#ifdef FIX_BUGS
- ThingsToDoBeforeGoingBack();
+ ThingsToDoBeforeLeavingPage();
#endif
- ShutdownJustMenu();
- SaveSettings();
+ SaveSettings();
#ifdef LOAD_INI_SETTINGS
- SaveINIControllerSettings();
+ SaveINIControllerSettings();
#endif
- m_bStartUpFrontEndRequested = false;
- pControlEdit = nil;
- m_bShutDownFrontEndRequested = false;
- DisplayComboButtonErrMsg = false;
+ 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;
-#endif
- m_nCurrScreen = MENUPAGE_NONE;
+ 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
+ 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_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;
-
- // In case we're windowed, keep mouse centered while in game. Done in main.cpp in other conditions.
-#if defined(RW_GL3) && defined(IMPROVED_VIDEOMODE)
- glfwSetInputMode(PSGLOBAL(window), GLFW_CURSOR, m_bMenuActive && m_nPrefsWindowed ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_DISABLED);
-#endif
+ m_OnlySaveMenu = true;
+
+ if (_InputMouseNeedsExclusive()) {
+ _InputShutdownMouse();
+ _InputInitialiseMouse(false);
+ }
+
+ Initialise();
+ LoadAllTextures();
+
+ if (CPad::bHasPlayerCheated) {
+ m_nCurrScreen = MENUPAGE_SAVE_CHEAT_WARNING;
+ m_nCurrOption = 0;
+ } else {
+ m_nCurrScreen = MENUPAGE_CHOOSE_SAVE_SLOT;
+ m_nCurrOption = 8;
+ }
}
m_bStartUpFrontEndRequested = false;
m_bShutDownFrontEndRequested = false;
+
+#ifdef GAMEPAD_MENU
+ // Reset pad shaking.
+ if (TimeToStopPadShaking && TimeToStopPadShaking < CTimer::GetTimeInMillisecondsPauseMode()) {
+ CPad::StopPadsShaking();
+ TimeToStopPadShaking = 0;
+ }
+#endif
}
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);
-#ifdef GAMEPAD_MENU
- int frontend_controllerTxdSlot = CTxdStore::FindTxdSlot("frontend_controller");
- if (frontend_controllerTxdSlot != -1)
- CTxdStore::RemoveTxd(frontend_controllerTxdSlot);
-#endif
+ if (!m_OnlySaveMenu) {
+ int frontend2 = CTxdStore::FindTxdSlot("frontend2");
+ for (int i = 3; i < NUM_MENU_SPRITES; ++i)
+ m_aFrontEndSprites[i].Delete();
+
+ CTxdStore::RemoveTxd(frontend2);
- 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();
+#ifdef GAMEPAD_MENU
+ // Unload controller txd
+ int frontend_controller = CTxdStore::FindTxdSlot("frontend_controller");
+ if (frontend_controller != -1)
+ CTxdStore::RemoveTxd(frontend_controller);
#endif
- int menu = CTxdStore::FindTxdSlot("menu");
- CTxdStore::RemoveTxd(menu);
+ }
- m_bSpritesLoaded = false;
+ m_bSpritesLoaded = false;
+ }
+ m_OnlySaveMenu = false;
+ CUserDisplay::PlaceName.ProcessAfterFrontEndShutDown();
}
void
@@ -5797,13 +5738,6 @@ CMenuManager::WaitForUserCD()
CSprite2d *splash;
char *splashscreen = nil;
-#if (!(defined RANDOMSPLASH) && GTA_VERSION < GTA3_PC_11)
- if (CGame::frenchGame || CGame::germanGame || !CGame::nastyGame)
- splashscreen = "mainsc2";
- else
- splashscreen = "mainsc1";
-#endif
-
splash = LoadSplash(splashscreen);
if (RsGlobal.quit)
@@ -5811,7 +5745,7 @@ CMenuManager::WaitForUserCD()
HandleExit();
CPad::UpdatePads();
- MessageScreen("NO_PCCD");
+ MessageScreen("NO_PCCD", true);
if (CPad::GetPad(0)->GetEscapeJustDown()) {
m_bQuitGameNoCD = true;
@@ -5819,15 +5753,245 @@ CMenuManager::WaitForUserCD()
}
}
+void
+CMenuManager::DrawQuitGameScreen(void)
+{
+ static int32 exitSignalTimer = 0;
+
+#ifdef FIX_BUGS
+ int alpha = Clamp(m_nMenuFadeAlpha, 0, 255);
+#else
+ int alpha = m_nMenuFadeAlpha;
+#endif
+
+#ifndef MUCH_SHORTER_OUTRO_SCREEN
+ static uint32 lastTickIncrease = 0;
+ if (alpha == 255 && CTimer::GetTimeInMillisecondsPauseMode() - lastTickIncrease > 10) {
+ exitSignalTimer++;
+ lastTickIncrease = CTimer::GetTimeInMillisecondsPauseMode();
+ }
+#else
+ static uint32 firstTick = CTimer::GetTimeInMillisecondsPauseMode();
+ if (alpha == 255 && CTimer::GetTimeInMillisecondsPauseMode() - firstTick > 750) {
+ exitSignalTimer = 150;
+ }
+#endif
+ static CSprite2d *splash = nil;
+
+ if (splash == nil)
+ splash = LoadSplash("OUTRO");
+
+ m_aFrontEndSprites[MENUSPRITE_VCLOGO].Draw(CRect(SCREEN_STRETCH_X(28.0f), MENU_Y(8.0f), SCREEN_STRETCH_X(27.0f) + MENU_X(130.f), MENU_Y(138.0f)), CRGBA(255, 255, 255, 255 - alpha));
+
+ // Or we can see menu background from sides
+#ifdef ASPECT_RATIO_SCALE
+ CSprite2d::DrawRect(CRect(0, 0, MENU_X_LEFT_ALIGNED(0.f), SCREEN_HEIGHT), CRGBA(0, 0, 0, alpha));
+ CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(0.f), 0, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(0, 0, 0, alpha));
+#endif
+
+ splash->Draw(CRect(MENU_X_LEFT_ALIGNED(0.f), 0, MENU_X_RIGHT_ALIGNED(0.f), SCREEN_HEIGHT), CRGBA(255, 255, 255, alpha));
+ if (alpha == 255 && exitSignalTimer == 150)
+ RsEventHandler(rsQUITAPP, nil);
+
+ m_bShowMouse = false;
+ m_AllowNavigation = false;
+}
+
+void
+CMenuManager::PrintMap(void)
+{
+ m_bMenuMapActive = true;
+ CRadar::InitFrontEndMap();
+
+ // Because m_fMapSize is half of the map length(hence * 2), and map consists of 3x3 tiles(hence / 3).
+ float halfTile = m_fMapSize * 2.f / 3.f / 2.f;
+
+ RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR);
+
+ 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 >= 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 >= 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 >= 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 >= 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 >= 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 >= 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 >= 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 >= 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();
+ if (m_PrefsShowLegends) {
+ CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(40.0f));
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(84.0f));
+ CFont::SetBackGroundOnlyTextOff();
+ CFont::SetColor(CRGBA(LABEL_COLOR.r, LABEL_COLOR.g, LABEL_COLOR.b, FadeIn(255)));
+ CFont::SetDropShadowPosition(2);
+ CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255)));
+ CFont::SetCentreOn();
+ CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING));
+ CFont::SetScale(SCREEN_SCALE_X(0.65f), SCREEN_SCALE_Y(0.95f));
+
+ int secondColumnStart = (CRadar::MapLegendCounter - 1) / 2;
+ int boxBottom = MENU_Y(100.0f);
+
+ // + 3, because we want 19*3 px padding
+ for (int i = 0; i < secondColumnStart + 3; i++) {
+ boxBottom += MENU_Y(19.f);
+ }
+
+ CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(95.0f), MENU_Y(100.0f), MENU_X_LEFT_ALIGNED(555.f), boxBottom),
+ CRGBA(0, 0, 0, FadeIn(190)));
+
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(320.0f), MENU_Y(102.0f), TheText.Get("FE_MLG"));
+ CFont::SetRightJustifyOff();
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
+ if (m_PrefsLanguage == LANGUAGE_AMERICAN)
+ CFont::SetScale(SCREEN_SCALE_X(0.55f), SCREEN_SCALE_Y(0.55f));
+ else
+ CFont::SetScale(SCREEN_SCALE_X(0.45f), SCREEN_SCALE_Y(0.55f));
+
+ CFont::SetColor(CRGBA(225, 225, 225, FadeIn(255)));
+ CFont::SetDropShadowPosition(0);
+
+ int y = MENU_Y(127.0f);
+ int x = MENU_X_LEFT_ALIGNED(160.0f);
+
+ for (int16 i = 0; i < CRadar::MapLegendCounter; i++) {
+ CRadar::DrawLegend(x, y, CRadar::MapLegendList[i]);
+
+ if (i == secondColumnStart) {
+ x = MENU_X_LEFT_ALIGNED(350.0f);
+ y = MENU_Y(127.0f);
+ } else {
+ y += MENU_Y(19.0f);
+ }
+ }
+ }
+
+#ifdef MAP_ENHANCEMENTS
+ if (m_nMenuFadeAlpha != 255 && !m_bShowMouse) {
+ mapCrosshair.x = SCREEN_WIDTH / 2;
+ mapCrosshair.y = SCREEN_HEIGHT / 2;
+ } else if (m_bShowMouse) {
+ mapCrosshair.x = m_nMousePosX;
+ mapCrosshair.y = m_nMousePosY;
+ }
+
+ CSprite2d::DrawRect(CRect(mapCrosshair.x - MENU_X(1.0f), 0.0f,
+ mapCrosshair.x + MENU_X(1.0f), SCREEN_HEIGHT),
+ CRGBA(0, 0, 0, 150));
+ CSprite2d::DrawRect(CRect(0.0f, mapCrosshair.y + MENU_X(1.0f),
+ SCREEN_WIDTH, mapCrosshair.y - MENU_X(1.0f)),
+ CRGBA(0, 0, 0, 150));
+
+#endif
+ m_bMenuMapActive = false;
+
+ CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN));
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_X_MARGIN));
+ DisplayHelperText("FEH_MPH");
+}
+
+void
+CMenuManager::ChangeRadioStation(int8 increaseBy)
+{
+ if (m_ScrollRadioBy != 0)
+ return;
+
+ m_PrefsRadioStation += increaseBy;
+ m_ScrollRadioBy = increaseBy;
+ if (m_ScrollRadioBy == 1) {
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_ENTER_OR_ADJUST, 0);
+ m_LeftMostRadioX = MENU_X_LEFT_ALIGNED(MENURADIO_ICON_FIRST_X);
+ } else {
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_ENTER_OR_ADJUST, 0);
+ m_LeftMostRadioX = MENU_X_LEFT_ALIGNED(MENURADIO_ICON_FIRST_X - (2 * MENURADIO_ICON_SIZE));
+ }
+
+ if (DMAudio.IsMP3RadioChannelAvailable()) {
+ if (m_PrefsRadioStation < WILDSTYLE)
+ m_PrefsRadioStation = USERTRACK;
+ if (m_PrefsRadioStation > USERTRACK)
+ m_PrefsRadioStation = WILDSTYLE;
+ } else {
+ if (m_PrefsRadioStation < WILDSTYLE)
+ m_PrefsRadioStation = WAVE;
+ if (m_PrefsRadioStation > WAVE)
+ m_PrefsRadioStation = WILDSTYLE;
+ }
+ DMAudio.StopFrontEndTrack();
+ DMAudio.PlayFrontEndSound(SOUND_RADIO_CHANGE, 0);
+}
+
+#if 0
+uint8 CMenuManager::GetNumberOfMenuOptions()
+{
+ uint8 Rows = -1;
+ for (int i = 0; i < NUM_MENUROWS; i++) {
+ if (aScreens[m_nCurrScreen].m_aEntries[i].m_Action == MENUACTION_NOTHING)
+ break;
+
+ ++Rows;
+ }
+ return Rows;
+}
+#endif
+
#ifdef GAMEPAD_MENU
+const char* controllerTypesPaths[] = {
+ "MODELS/FRONTEND_DS2.TXD",
+ "MODELS/FRONTEND_DS3.TXD",
+ "MODELS/FRONTEND_DS4.TXD",
+ "MODELS/FRONTEND_X360.TXD",
+ "MODELS/FRONTEND_XONE.TXD",
+ "MODELS/FRONTEND_NSW.TXD",
+};
+
void
CMenuManager::PrintController(void)
{
+ // Don't print anything if controller texture is missing
+ if (!m_aFrontEndSprites[MENUSPRITE_CONTROLLER].m_pTexture) return;
+
const float scale = 0.9f;
const float CONTROLLER_SIZE_X = 235.2f;
const float CONTROLLER_SIZE_Y = 175.2f;
const float CONTROLLER_POS_X = (DEFAULT_SCREEN_WIDTH - CONTROLLER_SIZE_X) / 2.0f;
- const float CONTROLLER_POS_Y = 160.0f;
+ const float CONTROLLER_POS_Y = 220.0f;
float centerX = CONTROLLER_POS_X + CONTROLLER_SIZE_X / 2;
float centerY = CONTROLLER_POS_Y + CONTROLLER_SIZE_Y / 2;
@@ -5835,46 +5999,46 @@ CMenuManager::PrintController(void)
#define X(f) ((f)*scale + centerX)
#define Y(f) ((f)*scale + centerY)
- m_aFrontEndSprites[FE_CONTROLLERSH].Draw(MENU_X_LEFT_ALIGNED(X(-CONTROLLER_SIZE_X / 2)), MENU_Y(Y(-CONTROLLER_SIZE_Y / 2)), MENU_X((CONTROLLER_SIZE_X + 4.8f) * scale), MENU_Y((CONTROLLER_SIZE_Y + 4.8f) * scale), CRGBA(0, 0, 0, 255));
- m_aFrontEndSprites[FE_CONTROLLER].Draw(MENU_X_LEFT_ALIGNED(X(-CONTROLLER_SIZE_X / 2)), MENU_Y(Y(-CONTROLLER_SIZE_Y / 2)), MENU_X(CONTROLLER_SIZE_X * scale), MENU_Y(CONTROLLER_SIZE_Y * scale), CRGBA(255, 255, 255, 255));
+ m_aFrontEndSprites[MENUSPRITE_CONTROLLER].Draw(MENU_X_LEFT_ALIGNED(X(-CONTROLLER_SIZE_X / 2)), MENU_Y(Y(-CONTROLLER_SIZE_Y / 2)), MENU_X(CONTROLLER_SIZE_X * scale), MENU_Y(CONTROLLER_SIZE_Y * scale), CRGBA(255, 255, 255, FadeIn(255)));
if (m_DisplayControllerOnFoot) {
- if (CTimer::GetTimeInMillisecondsPauseMode() & 0x400)
- m_aFrontEndSprites[FE_ARROWS1].Draw(MENU_X_LEFT_ALIGNED(X(-CONTROLLER_SIZE_X / 2)), MENU_Y(Y(-CONTROLLER_SIZE_Y / 2)), MENU_X(CONTROLLER_SIZE_X * scale), MENU_Y(CONTROLLER_SIZE_Y * scale), CRGBA(255, 255, 255, 255));
+ if ((int)CTimer::GetTimeInMillisecondsPauseMode() & 0x400)
+ m_aFrontEndSprites[MENUSPRITE_ARROWS1].Draw(MENU_X_LEFT_ALIGNED(X(-CONTROLLER_SIZE_X / 2)), MENU_Y(Y(-CONTROLLER_SIZE_Y / 2)), MENU_X(CONTROLLER_SIZE_X * scale), MENU_Y(CONTROLLER_SIZE_Y * scale), CRGBA(255, 255, 255, FadeIn(255)));
else
- m_aFrontEndSprites[FE_ARROWS3].Draw(MENU_X_LEFT_ALIGNED(X(-CONTROLLER_SIZE_X / 2)), MENU_Y(Y(-CONTROLLER_SIZE_Y / 2)), MENU_X(CONTROLLER_SIZE_X * scale), MENU_Y(CONTROLLER_SIZE_Y * scale), CRGBA(255, 255, 255, 255));
- } else {
- if (CTimer::GetTimeInMillisecondsPauseMode() & 0x400)
- m_aFrontEndSprites[FE_ARROWS2].Draw(MENU_X_LEFT_ALIGNED(X(-CONTROLLER_SIZE_X / 2)), MENU_Y(Y(-CONTROLLER_SIZE_Y / 2)), MENU_X(CONTROLLER_SIZE_X * scale), MENU_Y(CONTROLLER_SIZE_Y * scale), CRGBA(255, 255, 255, 255));
+ m_aFrontEndSprites[MENUSPRITE_ARROWS3].Draw(MENU_X_LEFT_ALIGNED(X(-CONTROLLER_SIZE_X / 2)), MENU_Y(Y(-CONTROLLER_SIZE_Y / 2)), MENU_X(CONTROLLER_SIZE_X * scale), MENU_Y(CONTROLLER_SIZE_Y * scale), CRGBA(255, 255, 255, FadeIn(255)));
+ }
+ else {
+ if ((int)CTimer::GetTimeInMillisecondsPauseMode() & 0x400)
+ m_aFrontEndSprites[MENUSPRITE_ARROWS2].Draw(MENU_X_LEFT_ALIGNED(X(-CONTROLLER_SIZE_X / 2)), MENU_Y(Y(-CONTROLLER_SIZE_Y / 2)), MENU_X(CONTROLLER_SIZE_X * scale), MENU_Y(CONTROLLER_SIZE_Y * scale), CRGBA(255, 255, 255, FadeIn(255)));
else
- m_aFrontEndSprites[FE_ARROWS4].Draw(MENU_X_LEFT_ALIGNED(X(-CONTROLLER_SIZE_X / 2)), MENU_Y(Y(-CONTROLLER_SIZE_Y / 2)), MENU_X(CONTROLLER_SIZE_X * scale), MENU_Y(CONTROLLER_SIZE_Y * scale), CRGBA(255, 255, 255, 255));
+ m_aFrontEndSprites[MENUSPRITE_ARROWS4].Draw(MENU_X_LEFT_ALIGNED(X(-CONTROLLER_SIZE_X / 2)), MENU_Y(Y(-CONTROLLER_SIZE_Y / 2)), MENU_X(CONTROLLER_SIZE_X * scale), MENU_Y(CONTROLLER_SIZE_Y * scale), CRGBA(255, 255, 255, FadeIn(255)));
}
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
- CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE * scale), MENU_Y(SMALLESTTEXT_Y_SCALE * scale)); // X
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
+
+ CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE * 2 * scale * 0.9f), MENU_Y(SMALLESTTEXT_Y_SCALE * scale * 0.9f)); // X
- // CFont::SetColor(CRGBA(128, 128, 128, FadeIn(255)));
CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255)));
- CFont::SetDropShadowPosition(1);
- CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255)));
+ CFont::SetDropShadowPosition(0);
+ CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255)));
CFont::SetWrapx(SCREEN_WIDTH);
- float TEXT_L2_X = 50.0f + CONTROLLER_POS_X - centerX, TEXT_L2_Y = -14.0f + CONTROLLER_POS_Y - centerY;
- float TEXT_L1_X = -4.0f + CONTROLLER_POS_X - centerX, TEXT_L1_Y = 25.0f + CONTROLLER_POS_Y - centerY, TEXT_L1_Y_VEH = 3.0f + TEXT_L1_Y;
- float TEXT_DPAD_X = -4.0f + CONTROLLER_POS_X - centerX, TEXT_DPAD_Y = 65.0f + CONTROLLER_POS_Y - centerY;
+ float TEXT_L2_X = 85.0f + CONTROLLER_POS_X - centerX, TEXT_L2_Y = -14.0f + CONTROLLER_POS_Y - centerY;
+ float TEXT_L1_X = -4.0f + CONTROLLER_POS_X - centerX, TEXT_L1_Y = 27.0f + CONTROLLER_POS_Y - centerY, TEXT_L1_Y_VEH = 3.0f + TEXT_L1_Y;
+ float TEXT_DPAD_X = -4.0f + CONTROLLER_POS_X - centerX, TEXT_DPAD_Y = 67.0f + CONTROLLER_POS_Y - centerY;
float TEXT_LSTICK_X = -4.0f + CONTROLLER_POS_X - centerX, TEXT_LSTICK_Y = 97.0f + CONTROLLER_POS_Y - centerY;
- float TEXT_SELECT_X = 103.0f + CONTROLLER_POS_X - centerX, TEXT_SELECT_Y = 141.0f + CONTROLLER_POS_Y - centerY;
+ float TEXT_SELECT_X = 170.0f + CONTROLLER_POS_X - centerX, TEXT_SELECT_Y = 141.0f + CONTROLLER_POS_Y - centerY;
float TEXT_START_X = 130.0f + CONTROLLER_POS_X - centerX, TEXT_START_Y = 128.0f + CONTROLLER_POS_Y - centerY;
- float TEXT_R2_X = 184.0F + CONTROLLER_POS_X - centerX, TEXT_R2_Y = -14.0f + CONTROLLER_POS_Y - centerY;
- float TEXT_R1_X = 238.0f + CONTROLLER_POS_X - centerX, TEXT_R1_Y = 25.0f + CONTROLLER_POS_Y - centerY;
-
- float TEXT_SQUARE_X = 144.0f + CONTROLLER_POS_X - centerX, TEXT_SQUARE_Y = 18.0f + CONTROLLER_POS_Y - centerY;
- float TEXT_TRIANGLE_X = 238.0f + CONTROLLER_POS_X - centerX, TEXT_TRIANGLE_Y = 52.0f + CONTROLLER_POS_Y - centerY;
- float TEXT_CIRCLE_X = 238.0f + CONTROLLER_POS_X - centerX, TEXT_CIRCLE_Y = 65.0f + CONTROLLER_POS_Y - centerY;
- float TEXT_CROSS_X = 238.0f + CONTROLLER_POS_X - centerX, TEXT_CROSS_Y = 78.0f + CONTROLLER_POS_Y - centerY;
- float TEXT_RSTICK_X = 238.0f + CONTROLLER_POS_X - centerX, TEXT_RSTICK_Y = 94.0f + CONTROLLER_POS_Y - centerY;
- float TEXT_R3_X = 238.0f + CONTROLLER_POS_X - centerX, TEXT_R3_Y = 109.0f + CONTROLLER_POS_Y - centerY;
- float TEXT_L3_X = 84.0f + CONTROLLER_POS_X - centerX, TEXT_L3_Y = 162.0f + CONTROLLER_POS_Y - centerY;
- float TEXT_L2R2_X = 74.0f + CONTROLLER_POS_X - centerX, TEXT_L2R2_Y = -6.0f + CONTROLLER_POS_Y - centerY;
+ float TEXT_R2_X = 164.0f + CONTROLLER_POS_X - centerX, TEXT_R2_Y = -14.0f + CONTROLLER_POS_Y - centerY;
+ float TEXT_R1_X = 242.0f + CONTROLLER_POS_X - centerX, TEXT_R1_Y = 27.0f + CONTROLLER_POS_Y - centerY;
+
+ float TEXT_SQUARE_X = 147.0f + CONTROLLER_POS_X - centerX, TEXT_SQUARE_Y = 30.0f + CONTROLLER_POS_Y - centerY;
+ float TEXT_TRIANGLE_X = 242.0f + CONTROLLER_POS_X - centerX, TEXT_TRIANGLE_Y = 55.0f + CONTROLLER_POS_Y - centerY;
+ float TEXT_CIRCLE_X = 242.0f + CONTROLLER_POS_X - centerX, TEXT_CIRCLE_Y = 67.0f + CONTROLLER_POS_Y - centerY;
+ float TEXT_CROSS_X = 242.0f + CONTROLLER_POS_X - centerX, TEXT_CROSS_Y = 80.0f + CONTROLLER_POS_Y - centerY;
+ float TEXT_RSTICK_X = 242.0f + CONTROLLER_POS_X - centerX, TEXT_RSTICK_Y = 97.0f + CONTROLLER_POS_Y - centerY;
+ float TEXT_R3_X = 242.0f + CONTROLLER_POS_X - centerX, TEXT_R3_Y = 110.0f + CONTROLLER_POS_Y - centerY;
+ float TEXT_L3_X = 94.0f + CONTROLLER_POS_X - centerX, TEXT_L3_Y = 162.0f + CONTROLLER_POS_Y - centerY;
+ float TEXT_L2R2_X = 120.0f + CONTROLLER_POS_X - centerX, TEXT_L2R2_Y = -4.0f + CONTROLLER_POS_Y - centerY;
switch (m_PrefsControllerType)
{
@@ -5887,7 +6051,7 @@ CMenuManager::PrintController(void)
TEXT_CROSS_Y -= 1.0f;
TEXT_RSTICK_Y -= 4.0f;
TEXT_R3_Y -= 4.0f;
- TEXT_DPAD_Y -= 1.0f;
+ TEXT_DPAD_Y -= 2.0f;
TEXT_LSTICK_Y -= 6.0f;
TEXT_L3_X -= 2.0f;
break;
@@ -5903,7 +6067,7 @@ CMenuManager::PrintController(void)
TEXT_RSTICK_Y += 1.0f;
TEXT_R3_Y += 1.0f;
TEXT_DPAD_Y += 29.0f;
- TEXT_LSTICK_Y -= 22.0f;
+ TEXT_LSTICK_Y -= 20.0f;
TEXT_L3_X -= 36.0f;
TEXT_L2R2_Y += 5.0f;
TEXT_SELECT_X += 4.0f;
@@ -5920,863 +6084,660 @@ CMenuManager::PrintController(void)
TEXT_RSTICK_Y += 4.0f;
TEXT_R3_Y += 4.0f;
TEXT_DPAD_Y += 30.0f;
- TEXT_LSTICK_Y -= 21.0f;
+ TEXT_LSTICK_Y -= 19.0f;
TEXT_L3_X -= 36.0f;
TEXT_L2R2_Y += 5.0f;
TEXT_SELECT_X += 3.0f;
break;
+ case CONTROLLER_NINTENDO_SWITCH:
+ TEXT_L1_Y += 5.0f;
+ TEXT_L1_Y_VEH = TEXT_L1_Y;
+ TEXT_R1_Y += 5.0f;
+ TEXT_TRIANGLE_Y += 3.0f;
+ TEXT_CIRCLE_Y += 3.0f;
+ TEXT_CROSS_Y += 3.0f;
+ TEXT_LSTICK_Y -= 23.0f;
+ TEXT_DPAD_Y += 25.0;
+ TEXT_RSTICK_Y += 1.0f;
+ TEXT_R3_Y += 1.0f;
+ break;
};
if (m_DisplayControllerOnFoot) {
switch (CPad::GetPad(0)->Mode) {
- case 0:
- CFont::SetRightJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L2_X)), MENU_Y(Y(TEXT_L2_Y)), TheText.Get("FEC_CWL"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L1_X)), MENU_Y(Y(TEXT_L1_Y)), TheText.Get("FEC_LOF"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_DPAD_X)), MENU_Y(Y(TEXT_DPAD_Y)), TheText.Get("FEC_MOV"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_LSTICK_X)), MENU_Y(Y(TEXT_LSTICK_Y)), TheText.Get("FEC_MOV"));
- CFont::SetJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SELECT_X)), MENU_Y(Y(TEXT_SELECT_Y)), TheText.Get("FEC_CAM"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_START_X)), MENU_Y(Y(TEXT_START_Y)), TheText.Get("FEC_PAU"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R2_X)), MENU_Y(Y(TEXT_R2_Y)), TheText.Get("FEC_CWR"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R1_X)), MENU_Y(Y(TEXT_R1_Y)), TheText.Get("FEC_TAR"));
- CFont::SetRightJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)), MENU_Y(Y(TEXT_SQUARE_Y)), TheText.Get("FEC_JUM"));
- CFont::SetJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_TRIANGLE_X)), MENU_Y(Y(TEXT_TRIANGLE_Y)), TheText.Get("FEC_ENV"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CIRCLE_X)), MENU_Y(Y(TEXT_CIRCLE_Y)), TheText.Get("FEC_ATT"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CROSS_X)), MENU_Y(Y(TEXT_CROSS_Y)), TheText.Get("FEC_RUN"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_RSTICK_X)), MENU_Y(Y(TEXT_RSTICK_Y)), TheText.Get("FEC_FPC"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R3_X)), MENU_Y(Y(TEXT_R3_Y)), TheText.Get("FEC_LB3"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R3_X)), MENU_Y(Y(TEXT_R3_Y + 13.0f)), TheText.Get("FEC_R3"));
+ case 0:
+ CFont::SetRightJustifyOn();
+ switch (m_PrefsLanguage)
+ {
+ case LANGUAGE_FRENCH:
+ case LANGUAGE_SPANISH:
+ TEXT_L2_X -= 45.0f;
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(X(TEXT_L1_X)) - SCREEN_SCALE_X(85));
+ break;
+ default:
+ CFont::SetRightJustifyWrap(0);
+ break;
+ }
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L2_X)), MENU_Y(Y(TEXT_L2_Y)), TheText.Get("FEC_CWL"));
+ CFont::SetRightJustifyWrap(0);
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L1_X)), MENU_Y(Y(TEXT_L1_Y)), TheText.Get("FEC_LOF"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_DPAD_X)), MENU_Y(Y(TEXT_DPAD_Y)), TheText.Get("FEC_MOV"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_LSTICK_X)), MENU_Y(Y(TEXT_LSTICK_Y)), TheText.Get("FEC_MOV"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_LSTICK_X)), MENU_Y(Y(TEXT_R3_Y)), TheText.Get("FEC_CR3"));
+ CFont::SetRightJustifyOn();
+ switch (m_PrefsLanguage)
+ {
+ case LANGUAGE_GERMAN:
+ TEXT_SELECT_X += 20.0f;
+ break;
+ case LANGUAGE_SPANISH:
+ TEXT_SELECT_X += 15.0f;
+ break;
+ default:
+ break;
+ }
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SELECT_X)), MENU_Y(Y(TEXT_SELECT_Y)), TheText.Get("FEC_CAM"));
+ CFont::SetJustifyOn();
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_START_X)), MENU_Y(Y(TEXT_START_Y)), TheText.Get("FEC_PAU"));
+ switch (m_PrefsLanguage)
+ {
+ case LANGUAGE_FRENCH:
+ case LANGUAGE_SPANISH:
+ TEXT_R2_X += 30.0f;
+ CFont::SetJustifyOff();
+ CFont::SetWrapx(MENU_X_LEFT_ALIGNED(X(TEXT_R2_X)) + SCREEN_SCALE_X(120));
+ break;
+ default:
break;
- case 1:
- CFont::SetRightJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L2_X)), MENU_Y(Y(TEXT_L2_Y)), TheText.Get("FEC_CWL"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L1_X)), MENU_Y(Y(TEXT_L1_Y)), TheText.Get("FEC_LOF"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_DPAD_X)), MENU_Y(Y(TEXT_DPAD_Y)), TheText.Get("FEC_CAM"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_LSTICK_X)), MENU_Y(Y(TEXT_LSTICK_Y)), TheText.Get("FEC_MOV"));
- CFont::SetJustifyOn(); // X
+ }
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R2_X)), MENU_Y(Y(TEXT_R2_Y)), TheText.Get("FEC_CWR"));
+ CFont::SetJustifyOn();
+ CFont::SetWrapx(SCREEN_WIDTH);
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R1_X)), MENU_Y(Y(TEXT_R1_Y)), TheText.Get("FEC_TAR"));
+ CFont::SetRightJustifyOn();
+ CFont::PrintStringFromBottom(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)), MENU_Y(Y(TEXT_SQUARE_Y)), TheText.Get("FEC_JUM"));
+ CFont::SetJustifyOn();
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_TRIANGLE_X)), MENU_Y(Y(TEXT_TRIANGLE_Y)), TheText.Get("FEC_ENV"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CIRCLE_X)), MENU_Y(Y(TEXT_CIRCLE_Y)), TheText.Get("FEC_ATT"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CROSS_X)), MENU_Y(Y(TEXT_CROSS_Y)), TheText.Get("FEC_RUN"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_RSTICK_X)), MENU_Y(Y(TEXT_RSTICK_Y)), TheText.Get("FEC_FPC"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R3_X)), MENU_Y(Y(TEXT_R3_Y)), TheText.Get("FEC_LB3"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R3_X)), MENU_Y(Y(TEXT_R3_Y + 13.0f)), TheText.Get("FEC_R3"));
+ break;
+ case 1:
+ CFont::SetRightJustifyOn();
+ switch (m_PrefsLanguage)
+ {
+ case LANGUAGE_FRENCH:
+ case LANGUAGE_SPANISH:
+ TEXT_L2_X -= 45.0f;
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(X(TEXT_L1_X)) - SCREEN_SCALE_X(85));
+ break;
+ default:
+ CFont::SetRightJustifyWrap(0);
+ break;
+ }
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L2_X)), MENU_Y(Y(TEXT_L2_Y)), TheText.Get("FEC_CWL"));
+ CFont::SetRightJustifyWrap(0);
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L1_X)), MENU_Y(Y(TEXT_L1_Y)), TheText.Get("FEC_LOF"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_DPAD_X)), MENU_Y(Y(TEXT_DPAD_Y)), TheText.Get("FEC_CAM"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_LSTICK_X)), MENU_Y(Y(TEXT_LSTICK_Y)), TheText.Get("FEC_MOV"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_LSTICK_X)), MENU_Y(Y(TEXT_R3_Y)), TheText.Get("FEC_CR3"));
+ switch (m_PrefsLanguage)
+ {
+ case LANGUAGE_GERMAN:
CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SELECT_X)), MENU_Y(Y(TEXT_SELECT_Y)), TheText.Get("FEC_NA"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_START_X)), MENU_Y(Y(TEXT_START_Y)), TheText.Get("FEC_PAU"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R2_X)), MENU_Y(Y(TEXT_R2_Y)), TheText.Get("FEC_CWR"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R1_X)), MENU_Y(Y(TEXT_R1_Y)), TheText.Get("FEC_TAR"));
- CFont::SetRightJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)), MENU_Y(Y(TEXT_SQUARE_Y)), TheText.Get("FEC_JUM"));
- CFont::SetJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_TRIANGLE_X)), MENU_Y(Y(TEXT_TRIANGLE_Y)), TheText.Get("FEC_ENV"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CIRCLE_X)), MENU_Y(Y(TEXT_CIRCLE_Y)), TheText.Get("FEC_ATT"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CROSS_X)), MENU_Y(Y(TEXT_CROSS_Y)), TheText.Get("FEC_RUN"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_RSTICK_X)), MENU_Y(Y(TEXT_RSTICK_Y)), TheText.Get("FEC_FPC"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R3_X)), MENU_Y(Y(TEXT_R3_Y)), TheText.Get("FEC_LB3"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R3_X)), MENU_Y(Y(TEXT_R3_Y + 13.0f)), TheText.Get("FEC_R3"));
break;
- case 2:
- CFont::SetRightJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L2_X)), MENU_Y(Y(TEXT_L2_Y)), TheText.Get("FEC_CWL"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L1_X)), MENU_Y(Y(TEXT_L1_Y)), TheText.Get("FEC_ENV"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_DPAD_X)), MENU_Y(Y(TEXT_DPAD_Y)), TheText.Get("FEC_MOV"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_LSTICK_X)), MENU_Y(Y(TEXT_LSTICK_Y)), TheText.Get("FEC_MOV"));
- CFont::SetJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SELECT_X)), MENU_Y(Y(TEXT_SELECT_Y)), TheText.Get("FEC_CAM"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_START_X)), MENU_Y(Y(TEXT_START_Y)), TheText.Get("FEC_PAU"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R2_X)), MENU_Y(Y(TEXT_R2_Y)), TheText.Get("FEC_CWR"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R1_X)), MENU_Y(Y(TEXT_R1_Y)), TheText.Get("FEC_TAR"));
- CFont::SetRightJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)), MENU_Y(Y(TEXT_SQUARE_Y)), TheText.Get("FEC_JUM"));
- CFont::SetJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_TRIANGLE_X)), MENU_Y(Y(TEXT_TRIANGLE_Y)), TheText.Get("FEC_LOF"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CIRCLE_X)), MENU_Y(Y(TEXT_CIRCLE_Y)), TheText.Get("FEC_RUN"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CROSS_X)), MENU_Y(Y(TEXT_CROSS_Y)), TheText.Get("FEC_ATT"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_RSTICK_X)), MENU_Y(Y(TEXT_RSTICK_Y)), TheText.Get("FEC_FPC"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R3_X)), MENU_Y(Y(TEXT_R3_Y)), TheText.Get("FEC_LB3"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R3_X)), MENU_Y(Y(TEXT_R3_Y + 13.0f)), TheText.Get("FEC_R3"));
+ default:
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SELECT_X - 50)), MENU_Y(Y(TEXT_SELECT_Y)), TheText.Get("FEC_NA"));
break;
- case 3:
- CFont::SetRightJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L2_X)), MENU_Y(Y(TEXT_L2_Y)), TheText.Get("FEC_CWL"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L1_X)), MENU_Y(Y(TEXT_L1_Y)), TheText.Get("FEC_TAR"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_DPAD_X)), MENU_Y(Y(TEXT_DPAD_Y)), TheText.Get("FEC_NA"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_LSTICK_X)), MENU_Y(Y(TEXT_LSTICK_Y)), TheText.Get("FEC_MOV"));
- CFont::SetJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SELECT_X)), MENU_Y(Y(TEXT_SELECT_Y)), TheText.Get("FEC_CAM"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_START_X)), MENU_Y(Y(TEXT_START_Y)), TheText.Get("FEC_PAU"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R2_X)), MENU_Y(Y(TEXT_R2_Y)), TheText.Get("FEC_CWR"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R1_X)), MENU_Y(Y(TEXT_R1_Y)), TheText.Get("FEC_ATT"));
- CFont::SetRightJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)), MENU_Y(Y(TEXT_SQUARE_Y)), TheText.Get("FEC_JUM"));
- CFont::SetJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_TRIANGLE_X)), MENU_Y(Y(TEXT_TRIANGLE_Y)), TheText.Get("FEC_ENV"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CIRCLE_X)), MENU_Y(Y(TEXT_CIRCLE_Y)), TheText.Get("FEC_LOF"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CROSS_X)), MENU_Y(Y(TEXT_CROSS_Y)), TheText.Get("FEC_RUN"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_RSTICK_X)), MENU_Y(Y(TEXT_RSTICK_Y)), TheText.Get("FEC_FPC"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R3_X)), MENU_Y(Y(TEXT_R3_Y)), TheText.Get("FEC_LB3"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R3_X)), MENU_Y(Y(TEXT_R3_Y + 13.0f)), TheText.Get("FEC_R3"));
+ }
+ CFont::SetJustifyOn();
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_START_X)), MENU_Y(Y(TEXT_START_Y)), TheText.Get("FEC_PAU"));
+ switch (m_PrefsLanguage)
+ {
+ case LANGUAGE_FRENCH:
+ case LANGUAGE_SPANISH:
+ TEXT_R2_X += 30.0f;
+ CFont::SetJustifyOff();
+ CFont::SetWrapx(MENU_X_LEFT_ALIGNED(X(TEXT_R2_X)) + SCREEN_SCALE_X(120));
break;
default:
- return;
- }
- } else {
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L2R2_X)), MENU_Y(Y(TEXT_L2R2_Y)), TheText.Get("FEC_LB"));
- switch (CPad::GetPad(0)->Mode) {
- case 0:
- CFont::SetRightJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L2_X)), MENU_Y(Y(TEXT_L2_Y)), TheText.Get("FEC_LL"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L1_X)), MENU_Y(Y(TEXT_L1_Y_VEH)), TheText.Get("FEC_RSC"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_DPAD_X)), MENU_Y(Y(TEXT_DPAD_Y)), TheText.Get("FEC_VES"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_LSTICK_X)), MENU_Y(Y(TEXT_LSTICK_Y)), TheText.Get("FEC_VES"));
- CFont::SetJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L3_X)), MENU_Y(Y(TEXT_L3_Y)), TheText.Get("FEC_HO3"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SELECT_X)), MENU_Y(Y(TEXT_SELECT_Y)), TheText.Get("FEC_CAM"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_START_X)), MENU_Y(Y(TEXT_START_Y)), TheText.Get("FEC_PAU"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R2_X)), MENU_Y(Y(TEXT_R2_Y)), TheText.Get("FEC_LR"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R1_X)), MENU_Y(Y(TEXT_R1_Y)), TheText.Get("FEC_HAB"));
- CFont::SetRightJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)), MENU_Y(Y(TEXT_SQUARE_Y)), TheText.Get("FEC_BRA"));
- CFont::SetJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_TRIANGLE_X)), MENU_Y(Y(TEXT_TRIANGLE_Y)), TheText.Get("FEC_EXV"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CIRCLE_X)), MENU_Y(Y(TEXT_CIRCLE_Y)), TheText.Get("FEC_CAW"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CROSS_X)), MENU_Y(Y(TEXT_CROSS_Y)), TheText.Get("FEC_ACC"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_RSTICK_X)), MENU_Y(Y(TEXT_RSTICK_Y)), TheText.Get("FEC_TUC"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R3_X)), MENU_Y(Y(TEXT_R3_Y)), TheText.Get("FEC_SM3"));
break;
- case 1:
- CFont::SetRightJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L2_X)), MENU_Y(Y(TEXT_L2_Y)), TheText.Get("FEC_LL"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L1_X)), MENU_Y(Y(TEXT_L1_Y_VEH)), TheText.Get("FEC_HOR"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_DPAD_X)), MENU_Y(Y(TEXT_DPAD_Y)), TheText.Get("FEC_CAM"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_LSTICK_X)), MENU_Y(Y(TEXT_LSTICK_Y)), TheText.Get("FEC_VES"));
- CFont::SetJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L3_X)), MENU_Y(Y(TEXT_L3_Y)), TheText.Get("FEC_NA"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SELECT_X)), MENU_Y(Y(TEXT_SELECT_Y)), TheText.Get("FEC_RSC"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_START_X)), MENU_Y(Y(TEXT_START_Y)), TheText.Get("FEC_PAU"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R2_X)), MENU_Y(Y(TEXT_R2_Y)), TheText.Get("FEC_LR"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R1_X)), MENU_Y(Y(TEXT_R1_Y)), TheText.Get("FEC_HAB"));
- CFont::SetRightJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)), MENU_Y(Y(TEXT_SQUARE_Y)), TheText.Get("FEC_BRA"));
- CFont::SetJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_TRIANGLE_X)), MENU_Y(Y(TEXT_TRIANGLE_Y)), TheText.Get("FEC_EXV"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CIRCLE_X)), MENU_Y(Y(TEXT_CIRCLE_Y)), TheText.Get("FEC_CAW"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CROSS_X)), MENU_Y(Y(TEXT_CROSS_Y)), TheText.Get("FEC_ACC"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_RSTICK_X)), MENU_Y(Y(TEXT_RSTICK_Y)), TheText.Get("FEC_TUC"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R3_X)), MENU_Y(Y(TEXT_R3_Y)), TheText.Get("FEC_SM3"));
+ }
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R2_X)), MENU_Y(Y(TEXT_R2_Y)), TheText.Get("FEC_CWR"));
+ CFont::SetJustifyOn();
+ CFont::SetWrapx(SCREEN_WIDTH);
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R1_X)), MENU_Y(Y(TEXT_R1_Y)), TheText.Get("FEC_TAR"));
+ CFont::SetRightJustifyOn();
+ CFont::PrintStringFromBottom(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)), MENU_Y(Y(TEXT_SQUARE_Y)), TheText.Get("FEC_JUM"));
+ CFont::SetJustifyOn();
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_TRIANGLE_X)), MENU_Y(Y(TEXT_TRIANGLE_Y)), TheText.Get("FEC_ENV"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CIRCLE_X)), MENU_Y(Y(TEXT_CIRCLE_Y)), TheText.Get("FEC_ATT"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CROSS_X)), MENU_Y(Y(TEXT_CROSS_Y)), TheText.Get("FEC_RUN"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_RSTICK_X)), MENU_Y(Y(TEXT_RSTICK_Y)), TheText.Get("FEC_FPC"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R3_X)), MENU_Y(Y(TEXT_R3_Y)), TheText.Get("FEC_LB3"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R3_X)), MENU_Y(Y(TEXT_R3_Y + 13.0f)), TheText.Get("FEC_R3"));
+ break;
+ case 2:
+ CFont::SetRightJustifyOn();
+ switch (m_PrefsLanguage)
+ {
+ case LANGUAGE_FRENCH:
+ case LANGUAGE_SPANISH:
+ TEXT_L2_X -= 45.0f;
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(X(TEXT_L1_X)) - SCREEN_SCALE_X(85));
break;
- case 2:
- CFont::SetRightJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L2_X)), MENU_Y(Y(TEXT_L2_Y)), TheText.Get("FEC_LL"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L1_X)), MENU_Y(Y(TEXT_L1_Y_VEH)), TheText.Get("FEC_EXV"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_DPAD_X)), MENU_Y(Y(TEXT_DPAD_Y)), TheText.Get("FEC_VES"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_LSTICK_X)), MENU_Y(Y(TEXT_LSTICK_Y)), TheText.Get("FEC_VES"));
- CFont::SetJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L3_X)), MENU_Y(Y(TEXT_L3_Y)), TheText.Get("FEC_RS3"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SELECT_X)), MENU_Y(Y(TEXT_SELECT_Y)), TheText.Get("FEC_CAM"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_START_X)), MENU_Y(Y(TEXT_START_Y)), TheText.Get("FEC_PAU"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R2_X)), MENU_Y(Y(TEXT_R2_Y)), TheText.Get("FEC_LR"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R1_X)), MENU_Y(Y(TEXT_R1_Y)), TheText.Get("FEC_HOR"));
- CFont::SetRightJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)), MENU_Y(Y(TEXT_SQUARE_Y)), TheText.Get("FEC_BRA"));
- CFont::SetJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_TRIANGLE_X)), MENU_Y(Y(TEXT_TRIANGLE_Y)), TheText.Get("FEC_HAB"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CIRCLE_X)), MENU_Y(Y(TEXT_CIRCLE_Y)), TheText.Get("FEC_CAW"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CROSS_X)), MENU_Y(Y(TEXT_CROSS_Y)), TheText.Get("FEC_ACC"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_RSTICK_X)), MENU_Y(Y(TEXT_RSTICK_Y)), TheText.Get("FEC_TUC"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R3_X)), MENU_Y(Y(TEXT_R3_Y)), TheText.Get("FEC_SM3"));
+ default:
+ CFont::SetRightJustifyWrap(0);
break;
- case 3:
- CFont::SetRightJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L2_X)), MENU_Y(Y(TEXT_L2_Y)), TheText.Get("FEC_LL"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L1_X)), MENU_Y(Y(TEXT_L1_Y_VEH)), TheText.Get("FEC_HAB"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_DPAD_X)), MENU_Y(Y(TEXT_DPAD_Y)), TheText.Get("FEC_TUC"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_LSTICK_X)), MENU_Y(Y(TEXT_LSTICK_Y)), TheText.Get("FEC_VES"));
- CFont::SetJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L3_X)), MENU_Y(Y(TEXT_L3_Y)), TheText.Get("FEC_HO3"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SELECT_X)), MENU_Y(Y(TEXT_SELECT_Y)), TheText.Get("FEC_CAM"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_START_X)), MENU_Y(Y(TEXT_START_Y)), TheText.Get("FEC_PAU"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R2_X)), MENU_Y(Y(TEXT_R2_Y)), TheText.Get("FEC_LR"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R1_X)), MENU_Y(Y(TEXT_R1_Y)), TheText.Get("FEC_CAW"));
- CFont::SetRightJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)), MENU_Y(Y(TEXT_SQUARE_Y)), TheText.Get("FEC_SMT"));
- CFont::SetJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_TRIANGLE_X)), MENU_Y(Y(TEXT_TRIANGLE_Y)), TheText.Get("FEC_EXV"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CIRCLE_X)), MENU_Y(Y(TEXT_CIRCLE_Y)), TheText.Get("FEC_RSC"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CROSS_X)), MENU_Y(Y(TEXT_CROSS_Y)), TheText.Get("FEC_NA"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_RSTICK_X)), MENU_Y(Y(TEXT_RSTICK_Y)), TheText.Get("FEC_ACC"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R3_X)), MENU_Y(Y(TEXT_R3_Y)), TheText.Get("FEC_BRA"));
+ }
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L2_X)), MENU_Y(Y(TEXT_L2_Y)), TheText.Get("FEC_CWL"));
+ CFont::SetRightJustifyWrap(0);
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L1_X)), MENU_Y(Y(TEXT_L1_Y)), TheText.Get("FEC_ENV"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_DPAD_X)), MENU_Y(Y(TEXT_DPAD_Y)), TheText.Get("FEC_MOV"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_LSTICK_X)), MENU_Y(Y(TEXT_LSTICK_Y)), TheText.Get("FEC_MOV"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_LSTICK_X)), MENU_Y(Y(TEXT_R3_Y)), TheText.Get("FEC_CR3"));
+ CFont::SetRightJustifyOn();
+ switch (m_PrefsLanguage)
+ {
+ case LANGUAGE_GERMAN:
+ TEXT_SELECT_X += 20.0f;
+ break;
+ case LANGUAGE_SPANISH:
+ TEXT_SELECT_X += 15.0f;
break;
default:
- return;
+ break;
+ }
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SELECT_X)), MENU_Y(Y(TEXT_SELECT_Y)), TheText.Get("FEC_CAM"));
+ CFont::SetJustifyOn();
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_START_X)), MENU_Y(Y(TEXT_START_Y)), TheText.Get("FEC_PAU"));
+ switch (m_PrefsLanguage)
+ {
+ case LANGUAGE_FRENCH:
+ case LANGUAGE_SPANISH:
+ TEXT_R2_X += 30.0f;
+ CFont::SetJustifyOff();
+ CFont::SetWrapx(MENU_X_LEFT_ALIGNED(X(TEXT_R2_X)) + SCREEN_SCALE_X(120));
+ break;
+ default:
+ break;
+ }
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R2_X)), MENU_Y(Y(TEXT_R2_Y)), TheText.Get("FEC_CWR"));
+ CFont::SetJustifyOn();
+ CFont::SetWrapx(SCREEN_WIDTH);
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R1_X)), MENU_Y(Y(TEXT_R1_Y)), TheText.Get("FEC_TAR"));
+ CFont::SetRightJustifyOn();
+ CFont::PrintStringFromBottom(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)), MENU_Y(Y(TEXT_SQUARE_Y)), TheText.Get("FEC_JUM"));
+ CFont::SetJustifyOn();
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_TRIANGLE_X)), MENU_Y(Y(TEXT_TRIANGLE_Y)), TheText.Get("FEC_LOF"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CIRCLE_X)), MENU_Y(Y(TEXT_CIRCLE_Y)), TheText.Get("FEC_RUN"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CROSS_X)), MENU_Y(Y(TEXT_CROSS_Y)), TheText.Get("FEC_ATT"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_RSTICK_X)), MENU_Y(Y(TEXT_RSTICK_Y)), TheText.Get("FEC_FPC"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R3_X)), MENU_Y(Y(TEXT_R3_Y)), TheText.Get("FEC_LB3"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R3_X)), MENU_Y(Y(TEXT_R3_Y + 13.0f)), TheText.Get("FEC_R3"));
+ break;
+ case 3:
+ CFont::SetRightJustifyOn();
+ switch (m_PrefsLanguage)
+ {
+ case LANGUAGE_FRENCH:
+ case LANGUAGE_SPANISH:
+ TEXT_L2_X -= 45.0f;
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(X(TEXT_L1_X)) - SCREEN_SCALE_X(85));
+ break;
+ default:
+ CFont::SetRightJustifyWrap(0);
+ break;
+ }
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L2_X)), MENU_Y(Y(TEXT_L2_Y)), TheText.Get("FEC_CWL"));
+ CFont::SetRightJustifyWrap(0);
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L1_X)), MENU_Y(Y(TEXT_L1_Y)), TheText.Get("FEC_TAR"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_DPAD_X)), MENU_Y(Y(TEXT_DPAD_Y)), TheText.Get("FEC_NA"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_LSTICK_X)), MENU_Y(Y(TEXT_LSTICK_Y)), TheText.Get("FEC_MOV"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_LSTICK_X)), MENU_Y(Y(TEXT_R3_Y)), TheText.Get("FEC_CR3"));
+ CFont::SetRightJustifyOn();
+ switch (m_PrefsLanguage)
+ {
+ case LANGUAGE_GERMAN:
+ TEXT_SELECT_X += 20.0f;
+ break;
+ case LANGUAGE_SPANISH:
+ TEXT_SELECT_X += 15.0f;
+ break;
+ default:
+ break;
+ }
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SELECT_X)), MENU_Y(Y(TEXT_SELECT_Y)), TheText.Get("FEC_CAM"));
+ CFont::SetJustifyOn();
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_START_X)), MENU_Y(Y(TEXT_START_Y)), TheText.Get("FEC_PAU"));
+ switch (m_PrefsLanguage)
+ {
+ case LANGUAGE_FRENCH:
+ case LANGUAGE_SPANISH:
+ TEXT_R2_X += 30.0f;
+ CFont::SetJustifyOff();
+ CFont::SetWrapx(MENU_X_LEFT_ALIGNED(X(TEXT_R2_X)) + SCREEN_SCALE_X(120));
+ break;
+ default:
+ break;
+ }
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R2_X)), MENU_Y(Y(TEXT_R2_Y)), TheText.Get("FEC_CWR"));
+ CFont::SetJustifyOn();
+ CFont::SetWrapx(SCREEN_WIDTH);
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R1_X)), MENU_Y(Y(TEXT_R1_Y)), TheText.Get("FEC_ATT"));
+ CFont::SetRightJustifyOn();
+ CFont::PrintStringFromBottom(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)), MENU_Y(Y(TEXT_SQUARE_Y)), TheText.Get("FEC_JUM"));
+ CFont::SetJustifyOn();
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_TRIANGLE_X)), MENU_Y(Y(TEXT_TRIANGLE_Y)), TheText.Get("FEC_ENV"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CIRCLE_X)), MENU_Y(Y(TEXT_CIRCLE_Y)), TheText.Get("FEC_LOF"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CROSS_X)), MENU_Y(Y(TEXT_CROSS_Y)), TheText.Get("FEC_RUN"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_RSTICK_X)), MENU_Y(Y(TEXT_RSTICK_Y)), TheText.Get("FEC_FPC"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R3_X)), MENU_Y(Y(TEXT_R3_Y)), TheText.Get("FEC_LB3"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R3_X)), MENU_Y(Y(TEXT_R3_Y + 13.0f)), TheText.Get("FEC_R3"));
+ break;
+ default:
+ return;
}
}
-
- CFont::SetDropShadowPosition(0); // X
-
-#undef X
-#undef Y
-}
-#else
-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) {
+ else {
+ CFont::SetCentreOn();
+ switch (m_PrefsLanguage)
+ {
+ case LANGUAGE_ITALIAN:
+ if (m_PrefsControllerType != CONTROLLER_XBOX360)
+ break;
+ case LANGUAGE_FRENCH:
+ case LANGUAGE_GERMAN:
+ CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE * 2 * scale * 0.65f), MENU_Y(SMALLESTTEXT_Y_SCALE * scale * 0.65f));
+ break;
+ default:
+ break;
+ }
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(0.0f)), MENU_Y(Y(TEXT_L2R2_Y)), TheText.Get("FEC_LB"));
+ CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE * 2 * scale * 0.9f), MENU_Y(SMALLESTTEXT_Y_SCALE* scale * 0.9f));
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"));
+ case 0:
+ CFont::SetRightJustifyOn();
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L2_X)), MENU_Y(Y(TEXT_L2_Y)), TheText.Get("FEC_LL"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L1_X)), MENU_Y(Y(TEXT_L1_Y_VEH)), TheText.Get("FEC_RSC"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_DPAD_X)), MENU_Y(Y(TEXT_DPAD_Y)), TheText.Get("FEC_VES"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_LSTICK_X)), MENU_Y(Y(TEXT_LSTICK_Y)), TheText.Get("FEC_VES"));
+ CFont::SetRightJustifyOn();
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L3_X)), MENU_Y(Y(TEXT_L3_Y)), TheText.Get("FEC_HO3"));
+ switch (m_PrefsLanguage)
+ {
+ case LANGUAGE_FRENCH:
+ TEXT_SELECT_X -= 5.0f;
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"));
+ case LANGUAGE_GERMAN:
+ TEXT_SELECT_X += 20.0f;
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"));
+ case LANGUAGE_SPANISH:
+ TEXT_SELECT_X += 15.0f;
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"));
+ default:
+ break;
+ }
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(X(TEXT_SELECT_X)) - SCREEN_SCALE_X(80));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SELECT_X)), MENU_Y(Y(TEXT_SELECT_Y)), TheText.Get("FEC_CAM"));
+ CFont::SetJustifyOn();
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_START_X)), MENU_Y(Y(TEXT_START_Y)), TheText.Get("FEC_PAU"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R2_X)), MENU_Y(Y(TEXT_R2_Y)), TheText.Get("FEC_LR"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R1_X)), MENU_Y(Y(TEXT_R1_Y)), TheText.Get("FEC_HAB"));
+ CFont::SetJustifyOn();
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_TRIANGLE_X)), MENU_Y(Y(TEXT_TRIANGLE_Y)), TheText.Get("FEC_EXV"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CIRCLE_X)), MENU_Y(Y(TEXT_CIRCLE_Y)), TheText.Get("FEC_CAW"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CROSS_X)), MENU_Y(Y(TEXT_CROSS_Y)), TheText.Get("FEC_ACC"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_RSTICK_X)), MENU_Y(Y(TEXT_RSTICK_Y)), TheText.Get("FEC_TUC"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R3_X)), MENU_Y(Y(TEXT_R3_Y)), TheText.Get("FEC_SM3"));
+ CFont::SetRightJustifyOn();
+ switch (m_PrefsControllerType)
+ {
+ case CONTROLLER_XBOXONE:
+ case CONTROLLER_XBOX360:
+ case CONTROLLER_NINTENDO_SWITCH:
+ CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE * 2 * scale * 0.65f), MENU_Y(SMALLESTTEXT_Y_SCALE * scale * 0.65f));
+ switch (m_PrefsLanguage)
+ {
+ case LANGUAGE_FRENCH:
+ TEXT_SQUARE_X += 3.0f;
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)) - SCREEN_SCALE_X(90));
+ break;
+ case LANGUAGE_GERMAN:
+ case LANGUAGE_SPANISH:
+ TEXT_SQUARE_X += 18.0f;
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)) - SCREEN_SCALE_X(90));
+ break;
+ default:
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)) - SCREEN_SCALE_X(60));
+ break;
+ }
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"));
+ switch (m_PrefsLanguage)
+ {
+ case LANGUAGE_FRENCH:
+ TEXT_SQUARE_X -= 15.0f;
+ TEXT_SQUARE_Y += 5.0f;
+ CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE * 2 * scale * 0.65f), MENU_Y(SMALLESTTEXT_Y_SCALE * scale * 0.65f));
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)) - SCREEN_SCALE_X(60));
+ break;
+ case LANGUAGE_GERMAN:
+ TEXT_SQUARE_X -= 15.0f;
+ TEXT_SQUARE_Y += 10.0f;
+ CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE * 2 * scale * 0.65f), MENU_Y(SMALLESTTEXT_Y_SCALE* scale * 0.65f));
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)) - SCREEN_SCALE_X(60));
+ break;
+ case LANGUAGE_SPANISH:
+ TEXT_SQUARE_X += 15.0f;
+ case LANGUAGE_ITALIAN:
+ CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE * 2 * scale * 0.65f), MENU_Y(SMALLESTTEXT_Y_SCALE * scale * 0.65f));
+ default:
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)) - SCREEN_SCALE_X(100));
+ break;
+ }
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"));
+ }
+ CFont::PrintStringFromBottom(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)), MENU_Y(Y(TEXT_SQUARE_Y)), TheText.Get("FEC_BRA"));
+ break;
+ case 1:
+ CFont::SetRightJustifyOn();
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L2_X)), MENU_Y(Y(TEXT_L2_Y)), TheText.Get("FEC_LL"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L1_X)), MENU_Y(Y(TEXT_L1_Y_VEH)), TheText.Get("FEC_HOR"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_DPAD_X)), MENU_Y(Y(TEXT_DPAD_Y)), TheText.Get("FEC_CAM"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_LSTICK_X)), MENU_Y(Y(TEXT_LSTICK_Y)), TheText.Get("FEC_VES"));
+ CFont::SetRightJustifyOn();
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L3_X)), MENU_Y(Y(TEXT_L3_Y)), TheText.Get("FEC_NA"));
+ switch (m_PrefsLanguage)
+ {
+ case LANGUAGE_GERMAN:
+ TEXT_SELECT_X += 20.0f;
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"));
+ case LANGUAGE_SPANISH:
+ TEXT_SELECT_X += 12.0f;
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"));
+ default:
+ break;
+ }
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(X(TEXT_SELECT_X)) - SCREEN_SCALE_X(80));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SELECT_X)), MENU_Y(Y(TEXT_SELECT_Y)), TheText.Get("FEC_RSC"));
+ CFont::SetJustifyOn();
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_START_X)), MENU_Y(Y(TEXT_START_Y)), TheText.Get("FEC_PAU"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R2_X)), MENU_Y(Y(TEXT_R2_Y)), TheText.Get("FEC_LR"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R1_X)), MENU_Y(Y(TEXT_R1_Y)), TheText.Get("FEC_HAB"));
+ CFont::SetJustifyOn();
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_TRIANGLE_X)), MENU_Y(Y(TEXT_TRIANGLE_Y)), TheText.Get("FEC_EXV"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CIRCLE_X)), MENU_Y(Y(TEXT_CIRCLE_Y)), TheText.Get("FEC_CAW"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CROSS_X)), MENU_Y(Y(TEXT_CROSS_Y)), TheText.Get("FEC_ACC"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_RSTICK_X)), MENU_Y(Y(TEXT_RSTICK_Y)), TheText.Get("FEC_TUC"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R3_X)), MENU_Y(Y(TEXT_R3_Y)), TheText.Get("FEC_SM3"));
+ CFont::SetRightJustifyOn();
+ switch (m_PrefsControllerType)
+ {
+ case CONTROLLER_XBOXONE:
+ case CONTROLLER_XBOX360:
+ case CONTROLLER_NINTENDO_SWITCH:
+ CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE * 2 * scale * 0.65f), MENU_Y(SMALLESTTEXT_Y_SCALE * scale * 0.65f));
+ switch (m_PrefsLanguage)
+ {
+ case LANGUAGE_FRENCH:
+ TEXT_SQUARE_X += 3.0f;
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)) - SCREEN_SCALE_X(90));
+ break;
+ case LANGUAGE_GERMAN:
+ case LANGUAGE_SPANISH:
+ TEXT_SQUARE_X += 18.0f;
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)) - SCREEN_SCALE_X(90));
+ break;
+ default:
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)) - SCREEN_SCALE_X(60));
+ break;
+ }
break;
default:
- return;
+ switch (m_PrefsLanguage)
+ {
+ case LANGUAGE_FRENCH:
+ TEXT_SQUARE_X -= 15.0f;
+ TEXT_SQUARE_Y += 5.0f;
+ CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE * 2 * scale * 0.65f), MENU_Y(SMALLESTTEXT_Y_SCALE * scale * 0.65f));
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)) - SCREEN_SCALE_X(60));
+ break;
+ case LANGUAGE_GERMAN:
+ TEXT_SQUARE_X -= 15.0f;
+ TEXT_SQUARE_Y += 10.0f;
+ CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE * 2 * scale * 0.65f), MENU_Y(SMALLESTTEXT_Y_SCALE * scale * 0.65f));
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)) - SCREEN_SCALE_X(60));
+ break;
+ case LANGUAGE_SPANISH:
+ TEXT_SQUARE_X += 15.0f;
+ case LANGUAGE_ITALIAN:
+ CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE * 2 * scale * 0.65f), MENU_Y(SMALLESTTEXT_Y_SCALE * scale * 0.65f));
+ default:
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)) - SCREEN_SCALE_X(100));
+ break;
+ }
+ break;
+ }
+ CFont::PrintStringFromBottom(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)), MENU_Y(Y(TEXT_SQUARE_Y)), TheText.Get("FEC_BRA"));
+ break;
+ case 2:
+ CFont::SetRightJustifyOn();
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L2_X)), MENU_Y(Y(TEXT_L2_Y)), TheText.Get("FEC_LL"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L1_X)), MENU_Y(Y(TEXT_L1_Y_VEH)), TheText.Get("FEC_EXV"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_DPAD_X)), MENU_Y(Y(TEXT_DPAD_Y)), TheText.Get("FEC_VES"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_LSTICK_X)), MENU_Y(Y(TEXT_LSTICK_Y)), TheText.Get("FEC_VES"));
+ CFont::SetRightJustifyOn();
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L3_X)), MENU_Y(Y(TEXT_L3_Y)), TheText.Get("FEC_RS3"));
+ switch (m_PrefsLanguage)
+ {
+ case LANGUAGE_FRENCH:
+ TEXT_SELECT_X -= 5.0f;
+ break;
+ case LANGUAGE_GERMAN:
+ TEXT_SELECT_X += 20.0f;
+ break;
+ case LANGUAGE_SPANISH:
+ TEXT_SELECT_X += 15.0f;
+ break;
+ default:
+ break;
+ }
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(X(TEXT_SELECT_X)) - SCREEN_SCALE_X(80));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SELECT_X)), MENU_Y(Y(TEXT_SELECT_Y)), TheText.Get("FEC_CAM"));
+ CFont::SetJustifyOn();
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_START_X)), MENU_Y(Y(TEXT_START_Y)), TheText.Get("FEC_PAU"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R2_X)), MENU_Y(Y(TEXT_R2_Y)), TheText.Get("FEC_LR"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R1_X)), MENU_Y(Y(TEXT_R1_Y)), TheText.Get("FEC_HOR"));
+ CFont::SetJustifyOn();
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_TRIANGLE_X)), MENU_Y(Y(TEXT_TRIANGLE_Y)), TheText.Get("FEC_HAB"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CIRCLE_X)), MENU_Y(Y(TEXT_CIRCLE_Y)), TheText.Get("FEC_CAW"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CROSS_X)), MENU_Y(Y(TEXT_CROSS_Y)), TheText.Get("FEC_ACC"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_RSTICK_X)), MENU_Y(Y(TEXT_RSTICK_Y)), TheText.Get("FEC_TUC"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R3_X)), MENU_Y(Y(TEXT_R3_Y)), TheText.Get("FEC_SM3"));
+ CFont::SetRightJustifyOn();
+ switch (m_PrefsControllerType)
+ {
+ case CONTROLLER_XBOXONE:
+ case CONTROLLER_XBOX360:
+ case CONTROLLER_NINTENDO_SWITCH:
+ CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE * 2 * scale * 0.65f), MENU_Y(SMALLESTTEXT_Y_SCALE * scale * 0.65f));
+ switch (m_PrefsLanguage)
+ {
+ case LANGUAGE_FRENCH:
+ TEXT_SQUARE_X += 3.0f;
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)) - SCREEN_SCALE_X(90));
+ break;
+ case LANGUAGE_GERMAN:
+ case LANGUAGE_SPANISH:
+ TEXT_SQUARE_X += 18.0f;
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)) - SCREEN_SCALE_X(90));
+ break;
+ default:
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)) - SCREEN_SCALE_X(60));
+ break;
+ }
+ break;
+ default:
+ switch (m_PrefsLanguage)
+ {
+ case LANGUAGE_FRENCH:
+ TEXT_SQUARE_X -= 15.0f;
+ TEXT_SQUARE_Y += 5.0f;
+ CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE * 2 * scale * 0.65f), MENU_Y(SMALLESTTEXT_Y_SCALE * scale * 0.65f));
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)) - SCREEN_SCALE_X(60));
+ break;
+ case LANGUAGE_GERMAN:
+ TEXT_SQUARE_X -= 15.0f;
+ TEXT_SQUARE_Y += 10.0f;
+ CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE * 2 * scale * 0.65f), MENU_Y(SMALLESTTEXT_Y_SCALE * scale * 0.65f));
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)) - SCREEN_SCALE_X(60));
+ break;
+ case LANGUAGE_SPANISH:
+ TEXT_SQUARE_X += 15.0f;
+ case LANGUAGE_ITALIAN:
+ CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE * 2 * scale * 0.65f), MENU_Y(SMALLESTTEXT_Y_SCALE * scale * 0.65f));
+ default:
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)) - SCREEN_SCALE_X(100));
+ break;
+ }
+ break;
+ }
+ CFont::PrintStringFromBottom(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)), MENU_Y(Y(TEXT_SQUARE_Y)), TheText.Get("FEC_BRA"));
+ break;
+ case 3:
+ CFont::SetRightJustifyOn();
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L2_X)), MENU_Y(Y(TEXT_L2_Y)), TheText.Get("FEC_LL"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L1_X)), MENU_Y(Y(TEXT_L1_Y_VEH)), TheText.Get("FEC_HAB"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_DPAD_X)), MENU_Y(Y(TEXT_DPAD_Y)), TheText.Get("FEC_TUC"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_LSTICK_X)), MENU_Y(Y(TEXT_LSTICK_Y)), TheText.Get("FEC_VES"));
+ CFont::SetRightJustifyOn();
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L3_X)), MENU_Y(Y(TEXT_L3_Y)), TheText.Get("FEC_HO3"));
+ switch (m_PrefsLanguage)
+ {
+ case LANGUAGE_FRENCH:
+ TEXT_SELECT_X -= 5.0f;
+ break;
+ case LANGUAGE_GERMAN:
+ TEXT_SELECT_X += 20.0f;
+ break;
+ case LANGUAGE_SPANISH:
+ TEXT_SELECT_X += 15.0f;
+ break;
+ default:
+ break;
+ }
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(X(TEXT_SELECT_X)) - SCREEN_SCALE_X(80));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SELECT_X)), MENU_Y(Y(TEXT_SELECT_Y)), TheText.Get("FEC_CAM"));
+ CFont::SetJustifyOn();
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_START_X)), MENU_Y(Y(TEXT_START_Y)), TheText.Get("FEC_PAU"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R2_X)), MENU_Y(Y(TEXT_R2_Y)), TheText.Get("FEC_LR"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R1_X)), MENU_Y(Y(TEXT_R1_Y)), TheText.Get("FEC_CAW"));
+ CFont::SetJustifyOn();
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_TRIANGLE_X)), MENU_Y(Y(TEXT_TRIANGLE_Y)), TheText.Get("FEC_EXV"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CIRCLE_X)), MENU_Y(Y(TEXT_CIRCLE_Y)), TheText.Get("FEC_RSC"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CROSS_X)), MENU_Y(Y(TEXT_CROSS_Y)), TheText.Get("FEC_NA"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_RSTICK_X)), MENU_Y(Y(TEXT_RSTICK_Y)), TheText.Get("FEC_ACC"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R3_X)), MENU_Y(Y(TEXT_R3_Y)), TheText.Get("FEC_BRA"));
+ CFont::SetRightJustifyOn();
+ CFont::SetRightJustifyWrap(0);
+ switch (m_PrefsControllerType)
+ {
+ case CONTROLLER_XBOXONE:
+ case CONTROLLER_XBOX360:
+ case CONTROLLER_NINTENDO_SWITCH:
+ CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE * 2 * scale * 0.65f), MENU_Y(SMALLESTTEXT_Y_SCALE * scale * 0.65f));
+ CFont::PrintStringFromBottom(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)), MENU_Y(Y(TEXT_SQUARE_Y)), TheText.Get("FEC_SMT"));
+ break;
+ default:
+ switch (m_PrefsLanguage)
+ {
+ case LANGUAGE_GERMAN:
+ TEXT_SQUARE_X += 5.0f;
+ case LANGUAGE_FRENCH:
+ case LANGUAGE_ITALIAN:
+ CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE * 2 * scale * 0.65f), MENU_Y(SMALLESTTEXT_Y_SCALE * scale * 0.65f));
+ CFont::PrintStringFromBottom(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)), MENU_Y(Y(TEXT_SQUARE_Y)), TheText.Get("FEC_SMT"));
+ break;
+ default:
+ CFont::PrintStringFromBottom(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X + 16.0f)), MENU_Y(Y(TEXT_SQUARE_Y)), TheText.Get("FEC_SMT"));
+ break;
+ }
+ break;
+ }
+ break;
+ default:
+ return;
}
}
CFont::SetDropShadowPosition(0); // X
+
+#undef X
+#undef Y
}
-#endif
-#ifdef MENU_MAP
-
-#define ZOOM(x, y, in) \
- do { \
- if(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); \
- \
- if (fMapSize < SCREEN_HEIGHT / 2 && !in) \
- break; \
- \
- fMapSize *= z2; \
- } while(0) \
void
-CMenuManager::PrintMap(void)
+CMenuManager::LoadController(int8 type)
{
- CFont::SetJustifyOn();
- bMenuMapActive = true;
- CRadar::InitFrontEndMap();
-
- if (m_nMenuFadeAlpha < 255 && fMapCenterX == 0.f && fMapCenterY == 0.f) {
- // Just entered. We need to do these transformations in here, because Radar knows whether map is active or not
- 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;
- }
-
- // Because fMapSize is half of the map length, and map consists of 3x3 tiles.
- float halfTile = fMapSize / 3.0f;
-
- // Darken background a bit
- CSprite2d::DrawRect(CRect(0, 0,
- SCREEN_WIDTH, SCREEN_HEIGHT),
- CRGBA(0, 0, 0, FadeIn(128)));
-
- 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 >= 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 >= 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 >= 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 >= 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 >= 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 >= 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 >= 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 >= 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)));
- }
-
- CRadar::DrawBlips();
- static CVector2D mapCrosshair;
-
- if (m_nMenuFadeAlpha != 255 && !m_bShowMouse) {
- mapCrosshair.x = SCREEN_WIDTH / 2;
- mapCrosshair.y = SCREEN_HEIGHT / 2;
- } else if (m_bShowMouse) {
- mapCrosshair.x = m_nMousePosX;
- mapCrosshair.y = m_nMousePosY;
- }
-
- CSprite2d::DrawRect(CRect(mapCrosshair.x - MENU_X(1.0f), 0.0f,
- mapCrosshair.x + MENU_X(1.0f), SCREEN_HEIGHT),
- CRGBA(0, 0, 0, 150));
- CSprite2d::DrawRect(CRect(0.0f, mapCrosshair.y + MENU_X(1.0f),
- SCREEN_WIDTH, mapCrosshair.y - MENU_X(1.0f)),
- CRGBA(0, 0, 0, 150));
-
- // Adding marker
- if (m_nMenuFadeAlpha >= 255) {
- if (CPad::GetPad(0)->GetRightMouseJustDown() || CPad::GetPad(0)->GetCrossJustDown()) {
- if (mapCrosshair.y > fMapCenterY - fMapSize && mapCrosshair.y < fMapCenterY + fMapSize &&
- mapCrosshair.x > fMapCenterX - fMapSize && mapCrosshair.x < fMapCenterX + fMapSize) {
-
- float diffX = fMapCenterX - fMapSize, diffY = fMapCenterY - fMapSize;
- float x = ((mapCrosshair.x - diffX) / (fMapSize * 2)) * 4000.0f - 2000.0f;
- float y = 2000.0f - ((mapCrosshair.y - diffY) / (fMapSize * 2)) * 4000.0f;
- CRadar::ToggleTargetMarker(x, y);
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
- }
- }
- }
-
- if (CPad::GetPad(0)->GetLeftMouse()) {
- fMapCenterX += m_nMousePosX - m_nMouseOldPosX;
- fMapCenterY += m_nMousePosY - m_nMouseOldPosY;
- } else if (CPad::GetPad(0)->GetLeft() || CPad::GetPad(0)->GetDPadLeft()) {
- fMapCenterX += 15.0f;
- } else if (CPad::GetPad(0)->GetRight() || CPad::GetPad(0)->GetDPadRight()) {
- fMapCenterX -= 15.0f;
- } else if (CPad::GetPad(0)->GetLeftStickX()) {
- fMapCenterX -= CPad::GetPad(0)->GetLeftStickX() / 128.0f * 20.0f;
- }
-
- if (CPad::GetPad(0)->GetUp() || CPad::GetPad(0)->GetDPadUp()) {
- fMapCenterY += 15.0f;
- } else if (CPad::GetPad(0)->GetDown() || CPad::GetPad(0)->GetDPadDown()) {
- fMapCenterY -= 15.0f;
- } else if (CPad::GetPad(0)->GetLeftStickY()) {
- fMapCenterY -= CPad::GetPad(0)->GetLeftStickY() / 128.0f * 20.0f;
- }
-
- if (CPad::GetPad(0)->GetMouseWheelDown() || CPad::GetPad(0)->GetPageDown() || CPad::GetPad(0)->GetRightShoulder2()) {
- if (CPad::GetPad(0)->GetMouseWheelDown())
- ZOOM(mapCrosshair.x, mapCrosshair.y, false);
- else
- ZOOM(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, false);
- } else if (CPad::GetPad(0)->GetMouseWheelUp() || CPad::GetPad(0)->GetPageUp() || CPad::GetPad(0)->GetRightShoulder1()) {
- if (CPad::GetPad(0)->GetMouseWheelUp())
- ZOOM(mapCrosshair.x, mapCrosshair.y, true);
- else
- ZOOM(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, true);
+ switch (type)
+ {
+ case CONTROLLER_DUALSHOCK2:
+ case CONTROLLER_DUALSHOCK3:
+ case CONTROLLER_DUALSHOCK4:
+ CFont::LoadButtons("MODELS/PS3BTNS.TXD");
+ break;
+ case CONTROLLER_NINTENDO_SWITCH:
+ CFont::LoadButtons("MODELS/NSWBTNS.TXD");
+ break;
+ default:
+ CFont::LoadButtons("MODELS/X360BTNS.TXD");
+ break;
}
-
- if (fMapCenterX - fMapSize > SCREEN_WIDTH / 2)
- fMapCenterX = fMapSize + SCREEN_WIDTH / 2;
-
- if (fMapCenterX + fMapSize < SCREEN_WIDTH / 2)
- fMapCenterX = SCREEN_WIDTH / 2 - fMapSize;
-
- if (fMapCenterY + fMapSize < SCREEN_HEIGHT - MENU_Y(60.0f))
- fMapCenterY = SCREEN_HEIGHT - MENU_Y(60.0f) - fMapSize;
-
- fMapCenterY = Min(fMapCenterY, fMapSize); // To not show beyond north border
-
- bMenuMapActive = false;
- 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));
-
- CFont::SetScale(MENU_X(0.4f), MENU_Y(0.7f));
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
- CFont::SetColor(CRGBA(HEADER_COLOR.r, HEADER_COLOR.g, HEADER_COLOR.b, FadeIn(255)));
-
- float nextX = MENU_X(30.0f), nextY = 95.0f;
- wchar *text;
-#ifdef MORE_LANGUAGES
-#define TEXT_PIECE(key,extraSpace) \
- text = TheText.Get(key);\
- CFont::PrintString(nextX, SCREEN_SCALE_FROM_BOTTOM(nextY), text);\
- if (CFont::IsJapanese())\
- nextX += CFont::GetStringWidth_Jap(text) + MENU_X(extraSpace);\
- else\
- nextX += CFont::GetStringWidth(text, true) + MENU_X(extraSpace);
-#else
-#define TEXT_PIECE(key,extraSpace) \
- text = TheText.Get(key); CFont::PrintString(nextX, SCREEN_SCALE_FROM_BOTTOM(nextY), text); nextX += CFont::GetStringWidth(text, true) + MENU_X(extraSpace);
-#endif
-
- TEXT_PIECE("FEC_MWF", 3.0f);
- TEXT_PIECE("FEC_PGU", 1.0f);
- TEXT_PIECE("FEC_IBT", 1.0f);
- TEXT_PIECE("FEC_ZIN", 20.0f);
- TEXT_PIECE("FEC_MWB", 3.0f);
- TEXT_PIECE("FEC_PGD", 1.0f);
- TEXT_PIECE("FEC_IBT", 1.0f);
- CFont::PrintString(nextX, SCREEN_SCALE_FROM_BOTTOM(nextY), TheText.Get("FEC_ZOT")); nextX = MENU_X(30.0f); nextY -= 11.0f;
- TEXT_PIECE("FEC_UPA", 2.0f);
- TEXT_PIECE("FEC_DWA", 2.0f);
- TEXT_PIECE("FEC_LFA", 2.0f);
- TEXT_PIECE("FEC_RFA", 2.0f);
- TEXT_PIECE("FEC_MSL", 1.0f);
- TEXT_PIECE("FEC_IBT", 1.0f);
- CFont::PrintString(nextX, SCREEN_SCALE_FROM_BOTTOM(nextY), TheText.Get("FEC_MOV")); nextX = MENU_X(30.0f); nextY -= 11.0f;
- TEXT_PIECE("FEC_MSR", 2.0f);
- TEXT_PIECE("FEC_IBT", 1.0f);
- CFont::PrintString(nextX, SCREEN_SCALE_FROM_BOTTOM(nextY), TheText.Get("FEM_TWP"));
-#undef TEXT_PIECE
-}
-
-#undef ZOOM
-#endif
-
-// rowIdx 99999 returns total numbers of rows. otherwise it returns 0.
-int
-CMenuManager::ConstructStatLine(int rowIdx)
-{
-#define int_STAT_IS_FLOAT false
-#define float_STAT_IS_FLOAT true
-#define STAT_LINE_1(varType, left, right1) \
- do { \
- if(counter == rowIdx){ \
- varType a = right1; \
- BuildStatLine(left, &a, varType##_STAT_IS_FLOAT, nil); \
- return 0; \
- } counter++; \
- } while(0)
-
-#define STAT_LINE_2(varType, left, right1, right2) \
- do { \
- if(counter == rowIdx){ \
- varType a = right1; \
- varType b = right2; \
- BuildStatLine(left, &a, varType##_STAT_IS_FLOAT, &b); \
- return 0; \
- } counter++; \
- } while(0)
-
-#define TEXT_ON_LEFT_GXT(name) \
- do { \
- if(counter == rowIdx){ \
- BuildStatLine(name, nil, false, nil); \
- return 0; \
- } counter++; \
- } while(0)
-
-#define TEXT_ON_RIGHT(text) \
- do { \
- if(counter == rowIdx){ \
- gUString[0] = '\0'; \
- UnicodeStrcpy(gUString2, text); \
- return 0; \
- } counter++; \
- } while(0)
-
- // Like TEXT_ON_LEFT_GXT, but counter wasn't initialized yet I think
- if (rowIdx == 0) {
- BuildStatLine("PL_STAT", nil, false, nil);
- return 0;
- }
+ // Unload current textures
+ for (int i = MENUSPRITE_CONTROLLER; i <= MENUSPRITE_ARROWS4; i++)
+ m_aFrontEndSprites[i].Delete();
- int percentCompleted = (CStats::TotalProgressInGame == 0 ? 0 :
- CStats::ProgressMade * 100.0f / (CGame::nastyGame ? CStats::TotalProgressInGame : CStats::TotalProgressInGame - 1));
- percentCompleted = Min(percentCompleted, 100);
+ // Unload txd
+ int frontend_controller = CTxdStore::FindTxdSlot("frontend_controller");
+ if (frontend_controller != -1)
+ CTxdStore::RemoveTxd(frontend_controller);
- switch (rowIdx) {
- // 0 is the heading text above
- case 1: {
- BuildStatLine("PER_COM", &percentCompleted, false, nil);
- return 0;
- }
- case 2: {
- BuildStatLine("NMISON", &CStats::MissionsGiven, false, nil);
- return 0;
- }
- case 3: {
- BuildStatLine("FEST_MP", &CStats::MissionsPassed, false, &CStats::TotalNumberMissions);
- return 0;
+ // Find the new txd to load
+ bool bTxdMissing = true;
+ if (controllerTypesPaths[type])
+ if (int file = CFileMgr::OpenFile(controllerTypesPaths[type])) {
+ CFileMgr::CloseFile(file);
+ bTxdMissing = false;
}
- }
- int counter = 4;
-
- if (CGame::nastyGame)
- STAT_LINE_2(int, "FEST_RP", CStats::NumberKillFrenziesPassed, CStats::TotalNumberKillFrenzies);
-
- CPlayerInfo &player = CWorld::Players[CWorld::PlayerInFocus];
-
- // Hidden packages shouldn't be shown with percent
-#ifdef FIX_BUGS
- STAT_LINE_2(int, "PERPIC", player.m_nCollectedPackages, player.m_nTotalPackages);
-#else
- float packagesPercent = 0.0f;
- if (player.m_nTotalPackages != 0)
- packagesPercent = player.m_nCollectedPackages * 100.0f / player.m_nTotalPackages;
-
- STAT_LINE_2(int, "PERPIC", packagesPercent, 100);
-#endif
- STAT_LINE_2(int, "NOUNIF", CStats::NumberOfUniqueJumpsFound, CStats::TotalNumberOfUniqueJumps);
- STAT_LINE_1(int, "DAYSPS", CStats::DaysPassed);
- if (CGame::nastyGame) {
- STAT_LINE_1(int, "PE_WAST", CStats::PeopleKilledByPlayer);
- STAT_LINE_1(int, "PE_WSOT", CStats::PeopleKilledByOthers);
- }
- STAT_LINE_1(int, "CAR_EXP", CStats::CarsExploded);
- STAT_LINE_1(int, "TM_BUST", CStats::TimesArrested);
- STAT_LINE_1(int, "TM_DED", CStats::TimesDied);
- STAT_LINE_1(int, "GNG_WST", CStats::PedsKilledOfThisType[PEDTYPE_GANG9] + CStats::PedsKilledOfThisType[PEDTYPE_GANG8]
- + CStats::PedsKilledOfThisType[PEDTYPE_GANG7] + CStats::PedsKilledOfThisType[PEDTYPE_GANG6]
- + CStats::PedsKilledOfThisType[PEDTYPE_GANG5] + CStats::PedsKilledOfThisType[PEDTYPE_GANG4]
- + CStats::PedsKilledOfThisType[PEDTYPE_GANG3] + CStats::PedsKilledOfThisType[PEDTYPE_GANG2]
- + CStats::PedsKilledOfThisType[PEDTYPE_GANG1]);
- STAT_LINE_1(int, "DED_CRI", CStats::PedsKilledOfThisType[PEDTYPE_CRIMINAL]);
- STAT_LINE_1(int, "HEL_DST", CStats::HelisDestroyed);
- STAT_LINE_1(int, "KGS_EXP", CStats::KgsOfExplosivesUsed);
- STAT_LINE_1(int, "ACCURA", (CStats::InstantHitsFiredByPlayer == 0 ? 0 :
- CStats::InstantHitsHitByPlayer * 100.0f / CStats::InstantHitsFiredByPlayer));
-
- if (CStats::ElBurroTime > 0) {
- STAT_LINE_1(int, "ELBURRO", CStats::ElBurroTime);
- }
- if (CStats::Record4x4One > 0) {
- STAT_LINE_1(int, "FEST_R1", CStats::Record4x4One);
- }
- if (CStats::Record4x4Two > 0) {
- STAT_LINE_1(int, "FEST_R2", CStats::Record4x4Two);
- }
- if (CStats::Record4x4Three > 0) {
- STAT_LINE_1(int, "FEST_R3", CStats::Record4x4Three);
- }
- if (CStats::Record4x4Mayhem > 0) {
- STAT_LINE_1(int, "FEST_RM", CStats::Record4x4Mayhem);
- }
- if (CStats::LongestFlightInDodo > 0) {
- STAT_LINE_1(int, "FEST_LF", CStats::LongestFlightInDodo);
- }
- if (CStats::TimeTakenDefuseMission > 0) {
- STAT_LINE_1(int, "FEST_BD", CStats::TimeTakenDefuseMission);
- }
- STAT_LINE_1(int, "CAR_CRU", CStats::CarsCrushed);
- if (CStats::HighestScores[0] > 0) {
- TEXT_ON_LEFT_GXT("FEST_BB");
- STAT_LINE_1(int, "FEST_H0", CStats::HighestScores[0]);
- }
- if (CStats::HighestScores[4] + CStats::HighestScores[3] + CStats::HighestScores[2] + CStats::HighestScores[1] > 0) {
- TEXT_ON_LEFT_GXT("FEST_GC");
- }
- if (CStats::HighestScores[1] > 0) {
- STAT_LINE_1(int, "FEST_H1", CStats::HighestScores[1]);
- }
- if (CStats::HighestScores[2] > 0) {
- STAT_LINE_1(int, "FEST_H2", CStats::HighestScores[2]);
- }
- if (CStats::HighestScores[3] > 0) {
- STAT_LINE_1(int, "FEST_H3", CStats::HighestScores[3]);
- }
- if (CStats::HighestScores[4] > 0) {
- STAT_LINE_1(int, "FEST_H4", CStats::HighestScores[4]);
- }
+ int txdSlot = -1;
- switch (m_PrefsLanguage) {
- case LANGUAGE_AMERICAN:
-#ifndef USE_MEASUREMENTS_IN_METERS
- STAT_LINE_1(float, "FEST_DF", CStats::DistanceTravelledOnFoot * MILES_IN_METER);
- STAT_LINE_1(float, "FEST_DC", CStats::DistanceTravelledInVehicle * MILES_IN_METER);
- STAT_LINE_1(int, "MMRAIN", CStats::mmRain);
- STAT_LINE_1(float, "MXCARD", CStats::MaximumJumpDistance * FEET_IN_METER);
- STAT_LINE_1(float, "MXCARJ", CStats::MaximumJumpHeight * FEET_IN_METER);
- break;
-#endif
- case LANGUAGE_FRENCH:
- case LANGUAGE_GERMAN:
- case LANGUAGE_ITALIAN:
- case LANGUAGE_SPANISH:
-#ifdef MORE_LANGUAGES
- case LANGUAGE_POLISH:
- case LANGUAGE_RUSSIAN:
- case LANGUAGE_JAPANESE:
-#endif
- STAT_LINE_1(float, "FESTDFM", CStats::DistanceTravelledOnFoot);
- STAT_LINE_1(float, "FESTDCM", CStats::DistanceTravelledInVehicle);
- STAT_LINE_1(int, "MMRAIN", CStats::mmRain);
- STAT_LINE_1(float, "MXCARDM", CStats::MaximumJumpDistance);
- STAT_LINE_1(float, "MXCARJM", CStats::MaximumJumpHeight);
- break;
- default:
- break;
+ if (bTxdMissing)
+ // Not found, fall back to original textures
+ txdSlot = CTxdStore::FindTxdSlot("frontend2");
+ else {
+ // Found, load txd
+ txdSlot = frontend_controller;
+ if (txdSlot == -1)
+ txdSlot = CTxdStore::AddTxdSlot("frontend_controller");
+ CTxdStore::LoadTxd(txdSlot, controllerTypesPaths[type]);
+ CTxdStore::AddRef(txdSlot);
}
- STAT_LINE_1(int, "MXFLIP", CStats::MaximumJumpFlips);
- STAT_LINE_1(int, "MXJUMP", CStats::MaximumJumpSpins);
- TEXT_ON_LEFT_GXT("BSTSTU");
-
- switch (CStats::BestStuntJump) {
- case 1:
- TEXT_ON_RIGHT(TheText.Get("INSTUN"));
- break;
- case 2:
- TEXT_ON_RIGHT(TheText.Get("PRINST"));
- break;
- case 3:
- TEXT_ON_RIGHT(TheText.Get("DBINST"));
- break;
- case 4:
- TEXT_ON_RIGHT(TheText.Get("DBPINS"));
- break;
- case 5:
- TEXT_ON_RIGHT(TheText.Get("TRINST"));
- break;
- case 6:
- TEXT_ON_RIGHT(TheText.Get("PRTRST"));
- break;
- case 7:
- TEXT_ON_RIGHT(TheText.Get("QUINST"));
- break;
- case 8:
- TEXT_ON_RIGHT(TheText.Get("PQUINS"));
- break;
- default:
- TEXT_ON_RIGHT(TheText.Get("NOSTUC"));
- break;
+ assert(txdSlot != -1);
+ // Load new textures
+ CTxdStore::SetCurrentTxd(txdSlot);
+ for (int i = MENUSPRITE_CONTROLLER; i <= MENUSPRITE_ARROWS4; i++) {
+ m_aFrontEndSprites[i].SetTexture(FrontendFilenames[i][0], FrontendFilenames[i][1]);
+ m_aFrontEndSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER);
}
-
- STAT_LINE_1(int, "PASDRO", CStats::PassengersDroppedOffWithTaxi);
- STAT_LINE_1(int, "MONTAX", CStats::MoneyMadeWithTaxi);
- STAT_LINE_1(int, "FEST_LS", CStats::LivesSavedWithAmbulance);
- STAT_LINE_1(int, "FEST_HA", CStats::HighestLevelAmbulanceMission);
- STAT_LINE_1(int, "FEST_CC", CStats::CriminalsCaught);
- STAT_LINE_1(int, "FEST_FE", CStats::FiresExtinguished);
- STAT_LINE_1(int, "DAYPLC", CTimer::GetTimeInMilliseconds() + 100);
- return counter;
-
-#undef STAT_LINE_1
-#undef STAT_LINE_2
-#undef TEXT_ON_LEFT_GXT
-#undef TEXT_ON_RIGHT
-#undef int_STAT_IS_FLOAT
-#undef float_STAT_IS_FLOAT
}
+#endif // GAMEPAD_MENU
#undef GetBackJustUp
#undef GetBackJustDown
-#undef ChangeScreen
-
-#endif
diff --git a/src/core/Frontend.h b/src/core/Frontend.h
index 32e5ef9d..b9be5a82 100644
--- a/src/core/Frontend.h
+++ b/src/core/Frontend.h
@@ -4,44 +4,68 @@
#else
#include "Sprite2d.h"
+#include "Timer.h"
-#ifdef PS2_LIKE_MENU
-#define MENUHEADER_POS_X 50.0f
-#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_HEIGHT 1.6f
-#endif
-#define MENUHEADER_WIDTH 0.84f
+#define MENUHEADER_POS_X 10.0f
+#define MENUHEADER_POS_Y 10.0f
+#define MENUHEADER_HEIGHT 2.0f
+#define MENUHEADER_WIDTH 1.0f
-#define MENU_X_MARGIN 40.0f
-#define MENUACTION_POS_Y 60.0f
-#define MENUACTION_SCALE_MULT 0.9f
+#define MENU_X_MARGIN 10.0f
-#define MENURADIO_ICON_SCALE 60.0f
-
-#define MENUSLIDER_X 256.0f
-#define MENUSLIDER_UNK 256.0f
+#define MENUACTION_SCALE_MULT 0.9f
#define MENUSLIDER_BARS 16
#define MENUSLIDER_LOGICAL_BARS MENUSLIDER_BARS
-#define BIGTEXT_X_SCALE 0.75f // For FONT_HEADING
-#define BIGTEXT_Y_SCALE 0.9f
-#define MEDIUMTEXT_X_SCALE 0.55f // For FONT_HEADING
-#define MEDIUMTEXT_Y_SCALE 0.8f
-#define SMALLTEXT_X_SCALE 0.45f // used for FONT_HEADING and FONT_BANK, but looks off for HEADING
-#define SMALLTEXT_Y_SCALE 0.7f
-#define SMALLESTTEXT_X_SCALE 0.4f // used for both FONT_HEADING and FONT_BANK
-#define SMALLESTTEXT_Y_SCALE 0.6f
+#define MENULABEL_X_MARGIN 80.0f
+#define MENULABEL_POS_X 100.0f
+#define MENULABEL_POS_Y 97.0f
-#define HELPER_TEXT_LEFT_MARGIN 320.0f
-#define HELPER_TEXT_BOTTOM_MARGIN 120.0f
+#define MENU_DEFAULT_CONTENT_X 320
+#define MENU_DEFAULT_CONTENT_Y 100
+#define MENU_DEFAULT_LINE_HEIGHT 29
-#define PLAYERSETUP_LIST_TOP 28.0f
-#define PLAYERSETUP_LIST_BOTTOM 125.0f
+#define RIGHT_ALIGNED_TEXT_RIGHT_MARGIN(xMargin) (xMargin + 30.0f)
+
+#define MENURADIO_ICON_FIRST_X 238.f
+#ifdef EXTERNAL_3D_SOUND
+#define MENURADIO_ICON_Y 288.0f
+#else
+#define MENURADIO_ICON_Y 248.0f
+#endif
+#define MENURADIO_ICON_SIZE 60.0f
+#ifdef EXTERNAL_3D_SOUND
+#define MENURADIO_SELECTOR_START_Y 285.f // other options should leave room on the screen
+#else
+#define MENURADIO_SELECTOR_START_Y 245.0f
+#endif
+#define MENURADIO_SELECTOR_HEIGHT 65.f
+
+#define MENUSLIDER_X 500.0f
+#define MENUSLIDER_UNK 100.0f
+#define MENUSLIDER_SMALLEST_BAR 8.0f
+#define MENUSLIDER_BIGGEST_BAR 25.0f
+
+#define BIGTEXT2_X_SCALE 0.6f // For FONT_STANDARD
+#define BIGTEXT2_Y_SCALE 1.2f
+#define BIGTEXT_X_SCALE 0.6f // For FONT_HEADING
+#define BIGTEXT_Y_SCALE 1.0f
+#define MEDIUMTEXT_X_SCALE 0.48f // For FONT_STANDARD
+#define MEDIUMTEXT_Y_SCALE 1.0f
+#define SMALLTEXT_X_SCALE 0.42f // For FONT_STANDARD
+#define SMALLTEXT_Y_SCALE 0.9f
+#define SMALLESTTEXT_X_SCALE 0.3f // For FONT_STANDARD
+#define SMALLESTTEXT_Y_SCALE 0.7f
+
+#define LISTITEM_X_SCALE 0.4f // Only unproportional and commonly used scale for FONT_STANDARD
+#define LISTITEM_Y_SCALE 0.6f
+
+#define HELPER_TEXT_RIGHT_MARGIN MENU_X_MARGIN
+#define HELPER_TEXT_BOTTOM_MARGIN 18.f
+
+#define PLAYERSETUP_LIST_TOP 58.0f
+#define PLAYERSETUP_LIST_BOTTOM 95.0f
#define PLAYERSETUP_LIST_LEFT 200.0f
#define PLAYERSETUP_LIST_RIGHT 36.0f
#ifdef FIX_BUGS // See the scrollbar button drawing code
@@ -53,96 +77,84 @@
#define PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION 64
#define PLAYERSETUP_SKIN_COLUMN_LEFT 220.0f
#define PLAYERSETUP_DATE_COLUMN_RIGHT 56.0f
-#define PLAYERSETUP_LIST_BODY_TOP 47
+#define PLAYERSETUP_LIST_BODY_TOP 77
#define PLAYERSETUP_ROW_HEIGHT 9
-#define STATS_SLIDE_Y_PER_SECOND 30.0f
-#define STATS_ROW_HEIGHT 20.0f
-#define STATS_ROW_X_MARGIN 50.0f
-#define STATS_BOTTOM_MARGIN 135.0f
-#define STATS_TOP_MARGIN 40.0f
-#define STATS_TOP_DIMMING_AREA_LENGTH (93.0f - STATS_TOP_MARGIN)
-#define STATS_BOTTOM_DIMMING_AREA_LENGTH 55.0f
-#define STATS_PUT_BACK_TO_BOTTOM_Y 50.0f
-#define STATS_RATING_X 24.0f
-#define STATS_RATING_Y 20.0f
-
-#define BRIEFS_TOP_MARGIN 40.0f
-#define BRIEFS_LINE_X 50.0f
-#define BRIEFS_LINE_HEIGHT 60.0f
+#define STATS_ROW_HEIGHT 17.0f
+#define STATS_ROW_LEFT_MARGIN 110.0f
+#define STATS_ROW_RIGHT_MARGIN 113.0f
+#define STATS_TOP_Y 135.0f // Just faded in
+#define STATS_BOTTOM_Y 300.0f // Starts to fade out after that
+#define STATS_FADING_AREA_LENGTH 50.0f
+#define STATS_VISIBLE_START_Y (STATS_TOP_Y - 10.f)
+#define STATS_VISIBLE_END_Y (STATS_BOTTOM_Y + 21.f)
+#define STATS_RATING_X 320.0f
+#define STATS_RATING_Y_1 85.0f
+#define STATS_RATING_Y_2 110.0f
+
+#define BRIEFS_TOP_MARGIN 140.0f
+#define BRIEFS_BOTTOM_MARGIN 280.0f
+#define BRIEFS_LINE_X 100.0f
+#define BRIEFS_LINE_HEIGHT 20.0f
+#define BRIEFS_LINE_SPACING 10.0f
#define CONTSETUP_STANDARD_ROW_HEIGHT 10.7f
#define CONTSETUP_CLASSIC_ROW_HEIGHT 9.0f
#define CONTSETUP_BOUND_HIGHLIGHT_HEIGHT 10
#define CONTSETUP_BOUND_COLUMN_WIDTH 190.0f
-#define CONTSETUP_LIST_HEADER_HEIGHT 20.0f
-#define CONTSETUP_LIST_TOP 28.0f
+#define CONTSETUP_LIST_TOP 58.0f
#define CONTSETUP_LIST_RIGHT 18.0f
-#define CONTSETUP_LIST_BOTTOM 120.0f
-#define CONTSETUP_LIST_LEFT 18.0f
+#define CONTSETUP_LIST_BOTTOM 78.0f
+#define CONTSETUP_LIST_LEFT 30.0f
#define CONTSETUP_COLUMN_1_X 40.0f
#define CONTSETUP_COLUMN_2_X 210.0f
#define CONTSETUP_COLUMN_3_X (CONTSETUP_COLUMN_2_X + CONTSETUP_BOUND_COLUMN_WIDTH + 10.0f)
#define CONTSETUP_BACK_RIGHT 35.0f
-#define CONTSETUP_BACK_BOTTOM 122.0f
+#define CONTSETUP_BACK_BOTTOM 82.0f
#define CONTSETUP_BACK_HEIGHT 25.0f
-enum eFrontendSprites
+enum
{
- 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
+ MENUALIGN_LEFT = 1,
+ MENUALIGN_RIGHT,
+ MENUALIGN_CENTER,
};
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,
+#ifdef GAMEPAD_MENU
+ MENUSPRITE_CONTROLLER,
+ MENUSPRITE_ARROWS1,
+ MENUSPRITE_ARROWS2,
+ MENUSPRITE_ARROWS3,
+ MENUSPRITE_ARROWS4,
+#endif
NUM_MENU_SPRITES
};
@@ -158,102 +170,72 @@ enum eSaveSlot
SAVESLOT_6,
SAVESLOT_7,
SAVESLOT_8,
- SAVESLOT_LABEL = 36,
+ 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,
- MENUPAGE_NONE = 0,
- MENUPAGE_STATS = 1,
- MENUPAGE_NEW_GAME = 2,
- MENUPAGE_BRIEFS = 3,
- MENUPAGE_CONTROLLER_SETTINGS = 4,
- MENUPAGE_SOUND_SETTINGS = 5,
- MENUPAGE_DISPLAY_SETTINGS = 6,
- MENUPAGE_LANGUAGE_SETTINGS = 7,
+ MENUPAGE_STATS = 0,
+ MENUPAGE_NEW_GAME = 1,
+ MENUPAGE_BRIEFS = 2,
+ MENUPAGE_SOUND_SETTINGS = 3,
+ MENUPAGE_DISPLAY_SETTINGS = 4,
+ MENUPAGE_LANGUAGE_SETTINGS = 5,
+ MENUPAGE_MAP = 6,
+ MENUPAGE_NEW_GAME_RELOAD = 7,
MENUPAGE_CHOOSE_LOAD_SLOT = 8,
MENUPAGE_CHOOSE_DELETE_SLOT = 9,
- MENUPAGE_NEW_GAME_RELOAD = 10,
- MENUPAGE_LOAD_SLOT_CONFIRM = 11,
- MENUPAGE_DELETE_SLOT_CONFIRM = 12,
- MENUPAGE_NO_MEMORY_CARD = 13, // hud adjustment page in mobile
- MENUPAGE_LOADING_IN_PROGRESS = 14,
- MENUPAGE_DELETING_IN_PROGRESS = 15,
- MENUPAGE_PS2_LOAD_FAILED = 16,
- MENUPAGE_DELETE_FAILED = 17,
- MENUPAGE_DEBUG_MENU = 18,
- MENUPAGE_MEMORY_CARD_DEBUG = 19,
- MENUPAGE_MEMORY_CARD_TEST = 20,
- MENUPAGE_MULTIPLAYER_MAIN = 21,
- MENUPAGE_PS2_SAVE_FAILED = 22,
- MENUPAGE_PS2_SAVE_FAILED_2 = 23,
- MENUPAGE_SAVE = 24,
- MENUPAGE_NO_MEMORY_CARD_2 = 25,
- MENUPAGE_CHOOSE_SAVE_SLOT = 26,
- MENUPAGE_SAVE_OVERWRITE_CONFIRM = 27,
- MENUPAGE_MULTIPLAYER_MAP = 28,
- MENUPAGE_MULTIPLAYER_CONNECTION = 29,
- MENUPAGE_MULTIPLAYER_FIND_GAME = 30,
- MENUPAGE_MULTIPLAYER_MODE = 31,
- MENUPAGE_MULTIPLAYER_CREATE = 32,
- MENUPAGE_MULTIPLAYER_START = 33,
- MENUPAGE_SKIN_SELECT_OLD = 34,
- MENUPAGE_CONTROLLER_PC = 35,
- MENUPAGE_CONTROLLER_PC_OLD1 = 36,
- MENUPAGE_CONTROLLER_PC_OLD2 = 37,
- MENUPAGE_CONTROLLER_PC_OLD3 = 38,
- MENUPAGE_CONTROLLER_PC_OLD4 = 39,
- MENUPAGE_CONTROLLER_DEBUG = 40,
- MENUPAGE_OPTIONS = 41,
- MENUPAGE_EXIT = 42,
- MENUPAGE_SAVING_IN_PROGRESS = 43,
- MENUPAGE_SAVE_SUCCESSFUL = 44,
- MENUPAGE_DELETING = 45,
- MENUPAGE_DELETE_SUCCESS = 46,
- MENUPAGE_SAVE_FAILED = 47,
- MENUPAGE_LOAD_FAILED = 48,
- MENUPAGE_LOAD_FAILED_2 = 49,
- MENUPAGE_FILTER_GAME = 50,
- MENUPAGE_START_MENU = 51,
- MENUPAGE_PAUSE_MENU = 52,
- MENUPAGE_CHOOSE_MODE = 53,
- MENUPAGE_SKIN_SELECT = 54,
- MENUPAGE_KEYBOARD_CONTROLS = 55,
- MENUPAGE_MOUSE_CONTROLS = 56,
- MENUPAGE_MISSION_RETRY = 57,
+ MENUPAGE_LOAD_SLOT_CONFIRM = 10,
+ MENUPAGE_DELETE_SLOT_CONFIRM = 11,
+ MENUPAGE_LOADING_IN_PROGRESS = 12,
+ MENUPAGE_DELETING_IN_PROGRESS = 13,
+ MENUPAGE_DELETE_SUCCESSFUL = 14,
+ MENUPAGE_CHOOSE_SAVE_SLOT = 15,
+ MENUPAGE_SAVE_OVERWRITE_CONFIRM = 16,
+ MENUPAGE_SAVING_IN_PROGRESS = 17,
+ MENUPAGE_SAVE_SUCCESSFUL = 18,
+ MENUPAGE_SAVE_CUSTOM_WARNING = 19,
+ MENUPAGE_SAVE_CHEAT_WARNING = 20,
+ MENUPAGE_SKIN_SELECT = 21,
+ MENUPAGE_SAVE_UNUSED = 22,
+ MENUPAGE_SAVE_FAILED = 23,
+ MENUPAGE_SAVE_FAILED_2 = 24,
+ MENUPAGE_LOAD_FAILED = 25,
+ MENUPAGE_CONTROLLER_PC = 26,
+ MENUPAGE_OPTIONS = 27,
+ MENUPAGE_EXIT = 28,
+ MENUPAGE_START_MENU = 29,
+ MENUPAGE_KEYBOARD_CONTROLS = 30,
+ MENUPAGE_MOUSE_CONTROLS = 31,
+ MENUPAGE_PAUSE_MENU = 32,
+ MENUPAGE_NONE = 33, // Then chooses main menu or pause menu
+#ifdef GAMEPAD_MENU
+ MENUPAGE_CONTROLLER_SETTINGS,
+#endif
+#ifdef LEGACY_MENU_OPTIONS
+ MENUPAGE_DEBUG_MENU,
+ MENUPAGE_CONTROLLER_PC_OLD1,
+ MENUPAGE_CONTROLLER_PC_OLD2,
+ MENUPAGE_CONTROLLER_PC_OLD3,
+ MENUPAGE_CONTROLLER_PC_OLD4,
+ MENUPAGE_CONTROLLER_DEBUG,
+#endif
#ifdef CUSTOM_FRONTEND_OPTIONS
-#ifdef MENU_MAP
- MENUPAGE_MAP = 58,
-#endif
#ifdef GRAPHICS_MENU_OPTIONS
MENUPAGE_GRAPHICS_SETTINGS,
#endif
#ifdef DETECT_JOYSTICK_MENU
MENUPAGE_DETECT_JOYSTICK,
#endif
-
#endif
- MENUPAGE_UNK, // originally 58. Custom screens are inserted above, because last screen in CMenuScreens should always be empty to make CFO work
- MENUPAGES
+#ifdef MISSION_REPLAY
+ MENUPAGE_MISSION_RETRY,
+#endif
+ MENUPAGE_OUTRO, // Originally 34, but CFO needs last screen to be empty to count number of menu pages
+ MENUPAGES
};
enum eMenuAction
@@ -265,9 +247,10 @@ enum eMenuAction
#endif
MENUACTION_NOTHING,
MENUACTION_LABEL,
+ MENUACTION_YES,
+ MENUACTION_NO,
MENUACTION_CHANGEMENU,
- MENUACTION_CTRLVIBRATION,
- MENUACTION_CTRLCONFIG,
+ MENUACTION_INVERTPADY,
MENUACTION_CTRLDISPLAY,
MENUACTION_FRAMESYNC,
MENUACTION_FRAMELIMIT,
@@ -275,10 +258,8 @@ enum eMenuAction
MENUACTION_SUBTITLES,
MENUACTION_WIDESCREEN,
MENUACTION_BRIGHTNESS,
- MENUACTION_DRAWDIST,
MENUACTION_MUSICVOLUME,
MENUACTION_SFXVOLUME,
- MENUACTION_UNK15,
MENUACTION_RADIO,
MENUACTION_LANG_ENG,
MENUACTION_LANG_FRE,
@@ -287,74 +268,24 @@ enum eMenuAction
MENUACTION_LANG_SPA,
MENUACTION_POPULATESLOTS_CHANGEMENU,
MENUACTION_CHECKSAVE,
- MENUACTION_UNK24,
MENUACTION_NEWGAME,
+ MENUACTION_RESUME_FROM_SAVEZONE,
MENUACTION_RELOADIDE,
- MENUACTION_RELOADIPL,
MENUACTION_SETDBGFLAG,
+ MENUACTION_LOADRADIO,
+ MENUACTION_SAVEGAME,
MENUACTION_SWITCHBIGWHITEDEBUGLIGHT,
- MENUACTION_PEDROADGROUPS,
- MENUACTION_CARROADGROUPS,
MENUACTION_COLLISIONPOLYS,
- MENUACTION_REGMEMCARD1,
- MENUACTION_TESTFORMATMEMCARD1,
- MENUACTION_TESTUNFORMATMEMCARD1,
- MENUACTION_CREATEROOTDIR,
- MENUACTION_CREATELOADICONS,
- MENUACTION_FILLWITHGUFF,
- MENUACTION_SAVEONLYTHEGAME,
- MENUACTION_SAVEGAME,
- MENUACTION_SAVEGAMEUNDERGTA,
- MENUACTION_CREATECOPYPROTECTED,
- MENUACTION_TESTSAVE,
- MENUACTION_TESTLOAD,
- MENUACTION_TESTDELETE,
- MENUACTION_PARSEHEAP,
- MENUACTION_SHOWCULL,
- MENUACTION_MEMCARDSAVECONFIRM,
- MENUACTION_RESUME_FROM_SAVEZONE,
- MENUACTION_UNK50,
- MENUACTION_DEBUGSTREAM,
- MENUACTION_MPMAP_LIBERTY,
- MENUACTION_MPMAP_REDLIGHT,
- MENUACTION_MPMAP_CHINATOWN,
- MENUACTION_MPMAP_TOWER,
- MENUACTION_MPMAP_SEWER,
- MENUACTION_MPMAP_INDUSTPARK,
- MENUACTION_MPMAP_DOCKS,
- MENUACTION_MPMAP_STAUNTON,
- MENUACTION_MPMAP_DEATHMATCH1,
- MENUACTION_MPMAP_DEATHMATCH2,
- MENUACTION_MPMAP_TEAMDEATH1,
- MENUACTION_MPMAP_TEAMDEATH2,
- MENUACTION_MPMAP_STASH,
- MENUACTION_MPMAP_CAPTURE,
- MENUACTION_MPMAP_RATRACE,
- MENUACTION_MPMAP_DOMINATION,
- MENUACTION_STARTMP,
- MENUACTION_UNK69,
- MENUACTION_UNK70,
- MENUACTION_FINDMP,
+ MENUACTION_LEGENDS,
+ MENUACTION_RADARMODE,
+ MENUACTION_HUD,
+ MENUACTION_GOBACK,
MENUACTION_KEYBOARDCTRLS,
- MENUACTION_UNK73,
- MENUACTION_INITMP,
- MENUACTION_MP_PLAYERCOLOR,
- MENUACTION_MP_PLAYERNAME,
- MENUACTION_MP_GAMENAME,
MENUACTION_GETKEY,
MENUACTION_SHOWHEADBOB,
- MENUACTION_UNK80,
+ MENUACTION_UNK38, // MENUACTION_PARSEHEAP? MENUACTION_DEBUGSTREAM? MENUACTION_MEMCARDSAVECONFIRM?
MENUACTION_INVVERT,
MENUACTION_CANCELGAME,
- MENUACTION_MP_PLAYERNUMBER,
- MENUACTION_MOUSESENS,
- MENUACTION_CHECKMPGAMES,
- MENUACTION_CHECKMPPING,
- MENUACTION_MP_SERVER,
- MENUACTION_MP_MAP,
- MENUACTION_MP_GAMETYPE,
- MENUACTION_MP_LAN,
- MENUACTION_MP_INTERNET,
MENUACTION_RESUME,
MENUACTION_DONTCANCEL,
MENUACTION_SCREENRES,
@@ -364,24 +295,18 @@ enum eMenuAction
MENUACTION_RESTOREDEF,
MENUACTION_CTRLMETHOD,
MENUACTION_DYNAMICACOUSTIC,
- MENUACTION_LOADRADIO,
MENUACTION_MOUSESTEER,
- MENUACTION_UNK103,
- MENUACTION_UNK104,
- MENUACTION_UNK105,
- MENUACTION_UNK106,
- MENUACTION_UNK107,
- MENUACTION_UNK108,
- MENUACTION_UNK109,
- MENUACTION_UNK110,
- MENUACTION_UNK111,
- MENUACTION_UNK112,
+ MENUACTION_DRAWDIST,
+ MENUACTION_MOUSESENS,
+ MENUACTION_MP3VOLUMEBOOST,
+#ifdef GAMEPAD_MENU
+ MENUACTION_CTRLVIBRATION,
+ MENUACTION_CTRLCONFIG,
+#endif
+#ifdef MISSION_REPLAY
MENUACTION_REJECT_RETRY,
- MENUACTION_UNK114,
-//#ifdef ANISOTROPIC_FILTERING
-// MENUACTION_MIPMAPS,
-// MENUACTION_TEXTURE_FILTERING,
-//#endif
+ MENUACTION_UNK114
+#endif
};
enum eCheckHover
@@ -408,16 +333,8 @@ enum eCheckHover
HOVEROPTION_LIST, // also layer in controller setup and skin menu
HOVEROPTION_SKIN,
HOVEROPTION_USESKIN, // also layer in controller setup and skin menu
- HOVEROPTION_RADIO_0,
- HOVEROPTION_RADIO_1,
- HOVEROPTION_RADIO_2,
- HOVEROPTION_RADIO_3,
- HOVEROPTION_RADIO_4,
- HOVEROPTION_RADIO_5,
- HOVEROPTION_RADIO_6,
- HOVEROPTION_RADIO_7,
- HOVEROPTION_RADIO_8,
- HOVEROPTION_RADIO_9,
+ HOVEROPTION_NEXT_RADIO,
+ HOVEROPTION_PREV_RADIO,
HOVEROPTION_INCREASE_BRIGHTNESS,
HOVEROPTION_DECREASE_BRIGHTNESS,
HOVEROPTION_INCREASE_DRAWDIST,
@@ -428,6 +345,8 @@ enum eCheckHover
HOVEROPTION_DECREASE_SFXVOLUME,
HOVEROPTION_INCREASE_MOUSESENS,
HOVEROPTION_DECREASE_MOUSESENS,
+ HOVEROPTION_INCREASE_MP3BOOST,
+ HOVEROPTION_DECREASE_MP3BOOST,
#ifdef CUSTOM_FRONTEND_OPTIONS
HOVEROPTION_INCREASE_CFO_SLIDER,
HOVEROPTION_DECREASE_CFO_SLIDER,
@@ -437,7 +356,11 @@ enum eCheckHover
enum
{
+#if defined LEGACY_MENU_OPTIONS || defined CUSTOM_FRONTEND_OPTIONS
NUM_MENUROWS = 18,
+#else
+ NUM_MENUROWS = 12,
+#endif
};
enum eControlMethod
@@ -450,7 +373,7 @@ enum eControlMethod
enum ControllerSetupColumn
{
CONTSETUP_PED_COLUMN = 0,
- CONTSETUP_VEHICLE_COLUMN = 14,
+ CONTSETUP_VEHICLE_COLUMN = 16,
};
struct tSkinInfo
@@ -472,9 +395,8 @@ struct BottomBarOption
struct CMenuScreen
{
char m_ScreenName[8];
- int32 unk; // 2 on MENUPAGE_MULTIPLAYER_START, 1 on everywhere else, 0 on unused.
- int32 m_PreviousPage[2]; // eMenuScreen
- int32 m_ParentEntry[2]; // row
+ int32 m_PreviousPage; // eMenuScreen
+ int32 m_ParentEntry; // row
struct CMenuEntry
{
@@ -482,21 +404,21 @@ struct CMenuScreen
char m_EntryName[8];
int32 m_SaveSlot; // eSaveSlot
int32 m_TargetMenu; // eMenuScreen
+ uint16 m_X;
+ uint16 m_Y;
+ uint8 m_Align;
} m_aEntries[NUM_MENUROWS];
};
extern CMenuScreen aScreens[MENUPAGES];
#else
#include "frontendoption.h"
struct CCustomScreenLayout {
- eMenuSprites sprite;
- int columnWidth;
- int headerHeight;
- int lineHeight;
- int8 font;
- int8 alignment;
+ int startX; // not used at all if first entry has X and Y values
+ int startY; // not used at all if first entry has X and Y values
+ int lineHeight; // used to determine next entry's Y coordinate, if it has 0-0 as coordinates
bool showLeftRightHelper;
- float fontScaleX;
- float fontScaleY;
+ bool noInvasiveBorders; // not needed on pages already handled by game
+ int xMargin; // useful for two part texts - 0/empty = MENU_X_MARGIN
};
struct CCFO
@@ -568,7 +490,7 @@ struct CCFODynamic : CCFO
struct CMenuScreenCustom
{
char m_ScreenName[8];
- int32 m_PreviousPage[2]; // eMenuScreen
+ int32 m_PreviousPage; // eMenuScreen
CCustomScreenLayout *layout;
ReturnPrevPageFunc returnPrevPageFunc;
@@ -586,74 +508,203 @@ struct CMenuScreenCustom
int32 m_SaveSlot; // eSaveSlot
int32 m_TargetMenu; // eMenuScreen
};
+ uint16 m_X;
+ uint16 m_Y;
+ uint8 m_Align;
} m_aEntries[NUM_MENUROWS];
};
extern CMenuScreenCustom aScreens[MENUPAGES];
#endif
+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;
+ bool m_DisplayControllerOnFoot;
+ 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;
+ 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;
+ int8 m_PrefsSfxVolume;
+ int8 m_PrefsMusicVolume;
+ int8 m_PrefsRadioStation;
+ uint8 m_PrefsStereoMono; // unused except restore settings
+ 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;
+ int8 m_PrefsMP3BoostVolume;
+ int8 m_ControlMethod;
+ int32 m_nPrefsVideoMode;
+ int32 m_nDisplayVideoMode;
int32 m_nMouseTempPosX;
int32 m_nMouseTempPosY;
- bool m_bShowMouse;
- tSkinInfo m_pSkinListHead;
- tSkinInfo *m_pSelectedSkin;
- int32 m_nFirstVisibleRowOnList;
- float m_nScrollbarTopMargin;
- int32 m_nTotalListRow;
- int32 m_nSkinsTotal;
- char _unk0[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_bGameNotLoaded;
+ int8 m_lastWorking3DAudioProvider;
+ bool m_bFrontEnd_ReloadObrTxtGxt;
+ int32 *pEditString;
+ uint8 field_74[4];
+ int32 *pControlEdit;
+ bool m_OnlySaveMenu;
+ int32 m_firstStartCounter;
+ CSprite2d m_aFrontEndSprites[NUM_MENU_SPRITES];
bool m_bSpritesLoaded;
- CSprite2d m_aFrontEndSprites[NUM_FE_SPRITES];
- CSprite2d m_aMenuSprites[NUM_MENU_SPRITES];
- int32 field_518;
+ int32 m_LeftMostRadioX;
+ int32 m_ScrollRadioBy;
+ int32 m_nCurrScreen;
+ int32 m_nPrevScreen;
+ int32 m_nCurrSaveSlot;
+ uint32 m_LastScreenSwitch;
int32 m_nMenuFadeAlpha;
+ int32 m_nOptionHighlightTransitionBlend;
+ 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;
- int32 m_CurrCntrlAction;
- char _unk1[4];
- int32 m_nSelectedContSetupColumn;
- bool m_bKeyIsOK;
- bool field_535;
- int8 m_nCurrExLayer;
- int32 m_nHelperTextAlpha;
+ uint8 field_129;
+ uint8 field_12A;
+ uint8 field_12B;
+ int32 m_nMousePosX;
+ int32 m_nMousePosY;
int32 m_nMouseOldPosX;
int32 m_nMouseOldPosY;
int32 m_nHoverOption;
- int32 m_nCurrScreen;
- int32 m_nCurrOption;
+ bool m_bShowMouse;
int32 m_nOptionMouseHovering;
- int32 m_nPrevScreen;
- uint32 field_558;
- int32 m_nCurrSaveSlot;
- int32 m_nScreenChangeDelayTimer;
+ 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;
+ uint8 field_67C[4];
+ int32 m_nSelectedListRow;
+ bool m_bSkinsEnumerated;
#ifdef IMPROVED_VIDEOMODE
int32 m_nPrefsWidth;
@@ -664,10 +715,27 @@ public:
int32 m_nSelectedScreenMode;
#endif
#ifdef MULTISAMPLING
- static int8 m_nPrefsMSAALevel;
- static int8 m_nDisplayMSAALevel;
+ int8 m_nPrefsMSAALevel;
+ int8 m_nDisplayMSAALevel;
#endif
+#ifdef MISSION_REPLAY
+ bool m_bAttemptingMissionRetry;
+#endif
+
+#ifdef GAMEPAD_MENU
+ enum
+ {
+ CONTROLLER_DUALSHOCK2 = 0,
+ CONTROLLER_DUALSHOCK3,
+ CONTROLLER_DUALSHOCK4,
+ CONTROLLER_XBOX360,
+ CONTROLLER_XBOXONE,
+ CONTROLLER_NINTENDO_SWITCH,
+ };
+
+ int8 m_PrefsControllerType;
+#endif
enum LANGUAGE
{
LANGUAGE_AMERICAN,
@@ -681,42 +749,8 @@ public:
LANGUAGE_JAPANESE,
#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;
-
#ifdef CUTSCENE_BORDERS_SWITCH
static bool m_PrefsCutsceneBorders;
#endif
@@ -726,14 +760,8 @@ public:
static bool m_PrefsDisableTutorials;
#endif // !MASTER
-#ifdef MENU_MAP
- static bool bMenuMapActive;
- static float fMapSize;
- static float fMapCenterY;
- static float fMapCenterX;
- static CSprite2d m_aMapSprites[NUM_MAP_SPRITES];
- void PrintMap();
-#endif
+ CMenuManager(void);
+ ~CMenuManager(void) { UnloadTextures(); }
#ifdef NO_ISLAND_LOADING
enum
@@ -743,94 +771,99 @@ public:
ISLAND_LOADING_HIGH
};
- static int8 m_PrefsIslandLoading;
+ int8 m_PrefsIslandLoading;
- #define ISLAND_LOADING_IS(p) if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_##p)
- #define ISLAND_LOADING_ISNT(p) if (CMenuManager::m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_##p)
+ #define ISLAND_LOADING_IS(p) if (FrontEndMenuManager.m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_##p)
+ #define ISLAND_LOADING_ISNT(p) if (FrontEndMenuManager.m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_##p)
#else
#define ISLAND_LOADING_IS(p)
#define ISLAND_LOADING_ISNT(p)
#endif
-#ifdef GAMEPAD_MENU
- enum
- {
- CONTROLLER_DUALSHOCK2 = 0,
- CONTROLLER_DUALSHOCK3,
- CONTROLLER_DUALSHOCK4,
- CONTROLLER_XBOX360,
- CONTROLLER_XBOXONE,
- };
-
- static int8 m_PrefsControllerType;
+#ifdef XBOX_MESSAGE_SCREEN
+ static uint32 m_nDialogHideTimer;
+ static uint32 m_nDialogHideTimerPauseMode;
+ static bool m_bDialogOpen;
+ static wchar *m_pDialogText;
+ static bool m_bSaveWasSuccessful;
+
+ static void SetDialogText(const char*);
+ static bool DialogTextCmp(const char*);
+ static void ToggleDialog(bool);
+ static void SetDialogTimer(uint32);
+ void ProcessDialogTimer(void);
+ void DrawOverlays(void);
+ void CloseDialog(void);
#endif
-public:
- static void BuildStatLine(Const char *text, void *stat, bool itsFloat, void *stat2);
+ void Initialise();
+ void PrintMap();
+ void SetFrontEndRenderStates();
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 DisplayHelperText(char*);
+ int DisplaySlider(float, float, float, float, float, float, float);
void DoSettingsBeforeStartingAGame();
- void Draw();
+ void DrawStandardMenus(bool);
void DrawControllerBound(int32, int32, int32, int8);
void DrawControllerScreenExtraText(int, int, int);
void DrawControllerSetupScreen();
+ void DrawQuitGameScreen();
void DrawFrontEnd();
- void DrawFrontEndNormal();
-#ifdef PS2_SAVE_DIALOG
- void DrawFrontEndSaveZone();
-#endif
- void DrawPlayerSetupScreen();
+ void DrawBackground(bool transitionCall);
+ void DrawPlayerSetupScreen(bool);
int FadeIn(int alpha);
- void FilterOutColorMarkersFromString(wchar*, CRGBA &);
int GetStartOptionsCntrlConfigScreens();
- static void InitialiseChangedLanguageSettings();
+ void InitialiseChangedLanguageSettings();
void LoadAllTextures();
void LoadSettings();
- void MessageScreen(const char *);
- void PickNewPlayerColour();
+ void MessageScreen(const char *str, bool);
+ void SmallMessageScreen(const char *str);
void PrintBriefs();
static void PrintErrorMessage();
void PrintStats();
void Process();
- void ProcessButtonPresses();
+ void ProcessList(bool &optionSelected, bool &goBack);
+ void UserInput();
+ void ProcessUserInput(uint8, uint8, uint8, uint8, int8);
+ void ChangeRadioStation(int8);
+ 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);
+ void AdditionalOptionInput(bool &goBack);
+ void ExportStats(void);
+ void PrintRadioSelector(void);
- // Those are either inlined in game, not in function yet, or I can't believe that they're not inlined.
- // Names were made up by me.
- void ThingsToDoBeforeGoingBack();
+ // New (not in function or inlined in the game)
+ void ThingsToDoBeforeLeavingPage();
void ScrollUpListByOne();
void ScrollDownListByOne();
void PageUpList(bool);
void PageDownList(bool);
int8 GetPreviousPageOption();
- void ProcessList(bool &goBack, bool &optionSelected);
+
+ // uint8 GetNumberOfMenuOptions();
#ifdef GAMEPAD_MENU
void LoadController(int8 type);
+ void PrintController(void);
#endif
};
#ifndef IMPROVED_VIDEOMODE
-VALIDATE_SIZE(CMenuManager, 0x564);
+VALIDATE_SIZE(CMenuManager, 0x688);
#endif
extern CMenuManager FrontEndMenuManager;
diff --git a/src/core/Frontend_PS2.cpp b/src/core/Frontend_PS2.cpp
index 1da15fbb..fa238031 100644
--- a/src/core/Frontend_PS2.cpp
+++ b/src/core/Frontend_PS2.cpp
@@ -203,6 +203,10 @@ static const char* FrontendFilenames[][2] =
{"fe_radio9", "" },
};
+#ifdef CUTSCENE_BORDERS_SWITCH
+bool CMenuManager::m_PrefsCutsceneBorders = true;
+#endif
+
int32 CMenuManager::m_PrefsSfxVolume = 102;
int32 CMenuManager::m_PrefsMusicVolume = 102;
int32 CMenuManager::m_PrefsBrightness = 256;
@@ -1178,30 +1182,9 @@ CMenuManager::InitialiseMenuContents(void)
STAT_LINE("KGS_EXP", &CStats::KgsOfExplosivesUsed, 0, nil);
- nTemp = (CStats::InstantHitsFiredByPlayer == 0 ? 0 : CStats::InstantHitsHitByPlayer * 100.0f / CStats::InstantHitsFiredByPlayer);
- STAT_LINE("ACCURA", &nTemp, 0, nil);
-
- if (CStats::ElBurroTime > 0)
- STAT_LINE("ELBURRO", &CStats::ElBurroTime, 0, nil);
-
- if (CStats::Record4x4One > 0)
- STAT_LINE("FEST_R1", &CStats::Record4x4One, 0, nil);
-
- if (CStats::Record4x4Two > 0)
- STAT_LINE("FEST_R2", &CStats::Record4x4Two, 0, nil);
-
- if (CStats::Record4x4Three > 0)
- STAT_LINE("FEST_R3", &CStats::Record4x4Three, 0, nil);
-
- if (CStats::Record4x4Mayhem > 0)
- STAT_LINE("FEST_RM", &CStats::Record4x4Mayhem, 0, nil);
-
if (CStats::LongestFlightInDodo > 0)
STAT_LINE("FEST_LF", &CStats::LongestFlightInDodo, 0, nil);
- if (CStats::TimeTakenDefuseMission > 0)
- STAT_LINE("FEST_BD", &CStats::TimeTakenDefuseMission, 0, nil);
-
STAT_LINE("CAR_CRU", &CStats::CarsCrushed, 0, nil);
if (CStats::HighestScores[0] > 0)
@@ -1230,7 +1213,11 @@ CMenuManager::InitialiseMenuContents(void)
STAT_LINE("FEST_H4", &CStats::HighestScores[4], 0, nil);
STAT_LINE("FESTDFM", &CStats::DistanceTravelledOnFoot, 0, nil);
- STAT_LINE("FESTDCM", &CStats::DistanceTravelledInVehicle, 0, nil);
+ STAT_LINE("FESTDCM", &CStats::DistanceTravelledByCar, 0, nil);
+ STAT_LINE("DISTBIM", &CStats::DistanceTravelledByBike, 0, nil);
+ STAT_LINE("DISTBOM", &CStats::DistanceTravelledByBoat, 0, nil);
+ STAT_LINE("DISTGOM", &CStats::DistanceTravelledByGolfCart, 0, nil);
+ STAT_LINE("DISTHEM", &CStats::DistanceTravelledByHelicoptor, 0, nil);
STAT_LINE("MMRAIN", &CStats::mmRain, 0, nil);
nTemp = (int32)CStats::MaximumJumpDistance;
STAT_LINE("MXCARDM", &nTemp, 0, nil);
diff --git a/src/core/Frontend_PS2.h b/src/core/Frontend_PS2.h
index 4bab7df9..6311d821 100644
--- a/src/core/Frontend_PS2.h
+++ b/src/core/Frontend_PS2.h
@@ -161,8 +161,10 @@ public:
static CONTRCONFIG m_PrefsControllerConfig;
static bool m_PrefsUseVibration;
-#define ISLAND_LOADING_IS(p)
-#define ISLAND_LOADING_ISNT(p)
+#ifdef CUTSCENE_BORDERS_SWITCH
+ static bool m_PrefsCutsceneBorders;
+#endif
+
#ifdef GTA_PC
bool m_bQuitGameNoCD;
diff --git a/src/core/Game.cpp b/src/core/Game.cpp
index b3dd1eda..77c8965f 100644
--- a/src/core/Game.cpp
+++ b/src/core/Game.cpp
@@ -41,6 +41,7 @@
#include "MBlur.h"
#include "Messages.h"
#include "MemoryCard.h"
+#include "MemoryHeap.h"
#include "Pad.h"
#include "Particle.h"
#include "ParticleObject.h"
@@ -62,6 +63,7 @@
#include "Script.h"
#include "Shadows.h"
#include "Skidmarks.h"
+#include "SetPieces.h"
#include "SpecialFX.h"
#include "Stats.h"
#include "Streaming.h"
@@ -81,17 +83,21 @@
#include "World.h"
#include "ZoneCull.h"
#include "Zones.h"
+#include "Occlusion.h"
#include "debugmenu.h"
+#include "Ropes.h"
+#include "WindModifiers.h"
+#include "WaterCreatures.h"
#include "postfx.h"
#include "custompipes.h"
#include "screendroplets.h"
-#include "crossplatform.h"
-#include "MemoryHeap.h"
+#include "VarConsole.h"
#ifdef USE_TEXTURE_POOL
#include "TexturePools.h"
#endif
eLevelName CGame::currLevel;
+int32 CGame::currArea;
bool CGame::bDemoMode = true;
bool CGame::nastyGame = true;
bool CGame::frenchGame;
@@ -103,15 +109,24 @@ char CGame::aDatFile[32];
bool CGame::russianGame = false;
bool CGame::japaneseGame = false;
#endif
+#ifndef MASTER
+CVector CGame::PlayerCoords;
+bool8 CGame::VarUpdatePlayerCoords;
+#endif
int gameTxdSlot;
+#ifdef SECUROM
+uint8 gameProcessPirateCheck = 0;
+#endif
bool DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha);
void DoRWStuffEndOfFrame(void);
#ifdef PS2_MENU
void MessageScreen(char *msg)
{
+ //TODO: stretch_screen
+
CRect rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
CRGBA color(255, 255, 255, 255);
@@ -123,32 +138,20 @@ void MessageScreen(char *msg)
CSprite2d *splash = LoadSplash(NULL);
splash->Draw(rect, color, color, color, color);
-#ifdef FIX_BUGS
- splash->DrawRect(CRect(SCREEN_SCALE_X(20.0f), SCREEN_SCALE_Y(110.0f), SCREEN_WIDTH-SCREEN_SCALE_X(20.0f), SCREEN_SCALE_Y(300.0f)), CRGBA(50, 50, 50, 192));
-#else
- splash->DrawRect(CRect(20.0f, 110.0f, SCREEN_WIDTH-20.0f, 300.0f), CRGBA(50, 50, 50, 192));
-#endif
+ splash->DrawRect(CRect(SCREEN_SCALE_X(20.0f), SCREEN_SCALE_Y(110.0f), SCREEN_SCALE_X(620.0f), SCREEN_SCALE_Y(300.0f)), CRGBA(50, 50, 50, 192));
+
CFont::SetFontStyle(FONT_BANK);
CFont::SetBackgroundOff();
- CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(190));
-#ifdef FIX_BUGS
+ CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(190.0f)); // 450.0f
CFont::SetScale(SCREEN_SCALE_X(1.0f), SCREEN_SCALE_Y(1.0f));
-#else
- CFont::SetScale(1.0f, 1.0f);
-#endif
CFont::SetCentreOn();
- CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH - 190)); // 450.0f
+ CFont::SetCentreSize(SCREEN_SCALE_X(450.0f));
CFont::SetJustifyOff();
CFont::SetColor(CRGBA(255, 255, 255, 255));
CFont::SetDropColor(CRGBA(32, 32, 32, 255));
CFont::SetDropShadowPosition(3);
- CFont::SetBackGroundOnlyTextOff();
CFont::SetPropOn();
-#ifdef FIX_BUGS
- CFont::PrintString(SCREEN_WIDTH/2, SCREEN_SCALE_Y(130.0f), TheText.Get(msg));
-#else
- CFont::PrintString(SCREEN_WIDTH/2, 130.0f, TheText.Get(msg));
-#endif
+ CFont::PrintString(SCREEN_SCALE_X(320.0f), SCREEN_SCALE_Y(130.0f), TheText.Get(msg));
CFont::DrawFonts();
DoRWStuffEndOfFrame();
@@ -160,7 +163,11 @@ CGame::InitialiseOnceBeforeRW(void)
{
CFileMgr::Initialise();
CdStreamInit(MAX_CDCHANNELS);
- ValidateVersion();
+ debug("size of matrix %d\n", sizeof(CMatrix));
+ debug("size of placeable %d\n", sizeof(CPlaceable));
+ debug("size of entity %d\n", sizeof(CEntity));
+ debug("size of building %d\n", sizeof(CBuilding));
+ debug("size of dummy %d\n", sizeof(CDummy));
#ifdef EXTENDED_COLOURFILTER
CPostFX::InitOnce();
#endif
@@ -184,16 +191,13 @@ void ReplaceAtomicPipeCallback();
bool
CGame::InitialiseRenderWare(void)
{
+ ValidateVersion();
#ifdef USE_TEXTURE_POOL
_TexturePoolsInitialise();
#endif
-#if GTA_VERSION > GTA3_PS2_160
- CTxdStore::Initialise(); // in GameInit on ps2
- CVisibilityPlugins::Initialise(); // in plugin attach on ps2
-#endif
-
- //InitialiseScene(Scene); // PS2 only, only clears Scene.camera
+ CTxdStore::Initialise();
+ CVisibilityPlugins::Initialise();
#ifdef GTA_PS2
RpSkySelectTrueTSClipper(TRUE);
@@ -213,7 +217,7 @@ CGame::InitialiseRenderWare(void)
return (false);
}
- RwCameraSetFarClipPlane(Scene.camera, 2000.0f); // 250.0f on PS2 but who cares
+ RwCameraSetFarClipPlane(Scene.camera, 2000.0f);
RwCameraSetNearClipPlane(Scene.camera, 0.9f);
CameraSize(Scene.camera, nil, DEFAULT_VIEWWINDOW, DEFAULT_ASPECT_RATIO);
@@ -237,11 +241,7 @@ CGame::InitialiseRenderWare(void)
RpWorldAddCamera(Scene.world, Scene.camera);
LightsCreate(Scene.world);
-#if GTA_VERSION > GTA3_PS2_160
- CreateDebugFont(); // in GameInit on PS2
-#else
- RwImageSetPath("textures");
-#endif
+ CreateDebugFont();
#ifdef LIBRW
#ifdef PS2_MATFX
@@ -253,7 +253,7 @@ CGame::InitialiseRenderWare(void)
rw::MatFX::envMapUseMatColor = false;
rw::MatFX::envMapFlipU = false;
#endif
- rw::RGBA envcol = { 128, 128, 128, 255 };
+ rw::RGBA envcol = { 64, 64, 64, 255 };
rw::MatFX::envMapColor = envcol;
#else
#ifdef PS2_MATFX
@@ -264,17 +264,12 @@ CGame::InitialiseRenderWare(void)
#endif // PS2_ALPHA_TEST
#endif // LIBRW
-
-#if GTA_VERSION > GTA3_PS2_160
- // in GameInit on PS2
PUSH_MEMID(MEMID_TEXTURES);
CFont::Initialise();
CHud::Initialise();
- POP_MEMID();
- // TODO: define
CPlayerSkin::Initialise();
-#endif
-
+ POP_MEMID();
+
#ifdef EXTENDED_PIPELINES
CustomPipes::CustomPipeInit(); // need Scene.world for this
#endif
@@ -285,7 +280,6 @@ CGame::InitialiseRenderWare(void)
return (true);
}
-// missing altogether on PS2
void CGame::ShutdownRenderWare(void)
{
#ifdef SCREEN_DROPLETS
@@ -295,7 +289,6 @@ void CGame::ShutdownRenderWare(void)
CustomPipes::CustomPipeShutdown();
#endif
- CMBlur::MotionBlurClose();
DestroySplashScreen();
CHud::Shutdown();
CFont::Shutdown();
@@ -303,7 +296,6 @@ void CGame::ShutdownRenderWare(void)
for ( int32 i = 0; i < NUMPLAYERS; i++ )
CWorld::Players[i].DeletePlayerSkin();
- // TODO: define
CPlayerSkin::Shutdown();
DestroyDebugFont();
@@ -326,64 +318,43 @@ void CGame::ShutdownRenderWare(void)
#endif
}
-// missing altogether on PS2
bool CGame::InitialiseOnceAfterRW(void)
{
-#if GTA_VERSION > GTA3_PS2_160
TheText.Load();
- DMAudio.Initialise(); // before TheGame() on PS2
CTimer::Initialise();
CTempColModels::Initialise();
mod_HandlingManager.Initialise();
CSurfaceTable::Initialise("DATA\\SURFACE.DAT");
CPedStats::Initialise();
CTimeCycle::Initialise();
+#ifdef GTA_PS2
+ LoadingScreen("Loading the Game", "Initialising audio", GetRandomSplashScreen());
+#endif
+ DMAudio.Initialise();
#ifndef GTA_PS2
+#ifdef EXTERNAL_3D_SOUND
if ( DMAudio.GetNum3DProvidersAvailable() == 0 )
- FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = -1;
-
- if ( FrontEndMenuManager.m_nPrefsAudio3DProviderIndex == -99 || FrontEndMenuManager.m_nPrefsAudio3DProviderIndex == -2 ) {
- CMenuManager::m_PrefsSpeakers = 0;
- int32 i;
- for (i = 0; i < DMAudio.GetNum3DProvidersAvailable(); i++) {
- wchar buff[64];
-
-#ifdef AUDIO_OAL
- extern int defaultProvider;
- if (defaultProvider >= 0 && defaultProvider < DMAudio.GetNum3DProvidersAvailable())
- break;
-#endif
- char *name = DMAudio.Get3DProviderName(i);
- AsciiToUnicode(name, buff);
- char *providername = UnicodeToAscii(buff);
- strupr(providername);
-#if defined(AUDIO_MSS)
- if (strcmp(providername, "MILES FAST 2D POSITIONAL AUDIO") == 0)
- break;
-#elif defined(AUDIO_OAL)
- if (strcmp(providername, "OPENAL SOFT") == 0)
- break;
-#endif
- }
+ FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = NO_AUDIO_PROVIDER;
- FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = i;
+ if ( FrontEndMenuManager.m_nPrefsAudio3DProviderIndex == AUDIO_PROVIDER_NOT_DETERMINED || FrontEndMenuManager.m_nPrefsAudio3DProviderIndex == -2 )
+ {
+ FrontEndMenuManager.m_PrefsSpeakers = 0;
+ FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = DMAudio.AutoDetect3DProviders();
}
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);
+#endif
+ DMAudio.SetDynamicAcousticModelingStatus(FrontEndMenuManager.m_PrefsDMA);
+ DMAudio.SetMusicMasterVolume(FrontEndMenuManager.m_PrefsMusicVolume);
+ DMAudio.SetEffectsMasterVolume(FrontEndMenuManager.m_PrefsSfxVolume);
DMAudio.SetEffectsFadeVol(127);
DMAudio.SetMusicFadeVol(127);
#endif
- CWorld::Players[0].SetPlayerSkin(CMenuManager::m_PrefsSkinFile);
-#endif
return true;
}
-// missing altogether on PS2
void
CGame::FinalShutdown(void)
{
@@ -392,31 +363,29 @@ CGame::FinalShutdown(void)
CdStreamShutdown();
}
-#if GTA_VERSION <= GTA3_PS2_160
-bool CGame::Initialise(void)
-#else
bool CGame::Initialise(const char* datFile)
-#endif
{
+ ResetLoadingScreenBar();
+ strcpy(aDatFile, datFile);
+
#ifdef GTA_PS2
// TODO: upload VU0 collision code here
#endif
-#if GTA_VERSION > GTA3_PS2_160
- ResetLoadingScreenBar();
- strcpy(aDatFile, datFile);
- CPools::Initialise(); // done in CWorld on PS2
-#endif
+ CPools::Initialise();
#ifndef GTA_PS2
#ifdef PED_CAR_DENSITY_SLIDERS
- // Load density values from gta3.ini only if our re3.ini have them 1.f
- if (CIniFile::PedNumberMultiplier == 1.f && CIniFile::CarNumberMultiplier == 1.f)
+ // Load density values from gta3.ini only if our reVC.ini have them 0.6f
+ if (CIniFile::PedNumberMultiplier == 0.6f && CIniFile::CarNumberMultiplier == 0.6f)
#endif
CIniFile::LoadIniFile();
#endif
-
- currLevel = LEVEL_INDUSTRIAL;
+#ifdef USE_TEXTURE_POOL
+ _TexturePoolsUnknown(false);
+#endif
+ currLevel = LEVEL_BEACH;
+ currArea = AREA_MAIN_MAP;
PUSH_MEMID(MEMID_TEXTURES);
LoadingScreen("Loading the Game", "Loading generic textures", GetRandomSplashScreen());
@@ -448,18 +417,16 @@ bool CGame::Initialise(const char* datFile)
CDebug::DebugInitTextBuffer();
ThePaths.Init();
ThePaths.AllocatePathFindInfoMem(4500);
+ CScriptPaths::Init();
CWeather::Init();
CCullZones::Init();
+ COcclusion::Init();
CCollision::Init();
-#ifdef PS2_MENU // TODO: is this the right define?
- TheText.Load();
-#endif
+ CSetPieces::Init();
CTheZones::Init();
CUserDisplay::Init();
CMessages::Init();
-#if GTA_VERSION > GTA3_PS2_160
CMessages::ClearAllMessagesDisplayedByGame();
-#endif
CRecordDataForGame::Init();
CRestart::Initialise();
@@ -467,22 +434,10 @@ bool CGame::Initialise(const char* datFile)
CWorld::Initialise();
POP_MEMID();
-#if GTA_VERSION <= GTA3_PS2_160
- mod_HandlingManager.Initialise();
- CSurfaceTable::Initialise("DATA\\SURFACE.DAT");
- CTempColModels::Initialise();
-#endif
-
PUSH_MEMID(MEMID_TEXTURES);
CParticle::Initialise();
POP_MEMID();
-#if GTA_VERSION <= GTA3_PS2_160
- gStartX = -180.0f;
- gStartY = 180.0f;
- gStartZ = 14.0f;
-#endif
-
PUSH_MEMID(MEMID_ANIMATION);
CAnimManager::Initialise();
CCutsceneMgr::Initialise();
@@ -493,13 +448,8 @@ bool CGame::Initialise(const char* datFile)
POP_MEMID();
PUSH_MEMID(MEMID_DEF_MODELS);
-#if GTA_VERSION > GTA3_PS2_160
InitModelIndices();
-#endif
CModelInfo::Initialise();
-
-#if GTA_VERSION > GTA3_PS2_160
- // probably moved before LoadLevel for multiplayer maps?
CPickups::Init();
CTheCarGenerators::Init();
@@ -507,55 +457,42 @@ bool CGame::Initialise(const char* datFile)
CFileLoader::LoadLevel("DATA\\DEFAULT.DAT");
CFileLoader::LoadLevel(datFile);
-#else
- CPedStats::Initialise(); // InitialiseOnceAfterRW
-
- CFileLoader::LoadLevel("GTA3.DAT");
-#endif
+ LoadingScreen("Loading the Game", "Add Particles", nil);
CWorld::AddParticles();
CVehicleModelInfo::LoadVehicleColours();
CVehicleModelInfo::LoadEnvironmentMaps();
CTheZones::PostZoneCreation();
POP_MEMID();
-#if GTA_VERSION <= GTA3_PS2_160
- TestModelIndices();
-#endif
- LoadingScreen("Loading the Game", "Setup paths", GetRandomSplashScreen());
+ LoadingScreen("Loading the Game", "Setup paths", nil);
ThePaths.PreparePathData();
-#if GTA_VERSION > GTA3_PS2_160
for (int i = 0; i < NUMPLAYERS; i++)
CWorld::Players[i].Clear();
CWorld::Players[0].LoadPlayerSkin();
TestModelIndices();
-#endif
LoadingScreen("Loading the Game", "Setup water", nil);
CWaterLevel::Initialise("DATA\\WATER.DAT");
-#if GTA_VERSION <= GTA3_PS2_160
- CTimeCycle::Initialise(); // InitialiseOnceAfterRW
-#else
TheConsole.Init();
-#endif
CDraw::SetFOV(120.0f);
CDraw::ms_fLODDistance = 500.0f;
LoadingScreen("Loading the Game", "Setup streaming", nil);
- CStreaming::Init();
CStreaming::LoadInitialVehicles();
CStreaming::LoadInitialPeds();
CStreaming::RequestBigBuildings(LEVEL_GENERIC);
CStreaming::LoadAllRequestedModels(false);
-#if GTA_VERSION > GTA3_PS2_160
+ CStreaming::RemoveIslandsNotUsed(currLevel);
printf("Streaming uses %zuK of its memory", CStreaming::ms_memoryUsed / 1024); // original modifier was %d
-#endif
LoadingScreen("Loading the Game", "Load animations", GetRandomSplashScreen());
PUSH_MEMID(MEMID_ANIMATION);
CAnimManager::LoadAnimFiles();
POP_MEMID();
+ CStreaming::LoadInitialWeapons();
+ CStreaming::LoadAllRequestedModels(0);
CPed::Initialise();
CRouteNode::Initialise();
CEventList::Initialise();
@@ -576,11 +513,6 @@ bool CGame::Initialise(const char* datFile)
LoadingScreen("Loading the Game", "Setup game variables", nil);
CPopulation::Initialise();
-#if GTA_VERSION <= GTA3_PS2_160
- for (int i = 0; i < NUMPLAYERS; i++)
- CWorld::Players[i].Clear();
-// CWorld::Players[0].LoadPlayerSkin(); // TODO: use a define for this
-#endif
CWorld::PlayerInFocus = 0;
CCoronas::Init();
CShadows::Init();
@@ -600,47 +532,24 @@ bool CGame::Initialise(const char* datFile)
POP_MEMID();
LoadingScreen("Loading the Game", "Setup game variables", nil);
-#if GTA_VERSION <= GTA3_PS2_160
- CTimer::Initialise();
-#endif
CClock::Initialise(1000);
-#if GTA_VERSION <= GTA3_PS2_160
- CTheCarGenerators::Init();
-#endif
CHeli::InitHelis();
CCranes::InitCranes();
CMovingThings::Init();
CDarkel::Init();
CStats::Init();
-#if GTA_VERSION <= GTA3_PS2_160
- CPickups::Init();
-#endif
CPacManPickups::Init();
-#if GTA_VERSION <= GTA3_PS2_160
- CGarages::Init();
-#endif
CRubbish::Init();
CClouds::Init();
-#if GTA_VERSION <= GTA3_PS2_160
- CRemote::Init();
-#endif
CSpecialFX::Init();
+ CRopes::Init();
CWaterCannons::Init();
CBridge::Init();
-#if GTA_VERSION > GTA3_PS2_160
CGarages::Init();
-#endif
LoadingScreen("Loading the Game", "Position dynamic objects", nil);
- CWorld::RepositionCertainDynamicObjects();
-#if GTA_VERSION <= GTA3_PS2_160
- CCullZones::ResolveVisibilities();
-#endif
-
LoadingScreen("Loading the Game", "Initialise vehicle paths", nil);
-#if GTA_VERSION > GTA3_PS2_160
- CCullZones::ResolveVisibilities();
-#endif
+
CTrain::InitTrains();
CPlane::InitPlanes();
CCredits::Init();
@@ -658,27 +567,44 @@ bool CGame::Initialise(const char* datFile)
}
LoadingScreen("Loading the Game", "Load scene", nil);
- CModelInfo::RemoveColModelsFromOtherLevels(currLevel);
CCollision::ms_collisionInMemory = currLevel;
for (int i = 0; i < MAX_PADS; i++)
CPad::GetPad(i)->Clear(true);
+#ifdef USE_TEXTURE_POOL
+ _TexturePoolsUnknown(true);
+#endif
+
+#ifndef MASTER
+ PlayerCoords = FindPlayerCoors();
+ VarConsole.Add("X PLAYER COORD", &PlayerCoords.x, 10.0f, -10000.0f, 10000.0f, true);
+ VarConsole.Add("Y PLAYER COORD", &PlayerCoords.y, 10.0f, -10000.0f, 10000.0f, true);
+ VarConsole.Add("Z PLAYER COORD", &PlayerCoords.z, 10.0f, -10000.0f, 10000.0f, true);
+ VarConsole.Add("UPDATE PLAYER COORD", &VarUpdatePlayerCoords, true);
+#endif
+
+
+ DMAudio.SetStartingTrackPositions(TRUE);
+ DMAudio.ChangeMusicMode(MUSICMODE_GAME);
return true;
}
bool CGame::ShutDown(void)
{
+#ifdef USE_TEXTURE_POOL
+ _TexturePoolsUnknown(false);
+#endif
CReplay::FinishPlayback();
+ CReplay::EmptyReplayBuffer();
CPlane::Shutdown();
CTrain::Shutdown();
+ CScriptPaths::Shutdown();
+ CWaterCreatures::RemoveAll();
CSpecialFX::Shutdown();
-#if GTA_VERSION > GTA3_PS2_160
CGarages::Shutdown();
-#endif
CMovingThings::Shutdown();
gPhoneInfo.Shutdown();
CWeapon::ShutdownWeapons();
CPedType::Shutdown();
- CMBlur::MotionBlurClose();
for (int32 i = 0; i < NUMPLAYERS; i++)
{
@@ -712,11 +638,14 @@ bool CGame::ShutDown(void)
CSkidmarks::Shutdown();
CWeaponEffects::Shutdown();
CParticle::Shutdown();
-#if GTA_VERSION > GTA3_PS2_160
CPools::ShutDown();
-#endif
+ CHud::ReInitialise();
CTxdStore::RemoveTxdSlot(gameTxdSlot);
+ CMBlur::MotionBlurClose();
CdStreamRemoveImages();
+#ifdef USE_TEXTURE_POOL
+ _TexturePoolsFinalShutdown();
+#endif
return true;
}
@@ -738,17 +667,15 @@ void CGame::ReInitGameObjectVariables(void)
CWorld::bDoingCarCollisions = false;
CHud::ReInitialise();
CRadar::Initialise();
-#if GTA_VERSION <= GTA3_PS2_160
- gStartX = -180.0f;
- gStartY = 180.0f;
- gStartZ = 14.0f;
-#endif
CCarCtrl::ReInit();
CTimeCycle::Initialise();
CDraw::SetFOV(120.0f);
CDraw::ms_fLODDistance = 500.0f;
CStreaming::RequestBigBuildings(LEVEL_GENERIC);
+ CStreaming::RemoveIslandsNotUsed(LEVEL_BEACH);
+ CStreaming::RemoveIslandsNotUsed(LEVEL_MAINLAND);
CStreaming::LoadAllRequestedModels(false);
+ currArea = AREA_MAIN_MAP;
CPed::Initialise();
CEventList::Initialise();
#ifdef SCREEN_DROPLETS
@@ -761,10 +688,6 @@ void CGame::ReInitGameObjectVariables(void)
CWorld::Players[i].Clear();
CWorld::PlayerInFocus = 0;
-#if GTA_VERSION <= GTA3_PS2_160
- CWeaponEffects::Init();
- CSkidmarks::Init();
-#endif
CAntennas::Init();
CGlass::Init();
gPhoneInfo.Initialise();
@@ -784,14 +707,11 @@ void CGame::ReInitGameObjectVariables(void)
CPickups::Init();
CPacManPickups::Init();
CGarages::Init();
-#if GTA_VERSION <= GTA3_PS2_160
- CClouds::Init();
- CRemote::Init();
-#endif
CSpecialFX::Init();
+ CRopes::Init();
CWaterCannons::Init();
+ CScriptPaths::Init();
CParticle::ReloadConfig();
- CCullZones::ResolveVisibilities();
#ifdef PS2_MENU
if ( !TheMemoryCard.m_bWantToLoad )
@@ -813,31 +733,18 @@ void CGame::ReInitGameObjectVariables(void)
void CGame::ReloadIPLs(void)
{
- CTimer::Stop();
- CWorld::RemoveStaticObjects();
- ThePaths.Init();
- CCullZones::Init();
- CFileLoader::ReloadPaths("GTA3.IDE");
- CFileLoader::LoadScene("INDUST.IPL");
- CFileLoader::LoadScene("COMMER.IPL");
- CFileLoader::LoadScene("SUBURBAN.IPL");
- CFileLoader::LoadScene("CULL.IPL");
- ThePaths.PreparePathData();
- CTrafficLights::ScanForLightsOnMap();
- CRoadBlocks::Init();
- CCranes::InitCranes();
- CGarages::Init();
- CWorld::RepositionCertainDynamicObjects();
- CCullZones::ResolveVisibilities();
- CRenderer::SortBIGBuildings();
- CTimer::Update();
+ // Empty and unused
}
void CGame::ShutDownForRestart(void)
{
+#ifdef USE_TEXTURE_POOL
+ _TexturePoolsUnknown(false);
+#endif
CReplay::FinishPlayback();
CReplay::EmptyReplayBuffer();
DMAudio.DestroyAllGameCreatedEntities();
+ CMovingThings::Shutdown();
for (int i = 0; i < NUMPLAYERS; i++)
CWorld::Players[i].Clear();
@@ -846,19 +753,16 @@ void CGame::ShutDownForRestart(void)
CTheScripts::UndoBuildingSwaps();
CTheScripts::UndoEntityInvisibilitySettings();
CWorld::ClearForRestart();
+ CGameLogic::ClearShortCut();
CTimer::Shutdown();
- CStreaming::FlushRequestList();
- CStreaming::DeleteAllRwObjects();
- CStreaming::RemoveAllUnusedModels();
- CStreaming::ms_disableStreaming = false;
+ CStreaming::ReInit();
CRadar::RemoveRadarSections();
FrontEndMenuManager.UnloadTextures();
- CParticleObject::RemoveAllParticleObjects();
-#if GTA_VERSION >= GTA3_PS2_160
+ CParticleObject::RemoveAllExpireableParticleObjects();
+ CWaterCreatures::RemoveAll();
+ CSetPieces::Init();
CPedType::Shutdown();
CSpecialFX::Shutdown();
-#endif
- TidyUpMemory(true, false);
}
void CGame::InitialiseWhenRestarting(void)
@@ -869,116 +773,38 @@ void CGame::InitialiseWhenRestarting(void)
CTimer::Initialise();
CSprite2d::SetRecipNearClip();
-#ifdef PS2_MENU
- if ( TheMemoryCard.b_FoundRecentSavedGameWantToLoad == true || TheMemoryCard.m_bWantToLoad == false )
+ if (b_FoundRecentSavedGameWantToLoad || FrontEndMenuManager.m_bWantToLoad)
{
- if ( TheMemoryCard.m_bWantToLoad == true )
- MessageScreen("MCLOAD"); // Loading Data. Please do not remove the Memory Card (PS2) in MEMORY CARD slot 1, reset or switch off the console.
- else
- MessageScreen("RESTART"); // Starting new game
- }
+ LoadSplash("splash1");
+#ifndef XBOX_MESSAGE_SCREEN
+ if (FrontEndMenuManager.m_bWantToLoad)
+ FrontEndMenuManager.MessageScreen("FELD_WR", true);
#endif
-
-#ifdef PS2_MENU
- TheMemoryCard.b_FoundRecentSavedGameWantToLoad = false;
-#else
+ }
+
b_FoundRecentSavedGameWantToLoad = false;
-#endif
TheCamera.Init();
-#ifdef PS2_MENU
- if ( TheMemoryCard.m_bWantToLoad == true )
- {
- TheMemoryCard.RestoreForStartLoad();
- CStreaming::LoadScene(TheCamera.GetPosition());
- }
-#else
if ( FrontEndMenuManager.m_bWantToLoad == true )
{
+#ifdef XBOX_MESSAGE_SCREEN
+ FrontEndMenuManager.SetDialogTimer(1000);
+ DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 0);
+ CSprite2d::InitPerFrame();
+ CFont::InitPerFrame();
+ FrontEndMenuManager.DrawOverlays();
+ DoRWStuffEndOfFrame();
+#endif
RestoreForStartLoad();
- CStreaming::LoadScene(TheCamera.GetPosition());
}
-#endif
ReInitGameObjectVariables();
-#ifdef PS2_MENU
- if ( TheMemoryCard.m_bWantToLoad == true )
- {
- if ( TheMemoryCard.LoadSavedGame() == CMemoryCard::RES_SUCCESS )
- {
- for ( int32 i = 0; i < 35; i++ )
- {
- MessageScreen("FESZ_LS"); // Load Successful.
- }
-
- DMAudio.ResetTimers(CTimer::GetTimeInMilliseconds());
- CTrain::InitTrains();
- CPlane::InitPlanes();
- }
- else
- {
- for ( int32 i = 0; i < 50; i++ )
- {
- DoRWStuffStartOfFrame(50, 50, 50, 0, 0, 0, 255);
-
- CSprite2d::InitPerFrame();
- CFont::InitPerFrame();
- DefinedState();
-
- CSprite2d *splash = LoadSplash(NULL);
- splash->Draw(rect, color, color, color, color);
-#ifdef FIX_BUGS
- splash->DrawRect(CRect(SCREEN_SCALE_X(20.0f), SCREEN_SCALE_Y(110.0f), SCREEN_SCALE_FROM_RIGHT(20.0f), SCREEN_SCALE_Y(300.0f)), CRGBA(50, 50, 50, 192));
-#else
- splash->DrawRect(CRect(20.0f, 110.0f, SCREEN_WIDTH-20.0f, 300.0f), CRGBA(50, 50, 50, 192));
-#endif
-
- CFont::SetBackgroundOff();
-#ifdef ASPECT_RATIO_SCALE
- CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(160.0f)); // because SCREEN_SCALE_FROM_RIGHT(x) != SCREEN_SCALE_X(640-x)
-#else
- CFont::SetWrapx(SCREEN_SCALE_X(480.0f));
-#endif
- CFont::SetScale(SCREEN_SCALE_X(1.0f), SCREEN_SCALE_Y(1.0f));
- CFont::SetCentreOn();
- CFont::SetCentreSize(SCREEN_SCALE_X(480.0f));
- CFont::SetJustifyOff();
- CFont::SetColor(CRGBA(255, 255, 255, 255));
- CFont::SetBackGroundOnlyTextOff();
- CFont::SetDropColor(CRGBA(32, 32, 32, 255));
- CFont::SetDropShadowPosition(3);
- CFont::SetPropOn();
-#ifdef FIX_BUGS
- CFont::PrintString(SCREEN_WIDTH/2, SCREEN_SCALE_Y(130.0f), TheText.Get("MC_LDFL")); // Load Failed!
- CFont::PrintString(SCREEN_WIDTH/2, SCREEN_SCALE_Y(170.0f), TheText.Get("FES_NOC")); // No Memory Card (PS2) in MEMORY CARD slot 1.
- CFont::PrintString(SCREEN_WIDTH/2, SCREEN_SCALE_Y(240.0f), TheText.Get("MC_NWRE")); // Now Restarting Game.
-#else
- CFont::PrintString(SCREEN_WIDTH/2, 130.0f, TheText.Get("MC_LDFL")); // Load Failed!
- CFont::PrintString(SCREEN_WIDTH/2, 170.0f, TheText.Get("FES_NOC")); // No Memory Card (PS2) in MEMORY CARD slot 1.
- CFont::PrintString(SCREEN_WIDTH/2, 240.0f, TheText.Get("MC_NWRE")); // Now Restarting Game.
-#endif
- CFont::DrawFonts();
-
- DoRWStuffEndOfFrame();
- }
-
- ShutDownForRestart();
- CTimer::Stop();
- CTimer::Initialise();
- TheMemoryCard.m_bWantToLoad = false;
- ReInitGameObjectVariables();
- currLevel = LEVEL_INDUSTRIAL;
- CCollision::SortOutCollisionAfterLoad();
-
- FrontEndMenuManager.SetSoundLevelsForMusicMenu();
- FrontEndMenuManager.InitialiseMenuContentsAfterLoadingGame();
- }
- }
-#else
if ( FrontEndMenuManager.m_bWantToLoad == true )
{
+ FrontEndMenuManager.m_bWantToLoad = false;
+ InitRadioStationPositionList();
if ( GenericLoad() == true )
{
DMAudio.ResetTimers(CTimer::GetTimeInMilliseconds());
@@ -990,23 +816,29 @@ void CGame::InitialiseWhenRestarting(void)
for ( int32 i = 0; i < 50; i++ )
{
HandleExit();
- FrontEndMenuManager.MessageScreen("FED_LFL"); // Loading save game has failed. The game will restart now.
+ FrontEndMenuManager.MessageScreen("FED_LFL", true); // Loading save game has failed. The game will restart now.
}
+ TheCamera.SetFadeColour(0, 0, 0);
ShutDownForRestart();
CTimer::Stop();
CTimer::Initialise();
FrontEndMenuManager.m_bWantToLoad = false;
ReInitGameObjectVariables();
- currLevel = LEVEL_INDUSTRIAL;
+ currLevel = LEVEL_GENERIC;
CCollision::SortOutCollisionAfterLoad();
}
- }
+#ifdef XBOX_MESSAGE_SCREEN
+ FrontEndMenuManager.ProcessDialogTimer();
#endif
+ }
CTimer::Update();
DMAudio.ChangeMusicMode(MUSICMODE_GAME);
+#ifdef USE_TEXTURE_POOL
+ _TexturePoolsUnknown(true);
+#endif
}
void CGame::Process(void)
@@ -1015,23 +847,35 @@ void CGame::Process(void)
#ifdef USE_CUSTOM_ALLOCATOR
ProcessTidyUpMemory();
#endif
- TheCamera.SetMotionBlurAlpha(0);
- if (TheCamera.m_BlurType == MOTION_BLUR_NONE || TheCamera.m_BlurType == MOTION_BLUR_SNIPER || TheCamera.m_BlurType == MOTION_BLUR_LIGHT_SCENE)
- TheCamera.SetMotionBlur(0, 0, 0, 0, MOTION_BLUR_NONE);
#ifdef DEBUGMENU
DebugMenuProcess();
#endif
CCutsceneMgr::Update();
- PUSH_MEMID(MEMID_FRONTEND);
if (!CCutsceneMgr::IsCutsceneProcessing() && !CTimer::GetIsCodePaused())
FrontEndMenuManager.Process();
- POP_MEMID();
+ CTheZones::Update();
+#ifdef SECUROM
+ if (CTimer::GetTimeInMilliseconds() >= (35 * 60 * 1000) && gameProcessPirateCheck == 0){
+ // if game not pirated
+ // gameProcessPirateCheck = 1;
+ // else
+ gameProcessPirateCheck = 2;
+ }
+#endif
+ uint32 startTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond();
CStreaming::Update();
+ uint32 processTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond() - startTime;
+ CWindModifiers::Number = 0;
if (!CTimer::GetIsPaused())
{
- CTheZones::Update();
+#ifndef MASTER
+ if (VarUpdatePlayerCoords) {
+ FindPlayerPed()->Teleport(PlayerCoords);
+ VarUpdatePlayerCoords = false;
+ }
+#endif
CSprite2d::SetRecipNearClip();
CSprite2d::InitPerFrame();
CFont::InitPerFrame();
@@ -1046,6 +890,7 @@ void CGame::Process(void)
POP_MEMID();
CCollision::Update();
+ CScriptPaths::Update();
CTrain::UpdateTrains();
CPlane::UpdatePlanes();
CHeli::UpdateHelis();
@@ -1056,10 +901,23 @@ void CGame::Process(void)
#ifdef GTA_SCENE_EDIT
CSceneEdit::Update();
#endif
+ CSetPieces::Update();
CEventList::Update();
CParticle::Update();
gFireManager.Update();
- CPopulation::Update();
+
+ // Otherwise even on 30 fps most probably you won't see any peds around Ocean View Hospital
+#if defined FIX_BUGS && !defined SQUEEZE_PERFORMANCE
+ if (processTime > 2) {
+#else
+ if (processTime >= 2) {
+#endif
+ CPopulation::Update(false);
+ } else {
+ uint32 startTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond();
+ CPopulation::Update(true);
+ processTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond() - startTime;
+ }
CWeapon::UpdateWeapons();
if (!CCutsceneMgr::IsRunning())
CTheCarGenerators::Process();
@@ -1081,6 +939,7 @@ void CGame::Process(void)
CGarages::Update();
CRubbish::Update();
CSpecialFX::Update();
+ CRopes::Update();
CTimeCycle::Update();
if (CReplay::ShouldStandardCameraBeProcessed())
TheCamera.Process();
@@ -1096,9 +955,11 @@ void CGame::Process(void)
if (!CReplay::IsPlayingBack())
{
PUSH_MEMID(MEMID_CARS);
- CCarCtrl::GenerateRandomCars();
+ if (processTime < 2)
+ CCarCtrl::GenerateRandomCars();
CRoadBlocks::GenerateRoadBlocks();
CCarCtrl::RemoveDistantCars();
+ CCarCtrl::RemoveCarsIfThePoolGetsFull();
POP_MEMID();
}
}
@@ -1109,15 +970,17 @@ void CGame::Process(void)
#ifdef USE_CUSTOM_ALLOCATOR
+// TODO(MIAMI)
+
int32 gNumMemMoved;
bool
-MoveMem(void **ptr)
+MoveMem(void** ptr)
{
- if(*ptr){
+ if (*ptr) {
gNumMemMoved++;
- void *newPtr = gMainHeap.MoveMemory(*ptr);
- if(*ptr != newPtr){
+ void* newPtr = gMainHeap.MoveMemory(*ptr);
+ if (*ptr != newPtr) {
*ptr = newPtr;
return true;
}
@@ -1147,21 +1010,21 @@ struct DMAGIFUpload
};
// This is very scary. it depends on the exact memory layout of the DMA chains and whatnot
-RwTexture *
-MoveTextureMemoryCB(RwTexture *texture, void *pData)
+RwTexture*
+MoveTextureMemoryCB(RwTexture* texture, void* pData)
{
#ifdef GTA_PS2
- bool *pRet = (bool*)pData;
- RwRaster *raster = RwTextureGetRaster(texture);
- _SkyRasterExt *rasterExt = RASTEREXTFROMRASTER(raster);
- if(raster->originalPixels == nil || // the raw data
- raster->cpPixels == raster->originalPixels || // old format, can't handle it
- rasterExt->dmaRefCount != 0 && rasterExt->dmaClrCount != 0)
+ bool* pRet = (bool*)pData;
+ RwRaster* raster = RwTextureGetRaster(texture);
+ _SkyRasterExt* rasterExt = RASTEREXTFROMRASTER(raster);
+ if (raster->originalPixels == nil || // the raw data
+ raster->cpPixels == raster->originalPixels || // old format, can't handle it
+ rasterExt->dmaRefCount != 0 && rasterExt->dmaClrCount != 0)
return texture;
// this is the allocated pointer we will move
- SkyDataPrefix *prefix = (SkyDataPrefix*)raster->originalPixels;
- DMAGIFUpload *uploads = (DMAGIFUpload*)(prefix+1);
+ SkyDataPrefix* prefix = (SkyDataPrefix*)raster->originalPixels;
+ DMAGIFUpload* uploads = (DMAGIFUpload*)(prefix + 1);
// We have 4qw for each upload,
// i.e. for each buffer width of mip levels,
@@ -1178,24 +1041,24 @@ MoveTextureMemoryCB(RwTexture *texture, void *pData)
uintptr dataDiff, upload1Diff, upload2Diff, pixelDiff, paletteDiff;
dataDiff = prefix->data - (uintptr)raster->originalPixels;
upload1Diff = uploads[0].tag2_addr - (uintptr)raster->originalPixels;
- if(raster->palette)
+ if (raster->palette)
upload2Diff = uploads[1].tag2_addr - (uintptr)raster->originalPixels;
pixelDiff = (uintptr)raster->cpPixels - (uintptr)raster->originalPixels;
- if(raster->palette)
+ if (raster->palette)
paletteDiff = (uintptr)raster->palette - (uintptr)raster->originalPixels;
- uint8 *newptr = (uint8*)gMainHeap.MoveMemory(raster->originalPixels);
- if(newptr != raster->originalPixels){
+ uint8* newptr = (uint8*)gMainHeap.MoveMemory(raster->originalPixels);
+ if (newptr != raster->originalPixels) {
// adjust everything
prefix->data = (uintptr)newptr + dataDiff;
uploads[0].tag2_addr = (uintptr)newptr + upload1Diff;
- if(raster->palette)
+ if (raster->palette)
uploads[1].tag2_addr = (uintptr)newptr + upload2Diff;
raster->originalPixels = newptr;
raster->cpPixels = newptr + pixelDiff;
- if(raster->palette)
+ if (raster->palette)
raster->palette = newptr + paletteDiff;
- if(pRet){
+ if (pRet) {
*pRet = true;
return nil;
}
@@ -1207,42 +1070,42 @@ MoveTextureMemoryCB(RwTexture *texture, void *pData)
}
bool
-MoveAtomicMemory(RpAtomic *atomic, bool onlyOne)
+MoveAtomicMemory(RpAtomic* atomic, bool onlyOne)
{
- RpGeometry *geo = RpAtomicGetGeometry(atomic);
+ RpGeometry* geo = RpAtomicGetGeometry(atomic);
#if THIS_IS_COMPATIBLE_WITH_GTA3_RW31
- if(MoveMem((void**)&geo->triangles) && onlyOne)
+ if (MoveMem((void**)&geo->triangles) && onlyOne)
return true;
- if(MoveMem((void**)&geo->matList.materials) && onlyOne)
+ if (MoveMem((void**)&geo->matList.materials) && onlyOne)
return true;
- if(MoveMem((void**)&geo->preLitLum) && onlyOne)
+ if (MoveMem((void**)&geo->preLitLum) && onlyOne)
return true;
- if(MoveMem((void**)&geo->texCoords[0]) && onlyOne)
+ if (MoveMem((void**)&geo->texCoords[0]) && onlyOne)
return true;
- if(MoveMem((void**)&geo->texCoords[1]) && onlyOne)
+ if (MoveMem((void**)&geo->texCoords[1]) && onlyOne)
return true;
// verts and normals of morph target are allocated together
int vertDiff;
- if(geo->morphTarget->normals)
+ if (geo->morphTarget->normals)
vertDiff = geo->morphTarget->normals - geo->morphTarget->verts;
- if(MoveMem((void**)&geo->morphTarget->verts)){
- if(geo->morphTarget->normals)
+ if (MoveMem((void**)&geo->morphTarget->verts)) {
+ if (geo->morphTarget->normals)
geo->morphTarget->normals = geo->morphTarget->verts + vertDiff;
- if(onlyOne)
+ if (onlyOne)
return true;
}
- RpMeshHeader *oldmesh = geo->mesh;
- if(MoveMem((void**)&geo->mesh)){
+ RpMeshHeader* oldmesh = geo->mesh;
+ if (MoveMem((void**)&geo->mesh)) {
// index pointers are allocated together with meshes,
// have to relocate those too
- RpMesh *mesh = (RpMesh*)(geo->mesh+1);
+ RpMesh* mesh = (RpMesh*)(geo->mesh + 1);
uintptr reloc = (uintptr)geo->mesh - (uintptr)oldmesh;
- for(int i = 0; i < geo->mesh->numMeshes; i++)
+ for (int i = 0; i < geo->mesh->numMeshes; i++)
mesh[i].indices = (RxVertexIndex*)((uintptr)mesh[i].indices + reloc);
- if(onlyOne)
+ if (onlyOne)
return true;
}
#else
@@ -1252,37 +1115,37 @@ MoveAtomicMemory(RpAtomic *atomic, bool onlyOne)
}
bool
-MoveColModelMemory(CColModel &colModel, bool onlyOne)
+MoveColModelMemory(CColModel& colModel, bool onlyOne)
{
#if GTA_VERSION >= GTA3_PS2_160
// hm...should probably only do this if ownsCollisionVolumes
// but it doesn't exist on PS2...
- if(!colModel.ownsCollisionVolumes)
+ if (!colModel.ownsCollisionVolumes)
return false;
#endif
- if(MoveMem((void**)&colModel.spheres) && onlyOne)
+ if (MoveMem((void**)&colModel.spheres) && onlyOne)
return true;
- if(MoveMem((void**)&colModel.lines) && onlyOne)
+ if (MoveMem((void**)&colModel.lines) && onlyOne)
return true;
- if(MoveMem((void**)&colModel.boxes) && onlyOne)
+ if (MoveMem((void**)&colModel.boxes) && onlyOne)
return true;
- if(MoveMem((void**)&colModel.vertices) && onlyOne)
+ if (MoveMem((void**)&colModel.vertices) && onlyOne)
return true;
- if(MoveMem((void**)&colModel.triangles) && onlyOne)
+ if (MoveMem((void**)&colModel.triangles) && onlyOne)
return true;
- if(MoveMem((void**)&colModel.trianglePlanes) && onlyOne)
+ if (MoveMem((void**)&colModel.trianglePlanes) && onlyOne)
return true;
return false;
}
RpAtomic*
-MoveAtomicMemoryCB(RpAtomic *atomic, void *pData)
+MoveAtomicMemoryCB(RpAtomic* atomic, void* pData)
{
- bool *pRet = (bool*)pData;
- if(pRet == nil)
+ bool* pRet = (bool*)pData;
+ if (pRet == nil)
MoveAtomicMemory(atomic, false);
- else if(MoveAtomicMemory(atomic, true)){
+ else if (MoveAtomicMemory(atomic, true)) {
*pRet = true;
return nil;
}
@@ -1290,34 +1153,35 @@ MoveAtomicMemoryCB(RpAtomic *atomic, void *pData)
}
bool
-TidyUpModelInfo(CBaseModelInfo *modelInfo, bool onlyone)
+TidyUpModelInfo(CBaseModelInfo* modelInfo, bool onlyone)
{
- if(modelInfo->GetColModel() && modelInfo->DoesOwnColModel())
- if(MoveColModelMemory(*modelInfo->GetColModel(), onlyone))
+ if (modelInfo->GetColModel() && modelInfo->DoesOwnColModel())
+ if (MoveColModelMemory(*modelInfo->GetColModel(), onlyone))
return true;
- RwObject *rwobj = modelInfo->GetRwObject();
- if(RwObjectGetType(rwobj) == rpATOMIC)
- if(MoveAtomicMemory((RpAtomic*)rwobj, onlyone))
+ RwObject* rwobj = modelInfo->GetRwObject();
+ if (RwObjectGetType(rwobj) == rpATOMIC)
+ if (MoveAtomicMemory((RpAtomic*)rwobj, onlyone))
return true;
- if(RwObjectGetType(rwobj) == rpCLUMP){
+ if (RwObjectGetType(rwobj) == rpCLUMP) {
bool ret = false;
- if(onlyone)
+ if (onlyone)
RpClumpForAllAtomics((RpClump*)rwobj, MoveAtomicMemoryCB, &ret);
else
RpClumpForAllAtomics((RpClump*)rwobj, MoveAtomicMemoryCB, nil);
- if(ret)
+ if (ret)
return true;
}
- if(modelInfo->GetModelType() == MITYPE_PED && ((CPedModelInfo*)modelInfo)->m_hitColModel)
- if(MoveColModelMemory(*((CPedModelInfo*)modelInfo)->m_hitColModel, onlyone))
+ if (modelInfo->GetModelType() == MITYPE_PED && ((CPedModelInfo*)modelInfo)->m_hitColModel)
+ if (MoveColModelMemory(*((CPedModelInfo*)modelInfo)->m_hitColModel, onlyone))
return true;
return false;
}
#endif
+
void CGame::DrasticTidyUpMemory(bool flushDraw)
{
#ifdef USE_CUSTOM_ALLOCATOR
@@ -1325,32 +1189,32 @@ void CGame::DrasticTidyUpMemory(bool flushDraw)
TidyUpMemory(true, flushDraw);
- if(gMainHeap.GetLargestFreeBlock() < 200000 && !playingIntro){
+ if (gMainHeap.GetLargestFreeBlock() < 200000 && !playingIntro) {
CStreaming::RemoveIslandsNotUsed(LEVEL_INDUSTRIAL);
CStreaming::RemoveIslandsNotUsed(LEVEL_COMMERCIAL);
CStreaming::RemoveIslandsNotUsed(LEVEL_SUBURBAN);
TidyUpMemory(true, flushDraw);
}
- if(gMainHeap.GetLargestFreeBlock() < 200000 && !playingIntro){
+ if (gMainHeap.GetLargestFreeBlock() < 200000 && !playingIntro) {
CModelInfo::RemoveColModelsFromOtherLevels(LEVEL_GENERIC);
TidyUpMemory(true, flushDraw);
removedCol = true;
}
- if(gMainHeap.GetLargestFreeBlock() < 200000 && !playingIntro){
+ if (gMainHeap.GetLargestFreeBlock() < 200000 && !playingIntro) {
CStreaming::RemoveBigBuildings(LEVEL_INDUSTRIAL);
CStreaming::RemoveBigBuildings(LEVEL_COMMERCIAL);
CStreaming::RemoveBigBuildings(LEVEL_SUBURBAN);
TidyUpMemory(true, flushDraw);
}
- if(removedCol){
+ if (removedCol) {
// different on PS2
CFileLoader::LoadCollisionFromDatFile(CCollision::ms_collisionInMemory);
}
- if(!playingIntro)
+ if (!playingIntro)
CStreaming::RequestBigBuildings(currLevel);
CStreaming::LoadAllRequestedModels(true);
@@ -1362,49 +1226,49 @@ void CGame::TidyUpMemory(bool moveTextures, bool flushDraw)
#ifdef USE_CUSTOM_ALLOCATOR
printf("Largest free block before tidy %d\n", gMainHeap.GetLargestFreeBlock());
- if(moveTextures){
- if(flushDraw){
+ if (moveTextures) {
+ if (flushDraw) {
#ifdef GTA_PS2
- for(int i = 0; i < sweMaxFlips+1; i++){
+ for (int i = 0; i < sweMaxFlips + 1; i++) {
#else
- for(int i = 0; i < 5; i++){ // probably more than needed
+ for (int i = 0; i < 5; i++) { // probably more than needed
#endif
RwCameraBeginUpdate(Scene.camera);
RwCameraEndUpdate(Scene.camera);
RwCameraShowRaster(Scene.camera, nil, 0);
}
- }
+ }
int fontSlot = CTxdStore::FindTxdSlot("fonts");
- for(int i = 0; i < TXDSTORESIZE; i++){
- if(i == fontSlot ||
- CTxdStore::GetSlot(i) == nil)
+ for (int i = 0; i < TXDSTORESIZE; i++) {
+ if (i == fontSlot ||
+ CTxdStore::GetSlot(i) == nil)
continue;
- RwTexDictionary *txd = CTxdStore::GetSlot(i)->texDict;
- if(txd)
+ RwTexDictionary* txd = CTxdStore::GetSlot(i)->texDict;
+ if (txd)
RwTexDictionaryForAllTextures(txd, MoveTextureMemoryCB, nil);
}
- }
+ }
// animations
- for(int i = 0; i < NUMANIMATIONS; i++){
- CAnimBlendHierarchy *anim = CAnimManager::GetAnimation(i);
- if(anim == nil)
+ for (int i = 0; i < NUMANIMATIONS; i++) {
+ CAnimBlendHierarchy* anim = CAnimManager::GetAnimation(i);
+ if (anim == nil)
continue; // cannot happen
anim->MoveMemory();
}
// model info
- for(int i = 0; i < MODELINFOSIZE; i++){
- CBaseModelInfo *mi = CModelInfo::GetModelInfo(i);
- if(mi == nil)
+ for (int i = 0; i < MODELINFOSIZE; i++) {
+ CBaseModelInfo* mi = CModelInfo::GetModelInfo(i);
+ if (mi == nil)
continue;
TidyUpModelInfo(mi, false);
}
printf("Largest free block after tidy %d\n", gMainHeap.GetLargestFreeBlock());
#endif
-}
+ }
void CGame::ProcessTidyUpMemory(void)
{
@@ -1413,52 +1277,76 @@ void CGame::ProcessTidyUpMemory(void)
static int32 animIndex = 0;
static int32 txdIndex = 0;
bool txdReturn = false;
- RwTexDictionary *txd = nil;
+ RwTexDictionary* txd = nil;
gNumMemMoved = 0;
// model infos
- for(int numCleanedUp = 0; numCleanedUp < 10; numCleanedUp++){
- CBaseModelInfo *mi;
- do{
+ for (int numCleanedUp = 0; numCleanedUp < 10; numCleanedUp++) {
+ CBaseModelInfo* mi;
+ do {
mi = CModelInfo::GetModelInfo(modelIndex);
modelIndex++;
- if(modelIndex >= MODELINFOSIZE)
+ if (modelIndex >= MODELINFOSIZE)
modelIndex = 0;
- }while(mi == nil);
+ } while (mi == nil);
- if(TidyUpModelInfo(mi, true))
+ if (TidyUpModelInfo(mi, true))
return;
}
// tex dicts
- for(int numCleanedUp = 0; numCleanedUp < 3; numCleanedUp++){
- if(gNumMemMoved > 80)
+ for (int numCleanedUp = 0; numCleanedUp < 3; numCleanedUp++) {
+ if (gNumMemMoved > 80)
break;
- do{
+ do {
#ifdef FIX_BUGS
txd = nil;
#endif
- if(CTxdStore::GetSlot(txdIndex))
+ if (CTxdStore::GetSlot(txdIndex))
txd = CTxdStore::GetSlot(txdIndex)->texDict;
txdIndex++;
- if(txdIndex >= TXDSTORESIZE)
+ if (txdIndex >= TXDSTORESIZE)
txdIndex = 0;
- }while(txd == nil);
+ } while (txd == nil);
RwTexDictionaryForAllTextures(txd, MoveTextureMemoryCB, &txdReturn);
- if(txdReturn)
+ if (txdReturn)
return;
- }
+ }
// animations
- CAnimBlendHierarchy *anim;
- do{
+ CAnimBlendHierarchy* anim;
+ do {
anim = CAnimManager::GetAnimation(animIndex);
animIndex++;
- if(animIndex >= NUMANIMATIONS)
+ if (animIndex >= NUMANIMATIONS)
animIndex = 0;
- }while(anim == nil); // always != nil
+ } while (anim == nil); // always != nil
anim->MoveMemory(true);
#endif
}
+
+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::CanSeeWaterFromCurrArea(void)
+{
+ return currArea == AREA_MAIN_MAP || currArea == AREA_MANSION
+ || currArea == AREA_HOTEL;
+}
+
+bool
+CGame::CanSeeOutSideFromCurrArea(void)
+{
+ return currArea == AREA_MAIN_MAP || currArea == AREA_MALL ||
+ currArea == AREA_MANSION || currArea == AREA_HOTEL;
+}
diff --git a/src/core/Game.h b/src/core/Game.h
index 002033a0..4052eb00 100644
--- a/src/core/Game.h
+++ b/src/core/Game.h
@@ -3,16 +3,39 @@
enum eLevelName {
LEVEL_IGNORE = -1, // beware, this is only used in CPhysical's m_nZoneLevel
LEVEL_GENERIC = 0,
- LEVEL_INDUSTRIAL,
- LEVEL_COMMERCIAL,
- LEVEL_SUBURBAN,
+ LEVEL_BEACH,
+ LEVEL_MAINLAND,
+
NUM_LEVELS
};
+enum eAreaName {
+ AREA_MAIN_MAP,
+ AREA_HOTEL,
+ AREA_MANSION,
+ AREA_BANK,
+ AREA_MALL,
+ AREA_STRIP_CLUB,
+ AREA_LAWYERS,
+ AREA_COFFEE_SHOP,
+ AREA_CONCERT_HALL,
+ AREA_STUDIO,
+ AREA_RIFLE_RANGE,
+ AREA_BIKER_BAR,
+ AREA_POLICE_STATION,
+ AREA_EVERYWHERE,
+ AREA_DIRT,
+ AREA_BLOOD,
+ AREA_OVALRING,
+ AREA_MALIBU_CLUB,
+ AREA_PRINT_WORKS
+};
+
class CGame
{
public:
static eLevelName currLevel;
+ static int32 currArea;
static bool bDemoMode;
static bool nastyGame;
static bool frenchGame;
@@ -25,25 +48,34 @@ public:
static bool playingIntro;
static char aDatFile[32];
+#ifndef MASTER
+ static CVector PlayerCoords;
+ static bool8 VarUpdatePlayerCoords;
+#endif
+
static bool InitialiseOnceBeforeRW(void);
static bool InitialiseRenderWare(void);
static void ShutdownRenderWare(void);
static bool InitialiseOnceAfterRW(void);
static void FinalShutdown(void);
-#if GTA_VERSION <= GTA3_PS2_160
- static bool Initialise(void);
-#else
static bool Initialise(const char *datFile);
-#endif
static bool ShutDown(void);
static void ReInitGameObjectVariables(void);
static void ReloadIPLs(void);
static void ShutDownForRestart(void);
static void InitialiseWhenRestarting(void);
static void Process(void);
+
+ static void InitAfterFocusLoss(void);
+
+ static bool IsInInterior(void) { return currArea != AREA_MAIN_MAP; }
+ static bool CanSeeWaterFromCurrArea(void);
+ static bool CanSeeOutSideFromCurrArea(void);
// NB: these do something on PS2
static void TidyUpMemory(bool, bool);
static void DrasticTidyUpMemory(bool);
static void ProcessTidyUpMemory(void);
};
+
+inline bool IsAreaVisible(int area) { return area == CGame::currArea || area == AREA_EVERYWHERE; }
diff --git a/src/core/General.h b/src/core/General.h
index d4b941dd..c17d916d 100644
--- a/src/core/General.h
+++ b/src/core/General.h
@@ -143,6 +143,18 @@ public:
return *str2 != '\0';
}
+ static bool SolveQuadratic(float a, float b, float c, float &root1, float &root2)
+ {
+ float discriminant = b * b - 4.f * a * c;
+ if (discriminant < 0.f)
+ return false;
+
+ float discriminantSqrt = Sqrt(discriminant);
+ root2 = (-b + discriminantSqrt) / (2.f * a);
+ root1 = (-b - discriminantSqrt) / (2.f * a);
+ return true;
+ }
+
// not too sure about all these...
static uint16 GetRandomNumber(void)
{ return myrand() & MYRAND_MAX; }
@@ -154,4 +166,6 @@ public:
static int32 GetRandomNumberInRange(int32 low, int32 high)
{ return low + (high - low)*(GetRandomNumber()/float(MYRAND_MAX + 1)); }
+ static void SetRandomSeed(int32 seed)
+ { mysrand(seed); }
};
diff --git a/src/core/IniFile.cpp b/src/core/IniFile.cpp
index 524632fe..5d343ec9 100644
--- a/src/core/IniFile.cpp
+++ b/src/core/IniFile.cpp
@@ -7,8 +7,8 @@
#include "main.h"
#include "Population.h"
-float CIniFile::PedNumberMultiplier = 1.0f;
-float CIniFile::CarNumberMultiplier = 1.0f;
+float CIniFile::PedNumberMultiplier = 0.6f;
+float CIniFile::CarNumberMultiplier = 0.6f;
void CIniFile::LoadIniFile()
{
@@ -24,5 +24,6 @@ void CIniFile::LoadIniFile()
CFileMgr::CloseFile(f);
}
CPopulation::MaxNumberOfPedsInUse = DEFAULT_MAX_NUMBER_OF_PEDS * PedNumberMultiplier;
+ CPopulation::MaxNumberOfPedsInUseInterior = DEFAULT_MAX_NUMBER_OF_PEDS_INTERIOR * PedNumberMultiplier;
CCarCtrl::MaxNumberOfCarsInUse = DEFAULT_MAX_NUMBER_OF_CARS * CarNumberMultiplier;
} \ No newline at end of file
diff --git a/src/core/IniFile.h b/src/core/IniFile.h
index 30dc8c21..dcaed980 100644
--- a/src/core/IniFile.h
+++ b/src/core/IniFile.h
@@ -1,6 +1,7 @@
#pragma once
#define DEFAULT_MAX_NUMBER_OF_PEDS 25.0f
+#define DEFAULT_MAX_NUMBER_OF_PEDS_INTERIOR 40.0f
#define DEFAULT_MAX_NUMBER_OF_CARS 12.0f
class CIniFile
diff --git a/src/core/MenuScreens.cpp b/src/core/MenuScreens.cpp
index 0a149f27..295038d9 100644
--- a/src/core/MenuScreens.cpp
+++ b/src/core/MenuScreens.cpp
@@ -6,445 +6,347 @@
// Check MenuScreensCustom.cpp
#ifndef CUSTOM_FRONTEND_OPTIONS
-CMenuScreen aScreens[MENUPAGES] = {
- // MENUPAGE_NONE = 0
- { "", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, },
-
- // MENUPAGE_STATS = 1
- { "FET_STA", 1, MENUPAGE_NONE, MENUPAGE_NONE, 5, 2,
- MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
- },
-
- // MENUPAGE_NEW_GAME = 2
- { "FET_SGA", 1, MENUPAGE_NONE, MENUPAGE_NONE, 0, 1,
- MENUACTION_CHANGEMENU, "FES_SNG", SAVESLOT_NONE, MENUPAGE_NEW_GAME_RELOAD,
- MENUACTION_POPULATESLOTS_CHANGEMENU, "GMLOAD", SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT,
- MENUACTION_POPULATESLOTS_CHANGEMENU, "FES_DGA", SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT,
- MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
+CMenuScreen aScreens[] = {
+ // MENUPAGE_STATS = 0
+ { "FEH_STA", MENUPAGE_NONE, 3,
+ MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 190, 320, MENUALIGN_RIGHT,
},
- // MENUPAGE_BRIEFS = 3
- { "FET_BRE", 1, MENUPAGE_NONE, MENUPAGE_NONE, 6, 3,
- MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
+ // MENUPAGE_NEW_GAME = 1
+ { "FEP_STG", MENUPAGE_NONE, 1,
+ MENUACTION_CHANGEMENU, "FES_NGA", SAVESLOT_NONE, MENUPAGE_NEW_GAME_RELOAD, 320, 155, MENUALIGN_CENTER,
+ MENUACTION_CHANGEMENU, "FES_LOA", SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_CHANGEMENU, "FES_DEL", SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, 0, 0, 0, MENUALIGN_CENTER,
},
- // MENUPAGE_CONTROLLER_SETTINGS = 4
- { "FET_CON", 1, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 0, 0,
- MENUACTION_CTRLCONFIG, "FEC_CCF", SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS,
- MENUACTION_CTRLDISPLAY, "FEC_CDP", SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS,
- MENUACTION_CTRLVIBRATION, "FEC_VIB", SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS,
- MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
+ // MENUPAGE_BRIEFS = 2
+ { "FEH_BRI", MENUPAGE_NONE, 4,
+ MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 190, 320, MENUALIGN_RIGHT,
},
- // MENUPAGE_SOUND_SETTINGS = 5
- { "FET_AUD", 1, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 1, 1,
- MENUACTION_MUSICVOLUME, "FEA_MUS", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS,
- MENUACTION_SFXVOLUME, "FEA_SFX", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS,
+ // MENUPAGE_SOUND_SETTINGS = 3
+ { "FEH_AUD", MENUPAGE_OPTIONS, 1,
+ MENUACTION_MUSICVOLUME, "FEA_MUS", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, 40, 76, MENUALIGN_LEFT,
+ MENUACTION_SFXVOLUME, "FEA_SFX", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_MP3VOLUMEBOOST, "FEA_MPB", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, 0, 0, MENUALIGN_LEFT,
+#ifdef EXTERNAL_3D_SOUND
+ MENUACTION_AUDIOHW, "FEA_3DH", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_SPEAKERCONF, "FEA_SPK", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, 0, 0, MENUALIGN_LEFT,
+#endif
+ MENUACTION_DYNAMICACOUSTIC, "FET_DAM", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_RADIO, "FEA_RSS", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, 0, 0, MENUALIGN_LEFT,
#ifdef EXTERNAL_3D_SOUND
- MENUACTION_AUDIOHW, "FEA_3DH", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS,
- MENUACTION_SPEAKERCONF, "FEA_SPK", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS,
+ MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, 320, 367, MENUALIGN_CENTER,
+#else
+ MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, 320, 327, MENUALIGN_CENTER,
#endif
- MENUACTION_DYNAMICACOUSTIC, "FET_DAM", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS,
- MENUACTION_RADIO, "FEA_RSS", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS,
- MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS,
- MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
- },
-
- // MENUPAGE_DISPLAY_SETTINGS = 6
- { "FET_DIS", 1, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 2, 2,
- MENUACTION_BRIGHTNESS, "FED_BRI", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS,
- MENUACTION_DRAWDIST, "FEM_LOD", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS,
- MENUACTION_FRAMESYNC, "FEM_VSC", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS,
- MENUACTION_FRAMELIMIT, "FEM_FRM", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS,
- MENUACTION_TRAILS, "FED_TRA", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS,
- MENUACTION_SUBTITLES, "FED_SUB", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS,
- MENUACTION_WIDESCREEN, "FED_WIS", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS,
- MENUACTION_SCREENRES, "FED_RES", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS,
- MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS,
- MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
- },
-
- // MENUPAGE_LANGUAGE_SETTINGS = 7
- { "FET_LAN", 1, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 3, 3,
- MENUACTION_LANG_ENG, "FEL_ENG", SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS,
- MENUACTION_LANG_FRE, "FEL_FRE", SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS,
- MENUACTION_LANG_GER, "FEL_GER", SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS,
- MENUACTION_LANG_ITA, "FEL_ITA", SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS,
- MENUACTION_LANG_SPA, "FEL_SPA", SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS,
- MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
+ MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, MENUALIGN_CENTER,
},
- // MENUPAGE_CHOOSE_LOAD_SLOT = 8
- { "FET_LG", 1, MENUPAGE_NEW_GAME, MENUPAGE_NEW_GAME, 1, 1,
- MENUACTION_CHANGEMENU, "FESZ_CA", SAVESLOT_NONE, MENUPAGE_NEW_GAME,
- MENUACTION_CHECKSAVE, "FEM_SL0", SAVESLOT_1, MENUPAGE_LOAD_SLOT_CONFIRM,
- MENUACTION_CHECKSAVE, "FEM_SL1", SAVESLOT_2, MENUPAGE_LOAD_SLOT_CONFIRM,
- MENUACTION_CHECKSAVE, "FEM_SL2", SAVESLOT_3, MENUPAGE_LOAD_SLOT_CONFIRM,
- MENUACTION_CHECKSAVE, "FEM_SL3", SAVESLOT_4, MENUPAGE_LOAD_SLOT_CONFIRM,
- MENUACTION_CHECKSAVE, "FEM_SL4", SAVESLOT_5, MENUPAGE_LOAD_SLOT_CONFIRM,
- MENUACTION_CHECKSAVE, "FEM_SL5", SAVESLOT_6, MENUPAGE_LOAD_SLOT_CONFIRM,
- MENUACTION_CHECKSAVE, "FEM_SL6", SAVESLOT_7, MENUPAGE_LOAD_SLOT_CONFIRM,
- MENUACTION_CHECKSAVE, "FEM_SL7", SAVESLOT_8, MENUPAGE_LOAD_SLOT_CONFIRM,
- },
+ // MENUPAGE_DISPLAY_SETTINGS = 4
+#ifdef LEGACY_MENU_OPTIONS
+ #define Y_OFFSET 50
+#else
+ #define Y_OFFSET 0
+#endif
- // MENUPAGE_CHOOSE_DELETE_SLOT = 9
- { "FET_DG", 1, MENUPAGE_NEW_GAME, MENUPAGE_NEW_GAME, 2, 2,
- MENUACTION_CHANGEMENU, "FESZ_CA", SAVESLOT_NONE, MENUPAGE_NEW_GAME,
- MENUACTION_CHANGEMENU, "FEM_SL0", SAVESLOT_1, MENUPAGE_DELETE_SLOT_CONFIRM,
- MENUACTION_CHANGEMENU, "FEM_SL1", SAVESLOT_2, MENUPAGE_DELETE_SLOT_CONFIRM,
- MENUACTION_CHANGEMENU, "FEM_SL2", SAVESLOT_3, MENUPAGE_DELETE_SLOT_CONFIRM,
- MENUACTION_CHANGEMENU, "FEM_SL3", SAVESLOT_4, MENUPAGE_DELETE_SLOT_CONFIRM,
- MENUACTION_CHANGEMENU, "FEM_SL4", SAVESLOT_5, MENUPAGE_DELETE_SLOT_CONFIRM,
- MENUACTION_CHANGEMENU, "FEM_SL5", SAVESLOT_6, MENUPAGE_DELETE_SLOT_CONFIRM,
- MENUACTION_CHANGEMENU, "FEM_SL6", SAVESLOT_7, MENUPAGE_DELETE_SLOT_CONFIRM,
- MENUACTION_CHANGEMENU, "FEM_SL7", SAVESLOT_8, MENUPAGE_DELETE_SLOT_CONFIRM,
+ { "FEH_DIS", MENUPAGE_OPTIONS, 2,
+ MENUACTION_BRIGHTNESS, "FED_BRI", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 78, MENUALIGN_LEFT,
+ MENUACTION_DRAWDIST, "FEM_LOD", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 103, MENUALIGN_LEFT,
+#ifdef LEGACY_MENU_OPTIONS
+ MENUACTION_FRAMESYNC, "FEM_VSC", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 128, MENUALIGN_LEFT,
+#endif
+ MENUACTION_FRAMELIMIT, "FEM_FRM", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 128 + Y_OFFSET/2, MENUALIGN_LEFT,
+#ifdef LEGACY_MENU_OPTIONS
+ MENUACTION_TRAILS, "FED_TRA", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 178, MENUALIGN_LEFT,
+#endif
+ MENUACTION_SUBTITLES, "FED_SUB", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 153 + Y_OFFSET, MENUALIGN_LEFT,
+ MENUACTION_WIDESCREEN, "FED_WIS", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 178 + Y_OFFSET, MENUALIGN_LEFT,
+ MENUACTION_LEGENDS, "MAP_LEG", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 202 + Y_OFFSET, MENUALIGN_LEFT,
+ MENUACTION_RADARMODE, "FED_RDR", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 228 + Y_OFFSET, MENUALIGN_LEFT,
+ MENUACTION_HUD, "FED_HUD", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 253 + Y_OFFSET, MENUALIGN_LEFT,
+ MENUACTION_SCREENRES, "FED_RES", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 278 + Y_OFFSET, MENUALIGN_LEFT,
+ MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 320, 303 + Y_OFFSET, MENUALIGN_CENTER,
+ MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 320, 328 + Y_OFFSET, MENUALIGN_CENTER,
},
- // MENUPAGE_NEW_GAME_RELOAD = 10
- { "FET_NG", 1, MENUPAGE_NEW_GAME, MENUPAGE_NEW_GAME, 0, 0,
- MENUACTION_LABEL, "FESZ_QR", SAVESLOT_NONE, MENUPAGE_NONE,
- MENUACTION_CHANGEMENU, "FEM_NO", SAVESLOT_NONE, MENUPAGE_NEW_GAME,
- MENUACTION_NEWGAME, "FEM_YES", SAVESLOT_NONE, MENUPAGE_NEW_GAME_RELOAD,
- },
+#undef Y_OFFSET
- // MENUPAGE_LOAD_SLOT_CONFIRM = 11
- { "FET_LG", 1, MENUPAGE_CHOOSE_LOAD_SLOT, MENUPAGE_CHOOSE_LOAD_SLOT, 0, 0,
- MENUACTION_LABEL, "FESZ_QL", SAVESLOT_NONE, MENUPAGE_NONE,
- MENUACTION_CHANGEMENU, "FEM_NO", SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT,
- MENUACTION_CHANGEMENU, "FEM_YES", SAVESLOT_NONE, MENUPAGE_LOADING_IN_PROGRESS,
+ // MENUPAGE_LANGUAGE_SETTINGS = 5
+ { "FEH_LAN", MENUPAGE_OPTIONS, 3,
+ MENUACTION_LANG_ENG, "FEL_ENG", SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS, 320, 132, MENUALIGN_CENTER,
+ MENUACTION_LANG_FRE, "FEL_FRE", SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_LANG_GER, "FEL_GER", SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_LANG_ITA, "FEL_ITA", SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_LANG_SPA, "FEL_SPA", SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, MENUALIGN_CENTER,
},
- // MENUPAGE_DELETE_SLOT_CONFIRM = 12
- { "FET_DG", 1, MENUPAGE_CHOOSE_DELETE_SLOT, MENUPAGE_CHOOSE_DELETE_SLOT, 0, 0,
- MENUACTION_LABEL, "FESZ_QD", SAVESLOT_NONE, MENUPAGE_NONE,
- MENUACTION_CHANGEMENU, "FEM_NO", SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT,
- MENUACTION_CHANGEMENU, "FEM_YES", SAVESLOT_NONE, MENUPAGE_DELETING,
+ // MENUPAGE_MAP = 6
+ { "FEH_MAP", MENUPAGE_NONE, 2,
+ MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 70, 380, MENUALIGN_CENTER,
},
- // MENUPAGE_NO_MEMORY_CARD = 13
- { "FES_NOC", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
- // hud adjustment page in mobile
+ // MENUPAGE_NEW_GAME_RELOAD = 7
+ { "FES_NGA", MENUPAGE_NEW_GAME, 0,
+ MENUACTION_LABEL, "FESZ_QR", SAVESLOT_NONE, 0, 0, 0, 0,
+ MENUACTION_NO, "FEM_NO", SAVESLOT_NONE, MENUPAGE_NEW_GAME, 320, 200, MENUALIGN_CENTER,
+ MENUACTION_NEWGAME, "FEM_YES", SAVESLOT_NONE, MENUPAGE_NEW_GAME_RELOAD, 320, 225, MENUALIGN_CENTER,
},
- // MENUPAGE_LOADING_IN_PROGRESS = 14
- { "FET_LG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
- MENUACTION_LABEL, "FED_LDW", SAVESLOT_NONE, MENUPAGE_LOAD_SLOT_CONFIRM,
+ // MENUPAGE_CHOOSE_LOAD_SLOT = 8
+ { "FET_LG", MENUPAGE_NEW_GAME, 1,
+ MENUACTION_CHECKSAVE, "FEM_SL1", SAVESLOT_1, 0, 40, 90, MENUALIGN_LEFT,
+ MENUACTION_CHECKSAVE, "FEM_SL2", SAVESLOT_2, 0, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_CHECKSAVE, "FEM_SL3", SAVESLOT_3, 0, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_CHECKSAVE, "FEM_SL4", SAVESLOT_4, 0, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_CHECKSAVE, "FEM_SL5", SAVESLOT_5, 0, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_CHECKSAVE, "FEM_SL6", SAVESLOT_6, 0, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_CHECKSAVE, "FEM_SL7", SAVESLOT_7, 0, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_CHECKSAVE, "FEM_SL8", SAVESLOT_8, 0, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, 0, 320, 345, MENUALIGN_CENTER,
},
- // MENUPAGE_DELETING_IN_PROGRESS = 15
- { "FET_DG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
- MENUACTION_LABEL, "FEDL_WR", SAVESLOT_NONE, MENUPAGE_NONE,
+ // MENUPAGE_CHOOSE_DELETE_SLOT = 9
+ { "FES_DEL", MENUPAGE_NEW_GAME, 2,
+ MENUACTION_CHECKSAVE, "FEM_SL1", SAVESLOT_1, 0, 40, 90, MENUALIGN_LEFT,
+ MENUACTION_CHECKSAVE, "FEM_SL2", SAVESLOT_2, 0, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_CHECKSAVE, "FEM_SL3", SAVESLOT_3, 0, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_CHECKSAVE, "FEM_SL4", SAVESLOT_4, 0, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_CHECKSAVE, "FEM_SL5", SAVESLOT_5, 0, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_CHECKSAVE, "FEM_SL6", SAVESLOT_6, 0, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_CHECKSAVE, "FEM_SL7", SAVESLOT_7, 0, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_CHECKSAVE, "FEM_SL8", SAVESLOT_8, 0, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, 0, 320, 345, MENUALIGN_CENTER,
},
- // MENUPAGE_PS2_LOAD_FAILED = 16
- { "FET_LG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
- MENUACTION_LABEL, "FES_LOE", SAVESLOT_NONE, MENUPAGE_NONE,
+ // MENUPAGE_LOAD_SLOT_CONFIRM = 10
+ { "FET_LG", MENUPAGE_CHOOSE_LOAD_SLOT, 0,
+ MENUACTION_LABEL, "FESZ_QL", SAVESLOT_NONE, 0, 0, 0, 0,
+ MENUACTION_NO, "FEM_NO", SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT, 320, 200, MENUALIGN_CENTER,
+ MENUACTION_YES, "FEM_YES", SAVESLOT_NONE, MENUPAGE_LOADING_IN_PROGRESS, 320, 225, MENUALIGN_CENTER,
},
- // MENUPAGE_DELETE_FAILED = 17
- { "FET_DG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
- MENUACTION_LABEL, "FES_DEE", SAVESLOT_NONE, MENUPAGE_NONE,
- MENUACTION_CHANGEMENU, "FEC_OKK", SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT,
+ // MENUPAGE_DELETE_SLOT_CONFIRM = 11
+ { "FES_DEL", MENUPAGE_CHOOSE_DELETE_SLOT, 0,
+ MENUACTION_LABEL, "FESZ_QD", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0,
+ MENUACTION_NO, "FEM_NO", SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT, 320, 200, MENUALIGN_CENTER,
+ MENUACTION_YES, "FEM_YES", SAVESLOT_NONE, MENUPAGE_DELETING_IN_PROGRESS, 320, 225, MENUALIGN_CENTER,
},
- // MENUPAGE_DEBUG_MENU = 18
- { "FED_DBG", 1, MENUPAGE_NONE, MENUPAGE_NONE, 4, 0,
- MENUACTION_RELOADIDE, "FED_RID", SAVESLOT_NONE, MENUPAGE_NONE,
- MENUACTION_RELOADIPL, "FED_RIP", SAVESLOT_NONE, MENUPAGE_NONE,
- MENUACTION_SETDBGFLAG, "FED_DFL", SAVESLOT_NONE, MENUPAGE_NONE,
- MENUACTION_SWITCHBIGWHITEDEBUGLIGHT, "FED_DLS", SAVESLOT_NONE, MENUPAGE_NONE,
- MENUACTION_PEDROADGROUPS, "FED_SPR", SAVESLOT_NONE, MENUPAGE_NONE,
- MENUACTION_CARROADGROUPS, "FED_SCR", SAVESLOT_NONE, MENUPAGE_NONE,
- MENUACTION_COLLISIONPOLYS, "FED_SCP", SAVESLOT_NONE, MENUPAGE_NONE,
- MENUACTION_PARSEHEAP, "FED_PAH", SAVESLOT_NONE, MENUPAGE_NONE,
- MENUACTION_SHOWCULL, "FED_SCZ", SAVESLOT_NONE, MENUPAGE_NONE,
- MENUACTION_DEBUGSTREAM, "FED_DSR", SAVESLOT_NONE, MENUPAGE_NONE,
- MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
+ // MENUPAGE_LOADING_IN_PROGRESS = 12
+ { "FET_LG", MENUPAGE_CHOOSE_LOAD_SLOT, 0,
},
- // MENUPAGE_MEMORY_CARD_DEBUG = 19
- { "FEM_MCM", 1, MENUPAGE_NONE, MENUPAGE_NONE, 7, 0,
- MENUACTION_REGMEMCARD1, "FEM_RMC", SAVESLOT_NONE, MENUPAGE_NONE,
- MENUACTION_TESTFORMATMEMCARD1, "FEM_TFM", SAVESLOT_NONE, MENUPAGE_NONE,
- MENUACTION_TESTUNFORMATMEMCARD1, "FEM_TUM", SAVESLOT_NONE, MENUPAGE_NONE,
- MENUACTION_CREATEROOTDIR, "FEM_CRD", SAVESLOT_NONE, MENUPAGE_NONE,
- MENUACTION_CREATELOADICONS, "FEM_CLI", SAVESLOT_NONE, MENUPAGE_NONE,
- MENUACTION_FILLWITHGUFF, "FEM_FFF", SAVESLOT_NONE, MENUPAGE_NONE,
- MENUACTION_SAVEONLYTHEGAME, "FEM_SOG", SAVESLOT_NONE, MENUPAGE_NONE,
- MENUACTION_SAVEGAME, "FEM_STG", SAVESLOT_NONE, MENUPAGE_NONE,
- MENUACTION_SAVEGAMEUNDERGTA, "FEM_STS", SAVESLOT_NONE, MENUPAGE_NONE,
- MENUACTION_CREATECOPYPROTECTED, "FEM_CPD", SAVESLOT_NONE, MENUPAGE_NONE,
+ // MENUPAGE_DELETING_IN_PROGRESS = 13
+ { "FES_DEL", MENUPAGE_CHOOSE_DELETE_SLOT, 0,
},
- // MENUPAGE_MEMORY_CARD_TEST = 20
- { "FEM_MC2", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
+ // MENUPAGE_DELETE_SUCCESSFUL = 14
+ { "FES_DEL", MENUPAGE_NEW_GAME, 0,
+ MENUACTION_LABEL, "FES_DSC", SAVESLOT_NONE, 0, 0, 0, 0,
+ MENUACTION_CHANGEMENU, "FEM_OK", SAVESLOT_NONE, MENUPAGE_NEW_GAME, 320, 225, MENUALIGN_CENTER,
+ },
+ // MENUPAGE_CHOOSE_SAVE_SLOT = 15
+ { "FET_SG", MENUPAGE_DISABLED, 0,
+ MENUACTION_SAVEGAME, "FEM_SL1", SAVESLOT_1, MENUPAGE_SAVE_OVERWRITE_CONFIRM, 40, 90, MENUALIGN_LEFT,
+ MENUACTION_SAVEGAME, "FEM_SL2", SAVESLOT_2, MENUPAGE_SAVE_OVERWRITE_CONFIRM, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_SAVEGAME, "FEM_SL3", SAVESLOT_3, MENUPAGE_SAVE_OVERWRITE_CONFIRM, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_SAVEGAME, "FEM_SL4", SAVESLOT_4, MENUPAGE_SAVE_OVERWRITE_CONFIRM, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_SAVEGAME, "FEM_SL5", SAVESLOT_5, MENUPAGE_SAVE_OVERWRITE_CONFIRM, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_SAVEGAME, "FEM_SL6", SAVESLOT_6, MENUPAGE_SAVE_OVERWRITE_CONFIRM, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_SAVEGAME, "FEM_SL7", SAVESLOT_7, MENUPAGE_SAVE_OVERWRITE_CONFIRM, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_SAVEGAME, "FEM_SL8", SAVESLOT_8, MENUPAGE_SAVE_OVERWRITE_CONFIRM, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_RESUME_FROM_SAVEZONE,"FESZ_CA", SAVESLOT_NONE, 0, 320, 345, MENUALIGN_CENTER,
},
- // MENUPAGE_MULTIPLAYER_MAIN = 21
- { "FET_MP", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
+ // MENUPAGE_SAVE_OVERWRITE_CONFIRM = 16
+ { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, 0,
+ MENUACTION_LABEL, "FESZ_QZ", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0,
+ MENUACTION_NO, "FEM_NO", SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT, 320, 200, MENUALIGN_CENTER,
+ MENUACTION_YES, "FEM_YES", SAVESLOT_NONE, MENUPAGE_SAVING_IN_PROGRESS, 320, 225, MENUALIGN_CENTER,
+ },
+ // MENUPAGE_SAVING_IN_PROGRESS = 17
+ { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, 0,
},
- // MENUPAGE_PS2_SAVE_FAILED = 22
- { "MCDNSP", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
- MENUACTION_MEMCARDSAVECONFIRM, "JAILB_U", SAVESLOT_NONE, MENUPAGE_NONE,
+ // MENUPAGE_SAVE_SUCCESSFUL = 18
+ { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, 0,
+ MENUACTION_LABEL, "FES_SSC", SAVESLOT_LABEL, MENUPAGE_NONE, 0, 0, 0,
+ MENUACTION_RESUME_FROM_SAVEZONE, "FEM_OK", SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT, 320, 225, MENUALIGN_CENTER,
},
- // MENUPAGE_PS2_SAVE_FAILED_2 = 23
- { "MCGNSP", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
- MENUACTION_MEMCARDSAVECONFIRM, "JAILB_U", SAVESLOT_NONE, MENUPAGE_NONE,
+ // MENUPAGE_SAVE_CUSTOM_WARNING = 19
+ { "FET_SG", MENUPAGE_NONE, 0,
+ MENUACTION_LABEL, "", SAVESLOT_NONE, 0, 0, 0, 0,
+ MENUACTION_CHANGEMENU, "FEM_OK", SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT, 320, 225, MENUALIGN_CENTER,
},
- // 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,
+ // MENUPAGE_SAVE_CHEAT_WARNING = 20
+ { "FET_SG", MENUPAGE_NEW_GAME, 0,
+ MENUACTION_LABEL, "FES_CHE", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0,
+ MENUACTION_CHANGEMENU, "FEM_OK", SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT, 320, 225, MENUALIGN_CENTER,
},
-#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,
+
+ // MENUPAGE_SKIN_SELECT = 21
+ { "FET_PS", MENUPAGE_OPTIONS, 4,
+ MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_OPTIONS, 0, 0, 0,
},
-#endif
- // MENUPAGE_NO_MEMORY_CARD_2 = 25
- { "FES_NOC", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
- MENUACTION_CHANGEMENU, "FESZ_CA", SAVESLOT_NONE, MENUPAGE_NONE,
+ // MENUPAGE_SAVE_UNUSED = 22
+ { "FET_SG", MENUPAGE_NEW_GAME, 0,
+ MENUACTION_LABEL, "FED_LWR", SAVESLOT_NONE, 0, 0, 0, 0,
+ MENUACTION_CHANGEMENU, "FEC_OKK", SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT, 0, 0, 0,
},
- // MENUPAGE_CHOOSE_SAVE_SLOT = 26
- { "FET_SG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
- MENUACTION_RESUME_FROM_SAVEZONE, "FESZ_CA", SAVESLOT_NONE, MENUPAGE_NONE,
- MENUACTION_CHANGEMENU, "FEM_SL1", SAVESLOT_1, MENUPAGE_SAVE_OVERWRITE_CONFIRM,
- MENUACTION_CHANGEMENU, "FEM_SL2", SAVESLOT_2, MENUPAGE_SAVE_OVERWRITE_CONFIRM,
- MENUACTION_CHANGEMENU, "FEM_SL3", SAVESLOT_3, MENUPAGE_SAVE_OVERWRITE_CONFIRM,
- MENUACTION_CHANGEMENU, "FEM_SL4", SAVESLOT_4, MENUPAGE_SAVE_OVERWRITE_CONFIRM,
- MENUACTION_CHANGEMENU, "FEM_SL5", SAVESLOT_5, MENUPAGE_SAVE_OVERWRITE_CONFIRM,
- MENUACTION_CHANGEMENU, "FEM_SL6", SAVESLOT_6, MENUPAGE_SAVE_OVERWRITE_CONFIRM,
- MENUACTION_CHANGEMENU, "FEM_SL7", SAVESLOT_7, MENUPAGE_SAVE_OVERWRITE_CONFIRM,
- MENUACTION_CHANGEMENU, "FEM_SL8", SAVESLOT_8, MENUPAGE_SAVE_OVERWRITE_CONFIRM,
+ // MENUPAGE_SAVE_FAILED = 23
+ { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, 0,
+ MENUACTION_LABEL, "FEC_SVU", SAVESLOT_NONE, 0, 0, 0, 0,
+ MENUACTION_CHANGEMENU, "FEC_OKK", SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT, 0, 0, 0,
},
- // MENUPAGE_SAVE_OVERWRITE_CONFIRM = 27
- { "FET_SG", 1, MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, 0, 0,
- MENUACTION_LABEL, "FESZ_QO", SAVESLOT_NONE, MENUPAGE_NONE,
- MENUACTION_CHANGEMENU, "FEM_YES", SAVESLOT_NONE, MENUPAGE_SAVING_IN_PROGRESS,
- MENUACTION_CHANGEMENU, "FEM_NO", SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT,
+ // MENUPAGE_SAVE_FAILED_2 = 24
+ { "FET_LG", MENUPAGE_CHOOSE_SAVE_SLOT, 0,
+ MENUACTION_LABEL, "FEC_SVU", SAVESLOT_NONE, 0, 0, 0, 0,
},
- // MENUPAGE_MULTIPLAYER_MAP = 28
- { "FET_MAP", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
+ // MENUPAGE_LOAD_FAILED = 25
+ { "FET_LG", MENUPAGE_NEW_GAME, 0,
+ MENUACTION_LABEL, "FEC_LUN", SAVESLOT_NONE, 0, 0, 0, 0,
+ MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NEW_GAME, 0, 0, 0,
+ },
+ // MENUPAGE_CONTROLLER_PC = 26
+ { "FET_CTL", MENUPAGE_OPTIONS, 0,
+#ifdef PC_PLAYER_CONTROLS
+ MENUACTION_CTRLMETHOD, "FET_STI", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC, 320, 150, MENUALIGN_CENTER,
+ MENUACTION_KEYBOARDCTRLS,"FEC_RED", SAVESLOT_NONE, MENUPAGE_KEYBOARD_CONTROLS, 0, 0, MENUALIGN_CENTER,
+#else
+ MENUACTION_KEYBOARDCTRLS,"FEC_RED", SAVESLOT_NONE, MENUPAGE_KEYBOARD_CONTROLS, 320, 150, MENUALIGN_CENTER,
+#endif
+ MENUACTION_CHANGEMENU, "FEC_MOU", SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, 0, 0, 0, MENUALIGN_CENTER,
+ },
+
+ // MENUPAGE_OPTIONS = 27
+ { "FET_OPT", MENUPAGE_NONE, 5,
+ MENUACTION_CHANGEMENU, "FEO_CON", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC, 320, 132, MENUALIGN_CENTER,
+ MENUACTION_LOADRADIO, "FEO_AUD", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_CHANGEMENU, "FEO_DIS", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_CHANGEMENU, "FEO_LAN", SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_PLAYERSETUP, "FET_PS", SAVESLOT_NONE, MENUPAGE_SKIN_SELECT, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, 0, 0, 0, MENUALIGN_CENTER,
},
- // MENUPAGE_MULTIPLAYER_CONNECTION = 29
- { "FET_CON", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
+ // MENUPAGE_EXIT = 28
+ { "FET_QG", MENUPAGE_NONE, 6,
+ MENUACTION_LABEL, "FEQ_SRE", SAVESLOT_NONE, 0, 0, 0, 0,
+ MENUACTION_DONTCANCEL, "FEM_NO", SAVESLOT_NONE, MENUPAGE_NONE, 320, 200, MENUALIGN_CENTER,
+ MENUACTION_CANCELGAME, "FEM_YES", SAVESLOT_NONE, MENUPAGE_NONE, 320, 225, MENUALIGN_CENTER,
+ },
+ // MENUPAGE_START_MENU = 29
+ { "FEM_MM", MENUPAGE_DISABLED, 0,
+ MENUACTION_CHANGEMENU, "FEP_STG", SAVESLOT_NONE, MENUPAGE_NEW_GAME, 320, 170, MENUALIGN_CENTER,
+ MENUACTION_CHANGEMENU, "FEP_OPT", SAVESLOT_NONE, MENUPAGE_OPTIONS, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_CHANGEMENU, "FEP_QUI", SAVESLOT_NONE, MENUPAGE_EXIT, 0, 0, MENUALIGN_CENTER,
+ },
+
+ // MENUPAGE_KEYBOARD_CONTROLS = 30
+ { "FET_STI", MENUPAGE_CONTROLLER_PC, 1,
},
- // MENUPAGE_MULTIPLAYER_FIND_GAME = 30
- { "FET_FG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
+ // MENUPAGE_MOUSE_CONTROLS = 31
+ { "FEC_MOU", MENUPAGE_CONTROLLER_PC, 2,
+ MENUACTION_MOUSESENS, "FEC_MSH", SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS, 40, 170, MENUALIGN_LEFT,
+ MENUACTION_INVVERT, "FEC_IVV", SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_MOUSESTEER, "FET_MST", SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, 0, 320, 260, MENUALIGN_CENTER,
+ },
+ // MENUPAGE_PAUSE_MENU = 32
+ { "FET_PAU", MENUPAGE_DISABLED, 0,
+ MENUACTION_RESUME, "FEP_RES", SAVESLOT_NONE, 0, 320, 120, MENUALIGN_CENTER,
+ MENUACTION_CHANGEMENU, "FEH_SGA", SAVESLOT_NONE, MENUPAGE_NEW_GAME, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_CHANGEMENU, "FEH_MAP", SAVESLOT_NONE, MENUPAGE_MAP, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_CHANGEMENU, "FEP_STA", SAVESLOT_NONE, MENUPAGE_STATS, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_CHANGEMENU, "FEH_BRI", SAVESLOT_NONE, MENUPAGE_BRIEFS, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_CHANGEMENU, "FET_OPT", SAVESLOT_NONE, MENUPAGE_OPTIONS, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_CHANGEMENU, "FEP_QUI", SAVESLOT_NONE, MENUPAGE_EXIT, 0, 0, MENUALIGN_CENTER,
},
- // MENUPAGE_MULTIPLAYER_MODE = 31
- { "FET_GT", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
+ // MENUPAGE_NONE = 33
+ { "", 0, 0, },
+#ifdef LEGACY_MENU_OPTIONS
+ // MENUPAGE_DEBUG_MENU
+ { "FED_DBG", MENUPAGE_NONE, 0,
+ MENUACTION_RELOADIDE, "FED_RID", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0,
+ MENUACTION_SETDBGFLAG, "FED_DFL", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0,
+ MENUACTION_SWITCHBIGWHITEDEBUGLIGHT, "FED_DLS", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0,
+ MENUACTION_COLLISIONPOLYS, "FED_SCP", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0,
+ MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0,
+ },
+
+ // MENUPAGE_CONTROLLER_PC_OLD1
+ { "FET_CTL", MENUPAGE_CONTROLLER_PC, 0,
+ MENUACTION_GETKEY, "FEC_PLB", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1, 0, 0, 0,
+ MENUACTION_GETKEY, "FEC_CWL", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1, 0, 0, 0,
+ MENUACTION_GETKEY, "FEC_CWR", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1, 0, 0, 0,
+ MENUACTION_GETKEY, "FEC_LKT", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1, 0, 0, 0,
+ MENUACTION_GETKEY, "FEC_PJP", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1, 0, 0, 0,
+ MENUACTION_GETKEY, "FEC_PSP", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1, 0, 0, 0,
+ MENUACTION_GETKEY, "FEC_TLF", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1, 0, 0, 0,
+ MENUACTION_GETKEY, "FEC_TRG", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1, 0, 0, 0,
+ MENUACTION_GETKEY, "FEC_CCM", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1, 0, 0, 0,
+ MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0,
},
- // MENUPAGE_MULTIPLAYER_CREATE = 32
- { "FET_HG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
+ // MENUPAGE_CONTROLLER_PC_OLD2
+ { "FET_CTL", MENUPAGE_CONTROLLER_PC, 1,
},
- // MENUPAGE_MULTIPLAYER_START = 33
- { "FEN_STA", 2, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
-
+ // MENUPAGE_CONTROLLER_PC_OLD3
+ { "FET_CTL", MENUPAGE_CONTROLLER_PC, 2,
+ MENUACTION_GETKEY, "FEC_LUP", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3, 0, 0, 0,
+ MENUACTION_GETKEY, "FEC_LDN", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3, 0, 0, 0,
+ MENUACTION_GETKEY, "FEC_SMS", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3, 0, 0, 0,
+ MENUACTION_SHOWHEADBOB, "FEC_GSL", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3, 0, 0, 0,
+ MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0,
},
- // MENUPAGE_SKIN_SELECT_OLD = 34
- { "FET_PS", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
+ // MENUPAGE_CONTROLLER_PC_OLD4
+ { "FET_CTL", MENUPAGE_CONTROLLER_PC, 3,
},
- // MENUPAGE_CONTROLLER_PC = 35
- { "FET_CTL", 1, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 0, 0,
-#ifdef PC_PLAYER_CONTROLS
- MENUACTION_CTRLMETHOD, "FET_CME", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC,
+ // MENUPAGE_CONTROLLER_DEBUG
+ { "FEC_DBG", MENUPAGE_CONTROLLER_PC, 3,
+ MENUACTION_GETKEY, "FEC_TGD", SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG, 0, 0, 0,
+ MENUACTION_GETKEY, "FEC_TDO", SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG, 0, 0, 0,
+ MENUACTION_GETKEY, "FEC_TSS", SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG, 0, 0, 0,
+ MENUACTION_GETKEY, "FEC_SMS", SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG, 0, 0, 0,
+ MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0,
+ },
#endif
- MENUACTION_KEYBOARDCTRLS,"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,
- MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
- },
-
- // MENUPAGE_CONTROLLER_PC_OLD1 = 36
- { "FET_CTL", 1, MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, 0, 0,
- MENUACTION_GETKEY, "FEC_PLB", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1,
- MENUACTION_GETKEY, "FEC_CWL", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1,
- MENUACTION_GETKEY, "FEC_CWR", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1,
- MENUACTION_GETKEY, "FEC_LKT", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1,
- MENUACTION_GETKEY, "FEC_PJP", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1,
- MENUACTION_GETKEY, "FEC_PSP", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1,
- MENUACTION_GETKEY, "FEC_TLF", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1,
- MENUACTION_GETKEY, "FEC_TRG", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1,
- MENUACTION_GETKEY, "FEC_CCM", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1,
- MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
- },
-
- // MENUPAGE_CONTROLLER_PC_OLD2 = 37
- { "FET_CTL", 1, MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, 1, 1,
-
- },
-
- // MENUPAGE_CONTROLLER_PC_OLD3 = 38
- { "FET_CTL", 1, MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, 2, 2,
- MENUACTION_GETKEY, "FEC_LUP", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3,
- MENUACTION_GETKEY, "FEC_LDN", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3,
- MENUACTION_GETKEY, "FEC_SMS", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3,
- MENUACTION_SHOWHEADBOB, "FEC_GSL", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3,
- MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
- },
-
- // MENUPAGE_CONTROLLER_PC_OLD4 = 39
- { "FET_CTL", 1, MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, 3, 3,
-
- },
-
- // MENUPAGE_CONTROLLER_DEBUG = 40
- { "FEC_DBG", 1, MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, 3, 3,
- MENUACTION_GETKEY, "FEC_TGD", SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG,
- MENUACTION_GETKEY, "FEC_TDO", SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG,
- MENUACTION_GETKEY, "FEC_TSS", SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG,
- MENUACTION_GETKEY, "FEC_SMS", SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG,
- MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
- },
-
- // MENUPAGE_OPTIONS = 41
- { "FET_OPT", 1, MENUPAGE_NONE, MENUPAGE_NONE, 1, 4,
- MENUACTION_CHANGEMENU, "FET_CTL", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC,
- MENUACTION_LOADRADIO, "FET_AUD", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS,
- MENUACTION_CHANGEMENU, "FET_DIS", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS,
- MENUACTION_CHANGEMENU, "FET_LAN", SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS,
- MENUACTION_PLAYERSETUP, "FET_PSU", SAVESLOT_NONE, MENUPAGE_SKIN_SELECT,
- MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
- },
-
- // MENUPAGE_EXIT = 42
- { "FET_QG", 1, MENUPAGE_NONE, MENUPAGE_NONE, 2, 5,
- MENUACTION_LABEL, "FEQ_SRE", SAVESLOT_NONE, MENUPAGE_NONE,
- MENUACTION_DONTCANCEL, "FEM_NO", SAVESLOT_NONE, MENUPAGE_NONE,
- MENUACTION_CANCELGAME, "FEM_YES", SAVESLOT_NONE, MENUPAGE_NONE,
- },
-
- // MENUPAGE_SAVING_IN_PROGRESS = 43
- { "", 1, MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, 0, 0,
- MENUACTION_LABEL, "FES_WAR", SAVESLOT_NONE, MENUPAGE_NONE,
- },
-
- // MENUPAGE_SAVE_SUCCESSFUL = 44
- { "FET_SG", 1, MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, 0, 0,
- MENUACTION_LABEL, "FES_SSC", SAVESLOT_LABEL, MENUPAGE_NONE,
- MENUACTION_RESUME_FROM_SAVEZONE, "FEC_OKK", SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT,
- },
-
- // MENUPAGE_DELETING = 45
- { "FET_DG", 1, MENUPAGE_CHOOSE_DELETE_SLOT, MENUPAGE_CHOOSE_DELETE_SLOT, 0, 0,
- MENUACTION_LABEL, "FED_DLW", SAVESLOT_NONE, MENUPAGE_NONE,
- },
-
- // MENUPAGE_DELETE_SUCCESS = 46
- { "FET_DG", 1, MENUPAGE_CHOOSE_DELETE_SLOT, MENUPAGE_CHOOSE_DELETE_SLOT, 0, 0,
- MENUACTION_LABEL, "DEL_FNM", SAVESLOT_NONE, MENUPAGE_NONE,
- MENUACTION_CHANGEMENU, "FEC_OKK", SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT,
- },
-
- // MENUPAGE_SAVE_FAILED = 47
- { "FET_SG", 1, MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, 0, 0,
- MENUACTION_LABEL, "FEC_SVU", SAVESLOT_NONE, MENUPAGE_NONE,
- MENUACTION_CHANGEMENU, "FEC_OKK", SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT,
- },
-
- // MENUPAGE_LOAD_FAILED = 48
- { "FET_SG", 1, MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, 0, 0,
- MENUACTION_LABEL, "FEC_SVU", SAVESLOT_NONE, MENUPAGE_NONE,
- },
-
- // MENUPAGE_LOAD_FAILED_2 = 49
- { "FET_LG", 1, MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, 0, 0,
- MENUACTION_LABEL, "FEC_LUN", SAVESLOT_NONE, MENUPAGE_NONE,
- MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT,
- },
-
- // MENUPAGE_FILTER_GAME = 50
- { "FIL_FLT", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
-
- },
-
- // MENUPAGE_START_MENU = 51
- { "FEM_MM", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
- MENUACTION_CHANGEMENU, "FEN_STA", SAVESLOT_NONE, MENUPAGE_NEW_GAME,
- MENUACTION_CHANGEMENU, "FET_OPT", SAVESLOT_NONE, MENUPAGE_OPTIONS,
- MENUACTION_CHANGEMENU, "FEM_QT", SAVESLOT_NONE, MENUPAGE_EXIT,
- },
-
- // MENUPAGE_PAUSE_MENU = 52
- { "FET_PAU", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
- MENUACTION_RESUME, "FEM_RES", SAVESLOT_NONE, MENUPAGE_NONE,
- MENUACTION_CHANGEMENU, "FEN_STA", SAVESLOT_NONE, MENUPAGE_NEW_GAME,
- MENUACTION_CHANGEMENU, "FEP_STA", SAVESLOT_NONE, MENUPAGE_STATS,
- MENUACTION_CHANGEMENU, "FEP_BRI", SAVESLOT_NONE, MENUPAGE_BRIEFS,
- MENUACTION_CHANGEMENU, "FET_OPT", SAVESLOT_NONE, MENUPAGE_OPTIONS,
- MENUACTION_CHANGEMENU, "FEM_QT", SAVESLOT_NONE, MENUPAGE_EXIT,
- },
-
- // MENUPAGE_CHOOSE_MODE = 53
- { "FEN_STA", 1, MENUPAGE_NONE, MENUPAGE_NONE, 0, 1,
- MENUACTION_CHANGEMENU, "FET_SP", SAVESLOT_NONE, MENUPAGE_NEW_GAME,
- MENUACTION_INITMP, "FET_MP", SAVESLOT_NONE, MENUPAGE_MULTIPLAYER_MAIN,
- MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
- },
-
- // MENUPAGE_SKIN_SELECT = 54
- { "FET_PSU", 1, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 4, 4,
- MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_MULTIPLAYER_MAIN,
- },
-
- // MENUPAGE_KEYBOARD_CONTROLS = 55
- { "FET_STI", 1, MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, 1, 1,
- MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC,
- },
-
- // MENUPAGE_MOUSE_CONTROLS = 56
- { "FET_MTI", 1, MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, 2, 2,
- MENUACTION_MOUSESENS, "FEC_MSH", SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS,
- MENUACTION_INVVERT, "FEC_IVV", SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS,
- MENUACTION_MOUSESTEER, "FET_MST", SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS,
- MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
- },
- // MENUPAGE_MISSION_RETRY = 57
+
#ifdef MISSION_REPLAY
+ // MENUPAGE_MISSION_RETRY = 57 on mobile
- { "M_FAIL", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
- MENUACTION_LABEL, "FESZ_RM", SAVESLOT_NONE, MENUPAGE_NONE,
- MENUACTION_CHANGEMENU, "FEM_YES", SAVESLOT_NONE, MENUPAGE_LOADING_IN_PROGRESS,
- MENUACTION_REJECT_RETRY, "FEM_NO", SAVESLOT_NONE, MENUPAGE_NONE
- },
-#else
- { "", 0, MENUPAGE_NONE, MENUPAGE_NONE, 0, 0,
- // mission failed, wanna restart page in mobile
- },
+ { "M_FAIL", MENUPAGE_DISABLED, 0,
+ MENUACTION_LABEL, "FESZ_RM", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0,
+ MENUACTION_CHANGEMENU, "FEM_YES", SAVESLOT_NONE, MENUPAGE_LOADING_IN_PROGRESS, 320, 200, MENUALIGN_CENTER,
+ MENUACTION_REJECT_RETRY, "FEM_NO", SAVESLOT_NONE, MENUPAGE_NONE, 320, 225, MENUALIGN_CENTER,
+ },
#endif
- // MENUPAGE_UNK
- { "", 0, MENUPAGE_NONE, MENUPAGE_NONE, 0, 0,
-
- },
-
+ // MENUPAGE_OUTRO - Originally 34
+ { "", 0, 0, },
};
#endif
diff --git a/src/core/MenuScreensCustom.cpp b/src/core/MenuScreensCustom.cpp
index c22b2e3a..ca3db581 100644
--- a/src/core/MenuScreensCustom.cpp
+++ b/src/core/MenuScreensCustom.cpp
@@ -26,6 +26,7 @@
#include "ModelInfo.h"
#include "Pad.h"
#include "ControllerConfig.h"
+#include "DMAudio.h"
#include "IniFile.h"
#include "CarCtrl.h"
#include "Population.h"
@@ -36,32 +37,32 @@
#ifdef CUSTOM_FRONTEND_OPTIONS
-#ifdef IMPROVED_VIDEOMODE
- #define VIDEOMODE_SELECTOR MENUACTION_CFO_SELECT, "FEM_SCF", { new CCFOSelect((int8*)&FrontEndMenuManager.m_nPrefsWindowed, "VideoMode", "Windowed", screenModes, 2, true, ScreenModeAfterChange, true) },
+#if defined(IMPROVED_VIDEOMODE) && !defined(GTA_HANDHELD)
+ #define VIDEOMODE_SELECTOR MENUACTION_CFO_SELECT, "FEM_SCF", { new CCFOSelect((int8*)&FrontEndMenuManager.m_nPrefsWindowed, "VideoMode", "Windowed", screenModes, 2, true, ScreenModeAfterChange, true) }, 0, 0, MENUALIGN_LEFT,
#else
#define VIDEOMODE_SELECTOR
#endif
#ifdef MULTISAMPLING
- #define MULTISAMPLING_SELECTOR MENUACTION_CFO_DYNAMIC, "FED_AAS", { new CCFODynamic((int8*)&FrontEndMenuManager.m_nPrefsMSAALevel, "Graphics", "MultiSampling", MultiSamplingDraw, MultiSamplingButtonPress) },
+ #define MULTISAMPLING_SELECTOR MENUACTION_CFO_DYNAMIC, "FED_AAS", { new CCFODynamic((int8*)&FrontEndMenuManager.m_nPrefsMSAALevel, "Graphics", "MultiSampling", MultiSamplingDraw, MultiSamplingButtonPress) }, 0, 0, MENUALIGN_LEFT,
#else
#define MULTISAMPLING_SELECTOR
#endif
#ifdef CUTSCENE_BORDERS_SWITCH
- #define CUTSCENE_BORDERS_TOGGLE MENUACTION_CFO_SELECT, "FEM_CSB", { new CCFOSelect((int8 *)&CMenuManager::m_PrefsCutsceneBorders, "Display", "CutsceneBorders", off_on, 2, false) },
+ #define CUTSCENE_BORDERS_TOGGLE MENUACTION_CFO_SELECT, "FEM_CSB", { new CCFOSelect((int8 *)&FrontEndMenuManager.m_PrefsCutsceneBorders, "Display", "CutsceneBorders", off_on, 2, false) }, 0, 0, MENUALIGN_LEFT,
#else
#define CUTSCENE_BORDERS_TOGGLE
#endif
#ifdef FREE_CAM
- #define FREE_CAM_TOGGLE MENUACTION_CFO_SELECT, "FEC_FRC", { new CCFOSelect((int8*)&TheCamera.bFreeCam, "Display", "FreeCam", off_on, 2, false) },
+ #define FREE_CAM_TOGGLE MENUACTION_CFO_SELECT, "FEC_FRC", { new CCFOSelect((int8*)&TheCamera.bFreeCam, "Display", "FreeCam", off_on, 2, false) }, 0, 0, MENUALIGN_LEFT,
#else
#define FREE_CAM_TOGGLE
#endif
#ifdef PS2_ALPHA_TEST
- #define DUALPASS_SELECTOR MENUACTION_CFO_SELECT, "FEM_2PR", { new CCFOSelect((int8*)&gPS2alphaTest, "Graphics", "PS2AlphaTest", off_on, 2, false) },
+ #define DUALPASS_SELECTOR MENUACTION_CFO_SELECT, "FEM_2PR", { new CCFOSelect((int8*)&gPS2alphaTest, "Graphics", "PS2AlphaTest", off_on, 2, false) }, 0, 0, MENUALIGN_LEFT,
#else
#define DUALPASS_SELECTOR
#endif
@@ -69,34 +70,34 @@
#ifdef PED_CAR_DENSITY_SLIDERS
// 0.2f - 3.4f makes it possible to have 1.0f somewhere inbetween
#define DENSITY_SLIDERS \
- MENUACTION_CFO_SLIDER, "FEM_PED", { new CCFOSlider(&CIniFile::PedNumberMultiplier, "Display", "PedDensity", 0.2f, 3.4f, PedDensityChange) }, \
- MENUACTION_CFO_SLIDER, "FEM_CAR", { new CCFOSlider(&CIniFile::CarNumberMultiplier, "Display", "CarDensity", 0.2f, 3.4f, CarDensityChange) },
+ MENUACTION_CFO_SLIDER, "FEM_PED", { new CCFOSlider(&CIniFile::PedNumberMultiplier, "Display", "PedDensity", 0.2f, 3.4f, PedDensityChange) }, 0, 0, MENUALIGN_LEFT, \
+ MENUACTION_CFO_SLIDER, "FEM_CAR", { new CCFOSlider(&CIniFile::CarNumberMultiplier, "Display", "CarDensity", 0.2f, 3.4f, CarDensityChange) }, 0, 0, MENUALIGN_LEFT,
#else
#define DENSITY_SLIDERS
#endif
#ifdef NO_ISLAND_LOADING
- #define ISLAND_LOADING_SELECTOR MENUACTION_CFO_SELECT, "FEM_ISL", { new CCFOSelect((int8*)&CMenuManager::m_PrefsIslandLoading, "Graphics", "IslandLoading", islandLoadingOpts, ARRAY_SIZE(islandLoadingOpts), true, IslandLoadingAfterChange) },
+ #define ISLAND_LOADING_SELECTOR MENUACTION_CFO_SELECT, "FEM_ISL", { new CCFOSelect((int8*)&FrontEndMenuManager.m_PrefsIslandLoading, "Graphics", "IslandLoading", islandLoadingOpts, ARRAY_SIZE(islandLoadingOpts), true, IslandLoadingAfterChange) }, 0, 0, MENUALIGN_LEFT,
#else
#define ISLAND_LOADING_SELECTOR
#endif
#ifdef EXTENDED_COLOURFILTER
#define POSTFX_SELECTORS \
- MENUACTION_CFO_SELECT, "FED_CLF", { new CCFOSelect((int8*)&CPostFX::EffectSwitch, "Graphics", "ColourFilter", filterNames, ARRAY_SIZE(filterNames), false) }, \
- MENUACTION_CFO_SELECT, "FED_MBL", { new CCFOSelect((int8*)&CPostFX::MotionBlurOn, "Graphics", "MotionBlur", off_on, 2, false) },
+ MENUACTION_CFO_SELECT, "FED_CLF", { new CCFOSelect((int8*)&CPostFX::EffectSwitch, "Graphics", "ColourFilter", filterNames, ARRAY_SIZE(filterNames), false) }, 0, 0, MENUALIGN_LEFT, \
+ MENUACTION_CFO_SELECT, "FED_MBL", { new CCFOSelect((int8*)&CPostFX::MotionBlurOn, "Graphics", "MotionBlur", off_on, 2, false) }, 0, 0, MENUALIGN_LEFT,
#else
#define POSTFX_SELECTORS
#endif
#ifdef INVERT_LOOK_FOR_PAD
- #define INVERT_PAD_SELECTOR MENUACTION_CFO_SELECT, "FEC_IVP", { new CCFOSelect((int8*)&CPad::bInvertLook4Pad, "Controller", "InvertPad", off_on, 2, false) },
+ #define INVERT_PAD_SELECTOR MENUACTION_CFO_SELECT, "FEC_ILU", { new CCFOSelect((int8*)&CPad::bInvertLook4Pad, "Controller", "InvertPad", off_on, 2, false) }, 0, 0, MENUALIGN_LEFT,
#else
#define INVERT_PAD_SELECTOR
#endif
#ifdef GAMEPAD_MENU
- #define SELECT_CONTROLLER_TYPE MENUACTION_CFO_SELECT, "FEC_TYP", { new CCFOSelect((int8*)&CMenuManager::m_PrefsControllerType, "Controller", "Type", controllerTypes, ARRAY_SIZE(controllerTypes), false, ControllerTypeAfterChange) },
+ #define SELECT_CONTROLLER_TYPE MENUACTION_CFO_SELECT, "FEC_TYP", { new CCFOSelect((int8*)&FrontEndMenuManager.m_PrefsControllerType, "Controller", "Type", controllerTypes, ARRAY_SIZE(controllerTypes), false, ControllerTypeAfterChange) }, 0, 0, MENUALIGN_LEFT,
#else
#define SELECT_CONTROLLER_TYPE
#endif
@@ -117,32 +118,22 @@ void RestoreDefGraphics(int8 action) {
#ifdef NO_ISLAND_LOADING
if (!FrontEndMenuManager.m_bGameNotLoaded) {
FrontEndMenuManager.m_PrefsIslandLoading = FrontEndMenuManager.ISLAND_LOADING_LOW;
- CCollision::bAlreadyLoaded = false;
- CModelInfo::RemoveColModelsFromOtherLevels(CGame::currLevel);
- CStreaming::RemoveUnusedBigBuildings(CGame::currLevel);
- CStreaming::RemoveUnusedBuildings(CGame::currLevel);
- CStreaming::RequestIslands(CGame::currLevel);
- CStreaming::LoadAllRequestedModels(true);
+ CStreaming::RemoveUnusedBigBuildings(CGame::currLevel);
+ CStreaming::RemoveUnusedBuildings(CGame::currLevel);
+ CStreaming::RequestIslands(CGame::currLevel);
+ CStreaming::LoadAllRequestedModels(true);
} else
FrontEndMenuManager.m_PrefsIslandLoading = FrontEndMenuManager.ISLAND_LOADING_LOW;
#endif
#ifdef GRAPHICS_MENU_OPTIONS // otherwise Frontend will handle those
- CMenuManager::m_PrefsFrameLimiter = true;
- CMenuManager::m_PrefsVsyncDisp = true;
- CMenuManager::m_PrefsVsync = true;
- CMenuManager::m_PrefsUseWideScreen = false;
- FrontEndMenuManager.m_nDisplayVideoMode = FrontEndMenuManager.m_nPrefsVideoMode;
- #if GTA_VERSION >= GTA3_PC_11
- if (_dwOperatingSystemVersion == OS_WIN98) {
- CMBlur::BlurOn = false;
- CMBlur::MotionBlurClose();
- } else {
- CMBlur::BlurOn = true;
- CMBlur::MotionBlurOpen(Scene.camera);
- }
- #else
- CMBlur::BlurOn = true;
+ FrontEndMenuManager.m_PrefsFrameLimiter = true;
+ FrontEndMenuManager.m_PrefsVsyncDisp = true;
+ #ifdef LEGACY_MENU_OPTIONS
+ FrontEndMenuManager.m_PrefsVsync = true;
#endif
+ FrontEndMenuManager.m_PrefsUseWideScreen = false;
+ FrontEndMenuManager.m_nDisplayVideoMode = FrontEndMenuManager.m_nPrefsVideoMode;
+ CMBlur::BlurOn = false;
FrontEndMenuManager.SaveSettings();
#endif
}
@@ -152,7 +143,7 @@ void RestoreDefDisplay(int8 action) {
return;
#ifdef CUTSCENE_BORDERS_SWITCH
- CMenuManager::m_PrefsCutsceneBorders = true;
+ FrontEndMenuManager.m_PrefsCutsceneBorders = true;
#endif
#ifdef FREE_CAM
TheCamera.bFreeCam = false;
@@ -161,10 +152,13 @@ void RestoreDefDisplay(int8 action) {
CIniFile::LoadIniFile();
#endif
#ifdef GRAPHICS_MENU_OPTIONS // otherwise Frontend will handle those
- CMenuManager::m_PrefsBrightness = 256;
- CMenuManager::m_PrefsLOD = 1.2f;
+ FrontEndMenuManager.m_PrefsBrightness = 256;
+ FrontEndMenuManager.m_PrefsLOD = 1.2f;
CRenderer::ms_lodDistScale = 1.2f;
- CMenuManager::m_PrefsShowSubtitles = true;
+ FrontEndMenuManager.m_PrefsShowSubtitles = false;
+ FrontEndMenuManager.m_PrefsShowLegends = true;
+ FrontEndMenuManager.m_PrefsRadarMode = 0;
+ FrontEndMenuManager.m_PrefsShowHud = true;
FrontEndMenuManager.SaveSettings();
#endif
}
@@ -176,16 +170,11 @@ void IslandLoadingAfterChange(int8 before, int8 after) {
if (after > FrontEndMenuManager.ISLAND_LOADING_LOW) {
FrontEndMenuManager.m_PrefsIslandLoading = before; // calls below needs previous mode :shrug:
- if (after == FrontEndMenuManager.ISLAND_LOADING_HIGH)
- CStreaming::RemoveIslandsNotUsed(LEVEL_GENERIC);
+ if (after == FrontEndMenuManager.ISLAND_LOADING_HIGH) {
+ CStreaming::RemoveIslandsNotUsed(LEVEL_BEACH);
+ CStreaming::RemoveIslandsNotUsed(LEVEL_MAINLAND);
+ }
if (before == FrontEndMenuManager.ISLAND_LOADING_LOW) {
- if (CGame::currLevel != LEVEL_INDUSTRIAL)
- CFileLoader::LoadCollisionFromDatFile(LEVEL_INDUSTRIAL);
- if (CGame::currLevel != LEVEL_COMMERCIAL)
- CFileLoader::LoadCollisionFromDatFile(LEVEL_COMMERCIAL);
- if (CGame::currLevel != LEVEL_SUBURBAN)
- CFileLoader::LoadCollisionFromDatFile(LEVEL_SUBURBAN);
- CCollision::bAlreadyLoaded = true;
FrontEndMenuManager.m_PrefsIslandLoading = after;
CStreaming::RequestBigBuildings(CGame::currLevel);
@@ -196,8 +185,6 @@ void IslandLoadingAfterChange(int8 before, int8 after) {
FrontEndMenuManager.m_PrefsIslandLoading = after;
} else { // low
- CCollision::bAlreadyLoaded = false;
- CModelInfo::RemoveColModelsFromOtherLevels(CGame::currLevel);
CStreaming::RemoveUnusedBigBuildings(CGame::currLevel);
CStreaming::RemoveUnusedBuildings(CGame::currLevel);
CStreaming::RequestIslands(CGame::currLevel);
@@ -213,6 +200,7 @@ void IslandLoadingAfterChange(int8 before, int8 after) {
#ifdef PED_CAR_DENSITY_SLIDERS
void PedDensityChange(float before, float after) {
CPopulation::MaxNumberOfPedsInUse = DEFAULT_MAX_NUMBER_OF_PEDS * after;
+ CPopulation::MaxNumberOfPedsInUseInterior = DEFAULT_MAX_NUMBER_OF_PEDS_INTERIOR * after;
}
void CarDensityChange(float before, float after) {
@@ -233,6 +221,8 @@ void MultiSamplingButtonPress(int8 action) {
if (FrontEndMenuManager.m_nDisplayMSAALevel != FrontEndMenuManager.m_nPrefsMSAALevel) {
FrontEndMenuManager.m_nPrefsMSAALevel = FrontEndMenuManager.m_nDisplayMSAALevel;
_psSelectScreenVM(FrontEndMenuManager.m_nPrefsVideoMode);
+ DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND);
+ DMAudio.Service();
FrontEndMenuManager.SetHelperText(0);
FrontEndMenuManager.SaveSettings();
}
@@ -294,6 +284,8 @@ const char* screenModes[] = { "FED_FLS", "FED_WND" };
void ScreenModeAfterChange(int8 before, int8 after)
{
_psSelectScreenVM(FrontEndMenuManager.m_nPrefsVideoMode); // apply same resolution
+ DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND);
+ DMAudio.Service();
FrontEndMenuManager.SetHelperText(0);
}
@@ -388,77 +380,70 @@ void DetectJoystickGoBack() {
#endif
#ifdef GAMEPAD_MENU
-const char* controllerTypes[] = { "FEC_DS2", "FEC_DS3", "FEC_DS4", "FEC_360", "FEC_ONE" };
+const char* controllerTypes[] = { "FEC_DS2", "FEC_DS3", "FEC_DS4", "FEC_360", "FEC_ONE", "FEC_NSW" };
void ControllerTypeAfterChange(int8 before, int8 after)
{
FrontEndMenuManager.LoadController(after);
}
#endif
-CMenuScreenCustom aScreens[MENUPAGES] = {
- // MENUPAGE_NONE = 0
- { "", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil, },
-
- // MENUPAGE_STATS = 1
- { "FET_STA", MENUPAGE_NONE, MENUPAGE_NONE, nil, nil,
- MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
+CMenuScreenCustom aScreens[] = {
+ // MENUPAGE_STATS = 0
+ { "FEH_STA", MENUPAGE_NONE, nil, nil,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 190, 320, MENUALIGN_RIGHT,
},
- // MENUPAGE_NEW_GAME = 2
- { "FET_SGA", MENUPAGE_NONE, MENUPAGE_NONE, nil, nil,
- MENUACTION_CHANGEMENU, "FES_SNG", { nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME_RELOAD },
- MENUACTION_POPULATESLOTS_CHANGEMENU, "GMLOAD", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT },
- MENUACTION_POPULATESLOTS_CHANGEMENU, "FES_DGA", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT },
- MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
+ // MENUPAGE_NEW_GAME = 1
+ { "FEP_STG", MENUPAGE_NONE, nil, nil,
+ MENUACTION_CHANGEMENU, "FES_NGA", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME_RELOAD}, 320, 155, MENUALIGN_CENTER,
+ MENUACTION_CHANGEMENU, "FES_LOA", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT}, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_CHANGEMENU, "FES_DEL", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT}, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, 0}, 0, 0, MENUALIGN_CENTER,
},
- // MENUPAGE_BRIEFS = 3
- { "FET_BRE", MENUPAGE_NONE, MENUPAGE_NONE, nil, nil,
- MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
+ // MENUPAGE_BRIEFS = 2
+ { "FEH_BRI", MENUPAGE_NONE, nil, nil,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 190, 320, MENUALIGN_RIGHT,
},
- // MENUPAGE_CONTROLLER_SETTINGS = 4
-#ifdef GAMEPAD_MENU
- { "FET_AGS", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, nil, nil,
-#else
- { "FET_CON", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, nil, nil,
+ // MENUPAGE_SOUND_SETTINGS = 3
+ { "FEH_AUD", MENUPAGE_OPTIONS, nil, nil,
+ MENUACTION_MUSICVOLUME, "FEA_MUS", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 40, 76, MENUALIGN_LEFT,
+ MENUACTION_SFXVOLUME, "FEA_SFX", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_MP3VOLUMEBOOST, "FEA_MPB", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_LEFT,
+#ifdef EXTERNAL_3D_SOUND
+ MENUACTION_AUDIOHW, "FEA_3DH", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_SPEAKERCONF, "FEA_SPK", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_LEFT,
#endif
- MENUACTION_CTRLCONFIG, "FEC_CCF", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS },
- MENUACTION_CTRLDISPLAY, "FEC_CDP", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS },
- INVERT_PAD_SELECTOR
- MENUACTION_CTRLVIBRATION, "FEC_VIB", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS },
- SELECT_CONTROLLER_TYPE
- MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- },
-
- // MENUPAGE_SOUND_SETTINGS = 5
- { "FET_AUD", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, nil, nil,
- MENUACTION_MUSICVOLUME, "FEA_MUS", { nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS },
- MENUACTION_SFXVOLUME, "FEA_SFX", { nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS },
+ MENUACTION_DYNAMICACOUSTIC, "FET_DAM", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_RADIO, "FEA_RSS", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_LEFT,
#ifdef EXTERNAL_3D_SOUND
- MENUACTION_AUDIOHW, "FEA_3DH", { nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS },
- MENUACTION_SPEAKERCONF, "FEA_SPK", { nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS },
+ MENUACTION_RESTOREDEF, "FET_DEF", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 320, 367, MENUALIGN_CENTER,
+#else
+ MENUACTION_RESTOREDEF, "FET_DEF", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 320, 327, MENUALIGN_CENTER,
#endif
- MENUACTION_DYNAMICACOUSTIC, "FET_DAM", { nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS },
- MENUACTION_RADIO, "FEA_RSS", { nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS },
- MENUACTION_RESTOREDEF, "FET_DEF", { nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS },
- MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, MENUALIGN_CENTER,
},
+ // MENUPAGE_DISPLAY_SETTINGS = 4
#ifndef GRAPHICS_MENU_OPTIONS
- // MENUPAGE_DISPLAY_SETTINGS = 6
- { "FET_DIS", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, nil, nil,
- MENUACTION_BRIGHTNESS, "FED_BRI", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
- MENUACTION_DRAWDIST, "FEM_LOD", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
+ { "FEH_DIS", MENUPAGE_OPTIONS, new CCustomScreenLayout({40, 78, 25, true}), nil,
+ MENUACTION_BRIGHTNESS, "FED_BRI", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_DRAWDIST, "FEM_LOD", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
DENSITY_SLIDERS
- MENUACTION_FRAMESYNC, "FEM_VSC", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
- MENUACTION_FRAMELIMIT, "FEM_FRM", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
-#ifndef EXTENDED_COLOURFILTER
- MENUACTION_TRAILS, "FED_TRA", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
-#endif
- MENUACTION_SUBTITLES, "FED_SUB", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
- MENUACTION_WIDESCREEN, "FED_WIS", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
- MENUACTION_SCREENRES, "FED_RES", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
+#ifdef LEGACY_MENU_OPTIONS
+ MENUACTION_FRAMESYNC, "FEM_VSC", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
+#endif
+ MENUACTION_FRAMELIMIT, "FEM_FRM", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
+#if defined LEGACY_MENU_OPTIONS && !defined EXTENDED_COLOURFILTER
+ MENUACTION_TRAILS, "FED_TRA", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
+#endif
+ MENUACTION_SUBTITLES, "FED_SUB", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_WIDESCREEN, "FED_WIS", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_LEGENDS, "MAP_LEG", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_RADARMODE, "FED_RDR", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_HUD, "FED_HUD", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_SCREENRES, "FED_RES", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
VIDEOMODE_SELECTOR
MULTISAMPLING_SELECTOR
ISLAND_LOADING_SELECTOR
@@ -467,461 +452,367 @@ CMenuScreenCustom aScreens[MENUPAGES] = {
FREE_CAM_TOGGLE
POSTFX_SELECTORS
// re3.cpp inserts here pipeline selectors if neo/neo.txd exists and EXTENDED_PIPELINES defined
- MENUACTION_RESTOREDEF, "FET_DEF", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
- MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
+ MENUACTION_RESTOREDEF, "FET_DEF", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 320, 0, MENUALIGN_CENTER,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 0, MENUALIGN_CENTER,
},
#else
- // MENUPAGE_DISPLAY_SETTINGS = 6
- { "FET_DIS", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, nil, nil,
- MENUACTION_BRIGHTNESS, "FED_BRI", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
- MENUACTION_DRAWDIST, "FEM_LOD", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
+ { "FEH_DIS", MENUPAGE_OPTIONS, new CCustomScreenLayout({40, 78, 25, true}), nil,
+ MENUACTION_BRIGHTNESS, "FED_BRI", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_DRAWDIST, "FEM_LOD", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT,
DENSITY_SLIDERS
CUTSCENE_BORDERS_TOGGLE
FREE_CAM_TOGGLE
- MENUACTION_SUBTITLES, "FED_SUB", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
- MENUACTION_CFO_DYNAMIC, "FET_DEF", { new CCFODynamic(nil, nil, nil, nil, RestoreDefDisplay) },
- MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
+ MENUACTION_LEGENDS, "MAP_LEG", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_RADARMODE, "FED_RDR", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_HUD, "FED_HUD", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_SUBTITLES, "FED_SUB", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_CFO_DYNAMIC, "FET_DEF", { new CCFODynamic(nil, nil, nil, nil, RestoreDefDisplay) }, 320, 0, MENUALIGN_CENTER,
+ MENUACTION_GOBACK, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 0, MENUALIGN_CENTER,
},
#endif
- // MENUPAGE_LANGUAGE_SETTINGS = 7
- { "FET_LAN", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, nil, nil,
- MENUACTION_LANG_ENG, "FEL_ENG", { nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS },
- MENUACTION_LANG_FRE, "FEL_FRE", { nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS },
- MENUACTION_LANG_GER, "FEL_GER", { nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS },
- MENUACTION_LANG_ITA, "FEL_ITA", { nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS },
- MENUACTION_LANG_SPA, "FEL_SPA", { nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS },
- // CustomFrontendOptionsPopulate will add languages here, if files are found
- MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- },
-
- // MENUPAGE_CHOOSE_LOAD_SLOT = 8
- { "FET_LG", MENUPAGE_NEW_GAME, MENUPAGE_NEW_GAME, nil, nil,
- MENUACTION_CHANGEMENU, "FESZ_CA", { nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME },
- MENUACTION_CHECKSAVE, "FEM_SL0", { nil, SAVESLOT_1, MENUPAGE_LOAD_SLOT_CONFIRM },
- MENUACTION_CHECKSAVE, "FEM_SL1", { nil, SAVESLOT_2, MENUPAGE_LOAD_SLOT_CONFIRM },
- MENUACTION_CHECKSAVE, "FEM_SL2", { nil, SAVESLOT_3, MENUPAGE_LOAD_SLOT_CONFIRM },
- MENUACTION_CHECKSAVE, "FEM_SL3", { nil, SAVESLOT_4, MENUPAGE_LOAD_SLOT_CONFIRM },
- MENUACTION_CHECKSAVE, "FEM_SL4", { nil, SAVESLOT_5, MENUPAGE_LOAD_SLOT_CONFIRM },
- MENUACTION_CHECKSAVE, "FEM_SL5", { nil, SAVESLOT_6, MENUPAGE_LOAD_SLOT_CONFIRM },
- MENUACTION_CHECKSAVE, "FEM_SL6", { nil, SAVESLOT_7, MENUPAGE_LOAD_SLOT_CONFIRM },
- MENUACTION_CHECKSAVE, "FEM_SL7", { nil, SAVESLOT_8, MENUPAGE_LOAD_SLOT_CONFIRM },
- },
-
- // MENUPAGE_CHOOSE_DELETE_SLOT = 9
- { "FET_DG", MENUPAGE_NEW_GAME, MENUPAGE_NEW_GAME, nil, nil,
- MENUACTION_CHANGEMENU, "FESZ_CA", { nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME },
- MENUACTION_CHANGEMENU, "FEM_SL0", { nil, SAVESLOT_1, MENUPAGE_DELETE_SLOT_CONFIRM },
- MENUACTION_CHANGEMENU, "FEM_SL1", { nil, SAVESLOT_2, MENUPAGE_DELETE_SLOT_CONFIRM },
- MENUACTION_CHANGEMENU, "FEM_SL2", { nil, SAVESLOT_3, MENUPAGE_DELETE_SLOT_CONFIRM },
- MENUACTION_CHANGEMENU, "FEM_SL3", { nil, SAVESLOT_4, MENUPAGE_DELETE_SLOT_CONFIRM },
- MENUACTION_CHANGEMENU, "FEM_SL4", { nil, SAVESLOT_5, MENUPAGE_DELETE_SLOT_CONFIRM },
- MENUACTION_CHANGEMENU, "FEM_SL5", { nil, SAVESLOT_6, MENUPAGE_DELETE_SLOT_CONFIRM },
- MENUACTION_CHANGEMENU, "FEM_SL6", { nil, SAVESLOT_7, MENUPAGE_DELETE_SLOT_CONFIRM },
- MENUACTION_CHANGEMENU, "FEM_SL7", { nil, SAVESLOT_8, MENUPAGE_DELETE_SLOT_CONFIRM },
- },
-
- // MENUPAGE_NEW_GAME_RELOAD = 10
- { "FET_NG", MENUPAGE_NEW_GAME, MENUPAGE_NEW_GAME, nil, nil,
- MENUACTION_LABEL, "FESZ_QR", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_CHANGEMENU, "FEM_NO", { nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME },
- MENUACTION_NEWGAME, "FEM_YES", { nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME_RELOAD },
- },
-
- // MENUPAGE_LOAD_SLOT_CONFIRM = 11
- { "FET_LG", MENUPAGE_CHOOSE_LOAD_SLOT, MENUPAGE_CHOOSE_LOAD_SLOT, nil, nil,
- MENUACTION_LABEL, "FESZ_QL", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_CHANGEMENU, "FEM_NO", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT },
- MENUACTION_CHANGEMENU, "FEM_YES", { nil, SAVESLOT_NONE, MENUPAGE_LOADING_IN_PROGRESS },
- },
-
- // MENUPAGE_DELETE_SLOT_CONFIRM = 12
- { "FET_DG", MENUPAGE_CHOOSE_DELETE_SLOT, MENUPAGE_CHOOSE_DELETE_SLOT, nil, nil,
- MENUACTION_LABEL, "FESZ_QD", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_CHANGEMENU, "FEM_NO", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT },
- MENUACTION_CHANGEMENU, "FEM_YES", { nil, SAVESLOT_NONE, MENUPAGE_DELETING },
+ // MENUPAGE_LANGUAGE_SETTINGS = 5
+ { "FEH_LAN", MENUPAGE_OPTIONS, nil, nil,
+ MENUACTION_LANG_ENG, "FEL_ENG", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 320, 132, MENUALIGN_CENTER,
+ MENUACTION_LANG_FRE, "FEL_FRE", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_LANG_GER, "FEL_GER", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_LANG_ITA, "FEL_ITA", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_LANG_SPA, "FEL_SPA", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, MENUALIGN_CENTER,
},
- // MENUPAGE_NO_MEMORY_CARD = 13
- { "FES_NOC", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
- // hud adjustment page in mobile
+ // MENUPAGE_MAP = 6
+ { "FEH_MAP", MENUPAGE_NONE, nil, nil,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 70, 380, MENUALIGN_CENTER,
},
- // MENUPAGE_LOADING_IN_PROGRESS = 14
- { "FET_LG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
- MENUACTION_LABEL, "FED_LDW", { nil, SAVESLOT_NONE, MENUPAGE_LOAD_SLOT_CONFIRM },
+ // MENUPAGE_NEW_GAME_RELOAD = 7
+ { "FES_NGA", MENUPAGE_NEW_GAME, nil, nil,
+ MENUACTION_LABEL, "FESZ_QR", {nil, SAVESLOT_NONE, 0}, 0, 0, 0,
+ MENUACTION_NO, "FEM_NO", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME}, 320, 200, MENUALIGN_CENTER,
+ MENUACTION_NEWGAME, "FEM_YES", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME_RELOAD}, 320, 225, MENUALIGN_CENTER,
},
- // MENUPAGE_DELETING_IN_PROGRESS = 15
- { "FET_DG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
- MENUACTION_LABEL, "FEDL_WR", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
+ // MENUPAGE_CHOOSE_LOAD_SLOT = 8
+ { "FET_LG", MENUPAGE_NEW_GAME, nil, nil,
+ MENUACTION_CHECKSAVE, "FEM_SL1", {nil, SAVESLOT_1, 0}, 40, 90, MENUALIGN_LEFT,
+ MENUACTION_CHECKSAVE, "FEM_SL2", {nil, SAVESLOT_2, 0}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_CHECKSAVE, "FEM_SL3", {nil, SAVESLOT_3, 0}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_CHECKSAVE, "FEM_SL4", {nil, SAVESLOT_4, 0}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_CHECKSAVE, "FEM_SL5", {nil, SAVESLOT_5, 0}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_CHECKSAVE, "FEM_SL6", {nil, SAVESLOT_6, 0}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_CHECKSAVE, "FEM_SL7", {nil, SAVESLOT_7, 0}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_CHECKSAVE, "FEM_SL8", {nil, SAVESLOT_8, 0}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, 0}, 320, 345, MENUALIGN_CENTER,
},
- // MENUPAGE_PS2_LOAD_FAILED = 16
- { "FET_LG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
- MENUACTION_LABEL, "FES_LOE", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
+ // MENUPAGE_CHOOSE_DELETE_SLOT = 9
+ { "FES_DEL", MENUPAGE_NEW_GAME, nil, nil,
+ MENUACTION_CHECKSAVE, "FEM_SL1", {nil, SAVESLOT_1, 0}, 40, 90, MENUALIGN_LEFT,
+ MENUACTION_CHECKSAVE, "FEM_SL2", {nil, SAVESLOT_2, 0}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_CHECKSAVE, "FEM_SL3", {nil, SAVESLOT_3, 0}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_CHECKSAVE, "FEM_SL4", {nil, SAVESLOT_4, 0}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_CHECKSAVE, "FEM_SL5", {nil, SAVESLOT_5, 0}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_CHECKSAVE, "FEM_SL6", {nil, SAVESLOT_6, 0}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_CHECKSAVE, "FEM_SL7", {nil, SAVESLOT_7, 0}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_CHECKSAVE, "FEM_SL8", {nil, SAVESLOT_8, 0}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, 0}, 320, 345, MENUALIGN_CENTER,
},
- // MENUPAGE_DELETE_FAILED = 17
- { "FET_DG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
- MENUACTION_LABEL, "FES_DEE", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_CHANGEMENU, "FEC_OKK", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT },
+ // MENUPAGE_LOAD_SLOT_CONFIRM = 10
+ { "FET_LG", MENUPAGE_CHOOSE_LOAD_SLOT, nil, nil,
+ MENUACTION_LABEL, "FESZ_QL", {nil, SAVESLOT_NONE, 0}, 0, 0, 0,
+ MENUACTION_NO, "FEM_NO", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT}, 320, 200, MENUALIGN_CENTER,
+ MENUACTION_YES, "FEM_YES", {nil, SAVESLOT_NONE, MENUPAGE_LOADING_IN_PROGRESS}, 320, 225, MENUALIGN_CENTER,
},
- // MENUPAGE_DEBUG_MENU = 18
- { "FED_DBG", MENUPAGE_NONE, MENUPAGE_NONE, nil, nil,
- MENUACTION_RELOADIDE, "FED_RID", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_RELOADIPL, "FED_RIP", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_SETDBGFLAG, "FED_DFL", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_SWITCHBIGWHITEDEBUGLIGHT, "FED_DLS", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_PEDROADGROUPS, "FED_SPR", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_CARROADGROUPS, "FED_SCR", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_COLLISIONPOLYS, "FED_SCP", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_PARSEHEAP, "FED_PAH", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_SHOWCULL, "FED_SCZ", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_DEBUGSTREAM, "FED_DSR", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
+ // MENUPAGE_DELETE_SLOT_CONFIRM = 11
+ { "FES_DEL", MENUPAGE_CHOOSE_DELETE_SLOT, nil, nil,
+ MENUACTION_LABEL, "FESZ_QD", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0,
+ MENUACTION_NO, "FEM_NO", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT}, 320, 200, MENUALIGN_CENTER,
+ MENUACTION_YES, "FEM_YES", {nil, SAVESLOT_NONE, MENUPAGE_DELETING_IN_PROGRESS}, 320, 225, MENUALIGN_CENTER,
},
- // MENUPAGE_MEMORY_CARD_DEBUG = 19
- { "FEM_MCM", MENUPAGE_NONE, MENUPAGE_NONE, nil, nil,
- MENUACTION_REGMEMCARD1, "FEM_RMC", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_TESTFORMATMEMCARD1, "FEM_TFM", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_TESTUNFORMATMEMCARD1, "FEM_TUM", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_CREATEROOTDIR, "FEM_CRD", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_CREATELOADICONS, "FEM_CLI", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_FILLWITHGUFF, "FEM_FFF", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_SAVEONLYTHEGAME, "FEM_SOG", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_SAVEGAME, "FEM_STG", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_SAVEGAMEUNDERGTA, "FEM_STS", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_CREATECOPYPROTECTED, "FEM_CPD", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
+ // MENUPAGE_LOADING_IN_PROGRESS = 12
+ { "FET_LG", MENUPAGE_CHOOSE_LOAD_SLOT, nil, nil,
},
- // MENUPAGE_MEMORY_CARD_TEST = 20
- { "FEM_MC2", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
-
+ // MENUPAGE_DELETING_IN_PROGRESS = 13
+ { "FES_DEL", MENUPAGE_CHOOSE_DELETE_SLOT, nil, nil,
},
- // MENUPAGE_MULTIPLAYER_MAIN = 21
- { "FET_MP", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
-
+ // MENUPAGE_DELETE_SUCCESSFUL = 14
+ { "FES_DEL", MENUPAGE_NEW_GAME, nil, nil,
+ MENUACTION_LABEL, "FES_DSC", {nil, SAVESLOT_NONE, 0}, 0, 0, 0,
+ MENUACTION_CHANGEMENU, "FEM_OK", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME}, 320, 225, MENUALIGN_CENTER,
},
- // MENUPAGE_PS2_SAVE_FAILED = 22
- { "MCDNSP", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
- MENUACTION_MEMCARDSAVECONFIRM, "JAILB_U", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
+ // MENUPAGE_CHOOSE_SAVE_SLOT = 15
+ { "FET_SG", MENUPAGE_DISABLED, nil, nil,
+ MENUACTION_SAVEGAME, "FEM_SL1", {nil, SAVESLOT_1, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 40, 90, MENUALIGN_LEFT,
+ MENUACTION_SAVEGAME, "FEM_SL2", {nil, SAVESLOT_2, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_SAVEGAME, "FEM_SL3", {nil, SAVESLOT_3, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_SAVEGAME, "FEM_SL4", {nil, SAVESLOT_4, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_SAVEGAME, "FEM_SL5", {nil, SAVESLOT_5, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_SAVEGAME, "FEM_SL6", {nil, SAVESLOT_6, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_SAVEGAME, "FEM_SL7", {nil, SAVESLOT_7, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_SAVEGAME, "FEM_SL8", {nil, SAVESLOT_8, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_RESUME_FROM_SAVEZONE,"FESZ_CA", {nil, SAVESLOT_NONE, 0}, 320, 345, MENUALIGN_CENTER,
},
- // MENUPAGE_PS2_SAVE_FAILED_2 = 23
- { "MCGNSP", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
- MENUACTION_MEMCARDSAVECONFIRM, "JAILB_U", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
+ // MENUPAGE_SAVE_OVERWRITE_CONFIRM = 16
+ { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
+ MENUACTION_LABEL, "FESZ_QZ", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0,
+ MENUACTION_NO, "FEM_NO", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT}, 320, 200, MENUALIGN_CENTER,
+ MENUACTION_YES, "FEM_YES", {nil, SAVESLOT_NONE, MENUPAGE_SAVING_IN_PROGRESS}, 320, 225, MENUALIGN_CENTER,
},
- // Unused in PC but anyway
- // MENUPAGE_SAVE = 24
-#ifdef PS2_SAVE_DIALOG
- { "FET_SG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
- MENUACTION_CHANGEMENU, "FESZ_SA", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT },
- MENUACTION_RESUME_FROM_SAVEZONE, "FESZ_CA", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- },
-#else
- { "FET_SG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
- MENUACTION_LABEL, "FES_SCG", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_POPULATESLOTS_CHANGEMENU, "GMSAVE", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT },
- MENUACTION_RESUME_FROM_SAVEZONE, "FESZ_CA", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- },
-#endif
-
- // MENUPAGE_NO_MEMORY_CARD_2 = 25
- { "FES_NOC", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
- MENUACTION_CHANGEMENU, "FESZ_CA", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
+ // MENUPAGE_SAVING_IN_PROGRESS = 17
+ { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
},
- // MENUPAGE_CHOOSE_SAVE_SLOT = 26
- { "FET_SG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
- MENUACTION_RESUME_FROM_SAVEZONE, "FESZ_CA", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_CHANGEMENU, "FEM_SL1", { nil, SAVESLOT_1, MENUPAGE_SAVE_OVERWRITE_CONFIRM },
- MENUACTION_CHANGEMENU, "FEM_SL2", { nil, SAVESLOT_2, MENUPAGE_SAVE_OVERWRITE_CONFIRM },
- MENUACTION_CHANGEMENU, "FEM_SL3", { nil, SAVESLOT_3, MENUPAGE_SAVE_OVERWRITE_CONFIRM },
- MENUACTION_CHANGEMENU, "FEM_SL4", { nil, SAVESLOT_4, MENUPAGE_SAVE_OVERWRITE_CONFIRM },
- MENUACTION_CHANGEMENU, "FEM_SL5", { nil, SAVESLOT_5, MENUPAGE_SAVE_OVERWRITE_CONFIRM },
- MENUACTION_CHANGEMENU, "FEM_SL6", { nil, SAVESLOT_6, MENUPAGE_SAVE_OVERWRITE_CONFIRM },
- MENUACTION_CHANGEMENU, "FEM_SL7", { nil, SAVESLOT_7, MENUPAGE_SAVE_OVERWRITE_CONFIRM },
- MENUACTION_CHANGEMENU, "FEM_SL8", { nil, SAVESLOT_8, MENUPAGE_SAVE_OVERWRITE_CONFIRM },
+ // MENUPAGE_SAVE_SUCCESSFUL = 18
+ { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
+ MENUACTION_LABEL, "FES_SSC", {nil, SAVESLOT_LABEL, MENUPAGE_NONE}, 0, 0, 0,
+ MENUACTION_RESUME_FROM_SAVEZONE, "FEM_OK", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT}, 320, 225, MENUALIGN_CENTER,
},
- // MENUPAGE_SAVE_OVERWRITE_CONFIRM = 27
- { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
- MENUACTION_LABEL, "FESZ_QO", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_CHANGEMENU, "FEM_YES", { nil, SAVESLOT_NONE, MENUPAGE_SAVING_IN_PROGRESS },
- MENUACTION_CHANGEMENU, "FEM_NO", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT },
- },
-
- // MENUPAGE_MULTIPLAYER_MAP = 28
- { "FET_MAP", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
-
+ // MENUPAGE_SAVE_CUSTOM_WARNING = 19
+ { "FET_SG", MENUPAGE_NONE, nil, nil,
+ MENUACTION_LABEL, "", {nil, SAVESLOT_NONE, 0}, 0, 0, 0,
+ MENUACTION_CHANGEMENU, "FEM_OK", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT}, 320, 225, MENUALIGN_CENTER,
},
- // MENUPAGE_MULTIPLAYER_CONNECTION = 29
- { "FET_CON", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
-
+ // MENUPAGE_SAVE_CHEAT_WARNING = 20
+ { "FET_SG", MENUPAGE_NEW_GAME, nil, nil,
+ MENUACTION_LABEL, "FES_CHE", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0,
+ MENUACTION_CHANGEMENU, "FEM_OK", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT}, 320, 225, MENUALIGN_CENTER,
},
- // MENUPAGE_MULTIPLAYER_FIND_GAME = 30
- { "FET_FG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
-
+ // MENUPAGE_SKIN_SELECT = 21
+ { "FET_PS", MENUPAGE_OPTIONS, nil, nil,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_OPTIONS}, 0, 0, 0,
},
- // MENUPAGE_MULTIPLAYER_MODE = 31
- { "FET_GT", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
-
+ // MENUPAGE_SAVE_UNUSED = 22
+ { "FET_SG", MENUPAGE_NEW_GAME, nil, nil,
+ MENUACTION_LABEL, "FED_LWR", {nil, SAVESLOT_NONE, 0}, 0, 0, 0,
+ MENUACTION_CHANGEMENU, "FEC_OKK", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT}, 0, 0, 0,
},
- // MENUPAGE_MULTIPLAYER_CREATE = 32
- { "FET_HG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
-
+ // MENUPAGE_SAVE_FAILED = 23
+ { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
+ MENUACTION_LABEL, "FEC_SVU", {nil, SAVESLOT_NONE, 0}, 0, 0, 0,
+ MENUACTION_CHANGEMENU, "FEC_OKK", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT}, 0, 0, 0,
},
- // MENUPAGE_MULTIPLAYER_START = 33
- { "FEN_STA", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
-
+ // MENUPAGE_SAVE_FAILED_2 = 24
+ { "FET_LG", MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
+ MENUACTION_LABEL, "FEC_SVU", {nil, SAVESLOT_NONE, 0}, 0, 0, 0,
},
- // MENUPAGE_SKIN_SELECT_OLD = 34
- { "FET_PS", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
-
+ // MENUPAGE_LOAD_FAILED = 25
+ { "FET_LG", MENUPAGE_NEW_GAME, nil, nil,
+ MENUACTION_LABEL, "FEC_LUN", {nil, SAVESLOT_NONE, 0}, 0, 0, 0,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME}, 0, 0, 0,
},
- // MENUPAGE_CONTROLLER_PC = 35
- { "FET_CTL", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, nil, nil,
+ // MENUPAGE_CONTROLLER_PC = 26
+ { "FET_CTL", MENUPAGE_OPTIONS, new CCustomScreenLayout({0, 0, MENU_DEFAULT_LINE_HEIGHT, false, false, 150}), nil,
#ifdef PC_PLAYER_CONTROLS
- MENUACTION_CTRLMETHOD, "FET_CME", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC },
+ MENUACTION_CTRLMETHOD, "FET_STI", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC}, 320, 150, MENUALIGN_CENTER,
+ MENUACTION_KEYBOARDCTRLS,"FEC_RED", {nil, SAVESLOT_NONE, MENUPAGE_KEYBOARD_CONTROLS}, 0, 0, MENUALIGN_CENTER,
+#else
+ MENUACTION_KEYBOARDCTRLS,"FEC_RED", {nil, SAVESLOT_NONE, MENUPAGE_KEYBOARD_CONTROLS}, 320, 150, MENUALIGN_CENTER,
#endif
- MENUACTION_KEYBOARDCTRLS,"FET_RDK", { nil, SAVESLOT_NONE, MENUPAGE_KEYBOARD_CONTROLS },
#ifdef GAMEPAD_MENU
- MENUACTION_CHANGEMENU, "FET_AGS", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS },
+ MENUACTION_CHANGEMENU, "FET_AGS", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS}, 0, 0, MENUALIGN_CENTER,
#endif
#ifdef DETECT_JOYSTICK_MENU
- MENUACTION_CHANGEMENU, "FEC_JOD", { nil, SAVESLOT_NONE, MENUPAGE_DETECT_JOYSTICK },
+ MENUACTION_CHANGEMENU, "FEC_JOD", {nil, SAVESLOT_NONE, MENUPAGE_DETECT_JOYSTICK}, 0, 0, MENUALIGN_CENTER,
#endif
- MENUACTION_CHANGEMENU, "FET_AMS", { nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS },
- MENUACTION_RESTOREDEF, "FET_DEF", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC },
- MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- },
-
- // MENUPAGE_CONTROLLER_PC_OLD1 = 36
- { "FET_CTL", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, nil, nil,
- MENUACTION_GETKEY, "FEC_PLB", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1 },
- MENUACTION_GETKEY, "FEC_CWL", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1 },
- MENUACTION_GETKEY, "FEC_CWR", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1 },
- MENUACTION_GETKEY, "FEC_LKT", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1 },
- MENUACTION_GETKEY, "FEC_PJP", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1 },
- MENUACTION_GETKEY, "FEC_PSP", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1 },
- MENUACTION_GETKEY, "FEC_TLF", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1 },
- MENUACTION_GETKEY, "FEC_TRG", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1 },
- MENUACTION_GETKEY, "FEC_CCM", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1 },
- MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- },
-
- // MENUPAGE_CONTROLLER_PC_OLD2 = 37
- { "FET_CTL", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, nil, nil,
-
- },
-
- // MENUPAGE_CONTROLLER_PC_OLD3 = 38
- { "FET_CTL", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, nil, nil,
- MENUACTION_GETKEY, "FEC_LUP", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3 },
- MENUACTION_GETKEY, "FEC_LDN", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3 },
- MENUACTION_GETKEY, "FEC_SMS", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3 },
- MENUACTION_SHOWHEADBOB, "FEC_GSL", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3 },
- MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- },
-
- // MENUPAGE_CONTROLLER_PC_OLD4 = 39
- { "FET_CTL", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, nil, nil,
-
+ MENUACTION_CHANGEMENU, "FEC_MOU", {nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS}, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_RESTOREDEF, "FET_DEF", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC}, 320, 0, MENUALIGN_CENTER,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, 0}, 320, 0, MENUALIGN_CENTER,
},
- // MENUPAGE_CONTROLLER_DEBUG = 40
- { "FEC_DBG", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, nil, nil,
- MENUACTION_GETKEY, "FEC_TGD", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG },
- MENUACTION_GETKEY, "FEC_TDO", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG },
- MENUACTION_GETKEY, "FEC_TSS", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG },
- MENUACTION_GETKEY, "FEC_SMS", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG },
- MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- },
-
- // MENUPAGE_OPTIONS = 41
- { "FET_OPT", MENUPAGE_NONE, MENUPAGE_NONE, nil, nil,
- MENUACTION_CHANGEMENU, "FET_CTL", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC },
- MENUACTION_LOADRADIO, "FET_AUD", { nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS },
- MENUACTION_CHANGEMENU, "FET_DIS", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
+ // MENUPAGE_OPTIONS = 27
+ { "FET_OPT", MENUPAGE_NONE, nil, nil,
+#ifdef GTA_HANDHELD
+ MENUACTION_CHANGEMENU, "FEO_CON", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS}, 320, 132, MENUALIGN_CENTER,
+#else
+ MENUACTION_CHANGEMENU, "FEO_CON", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC}, 320, 132, MENUALIGN_CENTER,
+#endif
+ MENUACTION_LOADRADIO, "FEO_AUD", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_CHANGEMENU, "FEO_DIS", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_CENTER,
#ifdef GRAPHICS_MENU_OPTIONS
- MENUACTION_CHANGEMENU, "FET_GFX", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS },
+ MENUACTION_CHANGEMENU, "FET_GFX", {nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS}, 0, 0, MENUALIGN_CENTER,
#endif
- MENUACTION_CHANGEMENU, "FET_LAN", { nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS },
- MENUACTION_PLAYERSETUP, "FET_PSU", { nil, SAVESLOT_NONE, MENUPAGE_SKIN_SELECT },
- MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- },
-
- // MENUPAGE_EXIT = 42
- { "FET_QG", MENUPAGE_NONE, MENUPAGE_NONE, nil, nil,
- MENUACTION_LABEL, "FEQ_SRE", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_DONTCANCEL, "FEM_NO", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_CANCELGAME, "FEM_YES", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
+ MENUACTION_CHANGEMENU, "FEO_LAN", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_PLAYERSETUP, "FET_PS", {nil, SAVESLOT_NONE, MENUPAGE_SKIN_SELECT}, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, 0}, 0, 0, MENUALIGN_CENTER,
},
- // MENUPAGE_SAVING_IN_PROGRESS = 43
- { "", MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
- MENUACTION_LABEL, "FES_WAR", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
+ // MENUPAGE_EXIT = 28
+ { "FET_QG", MENUPAGE_NONE, nil, nil,
+ MENUACTION_LABEL, "FEQ_SRE", {nil, SAVESLOT_NONE, 0}, 0, 0, 0,
+ MENUACTION_DONTCANCEL, "FEM_NO", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 200, MENUALIGN_CENTER,
+ MENUACTION_CANCELGAME, "FEM_YES", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 225, MENUALIGN_CENTER,
},
- // MENUPAGE_SAVE_SUCCESSFUL = 44
- { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
- MENUACTION_LABEL, "FES_SSC", { nil, SAVESLOT_LABEL, MENUPAGE_NONE },
- MENUACTION_RESUME_FROM_SAVEZONE, "FEC_OKK", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT },
+ // MENUPAGE_START_MENU = 29
+ { "FEM_MM", MENUPAGE_DISABLED, nil, nil,
+ MENUACTION_CHANGEMENU, "FEP_STG", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME}, 320, 170, MENUALIGN_CENTER,
+ MENUACTION_CHANGEMENU, "FEP_OPT", {nil, SAVESLOT_NONE, MENUPAGE_OPTIONS}, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_CHANGEMENU, "FEP_QUI", {nil, SAVESLOT_NONE, MENUPAGE_EXIT}, 0, 0, MENUALIGN_CENTER,
},
- // MENUPAGE_DELETING = 45
- { "FET_DG", MENUPAGE_CHOOSE_DELETE_SLOT, MENUPAGE_CHOOSE_DELETE_SLOT, nil, nil,
- MENUACTION_LABEL, "FED_DLW", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
+ // MENUPAGE_KEYBOARD_CONTROLS = 30
+ { "FET_STI", MENUPAGE_CONTROLLER_PC, nil, nil,
},
- // MENUPAGE_DELETE_SUCCESS = 46
- { "FET_DG", MENUPAGE_CHOOSE_DELETE_SLOT, MENUPAGE_CHOOSE_DELETE_SLOT, nil, nil,
- MENUACTION_LABEL, "DEL_FNM", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_CHANGEMENU, "FEC_OKK", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT },
- },
-
- // MENUPAGE_SAVE_FAILED = 47
- { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
- MENUACTION_LABEL, "FEC_SVU", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_CHANGEMENU, "FEC_OKK", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT },
- },
-
- // MENUPAGE_LOAD_FAILED = 48
- { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
- MENUACTION_LABEL, "FEC_SVU", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
+ // MENUPAGE_MOUSE_CONTROLS = 31
+ { "FEC_MOU", MENUPAGE_CONTROLLER_PC, nil, nil,
+ MENUACTION_MOUSESENS, "FEC_MSH", {nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS}, 40, 170, MENUALIGN_LEFT,
+ MENUACTION_INVVERT, "FEC_IVV", {nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS}, 0, 0, MENUALIGN_LEFT,
+#ifndef GAMEPAD_MENU
+ INVERT_PAD_SELECTOR
+#endif
+ MENUACTION_MOUSESTEER, "FET_MST", {nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, 0}, 320, 0, MENUALIGN_CENTER,
+ //MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, 0}, 320, 260, MENUALIGN_CENTER, // original y
},
- // MENUPAGE_LOAD_FAILED_2 = 49
- { "FET_LG", MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
- MENUACTION_LABEL, "FEC_LUN", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT },
+ // MENUPAGE_PAUSE_MENU = 32
+ { "FET_PAU", MENUPAGE_DISABLED, nil, nil,
+ MENUACTION_RESUME, "FEP_RES", {nil, SAVESLOT_NONE, 0}, 320, 120, MENUALIGN_CENTER,
+ MENUACTION_CHANGEMENU, "FEH_SGA", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME}, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_CHANGEMENU, "FEH_MAP", {nil, SAVESLOT_NONE, MENUPAGE_MAP}, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_CHANGEMENU, "FEP_STA", {nil, SAVESLOT_NONE, MENUPAGE_STATS}, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_CHANGEMENU, "FEH_BRI", {nil, SAVESLOT_NONE, MENUPAGE_BRIEFS}, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_CHANGEMENU, "FET_OPT", {nil, SAVESLOT_NONE, MENUPAGE_OPTIONS}, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_CHANGEMENU, "FEP_QUI", {nil, SAVESLOT_NONE, MENUPAGE_EXIT}, 0, 0, MENUALIGN_CENTER,
},
- // MENUPAGE_FILTER_GAME = 50
- { "FIL_FLT", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
+ // MENUPAGE_NONE = 33
+ { "", 0, nil, nil, },
+#ifdef GAMEPAD_MENU
+#ifdef GTA_HANDHELD
+ { "FET_AGS", MENUPAGE_OPTIONS, new CCustomScreenLayout({40, 78, 25, true, true}), nil,
+#else
+ { "FET_AGS", MENUPAGE_CONTROLLER_PC, new CCustomScreenLayout({40, 78, 25, true, true}), nil,
+#endif
+ MENUACTION_CTRLCONFIG, "FEC_CCF", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS }, 40, 76, MENUALIGN_LEFT,
+ MENUACTION_CTRLDISPLAY, "FEC_CDP", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS }, 0, 0, MENUALIGN_LEFT,
+ INVERT_PAD_SELECTOR
+ MENUACTION_CTRLVIBRATION, "FEC_VIB", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS }, 0, 0, MENUALIGN_LEFT,
+ SELECT_CONTROLLER_TYPE
+ MENUACTION_GOBACK, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE }, 0, 0, MENUALIGN_LEFT,
+ },
+#endif
+#ifdef LEGACY_MENU_OPTIONS
+ // MENUPAGE_DEBUG_MENU = 18
+ { "FED_DBG", MENUPAGE_NONE, nil, nil,
+ MENUACTION_RELOADIDE, "FED_RID", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0,
+ MENUACTION_SETDBGFLAG, "FED_DFL", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0,
+ MENUACTION_SWITCHBIGWHITEDEBUGLIGHT, "FED_DLS", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0,
+ MENUACTION_COLLISIONPOLYS, "FED_SCP", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0,
},
- // MENUPAGE_START_MENU = 51
- { "FEM_MM", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
- MENUACTION_CHANGEMENU, "FEN_STA", { nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME },
- MENUACTION_CHANGEMENU, "FET_OPT", { nil, SAVESLOT_NONE, MENUPAGE_OPTIONS },
- MENUACTION_CHANGEMENU, "FEM_QT", { nil, SAVESLOT_NONE, MENUPAGE_EXIT },
- },
-
- // MENUPAGE_PAUSE_MENU = 52
- { "FET_PAU", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
- MENUACTION_RESUME, "FEM_RES", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_CHANGEMENU, "FEN_STA", { nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME },
- // CMenuManager::LoadAllTextures will add map here, if MENU_MAP enabled and map textures are found
- MENUACTION_CHANGEMENU, "FEP_STA", { nil, SAVESLOT_NONE, MENUPAGE_STATS },
- MENUACTION_CHANGEMENU, "FEP_BRI", { nil, SAVESLOT_NONE, MENUPAGE_BRIEFS },
- MENUACTION_CHANGEMENU, "FET_OPT", { nil, SAVESLOT_NONE, MENUPAGE_OPTIONS },
- MENUACTION_CHANGEMENU, "FEM_QT", { nil, SAVESLOT_NONE, MENUPAGE_EXIT },
+ // MENUPAGE_CONTROLLER_PC_OLD1 = 36
+ { "FET_CTL", MENUPAGE_CONTROLLER_PC, nil, nil,
+ MENUACTION_GETKEY, "FEC_PLB", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0,
+ MENUACTION_GETKEY, "FEC_CWL", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0,
+ MENUACTION_GETKEY, "FEC_CWR", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0,
+ MENUACTION_GETKEY, "FEC_LKT", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0,
+ MENUACTION_GETKEY, "FEC_PJP", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0,
+ MENUACTION_GETKEY, "FEC_PSP", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0,
+ MENUACTION_GETKEY, "FEC_TLF", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0,
+ MENUACTION_GETKEY, "FEC_TRG", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0,
+ MENUACTION_GETKEY, "FEC_CCM", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0,
},
- // MENUPAGE_CHOOSE_MODE = 53
- { "FEN_STA", MENUPAGE_NONE, MENUPAGE_NONE, nil, nil,
- MENUACTION_CHANGEMENU, "FET_SP", { nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME },
- MENUACTION_INITMP, "FET_MP", { nil, SAVESLOT_NONE, MENUPAGE_MULTIPLAYER_MAIN },
- MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- },
+ // MENUPAGE_CONTROLLER_PC_OLD2 = 37
+ { "FET_CTL", MENUPAGE_CONTROLLER_PC, nil, nil,
- // MENUPAGE_SKIN_SELECT = 54
- { "FET_PSU", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, nil, nil,
- MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_MULTIPLAYER_MAIN },
- },
+ },
- // MENUPAGE_KEYBOARD_CONTROLS = 55
- { "FET_STI", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, nil, nil,
- MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC },
+ // MENUPAGE_CONTROLLER_PC_OLD3 = 38
+ { "FET_CTL", MENUPAGE_CONTROLLER_PC, nil, nil,
+ MENUACTION_GETKEY, "FEC_LUP", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3}, 0, 0, 0,
+ MENUACTION_GETKEY, "FEC_LDN", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3}, 0, 0, 0,
+ MENUACTION_GETKEY, "FEC_SMS", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3}, 0, 0, 0,
+ MENUACTION_SHOWHEADBOB, "FEC_GSL", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3}, 0, 0, 0,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0,
},
- // MENUPAGE_MOUSE_CONTROLS = 56
- { "FET_MTI", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, nil, nil,
- MENUACTION_MOUSESENS, "FEC_MSH", { nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS },
- MENUACTION_INVVERT, "FEC_IVV", { nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS },
-#ifndef GAMEPAD_MENU
- INVERT_PAD_SELECTOR
-#endif
- MENUACTION_MOUSESTEER, "FET_MST", { nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS },
- MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- },
- // MENUPAGE_MISSION_RETRY = 57
-#ifdef MISSION_REPLAY
+ // MENUPAGE_CONTROLLER_PC_OLD4 = 39
+ { "FET_CTL", MENUPAGE_CONTROLLER_PC, nil, nil,
- { "M_FAIL", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
- MENUACTION_LABEL, "FESZ_RM", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_CHANGEMENU, "FEM_YES", { nil, SAVESLOT_NONE, MENUPAGE_LOADING_IN_PROGRESS },
- MENUACTION_REJECT_RETRY, "FEM_NO", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- },
-#else
- { "", MENUPAGE_NONE, MENUPAGE_NONE, nil, nil,
- // mission failed, wanna restart page in mobile
- },
-#endif
+ },
-#ifdef MENU_MAP
- // MENUPAGE_MAP
- { "FEG_MAP", MENUPAGE_NONE, MENUPAGE_NONE, nil, nil,
- MENUACTION_UNK110, "", { nil, SAVESLOT_NONE, MENUPAGE_NONE }, // to prevent cross/enter to go back
- MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
+ // MENUPAGE_CONTROLLER_DEBUG = 40
+ { "FEC_DBG", MENUPAGE_CONTROLLER_PC, nil, nil,
+ MENUACTION_GETKEY, "FEC_TGD", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG}, 0, 0, 0,
+ MENUACTION_GETKEY, "FEC_TDO", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG}, 0, 0, 0,
+ MENUACTION_GETKEY, "FEC_TSS", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG}, 0, 0, 0,
+ MENUACTION_GETKEY, "FEC_SMS", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG}, 0, 0, 0,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0,
},
#endif
#ifdef GRAPHICS_MENU_OPTIONS
// MENUPAGE_GRAPHICS_SETTINGS
- { "FET_GFX", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS,
- new CCustomScreenLayout({MENUSPRITE_MAINMENU, 50, 0, 20, FONT_HEADING, FESCREEN_LEFT_ALIGN, true, MEDIUMTEXT_X_SCALE, MEDIUMTEXT_Y_SCALE}), GraphicsGoBack,
+ { "FET_GFX", MENUPAGE_OPTIONS, new CCustomScreenLayout({40, 78, 25, true, true}), GraphicsGoBack,
- MENUACTION_SCREENRES, "FED_RES", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS },
- MENUACTION_WIDESCREEN, "FED_WIS", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS },
+#ifndef GTA_HANDHELD
+ MENUACTION_SCREENRES, "FED_RES", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS }, 0, 0, MENUALIGN_LEFT,
+#endif
+ MENUACTION_WIDESCREEN, "FED_WIS", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS }, 0, 0, MENUALIGN_LEFT,
VIDEOMODE_SELECTOR
- MENUACTION_FRAMESYNC, "FEM_VSC", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
- MENUACTION_FRAMELIMIT, "FEM_FRM", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
+#ifdef LEGACY_MENU_OPTIONS
+ MENUACTION_FRAMESYNC, "FEM_VSC", {nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS}, 0, 0, MENUALIGN_LEFT,
+#endif
+ MENUACTION_FRAMELIMIT, "FEM_FRM", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS }, 0, 0, MENUALIGN_LEFT,
MULTISAMPLING_SELECTOR
ISLAND_LOADING_SELECTOR
DUALPASS_SELECTOR
#ifdef EXTENDED_COLOURFILTER
POSTFX_SELECTORS
-#else
- MENUACTION_TRAILS, "FED_TRA", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
+#elif defined LEGACY_MENU_OPTIONS
+ MENUACTION_TRAILS, "FED_TRA", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS }, 0, 0, MENUALIGN_LEFT,
#endif
// re3.cpp inserts here pipeline selectors if neo/neo.txd exists and EXTENDED_PIPELINES defined
- MENUACTION_CFO_DYNAMIC, "FET_DEF", { new CCFODynamic(nil, nil, nil, nil, RestoreDefGraphics) },
- MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
+ MENUACTION_CFO_DYNAMIC, "FET_DEF", { new CCFODynamic(nil, nil, nil, nil, RestoreDefGraphics) }, 320, 0, MENUALIGN_CENTER,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 0, MENUALIGN_CENTER,
},
#endif
#ifdef DETECT_JOYSTICK_MENU
// MENUPAGE_DETECT_JOYSTICK
- { "FEC_JOD", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC,
- new CCustomScreenLayout({MENUSPRITE_MAINMENU, 40, 60, 20, FONT_BANK, FESCREEN_LEFT_ALIGN, false, MEDIUMTEXT_X_SCALE, MEDIUMTEXT_Y_SCALE}), DetectJoystickGoBack,
-
- MENUACTION_LABEL, "FEC_JPR", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_CFO_DYNAMIC, "FEC_JDE", { new CCFODynamic(nil, nil, nil, DetectJoystickDraw, nil) },
- MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
+ { "FEC_JOD", MENUPAGE_CONTROLLER_PC, new CCustomScreenLayout({0, 0, 0, false, false, 30}), DetectJoystickGoBack,
+ MENUACTION_LABEL, "FEC_JPR", { nil, SAVESLOT_NONE, MENUPAGE_NONE }, 0, 0, 0,
+ MENUACTION_CFO_DYNAMIC, "FEC_JDE", { new CCFODynamic(nil, nil, nil, DetectJoystickDraw, nil) }, 80, 200, MENUALIGN_LEFT,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 225, MENUALIGN_CENTER,
},
#endif
- // MENUPAGE_UNK
- { "", MENUPAGE_NONE, MENUPAGE_NONE, nil, nil,
+
+#ifdef MISSION_REPLAY
+ // MENUPAGE_MISSION_RETRY = 57 on mobile
- },
+ { "M_FAIL", MENUPAGE_DISABLED, nil, nil,
+ MENUACTION_LABEL, "FESZ_RM", { nil, SAVESLOT_NONE, MENUPAGE_NONE }, 0, 0, 0,
+ MENUACTION_CHANGEMENU, "FEM_YES", { nil, SAVESLOT_NONE, MENUPAGE_LOADING_IN_PROGRESS }, 320, 200, MENUALIGN_CENTER,
+ MENUACTION_REJECT_RETRY, "FEM_NO", { nil, SAVESLOT_NONE, MENUPAGE_NONE }, 320, 225, MENUALIGN_CENTER,
+ },
+#endif
+ // MENUPAGE_OUTRO = 34
+ { "", 0, nil, nil, },
};
#endif
diff --git a/src/core/Pad.cpp b/src/core/Pad.cpp
index 60bb7a76..e75510e5 100644
--- a/src/core/Pad.cpp
+++ b/src/core/Pad.cpp
@@ -33,7 +33,14 @@
#include "Streaming.h"
#include "PathFind.h"
#include "Wanted.h"
+#include "WaterLevel.h"
#include "General.h"
+#include "Fluff.h"
+#include "Gangs.h"
+#include "platform.h"
+#include "Stats.h"
+#include "CarCtrl.h"
+#include "TrafficLights.h"
#ifdef GTA_PS2
#include "eetypes.h"
@@ -52,9 +59,9 @@ bool CPad::bDisplayNoControllerMessage;
bool CPad::bObsoleteControllerMessage;
bool CPad::bOldDisplayNoControllerMessage;
bool CPad::m_bMapPadOneToPadTwo;
-#ifdef INVERT_LOOK_FOR_PAD
+bool CPad::m_bDebugCamPCOn;
+bool CPad::bHasPlayerCheated;
bool CPad::bInvertLook4Pad;
-#endif
#ifdef GTA_PS2
unsigned char act_direct[6];
unsigned char act_align[6];
@@ -64,7 +71,7 @@ CKeyboardState CPad::OldKeyState;
CKeyboardState CPad::NewKeyState;
CKeyboardState CPad::TempKeyState;
-char CPad::KeyBoardCheatString[20];
+char CPad::KeyBoardCheatString[30];
CMouseControllerState CPad::OldMouseControllerState;
CMouseControllerState CPad::NewMouseControllerState;
@@ -77,62 +84,260 @@ bool CPad::IsAffectedByController = false;
_TODO("gbFastTime");
extern bool gbFastTime;
-void WeaponCheat()
+#ifdef WALLCLIMB_CHEAT
+extern bool gGravityCheat;
+#endif
+
+void SpecialCarCheats()
+{
+ if ( !CVehicle::bCheat9 )
+ {
+ ((CVehicleModelInfo*)CModelInfo::GetModelInfo(MI_INFERNUS))->m_wheelScale *= 1.3f;
+ ((CVehicleModelInfo*)CModelInfo::GetModelInfo(MI_CHEETAH))->m_wheelScale *= 1.3f;
+ ((CVehicleModelInfo*)CModelInfo::GetModelInfo(MI_PHEONIX))->m_wheelScale *= 1.3f;
+ ((CVehicleModelInfo*)CModelInfo::GetModelInfo(MI_DELUXO))->m_wheelScale *= 1.3f;
+ mod_HandlingManager.GetHandlingData(HANDLING_LANDSTAL)->Transmission.fEngineAcceleration *= 2.0f;
+ mod_HandlingManager.GetHandlingData(HANDLING_PATRIOT)->Transmission.fEngineAcceleration *= 2.0f;
+ mod_HandlingManager.GetHandlingData(HANDLING_BOBCAT)->Transmission.fEngineAcceleration *= 2.0f;
+ mod_HandlingManager.GetHandlingData(HANDLING_BFINJECT)->Transmission.fEngineAcceleration *= 2.0f;
+ mod_HandlingManager.GetHandlingData(HANDLING_RANCHER)->Transmission.fEngineAcceleration *= 2.0f;
+ mod_HandlingManager.GetHandlingData(HANDLING_DESPERAD)->Transmission.fEngineAcceleration *= 2.0f;
+ mod_HandlingManager.GetHandlingData(HANDLING_DELUXO)->Transmission.fEngineAcceleration *= 2.0f;
+
+ mod_HandlingManager.GetHandlingData(HANDLING_BAGGAGE)->Transmission.fEngineAcceleration *= 2.0f;
+ mod_HandlingManager.GetHandlingData(HANDLING_BAGGAGE)->Transmission.fMaxVelocity *= 2.0f;
+ mod_HandlingManager.GetHandlingData(HANDLING_BAGGAGE)->Transmission.InitGearRatios();
+
+ mod_HandlingManager.GetHandlingData(HANDLING_GOLFCART)->Transmission.fEngineAcceleration *= 2.0f;
+ mod_HandlingManager.GetHandlingData(HANDLING_GOLFCART)->Transmission.fMaxVelocity *= 2.0f;
+ mod_HandlingManager.GetHandlingData(HANDLING_GOLFCART)->Transmission.InitGearRatios();
+
+ mod_HandlingManager.GetHandlingData(HANDLING_STINGER)->fCollisionDamageMultiplier *= 0.25f;
+ mod_HandlingManager.GetHandlingData(HANDLING_STINGER)->fMass *= 2.5f;
+ mod_HandlingManager.GetHandlingData(HANDLING_STINGER)->fTurnMass *= 4.0f;
+
+ mod_HandlingManager.GetHandlingData(HANDLING_BANSHEE)->fCollisionDamageMultiplier *= 0.25f;
+ mod_HandlingManager.GetHandlingData(HANDLING_BANSHEE)->fMass *= 2.5f;
+ mod_HandlingManager.GetHandlingData(HANDLING_BANSHEE)->fTurnMass *= 4.0f;
+
+ mod_HandlingManager.GetHandlingData(HANDLING_SABRETUR)->fCollisionDamageMultiplier *= 0.25f;
+ mod_HandlingManager.GetHandlingData(HANDLING_SABRETUR)->fMass *= 2.5f;
+ mod_HandlingManager.GetHandlingData(HANDLING_SABRETUR)->fTurnMass *= 4.0f;
+
+ mod_HandlingManager.GetHandlingData(HANDLING_COMET)->fCollisionDamageMultiplier *= 0.25f;
+ mod_HandlingManager.GetHandlingData(HANDLING_COMET)->fMass *= 2.5f;
+ mod_HandlingManager.GetHandlingData(HANDLING_COMET)->fTurnMass *= 4.0f;
+
+ mod_HandlingManager.GetHandlingData(HANDLING_DELUXO)->fCollisionDamageMultiplier *= 0.25f;
+ mod_HandlingManager.GetHandlingData(HANDLING_DELUXO)->fMass *= 2.5f;
+ mod_HandlingManager.GetHandlingData(HANDLING_DELUXO)->fTurnMass *= 4.0f;
+ CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
+ CVehicle::bCheat9 = true;
+ CPad::bHasPlayerCheated = true;
+ }
+}
+
+void PickUpChicksCheat()
+{
+ if ( FindPlayerVehicle() && (FindPlayerVehicle()->IsCar() || FindPlayerVehicle()->IsBike()) )
+ {
+ CVehicle *vehicle = FindPlayerVehicle();
+ if ( FindPlayerVehicle()->IsBike() )
+ {
+ if ( vehicle->pPassengers[0] )
+ vehicle->pPassengers[0]->SetObjective(OBJECTIVE_LEAVE_CAR, vehicle);
+ }
+ CPed* someoneElse = (CPed*)CWorld::TestSphereAgainstWorld(vehicle->GetPosition(), 6.0f, FindPlayerPed(), false, false, true, false, false, false);
+ if ( someoneElse && someoneElse->m_nPedState != PED_DRIVING )
+ {
+ CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
+ someoneElse->SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, vehicle);
+ }
+ }
+}
+
+void WeaponCheat1()
{
CHud::SetHelpMessage(TheText.Get("CHEAT2"), true);
- FindPlayerPed()->GiveWeapon(WEAPONTYPE_BASEBALLBAT, 0);
+
+ CStreaming::RequestModel(MI_BRASS_KNUCKLES, STREAMFLAGS_DONT_REMOVE);
+ CStreaming::RequestModel(MI_BASEBALL_BAT, STREAMFLAGS_DONT_REMOVE);
+ CStreaming::RequestModel(MI_MOLOTOV, STREAMFLAGS_DONT_REMOVE);
+ CStreaming::RequestModel(MI_COLT45, STREAMFLAGS_DONT_REMOVE);
+ CStreaming::RequestModel(MI_SHOTGUN, STREAMFLAGS_DONT_REMOVE);
+ CStreaming::RequestModel(MI_TEC9, STREAMFLAGS_DONT_REMOVE);
+ CStreaming::RequestModel(MI_RUGER, STREAMFLAGS_DONT_REMOVE);
+ CStreaming::RequestModel(MI_SNIPERRIFLE, STREAMFLAGS_DONT_REMOVE);
+ CStreaming::RequestModel(MI_FLAMETHROWER, STREAMFLAGS_DONT_REMOVE);
+ CStreaming::LoadAllRequestedModels(false);
+
+ FindPlayerPed()->GiveWeapon(WEAPONTYPE_BRASSKNUCKLE, 1);
+ FindPlayerPed()->GiveWeapon(WEAPONTYPE_BASEBALLBAT, 1);
+ FindPlayerPed()->GiveWeapon(WEAPONTYPE_MOLOTOV, 10);
FindPlayerPed()->GiveWeapon(WEAPONTYPE_COLT45, 100);
- FindPlayerPed()->GiveWeapon(WEAPONTYPE_UZI, 100);
- FindPlayerPed()->GiveWeapon(WEAPONTYPE_SHOTGUN, 20);
- FindPlayerPed()->GiveWeapon(WEAPONTYPE_AK47, 200);
- FindPlayerPed()->GiveWeapon(WEAPONTYPE_M16, 200);
- FindPlayerPed()->GiveWeapon(WEAPONTYPE_SNIPERRIFLE, 5);
- FindPlayerPed()->GiveWeapon(WEAPONTYPE_ROCKETLAUNCHER, 5);
- FindPlayerPed()->GiveWeapon(WEAPONTYPE_MOLOTOV, 5);
- FindPlayerPed()->GiveWeapon(WEAPONTYPE_GRENADE, 5);
+ FindPlayerPed()->GiveWeapon(WEAPONTYPE_SHOTGUN, 50);
+ FindPlayerPed()->GiveWeapon(WEAPONTYPE_TEC9, 150);
+ FindPlayerPed()->GiveWeapon(WEAPONTYPE_RUGER, 120);
+ FindPlayerPed()->GiveWeapon(WEAPONTYPE_SNIPERRIFLE, 25);
FindPlayerPed()->GiveWeapon(WEAPONTYPE_FLAMETHROWER, 200);
+
+ CStreaming::SetModelIsDeletable(MI_BRASS_KNUCKLES);
+ CStreaming::SetModelIsDeletable(MI_BASEBALL_BAT);
+ CStreaming::SetModelIsDeletable(MI_MOLOTOV);
+ CStreaming::SetModelIsDeletable(MI_COLT45);
+ CStreaming::SetModelIsDeletable(MI_SHOTGUN);
+ CStreaming::SetModelIsDeletable(MI_TEC9);
+ CStreaming::SetModelIsDeletable(MI_RUGER);
+ CStreaming::SetModelIsDeletable(MI_SNIPERRIFLE);
+ CStreaming::SetModelIsDeletable(MI_FLAMETHROWER);
+#ifdef MOBILE_IMPROVEMENTS
+ if (FindPlayerVehicle()) {
+ FindPlayerPed()->RemoveWeaponWhenEnteringVehicle();
+ }
+#endif
+}
+
+void WeaponCheat2()
+{
+ CHud::SetHelpMessage(TheText.Get("CHEAT2"), true);
+
+ CStreaming::RequestModel(MI_KATANA, STREAMFLAGS_DONT_REMOVE);
+ CStreaming::RequestModel(MI_GRENADE, STREAMFLAGS_DONT_REMOVE);
+ CStreaming::RequestModel(MI_BOMB, STREAMFLAGS_DONT_REMOVE);
+ CStreaming::RequestModel(MI_PYTHON, STREAMFLAGS_DONT_REMOVE);
+ CStreaming::RequestModel(MI_STUBBY_SHOTGUN, STREAMFLAGS_DONT_REMOVE);
+ CStreaming::RequestModel(MI_SILENCEDINGRAM, STREAMFLAGS_DONT_REMOVE);
+ CStreaming::RequestModel(MI_M4, STREAMFLAGS_DONT_REMOVE);
+ CStreaming::RequestModel(MI_LASERSCOPE, STREAMFLAGS_DONT_REMOVE);
+ CStreaming::RequestModel(MI_ROCKETLAUNCHER, STREAMFLAGS_DONT_REMOVE);
+ CStreaming::LoadAllRequestedModels(false);
+
+#ifdef FIX_BUGS
+ FindPlayerPed()->GiveWeapon(WEAPONTYPE_KATANA, 1);
+#else
+ FindPlayerPed()->GiveWeapon(WEAPONTYPE_KATANA, 0);
+#endif
+ FindPlayerPed()->GiveWeapon(WEAPONTYPE_DETONATOR_GRENADE, 10);
+ FindPlayerPed()->GiveWeapon(WEAPONTYPE_PYTHON, 40);
+ FindPlayerPed()->GiveWeapon(WEAPONTYPE_STUBBY_SHOTGUN, 25);
+ FindPlayerPed()->GiveWeapon(WEAPONTYPE_SILENCED_INGRAM, 100);
+ FindPlayerPed()->GiveWeapon(WEAPONTYPE_M4, 150);
+ FindPlayerPed()->GiveWeapon(WEAPONTYPE_LASERSCOPE, 21);
+ FindPlayerPed()->GiveWeapon(WEAPONTYPE_ROCKETLAUNCHER, 5);
+
+ CStreaming::SetModelIsDeletable(MI_KATANA);
+ CStreaming::SetModelIsDeletable(MI_GRENADE);
+ CStreaming::SetModelIsDeletable(MI_BOMB);
+ CStreaming::SetModelIsDeletable(MI_PYTHON);
+ CStreaming::SetModelIsDeletable(MI_STUBBY_SHOTGUN);
+ CStreaming::SetModelIsDeletable(MI_SILENCEDINGRAM);
+ CStreaming::SetModelIsDeletable(MI_M4);
+ CStreaming::SetModelIsDeletable(MI_LASERSCOPE);
+ CStreaming::SetModelIsDeletable(MI_ROCKETLAUNCHER);
+#ifdef MOBILE_IMPROVEMENTS
+ if (FindPlayerVehicle()) {
+ FindPlayerPed()->RemoveWeaponWhenEnteringVehicle();
+ }
+#endif
+}
+
+void WeaponCheat3()
+{
+ CHud::SetHelpMessage(TheText.Get("CHEAT2"), true);
+
+ CStreaming::RequestModel(MI_CHAINSAW, STREAMFLAGS_DONT_REMOVE);
+ CStreaming::RequestModel(MI_GRENADE, STREAMFLAGS_DONT_REMOVE);
+ CStreaming::RequestModel(MI_PYTHON, STREAMFLAGS_DONT_REMOVE);
+ CStreaming::RequestModel(MI_SPAS12_SHOTGUN, STREAMFLAGS_DONT_REMOVE);
+ CStreaming::RequestModel(MI_MP5, STREAMFLAGS_DONT_REMOVE);
+ CStreaming::RequestModel(MI_M4, STREAMFLAGS_DONT_REMOVE);
+ CStreaming::RequestModel(MI_LASERSCOPE, STREAMFLAGS_DONT_REMOVE);
+ CStreaming::RequestModel(MI_MINIGUN, STREAMFLAGS_DONT_REMOVE);
+ CStreaming::RequestModel(MI_MINIGUN2, STREAMFLAGS_DONT_REMOVE);
+ CStreaming::LoadAllRequestedModels(false);
+
+#ifdef FIX_BUGS
+ FindPlayerPed()->GiveWeapon(WEAPONTYPE_CHAINSAW, 1);
+#else
+ FindPlayerPed()->GiveWeapon(WEAPONTYPE_CHAINSAW, 0);
+#endif
+ FindPlayerPed()->GiveWeapon(WEAPONTYPE_GRENADE, 10);
+ FindPlayerPed()->GiveWeapon(WEAPONTYPE_PYTHON, 40);
+ FindPlayerPed()->GiveWeapon(WEAPONTYPE_SPAS12_SHOTGUN, 30);
+ FindPlayerPed()->GiveWeapon(WEAPONTYPE_MP5, 100);
+ FindPlayerPed()->GiveWeapon(WEAPONTYPE_M4, 150);
+ FindPlayerPed()->GiveWeapon(WEAPONTYPE_LASERSCOPE, 21);
+ FindPlayerPed()->GiveWeapon(WEAPONTYPE_MINIGUN, 500);
+
+ CStreaming::SetModelIsDeletable(MI_CHAINSAW);
+ CStreaming::SetModelIsDeletable(MI_GRENADE);
+ CStreaming::SetModelIsDeletable(MI_PYTHON);
+ CStreaming::SetModelIsDeletable(MI_SPAS12_SHOTGUN);
+ CStreaming::SetModelIsDeletable(MI_MP5);
+ CStreaming::SetModelIsDeletable(MI_M4);
+ CStreaming::SetModelIsDeletable(MI_LASERSCOPE);
+ CStreaming::SetModelIsDeletable(MI_MINIGUN);
+ CStreaming::SetModelIsDeletable(MI_MINIGUN2);
+
+#ifdef MOBILE_IMPROVEMENTS
+ if (FindPlayerVehicle()) {
+ FindPlayerPed()->RemoveWeaponWhenEnteringVehicle();
+ }
+#endif
}
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)
+ if (FindPlayerVehicle()->m_vehType == VEHICLE_TYPE_CAR) {
((CAutomobile*)FindPlayerVehicle())->Damage.SetEngineStatus(0);
+ for (int32 i = 0; i < 4; i++)
+ ((CAutomobile*)FindPlayerVehicle())->Damage.SetWheelStatus(i, WHEEL_STATUS_OK);
+ }
}
}
-void TankCheat()
+// TODO(Miami): this is HELLA different on mobile, although it mostly has debug oriented things like player exiting it's current car and enters spawned one etc.
+void VehicleCheat(int model)
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
- CStreaming::RequestModel(MI_RHINO, 0);
+ CStreaming::RequestModel(model, STREAMFLAGS_DONT_REMOVE);
CStreaming::LoadAllRequestedModels(false);
- if (CStreaming::ms_aInfoForModel[MI_RHINO].m_loadState == STREAMSTATE_LOADED) {
+ 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 (!(CStreaming::ms_aInfoForModel[model].m_loadState & STREAMFLAGS_DONT_REMOVE)) {
+ CStreaming::SetModelIsDeletable(model);
+ CStreaming::SetModelTxdIsDeletable(model);
+ }
+
+ 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(model, 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);
}
}
+ CStats::CheatedCount += 1000;
+ CPad::bHasPlayerCheated = true;
}
+
void BlowUpCarsCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
@@ -146,7 +351,8 @@ void BlowUpCarsCheat()
void ChangePlayerCheat()
{
- int modelId;
+ // I don't know wtf is going on in here...
+ int modelId, anotherModelId;
if (FindPlayerPed()->IsPedInControl() && CModelInfo::GetModelInfo("player", nil)) {
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
@@ -154,25 +360,34 @@ void ChangePlayerCheat()
AssocGroupId AnimGrp = ped->m_animGroup;
do
{
- do
- modelId = CGeneral::GetRandomNumberInRange(0, MI_CAS_WOM+1);
- while (!CModelInfo::GetModelInfo(modelId));
- } while (modelId >= MI_SPECIAL01 && modelId <= MI_SPECIAL04 || modelId == MI_TAXI_D);
+ do {
+ modelId = CGeneral::GetRandomNumberInRange(0, MI_PGA);
+ anotherModelId = modelId+1;
+ } while (!CModelInfo::GetModelInfo(anotherModelId));
+ } while (anotherModelId >= MI_SPECIAL01 && anotherModelId <= MI_SPECIAL04 || modelId == MI_TAXI_D);
- uint8 flags = CStreaming::ms_aInfoForModel[modelId].m_flags;
+ uint8 flags = CStreaming::ms_aInfoForModel[anotherModelId].m_flags;
ped->DeleteRwObject();
- CStreaming::RequestModel(modelId, STREAMFLAGS_DEPENDENCY| STREAMFLAGS_DONT_REMOVE);
+ CStreaming::RequestModel(anotherModelId, STREAMFLAGS_DEPENDENCY| STREAMFLAGS_DONT_REMOVE);
CStreaming::LoadAllRequestedModels(false);
ped->m_modelIndex = -1;
- ped->SetModelIndex(modelId);
+ ped->SetModelIndex(anotherModelId);
ped->m_animGroup = AnimGrp;
- if (modelId != MI_PLAYER) {
+ if (modelId != -1) {
if (!(flags & STREAMFLAGS_DONT_REMOVE))
- CStreaming::SetModelIsDeletable(modelId);
+ CStreaming::SetModelIsDeletable(anotherModelId);
}
}
}
+void ChangePlayerModel(const char* name) {
+ if (!FindPlayerVehicle()) {
+ FindPlayerPed()->Undress(name);
+ CStreaming::LoadAllRequestedModels(0);
+ FindPlayerPed()->Dress();
+ }
+}
+
void MayhemCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
@@ -182,6 +397,8 @@ void MayhemCheat()
PED_FLAG_GANG2 | PED_FLAG_GANG3 | PED_FLAG_GANG4 | PED_FLAG_GANG5 |
PED_FLAG_GANG6 | PED_FLAG_GANG7 | PED_FLAG_GANG8 | PED_FLAG_GANG9 |
PED_FLAG_EMERGENCY | PED_FLAG_PROSTITUTE | PED_FLAG_CRIMINAL | PED_FLAG_SPECIAL );
+ CStats::CheatedCount += 1000;
+ CPad::bHasPlayerCheated = true;
}
void EverybodyAttacksPlayerCheat()
@@ -189,12 +406,17 @@ void EverybodyAttacksPlayerCheat()
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
for (int i = PEDTYPE_CIVMALE; i < PEDTYPE_SPECIAL; i++)
CPedType::AddThreat(i, PED_FLAG_PLAYER1);
+
+ CStats::CheatedCount += 1000;
+ CPad::bHasPlayerCheated = true;
}
void WeaponsForAllCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
CPopulation::ms_bGivePedsWeapons = !CPopulation::ms_bGivePedsWeapons;
+ CStats::CheatedCount += 1000;
+ CPad::bHasPlayerCheated = true;
}
void FastTimeCheat()
@@ -220,19 +442,19 @@ 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()
{
CHud::SetHelpMessage(TheText.Get("CHEAT5"), true);
- FindPlayerPed()->SetWantedLevel(Min(FindPlayerPed()->m_pWanted->GetWantedLevel() + 2, 6));
+ FindPlayerPed()->m_pWanted->CheatWantedLevel(Min(FindPlayerPed()->m_pWanted->GetWantedLevel() + 2, 6));
}
void WantedLevelDownCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT5"), true);
- FindPlayerPed()->SetWantedLevel(0);
+ FindPlayerPed()->m_pWanted->CheatWantedLevel(0);
}
void SunnyWeatherCheat()
@@ -241,6 +463,12 @@ void SunnyWeatherCheat()
CWeather::ForceWeatherNow(WEATHER_SUNNY);
}
+void ExtraSunnyWeatherCheat()
+{
+ CHud::SetHelpMessage(TheText.Get("CHEAT7"), true);
+ CWeather::ForceWeatherNow(WEATHER_EXTRA_SUNNY);
+}
+
void CloudyWeatherCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT7"), true);
@@ -269,25 +497,101 @@ void OnlyRenderWheelsCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
CVehicle::bWheelsOnlyCheat = !CVehicle::bWheelsOnlyCheat;
+ CStats::CheatedCount += 1000;
+ CPad::bHasPlayerCheated = true;
}
-
void ChittyChittyBangBangCheat()
{
+#ifdef BETTER_ALLCARSAREDODO_CHEAT
+ CHud::SetHelpMessage(TheText.Get(!CVehicle::bAllDodosCheat ? "CHEAT1" : "CHEATOF"), true);
+#else
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
+#endif
CVehicle::bAllDodosCheat = !CVehicle::bAllDodosCheat;
+ CStats::CheatedCount += 1000;
+ CPad::bHasPlayerCheated = true;
}
void StrongGripCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
CVehicle::bCheat3 = !CVehicle::bCheat3;
+ CStats::CheatedCount += 1000;
+ CPad::bHasPlayerCheated = true;
+}
+
+void FannyMagnetCheat()
+{
+ CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
+ CPed::bFannyMagnetCheat = !CPed::bFannyMagnetCheat;
+ CPad::bHasPlayerCheated = true;
+}
+
+void BlackCarsCheat()
+{
+ CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
+ gbBlackCars = true;
+ gbPinkCars = false;
+}
+
+void PinkCarsCheat()
+{
+ CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
+ gbBlackCars = false;
+ gbPinkCars = true;
+}
+
+void TrafficLightsCheat()
+{
+ CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
+ CTrafficLights::bGreenLightsCheat = true;
+}
+
+void MadCarsCheat()
+{
+ CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
+ CCarCtrl::bMadDriversCheat = true;
+}
+
+void NoSeaBedCheat(void)
+{
+ CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
+ CWaterLevel::m_bRenderSeaBed = !CWaterLevel::m_bRenderSeaBed;
}
-void NastyLimbsCheat()
+void RenderWaterLayersCheat(void)
{
- CPed::bNastyLimbsCheat = !CPed::bNastyLimbsCheat;
+ CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
+ if ( ++CWaterLevel::m_nRenderWaterLayers > 5 )
+ CWaterLevel::m_nRenderWaterLayers = 0;
+}
+
+void BackToTheFuture(void)
+{
+ CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
+ CVehicle::bHoverCheat = !CVehicle::bHoverCheat;
+ CPad::bHasPlayerCheated = true;
+}
+
+void SuicideCheat(void) {
+ CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
+ FindPlayerPed()->InflictDamage(nil, WEAPONTYPE_UNARMED, 1000.0f, PEDPIECE_TORSO, 0);
}
+
+void DoChicksWithGunsCheat(void) {
+ CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
+ CStreaming::SetModelIsDeletable(CGangs::GetGangPedModel1(GANG_PLAYER));
+ CStreaming::SetModelIsDeletable(CGangs::GetGangPedModel2(GANG_PLAYER));
+ CStreaming::SetModelTxdIsDeletable(CGangs::GetGangPedModel1(GANG_PLAYER));
+ CStreaming::SetModelTxdIsDeletable(CGangs::GetGangPedModel2(GANG_PLAYER));
+ CStreaming::RemoveCurrentZonesModels();
+ CGangs::SetGangPedModels(GANG_PLAYER, MI_HFYBE, MI_WFYBE);
+ CGangs::SetGangWeapons(GANG_PLAYER, WEAPONTYPE_M4, WEAPONTYPE_M4);
+ CStats::CheatedCount += 1000;
+ CPad::bHasPlayerCheated = true;
+}
+
//////////////////////////////////////////////////////////////////////////
#ifdef KANGAROO_CHEAT
@@ -312,7 +616,7 @@ void KangarooCheat()
}
#endif
-#ifdef ALLCARSHELI_CHEAT
+#ifdef RESTORE_ALLCARSHELI_CHEAT
void AllCarsHeliCheat(void)
{
wchar* string;
@@ -328,22 +632,34 @@ void AllCarsHeliCheat(void)
}
#endif
-#ifdef ALT_DODO_CHEAT
-void AltDodoCheat(void)
+#ifdef WALLCLIMB_CHEAT
+void WallClimbingCheat(void)
{
wchar* string;
- if (CVehicle::bAltDodoCheat) {
+ if (gGravityCheat) {
string = TheText.Get("CHEATOF");
- CVehicle::bAltDodoCheat = false;
+ gGravityCheat = false;
}
else {
string = TheText.Get("CHEAT1");
- CVehicle::bAltDodoCheat = true;
+ gGravityCheat = true;
}
CHud::SetHelpMessage(string, true);
}
#endif
+void FlyingFishCheat(void)
+{
+ CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
+ CVehicle::bCheat8 = !CVehicle::bCheat8;
+ CPad::bHasPlayerCheated = true;
+}
+
+void DoShowChaseStatCheat(void) {
+ CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
+ CStats::ShowChaseStatOnScreen = 1;
+}
+
bool
CControllerState::CheckForInput(void)
{
@@ -414,6 +730,8 @@ void CPad::Initialise(void)
bObsoleteControllerMessage = false;
bOldDisplayNoControllerMessage = false;
bDisplayNoControllerMessage = false;
+ m_bMapPadOneToPadTwo = false;
+ m_bDebugCamPCOn = false;
}
#endif
@@ -438,12 +756,17 @@ void CPad::Clear(bool bResetPlayerControls)
ShakeFreq = 0;
ShakeDur = 0;
+ for (int32 i = 0; i < DRUNK_STEERING_BUFFER_SIZE; i++)
+ SteeringLeftRightBuffer[i] = 0;
+
+ DrunkDrivingBufferUsed = 0;
+
if ( bResetPlayerControls )
DisablePlayerControls = PLAYERCONTROL_ENABLED;
+ JustOutOfFrontend = 0;
bApplyBrakes = false;
-
for ( int32 i = 0; i < HORNHISTORY_SIZE; i++ )
bHornHistory[i] = false;
@@ -457,6 +780,11 @@ void CPad::Clear(bool bResetPlayerControls)
AverageEntries = 0;
}
+uint32 CPad::InputHowLongAgo()
+{
+ return CTimer::GetTimeInMilliseconds() - LastTimeTouched;
+}
+
void CPad::ClearMouseHistory()
{
PCTempMouseControllerState.Clear();
@@ -464,6 +792,14 @@ void CPad::ClearMouseHistory()
OldMouseControllerState.Clear();
}
+// unused
+void CPad::ClearKeyBoardHistory()
+{
+ NewKeyState.Clear();
+ OldKeyState.Clear();
+ TempKeyState.Clear();
+}
+
CMouseControllerState::CMouseControllerState()
{
LMB = 0;
@@ -495,7 +831,7 @@ CMouseControllerState CMousePointerStateHelper::GetMouseSetUp()
#if defined RW_D3D9 || defined RWLIBS
if ( PSGLOBAL(mouse) == nil )
- _InputInitialiseMouse();
+ _InputInitialiseMouse(!FrontEndMenuManager.m_bMenuActive && _InputMouseNeedsExclusive());
if ( PSGLOBAL(mouse) != nil )
{
@@ -549,7 +885,7 @@ void CPad::UpdateMouse()
if ( IsForegroundApp() )
{
if ( PSGLOBAL(mouse) == nil )
- _InputInitialiseMouse();
+ _InputInitialiseMouse(!FrontEndMenuManager.m_bMenuActive && _InputMouseNeedsExclusive());
DIMOUSESTATE2 state;
@@ -693,7 +1029,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 )
@@ -715,7 +1051,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 )
@@ -742,7 +1078,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 )
@@ -776,7 +1112,7 @@ void CPad::AddToCheatString(char c)
#define _CHEATCMP(str) strncmp(str, CheatString, sizeof(str)-1)
// "4414LDRULDRU" - R2 R2 L1 R2 LEFT DOWN RIGHT UP LEFT DOWN RIGHT UP
if ( !_CHEATCMP("URDLURDL4144") )
- WeaponCheat();
+ WeaponCheat1();
// "4411LDRULDRU" - R2 R2 L1 L1 LEFT DOWN RIGHT UP LEFT DOWN RIGHT UP
else if ( !_CHEATCMP("URDLURDL1144") )
@@ -816,7 +1152,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(MI_RHINO);
// "CCCSSSSS1TCT" - CIRCLE CIRCLE CIRCLE SQUARE SQUARE SQUARE SQUARE SQUARE L1 TRIANGLE CIRCLE TRIANGLE
else if ( !_CHEATCMP("TCT1SSSSSCCC") )
@@ -862,143 +1198,354 @@ void CPad::AddToCheatString(char c)
else if ( !_CHEATCMP("T33L1413") )
StrongGripCheat();
- // "S1CD13TR1X" - SQUARE L1 CIRCLE DOWN L1 R1 TRIANGLE RIGHT L1 CROSS
- else if ( !_CHEATCMP("X1RT31DC1S") )
- NastyLimbsCheat();
-
-#ifdef KANGAROO_CHEAT
- // "X1DUC3RLS3" - R1 SQUARE LEFT RIGHT R1 CIRCLE UP DOWN L1 CROSS
- else if (!_CHEATCMP("X1DUC3RLS3"))
- KangarooCheat();
-#endif
-
-#ifndef MASTER
- // "31UD13XUD" - DOWN UP CROSS R1 L1 DOWN UP L1 R1
- else if (!_CHEATCMP("31UD13XUD"))
- CPed::SwitchDebugDisplay();
-#endif
-
-#ifdef ALLCARSHELI_CHEAT
- // "UCCL3R1TT" - TRIANGLE TRIANGLE L1 RIGHT R1 LEFT CIRCLE CIRCLE UP
- else if (!_CHEATCMP("UCCL3R1TT"))
- AllCarsHeliCheat();
-#endif
-
-#ifdef ALT_DODO_CHEAT
- // "DUU31XX13" - R1 L1 CROSS CROSS L1 R1 UP UP DOWN
- else if (!_CHEATCMP("DUU31XX13"))
- AltDodoCheat();
-#endif
#undef _CHEATCMP
}
#endif
+int Cheat_strncmp(char* sourceStr, char* origCheatStr)
+{
+#define ccmp(n) if((uint8)sourceStr[i] != (uint8)origCheatStr[i] - n) return 1;
+ int i = 0;
+ while(origCheatStr[i])
+ {
+ switch(i)
+ {
+ case 0: ccmp(3); break;
+ case 1: ccmp(5); break;
+ case 2: ccmp(7); break;
+ case 3: ccmp(1); break;
+ case 4: ccmp(13); break;
+ case 5: ccmp(27); break;
+ case 6: ccmp(3); break;
+ case 7: ccmp(7); break;
+ case 8: ccmp(1); break;
+ case 9: ccmp(11); break;
+ case 10: ccmp(13); break;
+ case 11: ccmp(8); break;
+ case 12: ccmp(7); break;
+ case 13: ccmp(32); break;
+ case 14: ccmp(13); break;
+ case 15: ccmp(6); break;
+ case 16: ccmp(28); break;
+ case 17: ccmp(19); break;
+ case 18: ccmp(10); break;
+ case 19: ccmp(3); break;
+ case 20: ccmp(3); break;
+ case 21: ccmp(5); break;
+ case 22: ccmp(7); break;
+ case 23: ccmp(1); break;
+ case 24: ccmp(13); break;
+ case 25: ccmp(27); break;
+ case 26: ccmp(3); break;
+ case 27: ccmp(7); break;
+ default: return 1;
+ }
+ i++;
+ }
+ return 0;
+#undef ccmp
+}
+
+// TODO(Miami): Mobile has changed some of the cheats to include debugging things
void CPad::AddToPCCheatString(char c)
{
- for ( int32 i = ARRAY_SIZE(KeyBoardCheatString) - 2; i >= 0; i-- )
+ for (int32 i = ARRAY_SIZE(KeyBoardCheatString) - 2; i >= 0; i--)
KeyBoardCheatString[i + 1] = KeyBoardCheatString[i];
KeyBoardCheatString[0] = c;
- #define _CHEATCMP(str) strncmp(str, KeyBoardCheatString, sizeof(str)-1)
-
- // "GUNSGUNSGUNS"
- if ( !_CHEATCMP("SNUGSNUGSNUG") )
- WeaponCheat();
-
- // "IFIWEREARICHMAN"
- if ( !_CHEATCMP("NAMHCIRAEREWIFI") )
- MoneyCheat();
+#define _CHEATCMP(str) strncmp(str, KeyBoardCheatString, sizeof(str)-1)
- // "GESUNDHEIT"
- if ( !_CHEATCMP("TIEHDNUSEG") )
+ // "THUGSTOOLS"
+ if (!Cheat_strncmp(KeyBoardCheatString, "VQVPanJ\\I_")) {
+ KeyBoardCheatString[0] = ' ';
+ WeaponCheat1();
+ }
+ // "PROFESSIONALTOOLS"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "VQVPagDUPT`[Lf\\Xl")) {
+ KeyBoardCheatString[0] = ' ';
+ WeaponCheat2();
+ }
+ // "NUTTERTOOLS"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "VQVPamH[U`[")) {
+ KeyBoardCheatString[0] = ' ';
+ WeaponCheat3();
+ }
+ // "PRECIOUSPROTECTION"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "QTPUP`WVS[`]ViPKnc")) {
+ KeyBoardCheatString[0] = ' ';
+ ArmourCheat();
+ }
+ // "ASPIRINE"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "HSPSVkVH")) {
+ KeyBoardCheatString[0] = ' ';
HealthCheat();
-
- // "MOREPOLICEPLEASE"
- if ( !_CHEATCMP("ESAELPECILOPEROM") )
+ }
+ // "YOUWONTTAKEMEALIVE"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "H[PMN`PLLLa\\Uod[kl")) {
+ KeyBoardCheatString[0] = ' ';
WantedLevelUpCheat();
-
- // "NOPOLICEPLEASE"
- if ( !_CHEATCMP("ESAELPECILOPON") )
+ }
+ // "LEAVEMEALONE"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "HSVMN`PLWLRT")) {
+ KeyBoardCheatString[0] = ' ';
WantedLevelDownCheat();
-
- // "GIVEUSATANK"
- if ( !_CHEATCMP("KNATASUEVIG") )
- TankCheat();
-
- // "BANGBANGBANG"
- if ( !_CHEATCMP("GNABGNABGNAB") )
+ }
+ // "APLEASANTDAY"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "\\FKU[\\VHFW]I")) {
+ KeyBoardCheatString[0] = ' ';
+ SunnyWeatherCheat();
+ }
+ // "ALOVELYDAY"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "\\FKZY`YVML")) {
+ KeyBoardCheatString[0] = ' ';
+ ExtraSunnyWeatherCheat();
+ }
+ // "ABITDRIEG"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "JJPSQoLIB")) {
+ KeyBoardCheatString[0] = ' ';
+ CloudyWeatherCheat();
+ }
+ // "CATSANDDOGS"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "VLVEQiDZULP")) {
+ KeyBoardCheatString[0] = ' ';
+ RainyWeatherCheat();
+ }
+ // "CANTSEEATHING"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "JSPIa\\HLT_[IJ")) {
+ KeyBoardCheatString[0] = ' ';
+ FoggyWeatherCheat();
+ }
+ // "PANZER"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "UJaONk")) {
+ KeyBoardCheatString[0] = ' ';
+ VehicleCheat(MI_RHINO);
+ }
+ // "LIFEISPASSINGMEBY"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "\\GLNTiLZTL][PeSOh")) {
+ KeyBoardCheatString[0] = ' ';
+ FastWeatherCheat();
+ }
+ // "BIGBANG"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "JSHCTdE")) {
+ KeyBoardCheatString[0] = ' ';
BlowUpCarsCheat();
-
- // "ILIKEDRESSINGUP"
- if ( !_CHEATCMP("PUGNISSERDEKILI") )
+ }
+ // "STILLLIKEDRESSINGUP"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "SZNOVnVLSORSPlYReg]")) {
+ KeyBoardCheatString[0] = ' ';
ChangePlayerCheat();
-
- // "ITSALLGOINGMAAAD"
- if ( !_CHEATCMP("DAAAMGNIOGLLASTI") )
+ }
+ // "FIGHTFIGHTFIGHT"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "WMNJSoKNJQaPNiS")) {
+ KeyBoardCheatString[0] = ' ';
MayhemCheat();
-
+ }
// "NOBODYLIKESME"
- if ( !_CHEATCMP("EMSEKILYDOBON") )
+ else if (!Cheat_strncmp(KeyBoardCheatString, "HRZFXdO`EZOWU")) {
+ KeyBoardCheatString[0] = ' ';
EverybodyAttacksPlayerCheat();
-
- // "WEAPONSFORALL"
- if ( !_CHEATCMP("LLAROFSNOPAEW") )
+ }
+ // "OURGODGIVENRIGHTTOBEARARMS"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "VRYB_\\HIP_aPNi_TaiSJGTNSbj")) {
+ KeyBoardCheatString[0] = ' ';
WeaponsForAllCheat();
-
- // "TIMEFLIESWHENYOU"
- if ( !_CHEATCMP("UOYNEHWSEILFEMIT") )
+ }
+ // "ONSPEED"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "GJLQ`iR")) {
+ KeyBoardCheatString[0] = ' ';
FastTimeCheat();
-
- // "BOOOOORING"
- if ( !_CHEATCMP("GNIROOOOOB") )
+ }
+ // "BOOOOOORING"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "JSPS\\jRVPZO")) {
+ KeyBoardCheatString[0] = ' ';
SlowTimeCheat();
-
-#if GTA_VERSION < GTA3_PC_11
- // "TURTOISE"
- if ( !_CHEATCMP("ESIOTRUT") )
- ArmourCheat();
-#else
- // "TORTOISE"
- if ( !_CHEATCMP("ESIOTROT") )
- ArmourCheat();
-#endif
-
- // "SKINCANCERFORME"
- if ( !_CHEATCMP("EMROFRECNACNIKS") )
- SunnyWeatherCheat();
-
- // "ILIKESCOTLAND"
- if ( !_CHEATCMP("DNALTOCSEKILI") )
- CloudyWeatherCheat();
-
- // "ILOVESCOTLAND"
- if ( !_CHEATCMP("DNALTOCSEVOLI") )
- RainyWeatherCheat();
-
- // "PEASOUP"
- if ( !_CHEATCMP("PUOSAEP") )
- FoggyWeatherCheat();
-
- // "MADWEATHER"
- if ( !_CHEATCMP("REHTAEWDAM") )
- FastWeatherCheat();
-
- // "ANICESETOFWHEELS"
- if ( !_CHEATCMP("SLEEHWFOTESECINA") )
+ }
+ // "WHEELSAREALLINEED"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "GJLOVgOHF]N[SeRNs")) {
+ KeyBoardCheatString[0] = ' ';
OnlyRenderWheelsCheat();
-
- // "CHITTYCHITTYBB"
- if ( !_CHEATCMP("BBYTTIHCYTTIHC") )
+ }
+ //COMEFLYWITHME
+ else if (!Cheat_strncmp(KeyBoardCheatString, "HROUVr\\SGPZWJ")) {
+ KeyBoardCheatString[0] = ' ';
ChittyChittyBangBangCheat();
-
- // "CORNERSLIKEMAD"
- if ( !_CHEATCMP("DAMEKILSRENROC") )
+ }
+ // "GRIPISEVERYTHING"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "JSPIatULWP`QWi_M")) {
+ KeyBoardCheatString[0] = ' ';
StrongGripCheat();
-
- // "NASTYLIMBSCHEAT"
- if ( !_CHEATCMP("TAEHCSBMILYTSAN") )
- NastyLimbsCheat();
+ }
+ // "CHASESTAT"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "WF[TRnDOD")) {
+ KeyBoardCheatString[0] = ' ';
+ DoShowChaseStatCheat();
+ }
+ // "CHICKSWITHGUNS"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "VS\\HUoL^TVPQOc")) {
+ KeyBoardCheatString[0] = ' ';
+ DoChicksWithGunsCheat();
+ }
+ // "ICANTTAKEITANYMORE"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "HWVNfiD[JPXI[t[G_\\")) {
+ KeyBoardCheatString[0] = ' ';
+ SuicideCheat();
+ }
+ // "GREENLIGHT"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "WMNJYiHLSR")) {
+ KeyBoardCheatString[0] = ' ';
+ TrafficLightsCheat();
+ }
+ // "MIAMITRAFFIC"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "FNMGNmWPNLVU")) {
+ KeyBoardCheatString[0] = ' ';
+ MadCarsCheat();
+ }
+ // "AHAIRDRESSERSCAR"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "UFJT_`VZF]QZPaUG")) {
+ KeyBoardCheatString[0] = ' ';
+ PinkCarsCheat();
+ }
+ // "IWANTITPAINTEDBLACK"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "NHHMO_H[OTNX[iaT]jS")) {
+ KeyBoardCheatString[0] = ' ';
+ BlackCarsCheat();
+ }
+ // "TRAVELINSTYLE"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "HQ`U`iLSFaNZ[")) {
+ KeyBoardCheatString[0] = ' ';
+ VehicleCheat(MI_BLOODRA);
+ }
+ // "THELASTRIDE"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "HIPSanDSFSa")) {
+ KeyBoardCheatString[0] = ' ';
+ VehicleCheat(MI_ROMERO);
+ }
+ // "ROCKANDROLLCAR"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "UFJMYjUKOLXKVr")) {
+ KeyBoardCheatString[0] = ' ';
+ VehicleCheat(MI_LOVEFIST);
+ }
+ // "RUBBISHCAR"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "UFJI`dEIV]")) {
+ KeyBoardCheatString[0] = ' ';
+ VehicleCheat(MI_TRASH);
+ }
+ // "GETTHEREQUICKLY"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "\\QRDVpTLSPU\\[eT")) {
+ KeyBoardCheatString[0] = ' ';
+ VehicleCheat(MI_BLOODRB);
+ }
+ // "GETTHEREFAST"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "WXHGRmHOU_RO")) {
+ KeyBoardCheatString[0] = ' ';
+ VehicleCheat(MI_SABRETUR);
+ }
+ // "BETTERTHANWALKING"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "JSPLY\\ZUBSaZLtaK^")) {
+ KeyBoardCheatString[0] = ' ';
+ VehicleCheat(MI_CADDY);
+ }
+ // "GETTHEREFASTINDEED"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "GJLE[dWZBQfZLvRXa[^WHL")) {
+ KeyBoardCheatString[0] = ' ';
+ VehicleCheat(MI_HOTRINA);
+ }
+ // "GETTHEREAMAZINGLYFAST"
+ else if (!Cheat_strncmp(KeyBoardCheatString, "WXHGfgJUJeNUHe_Kdg^HJ")) {
+ KeyBoardCheatString[0] = ' ';
+ VehicleCheat(MI_HOTRINB);
+ }
+ // LOOKLIKELANCE
+ else if (!Cheat_strncmp(KeyBoardCheatString, "HHUBY`NPMV\\WS")) {
+ KeyBoardCheatString[0] = ' ';
+ ChangePlayerModel("igbuddy");
+ }
+ // IWANTBIGTITS
+ else if (!Cheat_strncmp(KeyBoardCheatString, "VYPUTdE[OLdQ")) {
+ KeyBoardCheatString[0] = ' ';
+ ChangePlayerModel("igcandy");
+ }
+ // MYSONISALAWYER
+ else if (!Cheat_strncmp(KeyBoardCheatString, "UJ`XNgDZJY\\[`m")) {
+ KeyBoardCheatString[0] = ' ';
+ ChangePlayerModel("igken");
+ }
+ // ILOOKLIKEHILARY
+ else if (!Cheat_strncmp(KeyBoardCheatString, "\\WHMVcHRJWXWVlV")) {
+ KeyBoardCheatString[0] = ' ';
+ ChangePlayerModel("ighlary");
+ }
+ // ROCKANDROLLMAN
+ else if (!Cheat_strncmp(KeyBoardCheatString, "QFTMYjUKOLXKVr")) {
+ KeyBoardCheatString[0] = ' ';
+ ChangePlayerModel("igjezz");
+ }
+ // ONEARMEDBANDIT
+ else if (!Cheat_strncmp(KeyBoardCheatString, "WNKON]GLN]NMUo")) {
+ KeyBoardCheatString[0] = ' ';
+ ChangePlayerModel("igphil");
+ }
+ // IDONTHAVETHEMONEYSONNY
+ else if (!Cheat_strncmp(KeyBoardCheatString, "\\SUP`tHUPXRP[ecGdgXRGN")) {
+ KeyBoardCheatString[0] = ' ';
+ ChangePlayerModel("igsonny");
+ }
+ // FOXYLITTLETHING
+ else if (!Cheat_strncmp(KeyBoardCheatString, "JSPIa`O[UTYa_oS")) {
+ KeyBoardCheatString[0] = ' ';
+ ChangePlayerModel("igmerc");
+ }
+ // WELOVEOURDICK
+ else if (!Cheat_strncmp(KeyBoardCheatString, "NHPE_pRLWZYM^")) {
+ KeyBoardCheatString[0] = ' ';
+ ChangePlayerModel("igdick");
+ }
+ // CHEATSHAVEBEENCRACKED
+ else if (!Cheat_strncmp(KeyBoardCheatString, "GJRDNmFUFPOM]aUYpTOKF")) {
+ KeyBoardCheatString[0] = ' ';
+ ChangePlayerModel("igdiaz");
+ }
+ // DEEPFRIEDMARSBARS
+ else if (!Cheat_strncmp(KeyBoardCheatString, "VWHC`mDTEPVZMpRK")) {
+ KeyBoardCheatString[0] = ' ';
+ gfTommyFatness = 0.26f;
+ }
+ // PROGRAMMER
+ else if (!Cheat_strncmp(KeyBoardCheatString, "UJTNNmJVS[")) {
+ KeyBoardCheatString[0] = ' ';
+ gfTommyFatness = -0.3f;
+ }
+ // SEAWAYS
+ else if (!Cheat_strncmp(KeyBoardCheatString, "V^HXN`V")) {
+ KeyBoardCheatString[0] = ' ';
+ BackToTheFuture();
+ }
+ // LOADSOFLITTLETHINGS
+ else if (!Cheat_strncmp(KeyBoardCheatString, "VLUJUoHSU_VTMo`J]bV")) {
+ KeyBoardCheatString[0] = ' ';
+ SpecialCarCheats();
+ }
+ // HOPINGIRL
+ else if (!Cheat_strncmp(KeyBoardCheatString, "OWPH[dSVI")) {
+ KeyBoardCheatString[0] = ' ';
+ PickUpChicksCheat();
+ }
+ //CERTAINDEATH
+ else if (!Cheat_strncmp(KeyBoardCheatString, "KYHFQiLHU]RK")) {
+ KeyBoardCheatString[0] = ' ';
+ CSmokeTrails::CigOn = !CSmokeTrails::CigOn;
+ }
+ //AIRSHIP
+ else if (!Cheat_strncmp(KeyBoardCheatString, "SNOT_dD")) {
+ KeyBoardCheatString[0] = ' ';
+ FlyingFishCheat();
+ }
+ //FANNYMAGNET
+ else if (!Cheat_strncmp(KeyBoardCheatString, "WJUHNh\\UOLS")) {
+ KeyBoardCheatString[0] = ' ';
+ FannyMagnetCheat();
+ }
#ifdef KANGAROO_CHEAT
// "KANGAROO"
@@ -1012,19 +1559,29 @@ void CPad::AddToPCCheatString(char c)
CPed::SwitchDebugDisplay();
#endif
-#ifdef ALLCARSHELI_CHEAT
+#ifdef RESTORE_ALLCARSHELI_CHEAT
// "CARSAREHELI"
if (!_CHEATCMP("ILEHERASRAC"))
AllCarsHeliCheat();
#endif
-#ifdef ALT_DODO_CHEAT
- // "IWANTTOMASTERDODO"
- if (!_CHEATCMP("ODODRETSAMOTTNAWI"))
- AltDodoCheat();
+#ifdef WALLCLIMB_CHEAT
+ // "SPIDERCAR"
+ if (!_CHEATCMP("RACREDIPS"))
+ WallClimbingCheat();
+#endif
+
+#if !defined(PC_WATER) && defined(WATER_CHEATS)
+ // SEABEDCHEAT
+ if (!_CHEATCMP("TAEHCDEBAESON"))
+ NoSeaBedCheat();
+
+ // WATERLAYERSCHEAT
+ if (!_CHEATCMP("TAEHCSREYALRETAW"))
+ RenderWaterLayersCheat();
#endif
- #undef _CHEATCMP
+#undef _CHEATCMP
}
#ifdef XINPUT
@@ -1128,7 +1685,7 @@ void CPad::UpdatePads(void)
IsAffectedByController = false;
#endif
- if ( CReplay::IsPlayingBackFromFile() )
+ if ( CReplay::IsPlayingBackFromFile() && !FrontEndMenuManager.m_bMenuActive )
bUpdate = false;
if ( bUpdate )
@@ -1428,14 +1985,23 @@ void CPad::Update(int16 pad)
ProcessPCSpecificStuff();
+ if (NewState.CheckForInput())
+ LastTimeTouched = CTimer::GetTimeInMilliseconds();
+
if ( ++iCurrHornHistory >= HORNHISTORY_SIZE )
iCurrHornHistory = 0;
bHornHistory[iCurrHornHistory] = GetHorn();
+ for (int32 i = DRUNK_STEERING_BUFFER_SIZE - 2; i >= 0; i--) {
+ SteeringLeftRightBuffer[i + 1] = SteeringLeftRightBuffer[i];
+ }
if ( !bDisplayNoControllerMessage )
CGame::bDemoMode = false;
+
+ if ( JustOutOfFrontend != 0 )
+ --JustOutOfFrontend;
}
void CPad::DoCheats(void)
@@ -1520,12 +2086,12 @@ CPad *CPad::GetPad(int32 pad)
#define CURMODE (Mode)
#endif
-
int16 CPad::GetSteeringLeftRight(void)
{
if ( ArePlayerControlsDisabled() )
return 0;
+ int16 value;
switch (CURMODE)
{
case 0:
@@ -1535,9 +2101,12 @@ int16 CPad::GetSteeringLeftRight(void)
int16 dpad = (NewState.DPadRight - NewState.DPadLeft) / 2;
if ( Abs(axis) > Abs(dpad) )
- return axis;
+ value = axis;
else
- return dpad;
+ value = dpad;
+
+ SteeringLeftRightBuffer[0] = value;
+ value = SteeringLeftRightBuffer[DrunkDrivingBufferUsed];
break;
}
@@ -1545,13 +2114,18 @@ int16 CPad::GetSteeringLeftRight(void)
case 1:
case 3:
{
- return NewState.LeftStickX;
-
+ SteeringLeftRightBuffer[0] = NewState.LeftStickX;
+ value = SteeringLeftRightBuffer[DrunkDrivingBufferUsed];
+ break;
+ }
+ default:
+ {
+ value = 0;
break;
}
}
- return 0;
+ return value;
}
int16 CPad::GetSteeringUpDown(void)
@@ -1565,7 +2139,7 @@ int16 CPad::GetSteeringUpDown(void)
case 2:
{
int16 axis = NewState.LeftStickY;
- int16 dpad = (NewState.DPadUp - NewState.DPadDown) / 2;
+ int16 dpad = (NewState.DPadDown - NewState.DPadUp) / 2;
if ( Abs(axis) > Abs(dpad) )
return axis;
@@ -1674,7 +2248,6 @@ int16 CPad::GetPedWalkLeftRight(void)
return 0;
}
-
int16 CPad::GetPedWalkUpDown(void)
{
if ( ArePlayerControlsDisabled() )
@@ -1738,6 +2311,36 @@ int16 CPad::GetAnalogueUpDown(void)
return 0;
}
+int16 CPad::GetAnalogueLeftRight(void)
+{
+ switch (CURMODE)
+ {
+ case 0:
+ case 2:
+ {
+ int16 axis = NewState.LeftStickX;
+ int16 dpad = (NewState.DPadRight - NewState.DPadLeft) / 2;
+
+ if ( Abs(axis) > Abs(dpad) )
+ return axis;
+ else
+ return dpad;
+
+ break;
+ }
+
+ case 1:
+ case 3:
+ {
+ return NewState.LeftStickX;
+
+ break;
+ }
+ }
+
+ return 0;
+}
+
bool CPad::GetLookLeft(void)
{
if ( ArePlayerControlsDisabled() )
@@ -1849,7 +2452,6 @@ bool CPad::HornJustDown(void)
return false;
}
-
bool CPad::GetCarGunFired(void)
{
if ( ArePlayerControlsDisabled() )
@@ -1980,6 +2582,10 @@ bool CPad::GetExitVehicle(void)
if ( ArePlayerControlsDisabled() )
return false;
+
+ if ( JustOutOfFrontend != 0 )
+ return false;
+
switch (CURMODE)
{
case 0:
@@ -2007,6 +2613,9 @@ bool CPad::ExitVehicleJustDown(void)
if ( ArePlayerControlsDisabled() )
return false;
+ if ( JustOutOfFrontend != 0 )
+ return false;
+
switch (CURMODE)
{
case 0:
@@ -2133,6 +2742,53 @@ int16 CPad::GetAccelerate(void)
return 0;
}
+bool CPad::CycleCameraModeJustDown(void)
+{
+ bool result;
+ switch (CURMODE)
+ {
+ case 0:
+ case 2:
+ case 3:
+ {
+ result = !!(NewState.Select && !OldState.Select);
+
+ break;
+ }
+
+ case 1:
+ {
+ result = !!(NewState.DPadUp && !OldState.DPadUp);
+
+ break;
+ }
+ default:
+ {
+ result = false;
+ break;
+ }
+ }
+
+ if (!result)
+ {
+ switch (CURMODE)
+ {
+ case 1:
+ {
+ result = !!(NewState.DPadDown && !OldState.DPadDown);
+ break;
+ }
+ default:
+ {
+ result = false;
+ break;
+ }
+ }
+ }
+
+ return result;
+}
+
bool CPad::CycleCameraModeUpJustDown(void)
{
switch (CURMODE)
@@ -2220,7 +2876,6 @@ bool CPad::ChangeStationJustDown(void)
return false;
}
-
bool CPad::CycleWeaponLeftJustDown(void)
{
if ( ArePlayerControlsDisabled() )
@@ -2291,6 +2946,46 @@ bool CPad::TargetJustDown(void)
return false;
}
+bool CPad::CollectPickupJustDown(void)
+{
+ if ( ArePlayerControlsDisabled() )
+ return false;
+
+ switch (CURMODE)
+ {
+ case 0:
+ case 1:
+ {
+ return !!(NewState.LeftShoulder1 && !OldState.LeftShoulder1);
+
+ break;
+ }
+ case 2:
+ {
+ return !!(NewState.Triangle && !OldState.Triangle);
+
+ break;
+ }
+
+ case 3:
+ {
+ return !!(NewState.Circle && !OldState.Circle);
+
+ break;
+ }
+ }
+
+ return false;
+}
+
+bool CPad::DuckJustDown(void)
+{
+ if (ArePlayerControlsDisabled())
+ return false;
+
+ return !!(NewState.LeftShock && !OldState.LeftShock);
+}
+
bool CPad::JumpJustDown(void)
{
if ( ArePlayerControlsDisabled() )
@@ -2339,11 +3034,9 @@ bool CPad::ShiftTargetRightJustDown(void)
if ( ArePlayerControlsDisabled() )
return false;
- return !!(NewState.RightShoulder2 && !OldState.RightShoulder2);
+ return !!(NewState.LeftShoulder1 && !OldState.LeftShoulder1) || !!(NewState.RightShoulder2 && !OldState.RightShoulder2);
}
-#ifdef FIX_BUGS
-// FIX: fixes from VC for the bug of double switching the controller setup
bool CPad::GetAnaloguePadUp(void)
{
static int16 oldfStickY = 0;
@@ -2456,120 +3149,6 @@ bool CPad::GetAnaloguePadRightJustUp(void)
}
}
-#else
-bool CPad::GetAnaloguePadUp(void)
-{
- static int16 oldfStickY = 0;
-
- int16 Y = CPad::GetPad(0)->GetAnalogueUpDown();
-
- if ( Y < 0 && oldfStickY >= 0 )
- {
- oldfStickY = Y;
- return true;
- }
- else
- {
- oldfStickY = Y;
- return false;
- }
-}
-
-bool CPad::GetAnaloguePadDown(void)
-{
- static int16 oldfStickY = 0;
-
- int16 Y = CPad::GetPad(0)->GetAnalogueUpDown();
-
- if ( Y > 0 && oldfStickY <= 0 )
- {
- oldfStickY = Y;
- return true;
- }
- else
- {
- oldfStickY = Y;
- return false;
- }
-}
-
-bool CPad::GetAnaloguePadLeft(void)
-{
- static int16 oldfStickX = 0;
-
- int16 X = CPad::GetPad(0)->GetPedWalkLeftRight();
-
- if ( X < 0 && oldfStickX >= 0 )
- {
- oldfStickX = X;
- return true;
- }
- else
- {
- oldfStickX = X;
- return false;
- }
-}
-
-bool CPad::GetAnaloguePadRight(void)
-{
- static int16 oldfStickX = 0;
-
- int16 X = CPad::GetPad(0)->GetPedWalkLeftRight();
-
- if ( X > 0 && oldfStickX <= 0 )
- {
- oldfStickX = X;
- return true;
- }
- else
- {
- oldfStickX = X;
- return false;
- }
-}
-
-bool CPad::GetAnaloguePadLeftJustUp(void)
-{
- static int16 oldfStickX = 0;
-
- int16 X = GetPad(0)->GetPedWalkLeftRight();
-
- if ( X == 0 && oldfStickX < 0 )
- {
- oldfStickX = 0;
-
- return true;
- }
- else
- {
- oldfStickX = X;
-
- return false;
- }
-}
-
-bool CPad::GetAnaloguePadRightJustUp(void)
-{
- static int16 oldfStickX = 0;
-
- int16 X = GetPad(0)->GetPedWalkLeftRight();
-
- if ( X == 0 && oldfStickX > 0 )
- {
- oldfStickX = 0;
-
- return true;
- }
- else
- {
- oldfStickX = X;
-
- return false;
- }
-}
-#endif
-
bool CPad::ForceCameraBehindPlayer(void)
{
if ( ArePlayerControlsDisabled() )
@@ -2664,9 +3243,13 @@ int16 CPad::SniperModeLookLeftRight(void)
int16 axis = NewState.LeftStickX;
int16 dpad = (NewState.DPadRight - NewState.DPadLeft) / 2;
- if ( Abs(axis) > Abs(dpad) )
- return axis;
- else
+ if ( Abs(axis) > Abs(dpad) ) {
+ if ( Abs(axis) > 35.0f ) {
+ return (axis > 0.f ? axis - 35.f : axis + 35.f) * (128.f / (128 - 35));
+ } else {
+ return 0;
+ }
+ } else
return dpad;
}
@@ -2674,23 +3257,24 @@ int16 CPad::SniperModeLookUpDown(void)
{
int16 axis = NewState.LeftStickY;
int16 dpad;
+
#ifdef FIX_BUGS
axis = -axis;
#endif
-#ifndef INVERT_LOOK_FOR_PAD
- dpad = (NewState.DPadUp - NewState.DPadDown) / 2;
-#else
if (CPad::bInvertLook4Pad) {
axis = -axis;
dpad = (NewState.DPadDown - NewState.DPadUp) / 2;
} else {
dpad = (NewState.DPadUp - NewState.DPadDown) / 2;
}
-#endif
- if ( Abs(axis) > Abs(dpad) )
- return axis;
- else
+ if ( Abs(axis) > Abs(dpad) ) {
+ if ( Abs(axis) > 35.0f ) {
+ return (axis > 0.f ? axis - 35.f : axis + 35.f) * (128.f / (128 - 35));
+ } else {
+ return 0;
+ }
+ } else
return dpad;
}
@@ -2712,14 +3296,11 @@ int16 CPad::LookAroundLeftRight(void)
int16 CPad::LookAroundUpDown(void)
{
int16 axis = GetPad(0)->NewState.RightStickY;
-
#ifdef FIX_BUGS
axis = -axis;
#endif
-#ifdef INVERT_LOOK_FOR_PAD
if (CPad::bInvertLook4Pad)
axis = -axis;
-#endif
if ( Abs(axis) > 85 && !GetLookBehindForPed() )
return (int16) ( (axis + ( ( axis > 0 ) ? -85 : 85) )
@@ -2732,7 +3313,6 @@ int16 CPad::LookAroundUpDown(void)
return 0;
}
-
void CPad::ResetAverageWeapon(void)
{
AverageWeapon = GetWeapon();
@@ -2741,8 +3321,12 @@ void CPad::ResetAverageWeapon(void)
void CPad::PrintErrorMessage(void)
{
+ if (TheCamera.m_WideScreenOn)
+ return;
+
if ( bDisplayNoControllerMessage && !CGame::playingIntro && !FrontEndMenuManager.m_bMenuActive )
{
+ CSprite2d::DrawRect(CRect(SCREEN_STRETCH_X(20.0f), SCREEN_SCALE_FROM_BOTTOM(130.0f), SCREEN_STRETCH_FROM_RIGHT(20.0f), SCREEN_SCALE_Y(140.0f)), CRGBA(50, 50, 50, 210));
#ifdef FIX_BUGS
CFont::SetScale(SCREEN_SCALE_X(0.85f), SCREEN_SCALE_Y(1.0f));
#else
@@ -2758,16 +3342,17 @@ void CPad::PrintErrorMessage(void)
CFont::SetCentreOn();
CFont::SetPropOn();
CFont::SetColor(CRGBA(255, 255, 200, 200));
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
CFont::PrintString
(
SCREEN_WIDTH / 2,
- SCREEN_HEIGHT / 2,
+ SCREEN_HEIGHT / 2 - SCREEN_SCALE_Y(40.0f),
TheText.Get("NOCONT") // Please reconnect an analog controller (DUALSHOCK@) or analog controller (DUALSHOCK@2). to controller port 1 to continue
);
}
else if ( bObsoleteControllerMessage )
{
+ CSprite2d::DrawRect(CRect(SCREEN_STRETCH_X(20.0f), SCREEN_SCALE_FROM_BOTTOM(130.0f), SCREEN_STRETCH_FROM_RIGHT(20.0f), SCREEN_SCALE_Y(140.0f)), CRGBA(50, 50, 50, 210));
#ifdef FIX_BUGS
CFont::SetScale(SCREEN_SCALE_X(0.85f), SCREEN_SCALE_Y(1.0f));
#else
@@ -2783,11 +3368,11 @@ void CPad::PrintErrorMessage(void)
CFont::SetCentreOn();
CFont::SetPropOn();
CFont::SetColor(CRGBA(255, 255, 200, 200));
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
CFont::PrintString
(
SCREEN_WIDTH / 2,
- SCREEN_HEIGHT / 2,
+ SCREEN_HEIGHT / 2 - SCREEN_SCALE_Y(40.0f),
TheText.Get("WRCONT") // The controller connected to controller port 1 is an unsupported controller. Grand Theft Auto III requires an analog controller (DUALSHOCK@) or analog controller (DUALSHOCK@2).
);
}
@@ -2805,20 +3390,33 @@ void CPad::ResetCheats(void)
{
CWeather::ReleaseWeather();
+ gbFastTime = false;
CPopulation::ms_bGivePedsWeapons = false;
-
- CPed::bNastyLimbsCheat = false;
- CPed::bPedCheat2 = false;
- CPed::bPedCheat3 = false;
+ CTimer::SetTimeScale(1.0f);
CVehicle::bWheelsOnlyCheat = false;
CVehicle::bAllDodosCheat = false;
CVehicle::bCheat3 = false;
CVehicle::bCheat4 = false;
CVehicle::bCheat5 = false;
+ CVehicle::bAllTaxisHaveNitro = false;
+ CVehicle::bHoverCheat = false;
+ CVehicle::bCheat8 = false;
+ CVehicle::bCheat9 = false;
+ CVehicle::bCheat10 = false;
+#ifdef RESTORE_ALLCARSHELI_CHEAT
+ bAllCarCheat = false;
+#endif
+ gbBlackCars = false;
+ gbPinkCars = false;
+
+ CCarCtrl::bMadDriversCheat = false;
+ CTrafficLights::bGreenLightsCheat = false;
+ CStats::ShowChaseStatOnScreen = 0;
+ CPed::bNastyLimbsCheat = false;
+ CPed::bFannyMagnetCheat = false;
+ CPed::bPedCheat3 = false;
- gbFastTime = false;
- CTimer::SetTimeScale(1.0f);
}
char *CPad::EditString(char *pStr, int32 nSize)
@@ -3023,3 +3621,13 @@ int32 *CPad::EditCodesForControls(int32 *pRsKeys, int32 nSize)
return pRsKeys;
}
+
+void CPad::FixPadsAfterSave(void)
+{
+ UpdatePads();
+ if ( bObsoleteControllerMessage )
+ {
+ bObsoleteControllerMessage = false;
+ GetPad(0)->Phase = 0;
+ }
+}
diff --git a/src/core/Pad.h b/src/core/Pad.h
index b37659cd..f141ed6c 100644
--- a/src/core/Pad.h
+++ b/src/core/Pad.h
@@ -10,6 +10,7 @@ enum {
PLAYERCONTROL_PLAYERINFO = 32,
PLAYERCONTROL_PHONE = 64,
PLAYERCONTROL_CUTSCENE = 128,
+ PLAYERCONTROL_SHORTCUT_TAXI = 256,
};
class CControllerState
@@ -140,9 +141,12 @@ public:
enum
{
HORNHISTORY_SIZE = 5,
+ DRUNK_STEERING_BUFFER_SIZE = 10,
};
CControllerState NewState;
CControllerState OldState;
+ int16 SteeringLeftRightBuffer[DRUNK_STEERING_BUFFER_SIZE];
+ int32 DrunkDrivingBufferUsed;
CControllerState PCTempKeyState;
CControllerState PCTempJoyState;
CControllerState PCTempMouseState;
@@ -150,10 +154,11 @@ public:
int16 Phase;
int16 Mode;
int16 ShakeDur;
+ uint16 DisablePlayerControls;
uint8 ShakeFreq;
bool bHornHistory[HORNHISTORY_SIZE];
uint8 iCurrHornHistory;
- uint8 DisablePlayerControls;
+ int8 JustOutOfFrontend;
int8 bApplyBrakes;
char CheatString[12];
int32 LastTimeTouched;
@@ -170,14 +175,14 @@ public:
static bool bObsoleteControllerMessage;
static bool bOldDisplayNoControllerMessage;
static bool m_bMapPadOneToPadTwo;
-#ifdef INVERT_LOOK_FOR_PAD
+ static bool m_bDebugCamPCOn;
+ static bool bHasPlayerCheated;
static bool bInvertLook4Pad;
-#endif
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;
@@ -188,6 +193,7 @@ public:
#endif
void Clear(bool bResetPlayerControls);
void ClearMouseHistory();
+ void ClearKeyBoardHistory();
void UpdateMouse();
CControllerState ReconcileTwoControllersInput(CControllerState const &State1, CControllerState const &State2);
void StartShake(int16 nDur, uint8 nFreq);
@@ -217,6 +223,7 @@ public:
int16 GetPedWalkLeftRight(void);
int16 GetPedWalkUpDown(void);
int16 GetAnalogueUpDown(void);
+ int16 GetAnalogueLeftRight(void);
bool GetLookLeft(void);
bool GetLookRight(void);
bool GetLookBehindForCar(void);
@@ -232,6 +239,7 @@ public:
int32 GetWeapon(void);
bool WeaponJustDown(void);
int16 GetAccelerate(void);
+ bool CycleCameraModeJustDown(void);
bool CycleCameraModeUpJustDown(void);
bool CycleCameraModeDownJustDown(void);
bool ChangeStationJustDown(void);
@@ -239,6 +247,8 @@ public:
bool CycleWeaponRightJustDown(void);
bool GetTarget(void);
bool TargetJustDown(void);
+ bool DuckJustDown(void);
+ bool CollectPickupJustDown(void);
bool JumpJustDown(void);
bool GetSprint(void);
bool ShiftTargetLeftJustDown(void);
@@ -257,10 +267,13 @@ public:
int16 LookAroundLeftRight(void);
int16 LookAroundUpDown(void);
void ResetAverageWeapon(void);
+ static void FixPadsAfterSave(void);
static void PrintErrorMessage(void);
static void ResetCheats(void);
static char *EditString(char *pStr, int32 nSize);
static int32 *EditCodesForControls(int32 *pRsKeys, int32 nSize);
+ uint32 InputHowLongAgo(void);
+ void SetDrunkInputDelay(int32 delay) { DrunkDrivingBufferUsed = delay; }
#ifdef XINPUT
static int XInputJoy1;
@@ -425,6 +438,7 @@ public:
bool GetLeftShockJustDown() { return !!(NewState.LeftShock && !OldState.LeftShock); }
bool GetRightShockJustDown() { return !!(NewState.RightShock && !OldState.RightShock); }
bool GetStartJustDown() { return !!(NewState.Start && !OldState.Start); }
+ bool GetSelectJustDown() { return !!(NewState.Select && !OldState.Select); }
bool GetLeftStickXJustDown() { return !!(NewState.LeftStickX && !OldState.LeftStickX); }
bool GetLeftStickYJustDown() { return !!(NewState.LeftStickY && !OldState.LeftStickY); }
@@ -450,15 +464,16 @@ public:
bool GetRightShoulder1(void) { return !!NewState.RightShoulder1; }
bool GetRightShoulder2(void) { return !!NewState.RightShoulder2; }
bool GetStart() { return !!NewState.Start; }
+ bool GetSelect() { return !!NewState.Select; }
int16 GetLeftStickX(void) { return NewState.LeftStickX; }
int16 GetLeftStickY(void) { return NewState.LeftStickY; }
int16 GetRightStickX(void) { return NewState.RightStickX; }
int16 GetRightStickY(void) { return NewState.RightStickY; }
bool ArePlayerControlsDisabled(void) { return DisablePlayerControls != PLAYERCONTROL_ENABLED; }
- void SetDisablePlayerControls(uint8 who) { DisablePlayerControls |= who; }
- void SetEnablePlayerControls(uint8 who) { DisablePlayerControls &= ~who; }
- bool IsPlayerControlsDisabledBy(uint8 who) { return DisablePlayerControls & who; }
+ void SetDisablePlayerControls(uint16 who) { DisablePlayerControls |= who; }
+ void SetEnablePlayerControls(uint16 who) { DisablePlayerControls &= ~who; }
+ bool IsPlayerControlsDisabledBy(uint16 who) { return DisablePlayerControls & who; }
int16 GetMode() { return Mode; }
void SetMode(int16 mode) { Mode = mode; }
@@ -468,7 +483,3 @@ public:
VALIDATE_SIZE(CPad, 0xFC);
extern CPad Pads[MAX_PADS];
-
-#ifdef ALLCARSHELI_CHEAT
-extern bool bAllCarCheat;
-#endif
diff --git a/src/core/Placeable.cpp b/src/core/Placeable.cpp
index 162148f7..6efc1540 100644
--- a/src/core/Placeable.cpp
+++ b/src/core/Placeable.cpp
@@ -7,10 +7,6 @@ CPlaceable::CPlaceable(void)
m_matrix.SetScale(1.0f);
}
-CPlaceable::~CPlaceable(void)
-{
-}
-
void
CPlaceable::SetHeading(float angle)
{
diff --git a/src/core/Placeable.h b/src/core/Placeable.h
index 2f246bc5..94be3211 100644
--- a/src/core/Placeable.h
+++ b/src/core/Placeable.h
@@ -7,10 +7,9 @@ protected:
public:
// disable allocation
- static void *operator new(size_t) throw();
+ static void *operator new(size_t);
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;
@@ -34,4 +33,4 @@ public:
bool IsWithinArea(float x1, float y1, float z1, float x2, float y2, float z2);
};
-VALIDATE_SIZE(CPlaceable, 0x4C);
+VALIDATE_SIZE(CPlaceable, 0x48);
diff --git a/src/core/PlayerInfo.cpp b/src/core/PlayerInfo.cpp
index 91bd0691..36d05b82 100644
--- a/src/core/PlayerInfo.cpp
+++ b/src/core/PlayerInfo.cpp
@@ -31,7 +31,11 @@
#include "World.h"
#include "ZoneCull.h"
#include "main.h"
+#include "Bike.h"
+#include "Automobile.h"
+#include "GameLogic.h"
+CVector lastPlayerPos;
void
CPlayerInfo::Clear(void)
@@ -49,6 +53,8 @@ CPlayerInfo::Clear(void)
m_nTrafficMultiplier = 0;
m_fRoadDensity = 1.0f;
m_bInRemoteMode = false;
+ field_D5 = false;
+ field_D6 = false;
m_bUnusedTaxiThing = false;
m_nUnusedTaxiTimer = 0;
m_nCollectedPackages = 0;
@@ -60,14 +66,35 @@ CPlayerInfo::Clear(void)
m_nSexFrequency = 0;
m_pHooker = nil;
m_nTimeTankShotGun = 0;
- field_248 = 0;
+ field_EC = 0;
m_nUpsideDownCounter = 0;
+ m_nTimeCarSpentOnTwoWheels = 0;
+ m_nDistanceCarTravelledOnTwoWheels = 0;
+ m_nTimeNotFullyOnGround = 0;
+ m_nTimeSpentOnWheelie = 0;
+ m_nDistanceTravelledOnWheelie = 0.0f;
+ m_nTimeSpentOnStoppie = 0;
+ m_nDistanceTravelledOnStoppie = 0.0f;
+ m_nCancelWheelStuntTimer = 0;
+ m_nLastTimeCarSpentOnTwoWheels = 0;
+ m_nLastDistanceCarTravelledOnTwoWheels = 0;
+ m_nLastTimeSpentOnWheelie = 0;
+ m_nLastDistanceTravelledOnWheelie = 0;
+ m_nLastTimeSpentOnStoppie = 0;
+ m_nLastDistanceTravelledOnStoppie = 0;
m_bInfiniteSprint = false;
m_bFastReload = false;
+ m_bFireproof = false;
+ m_nMaxHealth = m_nMaxArmour = 100;
m_bGetOutOfJailFree = false;
m_bGetOutOfHospitalFree = false;
+ m_bDriveByAllowed = true;
m_nPreviousTimeRewardedForExplosion = 0;
m_nExplosionsSinceLastReward = 0;
+ m_nHavocLevel = 0;
+ m_fMediaAttention = 0.0f;
+ m_nCurrentBustedAudio = 1;
+ m_nBustedAudioStatus = BUSTEDAUDIO_NONE;
}
void
@@ -81,7 +108,7 @@ CPlayerInfo::Process(void)
bool startTaxiTimer = true;
if (m_bUnusedTaxiThing && m_pPed->bInVehicle) {
CVehicle *veh = m_pPed->m_pMyVehicle;
- if ((veh->GetModelIndex() == MI_TAXI || veh->GetModelIndex() == MI_CABBIE || veh->GetModelIndex() == MI_BORGNINE)
+ if (veh->IsTaxi()
&& veh->pDriver == m_pPed && veh->m_nNumPassengers != 0) {
for (uint32 timePassed = CTimer::GetTimeInMilliseconds() - m_nUnusedTaxiTimer; timePassed >= 1000; m_nUnusedTaxiTimer += 1000) {
timePassed -= 1000;
@@ -93,6 +120,157 @@ CPlayerInfo::Process(void)
if (startTaxiTimer)
m_nUnusedTaxiTimer = CTimer::GetTimeInMilliseconds();
+ if (!m_pPed->InVehicle()) {
+ m_nTimeCarSpentOnTwoWheels = 0;
+ m_nTimeNotFullyOnGround = 0;
+ m_nTimeSpentOnWheelie = 0;
+ m_nTimeSpentOnStoppie = 0;
+ m_nCancelWheelStuntTimer = 0;
+ } else if (m_pPed->m_pMyVehicle->IsCar()) {
+ CAutomobile *car = (CAutomobile*)m_pPed->m_pMyVehicle;
+
+ if (car->m_nWheelsOnGround < 3)
+ m_nTimeNotFullyOnGround += CTimer::GetTimeStepInMilliseconds();
+ else
+ m_nTimeNotFullyOnGround = 0;
+
+ if (car->m_aSuspensionSpringRatioPrev[2] == 1.f && car->m_aSuspensionSpringRatioPrev[3] == 1.f) {
+ if (car->m_aSuspensionSpringRatioPrev[0] < 1.0f && car->m_aSuspensionSpringRatioPrev[1] < 1.0f && car->m_fDamageImpulse == 0.0f) {
+ m_nTimeCarSpentOnTwoWheels += CTimer::GetTimeStepInMilliseconds();
+ m_nDistanceCarTravelledOnTwoWheels += car->m_fDistanceTravelled;
+ m_nCancelWheelStuntTimer = Max(0.0f, m_nCancelWheelStuntTimer - CTimer::GetTimeStepInMilliseconds() * 0.5f);
+
+ } else {
+ if (m_nTimeCarSpentOnTwoWheels != 0 && m_nCancelWheelStuntTimer < 500) {
+ m_nCancelWheelStuntTimer += CTimer::GetTimeStepInMilliseconds();
+ } else {
+ if (m_nTimeCarSpentOnTwoWheels >= 2000) {
+ m_nLastTimeCarSpentOnTwoWheels = m_nTimeCarSpentOnTwoWheels;
+ m_nLastDistanceCarTravelledOnTwoWheels = m_nDistanceCarTravelledOnTwoWheels;
+ if (CStats::Longest2Wheel < m_nTimeCarSpentOnTwoWheels / 1000)
+ CStats::Longest2Wheel = m_nTimeCarSpentOnTwoWheels / 1000;
+ if (CStats::Longest2WheelDist < m_nDistanceCarTravelledOnTwoWheels)
+ CStats::Longest2WheelDist = m_nDistanceCarTravelledOnTwoWheels;
+ }
+ m_nTimeCarSpentOnTwoWheels = 0;
+ m_nDistanceCarTravelledOnTwoWheels = 0;
+ m_nCancelWheelStuntTimer = 0;
+ }
+ }
+ } else if (car->m_aSuspensionSpringRatioPrev[0] == 1.0f && car->m_aSuspensionSpringRatioPrev[1] == 1.0f) {
+#ifdef FIX_BUGS
+ if (car->m_aSuspensionSpringRatioPrev[2] < 1.f
+#else
+ if (car->m_aSuspensionSpringRatioPrev[1] < 1.f
+#endif
+ && car->m_aSuspensionSpringRatioPrev[3] < 1.f && 0.0f == car->m_fDamageImpulse) {
+ m_nTimeCarSpentOnTwoWheels += CTimer::GetTimeStepInMilliseconds();
+ m_nDistanceCarTravelledOnTwoWheels += car->m_fDistanceTravelled;
+ m_nCancelWheelStuntTimer = Max(0.0f, m_nCancelWheelStuntTimer - CTimer::GetTimeStepInMilliseconds() * 0.2f);
+
+ } else if (m_nTimeCarSpentOnTwoWheels != 0 && m_nCancelWheelStuntTimer < 500) {
+ m_nCancelWheelStuntTimer += CTimer::GetTimeStepInMilliseconds();
+
+ } else {
+ if (m_nTimeCarSpentOnTwoWheels >= 2000) {
+ m_nLastTimeCarSpentOnTwoWheels = m_nTimeCarSpentOnTwoWheels;
+ m_nLastDistanceCarTravelledOnTwoWheels = m_nDistanceCarTravelledOnTwoWheels;
+ if (CStats::Longest2Wheel < m_nTimeCarSpentOnTwoWheels / 1000)
+ CStats::Longest2Wheel = m_nTimeCarSpentOnTwoWheels / 1000;
+ if (CStats::Longest2WheelDist < m_nDistanceCarTravelledOnTwoWheels)
+ CStats::Longest2WheelDist = m_nDistanceCarTravelledOnTwoWheels;
+ }
+ m_nTimeCarSpentOnTwoWheels = 0;
+ m_nDistanceCarTravelledOnTwoWheels = 0;
+ m_nCancelWheelStuntTimer = 0;
+ }
+ } else if (m_nTimeCarSpentOnTwoWheels != 0) {
+ if (m_nTimeCarSpentOnTwoWheels >= 2000) {
+ m_nLastTimeCarSpentOnTwoWheels = m_nTimeCarSpentOnTwoWheels;
+ m_nLastDistanceCarTravelledOnTwoWheels = m_nDistanceCarTravelledOnTwoWheels;
+ if (CStats::Longest2Wheel < m_nTimeCarSpentOnTwoWheels / 1000)
+ CStats::Longest2Wheel = m_nTimeCarSpentOnTwoWheels / 1000;
+ if (CStats::Longest2WheelDist < m_nDistanceCarTravelledOnTwoWheels)
+ CStats::Longest2WheelDist = m_nDistanceCarTravelledOnTwoWheels;
+ }
+ m_nTimeCarSpentOnTwoWheels = 0;
+ m_nDistanceCarTravelledOnTwoWheels = 0;
+ m_nCancelWheelStuntTimer = 0;
+ }
+ m_nTimeSpentOnWheelie = 0;
+ m_nTimeSpentOnStoppie = 0;
+ } else if (m_pPed->m_pMyVehicle->IsBike()) {
+ CBike *bike = (CBike*)m_pPed->m_pMyVehicle;
+ if (bike->m_aSuspensionSpringRatioPrev[0] == 1.0f && bike->m_aSuspensionSpringRatioPrev[1] == 1.0f) {
+ if (bike->m_aSuspensionSpringRatioPrev[2] < 1.0f
+ || (bike->m_aSuspensionSpringRatioPrev[3] < 1.0f && 0.0f == bike->m_fDamageImpulse)) {
+ m_nTimeSpentOnWheelie += CTimer::GetTimeStepInMilliseconds();
+ m_nDistanceTravelledOnWheelie += bike->m_fDistanceTravelled;
+ m_nCancelWheelStuntTimer = Max(0.0f, m_nCancelWheelStuntTimer - CTimer::GetTimeStepInMilliseconds() * 0.2f);
+
+ } else {
+ if (m_nTimeSpentOnWheelie != 0 && m_nCancelWheelStuntTimer < 500) {
+ m_nCancelWheelStuntTimer += CTimer::GetTimeStepInMilliseconds();
+ } else {
+ if (m_nTimeSpentOnWheelie >= 5000) {
+ m_nLastTimeSpentOnWheelie = m_nTimeSpentOnWheelie;
+ m_nLastDistanceTravelledOnWheelie = m_nDistanceTravelledOnWheelie;
+ if (CStats::LongestWheelie < m_nTimeSpentOnWheelie / 1000)
+ CStats::LongestWheelie = m_nTimeSpentOnWheelie / 1000;
+ if (CStats::LongestWheelieDist < m_nDistanceTravelledOnWheelie)
+ CStats::LongestWheelieDist = m_nDistanceTravelledOnWheelie;
+ }
+ m_nTimeSpentOnWheelie = 0;
+ m_nDistanceTravelledOnWheelie = 0;
+ m_nCancelWheelStuntTimer = 0;
+ }
+ }
+ } else if (m_nTimeSpentOnWheelie != 0) {
+ if (m_nTimeSpentOnWheelie >= 5000) {
+ m_nLastTimeSpentOnWheelie = m_nTimeSpentOnWheelie;
+ m_nLastDistanceTravelledOnWheelie = m_nDistanceTravelledOnWheelie;
+ if (CStats::LongestWheelie < m_nTimeSpentOnWheelie / 1000)
+ CStats::LongestWheelie = m_nTimeSpentOnWheelie / 1000;
+ if (CStats::LongestWheelieDist < m_nDistanceTravelledOnWheelie)
+ CStats::LongestWheelieDist = m_nDistanceTravelledOnWheelie;
+ }
+ m_nTimeSpentOnWheelie = 0;
+ m_nDistanceTravelledOnWheelie = 0;
+ m_nCancelWheelStuntTimer = 0;
+
+ } else if (bike->m_aSuspensionSpringRatioPrev[2] == 1.0f && bike->m_aSuspensionSpringRatioPrev[3] == 1.0f
+ && 0.0f == bike->m_fDamageImpulse) {
+ m_nTimeSpentOnStoppie += CTimer::GetTimeStepInMilliseconds();
+ m_nDistanceTravelledOnStoppie += bike->m_fDistanceTravelled;
+ m_nCancelWheelStuntTimer = Max(0.0f, m_nCancelWheelStuntTimer - CTimer::GetTimeStepInMilliseconds() * 0.2f);
+
+ } else {
+ if (m_nTimeSpentOnStoppie != 0 && m_nCancelWheelStuntTimer < 500) {
+ m_nCancelWheelStuntTimer += CTimer::GetTimeStepInMilliseconds();
+ } else {
+ if (m_nTimeSpentOnStoppie >= 2000) {
+ m_nLastTimeSpentOnStoppie = m_nTimeSpentOnStoppie;
+ m_nLastDistanceTravelledOnStoppie = m_nDistanceTravelledOnStoppie;
+ if (CStats::LongestStoppie < m_nTimeSpentOnStoppie / 1000)
+ CStats::LongestStoppie = m_nTimeSpentOnStoppie / 1000;
+ if (CStats::LongestStoppieDist < m_nDistanceTravelledOnStoppie)
+ CStats::LongestStoppieDist = m_nDistanceTravelledOnStoppie;
+ }
+ m_nTimeSpentOnStoppie = 0;
+ m_nDistanceTravelledOnStoppie = 0;
+ m_nCancelWheelStuntTimer = 0;
+ }
+ }
+ m_nTimeCarSpentOnTwoWheels = 0;
+ m_nTimeNotFullyOnGround = 0;
+ } else {
+ m_nTimeCarSpentOnTwoWheels = 0;
+ m_nTimeNotFullyOnGround = 0;
+ m_nTimeSpentOnWheelie = 0;
+ m_nTimeSpentOnStoppie = 0;
+ m_nCancelWheelStuntTimer = 0;
+ }
+
// The effect that makes money counter does while earning/losing money
if (m_nVisibleMoney != m_nMoney) {
int diff = m_nMoney - m_nVisibleMoney;
@@ -121,7 +299,7 @@ CPlayerInfo::Process(void)
m_fRoadDensity = ThePaths.CalcRoadDensity(playerPos.x, playerPos.y);
}
- m_fRoadDensity = Clamp(m_fRoadDensity, 0.4f, 1.45f);
+ m_fRoadDensity = Clamp(m_fRoadDensity, 0.5f, 1.45f);
// Because vehicle enter/exit use same key binding.
bool enterOrExitVeh;
@@ -130,39 +308,31 @@ CPlayerInfo::Process(void)
else
enterOrExitVeh = CPad::GetPad(0)->GetExitVehicle();
- if (enterOrExitVeh && m_pPed->m_nPedState != PED_SNIPER_MODE && m_pPed->m_nPedState != PED_ROCKET_MODE) {
+ if (enterOrExitVeh && m_pPed->m_nPedState != PED_ANSWER_MOBILE && m_pPed->m_nPedState != PED_SNIPER_MODE && m_pPed->m_nPedState != PED_ROCKET_MODE) {
if (m_pPed->bInVehicle) {
if (!m_pRemoteVehicle) {
CEntity *surfaceBelowVeh = m_pPed->m_pMyVehicle->m_pCurGroundEntity;
if (!surfaceBelowVeh || !CBridge::ThisIsABridgeObjectMovingUp(surfaceBelowVeh->GetModelIndex())) {
CVehicle *veh = m_pPed->m_pMyVehicle;
if (!veh->IsBoat() || veh->m_nDoorLock == CARLOCK_LOCKED_PLAYER_INSIDE) {
+ if (veh->GetStatus() != STATUS_WRECKED && veh->GetStatus() != STATUS_TRAIN_MOVING && veh->m_nDoorLock != CARLOCK_LOCKED_PLAYER_INSIDE) {
+ bool canJumpOff = false;
+ if (veh->m_vehType == VEHICLE_TYPE_BIKE) {
+ canJumpOff = veh->CanPedJumpOffBike();
+ } else if (veh->pDriver == m_pPed) {
+ canJumpOff = veh->CanPedJumpOutCar();
+ }
- // This condition will always return true, else block was probably WIP Miami code.
- if (veh->m_vehType != VEHICLE_TYPE_BIKE || veh->m_nDoorLock == CARLOCK_LOCKED_PLAYER_INSIDE) {
- if (veh->GetStatus() != STATUS_WRECKED && veh->GetStatus() != STATUS_TRAIN_MOVING && veh->m_nDoorLock != CARLOCK_LOCKED_PLAYER_INSIDE) {
- if (veh->m_vecMoveSpeed.Magnitude() < 0.17f && CTimer::GetTimeScale() >= 0.5f && !veh->bIsInWater) {
+ if (canJumpOff || veh->m_vecMoveSpeed.Magnitude() < 0.1f) {
+ if (!veh->bIsInWater)
m_pPed->SetObjective(OBJECTIVE_LEAVE_CAR, veh);
- }
+
+ } else if (veh->GetStatus() != STATUS_PLAYER && veh != CGameLogic::pShortCutTaxi) {
+ veh->AutoPilot.m_nTempAction = TEMPACT_WAIT;
+ veh->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 1000;
}
- } else {
- CVector sth = 0.7f * veh->GetRight() + veh->GetPosition();
- bool found = false;
- float groundZ = CWorld::FindGroundZFor3DCoord(sth.x, sth.y, 2.0f + sth.z, &found);
-
- if (found)
- sth.z = 1.0f + groundZ;
- m_pPed->SetPedState(PED_IDLE);
- m_pPed->SetMoveState(PEDMOVE_STILL);
- CPed::PedSetOutCarCB(0, m_pPed);
- CAnimManager::BlendAnimation(m_pPed->GetClump(), m_pPed->m_animGroup, ANIM_STD_IDLE, 100.0f);
- CAnimManager::BlendAnimation(m_pPed->GetClump(), ASSOCGRP_STD, ANIM_STD_FALL_LAND, 100.0f);
- m_pPed->SetPosition(sth);
- m_pPed->SetMoveState(PEDMOVE_STILL);
- m_pPed->m_vecMoveSpeed = veh->m_vecMoveSpeed;
}
} else {
- // The code in here was under CPed::SetExitBoat in VC, did the same for here.
m_pPed->SetExitBoat(veh);
m_pPed->bTryingToReachDryLand = true;
}
@@ -177,14 +347,10 @@ CPlayerInfo::Process(void)
CEntity *surfaceBelow = m_pPed->m_pCurrentPhysSurface;
if (surfaceBelow && surfaceBelow->IsVehicle()) {
carBelow = (CVehicle*)surfaceBelow;
- if (carBelow->IsBoat()) {
+ if (carBelow->IsBoat() && carBelow->m_modelIndex != MI_SKIMMER) {
weAreOnBoat = true;
m_pPed->bOnBoat = true;
-#ifdef VC_PED_PORTS
if (carBelow->GetStatus() != STATUS_WRECKED && carBelow->GetUp().z > 0.3f)
-#else
- if (carBelow->GetStatus() != STATUS_WRECKED)
-#endif
m_pPed->SetSeekBoatPosition(carBelow);
}
}
@@ -232,14 +398,15 @@ CPlayerInfo::Process(void)
}
}
}
+
if (m_bInRemoteMode) {
uint32 timeWithoutRemoteCar = CTimer::GetTimeInMilliseconds() - m_nTimeLostRemoteCar;
- if (CTimer::GetPreviousTimeInMilliseconds() - m_nTimeLostRemoteCar < 1000 && timeWithoutRemoteCar >= 1000 && m_WBState == WBSTATE_PLAYING) {
+ if (CTimer::GetPreviousTimeInMilliseconds() - m_nTimeLostRemoteCar < 1000 && timeWithoutRemoteCar >= 1000 && m_WBState == WBSTATE_PLAYING && field_D6) {
TheCamera.SetFadeColour(0, 0, 0);
TheCamera.Fade(1.0f, FADE_OUT);
}
if (timeWithoutRemoteCar > 2000) {
- if (m_WBState == WBSTATE_PLAYING) {
+ if (m_WBState == WBSTATE_PLAYING && field_D6) {
TheCamera.RestoreWithJumpCut();
TheCamera.SetFadeColour(0, 0, 0);
TheCamera.Fade(1.0f, FADE_IN);
@@ -251,6 +418,7 @@ CPlayerInfo::Process(void)
CTimer::Update();
}
m_bInRemoteMode = false;
+ CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->bRemoveFromWorld = true;
CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle = nil;
if (FindPlayerVehicle()) {
FindPlayerVehicle()->SetStatus(STATUS_PLAYER);
@@ -260,11 +428,10 @@ CPlayerInfo::Process(void)
if (!(CTimer::GetFrameCounter() & 31)) {
CVehicle *veh = FindPlayerVehicle();
if (veh && m_pPed->bInVehicle && veh->GetUp().z < 0.0f
- && veh->m_vecMoveSpeed.Magnitude() < 0.05f && veh->IsCar() && !veh->bIsInWater) {
+ && veh->m_vecMoveSpeed.Magnitude() < 0.05f && (veh->IsCar() || veh->IsBoat()) && !veh->bIsInWater) {
if (veh->GetUp().z < -0.5f) {
m_nUpsideDownCounter += 2;
-
} else {
m_nUpsideDownCounter++;
}
@@ -288,10 +455,76 @@ CPlayerInfo::Process(void)
if (veh->pPassengers[i])
veh->pPassengers[i]->m_nZoneLevel = LEVEL_GENERIC;
}
- CStats::DistanceTravelledInVehicle += veh->m_fDistanceTravelled;
+ if(veh->m_modelIndex == MI_CADDY)
+ CStats::DistanceTravelledByGolfCart += veh->m_fDistanceTravelled;
+ else {
+ if(veh->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI)
+ CStats::DistanceTravelledByHelicoptor += veh->m_fDistanceTravelled;
+ if (veh->GetVehicleAppearance() == VEHICLE_APPEARANCE_PLANE)
+ CStats::DistanceTravelledByPlane += veh->m_fDistanceTravelled;
+ if (veh->GetVehicleAppearance() == VEHICLE_APPEARANCE_CAR)
+ CStats::DistanceTravelledByCar += veh->m_fDistanceTravelled;
+ if (veh->GetVehicleAppearance() == VEHICLE_APPEARANCE_BIKE)
+ CStats::DistanceTravelledByBike += veh->m_fDistanceTravelled;
+ if (veh->GetVehicleAppearance() == VEHICLE_APPEARANCE_BOAT)
+ CStats::DistanceTravelledByBoat += veh->m_fDistanceTravelled;
+
+ if (veh->GetVehicleAppearance() == VEHICLE_APPEARANCE_PLANE) {
+ if (veh->m_vecMoveSpeed.Magnitude() > 0.2f) {
+ CStats::FlightTime += CTimer::GetTimeStep() * 16.f; // what a weird choice
+ }
+ }
+ }
} else {
CStats::DistanceTravelledOnFoot += FindPlayerPed()->m_fDistanceTravelled;
}
+
+ if (m_pPed->m_pWanted->GetWantedLevel() && !CTheScripts::IsPlayerOnAMission()) {
+ float maxDelta = 0.0f;
+ static bool movedSignificantly = true;
+ static bool thereIsACarPathNear = true;
+ // there was one more guard without variable's itself???
+
+ if (CTimer::GetTimeInMilliseconds() / 20000 != CTimer::GetPreviousTimeInMilliseconds() / 20000) {
+ float posChange = (lastPlayerPos - FindPlayerCoors()).Magnitude();
+ movedSignificantly = posChange >= 10.0f;
+ lastPlayerPos = FindPlayerCoors();
+ thereIsACarPathNear = ThePaths.FindNodeClosestToCoors(FindPlayerCoors(), PATH_CAR, 60.0f, true, false, false, false) != 0;
+ }
+ switch (m_pPed->m_pWanted->GetWantedLevel()) {
+ case 1:
+ maxDelta = 31.f;
+ break;
+ case 2:
+ maxDelta = 62.f;
+ break;
+ case 3:
+ maxDelta = 125.f;
+ break;
+ case 4:
+ maxDelta = 250.f;
+ break;
+ case 5:
+ maxDelta = 500.f;
+ break;
+ case 6:
+ maxDelta = 1000.f;
+ break;
+ default:
+ break;
+ }
+ float increaseDelta = maxDelta - m_fMediaAttention;
+ float increaseAttentionBy = CTimer::GetTimeStep() * 0.0001f * increaseDelta;
+ if (increaseAttentionBy < 0.0f
+ || movedSignificantly && thereIsACarPathNear && !CCullZones::NoPolice() && !CCullZones::PoliceAbandonCars() && CGame::currArea == AREA_MAIN_MAP) {
+ m_fMediaAttention += increaseAttentionBy;
+ }
+ } else {
+ m_fMediaAttention = 0.0f;
+ }
+ CStats::HighestChaseValue = Max(m_fMediaAttention, CStats::HighestChaseValue);
+ m_nMoney = Min(999999999, m_nMoney);
+ m_nVisibleMoney = Min(999999999, m_nVisibleMoney);
}
bool
@@ -317,9 +550,15 @@ CPlayerInfo::SavePlayerInfo(uint8 *buf, uint32 *size)
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFastReload);
+ CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFireproof);
+ CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMaxHealth);
+ CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMaxArmour);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree);
+ CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bDriveByAllowed);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName);
+ CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nBustedAudioStatus);
+ CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCurrentBustedAudio);
#undef CopyToBuf
}
@@ -337,9 +576,15 @@ CPlayerInfo::LoadPlayerInfo(uint8 *buf, uint32 size)
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFastReload);
+ CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFireproof);
+ CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMaxHealth);
+ CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMaxArmour);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree);
- CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName)
+ CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bDriveByAllowed);
+ CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName);
+ CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nBustedAudioStatus);
+ CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCurrentBustedAudio)
#undef CopyFromBuf
}
@@ -357,7 +602,7 @@ CPlayerInfo::FindClosestCarSectorList(CPtrList& carList, CPed* ped, float unk1,
&& (car->GetUp().z > 0.3f || (car->IsVehicle() && ((CVehicle*)car)->m_vehType == VEHICLE_TYPE_BIKE))) {
CVector carCentre = car->GetBoundCentre();
- if (Abs(ped->GetPosition().z - carCentre.z) < 2.0f) {
+ if (Abs(ped->GetPosition().z - carCentre.z) < 2.0f || car->IsCar() && carCentre.z < ped->GetPosition().z && ped->GetPosition().z - 4.f < carCentre.z) {
float dist = (ped->GetPosition() - carCentre).Magnitude2D();
if (dist <= 10.0f && !CCranes::IsThisCarBeingCarriedByAnyCrane(car)) {
EvaluateCarPosition(car, ped, dist, lastCloseness, closestCarOutput);
@@ -531,6 +776,7 @@ CPlayerInfo::ArrestPlayer()
m_WBState = WBSTATE_BUSTED;
m_nWBTime = CTimer::GetTimeInMilliseconds();
+ m_nBustedAudioStatus = BUSTEDAUDIO_NONE;
CDarkel::ResetOnPlayerDeath();
CMessages::AddBigMessage(TheText.Get("BUSTED"), 5000, 2);
CStats::TimesArrested++;
@@ -561,7 +807,6 @@ void
CPlayerInfo::MakePlayerSafe(bool toggle)
{
if (toggle) {
- CTheScripts::ResetCountdownToMakePlayerUnsafe();
m_pPed->m_pWanted->m_bIgnoredByEveryone = true;
CWorld::StopAllLawEnforcersInTheirTracks();
CPad::GetPad(0)->SetDisablePlayerControls(PLAYERCONTROL_PLAYERINFO);
@@ -582,7 +827,7 @@ 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)->SetEnablePlayerControls(PLAYERCONTROL_PLAYERINFO);
m_pPed->bBulletProof = false;
@@ -598,39 +843,14 @@ CPlayerInfo::MakePlayerSafe(bool toggle)
}
void
-CPlayerInfo::BlowUpRCBuggy(void)
+CPlayerInfo::BlowUpRCBuggy(bool actually)
{
if (!m_pRemoteVehicle || m_pRemoteVehicle->bRemoveFromWorld)
return;
- CRemote::TakeRemoteControlledCarFromPlayer();
- m_pRemoteVehicle->BlowUpCar(FindPlayerPed());
-}
-
-// There is something unfinished in here... Sadly all IDBs we have have it unfinished.
-void
-CPlayerInfo::AwardMoneyForExplosion(CVehicle *wreckedCar)
-{
- if (CTimer::GetTimeInMilliseconds() - m_nPreviousTimeRewardedForExplosion < 6000)
- ++m_nExplosionsSinceLastReward;
- else
- m_nExplosionsSinceLastReward = 1;
-
- m_nPreviousTimeRewardedForExplosion = CTimer::GetTimeInMilliseconds();
- int award = wreckedCar->pHandling->nMonetaryValue * 0.002f;
- sprintf(gString, "$%d", award);
-#ifdef MONEY_MESSAGES
- // This line is a leftover from PS2, I don't know what it was meant to be.
- // CVector sth(TheCamera.GetPosition() * 4.0f);
-
- CMoneyMessages::RegisterOne(wreckedCar->GetPosition() + CVector(0.0f, 0.0f, 2.0f), gString, 0, 255, 0, 2.0f, 0.5f);
-#endif
- CWorld::Players[CWorld::PlayerInFocus].m_nMoney += award;
-
- for (int i = m_nExplosionsSinceLastReward; i > 1; --i) {
- CGeneral::GetRandomNumber();
- CWorld::Players[CWorld::PlayerInFocus].m_nMoney += award;
- }
+ CRemote::TakeRemoteControlledCarFromPlayer(actually);
+ if (actually)
+ m_pRemoteVehicle->BlowUpCar(FindPlayerPed());
}
#ifdef GTA_PC
@@ -647,8 +867,6 @@ CPlayerInfo::LoadPlayerSkin()
DeletePlayerSkin();
m_pSkinTexture = CPlayerSkin::GetSkinTexture(m_aSkinName);
- if (!m_pSkinTexture)
- m_pSkinTexture = CPlayerSkin::GetSkinTexture(DEFAULT_SKIN_NAME);
}
void
@@ -659,4 +877,4 @@ CPlayerInfo::DeletePlayerSkin()
m_pSkinTexture = nil;
}
}
-#endif \ No newline at end of file
+#endif
diff --git a/src/core/PlayerInfo.h b/src/core/PlayerInfo.h
index 956756e4..fc12267d 100644
--- a/src/core/PlayerInfo.h
+++ b/src/core/PlayerInfo.h
@@ -10,6 +10,13 @@ enum eWastedBustedState
WBSTATE_FAILED_CRITICAL_MISSION,
};
+enum eBustedAudioState
+{
+ BUSTEDAUDIO_NONE,
+ BUSTEDAUDIO_LOADING,
+ BUSTEDAUDIO_DONE
+};
+
class CEntity;
class CPed;
class CVehicle;
@@ -38,29 +45,51 @@ public:
int8 m_WBState; // eWastedBustedState
uint32 m_nWBTime;
bool m_bInRemoteMode;
+ bool field_D5;
+ bool field_D6;
uint32 m_nTimeLostRemoteCar;
uint32 m_nTimeLastHealthLoss;
uint32 m_nTimeLastArmourLoss;
uint32 m_nTimeTankShotGun;
int32 m_nUpsideDownCounter;
- int32 field_248;
+ int32 field_EC;
+ int32 m_nTimeCarSpentOnTwoWheels;
+ float m_nDistanceCarTravelledOnTwoWheels;
+ int32 m_nTimeNotFullyOnGround;
+ int32 m_nTimeSpentOnWheelie;
+ float m_nDistanceTravelledOnWheelie;
+ int32 m_nTimeSpentOnStoppie;
+ float m_nDistanceTravelledOnStoppie;
+ int32 m_nCancelWheelStuntTimer;
+ int32 m_nLastTimeCarSpentOnTwoWheels;
+ float m_nLastDistanceCarTravelledOnTwoWheels;
+ int32 m_nLastTimeSpentOnWheelie;
+ float m_nLastDistanceTravelledOnWheelie;
+ int32 m_nLastTimeSpentOnStoppie;
+ float m_nLastDistanceTravelledOnStoppie;
int16 m_nTrafficMultiplier;
+ int16 field_12A;
float m_fRoadDensity;
uint32 m_nPreviousTimeRewardedForExplosion;
- int32 m_nExplosionsSinceLastReward;
- int32 field_268;
- int32 field_272;
+ uint32 m_nExplosionsSinceLastReward;
+ 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;
+ uint8 m_nBustedAudioStatus;
+ int16 m_nCurrentBustedAudio;
#ifdef GTA_PC
char m_aSkinName[32];
RwTexture *m_pSkinTexture;
#endif
void MakePlayerSafe(bool);
- void AwardMoneyForExplosion(CVehicle *vehicle);
const CVector &GetPos();
void Process(void);
void KillPlayer(void);
@@ -68,7 +97,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);
@@ -92,6 +121,4 @@ CVector FindPlayerCoors(void);
const CVector &FindPlayerSpeed(void);
const CVector &FindPlayerCentreOfWorld(int32 player);
const CVector &FindPlayerCentreOfWorld_NoSniperShift(void);
-float FindPlayerHeading(void);
-
-VALIDATE_SIZE(CPlayerInfo, 0x13C);
+float FindPlayerHeading(void); \ No newline at end of file
diff --git a/src/core/Pools.cpp b/src/core/Pools.cpp
index b0248664..e601b3c8 100644
--- a/src/core/Pools.cpp
+++ b/src/core/Pools.cpp
@@ -2,6 +2,7 @@
#include "Pools.h"
+#include "Bike.h"
#include "Boat.h"
#include "CarCtrl.h"
#ifdef MISSION_REPLAY
@@ -14,6 +15,7 @@
#include "Wanted.h"
#include "World.h"
#include "MemoryHeap.h"
+#include "SaveBuf.h"
CCPtrNodePool *CPools::ms_pPtrNodePool;
CEntryInfoNodePool *CPools::ms_pEntryInfoNodePool;
@@ -24,8 +26,10 @@ CTreadablePool *CPools::ms_pTreadablePool;
CObjectPool *CPools::ms_pObjectPool;
CDummyPool *CPools::ms_pDummyPool;
CAudioScriptObjectPool *CPools::ms_pAudioScriptObjectPool;
+CColModelPool *CPools::ms_pColModelPool;
-#ifdef GTA_PS2 // or USE_CUSTOM_ALLOCATOR
+#if defined GTA_PS2 && !defined MASTER // or USE_CUSTOM_ALLOCATOR
+// not in VC. perhaps ifdef'ed away
#define CHECKMEM(msg) CMemCheck::AllocateMemCheckBlock(msg)
#else
#define CHECKMEM(msg)
@@ -36,23 +40,25 @@ CPools::Initialise(void)
{
PUSH_MEMID(MEMID_POOLS);
CHECKMEM("before pools");
- ms_pPtrNodePool = new CCPtrNodePool(NUMPTRNODES);
+ ms_pPtrNodePool = new CCPtrNodePool(NUMPTRNODES, "PtrNode");
CHECKMEM("after CPtrNodePool");
- ms_pEntryInfoNodePool = new CEntryInfoNodePool(NUMENTRYINFOS);
+ ms_pEntryInfoNodePool = new CEntryInfoNodePool(NUMENTRYINFOS, "EntryInfoNode");
CHECKMEM("after CEntryInfoNodePool");
- ms_pPedPool = new CPedPool(NUMPEDS);
+ ms_pPedPool = new CPedPool(NUMPEDS, "Peds");
CHECKMEM("after CPedPool");
- ms_pVehiclePool = new CVehiclePool(NUMVEHICLES);
+ ms_pVehiclePool = new CVehiclePool(NUMVEHICLES, "Vehicles");
CHECKMEM("after CVehiclePool");
- ms_pBuildingPool = new CBuildingPool(NUMBUILDINGS);
+ ms_pBuildingPool = new CBuildingPool(NUMBUILDINGS, "Buildings");
CHECKMEM("after CBuildingPool");
- ms_pTreadablePool = new CTreadablePool(NUMTREADABLES);
+ ms_pTreadablePool = new CTreadablePool(NUMTREADABLES, "Treadables");
CHECKMEM("after CTreadablePool");
- ms_pObjectPool = new CObjectPool(NUMOBJECTS);
+ ms_pObjectPool = new CObjectPool(NUMOBJECTS, "Objects");
CHECKMEM("after CObjectPool");
- ms_pDummyPool = new CDummyPool(NUMDUMMIES);
+ ms_pDummyPool = new CDummyPool(NUMDUMMIES, "Dummys");
CHECKMEM("after CDummyPool");
- ms_pAudioScriptObjectPool = new CAudioScriptObjectPool(NUMAUDIOSCRIPTOBJECTS);
+ ms_pAudioScriptObjectPool = new CAudioScriptObjectPool(NUMAUDIOSCRIPTOBJECTS, "AudioScriptObj");
+ CHECKMEM("after cAudioScriptObjectPool");
+ ms_pColModelPool = new CColModelPool(NUMCOLMODELS, "ColModel");
CHECKMEM("after pools");
POP_MEMID();
}
@@ -69,6 +75,7 @@ CPools::ShutDown(void)
debug("Objects left %d\n", ms_pObjectPool->GetNoOfUsedSpaces());
debug("Dummys left %d\n", ms_pDummyPool->GetNoOfUsedSpaces());
debug("AudioScriptObjects left %d\n", ms_pAudioScriptObjectPool->GetNoOfUsedSpaces());
+ debug("ColModels left %d\n", ms_pColModelPool->GetNoOfUsedSpaces());
printf("Shutdown pool started\n");
delete ms_pPtrNodePool;
@@ -80,6 +87,7 @@ CPools::ShutDown(void)
delete ms_pObjectPool;
delete ms_pDummyPool;
delete ms_pAudioScriptObjectPool;
+ delete ms_pColModelPool;
printf("Shutdown pool done\n");
}
@@ -99,7 +107,7 @@ CPools::CheckPoolsEmpty()
printf("pools have been cleared\n");
}
-
+// Thankfully unused, it would break the game!
void
CPools::MakeSureSlotInObjectPoolIsEmpty(int32 slot)
{
@@ -131,10 +139,11 @@ CPools::MakeSureSlotInObjectPoolIsEmpty(int32 slot)
void CPools::LoadVehiclePool(uint8* buf, uint32 size)
{
INITSAVEBUF
- int nNumCars, nNumBoats;
+ int nNumCars, nNumBoats, nNumBikes;
ReadSaveBuf(&nNumCars, buf);
ReadSaveBuf(&nNumBoats, buf);
- for (int i = 0; i < nNumCars + nNumBoats; i++) {
+ ReadSaveBuf(&nNumBikes, buf);
+ for (int i = 0; i < nNumCars + nNumBoats + nNumBikes; i++) {
uint32 type;
int16 model;
int32 slot;
@@ -150,13 +159,15 @@ INITSAVEBUF
pVehicle = new(slot) CBoat(model, RANDOM_VEHICLE);
else if (type == VEHICLE_TYPE_CAR)
pVehicle = new(slot) CAutomobile(model, RANDOM_VEHICLE);
+ else if (type == VEHICLE_TYPE_BIKE)
+ pVehicle = new(slot) CBike(model, RANDOM_VEHICLE);
else
assert(0);
--CCarCtrl::NumRandomCars;
pVehicle->Load(buf);
CWorld::Add(pVehicle);
#else
- char* vbuf = new char[Max(CAutomobile::nSaveStructSize, CBoat::nSaveStructSize)];
+ char* vbuf = new char[Max(CBike::nSaveStructSize, Max(CAutomobile::nSaveStructSize, CBoat::nSaveStructSize))];
if (type == VEHICLE_TYPE_BOAT) {
memcpy(vbuf, buf, sizeof(CBoat));
SkipSaveBuf(buf, sizeof(CBoat));
@@ -175,6 +186,17 @@ INITSAVEBUF
pAutomobile->Damage = ((CAutomobile*)vbuf)->Damage;
pAutomobile->SetupDamageAfterLoad();
}
+ else if (type == VEHICLE_TYPE_BIKE) {
+#ifdef FIX_BUGS
+ memcpy(vbuf, buf, sizeof(CBike));
+#else
+ memcpy(vbuf, buf, sizeof(CAutomobile));
+#endif
+ SkipSaveBuf(buf, sizeof(CBike));
+ CBike* pBike = new(slot) CBike(model, RANDOM_VEHICLE);
+ pVehicle = pBike;
+ --CCarCtrl::NumRandomCars;
+ }
else
assert(0);
CVehicle* pBufferVehicle = (CVehicle*)vbuf;
@@ -212,6 +234,7 @@ INITSAVEBUF
(pVehicle->GetAddressOfEntityProperties())[0] = (pBufferVehicle->GetAddressOfEntityProperties())[0];
(pVehicle->GetAddressOfEntityProperties())[1] = (pBufferVehicle->GetAddressOfEntityProperties())[1];
pVehicle->AutoPilot = pBufferVehicle->AutoPilot;
+ CCarCtrl::UpdateCarCount(pVehicle, false);
CWorld::Add(pVehicle);
delete[] vbuf;
#endif
@@ -224,6 +247,7 @@ void CPools::SaveVehiclePool(uint8* buf, uint32* size)
INITSAVEBUF
int nNumCars = 0;
int nNumBoats = 0;
+ int nNumBikes = 0;
int nPoolSize = GetVehiclePool()->GetSize();
for (int i = 0; i < nPoolSize; i++) {
CVehicle* pVehicle = GetVehiclePool()->GetSlot(i);
@@ -245,19 +269,25 @@ INITSAVEBUF
++nNumCars;
if (pVehicle->IsBoat() && (pVehicle->VehicleCreatedBy == MISSION_VEHICLE || bForceSaving))
++nNumBoats;
+ if (pVehicle->IsBike() && (pVehicle->VehicleCreatedBy == MISSION_VEHICLE || bForceSaving))
+ ++nNumBikes;
#else
if (!pVehicle->pDriver && !bHasPassenger) {
if (pVehicle->IsCar() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE)
++nNumCars;
if (pVehicle->IsBoat() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE)
++nNumBoats;
+ if (pVehicle->IsBike() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE)
+ ++nNumBikes;
#endif
}
}
*size = nNumCars * (sizeof(uint32) + sizeof(int16) + sizeof(int32) + CAutomobile::nSaveStructSize) + sizeof(int) +
- nNumBoats * (sizeof(uint32) + sizeof(int16) + sizeof(int32) + CBoat::nSaveStructSize) + sizeof(int);
+ nNumBoats * (sizeof(uint32) + sizeof(int16) + sizeof(int32) + CBoat::nSaveStructSize) + sizeof(int) +
+ nNumBikes * (sizeof(uint32) + sizeof(int16) + sizeof(int32) + CBike::nSaveStructSize) + sizeof(int);
WriteSaveBuf(buf, nNumCars);
WriteSaveBuf(buf, nNumBoats);
+ WriteSaveBuf(buf, nNumBikes);
for (int i = 0; i < nPoolSize; i++) {
CVehicle* pVehicle = GetVehiclePool()->GetSlot(i);
if (!pVehicle)
@@ -277,9 +307,9 @@ INITSAVEBUF
#endif
#ifdef COMPATIBLE_SAVES
#ifdef MISSION_REPLAY
- if ((pVehicle->IsCar() || pVehicle->IsBoat()) && (pVehicle->VehicleCreatedBy == MISSION_VEHICLE || bForceSaving)) {
+ if ((pVehicle->IsCar() || pVehicle->IsBoat() || pVehicle->IsBike()) && (pVehicle->VehicleCreatedBy == MISSION_VEHICLE || bForceSaving)) {
#else
- if ((pVehicle->IsCar() || pVehicle->IsBoat()) && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) {
+ if ((pVehicle->IsCar() || pVehicle->IsBoat() || pVehicle->IsBike()) && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) {
#endif
WriteSaveBuf(buf, pVehicle->m_vehType);
WriteSaveBuf(buf, pVehicle->GetModelIndex());
@@ -309,6 +339,17 @@ INITSAVEBUF
memcpy(buf, pVehicle, sizeof(CBoat));
SkipSaveBuf(buf, sizeof(CBoat));
}
+#ifdef MISSION_REPLAY
+ if (pVehicle->IsBike() && (pVehicle->VehicleCreatedBy == MISSION_VEHICLE || bForceSaving)) {
+#else
+ if (pVehicle->IsBike() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) {
+#endif
+ WriteSaveBuf(buf, pVehicle->m_vehType);
+ WriteSaveBuf(buf, pVehicle->GetModelIndex());
+ WriteSaveBuf(buf, GetVehicleRef(pVehicle));
+ memcpy(buf, pVehicle, sizeof(CBike));
+ SkipSaveBuf(buf, sizeof(CBike));
+ }
#endif
}
}
@@ -330,8 +371,9 @@ INITSAVEBUF
++nObjects;
}
*size = nObjects * (sizeof(int16) + sizeof(int) + sizeof(CCompressedMatrix) +
- sizeof(float) + sizeof(CCompressedMatrix) + sizeof(int8) + 7 * sizeof(bool) + sizeof(float) +
- sizeof(int8) + sizeof(int8) + sizeof(uint32) + 2 * sizeof(uint32)) + sizeof(int);
+ sizeof(float) + sizeof(CCompressedMatrix) + sizeof(int8) + 7 * sizeof(bool) + sizeof(int16) +
+ + sizeof(int8) * 2 + sizeof(float) + sizeof(int8) + sizeof(int8) +
+ sizeof(uint32) + 2 * sizeof(uint32)) + sizeof(int);
CopyToBuf(buf, nObjects);
for (int i = 0; i < nPoolSize; i++) {
CObject* pObject = GetObjectPool()->GetSlot(i);
@@ -362,6 +404,9 @@ INITSAVEBUF
CopyToBuf(buf, bGlassBroken);
CopyToBuf(buf, bHasBeenDamaged);
CopyToBuf(buf, bUseVehicleColours);
+ CopyToBuf(buf, pObject->m_nCostValue);
+ CopyToBuf(buf, pObject->m_nBonusValue);
+ SkipSaveBuf(buf, 1);
CopyToBuf(buf, pObject->m_fCollisionDamageMultiplier);
CopyToBuf(buf, pObject->m_nCollisionDamageEffect);
CopyToBuf(buf, pObject->m_nSpecialCollisionResponseCases);
@@ -411,6 +456,9 @@ INITSAVEBUF
pBufferObject->bHasBeenDamaged = bitFlag;
CopyFromBuf(buf, bitFlag);
pBufferObject->bUseVehicleColours = bitFlag;
+ CopyFromBuf(buf, pBufferObject->m_nCostValue);
+ CopyFromBuf(buf, pBufferObject->m_nBonusValue);
+ SkipSaveBuf(buf, 1);
CopyFromBuf(buf, pBufferObject->m_fCollisionDamageMultiplier);
CopyFromBuf(buf, pBufferObject->m_nCollisionDamageEffect);
CopyFromBuf(buf, pBufferObject->m_nSpecialCollisionResponseCases);
@@ -445,6 +493,8 @@ INITSAVEBUF
(pObject->GetAddressOfEntityProperties())[1] = (pBufferObject->GetAddressOfEntityProperties())[1];
#endif
pObject->bHasCollided = false;
+ pObject->m_nCostValue = pBufferObject->m_nCostValue;
+ pObject->m_nBonusValue = pBufferObject->m_nBonusValue;
CWorld::Add(pObject);
delete[] obuf;
}
@@ -567,8 +617,20 @@ INITSAVEBUF
pPed->CharCreatedBy = pBufferPlayer->CharCreatedBy;
pPed->m_currentWeapon = 0;
pPed->m_maxWeaponTypeAllowed = pBufferPlayer->m_maxWeaponTypeAllowed;
- for (int i = 0; i < WEAPONTYPE_TOTAL_INVENTORY_WEAPONS; i++)
- pPed->m_weapons[i] = pBufferPlayer->m_weapons[i];
+ for (int i = 0; i < TOTAL_WEAPON_SLOTS; i++) {
+ if (pBufferPlayer->HasWeaponSlot(i)) {
+ int modelId = CWeaponInfo::GetWeaponInfo(pBufferPlayer->GetWeapon(i).m_eWeaponType)->m_nModelId;
+ if (modelId != -1) {
+ CStreaming::RequestModel(modelId, STREAMFLAGS_DEPENDENCY);
+ int modelId2 = CWeaponInfo::GetWeaponInfo(pBufferPlayer->GetWeapon(i).m_eWeaponType)->m_nModel2Id;
+ if (modelId2 != -1)
+ CStreaming::RequestModel(modelId2, STREAMFLAGS_DEPENDENCY);
+
+ CStreaming::LoadAllRequestedModels(false);
+ }
+ pPed->GiveWeapon(pBufferPlayer->GetWeapon(i).m_eWeaponType, pBufferPlayer->GetWeapon(i).m_nAmmoTotal, false);
+ }
+ }
if (pedtype == PEDTYPE_PLAYER1) {
pPed->m_wepAccuracy = 100;
diff --git a/src/core/Pools.h b/src/core/Pools.h
index b0ba6598..afef1b85 100644
--- a/src/core/Pools.h
+++ b/src/core/Pools.h
@@ -4,7 +4,7 @@
#include "Lists.h"
#include "Treadable.h"
#include "Object.h"
-#include "CutsceneHead.h"
+#include "CutsceneObject.h"
#include "PlayerPed.h"
#include "Automobile.h"
#include "DummyPed.h"
@@ -16,9 +16,10 @@ typedef CPool<CPed,CPlayerPed> CPedPool;
typedef CPool<CVehicle,CAutomobile> CVehiclePool;
typedef CPool<CBuilding> CBuildingPool;
typedef CPool<CTreadable> CTreadablePool;
-typedef CPool<CObject, CCutsceneHead> CObjectPool;
+typedef CPool<CObject, CCutsceneObject> CObjectPool;
typedef CPool<CDummy, CDummyPed> CDummyPool;
typedef CPool<cAudioScriptObject> CAudioScriptObjectPool;
+typedef CPool<CColModel> CColModelPool;
class CPools
{
@@ -31,6 +32,7 @@ class CPools
static CObjectPool *ms_pObjectPool;
static CDummyPool *ms_pDummyPool;
static CAudioScriptObjectPool *ms_pAudioScriptObjectPool;
+ static CColModelPool *ms_pColModelPool;
public:
static CCPtrNodePool *GetPtrNodePool(void) { return ms_pPtrNodePool; }
static CEntryInfoNodePool *GetEntryInfoNodePool(void) { return ms_pEntryInfoNodePool; }
@@ -41,6 +43,7 @@ public:
static CObjectPool *GetObjectPool(void) { return ms_pObjectPool; }
static CDummyPool *GetDummyPool(void) { return ms_pDummyPool; }
static CAudioScriptObjectPool *GetAudioScriptObjectPool(void) { return ms_pAudioScriptObjectPool; }
+ static CColModelPool *GetColModelPool(void) { return ms_pColModelPool; }
static void Initialise(void);
static void ShutDown(void);
diff --git a/src/core/Radar.cpp b/src/core/Radar.cpp
index d74ce007..7e3a75b3 100644
--- a/src/core/Radar.cpp
+++ b/src/core/Radar.cpp
@@ -19,60 +19,100 @@
#include "SaveBuf.h"
#include "Streaming.h"
#include "SpecialFX.h"
+#include "Font.h"
+#include "SaveBuf.h"
float CRadar::m_radarRange;
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;
-#ifdef MENU_MAP
+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;
+#ifdef MAP_ENHANCEMENTS
CSprite2d CRadar::WaypointSprite;
#endif
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,
-#ifdef MENU_MAP
- &WaypointSprite
+ &TShirtSprite,
+ &TommySprite,
+ &PhoneSprite,
+ &RadioWildstyleSprite,
+ &RadioFlashSprite,
+ &RadioKChatSprite,
+ &RadioFeverSprite,
+ &RadioVRockSprite,
+ &RadioVCPRSprite,
+ &RadioEspantosoSprite,
+ &RadioEmotionSprite,
+ &RadioWaveSprite,
+#ifdef MAP_ENHANCEMENTS
+ &WaypointSprite,
#endif
};
@@ -93,12 +133,15 @@ static_assert(RADAR_TILE_SIZE == (RADAR_SIZE_Y / RADAR_NUM_TILES), "CRadar: not
#define RADAR_MIN_SPEED (0.3f)
#define RADAR_MAX_SPEED (0.9f)
-#ifdef MENU_MAP
+CRGBA CRadar::ArrowBlipColour1;
+CRGBA CRadar::ArrowBlipColour2;
+int16 CRadar::MapLegendCounter;
+int16 CRadar::MapLegendList[NUM_MAP_LEGENDS];
+#ifdef MAP_ENHANCEMENTS
int CRadar::TargetMarkerId = -1;
CVector CRadar::TargetMarkerPos;
#endif
-// taken from VC
float CRadar::cachedCos;
float CRadar::cachedSin;
@@ -151,15 +194,14 @@ void GetTextureCorners(int32 x, int32 y, CVector2D *out)
uint8 CRadar::CalculateBlipAlpha(float dist)
{
-#ifdef MENU_MAP
- if (CMenuManager::bMenuMapActive)
+ if (FrontEndMenuManager.m_bMenuMapActive)
return 255;
-#endif
+
if (dist <= 1.0f)
return 255;
- if (dist <= 5.0f)
- return (128.0f * ((dist - 1.0f) / 4.0f)) + ((1.0f - (dist - 1.0f) / 4.0f) * 255.0f);
+ if (dist <= 10.0f)
+ return (128.0f * ((dist - 1.0f) / 9.0f)) + ((1.0f - (dist - 1.0f) / 9.0f) * 255.0f);
return 128;
}
@@ -198,12 +240,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
}
}
@@ -428,9 +467,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;
@@ -448,7 +486,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::GetColModel(entity->GetModelIndex())->boundingBox.max.z + 2.5f;
- C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), MARKERTYPE_ARROW, pos, 2.5f, 0, 128, 255, 255, 1024, 0.2f, 5);
+ C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), MARKERTYPE_ARROW, pos, 2.5f, CARBLIP_MARKER_COLOR_R, CARBLIP_MARKER_COLOR_G, CARBLIP_MARKER_COLOR_B, CARBLIP_MARKER_COLOR_A, 1024, 0.2f, 5);
}
break;
}
@@ -462,7 +500,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), MARKERTYPE_ARROW, pos, 1.5f, 0, 128, 255, 255, 1024, 0.2f, 5);
+ C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), MARKERTYPE_ARROW, pos, 1.5f, CHARBLIP_MARKER_COLOR_R, CHARBLIP_MARKER_COLOR_G, CHARBLIP_MARKER_COLOR_B, CHARBLIP_MARKER_COLOR_A, 1024, 0.2f, 5);
}
break;
}
@@ -472,7 +510,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::GetColModel(entity->GetModelIndex())->boundingBox.max.z + 1.0f + 1.0f;
- C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), MARKERTYPE_ARROW, pos, 1.0f, 0, 128, 255, 255, 1024, 0.2f, 5);
+ C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), MARKERTYPE_ARROW, pos, 1.0f, OBJECTBLIP_MARKER_COLOR_R, OBJECTBLIP_MARKER_COLOR_G, OBJECTBLIP_MARKER_COLOR_B, OBJECTBLIP_MARKER_COLOR_A, 1024, 0.2f, 5);
}
break;
}
@@ -481,7 +519,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), MARKERTYPE_CYLINDER, ms_RadarTrace[i].m_vecPos, 2.0f, 0, 128, 255, 128, 2048, 0.2f, 0);
+ C3dMarkers::PlaceMarkerSet(i | (ms_RadarTrace[i].m_BlipIndex << 16), MARKERTYPE_CYLINDER, 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;
}
@@ -491,11 +529,11 @@ void CRadar::Draw3dMarkers()
void CRadar::DrawBlips()
{
- if ((!TheCamera.m_WideScreenOn && CHud::m_Wants_To_Draw_Hud)
-#ifdef MENU_MAP
- || CMenuManager::bMenuMapActive
+ if (!TheCamera.m_WideScreenOn && CHud::m_Wants_To_Draw_Hud) {
+#ifdef SECUROM
+ extern uint8 roadBlocksPirateCheck;
+ if (roadBlocksPirateCheck == 2) return;
#endif
- ) {
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
@@ -507,9 +545,7 @@ void CRadar::DrawBlips()
CVector2D in = CVector2D(0.0f, 0.0f);
TransformRadarPointToScreenSpace(out, in);
-#ifdef MENU_MAP
- if (!CMenuManager::bMenuMapActive) {
-#endif
+ if (!FrontEndMenuManager.m_bMenuMapActive) {
float angle;
if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN)
angle = PI + FindPlayerHeading();
@@ -529,17 +565,9 @@ void CRadar::DrawBlips()
LimitRadarPoint(in);
TransformRadarPointToScreenSpace(out, in);
DrawRadarSprite(RADAR_SPRITE_NORTH, out.x, out.y, 255);
-#ifdef MENU_MAP
}
-#endif
- 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;
@@ -547,165 +575,65 @@ 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_PROPERTY
+ && (!CTheScripts::bPlayerIsInTheStatium || !FrontEndMenuManager.m_bMenuMapActive))
+ DrawEntityBlip(blipId);
- switch (ms_RadarTrace[blipId].m_eBlipType) {
- case BLIP_CAR:
- blipEntity = CPools::GetVehiclePool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle);
- break;
- case BLIP_CHAR:
- blipEntity = CPools::GetPedPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle);
- if (blipEntity != nil) {
- if (((CPed*)blipEntity)->InVehicle())
- blipEntity = ((CPed*)blipEntity)->m_pMyVehicle;
- }
- break;
- case BLIP_OBJECT:
- blipEntity = CPools::GetObjectPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle);
- break;
- default:
- break;
- }
- if (blipEntity) {
- uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim);
- if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
- if (CTheScripts::IsDebugOn()) {
- ShowRadarMarker(blipEntity->GetPosition(), color, ms_RadarTrace[blipId].m_Radius);
- ms_RadarTrace[blipId].m_Radius = ms_RadarTrace[blipId].m_Radius - 0.1f;
- if (ms_RadarTrace[blipId].m_Radius < 1.0f)
- ms_RadarTrace[blipId].m_Radius = 5.0f;
- }
- }
- if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BLIP_ONLY) {
- TransformRealWorldPointToRadarSpace(in, blipEntity->GetPosition());
- float dist = LimitRadarPoint(in);
- TransformRadarPointToScreenSpace(out, in);
- if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE) {
- DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist));
- } else {
-#ifdef TRIANGULAR_BLIPS
- const CVector &pos = FindPlayerCentreOfWorld_NoSniperShift();
- const CVector &blipPos = blipEntity->GetPosition();
- uint8 mode = BLIP_MODE_TRIANGULAR_UP;
- if (blipPos.z - pos.z <= 2.0f) {
- if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN;
- else mode = BLIP_MODE_SQUARE;
- }
- ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode);
-#else
- ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255);
-#endif
- }
- }
- }
- }
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)
- && (ms_RadarTrace[blipId].m_eBlipType != BLIP_CONTACT_POINT || !CTheScripts::IsPlayerOnAMission())) {
-
- uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim);
- if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
- if (CTheScripts::IsDebugOn()) {
- ShowRadarMarker(ms_RadarTrace[blipId].m_vecPos, color, ms_RadarTrace[blipId].m_Radius);
- ms_RadarTrace[blipId].m_Radius = ms_RadarTrace[blipId].m_Radius - 0.1f;
- if (ms_RadarTrace[blipId].m_Radius < 1.0f)
- ms_RadarTrace[blipId].m_Radius = 5.0f;
- }
- }
- if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BLIP_ONLY) {
- TransformRealWorldPointToRadarSpace(in, ms_RadarTrace[blipId].m_vec2DPos);
- float dist = LimitRadarPoint(in);
- TransformRadarPointToScreenSpace(out, in);
- if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE) {
- DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist));
- } else {
-#ifdef TRIANGULAR_BLIPS
- const CVector &pos = FindPlayerCentreOfWorld_NoSniperShift();
- const CVector &blipPos = ms_RadarTrace[blipId].m_vecPos;
- uint8 mode = BLIP_MODE_TRIANGULAR_UP;
- if (blipPos.z - pos.z <= 2.0f) {
- if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN;
- else mode = BLIP_MODE_SQUARE;
- }
- ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode);
-#else
- ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255);
-#endif
- }
- }
- }
+ if (ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_PHONE
+ && (!CTheScripts::bPlayerIsInTheStatium || !FrontEndMenuManager.m_bMenuMapActive))
+ DrawCoordBlip(blipId);
+
break;
default:
break;
}
}
+
+ // New in VC: Always draw Hardware/gun/pay'n spray/save blips
for(int blipId = 0; blipId < NUMRADARBLIPS; blipId++) {
if (!ms_RadarTrace[blipId].m_bInUse)
continue;
+ if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SAVE && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_HARDWARE
+ && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SPRAY && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_GUN)
+ continue;
+
switch (ms_RadarTrace[blipId].m_eBlipType) {
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 (!CTheScripts::bPlayerIsInTheStatium || !FrontEndMenuManager.m_bMenuMapActive)
+ DrawEntityBlip(blipId);
- switch (ms_RadarTrace[blipId].m_eBlipType) {
- case BLIP_CAR:
- blipEntity = CPools::GetVehiclePool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle);
- break;
- case BLIP_CHAR:
- blipEntity = CPools::GetPedPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle);
- if (blipEntity != nil) {
- if (((CPed*)blipEntity)->InVehicle())
- blipEntity = ((CPed*)blipEntity)->m_pMyVehicle;
- }
- break;
- case BLIP_OBJECT:
- blipEntity = CPools::GetObjectPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle);
- break;
- default:
- break;
- }
+ break;
+ case BLIP_COORD:
+ case BLIP_CONTACT_POINT:
+ if (!CTheScripts::bPlayerIsInTheStatium || !FrontEndMenuManager.m_bMenuMapActive)
+ DrawCoordBlip(blipId);
+
+ break;
+ default:
+ break;
+ }
+ }
- if (blipEntity) {
- uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim);
- if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
- if (CTheScripts::IsDebugOn()) {
- ShowRadarMarker(blipEntity->GetPosition(), color, ms_RadarTrace[blipId].m_Radius);
- ms_RadarTrace[blipId].m_Radius = ms_RadarTrace[blipId].m_Radius - 0.1f;
- if (ms_RadarTrace[blipId].m_Radius < 1.0f)
- ms_RadarTrace[blipId].m_Radius = 5.0f;
- }
- }
- if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BLIP_ONLY) {
- TransformRealWorldPointToRadarSpace(in, blipEntity->GetPosition());
- float dist = LimitRadarPoint(in);
- TransformRadarPointToScreenSpace(out, in);
- if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE)
- DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist));
- else
-#ifdef TRIANGULAR_BLIPS
- {
- const CVector &pos = FindPlayerCentreOfWorld_NoSniperShift();
- const CVector &blipPos = blipEntity->GetPosition();
- uint8 mode = BLIP_MODE_TRIANGULAR_UP;
- if (blipPos.z - pos.z <= 2.0f) {
- if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN;
- else mode = BLIP_MODE_SQUARE;
- }
- ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode);
- }
-#else
- ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255);
-#endif
- }
- }
- }
+ for(int blipId = 0; blipId < NUMRADARBLIPS; blipId++) {
+ if (!ms_RadarTrace[blipId].m_bInUse)
+ continue;
+
+ switch (ms_RadarTrace[blipId].m_eBlipType) {
+ case BLIP_CAR:
+ case BLIP_CHAR:
+ case BLIP_OBJECT:
+ if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SAVE && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_HARDWARE
+ && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SPRAY && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_PROPERTY
+ && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_GUN
+ && (!CTheScripts::bPlayerIsInTheStatium || !FrontEndMenuManager.m_bMenuMapActive))
+
+ DrawEntityBlip(blipId);
break;
default:
break;
@@ -718,65 +646,35 @@ 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
- && (ms_RadarTrace[blipId].m_eBlipType != BLIP_CONTACT_POINT || !CTheScripts::IsPlayerOnAMission())) {
-
- uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim);
- if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
- if (CTheScripts::IsDebugOn()) {
- ShowRadarMarker(ms_RadarTrace[blipId].m_vecPos, color, ms_RadarTrace[blipId].m_Radius);
- ms_RadarTrace[blipId].m_Radius = ms_RadarTrace[blipId].m_Radius - 0.1f;
- if (ms_RadarTrace[blipId].m_Radius < 1.0f)
- ms_RadarTrace[blipId].m_Radius = 5.0f;
- }
- }
- if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BLIP_ONLY) {
- TransformRealWorldPointToRadarSpace(in, ms_RadarTrace[blipId].m_vec2DPos);
- float dist = LimitRadarPoint(in);
- TransformRadarPointToScreenSpace(out, in);
- if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE)
- DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist));
- else
-#ifdef TRIANGULAR_BLIPS
- {
- const CVector &pos = FindPlayerCentreOfWorld_NoSniperShift();
- const CVector &blipPos = ms_RadarTrace[blipId].m_vecPos;
- uint8 mode = BLIP_MODE_TRIANGULAR_UP;
- if (blipPos.z - pos.z <= 2.0f) {
- if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN;
- else mode = BLIP_MODE_SQUARE;
- }
- ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode);
- }
-#else
- ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255);
-#endif
- }
- }
+ if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SAVE && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_HARDWARE
+ && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SPRAY && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_PROPERTY
+ && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_GUN && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_PHONE
+ && (!CTheScripts::bPlayerIsInTheStatium || !FrontEndMenuManager.m_bMenuMapActive))
+
+ DrawCoordBlip(blipId);
break;
default:
break;
}
}
-#ifdef MENU_MAP
- if (CMenuManager::bMenuMapActive) {
+ if (FrontEndMenuManager.m_bMenuMapActive) {
CVector2D in, out;
- TransformRealWorldPointToRadarSpace(in, FindPlayerCentreOfWorld_NoSniperShift());
+ if (!CTheScripts::bPlayerIsInTheStatium)
+ TransformRealWorldPointToRadarSpace(in, FindPlayerCentreOfWorld_NoSniperShift());
+ else
+ TransformRealWorldPointToRadarSpace(in, CVector2D(-1302.5f, 1332.8f));
+
LimitRadarPoint(in);
TransformRadarPointToScreenSpace(out, in);
DrawYouAreHereSprite(out.x, out.y);
}
-#endif
}
}
void CRadar::DrawMap()
{
if (!TheCamera.m_WideScreenOn && CHud::m_Wants_To_Draw_Hud) {
-#if 1 // from VC
CalculateCachedSinCos();
-#endif
if (FindPlayerVehicle()) {
float speed = FindPlayerSpeed().Magnitude();
if (speed < RADAR_MIN_SPEED)
@@ -790,14 +688,13 @@ void CRadar::DrawMap()
m_radarRange = RADAR_MIN_RANGE;
vec2DRadarOrigin = CVector2D(FindPlayerCentreOfWorld_NoSniperShift());
- DrawRadarMap();
+ if (FrontEndMenuManager.m_PrefsRadarMode != 1)
+ DrawRadarMap();
}
}
void CRadar::DrawRadarMap()
{
- // Game calculates an unused CRect here
-
DrawRadarMask();
// top left ist (0, 0)
@@ -875,6 +772,7 @@ void CRadar::DrawRadarMask()
#if !defined(GTA_PS2_STUFF) && defined(RWLIBS)
RwD3D8SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER);
#endif
+
}
void CRadar::DrawRadarSection(int32 x, int32 y)
@@ -892,11 +790,8 @@ void CRadar::DrawRadarSection(int32 x, int32 y)
GetTextureCorners(x, y, worldPoly);
ClipRadarTileCoords(x, y);
- assert(CTxdStore::GetSlot(gRadarTxdIds[x + RADAR_NUM_TILES * y]));
- txd = CTxdStore::GetSlot(gRadarTxdIds[x + RADAR_NUM_TILES * y])->texDict;
- if (txd)
- texture = GetFirstTexture(txd);
- if (texture == nil)
+ if (!CTheScripts::bPlayerIsInTheStatium &&
+ (!(txd = CTxdStore::GetSlot(gRadarTxdIds[x + RADAR_NUM_TILES * y])->texDict) || !(texture = GetFirstTexture(txd))))
return;
for (i = 0; i < 4; i++)
@@ -914,8 +809,15 @@ void CRadar::DrawRadarSection(int32 x, int32 y)
TransformRealWorldToTexCoordSpace(texCoords[i], worldPoly[i], x, y);
TransformRadarPointToScreenSpace(screenPoly[i], radarPoly[i]);
}
- RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(texture));
- CSprite2d::SetVertices(numVertices, (float*)screenPoly, (float*)texCoords, CRGBA(255, 255, 255, 255));
+
+ if (CTheScripts::bPlayerIsInTheStatium) {
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
+ CSprite2d::SetVertices(numVertices, (float*)screenPoly, (float*)texCoords, CRGBA(204, 204, 204, 255));
+ } else {
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(texture));
+ CSprite2d::SetVertices(numVertices, (float*)screenPoly, (float*)texCoords, CRGBA(255, 255, 255, 255));
+ }
+
// check done above now
// if(numVertices > 2)
RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::GetVertices(), numVertices);
@@ -923,10 +825,22 @@ void CRadar::DrawRadarSection(int32 x, int32 y)
void CRadar::DrawRadarSprite(uint16 sprite, float x, float y, uint8 alpha)
{
-#ifdef MENU_MAP
+#ifdef MAP_ENHANCEMENTS
if(sprite == RADAR_SPRITE_WAYPOINT) alpha = 255;
#endif
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));
+
+ if (FrontEndMenuManager.m_bMenuMapActive) {
+ bool alreadyThere = false;
+ for (int i = 0; i < NUM_MAP_LEGENDS; i++) {
+ if (MapLegendList[i] == sprite)
+ alreadyThere = true;
+ }
+ if (!alreadyThere) {
+ MapLegendList[MapLegendCounter] = sprite;
+ MapLegendCounter++;
+ }
+ }
}
void CRadar::DrawRotatingRadarSprite(CSprite2d* sprite, float x, float y, float angle, int32 alpha)
@@ -1031,14 +945,14 @@ const char* gRadarTexNames[] = {
void
CRadar::Initialise()
{
-#ifdef MENU_MAP
+#ifdef MAP_ENHANCEMENTS
TargetMarkerId = -1;
#endif
-
for (int i = 0; i < NUMRADARBLIPS; i++) {
ms_RadarTrace[i].m_BlipIndex = 1;
SetRadarMarkerState(i, false);
ms_RadarTrace[i].m_bInUse = false;
+ ms_RadarTrace[i].m_bShortRange = false;
ms_RadarTrace[i].m_eBlipType = BLIP_NONE;
ms_RadarTrace[i].m_eBlipDisplay = BLIP_DISPLAY_NEITHER;
ms_RadarTrace[i].m_eRadarSprite = RADAR_SPRITE_NONE;
@@ -1054,10 +968,10 @@ float CRadar::LimitRadarPoint(CVector2D &point)
float dist, invdist;
dist = point.Magnitude();
-#ifdef MENU_MAP
- if (CMenuManager::bMenuMapActive)
+
+ if (FrontEndMenuManager.m_bMenuMapActive)
return dist;
-#endif
+
if (dist > 1.0f) {
invdist = 1.0f / dist;
point.x *= invdist;
@@ -1072,38 +986,117 @@ void CRadar::LoadAllRadarBlips(uint8 *buf, uint32 size)
INITSAVEBUF
CheckSaveHeader(buf, 'R', 'D', 'R', '\0', size - SAVE_HEADER_SIZE);
- for (int i = 0; i < NUMRADARBLIPS; i++)
- ReadSaveBuf(&ms_RadarTrace[i], buf);
+ for (int i = 0; i < NUMRADARBLIPS; i++) {
+ ReadSaveBuf(&ms_RadarTrace[i].m_nColor, buf);
+ ReadSaveBuf(&ms_RadarTrace[i].m_Radius, buf);
+ ReadSaveBuf(&ms_RadarTrace[i].m_eBlipType, buf);
+ ReadSaveBuf(&ms_RadarTrace[i].m_nEntityHandle, buf);
+ ReadSaveBuf(&ms_RadarTrace[i].m_vec2DPos.x, buf);
+ ReadSaveBuf(&ms_RadarTrace[i].m_vec2DPos.y, buf);
+ ReadSaveBuf(&ms_RadarTrace[i].m_vecPos, buf);
+ ReadSaveBuf(&ms_RadarTrace[i].m_BlipIndex, buf);
+ ReadSaveBuf(&ms_RadarTrace[i].m_bDim, buf);
+ ReadSaveBuf(&ms_RadarTrace[i].m_bInUse, buf);
+ ReadSaveBuf(&ms_RadarTrace[i].m_bShortRange, buf);
+ ReadSaveBuf(&ms_RadarTrace[i].m_unused, buf);
+ ReadSaveBuf(&ms_RadarTrace[i].m_wScale, buf);
+ ReadSaveBuf(&ms_RadarTrace[i].m_eBlipDisplay, buf);
+ ReadSaveBuf(&ms_RadarTrace[i].m_eRadarSprite, buf);
+ }
VALIDATESAVEBUF(size);
}
+void CRadar::SaveAllRadarBlips(uint8 *buf, uint32 *size)
+{
+ *size = SAVE_HEADER_SIZE + NUMRADARBLIPS * sizeof(sRadarTraceSave);
+
+INITSAVEBUF
+ WriteSaveHeader(buf, 'R', 'D', 'R', '\0', *size - SAVE_HEADER_SIZE);
+
+#ifdef MAP_ENHANCEMENTS
+ bool bWaypointDeleted = false;
+ if (TargetMarkerId != -1) {
+ ClearBlip(TargetMarkerId);
+ TargetMarkerId = -1;
+ bWaypointDeleted = true;
+ }
+#endif
+
+ for (int i = 0; i < NUMRADARBLIPS; i++) {
+ sRadarTraceSave *saveStruct = (sRadarTraceSave*) buf;
+
+ saveStruct->m_nColor = ms_RadarTrace[i].m_nColor;
+ saveStruct->m_Radius = ms_RadarTrace[i].m_Radius;
+ saveStruct->m_eBlipType = ms_RadarTrace[i].m_eBlipType;
+ saveStruct->m_nEntityHandle = ms_RadarTrace[i].m_nEntityHandle;
+ saveStruct->m_vec2DPos = ms_RadarTrace[i].m_vec2DPos;
+ saveStruct->m_vecPos = ms_RadarTrace[i].m_vecPos;
+ saveStruct->m_BlipIndex = ms_RadarTrace[i].m_BlipIndex;
+ saveStruct->m_bDim = ms_RadarTrace[i].m_bDim;
+ saveStruct->m_bInUse = ms_RadarTrace[i].m_bInUse;
+ saveStruct->m_bShortRange = ms_RadarTrace[i].m_bShortRange;
+ saveStruct->m_unused = ms_RadarTrace[i].m_unused;
+ saveStruct->m_wScale = ms_RadarTrace[i].m_wScale;
+ saveStruct->m_eBlipDisplay = ms_RadarTrace[i].m_eBlipDisplay;
+ saveStruct->m_eRadarSprite = ms_RadarTrace[i].m_eRadarSprite;
+
+ SkipSaveBuf(buf, sizeof(sRadarTraceSave));
+ }
+
+#ifdef MAP_ENHANCEMENTS
+ if(bWaypointDeleted)
+ ToggleTargetMarker(TargetMarkerPos.x, TargetMarkerPos.y);
+#endif
+
+VALIDATESAVEBUF(*size);
+}
+
void
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");
-#ifdef MENU_MAP
+ 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");
+#ifdef MAP_ENHANCEMENTS
WaypointSprite.SetTexture("radar_waypoint");
if(!WaypointSprite.m_pTexture) {
// create the texture if it's missing in TXD
@@ -1150,33 +1143,6 @@ void CRadar::RemoveRadarSections()
RemoveMapSection(i, j);
}
-void CRadar::SaveAllRadarBlips(uint8 *buf, uint32 *size)
-{
- *size = SAVE_HEADER_SIZE + sizeof(ms_RadarTrace);
-INITSAVEBUF
- WriteSaveHeader(buf, 'R', 'D', 'R', '\0', *size - SAVE_HEADER_SIZE);
-
-#ifdef MENU_MAP
- bool bWaypointDeleted = false;
- if (TargetMarkerId != -1) {
- ClearBlip(TargetMarkerId);
- TargetMarkerId = -1;
- bWaypointDeleted = true;
- }
-#endif
-
- for (int i = 0; i < NUMRADARBLIPS; i++)
- WriteSaveBuf(buf, ms_RadarTrace[i]);
-
-
-#ifdef MENU_MAP
- if(bWaypointDeleted)
- ToggleTargetMarker(TargetMarkerPos.x, TargetMarkerPos.y);
-#endif
-
-VALIDATESAVEBUF(*size);
-}
-
void CRadar::SetBlipSprite(int32 i, int32 icon)
{
int index = CRadar::GetActualBlipArrayIndex(i);
@@ -1185,7 +1151,7 @@ void CRadar::SetBlipSprite(int32 i, int32 icon)
}
}
-int CRadar::SetCoordBlip(eBlipType type, CVector pos, int32 color, eBlipDisplay display)
+int CRadar::SetCoordBlip(eBlipType type, CVector pos, uint32 color, eBlipDisplay display)
{
int nextBlip;
for (nextBlip = 0; nextBlip < NUMRADARBLIPS; nextBlip++) {
@@ -1197,9 +1163,10 @@ int CRadar::SetCoordBlip(eBlipType type, CVector pos, int32 color, eBlipDisplay
return -1;
#endif
ms_RadarTrace[nextBlip].m_eBlipType = type;
- ms_RadarTrace[nextBlip].m_nColor = color;
- ms_RadarTrace[nextBlip].m_bDim = 1;
- ms_RadarTrace[nextBlip].m_bInUse = 1;
+ ms_RadarTrace[nextBlip].m_nColor = RADAR_TRACE_MAGENTA;
+ ms_RadarTrace[nextBlip].m_bDim = true;
+ ms_RadarTrace[nextBlip].m_bInUse = true;
+ ms_RadarTrace[nextBlip].m_bShortRange = false;
ms_RadarTrace[nextBlip].m_Radius = 1.0f;
ms_RadarTrace[nextBlip].m_vec2DPos = pos;
ms_RadarTrace[nextBlip].m_vecPos = pos;
@@ -1210,7 +1177,16 @@ int CRadar::SetCoordBlip(eBlipType type, CVector pos, int32 color, eBlipDisplay
return CRadar::GetNewUniqueBlipIndex(nextBlip);
}
-int CRadar::SetEntityBlip(eBlipType type, int32 handle, int32 color, eBlipDisplay display)
+int CRadar::SetShortRangeCoordBlip(eBlipType type, CVector pos, uint32 color, eBlipDisplay display)
+{
+ int index = SetCoordBlip(type, pos, color, display);
+ if (index == -1)
+ return -1;
+ ms_RadarTrace[GetActualBlipArrayIndex(index)].m_bShortRange = true;
+ return index;
+}
+
+int CRadar::SetEntityBlip(eBlipType type, int32 handle, uint32 color, eBlipDisplay display)
{
int nextBlip;
for (nextBlip = 0; nextBlip < NUMRADARBLIPS; nextBlip++) {
@@ -1222,9 +1198,10 @@ int CRadar::SetEntityBlip(eBlipType type, int32 handle, int32 color, eBlipDispla
return -1;
#endif
ms_RadarTrace[nextBlip].m_eBlipType = type;
- ms_RadarTrace[nextBlip].m_nColor = color;
- ms_RadarTrace[nextBlip].m_bDim = 1;
- ms_RadarTrace[nextBlip].m_bInUse = 1;
+ ms_RadarTrace[nextBlip].m_nColor = RADAR_TRACE_YELLOW;
+ ms_RadarTrace[nextBlip].m_bDim = true;
+ ms_RadarTrace[nextBlip].m_bInUse = true;
+ ms_RadarTrace[nextBlip].m_bShortRange = false;
ms_RadarTrace[nextBlip].m_Radius = 1.0f;
ms_RadarTrace[nextBlip].m_nEntityHandle = handle;
ms_RadarTrace[nextBlip].m_wScale = 1;
@@ -1278,11 +1255,7 @@ void CRadar::ShowRadarMarker(CVector pos, uint32 color, float radius) {
void CRadar::ShowRadarTrace(float x, float y, uint32 size, uint8 red, uint8 green, uint8 blue, uint8 alpha)
{
- if ((TheCamera.m_WideScreenOn || !CHud::m_Wants_To_Draw_Hud)
-#ifdef MENU_MAP
- && !CMenuManager::bMenuMapActive
-#endif
- )
+ if (!CHud::m_Wants_To_Draw_Hud || TheCamera.m_WideScreenOn)
return;
CSprite2d::DrawRect(CRect(x - SCREEN_SCALE_X(size + 1.0f), y - SCREEN_SCALE_Y(size + 1.0f), SCREEN_SCALE_X(size + 1.0f) + x, SCREEN_SCALE_Y(size + 1.0f) + y), CRGBA(0, 0, 0, alpha));
@@ -1291,22 +1264,18 @@ void CRadar::ShowRadarTrace(float x, float y, uint32 size, uint8 red, uint8 gree
void CRadar::ShowRadarTraceWithHeight(float x, float y, uint32 size, uint8 red, uint8 green, uint8 blue, uint8 alpha, uint8 mode)
{
- if ((TheCamera.m_WideScreenOn || !CHud::m_Wants_To_Draw_Hud)
-#ifdef MENU_MAP
- && !CMenuManager::bMenuMapActive
-#endif
- )
+ if (!CHud::m_Wants_To_Draw_Hud || TheCamera.m_WideScreenOn)
return;
switch (mode)
{
case BLIP_MODE_TRIANGULAR_UP:
- // size++; // VC does size + 1 for triangles
+ size++;
CSprite2d::Draw2DPolygon(x + SCREEN_SCALE_X(size + 3.0f), y + SCREEN_SCALE_Y(size + 2.0f), x - (SCREEN_SCALE_X(size + 3.0f)), y + SCREEN_SCALE_Y(size + 2.0f), x, y - (SCREEN_SCALE_Y(size + 3.0f)), x, y - (SCREEN_SCALE_Y(size + 3.0f)), CRGBA(0, 0, 0, alpha));
CSprite2d::Draw2DPolygon(x + SCREEN_SCALE_X(size + 1.0f), y + SCREEN_SCALE_Y(size + 1.0f), x - (SCREEN_SCALE_X(size + 1.0f)), y + SCREEN_SCALE_Y(size + 1.0f), x, y - (SCREEN_SCALE_Y(size + 1.0f)), x, y - (SCREEN_SCALE_Y(size + 1.0f)), CRGBA(red, green, blue, alpha));
break;
case BLIP_MODE_TRIANGULAR_DOWN:
- // size++; // VC does size + 1 for triangles
+ size++;
CSprite2d::Draw2DPolygon(x, y + SCREEN_SCALE_Y(size + 2.0f), x, y + SCREEN_SCALE_Y(size + 3.0f), x + SCREEN_SCALE_X(size + 3.0f), y - (SCREEN_SCALE_Y(size + 2.0f)), x - (SCREEN_SCALE_X(size + 3.0f)), y - (SCREEN_SCALE_Y(size + 2.0f)), CRGBA(0, 0, 0, alpha));
CSprite2d::Draw2DPolygon(x, y + SCREEN_SCALE_Y(size + 1.0f), x, y + SCREEN_SCALE_Y(size + 1.0f), x + SCREEN_SCALE_X(size + 1.0f), y - (SCREEN_SCALE_Y(size + 1.0f)), x - (SCREEN_SCALE_X(size + 1.0f)), y - (SCREEN_SCALE_Y(size + 1.0f)), CRGBA(red, green, blue, alpha));
break;
@@ -1319,27 +1288,46 @@ 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();
-#ifdef MENU_MAP
+ TShirtSprite.Delete();
+ TommySprite.Delete();
+ PhoneSprite.Delete();
+ RadioWildstyleSprite.Delete();
+ RadioFlashSprite.Delete();
+ RadioKChatSprite.Delete();
+ RadioFeverSprite.Delete();
+ RadioVRockSprite.Delete();
+ RadioVCPRSprite.Delete();
+ RadioEspantosoSprite.Delete();
+ RadioEmotionSprite.Delete();
+ RadioWaveSprite.Delete();
+#ifdef MAP_ENHANCEMENTS
WaypointSprite.Delete();
#endif
RemoveRadarSections();
@@ -1347,7 +1335,8 @@ void CRadar::Shutdown()
void CRadar::StreamRadarSections(const CVector &posn)
{
- StreamRadarSections(Floor((2000.0f + posn.x) / 500.0f), Ceil(7.0f - (2000.0f + posn.y) / 500.0f));
+ if (!CStreaming::ms_disableStreaming)
+ StreamRadarSections(Floor((RADAR_MAX_X + posn.x) / RADAR_TILE_SIZE), Ceil((RADAR_NUM_TILES - 1) - (RADAR_MAX_Y + posn.y) / RADAR_TILE_SIZE));
}
void CRadar::StreamRadarSections(int32 x, int32 y)
@@ -1373,33 +1362,8 @@ void CRadar::TransformRealWorldToTexCoordSpace(CVector2D &out, const CVector2D &
void CRadar::TransformRadarPointToRealWorldSpace(CVector2D &out, const CVector2D &in)
{
float s, c;
-#if 1
s = -cachedSin;
c = cachedCos;
-#else
- // Original code
-
- s = -Sin(TheCamera.GetForward().Heading());
- c = Cos(TheCamera.GetForward().Heading());
-
- if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN || TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOP_DOWN_PED) {
- s = 0.0f;
- c = 1.0f;
- }
- else if (TheCamera.GetLookDirection() != LOOKING_FORWARD) {
- CVector forward;
-
- if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON) {
- forward = TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->GetForward();
- forward.Normalise(); // a bit useless...
- }
- else
- forward = TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->GetPosition() - TheCamera.Cams[TheCamera.ActiveCam].SourceBeforeLookBehind;
-
- s = -Sin(forward.Heading());
- c = Cos(forward.Heading());
- }
-#endif
out.x = s * in.y + c * in.x;
out.y = c * in.y - s * in.x;
@@ -1410,14 +1374,10 @@ void CRadar::TransformRadarPointToRealWorldSpace(CVector2D &out, const CVector2D
// Radar space goes from -1.0 to 1.0 in x and y, top right is (1.0, 1.0)
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;
- } else
-#endif
- {
+ 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 {
#ifdef FIX_BUGS
out.x = (in.x + 1.0f) * 0.5f * SCREEN_SCALE_X(RADAR_WIDTH) + SCREEN_SCALE_X(RADAR_LEFT);
#else
@@ -1430,35 +1390,8 @@ void CRadar::TransformRadarPointToScreenSpace(CVector2D &out, const CVector2D &i
void CRadar::TransformRealWorldPointToRadarSpace(CVector2D &out, const CVector2D &in)
{
float s, c;
-#if 1
s = cachedSin;
c = cachedCos;
-#else
- // Original code
-
- float s, c;
- if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN || TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOP_DOWN_PED) {
- s = 0.0f;
- c = 1.0f;
- }
- else if (TheCamera.GetLookDirection() == LOOKING_FORWARD) {
- s = Sin(TheCamera.GetForward().Heading());
- c = Cos(TheCamera.GetForward().Heading());
- }
- else {
- CVector forward;
-
- if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON) {
- forward = TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->GetForward();
- forward.Normalise(); // a bit useless...
- }
- else
- forward = TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->GetPosition() - TheCamera.Cams[TheCamera.ActiveCam].SourceBeforeLookBehind;
-
- s = Sin(forward.Heading());
- c = Cos(forward.Heading());
- }
-#endif
float x = (in.x - vec2DRadarOrigin.x) * (1.0f / m_radarRange);
float y = (in.y - vec2DRadarOrigin.y) * (1.0f / m_radarRange);
@@ -1470,11 +1403,8 @@ void CRadar::TransformRealWorldPointToRadarSpace(CVector2D &out, const CVector2D
void
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
-#endif
- ) {
+ if (/*TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN || TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOP_DOWN_PED || */
+ FrontEndMenuManager.m_bMenuMapActive ) {
cachedSin = 0.0f;
cachedCos = 1.0f;
} else if (TheCamera.GetLookDirection() == LOOKING_FORWARD) {
@@ -1495,14 +1425,19 @@ CRadar::CalculateCachedSinCos()
}
}
-#ifdef MENU_MAP
void
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;
+ }
+ MapLegendCounter = 0;
+ ArrowBlipColour1 = CRGBA(0, 0, 0, 0);
+ ArrowBlipColour2 = CRGBA(0, 0, 0, 0);
}
void
@@ -1524,14 +1459,33 @@ CRadar::DrawYouAreHereSprite(float x, float y)
}
if (show) {
- float left = x - SCREEN_SCALE_X(12.0f);
- float top = y;
- float right = SCREEN_SCALE_X(12.0) + x;
- float bottom = y - SCREEN_SCALE_Y(24.0f);
- CentreSprite.Draw(CRect(left, top, right, bottom), CRGBA(255, 255, 255, 255));
+ const float left = x - SCREEN_SCALE_X(8.0f);
+ const float top = y - SCREEN_SCALE_Y(40.0f);
+ const float right = x + SCREEN_SCALE_X(40.0);
+ const float bottom = y + SCREEN_SCALE_Y(8.0f);
+ MapHereSprite.Draw(CRect(left + SCREEN_SCALE_X(2.f), top + SCREEN_SCALE_Y(2.f), right + SCREEN_SCALE_X(2.f), bottom + SCREEN_SCALE_Y(2.f)),
+ CRGBA(0, 0, 0, 255));
+
+ MapHereSprite.Draw(CRect(left, top, right, bottom), CRGBA(255, 255, 255, 255));
+
+ CFont::SetWrapx(right + SCREEN_SCALE_X(28.0f));
+ CFont::SetRightJustifyWrap(right);
+ CFont::SetBackGroundOnlyTextOff();
+ CFont::SetColor(CRGBA(255, 150, 225, 255));
+ CFont::SetDropShadowPosition(2);
+ CFont::SetDropColor(CRGBA(0, 0, 0, 255));
+ CFont::SetCentreOff();
+ CFont::SetRightJustifyOff();
+ CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING));
+ CFont::SetScale(SCREEN_SCALE_X(0.65f), SCREEN_SCALE_Y(0.95f));
+ CFont::PrintString(right, top, TheText.Get("MAP_YAH"));
+ CFont::SetDropShadowPosition(0);
+ CFont::DrawFonts();
}
+ MapLegendList[MapLegendCounter++] = RADAR_SPRITE_MAP_HERE;
}
+#ifdef MAP_ENHANCEMENTS
void
CRadar::ToggleTargetMarker(float x, float y)
{
@@ -1541,10 +1495,10 @@ CRadar::ToggleTargetMarker(float x, float y)
if (!ms_RadarTrace[nextBlip].m_bInUse)
break;
}
-#ifdef FIX_BUGS
+
if (nextBlip == 0)
return;
-#endif
+
ms_RadarTrace[nextBlip].m_eBlipType = BLIP_COORD;
ms_RadarTrace[nextBlip].m_nColor = RADAR_TRACE_GRAY;
ms_RadarTrace[nextBlip].m_bDim = 0;
@@ -1566,3 +1520,292 @@ CRadar::ToggleTargetMarker(float x, float y)
}
#endif
+void
+CRadar::DrawEntityBlip(int32 blipId)
+{
+ CVector2D out;
+ CVector2D in;
+ CEntity *blipEntity;
+ switch (ms_RadarTrace[blipId].m_eBlipType) {
+ case BLIP_CAR:
+ blipEntity = CPools::GetVehiclePool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle);
+ break;
+ case BLIP_CHAR:
+ blipEntity = CPools::GetPedPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle);
+ if (blipEntity != nil) {
+ if (((CPed*)blipEntity)->InVehicle())
+ blipEntity = ((CPed*)blipEntity)->m_pMyVehicle;
+ }
+ break;
+ case BLIP_OBJECT:
+ blipEntity = CPools::GetObjectPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle);
+ break;
+ default:
+ break;
+ }
+ if (blipEntity) {
+ uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim);
+ if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
+ if (CTheScripts::IsDebugOn()) {
+ ShowRadarMarker(blipEntity->GetPosition(), color, ms_RadarTrace[blipId].m_Radius);
+ ms_RadarTrace[blipId].m_Radius = ms_RadarTrace[blipId].m_Radius - 0.1f;
+ if (ms_RadarTrace[blipId].m_Radius < 1.0f)
+ ms_RadarTrace[blipId].m_Radius = 5.0f;
+ }
+ }
+ if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BLIP_ONLY) {
+ TransformRealWorldPointToRadarSpace(in, blipEntity->GetPosition());
+ float dist = LimitRadarPoint(in);
+ TransformRadarPointToScreenSpace(out, in);
+ 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 {
+ const CVector& pos = FindPlayerCentreOfWorld_NoSniperShift();
+ const CVector& blipPos = blipEntity->GetPosition();
+ uint8 mode = BLIP_MODE_TRIANGULAR_UP;
+ if (blipPos.z - pos.z <= 2.0f) {
+ if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN;
+ else mode = BLIP_MODE_SQUARE;
+ }
+ ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode);
+
+ if (FrontEndMenuManager.m_bMenuMapActive) {
+ bool alreadyThere = false;
+ for (int i = 0; i < NUM_MAP_LEGENDS; i++) {
+ if (MapLegendList[i] == -2)
+ alreadyThere = true;
+ }
+ if (!alreadyThere) {
+ MapLegendList[MapLegendCounter] = -2;
+ MapLegendCounter++;
+ ArrowBlipColour2 = CRGBA((uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void
+CRadar::DrawCoordBlip(int32 blipId)
+{
+ CVector2D out;
+ CVector2D in;
+ if (ms_RadarTrace[blipId].m_eBlipType != BLIP_CONTACT_POINT || !CTheScripts::IsPlayerOnAMission()) {
+
+ uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim);
+ if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
+ if (CTheScripts::IsDebugOn()) {
+ ShowRadarMarker(ms_RadarTrace[blipId].m_vecPos, color, ms_RadarTrace[blipId].m_Radius);
+ ms_RadarTrace[blipId].m_Radius = ms_RadarTrace[blipId].m_Radius - 0.1f;
+ if (ms_RadarTrace[blipId].m_Radius < 1.0f)
+ ms_RadarTrace[blipId].m_Radius = 5.0f;
+ }
+ }
+ if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BLIP_ONLY) {
+ TransformRealWorldPointToRadarSpace(in, ms_RadarTrace[blipId].m_vec2DPos);
+ float dist = LimitRadarPoint(in);
+ TransformRadarPointToScreenSpace(out, in);
+ 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 {
+ const CVector& pos = FindPlayerCentreOfWorld_NoSniperShift();
+ const CVector& blipPos = ms_RadarTrace[blipId].m_vecPos;
+ uint8 mode = BLIP_MODE_TRIANGULAR_UP;
+ if (blipPos.z - pos.z <= 2.0f) {
+ if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN;
+ else mode = BLIP_MODE_SQUARE;
+ }
+ ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode);
+
+ if (FrontEndMenuManager.m_bMenuMapActive) {
+ bool alreadyThere = false;
+ for (int i = 0; i < NUM_MAP_LEGENDS; i++) {
+ if (MapLegendList[i] == -1)
+ alreadyThere = true;
+ }
+ if (!alreadyThere) {
+ MapLegendList[MapLegendCounter] = -1;
+ MapLegendCounter++;
+ ArrowBlipColour1 = CRGBA((uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void
+CRadar::DrawLegend(int32 x, int32 y, int32 sprite)
+{
+ if (sprite < 0) {
+ static uint32 lastChange = 0;
+ static int8 blipMode = 0;
+
+ CRGBA color;
+ if (sprite == -1) {
+ color = ArrowBlipColour1;
+ } else {
+ color = ArrowBlipColour2;
+ }
+
+ if (CTimer::GetTimeInMillisecondsPauseMode() - lastChange > 600) {
+ lastChange = CTimer::GetTimeInMillisecondsPauseMode();
+ if ( blipMode == 2 )
+ blipMode = 0;
+ else
+ ++blipMode;
+ }
+
+ switch (blipMode) {
+ case BLIP_MODE_TRIANGULAR_UP:
+ CSprite2d::Draw2DPolygon(x + SCREEN_SCALE_X(14.0f), y + SCREEN_SCALE_Y(13.0f), x + SCREEN_SCALE_X(2.0f), y + SCREEN_SCALE_Y(13.0f), x + SCREEN_SCALE_X(8.f), y + SCREEN_SCALE_Y(2.0f), x + SCREEN_SCALE_X(8.f), y + SCREEN_SCALE_Y(2.0f), CRGBA(0, 0, 0, 255));
+ CSprite2d::Draw2DPolygon(x + SCREEN_SCALE_X(12.0f), y + SCREEN_SCALE_Y(12.0f), x + SCREEN_SCALE_X(4.0f), y + SCREEN_SCALE_Y(12.0f), x + SCREEN_SCALE_X(8.f), y + SCREEN_SCALE_Y(4.0f), x + SCREEN_SCALE_X(8.f), y + SCREEN_SCALE_Y(4.0f), color);
+ break;
+ case BLIP_MODE_TRIANGULAR_DOWN:
+ CSprite2d::Draw2DPolygon(x + SCREEN_SCALE_X(8.0f), y + SCREEN_SCALE_Y(14.0f), x + SCREEN_SCALE_X(8.0f), y + SCREEN_SCALE_Y(14.0f), x + SCREEN_SCALE_X(2.f), y + SCREEN_SCALE_Y(3.0f), x + SCREEN_SCALE_X(2.f), y + SCREEN_SCALE_Y(3.0f), CRGBA(0, 0, 0, 255));
+ CSprite2d::Draw2DPolygon(x + SCREEN_SCALE_X(8.0f), y + SCREEN_SCALE_Y(12.0f), x + SCREEN_SCALE_X(8.0f), y + SCREEN_SCALE_Y(12.0f), x + SCREEN_SCALE_X(12.f), y + SCREEN_SCALE_Y(4.0f), x + SCREEN_SCALE_X(4.f), y + SCREEN_SCALE_Y(4.0f), color);
+ break;
+ case BLIP_MODE_SQUARE:
+ CSprite2d::DrawRect(CRect(x + SCREEN_SCALE_X(4.0f), y + SCREEN_SCALE_Y(3.0f), SCREEN_SCALE_X(12.0f) + x, SCREEN_SCALE_Y(12.0f) + y), CRGBA(0, 0, 0, 255));
+ CSprite2d::DrawRect(CRect(x + SCREEN_SCALE_X(5.0f), y + SCREEN_SCALE_Y(4.0f), SCREEN_SCALE_X(11.0f) + x, SCREEN_SCALE_Y(11.0f) + y), color);
+ break;
+ }
+
+ } else {
+ RadarSprites[sprite]->Draw(CRect(x, y, x + SCREEN_SCALE_X(16.f), y + SCREEN_SCALE_X(16.f)), CRGBA(255, 255, 255, 255));
+ }
+
+ wchar *text;
+ switch ( sprite ) {
+ case RADAR_SPRITE_ENTITY_BLIP:
+ text = TheText.Get("LG_38");
+ break;
+ case RADAR_SPRITE_COORD_BLIP:
+ text = TheText.Get("LG_35");
+ break;
+ case RADAR_SPRITE_MAP_HERE:
+ text = TheText.Get("LG_01");
+ break;
+ case RADAR_SPRITE_AVERY:
+ text = TheText.Get("LG_02");
+ break;
+ case RADAR_SPRITE_BIKER:
+ text = TheText.Get("LG_03");
+ break;
+ case RADAR_SPRITE_CORTEZ:
+ text = TheText.Get("LG_04");
+ break;
+ case RADAR_SPRITE_DIAZ:
+ text = TheText.Get("LG_05");
+ break;
+ case RADAR_SPRITE_KENT:
+ text = TheText.Get("LG_06");
+ break;
+ case RADAR_SPRITE_LAWYER:
+ text = TheText.Get("LG_07");
+ break;
+ case RADAR_SPRITE_PHIL:
+ text = TheText.Get("LG_08");
+ break;
+ case RADAR_SPRITE_BIKERS:
+ text = TheText.Get("LG_03");
+ break;
+ case RADAR_SPRITE_BOATYARD:
+ text = TheText.Get("LG_09");
+ break;
+ case RADAR_SPRITE_MALIBU_CLUB:
+ text = TheText.Get("LG_10");
+ break;
+ case RADAR_SPRITE_CUBANS:
+ text = TheText.Get("LG_11");
+ break;
+ case RADAR_SPRITE_FILM:
+ text = TheText.Get("LG_12");
+ break;
+ case RADAR_SPRITE_GUN:
+ text = TheText.Get("LG_13");
+ break;
+ case RADAR_SPRITE_HAITIANS:
+ text = TheText.Get("LG_14");
+ break;
+ case RADAR_SPRITE_HARDWARE:
+ text = TheText.Get("LG_15");
+ break;
+ case RADAR_SPRITE_SAVE:
+ text = TheText.Get("LG_16");
+ break;
+ case RADAR_SPRITE_STRIP:
+ text = TheText.Get("LG_37");
+ break;
+ case RADAR_SPRITE_ICE:
+ text = TheText.Get("LG_17");
+ break;
+ case RADAR_SPRITE_KCABS:
+ text = TheText.Get("LG_18");
+ break;
+ case RADAR_SPRITE_LOVEFIST:
+ text = TheText.Get("LG_19");
+ break;
+ case RADAR_SPRITE_PRINTWORKS:
+ text = TheText.Get("LG_20");
+ break;
+ case RADAR_SPRITE_PROPERTY:
+ text = TheText.Get("LG_21");
+ break;
+ case RADAR_SPRITE_SUNYARD:
+ text = TheText.Get("LG_36");
+ break;
+ case RADAR_SPRITE_SPRAY:
+ text = TheText.Get("LG_22");
+ break;
+ case RADAR_SPRITE_TSHIRT:
+ text = TheText.Get("LG_23");
+ break;
+ case RADAR_SPRITE_TOMMY:
+ text = TheText.Get("LG_24");
+ break;
+ case RADAR_SPRITE_PHONE:
+ text = TheText.Get("LG_25");
+ break;
+ case RADAR_SPRITE_RADIO_WILDSTYLE:
+ text = TheText.Get("LG_26");
+ break;
+ case RADAR_SPRITE_RADIO_FLASH:
+ text = TheText.Get("LG_27");
+ break;
+ case RADAR_SPRITE_RADIO_KCHAT:
+ text = TheText.Get("LG_28");
+ break;
+ case RADAR_SPRITE_RADIO_FEVER:
+ text = TheText.Get("LG_29");
+ break;
+ case RADAR_SPRITE_RADIO_VROCK:
+ text = TheText.Get("LG_30");
+ break;
+ case RADAR_SPRITE_RADIO_VCPR:
+ text = TheText.Get("LG_31");
+ break;
+ case RADAR_SPRITE_RADIO_ESPANTOSO:
+ text = TheText.Get("LG_32");
+ break;
+ case RADAR_SPRITE_RADIO_EMOTION:
+ text = TheText.Get("LG_33");
+ break;
+ case RADAR_SPRITE_RADIO_WAVE:
+ text = TheText.Get("LG_34");
+ break;
+#ifdef MAP_ENHANCEMENTS
+ case RADAR_SPRITE_WAYPOINT:
+ text = TheText.Get("LG_38");
+ break;
+#endif
+ default:
+ break;
+ }
+ CFont::PrintString(SCREEN_SCALE_X(20.f) + x, SCREEN_SCALE_Y(3.0f) + y, text);
+}
diff --git a/src/core/Radar.h b/src/core/Radar.h
index ae87d0fa..afb37fe4 100644
--- a/src/core/Radar.h
+++ b/src/core/Radar.h
@@ -2,6 +2,35 @@
#include "Sprite2d.h"
#include "Draw.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 228
+
+#define NUM_MAP_LEGENDS 75
+
+#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,
@@ -22,34 +51,52 @@ enum eBlipDisplay
enum eRadarSprite
{
-#ifdef MENU_MAP
RADAR_SPRITE_ENTITY_BLIP = -2,
RADAR_SPRITE_COORD_BLIP = -1,
-#endif
RADAR_SPRITE_NONE = 0,
- RADAR_SPRITE_ASUKA,
- RADAR_SPRITE_BOMB,
- RADAR_SPRITE_CAT,
RADAR_SPRITE_CENTRE,
- RADAR_SPRITE_COPCAR,
- RADAR_SPRITE_DON,
- RADAR_SPRITE_EIGHT,
- RADAR_SPRITE_EL,
- RADAR_SPRITE_ICE,
- RADAR_SPRITE_JOEY,
- RADAR_SPRITE_KENJI,
- RADAR_SPRITE_LIZ,
- RADAR_SPRITE_LUIGI,
+ RADAR_SPRITE_MAP_HERE,
RADAR_SPRITE_NORTH,
- RADAR_SPRITE_RAY,
- RADAR_SPRITE_SAL,
+ 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_TONY,
- RADAR_SPRITE_WEAPON,
-#ifdef MENU_MAP
+ 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,
+#ifdef MAP_ENHANCEMENTS
RADAR_SPRITE_WAYPOINT,
#endif
+
RADAR_SPRITE_COUNT
};
@@ -76,25 +123,43 @@ struct sRadarTrace
uint32 m_nColor;
uint32 m_eBlipType; // eBlipType
int32 m_nEntityHandle;
- CVector2D m_vec2DPos;
+ CVector m_vec2DPos;
CVector m_vecPos;
uint16 m_BlipIndex;
bool m_bDim;
bool m_bInUse;
+ bool m_bShortRange;
+ bool m_unused;
float m_Radius;
int16 m_wScale;
uint16 m_eBlipDisplay; // eBlipDisplay
uint16 m_eRadarSprite; // eRadarSprite
};
-VALIDATE_SIZE(sRadarTrace, 0x30);
+
+// Either that was a thing while saving/loading blips, or they added sizes of each field one by one. I want to do the former.
+#pragma pack(push,1)
+struct sRadarTraceSave
+{
+ uint32 m_nColor;
+ float m_Radius;
+ uint32 m_eBlipType; // eBlipType
+ int32 m_nEntityHandle;
+ CVector2D m_vec2DPos;
+ CVector m_vecPos;
+ uint16 m_BlipIndex;
+ bool m_bDim;
+ bool m_bInUse;
+ bool m_bShortRange;
+ bool m_unused;
+ int16 m_wScale;
+ uint16 m_eBlipDisplay; // eBlipDisplay
+ uint16 m_eRadarSprite; // eRadarSprite
+};
+#pragma pack(pop)
// Values for screen space
#define RADAR_LEFT (40.0f)
-#ifdef PS2_HUD
-#define RADAR_BOTTOM (44.0f)
-#else
-#define RADAR_BOTTOM (47.0f)
-#endif
+#define RADAR_BOTTOM (40.0f)
#ifdef FIX_RADAR
/*
@@ -123,36 +188,62 @@ 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 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
+ static CRGBA ArrowBlipColour1;
+ static CRGBA ArrowBlipColour2;
+ static int16 MapLegendList[NUM_MAP_LEGENDS];
+ static int16 MapLegendCounter;
+
+#ifdef MAP_ENHANCEMENTS
static CSprite2d WaypointSprite;
static int TargetMarkerId;
static CVector TargetMarkerPos;
+#endif
static void InitFrontEndMap();
static void DrawYouAreHereSprite(float, float);
+#ifdef MAP_ENHANCEMENTS
static void ToggleTargetMarker(float, float);
#endif
static uint8 CalculateBlipAlpha(float dist);
@@ -182,8 +273,9 @@ public:
static void RemoveRadarSections();
static void SaveAllRadarBlips(uint8*, uint32*);
static void SetBlipSprite(int32 i, int32 icon);
- static int32 SetCoordBlip(eBlipType type, CVector pos, int32, eBlipDisplay);
- static int32 SetEntityBlip(eBlipType type, int32, int32, eBlipDisplay);
+ static int32 SetCoordBlip(eBlipType type, CVector pos, uint32, eBlipDisplay);
+ static int32 SetEntityBlip(eBlipType type, int32, uint32, eBlipDisplay);
+ static int32 SetShortRangeCoordBlip(eBlipType type, CVector pos, uint32, eBlipDisplay);
static void SetRadarMarkerState(int32 i, bool flag);
static void ShowRadarMarker(CVector pos, uint32 color, float radius);
static void ShowRadarTrace(float x, float y, uint32 size, uint8 red, uint8 green, uint8 blue, uint8 alpha);
@@ -195,7 +287,8 @@ public:
static void TransformRadarPointToRealWorldSpace(CVector2D &out, const CVector2D &in);
static void TransformRadarPointToScreenSpace(CVector2D &out, const CVector2D &in);
static void TransformRealWorldPointToRadarSpace(CVector2D &out, const CVector2D &in);
-
- // no in CRadar in the game:
static void CalculateCachedSinCos();
+ static void DrawEntityBlip(int32 blipId);
+ static void DrawCoordBlip(int32 blipId);
+ static void DrawLegend(int32, int32, int32);
};
diff --git a/src/core/References.cpp b/src/core/References.cpp
index b7782099..09913817 100644
--- a/src/core/References.cpp
+++ b/src/core/References.cpp
@@ -42,6 +42,23 @@ CEntity::RegisterReference(CEntity **pent)
}
}
+// Clean up the reference from *pent -> 'this'
+void
+CEntity::CleanUpOldReference(CEntity **pent)
+{
+ CReference* ref, ** lastnextp;
+ lastnextp = &m_pFirstReference;
+ for (ref = m_pFirstReference; ref; ref = ref->next) {
+ if (ref->pentity == pent) {
+ *lastnextp = ref->next;
+ ref->next = CReferences::pEmptyList;
+ CReferences::pEmptyList = ref;
+ break;
+ }
+ lastnextp = &ref->next;
+ }
+}
+
// Clear all references to this entity
void
CEntity::ResolveReferences(void)
diff --git a/src/core/Ropes.cpp b/src/core/Ropes.cpp
new file mode 100644
index 00000000..71297eb1
--- /dev/null
+++ b/src/core/Ropes.cpp
@@ -0,0 +1,176 @@
+#include "common.h"
+
+#include "main.h"
+#include "Timer.h"
+#include "ModelIndices.h"
+#include "Streaming.h"
+#include "CopPed.h"
+#include "Population.h"
+#include "RenderBuffer.h"
+#include "Camera.h"
+#include "Ropes.h"
+
+CRope CRopes::aRopes[8];
+
+RwImVertexIndex RopeIndices[64] = {
+ 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7,
+ 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15,
+ 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23,
+ 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31,
+ 31, 32 // unused
+};
+
+void
+CRope::Update(void)
+{
+ int i;
+ float step = Pow(0.85f, CTimer::GetTimeStep());
+ if(!m_bWasRegistered && CTimer::GetTimeInMilliseconds() > m_updateTimer){
+ m_speed[0].z -= 0.0015f*CTimer::GetTimeStep();
+ m_pos[0] += m_speed[0]*CTimer::GetTimeStep();
+ }
+ for(i = 1; i < ARRAY_SIZE(m_pos); i++){
+ CVector prevPos = m_pos[i];
+ m_pos[i] += m_speed[i]*step*CTimer::GetTimeStep();
+ m_pos[i].z -= 0.05f*CTimer::GetTimeStep();
+ CVector dist = m_pos[i] - m_pos[i-1];
+ m_pos[i] = m_pos[i-1] + (0.625f/dist.Magnitude())*dist;
+ m_speed[i] = (m_pos[i] - prevPos)/CTimer::GetTimeStep();
+ }
+ if(!m_bWasRegistered && m_pos[0].z < 0.0f)
+ m_bActive = false;
+ m_bWasRegistered = false;
+}
+
+void
+CRope::Render(void)
+{
+ int i;
+ int numVerts = 0;
+ if(!TheCamera.IsSphereVisible(m_pos[16], 20.0f))
+ return;
+
+ for(i = 0; i < ARRAY_SIZE(m_pos); i++){
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[i], 128, 128, 128, 100);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[i], m_pos[i].x, m_pos[i].y, m_pos[i].z);
+ }
+
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
+
+ if(RwIm3DTransform(TempBufferRenderVertices, ARRAY_SIZE(m_pos), nil, rwIM3D_VERTEXXYZ|rwIM3D_VERTEXRGBA)){
+#ifdef FIX_BUGS
+ RwIm3DRenderIndexedPrimitive(rwPRIMTYPELINELIST, RopeIndices, 2*(ARRAY_SIZE(m_pos)-1));
+#else
+ RwIm3DRenderIndexedPrimitive(rwPRIMTYPEPOLYLINE, RopeIndices, 2*(ARRAY_SIZE(m_pos)-1));
+#endif
+ RwIm3DEnd();
+ }
+}
+
+
+void
+CRopes::Init(void)
+{
+ int i;
+ for(i = 0; i < ARRAY_SIZE(aRopes); i++)
+ aRopes[i].m_bActive = false;
+}
+
+void
+CRopes::Update(void)
+{
+ int i;
+ for(i = 0; i < ARRAY_SIZE(aRopes); i++)
+ if(aRopes[i].m_bActive)
+ aRopes[i].Update();
+}
+
+void
+CRopes::Render(void)
+{
+ int i;
+ PUSH_RENDERGROUP("CRopes::Render");
+ for(i = 0; i < ARRAY_SIZE(aRopes); i++)
+ if(aRopes[i].m_bActive)
+ aRopes[i].Render();
+ POP_RENDERGROUP();
+}
+
+bool
+CRopes::RegisterRope(uintptr id, CVector pos, bool setUpdateTimer)
+{
+ int i, j;
+ for(i = 0; i < ARRAY_SIZE(aRopes); i++){
+ if(aRopes[i].m_bActive && aRopes[i].m_id == id){
+ aRopes[i].m_pos[0] = pos;
+ aRopes[i].m_speed[0] = CVector(0.0f, 0.0f, 0.0f);
+ aRopes[i].m_bWasRegistered = true;
+ return true;
+ }
+ }
+ for(i = 0; i < ARRAY_SIZE(aRopes); i++)
+ if(!aRopes[i].m_bActive){
+ aRopes[i].m_id = id;
+ aRopes[i].m_pos[0] = pos;
+ aRopes[i].m_speed[0] = CVector(0.0f, 0.0f, 0.0f);
+ aRopes[i].m_unk = false;
+ aRopes[i].m_bWasRegistered = true;
+ aRopes[i].m_updateTimer = setUpdateTimer ? CTimer::GetTimeInMilliseconds() + 20000 : 0;
+ for(j = 1; j < ARRAY_SIZE(aRopes[0].m_pos); j++){
+ if(j & 1)
+ aRopes[i].m_pos[j] = aRopes[i].m_pos[j-1] + CVector(0.0f, 0.0f, 0.625f);
+ else
+ aRopes[i].m_pos[j] = aRopes[i].m_pos[j-1] - CVector(0.0f, 0.0f, 0.625f);
+ aRopes[i].m_speed[j] = CVector(0.0f, 0.0f, 0.0f);
+ }
+ aRopes[i].m_bActive = true;
+ return true;
+ }
+ return false;
+}
+
+void
+CRopes::SetSpeedOfTopNode(uintptr id, CVector speed)
+{
+ int i;
+ for(i = 0; i < ARRAY_SIZE(aRopes); i++)
+ if(aRopes[i].m_bActive && aRopes[i].m_id == id){
+ aRopes[i].m_speed[0] = speed;
+ return;
+ }
+}
+
+bool
+CRopes::FindCoorsAlongRope(uintptr id, float t, CVector *coors)
+{
+ int i, j;
+ float f;
+ for(i = 0; i < ARRAY_SIZE(aRopes); i++)
+ if(aRopes[i].m_bActive && aRopes[i].m_id == id){
+ t = (ARRAY_SIZE(aRopes[0].m_pos)-1)*Clamp(t, 0.0f, 0.999f);
+ j = t;
+ f = t - j;
+ *coors = (1.0f-f)*aRopes[i].m_pos[j] + f*aRopes[i].m_pos[j+1];
+ return true;
+ }
+ return false;
+}
+
+bool
+CRopes::CreateRopeWithSwatComingDown(CVector pos)
+{
+ static uint32 ropeId = 0;
+
+ if(!CStreaming::HasModelLoaded(MI_SWAT) || !RegisterRope(ropeId+100, pos, true))
+ return false;
+ CCopPed *swat = (CCopPed*)CPopulation::AddPed(PEDTYPE_COP, COP_HELI_SWAT, pos);
+ swat->bUsesCollision = false;
+ swat->m_pRopeEntity = (CEntity*)1;
+ swat->m_nRopeID = 100 + ropeId;
+ CAnimManager::BlendAnimation(swat->GetClump(), ASSOCGRP_STD, ANIM_STD_ABSEIL, 4.0f);
+ ropeId++;
+ return true;
+}
diff --git a/src/core/Ropes.h b/src/core/Ropes.h
new file mode 100644
index 00000000..7930fa98
--- /dev/null
+++ b/src/core/Ropes.h
@@ -0,0 +1,31 @@
+#pragma once
+
+class CRope
+{
+public:
+ bool m_bActive;
+ bool m_bWasRegistered;
+ bool m_unk;
+ uintptr m_id;
+ uint32 m_updateTimer;
+ CVector m_pos[32];
+ CVector m_speed[32];
+
+ void Update(void);
+ void Render(void);
+};
+
+class CRopes
+{
+ static CRope aRopes[8];
+
+public:
+
+ static void Init(void);
+ static void Update(void);
+ static void Render(void);
+ static bool RegisterRope(uintptr id, CVector pos, bool setUpdateTimer);
+ static void SetSpeedOfTopNode(uintptr id, CVector speed);
+ static bool FindCoorsAlongRope(uintptr id, float t, CVector *coors);
+ static bool CreateRopeWithSwatComingDown(CVector pos);
+};
diff --git a/src/core/Stats.cpp b/src/core/Stats.cpp
index 9afd8ac3..8c6137f2 100644
--- a/src/core/Stats.cpp
+++ b/src/core/Stats.cpp
@@ -3,7 +3,27 @@
#include "Stats.h"
#include "Text.h"
#include "World.h"
+#include "Pad.h"
+#include "DMAudio.h"
+#include "main.h"
+#include "Font.h"
+#include "Frontend.h"
+#include "audio_enums.h"
+#include <climits>
+
+#ifdef USE_PRECISE_MEASUREMENT_CONVERTION
+#define MILES_IN_METER 0.000621371192f
+#define FEET_IN_METER 3.28084f
+#else
+#define MILES_IN_METER (1 / 1670.f)
+#define FEET_IN_METER 3.33f
+#endif
+
+int32 CStats::SeagullsKilled;
+int32 CStats::BoatsExploded;
+int32 CStats::WantedStarsAttained;
+int32 CStats::WantedStarsEvaded;
int32 CStats::DaysPassed;
int32 CStats::HeadsPopped;
int32 CStats::CommercialPassed;
@@ -16,10 +36,27 @@ int32 CStats::PedsKilledOfThisType[NUM_PEDTYPES];
int32 CStats::TimesDied;
int32 CStats::TimesArrested;
int32 CStats::KillsSinceLastCheckpoint;
-float CStats::DistanceTravelledInVehicle;
+float CStats::DistanceTravelledByCar;
+float CStats::DistanceTravelledByHelicoptor;
+float CStats::DistanceTravelledByBike;
+float CStats::DistanceTravelledByBoat;
+float CStats::DistanceTravelledByPlane;
+float CStats::DistanceTravelledByGolfCart;
float CStats::DistanceTravelledOnFoot;
-int32 CStats::ProgressMade;
-int32 CStats::TotalProgressInGame;
+int32 CStats::FlightTime;
+int32 CStats::TimesDrowned;
+int32 CStats::PhotosTaken;
+float CStats::LoanSharks;
+float CStats::StoresKnockedOff;
+float CStats::MovieStunts;
+float CStats::Assassinations;
+float CStats::PizzasDelivered;
+float CStats::GarbagePickups;
+float CStats::IceCreamSold;
+float CStats::TopShootingRangeScore;
+float CStats::ShootingRank;
+float CStats::ProgressMade;
+float CStats::TotalProgressInGame;
int32 CStats::CarsExploded;
int32 CStats::PeopleKilledByPlayer;
float CStats::MaximumJumpDistance;
@@ -35,84 +72,156 @@ int32 CStats::MissionsGiven;
int32 CStats::MissionsPassed;
char CStats::LastMissionPassedName[8];
int32 CStats::TotalLegitimateKills;
-int32 CStats::ElBurroTime;
-int32 CStats::Record4x4One;
-int32 CStats::Record4x4Two;
-int32 CStats::Record4x4Three;
-int32 CStats::Record4x4Mayhem;
int32 CStats::LivesSavedWithAmbulance;
int32 CStats::CriminalsCaught;
int32 CStats::HighestLevelAmbulanceMission;
+int32 CStats::HighestLevelVigilanteMission;
+int32 CStats::HighestLevelFireMission;
int32 CStats::FiresExtinguished;
-int32 CStats::LongestFlightInDodo;
-int32 CStats::TimeTakenDefuseMission;
int32 CStats::TotalNumberKillFrenzies;
int32 CStats::TotalNumberMissions;
int32 CStats::RoundsFiredByPlayer;
int32 CStats::KgsOfExplosivesUsed;
-int32 CStats::InstantHitsFiredByPlayer;
-int32 CStats::InstantHitsHitByPlayer;
+int32 CStats::BulletsThatHit;
int32 CStats::BestTimeBombDefusal;
-int32 CStats::mmRain;
-int32 CStats::CarsCrushed;
int32 CStats::FastestTimes[CStats::TOTAL_FASTEST_TIMES];
int32 CStats::HighestScores[CStats::TOTAL_HIGHEST_SCORES];
+int32 CStats::BestPositions[CStats::TOTAL_BEST_POSITIONS];
+bool CStats::PropertyOwned[CStats::TOTAL_PROPERTIES];
+int32 CStats::NumPropertyOwned;
+int32 CStats::PropertyDestroyed;
+float CStats::HighestChaseValue;
+int32 CStats::CheatedCount;
+int32 CStats::ShowChaseStatOnScreen;
+int32 CStats::PamphletMissionPassed;
+bool CStats::abSonyCDs[1];
+int32 CStats::BloodRingKills;
+int32 CStats::BloodRingTime;
+float CStats::FavoriteRadioStationList[NUM_RADIOS];
+
+int32 CStats::Sprayings;
+float CStats::AutoPaintingBudget;
+int32 CStats::NoMoreHurricanes;
+float CStats::FashionBudget;
+float CStats::PropertyBudget;
+float CStats::WeaponBudget;
+int32 CStats::SafeHouseVisits;
+int32 CStats::TyresPopped;
+
+int32 CStats::LongestWheelie;
+int32 CStats::LongestStoppie;
+int32 CStats::Longest2Wheel;
+float CStats::LongestWheelieDist;
+float CStats::LongestStoppieDist;
+float CStats::Longest2WheelDist;
void CStats::Init()
{
PeopleKilledByOthers = 0;
PeopleKilledByPlayer = 0;
- RoundsFiredByPlayer = 0;
CarsExploded = 0;
+ BoatsExploded = 0;
+ RoundsFiredByPlayer = 0;
+ for (int i = 0; i < NUM_PEDTYPES; i++)
+ PedsKilledOfThisType[i] = 0;
HelisDestroyed = 0;
- ProgressMade = 0;
+ ProgressMade = 0.0f;
KgsOfExplosivesUsed = 0;
- InstantHitsFiredByPlayer = 0;
- InstantHitsHitByPlayer = 0;
- CarsCrushed = 0;
+ BulletsThatHit = 0;
+ TyresPopped = 0;
HeadsPopped = 0;
+ WantedStarsAttained = 0;
+ WantedStarsEvaded = 0;
TimesArrested = 0;
TimesDied = 0;
DaysPassed = 0;
- NumberOfUniqueJumpsFound = 0;
- mmRain = 0;
- MaximumJumpFlips = 0;
- MaximumJumpSpins = 0;
+ SafeHouseVisits = 0;
+ Sprayings = 0;
MaximumJumpDistance = 0;
MaximumJumpHeight = 0;
+ MaximumJumpFlips = 0;
+ MaximumJumpSpins = 0;
BestStuntJump = 0;
+ NumberOfUniqueJumpsFound = 0;
TotalNumberOfUniqueJumps = 0;
- Record4x4One = 0;
- LongestFlightInDodo = 0;
- Record4x4Two = 0;
+ MissionsGiven = 0;
+ MissionsPassed = 0;
PassengersDroppedOffWithTaxi = 0;
- Record4x4Three = 0;
MoneyMadeWithTaxi = 0;
- Record4x4Mayhem = 0;
+ DistanceTravelledOnFoot = 0;
+ DistanceTravelledByCar = 0;
+ DistanceTravelledByBike = 0;
+ DistanceTravelledByBoat = 0;
+ DistanceTravelledByGolfCart = 0;
+ DistanceTravelledByHelicoptor = 0;
+#ifdef FIX_BUGS
+ DistanceTravelledByPlane = 0;
+#endif
LivesSavedWithAmbulance = 0;
- ElBurroTime = 0;
CriminalsCaught = 0;
- MissionsGiven = 0;
+ HighestLevelVigilanteMission = 0;
HighestLevelAmbulanceMission = 0;
- MissionsPassed = 0;
+ HighestLevelFireMission = 0;
FiresExtinguished = 0;
- DistanceTravelledOnFoot = 0;
- TimeTakenDefuseMission = 0;
+ PhotosTaken = 0;
NumberKillFrenziesPassed = 0;
- DistanceTravelledInVehicle = 0;
TotalNumberKillFrenzies = 0;
TotalNumberMissions = 0;
- KillsSinceLastCheckpoint = 0;
- TotalLegitimateKills = 0;
+ FlightTime = 0;
+ TimesDrowned = 0;
+ SeagullsKilled = 0;
+ WeaponBudget = 0.0f;
+ FashionBudget = 0.0f;
+ LoanSharks = 0.0f;
+ StoresKnockedOff = 0.0f;
+ MovieStunts = 0.0f;
+ Assassinations = 0.0f;
+ PizzasDelivered = 0.0f;
+ GarbagePickups = 0.0f;
+ IceCreamSold = 0.0f;
+ TopShootingRangeScore = 0.0f;
+ ShootingRank = 0.0f;
+ LongestWheelie = 0;
+ LongestStoppie = 0;
+ Longest2Wheel = 0;
+ LongestWheelieDist = 0.0f;
+ LongestStoppieDist = 0.0f;
+ Longest2WheelDist = 0.0f;
+ PropertyBudget = 0.0f;
+ AutoPaintingBudget = 0.0f;
+ PropertyDestroyed = 0;
+ HighestChaseValue = 0.0f;
+ CheatedCount = 0;
+
for (int i = 0; i < TOTAL_FASTEST_TIMES; i++)
FastestTimes[i] = 0;
for (int i = 0; i < TOTAL_HIGHEST_SCORES; i++)
HighestScores[i] = 0;
- for (int i = 0; i < NUM_PEDTYPES; i++)
- PedsKilledOfThisType[i] = 0;
+ for (int i = 0; i < TOTAL_BEST_POSITIONS; i++)
+ BestPositions[i] = INT_MAX;
+
+ KillsSinceLastCheckpoint = 0;
+ TotalLegitimateKills = 0;
+
+ for (int i = 0; i < ARRAY_SIZE(LastMissionPassedName); i++)
+ LastMissionPassedName[i] = 0;
+
IndustrialPassed = 0;
CommercialPassed = 0;
SuburbanPassed = 0;
+ PamphletMissionPassed = 0;
+ NoMoreHurricanes = 0;
+ ShowChaseStatOnScreen = 0;
+ for (int i = 0; i < ARRAY_SIZE(abSonyCDs); i++)
+ abSonyCDs[i] = 0;
+ PopulateFavoriteRadioStationList();
+
+ NumPropertyOwned = 0;
+ for (int i = 0; i < TOTAL_PROPERTIES; i++)
+ PropertyOwned[i] = false;
+
+ BloodRingKills = 0;
+ BloodRingTime = 0;
}
void CStats::RegisterFastestTime(int32 index, int32 time)
@@ -130,29 +239,10 @@ void CStats::RegisterHighestScore(int32 index, int32 score)
HighestScores[index] = Max(HighestScores[index], score);
}
-void CStats::RegisterElBurroTime(int32 time)
-{
- ElBurroTime = (ElBurroTime && ElBurroTime < time) ? ElBurroTime : time;
-}
-
-void CStats::Register4x4OneTime(int32 time)
-{
- Record4x4One = (Record4x4One && Record4x4One < time) ? Record4x4One : time;
-}
-
-void CStats::Register4x4TwoTime(int32 time)
-{
- Record4x4Two = (Record4x4Two && Record4x4Two < time) ? Record4x4Two : time;
-}
-
-void CStats::Register4x4ThreeTime(int32 time)
-{
- Record4x4Three = (Record4x4Three && Record4x4Three < time) ? Record4x4Three : time;
-}
-
-void CStats::Register4x4MayhemTime(int32 time)
+void CStats::RegisterBestPosition(int32 index, int32 position)
{
- Record4x4Mayhem = (Record4x4Mayhem && Record4x4Mayhem < time) ? Record4x4Mayhem : time;
+ assert(index >= 0 && index < TOTAL_BEST_POSITIONS);
+ BestPositions[index] = Min(BestPositions[index], position);
}
void CStats::AnotherLifeSavedWithAmbulance()
@@ -170,19 +260,19 @@ void CStats::RegisterLevelAmbulanceMission(int32 level)
HighestLevelAmbulanceMission = Max(HighestLevelAmbulanceMission, level);
}
-void CStats::AnotherFireExtinguished()
+void CStats::RegisterLevelVigilanteMission(int32 level)
{
- ++FiresExtinguished;
+ HighestLevelVigilanteMission = Max(HighestLevelVigilanteMission, level);
}
-void CStats::RegisterLongestFlightInDodo(int32 time)
+void CStats::RegisterLevelFireMission(int32 level)
{
- LongestFlightInDodo = Max(LongestFlightInDodo, time);
+ HighestLevelFireMission = Max(HighestLevelFireMission, level);
}
-void CStats::RegisterTimeTakenDefuseMission(int32 time)
+void CStats::AnotherFireExtinguished()
{
- TimeTakenDefuseMission = (TimeTakenDefuseMission && TimeTakenDefuseMission < time) ? TimeTakenDefuseMission : time;
+ ++FiresExtinguished;
}
void CStats::AnotherKillFrenzyPassed()
@@ -204,43 +294,202 @@ wchar *CStats::FindCriminalRatingString()
{
int rating = FindCriminalRatingNumber();
- if (rating < 10) return TheText.Get("RATNG1");
- if (rating < 25) return TheText.Get("RATNG2");
- if (rating < 70) return TheText.Get("RATNG3");
- if (rating < 150) return TheText.Get("RATNG4");
- if (rating < 250) return TheText.Get("RATNG5");
- if (rating < 450) return TheText.Get("RATNG6");
- if (rating < 700) return TheText.Get("RATNG7");
- if (rating < 1000) return TheText.Get("RATNG8");
- if (rating < 1400) return TheText.Get("RATNG9");
- if (rating < 1900) return TheText.Get("RATNG10");
- if (rating < 2500) return TheText.Get("RATNG11");
- if (rating < 3200) return TheText.Get("RATNG12");
- if (rating < 4000) return TheText.Get("RATNG13");
- if (rating < 5000) return TheText.Get("RATNG14");
- return TheText.Get("RATNG15");
+ if (rating < 0) {
+ if (rating > -500) return TheText.Get("RATNG53");
+ if (rating > -2000) return TheText.Get("RATNG54");
+ if (rating > -4000) return TheText.Get("RATNG55");
+ if (rating > -6000) return TheText.Get("RATNG56");
+ return TheText.Get("RATNG57");
+ }
+ if (rating < 20) return TheText.Get("RATNG1");
+ if (rating < 50) return TheText.Get("RATNG2");
+ if (rating < 75) return TheText.Get("RATNG3");
+ if (rating < 100) return TheText.Get("RATNG4");
+ if (rating < 120) return TheText.Get("RATNG5");
+ if (rating < 150) return TheText.Get("RATNG6");
+ if (rating < 200) return TheText.Get("RATNG7");
+ if (rating < 240) return TheText.Get("RATNG8");
+ if (rating < 270) return TheText.Get("RATNG9");
+ if (rating < 300) return TheText.Get("RATNG10");
+ if (rating < 335) return TheText.Get("RATNG11");
+ if (rating < 370) return TheText.Get("RATNG12");
+ if (rating < 400) return TheText.Get("RATNG13");
+ if (rating < 450) return TheText.Get("RATNG14");
+ if (rating < 500) return TheText.Get("RATNG15");
+ if (rating < 550) return TheText.Get("RATNG16");
+ if (rating < 600) return TheText.Get("RATNG17");
+ if (rating < 610) return TheText.Get("RATNG18");
+ if (rating < 650) return TheText.Get("RATNG19");
+ if (rating < 700) return TheText.Get("RATNG20");
+ if (rating < 850) return TheText.Get("RATNG21");
+ if (rating < 1000) return TheText.Get("RATNG22");
+ if (rating < 1005) return TheText.Get("RATNG23");
+ if (rating < 1150) return TheText.Get("RATNG24");
+ if (rating < 1300) return TheText.Get(TimesArrested > 0 ? "RATNG25" : "RATNG24");
+ if (rating < 1500) return TheText.Get("RATNG26");
+ if (rating < 1700) return TheText.Get("RATNG27");
+ if (rating < 2000) return TheText.Get("RATNG28");
+ if (rating < 2100) return TheText.Get("RATNG29");
+ if (rating < 2300) return TheText.Get("RATNG30");
+ if (rating < 2500) return TheText.Get("RATNG31");
+ if (rating < 2750) return TheText.Get("RATNG32");
+ if (rating < 3000) return TheText.Get("RATNG33");
+ if (rating < 3500) return TheText.Get("RATNG34");
+ if (rating < 4000) return TheText.Get("RATNG35");
+ if (rating < 5000) return TheText.Get("RATNG36");
+ if (rating < 7500) return TheText.Get("RATNG37");
+ if (rating < 10000) return TheText.Get("RATNG38");
+ if (rating < 20000) return TheText.Get("RATNG39");
+ if (rating < 30000) return TheText.Get("RATNG40");
+ if (rating < 40000) return TheText.Get("RATNG41");
+ if (rating < 50000) return TheText.Get("RATNG42");
+ if (rating < 65000) return TheText.Get("RATNG43");
+ if (rating < 80000) return TheText.Get("RATNG44");
+ if (rating < 100000) return TheText.Get("RATNG45");
+ if (rating < 150000) return TheText.Get("RATNG46");
+ if (rating < 200000) return TheText.Get("RATNG47");
+ if (rating < 300000) return TheText.Get("RATNG48");
+ if (rating < 375000) return TheText.Get("RATNG49");
+ if (rating < 500000) return TheText.Get(FlightTime / 60000 / 60 > 10 ? "RATNG50" : "RATNG49");
+ if (rating < 1000000) return TheText.Get("RATNG51");
+ return TheText.Get(CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney > 10000000 ? "RATNG52" : "RATNG51");
+}
+
+wchar *CStats::FindChaseString(float fMediaLevel) {
+ if (fMediaLevel < 20.0f) return TheText.Get("CHASE1");
+ if (fMediaLevel < 50.0f) return TheText.Get("CHASE2");
+ if (fMediaLevel < 75.0f) return TheText.Get("CHASE3");
+ if (fMediaLevel < 100.0f) return TheText.Get("CHASE4");
+ if (fMediaLevel < 150.0f) return TheText.Get("CHASE5");
+ if (fMediaLevel < 200.0f) return TheText.Get("CHASE6");
+ if (fMediaLevel < 250.0f) return TheText.Get("CHASE7");
+ if (fMediaLevel < 300.0f) return TheText.Get("CHASE8");
+ if (fMediaLevel < 350.0f) return TheText.Get("CHASE9");
+ if (fMediaLevel < 400.0f) return TheText.Get("CHASE10");
+ if (fMediaLevel < 500.0f) return TheText.Get("CHASE11");
+ if (fMediaLevel < 600.0f) return TheText.Get("CHASE12");
+ if (fMediaLevel < 700.0f) return TheText.Get("CHASE13");
+ if (fMediaLevel < 800.0f) return TheText.Get("CHASE14");
+ if (fMediaLevel < 900.0f) return TheText.Get("CHASE15");
+ if (fMediaLevel < 1000.0f) return TheText.Get("CHASE16");
+ if (fMediaLevel < 1200.0f) return TheText.Get("CHASE17");
+ if (fMediaLevel < 1400.0f) return TheText.Get("CHASE18");
+ if (fMediaLevel < 1600.0f) return TheText.Get("CHASE19");
+ if (fMediaLevel < 1800.0f) return TheText.Get("CHASE20");
+ return TheText.Get("CHASE21");
}
int32 CStats::FindCriminalRatingNumber()
{
int32 rating;
- rating = FiresExtinguished + 10 * HighestLevelAmbulanceMission + CriminalsCaught + LivesSavedWithAmbulance
+ rating = FiresExtinguished + 10 * HighestLevelFireMission + 10 * HighestLevelAmbulanceMission
+ + CriminalsCaught + LivesSavedWithAmbulance
+ 30 * HelisDestroyed + TotalLegitimateKills - 3 * TimesArrested - 3 * TimesDied
+ CWorld::Players[CWorld::PlayerInFocus].m_nMoney / 5000;
- if (rating <= 0) rating = 0;
+ if (CPad::bHasPlayerCheated || CheatedCount > 0) {
+ rating -= CheatedCount;
+ if (rating <= -10000)
+ rating = -10000;
+
+ } else if (rating <= 0) {
+ rating = 0;
+ }
- if (InstantHitsFiredByPlayer > 100)
- rating += (float)CStats::InstantHitsHitByPlayer / (float)CStats::InstantHitsFiredByPlayer * 500.0f;
+ if (RoundsFiredByPlayer > 100)
+ rating += (float)BulletsThatHit / (float)RoundsFiredByPlayer * 500.0f;
if (TotalProgressInGame)
- rating += (float)CStats::ProgressMade / (float)CStats::TotalProgressInGame * 1000.0f;
- if (!IndustrialPassed && rating >= 3521)
- rating = 3521;
- if (!CommercialPassed && rating >= 4552)
- rating = 4552;
+ rating += ProgressMade / TotalProgressInGame * 1000.0f;
return rating;
}
+float CStats::GetPercentageProgress()
+{
+ float percentCompleted = (TotalProgressInGame == 0.f ? 0.f :
+ 100.0f * ProgressMade / (CGame::nastyGame ? TotalProgressInGame : TotalProgressInGame - 1.0f));
+
+ return Min(percentCompleted, 100.0f);
+}
+
+void CStats::MoneySpentOnWeapons(int32 money)
+{
+ WeaponBudget += money;
+}
+
+void CStats::MoneySpentOnProperty(int32 money)
+{
+ PropertyBudget += money;
+}
+
+void CStats::MoneySpentOnAutoPainting(int32 money)
+{
+ AutoPaintingBudget += money;
+}
+
+void CStats::MoneySpentOnFashion(int32 money)
+{
+ FashionBudget += money;
+}
+
+void CStats::NumOfVisitsFromLoanSharks(int32 num)
+{
+ LoanSharks += num;
+}
+
+void CStats::NumOfStoresKnockedOff(int32 num)
+{
+ StoresKnockedOff += num;
+}
+
+void CStats::NumOfMovieStunts(int32 num)
+{
+ MovieStunts += num;
+}
+
+void CStats::NumOfAssassinations(int32 num)
+{
+ Assassinations += num;
+}
+
+void CStats::NumOfPizzasDelivered(int32 num)
+{
+ PizzasDelivered += num;
+}
+
+void CStats::NumOfGarbagePickups(int32 num)
+{
+ GarbagePickups += num;
+}
+
+void CStats::NumOfIceCreamSold(int32 num)
+{
+ IceCreamSold += num;
+}
+
+void CStats::AddNumBloodRingKills(int32 num)
+{
+ BloodRingKills += num;
+}
+
+void CStats::LongestTimeInBloodRing(int32 time)
+{
+ if (BloodRingTime < time)
+ BloodRingTime = time;
+}
+
+void CStats::AddPropertyAsOwned(int32 id)
+{
+ if (!PropertyOwned[id]) {
+ PropertyOwned[id] = true;
+ ++NumPropertyOwned;
+ }
+}
+
+float CStats::GetFavoriteRadioStationList(int32 station)
+{
+ return FavoriteRadioStationList[station];
+}
+
void CStats::SaveStats(uint8 *buf, uint32 *size)
{
CheckPointReachedSuccessfully();
@@ -248,20 +497,23 @@ void CStats::SaveStats(uint8 *buf, uint32 *size)
*size = sizeof(PeopleKilledByPlayer) +
sizeof(PeopleKilledByOthers) +
sizeof(CarsExploded) +
+ sizeof(BoatsExploded) +
+ sizeof(TyresPopped) +
sizeof(RoundsFiredByPlayer) +
sizeof(PedsKilledOfThisType) +
sizeof(HelisDestroyed) +
sizeof(ProgressMade) +
sizeof(TotalProgressInGame) +
sizeof(KgsOfExplosivesUsed) +
- sizeof(InstantHitsFiredByPlayer) +
- sizeof(InstantHitsHitByPlayer) +
- sizeof(CarsCrushed) +
+ sizeof(BulletsThatHit) +
sizeof(HeadsPopped) +
+ sizeof(WantedStarsAttained) +
+ sizeof(WantedStarsEvaded) +
sizeof(TimesArrested) +
sizeof(TimesDied) +
sizeof(DaysPassed) +
- sizeof(mmRain) +
+ sizeof(SafeHouseVisits) +
+ sizeof(Sprayings) +
sizeof(MaximumJumpDistance) +
sizeof(MaximumJumpHeight) +
sizeof(MaximumJumpFlips) +
@@ -270,52 +522,88 @@ void CStats::SaveStats(uint8 *buf, uint32 *size)
sizeof(NumberOfUniqueJumpsFound) +
sizeof(TotalNumberOfUniqueJumps) +
sizeof(MissionsGiven) +
- sizeof(MissionsPassed) +
sizeof(PassengersDroppedOffWithTaxi) +
sizeof(MoneyMadeWithTaxi) +
sizeof(IndustrialPassed) +
sizeof(CommercialPassed) +
sizeof(SuburbanPassed) +
- sizeof(ElBurroTime) +
+ sizeof(PamphletMissionPassed) +
+ sizeof(NoMoreHurricanes) +
sizeof(DistanceTravelledOnFoot) +
- sizeof(DistanceTravelledInVehicle) +
- sizeof(Record4x4One) +
- sizeof(Record4x4Two) +
- sizeof(Record4x4Three) +
- sizeof(Record4x4Mayhem) +
+ sizeof(DistanceTravelledByCar) +
+ sizeof(DistanceTravelledByBike) +
+ sizeof(DistanceTravelledByBoat) +
+ sizeof(DistanceTravelledByGolfCart) +
+ sizeof(DistanceTravelledByHelicoptor) +
+ sizeof(DistanceTravelledByPlane) +
sizeof(LivesSavedWithAmbulance) +
sizeof(CriminalsCaught) +
- sizeof(HighestLevelAmbulanceMission) +
sizeof(FiresExtinguished) +
- sizeof(LongestFlightInDodo) +
- sizeof(TimeTakenDefuseMission) +
+ sizeof(HighestLevelVigilanteMission) +
+ sizeof(HighestLevelAmbulanceMission) +
+ sizeof(HighestLevelFireMission) +
+ sizeof(PhotosTaken) +
sizeof(NumberKillFrenziesPassed) +
sizeof(TotalNumberKillFrenzies) +
sizeof(TotalNumberMissions) +
+ sizeof(FlightTime) +
+ sizeof(TimesDrowned) +
+ sizeof(SeagullsKilled) +
+ sizeof(WeaponBudget) +
+ sizeof(FashionBudget) +
+ sizeof(LoanSharks) +
+ sizeof(StoresKnockedOff) +
+ sizeof(MovieStunts) +
+ sizeof(Assassinations) +
+ sizeof(PizzasDelivered) +
+ sizeof(GarbagePickups) +
+ sizeof(IceCreamSold) +
+ sizeof(TopShootingRangeScore) +
+ sizeof(ShootingRank) +
+ sizeof(LongestWheelie) +
+ sizeof(LongestStoppie) +
+ sizeof(Longest2Wheel) +
+ sizeof(LongestWheelieDist) +
+ sizeof(LongestStoppieDist) +
+ sizeof(Longest2WheelDist) +
+ sizeof(PropertyBudget) +
+ sizeof(AutoPaintingBudget) +
+ sizeof(PropertyDestroyed) +
+ sizeof(NumPropertyOwned) +
+ sizeof(BloodRingKills) +
+ sizeof(BloodRingTime) +
+ sizeof(PropertyOwned) +
+ sizeof(HighestChaseValue) +
sizeof(FastestTimes) +
sizeof(HighestScores) +
+ sizeof(BestPositions) +
sizeof(KillsSinceLastCheckpoint) +
sizeof(TotalLegitimateKills) +
- sizeof(LastMissionPassedName);
+ sizeof(LastMissionPassedName) +
+ sizeof(CheatedCount) +
+ sizeof(FavoriteRadioStationList);
#define CopyToBuf(buf, data) memcpy(buf, &data, sizeof(data)); buf += sizeof(data);
CopyToBuf(buf, PeopleKilledByPlayer);
CopyToBuf(buf, PeopleKilledByOthers);
CopyToBuf(buf, CarsExploded);
+ CopyToBuf(buf, BoatsExploded);
+ CopyToBuf(buf, TyresPopped);
CopyToBuf(buf, RoundsFiredByPlayer);
CopyToBuf(buf, PedsKilledOfThisType);
CopyToBuf(buf, HelisDestroyed);
CopyToBuf(buf, ProgressMade);
CopyToBuf(buf, TotalProgressInGame);
CopyToBuf(buf, KgsOfExplosivesUsed);
- CopyToBuf(buf, InstantHitsFiredByPlayer);
- CopyToBuf(buf, InstantHitsHitByPlayer);
- CopyToBuf(buf, CarsCrushed);
+ CopyToBuf(buf, BulletsThatHit);
CopyToBuf(buf, HeadsPopped);
+ CopyToBuf(buf, WantedStarsAttained);
+ CopyToBuf(buf, WantedStarsEvaded);
CopyToBuf(buf, TimesArrested);
CopyToBuf(buf, TimesDied);
CopyToBuf(buf, DaysPassed);
- CopyToBuf(buf, mmRain);
+ CopyToBuf(buf, SafeHouseVisits);
+ CopyToBuf(buf, Sprayings);
CopyToBuf(buf, MaximumJumpDistance);
CopyToBuf(buf, MaximumJumpHeight);
CopyToBuf(buf, MaximumJumpFlips);
@@ -324,33 +612,67 @@ void CStats::SaveStats(uint8 *buf, uint32 *size)
CopyToBuf(buf, NumberOfUniqueJumpsFound);
CopyToBuf(buf, TotalNumberOfUniqueJumps);
CopyToBuf(buf, MissionsGiven);
- CopyToBuf(buf, MissionsPassed);
CopyToBuf(buf, PassengersDroppedOffWithTaxi);
CopyToBuf(buf, MoneyMadeWithTaxi);
CopyToBuf(buf, IndustrialPassed);
CopyToBuf(buf, CommercialPassed);
CopyToBuf(buf, SuburbanPassed);
- CopyToBuf(buf, ElBurroTime);
+ CopyToBuf(buf, PamphletMissionPassed);
+ CopyToBuf(buf, NoMoreHurricanes);
CopyToBuf(buf, DistanceTravelledOnFoot);
- CopyToBuf(buf, DistanceTravelledInVehicle);
- CopyToBuf(buf, Record4x4One);
- CopyToBuf(buf, Record4x4Two);
- CopyToBuf(buf, Record4x4Three);
- CopyToBuf(buf, Record4x4Mayhem);
+ CopyToBuf(buf, DistanceTravelledByCar);
+ CopyToBuf(buf, DistanceTravelledByBike);
+ CopyToBuf(buf, DistanceTravelledByBoat);
+ CopyToBuf(buf, DistanceTravelledByGolfCart);
+ CopyToBuf(buf, DistanceTravelledByHelicoptor);
+ CopyToBuf(buf, DistanceTravelledByPlane);
CopyToBuf(buf, LivesSavedWithAmbulance);
CopyToBuf(buf, CriminalsCaught);
- CopyToBuf(buf, HighestLevelAmbulanceMission);
CopyToBuf(buf, FiresExtinguished);
- CopyToBuf(buf, LongestFlightInDodo);
- CopyToBuf(buf, TimeTakenDefuseMission);
+ CopyToBuf(buf, HighestLevelVigilanteMission);
+ CopyToBuf(buf, HighestLevelAmbulanceMission);
+ CopyToBuf(buf, HighestLevelFireMission);
+ CopyToBuf(buf, PhotosTaken);
CopyToBuf(buf, NumberKillFrenziesPassed);
CopyToBuf(buf, TotalNumberKillFrenzies);
CopyToBuf(buf, TotalNumberMissions);
+ CopyToBuf(buf, FlightTime);
+ CopyToBuf(buf, TimesDrowned);
+ CopyToBuf(buf, SeagullsKilled);
+ CopyToBuf(buf, WeaponBudget);
+ CopyToBuf(buf, FashionBudget);
+ CopyToBuf(buf, LoanSharks);
+ CopyToBuf(buf, StoresKnockedOff);
+ CopyToBuf(buf, MovieStunts);
+ CopyToBuf(buf, Assassinations);
+ CopyToBuf(buf, PizzasDelivered);
+ CopyToBuf(buf, GarbagePickups);
+ CopyToBuf(buf, IceCreamSold);
+ CopyToBuf(buf, TopShootingRangeScore);
+ CopyToBuf(buf, ShootingRank);
+ CopyToBuf(buf, LongestWheelie);
+ CopyToBuf(buf, LongestStoppie);
+ CopyToBuf(buf, Longest2Wheel);
+ CopyToBuf(buf, LongestWheelieDist);
+ CopyToBuf(buf, LongestStoppieDist);
+ CopyToBuf(buf, Longest2WheelDist);
+ CopyToBuf(buf, PropertyBudget);
+ CopyToBuf(buf, AutoPaintingBudget);
+ CopyToBuf(buf, PropertyDestroyed);
+ CopyToBuf(buf, NumPropertyOwned);
+ CopyToBuf(buf, BloodRingKills);
+ CopyToBuf(buf, BloodRingTime);
+ CopyToBuf(buf, PropertyOwned);
+ CopyToBuf(buf, HighestChaseValue);
CopyToBuf(buf, FastestTimes);
CopyToBuf(buf, HighestScores);
+ CopyToBuf(buf, BestPositions);
CopyToBuf(buf, KillsSinceLastCheckpoint);
CopyToBuf(buf, TotalLegitimateKills);
CopyToBuf(buf, LastMissionPassedName);
+ CopyToBuf(buf, CheatedCount);
+ PopulateFavoriteRadioStationList();
+ CopyToBuf(buf, FavoriteRadioStationList);
assert(buf - buf_start == *size);
#undef CopyToBuf
@@ -365,20 +687,23 @@ void CStats::LoadStats(uint8 *buf, uint32 size)
CopyFromBuf(buf, PeopleKilledByPlayer);
CopyFromBuf(buf, PeopleKilledByOthers);
CopyFromBuf(buf, CarsExploded);
+ CopyFromBuf(buf, BoatsExploded);
+ CopyFromBuf(buf, TyresPopped);
CopyFromBuf(buf, RoundsFiredByPlayer);
CopyFromBuf(buf, PedsKilledOfThisType);
CopyFromBuf(buf, HelisDestroyed);
CopyFromBuf(buf, ProgressMade);
CopyFromBuf(buf, TotalProgressInGame);
CopyFromBuf(buf, KgsOfExplosivesUsed);
- CopyFromBuf(buf, InstantHitsFiredByPlayer);
- CopyFromBuf(buf, InstantHitsHitByPlayer);
- CopyFromBuf(buf, CarsCrushed);
+ CopyFromBuf(buf, BulletsThatHit);
CopyFromBuf(buf, HeadsPopped);
+ CopyFromBuf(buf, WantedStarsAttained);
+ CopyFromBuf(buf, WantedStarsEvaded);
CopyFromBuf(buf, TimesArrested);
CopyFromBuf(buf, TimesDied);
CopyFromBuf(buf, DaysPassed);
- CopyFromBuf(buf, mmRain);
+ CopyFromBuf(buf, SafeHouseVisits);
+ CopyFromBuf(buf, Sprayings);
CopyFromBuf(buf, MaximumJumpDistance);
CopyFromBuf(buf, MaximumJumpHeight);
CopyFromBuf(buf, MaximumJumpFlips);
@@ -387,34 +712,732 @@ void CStats::LoadStats(uint8 *buf, uint32 size)
CopyFromBuf(buf, NumberOfUniqueJumpsFound);
CopyFromBuf(buf, TotalNumberOfUniqueJumps);
CopyFromBuf(buf, MissionsGiven);
- CopyFromBuf(buf, MissionsPassed);
CopyFromBuf(buf, PassengersDroppedOffWithTaxi);
CopyFromBuf(buf, MoneyMadeWithTaxi);
CopyFromBuf(buf, IndustrialPassed);
CopyFromBuf(buf, CommercialPassed);
CopyFromBuf(buf, SuburbanPassed);
- CopyFromBuf(buf, ElBurroTime);
+ CopyFromBuf(buf, PamphletMissionPassed);
+ CopyFromBuf(buf, NoMoreHurricanes);
CopyFromBuf(buf, DistanceTravelledOnFoot);
- CopyFromBuf(buf, DistanceTravelledInVehicle);
- CopyFromBuf(buf, Record4x4One);
- CopyFromBuf(buf, Record4x4Two);
- CopyFromBuf(buf, Record4x4Three);
- CopyFromBuf(buf, Record4x4Mayhem);
+ CopyFromBuf(buf, DistanceTravelledByCar);
+ CopyFromBuf(buf, DistanceTravelledByBike);
+ CopyFromBuf(buf, DistanceTravelledByBoat);
+ CopyFromBuf(buf, DistanceTravelledByGolfCart);
+ CopyFromBuf(buf, DistanceTravelledByHelicoptor);
+ CopyFromBuf(buf, DistanceTravelledByPlane);
CopyFromBuf(buf, LivesSavedWithAmbulance);
CopyFromBuf(buf, CriminalsCaught);
- CopyFromBuf(buf, HighestLevelAmbulanceMission);
CopyFromBuf(buf, FiresExtinguished);
- CopyFromBuf(buf, LongestFlightInDodo);
- CopyFromBuf(buf, TimeTakenDefuseMission);
+ CopyFromBuf(buf, HighestLevelVigilanteMission);
+ CopyFromBuf(buf, HighestLevelAmbulanceMission);
+ CopyFromBuf(buf, HighestLevelFireMission);
+ CopyFromBuf(buf, PhotosTaken);
CopyFromBuf(buf, NumberKillFrenziesPassed);
CopyFromBuf(buf, TotalNumberKillFrenzies);
CopyFromBuf(buf, TotalNumberMissions);
+ CopyFromBuf(buf, FlightTime);
+ CopyFromBuf(buf, TimesDrowned);
+ CopyFromBuf(buf, SeagullsKilled);
+ CopyFromBuf(buf, WeaponBudget);
+ CopyFromBuf(buf, FashionBudget);
+ CopyFromBuf(buf, LoanSharks);
+ CopyFromBuf(buf, StoresKnockedOff);
+ CopyFromBuf(buf, MovieStunts);
+ CopyFromBuf(buf, Assassinations);
+ CopyFromBuf(buf, PizzasDelivered);
+ CopyFromBuf(buf, GarbagePickups);
+ CopyFromBuf(buf, IceCreamSold);
+ CopyFromBuf(buf, TopShootingRangeScore);
+ CopyFromBuf(buf, ShootingRank);
+ CopyFromBuf(buf, LongestWheelie);
+ CopyFromBuf(buf, LongestStoppie);
+ CopyFromBuf(buf, Longest2Wheel);
+ CopyFromBuf(buf, LongestWheelieDist);
+ CopyFromBuf(buf, LongestStoppieDist);
+ CopyFromBuf(buf, Longest2WheelDist);
+ CopyFromBuf(buf, PropertyBudget);
+ CopyFromBuf(buf, AutoPaintingBudget);
+ CopyFromBuf(buf, PropertyDestroyed);
+ CopyFromBuf(buf, NumPropertyOwned);
+ CopyFromBuf(buf, BloodRingKills);
+ CopyFromBuf(buf, BloodRingTime);
+ CopyFromBuf(buf, PropertyOwned);
+ CopyFromBuf(buf, HighestChaseValue);
CopyFromBuf(buf, FastestTimes);
CopyFromBuf(buf, HighestScores);
+ CopyFromBuf(buf, BestPositions);
CopyFromBuf(buf, KillsSinceLastCheckpoint);
CopyFromBuf(buf, TotalLegitimateKills);
CopyFromBuf(buf, LastMissionPassedName);
+ CopyFromBuf(buf, CheatedCount);
+ CopyFromBuf(buf, FavoriteRadioStationList);
assert(buf - buf_start == size);
#undef CopyFromBuf
}
+
+void
+CStats::PopulateFavoriteRadioStationList()
+{
+ float* pListenTimeArray = DMAudio.GetListenTimeArray();
+ for (int i = 0; i < NUM_RADIOS; i++)
+ FavoriteRadioStationList[i] = pListenTimeArray[i];
+}
+
+void
+CStats::BuildStatLine(Const char *text, void *stat, int displayType, void *stat2, int isTime)
+{
+#define STAT_D *(int*)stat
+#define STAT_F *(float*)stat
+#define STAT2_D *(int*)stat2
+#define STAT2_F *(float*)stat2
+ if (!text)
+ return;
+
+ gString2[0] = '\0';
+ if (isTime == 1) {
+ if (*((int*)stat2) >= 10)
+ sprintf(gString2, " %d:%d", STAT_D, STAT2_D);
+ else
+ sprintf(gString2, " %d:0%d", STAT_D, STAT2_D);
+
+ } else if (stat2) {
+#ifdef MORE_LANGUAGES
+ if (CFont::IsJapanese()) {
+ switch (displayType) {
+ case 0:
+ case 4:
+ sprintf(gString2, " %d/%d", STAT_D, STAT2_D);
+ break;
+ case 1:
+ sprintf(gString2, " %.2f/%.2f", STAT_F, STAT2_F);
+ break;
+ case 2:
+ sprintf(gString2, " %d%%/%d%%", STAT_D, STAT2_D);
+ break;
+ case 3:
+ sprintf(gString2, " $%.2f/$%.2f", STAT_F, STAT2_F);
+ break;
+ default:
+ break;
+ }
+ } else
+#endif
+ {
+ switch (displayType) {
+ case 0:
+ sprintf(gString2, " %d %s %d", STAT_D, UnicodeToAscii(TheText.Get("FEST_OO")), STAT2_D);
+ break;
+ case 1:
+ sprintf(gString2, " %.2f %s %.2f", STAT_F, UnicodeToAscii(TheText.Get("FEST_OO")), STAT2_F);
+ break;
+ case 2:
+ sprintf(gString2, " %d%% %s %d%%", STAT_D, UnicodeToAscii(TheText.Get("FEST_OO")), STAT2_D);
+ break;
+ case 3:
+ sprintf(gString2, " $%.2f %s $%.2f", STAT_F, UnicodeToAscii(TheText.Get("FEST_OO")), STAT2_F);
+ break;
+ case 4:
+ sprintf(gString2, " %d_ %s %d_", STAT_D, UnicodeToAscii(TheText.Get("FEST_OO")), STAT2_D);
+ break;
+ default:
+ break;
+ }
+ }
+ } else if (stat) {
+ switch (displayType) {
+ case 0:
+ sprintf(gString2, "%d", STAT_D);
+ break;
+ case 1:
+ sprintf(gString2, "%.2f", STAT_F);
+ break;
+ case 2:
+ sprintf(gString2, "%d%%", STAT_D);
+ break;
+ case 3:
+ sprintf(gString2, "$%.2f", STAT_F);
+ break;
+ case 4:
+#ifdef MORE_LANGUAGES
+ if (CFont::IsJapanese())
+ sprintf(gString2, "%d", STAT_D);
+ else
+#endif
+ sprintf(gString2, "%d_", STAT_D);
+ break;
+ default:
+ break;
+ }
+ }
+ UnicodeStrcpy(gUString, TheText.Get(text));
+ CFont::FilterOutTokensFromString(gUString);
+ AsciiToUnicode(gString2, gUString2);
+#undef STAT_D
+#undef STAT_F
+#undef STAT2_D
+#undef STAT2_F
+}
+
+// rowIdx 99999 returns total numbers of rows. otherwise it returns 0.
+int
+CStats::ConstructStatLine(int rowIdx)
+{
+
+#define STAT_LINE_1(varType, left, right1, type) \
+ do { \
+ if(counter == rowIdx){ \
+ varType a = right1; \
+ BuildStatLine(left, &a, type, nil, 0); \
+ return 0; \
+ } counter++; \
+ } while(0)
+
+#define STAT_LINE_2(varType, left, right1, type, right2, time) \
+ do { \
+ if(counter == rowIdx){ \
+ varType a = right1; \
+ varType b = right2; \
+ BuildStatLine(left, &a, type, &b, time); \
+ return 0; \
+ } counter++; \
+ } while(0)
+
+#define TEXT_ON_LEFT_GXT(name) \
+ do { \
+ if(counter == rowIdx){ \
+ BuildStatLine(name, nil, 0, nil, 0); \
+ return 0; \
+ } counter++; \
+ } while(0)
+
+#define TEXT_ON_RIGHT(text) \
+ do { \
+ if(counter == rowIdx){ \
+ gUString[0] = '\0'; \
+ UnicodeStrcpy(gUString2, text); \
+ return 0; \
+ } counter++; \
+ } while(0)
+
+#define FASTEST_TIME(id, str) \
+ do { \
+ if(FastestTimes[id]) { \
+ if(counter == rowIdx){ \
+ int hour = 0, minute; \
+ for (int i = FastestTimes[id]; i > 59; i -= 60) hour++; \
+ for (minute = FastestTimes[id]; minute > 59; minute -= 60); \
+ if (minute < 0) minute = -minute; \
+ BuildStatLine(str, &hour, 0, &minute, 1); \
+ return 0; \
+ } \
+ counter++; \
+ } \
+ } while(0)
+
+ switch (rowIdx) {
+ case 0: {
+ int percentCompleted = GetPercentageProgress();
+ BuildStatLine("PER_COM", &percentCompleted, 2, nil, 0);
+ return 0;
+ }
+ case 1: {
+ BuildStatLine("NMISON", &MissionsGiven, 0, nil, 0);
+ return 0;
+ }
+ case 2: {
+ int hour = (CTimer::GetTimeInMilliseconds() / 60000) / 60;
+ int minute = (CTimer::GetTimeInMilliseconds() / 60000) % 60;
+ BuildStatLine("ST_TIME", &hour, 0, &minute, 1);
+ return 0;
+ }
+ case 3: {
+ BuildStatLine("DAYSPS", &DaysPassed, 0, nil, 0);
+ return 0;
+ }
+ case 4: {
+ BuildStatLine("NUMSHV", &SafeHouseVisits, 0, nil, 0);
+ return 0;
+ }
+ }
+ int counter = 5;
+
+ if (CGame::nastyGame) {
+ STAT_LINE_2(int, "FEST_RP", NumberKillFrenziesPassed, 0, TotalNumberKillFrenzies, 0);
+ }
+
+ CPlayerInfo &player = CWorld::Players[CWorld::PlayerInFocus];
+
+ // Hidden packages shouldn't be shown with percent
+#ifdef FIX_BUGS
+ STAT_LINE_2(int, "PERPIC", player.m_nCollectedPackages, 0, player.m_nTotalPackages, 0);
+#else
+ float fPackagesPercent = 0.0f;
+ if (player.m_nTotalPackages != 0)
+ fPackagesPercent = player.m_nCollectedPackages * 100.0f / player.m_nTotalPackages;
+
+ STAT_LINE_2(int, "PERPIC", fPackagesPercent, 0, 100, 0);
+#endif
+
+ if (CGame::nastyGame) {
+ STAT_LINE_1(int, "PE_WAST", PeopleKilledByPlayer, 0);
+ STAT_LINE_1(int, "PE_WSOT", PeopleKilledByOthers, 0);
+ }
+ STAT_LINE_1(int, "CAR_EXP", CarsExploded, 0);
+ STAT_LINE_1(int, "BOA_EXP", BoatsExploded, 0);
+ STAT_LINE_1(int, "HEL_DST", HelisDestroyed, 0);
+ STAT_LINE_1(int, "TYREPOP", TyresPopped, 0);
+ STAT_LINE_1(int, "ST_STAR", WantedStarsAttained, 0);
+ STAT_LINE_1(int, "ST_STGN", WantedStarsEvaded, 0);
+ STAT_LINE_1(int, "TM_BUST", TimesArrested, 0);
+ STAT_LINE_1(int, "TM_DED", TimesDied, 0);
+
+#ifdef MORE_LANGUAGES
+ // JP version removed it altogether actually
+ if (!CFont::IsJapanese())
+#endif
+ STAT_LINE_1(int, "ST_HEAD", HeadsPopped, 0);
+
+ static uint32 lastProcessedDay = UINT32_MAX;
+ static uint32 lastPoliceSpending = 0;
+
+ // What a random stat...
+ if (lastProcessedDay != DaysPassed) {
+ lastProcessedDay = DaysPassed;
+ lastPoliceSpending = (CTimer::GetTimeInMilliseconds() & 255 + 80) * 255.44f;
+ }
+ STAT_LINE_1(float, "DAYPLC", lastPoliceSpending, 3);
+
+ int mostPatheticGang = 0;
+ int mostKill = 0;
+ for (int i = PEDTYPE_GANG1; i < PEDTYPE_GANG9; ++i) {
+ if (CStats::PedsKilledOfThisType[i] > mostKill) {
+ mostKill = CStats::PedsKilledOfThisType[i];
+ mostPatheticGang = i;
+ }
+ }
+ if (mostPatheticGang > 0) {
+ TEXT_ON_LEFT_GXT("ST_GANG");
+
+ switch (mostPatheticGang) {
+ case PEDTYPE_GANG1:
+ TEXT_ON_RIGHT(TheText.Get("ST_GNG1"));
+ break;
+ case PEDTYPE_GANG2:
+ TEXT_ON_RIGHT(TheText.Get("ST_GNG2"));
+ break;
+ case PEDTYPE_GANG3:
+ TEXT_ON_RIGHT(TheText.Get("ST_GNG3"));
+ break;
+ case PEDTYPE_GANG4:
+ TEXT_ON_RIGHT(TheText.Get("ST_GNG4"));
+ break;
+ case PEDTYPE_GANG5:
+ TEXT_ON_RIGHT(TheText.Get("ST_GNG5"));
+ break;
+ case PEDTYPE_GANG6:
+ TEXT_ON_RIGHT(TheText.Get("ST_GNG6"));
+ break;
+ case PEDTYPE_GANG7:
+ TEXT_ON_RIGHT(TheText.Get("ST_GNG7"));
+ break;
+ case PEDTYPE_GANG8:
+ TEXT_ON_RIGHT(TheText.Get("ST_GNG8"));
+ break;
+ default:
+ break;
+ }
+ }
+
+ STAT_LINE_1(int, "GNG_WST", PedsKilledOfThisType[PEDTYPE_GANG9] + PedsKilledOfThisType[PEDTYPE_GANG8]
+ + PedsKilledOfThisType[PEDTYPE_GANG7] + PedsKilledOfThisType[PEDTYPE_GANG6]
+ + PedsKilledOfThisType[PEDTYPE_GANG5] + PedsKilledOfThisType[PEDTYPE_GANG4]
+ + PedsKilledOfThisType[PEDTYPE_GANG3] + PedsKilledOfThisType[PEDTYPE_GANG2]
+ + PedsKilledOfThisType[PEDTYPE_GANG1], 0);
+
+ STAT_LINE_1(int, "DED_CRI", PedsKilledOfThisType[PEDTYPE_CRIMINAL], 0);
+ STAT_LINE_1(int, "KGS_EXP", KgsOfExplosivesUsed, 0);
+ STAT_LINE_1(int, "BUL_FIR", RoundsFiredByPlayer, 0);
+ STAT_LINE_1(int, "BUL_HIT", BulletsThatHit, 0);
+;
+ STAT_LINE_1(int, "ACCURA", RoundsFiredByPlayer == 0 ? 0 : (BulletsThatHit * 100.0f / (float)RoundsFiredByPlayer), 2);
+
+ switch (FrontEndMenuManager.m_PrefsLanguage) {
+ case CMenuManager::LANGUAGE_AMERICAN:
+#ifndef USE_MEASUREMENTS_IN_METERS
+ STAT_LINE_1(float, "FEST_DF", DistanceTravelledOnFoot * MILES_IN_METER, 1);
+ STAT_LINE_1(float, "FEST_DC", DistanceTravelledByCar * MILES_IN_METER, 1);
+ STAT_LINE_1(float, "DISTBIK", DistanceTravelledByBike * MILES_IN_METER, 1);
+ STAT_LINE_1(float, "DISTBOA", DistanceTravelledByBoat * MILES_IN_METER, 1);
+ STAT_LINE_1(float, "DISTGOL", DistanceTravelledByGolfCart * MILES_IN_METER, 1);
+ STAT_LINE_1(float, "DISTHEL", DistanceTravelledByHelicoptor * MILES_IN_METER, 1);
+#ifdef FIX_BUGS
+ STAT_LINE_1(float, "TOT_DIS", (DistanceTravelledOnFoot + DistanceTravelledByCar + DistanceTravelledByBoat + DistanceTravelledByBike
+ + DistanceTravelledByGolfCart + DistanceTravelledByHelicoptor + DistanceTravelledByPlane) * MILES_IN_METER, 1);
+ STAT_LINE_1(float, "MXCARD", MaximumJumpDistance * FEET_IN_METER, 1);
+ STAT_LINE_1(float, "MXCARJ", MaximumJumpHeight * FEET_IN_METER, 1);
+#else
+ STAT_LINE_1(float, "TOT_DIS", (DistanceTravelledOnFoot + DistanceTravelledByCar + DistanceTravelledByBoat + DistanceTravelledByBike
+ + DistanceTravelledByGolfCart + DistanceTravelledByHelicoptor) * MILES_IN_METER, 1);
+#endif
+ break;
+#endif
+ case CMenuManager::LANGUAGE_FRENCH:
+ case CMenuManager::LANGUAGE_GERMAN:
+ case CMenuManager::LANGUAGE_ITALIAN:
+ case CMenuManager::LANGUAGE_SPANISH:
+#ifdef MORE_LANGUAGES
+ case CMenuManager::LANGUAGE_POLISH:
+ case CMenuManager::LANGUAGE_RUSSIAN:
+ case CMenuManager::LANGUAGE_JAPANESE:
+#endif
+ STAT_LINE_1(float, "FESTDFM", DistanceTravelledOnFoot, 1);
+ STAT_LINE_1(float, "FESTDCM", DistanceTravelledByCar, 1);
+ STAT_LINE_1(float, "DISTBIM", DistanceTravelledByBike, 1);
+ STAT_LINE_1(float, "DISTBOM", DistanceTravelledByBoat, 1);
+ STAT_LINE_1(float, "DISTGOM", DistanceTravelledByGolfCart, 1);
+ STAT_LINE_1(float, "DISTHEM", DistanceTravelledByHelicoptor, 1);
+#ifdef FIX_BUGS
+ STAT_LINE_1(float, "TOTDISM", DistanceTravelledOnFoot + DistanceTravelledByCar + DistanceTravelledByBoat
+ + DistanceTravelledByBike + DistanceTravelledByGolfCart + DistanceTravelledByHelicoptor + DistanceTravelledByPlane, 1);
+ STAT_LINE_1(float, "MXCARDM", MaximumJumpDistance, 1);
+ STAT_LINE_1(float, "MXCARJM", MaximumJumpHeight, 1);
+#else
+ STAT_LINE_1(float, "TOTDISM", DistanceTravelledOnFoot + DistanceTravelledByCar + DistanceTravelledByBoat
+ + DistanceTravelledByGolfCart + DistanceTravelledByHelicoptor, 1);
+#endif
+ break;
+ default:
+ break;
+ }
+
+ // They were selecting the unit according to language in III, but they deleted the feet code in VC. Weird
+#ifndef FIX_BUGS
+ STAT_LINE_1(float, "MXCARDM", MaximumJumpDistance, 1);
+ STAT_LINE_1(float, "MXCARJM", MaximumJumpHeight, 1);
+#endif
+ STAT_LINE_1(int, "MXFLIP", MaximumJumpFlips, 0);
+ STAT_LINE_2(int, "NOUNIF", NumberOfUniqueJumpsFound, 0, TotalNumberOfUniqueJumps, 0);
+ STAT_LINE_1(int, "MXJUMP", MaximumJumpSpins, 4);
+
+ TEXT_ON_LEFT_GXT("BSTSTU");
+ switch (BestStuntJump) {
+ case 1:
+ TEXT_ON_RIGHT(TheText.Get("INSTUN"));
+ break;
+ case 2:
+ TEXT_ON_RIGHT(TheText.Get("PRINST"));
+ break;
+ case 3:
+ TEXT_ON_RIGHT(TheText.Get("DBINST"));
+ break;
+ case 4:
+ TEXT_ON_RIGHT(TheText.Get("DBPINS"));
+ break;
+ case 5:
+ TEXT_ON_RIGHT(TheText.Get("TRINST"));
+ break;
+ case 6:
+ TEXT_ON_RIGHT(TheText.Get("PRTRST"));
+ break;
+ case 7:
+ TEXT_ON_RIGHT(TheText.Get("QUINST"));
+ break;
+ case 8:
+ TEXT_ON_RIGHT(TheText.Get("PQUINS"));
+ break;
+ default:
+ TEXT_ON_RIGHT(TheText.Get("NOSTUC"));
+ break;
+ }
+ STAT_LINE_1(int, "ST_WHEE", LongestWheelie, 0);
+ STAT_LINE_1(float, "ST_WHED", LongestWheelieDist, 1);
+ STAT_LINE_1(int, "ST_STOP", LongestStoppie, 0);
+ STAT_LINE_1(float, "ST_STOD", LongestStoppieDist, 1);
+ STAT_LINE_1(int, "ST_2WHE", Longest2Wheel, 0);
+ STAT_LINE_1(float, "ST_2WHD", Longest2WheelDist, 1);
+
+ if (LoanSharks > 0.0f)
+ STAT_LINE_1(int, "ST_LOAN", LoanSharks, 0);
+
+ STAT_LINE_1(int, "FEST_CC", CriminalsCaught, 0);
+ STAT_LINE_1(int, "FEST_HV", HighestLevelVigilanteMission, 0);
+ STAT_LINE_1(int, "PASDRO", PassengersDroppedOffWithTaxi, 0);
+ STAT_LINE_1(float, "MONTAX", MoneyMadeWithTaxi, 3);
+ STAT_LINE_1(int, "FEST_LS", LivesSavedWithAmbulance, 0);
+ STAT_LINE_1(int, "FEST_HA", HighestLevelAmbulanceMission, 0);
+ STAT_LINE_1(int, "FEST_FE", FiresExtinguished, 0);
+ STAT_LINE_1(int, "FIRELVL", HighestLevelFireMission, 0);
+
+ STAT_LINE_2(int, "ST_STOR", StoresKnockedOff, 0, 15, 0);
+
+ if (MovieStunts > 0.0f)
+ STAT_LINE_1(int, "ST_MOVI", MovieStunts, 0);
+
+ STAT_LINE_2(int, "ST_ASSI", Assassinations, 0, 5, 0);
+
+ if (PhotosTaken > 0)
+ STAT_LINE_1(int, "ST_PHOT", PhotosTaken, 0);
+
+ if (PizzasDelivered > 0.0f)
+ STAT_LINE_1(int, "ST_PIZZ", PizzasDelivered, 0);
+
+ if (GarbagePickups > 0.0f)
+ STAT_LINE_1(int, "ST_GARB", GarbagePickups, 0);
+
+ if (IceCreamSold > 0.0f)
+ STAT_LINE_1(int, "ST_ICEC", IceCreamSold, 0);
+
+ if (HighestScores[1])
+ STAT_LINE_1(int, "STHC_02", HighestScores[1], 0);
+
+ FASTEST_TIME(0, "STFT_01");
+ FASTEST_TIME(1, "STFT_02");
+ FASTEST_TIME(2, "STFT_03");
+ FASTEST_TIME(3, "STFT_04");
+ FASTEST_TIME(4, "STFT_05");
+ FASTEST_TIME(5, "STFT_06");
+ FASTEST_TIME(6, "STFT_07");
+ FASTEST_TIME(7, "STFT_08");
+ FASTEST_TIME(8, "STFT_09");
+ FASTEST_TIME(9, "STFT_10");
+ FASTEST_TIME(10, "STFT_11");
+ FASTEST_TIME(11, "STFT_12");
+ FASTEST_TIME(12, "STFT_13");
+ FASTEST_TIME(13, "STFT_14");
+ FASTEST_TIME(14, "STFT_15");
+ FASTEST_TIME(15, "STFT_16");
+ FASTEST_TIME(16, "STFT_17");
+ FASTEST_TIME(17, "STFT_18");
+ FASTEST_TIME(18, "STFT_19");
+ FASTEST_TIME(19, "STFT_20");
+ FASTEST_TIME(22, "STFT_23");
+
+ if (HighestScores[0])
+ STAT_LINE_1(int, "STHC_01", HighestScores[0], 0);
+
+ if (HighestScores[3])
+ STAT_LINE_1(int, "STHC_04", HighestScores[3], 0);
+
+ if (HighestScores[2])
+ STAT_LINE_1(int, "STHC_03", HighestScores[2], 0);
+
+ if (BestPositions[0] != INT_MAX)
+ STAT_LINE_1(int, "STHC_05", BestPositions[0], 0);
+
+ FASTEST_TIME(20, "STFT_21");
+
+ if (FastestTimes[21])
+#ifdef FIX_BUGS
+ STAT_LINE_1(float, "STFT_22", Floor(FastestTimes[21] / 10) / 100, 1);
+#else
+ STAT_LINE_1(float, "STFT_22", FastestTimes[21] / 1000, 1);
+#endif
+
+ if (TopShootingRangeScore > 0.0f)
+ STAT_LINE_1(int, "TOP_SHO", TopShootingRangeScore, 0);
+
+ if (ShootingRank > 0.0f)
+ STAT_LINE_1(int, "SHO_RAN", ShootingRank, 0);
+
+ int flightMinute = (FlightTime / 60000) % 60;
+ int flightHour = (FlightTime / 60000) / 60;
+ STAT_LINE_2(int, "ST_FTIM", flightHour, 0, flightMinute, 1);
+
+ // We always have pilot rank if we flew more then 5 minutes
+#ifndef FIX_BUGS
+ if (flightHour != 0)
+ TEXT_ON_LEFT_GXT("ST_PRAN");
+#endif
+
+#ifdef FIX_BUGS
+#define FL_TIME_MORE_THAN(hour, minute) (flightHour > hour || (flightHour == hour && flightMinute >= minute))
+#else
+#define FL_TIME_MORE_THAN(hour, minute) (flightHour > hour || flightMinute >= minute)
+#endif
+
+ if (FL_TIME_MORE_THAN(0,5)) {
+
+#ifdef FIX_BUGS
+ TEXT_ON_LEFT_GXT("ST_PRAN");
+#endif
+ if (!FL_TIME_MORE_THAN(0,10)) TEXT_ON_RIGHT(TheText.Get("ST_PR01"));
+ else if (!FL_TIME_MORE_THAN(0,20)) TEXT_ON_RIGHT(TheText.Get("ST_PR02"));
+ else if (!FL_TIME_MORE_THAN(0,30)) TEXT_ON_RIGHT(TheText.Get("ST_PR03"));
+ else if (!FL_TIME_MORE_THAN(1,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR04"));
+ else if (!FL_TIME_MORE_THAN(1,30)) TEXT_ON_RIGHT(TheText.Get("ST_PR05"));
+ else if (!FL_TIME_MORE_THAN(2,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR06"));
+ else if (!FL_TIME_MORE_THAN(2,30)) TEXT_ON_RIGHT(TheText.Get("ST_PR07"));
+ else if (!FL_TIME_MORE_THAN(3,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR08"));
+ else if (!FL_TIME_MORE_THAN(3,30)) TEXT_ON_RIGHT(TheText.Get("ST_PR09"));
+ else if (!FL_TIME_MORE_THAN(4,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR10"));
+ else if (!FL_TIME_MORE_THAN(5,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR11"));
+ else if (!FL_TIME_MORE_THAN(10,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR12"));
+ else if (!FL_TIME_MORE_THAN(20,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR13"));
+ else if (!FL_TIME_MORE_THAN(25,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR14"));
+ else if (!FL_TIME_MORE_THAN(30,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR15"));
+ else if (!FL_TIME_MORE_THAN(49,2)) TEXT_ON_RIGHT(TheText.Get("ST_PR16"));
+ else if (!FL_TIME_MORE_THAN(50,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR17"));
+ else if (!FL_TIME_MORE_THAN(100,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR18"));
+ else TEXT_ON_RIGHT(TheText.Get("ST_PR19"));
+ }
+#undef FL_TIME_MORE_THAN
+
+ if (BloodRingKills > 0)
+ STAT_LINE_1(int, "ST_BRK", BloodRingKills, 0);
+
+ if (BloodRingTime > 0)
+ STAT_LINE_1(int, "ST_LTBR", BloodRingTime, 0);
+
+ STAT_LINE_1(int, "ST_DRWN", TimesDrowned, 0);
+
+ if (SeagullsKilled > 0)
+ STAT_LINE_1(int, "SEAGULL", SeagullsKilled, 0);
+
+ bool playerHatesRadio = true;
+ float* pListenTimeArray = DMAudio.GetListenTimeArray();
+ for (int i = 0; i < NUM_RADIOS; i++) {
+ FavoriteRadioStationList[i] = pListenTimeArray[i];
+ if (FavoriteRadioStationList[i] != 0.0) // double
+ playerHatesRadio = false;
+ }
+
+ if (!playerHatesRadio) {
+ // Most listened
+ TEXT_ON_LEFT_GXT("FST_MFR");
+ float mostListenTime = FavoriteRadioStationList[0];
+ int mostListenedRadio = 0;
+ for (int i = 0; i < NUM_RADIOS; i++) {
+ if (FavoriteRadioStationList[i] > mostListenTime) {
+ mostListenTime = FavoriteRadioStationList[i];
+ mostListenedRadio = i;
+ }
+ }
+ switch (mostListenedRadio) {
+ case WILDSTYLE:
+ TEXT_ON_RIGHT(TheText.Get("FEA_FM0"));
+ break;
+ case FLASH_FM:
+ TEXT_ON_RIGHT(TheText.Get("FEA_FM1"));
+ break;
+ case KCHAT:
+ TEXT_ON_RIGHT(TheText.Get("FEA_FM2"));
+ break;
+ case FEVER:
+ TEXT_ON_RIGHT(TheText.Get("FEA_FM3"));
+ break;
+ case V_ROCK:
+ TEXT_ON_RIGHT(TheText.Get("FEA_FM4"));
+ break;
+ case VCPR:
+ TEXT_ON_RIGHT(TheText.Get("FEA_FM5"));
+ break;
+ case RADIO_ESPANTOSO:
+ TEXT_ON_RIGHT(TheText.Get("FEA_FM6"));
+ break;
+ case EMOTION:
+ TEXT_ON_RIGHT(TheText.Get("FEA_FM7"));
+ break;
+ case WAVE:
+ TEXT_ON_RIGHT(TheText.Get("FEA_FM8"));
+ break;
+ case USERTRACK:
+ TEXT_ON_RIGHT(TheText.Get("FEA_MP3"));
+ break;
+ default:
+ TEXT_ON_RIGHT(TheText.Get("FEA_FM8")); // heh
+ break;
+ }
+
+ // Least listened
+ TEXT_ON_LEFT_GXT("FST_LFR");
+ float leastListenTime = FavoriteRadioStationList[0];
+ int leastListenedRadio = 0;
+ for (int i = 0; i < NUM_RADIOS; i++) {
+#ifdef FIX_BUGS
+ if (!DMAudio.IsMP3RadioChannelAvailable() && i == USERTRACK)
+ continue;
+#endif
+ if (FavoriteRadioStationList[i] < leastListenTime) {
+ leastListenTime = FavoriteRadioStationList[i];
+ leastListenedRadio = i;
+ }
+ }
+#ifndef FIX_BUGS
+ if (!DMAudio.IsMP3RadioChannelAvailable() && leastListenedRadio == USERTRACK)
+ leastListenedRadio = WAVE;
+#endif
+
+ switch (leastListenedRadio) {
+ case WILDSTYLE:
+ TEXT_ON_RIGHT(TheText.Get("FEA_FM0"));
+ break;
+ case FLASH_FM:
+ TEXT_ON_RIGHT(TheText.Get("FEA_FM1"));
+ break;
+ case KCHAT:
+ TEXT_ON_RIGHT(TheText.Get("FEA_FM2"));
+ break;
+ case FEVER:
+ TEXT_ON_RIGHT(TheText.Get("FEA_FM3"));
+ break;
+ case V_ROCK:
+ TEXT_ON_RIGHT(TheText.Get("FEA_FM4"));
+ break;
+ case VCPR:
+ TEXT_ON_RIGHT(TheText.Get("FEA_FM5"));
+ break;
+ case RADIO_ESPANTOSO:
+ TEXT_ON_RIGHT(TheText.Get("FEA_FM6"));
+ break;
+ case EMOTION:
+ TEXT_ON_RIGHT(TheText.Get("FEA_FM7"));
+ break;
+ case WAVE:
+ TEXT_ON_RIGHT(TheText.Get("FEA_FM8"));
+ break;
+ case USERTRACK:
+ TEXT_ON_RIGHT(TheText.Get("FEA_MP3"));
+ break;
+ default:
+ TEXT_ON_RIGHT(TheText.Get("FEA_FM8")); // heh
+ break;
+ }
+ }
+ STAT_LINE_1(int, "SPRAYIN", Sprayings, 0);
+ STAT_LINE_1(float, "ST_WEAP", WeaponBudget, 3);
+ STAT_LINE_1(float, "ST_FASH", FashionBudget, 3);
+ STAT_LINE_1(float, "ST_PROP", PropertyBudget, 3);
+ STAT_LINE_1(float, "ST_AUTO", AutoPaintingBudget, 3);
+ STAT_LINE_1(float, "ST_DAMA", PropertyBudget, 3);
+
+ if (NumPropertyOwned > 0) {
+ STAT_LINE_1(int, "PROPOWN", NumPropertyOwned, 0);
+ if (PropertyOwned[0]) TEXT_ON_RIGHT(TheText.Get("STPR_1"));
+ if (PropertyOwned[1]) TEXT_ON_RIGHT(TheText.Get("STPR_2"));
+ if (PropertyOwned[2]) TEXT_ON_RIGHT(TheText.Get("STPR_3"));
+ if (PropertyOwned[3]) TEXT_ON_RIGHT(TheText.Get("STPR_4"));
+ if (PropertyOwned[4]) TEXT_ON_RIGHT(TheText.Get("STPR_5"));
+ if (PropertyOwned[5]) TEXT_ON_RIGHT(TheText.Get("STPR_6"));
+ if (PropertyOwned[6]) TEXT_ON_RIGHT(TheText.Get("STPR_7"));
+ if (PropertyOwned[7]) TEXT_ON_RIGHT(TheText.Get("STPR_8"));
+ if (PropertyOwned[8]) TEXT_ON_RIGHT(TheText.Get("STPR_9"));
+ if (PropertyOwned[9]) TEXT_ON_RIGHT(TheText.Get("STPR_10"));
+ if (PropertyOwned[10]) TEXT_ON_RIGHT(TheText.Get("STPR_11"));
+ if (PropertyOwned[11]) TEXT_ON_RIGHT(TheText.Get("STPR_12"));
+ if (PropertyOwned[12]) TEXT_ON_RIGHT(TheText.Get("STPR_13"));
+ if (PropertyOwned[13]) TEXT_ON_RIGHT(TheText.Get("STPR_14"));
+ if (PropertyOwned[14]) TEXT_ON_RIGHT(TheText.Get("STPR_15"));
+ }
+ STAT_LINE_1(int, "CHASE", HighestChaseValue, 0);
+ TEXT_ON_RIGHT(FindChaseString(HighestChaseValue));
+
+ return counter;
+
+#undef STAT_LINE_1
+#undef STAT_LINE_2
+#undef TEXT_ON_LEFT_GXT
+#undef TEXT_ON_RIGHT
+#undef FASTEST_TIME
+}
diff --git a/src/core/Stats.h b/src/core/Stats.h
index 6abcfb61..243ff0ec 100644
--- a/src/core/Stats.h
+++ b/src/core/Stats.h
@@ -1,14 +1,18 @@
#pragma once
#include "PedType.h"
+#include "audio_enums.h"
class CStats
{
public:
enum {
- TOTAL_FASTEST_TIMES = 16,
- TOTAL_HIGHEST_SCORES = 16
+ TOTAL_FASTEST_TIMES = 23,
+ TOTAL_HIGHEST_SCORES = 5,
+ TOTAL_BEST_POSITIONS = 1,
+ TOTAL_PROPERTIES = 15
};
+ static int32 SeagullsKilled;
static int32 DaysPassed;
static int32 HeadsPopped;
static int32 CommercialPassed;
@@ -21,12 +25,32 @@ public:
static int32 TimesDied;
static int32 TimesArrested;
static int32 KillsSinceLastCheckpoint;
- static float DistanceTravelledInVehicle;
+ static float DistanceTravelledByCar;
+ static float DistanceTravelledByHelicoptor;
+ static float DistanceTravelledByBike;
+ static float DistanceTravelledByBoat;
+ static float DistanceTravelledByPlane;
+ static float DistanceTravelledByGolfCart;
static float DistanceTravelledOnFoot;
+ static int32 FlightTime;
+ static int32 TimesDrowned;
+ static int32 PhotosTaken;
+ static float LoanSharks;
+ static float StoresKnockedOff;
+ static float MovieStunts;
+ static float Assassinations;
+ static float PizzasDelivered;
+ static float GarbagePickups;
+ static float IceCreamSold;
+ static float TopShootingRangeScore;
+ static float ShootingRank;
static int32 CarsExploded;
+ static int32 BoatsExploded;
+ static int32 WantedStarsAttained;
+ static int32 WantedStarsEvaded;
static int32 PeopleKilledByPlayer;
- static int32 ProgressMade;
- static int32 TotalProgressInGame;
+ static float ProgressMade;
+ static float TotalProgressInGame;
static float MaximumJumpDistance;
static float MaximumJumpHeight;
static int32 MaximumJumpFlips;
@@ -40,45 +64,61 @@ public:
static int32 MissionsPassed;
static char LastMissionPassedName[8];
static int32 TotalLegitimateKills;
- static int32 ElBurroTime;
- static int32 Record4x4One;
- static int32 Record4x4Two;
- static int32 Record4x4Three;
- static int32 Record4x4Mayhem;
static int32 LivesSavedWithAmbulance;
static int32 CriminalsCaught;
static int32 HighestLevelAmbulanceMission;
+ static int32 HighestLevelVigilanteMission;
+ static int32 HighestLevelFireMission;
static int32 FiresExtinguished;
- 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 BulletsThatHit;
static int32 BestTimeBombDefusal;
- static int32 mmRain;
- static int32 CarsCrushed;
static int32 FastestTimes[TOTAL_FASTEST_TIMES];
static int32 HighestScores[TOTAL_HIGHEST_SCORES];
+ static int32 BestPositions[TOTAL_BEST_POSITIONS];
+ static bool PropertyOwned[TOTAL_PROPERTIES];
+ static int32 NumPropertyOwned;
+ static int32 PropertyDestroyed;
+ static float HighestChaseValue;
+ static int32 CheatedCount;
+ static int32 ShowChaseStatOnScreen;
+ static int32 PamphletMissionPassed;
+ static bool abSonyCDs[1];
+ static int32 BloodRingKills;
+ static int32 BloodRingTime;
+ static float FavoriteRadioStationList[NUM_RADIOS];
+ static int32 Sprayings;
+ static float AutoPaintingBudget;
+ static int32 NoMoreHurricanes;
+ static float FashionBudget;
+ static float PropertyBudget;
+ static float WeaponBudget;
+ static int32 SafeHouseVisits;
+ static int32 TyresPopped;
+
+ static int32 LongestWheelie;
+ static int32 LongestStoppie;
+ static int32 Longest2Wheel;
+ static float LongestWheelieDist;
+ static float LongestStoppieDist;
+ static float Longest2WheelDist;
public:
static void Init(void);
static void RegisterFastestTime(int32, int32);
static void RegisterHighestScore(int32, int32);
- static void RegisterElBurroTime(int32);
- static void Register4x4OneTime(int32);
- static void Register4x4TwoTime(int32);
- static void Register4x4ThreeTime(int32);
- static void Register4x4MayhemTime(int32);
+ static void RegisterBestPosition(int32, int32);
static void AnotherLifeSavedWithAmbulance();
static void AnotherCriminalCaught();
static void RegisterLevelAmbulanceMission(int32);
+ static void RegisterLevelVigilanteMission(int32);
+ static void RegisterLevelFireMission(int32);
static void AnotherFireExtinguished();
static wchar *FindCriminalRatingString();
- static void RegisterLongestFlightInDodo(int32);
- static void RegisterTimeTakenDefuseMission(int32);
+ static wchar *FindChaseString(float fMediaLevel);
static void AnotherKillFrenzyPassed();
static void SetTotalNumberKillFrenzies(int32);
static void SetTotalNumberMissions(int32);
@@ -87,4 +127,26 @@ public:
static int32 FindCriminalRatingNumber();
static void SaveStats(uint8 *buf, uint32 *size);
static void LoadStats(uint8 *buf, uint32 size);
+ static float GetPercentageProgress();
+
+ static void MoneySpentOnWeapons(int32);
+ static void MoneySpentOnProperty(int32);
+ static void MoneySpentOnAutoPainting(int32);
+ static void MoneySpentOnFashion(int32);
+
+ static void NumOfVisitsFromLoanSharks(int32);
+ static void NumOfStoresKnockedOff(int32);
+ static void NumOfMovieStunts(int32);
+ static void NumOfAssassinations(int32);
+ static void NumOfPizzasDelivered(int32);
+ static void NumOfGarbagePickups(int32);
+ static void NumOfIceCreamSold(int32);
+ static void AddNumBloodRingKills(int32);
+
+ static void LongestTimeInBloodRing(int32);
+ static void AddPropertyAsOwned(int32);
+ static void PopulateFavoriteRadioStationList();
+ static float GetFavoriteRadioStationList(int32);
+ static void BuildStatLine(Const char *, void *, int, void *, int);
+ static int ConstructStatLine(int);
};
diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp
index 9ac22096..6d980e18 100644
--- a/src/core/Streaming.cpp
+++ b/src/core/Streaming.cpp
@@ -18,7 +18,6 @@
#include "FileMgr.h"
#include "FileLoader.h"
#include "Zones.h"
-#include "ZoneCull.h"
#include "Radar.h"
#include "Camera.h"
#include "Record.h"
@@ -28,14 +27,16 @@
#include "CutsceneMgr.h"
#include "CdStream.h"
#include "Streaming.h"
-#ifdef FIX_BUGS
#include "Replay.h"
-#endif
#include "main.h"
-#include "Frontend.h"
-#include "Font.h"
+#include "ColStore.h"
+#include "DMAudio.h"
+#include "Script.h"
#include "MemoryMgr.h"
#include "MemoryHeap.h"
+#include "Font.h"
+#include "Frontend.h"
+#include "VarConsole.h"
bool CStreaming::ms_disableStreaming;
bool CStreaming::ms_bLoadingBigModel;
@@ -57,11 +58,12 @@ size_t CStreaming::ms_memoryUsed;
CStreamingChannel CStreaming::ms_channel[2];
int32 CStreaming::ms_channelError;
int32 CStreaming::ms_numVehiclesLoaded;
+int32 CStreaming::ms_numPedsLoaded;
int32 CStreaming::ms_vehiclesLoaded[MAXVEHICLESLOADED];
int32 CStreaming::ms_lastVehicleDeleted;
+bool CStreaming::ms_bIsPedFromPedGroupLoaded[NUMMODELSPERPEDGROUP];
CDirectory *CStreaming::ms_pExtraObjectsDir;
int32 CStreaming::ms_numPriorityRequests;
-bool CStreaming::ms_hasLoadedLODs;
int32 CStreaming::ms_currentPedGrp;
int32 CStreaming::ms_currentPedLoading;
int32 CStreaming::ms_lastCullZone;
@@ -74,16 +76,16 @@ size_t CStreaming::ms_memoryAvailable;
int32 desiredNumVehiclesLoaded = 12;
-CEntity *pIslandLODindustEntity;
-CEntity *pIslandLODcomIndEntity;
-CEntity *pIslandLODcomSubEntity;
-CEntity *pIslandLODsubIndEntity;
-CEntity *pIslandLODsubComEntity;
-int32 islandLODindust;
-int32 islandLODcomInd;
-int32 islandLODcomSub;
-int32 islandLODsubInd;
-int32 islandLODsubCom;
+CEntity *pIslandLODmainlandEntity;
+CEntity *pIslandLODbeachEntity;
+int32 islandLODmainland;
+int32 islandLODbeach;
+
+#ifndef MASTER
+bool gbPrintStats;
+bool gbPrintVehiclesInMemory; // TODO
+bool gbPrintStreamingBuffer; // TODO
+#endif
bool
CStreamingInfo::GetCdPosnAndSize(uint32 &posn, uint32 &size)
@@ -189,14 +191,17 @@ CStreaming::Init2(void)
for(i = 0; i < MAXVEHICLESLOADED; i++)
ms_vehiclesLoaded[i] = -1;
ms_numVehiclesLoaded = 0;
+ ms_numPedsLoaded = 8;
+
+ for(i = 0; i < ARRAY_SIZE(ms_bIsPedFromPedGroupLoaded); i++)
+ ms_bIsPedFromPedGroupLoaded[i] = false;
ms_pExtraObjectsDir = new CDirectory(EXTRADIRSIZE);
ms_numPriorityRequests = 0;
- ms_hasLoadedLODs = true;
ms_currentPedGrp = -1;
ms_lastCullZone = -1; // unused because RemoveModelsNotVisibleFromCullzone is gone
ms_loadedGangs = 0;
- ms_currentPedLoading = 8; // unused, whatever it is
+ ms_currentPedLoading = NUMMODELSPERPEDGROUP; // unused, whatever it is
LoadCdDirectory();
@@ -218,77 +223,84 @@ CStreaming::Init2(void)
// PC only, figure out how much memory we got
#ifdef GTA_PC
#define MB (1024*1024)
-
+#ifdef FIX_BUGS
+ // do what gta3 does
extern size_t _dwMemAvailPhys;
ms_memoryAvailable = (_dwMemAvailPhys - 10*MB)/2;
- if(ms_memoryAvailable < 50*MB)
- ms_memoryAvailable = 50*MB;
- desiredNumVehiclesLoaded = (int32)((ms_memoryAvailable / MB - 50) / 3 + 12);
+ if(ms_memoryAvailable < 65*MB)
+ ms_memoryAvailable = 65*MB;
+ desiredNumVehiclesLoaded = (int32)((ms_memoryAvailable / MB - 65) / 3 + 12);
if(desiredNumVehiclesLoaded > MAXVEHICLESLOADED)
desiredNumVehiclesLoaded = MAXVEHICLESLOADED;
+#else
+ ms_memoryAvailable = 65 * MB;
+ desiredNumVehiclesLoaded = 25;
debug("Memory allocated to Streaming is %zuMB", ms_memoryAvailable/MB); // original modifier was %d
+#endif
#undef MB
#endif
// find island LODs
- pIslandLODindustEntity = nil;
- pIslandLODcomIndEntity = nil;
- pIslandLODcomSubEntity = nil;
- pIslandLODsubIndEntity = nil;
- pIslandLODsubComEntity = nil;
- islandLODindust = -1;
- islandLODcomInd = -1;
- islandLODcomSub = -1;
- islandLODsubInd = -1;
- islandLODsubCom = -1;
- CModelInfo::GetModelInfo("IslandLODInd", &islandLODindust);
- CModelInfo::GetModelInfo("IslandLODcomIND", &islandLODcomInd);
- CModelInfo::GetModelInfo("IslandLODcomSUB", &islandLODcomSub);
- CModelInfo::GetModelInfo("IslandLODsubIND", &islandLODsubInd);
- CModelInfo::GetModelInfo("IslandLODsubCOM", &islandLODsubCom);
+ pIslandLODmainlandEntity = nil;
+ pIslandLODbeachEntity = nil;
+ islandLODmainland = -1;
+ islandLODbeach = -1;
+ CModelInfo::GetModelInfo("IslandLODmainland", &islandLODmainland);
+ CModelInfo::GetModelInfo("IslandLODbeach", &islandLODbeach);
- for(i = CPools::GetBuildingPool()->GetSize()-1; i >= 0; i--){
- CBuilding *building = CPools::GetBuildingPool()->GetSlot(i);
- if(building == nil)
- continue;
- if(building->GetModelIndex() == islandLODindust) pIslandLODindustEntity = building;
- if(building->GetModelIndex() == islandLODcomInd) pIslandLODcomIndEntity = building;
- if(building->GetModelIndex() == islandLODcomSub) pIslandLODcomSubEntity = building;
- if(building->GetModelIndex() == islandLODsubInd) pIslandLODsubIndEntity = building;
- if(building->GetModelIndex() == islandLODsubCom) pIslandLODsubComEntity = building;
- }
+#ifndef MASTER
+ VarConsole.Add("Streaming Debug", &gbPrintStats, true);
+ VarConsole.Add("Streaming Vehicle Debug", &gbPrintVehiclesInMemory, true);
+ VarConsole.Add("Printf Streaming Buffer contents", &gbPrintStreamingBuffer, true);
+#endif
}
void
CStreaming::Init(void)
{
#ifdef USE_TXD_CDIMAGE
- int txdHandle = CFileMgr::OpenFile("MODELS\\TXD.IMG", "r");
- if (txdHandle)
- CFileMgr::CloseFile(txdHandle);
- if (!CheckVideoCardCaps() && txdHandle) {
- CdStreamAddImage("MODELS\\TXD.IMG");
- CStreaming::Init2();
- } else {
- CStreaming::Init2();
- if (CreateTxdImageForVideoCard()) {
- CStreaming::Shutdown();
+ if(!CanVideoCardDoDXT()){
+ int txdHandle = CFileMgr::OpenFile("MODELS\\TXD.IMG", "r");
+ if (txdHandle)
+ CFileMgr::CloseFile(txdHandle);
+ if (!CheckVideoCardCaps() && txdHandle) {
CdStreamAddImage("MODELS\\TXD.IMG");
CStreaming::Init2();
+ } else {
+ CStreaming::Init2();
+ if (CreateTxdImageForVideoCard()) {
+ CStreaming::Shutdown();
+ CdStreamAddImage("MODELS\\TXD.IMG");
+ CStreaming::Init2();
+ }
}
- }
+ } else
+ CStreaming::Init2();
#else
CStreaming::Init2();
#endif
}
void
+CStreaming::ReInit(void)
+{
+ int i;
+ CStreaming::FlushRequestList();
+ CStreaming::DeleteAllRwObjects();
+ CStreaming::RemoveAllUnusedModels();
+ for(i = 0; i < MODELINFOSIZE; i++)
+ if(CModelInfo::GetModelInfo(i) && ms_aInfoForModel[i].m_flags & STREAMFLAGS_SCRIPTOWNED)
+ SetMissionDoesntRequireModel(i);
+ CStreaming::ms_disableStreaming = false;
+}
+
+void
CStreaming::Shutdown(void)
{
RwFreeAlign(ms_pStreamingBuffer[0]);
ms_streamingBufferSize = 0;
- if(ms_pExtraObjectsDir){
+ if(ms_pExtraObjectsDir) {
delete ms_pExtraObjectsDir;
#ifdef FIX_BUGS
ms_pExtraObjectsDir = nil;
@@ -304,7 +316,6 @@ uint64 timeProcessingDFF;
void
CStreaming::Update(void)
{
- CEntity *train;
CStreamingInfo *si, *prev;
bool requestedSubway = false;
@@ -323,39 +334,36 @@ CStreaming::Update(void)
if(CTimer::GetIsPaused())
return;
- train = FindPlayerTrain();
- if(train && train->GetPosition().z < 0.0f){
- RequestSubway();
- requestedSubway = true;
- }else if(!ms_disableStreaming)
- AddModelsToRequestList(TheCamera.GetPosition());
+ LoadBigBuildingsWhenNeeded();
+ if(!ms_disableStreaming && TheCamera.GetPosition().z < 55.0f)
+ AddModelsToRequestList(TheCamera.GetPosition(), 0);
DeleteFarAwayRwObjects(TheCamera.GetPosition());
if(!ms_disableStreaming &&
- !CCutsceneMgr::IsRunning() &&
- !requestedSubway &&
- !CGame::playingIntro &&
+ !CCutsceneMgr::IsCutsceneProcessing() &&
ms_numModelsRequested < 5 &&
- !CRenderer::m_loadingPriority
-#ifdef FIX_BUGS
- && !CReplay::IsPlayingBack()
-#endif
- ){
+ !CRenderer::m_loadingPriority &&
+ CGame::currArea == AREA_MAIN_MAP &&
+ !CReplay::IsPlayingBack()){
StreamVehiclesAndPeds();
StreamZoneModels(FindPlayerCoors());
}
LoadRequestedModels();
-#ifndef MASTER
- if (CPad::GetPad(1)->GetLeftShoulder1JustDown() && CPad::GetPad(1)->GetRightShoulder1() && CPad::GetPad(1)->GetRightShoulder2())
- PrintStreamingBufferState();
+ if(CWorld::Players[0].m_pRemoteVehicle){
+ CColStore::AddCollisionNeededAtPosn(FindPlayerCoors());
+ CColStore::LoadCollision(CWorld::Players[0].m_pRemoteVehicle->GetPosition());
+ CColStore::EnsureCollisionIsInMemory(CWorld::Players[0].m_pRemoteVehicle->GetPosition());
+ }else{
+ CColStore::LoadCollision(FindPlayerCoors());
+ CColStore::EnsureCollisionIsInMemory(FindPlayerCoors());
+ }
// TODO: PrintRequestList
//if (CPad::GetPad(1)->GetLeftShoulder2JustDown() && CPad::GetPad(1)->GetRightShoulder1() && CPad::GetPad(1)->GetRightShoulder2())
// PrintRequestList();
-#endif
for(si = ms_endRequestedList.m_prev; si != &ms_startRequestedList; si = prev){
prev = si->m_prev;
@@ -377,12 +385,6 @@ CStreaming::LoadCdDirectory(void)
ms_imageOffsets[3] = -1;
ms_imageOffsets[4] = -1;
ms_imageOffsets[5] = -1;
- ms_imageOffsets[6] = -1;
- ms_imageOffsets[7] = -1;
- ms_imageOffsets[8] = -1;
- ms_imageOffsets[9] = -1;
- ms_imageOffsets[10] = -1;
- ms_imageOffsets[11] = -1;
ms_imageSize = GetGTA3ImgSize();
// PS2 uses CFileMgr::GetCdFile on all IMG files to fill the array
#endif
@@ -402,8 +404,7 @@ void
CStreaming::LoadCdDirectory(const char *dirname, int n)
{
int fd, lastID, imgSelector;
- int modelId, txdId;
- uint32 posn, size;
+ int modelId;
CDirectory::DirectoryInfo direntry;
char *dot;
@@ -414,24 +415,23 @@ CStreaming::LoadCdDirectory(const char *dirname, int n)
imgSelector = n<<24;
assert(sizeof(direntry) == 32);
while(CFileMgr::Read(fd, (char*)&direntry, sizeof(direntry))){
- dot = strchr(direntry.name, '.');
- assert(dot);
- if(dot) *dot = '\0';
+ bool bAddToStreaming = false;
+
if(direntry.size > (uint32)ms_streamingBufferSize)
ms_streamingBufferSize = direntry.size;
+ direntry.name[23] = '\0';
+ dot = strchr(direntry.name, '.');
+ if(dot == nil || dot-direntry.name > 20){
+ debug("%s is too long\n", direntry.name);
+ lastID = -1;
+ continue;
+ }
+
+ *dot = '\0';
- if(!CGeneral::faststrcmp(dot+1, "DFF") || !CGeneral::faststrcmp(dot+1, "dff")){
+ if(strncasecmp(dot+1, "DFF", 3) == 0){
if(CModelInfo::GetModelInfo(direntry.name, &modelId)){
- if(ms_aInfoForModel[modelId].GetCdPosnAndSize(posn, size)){
- debug("%s appears more than once in %s\n", direntry.name, dirname);
- lastID = -1;
- }else{
- direntry.offset |= imgSelector;
- ms_aInfoForModel[modelId].SetCdPosnAndSize(direntry.offset, direntry.size);
- if(lastID != -1)
- ms_aInfoForModel[lastID].m_nextID = modelId;
- lastID = modelId;
- }
+ bAddToStreaming = true;
}else{
#ifdef FIX_BUGS
// remember which cdimage this came from
@@ -441,52 +441,66 @@ CStreaming::LoadCdDirectory(const char *dirname, int n)
#endif
lastID = -1;
}
- }else if(!CGeneral::faststrcmp(dot+1, "TXD") || !CGeneral::faststrcmp(dot+1, "txd")){
- txdId = CTxdStore::FindTxdSlot(direntry.name);
- if(txdId == -1)
- txdId = CTxdStore::AddTxdSlot(direntry.name);
- if(ms_aInfoForModel[txdId + STREAM_OFFSET_TXD].GetCdPosnAndSize(posn, size)){
- debug("%s appears more than once in %s\n", direntry.name, dirname);
+ }else if(strncasecmp(dot+1, "TXD", 3) == 0){
+ modelId = CTxdStore::FindTxdSlot(direntry.name);
+ if(modelId == -1)
+ modelId = CTxdStore::AddTxdSlot(direntry.name);
+ modelId += STREAM_OFFSET_TXD;
+ bAddToStreaming = true;
+ }else if(strncasecmp(dot+1, "COL", 3) == 0){
+ modelId = CColStore::FindColSlot(direntry.name);
+ if(modelId == -1)
+ modelId = CColStore::AddColSlot(direntry.name);
+ modelId += STREAM_OFFSET_COL;
+ bAddToStreaming = true;
+ }else if(strncasecmp(dot+1, "IFP", 3) == 0){
+ modelId = CAnimManager::RegisterAnimBlock(direntry.name);
+ modelId += STREAM_OFFSET_ANIM;
+ bAddToStreaming = true;
+ }else{
+ *dot = '.';
+ lastID = -1;
+ }
+
+ if(bAddToStreaming){
+ if(ms_aInfoForModel[modelId].GetCdSize()){
+ debug("%s.%s appears more than once in %s\n", direntry.name, dot+1, dirname);
lastID = -1;
}else{
direntry.offset |= imgSelector;
- ms_aInfoForModel[txdId + STREAM_OFFSET_TXD].SetCdPosnAndSize(direntry.offset, direntry.size);
+ ms_aInfoForModel[modelId].SetCdPosnAndSize(direntry.offset, direntry.size);
if(lastID != -1)
- ms_aInfoForModel[lastID].m_nextID = txdId + STREAM_OFFSET_TXD;
- lastID = txdId + STREAM_OFFSET_TXD;
+ ms_aInfoForModel[lastID].m_nextID = modelId;
+ lastID = modelId;
}
- }else
- lastID = -1;
+ }
}
CFileMgr::CloseFile(fd);
}
+static char*
+GetObjectName(int streamId)
+{
+ static char objname[32];
+ if(streamId < STREAM_OFFSET_TXD)
+ sprintf(objname, "%s.dff", CModelInfo::GetModelInfo(streamId)->GetModelName());
+ else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL)
+ sprintf(objname, "%s.txd", CTxdStore::GetTxdName(streamId-STREAM_OFFSET_TXD));
+ else if(streamId >= STREAM_OFFSET_COL && streamId < STREAM_OFFSET_ANIM)
+ sprintf(objname, "%s.col", CColStore::GetColName(streamId-STREAM_OFFSET_COL));
+ else{
+ assert(streamId < NUMSTREAMINFO);
+ sprintf(objname, "%s.ifp", CAnimManager::GetAnimationBlock(streamId-STREAM_OFFSET_ANIM)->name);
+ }
+ return objname;
+}
+
#ifdef USE_CUSTOM_ALLOCATOR
RpAtomic*
RegisterAtomicMemPtrsCB(RpAtomic *atomic, void *data)
{
-#if THIS_IS_COMPATIBLE_WITH_GTA3_RW31
- // not quite sure what's going on here:
- // gta3's RW 3.1 allocates separate memory for geometry data of RpGeometry.
- // Is that a R* change? rpDefaultGeometryInstance also depends on it
- RpGeometry *geo = RpAtomicGetGeometry(atomic);
- if(geo->triangles)
- REGISTER_MEMPTR(&geo->triangles);
- if(geo->matList.materials)
- REGISTER_MEMPTR(&geo->matList.materials);
- if(geo->preLitLum)
- REGISTER_MEMPTR(&geo->preLitLum);
- if(geo->texCoords[0])
- REGISTER_MEMPTR(&geo->texCoords[0]);
- if(geo->texCoords[1])
- REGISTER_MEMPTR(&geo->texCoords[1]);
-#else
- // normally RpGeometry is allocated in one block (excluding morph targets)
- // so we don't really have allocated pointers in the struct.
- // NB: in librw we actually do it in two allocations (geometry itself and data)
- // so we could conceivably come up with something here
-#endif
+ // empty because we expect models to be pre-instanced
return atomic;
}
#endif
@@ -512,34 +526,33 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
// Model
mi = CModelInfo::GetModelInfo(streamId);
- // Txd has to be loaded
+ // Txd and anim have to be loaded
+ int animId = mi->GetAnimFileIndex();
#ifdef FIX_BUGS
- if(!HasTxdLoaded(mi->GetTxdSlot())){
+ if(!HasTxdLoaded(mi->GetTxdSlot()) ||
#else
// texDict will exist even if only first part has loaded
- if(CTxdStore::GetSlot(mi->GetTxdSlot())->texDict == nil){
+ if(CTxdStore::GetSlot(mi->GetTxdSlot())->texDict == nil ||
#endif
- debug("failed to load %s because TXD %s is not in memory\n", mi->GetModelName(), CTxdStore::GetTxdName(mi->GetTxdSlot()));
+ animId != -1 && !CAnimManager::GetAnimationBlock(animId)->isLoaded){
RemoveModel(streamId);
-#ifndef FIX_BUGS
- // if we're just waiting for it to load, don't remove this
- RemoveTxd(mi->GetTxdSlot());
-#endif
ReRequestModel(streamId);
RwStreamClose(stream, &mem);
return false;
}
- // Set Txd to use
+ // Set Txd and anims to use
CTxdStore::AddRef(mi->GetTxdSlot());
+#if GTA_VERSION > GTAVC_PS2
+ if(animId != -1)
+ CAnimManager::AddAnimBlockRef(animId);
+#endif
PUSH_MEMID(MEMID_STREAM_MODELS);
CTxdStore::SetCurrentTxd(mi->GetTxdSlot());
if(mi->IsSimple()){
success = CFileLoader::LoadAtomicFile(stream, streamId);
-#ifdef USE_CUSTOM_ALLOCATOR
- RegisterAtomicMemPtrsCB(((CSimpleModelInfo*)mi)->m_atomics[0], nil);
-#endif
+ // TODO(MIAMI)? complain if file is not pre-instanced. we hardly are interested in that
} else if (mi->GetModelType() == MITYPE_VEHICLE) {
// load vehicles in two parts
CModelInfo::GetModelInfo(streamId)->AddRef();
@@ -556,9 +569,14 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
POP_MEMID();
UpdateMemoryUsed();
- // Txd no longer needed unless we only read part of the file
- if(ms_aInfoForModel[streamId].m_loadState != STREAMSTATE_STARTED)
+ // Txd and anims no longer needed unless we only read part of the file
+ if(ms_aInfoForModel[streamId].m_loadState != STREAMSTATE_STARTED){
CTxdStore::RemoveRefWithoutDelete(mi->GetTxdSlot());
+#if GTA_VERSION > GTAVC_PS2
+ if(animId != -1)
+ CAnimManager::RemoveAnimBlockRefWithoutDelete(animId);
+#endif
+ }
if(!success){
debug("Failed to load %s\n", CModelInfo::GetModelInfo(streamId)->GetModelName());
@@ -567,9 +585,8 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
RwStreamClose(stream, &mem);
return false;
}
- }else{
+ }else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL){
// Txd
- assert(streamId < NUMSTREAMINFO);
if((ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_KEEP_IN_MEMORY) == 0 &&
!IsTxdUsedByRequestedModels(streamId - STREAM_OFFSET_TXD)){
RemoveModel(streamId);
@@ -594,20 +611,33 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
RwStreamClose(stream, &mem);
return false;
}
+ }else if(streamId >= STREAM_OFFSET_COL && streamId < STREAM_OFFSET_ANIM){
+ PUSH_MEMID(MEMID_STREAM_COLLISION);
+ bool success = CColStore::LoadCol(streamId-STREAM_OFFSET_COL, mem.start, mem.length);
+ POP_MEMID();
+ if(!success){
+ debug("Failed to load %s.col\n", CColStore::GetColName(streamId - STREAM_OFFSET_COL));
+ RemoveModel(streamId);
+ ReRequestModel(streamId);
+ RwStreamClose(stream, &mem);
+ return false;
+ }
+ }else if(streamId >= STREAM_OFFSET_ANIM){
+ assert(streamId < NUMSTREAMINFO);
+ if((ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_KEEP_IN_MEMORY) == 0 &&
+ !AreAnimsUsedByRequestedModels(streamId - STREAM_OFFSET_ANIM)){
+ RemoveModel(streamId);
+ RwStreamClose(stream, &mem);
+ return false;
+ }
+ PUSH_MEMID(MEMID_STREAM_ANIMATION);
+ CAnimManager::LoadAnimFile(stream, true, nil);
+ CAnimManager::CreateAnimAssocGroups();
+ POP_MEMID();
}
RwStreamClose(stream, &mem);
- // We shouldn't even end up here unless load was successful
- if(!success){
- ReRequestModel(streamId);
- if(streamId < STREAM_OFFSET_TXD)
- debug("Failed to load %s.dff\n", mi->GetModelName());
- else
- debug("Failed to load %s.txd\n", CTxdStore::GetTxdName(streamId - STREAM_OFFSET_TXD));
- return false;
- }
-
if(streamId < STREAM_OFFSET_TXD){
// Model
// Vehicles and Peds not in loaded list
@@ -622,12 +652,14 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
smi->m_alpha = 0;
}
- if((ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_CANT_REMOVE) == 0)
+ if(CanRemoveModel(streamId))
ms_aInfoForModel[streamId].AddToList(&ms_startLoadedList);
}
- }else{
- // Txd
- if((ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_CANT_REMOVE) == 0)
+ }else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL ||
+ streamId >= STREAM_OFFSET_ANIM){
+ assert(streamId < NUMSTREAMINFO);
+ // Txd and anims
+ if(CanRemoveModel(streamId))
ms_aInfoForModel[streamId].AddToList(&ms_startLoadedList);
}
@@ -641,17 +673,12 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
endTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond();
timeDiff = endTime - startTime;
- if(timeDiff > 5){
- if(streamId < STREAM_OFFSET_TXD)
- debug("model %s took %d ms\n", CModelInfo::GetModelInfo(streamId)->GetModelName(), timeDiff);
- else
- debug("txd %s took %d ms\n", CTxdStore::GetTxdName(streamId - STREAM_OFFSET_TXD), timeDiff);
- }
+ if(timeDiff > 5)
+ debug("%s took %d ms\n", GetObjectName(streamId), timeDiff);
return true;
}
-
bool
CStreaming::FinishLoadingLargeFile(int8 *buf, int32 streamId)
{
@@ -688,18 +715,24 @@ CStreaming::FinishLoadingLargeFile(int8 *buf, int32 streamId)
POP_MEMID();
mi->RemoveRef();
CTxdStore::RemoveRefWithoutDelete(mi->GetTxdSlot());
- }else{
+#if GTA_VERSION > GTAVC_PS2
+ if(mi->GetAnimFileIndex() != -1)
+ CAnimManager::RemoveAnimBlockRefWithoutDelete(mi->GetAnimFileIndex());
+#endif
+ }else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL){
// Txd
CTxdStore::AddRef(streamId - STREAM_OFFSET_TXD);
PUSH_MEMID(MEMID_STREAM_TEXUTRES);
success = CTxdStore::FinishLoadTxd(streamId - STREAM_OFFSET_TXD, stream);
POP_MEMID();
CTxdStore::RemoveRefWithoutDelete(streamId - STREAM_OFFSET_TXD);
+ }else{
+ assert(0 && "invalid streamId");
}
RwStreamClose(stream, &mem);
- ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_LOADED; // only done if success on PS2
+ ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_LOADED;
#ifndef USE_CUSTOM_ALLOCATOR
ms_memoryUsed += ms_aInfoForModel[streamId].GetCdSize() * CDSTREAM_SECTOR_SIZE;
#endif
@@ -707,20 +740,16 @@ CStreaming::FinishLoadingLargeFile(int8 *buf, int32 streamId)
if(!success){
RemoveModel(streamId);
ReRequestModel(streamId);
- UpdateMemoryUsed(); // directly after pop on PS2
+ UpdateMemoryUsed();
return false;
}
- UpdateMemoryUsed(); // directly after pop on PS2
+ UpdateMemoryUsed();
endTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond();
timeDiff = endTime - startTime;
- if(timeDiff > 5){
- if(streamId < STREAM_OFFSET_TXD)
- debug("finish model %s took %d ms\n", CModelInfo::GetModelInfo(streamId)->GetModelName(), timeDiff);
- else
- debug("finish txd %s took %d ms\n", CTxdStore::GetTxdName(streamId - STREAM_OFFSET_TXD), timeDiff);
- }
+ if(timeDiff > 5)
+ debug("%s took %d ms\n", GetObjectName(streamId), timeDiff);
return true;
}
@@ -753,15 +782,20 @@ CStreaming::RequestModel(int32 id, int32 flags)
// reinsert into list
if(ms_aInfoForModel[id].m_next){
ms_aInfoForModel[id].RemoveFromList();
- if((ms_aInfoForModel[id].m_flags & STREAMFLAGS_CANT_REMOVE) == 0)
+ if(CanRemoveModel(id))
ms_aInfoForModel[id].AddToList(&ms_startLoadedList);
}
}else if(ms_aInfoForModel[id].m_loadState == STREAMSTATE_NOTLOADED ||
ms_aInfoForModel[id].m_loadState == STREAMSTATE_LOADED){ // how can this be true again?
if(ms_aInfoForModel[id].m_loadState == STREAMSTATE_NOTLOADED){
- if(id < STREAM_OFFSET_TXD)
- RequestTxd(CModelInfo::GetModelInfo(id)->GetTxdSlot(), flags);
+ if(id < STREAM_OFFSET_TXD){
+ mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(id);
+ RequestTxd(mi->GetTxdSlot(), flags);
+ int anim = mi->GetAnimFileIndex();
+ if(anim != -1)
+ RequestAnim(anim, STREAMFLAGS_DEPENDENCY);
+ }
ms_aInfoForModel[id].AddToList(&ms_startRequestedList);
ms_numModelsRequested++;
if(flags & STREAMFLAGS_PRIORITY)
@@ -773,52 +807,34 @@ CStreaming::RequestModel(int32 id, int32 flags)
}
}
+#define BIGBUILDINGFLAGS STREAMFLAGS_DONT_REMOVE
+
void
-CStreaming::RequestSubway(void)
-{
- RequestModel(MI_SUBWAY1, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY2, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY3, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY4, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY5, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY6, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY7, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY8, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY9, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY10, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY11, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY12, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY13, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY14, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY15, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY16, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY17, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY18, STREAMFLAGS_NOFADE);
-
- switch(CGame::currLevel){
- case LEVEL_INDUSTRIAL:
- RequestModel(MI_SUBPLATFORM_IND, STREAMFLAGS_NOFADE);
- break;
- case LEVEL_COMMERCIAL:
- if(FindPlayerTrain()->GetPosition().y < -700.0f){
- RequestModel(MI_SUBPLATFORM_COMS, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBPLATFORM_COMS2, STREAMFLAGS_NOFADE);
- }else{
- RequestModel(MI_SUBPLATFORM_COMN, STREAMFLAGS_NOFADE);
- }
- break;
- case LEVEL_SUBURBAN:
- RequestModel(MI_SUBPLATFORM_SUB, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBPLATFORM_SUB2, STREAMFLAGS_NOFADE);
- break;
- default: break;
+CStreaming::RequestBigBuildings(eLevelName level)
+{
+ int i, n;
+ CBuilding *b;
+
+ n = CPools::GetBuildingPool()->GetSize()-1;
+ for(i = n; i >= 0; i--){
+ b = CPools::GetBuildingPool()->GetSlot(i);
+ if(b && b->bIsBIGBuilding
+#ifdef NO_ISLAND_LOADING
+ && (((FrontEndMenuManager.m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_LOW) && (b != pIslandLODmainlandEntity) &&
+ (b != pIslandLODbeachEntity)) ||
+ (b->m_level == level))
+#else
+ && b->m_level == level
+#endif
+ )
+ if(!b->bStreamBIGBuilding)
+ RequestModel(b->GetModelIndex(), BIGBUILDINGFLAGS);
}
+ RequestIslands(level);
}
-#define BIGBUILDINGFLAGS STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_PRIORITY
-
void
-CStreaming::RequestBigBuildings(eLevelName level)
+CStreaming::RequestBigBuildings(eLevelName level, const CVector &pos)
{
int i, n;
CBuilding *b;
@@ -828,17 +844,74 @@ CStreaming::RequestBigBuildings(eLevelName level)
b = CPools::GetBuildingPool()->GetSlot(i);
if(b && b->bIsBIGBuilding
#ifdef NO_ISLAND_LOADING
- && (((CMenuManager::m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_LOW) && (b != pIslandLODindustEntity) && (b != pIslandLODcomIndEntity) &&
- (b != pIslandLODcomSubEntity) && (b != pIslandLODsubIndEntity) && (b != pIslandLODsubComEntity)
+ && (((FrontEndMenuManager.m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_LOW) && (b != pIslandLODmainlandEntity) && (b != pIslandLODbeachEntity)
) || (b->m_level == level))
#else
- && b->m_level == level
+ && b->m_level == level
#endif
)
- RequestModel(b->GetModelIndex(), BIGBUILDINGFLAGS);
+ if(b->bStreamBIGBuilding){
+ if(CRenderer::ShouldModelBeStreamed(b, pos))
+ RequestModel(b->GetModelIndex(), 0);
+ }else
+ RequestModel(b->GetModelIndex(), BIGBUILDINGFLAGS);
}
RequestIslands(level);
- ms_hasLoadedLODs = false;
+}
+
+void
+CStreaming::InstanceBigBuildings(eLevelName level, const CVector &pos)
+{
+ int i, n;
+ CBuilding *b;
+
+ n = CPools::GetBuildingPool()->GetSize()-1;
+ for(i = n; i >= 0; i--){
+ b = CPools::GetBuildingPool()->GetSlot(i);
+ if(b && b->bIsBIGBuilding && b->m_level == level &&
+ b->bStreamBIGBuilding && b->m_rwObject == nil)
+ if(CRenderer::ShouldModelBeStreamed(b, pos))
+ b->CreateRwObject();
+ }
+}
+
+void
+CStreaming::InstanceLoadedModelsInSectorList(CPtrList &list)
+{
+ CPtrNode *node;
+ CEntity *e;
+ for(node = list.first; node; node = node->next) {
+ e = (CEntity *)node->item;
+ if(IsAreaVisible(e->m_area) && e->m_rwObject == nil)
+ e->CreateRwObject();
+ }
+}
+
+void
+CStreaming::InstanceLoadedModels(const CVector &pos)
+{
+ int minX = CWorld::GetSectorIndexX(pos.x - 80.0f);
+ if(minX <= 0) minX = 0;
+
+ int minY = CWorld::GetSectorIndexY(pos.y - 80.0f);
+ if(minY <= 0) minY = 0;
+
+ int maxX = CWorld::GetSectorIndexX(pos.x + 80.0f);
+ if(maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X - 1;
+
+ int maxY = CWorld::GetSectorIndexY(pos.y + 80.0f);
+ if(maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y - 1;
+
+ int x, y;
+ for(y = minY; y <= maxY; y++){
+ for(x = minX; x <= maxX; x++){
+ CSector *sector = CWorld::GetSector(x, y);
+ InstanceLoadedModelsInSectorList(sector->m_lists[ENTITYLIST_BUILDINGS]);
+ InstanceLoadedModelsInSectorList(sector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP]);
+ InstanceLoadedModelsInSectorList(sector->m_lists[ENTITYLIST_OBJECTS]);
+ InstanceLoadedModelsInSectorList(sector->m_lists[ENTITYLIST_DUMMIES]);
+ }
+ }
}
void
@@ -846,22 +919,68 @@ CStreaming::RequestIslands(eLevelName level)
{
ISLAND_LOADING_ISNT(HIGH)
switch(level){
- case LEVEL_INDUSTRIAL:
- RequestModel(islandLODcomInd, BIGBUILDINGFLAGS);
- RequestModel(islandLODsubInd, BIGBUILDINGFLAGS);
+ case LEVEL_MAINLAND:
+ if(islandLODbeach != -1)
+ RequestModel(islandLODbeach, BIGBUILDINGFLAGS);
break;
- case LEVEL_COMMERCIAL:
- RequestModel(islandLODindust, BIGBUILDINGFLAGS);
- RequestModel(islandLODsubCom, BIGBUILDINGFLAGS);
- break;
- case LEVEL_SUBURBAN:
- RequestModel(islandLODindust, BIGBUILDINGFLAGS);
- RequestModel(islandLODcomSub, BIGBUILDINGFLAGS);
+ case LEVEL_BEACH:
+ if(islandLODmainland != -1)
+ RequestModel(islandLODmainland, BIGBUILDINGFLAGS);
break;
default: break;
}
}
+static char *IGnames[] = {
+ "player",
+ "player2",
+ "player3",
+ "player4",
+ "player5",
+ "player6",
+ "player7",
+ "player8",
+ "player9",
+ "play10",
+ "play11",
+ "igken",
+ "igcandy",
+ "igsonny",
+ "igbuddy",
+ "igjezz",
+ "ighlary",
+ "igphil",
+ "igmerc",
+ "igdick",
+ "igdiaz",
+ ""
+};
+
+static char *CSnames[] = {
+ "csplay",
+ "csplay2",
+ "csplay3",
+ "csplay4",
+ "csplay5",
+ "csplay6",
+ "csplay7",
+ "csplay8",
+ "csplay9",
+ "csplay10",
+ "csplay11",
+ "csken",
+ "cscandy",
+ "cssonny",
+ "csbuddy",
+ "csjezz",
+ "cshlary",
+ "csphil",
+ "csmerc",
+ "csdick",
+ "csdiaz",
+ ""
+};
+
void
CStreaming::RequestSpecialModel(int32 modelId, const char *modelName, int32 flags)
{
@@ -869,14 +988,43 @@ CStreaming::RequestSpecialModel(int32 modelId, const char *modelName, int32 flag
int txdId;
char oldName[48];
uint32 pos, size;
+ int i, n;
mi = CModelInfo::GetModelInfo(modelId);
+ if(strncasecmp("CSPlay", modelName, 6) == 0){
+ char *curname = CModelInfo::GetModelInfo(MI_PLAYER)->GetModelName();
+ for(int i = 0; CSnames[i][0]; i++){
+ if(strcasecmp(curname, IGnames[i]) == 0){
+ modelName = CSnames[i];
+ break;
+ }
+ }
+ }
if(!CGeneral::faststrcmp(mi->GetModelName(), modelName)){
// Already have the correct name, just request it
RequestModel(modelId, flags);
return;
}
+ if(mi->GetNumRefs() > 0){
+ n = CPools::GetPedPool()->GetSize()-1;
+ for(i = n; i >= 0 && mi->GetNumRefs() > 0; i--){
+ CPed *ped = CPools::GetPedPool()->GetSlot(i);
+ if(ped && ped->GetModelIndex() == modelId &&
+ !ped->IsPlayer() && ped->CanBeDeletedEvenInVehicle())
+ CTheScripts::RemoveThisPed(ped);
+ }
+ n = CPools::GetObjectPool()->GetSize()-1;
+ for(i = n; i >= 0 && mi->GetNumRefs() > 0; i--){
+ CObject *obj = CPools::GetObjectPool()->GetSlot(i);
+ if(obj && obj->GetModelIndex() == modelId && obj->CanBeDeleted()){
+ CWorld::Remove(obj);
+ CWorld::RemoveReferencesToDeletedObject(obj);
+ delete obj;
+ }
+ }
+ }
+
strcpy(oldName, mi->GetModelName());
mi->SetModelName(modelName);
@@ -942,13 +1090,15 @@ CStreaming::RemoveModel(int32 id)
if(ms_aInfoForModel[id].m_loadState == STREAMSTATE_LOADED){
if(id < STREAM_OFFSET_TXD)
CModelInfo::GetModelInfo(id)->DeleteRwObject();
- else
+ else if(id >= STREAM_OFFSET_TXD && id < STREAM_OFFSET_COL)
CTxdStore::RemoveTxd(id - STREAM_OFFSET_TXD);
-#ifdef USE_CUSTOM_ALLOCATOR
- UpdateMemoryUsed();
-#else
+ else if(id >= STREAM_OFFSET_COL && id < STREAM_OFFSET_ANIM)
+ CColStore::RemoveCol(id - STREAM_OFFSET_COL);
+ else if(id >= STREAM_OFFSET_ANIM){
+ assert(id < NUMSTREAMINFO);
+ CAnimManager::RemoveAnimBlock(id - STREAM_OFFSET_ANIM);
+ }
ms_memoryUsed -= ms_aInfoForModel[id].GetCdSize()*CDSTREAM_SECTOR_SIZE;
-#endif
}
if(ms_aInfoForModel[id].m_next){
@@ -968,11 +1118,14 @@ CStreaming::RemoveModel(int32 id)
if(ms_aInfoForModel[id].m_loadState == STREAMSTATE_STARTED){
if(id < STREAM_OFFSET_TXD)
RpClumpGtaCancelStream();
- else
+ else if(id >= STREAM_OFFSET_TXD && id < STREAM_OFFSET_COL)
CTxdStore::RemoveTxd(id - STREAM_OFFSET_TXD);
-#ifdef USE_CUSTOM_ALLOCATOR
- UpdateMemoryUsed();
-#endif
+ else if(id >= STREAM_OFFSET_COL && id < STREAM_OFFSET_ANIM)
+ CColStore::RemoveCol(id - STREAM_OFFSET_COL);
+ else if(id >= STREAM_OFFSET_ANIM){
+ assert(id < NUMSTREAMINFO);
+ CAnimManager::RemoveAnimBlock(id - STREAM_OFFSET_ANIM);
+ }
}
ms_aInfoForModel[id].m_loadState = STREAMSTATE_NOTLOADED;
@@ -981,12 +1134,10 @@ CStreaming::RemoveModel(int32 id)
void
CStreaming::RemoveUnusedBuildings(eLevelName level)
{
- if(level != LEVEL_INDUSTRIAL)
- RemoveBuildings(LEVEL_INDUSTRIAL);
- if(level != LEVEL_COMMERCIAL)
- RemoveBuildings(LEVEL_COMMERCIAL);
- if(level != LEVEL_SUBURBAN)
- RemoveBuildings(LEVEL_SUBURBAN);
+ if(level != LEVEL_BEACH)
+ RemoveBuildings(LEVEL_BEACH);
+ if(level != LEVEL_MAINLAND)
+ RemoveBuildings(LEVEL_MAINLAND);
}
void
@@ -1050,16 +1201,69 @@ CStreaming::RemoveBuildings(eLevelName level)
}
void
+CStreaming::RemoveBuildingsNotInArea(int32 area)
+{
+ int i, n;
+ CEntity *e;
+
+ n = CPools::GetBuildingPool()->GetSize()-1;
+ for(i = n; i >= 0; i--){
+ e = CPools::GetBuildingPool()->GetSlot(i);
+ if(e && e->m_rwObject && !IsAreaVisible(area) &&
+ (!e->bIsBIGBuilding || e->bStreamBIGBuilding)){
+ if(e->bIsBIGBuilding)
+ RequestModel(e->GetModelIndex(), 0);
+ if(!e->bImBeingRendered)
+ e->DeleteRwObject();
+ }
+ }
+
+ n = CPools::GetTreadablePool()->GetSize()-1;
+ for(i = n; i >= 0; i--){
+ e = CPools::GetTreadablePool()->GetSlot(i);
+ if(e && e->m_rwObject && !IsAreaVisible(area) &&
+ (!e->bIsBIGBuilding || e->bStreamBIGBuilding)){
+ if(e->bIsBIGBuilding)
+ RequestModel(e->GetModelIndex(), 0);
+ if(!e->bImBeingRendered)
+ e->DeleteRwObject();
+ }
+ }
+
+ n = CPools::GetObjectPool()->GetSize()-1;
+ for(i = n; i >= 0; i--){
+ e = CPools::GetObjectPool()->GetSlot(i);
+ if(e && e->m_rwObject && !IsAreaVisible(area) &&
+ (!e->bIsBIGBuilding || e->bStreamBIGBuilding)){
+ if(e->bIsBIGBuilding)
+ RequestModel(e->GetModelIndex(), 0);
+ if(!e->bImBeingRendered)
+ e->DeleteRwObject();
+ }
+ }
+
+ n = CPools::GetDummyPool()->GetSize()-1;
+ for(i = n; i >= 0; i--){
+ e = CPools::GetDummyPool()->GetSlot(i);
+ if(e && e->m_rwObject && !IsAreaVisible(area) &&
+ (!e->bIsBIGBuilding || e->bStreamBIGBuilding)){
+ if(e->bIsBIGBuilding)
+ RequestModel(e->GetModelIndex(), 0);
+ if(!e->bImBeingRendered)
+ e->DeleteRwObject();
+ }
+ }
+}
+
+void
CStreaming::RemoveUnusedBigBuildings(eLevelName level)
{
ISLAND_LOADING_IS(LOW)
{
- if (level != LEVEL_INDUSTRIAL)
- RemoveBigBuildings(LEVEL_INDUSTRIAL);
- if (level != LEVEL_COMMERCIAL)
- RemoveBigBuildings(LEVEL_COMMERCIAL);
- if (level != LEVEL_SUBURBAN)
- RemoveBigBuildings(LEVEL_SUBURBAN);
+ if(level != LEVEL_BEACH)
+ RemoveBigBuildings(LEVEL_BEACH);
+ if(level != LEVEL_MAINLAND)
+ RemoveBigBuildings(LEVEL_MAINLAND);
}
RemoveIslandsNotUsed(level);
}
@@ -1080,37 +1284,30 @@ DeleteIsland(CEntity *island)
void
CStreaming::RemoveIslandsNotUsed(eLevelName level)
{
+ int i;
+ if(pIslandLODmainlandEntity == nil)
+ for(i = CPools::GetBuildingPool()->GetSize()-1; i >= 0; i--){
+ CBuilding *building = CPools::GetBuildingPool()->GetSlot(i);
+ if(building == nil)
+ continue;
+ if(building->GetModelIndex() == islandLODmainland)
+ pIslandLODmainlandEntity = building;
+ if(building->GetModelIndex() == islandLODbeach)
+ pIslandLODbeachEntity = building;
+ }
#ifdef NO_ISLAND_LOADING
- if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_HIGH) {
- DeleteIsland(pIslandLODindustEntity);
- DeleteIsland(pIslandLODcomIndEntity);
- DeleteIsland(pIslandLODcomSubEntity);
- DeleteIsland(pIslandLODsubIndEntity);
- DeleteIsland(pIslandLODsubComEntity);
+ if(FrontEndMenuManager.m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_HIGH) {
+ DeleteIsland(pIslandLODmainlandEntity);
+ DeleteIsland(pIslandLODbeachEntity);
} else
#endif
switch(level){
- case LEVEL_INDUSTRIAL:
- DeleteIsland(pIslandLODindustEntity);
- DeleteIsland(pIslandLODcomSubEntity);
- DeleteIsland(pIslandLODsubComEntity);
- break;
- case LEVEL_COMMERCIAL:
- DeleteIsland(pIslandLODcomIndEntity);
- DeleteIsland(pIslandLODcomSubEntity);
- DeleteIsland(pIslandLODsubIndEntity);
- break;
- case LEVEL_SUBURBAN:
- DeleteIsland(pIslandLODsubIndEntity);
- DeleteIsland(pIslandLODsubComEntity);
- DeleteIsland(pIslandLODcomIndEntity);
+ case LEVEL_MAINLAND:
+ DeleteIsland(pIslandLODmainlandEntity);
break;
- default:
- DeleteIsland(pIslandLODindustEntity);
- DeleteIsland(pIslandLODcomIndEntity);
- DeleteIsland(pIslandLODcomSubEntity);
- DeleteIsland(pIslandLODsubIndEntity);
- DeleteIsland(pIslandLODsubComEntity);
+ case LEVEL_BEACH:
+ DeleteIsland(pIslandLODbeachEntity);
+
break;
}
}
@@ -1146,8 +1343,7 @@ CStreaming::RemoveLoadedVehicle(void)
if(ms_lastVehicleDeleted == MAXVEHICLESLOADED)
ms_lastVehicleDeleted = 0;
id = ms_vehiclesLoaded[ms_lastVehicleDeleted];
- if(id != -1 &&
- (ms_aInfoForModel[id].m_flags & STREAMFLAGS_CANT_REMOVE) == 0 && CModelInfo::GetModelInfo(id)->GetNumRefs() == 0 &&
+ if(id != -1 && CanRemoveModel(id) && CModelInfo::GetModelInfo(id)->GetNumRefs() == 0 &&
ms_aInfoForModel[id].m_loadState == STREAMSTATE_LOADED)
goto found;
}
@@ -1156,31 +1352,43 @@ found:
RemoveModel(ms_vehiclesLoaded[ms_lastVehicleDeleted]);
ms_numVehiclesLoaded--;
ms_vehiclesLoaded[ms_lastVehicleDeleted] = -1;
+ CVehicleModelInfo* pVehicleInfo = (CVehicleModelInfo*)CModelInfo::GetModelInfo(id);
+ if (pVehicleInfo->m_vehicleClass != -1)
+ CCarCtrl::RemoveFromLoadedVehicleArray(id, pVehicleInfo->m_vehicleClass);
return true;
}
bool
-CStreaming::RemoveLeastUsedModel(void)
+CStreaming::RemoveLeastUsedModel(uint32 excludeMask)
{
CStreamingInfo *si;
int streamId;
for(si = ms_endLoadedList.m_prev; si != &ms_startLoadedList; si = si->m_prev){
+ if(si->m_flags & excludeMask)
+ continue;
streamId = si - ms_aInfoForModel;
if(streamId < STREAM_OFFSET_TXD){
if (CModelInfo::GetModelInfo(streamId)->GetNumRefs() == 0) {
RemoveModel(streamId);
return true;
}
- }else{
+ }else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL){
if(CTxdStore::GetNumRefs(streamId - STREAM_OFFSET_TXD) == 0 &&
!IsTxdUsedByRequestedModels(streamId - STREAM_OFFSET_TXD)){
RemoveModel(streamId);
return true;
}
+ }else if(streamId >= STREAM_OFFSET_ANIM){
+ assert(streamId < NUMSTREAMINFO);
+ if(CAnimManager::GetNumRefsToAnimBlock(streamId - STREAM_OFFSET_ANIM) == 0 &&
+ !AreAnimsUsedByRequestedModels(streamId - STREAM_OFFSET_ANIM)){
+ RemoveModel(streamId);
+ return true;
+ }
}
}
- return ms_numVehiclesLoaded > 7 && RemoveLoadedVehicle();
+ return (ms_numVehiclesLoaded > 7 || CGame::currArea != AREA_MAIN_MAP && ms_numVehiclesLoaded > 4) && RemoveLoadedVehicle();
}
void
@@ -1193,7 +1401,6 @@ CStreaming::RemoveAllUnusedModels(void)
for(i = NUM_DEFAULT_MODELS; i < MODELINFOSIZE; i++){
if(ms_aInfoForModel[i].m_loadState == STREAMSTATE_LOADED &&
- ms_aInfoForModel[i].m_flags & STREAMFLAGS_DONT_REMOVE &&
CModelInfo::GetModelInfo(i)->GetNumRefs() == 0) {
RemoveModel(i);
ms_aInfoForModel[i].m_loadState = STREAMSTATE_NOTLOADED;
@@ -1201,28 +1408,33 @@ CStreaming::RemoveAllUnusedModels(void)
}
}
+void
+CStreaming::RemoveUnusedModelsInLoadedList(void)
+{
+ // empty
+}
+
bool
-CStreaming::RemoveReferencedTxds(size_t mem)
+CStreaming::RemoveLoadedZoneModel(void)
{
- CStreamingInfo *si;
- int streamId;
+ int i;
- for(si = ms_endLoadedList.m_prev; si != &ms_startLoadedList; si = si->m_prev){
- streamId = si - ms_aInfoForModel;
- if(streamId >= STREAM_OFFSET_TXD &&
- CTxdStore::GetNumRefs(streamId-STREAM_OFFSET_TXD) == 0){
- RemoveModel(streamId);
- if(ms_memoryUsed < mem)
- return true;
+ if(ms_currentPedGrp == -1)
+ return false;
+
+ for(i = 0; i < NUMMODELSPERPEDGROUP; i++){
+ int mi = CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i];
+ if(mi != -1 && ms_bIsPedFromPedGroupLoaded[i] &&
+ HasModelLoaded(mi) && CanRemoveModel(mi) &&
+ CModelInfo::GetModelInfo(mi)->GetNumRefs() == 0){
+ RemoveModel(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i]);
+ ms_numPedsLoaded--;
+ ms_bIsPedFromPedGroupLoaded[i] = false;
+ return true;
}
}
- return false;
-}
-void
-CStreaming::RemoveUnusedModelsInLoadedList(void)
-{
- // empty
+ return false;
}
bool
@@ -1253,6 +1465,34 @@ CStreaming::IsTxdUsedByRequestedModels(int32 txdId)
return false;
}
+bool
+CStreaming::AreAnimsUsedByRequestedModels(int32 animId)
+{
+ CStreamingInfo *si;
+ int streamId;
+ int i;
+
+ for(si = ms_startRequestedList.m_next; si != &ms_endRequestedList; si = si->m_next){
+ streamId = si - ms_aInfoForModel;
+ if(streamId < STREAM_OFFSET_TXD &&
+ CModelInfo::GetModelInfo(streamId)->GetAnimFileIndex() == animId)
+ return true;
+ }
+
+ for(i = 0; i < 4; i++){
+ streamId = ms_channel[0].streamIds[i];
+ if(streamId != -1 && streamId < STREAM_OFFSET_TXD &&
+ CModelInfo::GetModelInfo(streamId)->GetAnimFileIndex() == animId)
+ return true;
+ streamId = ms_channel[1].streamIds[i];
+ if(streamId != -1 && streamId < STREAM_OFFSET_TXD &&
+ CModelInfo::GetModelInfo(streamId)->GetAnimFileIndex() == animId)
+ return true;
+ }
+
+ return false;
+}
+
int32
CStreaming::GetAvailableVehicleSlot(void)
{
@@ -1284,8 +1524,8 @@ CStreaming::AddToLoadedVehiclesList(int32 modelId)
// find vehicle we can remove
for(i = 0; i < MAXVEHICLESLOADED; i++){
id = ms_vehiclesLoaded[ms_lastVehicleDeleted];
- if(id != -1 &&
- (ms_aInfoForModel[id].m_flags & STREAMFLAGS_CANT_REMOVE) == 0 && CModelInfo::GetModelInfo(id)->GetNumRefs() == 0)
+ if(id != -1 && CanRemoveModel(id) &&
+ CModelInfo::GetModelInfo(id)->GetNumRefs() == 0)
goto found;
ms_lastVehicleDeleted++;
if(ms_lastVehicleDeleted == MAXVEHICLESLOADED)
@@ -1301,13 +1541,21 @@ found:
ms_lastVehicleDeleted = id;
// this is more than we wanted actually
ms_numVehiclesLoaded++;
- }else
+ }
+ else{
RemoveModel(id);
+ CVehicleModelInfo* pVehicleInfo = (CVehicleModelInfo*)CModelInfo::GetModelInfo(id);
+ if (pVehicleInfo->m_vehicleClass != -1)
+ CCarCtrl::RemoveFromLoadedVehicleArray(id, pVehicleInfo->m_vehicleClass);
+ }
}
ms_vehiclesLoaded[ms_lastVehicleDeleted++] = modelId;
if(ms_lastVehicleDeleted == MAXVEHICLESLOADED)
ms_lastVehicleDeleted = 0;
+ CVehicleModelInfo* pVehicleInfo = (CVehicleModelInfo*)CModelInfo::GetModelInfo(modelId);
+ if (pVehicleInfo->m_vehicleClass != -1)
+ CCarCtrl::AddToLoadedVehicleArray(modelId, pVehicleInfo->m_vehicleClass, pVehicleInfo->m_frequency);
return true;
}
@@ -1319,45 +1567,10 @@ CStreaming::IsObjectInCdImage(int32 id)
}
void
-CStreaming::HaveAllBigBuildingsLoaded(eLevelName level)
-{
- int i, n;
- CEntity *e;
-
- if(ms_hasLoadedLODs)
- return;
-
- if(level == LEVEL_INDUSTRIAL){
- if(ms_aInfoForModel[islandLODcomInd].m_loadState != STREAMSTATE_LOADED ||
- ms_aInfoForModel[islandLODsubInd].m_loadState != STREAMSTATE_LOADED)
- return;
- }else if(level == LEVEL_COMMERCIAL){
- if(ms_aInfoForModel[islandLODindust].m_loadState != STREAMSTATE_LOADED ||
- ms_aInfoForModel[islandLODsubCom].m_loadState != STREAMSTATE_LOADED)
- return;
- }else if(level == LEVEL_SUBURBAN){
- if(ms_aInfoForModel[islandLODindust].m_loadState != STREAMSTATE_LOADED ||
- ms_aInfoForModel[islandLODcomSub].m_loadState != STREAMSTATE_LOADED)
- return;
- }
-
- n = CPools::GetBuildingPool()->GetSize()-1;
- for(i = n; i >= 0; i--){
- e = CPools::GetBuildingPool()->GetSlot(i);
- if(e && e->bIsBIGBuilding && e->m_level == level &&
- ms_aInfoForModel[e->GetModelIndex()].m_loadState != STREAMSTATE_LOADED)
- return;
- }
-
- RemoveUnusedBigBuildings(level);
- ms_hasLoadedLODs = true;
-}
-
-void
CStreaming::SetModelIsDeletable(int32 id)
{
ms_aInfoForModel[id].m_flags &= ~STREAMFLAGS_DONT_REMOVE;
- if ((id >= STREAM_OFFSET_TXD || CModelInfo::GetModelInfo(id)->GetModelType() != MITYPE_VEHICLE) &&
+ if ((id >= STREAM_OFFSET_TXD && id < STREAM_OFFSET_COL || CModelInfo::GetModelInfo(id)->GetModelType() != MITYPE_VEHICLE) &&
(ms_aInfoForModel[id].m_flags & STREAMFLAGS_SCRIPTOWNED) == 0){
if(ms_aInfoForModel[id].m_loadState != STREAMSTATE_LOADED)
RemoveModel(id);
@@ -1394,17 +1607,19 @@ CStreaming::LoadInitialPeds(void)
}
void
-CStreaming::LoadInitialVehicles(void)
+CStreaming::LoadInitialWeapons(void)
{
- int id;
+ CStreaming::RequestModel(MI_NIGHTSTICK, STREAMFLAGS_DONT_REMOVE);
+ CStreaming::RequestModel(MI_MISSILE, STREAMFLAGS_DONT_REMOVE);
+}
+void
+CStreaming::LoadInitialVehicles(void)
+{
ms_numVehiclesLoaded = 0;
ms_lastVehicleDeleted = 0;
- if(CModelInfo::GetModelInfo("taxi", &id))
- RequestModel(id, STREAMFLAGS_DONT_REMOVE);
- if(CModelInfo::GetModelInfo("police", &id))
- RequestModel(id, STREAMFLAGS_DONT_REMOVE);
+ RequestModel(MI_POLICE, STREAMFLAGS_DONT_REMOVE);
}
void
@@ -1432,11 +1647,11 @@ CStreaming::StreamVehiclesAndPeds(void)
}
if(FindPlayerPed()->m_pWanted->AreFbiRequired()){
- RequestModel(MI_FBICAR, STREAMFLAGS_DONT_REMOVE);
+ RequestModel(MI_FBIRANCH, STREAMFLAGS_DONT_REMOVE);
RequestModel(MI_FBI, STREAMFLAGS_DONT_REMOVE);
}else{
- SetModelIsDeletable(MI_FBICAR);
- if(!HasModelLoaded(MI_FBICAR))
+ SetModelIsDeletable(MI_FBIRANCH);
+ if(!HasModelLoaded(MI_FBIRANCH))
SetModelIsDeletable(MI_FBI);
}
@@ -1456,34 +1671,86 @@ CStreaming::StreamVehiclesAndPeds(void)
else
SetModelIsDeletable(MI_CHOPPER);
+ if (FindPlayerPed()->m_pWanted->AreMiamiViceRequired()) {
+ SetModelIsDeletable(MI_VICE1);
+ SetModelIsDeletable(MI_VICE2);
+ SetModelIsDeletable(MI_VICE3);
+ SetModelIsDeletable(MI_VICE4);
+ SetModelIsDeletable(MI_VICE5);
+ SetModelIsDeletable(MI_VICE6);
+ SetModelIsDeletable(MI_VICE7);
+ SetModelIsDeletable(MI_VICE8);
+ RequestModel(MI_VICECHEE, STREAMFLAGS_DONT_REMOVE);
+ if(CPopulation::NumMiamiViceCops == 0)
+ switch (CCarCtrl::MiamiViceCycle) {
+ case 0:
+ RequestModel(MI_VICE1, STREAMFLAGS_DONT_REMOVE);
+ RequestModel(MI_VICE2, STREAMFLAGS_DONT_REMOVE);
+ break;
+ case 1:
+ RequestModel(MI_VICE3, STREAMFLAGS_DONT_REMOVE);
+ RequestModel(MI_VICE4, STREAMFLAGS_DONT_REMOVE);
+ break;
+ case 2:
+ RequestModel(MI_VICE5, STREAMFLAGS_DONT_REMOVE);
+ RequestModel(MI_VICE6, STREAMFLAGS_DONT_REMOVE);
+ break;
+ case 3:
+ RequestModel(MI_VICE7, STREAMFLAGS_DONT_REMOVE);
+ RequestModel(MI_VICE8, STREAMFLAGS_DONT_REMOVE);
+ break;
+ }
+ }
+ else {
+ SetModelIsDeletable(MI_VICECHEE);
+ SetModelIsDeletable(MI_VICE1);
+ SetModelIsDeletable(MI_VICE2);
+ SetModelIsDeletable(MI_VICE3);
+ SetModelIsDeletable(MI_VICE4);
+ SetModelIsDeletable(MI_VICE5);
+ SetModelIsDeletable(MI_VICE6);
+ SetModelIsDeletable(MI_VICE7);
+ SetModelIsDeletable(MI_VICE8);
+ }
+
if(timeBeforeNextLoad >= 0)
timeBeforeNextLoad--;
else if(ms_numVehiclesLoaded <= desiredNumVehiclesLoaded){
- for(i = 1; i <= 10; i++){
- model = CCarCtrl::ChooseCarModel(modelQualityClass);
- modelQualityClass++;
- if(modelQualityClass >= CCarCtrl::TOTAL_CUSTOM_CLASSES)
- modelQualityClass = 0;
-
- // check if we want to load this model
- if(ms_aInfoForModel[model].m_loadState == STREAMSTATE_NOTLOADED &&
- ((CVehicleModelInfo*)CModelInfo::GetModelInfo(model))->m_level & (1 << (CGame::currLevel-1)))
- break;
+ CZoneInfo zone;
+ CVector coors = FindPlayerCoors();
+ CTheZones::GetZoneInfoForTimeOfDay(&coors, &zone);
+ int32 maxReq = -1;
+ int32 mostRequestedRating = 0;
+ for(i = 0; i < CCarCtrl::TOTAL_CUSTOM_CLASSES; i++){
+ if(CCarCtrl::NumRequestsOfCarRating[i] > maxReq &&
+ ((i == 0 && zone.carThreshold[0] != 0) ||
+#ifdef FIX_BUGS
+ (i < CCarCtrl::NUM_CAR_CLASSES && zone.carThreshold[i] != zone.carThreshold[i-1]) ||
+ (i == CCarCtrl::NUM_CAR_CLASSES && zone.boatThreshold[i - CCarCtrl::NUM_CAR_CLASSES] != 0) ||
+ (i > CCarCtrl::NUM_CAR_CLASSES && i < CCarCtrl::TOTAL_CUSTOM_CLASSES && zone.boatThreshold[i - CCarCtrl::NUM_CAR_CLASSES] != zone.boatThreshold[i - CCarCtrl::NUM_CAR_CLASSES - 1]))) {
+#else
+ (i != 0 && zone.carThreshold[i] != zone.carThreshold[i-1]))) {
+#endif
+ maxReq = CCarCtrl::NumRequestsOfCarRating[i];
+ mostRequestedRating = i;
+ }
}
-
- if(i <= 10){
+ model = CCarCtrl::ChooseCarModelToLoad(mostRequestedRating);
+ if(!HasModelLoaded(model)){
RequestModel(model, STREAMFLAGS_DEPENDENCY);
- timeBeforeNextLoad = 500;
+ timeBeforeNextLoad = 350;
}
+ CCarCtrl::NumRequestsOfCarRating[mostRequestedRating] = 0;
}
}
void
CStreaming::StreamZoneModels(const CVector &pos)
{
- int i;
+ int i, j;
uint16 gangsToLoad, gangCarsToLoad, bit;
CZoneInfo info;
+ static int timeBeforeNextLoad = 0;
CTheZones::GetZoneInfoForTimeOfDay(&pos, &info);
@@ -1492,6 +1759,7 @@ CStreaming::StreamZoneModels(const CVector &pos)
// unload pevious group
if(ms_currentPedGrp != -1)
for(i = 0; i < NUMMODELSPERPEDGROUP; i++){
+ ms_bIsPedFromPedGroupLoaded[i] = false;
if(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i] != -1){
SetModelIsDeletable(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i]);
SetModelTxdIsDeletable(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i]);
@@ -1500,63 +1768,101 @@ CStreaming::StreamZoneModels(const CVector &pos)
ms_currentPedGrp = info.pedGroup;
- for(i = 0; i < NUMMODELSPERPEDGROUP; i++){
- if(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i] != -1)
- RequestModel(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i], STREAMFLAGS_DONT_REMOVE);
+ for(i = 0; i < MAXZONEPEDSLOADED; i++){
+ do
+ j = CGeneral::GetRandomNumberInRange(0, NUMMODELSPERPEDGROUP);
+ while(ms_bIsPedFromPedGroupLoaded[j]);
+ ms_bIsPedFromPedGroupLoaded[j] = true;
+ if(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[j] != -1)
+ RequestModel(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[j], STREAMFLAGS_DEPENDENCY);
}
+ ms_numPedsLoaded = MAXZONEPEDSLOADED;
+ timeBeforeNextLoad = 300;
}
+
+ if(timeBeforeNextLoad >= 0)
+ timeBeforeNextLoad--;
+ else{
+ // Switch a ped
+ int oldMI;
+ // Find a ped to unload
+ for(i = 0; i < NUMMODELSPERPEDGROUP; i++)
+ if(ms_bIsPedFromPedGroupLoaded[i]){
+ oldMI = CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i];
+ if(oldMI != -1 && CModelInfo::GetModelInfo(oldMI)->GetNumRefs() == 0)
+ break;
+ }
+ // And load a new one
+ if(i != NUMMODELSPERPEDGROUP || ms_numPedsLoaded < MAXZONEPEDSLOADED){
+ do
+ j = CGeneral::GetRandomNumberInRange(0, NUMMODELSPERPEDGROUP);
+ while(ms_bIsPedFromPedGroupLoaded[j]);
+ if(ms_numPedsLoaded == MAXZONEPEDSLOADED)
+ ms_bIsPedFromPedGroupLoaded[i] = false;
+ ms_bIsPedFromPedGroupLoaded[j] = true;
+ int newMI = CPopulation::ms_pPedGroups[ms_currentPedGrp].models[j];
+ if(newMI != oldMI){
+ RequestModel(newMI, STREAMFLAGS_DEPENDENCY);
+ debug("Request Ped %s\n", CModelInfo::GetModelInfo(newMI)->GetModelName());
+ if(ms_numPedsLoaded == MAXZONEPEDSLOADED){
+ SetModelIsDeletable(oldMI);
+ SetModelTxdIsDeletable(oldMI);
+ debug("Remove Ped %s\n", CModelInfo::GetModelInfo(oldMI)->GetModelName());
+ }else
+ ms_numPedsLoaded++;
+ timeBeforeNextLoad = 300;
+ }
+ }
+ }
+
RequestModel(MI_MALE01, STREAMFLAGS_DONT_REMOVE);
+ RequestModel(MI_TAXI_D, STREAMFLAGS_DONT_REMOVE);
gangsToLoad = 0;
gangCarsToLoad = 0;
- if(info.gangDensity[0] != 0) gangsToLoad |= 1<<0;
- if(info.gangDensity[1] != 0) gangsToLoad |= 1<<1;
- if(info.gangDensity[2] != 0) gangsToLoad |= 1<<2;
- if(info.gangDensity[3] != 0) gangsToLoad |= 1<<3;
- if(info.gangDensity[4] != 0) gangsToLoad |= 1<<4;
- if(info.gangDensity[5] != 0) gangsToLoad |= 1<<5;
- if(info.gangDensity[6] != 0) gangsToLoad |= 1<<6;
- if(info.gangDensity[7] != 0) gangsToLoad |= 1<<7;
- if(info.gangDensity[8] != 0) gangsToLoad |= 1<<8;
- if(info.gangThreshold[0] != info.copDensity) gangCarsToLoad |= 1<<0;
- if(info.gangThreshold[1] != info.gangThreshold[0]) gangCarsToLoad |= 1<<1;
- if(info.gangThreshold[2] != info.gangThreshold[1]) gangCarsToLoad |= 1<<2;
- if(info.gangThreshold[3] != info.gangThreshold[2]) gangCarsToLoad |= 1<<3;
- if(info.gangThreshold[4] != info.gangThreshold[3]) gangCarsToLoad |= 1<<4;
- if(info.gangThreshold[5] != info.gangThreshold[4]) gangCarsToLoad |= 1<<5;
- if(info.gangThreshold[6] != info.gangThreshold[5]) gangCarsToLoad |= 1<<6;
- if(info.gangThreshold[7] != info.gangThreshold[6]) gangCarsToLoad |= 1<<7;
- if(info.gangThreshold[8] != info.gangThreshold[7]) gangCarsToLoad |= 1<<8;
+ if(info.gangPedThreshold[0] != info.copPedThreshold)
+ gangsToLoad = 1;
+ for(i = 1; i < NUM_GANGS; i++)
+ if(info.gangPedThreshold[i] != info.gangPedThreshold[i-1])
+ gangsToLoad |= 1<<i;
+ if(info.gangThreshold[0] != info.copThreshold)
+ gangCarsToLoad = 1;
+ for(i = 1; i < NUM_GANGS; i++)
+ if(info.gangThreshold[i] != info.gangThreshold[i-1])
+ gangCarsToLoad |= 1<<i;
if(gangsToLoad == ms_loadedGangs && gangCarsToLoad == ms_loadedGangCars)
return;
- // This makes things simpler than the game does it
- gangsToLoad |= gangCarsToLoad;
-
- for(i = 0; i < NUM_GANGS; i++){
- bit = 1<<i;
-
- if(gangsToLoad & bit && (ms_loadedGangs & bit) == 0){
- RequestModel(MI_GANG01 + i*2, STREAMFLAGS_DONT_REMOVE);
- RequestModel(MI_GANG01 + i*2 + 1, STREAMFLAGS_DONT_REMOVE);
- ms_loadedGangs |= bit;
- }else if((gangsToLoad & bit) == 0 && ms_loadedGangs & bit){
- SetModelIsDeletable(MI_GANG01 + i*2);
- SetModelIsDeletable(MI_GANG01 + i*2 + 1);
- SetModelTxdIsDeletable(MI_GANG01 + i*2);
- SetModelTxdIsDeletable(MI_GANG01 + i*2 + 1);
- ms_loadedGangs &= ~bit;
- }
+ int gangModelsToload = gangsToLoad | gangCarsToLoad;
+
+ if(gangsToLoad != ms_loadedGangs || gangCarsToLoad != ms_loadedGangCars){
+ for(i = 0; i < NUM_GANGS; i++){
+ bit = 1<<i;
+
+ if(gangModelsToload & bit && (ms_loadedGangs & bit) == 0){
+ RequestModel(CGangs::GetGangPedModel1(i), STREAMFLAGS_DEPENDENCY);
+ RequestModel(CGangs::GetGangPedModel2(i), STREAMFLAGS_DEPENDENCY);
+ ms_loadedGangs |= bit;
+ }else if((gangModelsToload & bit) == 0 && ms_loadedGangs & bit){
+ SetModelIsDeletable(CGangs::GetGangPedModel1(i));
+ SetModelIsDeletable(CGangs::GetGangPedModel2(i));
+ SetModelTxdIsDeletable(CGangs::GetGangPedModel1(i));
+ SetModelTxdIsDeletable(CGangs::GetGangPedModel2(i));
+ ms_loadedGangs &= ~bit;
+ }
- if(gangCarsToLoad & bit && (ms_loadedGangCars & bit) == 0){
- RequestModel(CGangs::GetGangInfo(i)->m_nVehicleMI, STREAMFLAGS_DONT_REMOVE);
- }else if((gangCarsToLoad & bit) == 0 && ms_loadedGangCars & bit){
- SetModelIsDeletable(CGangs::GetGangInfo(i)->m_nVehicleMI);
- SetModelTxdIsDeletable(CGangs::GetGangInfo(i)->m_nVehicleMI);
+ if(CGangs::GetGangVehicleModel(i) != -1){
+ if((gangCarsToLoad & bit) && (ms_loadedGangCars & bit) == 0){
+ RequestModel(CGangs::GetGangVehicleModel(i), STREAMFLAGS_DEPENDENCY);
+ }else if((gangCarsToLoad & bit) == 0 && ms_loadedGangCars & bit){
+ SetModelIsDeletable(CGangs::GetGangVehicleModel(i));
+ SetModelTxdIsDeletable(CGangs::GetGangVehicleModel(i));
+ }
+ }
}
+ ms_loadedGangCars = gangCarsToLoad;
}
- ms_loadedGangCars = gangCarsToLoad;
}
void
@@ -1564,19 +1870,31 @@ CStreaming::RemoveCurrentZonesModels(void)
{
int i;
- if(ms_currentPedGrp != -1)
- for(i = 0; i < 8; i++){
- if(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i] == -1)
- break;
- if(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i] != MI_MALE01)
+ if (ms_currentPedGrp != -1)
+ for (i = 0; i < NUMMODELSPERPEDGROUP; i++) {
+ ms_bIsPedFromPedGroupLoaded[i] = false;
+ if (CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i] != -1) {
SetModelIsDeletable(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i]);
+ SetModelTxdIsDeletable(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i]);
+ }
}
- 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);
+ CStreaming::RequestModel(MI_MALE01, STREAMFLAGS_DONT_REMOVE);
+ CStreaming::RequestModel(MI_TAXI_D, STREAMFLAGS_DONT_REMOVE);
+
+ for (i = 0; i < NUM_GANGS; i++) {
+ if (CGangs::GetGangPedModel1(i) != -1) {
+ SetModelIsDeletable(CGangs::GetGangPedModel1(i));
+ SetModelTxdIsDeletable(CGangs::GetGangPedModel1(i));
+ }
+ if (CGangs::GetGangPedModel2(i) != -1) {
+ SetModelIsDeletable(CGangs::GetGangPedModel2(i));
+ SetModelTxdIsDeletable(CGangs::GetGangPedModel2(i));
+ }
+ if (CGangs::GetGangVehicleModel(i) != -1) {
+ SetModelIsDeletable(CGangs::GetGangVehicleModel(i));
+ SetModelTxdIsDeletable(CGangs::GetGangVehicleModel(i));
+ }
}
ms_currentPedGrp = -1;
@@ -1584,6 +1902,53 @@ CStreaming::RemoveCurrentZonesModels(void)
ms_loadedGangCars = 0;
}
+void
+CStreaming::LoadBigBuildingsWhenNeeded(void)
+{
+ // Very much like CCollision::Update and CCollision::LoadCollisionWhenINeedIt
+ if(CCutsceneMgr::IsCutsceneProcessing())
+ return;
+
+ if(CTheZones::m_CurrLevel == LEVEL_GENERIC ||
+ CTheZones::m_CurrLevel == CGame::currLevel)
+ return;
+
+ CTimer::Suspend();
+ CGame::currLevel = CTheZones::m_CurrLevel;
+ ISLAND_LOADING_IS(LOW)
+ {
+ DMAudio.SetEffectsFadeVol(0);
+ CPad::StopPadsShaking();
+ CCollision::LoadCollisionScreen(CGame::currLevel);
+ DMAudio.Service();
+
+ RemoveUnusedBigBuildings(CGame::currLevel);
+ RemoveUnusedBuildings(CGame::currLevel);
+ RemoveUnusedModelsInLoadedList();
+ CGame::TidyUpMemory(true, true);
+ }
+ CReplay::EmptyReplayBuffer();
+ if(CGame::currLevel != LEVEL_GENERIC)
+ LoadSplash(GetLevelSplashScreen(CGame::currLevel));
+
+ ISLAND_LOADING_IS(LOW)
+ CStreaming::RequestBigBuildings(CGame::currLevel, TheCamera.GetPosition());
+#ifdef NO_ISLAND_LOADING
+ else if(FrontEndMenuManager.m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_MEDIUM) {
+ RemoveIslandsNotUsed(CGame::currLevel);
+ CStreaming::RequestIslands(CGame::currLevel);
+ }
+#endif
+
+ CStreaming::LoadAllRequestedModels(false);
+
+ CGame::TidyUpMemory(true, true);
+ CTimer::Resume();
+
+ ISLAND_LOADING_IS(LOW)
+ DMAudio.SetEffectsFadeVol(127);
+}
+
// Find starting offset of the cdimage we next want to read
// Not useful at all on PC...
@@ -1630,6 +1995,7 @@ ModelNotLoaded(int32 modelId)
}
inline bool TxdNotLoaded(int32 txdId) { return ModelNotLoaded(txdId + STREAM_OFFSET_TXD); }
+inline bool AnimNotLoaded(int32 animId) { return animId != -1 && ModelNotLoaded(animId + STREAM_OFFSET_ANIM); }
// Find stream id of next requested file in cdimage
int32
@@ -1654,14 +2020,20 @@ CStreaming::GetNextFileOnCd(int32 lastPosn, bool priority)
if(priority && ms_numPriorityRequests != 0 && !si->IsPriority())
continue;
- // request Txd if necessary
+ // request Txds or anims if necessary
if(streamId < STREAM_OFFSET_TXD){
int txdId = CModelInfo::GetModelInfo(streamId)->GetTxdSlot();
if(TxdNotLoaded(txdId)){
ReRequestTxd(txdId);
continue;
}
- }
+ int animId = CModelInfo::GetModelInfo(streamId)->GetAnimFileIndex();
+ if(AnimNotLoaded(animId)){
+ ReRequestAnim(animId);
+ continue;
+ }
+ }else if(streamId >= STREAM_OFFSET_ANIM && CCutsceneMgr::IsCutsceneProcessing())
+ continue;
if(ms_aInfoForModel[streamId].GetCdPosnAndSize(posn, size)){
if(posn < posnFirst){
@@ -1716,13 +2088,18 @@ CStreaming::RequestModelStream(int32 ch)
imgOffset = GetCdImageOffset(lastPosn);
streamId = GetNextFileOnCd(lastPosn - imgOffset, true);
- if(streamId == -1)
- return;
-
- // remove Txds that aren't requested anymore
- while(streamId >= STREAM_OFFSET_TXD){
- if(ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_KEEP_IN_MEMORY ||
- IsTxdUsedByRequestedModels(streamId - STREAM_OFFSET_TXD))
+ // remove Txds and Anims that aren't requested anymore
+ while(streamId != -1){
+ if(ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_KEEP_IN_MEMORY)
+ break;
+ if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL){
+ if(IsTxdUsedByRequestedModels(streamId - STREAM_OFFSET_TXD))
+ break;
+ }else if(streamId >= STREAM_OFFSET_ANIM){
+ assert(streamId < NUMSTREAMINFO);
+ if(AreAnimsUsedByRequestedModels(streamId - STREAM_OFFSET_ANIM))
+ break;
+ }else
break;
RemoveModel(streamId);
// so try next file
@@ -1759,7 +2136,8 @@ CStreaming::RequestModelStream(int32 ch)
if(streamId < STREAM_OFFSET_TXD){
if (havePed && CModelInfo::GetModelInfo(streamId)->GetModelType() == MITYPE_PED ||
haveBigFile && CModelInfo::GetModelInfo(streamId)->GetModelType() == MITYPE_VEHICLE ||
- TxdNotLoaded(CModelInfo::GetModelInfo(streamId)->GetTxdSlot()))
+ TxdNotLoaded(CModelInfo::GetModelInfo(streamId)->GetTxdSlot()) ||
+ AnimNotLoaded(CModelInfo::GetModelInfo(streamId)->GetAnimFileIndex()))
break;
}else{
if(haveBigFile && size > 200)
@@ -1840,10 +2218,10 @@ CStreaming::ProcessLoadingChannel(int32 ch)
if(id < STREAM_OFFSET_TXD && CModelInfo::GetModelInfo(id)->GetModelType() == MITYPE_VEHICLE &&
ms_numVehiclesLoaded >= desiredNumVehiclesLoaded &&
!RemoveLoadedVehicle() &&
- ((ms_aInfoForModel[id].m_flags & STREAMFLAGS_CANT_REMOVE) == 0 || GetAvailableVehicleSlot() == -1)){
+ (CanRemoveModel(id) || GetAvailableVehicleSlot() == -1)){
// can't load vehicle
RemoveModel(id);
- if(ms_aInfoForModel[id].m_flags & STREAMFLAGS_CANT_REMOVE)
+ if(!CanRemoveModel(id))
ReRequestModel(id);
else if(CTxdStore::GetNumRefs(CModelInfo::GetModelInfo(id)->GetTxdSlot()) == 0)
RemoveTxd(CModelInfo::GetModelInfo(id)->GetTxdSlot());
@@ -1950,6 +2328,7 @@ CStreaming::LoadAllRequestedModels(bool priority)
if(bInsideLoadAll)
return;
+ bInsideLoadAll = true;
FlushChannels();
imgOffset = GetCdImageOffset(CdStreamGetLastPosn());
@@ -2072,18 +2451,26 @@ CStreaming::LoadAllRequestedModels(bool priority)
int i;
uint32 posn, size;
+ int numRequests = 4*ms_numModelsRequested;
+
if(bInsideLoadAll)
return;
+ bInsideLoadAll = true;
+
+ if(priority)
+ numRequests = ms_numPriorityRequests;
FlushChannels();
imgOffset = GetCdImageOffset(CdStreamGetLastPosn());
- while(ms_endRequestedList.m_prev != &ms_startRequestedList){
+ while(ms_endRequestedList.m_prev != &ms_startRequestedList && numRequests > 0){
+ numRequests--;
streamId = GetNextFileOnCd(0, priority);
if(streamId == -1)
break;
ms_aInfoForModel[streamId].RemoveFromList();
+ ms_channel[0].streamIds[0] = streamId;
DecrementRef(streamId);
if(ms_aInfoForModel[streamId].GetCdPosnAndSize(posn, size)){
@@ -2180,14 +2567,16 @@ CStreaming::UpdateMemoryUsed(void)
ms_memoryUsed =
gMainHeap.GetMemoryUsed(MEMID_STREAM) +
gMainHeap.GetMemoryUsed(MEMID_STREAM_MODELS) +
- gMainHeap.GetMemoryUsed(MEMID_STREAM_TEXUTRES);
+ gMainHeap.GetMemoryUsed(MEMID_STREAM_TEXUTRES) +
+ gMainHeap.GetMemoryUsed(MEMID_STREAM_COLLISION) +
+ gMainHeap.GetMemoryUsed(MEMID_STREAM_ANIMATION);
#endif
}
#define STREAM_DIST 80.0f
void
-CStreaming::AddModelsToRequestList(const CVector &pos)
+CStreaming::AddModelsToRequestList(const CVector &pos, int32 flags)
{
float xmin, xmax, ymin, ymax;
int ixmin, ixmax, iymin, iymax;
@@ -2221,23 +2610,23 @@ CStreaming::AddModelsToRequestList(const CVector &pos)
dx = ix - CWorld::GetSectorIndexX(pos.x);
d = dx*dx + dy*dy;
sect = CWorld::GetSector(ix, iy);
- if(d <= 1){
- ProcessEntitiesInSectorList(sect->m_lists[ENTITYLIST_BUILDINGS]);
- ProcessEntitiesInSectorList(sect->m_lists[ENTITYLIST_BUILDINGS_OVERLAP]);
- ProcessEntitiesInSectorList(sect->m_lists[ENTITYLIST_OBJECTS]);
- ProcessEntitiesInSectorList(sect->m_lists[ENTITYLIST_DUMMIES]);
- }else if(d <= 4*4){
- ProcessEntitiesInSectorList(sect->m_lists[ENTITYLIST_BUILDINGS], pos.x, pos.y, xmin, ymin, xmax, ymax);
- ProcessEntitiesInSectorList(sect->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], pos.x, pos.y, xmin, ymin, xmax, ymax);
- ProcessEntitiesInSectorList(sect->m_lists[ENTITYLIST_OBJECTS], pos.x, pos.y, xmin, ymin, xmax, ymax);
- ProcessEntitiesInSectorList(sect->m_lists[ENTITYLIST_DUMMIES], pos.x, pos.y, xmin, ymin, xmax, ymax);
+ if(d <= 0){
+ ProcessEntitiesInSectorList(sect->m_lists[ENTITYLIST_BUILDINGS], flags);
+ ProcessEntitiesInSectorList(sect->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], flags);
+ ProcessEntitiesInSectorList(sect->m_lists[ENTITYLIST_OBJECTS], flags);
+ ProcessEntitiesInSectorList(sect->m_lists[ENTITYLIST_DUMMIES], flags);
+ }else if(d <= 3*3){
+ ProcessEntitiesInSectorList(sect->m_lists[ENTITYLIST_BUILDINGS], pos.x, pos.y, xmin, ymin, xmax, ymax, flags);
+ ProcessEntitiesInSectorList(sect->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], pos.x, pos.y, xmin, ymin, xmax, ymax, flags);
+ ProcessEntitiesInSectorList(sect->m_lists[ENTITYLIST_OBJECTS], pos.x, pos.y, xmin, ymin, xmax, ymax, flags);
+ ProcessEntitiesInSectorList(sect->m_lists[ENTITYLIST_DUMMIES], pos.x, pos.y, xmin, ymin, xmax, ymax, flags);
}
}
}
}
void
-CStreaming::ProcessEntitiesInSectorList(CPtrList &list, float x, float y, float xmin, float ymin, float xmax, float ymax)
+CStreaming::ProcessEntitiesInSectorList(CPtrList &list, float x, float y, float xmin, float ymin, float xmax, float ymax, int32 flags)
{
CPtrNode *node;
CEntity *e;
@@ -2251,8 +2640,7 @@ CStreaming::ProcessEntitiesInSectorList(CPtrList &list, float x, float y, float
continue;
e->m_scanCode = CWorld::GetCurrentScanCode();
- if(!e->bStreamingDontDelete && !e->bIsSubway &&
- (!e->IsObject() || ((CObject*)e)->ObjectCreatedBy != TEMP_OBJECT)){
+ if(!e->bStreamingDontDelete && IsAreaVisible(e->m_area) && !e->bDontStream && e->bIsVisible){
CTimeModelInfo *mi = (CTimeModelInfo*)CModelInfo::GetModelInfo(e->GetModelIndex());
if (mi->GetModelType() != MITYPE_TIME || CClock::GetIsTimeInRange(mi->GetTimeOn(), mi->GetTimeOff())) {
lodDistSq = sq(mi->GetLargestLodDistance());
@@ -2261,15 +2649,14 @@ CStreaming::ProcessEntitiesInSectorList(CPtrList &list, float x, float y, float
if(xmin < pos.x && pos.x < xmax &&
ymin < pos.y && pos.y < ymax &&
(CVector2D(x, y) - pos).MagnitudeSqr() < lodDistSq)
- if(CRenderer::IsEntityCullZoneVisible(e))
- RequestModel(e->GetModelIndex(), 0);
+ RequestModel(e->GetModelIndex(), flags);
}
}
}
}
void
-CStreaming::ProcessEntitiesInSectorList(CPtrList &list)
+CStreaming::ProcessEntitiesInSectorList(CPtrList &list, int32 flags)
{
CPtrNode *node;
CEntity *e;
@@ -2281,12 +2668,10 @@ CStreaming::ProcessEntitiesInSectorList(CPtrList &list)
continue;
e->m_scanCode = CWorld::GetCurrentScanCode();
- if(!e->bStreamingDontDelete && !e->bIsSubway &&
- (!e->IsObject() || ((CObject*)e)->ObjectCreatedBy != TEMP_OBJECT)){
+ if(!e->bStreamingDontDelete && IsAreaVisible(e->m_area) && !e->bDontStream && e->bIsVisible){
CTimeModelInfo *mi = (CTimeModelInfo*)CModelInfo::GetModelInfo(e->GetModelIndex());
if (mi->GetModelType() != MITYPE_TIME || CClock::GetIsTimeInRange(mi->GetTimeOn(), mi->GetTimeOff()))
- if(CRenderer::IsEntityCullZoneVisible(e))
- RequestModel(e->GetModelIndex(), 0);
+ RequestModel(e->GetModelIndex(), flags);
}
}
}
@@ -2502,6 +2887,11 @@ CStreaming::DeleteRwObjectsBehindCamera(size_t mem)
}
}
+
+ while(RemoveLoadedZoneModel())
+ if(ms_memoryUsed < mem)
+ return;
+
// Now a block that intersects with the camera's frustum
if(TheCamera.GetForward().x > 0.0f){
// looking east
@@ -2524,9 +2914,6 @@ CStreaming::DeleteRwObjectsBehindCamera(size_t mem)
}
}
- if(RemoveReferencedTxds(mem))
- return;
-
// As last resort, delete objects from the last step more aggressively
for(y = ymin; y <= ymax; y++){
for(x = xmax; x != xmin; x -= inc){
@@ -2566,6 +2953,10 @@ CStreaming::DeleteRwObjectsBehindCamera(size_t mem)
}
}
+ while(RemoveLoadedZoneModel())
+ if(ms_memoryUsed < mem)
+ return;
+
// Now a block that intersects with the camera's frustum
if(TheCamera.GetForward().y > 0.0f){
// looking north
@@ -2588,8 +2979,9 @@ CStreaming::DeleteRwObjectsBehindCamera(size_t mem)
}
}
- if(RemoveReferencedTxds(mem))
- return;
+// this is gone in mobile together with RemoveReferencedTxds
+// if(RemoveReferencedTxds(mem))
+// return;
// As last resort, delete objects from the last step more aggressively
for(x = xmin; x <= xmax; x++){
@@ -2602,6 +2994,8 @@ CStreaming::DeleteRwObjectsBehindCamera(size_t mem)
}
}
}
+
+ while(ms_memoryUsed >= mem && RemoveLeastUsedModel(0));
}
void
@@ -2627,13 +3021,13 @@ CStreaming::DeleteRwObjectsInOverlapSectorList(CPtrList &list, int32 x, int32 y)
e = (CEntity*)node->item;
if(e->m_rwObject && !e->bStreamingDontDelete && !e->bImBeingRendered){
// Now this is pretty weird...
- if(Abs(CWorld::GetSectorIndexX(e->GetPosition().x) - x) >= 2.0f)
+ if(Abs(CWorld::GetSectorIndexX(e->GetPosition().x) - x) >= 1.6f)
// {
e->DeleteRwObject();
// return; // BUG?
// }
else // FIX?
- if(Abs(CWorld::GetSectorIndexY(e->GetPosition().y) - y) >= 2.0f)
+ if(Abs(CWorld::GetSectorIndexY(e->GetPosition().y) - y) >= 1.6f)
e->DeleteRwObject();
}
}
@@ -2648,7 +3042,8 @@ CStreaming::DeleteRwObjectsBehindCameraInSectorList(CPtrList &list, size_t mem)
for(node = list.first; node; node = node->next){
e = (CEntity*)node->item;
if(!e->bStreamingDontDelete && !e->bImBeingRendered &&
- e->m_rwObject && ms_aInfoForModel[e->GetModelIndex()].m_next){
+ e->m_rwObject && ms_aInfoForModel[e->GetModelIndex()].m_next &&
+ FindPlayerPed()->m_pCurSurface != e){
e->DeleteRwObject();
if (CModelInfo::GetModelInfo(e->GetModelIndex())->GetNumRefs() == 0) {
RemoveModel(e->GetModelIndex());
@@ -2669,7 +3064,7 @@ CStreaming::DeleteRwObjectsNotInFrustumInSectorList(CPtrList &list, size_t mem)
for(node = list.first; node; node = node->next){
e = (CEntity*)node->item;
if(!e->bStreamingDontDelete && !e->bImBeingRendered &&
- e->m_rwObject && !e->IsVisible() && ms_aInfoForModel[e->GetModelIndex()].m_next){
+ e->m_rwObject && (!e->IsVisible() || e->bOffscreen) && ms_aInfoForModel[e->GetModelIndex()].m_next){
e->DeleteRwObject();
if (CModelInfo::GetModelInfo(e->GetModelIndex())->GetNumRefs() == 0) {
RemoveModel(e->GetModelIndex());
@@ -2689,12 +3084,12 @@ CStreaming::MakeSpaceFor(int32 size)
if(ms_memoryAvailable == 0) {
extern size_t _dwMemAvailPhys;
ms_memoryAvailable = (_dwMemAvailPhys - 10 * MB) / 2;
- if(ms_memoryAvailable < 50 * MB) ms_memoryAvailable = 50 * MB;
+ if(ms_memoryAvailable < 65 * MB) ms_memoryAvailable = 65 * MB;
}
#undef MB
#endif
while(ms_memoryUsed >= ms_memoryAvailable - size)
- if(!RemoveLeastUsedModel()) {
+ if(!RemoveLeastUsedModel(STREAMFLAGS_20)){
DeleteRwObjectsBehindCamera(ms_memoryAvailable - size);
return;
}
@@ -2714,17 +3109,44 @@ CStreaming::LoadScene(const CVector &pos)
RemoveModel(si - ms_aInfoForModel);
}
CRenderer::m_loadingPriority = false;
- CCullZones::ForceCullZoneCoors(pos);
DeleteAllRwObjects();
- AddModelsToRequestList(pos);
- CRadar::StreamRadarSections(pos);
+ if(level == LEVEL_GENERIC)
+ level = CGame::currLevel;
+ CGame::currLevel = level;
RemoveUnusedBigBuildings(level);
- RequestBigBuildings(level);
+ RequestBigBuildings(level, pos);
+ RequestBigBuildings(LEVEL_GENERIC, pos);
+ RemoveIslandsNotUsed(level);
+ LoadAllRequestedModels(false);
+ InstanceBigBuildings(level, pos);
+ InstanceBigBuildings(LEVEL_GENERIC, pos);
+ AddModelsToRequestList(pos, STREAMFLAGS_20);
+ CRadar::StreamRadarSections(pos);
+
+ if (!CGame::IsInInterior()) {
+ for (int i = 0; i < 5; i++) {
+ CZoneInfo zone;
+ CTheZones::GetZoneInfoForTimeOfDay(&pos, &zone);
+ int32 model = CCarCtrl::ChooseCarModelToLoad(CCarCtrl::ChooseCarRating(&zone));
+ CStreaming::RequestModel(model, STREAMFLAGS_DEPENDENCY);
+ }
+ }
LoadAllRequestedModels(false);
+ InstanceLoadedModels(pos);
+
+ for(int i = 0; i < NUMSTREAMINFO; i++)
+ ms_aInfoForModel[i].m_flags &= ~STREAMFLAGS_20;
debug("End load scene\n");
}
void
+CStreaming::LoadSceneCollision(const CVector &pos)
+{
+ CColStore::LoadCollision(pos);
+ CStreaming::LoadAllRequestedModels(false);
+}
+
+void
CStreaming::MemoryCardSave(uint8 *buf, uint32 *size)
{
int i;
@@ -2753,9 +3175,10 @@ void
CStreaming::UpdateForAnimViewer(void)
{
if (CStreaming::ms_channelError == -1) {
- CStreaming::AddModelsToRequestList(CVector(0.0f, 0.0f, 0.0f));
+ CStreaming::AddModelsToRequestList(CVector(0.0f, 0.0f, 0.0f), 0);
CStreaming::LoadRequestedModels();
- sprintf(gString, "Requested %d, memory size %zuK\n", CStreaming::ms_numModelsRequested, 2 * CStreaming::ms_memoryUsed); // original modifier was %d
+ // original modifier was %d
+ sprintf(gString, "Requested %d, memory size %zuK\n", CStreaming::ms_numModelsRequested, 2 * CStreaming::ms_memoryUsed);
}
else {
CStreaming::RetryLoadFile(CStreaming::ms_channelError);
diff --git a/src/core/Streaming.h b/src/core/Streaming.h
index 3294a88e..4ddf0b3b 100644
--- a/src/core/Streaming.h
+++ b/src/core/Streaming.h
@@ -4,7 +4,9 @@
enum {
STREAM_OFFSET_TXD = MODELINFOSIZE,
- NUMSTREAMINFO = STREAM_OFFSET_TXD+TXDSTORESIZE
+ STREAM_OFFSET_COL = STREAM_OFFSET_TXD+TXDSTORESIZE,
+ STREAM_OFFSET_ANIM = STREAM_OFFSET_COL+COLSTORESIZE,
+ NUMSTREAMINFO = STREAM_OFFSET_ANIM+NUMANIMBLOCKS
};
enum StreamFlags
@@ -14,6 +16,7 @@ enum StreamFlags
STREAMFLAGS_DEPENDENCY = 0x04, // Is this right?
STREAMFLAGS_PRIORITY = 0x08,
STREAMFLAGS_NOFADE = 0x10,
+ STREAMFLAGS_20 = 0x20, // TODO(MIAMI): what's this
STREAMFLAGS_CANT_REMOVE = STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_SCRIPTOWNED,
STREAMFLAGS_KEEP_IN_MEMORY = STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_SCRIPTOWNED|STREAMFLAGS_DEPENDENCY,
@@ -94,11 +97,12 @@ public:
static CStreamingChannel ms_channel[2];
static int32 ms_channelError;
static int32 ms_numVehiclesLoaded;
+ static int32 ms_numPedsLoaded;
static int32 ms_vehiclesLoaded[MAXVEHICLESLOADED];
static int32 ms_lastVehicleDeleted;
+ static bool ms_bIsPedFromPedGroupLoaded[NUMMODELSPERPEDGROUP];
static CDirectory *ms_pExtraObjectsDir;
static int32 ms_numPriorityRequests;
- static bool ms_hasLoadedLODs;
static int32 ms_currentPedGrp;
static int32 ms_lastCullZone;
static uint16 ms_loadedGangs;
@@ -111,6 +115,7 @@ public:
static void Init(void);
static void Init2(void);
+ static void ReInit(void);
static void Shutdown(void);
static void Update(void);
static void LoadCdDirectory(void);
@@ -119,14 +124,25 @@ public:
static bool FinishLoadingLargeFile(int8 *buf, int32 streamId);
static bool HasModelLoaded(int32 id) { return ms_aInfoForModel[id].m_loadState == STREAMSTATE_LOADED; }
static bool HasTxdLoaded(int32 id) { return HasModelLoaded(id+STREAM_OFFSET_TXD); }
+ static bool HasColLoaded(int32 id) { return HasModelLoaded(id+STREAM_OFFSET_COL); }
+ static bool HasAnimLoaded(int32 id) { return HasModelLoaded(id+STREAM_OFFSET_ANIM); }
static bool CanRemoveModel(int32 id) { return (ms_aInfoForModel[id].m_flags & STREAMFLAGS_CANT_REMOVE) == 0; }
static bool CanRemoveTxd(int32 id) { return CanRemoveModel(id+STREAM_OFFSET_TXD); }
+ static bool CanRemoveCol(int32 id) { return CanRemoveModel(id+STREAM_OFFSET_COL); }
+ static bool CanRemoveAnim(int32 id) { return CanRemoveModel(id+STREAM_OFFSET_ANIM); }
static void RequestModel(int32 model, int32 flags);
static void ReRequestModel(int32 model) { RequestModel(model, ms_aInfoForModel[model].m_flags); }
static void RequestTxd(int32 txd, int32 flags) { RequestModel(txd + STREAM_OFFSET_TXD, flags); }
static void ReRequestTxd(int32 txd) { ReRequestModel(txd + STREAM_OFFSET_TXD); }
- static void RequestSubway(void);
+ static void RequestCol(int32 col, int32 flags) { RequestModel(col + STREAM_OFFSET_COL, flags); }
+ static void ReRequestCol(int32 col) { ReRequestModel(col + STREAM_OFFSET_COL); }
+ static void RequestAnim(int32 col, int32 flags) { RequestModel(col + STREAM_OFFSET_ANIM, flags); }
+ static void ReRequestAnim(int32 col) { ReRequestModel(col + STREAM_OFFSET_ANIM); }
static void RequestBigBuildings(eLevelName level);
+ static void RequestBigBuildings(eLevelName level, const CVector &pos);
+ static void InstanceBigBuildings(eLevelName level, const CVector &pos);
+ static void InstanceLoadedModelsInSectorList(CPtrList &list);
+ static void InstanceLoadedModels(const CVector &pos);
static void RequestIslands(eLevelName level);
static void RequestSpecialModel(int32 modelId, const char *modelName, int32 flags);
static void RequestSpecialChar(int32 charId, const char *modelName, int32 flags);
@@ -135,29 +151,34 @@ public:
static void DecrementRef(int32 id);
static void RemoveModel(int32 id);
static void RemoveTxd(int32 id) { RemoveModel(id + STREAM_OFFSET_TXD); }
+ static void RemoveCol(int32 id) { RemoveModel(id + STREAM_OFFSET_COL); }
+ static void RemoveAnim(int32 id) { RemoveModel(id + STREAM_OFFSET_ANIM); }
static void RemoveUnusedBuildings(eLevelName level);
static void RemoveBuildings(eLevelName level);
+ static void RemoveBuildingsNotInArea(int32 area);
static void RemoveUnusedBigBuildings(eLevelName level);
static void RemoveIslandsNotUsed(eLevelName level);
static void RemoveBigBuildings(eLevelName level);
static bool RemoveLoadedVehicle(void);
- static bool RemoveLeastUsedModel(void);
+ static bool RemoveLeastUsedModel(uint32 excludeMask);
static void RemoveAllUnusedModels(void);
static void RemoveUnusedModelsInLoadedList(void);
- static bool RemoveReferencedTxds(size_t mem); // originally signed
+ static bool RemoveLoadedZoneModel(void);
static int32 GetAvailableVehicleSlot(void);
static bool IsTxdUsedByRequestedModels(int32 txdId);
+ static bool AreAnimsUsedByRequestedModels(int32 animId);
static bool AddToLoadedVehiclesList(int32 modelId);
static bool IsObjectInCdImage(int32 id);
- static void HaveAllBigBuildingsLoaded(eLevelName level);
static void SetModelIsDeletable(int32 id);
static void SetModelTxdIsDeletable(int32 id);
static void SetMissionDoesntRequireModel(int32 id);
static void LoadInitialPeds(void);
+ static void LoadInitialWeapons(void);
static void LoadInitialVehicles(void);
static void StreamVehiclesAndPeds(void);
static void StreamZoneModels(const CVector &pos);
static void RemoveCurrentZonesModels(void);
+ static void LoadBigBuildingsWhenNeeded(void);
static int32 GetCdImageOffset(int32 lastPosn);
static int32 GetNextFileOnCd(int32 position, bool priority);
@@ -174,9 +195,9 @@ public:
static void IHaveUsedStreamingMemory(void);
static void UpdateMemoryUsed(void);
- static void AddModelsToRequestList(const CVector &pos);
- static void ProcessEntitiesInSectorList(CPtrList &list, float x, float y, float xmin, float ymin, float xmax, float ymax);
- static void ProcessEntitiesInSectorList(CPtrList &list);
+ static void AddModelsToRequestList(const CVector &pos, int32 flags);
+ static void ProcessEntitiesInSectorList(CPtrList &list, float x, float y, float xmin, float ymin, float xmax, float ymax, int32 flags);
+ static void ProcessEntitiesInSectorList(CPtrList &list, int32 flags);
static void DeleteFarAwayRwObjects(const CVector &pos);
static void DeleteAllRwObjects(void);
static void DeleteRwObjectsAfterDeath(const CVector &pos);
@@ -187,6 +208,7 @@ public:
static bool DeleteRwObjectsNotInFrustumInSectorList(CPtrList &list, size_t mem); // originally signed
static void LoadScene(const CVector &pos);
+ static void LoadSceneCollision(const CVector &pos);
static void MemoryCardSave(uint8 *buffer, uint32 *length);
static void MemoryCardLoad(uint8 *buffer, uint32 length);
diff --git a/src/core/SurfaceTable.cpp b/src/core/SurfaceTable.cpp
index b1bcceb6..c4b184bf 100644
--- a/src/core/SurfaceTable.cpp
+++ b/src/core/SurfaceTable.cpp
@@ -74,7 +74,7 @@ CSurfaceTable::GetAdhesionGroup(uint8 surfaceType)
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_LOOSE;
+ 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;
@@ -89,6 +89,8 @@ CSurfaceTable::GetAdhesionGroup(uint8 surfaceType)
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;
}
}
@@ -108,6 +110,7 @@ CSurfaceTable::GetWetMultiplier(uint8 surfaceType)
case SURFACE_HEDGE:
case SURFACE_CARDBOARDBOX:
case SURFACE_TRANSPARENT_STONE:
+ case SURFACE_CONCRETE_BEACH:
return 1.0f - CWeather::WetRoads*0.25f;
case SURFACE_GRASS:
@@ -131,6 +134,10 @@ CSurfaceTable::GetWetMultiplier(uint8 surfaceType)
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;
}
@@ -141,3 +148,9 @@ CSurfaceTable::GetAdhesiveLimit(CColPoint &colpoint)
{
return ms_aAdhesiveLimitTable[GetAdhesionGroup(colpoint.surfaceB)][GetAdhesionGroup(colpoint.surfaceA)];
}
+
+bool
+CSurfaceTable::IsSoftLanding(uint8 surf)
+{
+ return surf == SURFACE_GRASS || surf == SURFACE_SAND || surf == SURFACE_SAND_BEACH;
+}
diff --git a/src/core/SurfaceTable.h b/src/core/SurfaceTable.h
index 8ee1724e..8ff43106 100644
--- a/src/core/SurfaceTable.h
+++ b/src/core/SurfaceTable.h
@@ -35,8 +35,6 @@ enum eSurfaceType
SURFACE_CARDBOARDBOX,
SURFACE_TRANSPARENT_STONE,
SURFACE_METAL_GATE,
-
- // These are illegal
SURFACE_SAND_BEACH,
SURFACE_CONCRETE_BEACH,
};
@@ -47,6 +45,7 @@ enum
ADHESIVE_HARD,
ADHESIVE_ROAD,
ADHESIVE_LOOSE,
+ ADHESIVE_SAND,
ADHESIVE_WET,
NUMADHESIVEGROUPS
@@ -60,11 +59,32 @@ IsSeeThrough(uint8 surfType)
switch(surfType)
case SURFACE_GLASS:
case SURFACE_TRANSPARENT_CLOTH:
-#if defined(FIX_BUGS) || defined(GTA_PS2)
case SURFACE_METAL_CHAIN_FENCE:
case SURFACE_TRANSPARENT_STONE:
case SURFACE_SCAFFOLD_POLE:
-#endif
+ return true;
+ return false;
+}
+
+// I think the necessity of this function is really a bug
+inline bool
+IsSeeThroughVertical(uint8 surfType)
+{
+ switch(surfType)
+ case SURFACE_GLASS:
+ case SURFACE_TRANSPARENT_CLOTH:
+ return true;
+ return false;
+}
+
+inline bool
+IsShootThrough(uint8 surfType)
+{
+ switch(surfType)
+ case SURFACE_TRANSPARENT_CLOTH:
+ case SURFACE_METAL_CHAIN_FENCE:
+ case SURFACE_TRANSPARENT_STONE:
+ case SURFACE_SCAFFOLD_POLE:
return true;
return false;
}
@@ -77,4 +97,5 @@ public:
static int GetAdhesionGroup(uint8 surfaceType);
static float GetWetMultiplier(uint8 surfaceType);
static float GetAdhesiveLimit(CColPoint &colpoint);
+ static bool IsSoftLanding(uint8 surf);
};
diff --git a/src/core/Timer.cpp b/src/core/Timer.cpp
index e4f5b01e..77f26a8b 100644
--- a/src/core/Timer.cpp
+++ b/src/core/Timer.cpp
@@ -5,9 +5,11 @@
#include "DMAudio.h"
#include "Record.h"
#include "Timer.h"
+#include "SpecialFX.h"
uint32 CTimer::m_snTimeInMilliseconds;
uint32 CTimer::m_snTimeInMillisecondsPauseMode = 1;
+
uint32 CTimer::m_snTimeInMillisecondsNonClipped;
uint32 CTimer::m_snPreviousTimeInMilliseconds;
uint32 CTimer::m_FrameCounter;
@@ -15,7 +17,7 @@ float CTimer::ms_fTimeScale;
float CTimer::ms_fTimeStep;
float CTimer::ms_fTimeStepNonClipped;
bool CTimer::m_UserPause;
-bool CTimer::m_CodePause;
+bool CTimer::m_CodePause;
#ifdef FIX_BUGS
uint32 CTimer::m_LogicalFrameCounter;
uint32 CTimer::m_LogicalFramesPassed;
@@ -83,9 +85,10 @@ void CTimer::Shutdown(void)
{
;
}
+
#ifdef FIX_BUGS
void CTimer::Update(void)
-{
+{
static double frameTimeLogical = 0.0;
static double frameTimeFraction = 0.0;
static double frameTimeFractionScaled = 0.0;
@@ -103,10 +106,9 @@ void CTimer::Update(void)
int32 updInCycles = (pc.LowPart - _oldPerfCounter.LowPart); // & 0x7FFFFFFF; pointless
_oldPerfCounter = pc;
-
- // bugfix from VC
- double updInCyclesScaled = GetIsPaused() ? updInCycles : updInCycles * ms_fTimeScale;
-
+
+ float updInCyclesScaled = GetIsPaused() ? updInCycles : updInCycles * ms_fTimeScale;
+
frameTime = updInCyclesScaled / (double)_nCyclesPerMS;
dblUpdInMs = (double)updInCycles / (double)_nCyclesPerMS;
@@ -117,10 +119,9 @@ void CTimer::Update(void)
RsTimerType timer = RsTimer();
RsTimerType updInMs = timer - oldPcTimer;
-
- // bugfix from VC
- frameTime = GetIsPaused() ? (double)updInMs : (double)updInMs * ms_fTimeScale;
-
+
+ frameTime = (double)updInMs * ms_fTimeScale;
+
oldPcTimer = timer;
dblUpdInMs = (double)updInMs;
@@ -129,7 +130,7 @@ void CTimer::Update(void)
// count frames as if we're running at 30 fps
m_LogicalFramesPassed = 0;
frameTimeLogical += dblUpdInMs;
- while(frameTimeLogical >= 1000.0 / 30.0) {
+ while (frameTimeLogical >= 1000.0 / 30.0) {
frameTimeLogical -= 1000.0 / 30.0;
m_LogicalFramesPassed++;
}
@@ -139,7 +140,7 @@ void CTimer::Update(void)
frameTimeFractionScaled += frameTime;
m_snTimeInMillisecondsPauseMode += uint32(frameTimeFraction);
-
+
if ( GetIsPaused() )
ms_fTimeStep = 0.0f;
else
@@ -151,7 +152,7 @@ void CTimer::Update(void)
frameTimeFraction -= uint32(frameTimeFraction);
frameTimeFractionScaled -= uint32(frameTimeFractionScaled);
- if ( ms_fTimeStep < 0.01f && !GetIsPaused() )
+ if ( ms_fTimeStep < 0.01f && !GetIsPaused() && !CSpecialFX::bSnapShotActive)
ms_fTimeStep = 0.01f;
ms_fTimeStepNonClipped = ms_fTimeStep;
@@ -186,10 +187,11 @@ void CTimer::Update(void)
int32 updInCycles = (pc.LowPart - _oldPerfCounter.LowPart); // & 0x7FFFFFFF; pointless
_oldPerfCounter = pc;
-
- float updInCyclesScaled = updInCycles * ms_fTimeScale;
-
+
+ float updInCyclesScaled = GetIsPaused() ? updInCycles : updInCycles * ms_fTimeScale;
+
double frameTime = updInCyclesScaled / (double)_nCyclesPerMS;
+
m_snTimeInMillisecondsPauseMode = m_snTimeInMillisecondsPauseMode + frameTime;
if ( GetIsPaused() )
@@ -209,11 +211,11 @@ void CTimer::Update(void)
RsTimerType updInMs = timer - oldPcTimer;
double frameTime = (double)updInMs * ms_fTimeScale;
-
- oldPcTimer = timer;
+ oldPcTimer = timer;
+
m_snTimeInMillisecondsPauseMode = m_snTimeInMillisecondsPauseMode + frameTime;
-
+
if ( GetIsPaused() )
ms_fTimeStep = 0.0f;
else
@@ -224,7 +226,7 @@ void CTimer::Update(void)
}
}
- if ( ms_fTimeStep < 0.01f && !GetIsPaused() )
+ if ( ms_fTimeStep < 0.01f && !GetIsPaused() && !CSpecialFX::bSnapShotActive)
ms_fTimeStep = 0.01f;
ms_fTimeStepNonClipped = ms_fTimeStep;
diff --git a/src/core/User.cpp b/src/core/User.cpp
index f906ae44..53196d03 100644
--- a/src/core/User.cpp
+++ b/src/core/User.cpp
@@ -1,6 +1,6 @@
#include "common.h"
-
+#include "GameLogic.h"
#include "Hud.h"
#include "PlayerPed.h"
#include "Replay.h"
@@ -32,8 +32,8 @@ void
CPlaceName::Process()
{
CVector pos = CWorld::Players[CWorld::PlayerInFocus].GetPos();
- CZone *navigZone = CTheZones::FindSmallestZonePositionType(&pos, ZONE_NAVIG);
- CZone *defaultZone = CTheZones::FindSmallestZonePositionType(&pos, ZONE_DEFAULT);
+ CZone *navigZone = CTheZones::FindSmallestNavigationZoneForPosition(&pos, false, true);
+ CZone *defaultZone = CTheZones::FindSmallestNavigationZoneForPosition(&pos, true, false);
if (navigZone == nil) m_pZone = nil;
if (defaultZone == nil) m_pZone2 = nil;
@@ -74,6 +74,14 @@ CPlaceName::Display()
CHud::SetZoneName(text);
}
+void
+CPlaceName::ProcessAfterFrontEndShutDown(void)
+{
+ CHud::m_pLastZoneName = nil;
+ CHud::m_ZoneState = 0;
+ m_nAdditionalTimer = 250;
+}
+
CCurrentVehicle::CCurrentVehicle()
{
Init();
@@ -99,7 +107,7 @@ void
CCurrentVehicle::Display()
{
wchar *text = nil;
- if (m_pCurrentVehicle != nil)
+ if (m_pCurrentVehicle != nil && m_pCurrentVehicle != CGameLogic::pShortCutTaxi)
text = TheText.Get(((CVehicleModelInfo*)CModelInfo::GetModelInfo(m_pCurrentVehicle->GetModelIndex()))->m_gameName);
CHud::SetVehicleName(text);
}
diff --git a/src/core/User.h b/src/core/User.h
index 153ef57b..dd53a40a 100644
--- a/src/core/User.h
+++ b/src/core/User.h
@@ -16,6 +16,7 @@ public:
void Init();
void Process();
void Display();
+ void ProcessAfterFrontEndShutDown();
};
class CCurrentVehicle
diff --git a/src/core/Wanted.cpp b/src/core/Wanted.cpp
index 909674d0..65bc84d8 100644
--- a/src/core/Wanted.cpp
+++ b/src/core/Wanted.cpp
@@ -10,16 +10,19 @@
#include "CopPed.h"
#include "Wanted.h"
#include "General.h"
+#include "Stats.h"
int32 CWanted::MaximumWantedLevel = 6;
-int32 CWanted::nMaximumWantedLevel = 6400;
+int32 CWanted::nMaximumWantedLevel = 9600;
void
CWanted::Initialise()
{
m_nChaos = 0;
+ m_nMinChaos = 0;
m_nLastUpdateTime = 0;
m_nLastWantedLevelChange = 0;
+ m_nLastTimeSuspended = 0;
m_CurrentCops = 0;
m_MaxCops = 0;
m_MaximumLawEnforcerVehicles = 0;
@@ -31,6 +34,7 @@ CWanted::Initialise()
m_bArmyRequired = false;
m_fCrimeSensitivity = 1.0f;
m_nWantedLevel = 0;
+ m_nMinWantedLevel = 0;
m_CopsBeatingSuspect = 0;
for (int i = 0; i < ARRAY_SIZE(m_pCops); i++)
@@ -40,6 +44,12 @@ CWanted::Initialise()
}
bool
+CWanted::AreMiamiViceRequired()
+{
+ return m_nWantedLevel >= 3;
+}
+
+bool
CWanted::AreSwatRequired()
{
return m_nWantedLevel == 4 || m_bSwatRequired;
@@ -69,7 +79,7 @@ CWanted::NumOfHelisRequired()
return 1;
case 5:
case 6:
- return 2;
+ return 1;
default:
return 0;
}
@@ -87,22 +97,22 @@ CWanted::SetWantedLevel(int32 level)
m_nChaos = 0;
break;
case 1:
- m_nChaos = 60;
+ m_nChaos = 70;
break;
case 2:
- m_nChaos = 220;
+ m_nChaos = 200;
break;
case 3:
- m_nChaos = 420;
+ m_nChaos = 570;
break;
case 4:
- m_nChaos = 820;
+ m_nChaos = 1220;
break;
case 5:
- m_nChaos = 1620;
+ m_nChaos = 2420;
break;
case 6:
- m_nChaos = 3220;
+ m_nChaos = 4820;
break;
default:
break;
@@ -113,11 +123,21 @@ CWanted::SetWantedLevel(int32 level)
void
CWanted::SetWantedLevelNoDrop(int32 level)
{
+ if (m_nWantedLevel < m_nMinWantedLevel)
+ SetWantedLevel(m_nMinWantedLevel);
+
if (level > m_nWantedLevel)
SetWantedLevel(level);
}
void
+CWanted::CheatWantedLevel(int32 level)
+{
+ SetWantedLevel(level);
+ UpdateWantedLevel();
+}
+
+void
CWanted::SetMaximumWantedLevel(int32 level)
{
switch(level){
@@ -126,27 +146,27 @@ CWanted::SetMaximumWantedLevel(int32 level)
MaximumWantedLevel = 0;
break;
case 1:
- nMaximumWantedLevel = 120;
+ nMaximumWantedLevel = 115;
MaximumWantedLevel = 1;
break;
case 2:
- nMaximumWantedLevel = 300;
+ nMaximumWantedLevel = 365;
MaximumWantedLevel = 2;
break;
case 3:
- nMaximumWantedLevel = 600;
+ nMaximumWantedLevel = 875;
MaximumWantedLevel = 3;
break;
case 4:
- nMaximumWantedLevel = 1200;
+ nMaximumWantedLevel = 1800;
MaximumWantedLevel = 4;
break;
case 5:
- nMaximumWantedLevel = 2400;
+ nMaximumWantedLevel = 3600;
MaximumWantedLevel = 5;
break;
case 6:
- nMaximumWantedLevel = 4800;
+ nMaximumWantedLevel = 7200;
MaximumWantedLevel = 6;
break;
}
@@ -161,10 +181,10 @@ CWanted::RegisterCrime(eCrimeType type, const CVector &coors, uint32 id, bool po
void
CWanted::RegisterCrime_Immediately(eCrimeType type, const CVector &coors, uint32 id, bool policeDoesntCare)
{
-#if defined FIX_SIGNIFICANT_BUGS || defined PEDS_REPORT_CRIMES_ON_PHONE
- if (!AddCrimeToQ(type, id, coors, true, policeDoesntCare))
+#ifdef FIX_SIGNIFICANT_BUGS
+ if(!AddCrimeToQ(type, id, coors, true, policeDoesntCare))
#else
- if (!AddCrimeToQ(type, id, coors, false, policeDoesntCare))
+ if(!AddCrimeToQ(type, id, coors, false, policeDoesntCare))
#endif
ReportCrimeNow(type, coors, policeDoesntCare);
}
@@ -223,9 +243,6 @@ CWanted::ReportCrimeNow(eCrimeType type, const CVector &coors, bool policeDoesnt
chaos *= 0.333f;
switch(type){
case CRIME_POSSESSION_GUN:
-#ifdef PEDS_REPORT_CRIMES_ON_PHONE
- m_nChaos += 5.0f*chaos;
-#endif
break;
case CRIME_HIT_PED:
m_nChaos += 5.0f*chaos;
@@ -272,10 +289,20 @@ CWanted::ReportCrimeNow(eCrimeType type, const CVector &coors, bool policeDoesnt
case CRIME_DESTROYED_CESSNA:
m_nChaos += 500.0f*chaos;
break;
+ case CRIME_EXPLOSION:
+ m_nChaos += 25.0f * chaos;
+ break;
+ case CRIME_HIT_PED_NASTYWEAPON:
+ m_nChaos += 35.0f * chaos;
+ break;
+ case CRIME_HIT_COP_NASTYWEAPON:
+ m_nChaos += 100.0f * chaos;
+ break;
default:
// Error("Undefined crime type, RegisterCrime, Crime.cpp"); // different file for some reason
Error("Undefined crime type, RegisterCrime, Wanted.cpp");
}
+ m_nChaos = Max(m_nChaos, m_nMinChaos);
DMAudio.ReportCrime(type, coors);
UpdateWantedLevel();
}
@@ -288,47 +315,49 @@ CWanted::UpdateWantedLevel()
if (m_nChaos > nMaximumWantedLevel)
m_nChaos = nMaximumWantedLevel;
- if (m_nChaos >= 0 && m_nChaos < 40) {
+ if (m_nChaos >= 0 && m_nChaos < 50) {
+ if (m_nWantedLevel == 1)
+ ++CStats::WantedStarsEvaded;
m_nWantedLevel = 0;
m_MaximumLawEnforcerVehicles = 0;
m_MaxCops = 0;
m_RoadblockDensity = 0;
- }
- else if (m_nChaos >= 40 && m_nChaos < 200) {
+ } else if (m_nChaos >= 50 && m_nChaos < 180) {
+ CStats::WantedStarsAttained += 1 - m_nWantedLevel;
m_nWantedLevel = 1;
m_MaximumLawEnforcerVehicles = 1;
m_MaxCops = 1;
m_RoadblockDensity = 0;
- }
- else if (m_nChaos >= 200 && m_nChaos < 400) {
+ } else if (m_nChaos >= 180 && m_nChaos < 550) {
+ CStats::WantedStarsAttained += 2 - m_nWantedLevel;
m_nWantedLevel = 2;
m_MaximumLawEnforcerVehicles = 2;
m_MaxCops = 3;
m_RoadblockDensity = 0;
- }
- else if (m_nChaos >= 400 && m_nChaos < 800) {
+ } else if (m_nChaos >= 550 && m_nChaos < 1200) {
+ CStats::WantedStarsAttained += 3 - m_nWantedLevel;
m_nWantedLevel = 3;
m_MaximumLawEnforcerVehicles = 2;
m_MaxCops = 4;
- m_RoadblockDensity = 4;
- }
- else if (m_nChaos >= 800 && m_nChaos < 1600) {
+ m_RoadblockDensity = 12;
+ } else if (m_nChaos >= 1200 && m_nChaos < 2400) {
+ CStats::WantedStarsAttained += 4 - m_nWantedLevel;
m_nWantedLevel = 4;
m_MaximumLawEnforcerVehicles = 2;
m_MaxCops = 6;
- m_RoadblockDensity = 8;
- }
- else if (m_nChaos >= 1600 && m_nChaos < 3200) {
+ m_RoadblockDensity = 18;
+ } else if (m_nChaos >= 2400 && m_nChaos < 4800) {
+ CStats::WantedStarsAttained += 5 - m_nWantedLevel;
m_nWantedLevel = 5;
m_MaximumLawEnforcerVehicles = 3;
m_MaxCops = 8;
- m_RoadblockDensity = 10;
- }
- else if (m_nChaos >= 3200) {
+ m_RoadblockDensity = 24;
+ } else if (m_nChaos >= 4800) {
+ CStats::WantedStarsAttained += 6 - m_nWantedLevel;
m_nWantedLevel = 6;
m_MaximumLawEnforcerVehicles = 3;
m_MaxCops = 10;
- m_RoadblockDensity = 12;
+ m_RoadblockDensity = 30;
}
if (CurrWantedLevel != m_nWantedLevel)
@@ -370,6 +399,10 @@ CWanted::WorkOutPolicePresence(CVector posn, float radius)
void
CWanted::Update(void)
{
+ if (CTimer::GetTimeInMilliseconds() > m_nLastTimeSuspended + 20000) {
+ m_nMinChaos = 0;
+ m_nMinWantedLevel = 0;
+ }
if (CTimer::GetTimeInMilliseconds() - m_nLastUpdateTime > 1000) {
if (m_nWantedLevel > 1) {
m_nLastUpdateTime = CTimer::GetTimeInMilliseconds();
@@ -447,30 +480,6 @@ CWanted::Reset(void)
Initialise();
}
-#ifdef PEDS_REPORT_CRIMES_ON_PHONE
-bool
-CrimeShouldBeReportedOnPhone(eCrimeType crime)
-{
- switch (crime) {
- case CRIME_POSSESSION_GUN:
- case CRIME_HIT_PED:
- case CRIME_HIT_COP:
- case CRIME_SHOOT_PED:
- case CRIME_SHOOT_COP:
- case CRIME_STEAL_CAR:
- case CRIME_RECKLESS_DRIVING:
- case CRIME_RUNOVER_PED:
- case CRIME_RUNOVER_COP:
- case CRIME_PED_BURNED:
- case CRIME_COP_BURNED:
- case CRIME_VEHICLE_BURNED:
- return true;
- default:
- return false;
- }
-}
-#endif
-
void
CWanted::UpdateCrimesQ(void)
{
@@ -478,9 +487,6 @@ CWanted::UpdateCrimesQ(void)
CCrimeBeingQd &crime = m_aCrimes[i];
if (crime.m_nType != CRIME_NONE) {
-#ifdef PEDS_REPORT_CRIMES_ON_PHONE
- if (!CrimeShouldBeReportedOnPhone(crime.m_nType))
-#endif
if (CTimer::GetTimeInMilliseconds() > crime.m_nTime + 500 && !crime.m_bReported) {
ReportCrimeNow(crime.m_nType, crime.m_vecPosn, crime.m_bPoliceDoesntCare);
crime.m_bReported = true;
@@ -490,3 +496,15 @@ CWanted::UpdateCrimesQ(void)
}
}
}
+
+void
+CWanted::Suspend(void)
+{
+ CStats::WantedStarsEvaded += m_nWantedLevel;
+ m_nMinChaos = m_nChaos;
+ m_nMinWantedLevel = m_nWantedLevel;
+ m_nLastTimeSuspended = CTimer::GetTimeInMilliseconds();
+ m_nChaos = 0;
+ m_nWantedLevel = 0;
+ ResetPolicePursuit();
+}
diff --git a/src/core/Wanted.h b/src/core/Wanted.h
index 9f08e752..f2da23e3 100644
--- a/src/core/Wanted.h
+++ b/src/core/Wanted.h
@@ -9,8 +9,10 @@ class CWanted
{
public:
int32 m_nChaos;
+ int32 m_nMinChaos;
int32 m_nLastUpdateTime;
uint32 m_nLastWantedLevelChange;
+ uint32 m_nLastTimeSuspended;
float m_fCrimeSensitivity;
uint8 m_CurrentCops;
uint8 m_MaxCops;
@@ -23,6 +25,7 @@ public:
uint8 m_bFbiRequired : 1;
uint8 m_bArmyRequired : 1;
int32 m_nWantedLevel;
+ int32 m_nMinWantedLevel;
CCrimeBeingQd m_aCrimes[16];
CCopPed *m_pCops[10];
@@ -31,6 +34,7 @@ public:
public:
void Initialise();
+ bool AreMiamiViceRequired();
bool AreSwatRequired();
bool AreFbiRequired();
bool AreArmyRequired();
@@ -38,6 +42,7 @@ public:
void SetWantedLevel(int32);
void SetWantedLevelNoDrop(int32 level);
int32 GetWantedLevel() { return m_nWantedLevel; }
+ void CheatWantedLevel(int32 level);
void RegisterCrime(eCrimeType type, const CVector &coors, uint32 id, bool policeDoesntCare);
void RegisterCrime_Immediately(eCrimeType type, const CVector &coors, uint32 id, bool policeDoesntCare);
void ClearQdCrimes();
@@ -49,6 +54,8 @@ public:
void UpdateCrimesQ();
void Update();
+ void Suspend();
+
bool IsIgnored(void) { return m_bIgnoredByCops || m_bIgnoredByEveryone; }
static int32 WorkOutPolicePresence(CVector posn, float radius);
diff --git a/src/core/World.cpp b/src/core/World.cpp
index 1c34a633..549c2cc0 100644
--- a/src/core/World.cpp
+++ b/src/core/World.cpp
@@ -12,6 +12,7 @@
#include "Messages.h"
#include "ModelIndices.h"
#include "ParticleObject.h"
+#include "Pickups.h"
#include "Population.h"
#include "ProjectileInfo.h"
#include "Record.h"
@@ -23,7 +24,6 @@
#include "WaterLevel.h"
#include "World.h"
-
#define OBJECT_REPOSITION_OFFSET_Z 2.0f
CColPoint gaTempSphereColPoints[MAX_COLLISION_POINTS];
@@ -44,13 +44,13 @@ bool CWorld::bProcessCutsceneOnly;
bool CWorld::bDoingCarCollisions;
bool CWorld::bIncludeCarTyres;
+bool CWorld::bIncludeBikers;
+
+CColPoint CWorld::m_aTempColPts[MAX_COLLISION_POINTS];
void
CWorld::Initialise()
{
-#if GTA_VERSION <= GTA3_PS2_160
- CPools::Initialise();
-#endif
pIgnoreEntity = nil;
bDoingCarCollisions = false;
bSecondShift = false;
@@ -59,6 +59,7 @@ CWorld::Initialise()
bIncludeDeadPeds = false;
bForceProcessControl = false;
bIncludeCarTyres = false;
+ bIncludeBikers = false;
}
void
@@ -151,6 +152,7 @@ CWorld::ClearExcitingStuffFromArea(const CVector &pos, float radius, bool bRemov
CProjectileInfo::RemoveAllProjectiles();
CShadows::TidyUpShadows();
}
+ CPickups::RemoveUnnecessaryPickups(pos, radius);
}
bool
@@ -163,7 +165,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;
@@ -182,7 +184,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
@@ -264,50 +266,55 @@ CWorld::ProcessLineOfSight(const CVector &point1, const CVector &point2, CColPoi
bool
CWorld::ProcessLineOfSightSector(CSector &sector, 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;
+ bool bikers = !!bIncludeBikers;
bIncludeDeadPeds = false;
+ bIncludeBikers = false;
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;
+ if(bikers) bIncludeBikers = 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;
+ bIncludeBikers = 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;
+ bIncludeBikers = bikers;
if(mindist < dist) {
dist = mindist;
@@ -318,53 +325,63 @@ CWorld::ProcessLineOfSightSector(CSector &sector, 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;
+ bool bikers = false;
+ bool carTyres = false;
float mindist = dist;
CPtrNode *node;
CEntity *e;
CColModel *colmodel;
-
+ CColModel tyreCol;
+ CColSphere tyreSpheres[6];
+ CColPoint tyreColPoint;
+ float tyreDist;
+
+ if(bIncludeCarTyres && list.first && ((CEntity*)list.first->item)->IsVehicle()){
+ carTyres = true;
+ tyreCol.numTriangles = 0;
+ tyreCol.numBoxes = 0;
+ tyreCol.numLines = 0;
+ tyreCol.spheres = tyreSpheres;
+ tyreCol.numSpheres = ARRAY_SIZE(tyreSpheres);
+ }
if(list.first && bIncludeDeadPeds && ((CEntity *)list.first->item)->IsPed()) deadPeds = true;
+ if(list.first && bIncludeBikers && ((CEntity *)list.first->item)->IsPed()) bikers = true;
for(node = list.first; node; node = node->next) {
e = (CEntity *)node->item;
- if(e->m_scanCode != GetCurrentScanCode() && e != pIgnoreEntity && (e->bUsesCollision || deadPeds) &&
+ if(e->m_scanCode != GetCurrentScanCode() && e != pIgnoreEntity && (e->bUsesCollision || deadPeds || bikers) &&
!(ignoreSomeObjects && CameraToIgnoreThisObject(e))) {
colmodel = nil;
+ tyreDist = mindist;
e->m_scanCode = GetCurrentScanCode();
if(e->IsPed()) {
- if(e->bUsesCollision || deadPeds && ((CPed *)e)->m_nPedState == PED_DEAD) {
-#ifdef PED_SKIN
- if(IsClumpSkinned(e->GetClump()))
- colmodel = ((CPedModelInfo *)CModelInfo::GetModelInfo(e->GetModelIndex()))->AnimatePedColModelSkinned(e->GetClump());
- else
-#endif
- 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
+ if(e->bUsesCollision || deadPeds && ((CPed *)e)->m_nPedState == PED_DEAD || bikers && ((CPed*)e)->InVehicle() && (((CPed*)e)->m_pMyVehicle->IsBike() || ((CPed*)e)->m_pMyVehicle->IsBoat())) {
+ colmodel = ((CPedModelInfo *)CModelInfo::GetModelInfo(e->GetModelIndex()))->AnimatePedColModelSkinned(e->GetClump());
} else
colmodel = nil;
+
} else if(e->bUsesCollision)
colmodel = CModelInfo::GetColModel(e->GetModelIndex());
if(colmodel && CCollision::ProcessLineOfSight(line, e->GetMatrix(), *colmodel, point, mindist,
- ignoreSeeThrough))
+ ignoreSeeThrough, ignoreShootThrough))
entity = e;
+ if(carTyres && ((CVehicle*)e)->SetUpWheelColModel(&tyreCol) && CCollision::ProcessLineOfSight(line, e->GetMatrix(), tyreCol, tyreColPoint, tyreDist, false, ignoreShootThrough)){
+ float dp1 = DotProduct(line.p1 - line.p0, e->GetRight());
+ float dp2 = DotProduct(point.point - e->GetPosition(), e->GetRight());
+ if(tyreDist < mindist || dp1 < -0.85f && dp2 > 0.0f || dp1 > 0.85f && dp2 < 0.0f){
+ mindist = tyreDist;
+ point = tyreColPoint;
+ entity = e;
+ }
+ }
}
}
+ tyreCol.spheres = nil;
if(mindist < dist) {
dist = mindist;
@@ -380,7 +397,11 @@ CWorld::ProcessVerticalLine(const CVector &point1, float z2, CColPoint &point, C
{
AdvanceCurrentScanCode();
CVector point2(point1.x, point1.y, z2);
- return ProcessVerticalLineSector(*GetSector(GetSectorIndexX(point1.x), GetSectorIndexY(point1.y)),
+ int secX = GetSectorIndexX(point1.x);
+ int secY = GetSectorIndexY(point1.y);
+ secX = Clamp(secX, 0, NUMSECTORS_X-1);
+ secY = Clamp(secY, 0, NUMSECTORS_Y-1);
+ return ProcessVerticalLineSector(*GetSector(secX, secY),
CColLine(point1, point2), point, entity, checkBuildings, checkVehicles,
checkPeds, checkObjects, checkDummies, ignoreSeeThrough, poly);
}
@@ -446,7 +467,7 @@ CWorld::ProcessVerticalLineSectorList(CPtrList &list, const CColLine &line, CCol
colmodel = CModelInfo::GetColModel(e->GetModelIndex());
if(CCollision::ProcessVerticalLine(line, e->GetMatrix(), *colmodel, point, mindist,
- ignoreSeeThrough, poly))
+ ignoreSeeThrough, false, poly))
entity = e;
}
}
@@ -647,7 +668,7 @@ CWorld::GetIsLineOfSightSectorListClear(CPtrList &list, const CColLine &line, bo
colmodel = CModelInfo::GetColModel(e->GetModelIndex());
- if(CCollision::TestLineOfSight(line, e->GetMatrix(), *colmodel, ignoreSeeThrough))
+ if(CCollision::TestLineOfSight(line, e->GetMatrix(), *colmodel, ignoreSeeThrough, false))
return false;
}
}
@@ -694,18 +715,10 @@ CWorld::FindObjectsInRange(Const CVector &centre, float radius, bool ignoreZ, in
if(minY <= 0) minY = 0;
int maxX = GetSectorIndexX(centre.x + radius);
-#ifdef FIX_BUGS
if(maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X - 1;
-#else
- if(maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X;
-#endif
int maxY = GetSectorIndexY(centre.y + radius);
-#ifdef FIX_BUGS
if(maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y - 1;
-#else
- if(maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y;
-#endif
AdvanceCurrentScanCode();
@@ -782,8 +795,13 @@ CWorld::FindObjectsOfTypeInRange(uint32 modelId, const CVector &position, float
const CVector2D vecSectorEndPos(position.x + radius, position.y + radius);
const int32 nStartX = Max(GetSectorIndexX(vecSectorStartPos.x), 0);
const int32 nStartY = Max(GetSectorIndexY(vecSectorStartPos.y), 0);
+#ifdef FIX_BUGS
const int32 nEndX = Min(GetSectorIndexX(vecSectorEndPos.x), NUMSECTORS_X - 1);
const int32 nEndY = Min(GetSectorIndexY(vecSectorEndPos.y), NUMSECTORS_Y - 1);
+#else
+ const int32 nEndX = Min(GetSectorIndexX(vecSectorEndPos.x), NUMSECTORS_X);
+ const int32 nEndY = Min(GetSectorIndexY(vecSectorEndPos.y), NUMSECTORS_Y);
+#endif
for(int32 y = nStartY; y <= nEndY; y++) {
for(int32 x = nStartX; x <= nEndX; x++) {
CSector *pSector = GetSector(x, y);
@@ -918,6 +936,7 @@ CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float rad
bool ignoreSomeObjects)
{
static CColModel OurColModel;
+ CColSphere sphere;
OurColModel.boundingSphere.center.x = 0.0f;
OurColModel.boundingSphere.center.y = 0.0f;
@@ -930,7 +949,8 @@ CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float rad
OurColModel.boundingBox.max.y = radius;
OurColModel.boundingBox.max.z = radius;
OurColModel.numSpheres = 1;
- OurColModel.spheres = &OurColModel.boundingSphere;
+ sphere.Set(radius, CVector(0.0f, 0.0f, 0.0f));
+ OurColModel.spheres = &sphere;
OurColModel.numLines = 0;
OurColModel.numBoxes = 0;
OurColModel.numTriangles = 0;
@@ -947,11 +967,7 @@ CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float rad
if(e != entityToIgnore && e->bUsesCollision &&
!(ignoreSomeObjects && CameraToIgnoreThisObject(e))) {
-#ifdef FIX_BUGS
CVector diff = spherePos - e->GetBoundCentre();
-#else
- CVector diff = spherePos - e->GetPosition();
-#endif
float distance = diff.Magnitude();
if(e->GetBoundRadius() + radius > distance) {
@@ -1053,8 +1069,13 @@ CWorld::FindObjectsKindaColliding(const CVector &position, float radius, bool bC
const CVector2D vecSectorEndPos(position.x + radius, position.y + radius);
const int32 nStartX = Max(GetSectorIndexX(vecSectorStartPos.x), 0);
const int32 nStartY = Max(GetSectorIndexY(vecSectorStartPos.y), 0);
+#ifdef FIX_BUGS
const int32 nEndX = Min(GetSectorIndexX(vecSectorEndPos.x), NUMSECTORS_X - 1);
const int32 nEndY = Min(GetSectorIndexY(vecSectorEndPos.y), NUMSECTORS_Y - 1);
+#else
+ const int32 nEndX = Min(GetSectorIndexX(vecSectorEndPos.x), NUMSECTORS_X);
+ const int32 nEndY = Min(GetSectorIndexY(vecSectorEndPos.y), NUMSECTORS_Y);
+#endif
for(int32 y = nStartY; y <= nEndY; y++) {
for(int32 x = nStartX; x <= nEndX; x++) {
CSector *pSector = GetSector(x, y);
@@ -1132,8 +1153,13 @@ CWorld::FindObjectsIntersectingCube(const CVector &vecStartPos, const CVector &v
*nIntersecting = 0;
const int32 nStartX = Max(GetSectorIndexX(vecStartPos.x), 0);
const int32 nStartY = Max(GetSectorIndexY(vecStartPos.y), 0);
- const int32 nEndX = Min(GetSectorIndexX(vecEndPos.x), NUMSECTORS_X - 1);
- const int32 nEndY = Min(GetSectorIndexY(vecEndPos.y), NUMSECTORS_Y - 1);
+#ifdef FIX_BUGS
+ const int32 nEndX = Min(GetSectorIndexX(vecStartPos.x), NUMSECTORS_X - 1);
+ const int32 nEndY = Min(GetSectorIndexY(vecStartPos.y), NUMSECTORS_Y - 1);
+#else
+ const int32 nEndX = Min(GetSectorIndexX(vecStartPos.x), NUMSECTORS_X);
+ const int32 nEndY = Min(GetSectorIndexY(vecStartPos.y), NUMSECTORS_Y);
+#endif
for(int32 y = nStartY; y <= nEndY; y++) {
for(int32 x = nStartX; x <= nEndX; x++) {
CSector *pSector = GetSector(x, y);
@@ -1203,7 +1229,7 @@ CWorld::FindObjectsIntersectingCubeSectorList(CPtrList &list, const CVector &vec
}
void
-CWorld::FindObjectsIntersectingAngledCollisionBox(const CColBox &boundingBox, const CMatrix &matrix,
+CWorld::FindObjectsIntersectingAngledCollisionBox(const CBox &boundingBox, const CMatrix &matrix,
const CVector &position, float fStartX, float fStartY, float fEndX,
float fEndY, int16 *nEntitiesFound, int16 maxEntitiesToFind,
CEntity **aEntities, bool bBuildings, bool bVehicles, bool bPeds,
@@ -1213,8 +1239,13 @@ CWorld::FindObjectsIntersectingAngledCollisionBox(const CColBox &boundingBox, co
*nEntitiesFound = 0;
const int32 nStartX = Max(GetSectorIndexX(fStartX), 0);
const int32 nStartY = Max(GetSectorIndexY(fStartY), 0);
+#ifdef FIX_BUGS
const int32 nEndX = Min(GetSectorIndexX(fEndX), NUMSECTORS_X - 1);
const int32 nEndY = Min(GetSectorIndexY(fEndY), NUMSECTORS_Y - 1);
+#else
+ const int32 nEndX = Min(GetSectorIndexX(fEndX), NUMSECTORS_X);
+ const int32 nEndY = Min(GetSectorIndexY(fEndY), NUMSECTORS_Y);
+#endif
for(int32 y = nStartY; y <= nEndY; y++) {
for(int32 x = nStartX; x <= nEndX; x++) {
CSector *pSector = GetSector(x, y);
@@ -1263,7 +1294,7 @@ CWorld::FindObjectsIntersectingAngledCollisionBox(const CColBox &boundingBox, co
}
void
-CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(CPtrList &list, const CColBox &boundingBox,
+CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(CPtrList &list, const CBox &boundingBox,
const CMatrix &matrix, const CVector &position,
int16 *nEntitiesFound, int16 maxEntitiesToFind,
CEntity **aEntities)
@@ -1293,8 +1324,13 @@ CWorld::FindMissionEntitiesIntersectingCube(const CVector &vecStartPos, const CV
*nIntersecting = 0;
const int32 nStartX = Max(GetSectorIndexX(vecStartPos.x), 0);
const int32 nStartY = Max(GetSectorIndexY(vecStartPos.y), 0);
+#ifdef FIX_BUGS
const int32 nEndX = Min(GetSectorIndexX(vecEndPos.x), NUMSECTORS_X - 1);
const int32 nEndY = Min(GetSectorIndexY(vecEndPos.y), NUMSECTORS_Y - 1);
+#else
+ const int32 nEndX = Min(GetSectorIndexX(vecEndPos.x), NUMSECTORS_X);
+ const int32 nEndY = Min(GetSectorIndexY(vecEndPos.y), NUMSECTORS_Y);
+#endif
for(int32 y = nStartY; y <= nEndY; y++) {
for(int32 x = nStartX; x <= nEndX; x++) {
CSector *pSector = GetSector(x, y);
@@ -1411,8 +1447,13 @@ CWorld::CallOffChaseForArea(float x1, float y1, float x2, float y2)
float fEndY = y2 + 10.0f;
const int32 nStartX = Max(GetSectorIndexX(fStartX), 0);
const int32 nStartY = Max(GetSectorIndexY(fStartY), 0);
+#ifdef FIX_BUGS
const int32 nEndX = Min(GetSectorIndexX(fEndX), NUMSECTORS_X - 1);
const int32 nEndY = Min(GetSectorIndexY(fEndY), NUMSECTORS_Y - 1);
+#else
+ const int32 nEndX = Min(GetSectorIndexX(fEndX), NUMSECTORS_X);
+ const int32 nEndY = Min(GetSectorIndexY(fEndY), NUMSECTORS_Y);
+#endif
for(int32 y = nStartY; y <= nEndY; y++) {
for(int32 x = nStartX; x <= nEndX; x++) {
CSector *pSector = GetSector(x, y);
@@ -1543,7 +1584,7 @@ CWorld::RemoveFallenCars(void)
CVehicle *veh = CPools::GetVehiclePool()->GetSlot(poolIndex);
if(veh) {
if(veh->GetPosition().z < MAP_Z_LOW_LIMIT) {
- if(veh->VehicleCreatedBy == MISSION_VEHICLE || veh == FindPlayerVehicle() ||
+ if(veh->VehicleCreatedBy == MISSION_VEHICLE && !veh->bRenderScorched || veh == FindPlayerVehicle() ||
(veh->pDriver && veh->pDriver->IsPlayer())) {
int closestNode = ThePaths.FindNodeClosestToCoors(veh->GetPosition(), PATH_CAR,
999999.9f, false, false);
@@ -1595,10 +1636,10 @@ CWorld::ExtinguishAllCarFiresInArea(CVector point, float range)
}
}
-inline void
-AddSteamsFromGround(CPtrList& list)
+inline void
+AddSteamsFromGround(CPtrList& list)
{
- CPtrNode *pNode = list.first;
+ CPtrNode* pNode = list.first;
while (pNode) {
((CEntity*)pNode->item)->AddSteamsFromGround(nil);
pNode = pNode->next;
@@ -1700,9 +1741,6 @@ CWorld::ShutDown(void)
}
}
ms_listMovingEntityPtrs.Flush();
-#if GTA_VERSION <= GTA3_PS2_160
- CPools::Shutdown();
-#endif
}
void
@@ -1750,35 +1788,56 @@ void
CWorld::RepositionOneObject(CEntity *pEntity)
{
int16 modelId = pEntity->GetModelIndex();
- if (IsStreetLight(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) {
- CVector &position = pEntity->GetMatrix().GetPosition();
- float fBoundingBoxMinZ = pEntity->GetColModel()->boundingBox.min.z;
+ 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)
+ ) {
+ CVector& position = pEntity->GetMatrix().GetPosition();
+ 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 = FindGroundZFor3DCoord(position.x, position.y,
- position.z + OBJECT_REPOSITION_OFFSET_Z, nil) -
- fBoundingBoxMinZ;
+ position.z + fHeight, nil) -
+ fBoundingBoxMinZ;
+ pEntity->GetMatrix().UpdateRW();
+ pEntity->UpdateRwFrame();
+ } else if(IsLightThatNeedsRepositioning(modelId)) {
+ CVector position = pEntity->GetMatrix().GetPosition();
+ 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;
+ if (pColModel->numBoxes == 1)
+ position = pEntity->GetMatrix() * CVector(
+ (pColModel->boxes[0].min.x + pColModel->boxes[0].max.x) / 2,
+ (pColModel->boxes[0].min.y + pColModel->boxes[0].max.y) / 2,
+ pColModel->boxes[0].min.z);
+ else if (pColModel->numSpheres > 0) {
+ position.z = 1000.0f;
+ for (int i = 0; i < pColModel->numSpheres; i++) {
+ if (pColModel->spheres[i].center.z < position.z)
+ position = pColModel->spheres[i].center;
+ }
+ if (position.z < 1000.0f)
+ position = pEntity->GetMatrix() * position;
+ }
+ pEntity->GetMatrix().GetPosition().z = FindGroundZFor3DCoord(position.x, position.y, pEntity->GetMatrix().GetPosition().z + fHeight, nil) - fBoundingBoxMinZ;
pEntity->GetMatrix().UpdateRW();
pEntity->UpdateRwFrame();
- } else if(modelId == MI_BUOY) {
- float fWaterLevel = 0.0f;
+
+ }
+ if(modelId == MI_BUOY) {
bool bFound = true;
const CVector &position = pEntity->GetPosition();
float fGroundZ = FindGroundZFor3DCoord(position.x, position.y,
position.z + OBJECT_REPOSITION_OFFSET_Z, &bFound);
- if(CWaterLevel::GetWaterLevelNoWaves(position.x, position.y, position.z + OBJECT_REPOSITION_OFFSET_Z,
- &fWaterLevel)) {
- if(!bFound || fWaterLevel > fGroundZ) {
- CColModel *pColModel = pEntity->GetColModel();
- float fHeight = pColModel->boundingBox.max.z - pColModel->boundingBox.min.z;
- pEntity->GetMatrix().GetPosition().z = 0.2f * fHeight + fWaterLevel - 0.5f * fHeight;
- }
- }
+ CColModel *pColModel = pEntity->GetColModel();
+ float fHeight = pColModel->boundingBox.max.z - pColModel->boundingBox.min.z;
+ pEntity->GetMatrix().GetPosition().z = 0.2f * fHeight + 6.0f - 0.5f * fHeight;
}
}
@@ -1797,6 +1856,28 @@ CWorld::SetCarsOnFire(float x, float y, float z, float radius, CEntity *reason)
}
void
+CWorld::SetPedsChoking(float x, float y, float z, float radius, CEntity* reason)
+{
+ int32 poolSize = CPools::GetPedPool()->GetSize();
+ for (int32 i = poolSize - 1; i >= 0; i--) {
+ CPed* pPed = CPools::GetPedPool()->GetSlot(i);
+ // suspicious copypaste
+ if (pPed && pPed->m_nPedState != PED_DEAD && !pPed->bInVehicle && !pPed->m_pFire && !pPed->bFireProof && pPed->CharCreatedBy != MISSION_CHAR) {
+ if (Abs(pPed->GetPosition().z - z) < 5.0f && Abs(pPed->GetPosition().x - x) < radius &&
+ Abs(pPed->GetPosition().y - y) < radius) {
+ if (!pPed->IsPlayer())
+ pPed->SetFlee(CVector2D(x, y), 10000);
+#ifdef FIX_BUGS
+ pPed->InflictDamage(reason, WEAPONTYPE_TEARGAS, 1.0f, PEDPIECE_TORSO, 0);
+#else
+ pPed->InflictDamage(nil, WEAPONTYPE_TEARGAS, 1.0f, PEDPIECE_TORSO, 0);
+#endif
+ }
+ }
+ }
+}
+
+void
CWorld::SetPedsOnFire(float x, float y, float z, float radius, CEntity *reason)
{
int32 poolSize = CPools::GetPedPool()->GetSize();
@@ -1848,10 +1929,13 @@ CWorld::Process(void)
if(csObj && csObj->m_entryInfoList.first) {
if(csObj->m_rwObject && RwObjectGetType(csObj->m_rwObject) == rpCLUMP &&
RpAnimBlendClumpGetFirstAssociation(csObj->GetClump())) {
- RpAnimBlendClumpUpdateAnimations(csObj->GetClump(),
- csObj->IsObject()
- ? CTimer::GetTimeStepNonClippedInSeconds()
- : CTimer::GetTimeStepInSeconds());
+ if (csObj->IsObject())
+ RpAnimBlendClumpUpdateAnimations(csObj->GetClump(), CTimer::GetTimeStepNonClippedInSeconds());
+ else {
+ if (!csObj->bOffscreen)
+ csObj->bOffscreen = !csObj->GetIsOnScreen();
+ RpAnimBlendClumpUpdateAnimations(csObj->GetClump(), CTimer::GetTimeStepInSeconds(), !csObj->bOffscreen);
+ }
}
csObj->ProcessControl();
csObj->ProcessCollision();
@@ -1864,16 +1948,15 @@ CWorld::Process(void)
} else {
for(CPtrNode *node = ms_listMovingEntityPtrs.first; node; node = node->next) {
CEntity *movingEnt = (CEntity *)node->item;
-#ifdef FIX_BUGS // from VC
if(!movingEnt->bRemoveFromWorld && movingEnt->m_rwObject && RwObjectGetType(movingEnt->m_rwObject) == rpCLUMP &&
-#else
- if(movingEnt->m_rwObject && RwObjectGetType(movingEnt->m_rwObject) == rpCLUMP &&
-#endif
RpAnimBlendClumpGetFirstAssociation(movingEnt->GetClump())) {
- RpAnimBlendClumpUpdateAnimations(movingEnt->GetClump(),
- movingEnt->IsObject()
- ? CTimer::GetTimeStepNonClippedInSeconds()
- : CTimer::GetTimeStepInSeconds());
+ if (movingEnt->IsObject())
+ RpAnimBlendClumpUpdateAnimations(movingEnt->GetClump(), CTimer::GetTimeStepNonClippedInSeconds());
+ else {
+ if (!movingEnt->bOffscreen)
+ movingEnt->bOffscreen = !movingEnt->GetIsOnScreen();
+ RpAnimBlendClumpUpdateAnimations(movingEnt->GetClump(), CTimer::GetTimeStepInSeconds(), !movingEnt->bOffscreen);
+ }
}
}
for(CPtrNode *node = ms_listMovingEntityPtrs.first; node; node = node->next) {
@@ -1957,7 +2040,7 @@ CWorld::Process(void)
movingEnt->bIsStuck = true;
if(movingEnt->GetStatus() == STATUS_PLAYER) {
printf("STUCK: Final Step: Player Entity %d Is Stuck\n", movingEnt->GetModelIndex());
- movingEnt->m_vecMoveSpeed *= 0.3f;
+ movingEnt->m_vecMoveSpeed *= Pow(0.707f, CTimer::GetTimeStep());
movingEnt->ApplyMoveSpeed();
movingEnt->ApplyTurnSpeed();
}
@@ -1972,9 +2055,12 @@ CWorld::Process(void)
movingPed->EnteringCar()) {
CVehicle *movingCar = movingPed->m_pMyVehicle;
if(movingCar) {
+#ifdef GTA_TRAIN
if(movingCar->IsTrain()) {
movingPed->SetPedPositionInTrain();
- } else {
+ } else
+#endif
+ {
switch(movingPed->m_nPedState) {
case PED_ENTER_CAR:
case PED_CARJACK: movingPed->EnterCar(); break;
@@ -1995,6 +2081,10 @@ CWorld::Process(void)
movingPed->bInVehicle = false;
movingPed->QuitEnteringCar();
}
+ } else if (movingPed->m_attachedTo) {
+ movingPed->PositionAttachedPed();
+ movingPed->GetMatrix().UpdateRW();
+ movingPed->UpdateRwFrame();
}
}
}
@@ -2059,7 +2149,7 @@ CWorld::TriggerExplosionSectorList(CPtrList &list, const CVector &position, floa
pObject->bHasBeenDamaged) {
if(pEntity->IsObject() &&
modelId != MI_EXPLODINGBARREL &&
- modelId != MI_PETROLPUMP)
+ modelId != MI_PETROLPUMP && modelId != MI_PETROLPUMP2)
pObject->bHasBeenDamaged = true;
} else {
CVector pos = pEntity->GetPosition();
@@ -2149,8 +2239,12 @@ CWorld::UseDetonator(CEntity *pEntity)
{
int32 i = CPools::GetVehiclePool()->GetSize();
while(--i >= 0) {
+#ifdef FIX_BUGS
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
+#else
CAutomobile *pVehicle = (CAutomobile *)CPools::GetVehiclePool()->GetSlot(i);
- if(pVehicle && !pVehicle->m_vehType && pVehicle->m_bombType == CARBOMB_REMOTE &&
+#endif
+ if(pVehicle && pVehicle->m_bombType == CARBOMB_REMOTE &&
pVehicle->m_pBombRigger == pEntity) {
pVehicle->m_bombType = CARBOMB_NONE;
pVehicle->m_nBombTimer = 500;
@@ -2159,4 +2253,60 @@ CWorld::UseDetonator(CEntity *pEntity)
pVehicle->m_pBlowUpEntity->RegisterReference(&pVehicle->m_pBlowUpEntity);
}
}
+ 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 3d553752..81eb5d4c 100644
--- a/src/core/World.h
+++ b/src/core/World.h
@@ -5,19 +5,19 @@
#include "PlayerInfo.h"
#include "Collision.h"
-/* Sectors span from -2000 to 2000 in x and y.
- * With 100x100 sectors, each is 40x40 units. */
+/* Sectors span from -2400 to 1600 in x and -2000 to 2000 y.
+ * With 80x80 sectors, each is 50x50 units. */
-#define SECTOR_SIZE_X (40.0f)
-#define SECTOR_SIZE_Y (40.0f)
+#define SECTOR_SIZE_X (50.0f)
+#define SECTOR_SIZE_Y (50.0f)
-#define NUMSECTORS_X (100)
-#define NUMSECTORS_Y (100)
+#define NUMSECTORS_X (80)
+#define NUMSECTORS_Y (80)
#define WORLD_SIZE_X (NUMSECTORS_X * SECTOR_SIZE_X)
#define WORLD_SIZE_Y (NUMSECTORS_Y * SECTOR_SIZE_Y)
-#define WORLD_MIN_X (-2000.0f)
+#define WORLD_MIN_X (-2400.0f)
#define WORLD_MIN_Y (-2000.0f)
#define WORLD_MAX_X (WORLD_MIN_X + WORLD_SIZE_X)
@@ -67,11 +67,13 @@ public:
static bool bProcessCutsceneOnly;
static bool bDoingCarCollisions;
static bool bIncludeCarTyres;
+ static bool bIncludeBikers;
+ static CColPoint m_aTempColPts[MAX_COLLISION_POINTS];
static void Remove(CEntity *entity);
static void Add(CEntity *entity);
- static CSector *GetSector(int x, int y) { return &ms_aSectors[y][x]; }
+ static CSector *GetSector(int x, int y) { if (x > NUMSECTORS_X - 1 || y > NUMSECTORS_Y - 1) return &ms_aSectors[0][0]; return &ms_aSectors[y][x]; }
static CPtrList &GetBigBuildingList(eLevelName i) { return ms_bigBuildingsList[i]; }
static CPtrList &GetMovingEntityList(void) { return ms_listMovingEntityPtrs; }
static uint16 GetCurrentScanCode(void) { return ms_nCurrentScanCode; }
@@ -86,9 +88,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 &sector, 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 &sector, 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 &sector, 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);
@@ -110,8 +112,8 @@ public:
static void FindObjectsKindaCollidingSectorList(CPtrList& list, const CVector& position, float radius, bool bCheck2DOnly, int16* nCollidingEntities, int16 maxEntitiesToFind, CEntity** aEntities);
static void FindObjectsIntersectingCube(const CVector& vecStartPos, const CVector& vecEndPos, int16* nIntersecting, int16 maxEntitiesToFind, CEntity** aEntities, bool bBuildings, bool bVehicles, bool bPeds, bool bObjects, bool bDummies);
static void FindObjectsIntersectingCubeSectorList(CPtrList& list, const CVector& vecStartPos, const CVector& vecEndPos, int16* nIntersecting, int16 maxEntitiesToFind, CEntity** aEntities);
- static void FindObjectsIntersectingAngledCollisionBox(const CColBox &, const CMatrix &, const CVector &, float, float, float, float, int16*, int16, CEntity **, bool, bool, bool, bool, bool);
- static void FindObjectsIntersectingAngledCollisionBoxSectorList(CPtrList& list, const CColBox& boundingBox, const CMatrix& matrix, const CVector& position, int16* nEntitiesFound, int16 maxEntitiesToFind, CEntity** aEntities);
+ static void FindObjectsIntersectingAngledCollisionBox(const CBox &, const CMatrix &, const CVector &, float, float, float, float, int16*, int16, CEntity **, bool, bool, bool, bool, bool);
+ static void FindObjectsIntersectingAngledCollisionBoxSectorList(CPtrList& list, const CBox& boundingBox, const CMatrix& matrix, const CVector& position, int16* nEntitiesFound, int16 maxEntitiesToFind, CEntity** aEntities);
static void FindMissionEntitiesIntersectingCube(const CVector& vecStartPos, const CVector& vecEndPos, int16* nIntersecting, int16 maxEntitiesToFind, CEntity** aEntities, bool bVehicles, bool bPeds, bool bObjects);
static void FindMissionEntitiesIntersectingCubeSectorList(CPtrList& list, const CVector& vecStartPos, const CVector& vecEndPos, int16* nIntersecting, int16 maxEntitiesToFind, CEntity** aEntities, bool bIsVehicleList, bool bIsPedList);
@@ -121,6 +123,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); }
@@ -136,6 +140,7 @@ public:
static void SetAllCarsCanBeDamaged(bool);
static void ExtinguishAllCarFiresInArea(CVector, float);
static void SetCarsOnFire(float x, float y, float z, float radius, CEntity* reason);
+ static void SetPedsChoking(float x, float y, float z, float radius, CEntity* reason);
static void SetPedsOnFire(float x, float y, float z, float radius, CEntity* reason);
static void Initialise();
@@ -149,7 +154,23 @@ public:
static void TriggerExplosion(const CVector& position, float fRadius, float fPower, CEntity* pCreator, bool bProcessVehicleBombTimer);
static void TriggerExplosionSectorList(CPtrList& list, const CVector& position, float fRadius, float fPower, CEntity* pCreator, bool bProcessVehicleBombTimer);
static void UseDetonator(CEntity *pEntity);
+
+ // NB: following functions are unused (TODO?)
+ static void CastShadow(float, float, float, float);
+ static void CastShadowSectorList(CPtrList&, float, float, float, float);
+ static void FindLowestZForCoord(float, float);
+ static void CheckBlockListIntegrity(void);
+ static void ProcessVerticalLineSectorList_FillGlobeColPoints(CPtrList&, const CColLine&, CEntity*&, bool, CStoredCollPoly*);
+ static void ProcessVerticalLineSector_FillGlobeColPoints(CSector&, const CColLine&, CEntity*&, bool, bool, bool, bool, bool, bool, CStoredCollPoly*);
+ static void ProcessVerticalLine_FillGlobeColPoints(const CVector&, float, CEntity*&, bool, bool, bool, bool, bool, bool, CStoredCollPoly*);
+ static void PrintCarChanges(void);
+ static void TestForBuildingsOnTopOfEachOther(CPtrList&);
+ static void TestForBuildingsOnTopOfEachOther(void);
+ static void TestForUnusedModels(CPtrList&, int*);
+ static void TestForUnusedModels(void);
+ static void HandleCollisionZoneChange(eLevelName, eLevelName);
+ static void DoZoneTestForChaser(class CPhysical*);
+ static void FindPlayerSlotWithPedPointer(void*);
};
extern CColPoint gaTempSphereColPoints[MAX_COLLISION_POINTS];
-
diff --git a/src/core/ZoneCull.cpp b/src/core/ZoneCull.cpp
index 5a76e5ed..db3577ad 100644
--- a/src/core/ZoneCull.cpp
+++ b/src/core/ZoneCull.cpp
@@ -1,6 +1,5 @@
#include "common.h"
-#include "General.h"
#include "Building.h"
#include "Treadable.h"
#include "Train.h"
@@ -12,242 +11,23 @@
#include "ZoneCull.h"
#include "Zones.h"
-#include "Debug.h"
-#include "Renderer.h"
-
-int32 CCullZones::NumCullZones;
-CCullZone CCullZones::aZones[NUMCULLZONES];
int32 CCullZones::NumAttributeZones;
CAttributeZone CCullZones::aAttributeZones[NUMATTRIBZONES];
-uint16 CCullZones::aIndices[NUMZONEINDICES];
-int16 CCullZones::aPointersToBigBuildingsForBuildings[NUMBUILDINGS];
-int16 CCullZones::aPointersToBigBuildingsForTreadables[NUMTREADABLES];
int32 CCullZones::CurrentWantedLevelDrop_Player;
int32 CCullZones::CurrentFlags_Camera;
int32 CCullZones::CurrentFlags_Player;
-int32 CCullZones::OldCullZone;
-int32 CCullZones::EntityIndicesUsed;
bool CCullZones::bCurrentSubwayIsInvisible;
-bool CCullZones::bCullZonesDisabled;
-
-#define NUMUNCOMPRESSED (6000)
-#define NUMTEMPINDICES (140000)
+bool CCullZones::bAtBeachForAudio;
void
CCullZones::Init(void)
{
- int i;
-
NumAttributeZones = 0;
CurrentWantedLevelDrop_Player = 0;
CurrentFlags_Camera = 0;
CurrentFlags_Player = 0;
bCurrentSubwayIsInvisible = false;
- NumCullZones = 0;
- OldCullZone = -1;
- EntityIndicesUsed = 0;
-
- for(i = 0; i < NUMBUILDINGS; i++)
- aPointersToBigBuildingsForBuildings[i] = -1;
- for(i = 0; i < NUMTREADABLES; i++)
- aPointersToBigBuildingsForTreadables[i] = -1;
-}
-
-
-uint16* pTempArrayIndices;
-int TempEntityIndicesUsed;
-
-void
-CCullZones::ResolveVisibilities(void)
-{
- int fd;
-
- CFileMgr::SetDir("");
- fd = CFileMgr::OpenFile("DATA\\cullzone.dat", "rb");
- if(fd > 0){
- CFileMgr::Read(fd, (char*)&NumCullZones, sizeof(NumCullZones));
- CFileMgr::Read(fd, (char*)aZones, sizeof(aZones));
- CFileMgr::Read(fd, (char*)&NumAttributeZones, sizeof(NumAttributeZones));
- CFileMgr::Read(fd, (char*)aAttributeZones, sizeof(aAttributeZones));
- CFileMgr::Read(fd, (char*)aIndices, sizeof(aIndices));
- CFileMgr::Read(fd, (char*)aPointersToBigBuildingsForBuildings, sizeof(aPointersToBigBuildingsForBuildings));
- CFileMgr::Read(fd, (char*)aPointersToBigBuildingsForTreadables, sizeof(aPointersToBigBuildingsForTreadables));
- CFileMgr::CloseFile(fd);
- }else{
-#ifndef MASTER
- EntityIndicesUsed = 0;
- BuildListForBigBuildings();
- pTempArrayIndices = new uint16[NUMTEMPINDICES];
- TempEntityIndicesUsed = 0;
-
-// if(!LoadTempFile()) // not in final game
- {
- for (int i = 0; i < NumCullZones; i++) {
-//printf("testing zone %d (%d indices)\n", i, TempEntityIndicesUsed);
- DoVisibilityTestCullZone(i, true);
- }
-
-// SaveTempFile(); // not in final game
- }
-
- CompressIndicesArray();
- delete[] pTempArrayIndices;
- pTempArrayIndices = nil;
-
- fd = CFileMgr::OpenFileForWriting("data\\cullzone.dat");
- if (fd != 0) {
- CFileMgr::Write(fd, (char*)&NumCullZones, sizeof(NumCullZones));
- CFileMgr::Write(fd, (char*)aZones, sizeof(aZones));
- CFileMgr::Write(fd, (char*)&NumAttributeZones, sizeof(NumAttributeZones));
- CFileMgr::Write(fd, (char*)&aAttributeZones, sizeof(aAttributeZones));
- CFileMgr::Write(fd, (char*)&aIndices, sizeof(aIndices));
- CFileMgr::Write(fd, (char*)&aPointersToBigBuildingsForBuildings, sizeof(aPointersToBigBuildingsForBuildings));
- CFileMgr::Write(fd, (char*)&aPointersToBigBuildingsForTreadables, sizeof(aPointersToBigBuildingsForTreadables));
- CFileMgr::CloseFile(fd);
- }
-#endif
- }
-}
-
-bool
-CCullZones::LoadTempFile(void)
-{
- int fd = CFileMgr::OpenFile("cullzone.tmp");
- if (fd != 0) {
- CFileMgr::Read(fd, (char*)&NumCullZones, sizeof(NumCullZones));
- CFileMgr::Read(fd, (char*)aZones, sizeof(aZones));
- CFileMgr::Read(fd, (char*)&NumAttributeZones, sizeof(NumAttributeZones));
- CFileMgr::Read(fd, (char*)&aAttributeZones, sizeof(aAttributeZones));
- CFileMgr::Read(fd, (char*)pTempArrayIndices, NUMTEMPINDICES*sizeof(uint16));
- CFileMgr::Read(fd, (char*)&TempEntityIndicesUsed, sizeof(TempEntityIndicesUsed));
- CFileMgr::Read(fd, (char*)&aPointersToBigBuildingsForBuildings, sizeof(aPointersToBigBuildingsForBuildings));
- CFileMgr::Read(fd, (char*)&aPointersToBigBuildingsForTreadables, sizeof(aPointersToBigBuildingsForTreadables));
- CFileMgr::CloseFile(fd);
- return true;
- }
- return false;
-}
-
-void
-CCullZones::SaveTempFile(void)
-{
- int fd = CFileMgr::OpenFileForWriting("cullzone.tmp");
- if (fd != 0) {
- CFileMgr::Write(fd, (char*)&NumCullZones, sizeof(NumCullZones));
- CFileMgr::Write(fd, (char*)aZones, sizeof(aZones));
- CFileMgr::Write(fd, (char*)&NumAttributeZones, sizeof(NumAttributeZones));
- CFileMgr::Write(fd, (char*)&aAttributeZones, sizeof(aAttributeZones));
- CFileMgr::Write(fd, (char*)pTempArrayIndices, NUMTEMPINDICES*sizeof(uint16));
- CFileMgr::Write(fd, (char*)&TempEntityIndicesUsed, sizeof(TempEntityIndicesUsed));
- CFileMgr::Write(fd, (char*)&aPointersToBigBuildingsForBuildings, sizeof(aPointersToBigBuildingsForBuildings));
- CFileMgr::Write(fd, (char*)&aPointersToBigBuildingsForTreadables, sizeof(aPointersToBigBuildingsForTreadables));
- CFileMgr::CloseFile(fd);
- }
-}
-
-
-void
-CCullZones::BuildListForBigBuildings()
-{
- for (int i = CPools::GetBuildingPool()->GetSize()-1; i >= 0; i--) {
- CBuilding *building = CPools::GetBuildingPool()->GetSlot(i);
- if (building == nil || !building->bIsBIGBuilding) continue;
- CSimpleModelInfo *nonlod = ((CSimpleModelInfo *)CModelInfo::GetModelInfo(building->GetModelIndex()))->GetRelatedModel();
- if (nonlod == nil) continue;
-
- for (int j = CPools::GetBuildingPool()->GetSize()-1; j >= 0; j--) {
- CBuilding *building2 = CPools::GetBuildingPool()->GetSlot(j);
- if (building2 == nil || building2->bIsBIGBuilding) continue;
- if (CModelInfo::GetModelInfo(building2->GetModelIndex()) == nonlod) {
- if ((building2->GetPosition() - building->GetPosition()).Magnitude() < 5.0f) {
- aPointersToBigBuildingsForBuildings[j] = i;
- }
- }
- }
-
- for (int j = CPools::GetTreadablePool()->GetSize()-1; j >= 0; j--) {
- CTreadable *treadable = CPools::GetTreadablePool()->GetSlot(j);
- if (treadable == nil || treadable->bIsBIGBuilding) continue;
- if (CModelInfo::GetModelInfo(treadable->GetModelIndex()) == nonlod) {
- if ((treadable->GetPosition() - building->GetPosition()).Magnitude() < 5.0f) {
- aPointersToBigBuildingsForTreadables[j] = i;
- }
- }
- }
- }
-}
-
-void
-CCullZones::DoVisibilityTestCullZone(int zoneId, bool findIndices)
-{
- aZones[zoneId].m_groupIndexCount[0] = 0;
- aZones[zoneId].m_groupIndexCount[1] = 0;
- aZones[zoneId].m_groupIndexCount[2] = 0;
- aZones[zoneId].m_indexStart = TempEntityIndicesUsed;
- aZones[zoneId].FindTestPoints();
-
- if (!findIndices) return;
-
- for (int i = CPools::GetBuildingPool()->GetSize() - 1; i >= 0; i--) {
- CBuilding *building = CPools::GetBuildingPool()->GetSlot(i);
- if (building != nil && !building->bIsBIGBuilding && aZones[zoneId].IsEntityCloseEnoughToZone(building, aPointersToBigBuildingsForBuildings[i] != -1)) {
- CBuilding *LODbuilding = nil;
- if (aPointersToBigBuildingsForBuildings[i] != -1)
- LODbuilding = CPools::GetBuildingPool()->GetSlot(aPointersToBigBuildingsForBuildings[i]);
-
- if (!aZones[zoneId].TestEntityVisibilityFromCullZone(building, 0.0f, LODbuilding)) {
- assert(TempEntityIndicesUsed < NUMTEMPINDICES);
- pTempArrayIndices[TempEntityIndicesUsed++] = i;
- aZones[zoneId].m_groupIndexCount[0]++;
- }
- }
- }
-
- for (int i = CPools::GetTreadablePool()->GetSize() - 1; i >= 0; i--) {
- CBuilding* building = CPools::GetTreadablePool()->GetSlot(i);
- if (building != nil && aZones[zoneId].IsEntityCloseEnoughToZone(building, aPointersToBigBuildingsForTreadables[i] != -1)) {
- CBuilding *LODbuilding = nil;
- if (aPointersToBigBuildingsForTreadables[i] != -1)
- LODbuilding = CPools::GetBuildingPool()->GetSlot(aPointersToBigBuildingsForTreadables[i]);
-
- if (!aZones[zoneId].TestEntityVisibilityFromCullZone(building, 10.0f, LODbuilding)) {
- assert(TempEntityIndicesUsed < NUMTEMPINDICES);
- pTempArrayIndices[TempEntityIndicesUsed++] = i;
- aZones[zoneId].m_groupIndexCount[1]++;
- }
- }
- }
-
- for (int i = CPools::GetTreadablePool()->GetSize() - 1; i >= 0; i--) {
- CBuilding *building = CPools::GetTreadablePool()->GetSlot(i);
- if (building != nil && aZones[zoneId].CalcDistToCullZoneSquared(building->GetPosition().x, building->GetPosition().y) < SQR(200.0f)) {
- int start = aZones[zoneId].m_groupIndexCount[0] + aZones[zoneId].m_indexStart;
- int end = aZones[zoneId].m_groupIndexCount[1] + start;
-
- bool alreadyAdded = false;
-
- for (int k = start; k < end; k++) {
-#ifdef FIX_BUGS
- if (pTempArrayIndices[k] == i)
-#else
- if (aIndices[k] == i)
-#endif
- alreadyAdded = true;
- }
-
- if (!alreadyAdded) {
- CBuilding *LODbuilding = nil;
- if (aPointersToBigBuildingsForTreadables[i] != -1)
- LODbuilding = CPools::GetBuildingPool()->GetSlot(aPointersToBigBuildingsForTreadables[i]);
- if (!aZones[zoneId].TestEntityVisibilityFromCullZone(building, 0.0f, LODbuilding)) {
- assert(TempEntityIndicesUsed < NUMTEMPINDICES);
- pTempArrayIndices[TempEntityIndicesUsed++] = i;
- aZones[zoneId].m_groupIndexCount[2]++;
- }
- }
- }
- }
}
void
@@ -255,14 +35,10 @@ CCullZones::Update(void)
{
bool invisible;
- if(bCullZonesDisabled)
- return;
-
switch(CTimer::GetFrameCounter() & 7){
case 0:
case 4:
- /* Update Cull zone */
- ForceCullZoneCoors(TheCamera.GetGameCamPosition());
+ UpdateAtBeachForAudio();
break;
case 2:
@@ -283,31 +59,30 @@ CCullZones::Update(void)
}
}
-void
-CCullZones::ForceCullZoneCoors(CVector coors)
+// TODO? put somewhere else?
+bool
+IsPointWithinArbitraryArea(float px, float py, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4)
{
- int32 z;
- z = FindCullZoneForCoors(coors);
- if(z != OldCullZone){
- if(OldCullZone >= 0)
- aZones[OldCullZone].DoStuffLeavingZone();
- if(z >= 0)
- aZones[z].DoStuffEnteringZone();
- OldCullZone = z;
- }
+ if((px-x1)*(x2-x1) - (py-y1)*(y2-y1) < 0.0f) return false;
+ if((px-x2)*(x3-x2) - (py-y2)*(y3-y2) < 0.0f) return false;
+ if((px-x3)*(x4-x3) - (py-y3)*(y4-y3) < 0.0f) return false;
+ if((px-x4)*(x1-x4) - (py-y4)*(y1-y4) < 0.0f) return false;
+ return true;
}
-int32
-CCullZones::FindCullZoneForCoors(CVector coors)
+void
+CCullZones::UpdateAtBeachForAudio(void)
{
- int i;
+ bAtBeachForAudio = IsPointWithinArbitraryArea(TheCamera.GetPosition().x, TheCamera.GetPosition().y,
+ 400.0f, -1644.4f,
+ 751.9f, 1267.8f,
+ 971.9f, 1216.2f,
+ 840.0f, -1744.0f);
+}
- for(i = 0; i < NumCullZones; i++)
- if(coors.x >= aZones[i].minx && coors.x <= aZones[i].maxx &&
- coors.y >= aZones[i].miny && coors.y <= aZones[i].maxy &&
- coors.z >= aZones[i].minz && coors.z <= aZones[i].maxz)
- return i;
- return -1;
+void
+CCullZones::ForceCullZoneCoors(CVector coors)
+{
}
int32
@@ -382,1208 +157,16 @@ CCullZones::AddCullZone(CVector const &position,
float minz, float maxz,
uint16 flag, int16 wantedLevel)
{
- CCullZone *cull;
CAttributeZone *attrib;
- CVector v;
- if((flag & ATTRZONE_NOTCULLZONE) == 0){
- cull = &aZones[NumCullZones++];
- v = position;
- // reposition start point to the start/end of the
- // alley next to the big building in the industrial district.
- // probably isn't analyzed correctly otherwise?s
- if((v-CVector(1032.14f, -624.255f, 24.93f)).Magnitude() < 1.0f)
- v = CVector(1061.7f, -613.0f, 19.0f);
- if((v-CVector(1029.48f, -495.757f, 21.98f)).Magnitude() < 1.0f)
- v = CVector(1061.4f, -506.0f, 18.5f);
- cull->position.x = Clamp(v.x, minx, maxx);
- cull->position.y = Clamp(v.y, miny, maxy);
- cull->position.z = Clamp(v.z, minz, maxz);
- cull->minx = minx;
- cull->maxx = maxx;
- cull->miny = miny;
- cull->maxy = maxy;
- cull->minz = minz;
- cull->maxz = maxz;
- cull->m_groupIndexCount[0] = 0;
- cull->m_groupIndexCount[1] = 0;
- cull->m_groupIndexCount[2] = 0;
- cull->m_indexStart = 0;
- }
- if(flag & ~ATTRZONE_NOTCULLZONE){
- attrib = &aAttributeZones[NumAttributeZones++];
- attrib->minx = minx;
- attrib->maxx = maxx;
- attrib->miny = miny;
- attrib->maxy = maxy;
- attrib->minz = minz;
- attrib->maxz = maxz;
- attrib->attributes = flag;
- attrib->wantedLevel = wantedLevel;
- }
-}
-
-uint16 *pExtraArrayIndices;
-
-void
-CCullZones::CompressIndicesArray()
-{
- uint16 set[3];
-
- // These are used to hold the compressed groups in sets of 3
- int numExtraIndices = 0;
- pExtraArrayIndices = new uint16[NUMTEMPINDICES];
-
- for(int numOccurrences = 6; numOccurrences > 1; numOccurrences--){
- if(NumCullZones == 0)
- break;
-
-//printf("checking occurrences %d\n", numOccurrences);
- int attempt = 0;
- while(attempt < 10000){
- for(;;){
- attempt++;
-
- int zone = CGeneral::GetRandomNumber() % NumCullZones;
- int group = CGeneral::GetRandomNumber() % 3;
- if(!PickRandomSetForGroup(zone, group, set))
- break;
- if(!DoWeHaveMoreThanXOccurencesOfSet(numOccurrences, set))
- break;
-
- // add this set
- attempt = 1;
- int setId = numExtraIndices + NUMUNCOMPRESSED;
- pExtraArrayIndices[numExtraIndices++] = set[0];
- pExtraArrayIndices[numExtraIndices++] = set[1];
- pExtraArrayIndices[numExtraIndices++] = set[2];
- ReplaceSetForAllGroups(set, setId);
- }
- }
- }
-
- TidyUpAndMergeLists(pExtraArrayIndices, numExtraIndices);
-
- delete[] pExtraArrayIndices;
-}
-
-// Get three random indices for this group of a zone
-bool
-CCullZones::PickRandomSetForGroup(int32 zone, int32 group, uint16 *set)
-{
- int32 start;
- int32 size;
-
- aZones[zone].GetGroupStartAndSize(group, start, size);
- if(size <= 0)
- return false;
-
- int numIndices = 0;
- for(int i = 0; i < size; i++)
- if(pTempArrayIndices[start + i] != 0xFFFF)
- numIndices++;
- if(numIndices < 3)
- return false;
-
- int first = CGeneral::GetRandomNumber() % (numIndices-2);
-
- numIndices = 0;
- int n = 0;
- for(int i = 0; i < size; i++)
- if(pTempArrayIndices[start + i] != 0xFFFF){
- if(n++ < first) continue;
-
- set[numIndices++] = pTempArrayIndices[start + i];
- if(numIndices == 3)
- break;
- }
- return true;
-}
-
-bool
-CCullZones::DoWeHaveMoreThanXOccurencesOfSet(int32 count, uint16 *set)
-{
- int32 curCount;
- int32 start;
- int32 size;
-
- curCount = 0;
- for (int i = 0; i < NumCullZones; i++) {
- for (int group = 0; group < 3; group++) {
- aZones[i].GetGroupStartAndSize(group, start, size);
- if(size <= 0) continue;
-
- // check if the set is a subset of the group
- int n = 0;
- for (int j = 0; j < size; j++) {
- for (int k = 0; k < 3; k++) {
- if (pTempArrayIndices[start+j] == set[k])
- n++;
- }
- }
- // yes it is
- if(n == 3){
- curCount++;
- // check if we have seen this set often enough
- if(curCount >= count)
- return true;
- }
- }
- }
- return false;
-}
-
-void
-CCullZones::ReplaceSetForAllGroups(uint16 *set, uint16 setid)
-{
- int32 start;
- int32 size;
-
- for(int i = 0; i < NumCullZones; i++)
- for(int group = 0; group < 3; group++){
- aZones[i].GetGroupStartAndSize(group, start, size);
- if(size <= 0) continue;
-
- // check if the set is a subset of the group
- int n = 0;
- for(int j = 0; j < size; j++){
- for(int k = 0; k < 3; k++){
- if(pTempArrayIndices[start+j] == set[k])
- n++;
- }
- }
-
- // yes it is, so replace it
- if(n == 3){
- bool insertedSet = false;
- for(int j = 0; j < size; j++){
- for(int k = 0; k < 3; k++){
- // replace first element by set, invalidate others
- if(pTempArrayIndices[start+j] == set[k]){
- if(!insertedSet)
- pTempArrayIndices[start+j] = setid;
- else
- pTempArrayIndices[start+j] = 0xFFFF;
- insertedSet = true;
- }
- }
- }
- }
- }
-}
-
-void
-CCullZones::TidyUpAndMergeLists(uint16 *extraIndices, int32 numExtraIndices)
-{
- int numTempIndices = 0;
- for(int i = 0; i < TempEntityIndicesUsed; i++)
- if(pTempArrayIndices[i] != 0xFFFF)
- numTempIndices++;
-
- // Fix up zone ranges such that there are no holes
- for(int i = 0; i < NumCullZones; i++){
- int j;
- int start = 0;
- for(j = 0; j < aZones[i].m_indexStart; j++)
- if(pTempArrayIndices[j] != 0xFFFF)
- start++;
-
- aZones[i].m_indexStart = start;
- aZones[i].m_numBuildings = 0;
- aZones[i].m_numTreadablesPlus10m = 0;
- aZones[i].m_numTreadables = 0;
-
- for(int k = 0; k < aZones[i].m_groupIndexCount[0]; k++)
- if(pTempArrayIndices[j++] != 0xFFFF)
- aZones[i].m_numBuildings++;
- for(int k = 0; k < aZones[i].m_groupIndexCount[1]; k++)
- if(pTempArrayIndices[j++] != 0xFFFF)
- aZones[i].m_numTreadablesPlus10m++;
- for(int k = 0; k < aZones[i].m_groupIndexCount[2]; k++)
- if(pTempArrayIndices[j++] != 0xFFFF)
- aZones[i].m_numTreadables++;
- }
-
- // Now copy the actually used indices
- EntityIndicesUsed = 0;
- for(int i = 0; i < TempEntityIndicesUsed; i++)
- if(pTempArrayIndices[i] != 0xFFFF){
- assert(EntityIndicesUsed < NUMZONEINDICES);
- if(pTempArrayIndices[i] < NUMUNCOMPRESSED)
- aIndices[EntityIndicesUsed++] = pTempArrayIndices[i];
- else
- aIndices[EntityIndicesUsed++] = pTempArrayIndices[i] + numTempIndices;
- }
- for(int i = 0; i < numExtraIndices; i++)
- if(extraIndices[i] != 0xFFFF){
- assert(EntityIndicesUsed < NUMZONEINDICES);
- if(extraIndices[i] < NUMUNCOMPRESSED)
- aIndices[EntityIndicesUsed++] = extraIndices[i];
- else
- aIndices[EntityIndicesUsed++] = extraIndices[i] + numTempIndices;
- }
-}
-
-
-
-void
-CCullZone::DoStuffLeavingZone(void)
-{
- int i;
-
- for(i = 0; i < m_numBuildings; i++)
- DoStuffLeavingZone_OneBuilding(CCullZones::aIndices[m_indexStart + i]);
- for(; i < m_numBuildings + m_numTreadablesPlus10m + m_numTreadables ; i++)
- DoStuffLeavingZone_OneTreadableBoth(CCullZones::aIndices[m_indexStart + i]);
-}
-
-void
-CCullZone::DoStuffLeavingZone_OneBuilding(uint16 i)
-{
- int16 bb;
- int j;
-
-
- if(i < NUMUNCOMPRESSED){
- CPools::GetBuildingPool()->GetSlot(i)->bZoneCulled = false;
- bb = CCullZones::aPointersToBigBuildingsForBuildings[i];
- if(bb != -1)
- CPools::GetBuildingPool()->GetSlot(bb)->bZoneCulled = false;
- }else{
- i -= NUMUNCOMPRESSED;
- for(j = 0; j < 3; j++)
- DoStuffLeavingZone_OneBuilding(CCullZones::aIndices[i+j]);
- }
-}
-
-void
-CCullZone::DoStuffLeavingZone_OneTreadableBoth(uint16 i)
-{
- int16 bb;
- int j;
-
- if(i < NUMUNCOMPRESSED){
- CPools::GetTreadablePool()->GetSlot(i)->bZoneCulled = false;
- CPools::GetTreadablePool()->GetSlot(i)->bZoneCulled2 = false;
- bb = CCullZones::aPointersToBigBuildingsForTreadables[i];
- if(bb != -1)
- CPools::GetBuildingPool()->GetSlot(bb)->bZoneCulled = false;
- }else{
- i -= NUMUNCOMPRESSED;
- for(j = 0; j < 3; j++)
- DoStuffLeavingZone_OneTreadableBoth(CCullZones::aIndices[i+j]);
- }
-}
-
-void
-CCullZone::DoStuffEnteringZone(void)
-{
- int i;
-
- for(i = 0; i < m_numBuildings; i++)
- DoStuffEnteringZone_OneBuilding(CCullZones::aIndices[m_indexStart + i]);
- for(; i < m_numBuildings + m_numTreadablesPlus10m; i++)
- DoStuffEnteringZone_OneTreadablePlus10m(CCullZones::aIndices[m_indexStart + i]);
- for(; i < m_numBuildings + m_numTreadablesPlus10m + m_numTreadables; i++)
- DoStuffEnteringZone_OneTreadable(CCullZones::aIndices[m_indexStart + i]);
-}
-
-void
-CCullZone::DoStuffEnteringZone_OneBuilding(uint16 i)
-{
- int16 bb;
- int j;
-
- if(i < NUMUNCOMPRESSED){
- CPools::GetBuildingPool()->GetSlot(i)->bZoneCulled = true;
- bb = CCullZones::aPointersToBigBuildingsForBuildings[i];
- if(bb != -1)
- CPools::GetBuildingPool()->GetSlot(bb)->bZoneCulled = true;
- }else{
- i -= NUMUNCOMPRESSED;
- for(j = 0; j < 3; j++)
- DoStuffEnteringZone_OneBuilding(CCullZones::aIndices[i+j]);
- }
-}
-
-void
-CCullZone::DoStuffEnteringZone_OneTreadablePlus10m(uint16 i)
-{
- int16 bb;
- int j;
-
- if(i < NUMUNCOMPRESSED){
- CPools::GetTreadablePool()->GetSlot(i)->bZoneCulled = true;
- CPools::GetTreadablePool()->GetSlot(i)->bZoneCulled2 = true;
- bb = CCullZones::aPointersToBigBuildingsForTreadables[i];
- if(bb != -1)
- CPools::GetBuildingPool()->GetSlot(bb)->bZoneCulled = true;
- }else{
- i -= NUMUNCOMPRESSED;
- for(j = 0; j < 3; j++)
- DoStuffEnteringZone_OneTreadablePlus10m(CCullZones::aIndices[i+j]);
- }
-}
-
-void
-CCullZone::DoStuffEnteringZone_OneTreadable(uint16 i)
-{
- int16 bb;
- int j;
-
- if(i < NUMUNCOMPRESSED){
- CPools::GetTreadablePool()->GetSlot(i)->bZoneCulled = true;
- bb = CCullZones::aPointersToBigBuildingsForTreadables[i];
- if(bb != -1)
- CPools::GetBuildingPool()->GetSlot(bb)->bZoneCulled = true;
- }else{
- i -= NUMUNCOMPRESSED;
- for(j = 0; j < 3; j++)
- DoStuffEnteringZone_OneTreadable(CCullZones::aIndices[i+j]);
- }
-}
-
-float
-CCullZone::CalcDistToCullZoneSquared(float x, float y)
-{
- float rx, ry;
-
- if (x < minx) rx = sq(x - minx);
- else if (x > maxx) rx = sq(x - maxx);
- else rx = 0.0f;
-
- if (y < miny) ry = sq(y - miny);
- else if (y > maxy) ry = sq(y - maxy);
- else ry = 0.0f;
-
- return rx + ry;
-}
-
-bool
-CCullZone::TestLine(CVector vec1, CVector vec2)
-{
- CColPoint colPoint;
- CEntity *entity;
-
- if (CWorld::ProcessLineOfSight(vec1, vec2, colPoint, entity, true, false, false, false, false, true, false))
- return true;
- if (CWorld::ProcessLineOfSight(CVector(vec1.x + 0.05f, vec1.y, vec1.z), CVector(vec2.x + 0.05f, vec2.y, vec2.z), colPoint, entity, true, false, false, false, false, true, false))
- return true;
- if (CWorld::ProcessLineOfSight(CVector(vec1.x - 0.05f, vec1.y, vec1.z), CVector(vec2.x - 0.05f, vec2.y, vec2.z), colPoint, entity, true, false, false, false, false, true, false))
- return true;
- if (CWorld::ProcessLineOfSight(CVector(vec1.x, vec1.y + 0.05f, vec1.z), CVector(vec2.x, vec2.y + 0.05f, vec2.z), colPoint, entity, true, false, false, false, false, true, false))
- return true;
- if (CWorld::ProcessLineOfSight(CVector(vec1.x, vec1.y - 0.05f, vec1.z), CVector(vec2.x, vec2.y - 0.05f, vec2.z), colPoint, entity, true, false, false, false, false, true, false))
- return true;
- if (CWorld::ProcessLineOfSight(CVector(vec1.x, vec1.y, vec1.z + 0.05f), CVector(vec2.x, vec2.y, vec2.z + 0.05f), colPoint, entity, true, false, false, false, false, true, false))
- return true;
- return CWorld::ProcessLineOfSight(CVector(vec1.x, vec1.y, vec1.z - 0.05f), CVector(vec2.x, vec2.y, vec2.z - 0.05f), colPoint, entity, true, false, false, false, false, true, false);
-}
-
-bool
-CCullZone::DoThoroughLineTest(CVector start, CVector end, CEntity *testEntity)
-{
- CColPoint colPoint;
- CEntity *entity;
-
- if(CWorld::ProcessLineOfSight(start, end, colPoint, entity, true, false, false, false, false, true, false) &&
- testEntity != entity)
- return false;
-
- CVector side;
-#ifdef FIX_BUGS
- if(start.x != end.x || start.y != end.y)
-#else
- if(start.x != end.x && start.y != end.y)
-#endif
- side = CVector(0.0f, 0.0f, 1.0f);
- else
- side = CVector(1.0f, 0.0f, 0.0f);
- CVector up = CrossProduct(side, end - start);
- side = CrossProduct(up, end - start);
- side.Normalise();
- up.Normalise();
- side *= 0.1f;
- up *= 0.1f;
-
- if(CWorld::ProcessLineOfSight(start+side, end+side, colPoint, entity, true, false, false, false, false, true, false) &&
- testEntity != entity)
- return false;
- if(CWorld::ProcessLineOfSight(start-side, end-side, colPoint, entity, true, false, false, false, false, true, false) &&
- testEntity != entity)
- return false;
- if(CWorld::ProcessLineOfSight(start+up, end+up, colPoint, entity, true, false, false, false, false, true, false) &&
- testEntity != entity)
- return false;
- if(CWorld::ProcessLineOfSight(start-up, end-up, colPoint, entity, true, false, false, false, false, true, false) &&
- testEntity != entity)
- return false;
- return true;
-}
-
-bool
-CCullZone::IsEntityCloseEnoughToZone(CEntity *entity, bool checkLevel)
-{
- const CVector &pos = entity->GetPosition();
-
- CSimpleModelInfo *minfo = (CSimpleModelInfo*)CModelInfo::GetModelInfo(entity->GetModelIndex());
- float distToZone = CalcDistToCullZone(pos.x, pos.y);
- float lodDist;
- if (minfo->m_noFade)
- lodDist = minfo->GetLargestLodDistance() + STREAM_DISTANCE;
- else
- lodDist = minfo->GetLargestLodDistance() + STREAM_DISTANCE + FADE_DISTANCE;
-
- if (lodDist > distToZone) return true;
- if (!checkLevel) return false;
- CVector tempPos(minx, miny, minz);
- return CTheZones::GetLevelFromPosition(&pos) == CTheZones::GetLevelFromPosition(&tempPos);
-}
-
-bool
-CCullZone::PointFallsWithinZone(CVector pos, float radius)
-{
- if(minx - radius > pos.x ||
- maxx + radius < pos.x ||
- miny - radius > pos.y ||
- maxy + radius < pos.y ||
- minz - radius > pos.z ||
- maxz + radius < pos.z)
- return false;
- return true;
-}
-
-
-CVector ExtraFudgePointsCoors[] = {
- CVector(978.0f, -394.0f, 18.0f),
- CVector(1189.7f, -414.6f, 27.0f),
- CVector(978.8f, -391.0f, 19.0f),
- CVector(1199.0f, -502.3f, 28.0f),
- CVector(1037.0f, -391.9f, 18.4f),
- CVector(1140.0f, -608.7f, 16.0f),
- CVector(1051.0f, -26.0f, 11.0f),
- CVector(951.5f, -345.1f, 12.0f),
- CVector(958.2f, -394.6f, 16.0f),
- CVector(1036.5f, -390.0f, 15.2f),
- CVector(960.6f, -390.5f, 20.9f),
- CVector(1061.0f, -640.6f, 16.3f),
- CVector(1034.5f, -388.96f, 14.78f),
- CVector(1038.4f, -13.98f, 12.2f),
- CVector(1047.2f, -16.7f, 10.6f),
- CVector(1257.9f, -333.3f, 40.0f),
- CVector(885.6f, -424.9f, 17.0f),
- CVector(1127.5f, -795.8f, 17.7f),
- CVector(1133.0f, -716.0f, 19.0f),
- CVector(1125.0f, -694.0f, 18.5f),
- CVector(1125.0f, -670.0f, 16.3f),
- CVector(1051.6f, 36.3f, 17.9f),
- CVector(1054.6f, -11.4f, 15.0f),
- CVector(1058.9f, -278.0f, 15.0f),
- CVector(1059.4f, -261.0f, 10.9f),
- CVector(1051.5f, -638.5f, 16.5f),
- CVector(1058.2f, -643.4f, 15.5f),
- CVector(1058.2f, -643.4f, 18.0f),
- CVector(826.0f, -260.0f, 7.0f),
- CVector(826.0f, -260.0f, 11.0f),
- CVector(833.0f, -603.6f, 16.4f),
- CVector(833.0f, -603.6f, 20.0f),
- CVector(1002.0f, -318.5f, 10.5f),
- CVector(998.0f, -318.0f, 9.8f),
- CVector(1127.0f, -183.0f, 18.1f),
- CVector(1123.0f, -331.5f, 23.8f),
- CVector(1123.8f, -429.0f, 24.0f),
- CVector(1197.0f, -30.0f, 13.7f),
- CVector(1117.5f, -230.0f, 17.3f),
- CVector(1117.5f, -230.0f, 20.0f),
- CVector(1120.0f, -281.6f, 21.5f),
- CVector(1120.0f, -281.6f, 24.0f),
- CVector(1084.5f, -1022.7f, 17.0f),
- CVector(1071.5f, 5.4f, 4.6f),
- CVector(1177.2f, -215.7f, 27.6f),
- CVector(841.6f, -460.0f, 19.7f),
- CVector(874.8f, -456.6f, 16.6f),
- CVector(918.3f, -451.8f, 17.8f),
- CVector(844.0f, -495.7f, 16.7f),
- CVector(842.0f, -493.4f, 21.0f),
- CVector(1433.5f, -774.4f, 16.9f),
- CVector(1051.0f, -205.0f, 7.5f),
- CVector(885.5f, -425.6f, 15.6f),
- CVector(182.6f, -470.4f, 27.8f),
- CVector(132.5f, -930.2f, 29.0f),
- CVector(124.7f, -904.0f, 28.0f),
- CVector(-50.0f, -686.0f, 22.0f),
- CVector(-49.1f, -694.5f, 22.5f),
- CVector(1063.8f, -404.45f, 16.2f),
- CVector(1062.2f, -405.5f, 17.0f)
-};
-int32 NumTestPoints;
-int32 aTestPointsX[100];
-int32 aTestPointsY[100];
-int32 aTestPointsZ[100];
-CVector aTestPoints[100];
-int32 ElementsX, ElementsY, ElementsZ;
-float StepX, StepY, StepZ;
-int32 Memsize;
-uint8 *pMem;
-#define MEM(x, y, z) pMem[((x)*ElementsY + (y))*ElementsZ + (z)]
-#define FLAG_FREE 1
-#define FLAG_PROCESSED 2
-
-int32 MinValX, MaxValX;
-int32 MinValY, MaxValY;
-int32 MinValZ, MaxValZ;
-int32 Point1, Point2;
-int32 NewPointX, NewPointY, NewPointZ;
-
-
-void
-CCullZone::FindTestPoints()
-{
- static int CZNumber;
-
- NumTestPoints = 0;
- ElementsX = (maxx-minx) < 1.0f ? 2 : (maxx-minx)+1.0f;
- ElementsY = (maxy-miny) < 1.0f ? 2 : (maxy-miny)+1.0f;
- ElementsZ = (maxz-minz) < 1.0f ? 2 : (maxz-minz)+1.0f;
- if(ElementsX > 32) ElementsX = 32;
- if(ElementsY > 32) ElementsY = 32;
- if(ElementsZ > 32) ElementsZ = 32;
- Memsize = ElementsX * ElementsY * ElementsZ;
- StepX = (maxx-minx)/(ElementsX-1);
- StepY = (maxy-miny)/(ElementsY-1);
- StepZ = (maxz-minz)/(ElementsZ-1);
-
- pMem = new uint8[Memsize];
- memset(pMem, 0, Memsize);
-
- // indices of center
- int x = ElementsX * (position.x-minx)/(maxx-minx);
- x = Clamp(x, 0, ElementsX-1);
- int y = ElementsY * (position.y-miny)/(maxy-miny);
- y = Clamp(y, 0, ElementsY-1);
- int z = ElementsZ * (position.z-minz)/(maxz-minz);
- z = Clamp(z, 0, ElementsZ-1);
-
- // Mark which test points inside the zone are not occupied by buildings.
- // To do this, mark the start point as free and do a food fill.
-
- // NB: we just assume the start position is free here!
- MEM(x, y, z) |= FLAG_FREE;
- aTestPointsX[NumTestPoints] = x;
- aTestPointsY[NumTestPoints] = y;
- aTestPointsZ[NumTestPoints] = z;
- NumTestPoints++;
-
- bool notDoneYet;
- do{
- notDoneYet = false;
- for(x = 0; x < ElementsX; x++){
- for(y = 0; y < ElementsY; y++){
- for(z = 0; z < ElementsZ; z++){
- if(!(MEM(x, y, z) & FLAG_FREE) || MEM(x, y, z) & FLAG_PROCESSED)
- continue;
-
- float pX = x*StepX + minx;
- float pY = y*StepY + miny;
- float pZ = z*StepZ + minz;
-
- if(x > 0 && !(MEM(x-1, y, z) & (FLAG_FREE | FLAG_PROCESSED)) &&
- !TestLine(CVector(pX, pY, pZ), CVector(pX-StepX, pY, pZ)))
- MEM(x-1, y, z) |= FLAG_FREE;
- if(x < ElementsX-1 && !(MEM(x+1, y, z) & (FLAG_FREE | FLAG_PROCESSED)) &&
- !TestLine(CVector(pX, pY, pZ), CVector(pX+StepX, pY, pZ)))
- MEM(x+1, y, z) |= FLAG_FREE;
-
- if(y > 0 && !(MEM(x, y-1, z) & (FLAG_FREE | FLAG_PROCESSED)) &&
- !TestLine(CVector(pX, pY, pZ), CVector(pX, pY-StepY, pZ)))
- MEM(x, y-1, z) |= FLAG_FREE;
- if(y < ElementsY-1 && !(MEM(x, y+1, z) & (FLAG_FREE | FLAG_PROCESSED)) &&
- !TestLine(CVector(pX, pY, pZ), CVector(pX, pY+StepY, pZ)))
- MEM(x, y+1, z) |= FLAG_FREE;
-
- if(z > 0 && !(MEM(x, y, z-1) & (FLAG_FREE | FLAG_PROCESSED)) &&
- !TestLine(CVector(pX, pY, pZ), CVector(pX, pY, pZ-StepZ)))
- MEM(x, y, z-1) |= FLAG_FREE;
- if(z < ElementsZ-1 && !(MEM(x, y, z+1) & (FLAG_FREE | FLAG_PROCESSED)) &&
- !TestLine(CVector(pX, pY, pZ), CVector(pX, pY, pZ+StepZ)))
- MEM(x, y, z+1) |= FLAG_FREE;
-
- notDoneYet = true;
- MEM(x, y, z) |= FLAG_PROCESSED;
- }
- }
- }
- }while(notDoneYet);
-
- bool done;
-
- // Find bound planes of free space
-
- // increase x, bounds in y and z
- x = 0;
- do{
- done = false;
- int minA = 10000;
- int minB = 10000;
- int maxA = -10000;
- int maxB = -10000;
- for(y = 0; y < ElementsY; y++)
- for(z = 0; z < ElementsZ; z++)
- if(MEM(x, y, z) & FLAG_FREE){
- if(y + z < minA){
- minA = y + z;
- aTestPointsX[NumTestPoints] = x;
- aTestPointsY[NumTestPoints] = y;
- aTestPointsZ[NumTestPoints] = z;
- }
- if(y + z > maxA){
- maxA = y + z;
- aTestPointsX[NumTestPoints+1] = x;
- aTestPointsY[NumTestPoints+1] = y;
- aTestPointsZ[NumTestPoints+1] = z;
- }
- if(y - z < minB){
- minB = y - z;
- aTestPointsX[NumTestPoints+2] = x;
- aTestPointsY[NumTestPoints+2] = y;
- aTestPointsZ[NumTestPoints+2] = z;
- }
- if(y - z > maxB){
- maxB = y - z;
- aTestPointsX[NumTestPoints+3] = x;
- aTestPointsY[NumTestPoints+3] = y;
- aTestPointsZ[NumTestPoints+3] = z;
- }
- done = true;
- }
- x++;
- }while(!done);
- NumTestPoints += 4;
-
- // decrease x, bounds in y and z
- x = ElementsX-1;
- do{
- done = false;
- int minA = 10000;
- int minB = 10000;
- int maxA = -10000;
- int maxB = -10000;
- for(y = 0; y < ElementsY; y++)
- for(z = 0; z < ElementsZ; z++)
- if(MEM(x, y, z) & FLAG_FREE){
- if(y + z < minA){
- minA = y + z;
- aTestPointsX[NumTestPoints] = x;
- aTestPointsY[NumTestPoints] = y;
- aTestPointsZ[NumTestPoints] = z;
- }
- if(y + z > maxA){
- maxA = y + z;
- aTestPointsX[NumTestPoints+1] = x;
- aTestPointsY[NumTestPoints+1] = y;
- aTestPointsZ[NumTestPoints+1] = z;
- }
- if(y - z < minB){
- minB = y - z;
- aTestPointsX[NumTestPoints+2] = x;
- aTestPointsY[NumTestPoints+2] = y;
- aTestPointsZ[NumTestPoints+2] = z;
- }
- if(y - z > maxB){
- maxB = y - z;
- aTestPointsX[NumTestPoints+3] = x;
- aTestPointsY[NumTestPoints+3] = y;
- aTestPointsZ[NumTestPoints+3] = z;
- }
- done = true;
- }
- x--;
- }while(!done);
- NumTestPoints += 4;
-
- // increase y, bounds in x and z
- y = 0;
- do{
- done = false;
- int minA = 10000;
- int minB = 10000;
- int maxA = -10000;
- int maxB = -10000;
- for(x = 0; x < ElementsX; x++)
- for(z = 0; z < ElementsZ; z++)
- if(MEM(x, y, z) & FLAG_FREE){
- if(x + z < minA){
- minA = x + z;
- aTestPointsX[NumTestPoints] = x;
- aTestPointsY[NumTestPoints] = y;
- aTestPointsZ[NumTestPoints] = z;
- }
- if(x + z > maxA){
- maxA = x + z;
- aTestPointsX[NumTestPoints+1] = x;
- aTestPointsY[NumTestPoints+1] = y;
- aTestPointsZ[NumTestPoints+1] = z;
- }
- if(x - z < minB){
- minB = x - z;
- aTestPointsX[NumTestPoints+2] = x;
- aTestPointsY[NumTestPoints+2] = y;
- aTestPointsZ[NumTestPoints+2] = z;
- }
- if(x - z > maxB){
- maxB = x - z;
- aTestPointsX[NumTestPoints+3] = x;
- aTestPointsY[NumTestPoints+3] = y;
- aTestPointsZ[NumTestPoints+3] = z;
- }
- done = true;
- }
- y++;
- }while(!done);
- NumTestPoints += 4;
-
- // decrease y, bounds in x and z
- y = ElementsY-1;
- do{
- done = false;
- int minA = 10000;
- int minB = 10000;
- int maxA = -10000;
- int maxB = -10000;
- for(x = 0; x < ElementsX; x++)
- for(z = 0; z < ElementsZ; z++)
- if(MEM(x, y, z) & FLAG_FREE){
- if(x + z < minA){
- minA = x + z;
- aTestPointsX[NumTestPoints] = x;
- aTestPointsY[NumTestPoints] = y;
- aTestPointsZ[NumTestPoints] = z;
- }
- if(x + z > maxA){
- maxA = x + z;
- aTestPointsX[NumTestPoints+1] = x;
- aTestPointsY[NumTestPoints+1] = y;
- aTestPointsZ[NumTestPoints+1] = z;
- }
- if(x - z < minB){
- minB = x - z;
- aTestPointsX[NumTestPoints+2] = x;
- aTestPointsY[NumTestPoints+2] = y;
- aTestPointsZ[NumTestPoints+2] = z;
- }
- if(x - z > maxB){
- maxB = x - z;
- aTestPointsX[NumTestPoints+3] = x;
- aTestPointsY[NumTestPoints+3] = y;
- aTestPointsZ[NumTestPoints+3] = z;
- }
- done = true;
- }
- y--;
- }while(!done);
- NumTestPoints += 4;
-
- // increase z, bounds in x and y
- z = 0;
- do{
- done = false;
- int minA = 10000;
- int minB = 10000;
- int maxA = -10000;
- int maxB = -10000;
- for(x = 0; x < ElementsX; x++)
- for(y = 0; y < ElementsY; y++)
- if(MEM(x, y, z) & FLAG_FREE){
- if(x + y < minA){
- minA = x + y;
- aTestPointsX[NumTestPoints] = x;
- aTestPointsY[NumTestPoints] = y;
- aTestPointsZ[NumTestPoints] = z;
- }
- if(x + y > maxA){
- maxA = x + y;
- aTestPointsX[NumTestPoints+1] = x;
- aTestPointsY[NumTestPoints+1] = y;
- aTestPointsZ[NumTestPoints+1] = z;
- }
- if(x - y < minB){
- minB = x - y;
- aTestPointsX[NumTestPoints+2] = x;
- aTestPointsY[NumTestPoints+2] = y;
- aTestPointsZ[NumTestPoints+2] = z;
- }
- if(x - y > maxB){
- maxB = x - y;
- aTestPointsX[NumTestPoints+3] = x;
- aTestPointsY[NumTestPoints+3] = y;
- aTestPointsZ[NumTestPoints+3] = z;
- }
- done = true;
- }
- z++;
- }while(!done);
- NumTestPoints += 4;
-
- // decrease z, bounds in x and y
- z = ElementsZ-1;
- do{
- done = false;
- int minA = 10000;
- int minB = 10000;
- int maxA = -10000;
- int maxB = -10000;
- for(x = 0; x < ElementsX; x++)
- for(y = 0; y < ElementsY; y++)
- if(MEM(x, y, z) & FLAG_FREE){
- if(x + y < minA){
- minA = x + y;
- aTestPointsX[NumTestPoints] = x;
- aTestPointsY[NumTestPoints] = y;
- aTestPointsZ[NumTestPoints] = z;
- }
- if(x + y > maxA){
- maxA = x + y;
- aTestPointsX[NumTestPoints+1] = x;
- aTestPointsY[NumTestPoints+1] = y;
- aTestPointsZ[NumTestPoints+1] = z;
- }
- if(x - y < minB){
- minB = x - y;
- aTestPointsX[NumTestPoints+2] = x;
- aTestPointsY[NumTestPoints+2] = y;
- aTestPointsZ[NumTestPoints+2] = z;
- }
- if(x - y > maxB){
- maxB = x - y;
- aTestPointsX[NumTestPoints+3] = x;
- aTestPointsY[NumTestPoints+3] = y;
- aTestPointsZ[NumTestPoints+3] = z;
- }
- done = true;
- }
- z--;
- }while(!done);
- NumTestPoints += 4;
-
- // divide the axis aligned bounding planes into 4 and place some test points
-
- // x = 0 plane
- MinValY = 999999;
- MinValZ = 999999;
- MaxValY = 0;
- MaxValZ = 0;
- for(y = 0; y < ElementsY; y++)
- for(z = 0; z < ElementsZ; z++)
- if(MEM(0, y, z) & FLAG_FREE){
- if(y < MinValY) MinValY = y;
- if(z < MinValZ) MinValZ = z;
- if(y > MaxValY) MaxValY = y;
- if(z > MaxValZ) MaxValZ = z;
- }
- // pick 4 points in the found bounds and add new test points
- if(MaxValY != 0 && MaxValZ != 0)
- for(Point1 = 0; Point1 < 2; Point1++)
- for(Point2 = 0; Point2 < 2; Point2++){
- NewPointY = (Point1 + 0.5f)*(MaxValY - MinValY)*0.5f + MinValY;
- NewPointZ = (Point2 + 0.5f)*(MaxValZ - MinValZ)*0.5f + MinValZ;
- if(MEM(0, NewPointY, NewPointZ) & FLAG_FREE){
- aTestPointsX[NumTestPoints] = 0;
- aTestPointsY[NumTestPoints] = NewPointY;
- aTestPointsZ[NumTestPoints] = NewPointZ;
- NumTestPoints++;
- }
- }
-
- // x = ElementsX-1 plane
- MinValY = 999999;
- MinValZ = 999999;
- MaxValY = 0;
- MaxValZ = 0;
- for(y = 0; y < ElementsY; y++)
- for(z = 0; z < ElementsZ; z++)
- if(MEM(ElementsX-1, y, z) & FLAG_FREE){
- if(y < MinValY) MinValY = y;
- if(z < MinValZ) MinValZ = z;
- if(y > MaxValY) MaxValY = y;
- if(z > MaxValZ) MaxValZ = z;
- }
- // pick 4 points in the found bounds and add new test points
- if(MaxValY != 0 && MaxValZ != 0)
- for(Point1 = 0; Point1 < 2; Point1++)
- for(Point2 = 0; Point2 < 2; Point2++){
- NewPointY = (Point1 + 0.5f)*(MaxValY - MinValY)*0.5f + MinValY;
- NewPointZ = (Point2 + 0.5f)*(MaxValZ - MinValZ)*0.5f + MinValZ;
- if(MEM(ElementsX-1, NewPointY, NewPointZ) & FLAG_FREE){
- aTestPointsX[NumTestPoints] = ElementsX-1;
- aTestPointsY[NumTestPoints] = NewPointY;
- aTestPointsZ[NumTestPoints] = NewPointZ;
- NumTestPoints++;
- }
- }
-
- // y = 0 plane
- MinValX = 999999;
- MinValZ = 999999;
- MaxValX = 0;
- MaxValZ = 0;
- for(x = 0; x < ElementsX; x++)
- for(z = 0; z < ElementsZ; z++)
- if(MEM(x, 0, z) & FLAG_FREE){
- if(x < MinValX) MinValX = x;
- if(z < MinValZ) MinValZ = z;
- if(x > MaxValX) MaxValX = x;
- if(z > MaxValZ) MaxValZ = z;
- }
- // pick 4 points in the found bounds and add new test points
- if(MaxValX != 0 && MaxValZ != 0)
- for(Point1 = 0; Point1 < 2; Point1++)
- for(Point2 = 0; Point2 < 2; Point2++){
- NewPointX = (Point1 + 0.5f)*(MaxValX - MinValX)*0.5f + MinValX;
- NewPointZ = (Point2 + 0.5f)*(MaxValZ - MinValZ)*0.5f + MinValZ;
- if(MEM(NewPointX, 0, NewPointZ) & FLAG_FREE){
- aTestPointsX[NumTestPoints] = NewPointX;
- aTestPointsY[NumTestPoints] = 0;
- aTestPointsZ[NumTestPoints] = NewPointZ;
- NumTestPoints++;
- }
- }
-
- // y = ElementsY-1 plane
- MinValX = 999999;
- MinValZ = 999999;
- MaxValX = 0;
- MaxValZ = 0;
- for(x = 0; x < ElementsX; x++)
- for(z = 0; z < ElementsZ; z++)
- if(MEM(x, ElementsY-1, z) & FLAG_FREE){
- if(x < MinValX) MinValX = x;
- if(z < MinValZ) MinValZ = z;
- if(x > MaxValX) MaxValX = x;
- if(z > MaxValZ) MaxValZ = z;
- }
- // pick 4 points in the found bounds and add new test points
- if(MaxValX != 0 && MaxValZ != 0)
- for(Point1 = 0; Point1 < 2; Point1++)
- for(Point2 = 0; Point2 < 2; Point2++){
- NewPointX = (Point1 + 0.5f)*(MaxValX - MinValX)*0.5f + MinValX;
- NewPointZ = (Point2 + 0.5f)*(MaxValZ - MinValZ)*0.5f + MinValZ;
- if(MEM(NewPointX, ElementsY-1, NewPointZ) & FLAG_FREE){
- aTestPointsX[NumTestPoints] = NewPointX;
- aTestPointsY[NumTestPoints] = ElementsY-1;
- aTestPointsZ[NumTestPoints] = NewPointZ;
- NumTestPoints++;
- }
- }
-
- // z = 0 plane
- MinValX = 999999;
- MinValY = 999999;
- MaxValX = 0;
- MaxValY = 0;
- for(x = 0; x < ElementsX; x++)
- for(y = 0; y < ElementsY; y++)
- if(MEM(x, y, 0) & FLAG_FREE){
- if(x < MinValX) MinValX = x;
- if(y < MinValY) MinValY = y;
- if(x > MaxValX) MaxValX = x;
- if(y > MaxValY) MaxValY = y;
- }
- // pick 4 points in the found bounds and add new test points
- if(MaxValX != 0 && MaxValY != 0)
- for(Point1 = 0; Point1 < 2; Point1++)
- for(Point2 = 0; Point2 < 2; Point2++){
- NewPointX = (Point1 + 0.5f)*(MaxValX - MinValX)*0.5f + MinValX;
- NewPointY = (Point2 + 0.5f)*(MaxValY - MinValY)*0.5f + MinValY;
- if(MEM(NewPointX, NewPointY, 0) & FLAG_FREE){
- aTestPointsX[NumTestPoints] = NewPointX;
- aTestPointsY[NumTestPoints] = NewPointY;
- aTestPointsZ[NumTestPoints] = 0;
- NumTestPoints++;
- }
- }
-
- // z = ElementsZ-1 plane
- MinValX = 999999;
- MinValY = 999999;
- MaxValX = 0;
- MaxValY = 0;
- for(x = 0; x < ElementsX; x++)
- for(y = 0; y < ElementsY; y++)
- if(MEM(x, y, ElementsZ-1) & FLAG_FREE){
- if(x < MinValX) MinValX = x;
- if(y < MinValY) MinValY = y;
- if(x > MaxValX) MaxValX = x;
- if(y > MaxValY) MaxValY = y;
- }
- // pick 4 points in the found bounds and add new test points
- if(MaxValX != 0 && MaxValY != 0)
- for(Point1 = 0; Point1 < 2; Point1++)
- for(Point2 = 0; Point2 < 2; Point2++){
- NewPointX = (Point1 + 0.5f)*(MaxValX - MinValX)*0.5f + MinValX;
- NewPointY = (Point2 + 0.5f)*(MaxValY - MinValY)*0.5f + MinValY;
- if(MEM(NewPointX, NewPointY, ElementsZ-1) & FLAG_FREE){
- aTestPointsX[NumTestPoints] = NewPointX;
- aTestPointsY[NumTestPoints] = NewPointY;
- aTestPointsZ[NumTestPoints] = ElementsZ-1;
- NumTestPoints++;
- }
- }
-
- // add some hardcoded test points
- for(int i = 0; i < ARRAY_SIZE(ExtraFudgePointsCoors); i++)
- if(PointFallsWithinZone(ExtraFudgePointsCoors[i], 0.0f)){
- x = ElementsX * (ExtraFudgePointsCoors[i].x-minx)/(maxx-minx);
- y = ElementsY * (ExtraFudgePointsCoors[i].y-miny)/(maxy-miny);
- z = ElementsZ * (ExtraFudgePointsCoors[i].z-minz)/(maxz-minz);
- if(MEM(x, y, z) & FLAG_FREE){
- aTestPointsX[NumTestPoints] = x;
- aTestPointsY[NumTestPoints] = y;
- aTestPointsZ[NumTestPoints] = z;
- NumTestPoints++;
- }
- }
-
- // remove duplicate points
- for(int i = 0; i < NumTestPoints; i++)
- for(int j = i+1; j < NumTestPoints; j++)
- if(aTestPointsX[j] == aTestPointsX[i] &&
- aTestPointsY[j] == aTestPointsY[i] &&
- aTestPointsZ[j] == aTestPointsZ[i]){
- // get rid of [j]
- for(int k = j; k < NumTestPoints-1; k++){
- aTestPointsX[k] = aTestPointsX[k+1];
- aTestPointsY[k] = aTestPointsY[k+1];
- aTestPointsZ[k] = aTestPointsZ[k+1];
- }
- NumTestPoints--;
- }
-
- // convert points to floating point
- for(int i = 0; i < NumTestPoints; i++){
- aTestPoints[i].x = aTestPointsX[i]*StepX + minx;
- aTestPoints[i].y = aTestPointsY[i]*StepY + miny;
- aTestPoints[i].z = aTestPointsZ[i]*StepZ + minz;
- }
-
- CZNumber++;
-
- delete[] pMem;
- pMem = nil;
-}
-
-bool
-CCullZone::TestEntityVisibilityFromCullZone(CEntity *entity, float extraDist, CEntity *LODentity)
-{
- CColModel *colmodel = entity->GetColModel();
- float boundMaxX = colmodel->boundingBox.max.x;
- float boundMaxY = colmodel->boundingBox.max.y;
- float boundMaxZ = colmodel->boundingBox.max.z;
- float boundMinX = colmodel->boundingBox.min.x;
- float boundMinY = colmodel->boundingBox.min.y;
- float boundMinZ = colmodel->boundingBox.min.z;
- if(LODentity){
- colmodel = LODentity->GetColModel();
- boundMaxX = Max(boundMaxX, colmodel->boundingBox.max.x);
- boundMaxY = Max(boundMaxY, colmodel->boundingBox.max.y);
- boundMaxZ = Max(boundMaxZ, colmodel->boundingBox.max.z);
- boundMinX = Min(boundMinX, colmodel->boundingBox.min.x);
- boundMinY = Min(boundMinY, colmodel->boundingBox.min.y);
- boundMinZ = Min(boundMinZ, colmodel->boundingBox.min.z);
- }
-
- if(boundMaxZ-boundMinZ + extraDist < 0.5f)
- boundMaxZ = boundMinZ + 0.5f;
- else
- boundMaxZ += extraDist;
-
- CVector vecMin = entity->GetMatrix() * CVector(boundMinX, boundMinY, boundMinZ);
- CVector vecMaxX = entity->GetMatrix() * CVector(boundMaxX, boundMinY, boundMinZ);
- CVector vecMaxY = entity->GetMatrix() * CVector(boundMinX, boundMaxY, boundMinZ);
- CVector vecMaxZ = entity->GetMatrix() * CVector(boundMinX, boundMinY, boundMaxZ);
- CVector dirx = vecMaxX - vecMin;
- CVector diry = vecMaxY - vecMin;
- CVector dirz = vecMaxZ - vecMin;
-
- // If building intersects zone at all, it's visible
- int x, y, z;
- for(x = 0; x < 9; x++){
- CVector posX = vecMin + x/8.0f*dirx;
- for(y = 0; y < 9; y++){
- CVector posY = posX + y/8.0f*diry;
- for(z = 0; z < 9; z++){
- CVector posZ = posY + z/8.0f*dirz;
- if(PointFallsWithinZone(posZ, 2.0f))
- return true;
- }
- }
- }
-
- float distToZone = CalcDistToCullZone(entity->GetPosition().x, entity->GetPosition().y)/15.0f;
- distToZone = Max(distToZone, 7.0f);
- int numX = (boundMaxX - boundMinX)/distToZone + 2.0f;
- int numY = (boundMaxY - boundMinY)/distToZone + 2.0f;
- int numZ = (boundMaxZ - boundMinZ)/distToZone + 2.0f;
-
- float stepX = 1.0f/(numX-1);
- float stepY = 1.0f/(numY-1);
- float stepZ = 1.0f/(numZ-1);
- float midX = (boundMaxX + boundMinX)/2.0f;
- float midY = (boundMaxY + boundMinY)/2.0f;
- float midZ = (boundMaxZ + boundMinZ)/2.0f;
-
- // check both xy planes
- for(int i = 0; i < NumTestPoints; i++){
- CVector testPoint = aTestPoints[i];
- CVector mid = entity->GetMatrix() * CVector(midX, midY, midZ);
- mid.z += 0.1f;
- if(DoThoroughLineTest(testPoint, mid, entity))
- return true;
-
- CVector ray = entity->GetPosition() - testPoint;
-
- float dotX = DotProduct(ray, dirx);
- float dotY = DotProduct(ray, diry);
- float dotZ = DotProduct(ray, dirz);
-
- for(x = 0; x < numX; x++){
- CVector pMinZ = vecMin + x*stepX*dirx;
- CVector pMaxZ = vecMin + x*stepX*dirx + dirz;
- for(y = 0; y < numY; y++)
- if(dotZ > 0.0f){
- if(DoThoroughLineTest(testPoint, pMinZ + y*stepY*diry, entity))
- return true;
- }else{
- if(DoThoroughLineTest(testPoint, pMaxZ + y*stepY*diry, entity))
- return true;
- }
- }
-
- for(x = 0; x < numX; x++){
- CVector pMinY = vecMin + x*stepX*dirx;
- CVector pMaxY = vecMin + x*stepX*dirx + diry;
- for(z = 1; z < numZ-1; z++) // edge cases already handled
- if(dotY > 0.0f){
- if(DoThoroughLineTest(testPoint, pMinY + z*stepZ*dirz, entity))
- return true;
- }else{
- if(DoThoroughLineTest(testPoint, pMaxY + z*stepZ*dirz, entity))
- return true;
- }
- }
-
- for(y = 1; y < numY-1; y++){ // edge cases already handled
- CVector pMinX = vecMin + y*stepY*diry;
- CVector pMaxX = vecMin + y*stepY*diry + dirx;
- for(z = 1; z < numZ-1; z++) // edge cases already handled
- if(dotX > 0.0f){
- if(DoThoroughLineTest(testPoint, pMinX + z*stepZ*dirz, entity))
- return true;
- }else{
- if(DoThoroughLineTest(testPoint, pMaxX + z*stepZ*dirz, entity))
- return true;
- }
- }
- }
-
- return false;
+ assert(NumAttributeZones < NUMATTRIBZONES);
+ attrib = &aAttributeZones[NumAttributeZones++];
+ attrib->minx = minx;
+ attrib->maxx = maxx;
+ attrib->miny = miny;
+ attrib->maxy = maxy;
+ attrib->minz = minz;
+ attrib->maxz = maxz;
+ attrib->attributes = flag;
+ attrib->wantedLevel = wantedLevel;
}
diff --git a/src/core/ZoneCull.h b/src/core/ZoneCull.h
index 10742ffb..d7780caf 100644
--- a/src/core/ZoneCull.h
+++ b/src/core/ZoneCull.h
@@ -1,62 +1,5 @@
class CEntity;
-class CCullZone
-{
-public:
- CVector position;
- float minx;
- float maxx;
- float miny;
- float maxy;
- float minz;
- float maxz;
-
- int32 m_indexStart;
- int16 m_groupIndexCount[3]; // only useful during resolution stage
- int16 m_numBuildings;
- int16 m_numTreadablesPlus10m;
- int16 m_numTreadables;
-
- void DoStuffLeavingZone(void);
- static void DoStuffLeavingZone_OneBuilding(uint16 i);
- static void DoStuffLeavingZone_OneTreadableBoth(uint16 i);
- void DoStuffEnteringZone(void);
- static void DoStuffEnteringZone_OneBuilding(uint16 i);
- static void DoStuffEnteringZone_OneTreadablePlus10m(uint16 i);
- static void DoStuffEnteringZone_OneTreadable(uint16 i);
-
-
- static bool TestLine(CVector vec1, CVector vec2);
- static bool DoThoroughLineTest(CVector vec1, CVector vec2, CEntity *testEntity);
- float CalcDistToCullZoneSquared(float x, float y);
- float CalcDistToCullZone(float x, float y) { return Sqrt(CalcDistToCullZoneSquared(x, y)); };
- bool IsEntityCloseEnoughToZone(CEntity* entity, bool checkLevel);
- bool PointFallsWithinZone(CVector pos, float radius);
- bool TestEntityVisibilityFromCullZone(CEntity *entity, float extraDist, CEntity *LODentity);
- void FindTestPoints();
-
- void GetGroupStartAndSize(int32 groupid, int32 &start, int32 &size) {
- switch (groupid) {
- case 0:
- default:
- // buildings
- start = m_indexStart;
- size = m_groupIndexCount[0];
- break;
- case 1:
- // treadables + 10m
- start = m_groupIndexCount[0] + m_indexStart;
- size = m_groupIndexCount[1];
- break;
- case 2:
- // treadables
- start = m_groupIndexCount[0] + m_groupIndexCount[1] + m_indexStart;
- size = m_groupIndexCount[2];
- break;
- }
- }
-};
-
enum eZoneAttribs
{
ATTRZONE_CAMCLOSEIN = 1,
@@ -67,16 +10,19 @@ enum eZoneAttribs
ATTRZONE_NOTCULLZONE = 0x20,
ATTRZONE_DOINEEDCOLLISION = 0x40,
ATTRZONE_SUBWAYVISIBLE = 0x80,
+ ATTRZONE_POLICEABANDONCARS = 0x100,
+ ATTRZONE_ROOMFORAUDIO = 0x200,
+ ATTRZONE_WATERFUDGE = 0x400,
};
struct CAttributeZone
{
- float minx;
- float maxx;
- float miny;
- float maxy;
- float minz;
- float maxz;
+ int16 minx;
+ int16 maxx;
+ int16 miny;
+ int16 maxy;
+ int16 minz;
+ int16 maxz;
int16 attributes;
int16 wantedLevel;
};
@@ -84,27 +30,19 @@ struct CAttributeZone
class CCullZones
{
public:
- static int32 NumCullZones;
- static CCullZone aZones[NUMCULLZONES];
static int32 NumAttributeZones;
static CAttributeZone aAttributeZones[NUMATTRIBZONES];
- static uint16 aIndices[NUMZONEINDICES];
- static int16 aPointersToBigBuildingsForBuildings[NUMBUILDINGS];
- static int16 aPointersToBigBuildingsForTreadables[NUMTREADABLES];
static int32 CurrentWantedLevelDrop_Player;
static int32 CurrentFlags_Camera;
static int32 CurrentFlags_Player;
- static int32 OldCullZone;
- static int32 EntityIndicesUsed;
static bool bCurrentSubwayIsInvisible;
- static bool bCullZonesDisabled;
+ static bool bAtBeachForAudio;
static void Init(void);
- static void ResolveVisibilities(void);
static void Update(void);
+ static void UpdateAtBeachForAudio(void);
static void ForceCullZoneCoors(CVector coors);
- static int32 FindCullZoneForCoors(CVector coors);
static int32 FindAttributesForCoors(CVector coors, int32 *wantedLevel);
static CAttributeZone *FindZoneWithStairsAttributeForPlayer(void);
static void MarkSubwayAsInvisible(bool visible);
@@ -120,18 +58,8 @@ public:
static bool DoINeedToLoadCollision(void) { return (CurrentFlags_Player & ATTRZONE_DOINEEDCOLLISION) != 0; }
static bool PlayerNoRain(void) { return (CurrentFlags_Player & ATTRZONE_NORAIN) != 0; }
static bool CamNoRain(void) { return (CurrentFlags_Camera & ATTRZONE_NORAIN) != 0; }
+ static bool PoliceAbandonCars(void) { return (CurrentFlags_Camera & ATTRZONE_POLICEABANDONCARS) != 0; }
+ static bool InRoomForAudio(void) { return (CurrentFlags_Camera & ATTRZONE_ROOMFORAUDIO) != 0; }
+ static bool WaterFudge(void) { return (CurrentFlags_Camera & ATTRZONE_WATERFUDGE) != 0; }
static int32 GetWantedLevelDrop(void) { return CurrentWantedLevelDrop_Player; }
-
- static void BuildListForBigBuildings();
- static void DoVisibilityTestCullZone(int zoneId, bool doIt);
- static bool DoWeHaveMoreThanXOccurencesOfSet(int32 count, uint16 *set);
-
- static void CompressIndicesArray();
- static bool PickRandomSetForGroup(int32 zone, int32 group, uint16 *set);
- static void ReplaceSetForAllGroups(uint16 *set, uint16 setid);
- static void TidyUpAndMergeLists(uint16 *extraIndices, int32 numExtraIndices);
-
- // debug
- static bool LoadTempFile(void);
- static void SaveTempFile(void);
};
diff --git a/src/core/Zones.cpp b/src/core/Zones.cpp
index 82fbc047..93eca199 100644
--- a/src/core/Zones.cpp
+++ b/src/core/Zones.cpp
@@ -10,51 +10,22 @@
#include "Timer.h"
#include "SaveBuf.h"
-#ifdef COMPATIBLE_SAVES
-#define ZONEARRAY_SAVE_SIZE 0xAF0
-#define MAPZONEARRAY_SAVE_SIZE 0x578
-#else
-#define ZONEARRAY_SAVE_SIZE sizeof(ZoneArray)
-#define MAPZONEARRAY_SAVE_SIZE sizeof(MapZoneArray)
-#endif
-
eLevelName CTheZones::m_CurrLevel;
-CZone *CTheZones::m_pPlayersZone;
int16 CTheZones::FindIndex;
uint16 CTheZones::NumberOfAudioZones;
int16 CTheZones::AudioZoneArray[NUMAUDIOZONES];
uint16 CTheZones::TotalNumberOfMapZones;
-uint16 CTheZones::TotalNumberOfZones;
-CZone CTheZones::ZoneArray[NUMZONES];
+uint16 CTheZones::TotalNumberOfInfoZones;
+uint16 CTheZones::TotalNumberOfNavigationZones;
+CZone CTheZones::InfoZoneArray[NUMINFOZONES];
CZone CTheZones::MapZoneArray[NUMMAPZONES];
+CZone CTheZones::NavigationZoneArray[NUMNAVIGZONES];
uint16 CTheZones::TotalNumberOfZoneInfos;
-CZoneInfo CTheZones::ZoneInfoArray[2*NUMZONES];
-
-#define SWAPF(a, b) { float t; t = a; a = b; b = t; }
+CZoneInfo CTheZones::ZoneInfoArray[2*NUMINFOZONES];
-inline bool IsNormalZone(int type) { return type == ZONE_DEFAULT || type == ZONE_NAVIG || type == ZONE_INFO; }
-static void
-CheckZoneInfo(CZoneInfo *info)
-{
- assert(info->carThreshold[0] >= 0);
- assert(info->carThreshold[0] <= info->carThreshold[1]);
- assert(info->carThreshold[1] <= info->carThreshold[2]);
- assert(info->carThreshold[2] <= info->carThreshold[3]);
- assert(info->carThreshold[3] <= info->carThreshold[4]);
- assert(info->carThreshold[4] <= info->carThreshold[5]);
- assert(info->carThreshold[5] <= info->copThreshold);
- assert(info->copThreshold <= info->gangThreshold[0]);
- assert(info->gangThreshold[0] <= info->gangThreshold[1]);
- assert(info->gangThreshold[1] <= info->gangThreshold[2]);
- assert(info->gangThreshold[2] <= info->gangThreshold[3]);
- assert(info->gangThreshold[3] <= info->gangThreshold[4]);
- assert(info->gangThreshold[4] <= info->gangThreshold[5]);
- assert(info->gangThreshold[5] <= info->gangThreshold[6]);
- assert(info->gangThreshold[6] <= info->gangThreshold[7]);
- assert(info->gangThreshold[7] <= info->gangThreshold[8]);
-}
+#define SWAPF(a, b) { float t; t = a; a = b; b = t; }
wchar*
CZone::GetTranslatedName(void)
@@ -65,66 +36,89 @@ CZone::GetTranslatedName(void)
void
CTheZones::Init(void)
{
- int i;
+ int i, j;
for(i = 0; i < NUMAUDIOZONES; i++)
AudioZoneArray[i] = -1;
NumberOfAudioZones = 0;
- for(i = 0; i < NUMZONES; i++)
- memset(&ZoneArray[i], 0, sizeof(CZone));
-
- CZoneInfo *zonei;
- int x = 1000/6;
- for(i = 0; i < 2*NUMZONES; i++){
- zonei = &ZoneInfoArray[i];
- zonei->carDensity = 10;
- zonei->carThreshold[0] = x;
- zonei->carThreshold[1] = zonei->carThreshold[0] + x;
- zonei->carThreshold[2] = zonei->carThreshold[1] + x;
- zonei->carThreshold[3] = zonei->carThreshold[2] + x;
- zonei->carThreshold[4] = zonei->carThreshold[3];
- zonei->carThreshold[5] = zonei->carThreshold[4];
- zonei->copThreshold = zonei->carThreshold[5] + x;
- zonei->gangThreshold[0] = zonei->copThreshold;
- zonei->gangThreshold[1] = zonei->gangThreshold[0];
- zonei->gangThreshold[2] = zonei->gangThreshold[1];
- zonei->gangThreshold[3] = zonei->gangThreshold[2];
- zonei->gangThreshold[4] = zonei->gangThreshold[3];
- zonei->gangThreshold[5] = zonei->gangThreshold[4];
- zonei->gangThreshold[6] = zonei->gangThreshold[5];
- zonei->gangThreshold[7] = zonei->gangThreshold[6];
- zonei->gangThreshold[8] = zonei->gangThreshold[7];
- CheckZoneInfo(zonei);
+ for(i = 0; i < NUMNAVIGZONES; i++)
+ memset(&NavigationZoneArray[i], 0, sizeof(CZone));
+
+ for(i = 0; i < NUMINFOZONES; i++)
+ memset(&InfoZoneArray[i], 0, sizeof(CZone));
+
+ int x = 1000/9;
+ for(i = 0; i < 2*NUMINFOZONES; i++){
+ // Cars
+
+ ZoneInfoArray[i].carDensity = 10;
+ ZoneInfoArray[i].carThreshold[0] = x;
+ ZoneInfoArray[i].carThreshold[1] = ZoneInfoArray[i].carThreshold[0] + x;
+ ZoneInfoArray[i].carThreshold[2] = ZoneInfoArray[i].carThreshold[1] + x;
+ ZoneInfoArray[i].carThreshold[3] = ZoneInfoArray[i].carThreshold[2] + x;
+ ZoneInfoArray[i].carThreshold[4] = ZoneInfoArray[i].carThreshold[3] + x;
+ ZoneInfoArray[i].carThreshold[5] = ZoneInfoArray[i].carThreshold[4] + x;
+ ZoneInfoArray[i].carThreshold[6] = ZoneInfoArray[i].carThreshold[5] + x;
+ ZoneInfoArray[i].carThreshold[7] = ZoneInfoArray[i].carThreshold[6] + x;
+ ZoneInfoArray[i].carThreshold[8] = 1000;
+
+ ZoneInfoArray[i].boatThreshold[0] = 500;
+ ZoneInfoArray[i].boatThreshold[1] = 1000;
+
+ // What's going on here? this looks more like density
+ ZoneInfoArray[i].copThreshold = 50;
+ for(j = 0; j < NUM_GANGS; j++)
+ ZoneInfoArray[i].gangThreshold[j] = ZoneInfoArray[i].copThreshold;
+
+ // Peds
+
+ ZoneInfoArray[i].pedDensity = 12;
+
+ // What's going on here? this looks more like density
+ ZoneInfoArray[i].copPedThreshold = 50;
+ for(j = 0; j < NUM_GANGS; j++)
+ ZoneInfoArray[i].gangPedThreshold[j] = ZoneInfoArray[i].copPedThreshold;
+
+ ZoneInfoArray[i].pedGroup = 0;
}
TotalNumberOfZoneInfos = 1; // why 1?
- TotalNumberOfZones = 1;
+ TotalNumberOfNavigationZones = 1;
+ TotalNumberOfInfoZones = 1;
+
+ strcpy(InfoZoneArray[0].name, "CITYINF");
+ InfoZoneArray[0].minx = -2400.0f;
+ InfoZoneArray[0].miny = -2000.0f;
+ InfoZoneArray[0].minz = -500.0f;
+ InfoZoneArray[0].maxx = 1600.0f;
+ InfoZoneArray[0].maxy = 2000.0f;
+ InfoZoneArray[0].maxz = 500.0f;
+ InfoZoneArray[0].level = LEVEL_GENERIC;
+ InfoZoneArray[0].type = ZONE_INFO;
+
+ strcpy(NavigationZoneArray[0].name, "VICE_C");
+ NavigationZoneArray[0].minx = -2400.0f;
+ NavigationZoneArray[0].miny = -2000.0f;
+ NavigationZoneArray[0].minz = -500.0f;
+ NavigationZoneArray[0].maxx = 1600.0f;
+ NavigationZoneArray[0].maxy = 2000.0f;
+ NavigationZoneArray[0].maxz = 500.0f;
+ NavigationZoneArray[0].level = LEVEL_GENERIC;
+ NavigationZoneArray[0].type = ZONE_DEFAULT;
m_CurrLevel = LEVEL_GENERIC;
- m_pPlayersZone = &ZoneArray[0];
-
- strcpy(ZoneArray[0].name, "CITYZON");
- ZoneArray[0].minx = -4000.0f;
- ZoneArray[0].miny = -4000.0f;
- ZoneArray[0].minz = -500.0f;
- ZoneArray[0].maxx = 4000.0f;
- ZoneArray[0].maxy = 4000.0f;
- ZoneArray[0].maxz = 500.0f;
- ZoneArray[0].level = LEVEL_GENERIC;
for(i = 0; i < NUMMAPZONES; i++){
memset(&MapZoneArray[i], 0, sizeof(CZone));
MapZoneArray[i].type = ZONE_MAPZONE;
}
-
TotalNumberOfMapZones = 1;
-
strcpy(MapZoneArray[0].name, "THEMAP");
- MapZoneArray[0].minx = -4000.0f;
- MapZoneArray[0].miny = -4000.0f;
+ MapZoneArray[0].minx = -2400.0f;
+ MapZoneArray[0].miny = -2000.0f;
MapZoneArray[0].minz = -500.0f;
- MapZoneArray[0].maxx = 4000.0f;
- MapZoneArray[0].maxy = 4000.0f;
+ MapZoneArray[0].maxx = 1600.0f;
+ MapZoneArray[0].maxy = 2000.0f;
MapZoneArray[0].maxz = 500.0f;
MapZoneArray[0].level = LEVEL_GENERIC;
}
@@ -138,7 +132,6 @@ CTheZones::Update(void)
#endif
CVector pos;
pos = FindPlayerCoors();
- m_pPlayersZone = FindSmallestZonePosition(&pos);
m_CurrLevel = GetLevelFromPosition(&pos);
}
@@ -148,8 +141,8 @@ CTheZones::CreateZone(char *name, eZoneType type,
float maxx, float maxy, float maxz,
eLevelName level)
{
+ char tmpname[24];
char *p;
- char tmpname[8];
if(minx > maxx) SWAPF(minx, maxx);
if(miny > maxy) SWAPF(miny, maxy);
@@ -158,62 +151,81 @@ CTheZones::CreateZone(char *name, eZoneType type,
// make upper case
for(p = name; *p; p++) if(islower(*p)) *p = toupper(*p);
- // add zone
strncpy(tmpname, name, 7);
tmpname[7] = '\0';
- strcpy(ZoneArray[TotalNumberOfZones].name, tmpname);
- ZoneArray[TotalNumberOfZones].type = type;
- ZoneArray[TotalNumberOfZones].minx = minx;
- ZoneArray[TotalNumberOfZones].miny = miny;
- ZoneArray[TotalNumberOfZones].minz = minz;
- ZoneArray[TotalNumberOfZones].maxx = maxx;
- ZoneArray[TotalNumberOfZones].maxy = maxy;
- ZoneArray[TotalNumberOfZones].maxz = maxz;
- ZoneArray[TotalNumberOfZones].level = level;
- if(IsNormalZone(type)){
- ZoneArray[TotalNumberOfZones].zoneinfoDay = TotalNumberOfZoneInfos++;
- ZoneArray[TotalNumberOfZones].zoneinfoNight = TotalNumberOfZoneInfos++;
- }
- TotalNumberOfZones++;
-}
-
-void
-CTheZones::CreateMapZone(char *name, eZoneType type,
- float minx, float miny, float minz,
- float maxx, float maxy, float maxz,
- eLevelName level)
-{
- CZone *zone;
- char *p;
-
- if(minx > maxx) SWAPF(minx, maxx);
- if(miny > maxy) SWAPF(miny, maxy);
- if(minz > maxz) SWAPF(minz, maxz);
-
- // make upper case
- for(p = name; *p; p++) if(islower(*p)) *p = toupper(*p);
// add zone
- zone = &MapZoneArray[TotalNumberOfMapZones++];
- strncpy(zone->name, name, 7);
- zone->name[7] = '\0';
- zone->type = type;
- zone->minx = minx;
- zone->miny = miny;
- zone->minz = minz;
- zone->maxx = maxx;
- zone->maxy = maxy;
- zone->maxz = maxz;
- zone->level = level;
+ switch(type){
+ case ZONE_DEFAULT:
+ case ZONE_NAVIG:
+ assert(TotalNumberOfNavigationZones < NUMNAVIGZONES);
+ strcpy(NavigationZoneArray[TotalNumberOfNavigationZones].name, tmpname);
+ NavigationZoneArray[TotalNumberOfNavigationZones].type = type;
+ NavigationZoneArray[TotalNumberOfNavigationZones].minx = minx;
+ NavigationZoneArray[TotalNumberOfNavigationZones].miny = miny;
+ NavigationZoneArray[TotalNumberOfNavigationZones].minz = minz;
+ NavigationZoneArray[TotalNumberOfNavigationZones].maxx = maxx;
+ NavigationZoneArray[TotalNumberOfNavigationZones].maxy = maxy;
+ NavigationZoneArray[TotalNumberOfNavigationZones].maxz = maxz;
+ NavigationZoneArray[TotalNumberOfNavigationZones].level = level;
+ TotalNumberOfNavigationZones++;
+ break;
+ case ZONE_INFO:
+ assert(TotalNumberOfInfoZones < NUMINFOZONES);
+ strcpy(InfoZoneArray[TotalNumberOfInfoZones].name, tmpname);
+ InfoZoneArray[TotalNumberOfInfoZones].type = type;
+ InfoZoneArray[TotalNumberOfInfoZones].minx = minx;
+ InfoZoneArray[TotalNumberOfInfoZones].miny = miny;
+ InfoZoneArray[TotalNumberOfInfoZones].minz = minz;
+ InfoZoneArray[TotalNumberOfInfoZones].maxx = maxx;
+ InfoZoneArray[TotalNumberOfInfoZones].maxy = maxy;
+ InfoZoneArray[TotalNumberOfInfoZones].maxz = maxz;
+ InfoZoneArray[TotalNumberOfInfoZones].level = level;
+ InfoZoneArray[TotalNumberOfInfoZones].zoneinfoDay = TotalNumberOfZoneInfos++;
+ InfoZoneArray[TotalNumberOfInfoZones].zoneinfoNight = TotalNumberOfZoneInfos++;
+ TotalNumberOfInfoZones++;
+ break;
+ case ZONE_MAPZONE:
+ assert(TotalNumberOfMapZones < NUMMAPZONES);
+ strcpy(MapZoneArray[TotalNumberOfMapZones].name, tmpname);
+ MapZoneArray[TotalNumberOfMapZones].type = type;
+ MapZoneArray[TotalNumberOfMapZones].minx = minx;
+ MapZoneArray[TotalNumberOfMapZones].miny = miny;
+ MapZoneArray[TotalNumberOfMapZones].minz = minz;
+ MapZoneArray[TotalNumberOfMapZones].maxx = maxx;
+ MapZoneArray[TotalNumberOfMapZones].maxy = maxy;
+ MapZoneArray[TotalNumberOfMapZones].maxz = maxz;
+ MapZoneArray[TotalNumberOfMapZones].level = level;
+ TotalNumberOfMapZones++;
+ break;
+ }
}
void
CTheZones::PostZoneCreation(void)
{
int i;
- for(i = 1; i < TotalNumberOfZones; i++)
- InsertZoneIntoZoneHierarchy(&ZoneArray[i]);
+ for(i = 1; i < TotalNumberOfNavigationZones; i++)
+ InsertZoneIntoZoneHierarchy(&NavigationZoneArray[i]);
InitialiseAudioZoneArray();
+#ifndef MASTER
+ CheckZonesForOverlap();
+#endif
+}
+
+void
+CTheZones::CheckZonesForOverlap(void)
+{
+ int i, j;
+ char str[116];
+
+ for(i = 1; i < TotalNumberOfInfoZones; i++){
+ ZoneIsEntirelyContainedWithinOtherZone(&InfoZoneArray[i], &InfoZoneArray[0]);
+
+ for(j = 1; j < TotalNumberOfInfoZones; j++)
+ if(i != j && ZoneIsEntirelyContainedWithinOtherZone(&InfoZoneArray[i], &InfoZoneArray[j]))
+ sprintf(str, "Info zone %s contains %s\n", InfoZoneArray[j].name, InfoZoneArray[i].name);
+ }
}
void
@@ -222,7 +234,7 @@ CTheZones::InsertZoneIntoZoneHierarchy(CZone *zone)
zone->child = nil;
zone->parent = nil;
zone->next = nil;
- InsertZoneIntoZoneHierRecursive(zone, &ZoneArray[0]);
+ InsertZoneIntoZoneHierRecursive(zone, &NavigationZoneArray[0]);
}
bool
@@ -314,34 +326,32 @@ CTheZones::GetLevelFromPosition(CVector const *v)
}
CZone*
-CTheZones::FindSmallestZonePosition(const CVector *v)
+CTheZones::FindInformationZoneForPosition(const CVector *v)
{
- CZone *best = &ZoneArray[0];
- // zone to test next
- CZone *zone = ZoneArray[0].child;
- while(zone)
- // if in zone, descent into children
- if(PointLiesWithinZone(v, zone)){
- best = zone;
- zone = zone->child;
- // otherwise try next zone
- }else
- zone = zone->next;
- return best;
+ int i;
+// char tmp[116];
+// if(!PointLiesWithinZone(v, &InfoZoneArray[0]))
+// sprintf(tmp, "x = %.3f y= %.3f z = %.3f\n", v.x, v.y, v.z);
+ for(i = 1; i < TotalNumberOfInfoZones; i++)
+ if(PointLiesWithinZone(v, &InfoZoneArray[i]))
+ return &InfoZoneArray[i];
+ return &InfoZoneArray[0];
}
CZone*
-CTheZones::FindSmallestZonePositionType(const CVector *v, eZoneType type)
+CTheZones::FindSmallestNavigationZoneForPosition(const CVector *v, bool findDefault, bool findNavig)
{
CZone *best = nil;
- if(ZoneArray[0].type == type)
- best = &ZoneArray[0];
+ if(findDefault && NavigationZoneArray[0].type == ZONE_DEFAULT ||
+ findNavig && NavigationZoneArray[0].type == ZONE_NAVIG)
+ best = &NavigationZoneArray[0];
// zone to test next
- CZone *zone = ZoneArray[0].child;
+ CZone *zone = NavigationZoneArray[0].child;
while(zone)
// if in zone, descent into children
if(PointLiesWithinZone(v, zone)){
- if(zone->type == type)
+ if(findDefault && zone->type == ZONE_DEFAULT ||
+ findNavig && zone->type == ZONE_NAVIG)
best = zone;
zone = zone->child;
// otherwise try next zone
@@ -350,35 +360,62 @@ CTheZones::FindSmallestZonePositionType(const CVector *v, eZoneType type)
return best;
}
-CZone*
-CTheZones::FindSmallestZonePositionILN(const CVector *v)
+int16
+CTheZones::FindZoneByLabelAndReturnIndex(char *name, eZoneType type)
{
- CZone *best = nil;
- if(IsNormalZone(ZoneArray[0].type))
- best = &ZoneArray[0];
- // zone to test next
- CZone *zone = ZoneArray[0].child;
- while(zone)
- // if in zone, descent into children
- if(PointLiesWithinZone(v, zone)){
- if(IsNormalZone(zone->type))
- best = zone;
- zone = zone->child;
- // otherwise try next zone
- }else
- zone = zone->next;
- return best;
+ char str[8];
+ memset(str, 0, 8);
+ strncpy(str, name, 8);
+ switch(type){
+ case ZONE_DEFAULT:
+ case ZONE_NAVIG:
+ for(FindIndex = 0; FindIndex < TotalNumberOfNavigationZones; FindIndex++)
+ if(strcmp(GetNavigationZone(FindIndex)->name, name) == 0)
+ return FindIndex;
+ break;
+
+ case ZONE_INFO:
+ for(FindIndex = 0; FindIndex < TotalNumberOfInfoZones; FindIndex++)
+ if(strcmp(GetInfoZone(FindIndex)->name, name) == 0)
+ return FindIndex;
+ break;
+
+ case ZONE_MAPZONE:
+ for(FindIndex = 0; FindIndex < TotalNumberOfMapZones; FindIndex++)
+ if(strcmp(GetMapZone(FindIndex)->name, name) == 0)
+ return FindIndex;
+ break;
+ }
+ return -1;
}
int16
-CTheZones::FindZoneByLabelAndReturnIndex(Const char *name)
+CTheZones::FindNextZoneByLabelAndReturnIndex(char *name, eZoneType type)
{
char str[8];
+ ++FindIndex;
memset(str, 0, 8);
strncpy(str, name, 8);
- for(FindIndex = 0; FindIndex < TotalNumberOfZones; FindIndex++)
- if(strcmp(GetZone(FindIndex)->name, name) == 0)
- return FindIndex;
+ switch(type){
+ case ZONE_DEFAULT:
+ case ZONE_NAVIG:
+ for(; FindIndex < TotalNumberOfNavigationZones; FindIndex++)
+ if(strcmp(GetNavigationZone(FindIndex)->name, name) == 0)
+ return FindIndex;
+ break;
+
+ case ZONE_INFO:
+ for(; FindIndex < TotalNumberOfInfoZones; FindIndex++)
+ if(strcmp(GetInfoZone(FindIndex)->name, name) == 0)
+ return FindIndex;
+ break;
+
+ case ZONE_MAPZONE:
+ for(; FindIndex < TotalNumberOfMapZones; FindIndex++)
+ if(strcmp(GetMapZone(FindIndex)->name, name) == 0)
+ return FindIndex;
+ break;
+ }
return -1;
}
@@ -386,7 +423,7 @@ CZoneInfo*
CTheZones::GetZoneInfo(const CVector *v, uint8 day)
{
CZone *zone;
- zone = FindSmallestZonePositionILN(v);
+ zone = FindInformationZoneForPosition(v);
if(zone == nil)
return &ZoneInfoArray[0];
return &ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight];
@@ -397,6 +434,7 @@ CTheZones::GetZoneInfoForTimeOfDay(const CVector *pos, CZoneInfo *info)
{
CZoneInfo *day, *night;
float d, n;
+ int i;
day = GetZoneInfo(pos, 1);
night = GetZoneInfo(pos, 0);
@@ -415,110 +453,78 @@ CTheZones::GetZoneInfoForTimeOfDay(const CVector *pos, CZoneInfo *info)
assert(d >= 0.0f && d <= 1.0f);
n = 1.0f - d;
}
+#ifdef FIX_BUGS
info->carDensity = day->carDensity * d + night->carDensity * n;
- info->carThreshold[0] = day->carThreshold[0] * d + night->carThreshold[0] * n;
- info->carThreshold[1] = day->carThreshold[1] * d + night->carThreshold[1] * n;
- info->carThreshold[2] = day->carThreshold[2] * d + night->carThreshold[2] * n;
- info->carThreshold[3] = day->carThreshold[3] * d + night->carThreshold[3] * n;
- info->carThreshold[4] = day->carThreshold[4] * d + night->carThreshold[4] * n;
- info->carThreshold[5] = day->carThreshold[5] * d + night->carThreshold[5] * n;
- info->copThreshold = day->copThreshold * d + night->copThreshold * n;
- info->gangThreshold[0] = day->gangThreshold[0] * d + night->gangThreshold[0] * n;
- info->gangThreshold[1] = day->gangThreshold[1] * d + night->gangThreshold[1] * n;
- info->gangThreshold[2] = day->gangThreshold[2] * d + night->gangThreshold[2] * n;
- info->gangThreshold[3] = day->gangThreshold[3] * d + night->gangThreshold[3] * n;
- info->gangThreshold[4] = day->gangThreshold[4] * d + night->gangThreshold[4] * n;
- info->gangThreshold[5] = day->gangThreshold[5] * d + night->gangThreshold[5] * n;
- info->gangThreshold[6] = day->gangThreshold[6] * d + night->gangThreshold[6] * n;
- info->gangThreshold[7] = day->gangThreshold[7] * d + night->gangThreshold[7] * n;
- info->gangThreshold[8] = day->gangThreshold[8] * d + night->gangThreshold[8] * n;
+ for(i = 0; i < ARRAY_SIZE(info->carThreshold); i++)
+ info->carThreshold[i] = day->carThreshold[i] * d + night->carThreshold[i] * n;
+ for(i = 0; i < ARRAY_SIZE(info->boatThreshold); i++)
+ info->boatThreshold[i] = day->boatThreshold[i] * d + night->boatThreshold[i] * n;
+ for(i = 0; i < ARRAY_SIZE(info->gangThreshold); i++)
+ info->gangThreshold[i] = day->gangThreshold[i] * d + night->gangThreshold[i] * n;
+ info->copThreshold = day->copThreshold * d + night->copThreshold * n;
info->pedDensity = day->pedDensity * d + night->pedDensity * n;
- info->copDensity = day->copDensity * d + night->copDensity * n;
- info->gangDensity[0] = day->gangDensity[0] * d + night->gangDensity[0] * n;
- info->gangDensity[1] = day->gangDensity[1] * d + night->gangDensity[1] * n;
- info->gangDensity[2] = day->gangDensity[2] * d + night->gangDensity[2] * n;
- info->gangDensity[3] = day->gangDensity[3] * d + night->gangDensity[3] * n;
- info->gangDensity[4] = day->gangDensity[4] * d + night->gangDensity[4] * n;
- info->gangDensity[5] = day->gangDensity[5] * d + night->gangDensity[5] * n;
- info->gangDensity[6] = day->gangDensity[6] * d + night->gangDensity[6] * n;
- info->gangDensity[7] = day->gangDensity[7] * d + night->gangDensity[7] * n;
- info->gangDensity[8] = day->gangDensity[8] * d + night->gangDensity[8] * n;
+ info->copPedThreshold = day->copPedThreshold * d + night->copPedThreshold * n;
+ for(i = 0; i < ARRAY_SIZE(info->gangPedThreshold); i++)
+ info->gangPedThreshold[i] = day->gangPedThreshold[i] * d + night->gangPedThreshold[i] * n;
+#else
+ // This is a complete mess.
+ info->carDensity = day->carDensity * n + night->carDensity * d;
+ for(i = 0; i < ARRAY_SIZE(info->carThreshold); i++)
+ info->carThreshold[i] = night->carThreshold[i] * d + night->carThreshold[i] * n;
+ for(i = 0; i < ARRAY_SIZE(info->boatThreshold); i++)
+ info->boatThreshold[i] = night->boatThreshold[i] * d + night->boatThreshold[i] * n;
+ for(i = 0; i < ARRAY_SIZE(info->gangThreshold); i++)
+ info->gangThreshold[i] = night->gangThreshold[i] * d + night->gangThreshold[i] * n;
+
+ info->copThreshold = night->copThreshold * d + night->copThreshold * n;
+ info->pedDensity = night->pedDensity * d + night->pedDensity * n;
+ info->copPedThreshold = night->copPedThreshold * d + night->copPedThreshold * n;
+ for(i = 0; i < ARRAY_SIZE(info->gangPedThreshold); i++)
+ info->gangPedThreshold[i] = night->gangPedThreshold[i] * d + night->gangPedThreshold[i] * n;
+#endif
}
if(CClock::GetIsTimeInRange(5, 19))
info->pedGroup = day->pedGroup;
else
info->pedGroup = night->pedGroup;
-
- CheckZoneInfo(info);
}
void
CTheZones::SetZoneCarInfo(uint16 zoneid, uint8 day, int16 carDensity,
- int16 gang0Num, int16 gang1Num, int16 gang2Num,
- int16 gang3Num, int16 gang4Num, int16 gang5Num,
- int16 gang6Num, int16 gang7Num, int16 gang8Num,
- int16 copNum,
- int16 car0Num, int16 car1Num, int16 car2Num,
- int16 car3Num, int16 car4Num, int16 car5Num)
+ int16 copCarDensity, const int16 *gangCarDensities)
{
CZone *zone;
CZoneInfo *info;
- zone = GetZone(zoneid);
+ zone = GetInfoZone(zoneid);
info = &ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight];
- CheckZoneInfo(info);
-
- if(carDensity != -1) info->carDensity = carDensity;
- int16 oldCar1Num = info->carThreshold[1] - info->carThreshold[0];
- int16 oldCar2Num = info->carThreshold[2] - info->carThreshold[1];
- int16 oldCar3Num = info->carThreshold[3] - info->carThreshold[2];
- int16 oldCar4Num = info->carThreshold[4] - info->carThreshold[3];
- int16 oldCar5Num = info->carThreshold[5] - info->carThreshold[4];
- int16 oldCopNum = info->copThreshold - info->carThreshold[5];
- int16 oldGang0Num = info->gangThreshold[0] - info->copThreshold;
- int16 oldGang1Num = info->gangThreshold[1] - info->gangThreshold[0];
- int16 oldGang2Num = info->gangThreshold[2] - info->gangThreshold[1];
- int16 oldGang3Num = info->gangThreshold[3] - info->gangThreshold[2];
- int16 oldGang4Num = info->gangThreshold[4] - info->gangThreshold[3];
- int16 oldGang5Num = info->gangThreshold[5] - info->gangThreshold[4];
- int16 oldGang6Num = info->gangThreshold[6] - info->gangThreshold[5];
- int16 oldGang7Num = info->gangThreshold[7] - info->gangThreshold[6];
- int16 oldGang8Num = info->gangThreshold[8] - info->gangThreshold[7];
-
- if(car0Num != -1) info->carThreshold[0] = car0Num;
- if(car1Num != -1) info->carThreshold[1] = info->carThreshold[0] + car1Num;
- else info->carThreshold[1] = info->carThreshold[0] + oldCar1Num;
- if(car2Num != -1) info->carThreshold[2] = info->carThreshold[1] + car2Num;
- else info->carThreshold[2] = info->carThreshold[1] + oldCar2Num;
- if(car3Num != -1) info->carThreshold[3] = info->carThreshold[2] + car3Num;
- else info->carThreshold[3] = info->carThreshold[2] + oldCar3Num;
- if(car4Num != -1) info->carThreshold[4] = info->carThreshold[3] + car4Num;
- else info->carThreshold[4] = info->carThreshold[3] + oldCar4Num;
- if(car5Num != -1) info->carThreshold[5] = info->carThreshold[4] + car5Num;
- else info->carThreshold[5] = info->carThreshold[4] + oldCar5Num;
- if(copNum != -1) info->copThreshold = info->carThreshold[5] + copNum;
- else info->copThreshold = info->carThreshold[5] + oldCopNum;
- if(gang0Num != -1) info->gangThreshold[0] = info->copThreshold + gang0Num;
- else info->gangThreshold[0] = info->copThreshold + oldGang0Num;
- if(gang1Num != -1) info->gangThreshold[1] = info->gangThreshold[0] + gang1Num;
- else info->gangThreshold[1] = info->gangThreshold[0] + oldGang1Num;
- if(gang2Num != -1) info->gangThreshold[2] = info->gangThreshold[1] + gang2Num;
- else info->gangThreshold[2] = info->gangThreshold[1] + oldGang2Num;
- if(gang3Num != -1) info->gangThreshold[3] = info->gangThreshold[2] + gang3Num;
- else info->gangThreshold[3] = info->gangThreshold[2] + oldGang3Num;
- if(gang4Num != -1) info->gangThreshold[4] = info->gangThreshold[3] + gang4Num;
- else info->gangThreshold[4] = info->gangThreshold[3] + oldGang4Num;
- if(gang5Num != -1) info->gangThreshold[5] = info->gangThreshold[4] + gang5Num;
- else info->gangThreshold[5] = info->gangThreshold[4] + oldGang5Num;
- if(gang6Num != -1) info->gangThreshold[6] = info->gangThreshold[5] + gang6Num;
- else info->gangThreshold[6] = info->gangThreshold[5] + oldGang6Num;
- if(gang7Num != -1) info->gangThreshold[7] = info->gangThreshold[6] + gang7Num;
- else info->gangThreshold[7] = info->gangThreshold[6] + oldGang7Num;
- if(gang8Num != -1) info->gangThreshold[8] = info->gangThreshold[7] + gang8Num;
- else info->gangThreshold[8] = info->gangThreshold[7] + oldGang8Num;
-
- CheckZoneInfo(info);
+ info->carDensity = carDensity;
+ info->copThreshold = copCarDensity;
+ info->gangThreshold[0] = gangCarDensities[0] + copCarDensity;
+ info->gangThreshold[1] = gangCarDensities[1] + info->gangThreshold[0];
+ info->gangThreshold[2] = gangCarDensities[2] + info->gangThreshold[1];
+ info->gangThreshold[3] = gangCarDensities[3] + info->gangThreshold[2];
+ info->gangThreshold[4] = gangCarDensities[4] + info->gangThreshold[3];
+ info->gangThreshold[5] = gangCarDensities[5] + info->gangThreshold[4];
+ info->gangThreshold[6] = gangCarDensities[6] + info->gangThreshold[5];
+ info->gangThreshold[7] = gangCarDensities[7] + info->gangThreshold[6];
+ info->gangThreshold[8] = gangCarDensities[8] + info->gangThreshold[7];
+}
+
+void CTheZones::SetZoneCivilianCarInfo(uint16 zoneid, uint8 day,
+ const int16* carDensities, const int16* boatDensities)
+{
+ CZone* zone;
+ CZoneInfo* info;
+ zone = GetInfoZone(zoneid);
+ info = &ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight];
+ info->carThreshold[0] = carDensities[0];
+ for (int i = 1; i < CCarCtrl::NUM_CAR_CLASSES; i++)
+ info->carThreshold[i] = carDensities[i] + info->carThreshold[i-1];
+ info->boatThreshold[0] = boatDensities[0];
+ for (int i = 1; i < CCarCtrl::NUM_BOAT_CLASSES; i++)
+ info->boatThreshold[i] = boatDensities[i] + info->boatThreshold[i - 1];
}
void
@@ -529,46 +535,55 @@ CTheZones::SetZonePedInfo(uint16 zoneid, uint8 day, int16 pedDensity,
{
CZone *zone;
CZoneInfo *info;
- zone = GetZone(zoneid);
+ zone = GetInfoZone(zoneid);
info = &ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight];
- if(pedDensity != -1) info->pedDensity = pedDensity;
- if(copDensity != -1) info->copDensity = copDensity;
- if(gang0Density != -1) info->gangDensity[0] = gang0Density;
- if(gang1Density != -1) info->gangDensity[1] = gang1Density;
- if(gang2Density != -1) info->gangDensity[2] = gang2Density;
- if(gang3Density != -1) info->gangDensity[3] = gang3Density;
- if(gang4Density != -1) info->gangDensity[4] = gang4Density;
- if(gang5Density != -1) info->gangDensity[5] = gang5Density;
- if(gang6Density != -1) info->gangDensity[6] = gang6Density;
- if(gang7Density != -1) info->gangDensity[7] = gang7Density;
- if(gang8Density != -1) info->gangDensity[8] = gang8Density;
+ info->pedDensity = pedDensity;
+ info->copPedThreshold = copDensity;
+ info->gangPedThreshold[0] = gang0Density;
+ info->gangPedThreshold[1] = gang1Density;
+ info->gangPedThreshold[2] = gang2Density;
+ info->gangPedThreshold[3] = gang3Density;
+ info->gangPedThreshold[4] = gang4Density;
+ info->gangPedThreshold[5] = gang5Density;
+ info->gangPedThreshold[6] = gang6Density;
+ info->gangPedThreshold[7] = gang7Density;
+ info->gangPedThreshold[8] = gang8Density;
+
+ info->gangPedThreshold[0] += info->copPedThreshold;
+ info->gangPedThreshold[1] += info->gangPedThreshold[0];
+ info->gangPedThreshold[2] += info->gangPedThreshold[1];
+ info->gangPedThreshold[3] += info->gangPedThreshold[2];
+ info->gangPedThreshold[4] += info->gangPedThreshold[3];
+ info->gangPedThreshold[5] += info->gangPedThreshold[4];
+ info->gangPedThreshold[6] += info->gangPedThreshold[5];
+ info->gangPedThreshold[7] += info->gangPedThreshold[6];
+ info->gangPedThreshold[8] += info->gangPedThreshold[7];
}
+// unused
void
CTheZones::SetCarDensity(uint16 zoneid, uint8 day, uint16 cardensity)
{
CZone *zone;
- zone = GetZone(zoneid);
- if(IsNormalZone(zone->type))
- ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].carDensity = cardensity;
+ zone = GetInfoZone(zoneid);
+ ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].carDensity = cardensity;
}
+// unused
void
CTheZones::SetPedDensity(uint16 zoneid, uint8 day, uint16 peddensity)
{
CZone *zone;
- zone = GetZone(zoneid);
- if(IsNormalZone(zone->type))
- ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].pedDensity = peddensity;
+ zone = GetInfoZone(zoneid);
+ ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].pedDensity = peddensity;
}
void
CTheZones::SetPedGroup(uint16 zoneid, uint8 day, uint16 pedgroup)
{
CZone *zone;
- zone = GetZone(zoneid);
- if(IsNormalZone(zone->type))
- ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].pedGroup = pedgroup;
+ zone = GetInfoZone(zoneid);
+ ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].pedGroup = pedgroup;
}
int16
@@ -582,18 +597,6 @@ CTheZones::FindAudioZone(CVector *pos)
return -1;
}
-eLevelName
-CTheZones::FindZoneForPoint(const CVector &pos)
-{
- if(PointLiesWithinZone(&pos, GetZone(FindZoneByLabelAndReturnIndex("IND_ZON"))))
- return LEVEL_INDUSTRIAL;
- if(PointLiesWithinZone(&pos, GetZone(FindZoneByLabelAndReturnIndex("COM_ZON"))))
- return LEVEL_COMMERCIAL;
- if(PointLiesWithinZone(&pos, GetZone(FindZoneByLabelAndReturnIndex("SUB_ZON"))))
- return LEVEL_SUBURBAN;
- return LEVEL_GENERIC;
-}
-
void
CTheZones::AddZoneToAudioZoneArray(CZone *zone)
{
@@ -604,9 +607,10 @@ CTheZones::AddZoneToAudioZoneArray(CZone *zone)
/* This is a bit stupid */
z = -1;
- for(i = 0; i < NUMZONES; i++)
- if(&ZoneArray[i] == zone)
+ for(i = 0; i < NUMNAVIGZONES; i++)
+ if(&NavigationZoneArray[i] == zone)
z = i;
+ assert(NumberOfAudioZones < NUMAUDIOZONES);
AudioZoneArray[NumberOfAudioZones++] = z;
}
@@ -617,7 +621,7 @@ CTheZones::InitialiseAudioZoneArray(void)
CZone *zone;
gonext = false;
- zone = &ZoneArray[0];
+ zone = &NavigationZoneArray[0];
// Go deep first,
// set gonext when backing up a level to visit the next child
while(zone)
@@ -641,175 +645,113 @@ CTheZones::InitialiseAudioZoneArray(void)
}
}
-#ifdef COMPATIBLE_SAVES
-static inline void
-SaveOneZone(CZone &zone, uint8 *&buffer)
-{
- memcpy(buffer, zone.name, sizeof(zone.name));
- SkipSaveBuf(buffer, sizeof(zone.name));
- WriteSaveBuf(buffer, zone.minx);
- WriteSaveBuf(buffer, zone.miny);
- WriteSaveBuf(buffer, zone.minz);
- WriteSaveBuf(buffer, zone.maxx);
- WriteSaveBuf(buffer, zone.maxy);
- WriteSaveBuf(buffer, zone.maxz);
- WriteSaveBuf(buffer, zone.type);
- WriteSaveBuf(buffer, zone.level);
- WriteSaveBuf(buffer, zone.zoneinfoDay);
- WriteSaveBuf(buffer, zone.zoneinfoNight);
- WriteSaveBuf(buffer, (int32)CTheZones::GetIndexForZonePointer(zone.child));
- WriteSaveBuf(buffer, (int32)CTheZones::GetIndexForZonePointer(zone.parent));
- WriteSaveBuf(buffer, (int32)CTheZones::GetIndexForZonePointer(zone.next));
-}
-#endif
-
void
CTheZones::SaveAllZones(uint8 *buffer, uint32 *size)
{
INITSAVEBUF
int i;
+#define CZONE_SAVE_SIZE (sizeof(char)*8+sizeof(float)+sizeof(float)+sizeof(float)+sizeof(float)+sizeof(float)+sizeof(float)+sizeof(eZoneType)+sizeof(eLevelName)+sizeof(int16)+sizeof(int16)+sizeof(int32)+sizeof(int32)+sizeof(int32))
+
*size = SAVE_HEADER_SIZE
- + sizeof(int32) // GetIndexForZonePointer
+ sizeof(m_CurrLevel) + sizeof(FindIndex)
+ sizeof(int16) // padding
- + ZONEARRAY_SAVE_SIZE + sizeof(ZoneInfoArray)
- + sizeof(TotalNumberOfZones) + sizeof(TotalNumberOfZoneInfos)
- + MAPZONEARRAY_SAVE_SIZE + sizeof(AudioZoneArray)
+ + CZONE_SAVE_SIZE * ARRAY_SIZE(NavigationZoneArray) + CZONE_SAVE_SIZE * ARRAY_SIZE(InfoZoneArray) + sizeof(ZoneInfoArray)
+ + sizeof(TotalNumberOfNavigationZones) + sizeof(TotalNumberOfInfoZones) + sizeof(TotalNumberOfZoneInfos)
+ + sizeof(int16) // padding
+ + CZONE_SAVE_SIZE * ARRAY_SIZE(MapZoneArray) + sizeof(AudioZoneArray)
+ sizeof(TotalNumberOfMapZones) + sizeof(NumberOfAudioZones);
+#undef CZONE_SAVE_SIZE
- WriteSaveHeader(buffer, 'Z', 'N', 'S', '\0', *size - SAVE_HEADER_SIZE);
+ uint32 length = 0;
+ WriteSaveHeaderWithLength(buffer, length, 'Z', 'N', 'S', '\0', *size - SAVE_HEADER_SIZE);
- WriteSaveBuf(buffer, (int32)GetIndexForZonePointer(m_pPlayersZone));
- WriteSaveBuf(buffer, m_CurrLevel);
- WriteSaveBuf(buffer, FindIndex);
- WriteSaveBuf(buffer, (int16)0); // padding
+ WriteSaveBuf(buffer, length, m_CurrLevel);
+ WriteSaveBuf(buffer, length, FindIndex);
+ WriteSaveBuf(buffer, length, (int16)0); // padding
- for(i = 0; i < ARRAY_SIZE(ZoneArray); i++){
-#ifdef COMPATIBLE_SAVES
- SaveOneZone(ZoneArray[i], buffer);
-#else
- CZone *zone = WriteSaveBuf(buffer, ZoneArray[i]);
- zone->child = (CZone*)GetIndexForZonePointer(ZoneArray[i].child);
- zone->parent = (CZone*)GetIndexForZonePointer(ZoneArray[i].parent);
- zone->next = (CZone*)GetIndexForZonePointer(ZoneArray[i].next);
-#endif
- }
+ for(i = 0; i < ARRAY_SIZE(NavigationZoneArray); i++)
+ SaveOneZone(&NavigationZoneArray[i], &buffer, &length, ZONE_NAVIG);
- for(i = 0; i < ARRAY_SIZE(ZoneInfoArray); i++)
- WriteSaveBuf(buffer, ZoneInfoArray[i]);
+ for(i = 0; i < ARRAY_SIZE(InfoZoneArray); i++)
+ SaveOneZone(&InfoZoneArray[i], &buffer, &length, ZONE_INFO);
- WriteSaveBuf(buffer, TotalNumberOfZones);
- WriteSaveBuf(buffer, TotalNumberOfZoneInfos);
+ for(i = 0; i < ARRAY_SIZE(ZoneInfoArray); i++)
+ WriteSaveBuf(buffer, length, ZoneInfoArray[i]);
- for(i = 0; i < ARRAY_SIZE(MapZoneArray); i++) {
-#ifndef COMPATIBLE_SAVES
- CZone* zone = WriteSaveBuf(buffer, MapZoneArray[i]);
-#endif
+ WriteSaveBuf(buffer, length, TotalNumberOfNavigationZones);
+ WriteSaveBuf(buffer, length, TotalNumberOfInfoZones);
+ WriteSaveBuf(buffer, length, TotalNumberOfZoneInfos);
+ WriteSaveBuf(buffer, length, (int16)0); // padding
- /*
- The call of GetIndexForZonePointer is wrong, as it is
- meant for a different array, but the game doesn't brake
- if those fields are nil. Let's make sure they are.
- */
- assert(MapZoneArray[i].child == nil);
- assert(MapZoneArray[i].parent == nil);
- assert(MapZoneArray[i].next == nil);
-#ifndef COMPATIBLE_SAVES
- zone->child = (CZone*)GetIndexForZonePointer(MapZoneArray[i].child);
- zone->parent = (CZone*)GetIndexForZonePointer(MapZoneArray[i].parent);
- zone->next = (CZone*)GetIndexForZonePointer(MapZoneArray[i].next);
-#else
- SaveOneZone(MapZoneArray[i], buffer);
-#endif
- }
+ for(i = 0; i < ARRAY_SIZE(MapZoneArray); i++)
+ SaveOneZone(&MapZoneArray[i], &buffer, &length, ZONE_MAPZONE);
for(i = 0; i < ARRAY_SIZE(AudioZoneArray); i++)
- WriteSaveBuf(buffer, AudioZoneArray[i]);
+ WriteSaveBuf(buffer, length, AudioZoneArray[i]);
- WriteSaveBuf(buffer, TotalNumberOfMapZones);
- WriteSaveBuf(buffer, NumberOfAudioZones);
+ WriteSaveBuf(buffer, length, TotalNumberOfMapZones);
+ WriteSaveBuf(buffer, length, NumberOfAudioZones);
VALIDATESAVEBUF(*size)
}
-#ifdef COMPATIBLE_SAVES
-static inline void
-LoadOneZone(CZone &zone, uint8 *&buffer)
+void
+CTheZones::SaveOneZone(CZone *zone, uint8 **buffer, uint32 *length, eZoneType zoneType)
{
- memcpy(zone.name, buffer, sizeof(zone.name));
- SkipSaveBuf(buffer, sizeof(zone.name));
- ReadSaveBuf(&zone.minx, buffer);
- ReadSaveBuf(&zone.miny, buffer);
- ReadSaveBuf(&zone.minz, buffer);
- ReadSaveBuf(&zone.maxx, buffer);
- ReadSaveBuf(&zone.maxy, buffer);
- ReadSaveBuf(&zone.maxz, buffer);
- ReadSaveBuf(&zone.type, buffer);
- ReadSaveBuf(&zone.level, buffer);
- ReadSaveBuf(&zone.zoneinfoDay, buffer);
- ReadSaveBuf(&zone.zoneinfoNight, buffer);
- int32 tmp;
- ReadSaveBuf(&tmp, buffer);
- zone.child = CTheZones::GetPointerForZoneIndex(tmp);
- ReadSaveBuf(&tmp, buffer);
- zone.parent = CTheZones::GetPointerForZoneIndex(tmp);
- ReadSaveBuf(&tmp, buffer);
- zone.next = CTheZones::GetPointerForZoneIndex(tmp);
+ WriteSaveBuf(*buffer, *length, *(uint32*)&zone->name[0]);
+ WriteSaveBuf(*buffer, *length, *(uint32*)&zone->name[4]);
+
+ WriteSaveBuf(*buffer, *length, zone->minx);
+ WriteSaveBuf(*buffer, *length, zone->miny);
+ WriteSaveBuf(*buffer, *length, zone->minz);
+ WriteSaveBuf(*buffer, *length, zone->maxx);
+ WriteSaveBuf(*buffer, *length, zone->maxy);
+ WriteSaveBuf(*buffer, *length, zone->maxz);
+
+ WriteSaveBuf(*buffer, *length, zone->type);
+ WriteSaveBuf(*buffer, *length, zone->level);
+ WriteSaveBuf(*buffer, *length, zone->zoneinfoDay);
+ WriteSaveBuf(*buffer, *length, zone->zoneinfoNight);
+
+ int32 zoneId;
+ zoneId = GetIndexForNavigationZonePointer(zone->child);
+ WriteSaveBuf(*buffer, *length, zoneId);
+ zoneId = GetIndexForNavigationZonePointer(zone->parent);
+ WriteSaveBuf(*buffer, *length, zoneId);
+ zoneId = GetIndexForNavigationZonePointer(zone->next);
+ WriteSaveBuf(*buffer, *length, zoneId);
}
-#endif
void
CTheZones::LoadAllZones(uint8 *buffer, uint32 size)
{
INITSAVEBUF
- int32 i;
+ int i;
- CheckSaveHeader(buffer, 'Z', 'N', 'S', '\0', size - SAVE_HEADER_SIZE);
+ uint32 length = 0;
+ CheckSaveHeaderWithLength(buffer, length, 'Z', 'N', 'S', '\0', size - SAVE_HEADER_SIZE);
- ReadSaveBuf(&i, buffer);
- m_pPlayersZone = GetPointerForZoneIndex(i);
ReadSaveBuf(&m_CurrLevel, buffer);
ReadSaveBuf(&FindIndex, buffer);
SkipSaveBuf(buffer, 2);
- for(i = 0; i < ARRAY_SIZE(ZoneArray); i++){
-#ifdef COMPATIBLE_SAVES
- LoadOneZone(ZoneArray[i], buffer);
-#else
- ReadSaveBuf(&ZoneArray[i], buffer);
+ for(i = 0; i < ARRAY_SIZE(NavigationZoneArray); i++)
+ LoadOneZone(&NavigationZoneArray[i], &buffer, &length, ZONE_NAVIG);
- ZoneArray[i].child = GetPointerForZoneIndex((uintptr)ZoneArray[i].child);
- ZoneArray[i].parent = GetPointerForZoneIndex((uintptr)ZoneArray[i].parent);
- ZoneArray[i].next = GetPointerForZoneIndex((uintptr)ZoneArray[i].next);
-#endif
- }
+ for (i = 0; i < ARRAY_SIZE(InfoZoneArray); i++)
+ LoadOneZone(&InfoZoneArray[i], &buffer, &length, ZONE_INFO);
for(i = 0; i < ARRAY_SIZE(ZoneInfoArray); i++)
ReadSaveBuf(&ZoneInfoArray[i], buffer);
- ReadSaveBuf(&TotalNumberOfZones, buffer);
+ ReadSaveBuf(&TotalNumberOfNavigationZones, buffer);
+ ReadSaveBuf(&TotalNumberOfInfoZones, buffer);
ReadSaveBuf(&TotalNumberOfZoneInfos, buffer);
+ SkipSaveBuf(buffer, 2);
- for(i = 0; i < ARRAY_SIZE(MapZoneArray); i++){
-#ifdef COMPATIBLE_SAVES
- LoadOneZone(MapZoneArray[i], buffer);
-#else
- ReadSaveBuf(&MapZoneArray[i], buffer);
-
- /*
- The call of GetPointerForZoneIndex is wrong, as it is
- meant for a different array, but the game doesn't brake
- if save data stored is -1.
- */
- MapZoneArray[i].child = GetPointerForZoneIndex((uintptr)MapZoneArray[i].child);
- MapZoneArray[i].parent = GetPointerForZoneIndex((uintptr)MapZoneArray[i].parent);
- MapZoneArray[i].next = GetPointerForZoneIndex((uintptr)MapZoneArray[i].next);
-#endif
- assert(MapZoneArray[i].child == nil);
- assert(MapZoneArray[i].parent == nil);
- assert(MapZoneArray[i].next == nil);
- }
+ for(i = 0; i < ARRAY_SIZE(MapZoneArray); i++)
+ LoadOneZone(&MapZoneArray[i], &buffer, &length, ZONE_MAPZONE);
for(i = 0; i < ARRAY_SIZE(AudioZoneArray); i++)
ReadSaveBuf(&AudioZoneArray[i], buffer);
@@ -819,3 +761,40 @@ CTheZones::LoadAllZones(uint8 *buffer, uint32 size)
VALIDATESAVEBUF(size)
}
+
+void
+CTheZones::LoadOneZone(CZone *zone, uint8 **buffer, uint32 *length, eZoneType zoneType)
+{
+#ifdef THIS_IS_STUPID
+ uint32 part1, part2;
+ ReadSaveBuf(&part1, *buffer, *length);
+ ReadSaveBuf(&part2, *buffer, *length);
+
+ *(uint64 *)&zone->name[0] = (uint64)part2;
+ *(uint64 *)&zone->name[0] <<= 32;
+ *(uint64 *)&zone->name[0] |= (uint64)part1;
+#else
+ for(int i = 0; i < sizeof(zone->name); i++)
+ ReadSaveBuf(&zone->name[i], *buffer, *length);
+#endif
+
+ ReadSaveBuf(&zone->minx, *buffer, *length);
+ ReadSaveBuf(&zone->miny, *buffer, *length);
+ ReadSaveBuf(&zone->minz, *buffer, *length);
+ ReadSaveBuf(&zone->maxx, *buffer, *length);
+ ReadSaveBuf(&zone->maxy, *buffer, *length);
+ ReadSaveBuf(&zone->maxz, *buffer, *length);
+
+ ReadSaveBuf(&zone->type, *buffer, *length);
+ ReadSaveBuf(&zone->level, *buffer, *length);
+ ReadSaveBuf(&zone->zoneinfoDay, *buffer, *length);
+ ReadSaveBuf(&zone->zoneinfoNight, *buffer, *length);
+
+ int32 zoneId;
+ ReadSaveBuf(&zoneId, *buffer, *length);
+ zone->child = GetPointerForNavigationZoneIndex(zoneId);
+ ReadSaveBuf(&zoneId, *buffer, *length);
+ zone->parent = GetPointerForNavigationZoneIndex(zoneId);
+ ReadSaveBuf(&zoneId, *buffer, *length);
+ zone->next = GetPointerForNavigationZoneIndex(zoneId);
+} \ No newline at end of file
diff --git a/src/core/Zones.h b/src/core/Zones.h
index aa0466e8..2316eeef 100644
--- a/src/core/Zones.h
+++ b/src/core/Zones.h
@@ -2,6 +2,7 @@
#include "Game.h"
#include "Gangs.h"
+#include "CarCtrl.h"
enum eZoneType
{
@@ -37,31 +38,33 @@ class CZoneInfo
public:
// Car data
int16 carDensity;
- int16 carThreshold[6];
- int16 copThreshold;
+ int16 carThreshold[CCarCtrl::NUM_CAR_CLASSES];
+ int16 boatThreshold[CCarCtrl::NUM_BOAT_CLASSES];
int16 gangThreshold[NUM_GANGS];
+ int16 copThreshold;
// Ped data
uint16 pedDensity;
- uint16 copDensity;
- uint16 gangDensity[NUM_GANGS];
+ uint16 gangPedThreshold[NUM_GANGS];
+ uint16 copPedThreshold;
uint16 pedGroup;
};
class CTheZones
{
- static CZone *m_pPlayersZone;
static int16 FindIndex;
static uint16 NumberOfAudioZones;
static int16 AudioZoneArray[NUMAUDIOZONES];
static uint16 TotalNumberOfMapZones;
- static uint16 TotalNumberOfZones;
- static CZone ZoneArray[NUMZONES];
+ static uint16 TotalNumberOfInfoZones;
+ static uint16 TotalNumberOfNavigationZones;
+ static CZone InfoZoneArray[NUMINFOZONES];
static CZone MapZoneArray[NUMMAPZONES];
+ static CZone NavigationZoneArray[NUMNAVIGZONES];
static uint16 TotalNumberOfZoneInfos;
- static CZoneInfo ZoneInfoArray[2*NUMZONES];
+ static CZoneInfo ZoneInfoArray[2*NUMINFOZONES];
public:
static eLevelName m_CurrLevel;
@@ -71,31 +74,27 @@ public:
float minx, float miny, float minz,
float maxx, float maxy, float maxz,
eLevelName level);
- static void CreateMapZone(char *name, eZoneType type,
- float minx, float miny, float minz,
- float maxx, float maxy, float maxz,
- eLevelName level);
- static CZone *GetZone(uint16 i) { return &ZoneArray[i]; }
- static CZone *GetAudioZone(uint16 i) { return &ZoneArray[AudioZoneArray[i]]; }
+ static CZone *GetInfoZone(uint16 i) { return &InfoZoneArray[i]; }
+ static CZone *GetNavigationZone(uint16 i) { return &NavigationZoneArray[i]; }
+ static CZone *GetMapZone(uint16 i) { return &MapZoneArray[i]; }
+ static CZone *GetAudioZone(uint16 i) { return &NavigationZoneArray[AudioZoneArray[i]]; }
static void PostZoneCreation(void);
+ static void CheckZonesForOverlap(void);
static void InsertZoneIntoZoneHierarchy(CZone *zone);
static bool InsertZoneIntoZoneHierRecursive(CZone *z1, CZone *z2);
static bool ZoneIsEntirelyContainedWithinOtherZone(CZone *z1, CZone *z2);
static bool PointLiesWithinZone(const CVector *v, CZone *zone);
static eLevelName GetLevelFromPosition(const CVector *v);
- static CZone *FindSmallestZonePosition(const CVector *v);
- static CZone *FindSmallestZonePositionType(const CVector *v, eZoneType type);
- static CZone *FindSmallestZonePositionILN(const CVector *v);
- static int16 FindZoneByLabelAndReturnIndex(Const char *name);
+ static CZone *FindInformationZoneForPosition(const CVector *v);
+ static CZone *FindSmallestNavigationZoneForPosition(const CVector *v, bool findDefault, bool findNavig);
+ static int16 FindZoneByLabelAndReturnIndex(char *name, eZoneType type);
+ static int16 FindNextZoneByLabelAndReturnIndex(char *name, eZoneType type);
static CZoneInfo *GetZoneInfo(const CVector *v, uint8 day);
static void GetZoneInfoForTimeOfDay(const CVector *pos, CZoneInfo *info);
static void SetZoneCarInfo(uint16 zoneid, uint8 day, int16 carDensity,
- int16 gang0Num, int16 gang1Num, int16 gang2Num,
- int16 gang3Num, int16 gang4Num, int16 gang5Num,
- int16 gang6Num, int16 gang7Num, int16 gang8Num,
- int16 copNum,
- int16 car0Num, int16 car1Num, int16 car2Num,
- int16 car3Num, int16 car4Num, int16 car5Num);
+ int16 copCarDensity, const int16 *gangCarDensities /*[NUMGANGS]*/);
+ static void SetZoneCivilianCarInfo(uint16 zoneid, uint8 day,
+ const int16* carDensities, const int16* boatDensities);
static void SetZonePedInfo(uint16 zoneid, uint8 day, int16 pedDensity,
int16 gang0Density, int16 gang1Density, int16 gang2Density, int16 gang3Density,
int16 gang4Density, int16 gang5Density, int16 gang6Density, int16 gang7Density,
@@ -104,11 +103,12 @@ public:
static void SetPedDensity(uint16 zoneid, uint8 day, uint16 peddensity);
static void SetPedGroup(uint16 zoneid, uint8 day, uint16 pedgroup);
static int16 FindAudioZone(CVector *pos);
- static eLevelName FindZoneForPoint(const CVector &pos);
- static CZone *GetPointerForZoneIndex(ssize_t i) { return i == -1 ? nil : &ZoneArray[i]; }
- static ssize_t GetIndexForZonePointer(CZone *zone) { return zone == nil ? -1 : zone - ZoneArray; }
+ static CZone *GetPointerForNavigationZoneIndex(ssize_t i) { return i == -1 ? nil : &NavigationZoneArray[i]; }
+ static ssize_t GetIndexForNavigationZonePointer(CZone *zone) { return zone == nil ? -1 : zone - NavigationZoneArray; }
static void AddZoneToAudioZoneArray(CZone *zone);
static void InitialiseAudioZoneArray(void);
static void SaveAllZones(uint8 *buffer, uint32 *length);
+ static void SaveOneZone(CZone *zone, uint8 **buffer, uint32 *length, eZoneType zoneType);
static void LoadAllZones(uint8 *buffer, uint32 length);
+ static void LoadOneZone(CZone *zone, uint8 **buffer, uint32 *length, eZoneType zoneType);
};
diff --git a/src/core/common.h b/src/core/common.h
index 3f69a394..12c80b71 100644
--- a/src/core/common.h
+++ b/src/core/common.h
@@ -11,6 +11,11 @@
#define __STDC_LIMIT_MACROS // so we get UINT32_MAX etc
#endif
+
+#ifdef __SWITCH__
+#include <switch.h>
+#endif
+
#include <stdint.h>
#include <string.h>
#include <math.h>
@@ -116,10 +121,8 @@ typedef ptrdiff_t ssize_t;
#include "config.h"
-#ifdef PED_SKIN
#include <rphanim.h>
#include <rpskin.h>
-#endif
#ifdef __GNUC__
#define TYPEALIGN(n) __attribute__ ((aligned (n)))
@@ -148,7 +151,7 @@ inline uint32 ldb(uint32 p, uint32 s, uint32 w)
#include "skeleton.h"
#include "Draw.h"
-#if defined(PROPER_SCALING) || defined(PS2_HUD)
+#if defined(PROPER_SCALING)
#ifdef FORCE_PC_SCALING
#define DEFAULT_SCREEN_WIDTH (640)
#define DEFAULT_SCREEN_HEIGHT (448)
@@ -286,6 +289,7 @@ public:
#if (defined(_MSC_VER))
extern int strcasecmp(const char *str1, const char *str2);
+extern int strncasecmp(const char *str1, const char *str2, size_t len);
#endif
extern wchar *AllocUnicode(const char*src);
@@ -395,3 +399,4 @@ template<int s, int t> struct check_size {
#define STR(x) STRINGIFY(x)
#define CONCAT_(x,y) x##y
#define CONCAT(x,y) CONCAT_(x,y)
+
diff --git a/src/core/config.h b/src/core/config.h
index 1e9bf6d2..e6af6ccd 100644
--- a/src/core/config.h
+++ b/src/core/config.h
@@ -1,82 +1,82 @@
#pragma once
-// disables (most) stuff that wasn't in original gta3.exe
+// disables (most) stuff that wasn't in original gta-vc.exe
#ifdef __MWERKS__
#define VANILLA_DEFINES
#endif
enum Config {
- NUMPLAYERS = 1, // 4 on PS2
+ NUMPLAYERS = 1,
- NUMCDIMAGES = 12, // gta3.img duplicates (not used on PC)
+ NUMCDIMAGES = 6, // gta3.img duplicates (not used on PC)
MAX_CDIMAGES = 8, // additional cdimages
MAX_CDCHANNELS = 5,
- MODELINFOSIZE = 5500, // 3150 on PS2
-#ifdef VANILLA_DEFINES
- TXDSTORESIZE = 850,
-#else
- TXDSTORESIZE = 1024, // for Xbox map
-#endif
- EXTRADIRSIZE = 128,
+ MODELINFOSIZE = 6500, // 4900 on PS2
+ TXDSTORESIZE = 1385,
+ COLSTORESIZE = 31,
+ EXTRADIRSIZE = 256,
CUTSCENEDIRSIZE = 512,
- SIMPLEMODELSIZE = 5000, // 2910 on PS2
- MLOMODELSIZE = 1,
- MLOINSTANCESIZE = 1,
- TIMEMODELSIZE = 30,
+ SIMPLEMODELSIZE = 3885,
+ TIMEMODELSIZE = 385,
CLUMPMODELSIZE = 5,
- PEDMODELSIZE = 90,
- VEHICLEMODELSIZE = 120, // 70 on PS2
- XTRACOMPSMODELSIZE = 2,
- TWODFXSIZE = 2000, // 1210 on PS2
+ WEAPONMODELSIZE = 37,
+ PEDMODELSIZE = 130,
+ VEHICLEMODELSIZE = 110,
+ TWODFXSIZE = 1210,
MAXVEHICLESLOADED = 50, // 70 on mobile
- NUMOBJECTINFO = 168, // object.dat
+ NUMOBJECTINFO = 210,
// Pool sizes
- NUMPTRNODES = 30000, // 26000 on PS2
- NUMENTRYINFOS = 5400, // 3200 on PS2
- NUMPEDS = 140, // 90 on PS2
- NUMVEHICLES = 110, // 70 on PS2
- NUMBUILDINGS = 5500, // 4915 on PS2
- NUMTREADABLES = 1214,
- NUMOBJECTS = 450,
- NUMDUMMIES = 2802, // 2368 on PS2
- NUMAUDIOSCRIPTOBJECTS = 256,
- NUMCUTSCENEOBJECTS = 50,
-
- NUMANIMBLOCKS = 2,
- NUMANIMATIONS = 250,
-
- NUMTEMPOBJECTS = 30,
+ NUMPTRNODES = 50000,
+ NUMENTRYINFOS = 3200,
+ NUMPEDS = 140,
+ NUMVEHICLES = 110,
+ NUMBUILDINGS = 7000,
+ NUMTREADABLES = 1,
+ NUMOBJECTS = 460,
+ NUMDUMMIES = 2340,
+ NUMAUDIOSCRIPTOBJECTS = 192,
+ NUMCOLMODELS = 4400,
+ NUMCUTSCENEOBJECTS = 50, // not a pool in VC
+
+ NUMANIMBLOCKS = 35,
+ NUMANIMATIONS = 450,
+
+ NUMTEMPOBJECTS = 40,
// Path data
- NUM_PATHNODES = 4930,
- NUM_CARPATHLINKS = 2076,
+ NUM_PATHNODES = 9650,
+ NUM_CARPATHLINKS = 3500,
NUM_MAPOBJECTS = 1250,
- NUM_PATHCONNECTIONS = 10260,
+ NUM_PATHCONNECTIONS = 20400,
// Link list lengths
NUMALPHALIST = 20,
- NUMALPHAENTITYLIST = 150,
- NUMCOLCACHELINKS = 200,
+ NUMBOATALPHALIST = 20,
+ NUMALPHAENTITYLIST = 200,
+ NUMALPHAUNTERWATERENTITYLIST = 30,
+ NUMCOLCACHELINKS = 50,
NUMREFERENCES = 800,
// Zones
- NUMAUDIOZONES = 36,
- NUMZONES = 50,
- NUMMAPZONES = 25,
+ NUMAUDIOZONES = 14,
+ NUMINFOZONES = 169,
+ NUMMAPZONES = 39,
+ NUMNAVIGZONES = 20,
// Cull zones
- NUMCULLZONES = 512,
- NUMATTRIBZONES = 288,
- NUMZONEINDICES = 55000,
+ NUMATTRIBZONES = 704,
+
+ NUMOCCLUSIONVOLUMES = 350,
+ NUMACTIVEOCCLUDERS = 48,
PATHNODESIZE = 4500,
- NUMWEATHERS = 4,
+ NUMWEATHERS = 7,
NUMHOURS = 24,
NUMEXTRADIRECTIONALS = 4,
@@ -92,8 +92,9 @@ enum Config {
NUMMBLURSTREAKS = 4,
NUMSKIDMARKS = 32,
- NUMONSCREENTIMERENTRIES = 1,
- NUMRADARBLIPS = 32,
+ NUMONSCREENCLOCKS = 1,
+ NUMONSCREENCOUNTERS = 3,
+ NUMRADARBLIPS = 75,
NUMGENERALPICKUPS = 320,
NUMSCRIPTEDPICKUPS = 16,
NUMPICKUPS = NUMGENERALPICKUPS + NUMSCRIPTEDPICKUPS,
@@ -101,7 +102,7 @@ enum Config {
NUMPACMANPICKUPS = 256,
NUMEVENTS = 64,
- NUM_CARGENS = 160,
+ NUM_CARGENS = 185,
NUM_PATH_NODES_IN_AUTOPILOT = 8,
@@ -116,11 +117,13 @@ enum Config {
NUMPEDROUTES = 200,
NUMPHONES = 50,
- NUMPEDGROUPS = 31,
- NUMMODELSPERPEDGROUP = 8,
+ NUMPEDGROUPS = 67,
+ NUMMODELSPERPEDGROUP = 16,
+ MAXZONEPEDSLOADED = 8,
NUMSHOTINFOS = 100,
- NUMROADBLOCKS = 600,
+ NUMROADBLOCKS = 300,
+ NUM_SCRIPT_ROADBLOCKS = 16,
NUMVISIBLEENTITIES = 2000,
NUMINVISIBLEENTITIES = 150,
@@ -130,15 +133,20 @@ enum Config {
NUM_PED_COMMENTS_SLOTS = 20,
NUM_SOUNDS_SAMPLES_BANKS = 2,
- NUM_AUDIOENTITIES = 200,
+ NUM_AUDIOENTITIES = 250,
NUM_SCRIPT_MAX_ENTITIES = 40,
- NUM_GARAGE_STORED_CARS = 6,
+ NUM_GARAGE_STORED_CARS = 4,
NUM_CRANES = 8,
+ NUM_ESCALATORS = 22,
+ NUM_WATER_CREATURES = 8,
NUM_EXPLOSIONS = 48,
+
+ NUM_SETPIECES = 96,
+ NUM_SHORTCUT_START_POINTS = 16
};
// We don't expect to compile for PS2 or Xbox
@@ -148,29 +156,42 @@ enum Config {
//#define GTA_XBOX
// Version defines
-#define GTA3_PS2_140 300
-#define GTA3_PS2_160 301
-#define GTA3_PC_10 310
-#define GTA3_PC_11 311
-#define GTA3_PC_STEAM 312
+#define GTAVC_PS2 400
+#define GTAVC_PC_10 410
+#define GTAVC_PC_11 411
+#define GTAVC_PC_JAP 412
// TODO? maybe something for xbox or android?
-#define GTA_VERSION GTA3_PC_11
+#define GTA_VERSION GTAVC_PC_11
+
+// Enable configuration for handheld console ports
+#if defined(__SWITCH__) || defined(PSP2)
+ #define GTA_HANDHELD
+#endif
+
+// TODO(MIAMI): someone ought to find and check out uses of these defines:
+//#define GTA3_STEAM_PATCH
+//#define GTAVC_JP_PATCH
#if defined GTA_PS2
# define GTA_PS2_STUFF
# define RANDOMSPLASH
-# define USE_CUSTOM_ALLOCATOR
+//# define USE_CUSTOM_ALLOCATOR
# define VU_COLLISION
-# define ANIM_COMPRESSION
# define PS2_MENU
#elif defined GTA_PC
# define EXTERNAL_3D_SOUND
-# define PC_PLAYER_CONTROLS // mouse player/cam mode
+# ifndef GTA_HANDHELD
+# define PC_PLAYER_CONTROLS // mouse player/cam mode
+# endif
# define GTA_REPLAY
# define GTA_SCENE_EDIT
# define PC_MENU
+# define PC_WATER
#elif defined GTA_XBOX
+#elif defined GTA_MOBILE
+# define MISSION_REPLAY
+# define SIMPLER_MISSIONS
#endif
// This is enabled for all released games.
@@ -203,7 +224,6 @@ enum Config {
#define MASTER
//#define USE_MY_DOCUMENTS
#define THIS_IS_STUPID
-#define PC_PARTICLE
#define DONT_FIX_REPLAY_BUGS
#define USE_TXD_CDIMAGE // generate and load textures from txd.img
//#define USE_TEXTURE_POOL // not possible because R* used custom RW33
@@ -221,7 +241,6 @@ enum Config {
// If you disable this then game will fetch version from peds.col, as R* did while in development.
//#define USE_OUR_VERSIONING // enabled from buildfiles by default
#endif
-//#define DRAW_MENU_VERSION_TEXT
// Memory allocation and compression
// #define USE_CUSTOM_ALLOCATOR // use CMemoryHeap for allocation. use with care, not finished yet
@@ -259,7 +278,7 @@ enum Config {
#define FIX_BUGS // fixes bugs that we've came across during reversing. You can undefine this only on release builds.
#define MORE_LANGUAGES // Add more translations to the game
-#define COMPATIBLE_SAVES // this allows changing structs while keeping saves compatible, and keeps saves compatible between platforms, needs to be enabled on 64bit builds!
+#define COMPATIBLE_SAVES // this allows changing structs while keeping saves compatible, and keeps saves compatible between platforms
#define FIX_INCOMPATIBLE_SAVES // try to fix incompatible saves, requires COMPATIBLE_SAVES
#define LOAD_INI_SETTINGS // as the name suggests. fundamental for CUSTOM_FRONTEND_OPTIONS
@@ -274,19 +293,17 @@ enum Config {
#define ASCII_STRCMP // use faster ascii str comparisons
-#if !defined _WIN32 || defined __MINGW32__
+#if !defined _WIN32 || defined __MINGW32__
#undef ASCII_STRCMP
#endif
// Just debug menu entries
#ifdef DEBUGMENU
+#define RELOADABLES // some debug menu options to reload TXD files
#define MISSION_SWITCHER // from debug menu
#endif
// Rendering/display
-//#define EXTRA_MODEL_FLAGS // from mobile to optimize rendering
-//# define HARDCODED_MODEL_FLAGS // sets the flags enabled above from hardcoded model names.
- // NB: keep this enabled unless your map IDEs have these flags baked in
#define ASPECT_RATIO_SCALE // Not just makes everything scale with aspect ratio, also adds support for all aspect ratios
#define PROPER_SCALING // use original DEFAULT_SCREEN_WIDTH/DEFAULT_SCREEN_HEIGHT from PS2 instead of PC(R* changed HEIGHT here to make radar look better, but broke other hud elements aspect ratio).
#define DEFAULT_NATIVE_RESOLUTION // Set default video mode to your native resolution (fixes Windows 10 launch)
@@ -294,10 +311,6 @@ enum Config {
#define PS2_ALPHA_TEST // emulate ps2 alpha test
#define IMPROVED_VIDEOMODE // save and load videomode parameters instead of a magic number
#define DISABLE_LOADING_SCREEN // disable the loading screen which vastly improves the loading time
-#ifdef DISABLE_LOADING_SCREEN
-// enable the PC splash
-#undef RANDOMSPLASH
-#endif
#define DISABLE_VSYNC_ON_TEXTURE_CONVERSION // make texture conversion work faster by disabling vsync
#define ANISOTROPIC_FILTERING // set all textures to max anisotropic filtering
//#define USE_TEXTURE_POOL
@@ -314,58 +327,55 @@ enum Config {
#undef SCREEN_DROPLETS // we need the backbuffer for this effect
#endif
-// Particle
-//#define PC_PARTICLE
-//#define PS2_ALTERNATIVE_CARSPLASH // unused on PS2
+// Water & Particle
+#undef PC_WATER
+#define WATER_CHEATS
+
+//#define USE_CUTSCENE_SHADOW_FOR_PED // requires COMPATIBLE_SAVES
+//#define DISABLE_CUTSCENE_SHADOWS
// Pad
#if !defined(RW_GL3) && defined(_WIN32)
#define XINPUT
#endif
-#if defined XINPUT || (defined RW_GL3 && !defined LIBRW_SDL2 && !defined __SWITCH__)
+#if defined XINPUT || (defined RW_GL3 && !defined LIBRW_SDL2 && !defined GTA_HANDHELD)
#define DETECT_JOYSTICK_MENU // Then we'll expect user to enter Controller->Detect joysticks if his joystick isn't detected at the start.
#endif
#define DETECT_PAD_INPUT_SWITCH // Adds automatic switch of pad related stuff between controller and kb/m
#define KANGAROO_CHEAT
-#define ALLCARSHELI_CHEAT
-#define ALT_DODO_CHEAT
+#define RESTORE_ALLCARSHELI_CHEAT
+#define BETTER_ALLCARSAREDODO_CHEAT
+#define WALLCLIMB_CHEAT
#define REGISTER_START_BUTTON
#define BIND_VEHICLE_FIREWEAPON // Adds ability to rebind fire key for 'in vehicle' controls
#define BUTTON_ICONS // use textures to show controller buttons
// Hud, frontend and radar
-//#define PS2_HUD
-#define HUD_ENHANCEMENTS // Adjusts some aspects to make the HUD look/behave a little bit better.
-// #define BETA_SLIDING_TEXT
-#define TRIANGULAR_BLIPS // height indicating triangular radar blips, as in VC
-#define FIX_RADAR // use radar size from early version before R* broke it
-// #define XBOX_SUBTITLES // the infamous outlines
-#define RADIO_OFF_TEXT
#define PC_MENU
+#define FIX_RADAR // use radar size from early version before R* broke it
+#define RADIO_OFF_TEXT // Won't work without FIX_BUGS
#ifndef PC_MENU
# define PS2_MENU
//# define PS2_MENU_USEALLPAGEICONS
#else
-
-# ifdef XINPUT
+# define MAP_ENHANCEMENTS // Adding waypoint and better mouse support
+# if defined(XINPUT) || defined(GTA_HANDHELD)
# define GAMEPAD_MENU // Add gamepad menu
# endif
-
-# define SCROLLABLE_STATS_PAGE // only draggable by mouse atm
# define TRIANGLE_BACK_BUTTON
//# define CIRCLE_BACK_BUTTON
-//# define PS2_LIKE_MENU // An effort to recreate PS2 menu, cycling through tabs, different bg etc.
-//# define PS2_SAVE_DIALOG // PS2 style save dialog with transparent black box
+#define LEGACY_MENU_OPTIONS // i.e. frame sync(vsync)
+#define MUCH_SHORTER_OUTRO_SCREEN
+// #define XBOX_MESSAGE_SCREEN // Blue background, no "saved successfully press OK" screen etc.
# define CUSTOM_FRONTEND_OPTIONS
# ifdef CUSTOM_FRONTEND_OPTIONS
-# define MENU_MAP // VC-like menu map. Won't appear if you don't have our menu.txd
# define GRAPHICS_MENU_OPTIONS // otherwise Display settings will be scrollable
# define NO_ISLAND_LOADING // disable loadscreen between islands via loading all island data at once, consumes more memory and CPU
# define CUTSCENE_BORDERS_SWITCH
# define MULTISAMPLING // adds MSAA option
-# define INVERT_LOOK_FOR_PAD // add bInvertLook4Pad from VC
+# define INVERT_LOOK_FOR_PAD // enable the hidden option
# define PED_CAR_DENSITY_SLIDERS
# endif
#endif
@@ -374,10 +384,18 @@ enum Config {
#define USE_DEBUG_SCRIPT_LOADER // Loads main.scm by default. Hold R for main_freeroam.scm and D for main_d.scm
#define USE_MEASUREMENTS_IN_METERS // makes game use meters instead of feet in script
#define USE_PRECISE_MEASUREMENT_CONVERTION // makes game convert feet to meeters more precisely
+#define SUPPORT_JAPANESE_SCRIPT
+//#define SUPPORT_XBOX_SCRIPT
+#define SUPPORT_MOBILE_SCRIPT
+#define SUPPORT_GINPUT_SCRIPT
+#if (defined SUPPORT_XBOX_SCRIPT && defined SUPPORT_MOBILE_SCRIPT)
+static_assert(false, "SUPPORT_XBOX_SCRIPT and SUPPORT_MOBILE_SCRIPT are mutually exclusive");
+#endif
#ifdef PC_MENU
-# define MISSION_REPLAY // mobile feature
+#define MISSION_REPLAY // mobile feature
+//#define SIMPLER_MISSIONS // apply simplifications from mobile
+#define USE_MISSION_REPLAY_OVERRIDE_FOR_NON_MOBILE_SCRIPT
#endif
-//#define SIMPLIER_MISSIONS // apply simplifications from mobile
#define USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
#define SCRIPT_LOG_FILE_LEVEL 0 // 0 == no log, 1 == overwrite every frame, 2 == full log
@@ -394,47 +412,45 @@ enum Config {
#undef USE_BASIC_SCRIPT_DEBUG_OUTPUT
#endif
+#ifndef MISSION_REPLAY
+#undef USE_MISSION_REPLAY_OVERRIDE_FOR_NON_MOBILE_SCRIPT
+#endif
+
// Replay
//#define DONT_FIX_REPLAY_BUGS // keeps various bugs in CReplay, some of which are fairly cool!
//#define USE_BETA_REPLAY_MODE // adds another replay mode, a few seconds slomo (caution: buggy!)
// Vehicles
#define EXPLODING_AIRTRAIN // can blow up jumbo jet with rocket launcher
-//#define REMOVE_TREADABLE_PATHFIND
+#define CPLANE_ROTORS // make the rotors of the NPC police heli rotate
// Pickups
//#define MONEY_MESSAGES
#define CAMERA_PICKUP
// Peds
-#define PED_SKIN // support for skinned geometry on peds, requires COMPATIBLE_SAVES
-#define ANIMATE_PED_COL_MODEL
-// #define VC_PED_PORTS // various ports from VC's CPed, mostly subtle
-// #define NEW_WALK_AROUND_ALGORITHM // to make walking around vehicles/objects less awkward
#define CANCELLABLE_CAR_ENTER
-//#define PEDS_REPORT_CRIMES_ON_PHONE // requires COMPATIBLE_SAVES
// Camera
-//#define PS2_CAM_TRANSITION // old way of transitioning between cam modes
#define IMPROVED_CAMERA // Better Debug cam, and maybe more in the future
#define FREE_CAM // Rotating cam
// Audio
#define EXTERNAL_3D_SOUND // use external engine to simulate 3d audio spatialization. OpenAL would not work without it (because it works in a 3d space
// originally and making it work in 2d only requires more resource). Will not work on PS2
-#define RADIO_SCROLL_TO_PREV_STATION
-#define AUDIO_CACHE
-#define PS2_AUDIO_CHANNELS // increases the maximum number of audio channels to PS2 value of 44 (PC has 28 originally)
+#define RADIO_SCROLL_TO_PREV_STATION // Won't work without FIX_BUGS
+#define AUDIO_CACHE // cache sound lengths to speed up the cold boot
+#define PS2_AUDIO_CHANNELS // increases the maximum number of audio channels to PS2 value of 43 (PC has 28 originally)
#define PS2_AUDIO_PATHS // changes audio paths for cutscenes and radio to PS2 paths (needs vbdec on MSS builds)
//#define AUDIO_OAL_USE_SNDFILE // use libsndfile to decode WAVs instead of our internal decoder
#define AUDIO_OAL_USE_MPG123 // use mpg123 to support mp3 files
-#define PAUSE_RADIO_IN_FRONTEND // pause radio when game is paused
#define MULTITHREADED_AUDIO // for streams. requires C++11 or later
+#define PAUSE_RADIO_IN_FRONTEND // pause radio when game is paused
#ifdef AUDIO_OPUS
#define AUDIO_OAL_USE_OPUS // enable support of opus files
-#define OPUS_AUDIO_PATHS // changes audio paths to opus paths (doesn't work if AUDIO_OAL_USE_OPUS isn't enabled)
-#define OPUS_SFX // enable if your sfx.raw is encoded with opus (doesn't work if AUDIO_OAL_USE_OPUS isn't enabled)
+//#define OPUS_AUDIO_PATHS // (not supported on VC yet) changes audio paths to opus paths (doesn't work if AUDIO_OAL_USE_OPUS isn't enabled)
+//#define OPUS_SFX // enable if your sfx.raw is encoded with opus (doesn't work if AUDIO_OAL_USE_OPUS isn't enabled)
#ifndef AUDIO_OAL_USE_OPUS
#undef OPUS_AUDIO_PATHS
@@ -456,15 +472,19 @@ enum Config {
#undef NO_ISLAND_LOADING
#undef PS2_AUDIO_CHANNELS
#undef EXTENDED_OFFSCREEN_DESPAWN_RANGE
- #define PC_PARTICLE
- #define VC_PED_PORTS // To not process collisions always. But should be tested if that's really beneficial
- #define VC_RAIN_NERF // Reduces number of rain particles
#endif
// if these defines are enabled saves are not vanilla compatible without COMPATIBLE_SAVES
#ifndef COMPATIBLE_SAVES
-#undef PED_SKIN
-#undef PEDS_REPORT_CRIMES_ON_PHONE
+#undef USE_CUTSCENE_SHADOW_FOR_PED
+#endif
+
+#ifdef GTA_HANDHELD
+ #define IGNORE_MOUSE_KEYBOARD // ignore mouse & keyboard input
+#endif
+
+#ifdef __SWITCH__
+ #define USE_UNNAMED_SEM // named semaphores are unsupported on the switch
#endif
#endif // VANILLA_DEFINES
diff --git a/src/core/main.cpp b/src/core/main.cpp
index 2a0a77ca..e84c6eeb 100644
--- a/src/core/main.cpp
+++ b/src/core/main.cpp
@@ -65,13 +65,16 @@
#include "timebars.h"
#include "GenericGameStorage.h"
#include "MemoryCard.h"
+#include "MemoryHeap.h"
#include "SceneEdit.h"
#include "debugmenu.h"
#include "Clock.h"
+#include "Occlusion.h"
+#include "Ropes.h"
#include "postfx.h"
#include "custompipes.h"
#include "screendroplets.h"
-#include "MemoryHeap.h"
+#include "VarConsole.h"
#ifdef USE_OUR_VERSIONING
#include "GitSHA1.h"
#endif
@@ -105,11 +108,7 @@ RwRGBA gColourTop;
bool gameAlreadyInitialised;
float NumberOfChunksLoaded;
-#ifdef GTA_PS2
-#define TOTALNUMCHUNKS 48.0f
-#else
-#define TOTALNUMCHUNKS 73.0f
-#endif
+#define TOTALNUMCHUNKS 95.0f
bool g_SlowMode = false;
char version_name[64];
@@ -127,7 +126,7 @@ void DebugMenuPopulate(void);
bool gbPrintMemoryUsage;
#endif
-#ifdef PS2_MENU
+#ifdef GTA_PS2
#define WANT_TO_LOAD TheMemoryCard.m_bWantToLoad
#define FOUND_GAME_TO_LOAD TheMemoryCard.b_FoundRecentSavedGameWantToLoad
#else
@@ -137,11 +136,18 @@ bool gbPrintMemoryUsage;
#ifdef NEW_RENDERER
bool gbNewRenderer;
+#endif
+#ifdef FIX_BUGS
+// need to clear stencil for mblur fx. no idea why it works in the original game
+// also for clearing out water rects in new renderer
#define CLEARMODE (rwCAMERACLEARZ | rwCAMERACLEARSTENCIL)
#else
#define CLEARMODE (rwCAMERACLEARZ)
#endif
+bool bDisplayNumOfAtomicsRendered = false;
+bool bDisplayPosn = false;
+
#ifdef __MWERKS__
void
debug(char *fmt, ...)
@@ -201,20 +207,14 @@ DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomR
CRGBA TopColor(TopRed, TopGreen, TopBlue, Alpha);
CRGBA BottomColor(BottomRed, BottomGreen, BottomBlue, Alpha);
-#ifndef ASPECT_RATIO_SCALE
- CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, (CMenuManager::m_PrefsUseWideScreen ? 16.f / 9.f : 4.f / 3.f));
-#else
+ CDraw::CalculateAspectRatio();
CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, SCREEN_ASPECT_RATIO);
-#endif
CVisibilityPlugins::SetRenderWareCamera(Scene.camera);
RwCameraClear(Scene.camera, &TopColor.rwRGBA, CLEARMODE);
if(!RsCameraBeginUpdate(Scene.camera))
return false;
-#ifdef FIX_BUGS
- CSprite2d::SetRecipNearClip();
-#endif
CSprite2d::InitPerFrame();
if(Alpha != 0)
@@ -226,11 +226,8 @@ 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)
{
-#ifndef ASPECT_RATIO_SCALE
- CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, (CMenuManager::m_PrefsUseWideScreen ? 16.f/9.f : 4.f/3.f));
-#else
+ CDraw::CalculateAspectRatio();
CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, SCREEN_ASPECT_RATIO);
-#endif
CVisibilityPlugins::SetRenderWareCamera(Scene.camera);
RwCameraClear(Scene.camera, &gColourTop, CLEARMODE);
@@ -287,13 +284,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)
@@ -318,31 +315,11 @@ DoFade(void)
fadeColor.a = alpha;
}
- if(TheCamera.m_WideScreenOn
-#ifdef CUTSCENE_BORDERS_SWITCH
- && CMenuManager::m_PrefsCutsceneBorders
-#endif
- ){
- // what's this?
- float y = SCREEN_HEIGHT/2 * TheCamera.m_ScreenReductionPercentage/100.0f;
- rect.left = 0.0f;
- rect.right = SCREEN_WIDTH;
-#ifdef FIX_BUGS
- rect.top = y - SCREEN_SCALE_Y(8.0f);
- rect.bottom = SCREEN_HEIGHT - y - SCREEN_SCALE_Y(8.0f);
-#else
- rect.top = y - 8.0f;
- rect.bottom = SCREEN_HEIGHT - y - 8.0f;
-#endif // FIX_BUGS
- }else{
- rect.left = 0.0f;
- rect.right = SCREEN_WIDTH;
- rect.top = 0.0f;
- rect.bottom = SCREEN_HEIGHT;
- }
+ TheCamera.GetScreenRect(rect);
CSprite2d::DrawRect(rect, fadeColor);
if(CDraw::FadeValue != 0 && TheCamera.m_FadeTargetIsSplashScreen){
+ RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR);
fadeColor.r = 255;
fadeColor.g = 255;
fadeColor.b = 255;
@@ -425,7 +402,12 @@ PluginAttach(void)
return FALSE;
}
-
+#ifndef LIBRW
+ if (!RtAnimInitialize())
+ {
+ return FALSE;
+ }
+#endif
if( !RpHAnimPluginAttach() )
{
printf("Couldn't attach RpHAnim plugin\n");
@@ -471,19 +453,21 @@ PluginAttach(void)
}
#ifdef GTA_PS2
-#define NUM_PREALLOC_ATOMICS 3245
-#define NUM_PREALLOC_CLUMPS 101
-#define NUM_PREALLOC_FRAMES 2821
-#define NUM_PREALLOC_GEOMETRIES 1404
-#define NUM_PREALLOC_TEXDICTS 106
-#define NUM_PREALLOC_TEXTURES 1900
-#define NUM_PREALLOC_MATERIALS 3300
+#define NUM_PREALLOC_ATOMICS 1800
+#define NUM_PREALLOC_CLUMPS 80
+#define NUM_PREALLOC_FRAMES 2600
+#define NUM_PREALLOC_GEOMETRIES 850
+#define NUM_PREALLOC_TEXDICTS 121
+#define NUM_PREALLOC_TEXTURES 1700
+#define NUM_PREALLOC_MATERIALS 2600
bool preAlloc;
void
PreAllocateRwObjects(void)
{
int i;
+
+ PUSH_MEMID(MEMID_PRE_ALLOC);
void **tmp = new void*[0x8000];
preAlloc = true;
@@ -524,20 +508,31 @@ PreAllocateRwObjects(void)
delete[] tmp;
preAlloc = false;
+ POP_MEMID();
}
#endif
static RwBool
Initialise3D(void *param)
{
+ PUSH_MEMID(MEMID_RENDER);
+
+#ifndef MASTER
+ VarConsole.Add("Display number of atomics rendered", &bDisplayNumOfAtomicsRendered, true);
+ VarConsole.Add("Display posn and framerate", &bDisplayPosn, true);
+#endif
+
if (RsRwInitialize(param))
{
+ POP_MEMID();
+
#ifdef DEBUGMENU
DebugMenuInit();
DebugMenuPopulate();
#endif // !DEBUGMENU
return CGame::InitialiseRenderWare();
}
+ POP_MEMID();
return (FALSE);
}
@@ -609,16 +604,16 @@ 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;
@@ -656,10 +651,7 @@ LoadingScreen(const char *str1, const char *str2, const char *splashscreen)
#endif
#ifndef RANDOMSPLASH
- if(CGame::frenchGame || CGame::germanGame || !CGame::nastyGame)
- splashscreen = "mainsc2";
- else
- splashscreen = "mainsc1";
+ splashscreen = "LOADSC0";
#endif
splash = LoadSplash(splashscreen);
@@ -669,12 +661,7 @@ LoadingScreen(const char *str1, const char *str2, const char *splashscreen)
return;
#endif
-#ifndef GTA_PS2
- if(DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255))
-#else
- DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255);
-#endif
- {
+ if(DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255)){
CSprite2d::SetRecipNearClip();
CSprite2d::InitPerFrame();
CFont::InitPerFrame();
@@ -685,37 +672,51 @@ 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::SetFontStyle(FONT_STANDARD);
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;
if (str2) {
AsciiToUnicode(str2, tmpstr);
- CFont::PrintString(hpos, vpos, tmpstr);
+ CFont::PrintString(hpos, top, tmpstr);
}
#endif
}
@@ -729,83 +730,19 @@ void
LoadingIslandScreen(const char *levelName)
{
CSprite2d *splash;
- wchar *name;
- char str[100];
- wchar wstr[80];
- CRGBA col;
splash = LoadSplash(nil);
- name = TheText.Get(levelName);
-
-#ifndef GTA_PS2
if(!DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255))
return;
-#else
- DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255);
-#endif
CSprite2d::SetRecipNearClip();
CSprite2d::InitPerFrame();
CFont::InitPerFrame();
DefinedState();
- col = CRGBA(255, 255, 255, 255);
+ CRGBA col = CRGBA(255, 255, 255, 255);
+ CRGBA col2 = CRGBA(0, 0, 0, 255);
+ CSprite2d::DrawRect(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), col2);
splash->Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), col, col, col, col);
- CFont::SetBackgroundOff();
-#ifdef FIX_BUGS
- CFont::SetScale(SCREEN_SCALE_X(1.5f), SCREEN_SCALE_Y(1.5f));
-#else
- CFont::SetScale(1.5f, 1.5f);
-#endif
- CFont::SetPropOn();
- CFont::SetRightJustifyOn();
-#ifdef FIX_BUGS
- CFont::SetRightJustifyWrap(SCREEN_SCALE_X(150.0f));
-#else
- CFont::SetRightJustifyWrap(150.0f);
-#endif
- CFont::SetFontStyle(FONT_HEADING);
- sprintf(str, "WELCOME TO");
- AsciiToUnicode(str, wstr);
- CFont::SetDropColor(CRGBA(0, 0, 0, 255));
- CFont::SetDropShadowPosition(3);
- CFont::SetColor(CRGBA(243, 237, 71, 255));
-#if !defined(PS2_HUD) && defined(GTA_PC)
- CFont::SetScale(SCREEN_SCALE_X(1.2f), SCREEN_SCALE_Y(1.2f));
-#endif
-
-#ifdef PS2_HUD
- #ifdef FIX_BUGS
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f), SCREEN_SCALE_FROM_BOTTOM(140.0f), TheText.Get("WELCOME"));
- #else
- CFont::PrintString(SCREEN_WIDTH - 20, SCREEN_HEIGHT - 140, TheText.Get("WELCOME"));
- #endif
-#else
- #ifdef FIX_BUGS
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f), SCREEN_SCALE_FROM_BOTTOM(110.0f), TheText.Get("WELCOME"));
- #else
- CFont::PrintString(SCREEN_WIDTH - 20, SCREEN_SCALE_FROM_BOTTOM(110.0f), TheText.Get("WELCOME"));
- #endif
-#endif
- TextCopy(wstr, name);
- TheText.UpperCase(wstr);
- CFont::SetColor(CRGBA(243, 237, 71, 255));
-#if !defined(PS2_HUD) && defined(GTA_PC)
- CFont::SetScale(SCREEN_SCALE_X(1.2f), SCREEN_SCALE_Y(1.2f));
-#endif
-
-#ifdef PS2_HUD
- #ifdef FIX_BUGS
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f), SCREEN_SCALE_FROM_BOTTOM(110.0f), wstr);
- #else
- CFont::PrintString(SCREEN_WIDTH-20, SCREEN_HEIGHT - 110, wstr);
- #endif
-#else
- #ifdef FIX_BUGS
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f), SCREEN_SCALE_FROM_BOTTOM(80.0f), wstr);
- #else
- CFont::PrintString(SCREEN_WIDTH-20, SCREEN_SCALE_FROM_BOTTOM(80.0f), wstr);
- #endif
-#endif
CFont::DrawFonts();
DoRWStuffEndOfFrame();
}
@@ -838,7 +775,7 @@ ProcessSlowMode(void)
do
{
- if ( CPad::GetPad(1)->GetLeftShoulder1JustDown() || CPad::GetPad(1)->GetRightShoulder1() )
+ if ( CPad::GetPad(1)->GetSelectJustDown() || CPad::GetPad(1)->GetStart() )
break;
if ( stop )
@@ -852,10 +789,7 @@ ProcessSlowMode(void)
RwCameraBeginUpdate(Scene.camera);
RwCameraEndUpdate(Scene.camera);
- if ( CPad::GetPad(1)->GetLeftShoulder1JustDown() || CPad::GetPad(1)->GetRightShoulder1() )
- break;
-
- } while (!CPad::GetPad(1)->GetRightShoulder1());
+ } while (!CPad::GetPad(1)->GetSelectJustDown() && !CPad::GetPad(1)->GetStart());
CPad::GetPad(0)->OldState.LeftStickX = lX;
@@ -909,22 +843,32 @@ int32 FrameSamples;
#ifndef MASTER
struct tZonePrint
{
- char name[12];
- CRect rect;
+ char name[11];
+ char area[5];
+ CRect rect;
};
tZonePrint ZonePrint[] =
{
- { "suburban", CRect(-1639.4f, 1014.3f, -226.23f, -1347.9f) },
- { "comntop", CRect(-223.52f, 203.62f, 616.79f, -413.6f) },
- { "comnbtm", CRect(-227.24f, -413.6f, 620.51f, -911.84f) },
- { "comse", CRect( 200.35f, -911.84f, 620.51f, -1737.3f) },
- { "comsw", CRect(-223.52f, -911.84f, 200.35f, -1737.3f) },
- { "industsw", CRect( 744.05f, -473.0f, 1067.5f, -1331.5f) },
- { "industne", CRect( 1067.5f, 282.19f, 1915.3f, -473.0f) },
- { "industnw", CRect( 744.05f, 324.95f, 1067.5f, -473.0f) },
- { "industse", CRect( 1070.3f, -473.0f, 1918.1f, -1331.5f) },
- { "no zone", CRect( 0.0f, 0.0f, 0.0f, 0.0f) }
+ { "DOWNTOWN", "GM", CRect(-1500.0f, 1500.0f, -300.0f, 980.0f)},
+ { "DOWNTOWS", "KB", CRect(-1200.0f, 980.0f, -300.0f, 435.0f)},
+ { "GOLF", "NT", CRect(-300.0f, 660.0f, 320.0f, -255.0f)},
+ { "LITTLEHA", "AG", CRect(-1250.0f, -310.0f, -746.0f, -926.0f)},
+ { "HAITI", "CJ", CRect(-1355.0f, 30.0f, -637.0f, -304.0f)},
+ { "HAITIN", "SM", CRect(-1355.0f, 435.0f, -637.0f, 30.0f)},
+ { "DOCKS", "AW", CRect(-1122.0f, -926.0f, -609.0f, -1575.0f)},
+ { "AIRPORT", "NT", CRect(-2000.0f, 200.0f, -871.0f, -2000.0f)},
+ { "STARISL", "CJ", CRect(-724.0f, -320.0f, -40.0f, -380.0f)},
+ { "CENT.ISLA", "NT", CRect(-163.0f, 1260.0f, 120.0f, 830.0f)},
+ { "MALL", "AW", CRect( 300.0f, 1266.0f, 483.0f, 995.0f)},
+ { "MANSION", "KB", CRect(-724.0f, -500.0f, -40.0f, -670.0f)},
+ { "NBEACH", "AS", CRect( 120.0f, 1340.0f, 900.0f, 600.0f)},
+ { "NBEACHBT", "AS", CRect( 200.0f, 680.0f, 660.0f, -50.0f)},
+ { "NBEACHW", "AS", CRect(-93.0f, 80.0f, 410.0f, -680.0f)},
+ { "OCEANDRV", "AC", CRect( 200.0f, -964.0f, 955.0f, -1797.0f)},
+ { "OCEANDN", "WS", CRect( 400.0f, 50.0f, 955.0f, -964.0f)},
+ { "WASHINGTN", "AC", CRect(-320.0f, -487.0f, 500.0f, -1200.0f)},
+ { "WASHINBTM", "AC", CRect(-255.0f, -1200.0f, 500.0f, -1690.0f)}
};
void
@@ -973,7 +917,7 @@ return;
CFont::PrintString(24.0f, y, gUString);
y += 12.0f;
- sprintf(gString, "Render List: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_RENDERLIST), gMainHeap.GetMemoryUsed(MEMID_RENDERLIST));
+ sprintf(gString, "PreAlloc: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_PRE_ALLOC), gMainHeap.GetMemoryUsed(MEMID_PRE_ALLOC));
AsciiToUnicode(gString, gUString);
CFont::PrintString(24.0f, y, gUString);
y += 12.0f;
@@ -998,11 +942,31 @@ return;
CFont::PrintString(24.0f, y, gUString);
y += 12.0f;
+ sprintf(gString, "Streamed LODs: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_STREAM_LODS), gMainHeap.GetMemoryUsed(MEMID_STREAM_LODS));
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(24.0f, y, gUString);
+ y += 12.0f;
+
sprintf(gString, "Streamed Textures: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_STREAM_TEXUTRES), gMainHeap.GetMemoryUsed(MEMID_STREAM_TEXUTRES));
AsciiToUnicode(gString, gUString);
CFont::PrintString(24.0f, y, gUString);
y += 12.0f;
+ sprintf(gString, "Streamed Collision: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_STREAM_COLLISION), gMainHeap.GetMemoryUsed(MEMID_STREAM_COLLISION));
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(24.0f, y, gUString);
+ y += 12.0f;
+
+ sprintf(gString, "Streamed Animation: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_STREAM_ANIMATION), gMainHeap.GetMemoryUsed(MEMID_STREAM_ANIMATION));
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(24.0f, y, gUString);
+ y += 12.0f;
+
+ sprintf(gString, "Ped Attr: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_PED_ATTR), gMainHeap.GetMemoryUsed(MEMID_PED_ATTR));
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(24.0f, y, gUString);
+ y += 12.0f;
+
sprintf(gString, "Animation: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_ANIMATION), gMainHeap.GetMemoryUsed(MEMID_ANIMATION));
AsciiToUnicode(gString, gUString);
CFont::PrintString(24.0f, y, gUString);
@@ -1032,11 +996,6 @@ return;
AsciiToUnicode(gString, gUString);
CFont::PrintString(24.0f, y, gUString);
y += 12.0f;
-
- sprintf(gString, "Frontend: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_FRONTEND), gMainHeap.GetMemoryUsed(MEMID_FRONTEND));
- AsciiToUnicode(gString, gUString);
- CFont::PrintString(24.0f, y, gUString);
- y += 12.0f;
#endif
y = 132.0f;
@@ -1093,13 +1052,13 @@ return;
void
DisplayGameDebugText()
{
- static bool bDisplayPosn = false;
- static bool bDisplayRate = false;
+ static bool bDisplayCheatStr = false; // custom
+
#ifndef FINAL
{
SETTWEAKPATH("Debug");
TWEAKBOOL(bDisplayPosn);
- TWEAKBOOL(bDisplayRate);
+ TWEAKBOOL(bDisplayCheatStr);
}
if(gbPrintMemoryUsage)
@@ -1160,18 +1119,14 @@ DisplayGameDebugText()
CFont::SetPropOn();
CFont::SetBackgroundOff();
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
CFont::SetCentreOff();
CFont::SetRightJustifyOff();
CFont::SetWrapx(SCREEN_WIDTH);
CFont::SetJustifyOff();
CFont::SetBackGroundOnlyTextOff();
CFont::SetColor(CRGBA(255, 108, 0, 255));
-#ifdef FIX_BUGS
CFont::PrintString(SCREEN_SCALE_X(10.0f), SCREEN_SCALE_Y(10.0f), ver);
-#else
- CFont::PrintString(10.0f, 10.0f, ver);
-#endif
}
#endif // #ifdef DRAW_GAME_VERSION_TEXT
@@ -1183,7 +1138,7 @@ DisplayGameDebugText()
PreviousTimeInMillisecondsPauseMode = CTimer::GetTimeInMillisecondsPauseMode();
FramesPerSecond = FrameSamples / FramesPerSecondCounter;
#else
- FramesPerSecondCounter += 1000.0f / CTimer::GetTimeStepNonClippedInMilliseconds();
+ FramesPerSecondCounter += 1000.0f / CTimer::GetTimeStepNonClippedInMilliseconds();
FramesPerSecond = FramesPerSecondCounter / FrameSamples;
#endif
@@ -1192,23 +1147,8 @@ DisplayGameDebugText()
FramesPerSecondCounter = 0.0f;
FrameSamples = 0;
}
-
- if ( !TheCamera.WorldViewerBeingUsed
- && CPad::GetPad(1)->GetSquare()
- && CPad::GetPad(1)->GetTriangle()
- && CPad::GetPad(1)->GetLeftShoulder2JustDown() )
- {
- bDisplayPosn = !bDisplayPosn;
- }
- if ( CPad::GetPad(1)->GetSquare()
- && CPad::GetPad(1)->GetTriangle()
- && CPad::GetPad(1)->GetRightShoulder2JustDown() )
- {
- bDisplayRate = !bDisplayRate;
- }
-
- if ( bDisplayPosn || bDisplayRate )
+ if ( bDisplayPosn )
{
CVector pos = FindPlayerCoors();
int32 ZoneId = ARRAY_SIZE(ZonePrint)-1; // no zone
@@ -1225,44 +1165,48 @@ DisplayGameDebugText()
}
//NOTE: fps should be 30, but its 29 due to different fp2int conversion
- if ( bDisplayRate )
- sprintf(str, "X:%5.1f, Y:%5.1f, Z:%5.1f, F-%d, %s", pos.x, pos.y, pos.z, (int32)FramesPerSecond, ZonePrint[ZoneId].name);
- else
- sprintf(str, "X:%5.1f, Y:%5.1f, Z:%5.1f, %s", pos.x, pos.y, pos.z, ZonePrint[ZoneId].name);
-
+ sprintf(str, "X:%4.0f Y:%4.0f Z:%4.0f F-%d %s-%s", pos.x, pos.y, pos.z, (int32)FramesPerSecond,
+ ZonePrint[ZoneId].name, ZonePrint[ZoneId].area);
+
AsciiToUnicode(str, ustr);
- CFont::SetPropOff();
+ CFont::SetPropOn();
CFont::SetBackgroundOff();
-#ifdef FIX_BUGS
- CFont::SetScale(SCREEN_SCALE_X(0.7f), SCREEN_SCALE_Y(1.5f));
-#else
- CFont::SetScale(0.7f, 1.5f);
-#endif
+ CFont::SetScale(SCREEN_SCALE_X(0.6f), SCREEN_SCALE_Y(0.8f));
CFont::SetCentreOff();
CFont::SetRightJustifyOff();
CFont::SetJustifyOff();
CFont::SetBackGroundOnlyTextOff();
-#ifdef FIX_BUGS
CFont::SetWrapx(SCREEN_STRETCH_X(DEFAULT_SCREEN_WIDTH));
-#else
- CFont::SetWrapx(DEFAULT_SCREEN_WIDTH);
-#endif
- CFont::SetFontStyle(FONT_HEADING);
-
+ CFont::SetFontStyle(FONT_STANDARD);
+ CFont::SetDropColor(CRGBA(0, 0, 0, 255));
+ CFont::SetDropShadowPosition(2);
CFont::SetColor(CRGBA(0, 0, 0, 255));
-#ifdef FIX_BUGS
- CFont::PrintString(SCREEN_SCALE_X(40.0f+2.0f), SCREEN_SCALE_Y(40.0f+2.0f), ustr);
-#else
- CFont::PrintString(40.0f+2.0f, 40.0f+2.0f, ustr);
-#endif
+ CFont::PrintString(41.0f, 41.0f, ustr);
- CFont::SetColor(CRGBA(255, 108, 0, 255));
-#ifdef FIX_BUGS
- CFont::PrintString(SCREEN_SCALE_X(40.0f), SCREEN_SCALE_Y(40.0f), ustr);
-#else
+ CFont::SetColor(CRGBA(205, 205, 0, 255));
CFont::PrintString(40.0f, 40.0f, ustr);
-#endif
+ }
+
+ // custom
+ if (bDisplayCheatStr)
+ {
+ sprintf(str, "%s", CPad::KeyBoardCheatString);
+ AsciiToUnicode(str, ustr);
+
+ CFont::SetPropOn();
+ CFont::SetBackgroundOff();
+ CFont::SetScale(SCREEN_SCALE_X(0.6f), SCREEN_SCALE_Y(0.8f));
+ CFont::SetCentreOn();
+ CFont::SetBackGroundOnlyTextOff();
+ CFont::SetWrapx(SCREEN_STRETCH_X(DEFAULT_SCREEN_WIDTH));
+ CFont::SetFontStyle(FONT_STANDARD);
+
+ 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
@@ -1270,7 +1214,7 @@ DisplayGameDebugText()
#ifdef NEW_RENDERER
bool gbRenderRoads = true;
bool gbRenderEverythingBarRoads = true;
-//bool gbRenderFadingInUnderwaterEntities = true;
+bool gbRenderFadingInUnderwaterEntities = true;
bool gbRenderFadingInEntities = true;
bool gbRenderWater = true;
bool gbRenderBoats = true;
@@ -1287,8 +1231,8 @@ MattRenderScene(void)
// CMattRenderer::ResetRenderStates
/// CRenderer::ClearForFrame(); // before ConstructRenderList
// CClock::CalcEnvMapTimeMultiplicator
-if(gbRenderWater)
- CRenderer::RenderWater(); // actually CMattRenderer::RenderWater
+ RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)rwCULLMODECULLNONE);
+ CWaterLevel::RenderWater(); // actually CMattRenderer::RenderWater
// CClock::ms_EnvMapTimeMultiplicator = 1.0f;
// cWorldStream::ClearDynamics
/// CRenderer::ConstructRenderList(); // before PreRender
@@ -1304,10 +1248,14 @@ if(gbRenderRoads)
CRenderer::RenderPeds();
+ // not sure where to put these since LCS has no underwater entities
if(gbRenderBoats)
CRenderer::RenderBoats();
-//if(gbRenderFadingInUnderwaterEntities)
-// CRenderer::RenderFadingInUnderwaterEntities();
+if(gbRenderFadingInUnderwaterEntities)
+ CRenderer::RenderFadingInUnderwaterEntities();
+ RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)rwCULLMODECULLNONE);
+if(gbRenderWater)
+ CRenderer::RenderTransparentWater();
if(gbRenderEverythingBarRoads)
CRenderer::RenderEverythingBarRoads();
@@ -1375,11 +1323,13 @@ if(gbRenderFadingInEntities)
CGlass::Render();
// CMattRenderer::ResetRenderStates
DefinedState();
+ CCoronas::RenderSunReflection();
CWeather::RenderRainStreaks();
// CWeather::AddSnow
CWaterCannons::Render();
CAntennas::Render();
CSpecialFX::Render();
+ CRopes::Render();
CCoronas::Render();
CParticle::Render();
CPacManPickups::Render();
@@ -1405,16 +1355,17 @@ RenderScene(void)
DoRWRenderHorizon();
CRenderer::RenderRoads();
CCoronas::RenderReflections();
- RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE);
CRenderer::RenderEverythingBarRoads();
- CRenderer::RenderBoats();
- DefinedState();
+ RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)rwCULLMODECULLNONE);
CWaterLevel::RenderWater();
+ CRenderer::RenderBoats();
+ CRenderer::RenderFadingInUnderwaterEntities();
+ RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)rwCULLMODECULLNONE);
+ CWaterLevel::RenderTransparentWater();
CRenderer::RenderFadingInEntities();
-#ifndef SQUEEZE_PERFORMANCE
- CRenderer::RenderVehiclesButNotBoats();
-#endif
+ RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)rwCULLMODECULLNONE);
CWeather::RenderRainStreaks();
+ CCoronas::RenderSunReflection();
POP_RENDERGROUP();
}
@@ -1446,6 +1397,7 @@ RenderEffects(void)
CGlass::Render();
CWaterCannons::Render();
CSpecialFX::Render();
+ CRopes::Render();
CShadows::RenderStaticShadows();
CShadows::RenderStoredShadows();
CSkidmarks::Render();
@@ -1492,11 +1444,12 @@ Render2dStuff(void)
if(cammode == CCam::MODE_SNIPER ||
cammode == CCam::MODE_SNIPER_RUNABOUT ||
cammode == CCam::MODE_ROCKETLAUNCHER ||
- cammode == CCam::MODE_ROCKETLAUNCHER_RUNABOUT)
+ cammode == CCam::MODE_ROCKETLAUNCHER_RUNABOUT ||
+ cammode == CCam::MODE_CAMERA)
firstPersonWeapon = true;
// Draw black border for sniper and rocket launcher
- if((weaponType == WEAPONTYPE_SNIPERRIFLE || weaponType == WEAPONTYPE_ROCKETLAUNCHER) && firstPersonWeapon){
+ if((weaponType == WEAPONTYPE_SNIPERRIFLE || weaponType == WEAPONTYPE_ROCKETLAUNCHER || weaponType == WEAPONTYPE_LASERSCOPE) && firstPersonWeapon){
CRGBA black(0, 0, 0, 255);
// top and bottom strips
@@ -1520,12 +1473,17 @@ Render2dStuff(void)
else
#endif
CHud::Draw();
+
+ CSpecialFX::Render2DFXs();
CUserDisplay::OnscnTimer.ProcessForDisplay();
CMessages::Display();
CDarkel::DrawMessages();
CGarages::PrintMessages();
CPad::PrintErrorMessage();
CFont::DrawFonts();
+#ifndef MASTER
+ COcclusion::Render();
+#endif
#ifdef DEBUGMENU
DebugMenuRender();
@@ -1539,11 +1497,13 @@ RenderMenus(void)
if (FrontEndMenuManager.m_bMenuActive)
{
PUSH_RENDERGROUP("RenderMenus");
- PUSH_MEMID(MEMID_FRONTEND);
FrontEndMenuManager.DrawFrontEnd();
- POP_MEMID();
POP_RENDERGROUP();
}
+#ifndef MASTER
+ else
+ VarConsole.Check();
+#endif
}
void
@@ -1554,18 +1514,18 @@ Render2dStuffAfterFade(void)
DisplayGameDebugText();
#endif
+#ifdef MOBILE_IMPROVEMENTS
+ if (CDraw::FadeValue != 0)
+#endif
CHud::DrawAfterFade();
CFont::DrawFonts();
+ CCredits::Render();
POP_RENDERGROUP();
}
void
Idle(void *arg)
{
-#ifdef ASPECT_RATIO_SCALE
- CDraw::SetAspectRatio(CDraw::FindAspectRatio());
-#endif
-
CTimer::Update();
tbInit();
@@ -1573,32 +1533,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 {
- PUSH_MEMID(MEMID_GAME_PROCESS);
- CPointLights::InitPerFrame();
- tbStartTimer(0, "CGame::Process");
- CGame::Process();
- tbEndTimer("CGame::Process");
- POP_MEMID();
-
- tbStartTimer(0, "DMAudio.Service");
- DMAudio.Service();
- tbEndTimer("DMAudio.Service");
- }
-
- if (RsGlobal.quit)
- return;
-#else
-
PUSH_MEMID(MEMID_GAME_PROCESS);
CPointLights::InitPerFrame();
@@ -1610,7 +1544,6 @@ Idle(void *arg)
tbStartTimer(0, "DMAudio.Service");
DMAudio.Service();
tbEndTimer("DMAudio.Service");
-#endif
if(CGame::bDemoMode && CTimer::GetTimeInMilliseconds() > (3*60 + 30)*1000 && !CCutsceneMgr::IsCutsceneProcessing()){
WANT_TO_LOAD = false;
@@ -1630,21 +1563,20 @@ Idle(void *arg)
PUSH_MEMID(MEMID_RENDER);
- if((!FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bRenderGameInMenu) &&
- TheCamera.GetScreenFadeStatus() != FADE_2)
+ if(!FrontEndMenuManager.m_bMenuActive && TheCamera.GetScreenFadeStatus() != FADE_2)
{
-#if defined(GTA_PC) && !defined(RW_GL3) && defined(FIX_BUGS)
// This is from SA, but it's nice for windowed mode
- if (!FrontEndMenuManager.m_bRenderGameInMenu) {
- RwV2d pos;
- pos.x = SCREEN_WIDTH / 2.0f;
- pos.y = SCREEN_HEIGHT / 2.0f;
- RsMouseSetPos(&pos);
- }
+#if defined(GTA_PC) && !defined(RW_GL3)
+ RwV2d pos;
+ pos.x = SCREEN_WIDTH / 2.0f;
+ pos.y = SCREEN_HEIGHT / 2.0f;
+ RsMouseSetPos(&pos);
#endif
- PUSH_MEMID(MEMID_RENDERLIST);
tbStartTimer(0, "CnstrRenderList");
+#ifdef PC_WATER
+ CWaterLevel::PreCalcWaterGeometry();
+#endif
#ifdef NEW_RENDERER
if(gbNewRenderer){
CWorld::AdvanceCurrentScanCode(); // don't think this is even necessary
@@ -1657,7 +1589,6 @@ Idle(void *arg)
tbStartTimer(0, "PreRender");
CRenderer::PreRender();
tbEndTimer("PreRender");
- POP_MEMID();
#ifdef FIX_BUGS
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void *)FALSE); // TODO: temp? this fixes OpenGL render but there should be a better place for this
@@ -1712,6 +1643,7 @@ Idle(void *arg)
Render2dStuff();
tbEndTimer("Render2dStuff");
}else{
+ CDraw::CalculateAspectRatio();
#ifdef ASPECT_RATIO_SCALE
CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, SCREEN_ASPECT_RATIO);
#else
@@ -1723,10 +1655,6 @@ Idle(void *arg)
goto popret;
}
-#ifdef PS2_SAVE_DIALOG
- if (FrontEndMenuManager.m_bMenuActive)
- DefinedState();
-#endif
tbStartTimer(0, "RenderMenus");
RenderMenus();
tbEndTimer("RenderMenus");
@@ -1743,9 +1671,10 @@ Idle(void *arg)
tbStartTimer(0, "Render2dStuff-Fade");
Render2dStuffAfterFade();
tbEndTimer("Render2dStuff-Fade");
-
- CCredits::Render();
-
+ // CCredits::Render(); // They added it to function above and also forgot it here
+#ifdef XBOX_MESSAGE_SCREEN
+ FrontEndMenuManager.DrawOverlays();
+#endif
if (gbShowTimebars)
tbDisplay();
@@ -1764,10 +1693,7 @@ popret: POP_MEMID(); // MEMID_RENDER
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();
@@ -1778,11 +1704,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, CLEARMODE);
if(!RsCameraBeginUpdate(Scene.camera))
@@ -1790,9 +1712,12 @@ FrontendIdle(void)
DefinedState(); // seems redundant, but breaks resolution change.
RenderMenus();
+#ifdef XBOX_MESSAGE_SCREEN
+ FrontEndMenuManager.DrawOverlays();
+#endif
DoFade();
Render2dStuffAfterFade();
-// CFont::DrawFonts(); // redundant
+ CFont::DrawFonts();
DoRWStuffEndOfFrame();
}
@@ -1800,7 +1725,7 @@ void
InitialiseGame(void)
{
LoadingScreen(nil, nil, "loadsc0");
- CGame::Initialise("DATA\\GTA3.DAT");
+ CGame::Initialise("DATA\\GTA_VC.DAT");
}
RsEventStatus
@@ -1863,11 +1788,7 @@ AppEventHandler(RsEvent event, void *param)
case rsFRONTENDIDLE:
{
-#ifdef PS2_SAVE_DIALOG
- Idle((void*)1);
-#else
FrontendIdle();
-#endif
return rsEVENTPROCESSED;
}
@@ -1893,20 +1814,20 @@ TheModelViewer(void)
#if (defined(GTA_PS2) || defined(GTA_XBOX))
//TODO
#else
- // This is III Mobile code. III Xbox code run it like main function, which is impossible to implement on PC's state machine implementation.
- // Also we want 2D things initialized in here to print animation ids etc., our additions for that marked with X
-#ifdef ASPECT_RATIO_SCALE
- CDraw::SetAspectRatio(CDraw::FindAspectRatio()); // X
-#endif
+ // This is not original. Because;
+ // 1- We want 2D things to be initalized, whereas original AnimViewer doesn't use them. my additions marked with X
+ // 2- VC Mobile code run it like main function(as opposed to III and LCS), so it has it's own loop inside it, but our func. already called in a loop.
+
+ CDraw::CalculateAspectRatio(); // X
CAnimViewer::Update();
- CTimer::Update();
SetLightsWithTimeOfDayColour(Scene.world);
CRenderer::ConstructRenderList();
- DoRWStuffStartOfFrame(CTimeCycle::GetSkyTopRed(), CTimeCycle::GetSkyTopGreen(), CTimeCycle::GetSkyTopBlue(),
+ DoRWStuffStartOfFrame(CTimeCycle::GetSkyTopRed()*0.5f, CTimeCycle::GetSkyTopGreen()*0.5f, CTimeCycle::GetSkyTopBlue()*0.5f,
CTimeCycle::GetSkyBottomRed(), CTimeCycle::GetSkyBottomGreen(), CTimeCycle::GetSkyBottomBlue(),
255);
+ CSprite2d::SetRecipNearClip(); // X
CSprite2d::InitPerFrame(); // X
CFont::InitPerFrame(); // X
DefinedState();
@@ -1914,6 +1835,7 @@ TheModelViewer(void)
CAnimViewer::Render();
Render2dStuff(); // X
DoRWStuffEndOfFrame();
+ CTimer::Update();
#endif
}
#endif
@@ -1928,17 +1850,14 @@ void TheGame(void)
CTimer::Initialise();
-#if GTA_VERSION <= GTA3_PS2_160
- CGame::Initialise();
-#else
CGame::Initialise("DATA\\GTA3.DAT");
-#endif
Const char *splash = GetRandomSplashScreen(); // inlined here
LoadingScreen("Starting Game", NULL, splash);
#ifdef GTA_PS2
+ // TODO(MIAMI): not checked yet
if ( TheMemoryCard.CheckCardInserted(CARD_ONE) == CMemoryCard::NO_ERR_SUCCESS
&& TheMemoryCard.ChangeDirectory(CARD_ONE, TheMemoryCard.Cards[CARD_ONE].dir)
&& TheMemoryCard.FindMostRecentFileName(CARD_ONE, TheMemoryCard.MostRecentFile) == true
@@ -1947,9 +1866,9 @@ void TheGame(void)
strcpy(TheMemoryCard.LoadFileName, TheMemoryCard.MostRecentFile);
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();
}
@@ -1962,7 +1881,7 @@ void TheGame(void)
while (true)
{
- if (WANT_TO_LOAD)
+ if (FOUND_GAME_TO_LOAD)
{
Const char *splash1 = GetLevelSplashScreen(CGame::currLevel);
LoadSplash(splash1);
@@ -1998,13 +1917,12 @@ void TheGame(void)
PUSH_MEMID(MEMID_RENDER);
+ CRenderer::ConstructRenderList();
+
if ((!FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bRenderGameInMenu == true) && TheCamera.GetScreenFadeStatus() != FADE_2 )
{
-
- PUSH_MEMID(MEMID_RENDERLIST);
- CRenderer::ConstructRenderList();
CRenderer::PreRender();
- POP_MEMID();
+ // TODO(MIAMI): something ps2all specific
#ifdef FIX_BUGS
// This has to be done BEFORE RwCameraBeginUpdate
@@ -2035,11 +1953,7 @@ void TheGame(void)
}
else
{
-#ifdef ASPECT_RATIO_SCALE
- CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, SCREEN_ASPECT_RATIO);
-#else
- CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, DEFAULT_ASPECT_RATIO);
-#endif
+ CameraSize(Scene.camera, NULL, SCREEN_VIEWWINDOW, SCREEN_ASPECT_RATIO);
CVisibilityPlugins::SetRenderWareCamera(Scene.camera);
RwCameraClear(Scene.camera, &gColourTop, CLEARMODE);
RsCameraBeginUpdate(Scene.camera);
@@ -2102,10 +2016,6 @@ void TheGame(void)
void SystemInit()
{
-#ifdef __MWERKS__
- mwInit();
-#endif
-
#ifdef USE_CUSTOM_ALLOCATOR
InitMemoryMgr();
#endif
@@ -2115,7 +2025,7 @@ void SystemInit()
char path[256];
- sprintf(path, "cdrom0:\\%s%s;1", "SYSTEM\\", "IOPRP23.IMG");
+ sprintf(path, "cdrom0:\\%s%s;1", "SYSTEM\\", "IOPRP241.IMG");
sceSifInitRpc(0);
@@ -2129,11 +2039,7 @@ void SystemInit()
CFileMgr::InitCdSystem();
sceFsReset();
-#endif
- CFileMgr::Initialise();
-
-#ifdef GTA_PS2
CFileMgr::InitCd();
char modulepath[256];
@@ -2167,6 +2073,16 @@ void SystemInit()
strcat(modulepath, "SYSTEM\\");
strcat(modulepath, "MCSERV.IRX");
LoadModule(modulepath);
+
+ strcpy(modulepath, "cdrom0:\\");
+ strcat(modulepath, "SYSTEM\\");
+ strcat(modulepath, "CDSTREAM.IRX");
+ LoadModule(modulepath);
+
+ strcpy(modulepath, "cdrom0:\\");
+ strcat(modulepath, "SYSTEM\\");
+ strcat(modulepath, "SAMPMAN2.IRX");
+ LoadModule(modulepath);
#endif
@@ -2193,30 +2109,31 @@ void SystemInit()
CGame::frenchGame = false;
CGame::germanGame = false;
CGame::nastyGame = true;
- CMenuManager::m_PrefsAllowNastyGame = true;
+ FrontEndMenuManager.m_PrefsAllowNastyGame = true;
#ifdef GTA_PS2
+ // TODO(MIAMI): this code probably went elsewhere?
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
@@ -2242,43 +2159,35 @@ extern "C" void WaitVBlank(void)
while(startFrame == frameCount);
}
-void GameInit()
+void GameInit(bool onlyRW)
{
- if ( !gameAlreadyInitialised )
+ if(onlyRW)
{
#ifdef GTA_PS2
- char path[256];
-
- strcpy(path, "cdrom0:\\");
- strcat(path, "SYSTEM\\");
- strcat(path, "CDSTREAM.IRX");
- LoadModule(path);
-
- strcpy(path, "cdrom0:\\");
- strcat(path, "SYSTEM\\");
- strcat(path, "SAMPMAN.IRX");
- LoadModule(path);
-
- strcpy(path, "cdrom0:\\");
- strcat(path, "SYSTEM\\");
- strcat(path, "MUSICSTR.IRX");
- LoadModule(path);
+ Initialise3D(nil);
+#else
+ Initialise3D(nil); //TODO: window parameter
#endif
- CdStreamInit(MAX_CDCHANNELS);
-
+ gameAlreadyInitialised = true;
+ }
+ else
+ {
+ if ( !gameAlreadyInitialised )
#ifdef GTA_PS2
- Initialise3D(); //no params
+ Initialise3D(nil);
#else
- //TODO
+ Initialise3D(nil); //TODO: window parameter
#endif
-
+ }
+
#ifdef GTA_PS2
char *files[] =
{
"\\ANIM\\CUTS.IMG;1",
"\\ANIM\\CUTS.DIR;1",
"\\ANIM\\PED.IFP;1",
- "\\MODELS\\FRONTEND.TXD;1",
+ "\\MODELS\\FRONTEN1.TXD;1",
+ "\\MODELS\\FRONTEN2.TXD;1",
"\\MODELS\\FONTS.TXD;1",
"\\MODELS\\HUD.TXD;1",
"\\MODELS\\PARTICLE.TXD;1",
@@ -2295,6 +2204,96 @@ void GameInit()
#else
"\\TEXT\\AMERICAN.GXT;1",
#endif
+ "\\MODELS\\COLL\\GENERIC.COL;1",
+ "\\MODELS\\COLL\\VEHICLES.COL;1",
+ "\\MODELS\\COLL\\PEDS.COL;1",
+ "\\MODELS\\COLL\\WEAPONS.COL;1",
+ "\\MODELS\\GENERIC\\AIR_VLO.DFF;1",
+ "\\MODELS\\GENERIC\\WHEELS.DFF;1",
+ "\\MODELS\\GENERIC\\ARROW.DFF;1",
+ "\\MODELS\\GENERIC\\ZONECYLB.DFF;1",
+ "\\DATA\\HANDLING.CFG;1",
+ "\\DATA\\SURFACE.DAT;1",
+ "\\DATA\\PEDSTATS.DAT;1",
+ "\\DATA\\TIMECYC.DAT;1",
+ "\\DATA\\PARTICLE.CFG;1",
+ "\\DATA\\DEFAULT.DAT;1",
+ "\\DATA\\DEFAULT.IDE;1",
+ "\\DATA\\GTA_VC.DAT;1",
+ "\\DATA\\OBJECT.DAT;1",
+ "\\DATA\\MAP.ZON;1",
+ "\\DATA\\NAVIG.ZON;1",
+ "\\DATA\\INFO.ZON;1",
+ "\\DATA\\WATERPRO.DAT;1",
+ "\\DATA\\MAIN.SCM;1",
+ "\\DATA\\CARCOLS.DAT;1",
+ "\\DATA\\PED.DAT;1",
+ "\\DATA\\FISTFITE.DAT;1",
+ "\\DATA\\WEAPON.DAT;1",
+ "\\DATA\\PEDGRP.DAT;1",
+ "\\DATA\\PATHS\\FLIGHT.DAT;1",
+ "\\DATA\\PATHS\\FLIGHT2.DAT;1",
+ "\\DATA\\PATHS\\FLIGHT3.DAT;1",
+ "\\DATA\\PATHS\\SPATH0.DAT;1",
+ "\\DATA\\MAPS\\LITTLEHA\\LITTLEHA.IDE;1",
+ "\\DATA\\MAPS\\DOWNTOWN\\DOWNTOWN.IDE;1",
+ "\\DATA\\MAPS\\DOWNTOWS\\DOWNTOWS.IDE;1",
+ "\\DATA\\MAPS\\DOCKS\\DOCKS.IDE;1",
+ "\\DATA\\MAPS\\WASHINTN\\WASHINTN.IDE;1",
+ "\\DATA\\MAPS\\WASHINTS\\WASHINTS.IDE;1",
+ "\\DATA\\MAPS\\OCEANDRV\\OCEANDRV.IDE;1",
+ "\\DATA\\MAPS\\OCEANDN\\OCEANDN.IDE;1",
+ "\\DATA\\MAPS\\GOLF\\GOLF.IDE;1",
+ "\\DATA\\MAPS\\BRIDGE\\BRIDGE.IDE;1",
+ "\\DATA\\MAPS\\STARISL\\STARISL.IDE;1",
+ "\\DATA\\MAPS\\NBEACHBT\\NBEACHBT.IDE;1",
+ "\\DATA\\MAPS\\NBEACHW\\NBEACHW.IDE;1",
+ "\\DATA\\MAPS\\NBEACH\\NBEACH.IDE;1",
+ "\\DATA\\MAPS\\BANK\\BANK.IDE;1",
+ "\\DATA\\MAPS\\MALL\\MALL.IDE;1",
+ "\\DATA\\MAPS\\YACHT\\YACHT.IDE;1",
+ "\\DATA\\MAPS\\CISLAND\\CISLAND.IDE;1",
+ "\\DATA\\MAPS\\CLUB\\CLUB.IDE;1",
+ "\\DATA\\MAPS\\HOTEL\\HOTEL.IDE;1",
+ "\\DATA\\MAPS\\LAWYERS\\LAWYERS.IDE;1",
+ "\\DATA\\MAPS\\STRIPCLB\\STRIPCLB.IDE;1",
+ "\\DATA\\MAPS\\AIRPORT\\AIRPORT.IDE;1",
+ "\\DATA\\MAPS\\HAITI\\HAITI.IDE;1",
+ "\\DATA\\MAPS\\HAITIN\\HAITIN.IDE;1",
+ "\\DATA\\MAPS\\CONCERTH\\CONCERTH.IDE;1",
+ "\\DATA\\MAPS\\MANSION\\MANSION.IDE;1",
+ "\\DATA\\MAPS\\ISLANDSF\\ISLANDSF.IDE;1",
+ "\\DATA\\MAPS\\LITTLEHA\\LITTLEHA.IPL;1",
+ "\\DATA\\MAPS\\DOWNTOWN\\DOWNTOWN.IPL;1",
+ "\\DATA\\MAPS\\DOWNTOWS\\DOWNTOWS.IPL;1",
+ "\\DATA\\MAPS\\DOCKS\\DOCKS.IPL;1",
+ "\\DATA\\MAPS\\WASHINTN\\WASHINTN.IPL;1",
+ "\\DATA\\MAPS\\WASHINTS\\WASHINTS.IPL;1",
+ "\\DATA\\MAPS\\OCEANDRV\\OCEANDRV.IPL;1",
+ "\\DATA\\MAPS\\OCEANDN\\OCEANDN.IPL;1",
+ "\\DATA\\MAPS\\GOLF\\GOLF.IPL;1",
+ "\\DATA\\MAPS\\BRIDGE\\BRIDGE.IPL;1",
+ "\\DATA\\MAPS\\STARISL\\STARISL.IPL;1",
+ "\\DATA\\MAPS\\NBEACHBT\\NBEACHBT.IPL;1",
+ "\\DATA\\MAPS\\NBEACH\\NBEACH.IPL;1",
+ "\\DATA\\MAPS\\NBEACHW\\NBEACHW.IPL;1",
+ "\\DATA\\MAPS\\CISLAND\\CISLAND.IPL;1",
+ "\\DATA\\MAPS\\AIRPORT\\AIRPORT.IPL;1",
+ "\\DATA\\MAPS\\HAITI\\HAITI.IPL;1",
+ "\\DATA\\MAPS\\HAITIN\\HAITIN.IPL;1",
+ "\\DATA\\MAPS\\ISLANDSF\\ISLANDSF.IPL;1",
+ "\\DATA\\MAPS\\BANK\\BANK.IPL;1",
+ "\\DATA\\MAPS\\MALL\\MALL.IPL;1",
+ "\\DATA\\MAPS\\YACHT\\YACHT.IPL;1",
+ "\\DATA\\MAPS\\CLUB\\CLUB.IPL;1",
+ "\\DATA\\MAPS\\HOTEL\\HOTEL.IPL;1",
+ "\\DATA\\MAPS\\LAWYERS\\LAWYERS.IPL;1",
+ "\\DATA\\MAPS\\STRIPCLB\\STRIPCLB.IPL;1",
+ "\\DATA\\MAPS\\CONCERTH\\CONCERTH.IPL;1",
+ "\\DATA\\MAPS\\MANSION\\MANSION.IPL;1",
+ "\\DATA\\MAPS\\GENERIC.IDE;1",
+ "\\DATA\\OCCLU.IPL;1",
+ "\\DATA\\MAPS\\PATHS.IPL;1",
"\\TXD\\LOADSC0.TXD;1",
"\\TXD\\LOADSC1.TXD;1",
"\\TXD\\LOADSC2.TXD;1",
@@ -2309,90 +2308,17 @@ void GameInit()
"\\TXD\\LOADSC11.TXD;1",
"\\TXD\\LOADSC12.TXD;1",
"\\TXD\\LOADSC13.TXD;1",
- "\\TXD\\LOADSC14.TXD;1",
- "\\TXD\\LOADSC15.TXD;1",
- "\\TXD\\LOADSC16.TXD;1",
- "\\TXD\\LOADSC17.TXD;1",
- "\\TXD\\LOADSC18.TXD;1",
- "\\TXD\\LOADSC19.TXD;1",
- "\\TXD\\LOADSC20.TXD;1",
- "\\TXD\\LOADSC21.TXD;1",
- "\\TXD\\LOADSC22.TXD;1",
- "\\TXD\\LOADSC23.TXD;1",
- "\\TXD\\LOADSC24.TXD;1",
- "\\TXD\\LOADSC25.TXD;1",
- "\\TXD\\NEWS.TXD;1",
- "\\MODELS\\COLL\\GENERIC.COL;1",
- "\\MODELS\\COLL\\INDUST.COL;1",
- "\\MODELS\\COLL\\COMMER.COL;1",
- "\\MODELS\\COLL\\SUBURB.COL;1",
- "\\MODELS\\COLL\\WEAPONS.COL;1",
- "\\MODELS\\COLL\\VEHICLES.COL;1",
- "\\MODELS\\COLL\\PEDS.COL;1",
- "\\MODELS\\GENERIC\\AIR_VLO.DFF;1",
- "\\MODELS\\GENERIC\\WEAPONS.DFF;1",
- "\\MODELS\\GENERIC\\WHEELS.DFF;1",
- "\\MODELS\\GENERIC\\LOPLYGUY.DFF;1",
- "\\MODELS\\GENERIC\\ARROW.DFF;1",
- "\\MODELS\\GENERIC\\ZONECYLB.DFF;1",
- "\\DATA\\MAPS\\COMNTOP.IPL;1",
- "\\DATA\\MAPS\\COMNBTM.IPL;1",
- "\\DATA\\MAPS\\COMSE.IPL;1",
- "\\DATA\\MAPS\\COMSW.IPL;1",
- "\\DATA\\MAPS\\CULL.IPL;1",
- "\\DATA\\MAPS\\INDUSTNE.IPL;1",
- "\\DATA\\MAPS\\INDUSTNW.IPL;1",
- "\\DATA\\MAPS\\INDUSTSE.IPL;1",
- "\\DATA\\MAPS\\INDUSTSW.IPL;1",
- "\\DATA\\MAPS\\SUBURBNE.IPL;1",
- "\\DATA\\MAPS\\SUBURBSW.IPL;1",
- "\\DATA\\MAPS\\OVERVIEW.IPL;1",
- "\\DATA\\MAPS\\PROPS.IPL;1",
- "\\DATA\\MAPS\\GTA3.IDE;1",
- "\\DATA\\PATHS\\FLIGHT.DAT;1",
- "\\DATA\\PATHS\\FLIGHT2.DAT;1",
- "\\DATA\\PATHS\\FLIGHT3.DAT;1",
- "\\DATA\\PATHS\\FLIGHT4.DAT;1",
- "\\DATA\\PATHS\\TRACKS.DAT;1",
- "\\DATA\\PATHS\\TRACKS2.DAT;1",
- "\\DATA\\PATHS\\CHASE0.DAT;1",
- "\\DATA\\PATHS\\CHASE1.DAT;1",
- "\\DATA\\PATHS\\CHASE2.DAT;1",
- "\\DATA\\PATHS\\CHASE3.DAT;1",
- "\\DATA\\PATHS\\CHASE4.DAT;1",
- "\\DATA\\PATHS\\CHASE5.DAT;1",
- "\\DATA\\PATHS\\CHASE6.DAT;1",
- "\\DATA\\PATHS\\CHASE7.DAT;1",
- "\\DATA\\PATHS\\CHASE10.DAT;1",
- "\\DATA\\PATHS\\CHASE11.DAT;1",
- "\\DATA\\PATHS\\CHASE14.DAT;1",
- "\\DATA\\PATHS\\CHASE16.DAT;1",
- "\\DATA\\PATHS\\CHASE18.DAT;1",
- "\\DATA\\PATHS\\CHASE19.DAT;1"
+ "\\TXD\\SPLASH1.TXD;1"
};
for ( int32 i = 0; i < ARRAY_SIZE(files); i++ )
SkyRegisterFileOnCd([i]);
#endif
- CreateDebugFont();
-
#ifdef GTA_PS2
AddIntcHandler(INTC_VBLANK_S, VBlankCounter, 0);
#endif
- CameraSize(Scene.camera, NULL, DEFAULT_VIEWWINDOW, DEFAULT_ASPECT_RATIO);
-
- CSprite2d::SetRecipNearClip();
- CTxdStore::Initialise();
-
- PUSH_MEMID(MEMID_TEXTURES);
- CFont::Initialise();
- CHud::Initialise();
- POP_MEMID();
-
- ValidateVersion();
-
#ifdef GTA_PS2
sceCdCLOCK rtc;
sceCdReadClock(&rtc);
@@ -2404,10 +2330,13 @@ void GameInit()
//TODO: mysrand();
#endif
- gameAlreadyInitialised = true;
+ // gameAlreadyInitialised = true; // why is this gone?
}
}
+int32 SkipAllMPEGs;
+int32 gMemoryStickLoadOK;
+
void PlayIntroMPEGs()
{
#ifdef GTA_PS2
@@ -2416,17 +2345,33 @@ void PlayIntroMPEGs()
InitMPEGPlayer();
+ float skipTime; // wrong type, should be int
#ifdef GTA_PAL
- PlayMPEG("cdrom0:\\MOVIES\\DMAPAL.PSS;1", false);
-
- if (CGame::frenchGame || CGame::germanGame)
- PlayMPEG("cdrom0:\\MOVIES\\INTROPAF.PSS;1", true);
+ if(gMemoryStickLoadOK)
+ skipTime = 2500000;
else
- PlayMPEG("cdrom0:\\MOVIES\\INTROPAL.PSS;1", true);
+ skipTime = 5300000;
+
+ if(!SkipAllMPEGs)
+ PlayMPEG("cdrom0:\\MOVIES\\VCPAL.PSS;1", false, unk);
+
+ if(!SkipAllMPEGs){
+ SkipAllMPEGs = true;
+ PlayMPEG("cdrom0:\\MOVIES\\VICEPAL.PSS;1", true, 0);
+ }
#else
- PlayMPEG("cdrom0:\\MOVIES\\DMANTSC.PSS;1", false);
+ if(gMemoryStickLoadOK)
+ skipTime = 2750000;
+ else
+ skipTime = 5500000;
+
+ if(!SkipAllMPEGs)
+ PlayMPEG("cdrom0:\\MOVIES\\VCNTSC.PSS;1", false, unk);
- PlayMPEG("cdrom0:\\MOVIES\\INTRNTSC.PSS;1", true);
+ if(!SkipAllMPEGs){
+ SkipAllMPEGs = true;
+ PlayMPEG("cdrom0:\\MOVIES\\VICE.PSS;1", true, 0);
+ }
#endif
ShutdownMPEGPlayer();
@@ -2446,13 +2391,16 @@ main(int argc, char *argv[])
#endif
SystemInit();
-
+
+ if(RsEventHandler(rsINITIALIZE, nil) == rsEVENTERROR)
+ return 0;
+
#ifdef GTA_PS2
int32 r = TheMemoryCard.CheckCardStateAtGameStartUp(CARD_ONE);
if ( r == CMemoryCard::ERR_DIRNOENTRY || r == CMemoryCard::ERR_NOFORMAT )
{
- GameInit();
+ GameInit(true);
TheText.Unload();
TheText.Load();
@@ -2460,24 +2408,24 @@ main(int argc, char *argv[])
CFont::Initialise();
FrontEndMenuManager.DrawMemoryCardStartUpMenus();
- }else if(r == CMemoryCard::ERR_OPENNOENTRY || r == CMemoryCard::ERR_NONE){
- // eh?
- }
+ }else if(r == CMemoryCard::ERR_OPENNOENTRY)
+ gMemoryStickLoadOK = false;
+ else if(r == CMemoryCard::ERR_NONE)
+ gMemoryStickLoadOK = true;
#endif
PlayIntroMPEGs();
- GameInit();
+ GameInit(false);
+
+ frameCount = 0;
+ while(frameCount < 100);
+
+ CGame::InitialiseOnceAfterRW();
- if ( CGame::frenchGame || CGame::germanGame )
- LoadingScreen(NULL, version_name, "loadsc24");
- else
- LoadingScreen(NULL, version_name, "loadsc0");
-
- DMAudio.Initialise();
-
TheGame();
-
+
+#if 0 // maybe ifndef FINAL or MASTER?
CGame::ShutDown();
RwEngineStop();
@@ -2487,7 +2435,7 @@ main(int argc, char *argv[])
#ifdef __MWERKS__
mwExit(); // metrowerks shutdown
#endif
-
+#endif
return 0;
}
#endif
diff --git a/src/core/re3.cpp b/src/core/re3.cpp
index 4914cd9c..d3b1f266 100644
--- a/src/core/re3.cpp
+++ b/src/core/re3.cpp
@@ -10,18 +10,20 @@
#endif
#endif
#include "Renderer.h"
+#include "Occlusion.h"
#include "Credits.h"
#include "Camera.h"
#include "Weather.h"
+#include "Timecycle.h"
#include "Clock.h"
#include "World.h"
#include "Vehicle.h"
#include "ModelIndices.h"
#include "Streaming.h"
-#include "PathFind.h"
#include "Boat.h"
#include "Heli.h"
#include "Automobile.h"
+#include "Bike.h"
#include "Console.h"
#include "Debug.h"
#include "Hud.h"
@@ -34,6 +36,7 @@
#include "WaterLevel.h"
#include "main.h"
#include "Script.h"
+#include "MBlur.h"
#include "postfx.h"
#include "custompipes.h"
#include "MemoryHeap.h"
@@ -45,15 +48,15 @@
#include "Population.h"
#include "IniFile.h"
-#ifdef DETECT_JOYSTICK_MENU
#include "crossplatform.h"
-#endif
#ifndef _WIN32
#include "assert.h"
#include <stdarg.h>
#endif
+#include <list>
+
#ifdef RWLIBS
extern "C" int vsprintf(char* const _Buffer, char const* const _Format, va_list _ArgList);
#endif
@@ -88,6 +91,8 @@ mysrand(unsigned int seed)
#ifdef CUSTOM_FRONTEND_OPTIONS
#include "frontendoption.h"
+
+
#ifdef MORE_LANGUAGES
void LangPolSelect(int8 action)
{
@@ -125,8 +130,8 @@ CustomFrontendOptionsPopulate(void)
{
// Most of custom options are done statically in MenuScreensCustom.cpp, we add them here only if they're dependent to extra files
- // These work only if we have neo folder
int fd;
+ // These work only if we have neo folder, so they're dynamically added
#ifdef EXTENDED_PIPELINES
const char *vehPipelineNames[] = { "FED_MFX", "FED_NEO" };
const char *off_on[] = { "FEM_OFF", "FEM_ON" };
@@ -134,49 +139,52 @@ CustomFrontendOptionsPopulate(void)
if (fd) {
#ifdef GRAPHICS_MENU_OPTIONS
FrontendOptionSetCursor(MENUPAGE_GRAPHICS_SETTINGS, -3, false);
- FrontendOptionAddSelect("FED_VPL", vehPipelineNames, ARRAY_SIZE(vehPipelineNames), (int8*)&CustomPipes::VehiclePipeSwitch, false, nil, "Graphics", "VehiclePipeline");
- FrontendOptionAddSelect("FED_PRM", off_on, 2, (int8*)&CustomPipes::RimlightEnable, false, nil, "Graphics", "NeoRimLight");
- FrontendOptionAddSelect("FED_WLM", off_on, 2, (int8*)&CustomPipes::LightmapEnable, false, nil, "Graphics", "NeoLightMaps");
- FrontendOptionAddSelect("FED_RGL", off_on, 2, (int8*)&CustomPipes::GlossEnable, false, nil, "Graphics", "NeoRoadGloss");
+ FrontendOptionAddSelect("FED_VPL", 0, 0, MENUALIGN_LEFT, vehPipelineNames, ARRAY_SIZE(vehPipelineNames), (int8*)&CustomPipes::VehiclePipeSwitch, false, nil, "Graphics", "VehiclePipeline");
+ FrontendOptionAddSelect("FED_PRM", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::RimlightEnable, false, nil, "Graphics", "NeoRimLight");
+ FrontendOptionAddSelect("FED_WLM", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::LightmapEnable, false, nil, "Graphics", "NeoLightMaps");
+ FrontendOptionAddSelect("FED_RGL", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::GlossEnable, false, nil, "Graphics", "NeoRoadGloss");
#else
FrontendOptionSetCursor(MENUPAGE_DISPLAY_SETTINGS, -3, false);
- FrontendOptionAddSelect("FED_VPL", vehPipelineNames, ARRAY_SIZE(vehPipelineNames), (int8*)&CustomPipes::VehiclePipeSwitch, false, nil, "Graphics", "VehiclePipeline");
- FrontendOptionAddSelect("FED_PRM", off_on, 2, (int8*)&CustomPipes::RimlightEnable, false, nil, "Graphics", "NeoRimLight");
- FrontendOptionAddSelect("FED_WLM", off_on, 2, (int8*)&CustomPipes::LightmapEnable, false, nil, "Graphics", "NeoLightMaps");
- FrontendOptionAddSelect("FED_RGL", off_on, 2, (int8*)&CustomPipes::GlossEnable, false, nil, "Graphics", "NeoRoadGloss");
+ FrontendOptionAddSelect("FED_VPL", 0, 0, MENUALIGN_LEFT, vehPipelineNames, ARRAY_SIZE(vehPipelineNames), (int8*)&CustomPipes::VehiclePipeSwitch, false, nil, "Graphics", "VehiclePipeline");
+ FrontendOptionAddSelect("FED_PRM", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::RimlightEnable, false, nil, "Graphics", "NeoRimLight");
+ FrontendOptionAddSelect("FED_WLM", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::LightmapEnable, false, nil, "Graphics", "NeoLightMaps");
+ FrontendOptionAddSelect("FED_RGL", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::GlossEnable, false, nil, "Graphics", "NeoRoadGloss");
#endif
CFileMgr::CloseFile(fd);
}
#endif
-
// Add outsourced language translations, if files are found
#ifdef MORE_LANGUAGES
int fd2;
FrontendOptionSetCursor(MENUPAGE_LANGUAGE_SETTINGS, 5, false);
- if (fd = CFileMgr::OpenFile("text/polish.gxt","r")) {
- if (fd2 = CFileMgr::OpenFile("models/fonts_p.txd","r")) {
- FrontendOptionAddDynamic("FEL_POL", nil, nil, LangPolSelect, nil, nil);
+#if 0
+ if (fd = CFileMgr::OpenFile("text/polish.gxt")) {
+ if (fd2 = CFileMgr::OpenFile("models/fonts_p.txd")) {
+ FrontendOptionAddDynamic("FEL_POL", 0, 0, MENUALIGN_CENTER, nil, nil, LangPolSelect, nil, nil);
CFileMgr::CloseFile(fd2);
}
CFileMgr::CloseFile(fd);
}
+#endif
- if (fd = CFileMgr::OpenFile("text/russian.gxt","r")) {
- if (fd2 = CFileMgr::OpenFile("models/fonts_r.txd","r")) {
- FrontendOptionAddDynamic("FEL_RUS", nil, nil, LangRusSelect, nil, nil);
+ if (fd = CFileMgr::OpenFile("text/russian.gxt")) {
+ if (fd2 = CFileMgr::OpenFile("models/fonts_r.txd")) {
+ FrontendOptionAddDynamic("FEL_RUS", 0, 0, MENUALIGN_CENTER, nil, nil, LangRusSelect, nil, nil);
CFileMgr::CloseFile(fd2);
}
CFileMgr::CloseFile(fd);
}
- if (fd = CFileMgr::OpenFile("text/japanese.gxt","r")) {
- if (fd2 = CFileMgr::OpenFile("models/fonts_j.txd","r")) {
- FrontendOptionAddDynamic("FEL_JAP", nil, nil, LangJapSelect, nil, nil);
+#if 0
+ if (fd = CFileMgr::OpenFile("text/japanese.gxt")) {
+ if (fd2 = CFileMgr::OpenFile("models/fonts_j.txd")) {
+ FrontendOptionAddDynamic("FEL_JAP", 0, 0, MENUALIGN_CENTER, nil, nil, LangJapSelect, nil, nil);
CFileMgr::CloseFile(fd2);
}
CFileMgr::CloseFile(fd);
}
#endif
+#endif
}
#endif
@@ -185,7 +193,7 @@ CustomFrontendOptionsPopulate(void)
#define MINI_CASE_SENSITIVE
#include "ini.h"
-mINI::INIFile ini("re3.ini");
+mINI::INIFile ini("reVC.ini");
mINI::INIStructure cfg;
bool ReadIniIfExists(const char *cat, const char *key, uint32 *out)
@@ -306,14 +314,14 @@ void StoreIni(const char *cat, const char *key, char *val, int size)
}
const char *iniControllerActions[] = { "PED_FIREWEAPON", "PED_CYCLE_WEAPON_RIGHT", "PED_CYCLE_WEAPON_LEFT", "GO_FORWARD", "GO_BACK", "GO_LEFT", "GO_RIGHT", "PED_SNIPER_ZOOM_IN",
- "PED_SNIPER_ZOOM_OUT", "VEHICLE_ENTER_EXIT", "CAMERA_CHANGE_VIEW_ALL_SITUATIONS", "PED_JUMPING", "PED_SPRINT", "PED_LOOKBEHIND",
+ "PED_SNIPER_ZOOM_OUT", "VEHICLE_ENTER_EXIT", "CAMERA_CHANGE_VIEW_ALL_SITUATIONS", "PED_JUMPING", "PED_SPRINT", "PED_LOOKBEHIND", "PED_DUCK", "PED_ANSWER_PHONE",
#ifdef BIND_VEHICLE_FIREWEAPON
"VEHICLE_FIREWEAPON",
#endif
"VEHICLE_ACCELERATE", "VEHICLE_BRAKE", "VEHICLE_CHANGE_RADIO_STATION", "VEHICLE_HORN", "TOGGLE_SUBMISSIONS", "VEHICLE_HANDBRAKE", "PED_1RST_PERSON_LOOK_LEFT",
"PED_1RST_PERSON_LOOK_RIGHT", "VEHICLE_LOOKLEFT", "VEHICLE_LOOKRIGHT", "VEHICLE_LOOKBEHIND", "VEHICLE_TURRETLEFT", "VEHICLE_TURRETRIGHT", "VEHICLE_TURRETUP", "VEHICLE_TURRETDOWN",
"PED_CYCLE_TARGET_LEFT", "PED_CYCLE_TARGET_RIGHT", "PED_CENTER_CAMERA_BEHIND_PLAYER", "PED_LOCK_TARGET", "NETWORK_TALK", "PED_1RST_PERSON_LOOK_UP", "PED_1RST_PERSON_LOOK_DOWN",
- "_CONTROLLERACTION_36", "TOGGLE_DPAD", "SWITCH_DEBUG_CAM_ON", "TAKE_SCREEN_SHOT", "SHOW_MOUSE_POINTER_TOGGLE" };
+ "_CONTROLLERACTION_36", "TOGGLE_DPAD", "SWITCH_DEBUG_CAM_ON", "TAKE_SCREEN_SHOT", "SHOW_MOUSE_POINTER_TOGGLE", "UNKNOWN_ACTION" };
const char *iniControllerTypes[] = { "kbd:", "2ndKbd:", "mouse:", "joy:" };
@@ -413,7 +421,7 @@ void LoadINIControllerSettings()
}
}
}
-
+
ControlsManager.SetControllerKeyAssociatedWithAction((e_ControllerAction)i, contKey, (eControllerType)contType);
}
}
@@ -424,7 +432,7 @@ void SaveINIControllerSettings()
{
for (int32 i = 0; i < MAX_CONTROLLERACTIONS; i++) {
char value[128] = { '\0' };
-
+
// upper limit should've been GetNumOfSettingsForAction(i), but sadly even R* doesn't use it's own system correctly, and there are gaps between orders.
for (int32 j = SETORDER_1; j < MAX_SETORDERS; j++){
@@ -485,13 +493,13 @@ bool LoadINISettings()
ReadIniIfExists("Graphics", "VideoMode", &FrontEndMenuManager.m_nDisplayVideoMode);
#endif
ReadIniIfExists("Controller", "HeadBob1stPerson", &TheCamera.m_bHeadBob);
- ReadIniIfExists("Controller", "VerticalMouseSens", &TheCamera.m_fMouseAccelVertical);
ReadIniIfExists("Controller", "HorizantalMouseSens", &TheCamera.m_fMouseAccelHorzntl);
ReadIniIfExists("Controller", "InvertMouseVertically", &MousePointerStateHelper.bInvertVertically);
ReadIniIfExists("Controller", "DisableMouseSteering", &CVehicle::m_bDisableMouseSteering);
ReadIniIfExists("Controller", "Vibration", &FrontEndMenuManager.m_PrefsUseVibration);
ReadIniIfExists("Audio", "SfxVolume", &FrontEndMenuManager.m_PrefsSfxVolume);
ReadIniIfExists("Audio", "MusicVolume", &FrontEndMenuManager.m_PrefsMusicVolume);
+ ReadIniIfExists("Audio", "MP3BoostVolume", &FrontEndMenuManager.m_PrefsMP3BoostVolume);
ReadIniIfExists("Audio", "Radio", &FrontEndMenuManager.m_PrefsRadioStation);
#ifdef EXTERNAL_3D_SOUND
ReadIniIfExists("Audio", "SpeakerType", &FrontEndMenuManager.m_PrefsSpeakers);
@@ -502,12 +510,17 @@ bool LoadINISettings()
ReadIniIfExists("Display", "DrawDistance", &FrontEndMenuManager.m_PrefsLOD);
ReadIniIfExists("Display", "Subtitles", &FrontEndMenuManager.m_PrefsShowSubtitles);
ReadIniIfExists("Graphics", "AspectRatio", &FrontEndMenuManager.m_PrefsUseWideScreen);
- ReadIniIfExists("Graphics", "VSync", &FrontEndMenuManager.m_PrefsVsyncDisp);
ReadIniIfExists("Graphics", "FrameLimiter", &FrontEndMenuManager.m_PrefsFrameLimiter);
+#ifdef LEGACY_MENU_OPTIONS
+ ReadIniIfExists("Graphics", "VSync", &FrontEndMenuManager.m_PrefsVsyncDisp);
ReadIniIfExists("Graphics", "Trails", &CMBlur::BlurOn);
+#endif
ReadIniIfExists("General", "SkinFile", FrontEndMenuManager.m_PrefsSkinFile, 256);
ReadIniIfExists("Controller", "Method", &FrontEndMenuManager.m_ControlMethod);
ReadIniIfExists("General", "Language", &FrontEndMenuManager.m_PrefsLanguage);
+ ReadIniIfExists("Display", "ShowHud", &FrontEndMenuManager.m_PrefsShowHud);
+ ReadIniIfExists("Display", "RadarMode", &FrontEndMenuManager.m_PrefsRadarMode);
+ ReadIniIfExists("Display", "ShowLegends", &FrontEndMenuManager.m_PrefsShowLegends);
#ifdef EXTENDED_COLOURFILTER
ReadIniIfExists("CustomPipesValues", "PostFXIntensity", &CPostFX::Intensity);
@@ -519,6 +532,7 @@ bool LoadINISettings()
ReadIniIfExists("CustomPipesValues", "LightmapMult", &CustomPipes::LightmapMult);
ReadIniIfExists("CustomPipesValues", "GlossMult", &CustomPipes::GlossMult);
#endif
+ ReadIniIfExists("Rendering", "BackfaceCulling", &gBackfaceCulling);
#ifdef NEW_RENDERER
ReadIniIfExists("Rendering", "NewRenderer", &gbNewRenderer);
#endif
@@ -569,6 +583,7 @@ bool LoadINISettings()
// Fetched in above block, but needs evaluation
#ifdef PED_CAR_DENSITY_SLIDERS
CPopulation::MaxNumberOfPedsInUse = DEFAULT_MAX_NUMBER_OF_PEDS * CIniFile::PedNumberMultiplier;
+ CPopulation::MaxNumberOfPedsInUseInterior = DEFAULT_MAX_NUMBER_OF_PEDS_INTERIOR * CIniFile::PedNumberMultiplier;
CCarCtrl::MaxNumberOfCarsInUse = DEFAULT_MAX_NUMBER_OF_CARS * CIniFile::CarNumberMultiplier;
#endif
@@ -587,13 +602,13 @@ void SaveINISettings()
StoreIni("Graphics", "VideoMode", FrontEndMenuManager.m_nDisplayVideoMode);
#endif
StoreIni("Controller", "HeadBob1stPerson", TheCamera.m_bHeadBob);
- StoreIni("Controller", "VerticalMouseSens", TheCamera.m_fMouseAccelVertical);
StoreIni("Controller", "HorizantalMouseSens", TheCamera.m_fMouseAccelHorzntl);
StoreIni("Controller", "InvertMouseVertically", MousePointerStateHelper.bInvertVertically);
StoreIni("Controller", "DisableMouseSteering", CVehicle::m_bDisableMouseSteering);
StoreIni("Controller", "Vibration", FrontEndMenuManager.m_PrefsUseVibration);
StoreIni("Audio", "SfxVolume", FrontEndMenuManager.m_PrefsSfxVolume);
StoreIni("Audio", "MusicVolume", FrontEndMenuManager.m_PrefsMusicVolume);
+ StoreIni("Audio", "MP3BoostVolume", FrontEndMenuManager.m_PrefsMP3BoostVolume);
StoreIni("Audio", "Radio", FrontEndMenuManager.m_PrefsRadioStation);
#ifdef EXTERNAL_3D_SOUND
StoreIni("Audio", "SpeakerType", FrontEndMenuManager.m_PrefsSpeakers);
@@ -604,12 +619,17 @@ void SaveINISettings()
StoreIni("Display", "DrawDistance", FrontEndMenuManager.m_PrefsLOD);
StoreIni("Display", "Subtitles", FrontEndMenuManager.m_PrefsShowSubtitles);
StoreIni("Graphics", "AspectRatio", FrontEndMenuManager.m_PrefsUseWideScreen);
+#ifdef LEGACY_MENU_OPTIONS
StoreIni("Graphics", "VSync", FrontEndMenuManager.m_PrefsVsyncDisp);
- StoreIni("Graphics", "FrameLimiter", FrontEndMenuManager.m_PrefsFrameLimiter);
StoreIni("Graphics", "Trails", CMBlur::BlurOn);
+#endif
+ StoreIni("Graphics", "FrameLimiter", FrontEndMenuManager.m_PrefsFrameLimiter);
StoreIni("General", "SkinFile", FrontEndMenuManager.m_PrefsSkinFile, 256);
StoreIni("Controller", "Method", FrontEndMenuManager.m_ControlMethod);
StoreIni("General", "Language", FrontEndMenuManager.m_PrefsLanguage);
+ StoreIni("Display", "ShowHud", FrontEndMenuManager.m_PrefsShowHud);
+ StoreIni("Display", "RadarMode", FrontEndMenuManager.m_PrefsRadarMode);
+ StoreIni("Display", "ShowLegends", FrontEndMenuManager.m_PrefsShowLegends);
#ifdef EXTENDED_COLOURFILTER
StoreIni("CustomPipesValues", "PostFXIntensity", CPostFX::Intensity);
@@ -621,6 +641,7 @@ void SaveINISettings()
StoreIni("CustomPipesValues", "LightmapMult", CustomPipes::LightmapMult);
StoreIni("CustomPipesValues", "GlossMult", CustomPipes::GlossMult);
#endif
+ StoreIni("Rendering", "BackfaceCulling", gBackfaceCulling);
#ifdef NEW_RENDERER
StoreIni("Rendering", "NewRenderer", gbNewRenderer);
#endif
@@ -662,11 +683,12 @@ void SaveINISettings()
#endif
-
#ifdef DEBUGMENU
-void WeaponCheat();
+void WeaponCheat1();
+void WeaponCheat2();
+void WeaponCheat3();
void HealthCheat();
-void TankCheat();
+void VehicleCheat(int model);
void BlowUpCarsCheat();
void ChangePlayerCheat();
void MayhemCheat();
@@ -686,7 +708,8 @@ void FastWeatherCheat();
void OnlyRenderWheelsCheat();
void ChittyChittyBangBangCheat();
void StrongGripCheat();
-void NastyLimbsCheat();
+void SpecialCarCheats();
+void PickUpChicksCheat();
DebugMenuEntry *carCol1;
DebugMenuEntry *carCol2;
@@ -709,6 +732,8 @@ SpawnCar(int id)
CVehicle *v;
if(CModelInfo::IsBoatModel(id))
v = new CBoat(id, RANDOM_VEHICLE);
+ else if(CModelInfo::IsBikeModel(id))
+ v = new CBike(id, RANDOM_VEHICLE);
else
v = new CAutomobile(id, RANDOM_VEHICLE);
@@ -738,13 +763,15 @@ FixCar(void)
if(veh == nil)
return;
veh->m_fHealth = 1000.0f;
- if(!veh->IsCar())
- return;
- ((CAutomobile*)veh)->Damage.SetEngineStatus(0);
- ((CAutomobile*)veh)->Fix();
+ if(veh->IsCar()){
+ ((CAutomobile*)veh)->Damage.SetEngineStatus(0);
+ ((CAutomobile*)veh)->Fix();
+ }else if(veh->IsBike()){
+ ((CBike*)veh)->Fix();
+ }
}
-#ifdef MENU_MAP
+#ifdef MAP_ENHANCEMENTS
static void
TeleportToWaypoint(void)
{
@@ -799,20 +826,20 @@ SwitchToMission(void)
}
#endif
-#ifdef USE_CUSTOM_ALLOCATOR
-static void ParseHeap(void) { gMainHeap.ParseHeap(); }
-#endif
-
static const char *carnames[] = {
- "landstal", "idaho", "stinger", "linerun", "peren", "sentinel", "patriot", "firetruk", "trash", "stretch", "manana", "infernus", "blista", "pony",
- "mule", "cheetah", "ambulan", "fbicar", "moonbeam", "esperant", "taxi", "kuruma", "bobcat", "mrwhoop", "bfinject", "corpse", "police", "enforcer",
- "securica", "banshee", "predator", "bus", "rhino", "barracks", "train", "chopper", "dodo", "coach", "cabbie", "stallion", "rumpo", "rcbandit",
- "bellyup", "mrwongs", "mafia", "yardie", "yakuza", "diablos", "columb", "hoods", "airtrain", "deaddodo", "speeder", "reefer", "panlant", "flatbed",
- "yankee", "escape", "borgnine", "toyz", "ghost",
+ "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"
};
-//#include <list>
-
static CTweakVar** TweakVarsList;
static int TweakVarsListSize = -1;
static bool bAddTweakVarsNow = false;
@@ -870,11 +897,37 @@ TWEAKSWITCH(CWeather::NewWeatherType, 0, 3, wt, NULL);
*/
void
+switchWeather(void)
+{
+ CWeather::StreamAfterRainTimer = 0;
+}
+
+void
DebugMenuPopulate(void)
{
if(1){
static const char *weathers[] = {
- "Sunny", "Cloudy", "Rainy", "Foggy"
+ "Sunny", "Cloudy", "Rainy", "Foggy", "Extrasunny", "Stormy"
+ };
+ static const char *extracols[] = {
+ "1 - Malibu club",
+ "2 - Strib club",
+ "3 - Hotel",
+ "4 - Bank",
+ "5 - Police HQ",
+ "6 - Mall",
+ "7 - Rifle Range",
+ "8 - Mansion",
+ "9 - Dirt ring",
+ "10 - Blood ring",
+ "11 - Hot ring",
+ "12 - Concert hall",
+ "13 - Auntie Poulets",
+ "14 - Intro at docks",
+ "15 - Biker bar",
+ "16 - Intro cafe",
+ "17 - Studio",
+ "18", "19", "20", "21", "22", "23", "24"
};
DebugMenuEntry *e;
e = DebugMenuAddVar("Time & Weather", "Current Hour", &CClock::GetHoursRef(), nil, 1, 0, 23, nil);
@@ -882,19 +935,22 @@ 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, switchWeather, 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, switchWeather, 1, 0, 5, weathers);
DebugMenuEntrySetWrap(e, true);
- DebugMenuAddVar("Time & Weather", "Wind", (float*)&CWeather::Wind, nil, 0.1f, 0.0f, 1.0f);
+ DebugMenuAddVarBool32("Time & Weather", "Extracolours On", &CTimeCycle::m_bExtraColourOn, nil);
+ DebugMenuAddVar("Time & Weather", "Extracolour", &CTimeCycle::m_ExtraColour, nil, 1, 0, 23, extracols);
DebugMenuAddVar("Time & Weather", "Time scale", (float*)&CTimer::GetTimeScale(), nil, 0.1f, 0.0f, 10.0f);
- DebugMenuAddCmd("Cheats", "Weapons", WeaponCheat);
+ DebugMenuAddCmd("Cheats", "Weapon set 1", WeaponCheat1);
+ DebugMenuAddCmd("Cheats", "Weapon set 2", WeaponCheat2);
+ DebugMenuAddCmd("Cheats", "Weapon set 3", WeaponCheat3);
DebugMenuAddCmd("Cheats", "Money", MoneyCheat);
DebugMenuAddCmd("Cheats", "Health", HealthCheat);
DebugMenuAddCmd("Cheats", "Wanted level up", WantedLevelUpCheat);
DebugMenuAddCmd("Cheats", "Wanted level down", WantedLevelDownCheat);
- DebugMenuAddCmd("Cheats", "Tank", TankCheat);
+ DebugMenuAddCmd("Cheats", "Tank", []() { VehicleCheat(MI_TAXI); });
DebugMenuAddCmd("Cheats", "Blow up cars", BlowUpCarsCheat);
DebugMenuAddCmd("Cheats", "Change player", ChangePlayerCheat);
DebugMenuAddCmd("Cheats", "Mayhem", MayhemCheat);
@@ -911,17 +967,16 @@ DebugMenuPopulate(void)
DebugMenuAddCmd("Cheats", "Only render wheels", OnlyRenderWheelsCheat);
DebugMenuAddCmd("Cheats", "Chitty chitty bang bang", ChittyChittyBangBangCheat);
DebugMenuAddCmd("Cheats", "Strong grip", StrongGripCheat);
- DebugMenuAddCmd("Cheats", "Nasty limbs", NastyLimbsCheat);
+ DebugMenuAddCmd("Cheats", "Special car", SpecialCarCheats);
+ DebugMenuAddCmd("Cheats", "Pickup chicks", PickUpChicksCheat);
static int spawnCarId = MI_LANDSTAL;
- e = DebugMenuAddVar("Spawn", "Spawn Car ID", &spawnCarId, nil, 1, MI_LANDSTAL, MI_GHOST, carnames);
+ e = DebugMenuAddVar("Spawn", "Spawn Car ID", &spawnCarId, nil, 1, MI_LANDSTAL, MI_VICECHEE, carnames);
DebugMenuEntrySetWrap(e, true);
DebugMenuAddCmd("Spawn", "Spawn Car", [](){
- if(spawnCarId == MI_TRAIN ||
- spawnCarId == MI_CHOPPER ||
+ if(spawnCarId == MI_CHOPPER ||
spawnCarId == MI_AIRTRAIN ||
- spawnCarId == MI_DEADDODO ||
- spawnCarId == MI_ESCAPE)
+ spawnCarId == MI_DEADDODO)
return;
SpawnCar(spawnCarId);
});
@@ -931,22 +986,33 @@ DebugMenuPopulate(void)
DebugMenuAddCmd("Spawn", "Spawn Stinger", [](){ SpawnCar(MI_STINGER); });
DebugMenuAddCmd("Spawn", "Spawn Infernus", [](){ SpawnCar(MI_INFERNUS); });
DebugMenuAddCmd("Spawn", "Spawn Cheetah", [](){ SpawnCar(MI_CHEETAH); });
+ DebugMenuAddCmd("Spawn", "Spawn Phoenix", [](){ SpawnCar(MI_PHEONIX); });
+ DebugMenuAddCmd("Spawn", "Spawn Banshee", [](){ SpawnCar(MI_BANSHEE); });
DebugMenuAddCmd("Spawn", "Spawn Esperanto", [](){ SpawnCar(MI_ESPERANT); });
DebugMenuAddCmd("Spawn", "Spawn Stallion", [](){ SpawnCar(MI_STALLION); });
- DebugMenuAddCmd("Spawn", "Spawn Kuruma", [](){ SpawnCar(MI_KURUMA); });
+ DebugMenuAddCmd("Spawn", "Spawn Admiral", [](){ SpawnCar(MI_ADMIRAL); });
+ DebugMenuAddCmd("Spawn", "Spawn Washington", [](){ SpawnCar(MI_WASHING); });
DebugMenuAddCmd("Spawn", "Spawn Taxi", [](){ SpawnCar(MI_TAXI); });
DebugMenuAddCmd("Spawn", "Spawn Police", [](){ SpawnCar(MI_POLICE); });
DebugMenuAddCmd("Spawn", "Spawn Enforcer", [](){ SpawnCar(MI_ENFORCER); });
- DebugMenuAddCmd("Spawn", "Spawn Banshee", [](){ SpawnCar(MI_BANSHEE); });
- DebugMenuAddCmd("Spawn", "Spawn Yakuza", [](){ SpawnCar(MI_YAKUZA); });
- DebugMenuAddCmd("Spawn", "Spawn Yardie", [](){ SpawnCar(MI_YARDIE); });
- DebugMenuAddCmd("Spawn", "Spawn Dodo", [](){ SpawnCar(MI_DODO); });
+ DebugMenuAddCmd("Spawn", "Spawn Cuban", [](){ SpawnCar(MI_CUBAN); });
+ DebugMenuAddCmd("Spawn", "Spawn Voodoo", [](){ SpawnCar(MI_VOODOO); });
+ DebugMenuAddCmd("Spawn", "Spawn BF injection", [](){ SpawnCar(MI_BFINJECT); });
+ 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); });
+ DebugMenuAddCmd("Spawn", "Spawn PCJ 600", [](){ SpawnCar(MI_PCJ600); });
+ DebugMenuAddCmd("Spawn", "Spawn Faggio", [](){ SpawnCar(MI_FAGGIO); });
+ DebugMenuAddCmd("Spawn", "Spawn Freeway", [](){ SpawnCar(MI_FREEWAY); });
+ DebugMenuAddCmd("Spawn", "Spawn Squalo", [](){ SpawnCar(MI_SQUALO); });
+ DebugMenuAddCmd("Spawn", "Spawn Skimmer", [](){ SpawnCar(MI_SKIMMER); });
DebugMenuAddVarBool8("Render", "Draw hud", &CHud::m_Wants_To_Draw_Hud, nil);
-
#ifdef PROPER_SCALING
DebugMenuAddVarBool8("Render", "Proper Scaling", &CDraw::ms_bProperScaling, nil);
#endif
@@ -956,6 +1022,7 @@ DebugMenuPopulate(void)
#ifdef FIX_SPRITES
DebugMenuAddVarBool8("Render", "Fix Sprites", &CDraw::ms_bFixSprites, nil);
#endif
+ DebugMenuAddVarBool8("Render", "Backface Culling", &gBackfaceCulling, nil);
DebugMenuAddVarBool8("Render", "PS2 Alpha test Emu", &gPS2alphaTest, nil);
DebugMenuAddVarBool8("Render", "Frame limiter", &FrontEndMenuManager.m_PrefsFrameLimiter, nil);
DebugMenuAddVarBool8("Render", "VSynch", &FrontEndMenuManager.m_PrefsVsync, nil);
@@ -964,7 +1031,7 @@ DebugMenuPopulate(void)
DebugMenuAddVarBool8("Render", "New Renderer", &gbNewRenderer, nil);
extern bool gbRenderRoads;
extern bool gbRenderEverythingBarRoads;
-//extern bool gbRenderFadingInUnderwaterEntities;
+extern bool gbRenderFadingInUnderwaterEntities;
extern bool gbRenderFadingInEntities;
extern bool gbRenderWater;
extern bool gbRenderBoats;
@@ -974,7 +1041,7 @@ extern bool gbRenderWorld1;
extern bool gbRenderWorld2;
DebugMenuAddVarBool8("Debug Render", "gbRenderRoads", &gbRenderRoads, nil);
DebugMenuAddVarBool8("Debug Render", "gbRenderEverythingBarRoads", &gbRenderEverythingBarRoads, nil);
-// DebugMenuAddVarBool8("Debug Render", "gbRenderFadingInUnderwaterEntities", &gbRenderFadingInUnderwaterEntities, nil);
+ DebugMenuAddVarBool8("Debug Render", "gbRenderFadingInUnderwaterEntities", &gbRenderFadingInUnderwaterEntities, nil);
DebugMenuAddVarBool8("Debug Render", "gbRenderFadingInEntities", &gbRenderFadingInEntities, nil);
DebugMenuAddVarBool8("Debug Render", "gbRenderWater", &gbRenderWater, nil);
DebugMenuAddVarBool8("Debug Render", "gbRenderBoats", &gbRenderBoats, nil);
@@ -989,8 +1056,13 @@ extern bool gbRenderWorld2;
e = DebugMenuAddVar("Render", "Colourfilter", &CPostFX::EffectSwitch, nil, 1, CPostFX::POSTFX_OFF, CPostFX::POSTFX_MOBILE, filternames);
DebugMenuEntrySetWrap(e, true);
DebugMenuAddVar("Render", "Intensity", &CPostFX::Intensity, nil, 0.05f, 0, 10.0f);
+ DebugMenuAddVarBool8("Render", "Blur", &CPostFX::BlurOn, nil);
DebugMenuAddVarBool8("Render", "Motion Blur", &CPostFX::MotionBlurOn, nil);
#endif
+ DebugMenuAddVar("Render", "Drunkness", &CMBlur::Drunkness, nil, 0.05f, 0, 1.0f);
+#ifndef MASTER
+ DebugMenuAddVarBool8("Render", "Occlusion debug", &bDispayOccDebugStuff, nil);
+#endif
#ifdef LIBRW
DebugMenuAddVarBool32("Render", "MatFX env map apply light", &rw::MatFX::envMapApplyLight, nil);
DebugMenuAddVarBool32("Render", "MatFX env map flip U", &rw::MatFX::envMapFlipU, nil);
@@ -1013,8 +1085,6 @@ extern bool gbRenderWorld2;
DebugMenuAddVarBool8("Debug Render", "Show Ped Paths", &gbShowPedPaths, nil);
DebugMenuAddVarBool8("Debug Render", "Show Car Paths", &gbShowCarPaths, nil);
DebugMenuAddVarBool8("Debug Render", "Show Car Path Links", &gbShowCarPathsLinks, nil);
- DebugMenuAddVarBool8("Debug Render", "Show Ped Road Groups", &gbShowPedRoadGroups, nil);
- DebugMenuAddVarBool8("Debug Render", "Show Car Road Groups", &gbShowCarRoadGroups, nil);
DebugMenuAddVarBool8("Debug Render", "Show Collision Lines", &gbShowCollisionLines, nil);
DebugMenuAddVarBool8("Debug Render", "Show Collision Polys", &gbShowCollisionPolys, nil);
DebugMenuAddVarBool8("Debug Render", "Don't render Buildings", &gbDontRenderBuildings, nil);
@@ -1023,7 +1093,7 @@ extern bool gbRenderWorld2;
DebugMenuAddVarBool8("Debug Render", "Don't render Vehicles", &gbDontRenderVehicles, nil);
DebugMenuAddVarBool8("Debug Render", "Don't render Objects", &gbDontRenderObjects, nil);
DebugMenuAddVarBool8("Debug Render", "Don't Render Water", &gbDontRenderWater, nil);
-
+
#ifdef DRAW_GAME_VERSION_TEXT
DebugMenuAddVarBool8("Debug", "Version Text", &gbDrawVersionText, nil);
@@ -1039,8 +1109,6 @@ extern bool gbRenderWorld2;
DebugMenuAddCmd("Debug", "Parse Heap", ParseHeap);
#endif
#endif
- DebugMenuAddVarBool8("Debug", "Show cullzone debug stuff", &gbShowCullZoneDebugStuff, nil);
- DebugMenuAddVarBool8("Debug", "Disable zone cull", &gbDisableZoneCull, nil);
DebugMenuAddVarBool8("Debug", "pad 1 -> pad 2", &CPad::m_bMapPadOneToPadTwo, nil);
#ifdef GTA_SCENE_EDIT
@@ -1049,7 +1117,12 @@ extern bool gbRenderWorld2;
//DebugMenuAddCmd("Debug", "Start Credits", CCredits::Start);
//DebugMenuAddCmd("Debug", "Stop Credits", CCredits::Stop);
-#ifdef MENU_MAP
+#ifdef RELOADABLES
+// maybe put it back if we have more to reload
+// DebugMenuAddCmd("Reload", "HUD.TXD", CHud::ReloadTXD);
+#endif
+
+#ifdef MAP_ENHANCEMENTS
DebugMenuAddCmd("Game", "Teleport to map waypoint", TeleportToWaypoint);
#endif
DebugMenuAddCmd("Game", "Fix Car", FixCar);
@@ -1057,32 +1130,34 @@ extern bool gbRenderWorld2;
DebugMenuAddCmd("Game", "Switch car collision", SwitchCarCollision);
DebugMenuAddCmd("Game", "Toggle Comedy Controls", ToggleComedy);
- DebugMenuAddVarBool8("Game", "Toggle popping heads on headshot", &CPed::bPopHeadsOnHeadshot, nil);
#ifdef MISSION_SWITCHER
DebugMenuEntry *missionEntry;
static const char* missions[] = {
- "Intro Movie", "Hospital Info Scene", "Police Station Info Scene",
- "RC Diablo Destruction", "RC Mafia Massacre", "RC Rumpo Rampage", "RC Casino Calamity",
- "Patriot Playground", "A Ride In The Park", "Gripped!", "Multistorey Mayhem",
- "Paramedic", "Firefighter", "Vigilante", "Taxi Driver",
- "The Crook", "The Thieves", "The Wife", "Her Lover",
- "Give Me Liberty and Luigi's Girls", "Don't Spank My Bitch Up", "Drive Misty For Me", "Pump-Action Pimp", "The Fuzz Ball",
- "Mike Lips Last Lunch", "Farewell 'Chunky' Lee Chong", "Van Heist", "Cipriani's Chauffeur", "Dead Skunk In The Trunk", "The Getaway",
- "Taking Out The Laundry", "The Pick-Up", "Salvatore's Called A Meeting", "Triads And Tribulations", "Blow Fish", "Chaperone", "Cutting The Grass",
- "Bomb Da Base: Act I", "Bomb Da Base: Act II", "Last Requests", "Turismo", "I Scream, You Scream", "Trial By Fire", "Big'N'Veiny", "Sayonara Salvatore",
- "Under Surveillance", "Paparazzi Purge", "Payday For Ray", "Two-Faced Tanner", "Kanbu Bust-Out", "Grand Theft Auto", "Deal Steal", "Shima", "Smack Down",
- "Silence The Sneak", "Arms Shortage", "Evidence Dash", "Gone Fishing", "Plaster Blaster", "Marked Man",
- "Liberator", "Waka-Gashira Wipeout!", "A Drop In The Ocean", "Bling-Bling Scramble", "Uzi Rider", "Gangcar Round-Up", "Kingdom Come",
- "Grand Theft Aero", "Escort Service", "Decoy", "Love's Disappearance", "Bait", "Espresso-2-Go!", "S.A.M.",
- "Uzi Money", "Toyminator", "Rigged To Blow", "Bullion Run", "Rumble", "The Exchange"
+ "Initial", "Intro", "An Old Friend", "The Party", "Back Alley Brawl", "Jury Fury", "Riot",
+ "Treacherous Swine", "Mall Shootout", "Guardian Angels", "Sir, Yes Sir!", "All Hands On Deck!",
+ "The Chase", "Phnom Penh '86", "The Fastest Boat", "Supply & Demand", "Rub Out", "Death Row",
+ "Four Iron", "Demolition Man", "Two Bit Hit", "No Escape?", "The Shootist", "The Driver",
+ "The Job", "Gun Runner", "Boomshine Saigon", "Recruitment Drive", "Dildo Dodo", "Martha's Mug Shot",
+ "G-spotlight", "Shakedown", "Bar Brawl", "Cop Land", "Spilling the Beans", "Hit the Courier",
+ "Printworks Buy", "Sunshine Autos", "Interglobal Films Buy", "Cherry Popper Icecreams Buy",
+ "Kaufman Cabs Buy", "Malibu Club Buy", "The Boatyard Buy", "Pole Position Club Buy", "El Swanko Casa Buy",
+ "Links View Apartment Buy", "Hyman Condo Buy", "Ocean Heighs Aprt. Buy", "1102 Washington Street Buy",
+ "Vice Point Buy", "Skumole Shack Buy", "Cap the Collector", "Keep your Friends Close...",
+ "Alloy Wheels of Steel", "Messing with the Man", "Hog Tied", "Stunt Boat Challenge", "Cannon Fodder",
+ "Naval Engagement", "Trojan Voodoo", "Juju Scramble", "Bombs Away!", "Dirty Lickin's", "Love Juice",
+ "Psycho Killer", "Publicity Tour", "Weapon Range", "Road Kill", "Waste the Wife", "Autocide",
+ "Check Out at the Check In", "Loose Ends", "V.I.P.", "Friendly Rivalry", "Cabmaggedon", "TAXI DRIVER",
+ "PARAMEDIC", "FIREFIGHTER", "VIGILANTE", "HOTRING", "BLOODRING", "DIRTRING", "Sunshine Autos Races",
+ "Distribution", "Downtown Chopper Checkpoint", "Ocean Beach Chopper Checkpoint", "Vice Point Chopper Checkpoint",
+ "Little Haiti Chopper Checkpoint", "Trial by Dirt", "Test Track", "PCJ Playground", "Cone Crazy",
+ "PIZZA BOY", "RC Raider Pickup", "RC Bandit Race", "RC Baron Race", "Checkpoint Charlie"
};
missionEntry = DebugMenuAddVar("Game", "Select mission", &nextMissionToSwitch, nil, 1, 0, ARRAY_SIZE(missions) - 1, missions);
DebugMenuEntrySetWrap(missionEntry, true);
DebugMenuAddCmd("Game", "Start selected mission ", SwitchToMission);
#endif
-
extern bool PrintDebugCode;
extern int16 DebugCamMode;
DebugMenuAddVarBool8("Cam", "Use mouse Cam", &CCamera::m_bUseMouse3rdPerson, nil);
@@ -1092,9 +1167,6 @@ extern bool gbRenderWorld2;
DebugMenuAddVarBool8("Cam", "Print Debug Code", &PrintDebugCode, nil);
DebugMenuAddVar("Cam", "Cam Mode", &DebugCamMode, nil, 1, 0, CCam::MODE_EDITOR, nil);
DebugMenuAddCmd("Cam", "Normal", []() { DebugCamMode = 0; });
- // DebugMenuAddCmd("Cam", "Follow Ped With Bind", []() { DebugCamMode = CCam::MODE_FOLLOW_PED_WITH_BIND; });
- // DebugMenuAddCmd("Cam", "Reaction", []() { DebugCamMode = CCam::MODE_REACTION; });
- // DebugMenuAddCmd("Cam", "Chris", []() { DebugCamMode = CCam::MODE_CHRIS; });
DebugMenuAddCmd("Cam", "Reset Statics", ResetCamStatics);
CTweakVars::AddDBG("Debug");
@@ -1137,7 +1209,7 @@ void re3_assert(const char *expr, const char *filename, unsigned int lineno, con
strcat_s(re3_buff, re3_buffsize, "(Press Retry to debug the application)");
- nCode = ::MessageBoxA(nil, re3_buff, "RE3 Assertion Failed!",
+ nCode = ::MessageBoxA(nil, re3_buff, "REVC Assertion Failed!",
MB_ABORTRETRYIGNORE|MB_ICONHAND|MB_SETFOREGROUND|MB_TASKMODAL);
if (nCode == IDABORT)
@@ -1158,7 +1230,7 @@ void re3_assert(const char *expr, const char *filename, unsigned int lineno, con
abort();
#else
// TODO
- printf("\nRE3 ASSERT FAILED\n\tFile: %s\n\tLine: %d\n\tFunction: %s\n\tExpression: %s\n",filename,lineno,func,expr);
+ printf("\nREVC ASSERT FAILED\n\tFile: %s\n\tLine: %d\n\tFunction: %s\n\tExpression: %s\n",filename,lineno,func,expr);
assert(false);
#endif
}
@@ -1212,14 +1284,14 @@ void re3_usererror(const char *format, ...)
vsprintf_s(re3_buff, re3_buffsize, format, va);
va_end(va);
- ::MessageBoxA(nil, re3_buff, "RE3 Error!",
+ ::MessageBoxA(nil, re3_buff, "REVC Error!",
MB_OK|MB_ICONHAND|MB_SETFOREGROUND|MB_TASKMODAL);
raise(SIGABRT);
_exit(3);
#else
vsprintf(re3_buff, format, va);
- printf("\nRE3 Error!\n\t%s\n",re3_buff);
+ printf("\nREVC Error!\n\t%s\n",re3_buff);
assert(false);
#endif
}
diff --git a/src/core/templates.h b/src/core/templates.h
index 545dac39..7bc85ee6 100644
--- a/src/core/templates.h
+++ b/src/core/templates.h
@@ -41,11 +41,11 @@ class CPool
int32 m_allocPtr;
public:
- CPool(int32 size){
+ CPool(int32 size, const char *name){
m_entries = (U*)new uint8[sizeof(U)*size];
m_flags = new uint8[size];
m_size = size;
- m_allocPtr = 0;
+ m_allocPtr = -1;
for(int i = 0; i < size; i++){
SetId(i, 0);
SetIsFree(i, true);
@@ -74,7 +74,6 @@ public:
else
m_flags[i] &= ~POOLFLAG_ISFREE;
}
-
~CPool() {
Flush();
}
@@ -142,21 +141,22 @@ public:
return m_flags[handle>>8] == (handle & 0xFF) ?
(T*)&m_entries[handle >> 8] : nil;
}
- int32 GetIndex(T *entry){
+ int32 GetIndex(T* entry) {
int i = GetJustIndex_NoFreeAssert(entry);
return m_flags[i] + (i<<8);
}
- int32 GetJustIndex(T *entry){
+ int32 GetJustIndex(T* entry) {
int index = GetJustIndex_NoFreeAssert(entry);
+ assert((U*)entry == (U*)&m_entries[index]); // cast is unsafe - check required
assert(!GetIsFree(index));
return index;
}
- int32 GetJustIndex_NoFreeAssert(T* entry){
+ int32 GetJustIndex_NoFreeAssert(T* entry) {
int index = ((U*)entry - m_entries);
- assert((U*)entry == (U*)&m_entries[index]); // cast is unsafe - check required
+ // Please don't add unsafe assert here, because at least one func. use this to check if entity is ped or vehicle.
return index;
}
- int32 GetNoOfUsedSpaces(void) const{
+ int32 GetNoOfUsedSpaces(void) const {
int i;
int n = 0;
for(i = 0; i < m_size; i++)
@@ -186,6 +186,7 @@ public:
memcpy(entries, m_entries, sizeof(U)*m_size);
debug("Stored:%d (/%d)\n", GetNoOfUsedSpaces(), m_size); /* Assumed inlining */
}
+ int32 GetNoOfFreeSpaces() const { return GetSize() - GetNoOfUsedSpaces(); }
};
template<typename T>
diff --git a/src/core/timebars.cpp b/src/core/timebars.cpp
index 94051b25..169fef8c 100644
--- a/src/core/timebars.cpp
+++ b/src/core/timebars.cpp
@@ -92,7 +92,7 @@ void tbDisplay()
CFont::SetWrapx(SCREEN_STRETCH_X(DEFAULT_SCREEN_WIDTH));
CFont::SetRightJustifyOff();
CFont::SetPropOn();
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
sprintf(temp, "FPS: %.2f", Diag_GetFPS());
AsciiToUnicode(temp, wtemp);
CFont::SetColor(CRGBA(255, 255, 255, 255));
diff --git a/src/entities/Dummy.cpp b/src/entities/Dummy.cpp
index d5fad3e4..d62d2434 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_NoFreeAssert(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 6c3f12ea..9b73eefc 100644
--- a/src/entities/Dummy.h
+++ b/src/entities/Dummy.h
@@ -16,5 +16,4 @@ public:
static void operator delete(void*, size_t) throw();
};
-VALIDATE_SIZE(CDummy, 0x68);
-
+bool IsDummyPointerValid(CDummy* pDummy);
diff --git a/src/entities/Entity.cpp b/src/entities/Entity.cpp
index c38f12c7..b2fcfbc7 100644
--- a/src/entities/Entity.cpp
+++ b/src/entities/Entity.cpp
@@ -1,5 +1,6 @@
#include "common.h"
+#include "VuVector.h"
#include "General.h"
#include "RwHelper.h"
#include "ModelIndices.h"
@@ -22,6 +23,9 @@
#include "MemoryHeap.h"
#include "Bones.h"
#include "Debug.h"
+#include "Ped.h"
+#include "Dummy.h"
+#include "WindModifiers.h"
#include "SaveBuf.h"
int gBuildings;
@@ -47,18 +51,17 @@ CEntity::CEntity(void)
bRenderScorched = false;
bHasBlip = false;
bIsBIGBuilding = false;
- bRenderDamaged = false;
+ bStreamBIGBuilding = false;
+ bRenderDamaged = false;
bBulletProof = false;
bFireProof = false;
bCollisionProof = false;
bMeleeProof = false;
bOnlyDamagedByPlayer = false;
bStreamingDontDelete = false;
- bZoneCulled = false;
- bZoneCulled2 = false;
-
bRemoveFromWorld = false;
+
bHasHitWall = false;
bImBeingRendered = false;
bTouchingWater = false;
@@ -66,13 +69,20 @@ CEntity::CEntity(void)
bDrawLast = false;
bNoBrightHeadLights = false;
bDoNotRender = false;
-
bDistanceFade = false;
- m_flagE2 = false;
+
+ m_flagE1 = false;
+ bDontCastShadowsOn = false;
+ bOffscreen = false;
+ bIsStaticWaitingForCollision = false;
+ bDontStream = false;
+ bUnderwater = false;
+ bHasPreRenderEffects = false;
m_scanCode = 0;
m_modelIndex = -1;
m_rwObject = nil;
+ m_area = AREA_MAIN_MAP;
m_randomSeed = CGeneral::GetRandomNumber();
m_pFirstReference = nil;
}
@@ -87,6 +97,7 @@ void
CEntity::SetModelIndex(uint32 id)
{
m_modelIndex = id;
+ bHasPreRenderEffects = HasPreRenderEffects();
CreateRwObject();
}
@@ -94,6 +105,7 @@ void
CEntity::SetModelIndexNoCreate(uint32 id)
{
m_modelIndex = id;
+ bHasPreRenderEffects = HasPreRenderEffects();
}
void
@@ -114,6 +126,7 @@ CEntity::CreateRwObject(void)
GetMatrix().AttachRW(RwFrameGetMatrix(RpAtomicGetFrame((RpAtomic *)m_rwObject)), false);
else if(RwObjectGetType(m_rwObject) == rpCLUMP)
GetMatrix().AttachRW(RwFrameGetMatrix(RpClumpGetFrame((RpClump *)m_rwObject)), false);
+
mi->AddRef();
}
}
@@ -127,6 +140,7 @@ CEntity::AttachToRwObject(RwObject *obj)
GetMatrix().Attach(RwFrameGetMatrix(RpAtomicGetFrame((RpAtomic *)m_rwObject)), false);
else if(RwObjectGetType(m_rwObject) == rpCLUMP)
GetMatrix().Attach(RwFrameGetMatrix(RpClumpGetFrame((RpClump *)m_rwObject)), false);
+
CModelInfo::GetModelInfo(m_modelIndex)->AddRef();
}
}
@@ -140,7 +154,6 @@ CEntity::DetachFromRwObject(void)
GetMatrix().Detach();
}
-#ifdef PED_SKIN
RpAtomic*
AtomicRemoveAnimFromSkinCB(RpAtomic *atomic, void *data)
{
@@ -152,15 +165,14 @@ AtomicRemoveAnimFromSkinCB(RpAtomic *atomic, void *data)
hier->interpolator->currentAnim = nil;
}
#else
- if(hier && hier->pCurrentAnim){
- RpHAnimAnimationDestroy(hier->pCurrentAnim);
- hier->pCurrentAnim = nil;
+ if(hier && hier->currentAnim){
+ RpHAnimAnimationDestroy(hier->currentAnim->pCurrentAnim);
+ hier->currentAnim = nil;
}
#endif
}
return atomic;
}
-#endif
void
CEntity::DeleteRwObject(void)
@@ -174,10 +186,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;
@@ -241,13 +251,12 @@ CEntity::UpdateRwFrame(void)
RwFrameUpdateObjects((RwFrame*)rwObjectGetParent(m_rwObject));
}
-#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];
@@ -276,22 +285,42 @@ CEntity::UpdateRpHAnim(void)
void RenderSkeleton(RpHAnimHierarchy *hier);
RenderSkeleton(hier);
#endif
+ }
+}
+
+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());
}
-#endif
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:
@@ -311,22 +340,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;
@@ -334,7 +347,7 @@ CEntity::PreRender(void)
gpShadowExplosionTex, &pos,
8.0f, 0.0f, 0.0f, -8.0f,
255, 200.0f*flicker, 160.0f*flicker, 120.0f*flicker,
- 20.0f, false, 1.0f);
+ 20.0f, false, 1.0f, nil, false);
CPointLights::AddLight(CPointLights::LIGHT_POINT,
pos, CVector(0.0f, 0.0f, 0.0f),
8.0f,
@@ -349,12 +362,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, nil, false);
}
// 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)
@@ -363,14 +408,8 @@ 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
@@ -386,7 +425,6 @@ CEntity::Render(void)
}
}
-
bool
CEntity::GetIsTouching(CVUVECTOR const &center, float radius)
{
@@ -594,14 +632,12 @@ CEntity::SetupBigBuilding(void)
bStreamingDontDelete = true;
bUsesCollision = false;
m_level = CTheZones::GetLevelFromPosition(&GetPosition());
- if(m_level == LEVEL_GENERIC){
- if(mi->GetTxdSlot() != CTxdStore::FindTxdSlot("generic")){
- mi->SetTexDictionary("generic");
- printf("%d:%s txd has been set to generic\n", m_modelIndex, mi->GetModelName());
- }
- }
- if(mi->m_lodDistances[0] > 2000.0f)
+ if(mi->m_lodDistances[0] <= 2000.0f)
+ bStreamBIGBuilding = true;
+ if(mi->m_lodDistances[0] > 2500.0f || mi->m_ignoreDrawDist)
m_level = LEVEL_GENERIC;
+ else if(m_level == LEVEL_GENERIC)
+ printf("%s isn't in a level\n", mi->GetModelName());
}
float WindTabel[] = {
@@ -622,27 +658,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();
}
@@ -654,6 +694,7 @@ float BannerWindTabel[] = {
0.28f, 0.28f, 0.22f, 0.1f, 0.0f, -0.1f, -0.17f, -0.12f
};
+// unused
void
CEntity::ModifyMatrixForBannerInWind(void)
{
@@ -693,10 +734,61 @@ CEntity::ModifyMatrixForBannerInWind(void)
void
CEntity::PreRenderForGlassWindow(void)
{
+ if(((CSimpleModelInfo*)CModelInfo::GetModelInfo(m_modelIndex))->m_isArtistGlass)
+ return;
CGlass::AskForObjectToBeRenderedInGlass(this);
bIsVisible = false;
}
+RpMaterial*
+SetAtomicAlphaCB(RpMaterial *material, void *data)
+{
+ ((RwRGBA*)RpMaterialGetColor(material))->alpha = (uint8)(uintptr)data;
+ return material;
+}
+
+RpAtomic*
+SetClumpAlphaCB(RpAtomic *atomic, void *data)
+{
+ RpGeometry *geometry = RpAtomicGetGeometry(atomic);
+ RpGeometrySetFlags(geometry, RpGeometryGetFlags(geometry) | rpGEOMETRYMODULATEMATERIALCOLOR);
+ RpGeometryForAllMaterials(geometry, SetAtomicAlphaCB, (void*)data);
+ return atomic;
+}
+
+void
+CEntity::SetRwObjectAlpha(int32 alpha)
+{
+ if (m_rwObject != nil) {
+ switch (RwObjectGetType(m_rwObject)) {
+ case rpATOMIC: {
+ RpGeometry *geometry = RpAtomicGetGeometry((RpAtomic*)m_rwObject);
+ RpGeometrySetFlags(geometry, RpGeometryGetFlags(geometry) | rpGEOMETRYMODULATEMATERIALCOLOR);
+ RpGeometryForAllMaterials(geometry, SetAtomicAlphaCB, (void*)alpha);
+ break;
+ }
+ case rpCLUMP:
+ RpClumpForAllAtomics((RpClump*)m_rwObject, SetClumpAlphaCB, (void*)alpha);
+ break;
+ }
+ }
+}
+
+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;
+}
+
#ifdef COMPATIBLE_SAVES
void
CEntity::SaveEntityFlags(uint8*& buf)
@@ -721,32 +813,37 @@ 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 (bZoneCulled) tmp |= BIT(30);
- if (bZoneCulled2) tmp |= BIT(31);
+ 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 (bRemoveFromWorld) tmp |= BIT(0);
- if (bHasHitWall) tmp |= BIT(1);
- 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 (m_flagE2) tmp |= BIT(9);
+ 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 (bDontCastShadowsOn) tmp |= BIT(9);
+ if (bOffscreen) tmp |= BIT(10);
+ if (bIsStaticWaitingForCollision) tmp |= BIT(11);
+ if (bDontStream) tmp |= BIT(12);
+ if (bUnderwater) tmp |= BIT(13);
+ if (bHasPreRenderEffects) tmp |= BIT(14);
WriteSaveBuf(buf, tmp);
}
@@ -775,30 +872,35 @@ 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));
- bZoneCulled = !!(tmp & BIT(30));
- bZoneCulled2 = !!(tmp & BIT(31));
+ 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));
ReadSaveBuf(&tmp, buf);
- bRemoveFromWorld = !!(tmp & BIT(0));
- bHasHitWall = !!(tmp & BIT(1));
- 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));
- m_flagE2 = !!(tmp & BIT(9));
+ 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));
+ bDontCastShadowsOn = !!(tmp & BIT(9));
+ bOffscreen = !!(tmp & BIT(10));
+ bIsStaticWaitingForCollision = !!(tmp & BIT(11));
+ bDontStream = !!(tmp & BIT(12));
+ bUnderwater = !!(tmp & BIT(13));
+ bHasPreRenderEffects = !!(tmp & BIT(14));
}
#endif
diff --git a/src/entities/Entity.h b/src/entities/Entity.h
index 6174b61d..957ee3bf 100644
--- a/src/entities/Entity.h
+++ b/src/entities/Entity.h
@@ -30,6 +30,7 @@ enum eEntityStatus
STATUS_PLANE,
STATUS_PLAYER_REMOTE,
STATUS_PLAYER_DISABLED,
+ STATUS_GHOST
};
class CEntity : public CPlaceable
@@ -59,36 +60,42 @@ public:
uint32 bRenderScorched : 1;
uint32 bHasBlip : 1;
uint32 bIsBIGBuilding : 1; // Set if this entity is a big building
- uint32 bRenderDamaged : 1; // use damaged LOD models for objects with applicable damage
+ uint32 bStreamBIGBuilding : 1; // set when draw dist <= 2000
// flagsC
+ uint32 bRenderDamaged : 1; // use damaged LOD models for objects with applicable damage
uint32 bBulletProof : 1;
uint32 bFireProof : 1;
uint32 bCollisionProof : 1;
uint32 bMeleeProof : 1;
uint32 bOnlyDamagedByPlayer : 1;
uint32 bStreamingDontDelete : 1; // Dont let the streaming remove this
- uint32 bZoneCulled : 1;
- uint32 bZoneCulled2 : 1; // only treadables+10m
+ uint32 bRemoveFromWorld : 1; // remove this entity next time it should be processed
// flagsD
- uint32 bRemoveFromWorld : 1; // remove this entity next time it should be processed
uint32 bHasHitWall : 1; // has collided with a building (changes subsequent collisions)
uint32 bImBeingRendered : 1; // don't delete me because I'm being rendered
uint32 bTouchingWater : 1; // used by cBuoyancy::ProcessBuoyancy
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
- uint32 bDistanceFade : 1; // Fade entity because it is far away
- uint32 m_flagE2 : 1;
+ uint32 m_flagE1 : 1;
+ uint32 bDontCastShadowsOn : 1; // Dont cast shadows on this object
+ uint32 bOffscreen : 1; // offscreen flag. This can only be trusted when it is set to true
+ uint32 bIsStaticWaitingForCollision : 1; // this is used by script created entities - they are static until the collision is loaded below them
+ uint32 bDontStream : 1; // tell the streaming not to stream me
+ uint32 bUnderwater : 1; // this object is underwater change drawing order
+ uint32 bHasPreRenderEffects : 1; // Object has a prerender effects attached to it
uint16 m_scanCode;
uint16 m_randomSeed;
int16 m_modelIndex;
- uint16 m_level; // int16
+ int8 m_level;
+ int8 m_area;
CReference *m_pFirstReference;
public:
@@ -97,7 +104,7 @@ public:
uint8 GetStatus() const { return m_status; }
void SetStatus(uint8 status) { m_status = status; }
CColModel *GetColModel(void) { return CModelInfo::GetModelInfo(m_modelIndex)->GetColModel(); }
- bool GetIsStatic(void) const { return bIsStatic; }
+ bool GetIsStatic(void) const { return bIsStatic || bIsStaticWaitingForCollision; }
void SetIsStatic(bool state) { bIsStatic = state; }
#ifdef COMPATIBLE_SAVES
void SaveEntityFlags(uint8*& buf);
@@ -107,7 +114,7 @@ public:
#endif
CEntity(void);
- ~CEntity(void);
+ virtual ~CEntity(void);
virtual void Add(void);
virtual void Remove(void);
@@ -150,9 +157,11 @@ public:
bool GetIsOnScreenComplex(void);
bool IsVisible(void);
bool IsVisibleComplex(void);
+ bool IsEntityOccluded(void);
int16 GetModelIndex(void) const { return m_modelIndex; }
void UpdateRwFrame(void);
void SetupBigBuilding(void);
+ bool HasPreRenderEffects(void);
void AttachToRwObject(RwObject *obj);
void DetachFromRwObject(void);
@@ -160,16 +169,16 @@ public:
void RegisterReference(CEntity **pent);
void ResolveReferences(void);
void PruneReferences(void);
+ void CleanUpOldReference(CEntity **pent);
-#ifdef PED_SKIN
void UpdateRpHAnim(void);
-#endif
void PreRenderForGlassWindow(void);
void AddSteamsFromGround(CVector *unused);
void ModifyMatrixForTreeInWind(void);
void ModifyMatrixForBannerInWind(void);
void ProcessLightsForEntity(void);
+ void SetRwObjectAlpha(int32 alpha);
};
-VALIDATE_SIZE(CEntity, 0x64);
+bool IsEntityPointerValid(CEntity*);
diff --git a/src/entities/Physical.cpp b/src/entities/Physical.cpp
index 32a3df3b..fb796fcd 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,14 @@
#include "CarCtrl.h"
#include "DMAudio.h"
#include "Automobile.h"
-#include "Physical.h"
#include "Bike.h"
+#include "Pickups.h"
+#include "Physical.h"
+
+#ifdef WALLCLIMB_CHEAT
+bool gGravityCheat;
+#endif
+
CPhysical::CPhysical(void)
{
@@ -42,6 +50,7 @@ CPhysical::CPhysical(void)
m_aCollisionRecords[i] = nil;
m_bIsVehicleBeingShifted = false;
+ bJustCheckCollision = false;
m_nDamagePieceType = 0;
m_fDamageImpulse = 0.0f;
@@ -57,21 +66,22 @@ CPhysical::CPhysical(void)
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;
#ifdef FIX_BUGS
m_nSurfaceTouched = SURFACE_DEFAULT;
#endif
m_nZoneLevel = LEVEL_GENERIC;
+
+ bIsFrozen = false;
+ bDontLoadCollision = false;
}
CPhysical::~CPhysical(void)
@@ -226,7 +236,8 @@ CPhysical::GetBoundRect(void)
void
CPhysical::AddToMovingList(void)
{
- m_movingListNode = CWorld::GetMovingEntityList().InsertItem(this);
+ if (!bIsStaticWaitingForCollision)
+ m_movingListNode = CWorld::GetMovingEntityList().InsertItem(this);
}
void
@@ -254,6 +265,7 @@ CPhysical::AddCollisionRecord(CEntity *ent)
AddCollisionRecord_Treadable(ent);
this->bHasCollided = true;
ent->bHasCollided = true;
+ this->m_nLastTimeCollided = CTimer::GetTimeInMilliseconds();
if(IsVehicle() && ent->IsVehicle()){
if(((CVehicle*)this)->m_nAlarmState == -1)
((CVehicle*)this)->m_nAlarmState = 15000;
@@ -267,7 +279,6 @@ CPhysical::AddCollisionRecord(CEntity *ent)
return;
if(m_nCollisionRecords < PHYSICAL_MAX_COLLISIONRECORDS)
m_aCollisionRecords[m_nCollisionRecords++] = ent;
- m_nLastTimeCollided = CTimer::GetTimeInMilliseconds();
}
}
@@ -275,17 +286,6 @@ void
CPhysical::AddCollisionRecord_Treadable(CEntity *ent)
{
if(ent->IsBuilding() && ((CBuilding*)ent)->GetIsATreadable()){
- CTreadable *t = (CTreadable*)ent;
- if(t->m_nodeIndices[PATH_PED][0] >= 0 ||
- t->m_nodeIndices[PATH_PED][1] >= 0 ||
- t->m_nodeIndices[PATH_PED][2] >= 0 ||
- t->m_nodeIndices[PATH_PED][3] >= 0)
- m_treadable[PATH_PED] = t;
- if(t->m_nodeIndices[PATH_CAR][0] >= 0 ||
- t->m_nodeIndices[PATH_CAR][1] >= 0 ||
- t->m_nodeIndices[PATH_CAR][2] >= 0 ||
- t->m_nodeIndices[PATH_CAR][3] >= 0)
- m_treadable[PATH_CAR] = t;
}
}
@@ -305,7 +305,7 @@ CPhysical::RemoveRefsToEntity(CEntity *ent)
{
int i = 0, j;
- while(i < m_nCollisionRecords) {
+ while (i < m_nCollisionRecords){
if(m_aCollisionRecords[i] == ent){
for(j = i; j < m_nCollisionRecords-1; j++)
m_aCollisionRecords[j] = m_aCollisionRecords[j+1];
@@ -419,18 +419,25 @@ 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
@@ -474,6 +481,23 @@ 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;
+ if(bIsHeavy)
+ impulse *= 0.75f;
+ ApplyMoveForce(forceDir*impulse);
+ ApplyTurnForce(forceDir*impulse, point);
+ }
+ return true;
+}
+
// What exactly is speed?
bool
CPhysical::ApplySpringDampening(float damping, CVector &springDir, CVector &point, CVector &speed)
@@ -486,6 +510,8 @@ CPhysical::ApplySpringDampening(float damping, CVector &springDir, CVector &poin
#endif
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);
@@ -502,8 +528,29 @@ CPhysical::ApplySpringDampening(float damping, CVector &springDir, CVector &poin
void
CPhysical::ApplyGravity(void)
{
- if(bAffectedByGravity)
- m_vecMoveSpeed.z -= GRAVITY * CTimer::GetTimeStep();
+ if (!bAffectedByGravity)
+ return;
+#ifdef WALLCLIMB_CHEAT
+ if (gGravityCheat && this == FindPlayerVehicle()) {
+ static CVector gravityUp(0.0f, 0.0f, 1.0f), surfaceUp(0.0f, 0.0f, 1.0f);
+ CVector belowCar = GetPosition() - 2.0f*GetUp();
+ CColPoint point;
+ CEntity* entity;
+ if (CWorld::ProcessLineOfSight(GetPosition(), belowCar, point, entity, true, false, false, false, false, false))
+ surfaceUp = point.normal;
+ else
+ surfaceUp = CVector(0.0f, 0.0f, 1.0f);
+ float t = Clamp(CTimer::GetTimeStep() * 0.5f, 0.05f, 0.8f);
+ gravityUp = gravityUp * (1.0f - t) + surfaceUp * t;
+ if (gravityUp.MagnitudeSqr() < 0.1f)
+ gravityUp = CVector(0.0f, 0.0f, 1.0f);
+ else
+ gravityUp.Normalise();
+ m_vecMoveSpeed -= GRAVITY * CTimer::GetTimeStep() * gravityUp;
+ return;
+ }
+#endif
+ m_vecMoveSpeed.z -= GRAVITY * CTimer::GetTimeStep();
}
void
@@ -522,8 +569,8 @@ CPhysical::ApplyAirResistance(void)
float f = Pow(m_fAirResistance, CTimer::GetTimeStep());
m_vecMoveSpeed *= f;
m_vecTurnSpeed *= f;
- }else{
- float f = Pow(1.0f/Abs(m_fAirResistance*0.5f*m_vecMoveSpeed.MagnitudeSqr() + 1.0f), CTimer::GetTimeStep());
+ }else if(GetStatus() != STATUS_GHOST){
+ float f = Pow(1.0f/Abs(1.0f + m_fAirResistance*0.5f*m_vecMoveSpeed.MagnitudeSqr()), CTimer::GetTimeStep());
m_vecMoveSpeed *= f;
m_vecTurnSpeed *= 0.99f;
}
@@ -536,6 +583,7 @@ 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;
@@ -551,7 +599,7 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl
if(A->bPedPhysics){
if(A->IsPed() && ((CPed*)A)->IsPlayer() && B->IsVehicle() &&
(B->GetStatus() == STATUS_ABANDONED || B->GetStatus() == STATUS_WRECKED || A->bHasHitWall))
- massFactorB = 2200.0f / B->m_fMass;
+ massFactorB = 1.0f/(Max(B->m_fMass - 2000.0f, 0.0f)/5000.0f + 1.0f);
else
massFactorB = 10.0f;
@@ -560,8 +608,13 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl
}else
massFactorB = B->bIsHeavy ? 2.0f : 1.0f;
+ if(B->bInfiniteMass && !B->m_phy_flagA08){
+ ispedcontactB = false;
+ foo = true;
+ }
+
float speedA, speedB;
- if(B->GetIsStatic()){
+ if(B->GetIsStatic() && !foo){
if(A->bPedPhysics){
speedA = DotProduct(A->m_vecMoveSpeed, colpoint.normal);
if(speedA < 0.0f){
@@ -571,8 +624,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->SetIsStatic(false);
+ CWorld::Players[CWorld::PlayerInFocus].m_nHavocLevel += 2;
+ CStats::PropertyDestroyed += CGeneral::GetRandomNumberInRange(30, 60);
+ }
}else{
if(IsGlass(B->GetModelIndex()))
CGlass::WindowRespondsToSoftCollision(B, impulseA);
@@ -624,6 +680,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) && !Bobj->bHasBeenDamaged){
+ CPickups::CreateSomeMoney(GetPosition(), CGeneral::GetRandomNumber()%100);
+ Bobj->bHasBeenDamaged = true;
}else if(B->IsObject() && !IsExplosiveThingModel(model))
Bobj->bHasBeenDamaged = true;
}else{
@@ -639,14 +698,17 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl
}
return true;
}
- }else if(!B->bInfiniteMass)
+ }else if(!B->bInfiniteMass){
B->SetIsStatic(false);
+ CWorld::Players[CWorld::PlayerInFocus].m_nHavocLevel += 2;
+ CStats::PropertyDestroyed += CGeneral::GetRandomNumberInRange(30, 60);
+ }
}
}
if(B->GetIsStatic())
return false;
- if(!B->bInfiniteMass)
+ if(!B->bInfiniteMass && !B->bIsStaticWaitingForCollision)
B->AddToMovingList();
}
@@ -656,19 +718,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 = DotProduct(B->m_vecMoveSpeed, colpoint.normal);
- float speedSum = Max(0.0f, DotProduct(B->m_vecMoveSpeed, colpoint.normal));
- // A has moved into B
+
+ 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) * A->m_fMass * massFactorA;
+ impulseA = (eA-speedA) * mA;
if(!A->bInfiniteMass)
- A->ApplyMoveForce(colpoint.normal*(impulseA/massFactorA));
+ 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){
@@ -678,7 +757,11 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl
float mA = A->m_fMass*massFactorA;
float mB = B->GetMassTweak(pointposB, colpoint.normal, massFactorB);
- float speedSum = (mB*speedB + mA*speedA)/(mA + mB);
+ float speedSum;
+ if(foo)
+ speedSum = speedB;
+ else
+ speedSum = (mB*speedB + mA*speedA)/(mA + mB);
if(speedA < speedSum){
if(A->bHasHitWall)
eA = speedSum;
@@ -813,13 +896,52 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl
}
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){
@@ -832,28 +954,61 @@ CPhysical::ApplyCollisionAlt(CEntity *B, CColPoint &colpoint, float &impulse, CV
speed = GetSpeed(pointpos);
normalSpeed = DotProduct(speed, colpoint.normal);
if(normalSpeed < 0.0f){
- float minspeed = 1.3f*GRAVITY * CTimer::GetTimeStep();
-#if GTA_VERSION >= GTA3_PC_11
- 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
@@ -1131,13 +1286,13 @@ CPhysical::ProcessShiftSectorList(CPtrList *lists)
if(B->IsBuilding())
skipShift = false;
- else if(IsStreetLight(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 &&
- IsStreetLight(B->GetModelIndex()))
+ IsLightWithoutShift(B->GetModelIndex()))
skipShift = true;
else if(A->IsObject() && B->IsVehicle()){
CObject *Aobj = (CObject*)A;
@@ -1260,6 +1415,9 @@ CPhysical::ProcessCollisionSectorList_SimpleCar(CPtrList *lists)
A = (CPhysical*)this;
+ if(!A->bUsesCollision)
+ return false;
+
radius = A->GetBoundRadius();
A->GetBoundCentre(center);
@@ -1278,6 +1436,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)){
@@ -1421,6 +1580,7 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
int numResponses;
int i, j;
bool skipCollision, altcollision;
+ bool ret = false;
float impulseA = -1.0f;
float impulseB = -1.0f;
@@ -1441,9 +1601,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)
continue;
if(!B->GetIsTouching(center, radius)){
if(A->IsObject() && Aobj->m_pCollidingEntity == B)
@@ -1463,27 +1623,27 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
if(B->IsBuilding())
skipCollision = false;
- else if(IsStreetLight(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 &&
- IsStreetLight(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->GetIsStatic()){
if(Aobj->m_pCollidingEntity == B)
skipCollision = true;
- else{
+ else if(Aobj->m_nCollisionDamageEffect < DAMAGE_EFFECT_SMASH_COMPLETELY){
CMatrix inv;
CVector size = CModelInfo::GetColModel(A->GetModelIndex())->boundingBox.GetSize();
size = A->GetMatrix() * size;
@@ -1495,14 +1655,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->GetIsStatic()){
if(Bobj->m_pCollidingEntity == A)
skipCollision = true;
- else{
+ else if(Bobj->m_nCollisionDamageEffect < DAMAGE_EFFECT_SMASH_COMPLETELY){
CMatrix inv;
CVector size = CModelInfo::GetColModel(B->GetModelIndex())->boundingBox.GetSize();
size = B->GetMatrix() * size;
@@ -1512,14 +1672,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->bKnockedOffBike)
A->bSkipLineCol = true;
}else if(B->IsPed() && Bped->m_pCollidingEntity == A){
skipCollision = true;
@@ -1534,9 +1696,12 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
if(!A->bUsesCollision || skipCollision){
B->m_scanCode = CWorld::GetCurrentScanCode();
- A->ProcessEntityCollision(B, aColPoints);
- }else if(B->IsBuilding() || B->bIsStuck || B->bInfiniteMass || altcollision){
-
+ 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->m_phy_flagA08 || altcollision){
// This is the case where B doesn't move
B->m_scanCode = CWorld::GetCurrentScanCode();
@@ -1546,6 +1711,7 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
CVector moveSpeed = CVector(0.0f, 0.0f, 0.0f);
CVector turnSpeed = CVector(0.0f, 0.0f, 0.0f);
+ float maxImpulseA = 0.0f;
numResponses = 0;
if(A->bHasContacted){
for(i = 0; i < numCollisions; i++){
@@ -1553,20 +1719,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);
+
+ 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 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(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();
+ 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));
+ DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, impulseA, Max(turnSpeedDiff, moveSpeedDiff));
+ }
}
}else{
for(i = 0; i < numCollisions; i++){
@@ -1574,38 +1755,52 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
continue;
numResponses++;
+ if(impulseA > maxImpulseA) maxImpulseA = impulseA;
+ float adhesion = CSurfaceTable::GetAdhesiveLimit(aColPoints[i]) / numCollisions;
- 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();
+ if(A->IsVehicle()){
+ if(((CVehicle*)A)->IsBoat() && aColPoints[i].surfaceB == SURFACE_WOOD_SOLID)
+ adhesion = 0.0f;
+ else if(impulseA > A->m_fDamageImpulse)
+ A->SetDamagedPieceRecord(aColPoints[i].pieceA, impulseA, B, aColPoints[i].normal);
- DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, imp, Max(turnSpeedDiff, moveSpeedDiff));
+ if(CSurfaceTable::GetAdhesionGroup(aColPoints[i].surfaceB) == ADHESIVE_SAND)
+ aColPoints[i].surfaceB = SURFACE_SAND;
- float adhesion = CSurfaceTable::GetAdhesiveLimit(aColPoints[i]) / numCollisions;
+ float turnSpeedDiff = A->m_vecTurnSpeed.MagnitudeSqr();
+ float moveSpeedDiff = A->m_vecMoveSpeed.MagnitudeSqr();
- if(A->GetModelIndex() == MI_RCBANDIT)
- adhesion *= 0.2f;
- else if(IsBoatModel(A->GetModelIndex())){
- if(aColPoints[i].normal.z > 0.6f){
- if(CSurfaceTable::GetAdhesionGroup(aColPoints[i].surfaceB) == ADHESIVE_LOOSE)
- adhesion *= 3.0f;
- }else
- adhesion = 0.0f;
- }else if(A->IsVehicle()){
- if(A->GetStatus() == STATUS_WRECKED)
+ 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]))
@@ -1619,12 +1814,18 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
if(!CWorld::bNoMoreCollisionTorque &&
A->GetStatus() == STATUS_PLAYER && A->IsVehicle() &&
Abs(A->m_vecMoveSpeed.x) > 0.2f &&
- Abs(A->m_vecMoveSpeed.y) > 0.2f){
+ Abs(A->m_vecMoveSpeed.y) > 0.2f && !A->bIsInWater){
A->m_vecMoveFriction.x += moveSpeed.x * -0.3f / numCollisions;
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{
@@ -1764,9 +1965,29 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
// 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::GetColModel(B->GetModelIndex())->boundingBox.GetSize();
+ size = B->GetMatrix() * size;
+ if(size.z < A->GetPosition().z ||
+ (Invert(A->GetMatrix(), inv) * size).z < 0.0f)
+ Bobj->ObjectDamage(50.0f);
+ }
}else if(A->IsObject() && A->bUsesCollision && B->IsVehicle()){
if(Aobj->m_nCollisionDamageEffect && maxImpulseB > 20.0f)
Aobj->ObjectDamage(maxImpulseB);
+#ifdef FIX_BUGS
+ else if(Aobj->m_nCollisionDamageEffect >= DAMAGE_EFFECT_SMASH_COMPLETELY){
+#else
+ else if(Bobj->m_nCollisionDamageEffect >= DAMAGE_EFFECT_SMASH_COMPLETELY){
+#endif
+ CMatrix inv;
+ CVector size = CModelInfo::GetColModel(A->GetModelIndex())->boundingBox.GetSize();
+ size = A->GetMatrix() * size;
+ if(size.z < B->GetPosition().z ||
+ (Invert(B->GetMatrix(), inv) * size).z < 0.0f)
+ Aobj->ObjectDamage(50.0f);
+ }
}
if(B->GetStatus() == STATUS_SIMPLE){
@@ -1775,13 +1996,15 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
CCarCtrl::SwitchVehicleToRealPhysics((CVehicle*)B);
}
- return true;
+ if(!CWorld::bSecondShift)
+ return true;
+ ret = true;
}
}
}
- return false;
+ return ret;
}
bool
@@ -1810,6 +2033,8 @@ CPhysical::CheckCollision_SimpleCar(void)
return false;
}
+float PHYSICAL_SHIFT_SPEED_DAMP = 0.707f;
+
void
CPhysical::ProcessShift(void)
{
@@ -1819,6 +2044,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();
@@ -1836,11 +2068,19 @@ CPhysical::ProcessShift(void)
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;
@@ -1852,6 +2092,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)
{
@@ -1883,31 +2126,79 @@ 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 = 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;
+ bool savedUsesCollision = bUsesCollision;
+ bUsesCollision = false;
+ if(!CheckCollision()){
+ bJustCheckCollision = false;
+ bUsesCollision = savedUsesCollision;
+ 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 = savedUsesCollision;
+ 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 = CVector(0.0f, 0.0f, 0.0f);
CVector speedDown = CVector(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);
@@ -1947,6 +2238,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 &&
@@ -1964,7 +2256,7 @@ CPhysical::ProcessCollision(void)
car->m_aSuspensionSpringRatio[2] = 1.0f;
car->m_aSuspensionSpringRatio[3] = 1.0f;
}else if(veh->m_vehType == VEHICLE_TYPE_BIKE){
- CBike* bike = (CBike*)this;
+ CBike *bike = (CBike*)this;
bike->m_aSuspensionSpringRatio[0] = 1.0f;
bike->m_aSuspensionSpringRatio[1] = 1.0f;
bike->m_aSuspensionSpringRatio[2] = 1.0f;
@@ -1980,15 +2272,15 @@ CPhysical::ProcessCollision(void)
bSkipLineCol = false;
if(!m_vecMoveSpeed.IsZero() ||
!m_vecTurnSpeed.IsZero() ||
-#ifdef GTA_TRAIN
bHitByTrain ||
-#endif
GetStatus() == STATUS_PLAYER ||
+ IsVehicle() && ((CVehicle*)this)->bRestingOnPhysical ||
IsPed() && ped->IsPlayer()){
if(IsVehicle())
((CVehicle*)this)->bVehicleColProcessed = true;
if(CheckCollision()){
GetMatrix() = savedMatrix;
+ m_fElasticity = savedElasticity;
return;
}
}
@@ -1998,5 +2290,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 a16bb211..f552da6c 100644
--- a/src/entities/Physical.h
+++ b/src/entities/Physical.h
@@ -17,7 +17,6 @@ class CPhysical : public CEntity
public:
int32 m_audioEntityId;
float m_phys_unused1;
- CTreadable *m_treadable[2]; // car and ped
uint32 m_nLastTimeCollided;
CVector m_vecMoveSpeed; // velocity
CVector m_vecTurnSpeed; // angular velocity
@@ -38,7 +37,6 @@ public:
int8 m_phys_unused2;
uint8 m_nStaticFrames;
uint8 m_nCollisionRecords;
- bool m_bIsVehicleBeingShifted;
CEntity *m_aCollisionRecords[PHYSICAL_MAX_COLLISIONRECORDS];
float m_fDistanceTravelled;
@@ -52,12 +50,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;
@@ -114,6 +117,17 @@ public:
void SetMoveSpeed(const CVector& speed) {
m_vecMoveSpeed = speed;
}
+ void AddToMoveSpeed(float x, float y, float z) {
+ m_vecMoveSpeed.x += x;
+ m_vecMoveSpeed.y += y;
+ m_vecMoveSpeed.z += z;
+ }
+ void AddToMoveSpeed(const CVector& addition) {
+ m_vecMoveSpeed += addition;
+ }
+ void AddToMoveSpeed(const CVector2D& addition) {
+ m_vecMoveSpeed += CVector(addition.x, addition.y, 0.0f);
+ }
const CVector &GetTurnSpeed() { return m_vecTurnSpeed; }
void SetTurnSpeed(float x, float y, float z) {
m_vecTurnSpeed.x = x;
@@ -142,11 +156,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);
@@ -157,5 +173,3 @@ public:
bool CheckCollision(void);
bool CheckCollision_SimpleCar(void);
};
-
-VALIDATE_SIZE(CPhysical, 0x128);
diff --git a/src/extras/custompipes.cpp b/src/extras/custompipes.cpp
index 092b3e23..a485138e 100644
--- a/src/extras/custompipes.cpp
+++ b/src/extras/custompipes.cpp
@@ -342,7 +342,7 @@ ReadTweakValueTable(char *fp, InterpolatedValue &interp)
*/
int32 VehiclePipeSwitch = VEHICLEPIPE_MATFX;
-float VehicleShininess = 0.7f; // the default is a bit extreme
+float VehicleShininess = 1.0f;
float VehicleSpecularity = 1.0f;
InterpolatedFloat Fresnel(0.4f);
InterpolatedFloat Power(18.0f);
diff --git a/src/extras/custompipes_d3d9.cpp b/src/extras/custompipes_d3d9.cpp
index 8b984448..3ad824e3 100644
--- a/src/extras/custompipes_d3d9.cpp
+++ b/src/extras/custompipes_d3d9.cpp
@@ -132,6 +132,7 @@ vehicleRenderCB(rw::Atomic *atomic, rw::d3d9::InstanceDataHeader *header)
drawInst(header, inst);
inst++;
}
+
d3d::setTexture(1, nil);
SetRenderState(SRCBLEND, BLENDSRCALPHA);
@@ -186,7 +187,7 @@ DestroyVehiclePipe(void)
*/
static void *neoWorld_VS;
-static void *neoWorldIII_PS;
+static void *neoWorldVC_PS;
static void
worldRenderCB(rw::Atomic *atomic, rw::d3d9::InstanceDataHeader *header)
@@ -244,7 +245,7 @@ worldRenderCB(rw::Atomic *atomic, rw::d3d9::InstanceDataHeader *header)
d3d::setTexture(0, m->texture);
else
d3d::setTexture(0, gpWhiteTexture);
- setPixelShader(neoWorldIII_PS);
+ setPixelShader(neoWorldVC_PS);
drawInst(header, inst);
inst++;
@@ -264,9 +265,9 @@ CreateWorldPipe(void)
neoWorld_VS = rw::d3d::createVertexShader(default_UV2_VS_cso);
assert(neoWorld_VS);
-#include "shaders/obj/neoWorldIII_PS.inc"
- neoWorldIII_PS = rw::d3d::createPixelShader(neoWorldIII_PS_cso);
- assert(neoWorldIII_PS);
+#include "shaders/obj/neoWorldVC_PS.inc"
+ neoWorldVC_PS = rw::d3d::createPixelShader(neoWorldVC_PS_cso);
+ assert(neoWorldVC_PS);
rw::d3d9::ObjPipeline *pipe = rw::d3d9::ObjPipeline::create();
@@ -281,8 +282,8 @@ DestroyWorldPipe(void)
{
rw::d3d::destroyVertexShader(neoWorld_VS);
neoWorld_VS = nil;
- rw::d3d::destroyPixelShader(neoWorldIII_PS);
- neoWorldIII_PS = nil;
+ rw::d3d::destroyPixelShader(neoWorldVC_PS);
+ neoWorldVC_PS = nil;
((rw::d3d9::ObjPipeline*)worldPipe)->destroy();
@@ -568,7 +569,6 @@ struct BuildingInst
{
rw::RawMatrix combinedMat;
rw::d3d9::InstanceDataHeader *instHeader;
- uint32 cullMode;
uint8 fadeAlpha;
bool lighting;
};
@@ -613,7 +613,6 @@ AtomicFirstPass(RpAtomic *atomic, int pass)
assert(building->instHeader->platform == PLATFORM_D3D9);
building->fadeAlpha = 255;
building->lighting = !!(atomic->geometry->flags & rw::Geometry::LIGHT);
- building->cullMode = rw::GetRenderState(rw::CULLMODE);
rw::uint32 flags = atomic->geometry->flags;
bool setupDone = false;
@@ -632,7 +631,6 @@ AtomicFirstPass(RpAtomic *atomic, int pass)
// alright we're rendering this atomic
if(!setupDone){
- rw::SetRenderState(rw::CULLMODE, building->cullMode);
setStreamSource(0, building->instHeader->vertexStream[0].vertexBuffer, 0, building->instHeader->vertexStream[0].stride);
setIndices(building->instHeader->indexBuffer);
setVertexDeclaration(building->instHeader->vertexDeclaration);
@@ -674,7 +672,6 @@ AtomicFullyTransparent(RpAtomic *atomic, int pass, int fadeAlpha)
assert(building->instHeader->platform == PLATFORM_D3D9);
building->fadeAlpha = fadeAlpha;
building->lighting = !!(atomic->geometry->flags & rw::Geometry::LIGHT);
- building->cullMode = rw::GetRenderState(rw::CULLMODE);
SetMatrix(building, atomic->getFrame()->getLTM());
numBlendInsts[pass]++;
}
@@ -692,7 +689,6 @@ RenderBlendPass(int pass)
for(i = 0; i < numBlendInsts[pass]; i++){
BuildingInst *building = &blendInsts[pass][i];
- rw::SetRenderState(rw::CULLMODE, building->cullMode);
setStreamSource(0, building->instHeader->vertexStream[0].vertexBuffer, 0, building->instHeader->vertexStream[0].stride);
setIndices(building->instHeader->indexBuffer);
setVertexDeclaration(building->instHeader->vertexDeclaration);
diff --git a/src/extras/custompipes_gl.cpp b/src/extras/custompipes_gl.cpp
index 2b28cb52..d74e40db 100644
--- a/src/extras/custompipes_gl.cpp
+++ b/src/extras/custompipes_gl.cpp
@@ -128,9 +128,10 @@ vehicleRenderCB(rw::Atomic *atomic, rw::gl3::InstanceDataHeader *header)
inst++;
}
- SetRenderState(SRCBLEND, BLENDSRCALPHA);
setTexture(1, nil);
+ SetRenderState(SRCBLEND, BLENDSRCALPHA);
+
teardownVertexInput(header);
}
@@ -255,10 +256,10 @@ CreateWorldPipe(void)
ReadTweakValueTable((char*)work_buff, WorldLightmapBlend);
{
-#include "shaders/obj/neoWorldIII_frag.inc"
+#include "shaders/obj/neoWorldVC_frag.inc"
#include "shaders/obj/default_UV2_vert.inc"
const char *vs[] = { shaderDecl, header_vert_src, default_UV2_vert_src, nil };
- const char *fs[] = { shaderDecl, header_frag_src, neoWorldIII_frag_src, nil };
+ const char *fs[] = { shaderDecl, header_frag_src, neoWorldVC_frag_src, nil };
neoWorldShader = Shader::create(vs, fs);
assert(neoWorldShader);
}
@@ -595,7 +596,6 @@ struct BuildingInst
{
rw::Matrix matrix;
rw::gl3::InstanceDataHeader *instHeader;
- uint32 cullMode;
uint8 fadeAlpha;
bool lighting;
};
@@ -628,7 +628,6 @@ AtomicFirstPass(RpAtomic *atomic, int pass)
assert(building->instHeader->platform == PLATFORM_GL3);
building->fadeAlpha = 255;
building->lighting = !!(atomic->geometry->flags & rw::Geometry::LIGHT);
- building->cullMode = rw::GetRenderState(rw::CULLMODE);
rw::uint32 flags = atomic->geometry->flags;
WorldLights lights;
@@ -656,7 +655,6 @@ AtomicFirstPass(RpAtomic *atomic, int pass)
// alright we're rendering this atomic
if(!setupDone){
- rw::SetRenderState(rw::CULLMODE, building->cullMode);
defaultShader->use();
setWorldMatrix(&building->matrix);
setupVertexInput(building->instHeader);
@@ -689,7 +687,6 @@ AtomicFullyTransparent(RpAtomic *atomic, int pass, int fadeAlpha)
assert(building->instHeader->platform == PLATFORM_GL3);
building->fadeAlpha = fadeAlpha;
building->lighting = !!(atomic->geometry->flags & rw::Geometry::LIGHT);
- building->cullMode = rw::GetRenderState(rw::CULLMODE);
building->matrix = *atomic->getFrame()->getLTM();
numBlendInsts[pass]++;
}
@@ -710,7 +707,6 @@ RenderBlendPass(int pass)
for(i = 0; i < numBlendInsts[pass]; i++){
BuildingInst *building = &blendInsts[pass][i];
- rw::SetRenderState(rw::CULLMODE, building->cullMode);
setupVertexInput(building->instHeader);
setWorldMatrix(&building->matrix);
if(building->lighting)
diff --git a/src/extras/debugmenu.h b/src/extras/debugmenu.h
index 45b65d04..f1357c0a 100644
--- a/src/extras/debugmenu.h
+++ b/src/extras/debugmenu.h
@@ -30,61 +30,61 @@
class CTweakVar
{
public:
- virtual void AddDBG(const char* path) = 0;
+ virtual void AddDBG(const char *path) = 0;
};
class CTweakVars
{
public:
- static void Add(CTweakVar* var);
- static void AddDBG(const char* path);
+ static void Add(CTweakVar *var);
+ static void AddDBG(const char *path);
};
class CTweakFunc : public CTweakVar
{
- const char* m_pPath, * m_pVarName;
+ const char *m_pPath, *m_pVarName;
void (*m_pFunc)();
public:
- CTweakFunc(void (*pFunc)(), const char* strName, const char* strPath) :
+ CTweakFunc(void (*pFunc)(), const char *strName, const char *strPath) :
m_pPath(strPath), m_pVarName(strName), m_pFunc(pFunc)
{
CTweakVars::Add(this);
}
-
- void AddDBG(const char* path);
+
+ void AddDBG(const char *path);
};
class CTweakBool : public CTweakVar
{
- const char* m_pPath, * m_pVarName;
- bool* m_pBoolVar;
+ const char *m_pPath, *m_pVarName;
+ bool *m_pBoolVar;
public:
- CTweakBool(bool* pBool, const char* strName, const char* strPath) :
+ CTweakBool(bool *pBool, const char *strName, const char *strPath) :
m_pPath(strPath), m_pVarName(strName), m_pBoolVar(pBool)
{
CTweakVars::Add(this);
}
-
- void AddDBG(const char* path);
+
+ void AddDBG(const char *path);
};
class CTweakSwitch : public CTweakVar
{
- const char* m_pPath, * m_pVarName;
- void* m_pIntVar;
+ const char *m_pPath, *m_pVarName;
+ void *m_pIntVar;
int32 m_nMin, m_nMax;
- const char** m_aStr;
+ const char **m_aStr;
void (*m_pFunc)();
public:
- CTweakSwitch(void* pInt, const char* strName, int32 nMin, int32 nMax, const char** aStr,
- void (*pFunc)(), const char* strPath)
- : m_pPath(strPath), m_pVarName(strName), m_pIntVar(pInt), m_nMin(nMin), m_nMax(nMax),
- m_aStr(aStr)
+ CTweakSwitch(void *pInt, const char *strName, int32 nMin, int32 nMax, const char **aStr,
+ void (*pFunc)(), const char *strPath)
+ : m_pPath(strPath), m_pVarName(strName), m_pIntVar(pInt), m_nMin(nMin), m_nMax(nMax),
+ m_aStr(aStr)
{
CTweakVars::Add(this);
}
- void AddDBG(const char* path);
+ void AddDBG(const char *path);
};
#define _TWEEKCLASS(name, type) \
diff --git a/src/extras/frontendoption.cpp b/src/extras/frontendoption.cpp
index 5d388bfd..2660e75e 100644
--- a/src/extras/frontendoption.cpp
+++ b/src/extras/frontendoption.cpp
@@ -13,24 +13,9 @@ int optionCursor = -2;
int currentMenu;
bool optionOverwrite = false;
-void ChangeScreen(int screen, int option, bool fadeIn)
+void GoBack()
{
- FrontEndMenuManager.m_nPrevScreen = FrontEndMenuManager.m_nCurrScreen;
- FrontEndMenuManager.m_nCurrScreen = screen;
- FrontEndMenuManager.m_nCurrOption = option;
- if (fadeIn)
- FrontEndMenuManager.m_nMenuFadeAlpha = 0;
-}
-
-void GoBack(bool fadeIn)
-{
- int screen = !FrontEndMenuManager.m_bGameNotLoaded ?
- aScreens[FrontEndMenuManager.m_nCurrScreen].m_PreviousPage[1] : aScreens[FrontEndMenuManager.m_nCurrScreen].m_PreviousPage[0];
- int option = FrontEndMenuManager.GetPreviousPageOption();
-
- FrontEndMenuManager.ThingsToDoBeforeGoingBack();
-
- ChangeScreen(screen, option, fadeIn);
+ FrontEndMenuManager.SwitchToNewScreen(-1);
}
uint8
@@ -51,7 +36,7 @@ GetLastMenuScreen()
{
int8 page = -1;
for (int i = 0; i < MENUPAGES; i++) {
- if (strcmp(aScreens[i].m_ScreenName, "") == 0 && aScreens[i].m_PreviousPage[0] == MENUPAGE_NONE)
+ if (strcmp(aScreens[i].m_ScreenName, "") == 0 && aScreens[i].m_PreviousPage == MENUPAGE_NONE)
break;
++page;
@@ -68,7 +53,7 @@ int8 RegisterNewScreen(const char *name, int prevPage, ReturnPrevPageFunc return
int id = lastOgScreen + numCustomFrontendScreens;
assert(id < MENUPAGES && "No room for new custom frontend screens! Increase MENUPAGES");
strncpy(aScreens[id].m_ScreenName, name, 8);
- aScreens[id].m_PreviousPage[0] = aScreens[id].m_PreviousPage[1] = prevPage;
+ aScreens[id].m_PreviousPage = prevPage;
aScreens[id].returnPrevPageFunc = returnPrevPageFunc;
return id;
}
@@ -101,7 +86,7 @@ void FrontendOptionSetCursor(int screen, int8 option, bool overwrite)
optionOverwrite = overwrite;
}
-void FrontendOptionAddBuiltinAction(const char* gxtKey, int action, int targetMenu, int saveSlot) {
+void FrontendOptionAddBuiltinAction(const char* gxtKey, uint16 x, uint16 y, uint8 align, int action, int targetMenu, int saveSlot) {
int8 screenOptionOrder = RegisterNewOption();
CMenuScreenCustom::CMenuEntry &option = aScreens[currentMenu].m_aEntries[screenOptionOrder];
@@ -118,17 +103,23 @@ void FrontendOptionAddBuiltinAction(const char* gxtKey, int action, int targetMe
strncpy(option.m_EntryName, gxtKey, 8);
break;
}
+ option.m_X = x;
+ option.m_Y = y;
+ option.m_Align = align;
option.m_Action = action;
option.m_SaveSlot = saveSlot;
option.m_TargetMenu = targetMenu;
}
-void FrontendOptionAddSelect(const char* gxtKey, const char** rightTexts, int8 numRightTexts, int8 *var, bool onlyApplyOnEnter, ChangeFunc changeFunc, const char* saveCat, const char* saveKey, bool disableIfGameLoaded)
+void FrontendOptionAddSelect(const char* gxtKey, uint16 x, uint16 y, uint8 align, const char** rightTexts, int8 numRightTexts, int8 *var, bool onlyApplyOnEnter, ChangeFunc changeFunc, const char* saveCat, const char* saveName, bool disableIfGameLoaded)
{
int8 screenOptionOrder = RegisterNewOption();
CMenuScreenCustom::CMenuEntry &option = aScreens[currentMenu].m_aEntries[screenOptionOrder];
option.m_Action = MENUACTION_CFO_SELECT;
+ option.m_X = x;
+ option.m_Y = y;
+ option.m_Align = align;
strncpy(option.m_EntryName, gxtKey, 8);
option.m_CFOSelect = new CCFOSelect();
option.m_CFOSelect->rightTexts = (char**)malloc(numRightTexts * sizeof(char*));
@@ -140,42 +131,39 @@ void FrontendOptionAddSelect(const char* gxtKey, const char** rightTexts, int8 n
option.m_CFOSelect->lastSavedValue = *var;
}
option.m_CFOSelect->saveCat = saveCat;
- option.m_CFOSelect->save = saveKey;
+ option.m_CFOSelect->save = saveName;
option.m_CFOSelect->onlyApplyOnEnter = onlyApplyOnEnter;
option.m_CFOSelect->changeFunc = changeFunc;
option.m_CFOSelect->disableIfGameLoaded = disableIfGameLoaded;
}
-void FrontendOptionAddDynamic(const char* gxtKey, DrawFunc drawFunc, int8 *var, ButtonPressFunc buttonPressFunc, const char* saveCat, const char* saveKey)
+void FrontendOptionAddDynamic(const char* gxtKey, uint16 x, uint16 y, uint8 align, DrawFunc drawFunc, int8 *var, ButtonPressFunc buttonPressFunc, const char* saveCat, const char* saveName)
{
int8 screenOptionOrder = RegisterNewOption();
CMenuScreenCustom::CMenuEntry &option = aScreens[currentMenu].m_aEntries[screenOptionOrder];
option.m_Action = MENUACTION_CFO_DYNAMIC;
+ option.m_X = x;
+ option.m_Y = y;
+ option.m_Align = align;
strncpy(option.m_EntryName, gxtKey, 8);
option.m_CFODynamic = new CCFODynamic();
option.m_CFODynamic->drawFunc = drawFunc;
option.m_CFODynamic->buttonPressFunc = buttonPressFunc;
option.m_CFODynamic->value = var;
option.m_CFODynamic->saveCat = saveCat;
- option.m_CFODynamic->save = saveKey;
+ option.m_CFODynamic->save = saveName;
}
-uint8 FrontendScreenAdd(const char* gxtKey, eMenuSprites sprite, int prevPage, int columnWidth, int headerHeight, int lineHeight,
- int8 font, float fontScaleX, float fontScaleY, int8 alignment, bool showLeftRightHelper, ReturnPrevPageFunc returnPrevPageFunc) {
+// lineHeight = 0 means game will use MENU_DEFAULT_LINE_HEIGHT
+uint8 FrontendScreenAdd(const char* gxtKey, int prevPage, int lineHeight, bool showLeftRightHelper, ReturnPrevPageFunc returnPrevPageFunc) {
uint8 screenOrder = RegisterNewScreen(gxtKey, prevPage, returnPrevPageFunc);
CCustomScreenLayout *screen = new CCustomScreenLayout();
aScreens[screenOrder].layout = screen;
- screen->sprite = sprite;
- screen->columnWidth = columnWidth;
- screen->headerHeight = headerHeight;
screen->lineHeight = lineHeight;
- screen->font = font;
- screen->fontScaleX = fontScaleX;
- screen->fontScaleY = fontScaleY;
- screen->alignment = alignment;
+ screen->showLeftRightHelper = showLeftRightHelper;
return screenOrder;
}
diff --git a/src/extras/frontendoption.h b/src/extras/frontendoption.h
index a571170f..db1b9021 100644
--- a/src/extras/frontendoption.h
+++ b/src/extras/frontendoption.h
@@ -26,11 +26,6 @@
#define FEOPTION_ACTION_SELECT 2
#define FEOPTION_ACTION_FOCUSLOSS 3
-// -- Passed via FrontendScreenAdd()
-#define FESCREEN_CENTER 0
-#define FESCREEN_LEFT_ALIGN 1
-#define FESCREEN_RIGHT_ALIGN 2
-
// -- Callbacks
// pretty much in everything I guess, and optional in all of them
@@ -54,8 +49,7 @@ extern int numCustomFrontendOptions;
extern int numCustomFrontendScreens;
// -- To be used in ButtonPressFunc / ChangeFunc(this one would be weird):
-void ChangeScreen(int screen, int option = 0, bool fadeIn = true);
-void GoBack(bool fadeIn = true);
+void GoBack(void);
uint8 GetNumberOfMenuOptions(int screen);
@@ -84,10 +78,11 @@ uint8 GetNumberOfMenuOptions(int screen);
void FrontendOptionSetCursor(int screen, int8 option, bool overwrite = false);
-// var is optional in AddDynamic, enables you to save them in an INI file(also needs passing char array to and saveCat saveKey param. obv), otherwise pass nil/0
-void FrontendOptionAddBuiltinAction(const char* gxtKey, int action, int targetMenu = MENUPAGE_NONE, int saveSlot = SAVESLOT_NONE);
-void FrontendOptionAddSelect(const char* gxtKey, const char** rightTexts, int8 numRightTexts, int8 *var, bool onlyApplyOnEnter, ChangeFunc changeFunc, const char* saveCat = nil, const char* saveKey = nil, bool disableIfGameLoaded = false);
-void FrontendOptionAddDynamic(const char* gxtKey, DrawFunc rightTextDrawFunc, int8 *var, ButtonPressFunc buttonPressFunc, const char* saveCat = nil, const char* saveKey = nil);
+// var is optional in AddDynamic, enables you to save them in an INI file(also needs passing char array to saveCat and saveKey param. obv), otherwise pass nil/0
+void FrontendOptionAddBuiltinAction(const char* gxtKey, uint16 x, uint16 y, uint8 align, int action, int targetMenu = MENUPAGE_NONE, int saveSlot = SAVESLOT_NONE);
+void FrontendOptionAddSelect(const char* gxtKey, uint16 x, uint16 y, uint8 align, const char** rightTexts, int8 numRightTexts, int8 *var, bool onlyApplyOnEnter, ChangeFunc changeFunc, const char* saveCat = nil, const char* saveKey = nil, bool disableIfGameLoaded = false);
+void FrontendOptionAddDynamic(const char* gxtKey, uint16 x, uint16 y, uint8 align, DrawFunc rightTextDrawFunc, int8 *var, ButtonPressFunc buttonPressFunc, const char* saveCat = nil, const char* saveKey = nil);
-uint8 FrontendScreenAdd(const char* gxtKey, eMenuSprites sprite, int prevPage, int columnWidth, int headerHeight, int lineHeight, int8 font, float fontScaleX, float fontScaleY, int8 alignment, bool showLeftRightHelper, ReturnPrevPageFunc returnPrevPageFunc = nil);
+// lineHeight = 0 means game will use MENU_DEFAULT_LINE_HEIGHT
+uint8 FrontendScreenAdd(const char* gxtKey, int prevPage, int lineHeight, bool showLeftRightHelper, ReturnPrevPageFunc returnPrevPageFunc = nil);
#endif
diff --git a/src/extras/postfx.cpp b/src/extras/postfx.cpp
index 425a22d4..ee6c3964 100644
--- a/src/extras/postfx.cpp
+++ b/src/extras/postfx.cpp
@@ -17,6 +17,7 @@ RwRaster *CPostFX::pFrontBuffer;
RwRaster *CPostFX::pBackBuffer;
bool CPostFX::bJustInitialised;
int CPostFX::EffectSwitch = POSTFX_NORMAL;
+bool CPostFX::BlurOn = false;
bool CPostFX::MotionBlurOn = false;
static RwIm2DVertex Vertex[4];
@@ -24,14 +25,14 @@ static RwIm2DVertex Vertex2[4];
static RwImVertexIndex Index[6] = { 0, 1, 2, 0, 2, 3 };
#ifdef RW_D3D9
-void *colourfilterIII_PS;
+void *colourfilterVC_PS;
void *contrast_PS;
#endif
#ifdef RW_OPENGL
int32 u_blurcolor;
int32 u_contrastAdd;
int32 u_contrastMult;
-rw::gl3::Shader *colourFilterIII;
+rw::gl3::Shader *colourFilterVC;
rw::gl3::Shader *contrast;
#endif
@@ -145,20 +146,21 @@ CPostFX::Open(RwCamera *cam)
#ifdef RW_D3D9
-#include "shaders/obj/colourfilterIII_PS.inc"
- colourfilterIII_PS = rw::d3d::createPixelShader(colourfilterIII_PS_cso);
+#include "shaders/obj/colourfilterVC_PS.inc"
+ colourfilterVC_PS = rw::d3d::createPixelShader(colourfilterVC_PS_cso);
#include "shaders/obj/contrastPS.inc"
contrast_PS = rw::d3d::createPixelShader(contrastPS_cso);
#endif
#ifdef RW_OPENGL
using namespace rw::gl3;
+
{
#include "shaders/obj/im2d_vert.inc"
-#include "shaders/obj/colourfilterIII_frag.inc"
+#include "shaders/obj/colourfilterVC_frag.inc"
const char *vs[] = { shaderDecl, header_vert_src, im2d_vert_src, nil };
- const char *fs[] = { shaderDecl, header_frag_src, colourfilterIII_frag_src, nil };
- colourFilterIII = Shader::create(vs, fs);
- assert(colourFilterIII);
+ const char *fs[] = { shaderDecl, header_frag_src, colourfilterVC_frag_src, nil };
+ colourFilterVC = Shader::create(vs, fs);
+ assert(colourFilterVC);
}
{
@@ -185,9 +187,9 @@ CPostFX::Close(void)
pBackBuffer = nil;
}
#ifdef RW_D3D9
- if(colourfilterIII_PS){
- rw::d3d::destroyPixelShader(colourfilterIII_PS);
- colourfilterIII_PS = nil;
+ if(colourfilterVC_PS){
+ rw::d3d::destroyPixelShader(colourfilterVC_PS);
+ colourfilterVC_PS = nil;
}
if(contrast_PS){
rw::d3d::destroyPixelShader(contrast_PS);
@@ -195,9 +197,9 @@ CPostFX::Close(void)
}
#endif
#ifdef RW_OPENGL
- if(colourFilterIII){
- colourFilterIII->destroy();
- colourFilterIII = nil;
+ if(colourFilterVC){
+ colourFilterVC->destroy();
+ colourFilterVC = nil;
}
if(contrast){
contrast->destroy();
@@ -212,37 +214,35 @@ CPostFX::RenderOverlayBlur(RwCamera *cam, int32 r, int32 g, int32 b, int32 a)
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, pFrontBuffer);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
- RwIm2DVertexSetIntRGBA(&Vertex[0], r, g, b, a);
- RwIm2DVertexSetIntRGBA(&Vertex[1], r, g, b, a);
- RwIm2DVertexSetIntRGBA(&Vertex[2], r, g, b, a);
- RwIm2DVertexSetIntRGBA(&Vertex[3], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex[0], r*2, g*2, b*2, 30);
+ RwIm2DVertexSetIntRGBA(&Vertex[1], r*2, g*2, b*2, 30);
+ RwIm2DVertexSetIntRGBA(&Vertex[2], r*2, g*2, b*2, 30);
+ RwIm2DVertexSetIntRGBA(&Vertex[3], r*2, g*2, b*2, 30);
+ RwIm2DVertexSetIntRGBA(&Vertex2[0], r*2, g*2, b*2, 30);
+ RwIm2DVertexSetIntRGBA(&Vertex2[1], r*2, g*2, b*2, 30);
+ RwIm2DVertexSetIntRGBA(&Vertex2[2], r*2, g*2, b*2, 30);
+ RwIm2DVertexSetIntRGBA(&Vertex2[3], r*2, g*2, b*2, 30);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
- RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, Vertex, 4, Index, 6);
-}
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, BlurOn ? Vertex2 : Vertex, 4, Index, 6);
-void
-CPostFX::RenderOverlaySimple(RwCamera *cam, int32 r, int32 g, int32 b, int32 a)
-{
- RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
- RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
-
- r *= 0.6f;
- g *= 0.6f;
- b *= 0.6f;
- a *= 0.6f;
+ RwIm2DVertexSetIntRGBA(&Vertex2[0], r, g, b, a);
RwIm2DVertexSetIntRGBA(&Vertex[0], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex2[1], r, g, b, a);
RwIm2DVertexSetIntRGBA(&Vertex[1], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex2[2], r, g, b, a);
RwIm2DVertexSetIntRGBA(&Vertex[2], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex2[3], r, g, b, a);
RwIm2DVertexSetIntRGBA(&Vertex[3], r, g, b, a);
- RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
- RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, Vertex, 4, Index, 6);
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, BlurOn ? Vertex2 : Vertex, 4, Index, 6);
}
void
@@ -270,12 +270,12 @@ CPostFX::RenderOverlayShader(RwCamera *cam, int32 r, int32 g, int32 b, int32 a)
if(EffectSwitch == POSTFX_MOBILE){
float mult[3], add[3];
- mult[0] = (r-64)/384.0f + 1.14f;
- mult[1] = (g-64)/384.0f + 1.14f;
- mult[2] = (b-64)/384.0f + 1.14f;
- add[0] = r/1536.f;
- add[1] = g/1536.f;
- add[2] = b/1536.f;
+ mult[0] = (r-64)/256.0f + 1.4f;
+ mult[1] = (g-64)/256.0f + 1.4f;
+ mult[2] = (b-64)/256.0f + 1.4f;
+ add[0] = r/1536.f - 0.05f;
+ add[1] = g/1536.f - 0.05f;
+ add[2] = b/1536.f - 0.05f;
#ifdef RW_D3D9
rw::d3d::d3ddevice->SetPixelShaderConstantF(10, mult, 1);
rw::d3d::d3ddevice->SetPixelShaderConstantF(11, add, 1);
@@ -291,18 +291,18 @@ CPostFX::RenderOverlayShader(RwCamera *cam, int32 r, int32 g, int32 b, int32 a)
}else{
float f = Intensity;
float blurcolors[4];
- blurcolors[0] = r/255.0f;
- blurcolors[1] = g/255.0f;
- blurcolors[2] = b/255.0f;
- blurcolors[3] = a*f/255.0f;
+ blurcolors[0] = r*f/255.0f;
+ blurcolors[1] = g*f/255.0f;
+ blurcolors[2] = b*f/255.0f;
+ blurcolors[3] = 30/255.0f;
#ifdef RW_D3D9
rw::d3d::d3ddevice->SetPixelShaderConstantF(10, blurcolors, 1);
- rw::d3d::im2dOverridePS = colourfilterIII_PS;
+ rw::d3d::im2dOverridePS = colourfilterVC_PS;
#endif
#ifdef RW_OPENGL
- rw::gl3::im2dOverrideShader = colourFilterIII;
- colourFilterIII->use();
- glUniform4fv(colourFilterIII->uniformLocations[u_blurcolor], 1, blurcolors);
+ rw::gl3::im2dOverrideShader = colourFilterVC;
+ colourFilterVC->use();
+ glUniform4fv(colourFilterVC->uniformLocations[u_blurcolor], 1, blurcolors);
#endif
}
RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, Vertex, 4, Index, 6);
@@ -339,9 +339,8 @@ CPostFX::NeedBackBuffer(void)
// Current frame -- needed for non-blur effect
switch(EffectSwitch){
case POSTFX_OFF:
- // no actual rendering here
- return false;
case POSTFX_SIMPLE:
+ // no actual rendering here
return false;
case POSTFX_NORMAL:
if(MotionBlurOn)
@@ -358,11 +357,24 @@ bool
CPostFX::NeedFrontBuffer(int32 type)
{
// Last frame -- needed for motion blur
- if(MotionBlurOn)
+ if(CMBlur::Drunkness > 0.0f)
return true;
if(type == MOTION_BLUR_SNIPER)
return true;
+ switch(EffectSwitch){
+ case POSTFX_OFF:
+ case POSTFX_SIMPLE:
+ // no actual rendering here
+ return false;
+ case POSTFX_NORMAL:
+ if(MotionBlurOn)
+ return true;
+ else
+ return false;
+ case POSTFX_MOBILE:
+ return false;
+ }
return false;
}
@@ -377,46 +389,21 @@ CPostFX::GetBackBuffer(RwCamera *cam)
void
CPostFX::Render(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 blur, int32 type, uint32 bluralpha)
{
- switch(type)
- {
- case MOTION_BLUR_SECURITY_CAM:
- red = 0;
- green = 255;
- blue = 0;
- blur = 128;
- break;
- case MOTION_BLUR_INTRO:
- red = 100;
- green = 220;
- blue = 230;
- blur = 158;
- break;
- case MOTION_BLUR_INTRO2:
- red = 80;
- green = 255;
- blue = 230;
- blur = 138;
- break;
- case MOTION_BLUR_INTRO3:
- red = 255;
- green = 60;
- blue = 60;
- blur = 200;
- break;
- case MOTION_BLUR_INTRO4:
- red = 255;
- green = 180;
- blue = 180;
- blur = 128;
- break;
- }
-
PUSH_RENDERGROUP("CPostFX::Render");
+
if(pFrontBuffer == nil)
Open(cam);
assert(pFrontBuffer);
assert(pBackBuffer);
+ if(type == MOTION_BLUR_LIGHT_SCENE){
+ SmoothColor(red, green, blue, blur);
+ red = AvgRed;
+ green = AvgGreen;
+ blue = AvgBlue;
+ blur = AvgAlpha;
+ }
+
if(NeedBackBuffer())
GetBackBuffer(cam);
@@ -432,10 +419,8 @@ CPostFX::Render(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 blu
RenderOverlaySniper(cam, red, green, blue, blur);
}else switch(EffectSwitch){
case POSTFX_OFF:
- // no actual rendering here
- break;
case POSTFX_SIMPLE:
- RenderOverlaySimple(cam, red, green, blue, blur);
+ // no actual rendering here
break;
case POSTFX_NORMAL:
if(MotionBlurOn){
@@ -450,10 +435,8 @@ CPostFX::Render(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 blu
break;
}
- // TODO? maybe we want this even without motion blur on sometimes?
- if(MotionBlurOn)
- if(!bJustInitialised)
- RenderMotionBlur(cam, bluralpha);
+ if(!bJustInitialised)
+ RenderMotionBlur(cam, 175.0f * CMBlur::Drunkness);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
@@ -473,4 +456,39 @@ CPostFX::Render(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 blu
POP_RENDERGROUP();
}
+int CPostFX::PrevRed[NUMAVERAGE], CPostFX::AvgRed;
+int CPostFX::PrevGreen[NUMAVERAGE], CPostFX::AvgGreen;
+int CPostFX::PrevBlue[NUMAVERAGE], CPostFX::AvgBlue;
+int CPostFX::PrevAlpha[NUMAVERAGE], CPostFX::AvgAlpha;
+int CPostFX::Next;
+int CPostFX::NumValues;
+
+// This is rather annoying...the blur color can flicker slightly
+// which becomes very visible when amplified by the shader
+void
+CPostFX::SmoothColor(uint32 red, uint32 green, uint32 blue, uint32 alpha)
+{
+ PrevRed[Next] = red;
+ PrevGreen[Next] = green;
+ PrevBlue[Next] = blue;
+ PrevAlpha[Next] = alpha;
+ Next = (Next+1) % NUMAVERAGE;
+ NumValues = Min(NumValues+1, NUMAVERAGE);
+
+ AvgRed = 0;
+ AvgGreen = 0;
+ AvgBlue = 0;
+ AvgAlpha = 0;
+ for(int i = 0; i < NumValues; i++){
+ AvgRed += PrevRed[i];
+ AvgGreen += PrevGreen[i];
+ AvgBlue += PrevBlue[i];
+ AvgAlpha += PrevAlpha[i];
+ }
+ AvgRed /= NumValues;
+ AvgGreen /= NumValues;
+ AvgBlue /= NumValues;
+ AvgAlpha /= NumValues;
+}
+
#endif
diff --git a/src/extras/postfx.h b/src/extras/postfx.h
index f8779a6d..db702bf3 100644
--- a/src/extras/postfx.h
+++ b/src/extras/postfx.h
@@ -15,18 +15,28 @@ public:
static RwRaster *pBackBuffer;
static bool bJustInitialised;
static int EffectSwitch;
+ static bool BlurOn; // or use CMblur for that?
static bool MotionBlurOn; // or use CMblur for that?
static float Intensity;
+ // smooth blur color
+ enum { NUMAVERAGE = 20 };
+ static int PrevRed[NUMAVERAGE], AvgRed;
+ static int PrevGreen[NUMAVERAGE], AvgGreen;
+ static int PrevBlue[NUMAVERAGE], AvgBlue;
+ static int PrevAlpha[NUMAVERAGE], AvgAlpha;
+ static int Next;
+ static int NumValues;
+
static void InitOnce(void);
static void Open(RwCamera *cam);
static void Close(void);
static void RenderOverlayBlur(RwCamera *cam, int32 r, int32 g, int32 b, int32 a);
- static void RenderOverlaySimple(RwCamera *cam, int32 r, int32 g, int32 b, int32 a);
static void RenderOverlaySniper(RwCamera *cam, int32 r, int32 g, int32 b, int32 a);
static void RenderOverlayShader(RwCamera *cam, int32 r, int32 g, int32 b, int32 a);
static void RenderMotionBlur(RwCamera *cam, uint32 blur);
static void Render(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 blur, int32 type, uint32 bluralpha);
+ static void SmoothColor(uint32 red, uint32 green, uint32 blue, uint32 alpha);
static bool NeedBackBuffer(void);
static bool NeedFrontBuffer(int32 type);
static void GetBackBuffer(RwCamera *cam);
diff --git a/src/extras/shaders/colourfilterIII.frag b/src/extras/shaders/colourfilterVC.frag
index 95e5d052..283aa817 100644
--- a/src/extras/shaders/colourfilterIII.frag
+++ b/src/extras/shaders/colourfilterVC.frag
@@ -9,10 +9,13 @@ void
main(void)
{
float a = u_blurcolor.a;
+ vec4 doublec = clamp(u_blurcolor*2.0, 0.0, 1.0);
vec4 dst = texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));
vec4 prev = dst;
for(int i = 0; i < 5; i++){
- vec4 tmp = dst*(1.0-a) + prev*u_blurcolor*a;
+ vec4 tmp = dst*(1.0-a) + prev*doublec*a;
+ tmp += prev*u_blurcolor;
+ tmp += prev*u_blurcolor;
prev = clamp(tmp, 0.0, 1.0);
}
vec4 color;
diff --git a/src/extras/shaders/colourfilterIII_PS.hlsl b/src/extras/shaders/colourfilterVC_PS.hlsl
index 3d893c3c..90d3b50c 100644
--- a/src/extras/shaders/colourfilterIII_PS.hlsl
+++ b/src/extras/shaders/colourfilterVC_PS.hlsl
@@ -1,13 +1,21 @@
sampler2D tex : register(s0);
float4 blurcol : register(c10);
+//float4 blurcols[10] : register(c15);
+
+
float4 main(in float2 texcoord : TEXCOORD0) : COLOR0
{
float a = blurcol.a;
+
+ float4 doublec = saturate(blurcol*2);
float4 dst = tex2D(tex, texcoord.xy);
float4 prev = dst;
for(int i = 0; i < 5; i++){
- float4 tmp = dst*(1-a) + prev*blurcol*a;
+// float4 doublec = saturate(blurcol*2);
+ float4 tmp = dst*(1-a) + prev*doublec*a;
+ tmp += prev*blurcol;
+ tmp += prev*blurcol;
prev = saturate(tmp);
}
prev.a = 1.0;
diff --git a/src/extras/shaders/neoWorldIII.frag b/src/extras/shaders/neoWorldVC.frag
index d8bb7159..08cae743 100644
--- a/src/extras/shaders/neoWorldIII.frag
+++ b/src/extras/shaders/neoWorldVC.frag
@@ -14,7 +14,8 @@ main(void)
vec4 t0 = texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));
vec4 t1 = texture(tex1, vec2(v_tex1.x, 1.0-v_tex1.y));
- vec4 color = t0*v_color*(1.0 + u_lightMap*(2.0*t1-1.0));
+ vec4 color;
+ color = t0*v_color*(1.0 + u_lightMap*(t1-1.0));
color.a = v_color.a*t0.a*u_lightMap.a;
color.rgb = mix(u_fogColor.rgb, color.rgb, v_fog);
diff --git a/src/extras/shaders/neoWorldIII_PS.hlsl b/src/extras/shaders/neoWorldVC_PS.hlsl
index 8a3d5d86..fc4f1de9 100644
--- a/src/extras/shaders/neoWorldIII_PS.hlsl
+++ b/src/extras/shaders/neoWorldVC_PS.hlsl
@@ -16,7 +16,7 @@ main(PS_INPUT IN) : COLOR
float4 t0 = tex2D(Diffuse, IN.Tex0.xy);
float4 t1 = tex2D(Light, IN.Tex1);
- float4 col = t0*IN.Color*(1 + lm*(2*t1-1));
+ float4 col = t0*IN.Color*(1 + lm*(t1-1));
col.a = IN.Color.a*t0.a*lm.a;
col.rgb = lerp(fogColor.rgb, col.rgb, IN.Tex0.z);
diff --git a/src/extras/shaders/obj/colourfilterIII_PS.cso b/src/extras/shaders/obj/colourfilterIII_PS.cso
deleted file mode 100644
index cc41bcec..00000000
--- a/src/extras/shaders/obj/colourfilterIII_PS.cso
+++ /dev/null
Binary files differ
diff --git a/src/extras/shaders/obj/colourfilterIII_PS.inc b/src/extras/shaders/obj/colourfilterIII_PS.inc
deleted file mode 100644
index db49de6c..00000000
--- a/src/extras/shaders/obj/colourfilterIII_PS.inc
+++ /dev/null
@@ -1,40 +0,0 @@
-static unsigned char colourfilterIII_PS_cso[] = {
- 0x00, 0x02, 0xff, 0xff, 0xfe, 0xff, 0x2b, 0x00, 0x43, 0x54, 0x41, 0x42,
- 0x1c, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff,
- 0x02, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
- 0x70, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0a, 0x00,
- 0x01, 0x00, 0x2a, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x5c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
- 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x6c, 0x75, 0x72,
- 0x63, 0x6f, 0x6c, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x00,
- 0x04, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x70, 0x73, 0x5f, 0x32, 0x5f, 0x30, 0x00, 0x4d,
- 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29,
- 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72,
- 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e,
- 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00,
- 0x51, 0x00, 0x00, 0x05, 0x00, 0x00, 0x0f, 0xa0, 0x00, 0x00, 0x80, 0x3f,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x03, 0xb0,
- 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x90, 0x00, 0x08, 0x0f, 0xa0,
- 0x42, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0xb0,
- 0x00, 0x08, 0xe4, 0xa0, 0x05, 0x00, 0x00, 0x03, 0x01, 0x00, 0x07, 0x80,
- 0x00, 0x00, 0xe4, 0x80, 0x0a, 0x00, 0xe4, 0xa0, 0x12, 0x00, 0x00, 0x04,
- 0x02, 0x00, 0x17, 0x80, 0x0a, 0x00, 0xff, 0xa0, 0x01, 0x00, 0xe4, 0x80,
- 0x00, 0x00, 0xe4, 0x80, 0x05, 0x00, 0x00, 0x03, 0x01, 0x00, 0x07, 0x80,
- 0x02, 0x00, 0xe4, 0x80, 0x0a, 0x00, 0xe4, 0xa0, 0x12, 0x00, 0x00, 0x04,
- 0x02, 0x00, 0x17, 0x80, 0x0a, 0x00, 0xff, 0xa0, 0x01, 0x00, 0xe4, 0x80,
- 0x00, 0x00, 0xe4, 0x80, 0x05, 0x00, 0x00, 0x03, 0x01, 0x00, 0x07, 0x80,
- 0x02, 0x00, 0xe4, 0x80, 0x0a, 0x00, 0xe4, 0xa0, 0x12, 0x00, 0x00, 0x04,
- 0x02, 0x00, 0x17, 0x80, 0x0a, 0x00, 0xff, 0xa0, 0x01, 0x00, 0xe4, 0x80,
- 0x00, 0x00, 0xe4, 0x80, 0x05, 0x00, 0x00, 0x03, 0x01, 0x00, 0x07, 0x80,
- 0x02, 0x00, 0xe4, 0x80, 0x0a, 0x00, 0xe4, 0xa0, 0x12, 0x00, 0x00, 0x04,
- 0x02, 0x00, 0x17, 0x80, 0x0a, 0x00, 0xff, 0xa0, 0x01, 0x00, 0xe4, 0x80,
- 0x00, 0x00, 0xe4, 0x80, 0x05, 0x00, 0x00, 0x03, 0x01, 0x00, 0x07, 0x80,
- 0x02, 0x00, 0xe4, 0x80, 0x0a, 0x00, 0xe4, 0xa0, 0x12, 0x00, 0x00, 0x04,
- 0x02, 0x00, 0x17, 0x80, 0x0a, 0x00, 0xff, 0xa0, 0x01, 0x00, 0xe4, 0x80,
- 0x00, 0x00, 0xe4, 0x80, 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x08, 0x80,
- 0x00, 0x00, 0x00, 0xa0, 0x01, 0x00, 0x00, 0x02, 0x00, 0x08, 0x0f, 0x80,
- 0x02, 0x00, 0xe4, 0x80, 0xff, 0xff, 0x00, 0x00
-};
diff --git a/src/extras/shaders/obj/colourfilterVC_PS.cso b/src/extras/shaders/obj/colourfilterVC_PS.cso
new file mode 100644
index 00000000..4b0e9f3f
--- /dev/null
+++ b/src/extras/shaders/obj/colourfilterVC_PS.cso
Binary files differ
diff --git a/src/extras/shaders/obj/colourfilterVC_PS.inc b/src/extras/shaders/obj/colourfilterVC_PS.inc
new file mode 100644
index 00000000..daa18360
--- /dev/null
+++ b/src/extras/shaders/obj/colourfilterVC_PS.inc
@@ -0,0 +1,56 @@
+static unsigned char colourfilterVC_PS_cso[] = {
+ 0x00, 0x02, 0xff, 0xff, 0xfe, 0xff, 0x2b, 0x00, 0x43, 0x54, 0x41, 0x42,
+ 0x1c, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff,
+ 0x02, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x70, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0a, 0x00,
+ 0x01, 0x00, 0x2a, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x5c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
+ 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x6c, 0x75, 0x72,
+ 0x63, 0x6f, 0x6c, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x00,
+ 0x04, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x70, 0x73, 0x5f, 0x32, 0x5f, 0x30, 0x00, 0x4d,
+ 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29,
+ 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72,
+ 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e,
+ 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00,
+ 0x51, 0x00, 0x00, 0x05, 0x00, 0x00, 0x0f, 0xa0, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x03, 0xb0,
+ 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x90, 0x00, 0x08, 0x0f, 0xa0,
+ 0x42, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0xb0,
+ 0x00, 0x08, 0xe4, 0xa0, 0x02, 0x00, 0x00, 0x03, 0x01, 0x00, 0x17, 0x80,
+ 0x0a, 0x00, 0xe4, 0xa0, 0x0a, 0x00, 0xe4, 0xa0, 0x05, 0x00, 0x00, 0x03,
+ 0x02, 0x00, 0x07, 0x80, 0x00, 0x00, 0xe4, 0x80, 0x01, 0x00, 0xe4, 0x80,
+ 0x12, 0x00, 0x00, 0x04, 0x03, 0x00, 0x07, 0x80, 0x0a, 0x00, 0xff, 0xa0,
+ 0x02, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xe4, 0x80, 0x05, 0x00, 0x00, 0x03,
+ 0x02, 0x00, 0x07, 0x80, 0x00, 0x00, 0xe4, 0x80, 0x0a, 0x00, 0xe4, 0xa0,
+ 0x04, 0x00, 0x00, 0x04, 0x02, 0x00, 0x17, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x00, 0x00, 0x00, 0xa0, 0x03, 0x00, 0xe4, 0x80, 0x05, 0x00, 0x00, 0x03,
+ 0x03, 0x00, 0x07, 0x80, 0x01, 0x00, 0xe4, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x05, 0x00, 0x00, 0x03, 0x02, 0x00, 0x07, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x0a, 0x00, 0xe4, 0xa0, 0x12, 0x00, 0x00, 0x04, 0x04, 0x00, 0x07, 0x80,
+ 0x0a, 0x00, 0xff, 0xa0, 0x03, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xe4, 0x80,
+ 0x04, 0x00, 0x00, 0x04, 0x02, 0x00, 0x17, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x00, 0x00, 0x00, 0xa0, 0x04, 0x00, 0xe4, 0x80, 0x05, 0x00, 0x00, 0x03,
+ 0x03, 0x00, 0x07, 0x80, 0x01, 0x00, 0xe4, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x05, 0x00, 0x00, 0x03, 0x02, 0x00, 0x07, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x0a, 0x00, 0xe4, 0xa0, 0x12, 0x00, 0x00, 0x04, 0x04, 0x00, 0x07, 0x80,
+ 0x0a, 0x00, 0xff, 0xa0, 0x03, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xe4, 0x80,
+ 0x04, 0x00, 0x00, 0x04, 0x02, 0x00, 0x17, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x00, 0x00, 0x00, 0xa0, 0x04, 0x00, 0xe4, 0x80, 0x05, 0x00, 0x00, 0x03,
+ 0x03, 0x00, 0x07, 0x80, 0x01, 0x00, 0xe4, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x05, 0x00, 0x00, 0x03, 0x02, 0x00, 0x07, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x0a, 0x00, 0xe4, 0xa0, 0x12, 0x00, 0x00, 0x04, 0x04, 0x00, 0x07, 0x80,
+ 0x0a, 0x00, 0xff, 0xa0, 0x03, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xe4, 0x80,
+ 0x04, 0x00, 0x00, 0x04, 0x02, 0x00, 0x17, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x00, 0x00, 0x00, 0xa0, 0x04, 0x00, 0xe4, 0x80, 0x05, 0x00, 0x00, 0x03,
+ 0x01, 0x00, 0x07, 0x80, 0x01, 0x00, 0xe4, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x05, 0x00, 0x00, 0x03, 0x02, 0x00, 0x07, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x0a, 0x00, 0xe4, 0xa0, 0x12, 0x00, 0x00, 0x04, 0x03, 0x00, 0x07, 0x80,
+ 0x0a, 0x00, 0xff, 0xa0, 0x01, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xe4, 0x80,
+ 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x17, 0x80, 0x02, 0x00, 0xe4, 0x80,
+ 0x00, 0x00, 0x00, 0xa0, 0x03, 0x00, 0xe4, 0x80, 0x01, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x08, 0x80, 0x00, 0x00, 0x55, 0xa0, 0x01, 0x00, 0x00, 0x02,
+ 0x00, 0x08, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0x80, 0xff, 0xff, 0x00, 0x00
+};
diff --git a/src/extras/shaders/obj/colourfilterIII_frag.inc b/src/extras/shaders/obj/colourfilterVC_frag.inc
index 05f92785..b61322d9 100644
--- a/src/extras/shaders/obj/colourfilterIII_frag.inc
+++ b/src/extras/shaders/obj/colourfilterVC_frag.inc
@@ -1,4 +1,4 @@
-const char *colourfilterIII_frag_src =
+const char *colourfilterVC_frag_src =
"uniform sampler2D tex0;\n"
"uniform vec4 u_blurcolor;\n"
@@ -10,10 +10,13 @@ const char *colourfilterIII_frag_src =
"main(void)\n"
"{\n"
" float a = u_blurcolor.a;\n"
+" vec4 doublec = clamp(u_blurcolor*2.0, 0.0, 1.0);\n"
" vec4 dst = texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));\n"
" vec4 prev = dst;\n"
" for(int i = 0; i < 5; i++){\n"
-" vec4 tmp = dst*(1.0-a) + prev*u_blurcolor*a;\n"
+" vec4 tmp = dst*(1.0-a) + prev*doublec*a;\n"
+" tmp += prev*u_blurcolor;\n"
+" tmp += prev*u_blurcolor;\n"
" prev = clamp(tmp, 0.0, 1.0);\n"
" }\n"
" vec4 color;\n"
diff --git a/src/extras/shaders/obj/neoWorldIII_PS.cso b/src/extras/shaders/obj/neoWorldIII_PS.cso
deleted file mode 100644
index 817888ef..00000000
--- a/src/extras/shaders/obj/neoWorldIII_PS.cso
+++ /dev/null
Binary files differ
diff --git a/src/extras/shaders/obj/neoWorldVC_PS.cso b/src/extras/shaders/obj/neoWorldVC_PS.cso
new file mode 100644
index 00000000..5e8d1696
--- /dev/null
+++ b/src/extras/shaders/obj/neoWorldVC_PS.cso
Binary files differ
diff --git a/src/extras/shaders/obj/neoWorldIII_PS.inc b/src/extras/shaders/obj/neoWorldVC_PS.inc
index a4631efb..eb8bf2ee 100644
--- a/src/extras/shaders/obj/neoWorldIII_PS.inc
+++ b/src/extras/shaders/obj/neoWorldVC_PS.inc
@@ -1,4 +1,4 @@
-static unsigned char neoWorldIII_PS_cso[] = {
+static unsigned char neoWorldVC_PS_cso[] = {
0x00, 0x02, 0xff, 0xff, 0xfe, 0xff, 0x3e, 0x00, 0x43, 0x54, 0x41, 0x42,
0x1c, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff,
0x04, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
@@ -21,7 +21,7 @@ static unsigned char neoWorldIII_PS_cso[] = {
0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72,
0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31,
0x31, 0x31, 0x00, 0xab, 0x51, 0x00, 0x00, 0x05, 0x02, 0x00, 0x0f, 0xa0,
- 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x80, 0xbf, 0x00, 0x00, 0x80, 0x3f,
+ 0x00, 0x00, 0x80, 0xbf, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80,
0x00, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80,
0x00, 0x00, 0x07, 0xb0, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80,
@@ -30,17 +30,17 @@ static unsigned char neoWorldIII_PS_cso[] = {
0x01, 0x08, 0x0f, 0xa0, 0x42, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0f, 0x80,
0x01, 0x00, 0xe4, 0xb0, 0x01, 0x08, 0xe4, 0xa0, 0x42, 0x00, 0x00, 0x03,
0x01, 0x00, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0xb0, 0x00, 0x08, 0xe4, 0xa0,
- 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0xe4, 0x80,
- 0x02, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x55, 0xa0, 0x01, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x08, 0x80, 0x02, 0x00, 0xaa, 0xa0, 0x04, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x07, 0x80, 0x01, 0x00, 0xe4, 0xa0, 0x00, 0x00, 0xe4, 0x80,
- 0x00, 0x00, 0xff, 0x80, 0x05, 0x00, 0x00, 0x03, 0x01, 0x00, 0x07, 0x80,
- 0x01, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xe4, 0x90, 0x05, 0x00, 0x00, 0x03,
- 0x00, 0x00, 0x08, 0x80, 0x01, 0x00, 0xff, 0x80, 0x00, 0x00, 0xff, 0x90,
- 0x05, 0x00, 0x00, 0x03, 0x02, 0x00, 0x08, 0x80, 0x00, 0x00, 0xff, 0x80,
- 0x01, 0x00, 0xff, 0xa0, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x07, 0x80,
- 0x01, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xe4, 0xa1,
- 0x04, 0x00, 0x00, 0x04, 0x02, 0x00, 0x07, 0x80, 0x00, 0x00, 0xaa, 0xb0,
- 0x00, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xe4, 0xa0, 0x01, 0x00, 0x00, 0x02,
- 0x00, 0x08, 0x0f, 0x80, 0x02, 0x00, 0xe4, 0x80, 0xff, 0xff, 0x00, 0x00
+ 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0xe4, 0x80,
+ 0x02, 0x00, 0x00, 0xa0, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0x80,
+ 0x02, 0x00, 0x55, 0xa0, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x07, 0x80,
+ 0x01, 0x00, 0xe4, 0xa0, 0x00, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xff, 0x80,
+ 0x05, 0x00, 0x00, 0x03, 0x01, 0x00, 0x07, 0x80, 0x01, 0x00, 0xe4, 0x80,
+ 0x00, 0x00, 0xe4, 0x90, 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08, 0x80,
+ 0x01, 0x00, 0xff, 0x80, 0x00, 0x00, 0xff, 0x90, 0x05, 0x00, 0x00, 0x03,
+ 0x02, 0x00, 0x08, 0x80, 0x00, 0x00, 0xff, 0x80, 0x01, 0x00, 0xff, 0xa0,
+ 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x07, 0x80, 0x01, 0x00, 0xe4, 0x80,
+ 0x00, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xe4, 0xa1, 0x04, 0x00, 0x00, 0x04,
+ 0x02, 0x00, 0x07, 0x80, 0x00, 0x00, 0xaa, 0xb0, 0x00, 0x00, 0xe4, 0x80,
+ 0x00, 0x00, 0xe4, 0xa0, 0x01, 0x00, 0x00, 0x02, 0x00, 0x08, 0x0f, 0x80,
+ 0x02, 0x00, 0xe4, 0x80, 0xff, 0xff, 0x00, 0x00
};
diff --git a/src/extras/shaders/obj/neoWorldIII_frag.inc b/src/extras/shaders/obj/neoWorldVC_frag.inc
index afd75f57..b4385fc7 100644
--- a/src/extras/shaders/obj/neoWorldIII_frag.inc
+++ b/src/extras/shaders/obj/neoWorldVC_frag.inc
@@ -1,4 +1,4 @@
-const char *neoWorldIII_frag_src =
+const char *neoWorldVC_frag_src =
"uniform sampler2D tex0;\n"
"uniform sampler2D tex1;\n"
@@ -15,7 +15,8 @@ const char *neoWorldIII_frag_src =
" vec4 t0 = texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));\n"
" vec4 t1 = texture(tex1, vec2(v_tex1.x, 1.0-v_tex1.y));\n"
-" vec4 color = t0*v_color*(1.0 + u_lightMap*(2.0*t1-1.0));\n"
+" vec4 color;\n"
+" color = t0*v_color*(1.0 + u_lightMap*(t1-1.0));\n"
" color.a = v_color.a*t0.a*u_lightMap.a;\n"
" color.rgb = mix(u_fogColor.rgb, color.rgb, v_fog);\n"
diff --git a/src/fakerw/fake.cpp b/src/fakerw/fake.cpp
index 6dfebb39..ee779788 100644
--- a/src/fakerw/fake.cpp
+++ b/src/fakerw/fake.cpp
@@ -299,6 +299,7 @@ RwTextureAddressMode RwTextureGetAddressingV(const RwTexture *texture);
// TODO
void _rwD3D8TexDictionaryEnableRasterFormatConversion(bool enable) { }
+
// hack for reading native textures
RwBool rwNativeTextureHackRead(RwStream *stream, RwTexture **tex, RwInt32 size)
{
diff --git a/src/math/Matrix.cpp b/src/math/Matrix.cpp
index b11e8a1c..c0d909cb 100644
--- a/src/math/Matrix.cpp
+++ b/src/math/Matrix.cpp
@@ -453,63 +453,50 @@ CMatrix &
Invert(const CMatrix &src, CMatrix &dst)
{
// TODO: VU0 code
- // GTA handles this as a raw 4x4 orthonormal matrix
- // and trashes the RW flags, let's not do that
dst.f[3][0] = dst.f[3][1] = dst.f[3][2] = 0.0f;
-#ifndef FIX_BUGS
- dst.f[3][3] = src.f[3][3];
-#endif
dst.f[0][0] = src.f[0][0];
dst.f[0][1] = src.f[1][0];
dst.f[0][2] = src.f[2][0];
-#ifndef FIX_BUGS
- dst.f[0][3] = src.f[3][0];
-#endif
+
dst.f[1][0] = src.f[0][1];
dst.f[1][1] = src.f[1][1];
dst.f[1][2] = src.f[2][1];
-#ifndef FIX_BUGS
- dst.f[1][3] = src.f[3][1];
-#endif
+
dst.f[2][0] = src.f[0][2];
dst.f[2][1] = src.f[1][2];
dst.f[2][2] = src.f[2][2];
-#ifndef FIX_BUGS
- dst.f[2][3] = src.f[3][2];
-#endif
+
dst.f[3][0] += dst.f[0][0] * src.f[3][0];
dst.f[3][1] += dst.f[0][1] * src.f[3][0];
dst.f[3][2] += dst.f[0][2] * src.f[3][0];
-#ifndef FIX_BUGS
- dst.f[3][3] += dst.f[0][3] * src.f[3][0];
-#endif
dst.f[3][0] += dst.f[1][0] * src.f[3][1];
dst.f[3][1] += dst.f[1][1] * src.f[3][1];
dst.f[3][2] += dst.f[1][2] * src.f[3][1];
-#ifndef FIX_BUGS
- dst.f[3][3] += dst.f[1][3] * src.f[3][1];
-#endif
dst.f[3][0] += dst.f[2][0] * src.f[3][2];
dst.f[3][1] += dst.f[2][1] * src.f[3][2];
dst.f[3][2] += dst.f[2][2] * src.f[3][2];
-#ifndef FIX_BUGS
- dst.f[3][3] += dst.f[2][3] * src.f[3][2];
-#endif
dst.f[3][0] = -dst.f[3][0];
dst.f[3][1] = -dst.f[3][1];
dst.f[3][2] = -dst.f[3][2];
-#ifndef FIX_BUGS
- dst.f[3][3] = src.f[3][3] - dst.f[3][3];
-#endif
return dst;
}
+void
+CMatrix::CopyToRwMatrix(RwMatrix* matrix)
+{
+ matrix->right = GetRight();
+ matrix->up = GetForward();
+ matrix->at = GetUp();
+ matrix->pos = GetPosition();
+ RwMatrixUpdate(matrix);
+}
+
CMatrix
Invert(const CMatrix &matrix)
{
diff --git a/src/math/Matrix.h b/src/math/Matrix.h
index 6404b506..0adcf32c 100644
--- a/src/math/Matrix.h
+++ b/src/math/Matrix.h
@@ -3,6 +3,21 @@
class CMatrix
{
public:
+#ifdef GTA_PS2
+ union
+ {
+ float f[4][4];
+ struct
+ {
+ float rx, ry, rz;
+ RwMatrix *m_attachment;
+ float fx, fy, fz;
+ bool m_hasRwMatrix; // are we the owner?
+ float ux, uy, uz, uw;
+ float px, py, pz, pw;
+ };
+ };
+#else
union
{
float f[4][4];
@@ -17,6 +32,7 @@ public:
RwMatrix *m_attachment;
bool m_hasRwMatrix; // are we the owner?
+#endif
CMatrix(void);
CMatrix(CMatrix const &m);
@@ -60,13 +76,17 @@ public:
void Scale(float scale)
{
for (int i = 0; i < 3; i++)
-#ifdef FIX_BUGS // BUGFIX from VC
for (int j = 0; j < 3; j++)
-#else
- for (int j = 0; j < 4; j++)
-#endif
f[i][j] *= scale;
}
+ void Scale(float sx, float sy, float sz)
+ {
+ for (int i = 0; i < 3; i++){
+ f[i][0] *= sx;
+ f[i][1] *= sy;
+ f[i][2] *= sz;
+ }
+ }
void SetRotateXOnly(float angle);
@@ -85,6 +105,9 @@ public:
void CopyOnlyMatrix(const CMatrix &other);
void SetUnity(void);
void ResetOrientation(void);
+
+ void CopyToRwMatrix(RwMatrix* matrix);
+
void SetTranslateOnly(float x, float y, float z) {
px = x;
py = y;
diff --git a/src/math/Vector.h b/src/math/Vector.h
index 776bfcfe..02128454 100644
--- a/src/math/Vector.h
+++ b/src/math/Vector.h
@@ -64,11 +64,11 @@ public:
return CVector(-x, -y, -z);
}
- const bool operator==(CVector const &right) {
+ const bool operator==(CVector const &right) const {
return x == right.x && y == right.y && z == right.z;
}
- const bool operator!=(CVector const &right) {
+ const bool operator!=(CVector const &right) const {
return x != right.x || y != right.y || z != right.z;
}
diff --git a/src/math/Vector2D.h b/src/math/Vector2D.h
index 0235dbe5..deabd0b1 100644
--- a/src/math/Vector2D.h
+++ b/src/math/Vector2D.h
@@ -13,14 +13,6 @@ public:
void Normalise(void) {
float sq = MagnitudeSqr();
- // assert(sq != 0.0f); // just be safe here
- float invsqrt = RecipSqrt(sq);
- x *= invsqrt;
- y *= invsqrt;
- }
-
- void NormaliseSafe(void) {
- float sq = MagnitudeSqr();
if(sq > 0.0f){
float invsqrt = RecipSqrt(sq);
x *= invsqrt;
@@ -61,6 +53,9 @@ public:
CVector2D operator/(float t) const {
return CVector2D(x/t, y/t);
}
+ CVector2D operator-() const {
+ return CVector2D(-x, -y);
+ }
};
inline float
diff --git a/src/modelinfo/BaseModelInfo.cpp b/src/modelinfo/BaseModelInfo.cpp
index 7137c604..709420fd 100644
--- a/src/modelinfo/BaseModelInfo.cpp
+++ b/src/modelinfo/BaseModelInfo.cpp
@@ -4,12 +4,13 @@
#include "TxdStore.h"
#include "2dEffect.h"
#include "BaseModelInfo.h"
+#include "ModelInfo.h"
#include "ColModel.h"
CBaseModelInfo::CBaseModelInfo(ModelInfoType type)
{
m_colModel = nil;
- m_twodEffects = nil;
+ m_2dEffectsID = -1;
m_objectId = -1;
m_refCount = 0;
m_txdSlot = -1;
@@ -23,9 +24,10 @@ CBaseModelInfo::Shutdown(void)
{
DeleteCollisionModel();
DeleteRwObject();
- m_twodEffects = nil;
+ m_2dEffectsID = -1;
m_num2dEffects = 0;
m_txdSlot = -1;
+ m_objectId = -1;
}
void
@@ -76,17 +78,17 @@ CBaseModelInfo::RemoveTexDictionaryRef(void)
void
CBaseModelInfo::Init2dEffects(void)
{
- m_twodEffects = nil;
+ m_2dEffectsID = -1;
m_num2dEffects = 0;
}
void
CBaseModelInfo::Add2dEffect(C2dEffect *fx)
{
- if(m_twodEffects)
+ if(m_2dEffectsID >= 0)
m_num2dEffects++;
else{
- m_twodEffects = fx;
+ m_2dEffectsID = CModelInfo::Get2dEffectStore().GetIndex(fx);
m_num2dEffects = 1;
}
}
@@ -94,8 +96,8 @@ CBaseModelInfo::Add2dEffect(C2dEffect *fx)
C2dEffect*
CBaseModelInfo::Get2dEffect(int n)
{
- if(m_twodEffects)
- return &m_twodEffects[n];
+ if(m_2dEffectsID >= 0)
+ return CModelInfo::Get2dEffectStore().GetItem(m_2dEffectsID+n);
else
return nil;
}
diff --git a/src/modelinfo/BaseModelInfo.h b/src/modelinfo/BaseModelInfo.h
index f46cea84..2d1dc8ac 100644
--- a/src/modelinfo/BaseModelInfo.h
+++ b/src/modelinfo/BaseModelInfo.h
@@ -2,18 +2,20 @@
struct CColModel;
-#define MAX_MODEL_NAME (24)
+#define MAX_MODEL_NAME (21)
enum ModelInfoType
{
- MITYPE_NA = 0,
- MITYPE_SIMPLE = 1,
- MITYPE_MLO = 2,
- MITYPE_TIME = 3,
- MITYPE_CLUMP = 4,
- MITYPE_VEHICLE = 5,
- MITYPE_PED = 6,
- MITYPE_XTRACOMPS = 7,
+ MITYPE_NA,
+ MITYPE_SIMPLE,
+ MITYPE_MLO, // unused but still in enum
+ MITYPE_TIME,
+ MITYPE_WEAPON,
+ MITYPE_CLUMP,
+ MITYPE_VEHICLE,
+ MITYPE_PED,
+ MITYPE_XTRACOMPS, // unused but still in enum
+ MITYPE_HAND // xbox and mobile
};
class C2dEffect;
@@ -22,22 +24,14 @@ class CBaseModelInfo
{
protected:
char m_name[MAX_MODEL_NAME];
+ uint8 m_type;
+ uint8 m_num2dEffects;
+ bool m_bOwnsColModel;
CColModel *m_colModel;
- C2dEffect *m_twodEffects;
+ int16 m_2dEffectsID;
int16 m_objectId;
uint16 m_refCount;
int16 m_txdSlot;
- uint8 m_type;
- uint8 m_num2dEffects;
- bool m_bOwnsColModel;
-#ifdef EXTRA_MODEL_FLAGS
-public:
- // from mobile
- bool m_bIsDoubleSided;
- bool m_bIsTree;
- bool m_bCanBeIgnored; // for low-end devices
- bool RenderDoubleSided(void) { return m_bIsDoubleSided || m_bIsTree; }
-#endif
public:
CBaseModelInfo(ModelInfoType type);
@@ -47,13 +41,15 @@ public:
virtual RwObject *CreateInstance(void) = 0;
virtual RwObject *CreateInstance(RwMatrix *) = 0;
virtual RwObject *GetRwObject(void) = 0;
+ virtual void SetAnimFile(const char *file) {}
+ virtual void ConvertAnimFileIndex(void) {}
+ virtual int GetAnimFileIndex(void) { return -1; }
// one day it becomes virtual
uint8 GetModelType() const { return m_type; }
- bool IsSimple(void) { return m_type == MITYPE_SIMPLE || m_type == MITYPE_TIME; }
- bool IsClump(void) { return m_type == MITYPE_CLUMP || m_type == MITYPE_PED || m_type == MITYPE_VEHICLE ||
- m_type == MITYPE_MLO || m_type == MITYPE_XTRACOMPS; // unused but what the heck
- }
+ bool IsBuilding(void) { return m_type == MITYPE_SIMPLE || m_type == MITYPE_TIME; }
+ bool IsSimple(void) { return m_type == MITYPE_SIMPLE || m_type == MITYPE_TIME || m_type == MITYPE_WEAPON; }
+ bool IsClump(void) { return m_type == MITYPE_CLUMP || m_type == MITYPE_PED || m_type == MITYPE_VEHICLE; }
char *GetModelName(void) { return m_name; }
void SetModelName(const char *name) { strncpy(m_name, name, MAX_MODEL_NAME); }
void SetColModel(CColModel *col, bool owns = false){
@@ -76,5 +72,3 @@ public:
uint8 GetNum2dEffects() const { return m_num2dEffects; }
uint16 GetNumRefs() const { return m_refCount; }
};
-
-VALIDATE_SIZE(CBaseModelInfo, 0x30);
diff --git a/src/modelinfo/ClumpModelInfo.cpp b/src/modelinfo/ClumpModelInfo.cpp
index 44a62afb..ba18bfa7 100644
--- a/src/modelinfo/ClumpModelInfo.cpp
+++ b/src/modelinfo/ClumpModelInfo.cpp
@@ -5,7 +5,7 @@
#include "NodeName.h"
#include "VisibilityPlugins.h"
#include "ModelInfo.h"
-#include "ModelIndices.h"
+#include "AnimManager.h"
void
CClumpModelInfo::DeleteRwObject(void)
@@ -14,17 +14,17 @@ CClumpModelInfo::DeleteRwObject(void)
RpClumpDestroy(m_clump);
m_clump = nil;
RemoveTexDictionaryRef();
+ if(GetAnimFileIndex() != -1)
+ CAnimManager::RemoveAnimBlockRef(GetAnimFileIndex());
}
}
-#ifdef PED_SKIN
static RpAtomic*
SetHierarchyForSkinAtomic(RpAtomic *atomic, void *data)
{
RpSkinAtomicSetHAnimHierarchy(atomic, (RpHAnimHierarchy*)data);
return nil;
}
-#endif
RwObject*
CClumpModelInfo::CreateInstance(void)
@@ -32,24 +32,17 @@ CClumpModelInfo::CreateInstance(void)
if(m_clump == nil)
return nil;
RpClump *clone = RpClumpClone(m_clump);
-#ifdef PED_SKIN
if(IsClumpSkinned(clone)){
RpHAnimHierarchy *hier;
RpHAnimAnimation *anim;
hier = GetAnimHierarchyFromClump(clone);
assert(hier);
- // This seems dangerous as only the first atomic will get a hierarchy
- // can we guarantee this if hands and head are also in the clump?
RpClumpForAllAtomics(clone, SetHierarchyForSkinAtomic, hier);
anim = HAnimAnimationCreateForHierarchy(hier);
RpHAnimHierarchySetCurrentAnim(hier, anim);
RpHAnimHierarchySetFlags(hier, (RpHAnimHierarchyFlag)(rpHANIMHIERARCHYUPDATEMODELLINGMATRICES|rpHANIMHIERARCHYUPDATELTMS));
- // the rest is xbox only:
- // RpSkinGetNumBones(RpSkinGeometryGetSkin(RpAtomicGetGeometry(IsClumpSkinned(clone))));
- RpHAnimHierarchyUpdateMatrices(hier);
}
-#endif
return (RwObject*)clone;
}
@@ -77,27 +70,18 @@ CClumpModelInfo::SetClump(RpClump *clump)
m_clump = clump;
CVisibilityPlugins::SetClumpModelInfo(m_clump, this);
AddTexDictionaryRef();
- RpClumpForAllAtomics(clump, SetAtomicRendererCB, nil);
-
-#ifdef PED_SKIN
+ if(GetAnimFileIndex() != -1)
+ CAnimManager::AddAnimBlockRef(GetAnimFileIndex());
if(IsClumpSkinned(clump)){
int i;
RpHAnimHierarchy *hier;
RpAtomic *skinAtomic;
RpSkin *skin;
- // mobile:
-// hier = nil;
-// RwFrameForAllChildren(RpClumpGetFrame(clump), GetHierarchyFromChildNodesCB, &hier);
-// assert(hier);
-// RpClumpForAllAtomics(clump, SetHierarchyForSkinAtomic, hier);
-// skinAtomic = GetFirstAtomic(clump);
-
- // xbox:
hier = GetAnimHierarchyFromClump(clump);
assert(hier);
- RpSkinAtomicSetHAnimHierarchy(IsClumpSkinned(clump), hier);
- skinAtomic = IsClumpSkinned(clump);
+ RpClumpForAllAtomics(clump, SetHierarchyForSkinAtomic, hier);
+ skinAtomic = GetFirstAtomic(clump);
assert(skinAtomic);
skin = RpSkinGeometryGetSkin(RpAtomicGetGeometry(skinAtomic));
@@ -112,17 +96,27 @@ CClumpModelInfo::SetClump(RpClump *clump)
}
RpHAnimHierarchySetFlags(hier, (RpHAnimHierarchyFlag)(rpHANIMHIERARCHYUPDATEMODELLINGMATRICES|rpHANIMHIERARCHYUPDATELTMS));
}
- if(strcmp(GetModelName(), "playerh") == 0){
- // playerh is incompatible with the xbox player skin
- // so check if player model is skinned and only apply skin to head if it isn't
- CPedModelInfo *body = (CPedModelInfo*)CModelInfo::GetModelInfo(MI_PLAYER);
- if(!(body->m_clump && IsClumpSkinned(body->m_clump)))
- RpClumpForAllAtomics(clump, SetAtomicRendererCB, (void*)CVisibilityPlugins::RenderPlayerCB);
+}
+
+void
+CClumpModelInfo::SetAnimFile(const char *file)
+{
+ if(strcasecmp(file, "null") == 0)
+ return;
+
+ m_animFileName = new char[strlen(file)+1];
+ strcpy(m_animFileName, file);
+}
+
+void
+CClumpModelInfo::ConvertAnimFileIndex(void)
+{
+ if(m_animFileIndex != -1){
+ // we have a string pointer in that union
+ int32 index = CAnimManager::GetAnimationBlockIndex(m_animFileName);
+ delete[] m_animFileName;
+ m_animFileIndex = index;
}
-#else
- if(strcmp(GetModelName(), "playerh") == 0)
- RpClumpForAllAtomics(clump, SetAtomicRendererCB, (void*)CVisibilityPlugins::RenderPlayerCB);
-#endif
}
void
@@ -154,6 +148,7 @@ CClumpModelInfo::FindFrameFromIdCB(RwFrame *frame, void *data)
return assoc->frame ? nil : frame;
}
+// unused
RwFrame*
CClumpModelInfo::FindFrameFromNameCB(RwFrame *frame, void *data)
{
diff --git a/src/modelinfo/ClumpModelInfo.h b/src/modelinfo/ClumpModelInfo.h
index 58b6de11..0113d340 100644
--- a/src/modelinfo/ClumpModelInfo.h
+++ b/src/modelinfo/ClumpModelInfo.h
@@ -30,9 +30,13 @@ class CClumpModelInfo : public CBaseModelInfo
{
public:
RpClump *m_clump;
+ union {
+ int32 m_animFileIndex;
+ char *m_animFileName;
+ };
- CClumpModelInfo(void) : CBaseModelInfo(MITYPE_CLUMP) {}
- CClumpModelInfo(ModelInfoType id) : CBaseModelInfo(id) {}
+ CClumpModelInfo(void) : CBaseModelInfo(MITYPE_CLUMP) { m_animFileIndex = -1; }
+ CClumpModelInfo(ModelInfoType id) : CBaseModelInfo(id) { m_animFileIndex = -1; }
~CClumpModelInfo() {}
void DeleteRwObject(void);
RwObject *CreateInstance(void);
@@ -40,6 +44,9 @@ public:
RwObject *GetRwObject(void) { return (RwObject*)m_clump; }
virtual void SetClump(RpClump *);
+ virtual void SetAnimFile(const char *file);
+ virtual void ConvertAnimFileIndex(void);
+ virtual int GetAnimFileIndex(void) { return m_animFileIndex; }
static RpAtomic *SetAtomicRendererCB(RpAtomic *atomic, void *data);
void SetFrameIds(RwObjectNameIdAssocation *assocs);
@@ -50,5 +57,4 @@ public:
static RwFrame *FillFrameArrayCB(RwFrame *frame, void *data);
static RwFrame *GetFrameFromId(RpClump *clump, int32 id);
};
-
-VALIDATE_SIZE(CClumpModelInfo, 0x34);
+//static_assert(sizeof(CClumpModelInfo) == 0x34, "CClumpModelInfo: error");
diff --git a/src/modelinfo/MloModelInfo.cpp b/src/modelinfo/MloModelInfo.cpp
index 7535e6c5..fa12b900 100644
--- a/src/modelinfo/MloModelInfo.cpp
+++ b/src/modelinfo/MloModelInfo.cpp
@@ -3,6 +3,7 @@
#include "VisibilityPlugins.h"
#include "ModelInfo.h"
+/*
void
CMloModelInfo::ConstructClump()
{
@@ -36,4 +37,5 @@ CMloModelInfo::ConstructClump()
RpClumpDestroy(m_clump);
m_clump = nil;
}
-} \ No newline at end of file
+}
+*/ \ No newline at end of file
diff --git a/src/modelinfo/ModelIndices.h b/src/modelinfo/ModelIndices.h
index c0f01929..836c4092 100644
--- a/src/modelinfo/ModelIndices.h
+++ b/src/modelinfo/ModelIndices.h
@@ -1,13 +1,9 @@
#pragma once
+#include "ModelInfo.h"
+
#define MODELINDICES \
X("fire_hydrant", MI_FIRE_HYDRANT) \
- X("bagelstnd02", MI_BAGELSTAND2) \
- X("fish01", MI_FISHSTALL01) \
- X("fishstall02", MI_FISHSTALL02) \
- X("fishstall03", MI_FISHSTALL03) \
- X("fishstall04", MI_FISHSTALL04) \
- X("taxisign", MI_TAXISIGN) \
X("phonesign", MI_PHONESIGN) \
X("noparkingsign1", MI_NOPARKINGSIGN1) \
X("bussign1", MI_BUSSIGN1) \
@@ -20,97 +16,62 @@
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("rd_Road2A10", MI_ROADSFORROADBLOCKSSTART) \
- X("rd_Road1A30", MI_ROADSFORROADBLOCKSEND) \
- X("veg_tree1", MI_TREE1) \
+ X("Streetlamp1", MI_STREETLAMP1) \
+ X("Streetlamp2", MI_STREETLAMP2) \
X("veg_tree3", MI_TREE2) \
X("veg_treea1", MI_TREE3) \
- X("veg_treenew01", MI_TREE4) \
- X("veg_treenew05", MI_TREE5) \
X("veg_treeb1", MI_TREE6) \
- X("veg_treenew10", MI_TREE7) \
X("veg_treea3", MI_TREE8) \
- X("veg_treenew09", MI_TREE9) \
- X("veg_treenew08", MI_TREE10) \
- X("veg_treenew03", MI_TREE11) \
- X("veg_treenew16", MI_TREE12) \
- X("veg_treenew17", MI_TREE13) \
- X("veg_treenew06", MI_TREE14) \
- X("doc_crane_cab", MODELID_CRANE_1) \
- X("cranetopb", MODELID_CRANE_2) \
- X("cranetopa", MODELID_CRANE_3) \
+ X("doc_crane_cab0", 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("oddjgaragdoor", MI_GARAGEDOOR1) \
- X("bombdoor", MI_GARAGEDOOR2) \
- X("door_bombshop", MI_GARAGEDOOR3) \
- X("vheistlocdoor", MI_GARAGEDOOR4) \
- X("door2_garage", MI_GARAGEDOOR5) \
- X("ind_slidedoor", MI_GARAGEDOOR6) \
- X("bankjobdoor", MI_GARAGEDOOR7) \
- X("door_jmsgrage", MI_GARAGEDOOR9) \
- X("jamesgrge_kb", MI_GARAGEDOOR10) \
- X("door_sfehousegrge", MI_GARAGEDOOR11) \
- X("shedgaragedoor", MI_GARAGEDOOR12) \
- X("door4_garage", MI_GARAGEDOOR13) \
- X("door_col_compnd_01", MI_GARAGEDOOR14) \
- X("door_col_compnd_02", MI_GARAGEDOOR15) \
- X("door_col_compnd_03", MI_GARAGEDOOR16) \
- X("door_col_compnd_04", MI_GARAGEDOOR17) \
- X("door_col_compnd_05", MI_GARAGEDOOR18) \
- X("impex_door", MI_GARAGEDOOR19) \
- X("SalvGarage", MI_GARAGEDOOR20) \
- X("door3_garage", MI_GARAGEDOOR21) \
- X("leveldoor2", MI_GARAGEDOOR22) \
- X("double_garage_dr", MI_GARAGEDOOR23) \
- X("amcogaragedoor", MI_GARAGEDOOR24) \
- X("towergaragedoor1", MI_GARAGEDOOR25) \
- X("towergaragedoor2", MI_GARAGEDOOR26) \
- X("towergaragedoor3", MI_GARAGEDOOR27) \
- X("plysve_gragedoor", MI_GARAGEDOOR28) \
- X("impexpsubgrgdoor", MI_GARAGEDOOR29) \
- X("Sub_sprayshopdoor", MI_GARAGEDOOR30) \
- X("ind_plyrwoor", MI_GARAGEDOOR31) \
- X("8ballsuburbandoor", MI_GARAGEDOOR32) \
+ 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("crushercrush", MI_CRUSHERBODY) \
- X("crushertop", MI_CRUSHERLID) \
- X("donkeymag", MI_DONKEYMAG) \
- X("bullion", MI_BULLION) \
- X("floatpackge1", MI_FLOATPACKAGE1) \
X("briefcase", MI_BRIEFCASE) \
- X("chinabanner1", MI_CHINABANNER1) \
- X("chinabanner2", MI_CHINABANNER2) \
- X("chinabanner3", MI_CHINABANNER3) \
- X("chinabanner4", MI_CHINABANNER4) \
- X("iten_chinatown5", MI_CHINABANNER5) \
- X("iten_chinatown7", MI_CHINABANNER6) \
- X("iten_chinatown3", MI_CHINABANNER7) \
- X("iten_chinatown2", MI_CHINABANNER8) \
- X("iten_chinatown4", MI_CHINABANNER9) \
- X("iten_washline01", MI_CHINABANNER10) \
- X("iten_washline02", MI_CHINABANNER11) \
- X("iten_washline03", MI_CHINABANNER12) \
- X("chinalanterns", MI_CHINALANTERN) \
- X("glassfx1", MI_GLASS1) \
- X("glassfx2", MI_GLASS2) \
- X("glassfx3", MI_GLASS3) \
- X("glassfx4", MI_GLASS4) \
- X("glassfx55", MI_GLASS5) \
- X("glassfxsub1", MI_GLASS6) \
- X("glassfxsub2", MI_GLASS7) \
+ X("wglasssmash", MI_GLASS1) \
X("glassfx_composh", MI_GLASS8) \
- X("bridge_liftsec", MI_BRIDGELIFT) \
- X("bridge_liftweight", MI_BRIDGEWEIGHT) \
- X("subbridge_lift", MI_BRIDGEROADSEGMENT) \
X("barrel4", MI_EXPLODINGBARREL) \
- X("flagsitaly", MI_ITALYBANNER1) \
X("adrenaline", MI_PICKUP_ADRENALINE) \
X("bodyarmour", MI_PICKUP_BODYARMOUR) \
X("info", MI_PICKUP_INFO) \
@@ -119,44 +80,65 @@
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("magnet", MI_MAGNET) \
- X("streetlamp1", MI_STREETLAMP1) \
- X("streetlamp2", MI_STREETLAMP2) \
- X("railtrax_lo4b", MI_RAILTRACKS) \
X("bar_barrier10", MI_FENCE) \
X("bar_barrier12", MI_FENCE2) \
X("petrolpump", MI_PETROLPUMP) \
- X("bodycast", MI_BODYCAST) \
- X("backdoor", MI_BACKDOOR) \
- X("coffee", MI_COFFEE) \
+ X("washgaspump", MI_PETROLPUMP2) \
X("bouy", MI_BUOY) \
X("parktable1", MI_PARKTABLE) \
- X("sbwy_tunl_start", MI_SUBWAY1) \
- X("sbwy_tunl_bit", MI_SUBWAY2) \
- X("sbwy_tunl_bend", MI_SUBWAY3) \
- X("sbwy_tunl_cstm6", MI_SUBWAY4) \
- X("sbwy_tunl_cstm7", MI_SUBWAY5) \
- X("sbwy_tunl_cstm8", MI_SUBWAY6) \
- X("sbwy_tunl_cstm10", MI_SUBWAY7) \
- X("sbwy_tunl_cstm9", MI_SUBWAY8) \
- X("sbwy_tunl_cstm11", MI_SUBWAY9) \
- X("sbwy_tunl_cstm1", MI_SUBWAY10) \
- X("sbwy_tunl_cstm2", MI_SUBWAY11) \
- X("sbwy_tunl_cstm4", MI_SUBWAY12) \
- X("sbwy_tunl_cstm3", MI_SUBWAY13) \
- X("sbwy_tunl_cstm5", MI_SUBWAY14) \
- X("subplatform_n2", MI_SUBWAY15) \
- X("suby_tunl_start", MI_SUBWAY16) \
- X("sbwy_tunl_start2", MI_SUBWAY17) \
- X("indy_tunl_start", MI_SUBWAY18) \
- X("indsubway03", MI_SUBPLATFORM_IND) \
- X("comerside_subway", MI_SUBPLATFORM_COMS) \
- X("subplatform", MI_SUBPLATFORM_COMS2) \
- X("subplatform_n", MI_SUBPLATFORM_COMN) \
- X("Otherside_subway", MI_SUBPLATFORM_SUB) \
- X("subplatform_sub", MI_SUBPLATFORM_SUB2) \
- X("files", MI_FILES)
+ 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) extern int16 var;
MODELINDICES
@@ -174,88 +156,131 @@ enum
MI_MEDIC,
MI_FIREMAN,
MI_MALE01,
- 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_HFYST = 9,
+ MI_HFOST,
+ MI_HMYST,
+ MI_HMOST,
+ MI_HFYRI,
+ MI_HFORI,
+ MI_HMYRI,
+ MI_HMORI,
+ MI_HFYBE,
+ MI_HFOBE,
+ MI_HMYBE,
+ MI_HMOBE,
+ MI_HFYBU,
+ MI_HFYMD,
+ MI_HFYCG,
+ MI_HFYPR,
+ MI_HFOTR,
+ MI_HMOTR,
+ MI_HMYAP,
+ MI_HMOCA,
+ MI_TAXI_D = MI_HMOCA,
+ MI_BMODK,
+ MI_BMYKR,
+ MI_BFYST,
+ MI_BFOST,
+ MI_BMYST,
+ MI_BMOST,
+ MI_BFYRI,
+ MI_BFORI,
+ MI_BMYRI,
+ MI_BFYBE,
+ MI_BMYBE,
+ MI_BFOBE,
+ MI_BMOBE,
+ MI_BMYBU,
+ MI_BFYPR,
+ MI_BFOTR,
+ MI_BMOTR,
+ MI_BMYPI,
+ MI_BMYBB,
+ MI_WMYCR,
+ MI_WFYST,
+ MI_WFOST,
+ MI_WMYST,
+ MI_WMOST,
+ MI_WFYRI,
+ MI_WFORI,
+ MI_WMYRI,
+ MI_WMORI,
+ MI_WFYBE,
+ MI_WMYBE,
+ MI_WFOBE,
+ MI_WMOBE,
+ MI_WMYCW,
+ MI_WMYGO,
+ MI_WFOGO,
+ MI_WMOGO,
+ MI_WFYLG,
+ MI_WMYLG,
+ MI_WFYBU,
+ MI_WMYBU,
+ MI_WMOBU,
+ MI_WFYPR,
+ MI_WFOTR,
+ MI_WMOTR,
+ MI_WMYPI,
+ MI_WMOCA,
+ MI_WFYJG,
+ MI_WMYJG,
+ MI_WFYSK,
+ MI_WMYSK,
+ MI_WFYSH,
+ MI_WFOSH,
+ MI_JFOTO,
+ MI_JMOTO,
+
+ 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,
+ MI_VICE5,
+ MI_VICE6,
+ MI_VICE7,
+ MI_VICE8,
+ MI_WFYG1,
+ MI_WFYG2,// = 106, // last regular ped
+ // three more peds possible
+ MI_SPECIAL01 = 109,
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_SPECIAL05,
+ MI_SPECIAL06,
+ MI_SPECIAL07,
+ MI_SPECIAL08,
+ MI_SPECIAL09,
+ MI_SPECIAL10,
+ MI_SPECIAL11,
+ MI_SPECIAL12,
+ MI_SPECIAL13,
+ MI_SPECIAL14,
+ MI_SPECIAL15,
+ MI_SPECIAL16,
+ MI_SPECIAL17,
+ MI_SPECIAL18,
+ MI_SPECIAL19,
+ MI_SPECIAL20,
+ MI_SPECIAL21,// = 129,
- MI_LAST_PED = 89,
+ MI_LAST_PED = MI_SPECIAL21,
MI_FIRST_VEHICLE,
MI_LANDSTAL = MI_FIRST_VEHICLE,
@@ -264,13 +289,13 @@ enum
MI_LINERUN,
MI_PEREN,
MI_SENTINEL,
- MI_PATRIOT,
+ MI_RIO,
MI_FIRETRUCK,
MI_TRASH,
MI_STRETCH,
MI_MANANA,
MI_INFERNUS,
- MI_BLISTA,
+ MI_VOODOO,
MI_PONY,
MI_MULE,
MI_CHEETAH,
@@ -279,11 +304,11 @@ enum
MI_MOONBEAM,
MI_ESPERANT,
MI_TAXI,
- MI_KURUMA,
+ MI_WASHING,
MI_BOBCAT,
MI_MRWHOOP,
MI_BFINJECT,
- MI_CORPSE,
+ MI_HUNTER,
MI_POLICE,
MI_ENFORCER,
MI_SECURICA,
@@ -292,77 +317,159 @@ enum
MI_BUS,
MI_RHINO,
MI_BARRACKS,
- MI_TRAIN,
+ MI_CUBAN,
MI_CHOPPER,
- MI_DODO,
+ MI_ANGEL,
MI_COACH,
MI_CABBIE,
MI_STALLION,
MI_RUMPO,
MI_RCBANDIT,
- MI_BELLYUP,
- MI_MRWONGS,
- MI_MAFIA,
- MI_YARDIE,
- MI_YAKUZA,
- MI_DIABLOS,
- MI_COLUMB ,
- MI_HOODS,
+ MI_ROMERO,
+ MI_PACKER,
+ MI_SENTXS,
+ MI_ADMIRAL,
+ MI_SQUALO,
+ MI_SEASPAR,
+ MI_PIZZABOY,
+ MI_GANGBUR,
MI_AIRTRAIN,
MI_DEADDODO,
MI_SPEEDER,
MI_REEFER,
- MI_PANLANT,
+ MI_TROPIC,
MI_FLATBED,
MI_YANKEE,
- MI_ESCAPE,
- MI_BORGNINE,
- MI_TOYZ,
- MI_GHOST,
-
- // leftovers on PC
- MI_MIAMI_RCBARON = 154,
- MI_MIAMI_RCRAIDER = 155,
- MI_MIAMI_SPARROW = 159,
-
- MI_GRENADE = 170,
- MI_AK47,
+ MI_CADDY,
+ MI_ZEBRA,
+ MI_TOPFUN,
+ MI_SKIMMER,
+ MI_PCJ600,
+ MI_FAGGIO,
+ MI_FREEWAY,
+ MI_RCBARON,
+ MI_RCRAIDER,
+ MI_GLENDALE,
+ MI_OCEANIC,
+ MI_SANCHEZ,
+ MI_SPARROW,
+ MI_PATRIOT,
+ MI_LOVEFIST,
+ MI_COASTG,
+ MI_DINGHY,
+ MI_HERMES,
+ MI_SABRE,
+ MI_SABRETUR,
+ MI_PHEONIX,
+ MI_WALTON,
+ MI_REGINA,
+ MI_COMET,
+ MI_DELUXO,
+ MI_BURRITO,
+ MI_SPAND,
+ MI_MARQUIS,
+ MI_BAGGAGE,
+ MI_KAUFMAN,
+ MI_MAVERICK,
+ MI_VCNMAV,
+ MI_RANCHER,
+ MI_FBIRANCH,
+ MI_VIRGO,
+ MI_GREENWOO,
+ MI_JETMAX,
+ MI_HOTRING,
+ MI_SANDKING,
+ MI_BLISTAC,
+ MI_POLMAV,
+ MI_BOXVILLE,
+ MI_BENSON,
+ MI_MESA,
+ MI_RCGOBLIN,
+ MI_HOTRINA,
+ MI_HOTRINB,
+ MI_BLOODRA,
+ MI_BLOODRB,
+ MI_VICECHEE,
+
+ // HACK
+ MI_TRAIN = -1,
+ MI_DODO = -2,
+
+ MI_LAST_VEHICLE = MI_VICECHEE,
+
+ MI_WHEEL_RIM,
+ MI_WHEEL_OFFROAD,
+ MI_WHEEL_TRUCK,
+
+ MI_CAR_DOOR,// = 240,
+ MI_CAR_BUMPER,
+ MI_CAR_PANEL,
+ MI_CAR_BONNET,
+ MI_CAR_BOOT,
+ MI_CAR_WHEEL,
+ MI_BODYPARTA,
+ MI_BODYPARTB,
+
+ MI_WHEEL_SPORT = 250,
+ MI_WHEEL_SALOON,
+ MI_WHEEL_LIGHTVAN,
+ MI_WHEEL_CLASSIC,
+ MI_WHEEL_ALLOY,
+ MI_WHEEL_LIGHTTRUCK,
+ MI_WHEEL_SMALLCAR,
+
+ MI_AIRTRAIN_VLO, // = 257,
+ MI_MOBILE,
+
+ MI_BRASS_KNUCKLES, // 259
+ MI_SCREWDRIVER,
+ MI_GOLFCLUB,
+ MI_NIGHTSTICK,
+ MI_KNIFE,
MI_BASEBALL_BAT,
- MI_COLT,
+ MI_HAMMER,
+ MI_MEAT_CLEAVER,
+ MI_MACHETE,
+ MI_KATANA,
+ MI_CHAINSAW,
+ MI_GRENADE,
+ MI_TEARGAS,
MI_MOLOTOV,
- MI_ROCKETLAUNCHER,
+ MI_MISSILE,
+ MI_COLT45,
+ MI_PYTHON,
+ MI_RUGER,
MI_SHOTGUN,
- MI_SNIPER,
+ MI_SPAS12_SHOTGUN,
+ MI_STUBBY_SHOTGUN,
+ MI_M4,
+ MI_TEC9,
MI_UZI,
- MI_MISSILE,
- MI_M16,
+ 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 = 185,
+ MI_CUTOBJ01,// = 295,
MI_CUTOBJ02,
MI_CUTOBJ03,
MI_CUTOBJ04,
MI_CUTOBJ05,
- MI_CAR_DOOR = 190,
- MI_CAR_BUMPER,
- MI_CAR_PANEL,
- MI_CAR_BONNET,
- MI_CAR_BOOT,
- MI_CAR_WHEEL,
- MI_BODYPARTA,
- MI_BODYPARTB,
-
- MI_AIRTRAIN_VLO = 198,
- MI_LOPOLYGUY,
- NUM_DEFAULT_MODELS
+ NUM_DEFAULT_MODELS,// = 300
};
enum{
- NUM_OF_SPECIAL_CHARS = 4,
+ NUM_OF_SPECIAL_CHARS = 21,
NUM_OF_CUTSCENE_OBJECTS = 5
};
@@ -373,18 +480,21 @@ void TestModelIndices(void);
inline bool
IsGlass(int16 id)
{
- return id == MI_GLASS1 ||
- id == MI_GLASS2 ||
- id == MI_GLASS3 ||
- id == MI_GLASS4 ||
- id == MI_GLASS5 ||
- id == MI_GLASS6 ||
- id == MI_GLASS7 ||
- id == MI_GLASS8;
+ CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(id);
+ return mi->IsBuilding() && (mi->m_isCodeGlass || mi->m_isArtistGlass);
+}
+
+inline bool
+IsTrafficLight(int16 id)
+{
+ return id == MI_TRAFFICLIGHTS ||
+ id == MI_TRAFFICLIGHTS_VERTICAL ||
+ id == MI_TRAFFICLIGHTS_MIAMI ||
+ id == MI_TRAFFICLIGHTS_TWOVERTICAL;
}
inline bool
-IsStreetLight(int16 id)
+IsLightWithoutShift(int16 id)
{
return id == MI_TRAFFICLIGHTS ||
id == MI_SINGLESTREETLIGHTS1 ||
@@ -394,86 +504,87 @@ IsStreetLight(int16 id)
}
inline bool
-IsBodyPart(int16 id)
+IsLightWithPreRenderEffects(int16 id)
{
- return id == MI_BODYPARTA || id == MI_BODYPARTB;
+ return IsTrafficLight(id) ||
+ id == MI_SINGLESTREETLIGHTS1 ||
+ id == MI_SINGLESTREETLIGHTS2 ||
+ id == MI_SINGLESTREETLIGHTS3 ||
+ id == MI_DOUBLESTREETLIGHTS;
}
-// This is bad and should perhaps not be used
inline bool
-IsBoatModel(int16 id)
+IsLightThatNeedsRepositioning(int16 id)
{
- return id == MI_PREDATOR ||
- id == MI_REEFER ||
- id == MI_SPEEDER ||
- id == MI_GHOST;
+ 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
-IsPedModel(int16 id)
+IsLightObject(int16 id)
{
- return id >= MI_PLAYER && id <= MI_LAST_PED;
+ 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
-IsTreeModel(int16 id)
+IsLampPost(int16 id)
{
- return id == MI_TREE1 ||
- 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;
+ return id == MI_SINGLESTREETLIGHTS1 ||
+ id == MI_SINGLESTREETLIGHTS2 ||
+ id == MI_SINGLESTREETLIGHTS3 ||
+ id == MI_BOLLARDLIGHT ||
+ id == MI_MLAMPPOST ||
+ id == MI_STREETLAMP1 ||
+ id == MI_STREETLAMP2 ||
+ id == MI_TELPOLE02 ||
+ id == MI_TRAFFICLIGHTS_MIAMI ||
+ id == MI_TRAFFICLIGHTS_TWOVERTICAL;
}
inline bool
-IsBannerModel(int16 id)
+IsBodyPart(int16 id)
+{
+ return id == MI_BODYPARTA || id == MI_BODYPARTB;
+}
+
+inline bool
+IsPedModel(int16 id)
+{
+ return id >= MI_PLAYER && id <= MI_LAST_PED;
+}
+inline bool
+IsPalmTreeModel(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;
+ 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
-IsPickupModel(int16 id)
+IsTreeModel(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;
+ return id == MI_TREE2 ||
+ id == MI_TREE3 ||
+ id == MI_TREE6 ||
+ id == MI_TREE8 ||
+ IsPalmTreeModel(id);
}
inline bool
@@ -498,7 +609,8 @@ inline bool
IsExplosiveThingModel(int16 id)
{
return id == MI_EXPLODINGBARREL ||
- id == MI_PETROLPUMP;
+ id == MI_PETROLPUMP ||
+ id == MI_PETROLPUMP2;
}
inline bool
@@ -506,4 +618,4 @@ IsFence(int16 id)
{
return id == MI_FENCE ||
id == MI_FENCE2;
-} \ No newline at end of file
+}
diff --git a/src/modelinfo/ModelInfo.cpp b/src/modelinfo/ModelInfo.cpp
index 7aa5fc8b..41515e20 100644
--- a/src/modelinfo/ModelInfo.cpp
+++ b/src/modelinfo/ModelInfo.cpp
@@ -4,18 +4,15 @@
#include "TempColModels.h"
#include "ModelIndices.h"
#include "ModelInfo.h"
-#include "Frontend.h"
CBaseModelInfo *CModelInfo::ms_modelInfoPtrs[MODELINFOSIZE];
CStore<CSimpleModelInfo, SIMPLEMODELSIZE> CModelInfo::ms_simpleModelStore;
-CStore<CMloModelInfo, MLOMODELSIZE> CModelInfo::ms_mloModelStore;
-CStore<CInstance, MLOINSTANCESIZE> CModelInfo::ms_mloInstanceStore;
CStore<CTimeModelInfo, TIMEMODELSIZE> CModelInfo::ms_timeModelStore;
+CStore<CWeaponModelInfo, WEAPONMODELSIZE> CModelInfo::ms_weaponModelStore;
CStore<CClumpModelInfo, CLUMPMODELSIZE> CModelInfo::ms_clumpModelStore;
CStore<CPedModelInfo, PEDMODELSIZE> CModelInfo::ms_pedModelStore;
CStore<CVehicleModelInfo, VEHICLEMODELSIZE> CModelInfo::ms_vehicleModelStore;
-CStore<CXtraCompsModelInfo, XTRACOMPSMODELSIZE> CModelInfo::ms_xtraCompsModelStore;
CStore<C2dEffect, TWODFXSIZE> CModelInfo::ms_2dEffectStore;
void
@@ -24,14 +21,20 @@ CModelInfo::Initialise(void)
int i;
CSimpleModelInfo *m;
+ debug("sizeof SimpleModelStore %d\n", sizeof(ms_simpleModelStore));
+ debug("sizeof TimeModelStore %d\n", sizeof(ms_timeModelStore));
+ debug("sizeof WeaponModelStore %d\n", sizeof(ms_weaponModelStore));
+ debug("sizeof ClumpModelStore %d\n", sizeof(ms_clumpModelStore));
+ debug("sizeof VehicleModelStore %d\n", sizeof(ms_vehicleModelStore));
+ debug("sizeof PedModelStore %d\n", sizeof(ms_pedModelStore));
+ debug("sizeof 2deffectsModelStore %d\n", sizeof(ms_2dEffectStore));
+
for(i = 0; i < MODELINFOSIZE; i++)
ms_modelInfoPtrs[i] = nil;
ms_2dEffectStore.Clear();
- ms_mloInstanceStore.Clear();
- ms_xtraCompsModelStore.Clear();
ms_simpleModelStore.Clear();
ms_timeModelStore.Clear();
- ms_mloModelStore.Clear();
+ ms_weaponModelStore.Clear();
ms_clumpModelStore.Clear();
ms_pedModelStore.Clear();
ms_vehicleModelStore.Clear();
@@ -91,29 +94,23 @@ CModelInfo::ShutDown(void)
int i;
for(i = 0; i < ms_simpleModelStore.allocPtr; i++)
ms_simpleModelStore.store[i].Shutdown();
- for(i = 0; i < ms_mloInstanceStore.allocPtr; i++)
- ms_mloInstanceStore.store[i].Shutdown();
for(i = 0; i < ms_timeModelStore.allocPtr; i++)
ms_timeModelStore.store[i].Shutdown();
+ for(i = 0; i < ms_weaponModelStore.allocPtr; i++)
+ ms_weaponModelStore.store[i].Shutdown();
for(i = 0; i < ms_clumpModelStore.allocPtr; i++)
ms_clumpModelStore.store[i].Shutdown();
for(i = 0; i < ms_vehicleModelStore.allocPtr; i++)
ms_vehicleModelStore.store[i].Shutdown();
for(i = 0; i < ms_pedModelStore.allocPtr; i++)
ms_pedModelStore.store[i].Shutdown();
- for(i = 0; i < ms_xtraCompsModelStore.allocPtr; i++)
- ms_xtraCompsModelStore.store[i].Shutdown();
- for(i = 0; i < ms_mloInstanceStore.allocPtr; i++)
- ms_mloInstanceStore.store[i].Shutdown();
for(i = 0; i < ms_2dEffectStore.allocPtr; i++)
ms_2dEffectStore.store[i].Shutdown();
ms_2dEffectStore.Clear();
ms_simpleModelStore.Clear();
- ms_mloInstanceStore.Clear();
- ms_mloModelStore.Clear();
- ms_xtraCompsModelStore.Clear();
ms_timeModelStore.Clear();
+ ms_weaponModelStore.Clear();
ms_pedModelStore.Clear();
ms_clumpModelStore.Clear();
ms_vehicleModelStore.Clear();
@@ -129,23 +126,21 @@ CModelInfo::AddSimpleModel(int id)
return modelinfo;
}
-CMloModelInfo *
-CModelInfo::AddMloModel(int id)
+CTimeModelInfo*
+CModelInfo::AddTimeModel(int id)
{
- CMloModelInfo *modelinfo;
- modelinfo = CModelInfo::ms_mloModelStore.Alloc();
+ CTimeModelInfo *modelinfo;
+ modelinfo = CModelInfo::ms_timeModelStore.Alloc();
CModelInfo::ms_modelInfoPtrs[id] = modelinfo;
- modelinfo->m_clump = nil;
- modelinfo->firstInstance = 0;
- modelinfo->lastInstance = 0;
+ modelinfo->Init();
return modelinfo;
}
-CTimeModelInfo*
-CModelInfo::AddTimeModel(int id)
+CWeaponModelInfo*
+CModelInfo::AddWeaponModel(int id)
{
- CTimeModelInfo *modelinfo;
- modelinfo = CModelInfo::ms_timeModelStore.Alloc();
+ CWeaponModelInfo *modelinfo;
+ modelinfo = CModelInfo::ms_weaponModelStore.Alloc();
CModelInfo::ms_modelInfoPtrs[id] = modelinfo;
modelinfo->Init();
return modelinfo;
@@ -201,6 +196,21 @@ CModelInfo::GetModelInfo(const char *name, int *id)
return nil;
}
+CBaseModelInfo*
+CModelInfo::GetModelInfo(const char *name, int minIndex, int maxIndex)
+{
+ if (minIndex > maxIndex)
+ return 0;
+
+ CBaseModelInfo *modelinfo;
+ for(int i = minIndex; i <= maxIndex; i++){
+ modelinfo = CModelInfo::ms_modelInfoPtrs[i];
+ if(modelinfo && !CGeneral::faststricmp(modelinfo->GetModelName(), name))
+ return modelinfo;
+ }
+ return nil;
+}
+
bool
CModelInfo::IsBoatModel(int32 id)
{
@@ -215,31 +225,25 @@ CModelInfo::IsBikeModel(int32 id)
((CVehicleModelInfo*)GetModelInfo(id))->m_vehicleType == VEHICLE_TYPE_BIKE;
}
-void
-CModelInfo::RemoveColModelsFromOtherLevels(eLevelName level)
-{
- ISLAND_LOADING_IS(LOW)
- {
- int i;
- CBaseModelInfo *mi;
- CColModel *colmodel;
-
- for (i = 0; i < MODELINFOSIZE; i++) {
- mi = GetModelInfo(i);
- if (mi) {
- colmodel = mi->GetColModel();
- if (colmodel && colmodel->level != LEVEL_GENERIC && colmodel->level != level)
- colmodel->RemoveCollisionVolumes();
- }
- }
- }
+bool
+CModelInfo::IsCarModel(int32 id)
+{
+ return GetModelInfo(id)->GetModelType() == MITYPE_VEHICLE &&
+ ((CVehicleModelInfo*)GetModelInfo(id))->m_vehicleType == VEHICLE_TYPE_CAR;
}
-void
-CModelInfo::ConstructMloClumps()
+bool
+CModelInfo::IsHeliModel(int32 id)
+{
+ return GetModelInfo(id)->GetModelType() == MITYPE_VEHICLE &&
+ ((CVehicleModelInfo*)GetModelInfo(id))->m_vehicleType == VEHICLE_TYPE_HELI;
+}
+
+bool
+CModelInfo::IsPlaneModel(int32 id)
{
- for (int i = 0; i < ms_mloModelStore.allocPtr; i++)
- ms_mloModelStore.store[i].ConstructClump();
+ return GetModelInfo(id)->GetModelType() == MITYPE_VEHICLE &&
+ ((CVehicleModelInfo*)GetModelInfo(id))->m_vehicleType == VEHICLE_TYPE_PLANE;
}
void
diff --git a/src/modelinfo/ModelInfo.h b/src/modelinfo/ModelInfo.h
index 4d24e78f..a0ee0015 100644
--- a/src/modelinfo/ModelInfo.h
+++ b/src/modelinfo/ModelInfo.h
@@ -1,55 +1,52 @@
#pragma once
#include "2dEffect.h"
-#include "BaseModelInfo.h"
#include "SimpleModelInfo.h"
#include "MloModelInfo.h"
#include "TimeModelInfo.h"
+#include "WeaponModelInfo.h"
#include "ClumpModelInfo.h"
#include "PedModelInfo.h"
#include "VehicleModelInfo.h"
-#include "XtraCompsModelInfo.h"
-#include "Instance.h"
-#include "Game.h"
+#include "templates.h"
class CModelInfo
{
static CBaseModelInfo *ms_modelInfoPtrs[MODELINFOSIZE];
static CStore<CSimpleModelInfo, SIMPLEMODELSIZE> ms_simpleModelStore;
- static CStore<CMloModelInfo, MLOMODELSIZE> ms_mloModelStore;
- static CStore<CInstance, MLOINSTANCESIZE> ms_mloInstanceStore;
static CStore<CTimeModelInfo, TIMEMODELSIZE> ms_timeModelStore;
+ static CStore<CWeaponModelInfo, WEAPONMODELSIZE> ms_weaponModelStore;
static CStore<CClumpModelInfo, CLUMPMODELSIZE> ms_clumpModelStore;
static CStore<CPedModelInfo, PEDMODELSIZE> ms_pedModelStore;
static CStore<CVehicleModelInfo, VEHICLEMODELSIZE> ms_vehicleModelStore;
static CStore<C2dEffect, TWODFXSIZE> ms_2dEffectStore;
- static CStore<CXtraCompsModelInfo, XTRACOMPSMODELSIZE> ms_xtraCompsModelStore;
public:
static void Initialise(void);
static void ShutDown(void);
static CSimpleModelInfo *AddSimpleModel(int id);
- static CMloModelInfo *AddMloModel(int id);
static CTimeModelInfo *AddTimeModel(int id);
+ static CWeaponModelInfo *AddWeaponModel(int id);
static CClumpModelInfo *AddClumpModel(int id);
static CPedModelInfo *AddPedModel(int id);
static CVehicleModelInfo *AddVehicleModel(int id);
static CStore<C2dEffect, TWODFXSIZE> &Get2dEffectStore(void) { return ms_2dEffectStore; }
- static CStore<CInstance, MLOINSTANCESIZE> &GetMloInstanceStore(void) { return ms_mloInstanceStore; }
static CBaseModelInfo *GetModelInfo(const char *name, int *id);
static CBaseModelInfo *GetModelInfo(int id){
return ms_modelInfoPtrs[id];
}
+ static CBaseModelInfo *GetModelInfo(const char *name, int minIndex, int maxIndex);
static CColModel *GetColModel(int id){
return ms_modelInfoPtrs[id]->GetColModel();
}
static bool IsBoatModel(int32 id);
static bool IsBikeModel(int32 id);
- static void RemoveColModelsFromOtherLevels(eLevelName level);
- static void ConstructMloClumps();
+ static bool IsCarModel(int32 id);
+ static bool IsHeliModel(int32 id);
+ static bool IsPlaneModel(int32 id);
static void ReInit2dEffects();
};
diff --git a/src/modelinfo/PedModelInfo.cpp b/src/modelinfo/PedModelInfo.cpp
index 2cce48f4..25b260d3 100644
--- a/src/modelinfo/PedModelInfo.cpp
+++ b/src/modelinfo/PedModelInfo.cpp
@@ -13,33 +13,13 @@
void
CPedModelInfo::DeleteRwObject(void)
{
+ CClumpModelInfo::DeleteRwObject();
if(m_hitColModel)
delete m_hitColModel;
m_hitColModel = nil;
-#ifdef PED_SKIN
- RwFrame *frame;
- if(m_head){
- frame = RpAtomicGetFrame(m_head);
- RpAtomicDestroy(m_head);
- RwFrameDestroy(frame);
- m_head = nil;
- }
- if(m_lhand){
- frame = RpAtomicGetFrame(m_lhand);
- RpAtomicDestroy(m_lhand);
- RwFrameDestroy(frame);
- m_lhand = nil;
- }
- if(m_rhand){
- frame = RpAtomicGetFrame(m_rhand);
- RpAtomicDestroy(m_rhand);
- RwFrameDestroy(frame);
- m_rhand = nil;
- }
-#endif
- CClumpModelInfo::DeleteRwObject(); // PC calls this first
}
+// leftover...
RwObjectNameIdAssocation CPedModelInfo::m_pPedIds[PED_NODE_MAX] = {
{ "Smid", PED_MID, 0, }, // that is strange...
{ "Shead", PED_HEAD, 0, },
@@ -55,133 +35,19 @@ RwObjectNameIdAssocation CPedModelInfo::m_pPedIds[PED_NODE_MAX] = {
{ nil, 0, 0, },
};
-#ifdef PED_SKIN
-struct LimbCBarg
-{
- CPedModelInfo *mi;
- RpClump *clump;
- int32 frameIDs[3];
-};
-
-RpAtomic*
-CPedModelInfo::findLimbsCb(RpAtomic *atomic, void *data)
-{
- LimbCBarg *limbs = (LimbCBarg*)data;
- RwFrame *frame = RpAtomicGetFrame(atomic);
- const char *name = GetFrameNodeName(frame);
- if(CGeneral::faststricmp(name, "Shead01") == 0){
- limbs->frameIDs[0] = RpHAnimFrameGetID(frame);
- limbs->mi->m_head = atomic;
- RpClumpRemoveAtomic(limbs->clump, atomic);
- RwFrameRemoveChild(frame);
- }else if(CGeneral::faststricmp(name, "SLhand01") == 0){
- limbs->frameIDs[1] = RpHAnimFrameGetID(frame);
- limbs->mi->m_lhand = atomic;
- RpClumpRemoveAtomic(limbs->clump, atomic);
- RwFrameRemoveChild(frame);
- }else if(CGeneral::faststricmp(name, "SRhand01") == 0){
- limbs->frameIDs[2] = RpHAnimFrameGetID(frame);
- limbs->mi->m_rhand = atomic;
- RpClumpRemoveAtomic(limbs->clump, atomic);
- RwFrameRemoveChild(frame);
- }
- return atomic;
-}
-#endif
-
void
CPedModelInfo::SetClump(RpClump *clump)
{
#ifdef EXTENDED_PIPELINES
CustomPipes::AttachRimPipe(clump);
#endif
-#ifdef PED_SKIN
- // CB has to be set here before atomics are detached from clump
- if(strcmp(GetModelName(), "player") == 0)
- RpClumpForAllAtomics(clump, SetAtomicRendererCB, (void*)CVisibilityPlugins::RenderPlayerCB);
- if(IsClumpSkinned(clump)){
- LimbCBarg limbs = { this, clump, { 0, 0, 0 } };
- RpClumpForAllAtomics(clump, findLimbsCb, &limbs);
- }
CClumpModelInfo::SetClump(clump);
- SetFrameIds(m_pPedIds);
- if(m_hitColModel == nil && !IsClumpSkinned(clump))
- CreateHitColModel();
- // And again because CClumpModelInfo resets it
- if(strcmp(GetModelName(), "player") == 0)
- RpClumpForAllAtomics(m_clump, SetAtomicRendererCB, (void*)CVisibilityPlugins::RenderPlayerCB);
- else if(IsClumpSkinned(clump))
- // skinned peds have no low detail version, so they don't have the right render Cb
- RpClumpForAllAtomics(m_clump, SetAtomicRendererCB, (void*)CVisibilityPlugins::RenderPedCB);
-#else
- CClumpModelInfo::SetClump(clump);
- SetFrameIds(m_pPedIds);
+ SetFrameIds(m_pPedIds); // not needed in VC actually
if(m_hitColModel == nil)
- CreateHitColModel();
+ CreateHitColModelSkinned(clump);
+ RpClumpForAllAtomics(m_clump, SetAtomicRendererCB, (void*)CVisibilityPlugins::RenderPedCB);
if(strcmp(GetModelName(), "player") == 0)
RpClumpForAllAtomics(m_clump, SetAtomicRendererCB, (void*)CVisibilityPlugins::RenderPlayerCB);
-#endif
-}
-
-RpAtomic*
-CountAtomicsCB(RpAtomic *atomic, void *data)
-{
- (*(int32*)data)++;
- return atomic;
-}
-
-RpAtomic*
-GetAtomicListCB(RpAtomic *atomic, void *data)
-{
- **(RpAtomic***)data = atomic;
- (*(RpAtomic***)data)++;
- return atomic;
-}
-
-RwFrame*
-FindPedFrameFromNameCB(RwFrame *frame, void *data)
-{
- RwObjectNameAssociation *assoc = (RwObjectNameAssociation*)data;
-
- if(CGeneral::faststricmp(GetFrameNodeName(frame)+1, assoc->name+1)){
- RwFrameForAllChildren(frame, FindPedFrameFromNameCB, assoc);
- return assoc->frame ? nil : frame;
- }else{
- assoc->frame = frame;
- return nil;
- }
-}
-
-void
-CPedModelInfo::SetLowDetailClump(RpClump *lodclump)
-{
- RpAtomic *atomics[16];
- RpAtomic **pAtm;
- int32 numAtm, numLodAtm;
- int i;
- RwObjectNameAssociation assoc;
-
- numAtm = 0;
- numLodAtm = 0;
- RpClumpForAllAtomics(m_clump, CountAtomicsCB, &numAtm); // actually unused
- RpClumpForAllAtomics(lodclump, CountAtomicsCB, &numLodAtm);
-
- RpClumpForAllAtomics(m_clump, SetAtomicRendererCB, (void*)CVisibilityPlugins::RenderPedHiDetailCB);
- RpClumpForAllAtomics(lodclump, SetAtomicRendererCB, (void*)CVisibilityPlugins::RenderPedLowDetailCB);
-
- pAtm = atomics;
- RpClumpForAllAtomics(lodclump, GetAtomicListCB, &pAtm);
-
- for(i = 0; i < numLodAtm; i++){
- assoc.name = GetFrameNodeName(RpAtomicGetFrame(atomics[i]));
- assoc.frame = nil;
- RwFrameForAllChildren(RpClumpGetFrame(m_clump), FindPedFrameFromNameCB, &assoc);
- if(assoc.frame){
- RpAtomicSetFrame(atomics[i], assoc.frame);
- RpClumpRemoveAtomic(lodclump, atomics[i]);
- RpClumpAddAtomic(m_clump, atomics[i]);
- }
- }
}
struct ColNodeInfo
@@ -193,117 +59,20 @@ struct ColNodeInfo
float radius;
};
-#define NUMPEDINFONODES 8
+#define NUMPEDINFONODES 10
ColNodeInfo m_pColNodeInfos[NUMPEDINFONODES] = {
- { nil, PED_HEAD, PEDPIECE_HEAD, 0.0f, 0.05f, 0.2f },
- { "Storso", 0, PEDPIECE_TORSO, 0.0f, 0.15f, 0.2f },
- { "Storso", 0, PEDPIECE_TORSO, 0.0f, -0.05f, 0.3f },
- { nil, PED_MID, PEDPIECE_MID, 0.0f, -0.07f, 0.3f },
- { nil, PED_UPPERARML, PEDPIECE_LEFTARM, 0.07f, -0.1f, 0.2f },
- { nil, PED_UPPERARMR, PEDPIECE_RIGHTARM, -0.07f, -0.1f, 0.2f },
- { "Slowerlegl", 0, PEDPIECE_LEFTLEG, 0.0f, 0.07f, 0.25f },
- { nil, PED_LOWERLEGR, PEDPIECE_RIGHTLEG, 0.0f, 0.07f, 0.25f },
+ { nil, PED_HEAD, PEDPIECE_HEAD, 0.0f, 0.05f, 0.15f },
+ { nil, PED_MID, PEDPIECE_TORSO, 0.0f, 0.15f, 0.2f },
+ { nil, PED_MID, PEDPIECE_TORSO, 0.0f, -0.05f, 0.25f },
+ { nil, PED_MID, PEDPIECE_MID, 0.0f, -0.25f, 0.25f },
+ { nil, PED_UPPERARML, PEDPIECE_LEFTARM, 0.03f, -0.05f, 0.16f },
+ { nil, PED_UPPERARMR, PEDPIECE_RIGHTARM, -0.03f, -0.05f, 0.16f },
+ { nil, PED_LOWERLEGL, PEDPIECE_LEFTLEG, 0.0f, 0.15f, 0.2f },
+ { nil, PED_LOWERLEGR, PEDPIECE_RIGHTLEG, 0.0f, 0.15f, 0.2f },
+ { nil, PED_FOOTL, PEDPIECE_LEFTLEG, 0.0f, 0.15f, 0.15f },
+ { nil, PED_FOOTR, PEDPIECE_RIGHTLEG, 0.0f, 0.15f, 0.15f },
};
-RwObject*
-FindHeadRadiusCB(RwObject *object, void *data)
-{
- RpAtomic *atomic = (RpAtomic*)object;
- *(float*)data = RpAtomicGetBoundingSphere(atomic)->radius;
- return nil;
-}
-
-void
-CPedModelInfo::CreateHitColModel(void)
-{
- RwObjectNameAssociation nameAssoc;
- RwObjectIdAssociation idAssoc;
- RwFrame *nodeFrame;
- CColModel *colmodel = new CColModel;
- CColSphere *spheres = (CColSphere*)RwMalloc(NUMPEDINFONODES*sizeof(CColSphere));
- RwFrame *root = RpClumpGetFrame(m_clump);
- RwMatrix *mat = RwMatrixCreate();
- for(int i = 0; i < NUMPEDINFONODES; i++){
- nodeFrame = nil;
- if(m_pColNodeInfos[i].name){
- nameAssoc.name = m_pColNodeInfos[i].name;
- nameAssoc.frame = nil;
- RwFrameForAllChildren(root, FindFrameFromNameCB, &nameAssoc);
- nodeFrame = nameAssoc.frame;
- }else{
- idAssoc.id = m_pColNodeInfos[i].pedNode;
- idAssoc.frame = nil;
- RwFrameForAllChildren(root, FindFrameFromIdCB, &idAssoc);
- nodeFrame = idAssoc.frame;
- }
- if(nodeFrame){
- float radius = m_pColNodeInfos[i].radius;
- if(m_pColNodeInfos[i].pieceType == PEDPIECE_HEAD)
- RwFrameForAllObjects(nodeFrame, FindHeadRadiusCB, &radius);
- RwMatrixTransform(mat, RwFrameGetMatrix(nodeFrame), rwCOMBINEREPLACE);
- const char *name = GetFrameNodeName(nodeFrame);
- for(nodeFrame = RwFrameGetParent(nodeFrame);
- nodeFrame;
- nodeFrame = RwFrameGetParent(nodeFrame)){
- name = GetFrameNodeName(nodeFrame);
- RwMatrixTransform(mat, RwFrameGetMatrix(nodeFrame), rwCOMBINEPOSTCONCAT);
- if(RwFrameGetParent(nodeFrame) == root)
- break;
- }
- spheres[i].center = mat->pos + CVector(m_pColNodeInfos[i].x, 0.0f, m_pColNodeInfos[i].z);
- spheres[i].radius = radius;
- spheres[i].surface = SURFACE_PED;
- spheres[i].piece = m_pColNodeInfos[i].pieceType;
- }
- }
- RwMatrixDestroy(mat);
- colmodel->spheres = spheres;
- colmodel->numSpheres = NUMPEDINFONODES;
- colmodel->boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
- colmodel->boundingBox.Set(CVector(-0.5f, -0.5f, -1.2f), CVector(0.5f, 0.5f, 1.2f), SURFACE_DEFAULT, 0);
- colmodel->level = LEVEL_GENERIC;
- m_hitColModel = colmodel;
-}
-
-CColModel*
-CPedModelInfo::AnimatePedColModel(CColModel* colmodel, RwFrame* frame)
-{
- RwObjectNameAssociation nameAssoc;
- RwObjectIdAssociation idAssoc;
- RwMatrix* mat = RwMatrixCreate();
- CColSphere* spheres = colmodel->spheres;
-
- for (int i = 0; i < NUMPEDINFONODES; i++) {
- RwFrame* f = nil;
- if (m_pColNodeInfos[i].name) {
- nameAssoc.name = m_pColNodeInfos[i].name;
- nameAssoc.frame = nil;
- RwFrameForAllChildren(frame, FindFrameFromNameCB, &nameAssoc);
- f = nameAssoc.frame;
- }
- else {
- idAssoc.id = m_pColNodeInfos[i].pedNode;
- idAssoc.frame = nil;
- RwFrameForAllChildren(frame, FindFrameFromIdCB, &idAssoc);
- f = idAssoc.frame;
- }
- if (f) {
- RwMatrixCopy(mat, RwFrameGetMatrix(f));
-
- for (f = RwFrameGetParent(f); f; f = RwFrameGetParent(f)) {
- RwMatrixTransform(mat, RwFrameGetMatrix(f), rwCOMBINEPOSTCONCAT);
- if (RwFrameGetParent(f) == frame)
- break;
- }
-
- spheres[i].center = mat->pos + CVector(m_pColNodeInfos[i].x, 0.0f, m_pColNodeInfos[i].z);
- }
- }
-
- return colmodel;
-}
-
-#ifdef PED_SKIN
void
CPedModelInfo::CreateHitColModelSkinned(RpClump *clump)
{
@@ -317,6 +86,7 @@ CPedModelInfo::CreateHitColModelSkinned(RpClump *clump)
for(int i = 0; i < NUMPEDINFONODES; i++){
*mat = *invmat;
+
// From LCS. Otherwise gives FPE
#ifdef FIX_BUGS
spheres[i].center = CVector(0.0f, 0.0f, 0.0f);
@@ -339,8 +109,8 @@ CPedModelInfo::CreateHitColModelSkinned(RpClump *clump)
RwMatrixDestroy(mat);
colmodel->spheres = spheres;
colmodel->numSpheres = NUMPEDINFONODES;
- colmodel->boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
- colmodel->boundingBox.Set(CVector(-0.5f, -0.5f, -1.2f), CVector(0.5f, 0.5f, 1.2f), SURFACE_DEFAULT, 0);
+ colmodel->boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f));
+ colmodel->boundingBox.Set(CVector(-0.5f, -0.5f, -1.2f), CVector(0.5f, 0.5f, 1.2f));
colmodel->level = LEVEL_GENERIC;
m_hitColModel = colmodel;
}
@@ -375,4 +145,24 @@ CPedModelInfo::AnimatePedColModelSkinned(RpClump *clump)
return m_hitColModel;
}
-#endif
+CColModel*
+CPedModelInfo::AnimatePedColModelSkinnedWorld(RpClump *clump)
+{
+ if(m_hitColModel == nil)
+ CreateHitColModelSkinned(clump);
+ CColSphere *spheres = m_hitColModel->spheres;
+ RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(clump);
+ RwMatrix *mat;
+
+ for(int i = 0; i < NUMPEDINFONODES; i++){
+ int id = ConvertPedNode2BoneTag(m_pColNodeInfos[i].pedNode);
+ int idx = RpHAnimIDGetIndex(hier, id);
+
+ mat = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwV3d pos = { 0.0f, 0.0f, 0.0f };
+ RwV3dTransformPoints(&pos, &pos, 1, mat);
+
+ spheres[i].center = pos + CVector(m_pColNodeInfos[i].x, 0.0f, m_pColNodeInfos[i].z);
+ }
+ return m_hitColModel;
+}
diff --git a/src/modelinfo/PedModelInfo.h b/src/modelinfo/PedModelInfo.h
index 26ab3c3f..79bd7eaa 100644
--- a/src/modelinfo/PedModelInfo.h
+++ b/src/modelinfo/PedModelInfo.h
@@ -5,8 +5,8 @@
#include "PedType.h"
enum PedNode {
- PED_TORSO,
- PED_MID, // Smid on PS2/PC, Storso on mobile/xbox
+ PED_TORSO = 0, // has no bone!
+ PED_MID,
PED_HEAD,
PED_UPPERARML,
PED_UPPERARMR,
@@ -17,7 +17,15 @@ enum PedNode {
PED_FOOTL,
PED_FOOTR,
PED_LOWERLEGR,
- PED_NODE_MAX// Not valid: PED_LOWERLEGL
+ PED_LOWERLEGL,
+
+ PED_FOREARML,
+ PED_FOREARMR,
+ PED_CLAVICLEL,
+ PED_CLAVICLER,
+ PED_NECK,
+
+ PED_NODE_MAX
};
class CPedModelInfo : public CClumpModelInfo
@@ -28,40 +36,17 @@ public:
ePedStats m_pedStatType;
uint32 m_carsCanDrive;
CColModel *m_hitColModel;
-#ifdef PED_SKIN
- RpAtomic *m_head;
- RpAtomic *m_lhand;
- RpAtomic *m_rhand;
-#endif
+ int8 radio1, radio2;
static RwObjectNameIdAssocation m_pPedIds[PED_NODE_MAX];
- CPedModelInfo(void) : CClumpModelInfo(MITYPE_PED) {
- m_hitColModel = nil;
-#ifdef PED_SKIN
- m_head = nil;
- m_lhand = nil;
- m_rhand = nil;
-#endif
- }
+ CPedModelInfo(void) : CClumpModelInfo(MITYPE_PED) { m_hitColModel = nil; }
~CPedModelInfo(void) { delete m_hitColModel; }
void DeleteRwObject(void);
void SetClump(RpClump *);
- void SetLowDetailClump(RpClump*);
- void CreateHitColModel(void);
void CreateHitColModelSkinned(RpClump *clump);
CColModel *GetHitColModel(void) { return m_hitColModel; }
- static CColModel *AnimatePedColModel(CColModel* colmodel, RwFrame* frame);
CColModel *AnimatePedColModelSkinned(RpClump *clump);
-
-#ifdef PED_SKIN
- static RpAtomic *findLimbsCb(RpAtomic *atomic, void *data);
- RpAtomic *getHead(void) { return m_head; }
- RpAtomic *getLeftHand(void) { return m_lhand; }
- RpAtomic *getRightHand(void) { return m_rhand; }
-#endif
+ CColModel *AnimatePedColModelSkinnedWorld(RpClump *clump);
};
-#ifndef PED_SKIN
-VALIDATE_SIZE(CPedModelInfo, 0x48);
-#endif \ No newline at end of file
diff --git a/src/modelinfo/SimpleModelInfo.cpp b/src/modelinfo/SimpleModelInfo.cpp
index 9fc0dd6e..18eb7e5f 100644
--- a/src/modelinfo/SimpleModelInfo.cpp
+++ b/src/modelinfo/SimpleModelInfo.cpp
@@ -4,6 +4,7 @@
#include "Camera.h"
#include "Renderer.h"
#include "ModelInfo.h"
+#include "AnimManager.h"
#include "custompipes.h"
void
@@ -18,6 +19,8 @@ CSimpleModelInfo::DeleteRwObject(void)
RwFrameDestroy(f);
m_atomics[i] = nil;
RemoveTexDictionaryRef();
+ if(GetAnimFileIndex() != -1)
+ CAnimManager::RemoveAnimBlockRef(GetAnimFileIndex());
}
}
@@ -55,7 +58,7 @@ CSimpleModelInfo::Init(void)
m_atomics[2] = nil;
m_numAtomics = 0;
m_firstDamaged = 0;
- m_normalCull = 0;
+ m_wetRoadReflection = 0;
m_isDamaged = 0;
m_isBigBuilding = 0;
m_noFade = 0;
@@ -64,6 +67,10 @@ CSimpleModelInfo::Init(void)
m_isSubway = 0;
m_ignoreLight = 0;
m_noZwrite = 0;
+ m_noShadows = 0;
+ m_ignoreDrawDist = 0;
+ m_isCodeGlass = 0;
+ m_isArtistGlass = 0;
}
void
@@ -71,13 +78,20 @@ CSimpleModelInfo::SetAtomic(int n, RpAtomic *atomic)
{
AddTexDictionaryRef();
m_atomics[n] = atomic;
- if(m_ignoreLight){
- RpGeometry *geo = RpAtomicGetGeometry(atomic);
+ if(GetAnimFileIndex() != -1)
+ CAnimManager::AddAnimBlockRef(GetAnimFileIndex());
+ RpGeometry *geo = RpAtomicGetGeometry(atomic);
+ if(m_ignoreLight)
RpGeometrySetFlags(geo, RpGeometryGetFlags(geo) & ~rpGEOMETRYLIGHT);
- }
+ if(RpGeometryGetFlags(geo) & rpGEOMETRYNORMALS &&
+ RpGeometryGetNumTriangles(geo) > 200)
+ debug("%s has %d polys\n", m_name, RpGeometryGetNumTriangles(geo));
#ifdef EXTENDED_PIPELINES
- CustomPipes::AttachWorldPipe(atomic);
+ if(m_wetRoadReflection)
+ CustomPipes::AttachGlossPipe(atomic);
+ else
+ CustomPipes::AttachWorldPipe(atomic);
#endif
}
@@ -134,12 +148,20 @@ CSimpleModelInfo::GetAtomicFromDistance(float dist)
return nil;
}
+RpAtomic*
+CSimpleModelInfo::GetFirstAtomicFromDistance(float dist)
+{
+ if(dist < m_lodDistances[0] * TheCamera.LODDistMultiplier)
+ return m_atomics[0];
+ return nil;
+}
+
void
-CSimpleModelInfo::FindRelatedModel(void)
+CSimpleModelInfo::FindRelatedModel(int32 minID, int32 maxID)
{
int i;
CBaseModelInfo *mi;
- for(i = 0; i < MODELINFOSIZE; i++){
+ for(i = minID; i <= maxID; i++){
mi = CModelInfo::GetModelInfo(i);
if(mi && mi != this &&
!CGeneral::faststrcmp(GetModelName()+3, mi->GetModelName()+3)){
@@ -150,24 +172,23 @@ CSimpleModelInfo::FindRelatedModel(void)
}
}
+#define NEAR_DRAW_DIST 0.0f // 100.0f in liberty city
+
void
-CSimpleModelInfo::SetupBigBuilding(void)
+CSimpleModelInfo::SetupBigBuilding(int32 minID, int32 maxID)
{
CSimpleModelInfo *related;
if(m_lodDistances[0] > LOD_DISTANCE && GetRelatedModel() == nil){
m_isBigBuilding = 1;
- FindRelatedModel();
+ FindRelatedModel(minID, maxID);
related = GetRelatedModel();
- if(related)
+ if(related){
m_lodDistances[2] = related->GetLargestLodDistance()/TheCamera.LODDistMultiplier;
- else
-#ifdef FIX_BUGS
- if(toupper(m_name[0]) == 'L' && toupper(m_name[1]) == 'O' && toupper(m_name[2]) == 'D')
- m_lodDistances[2] = 100.0f;
- else
- m_lodDistances[2] = 0.0f;
-#else
- m_lodDistances[2] = 100.0f;
-#endif
+ if(m_drawLast){
+ m_drawLast = false;
+ debug("%s was draw last\n", GetModelName());
+ }
+ }else
+ m_lodDistances[2] = NEAR_DRAW_DIST;
}
}
diff --git a/src/modelinfo/SimpleModelInfo.h b/src/modelinfo/SimpleModelInfo.h
index 94e55a2f..986cb886 100644
--- a/src/modelinfo/SimpleModelInfo.h
+++ b/src/modelinfo/SimpleModelInfo.h
@@ -11,30 +11,25 @@ public:
float m_lodDistances[3];
uint8 m_numAtomics;
uint8 m_alpha;
- /* // For reference, PS2 has:
- uint8 m_firstDamaged;
- uint8 m_normalCull : 1;
- uint8 m_isDamaged : 1;
- uint8 m_isBigBuilding : 1;
- uint8 m_noFade : 1;
- uint8 m_drawLast : 1;
- uint8 m_additive : 1;
- uint8 m_isSubway : 1;
- uint8 m_ignoreLight : 1;
- // m_noZwrite is missing because not needed
- */
uint16 m_firstDamaged : 2; // 0: no damage model
// 1: 1 and 2 are damage models
// 2: 2 is damage model
- uint16 m_normalCull : 1;
+ uint16 m_wetRoadReflection : 1;
uint16 m_isDamaged : 1;
+
uint16 m_isBigBuilding : 1;
uint16 m_noFade : 1;
uint16 m_drawLast : 1;
uint16 m_additive : 1;
+
uint16 m_isSubway : 1;
uint16 m_ignoreLight : 1;
uint16 m_noZwrite : 1;
+ uint16 m_noShadows : 1;
+
+ uint16 m_ignoreDrawDist : 1;
+ uint16 m_isCodeGlass : 1;
+ uint16 m_isArtistGlass : 1;
CSimpleModelInfo(void) : CBaseModelInfo(MITYPE_SIMPLE) {}
CSimpleModelInfo(ModelInfoType id) : CBaseModelInfo(id) {}
@@ -44,16 +39,18 @@ public:
RwObject *CreateInstance(RwMatrix *);
RwObject *GetRwObject(void) { return (RwObject*)m_atomics[0]; }
+ virtual void SetAtomic(int n, RpAtomic *atomic);
+
void Init(void);
void IncreaseAlpha(void);
- void SetAtomic(int n, RpAtomic *atomic);
void SetLodDistances(float *dist);
float GetLodDistance(int i);
float GetNearDistance(void);
float GetLargestLodDistance(void);
RpAtomic *GetAtomicFromDistance(float dist);
- void FindRelatedModel(void);
- void SetupBigBuilding(void);
+ RpAtomic *GetFirstAtomicFromDistance(float dist);
+ void FindRelatedModel(int32 minID, int32 maxID);
+ void SetupBigBuilding(int32 minID, int32 maxID);
void SetNumAtomics(int n) { m_numAtomics = n; }
CSimpleModelInfo *GetRelatedModel(void){
@@ -61,5 +58,4 @@ public:
void SetRelatedModel(CSimpleModelInfo *m){
m_atomics[2] = (RpAtomic*)m; }
};
-
-VALIDATE_SIZE(CSimpleModelInfo, 0x4C);
+//static_assert(sizeof(CSimpleModelInfo) == 0x4C, "CSimpleModelInfo: error");
diff --git a/src/modelinfo/TimeModelInfo.h b/src/modelinfo/TimeModelInfo.h
index 73b6ab26..6e3c64fb 100644
--- a/src/modelinfo/TimeModelInfo.h
+++ b/src/modelinfo/TimeModelInfo.h
@@ -17,5 +17,4 @@ public:
void SetOtherTimeModel(int32 other) { m_otherTimeModelID = other; }
CTimeModelInfo *FindOtherTimeModel(void);
};
-
-VALIDATE_SIZE(CTimeModelInfo, 0x58);
+//static_assert(sizeof(CTimeModelInfo) == 0x58, "CTimeModelInfo: error");
diff --git a/src/modelinfo/VehicleModelInfo.cpp b/src/modelinfo/VehicleModelInfo.cpp
index 685b6ef6..d31962ce 100644
--- a/src/modelinfo/VehicleModelInfo.cpp
+++ b/src/modelinfo/VehicleModelInfo.cpp
@@ -23,7 +23,6 @@
int8 CVehicleModelInfo::ms_compsToUse[2] = { -2, -2 };
int8 CVehicleModelInfo::ms_compsUsed[2];
-RwTexture *CVehicleModelInfo::ms_pEnvironmentMaps[NUM_VEHICLE_ENVMAPS];
RwRGBA CVehicleModelInfo::ms_vehicleColourTable[256];
RwTexture *CVehicleModelInfo::ms_colourTextureTable[256];
@@ -83,9 +82,23 @@ RwObjectNameIdAssocation carIds[] = {
};
RwObjectNameIdAssocation boatIds[] = {
- { "boat_moving_hi", BOAT_MOVING, VEHICLE_FLAG_COLLAPSE },
- { "boat_rudder_hi", BOAT_RUDDER, VEHICLE_FLAG_COLLAPSE },
- { "windscreen", BOAT_WINDSCREEN, VEHICLE_FLAG_WINDSCREEN | VEHICLE_FLAG_COLLAPSE },
+ { "boat_moving_hi", BOAT_MOVING, 0 },
+ { "boat_rudder_hi", BOAT_RUDDER, 0 },
+ { "boat_flap_left", BOAT_FLAP_LEFT, 0 },
+ { "boat_flap_right", BOAT_FLAP_RIGHT, 0 },
+ { "boat_rearflap_left", BOAT_REARFLAP_LEFT, 0 },
+ { "boat_rearflap_right", BOAT_REARFLAP_RIGHT, 0 },
+#ifdef FIX_BUGS
+ // let's just accept both
+ { "windscreen", BOAT_WINDSCREEN, VEHICLE_FLAG_WINDSCREEN | VEHICLE_FLAG_DRAWLAST },
+ { "windscreen_hi_ok", BOAT_WINDSCREEN, VEHICLE_FLAG_WINDSCREEN | VEHICLE_FLAG_DRAWLAST },
+#else
+#ifdef GTA_PS2
+ { "windscreen", BOAT_WINDSCREEN, VEHICLE_FLAG_WINDSCREEN | VEHICLE_FLAG_DRAWLAST },
+#else
+ { "windscreen_hi_ok", BOAT_WINDSCREEN, VEHICLE_FLAG_WINDSCREEN | VEHICLE_FLAG_DRAWLAST },
+#endif
+#endif
{ "ped_frontseat", BOAT_POS_FRONTSEAT, VEHICLE_FLAG_POS | CLUMP_FLAG_NO_HIERID },
{ nil, 0, 0 }
};
@@ -128,7 +141,9 @@ RwObjectNameIdAssocation bikeIds[] = {
{ "wheel_front", BIKE_WHEEL_FRONT, 0 },
{ "wheel_rear", BIKE_WHEEL_REAR, 0 },
{ "mudguard", BIKE_MUDGUARD, 0 },
+ { "handlebars", BIKE_HANDLEBARS, 0 },
{ "ped_frontseat", CAR_POS_FRONTSEAT, VEHICLE_FLAG_POS | CLUMP_FLAG_NO_HIERID },
+ { "ped_backseat", CAR_POS_BACKSEAT, VEHICLE_FLAG_POS | CLUMP_FLAG_NO_HIERID },
{ "headlights", CAR_POS_HEADLIGHTS, VEHICLE_FLAG_POS | CLUMP_FLAG_NO_HIERID },
{ "taillights", CAR_POS_TAILLIGHTS, VEHICLE_FLAG_POS | CLUMP_FLAG_NO_HIERID },
{ "exhaust", CAR_POS_EXHAUST, VEHICLE_FLAG_POS | CLUMP_FLAG_NO_HIERID },
@@ -150,6 +165,8 @@ RwObjectNameIdAssocation *CVehicleModelInfo::ms_vehicleDescs[] = {
bikeIds
};
+bool gbBlackCars;
+bool gbPinkCars;
CVehicleModelInfo::CVehicleModelInfo(void)
: CClumpModelInfo(MITYPE_VEHICLE)
@@ -161,6 +178,7 @@ CVehicleModelInfo::CVehicleModelInfo(void)
m_positions[i].z = 0.0f;
}
m_numColours = 0;
+ m_animFileIndex = -1;
}
void
@@ -191,7 +209,7 @@ CVehicleModelInfo::CreateInstance(void)
clumpframe = RpClumpGetFrame(clump);
comp1 = ChooseComponent();
- if(comp1 != -1){
+ if(comp1 != -1 && m_comps[comp1]){
atomic = RpAtomicClone(m_comps[comp1]);
f = RwFrameCreate();
RwFrameTransform(f,
@@ -204,7 +222,7 @@ CVehicleModelInfo::CreateInstance(void)
ms_compsUsed[0] = comp1;
comp2 = ChooseSecondComponent();
- if(comp2 != -1){
+ if(comp2 != -1 && m_comps[comp2]){
atomic = RpAtomicClone(m_comps[comp2]);
f = RwFrameCreate();
RwFrameTransform(f,
@@ -230,10 +248,30 @@ CVehicleModelInfo::SetClump(RpClump *clump)
SetFrameIds(ms_vehicleDescs[m_vehicleType]);
PreprocessHierarchy();
FindEditableMaterialList();
- m_envMap = nil;
SetEnvironmentMap();
}
+void
+CVehicleModelInfo::SetAnimFile(const char *file)
+{
+ if(strcasecmp(file, "null") == 0)
+ return;
+
+ m_animFileName = new char[strlen(file)+1];
+ strcpy(m_animFileName, file);
+}
+
+void
+CVehicleModelInfo::ConvertAnimFileIndex(void)
+{
+ if(m_animFileIndex != -1){
+ // we have a string pointer in that union
+ int32 index = CAnimManager::GetAnimationBlockIndex(m_animFileName);
+ delete[] m_animFileName;
+ m_animFileIndex = index;
+ }
+}
+
RwFrame*
CVehicleModelInfo::CollapseFramesCB(RwFrame *frame, void *data)
{
@@ -301,7 +339,7 @@ CVehicleModelInfo::SetAtomicRendererCB(RpAtomic *atomic, void *data)
}else if(strstr(name, "_lo")){
RpClumpRemoveAtomic(clump, atomic);
RpAtomicDestroy(atomic);
- return atomic; // BUG: not done by gta
+ return atomic; // BUG: nil in gta
}else if(strstr(name, "_vlo"))
CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleReallyLowDetailCB);
else
@@ -364,21 +402,31 @@ CVehicleModelInfo::SetAtomicRendererCB_Boat(RpAtomic *atomic, void *data)
{
RpClump *clump;
char *name;
+ bool alpha;
clump = (RpClump*)data;
name = GetFrameNodeName(RpAtomicGetFrame(atomic));
+ alpha = false;
+ RpGeometryForAllMaterials(RpAtomicGetGeometry(atomic), HasAlphaMaterialCB, &alpha);
if(strcmp(name, "boat_hi") == 0 || !CGeneral::faststrncmp(name, "extra", 5))
CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleHiDetailCB_Boat);
- else if(strstr(name, "_hi"))
- CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleHiDetailCB);
- else if(strstr(name, "_lo")){
+ else if(strstr(name, "_hi")){
+ if(alpha)
+ CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleHiDetailAlphaCB_Boat);
+ else
+ CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleHiDetailCB);
+ }else if(strstr(name, "_lo")){
RpClumpRemoveAtomic(clump, atomic);
RpAtomicDestroy(atomic);
return atomic; // BUG: not done by gta
}else if(strstr(name, "_vlo"))
- CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleReallyLowDetailCB_BigVehicle);
- else
- CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil);
+ CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleLoDetailCB_Boat);
+ else{
+ if(alpha)
+ CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleHiDetailAlphaCB_Boat);
+ else
+ CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil);
+ }
HideDamagedAtomicCB(atomic, nil);
return atomic;
}
@@ -386,30 +434,68 @@ CVehicleModelInfo::SetAtomicRendererCB_Boat(RpAtomic *atomic, void *data)
RpAtomic*
CVehicleModelInfo::SetAtomicRendererCB_Heli(RpAtomic *atomic, void *data)
{
- CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil);
+ char *name;
+
+ name = GetFrameNodeName(RpAtomicGetFrame(atomic));
+ if(strncmp(name, "toprotor", 8) == 0)
+ CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleRotorAlphaCB);
+ else if(strncmp(name, "rearrotor", 9) == 0)
+ CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleTailRotorAlphaCB);
+ else
+ CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil);
+ return atomic;
+}
+
+RpAtomic*
+CVehicleModelInfo::SetAtomicRendererCB_RealHeli(RpAtomic *atomic, void *data)
+{
+ RpClump *clump;
+ char *name;
+ bool alpha;
+
+ clump = (RpClump*)data;
+ name = GetFrameNodeName(RpAtomicGetFrame(atomic));
+ alpha = false;
+ RpGeometryForAllMaterials(RpAtomicGetGeometry(atomic), HasAlphaMaterialCB, &alpha);
+ if(strncmp(name, "toprotor", 8) == 0)
+ CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleRotorAlphaCB);
+ else if(strncmp(name, "rearrotor", 9) == 0)
+ CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleTailRotorAlphaCB);
+ else if(strstr(name, "_hi") || !CGeneral::faststrncmp(name, "extra", 5)) {
+ if(alpha || strncmp(name, "windscreen", 10) == 0)
+ CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleHiDetailAlphaCB);
+ else
+ CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleHiDetailCB);
+ }else if(strstr(name, "_lo")){
+ RpClumpRemoveAtomic(clump, atomic);
+ RpAtomicDestroy(atomic);
+ return atomic; // BUG: nil in gta
+ }else if(strstr(name, "_vlo"))
+ CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleReallyLowDetailCB);
+ else
+ CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil);
+ HideDamagedAtomicCB(atomic, nil);
return atomic;
}
void
CVehicleModelInfo::SetAtomicRenderCallbacks(void)
{
- switch(m_vehicleType){
- case VEHICLE_TYPE_TRAIN:
+#ifdef GTA_TRAIN
+ if(m_vehicleType == VEHICLE_TYPE_TRAIN)
RpClumpForAllAtomics(m_clump, SetAtomicRendererCB_Train, nil);
- break;
- case VEHICLE_TYPE_HELI:
+ else
+#endif
+ if(m_vehicleType == VEHICLE_TYPE_HELI)
RpClumpForAllAtomics(m_clump, SetAtomicRendererCB_Heli, nil);
- break;
- case VEHICLE_TYPE_PLANE:
+ else if(m_vehicleType == VEHICLE_TYPE_PLANE)
RpClumpForAllAtomics(m_clump, SetAtomicRendererCB_BigVehicle, nil);
- break;
- case VEHICLE_TYPE_BOAT:
+ else if(m_vehicleType == VEHICLE_TYPE_BOAT)
RpClumpForAllAtomics(m_clump, SetAtomicRendererCB_Boat, m_clump);
- break;
- default:
+ else if(mod_HandlingManager.GetHandlingData((tVehicleType)m_handlingId)->Flags & HANDLING_IS_HELI)
+ RpClumpForAllAtomics(m_clump, SetAtomicRendererCB_RealHeli, m_clump);
+ else
RpClumpForAllAtomics(m_clump, SetAtomicRendererCB, m_clump);
- break;
- }
}
RwObject*
@@ -606,6 +692,17 @@ ChooseComponent(int32 rule, int32 comps)
// only valid in rain
n = CGeneral::GetRandomNumberInRange(0, CountCompsInRule(comps));
return COMPRULE_COMPN(comps, n);
+ case 3:
+ n = CGeneral::GetRandomNumberInRange(0, 1+CountCompsInRule(comps));
+ if(n != 0)
+ return COMPRULE_COMPN(comps, n-1);
+ return -1;
+ case 4:
+#ifdef FIX_BUGS
+ return CGeneral::GetRandomNumberInRange(0, 6);
+#else
+ return CGeneral::GetRandomNumberInRange(0, 5);
+#endif
}
return -1;
}
@@ -732,6 +829,9 @@ CVehicleModelInfo::GetEditableMaterialListCB(RpAtomic *atomic, void *data)
return atomic;
}
+static int maxFirstMaterials;
+static int maxSecondMaterials;
+
void
CVehicleModelInfo::FindEditableMaterialList(void)
{
@@ -746,6 +846,8 @@ CVehicleModelInfo::FindEditableMaterialList(void)
GetEditableMaterialListCB(m_comps[i], &cbdata);
m_materials1[cbdata.numMats1] = nil;
m_materials2[cbdata.numMats2] = nil;
+ maxFirstMaterials = Max(maxFirstMaterials, cbdata.numMats1);
+ maxSecondMaterials = Max(maxSecondMaterials, cbdata.numMats2);
m_currentColour1 = -1;
m_currentColour2 = -1;
}
@@ -754,35 +856,26 @@ void
CVehicleModelInfo::SetVehicleColour(uint8 c1, uint8 c2)
{
RwRGBA col, *colp;
- RwTexture *coltex;
RpMaterial **matp;
if(c1 != m_currentColour1){
col = ms_vehicleColourTable[c1];
- coltex = ms_colourTextureTable[c1];
for(matp = m_materials1; *matp; matp++){
- if(RpMaterialGetTexture(*matp) && RwTextureGetName(RpMaterialGetTexture(*matp))[0] != '@'){
- colp = (RwRGBA*)RpMaterialGetColor(*matp); // get rid of const
- colp->red = col.red;
- colp->green = col.green;
- colp->blue = col.blue;
- }else
- RpMaterialSetTexture(*matp, coltex);
+ colp = (RwRGBA*)RpMaterialGetColor(*matp); // get rid of const
+ colp->red = col.red;
+ colp->green = col.green;
+ colp->blue = col.blue;
}
m_currentColour1 = c1;
}
if(c2 != m_currentColour2){
col = ms_vehicleColourTable[c2];
- coltex = ms_colourTextureTable[c2];
for(matp = m_materials2; *matp; matp++){
- if(RpMaterialGetTexture(*matp) && RwTextureGetName(RpMaterialGetTexture(*matp))[0] != '@'){
- colp = (RwRGBA*)RpMaterialGetColor(*matp); // get rid of const
- colp->red = col.red;
- colp->green = col.green;
- colp->blue = col.blue;
- }else
- RpMaterialSetTexture(*matp, coltex);
+ colp = (RwRGBA*)RpMaterialGetColor(*matp); // get rid of const
+ colp->red = col.red;
+ colp->green = col.green;
+ colp->blue = col.blue;
}
m_currentColour2 = c2;
}
@@ -791,9 +884,12 @@ CVehicleModelInfo::SetVehicleColour(uint8 c1, uint8 c2)
void
CVehicleModelInfo::ChooseVehicleColour(uint8 &col1, uint8 &col2)
{
- if(m_numColours == 0){
+ if(m_numColours == 0 || gbBlackCars){
col1 = 0;
col2 = 0;
+ }else if(gbPinkCars){
+ col1 = 68;
+ col2 = 68;
}else{
m_lastColorVariation = (m_lastColorVariation+1) % m_numColours;
col1 = m_colours1[m_lastColorVariation];
@@ -816,18 +912,27 @@ CVehicleModelInfo::AvoidSameVehicleColour(uint8 *col1, uint8 *col2)
{
int i, n;
- if(m_numColours > 1)
- for(i = 0; i < 8; i++){
- if(*col1 != m_lastColour1 || *col2 != m_lastColour2)
- break;
- n = CGeneral::GetRandomNumberInRange(0, m_numColours);
- *col1 = m_colours1[n];
- *col2 = m_colours2[n];
- }
- m_lastColour1 = *col1;
- m_lastColour2 = *col2;
+ if(gbBlackCars){
+ *col1 = 0;
+ *col2 = 0;
+ }else if(gbPinkCars){
+ *col1 = 68;
+ *col2 = 68;
+ }else{
+ if(m_numColours > 1)
+ for(i = 0; i < 8; i++){
+ if(*col1 != m_lastColour1 || *col2 != m_lastColour2)
+ break;
+ n = CGeneral::GetRandomNumberInRange(0, m_numColours);
+ *col1 = m_colours1[n];
+ *col2 = m_colours2[n];
+ }
+ m_lastColour1 = *col1;
+ m_lastColour2 = *col2;
+ }
}
+// unused
RwTexture*
CreateCarColourTexture(uint8 r, uint8 g, uint8 b)
{
@@ -916,7 +1021,7 @@ CVehicleModelInfo::LoadVehicleColours(void)
if(section == NONE){
if(line[start] == 'c' && line[start + 1] == 'o' && line[start + 2] == 'l')
section = COLOURS;
- else if(line[start] == 'c' && line[start + 1] == 'a' && line[start + 2] == 'r')
+ if(line[start] == 'c' && line[start + 1] == 'a' && line[start + 2] == 'r')
section = CARS;
}else if(line[start] == 'e' && line[start + 1] == 'n' && line[start + 2] == 'd'){
section = NONE;
@@ -927,7 +1032,6 @@ CVehicleModelInfo::LoadVehicleColours(void)
ms_vehicleColourTable[numCols].green = g;
ms_vehicleColourTable[numCols].blue = b;
ms_vehicleColourTable[numCols].alpha = 0xFF;
- ms_colourTextureTable[numCols] = CreateCarColourTexture(r, g, b);
numCols++;
}else if(section == CARS){
n = sscanf(&line[start], // BUG: games doesn't add start
@@ -962,63 +1066,49 @@ CVehicleModelInfo::DeleteVehicleColourTextures(void)
for(i = 0; i < 256; i++){
if(ms_colourTextureTable[i]){
RwTextureDestroy(ms_colourTextureTable[i]);
-#if GTA_VERSION >= GTA3_PC_11
ms_colourTextureTable[i] = nil;
-#endif
}
}
}
RpMaterial*
-CVehicleModelInfo::HasSpecularMaterialCB(RpMaterial *material, void *data)
+CVehicleModelInfo::GetMatFXEffectMaterialCB(RpMaterial *material, void *data)
{
- if(RpMaterialGetSurfaceProperties(material)->specular <= 0.0f)
+ if(RpMatFXMaterialGetEffects(material) == rpMATFXEFFECTNULL)
return material;
- *(bool*)data = true;
+ *(int*)data = RpMatFXMaterialGetEffects(material);
return nil;
}
RpMaterial*
-CVehicleModelInfo::SetEnvironmentMapCB(RpMaterial *material, void *data)
+CVehicleModelInfo::SetDefaultEnvironmentMapCB(RpMaterial *material, void *data)
{
- float spec;
-
- spec = RpMaterialGetSurfaceProperties(material)->specular;
- if(spec <= 0.0f)
- RpMatFXMaterialSetEffects(material, rpMATFXEFFECTNULL);
- else{
+ if(RpMatFXMaterialGetEffects(material) == rpMATFXEFFECTENVMAP){
+ RpMatFXMaterialSetEnvMapFrame(material, pMatFxIdentityFrame);
if(RpMaterialGetTexture(material) == nil)
RpMaterialSetTexture(material, gpWhiteTexture);
RpMatFXMaterialSetEffects(material, rpMATFXEFFECTENVMAP);
#ifndef PS2_MATFX
- spec *= 0.5f; // Tone down a bit for PC
+ float coef = RpMatFXMaterialGetEnvMapCoefficient(material);
+ coef *= 0.25f; // Tone down a bit for PC
+ RpMatFXMaterialSetEnvMapCoefficient(material, coef);
#endif
- RpMatFXMaterialSetupEnvMap(material, (RwTexture*)data, pMatFxIdentityFrame, false, spec);
}
return material;
}
-bool initialised;
-
RpAtomic*
CVehicleModelInfo::SetEnvironmentMapCB(RpAtomic *atomic, void *data)
{
- bool hasSpec;
+ int fx;
RpGeometry *geo;
geo = RpAtomicGetGeometry(atomic);
- hasSpec = 0;
- RpGeometryForAllMaterials(geo, HasSpecularMaterialCB, &hasSpec);
- if(hasSpec){
- RpGeometryForAllMaterials(geo, SetEnvironmentMapCB, data);
- RpGeometrySetFlags(geo, RpGeometryGetFlags(geo) | rpGEOMETRYMODULATEMATERIALCOLOR);
+ fx = rpMATFXEFFECTNULL;
+ RpGeometryForAllMaterials(geo, GetMatFXEffectMaterialCB, &fx);
+ if(fx != rpMATFXEFFECTNULL){
RpMatFXAtomicEnableEffects(atomic);
-#ifdef GTA_PS2
- if(!initialised){
- SetupPS2ManagerLightingCallback(RpAtomicGetInstancePipeline(atomic));
- initialised = true;
- }
-#endif
+ RpGeometryForAllMaterials(geo, SetDefaultEnvironmentMapCB, data);
}
return atomic;
}
@@ -1030,20 +1120,18 @@ CVehicleModelInfo::SetEnvironmentMap(void)
int32 i;
if(pMatFxIdentityFrame == nil){
+ RwV3d axis = { 1.0f, 0.0f, 0.0f };
pMatFxIdentityFrame = RwFrameCreate();
- RwMatrixSetIdentity(RwFrameGetMatrix(pMatFxIdentityFrame));
+ RwMatrixRotate(RwFrameGetMatrix(pMatFxIdentityFrame), &axis, 60.0f, rwCOMBINEREPLACE);
RwFrameUpdateObjects(pMatFxIdentityFrame);
RwFrameGetLTM(pMatFxIdentityFrame);
}
- if(m_envMap != ms_pEnvironmentMaps[0]){
- m_envMap = ms_pEnvironmentMaps[0];
- RpClumpForAllAtomics(m_clump, SetEnvironmentMapCB, m_envMap);
- if(m_wheelId != -1){
- wheelmi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(m_wheelId);
- for(i = 0; i < wheelmi->m_numAtomics; i++)
- SetEnvironmentMapCB(wheelmi->m_atomics[i], m_envMap);
- }
+ RpClumpForAllAtomics(m_clump, SetEnvironmentMapCB, nil);
+ if(m_wheelId != -1){
+ wheelmi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(m_wheelId);
+ for(i = 0; i < wheelmi->m_numAtomics; i++)
+ SetEnvironmentMapCB(wheelmi->m_atomics[i], nil);
}
#ifdef EXTENDED_PIPELINES
@@ -1054,24 +1142,11 @@ CVehicleModelInfo::SetEnvironmentMap(void)
void
CVehicleModelInfo::LoadEnvironmentMaps(void)
{
- const char *texnames[] = {
- "reflection01", // only one used
- "reflection02",
- "reflection03",
- "reflection04",
- "reflection05",
- "reflection06",
- };
int32 txdslot;
- int32 i;
txdslot = CTxdStore::FindTxdSlot("particle");
CTxdStore::PushCurrentTxd();
CTxdStore::SetCurrentTxd(txdslot);
- for(i = 0; i < NUM_VEHICLE_ENVMAPS; i++){
- ms_pEnvironmentMaps[i] = RwTextureRead(texnames[i], nil);
- RwTextureSetFilterMode(ms_pEnvironmentMaps[i], rwFILTERLINEAR);
- }
if(gpWhiteTexture == nil){
gpWhiteTexture = RwTextureRead("white", nil);
RwTextureGetName(gpWhiteTexture)[0] = '@';
@@ -1083,14 +1158,8 @@ CVehicleModelInfo::LoadEnvironmentMaps(void)
void
CVehicleModelInfo::ShutdownEnvironmentMaps(void)
{
- int32 i;
-
- // ignoring "initialised" as that's a PS2 thing only
RwTextureDestroy(gpWhiteTexture);
gpWhiteTexture = nil;
- for(i = 0; i < NUM_VEHICLE_ENVMAPS; i++)
- if(ms_pEnvironmentMaps[i])
- RwTextureDestroy(ms_pEnvironmentMaps[i]);
RwFrameDestroy(pMatFxIdentityFrame);
pMatFxIdentityFrame = nil;
}
@@ -1107,12 +1176,15 @@ CVehicleModelInfo::GetMaximumNumberOfPassengersFromNumberOfDoors(int id)
case MI_FIRETRUCK:
n = 2;
break;
+ case MI_HUNTER:
+ n = 1;
+ break;
default:
n = ((CVehicleModelInfo*)CModelInfo::GetModelInfo(id))->m_numDoors;
}
if(n == 0)
- return id == MI_RCBANDIT ? 0 : 1;
+ return id == MI_RCBANDIT || id == MI_PIZZABOY || id == MI_BAGGAGE ? 0 : 1;
if(id == MI_COACH)
return 8;
diff --git a/src/modelinfo/VehicleModelInfo.h b/src/modelinfo/VehicleModelInfo.h
index e6ba576d..c7a41126 100644
--- a/src/modelinfo/VehicleModelInfo.h
+++ b/src/modelinfo/VehicleModelInfo.h
@@ -3,10 +3,9 @@
#include "ClumpModelInfo.h"
enum {
- NUM_FIRST_MATERIALS = 26,
- NUM_SECOND_MATERIALS = 26,
+ NUM_FIRST_MATERIALS = 24,
+ NUM_SECOND_MATERIALS = 20,
NUM_VEHICLE_COLOURS = 8,
- NUM_VEHICLE_ENVMAPS = 1
};
enum {
@@ -41,13 +40,6 @@ enum eCarPositions
CAR_POS_TAILLIGHTS,
CAR_POS_FRONTSEAT,
CAR_POS_BACKSEAT,
- // these are unused so we don't know the actual values
- CAR_POS_REVERSELIGHTS,
- CAR_POS_BRAKELIGHTS,
- CAR_POS_INDICATORS_FRONT,
- CAR_POS_INDICATORS_BACK,
- CAR_POS_STEERWHEEL,
- //
CAR_POS_EXHAUST
};
@@ -73,7 +65,7 @@ enum ePlanePositions
};
enum {
- NUM_VEHICLE_POSITIONS = 10
+ NUM_VEHICLE_POSITIONS = 5
};
class CVehicleModelInfo : public CClumpModelInfo
@@ -81,17 +73,19 @@ class CVehicleModelInfo : public CClumpModelInfo
public:
uint8 m_lastColour1;
uint8 m_lastColour2;
- char m_gameName[32];
+ char m_gameName[10];
int32 m_vehicleType;
+ float m_wheelScale;
union {
- int32 m_wheelId;
- int32 m_planeLodId;
+ int16 m_wheelId;
+ int16 m_planeLodId;
};
- float m_wheelScale;
- int32 m_numDoors;
- int32 m_handlingId;
- int32 m_vehicleClass;
- int32 m_level;
+ int16 m_handlingId;
+ int8 m_numDoors;
+ int8 m_vehicleClass;
+ int8 m_level;
+ int8 m_numComps;
+ int16 m_frequency;
CVector m_positions[NUM_VEHICLE_POSITIONS];
uint32 m_compRules;
float m_bikeSteerAngle;
@@ -103,13 +97,15 @@ public:
uint8 m_lastColorVariation;
uint8 m_currentColour1;
uint8 m_currentColour2;
- RwTexture *m_envMap;
RpAtomic *m_comps[6];
- int32 m_numComps;
+ // This is stupid, CClumpModelInfo already has it!
+ union {
+ int32 m_animFileIndex;
+ char *m_animFileName;
+ };
static int8 ms_compsToUse[2];
static int8 ms_compsUsed[2];
- static RwTexture *ms_pEnvironmentMaps[NUM_VEHICLE_ENVMAPS];
static RwRGBA ms_vehicleColourTable[256];
static RwTexture *ms_colourTextureTable[256];
static RwObjectNameIdAssocation *ms_vehicleDescs[NUM_VEHICLE_TYPES];
@@ -118,6 +114,9 @@ public:
void DeleteRwObject(void);
RwObject *CreateInstance(void);
void SetClump(RpClump *);
+ void SetAnimFile(const char *file);
+ void ConvertAnimFileIndex(void);
+ int GetAnimFileIndex(void) { return m_animFileIndex; }
static RwFrame *CollapseFramesCB(RwFrame *frame, void *data);
static RwObject *MoveObjectsCB(RwObject *object, void *data);
@@ -130,6 +129,7 @@ public:
static RpAtomic *SetAtomicRendererCB_Train(RpAtomic *atomic, void *data);
static RpAtomic *SetAtomicRendererCB_Boat(RpAtomic *atomic, void *data);
static RpAtomic *SetAtomicRendererCB_Heli(RpAtomic *atomic, void *data);
+ static RpAtomic *SetAtomicRendererCB_RealHeli(RpAtomic *atomic, void *data);
void SetAtomicRenderCallbacks(void);
static RwObject *SetAtomicFlagCB(RwObject *object, void *data);
@@ -152,8 +152,8 @@ public:
static void DeleteVehicleColourTextures(void);
static RpAtomic *SetEnvironmentMapCB(RpAtomic *atomic, void *data);
- static RpMaterial *SetEnvironmentMapCB(RpMaterial *material, void *data);
- static RpMaterial *HasSpecularMaterialCB(RpMaterial *material, void *data);
+ static RpMaterial *SetDefaultEnvironmentMapCB(RpMaterial *material, void *data);
+ static RpMaterial *GetMatFXEffectMaterialCB(RpMaterial *material, void *data);
void SetEnvironmentMap(void);
static void LoadEnvironmentMaps(void);
static void ShutdownEnvironmentMaps(void);
@@ -162,4 +162,5 @@ public:
static void SetComponentsToUse(int8 c1, int8 c2) { ms_compsToUse[0] = c1; ms_compsToUse[1] = c2; }
};
-VALIDATE_SIZE(CVehicleModelInfo, 0x1F8);
+extern bool gbBlackCars;
+extern bool gbPinkCars;
diff --git a/src/modelinfo/WeaponModelInfo.cpp b/src/modelinfo/WeaponModelInfo.cpp
new file mode 100644
index 00000000..d9294c3f
--- /dev/null
+++ b/src/modelinfo/WeaponModelInfo.cpp
@@ -0,0 +1,53 @@
+#include "common.h"
+
+#include "ModelInfo.h"
+#include "AnimManager.h"
+#include "VisibilityPlugins.h"
+
+void
+CWeaponModelInfo::SetAnimFile(const char *file)
+{
+ if(strcasecmp(file, "null") == 0)
+ return;
+
+ m_animFileName = new char[strlen(file)+1];
+ strcpy(m_animFileName, file);
+}
+
+void
+CWeaponModelInfo::ConvertAnimFileIndex(void)
+{
+ if(m_animFileIndex != -1){
+ // we have a string pointer in that union
+ int32 index = CAnimManager::GetAnimationBlockIndex(m_animFileName);
+ delete[] m_animFileName;
+ m_animFileIndex = index;
+ }
+}
+
+void
+CWeaponModelInfo::Init(void)
+{
+ CSimpleModelInfo::Init();
+ SetWeaponInfo(0);
+}
+
+void
+CWeaponModelInfo::SetWeaponInfo(int32 weaponId)
+{
+ m_atomics[2] = (RpAtomic*)weaponId;
+}
+
+eWeaponType
+CWeaponModelInfo::GetWeaponInfo(void)
+{
+ return (eWeaponType)(uintptr)m_atomics[2];
+}
+
+void
+CWeaponModelInfo::SetAtomic(int n, RpAtomic *atomic)
+{
+ CSimpleModelInfo::SetAtomic(n, atomic);
+ CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderWeaponCB);
+}
+
diff --git a/src/modelinfo/WeaponModelInfo.h b/src/modelinfo/WeaponModelInfo.h
new file mode 100644
index 00000000..548bf8a6
--- /dev/null
+++ b/src/modelinfo/WeaponModelInfo.h
@@ -0,0 +1,23 @@
+#pragma once
+
+#include "SimpleModelInfo.h"
+#include "WeaponType.h"
+
+class CWeaponModelInfo : public CSimpleModelInfo
+{
+ union {
+ int32 m_animFileIndex;
+ char *m_animFileName;
+ };
+public:
+ CWeaponModelInfo(void) : CSimpleModelInfo(MITYPE_WEAPON) { m_animFileIndex = -1; }
+
+ virtual void SetAnimFile(const char *file);
+ virtual void ConvertAnimFileIndex(void);
+ virtual int GetAnimFileIndex(void) { return m_animFileIndex; }
+ virtual void SetAtomic(int n, RpAtomic *atomic);
+
+ void Init(void);
+ void SetWeaponInfo(int32 weaponId);
+ eWeaponType GetWeaponInfo(void);
+};
diff --git a/src/modelinfo/XtraCompsModelInfo.h b/src/modelinfo/XtraCompsModelInfo.h
deleted file mode 100644
index ab308a8a..00000000
--- a/src/modelinfo/XtraCompsModelInfo.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#pragma once
-
-#include "ClumpModelInfo.h"
-
-class CXtraCompsModelInfo : public CClumpModelInfo
-{
- int field_34;
-public:
- CXtraCompsModelInfo(void) : CClumpModelInfo(MITYPE_XTRACOMPS) { field_34 = 0; }
- void Shutdown(void) {};
- RwObject *CreateInstance(void) { return nil; }
- void SetClump(RpClump*) {};
-}; \ No newline at end of file
diff --git a/src/objects/CutsceneHead.cpp b/src/objects/CutsceneHead.cpp
deleted file mode 100644
index 19b3a592..00000000
--- a/src/objects/CutsceneHead.cpp
+++ /dev/null
@@ -1,230 +0,0 @@
-#include "common.h"
-#include <rpskin.h>
-
-#include "main.h"
-#include "RwHelper.h"
-#include "RpAnimBlend.h"
-#include "AnimBlendClumpData.h"
-#include "Bones.h"
-#include "Directory.h"
-#include "CutsceneMgr.h"
-#include "Streaming.h"
-#include "CutsceneHead.h"
-#include "CdStream.h"
-
-#ifdef GTA_PS2_STUFF
-// this is a total hack to switch between PC and PS2 code
-static bool lastLoadedSKA;
-#endif
-
-CCutsceneHead::CCutsceneHead(CObject *obj)
-{
- RpAtomic *atm;
-
- assert(RwObjectGetType(obj->m_rwObject) == rpCLUMP);
-#ifdef PED_SKIN
- unk1 = 0;
- bIsSkinned = false;
- m_parentObject = (CCutsceneObject*)obj;
- // Hide original head
- if(IsClumpSkinned(obj->GetClump())){
- m_parentObject->SetRenderHead(false);
- bIsSkinned = true;
- }else
-#endif
- {
- m_pHeadNode = RpAnimBlendClumpFindFrame((RpClump*)obj->m_rwObject, "Shead")->frame;
- atm = (RpAtomic*)GetFirstObject(m_pHeadNode);
- if(atm){
- assert(RwObjectGetType((RwObject*)atm) == rpATOMIC);
- RpAtomicSetFlags(atm, RpAtomicGetFlags(atm) & ~rpATOMICRENDER);
- }
- }
-}
-
-void
-CCutsceneHead::CreateRwObject(void)
-{
- RpAtomic *atm;
-
- CEntity::CreateRwObject();
- assert(RwObjectGetType(m_rwObject) == rpCLUMP);
- atm = GetFirstAtomic((RpClump*)m_rwObject);
- RpSkinAtomicSetHAnimHierarchy(atm, RpHAnimFrameGetHierarchy(GetFirstChild(RpClumpGetFrame((RpClump*)m_rwObject))));
-}
-
-void
-CCutsceneHead::DeleteRwObject(void)
-{
- CEntity::DeleteRwObject();
-}
-
-void
-CCutsceneHead::ProcessControl(void)
-{
- RpAtomic *atm;
- RpHAnimHierarchy *hier;
-
- // android/xbox calls is at the end
- CPhysical::ProcessControl();
-
-#ifdef PED_SKIN
- if(bIsSkinned){
- UpdateRpHAnim();
- UpdateRwFrame();
-
- RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(m_parentObject->GetClump());
- int idx = RpHAnimIDGetIndex(hier, BONE_head);
- RwMatrix *mat = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
- if(RwV3dLength(&mat->pos) > 100.0f){
- m_matrix.SetRotateY(PI/2);
- m_matrix = CMatrix(mat) * m_matrix;
- }
- }else
-#endif
- {
- m_matrix.SetRotateY(PI/2);
- m_matrix = CMatrix(RwFrameGetLTM(m_pHeadNode)) * m_matrix;
- }
-
- assert(RwObjectGetType(m_rwObject) == rpCLUMP);
- atm = GetFirstAtomic((RpClump*)m_rwObject);
- hier = RpSkinAtomicGetHAnimHierarchy(atm);
-#ifdef GTA_PS2_STUFF
- // PS2 only plays anims in cutscene, PC always plays anims
- if(!lastLoadedSKA || CCutsceneMgr::IsRunning())
-#endif
- RpHAnimHierarchyAddAnimTime(hier, CTimer::GetTimeStepNonClippedInSeconds());
-}
-
-void
-CCutsceneHead::Render(void)
-{
- RpAtomic *atm;
-
-#ifdef PED_SKIN
- if(bIsSkinned){
- RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(m_parentObject->GetClump());
- RpHAnimHierarchyUpdateMatrices(hier);
- int idx = RpHAnimIDGetIndex(hier, BONE_head);
- RwMatrix *mat = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
- if(RwV3dLength(&mat->pos) > 100.0f){
- m_matrix.SetRotateY(PI/2);
- m_matrix = CMatrix(mat) * m_matrix;
- }
- // This is head...it has no limbs
-#ifndef FIX_BUGS
- RenderLimb(BONE_Lhand);
- RenderLimb(BONE_Rhand);
-#endif
- }else
-#endif
- {
- m_matrix.SetRotateY(PI/2);
- m_matrix = CMatrix(RwFrameGetLTM(m_pHeadNode)) * m_matrix;
- }
-
- UpdateRwFrame();
-
- assert(RwObjectGetType(m_rwObject) == rpCLUMP);
- atm = GetFirstAtomic((RpClump*)m_rwObject);
- RpHAnimHierarchyUpdateMatrices(RpSkinAtomicGetHAnimHierarchy(atm));
-
- CObject::Render();
-}
-
-#ifdef PED_SKIN
-void
-CCutsceneHead::RenderLimb(int32 bone)
-{
- // It's not clear what this is...
- // modelinfo for this object is not a ped so it also doesn't have any limbs
-#ifndef FIX_BUGS
- RpAtomic *atomic;
- RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(m_parentObject->GetClump());
- int idx = RpHAnimIDGetIndex(hier, bone);
- RwMatrix *mats = RpHAnimHierarchyGetMatrixArray(hier);
- CPedModelInfo *mi = (CPedModelInfo*)CModelInfo::GetModelInfo(GetModelIndex());
- assert(mi->GetModelType() == MITYPE_PED);
- switch(bone){
- case BONE_Lhand:
- atomic = mi->getLeftHand();
- break;
- case BONE_Rhand:
- atomic = mi->getRightHand();
- break;
- default:
- return;
- }
- if(atomic){
- RwFrame *frame = RpAtomicGetFrame(atomic);
- RwMatrixTransform(RwFrameGetMatrix(frame), &mats[idx], rwCOMBINEREPLACE);
- RwFrameUpdateObjects(frame);
- RpAtomicRender(atomic);
- }
-#endif
-}
-#endif
-
-void
-CCutsceneHead::PlayAnimation(const char *animName)
-{
- RpAtomic *atm;
- RpHAnimHierarchy *hier;
- RpHAnimAnimation *anim;
- uint32 offset, size;
- RwStream *stream;
-
-#ifdef GTA_PS2_STUFF
- lastLoadedSKA = false;
-#endif
-
- assert(RwObjectGetType(m_rwObject) == rpCLUMP);
- atm = GetFirstAtomic((RpClump*)m_rwObject);
- hier = RpSkinAtomicGetHAnimHierarchy(atm);
-
- sprintf(gString, "%s.anm", animName);
-
- if(CCutsceneMgr::ms_pCutsceneDir->FindItem(gString, offset, size)){
- stream = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMREAD, "ANIM\\CUTS.IMG");
- assert(stream);
-
- CStreaming::MakeSpaceFor(size * CDSTREAM_SECTOR_SIZE);
- CStreaming::ImGonnaUseStreamingMemory();
-
- RwStreamSkip(stream, offset*2048);
- if(RwStreamFindChunk(stream, rwID_HANIMANIMATION, nil, nil)){
- anim = RpHAnimAnimationStreamRead(stream);
- RpHAnimHierarchySetCurrentAnim(hier, anim);
- }
-
- CStreaming::IHaveUsedStreamingMemory();
-
- RwStreamClose(stream, nil);
- }
-#ifdef GTA_PS2_STUFF
-#ifdef LIBRW
- else{
- sprintf(gString, "%s.ska", animName);
-
- if(CCutsceneMgr::ms_pCutsceneDir->FindItem(gString, offset, size)){
- stream = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMREAD, "ANIM\\CUTS.IMG");
- assert(stream);
-
- CStreaming::MakeSpaceFor(size * CDSTREAM_SECTOR_SIZE);
- CStreaming::ImGonnaUseStreamingMemory();
-
- RwStreamSkip(stream, offset*2048);
- anim = rw::Animation::streamReadLegacy(stream);
- RpHAnimHierarchySetCurrentAnim(hier, anim);
-
- CStreaming::IHaveUsedStreamingMemory();
-
- RwStreamClose(stream, nil);
-
- lastLoadedSKA = true;
- }
- }
-#endif
-#endif
-}
diff --git a/src/objects/CutsceneHead.h b/src/objects/CutsceneHead.h
deleted file mode 100644
index c931eb01..00000000
--- a/src/objects/CutsceneHead.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#pragma once
-
-#include "CutsceneObject.h"
-
-class CCutsceneHead : public CCutsceneObject
-{
-public:
- RwFrame *m_pHeadNode;
-#ifdef PED_SKIN
- int32 unk1;
- CCutsceneObject *m_parentObject;
- int32 unk2;
- int32 bIsSkinned;
-#endif
-
- CCutsceneHead(CObject *obj);
-
- void CreateRwObject(void);
- void DeleteRwObject(void);
- void ProcessControl(void);
- void Render(void);
- void RenderLimb(int32 bone);
-
- void PlayAnimation(const char *animName);
-};
-#ifndef PED_SKIN
-VALIDATE_SIZE(CCutsceneHead, 0x19C);
-#endif
diff --git a/src/objects/CutsceneObject.cpp b/src/objects/CutsceneObject.cpp
index 64e57805..7d9fe640 100644
--- a/src/objects/CutsceneObject.cpp
+++ b/src/objects/CutsceneObject.cpp
@@ -11,7 +11,11 @@
#include "ModelIndices.h"
#include "Shadows.h"
#include "Timecycle.h"
+#include "CutsceneShadow.h"
#include "CutsceneObject.h"
+#include "ModelIndices.h"
+#include "RpAnimBlend.h"
+
CCutsceneObject::CCutsceneObject(void)
{
@@ -21,12 +25,19 @@ CCutsceneObject::CCutsceneObject(void)
ObjectCreatedBy = CUTSCENE_OBJECT;
m_fMass = 1.0f;
m_fTurnMass = 1.0f;
+
+ m_pAttachTo = nil;
+ m_pAttachmentObject = nil;
+ m_pShadow = nil;
+}
-#ifdef PED_SKIN
- bRenderHead = true;
- bRenderRightHand = true;
- bRenderLeftHand = true;
-#endif
+CCutsceneObject::~CCutsceneObject(void)
+{
+ if ( m_pShadow )
+ {
+ delete m_pShadow;
+ m_pShadow = nil;
+ }
}
void
@@ -40,21 +51,37 @@ CCutsceneObject::SetModelIndex(uint32 id)
}
void
+CCutsceneObject::CreateShadow(void)
+{
+ if ( IsPedModel(GetModelIndex()) )
+ {
+ m_pShadow = new CCutsceneShadow();
+ if (!m_pShadow->IsInitialized())
+ m_pShadow->Create(m_rwObject, 6, true, 4, true);
+ }
+}
+
+void
CCutsceneObject::ProcessControl(void)
{
CPhysical::ProcessControl();
- if(CTimer::GetTimeStep() < 1/100.0f)
- m_vecMoveSpeed *= 100.0f;
+ if ( m_pAttachTo )
+ {
+ if ( m_pAttachmentObject )
+ GetMatrix() = CMatrix((RwMatrix*)m_pAttachTo);
+ else
+ GetMatrix() = CMatrix(RwFrameGetLTM((RwFrame*)m_pAttachTo));
+ }
else
- m_vecMoveSpeed *= 1.0f/CTimer::GetTimeStep();
-
- ApplyMoveSpeed();
-
-#ifdef PED_SKIN
- if(IsClumpSkinned(GetClump()))
- UpdateRpHAnim();
-#endif
+ {
+ if(CTimer::GetTimeStep() < 1/100.0f)
+ m_vecMoveSpeed *= 100.0f;
+ else
+ m_vecMoveSpeed *= 1.0f/CTimer::GetTimeStep();
+
+ ApplyMoveSpeed();
+ }
}
static RpMaterial*
@@ -67,14 +94,52 @@ MaterialSetAlpha(RpMaterial *material, void *data)
void
CCutsceneObject::PreRender(void)
{
- if(IsPedModel(GetModelIndex())){
- CShadows::StoreShadowForPedObject(this,
- CTimeCycle::m_fShadowDisplacementX[CTimeCycle::m_CurrentStoredValue],
- CTimeCycle::m_fShadowDisplacementY[CTimeCycle::m_CurrentStoredValue],
- CTimeCycle::m_fShadowFrontX[CTimeCycle::m_CurrentStoredValue],
- CTimeCycle::m_fShadowFrontY[CTimeCycle::m_CurrentStoredValue],
- CTimeCycle::m_fShadowSideX[CTimeCycle::m_CurrentStoredValue],
- CTimeCycle::m_fShadowSideY[CTimeCycle::m_CurrentStoredValue]);
+ if ( m_pAttachTo )
+ {
+ if ( m_pAttachmentObject )
+ {
+ m_pAttachmentObject->UpdateRpHAnim();
+ GetMatrix() = CMatrix((RwMatrix*)m_pAttachTo);
+ }
+ else
+ GetMatrix() = CMatrix(RwFrameGetLTM((RwFrame*)m_pAttachTo));
+
+ if ( RwObjectGetType(m_rwObject) == rpCLUMP && IsClumpSkinned(GetClump()) )
+ {
+ RpAtomic *atomic = GetFirstAtomic(GetClump());
+ atomic->boundingSphere.center = (*RPANIMBLENDCLUMPDATA(GetClump()))->frames[0].hanimFrame->t;
+ }
+ }
+
+ if ( RwObjectGetType(m_rwObject) == rpCLUMP )
+ UpdateRpHAnim();
+
+ if(IsPedModel(GetModelIndex()))
+ {
+ if ( m_pShadow == nil )
+ {
+ CShadows::StoreShadowForPedObject(this,
+ CTimeCycle::m_fShadowDisplacementX[CTimeCycle::m_CurrentStoredValue],
+ CTimeCycle::m_fShadowDisplacementY[CTimeCycle::m_CurrentStoredValue],
+ CTimeCycle::m_fShadowFrontX[CTimeCycle::m_CurrentStoredValue],
+ CTimeCycle::m_fShadowFrontY[CTimeCycle::m_CurrentStoredValue],
+ CTimeCycle::m_fShadowSideX[CTimeCycle::m_CurrentStoredValue],
+ CTimeCycle::m_fShadowSideY[CTimeCycle::m_CurrentStoredValue]);
+ }
+ else
+ {
+ if ( m_pShadow->IsInitialized() )
+ m_pShadow->UpdateForCutscene();
+
+ CShadows::StoreShadowForCutscenePedObject(this,
+ CTimeCycle::m_fShadowDisplacementX[CTimeCycle::m_CurrentStoredValue],
+ CTimeCycle::m_fShadowDisplacementY[CTimeCycle::m_CurrentStoredValue],
+ CTimeCycle::m_fShadowFrontX[CTimeCycle::m_CurrentStoredValue],
+ CTimeCycle::m_fShadowFrontY[CTimeCycle::m_CurrentStoredValue],
+ CTimeCycle::m_fShadowSideX[CTimeCycle::m_CurrentStoredValue],
+ CTimeCycle::m_fShadowSideY[CTimeCycle::m_CurrentStoredValue]);
+ }
+
// For some reason xbox/android limbs are transparent here...
RpGeometry *geometry = RpAtomicGetGeometry(GetFirstAtomic(GetClump()));
RpGeometrySetFlags(geometry, RpGeometryGetFlags(geometry) | rpGEOMETRYMODULATEMATERIALCOLOR);
@@ -85,47 +150,11 @@ CCutsceneObject::PreRender(void)
void
CCutsceneObject::Render(void)
{
-#ifdef PED_SKIN
- if(IsClumpSkinned(GetClump())){
- if(bRenderLeftHand) RenderLimb(BONE_Lhand);
- if(bRenderRightHand) RenderLimb(BONE_Rhand);
- if(bRenderHead) RenderLimb(BONE_head);
- }
-#endif
+ SetCullMode(rwCULLMODECULLNONE);
CObject::Render();
+ SetCullMode(rwCULLMODECULLBACK);
}
-#ifdef PED_SKIN
-void
-CCutsceneObject::RenderLimb(int32 bone)
-{
- RpAtomic *atomic;
- CPedModelInfo *mi = (CPedModelInfo *)CModelInfo::GetModelInfo(GetModelIndex());
- switch(bone){
- case BONE_head:
- atomic = mi->getHead();
- break;
- case BONE_Lhand:
- atomic = mi->getLeftHand();
- break;
- case BONE_Rhand:
- atomic = mi->getRightHand();
- break;
- default:
- return;
- }
- if(atomic){
- RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump());
- int idx = RpHAnimIDGetIndex(hier, bone);
- RwMatrix *mat = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
- RwFrame *frame = RpAtomicGetFrame(atomic);
- *RwFrameGetMatrix(frame) = *mat;
- RwFrameUpdateObjects(frame);
- RpAtomicRender(atomic);
- }
-}
-#endif
-
bool
CCutsceneObject::SetupLighting(void)
{
@@ -137,7 +166,7 @@ CCutsceneObject::SetupLighting(void)
}else{
CVector coors = GetPosition();
float lighting = CPointLights::GenerateLightsAffectingObject(&coors);
- if(!bHasBlip && lighting != 1.0f){
+ if(lighting != 1.0f){
SetAmbientAndDirectionalColours(lighting);
return true;
}
diff --git a/src/objects/CutsceneObject.h b/src/objects/CutsceneObject.h
index 407adcc7..af24c0a6 100644
--- a/src/objects/CutsceneObject.h
+++ b/src/objects/CutsceneObject.h
@@ -2,32 +2,23 @@
#include "Object.h"
+class CCutsceneShadow;
+
class CCutsceneObject : public CObject
{
public:
-#ifdef PED_SKIN
- bool bRenderHead;
- bool bRenderRightHand;
- bool bRenderLeftHand;
-
- bool GetRenderHead(void) { return bRenderHead; }
- bool GetRenderRightHand(void) { return bRenderRightHand; }
- bool GetRenderLeftHand(void) { return bRenderLeftHand; }
- void SetRenderHead(bool render) { bRenderHead = render; }
- void SetRenderRightHand(bool render) { bRenderRightHand = render; }
- void SetRenderLeftHand(bool render) { bRenderLeftHand = render; }
-#endif
-
+ CCutsceneShadow *m_pShadow;
+ void *m_pAttachTo;
+ CObject *m_pAttachmentObject;
+
CCutsceneObject(void);
+ ~CCutsceneObject(void);
void SetModelIndex(uint32 id);
+ void CreateShadow(void);
void ProcessControl(void);
void PreRender(void);
void Render(void);
- void RenderLimb(int32 bone);
bool SetupLighting(void);
void RemoveLighting(bool reset);
};
-#ifndef PED_SKIN
-VALIDATE_SIZE(CCutsceneObject, 0x198);
-#endif
diff --git a/src/objects/DummyObject.cpp b/src/objects/DummyObject.cpp
index d5805073..8dd1643d 100644
--- a/src/objects/DummyObject.cpp
+++ b/src/objects/DummyObject.cpp
@@ -10,4 +10,5 @@ CDummyObject::CDummyObject(CObject *obj)
AttachToRwObject(obj->m_rwObject);
obj->DetachFromRwObject();
m_level = obj->m_level;
+ m_area = obj->m_area;
}
diff --git a/src/objects/DummyObject.h b/src/objects/DummyObject.h
index d6f88335..680df685 100644
--- a/src/objects/DummyObject.h
+++ b/src/objects/DummyObject.h
@@ -10,5 +10,3 @@ public:
CDummyObject(void) {}
CDummyObject(CObject *obj);
};
-
-VALIDATE_SIZE(CDummyObject, 0x68);
diff --git a/src/objects/Object.cpp b/src/objects/Object.cpp
index 2a7de2c7..64c9e256 100644
--- a/src/objects/Object.cpp
+++ b/src/objects/Object.cpp
@@ -12,9 +12,18 @@
#include "World.h"
#include "Floater.h"
#include "soundlist.h"
+#include "WaterLevel.h"
+#include "Timecycle.h"
+#include "Stats.h"
+#include "SpecialFX.h"
+
+#define BEACHBALL_MAX_SCORE 250
+// the proportion of the ball speed compared to the player speed when it hits the player
+#define BEACHBALL_SPEED_PROPORTION 0.4f
int16 CObject::nNoTempObjects;
-int16 CObject::nBodyCastHealth = 1000;
+//int16 CObject::nBodyCastHealth = 1000;
+float CObject::fDistToNearestTree;
// Object pools tends to be full sometimes, let's free a temp. object in this case.
#ifdef FIX_BUGS
@@ -52,11 +61,12 @@ CObject::CObject(void)
m_bCameraToAvoidThisObject = false;
ObjectCreatedBy = UNKNOWN_OBJECT;
m_nEndOfLifeTime = 0;
-// m_nRefModelIndex = -1; // duplicate
-// bUseVehicleColours = false; // duplicate
+ // m_nRefModelIndex = -1; // duplicate
+ // bUseVehicleColours = false; // duplicate
m_colour2 = 0;
m_colour1 = m_colour2;
m_nBonusValue = 0;
+ m_nCostValue = 0;
bIsPickup = false;
bPickupObjWithMessage = false;
bOutOfStock = false;
@@ -65,8 +75,12 @@ CObject::CObject(void)
bHasBeenDamaged = false;
m_nRefModelIndex = -1;
bUseVehicleColours = false;
+ // bIsStreetLight = false; // duplicate
m_pCurSurface = nil;
m_pCollidingEntity = nil;
+ m_nBeachballBounces = 0;
+ bIsStreetLight = false;
+ m_area = AREA_EVERYWHERE;
}
CObject::CObject(int32 mi, bool createRW)
@@ -91,22 +105,23 @@ CObject::CObject(CDummyObject *dummy)
dummy->DetachFromRwObject();
Init();
m_level = dummy->m_level;
+ m_area = dummy->m_area;
}
CObject::~CObject(void)
{
CRadar::ClearBlipForEntity(BLIP_OBJECT, CPools::GetObjectPool()->GetIndex(this));
- if(m_nRefModelIndex != -1)
+ if (m_nRefModelIndex != -1)
CModelInfo::GetModelInfo(m_nRefModelIndex)->RemoveRef();
- if(ObjectCreatedBy == TEMP_OBJECT && nNoTempObjects != 0)
+ if (ObjectCreatedBy == TEMP_OBJECT && nNoTempObjects != 0)
nNoTempObjects--;
}
-void
-CObject::ProcessControl(void)
-{
+void
+CObject::ProcessControl(void)
+{
CVector point, impulse;
if (m_nCollisionDamageEffect)
ObjectDamage(m_fDamageImpulse);
@@ -120,7 +135,8 @@ CObject::ProcessControl(void)
m_vecMoveSpeed *= fTimeStep;
m_vecTurnSpeed *= fTimeStep;
}
- if ((GetModelIndex() == MI_EXPLODINGBARREL || GetModelIndex() == MI_PETROLPUMP) && bHasBeenDamaged && bIsVisible
+ int16 mi = GetModelIndex();
+ if ((mi == MI_EXPLODINGBARREL || mi == MI_PETROLPUMP || mi == MI_PETROLPUMP2) && bHasBeenDamaged && bIsVisible
&& (CGeneral::GetRandomNumber() & 0x1F) == 10) {
bExplosionProof = true;
bIsVisible = false;
@@ -128,11 +144,73 @@ CObject::ProcessControl(void)
bAffectedByGravity = false;
m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
}
+ if (mi == MI_RCBOMB) {
+ float fTurnForce = -(m_fTurnMass / 20.0f);
+ CPhysical::ApplyTurnForce(m_vecMoveSpeed * fTurnForce, -GetForward());
+ float fScalar = 1.0f - m_vecMoveSpeed.MagnitudeSqr() / 5.0f;
+ float fScalarTimed = Pow(fScalar, CTimer::GetTimeStep());
+ m_vecMoveSpeed *= fScalarTimed;
+ }
+ if (mi == MI_BEACHBALL) {
+ float fTimeStep = Pow(0.95f, CTimer::GetTimeStep());
+ float fPreviousVecSpeedMag = m_vecMoveSpeed.Magnitude2D();
+ m_vecMoveSpeed.x *= fTimeStep;
+ m_vecMoveSpeed.y *= fTimeStep;
+ m_vecMoveSpeed.z += fPreviousVecSpeedMag - m_vecMoveSpeed.Magnitude2D();
+ if (!FindPlayerVehicle()) {
+ CVector distance;
+ distance.x = FindPlayerCoors().x - GetPosition().x;
+ distance.y = FindPlayerCoors().y - GetPosition().y;
+ distance.z = FindPlayerCoors().z - GetPosition().z;
+ if (distance.z > 0.0 && distance.z < 1.5f && distance.Magnitude2D() < 1.0f) {
+ CVector playerSpeed = FindPlayerSpeed();
+ if (fPreviousVecSpeedMag < 0.05f && playerSpeed.Magnitude() > 0.1f) {
+ playerSpeed.z = 0.0f;
+ playerSpeed.Normalise();
+ playerSpeed.z = 0.3f;
+ m_vecMoveSpeed = CVector(
+ playerSpeed.x * BEACHBALL_SPEED_PROPORTION,
+ playerSpeed.y * BEACHBALL_SPEED_PROPORTION,
+ 0.3f * BEACHBALL_SPEED_PROPORTION
+ );
+ PlayOneShotScriptObject(SCRIPT_SOUND_HIT_BALL, GetPosition());
+ m_vecTurnSpeed += CVector(
+ ((CGeneral::GetRandomNumber() % 16) - 7) / 10.0f,
+ ((CGeneral::GetRandomNumber() % 16) - 7) / 10.0f,
+ 0.0f);
+ if (m_nBeachballBounces > 0) {
+ m_nBeachballBounces++;
+ }
+ if (m_nBeachballBounces > 0) {
+ sprintf(gString, "%d", m_nBeachballBounces);
+ CMoneyMessages::RegisterOne(GetPosition(), gString, 255, 50, 0, 0.6f, 0.5f);
+ CStats::RegisterHighestScore(3, m_nBeachballBounces);
+ }
+ }
+ }
+ if (distance.z > -1.05 && distance.z < -0.6 && m_vecMoveSpeed.z < 0.0f && distance.Magnitude2D() < 0.9f) {
+ m_vecMoveSpeed.x += (CGeneral::GetRandomNumber() % 8 - 3) / 100.0f;
+ m_vecMoveSpeed.y += (CGeneral::GetRandomNumber() % 8 - 3) / 100.0f;
+ m_vecMoveSpeed.z = Max(m_vecMoveSpeed.z + 0.3f, 0.2f);
+ PlayOneShotScriptObject(SCRIPT_SOUND_HIT_BALL, GetPosition());
+ m_vecTurnSpeed.x += (CGeneral::GetRandomNumber() % 16 - 7) / 10.0f;
+ m_vecTurnSpeed.y += (CGeneral::GetRandomNumber() % 16 - 7) / 10.0f;
+ m_nBeachballBounces++;
+ m_nBeachballBounces = Min(m_nBeachballBounces, BEACHBALL_MAX_SCORE);
+ sprintf(gString, "%d", m_nBeachballBounces);
+ CMoneyMessages::RegisterOne(GetPosition(), gString, 255, 50, 0, 0.6f, 0.5f);
+ CStats::RegisterHighestScore(3, m_nBeachballBounces);
+ }
+ }
+ }
+ if (bIsBIGBuilding) {
+ bIsInSafePosition = true;
+ }
}
-void
+void
CObject::Teleport(CVector vecPos)
-{
+{
CWorld::Remove(this);
GetMatrix().GetPosition() = vecPos;
GetMatrix().UpdateRW();
@@ -143,27 +221,131 @@ CObject::Teleport(CVector vecPos)
void
CObject::Render(void)
{
- if(bDoNotRender)
+ if (bDoNotRender)
return;
- if(m_nRefModelIndex != -1 && ObjectCreatedBy == TEMP_OBJECT && bUseVehicleColours){
+ if (m_nRefModelIndex != -1 && ObjectCreatedBy == TEMP_OBJECT && bUseVehicleColours) {
CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(m_nRefModelIndex);
assert(mi->GetModelType() == MITYPE_VEHICLE);
mi->SetVehicleColour(m_colour1, m_colour2);
}
+ float red = (0.8f * CTimeCycle::GetDirectionalRed() + CTimeCycle::GetAmbientRed_Obj()) * 165.75f;
+ float green = (0.8f * CTimeCycle::GetDirectionalGreen() + CTimeCycle::GetAmbientGreen_Obj()) * 165.75f;
+ float blue = (0.8f * CTimeCycle::GetDirectionalBlue() + CTimeCycle::GetAmbientBlue_Obj()) * 165.75f;
+
+ red = Clamp(red, 0.0f, 255.0f);
+ green = Clamp(green, 0.0f, 255.0f);
+ blue = Clamp(blue, 0.0f, 255.0f);
+
+ int alpha = CGeneral::GetRandomNumberInRange(196, 225);
+
+ RwRGBA color = { (uint8)red, (uint8)green, (uint8)blue, (uint8)alpha };
+
+ if (this->GetModelIndex() == MI_YT_MAIN_BODY) {
+ float moveSpeedMagnitude = this->GetMoveSpeed().Magnitude();
+ if (moveSpeedMagnitude > 0.0f) {
+ float scaleMax = GetColModel()->boundingBox.max.y * 0.85f;
+
+ CVector dir = this->GetMoveSpeed() + 0.3f * this->GetRight() - 0.5f * this->GetForward();
+ dir.z += 0.05f * moveSpeedMagnitude;
+
+ CVector pos = scaleMax * this->GetForward() + 2.25f * this->GetRight() + this->GetPosition();
+
+ float fWaterLevel;
+ CWaterLevel::GetWaterLevel(pos.x, pos.y, pos.z, &fWaterLevel, true);
+ pos.z = fWaterLevel + 0.75f;
+
+ CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, 1.2f * moveSpeedMagnitude, color,
+ CGeneral::GetRandomNumberInRange(0.0f, 0.4f), CGeneral::GetRandomNumberInRange(0.0f, 45.0f), 0, 0);
+
+ float scaleMin = GetColModel()->boundingBox.min.y;
+
+ dir = this->GetMoveSpeed() - 0.5f * this->GetForward();
+ dir.z += 0.05f * moveSpeedMagnitude;
+
+ pos = scaleMin * this->GetForward() + 4.5f * this->GetRight() + this->GetPosition();
+
+ CWaterLevel::GetWaterLevel(pos.x, pos.y, pos.z, &fWaterLevel, true);
+ pos.z = fWaterLevel + 0.55f;
+
+ CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, 0.9f, color,
+ CGeneral::GetRandomNumberInRange(0.0f, 0.4f), CGeneral::GetRandomNumberInRange(0.0f, 45.0f), 0, 0);
+
+ pos = scaleMin * 1.1f * this->GetForward() + 2.25f * this->GetRight() + this->GetPosition();
+
+ CWaterLevel::GetWaterLevel(pos.x, pos.y, pos.z, &fWaterLevel, true);
+ pos.z = fWaterLevel + 0.55f;
+
+ CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, 0.9f, color,
+ CGeneral::GetRandomNumberInRange(0.0f, 0.4f), CGeneral::GetRandomNumberInRange(0.0f, 45.0f), 0, 0);
+
+ pos = scaleMin * 1.1f * this->GetForward() - 0.05f * this->GetRight() + this->GetPosition();
+
+ CWaterLevel::GetWaterLevel(pos.x, pos.y, pos.z, &fWaterLevel, true);
+ pos.z = fWaterLevel + 0.55f;
+
+ CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, 0.9f, color,
+ CGeneral::GetRandomNumberInRange(0.0f, 0.4f), CGeneral::GetRandomNumberInRange(0.0f, 45.0f), 0, 0);
+ }
+ }
+
+ if (this->GetModelIndex() == MI_YT_MAIN_BODY2) {
+ float moveSpeedMagnitude = this->GetMoveSpeed().Magnitude();
+ if (moveSpeedMagnitude > 0.0f) {
+ float scaleMax = GetColModel()->boundingBox.max.y * 0.85f;
+
+ CVector dir = this->GetMoveSpeed() - 0.3f * this->GetRight() - 0.5f * this->GetForward();
+ dir.z += 0.05f * moveSpeedMagnitude;
+
+ CVector pos = scaleMax * this->GetForward() - 2.25f * this->GetRight() + this->GetPosition();
+
+ float fWaterLevel;
+ CWaterLevel::GetWaterLevel(pos.x, pos.y, pos.z, &fWaterLevel, true);
+ pos.z = fWaterLevel + 0.75f;
+
+ CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, 1.2f * moveSpeedMagnitude, color,
+ CGeneral::GetRandomNumberInRange(0.0f, 0.4f), CGeneral::GetRandomNumberInRange(0.0f, 45.0f), 0, 0);
+
+ float scaleMin = GetColModel()->boundingBox.min.y;
+
+ dir = this->GetMoveSpeed() - 0.5f * this->GetForward();
+ dir.z += 0.05f * moveSpeedMagnitude;
+
+ pos = scaleMin * this->GetForward() - 4.5f * this->GetRight() + this->GetPosition();
+
+ CWaterLevel::GetWaterLevel(pos.x, pos.y, pos.z, &fWaterLevel, true);
+ pos.z = fWaterLevel + 0.55f;
+
+ CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, 0.9f, color,
+ CGeneral::GetRandomNumberInRange(0.0f, 0.4f), CGeneral::GetRandomNumberInRange(0.0f, 45.0f), 0, 0);
+
+ pos = scaleMin * 1.1f * this->GetForward() - 2.25f * this->GetRight() + this->GetPosition();
+
+ CWaterLevel::GetWaterLevel(pos.x, pos.y, pos.z, &fWaterLevel, true);
+ pos.z = fWaterLevel + 0.55f;
+
+ CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, 0.9f, color,
+ CGeneral::GetRandomNumberInRange(0.0f, 0.4f), CGeneral::GetRandomNumberInRange(0.0f, 45.0f), 0, 0);
+ }
+ }
+
CEntity::Render();
}
bool
CObject::SetupLighting(void)
{
- DeActivateDirectional();
- SetAmbientColours();
-
- if(bRenderScorched){
+ if (bRenderScorched) {
WorldReplaceNormalLightsWithScorched(Scene.world, 0.1f);
return true;
+ } else if (bIsPickup) {
+ SetFullAmbient();
+ return true;
+ } else if (bIsWeapon) {
+ ActivateDirectional();
+ SetAmbientColoursForPedsCarsAndObjects();
+ return true;
}
return false;
}
@@ -171,17 +353,20 @@ CObject::SetupLighting(void)
void
CObject::RemoveLighting(bool reset)
{
- if(reset)
- WorldReplaceScorchedLightsWithNormal(Scene.world);
+ if (reset) {
+ SetAmbientColours();
+ DeActivateDirectional();
+ }
}
-void
-CObject::ObjectDamage(float amount)
+void
+CObject::ObjectDamage(float amount)
{
if (!m_nCollisionDamageEffect || !bUsesCollision)
return;
static int8 nFrameGen = 0;
bool bBodyCastDamageEffect = false;
+#if 0
if (GetModelIndex() == MI_BODYCAST) {
if (amount > 50.0f)
nBodyCastHealth = (int16)(nBodyCastHealth - 0.5f * amount);
@@ -191,133 +376,363 @@ CObject::ObjectDamage(float amount)
bBodyCastDamageEffect = true;
amount = 0.0f;
}
+#endif
if ((amount * m_fCollisionDamageMultiplier > 150.0f || bBodyCastDamageEffect) && m_nCollisionDamageEffect) {
const CVector& vecPos = GetMatrix().GetPosition();
const float fDirectionZ = 0.0002f * amount;
- switch (m_nCollisionDamageEffect)
- {
- case DAMAGE_EFFECT_CHANGE_MODEL:
- bRenderDamaged = true;
- break;
- case DAMAGE_EFFECT_SPLIT_MODEL:
- break;
- case DAMAGE_EFFECT_SMASH_COMPLETELY:
- bIsVisible = false;
- bUsesCollision = false;
- SetIsStatic(true);
- bExplosionProof = true;
- SetMoveSpeed(0.0f, 0.0f, 0.0f);
- SetTurnSpeed(0.0f, 0.0f, 0.0f);
- break;
- case DAMAGE_EFFECT_CHANGE_THEN_SMASH:
- if (!bRenderDamaged) {
+ switch (m_nCollisionDamageEffect) {
+ case DAMAGE_EFFECT_CHANGE_MODEL:
bRenderDamaged = true;
+ return;
+ case DAMAGE_EFFECT_SPLIT_MODEL:
+ return;
+ case DAMAGE_EFFECT_SMASH_AND_DAMAGE_TRAFFICLIGHTS:
+ {
+ static RwRGBA debrisColor = { 0xc8,0xc8,0xc8,0xff };
+ if (bRenderDamaged) {
+ break;
+ }
+ bRenderDamaged = true;
+ CVector min = 0.85f * GetColModel()->boundingBox.min;
+ CVector max = 0.85f * GetColModel()->boundingBox.max;
+ min.z = max.z;
+ min = GetMatrix() * min;
+ max = GetMatrix() * max;
+ CVector temp = (max - min) * 0.02f;
+ for (int32 i = 0; i < 50; i++) {
+ CVector vecDir = CVector(
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(0.10f, 0.25f)
+ );
+ ++nFrameGen;
+ int32 currentFrame = nFrameGen & 3;
+ CVector pos = min + temp * (float)i;
+ float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f);
+ float fColorFactor = CGeneral::GetRandomNumberInRange(0.6f, 1.2f);
+ RwRGBA color = debrisColor;
+ color.red *= fColorFactor;
+ color.green *= fColorFactor;
+ int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-0.40f, 0.40f);
+ CParticle::AddParticle(PARTICLE_CAR_DEBRIS, pos, vecDir, nil, fSize, color, nRotationSpeed, 0, currentFrame, 0);
+ }
+ PlayOneShotScriptObject(SCRIPT_SOUND_METAL_COLLISION, min);
+ break;
}
- else {
+ case DAMAGE_EFFECT_CHANGE_THEN_SMASH: {
+ if (!bRenderDamaged) {
+ bRenderDamaged = true;
+ return;
+ }
+ // fall through
+ }
+ case DAMAGE_EFFECT_SMASH_COMPLETELY: {
bIsVisible = false;
bUsesCollision = false;
+ if (!GetIsStatic()) {
+ RemoveFromMovingList();
+ }
SetIsStatic(true);
bExplosionProof = true;
SetMoveSpeed(0.0f, 0.0f, 0.0f);
SetTurnSpeed(0.0f, 0.0f, 0.0f);
+ break;
}
- break;
- case DAMAGE_EFFECT_SMASH_CARDBOARD_COMPLETELY: {
- bIsVisible = false;
- bUsesCollision = false;
- SetIsStatic(true);
- bExplosionProof = true;
- SetMoveSpeed(0.0f, 0.0f, 0.0f);
- SetTurnSpeed(0.0f, 0.0f, 0.0f);
- const RwRGBA color = { 96, 48, 0, 255 };
- for (int32 i = 0; i < 25; i++) {
- CVector vecDir(CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
- CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
- CGeneral::GetRandomNumberInRange(0.1f, 0.25f) + fDirectionZ);
- ++nFrameGen;
- int32 currentFrame = nFrameGen & 3;
- float fRandom = CGeneral::GetRandomNumberInRange(0.01f, 1.0f);
- RwRGBA randomColor = { uint8(color.red * fRandom), uint8(color.green * fRandom) , color.blue, color.alpha };
- float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f);
- int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40);
- CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, randomColor, nRotationSpeed, 0, currentFrame, 0);
+ case DAMAGE_EFFECT_SMASH_CARDBOARD_COMPLETELY:
+ case DAMAGE_EFFECT_SMASH_YELLOW_TARGET_COMPLETELY:
+ {
+ bIsVisible = false;
+ bUsesCollision = false;
+ if (!GetIsStatic()) {
+ RemoveFromMovingList();
+ }
+ SetIsStatic(true);
+ bExplosionProof = true;
+ SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ SetTurnSpeed(0.0f, 0.0f, 0.0f);
+ const RwRGBA color = { 96, 48, 0, 255 };
+ for (int32 i = 0; i < 25; i++) {
+ CVector vecDir = CVector(
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(0.10f, 0.25f) + fDirectionZ
+ );
+ ++nFrameGen;
+ int32 currentFrame = nFrameGen & 3;
+ RwRGBA randomColor = color;
+ switch (m_nCollisionDamageEffect) {
+ case DAMAGE_EFFECT_SMASH_CARDBOARD_COMPLETELY: {
+ float fRandom = CGeneral::GetRandomNumberInRange(0.01f, 1.0f);
+ randomColor.red *= fRandom;
+ randomColor.green *= fRandom;
+ randomColor.blue *= fRandom;
+ break;
+ }
+ case DAMAGE_EFFECT_SMASH_YELLOW_TARGET_COMPLETELY: {
+ randomColor.red = 0xff;
+ randomColor.green = 0xfc;
+ break;
+ }
+ }
+ float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f);
+ int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40);
+ CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, randomColor, nRotationSpeed, 0, currentFrame, 0);
+ }
+ PlayOneShotScriptObject(SCRIPT_SOUND_BOX_DESTROYED_2, vecPos);
+ break;
}
- PlayOneShotScriptObject(SCRIPT_SOUND_BOX_DESTROYED_2, vecPos);
- break;
- }
- case DAMAGE_EFFECT_SMASH_WOODENBOX_COMPLETELY: {
- bIsVisible = false;
- bUsesCollision = false;
- SetIsStatic(true);
- bExplosionProof = true;
- SetMoveSpeed(0.0f, 0.0f, 0.0f);
- SetTurnSpeed(0.0f, 0.0f, 0.0f);
- const RwRGBA color = { 128, 128, 128, 255 };
- for (int32 i = 0; i < 45; i++) {
- CVector vecDir(CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
- CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
- CGeneral::GetRandomNumberInRange(0.1f, 0.25f) + fDirectionZ);
- ++nFrameGen;
- int32 currentFrame = nFrameGen & 3;
- float fRandom = CGeneral::GetRandomNumberInRange(0.5f, 1.0f);
- RwRGBA randomColor = { uint8(color.red * fRandom), uint8(color.green * fRandom), uint8(color.blue * fRandom), color.alpha };
- float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f);
- int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40);
- CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, randomColor, nRotationSpeed, 0, currentFrame, 0);
+ case DAMAGE_EFFECT_SMASH_WOODENBOX_COMPLETELY:
+ {
+ bIsVisible = false;
+ bUsesCollision = false;
+ if (!GetIsStatic()) {
+ RemoveFromMovingList();
+ }
+ SetIsStatic(true);
+ bExplosionProof = true;
+ SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ SetTurnSpeed(0.0f, 0.0f, 0.0f);
+ static const RwRGBA color = { 128, 128, 128, 255 };
+ CVector position = GetPosition();
+ for (int32 i = 0; i < 45; i++) {
+ CVector vecDir = CVector(
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(0.10f, 0.25f) + fDirectionZ
+ );
+ ++nFrameGen;
+ int32 currentFrame = nFrameGen & 3;
+ float fRandom = CGeneral::GetRandomNumberInRange(0.5f, 1.0f);
+ RwRGBA randomColor = { uint8(color.red * fRandom), uint8(color.green * fRandom), uint8(color.blue * fRandom), color.alpha };
+ float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f);
+ int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40);
+ CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, randomColor, nRotationSpeed, 0, currentFrame, 0);
+ }
+ PlayOneShotScriptObject(SCRIPT_SOUND_BOX_DESTROYED_1, vecPos);
+ break;
}
- PlayOneShotScriptObject(SCRIPT_SOUND_BOX_DESTROYED_1, vecPos);
- break;
- }
- case DAMAGE_EFFECT_SMASH_TRAFFICCONE_COMPLETELY: {
- bIsVisible = false;
- bUsesCollision = false;
- SetIsStatic(true);
- bExplosionProof = true;
- SetMoveSpeed(0.0f, 0.0f, 0.0f);
- SetTurnSpeed(0.0f, 0.0f, 0.0f);
- const RwRGBA color1 = { 200, 0, 0, 255 };
- const RwRGBA color2 = { 200, 200, 200, 255 };
- for (int32 i = 0; i < 10; i++) {
- CVector vecDir(CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
- CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
- CGeneral::GetRandomNumberInRange(0.1f, 0.25f) + fDirectionZ);
- ++nFrameGen;
- int32 currentFrame = nFrameGen & 3;
- RwRGBA color = color2;
- if (nFrameGen & 1)
- color = color1;
- float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f);
- int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40);
- CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, color, nRotationSpeed, 0, currentFrame, 0);
+ case DAMAGE_EFFECT_SMASH_TRAFFICCONE_COMPLETELY:
+ case DAMAGE_EFFECT_BURST_BEACHBALL:
+ {
+ bIsVisible = false;
+ bUsesCollision = false;
+ if (!GetIsStatic()) {
+ RemoveFromMovingList();
+ }
+ SetIsStatic(true);
+ bExplosionProof = true;
+ SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ SetTurnSpeed(0.0f, 0.0f, 0.0f);
+ const RwRGBA color1 = { 200, 0, 0, 255 };
+ const RwRGBA color2 = { 200, 200, 200, 255 };
+ for (int32 i = 0; i < 10; i++) {
+ CVector vecDir = CVector(
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(0.10f, 0.25f) + fDirectionZ
+ );
+ ++nFrameGen;
+ int32 currentFrame = nFrameGen & 3;
+ RwRGBA color = color2;
+ if (nFrameGen & 1)
+ color = color1;
+ float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f);
+ int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40);
+ CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, color, nRotationSpeed, 0, currentFrame, 0);
+ }
+ if (m_nCollisionDamageEffect == DAMAGE_EFFECT_BURST_BEACHBALL) {
+ PlayOneShotScriptObject(SCRIPT_SOUND_HIT_BALL, vecPos);
+ } else {
+ PlayOneShotScriptObject(SCRIPT_SOUND_TIRE_COLLISION, vecPos);
+ }
+ break;
}
- PlayOneShotScriptObject(SCRIPT_SOUND_TIRE_COLLISION, vecPos);
- break;
- }
- case DAMAGE_EFFECT_SMASH_BARPOST_COMPLETELY: {
- bIsVisible = false;
- bUsesCollision = false;
- SetIsStatic(true);
- bExplosionProof = true;
- SetMoveSpeed(0.0f, 0.0f, 0.0f);
- SetTurnSpeed(0.0f, 0.0f, 0.0f);
- const RwRGBA color1 = { 200, 0, 0, 255 };
- const RwRGBA color2 = { 200, 200, 200, 255 };
- for (int32 i = 0; i < 32; i++) {
- CVector vecDir(CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
- CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
- CGeneral::GetRandomNumberInRange(0.1f, 0.25f) + fDirectionZ);
- ++nFrameGen;
- int32 currentFrame = nFrameGen & 3;
- RwRGBA color = color2;
- if (nFrameGen & 1)
- color = color1;
- float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f);
- int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40);
- CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, color, nRotationSpeed, 0, currentFrame, 0);
+ case DAMAGE_EFFECT_SMASH_BARPOST_COMPLETELY:
+ {
+ bIsVisible = false;
+ bUsesCollision = false;
+ if (!GetIsStatic()) {
+ RemoveFromMovingList();
+ }
+ SetIsStatic(true);
+ bExplosionProof = true;
+ SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ SetTurnSpeed(0.0f, 0.0f, 0.0f);
+ const RwRGBA color1 = { 200, 0, 0, 255 };
+ const RwRGBA color2 = { 200, 200, 200, 255 };
+ SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ SetTurnSpeed(0.0f, 0.0f, 0.0f);
+ for (int32 i = 0; i < 32; i++) {
+ CVector vecDir = CVector(
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(0.10f, 0.25f) + fDirectionZ
+ );
+ ++nFrameGen;
+ int32 currentFrame = nFrameGen & 3;
+ const RwRGBA &color = nFrameGen & 1 ? color1 : color2;
+ float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f);
+ int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40);
+ CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, color, nRotationSpeed, 0, currentFrame, 0);
+ }
+ PlayOneShotScriptObject(SCRIPT_SOUND_METAL_COLLISION, vecPos);
+ break;
}
- PlayOneShotScriptObject(SCRIPT_SOUND_METAL_COLLISION, vecPos);
- break;
- }
+ case DAMAGE_EFFECT_SMASH_NEWSTANDNEW1:
+ case DAMAGE_EFFECT_SMASH_NEWSTANDNEW2:
+ case DAMAGE_EFFECT_SMASH_NEWSTANDNEW3:
+ case DAMAGE_EFFECT_SMASH_NEWSTANDNEW4:
+ case DAMAGE_EFFECT_SMASH_NEWSTANDNEW5:
+ {
+ bIsVisible = false;
+ bUsesCollision = false;
+ if (!GetIsStatic()) {
+ RemoveFromMovingList();
+ }
+ SetIsStatic(true);
+ bExplosionProof = true;
+ SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ SetTurnSpeed(0.0f, 0.0f, 0.0f);
+ CRGBA possibleColor1;
+ CRGBA possibleColor2;
+ switch (m_nCollisionDamageEffect) {
+ case DAMAGE_EFFECT_SMASH_NEWSTANDNEW1:
+ possibleColor1 = CRGBA(0xC0, 0x3E, 0xC, 0xFF);
+ possibleColor2 = possibleColor1;
+ break;
+ case DAMAGE_EFFECT_SMASH_NEWSTANDNEW2:
+ possibleColor1 = CRGBA(0xA3, 0x36, 0x21, 0xFF);
+ possibleColor2 = possibleColor1;
+ break;
+ case DAMAGE_EFFECT_SMASH_NEWSTANDNEW3:
+ possibleColor1 = CRGBA(0x12, 0x31, 0x24, 0xFF);
+ possibleColor2 = possibleColor1;
+ break;
+ case DAMAGE_EFFECT_SMASH_NEWSTANDNEW4:
+ possibleColor1 = CRGBA(0xC0, 0xC8, 0xBE, 0xFF);
+ possibleColor2 = CRGBA(0x10, 0x57, 0x85, 0xFF);
+ break;
+ case DAMAGE_EFFECT_SMASH_NEWSTANDNEW5:
+ possibleColor1 = CRGBA(0xD0, 0x94, 0x1B, 0xFF);
+ possibleColor2 = possibleColor1;
+ break;
+ }
+ for (int32 i = 0; i < 16; i++) {
+ CVector vecDir(
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(0.10f, 0.15f) + fDirectionZ
+ );
+ float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f);
+ int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40);
+ ++nFrameGen;
+ int32 nCurFrame = nFrameGen & 0x3;
+ CRGBA &selectedColor = nFrameGen & 0x1 ? possibleColor1 : possibleColor2;
+ CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, selectedColor, nRotationSpeed, 0, nCurFrame, 0);
+ if (!(i % 7)) {
+ static CRGBA secondParticleColors[4] = {
+ CRGBA(0xA0, 0x60, 0x60, 0xFF),
+ CRGBA(0x60, 0xA0, 0x60, 0xFF),
+ CRGBA(0x60, 0x60, 0xA0, 0xFF),
+ CRGBA(0xA0, 0xA0, 0xA0, 0xFF)
+ };
+ vecDir *= 0.5f;
+ CRGBA &secondParticleColor = secondParticleColors[nFrameGen & 3];
+ int32 nSecondRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40);
+ CParticle::AddParticle(PARTICLE_DEBRIS, vecPos, vecDir, nil, 0.1f, secondParticleColor, nSecondRotationSpeed, 0, 1, 0);
+ }
+ }
+ PlayOneShotScriptObject(SCRIPT_SOUND_METAL_COLLISION, vecPos);
+ break;
+ }
+ case DAMAGE_EFFECT_SMASH_VEGPALM:
+ {
+ static RwRGBA primaryColor1 = { 0x39, 0x4D, 0x29, 0xff };
+ static RwRGBA primaryColor2 = { 0x94, 0x7D, 0x73, 0xff };
+ bIsVisible = false;
+ bUsesCollision = false;
+ if (!GetIsStatic()) {
+ RemoveFromMovingList();
+ }
+ SetIsStatic(true);
+ bExplosionProof = true;
+ SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ SetTurnSpeed(0.0f, 0.0f, 0.0f);
+ float fRadius = GetColModel()->boundingSphere.radius;
+ for (int32 i = 0; i < 32; i++) {
+ CVector particleDir = CVector(
+ CGeneral::GetRandomNumberInRange(-0.25f, 0.25f),
+ CGeneral::GetRandomNumberInRange(-0.25f, 0.25f),
+ CGeneral::GetRandomNumberInRange(-0.05f, 0.05f) + fDirectionZ
+ );
+ CVector particlePos = vecPos;
+ particlePos.z += CGeneral::GetRandomNumberInRange(0.0f, 1.0f) * fRadius;
+ ++nFrameGen;
+ int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40);
+ int32 nCurFrame = nFrameGen & 0x3;
+ float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f);
+ RwRGBA& particleColor = nFrameGen & 1 ? primaryColor1 : primaryColor2;
+ CParticle::AddParticle(PARTICLE_CAR_DEBRIS, particlePos, particleDir, nil, fSize, particleColor, nRotationSpeed, 0, nCurFrame, 0);
+ if ((i % 7) == 0) {
+ static RwRGBA secondaryColor = { 0x9A, 0x99, 0x99, 0x3E };
+ CParticle::AddParticle(PARTICLE_DEBRIS, particlePos, particleDir, nil, 0.3f, secondaryColor, nRotationSpeed);
+ }
+ }
+ PlayOneShotScriptObject(SCRIPT_SOUND_BOX_DESTROYED_2, vecPos);
+ break;
+ }
+ case DAMAGE_EFFECT_SMASH_BLACKBAG:
+ case DAMAGE_EFFECT_SMASH_BEACHLOUNGE_WOOD:
+ case DAMAGE_EFFECT_SMASH_BEACHLOUNGE_TOWEL:
+ {
+ bIsVisible = false;
+ bUsesCollision = false;
+ if (!GetIsStatic()) {
+ RemoveFromMovingList();
+ }
+ SetIsStatic(true);
+ bExplosionProof = true;
+ SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ SetTurnSpeed(0.0f, 0.0f, 0.0f);
+ CRGBA possibleColor1;
+ CRGBA possibleColor2;
+ switch (m_nCollisionDamageEffect) {
+ case DAMAGE_EFFECT_SMASH_BLACKBAG:
+ possibleColor1 = CRGBA(0, 0, 0, 0xFF);
+ possibleColor2 = possibleColor1;
+ break;
+ case DAMAGE_EFFECT_SMASH_BEACHLOUNGE_WOOD:
+ possibleColor1 = CRGBA(0x8F, 0x8A, 0x8C, 0xFF);
+ possibleColor2 = CRGBA(0x73, 0x75, 0x7B, 0xFF);
+ break;
+ case DAMAGE_EFFECT_SMASH_BEACHLOUNGE_TOWEL:
+ possibleColor1 = CRGBA(0x52, 0x92, 0x4A, 0xFF);
+ possibleColor2 = CRGBA(0xCE, 0xCF, 0xCE, 0xFF);
+ break;
+ }
+ for (int32 i = 0; i < 16; i++) {
+ CVector vecDir(
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(0.10f, 0.25f) + fDirectionZ
+ );
+ ++nFrameGen;
+ int32 nCurFrame = nFrameGen & 0x3;
+ CRGBA &selectedColor = nFrameGen & 0x1 ? possibleColor1 : possibleColor2;
+ float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f);
+ int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40);
+ CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, selectedColor, nRotationSpeed, 0, nCurFrame, 0);
+ }
+ if (m_nCollisionDamageEffect == DAMAGE_EFFECT_SMASH_BLACKBAG) {
+ PlayOneShotScriptObject(SCRIPT_SOUND_BOX_DESTROYED_2, vecPos);
+ } else if (m_nCollisionDamageEffect == DAMAGE_EFFECT_SMASH_BEACHLOUNGE_WOOD) {
+ PlayOneShotScriptObject(SCRIPT_SOUND_METAL_COLLISION, vecPos);
+ }
+ break;
+ }
+ default:
+ DEV("Unhandled collision damage effect id: %d\n", m_nCollisionDamageEffect);
+ return;
}
}
}
@@ -329,9 +744,9 @@ CObject::RefModelInfo(int32 modelId)
CModelInfo::GetModelInfo(modelId)->AddRef();
}
-void
-CObject::Init(void)
-{
+void
+CObject::Init(void)
+{
m_type = ENTITY_TYPE_OBJECT;
CObjectData::SetObjectData(GetModelIndex(), *this);
m_nEndOfLifeTime = 0;
@@ -348,18 +763,25 @@ CObject::Init(void)
m_colour1 = 0;
m_colour2 = 0;
m_nBonusValue = 0;
+ bIsWeapon = false;
+ m_nCostValue = 0;
m_pCollidingEntity = nil;
CColPoint point;
- CEntity* outEntity = nil;
+ CEntity *outEntity = nil;
const CVector& vecPos = GetMatrix().GetPosition();
if (CWorld::ProcessVerticalLine(vecPos, vecPos.z - 10.0f, point, outEntity, true, false, false, false, false, false, nil))
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
@@ -374,6 +796,8 @@ CObject::CanBeDeleted(void)
return true;
case CUTSCENE_OBJECT:
return false;
+ case CONTROLLED_SUB_OBJECT:
+ return false;
default:
return true;
}
@@ -382,9 +806,9 @@ CObject::CanBeDeleted(void)
void
CObject::DeleteAllMissionObjects()
{
- CObjectPool* objectPool = CPools::GetObjectPool();
+ CObjectPool *objectPool = CPools::GetObjectPool();
for (int32 i = 0; i < objectPool->GetSize(); i++) {
- CObject* pObject = objectPool->GetSlot(i);
+ CObject *pObject = objectPool->GetSlot(i);
if (pObject && pObject->ObjectCreatedBy == MISSION_OBJECT) {
CWorld::Remove(pObject);
delete pObject;
@@ -392,12 +816,12 @@ CObject::DeleteAllMissionObjects()
}
}
-void
-CObject::DeleteAllTempObjects()
+void
+CObject::DeleteAllTempObjects()
{
- CObjectPool* objectPool = CPools::GetObjectPool();
+ CObjectPool *objectPool = CPools::GetObjectPool();
for (int32 i = 0; i < objectPool->GetSize(); i++) {
- CObject* pObject = objectPool->GetSlot(i);
+ CObject *pObject = objectPool->GetSlot(i);
if (pObject && pObject->ObjectCreatedBy == TEMP_OBJECT) {
CWorld::Remove(pObject);
delete pObject;
@@ -405,8 +829,8 @@ CObject::DeleteAllTempObjects()
}
}
-void
-CObject::DeleteAllTempObjectsInArea(CVector point, float fRadius)
+void
+CObject::DeleteAllTempObjectsInArea(CVector point, float fRadius)
{
CObjectPool *objectPool = CPools::GetObjectPool();
for (int32 i = 0; i < objectPool->GetSize(); i++) {
@@ -417,3 +841,18 @@ CObject::DeleteAllTempObjectsInArea(CVector point, float fRadius)
}
}
}
+
+bool
+IsObjectPointerValid(CObject *pObject)
+{
+ if (!pObject)
+ return false;
+ int index = CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(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 114a1a9f..f59379bf 100644
--- a/src/objects/Object.h
+++ b/src/objects/Object.h
@@ -8,6 +8,7 @@ enum {
MISSION_OBJECT = 2,
TEMP_OBJECT = 3,
CUTSCENE_OBJECT = 4,
+ CONTROLLED_SUB_OBJECT = 5,
};
enum CollisionSpecialResponseCase
@@ -25,13 +26,29 @@ enum CollisionDamageEffect
DAMAGE_EFFECT_NONE,
DAMAGE_EFFECT_CHANGE_MODEL,
DAMAGE_EFFECT_SPLIT_MODEL,
- DAMAGE_EFFECT_SMASH_COMPLETELY,
+ DAMAGE_EFFECT_SMASH_AND_DAMAGE_TRAFFICLIGHTS,
+
+ DAMAGE_EFFECT_SMASH_COMPLETELY = 20,
DAMAGE_EFFECT_CHANGE_THEN_SMASH,
DAMAGE_EFFECT_SMASH_CARDBOARD_COMPLETELY = 50,
+ DAMAGE_EFFECT_SMASH_YELLOW_TARGET_COMPLETELY = 51,
+
DAMAGE_EFFECT_SMASH_WOODENBOX_COMPLETELY = 60,
DAMAGE_EFFECT_SMASH_TRAFFICCONE_COMPLETELY = 70,
- DAMAGE_EFFECT_SMASH_BARPOST_COMPLETELY = 80
+ DAMAGE_EFFECT_SMASH_BARPOST_COMPLETELY = 80,
+
+ DAMAGE_EFFECT_SMASH_NEWSTANDNEW1 = 91,
+ DAMAGE_EFFECT_SMASH_NEWSTANDNEW2 = 92,
+ DAMAGE_EFFECT_SMASH_NEWSTANDNEW3 = 93,
+ DAMAGE_EFFECT_SMASH_NEWSTANDNEW4 = 94,
+ DAMAGE_EFFECT_SMASH_NEWSTANDNEW5 = 95,
+
+ DAMAGE_EFFECT_SMASH_BLACKBAG = 100,
+ DAMAGE_EFFECT_SMASH_VEGPALM = 110,
+ DAMAGE_EFFECT_BURST_BEACHBALL = 120,
+ DAMAGE_EFFECT_SMASH_BEACHLOUNGE_WOOD = 131,
+ DAMAGE_EFFECT_SMASH_BEACHLOUNGE_TOWEL = 132,
};
class CVehicle;
@@ -43,18 +60,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;
- int8 m_nBonusValue;
+ uint8 bIsPickup : 1;
+ uint8 bAmmoCollected : 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;
+ uint16 m_nCostValue;
float m_fCollisionDamageMultiplier;
uint8 m_nCollisionDamageEffect;
uint8 m_nSpecialCollisionResponseCases;
bool m_bCameraToAvoidThisObject;
+ uint8 m_nBeachballBounces;
uint32 m_obj_unused1;
uint32 m_nEndOfLifeTime;
int16 m_nRefModelIndex;
@@ -63,7 +85,7 @@ public:
int8 m_colour1, m_colour2;
static int16 nNoTempObjects;
- static int16 nBodyCastHealth;
+ static float fDistToNearestTree;
static void *operator new(size_t) throw();
static void *operator new(size_t, int) throw();
@@ -91,4 +113,4 @@ public:
static void DeleteAllTempObjectsInArea(CVector point, float fRadius);
};
-VALIDATE_SIZE(CObject, 0x198);
+bool IsObjectPointerValid(CObject* pObject);
diff --git a/src/objects/ObjectData.cpp b/src/objects/ObjectData.cpp
index 589cc3f7..8b23f0ae 100644
--- a/src/objects/ObjectData.cpp
+++ b/src/objects/ObjectData.cpp
@@ -18,11 +18,55 @@ CObjectData::Initialise(const char *filename)
float percentSubmerged;
int damageEffect, responseCase, camAvoid;
CBaseModelInfo *mi;
+
+ ms_aObjectInfo[0].m_fMass = 99999.0f;
+ ms_aObjectInfo[0].m_fTurnMass = 99999.0f;
+ ms_aObjectInfo[0].m_fAirResistance = 0.99f;
+ ms_aObjectInfo[0].m_fElasticity = 0.1f;
+ ms_aObjectInfo[0].m_fBuoyancy = GRAVITY * ms_aObjectInfo[0].m_fMass * 2.0f;
+ ms_aObjectInfo[0].m_fUprootLimit = 0.0f;
+ ms_aObjectInfo[0].m_fCollisionDamageMultiplier = 1.0f;
+ ms_aObjectInfo[0].m_nCollisionDamageEffect = 0;
+ ms_aObjectInfo[0].m_nSpecialCollisionResponseCases = 0;
+ ms_aObjectInfo[0].m_bCameraToAvoidThisObject = false;
+
+ ms_aObjectInfo[1].m_fMass = 99999.0f;
+ ms_aObjectInfo[1].m_fTurnMass = 99999.0f;
+ ms_aObjectInfo[1].m_fAirResistance = 0.99f;
+ ms_aObjectInfo[1].m_fElasticity = 0.1f;
+ ms_aObjectInfo[1].m_fBuoyancy = ms_aObjectInfo[0].m_fBuoyancy;
+ ms_aObjectInfo[1].m_fUprootLimit = 0.0f;
+ ms_aObjectInfo[1].m_fCollisionDamageMultiplier = 1.0f;
+ ms_aObjectInfo[1].m_nCollisionDamageEffect = 0;
+ ms_aObjectInfo[1].m_nSpecialCollisionResponseCases = 0;
+ ms_aObjectInfo[1].m_bCameraToAvoidThisObject = true;
+
+ ms_aObjectInfo[2].m_fMass = 99999.0f;
+ ms_aObjectInfo[2].m_fTurnMass = 99999.0f;
+ ms_aObjectInfo[2].m_fAirResistance = 0.99f;
+ ms_aObjectInfo[2].m_fElasticity = 0.1f;
+ ms_aObjectInfo[2].m_fBuoyancy = ms_aObjectInfo[0].m_fBuoyancy;
+ ms_aObjectInfo[2].m_fUprootLimit = 0.0f;
+ ms_aObjectInfo[2].m_fCollisionDamageMultiplier = 1.0f;
+ ms_aObjectInfo[2].m_nCollisionDamageEffect = 0;
+ ms_aObjectInfo[2].m_bCameraToAvoidThisObject = false;
+ ms_aObjectInfo[2].m_nSpecialCollisionResponseCases = 4;
+
+ ms_aObjectInfo[3].m_fMass = 99999.0f;
+ ms_aObjectInfo[3].m_fTurnMass = 99999.0f;
+ ms_aObjectInfo[3].m_fAirResistance = 0.99f;
+ ms_aObjectInfo[3].m_fElasticity = 0.1f;
+ ms_aObjectInfo[3].m_fBuoyancy = ms_aObjectInfo[0].m_fBuoyancy;
+ ms_aObjectInfo[3].m_fUprootLimit = 0.0f;
+ ms_aObjectInfo[3].m_fCollisionDamageMultiplier = 1.0f;
+ ms_aObjectInfo[3].m_nCollisionDamageEffect = 0;
+ ms_aObjectInfo[3].m_nSpecialCollisionResponseCases = 4;
+ ms_aObjectInfo[3].m_bCameraToAvoidThisObject = true;
CFileMgr::SetDir("");
CFileMgr::LoadFile(filename, work_buff, sizeof(work_buff), "r");
- id = 0;
+ id = 4;
p = (char*)work_buff;
while(*p != '*'){
// skip over white space and comments
@@ -44,7 +88,11 @@ CObjectData::Initialise(const char *filename)
}
if(*p == '\n')
p++;
+#ifdef FIX_BUGS
*lp = '\0'; // FIX: game wrote '\n' here
+#else
+ *lp = '\n';
+#endif
assert(id < NUMOBJECTINFO);
sscanf(line, "%s %f %f %f %f %f %f %f %d %d %d", name,
@@ -63,9 +111,23 @@ CObjectData::Initialise(const char *filename)
ms_aObjectInfo[id].m_bCameraToAvoidThisObject = camAvoid;
mi = CModelInfo::GetModelInfo(name, nil);
- if(mi)
- mi->SetObjectID(id++);
- else
+ if (mi) {
+ if (ms_aObjectInfo[0].m_fMass != ms_aObjectInfo[id].m_fMass
+ || ms_aObjectInfo[0].m_fCollisionDamageMultiplier != ms_aObjectInfo[id].m_fCollisionDamageMultiplier
+ || ms_aObjectInfo[0].m_nCollisionDamageEffect != ms_aObjectInfo[id].m_nCollisionDamageEffect
+ || ((ms_aObjectInfo[0].m_nSpecialCollisionResponseCases != ms_aObjectInfo[id].m_nSpecialCollisionResponseCases)
+ && (ms_aObjectInfo[2].m_nSpecialCollisionResponseCases != ms_aObjectInfo[id].m_nSpecialCollisionResponseCases))) {
+ mi->SetObjectID(id++);
+ } else if (ms_aObjectInfo[0].m_nSpecialCollisionResponseCases == ms_aObjectInfo[id].m_nSpecialCollisionResponseCases) {
+ if (ms_aObjectInfo[0].m_bCameraToAvoidThisObject == ms_aObjectInfo[id].m_bCameraToAvoidThisObject)
+ mi->SetObjectID(0);
+ else
+ mi->SetObjectID(1);
+ } else if (ms_aObjectInfo[2].m_bCameraToAvoidThisObject == ms_aObjectInfo[id].m_bCameraToAvoidThisObject)
+ mi->SetObjectID(2);
+ else
+ mi->SetObjectID(3);
+ } else
debug("CObjectData: Cannot find object %s\n", name);
}
}
@@ -92,6 +154,7 @@ CObjectData::SetObjectData(int32 modelId, CObject &object)
object.m_bCameraToAvoidThisObject = objinfo->m_bCameraToAvoidThisObject;
if(object.m_fMass >= 99998.0f){
object.bInfiniteMass = true;
+ object.m_phy_flagA08 = true;
object.bAffectedByGravity = false;
object.bExplosionProof = true;
}
diff --git a/src/objects/ParticleObject.cpp b/src/objects/ParticleObject.cpp
index 5d480ecc..28c5240f 100644
--- a/src/objects/ParticleObject.cpp
+++ b/src/objects/ParticleObject.cpp
@@ -11,7 +11,7 @@
#include "screendroplets.h"
#ifdef COMPATIBLE_SAVES
-#define PARTICLE_OBJECT_SIZEOF 0x88
+#define PARTICLE_OBJECT_SIZEOF 0x84
#else
#define PARTICLE_OBJECT_SIZEOF sizeof(CParticleObject)
#endif
@@ -59,7 +59,7 @@ CAudioHydrant::Remove(CParticleObject *particleobject)
{
DMAudio.DestroyEntity(List[i].AudioEntity);
List[i].AudioEntity = AEHANDLE_NONE;
- List[i].pParticleObject = NULL;
+ List[i].pParticleObject = nil;
}
}
}
@@ -68,8 +68,8 @@ CParticleObject::CParticleObject() :
CPlaceable(),
m_nFrameCounter(0),
m_nState(POBJECTSTATE_INITIALISED),
- m_pNext(NULL),
- m_pPrev(NULL),
+ m_pNext(nil),
+ m_pPrev(nil),
m_nRemoveTimer(0)
{
@@ -84,20 +84,20 @@ CParticleObject::~CParticleObject()
void
CParticleObject::Initialise()
{
- pCloseListHead = NULL;
- pFarListHead = NULL;
+ pCloseListHead = nil;
+ pFarListHead = nil;
pUnusedListHead = &gPObjectArray[0];
for ( int32 i = 0; i < MAX_PARTICLEOBJECTS; i++ )
{
if ( i == 0 )
- gPObjectArray[i].m_pPrev = NULL;
+ gPObjectArray[i].m_pPrev = nil;
else
gPObjectArray[i].m_pPrev = &gPObjectArray[i - 1];
if ( i == MAX_PARTICLEOBJECTS-1 )
- gPObjectArray[i].m_pNext = NULL;
+ gPObjectArray[i].m_pNext = nil;
else
gPObjectArray[i].m_pNext = &gPObjectArray[i + 1];
@@ -133,12 +133,10 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe
{
CParticleObject *pobj = pUnusedListHead;
- ASSERT(pobj != NULL);
-
- if ( pobj == NULL )
+ if ( pobj == nil )
{
printf("Error: No particle objects available!\n");
- return NULL;
+ return nil;
}
MoveToList(&pUnusedListHead, &pCloseListHead, pobj);
@@ -156,7 +154,7 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe
pobj->m_bRemove = remove;
- pobj->m_pParticle = NULL;
+ pobj->m_pParticle = nil;
if ( lifeTime != 0 )
pobj->m_nRemoveTimer = CTimer::GetTimeInMilliseconds() + lifeTime;
@@ -171,229 +169,243 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe
pobj->m_fSize = size;
pobj->m_fRandVal = 0.0f;
- if ( type <= POBJECT_CATALINAS_SHOTGUNFLASH )
+ switch ( type )
{
- switch ( type )
+ case POBJECT_PAVEMENT_STEAM:
{
- case POBJECT_PAVEMENT_STEAM:
- {
- pobj->m_ParticleType = PARTICLE_STEAM_NY;
- pobj->m_nNumEffectCycles = 1;
-#ifdef PC_PARTICLE
- pobj->m_nSkipFrames = 3;
-#else
- pobj->m_nSkipFrames = 1;
-#endif
- pobj->m_nCreationChance = 8;
- break;
- }
-
- case POBJECT_PAVEMENT_STEAM_SLOWMOTION:
- {
- pobj->m_ParticleType = PARTICLE_STEAM_NY_SLOWMOTION;
- pobj->m_nNumEffectCycles = 1;
- pobj->m_nSkipFrames = 1;
- pobj->m_nCreationChance = 8;
- break;
- }
-
- case POBJECT_WALL_STEAM:
- {
- pobj->m_ParticleType = PARTICLE_STEAM_NY;
- pobj->m_nNumEffectCycles = 1;
-#ifdef PC_PARTICLE
- pobj->m_nSkipFrames = 3;
-#else
- pobj->m_nSkipFrames = 1;
-#endif
- pobj->m_nCreationChance = 8;
- break;
- }
-
- case POBJECT_WALL_STEAM_SLOWMOTION:
- {
- pobj->m_ParticleType = PARTICLE_STEAM_NY_SLOWMOTION;
- pobj->m_nNumEffectCycles = 1;
- pobj->m_nSkipFrames = 1;
- pobj->m_nCreationChance = 8;
- break;
- }
-
- case POBJECT_DARK_SMOKE:
- {
- pobj->m_ParticleType = PARTICLE_STEAM_NY;
- pobj->m_nNumEffectCycles = 1;
-#ifdef PC_PARTICLE
- pobj->m_nSkipFrames = 3;
-#else
- pobj->m_nSkipFrames = 1;
-#endif
- pobj->m_nCreationChance = 8;
- pobj->m_Color = CRGBA(16, 16, 16, 255);
- break;
- }
-
- case POBJECT_FIRE_HYDRANT:
- {
- pobj->m_ParticleType = PARTICLE_WATER_HYDRANT;
- pobj->m_nNumEffectCycles = 4;
- pobj->m_nSkipFrames = 1;
- pobj->m_nCreationChance = 0;
- pobj->m_vecTarget = CVector(0.0f, 0.0f, 0.3f);
- pobj->m_nRemoveTimer = CTimer::GetTimeInMilliseconds() + 5000;
- CAudioHydrant::Add(pobj);
- break;
- }
-
- case POBJECT_CAR_WATER_SPLASH:
- case POBJECT_PED_WATER_SPLASH:
- {
- pobj->m_ParticleType = PARTICLE_CAR_SPLASH;
- pobj->m_nNumEffectCycles = 0;
-#ifdef PC_PARTICLE
- pobj->m_nSkipFrames = 1;
-#else
- pobj->m_nSkipFrames = 3;
-#endif
- pobj->m_nCreationChance = 0;
+ pobj->m_ParticleType = PARTICLE_STEAM_NY;
+ pobj->m_nNumEffectCycles = 1;
+ pobj->m_nSkipFrames = 3;
+ pobj->m_nCreationChance = 8;
+ break;
+ }
+
+ case POBJECT_PAVEMENT_STEAM_SLOWMOTION:
+ {
+ pobj->m_ParticleType = PARTICLE_STEAM_NY_SLOWMOTION;
+ pobj->m_nNumEffectCycles = 1;
+ pobj->m_nSkipFrames = 1;
+ pobj->m_nCreationChance = 8;
+ break;
+ }
+
+ case POBJECT_WALL_STEAM:
+ {
+ pobj->m_ParticleType = PARTICLE_STEAM_NY;
+ pobj->m_nNumEffectCycles = 1;
+ pobj->m_nSkipFrames = 3;
+ pobj->m_nCreationChance = 8;
+ break;
+ }
+
+ case POBJECT_WALL_STEAM_SLOWMOTION:
+ {
+ pobj->m_ParticleType = PARTICLE_STEAM_NY_SLOWMOTION;
+ pobj->m_nNumEffectCycles = 1;
+ pobj->m_nSkipFrames = 1;
+ pobj->m_nCreationChance = 8;
+ break;
+ }
+
+ case POBJECT_DARK_SMOKE:
+ {
+ pobj->m_ParticleType = PARTICLE_STEAM_NY;
+ pobj->m_nNumEffectCycles = 1;
+ pobj->m_nSkipFrames = 3;
+ pobj->m_nCreationChance = 8;
+ pobj->m_Color = CRGBA(16, 16, 16, 255);
+ break;
+ }
+
+ case POBJECT_WATER_FOUNTAIN_VERT:
+ {
+ pobj->m_ParticleType = PARTICLE_WATER_HYDRANT;
+ pobj->m_nNumEffectCycles = 1;
+ pobj->m_nSkipFrames = 1;
+ pobj->m_nCreationChance = 0;
+ pobj->m_vecTarget = CVector(0.0f, 0.0f, 0.1f);
+ break;
+ }
+
+ case POBJECT_WATER_FOUNTAIN_HORIZ:
+ {
+ pobj->m_ParticleType = PARTICLE_WATER_HYDRANT;
+ pobj->m_nNumEffectCycles = 1;
+ pobj->m_nSkipFrames = 1;
+ pobj->m_nCreationChance = 0;
+ break;
+ }
+
+ case POBJECT_FIRE_HYDRANT:
+ {
+ pobj->m_ParticleType = PARTICLE_WATER_HYDRANT;
+ pobj->m_nNumEffectCycles = 1;
+ pobj->m_nSkipFrames = 1;
+ pobj->m_nCreationChance = 0;
+ pobj->m_vecTarget = CVector(0.0f, 0.0f, 0.3f);
+ pobj->m_nRemoveTimer = CTimer::GetTimeInMilliseconds() + 5000;
+ CAudioHydrant::Add(pobj);
+ break;
+ }
+
+ case POBJECT_CAR_WATER_SPLASH:
+ case POBJECT_PED_WATER_SPLASH:
+ {
+ pobj->m_ParticleType = PARTICLE_CAR_SPLASH;
+ pobj->m_nNumEffectCycles = 0;
+ pobj->m_nSkipFrames = 1;
+ pobj->m_nCreationChance = 0;
#ifdef SCREEN_DROPLETS
- ScreenDroplets::RegisterSplash(pobj);
-#endif
- break;
- }
-
- case POBJECT_SPLASHES_AROUND:
- {
- pobj->m_ParticleType = PARTICLE_SPLASH;
-#ifdef PC_PARTICLE
- pobj->m_nNumEffectCycles = 15;
-#else
- pobj->m_nNumEffectCycles = 30;
-#endif
- pobj->m_nSkipFrames = 2;
- pobj->m_nCreationChance = 0;
- break;
- }
-
- case POBJECT_SMALL_FIRE:
- {
- pobj->m_ParticleType = PARTICLE_FLAME;
- pobj->m_nNumEffectCycles = 1;
-#ifdef PC_PARTICLE
- pobj->m_nSkipFrames = 2;
-#else
- pobj->m_nSkipFrames = 1;
-#endif
- pobj->m_nCreationChance = 2;
- pobj->m_vecTarget = CVector(0.0f, 0.0f, 0.0f);
- break;
- }
-
- case POBJECT_BIG_FIRE:
- {
- pobj->m_ParticleType = PARTICLE_FLAME;
- pobj->m_nNumEffectCycles = 1;
-#ifdef PC_PARTICLE
- pobj->m_nSkipFrames = 2;
-#else
- pobj->m_nSkipFrames = 1;
+ ScreenDroplets::RegisterSplash(pobj);
#endif
- pobj->m_nCreationChance = 4;
- pobj->m_vecTarget = CVector(0.0f, 0.0f, 0.0f);
- break;
- }
-
- case POBJECT_DRY_ICE:
- {
- pobj->m_ParticleType = PARTICLE_SMOKE;
- pobj->m_nNumEffectCycles = 1;
- pobj->m_nSkipFrames = 1;
- pobj->m_nCreationChance = 0;
- pobj->m_vecTarget = CVector(0.0f, 0.0f, 0.0f);
- break;
- }
-
- case POBJECT_DRY_ICE_SLOWMOTION:
- {
- pobj->m_ParticleType = PARTICLE_SMOKE_SLOWMOTION;
- pobj->m_nNumEffectCycles = 1;
- pobj->m_nSkipFrames = 1;
- pobj->m_nCreationChance = 0;
- pobj->m_vecTarget = CVector(0.0f, 0.0f, 0.0f);
- break;
- }
-
- case POBJECT_FIRE_TRAIL:
- {
- pobj->m_ParticleType = PARTICLE_EXPLOSION_MEDIUM;
- pobj->m_nNumEffectCycles = 1;
-#ifdef PC_PARTICLE
- pobj->m_nSkipFrames = 3;
-#else
- pobj->m_nSkipFrames = 1;
-#endif
- pobj->m_nCreationChance = 2;
- pobj->m_fRandVal = 0.01f;
- break;
- }
-
- case POBJECT_SMOKE_TRAIL:
- {
- pobj->m_ParticleType = PARTICLE_FIREBALL_SMOKE;
- pobj->m_nNumEffectCycles = 1;
- pobj->m_nSkipFrames = 1;
- pobj->m_nCreationChance = 2;
- pobj->m_fRandVal = 0.02f;
- break;
- }
-
- case POBJECT_FIREBALL_AND_SMOKE:
- {
- pobj->m_ParticleType = PARTICLE_FLAME;
- pobj->m_nNumEffectCycles = 1;
- pobj->m_nSkipFrames = 1;
- pobj->m_nCreationChance = 2;
- pobj->m_fRandVal = 0.1f;
- break;
- }
-
- case POBJECT_ROCKET_TRAIL:
- {
- pobj->m_ParticleType = PARTICLE_FLAME;
- pobj->m_nNumEffectCycles = 1;
- pobj->m_nSkipFrames = 2;
- pobj->m_nCreationChance = 8;
- pobj->m_fRandVal = 0.1f;
- break;
- }
-
- case POBJECT_EXPLOSION_ONCE:
- {
- pobj->m_ParticleType = PARTICLE_EXPLOSION_LARGE;
- pobj->m_nNumEffectCycles = 1;
- pobj->m_nSkipFrames = 1;
- pobj->m_nCreationChance = 0;
- pobj->m_nRemoveTimer = CTimer::GetTimeInMilliseconds();
- break;
- }
-
- case POBJECT_CATALINAS_GUNFLASH:
- case POBJECT_CATALINAS_SHOTGUNFLASH:
- {
- pobj->m_ParticleType = PARTICLE_GUNFLASH_NOANIM;
- pobj->m_nNumEffectCycles = 1;
- pobj->m_nSkipFrames = 1;
- pobj->m_nCreationChance = 0;
- pobj->m_nRemoveTimer = CTimer::GetTimeInMilliseconds();
- pobj->m_vecTarget.Normalise();
- break;
- }
+ break;
+ }
+
+ case POBJECT_SPLASHES_AROUND:
+ {
+ pobj->m_ParticleType = PARTICLE_SPLASH;
+ pobj->m_nNumEffectCycles = 15;
+ pobj->m_nSkipFrames = 2;
+ pobj->m_nCreationChance = 0;
+ break;
+ }
+
+ case POBJECT_SMALL_FIRE:
+ {
+ pobj->m_ParticleType = PARTICLE_FLAME;
+ pobj->m_nNumEffectCycles = 1;
+ pobj->m_nSkipFrames = 2;
+ pobj->m_nCreationChance = 2;
+ pobj->m_vecTarget = CVector(0.0f, 0.0f, 0.0f);
+ break;
+ }
+
+ case POBJECT_BIG_FIRE:
+ {
+ pobj->m_ParticleType = PARTICLE_FLAME;
+ pobj->m_nNumEffectCycles = 1;
+ pobj->m_nSkipFrames = 2;
+ pobj->m_nCreationChance = 4;
+ pobj->m_vecTarget = CVector(0.0f, 0.0f, 0.0f);
+ break;
+ }
+
+ case POBJECT_DRY_ICE:
+ {
+ pobj->m_ParticleType = PARTICLE_SMOKE;
+ pobj->m_nNumEffectCycles = 1;
+ pobj->m_nSkipFrames = 1;
+ pobj->m_nCreationChance = 0;
+ pobj->m_vecTarget = CVector(0.0f, 0.0f, 0.0f);
+ break;
+ }
+
+ case POBJECT_DRY_ICE_SLOWMOTION:
+ {
+ pobj->m_ParticleType = PARTICLE_SMOKE_SLOWMOTION;
+ pobj->m_nNumEffectCycles = 1;
+ pobj->m_nSkipFrames = 1;
+ pobj->m_nCreationChance = 0;
+ pobj->m_vecTarget = CVector(0.0f, 0.0f, 0.0f);
+ break;
+ }
+
+ case POBJECT_FIRE_TRAIL:
+ {
+ pobj->m_ParticleType = PARTICLE_EXPLOSION_MEDIUM;
+ pobj->m_nNumEffectCycles = 1;
+ pobj->m_nSkipFrames = 3;
+ pobj->m_nCreationChance = 2;
+ pobj->m_fRandVal = 0.01f;
+ break;
+ }
+
+ case POBJECT_SMOKE_TRAIL:
+ {
+ pobj->m_ParticleType = PARTICLE_FIREBALL_SMOKE;
+ pobj->m_nNumEffectCycles = 1;
+ pobj->m_nSkipFrames = 1;
+ pobj->m_nCreationChance = 2;
+ pobj->m_fRandVal = 0.02f;
+ break;
+ }
+
+ case POBJECT_FIREBALL_AND_SMOKE:
+ {
+ pobj->m_ParticleType = PARTICLE_FLAME;
+ pobj->m_nNumEffectCycles = 1;
+ pobj->m_nSkipFrames = 1;
+ pobj->m_nCreationChance = 0;
+ pobj->m_fRandVal = 0.1f;
+ break;
+ }
+
+ case POBJECT_ROCKET_TRAIL:
+ {
+ pobj->m_ParticleType = PARTICLE_FLAME;
+ pobj->m_nNumEffectCycles = 1;
+ pobj->m_nSkipFrames = 2;
+ pobj->m_nCreationChance = 8;
+ pobj->m_fRandVal = 0.1f;
+ break;
+ }
+
+ case POBJECT_EXPLOSION_ONCE:
+ {
+ pobj->m_ParticleType = PARTICLE_EXPLOSION_LARGE;
+ pobj->m_nNumEffectCycles = 1;
+ pobj->m_nSkipFrames = 1;
+ pobj->m_nCreationChance = 0;
+ pobj->m_nRemoveTimer = CTimer::GetTimeInMilliseconds();
+ break;
}
}
return pobj;
}
+CParticleObject *
+CParticleObject::AddObject(tParticleType type, CVector const &pos, CVector const &target, float size, uint32 lifeTime, uint8 numEffectCycles, uint8 skipFrames, uint16 creationChance, uint8 remove)
+{
+ CParticleObject *pobj = pUnusedListHead;
+
+ ASSERT(pobj != nil);
+
+ if ( pobj == nil )
+ {
+ printf("Error: No particle objects available!\n");
+ return nil;
+ }
+
+ MoveToList(&pUnusedListHead, &pCloseListHead, pobj);
+
+ pobj->m_nState = POBJECTSTATE_UPDATE_CLOSE;
+ pobj->m_Type = (eParticleObjectType)-1;
+ pobj->m_ParticleType = type;
+
+ pobj->SetPosition(pos);
+ pobj->m_vecTarget = target;
+
+ pobj->m_nNumEffectCycles = numEffectCycles;
+ pobj->m_nSkipFrames = skipFrames;
+ pobj->m_nCreationChance = creationChance;
+ pobj->m_nFrameCounter = 0;
+
+ pobj->m_bRemove = remove;
+
+ if ( lifeTime != 0 )
+ pobj->m_nRemoveTimer = CTimer::GetTimeInMilliseconds() + lifeTime;
+ else
+ pobj->m_nRemoveTimer = 0;
+
+ pobj->m_Color.alpha = 0;
+
+ pobj->m_fSize = size;
+ pobj->m_fRandVal = 0.0f;
+
+ return pobj;
+}
+
void
CParticleObject::RemoveObject(void)
{
@@ -420,7 +432,7 @@ CParticleObject::UpdateAll(void)
{
CParticleObject *pobj = pCloseListHead;
CParticleObject *nextpobj;
- if ( pobj != NULL )
+ if ( pobj != nil )
{
do
{
@@ -428,7 +440,7 @@ CParticleObject::UpdateAll(void)
pobj->UpdateClose();
pobj = nextpobj;
}
- while ( nextpobj != NULL );
+ while ( nextpobj != nil );
}
}
@@ -438,7 +450,7 @@ CParticleObject::UpdateAll(void)
CParticleObject *pobj = pFarListHead;
CParticleObject *nextpobj;
- if ( pobj != NULL )
+ if ( pobj != nil )
{
do
{
@@ -454,7 +466,7 @@ CParticleObject::UpdateAll(void)
pobj = nextpobj;
}
- while ( nextpobj != NULL );
+ while ( nextpobj != nil );
}
}
}
@@ -509,7 +521,7 @@ void CParticleObject::UpdateClose(void)
flamevel.y = vel.y;
flamevel.z = CGeneral::GetRandomNumberInRange(0.0125f*size, 0.1f*size);
- CParticle::AddParticle(PARTICLE_FLAME, pos, flamevel, NULL, size);
+ CParticle::AddParticle(PARTICLE_FLAME, pos, flamevel, nil, size);
CVector possmoke = pos;
@@ -540,7 +552,7 @@ void CParticleObject::UpdateClose(void)
float flamesize = 0.8f*size;
- CParticle::AddParticle(PARTICLE_FLAME, pos, flamevel, NULL, flamesize);
+ CParticle::AddParticle(PARTICLE_FLAME, pos, flamevel, nil, flamesize);
for ( int32 i = 0; i < 4; i++ )
@@ -559,7 +571,7 @@ void CParticleObject::UpdateClose(void)
case POBJECT_FIREBALL_AND_SMOKE:
{
- if ( this->m_pParticle == NULL )
+ if ( this->m_pParticle == nil )
{
CVector pos = this->GetPosition();
CVector vel = this->m_vecTarget;
@@ -567,7 +579,7 @@ void CParticleObject::UpdateClose(void)
CVector expvel = 1.2f*vel;
float expsize = 1.2f*size;
- this->m_pParticle = CParticle::AddParticle(PARTICLE_EXPLOSION_MEDIUM, pos, expvel, NULL, expsize);
+ this->m_pParticle = CParticle::AddParticle(PARTICLE_EXPLOSION_MEDIUM, pos, expvel, nil, expsize);
}
else
{
@@ -584,7 +596,7 @@ void CParticleObject::UpdateClose(void)
fireballvel.y += CGeneral::GetRandomNumberInRange(-veloffset.y, veloffset.y);
fireballvel.z += CGeneral::GetRandomNumberInRange(-veloffset.z, veloffset.z);
- CParticle::AddParticle(PARTICLE_FIREBALL_SMOKE, pos, fireballvel, NULL, size);
+ CParticle::AddParticle(PARTICLE_FIREBALL_SMOKE, pos, fireballvel, nil, size);
}
}
@@ -593,13 +605,13 @@ void CParticleObject::UpdateClose(void)
case POBJECT_ROCKET_TRAIL:
{
- if ( this->m_pParticle == NULL )
+ if ( this->m_pParticle == nil )
{
CVector pos = this->GetPosition();
CVector vel = this->m_vecTarget;
float size = this->m_fSize;
- this->m_pParticle = CParticle::AddParticle(PARTICLE_EXPLOSION_MEDIUM, pos, vel, NULL, size);
+ this->m_pParticle = CParticle::AddParticle(PARTICLE_EXPLOSION_MEDIUM, pos, vel, nil, size);
}
else
{
@@ -612,7 +624,7 @@ void CParticleObject::UpdateClose(void)
for ( int32 i = 0; i < this->m_nNumEffectCycles; i++ )
{
- CParticle::AddParticle(PARTICLE_FIREBALL_SMOKE, pos, fireballvel, NULL, fireballsize);
+ CParticle::AddParticle(PARTICLE_FIREBALL_SMOKE, pos, fireballvel, nil, fireballsize);
}
}
@@ -634,7 +646,7 @@ void CParticleObject::UpdateClose(void)
if ( vel.z != 0.0f )
vel.z += CGeneral::GetRandomNumberInRange(-this->m_fRandVal, this->m_fRandVal);
- CParticle::AddParticle(this->m_ParticleType, this->GetPosition(), vel, NULL, this->m_fSize,
+ CParticle::AddParticle(this->m_ParticleType, this->GetPosition(), vel, nil, this->m_fSize,
CGeneral::GetRandomNumberInRange(-6.0f, 6.0f));
}
@@ -643,7 +655,6 @@ void CParticleObject::UpdateClose(void)
case POBJECT_PED_WATER_SPLASH:
{
-#ifdef PC_PARTICLE
CRGBA colorsmoke(255, 255, 255, 196);
CVector pos = this->GetPosition();
@@ -661,9 +672,9 @@ void CParticleObject::UpdateClose(void)
splashpos = pos + CVector(0.75f*fCos, 0.75f*fSin, 0.0f);
splashvel = vel + CVector(0.05f*fCos, 0.05f*fSin, CGeneral::GetRandomNumberInRange(0.04f, 0.08f));
- CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, splashpos, splashvel, NULL,
+ CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, splashpos, splashvel, nil,
CGeneral::GetRandomNumberInRange(0.1f, 0.8f), colorsmoke);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL,
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil,
CGeneral::GetRandomNumberInRange(0.1f, 0.5f), this->m_Color);
@@ -671,9 +682,9 @@ void CParticleObject::UpdateClose(void)
splashvel = vel + CVector(0.05f*fCos, 0.05f*-fSin, CGeneral::GetRandomNumberInRange(0.04f, 0.08f));
- CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, splashpos, splashvel, NULL,
+ CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, splashpos, splashvel, nil,
CGeneral::GetRandomNumberInRange(0.1f, 0.8f), colorsmoke);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL,
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil,
CGeneral::GetRandomNumberInRange(0.1f, 0.5f), this->m_Color);
@@ -681,18 +692,18 @@ void CParticleObject::UpdateClose(void)
splashvel = vel + CVector(0.05f*-fCos, 0.05f*fSin, CGeneral::GetRandomNumberInRange(0.04f, 0.08f));
- CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, splashpos, splashvel, NULL,
+ CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, splashpos, splashvel, nil,
CGeneral::GetRandomNumberInRange(0.1f, 0.8f), colorsmoke);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL,
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil,
CGeneral::GetRandomNumberInRange(0.1f, 0.5f), this->m_Color);
splashpos = pos + CVector(0.75f*-fCos, 0.75f*-fSin, 0.0f);
splashvel = vel + CVector(0.05f*-fCos, 0.05f*-fSin, CGeneral::GetRandomNumberInRange(0.04f, 0.08f));
- CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, splashpos, splashvel, NULL,
+ CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, splashpos, splashvel, nil,
CGeneral::GetRandomNumberInRange(0.1f, 0.8f), colorsmoke);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL,
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil,
CGeneral::GetRandomNumberInRange(0.1f, 0.5f), this->m_Color);
}
@@ -712,7 +723,7 @@ void CParticleObject::UpdateClose(void)
splashvel.y += CGeneral::GetRandomNumberInRange(-0.25f, 0.25f) * fSin;
splashvel.z += CGeneral::GetRandomNumberInRange(0.05f, 0.25f);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL,
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil,
CGeneral::GetRandomNumberInRange(0.4f, 1.0f), this->m_Color);
@@ -722,7 +733,7 @@ void CParticleObject::UpdateClose(void)
splashvel.y += CGeneral::GetRandomNumberInRange(-0.25f, 0.25f) * -fSin;
splashvel.z += CGeneral::GetRandomNumberInRange(0.05f, 0.25f);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL,
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil,
CGeneral::GetRandomNumberInRange(0.4f, 1.0f), this->m_Color);
@@ -732,7 +743,7 @@ void CParticleObject::UpdateClose(void)
splashvel.y += CGeneral::GetRandomNumberInRange(-0.25f, 0.25f) * fSin;
splashvel.z += CGeneral::GetRandomNumberInRange(0.05f, 0.25f);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL,
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil,
CGeneral::GetRandomNumberInRange(0.4f, 1.0f), this->m_Color);
@@ -742,72 +753,15 @@ void CParticleObject::UpdateClose(void)
splashvel.y += CGeneral::GetRandomNumberInRange(-0.25f, 0.25f) * -fSin;
splashvel.z += CGeneral::GetRandomNumberInRange(0.05f, 0.25f);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL,
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil,
CGeneral::GetRandomNumberInRange(0.4f, 1.0f), this->m_Color);
}
-#else
- CVector pos;
- CVector vel;
-
- for ( int32 i = -2; i < 2; i++ )
- {
- pos = this->GetPosition();
- pos += CVector(-0.75f, 0.5f * float(i), 0.0f);
-
- vel = this->m_vecTarget;
- vel.x += -1.5 * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
- vel.y += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
- vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
- CParticle::AddParticle(PARTICLE_PED_SPLASH, pos, vel, NULL, 0.8f, this->m_Color);
-
- pos = this->GetPosition();
- pos += CVector(0.75f, 0.5f * float(i), 0.0f);
-
- vel = this->m_vecTarget;
- vel.x += 1.5f * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
- vel.y += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
- vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
- CParticle::AddParticle(PARTICLE_PED_SPLASH, pos, vel, NULL, 0.8f, this->m_Color);
-
- pos = this->GetPosition();
- pos += CVector(0.5f * float(i), -0.75, 0.0f);
-
- vel = this->m_vecTarget;
- vel.x += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
- vel.y += -1.5f * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
- vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
- CParticle::AddParticle(PARTICLE_PED_SPLASH, pos, vel, NULL, 0.8f, this->m_Color);
-
-
- pos = this->GetPosition();
- pos += CVector(0.5f * float(i), 0.75, 0.0f);
-
- vel = this->m_vecTarget;
- vel.x += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
- vel.y += 1.5f * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
- vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
- CParticle::AddParticle(PARTICLE_PED_SPLASH, pos, vel, NULL, 0.8f, this->m_Color);
- }
-
-
- for ( int32 i = 0; i < 4; i++ )
- {
- pos = this->GetPosition();
-
- pos.x += CGeneral::GetRandomNumberInRange(-1.5f, 1.5f);
- pos.y += CGeneral::GetRandomNumberInRange(-1.5f, 1.5f);
- pos.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
- vel = this->m_vecTarget;
- CParticle::AddParticle(PARTICLE_PED_SPLASH, pos, vel, NULL, 0.8f, this->m_Color);
- }
-#endif
break;
}
case POBJECT_CAR_WATER_SPLASH:
{
-#ifdef PC_PARTICLE
CRGBA colorsmoke(255, 255, 255, 196);
CVector pos = this->GetPosition();
@@ -831,8 +785,8 @@ void CParticleObject::UpdateClose(void)
splashvel.y += CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) * fSin;
splashvel.z += CGeneral::GetRandomNumberInRange(0.01f, 0.03f);
- CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, splashpos, splashvel, NULL, size, colorsmoke);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL, 0.0f, this->m_Color);
+ CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, splashpos, splashvel, nil, size, colorsmoke);
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil, 0.0f, this->m_Color);
splashpos = pos + CVector(2.0f*fCos, 2.0f*-fSin, 0.0f);
@@ -841,8 +795,8 @@ void CParticleObject::UpdateClose(void)
splashvel.y += CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) * -fSin;
splashvel.z += CGeneral::GetRandomNumberInRange(0.01f, 0.03f);
- CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, splashpos, splashvel, NULL, size, colorsmoke);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL, 0.0f, this->m_Color);
+ CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, splashpos, splashvel, nil, size, colorsmoke);
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil, 0.0f, this->m_Color);
splashpos = pos + CVector(2.0f*-fCos, 2.0f*fSin, 0.0f);
splashvel = vel;
@@ -850,8 +804,8 @@ void CParticleObject::UpdateClose(void)
splashvel.y += CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) * fSin;
splashvel.z += CGeneral::GetRandomNumberInRange(0.01f, 0.03f);
- CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, splashpos, splashvel, NULL, size, colorsmoke);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL, 0.0f, this->m_Color);
+ CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, splashpos, splashvel, nil, size, colorsmoke);
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil, 0.0f, this->m_Color);
splashpos = pos + CVector(2.0f*-fCos, 2.0f*-fSin, 0.0f);
splashvel = vel;
@@ -859,8 +813,8 @@ void CParticleObject::UpdateClose(void)
splashvel.y += CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) * -fSin;
splashvel.z += CGeneral::GetRandomNumberInRange(0.01f, 0.03f);
- CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, splashpos, splashvel, NULL, size, colorsmoke);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL, 0.0f, this->m_Color);
+ CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, splashpos, splashvel, nil, size, colorsmoke);
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil, 0.0f, this->m_Color);
}
for ( int32 i = 0; i < 1; i++ )
@@ -879,88 +833,30 @@ void CParticleObject::UpdateClose(void)
splashvel.x += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f) * fCos;
splashvel.y += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f) * fSin;
splashvel.z += CGeneral::GetRandomNumberInRange(0.26f, 0.53f);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL, 0.0f, this->m_Color);
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil, 0.0f, this->m_Color);
splashpos = pos + CVector(1.25f*fCos, 1.25f*-fSin, 0.0f);
splashvel = vel;
splashvel.x += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f) * fCos;
splashvel.y += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f) * -fSin;
splashvel.z += CGeneral::GetRandomNumberInRange(0.26f, 0.53f);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL, 0.0f, this->m_Color);
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil, 0.0f, this->m_Color);
splashpos = pos + CVector(1.25f*-fCos, 1.25f*fSin, 0.0f);
splashvel = vel;
splashvel.x += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f) * -fCos;
splashvel.y += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f) * fSin;
splashvel.z += CGeneral::GetRandomNumberInRange(0.26f, 0.53f);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL, 0.0f, this->m_Color);
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil, 0.0f, this->m_Color);
splashpos = pos + CVector(1.25f*-fCos, 1.25f*-fSin, 0.0f);
splashvel = vel;
splashvel.x += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f) * -fCos;
splashvel.y += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f) * -fSin;
splashvel.z += CGeneral::GetRandomNumberInRange(0.26f, 0.53f);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL, 0.0f, this->m_Color);
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil, 0.0f, this->m_Color);
}
-#else
- CVector pos;
- CVector vel;
-
- for ( int32 i = -3; i < 4; i++ )
- {
- pos = this->GetPosition();
- pos += CVector(-1.5f, 0.5f * float(i), 0.0f);
-
-
- vel = this->m_vecTarget;
- vel.x += -3.0f * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
- vel.y += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
- vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, vel, NULL, 0.0f, this->m_Color);
-
-
- pos = this->GetPosition();
- pos += CVector(1.5f, 0.5f * float(i), 0.0f);
-
- vel = this->m_vecTarget;
- vel.x += 3.0f * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
- vel.y += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
- vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, vel, NULL, 0.0f, this->m_Color);
-
-
- pos = this->GetPosition();
- pos += CVector(0.5f * float(i), -1.5f, 0.0f);
-
- vel = this->m_vecTarget;
- vel.x += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
- vel.y += -3.0f * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
- vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, vel, NULL, 0.0f, this->m_Color);
-
-
- pos = this->GetPosition();
- pos += CVector(0.5f * float(i), 1.5f, 0.0f);
-
-
- vel = this->m_vecTarget;
- vel.x += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
- vel.y += 3.0f * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
- vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, vel, NULL, 0.0f, this->m_Color);
- }
-
- for ( int32 i = 0; i < 8; i++ )
- {
- pos = this->GetPosition();
- pos.x += CGeneral::GetRandomNumberInRange(-3.0f, 3.0f);
- pos.y += CGeneral::GetRandomNumberInRange(-3.0f, 3.0f);
-
- vel = this->m_vecTarget;
- vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, vel, NULL, 0.0f, this->m_Color);
- }
-#endif
+
break;
}
@@ -979,75 +875,119 @@ void CParticleObject::UpdateClose(void)
if ( CGeneral::GetRandomNumber() & 1 )
{
CParticle::AddParticle(PARTICLE_RAIN_SPLASH, splashpos, CVector(0.0f, 0.0f, 0.0f),
- NULL, 0.1f, this->m_Color);
+ nil, 0.1f, this->m_Color);
}
else
{
CParticle::AddParticle(PARTICLE_RAIN_SPLASHUP, splashpos, CVector(0.0f, 0.0f, 0.0f),
- NULL, 0.12f, this->m_Color);
+ nil, 0.12f, this->m_Color);
}
}
break;
}
- case POBJECT_CATALINAS_GUNFLASH:
+ case POBJECT_FIRE_HYDRANT:
{
- CRGBA flashcolor(120, 120, 120, 255);
-
- CVector vel = this->m_vecTarget;
CVector pos = this->GetPosition();
-
- float size = 1.0f;
- if ( this->m_fSize != 0.0f )
- size = this->m_fSize;
-
- CParticle::AddParticle(PARTICLE_GUNFLASH, pos, CVector(0.0f, 0.0f, 0.0f), NULL, 0.12f*size, flashcolor);
-
- pos += size * (0.06f * vel);
- CParticle::AddParticle(PARTICLE_GUNFLASH, pos, CVector(0.0f, 0.0f, 0.0f), NULL, 0.08f*size, flashcolor);
-
- pos += size * (0.04f * vel);
- CParticle::AddParticle(PARTICLE_GUNFLASH, pos, CVector(0.0f, 0.0f, 0.0f), NULL, 0.04f*size, flashcolor);
+ CVector vel = this->m_vecTarget;
- CVector smokepos = this->GetPosition();
- CVector smokevel = 0.1f * vel;
- CParticle::AddParticle(PARTICLE_GUNSMOKE2, smokepos, smokevel, NULL, 0.005f*size);
+ if ( (TheCamera.GetPosition() - pos).Magnitude() > 5.0f )
+ {
+ for ( int32 i = 0; i < 1; i++ )
+ {
+ int32 angle = 180 * i;
+
+ float fCos = CParticle::Cos(angle);
+ float fSin = CParticle::Sin(angle);
+
+ CVector splashpos, splashvel;
+
+ splashpos = pos + CVector(0.01f*fCos, 0.01f*fSin, 0.0f);
+ splashvel = vel + CVector(0.0f, 0.0f, CGeneral::GetRandomNumberInRange(0.004f, 0.008f));
+
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil,
+ CGeneral::GetRandomNumberInRange(0.005f, 0.0075f), this->m_Color, 0, 0, 1, 300);
+
+ splashpos = pos + CVector(0.01f*fCos, 0.01f*-fSin, 0.0f);
+ splashvel = vel + CVector(0.0f, 0.0f, CGeneral::GetRandomNumberInRange(0.004f, 0.008f));
+
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil,
+ CGeneral::GetRandomNumberInRange(0.005f, 0.0075f), this->m_Color, 0, 0, 1, 300);
+
+ splashpos = pos + CVector(0.01f*-fCos, 0.01f*fSin, 0.0f);
+ splashvel = vel + CVector(0.0f, 0.0f, CGeneral::GetRandomNumberInRange(0.004f, 0.008f));
+
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil,
+ CGeneral::GetRandomNumberInRange(0.005f, 0.0075f), this->m_Color, 0, 0, 1, 300);
+
+ splashpos = pos + CVector(0.01f*-fCos, 0.01f*-fSin, 0.0f);
+ splashvel = vel + CVector(0.0f, 0.0f, CGeneral::GetRandomNumberInRange(0.004f, 0.008f));
+
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil,
+ CGeneral::GetRandomNumberInRange(0.005f, 0.0075f), this->m_Color, 0, 0, 1, 300);
+ }
+ for ( int32 i = 0; i < this->m_nNumEffectCycles; i++ )
+ {
+ CParticle::AddParticle(this->m_ParticleType, pos, vel, nil, 0.0f, this->m_Color);
+ }
+ }
break;
}
- case POBJECT_CATALINAS_SHOTGUNFLASH:
+ case POBJECT_WATER_FOUNTAIN_VERT:
{
- CRGBA flashcolor(120, 120, 120, 255);
-
+ CVector pos = this->GetPosition();
CVector vel = this->m_vecTarget;
- float size = 1.0f;
- if ( this->m_fSize != 0.0f )
- size = this->m_fSize;
+ for ( int32 i = 0; i < 2; i++ )
+ {
+ int32 angle = 180 * i;
+
+ float fCos = CParticle::Cos(angle);
+ float fSin = CParticle::Sin(angle);
+
+ CVector splashpos, splashvel;
+
+ splashpos = pos + CVector(0.015f*fCos, 0.015f*fSin, 0.0f);
+ splashvel = vel + CVector(0.015f*fCos, 0.015f*fSin, CGeneral::GetRandomNumberInRange(0.004f, 0.008f));
+
+ CParticle::AddParticle(PARTICLE_SPLASH, splashpos, splashvel, nil,
+ CGeneral::GetRandomNumberInRange(0.001f, 0.005f), this->m_Color, 0, 0, 1, 1000);
+
+ splashpos = pos + CVector(0.015f*fCos, 0.015f*-fSin, 0.0f);
+ splashvel = vel + CVector(0.015f*fCos, 0.015f*-fSin, CGeneral::GetRandomNumberInRange(0.004f, 0.008f));
+
+ CParticle::AddParticle(PARTICLE_SPLASH, splashpos, splashvel, nil,
+ CGeneral::GetRandomNumberInRange(0.001f, 0.005f), this->m_Color, 0, 0, 1, 1000);
+
+ splashpos = pos + CVector(0.015f*-fCos, 0.015f*fSin, 0.0f);
+ splashvel = vel + CVector(0.015f*-fCos, 0.015f*fSin, CGeneral::GetRandomNumberInRange(0.004f, 0.008f));
+
+ CParticle::AddParticle(PARTICLE_SPLASH, splashpos, splashvel, nil,
+ CGeneral::GetRandomNumberInRange(0.001f, 0.005f), this->m_Color, 0, 0, 1, 1000);
+
+ splashpos = pos + CVector(0.015f*-fCos, 0.015f*-fSin, 0.0f);
+ splashvel = vel + CVector(0.015f*-fCos, 0.015f*-fSin, CGeneral::GetRandomNumberInRange(0.004f, 0.008f));
+
+ CParticle::AddParticle(PARTICLE_SPLASH, splashpos, splashvel, nil,
+ CGeneral::GetRandomNumberInRange(0.001f, 0.005f), this->m_Color, 0, 0, 1, 1000);
+ }
+ break;
+ }
+
+ case POBJECT_WATER_FOUNTAIN_HORIZ:
+ {
CVector pos = this->GetPosition();
-
- CVector velstep = size * (0.1f * vel);
- CVector flashpos = pos;
-
- flashpos += velstep;
- CParticle::AddParticle(PARTICLE_GUNFLASH, flashpos, CVector(0.0f, 0.0f, 0.0f), NULL, 0.0f, flashcolor);
-
- flashpos += velstep;
- CParticle::AddParticle(PARTICLE_GUNFLASH, flashpos, CVector(0.0f, 0.0f, 0.0f), NULL, 0.15f*size, flashcolor);
-
- flashpos += velstep;
- CParticle::AddParticle(PARTICLE_GUNFLASH, flashpos, CVector(0.0f, 0.0f, 0.0f), NULL, 0.2f*size, flashcolor);
-
+ CVector vel = this->m_vecTarget;
- CParticle::AddParticle(PARTICLE_GUNFLASH, pos, CVector(0.0f, 0.0f, 0.0f), NULL, 0.0f, flashcolor);
+ for ( int32 i = 0; i < 3; i++ )
+ {
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, vel, nil, 0.001f, this->m_Color, 0, 0, 1, 1000);
+ }
- CVector smokepos = this->GetPosition();
- CVector smokevel = 0.1f*vel;
- CParticle::AddParticle(PARTICLE_GUNSMOKE2, smokepos, smokevel, NULL, 0.1f*size);
-
break;
}
@@ -1068,7 +1008,7 @@ void CParticleObject::UpdateClose(void)
if ( vel.z != 0.0f )
vel.z += CGeneral::GetRandomNumberInRange(-this->m_fRandVal, this->m_fRandVal);
- CParticle::AddParticle(this->m_ParticleType, this->GetPosition(), vel, NULL,
+ CParticle::AddParticle(this->m_ParticleType, this->GetPosition(), vel, nil,
this->m_fSize, this->m_Color);
}
}
@@ -1076,7 +1016,7 @@ void CParticleObject::UpdateClose(void)
{
for ( int32 i = 0; i < this->m_nNumEffectCycles; i++ )
{
- CParticle::AddParticle(this->m_ParticleType, this->GetPosition(), this->m_vecTarget, NULL,
+ CParticle::AddParticle(this->m_ParticleType, this->GetPosition(), this->m_vecTarget, nil,
this->m_fSize, this->m_Color);
}
}
@@ -1126,7 +1066,6 @@ SaveOneParticle(CParticleObject *p, uint8 *&buffer)
#define CopyToBuf(buf, data) memcpy(buf, &data, sizeof(data)); SkipBuf(buf, sizeof(data))
// CPlaceable
{
- ZeroBuf(buffer, 4);
CopyToBuf(buffer, p->GetMatrix().f);
ZeroBuf(buffer, 4);
CopyToBuf(buffer, p->GetMatrix().m_hasRwMatrix);
@@ -1163,15 +1102,15 @@ SaveOneParticle(CParticleObject *p, uint8 *&buffer)
bool
CParticleObject::SaveParticle(uint8 *buffer, uint32 *length)
{
- ASSERT( buffer != NULL );
- ASSERT( length != NULL );
+ ASSERT( buffer != nil );
+ ASSERT( length != nil );
int32 numObjects = 0;
- for ( CParticleObject *p = pCloseListHead; p != NULL; p = p->m_pNext )
+ for ( CParticleObject *p = pCloseListHead; p != nil; p = p->m_pNext )
++numObjects;
- for ( CParticleObject *p = pFarListHead; p != NULL; p = p->m_pNext )
+ for ( CParticleObject *p = pFarListHead; p != nil; p = p->m_pNext )
++numObjects;
*(int32 *)buffer = numObjects;
@@ -1180,7 +1119,7 @@ CParticleObject::SaveParticle(uint8 *buffer, uint32 *length)
int32 objectsLength = PARTICLE_OBJECT_SIZEOF * (numObjects + 1);
int32 dataLength = objectsLength + sizeof(int32);
- for ( CParticleObject *p = pCloseListHead; p != NULL; p = p->m_pNext )
+ for ( CParticleObject *p = pCloseListHead; p != nil; p = p->m_pNext )
{
#ifdef COMPATIBLE_SAVES
SaveOneParticle(p, buffer);
@@ -1194,7 +1133,7 @@ CParticleObject::SaveParticle(uint8 *buffer, uint32 *length)
#endif
}
- for ( CParticleObject *p = pFarListHead; p != NULL; p = p->m_pNext )
+ for ( CParticleObject *p = pFarListHead; p != nil; p = p->m_pNext )
{
#ifdef COMPATIBLE_SAVES
SaveOneParticle(p, buffer);
@@ -1216,7 +1155,7 @@ CParticleObject::SaveParticle(uint8 *buffer, uint32 *length)
bool
CParticleObject::LoadParticle(uint8 *buffer, uint32 length)
{
- ASSERT( buffer != NULL );
+ ASSERT( buffer != nil );
RemoveAllParticleObjects();
@@ -1239,11 +1178,11 @@ CParticleObject::LoadParticle(uint8 *buffer, uint32 length)
buffer += sizeof(CParticleObject);
#endif
- if ( dst == NULL )
+ if ( dst == nil )
return false;
MoveToList(&pUnusedListHead, &pCloseListHead, dst);
-
+
#ifndef COMPATIBLE_SAVES
dst->m_nState = POBJECTSTATE_UPDATE_CLOSE;
dst->m_Type = src->m_Type;
@@ -1252,7 +1191,7 @@ CParticleObject::LoadParticle(uint8 *buffer, uint32 length)
dst->m_vecTarget = src->m_vecTarget;
dst->m_nFrameCounter = src->m_nFrameCounter;
dst->m_bRemove = src->m_bRemove;
- dst->m_pParticle = NULL;
+ dst->m_pParticle = nil;
dst->m_nRemoveTimer = src->m_nRemoveTimer;
dst->m_Color = src->m_Color;
dst->m_fSize = src->m_fSize;
@@ -1268,7 +1207,6 @@ CParticleObject::LoadParticle(uint8 *buffer, uint32 length)
#define CopyFromBuf(buf, data) memcpy(&data, buf, sizeof(data)); SkipBuf(buf, sizeof(data))
// CPlaceable
{
- SkipBuf(buffer, 4);
CMatrix matrix;
CopyFromBuf(buffer, matrix.f);
SkipBuf(buffer, 4);
@@ -1309,22 +1247,64 @@ CParticleObject::LoadParticle(uint8 *buffer, uint32 length)
}
void
+CParticleObject::RemoveAllExpireableParticleObjects(void)
+{
+ {
+ CParticleObject *pobj = pCloseListHead;
+ CParticleObject *nextpobj;
+ if ( pobj != nil )
+ {
+ do
+ {
+ nextpobj = pobj->m_pNext;
+ if ( pobj->m_nRemoveTimer != 0 )
+ {
+ MoveToList(&pCloseListHead, &pUnusedListHead, pobj);
+ pobj->m_nState = POBJECTSTATE_FREE;
+ }
+ pobj = nextpobj;
+ }
+ while ( nextpobj != nil );
+ }
+ }
+
+ {
+ CParticleObject *pobj = pFarListHead;
+ CParticleObject *nextpobj;
+ if ( pobj != nil )
+ {
+ do
+ {
+ nextpobj = pobj->m_pNext;
+ if ( pobj->m_nRemoveTimer != 0 )
+ {
+ MoveToList(&pFarListHead, &pUnusedListHead, pobj);
+ pobj->m_nState = POBJECTSTATE_FREE;
+ }
+ pobj = nextpobj;
+ }
+ while ( nextpobj != nil );
+ }
+ }
+}
+
+void
CParticleObject::RemoveAllParticleObjects(void)
{
pUnusedListHead = &gPObjectArray[0];
- pCloseListHead = NULL;
- pFarListHead = NULL;
+ pCloseListHead = nil;
+ pFarListHead = nil;
for ( int32 i = 0; i < MAX_PARTICLEOBJECTS; i++ )
{
if ( i == 0 )
- gPObjectArray[i].m_pPrev = NULL;
+ gPObjectArray[i].m_pPrev = nil;
else
gPObjectArray[i].m_pPrev = &gPObjectArray[i - 1];
if ( i == MAX_PARTICLEOBJECTS-1 )
- gPObjectArray[i].m_pNext = NULL;
+ gPObjectArray[i].m_pNext = nil;
else
gPObjectArray[i].m_pNext = &gPObjectArray[i + 1];
@@ -1335,20 +1315,20 @@ CParticleObject::RemoveAllParticleObjects(void)
void
CParticleObject::MoveToList(CParticleObject **from, CParticleObject **to, CParticleObject *obj)
{
- ASSERT( from != NULL );
- ASSERT( to != NULL );
- ASSERT( obj != NULL );
+ ASSERT( from != nil );
+ ASSERT( to != nil );
+ ASSERT( obj != nil );
- if ( obj->m_pPrev == NULL )
+ if ( obj->m_pPrev == nil )
{
*from = obj->m_pNext;
if ( *from )
- (*from)->m_pPrev = NULL;
+ (*from)->m_pPrev = nil;
}
else
{
- if ( obj->m_pNext == NULL )
- obj->m_pPrev->m_pNext = NULL;
+ if ( obj->m_pNext == nil )
+ obj->m_pPrev->m_pNext = nil;
else
{
obj->m_pNext->m_pPrev = obj->m_pPrev;
@@ -1357,7 +1337,7 @@ CParticleObject::MoveToList(CParticleObject **from, CParticleObject **to, CParti
}
obj->m_pNext = *to;
- obj->m_pPrev = NULL;
+ obj->m_pPrev = nil;
*to = obj;
if ( obj->m_pNext )
diff --git a/src/objects/ParticleObject.h b/src/objects/ParticleObject.h
index e4e7fcd2..f199e533 100644
--- a/src/objects/ParticleObject.h
+++ b/src/objects/ParticleObject.h
@@ -4,12 +4,12 @@
#include "ParticleType.h"
#include "Placeable.h"
-#define MAX_PARTICLEOBJECTS 100
+#define MAX_PARTICLEOBJECTS 70
#define MAX_AUDIOHYDRANTS 8
enum eParticleObjectType
{
- POBJECT_PAVEMENT_STEAM,
+ POBJECT_PAVEMENT_STEAM = 0,
POBJECT_PAVEMENT_STEAM_SLOWMOTION,
POBJECT_WALL_STEAM,
POBJECT_WALL_STEAM_SLOWMOTION,
@@ -22,6 +22,8 @@ enum eParticleObjectType
POBJECT_BIG_FIRE,
POBJECT_DRY_ICE,
POBJECT_DRY_ICE_SLOWMOTION,
+ POBJECT_WATER_FOUNTAIN_VERT,
+ POBJECT_WATER_FOUNTAIN_HORIZ,
POBJECT_FIRE_TRAIL,
POBJECT_SMOKE_TRAIL,
POBJECT_FIREBALL_AND_SMOKE,
@@ -69,12 +71,13 @@ public:
~CParticleObject();
static void Initialise(void);
-
- static CParticleObject *AddObject(uint16 type, CVector const &pos, uint8 remove);
- static CParticleObject *AddObject(uint16 type, CVector const &pos, float size, uint8 remove);
- static CParticleObject *AddObject(uint16 type, CVector const &pos, CVector const &target, float size, uint8 remove);
- static CParticleObject *AddObject(uint16 type, CVector const &pos, CVector const &target, float size, uint32 lifeTime, RwRGBA const &color, uint8 remove);
-
+
+ static CParticleObject *AddObject(uint16 type, CVector const &pos, uint8 remove);
+ static CParticleObject *AddObject(uint16 type, CVector const &pos, float size, uint8 remove);
+ static CParticleObject *AddObject(uint16 type, CVector const &pos, CVector const &target, float size, uint8 remove);
+ static CParticleObject *AddObject(uint16 type, CVector const &pos, CVector const &target, float size, uint32 lifeTime, RwRGBA const &color, uint8 remove);
+ static CParticleObject *AddObject(tParticleType type, CVector const &pos, CVector const &target, float size, uint32 lifeTime, uint8 numEffectCycles, uint8 skipFrames, uint16 creationChance, uint8 remove);
+
void RemoveObject(void);
static void UpdateAll(void);
@@ -84,6 +87,7 @@ public:
static bool SaveParticle(uint8 *buffer, uint32 *length);
static bool LoadParticle(uint8 *buffer, uint32 length);
+ static void RemoveAllExpireableParticleObjects(void);
static void RemoveAllParticleObjects(void);
static void MoveToList(CParticleObject **from, CParticleObject **to, CParticleObject *obj);
};
@@ -98,7 +102,7 @@ public:
CAudioHydrant() :
AudioEntity(AEHANDLE_NONE),
- pParticleObject(NULL)
+ pParticleObject(nil)
{ }
static bool Add (CParticleObject *particleobject);
diff --git a/src/objects/Stinger.cpp b/src/objects/Stinger.cpp
new file mode 100644
index 00000000..d3eee416
--- /dev/null
+++ b/src/objects/Stinger.cpp
@@ -0,0 +1,259 @@
+#include "common.h"
+#include "Stinger.h"
+#include "CopPed.h"
+#include "ModelIndices.h"
+#include "RpAnimBlend.h"
+#include "World.h"
+#include "Automobile.h"
+#include "Bike.h"
+#include "Particle.h"
+#include "AnimBlendAssociation.h"
+#include "General.h"
+
+uint32 NumOfStingerSegments;
+
+/* -- CStingerSegment -- */
+
+CStingerSegment::CStingerSegment()
+{
+ m_fMass = 1.0f;
+ m_fTurnMass = 1.0f;
+ m_fAirResistance = 0.99999f;
+ m_fElasticity = 0.75f;
+ m_fBuoyancy = GRAVITY * m_fMass * 0.1f;
+ bExplosionProof = true;
+ SetModelIndex(MI_PLC_STINGER);
+ ObjectCreatedBy = CONTROLLED_SUB_OBJECT;
+ NumOfStingerSegments++;
+}
+
+CStingerSegment::~CStingerSegment()
+{
+ NumOfStingerSegments--;
+}
+
+/* -- CStinger -- */
+
+CStinger::CStinger()
+{
+ bIsDeployed = false;
+}
+
+void
+CStinger::Init(CPed *pPed)
+{
+ int32 i;
+
+ pOwner = pPed;
+ for (i = 0; i < NUM_STINGER_SEGMENTS; i++) {
+ pSpikes[i] = new CStingerSegment();
+#ifdef FIX_BUGS
+ if (!pSpikes[i]) {
+ // Abort!! Pool is full
+ Remove();
+ return;
+ }
+#endif
+ pSpikes[i]->bUsesCollision = false;
+ }
+ bIsDeployed = true;
+ m_vPos = pPed->GetPosition();
+ m_vPos.z -= 1.0f;
+ m_fMax_Z = Atan2(-pPed->GetForward().x, pPed->GetForward().y) + HALFPI;
+
+ for (i = 0; i < NUM_STINGER_SEGMENTS; i++) {
+ pSpikes[i]->SetOrientation(0.0f, 0.0f, Atan2(-pPed->GetForward().x, pPed->GetForward().y));
+ pSpikes[i]->SetPosition(m_vPos);
+ }
+
+ CVector2D fwd2d(pPed->GetForward().x, pPed->GetForward().y);
+
+ for (i = 0; i < ARRAY_SIZE(m_vPositions); i++)
+ m_vPositions[i] = fwd2d * 1.8f * Sin(DEGTORAD(i));
+
+ m_nSpikeState = STINGERSTATE_NONE;
+ m_nTimeOfDeploy = CTimer::GetTimeInMilliseconds();
+}
+
+void
+CStinger::Remove()
+{
+ if (!bIsDeployed) return;
+
+ for (int32 i = 0; i < NUM_STINGER_SEGMENTS; i++) {
+ CStingerSegment *spikeSegment = pSpikes[i];
+
+#ifdef FIX_BUGS
+ if (spikeSegment) {
+ CWorld::Remove(spikeSegment);
+ delete spikeSegment;
+ pSpikes[i] = nil;
+ }
+#else
+ if (spikeSegment->m_entryInfoList.first != nil)
+ spikeSegment->bRemoveFromWorld = true;
+ else
+ delete spikeSegment;
+#endif
+ }
+ bIsDeployed = false;
+}
+
+void
+CStinger::Deploy(CPed *pPed)
+{
+ // So total number of stingers allowed at the same time is 2, each by different CCopPed.
+ if (NumOfStingerSegments < NUM_STINGER_SEGMENTS*2 && !pPed->bInVehicle && pPed->IsPedInControl()) {
+ if (!bIsDeployed && RpAnimBlendClumpGetAssociation(pPed->GetClump(), ANIM_STD_THROW_UNDER) == nil) {
+ Init(pPed);
+#ifdef FIX_BUGS
+ // Above call won't set it to true no more when object pool is full
+ if (!bIsDeployed)
+ return;
+#endif
+ pPed->SetPedState(PED_DEPLOY_STINGER);
+ CAnimManager::AddAnimation(pPed->GetClump(), ASSOCGRP_STD, ANIM_STD_THROW_UNDER);
+ }
+ }
+}
+
+void
+CStinger::CheckForBurstTyres()
+{
+ CVector firstPos = pSpikes[0]->GetPosition();
+ firstPos.z += 0.2f;
+ CVector lastPos = pSpikes[NUM_STINGER_SEGMENTS - 1]->GetPosition();
+ lastPos.z += 0.2f;
+ float dist = (lastPos - firstPos).Magnitude();
+ if (dist < 0.1f) return;
+
+ CVehicle *vehsInRange[16];
+ int16 numObjects;
+ CEntity entity;
+
+ CWorld::FindObjectsInRange((lastPos + firstPos) / 2.0f,
+ dist, true, &numObjects, 15, (CEntity**)vehsInRange,
+ false, true, false, false, false);
+
+ for (int32 i = 0; i < numObjects; i++) {
+ CAutomobile *pAutomobile = nil;
+ CBike *pBike = nil;
+
+ if (vehsInRange[i]->IsCar())
+ pAutomobile = (CAutomobile*)vehsInRange[i];
+ else if (vehsInRange[i]->IsBike())
+ pBike = (CBike*)vehsInRange[i];
+
+ if (pAutomobile == nil && pBike == nil) continue;
+
+ float maxWheelDistToSpike = sq(((CVehicleModelInfo*)CModelInfo::GetModelInfo(vehsInRange[i]->GetModelIndex()))->m_wheelScale + 0.1f);
+
+ for (int wheelId = 0; wheelId < 4; wheelId++) {
+ if ((pAutomobile != nil && pAutomobile->m_aSuspensionSpringRatioPrev[wheelId] < 1.0f) ||
+ (pBike != nil && pBike->m_aSuspensionSpringRatioPrev[wheelId] < 1.0f)) {
+ CVector vecWheelPos;
+ if (pAutomobile != nil)
+ vecWheelPos = pAutomobile->m_aWheelColPoints[wheelId].point;
+ else if (pBike != nil)
+ vecWheelPos = pBike->m_aWheelColPoints[wheelId].point;
+
+ for (int32 spike = 0; spike < NUM_STINGER_SEGMENTS; spike++) {
+ if ((pSpikes[spike]->GetPosition() - vecWheelPos).Magnitude() < maxWheelDistToSpike) {
+ if (pBike) {
+ if (wheelId < 2)
+ vehsInRange[i]->BurstTyre(CAR_PIECE_WHEEL_LF, true);
+ else
+ vehsInRange[i]->BurstTyre(CAR_PIECE_WHEEL_LR, true);
+ }
+ else {
+ switch (wheelId) {
+ case 0: vehsInRange[i]->BurstTyre(CAR_PIECE_WHEEL_LF, true); break;
+ case 1: vehsInRange[i]->BurstTyre(CAR_PIECE_WHEEL_LR, true); break;
+ case 2: vehsInRange[i]->BurstTyre(CAR_PIECE_WHEEL_RF, true); break;
+ case 3: vehsInRange[i]->BurstTyre(CAR_PIECE_WHEEL_RR, true); break;
+ }
+ }
+ vecWheelPos.z += 0.15f;
+ for (int j = 0; j < 4; j++)
+ CParticle::AddParticle(PARTICLE_BULLETHIT_SMOKE, vecWheelPos, vehsInRange[i]->GetRight() * 0.1f);
+ }
+ }
+ }
+ }
+ }
+}
+
+// Only called when bIsDeployed
+void
+CStinger::Process()
+{
+ switch (m_nSpikeState)
+ {
+ case STINGERSTATE_NONE:
+ if (pOwner != nil
+ && !pOwner->bInVehicle
+ && pOwner->GetPedState() == PED_DEPLOY_STINGER
+ && RpAnimBlendClumpGetAssociation(pOwner->GetClump(), ANIM_STD_THROW_UNDER)->currentTime > 0.39f)
+ {
+ m_nSpikeState = STINGERSTATE_DEPLOYING;
+ for (int i = 0; i < NUM_STINGER_SEGMENTS; i++)
+ CWorld::Add(pSpikes[i]);
+ pOwner->SetIdle();
+ }
+ break;
+ case STINGERSTATE_DEPLOYED:
+ if (pOwner != nil && pOwner->m_nPedType == PEDTYPE_COP)
+ ((CCopPed*)pOwner)->m_bThrowsSpikeTrap = false;
+ break;
+ case STINGERSTATE_UNDEPLOYING:
+ if (CTimer::GetTimeInMilliseconds() > m_nTimeOfDeploy + 2500)
+ m_nSpikeState = STINGERSTATE_REMOVE;
+ // no break
+ case STINGERSTATE_DEPLOYING:
+ if (m_nSpikeState == STINGERSTATE_DEPLOYING && CTimer::GetTimeInMilliseconds() > m_nTimeOfDeploy + 2500)
+ m_nSpikeState = STINGERSTATE_DEPLOYED;
+ else {
+ float progress = (CTimer::GetTimeInMilliseconds() - m_nTimeOfDeploy) / 2500.0f;
+ if (m_nSpikeState != STINGERSTATE_DEPLOYING)
+ progress = 1.0f - progress;
+
+ float degangle = progress * ARRAY_SIZE(m_vPositions);
+ float angle1 = m_fMax_Z + DEGTORAD(degangle);
+ float angle2 = m_fMax_Z - DEGTORAD(degangle);
+ int pos = Clamp(degangle, 0, ARRAY_SIZE(m_vPositions)-1);
+
+ CVector2D pos2d = m_vPositions[pos];
+ CVector pos3d = m_vPos;
+ CColPoint colPoint;
+ CEntity *pEntity;
+ if (CWorld::ProcessVerticalLine(CVector(pos3d.x, pos3d.y, pos3d.z - 10.0f), pos3d.z, colPoint, pEntity, true, false, false, false, true, false, nil))
+ pos3d.z = colPoint.point.z + 0.15f;
+
+ angle1 = CGeneral::LimitRadianAngle(angle1);
+ angle2 = CGeneral::LimitRadianAngle(angle2);
+
+ for (int spike = 0; spike < NUM_STINGER_SEGMENTS; spike++) {
+ if (CWorld::TestSphereAgainstWorld(pos3d + CVector(pos2d.x, pos2d.y, 0.6f), 0.3f, nil, true, false, false, true, false, false))
+ pos2d = CVector2D(0.0f, 0.0f);
+
+ if (spike % 2 == 0) {
+ pSpikes[spike]->SetOrientation(0.0f, 0.0f, angle1);
+ pos3d.x += pos2d.x;
+ pos3d.y += pos2d.y;
+ } else {
+ pSpikes[spike]->SetOrientation(0.0f, 0.0f, angle2);
+ }
+ pSpikes[spike]->SetPosition(pos3d);
+ }
+ }
+ break;
+ case STINGERSTATE_REMOVE:
+ Remove();
+#ifdef FIX_BUGS
+ return;
+#else
+ break;
+#endif
+ }
+ CheckForBurstTyres();
+} \ No newline at end of file
diff --git a/src/objects/Stinger.h b/src/objects/Stinger.h
new file mode 100644
index 00000000..250cf62d
--- /dev/null
+++ b/src/objects/Stinger.h
@@ -0,0 +1,40 @@
+#pragma once
+
+#include "Object.h"
+
+class CStingerSegment : public CObject
+{
+public:
+ CStingerSegment();
+ ~CStingerSegment();
+};
+
+#define NUM_STINGER_SEGMENTS (12)
+
+enum {
+ STINGERSTATE_NONE = 0,
+ STINGERSTATE_DEPLOYING,
+ STINGERSTATE_DEPLOYED,
+ STINGERSTATE_UNDEPLOYING,
+ STINGERSTATE_REMOVE,
+};
+
+class CStinger
+{
+public:
+ bool bIsDeployed;
+ uint32 m_nTimeOfDeploy;
+ CVector m_vPos;
+ float m_fMax_Z;
+ float m_fMin_Z;
+ CVector2D m_vPositions[60];
+ CStingerSegment *pSpikes[NUM_STINGER_SEGMENTS];
+ class CPed *pOwner;
+ uint8 m_nSpikeState;
+ CStinger();
+ void Init(CPed *pPed);
+ void Remove();
+ void Deploy(CPed *pPed);
+ void CheckForBurstTyres();
+ void Process();
+}; \ No newline at end of file
diff --git a/src/peds/CivilianPed.cpp b/src/peds/CivilianPed.cpp
index 1c4f10f5..f3511366 100644
--- a/src/peds/CivilianPed.cpp
+++ b/src/peds/CivilianPed.cpp
@@ -9,29 +9,13 @@
#include "World.h"
#include "Vehicle.h"
#include "SurfaceTable.h"
+#include "Weather.h"
+#include "PedAttractor.h"
+#include "Object.h"
+#include "CarCtrl.h"
-#ifdef PEDS_REPORT_CRIMES_ON_PHONE
-eCrimeType
-EventTypeToCrimeType(eEventType event)
-{
- eCrimeType crime;
- switch (event) {
- case EVENT_ASSAULT: crime = CRIME_HIT_PED; break;
- case EVENT_RUN_REDLIGHT: crime = CRIME_RUN_REDLIGHT; break;
- case EVENT_ASSAULT_POLICE: crime = CRIME_HIT_COP; break;
- case EVENT_GUNSHOT: crime = CRIME_POSSESSION_GUN; break;
- case EVENT_STEAL_CAR: crime = CRIME_STEAL_CAR; break;
- case EVENT_HIT_AND_RUN: crime = CRIME_RUNOVER_PED; break;
- case EVENT_HIT_AND_RUN_COP: crime = CRIME_RUNOVER_COP; break;
- case EVENT_SHOOT_PED: crime = CRIME_SHOOT_PED; break;
- case EVENT_SHOOT_COP: crime = CRIME_SHOOT_COP; break;
- case EVENT_PED_SET_ON_FIRE: crime = CRIME_PED_BURNED; break;
- case EVENT_COP_SET_ON_FIRE: crime = CRIME_COP_BURNED; break;
- case EVENT_CAR_SET_ON_FIRE: crime = CRIME_VEHICLE_BURNED; break;
- default: crime = CRIME_NONE; break;
- }
- return crime;
-}
+#ifndef _WIN32
+#include <float.h>
#endif
CCivilianPed::CCivilianPed(ePedType pedtype, uint32 mi) : CPed(pedtype)
@@ -40,6 +24,26 @@ CCivilianPed::CCivilianPed(ePedType pedtype, uint32 mi) : CPed(pedtype)
for (int i = 0; i < ARRAY_SIZE(m_nearPeds); i++) {
m_nearPeds[i] = nil;
}
+ m_bLookForVacantCars = false;
+ if (pedtype == PEDTYPE_CRIMINAL)
+ m_bLookForVacantCars = true;
+
+ m_nLookForVacantCarsCounter = 0;
+ m_bJustStoleACar = false;
+ m_bStealCarEvenIfThereIsSomeoneInIt = false;
+ for (int i = 0; i < ARRAY_SIZE(m_nStealWishList); i++) {
+#ifdef FIX_BUGS
+ uint32 randomCarModel = CGeneral::GetRandomNumberInRange(MI_LANDSTAL, MI_LAST_VEHICLE);
+#else
+ uint32 randomCarModel = CGeneral::GetRandomNumberInRange(MI_LANDSTAL, MI_LANDSTAL + VEHICLEMODELSIZE);
+#endif
+ if (CModelInfo::IsCarModel(randomCarModel) || CModelInfo::IsBikeModel(randomCarModel))
+ m_nStealWishList[i] = randomCarModel;
+ else
+ m_nStealWishList[i] = MI_CHEETAH;
+ }
+ m_nAttractorCycleState = 0;
+ m_bAttractorUnk = (CGeneral::GetRandomNumberInRange(0.0f, 1.0f) < 1.25f);
}
void
@@ -58,7 +62,13 @@ CCivilianPed::CivilianAI(void)
if (CTimer::GetTimeInMilliseconds() <= m_lookTimer)
return;
- uint32 closestThreatFlag = ScanForThreats();
+ ScanForDelayedResponseThreats();
+ if (!m_threatFlags || CTimer::GetTimeInMilliseconds() <= m_threatCheckTimer)
+ return;
+ CheckThreatValidity();
+ uint32 closestThreatFlag = m_threatFlags;
+ m_threatFlags = 0;
+ m_threatCheckTimer = 0;
if (closestThreatFlag == PED_FLAG_EXPLOSION) {
float angleToFace = CGeneral::GetRadianAngleBetweenPoints(
m_eventOrThreat.x, m_eventOrThreat.y,
@@ -72,18 +82,30 @@ CCivilianPed::CivilianAI(void)
}
return;
}
- uint32 closestThreatFlag = ScanForThreats();
+ ScanForDelayedResponseThreats();
+ if (!m_threatFlags || CTimer::GetTimeInMilliseconds() <= m_threatCheckTimer)
+ return;
+ CheckThreatValidity();
+ uint32 closestThreatFlag = m_threatFlags;
+ m_threatFlags = 0;
+ m_threatCheckTimer = 0;
if (closestThreatFlag == PED_FLAG_GUN) {
if (!m_threatEntity || !m_threatEntity->IsPed())
return;
CPed *threatPed = (CPed*)m_threatEntity;
float threatDistSqr = (m_threatEntity->GetPosition() - GetPosition()).MagnitudeSqr2D();
+ if (CharCreatedBy == MISSION_CHAR && bCrouchWhenScared) {
+ SetDuck(10000, true);
+ SetLookFlag(m_threatEntity, false);
+ SetLookTimer(500);
+ return;
+ }
if (m_pedStats->m_fear <= m_pedStats->m_lawfulness) {
if (m_pedStats->m_temper <= m_pedStats->m_fear) {
if (!threatPed->IsPlayer() || !RunToReportCrime(CRIME_POSSESSION_GUN)) {
- if (threatDistSqr < sq(10.0f)) {
- Say(SOUND_PED_FLEE_SPRINT);
+ if (threatDistSqr < sq(30.0f)) {
+ bMakeFleeScream = true;
SetFindPathAndFlee(m_threatEntity, 10000);
} else {
SetFindPathAndFlee(m_threatEntity->GetPosition(), 5000, true);
@@ -93,13 +115,16 @@ CCivilianPed::CivilianAI(void)
SetFindPathAndFlee(m_threatEntity, 5000);
if (threatDistSqr < sq(20.0f)) {
SetMoveState(PEDMOVE_RUN);
- Say(SOUND_PED_FLEE_SPRINT);
+ bMakeFleeScream = true;
} else {
SetMoveState(PEDMOVE_WALK);
}
+ } else if (threatPed->IsPlayer() && IsGangMember() && bCanAttackPlayerWithCops) {
+ SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, m_threatEntity);
+
} else if (threatPed->IsPlayer() && FindPlayerPed()->m_pWanted->m_CurrentCops != 0) {
SetFindPathAndFlee(m_threatEntity, 5000);
- if (threatDistSqr < sq(10.0f)) {
+ if (threatDistSqr < sq(30.0f)) {
SetMoveState(PEDMOVE_RUN);
} else {
SetMoveState(PEDMOVE_WALK);
@@ -108,12 +133,12 @@ CCivilianPed::CivilianAI(void)
SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, m_threatEntity);
}
} else {
- if (threatDistSqr < sq(10.0f)) {
- Say(SOUND_PED_FLEE_SPRINT);
+ if (threatDistSqr < sq(30.0f)) {
+ bMakeFleeScream = true;
SetFindPathAndFlee(m_threatEntity, 10000);
SetMoveState(PEDMOVE_SPRINT);
} else {
- Say(SOUND_PED_FLEE_SPRINT);
+ bMakeFleeScream = false;
SetFindPathAndFlee(m_threatEntity, 5000);
SetMoveState(PEDMOVE_RUN);
}
@@ -122,7 +147,10 @@ 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 (CharCreatedBy == MISSION_CHAR && bCrouchWhenScared && eventDistSqr < sq(5.0f)) {
+ SetDuck(10000, true);
+
+ } else 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);
@@ -137,32 +165,21 @@ CCivilianPed::CivilianAI(void)
investigateDeadPed = false;
}
-#ifdef PEDS_REPORT_CRIMES_ON_PHONE
- int32 eventId = CheckForPlayerCrimes((CPed*)m_pEventEntity);
- eCrimeType crime = (eventId == -1 ? CRIME_NONE : EventTypeToCrimeType(gaEvent[eventId].type));
- bool eligibleToReport = crime != CRIME_NONE && m_pedStats->m_fear <= m_pedStats->m_lawfulness && m_pedStats->m_temper <= m_pedStats->m_fear;
- if (IsGangMember() || !eligibleToReport || !RunToReportCrime(crime))
-#endif
if (investigateDeadPed)
SetInvestigateEvent(EVENT_DEAD_PED, CVector2D(m_pEventEntity->GetPosition()), 1.0f, 20000, 0.0f);
} else {
-#ifdef PEDS_REPORT_CRIMES_ON_PHONE
- int32 eventId = CheckForPlayerCrimes((CPed*)m_pEventEntity);
- eCrimeType crime = (eventId == -1 ? CRIME_NONE : EventTypeToCrimeType(gaEvent[eventId].type));
- bool eligibleToReport = crime != CRIME_NONE && m_pedStats->m_fear <= m_pedStats->m_lawfulness && m_pedStats->m_temper <= m_pedStats->m_fear;
- if(!eligibleToReport || !RunToReportCrime(crime))
-#endif
- {
- SetFindPathAndFlee(m_pEventEntity, 5000);
- SetMoveState(PEDMOVE_RUN);
- }
+ SetFindPathAndFlee(m_pEventEntity, 5000);
+ SetMoveState(PEDMOVE_RUN);
}
} else if (closestThreatFlag == PED_FLAG_EXPLOSION) {
CVector2D eventDistVec = m_eventOrThreat - GetPosition();
float eventDistSqr = eventDistVec.MagnitudeSqr();
- if (eventDistSqr < sq(20.0f)) {
- Say(SOUND_PED_FLEE_SPRINT);
+ if (CharCreatedBy == MISSION_CHAR && bCrouchWhenScared && eventDistSqr < sq(20.0f)) {
+ SetDuck(10000, true);
+
+ } else if (eventDistSqr < sq(20.0f)) {
+ bMakeFleeScream = true;
SetFlee(m_eventOrThreat, 2000);
float angleToFace = CGeneral::GetRadianAngleBetweenPoints(
m_eventOrThreat.x, m_eventOrThreat.y,
@@ -184,55 +201,32 @@ CCivilianPed::CivilianAI(void)
}
}
} else {
-#ifdef PEDS_REPORT_CRIMES_ON_PHONE
- bool youShouldRunEventually = false;
- bool dontGoToPhone = false;
-#endif
if (m_threatEntity && m_threatEntity->IsPed()) {
CPed *threatPed = (CPed*)m_threatEntity;
if (m_pedStats->m_fear <= 100 - threatPed->m_pedStats->m_temper && threatPed->m_nPedType != PEDTYPE_COP) {
- if (threatPed->GetWeapon(m_currentWeapon).IsTypeMelee() || !GetWeapon()->IsTypeMelee()) {
- if (threatPed->IsPlayer() && FindPlayerPed()->m_pWanted->m_CurrentCops != 0) {
+ if (threatPed->GetWeapon()->IsTypeMelee() || !GetWeapon()->IsTypeMelee()) {
+ if (threatPed->IsPlayer() && IsGangMember() && bCanAttackPlayerWithCops) {
+ SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, m_threatEntity);
+
+ } else if (threatPed->IsPlayer() && FindPlayerPed()->m_pWanted->m_CurrentCops != 0) {
if (m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT || m_objective == OBJECTIVE_KILL_CHAR_ANY_MEANS) {
-#ifdef PEDS_REPORT_CRIMES_ON_PHONE
- dontGoToPhone = true;
-#endif
SetFindPathAndFlee(m_threatEntity, 10000);
}
} else {
-#ifdef PEDS_REPORT_CRIMES_ON_PHONE
- dontGoToPhone = true;
-#endif
SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, m_threatEntity);
}
}
} else {
-#ifdef PEDS_REPORT_CRIMES_ON_PHONE
- youShouldRunEventually = true;
-#else
- SetFindPathAndFlee(m_threatEntity, 10000, true);
-#endif
- }
- }
-
-#ifdef PEDS_REPORT_CRIMES_ON_PHONE
- if (!dontGoToPhone) {
- int32 eventId = CheckForPlayerCrimes(nil);
- eCrimeType crime = (eventId == -1 ? CRIME_NONE : EventTypeToCrimeType(gaEvent[eventId].type));
- bool eligibleToReport = crime != CRIME_NONE && m_pedStats->m_fear <= m_pedStats->m_lawfulness;
-
- if ((!eligibleToReport || !RunToReportCrime(crime)) && youShouldRunEventually) {
SetFindPathAndFlee(m_threatEntity, 10000, true);
}
}
-#endif
}
}
void
CCivilianPed::ProcessControl(void)
{
- if (m_nZoneLevel > LEVEL_GENERIC && m_nZoneLevel != CCollision::ms_collisionInMemory)
+ if (CharCreatedBy == UNK_CHAR)
return;
CPed::ProcessControl();
@@ -243,7 +237,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:
@@ -260,19 +254,10 @@ 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 || m_objective == OBJECTIVE_SPRINT_TO_AREA ||
+ IsUseAttractorObjective(m_objective)) && m_pNextPathNode) {
m_pNextPathNode = nil;
-#ifdef PEDS_REPORT_CRIMES_ON_PHONE
- } else if (bRunningToPhone && m_objective < OBJECTIVE_FLEE_ON_FOOT_TILL_SAFE) {
- if (crimeReporters[m_phoneId] != this) {
- RestorePreviousState();
- m_phoneId = -1;
- bRunningToPhone = false;
- } else {
- m_facePhoneStart = true;
- SetPedState(PED_FACE_PHONE);
- }
-#else
+
} else if (bRunningToPhone) {
if (gPhoneInfo.m_aPhones[m_phoneId].m_nState != PHONE_STATE_FREE) {
RestorePreviousState();
@@ -281,9 +266,8 @@ CCivilianPed::ProcessControl(void)
gPhoneInfo.m_aPhones[m_phoneId].m_nState = PHONE_STATE_REPORTING_CRIME;
SetPedState(PED_FACE_PHONE);
}
-#endif
} else if (m_objective != OBJECTIVE_KILL_CHAR_ANY_MEANS && m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT) {
- if (m_objective == OBJECTIVE_FOLLOW_CHAR_IN_FORMATION) {
+ if (m_pedInObjective && m_objective == OBJECTIVE_FOLLOW_CHAR_IN_FORMATION) {
if (m_moved.Magnitude() == 0.0f) {
if (m_pedInObjective->m_nMoveState == PEDMOVE_STILL)
m_fRotationDest = m_pedInObjective->m_fRotationCur;
@@ -291,7 +275,8 @@ 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 || m_objective == OBJECTIVE_SPRINT_TO_AREA ||
+ IsUseAttractorObjective(m_objective)) {
SetIdle();
} else {
RestorePreviousState();
@@ -357,6 +342,8 @@ CCivilianPed::ProcessControl(void)
GetPosition().x - m_pMyVehicle->GetPosition().x, GetPosition().y - m_pMyVehicle->GetPosition().y, 0.0f);
DMAudio.PlayOneShot(m_pMyVehicle->m_audioEntityId, SOUND_CAR_JERK, 0.0f);
+ m_pMyVehicle->pDriver->Say(SOUND_PED_PLAYER_BEFORESEX);
+ Say(SOUND_PED_PLAYER_BEFORESEX);
int playerSexFrequency = CWorld::Players[CWorld::PlayerInFocus].m_nSexFrequency;
if (CWorld::Players[CWorld::PlayerInFocus].m_nMoney >= 10 && playerSexFrequency > 250) {
@@ -367,19 +354,23 @@ 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 {
bWanderPathAfterExitingCar = true;
CWorld::Players[CWorld::PlayerInFocus].m_pHooker = nil;
+ ClearLeader();
SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
+ m_pMyVehicle->pDriver->Say(SOUND_PED_PLAYER_AFTERSEX);
}
} 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;
+ ClearLeader();
SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
+ m_pMyVehicle->pDriver->Say(SOUND_PED_PLAYER_AFTERSEX);
}
} else {
CWorld::Players[CWorld::PlayerInFocus].m_nNextSexFrequencyUpdateTime = CTimer::GetTimeInMilliseconds() + 3000;
@@ -392,6 +383,7 @@ CCivilianPed::ProcessControl(void)
} else {
bWanderPathAfterExitingCar = true;
CWorld::Players[CWorld::PlayerInFocus].m_pHooker = nil;
+ ClearLeader();
SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
}
}
@@ -412,6 +404,11 @@ CCivilianPed::ProcessControl(void)
if (IsPedInControl())
CivilianAI();
+ if (CharCreatedBy == RANDOM_CHAR) {
+ EnterVacantNearbyCars();
+ UseNearbyAttractors();
+ }
+
if (CTimer::GetTimeInMilliseconds() > m_timerUnused) {
m_stateUnused = 0;
m_timerUnused = 0;
@@ -421,27 +418,12 @@ CCivilianPed::ProcessControl(void)
Avoid();
}
-// It's "CPhoneInfo::ProcessNearestFreePhone" in PC IDB but that's not true, someone made it up.
bool
CPed::RunToReportCrime(eCrimeType crimeToReport)
{
-#ifdef PEDS_REPORT_CRIMES_ON_PHONE
- if (bRunningToPhone) {
- if (!isPhoneAvailable(m_phoneId) && crimeReporters[m_phoneId] != this) {
- crimeReporters[m_phoneId] = nil;
- m_phoneId = -1;
- bIsRunning = false;
- ClearSeek(); // clears bRunningToPhone
- return false;
- }
-
- return true;
- }
-#else
// They changed true into false to make this function unusable. So running to phone actually starts but first frame after that cancels it.
if (m_nPedState == PED_SEEK_POS)
return false;
-#endif
CVector pos = GetPosition();
int phoneId = gPhoneInfo.FindNearestFreePhone(&pos);
@@ -449,19 +431,180 @@ CPed::RunToReportCrime(eCrimeType crimeToReport)
if (phoneId == -1)
return false;
- CPhone *phone = &gPhoneInfo.m_aPhones[phoneId];
-#ifndef PEDS_REPORT_CRIMES_ON_PHONE
+ CPhone* phone = &gPhoneInfo.m_aPhones[phoneId];
if (phone->m_nState != PHONE_STATE_FREE)
return false;
-#else
- crimeReporters[phoneId] = this;
-#endif
bRunningToPhone = true;
- SetSeek(phone->m_pEntity->GetMatrix() * -phone->m_pEntity->GetForward(), 1.0f); // original: phone.m_vecPos, 0.3f
+ SetSeek(phone->m_vecPos, 0.3f);
SetMoveState(PEDMOVE_RUN);
- bIsRunning = true; // not there in original
m_phoneId = phoneId;
m_crimeToReportOnPhone = crimeToReport;
return true;
+}
+
+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->GetIsStatic() || ((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;
+}
+
+void
+CCivilianPed::EnterVacantNearbyCars(void)
+{
+ if (!m_bLookForVacantCars)
+ return;
+
+ if (m_bJustStoleACar && bInVehicle && m_carInObjective == m_pMyVehicle) {
+ m_bJustStoleACar = false;
+ m_pMyVehicle->SetStatus(STATUS_PHYSICS);
+ m_pMyVehicle->AutoPilot.m_nCarMission = MISSION_CRUISE;
+ m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 10;
+ m_pMyVehicle->bEngineOn = true;
+
+ } else if (!bHasAlreadyStoleACar) {
+ if (m_nLookForVacantCarsCounter == 8) {
+ m_nLookForVacantCarsCounter = 0;
+ if (IsPedInControl() && m_objective == OBJECTIVE_NONE) {
+
+ CVehicle *foundCar = nil;
+ float closestDist = FLT_MAX;
+ int minX = CWorld::GetSectorIndexX(GetPosition().x - 10.0f);
+ if (minX < 0) minX = 0;
+ int minY = CWorld::GetSectorIndexY(GetPosition().y - 10.0f);
+ if (minY < 0) minY = 0;
+ int maxX = CWorld::GetSectorIndexX(GetPosition().x + 10.0f);
+ if (maxX > NUMSECTORS_X - 1) maxX = NUMSECTORS_X - 1;
+ int maxY = CWorld::GetSectorIndexY(GetPosition().y + 10.0f);
+ if (maxY > NUMSECTORS_Y - 1) maxY = NUMSECTORS_Y - 1;
+
+ for (int curY = minY; curY <= maxY; curY++) {
+ for (int curX = minX; curX <= maxX; curX++) {
+ CSector* sector = CWorld::GetSector(curX, curY);
+ for (CPtrNode* node = sector->m_lists[ENTITYLIST_VEHICLES].first; node; node = node->next) {
+ CVehicle* veh = (CVehicle*)node->item;
+ if (veh && veh->IsCar()) {
+
+ // Looks like PARKED_VEHICLE condition isn't there in Mobile.
+ if (veh->VehicleCreatedBy == RANDOM_VEHICLE || veh->VehicleCreatedBy == PARKED_VEHICLE) {
+ if (IsOnStealWishList(veh->GetModelIndex()) && !veh->IsLawEnforcementVehicle()
+ && (m_bStealCarEvenIfThereIsSomeoneInIt || !veh->pDriver && !veh->m_nNumPassengers)
+ && !veh->m_nNumGettingIn && !veh->m_nGettingInFlags && !veh->m_nGettingOutFlags
+ && !veh->m_pCarFire && veh->m_fHealth > 800.0f
+ && !veh->IsUpsideDown() && !veh->IsOnItsSide() && veh->CanPedEnterCar()) {
+ float dist = (GetPosition() - veh->GetPosition()).MagnitudeSqr();
+ if (dist < sq(10.0f) && dist < closestDist && veh->IsClearToDriveAway()) {
+ foundCar = veh;
+ closestDist = dist;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if (foundCar) {
+ m_bJustStoleACar = true;
+ bHasAlreadyStoleACar = true;
+ CCarCtrl::JoinCarWithRoadSystem(foundCar);
+ SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, foundCar);
+ SetObjectiveTimer(10000);
+ }
+ }
+ } else {
+ ++m_nLookForVacantCarsCounter;
+ }
+ }
+}
+
+bool
+CCivilianPed::IsOnStealWishList(int32 model)
+{
+ for (int i = 0; i < ARRAY_SIZE(m_nStealWishList); i++) {
+ if (model == m_nStealWishList[i]) {
+ return true;
+ }
+ }
+ return false;
} \ No newline at end of file
diff --git a/src/peds/CivilianPed.h b/src/peds/CivilianPed.h
index 8418a99f..dcd49a96 100644
--- a/src/peds/CivilianPed.h
+++ b/src/peds/CivilianPed.h
@@ -4,13 +4,23 @@
class CCivilianPed : public CPed
{
+ bool m_bLookForVacantCars;
+ uint32 m_nLookForVacantCarsCounter;
+ bool m_bStealCarEvenIfThereIsSomeoneInIt; // unused
+ bool m_bJustStoleACar;
+ uint32 m_nStealWishList[16];
+ 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);
+ void EnterVacantNearbyCars(void);
+ bool IsOnStealWishList(int32);
};
-#ifndef PED_SKIN
-VALIDATE_SIZE(CCivilianPed, 0x53C);
-#endif
+//VALIDATE_SIZE(CCivilianPed, 0x53C);
diff --git a/src/peds/CopPed.cpp b/src/peds/CopPed.cpp
index 44e3baf0..1efd7733 100644
--- a/src/peds/CopPed.cpp
+++ b/src/peds/CopPed.cpp
@@ -16,14 +16,18 @@
#include "CarCtrl.h"
#include "Renderer.h"
#include "Camera.h"
+#include "PedPlacement.h"
+#include "Ropes.h"
+#include "Stinger.h"
-CCopPed::CCopPed(eCopType copType) : CPed(PEDTYPE_COP)
+CCopPed::CCopPed(eCopType copType, int32 modifier) : CPed(PEDTYPE_COP)
{
m_nCopType = copType;
switch (copType) {
case COP_STREET:
SetModelIndex(MI_COP);
- GiveWeapon(WEAPONTYPE_COLT45, 1000);
+ GiveWeapon(WEAPONTYPE_NIGHTSTICK, 1000, true);
+ GiveDelayedWeapon(WEAPONTYPE_COLT45, 1000);
m_currentWeapon = WEAPONTYPE_UNARMED;
m_fArmour = 0.0f;
m_wepSkills = 208; /* TODO: what is this? seems unused */
@@ -31,17 +35,16 @@ CCopPed::CCopPed(eCopType copType) : CPed(PEDTYPE_COP)
break;
case COP_FBI:
SetModelIndex(MI_FBI);
- GiveWeapon(WEAPONTYPE_COLT45, 1000);
- GiveWeapon(WEAPONTYPE_AK47, 1000);
- SetCurrentWeapon(WEAPONTYPE_AK47);
+ GiveDelayedWeapon(WEAPONTYPE_MP5, 1000);
+ SetCurrentWeapon(WEAPONTYPE_MP5);
m_fArmour = 100.0f;
m_wepSkills = 176; /* TODO: what is this? seems unused */
m_wepAccuracy = 76;
break;
case COP_SWAT:
+ case COP_HELI_SWAT:
SetModelIndex(MI_SWAT);
- GiveWeapon(WEAPONTYPE_COLT45, 1000);
- GiveWeapon(WEAPONTYPE_UZI, 1000);
+ GiveDelayedWeapon(WEAPONTYPE_UZI, 1000);
SetCurrentWeapon(WEAPONTYPE_UZI);
m_fArmour = 50.0f;
m_wepSkills = 32; /* TODO: what is this? seems unused */
@@ -49,37 +52,56 @@ CCopPed::CCopPed(eCopType copType) : CPed(PEDTYPE_COP)
break;
case COP_ARMY:
SetModelIndex(MI_ARMY);
- GiveWeapon(WEAPONTYPE_COLT45, 1000);
- GiveWeapon(WEAPONTYPE_M16, 1000);
- GiveWeapon(WEAPONTYPE_GRENADE, 10);
- SetCurrentWeapon(WEAPONTYPE_M16);
+ GiveDelayedWeapon(WEAPONTYPE_MP5, 1000);
+ SetCurrentWeapon(WEAPONTYPE_MP5);
m_fArmour = 100.0f;
m_wepSkills = 32; /* TODO: what is this? seems unused */
m_wepAccuracy = 84;
break;
- default:
+ case COP_MIAMIVICE:
+ switch (modifier) {
+ case 0: SetModelIndex(MI_VICE1); break;
+ case 1: SetModelIndex(MI_VICE2); break;
+ case 2: SetModelIndex(MI_VICE3); break;
+ case 3: SetModelIndex(MI_VICE4); break;
+ case 4: SetModelIndex(MI_VICE5); break;
+ case 5: SetModelIndex(MI_VICE6); break;
+ case 6: SetModelIndex(MI_VICE7); break;
+ case 7: SetModelIndex(MI_VICE8); break;
+ default: assert(0); break;
+ }
+ GiveDelayedWeapon(WEAPONTYPE_UZI, 1000);
+ SetCurrentWeapon(WEAPONTYPE_UZI);
+ m_fArmour = 100.0f;
+ m_wepSkills = 176;
+ m_wepAccuracy = 76;
break;
}
m_bIsInPursuit = false;
- field_1350 = 1;
+ field_5FE = 1;
m_bIsDisabledCop = false;
- m_fAbseilPos = 0.0f;
m_attackTimer = 0;
m_bBeatingSuspect = false;
m_bStopAndShootDisabledZone = false;
+ m_bDragsPlayerFromCar = false;
m_bZoneDisabled = false;
- field_1364 = -1;
+ field_628 = -1;
+ m_nRoadblockVeh = nil;
+ m_bThrowsSpikeTrap = false;
+ m_pRopeEntity = nil;
+ m_fAbseilPos = 0.0f;
+ m_nHassleTimer = 0;
+ field_61C = 0;
+ field_624 = 0;
+ m_pStinger = new CStinger();
SetWeaponLockOnTarget(nil);
-
- // VC also initializes in here, but as nil
-#ifdef FIX_BUGS
- m_nRoadblockNode = -1;
-#endif
}
CCopPed::~CCopPed()
{
ClearPursuit();
+ m_pStinger->Remove();
+ delete m_pStinger;
}
// Parameter should always be CPlayerPed, but it seems they considered making civilians arrestable at some point
@@ -89,17 +111,9 @@ CCopPed::SetArrestPlayer(CPed *player)
if (!IsPedInControl() || !player)
return;
- switch (m_nCopType) {
- case COP_FBI:
- Say(SOUND_PED_ARREST_FBI);
- break;
- case COP_SWAT:
- Say(SOUND_PED_ARREST_SWAT);
- break;
- default:
- Say(SOUND_PED_ARREST_COP);
- break;
- }
+ player->Say(SOUND_PED_PLAYER_REACTTOCOP);
+ Say(SOUND_PED_ARREST_COP);
+
if (player->EnteringCar()) {
if (CTimer::GetTimeInMilliseconds() > m_nPedStateTimer)
return;
@@ -134,7 +148,7 @@ CCopPed::SetArrestPlayer(CPed *player)
player->m_pMyVehicle->bIsHandbrakeOn = true;
player->m_pMyVehicle->SetStatus(STATUS_PLAYER_DISABLED);
}
- if (GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED)
+ if (GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED || GetWeapon()->m_eWeaponType == WEAPONTYPE_BRASSKNUCKLE)
SetCurrentWeapon(WEAPONTYPE_COLT45);
}
@@ -176,6 +190,7 @@ CCopPed::ClearPursuit(void)
bNotAllowedToDuck = false;
bKindaStayInSamePlace = false;
m_bStopAndShootDisabledZone = false;
+ m_bDragsPlayerFromCar = false;
m_bZoneDisabled = false;
ClearObjective();
if (IsPedInControl()) {
@@ -197,6 +212,9 @@ CCopPed::ClearPursuit(void)
void
CCopPed::SetPursuit(bool ignoreCopLimit)
{
+ if (CTimer::GetTimeInMilliseconds() < field_61C)
+ return;
+
CWanted *wanted = FindPlayerPed()->m_pWanted;
if (m_bIsInPursuit || !IsPedInControl())
return;
@@ -304,11 +322,6 @@ CCopPed::CopAI(void)
if (bHitSomethingLastFrame) {
m_bZoneDisabled = true;
m_bIsDisabledCop = true;
-#ifdef FIX_BUGS
- m_nRoadblockNode = -1;
-#else
- m_nRoadblockNode = 0;
-#endif
bKindaStayInSamePlace = true;
bIsRunning = false;
bNotAllowedToDuck = false;
@@ -335,6 +348,27 @@ CCopPed::CopAI(void)
}
if (wantedLevel > 0) {
if (!m_bIsDisabledCop) {
+ // Turn and shoot the player's vehicle, if possible
+ if (!m_bIsInPursuit && !GetWeapon()->IsTypeMelee() && FindPlayerVehicle() && m_fDistanceToTarget < CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_fRange) {
+ if (FindPlayerVehicle()->m_vecMoveSpeed.Magnitude2D() > 0.1f) {
+ CVector2D distToVeh = GetPosition() - FindPlayerVehicle()->GetPosition();
+ distToVeh.Normalise();
+ CVector2D vehSpeed = FindPlayerVehicle()->m_vecMoveSpeed;
+ vehSpeed.Normalise();
+
+ if (DotProduct2D(distToVeh, vehSpeed) > 0.8f) {
+ SetLookFlag(playerOrHisVeh, true);
+ SetMoveState(PEDMOVE_STILL);
+ if (TurnBody()) {
+ SetAttack(FindPlayerVehicle());
+ SetShootTimer(CGeneral::GetRandomNumberInRange(500.0f, 1000.0f));
+ SetAttackTimer(CGeneral::GetRandomNumberInRange(200.0f, 300.0f));
+ }
+ } else if (m_nPedState == PED_ATTACK)
+ RestorePreviousState();
+ }
+ }
+
if (!m_bIsInPursuit || wanted->m_CurrentCops > wanted->m_MaxCops) {
CCopPed *copFarthestToTarget = nil;
float copFarthestToTargetDist = m_fDistanceToTarget;
@@ -377,11 +411,14 @@ CCopPed::CopAI(void)
if (wantedLevel > 1 && GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED)
SetCurrentWeapon(WEAPONTYPE_COLT45);
- else if (wantedLevel == 1 && GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED && !FindPlayerPed()->m_pCurrentPhysSurface) {
+ else if (wantedLevel == 1 && GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED && !FindPlayerPed()->m_pCurrentPhysSurface) {
// i.e. if player is on top of car, cop will still use colt45.
- SetCurrentWeapon(WEAPONTYPE_UNARMED);
+ SetCurrentWeapon(GetWeaponSlot(WEAPONTYPE_NIGHTSTICK) >= 0 ? WEAPONTYPE_NIGHTSTICK : WEAPONTYPE_UNARMED);
}
+ if (m_bBeatingSuspect && GetWeapon()->m_eWeaponType == WEAPONTYPE_NIGHTSTICK)
+ Say(SOUND_PED_PULLOUTWEAPON);
+
if (FindPlayerVehicle()) {
if (m_bBeatingSuspect) {
--wanted->m_CopsBeatingSuspect;
@@ -392,18 +429,18 @@ CCopPed::CopAI(void)
}
return;
}
- float weaponRange = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_fRange;
+ SetCurrentWeapon(WEAPONTYPE_COLT45);
+ CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
+ float weaponRange = weaponInfo->m_fRange;
SetLookFlag(playerOrHisVeh, true);
TurnBody();
- SetCurrentWeapon(WEAPONTYPE_COLT45);
- if (!bIsDucking) {
+ if (!bIsDucking || bCrouchWhenShooting && GetCrouchFireAnim(weaponInfo)) {
if (m_attackTimer >= CTimer::GetTimeInMilliseconds()) {
if (m_nPedState != PED_ATTACK && m_nPedState != PED_FIGHT && !m_bZoneDisabled) {
CVector targetDist = playerOrHisVeh->GetPosition() - GetPosition();
if (m_fDistanceToTarget > 30.0f) {
- CAnimBlendAssociation* crouchShootAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_RBLOCK_SHOOT);
- if (crouchShootAssoc)
- crouchShootAssoc->blendDelta = -1000.0f;
+ if (bIsDucking)
+ ClearDuck();
// Target is coming onto us
if (DotProduct(playerOrHisVeh->m_vecMoveSpeed, targetDist) > 0.0f) {
@@ -421,49 +458,28 @@ CCopPed::CopAI(void)
bNotAllowedToDuck = false;
bDuckAndCover = false;
} else {
- // VC checks for != nil compared to buggy behaviour of III. I check for != -1 here.
-#ifdef VC_PED_PORTS
float dotProd;
- if (m_nRoadblockNode != -1) {
- CTreadable *roadBlockRoad = ThePaths.m_mapObjects[CRoadBlocks::RoadBlockObjects[m_nRoadblockNode]];
- dotProd = DotProduct2D(playerOrHisVeh->GetPosition() - roadBlockRoad->GetPosition(), GetPosition() - roadBlockRoad->GetPosition());
+ if (m_nRoadblockVeh) {
+ dotProd = DotProduct2D(playerOrHisVeh->GetPosition() - m_nRoadblockVeh->GetPosition(), GetPosition() - m_nRoadblockVeh->GetPosition());
} else
dotProd = -1.0f;
- if(dotProd >= 0.0f) {
-#else
-
-#ifndef FIX_BUGS
- float copRoadDotProd, targetRoadDotProd;
-#else
- float copRoadDotProd = 1.0f, targetRoadDotProd = 1.0f;
- if (m_nRoadblockNode != -1)
-#endif
- {
- CTreadable* roadBlockRoad = ThePaths.m_mapObjects[CRoadBlocks::RoadBlockObjects[m_nRoadblockNode]];
- CVector2D roadFwd = roadBlockRoad->GetForward();
- copRoadDotProd = DotProduct2D(GetPosition() - roadBlockRoad->GetPosition(), roadFwd);
- targetRoadDotProd = DotProduct2D(playerOrHisVeh->GetPosition() - roadBlockRoad->GetPosition(), roadFwd);
- }
- // Roadblock may be towards road's fwd or opposite, so check both
- if ((copRoadDotProd >= 0.0f || targetRoadDotProd >= 0.0f)
- && (copRoadDotProd <= 0.0f || targetRoadDotProd <= 0.0f)) {
-#endif
- bIsPointingGunAt = true;
- } else {
+ if(dotProd < 0.0f) {
+ if (bIsDucking)
+ ClearDuck();
m_bIsDisabledCop = false;
bKindaStayInSamePlace = false;
bNotAllowedToDuck = false;
bCrouchWhenShooting = false;
- bIsDucking = false;
bDuckAndCover = false;
SetPursuit(false);
+ } else {
+ bIsPointingGunAt = true;
}
}
}
} else {
if (m_fDistanceToTarget < weaponRange) {
- CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
CVector gunPos = weaponInfo->m_vecFireOffset;
TransformToNode(gunPos, PED_HANDR);
@@ -472,6 +488,7 @@ CCopPed::CopAI(void)
if (!CWorld::ProcessLineOfSight(gunPos, playerOrHisVeh->GetPosition(), foundCol, foundEnt,
false, true, false, false, true, false, false)
|| foundEnt && foundEnt == playerOrHisVeh) {
+
SetWeaponLockOnTarget(playerOrHisVeh);
SetAttack(playerOrHisVeh);
SetShootTimer(CGeneral::GetRandomNumberInRange(500, 1000));
@@ -506,10 +523,8 @@ CCopPed::CopAI(void)
ClearObjective();
SetWanderPath(CGeneral::GetRandomNumber() & 7);
}
- }
-#ifdef VC_PED_PORTS
- else {
- if (m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT && CharCreatedBy == RANDOM_CHAR) {
+ } else {
+ if (m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT && m_objective != OBJECTIVE_HASSLE_CHAR && CharCreatedBy == RANDOM_CHAR) {
for (int i = 0; i < m_numNearPeds; i++) {
CPed *nearPed = m_nearPeds[i];
if (nearPed->CharCreatedBy == RANDOM_CHAR) {
@@ -529,12 +544,30 @@ CCopPed::CopAI(void)
nearPed->bBeingChasedByPolice = true;
return;
}
+ } else {
+ if (nearPed->m_nPedType != PEDTYPE_COP && !nearPed->IsPlayer()
+ && nearPed->IsPedInControl() && m_nHassleTimer < CTimer::GetTimeInMilliseconds()) {
+
+ if (nearPed->m_objective == OBJECTIVE_NONE && nearPed->m_nPedState == PED_WANDER_PATH
+ && !nearPed->m_pLookTarget && nearPed->m_lookTimer < CTimer::GetTimeInMilliseconds()) {
+
+ if ((GetPosition() - nearPed->GetPosition()).MagnitudeSqr() < sq(5.0f)) {
+
+ if (CWorld::GetIsLineOfSightClear(GetPosition(), nearPed->GetPosition(),
+ true, false, false, false, false, false, false)) {
+ Say(SOUND_PED_COP_ASK_FOR_ID);
+ SetObjective(OBJECTIVE_HASSLE_CHAR, nearPed);
+ nearPed->SetObjective(OBJECTIVE_WAIT_ON_FOOT_FOR_COP, this);
+ m_nHassleTimer = CTimer::GetTimeInMilliseconds() + 100000;
+ }
+ }
+ }
+ }
}
}
}
}
}
-#endif
}
}
} else {
@@ -545,8 +578,9 @@ CCopPed::CopAI(void)
bKindaStayInSamePlace = false;
bNotAllowedToDuck = false;
bCrouchWhenShooting = false;
- bIsDucking = false;
bDuckAndCover = false;
+ if (bIsDucking)
+ ClearDuck();
if (m_pMyVehicle)
SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, m_pMyVehicle);
}
@@ -556,10 +590,20 @@ CCopPed::CopAI(void)
void
CCopPed::ProcessControl(void)
{
- if (m_nZoneLevel > LEVEL_GENERIC && m_nZoneLevel != CCollision::ms_collisionInMemory)
- return;
+ if (m_nCopType == COP_HELI_SWAT)
+ ProcessHeliSwat();
CPed::ProcessControl();
+
+ if (m_bThrowsSpikeTrap) {
+ if (CGame::currArea != AREA_MALL)
+ ProcessStingerCop();
+ return;
+ }
+
+ if (m_pStinger && m_pStinger->bIsDeployed && m_pStinger->m_nSpikeState == STINGERSTATE_DEPLOYED && CGame::currArea != AREA_MALL)
+ m_pStinger->Process();
+
if (bWasPostponed)
return;
@@ -575,7 +619,7 @@ CCopPed::ProcessControl(void)
ArrestPlayer();
return;
}
- GetWeapon()->Update(m_audioEntityId);
+ GetWeapon()->Update(m_audioEntityId, nil);
if (m_moved.Magnitude() > 0.0f)
Avoid();
@@ -591,21 +635,33 @@ CCopPed::ProcessControl(void)
if (IsPedInControl())
SetIdle();
}
+
if (m_bIsInPursuit) {
if (player->m_nPedState != PED_ARRESTED && !player->DyingOrDead()) {
- switch (m_nCopType) {
- case COP_FBI:
- Say(SOUND_PED_PURSUIT_FBI);
- break;
- case COP_SWAT:
- Say(SOUND_PED_PURSUIT_SWAT);
- break;
- case COP_ARMY:
- Say(SOUND_PED_PURSUIT_ARMY);
- break;
- default:
- Say(SOUND_PED_PURSUIT_COP);
- break;
+ if (player->m_pWanted->m_CurrentCops == 1) {
+ Say(SOUND_PED_COP_ALONE);
+ } else {
+ int numCopsNear = 0;
+ for (int i = 0; i < player->m_numNearPeds; ++i) {
+ CPed *nearPed = player->m_nearPeds[i];
+ if (nearPed->m_nPedType == PEDTYPE_COP && nearPed->m_nPedState != PED_DEAD)
+ ++numCopsNear;
+ }
+ if (numCopsNear <= 3) {
+ Say(SOUND_PED_COP_LITTLECOPSAROUND);
+ if (!player->bInVehicle) {
+ CVector distToPlayer = player->GetPosition() - GetPosition();
+ if (distToPlayer.MagnitudeSqr() < sq(20.0f)) {
+ player->Say(SOUND_PED_PLAYER_FARFROMCOPS);
+ if (player->m_nPedState != PED_ATTACK && player->m_nPedState != PED_AIM_GUN) {
+ player->SetLookFlag(this, false);
+ player->SetLookTimer(1000);
+ }
+ }
+ }
+ } else if ((CGeneral::GetRandomNumber() % 16) == 1) {
+ Say(SOUND_PED_COP_MANYCOPSAROUND);
+ }
}
}
}
@@ -655,23 +711,10 @@ CCopPed::ProcessControl(void)
RestorePreviousObjective();
} else {
if (player->m_pMyVehicle && player->m_pMyVehicle->m_nNumGettingIn != 0) {
- // This is 1.3f when arresting in car without seeking first (in above)
-#if defined(VC_PED_PORTS) || defined(FIX_BUGS)
m_distanceToCountSeekDone = 1.3f;
-#else
- m_distanceToCountSeekDone = 2.0f;
-#endif
}
- if (bDuckAndCover) {
-#if GTA_VERSION < GTA3_PC_11 && !defined(VC_PED_PORTS)
- if (!bNotAllowedToDuck && Seek()) {
- SetMoveState(PEDMOVE_STILL);
- SetMoveAnim();
- SetPointGunAt(m_pedInObjective);
- }
-#endif
- } else if (Seek()) {
+ if (!bDuckAndCover && Seek()) {
CVehicle *playerVeh = FindPlayerVehicle();
if (!playerVeh && player && player->EnteringCar()) {
SetArrestPlayer(player);
@@ -702,35 +745,130 @@ CCopPed::ProcessControl(void)
}
}
}
- if (!m_bStopAndShootDisabledZone)
- return;
- bool dontShoot = false;
- if (GetIsOnScreen() && CRenderer::IsEntityCullZoneVisible(this)) {
- if (((CTimer::GetFrameCounter() + m_randomSeed) & 0x1F) == 17) {
- CEntity *foundBuilding = nil;
- CColPoint foundCol;
- CVector lookPos = GetPosition() + CVector(0.0f, 0.0f, 0.7f);
- CVector camPos = TheCamera.GetGameCamPosition();
- CWorld::ProcessLineOfSight(camPos, lookPos, foundCol, foundBuilding,
- true, false, false, false, false, false, false);
-
- // He's at least 15.0 far, in disabled zone, collided into somewhere (that's why m_bStopAndShootDisabledZone set),
- // and now has building on front of him. He's stupid, we don't need him.
- if (foundBuilding) {
- FlagToDestroyWhenNextProcessed();
- dontShoot = true;
+ if (m_pPointGunAt)
+ Say(SOUND_PED_COP_TARGETING);
+
+ if (m_bStopAndShootDisabledZone) {
+ bool dontShoot = false;
+ if (GetIsOnScreen()) {
+ if (((CTimer::GetFrameCounter() + m_randomSeed) & 0x1F) == 17) {
+ CEntity* foundBuilding = nil;
+ CColPoint foundCol;
+ CVector lookPos = GetPosition() + CVector(0.0f, 0.0f, 0.7f);
+ CVector camPos = TheCamera.GetGameCamPosition();
+ CWorld::ProcessLineOfSight(camPos, lookPos, foundCol, foundBuilding,
+ true, false, false, false, false, false, false);
+
+ // He's at least 15.0 far, in disabled zone, collided into somewhere (that's why m_bStopAndShootDisabledZone set),
+ // and now has building on front of him. He's stupid, we don't need him.
+ if (foundBuilding) {
+ FlagToDestroyWhenNextProcessed();
+ dontShoot = true;
+ }
+ }
+ } else {
+ FlagToDestroyWhenNextProcessed();
+ dontShoot = true;
+ }
+
+ if (!dontShoot) {
+ bStopAndShoot = true;
+ bKindaStayInSamePlace = true;
+ bIsPointingGunAt = true;
+ SetAttack(m_pedInObjective);
+ }
+ }
+
+ if (field_624 >= 2 && m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT) {
+ CVector centre = GetPosition() + CVector(0.f, 0.f, 0.65f);
+ if (CWorld::TestSphereAgainstWorld(centre, 0.35f, this, true, false, false, false, false, false)) {
+ field_624 = 0;
+ m_bStopAndShootDisabledZone = true;
+ ClearPursuit();
+ SetObjective(OBJECTIVE_NONE);
+ SetWanderPath(CGeneral::GetRandomNumberInRange(0,8));
+ field_61C = CTimer::GetTimeInMilliseconds() + 30000;
+ } else {
+ field_624 = 0;
+ if (GetWeapon()->IsTypeMelee()) {
+ // TODO(Miami): enum
+ for (int i = 3; i < 7; i++) {
+ if (HasWeaponSlot(i)) {
+ SetCurrentWeapon(i);
+ break;
+ }
+ }
+ SetMoveState(PEDMOVE_STILL);
+ bStopAndShoot = true;
}
}
+ } else if (CTimer::GetTimeStep() / 100.f <= m_fDistanceTravelled)
+ field_624 = 0;
+}
+
+void
+CCopPed::ProcessHeliSwat(void)
+{
+ CVector bestPos = GetPosition();
+ SetPedState(PED_ABSEIL);
+ CPedPlacement::FindZCoorForPed(&bestPos);
+ if (GetPosition().z - 2.0f >= bestPos.z && m_pRopeEntity) {
+ m_fAbseilPos += 0.003f * CTimer::GetTimeStep();
+ m_vecMoveSpeed.z = -0.03f;
+ m_vecTurnSpeed = CVector(0.f, 0.f, (m_randomSeed % 32) * 0.003f - 0.05f);
+ CPhysical::ApplyTurnSpeed();
+ GetMatrix().Reorthogonalise();
+ CVector posOnRope;
+
+ if (CRopes::FindCoorsAlongRope(m_nRopeID, m_fAbseilPos, &posOnRope)) {
+ SetPosition(posOnRope);
+ } else {
+ bUsesCollision = true;
+ m_vecMoveSpeed = CVector(0.f, 0.f, 0.f);
+ SetPedState(PED_IDLE);
+ m_nCopType = COP_SWAT;
+ SetInTheAir();
+ bKnockedUpIntoAir = true;
+ }
+ Say(SOUND_PED_COP_HELIPILOTPHRASE);
} else {
- FlagToDestroyWhenNextProcessed();
- dontShoot = true;
+ bUsesCollision = true;
+ m_vecMoveSpeed = CVector(0.f, 0.f, 0.f);
+ SetPedState(PED_IDLE);
+ m_nCopType = COP_SWAT;
+ SetInTheAir();
+ bKnockedUpIntoAir = true;
}
+}
- if (!dontShoot) {
- bStopAndShoot = true;
- bKindaStayInSamePlace = true;
- bIsPointingGunAt = true;
- SetAttack(m_pedInObjective);
+void
+CCopPed::ProcessStingerCop(void)
+{
+ if (m_pStinger->bIsDeployed || FindPlayerVehicle() && (FindPlayerVehicle()->IsCar() || FindPlayerVehicle()->IsBike())) {
+ if (m_pStinger->bIsDeployed) {
+ m_pStinger->Process();
+ } else {
+ CVector2D vehDist = GetPosition() - FindPlayerVehicle()->GetPosition();
+ CVector2D dirVehGoing = FindPlayerVehicle()->m_vecMoveSpeed;
+ if (vehDist.MagnitudeSqr() < sq(30.0f)) {
+ if (dirVehGoing.MagnitudeSqr() > 0.0f) {
+ vehDist.Normalise();
+ dirVehGoing.Normalise();
+ if (DotProduct2D(vehDist, dirVehGoing) > 0.8f) {
+ float angle = (CrossProduct2D(vehDist, dirVehGoing - vehDist) < 0.0f ?
+ FindPlayerVehicle()->GetForward().Heading() - HALFPI :
+ HALFPI + FindPlayerVehicle()->GetForward().Heading());
+
+ SetHeading(angle);
+ m_fRotationCur = angle;
+ m_fRotationDest = angle;
+ m_pStinger->Deploy(this);
+ }
+ }
+ }
+ }
+ } else {
+ ClearPursuit();
}
}
diff --git a/src/peds/CopPed.h b/src/peds/CopPed.h
index 5346d9a1..3f5ae06d 100644
--- a/src/peds/CopPed.h
+++ b/src/peds/CopPed.h
@@ -6,25 +6,35 @@ enum eCopType
COP_STREET = 0,
COP_FBI = 1,
COP_SWAT = 2,
- COP_ARMY = 3,
+ COP_HELI_SWAT = 3,
+ COP_ARMY = 4,
+ COP_MIAMIVICE = 5
};
class CCopPed : public CPed
{
public:
- int16 m_nRoadblockNode;
+ CVehicle* m_nRoadblockVeh;
float m_fDistanceToTarget;
bool m_bIsInPursuit;
bool m_bIsDisabledCop;
- int8 field_1350;
+ int8 field_5FE;
bool m_bBeatingSuspect;
bool m_bStopAndShootDisabledZone;
+ bool m_bDragsPlayerFromCar;
bool m_bZoneDisabled;
- float m_fAbseilPos; // VC leftover, unused
+ float m_fAbseilPos;
eCopType m_nCopType;
- int8 field_1364;
+ bool m_bThrowsSpikeTrap;
+ CEntity *m_pRopeEntity; // CHeli or 1
+ uintptr m_nRopeID;
+ uint32 m_nHassleTimer;
+ uint32 field_61C;
+ class CStinger *m_pStinger;
+ int32 field_624;
+ int8 field_628;
- CCopPed(eCopType);
+ CCopPed(eCopType, int32 modifier = 0);
~CCopPed();
void ClearPursuit(void);
@@ -34,8 +44,8 @@ public:
void ArrestPlayer(void);
void ScanForCrimes(void);
void CopAI(void);
+ void ProcessHeliSwat(void);
+ void ProcessStingerCop(void);
};
-#ifndef PED_SKIN
-VALIDATE_SIZE(CCopPed, 0x558);
-#endif
+VALIDATE_SIZE(CCopPed, 0x62C);
diff --git a/src/peds/DummyPed.h b/src/peds/DummyPed.h
index ea617c76..cace4ead 100644
--- a/src/peds/DummyPed.h
+++ b/src/peds/DummyPed.h
@@ -8,5 +8,3 @@ class CDummyPed : CDummy
int32 pedType;
int32 unknown;
};
-
-VALIDATE_SIZE(CDummyPed, 0x70);
diff --git a/src/peds/EmergencyPed.cpp b/src/peds/EmergencyPed.cpp
index d8c8309e..954c1c79 100644
--- a/src/peds/EmergencyPed.cpp
+++ b/src/peds/EmergencyPed.cpp
@@ -44,15 +44,12 @@ CEmergencyPed::InRange(CPed *victim)
void
CEmergencyPed::ProcessControl(void)
{
- if (m_nZoneLevel > LEVEL_GENERIC && m_nZoneLevel != CCollision::ms_collisionInMemory)
- return;
-
CPed::ProcessControl();
if (bWasPostponed)
return;
if(!DyingOrDead()) {
- GetWeapon()->Update(m_audioEntityId);
+ GetWeapon()->Update(m_audioEntityId, nil);
if (IsPedInControl() && m_moved.Magnitude() > 0.0f)
Avoid();
@@ -107,7 +104,6 @@ CEmergencyPed::FiremanAI(void)
m_pAttendedFire = nearestFire;
#ifdef FIX_BUGS
bIsRunning = true;
- ++nearestFire->m_nFiremenPuttingOut;
#endif
}
break;
@@ -119,10 +115,6 @@ CEmergencyPed::FiremanAI(void)
SetMoveState(PEDMOVE_RUN);
#ifdef FIX_BUGS
bIsRunning = true;
- if (m_pAttendedFire) {
- --m_pAttendedFire->m_nFiremenPuttingOut;
- }
- ++nearestFire->m_nFiremenPuttingOut;
m_pAttendedFire = nearestFire;
} else if (!nearestFire) {
#else
@@ -156,10 +148,7 @@ CEmergencyPed::FiremanAI(void)
case EMERGENCY_PED_STOP:
#ifdef FIX_BUGS
bIsRunning = false;
- if (m_pAttendedFire)
#endif
- --m_pAttendedFire->m_nFiremenPuttingOut;
-
SetPedState(PED_NONE);
SetWanderPath(CGeneral::GetRandomNumber() & 7);
m_pAttendedFire = nil;
@@ -175,15 +164,20 @@ CEmergencyPed::MedicAI(void)
{
float distToEmergency;
if (!bInVehicle && IsPedInControl()) {
- ScanForThreats();
- if (m_threatEntity && m_threatEntity->IsPed() && ((CPed*)m_threatEntity)->IsPlayer()) {
- if (((CPed*)m_threatEntity)->GetWeapon()->IsTypeMelee()) {
- SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, m_threatEntity);
- } else {
- SetFlee(m_threatEntity, 6000);
- Say(SOUND_PED_FLEE_SPRINT);
+ ScanForDelayedResponseThreats();
+ if (m_threatFlags && CTimer::GetTimeInMilliseconds() > m_threatCheckTimer) {
+ CheckThreatValidity();
+ m_threatFlags = 0;
+ m_threatCheckTimer = 0;
+ if (m_threatEntity && m_threatEntity->IsPed() && ((CPed*)m_threatEntity)->IsPlayer()) {
+ if (((CPed*)m_threatEntity)->GetWeapon()->IsTypeMelee()) {
+ SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, m_threatEntity);
+ } else {
+ SetFlee(m_threatEntity, 6000);
+ Say(SOUND_PED_FLEE_SPRINT);
+ }
+ return;
}
- return;
}
}
@@ -236,8 +230,7 @@ CEmergencyPed::MedicAI(void)
m_pRevivedPed->RegisterReference((CEntity**)&m_pRevivedPed);
m_pRevivedPed->m_pedIK.GetComponentPosition(midPos, PED_MID);
m_pRevivedPed->m_pedIK.GetComponentPosition(headPos, PED_HEAD);
- SetSeek((headPos + midPos) * 0.5f, 1.0f);
- SetObjective(OBJECTIVE_NONE);
+ SetObjective(OBJECTIVE_GOTO_AREA_ON_FOOT, CVector((headPos + midPos) * 0.5f));
bIsRunning = true;
m_nEmergencyPedState = EMERGENCY_PED_DETERMINE_NEXT_STATE;
m_pAttendedAccident = nearestAccident;
@@ -250,6 +243,7 @@ CEmergencyPed::MedicAI(void)
CPed* driver = m_pMyVehicle->pDriver;
if (driver && driver->m_nPedType != PEDTYPE_EMERGENCY && m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT) {
SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, driver);
+
} else if (m_objective != OBJECTIVE_ENTER_CAR_AS_DRIVER
&& m_objective != OBJECTIVE_ENTER_CAR_AS_PASSENGER
&& m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT) {
@@ -276,8 +270,7 @@ CEmergencyPed::MedicAI(void)
}
m_pRevivedPed->m_pedIK.GetComponentPosition(midPos, PED_MID);
m_pRevivedPed->m_pedIK.GetComponentPosition(headPos, PED_HEAD);
- SetSeek((headPos + midPos) * 0.5f, nearestAccident->m_nMedicsPerformingCPR * 0.5f + 1.0f);
- SetObjective(OBJECTIVE_NONE);
+ SetObjective(OBJECTIVE_GOTO_AREA_ON_FOOT, CVector((headPos + midPos) * 0.5f));
bIsRunning = true;
--m_pAttendedAccident->m_nMedicsAttending;
++nearestAccident->m_nMedicsAttending;
@@ -317,7 +310,7 @@ CEmergencyPed::MedicAI(void)
m_nEmergencyPedState = EMERGENCY_PED_STAND_STILL;
} else {
m_nEmergencyPedState = EMERGENCY_PED_FACE_TO_PATIENT;
- m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_MEDIC_CPR, 4.0f);
+ m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_MEDIC, ANIM_MEDIC_CPR, 4.0f);
bIsDucking = true;
}
SetLookTimer(2000);
@@ -380,6 +373,8 @@ CEmergencyPed::MedicAI(void)
m_pRevivedPed->bIsPedDieAnimPlaying = false;
m_pRevivedPed->bKnockedUpIntoAir = false;
m_pRevivedPed->m_pCollidingEntity = nil;
+ m_pRevivedPed->bKnockedOffBike = false;
+ m_pRevivedPed->Say(SOUND_PED_ACCIDENTREACTION1);
}
break;
case EMERGENCY_PED_STOP_CPR:
diff --git a/src/peds/EmergencyPed.h b/src/peds/EmergencyPed.h
index 390ba0bd..41bc86e5 100644
--- a/src/peds/EmergencyPed.h
+++ b/src/peds/EmergencyPed.h
@@ -36,6 +36,4 @@ public:
void FiremanAI(void);
void MedicAI(void);
};
-#ifndef PED_SKIN
-VALIDATE_SIZE(CEmergencyPed, 0x554);
-#endif
+//VALIDATE_SIZE(CEmergencyPed, 0x554);
diff --git a/src/peds/Gangs.cpp b/src/peds/Gangs.cpp
index be29379c..240f6b37 100644
--- a/src/peds/Gangs.cpp
+++ b/src/peds/Gangs.cpp
@@ -2,13 +2,18 @@
#include "ModelIndices.h"
#include "Gangs.h"
+#include "General.h"
+#include "Streaming.h"
#include "Weapon.h"
#include "SaveBuf.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)
@@ -16,21 +21,63 @@ CGangInfo::CGangInfo() :
void CGangs::Initialise(void)
{
- Gang[GANG_MAFIA].m_nVehicleMI = MI_MAFIA;
- Gang[GANG_TRIAD].m_nVehicleMI = MI_BELLYUP;
- Gang[GANG_DIABLOS].m_nVehicleMI = MI_DIABLOS;
- Gang[GANG_YAKUZA].m_nVehicleMI = MI_YAKUZA;
- Gang[GANG_YARDIE].m_nVehicleMI = MI_YARDIE;
- Gang[GANG_COLUMB].m_nVehicleMI = MI_COLUMB;
- Gang[GANG_HOODS].m_nVehicleMI = MI_HOODS;
- 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 96c1d094..6cbe7484 100644
--- a/src/peds/Ped.cpp
+++ b/src/peds/Ped.cpp
@@ -30,7 +30,14 @@
#include "Timecycle.h"
#include "ParticleObject.h"
#include "Floater.h"
-#include "Range2D.h"
+#include "Range2D.h"
+#include "Streaming.h"
+#include "PedAttractor.h"
+#include "GameLogic.h"
+#include "Bike.h"
+#include "WindModifiers.h"
+#include "CutsceneShadow.h"
+#include "Clock.h"
#include "Wanted.h"
#include "SaveBuf.h"
@@ -39,12 +46,11 @@ uint16 gnNumTempPedList;
static CColPoint aTempPedColPts[MAX_COLLISION_POINTS];
-
uint16 CPed::nThreatReactionRangeMultiplier = 1;
uint16 CPed::nEnterCarRangeMultiplier = 1;
bool CPed::bNastyLimbsCheat;
-bool CPed::bPedCheat2;
+bool CPed::bFannyMagnetCheat;
bool CPed::bPedCheat3;
CVector2D CPed::ms_vec2DFleePosition;
@@ -53,16 +59,13 @@ void *CPed::operator new(size_t sz, int handle) throw() { return CPools::GetPedP
void CPed::operator delete(void *p, size_t sz) throw() { CPools::GetPedPool()->Delete((CPed*)p); }
void CPed::operator delete(void *p, int handle) throw() { CPools::GetPedPool()->Delete((CPed*)p); }
-#ifdef DEBUGMENU
-bool CPed::bPopHeadsOnHeadshot = false;
-#endif
+float gfTommyFatness = 1.0f;
CPed::CPed(uint32 pedType) : m_pedIK(this)
{
- m_type = ENTITY_TYPE_PED;
- bPedPhysics = true;
- bUseCollisionRecords = true;
-
+#ifdef USE_CUTSCENE_SHADOW_FOR_PED
+ m_pRTShadow = nil;
+#endif
m_vecAnimMoveDelta.x = 0.0f;
m_vecAnimMoveDelta.y = 0.0f;
m_fHealth = 100.0f;
@@ -72,6 +75,12 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
m_soundStart = 0;
m_lastQueuedSound = SOUND_NO_SOUND;
m_queuedSound = SOUND_NO_SOUND;
+ m_canTalk = true;
+
+ m_type = ENTITY_TYPE_PED;
+ bPedPhysics = true;
+ bUseCollisionRecords = true;
+
m_objective = OBJECTIVE_NONE;
m_prevObjective = OBJECTIVE_NONE;
#ifdef FIX_BUGS
@@ -80,13 +89,17 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
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;
@@ -115,15 +128,19 @@ 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;
+ m_followPathDestPos = CVector(0.f, 0.f, 0.f);
+ m_followPathAbortDist = 0.0f;
+ m_followPathMoveState = PEDMOVE_NONE;
bRunningToPhone = false;
m_phoneId = -1;
m_lastAccident = 0;
m_fleeFrom = nil;
- m_fleeFromPosX = 0;
- m_fleeFromPosY = 0;
+ m_fleeFromPos = CVector2D(0.0f, 0.0f);
m_fleeTimer = 0;
- m_vecSeekPosEx = CVector(0.0f, 0.0f, 0.0f);
- m_distanceToCountSeekDoneEx = 0.0f;
+ m_threatEx = nil;
+ m_vecSpotToGuard = CVector(0.0f, 0.0f, 0.0f);
+ m_radiusToGuard = 0.0f;
m_nWaitState = WAITSTATE_FALSE;
m_nWaitTimer = 0;
m_pCollidingEntity = nil;
@@ -140,22 +157,37 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
m_fLookDirection = 0.0f;
m_pCurSurface = nil;
m_wanderRangeBounds = nil;
- m_nPathNodes = 0;
- m_nCurPathNode = 0;
+
+ for (int i = 0; i < ARRAY_SIZE(m_pathNodesToGo); i++) {
+ m_pathNodesToGo[i] = nil;
+ }
+ m_nNumPathNodes = 0;
+ m_nCurPathNodeId = 0;
m_nPathDir = 0;
m_pLastPathNode = nil;
m_pNextPathNode = nil;
+ m_followPathWalkAroundEnt = nil;
+ m_followPathTargetEnt = nil;
+ m_pathNodeTimer = 0;
+ m_pCurPathNode = nil;
+
+ m_threatFlags = 0;
+ m_threatCheckTimer = 0;
+ m_threatCheckInterval = CGeneral::GetRandomNumberInRange(250, 1000);
+
m_routeLastPoint = -1;
m_routeStartPoint = 0;
m_routePointsPassed = 0;
m_routeType = 0;
- m_bodyPartBleeding = -1;
m_fMass = 70.0f;
m_fTurnMass = 100.0f;
m_fAirResistance = 0.4f / m_fMass;
m_fElasticity = 0.05f;
+ m_ceaseAttackTimer = 0;
+ m_bodyPartBleeding = -1;
+
bIsStanding = false;
bWasStanding = false;
bIsAttacking = false;
@@ -203,7 +235,6 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
bWanderPathAfterExitingCar = false;
bIsLeader = false;
bDontDragMeOutCar = false;
- m_ped_flagF8 = false;
bWillBeQuickJacked = false;
bCancelEnteringCar = false;
bObstacleShowedUpDuringKillObjective = false;
@@ -232,18 +263,60 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
bVehExitWillBeInstant = false;
bHasAlreadyBeenRecorded = false;
bFallenDown = false;
+ bDontAcceptIKLookAts = false;
+ bReachedAttractorHeadingTarget = false;
+ bTurnedAroundOnAttractor = false;
#ifdef KANGAROO_CHEAT
m_ped_flagI80 = false;
#endif
-#ifdef VC_PED_PORTS
- bSomeVCflag1 = false;
-#endif
+
+ bHasAlreadyUsedAttractor = false;
+ bHasAlreadyStoleACar = false;
+ bCarPassenger = false;
+ bFleeWhenStanding = false;
+ bGotUpOfMyOwnAccord = false;
+ bMiamiViceCop = false;
+ bMoneyHasBeenGivenByScript = false;
+ bHasBeenPhotographed = false;
+
+ bIsDrowning = false;
+ bDrownsInWater = true;
+ bWaitForLeaderToComeCloser = false;
+ bHeldHostageInCar = false;
+ bIsPlayerFriend = true;
+ bHeadStuckInCollision = false;
+ bDeadPedInFrontOfCar = false;
+
+ m_gangFlags = ~0;
+
+ bStayInCarOnJack = false;
+
+ bDontFight = false;
+ bDoomAim = true;
+ bCanBeShotInVehicle = true;
+ bPushedAlongByCar = false;
+ bRemoveMeWhenIGotIntoCar = false;
+ bIgnoreThreatsBehindObjects = false;
+
+ bNeverEverTargetThisPed = false;
+ bCrouchWhenScared = false;
+ bKnockedOffBike = false;
+ b158_8 = false;
+ bCollectBusFare = false;
+ bBoughtIceCream = false;
+ bDonePositionOutOfCollision = false;
+ bCanAttackPlayerWithCops = false;
if (CGeneral::GetRandomNumber() & 3)
bHasACamera = false;
else
bHasACamera = true;
+ if (CGeneral::GetRandomNumberInRange(0.0f, 1.0f) <= 0.95f)
+ bCanGiveUpSunbathing = false;
+ else
+ bCanGiveUpSunbathing = true;
+
m_audioEntityId = DMAudio.CreateEntity(AUDIOTYPE_PHYSICAL, this);
DMAudio.SetEntityStatus(m_audioEntityId, TRUE);
m_fearFlags = CPedType::GetThreats(m_nPedType);
@@ -255,15 +328,13 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
for (int i = 0; i < ARRAY_SIZE(m_nearPeds); i++) {
m_nearPeds[i] = nil;
- if (i < ARRAY_SIZE(m_pPathNodesStates)) {
- m_pPathNodesStates[i] = nil;
- }
}
m_maxWeaponTypeAllowed = WEAPONTYPE_UNARMED;
m_currentWeapon = WEAPONTYPE_UNARMED;
m_storedWeapon = WEAPONTYPE_UNIDENTIFIED;
+ m_delayedWeapon = WEAPONTYPE_UNIDENTIFIED;
- for(int i = 0; i < WEAPONTYPE_TOTAL_INVENTORY_WEAPONS; i++) {
+ for(int i = 0; i < TOTAL_WEAPON_SLOTS; i++) {
CWeapon &weapon = GetWeapon(i);
weapon.m_eWeaponType = WEAPONTYPE_UNARMED;
weapon.m_eWeaponState = WEAPONSTATE_READY;
@@ -272,29 +343,47 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
weapon.m_nTimer = 0;
}
- m_curFightMove = FIGHTMOVE_NULL;
- GiveWeapon(WEAPONTYPE_UNARMED, 0);
+ m_curFightMove = m_lastFightMove = FIGHTMOVE_IDLE;
+ 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;
-#ifdef PED_SKIN
+ uint16 random = CGeneral::GetRandomNumber();
+ m_nPedMoney = random % 25;
+ if (m_nPedMoney == 23)
+ m_nPedMoney = 400;
+ m_bleedCounter = 0;
+ m_nExtendedRangeTimer = 0;
+ m_vehicleInAccident = nil;
+ m_attractor = nil;
+ m_positionInQueue = -1;
m_pWeaponModel = nil;
-#endif
+ m_delayedSoundID = -1;
+ m_delayedSoundTimer = 0;
CPopulation::UpdatePedCount((ePedType)m_nPedType, false);
+ m_lastComment = UINT32_MAX;
}
CPed::~CPed(void)
{
+#ifdef USE_CUTSCENE_SHADOW_FOR_PED
+ if ( m_pRTShadow ) delete m_pRTShadow;
+#endif
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_vehDoor);
if (m_pMyVehicle->pDriver == this)
m_pMyVehicle->pDriver = nil;
else {
- // FIX: Passenger counter now decreasing after removing ourself from vehicle.
+ // FIX: Passenger counter now being decreased after removing ourself from vehicle.
m_pMyVehicle->RemovePassenger(this);
}
if (m_nPedState == PED_EXIT_CAR || m_nPedState == PED_DRAG_FROM_CAR)
@@ -306,6 +395,12 @@ CPed::~CPed(void)
}
if (m_pFire)
m_pFire->Extinguish();
+
+ ClearWeapons();
+ if (bCarPassenger)
+ CPopulation::ms_nTotalCarPassengerPeds--;
+ if (bMiamiViceCop)
+ CPopulation::NumMiamiViceCops--;
CPopulation::UpdatePedCount((ePedType)m_nPedType, true);
DMAudio.DestroyEntity(m_audioEntityId);
@@ -357,11 +452,22 @@ CPed::SetModelIndex(uint32 mi)
m_animGroup = (AssocGroupId) modelInfo->m_animGroup;
CAnimManager::AddAnimation(GetClump(), m_animGroup, ANIM_STD_IDLE);
+ if (!CanUseTorsoWhenLooking())
+ m_pedIK.m_flags |= CPedIK::LOOKAROUND_HEAD_ONLY;
+
(*RPANIMBLENDCLUMPDATA(m_rwObject))->velocity2d = &m_vecAnimMoveDelta;
-#ifdef PED_SKIN
if(modelInfo->GetHitColModel() == nil)
modelInfo->CreateHitColModelSkinned(GetClump());
+
+ UpdateRpHAnim();
+#ifdef USE_CUTSCENE_SHADOW_FOR_PED
+ if (!m_pRTShadow)
+ {
+ m_pRTShadow = new CCutsceneShadow;
+ m_pRTShadow->Create(m_rwObject, 10, 1, 1, 1);
+ //m_pRTShadow->Create(m_rwObject, 8, 0, 0, 0);
+ }
#endif
}
@@ -372,14 +478,21 @@ CPed::SetPedStats(ePedStats pedStat)
}
void
+CPed::DeleteRwObject()
+{
+ CEntity::DeleteRwObject();
+}
+
+void
CPed::BuildPedLists(void)
{
if (((CTimer::GetFrameCounter() + m_randomSeed) % 16) == 0) {
CVector centre = CEntity::GetBoundCentre();
- CRect rect(centre.x - 20.0f,
- centre.y - 20.0f,
- centre.x + 20.0f,
- centre.y + 20.0f);
+ int deadsRegistered = 0;
+ CRect rect(centre.x - 20.f * nThreatReactionRangeMultiplier,
+ centre.y - 20.f * nThreatReactionRangeMultiplier,
+ centre.x + 20.f * nThreatReactionRangeMultiplier,
+ centre.y + 20.f * nThreatReactionRangeMultiplier);
int xstart = CWorld::GetSectorIndexX(rect.left);
int ystart = CWorld::GetSectorIndexY(rect.top);
int xend = CWorld::GetSectorIndexX(rect.right);
@@ -390,9 +503,14 @@ CPed::BuildPedLists(void)
for(int x = xstart; x <= xend; x++) {
for (CPtrNode *pedPtrNode = CWorld::GetSector(x,y)->m_lists[ENTITYLIST_PEDS].first; pedPtrNode; pedPtrNode = pedPtrNode->next) {
CPed *ped = (CPed*)pedPtrNode->item;
- if (ped != this && !ped->bInVehicle) {
- float dist = (ped->GetPosition() - GetPosition()).Magnitude2D();
- if (nThreatReactionRangeMultiplier * 30.0f > dist) {
+ if (ped != this && (!ped->bInVehicle || (ped->m_pMyVehicle && ped->m_pMyVehicle->IsBike()))) {
+
+ if (nThreatReactionRangeMultiplier * 30.0f > (ped->GetPosition() - GetPosition()).Magnitude2D()) {
+ if (ped->m_nPedState == PED_DEAD) {
+ if (deadsRegistered > 3)
+ continue;
+ deadsRegistered++;
+ }
#ifdef FIX_BUGS
// If the gap ped list is full, sort it and truncate it
// before pushing more unsorted peds
@@ -424,36 +542,38 @@ CPed::BuildPedLists(void)
}
for (int pedToClear = m_numNearPeds; pedToClear < ARRAY_SIZE(m_nearPeds); pedToClear++)
m_nearPeds[pedToClear] = nil;
- } else {
- for(int i = 0; i < ARRAY_SIZE(m_nearPeds); ) {
- bool removePed = false;
- if (m_nearPeds[i]) {
- if (m_nearPeds[i]->IsPointerValid()) {
- float distSqr = (GetPosition() - m_nearPeds[i]->GetPosition()).MagnitudeSqr2D();
- if (distSqr > 900.0f)
- removePed = true;
- } else
+ }
+
+ for(int i = 0; i < ARRAY_SIZE(m_nearPeds); ) {
+ bool removePed = false;
+ if (m_nearPeds[i]) {
+ if (m_nearPeds[i]->IsPointerValid()) {
+ float distSqr = (GetPosition() - m_nearPeds[i]->GetPosition()).MagnitudeSqr2D();
+ if (distSqr > sq(nThreatReactionRangeMultiplier * 30.f)) {
removePed = true;
+ }
+ } else {
+ removePed = true;
}
+ }
- assert(i == ARRAY_SIZE(m_nearPeds) - 1 || m_nearPeds[i] || !m_nearPeds[i+1]); // ensure nil comes after nil
+ assert(i == ARRAY_SIZE(m_nearPeds) - 1 || m_nearPeds[i] || !m_nearPeds[i+1]); // ensure nil comes after nil
- if (removePed) {
- // If we arrive here, the ped we're checking isn't "near", so we should remove it.
- for (int j = i; j < ARRAY_SIZE(m_nearPeds) - 1; j++) {
- m_nearPeds[j] = m_nearPeds[j + 1];
- m_nearPeds[j + 1] = nil;
- }
- m_nearPeds[ARRAY_SIZE(m_nearPeds) - 1] = nil;
- m_numNearPeds--;
- } else
- i++;
- }
+ if (removePed) {
+ // If we arrive here, the ped we're checking isn't "near", so we should remove it.
+ for (int j = i; j < ARRAY_SIZE(m_nearPeds) - 1; j++) {
+ m_nearPeds[j] = m_nearPeds[j + 1];
+ m_nearPeds[j + 1] = nil;
+ }
+ m_nearPeds[ARRAY_SIZE(m_nearPeds) - 1] = nil;
+ m_numNearPeds--;
+ } else
+ i++;
}
}
bool
-CPed::OurPedCanSeeThisOne(CEntity *target)
+CPed::OurPedCanSeeThisOne(CEntity *target, bool shootablesDoBlock)
{
CColPoint colpoint;
CEntity *ent;
@@ -469,9 +589,8 @@ CPed::OurPedCanSeeThisOne(CEntity *target)
return false;
// Check line of sight from head
- CVector headPos = this->GetPosition();
- headPos.z += 1.0f;
- return !CWorld::ProcessLineOfSight(headPos, target->GetPosition(), colpoint, ent, true, false, false, false, false, false);
+ return !CWorld::ProcessLineOfSight(GetPosition() + CVector(0.f, 0.f, 1.f), target->GetPosition() + CVector(0.f, 0.f, 1.f),
+ colpoint, ent, true, false, false, shootablesDoBlock, false, false, false, shootablesDoBlock);
}
// Some kind of binary sort
@@ -520,7 +639,7 @@ CPed::SetMoveState(eMoveState state)
void
CPed::SetMoveAnim(void)
{
- if (m_nStoredMoveState == m_nMoveState || !IsPedInControl())
+ if (m_nStoredMoveState == m_nMoveState || !IsPedInControl() || m_attachedTo)
return;
if (m_nMoveState == PEDMOVE_NONE) {
@@ -536,12 +655,14 @@ CPed::SetMoveAnim(void)
CAnimBlendAssociation *animAssoc = RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_BLOCK);
if (!animAssoc) {
- CAnimBlendAssociation *fightIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_FIGHT_IDLE);
- animAssoc = fightIdleAssoc;
- if (fightIdleAssoc && m_nPedState == PED_FIGHT)
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_FIGHT_IDLE);
+ if (!animAssoc)
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_MELEE_IDLE_FIGHTMODE);
+
+ if (animAssoc && m_nPedState == PED_FIGHT)
return;
- if (fightIdleAssoc) {
+ if (animAssoc) {
CAnimBlendAssociation *idleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_IDLE);
if (!idleAssoc || idleAssoc->blendDelta <= 0.0f) {
animAssoc->flags |= ASSOC_DELETEFADEDOUT;
@@ -661,10 +782,7 @@ CPed::SetStoredState(void)
if (m_nMoveState == PEDMOVE_NONE || m_nMoveState == PEDMOVE_STILL)
m_nMoveState = PEDMOVE_WALK;
}
-#ifdef VC_PED_PORTS
- if (m_nPedState != PED_IDLE)
-#endif
- {
+ if (m_nPedState != PED_IDLE) {
m_nLastPedState = m_nPedState;
if (m_nMoveState >= m_nPrevMoveState)
m_nPrevMoveState = m_nMoveState;
@@ -674,7 +792,7 @@ CPed::SetStoredState(void)
void
CPed::RestorePreviousState(void)
{
- if(!CanSetPedState() || m_nPedState == PED_FALL)
+ if (!CanSetPedState() || m_nPedState == PED_FALL)
return;
if (m_nPedState == PED_GETUP && !bGetUpAnimStarted)
@@ -702,14 +820,15 @@ CPed::RestorePreviousState(void)
bIsRunning = false;
if (bFindNewNodeAfterStateRestore) {
if (m_pNextPathNode) {
- CVector diff = m_pNextPathNode->GetPosition() - GetPosition();
+ CVector nextNode = CPathFind::TakeWidthIntoAccountForWandering(m_pNextPathNode, m_randomSeed);
+ CVector diff = nextNode - GetPosition();
if (diff.MagnitudeSqr() < sq(7.0f)) {
SetMoveState(PEDMOVE_WALK);
break;
}
}
}
- SetWanderPath(CGeneral::GetRandomNumber() & 7);
+ SetWanderPath(m_nPedState == PED_FOLLOW_PATH ? m_nPathDir : CGeneral::GetRandomNumber() & 7);
break;
default:
SetPedState(m_nLastPedState);
@@ -732,18 +851,22 @@ CPed::ScanForThreats(void)
return PED_FLAG_EXPLOSION;
}
- CPed *shooter = nil;
- if ((fearFlags & PED_FLAG_GUN) && (shooter = CheckForGunShots()) && (m_nPedType != shooter->m_nPedType || m_nPedType == PEDTYPE_CIVMALE || m_nPedType == PEDTYPE_CIVFEMALE)) {
- if (!IsGangMember()) {
- m_threatEntity = shooter;
- m_threatEntity->RegisterReference((CEntity **) &m_threatEntity);
- return PED_FLAG_GUN;
- }
+ if (fearFlags & PED_FLAG_GUN) {
+ CPed *shooter = CheckForGunShots();
+ if (shooter && (m_nPedType != shooter->m_nPedType || m_nPedType == PEDTYPE_CIVMALE || m_nPedType == PEDTYPE_CIVFEMALE)) {
+ if (!IsGangMember()) {
+ m_threatEntity = shooter;
+ m_threatEntity->RegisterReference((CEntity**)&m_threatEntity);
+ return PED_FLAG_GUN;
+ }
- if (CPedType::GetFlag(shooter->m_nPedType) & fearFlags) {
- m_threatEntity = shooter;
- m_threatEntity->RegisterReference((CEntity **) &m_threatEntity);
- return CPedType::GetFlag(shooter->m_nPedType);
+ if (CPedType::GetFlag(shooter->m_nPedType) & fearFlags || m_nPedType == PEDTYPE_GANG5) {
+ if (m_threatEntity)
+ m_threatEntity->CleanUpOldReference(&m_threatEntity);
+ m_threatEntity = shooter;
+ m_threatEntity->RegisterReference((CEntity**)&m_threatEntity);
+ return CPedType::GetFlag(shooter->m_nPedType);
+ }
}
}
@@ -761,32 +884,6 @@ CPed::ScanForThreats(void)
uint32 flagsOfNearPed = 0;
CPed *pedToFearFrom = nil;
-#ifndef VC_PED_PORTS
- for (int i = 0; i < m_numNearPeds; i++) {
- if (CharCreatedBy != RANDOM_CHAR || m_nearPeds[i]->CharCreatedBy != MISSION_CHAR || m_nearPeds[i]->IsPlayer()) {
- CPed *nearPed = m_nearPeds[i];
-
- // BUG: WTF Rockstar?! Putting this here will result in returning the flags of farthest ped to us, since m_nearPeds is sorted by distance.
- // Fixed at the bottom of the function.
- flagsOfNearPed = CPedType::GetFlag(nearPed->m_nPedType);
-
- if (flagsOfNearPed & fearFlags) {
- if (nearPed->m_fHealth > 0.0f && OurPedCanSeeThisOne(m_nearPeds[i])) {
- // FIX: Taken from VC
-#ifdef FIX_BUGS
- float nearPedDistSqr = (nearPed->GetPosition() - ourPos).MagnitudeSqr2D();
-#else
- float nearPedDistSqr = (CVector2D(ourPos) - explosionPos).MagnitudeSqr();
-#endif
- if (sq(closestPedDist) > nearPedDistSqr) {
- closestPedDist = Sqrt(nearPedDistSqr);
- pedToFearFrom = m_nearPeds[i];
- }
- }
- }
- }
- }
-#else
bool weSawOurEnemy = false;
bool weMaySeeOurEnemy = false;
float closestEnemyDist = 60.0f;
@@ -797,14 +894,13 @@ CPed::ScanForThreats(void)
continue;
}
- // BUG: Explained at the same occurence of this bug above. Fixed at the bottom of the function.
+ // BUG: Putting this here will result in returning the flags of farthest ped to us, since m_nearPeds is sorted by distance.
+ // Fixed at the bottom of the function.
flagsOfNearPed = CPedType::GetFlag(m_nearPeds[i]->m_nPedType);
if (flagsOfNearPed & fearFlags) {
if (m_nearPeds[i]->m_fHealth > 0.0f) {
-
- // VC also has ability to include objects to line of sight check here (via last bit of flagsL)
- if (OurPedCanSeeThisOne(m_nearPeds[i])) {
+ if (OurPedCanSeeThisOne(m_nearPeds[i], !!bIgnoreThreatsBehindObjects)) {
if (m_nearPeds[i]->m_nPedState == PED_ATTACK) {
if (m_nearPeds[i]->m_pedInObjective == this) {
@@ -831,9 +927,8 @@ CPed::ScanForThreats(void)
CEntity *foundEnt;
// We don't see him yet but he's behind a ped, vehicle or object
- // VC also has ability to include objects to line of sight check here (via last bit of flagsL)
if (!CWorld::ProcessLineOfSight(ourPos, nearPed->GetPosition(), foundCol, foundEnt,
- true, false, false, false, false, false, false)) {
+ true, false, false, !!bIgnoreThreatsBehindObjects, false, false, false)) {
if (nearPed->m_pedInObjective == this) {
float enemyDistSqr = (m_nearPeds[i]->GetPosition() - ourPos).MagnitudeSqr2D();
@@ -859,7 +954,7 @@ CPed::ScanForThreats(void)
}
}
}
-#endif
+
int16 lastVehicle;
CEntity* vehicles[8];
CWorld::FindObjectsInRange(ourPos, 20.0f, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
@@ -873,6 +968,7 @@ CPed::ScanForThreats(void)
// BUG: Same bug as above. Fixed at the bottom of function.
flagsOfNearPed = CPedType::GetFlag(driver->m_nPedType);
if (flagsOfNearPed & fearFlags) {
+
if (driver->m_fHealth > 0.0f && OurPedCanSeeThisOne(nearVeh->pDriver)) {
// FIX: Taken from VC
#ifdef FIX_BUGS
@@ -904,25 +1000,69 @@ CPed::ScanForThreats(void)
}
void
-CPed::SetLookFlag(float direction, bool keepTryingToLook)
+CPed::ScanForDelayedResponseThreats(void)
{
- if (m_lookTimer < CTimer::GetTimeInMilliseconds()) {
+ if (m_threatFlags)
+ return;
+
+ m_threatEntity = nil;
+ m_pEventEntity = nil;
+ m_threatFlags = ScanForThreats();
+ if (m_threatFlags) {
+ if (m_threatEntity || m_pEventEntity) {
+ m_threatCheckTimer = CTimer::GetTimeInMilliseconds() + m_threatCheckInterval;
+ return;
+ }
+ m_threatFlags = 0;
+ }
+ m_threatCheckTimer = 0;
+}
+
+void
+CPed::CheckThreatValidity(void)
+{
+ if (m_threatEntity && !IsEntityPointerValid(m_threatEntity)) {
+ m_threatFlags = 0;
+ m_threatEntity = nil;
+ }
+ if (m_pEventEntity && !IsEntityPointerValid(m_pEventEntity)) {
+ m_threatFlags = 0;
+ m_pEventEntity = nil;
+ }
+ if (!m_threatEntity && !m_pEventEntity)
+ m_threatFlags = 0;
+}
+
+bool
+CPed::CanUseTorsoWhenLooking(void)
+{
+ if (m_nPedState != PED_DRIVING && m_nPedState != PED_DRAG_FROM_CAR && !bIsDucking) {
+ if (m_animGroup != ASSOCGRP_SEXYWOMAN && m_animGroup != ASSOCGRP_WOMAN)
+ return true;
+ }
+ return false;
+}
+
+void
+CPed::SetLookFlag(float direction, bool keepTryingToLook, bool cancelPrevious)
+{
+ if (m_lookTimer < CTimer::GetTimeInMilliseconds() || cancelPrevious) {
bIsLooking = true;
bIsRestoringLook = false;
- m_pLookTarget = nil;
m_fLookDirection = direction;
+ m_pLookTarget = nil;
m_lookTimer = 0;
bKeepTryingToLook = keepTryingToLook;
- if (m_nPedState != PED_DRIVING) {
+ if (CanUseTorsoWhenLooking()) {
m_pedIK.m_flags &= ~CPedIK::LOOKAROUND_HEAD_ONLY;
}
}
}
void
-CPed::SetLookFlag(CEntity *target, bool keepTryingToLook)
+CPed::SetLookFlag(CEntity *target, bool keepTryingToLook, bool cancelPrevious)
{
- if (m_lookTimer < CTimer::GetTimeInMilliseconds()) {
+ if (m_lookTimer < CTimer::GetTimeInMilliseconds() || cancelPrevious) {
bIsLooking = true;
bIsRestoringLook = false;
m_pLookTarget = target;
@@ -930,7 +1070,7 @@ CPed::SetLookFlag(CEntity *target, bool keepTryingToLook)
m_fLookDirection = 999999.0f;
m_lookTimer = 0;
bKeepTryingToLook = keepTryingToLook;
- if (m_nPedState != PED_DRIVING) {
+ if (CanUseTorsoWhenLooking()) {
m_pedIK.m_flags &= ~CPedIK::LOOKAROUND_HEAD_ONLY;
}
}
@@ -943,7 +1083,9 @@ CPed::ClearLookFlag(void) {
bIsRestoringLook = true;
bShakeFist = false;
- m_pedIK.m_flags &= ~CPedIK::LOOKAROUND_HEAD_ONLY;
+ if (CanUseTorsoWhenLooking())
+ m_pedIK.m_flags &= ~CPedIK::LOOKAROUND_HEAD_ONLY;
+
if (IsPlayer())
m_lookTimer = CTimer::GetTimeInMilliseconds() + 2000;
else
@@ -956,53 +1098,19 @@ CPed::ClearLookFlag(void) {
}
void
-FinishFuckUCB(CAnimBlendAssociation *animAssoc, void *arg)
-{
- CPed *ped = (CPed*)arg;
-
- if (animAssoc->animId == ANIM_STD_PARTIAL_FUCKU && ped->GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED)
- ped->RemoveWeaponModel(0);
-}
-
-void
CPed::MoveHeadToLook(void)
{
CVector lookPos;
if (m_lookTimer && CTimer::GetTimeInMilliseconds() > m_lookTimer) {
ClearLookFlag();
- } else if (m_nPedState == PED_DRIVING) {
- m_pedIK.m_flags |= CPedIK::LOOKAROUND_HEAD_ONLY;
- }
-
- if (m_pLookTarget) {
-
- if (!bShakeFist && GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED) {
-
- CAnimBlendAssociation *fuckUAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_PARTIAL_FUCKU);
- if (fuckUAssoc) {
-
- float animTime = fuckUAssoc->currentTime;
- if (animTime > 4.0f / 30.0f && animTime - fuckUAssoc->timeStep > 4.0f / 30.0f) {
-
- bool lookingToCop = false;
- if (m_pLookTarget->GetModelIndex() == MI_POLICE
- || m_pLookTarget->IsPed() && ((CPed*)m_pLookTarget)->m_nPedType == PEDTYPE_COP) {
-
- lookingToCop = true;
- }
+ }
- if (IsPlayer() && (m_pedStats->m_temper >= 52 || lookingToCop)) {
- AddWeaponModel(MI_FINGERS);
- ((CPlayerPed*)this)->AnnoyPlayerPed(true);
-
- } else if ((CGeneral::GetRandomNumber() & 3) == 0) {
- AddWeaponModel(MI_FINGERS);
- }
- }
- }
- }
+ if (bIsLooking || bIsRestoringLook)
+ if (!CanUseTorsoWhenLooking())
+ m_pedIK.m_flags |= CPedIK::LOOKAROUND_HEAD_ONLY;
+ if (m_pLookTarget) {
if (m_pLookTarget->IsPed()) {
((CPed*)m_pLookTarget)->m_pedIK.GetComponentPosition(lookPos, PED_MID);
} else {
@@ -1019,37 +1127,34 @@ CPed::MoveHeadToLook(void)
if (!bShakeFist || bIsAimingGun || bIsRestoringGun)
return;
+ if (m_nPedState == PED_ANSWER_MOBILE)
+ return;
+
if (m_lookTimer - CTimer::GetTimeInMilliseconds() >= 1000)
return;
- bool notRocketLauncher = false;
- bool notTwoHanded = false;
+ bool handFreeToMove = false;
AnimationId animToPlay = ANIM_STD_NUM;
- if (!GetWeapon()->IsType2Handed())
- notTwoHanded = true;
-
- if (notTwoHanded && GetWeapon()->m_eWeaponType != WEAPONTYPE_ROCKETLAUNCHER)
- notRocketLauncher = true;
+ if (!GetWeapon()->IsType2Handed() && GetWeapon()->m_eWeaponType != WEAPONTYPE_ROCKETLAUNCHER)
+ handFreeToMove = true;
- if (IsPlayer() && notRocketLauncher) {
+ if (IsPlayer() && handFreeToMove) {
if (m_pLookTarget->IsPed()) {
-
- if (m_pedStats->m_temper >= 49 && ((CPed*)m_pLookTarget)->m_nPedType != PEDTYPE_COP) {
-
- // FIX: Unreachable and meaningless condition
-#ifndef FIX_BUGS
- if (m_pedStats->m_temper < 47)
+#ifdef FIX_BUGS
+ if (m_pedStats->m_temper > 49 || ((CPed*)m_pLookTarget)->m_nPedType == PEDTYPE_COP)
+#else
+ if (m_pedStats->m_temper < 49 || ((CPed*)m_pLookTarget)->m_nPedType == PEDTYPE_COP)
#endif
- animToPlay = ANIM_STD_PARTIAL_PUNCH;
- } else {
animToPlay = ANIM_STD_PARTIAL_FUCKU;
- }
- } else if (m_pedStats->m_temper > 49 || m_pLookTarget->GetModelIndex() == MI_POLICE) {
- animToPlay = ANIM_STD_PARTIAL_FUCKU;
+ else if(m_pedStats->m_temper < 47)
+ animToPlay = ANIM_STD_PARTIAL_PUNCH;
+ } else {
+ if (m_pedStats->m_temper > 49 || m_pLookTarget->GetModelIndex() == MI_POLICE)
+ animToPlay = ANIM_STD_PARTIAL_FUCKU;
}
- } else if (notRocketLauncher && (CGeneral::GetRandomNumber() & 1)) {
+ } else if (handFreeToMove && (CGeneral::GetRandomNumber() & 1)) {
animToPlay = ANIM_STD_PARTIAL_FUCKU;
}
@@ -1059,13 +1164,10 @@ CPed::MoveHeadToLook(void)
if (newAssoc) {
newAssoc->flags |= ASSOC_FADEOUTWHENDONE;
newAssoc->flags |= ASSOC_DELETEFADEDOUT;
- if (newAssoc->animId == ANIM_STD_PARTIAL_FUCKU)
- newAssoc->SetDeleteCallback(FinishFuckUCB, this);
}
}
bShakeFist = false;
- return;
- } else if (999999.0f == m_fLookDirection) {
+ } else if (m_fLookDirection == 999999.0f) {
ClearLookFlag();
} else if (!m_pedIK.LookInDirection(m_fLookDirection, 0.0f)) {
if (!bKeepTryingToLook)
@@ -1076,8 +1178,13 @@ CPed::MoveHeadToLook(void)
void
CPed::RestoreHeadPosition(void)
{
+ if(!CanUseTorsoWhenLooking())
+ m_pedIK.m_flags |= CPedIK::LOOKAROUND_HEAD_ONLY;
+
if (m_pedIK.RestoreLookAt()) {
bIsRestoringLook = false;
+ if(CanUseTorsoWhenLooking())
+ m_pedIK.m_flags &= ~CPedIK::LOOKAROUND_HEAD_ONLY;
}
}
@@ -1090,6 +1197,10 @@ CPed::SetAimFlag(float angle)
m_lookTimer = 0;
m_pLookTarget = nil;
m_pSeekTarget = nil;
+
+ if (bIsDucking)
+ m_pedIK.m_flags &= ~CPedIK::AIMS_WITH_ARM;
+
if (CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM))
m_pedIK.m_flags |= CPedIK::AIMS_WITH_ARM;
else
@@ -1101,8 +1212,12 @@ CPed::SetAimFlag(CEntity *to)
{
bIsAimingGun = true;
bIsRestoringGun = false;
+ if (m_pLookTarget)
+ m_pLookTarget->CleanUpOldReference(&m_pLookTarget);
m_pLookTarget = to;
m_pLookTarget->RegisterReference((CEntity **) &m_pLookTarget);
+ if (m_pSeekTarget)
+ m_pSeekTarget->CleanUpOldReference(&m_pSeekTarget);
m_pSeekTarget = to;
m_pSeekTarget->RegisterReference((CEntity **) &m_pSeekTarget);
m_lookTimer = 0;
@@ -1115,13 +1230,15 @@ CPed::ClearAimFlag(void)
bIsAimingGun = false;
bIsRestoringGun = true;
m_pedIK.m_flags &= ~CPedIK::AIMS_WITH_ARM;
-#if defined VC_PED_PORTS || defined FIX_BUGS
m_lookTimer = 0;
-#endif
}
- if (IsPlayer())
+ if (IsPlayer()) {
((CPlayerPed*)this)->m_fFPSMoveHeading = 0.0f;
+#ifdef FREE_CAM
+ ((CPlayerPed*)this)->m_bFreeAimActive = false;
+#endif
+ }
}
void
@@ -1129,17 +1246,22 @@ CPed::AimGun(void)
{
CVector vector;
+ if (IsPlayer() && bIsDucking)
+ m_pedIK.m_flags &= ~CPedIK::AIMS_WITH_ARM;
+
if (m_pSeekTarget) {
if (m_pSeekTarget->IsPed()) {
((CPed*)m_pSeekTarget)->m_pedIK.GetComponentPosition(vector, PED_MID);
} else {
vector = m_pSeekTarget->GetPosition();
}
- Say(SOUND_PED_ATTACK);
+
+ if (!IsPlayer())
+ Say(SOUND_PED_ATTACK);
bCanPointGunAtTarget = m_pedIK.PointGunAtPosition(vector);
if (m_pLookTarget != m_pSeekTarget) {
- SetLookFlag(m_pSeekTarget, true);
+ SetLookFlag(m_pSeekTarget, true, true);
}
} else {
@@ -1165,6 +1287,12 @@ CPed::RestoreGunPosition(void)
}
}
+bool
+CPed::CanWeRunAndFireWithWeapon(void)
+{
+ return CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM);
+}
+
void
CPed::ScanForInterestingStuff(void)
{
@@ -1236,28 +1364,6 @@ CPed::ScanForInterestingStuff(void)
}
if (m_nPedState == PED_WANDER_PATH) {
-#ifndef VC_PED_PORTS
- if (CTimer::GetTimeInMilliseconds() > m_chatTimer) {
-
- // += 2 is weird
- for (int i = 0; i < m_numNearPeds; i += 2) {
- if (m_nearPeds[i]->m_nPedState == PED_WANDER_PATH && WillChat(m_nearPeds[i])) {
- if (CGeneral::GetRandomNumberInRange(0, 100) >= 100)
- m_chatTimer = CTimer::GetTimeInMilliseconds() + 30000;
- else {
- if ((GetPosition() - m_nearPeds[i]->GetPosition()).Magnitude() >= 1.8f) {
- m_chatTimer = CTimer::GetTimeInMilliseconds() + 30000;
- } else if (CanSeeEntity(m_nearPeds[i])) {
- int time = CGeneral::GetRandomNumber() % 4000 + 10000;
- SetChat(m_nearPeds[i], time);
- m_nearPeds[i]->SetChat(this, time);
- return;
- }
- }
- }
- }
- }
-#else
if (CGeneral::GetRandomNumberInRange(0.0f, 1.0f) < 0.5f) {
if (CTimer::GetTimeInMilliseconds() > m_chatTimer) {
for (int i = 0; i < m_numNearPeds; i ++) {
@@ -1270,7 +1376,6 @@ CPed::ScanForInterestingStuff(void)
int time = CGeneral::GetRandomNumber() % 4000 + 10000;
SetChat(m_nearPeds[i], time);
m_nearPeds[i]->SetChat(this, time);
- return;
}
}
}
@@ -1278,50 +1383,6 @@ CPed::ScanForInterestingStuff(void)
} else {
m_chatTimer = CTimer::GetTimeInMilliseconds() + 200;
}
-#endif
- }
-
- // Parts below aren't there in VC, they're in somewhere else.
- if (!CGame::noProstitutes && m_nPedType == PEDTYPE_PROSTITUTE && CharCreatedBy != MISSION_CHAR
- && m_objectiveTimer < CTimer::GetTimeInMilliseconds() && !CTheScripts::IsPlayerOnAMission()) {
-
- CVector pos = GetPosition();
- int16 lastVehicle;
- CEntity* vehicles[8];
- CWorld::FindObjectsInRange(pos, CHECK_NEARBY_THINGS_MAX_DIST, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
-
- for (int i = 0; i < lastVehicle; i++) {
- CVehicle* veh = (CVehicle*)vehicles[i];
-
- if (veh->IsVehicleNormal()) {
- if (veh->IsCar()) {
- if ((GetPosition() - veh->GetPosition()).Magnitude() < 5.0f && veh->IsRoomForPedToLeaveCar(CAR_DOOR_LF, nil)) {
- SetObjective(OBJECTIVE_SOLICIT_VEHICLE, veh);
- Say(SOUND_PED_SOLICIT);
- return;
- }
- }
- }
- }
- }
- if (m_nPedType == PEDTYPE_CIVMALE || m_nPedType == PEDTYPE_CIVFEMALE) {
- CVector pos = GetPosition();
- int16 lastVehicle;
- CEntity* vehicles[8];
- CWorld::FindObjectsInRange(pos, CHECK_NEARBY_THINGS_MAX_DIST, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
-
- for (int i = 0; i < lastVehicle; i++) {
- CVehicle* veh = (CVehicle*)vehicles[i];
-
- if (veh->GetModelIndex() == MI_MRWHOOP) {
- if (veh->GetStatus() != STATUS_ABANDONED && veh->GetStatus() != STATUS_WRECKED) {
- if ((GetPosition() - veh->GetPosition()).Magnitude() < 5.0f) {
- SetObjective(OBJECTIVE_BUY_ICE_CREAM, veh);
- return;
- }
- }
- }
- }
}
}
@@ -1341,6 +1402,10 @@ CPed::WillChat(CPed *stranger)
return true;
if (m_nPedType == PEDTYPE_CRIMINAL)
return false;
+ if (stranger->m_nPedType == PEDTYPE_COP)
+ return false;
+ if (stranger->IsPlayer())
+ return false;
if ((IsGangMember() || stranger->IsGangMember()) && m_nPedType != stranger->m_nPedType)
return false;
return true;
@@ -1360,12 +1425,6 @@ CPed::CalculateNewVelocity(void)
limitedRotDest -= 2 * PI;
}
-#ifdef FREE_CAM
- if (!TheCamera.Cams[0].Using3rdPersonMouseCam())
-#endif
- if (IsPlayer() && m_nPedState == PED_ATTACK)
- headAmount /= 4.0f;
-
float neededTurn = limitedRotDest - m_fRotationCur;
if (neededTurn <= headAmount) {
if (neededTurn > (-headAmount))
@@ -1389,8 +1448,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();
@@ -1410,11 +1473,13 @@ CPed::CalculateNewVelocity(void)
CAnimBlendAssociation *idleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_IDLE);
CAnimBlendAssociation *fightAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_FIGHT_IDLE);
-#ifdef VC_PED_PORTS
+ if(!fightAssoc)
+ fightAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_IDLE_TIRED);
+
+ if(!fightAssoc)
+ fightAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_MELEE_IDLE_FIGHTMODE);
+
if ((!idleAssoc || idleAssoc->blendAmount < 0.5f) && !fightAssoc && !bIsDucking) {
-#else
- if ((!idleAssoc || idleAssoc->blendAmount < 0.5f) && !fightAssoc) {
-#endif
LimbOrientation newUpperLegs;
newUpperLegs.yaw = localWalkAngle;
@@ -1425,31 +1490,14 @@ CPed::CalculateNewVelocity(void)
}
if (newUpperLegs.yaw > -DEGTORAD(50.0f) && newUpperLegs.yaw < DEGTORAD(50.0f)) {
-#ifdef PED_SKIN
- if(IsClumpSkinned(GetClump())){
-/*
- // this looks shit
- newUpperLegs.pitch = 0.0f;
- RwV3d axis = { -1.0f, 0.0f, 0.0f };
- RtQuatRotate(&m_pFrames[PED_UPPERLEGL]->hanimFrame->q, &axis, RADTODEG(newUpperLegs.yaw), rwCOMBINEPRECONCAT);
- RtQuatRotate(&m_pFrames[PED_UPPERLEGR]->hanimFrame->q, &axis, RADTODEG(newUpperLegs.yaw), rwCOMBINEPRECONCAT);
-*/
- newUpperLegs.pitch = 0.1f;
- RwV3d Xaxis = { 1.0f, 0.0f, 0.0f };
- RwV3d Zaxis = { 0.0f, 0.0f, 1.0f };
- RtQuatRotate(&m_pFrames[PED_UPPERLEGL]->hanimFrame->q, &Zaxis, RADTODEG(newUpperLegs.pitch), rwCOMBINEPOSTCONCAT);
- RtQuatRotate(&m_pFrames[PED_UPPERLEGL]->hanimFrame->q, &Xaxis, RADTODEG(newUpperLegs.yaw), rwCOMBINEPOSTCONCAT);
- RtQuatRotate(&m_pFrames[PED_UPPERLEGR]->hanimFrame->q, &Zaxis, RADTODEG(newUpperLegs.pitch), rwCOMBINEPOSTCONCAT);
- RtQuatRotate(&m_pFrames[PED_UPPERLEGR]->hanimFrame->q, &Xaxis, RADTODEG(newUpperLegs.yaw), rwCOMBINEPOSTCONCAT);
-
- bDontAcceptIKLookAts = true;
- }else
-#endif
- {
- newUpperLegs.pitch = 0.0f;
- m_pedIK.RotateTorso(m_pFrames[PED_UPPERLEGL], &newUpperLegs, false);
- m_pedIK.RotateTorso(m_pFrames[PED_UPPERLEGR], &newUpperLegs, false);
- }
+ newUpperLegs.pitch = 0.1f;
+ RwV3d Xaxis = { 1.0f, 0.0f, 0.0f };
+ RwV3d Zaxis = { 0.0f, 0.0f, 1.0f };
+ RtQuatRotate(&m_pFrames[PED_UPPERLEGL]->hanimFrame->q, &Zaxis, RADTODEG(newUpperLegs.pitch), rwCOMBINEPOSTCONCAT);
+ RtQuatRotate(&m_pFrames[PED_UPPERLEGL]->hanimFrame->q, &Xaxis, RADTODEG(newUpperLegs.yaw), rwCOMBINEPOSTCONCAT);
+ RtQuatRotate(&m_pFrames[PED_UPPERLEGR]->hanimFrame->q, &Zaxis, RADTODEG(newUpperLegs.pitch), rwCOMBINEPOSTCONCAT);
+ RtQuatRotate(&m_pFrames[PED_UPPERLEGR]->hanimFrame->q, &Xaxis, RADTODEG(newUpperLegs.yaw), rwCOMBINEPOSTCONCAT);
+ bDontAcceptIKLookAts = true;
}
}
}
@@ -1469,9 +1517,9 @@ 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);
@@ -1480,7 +1528,7 @@ CPed::WorkOutHeadingForMovingFirstPerson(float offset)
void
CPed::UpdatePosition(void)
{
- if (CReplay::IsPlayingBack() || !bIsStanding)
+ if (CReplay::IsPlayingBack() || !bIsStanding || m_attachedTo)
return;
CVector2D velocityChange;
@@ -1527,7 +1575,7 @@ CPed::UpdatePosition(void)
}
// Take time step into account
- if (m_pCurrentPhysSurface) {
+ if (m_pCurrentPhysSurface && (!m_pCurrentPhysSurface->bInfiniteMass || m_pCurrentPhysSurface->m_phy_flagA08)) {
float speedChange = velocityChange.Magnitude();
float changeMult = speedChange;
if (m_nPedState == PED_DIE && m_pCurrentPhysSurface->IsVehicle()) {
@@ -1563,32 +1611,26 @@ CPed::ClearAll(void)
SetMoveState(PEDMOVE_NONE);
m_pSeekTarget = nil;
m_vecSeekPos = CVector(0.0f, 0.0f, 0.0f);
- m_fleeFromPosX = 0.0f;
- m_fleeFromPosY = 0.0f;
+ m_fleeFromPos = CVector2D(0.0f, 0.0f);
m_fleeFrom = nil;
m_fleeTimer = 0;
+ m_threatEx = nil;
bUsesCollision = true;
-#ifdef VC_PED_PORTS
ClearPointGunAt();
-#else
- ClearAimFlag();
- ClearLookFlag();
-#endif
bIsPointingGunAt = false;
bRenderPedInCar = true;
bKnockedUpIntoAir = false;
+ bKnockedOffBike = false;
m_pCollidingEntity = nil;
}
void
CPed::ProcessBuoyancy(void)
{
+ float buoyancyLevel = 1.1f;
static uint32 nGenerateRaindrops = 0;
static uint32 nGenerateWaterCircles = 0;
- CRGBA color(((0.5f * CTimeCycle::GetDirectionalRed() + CTimeCycle::GetAmbientRed()) * 127.5f),
- ((0.5f * CTimeCycle::GetDirectionalBlue() + CTimeCycle::GetAmbientBlue()) * 127.5f),
- ((0.5f * CTimeCycle::GetDirectionalGreen() + CTimeCycle::GetAmbientGreen()) * 127.5f),
- CGeneral::GetRandomNumberInRange(48.0f, 96.0f));
+ CRGBA color;
if (bInVehicle)
return;
@@ -1596,21 +1638,22 @@ CPed::ProcessBuoyancy(void)
CVector buoyancyPoint;
CVector buoyancyImpulse;
-#ifndef VC_PED_PORTS
- float buoyancyLevel = (m_nPedState == PED_DEAD ? 1.5f : 1.3f);
-#else
- float buoyancyLevel = (m_nPedState == PED_DEAD ? 1.8f : 1.1f);
-#endif
+ if (DyingOrDead())
+ buoyancyLevel = 1.8f;
if (mod_Buoyancy.ProcessBuoyancy(this, GRAVITY * m_fMass * buoyancyLevel, &buoyancyPoint, &buoyancyImpulse)) {
bTouchingWater = true;
CEntity *entity;
CColPoint point;
if (CWorld::ProcessVerticalLine(GetPosition(), GetPosition().z - 3.0f, point, entity, false, true, false, false, false, false, nil)
- && entity->IsVehicle() && ((CVehicle*)entity)->IsBoat()) {
+ && entity->IsVehicle() && ((CVehicle*)entity)->IsBoat() && !entity->bRenderScorched) {
bIsInWater = false;
return;
}
+ color.r = (0.5f * CTimeCycle::GetDirectionalRed() + CTimeCycle::GetAmbientRed()) * 127.5f;
+ color.g = (0.5f * CTimeCycle::GetDirectionalBlue() + CTimeCycle::GetAmbientBlue()) * 127.5f;
+ color.b = (0.5f * CTimeCycle::GetDirectionalGreen() + CTimeCycle::GetAmbientGreen()) * 127.5f;
+ color.a = CGeneral::GetRandomNumberInRange(48.0f, 96.0f);
bIsInWater = true;
ApplyMoveForce(buoyancyImpulse);
if (!DyingOrDead()) {
@@ -1627,109 +1670,76 @@ CPed::ProcessBuoyancy(void)
bIsInTheAir = false;
}
pos.z = pos.z - 0.8f;
-#ifdef PC_PARTICLE
CParticleObject::AddObject(POBJECT_PED_WATER_SPLASH, pos, CVector(0.0f, 0.0f, 0.0f), 0.0f, 50, color, true);
-#else
- CParticleObject::AddObject(POBJECT_PED_WATER_SPLASH, pos, CVector(0.0f, 0.0f, 0.0f), 0.0f, 50, CRGBA(0, 0, 0, 0), true);
-#endif
m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
SetPedState(PED_IDLE);
return;
}
}
}
- float speedMult = 0.0f;
- if (buoyancyImpulse.z / m_fMass > GRAVITY * 0.75f * CTimer::GetTimeStep()
- || mod_Buoyancy.m_waterlevel > GetPosition().z) {
+ }
+ float speedMult = 0.0f;
+ if (buoyancyImpulse.z / m_fMass > GRAVITY * CTimer::GetTimeStep()
+ || mod_Buoyancy.m_waterlevel > GetPosition().z + 0.6f) {
+ speedMult = pow(0.9f, CTimer::GetTimeStep());
+ m_vecMoveSpeed.x *= speedMult;
+ 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 > GRAVITY * 0.25f * CTimer::GetTimeStep()) {
+ if (speedMult == 0.0f) {
speedMult = pow(0.9f, CTimer::GetTimeStep());
- m_vecMoveSpeed.x *= speedMult;
- m_vecMoveSpeed.y *= speedMult;
- m_vecMoveSpeed.z *= speedMult;
- bIsStanding = false;
- InflictDamage(nil, WEAPONTYPE_DROWNING, 3.0f * CTimer::GetTimeStep(), PEDPIECE_TORSO, 0);
}
- if (buoyancyImpulse.z / m_fMass > GRAVITY * 0.25f * CTimer::GetTimeStep()) {
- if (speedMult == 0.0f) {
- speedMult = pow(0.9f, CTimer::GetTimeStep());
- }
- m_vecMoveSpeed.x *= speedMult;
- m_vecMoveSpeed.y *= speedMult;
- if (m_vecMoveSpeed.z >= -0.1f) {
- if (m_vecMoveSpeed.z < -0.04f)
- m_vecMoveSpeed.z = -0.02f;
- } else {
- m_vecMoveSpeed.z = -0.01f;
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_SPLASH, 0.0f);
-#ifdef PC_PARTICLE
- CVector aBitForward = 2.2f * m_vecMoveSpeed + GetPosition();
- float level = 0.0f;
- if (CWaterLevel::GetWaterLevel(aBitForward, &level, false))
- aBitForward.z = level;
-
- CParticleObject::AddObject(POBJECT_PED_WATER_SPLASH, aBitForward, CVector(0.0f, 0.0f, 0.1f), 0.0f, 200, color, true);
- nGenerateRaindrops = CTimer::GetTimeInMilliseconds() + 80;
- nGenerateWaterCircles = CTimer::GetTimeInMilliseconds() + 100;
-#else
- CVector aBitForward = 1.6f * m_vecMoveSpeed + GetPosition();
- float level = 0.0f;
- if (CWaterLevel::GetWaterLevel(aBitForward, &level, false))
- aBitForward.z = level + 0.5f;
-
- CVector vel = m_vecMoveSpeed * 0.1f;
- vel.z = 0.18f;
- CParticleObject::AddObject(POBJECT_PED_WATER_SPLASH, aBitForward, vel, 0.0f, 350, CRGBA(0, 0, 0, 0), true);
- nGenerateRaindrops = CTimer::GetTimeInMilliseconds() + 300;
- nGenerateWaterCircles = CTimer::GetTimeInMilliseconds() + 60;
-#endif
- }
- }
- } else
- return;
- } else
- bTouchingWater = false;
+ m_vecMoveSpeed.x *= speedMult;
+ m_vecMoveSpeed.y *= speedMult;
+ if (m_vecMoveSpeed.z >= -0.1f) {
+ if (m_vecMoveSpeed.z < -0.04f)
+ m_vecMoveSpeed.z = -0.02f;
+ } else {
+ m_vecMoveSpeed.z = -0.01f;
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_SPLASH, 0.0f);
+ CVector aBitForward = 2.2f * m_vecMoveSpeed + GetPosition();
+ float level = 0.0f;
+ if (CWaterLevel::GetWaterLevel(aBitForward, &level, false))
+ aBitForward.z = level;
- if (nGenerateWaterCircles && CTimer::GetTimeInMilliseconds() >= nGenerateWaterCircles) {
- CVector pos = GetPosition();
- float level = 0.0f;
- if (CWaterLevel::GetWaterLevel(pos, &level, false))
- pos.z = level;
-
- if (pos.z != 0.0f) {
- nGenerateWaterCircles = 0;
- for(int i = 0; i < 4; i++) {
-#ifdef PC_PARTICLE
- pos.x += CGeneral::GetRandomNumberInRange(-0.75f, 0.75f);
- pos.y += CGeneral::GetRandomNumberInRange(-0.75f, 0.75f);
- CParticle::AddParticle(PARTICLE_RAIN_SPLASH_BIGGROW, pos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, color, 0, 0, 0, 0);
-#else
- pos.x += CGeneral::GetRandomNumberInRange(-2.5f, 2.5f);
- pos.y += CGeneral::GetRandomNumberInRange(-2.5f, 2.5f);
- CParticle::AddParticle(PARTICLE_RAIN_SPLASH_BIGGROW, pos+CVector(0.0f, 0.0f, 1.0f), CVector(0.0f, 0.0f, 0.0f));
-#endif
+ CParticleObject::AddObject(POBJECT_PED_WATER_SPLASH, aBitForward, CVector(0.0f, 0.0f, 0.1f), 0.0f, 200, color, true);
+ nGenerateRaindrops = CTimer::GetTimeInMilliseconds() + 80;
+ nGenerateWaterCircles = CTimer::GetTimeInMilliseconds() + 100;
}
}
- }
-
- if (nGenerateRaindrops && CTimer::GetTimeInMilliseconds() >= nGenerateRaindrops) {
- CVector pos = GetPosition();
- float level = 0.0f;
- if (CWaterLevel::GetWaterLevel(pos, &level, false))
- pos.z = level;
+ if (nGenerateWaterCircles && CTimer::GetTimeInMilliseconds() >= nGenerateWaterCircles) {
+ CVector pos = GetPosition();
+ float level = 0.0f;
+ if (CWaterLevel::GetWaterLevel(pos, &level, false))
+ pos.z = level;
+
+ if (pos.z != 0.0f) {
+ nGenerateWaterCircles = 0;
+ for(int i = 0; i < 4; i++) {
+ pos.x += CGeneral::GetRandomNumberInRange(-0.75f, 0.75f);
+ pos.y += CGeneral::GetRandomNumberInRange(-0.75f, 0.75f);
+ CParticle::AddParticle(PARTICLE_RAIN_SPLASH_BIGGROW, pos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, color, 0, 0, 0, 0);
+ }
+ }
+ }
+ if (nGenerateRaindrops && CTimer::GetTimeInMilliseconds() >= nGenerateRaindrops) {
+ CVector pos = GetPosition();
+ float level = 0.0f;
+ if (CWaterLevel::GetWaterLevel(pos, &level, false))
+ pos.z = level;
- if (pos.z >= 0.0f) {
-#ifdef PC_PARTICLE
- pos.z += 0.25f;
-#else
- pos.z += 0.5f;
-#endif
- nGenerateRaindrops = 0;
-#ifdef PC_PARTICLE
- CParticleObject::AddObject(POBJECT_SPLASHES_AROUND, pos, CVector(0.0f, 0.0f, 0.0f), 4.5f, 1500, CRGBA(0,0,0,0), true);
-#else
- CParticleObject::AddObject(POBJECT_SPLASHES_AROUND, pos, CVector(0.0f, 0.0f, 0.0f), 4.5f, 2500, CRGBA(0,0,0,0), true);
-#endif
+ if (pos.z >= 0.0f) {
+ pos.z += 0.25f;
+ nGenerateRaindrops = 0;
+ CParticleObject::AddObject(POBJECT_SPLASHES_AROUND, pos, CVector(0.0f, 0.0f, 0.0f), 4.5f, 1500, CRGBA(0,0,0,0), true);
+ }
}
- }
+ } else
+ bTouchingWater = false;
}
void
@@ -1738,8 +1748,8 @@ CPed::ProcessControl(void)
CColPoint foundCol;
CEntity *foundEnt = nil;
- if (m_nZoneLevel > LEVEL_GENERIC && m_nZoneLevel != CCollision::ms_collisionInMemory)
- return;
+ if (CTimer::GetFrameCounter() + m_randomSeed % 32 == 0)
+ PruneReferences();
int alpha = CVisibilityPlugins::GetClumpAlpha(GetClump());
if (!bFadeOut) {
@@ -1756,18 +1766,16 @@ CPed::ProcessControl(void)
CVisibilityPlugins::SetClumpAlpha(GetClump(), alpha);
bIsShooting = false;
+ bDonePositionOutOfCollision = false;
BuildPedLists();
bIsInWater = false;
+ bIsDrowning = false;
ProcessBuoyancy();
if (m_nPedState != PED_ARRESTED) {
if (m_nPedState == PED_DEAD) {
DeadPedMakesTyresBloody();
-#ifndef VC_PED_PORTS
- if (CGame::nastyGame) {
-#else
if (CGame::nastyGame && !bIsInWater) {
-#endif
uint32 remainingBloodyFpTime = CTimer::GetTimeInMilliseconds() - m_bloodyFootprintCountOrDeathTime;
float timeDependentDist;
if (remainingBloodyFpTime >= 2000) {
@@ -1790,6 +1798,7 @@ CPed::ProcessControl(void)
if (!nearPed->bIsLooking && nearPed->m_nPedState != PED_ATTACK) {
int16 camMode = TheCamera.Cams[TheCamera.ActiveCam].Mode;
if (camMode != CCam::MODE_SNIPER
+ && camMode != CCam::MODE_CAMERA
&& camMode != CCam::MODE_ROCKETLAUNCHER
&& camMode != CCam::MODE_M16_1STPERSON
&& camMode != CCam::MODE_1STPERSON
@@ -1825,13 +1834,11 @@ CPed::ProcessControl(void)
if (ServiceTalkingWhenDead())
ServiceTalking();
-#ifdef VC_PED_PORTS
if (bIsInWater) {
bIsStanding = false;
bWasStanding = false;
CPhysical::ProcessControl();
}
-#endif
return;
}
@@ -1852,16 +1859,15 @@ CPed::ProcessControl(void)
++m_panicCounter;
if (m_fHealth <= 1.0f && m_nPedState <= PED_STATES_NO_AI && !bIsInTheAir && !bIsLanding)
- SetDie(ANIM_STD_KO_FRONT, 4.0f, 0.0f);
+ SetDie();
+
+ if (bIsStanding)
+ bPushedAlongByCar = false;
bCollidedWithMyVehicle = false;
CEntity *collidingEnt = m_pDamageEntity;
-#ifndef VC_PED_PORTS
- if (!bUsesCollision || m_fDamageImpulse <= 0.0f || m_nPedState == PED_DIE || !collidingEnt) {
-#else
- if (!bUsesCollision || ((!collidingEnt || m_fDamageImpulse <= 0.0f) && (!IsPlayer() || !bIsStuck)) || m_nPedState == PED_DIE) {
-#endif
+ if (!bUsesCollision || ((!collidingEnt || m_fDamageImpulse <= 0.0f) && (!IsPlayer() || !bIsStuck)) || m_nPedState == PED_DIE) {
bHitSomethingLastFrame = false;
if (m_nPedStateTimer <= 500 && bIsInTheAir) {
if (m_nPedStateTimer)
@@ -1869,7 +1875,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
@@ -1880,11 +1886,7 @@ CPed::ProcessControl(void)
}
*/
-#ifndef VC_PED_PORTS
- } else {
-#else
} else if (collidingEnt) {
-#endif
switch (collidingEnt->GetType())
{
case ENTITY_TYPE_BUILDING:
@@ -1919,6 +1921,13 @@ CPed::ProcessControl(void)
float oldDestRot = CGeneral::LimitRadianAngle(m_fRotationDest);
+ if (m_nPedState == PED_FOLLOW_PATH) {
+ if (DotProduct(m_vecDamageNormal, GetForward()) < -0.866f && CanPedJumpThis(collidingEnt, &m_vecDamageNormal)) {
+ SetJump();
+ }
+ break;
+ }
+
if (m_pedInObjective &&
(m_objective == OBJECTIVE_GOTO_CHAR_ON_FOOT || m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT)) {
@@ -1927,6 +1936,9 @@ CPed::ProcessControl(void)
if (CanPedJumpThis(collidingEnt)) {
SetJump();
} else if (m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT) {
+ if (m_nPedType == PEDTYPE_COP && m_nWaitState != WAITSTATE_LOOK_ABOUT)
+ ((CCopPed*)this)->field_624++;
+
SetWaitState(WAITSTATE_LOOK_ABOUT, nil);
} else {
SetWaitState(WAITSTATE_PLAYANIM_TAXI, nil);
@@ -1936,6 +1948,9 @@ CPed::ProcessControl(void)
Say(SOUND_PED_TAXI_CALL);
}
} else {
+ if (m_pLookTarget)
+ m_pLookTarget->CleanUpOldReference(&m_pLookTarget);
+
m_pLookTarget = m_pedInObjective;
m_pLookTarget->RegisterReference((CEntity **) &m_pLookTarget);
TurnBody();
@@ -1965,10 +1980,10 @@ CPed::ProcessControl(void)
m_collidingEntityWhileFleeing = collidingEnt;
m_collidingEntityWhileFleeing->RegisterReference((CEntity **) &m_collidingEntityWhileFleeing);
- uint8 currentDir = Floor((PI + m_fRotationCur) / DEGTORAD(45.0f));
- uint8 nextDir;
- ThePaths.FindNextNodeWandering(PATH_PED, GetPosition(), &m_pLastPathNode, &m_pNextPathNode, currentDir, &nextDir);
-
+ if (m_nWaitState != WAITSTATE_HITWALL)
+ SetWaitState(WAITSTATE_TURN180, nil);
+ m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 5000;
+ Flee();
} else {
if (neededTurn < DEGTORAD(60.0f)) {
CVector posToHead = m_vecDamageNormal * 4.0f;
@@ -1982,9 +1997,17 @@ CPed::ProcessControl(void)
if (m_nPedState != PED_SEEK_POS && m_nPedState != PED_SEEK_CAR) {
if (m_nPedState == PED_WANDER_PATH) {
m_pNextPathNode = &ThePaths.m_pathNodes[closestNodeId];
+ CVector bestCoords = CPathFind::TakeWidthIntoAccountForWandering(m_pNextPathNode, m_randomSeed);
+ angleToFace = CGeneral::GetRadianAngleBetweenPoints(
+ bestCoords.x, bestCoords.y,
+ GetPosition().x, GetPosition().y);
+
+ } else if (m_nPedState == PED_FOLLOW_PATH) {
+ CVector bestCoords = m_pathNodesToGo[m_nCurPathNodeId]->GetPosition();
angleToFace = CGeneral::GetRadianAngleBetweenPoints(
- m_pNextPathNode->GetX(), m_pNextPathNode->GetY(),
+ bestCoords.x, bestCoords.y,
GetPosition().x, GetPosition().y);
+
} else {
if (ThePaths.m_pathNodes[closestNodeId].GetX() == 0.0f
|| ThePaths.m_pathNodes[closestNodeId].GetY() == 0.0f) {
@@ -1994,6 +2017,7 @@ CPed::ProcessControl(void)
} else {
posToHead.x = ThePaths.m_pathNodes[closestNodeId].GetX();
posToHead.y = ThePaths.m_pathNodes[closestNodeId].GetY();
+ posToHead.z = ThePaths.m_pathNodes[closestNodeId].GetZ();
}
angleToFace = CGeneral::GetRadianAngleBetweenPoints(
posToHead.x, posToHead.y,
@@ -2090,7 +2114,7 @@ CPed::ProcessControl(void)
if (collidingVeh == m_pMyVehicle)
bCollidedWithMyVehicle = true;
-#ifdef VC_PED_PORTS
+
float oldHealth = m_fHealth;
bool playerSufferSound = false;
@@ -2099,23 +2123,30 @@ CPed::ProcessControl(void)
&& (!IsPlayer()
|| m_objective == OBJECTIVE_GOTO_AREA_ON_FOOT
|| m_objective == OBJECTIVE_RUN_TO_AREA
- || m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER)) {
+ || m_objective == OBJECTIVE_SPRINT_TO_AREA
+ || m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER
+ || IsUseAttractorObjective(m_objective))) {
if (collidingVeh != m_pCurrentPhysSurface || IsPlayer()) {
if (!bVehEnterDoorIsBlocked) {
if (collidingVeh->GetStatus() != STATUS_PLAYER || CharCreatedBy == MISSION_CHAR) {
- // VC calls SetDirectionToWalkAroundVehicle instead if ped is in PED_SEEK_CAR.
- SetDirectionToWalkAroundObject(collidingVeh);
- CWorld::Players[CWorld::PlayerInFocus].m_nLastBumpPlayerCarTimer = m_nPedStateTimer;
+ if (m_nPedState == PED_SEEK_CAR) {
+ SetDirectionToWalkAroundObject(collidingVeh);
+ CWorld::Players[CWorld::PlayerInFocus].m_nLastBumpPlayerCarTimer = m_nPedStateTimer;
+ } else {
+ SetDirectionToWalkAroundVehicle(collidingVeh);
+ }
} else {
if (CTimer::GetTimeInMilliseconds() >= CWorld::Players[CWorld::PlayerInFocus].m_nLastBumpPlayerCarTimer
|| m_nPedStateTimer >= CTimer::GetTimeInMilliseconds()) {
- // VC calls SetDirectionToWalkAroundVehicle instead if ped is in PED_SEEK_CAR.
- SetDirectionToWalkAroundObject(collidingVeh);
- CWorld::Players[CWorld::PlayerInFocus].m_nLastBumpPlayerCarTimer = m_nPedStateTimer;
-
+ if (m_nPedState == PED_SEEK_CAR) {
+ SetDirectionToWalkAroundObject(collidingVeh);
+ CWorld::Players[CWorld::PlayerInFocus].m_nLastBumpPlayerCarTimer = m_nPedStateTimer;
+ } else {
+ SetDirectionToWalkAroundVehicle(collidingVeh);
+ }
} else if (m_fleeFrom != collidingVeh) {
SetFlee(collidingVeh, 4000);
bUsePedNodeSeek = false;
@@ -2139,10 +2170,11 @@ CPed::ProcessControl(void)
SetLookTimer(1300);
eWeaponType weaponType = GetWeapon()->m_eWeaponType;
+ uint32 weaponSlot = CWeaponInfo::GetWeaponInfo(weaponType)->m_nWeaponSlot;
if (weaponType == WEAPONTYPE_UNARMED
- || weaponType == WEAPONTYPE_BASEBALLBAT
- || weaponType == WEAPONTYPE_COLT45
- || weaponType == WEAPONTYPE_UZI) {
+ || weaponSlot == 3
+ || weaponSlot == 5
+ || weaponSlot == 1) {
bShakeFist = true;
}
} else {
@@ -2176,7 +2208,7 @@ CPed::ProcessControl(void)
Say(SOUND_PED_DAMAGE);
}
- CColModel* collidingCol = CModelInfo::GetModelInfo(collidingVeh->m_modelIndex)->GetColModel();
+ CColModel *collidingCol = CModelInfo::GetColModel(collidingVeh->m_modelIndex);
CVector colMinVec = collidingCol->boundingBox.min;
CVector colMaxVec = collidingCol->boundingBox.max;
@@ -2248,142 +2280,12 @@ CPed::ProcessControl(void)
KillPedWithCar(collidingVeh, m_fDamageImpulse);
}
- /* VC specific
if (m_pCollidingEntity != collidingEnt)
bPushedAlongByCar = true;
- */
}
if (m_fHealth < oldHealth && playerSufferSound)
Say(SOUND_PED_HIT);
-#else
- if (collidingVehSpeedSqr <= 1.0f / 400.0f) {
- if (!IsPedInControl()
- || IsPlayer()
- && m_objective != OBJECTIVE_GOTO_AREA_ON_FOOT
- && m_objective != OBJECTIVE_ENTER_CAR_AS_DRIVER
- && m_objective != OBJECTIVE_RUN_TO_AREA) {
-
- if (IsPlayer() && !bIsInTheAir) {
-
- if (IsPedInControl()
- && ((CPlayerPed*)this)->m_fMoveSpeed == 0.0f
- && !bIsLooking
- && CTimer::GetTimeInMilliseconds() > m_lookTimer
- && collidingVeh->pDriver) {
-
- ((CPlayerPed*)this)->AnnoyPlayerPed(false);
- SetLookFlag(collidingVeh, true);
- SetLookTimer(1300);
-
- eWeaponType weaponType = GetWeapon()->m_eWeaponType;
- if (weaponType == WEAPONTYPE_UNARMED
- || weaponType == WEAPONTYPE_BASEBALLBAT
- || weaponType == WEAPONTYPE_COLT45
- || weaponType == WEAPONTYPE_UZI) {
- bShakeFist = true;
- }
- } else {
- SetLookFlag(collidingVeh, true);
- SetLookTimer(500);
- }
- }
-
- } else if (!bVehEnterDoorIsBlocked) {
- if (collidingVeh->GetStatus() != STATUS_PLAYER || CharCreatedBy == MISSION_CHAR) {
- SetDirectionToWalkAroundObject(collidingVeh);
-
- } else if (CTimer::GetTimeInMilliseconds() >= CWorld::Players[CWorld::PlayerInFocus].m_nLastBumpPlayerCarTimer
- || m_nPedStateTimer >= CTimer::GetTimeInMilliseconds()) {
-
- SetDirectionToWalkAroundObject(collidingVeh);
- CWorld::Players[CWorld::PlayerInFocus].m_nLastBumpPlayerCarTimer = m_nPedStateTimer;
-
- } else if (m_fleeFrom != collidingVeh) {
- SetFlee(collidingVeh, 4000);
- bUsePedNodeSeek = false;
- SetMoveState(PEDMOVE_WALK);
- }
- }
- } else {
- DMAudio.PlayOneShot(collidingVeh->m_audioEntityId, SOUND_CAR_PED_COLLISION, m_fDamageImpulse);
- if (IsPlayer()) {
- CColModel *collidingCol = CModelInfo::GetColModel(collidingVeh->GetModelIndex());
- CVector colMinVec = collidingCol->boundingBox.min;
- CVector colMaxVec = collidingCol->boundingBox.max;
-
- CVector vehColCenterDist = collidingVeh->GetMatrix() * ((colMinVec + colMaxVec) * 0.5f) - GetPosition();
-
- // TLVC = To look vehicle center
-
- float angleToVehFront = collidingVeh->GetForward().Heading();
- float angleDiffFromLookingFrontTLVC = angleToVehFront - vehColCenterDist.Heading();
- angleDiffFromLookingFrontTLVC = CGeneral::LimitRadianAngle(angleDiffFromLookingFrontTLVC);
-
- // I don't know why do we use that
- float vehTopRightHeading = Atan2(colMaxVec.x - colMinVec.x, colMaxVec.y - colMinVec.y);
-
- CVector vehDist = GetPosition() - collidingVeh->GetPosition();
- vehDist.Normalise();
-
- float vehRightVecAndSpeedDotProd;
-
- if (Abs(angleDiffFromLookingFrontTLVC) >= vehTopRightHeading && Abs(angleDiffFromLookingFrontTLVC) < PI - vehTopRightHeading) {
- if (angleDiffFromLookingFrontTLVC <= 0.0f) {
- vehRightVecAndSpeedDotProd = DotProduct(collidingVeh->GetRight(), collidingVeh->m_vecMoveSpeed);
-
- // vehRightVecAndSpeedDotProd < 0.1f = Vehicle being overturned or spinning to it's right?
- if (collidingVehSpeedSqr > 1.0f / 100.0f && vehRightVecAndSpeedDotProd < 0.1f) {
-
- // Car's right faces towards us and isn't coming directly to us
- if (DotProduct(collidingVeh->GetRight(), GetForward()) < 0.0f
- && DotProduct(vehDist, collidingVeh->m_vecMoveSpeed) > 0.0f) {
- SetEvasiveStep(collidingVeh, 1);
- }
- }
- } else {
- vehRightVecAndSpeedDotProd = DotProduct(-1.0f * collidingVeh->GetRight(), collidingVeh->m_vecMoveSpeed);
-
- if (collidingVehSpeedSqr > 1.0f / 100.0f && vehRightVecAndSpeedDotProd < 0.1f) {
- if (DotProduct(collidingVeh->GetRight(), GetForward()) > 0.0f
- && DotProduct(vehDist, collidingVeh->m_vecMoveSpeed) > 0.0f) {
- SetEvasiveStep(collidingVeh, 1);
- }
- }
- }
- } else {
- vehRightVecAndSpeedDotProd = DotProduct(vehDist, collidingVeh->m_vecMoveSpeed);
- }
-
- if (vehRightVecAndSpeedDotProd <= 0.1f) {
- if (m_nPedState != PED_FIGHT) {
- SetLookFlag(collidingVeh, true);
- SetLookTimer(700);
- }
- } else {
- bIsStanding = false;
- CVector2D collidingEntMoveDir = -collidingVeh->m_vecMoveSpeed;
- int dir = GetLocalDirection(collidingEntMoveDir);
- SetFall(1000, (AnimationId)(dir + ANIM_STD_HIGHIMPACT_FRONT), false);
- CPed *driver = collidingVeh->pDriver;
-
- float damage;
- if (driver && driver->IsPlayer()) {
- damage = vehRightVecAndSpeedDotProd * 1000.0f;
- } else if (collidingVeh->GetModelIndex() == MI_TRAIN) {
- damage = 50.0f;
- } else {
- damage = 20.0f;
- }
-
- InflictDamage(collidingVeh, WEAPONTYPE_RAMMEDBYCAR, damage, PEDPIECE_TORSO, dir);
- Say(SOUND_PED_DAMAGE);
- }
- } else {
- KillPedWithCar(collidingVeh, m_fDamageImpulse);
- }
- }
-#endif
break;
}
case ENTITY_TYPE_PED:
@@ -2399,11 +2301,12 @@ CPed::ProcessControl(void)
player->AnnoyPlayerPed(false);
player->SetLookFlag(this, true);
player->SetLookTimer(1300);
- eWeaponType weapon = player->GetWeapon()->m_eWeaponType;
- if (weapon == WEAPONTYPE_UNARMED
- || weapon == WEAPONTYPE_BASEBALLBAT
- || weapon == WEAPONTYPE_COLT45
- || weapon == WEAPONTYPE_UZI) {
+ eWeaponType weaponType = player->GetWeapon()->m_eWeaponType;
+ uint32 weaponSlot = CWeaponInfo::GetWeaponInfo(weaponType)->m_nWeaponSlot;
+ if (weaponType == WEAPONTYPE_UNARMED
+ || weaponSlot == 3
+ || weaponSlot == 5
+ || weaponSlot == 1) {
player->bShakeFist = true;
}
}
@@ -2418,12 +2321,7 @@ CPed::ProcessControl(void)
}
}
CVector forceDir;
- if (!bIsInTheAir && m_nPedState != PED_JUMP
-#ifdef VC_PED_PORTS
- && m_fDamageImpulse > 0.0f
-#endif
- ) {
-
+ if (!bIsInTheAir && m_nPedState != PED_JUMP && m_fDamageImpulse > 0.0f) {
forceDir = m_vecDamageNormal;
forceDir.z = 0.0f;
if (!bIsStanding) {
@@ -2434,11 +2332,7 @@ CPed::ProcessControl(void)
ApplyMoveForce(forceDir);
}
- if ((bIsInTheAir && !DyingOrDead())
-#ifdef VC_PED_PORTS
- || (!bIsStanding && !bWasStanding && m_nPedState == PED_FALL)
-#endif
- ) {
+ if ((bIsInTheAir && !DyingOrDead()) || (!bIsStanding && !bWasStanding && m_nPedState == PED_FALL)) {
if (m_nPedStateTimer > 0 && m_nPedStateTimer <= 1000) {
forceDir = GetPosition() - m_vecHitLastPos;
} else {
@@ -2459,11 +2353,7 @@ CPed::ProcessControl(void)
if (m_nCollisionRecords == 1 && m_aCollisionRecords[0] != nil && m_aCollisionRecords[0]->IsBuilding()
&& m_nPedStateTimer > 50.0f / (2.0f * adjustedTs) && m_nPedStateTimer * 1.0f / 250.0f > Abs(forceDir.z)) {
offsetToCheck.x = -forceDir.y;
-#ifdef VC_PED_PORTS
offsetToCheck.z = 1.0f;
-#else
- offsetToCheck.z = 0.0f;
-#endif
offsetToCheck.y = forceDir.x;
offsetToCheck.Normalise();
@@ -2488,7 +2378,6 @@ CPed::ProcessControl(void)
} else {
obstacleForFlyingOtherDirZ = 501.0f;
}
-#ifdef VC_PED_PORTS
int16 flyDir = 0;
float feetZ = GetPosition().z - FEET_OFFSET;
#ifdef FIX_BUGS
@@ -2503,14 +2392,13 @@ CPed::ProcessControl(void)
flyDir = 2;
#endif
- if (flyDir > 0 && !bSomeVCflag1) {
- GetMatrix().SetTranslateOnly((flyDir == 2 ? obstacleForFlyingOtherDir.point : obstacleForFlying.point));
+ if (flyDir > 0 && !bHeadStuckInCollision) {
+ GetMatrix().SetTranslateOnly(flyDir == 2 ? obstacleForFlyingOtherDir.point : obstacleForFlying.point);
GetMatrix().GetPosition().z += FEET_OFFSET;
GetMatrix().UpdateRW();
SetLanding();
bIsStanding = true;
}
-#endif
if (obstacleForFlyingZ < obstacleForFlyingOtherDirZ) {
offsetToCheck *= -1.0f;
}
@@ -2535,12 +2423,6 @@ CPed::ProcessControl(void)
}
bIsInTheAir = false;
} else if (m_vecDamageNormal.z > 0.4f) {
-#ifndef VC_PED_PORTS
- forceDir = m_vecDamageNormal;
- forceDir.z = 0.0f;
- forceDir.Normalise();
- ApplyMoveForce(2.0f * forceDir);
-#else
if (m_nPedState == PED_JUMP) {
if (m_nWaitTimer <= 2000) {
if (m_nWaitTimer < 1000)
@@ -2557,7 +2439,6 @@ CPed::ProcessControl(void)
} else {
ApplyMoveForce(-4.0f * forceDir);
}
-#endif
}
} else if ((CTimer::GetFrameCounter() + m_randomSeed % 256 + 3) & 7) {
if (IsPlayer() && m_nPedState != PED_JUMP && pad0->JumpJustDown()) {
@@ -2613,17 +2494,12 @@ CPed::ProcessControl(void)
offsetToCheck.z += 0.5f;
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;
- GetMatrix().UpdateRW();
-#endif
SetLanding();
bIsStanding = true;
}
@@ -2644,15 +2520,15 @@ CPed::ProcessControl(void)
} else if (m_nPedState == PED_DRIVING) {
bWanderPathAfterExitingCar = true;
SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
+ bStartWanderPathOnFoot = false;
}
}
- if (!bIsStanding && m_vecMoveSpeed.z > 0.25f) {
+ if (!bIsStanding && m_vecMoveSpeed.z > 0.25) {
float airResistance = Pow(0.95f, CTimer::GetTimeStep());
m_vecMoveSpeed *= airResistance;
}
-#ifdef VC_PED_PORTS
if (IsPlayer() || !bIsStanding || m_vecMoveSpeed.x != 0.0f || m_vecMoveSpeed.y != 0.0f || m_vecMoveSpeed.z != 0.0f
|| (m_nMoveState != PEDMOVE_NONE && m_nMoveState != PEDMOVE_STILL)
|| m_vecAnimMoveDelta.x != 0.0f || m_vecAnimMoveDelta.y != 0.0f
@@ -2674,30 +2550,29 @@ CPed::ProcessControl(void)
m_vecTurnFriction = CVector(0.0f, 0.0f, 0.0f);
m_vecMoveFriction = CVector(0.0f, 0.0f, 0.0f);
}
-#else
- CPhysical::ProcessControl();
-#endif
+
if (m_nPedState != PED_DIE || bIsPedDieAnimPlaying) {
+ RequestDelayedWeapon();
+ PlayFootSteps();
if (m_nPedState != PED_DEAD) {
CalculateNewVelocity();
CalculateNewOrientation();
}
UpdatePosition();
- PlayFootSteps();
- if (IsPedInControl() && !bIsStanding && !m_pDamageEntity && CheckIfInTheAir()) {
- SetInTheAir();
-#ifdef VC_PED_PORTS
- bSomeVCflag1 = false;
-#endif
+ if (IsPedInControl() && !bIsStanding && !m_pDamageEntity) {
+ if (m_attachedTo) {
+ bIsInTheAir = false;
+ } else if (CheckIfInTheAir()) {
+ SetInTheAir();
+ bHeadStuckInCollision = false;
+ }
}
-#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();
if (!bIsAimingGun) {
if (bIsRestoringGun)
@@ -2726,14 +2601,6 @@ CPed::ProcessControl(void)
if (m_nWaitState != WAITSTATE_FALSE)
Wait();
- if (m_nPedState != PED_IDLE) {
- CAnimBlendAssociation *idleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_IDLE_BIGGUN);
- if(idleAssoc) {
- idleAssoc->blendDelta = -8.0f;
- idleAssoc->flags |= ASSOC_DELETEFADEDOUT;
- }
- }
-
#ifdef CANCELLABLE_CAR_ENTER
static bool cancelJack = false;
if (IsPlayer()) {
@@ -2785,22 +2652,27 @@ CPed::ProcessControl(void)
Look();
break;
case PED_WANDER_RANGE:
+ // III has these in here(and they were unused):
+ /*
WanderRange();
CheckAroundForPossibleCollisions();
+ */
break;
case PED_WANDER_PATH:
WanderPath();
break;
case PED_ENTER_CAR:
case PED_CARJACK:
+ {
break;
+ }
case PED_FLEE_POS:
- ms_vec2DFleePosition.x = m_fleeFromPosX;
- ms_vec2DFleePosition.y = m_fleeFromPosY;
+ ms_vec2DFleePosition = m_fleeFromPos;
Flee();
break;
case PED_FLEE_ENTITY:
if (!m_fleeFrom) {
+ bMakeFleeScream = false;
SetIdle();
break;
}
@@ -2842,6 +2714,9 @@ CPed::ProcessControl(void)
case PED_SEEK_IN_BOAT:
SeekBoatPosition();
break;
+ case PED_BUY_ICECREAM:
+ BuyIceCream();
+ break;
case PED_INVESTIGATE:
InvestigateEvent();
break;
@@ -2850,30 +2725,40 @@ CPed::ProcessControl(void)
break;
if (CTimer::GetTimeInMilliseconds() <= m_fleeTimer) {
- if (m_fleeFrom) {
- ms_vec2DFleePosition = m_fleeFrom->GetPosition();
+ if (m_pFire) {
+ if (m_fleeFrom) {
+ ms_vec2DFleePosition = m_fleeFrom->GetPosition();
+ } else {
+ ms_vec2DFleePosition = m_fleeFromPos;
+ }
+ Flee();
} else {
- ms_vec2DFleePosition.x = m_fleeFromPosX;
- ms_vec2DFleePosition.y = m_fleeFromPosY;
+ m_nLastPedState = PED_NONE;
+ SetWanderPath(0);
+ SetWaitState(WAITSTATE_FINISH_FLEE, 0);
}
- Flee();
} else {
if (m_pFire)
m_pFire->Extinguish();
}
break;
+ case PED_ANSWER_MOBILE:
+ AnswerMobile();
+ break;
case PED_FALL:
Fall();
break;
case PED_GETUP:
SetGetUp();
break;
+#ifdef GTA_TRAIN
case PED_ENTER_TRAIN:
EnterTrain();
break;
case PED_EXIT_TRAIN:
ExitTrain();
break;
+#endif
case PED_DRIVING:
{
if (!m_pMyVehicle) {
@@ -2882,129 +2767,63 @@ CPed::ProcessControl(void)
return;
}
- if (m_pMyVehicle->pDriver != this || m_pMyVehicle->IsBoat()) {
- LookForSexyPeds();
- LookForSexyCars();
- break;
- }
-
- if (m_pMyVehicle->m_vehType == VEHICLE_TYPE_BIKE || !m_pMyVehicle->pDriver->IsPlayer()) {
- break;
- }
-
- CPad* pad = CPad::GetPad(0);
-
#ifdef CAR_AIRBREAK
- if (!pad->ArePlayerControlsDisabled()) {
- if (pad->GetHorn()) {
- float c = Cos(m_fRotationCur);
- float s = Sin(m_fRotationCur);
- m_pMyVehicle->GetRight() = CVector(1.0f, 0.0f, 0.0f);
- m_pMyVehicle->GetForward() = CVector(0.0f, 1.0f, 0.0f);
- m_pMyVehicle->GetUp() = CVector(0.0f, 0.0f, 1.0f);
- if (pad->GetAccelerate()) {
- m_pMyVehicle->ApplyMoveForce(GetForward() * 30.0f);
- } else if (pad->GetBrake()) {
- m_pMyVehicle->ApplyMoveForce(-GetForward() * 30.0f);
- } else {
- int16 lr = pad->GetSteeringLeftRight();
- if (lr < 0) {
- //m_pMyVehicle->ApplyTurnForce(20.0f * -GetRight(), GetForward());
- m_pMyVehicle->ApplyMoveForce(-GetRight() * 30.0f);
- } else if (lr > 0) {
- m_pMyVehicle->ApplyMoveForce(GetRight() * 30.0f);
- } else {
- m_pMyVehicle->ApplyMoveForce(0.0f, 0.0f, 50.0f);
+ if (IsPlayer()) {
+ CPad* pad = CPad::GetPad(0);
+ if (!pad->ArePlayerControlsDisabled()) {
+ if (pad->GetHorn()) {
+ float c = Cos(m_fRotationCur);
+ float s = Sin(m_fRotationCur);
+ m_pMyVehicle->GetRight() = CVector(1.0f, 0.0f, 0.0f);
+ m_pMyVehicle->GetForward() = CVector(0.0f, 1.0f, 0.0f);
+ m_pMyVehicle->GetUp() = CVector(0.0f, 0.0f, 1.0f);
+ if (pad->GetAccelerate()) {
+ m_pMyVehicle->ApplyMoveForce(GetForward() * 30.0f);
+ }
+ else if (pad->GetBrake()) {
+ m_pMyVehicle->ApplyMoveForce(-GetForward() * 30.0f);
+ }
+ else {
+ int16 lr = pad->GetSteeringLeftRight();
+ if (lr < 0) {
+ //m_pMyVehicle->ApplyTurnForce(20.0f * -GetRight(), GetForward());
+ m_pMyVehicle->ApplyMoveForce(-GetRight() * 30.0f);
+ }
+ else if (lr > 0) {
+ m_pMyVehicle->ApplyMoveForce(GetRight() * 30.0f);
+ }
+ else {
+ m_pMyVehicle->ApplyMoveForce(0.0f, 0.0f, 50.0f);
+ }
}
}
}
}
#endif
- float steerAngle = m_pMyVehicle->m_fSteerAngle;
- CAnimBlendAssociation *lDriveAssoc;
- CAnimBlendAssociation *rDriveAssoc;
- CAnimBlendAssociation *lbAssoc;
- CAnimBlendAssociation *sitAssoc;
- if (m_pMyVehicle->bLowVehicle) {
- sitAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_SIT_LO);
-
- if (!sitAssoc || sitAssoc->blendAmount < 1.0f) {
- break;
- }
- lDriveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_DRIVE_LEFT_LO);
- lbAssoc = nil;
- rDriveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_DRIVE_RIGHT_LO);
+ if (m_pMyVehicle->pDriver == this) {
+ DriveVehicle();
+ if (!m_pMyVehicle)
+ return;
} else {
- sitAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_SIT);
-
- if (!sitAssoc || sitAssoc->blendAmount < 1.0f) {
- break;
- }
-
- lDriveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_DRIVE_LEFT);
- rDriveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_DRIVE_RIGHT);
- lbAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_LOOKBEHIND);
-
- if (lbAssoc &&
- TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON
- && TheCamera.Cams[TheCamera.ActiveCam].DirectionWasLooking == LOOKING_LEFT) {
- lbAssoc->blendDelta = -1000.0f;
- }
+ LookForSexyPeds();
+ LookForSexyCars();
}
-
- CAnimBlendAssociation *driveByAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_DRIVEBY_LEFT);
-
- if (!driveByAssoc)
- driveByAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_DRIVEBY_RIGHT);
-
- if (m_pMyVehicle->bLowVehicle || m_pMyVehicle->m_fGasPedal >= 0.0f || driveByAssoc) {
- if (steerAngle == 0.0f || driveByAssoc) {
- if (lDriveAssoc)
- lDriveAssoc->blendAmount = 0.0f;
- if (rDriveAssoc)
- rDriveAssoc->blendAmount = 0.0f;
-
- } else if (steerAngle <= 0.0f) {
- if (lDriveAssoc)
- lDriveAssoc->blendAmount = 0.0f;
-
- if (rDriveAssoc)
- rDriveAssoc->blendAmount = Clamp(steerAngle * -100.0f / 61.0f, 0.0f, 1.0f);
- else if (m_pMyVehicle->bLowVehicle)
- CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_DRIVE_RIGHT_LO);
- else
- CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_DRIVE_RIGHT);
-
- } else {
- if (rDriveAssoc)
- rDriveAssoc->blendAmount = 0.0f;
-
- if (lDriveAssoc)
- lDriveAssoc->blendAmount = Clamp(steerAngle * 100.0f / 61.0f, 0.0f, 1.0f);
- else if (m_pMyVehicle->bLowVehicle)
- CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_DRIVE_LEFT_LO);
- else
- CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_DRIVE_LEFT);
- }
-
- if (lbAssoc)
- lbAssoc->blendDelta = -4.0f;
- } else {
-
- 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_STD_CAR_LOOKBEHIND, 4.0f);
- }
+
+ if (!IsPlayer() && m_pMyVehicle->IsBoat()
+ && FindPlayerPed()->m_pCurrentPhysSurface == m_pMyVehicle
+ && (CharCreatedBy != MISSION_CHAR || !bIsPlayerFriend)) {
+ SetObjective(OBJECTIVE_KILL_CHAR_ON_BOAT, FindPlayerPed());
+ Say(SOUND_PED_CAR_JACKED);
}
+
break;
}
case PED_DIE:
Die();
break;
case PED_HANDS_UP:
- if (m_pedStats->m_temper <= 50) {
+ if (m_pedStats->m_flags & STAT_GUN_PANIC) {
if (!RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_HANDSCOWER)) {
CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_HANDSCOWER);
Say(SOUND_PED_HANDS_COWER);
@@ -3014,11 +2833,15 @@ CPed::ProcessControl(void)
Say(SOUND_PED_HANDS_UP);
}
break;
- default: break;
+ 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)) {
@@ -3039,9 +2862,24 @@ CPed::ProcessControl(void)
ServiceTalking();
if (bInVehicle && !m_pMyVehicle)
bInVehicle = false;
-#ifndef VC_PED_PORTS
- m_pCurrentPhysSurface = nil;
-#endif
+
+ if (bHeldHostageInCar) {
+ if (m_pMyVehicle && m_pMyVehicle->pDriver && m_pMyVehicle->pDriver->IsPlayer()) {
+ Say(SOUND_PED_FLEE_SPRINT);
+ }
+ }
+
+ if (m_delayedSoundID >= 0 && CTimer::GetTimeInMilliseconds() > m_delayedSoundTimer) {
+ Say(m_delayedSoundID);
+ m_delayedSoundID = -1;
+ m_delayedSoundTimer = 0;
+ }
+
+ if (bFannyMagnetCheat && m_nPedType == PEDTYPE_CIVFEMALE
+ && m_pedStats->m_sexiness > 40 && !m_leader) {
+ SetLeader(FindPlayerPed());
+ }
+
} else {
if (bIsStanding && (!m_pCurrentPhysSurface || IsPlayer())
|| bIsInWater || !bUsesCollision) {
@@ -3049,7 +2887,8 @@ CPed::ProcessControl(void)
}
m_pCurrentPhysSurface = nil;
}
- }
+ } else
+ ServiceTalking();
}
int32
@@ -3064,22 +2903,16 @@ CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints)
CColModel *ourCol = CModelInfo::GetColModel(GetModelIndex());
CColModel *hisCol = CModelInfo::GetColModel(collidingEnt->GetModelIndex());
- if (!bUsesCollision)
+ if (!bUsesCollision && !bJustCheckCollision)
return 0;
if (collidingEnt->IsVehicle() && ((CVehicle*)collidingEnt)->IsBoat())
collidedWithBoat = true;
// ofc we're not vehicle
- if (!m_bIsVehicleBeingShifted && !bSkipLineCol
-#ifdef VC_PED_PORTS
- && !collidingEnt->IsPed()
-#endif
- ) {
+ if (!m_bIsVehicleBeingShifted && !bSkipLineCol && !collidingEnt->IsPed()) {
if (!bCollisionProcessed) {
-#ifdef VC_PED_PORTS
m_pCurrentPhysSurface = nil;
-#endif
if (bIsStanding) {
bIsStanding = false;
bWasStanding = true;
@@ -3101,16 +2934,11 @@ 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;
-#endif
-
m_vecMoveSpeed.z = 0.0f;
bIsStanding = true;
} else {
@@ -3145,18 +2973,15 @@ 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
- if (!collidingEnt->IsPed()) {
-#endif
if (!bIsStanding
|| FEET_OFFSET + intersectionPoint.point.z > GetPosition().z
|| collidedWithBoat && 3.12f + intersectionPoint.point.z > GetPosition().z) {
@@ -3179,22 +3004,19 @@ CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints)
bOnBoat = false;
}
}
-#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_STEEP_CLIFF) {
bHitSteepSlope = true;
m_vecDamageNormal = intersectionPoint.normal;
}
}
-#ifdef VC_PED_PORTS
+
float upperSpeedLimit = 0.33f;
float lowerSpeedLimit = -0.25f;
float speed = m_vecMoveSpeed.Magnitude2D();
@@ -3203,7 +3025,7 @@ CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints)
lowerSpeedLimit *= 1.5f;
}
CAnimBlendAssociation *fallAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_FALL);
- if (!bWasStanding && ((speed > upperSpeedLimit /* ||!bPushedAlongByCar*/) || (m_vecMoveSpeed.z < lowerSpeedLimit))
+ if (!bWasStanding && ((speed > upperSpeedLimit && !bPushedAlongByCar) || (m_vecMoveSpeed.z < lowerSpeedLimit))
&& m_pCollidingEntity != collidingEnt) {
float damage = 100.0f * Max(speed - 0.25f, 0.0f);
@@ -3216,6 +3038,8 @@ CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints)
CVector2D offset = -m_vecMoveSpeed;
dir = GetLocalDirection(offset);
}
+ if (CSurfaceTable::IsSoftLanding(intersectionPoint.surfaceB))
+ damage *= 0.5f;
InflictDamage(collidingEnt, WEAPONTYPE_FALL, damage, PEDPIECE_TORSO, dir);
if (IsPlayer() && damage2 > 5.0f)
@@ -3224,31 +3048,8 @@ CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints)
} else if (!bWasStanding && fallAnim && -0.016f * CTimer::GetTimeStep() > m_vecMoveSpeed.z) {
InflictDamage(collidingEnt, WEAPONTYPE_FALL, 15.0f, PEDPIECE_TORSO, 2);
}
-#else
- float speedSqr = 0.0f;
- CAnimBlendAssociation *fallAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_FALL);
- if (!bWasStanding && (m_vecMoveSpeed.z < -0.25f || (speedSqr = m_vecMoveSpeed.MagnitudeSqr()) > sq(0.5f))) {
- if (speedSqr == 0.0f)
- speedSqr = sq(m_vecMoveSpeed.z);
-
- uint8 dir = 2; // from backward
- if (m_vecMoveSpeed.x > 0.01f || m_vecMoveSpeed.x < -0.01f || m_vecMoveSpeed.y > 0.01f || m_vecMoveSpeed.y < -0.01f) {
- CVector2D offset = -m_vecMoveSpeed;
- dir = GetLocalDirection(offset);
- }
- InflictDamage(collidingEnt, WEAPONTYPE_FALL, 350.0f * sq(speedSqr), PEDPIECE_TORSO, dir);
-
- } else if (!bWasStanding && fallAnim && -0.016f * CTimer::GetTimeStep() > m_vecMoveSpeed.z) {
- InflictDamage(collidingEnt, WEAPONTYPE_FALL, 15.0f, PEDPIECE_TORSO, 2);
- }
-#endif
m_vecMoveSpeed.z = 0.0f;
bIsStanding = true;
-#ifndef VC_PED_PORTS
- } else {
- bOnBoat = false;
- }
-#endif
} else {
bOnBoat = false;
}
@@ -3267,29 +3068,24 @@ CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints)
}
}
if (collidingEnt->IsBuilding() || collidingEnt->GetIsStatic()) {
-
if (bWasStanding) {
CVector sphereNormal;
float normalLength;
for(int sphere = 0; sphere < ourCollidedSpheres; sphere++) {
sphereNormal = collidingPoints[sphere].normal;
-#ifdef VC_PED_PORTS
if (sphereNormal.z >= -1.0f || !IsPlayer()) {
-#endif
normalLength = sphereNormal.Magnitude2D();
if (normalLength != 0.0f) {
sphereNormal.x = sphereNormal.x / normalLength;
sphereNormal.y = sphereNormal.y / normalLength;
}
-#ifdef VC_PED_PORTS
} else {
float speed = m_vecMoveSpeed.Magnitude2D();
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_STEEP_CLIFF)
@@ -3303,7 +3099,6 @@ CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints)
static void
particleProduceFootSplash(CPed *ped, CVector const &pos, float size, int times)
{
-#ifdef PC_PARTICLE
for (int i = 0; i < times; i++) {
CVector adjustedPos = pos;
adjustedPos.x += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f);
@@ -3312,16 +3107,6 @@ particleProduceFootSplash(CPed *ped, CVector const &pos, float size, int times)
CVector direction = ped->GetForward() * -0.05f;
CParticle::AddParticle(PARTICLE_RAIN_SPLASHUP, adjustedPos, direction, nil, size, CRGBA(32, 32, 32, 32), 0, 0, CGeneral::GetRandomNumber() & 1, 200);
}
-#else
- for ( int32 i = 0; i < times; i++ )
- {
- CVector adjustedPos = pos;
- adjustedPos.x += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f);
- adjustedPos.y += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f);
-
- CParticle::AddParticle(PARTICLE_RAIN_SPLASHUP, adjustedPos, CVector(0.0f, 0.0f, 0.0f), nil, size, CRGBA(0, 0, 0, 0), 0, 0, CGeneral::GetRandomNumber() & 1, 200);
- }
-#endif
}
static void
@@ -3333,10 +3118,15 @@ particleProduceFootDust(CPed *ped, CVector const &pos, float size, int times)
case SURFACE_GRAVEL:
case SURFACE_PAVEMENT:
case SURFACE_SAND:
+ case SURFACE_SAND_BEACH:
+ case SURFACE_CONCRETE_BEACH:
for (int i = 0; i < times; ++i) {
CVector adjustedPos = pos;
adjustedPos.x += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f);
adjustedPos.y += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f);
+ // ??
+ CGeneral::GetRandomNumber();
+ CGeneral::GetRandomNumber();
CParticle::AddParticle(PARTICLE_PEDFOOT_DUST, adjustedPos, CVector(0.0f, 0.0f, 0.0f), nil, size, CRGBA(0, 0, 0, 0), 0, 0, 0, 0);
}
break;
@@ -3348,6 +3138,14 @@ particleProduceFootDust(CPed *ped, CVector const &pos, float size, int times)
void
CPed::PlayFootSteps(void)
{
+ CAnimBlendAssociation *assoc = RpAnimBlendClumpGetFirstAssociation(GetClump());
+ CAnimBlendAssociation *walkRunAssoc = nil;
+ float walkRunAssocBlend = 0.0f, idleAssocBlend = 0.0f;
+ bool isSkater = m_pedStats == CPedStats::ms_apPedStats[PEDSTAT_SKATER];
+
+ CVector footPosL(0.0f, 0.0f, 0.0f), footPosR(0.0f, 0.0f, 0.0f);
+ bool footPosLok = false, footPosRok = false;
+
if (bDoBloodyFootprints) {
if (m_bloodyFootprintCountOrDeathTime > 0 && m_bloodyFootprintCountOrDeathTime < 300) {
m_bloodyFootprintCountOrDeathTime--;
@@ -3360,10 +3158,6 @@ CPed::PlayFootSteps(void)
if (!bIsStanding)
return;
- CAnimBlendAssociation *assoc = RpAnimBlendClumpGetFirstAssociation(GetClump());
- CAnimBlendAssociation *walkRunAssoc = nil;
- float walkRunAssocBlend = 0.0f, idleAssocBlend = 0.0f;
-
for (; assoc; assoc = RpAnimBlendGetNextAssociation(assoc)) {
if (assoc->flags & ASSOC_WALK) {
walkRunAssoc = assoc;
@@ -3373,96 +3167,200 @@ CPed::PlayFootSteps(void)
}
}
-#ifdef GTA_PS2_STUFF
- CAnimBlendAssociation *runStopAsoc = NULL;
-
- if ( IsPlayer() )
- {
- runStopAsoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_RUNSTOP2);
-
- if ( runStopAsoc == NULL )
- runStopAsoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_RUNSTOP2);
- }
-
- if ( runStopAsoc != NULL && runStopAsoc->blendAmount > 0.1f )
- {
- {
- CVector pos(0.0f, 0.0f, 0.0f);
- TransformToNode(pos, PED_FOOTL);
-
- pos.z -= 0.1f;
- pos += GetForward()*0.2f;
- particleProduceFootDust(this, pos, 0.02f, 1);
- }
-
- {
- CVector pos(0.0f, 0.0f, 0.0f);
- TransformToNode(pos, PED_FOOTR);
-
- pos.z -= 0.1f;
- pos += GetForward()*0.2f;
- particleProduceFootDust(this, pos, 0.02f, 1);
- }
- }
-#endif
-
-
if (walkRunAssoc && walkRunAssocBlend > 0.5f && idleAssocBlend < 1.0f) {
- float stepStart = 1 / 15.0f;
+
+ float stepStart = 1.f / 15.f;
float stepEnd = walkRunAssoc->hierarchy->totalLength / 2.0f + stepStart;
float currentTime = walkRunAssoc->currentTime;
- int stepPart = 0;
- if (currentTime >= stepStart && currentTime - walkRunAssoc->timeStep < stepStart)
- stepPart = 1;
- else if (currentTime >= stepEnd && currentTime - walkRunAssoc->timeStep < stepEnd)
- stepPart = 2;
+ if (isSkater) {
+ // both are unused
+ static float stepStartSection = 1.0f;
+ static float animSections = 15.f;
- if (stepPart != 0) {
- DMAudio.PlayOneShot(m_audioEntityId, stepPart == 1 ? SOUND_STEP_START : SOUND_STEP_END, 1.0f);
- CVector footPos(0.0f, 0.0f, 0.0f);
- TransformToNode(footPos, stepPart == 1 ? PED_FOOTL : PED_FOOTR);
+ float moveStart, soundVolume, skateTime;
+ if (walkRunAssoc->animId == ANIM_STD_WALK) {
+ moveStart = 0.0f;
+ skateTime = 8.f / 15.f;
+ } else {
+ moveStart = 0.0f;
+ skateTime = 5.f / 15.f;
+ }
+ switch (CSurfaceTable::GetAdhesionGroup(m_nSurfaceTouched)) {
+ case ADHESIVE_LOOSE:
+ if (CGeneral::GetRandomNumber() % 128) {
+ m_vecAnimMoveDelta *= 0.5f;
+ } else {
+ SetFall(0, ANIM_STD_HIGHIMPACT_BACK, false);
+ }
+ soundVolume = 0.5f;
+ break;
+ case ADHESIVE_SAND:
+ if (CGeneral::GetRandomNumber() % 64) {
+ m_vecAnimMoveDelta *= 0.2f;
+ } else {
+ SetFall(0, ANIM_STD_HIGHIMPACT_BACK, false);
+ }
+ soundVolume = 0.2f;
+ break;
+ case ADHESIVE_WET:
+ m_vecAnimMoveDelta *= 0.3f;
+ soundVolume = 0.2f;
+ break;
+ default:
+ soundVolume = 1.f;
+ break;
+ }
+ if (soundVolume > 0.2f && currentTime > moveStart && currentTime - walkRunAssoc->timeStep <= moveStart) {
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_SKATING, ((int)(127.f * soundVolume) | (walkRunAssoc->animId << 8)));
+ } else if (soundVolume > 0.2f) {
+ if (currentTime > skateTime && currentTime - walkRunAssoc->timeStep <= skateTime) {
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_SKATING, ((int)(127.f * soundVolume) | (walkRunAssoc->animId << 8)));
+ }
+ }
+
+ } else {
+ int stepPart = 0;
+
+ // This section is shortened/optimized for sanity.
+
+ if (currentTime >= stepStart && currentTime - walkRunAssoc->timeStep < stepStart)
+ stepPart = 1;
+ else if (currentTime >= stepEnd && currentTime - walkRunAssoc->timeStep < stepEnd)
+ stepPart = 2;
+
+ if (stepPart != 0) {
+ CVector adjustedFootPos;
+ if (stepPart == 1) {
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_STEP_START, 1.0f);
+ TransformToNode(footPosL, PED_FOOTL);
+ footPosLok = true;
+ adjustedFootPos = footPosL;
+ } else {
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_STEP_END, 1.0f);
+ TransformToNode(footPosR, PED_FOOTR);
+ footPosRok = true;
+ adjustedFootPos = footPosR;
+ }
- CVector forward = GetForward();
+ CVector forward = GetForward();
- footPos.z -= 0.1f;
- footPos += 0.2f * forward;
+ adjustedFootPos.z -= 0.1f;
+ adjustedFootPos += 0.2f * forward;
- if (bDoBloodyFootprints) {
- CVector2D top(forward * 0.26f);
+ if (bDoBloodyFootprints) {
+ CVector2D top(forward * 0.26f);
+ CVector2D right(GetRight() * (stepPart == 1 ? 0.14f : 0.1f));
+
+ CShadows::AddPermanentShadow(SHADOWTYPE_DARK, gpBloodPoolTex, &adjustedFootPos,
+ top.x, top.y,
+ right.x, right.y,
+ 255, 255, 0, 0, 4.0f, 3000, 1.0f);
+
+ if (m_bloodyFootprintCountOrDeathTime <= 20) {
+ m_bloodyFootprintCountOrDeathTime = 0;
+ bDoBloodyFootprints = false;
+ } else {
+ m_bloodyFootprintCountOrDeathTime -= 20;
+ }
+ }
+ if (m_nSurfaceTouched == SURFACE_SAND || m_nSurfaceTouched == SURFACE_SAND_BEACH) {
+ CVector2D top(forward * -0.26f);
+ CVector2D right(GetRight() * (stepPart == 1 ? 0.1f : 0.14f));
+
+ CShadows::AddPermanentShadow(SHADOWTYPE_DARK, gpShadowPedTex, &adjustedFootPos,
+ top.x, top.y,
+ right.x, right.y,
+ 120, 250, 250, 50, 4.0f, 5000, 1.0f);
+ }
+ if (CWeather::Rain <= 0.1f || CCullZones::CamNoRain() || CCullZones::PlayerNoRain()) {
+ if (IsPlayer())
+ particleProduceFootDust(this, adjustedFootPos, 0.0f, 4);
+
+ } else if (stepPart == 2) {
+ particleProduceFootSplash(this, adjustedFootPos, 0.15f, 4);
+ }
+ }
+ }
+ }
+
+ if (IsPlayer() && !walkRunAssoc && bIsLanding) {
+ if (!footPosLok)
+ TransformToNode(footPosL, PED_FOOTL);
+
+ CVector forward = GetForward();
+
+ CVector adjustedFootPosL = footPosL;
+ adjustedFootPosL.z -= 0.1f;
+ adjustedFootPosL += 0.2f * forward;
+ if (bDoBloodyFootprints) {
+ CVector2D top(forward * 0.26f);
+ CVector2D right(GetRight() * 0.14f);
+
+ CShadows::AddPermanentShadow(SHADOWTYPE_DARK, gpBloodPoolTex, &adjustedFootPosL,
+ top.x, top.y,
+ right.x, right.y,
+ 255, 255, 0, 0, 4.0f, 3000, 1.0f);
+
+ if (m_bloodyFootprintCountOrDeathTime <= 20) {
+ m_bloodyFootprintCountOrDeathTime = 0;
+ bDoBloodyFootprints = false;
+ }
+ else {
+ m_bloodyFootprintCountOrDeathTime -= 20;
+ }
+ }
+ if (!isSkater) {
+ if (m_nSurfaceTouched == SURFACE_SAND || m_nSurfaceTouched == SURFACE_SAND_BEACH) {
+ CVector2D top(forward * -0.26f);
CVector2D right(GetRight() * 0.14f);
- CShadows::AddPermanentShadow(SHADOWTYPE_DARK, gpBloodPoolTex, &footPos,
+ CShadows::AddPermanentShadow(SHADOWTYPE_DARK, gpShadowPedTex, &adjustedFootPosL,
top.x, top.y,
right.x, right.y,
- 255, 255, 0, 0, 4.0f, 3000.0f, 1.0f);
-
- if (m_bloodyFootprintCountOrDeathTime <= 20) {
- m_bloodyFootprintCountOrDeathTime = 0;
- bDoBloodyFootprints = false;
- } else {
- m_bloodyFootprintCountOrDeathTime -= 20;
- }
+ 120, 250, 250, 50, 4.0f, 5000, 1.0f);
}
- if (CWeather::Rain <= 0.1f || CCullZones::CamNoRain() || CCullZones::PlayerNoRain()) {
- if(IsPlayer())
- particleProduceFootDust(this, footPos, 0.0f, 4);
+ }
+ if(!footPosRok)
+ TransformToNode(footPosR, PED_FOOTR);
+
+ CVector adjustedFootPosR = footPosR;
+ adjustedFootPosR.z -= 0.1f;
+ adjustedFootPosR += 0.2f * forward;
+
+ if (bDoBloodyFootprints) {
+ CVector2D top(forward * 0.26f);
+ CVector2D right(GetRight() * 0.1f);
+
+ CShadows::AddPermanentShadow(SHADOWTYPE_DARK, gpBloodPoolTex, &adjustedFootPosR,
+ top.x, top.y,
+ right.x, right.y,
+ 255, 255, 0, 0, 4.0f, 3000, 1.0f);
+
+ if (m_bloodyFootprintCountOrDeathTime <= 20) {
+ m_bloodyFootprintCountOrDeathTime = 0;
+ bDoBloodyFootprints = false;
+ } else {
+ m_bloodyFootprintCountOrDeathTime -= 20;
}
-#ifdef PC_PARTICLE
- else if(stepPart == 2)
-#else
- else
-#endif
- {
- particleProduceFootSplash(this, footPos, 0.15f, 4);
+ }
+ if (!isSkater) {
+ if (m_nSurfaceTouched == SURFACE_SAND || m_nSurfaceTouched == SURFACE_SAND_BEACH) {
+ CVector2D top(forward * -0.26f);
+ CVector2D right(GetRight() * 0.14f);
+
+ CShadows::AddPermanentShadow(SHADOWTYPE_DARK, gpShadowPedTex, &adjustedFootPosR,
+ top.x, top.y,
+ right.x, right.y,
+ 120, 250, 250, 50, 4.0f, 5000, 1.0f);
}
}
}
if (m_nSurfaceTouched == SURFACE_WATER) {
+ CRGBA rubberSmokeColor(255, 255, 255, 196);
float pedSpeed = CVector2D(m_vecMoveSpeed).Magnitude();
if (pedSpeed > 0.03f && CTimer::GetFrameCounter() % 2 == 0 && pedSpeed > 0.13f) {
-#ifdef PC_PARTICLE
float particleSize = pedSpeed * 2.0f;
if (particleSize < 0.25f)
@@ -3477,16 +3375,20 @@ CPed::PlayFootSteps(void)
CVector particleDir = m_vecMoveSpeed * -0.75f;
particleDir.z = CGeneral::GetRandomNumberInRange(0.01f, 0.03f);
- CParticle::AddParticle(PARTICLE_PED_SPLASH, particlePos, particleDir, nil, 0.8f * particleSize, CRGBA(155,155,185,128), 0, 0, 0, 0);
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, particlePos, particleDir, nil, 0.5f * particleSize, CRGBA(0,0,0,0), 0, 0, 0, 0);
+ CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, particlePos, particleDir, nil, particleSize, rubberSmokeColor, 0, 0, 0, 0);
+ }
- particleDir.z = CGeneral::GetRandomNumberInRange(0.03f, 0.05f);
- CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, particlePos, particleDir, nil, particleSize, CRGBA(255,255,255,255), 0, 0, 0, 0);
-#else
- CVector particlePos = (GetPosition() - 0.3f * GetUp()) + GetForward()*0.3f;
- CVector particleDir = m_vecMoveSpeed * 0.45f;
- particleDir.z = CGeneral::GetRandomNumberInRange(0.03f, 0.05f);
- CParticle::AddParticle(PARTICLE_PED_SPLASH, particlePos-CVector(0.0f, 0.0f, 1.2f), particleDir, nil, 0.0f, CRGBA(155, 185, 155, 255));
-#endif
+ if (m_nPedState == PED_JUMP) {
+ CVector particlePos = GetPosition();
+ particlePos.z -= 0.1f;
+
+ CVector particleDir(0.0f, 0.075f, 0.0f);
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, particlePos, particleDir, nil, 0.005f, CRGBA(0, 0, 0, 0), 0, 0, 0, 0);
+ particleDir.x += CGeneral::GetRandomNumberInRange(-0.05f, 0.05f);
+ particleDir.y += CGeneral::GetRandomNumberInRange(-0.05f, 0.05f);
+ particleDir.z -= CGeneral::GetRandomNumberInRange(0.025f, 0.05f);
+ CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, particlePos, particleDir, nil, 0.5f, rubberSmokeColor, 0, 0, 0, 0);
}
}
}
@@ -3506,52 +3408,12 @@ CPed::GetLocalDirection(const CVector2D &posOffset)
return direction;
}
-#ifdef NEW_WALK_AROUND_ALGORITHM
-CVector
-LocalPosForWalkAround(CVector2D colMin, CVector2D colMax, int walkAround, uint32 enterDoorNode, bool itsVan) {
- switch (walkAround) {
- case 0:
- if (enterDoorNode == CAR_DOOR_LF)
- return CVector(colMin.x, colMax.y - 1.0f, 0.0f);
- case 1:
- return CVector(colMin.x, colMax.y, 0.0f);
- case 2:
- case 3:
- if (walkAround == 3 && enterDoorNode == CAR_DOOR_RF)
- return CVector(colMax.x, colMax.y - 1.0f, 0.0f);
-
- return CVector(colMax.x, colMax.y, 0.0f);
- case 4:
- if (enterDoorNode == CAR_DOOR_RR && !itsVan)
- return CVector(colMax.x, colMin.y + 1.0f, 0.0f);
- case 5:
- return CVector(colMax.x, colMin.y, 0.0f);
- case 6:
- case 7:
- if (walkAround == 7 && enterDoorNode == CAR_DOOR_LR && !itsVan)
- return CVector(colMin.x, colMin.y + 1.0f, 0.0f);
-
- return CVector(colMin.x, colMin.y, 0.0f);
- default:
- return CVector(0.0f, 0.0f, 0.0f);
- }
-}
-
bool
-CanWeSeeTheCorner(CVector2D dist, CVector2D fwdOffset)
+CPed::SetDirectionToWalkAroundVehicle(CVehicle* veh)
{
- // because fov isn't important if dist is more then 5 unit, we want shortest way
- if (dist.Magnitude() > 5.0f)
- return true;
-
- if (DotProduct2D(dist, fwdOffset) < 0.0f)
- return false;
-
- return true;
+ return SetFollowPath(m_vecSeekPos, 0.0f, m_nMoveState, veh, m_pedInObjective, m_nMoveState == PEDMOVE_WALK ? 2000 : 250);
}
-#endif
-// This function looks completely same on VC.
void
CPed::SetDirectionToWalkAroundObject(CEntity *obj)
{
@@ -3572,13 +3434,11 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
if (m_nMoveState == PEDMOVE_NONE || m_nMoveState == PEDMOVE_STILL)
return;
-#ifndef PEDS_REPORT_CRIMES_ON_PHONE
if (CharCreatedBy != MISSION_CHAR && obj->GetModelIndex() == MI_PHONEBOOTH1) {
bool isRunning = m_nMoveState == PEDMOVE_RUN || m_nMoveState == PEDMOVE_SPRINT;
SetFindPathAndFlee(obj, 5000, !isRunning);
return;
}
-#endif
CVector2D adjustedColMin(objColMin.x - 0.35f, objColMin.y - 0.35f);
CVector2D adjustedColMax(objColMax.x + 0.35f, objColMax.y + 0.35f);
@@ -3614,11 +3474,9 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
objUpsideDown = false;
}
float oldRotDest = m_fRotationDest;
-#ifndef NEW_WALK_AROUND_ALGORITHM
float angleToFaceObjCenter = (objColCenter - GetPosition()).Heading();
float angleDiffBtwObjCenterAndForward = CGeneral::LimitRadianAngle(dirToSet - angleToFaceObjCenter);
float objTopRightHeading = Atan2(adjustedColMax.x - adjustedColMin.x, adjustedColMax.y - adjustedColMin.y);
-#endif
if (IsPlayer()) {
if (FindPlayerPed()->m_fMoveSpeed <= 0.0f)
@@ -3662,16 +3520,9 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
bool collidingThingChanged = true;
CEntity *obstacle;
-#ifndef NEW_WALK_AROUND_ALGORITHM
if (!obj->IsVehicle() || objUpsideDown) {
collidingThingChanged = false;
- } else {
-#else
- CVector cornerToGo = CVector(10.0f, 10.0f, 10.0f);
- int dirToGo;
- m_walkAroundType = 0;
- int iWouldPreferGoingBack = 0; // 1:left 2:right
-#endif
+ } else {
float adjustedCheckInterval = 0.7f * checkIntervalInDist;
CVector posToCheck;
@@ -3692,25 +3543,6 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
entityOnTopLeftOfObj = 3;
}
}
-#ifdef NEW_WALK_AROUND_ALGORITHM
- else {
- CVector tl = obj->GetMatrix() * CVector(adjustedColMin.x, adjustedColMax.y, 0.0f) - GetPosition();
- if (goingToEnterCar && (m_vehDoor == CAR_DOOR_LF || m_vehDoor == CAR_DOOR_LR)) {
- cornerToGo = tl;
- m_walkAroundType = 1;
-
- if (m_vehDoor == CAR_DOOR_LR)
- iWouldPreferGoingBack = 1;
- } else if(CanWeSeeTheCorner(tl, GetForward())){
- cornerToGo = tl;
- dirToGo = GetLocalDirection(tl);
- if (dirToGo == 1)
- m_walkAroundType = 0; // ALL of the next turns will be right turn
- else if (dirToGo == 3)
- m_walkAroundType = 1; // ALL of the next turns will be left turn
- }
- }
-#endif
// Top right of obj
posToCheck.x = adjustedColMax.x - adjustedCheckInterval;
@@ -3729,27 +3561,6 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
entityOnTopRightOfObj = 3;
}
}
-#ifdef NEW_WALK_AROUND_ALGORITHM
- else {
- CVector tr = obj->GetMatrix() * CVector(adjustedColMax.x, adjustedColMax.y, 0.0f) - GetPosition();
- if (tr.Magnitude2D() < cornerToGo.Magnitude2D()) {
- if (goingToEnterCar && (m_vehDoor == CAR_DOOR_RF || m_vehDoor == CAR_DOOR_RR)) {
- cornerToGo = tr;
- m_walkAroundType = 2;
-
- if (m_vehDoor == CAR_DOOR_RR)
- iWouldPreferGoingBack = 2;
- } else if (CanWeSeeTheCorner(tr, GetForward())) {
- cornerToGo = tr;
- dirToGo = GetLocalDirection(tr);
- if (dirToGo == 1)
- m_walkAroundType = 2; // ALL of the next turns will be right turn
- else if (dirToGo == 3)
- m_walkAroundType = 3; // ALL of the next turns will be left turn
- }
- }
- }
-#endif
// Bottom right of obj
posToCheck.x = adjustedColMax.x - adjustedCheckInterval;
@@ -3768,26 +3579,6 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
entityOnBottomRightOfObj = 3;
}
}
-#ifdef NEW_WALK_AROUND_ALGORITHM
- else {
- CVector br = obj->GetMatrix() * CVector(adjustedColMax.x, adjustedColMin.y, 0.0f) - GetPosition();
- if (iWouldPreferGoingBack == 2)
- m_walkAroundType = 4;
- else if (br.Magnitude2D() < cornerToGo.Magnitude2D()) {
- if (goingToEnterCar && (m_vehDoor == CAR_DOOR_RF || m_vehDoor == CAR_DOOR_RR)) {
- cornerToGo = br;
- m_walkAroundType = 5;
- } else if (CanWeSeeTheCorner(br, GetForward())) {
- cornerToGo = br;
- dirToGo = GetLocalDirection(br);
- if (dirToGo == 1)
- m_walkAroundType = 4; // ALL of the next turns will be right turn
- else if (dirToGo == 3)
- m_walkAroundType = 5; // ALL of the next turns will be left turn
- }
- }
- }
-#endif
// Bottom left of obj
posToCheck.x = adjustedColMin.x + adjustedCheckInterval;
@@ -3806,26 +3597,55 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
entityOnBottomLeftOfObj = 3;
}
}
-#ifdef NEW_WALK_AROUND_ALGORITHM
- else {
- CVector bl = obj->GetMatrix() * CVector(adjustedColMin.x, adjustedColMin.y, 0.0f) - GetPosition();
- if (iWouldPreferGoingBack == 1)
- m_walkAroundType = 7;
- else if (bl.Magnitude2D() < cornerToGo.Magnitude2D()) {
- if (goingToEnterCar && (m_vehDoor == CAR_DOOR_LF || m_vehDoor == CAR_DOOR_LR)) {
- cornerToGo = bl;
- m_walkAroundType = 6;
- } else if (CanWeSeeTheCorner(bl, GetForward())) {
- cornerToGo = bl;
- dirToGo = GetLocalDirection(bl);
- if (dirToGo == 1)
- m_walkAroundType = 6; // ALL of the next turns will be right turn
- else if (dirToGo == 3)
- m_walkAroundType = 7; // ALL of the next turns will be left turn
- }
+ }
+
+ if (!entityOnTopLeftOfObj && !entityOnTopRightOfObj) {
+ CVector topLeftCorner(adjustedColMin.x - 0.3f, adjustedColMax.y + 0.3f, 0.0f);
+ topLeftCorner = objMat * topLeftCorner;
+ CVector topRightCorner(adjustedColMax.x + 0.3f, adjustedColMax.y + 0.3f, 0.0f);
+ topRightCorner = objMat * topRightCorner;
+ CColPoint foundCol;
+ CEntity *foundEnt;
+ if (CWorld::ProcessLineOfSight(topLeftCorner, topRightCorner, foundCol, foundEnt, true, true, false, true, false, false, false, false)) {
+ switch (foundEnt->GetType()) {
+ case ENTITY_TYPE_VEHICLE:
+ entityOnTopRightOfObj = 2;
+ entityOnTopLeftOfObj = 2;
+ break;
+ case ENTITY_TYPE_BUILDING:
+ entityOnTopRightOfObj = 1;
+ entityOnTopLeftOfObj = 1;
+ break;
+ case ENTITY_TYPE_OBJECT:
+ entityOnTopRightOfObj = 3;
+ entityOnTopLeftOfObj = 3;
+ break;
+ }
+ }
+ }
+ if (!entityOnBottomRightOfObj && !entityOnBottomLeftOfObj) {
+ CVector bottomRightCorner(adjustedColMax.x + 0.3f, adjustedColMin.y - 0.3f, 0.0f);
+ bottomRightCorner = objMat * bottomRightCorner;
+ CVector bottomLeftCorner(adjustedColMin.x - 0.3f, adjustedColMin.y - 0.3f, 0.0f);
+ bottomLeftCorner = objMat * bottomLeftCorner;
+ CColPoint foundCol;
+ CEntity* foundEnt;
+ if (CWorld::ProcessLineOfSight(bottomRightCorner, bottomLeftCorner, foundCol, foundEnt, true, true, false, true, false, false, false, false)) {
+ switch (foundEnt->GetType()) {
+ case ENTITY_TYPE_VEHICLE:
+ entityOnBottomLeftOfObj = 2;
+ entityOnBottomRightOfObj = 2;
+ break;
+ case ENTITY_TYPE_BUILDING:
+ entityOnBottomLeftOfObj = 1;
+ entityOnBottomRightOfObj = 1;
+ break;
+ case ENTITY_TYPE_OBJECT:
+ entityOnBottomLeftOfObj = 3;
+ entityOnBottomRightOfObj = 3;
+ break;
}
}
-#else
}
if (entityOnTopLeftOfObj && entityOnTopRightOfObj && entityOnBottomRightOfObj && entityOnBottomLeftOfObj) {
@@ -3897,7 +3717,6 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
m_walkAroundType = 0;
}
}
-#endif
}
m_collidingEntityWhileFleeing = obj;
m_collidingEntityWhileFleeing->RegisterReference((CEntity**) &m_collidingEntityWhileFleeing);
@@ -3907,56 +3726,6 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
CVector localPosToHead;
-#ifdef NEW_WALK_AROUND_ALGORITHM
- int nextWalkAround = m_walkAroundType;
- if (m_walkAroundType % 2 == 0) {
- nextWalkAround += 2;
- if (nextWalkAround > 6)
- nextWalkAround = 0;
- } else {
- nextWalkAround -= 2;
- if (nextWalkAround < 0)
- nextWalkAround = 7;
- }
-
- CVector nextPosToHead = objMat * LocalPosForWalkAround(adjustedColMin, adjustedColMax, nextWalkAround, goingToEnterCar ? m_vehDoor : 0, goingToEnterCarAndItsVan);
- bool nextRouteIsClear = CWorld::GetIsLineOfSightClear(GetPosition(), nextPosToHead, true, true, true, true, true, true, false);
-
- if(nextRouteIsClear)
- m_walkAroundType = nextWalkAround;
- else {
- CVector posToHead = objMat * LocalPosForWalkAround(adjustedColMin, adjustedColMax, m_walkAroundType, goingToEnterCar ? m_vehDoor : 0, goingToEnterCarAndItsVan);
- bool currentRouteIsClear = CWorld::GetIsLineOfSightClear(GetPosition(), posToHead,
- true, true, true, true, true, true, false);
-
- /* Either;
- * - Some obstacle came in and it's impossible to reach current destination
- * - We reached to the destination, but since next route is not clear, we're turning around us
- */
- if (!currentRouteIsClear ||
- ((posToHead - GetPosition()).Magnitude2D() < 0.8f &&
- !CWorld::GetIsLineOfSightClear(GetPosition() + GetForward(), nextPosToHead,
- true, true, true, true, true, true, false))) {
-
- // Change both target and direction (involves changing even/oddness)
- if (m_walkAroundType % 2 == 0) {
- m_walkAroundType -= 2;
- if (m_walkAroundType < 0)
- m_walkAroundType = 7;
- else
- m_walkAroundType += 1;
- } else {
- m_walkAroundType += 2;
- if (m_walkAroundType > 7)
- m_walkAroundType = 0;
- else
- m_walkAroundType -= 1;
- }
- }
- }
-
- localPosToHead = LocalPosForWalkAround(adjustedColMin, adjustedColMax, m_walkAroundType, goingToEnterCar ? m_vehDoor : 0, goingToEnterCarAndItsVan);
-#else
if (Abs(angleDiffBtwObjCenterAndForward) < objTopRightHeading) {
if (goingToEnterCar) {
if (goingToEnterCarAndItsVan) {
@@ -4071,7 +3840,6 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
}
}
}
-#endif
if (objUpsideDown)
localPosToHead.x = localPosToHead.x * -1.0f;
@@ -4142,7 +3910,15 @@ CPed::CanStrafeOrMouseControl(void)
return false;
#endif
return m_nPedState == PED_NONE || m_nPedState == PED_IDLE || m_nPedState == PED_FLEE_POS || m_nPedState == PED_FLEE_ENTITY ||
- m_nPedState == PED_ATTACK || m_nPedState == PED_FIGHT || m_nPedState == PED_AIM_GUN || m_nPedState == PED_JUMP;
+ m_nPedState == PED_ATTACK || m_nPedState == PED_FIGHT || m_nPedState == PED_AIM_GUN || m_nPedState == PED_JUMP || m_nPedState == PED_ANSWER_MOBILE;
+}
+
+void
+CPed::PedSetPreviousStateCB(CAnimBlendAssociation* assoc, void* arg)
+{
+ CPed* ped = (CPed*)arg;
+ ped->RestorePreviousState();
+ ped->m_pVehicleAnim = nil;
}
void
@@ -4158,12 +3934,25 @@ CPed::PedGetupCB(CAnimBlendAssociation* animAssoc, void* arg)
if (ped->m_nPedState == PED_GETUP)
ped->RestorePreviousState();
- if (ped->m_nPedState != PED_FLEE_POS && ped->m_nPedState != PED_FLEE_ENTITY)
- ped->SetMoveState(PEDMOVE_STILL);
- else
- ped->SetMoveState(PEDMOVE_RUN);
+ if (ped->bFleeWhenStanding && ped->m_threatEx) {
+ ped->SetFlee(ped->m_threatEx, 10000);
+ ped->Say(SOUND_PED_FLEE_SPRINT);
+ ped->bFleeWhenStanding = false;
+ ped->m_threatEx = nil;
+
+ } else if (ped->bGotUpOfMyOwnAccord) {
+ ped->SetObjective(OBJECTIVE_NONE);
+ ped->SetWanderPath(CGeneral::GetRandomNumberInRange(0.f, 8.f));
+ ped->bGotUpOfMyOwnAccord = false;
+
+ } else {
+ if (ped->m_nPedState != PED_FLEE_POS && ped->m_nPedState != PED_FLEE_ENTITY)
+ ped->SetMoveState(PEDMOVE_STILL);
+ else
+ ped->SetMoveState(PEDMOVE_RUN);
+ ped->SetMoveAnim();
+ }
- ped->SetMoveAnim();
ped->bGetUpAnimStarted = false;
}
@@ -4189,7 +3978,6 @@ CPed::PedStaggerCB(CAnimBlendAssociation* animAssoc, void* arg)
// nothing
*/
}
-
void
CPed::PedSetOutCarCB(CAnimBlendAssociation *animAssoc, void *arg)
{
@@ -4207,22 +3995,32 @@ CPed::PedSetOutCarCB(CAnimBlendAssociation *animAssoc, void *arg)
if (ped->m_objective == OBJECTIVE_LEAVE_CAR)
ped->RestorePreviousObjective();
-#ifdef VC_PED_PORTS
else if (ped->m_objective == OBJECTIVE_LEAVE_CAR_AND_DIE) {
ped->m_fHealth = 0.0f;
ped->SetDie(ANIM_STD_HIT_FLOOR, 4.0f, 0.5f);
}
-#endif
ped->bInVehicle = false;
- if (veh && veh->IsCar() && !veh->IsRoomForPedToLeaveCar(ped->m_vehDoor, nil)) {
- ped->PositionPedOutOfCollision();
+ if (veh && (veh->IsCar() || veh->IsBike())) {
+ CWorld::pIgnoreEntity = veh;
+ if (CWorld::TestSphereAgainstWorld(ped->GetPosition() - CVector(0.f, 0.f, 0.2f),
+ 0.4f, veh, true, true, false, false, false, false)
+ || CWorld::TestSphereAgainstWorld(ped->GetPosition() + CVector(0.f, 0.f, 0.2f),
+ 0.4f, veh, true, true, false, false, false, false)
+ || !CWorld::GetIsLineOfSightClear(veh->GetPosition(), ped->GetPosition(), true, false, false, true, false, false, false)) {
+ CWorld::pIgnoreEntity = nil;
+ ped->PositionPedOutOfCollision();
+ }
+ CWorld::pIgnoreEntity = nil;
}
if (ped->m_nPedState == PED_EXIT_CAR) {
- if (ped->m_nPedType == PEDTYPE_COP)
+ if (ped->m_nPedType == PEDTYPE_COP) {
ped->SetIdle();
- else
+ if (((CCopPed*)ped)->m_nCopType == COP_MIAMIVICE && ped->m_pMyVehicle && ped->m_pMyVehicle->pDriver == ped) {
+ DMAudio.PlayOneShot(ped->m_audioEntityId, SOUND_PED_MIAMIVICE_EXITING_CAR, 0.f);
+ }
+ } else
ped->RestorePreviousState();
veh = ped->m_pMyVehicle;
@@ -4270,22 +4068,16 @@ CPed::PedSetOutCarCB(CAnimBlendAssociation *animAssoc, void *arg)
} else if (ped->m_objective == OBJECTIVE_NONE && ped->CharCreatedBy != MISSION_CHAR && ped->m_nPedState == PED_IDLE && !ped->IsPlayer()) {
ped->SetWanderPath(CGeneral::GetRandomNumberInRange(0.0f, 8.0f));
}
- }
-#ifdef VC_PED_PORTS
- else {
+ } else if (ped->m_nPedState == PED_DRIVING) {
ped->m_nPedState = PED_IDLE;
}
-#endif
if (animAssoc)
animAssoc->blendDelta = -1000.0f;
ped->RestartNonPartialAnims();
ped->m_pVehicleAnim = nil;
- CVector posFromZ = ped->GetPosition();
- CPedPlacement::FindZCoorForPed(&posFromZ);
ped->m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
- ped->SetPosition(posFromZ);
veh = ped->m_pMyVehicle;
if (veh) {
if (ped->m_nPedType == PEDTYPE_PROSTITUTE) {
@@ -4300,7 +4092,12 @@ CPed::PedSetOutCarCB(CAnimBlendAssociation *animAssoc, void *arg)
}
}
}
- veh->m_nGettingOutFlags &= ~GetCarDoorFlag(ped->m_vehDoor);
+ if (veh && veh->IsBike())
+ // BUG?
+ veh->m_nGettingOutFlags &= ~GetBikeDoorFlag(ped->m_vehDoor);
+ else
+ veh->m_nGettingOutFlags &= ~GetCarDoorFlag(ped->m_vehDoor);
+
if (veh->pDriver == ped) {
veh->RemoveDriver();
#ifndef FIX_BUGS // RemoveDriver does it anyway
@@ -4310,6 +4107,11 @@ CPed::PedSetOutCarCB(CAnimBlendAssociation *animAssoc, void *arg)
veh->m_nDoorLock = CARLOCK_UNLOCKED;
if (ped->m_nPedType == PEDTYPE_COP && veh->IsLawEnforcementVehicle())
veh->ChangeLawEnforcerState(false);
+ if (veh->IsBike()) {
+ if (Abs(veh->m_vecMoveSpeed.x) < 0.1 && Abs(veh->m_vecMoveSpeed.y) < 0.1f) {
+ ((CBike*)veh)->bIsStanding = true;
+ }
+ }
} else {
veh->RemovePassenger(ped);
}
@@ -4353,6 +4155,7 @@ CPed::PedSetOutCarCB(CAnimBlendAssociation *animAssoc, void *arg)
if (createdBy == MISSION_CHAR && !startedToRun)
ped->SetMoveState(PEDMOVE_WALK);
}
+ ped->bHeldHostageInCar = false;
}
void
@@ -4362,7 +4165,20 @@ CPed::PedSetDraggedOutCarCB(CAnimBlendAssociation *dragAssoc, void *arg)
CVehicle *vehicle;
CPed *ped = (CPed*)arg;
+ uint8 exitFlags = 0;
quickJackedAssoc = RpAnimBlendClumpGetAssociation(ped->GetClump(), ANIM_STD_QUICKJACKED);
+ if (dragAssoc && dragAssoc->animId == ANIM_BIKE_HIT && ped->m_pMyVehicle) {
+ if (ped->m_vehDoor == CAR_DOOR_LF || ped->m_vehDoor == CAR_DOOR_RF) {
+ CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_BIKE_FALLOFF, 100.0f);
+ ped->m_pMyVehicle->m_nGettingOutFlags &= ~(CAR_DOOR_FLAG_RF | CAR_DOOR_FLAG_LF);
+ } else {
+ CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_BIKE_FALLBACK, 100.0f);
+ ped->m_pMyVehicle->m_nGettingOutFlags &= ~(CAR_DOOR_FLAG_RR | CAR_DOOR_FLAG_LR);
+ }
+ ((CBike*)ped->m_pMyVehicle)->KnockOffRider(WEAPONTYPE_UNIDENTIFIED, 0, ped, true);
+ return;
+ }
+
if (ped->m_nPedState != PED_ARRESTED) {
ped->m_nLastPedState = PED_NONE;
if (dragAssoc)
@@ -4373,9 +4189,15 @@ CPed::PedSetDraggedOutCarCB(CAnimBlendAssociation *dragAssoc, void *arg)
ped->m_pSeekTarget = nil;
vehicle = ped->m_pMyVehicle;
- if (vehicle) {
- vehicle->m_nGettingOutFlags &= ~GetCarDoorFlag(ped->m_vehDoor);
+ if (vehicle && vehicle->IsBike())
+ exitFlags = GetBikeDoorFlagInclJumpInFromFront(ped->m_vehDoor);
+ else
+ exitFlags = GetCarDoorFlag(ped->m_vehDoor);
+
+ if (vehicle)
+ vehicle->m_nGettingOutFlags &= ~exitFlags;
+ if (vehicle) {
if (vehicle->pDriver == ped) {
vehicle->RemoveDriver();
if (vehicle->m_nDoorLock == CARLOCK_LOCKED_INITIALLY)
@@ -4391,14 +4213,12 @@ CPed::PedSetDraggedOutCarCB(CAnimBlendAssociation *dragAssoc, void *arg)
if (ped->IsPlayer())
AudioManager.PlayerJustLeftCar();
-#ifdef VC_PED_PORTS
if (ped->m_objective == OBJECTIVE_LEAVE_CAR_AND_DIE) {
dragAssoc->SetDeleteCallback(PedSetDraggedOutCarPositionCB, ped);
ped->m_fHealth = 0.0f;
ped->SetDie(ANIM_STD_HIT_FLOOR, 1000.0f, 0.5f);
return;
}
-#endif
if (quickJackedAssoc) {
dragAssoc->SetDeleteCallback(PedSetQuickDraggedOutCarPositionCB, ped);
@@ -4425,7 +4245,6 @@ CPed::PedSetInCarCB(CAnimBlendAssociation *animAssoc, void *arg)
if (!veh)
return;
-#ifdef VC_PED_PORTS
// Situation of entering car as a driver while there is already a driver exiting atm.
CPed *driver = veh->pDriver;
if (driver && driver->m_nPedState == PED_DRIVING && !veh->bIsBus && driver->m_objective == OBJECTIVE_LEAVE_CAR
@@ -4451,7 +4270,16 @@ CPed::PedSetInCarCB(CAnimBlendAssociation *animAssoc, void *arg)
veh->pDriver = nil;
}
}
-#endif
+
+ if (ped->bRemoveMeWhenIGotIntoCar) {
+ ped->bRemoveMeWhenIGotIntoCar = false;
+ ped->bRemoveFromWorld = true;
+ }
+ if (ped->bCollectBusFare) {
+ ped->bCollectBusFare = false;
+ if (FindPlayerPed())
+ FindPlayerPed()->m_nLastBusFareCollected += 5;
+ }
if (!ped->IsNotInWreckedVehicle() || ped->DyingOrDead())
return;
@@ -4467,11 +4295,7 @@ CPed::PedSetInCarCB(CAnimBlendAssociation *animAssoc, void *arg)
}
}
}
- if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER
-#if defined VC_PED_PORTS || defined FIX_BUGS
- || ped->m_nPedState == PED_CARJACK
-#endif
- )
+ if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER || ped->m_nPedState == PED_CARJACK)
veh->bIsBeingCarJacked = false;
if (veh->m_nNumGettingIn)
@@ -4482,9 +4306,7 @@ CPed::PedSetInCarCB(CAnimBlendAssociation *animAssoc, void *arg)
if (veh->IsBoat()) {
if (ped->IsPlayer()) {
-#if defined VC_PED_PORTS || defined FIX_BUGS
CCarCtrl::RegisterVehicleOfInterest(veh);
-#endif
if (veh->GetStatus() == STATUS_SIMPLE) {
veh->m_vecMoveSpeed = CVector(0.0f, 0.0f, -0.00001f);
veh->m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f);
@@ -4498,6 +4320,7 @@ CPed::PedSetInCarCB(CAnimBlendAssociation *animAssoc, void *arg)
ped->SetPedState(PED_DRIVING);
ped->StopNonPartialAnims();
+ ped->RemoveWeaponWhenEnteringVehicle();
return;
}
@@ -4509,7 +4332,7 @@ CPed::PedSetInCarCB(CAnimBlendAssociation *animAssoc, void *arg)
veh->m_nAlarmState = 15000;
if (ped->IsPlayer()) {
- if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER) {
+ if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER || veh->IsBike()) {
if (veh->GetStatus() == STATUS_SIMPLE) {
veh->m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
veh->m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f);
@@ -4528,27 +4351,12 @@ CPed::PedSetInCarCB(CAnimBlendAssociation *animAssoc, void *arg)
if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER) {
for (int i = 0; i < veh->m_nNumMaxPassengers; ++i) {
CPed *passenger = veh->pPassengers[i];
- if (passenger && passenger->CharCreatedBy == RANDOM_CHAR) {
+ if (passenger && !passenger->bStayInCarOnJack && !passenger->bHeldHostageInCar && (passenger->m_leader != ped || !ped->bIsLeader)) {
passenger->SetObjective(OBJECTIVE_LEAVE_CAR, veh);
-#ifdef VC_PED_PORTS
passenger->m_leaveCarTimer = CTimer::GetTimeInMilliseconds();
-#endif
}
}
}
- // This shouldn't happen at all. Passengers can't enter with PED_CARJACK. Even though they did, we shouldn't call AddPassenger in here and SetDriver in below.
-#if !defined VC_PED_PORTS && !defined FIX_BUGS
- else if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER) {
- if (ped->m_nPedState == PED_CARJACK) {
- veh->AddPassenger(ped, 0);
- ped->SetPedState(PED_DRIVING);
- ped->RestorePreviousObjective();
- ped->SetObjective(OBJECTIVE_LEAVE_CAR, veh);
- } else if (veh->pDriver && ped->CharCreatedBy == RANDOM_CHAR) {
- veh->AutoPilot.m_nCruiseSpeed = 17;
- }
- }
-#endif
if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER || ped->m_nPedState == PED_CARJACK) {
veh->SetDriver(ped);
@@ -4584,14 +4392,24 @@ CPed::PedSetInCarCB(CAnimBlendAssociation *animAssoc, void *arg)
ped->SetPedState(PED_DRIVING);
if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER) {
- if (ped->m_prevObjective == OBJECTIVE_RUN_TO_AREA || ped->m_prevObjective == OBJECTIVE_GOTO_CHAR_ON_FOOT || ped->m_prevObjective == OBJECTIVE_KILL_CHAR_ON_FOOT)
+ if (ped->m_prevObjective == OBJECTIVE_RUN_TO_AREA || ped->m_prevObjective == OBJECTIVE_GOTO_CHAR_ON_FOOT
+ || ped->m_prevObjective == OBJECTIVE_SPRINT_TO_AREA || ped->m_prevObjective == OBJECTIVE_KILL_CHAR_ON_FOOT)
ped->m_prevObjective = OBJECTIVE_NONE;
ped->RestorePreviousObjective();
}
- } else if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER) {
- if (veh->bIsBus) {
+ } else {
+
+ bool slowDown = false;
+ if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER && veh->pDriver && ped->CharCreatedBy == RANDOM_CHAR)
+ slowDown = true;
+
+ // VC also has a dead condition in here.
+
+ if (veh->IsBike()) {
+ veh->AddPassenger(ped, 0);
+ } else if (veh->bIsBus) {
veh->AddPassenger(ped);
} else {
switch (ped->m_vehDoor) {
@@ -4610,17 +4428,26 @@ CPed::PedSetInCarCB(CAnimBlendAssociation *animAssoc, void *arg)
}
}
ped->SetPedState(PED_DRIVING);
- if (ped->m_prevObjective == OBJECTIVE_RUN_TO_AREA || ped->m_prevObjective == OBJECTIVE_GOTO_CHAR_ON_FOOT || ped->m_prevObjective == OBJECTIVE_KILL_CHAR_ON_FOOT)
+ if (ped->m_prevObjective == OBJECTIVE_RUN_TO_AREA || ped->m_prevObjective == OBJECTIVE_GOTO_CHAR_ON_FOOT
+ || ped->m_prevObjective == OBJECTIVE_SPRINT_TO_AREA || ped->m_prevObjective == OBJECTIVE_KILL_CHAR_ON_FOOT)
ped->m_prevObjective = OBJECTIVE_NONE;
ped->RestorePreviousObjective();
-#ifdef VC_PED_PORTS
- if(veh->pDriver && ped->CharCreatedBy == RANDOM_CHAR)
+
+ // VC has conditional OBJECTIVE_LEAVE_CAR here, which runs if it entered the first dead condition.
+
+ if(slowDown)
veh->AutoPilot.m_nCruiseSpeed = 17;
-#endif
}
- veh->m_nGettingInFlags &= ~GetCarDoorFlag(ped->m_vehDoor);
+ int8 doorFlag;
+ if (veh->IsBike()) {
+ doorFlag = GetBikeDoorFlagInclJumpInFromFront(ped->m_vehDoor);
+ } else {
+ doorFlag = GetEnterCarDoorFlag(ped->m_vehDoor, veh->m_nNumMaxPassengers);
+ }
+
+ veh->m_nGettingInFlags &= ~doorFlag;
if (veh->bIsBus && !veh->m_nGettingInFlags)
((CAutomobile*)veh)->SetBusDoorTimer(1000, 1);
@@ -4633,24 +4460,19 @@ CPed::PedSetInCarCB(CAnimBlendAssociation *animAssoc, void *arg)
case OBJECTIVE_GOTO_AREA_ANY_MEANS:
case OBJECTIVE_GOTO_AREA_ON_FOOT:
case OBJECTIVE_RUN_TO_AREA:
+ case OBJECTIVE_GOTO_SEAT_ON_FOOT:
+ case OBJECTIVE_GOTO_ATM_ON_FOOT:
+ case OBJECTIVE_GOTO_BUS_STOP_ON_FOOT:
+ case OBJECTIVE_GOTO_PIZZA_ON_FOOT:
+ case OBJECTIVE_GOTO_SHELTER_ON_FOOT:
+ case OBJECTIVE_SPRINT_TO_AREA:
+ case OBJECTIVE_GOTO_ICE_CREAM_VAN_ON_FOOT:
break;
default:
ped->SetObjective(OBJECTIVE_NONE);
}
- if (veh->pDriver == ped) {
- if (veh->bLowVehicle) {
- ped->m_pVehicleAnim = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_SIT_LO, 100.0f);
- } else {
- ped->m_pVehicleAnim = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_SIT, 100.0f);
- }
- } else if (veh->bLowVehicle) {
- ped->m_pVehicleAnim = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_SIT_P_LO, 100.0f);
- } else {
- ped->m_pVehicleAnim = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_SIT_P, 100.0f);
- }
-
- ped->StopNonPartialAnims();
+ ped->AddInCarAnims(veh, veh->pDriver == ped);
if (veh->bIsBus)
ped->bRenderPedInCar = false;
@@ -4681,6 +4503,23 @@ CPed::CanBeDeleted(void)
return true;
case MISSION_CHAR:
return false;
+ case UNK_CHAR:
+ return false;
+ default:
+ return true;
+ }
+}
+
+bool
+CPed::CanBeDeletedEvenInVehicle(void)
+{
+ switch (CharCreatedBy) {
+ case RANDOM_CHAR:
+ return true;
+ case MISSION_CHAR:
+ return false;
+ case UNK_CHAR:
+ return false;
default:
return true;
}
@@ -4689,24 +4528,16 @@ CPed::CanBeDeleted(void)
void
CPed::AddWeaponModel(int id)
{
- RpAtomic *atm;
-
if (id != -1) {
-#ifdef PED_SKIN
- if (IsClumpSkinned(GetClump())) {
- if (m_pWeaponModel)
- RemoveWeaponModel(-1);
+ if (m_pWeaponModel)
+ RemoveWeaponModel(-1);
- m_pWeaponModel = (RpAtomic*)CModelInfo::GetModelInfo(id)->CreateInstance();
- } else
-#endif
- {
- atm = (RpAtomic*)CModelInfo::GetModelInfo(id)->CreateInstance();
- RwFrameDestroy(RpAtomicGetFrame(atm));
- RpAtomicSetFrame(atm, m_pFrames[PED_HANDR]->frame);
- RpClumpAddAtomic(GetClump(), atm);
- }
+ m_pWeaponModel = (RpAtomic*)CModelInfo::GetModelInfo(id)->CreateInstance();
+ CModelInfo::GetModelInfo(id)->AddRef();
m_wepModelID = id;
+
+ if (IsPlayer() && id == MI_MINIGUN)
+ ((CPlayerPed*)this)->m_pMinigunTopAtomic = (RpAtomic*)CModelInfo::GetModelInfo(MI_MINIGUN2)->CreateInstance();
}
}
@@ -4725,108 +4556,218 @@ void
CPed::RemoveWeaponModel(int modelId)
{
// modelId is not used!! This function just removes the current weapon.
-#ifdef PED_SKIN
- if(IsClumpSkinned(GetClump())){
- if(m_pWeaponModel){
- RwFrame *frm = RpAtomicGetFrame(m_pWeaponModel);
+ if(m_pWeaponModel){
+ if (modelId == -1
+ || CVisibilityPlugins::GetAtomicModelInfo(m_pWeaponModel) == CModelInfo::GetModelInfo(modelId)) {
+ CVisibilityPlugins::GetAtomicModelInfo(m_pWeaponModel)->RemoveRef();
+ RwFrame* frm = RpAtomicGetFrame(m_pWeaponModel);
RpAtomicDestroy(m_pWeaponModel);
RwFrameDestroy(frm);
m_pWeaponModel = nil;
}
- }else
-#endif
- RwFrameForAllObjects(m_pFrames[PED_HANDR]->frame,RemoveAllModelCB,nil);
+ }
+
+ if (IsPlayer() && (modelId == -1 || modelId == MI_MINIGUN)) {
+ RpAtomic* &atm = ((CPlayerPed*)this)->m_pMinigunTopAtomic;
+ if (atm) {
+ RwFrame *frm = RpAtomicGetFrame(atm);
+ RpAtomicDestroy(atm);
+ RwFrameDestroy(frm);
+ atm = nil;
+ }
+ }
m_wepModelID = -1;
}
-uint32
-CPed::GiveWeapon(eWeaponType weaponType, uint32 ammo)
+void
+CPed::RequestDelayedWeapon()
{
- CWeapon &weapon = GetWeapon(weaponType);
+ 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)
+ CStreaming::RequestModel(modelId2, STREAMFLAGS_DEPENDENCY);
- if (HasWeapon(weaponType)) {
- if (weapon.m_nAmmoTotal + ammo > 99999)
- weapon.m_nAmmoTotal = 99999;
- else
- weapon.m_nAmmoTotal += ammo;
+ if ((modelId1 == -1 || CStreaming::HasModelLoaded(modelId1))
+ && (modelId2 == -1 || CStreaming::HasModelLoaded(modelId2))) {
+ GiveWeapon(m_delayedWeapon, m_delayedWeaponAmmo, 1);
+ m_delayedWeapon = WEAPONTYPE_UNIDENTIFIED;
+ }
+ }
+}
+
+void
+CPed::GiveDelayedWeapon(eWeaponType weapon, uint32 ammo)
+{
+ 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)
+ CStreaming::RequestModel(modelId2, STREAMFLAGS_DEPENDENCY);
+
+ if ((modelId1 == -1 || CStreaming::HasModelLoaded(modelId1))
+ && (modelId2 == -1 || CStreaming::HasModelLoaded(modelId2))) {
+ GiveWeapon(m_delayedWeapon, m_delayedWeaponAmmo, true);
+ m_delayedWeapon = WEAPONTYPE_UNIDENTIFIED;
+ }
+ }
+}
- weapon.Reload();
+int32
+CPed::GiveWeapon(eWeaponType weaponType, uint32 ammo, bool unused)
+{
+ int slot = GetWeaponSlot(weaponType);
+
+ if (m_weapons[slot].m_eWeaponType == weaponType) {
+ 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], GetWeapon(slot).m_nAmmoTotal);
+ } else {
+ GetWeapon(slot).m_nAmmoTotal = Min(99999, GetWeapon(slot).m_nAmmoTotal);
+ }
+ GetWeapon(slot).Reload();
+ if (GetWeapon(slot).m_eWeaponState == WEAPONSTATE_OUT_OF_AMMO && GetWeapon(slot).m_nAmmoTotal > 0)
+ GetWeapon(slot).m_eWeaponState = WEAPONSTATE_READY;
} else {
- weapon.Initialise(weaponType, ammo);
- // TODO: It seems game uses this as both weapon count and max WeaponType we have, which is ofcourse erroneous.
- m_maxWeaponTypeAllowed++;
+ if (HasWeaponSlot(slot)) {
+ if (CWeaponInfo::IsWeaponSlotAmmoMergeable(slot))
+ ammo += GetWeapon(slot).m_nAmmoTotal;
+
+ RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(GetWeapon(slot).m_eWeaponType)->m_nModelId);
+ GetWeapon(slot).Shutdown();
+ }
+ GetWeapon(slot).Initialise(weaponType, ammo);
+ if (slot == m_currentWeapon && !bInVehicle) {
+ AddWeaponModel(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_nModelId);
+ }
}
- if (weapon.m_eWeaponState == WEAPONSTATE_OUT_OF_AMMO)
- weapon.m_eWeaponState = WEAPONSTATE_READY;
+ if (GetWeapon(slot).m_eWeaponState != WEAPONSTATE_OUT_OF_AMMO)
+ GetWeapon(slot).m_eWeaponState = WEAPONSTATE_READY;
- return weaponType;
+ return slot;
}
-// Some kind of VC leftover I think
int
CPed::GetWeaponSlot(eWeaponType weaponType)
{
- if (HasWeapon(weaponType))
- return weaponType;
- else
- return -1;
+ return CWeaponInfo::GetWeaponInfo(weaponType)->m_nWeaponSlot;
}
void
-CPed::SetCurrentWeapon(uint32 weaponType)
+CPed::SetCurrentWeapon(int slot)
{
- CWeaponInfo *weaponInfo;
- if (HasWeapon(weaponType)) {
+ if (slot == -1)
+ return;
+
+ CWeaponInfo* weaponInfo;
+ if (GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED) {
weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
RemoveWeaponModel(weaponInfo->m_nModelId);
+ }
+ m_currentWeapon = slot;
- m_currentWeapon = weaponType;
+ if (FindPlayerPed() && IsPlayer())
+ ((CPlayerPed*)this)->m_nSelectedWepSlot = m_currentWeapon;
+ if (HasWeaponSlot(slot)) {
weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
AddWeaponModel(weaponInfo->m_nModelId);
}
}
void
+CPed::SetCurrentWeapon(eWeaponType weaponType)
+{
+ SetCurrentWeapon(CWeaponInfo::GetWeaponInfo(weaponType)->m_nWeaponSlot);
+}
+
+void
CPed::GrantAmmo(eWeaponType weaponType, uint32 ammo)
{
- if (HasWeapon(weaponType)) {
- GetWeapon(weaponType).m_nAmmoTotal += ammo;
+ int slot = CWeaponInfo::GetWeaponInfo(weaponType)->m_nWeaponSlot;
+ if (slot == -1)
+ return;
+
+ 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], GetWeapon(slot).m_nAmmoTotal);
} else {
- GetWeapon(weaponType).Initialise(weaponType, ammo);
- m_maxWeaponTypeAllowed++;
+ GetWeapon(slot).m_nAmmoTotal = Min(99999, GetWeapon(slot).m_nAmmoTotal);
}
+
+ if (GetWeapon(slot).m_eWeaponState == WEAPONSTATE_OUT_OF_AMMO && GetWeapon(slot).m_nAmmoTotal > 0)
+ GetWeapon(slot).m_eWeaponState = WEAPONSTATE_READY;
}
void
CPed::SetAmmo(eWeaponType weaponType, uint32 ammo)
{
- if (HasWeapon(weaponType)) {
- GetWeapon(weaponType).m_nAmmoTotal = ammo;
+ int slot = CWeaponInfo::GetWeaponInfo(weaponType)->m_nWeaponSlot;
+ if (slot == -1)
+ return;
+
+ 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], GetWeapon(slot).m_nAmmoTotal);
} else {
- GetWeapon(weaponType).Initialise(weaponType, ammo);
- m_maxWeaponTypeAllowed++;
+ GetWeapon(slot).m_nAmmoTotal = Min(99999, 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;
+
+ if (GetWeapon(slot).m_eWeaponState == WEAPONSTATE_OUT_OF_AMMO && GetWeapon(slot).m_nAmmoTotal > 0)
+ GetWeapon(slot).m_eWeaponState = WEAPONSTATE_READY;
}
void
CPed::ClearWeapons(void)
{
- CWeaponInfo *currentWeapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
- RemoveWeaponModel(currentWeapon->m_nModelId);
+ RemoveWeaponModel(-1);
+ for (int i = 0; i < ARRAY_SIZE(m_weapons); i++) {
+ GetWeapon(i).Shutdown();
+ }
+ SetCurrentWeapon(WEAPONTYPE_UNARMED);
+}
- m_maxWeaponTypeAllowed = WEAPONTYPE_BASEBALLBAT;
- m_currentWeapon = WEAPONTYPE_UNARMED;
+void
+CPed::RemoveWeaponWhenEnteringVehicle(void)
+{
+ 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);
+ } else {
+ CWeaponInfo *ourWeapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
+ RemoveWeaponModel(ourWeapon->m_nModelId);
+ }
+}
+void
+CPed::ReplaceWeaponWhenExitingVehicle(void)
+{
+ eWeaponType weaponType = GetWeapon()->m_eWeaponType;
- currentWeapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
- AddWeaponModel(currentWeapon->m_nModelId);
- for(int i = 0; i < WEAPONTYPE_TOTAL_INVENTORY_WEAPONS; i++) {
- CWeapon &weapon = GetWeapon(i);
- weapon.m_eWeaponType = WEAPONTYPE_UNARMED;
- weapon.m_eWeaponState = WEAPONSTATE_READY;
- weapon.m_nAmmoInClip = 0;
- weapon.m_nAmmoTotal = 0;
- weapon.m_nTimer = 0;
+ // If it's Uzi, we may have stored weapon. Uzi is the only gun we can use in car.
+ if (IsPlayer() && GetWeaponSlot(weaponType) == WEAPONSLOT_SUBMACHINEGUN) {
+ if (m_storedWeapon != WEAPONTYPE_UNIDENTIFIED) {
+ SetCurrentWeapon(m_storedWeapon);
+ m_storedWeapon = WEAPONTYPE_UNIDENTIFIED;
+ }
+ } else {
+ AddWeaponModel(CWeaponInfo::GetWeaponInfo(weaponType)->m_nModelId);
}
}
@@ -4838,20 +4779,160 @@ CPed::PreRender(void)
CTimeCycle::m_fShadowFrontX[CTimeCycle::m_CurrentStoredValue], CTimeCycle::m_fShadowFrontY[CTimeCycle::m_CurrentStoredValue],
CTimeCycle::m_fShadowSideX[CTimeCycle::m_CurrentStoredValue], CTimeCycle::m_fShadowSideY[CTimeCycle::m_CurrentStoredValue]);
-#ifdef PED_SKIN
- if(IsClumpSkinned(GetClump())){
- UpdateRpHAnim();
+ UpdateRpHAnim();
+
+ bool bIsWindModifierTurnedOn = false;
+ float fAnyDirectionShift = 1.0f;
+ bool bIsPedDrivingBikeOrOpenTopCar = false;
+ if (IsPlayer() && CWindModifiers::FindWindModifier(GetPosition(), &fAnyDirectionShift, &fAnyDirectionShift)
+ && !CCullZones::PlayerNoRain() && GetPedState() != PED_DRIVING)
+ bIsWindModifierTurnedOn = true;
- if(bBodyPartJustCameOff && m_bodyPartBleeding == PED_HEAD){
- // scale head to 0 if shot off
- RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump());
- int32 idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_HEAD));
- RwMatrix *head = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
- RwV3d zero = { 0.0f, 0.0f, 0.0f };
- RwMatrixScale(head, &zero, rwCOMBINEPRECONCAT);
+ if (GetPedState() == PED_DRIVING && m_pMyVehicle) {
+ if (m_pMyVehicle->m_vehType == VEHICLE_TYPE_BIKE
+ || (m_pMyVehicle->m_vehType == VEHICLE_TYPE_CAR && m_pMyVehicle->IsOpenTopCar()))
+ bIsPedDrivingBikeOrOpenTopCar = true;
+ }
+
+ if (bIsWindModifierTurnedOn || bIsPedDrivingBikeOrOpenTopCar) {
+ float fWindMult = 0.0f;
+ if (bIsPedDrivingBikeOrOpenTopCar) {
+ fWindMult = DotProduct(m_pMyVehicle->m_vecMoveSpeed, GetForward());
+ if (fWindMult > 0.4f) {
+ float volume = (fWindMult - 0.4f) / 0.6f;
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_SHIRT_WIND_FLAP, volume);
+ }
}
+
+ if (bIsWindModifierTurnedOn)
+ fWindMult = Min(fWindMult, Abs(fAnyDirectionShift - 1.0f));
+
+ RpHAnimHierarchy* hier = GetAnimHierarchyFromSkinClump(GetClump());
+ int32 idx;
+ RwV3d scale;
+ float fScaleOffset;
+
+ fScaleOffset = fWindMult * 0.2f;
+ scale.x = CGeneral::GetRandomNumberInRange(1.0f - fScaleOffset, 1.0f + fScaleOffset);
+ scale.y = CGeneral::GetRandomNumberInRange(1.0f - fScaleOffset, 1.0f + fScaleOffset);
+ scale.z = CGeneral::GetRandomNumberInRange(1.0f - fScaleOffset, 1.0f + fScaleOffset);
+
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_NECK));
+ RwMatrix* neck = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(neck, &scale, rwCOMBINEPRECONCAT);
+
+ fScaleOffset = fWindMult * 0.1f;
+ scale.x = CGeneral::GetRandomNumberInRange(1.0f - fScaleOffset, 1.0f + fScaleOffset);
+ scale.y = CGeneral::GetRandomNumberInRange(1.0f - fScaleOffset, 1.0f + fScaleOffset);
+ scale.z = CGeneral::GetRandomNumberInRange(1.0f - fScaleOffset, 1.0f + fScaleOffset);
+
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_CLAVICLEL));
+ RwMatrix* clavicleL = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(clavicleL, &scale, rwCOMBINEPRECONCAT);
+
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_CLAVICLER));
+ RwMatrix* clavicleR = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(clavicleR, &scale, rwCOMBINEPRECONCAT);
+
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_MID));
+ RwMatrix* mid = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(mid, &scale, rwCOMBINEPRECONCAT);
+
+ fScaleOffset = fWindMult * 0.2f;
+ scale.x = CGeneral::GetRandomNumberInRange(1.0f - fScaleOffset, 1.0f + fScaleOffset);
+ scale.y = CGeneral::GetRandomNumberInRange(1.0f - fScaleOffset, 1.0f + fScaleOffset);
+ scale.z = CGeneral::GetRandomNumberInRange(1.0f - fScaleOffset, 1.0f + fScaleOffset);
+
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_UPPERARML));
+ RwMatrix* upperArmL = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(upperArmL, &scale, rwCOMBINEPRECONCAT);
+
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_UPPERARMR));
+ RwMatrix* upperArmR = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(upperArmR, &scale, rwCOMBINEPRECONCAT);
+ }
+
+ if (bBodyPartJustCameOff && m_bodyPartBleeding == PED_HEAD) {
+ // scale head to 0 if shot off
+ RpHAnimHierarchy* hier = GetAnimHierarchyFromSkinClump(GetClump());
+ int32 idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_HEAD));
+ RwMatrix* head = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwV3d zero = { 0.0f, 0.0f, 0.0f };
+ RwMatrixScale(head, &zero, rwCOMBINEPRECONCAT);
+ }
+
+ if (IsPlayer() && gfTommyFatness != 1.0f) {
+ RpHAnimHierarchy* hier = GetAnimHierarchyFromSkinClump(GetClump());
+ int32 idx;
+ RwV3d scale;
+
+ scale.x = 1.0f;
+ scale.y = 1.0f + gfTommyFatness * 0.7f;
+ scale.z = 1.0f + gfTommyFatness * 0.7f;
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_HEAD));
+ RwMatrix* head = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(head, &scale, rwCOMBINEPRECONCAT);
+
+ scale.y = 1.0f + gfTommyFatness * 0.2f;
+ scale.z = 1.0f + gfTommyFatness * 0.2f;
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_NECK));
+ RwMatrix* neck = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(neck, &scale, rwCOMBINEPRECONCAT);
+
+ scale.y = 1.0f + gfTommyFatness * 0.5f;
+ scale.z = 1.0f + gfTommyFatness * 0.5f;
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_MID));
+ RwMatrix* mid = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(mid, &scale, rwCOMBINEPRECONCAT);
+
+ scale.y = 1.0f + gfTommyFatness;
+ scale.z = 1.0f + gfTommyFatness;
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_UPPERLEGL));
+ RwMatrix* upperLegL = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(upperLegL, &scale, rwCOMBINEPRECONCAT);
+
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_UPPERLEGR));
+ RwMatrix* upperLegR = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(upperLegR, &scale, rwCOMBINEPRECONCAT);
+
+ scale.y = 1.0f + gfTommyFatness * 0.5f;
+ scale.z = 1.0f + gfTommyFatness * 0.5f;
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_LOWERLEGR));
+ RwMatrix* lowerLegR = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(lowerLegR, &scale, rwCOMBINEPRECONCAT);
+
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_LOWERLEGL));
+ RwMatrix* lowerLegL = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(lowerLegL, &scale, rwCOMBINEPRECONCAT);
+
+ scale.y = 1.0f + gfTommyFatness * 0.23f;
+ scale.z = 1.0f + gfTommyFatness * 0.23f;
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_FOOTL));
+ RwMatrix* footL = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(footL, &scale, rwCOMBINEPRECONCAT);
+
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_FOOTR));
+ RwMatrix* footR = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(footR, &scale, rwCOMBINEPRECONCAT);
+
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_UPPERARML));
+ RwMatrix* upperArmL = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(upperArmL, &scale, rwCOMBINEPRECONCAT);
+
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_UPPERARMR));
+ RwMatrix* upperArmR = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(upperArmR, &scale, rwCOMBINEPRECONCAT);
+
+ scale.y = 1.0f + gfTommyFatness * 0.2f;
+ scale.z = 1.0f + gfTommyFatness * 0.2f;
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_FOREARML));
+ RwMatrix* foreArmL = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(foreArmL, &scale, rwCOMBINEPRECONCAT);
+
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_FOREARMR));
+ RwMatrix* foreArmR = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(foreArmR, &scale, rwCOMBINEPRECONCAT);
}
-#endif
if (bBodyPartJustCameOff && bIsPedDieAnimPlaying && m_bodyPartBleeding != -1 && (CTimer::GetFrameCounter() & 7) > 3) {
CVector bloodDir(0.0f, 0.0f, 0.0f);
@@ -4922,27 +5003,25 @@ CPed::PreRender(void)
}
}
+CVector vecTestTemp(-1.0f, -1.0f, -1.0f);
+
void
CPed::Render(void)
{
- if (bInVehicle && m_nPedState != PED_EXIT_CAR && m_nPedState != PED_DRAG_FROM_CAR) {
+ if (bInVehicle && m_pMyVehicle && m_nPedState != PED_EXIT_CAR && m_nPedState != PED_DRAG_FROM_CAR) {
if (!bRenderPedInCar)
return;
- float camDistSq = (TheCamera.GetPosition() - GetPosition()).MagnitudeSqr();
- if (camDistSq > SQR(25.0f * TheCamera.LODDistMultiplier))
- return;
+ if (!m_pMyVehicle->IsBike() && !IsPlayer()) {
+ float camDistSq = (TheCamera.GetPosition() - GetPosition()).MagnitudeSqr();
+ if (camDistSq > SQR((m_pMyVehicle->IsBoat() ? 40.0f : 25.0f) * TheCamera.LODDistMultiplier))
+ return;
+ }
}
CEntity::Render();
-#ifdef PED_SKIN
- if(IsClumpSkinned(GetClump())){
- renderLimb(PED_HEAD);
- renderLimb(PED_HANDL);
- renderLimb(PED_HANDR);
- }
- if(m_pWeaponModel && IsClumpSkinned(GetClump())){
+ if(m_pWeaponModel){
RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump());
int idx = RpHAnimIDGetIndex(hier, m_pFrames[PED_HANDR]->nodeID);
RwMatrix *mat = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
@@ -4950,8 +5029,29 @@ CPed::Render(void)
*RwFrameGetMatrix(frame) = *mat;
RwFrameUpdateObjects(frame);
RpAtomicRender(m_pWeaponModel);
+ if (IsPlayer()) {
+ CPlayerPed *player = (CPlayerPed*)this;
+ if (player->m_pMinigunTopAtomic) {
+ frame = RpAtomicGetFrame(player->m_pMinigunTopAtomic);
+ *RwFrameGetMatrix(frame) = *mat;
+
+ player->m_fGunSpinAngle = player->m_fGunSpinSpeed * CTimer::GetTimeStep() + player->m_fGunSpinAngle;
+ if (player->m_fGunSpinAngle > TWOPI)
+ player->m_fGunSpinAngle -= TWOPI;
+
+ CMatrix mgTopMat, localAdjMat;
+ mgTopMat.Attach(RwFrameGetMatrix(frame));
+ localAdjMat.SetRotateX(player->m_fGunSpinAngle);
+ localAdjMat.Rotate(DEGTORAD(-4.477f)* vecTestTemp.x, DEGTORAD(29.731f) * vecTestTemp.y, DEGTORAD(1.064f) * vecTestTemp.z);
+ localAdjMat.GetPosition() += CVector(0.829f, -0.001f, 0.226f);
+ mgTopMat = mgTopMat * localAdjMat;
+ mgTopMat.UpdateRW();
+
+ RwFrameUpdateObjects(frame);
+ RpAtomicRender(player->m_pMinigunTopAtomic);
+ }
+ }
}
-#endif
}
void
@@ -4990,14 +5090,12 @@ void
CPed::SetIdle(void)
{
if (m_nPedState != PED_IDLE && m_nPedState != PED_MUG && m_nPedState != PED_FLEE_ENTITY) {
-#ifdef VC_PED_PORTS
if (m_nPedState == PED_AIM_GUN)
ClearPointGunAt();
- m_nLastPedState = PED_NONE;
-#endif
SetPedState(PED_IDLE);
SetMoveState(PEDMOVE_STILL);
+ m_nLastPedState = PED_NONE;
}
if (m_nWaitState == WAITSTATE_FALSE) {
m_nWaitTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(2000, 4000);
@@ -5025,39 +5123,9 @@ CPed::Idle(void)
}
}
- CAnimBlendAssociation *armedIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_IDLE_BIGGUN);
- CAnimBlendAssociation *unarmedIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_IDLE);
- int waitTime;
-
- if (m_nMoveState == PEDMOVE_STILL) {
-
- eWeaponType curWeapon = GetWeapon()->m_eWeaponType;
- if (!armedIdleAssoc ||
- CTimer::GetTimeInMilliseconds() <= m_nWaitTimer && curWeapon != WEAPONTYPE_UNARMED && curWeapon != WEAPONTYPE_MOLOTOV && curWeapon != WEAPONTYPE_GRENADE) {
-
- if ((!GetWeapon()->IsType2Handed() || curWeapon == WEAPONTYPE_SHOTGUN) && curWeapon != WEAPONTYPE_BASEBALLBAT
- || !unarmedIdleAssoc || unarmedIdleAssoc->blendAmount <= 0.95f || m_nWaitState != WAITSTATE_FALSE || CTimer::GetTimeInMilliseconds() <= m_nWaitTimer) {
+ if (m_nMoveState != PEDMOVE_STILL && !IsPlayer())
+ SetMoveState(PEDMOVE_STILL);
- m_moved = CVector2D(0.0f, 0.0f);
- return;
- }
- CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_IDLE_BIGGUN, 3.0f);
- waitTime = CGeneral::GetRandomNumberInRange(4000, 7500);
- } else {
- armedIdleAssoc->blendDelta = -2.0f;
- armedIdleAssoc->flags |= ASSOC_DELETEFADEDOUT;
- waitTime = CGeneral::GetRandomNumberInRange(3000, 8500);
- }
- m_nWaitTimer = CTimer::GetTimeInMilliseconds() + waitTime;
- } else {
- if (armedIdleAssoc) {
- armedIdleAssoc->blendDelta = -8.0f;
- armedIdleAssoc->flags |= ASSOC_DELETEFADEDOUT;
- m_nWaitTimer = 0;
- }
- if (!IsPlayer())
- SetMoveState(PEDMOVE_STILL);
- }
m_moved = CVector2D(0.0f, 0.0f);
}
@@ -5078,6 +5146,9 @@ CPed::Pause(void)
void
CPed::SetFall(int extraTime, AnimationId animId, uint8 evenIfNotInControl)
{
+ if (m_attachedTo)
+ return;
+
if (!IsPedInControl() && (!evenIfNotInControl || DyingOrDead()))
return;
@@ -5085,24 +5156,43 @@ CPed::SetFall(int extraTime, AnimationId animId, uint8 evenIfNotInControl)
ClearAimFlag();
SetStoredState();
SetPedState(PED_FALL);
- CAnimBlendAssociation *fallAssoc = RpAnimBlendClumpGetAssociation(GetClump(), animId);
-
- if (fallAssoc) {
- fallAssoc->SetCurrentTime(0.0f);
- fallAssoc->blendAmount = 0.0f;
- fallAssoc->blendDelta = 8.0f;
- fallAssoc->SetRun();
+ CAnimBlendAssociation *fallAssoc = nil;
+ if (animId == ANIM_STD_NUM) {
+ if (IsPlayer()) {
+ fallAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_ROLLOUT_LHS);
+ if (!fallAssoc)
+ fallAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_ROLLOUT_RHS);
+ }
} else {
- fallAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, animId, 8.0f);
+ fallAssoc = RpAnimBlendClumpGetAssociation(GetClump(), animId);
+
+ if (fallAssoc) {
+ fallAssoc->SetCurrentTime(0.0f);
+ fallAssoc->blendAmount = 0.0f;
+ fallAssoc->blendDelta = 8.0f;
+ fallAssoc->SetRun();
+ }
+ else {
+ fallAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, animId, 8.0f);
+ }
+ if (animId == ANIM_STD_BIKE_FALLBACK)
+ fallAssoc->SetCurrentTime(0.4f);
}
if (extraTime == -1) {
m_getUpTimer = UINT32_MAX;
} else if (fallAssoc) {
if (IsPlayer()) {
- m_getUpTimer = 1000.0f * fallAssoc->hierarchy->totalLength
- + CTimer::GetTimeInMilliseconds()
- + 500.0f;
+ if (fallAssoc->animId == ANIM_STD_ROLLOUT_LHS || fallAssoc->animId == ANIM_STD_ROLLOUT_RHS) {
+ m_getUpTimer = 1000.0f * fallAssoc->hierarchy->totalLength
+ + CTimer::GetTimeInMilliseconds()
+ - 1000.0f * fallAssoc->currentTime
+ + 100.0f;
+ } else {
+ m_getUpTimer = 1000.0f * fallAssoc->hierarchy->totalLength
+ + CTimer::GetTimeInMilliseconds()
+ + 500.0f;
+ }
} else {
m_getUpTimer = 1000.0f * fallAssoc->hierarchy->totalLength
+ CTimer::GetTimeInMilliseconds()
@@ -5127,14 +5217,59 @@ CPed::ClearFall(void)
void
CPed::Fall(void)
{
- if (m_getUpTimer != UINT32_MAX && CTimer::GetTimeInMilliseconds() > m_getUpTimer
-#ifdef VC_PED_PORTS
- && bIsStanding
-#endif
- )
+ if (m_getUpTimer != UINT32_MAX && CTimer::GetTimeInMilliseconds() > m_getUpTimer && bIsStanding)
ClearFall();
- // VC plays animations ANIM_STD_FALL_ONBACK and ANIM_STD_FALL_ONFRONT in here, which doesn't exist in III.
+ CAnimBlendAssociation *firstPartialAssoc;
+ CAnimBlendAssociation *fallAssoc;
+
+ if (IsPlayer() && (bKnockedUpIntoAir || bKnockedOffBike) && !bIsStanding) {
+ firstPartialAssoc = RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_PARTIAL);
+
+ // What???
+ if (firstPartialAssoc && (firstPartialAssoc->animId == ANIM_STD_FALL_ONBACK || firstPartialAssoc->animId == ANIM_STD_FALL_ONFRONT))
+ fallAssoc = firstPartialAssoc;
+ else
+ fallAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_FALL_ONBACK);
+
+ if (!fallAssoc)
+ fallAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_FALL_ONFRONT);
+
+ if (!fallAssoc && firstPartialAssoc && 0.8f * firstPartialAssoc->hierarchy->totalLength < firstPartialAssoc->currentTime) {
+ if (firstPartialAssoc->flags & ASSOC_FRONTAL) {
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_FALL_ONFRONT, 8.0f);
+ } else {
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_FALL_ONBACK, 8.0f);
+ }
+ } else if (fallAssoc && fallAssoc->blendAmount > 0.3f && fallAssoc->blendDelta >= 0.0f) {
+ float time = fallAssoc->currentTime;
+
+ if (time > 0.667f && time - fallAssoc->timeStep <= 0.667f) {
+ fallAssoc->SetCurrentTime(0.0f);
+ fallAssoc->SetRun();
+ }
+ }
+ } else if ((bKnockedUpIntoAir || bKnockedOffBike) && bIsStanding && !bWasStanding) {
+ fallAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_FALL_ONBACK);
+
+ if (!fallAssoc)
+ fallAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_FALL_ONFRONT);
+
+ if (fallAssoc) {
+ bKnockedUpIntoAir = false;
+ bKnockedOffBike = false;
+ fallAssoc->speed = 3.0f;
+ if (IsPlayer())
+ Say(SOUND_PED_LAND);
+
+ } else {
+ firstPartialAssoc = RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_PARTIAL);
+ if (firstPartialAssoc && !firstPartialAssoc->IsRunning()) {
+ bKnockedUpIntoAir = false;
+ bKnockedOffBike = false;
+ }
+ }
+ }
}
bool
@@ -5189,17 +5324,11 @@ CPed::InTheAir(void)
if (m_vecMoveSpeed.z < 0.0f && !bIsPedDieAnimPlaying) {
if (!DyingOrDead()) {
if (CWorld::ProcessLineOfSight(ourPos, bitBelow, foundCol, foundEnt, true, true, false, true, false, false, false)) {
- if (GetPosition().z - foundCol.point.z < 1.3f
-#ifdef VC_PED_PORTS
- || bIsStanding
-#endif
- )
+ if (GetPosition().z - foundCol.point.z < 1.3f || bIsStanding)
SetLanding();
- } else {
- if (!RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_FALL)) {
- if (m_vecMoveSpeed.z < -0.1f)
- CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_FALL, 4.0f);
- }
+ } else if (m_nPedState != PED_ABSEIL && !RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_FALL)) {
+ if (m_vecMoveSpeed.z < -0.1f)
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_FALL, 4.0f);
}
}
}
@@ -5214,14 +5343,22 @@ CPed::SetLanding(void)
CAnimBlendAssociation *fallAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_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_STD_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_STD_FALL_LAND);
DMAudio.PlayOneShot(m_audioEntityId, SOUND_FALL_LAND, 1.0f);
@@ -5254,26 +5391,23 @@ CPed::SetGetUp(void)
CVehicle *collidingVeh = (CVehicle*)m_pCollidingEntity;
CVehicle *veh = (CVehicle*)CPedPlacement::IsPositionClearOfCars(&GetPosition());
- if (veh && veh->m_vehType != VEHICLE_TYPE_BIKE ||
+ if (veh && veh->m_vehType != VEHICLE_TYPE_BIKE && veh != m_attachedTo ||
collidingVeh && collidingVeh->IsVehicle() && collidingVeh->m_vehType != VEHICLE_TYPE_BIKE
&& ((uint8)(CTimer::GetFrameCounter() + m_randomSeed + 5) % 8 ||
- CCollision::ProcessColModels(GetMatrix(), *GetColModel(), collidingVeh->GetMatrix(), *collidingVeh->GetColModel(),
+ CCollision::ProcessColModels(GetMatrix(), *GetColModel(), collidingVeh->GetMatrix(), *collidingVeh->GetColModel(),
aTempPedColPts, nil, nil) > 0)) {
bGetUpAnimStarted = false;
if (IsPlayer())
InflictDamage(nil, WEAPONTYPE_RUNOVERBYCAR, CTimer::GetTimeStep(), PEDPIECE_TORSO, 0);
- else {
- if (!CPad::GetPad(0)->ArePlayerControlsDisabled())
- return;
-
+ else if(CPad::GetPad(0)->ArePlayerControlsDisabled())
InflictDamage(nil, WEAPONTYPE_RUNOVERBYCAR, 1000.0f, PEDPIECE_TORSO, 0);
- }
return;
}
bGetUpAnimStarted = true;
m_pCollidingEntity = nil;
bKnockedUpIntoAir = false;
+ bKnockedOffBike = false;
CAnimBlendAssociation *animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_RUNFAST);
if (animAssoc) {
if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_RUN)) {
@@ -5284,12 +5418,21 @@ CPed::SetGetUp(void)
animAssoc->flags |= ASSOC_DELETEFADEDOUT;
}
- if (RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_FRONTAL))
+ if (m_nWaitState == WAITSTATE_SUN_BATHE_IDLE) {
+ m_headingRate = 0.0f;
+
+ // Seemingly they planned to use different getup anims for different conditions, but sadly in final game all getup anims(GETUP1, GETUP2, GETUP3) are same...
+ if (bFleeWhenStanding && m_threatEx)
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_GET_UP, 1000.0f);
+ else
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_GET_UP, 1000.0f);
+
+ } else if (RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_FRONTAL))
animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_GET_UP_FRONT, 1000.0f);
else
animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_GET_UP, 1000.0f);
- animAssoc->SetFinishCallback(PedGetupCB,this);
+ animAssoc->SetFinishCallback(PedGetupCB, this);
} else {
m_fHealth = 0.0f;
SetDie(ANIM_STD_NUM, 4.0f, 0.0f);
@@ -5317,6 +5460,27 @@ CPed::Mug(void)
}
}
+// Unused
+void
+CPed::SetLook(float direction)
+{
+ if (IsPedInControl()) {
+ SetStoredState();
+ SetPedState(PED_LOOK_HEADING);
+ SetLookFlag(direction, false);
+ }
+}
+
+void
+CPed::SetLook(CEntity* to)
+{
+ if (IsPedInControl()) {
+ SetStoredState();
+ SetPedState(PED_LOOK_ENTITY);
+ SetLookFlag(to, false);
+ }
+}
+
void
CPed::SetLookTimer(int time)
{
@@ -5350,7 +5514,7 @@ CPed::ClearLook(void)
void
CPed::Look(void)
{
- // UNUSED: This is a perfectly empty function.
+ TurnBody();
}
bool
@@ -5390,14 +5554,10 @@ void
CPed::SetSeek(CVector pos, float distanceToCountDone)
{
if (!IsPedInControl()
- || (m_nPedState == PED_SEEK_POS && m_vecSeekPos.x == pos.x && m_vecSeekPos.y == pos.y))
+ || (m_nPedState == PED_SEEK_POS && m_vecSeekPos.x == pos.x && m_vecSeekPos.y == pos.y) || m_nPedState == PED_FOLLOW_PATH)
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)->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM)) {
ClearPointGunAt();
}
@@ -5408,7 +5568,6 @@ CPed::SetSeek(CVector pos, float distanceToCountDone)
m_distanceToCountSeekDone = distanceToCountDone;
m_vecSeekPos = pos;
}
-
void
CPed::SetSeek(CEntity *seeking, float distanceToCountDone)
{
@@ -5418,7 +5577,7 @@ CPed::SetSeek(CEntity *seeking, float distanceToCountDone)
if (m_nPedState == PED_SEEK_ENTITY && m_pSeekTarget == seeking)
return;
- if (!seeking)
+ if (!seeking || m_nPedState == PED_FOLLOW_PATH)
return;
if (m_nPedState != PED_SEEK_ENTITY)
@@ -5450,13 +5609,13 @@ CPed::Seek(void)
m_objective != OBJECTIVE_ENTER_CAR_AS_PASSENGER && m_objective != OBJECTIVE_SOLICIT_VEHICLE && !bDuckAndCover) {
if ((!m_pedInObjective || !m_pedInObjective->bInVehicle)
- && !((CTimer::GetFrameCounter() + (m_randomSeed % 256) + 17) & 7)) {
+ && (CTimer::GetFrameCounter() + m_randomSeed + 60) % 32 == 0) {
CEntity *obstacle = CWorld::TestSphereAgainstWorld(m_vecSeekPos, 0.4f, nil,
false, true, false, false, false, false);
if (obstacle) {
- if (!obstacle->IsVehicle() || ((CVehicle*)obstacle)->m_vehType == VEHICLE_TYPE_CAR) {
+ if (!obstacle->IsVehicle() || ((CVehicle*)obstacle)->IsCar()) {
distanceToCountItDone = 2.5f;
} else {
CVehicleModelInfo *vehModel = (CVehicleModelInfo *)CModelInfo::GetModelInfo(obstacle->GetModelIndex());
@@ -5472,6 +5631,13 @@ CPed::Seek(void)
if (!m_pSeekTarget && m_nPedState == PED_SEEK_ENTITY)
ClearSeek();
+ if (m_objective == OBJECTIVE_FOLLOW_CHAR_IN_FORMATION && !m_pedInObjective) {
+ m_objective = OBJECTIVE_NONE;
+ ClearObjective();
+ SetWanderPath(0);
+ return false;
+ }
+
float seekPosDist = (m_vecSeekPos - GetPosition()).Magnitude2D();
if (seekPosDist < 2.0f || m_objective == OBJECTIVE_GOTO_AREA_ON_FOOT) {
@@ -5484,7 +5650,9 @@ CPed::Seek(void)
} else if (m_objective != OBJECTIVE_FOLLOW_CHAR_IN_FORMATION) {
- if (m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT || m_objective == OBJECTIVE_KILL_CHAR_ANY_MEANS || m_objective == OBJECTIVE_RUN_TO_AREA || bIsRunning)
+ if (m_objective == OBJECTIVE_SPRINT_TO_AREA)
+ nextMove = PEDMOVE_SPRINT;
+ else if (m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT || m_objective == OBJECTIVE_KILL_CHAR_ANY_MEANS || m_objective == OBJECTIVE_RUN_TO_AREA || bIsRunning)
nextMove = PEDMOVE_RUN;
else
nextMove = PEDMOVE_WALK;
@@ -5505,8 +5673,10 @@ CPed::Seek(void)
}
}
- if (seekPosDist >= distanceToCountItDone) {
- if (bIsRunning)
+ CVector *nextNode = SeekFollowingPath();
+
+ if (nextNode || seekPosDist >= distanceToCountItDone) {
+ if (bIsRunning && nextMove != PEDMOVE_SPRINT)
nextMove = PEDMOVE_RUN;
if (CTimer::GetTimeInMilliseconds() <= m_nPedStateTimer) {
@@ -5538,14 +5708,21 @@ CPed::Seek(void)
CVector2D moveDist(GetPosition().x - m_actionX, GetPosition().y - m_actionY);
if (moveDist.Magnitude() < 0.5f) {
m_nPedStateTimer = 0;
- m_actionX = 0;
- m_actionY = 0;
+ m_actionX = 0.f;
+ m_actionY = 0.f;
}
}
+
} else {
- m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(
- m_vecSeekPos.x, m_vecSeekPos.y,
- GetPosition().x, GetPosition().y);
+ if (nextNode) {
+ m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(
+ nextNode->x, nextNode->y,
+ GetPosition().x, GetPosition().y);
+ } else {
+ m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(
+ m_vecSeekPos.x, m_vecSeekPos.y,
+ GetPosition().x, GetPosition().y);
+ }
float neededTurn = Abs(m_fRotationDest - m_fRotationCur);
@@ -5553,7 +5730,7 @@ CPed::Seek(void)
neededTurn = TWOPI - neededTurn;
if (neededTurn > HALFPI) {
- if (seekPosDist >= 1.0 && neededTurn <= DEGTORAD(135.0f)) {
+ if (seekPosDist >= 1.0f && neededTurn <= DEGTORAD(135.0f)) {
if (seekPosDist < 2.0f)
nextMove = PEDMOVE_WALK;
} else {
@@ -5563,7 +5740,7 @@ CPed::Seek(void)
}
if (((m_nPedState == PED_FLEE_POS || m_nPedState == PED_FLEE_ENTITY) && m_nMoveState < nextMove)
- || (m_nPedState != PED_FLEE_POS && m_nPedState != PED_FLEE_ENTITY && m_objective != OBJECTIVE_GOTO_CHAR_ON_FOOT && m_nWaitState == WAITSTATE_FALSE)) {
+ || (m_nPedState != PED_FLEE_POS && m_nPedState != PED_FLEE_ENTITY && m_nPedState != PED_FOLLOW_PATH && m_objective != OBJECTIVE_GOTO_CHAR_ON_FOOT && m_nWaitState == WAITSTATE_FALSE)) {
SetMoveState(nextMove);
}
@@ -5574,11 +5751,13 @@ CPed::Seek(void)
if ((m_objective != OBJECTIVE_FOLLOW_CHAR_IN_FORMATION || m_pedInObjective->m_nMoveState == PEDMOVE_STILL) && m_nMoveState != PEDMOVE_STILL) {
m_nPedStateTimer = 0;
- m_actionX = 0;
- m_actionY = 0;
+ m_actionX = 0.f;
+ m_actionY = 0.f;
}
- if (m_objective == OBJECTIVE_GOTO_AREA_ON_FOOT || m_objective == OBJECTIVE_RUN_TO_AREA || m_objective == OBJECTIVE_GOTO_AREA_ANY_MEANS) {
+ if (m_objective == OBJECTIVE_GOTO_AREA_ON_FOOT || m_objective == OBJECTIVE_RUN_TO_AREA || m_objective == OBJECTIVE_SPRINT_TO_AREA ||
+ m_objective == OBJECTIVE_GOTO_AREA_ANY_MEANS || IsUseAttractorObjective(m_objective)) {
+
if (m_pNextPathNode)
m_pNextPathNode = nil;
else
@@ -5587,9 +5766,6 @@ CPed::Seek(void)
bUsePedNodeSeek = true;
}
- if (SeekFollowingPath(nil))
- m_nCurPathNode++;
-
return true;
}
@@ -5603,8 +5779,7 @@ CPed::SetFlee(CVector2D const &from, int time)
SetStoredState();
SetPedState(PED_FLEE_POS);
SetMoveState(PEDMOVE_RUN);
- m_fleeFromPosX = from.x;
- m_fleeFromPosY = from.y;
+ m_fleeFromPos = from;
}
bUsePedNodeSeek = true;
@@ -5673,11 +5848,14 @@ CPed::Flee(void)
}
if (mayFinishFleeing) {
+ bMakeFleeScream = false;
eMoveState moveState = m_nMoveState;
ClearFlee();
- if (m_objective == OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE || m_objective == OBJECTIVE_FLEE_CHAR_ON_FOOT_ALWAYS)
+ if (m_objective == OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE || m_objective == OBJECTIVE_FLEE_CHAR_ON_FOOT_ALWAYS) {
+ bBeingChasedByPolice = false;
RestorePreviousObjective();
+ }
if ((m_nPedState == PED_IDLE || m_nPedState == PED_WANDER_PATH) && CGeneral::GetRandomNumber() & 1) {
SetWaitState(moveState <= PEDMOVE_WALK ? WAITSTATE_CROSS_ROAD_LOOK : WAITSTATE_FINISH_FLEE, nil);
@@ -5687,6 +5865,11 @@ CPed::Flee(void)
m_fleeTimer = CTimer::GetTimeInMilliseconds() + 5000;
}
+ if (bMakeFleeScream && !((CTimer::GetFrameCounter() + m_randomSeed) & 7)) {
+ Say(SOUND_PED_FLEE_SPRINT);
+ bMakeFleeScream = false;
+ }
+
if (bUsePedNodeSeek) {
CPathNode *realLastNode = nil;
uint8 nextDirection = 0;
@@ -5710,7 +5893,7 @@ CPed::Flee(void)
}
if (m_pNextPathNode) {
- m_vecSeekPos = m_pNextPathNode->GetPosition();
+ m_vecSeekPos = CPathFind::TakeWidthIntoAccountForWandering(m_pNextPathNode, m_randomSeed);
if (m_nMoveState == PEDMOVE_RUN)
bIsRunning = true;
@@ -5764,22 +5947,6 @@ CPed::Flee(void)
m_fRotationDest -= TWOPI;
}
- if (CTimer::GetTimeInMilliseconds() & 0x20) {
- //CVector forwardPos = GetPosition();
- CMatrix forwardMat(GetMatrix());
- forwardMat.GetPosition() += Multiply3x3(forwardMat, CVector(0.0f, 4.0f, 0.0f));
- CVector forwardPos = forwardMat.GetPosition();
-
- CEntity *foundEnt;
- CColPoint foundCol;
- bool found = CWorld::ProcessVerticalLine(forwardPos, forwardMat.GetPosition().z - 100.0f, foundCol, foundEnt, 1, 0, 0, 0, 1, 0, 0);
-
- if (!found || Abs(forwardPos.z - forwardMat.GetPosition().z) > 1.0f) {
- m_fRotationDest += DEGTORAD(112.5f);
- m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 2000;
- }
- }
-
if (CTimer::GetTimeInMilliseconds() >= m_collidingThingTimer)
return;
@@ -5789,7 +5956,6 @@ CPed::Flee(void)
double collidingThingPriorityMult = (double)(m_collidingThingTimer - CTimer::GetTimeInMilliseconds()) * 2.0 / 2500;
if (collidingThingPriorityMult <= 1.5) {
-
double angleToFleeEntity = CGeneral::GetRadianAngleBetweenPoints(
GetPosition().x,
GetPosition().y,
@@ -5863,6 +6029,9 @@ CPed::SetWanderPath(int8 pathStateDest)
{
uint8 nextPathState;
+ if (IsPlayer())
+ return false;
+
if (IsPedInControl()) {
if (bKindaStayInSamePlace) {
SetIdle();
@@ -5915,14 +6084,14 @@ CPed::WanderPath(void)
if (m_nMoveState == PEDMOVE_STILL || m_nMoveState == PEDMOVE_NONE)
SetMoveState(PEDMOVE_WALK);
}
- m_vecSeekPos = m_pNextPathNode->GetPosition();
+ m_vecSeekPos = CPathFind::TakeWidthIntoAccountForWandering(m_pNextPathNode, m_randomSeed);
m_vecSeekPos.z += 1.0f;
// Only returns true when ped is stuck(not stopped) I think, then we should assign new direction or wait state to him.
if (!Seek())
return;
- CPathNode *previousLastNode = m_pLastPathNode;
+ CPathNode *previousLastNode = m_pLastPathNode;
uint8 randVal = (m_randomSeed + 3 * CTimer::GetFrameCounter()) % 100;
// We don't prefer 180-degree turns in normal situations
@@ -5935,6 +6104,8 @@ CPed::WanderPath(void)
CPathNode *nodeWeWouldntPrefer = nil;
uint8 dirToSet = 9; // means undefined
uint8 dirWeWouldntPrefer2 = 9; // means undefined
+ uint8 tryCount = 0;
+
if (randVal <= 90) {
if (randVal > 80) {
m_nPathDir += 2;
@@ -5950,7 +6121,13 @@ CPed::WanderPath(void)
ThePaths.FindNextNodeWandering(PATH_PED, GetPosition(), &m_pLastPathNode, &m_pNextPathNode,
m_nPathDir, &dirToSet);
- uint8 tryCount = 0;
+ if (((CPedModelInfo*)CModelInfo::GetModelInfo(m_modelIndex))->m_pedStatType == PEDSTAT_SKATER) {
+ if (m_pNextPathNode) {
+ CVector unpacked(m_pNextPathNode->GetPosition() / 8.f);
+ if (!CPopulation::IsSkateable(unpacked))
+ m_pNextPathNode = nil;
+ }
+ }
// NB: SetWanderPath checks for m_nPathDir == dirToStartWith, this one checks for tryCount > 7
while (!m_pNextPathNode) {
@@ -5978,6 +6155,13 @@ CPed::WanderPath(void)
m_pNextPathNode = nil;
}
}
+ if (((CPedModelInfo*)CModelInfo::GetModelInfo(m_modelIndex))->m_pedStatType == PEDSTAT_SKATER) {
+ if (m_pNextPathNode) {
+ CVector unpacked(m_pNextPathNode->GetPosition() / 8.f);
+ if (!CPopulation::IsSkateable(unpacked))
+ m_pNextPathNode = nil;
+ }
+ }
}
}
@@ -5995,7 +6179,6 @@ CPed::WanderPath(void)
Say(SOUND_PED_WAIT_DOUBLEBACK);
}
}
-
void
CPed::Avoid(void)
{
@@ -6044,68 +6227,567 @@ CPed::Avoid(void)
}
}
-bool
-CPed::SeekFollowingPath(CVector *unused)
+CVector*
+CPed::SeekFollowingPath(void)
{
- return m_nCurPathNode <= m_nPathNodes && m_nPathNodes;
+ static CVector vecNextPathNode;
+
+ if (m_nCurPathNodeId >= m_nNumPathNodes || m_nNumPathNodes == 0)
+ return nil;
+
+ vecNextPathNode = m_pathNodesToGo[m_nCurPathNodeId]->GetPosition();
+
+ if ((vecNextPathNode - GetPosition()).Magnitude2D() < m_distanceToCountSeekDone) {
+ m_nCurPathNodeId++;
+ if (m_nCurPathNodeId < m_nNumPathNodes)
+ m_pCurPathNode = m_pathNodesToGo[m_nCurPathNodeId];
+ }
+ if (m_nCurPathNodeId == m_nNumPathNodes)
+ return nil;
+ else
+ return &vecNextPathNode;
}
bool
-CPed::SetFollowPath(CVector dest)
+CPed::SetFollowPath(CVector dest, float radius, eMoveState state, CEntity* walkAroundEnt, CEntity* targetEnt, int time)
{
- if (m_nPedState == PED_FOLLOW_PATH)
- return false;
+ if (m_nPedState == PED_FOLLOW_PATH) {
+ bool stopFollow = false;
+ if (walkAroundEnt && walkAroundEnt != m_followPathWalkAroundEnt || !walkAroundEnt && m_followPathWalkAroundEnt
+ || targetEnt && targetEnt != m_followPathTargetEnt || !targetEnt && m_followPathTargetEnt) {
+ stopFollow = true;
- if (FindPlayerPed() != this)
- return false;
+ } else if (targetEnt) {
+ if ((targetEnt->GetPosition() - m_followPathDestPos).MagnitudeSqr() > 1.f)
+ stopFollow = true;
- if ((dest - GetPosition()).Magnitude() <= 2.0f)
- return false;
+ } else if (!walkAroundEnt && !targetEnt) {
+ if ((dest - m_followPathDestPos).MagnitudeSqr() > 1.f)
+ stopFollow = true;
+ }
- CVector pointPoses[7];
- int16 pointsFound;
- CPedPath::CalcPedRoute(0, GetPosition(), dest, pointPoses, &pointsFound, 7);
- for(int i = 0; i < pointsFound; i++) {
- m_stPathNodeStates[i].x = pointPoses[i].x;
- m_stPathNodeStates[i].y = pointPoses[i].y;
+ if (!stopFollow)
+ return false;
}
+ m_pathNodeTimer = CTimer::GetTimeInMilliseconds() + time;
+ m_followPathWalkAroundEnt = walkAroundEnt;
+ m_followPathTargetEnt = targetEnt;
+ m_distanceToCountSeekDone = 0.5f;
- m_nCurPathNode = 0;
- m_nPathNodes = pointsFound;
- if (m_nPathNodes < 1)
- return false;
+ bool weHaveTargetPed = targetEnt && targetEnt->IsPed();
+ bool useDestVec = !weHaveTargetPed;
- SetStoredState();
- SetPedState(PED_FOLLOW_PATH);
- SetMoveState(PEDMOVE_WALK);
- return true;
+ if (useDestVec)
+ m_followPathDestPos = dest;
+ else
+ m_followPathDestPos = targetEnt->GetPosition();
+
+ if (targetEnt && m_nPedState == PED_SEEK_POS) {
+ m_followPathDestPos = m_vecSeekPos;
+ }
+
+ m_followPathAbortDist = radius > 0.f ? radius : 20.f;
+
+ bool useGivenPedMove = state == PEDMOVE_RUN || state == PEDMOVE_WALK;
+ if (useGivenPedMove)
+ m_followPathMoveState = state;
+ else
+ m_followPathMoveState = PEDMOVE_WALK;
+
+ if (m_followPathWalkAroundEnt)
+ return SetFollowPathDynamic();
+ else
+ return SetFollowPathStatic();
}
-void
-CPed::FollowPath(void)
+bool
+CPed::SetFollowPathStatic(void)
{
- m_vecSeekPos.x = m_stPathNodeStates[m_nCurPathNode].x;
- m_vecSeekPos.y = m_stPathNodeStates[m_nCurPathNode].y;
- m_vecSeekPos.z = GetPosition().z;
+ ClearFollowPath();
+ if (sq(m_followPathAbortDist) > (GetPosition() - m_followPathDestPos).MagnitudeSqr()
+ && CWorld::IsWanderPathClear(GetPosition(), m_followPathDestPos, 0.5f, 4)) {
+
+ RestorePreviousState();
+ if (m_objective == OBJECTIVE_NONE) {
+ if (m_followPathMoveState == PEDMOVE_RUN)
+ SetObjective(OBJECTIVE_RUN_TO_AREA, m_followPathDestPos);
+ else
+ SetObjective(OBJECTIVE_GOTO_AREA_ON_FOOT, m_followPathDestPos);
+ }
+ SetPedState(PED_NONE);
+ } else {
+ ThePaths.DoPathSearch(PATH_PED, GetPosition(), -1, m_followPathDestPos, m_pathNodesToGo, &m_nNumPathNodes,
+ ARRAY_SIZE(m_pathNodesToGo), nil, nil, 999999.9f, -1);
+
+ if (m_nNumPathNodes != 0) {
+ if (m_nNumPathNodes > 0 && m_pathNodesToGo[0] != m_pCurPathNode) {
+ for (int i = 0; i < ARRAY_SIZE(m_pathNodesToGo) - 1; i++) {
+ m_pathNodesToGo[i] = m_pathNodesToGo[i+1];
+ }
+ --m_nNumPathNodes;
+ }
+ for (int i = 0; i < m_nNumPathNodes; ++i) {
+ CVector nodePos = m_pathNodesToGo[i]->GetPosition();
+ if (sq(m_followPathAbortDist) > (nodePos - m_followPathDestPos).MagnitudeSqr()
+ && CWorld::IsWanderPathClear(nodePos, m_followPathDestPos, 0.5f, 4)) {
+
+ m_nNumPathNodes = i + 1;
+ break;
+ }
+ }
+
+ m_nCurPathNodeId = 0;
+ if (m_pCurPathNode) {
+ for (int j = 0; j < m_nNumPathNodes; ++j) {
+ if (m_pathNodesToGo[j] == m_pCurPathNode) {
+ m_nCurPathNodeId = j;
+ break;
+ }
+ }
+ }
+ m_pCurPathNode = m_pathNodesToGo[m_nCurPathNodeId];
+ PedState oldLastState = m_nLastPedState;
+ m_nLastPedState = PED_NONE;
+ SetStoredState();
+ if (m_nLastPedState == PED_NONE)
+ m_nLastPedState = oldLastState;
+
+ SetPedState(PED_FOLLOW_PATH);
+ SetMoveState(m_followPathMoveState);
+ } else {
+ RestorePreviousState();
+ if (m_objective == OBJECTIVE_NONE) {
+ if (m_followPathMoveState == PEDMOVE_RUN)
+ SetObjective(OBJECTIVE_RUN_TO_AREA, m_followPathDestPos);
+ else
+ SetObjective(OBJECTIVE_GOTO_AREA_ON_FOOT, m_followPathDestPos);
+ }
+ SetPedState(PED_NONE);
+ }
+ }
+ return true;
+}
+
+bool
+CPed::SetFollowPathDynamic(void)
+{
+ CVector colBoxMin = m_followPathWalkAroundEnt->GetColModel()->boundingBox.min + CVector(-0.35f, -0.35f, 0.f);
+ CVector colBoxMax = m_followPathWalkAroundEnt->GetColModel()->boundingBox.max + CVector(0.35f, 0.35f, 0.f);
+
+ CVector colCornerOffsets[4]; // BL, BR, TR, TL
+ colCornerOffsets[0] = CVector(colBoxMin.x, colBoxMin.y, 0.f);
+ colCornerOffsets[1] = CVector(colBoxMax.x, colBoxMin.y, 0.f);
+ colCornerOffsets[2] = CVector(colBoxMax.x, colBoxMax.y, 0.f);
+ colCornerOffsets[3] = CVector(colBoxMin.x, colBoxMax.y, 0.f);
+
+ if (m_followPathWalkAroundEnt->IsVehicle() && ((CVehicle*)m_followPathWalkAroundEnt)->IsUpsideDown()) {
+ CVector old0 = colCornerOffsets[0];
+ colCornerOffsets[0] = colCornerOffsets[1];
+ colCornerOffsets[1] = old0;
+ CVector old2 = colCornerOffsets[2];
+ colCornerOffsets[2] = colCornerOffsets[3];
+ colCornerOffsets[3] = old2;
+ }
+
+ CVector colCornerPos[4]; // global. again BL, BR, TR, TL
+ float dotProdCorrection[4];
+ CVector colBoxPlaneNormal[4];
+
+ for (int i=0; i<4; i++) {
+ colCornerPos[i] = m_followPathWalkAroundEnt->GetMatrix() * colCornerOffsets[i];
+ colCornerPos[i].z = GetPosition().z;
+ }
+
+ CVector prevColCorner = colCornerPos[3]; // top left
+ CVector *curCornerPos;
+ CVector fwdToNextCorner;
+
+ for (int i=0; i<4; i++) {
+ curCornerPos = &colCornerPos[i];
+ fwdToNextCorner = *curCornerPos - prevColCorner;
+ fwdToNextCorner.Normalise();
+ colBoxPlaneNormal[i] = CrossProduct(fwdToNextCorner, CVector(0.f, 0.f, 1.f));
+ dotProdCorrection[i] = -DotProduct(prevColCorner, colBoxPlaneNormal[i]); // yes, dp with global coord, as if in distance to plane calculation
+ prevColCorner = *curCornerPos;
+ }
+
+ bool weReGoingGreat = false;
+ CVector startVecCandidate = GetPosition();
+ CVector targetVecCandidate = m_followPathDestPos;
+ CVector dirToGo = targetVecCandidate - startVecCandidate;
+ dirToGo.Normalise();
+ CVector ourPos = startVecCandidate;
- // Mysterious code
-/* int v4 = 0;
- int maxNodeIndex = m_nPathNodes - 1;
- if (maxNodeIndex > 0) {
- if (maxNodeIndex > 8) {
- while (v4 < maxNodeIndex - 8)
- v4 += 8;
+ for (int i=0; i<4; i++) {
+ CVector curPlaneNormal = colBoxPlaneNormal[i];
+ float minusGlobalCornerPos = dotProdCorrection[i];
+ float startVecDistToPlane = DotProduct(curPlaneNormal, startVecCandidate) + minusGlobalCornerPos;
+
+#define FRONT_OF_PLANE 1
+#define ON_THE_PLANE 0
+#define BEHIND_THE_PLANE -1
+
+ int8 startVecStatus;
+ int8 targetVecStatus;
+
+ if (startVecDistToPlane > 0.1f)
+ startVecStatus = FRONT_OF_PLANE;
+ else if (startVecDistToPlane < -0.1f)
+ startVecStatus = BEHIND_THE_PLANE;
+ else
+ startVecStatus = ON_THE_PLANE;
+
+ float targetVecDistToPlane = DotProduct(curPlaneNormal, targetVecCandidate) + minusGlobalCornerPos;
+ if (targetVecDistToPlane > 0.1f)
+ targetVecStatus = FRONT_OF_PLANE;
+ else if (targetVecDistToPlane < -0.1f)
+ targetVecStatus = BEHIND_THE_PLANE;
+ else
+ targetVecStatus = ON_THE_PLANE;
+
+
+ if (startVecStatus == BEHIND_THE_PLANE || targetVecStatus == BEHIND_THE_PLANE) {
+ if (startVecStatus == BEHIND_THE_PLANE && targetVecStatus == FRONT_OF_PLANE) {
+ targetVecCandidate = -(DotProduct(ourPos, curPlaneNormal) + minusGlobalCornerPos) / DotProduct(dirToGo, curPlaneNormal) * dirToGo + ourPos;
+
+ } else if (startVecStatus == FRONT_OF_PLANE && targetVecStatus == BEHIND_THE_PLANE) {
+ startVecCandidate = -(DotProduct(ourPos, curPlaneNormal) + minusGlobalCornerPos) / DotProduct(dirToGo, curPlaneNormal) * dirToGo + ourPos;
+ }
+ } else {
+ weReGoingGreat = true;
+ if (startVecStatus == ON_THE_PLANE)
+ startVecCandidate += (0.1f - startVecDistToPlane) * curPlaneNormal;
+
+ if (targetVecStatus == ON_THE_PLANE)
+ targetVecCandidate += (0.1f - targetVecDistToPlane) * curPlaneNormal;
}
+#undef FRONT_OF_PLANE
+#undef ON_THE_PLANE
+#undef BEHIND_THE_PLANE
+ }
+
+ if (!weReGoingGreat) {
+ CVector avgOfColPoints = (colCornerPos[0] + colCornerPos[1] + colCornerPos[2] + colCornerPos[3]) / 4.f;
+ float radius = 0.0f;
+
+ // Find radius of col box of the entity we follow
+ for (int i=0; i<4; i++) {
+ float cornerDist = (colCornerPos[i] - avgOfColPoints).MagnitudeSqr();
- while (v4 < maxNodeIndex)
- v4++;
+ if (cornerDist > radius)
+ radius = cornerDist;
+ }
+ CColSphere followedEntSphere;
+ followedEntSphere.Set(Sqrt(radius) * 1.1f, avgOfColPoints, 0, 0);
+ CVector distToDest = m_followPathDestPos - GetPosition();
+ distToDest.z = 0.f;
+
+ if (distToDest.Magnitude() == 0.0f)
+ return false;
+ distToDest.Normalise();
+
+ // Entity we follow doesn't go toward destination anymore, abort the following.
+ if (!followedEntSphere.IntersectRay(GetPosition(), distToDest, startVecCandidate, targetVecCandidate)) {
+ m_pathNodeTimer = 0;
+ if (m_nPedState == PED_FOLLOW_PATH)
+ RestorePreviousState();
+
+ return false;
+ }
}
-*/
- if (Seek()) {
- m_nCurPathNode++;
- if (m_nCurPathNode == m_nPathNodes)
+
+ int lastPlaneBehindUs = -1;
+ int lastPlaneInFrontOfUs = -1;
+ CVector oldstartVecCandidate = startVecCandidate;
+ CVector oldDirToGo = targetVecCandidate - startVecCandidate;
+ oldDirToGo.Normalise();
+
+
+ // At least one plane should be between target and us.
+ for (int i=0; i<4; i++) {
+ CVector curPlaneNormal = colBoxPlaneNormal[i];
+ float minusGlobalCornerPos = dotProdCorrection[i];
+ float startVecDistToPlane = DotProduct(curPlaneNormal, startVecCandidate) + minusGlobalCornerPos;
+ float targetVecDistToPlane = DotProduct(curPlaneNormal, targetVecCandidate) + minusGlobalCornerPos;
+
+ if (startVecDistToPlane > 0.0f && targetVecDistToPlane < 0.0f) {
+ lastPlaneInFrontOfUs = i;
+ startVecCandidate = -(DotProduct(oldstartVecCandidate, curPlaneNormal) + minusGlobalCornerPos) / DotProduct(oldDirToGo, curPlaneNormal) * oldDirToGo + oldstartVecCandidate;
+
+ } else if (startVecDistToPlane < 0.0f && targetVecDistToPlane > 0.0f) {
+ lastPlaneBehindUs = i;
+ targetVecCandidate = -(DotProduct(oldstartVecCandidate, curPlaneNormal) + minusGlobalCornerPos) / DotProduct(oldDirToGo, curPlaneNormal) * oldDirToGo + oldstartVecCandidate;
+ }
+ }
+
+ CVector destsVariant1[5];
+ CVector destsVariant2[5];
+
+ // If not, followed entity diverged from route and we should abort the following.
+ if (lastPlaneBehindUs >= 0 && lastPlaneInFrontOfUs >= 0) {
+
+ int planeInFrontCircular = (lastPlaneInFrontOfUs + 4) % -4;
+ int planeInFrontCircularMinusOne = (lastPlaneInFrontOfUs + 3) % -4;
+ int planeInBehindCircular = (lastPlaneBehindUs + 4) % -4;
+ int planeInBehindCircularMinusOne = (lastPlaneBehindUs + 3) % -4;
+
+ destsVariant1[0] = GetPosition();
+ destsVariant1[1] = colCornerPos[planeInFrontCircularMinusOne];
+
+ int destsVar1LastNode = 2;
+ for(; planeInFrontCircularMinusOne != planeInBehindCircular; destsVar1LastNode++) {
+ planeInFrontCircularMinusOne = (planeInFrontCircularMinusOne + 3) % -4;
+ destsVariant1[destsVar1LastNode] = colCornerPos[planeInFrontCircularMinusOne];
+ }
+ destsVariant1[destsVar1LastNode] = m_followPathDestPos;
+
+ destsVariant2[0] = GetPosition();
+ destsVariant2[1] = colCornerPos[planeInFrontCircular];
+
+ int destsVar2LastNode = 2;
+ for (; planeInFrontCircular != planeInBehindCircularMinusOne; destsVar2LastNode++) {
+ planeInFrontCircular = (planeInFrontCircular + 5) % -4;
+ destsVariant2[destsVar2LastNode] = colCornerPos[planeInFrontCircular];
+ }
+ destsVariant2[destsVar2LastNode] = m_followPathDestPos;
+ CEntity *foundEnt1 = nil;
+ int dests1isOk = true;
+ int nodeToStopDestsVar1 = destsVar1LastNode + 1;
+ CVector avgOfColPoints2 = (colCornerPos[0] + colCornerPos[1] + colCornerPos[2] + colCornerPos[3]) / 4.f;
+
+ CVector prevDestVar1 = destsVariant1[0];
+
+ for (int i = 1; i < destsVar1LastNode + 1; i++) {
+ CVector *curDestVar1 = &destsVariant1[i];
+
+ CVector routeNormalHalf = *curDestVar1 - prevDestVar1;
+ routeNormalHalf.z = 0.f;
+ routeNormalHalf.Normalise();
+ routeNormalHalf *= 0.5f;
+
+ float oldX = -routeNormalHalf.x;
+ routeNormalHalf.z = 0.0f;
+ routeNormalHalf.x = routeNormalHalf.y;
+ routeNormalHalf.y = oldX;
+
+ if (DotProduct(*curDestVar1 - avgOfColPoints2, routeNormalHalf) < 0.0f)
+ routeNormalHalf *= -1.f;
+
+ CColPoint foundCol;
+ bool foundObstacle = CWorld::ProcessLineOfSight(prevDestVar1, *curDestVar1, foundCol, foundEnt1,
+ true, true, true, true, false, false, false, false);
+
+ if (!foundObstacle)
+ foundObstacle = CWorld::ProcessLineOfSight(prevDestVar1 + routeNormalHalf, *curDestVar1 + routeNormalHalf, foundCol, foundEnt1, true, true, true, true, false, false, false, false);
+
+ if (foundObstacle) {
+ if (foundEnt1 == m_followPathWalkAroundEnt || foundEnt1 == this || foundEnt1 == m_pSeekTarget) {
+ foundEnt1 = nil;
+
+ } else {
+ if (!foundEnt1->IsPed()) {
+ dests1isOk = false;
+ nodeToStopDestsVar1 = i;
+ break;
+ }
+ if (((CPed*)foundEnt1)->m_nPedState == PED_IDLE) {
+ dests1isOk = false;
+ nodeToStopDestsVar1 = i;
+ break;
+ }
+ if (DotProduct(*curDestVar1 - prevDestVar1, foundEnt1->GetForward()) < 0.f) {
+ dests1isOk = false;
+ nodeToStopDestsVar1 = i;
+ break;
+ }
+ if (((CPed*)foundEnt1)->m_pedInObjective == this) {
+ dests1isOk = false;
+ nodeToStopDestsVar1 = i;
+ break;
+ }
+ }
+ }
+ prevDestVar1 = *curDestVar1;
+ }
+ CEntity *foundEnt2 = nil;
+ int dests2isOk = true;
+ int nodeToStopDestsVar2 = destsVar2LastNode + 1;
+
+ CVector prevDestVar2 = destsVariant2[0];
+
+ for (int i = 1; i < destsVar2LastNode + 1; i++) {
+ CVector *curDestVar2 = &destsVariant2[i];
+
+ CVector routeNormalHalf = *curDestVar2 - prevDestVar2;
+ routeNormalHalf.z = 0.f;
+ routeNormalHalf.Normalise();
+ routeNormalHalf *= 0.5f;
+
+ float oldX = -routeNormalHalf.x;
+ routeNormalHalf.z = 0.0f;
+ routeNormalHalf.x = routeNormalHalf.y;
+ routeNormalHalf.y = oldX;
+
+ if (DotProduct(*curDestVar2 - avgOfColPoints2, routeNormalHalf) < 0.0f)
+ routeNormalHalf *= -1.f;
+
+ CColPoint foundCol;
+ bool foundObstacle = CWorld::ProcessLineOfSight(prevDestVar2, *curDestVar2, foundCol, foundEnt2,
+ true, true, true, true, false, false, false, false);
+
+ if (!foundObstacle)
+ foundObstacle = CWorld::ProcessLineOfSight(prevDestVar2 + routeNormalHalf, *curDestVar2 + routeNormalHalf, foundCol, foundEnt2, true, true, true, true, false, false, false, false);
+
+ if (foundObstacle) {
+ if (foundEnt2 == m_followPathWalkAroundEnt || foundEnt2 == this || foundEnt2 == m_pSeekTarget) {
+ foundEnt2 = 0;
+ } else {
+ if (!foundEnt2->IsPed()) {
+ dests2isOk = false;
+ nodeToStopDestsVar2 = i;
+ break;
+ }
+ if (((CPed*)foundEnt2)->m_nPedState == PED_IDLE) {
+ dests2isOk = false;
+ nodeToStopDestsVar2 = i;
+ break;
+ }
+ if (DotProduct(*curDestVar2 - prevDestVar2, foundEnt2->GetForward()) < 0.f) {
+ dests2isOk = false;
+ nodeToStopDestsVar2 = i;
+ break;
+ }
+ if (((CPed*)foundEnt2)->m_pedInObjective == this) {
+ dests2isOk = false;
+ nodeToStopDestsVar2 = i;
+ break;
+ }
+ }
+ }
+ prevDestVar2 = *curDestVar2;
+ }
+
+ float destTotalLengthVar1 = 0.0f;
+ for(int i=0; i < destsVar1LastNode; i++){
+ destTotalLengthVar1 += (destsVariant1[i + 1] - destsVariant1[i]).Magnitude();
+ }
+
+ float destTotalLengthVar2 = 0.0f;
+ for (int i = 0; i < destsVar2LastNode; i++) {
+ destTotalLengthVar2 += (destsVariant2[i + 1] - destsVariant2[i]).Magnitude();
+ }
+
+ int destVariantToUse;
+ if (dests1isOk && dests2isOk) {
+ if (destTotalLengthVar1 < destTotalLengthVar2)
+ destVariantToUse = 1;
+ else
+ destVariantToUse = 2;
+
+ } else if (dests1isOk) {
+ destVariantToUse = 1;
+
+ } else if (dests2isOk) {
+ destVariantToUse = 2;
+
+ } else if (nodeToStopDestsVar1 == 1 && nodeToStopDestsVar2 > 1) {
+ destVariantToUse = 2;
+
+ } else if (nodeToStopDestsVar1 > 1 && nodeToStopDestsVar2 == 1) {
+ destVariantToUse = 1;
+
+ } else if (foundEnt1 == foundEnt2) {
+ if (destTotalLengthVar1 < destTotalLengthVar2)
+ destVariantToUse = 1;
+ else
+ destVariantToUse = 2;
+
+ } else if (foundEnt1->GetColModel()->boundingSphere.radius >= foundEnt2->GetColModel()->boundingSphere.radius) {
+ destVariantToUse = 2;
+ } else {
+ destVariantToUse = 1;
+ }
+
+ if (destVariantToUse == 1) {
+ ClearFollowPath();
+ for (int i = 1; i < destsVar1LastNode; i++) {
+ CPathNode* nextNode = &m_pathNodeObjPool[m_nNumPathNodes];
+ nextNode->SetPosition(destsVariant1[i]);
+ m_pathNodesToGo[m_nNumPathNodes++] = nextNode;
+ }
+ } else if (destVariantToUse == 2) {
+ ClearFollowPath();
+ for (int i = 1; i < destsVar2LastNode; i++) {
+ CPathNode *nextNode = &m_pathNodeObjPool[m_nNumPathNodes];
+ nextNode->SetPosition(destsVariant2[i]);
+ m_pathNodesToGo[m_nNumPathNodes++] = nextNode;
+ }
+ }
+ if (m_nNumPathNodes != 0) {
+ PedState oldLastState = m_nLastPedState;
+ m_nLastPedState = PED_NONE;
+ SetStoredState();
+ if (m_nLastPedState == PED_NONE)
+ m_nLastPedState = oldLastState;
+
+ SetPedState(PED_FOLLOW_PATH);
+ SetMoveState(m_followPathMoveState);
+ return true;
+
+ } else {
+ m_pathNodeTimer = 0;
+ if (m_nPedState == PED_FOLLOW_PATH)
+ RestorePreviousState();
+
+ return false;
+ }
+ } else {
+ m_pathNodeTimer = 0;
+ if (m_nPedState == PED_FOLLOW_PATH)
+ RestorePreviousState();
+
+ return false;
+ }
+}
+
+void
+CPed::ClearFollowPath()
+{
+ for (int i = 0; i < ARRAY_SIZE(m_pathNodesToGo); i++) {
+ m_pathNodesToGo[i] = nil;
+ }
+ m_nNumPathNodes = 0;
+ m_nCurPathNodeId = 0;
+}
+
+void
+CPed::FollowPath(void)
+{
+ m_pCurPathNode = m_pathNodesToGo[m_nCurPathNodeId];
+ if (m_pathNodeTimer > 0 && CTimer::GetTimeInMilliseconds() > m_pathNodeTimer) {
+ RestorePreviousState();
+ ClearFollowPath();
+ m_pathNodeTimer = 0;
+ } else {
+ if (m_pathNodesToGo[m_nCurPathNodeId]) {
+ m_vecSeekPos.x = m_pathNodesToGo[m_nCurPathNodeId]->GetPosition().x;
+ m_vecSeekPos.y = m_pathNodesToGo[m_nCurPathNodeId]->GetPosition().y;
+ m_vecSeekPos.z = GetPosition().z;
+
+ if (Seek()) {
+ if (m_nCurPathNodeId == m_nNumPathNodes) {
+ RestorePreviousState();
+ ClearFollowPath();
+ SetFollowPath(m_followPathDestPos, m_followPathAbortDist, m_followPathMoveState, m_followPathWalkAroundEnt,
+ m_followPathTargetEnt, m_pathNodeTimer - CTimer::GetTimeInMilliseconds());
+ }
+ }
+ } else {
RestorePreviousState();
+ ClearFollowPath();
+ m_pathNodeTimer = 0;
+ }
}
}
@@ -6141,8 +6823,8 @@ CPed::SetEvasiveStep(CPhysical *reason, uint8 animType)
SetLookFlag(reason, true);
if ((CGeneral::GetRandomNumber() & 1) && reason->GetModelIndex() != MI_RCBANDIT && animType == 0) {
stepAnim = ANIM_STD_HAILTAXI;
- } else {
+ } else {
float dangerDirection = CGeneral::GetRadianAngleBetweenPoints(
reason->m_vecMoveSpeed.x, reason->m_vecMoveSpeed.y,
0.0f, 0.0f);
@@ -6226,7 +6908,7 @@ CPed::SetEvasiveDive(CPhysical *reason, uint8 onlyRandomJump)
angleToFace = CGeneral::LimitRadianAngle(angleToFace);
m_fRotationCur = CGeneral::LimitRadianAngle(m_fRotationCur);
- // FIX: Peds no more dive into cars. Taken from SetEvasiveStep, last if statement inverted
+ // FIX: Peds no more select dive direction randomly. Taken from SetEvasiveStep, last if statement inverted
#ifdef FIX_BUGS
float vehDirection = CGeneral::GetRadianAngleBetweenPoints(
veh->m_vecMoveSpeed.x, veh->m_vecMoveSpeed.y,
@@ -6261,6 +6943,13 @@ CPed::SetEvasiveDive(CPhysical *reason, uint8 onlyRandomJump)
if (CGeneral::GetRandomNumber() & 7)
return;
}
+
+ // VC's primitve solution to dive direction problem, see above for better one. This part doesn't exist on III at all
+#ifndef FIX_BUGS
+ angleToFace += HALFPI;
+ if (CGeneral::GetRandomNumber() & 1)
+ angleToFace -= PI;
+#endif
Say(SOUND_PED_EVADE);
}
@@ -6295,14 +6984,6 @@ CPed::SetEvasiveDive(CPhysical *reason, uint8 onlyRandomJump)
wanted->RegisterCrime_Immediately(CRIME_SPEEDING, GetPosition(), (uintptr)this, false);
}
}
-#ifdef PEDS_REPORT_CRIMES_ON_PHONE
- else if (reason->IsVehicle()) {
- if (veh->pDriver && veh->pDriver->IsPlayer()) {
- CWanted* wanted = FindPlayerPed()->m_pWanted;
- wanted->RegisterCrime(CRIME_RECKLESS_DRIVING, GetPosition(), (uintptr)this, false);
- }
- }
-#endif
}
void
@@ -6314,12 +6995,11 @@ CPed::PedEvadeCB(CAnimBlendAssociation* animAssoc, void* arg)
ped->ClearLookFlag();
if (ped->m_nPedState == PED_DIVE_AWAY || ped->m_nPedState == PED_STEP_AWAY)
ped->RestorePreviousState();
-
+
} else if (animAssoc->animId == ANIM_STD_EVADE_DIVE) {
ped->bUpdateAnimHeading = true;
ped->ClearLookFlag();
- if (ped->m_nPedState == PED_DIVE_AWAY)
- {
+ if (ped->m_nPedState == PED_DIVE_AWAY) {
ped->m_getUpTimer = CTimer::GetTimeInMilliseconds() + 1;
ped->SetPedState(PED_FALL);
}
@@ -6346,6 +7026,8 @@ CPed::PedEvadeCB(CAnimBlendAssociation* animAssoc, void* arg)
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)
@@ -6356,6 +7038,7 @@ CPed::SetDie(AnimationId animId, float delta, float speed)
if (DyingOrDead())
return;
+ CAnimBlendAssociation *dieAssoc = nil;
if (m_nPedState == PED_FALL || m_nPedState == PED_GETUP)
delta *= 0.5f;
@@ -6363,7 +7046,7 @@ CPed::SetDie(AnimationId animId, float delta, float speed)
ClearAll();
m_fHealth = 0.0f;
if (m_nPedState == PED_DRIVING) {
- if (!IsPlayer())
+ if (!IsPlayer() && (!m_pMyVehicle || !m_pMyVehicle->IsBike()))
FlagToDestroyWhenNextProcessed();
} else if (bInVehicle) {
if (m_pVehicleAnim)
@@ -6376,7 +7059,7 @@ CPed::SetDie(AnimationId animId, float delta, float speed)
if (animId == ANIM_STD_NUM) {
bIsPedDieAnimPlaying = false;
} else {
- CAnimBlendAssociation *dieAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, animId, delta);
+ dieAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, animId, delta);
if (speed > 0.0f)
dieAssoc->speed = speed;
@@ -6390,10 +7073,17 @@ CPed::SetDie(AnimationId animId, float delta, float speed)
Say(SOUND_PED_DEATH);
if (m_nLastPedState == PED_ENTER_CAR || m_nLastPedState == PED_CARJACK)
QuitEnteringCar();
+
if (!bInVehicle)
StopNonPartialAnims();
m_bloodyFootprintCountOrDeathTime = CTimer::GetTimeInMilliseconds();
+ if (!CGame::nastyGame && animId == ANIM_STD_HIT_FLOOR) {
+ if (dieAssoc) {
+ dieAssoc->SetCurrentTime(dieAssoc->hierarchy->totalLength - 0.01f);
+ dieAssoc->SetRun();
+ }
+ }
}
void
@@ -6408,7 +7098,8 @@ CPed::FinishDieAnimCB(CAnimBlendAssociation *animAssoc, void *arg)
void
CPed::SetDead(void)
{
- bUsesCollision = false;
+ if (!RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_DROWN))
+ bUsesCollision = false;
m_fHealth = 0.0f;
if (m_nPedState == PED_DRIVING)
@@ -6424,6 +7115,7 @@ CPed::SetDead(void)
m_currentWeapon = WEAPONTYPE_UNARMED;
CEventList::RegisterEvent(EVENT_INJURED_PED, EVENT_ENTITY_PED, this, nil, 250);
if (this != FindPlayerPed()) {
+ RemoveWeaponAnims(0, -1000.0f);
CreateDeadPedWeaponPickups();
CreateDeadPedMoney();
}
@@ -6444,14 +7136,14 @@ CPed::Die(void)
void
CPed::SetChat(CEntity *chatWith, uint32 time)
{
- if(m_nPedState != PED_CHAT)
+ if (m_nPedState != PED_CHAT) {
+ m_nLastPedState = PED_NONE;
SetStoredState();
+ }
SetPedState(PED_CHAT);
SetMoveState(PEDMOVE_STILL);
-#if defined VC_PED_PORTS || defined FIX_BUGS
m_lookTimer = 0;
-#endif
SetLookFlag(chatWith, true);
m_chatTimer = CTimer::GetTimeInMilliseconds() + time;
m_lookTimer = CTimer::GetTimeInMilliseconds() + 3000;
@@ -6473,6 +7165,7 @@ CPed::Chat(void)
if (partner->m_nPedState != PED_CHAT) {
ClearChat();
+ m_chatTimer = CTimer::GetTimeInMilliseconds() + 30000;
if (partner->m_pedInObjective) {
if (partner->m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT ||
partner->m_objective == OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE)
@@ -6522,67 +7215,30 @@ CPed::ClearChat(void)
bIsTalking = false;
ClearLookFlag();
RestorePreviousState();
-}
-
-#ifdef PEDS_REPORT_CRIMES_ON_PHONE
-void
-ReportPhonePickUpCB(CAnimBlendAssociation* assoc, void* arg)
-{
- CPed* ped = (CPed*)arg;
- ped->m_nMoveState = PEDMOVE_STILL;
- CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_IDLE, 8.0f);
-
- if (assoc->blendAmount > 0.5f && ped) {
- CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_PHONE_TALK, 8.0f);
+ if (m_objective == OBJECTIVE_BUY_ICE_CREAM) {
+ bBoughtIceCream = true;
+ SetObjective(OBJECTIVE_NONE);
+ SetWanderPath(CGeneral::GetRandomNumberInRange(0, 8));
}
}
-void
-ReportPhonePutDownCB(CAnimBlendAssociation* assoc, void* arg)
-{
- assoc->flags |= ASSOC_DELETEFADEDOUT;
- assoc->blendDelta = -1000.0f;
- CPed* ped = (CPed*)arg;
-
- if (ped->m_phoneId != -1 && crimeReporters[ped->m_phoneId] == ped) {
- crimeReporters[ped->m_phoneId] = nil;
- gPhoneInfo.m_aPhones[ped->m_phoneId].m_nState = PHONE_STATE_FREE;
- ped->m_phoneId = -1;
- }
-
- if (assoc->blendAmount > 0.5f)
- ped->bUpdateAnimHeading = true;
-
- ped->SetWanderPath(CGeneral::GetRandomNumber() & 7);
-}
-#endif
-
bool
CPed::FacePhone(void)
{
- // This function was broken since it's left unused early in development.
-#ifdef PEDS_REPORT_CRIMES_ON_PHONE
+ // FIX: This function was broken since it's left unused early in development.
+#ifdef FIX_BUGS
float phoneDir = CGeneral::GetRadianAngleBetweenPoints(
gPhoneInfo.m_aPhones[m_phoneId].m_vecPos.x, gPhoneInfo.m_aPhones[m_phoneId].m_vecPos.y,
GetPosition().x, GetPosition().y);
- if (m_facePhoneStart) {
- m_lookTimer = 0;
- SetLookFlag(phoneDir, true);
- m_lookTimer = CTimer::GetTimeInMilliseconds() + 3000;
- m_facePhoneStart = false;
- }
-
- if (bIsLooking && TurnBody()) {
- ClearLookFlag();
+ SetLookFlag(phoneDir, false);
+ bool turnDone = TurnBody();
+ if (turnDone) {
SetIdle();
+ ClearLookFlag();
m_phoneTalkTimer = CTimer::GetTimeInMilliseconds() + 10000;
- CAnimBlendAssociation* assoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_PHONE_IN, 4.0f);
- assoc->SetFinishCallback(ReportPhonePickUpCB, this);
- return true;
}
-
- return false;
+ return turnDone;
#else
float currentRot = RADTODEG(m_fRotationCur);
float phoneDir = CGeneral::GetRadianAngleBetweenPoints(
@@ -6613,45 +7269,110 @@ CPed::FacePhone(void)
}
#endif
}
+
bool
CPed::MakePhonecall(void)
{
-#ifdef PEDS_REPORT_CRIMES_ON_PHONE
- if (!IsPlayer() && CTimer::GetTimeInMilliseconds() > m_phoneTalkTimer - 7000 && bRunningToPhone) {
-
- FindPlayerPed()->m_pWanted->RegisterCrime_Immediately(m_crimeToReportOnPhone, GetPosition(),
- (m_crimeToReportOnPhone == CRIME_POSSESSION_GUN ? (uintptr)m_threatEntity : (uintptr)m_victimOfPlayerCrime), false);
-
- if (m_crimeToReportOnPhone != CRIME_POSSESSION_GUN)
- FindPlayerPed()->m_pWanted->SetWantedLevelNoDrop(1);
-
- bRunningToPhone = false;
- }
-#endif
if (CTimer::GetTimeInMilliseconds() <= m_phoneTalkTimer)
return false;
-#ifdef PEDS_REPORT_CRIMES_ON_PHONE
- CAnimBlendAssociation* talkAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_PHONE_TALK);
- if (talkAssoc && talkAssoc->blendAmount > 0.5f) {
- CAnimBlendAssociation* endAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_PHONE_OUT, 8.0f);
- endAssoc->flags &= ~ASSOC_DELETEFADEDOUT;
- endAssoc->SetFinishCallback(ReportPhonePutDownCB, this);
- }
-#endif
SetIdle();
-
gPhoneInfo.m_aPhones[m_phoneId].m_nState = PHONE_STATE_FREE;
-#ifndef PEDS_REPORT_CRIMES_ON_PHONE
m_phoneId = -1;
+ return true;
+}
+
+void
+StartTalkingOnMobileCB(CAnimBlendAssociation* assoc, void* arg)
+{
+ CPed* ped = (CPed*)arg;
+ if (ped->m_nPedState == PED_ANSWER_MOBILE)
+ CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_PHONE_TALK, 4.0f);
+}
+
+void
+FinishTalkingOnMobileCB(CAnimBlendAssociation *assoc, void *arg)
+{
+ CPed *ped = (CPed*)arg;
+ if (ped->m_storedWeapon != WEAPONTYPE_UNIDENTIFIED) {
+ ped->RemoveWeaponModel(MI_MOBILE);
+ ped->SetCurrentWeapon(ped->m_storedWeapon);
+ ped->m_storedWeapon = WEAPONTYPE_UNIDENTIFIED;
+ }
+ ped->m_lookTimer = 0;
+}
+
+void
+CPed::SetAnswerMobile(void)
+{
+ if (m_nPedState != PED_ANSWER_MOBILE && !DyingOrDead()) {
+ SetPedState(PED_ANSWER_MOBILE);
+#ifdef FIX_BUGS
+ ClearLookFlag();
#endif
+ RemoveWeaponAnims(GetWeapon()->m_eWeaponType, -4.0f);
+ CAnimBlendAssociation *assoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_PHONE_IN, 4.0f);
+ assoc->SetFinishCallback(StartTalkingOnMobileCB, this);
+ m_lookTimer = INT32_MAX;
+ if (m_storedWeapon == WEAPONTYPE_UNIDENTIFIED)
+ m_storedWeapon = GetWeapon()->m_eWeaponType;
- // Because SetWanderPath is now done async in ReportPhonePutDownCB
-#ifdef PEDS_REPORT_CRIMES_ON_PHONE
- return false;
-#else
- return true;
+#ifdef FIX_BUGS
+ SetCurrentWeapon(0);
#endif
+ RemoveWeaponModel(-1);
+ }
+}
+
+void
+CPed::ClearAnswerMobile(void)
+{
+ if (m_nLastPedState == PED_ANSWER_MOBILE)
+ m_nLastPedState = PED_NONE;
+
+ if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_PHONE_TALK)) {
+ CAnimBlendAssociation *assoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_PHONE_OUT, 8.0f);
+ assoc->SetFinishCallback(FinishTalkingOnMobileCB, this);
+ } else
+ FinishTalkingOnMobileCB(nil, this);
+
+ if (m_nPedState == PED_ANSWER_MOBILE) {
+ m_nPedState = PED_IDLE;
+ RestorePreviousState();
+ m_pVehicleAnim = nil;
+ }
+}
+
+void
+CPed::AnswerMobile(void)
+{
+ if (!IsPedInControl())
+ return;
+
+ CAnimBlendAssociation *phoneInAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_PHONE_IN);
+ CAnimBlendAssociation *phoneOutAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_PHONE_OUT);
+ CAnimBlendAssociation *phoneTalkAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_PHONE_TALK);
+ if (phoneInAssoc || phoneTalkAssoc || phoneOutAssoc) {
+ if (phoneInAssoc) {
+ if (phoneInAssoc->currentTime >= 0.85f && !m_pWeaponModel) {
+ CBaseModelInfo *phoneModel = CModelInfo::GetModelInfo(MI_MOBILE);
+ m_pWeaponModel = (RpAtomic*)phoneModel->CreateInstance();
+ phoneModel->AddRef();
+ m_wepModelID = MI_MOBILE;
+
+ // They copied AddWeaponModel and forgot that here
+ // bool unused = IsPlayer();
+ }
+ } else if (phoneOutAssoc) {
+ if (phoneOutAssoc->currentTime >= 0.5f && phoneOutAssoc->currentTime - phoneOutAssoc->timeStep < 0.5f) {
+ RemoveWeaponModel(MI_MOBILE);
+ SetCurrentWeapon(m_storedWeapon);
+ m_storedWeapon = WEAPONTYPE_UNIDENTIFIED;
+ }
+ }
+ } else {
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_PHONE_TALK, 4.0f);
+ }
}
void
@@ -6673,10 +7394,8 @@ CPed::SetSeekCar(CVehicle *car, uint32 doorNode)
if (m_nPedState == PED_SEEK_CAR)
return;
-#ifdef VC_PED_PORTS
if (!CanSetPedState() || m_nPedState == PED_DRIVING)
return;
-#endif
SetStoredState();
m_pSeekTarget = car;
@@ -6703,7 +7422,7 @@ CPed::SeekCar(void)
}
if (m_objective != OBJECTIVE_ENTER_CAR_AS_PASSENGER) {
- if (m_vehDoor && m_objective != OBJECTIVE_ENTER_CAR_AS_DRIVER) {
+ if (!vehToSeek->IsBike() && m_vehDoor && m_objective != OBJECTIVE_ENTER_CAR_AS_DRIVER) {
if (IsRoomToBeCarJacked()) {
dest = GetPositionToOpenCarDoor(vehToSeek, m_vehDoor);
} else if (m_nPedType == PEDTYPE_COP) {
@@ -6774,14 +7493,10 @@ CPed::SeekCar(void)
bool foundBetterPosToSeek = PossiblyFindBetterPosToSeekCar(&dest, vehToSeek);
m_vecSeekPos = dest;
float distToDestSqr = (m_vecSeekPos - GetPosition()).MagnitudeSqr();
-#ifndef VC_PED_PORTS
- if (bIsRunning)
- SetMoveState(PEDMOVE_RUN);
-#else
+
if (bIsRunning ||
vehToSeek->pDriver && distToDestSqr > sq(2.0f) && (Abs(vehToSeek->m_vecMoveSpeed.x) > 0.01f || Abs(vehToSeek->m_vecMoveSpeed.y) > 0.01f))
SetMoveState(PEDMOVE_RUN);
-#endif
else if (distToDestSqr < sq(2.0f))
SetMoveState(PEDMOVE_WALK);
@@ -6798,10 +7513,13 @@ CPed::SeekCar(void)
// Arrived to the car
if (Seek()) {
if (!foundBetterPosToSeek) {
- if (1.5f + GetPosition().z > dest.z && GetPosition().z - 0.5f < dest.z) {
+ if (1.6f + GetPosition().z > dest.z && GetPosition().z - 0.5f < dest.z) {
+#ifdef GTA_TRAIN
if (vehToSeek->IsTrain()) {
SetEnterTrain(vehToSeek, m_vehDoor);
- } else {
+ } else
+#endif
+ {
m_fRotationCur = m_fRotationDest;
if (!bVehEnterDoorIsBlocked) {
vehToSeek->SetIsStatic(false);
@@ -6817,7 +7535,15 @@ CPed::SeekCar(void)
case STATUS_SIMPLE:
case STATUS_PHYSICS:
case STATUS_PLAYER_DISABLED:
- if (!vehToSeek->bIsBus && (!m_leader || m_leader != vehToSeek->pDriver) &&
+ if (vehToSeek->IsBike()) {
+ if ((!m_leader || m_leader != vehToSeek->pDriver) &&
+ ((m_vehDoor == CAR_DOOR_LF || m_vehDoor == CAR_DOOR_RF || m_vehDoor == CAR_WINDSCREEN) && vehToSeek->pDriver ||
+ (m_vehDoor == CAR_DOOR_LR || m_vehDoor == CAR_DOOR_RR) && vehToSeek->pPassengers[0])) {
+ SetCarJack(vehToSeek);
+ } else {
+ SetEnterCar(vehToSeek, m_vehDoor);
+ }
+ } else if (!vehToSeek->bIsBus && (!m_leader || m_leader != vehToSeek->pDriver) &&
(m_vehDoor == CAR_DOOR_LF && vehToSeek->pDriver || m_vehDoor == CAR_DOOR_RF && vehToSeek->pPassengers[0] || m_vehDoor == CAR_DOOR_LR && vehToSeek->pPassengers[1] || m_vehDoor == CAR_DOOR_RR && vehToSeek->pPassengers[2])) {
SetCarJack(vehToSeek);
if (m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER && m_vehDoor != CAR_DOOR_LF)
@@ -6827,7 +7553,18 @@ CPed::SeekCar(void)
}
break;
case STATUS_ABANDONED:
- if (m_vehDoor == CAR_DOOR_RF && vehToSeek->pPassengers[0]) {
+ if (vehToSeek->IsBike()) {
+ if ((m_vehDoor == CAR_DOOR_LR || m_vehDoor == CAR_DOOR_RR) && vehToSeek->pPassengers[0]) {
+ if (vehToSeek->pPassengers[0]->bDontDragMeOutCar) {
+ if (IsPlayer())
+ SetEnterCar(vehToSeek, m_vehDoor);
+ } else {
+ SetCarJack(vehToSeek);
+ }
+ } else {
+ SetEnterCar(vehToSeek, m_vehDoor);
+ }
+ } else if (m_vehDoor == CAR_DOOR_RF && vehToSeek->pPassengers[0]) {
if (vehToSeek->pPassengers[0]->bDontDragMeOutCar) {
if (IsPlayer())
SetEnterCar(vehToSeek, m_vehDoor);
@@ -6933,8 +7670,13 @@ CPed::CheckForDeadPeds(void)
bool
CPed::IsPlayer(void) const
{
+#if 0
+ return m_nPedType == PEDTYPE_PLAYER1; // Original
+#else
+ // We still have those in enum, so let's also check for them.
return m_nPedType == PEDTYPE_PLAYER1 || m_nPedType == PEDTYPE_PLAYER2 ||
m_nPedType == PEDTYPE_PLAYER3 || m_nPedType == PEDTYPE_PLAYER4;
+#endif
}
bool
@@ -6944,6 +7686,31 @@ CPed::IsGangMember(void) const
}
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();
+}
+
+bool
+IsPedPointerValid_NotInWorld(CPed* pPed)
+{
+ if (!pPed)
+ return false;
+ int index = CPools::GetPedPool()->GetJustIndex_NoFreeAssert(pPed);
+#ifdef FIX_BUGS
+ if (index < 0 || index >= NUMPEDS)
+#else
+ if (index < 0 || index > NUMPEDS)
+#endif
+ return false;
+ return true;
+}
+
+bool
CPed::IsPointerValid(void)
{
int pedIndex = CPools::GetPedPool()->GetIndex(this) >> 8;
@@ -6959,24 +7726,35 @@ CPed::IsPointerValid(void)
void
CPed::SetPedPositionInCar(void)
{
+ bool notYet = false;
if (CReplay::IsPlayingBack())
return;
if (bChangedSeat) {
- bool notYet = false;
- if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_GET_IN_LHS)
- || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_GET_IN_LO_LHS)
- || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_CLOSE_DOOR_LHS)
- || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_CLOSE_DOOR_LO_LHS)
- || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_SHUFFLE_RHS)
- || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_SHUFFLE_LO_RHS)
- || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_VAN_CLOSE_DOOR_REAR_LHS)
- || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_VAN_CLOSE_DOOR_REAR_RHS)
- || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_VAN_GET_IN_REAR_LHS)
- || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_VAN_GET_IN_REAR_RHS)
- || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_COACH_GET_IN_LHS)
- || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_COACH_GET_IN_RHS)) {
- notYet = true;
+ if (m_pMyVehicle->IsBike()) {
+ if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_JUMPON_LHS)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_JUMPON_RHS)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_KICK)) {
+ LineUpPedWithCar(LINE_UP_TO_CAR_START);
+ return;
+ }
+ bChangedSeat = false;
+ } else {
+ if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_GET_IN_LHS)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_GET_IN_LO_LHS)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_CLOSE_DOOR_LHS)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_CLOSE_DOOR_LO_LHS)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_SHUFFLE_RHS)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_SHUFFLE_LO_RHS)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_VAN_CLOSE_DOOR_REAR_LHS)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_VAN_CLOSE_DOOR_REAR_RHS)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_VAN_GET_IN_REAR_LHS)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_VAN_GET_IN_REAR_RHS)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_COACH_GET_IN_LHS)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_COACH_GET_IN_RHS)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_JUMP_IN_LO_LHS)) {
+ notYet = true;
+ }
}
if (notYet) {
LineUpPedWithCar(LINE_UP_TO_CAR_START);
@@ -6989,14 +7767,16 @@ CPed::SetPedPositionInCar(void)
CVector seatPos;
if (m_pMyVehicle->pDriver == this) {
seatPos = vehModel->GetFrontSeatPosn();
- if (!m_pMyVehicle->IsBoat() && m_pMyVehicle->m_vehType != VEHICLE_TYPE_BIKE)
+ if (!m_pMyVehicle->IsBoat() && !m_pMyVehicle->IsBike())
seatPos.x = -seatPos.x;
} else if (m_pMyVehicle->pPassengers[0] == this) {
- seatPos = vehModel->GetFrontSeatPosn();
+ seatPos = m_pMyVehicle->IsBike() ? vehModel->m_positions[CAR_POS_BACKSEAT]: vehModel->GetFrontSeatPosn();
+
} else if (m_pMyVehicle->pPassengers[1] == this) {
seatPos = vehModel->m_positions[CAR_POS_BACKSEAT];
seatPos.x = -seatPos.x;
+
} else {
if (m_pMyVehicle->pPassengers[2] == this) {
seatPos = vehModel->m_positions[CAR_POS_BACKSEAT];
@@ -7004,6 +7784,10 @@ CPed::SetPedPositionInCar(void)
seatPos = vehModel->GetFrontSeatPosn();
}
}
+ if (m_pMyVehicle->IsBike()) {
+ ((CBike*)m_pMyVehicle)->CalculateLeanMatrix();
+ newMat = ((CBike*)m_pMyVehicle)->m_leanMatrix;
+ }
newMat.GetPosition() += Multiply3x3(newMat, seatPos);
// Already done below (SetTranslate(0.0f, 0.0f, 0.0f))
// tempMat.SetUnity();
@@ -7015,6 +7799,7 @@ CPed::SetPedPositionInCar(void)
m_fRotationCur = m_pMyVehicle->GetForward().Heading() - HALFPI;
tempMat.SetTranslate(0.0f, 0.0f, 0.0f);
tempMat.RotateZ(-HALFPI);
+ tempMat.Translate(0.0f, 0.6f, 0.0f);
newMat = newMat * tempMat;
} else if (m_pMyVehicle->pPassengers[2] == this) {
m_fRotationCur = m_pMyVehicle->GetForward().Heading() + HALFPI;
@@ -7036,8 +7821,7 @@ CPed::LookForSexyPeds(void)
if ((!IsPedInControl() && m_nPedState != PED_DRIVING)
|| m_lookTimer >= CTimer::GetTimeInMilliseconds() ||
#ifdef FIX_BUGS
- // gang members have these lines too
- (!IsGangMember() && m_nPedType != PEDTYPE_CIVMALE)
+ (m_nPedType != PEDTYPE_CIVMALE) && !IsFemale() && (m_nPedType != PEDTYPE_CRIMINAL) && !IsGangMember()
#else
m_nPedType != PEDTYPE_CIVMALE
#endif
@@ -7048,17 +7832,20 @@ CPed::LookForSexyPeds(void)
if (CanSeeEntity(m_nearPeds[i])) {
if ((GetPosition() - m_nearPeds[i]->GetPosition()).Magnitude() < 10.0f) {
CPed *nearPed = m_nearPeds[i];
- if ((nearPed->m_pedStats->m_sexiness > m_pedStats->m_sexiness)
+ if((nearPed->m_pedStats->m_sexiness > m_pedStats->m_sexiness)
#ifdef FIX_BUGS
- // react to prostitutes as well
- && ((nearPed->m_nPedType == PEDTYPE_CIVFEMALE) || (nearPed->m_nPedType == PEDTYPE_PROSTITUTE))) {
+ && ((IsFemale() && !nearPed->IsFemale()) || (!IsFemale() && nearPed->IsFemale()))) {
#else
- && nearPed->m_nPedType == PEDTYPE_CIVFEMALE) {
+ && nearPed->m_nPedType == PEDTYPE_CIVFEMALE) {
#endif
SetLookFlag(nearPed, true);
m_lookTimer = CTimer::GetTimeInMilliseconds() + 4000;
- Say(SOUND_PED_CHAT_SEXY);
+#ifdef FIX_BUGS
+ Say(IsFemale() ? SOUND_PED_CHAT_SEXY_FEMALE : SOUND_PED_CHAT_SEXY_MALE);
+#else
+ Say(SOUND_PED_CHAT_SEXY_MALE);
+#endif
return;
}
}
@@ -7238,6 +8025,145 @@ CPed::LookForInterestingNodes(void)
}
void
+PlayRandomAnimationsFromAnimBlock(CPed* ped, AssocGroupId animGroup, uint32 first, uint32 amount)
+{
+ if (!ped->IsPedInControl())
+ return;
+
+ const char *groupName = CAnimManager::GetAnimGroupName(animGroup);
+ CAnimBlock *animBlock = CAnimManager::GetAnimationBlock(groupName);
+ CAnimBlendAssociation *assoc;
+ for (assoc = RpAnimBlendClumpGetFirstAssociation(ped->GetClump()); assoc; assoc = RpAnimBlendGetNextAssociation(assoc)) {
+ int first = animBlock->firstIndex;
+ int index = assoc->hierarchy - CAnimManager::GetAnimation(0);
+ if (index >= first && index < first + animBlock->numAnims) {
+ break;
+ }
+ }
+
+ if (CTimer::GetTimeInMilliseconds() > ped->m_nWaitTimer && assoc)
+ assoc->flags &= ~ASSOC_REPEAT;
+
+ if (!assoc || assoc->blendDelta < 0.0f) {
+ int selectedAnimOffset;
+ do
+ selectedAnimOffset = CGeneral::GetRandomNumberInRange(0, amount);
+ while (assoc && first + selectedAnimOffset == assoc->animId);
+
+ assoc = CAnimManager::BlendAnimation(ped->GetClump(), animGroup, (AnimationId)(first + selectedAnimOffset), 3.0f);
+
+ assoc->SetFinishCallback(CPed::FinishedWaitCB, ped);
+ if (assoc->flags & ASSOC_REPEAT)
+ ped->m_nWaitTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(3000, 8000);
+ else
+ ped->m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 8000;
+ }
+}
+
+void
+CPed::ClearWaitState(void)
+{
+ CAnimBlendAssociation *assoc;
+ 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) {
+ if (m_nWaitState == WAITSTATE_USE_ATM) {
+ assoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_ATM);
+ if (assoc)
+ assoc->blendDelta = -8.0f;
+ if (m_attractor)
+ GetPedAttractorManager()->DeRegisterPed(this, m_attractor);
+
+ } else if (m_nWaitState == WAITSTATE_PLAYANIM_CHAT) {
+ assoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CHAT);
+ if (assoc)
+ assoc->blendDelta = -8.0f;
+ if (m_attractor)
+ GetPedAttractorManager()->DeRegisterPed(this, m_attractor);
+
+ } else if (m_nWaitState == WAITSTATE_SIT_DOWN || m_nWaitState == WAITSTATE_SIT_DOWN_RVRS || m_nWaitState == WAITSTATE_SIT_IDLE || m_nWaitState == WAITSTATE_SIT_UP) {
+ switch (m_nWaitState) {
+ case WAITSTATE_SIT_DOWN:
+ assoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_SEAT_DOWN);
+ if (assoc)
+ assoc->blendDelta = -8.0f;
+ break;
+ case WAITSTATE_SIT_IDLE:
+ assoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_SEAT_IDLE);
+ if (assoc)
+ assoc->blendDelta = -8.0f;
+ break;
+ case WAITSTATE_SIT_UP:
+ assoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_SEAT_UP);
+ if (assoc)
+ assoc->blendDelta = -8.0f;
+ break;
+ default:
+ break;
+ }
+ if (m_attractor)
+ GetPedAttractorManager()->DeRegisterPed(this, m_attractor);
+ }
+ }
+ break;
+ case WAITSTATE_RIOT:
+ {
+ CAnimBlock* riotAnimBlock = CAnimManager::GetAnimationBlock("riot");
+
+ for (assoc = RpAnimBlendClumpGetFirstAssociation(GetClump()); assoc; assoc = RpAnimBlendGetNextAssociation(assoc)) {
+ int first = riotAnimBlock->firstIndex;
+ int index = assoc->hierarchy - CAnimManager::GetAnimation(0);
+ if (index >= first && index < first + riotAnimBlock->numAnims) {
+ assoc->blendDelta = -1000.0f;
+ }
+ }
+ break;
+ }
+ case WAITSTATE_FAST_FALL:
+ if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_HIGHIMPACT_FRONT))
+ SetGetUp();
+
+ break;
+ case WAITSTATE_BOMBER:
+ assoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_DETONATE);
+ if (assoc)
+ assoc->blendDelta = -8.0f;
+ break;
+ case WAITSTATE_STRIPPER:
+ {
+ CAnimBlock* stripAnimBlock = CAnimManager::GetAnimationBlock("strip");
+
+ for (assoc = RpAnimBlendClumpGetFirstAssociation(GetClump()); assoc; assoc = RpAnimBlendGetNextAssociation(assoc)) {
+ int first = stripAnimBlock->firstIndex;
+ int index = assoc->hierarchy - CAnimManager::GetAnimation(0);
+ if (index >= first && index < first + stripAnimBlock->numAnims) {
+ assoc->blendDelta = -1000.0f;
+ }
+ }
+ break;
+ }
+ case WAITSTATE_LANCESITTING:
+ assoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_SUNBATHE_IDLE);
+ if (assoc)
+ assoc->blendDelta = -8.0f;
+ break;
+ case WAITSTATE_PLAYANIM_HANDSUP_SIMPLE:
+ assoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_HANDSUP);
+ if (assoc)
+ assoc->blendDelta = -8.0f;
+ break;
+ default:
+ break;
+ }
+ m_nWaitState = WAITSTATE_FALSE;
+}
+
+void
CPed::SetWaitState(eWaitState state, void *time)
{
AnimationId waitAnim = ANIM_STD_NUM;
@@ -7246,6 +8172,9 @@ CPed::SetWaitState(eWaitState state, void *time)
if (!IsPedInControl())
return;
+ if (m_nWaitState == WAITSTATE_RIOT && state != WAITSTATE_FALSE)
+ return;
+
if (state != m_nWaitState)
FinishedWaitCB(nil, this);
@@ -7271,6 +8200,8 @@ CPed::SetWaitState(eWaitState state, void *time)
case WAITSTATE_LOOK_SHOP:
case WAITSTATE_LOOK_ACCIDENT:
case WAITSTATE_FACEOFF_GANG:
+ case WAITSTATE_RIOT:
+ case WAITSTATE_STRIPPER:
break;
case WAITSTATE_DOUBLEBACK:
m_headingRate = 0.0f;
@@ -7299,7 +8230,6 @@ CPed::SetWaitState(eWaitState state, void *time)
m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 5000;
animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_TURN180, 4.0f);
animAssoc->SetFinishCallback(FinishedWaitCB, this);
- animAssoc->SetDeleteCallback(RestoreHeadingRateCB, this);
break;
case WAITSTATE_SURPRISE:
m_headingRate = 0.0f;
@@ -7317,6 +8247,7 @@ CPed::SetWaitState(eWaitState state, void *time)
animAssoc->SetFinishCallback(RestoreHeadingRateCB, this);
#endif
+ // Random char as passenger? Cop, medic etc.?
if (m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER && CharCreatedBy == RANDOM_CHAR && m_nPedState == PED_SEEK_CAR) {
ClearObjective();
RestorePreviousState();
@@ -7379,8 +8310,72 @@ CPed::SetWaitState(eWaitState state, void *time)
animAssoc->SetFinishCallback(RestoreHeadingRateCB, this);
#endif
break;
+ case WAITSTATE_SIT_DOWN:
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_SEAT_DOWN, 4.0f);
+ animAssoc->SetFinishCallback(FinishedWaitCB, this);
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 100000;
+ break;
+ case WAITSTATE_SIT_UP:
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_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_STD_SEAT_IDLE, 128.f);
+ 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_STD_ATM, 4.0f);
+ animAssoc->SetFinishCallback(FinishedWaitCB, this);
+ if (time)
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + *(int*)time;
+ else
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 100000;
+ break;
+ case WAITSTATE_SUN_BATHE_IDLE:
+ m_headingRate = 0.0f;
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_SUNBATHE, ANIM_SUNBATHE_IDLE, 4.0f);
+ animAssoc->SetDeleteCallback(DeleteSunbatheIdleAnimCB, this);
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(50000, 100000);
+ break;
+ case WAITSTATE_FAST_FALL:
+ SetFall(-1, ANIM_STD_HIGHIMPACT_FRONT, true);
+ break;
+ case WAITSTATE_BOMBER:
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_DETONATE, 4.0f);
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + *(int*)time;
+ break;
+ case WAITSTATE_GROUND_ATTACK:
+ {
+ CWeaponInfo* currentWeapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
+ if (!currentWeapon)
+ break;
+ if (GetFireAnimGround(currentWeapon, false)) {
+ if (!RpAnimBlendClumpGetAssociation(GetClump(), GetFireAnimGround(currentWeapon, false))) {
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 5000;
+ CAnimBlendAssociation* newAnim = CAnimManager::BlendAnimation(GetClump(),
+ currentWeapon->m_AnimToPlay, GetFireAnimGround(currentWeapon, false), 8.0f);
+ newAnim->SetDeleteCallback(FinishedWaitCB, this);
+ }
+ }
+ break;
+ }
+ case WAITSTATE_LANCESITTING:
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_LANCE, ANIM_SUNBATHE_IDLE, 4.0f);
+ break;
+ case WAITSTATE_PLAYANIM_HANDSUP_SIMPLE:
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_HANDSUP, 4.0f);
+ animAssoc->flags &= ~ASSOC_FADEOUTWHENDONE;
+ animAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ animAssoc->SetDeleteCallback(FinishedWaitCB, this);
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + *(int*)time;
+ break;
default:
- m_nWaitState = WAITSTATE_FALSE;
+ ClearWaitState();
RestoreHeadingRate();
return;
}
@@ -7395,7 +8390,7 @@ CPed::Wait(void)
CPed *pedWeLook;
if (DyingOrDead()) {
- m_nWaitState = WAITSTATE_FALSE;
+ ClearWaitState();
RestoreHeadingRate();
return;
}
@@ -7405,7 +8400,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);
}
}
@@ -7414,7 +8409,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);
@@ -7428,7 +8423,7 @@ CPed::Wait(void)
case WAITSTATE_CROSS_ROAD_LOOK:
if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) {
- m_nWaitState = WAITSTATE_FALSE;
+ ClearWaitState();
animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_ROADCROSS);
if (animAssoc) {
animAssoc->blendDelta = -8.0f;
@@ -7445,7 +8440,7 @@ CPed::Wait(void)
CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_XPRESS_SCRATCH, 4.0f);
}
} else {
- m_nWaitState = WAITSTATE_FALSE;
+ ClearWaitState();
SetMoveState(PEDMOVE_WALK);
}
break;
@@ -7456,14 +8451,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;
- SetMoveState(PEDMOVE_WALK);
+ ClearWaitState();
m_fRotationCur = m_fRotationCur + PI;
if (m_nPedState == PED_INVESTIGATE)
ClearInvestigateEvent();
@@ -7481,7 +8475,7 @@ CPed::Wait(void)
animAssoc->SetFinishCallback(FinishedWaitCB, this);
m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 5000;
} else {
- m_nWaitState = WAITSTATE_FALSE;
+ ClearWaitState();
}
}
break;
@@ -7510,7 +8504,7 @@ CPed::Wait(void)
if (animAssoc->animId == ANIM_STD_TURN180) {
m_fRotationCur = CGeneral::LimitRadianAngle(PI + m_fRotationCur);
- m_nWaitState = WAITSTATE_FALSE;
+ ClearWaitState();
SetMoveState(PEDMOVE_WALK);
m_nStoredMoveState = PEDMOVE_NONE;
m_panicCounter = 0;
@@ -7547,7 +8541,7 @@ CPed::Wait(void)
case WAITSTATE_LOOK_ABOUT:
if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) {
- m_nWaitState = WAITSTATE_FALSE;
+ ClearWaitState();
animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_IDLE_HBHB);
if (animAssoc) {
animAssoc->blendDelta = -8.0f;
@@ -7572,39 +8566,39 @@ CPed::Wait(void)
&& CTimer::GetTimeInMilliseconds() <= m_nWaitTimer
&& animAssoc) {
- TurnBody();
+ if (pedWeLook)
+ TurnBody();
} else {
- m_nWaitState = WAITSTATE_FALSE;
+ ClearWaitState();
m_nWaitTimer = 0;
if (m_pLookTarget && m_pLookTarget->IsPed()) {
-
if (m_nPedState != PED_FLEE_ENTITY && m_nPedState != PED_ATTACK) {
+ if (bCrouchWhenScared) {
+ if (bIsDucking) {
+ ClearDuck(false);
+ SetDuck(10000, true);
+ }
- if (m_pedStats->m_fear <= 100 - pedWeLook->m_pedStats->m_temper) {
-
+ } else if (m_pedStats->m_fear <= 100 - pedWeLook->m_pedStats->m_temper) {
if (GetWeapon()->IsTypeMelee()) {
-#ifdef VC_PED_PORTS
if(m_pedStats->m_flags & STAT_GUN_PANIC) {
-#endif
- SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE, m_pLookTarget);
- if (m_nPedState == PED_FLEE_ENTITY || m_nPedState == PED_FLEE_POS) {
+ SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE, m_pLookTarget);
+ if (m_nPedState == PED_FLEE_ENTITY || m_nPedState == PED_FLEE_POS) {
- bUsePedNodeSeek = true;
- m_pNextPathNode = nil;
- }
- if (m_nMoveState != PEDMOVE_RUN)
- SetMoveState(PEDMOVE_WALK);
+ bUsePedNodeSeek = true;
+ m_pNextPathNode = nil;
+ }
+ if (m_nMoveState != PEDMOVE_RUN)
+ SetMoveState(PEDMOVE_WALK);
- if (m_nPedType != PEDTYPE_COP) {
- ProcessObjective();
- SetMoveState(PEDMOVE_WALK);
- }
-#ifdef VC_PED_PORTS
+ if (m_nPedType != PEDTYPE_COP) {
+ ProcessObjective();
+ SetMoveState(PEDMOVE_WALK);
+ }
} else {
SetObjective(OBJECTIVE_NONE);
SetWanderPath(CGeneral::GetRandomNumberInRange(0.0f, 8.0f));
}
-#endif
} else {
SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, m_pLookTarget);
SetObjectiveTimer(20000);
@@ -7649,21 +8643,23 @@ CPed::Wait(void)
animAssoc->blendDelta = -4.0f;
animAssoc->flags |= ASSOC_DELETEFADEDOUT;
}
- m_nWaitState = WAITSTATE_FALSE;
- }
-#ifdef VC_PED_PORTS
- else if (m_nWaitState == WAITSTATE_PLAYANIM_TAXI) {
+ if (m_attractor && m_objective == OBJECTIVE_WAIT_ON_FOOT_AT_ICE_CREAM_VAN) {
+ GetPedAttractorManager()->BroadcastDeparture(this, m_attractor);
+ bBoughtIceCream = true;
+ }
+ ClearWaitState();
+ } else if (m_nWaitState == WAITSTATE_PLAYANIM_TAXI) {
if (m_pedInObjective) {
if (m_objective == OBJECTIVE_GOTO_CHAR_ON_FOOT || m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT) {
-
- // VC also calls CleanUpOldReference here for old LookTarget.
+
+ if (m_pLookTarget)
+ m_pLookTarget->CleanUpOldReference(&m_pLookTarget);
m_pLookTarget = m_pedInObjective;
m_pLookTarget->RegisterReference((CEntity **) &m_pLookTarget);
TurnBody();
}
}
}
-#endif
break;
case WAITSTATE_FINISH_FLEE:
@@ -7673,13 +8669,154 @@ CPed::Wait(void)
animAssoc->flags |= ASSOC_DELETEFADEDOUT;
CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_STD_IDLE, 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();
+ if (bFleeWhenStanding) {
+ if (m_threatEx) {
+ SetFlee(m_threatEx, 10000);
+ bFleeWhenStanding = false;
+ m_threatEx = nil;
+ Say(SOUND_PED_FLEE_SPRINT);
+ }
+ }
+ }
+ break;
+ case WAITSTATE_SIT_IDLE:
+ if (bTurnedAroundOnAttractor) {
+ m_fRotationCur += PI;
+ m_fRotationCur = CGeneral::LimitRadianAngle(m_fRotationCur);
+ m_fRotationDest = m_fRotationCur;
+ bTurnedAroundOnAttractor = false;
+ }
+ if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) {
+ ClearWaitState();
+ SetWaitState(WAITSTATE_SIT_UP, 0);
+ } else {
+ if (m_fleeFrom && m_fleeFrom->IsVehicle()) {
+ m_pNextPathNode = nil;
+ m_threatEx = m_threatEntity;
+ bFleeWhenStanding = true;
+ ClearWaitState();
+ SetWaitState(WAITSTATE_SIT_UP, 0);
+ } else {
+ uint32 threatFlag = ScanForThreats();
+ if (threatFlag == PED_FLAG_GUN || threatFlag == PED_FLAG_EXPLOSION || threatFlag == PED_FLAG_DEADPEDS) {
+ m_pNextPathNode = nil;
+ m_threatEx = m_threatEntity;
+ bFleeWhenStanding = true;
+ 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_IDLE:
+ if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer && bCanGiveUpSunbathing) {
+ m_pNextPathNode = nil;
+ bGotUpOfMyOwnAccord = true;
+ SetGetUp();
+ ClearWaitState();
+
+ } else if (CWeather::Rain <= 0.1f) {
+ if (CClock::GetHours() <= 18 || CGeneral::GetRandomNumberInRange(0.f, 1.0f) < 0.005f) {
+ uint32 threatFlag = ScanForThreats();
+ if (threatFlag == PED_FLAG_GUN || threatFlag == PED_FLAG_EXPLOSION || threatFlag == PED_FLAG_DEADPEDS) {
+ // Get up in case of danger
+ m_pNextPathNode = nil;
+ m_threatEx = m_threatEntity;
+ bFleeWhenStanding = true;
+ SetGetUp();
+ ClearWaitState();
+ }
+ CPlayerPed *player = FindPlayerPed();
+ if (player) {
+ // Get up if player coming towards us with a car
+ if (player->InVehicle()){
+ CVector vehSpeedPerSec = player->m_pMyVehicle->m_vecMoveSpeed * GAME_SPEED_TO_METERS_PER_SECOND;
+ CVector vehPos = player->m_pMyVehicle->GetPosition();
+ CVector ourPos = GetPosition();
+ float timeUntilVehReachPed = DotProduct(ourPos - vehPos, vehSpeedPerSec) / vehSpeedPerSec.MagnitudeSqr();
+ if (timeUntilVehReachPed > 0.0 && timeUntilVehReachPed < 8.0f) {
+ if ((ourPos - (timeUntilVehReachPed * vehSpeedPerSec + vehPos)).Magnitude() < 5.0f) {
+ m_pNextPathNode = nil;
+ m_threatEx = player;
+ bFleeWhenStanding = true;
+ SetGetUp();
+ ClearWaitState();
+ }
+ }
+ }
+ }
+ } else {
+ m_pNextPathNode = nil;
+ bGotUpOfMyOwnAccord = true;
+ SetGetUp();
+ ClearWaitState();
+ }
+ } else {
+ m_pNextPathNode = nil;
+ bGotUpOfMyOwnAccord = true;
+ SetGetUp();
+ ClearWaitState();
+ }
+ break;
+ case WAITSTATE_RIOT:
+ if (m_nPedState == PED_FLEE_ENTITY || m_nPedState == PED_ATTACK) {
+ ClearWaitState();
+ break;
+ }
+
+ PlayRandomAnimationsFromAnimBlock(this, ASSOCGRP_RIOT, ANIM_RIOT_ANGRY, ANIM_RIOT_FUCKYOU - ANIM_RIOT_ANGRY + 1);
+ if (IsPedInControl() && CGeneral::GetRandomNumberInRange(0.f,1.f) < 0.25f
+ && CPopulation::CanJeerAtStripper(m_modelIndex)) {
+ for (int i = 0; i < m_numNearPeds; ++i) {
+ CPed *nearPed = m_nearPeds[i];
+ if (nearPed) {
+ if ((GetPosition() - nearPed->GetPosition()).MagnitudeSqr() < sq(10.f)) {
+ for (int anim = ANIM_STRIP_A; anim <= ANIM_STRIP_G; anim++) {
+ if (RpAnimBlendClumpGetAssociation(nearPed->GetClump(), anim))
+ Say(SOUND_PED_JEER);
+ }
+ }
+ }
+ }
+ }
+ break;
+ case WAITSTATE_BOMBER:
+ if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer)
+ ClearWaitState();
+ break;
+ case WAITSTATE_STRIPPER:
+ PlayRandomAnimationsFromAnimBlock(this, ASSOCGRP_STRIP, ANIM_STRIP_A, ANIM_STRIP_G - ANIM_STRIP_A + 1);
+ break;
+ case WAITSTATE_PLAYANIM_HANDSUP_SIMPLE:
+ if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer)
+ ClearWaitState();
+ break;
default:
break;
}
@@ -7689,6 +8826,24 @@ CPed::Wait(void)
}
void
+CPed::DeleteSunbatheIdleAnimCB(CAnimBlendAssociation *assoc, void *arg)
+{
+ CPed *ped = (CPed*) arg;
+
+ if (CTimer::GetTimeInMilliseconds() <= ped->m_nWaitTimer
+ && !ped->bGotUpOfMyOwnAccord && !ped->bFleeWhenStanding && !ped->m_threatEx) {
+ ped->m_pNextPathNode = nil;
+ ped->bFleeWhenStanding = true;
+ ped->m_threatEx = FindPlayerPed();
+ ped->SetGetUp();
+ ped->ClearWaitState();
+ }
+ ped->m_nWaitTimer = 0;
+ ped->RestoreHeadingRate();
+ ped->Wait();
+}
+
+void
CPed::FinishedWaitCB(CAnimBlendAssociation *animAssoc, void *arg)
{
CPed *ped = (CPed*)arg;
@@ -7707,7 +8862,7 @@ CPed::RestoreHeadingRate(void)
void
CPed::RestoreHeadingRateCB(CAnimBlendAssociation *assoc, void *arg)
{
- ((CPed*)arg)->m_headingRate = ((CPed*)arg)->m_pedStats->m_headingChangeRate;
+ ((CPed*)arg)->RestoreHeadingRate();
}
void
@@ -7763,6 +8918,10 @@ CPed::Solicit(void)
{
if (m_chatTimer >= CTimer::GetTimeInMilliseconds() && m_carInObjective) {
CVector doorPos = GetPositionToOpenCarDoor(m_carInObjective, m_vehDoor, 0.0f);
+ Say(SOUND_PED_SOLICIT);
+ if (FindPlayerVehicle() == m_carInObjective) {
+ FindPlayerPed()->Say(SOUND_PED_SOLICIT);
+ }
SetMoveState(PEDMOVE_STILL);
// Game uses GetAngleBetweenPoints and converts it to radian
@@ -7771,9 +8930,9 @@ CPed::Solicit(void)
GetPosition().x, GetPosition().y);
if (m_fRotationDest < 0.0f) {
- m_fRotationDest = m_fRotationDest + TWOPI;
+ m_fRotationDest += TWOPI;
} else if (m_fRotationDest > TWOPI) {
- m_fRotationDest = m_fRotationDest - TWOPI;
+ m_fRotationDest -= TWOPI;
}
if ((GetPosition() - doorPos).MagnitudeSqr() <= 1.0f)
@@ -7795,6 +8954,7 @@ CPed::Solicit(void)
} else {
m_pVehicleAnim = nil;
SetLeader(m_carInObjective->pDriver);
+ Say(SOUND_PED_SOLICIT);
}
}
@@ -7807,26 +8967,24 @@ CPed::SetBuyIceCream(void)
if (!m_carInObjective)
return;
-#ifdef FIX_ICECREAM
-
- // Simulating BuyIceCream
- CPed* driver = m_carInObjective->pDriver;
- if (driver) {
- SetPedState(PED_BUY_ICECREAM);
- bFindNewNodeAfterStateRestore = true;
- SetObjectiveTimer(8000);
- SetChat(driver, 8000);
- driver->SetChat(this, 8000);
- return;
- }
-#endif
-
- // Side of the Ice Cream van
- m_fRotationDest = m_carInObjective->GetForward().Heading() - HALFPI;
+ SetPedState(PED_BUY_ICECREAM);
+}
- if (Abs(m_fRotationDest - m_fRotationCur) < HALFPI) {
- m_chatTimer = CTimer::GetTimeInMilliseconds() + 3000;
- SetPedState(PED_BUY_ICECREAM);
+void
+CPed::BuyIceCream(void)
+{
+ if (m_carInObjective) {
+ CPed *driver = m_carInObjective->pDriver;
+ if (driver && CTimer::GetTimeInMilliseconds() > m_chatTimer) {
+ SetChat(driver, 8000);
+ driver->SetChat(this, 8000);
+ return;
+ }
+ SetObjective(OBJECTIVE_NONE);
+ SetWanderPath(CGeneral::GetRandomNumberInRange(0, 8));
+ } else {
+ SetObjective(OBJECTIVE_NONE);
+ SetWanderPath(CGeneral::GetRandomNumberInRange(0, 8));
}
}
@@ -7968,11 +9126,12 @@ CPed::SetLeader(CEntity *leader)
{
m_leader = (CPed*)leader;
- if(m_leader)
- m_leader->RegisterReference((CEntity **)&m_leader);
+ if (m_leader) {
+ m_leader->bIsLeader = true;
+ m_leader->RegisterReference((CEntity**)&m_leader);
+ }
}
-#ifdef VC_PED_PORTS
bool
CPed::CanPedJumpThis(CEntity *unused, CVector *damageNormal)
{
@@ -7985,7 +9144,7 @@ CPed::CanPedJumpThis(CEntity *unused, CVector *damageNormal)
if (damageNormal->z > 0.9f)
return false;
- CColModel *ourCol = CModelInfo::GetModelInfo(m_modelIndex)->GetColModel();
+ CColModel *ourCol = GetColModel();
pos.z = ourCol->spheres->center.z - ourCol->spheres->radius * damageNormal->z + pos.z;
pos.z = pos.z + 0.05f;
float collPower = damageNormal->Magnitude2D();
@@ -8004,29 +9163,13 @@ CPed::CanPedJumpThis(CEntity *unused, CVector *damageNormal)
CVector forwardPos = pos + forwardOffset;
return CWorld::GetIsLineOfSightClear(pos, forwardPos, true, false, false, true, false, false, false);
}
-#else
-bool
-CPed::CanPedJumpThis(CEntity *unused)
-{
- CVector2D forward(-Sin(m_fRotationCur), Cos(m_fRotationCur));
- CVector pos = GetPosition();
- CVector forwardPos(
- forward.x + pos.x,
- forward.y + pos.y,
- pos.z);
-
- return CWorld::GetIsLineOfSightClear(pos, forwardPos, true, false, false, true, false, false, false);
-}
-#endif
void
CPed::SetJump(void)
{
- if (!bInVehicle &&
-#if defined VC_PED_PORTS || defined FIX_BUGS
- m_nPedState != PED_JUMP && !RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_JUMP_LAUNCH) &&
-#endif
+ if (!bInVehicle && m_nPedState != PED_JUMP && !RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_JUMP_LAUNCH) &&
(m_nSurfaceTouched != SURFACE_STEEP_CLIFF || DotProduct(GetForward(), m_vecDamageNormal) >= 0.0f)) {
+
SetStoredState();
SetPedState(PED_JUMP);
CAnimBlendAssociation *jumpAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_JUMP_LAUNCH, 8.0f);
@@ -8043,8 +9186,8 @@ CPed::FinishLaunchCB(CAnimBlendAssociation *animAssoc, void *arg)
if (ped->m_nPedState != PED_JUMP)
return;
- CVector forward(0.15f * ped->GetForward() + ped->GetPosition());
- forward.z += CModelInfo::GetColModel(ped->GetModelIndex())->spheres->center.z + 0.25f;
+ CVector forward(0.09f * ped->GetForward() + ped->GetPosition());
+ forward.z += CModelInfo::GetColModel(ped->GetModelIndex())->spheres[2].center.z + 0.35f;
CEntity *obstacle = CWorld::TestSphereAgainstWorld(forward, 0.25f, nil, true, true, false, true, false, false);
if (!obstacle) {
@@ -8054,11 +9197,12 @@ CPed::FinishLaunchCB(CAnimBlendAssociation *animAssoc, void *arg)
obstacle = CWorld::TestSphereAgainstWorld(forward, 0.25f, nil, true, true, false, true, false, false);
}
+ if (!obstacle && CCullZones::CamStairsForPlayer() && CCullZones::FindZoneWithStairsAttributeForPlayer())
+ obstacle = ped;
+
if (obstacle) {
animAssoc->flags |= ASSOC_DELETEFADEDOUT;
-
- // ANIM_HIT_WALL in VC (which makes more sense)
- CAnimBlendAssociation *handsCoverAssoc = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_HANDSCOWER, 8.0f);
+ CAnimBlendAssociation *handsCoverAssoc = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_HIT_WALL, 8.0f);
handsCoverAssoc->flags &= ~ASSOC_FADEOUTWHENDONE;
handsCoverAssoc->SetFinishCallback(FinishHitHeadCB, ped);
ped->bIsLanding = true;
@@ -8077,20 +9221,12 @@ CPed::FinishLaunchCB(CAnimBlendAssociation *animAssoc, void *arg)
}
}
- if (ped->IsPlayer()
-#ifdef VC_PED_PORTS
- || ped->m_pedInObjective && ped->m_pedInObjective->IsPlayer()
-#endif
- )
+ if (ped->IsPlayer() || ped->m_pedInObjective && ped->m_pedInObjective->IsPlayer())
ped->ApplyMoveForce(0.0f, 0.0f, 8.5f);
else
ped->ApplyMoveForce(0.0f, 0.0f, 4.5f);
- if (sq(velocityFromAnim) > ped->m_vecMoveSpeed.MagnitudeSqr2D()
-#ifdef VC_PED_PORTS
- || ped->m_pCurrentPhysSurface
-#endif
- ) {
+ if (sq(velocityFromAnim) > ped->m_vecMoveSpeed.MagnitudeSqr2D() || ped->m_pCurrentPhysSurface) {
#ifdef FREE_CAM
if (TheCamera.Cams[0].Using3rdPersonMouseCam() && !CCamera::bFreeCam) {
@@ -8104,12 +9240,11 @@ CPed::FinishLaunchCB(CAnimBlendAssociation *animAssoc, void *arg)
ped->m_vecMoveSpeed.x = -velocityFromAnim * Sin(ped->m_fRotationCur);
ped->m_vecMoveSpeed.y = velocityFromAnim * Cos(ped->m_fRotationCur);
}
-#ifdef VC_PED_PORTS
+
if (ped->m_pCurrentPhysSurface) {
ped->m_vecMoveSpeed.x += ped->m_pCurrentPhysSurface->m_vecMoveSpeed.x;
ped->m_vecMoveSpeed.y += ped->m_pCurrentPhysSurface->m_vecMoveSpeed.y;
}
-#endif
}
ped->bIsStanding = false;
@@ -8194,131 +9329,23 @@ CPed::CanPedDriveOff(void)
}
return true;
}
-
-// These categories are purely random, most of ped models have no correlation. So I don't think making an enum.
-uint8
-CPed::GetPedRadioCategory(uint32 modelIndex)
-{
- switch (modelIndex) {
- case MI_MALE01:
- case MI_FEMALE03:
- case MI_PROSTITUTE2:
- case MI_WORKER1:
- case MI_MOD_MAN:
- case MI_MOD_WOM:
- case MI_ST_WOM:
- case MI_FAN_WOM:
- return 3;
- case MI_TAXI_D:
- case MI_PIMP:
- case MI_MALE02:
- case MI_FEMALE02:
- case MI_FATFEMALE01:
- case MI_FATFEMALE02:
- case MI_DOCKER1:
- case MI_WORKER2:
- case MI_FAN_MAN2:
- return 9;
- case MI_GANG01:
- case MI_GANG02:
- case MI_SCUM_MAN:
- case MI_SCUM_WOM:
- case MI_HOS_WOM:
- case MI_CONST1:
- return 1;
- case MI_GANG03:
- case MI_GANG04:
- case MI_GANG07:
- case MI_GANG08:
- case MI_CT_MAN2:
- case MI_CT_WOM2:
- case MI_B_MAN3:
- case MI_SHOPPER3:
- return 4;
- case MI_GANG05:
- case MI_GANG06:
- case MI_GANG11:
- case MI_GANG12:
- case MI_CRIMINAL02:
- case MI_B_WOM2:
- case MI_ST_MAN:
- case MI_HOS_MAN:
- return 5;
- case MI_FATMALE01:
- case MI_LI_MAN2:
- case MI_SHOPPER1:
- case MI_CAS_MAN:
- return 6;
- case MI_PROSTITUTE:
- case MI_P_WOM2:
- case MI_LI_WOM2:
- case MI_B_WOM3:
- case MI_CAS_WOM:
- return 2;
- case MI_P_WOM1:
- case MI_DOCKER2:
- case MI_STUD_MAN:
- return 7;
- case MI_CT_MAN1:
- case MI_CT_WOM1:
- case MI_LI_MAN1:
- case MI_LI_WOM1:
- case MI_B_MAN1:
- case MI_B_MAN2:
- case MI_B_WOM1:
- case MI_SHOPPER2:
- case MI_STUD_WOM:
- return 8;
- default:
- return 0;
- }
-}
-
void
CPed::SetRadioStation(void)
{
- static const uint8 radiosPerRadioCategories[10][4] = {
- {JAH_RADIO, RISE_FM, GAME_FM, MSX_FM},
- {HEAD_RADIO, DOUBLE_CLEF, LIPS_106, FLASHBACK},
- {RISE_FM, GAME_FM, MSX_FM, FLASHBACK},
- {HEAD_RADIO, RISE_FM, LIPS_106, MSX_FM},
- {HEAD_RADIO, RISE_FM, MSX_FM, FLASHBACK},
- {JAH_RADIO, RISE_FM, LIPS_106, FLASHBACK},
- {HEAD_RADIO, RISE_FM, LIPS_106, FLASHBACK},
- {HEAD_RADIO, JAH_RADIO, LIPS_106, FLASHBACK},
- {HEAD_RADIO, DOUBLE_CLEF, LIPS_106, FLASHBACK},
- {CHATTERBOX, HEAD_RADIO, LIPS_106, GAME_FM}
- };
- uint8 orderInCat = 0; // BUG: this wasn't initialized
+ CPedModelInfo* modelInfo = (CPedModelInfo*)CModelInfo::GetModelInfo(GetModelIndex());
if (IsPlayer() || !m_pMyVehicle || m_pMyVehicle->pDriver != this)
return;
- uint8 category = GetPedRadioCategory(GetModelIndex());
- if (DMAudio.IsMP3RadioChannelAvailable()) {
- if (CGeneral::GetRandomNumber() & 15) {
- for (orderInCat = 0; orderInCat < 4; orderInCat++) {
- if (m_pMyVehicle->m_nRadioStation == radiosPerRadioCategories[category][orderInCat])
- break;
- }
- } else {
- m_pMyVehicle->m_nRadioStation = USERTRACK;
- }
- } else {
- for (orderInCat = 0; orderInCat < 4; orderInCat++) {
- if (m_pMyVehicle->m_nRadioStation == radiosPerRadioCategories[category][orderInCat])
- break;
- }
- }
- if (orderInCat == 4) {
- if (DMAudio.IsMP3RadioChannelAvailable()) {
- if (CGeneral::GetRandomNumber() & 15)
- m_pMyVehicle->m_nRadioStation = radiosPerRadioCategories[category][CGeneral::GetRandomNumber() & 3];
+ if (GetModelIndex() != MI_PGA && GetModelIndex() != MI_PGB) {
+ if (m_pMyVehicle->m_nRadioStation != modelInfo->radio1 && m_pMyVehicle->m_nRadioStation != modelInfo->radio2) {
+ if (CGeneral::GetRandomTrueFalse())
+ m_pMyVehicle->m_nRadioStation = modelInfo->radio1;
else
- m_pMyVehicle->m_nRadioStation = USERTRACK;
- } else {
- m_pMyVehicle->m_nRadioStation = radiosPerRadioCategories[category][CGeneral::GetRandomNumber() & 3];
+ m_pMyVehicle->m_nRadioStation = modelInfo->radio2;
}
+ } else {
+ m_pMyVehicle->m_nRadioStation = DMAudio.GetFavouriteRadioStation();
}
}
@@ -8339,6 +9366,10 @@ CPed::WarpPedIntoCar(CVehicle *car)
car->pDriver->RegisterReference((CEntity **) &car->pDriver);
} else if (m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER) {
+ if (car->IsBike() && !car->pPassengers[0]) {
+ car->pPassengers[0] = this;
+ car->pPassengers[0]->RegisterReference((CEntity**) &car->pPassengers[0]);
+ }
for (int i = 0; i < 4; i++) {
if (!car->pPassengers[i]) {
car->pPassengers[i] = this;
@@ -8374,137 +9405,202 @@ 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_STD_BOAT_DRIVE, 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_STD_CAR_SIT_LO, 100.0f);
- else
- m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_SIT, 100.0f);
- }
-#endif
- StopNonPartialAnims();
if (car->bIsBus)
bRenderPedInCar = false;
bChangedSeat = true;
}
+bool
+CPed::HasAttractor(void)
+{
+ return m_attractor != nil;
+}
-#ifdef PEDS_REPORT_CRIMES_ON_PHONE
-// returns event id, parameter is optional
-int32
-CPed::CheckForPlayerCrimes(CPed *victim)
+void
+CPed::SetNewAttraction(CPedAttractor* pAttractor, const CVector& pos, float heading, float time, int32 qid)
{
- int i;
- float dist;
- float mindist = 60.0f;
- CPlayerPed *player = FindPlayerPed();
- int32 victimRef = (victim ? CPools::GetPedRef(victim) : 0);
- int event = -1;
+ if (!m_attractor)
+ m_attractor = pAttractor;
+ if (m_attractor != pAttractor)
+ return;
+ switch (pAttractor->GetEffect()->pedattr.type) {
+ case ATTRACTOR_ATM: SetObjective(OBJECTIVE_GOTO_ATM_ON_FOOT, heading, pos); break;
+ case ATTRACTOR_SEAT: SetObjective(OBJECTIVE_GOTO_SEAT_ON_FOOT, heading, pos); break;
+ case ATTRACTOR_STOP: SetObjective(OBJECTIVE_GOTO_BUS_STOP_ON_FOOT, heading, pos); break;
+ case ATTRACTOR_PIZZA: SetObjective(OBJECTIVE_GOTO_PIZZA_ON_FOOT, heading, pos); break;
+ case ATTRACTOR_SHELTER: SetObjective(OBJECTIVE_GOTO_SHELTER_ON_FOOT, heading, pos); break;
+ case ATTRACTOR_ICECREAM: SetObjective(OBJECTIVE_GOTO_ICE_CREAM_VAN_ON_FOOT, heading, pos); break;
+ default: return;
+ }
+ SetObjectiveTimer(time);
+ m_positionInQueue = qid;
+}
- for (i = 0; i < NUMEVENTS; i++) {
- if (gaEvent[i].type == EVENT_NULL || gaEvent[i].type > EVENT_CAR_SET_ON_FIRE)
- continue;
+void
+CPed::AttachPedToEntity(CEntity *ent, CVector offset, uint16 type, float rot, eWeaponType weapon)
+{
+ if (!ent || bInVehicle)
+ return;
- // those are already handled in game, also DEAD_PED isn't registered alone, most of the time there is SHOOT_PED etc.
- if (gaEvent[i].type == EVENT_DEAD_PED || gaEvent[i].type == EVENT_GUNSHOT || gaEvent[i].type == EVENT_EXPLOSION)
- continue;
+ m_attachedTo = ent;
+ m_attachedTo->RegisterReference(&m_attachedTo);
+ m_vecAttachOffset = offset;
+ m_attachType = type;
+ m_attachRotStep = rot;
+ if (IsPlayer()) {
+ bUsesCollision = false;
+ } else if (ent->IsVehicle()) {
+ m_pCollidingEntity = ent;
+ }
- if (victim && gaEvent[i].entityRef != victimRef)
- continue;
+ if (IsPlayer()) {
+ m_objective = OBJECTIVE_NONE;
+ m_prevObjective = OBJECTIVE_NONE;
+ }
+ SetStoredState();
+ SetPedState(PED_IDLE);
+ CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_STD_IDLE, 1000.0f);
- if (gaEvent[i].criminal != player)
- continue;
+ if (m_storedWeapon == WEAPONTYPE_UNIDENTIFIED) {
+ m_storedWeapon = GetWeapon()->m_eWeaponType;
+ m_attachWepAmmo = GetWeapon()->m_nAmmoTotal;
+ }
+ if (IsPlayer()) {
+ GiveWeapon(weapon, 30000, 1);
+#ifndef FIX_BUGS
+ ((CPlayerPed*)this)->m_nSelectedWepSlot = weapon;
+#else
+ ((CPlayerPed*)this)->m_nSelectedWepSlot = GetWeaponSlot(weapon);
+#endif
+ ((CPlayerPed*)this)->MakeChangesForNewWeapon(weapon);
+ TheCamera.SetNewPlayerWeaponMode(CCam::MODE_HELICANNON_1STPERSON, 0, 0);
+ SetPedState(PED_SNIPER_MODE);
+ } else {
+ GiveWeapon(weapon, 30000, true);
+ SetCurrentWeapon(weapon);
+ }
- dist = (GetPosition() - gaEvent[i].posn).Magnitude();
- if (dist < mindist) {
- mindist = dist;
- event = i;
+ PositionAttachedPed();
+}
+
+void
+CPed::DettachPedFromEntity(void)
+{
+ CEntity* pVehicleAttachedTo = m_attachedTo;
+ m_attachedTo = nil;
+ if (m_nPedState == PED_DIE) {
+ m_pCollidingEntity = pVehicleAttachedTo;
+ ApplyMoveForce(pVehicleAttachedTo->GetForward() * -4.0f + CVector(0.0f, 0.0f, 4.0f));
+ bIsStanding = false;
+ } else if (m_nPedState != PED_DEAD) {
+ RestorePreviousState();
+ CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_STD_IDLE, 1000.0f);
+ bUsesCollision = true;
+ if (m_storedWeapon != WEAPONTYPE_UNIDENTIFIED) {
+ GetWeapon()->m_nAmmoInClip = 0;
+ GetWeapon()->m_nAmmoTotal = 0;
+ SetCurrentWeapon(m_storedWeapon);
+ GetWeapon()->m_nAmmoTotal = m_attachWepAmmo;
+ m_storedWeapon = WEAPONTYPE_UNIDENTIFIED;
}
}
+}
- if (event != -1) {
- if (victim) {
- m_victimOfPlayerCrime = victim;
- } else {
- switch (gaEvent[event].entityType) {
- case EVENT_ENTITY_PED:
- m_victimOfPlayerCrime = CPools::GetPed(gaEvent[event].entityRef);
+void
+CPed::PositionAttachedPed()
+{
+ if(!m_attachedTo)
+ return;
+
+ CMatrix rotMatrix, targetMat;
+ targetMat = m_attachedTo->GetMatrix();
+ targetMat.GetPosition() += Multiply3x3(m_attachedTo->GetMatrix(), m_vecAttachOffset);
+ float objAngle = m_attachedTo->GetForward().Heading();
+
+ if (!IsPlayer()) {
+ float targetAngle = objAngle;
+ switch (m_attachType) {
+ case 1:
+ targetAngle += HALFPI;
break;
- case EVENT_ENTITY_VEHICLE:
- m_victimOfPlayerCrime = CPools::GetVehicle(gaEvent[event].entityRef);
+ case 2:
+ targetAngle += PI;
break;
- case EVENT_ENTITY_OBJECT:
- m_victimOfPlayerCrime = CPools::GetObject(gaEvent[event].entityRef);
+ case 3:
+ targetAngle -= HALFPI;
break;
default:
break;
- }
}
+ targetAngle = CGeneral::LimitRadianAngle(targetAngle);
+ m_fRotationCur = CGeneral::LimitRadianAngle(m_fRotationCur);
+ float neededTurn = m_fRotationCur - targetAngle;
+
+ if (neededTurn > PI)
+ neededTurn -= TWOPI;
+ else if (neededTurn < -PI)
+ neededTurn += TWOPI;
+
+ if (neededTurn > m_attachRotStep)
+ m_fRotationCur = CGeneral::LimitRadianAngle(targetAngle + m_attachRotStep);
+ else if (-m_attachRotStep > neededTurn)
+ m_fRotationCur = CGeneral::LimitRadianAngle(targetAngle - m_attachRotStep);
+ else
+ m_fRotationCur = CGeneral::LimitRadianAngle(m_fRotationCur);
+ }
+ rotMatrix.SetRotateZ(m_fRotationCur - objAngle);
+ targetMat = targetMat * rotMatrix;
+ GetMatrix() = targetMat;
+ if (m_attachedTo->IsVehicle() || m_attachedTo->IsObject()) {
+ m_vecMoveSpeed = ((CPhysical*)m_attachedTo)->m_vecMoveSpeed;
+ m_vecTurnSpeed = ((CPhysical*)m_attachedTo)->m_vecTurnSpeed;
}
+}
- return event;
+void
+CPed::Undress(const char* name)
+{
+ int mi = GetModelIndex();
+ CAnimBlendAssociation* pAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_PHONE_OUT);
+ if (pAnim)
+ FinishTalkingOnMobileCB(pAnim, this);
+
+ DeleteRwObject();
+ if (IsPlayer())
+ mi = MI_PLAYER;
+ CStreaming::RequestSpecialModel(mi, name, STREAMFLAGS_DEPENDENCY | STREAMFLAGS_SCRIPTOWNED);
+ CWorld::Remove(this);
}
-#endif
-#ifdef PED_SKIN
-static RpMaterial*
-SetLimbAlphaCB(RpMaterial *material, void *data)
-{
- ((RwRGBA*)RpMaterialGetColor(material))->alpha = *(uint8*)data;
- return material;
-}
-
-void
-CPed::renderLimb(int node)
-{
- RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump());
- int idx = RpHAnimIDGetIndex(hier, m_pFrames[node]->nodeID);
- RwMatrix *mat = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
- CPedModelInfo *mi = (CPedModelInfo *)CModelInfo::GetModelInfo(GetModelIndex());
- RpAtomic *atomic;
- switch(node){
- case PED_HEAD:
- atomic = mi->getHead();
- break;
- case PED_HANDL:
- atomic = mi->getLeftHand();
- break;
- case PED_HANDR:
- atomic = mi->getRightHand();
- break;
- default:
- return;
- }
- if(atomic == nil)
- return;
+void
+CPed::Dress(void)
+{
+ int mi = GetModelIndex();
+ m_modelIndex = -1;
+ SetModelIndex(mi);
+ m_nPedState = PED_IDLE;
+ m_nLastPedState = PED_NONE;
+ m_objective = OBJECTIVE_NONE;
+ m_prevObjective = OBJECTIVE_NONE;
+ m_nWaitState = WAITSTATE_FALSE;
+ CWorld::Add(this);
+ RestoreHeadingRate();
+}
- RwFrame *frame = RpAtomicGetFrame(atomic);
- *RwFrameGetMatrix(frame) = *mat;
- RwFrameUpdateObjects(frame);
- int alpha = CVisibilityPlugins::GetClumpAlpha(GetClump());
- RpGeometryForAllMaterials(RpAtomicGetGeometry(atomic), SetLimbAlphaCB, &alpha);
- RpAtomicRender(atomic);
+void
+CPed::Say(uint16 audio, int32 time)
+{
+ if (m_delayedSoundID == -1) {
+ m_delayedSoundID = audio;
+ m_delayedSoundTimer = CTimer::GetTimeInMilliseconds() + time;
+ }
}
-#endif
#ifdef COMPATIBLE_SAVES
#define CopyFromBuf(buf, data) memcpy(&data, buf, sizeof(data)); SkipSaveBuf(buf, sizeof(data));
@@ -8518,15 +9614,13 @@ CPed::Save(uint8*& buf)
CopyToBuf(buf, GetPosition().z);
ZeroSaveBuf(buf, 288);
CopyToBuf(buf, CharCreatedBy);
- ZeroSaveBuf(buf, 351);
+ ZeroSaveBuf(buf, 499);
CopyToBuf(buf, m_fHealth);
CopyToBuf(buf, m_fArmour);
- ZeroSaveBuf(buf, 148);
- for (int i = 0; i < 13; i++) // has to be hardcoded
+ ZeroSaveBuf(buf, 172);
+ for (int i = 0; i < 10; i++) // has to be hardcoded
m_weapons[i].Save(buf);
- ZeroSaveBuf(buf, 5);
- CopyToBuf(buf, m_maxWeaponTypeAllowed);
- ZeroSaveBuf(buf, 162);
+ ZeroSaveBuf(buf, 252);
}
void
@@ -8538,15 +9632,30 @@ CPed::Load(uint8*& buf)
CopyFromBuf(buf, GetMatrix().GetPosition().z);
SkipSaveBuf(buf, 288);
CopyFromBuf(buf, CharCreatedBy);
- SkipSaveBuf(buf, 351);
+ SkipSaveBuf(buf, 499);
CopyFromBuf(buf, m_fHealth);
CopyFromBuf(buf, m_fArmour);
- SkipSaveBuf(buf, 148);
- for (int i = 0; i < 13; i++) // has to be hardcoded
- m_weapons[i].Load(buf);
- SkipSaveBuf(buf, 5);
- CopyFromBuf(buf, m_maxWeaponTypeAllowed);
- SkipSaveBuf(buf, 162);
+ SkipSaveBuf(buf, 172);
+ m_currentWeapon = WEAPONTYPE_UNARMED;
+
+ CWeapon bufWeapon;
+ for (int i = 0; i < 10; i++) { // has to be hardcoded
+ bufWeapon.Load(buf);
+
+ if (bufWeapon.m_eWeaponType != WEAPONTYPE_UNARMED) {
+ int modelId = CWeaponInfo::GetWeaponInfo(bufWeapon.m_eWeaponType)->m_nModelId;
+ if (modelId != -1) {
+ CStreaming::RequestModel(modelId, STREAMFLAGS_DEPENDENCY);
+ int modelId2 = CWeaponInfo::GetWeaponInfo(bufWeapon.m_eWeaponType)->m_nModel2Id;
+ if (modelId2 != -1)
+ CStreaming::RequestModel(modelId2, STREAMFLAGS_DEPENDENCY);
+
+ CStreaming::LoadAllRequestedModels(false);
+ }
+ GiveWeapon(bufWeapon.m_eWeaponType, bufWeapon.m_nAmmoTotal, false);
+ }
+ }
+ SkipSaveBuf(buf, 252);
}
#undef CopyFromBuf
#undef CopyToBuf
diff --git a/src/peds/Ped.h b/src/peds/Ped.h
index 33839aa7..f5a7d7dc 100644
--- a/src/peds/Ped.h
+++ b/src/peds/Ped.h
@@ -9,6 +9,7 @@
#include "Physical.h"
#include "Weapon.h"
#include "WeaponInfo.h"
+#include "PathFind.h"
#include "Collision.h"
#define FEET_OFFSET 1.04f
@@ -16,12 +17,12 @@
#define ENTER_CAR_MAX_DIST 30.0f
#define CAN_SEE_ENTITY_ANGLE_THRESHOLD DEGTORAD(60.0f)
-struct CPathNode;
class CAccident;
class CObject;
class CFire;
struct AnimBlendFrameData;
class CAnimBlendAssociation;
+class CPedAttractor;
struct PedAudioData
{
@@ -31,6 +32,13 @@ struct PedAudioData
int m_nMaxRandomDelayTime;
};
+enum
+{
+ ATTACK_IN_PROGRESS,
+ CANT_ATTACK,
+ WATCH_UNTIL_HE_DISAPPEARS,
+};
+
enum eFormation
{
FORMATION_UNDEFINED,
@@ -81,11 +89,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
@@ -96,13 +104,20 @@ enum PedFightMoves
FIGHTMOVE_IDLE,
FIGHTMOVE_SHUFFLE_F,
FIGHTMOVE_KNEE,
- FIGHTMOVE_HEADBUTT,
- FIGHTMOVE_PUNCHJAB,
FIGHTMOVE_PUNCHHOOK,
- FIGHTMOVE_KICK,
+ FIGHTMOVE_PUNCHJAB,
+ 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,
@@ -115,6 +130,9 @@ enum PedFightMoves
FIGHTMOVE_HITBIGSTEP,
FIGHTMOVE_HITONFLOOR,
FIGHTMOVE_HITBEHIND,
+ FIGHTMOVE_MELEE1,
+ FIGHTMOVE_MELEE2,
+ FIGHTMOVE_MELEE3,
FIGHTMOVE_IDLE2NORM,
NUM_FIGHTMOVES
};
@@ -151,15 +169,31 @@ 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 {
OBJECTIVE_NONE,
OBJECTIVE_WAIT_ON_FOOT,
+ OBJECTIVE_WAIT_ON_FOOT_FOR_COP,
OBJECTIVE_FLEE_ON_FOOT_TILL_SAFE,
OBJECTIVE_GUARD_SPOT,
- OBJECTIVE_GUARD_AREA, // not implemented
+ OBJECTIVE_GUARD_AREA,
OBJECTIVE_WAIT_IN_CAR,
OBJECTIVE_WAIT_IN_CAR_THEN_GET_OUT,
OBJECTIVE_KILL_CHAR_ON_FOOT,
@@ -167,19 +201,21 @@ enum eObjective {
OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE,
OBJECTIVE_FLEE_CHAR_ON_FOOT_ALWAYS,
OBJECTIVE_GOTO_CHAR_ON_FOOT,
+ OBJECTIVE_GOTO_CHAR_ON_FOOT_WALKING,
+ OBJECTIVE_HASSLE_CHAR,
OBJECTIVE_FOLLOW_CHAR_IN_FORMATION,
OBJECTIVE_LEAVE_CAR,
OBJECTIVE_ENTER_CAR_AS_PASSENGER,
OBJECTIVE_ENTER_CAR_AS_DRIVER,
- OBJECTIVE_FOLLOW_CAR_IN_CAR, // not implemented
- OBJECTIVE_FIRE_AT_OBJECT_FROM_VEHICLE, // not implemented
- OBJECTIVE_DESTROY_OBJECT, // not implemented
+ OBJECTIVE_FOLLOW_CAR_IN_CAR,
+ OBJECTIVE_FIRE_AT_OBJECT_FROM_VEHICLE,
+ OBJECTIVE_DESTROY_OBJECT,
OBJECTIVE_DESTROY_CAR,
OBJECTIVE_GOTO_AREA_ANY_MEANS,
OBJECTIVE_GOTO_AREA_ON_FOOT,
OBJECTIVE_RUN_TO_AREA,
- OBJECTIVE_GOTO_AREA_IN_CAR, // not implemented
- OBJECTIVE_FOLLOW_CAR_ON_FOOT_WITH_OFFSET, // not implemented
+ OBJECTIVE_GOTO_AREA_IN_CAR,
+ OBJECTIVE_FOLLOW_CAR_ON_FOOT_WITH_OFFSET,
OBJECTIVE_GUARD_ATTACK,
OBJECTIVE_SET_LEADER,
OBJECTIVE_FOLLOW_ROUTE,
@@ -188,22 +224,44 @@ enum eObjective {
OBJECTIVE_CATCH_TRAIN,
OBJECTIVE_BUY_ICE_CREAM,
OBJECTIVE_STEAL_ANY_CAR,
+ OBJECTIVE_STEAL_ANY_MISSION_CAR,
OBJECTIVE_MUG_CHAR,
+ OBJECTIVE_LEAVE_CAR_AND_DIE,
+ OBJECTIVE_GOTO_SEAT_ON_FOOT,
+ OBJECTIVE_GOTO_ATM_ON_FOOT,
OBJECTIVE_FLEE_CAR,
-#ifdef VC_PED_PORTS
- OBJECTIVE_LEAVE_CAR_AND_DIE
-#endif
+ OBJECTIVE_SUN_BATHE,
+ OBJECTIVE_GOTO_BUS_STOP_ON_FOOT,
+ OBJECTIVE_GOTO_PIZZA_ON_FOOT,
+ OBJECTIVE_GOTO_SHELTER_ON_FOOT,
+ OBJECTIVE_AIM_GUN_AT,
+ OBJECTIVE_WANDER,
+ OBJECTIVE_WAIT_ON_FOOT_AT_SHELTER,
+ OBJECTIVE_SPRINT_TO_AREA,
+ OBJECTIVE_KILL_CHAR_ON_BOAT,
+ OBJECTIVE_SOLICIT_FOOT,
+ OBJECTIVE_WAIT_ON_FOOT_AT_BUS_STOP,
+ OBJECTIVE_GOTO_ICE_CREAM_VAN_ON_FOOT,
+ OBJECTIVE_WAIT_ON_FOOT_AT_ICE_CREAM_VAN,
+ OBJ_55,
+ OBJ_56,
+ OBJ_57,
+ OBJ_58,
+ OBJ_59
+
};
enum {
RANDOM_CHAR = 1,
MISSION_CHAR,
+ UNK_CHAR,
};
enum PedLineUpPhase {
LINE_UP_TO_CAR_START,
LINE_UP_TO_CAR_END,
- LINE_UP_TO_CAR_2 // Buggy. Used for cops arresting you from passenger door
+ LINE_UP_TO_CAR_2, // Buggy. Used for cops arresting you from passenger door
+ LINE_UP_TO_CAR_FALL
};
enum PedOnGroundState {
@@ -254,12 +312,17 @@ enum PedState
PED_INVESTIGATE,
PED_STEP_AWAY,
PED_ON_FIRE,
+ PED_SUN_BATHE,
+ PED_FLASH,
+ PED_JOG,
+ PED_ANSWER_MOBILE,
PED_UNKNOWN, // Same with IDLE, but also infects up to 5 peds with same pedType and WANDER_PATH, so they become stone too. HANG_OUT in Fire_Head's idb
PED_STATES_NO_AI,
- // One of these states isn't on PS2 - start
+ PED_ABSEIL,
+ PED_SIT,
PED_JUMP,
PED_FALL,
PED_GETUP,
@@ -270,7 +333,6 @@ enum PedState
PED_ENTER_TRAIN,
PED_EXIT_TRAIN,
PED_ARREST_PLAYER,
- // One of these states isn't on PS2 - end
PED_DRIVING,
PED_PASSENGER,
@@ -285,21 +347,29 @@ enum PedState
PED_EXIT_CAR,
PED_HANDS_UP,
PED_ARRESTED,
+ PED_DEPLOY_STINGER
};
enum eMoveState {
PEDMOVE_NONE,
PEDMOVE_STILL,
PEDMOVE_WALK,
+ PEDMOVE_JOG,
PEDMOVE_RUN,
PEDMOVE_SPRINT,
+ PEDMOVE_THROWN
};
+extern float gfTommyFatness;
+
class CVehicle;
class CPed : public CPhysical
{
public:
+#ifdef USE_CUTSCENE_SHADOW_FOR_PED
+ class CCutsceneShadow *m_pRTShadow;
+#endif
// 0x128
CStoredCollPoly m_collPoly;
float m_fCollisionSpeed;
@@ -342,7 +412,7 @@ public:
uint32 bScriptObjectiveCompleted : 1;
uint32 bKindaStayInSamePlace : 1;
- uint32 bBeingChasedByPolice : 1; // Unused VC leftover. Should've been set for criminal/gang members
+ uint32 bBeingChasedByPolice : 1;
uint32 bNotAllowedToDuck : 1;
uint32 bCrouchWhenShooting : 1;
uint32 bIsDucking : 1;
@@ -382,21 +452,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
+ uint32 bDontAcceptIKLookAts : 1;
+ uint32 bReachedAttractorHeadingTarget : 1;
+ uint32 bTurnedAroundOnAttractor : 1;
+
+ uint32 bHasAlreadyUsedAttractor : 1;
+ uint32 bHasAlreadyStoleACar : 1;
+ uint32 bCarPassenger : 1;
+ uint32 bFleeWhenStanding : 1;
+ uint32 bGotUpOfMyOwnAccord : 1;
+ uint32 bMiamiViceCop : 1;
+ uint32 bMoneyHasBeenGivenByScript : 1; //
+ uint32 bHasBeenPhotographed : 1; //
+
+ uint32 bIsDrowning : 1;
+ uint32 bDrownsInWater : 1;
+ uint32 bWaitForLeaderToComeCloser : 1;
+ uint32 bHeldHostageInCar : 1;
+ uint32 bIsPlayerFriend : 1;
+ uint32 bHeadStuckInCollision : 1;
+ uint32 bDeadPedInFrontOfCar : 1;
+ uint32 bStayInCarOnJack : 1;
+
+ uint32 bDontFight : 1;
+ uint32 bDoomAim : 1;
+ uint32 bCanBeShotInVehicle : 1;
+ uint32 bCanGiveUpSunbathing : 1;
+ uint32 bMakeFleeScream : 1;
+ uint32 bPushedAlongByCar : 1;
+ uint32 bRemoveMeWhenIGotIntoCar : 1;
+ uint32 bIgnoreThreatsBehindObjects : 1;
+
+ uint32 bNeverEverTargetThisPed : 1;
+ uint32 bCrouchWhenScared : 1;
+ uint32 bKnockedOffBike : 1;
+ uint32 b158_8 : 1;
+ uint32 bCollectBusFare : 1;
+ uint32 bBoughtIceCream : 1;
+ uint32 bDonePositionOutOfCollision : 1;
+ uint32 bCanAttackPlayerWithCops : 1;
+
+#ifdef KANGAROO_CHEAT
+ // our own flags
+ uint32 m_ped_flagI80 : 1; // KANGAROO_CHEAT define makes use of this as cheat toggle
#endif
- uint32 m_ped_flagI40 : 1;
- uint32 m_ped_flagI80 : 1; // originally unused, KANGAROO_CHEAT define makes use of this as cheat toggle
+ uint8 m_gangFlags;
+ uint8 m_unused15D; // these 3 can't be padding but had to actually have been members ...
+ uint8 m_unused15E;
+ uint8 m_unused15F;
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;
@@ -406,10 +517,7 @@ public:
CEntity* m_pEventEntity;
float m_fAngleToEvent;
AnimBlendFrameData *m_pFrames[PED_NODE_MAX];
-#ifdef PED_SKIN
- // stored inside the clump with non-skin ped
RpAtomic *m_pWeaponModel;
-#endif
AssocGroupId m_animGroup;
CAnimBlendAssociation *m_pVehicleAnim;
CVector2D m_vecAnimMoveDelta;
@@ -425,16 +533,23 @@ public:
int32 m_nPrevMoveState;
eWaitState m_nWaitState;
uint32 m_nWaitTimer;
- void *m_pPathNodesStates[8]; // unused, probably leftover from VC
- CVector2D m_stPathNodeStates[10];
- uint16 m_nPathNodes;
- int16 m_nCurPathNode;
+ CPathNode* m_pathNodesToGo[8];
+ int16 m_nNumPathNodes;
+ int16 m_nCurPathNodeId;
+ CEntity* m_followPathWalkAroundEnt;
+ CEntity* m_followPathTargetEnt;
+ uint32 m_pathNodeTimer;
+ CPathNode m_pathNodeObjPool[8];
+ CPathNode* m_pCurPathNode;
int8 m_nPathDir;
-public:
- CPathNode *m_pLastPathNode;
- CPathNode *m_pNextPathNode;
+ CPathNode* m_pLastPathNode;
+ CPathNode* m_pNextPathNode;
+ CVector m_followPathDestPos;
+ float m_followPathAbortDist;
+ eMoveState m_followPathMoveState;
float m_fHealth;
float m_fArmour;
+ uint32 m_nExtendedRangeTimer;
int16 m_routeLastPoint;
uint16 m_routeStartPoint;
int16 m_routePointsPassed;
@@ -454,29 +569,31 @@ public:
CVehicle *m_pMyVehicle;
bool bInVehicle;
float m_distanceToCountSeekDone;
+ float m_acceptableHeadingOffset;
+ CVehicle* m_vehicleInAccident;
+ CPedAttractor* m_attractor;
+ int32 m_positionInQueue;
bool bRunningToPhone;
int16 m_phoneId;
-#ifdef PEDS_REPORT_CRIMES_ON_PHONE
- bool m_facePhoneStart;
- CEntity *m_victimOfPlayerCrime;
-#endif
eCrimeType m_crimeToReportOnPhone;
uint32 m_phoneTalkTimer;
CAccident *m_lastAccident;
uint32 m_nPedType;
CPedStats *m_pedStats;
- float m_fleeFromPosX;
- float m_fleeFromPosY;
+ CVector2D m_fleeFromPos;
CEntity *m_fleeFrom;
uint32 m_fleeTimer;
+ CEntity* m_threatEx; // TODO(Miami): What is this?
CEntity* m_collidingEntityWhileFleeing;
uint32 m_collidingThingTimer;
CEntity *m_pCollidingEntity;
uint8 m_stateUnused;
uint32 m_timerUnused;
class CRange2D *m_wanderRangeBounds;
- CWeapon m_weapons[WEAPONTYPE_TOTAL_INVENTORY_WEAPONS];
+ CWeapon m_weapons[TOTAL_WEAPON_SLOTS];
eWeaponType m_storedWeapon;
+ eWeaponType m_delayedWeapon;
+ uint32 m_delayedWeaponAmmo;
uint8 m_currentWeapon; // eWeaponType
uint8 m_maxWeaponTypeAllowed; // eWeaponType
uint8 m_wepSkills;
@@ -484,9 +601,11 @@ public:
CEntity *m_pPointGunAt;
CVector m_vecHitLastPos;
uint32 m_curFightMove;
+ uint32 m_lastFightMove;
uint8 m_fightButtonPressure;
int8 m_fightState;
bool m_takeAStepAfterAttack;
+ uint8 m_bleedCounter;
CFire *m_pFire;
CEntity *m_pLookTarget;
float m_fLookDirection;
@@ -502,18 +621,34 @@ public:
uint32 m_duckTimer;
uint32 m_duckAndCoverTimer;
uint32 m_bloodyFootprintCountOrDeathTime; // Death time when bDoBloodyFootprints is false. Weird decision
+ uint32 m_shotTime;
+ 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;
- int8 m_lastWepDam;
+ uint16 m_nPedMoney;
+ int8 m_lastWepDam;
+ CEntity *m_lastDamEntity;
+ CEntity *m_attachedTo;
+ CVector m_vecAttachOffset;
+ uint16 m_attachType;
+ float m_attachRotStep;
+ uint32 m_attachWepAmmo;
+ uint32 m_threatFlags;
+ uint32 m_threatCheckTimer;
+ uint32 m_threatCheckInterval;
+ int32 m_delayedSoundID;
+ uint32 m_delayedSoundTimer;
uint32 m_lastSoundStart;
uint32 m_soundStart;
uint16 m_lastQueuedSound;
uint16 m_queuedSound;
- CVector m_vecSeekPosEx; // used for OBJECTIVE_GUARD_SPOT
- float m_distanceToCountSeekDoneEx; // used for OBJECTIVE_GUARD_SPOT
+ bool m_canTalk;
+ uint32 m_lastComment;
+ CVector m_vecSpotToGuard;
+ float m_radiusToGuard;
static void *operator new(size_t) throw();
static void *operator new(size_t, int) throw();
@@ -523,6 +658,7 @@ public:
CPed(uint32 pedType);
~CPed(void);
+ void DeleteRwObject();
void SetModelIndex(uint32 mi);
void ProcessControl(void);
void Teleport(CVector);
@@ -539,14 +675,15 @@ public:
void AimGun(void);
void KillPedWithCar(CVehicle *veh, float impulse);
void Say(uint16 audio);
- void SetLookFlag(CEntity *target, bool keepTryingToLook);
- void SetLookFlag(float direction, bool keepTryingToLook);
+ void Say(uint16 audio, int32 time);
+ void SetLookFlag(CEntity* target, bool keepTryingToLook, bool cancelPrevious = false);
+ void SetLookFlag(float direction, bool keepTryingToLook, bool cancelPrevious = false);
void SetLookTimer(int time);
- void SetDie(AnimationId anim, float arg1, float arg2);
+ void SetDie(AnimationId anim = ANIM_STD_KO_FRONT, float arg1 = 4.0f, float arg2 = 0.0f);
void SetDead(void);
void ApplyHeadShot(eWeaponType weaponType, CVector pos, bool evenOnPlayer);
void RemoveBodyPart(PedNode nodeId, int8 direction);
- bool OurPedCanSeeThisOne(CEntity *target);
+ bool OurPedCanSeeThisOne(CEntity *target, bool shootablesDoBlock = false);
void Avoid(void);
void Attack(void);
void ClearAimFlag(void);
@@ -555,9 +692,10 @@ public:
void ClearAttack(void);
bool IsPedHeadAbovePos(float zOffset);
void RemoveWeaponModel(int modelId);
- void SetCurrentWeapon(uint32 weaponType);
+ 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);
@@ -566,7 +704,7 @@ public:
void PlayFootSteps(void);
void QuitEnteringCar(void);
void BuildPedLists(void);
- uint32 GiveWeapon(eWeaponType weaponType, uint32 ammo);
+ int32 GiveWeapon(eWeaponType weaponType, uint32 ammo, bool unused = true);
void CalculateNewOrientation(void);
float WorkOutHeadingForMovingFirstPerson(float);
void CalculateNewVelocity(void);
@@ -580,11 +718,11 @@ public:
void SetObjective(eObjective);
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);
@@ -594,9 +732,6 @@ public:
bool MakePhonecall(void);
bool FacePhone(void);
CPed *CheckForDeadPeds(void);
-#ifdef PEDS_REPORT_CRIMES_ON_PHONE
- int32 CheckForPlayerCrimes(CPed *victim = nil);
-#endif
bool CheckForExplosions(CVector2D &area);
CPed *CheckForGunShots(void);
uint8 CheckForPointBlankPeds(CPed*);
@@ -605,7 +740,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);
@@ -631,18 +768,25 @@ public:
void SetAttack(CEntity*);
void StartFightAttack(uint8);
void SetWaitState(eWaitState, void*);
- bool FightStrike(CVector&);
+ bool FightStrike(CVector&, bool);
+ void FightHitPed(CPed*, CVector&, CVector&, int16);
+ int32 ChooseAttackPlayer(uint8, bool);
+ int32 ChooseAttackAI(uint8, bool);
int GetLocalDirection(const CVector2D &);
void StartFightDefend(uint8, uint8, uint8);
void PlayHitSound(CPed*);
void SetFall(int, AnimationId, uint8);
void SetFlee(CEntity*, int);
void SetFlee(CVector2D const &, int);
+ void RemoveDrivebyAnims(void);
void RemoveInCarAnims(void);
void CollideWithPed(CPed*);
void SetDirectionToWalkAroundObject(CEntity*);
+ bool SetDirectionToWalkAroundVehicle(CVehicle*);
+ 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);
@@ -650,27 +794,25 @@ public:
void SetChat(CEntity*, uint32);
void DeadPedMakesTyresBloody(void);
void MakeTyresMuddySectorList(CPtrList&);
- uint8 DoesLOSBulletHitPed(CColPoint &point);
bool DuckAndCover(void);
void EndFight(uint8);
void EnterCar(void);
uint8 GetNearestTrainPedPosition(CVehicle*, CVector&);
uint8 GetNearestTrainDoor(CVehicle*, CVector&);
- void LineUpPedWithTrain(void);
void ExitCar(void);
void Fight(void);
bool FindBestCoordsFromNodes(CVector, CVector*);
void Wait(void);
void ProcessObjective(void);
- bool SeekFollowingPath(CVector*);
+ CVector *SeekFollowingPath(void);
void Flee(void);
void FollowPath(void);
CVector GetFormationPosition(void);
void GetNearestDoor(CVehicle*, CVector&);
bool GetNearestPassengerDoor(CVehicle*, CVector&);
int GetNextPointOnRoute(void);
- uint8 GetPedRadioCategory(uint32);
int GetWeaponSlot(eWeaponType);
+ bool CanWeRunAndFireWithWeapon(void);
void GoToNearestDoor(CVehicle*);
bool HaveReachedNextPointOnRoute(float);
void Idle(void);
@@ -693,6 +835,7 @@ public:
void ReactToPointGun(CEntity*);
void SeekCar(void);
bool PositionPedOutOfCollision(void);
+ bool PositionAnyPedOutOfCollision(void);
bool RunToReportCrime(eCrimeType);
bool PlacePedOnDryLand(void);
bool PossiblyFindBetterPosToSeekCar(CVector*, CVehicle*);
@@ -703,7 +846,6 @@ public:
void SetExitCar(CVehicle*, uint32);
void SetFormation(eFormation);
bool WillChat(CPed*);
- void SetEnterTrain(CVehicle*, uint32);
void SetEnterCar_AllClear(CVehicle*, uint32, uint32);
void SetSolicit(uint32 time);
void ScanForInterestingStuff(void);
@@ -712,6 +854,23 @@ public:
bool WarpPedToNearLeaderOffScreen(void);
void Solicit(void);
void SetExitBoat(CVehicle*);
+ void ClearFollowPath();
+ void GiveDelayedWeapon(eWeaponType weapon, uint32 ammo);
+ void RequestDelayedWeapon();
+ void AddInCarAnims(CVehicle* car, bool isDriver);
+ bool CanBeDamagedByThisGangMember(CPed*);
+ void AnswerMobile(void);
+ void BuyIceCream(void);
+ void CheckThreatValidity(void);
+ void ClearAnswerMobile(void);
+ void SetAnswerMobile(void);
+ void AttachPedToEntity(CEntity*, CVector, uint16, float, eWeaponType);
+ void DettachPedFromEntity();
+ void PedShuffle();
+ void DriveVehicle();
+ void PositionAttachedPed();
+ bool CanUseTorsoWhenLooking();
+ void ScanForDelayedResponseThreats();
// Static methods
static CVector GetLocalPositionToOpenCarDoor(CVehicle *veh, uint32 component, float offset);
@@ -739,8 +898,11 @@ public:
static void PedSetDraggedOutCarCB(CAnimBlendAssociation *assoc, void *arg);
static void PedAnimStepOutCarCB(CAnimBlendAssociation *assoc, void *arg);
static void PedSetInTrainCB(CAnimBlendAssociation *assoc, void *arg);
+#ifdef GTA_TRAIN
static void PedSetOutTrainCB(CAnimBlendAssociation *assoc, void *arg);
+#endif
static void FinishedAttackCB(CAnimBlendAssociation *assoc, void *arg);
+ static void FinishedReloadCB(CAnimBlendAssociation *assoc, void *arg);
static void FinishFightMoveCB(CAnimBlendAssociation *assoc, void *arg);
static void PedAnimDoorCloseRollingCB(CAnimBlendAssociation *assoc, void *arg);
static void FinishJumpCB(CAnimBlendAssociation *assoc, void *arg);
@@ -748,13 +910,19 @@ public:
static void RestoreHeadingRateCB(CAnimBlendAssociation *assoc, void *arg);
static void PedSetQuickDraggedOutCarPositionCB(CAnimBlendAssociation *assoc, void *arg);
static void PedSetDraggedOutCarPositionCB(CAnimBlendAssociation *assoc, void *arg);
+ static void DeleteSunbatheIdleAnimCB(CAnimBlendAssociation *assoc, void *arg);
+ static void PedSetPreviousStateCB(CAnimBlendAssociation *assoc, void *arg);
+ static void PedAnimShuffleCB(CAnimBlendAssociation *assoc, void *arg);
+ static void PedSetGetInCarPositionCB(CAnimBlendAssociation* assoc, void* arg);
bool IsPlayer(void) const;
+ bool IsFemale(void) { return m_nPedType == PEDTYPE_CIVFEMALE || m_nPedType == PEDTYPE_PROSTITUTE; }
bool UseGroundColModel(void);
bool CanSetPedState(void);
bool IsPedInControl(void);
bool CanPedDriveOff(void);
bool CanBeDeleted(void);
+ bool CanBeDeletedEvenInVehicle(void);
bool CanStrafeOrMouseControl(void);
bool CanPedReturnToState(void);
void SetMoveState(eMoveState);
@@ -769,8 +937,14 @@ public:
void SetPedStats(ePedStats);
bool IsGangMember(void) const;
void Die(void);
+#ifdef GTA_TRAIN
void EnterTrain(void);
void ExitTrain(void);
+ void SetExitTrain(CVehicle*);
+ void SetPedPositionInTrain(void);
+ void LineUpPedWithTrain(void);
+ void SetEnterTrain(CVehicle*, uint32);
+#endif
void Fall(void);
bool IsPedShootable(void);
void Look(void);
@@ -778,29 +952,36 @@ public:
void RestoreHeadPosition(void);
void PointGunAt(void);
bool ServiceTalkingWhenDead(void);
- void SetPedPositionInTrain(void);
void SetShootTimer(uint32);
void SetSeekCar(CVehicle*, uint32);
void SetSeekBoatPosition(CVehicle*);
- void SetExitTrain(CVehicle*);
void WanderRange(void);
void SetFollowRoute(int16, int16);
void SeekBoatPosition(void);
void UpdatePosition(void);
CObject *SpawnFlyingComponent(int, int8);
void SetCarJack_AllClear(CVehicle*, uint32, uint32);
-#ifdef VC_PED_PORTS
bool CanPedJumpThis(CEntity *unused, CVector *damageNormal = nil);
-#else
- bool CanPedJumpThis(CEntity*);
-#endif
-
- bool HasWeapon(uint8 weaponType) { return m_weapons[weaponType].m_eWeaponType == weaponType; }
- CWeapon &GetWeapon(uint8 weaponType) { return m_weapons[weaponType]; }
+ void SetNewAttraction(CPedAttractor* pAttractor, const CVector& pos, float, float, int);
+ void ClearWaitState(void);
+ void Undress(const char*);
+ void Dress(void);
+ int32 KillCharOnFootMelee(CVector&, CVector&, CVector&);
+ int32 KillCharOnFootArmed(CVector&, CVector&, CVector&);
+ void SetLook(CEntity* to);
+ void SetLook(float direction);
+
+ bool HasWeaponSlot(uint8 slot) { return m_weapons[slot].m_eWeaponType != WEAPONTYPE_UNARMED; }
+ 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 && state != 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; }
@@ -810,41 +991,111 @@ 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);
+ bool IsUseAttractorObjective(eObjective obj) {
+ return obj == OBJECTIVE_GOTO_ATM_ON_FOOT || obj == OBJECTIVE_GOTO_ICE_CREAM_VAN_ON_FOOT ||
+ obj == OBJECTIVE_GOTO_PIZZA_ON_FOOT || obj == OBJECTIVE_GOTO_SEAT_ON_FOOT ||
+ obj == OBJECTIVE_GOTO_SHELTER_ON_FOOT || obj == OBJECTIVE_GOTO_BUS_STOP_ON_FOOT;
+ }
- // It was inlined in III but not in VC.
- inline void
- ReplaceWeaponWhenExitingVehicle(void)
+ void ReplaceWeaponWhenExitingVehicle(void);
+ void RemoveWeaponWhenEnteringVehicle(void);
+ bool IsNotInWreckedVehicle()
{
- eWeaponType weaponType = GetWeapon()->m_eWeaponType;
-
- // If it's Uzi, we may have stored weapon. Uzi is the only gun we can use in car.
- if (IsPlayer() && weaponType == WEAPONTYPE_UZI) {
- if (/*IsPlayer() && */ m_storedWeapon != WEAPONTYPE_UNIDENTIFIED) {
- SetCurrentWeapon(m_storedWeapon);
- m_storedWeapon = WEAPONTYPE_UNIDENTIFIED;
- }
- } else {
- AddWeaponModel(CWeaponInfo::GetWeaponInfo(weaponType)->m_nModelId);
- }
+ return m_pMyVehicle != nil && ((CEntity*)m_pMyVehicle)->GetStatus() != STATUS_WRECKED;
}
- // It was inlined in III but not in VC.
- inline void
- RemoveWeaponWhenEnteringVehicle(void)
- {
- if (IsPlayer() && HasWeapon(WEAPONTYPE_UZI) && GetWeapon(WEAPONTYPE_UZI).m_nAmmoTotal > 0) {
- if (m_storedWeapon == WEAPONTYPE_UNIDENTIFIED)
- m_storedWeapon = GetWeapon()->m_eWeaponType;
- SetCurrentWeapon(WEAPONTYPE_UZI);
- } else {
- CWeaponInfo *ourWeapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
- RemoveWeaponModel(ourWeapon->m_nModelId);
- }
+ // My names. Inlined in VC
+ AnimationId GetFireAnimNotDucking(CWeaponInfo* weapon) {
+ if (m_nPedType == PEDTYPE_COP && weapon->IsFlagSet(WEAPONFLAG_COP3_RD))
+ return Get3rdFireAnim(weapon);
+ else
+ return GetPrimaryFireAnim(weapon);
}
- bool IsNotInWreckedVehicle()
+
+ static AnimationId Get3rdFireAnim(CWeaponInfo* weapon) {
+ if (weapon->IsFlagSet(WEAPONFLAG_COP3_RD))
+ return ANIM_WEAPON_FIRE_3RD;
+ else
+ return (AnimationId)0;
+ }
+
+ static AnimationId GetFireAnimGround(CWeaponInfo* weapon, bool kickFloorIfNone = true) {
+ if (weapon->IsFlagSet(WEAPONFLAG_GROUND_2ND))
+ return ANIM_WEAPON_CROUCHFIRE;
+ else if (weapon->IsFlagSet(WEAPONFLAG_GROUND_3RD))
+ return ANIM_WEAPON_FIRE_3RD;
+ else if (kickFloorIfNone)
+ return ANIM_STD_KICKGROUND;
+ else
+ return (AnimationId)0;
+ }
+
+ static AnimationId GetPrimaryFireAnim(CWeaponInfo* weapon) {
+ if (weapon->IsFlagSet(WEAPONFLAG_ANIMDETONATE))
+ return ANIM_STD_DETONATE;
+ else
+ return ANIM_WEAPON_FIRE;
+ }
+
+ static AnimationId GetCrouchReloadAnim(CWeaponInfo* weapon) {
+ if (weapon->IsFlagSet(WEAPONFLAG_RELOAD))
+ return ANIM_WEAPON_CROUCHRELOAD;
+ else
+ return (AnimationId)0;
+ }
+
+ static AnimationId GetCrouchFireAnim(CWeaponInfo* weapon) {
+ if (weapon->IsFlagSet(WEAPONFLAG_CROUCHFIRE))
+ return ANIM_WEAPON_CROUCHFIRE;
+ else
+ return (AnimationId)0;
+ }
+
+ static AnimationId GetReloadAnim(CWeaponInfo* weapon) {
+ if (weapon->IsFlagSet(WEAPONFLAG_RELOAD))
+ return ANIM_WEAPON_RELOAD;
+ else
+ return (AnimationId)0;
+ }
+
+ static AnimationId GetFightIdleWithMeleeAnim(CWeaponInfo* weapon) {
+ if (weapon->IsFlagSet(WEAPONFLAG_FIGHTMODE))
+ return ANIM_MELEE_IDLE_FIGHTMODE;
+ else
+ return (AnimationId)0;
+ }
+
+ static AnimationId GetFinishingAttackAnim(CWeaponInfo* weapon) {
+ if (weapon->IsFlagSet(WEAPONFLAG_FINISH_3RD))
+ return ANIM_MELEE_ATTACK_FINISH;
+ else
+ return (AnimationId)0;
+ }
+
+ static AnimationId GetSecondFireAnim(CWeaponInfo* weapon) {
+ if (weapon->IsFlagSet(WEAPONFLAG_USE_2ND))
+ return ANIM_WEAPON_FIRE_2ND;
+ else
+ return (AnimationId)0;
+ }
+
+ static AnimationId GetMeleeStartAnim(CWeaponInfo* weapon) {
+ if (weapon->IsFlagSet(WEAPONFLAG_PARTIALATTACK))
+ return ANIM_MELEE_ATTACK_START;
+ else
+ return (AnimationId)0;
+ }
+
+ static AnimationId GetThrowAnim(CWeaponInfo *weapon)
{
- return m_pMyVehicle != nil && ((CEntity*)m_pMyVehicle)->GetStatus() != STATUS_WRECKED;
+ if (weapon->IsFlagSet(WEAPONFLAG_THROW))
+ return ANIM_THROWABLE_START_THROW;
+ else
+ return (AnimationId)0;
}
+ // --
+
// My additions, because there were many, many instances of that.
inline void SetFindPathAndFlee(CEntity *fleeFrom, int time, bool walk = false)
{
@@ -863,50 +1114,34 @@ public:
if (walk)
SetMoveState(PEDMOVE_WALK);
}
+ // --
inline void SetWeaponLockOnTarget(CEntity *target)
{
- m_pPointGunAt = (CPed *)target;
- if(target)
- ((CEntity *)target)->RegisterReference(&m_pPointGunAt);
+ if (m_pPointGunAt)
+ m_pPointGunAt->CleanUpOldReference(&m_pPointGunAt);
+
+ m_pPointGunAt = (CPed*)target;
+ if (target)
+ ((CEntity*)target)->RegisterReference(&m_pPointGunAt);
}
// Using this to abstract nodes of skinned and non-skinned meshes
CVector GetNodePosition(int32 node)
{
-#ifdef PED_SKIN
- if(IsClumpSkinned(GetClump())){
- RwV3d pos = { 0.0f, 0.0f, 0.0f };
- RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump());
- int32 idx = RpHAnimIDGetIndex(hier, m_pFrames[node]->nodeID);
- RwMatrix *mats = RpHAnimHierarchyGetMatrixArray(hier);
- // this is just stupid
- //RwV3dTransformPoints(&pos, &pos, 1, &mats[idx]);
- pos = mats[idx].pos;
- return pos;
- }else
-#endif
- {
- RwMatrix mat;
- CPedIK::GetWorldMatrix(m_pFrames[node]->frame, &mat);
- return mat.pos;
- }
+ RwV3d pos = { 0.0f, 0.0f, 0.0f };
+ RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump());
+ int32 idx = RpHAnimIDGetIndex(hier, m_pFrames[node]->nodeID);
+ RwMatrix *mats = RpHAnimHierarchyGetMatrixArray(hier);
+ pos = mats[idx].pos;
+ return pos;
}
void TransformToNode(CVector &pos, int32 node)
{
-#ifdef PED_SKIN
- if(IsClumpSkinned(GetClump())){
- RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump());
- int32 idx = RpHAnimIDGetIndex(hier, m_pFrames[node]->nodeID);
- RwMatrix *mats = RpHAnimHierarchyGetMatrixArray(hier);
- RwV3dTransformPoints(&pos, &pos, 1, &mats[idx]);
- }else
-#endif
- {
- RwFrame *frame;
- for (frame = m_pFrames[node]->frame; frame; frame = RwFrameGetParent(frame))
- RwV3dTransformPoints(&pos, &pos, 1, RwFrameGetMatrix(frame));
- }
+ RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump());
+ int32 idx = RpHAnimIDGetIndex(hier, m_pFrames[node]->nodeID);
+ RwMatrix *mats = RpHAnimHierarchyGetMatrixArray(hier);
+ RwV3dTransformPoints(&pos, &pos, 1, &mats[idx]);
}
// set by 0482:set_threat_reaction_range_multiplier opcode
@@ -916,14 +1151,10 @@ public:
static uint16 nEnterCarRangeMultiplier;
static bool bNastyLimbsCheat;
- static bool bPedCheat2;
+ static bool bFannyMagnetCheat;
static bool bPedCheat3;
static CVector2D ms_vec2DFleePosition;
-#ifdef DEBUGMENU
- static bool bPopHeadsOnHeadshot;
-#endif
-
#ifndef MASTER
// Mobile things
void DebugDrawPedDestination(CPed *, int, int);
@@ -943,18 +1174,17 @@ public:
void DebugRenderClosePedText();
#endif
-#ifdef PED_SKIN
- void renderLimb(int node);
-#endif
-
#ifdef COMPATIBLE_SAVES
virtual void Save(uint8*& buf);
virtual void Load(uint8*& buf);
#endif
};
-void FinishFuckUCB(CAnimBlendAssociation *assoc, void *arg);
+void FinishTalkingOnMobileCB(CAnimBlendAssociation* assoc, void* arg);
+void StartTalkingOnMobileCB(CAnimBlendAssociation* assoc, void* arg);
+void PlayRandomAnimationsFromAnimBlock(CPed* ped, AssocGroupId animGroup, uint32 first, uint32 amount);
-#ifndef PED_SKIN
-VALIDATE_SIZE(CPed, 0x53C);
-#endif
+VALIDATE_SIZE(CPed, 0x5F4);
+
+bool IsPedPointerValid(CPed*);
+bool IsPedPointerValid_NotInWorld(CPed*);
diff --git a/src/peds/PedAI.cpp b/src/peds/PedAI.cpp
index f1c753ec..e204dad9 100644
--- a/src/peds/PedAI.cpp
+++ b/src/peds/PedAI.cpp
@@ -24,6 +24,11 @@
#include "CarAI.h"
#include "Zones.h"
#include "Cranes.h"
+#include "PedAttractor.h"
+#include "Bike.h"
+#include "Weather.h"
+#include "GameLogic.h"
+#include "Streaming.h"
CVector vecPedCarDoorAnimOffset;
CVector vecPedCarDoorLoAnimOffset;
@@ -31,6 +36,11 @@ CVector vecPedVanRearDoorAnimOffset;
CVector vecPedQuickDraggedOutCarAnimOffset;
CVector vecPedDraggedOutCarAnimOffset;
CVector vecPedTrainDoorAnimOffset;
+CVector vecPedStdBikeJumpRhsAnimOffset;
+CVector vecPedVespaBikeJumpRhsAnimOffset;
+CVector vecPedHarleyBikeJumpRhsAnimOffset;
+CVector vecPedDirtBikeJumpRhsAnimOffset;
+CVector vecPedBikeKickAnimOffset;
void
CPed::SetObjectiveTimer(int time)
@@ -48,20 +58,28 @@ CPed::SetStoredObjective(void)
if (m_objective == m_prevObjective)
return;
- switch (m_objective)
- {
+ switch (m_objective) {
case OBJECTIVE_FLEE_ON_FOOT_TILL_SAFE:
case OBJECTIVE_KILL_CHAR_ON_FOOT:
case OBJECTIVE_KILL_CHAR_ANY_MEANS:
case OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE:
case OBJECTIVE_FLEE_CHAR_ON_FOOT_ALWAYS:
case OBJECTIVE_GOTO_CHAR_ON_FOOT:
+ case OBJECTIVE_GOTO_CHAR_ON_FOOT_WALKING:
+ case OBJECTIVE_HASSLE_CHAR:
case OBJECTIVE_FOLLOW_CHAR_IN_FORMATION:
case OBJECTIVE_LEAVE_CAR:
case OBJECTIVE_ENTER_CAR_AS_PASSENGER:
case OBJECTIVE_ENTER_CAR_AS_DRIVER:
case OBJECTIVE_GOTO_AREA_ON_FOOT:
case OBJECTIVE_RUN_TO_AREA:
+ case OBJECTIVE_GOTO_SEAT_ON_FOOT:
+ case OBJECTIVE_GOTO_ATM_ON_FOOT:
+ case OBJECTIVE_GOTO_BUS_STOP_ON_FOOT:
+ case OBJECTIVE_GOTO_PIZZA_ON_FOOT:
+ case OBJECTIVE_GOTO_SHELTER_ON_FOOT:
+ case OBJECTIVE_SPRINT_TO_AREA:
+ case OBJECTIVE_GOTO_ICE_CREAM_VAN_ON_FOOT:
return;
default:
m_prevObjective = m_objective;
@@ -76,17 +94,25 @@ CPed::ForceStoredObjective(eObjective objective)
return;
}
- switch (m_objective)
- {
+ switch (m_objective) {
case OBJECTIVE_FLEE_ON_FOOT_TILL_SAFE:
case OBJECTIVE_KILL_CHAR_ON_FOOT:
case OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE:
case OBJECTIVE_FLEE_CHAR_ON_FOOT_ALWAYS:
case OBJECTIVE_GOTO_CHAR_ON_FOOT:
+ case OBJECTIVE_GOTO_CHAR_ON_FOOT_WALKING:
+ case OBJECTIVE_HASSLE_CHAR:
case OBJECTIVE_ENTER_CAR_AS_PASSENGER:
case OBJECTIVE_ENTER_CAR_AS_DRIVER:
case OBJECTIVE_GOTO_AREA_ON_FOOT:
case OBJECTIVE_RUN_TO_AREA:
+ case OBJECTIVE_GOTO_SEAT_ON_FOOT:
+ case OBJECTIVE_GOTO_ATM_ON_FOOT:
+ case OBJECTIVE_GOTO_BUS_STOP_ON_FOOT:
+ case OBJECTIVE_GOTO_PIZZA_ON_FOOT:
+ case OBJECTIVE_GOTO_SHELTER_ON_FOOT:
+ case OBJECTIVE_SPRINT_TO_AREA:
+ case OBJECTIVE_GOTO_ICE_CREAM_VAN_ON_FOOT:
return;
default:
m_prevObjective = m_objective;
@@ -97,41 +123,25 @@ bool
CPed::IsTemporaryObjective(eObjective objective)
{
return objective == OBJECTIVE_LEAVE_CAR || objective == OBJECTIVE_SET_LEADER ||
-#ifdef VC_PED_PORTS
- objective == OBJECTIVE_LEAVE_CAR_AND_DIE ||
-#endif
- objective == OBJECTIVE_ENTER_CAR_AS_DRIVER || objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER;
+ objective == OBJECTIVE_LEAVE_CAR_AND_DIE || objective == OBJECTIVE_ENTER_CAR_AS_DRIVER ||
+ objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER;
}
void
CPed::SetObjective(eObjective newObj)
{
- if (DyingOrDead())
+ if (DyingOrDead() || m_attachedTo)
return;
if (newObj == OBJECTIVE_NONE) {
if ((m_objective == OBJECTIVE_LEAVE_CAR || m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER || m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER
-#ifdef VC_PED_PORTS
- || m_objective == OBJECTIVE_LEAVE_CAR_AND_DIE)
- && !IsPlayer()
-#else
- )
-#endif
- && !IsPedInControl()) {
+ || m_objective == OBJECTIVE_LEAVE_CAR_AND_DIE) && !IsPlayer() && !IsPedInControl()) {
bStartWanderPathOnFoot = true;
- return;
- }
- // Unused code from assembly...
- /*
- else if(m_objective == OBJECTIVE_FLEE_CAR) {
-
} else {
-
+ m_objective = OBJECTIVE_NONE;
+ m_prevObjective = OBJECTIVE_NONE;
}
- */
- m_objective = OBJECTIVE_NONE;
- m_prevObjective = OBJECTIVE_NONE;
} else if (m_prevObjective != newObj || m_prevObjective == OBJECTIVE_NONE) {
SetObjectiveTimer(0);
@@ -169,33 +179,33 @@ CPed::SetObjective(eObjective newObj, void *entity)
if (DyingOrDead())
return;
- if (m_prevObjective == newObj) {
- // Why?
- if (m_prevObjective != OBJECTIVE_NONE)
- return;
- }
+ if (m_prevObjective == newObj && m_prevObjective != OBJECTIVE_NONE)
+ return;
if (entity == this)
return;
- SetObjectiveTimer(0);
+ if (m_attachedTo && newObj != OBJECTIVE_KILL_CHAR_ON_FOOT && newObj != OBJECTIVE_KILL_CHAR_ANY_MEANS && newObj != OBJECTIVE_DESTROY_OBJECT && newObj != OBJECTIVE_DESTROY_CAR)
+ return;
+
if (m_objective == newObj) {
switch (newObj) {
case OBJECTIVE_KILL_CHAR_ON_FOOT:
case OBJECTIVE_KILL_CHAR_ANY_MEANS:
case OBJECTIVE_GOTO_CHAR_ON_FOOT:
+ case OBJECTIVE_GOTO_CHAR_ON_FOOT_WALKING:
+ case OBJECTIVE_HASSLE_CHAR:
case OBJECTIVE_FOLLOW_CHAR_IN_FORMATION:
case OBJECTIVE_GOTO_AREA_ANY_MEANS:
case OBJECTIVE_GUARD_ATTACK:
+ case OBJECTIVE_KILL_CHAR_ON_BOAT:
+ case OBJECTIVE_SOLICIT_FOOT:
if (m_pedInObjective == entity)
return;
-
break;
case OBJECTIVE_LEAVE_CAR:
case OBJECTIVE_FLEE_CAR:
-#ifdef VC_PED_PORTS
case OBJECTIVE_LEAVE_CAR_AND_DIE:
-#endif
return;
case OBJECTIVE_ENTER_CAR_AS_PASSENGER:
case OBJECTIVE_ENTER_CAR_AS_DRIVER:
@@ -205,28 +215,30 @@ CPed::SetObjective(eObjective newObj, void *entity)
if (m_carInObjective == entity)
return;
+ if (newObj == OBJECTIVE_BUY_ICE_CREAM && bBoughtIceCream)
+ return;
+
break;
case OBJECTIVE_SET_LEADER:
if (m_leader == entity)
return;
-
+ break;
+ case OBJECTIVE_AIM_GUN_AT:
+ if (m_pedInObjective == entity)
+ return;
break;
default:
break;
}
} else {
- if ((newObj == OBJECTIVE_LEAVE_CAR
-#ifdef VC_PED_PORTS
- || newObj == OBJECTIVE_LEAVE_CAR_AND_DIE
-#endif
- ) && !bInVehicle)
+ if (newObj != OBJECTIVE_WAIT_IN_CAR_THEN_GET_OUT && (newObj == OBJECTIVE_LEAVE_CAR || newObj == OBJECTIVE_LEAVE_CAR_AND_DIE)
+ && !bInVehicle)
return;
}
-#ifdef VC_PED_PORTS
- ClearPointGunAt();
-#endif
bObjectiveCompleted = false;
+ ClearPointGunAt();
+ m_objectiveTimer = 0;
if (IsTemporaryObjective(m_objective) && !IsTemporaryObjective(newObj)) {
m_prevObjective = newObj;
} else {
@@ -240,6 +252,12 @@ CPed::SetObjective(eObjective newObj, void *entity)
}
switch (newObj) {
+ case OBJECTIVE_WAIT_ON_FOOT_FOR_COP:
+ m_pedInObjective = (CPed*)entity;
+ m_pedInObjective->RegisterReference((CEntity**)&m_pedInObjective);
+ SetIdle();
+ SetLook(m_pedInObjective);
+ break;
case OBJECTIVE_WAIT_IN_CAR_THEN_GET_OUT:
// In this special case, entity parameter isn't CEntity, but int.
@@ -248,20 +266,33 @@ CPed::SetObjective(eObjective newObj, void *entity)
case OBJECTIVE_KILL_CHAR_ON_FOOT:
case OBJECTIVE_KILL_CHAR_ANY_MEANS:
case OBJECTIVE_MUG_CHAR:
+ case OBJECTIVE_KILL_CHAR_ON_BOAT:
m_pNextPathNode = nil;
bUsePedNodeSeek = false;
- m_vecSeekPos = CVector(0.0f, 0.0f, 0.0f);
+
+ if (m_pedInObjective)
+ m_pedInObjective->CleanUpOldReference((CEntity**)&m_pedInObjective);
+ if (m_pLookTarget)
+ m_pLookTarget->CleanUpOldReference(&m_pLookTarget);
+
+ m_pLookTarget = (CEntity*)entity;
m_pedInObjective = (CPed*)entity;
+ m_vecSeekPos = CVector(0.0f, 0.0f, 0.0f);
m_pedInObjective->RegisterReference((CEntity**)&m_pedInObjective);
- m_pLookTarget = (CEntity*)entity;
+ // m_pLookTarget = (CEntity*)entity; // duplicate
m_pLookTarget->RegisterReference((CEntity**)&m_pLookTarget);
break;
case OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE:
case OBJECTIVE_FLEE_CHAR_ON_FOOT_ALWAYS:
case OBJECTIVE_GOTO_CHAR_ON_FOOT:
+ case OBJECTIVE_GOTO_CHAR_ON_FOOT_WALKING:
+ case OBJECTIVE_HASSLE_CHAR:
case OBJECTIVE_GUARD_ATTACK:
- m_vecSeekPos = CVector(0.0f, 0.0f, 0.0f);
+
+ if (m_pedInObjective)
+ m_pedInObjective->CleanUpOldReference((CEntity**)&m_pedInObjective);
m_pedInObjective = (CPed*)entity;
+ m_vecSeekPos = CVector(0.0f, 0.0f, 0.0f);
m_pedInObjective->RegisterReference((CEntity**)&m_pedInObjective);
break;
case OBJECTIVE_FOLLOW_CHAR_IN_FORMATION:
@@ -270,9 +301,7 @@ CPed::SetObjective(eObjective newObj, void *entity)
m_pedFormation = FORMATION_REAR;
break;
case OBJECTIVE_LEAVE_CAR:
-#ifdef VC_PED_PORTS
case OBJECTIVE_LEAVE_CAR_AND_DIE:
-#endif
case OBJECTIVE_FLEE_CAR:
m_carInObjective = (CVehicle*)entity;
m_carInObjective->RegisterReference((CEntity **)&m_carInObjective);
@@ -286,12 +315,15 @@ CPed::SetObjective(eObjective newObj, void *entity)
}
break;
+ case OBJECTIVE_DESTROY_OBJECT:
+ SetWeaponLockOnTarget((CEntity*)entity);
+ break;
case OBJECTIVE_ENTER_CAR_AS_PASSENGER:
case OBJECTIVE_ENTER_CAR_AS_DRIVER:
if (m_nMoveState == PEDMOVE_STILL)
SetMoveState(PEDMOVE_RUN);
- if (((CVehicle*)entity)->m_vehType == VEHICLE_TYPE_BOAT && !IsPlayer()) {
+ if (((CVehicle*)entity)->IsBoat() && !IsPlayer() && m_pCurrentPhysSurface != entity) {
RestorePreviousObjective();
break;
}
@@ -317,55 +349,19 @@ CPed::SetObjective(eObjective newObj, void *entity)
SetLeader((CEntity*)entity);
RestorePreviousObjective();
break;
+ case OBJECTIVE_AIM_GUN_AT:
+ m_pedInObjective = (CPed*)entity;
+ m_pedInObjective->RegisterReference((CEntity**)&m_pedInObjective);
+ break;
+ case OBJECTIVE_SOLICIT_FOOT:
+ m_pedInObjective = (CPed*)entity;
+ m_pedInObjective->RegisterReference((CEntity**)&m_pedInObjective);
+ break;
default:
break;
}
}
-void
-CPed::SetObjective(eObjective newObj, CVector dest, float safeDist)
-{
- if (DyingOrDead())
- return;
-
- if (m_prevObjective != OBJECTIVE_NONE && m_prevObjective == newObj)
- return;
-
- SetObjectiveTimer(0);
- if (m_objective == newObj) {
- if (newObj == OBJECTIVE_GOTO_AREA_ANY_MEANS || newObj == OBJECTIVE_GOTO_AREA_ON_FOOT || newObj == OBJECTIVE_RUN_TO_AREA) {
- if (m_nextRoutePointPos == dest && m_distanceToCountSeekDone == safeDist)
- return;
- } else if (newObj == OBJECTIVE_GUARD_SPOT) {
- if (m_vecSeekPosEx == dest && m_distanceToCountSeekDoneEx == safeDist)
- return;
- }
- }
-
-#ifdef VC_PED_PORTS
- ClearPointGunAt();
-#endif
- bObjectiveCompleted = false;
- if (IsTemporaryObjective(m_objective)) {
- m_prevObjective = newObj;
- } else {
- if (m_objective != newObj)
- SetStoredObjective();
-
- m_objective = newObj;
- }
-
- if (newObj == OBJECTIVE_GUARD_SPOT) {
- m_vecSeekPosEx = dest;
- m_distanceToCountSeekDoneEx = safeDist;
- } else if (newObj == OBJECTIVE_GOTO_AREA_ANY_MEANS || newObj == OBJECTIVE_GOTO_AREA_ON_FOOT || newObj == OBJECTIVE_RUN_TO_AREA) {
- m_pNextPathNode = nil;
- m_nextRoutePointPos = dest;
- m_vecSeekPos = m_nextRoutePointPos;
- bUsePedNodeSeek = true;
- }
-}
-
// Only used in 01E1: SET_CHAR_OBJ_FOLLOW_ROUTE opcode
// IDA fails very badly in here, puts a fake loop and ignores SetFollowRoute call...
void
@@ -377,11 +373,12 @@ CPed::SetObjective(eObjective newObj, int16 routePoint, int16 routeType)
if (m_prevObjective == newObj && m_prevObjective != OBJECTIVE_NONE)
return;
- SetObjectiveTimer(0);
-
if (m_objective == newObj && newObj == OBJECTIVE_FOLLOW_ROUTE && m_routeLastPoint == routePoint && m_routeType == routeType)
return;
+ ClearPointGunAt();
+ SetObjectiveTimer(0);
+
bObjectiveCompleted = false;
if (IsTemporaryObjective(m_objective)) {
m_prevObjective = newObj;
@@ -406,25 +403,23 @@ CPed::SetObjective(eObjective newObj, CVector dest)
if (m_prevObjective != OBJECTIVE_NONE && m_prevObjective == newObj)
return;
- SetObjectiveTimer(0);
if (m_objective == newObj) {
- if (newObj == OBJECTIVE_GOTO_AREA_ANY_MEANS || newObj == OBJECTIVE_GOTO_AREA_ON_FOOT || newObj == OBJECTIVE_RUN_TO_AREA) {
+ if (newObj == OBJECTIVE_GOTO_AREA_ANY_MEANS || newObj == OBJECTIVE_GOTO_AREA_ON_FOOT || newObj == OBJECTIVE_RUN_TO_AREA || newObj == OBJECTIVE_SPRINT_TO_AREA) {
if (m_nextRoutePointPos == dest)
return;
} else if (newObj == OBJECTIVE_GUARD_SPOT) {
- if (m_vecSeekPosEx == dest)
+ if (m_vecSpotToGuard == dest)
return;
}
}
-#ifdef VC_PED_PORTS
ClearPointGunAt();
-#endif
+ m_objectiveTimer = 0;
bObjectiveCompleted = false;
switch (newObj) {
case OBJECTIVE_GUARD_SPOT:
- m_vecSeekPosEx = dest;
- m_distanceToCountSeekDoneEx = 5.0f;
+ m_vecSpotToGuard = dest;
+ m_radiusToGuard = 5.0f;
SetMoveState(PEDMOVE_STILL);
break;
case OBJECTIVE_GUARD_AREA:
@@ -435,6 +430,8 @@ CPed::SetObjective(eObjective newObj, CVector dest)
case OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE:
case OBJECTIVE_FLEE_CHAR_ON_FOOT_ALWAYS:
case OBJECTIVE_GOTO_CHAR_ON_FOOT:
+ case OBJECTIVE_GOTO_CHAR_ON_FOOT_WALKING:
+ case OBJECTIVE_HASSLE_CHAR:
case OBJECTIVE_FOLLOW_CHAR_IN_FORMATION:
case OBJECTIVE_LEAVE_CAR:
case OBJECTIVE_ENTER_CAR_AS_PASSENGER:
@@ -443,19 +440,77 @@ CPed::SetObjective(eObjective newObj, CVector dest)
case OBJECTIVE_FIRE_AT_OBJECT_FROM_VEHICLE:
case OBJECTIVE_DESTROY_OBJECT:
case OBJECTIVE_DESTROY_CAR:
+ case OBJECTIVE_GOTO_AREA_IN_CAR:
+ case OBJECTIVE_FOLLOW_CAR_ON_FOOT_WITH_OFFSET:
+ case OBJECTIVE_GUARD_ATTACK:
+ case OBJECTIVE_SET_LEADER:
+ case OBJECTIVE_FOLLOW_ROUTE:
+ case OBJECTIVE_SOLICIT_VEHICLE:
+ case OBJECTIVE_HAIL_TAXI:
+ case OBJECTIVE_CATCH_TRAIN:
+ case OBJECTIVE_BUY_ICE_CREAM:
+ case OBJECTIVE_STEAL_ANY_CAR:
+ case OBJECTIVE_STEAL_ANY_MISSION_CAR:
+ case OBJECTIVE_MUG_CHAR:
+ case OBJECTIVE_LEAVE_CAR_AND_DIE:
+ case OBJECTIVE_FLEE_CAR:
+ case OBJECTIVE_SUN_BATHE:
+ case OBJECTIVE_AIM_GUN_AT:
+ case OBJECTIVE_WANDER:
+ case OBJECTIVE_WAIT_ON_FOOT_AT_SHELTER:
+ case OBJECTIVE_KILL_CHAR_ON_BOAT:
+ case OBJECTIVE_SOLICIT_FOOT:
+ case OBJECTIVE_WAIT_ON_FOOT_AT_BUS_STOP:
break;
case OBJECTIVE_GOTO_AREA_ANY_MEANS:
case OBJECTIVE_GOTO_AREA_ON_FOOT:
+ case OBJECTIVE_GOTO_SEAT_ON_FOOT:
+ case OBJECTIVE_GOTO_ATM_ON_FOOT:
+ case OBJECTIVE_GOTO_BUS_STOP_ON_FOOT:
+ case OBJECTIVE_GOTO_PIZZA_ON_FOOT:
+ case OBJECTIVE_GOTO_SHELTER_ON_FOOT:
+ case OBJECTIVE_GOTO_ICE_CREAM_VAN_ON_FOOT:
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 (newObj == OBJECTIVE_GOTO_ATM_ON_FOOT) {
+ m_distanceToCountSeekDone = m_attractor->GetDistanceToCountSeekDone();
+ m_acceptableHeadingOffset = m_attractor->GetAcceptableHeading();
+ }
+ if (newObj == OBJECTIVE_GOTO_SEAT_ON_FOOT) {
+ m_distanceToCountSeekDone = m_attractor->GetDistanceToCountSeekDone();
+ m_acceptableHeadingOffset = m_attractor->GetAcceptableHeading();
+ }
+ if (newObj == OBJECTIVE_GOTO_BUS_STOP_ON_FOOT) {
+ m_distanceToCountSeekDone = m_attractor->GetDistanceToCountSeekDone();
+ m_acceptableHeadingOffset = m_attractor->GetAcceptableHeading();
+ }
+ if (newObj == OBJECTIVE_GOTO_PIZZA_ON_FOOT) {
+ m_distanceToCountSeekDone = m_attractor->GetDistanceToCountSeekDone();
+ m_acceptableHeadingOffset = m_attractor->GetAcceptableHeading();
+ }
+ if (newObj == OBJECTIVE_GOTO_SHELTER_ON_FOOT) {
+ bIsRunning = true;
+ m_distanceToCountSeekDone = m_attractor->GetDistanceToCountSeekDone();
+ m_acceptableHeadingOffset = m_attractor->GetAcceptableHeading();
+ }
+ if (newObj == OBJECTIVE_GOTO_ICE_CREAM_VAN_ON_FOOT) {
+ 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:
+ case OBJECTIVE_SPRINT_TO_AREA:
bIsRunning = true;
m_pNextPathNode = nil;
m_nextRoutePointPos = dest;
@@ -479,27 +534,37 @@ CPed::SetObjective(eObjective newObj, CVector dest)
}
void
+CPed::SetObjective(eObjective newObj, float heading, const CVector& pos)
+{
+ switch (newObj) {
+ case OBJECTIVE_GOTO_SEAT_ON_FOOT:
+ case OBJECTIVE_GOTO_ATM_ON_FOOT:
+ case OBJECTIVE_GOTO_BUS_STOP_ON_FOOT:
+ case OBJECTIVE_GOTO_PIZZA_ON_FOOT:
+ case OBJECTIVE_GOTO_SHELTER_ON_FOOT:
+ case OBJECTIVE_GOTO_ICE_CREAM_VAN_ON_FOOT:
+ ClearPointGunAt();
+ SetObjective(newObj, pos);
+ m_attractorHeading = heading;
+ }
+}
+
+void
CPed::ClearObjective(void)
{
if (IsPedInControl() || m_nPedState == PED_DRIVING) {
m_objective = OBJECTIVE_NONE;
-#ifdef VC_PED_PORTS
m_pedInObjective = nil;
m_carInObjective = nil;
-#endif
- if (m_nPedState == PED_DRIVING && m_pMyVehicle) {
+ if (m_nPedState == PED_DRIVING && m_pMyVehicle) {
if (m_pMyVehicle->pDriver != this) {
-#if defined VC_PED_PORTS || defined FIX_BUGS
if(!IsPlayer())
-#endif
bWanderPathAfterExitingCar = true;
SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
}
-#ifdef VC_PED_PORTS
m_nLastPedState = PED_NONE;
-#endif
} else {
SetIdle();
SetMoveState(PEDMOVE_STILL);
@@ -544,14 +609,17 @@ CPed::UpdateFromLeader(void)
leaderDist = m_leader->GetPosition() - GetPosition();
if (leaderDist.Magnitude() > 30.0f) {
- if (IsPedInControl()) {
- SetObjective(OBJECTIVE_NONE);
- SetIdle();
- SetMoveState(PEDMOVE_STILL);
+ if (bWaitForLeaderToComeCloser) {
+ if (IsPedInControl()) {
+ SetObjective(OBJECTIVE_NONE);
+ SetIdle();
+ SetMoveState(PEDMOVE_STILL);
+ }
+ return;
}
- SetLeader(nil);
- return;
- }
+ bWaitForLeaderToComeCloser = true;
+ } else
+ bWaitForLeaderToComeCloser = false;
if (IsPedInControl()) {
if (m_nWaitState == WAITSTATE_PLAYANIM_TAXI)
@@ -588,11 +656,10 @@ CPed::UpdateFromLeader(void)
} else if (m_leader->m_objective == OBJECTIVE_NONE || (m_leader->IsPlayer() && m_leader->m_objective == OBJECTIVE_WAIT_ON_FOOT)
|| m_objective == m_leader->m_objective) {
- if (m_leader->m_nPedState == PED_ATTACK) {
+ if (m_leader->m_nPedState == PED_ATTACK && !bDontFight) {
CEntity *lookTargetOfLeader = m_leader->m_pLookTarget;
- if (lookTargetOfLeader && m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT
- && lookTargetOfLeader->IsPed() && lookTargetOfLeader != this) {
+ if (lookTargetOfLeader && m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT && lookTargetOfLeader->IsPed() && lookTargetOfLeader != this) {
SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, lookTargetOfLeader);
SetObjectiveTimer(8000);
SetLookFlag(m_leader->m_pLookTarget, false);
@@ -600,21 +667,14 @@ CPed::UpdateFromLeader(void)
}
} else {
if (IsPedInControl() && m_nPedState != PED_ATTACK) {
-#ifndef VC_PED_PORTS
- SetObjective(OBJECTIVE_GOTO_CHAR_ON_FOOT, m_leader);
- SetObjectiveTimer(0);
-#else
- if (m_leader->m_objective == OBJECTIVE_NONE && m_objective == OBJECTIVE_NONE
- && m_leader->m_nPedState == PED_CHAT && m_nPedState == PED_CHAT) {
-
+ if (m_leader->m_objective == OBJECTIVE_NONE && m_objective == OBJECTIVE_NONE && m_leader->m_nPedState == PED_CHAT && m_nPedState == PED_CHAT) {
SetObjective(OBJECTIVE_NONE);
} else {
SetObjective(OBJECTIVE_GOTO_CHAR_ON_FOOT, m_leader);
SetObjectiveTimer(0);
}
-#endif
}
- if (m_nPedState == PED_IDLE && m_leader->IsPlayer()) {
+ if (m_nPedState == PED_IDLE && m_leader->IsPlayer() && !bDontFight) {
if (ScanForThreats() && m_threatEntity) {
m_pLookTarget = m_threatEntity;
m_pLookTarget->RegisterReference((CEntity **) &m_pLookTarget);
@@ -636,12 +696,14 @@ CPed::UpdateFromLeader(void)
m_objectiveTimer = m_leader->m_objectiveTimer;
break;
case OBJECTIVE_GUARD_SPOT:
- SetObjective(OBJECTIVE_GUARD_SPOT, m_leader->m_vecSeekPosEx);
+ SetObjective(OBJECTIVE_GUARD_SPOT, m_leader->m_vecSpotToGuard);
m_objectiveTimer = m_leader->m_objectiveTimer;
break;
case OBJECTIVE_KILL_CHAR_ON_FOOT:
case OBJECTIVE_KILL_CHAR_ANY_MEANS:
case OBJECTIVE_GOTO_CHAR_ON_FOOT:
+ case OBJECTIVE_GOTO_CHAR_ON_FOOT_WALKING:
+ case OBJECTIVE_HASSLE_CHAR:
if (m_leader->m_pedInObjective) {
SetObjective(m_leader->m_objective, m_leader->m_pedInObjective);
m_objectiveTimer = m_leader->m_objectiveTimer;
@@ -650,6 +712,7 @@ CPed::UpdateFromLeader(void)
case OBJECTIVE_ENTER_CAR_AS_PASSENGER:
case OBJECTIVE_ENTER_CAR_AS_DRIVER:
if (m_leader->m_carInObjective) {
+ m_leaveCarTimer = CTimer::GetTimeInMilliseconds() + 150;
SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, m_leader->m_carInObjective);
return;
}
@@ -678,9 +741,7 @@ CPed::UpdateFromLeader(void)
// fall through
default:
if (m_pMyVehicle && m_objective != OBJECTIVE_LEAVE_CAR) {
-#ifdef VC_PED_PORTS
m_leaveCarTimer = CTimer::GetTimeInMilliseconds() + 250;
-#endif
SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
}
@@ -697,10 +758,7 @@ CPed::RestorePreviousObjective(void)
return;
if (m_objective != OBJECTIVE_LEAVE_CAR && m_objective != OBJECTIVE_ENTER_CAR_AS_PASSENGER && m_objective != OBJECTIVE_ENTER_CAR_AS_DRIVER
-#if defined VC_PED_PORTS || defined FIX_BUGS
- && m_nPedState != PED_CARJACK
-#endif
- )
+ && m_nPedState != PED_CARJACK)
m_pedInObjective = nil;
if (m_objective == OBJECTIVE_WAIT_IN_CAR_THEN_GET_OUT) {
@@ -752,21 +810,36 @@ CPed::ProcessObjective(void)
}
switch (m_objective) {
- case OBJECTIVE_NONE:
- case OBJECTIVE_GUARD_AREA:
- case OBJECTIVE_FOLLOW_CAR_IN_CAR:
- case OBJECTIVE_FIRE_AT_OBJECT_FROM_VEHICLE:
- case OBJECTIVE_DESTROY_OBJECT:
- case OBJECTIVE_GOTO_AREA_IN_CAR:
- case OBJECTIVE_FOLLOW_CAR_ON_FOOT_WITH_OFFSET:
- case OBJECTIVE_SET_LEADER:
- break;
case OBJECTIVE_WAIT_ON_FOOT:
- 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_WAIT_ON_FOOT_FOR_COP:
+ if (!m_pedInObjective) {
+ m_objective = OBJECTIVE_NONE;
+ SetWanderPath(CGeneral::GetRandomNumberInRange(0.f, 8.f));
+ } else if (m_pedInObjective->m_nPedType == PEDTYPE_COP && m_pedInObjective->m_nPedState == PED_DEAD) {
+ m_objective = OBJECTIVE_NONE;
+ SetWanderPath(CGeneral::GetRandomNumberInRange(0.f, 8.f));
+ m_pedInObjective = nil;
+ }
break;
case OBJECTIVE_FLEE_ON_FOOT_TILL_SAFE:
+ if (m_leaveCarTimer >= CTimer::GetTimeInMilliseconds())
+ break;
+
if (InVehicle()) {
SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
bFleeAfterExitingCar = true;
@@ -779,7 +852,7 @@ CPed::ProcessObjective(void)
break;
case OBJECTIVE_GUARD_SPOT:
{
- distWithTarget = m_vecSeekPosEx - GetPosition();
+ distWithTarget = m_vecSpotToGuard - GetPosition();
if (m_pedInObjective) {
SetLookFlag(m_pedInObjective, true);
m_pLookTarget = m_pedInObjective;
@@ -787,12 +860,14 @@ CPed::ProcessObjective(void)
TurnBody();
}
float distWithTargetSc = distWithTarget.Magnitude();
- if (2.0f * m_distanceToCountSeekDoneEx >= distWithTargetSc) {
- if (m_pedInObjective) {
- if (distWithTargetSc <= m_distanceToCountSeekDoneEx)
+ if (2.0f * m_radiusToGuard >= distWithTargetSc) {
+ if (m_pedInObjective && m_pedInObjective->m_nPedState != PED_DEAD) {
+ if (distWithTargetSc <= m_radiusToGuard)
SetIdle();
- else
- SetSeek(m_vecSeekPosEx, m_distanceToCountSeekDoneEx);
+ else {
+ CVector seekPos = m_vecSpotToGuard;
+ SetSeek(seekPos, m_radiusToGuard);
+ }
} else if (CTimer::GetTimeInMilliseconds() > m_lookTimer) {
int threatType = ScanForThreats();
SetLookTimer(CGeneral::GetRandomNumberInRange(500, 1500));
@@ -804,7 +879,8 @@ CPed::ProcessObjective(void)
}
}
} else {
- SetSeek(m_vecSeekPosEx, m_distanceToCountSeekDoneEx);
+ CVector seekPos = m_vecSpotToGuard;
+ SetSeek(seekPos, m_radiusToGuard);
}
break;
}
@@ -825,9 +901,9 @@ CPed::ProcessObjective(void)
break;
}
if (InVehicle()) {
- if (distWithTarget.Magnitude() >= 20.0f
- || m_pMyVehicle->m_vecMoveSpeed.MagnitudeSqr() >= sq(0.02f)) {
- if (m_pMyVehicle->pDriver == this
+ if (distWithTarget.Magnitude() >= 20.0f || m_pMyVehicle->m_vecMoveSpeed.MagnitudeSqr() >= sq(0.02f)) {
+
+ if (((m_pMyVehicle->pDriver == this && m_pMyVehicle->AutoPilot.m_nCarMission == MISSION_NONE) || m_pMyVehicle->AutoPilot.m_nCarMission == MISSION_CRUISE)
&& !m_pMyVehicle->m_nGettingInFlags) {
m_pMyVehicle->SetStatus(STATUS_PHYSICS);
m_pMyVehicle->AutoPilot.m_nPrevRouteNode = 0;
@@ -842,8 +918,7 @@ CPed::ProcessObjective(void)
}
} else {
bool targetHasVeh = m_pedInObjective->bInVehicle;
- if (!targetHasVeh
- || targetHasVeh && m_pedInObjective->m_pMyVehicle->CanPedExitCar()) {
+ if (!targetHasVeh || targetHasVeh && m_pedInObjective->m_pMyVehicle->CanPedExitCar(false)) {
m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0;
m_pMyVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
@@ -859,7 +934,7 @@ CPed::ProcessObjective(void)
float closestVehDist = 60.0f;
int16 lastVehicle;
CEntity* vehicles[8];
- CWorld::FindObjectsInRange(GetPosition(), 25.0f, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
+ CWorld::FindObjectsInRange(GetPosition(), ENTER_CAR_MAX_DIST, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
CVehicle *foundVeh = nil;
for(int i = 0; i < lastVehicle; i++) {
CVehicle *nearVeh = (CVehicle*)vehicles[i];
@@ -870,7 +945,7 @@ CPed::ProcessObjective(void)
*/
CVector vehDistVec = nearVeh->GetPosition() - GetPosition();
if (vehDistVec.Magnitude() < closestVehDist && m_pedInObjective->m_pMyVehicle != nearVeh
- && nearVeh->CanPedOpenLocks(this)) {
+ && nearVeh->CanPedOpenLocks(this) && nearVeh->m_fHealth > 250.f) {
foundVeh = nearVeh;
closestVehDist = vehDistVec.Magnitude();
@@ -892,11 +967,18 @@ CPed::ProcessObjective(void)
CZoneInfo zoneInfo;
int chosenCarClass;
CTheZones::GetZoneInfoForTimeOfDay(&ourPos, &zoneInfo);
- int chosenModel = CCarCtrl::ChooseModel(&zoneInfo, &ourPos, &chosenCarClass);
- CAutomobile *newVeh = new CAutomobile(chosenModel, RANDOM_VEHICLE);
+ int chosenModel = CCarCtrl::ChooseModel(&zoneInfo, &chosenCarClass);
+ CVehicle *newVeh = nil;
+ if (chosenModel != -1) {
+ if (CModelInfo::IsBikeModel(chosenModel)) {
+ newVeh = new CBike(chosenModel, RANDOM_VEHICLE);
+ } else {
+ newVeh = new CAutomobile(chosenModel, RANDOM_VEHICLE);
+ }
+ }
if (newVeh) {
- newVeh->GetMatrix().GetPosition() = ThePaths.m_pathNodes[closestNode].GetPosition();
- newVeh->GetMatrix().GetPosition().z += 4.0f;
+ newVeh->GetMatrix().GetPosition() = ThePaths.m_pathNodes[closestNode].GetPosition();
+ newVeh->GetMatrix().GetPosition().z += 4.0f;
newVeh->SetHeading(DEGTORAD(200.0f));
newVeh->SetStatus(STATUS_ABANDONED);
newVeh->m_nDoorLock = CARLOCK_UNLOCKED;
@@ -921,348 +1003,28 @@ CPed::ProcessObjective(void)
}
case OBJECTIVE_KILL_CHAR_ON_FOOT:
{
- bool killPlayerInNoPoliceZone = false;
if (m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT && InVehicle()) {
SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
break;
}
if (!m_pedInObjective || m_pedInObjective->DyingOrDead()) {
- ClearLookFlag();
bObjectiveCompleted = true;
+ ClearLookFlag();
SetMoveAnim();
break;
}
- if (m_pedInObjective->IsPlayer() && CCullZones::NoPolice())
- killPlayerInNoPoliceZone = true;
-
- if (!bNotAllowedToDuck || killPlayerInNoPoliceZone) {
- if (m_nPedType == PEDTYPE_COP && !m_pedInObjective->GetWeapon()->IsTypeMelee() && !GetWeapon()->IsTypeMelee())
- bNotAllowedToDuck = true;
- } else {
- if (!m_pedInObjective->bInVehicle) {
- if (m_pedInObjective->GetWeapon()->IsTypeMelee() || GetWeapon()->IsTypeMelee()) {
- bNotAllowedToDuck = false;
- bCrouchWhenShooting = false;
- } else if (DuckAndCover()) {
- break;
- }
- } else {
- bNotAllowedToDuck = false;
- bCrouchWhenShooting = false;
- }
- }
- if (m_leaveCarTimer > CTimer::GetTimeInMilliseconds() && !bKindaStayInSamePlace) {
- SetMoveState(PEDMOVE_STILL);
- break;
- }
- if (m_pedInObjective->IsPlayer()) {
- CPlayerPed *player = FindPlayerPed();
- if (m_nPedType == PEDTYPE_COP && player->m_pWanted->m_bIgnoredByCops
- || player->m_pWanted->m_bIgnoredByEveryone
- || m_pedInObjective->bIsInWater
- || m_pedInObjective->m_nPedState == PED_ARRESTED) {
-
- if (m_nPedState != PED_ARREST_PLAYER)
- SetIdle();
-
- break;
- }
- }
- CWeaponInfo *wepInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
- float wepRange = wepInfo->m_fRange;
- float maxDistToKeep;
- if (GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED) {
- maxDistToKeep = wepRange / 3.0f;
- } else {
- if (m_nPedState == PED_FIGHT) {
- if (!IsPlayer() && !(m_pedStats->m_flags & STAT_CAN_KICK))
- wepRange = 2.0f;
- } else {
- wepRange = 1.3f;
- }
- maxDistToKeep = wepRange;
- }
- if (m_pedInObjective->m_getUpTimer > CTimer::GetTimeInMilliseconds() && maxDistToKeep < 2.5f) {
- maxDistToKeep = 2.5f;
- }
- if (m_pedInObjective->IsPlayer() && m_nPedType != PEDTYPE_COP
- && CharCreatedBy != MISSION_CHAR && FindPlayerPed()->m_pWanted->m_CurrentCops) {
- SetObjective(OBJECTIVE_FLEE_ON_FOOT_TILL_SAFE);
- break;
- }
- if (m_pedInObjective->m_fHealth <= 0.0f) {
- bObjectiveCompleted = true;
- bScriptObjectiveCompleted = true;
- SetMoveAnim();
- break;
- }
- float distWithTargetSc = distWithTarget.Magnitude();
- if (m_pedInObjective->bInVehicle && m_pedInObjective->m_nPedState != PED_DRAG_FROM_CAR) {
- CVehicle *vehOfTarget = m_pedInObjective->m_pMyVehicle;
- if (vehOfTarget->bIsInWater || vehOfTarget->GetStatus() == STATUS_PLAYER_DISABLED
- || m_pedInObjective->IsPlayer() && CPad::GetPad(0)->ArePlayerControlsDisabled()) {
- SetIdle();
- return;
- }
- SetLookFlag(vehOfTarget, false);
- if (m_nPedState != PED_CARJACK) {
- if (m_pedInObjective->m_nPedState != PED_ARRESTED) {
- if (m_attackTimer < CTimer::GetTimeInMilliseconds() && wepInfo->m_eWeaponFire != WEAPON_FIRE_MELEE
- && distWithTargetSc < wepRange && distWithTargetSc > 3.0f) {
-
- // I hope so
- CVector ourHead = GetMatrix() * CVector(0.5f, 0.0f, 0.6f);
- CVector maxShotPos = vehOfTarget->GetPosition() - ourHead;
- maxShotPos *= wepInfo->m_fRange / maxShotPos.Magnitude();
- maxShotPos += ourHead;
-
- CColPoint foundCol;
- CEntity *foundEnt;
-
- CWorld::bIncludeDeadPeds = true;
- CWorld::ProcessLineOfSight(ourHead, maxShotPos, foundCol, foundEnt, true, true, true, true, false, true, false);
- CWorld::bIncludeDeadPeds = false;
- if (foundEnt == vehOfTarget) {
- SetAttack(vehOfTarget);
- SetWeaponLockOnTarget(vehOfTarget);
- SetShootTimer(CGeneral::GetRandomNumberInRange(500, 2000));
- if (distWithTargetSc <= m_distanceToCountSeekDone) {
- SetAttackTimer(CGeneral::GetRandomNumberInRange(200, 500));
- SetMoveState(PEDMOVE_STILL);
- } else {
- SetAttackTimer(CGeneral::GetRandomNumberInRange(2000, 5000));
- }
- }
- } else if (m_nPedState != PED_ATTACK && !bKindaStayInSamePlace && !killPlayerInNoPoliceZone) {
- if (vehOfTarget) {
- if (m_nPedType == PEDTYPE_COP || vehOfTarget->bIsBus) {
- GoToNearestDoor(vehOfTarget);
- } else {
- m_vehDoor = 0;
- if (m_pedInObjective == vehOfTarget->pDriver || vehOfTarget->bIsBus) {
- m_vehDoor = CAR_DOOR_LF;
- } else if (m_pedInObjective == vehOfTarget->pPassengers[0]) {
- m_vehDoor = CAR_DOOR_RF;
- } else if (m_pedInObjective == vehOfTarget->pPassengers[1]) {
- m_vehDoor = CAR_DOOR_LR;
- } else if (m_pedInObjective == vehOfTarget->pPassengers[2]) {
- m_vehDoor = CAR_DOOR_RR;
- }
- // Unused
- // GetPositionToOpenCarDoor(vehOfTarget, m_vehDoor);
- SetSeekCar(vehOfTarget, m_vehDoor);
- SetMoveState(PEDMOVE_RUN);
- }
- }
- }
- }
- }
- SetMoveAnim();
- break;
- }
- if (m_nMoveState == PEDMOVE_STILL && IsPedInControl()) {
- SetLookFlag(m_pedInObjective, false);
- TurnBody();
- }
- if (m_nPedType == PEDTYPE_COP && distWithTargetSc < 1.5f && m_pedInObjective->IsPlayer()) {
- if (m_pedInObjective->m_getUpTimer > CTimer::GetTimeInMilliseconds()
- || m_pedInObjective->m_nPedState == PED_DRAG_FROM_CAR) {
+ if (m_pedInObjective) {
+ int status;
+ if (GetWeapon()->IsTypeMelee())
+ status = KillCharOnFootMelee(carOrOurPos, targetCarOrHisPos, distWithTarget);
+ else
+ status = KillCharOnFootArmed(carOrOurPos, targetCarOrHisPos, distWithTarget);
- ((CCopPed*)this)->SetArrestPlayer(m_pedInObjective);
+ if (status == WATCH_UNTIL_HE_DISAPPEARS)
return;
- }
- }
- if (!bKindaStayInSamePlace && !bStopAndShoot && m_nPedState != PED_ATTACK && !killPlayerInNoPoliceZone) {
- if (distWithTargetSc > wepRange
- || m_pedInObjective->m_getUpTimer > CTimer::GetTimeInMilliseconds()
- || m_pedInObjective->m_nPedState == PED_ARRESTED
- || m_pedInObjective->EnteringCar() && distWithTargetSc < 3.0f
- || distWithTargetSc > m_distanceToCountSeekDone && !CanSeeEntity(m_pedInObjective)) {
-
- if (m_pedInObjective->EnteringCar())
- maxDistToKeep = 2.0f;
-
- if (bUsePedNodeSeek) {
- CVector bestCoords(0.0f, 0.0f, 0.0f);
- m_vecSeekPos = m_pedInObjective->GetPosition();
-
- if (!m_pNextPathNode)
- FindBestCoordsFromNodes(m_vecSeekPos, &bestCoords);
-
- if (m_pNextPathNode)
- m_vecSeekPos = m_pNextPathNode->GetPosition();
-
- SetSeek(m_vecSeekPos, m_distanceToCountSeekDone);
- } else {
- SetSeek(m_pedInObjective, maxDistToKeep);
- }
- bCrouchWhenShooting = false;
- if (m_pedInObjective->m_pCurrentPhysSurface && distWithTargetSc < 5.0f) {
- if (wepRange <= 5.0f) {
- if (m_pedInObjective->IsPlayer()
- && FindPlayerPed()->m_bSpeedTimerFlag
- && (IsGangMember() || m_nPedType == PEDTYPE_COP)
- && GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED) {
- GiveWeapon(WEAPONTYPE_COLT45, 1000);
- SetCurrentWeapon(WEAPONTYPE_COLT45);
- }
- } else {
- bStopAndShoot = true;
- }
- SetMoveState(PEDMOVE_STILL);
- SetMoveAnim();
- break;
- }
- bStopAndShoot = false;
- SetMoveAnim();
+ if (status == CANT_ATTACK)
break;
- }
- }
- if (m_attackTimer < CTimer::GetTimeInMilliseconds()
- && distWithTargetSc < wepRange && m_pedInObjective->m_nPedState != PED_GETUP && m_pedInObjective->m_nPedState != PED_DRAG_FROM_CAR) {
- if (bIsDucking) {
- CAnimBlendAssociation *duckAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_DUCK_DOWN);
- if (duckAnim) {
- duckAnim->blendDelta = -2.0f;
- break;
- }
- bIsDucking = false;
- } else if (wepRange <= 5.0f) {
- SetMoveState(PEDMOVE_STILL);
- SetAttack(m_pedInObjective);
- m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(
- m_pedInObjective->GetPosition().x, m_pedInObjective->GetPosition().y,
- GetPosition().x, GetPosition().y);
- SetShootTimer(CGeneral::GetRandomNumberInRange(0.0f, 500.0f));
- SetAttackTimer(CGeneral::GetRandomNumberInRange(0.0f, 1500.0f));
- bObstacleShowedUpDuringKillObjective = false;
-
- } else {
- CVector target;
- CVector ourHead = GetMatrix() * CVector(0.5f, 0.0f, 0.6f);
- if (m_pedInObjective->IsPed())
- m_pedInObjective->m_pedIK.GetComponentPosition(target, PED_MID);
- else
- target = m_pedInObjective->GetPosition();
-
- target -= ourHead;
- target *= wepInfo->m_fRange / target.Magnitude();
- target += ourHead;
-
- CColPoint foundCol;
- CEntity *foundEnt = nil;
-
- CWorld::bIncludeDeadPeds = true;
- CWorld::ProcessLineOfSight(ourHead, target, foundCol, foundEnt, true, true, true, true, false, true, false);
- CWorld::bIncludeDeadPeds = false;
- if (foundEnt == m_pedInObjective) {
- SetAttack(m_pedInObjective);
- SetWeaponLockOnTarget(m_pedInObjective);
- SetShootTimer(CGeneral::GetRandomNumberInRange(500.0f, 2000.0f));
-
- int time;
- if (distWithTargetSc <= maxDistToKeep)
- time = CGeneral::GetRandomNumberInRange(100.0f, 500.0f);
- else
- time = CGeneral::GetRandomNumberInRange(1500.0f, 3000.0f);
-
- SetAttackTimer(time);
- bObstacleShowedUpDuringKillObjective = false;
-
- } else {
- if (foundEnt) {
- if (foundEnt->IsPed()) {
- SetAttackTimer(CGeneral::GetRandomNumberInRange(500.0f, 1000.0f));
- bObstacleShowedUpDuringKillObjective = false;
- } else {
- if (foundEnt->IsObject()) {
- SetAttackTimer(CGeneral::GetRandomNumberInRange(200.0f, 400.0f));
- bObstacleShowedUpDuringKillObjective = true;
- } else if (foundEnt->IsVehicle()) {
- SetAttackTimer(CGeneral::GetRandomNumberInRange(400.0f, 600.0f));
- bObstacleShowedUpDuringKillObjective = true;
- } else {
- SetAttackTimer(CGeneral::GetRandomNumberInRange(700.0f, 1200.0f));
- bObstacleShowedUpDuringKillObjective = true;
- }
- }
-
- m_fleeFrom = foundEnt;
- m_fleeFrom->RegisterReference((CEntity**) &m_fleeFrom);
- }
- SetPointGunAt(m_pedInObjective);
- }
- }
- } else {
- if (!m_pedInObjective->m_pCurrentPhysSurface)
- bStopAndShoot = false;
-
- if (m_nPedState != PED_ATTACK && m_nPedState != PED_FIGHT) {
-
- // This is weird...
- if (bNotAllowedToDuck && bKindaStayInSamePlace) {
- if (!bIsDucking) {
- CAnimBlendAssociation* duckAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_DUCK_DOWN);
- if (!duckAnim || duckAnim->blendDelta < 0.0f) {
- CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_DUCK_DOWN, 4.0f);
- bIsDucking = true;
- }
- break;
- } else {
- CAnimBlendAssociation* duckAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_DUCK_DOWN);
- if (!duckAnim || duckAnim->blendDelta < 0.0f) {
- bIsDucking = false;
- } else {
- break;
- }
- }
- }
- if (bObstacleShowedUpDuringKillObjective) {
- if (m_nPedType == PEDTYPE_COP) {
- if (GetWeapon()->m_eWeaponType > WEAPONTYPE_COLT45
- || m_fleeFrom && m_fleeFrom->IsObject()) {
- maxDistToKeep = 6.0f;
- } else if (m_fleeFrom && m_fleeFrom->IsVehicle()) {
- maxDistToKeep = 4.0f;
- } else {
- maxDistToKeep = 2.0f;
- }
- } else {
- maxDistToKeep = 2.0f;
- }
- }
- if (distWithTargetSc <= maxDistToKeep) {
- SetMoveState(PEDMOVE_STILL);
- bIsPointingGunAt = true;
- if (m_nPedState != PED_AIM_GUN && !bDuckAndCover) {
- m_attackTimer = CTimer::GetTimeInMilliseconds();
- SetIdle();
- }
- } else {
- if (m_nPedState != PED_SEEK_ENTITY && m_nPedState != PED_SEEK_POS
- && !bStopAndShoot && !killPlayerInNoPoliceZone && !bKindaStayInSamePlace) {
- Say(SOUND_PED_ATTACK);
- SetSeek(m_pedInObjective, maxDistToKeep);
- bIsRunning = true;
- }
- }
- }
}
-
- if (distWithTargetSc < 2.5f && wepRange > 5.0f
- && wepInfo->m_eWeaponFire != WEAPON_FIRE_MELEE) {
-
- SetAttack(m_pedInObjective);
- if (m_attackTimer < CTimer::GetTimeInMilliseconds()) {
- int time = CGeneral::GetRandomNumberInRange(500.0f, 1000.0f);
- SetAttackTimer(time);
- SetShootTimer(time - 500);
- }
- SetMoveState(PEDMOVE_STILL);
- }
- if (CTimer::GetTimeInMilliseconds() > m_nPedStateTimer)
- m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(m_pedInObjective->GetPosition().x, m_pedInObjective->GetPosition().y, GetPosition().x, GetPosition().y);
-
SetMoveAnim();
break;
}
@@ -1280,15 +1042,21 @@ CPed::ProcessObjective(void)
time = 6000;
SetFindPathAndFlee(m_pedInObjective, time);
+ if (m_pedStats == CPedStats::ms_apPedStats[PEDSTAT_FIREMAN])
+ bMakeFleeScream = true;
}
break;
}
case OBJECTIVE_GOTO_CHAR_ON_FOOT:
+ case OBJECTIVE_GOTO_CHAR_ON_FOOT_WALKING:
+ case OBJECTIVE_HASSLE_CHAR:
{
if (m_pedInObjective) {
float safeDistance = 2.0f;
if (m_pedInObjective->bInVehicle)
safeDistance = 3.0f;
+ if (m_objective == OBJECTIVE_HASSLE_CHAR)
+ safeDistance = 1.0f;
float distWithTargetSc = distWithTarget.Magnitude();
if (m_nPedStateTimer < CTimer::GetTimeInMilliseconds()) {
@@ -1296,6 +1064,8 @@ CPed::ProcessObjective(void)
bScriptObjectiveCompleted = true;
if (m_nPedState != PED_ATTACK) {
SetIdle();
+ if (m_pLookTarget)
+ m_pLookTarget->CleanUpOldReference(&m_pLookTarget);
m_pLookTarget = m_pedInObjective;
m_pLookTarget->RegisterReference((CEntity **) &m_pLookTarget);
TurnBody();
@@ -1304,6 +1074,18 @@ CPed::ProcessObjective(void)
SetMoveState(m_pedInObjective->m_nMoveState);
else
SetMoveState(PEDMOVE_STILL);
+
+ if (m_objective == OBJECTIVE_HASSLE_CHAR) {
+ Say(SOUND_PED_COP_ASK_FOR_ID);
+ m_pedInObjective->Say(SOUND_PED_INNOCENT);
+ m_leaveCarTimer = CTimer::GetTimeInMilliseconds() + 3000;
+ m_pedInObjective->m_leaveCarTimer = CTimer::GetTimeInMilliseconds() + 3000;
+ SetObjective(OBJECTIVE_WANDER);
+ m_pedInObjective->SetObjective(OBJECTIVE_WANDER);
+ CVector2D dist = GetPosition() - m_pedInObjective->GetPosition();
+ m_nPathDir = CGeneral::GetNodeHeadingFromVector(dist.x, dist.y);
+ m_pedInObjective->m_nPathDir = CGeneral::GetNodeHeadingFromVector(-dist.x, -dist.y);
+ }
} else {
SetSeek(m_pedInObjective, safeDistance);
if (distWithTargetSc >= 5.0f) {
@@ -1329,6 +1111,8 @@ CPed::ProcessObjective(void)
}
}
}
+ if (m_objective == OBJECTIVE_GOTO_CHAR_ON_FOOT_WALKING && m_nMoveState > PEDMOVE_STILL)
+ SetMoveState(PEDMOVE_WALK);
}
} else {
SetObjective(OBJECTIVE_NONE);
@@ -1343,7 +1127,7 @@ CPed::ProcessObjective(void)
SetSeek(posToGo, 1.0f);
if (distWithTarget.Magnitude() <= 3.0f) {
SetSeek(posToGo, 1.0f);
- if (m_pedInObjective->m_nMoveState != PEDMOVE_STILL)
+ if (m_pedInObjective && m_pedInObjective->m_nMoveState != PEDMOVE_STILL)
SetMoveState(m_pedInObjective->m_nMoveState);
} else {
SetSeek(posToGo, 1.0f);
@@ -1376,21 +1160,28 @@ CPed::ProcessObjective(void)
if (m_objectiveTimer && m_objectiveTimer < CTimer::GetTimeInMilliseconds()) {
if (!EnteringCar()) {
bool foundSeat = false;
- if (m_carInObjective->pPassengers[0] || m_carInObjective->m_nGettingInFlags & CAR_DOOR_FLAG_RF) {
- if (m_carInObjective->pPassengers[1] || m_carInObjective->m_nGettingInFlags & CAR_DOOR_FLAG_LR) {
- if (m_carInObjective->pPassengers[2] || m_carInObjective->m_nGettingInFlags & CAR_DOOR_FLAG_RR) {
- foundSeat = false;
+ if (m_carInObjective->IsBike()) {
+ if (!m_carInObjective->pPassengers[0] && !(m_carInObjective->m_nGettingInFlags & (CAR_DOOR_FLAG_RR | CAR_DOOR_FLAG_LR))) {
+ m_vehDoor = CAR_DOOR_RR;
+ foundSeat = true;
+ }
+ } else {
+ if (m_carInObjective->pPassengers[0] || m_carInObjective->m_nGettingInFlags & CAR_DOOR_FLAG_RF) {
+ if (m_carInObjective->pPassengers[1] || m_carInObjective->m_nGettingInFlags & CAR_DOOR_FLAG_LR) {
+ if (m_carInObjective->pPassengers[2] || m_carInObjective->m_nGettingInFlags & CAR_DOOR_FLAG_RR) {
+ foundSeat = false;
+ } else {
+ m_vehDoor = CAR_DOOR_RR;
+ foundSeat = true;
+ }
} else {
- m_vehDoor = CAR_DOOR_RR;
+ m_vehDoor = CAR_DOOR_LR;
foundSeat = true;
}
} else {
- m_vehDoor = CAR_DOOR_LR;
+ m_vehDoor = CAR_DOOR_RF;
foundSeat = true;
}
- } else {
- m_vehDoor = CAR_DOOR_RF;
- foundSeat = true;
}
for (int i = 2; i < m_carInObjective->m_nNumMaxPassengers; ++i) {
if (!m_carInObjective->pPassengers[i] && !(m_carInObjective->m_nGettingInFlags & CAR_DOOR_FLAG_RF)) {
@@ -1411,12 +1202,9 @@ CPed::ProcessObjective(void)
case OBJECTIVE_ENTER_CAR_AS_DRIVER:
{
if (!m_carInObjective || bInVehicle) {
-#ifdef VC_PED_PORTS
if (bInVehicle && m_pMyVehicle != m_carInObjective) {
SetExitCar(m_pMyVehicle, 0);
- } else
-#endif
- {
+ } else {
bObjectiveCompleted = true;
bScriptObjectiveCompleted = true;
RestorePreviousState();
@@ -1434,11 +1222,7 @@ CPed::ProcessObjective(void)
return;
}
if (m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER) {
- if (m_carInObjective->pDriver
-#ifdef VC_PED_PORTS
- && !IsPlayer()
-#endif
- ) {
+ if (m_carInObjective->pDriver && !IsPlayer()) {
if (m_carInObjective->pDriver->m_objective == OBJECTIVE_KILL_CHAR_ANY_MEANS && m_carInObjective->pDriver != m_pedInObjective) {
SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, m_carInObjective);
m_carInObjective->bIsBeingCarJacked = false;
@@ -1447,9 +1231,7 @@ CPed::ProcessObjective(void)
}
} else if (m_objective != OBJECTIVE_ENTER_CAR_AS_PASSENGER) {
if (m_carInObjective->pDriver
-#ifdef VC_PED_PORTS
&& (CharCreatedBy != MISSION_CHAR || m_carInObjective->pDriver->CharCreatedBy != RANDOM_CHAR)
-#endif
) {
if (m_carInObjective->pDriver->m_nPedType == m_nPedType) {
SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, m_carInObjective);
@@ -1479,10 +1261,7 @@ CPed::ProcessObjective(void)
WarpPedToNearEntityOffScreen(m_carInObjective);
if (CharCreatedBy != MISSION_CHAR || m_prevObjective == OBJECTIVE_KILL_CHAR_ANY_MEANS
-#ifdef VC_PED_PORTS
- || IsPlayer() && !CPad::GetPad(0)->ArePlayerControlsDisabled()
-#endif
- ) {
+ || IsPlayer() && !CPad::GetPad(0)->ArePlayerControlsDisabled()) {
RestorePreviousObjective();
RestorePreviousState();
if (IsPedInControl())
@@ -1503,6 +1282,15 @@ CPed::ProcessObjective(void)
}
break;
}
+ case OBJECTIVE_DESTROY_OBJECT:
+ if (m_pPointGunAt) {
+ if (m_nPedState != PED_ATTACK)
+ SetAttack(m_pPointGunAt);
+ } else {
+ bScriptObjectiveCompleted = true;
+ RestorePreviousObjective();
+ }
+ break;
case OBJECTIVE_DESTROY_CAR:
{
if (!m_carInObjective) {
@@ -1526,9 +1314,7 @@ CPed::ProcessObjective(void)
break;
}
- if (m_attackTimer < CTimer::GetTimeInMilliseconds() && wepInfo->m_eWeaponFire != WEAPON_FIRE_MELEE
- && distWithTargetSc < wepRange) {
-
+ if (m_attackTimer < CTimer::GetTimeInMilliseconds() && distWithTargetSc < wepRange) {
// I hope so
CVector ourHead = GetMatrix() * CVector(0.5f, 0.0f, 0.6f);
CVector maxShotPos = m_carInObjective->GetPosition() - ourHead;
@@ -1553,74 +1339,30 @@ CPed::ProcessObjective(void)
}
}
} else if (m_nPedState != PED_ATTACK && !bKindaStayInSamePlace) {
+ if (wepRange <= 5.0f) {
+ if (Abs(distWithTarget.x) > wepRange || Abs(distWithTarget.y) > wepRange ||
+ (distWithTarget.z > -1.0f && distWithTarget.z < 0.3)) {
+ SetSeek(m_carInObjective, 3.0f);
+ SetMoveState(PEDMOVE_RUN);
+ } else {
+ SetIdle();
+ }
+ } else {
+ float safeDistance = wepRange * 0.25f;
- float safeDistance;
- if (wepRange <= 5.0f)
- safeDistance = 3.0f;
- else
- safeDistance = wepRange * 0.25f;
-
- SetSeek(m_carInObjective, safeDistance);
- SetMoveState(PEDMOVE_RUN);
+ SetSeek(m_carInObjective, safeDistance);
+ SetMoveState(PEDMOVE_RUN);
+ }
}
SetLookFlag(m_carInObjective, false);
TurnBody();
break;
}
- case OBJECTIVE_GOTO_AREA_ANY_MEANS:
- {
- distWithTarget = m_nextRoutePointPos - GetPosition();
- distWithTarget.z = 0.0f;
- if (InVehicle()) {
- CCarAI::GetCarToGoToCoors(m_pMyVehicle, &m_nextRoutePointPos);
- CCarCtrl::RegisterVehicleOfInterest(m_pMyVehicle);
- if (distWithTarget.MagnitudeSqr() < sq(20.0f)) {
- m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0;
- ForceStoredObjective(OBJECTIVE_GOTO_AREA_ANY_MEANS);
- SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
- }
- break;
- }
- if (distWithTarget.Magnitude() > 30.0f) {
- if (m_pMyVehicle) {
- m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0;
- } else {
- float closestVehDist = SQR(60.0f);
- int16 lastVehicle;
- CEntity* vehicles[8];
- CWorld::FindObjectsInRange(GetPosition(), 25.0f, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
- CVehicle* foundVeh = nil;
- for (int i = 0; i < lastVehicle; i++) {
- CVehicle* nearVeh = (CVehicle*)vehicles[i];
- /*
- Not used.
- CVector vehSpeed = nearVeh->GetSpeed();
- CVector ourSpeed = GetSpeed();
- */
- CVector vehDistVec = nearVeh->GetPosition() - GetPosition();
- if (vehDistVec.MagnitudeSqr() < closestVehDist
- && m_pedInObjective->m_pMyVehicle != nearVeh)
- {
- foundVeh = nearVeh;
- closestVehDist = vehDistVec.MagnitudeSqr();
- }
- }
- m_pMyVehicle = foundVeh;
- if (m_pMyVehicle) {
- m_pMyVehicle->RegisterReference((CEntity **) &m_pMyVehicle);
- m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0;
- SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, m_pMyVehicle);
- }
- }
- break;
- }
- // fall through
- }
case OBJECTIVE_GOTO_AREA_ON_FOOT:
case OBJECTIVE_RUN_TO_AREA:
+ case OBJECTIVE_SPRINT_TO_AREA:
{
- if ((m_objective == OBJECTIVE_GOTO_AREA_ON_FOOT || m_objective == OBJECTIVE_RUN_TO_AREA)
- && InVehicle()) {
+ if (InVehicle()) {
SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
} else {
distWithTarget = m_nextRoutePointPos - GetPosition();
@@ -1634,12 +1376,23 @@ CPed::ProcessObjective(void)
CVector bestCoords(0.0f, 0.0f, 0.0f);
m_vecSeekPos = m_nextRoutePointPos;
- if (!m_pNextPathNode)
- FindBestCoordsFromNodes(m_vecSeekPos, &bestCoords);
-
+ if (!m_pNextPathNode) {
+ bool found = FindBestCoordsFromNodes(m_vecSeekPos, &bestCoords);
+ if (m_pNextPathNode) {
+ // Because it already does that if it finds better coords.
+ if (!found) {
+ bestCoords = CPathFind::TakeWidthIntoAccountForWandering(m_pNextPathNode, m_randomSeed);
+ }
+ if ((bestCoords - GetPosition()).Magnitude2D() < m_distanceToCountSeekDone) {
+ m_pNextPathNode = nil;
+ bUsePedNodeSeek = false;
+ }
+ }
+ }
if (m_pNextPathNode)
- m_vecSeekPos = m_pNextPathNode->GetPosition();
+ m_vecSeekPos = CPathFind::TakeWidthIntoAccountForWandering(m_pNextPathNode, m_randomSeed);
}
+ CVector seekPos = m_vecSeekPos;
SetSeek(m_vecSeekPos, m_distanceToCountSeekDone);
}
}
@@ -1676,7 +1429,8 @@ CPed::ProcessObjective(void)
int nextPoint = GetNextPointOnRoute();
m_nextRoutePointPos = CRouteNode::GetPointPosition(nextPoint);
} else {
- SetSeek(m_nextRoutePointPos, 0.8f);
+ CVector seekPos = m_nextRoutePointPos;
+ SetSeek(seekPos, 0.8f);
}
break;
case OBJECTIVE_SOLICIT_VEHICLE:
@@ -1740,32 +1494,27 @@ CPed::ProcessObjective(void)
}
case OBJECTIVE_BUY_ICE_CREAM:
if (m_carInObjective) {
- if (m_nPedState != PED_FLEE_ENTITY && m_nPedState != PED_BUY_ICECREAM)
+ if (m_nPedState != PED_FLEE_ENTITY && m_nPedState != PED_BUY_ICECREAM && m_nPedState != PED_CHAT)
SetSeekCar(m_carInObjective, 0);
- } else {
- RestorePreviousObjective();
- RestorePreviousState();
- if (IsPedInControl())
- m_pMyVehicle = nil;
}
break;
case OBJECTIVE_STEAL_ANY_CAR:
+ case OBJECTIVE_STEAL_ANY_MISSION_CAR:
{
if (bInVehicle) {
bScriptObjectiveCompleted = true;
RestorePreviousObjective();
} else if (m_carJackTimer < CTimer::GetTimeInMilliseconds()) {
CVehicle *carToSteal = nil;
- float closestCarDist = ENTER_CAR_MAX_DIST;
+ float closestCarDist = nEnterCarRangeMultiplier * ENTER_CAR_MAX_DIST;
CVector pos = GetPosition();
int16 lastVehicle;
CEntity *vehicles[8];
- // NB: This should've been ENTER_CAR_MAX_DIST actually, and is fixed in VC.
- CWorld::FindObjectsInRange(pos, CHECK_NEARBY_THINGS_MAX_DIST, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
+ CWorld::FindObjectsInRange(pos, closestCarDist, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
for(int i = 0; i < lastVehicle; i++) {
CVehicle *nearVeh = (CVehicle*)vehicles[i];
- if (nearVeh->VehicleCreatedBy != MISSION_VEHICLE) {
+ if (m_objective == OBJECTIVE_STEAL_ANY_MISSION_CAR || nearVeh->VehicleCreatedBy != MISSION_VEHICLE) {
if (nearVeh->m_vecMoveSpeed.Magnitude() <= 0.1f) {
if (nearVeh->CanPedOpenLocks(this)) {
CVector vehDistVec = GetPosition() - nearVeh->GetPosition();
@@ -1813,14 +1562,14 @@ CPed::ProcessObjective(void)
float distWithTargetScSqr = distWithTarget.MagnitudeSqr();
if (distWithTargetScSqr <= sq(10.0f)) {
if (distWithTargetScSqr <= sq(1.4f)) {
- CAnimBlendAssociation *reloadAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_AK_RELOAD);
+ CAnimBlendAssociation *reloadAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_PARTIAL_FUCKU);
m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(
m_pedInObjective->GetPosition().x, m_pedInObjective->GetPosition().y,
GetPosition().x, GetPosition().y);
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_STD_PARTIAL_PUNCH, 8.0f);
punchAssoc->flags |= ASSOC_DELETEFADEDOUT;
punchAssoc->flags |= ASSOC_FADEOUTWHENDONE;
@@ -1832,7 +1581,7 @@ CPed::ProcessObjective(void)
Say(SOUND_PED_MUGGING);
bRichFromMugging = true;
- // VC FIX: ClearObjective() clears m_pedInObjective in VC (also same with VC_PED_PORTS), so get it before call
+ // FIX: ClearObjective() clears m_pedInObjective, so get it before call
CPed *victim = m_pedInObjective;
ClearObjective();
if (victim->m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT
@@ -1850,7 +1599,7 @@ CPed::ProcessObjective(void)
if (weaponType != WEAPONTYPE_UNARMED && weaponType != WEAPONTYPE_BASEBALLBAT)
SetCurrentWeapon(WEAPONTYPE_UNARMED);
- CAnimBlendAssociation *newReloadAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_AK_RELOAD, 8.0f);
+ CAnimBlendAssociation *newReloadAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_PARTIAL_FUCKU, 8.0f);
newReloadAssoc->flags |= ASSOC_DELETEFADEDOUT;
newReloadAssoc->flags |= ASSOC_FADEOUTWHENDONE;
}
@@ -1866,13 +1615,230 @@ CPed::ProcessObjective(void)
SetWanderPath(CGeneral::GetRandomNumber() & 7);
}
} else {
-#ifdef VC_PED_PORTS
m_objective = OBJECTIVE_NONE;
-#endif
ClearObjective();
}
+ }
+ // fall through
+ case OBJECTIVE_WANDER:
+ if (CTimer::GetTimeInMilliseconds() > m_leaveCarTimer && !bInVehicle) {
+ m_leaveCarTimer = 0;
+ m_objective = OBJECTIVE_NONE;
+ SetWanderPath(m_nPathDir);
+ }
+ break;
+ case OBJECTIVE_LEAVE_CAR_AND_DIE:
+ {
+ if (CTimer::GetTimeInMilliseconds() > m_leaveCarTimer) {
+ if (InVehicle()) {
+ if (m_nPedState != PED_EXIT_CAR && m_nPedState != PED_DRAG_FROM_CAR && m_nPedState != PED_EXIT_TRAIN) {
+ if (m_pMyVehicle->IsBoat())
+ SetExitBoat(m_pMyVehicle);
+ else if (m_pMyVehicle->bIsBus)
+ SetExitCar(m_pMyVehicle, 0);
+ else {
+ eCarNodes doorNode = CAR_DOOR_LF;
+ if (m_pMyVehicle->pDriver != this) {
+ if (m_pMyVehicle->pPassengers[0] == this) {
+ doorNode = CAR_DOOR_RF;
+ } else if (m_pMyVehicle->pPassengers[1] == this) {
+ doorNode = CAR_DOOR_LR;
+ } else if (m_pMyVehicle->pPassengers[2] == this) {
+ doorNode = CAR_DOOR_RR;
+ }
+ }
+ SetBeingDraggedFromCar(m_pMyVehicle, doorNode, false);
+ }
+ }
+ }
+ }
+ break;
+ }
+ case OBJECTIVE_GOTO_AREA_ANY_MEANS:
+ {
+ distWithTarget = m_nextRoutePointPos - GetPosition();
+ distWithTarget.z = 0.0f;
+ if (InVehicle()) {
+ CCarAI::GetCarToGoToCoors(m_pMyVehicle, &m_nextRoutePointPos);
+ CCarCtrl::RegisterVehicleOfInterest(m_pMyVehicle);
+ if (distWithTarget.MagnitudeSqr() < sq(20.0f)) {
+ m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0;
+ ForceStoredObjective(OBJECTIVE_GOTO_AREA_ANY_MEANS);
+ SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
+ }
+ break;
+ }
+ if (distWithTarget.Magnitude() > 30.0f) {
+ if (m_pMyVehicle) {
+ m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0;
+ } else {
+ float closestVehDist = SQR(60.0f);
+ int16 lastVehicle;
+ CEntity* vehicles[8];
+ // NB: 25.0f in here is prolly a forgotten setting, all other places now use 30.0f (ENTER_CAR_MAX_DIST)
+ CWorld::FindObjectsInRange(GetPosition(), 25.0f, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
+ CVehicle* foundVeh = nil;
+ for (int i = 0; i < lastVehicle; i++) {
+ CVehicle* nearVeh = (CVehicle*)vehicles[i];
+ /*
+ Not used.
+ CVector vehSpeed = nearVeh->GetSpeed();
+ CVector ourSpeed = GetSpeed();
+ */
+ CVector vehDistVec = nearVeh->GetPosition() - GetPosition();
+ if (vehDistVec.MagnitudeSqr() < closestVehDist && m_pedInObjective->m_pMyVehicle != nearVeh) {
+ foundVeh = nearVeh;
+ closestVehDist = vehDistVec.MagnitudeSqr();
+ }
+ }
+ m_pMyVehicle = foundVeh;
+ if (m_pMyVehicle) {
+ m_pMyVehicle->RegisterReference((CEntity **) &m_pMyVehicle);
+ m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0;
+ SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, m_pMyVehicle);
+ }
+ }
+ break;
+ }
+ // Falls to different objectives in III and VC
+#ifdef FIX_BUGS
break;
+#else
+ // fall through
+#endif
}
+ case OBJECTIVE_GOTO_SEAT_ON_FOOT:
+ case OBJECTIVE_GOTO_ATM_ON_FOOT:
+ case OBJECTIVE_GOTO_BUS_STOP_ON_FOOT:
+ case OBJECTIVE_GOTO_PIZZA_ON_FOOT:
+ case OBJECTIVE_GOTO_SHELTER_ON_FOOT:
+ case OBJECTIVE_GOTO_ICE_CREAM_VAN_ON_FOOT:
+ 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_GOTO_SHELTER_ON_FOOT) {
+ if (m_nMoveState == PEDMOVE_RUN && distance.MagnitudeSqr() < SQR(2.0f)) {
+ SetMoveState(PEDMOVE_WALK);
+ bIsRunning = false;
+ }
+ if (CWeather::Rain < 0.2f && m_attractor) {
+ GetPedAttractorManager()->DeRegisterPed(this, m_attractor);
+ return;
+ }
+ }
+ else if (m_objective == OBJECTIVE_GOTO_ICE_CREAM_VAN_ON_FOOT) {
+ if (m_nMoveState == PEDMOVE_RUN && distance.MagnitudeSqr() < 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) {
+ m_vecSeekPos = m_nextRoutePointPos;
+ 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_GOTO_SEAT_ON_FOOT:
+ if (!bTurnedAroundOnAttractor) {
+ ClearObjective();
+ SetWaitState(WAITSTATE_SIT_DOWN, 0);
+ }
+ else {
+ ClearObjective();
+ SetWaitState(WAITSTATE_SIT_DOWN_RVRS, 0);
+ }
+ break;
+ case OBJECTIVE_GOTO_ATM_ON_FOOT:
+ ClearObjective();
+ SetWaitState(WAITSTATE_USE_ATM, 0);
+ break;
+ case OBJECTIVE_GOTO_BUS_STOP_ON_FOOT:
+ ClearObjective();
+ SetObjective(OBJECTIVE_WAIT_ON_FOOT_AT_BUS_STOP);
+ break;
+ case OBJECTIVE_GOTO_PIZZA_ON_FOOT:
+ ClearObjective();
+ m_prevObjective = OBJECTIVE_NONE;
+ SetObjective(OBJECTIVE_WAIT_ON_FOOT);
+ m_objectiveTimer = CTimer::GetTimeInMilliseconds() + m_attractor->GetHeadOfQueueWaitTime();
+ break;
+ case OBJECTIVE_GOTO_SHELTER_ON_FOOT:
+ m_prevObjective = OBJECTIVE_NONE;
+ SetObjective(OBJECTIVE_WAIT_ON_FOOT_AT_SHELTER);
+ break;
+ case OBJECTIVE_GOTO_ICE_CREAM_VAN_ON_FOOT:
+ m_prevObjective = OBJECTIVE_NONE;
+ SetObjective(OBJECTIVE_WAIT_ON_FOOT_AT_ICE_CREAM_VAN);
+ break;
+ }
+ } else {
+ m_prevObjective = OBJECTIVE_NONE;
+ SetObjective(OBJECTIVE_WAIT_ON_FOOT);
+ m_objectiveTimer = 0;
+ }
+ }
+ }
+ }
+ return;
case OBJECTIVE_FLEE_CAR:
if (!bInVehicle && m_nPedState != PED_FLEE_ENTITY && m_pMyVehicle) {
RestorePreviousObjective();
@@ -1882,24 +1848,20 @@ CPed::ProcessObjective(void)
// fall through
case OBJECTIVE_LEAVE_CAR:
if (CTimer::GetTimeInMilliseconds() > m_leaveCarTimer) {
- if (InVehicle()
-#ifdef VC_PED_PORTS
- && (FindPlayerPed() != this || !CPad::GetPad(0)->GetAccelerate()
- || bBusJacked)
-#endif
- ) {
+ if (InVehicle() &&
+ (FindPlayerPed() != this || !CPad::GetPad(0)->GetAccelerate() || bBusJacked)) {
+
if (m_nPedState != PED_EXIT_CAR && m_nPedState != PED_DRAG_FROM_CAR && m_nPedState != PED_EXIT_TRAIN
&& (m_nPedType != PEDTYPE_COP
-#ifdef VC_PED_PORTS
|| m_pMyVehicle->IsBoat()
-#endif
|| m_pMyVehicle->m_vecMoveSpeed.MagnitudeSqr2D() < sq(0.005f))) {
+#ifdef GTA_TRAIN
if (m_pMyVehicle->IsTrain())
SetExitTrain(m_pMyVehicle);
-#ifdef VC_PED_PORTS
- else if (m_pMyVehicle->IsBoat())
- SetExitBoat(m_pMyVehicle);
+ else
#endif
+ if (m_pMyVehicle->IsBoat())
+ SetExitBoat(m_pMyVehicle);
else
SetExitCar(m_pMyVehicle, 0);
}
@@ -1907,36 +1869,162 @@ CPed::ProcessObjective(void)
RestorePreviousObjective();
}
}
+ if (bHeldHostageInCar) {
+ if (CTheScripts::IsPlayerOnAMission()) {
+ CVehicle *playerVeh = FindPlayerVehicle();
+ if (playerVeh && playerVeh->IsPassenger(this)) {
+ if (m_leaveCarTimer != 0)
+ m_leaveCarTimer = 0;
+ }
+ }
+ }
break;
-#ifdef VC_PED_PORTS
- case OBJECTIVE_LEAVE_CAR_AND_DIE:
- {
- if (CTimer::GetTimeInMilliseconds() > m_leaveCarTimer) {
- if (InVehicle()) {
- if (m_nPedState != PED_EXIT_CAR && m_nPedState != PED_DRAG_FROM_CAR && m_nPedState != PED_EXIT_TRAIN) {
- if (m_pMyVehicle->IsBoat())
- SetExitBoat(m_pMyVehicle);
- else if (m_pMyVehicle->bIsBus)
- SetExitCar(m_pMyVehicle, 0);
- else {
- eCarNodes doorNode = CAR_DOOR_LF;
- if (m_pMyVehicle->pDriver != this) {
- if (m_pMyVehicle->pPassengers[0] == this) {
- doorNode = CAR_DOOR_RF;
- } else if (m_pMyVehicle->pPassengers[1] == this) {
- doorNode = CAR_DOOR_LR;
- } else if (m_pMyVehicle->pPassengers[2] == this) {
- doorNode = CAR_DOOR_RR;
- }
+ case OBJECTIVE_AIM_GUN_AT:
+ if (m_pedInObjective) {
+ if (!bObstacleShowedUpDuringKillObjective)
+ SetPointGunAt(m_pedInObjective);
+
+ if (m_nMoveState == PEDMOVE_STILL && IsPedInControl()) {
+ SetLookFlag(m_pedInObjective, false);
+ TurnBody();
+ }
+ } else {
+ ClearObjective();
+ }
+ break;
+ case OBJECTIVE_WAIT_ON_FOOT_AT_SHELTER:
+ SetIdle();
+ if (m_attractor && CWeather::Rain < 0.2f)
+ GetPedAttractorManager()->DeRegisterPed(this, m_attractor);
+ break;
+ case OBJECTIVE_KILL_CHAR_ON_BOAT:
+ SetPedStats(PEDSTAT_TOUGH_GUY);
+ if (bInVehicle) {
+ if (m_pedInObjective && m_pedInObjective->m_pCurrentPhysSurface != m_pMyVehicle) {
+ bObjectiveCompleted = true;
+ ClearObjective();
+ CCarCtrl::SwitchVehicleToRealPhysics(m_pMyVehicle);
+ m_pMyVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS;
+ m_pMyVehicle->AutoPilot.m_nCruiseSpeed = GAME_SPEED_TO_CARAI_SPEED * m_pMyVehicle->pHandling->Transmission.fMaxCruiseVelocity;
+ m_pMyVehicle->SetStatus(STATUS_PHYSICS);
+ } else {
+ SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
+ }
+ } else if (m_pedInObjective && !m_pedInObjective->DyingOrDead() &&
+ (!m_pCurrentPhysSurface || !m_pedInObjective->m_pCurrentPhysSurface ||
+ m_pedInObjective->m_pCurrentPhysSurface == m_pCurrentPhysSurface)) {
+
+ CBoat *boatWeAreOn = nil;
+ if (m_pCurrentPhysSurface && m_pCurrentPhysSurface->IsVehicle() && ((CVehicle*)m_pCurrentPhysSurface)->IsBoat())
+ boatWeAreOn = (CBoat*)m_pCurrentPhysSurface;
+
+ if (boatWeAreOn) {
+ SetObjective(OBJECTIVE_RUN_TO_AREA, boatWeAreOn->GetPosition() - (boatWeAreOn->GetForward() * 10.f));
+ } else if (m_pedInObjective) {
+ SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_ALWAYS, m_pedInObjective);
+ }
+ SetMoveAnim();
+ } else {
+ ClearLookFlag();
+ SetMoveAnim();
+ if (m_pCurrentPhysSurface && m_pCurrentPhysSurface->IsVehicle())
+ SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, m_pCurrentPhysSurface);
+ }
+ break;
+ case OBJECTIVE_SOLICIT_FOOT:
+ if (m_pedInObjective) {
+ if (m_objectiveTimer < CTimer::GetTimeInMilliseconds())
+ bScriptObjectiveCompleted = true;
+ } else {
+ bScriptObjectiveCompleted = true;
+ }
+ break;
+ case OBJECTIVE_WAIT_ON_FOOT_AT_BUS_STOP:
+ 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;
}
- SetBeingDraggedFromCar(m_pMyVehicle, doorNode, false);
}
}
}
+
+ if (pBus) {
+ if (pBus->m_nNumPassengers >= pBus->m_nNumMaxPassengers - 1)
+ SetObjective(OBJECTIVE_WAIT_ON_FOOT);
+ else {
+ GetPedAttractorManager()->DeRegisterPed(this, m_attractor);
+ SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, pBus);
+ bDontDragMeOutCar = true;
+ bRemoveMeWhenIGotIntoCar = true;
+ CPlayerPed *player = FindPlayerPed();
+ if (pBus->IsPassenger(player) || pBus->IsDriver(player)) {
+ bCollectBusFare = true;
+ }
+ }
+ }
+ }
+ break;
+ case OBJECTIVE_WAIT_ON_FOOT_AT_ICE_CREAM_VAN:
+ {
+ SetIdle();
+ CVehicle* pIceCreamVan = GetPedAttractorManager()->GetIceCreamVanForEffect(m_attractor->GetEffect());
+ if (m_attractor && m_nWaitState != WAITSTATE_PLAYANIM_CHAT && pIceCreamVan && pIceCreamVan->pDriver && pIceCreamVan->pDriver->IsPlayer()) {
+ int time = 5000;
+ SetWaitState(WAITSTATE_PLAYANIM_CHAT, &time);
+ break;
+ }
+ if (!m_attractor)
+ break;
+ CVehicle* pVan = GetPedAttractorManager()->GetIceCreamVanForEffect(m_attractor->GetEffect());
+ if (!pVan)
+ break;
+ if (0.01f * CTimer::GetTimeStep() * 5.0f < pVan->m_fDistanceTravelled) {
+ GetPedAttractorManager()->DeRegisterPed(this, m_attractor);
+ break;
+ }
+ if (!pVan->pDriver || !pVan->pDriver->IsPlayer() || pVan->pDriver->GetPedState() == PED_ARRESTED || pVan->pDriver->GetPedState() == PED_DEAD) {
+ GetPedAttractorManager()->DeRegisterPed(this, m_attractor);
+ break;
+ }
+ if (!pVan->m_bSirenOrAlarm) {
+ GetPedAttractorManager()->DeRegisterPed(this, m_attractor);
+ return; // Why?
+ }
+ if (pVan->GetStatus() == STATUS_WRECKED) {
+ GetPedAttractorManager()->DeRegisterPed(this, m_attractor);
+ return; // Why?
}
break;
}
-#endif
}
if (bObjectiveCompleted
|| m_objectiveTimer > 0 && CTimer::GetTimeInMilliseconds() > m_objectiveTimer) {
@@ -1960,11 +2048,11 @@ void
CPed::SetFollowRoute(int16 currentPoint, int16 routeType)
{
m_routeLastPoint = currentPoint;
- m_routeStartPoint = CRouteNode::GetRouteStart(currentPoint);
- m_routePointsPassed = 0;
m_routeType = routeType;
m_routePointsBeingPassed = 1;
+ m_routePointsPassed = 0;
m_objective = OBJECTIVE_FOLLOW_ROUTE;
+ m_routeStartPoint = CRouteNode::GetRouteStart(currentPoint);
m_nextRoutePointPos = CRouteNode::GetPointPosition(GetNextPointOnRoute());
}
@@ -1998,11 +2086,11 @@ CPed::GetNextPointOnRoute(void)
bool
CPed::HaveReachedNextPointOnRoute(float distToCountReached)
{
- if ((m_nextRoutePointPos - GetPosition()).Magnitude2D() >= distToCountReached)
- return false;
-
- m_routePointsPassed += m_routePointsBeingPassed;
- return true;
+ if ((m_nextRoutePointPos - GetPosition()).Magnitude2D() < distToCountReached) {
+ m_routePointsPassed += m_routePointsBeingPassed;
+ return true;
+ }
+ return false;
}
bool
@@ -2034,11 +2122,14 @@ CPed::CanSeeEntity(CEntity *entity, float threshold)
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_BASEBALLBAT || weaponType == WEAPONTYPE_COLT45 || weaponType == WEAPONTYPE_UZI || weaponType == WEAPONTYPE_SHOTGUN ||
- weaponType == WEAPONTYPE_M16 || weaponType == WEAPONTYPE_SNIPERRIFLE || weaponType == WEAPONTYPE_ROCKETLAUNCHER) {
+
+ if (weaponType == WEAPONTYPE_COLT45 || weaponType == WEAPONTYPE_UZI || weaponType == WEAPONTYPE_MP5 || weaponType == WEAPONTYPE_M4 ||
+ weaponType == WEAPONTYPE_COLT45 || weaponType == WEAPONTYPE_PYTHON || weaponType == WEAPONTYPE_SHOTGUN ||
+ weaponType == WEAPONTYPE_SPAS12_SHOTGUN || weaponType == WEAPONTYPE_STUBBY_SHOTGUN ||
+ weaponType == WEAPONTYPE_ROCKETLAUNCHER || weaponType == WEAPONTYPE_SNIPERRIFLE || weaponType == WEAPONTYPE_FLAMETHROWER) {
SetCurrentWeapon(i);
return true;
}
@@ -2047,21 +2138,20 @@ CPed::SelectGunIfArmed(void)
SetCurrentWeapon(WEAPONTYPE_UNARMED);
return false;
}
-
void
CPed::ReactToPointGun(CEntity *entWithGun)
{
CPed *pedWithGun = (CPed*)entWithGun;
int waitTime;
- if (IsPlayer() || !IsPedInControl() || CharCreatedBy == MISSION_CHAR)
+ if (IsPlayer() || !IsPedInControl() || (CharCreatedBy == MISSION_CHAR && !bCrouchWhenScared))
return;
if (m_leader == pedWithGun)
return;
if (m_nWaitState == WAITSTATE_PLAYANIM_HANDSUP || m_nWaitState == WAITSTATE_PLAYANIM_HANDSCOWER ||
- (GetPosition() - pedWithGun->GetPosition()).MagnitudeSqr2D() > 225.0f)
+ (GetPosition() - pedWithGun->GetPosition()).MagnitudeSqr2D() > 225.0f || (m_nPedType == PEDTYPE_GANG7 && pedWithGun == FindPlayerPed()))
return;
if (m_leader) {
@@ -2141,9 +2231,13 @@ CPed::ReactToAttack(CEntity *attacker)
SetLookTimer(700);
return;
}
+
+ if (m_nPedType == PEDTYPE_GANG7 && attacker->IsPed() && ((CPed*)attacker)->IsPlayer()) {
+ if (m_nPedState != PED_FALL) {
+ SetFall(15000, (AnimationId)(ANIM_STD_KO_FRONT + CGeneral::GetRandomNumberInRange(0, 5)), 0);
+ }
-#ifdef VC_PED_PORTS
- if (m_nPedState == PED_DRIVING && InVehicle()
+ } else if (m_nPedState == PED_DRIVING && InVehicle()
&& (m_pMyVehicle->pDriver == this || m_pMyVehicle->pDriver && m_pMyVehicle->pDriver->m_nPedState == PED_DRIVING && m_pMyVehicle->pDriver->m_objective != OBJECTIVE_LEAVE_CAR_AND_DIE)) {
if (m_pMyVehicle->VehicleCreatedBy == RANDOM_VEHICLE
@@ -2155,12 +2249,9 @@ CPed::ReactToAttack(CEntity *attacker)
m_pMyVehicle->AutoPilot.m_nCruiseSpeed = GAME_SPEED_TO_CARAI_SPEED * m_pMyVehicle->pHandling->Transmission.fMaxCruiseVelocity;
m_pMyVehicle->SetStatus(STATUS_PHYSICS);
}
- } else
-#endif
- if (IsPedInControl() && (CharCreatedBy != MISSION_CHAR || bRespondsToThreats)) {
- CPed *ourLeader = m_leader;
- if (ourLeader != attacker && (!ourLeader || FindPlayerPed() != ourLeader)
- && attacker->IsPed()) {
+
+ } else if ((IsPedInControl() || m_nPedState == PED_DRIVING) && (CharCreatedBy != MISSION_CHAR || bRespondsToThreats)) {
+ if (m_leader != attacker && (!m_leader || FindPlayerPed() != m_leader) && attacker->IsPed()) {
CPed *attackerPed = (CPed*)attacker;
if (bNotAllowedToDuck) {
@@ -2169,28 +2260,35 @@ CPed::ReactToAttack(CEntity *attacker)
return;
}
} else if (bCrouchWhenShooting || bKindaStayInSamePlace) {
- SetDuck(CGeneral::GetRandomNumberInRange(1000, 3000));
+ SetDuck(CGeneral::GetRandomNumberInRange(1000,3000));
return;
}
- if (m_pedStats->m_fear <= 100 - attackerPed->m_pedStats->m_temper) {
- if (m_pedStats != attackerPed->m_pedStats) {
- if (IsGangMember() || m_nPedType == PEDTYPE_EMERGENCY || m_nPedType == PEDTYPE_FIREMAN) {
- RegisterThreatWithGangPeds(attackerPed);
- }
- if (!attackerPed->GetWeapon()->IsTypeMelee() && GetWeapon()->IsTypeMelee()) {
- SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE, attacker);
- SetMoveState(PEDMOVE_RUN);
- } else {
- SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, attacker);
- SetObjectiveTimer(20000);
+ if (m_nWaitState == WAITSTATE_STRIPPER) {
+ ClearWaitState();
+ SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, attacker);
+ SetObjectiveTimer(20000);
+
+ } else {
+ if (m_pedStats->m_fear <= 100 - attackerPed->m_pedStats->m_temper) {
+ if (m_pedStats != attackerPed->m_pedStats) {
+ if (IsGangMember() || m_nPedType == PEDTYPE_EMERGENCY || m_nPedType == PEDTYPE_FIREMAN) {
+ RegisterThreatWithGangPeds(attackerPed);
+ }
+ if (!attackerPed->GetWeapon()->IsTypeMelee() && GetWeapon()->IsTypeMelee()) {
+ SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE, attacker);
+ SetMoveState(PEDMOVE_RUN);
+ } else {
+ SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, attacker);
+ SetObjectiveTimer(20000);
+ }
}
+ } else {
+ SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE, attackerPed);
+ SetMoveState(PEDMOVE_RUN);
+ if (attackerPed->GetWeapon()->IsTypeMelee())
+ Say(SOUND_PED_FLEE_RUN);
}
- } else {
- SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE, attackerPed);
- SetMoveState(PEDMOVE_RUN);
- if (attackerPed->GetWeapon()->IsTypeMelee())
- Say(SOUND_PED_FLEE_RUN);
}
}
}
@@ -2209,24 +2307,25 @@ CPed::PedAnimAlignCB(CAnimBlendAssociation *animAssoc, void *arg)
return;
if (!ped->EnteringCar()) {
-#ifdef VC_PED_PORTS
if (ped->m_nPedState != PED_DRIVING)
-#endif
ped->QuitEnteringCar();
return;
}
+
+ if (!ped->m_vehDoor) {
+ ped->QuitEnteringCar();
+ return;
+ }
+
if (ped->m_fHealth == 0.0f) {
ped->QuitEnteringCar();
return;
}
bool itsVan = !!veh->bIsVan;
bool itsBus = !!veh->bIsBus;
-#ifdef FIX_BUGS
bool itsLow = !!veh->bLowVehicle;
-#endif
eDoors enterDoor;
- AnimationId enterAnim;
switch (ped->m_vehDoor) {
case CAR_DOOR_RF:
@@ -2247,37 +2346,134 @@ CPed::PedAnimAlignCB(CAnimBlendAssociation *animAssoc, void *arg)
break;
}
+ if (veh->IsBike()) {
+ CPed *pedToDragOut = nil;
+ if (veh->GetStatus() == STATUS_ABANDONED) {
+ if (ped->m_vehDoor == CAR_WINDSCREEN) {
+ ped->m_pVehicleAnim = CAnimManager::BlendAnimation(ped->GetClump(), ((CBike*)veh)->m_bikeAnimType, ANIM_BIKE_KICK, 6.0f);
+ ped->m_pVehicleAnim->SetFinishCallback(PedAnimGetInCB, ped);
+ ((CBike*)veh)->bIsBeingPickedUp = true;
+
+ } else if (veh->GetRight().z >= 0.5f || veh->GetRight().z <= -0.5f || veh->GetUp().z <= 0.0f) {
+ if (enterDoor == DOOR_FRONT_LEFT || enterDoor == DOOR_REAR_LEFT) {
+ if (veh->GetRight().z > 0.0f)
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_BIKE_PICKUP_LHS);
+ else
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_BIKE_PULLUP_LHS);
+
+ } else {
+ if (veh->GetRight().z < 0.0f)
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_BIKE_PICKUP_RHS);
+ else
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_BIKE_PULLUP_RHS);
+ }
+ ped->m_pVehicleAnim->SetFinishCallback(PedAnimDoorOpenCB, ped);
+
+ } else {
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ((CBike*)veh)->m_bikeAnimType,
+ enterDoor == DOOR_FRONT_LEFT || enterDoor == DOOR_REAR_LEFT ? ANIM_BIKE_JUMPON_LHS : ANIM_BIKE_JUMPON_RHS);
+ ped->m_pVehicleAnim->SetFinishCallback(PedAnimGetInCB, ped);
+ ((CBike*)veh)->bIsBeingPickedUp = true;
+ }
+ } else if (ped->m_vehDoor == CAR_WINDSCREEN) {
+ if (veh->pDriver->m_nPedState != PED_DRIVING || veh->pDriver->bDontDragMeOutCar) {
+ ped->QuitEnteringCar();
+ } else {
+ ped->m_pVehicleAnim = CAnimManager::BlendAnimation(ped->GetClump(), ((CBike*)veh)->m_bikeAnimType, ANIM_BIKE_KICK, 6.0f);
+ ped->m_pVehicleAnim->SetFinishCallback(PedAnimGetInCB, ped);
+ pedToDragOut = veh->pDriver;
+ }
+ ((CBike*)veh)->bIsBeingPickedUp = true;
+ } else {
+ if (enterDoor == DOOR_FRONT_LEFT || enterDoor == DOOR_FRONT_RIGHT) {
+ if (veh->pDriver) {
+ if (veh->m_vecMoveSpeed.Magnitude() > 0.2f) {
+ ped->QuitEnteringCar();
+ ped->SetFall(1000, ped->m_vehDoor == CAR_DOOR_LF || ped->m_vehDoor == CAR_DOOR_LR ? ANIM_STD_HIGHIMPACT_RIGHT : ANIM_STD_HIGHIMPACT_LEFT, false);
+ return;
+ }
+ if (veh->pDriver->m_nPedState != PED_DRIVING || veh->pDriver->bDontDragMeOutCar) {
+ ped->QuitEnteringCar();
+ } else {
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, enterDoor == DOOR_FRONT_LEFT ? ANIM_STD_BIKE_ELBOW_LHS : ANIM_STD_BIKE_ELBOW_RHS);
+ ped->m_pVehicleAnim->SetFinishCallback(PedAnimPullPedOutCB, ped);
+ pedToDragOut = veh->pDriver;
+ }
+ ((CBike*)veh)->bIsBeingPickedUp = true;
+
+ } else {
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ((CBike*)veh)->m_bikeAnimType, enterDoor == DOOR_FRONT_LEFT ? ANIM_BIKE_JUMPON_LHS : ANIM_BIKE_JUMPON_RHS);
+ ped->m_pVehicleAnim->SetFinishCallback(PedAnimGetInCB, ped);
+ ((CBike*)veh)->bIsBeingPickedUp = true;
+ }
+ } else {
+ if (veh->pPassengers[0]) {
+ if (veh->m_vecMoveSpeed.Magnitude() > 0.2f) {
+ ped->QuitEnteringCar();
+ ped->SetFall(1000, ped->m_vehDoor == CAR_DOOR_LF || ped->m_vehDoor == CAR_DOOR_LR ? ANIM_STD_HIGHIMPACT_RIGHT : ANIM_STD_HIGHIMPACT_LEFT, false);
+ return;
+ }
+ if (veh->pPassengers[0]->m_nPedState != PED_DRIVING || veh->pPassengers[0]->bDontDragMeOutCar) {
+ ped->QuitEnteringCar();
+ } else {
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD,
+ enterDoor == DOOR_REAR_LEFT ? ANIM_STD_BIKE_ELBOW_LHS : ANIM_STD_BIKE_ELBOW_RHS);
+ ped->m_pVehicleAnim->SetFinishCallback(PedAnimPullPedOutCB, ped);
+ pedToDragOut = veh->pPassengers[0];
+ }
+ ((CBike*)veh)->bIsBeingPickedUp = true;
+
+ } else {
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(),
+ ((CBike*)veh)->m_bikeAnimType, enterDoor == DOOR_REAR_LEFT ? ANIM_BIKE_JUMPON_LHS : ANIM_BIKE_JUMPON_RHS);
+ ped->m_pVehicleAnim->SetFinishCallback(PedAnimGetInCB, ped);
+ ((CBike*)veh)->bIsBeingPickedUp = true;
+ }
+ }
+ }
+
+ if (pedToDragOut) {
+ pedToDragOut->SetBeingDraggedFromCar(veh, ped->m_vehDoor, false);
+ if (pedToDragOut->IsGangMember())
+ pedToDragOut->RegisterThreatWithGangPeds(ped);
+
+ if (ped->m_nPedType == PEDTYPE_COP && pedToDragOut == FindPlayerPed() && veh->IsBike())
+ ((CCopPed*)ped)->m_bDragsPlayerFromCar = 1;
+
+ if (pedToDragOut == veh->pDriver) {
+ if (veh->pPassengers[0])
+ veh->pPassengers[0]->SetBeingDraggedFromCar(veh, CAR_DOOR_LR, false);
+ }
+ }
+ return;
+ }
+
if (veh->IsDoorMissing(enterDoor) || veh->IsDoorFullyOpen(enterDoor)) {
veh->AutoPilot.m_nCruiseSpeed = 0;
- if (ped->m_nPedState == PED_CARJACK) {
+ if (ped->m_nPedState == PED_CARJACK || veh->m_nNumMaxPassengers == 0 && veh->pDriver && enterDoor == DOOR_FRONT_RIGHT) {
ped->PedAnimDoorOpenCB(nil, ped);
return;
}
if (enterDoor != DOOR_FRONT_LEFT && enterDoor != DOOR_REAR_LEFT) {
if (itsVan) {
- enterAnim = ANIM_STD_VAN_GET_IN_REAR_RHS;
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_VAN, ANIM_STD_VAN_GET_IN_REAR_RHS);
} else if (itsBus) {
- enterAnim = ANIM_STD_COACH_GET_IN_RHS;
-#ifdef FIX_BUGS
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_COACH, ANIM_STD_COACH_GET_IN_RHS);
} else if (itsLow) {
- enterAnim = ANIM_STD_CAR_GET_IN_LO_RHS;
-#endif
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_GET_IN_LO_RHS);
} else {
- enterAnim = ANIM_STD_CAR_GET_IN_RHS;
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_GET_IN_RHS);
}
} else if (itsVan) {
- enterAnim = ANIM_STD_VAN_GET_IN_REAR_LHS;
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_VAN, ANIM_STD_VAN_GET_IN_REAR_LHS);
} else if (itsBus) {
- enterAnim = ANIM_STD_COACH_GET_IN_LHS;
-#ifdef FIX_BUGS
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_COACH, ANIM_STD_COACH_GET_IN_LHS);
} else if (itsLow) {
- enterAnim = ANIM_STD_CAR_GET_IN_LO_LHS;
-#endif
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_GET_IN_LO_LHS);
} else {
- enterAnim = ANIM_STD_CAR_GET_IN_LHS;
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_GET_IN_LHS);
}
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, enterAnim);
ped->m_pVehicleAnim->SetFinishCallback(PedAnimGetInCB, ped);
} else if (veh->CanPedOpenLocks(ped)) {
@@ -2285,16 +2481,16 @@ CPed::PedAnimAlignCB(CAnimBlendAssociation *animAssoc, void *arg)
veh->AutoPilot.m_nCruiseSpeed = 0;
if (enterDoor != DOOR_FRONT_LEFT && enterDoor != DOOR_REAR_LEFT) {
if (itsVan) {
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_VAN_OPEN_DOOR_REAR_RHS);
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_VAN, ANIM_STD_VAN_OPEN_DOOR_REAR_RHS);
} else if (itsBus) {
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_COACH_OPEN_RHS);
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_COACH, ANIM_STD_COACH_OPEN_RHS);
} else {
ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_OPEN_DOOR_RHS);
}
} else if (itsVan) {
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_VAN_OPEN_DOOR_REAR_LHS);
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_VAN, ANIM_STD_VAN_OPEN_DOOR_REAR_LHS);
} else if (itsBus) {
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_COACH_OPEN_LHS);
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_COACH, ANIM_STD_COACH_OPEN_LHS);
} else {
if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER && veh->pDriver) {
@@ -2305,13 +2501,28 @@ CPed::PedAnimAlignCB(CAnimBlendAssociation *animAssoc, void *arg)
ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_QUICKJACK);
ped->m_pVehicleAnim->SetFinishCallback(PedAnimGetInCB, ped);
- veh->pDriver->SetBeingDraggedFromCar(veh, ped->m_vehDoor, true);
- if (veh->pDriver->IsGangMember())
- veh->pDriver->RegisterThreatWithGangPeds(ped);
+ CPlayerPed *player = nil;
+ CCopPed *cop = nil;
+ veh->MakeNonDraggedPedsLeaveVehicle(veh->pDriver, ped, player, cop);
+ if (player && cop) {
+ cop->QuitEnteringCar();
+ cop->SetArrestPlayer(player);
+ }
+
+ if (player != veh->pDriver) {
+ veh->pDriver->SetBeingDraggedFromCar(veh, ped->m_vehDoor, true);
+ if (veh->pDriver->IsGangMember())
+ veh->pDriver->RegisterThreatWithGangPeds(ped);
+ }
return;
}
}
+ if (veh->IsOpenTopCar() && !veh->pDriver && ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER) {
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_JUMP_IN_LO_LHS);
+ ped->m_pVehicleAnim->SetFinishCallback(PedAnimGetInCB, ped);
+ return;
+ }
ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_OPEN_DOOR_LHS);
}
ped->m_pVehicleAnim->SetFinishCallback(PedAnimDoorOpenCB, ped);
@@ -2341,9 +2552,7 @@ CPed::PedAnimDoorOpenCB(CAnimBlendAssociation* animAssoc, void* arg)
return;
if (!ped->EnteringCar()) {
-#ifdef VC_PED_PORTS
- if (ped->m_nPedState != PED_DRIVING)
-#endif
+ if(ped->m_nPedState != PED_DRIVING)
ped->QuitEnteringCar();
return;
@@ -2352,10 +2561,26 @@ CPed::PedAnimDoorOpenCB(CAnimBlendAssociation* animAssoc, void* arg)
eDoors door;
CPed *pedInSeat = nil;
switch (ped->m_vehDoor) {
- case CAR_DOOR_RF: door = DOOR_FRONT_RIGHT; pedInSeat = veh->pPassengers[0]; break;
- case CAR_DOOR_RR: door = DOOR_REAR_RIGHT; pedInSeat = veh->pPassengers[2]; break;
- case CAR_DOOR_LF: door = DOOR_FRONT_LEFT; pedInSeat = veh->pDriver; break;
- case CAR_DOOR_LR: door = DOOR_REAR_LEFT; pedInSeat = veh->pPassengers[1]; break;
+ case CAR_DOOR_RF:
+ door = DOOR_FRONT_RIGHT;
+ pedInSeat = veh->pPassengers[0];
+ if (!veh->pPassengers[0] && ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER)
+ pedInSeat = veh->pDriver;
+ break;
+ case CAR_DOOR_RR:
+ door = DOOR_REAR_RIGHT;
+ pedInSeat = veh->pPassengers[2];
+ break;
+ case CAR_DOOR_LF:
+ door = DOOR_FRONT_LEFT;
+ pedInSeat = veh->pDriver;
+ if (veh->bIsBus && ped->m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER)
+ pedInSeat = nil;
+ break;
+ case CAR_DOOR_LR:
+ door = DOOR_REAR_LEFT;
+ pedInSeat = veh->pPassengers[1];
+ break;
default: assert(0);
}
@@ -2390,7 +2615,8 @@ CPed::PedAnimDoorOpenCB(CAnimBlendAssociation* animAssoc, void* arg)
((CAutomobile*)veh)->Damage.SetDoorStatus(door, DOOR_STATUS_SWINGING);
}
- if (veh->m_vecMoveSpeed.Magnitude() > 0.2f) {
+ if (veh->m_vecMoveSpeed.Magnitude() > 0.2f ||
+ veh->IsCar() && veh->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI && ((CAutomobile*)veh)->m_nWheelsOnGround == 0) {
ped->QuitEnteringCar();
if (ped->m_vehDoor != CAR_DOOR_LF && ped->m_vehDoor != CAR_DOOR_LR)
ped->SetFall(1000, ANIM_STD_HIGHIMPACT_LEFT, false);
@@ -2405,28 +2631,36 @@ CPed::PedAnimDoorOpenCB(CAnimBlendAssociation* animAssoc, void* arg)
isVan = false;
if (ped->m_nPedState != PED_CARJACK || isBus) {
- AnimationId animToPlay;
- if (ped->m_vehDoor != CAR_DOOR_LF && ped->m_vehDoor != CAR_DOOR_LR) {
- if (isVan) {
- animToPlay = ANIM_STD_VAN_GET_IN_REAR_RHS;
+ if (ped->m_vehDoor == CAR_DOOR_LF || ped->m_vehDoor == CAR_DOOR_LR) {
+ if (veh->IsBike()) {
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ((CBike*)veh)->m_bikeAnimType, ANIM_BIKE_JUMPON_LHS);
+ } else if (isVan) {
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_VAN, ANIM_STD_VAN_GET_IN_REAR_LHS);
} else if (isBus) {
- animToPlay = ANIM_STD_COACH_GET_IN_RHS;
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_COACH, ANIM_STD_COACH_GET_IN_LHS);
} else if (isLow) {
- animToPlay = ANIM_STD_CAR_GET_IN_LO_RHS;
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_GET_IN_LO_LHS);
} else {
- animToPlay = ANIM_STD_CAR_GET_IN_RHS;
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_GET_IN_LHS);
}
- } else if (isVan) {
- animToPlay = ANIM_STD_VAN_GET_IN_REAR_LHS;
- } else if (isBus) {
- animToPlay = ANIM_STD_COACH_GET_IN_LHS;
- } else if (isLow) {
- animToPlay = ANIM_STD_CAR_GET_IN_LO_LHS;
} else {
- animToPlay = ANIM_STD_CAR_GET_IN_LHS;
+ if (veh->IsBike()) {
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ((CBike*)veh)->m_bikeAnimType, ANIM_BIKE_JUMPON_RHS);
+ } else if (isVan) {
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_VAN, ANIM_STD_VAN_GET_IN_REAR_RHS);
+ } else if (isBus) {
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_COACH, ANIM_STD_COACH_GET_IN_RHS);
+ } else if (isLow) {
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_GET_IN_LO_RHS);
+ } else {
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_GET_IN_RHS);
+ }
+
+ if (ped->m_vehDoor == CAR_DOOR_RF && pedInSeat && veh->IsCar())
+ pedInSeat->SetObjective(OBJECTIVE_LEAVE_CAR, veh);
}
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, animToPlay);
+
ped->m_pVehicleAnim->SetFinishCallback(PedAnimGetInCB, ped);
} else {
CPed *pedToDragOut = nil;
@@ -2445,6 +2679,7 @@ CPed::PedAnimDoorOpenCB(CAnimBlendAssociation* animAssoc, void* arg)
}
if (ped->m_vehDoor != CAR_DOOR_LF && ped->m_vehDoor != CAR_DOOR_LR) {
+
if (pedToDragOut && !pedToDragOut->bDontDragMeOutCar) {
if (pedToDragOut->m_nPedState != PED_DRIVING) {
ped->QuitEnteringCar();
@@ -2461,54 +2696,63 @@ CPed::PedAnimDoorOpenCB(CAnimBlendAssociation* animAssoc, void* arg)
ped->QuitEnteringCar();
if (ped->m_pedInObjective && ped->m_pedInObjective->m_nPedState == PED_DRIVING) {
veh->SetStatus(STATUS_PLAYER_DISABLED);
- ((CCopPed*)ped)->SetArrestPlayer(ped->m_pedInObjective);
+
+ if (ped->m_pedInObjective->IsPlayer()) {
+ ((CCopPed*)ped)->SetArrestPlayer(ped->m_pedInObjective);
+ } else {
+ ped->ClearObjective();
+ ped->SetWanderPath(CGeneral::GetRandomNumberInRange(0.f, 8.f));
+ }
+
} else if (!veh->IsDoorMissing(DOOR_FRONT_RIGHT)) {
((CAutomobile*)veh)->Damage.SetDoorStatus(DOOR_FRONT_RIGHT, DOOR_STATUS_SWINGING);
}
} else {
- // BUG: Probably we will sit on top of the passenger if his m_ped_flagF4 is true.
if (isLow)
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_GET_IN_LO_LHS);
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_GET_IN_LO_RHS);
else
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_GET_IN_LHS);
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_GET_IN_RHS);
ped->m_pVehicleAnim->SetFinishCallback(PedAnimGetInCB, ped);
}
- } else {
- if (pedToDragOut) {
- if (pedToDragOut->m_nPedState != PED_DRIVING || pedToDragOut->bDontDragMeOutCar) {
+ } else if (pedToDragOut) {
- // BUG: Player freezes in that condition due to its objective isn't restored. It's an unfinished feature, used in VC.
- ped->QuitEnteringCar();
- pedToDragOut = nil;
- } else {
- if (isLow)
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_PULL_OUT_PED_LO_LHS);
- else
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_PULL_OUT_PED_LHS);
-
- ped->m_pVehicleAnim->SetFinishCallback(PedAnimPullPedOutCB, ped);
- }
+ if (pedToDragOut->m_nPedState != PED_DRIVING || pedToDragOut->bDontDragMeOutCar) {
+ ped->QuitEnteringCar();
+ pedToDragOut = nil;
} else {
if (isLow)
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_GET_IN_LO_LHS);
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_PULL_OUT_PED_LO_LHS);
else
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_GET_IN_LHS);
-
- ped->m_pVehicleAnim->SetFinishCallback(PedAnimGetInCB, ped);
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_PULL_OUT_PED_LHS);
+
+ ped->m_pVehicleAnim->SetFinishCallback(PedAnimPullPedOutCB, ped);
}
+ } else {
+ if (isLow)
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_GET_IN_LO_LHS);
+ else
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_GET_IN_LHS);
+
+ ped->m_pVehicleAnim->SetFinishCallback(PedAnimGetInCB, ped);
}
if (pedToDragOut) {
- pedToDragOut->SetBeingDraggedFromCar(veh, ped->m_vehDoor, false);
- if (pedToDragOut->IsGangMember())
- pedToDragOut->RegisterThreatWithGangPeds(ped);
- }
- }
+ CPlayerPed* player = nil;
+ CCopPed* cop = nil;
+ veh->MakeNonDraggedPedsLeaveVehicle(pedToDragOut, ped, player, cop);
+ if (player && cop) {
+ cop->QuitEnteringCar();
+ veh->SetStatus(STATUS_PLAYER_DISABLED);
+ cop->SetArrestPlayer(player);
+ }
- if (veh->pDriver && ped) {
- veh->pDriver->SetLookFlag(ped, true);
- veh->pDriver->SetLookTimer(1000);
+ if (player != pedToDragOut) {
+ pedToDragOut->SetBeingDraggedFromCar(veh, ped->m_vehDoor, false);
+ if (pedToDragOut->IsGangMember())
+ pedToDragOut->RegisterThreatWithGangPeds(ped);
+ }
+ }
}
return;
}
@@ -2574,23 +2818,26 @@ CPed::PedAnimPullPedOutCB(CAnimBlendAssociation* animAssoc, void* arg)
}
if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER) {
- AnimationId animToPlay;
- if (ped->m_vehDoor != CAR_DOOR_LF && ped->m_vehDoor != CAR_DOOR_LR) {
- if (isLow)
- animToPlay = ANIM_STD_CAR_GET_IN_LO_RHS;
+ if (ped->m_vehDoor == CAR_DOOR_LF || ped->m_vehDoor == CAR_DOOR_LR) {
+ if (veh->IsBike())
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ((CBike*)veh)->m_bikeAnimType, ANIM_BIKE_JUMPON_LHS);
+ else if (isLow)
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_GET_IN_LO_LHS);
else
- animToPlay = ANIM_STD_CAR_GET_IN_RHS;
- } else if (isLow) {
- animToPlay = ANIM_STD_CAR_GET_IN_LO_LHS;
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_GET_IN_LHS);
} else {
- animToPlay = ANIM_STD_CAR_GET_IN_LHS;
+ if (veh->IsBike())
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ((CBike*)veh)->m_bikeAnimType, ANIM_BIKE_JUMPON_RHS);
+ else if (isLow)
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_GET_IN_LO_RHS);
+ else
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_GET_IN_RHS);
}
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, animToPlay);
ped->m_pVehicleAnim->SetFinishCallback(PedAnimGetInCB, ped);
} else {
ped->QuitEnteringCar();
}
- } else {
+ } else if(ped->m_nPedState != PED_DRIVING) {
ped->QuitEnteringCar();
}
}
@@ -2608,13 +2855,12 @@ CPed::PedAnimGetInCB(CAnimBlendAssociation *animAssoc, void *arg)
return;
if (!ped->EnteringCar()) {
-#ifdef VC_PED_PORTS
if(ped->m_nPedState != PED_DRIVING)
-#endif
ped->QuitEnteringCar();
return;
}
+ ped->RemoveWeaponWhenEnteringVehicle();
if (ped->IsPlayer() && ped->bGonnaKillTheCarJacker && ((CPlayerPed*)ped)->m_pArrestingCop) {
PedSetInCarCB(nil, ped);
ped->m_nLastPedState = ped->m_nPedState;
@@ -2630,13 +2876,19 @@ CPed::PedAnimGetInCB(CAnimBlendAssociation *animAssoc, void *arg)
}
if (ped->IsPlayer() && ped->m_vehDoor == CAR_DOOR_LF
&& (Pads[0].GetAccelerate() >= 255.0f || Pads[0].GetBrake() >= 255.0f)
- && veh->IsCar()) {
+ && veh->IsCar() && !veh->pDriver) {
+
+ if (!animAssoc || animAssoc->animId != ANIM_STD_CAR_JUMP_IN_LO_LHS)
if (((CAutomobile*)veh)->Damage.GetDoorStatus(DOOR_FRONT_LEFT) != DOOR_STATUS_MISSING)
((CAutomobile*)veh)->Damage.SetDoorStatus(DOOR_FRONT_LEFT, DOOR_STATUS_SWINGING);
PedSetInCarCB(nil, ped);
return;
}
+ if (veh->IsBike()) {
+ ped->PedSetInCarCB(nil, ped);
+ return;
+ }
bool isVan = !!veh->bIsVan;
bool isBus = !!veh->bIsBus;
bool isLow = !!veh->bLowVehicle;
@@ -2659,10 +2911,15 @@ CPed::PedAnimGetInCB(CAnimBlendAssociation *animAssoc, void *arg)
default:
break;
}
- if (!veh->IsDoorMissing(enterDoor)) {
+ bool doorClosed = true;
+ if (veh->IsOpenTopCar() && enterDoor == DOOR_FRONT_LEFT && veh->IsDoorClosed(DOOR_FRONT_LEFT)) {
+ doorClosed = false;
+
+ } else if (!veh->IsDoorMissing(enterDoor)) {
if (veh->IsCar())
((CAutomobile*)veh)->Damage.SetDoorStatus(enterDoor, DOOR_STATUS_SWINGING);
}
+
CPed *driver = veh->pDriver;
if (driver && (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER || ped->m_nPedState == PED_CARJACK)) {
if (veh->bIsBus) {
@@ -2703,39 +2960,53 @@ CPed::PedAnimGetInCB(CAnimBlendAssociation *animAssoc, void *arg)
&& (ped->m_nPedType != PEDTYPE_COP || veh->pDriver->m_nPedType != PEDTYPE_COP)) {
veh->pDriver->SetObjective(OBJECTIVE_LEAVE_CAR, veh);
veh->pDriver->Say(SOUND_PED_CAR_JACKED);
-#ifdef VC_PED_PORTS
veh->pDriver->SetRadioStation();
-#endif
+ if (veh->m_nDoorLock == CARLOCK_UNLOCKED)
+ ped->Say(SOUND_PED_CAR_JACKING);
+
} else {
ped->m_objective = OBJECTIVE_ENTER_CAR_AS_PASSENGER;
}
}
}
- if (veh->IsDoorMissing(enterDoor) || isBus) {
+ if (veh->IsDoorMissing(enterDoor) || !doorClosed || isBus) {
PedAnimDoorCloseCB(nil, ped);
} else {
- AnimationId animToPlay;
if (enterDoor != DOOR_FRONT_LEFT && enterDoor != DOOR_REAR_LEFT) {
if (isVan) {
- animToPlay = ANIM_STD_VAN_CLOSE_DOOR_REAR_RHS;
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_VAN, ANIM_STD_VAN_CLOSE_DOOR_REAR_RHS);
} else if (isLow) {
- animToPlay = ANIM_STD_CAR_CLOSE_DOOR_LO_RHS;
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_CLOSE_DOOR_LO_RHS);
} else {
- animToPlay = ANIM_STD_CAR_CLOSE_DOOR_RHS;
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_CLOSE_DOOR_RHS);
}
} else if (isVan) {
- animToPlay = ANIM_STD_VAN_CLOSE_DOOR_REAR_LHS;
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_VAN, ANIM_STD_VAN_CLOSE_DOOR_REAR_LHS);
} else if (isLow) {
- animToPlay = ANIM_STD_CAR_CLOSE_DOOR_LO_LHS;
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_CLOSE_DOOR_LO_LHS);
} else {
- animToPlay = ANIM_STD_CAR_CLOSE_DOOR_LHS;
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_CLOSE_DOOR_LHS);
}
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, animToPlay);
ped->m_pVehicleAnim->SetFinishCallback(PedAnimDoorCloseCB, ped);
}
}
void
+CPed::PedShuffle(void)
+{
+ if (m_pMyVehicle->pPassengers[0] == this) {
+ CPed *driver = m_pMyVehicle->pDriver;
+ if (!driver || driver->m_objective == OBJECTIVE_LEAVE_CAR) {
+ m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, m_pMyVehicle->bLowVehicle ? ANIM_STD_CAR_SHUFFLE_LO_RHS : ANIM_STD_CAR_SHUFFLE_RHS);
+ m_objective = OBJECTIVE_ENTER_CAR_AS_DRIVER;
+ m_pMyVehicle->RemovePassenger(this);
+ bInVehicle = false;
+ m_pVehicleAnim->SetFinishCallback(PedSetInCarCB, this);
+ }
+ }
+}
+
+void
CPed::PedAnimDoorCloseCB(CAnimBlendAssociation *animAssoc, void *arg)
{
CPed *ped = (CPed*)arg;
@@ -2763,22 +3034,16 @@ CPed::PedAnimDoorCloseCB(CAnimBlendAssociation *animAssoc, void *arg)
if (veh->Damage.GetDoorStatus(door) == DOOR_STATUS_SWINGING)
veh->Damage.SetDoorStatus(door, DOOR_STATUS_OK);
- if (door == DOOR_FRONT_LEFT || ped->m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER || veh->bIsBus) {
+ if (door == DOOR_FRONT_LEFT || ped->m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER || veh->bIsBus || veh->m_nNumMaxPassengers == 0) {
PedSetInCarCB(nil, ped);
} else if (ped->m_vehDoor == CAR_DOOR_RF
&& (veh->m_nGettingInFlags & CAR_DOOR_FLAG_LF ||
(veh->pDriver != nil &&
(veh->pDriver->m_objective != OBJECTIVE_LEAVE_CAR
-#ifdef VC_PED_PORTS
&& veh->pDriver->m_objective != OBJECTIVE_LEAVE_CAR_AND_DIE
-#endif
|| !veh->IsRoomForPedToLeaveCar(CAR_DOOR_LF, nil))))) {
- if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER
-#if defined VC_PED_PORTS || defined FIX_BUGS
- || ped->m_nPedState == PED_CARJACK
-#endif
- )
+ if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER || ped->m_nPedState == PED_CARJACK)
veh->bIsBeingCarJacked = false;
ped->m_objective = OBJECTIVE_ENTER_CAR_AS_PASSENGER;
@@ -2802,11 +3067,19 @@ CPed::PedAnimDoorCloseCB(CAnimBlendAssociation *animAssoc, void *arg)
ped->m_pVehicleAnim->SetFinishCallback(PedSetInCarCB, ped);
}
- } else {
-#ifdef VC_PED_PORTS
- if (ped->m_nPedState != PED_DRIVING)
-#endif
- ped->QuitEnteringCar();
+ } else if (ped->m_nPedState != PED_DRIVING) {
+ ped->QuitEnteringCar();
+ }
+}
+
+void
+CPed::PedAnimShuffleCB(CAnimBlendAssociation* assoc, void* arg)
+{
+ CPed *ped = (CPed*)arg;
+ if (ped->EnteringCar()) {
+ PedSetInCarCB(nil, ped);
+ } else if (ped->m_nPedState != PED_DRIVING) {
+ ped->QuitEnteringCar();
}
}
@@ -2836,6 +3109,9 @@ CPed::SetFormation(eFormation type)
CVector
CPed::GetFormationPosition(void)
{
+ if (!m_pedInObjective)
+ return GetPosition();
+
if (m_pedInObjective->m_nPedState == PED_DEAD) {
if (!m_pedInObjective->m_pedInObjective) {
m_pedInObjective = nil;
@@ -2845,36 +3121,37 @@ CPed::GetFormationPosition(void)
}
CVector formationOffset;
+ float offset = CGeneral::GetRandomNumberInRange(1.f, 1.25f) * 1.75f;
switch (m_pedFormation) {
case FORMATION_REAR:
- formationOffset = CVector(0.0f, -1.5f, 0.0f);
+ formationOffset = CVector(0.0f, -offset, 0.0f);
break;
case FORMATION_REAR_LEFT:
- formationOffset = CVector(-1.5f, -1.5f, 0.0f);
+ formationOffset = CVector(-offset, -offset, 0.0f);
break;
case FORMATION_REAR_RIGHT:
- formationOffset = CVector(1.5f, -1.5f, 0.0f);
+ formationOffset = CVector(offset, -offset, 0.0f);
break;
case FORMATION_FRONT_LEFT:
- formationOffset = CVector(-1.5f, 1.5f, 0.0f);
+ formationOffset = CVector(-offset, offset, 0.0f);
break;
case FORMATION_FRONT_RIGHT:
- formationOffset = CVector(1.5f, 1.5f, 0.0f);
+ formationOffset = CVector(offset, offset, 0.0f);
break;
case FORMATION_LEFT:
- formationOffset = CVector(-1.5f, 0.0f, 0.0f);
+ formationOffset = CVector(-offset, 0.0f, 0.0f);
break;
case FORMATION_RIGHT:
- formationOffset = CVector(1.5f, 0.0f, 0.0f);
+ formationOffset = CVector(offset, 0.0f, 0.0f);
break;
case FORMATION_FRONT:
- formationOffset = CVector(0.0f, 1.5f, 0.0f);
+ formationOffset = CVector(0.0f, offset, 0.0f);
break;
default:
formationOffset = CVector(0.0f, 0.0f, 0.0f);
break;
}
- return formationOffset + m_pedInObjective->GetPosition();
+ return m_pedInObjective->GetMatrix() * formationOffset;
}
void
@@ -2883,21 +3160,27 @@ CPed::PedAnimStepOutCarCB(CAnimBlendAssociation* animAssoc, void* arg)
CPed* ped = (CPed*)arg;
CVehicle* veh = ped->m_pMyVehicle;
- if (animAssoc)
+ if (animAssoc) {
+ if ((animAssoc->animId == ANIM_STD_ROLLOUT_LHS || animAssoc->animId == ANIM_STD_ROLLOUT_RHS) && ped && ped->m_nPedState == PED_FALL) {
+ ped->RestoreHeadingRate();
+ return;
+ }
animAssoc->blendDelta = -1000.0f;
+ if (animAssoc->animId == ANIM_BIKE_GETOFF_BACK)
+ ped->RestoreHeadingRate();
+ }
if (!veh) {
PedSetOutCarCB(nil, ped);
return;
}
-#ifdef VC_PED_PORTS
CVector posForZ = ped->GetPosition();
CPedPlacement::FindZCoorForPed(&posForZ);
if (ped->GetPosition().z - 0.5f > posForZ.z) {
PedSetOutCarCB(nil, ped);
return;
}
-#endif
+
veh->m_nStaticFrames = 0;
veh->m_vecMoveSpeed += CVector(0.001f, 0.001f, 0.001f);
veh->m_vecTurnSpeed += CVector(0.001f, 0.001f, 0.001f);
@@ -2965,10 +3248,8 @@ CPed::PedAnimStepOutCarCB(CAnimBlendAssociation* animAssoc, void* arg)
}
}
-#ifdef VC_PED_PORTS
if (ped->m_objective == OBJECTIVE_LEAVE_CAR_AND_DIE)
closeDoor = false;
-#endif
if (!closeDoor) {
if (!veh->IsDoorMissing(door) && !veh->bIsBus) {
@@ -3021,28 +3302,58 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
float seatPosMult = 0.0f;
float currentZ;
float adjustedTimeStep;
+ CVector autoZPos;
if (CReplay::IsPlayingBack())
return;
if (!bChangedSeat && phase != LINE_UP_TO_CAR_2) {
- if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_SIT)) {
- SetPedPositionInCar();
- return;
- }
- if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_SIT_LO)) {
- SetPedPositionInCar();
- return;
+ if (m_pMyVehicle->IsBike()) {
+ if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_RIDE) ||
+ RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_RIDE_P)) {
+ SetPedPositionInCar();
+ return;
+ }
+ } else {
+ if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_SIT)) {
+ SetPedPositionInCar();
+ return;
+ }
+ if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_SIT_LO)) {
+ SetPedPositionInCar();
+ return;
+ }
+ if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_SIT_P)) {
+ SetPedPositionInCar();
+ return;
+ }
+ if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_SIT_P_LO)) {
+ SetPedPositionInCar();
+ return;
+ }
}
- if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_SIT_P)) {
- SetPedPositionInCar();
- return;
+ bChangedSeat = true;
+ }
+ if (phase == LINE_UP_TO_CAR_FALL) {
+ SetPedPositionInCar();
+ autoZPos = GetPosition();
+ CPedPlacement::FindZCoorForPed(&autoZPos);
+ if (m_pVehicleAnim && (m_pVehicleAnim->animId == ANIM_STD_ROLLOUT_LHS || m_pVehicleAnim->animId == ANIM_STD_ROLLOUT_RHS)
+ && autoZPos.z > GetPosition().z) {
+ m_matrix.GetPosition().z = autoZPos.z;
}
- if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_SIT_P_LO)) {
- SetPedPositionInCar();
- return;
+ if (m_pVehicleAnim && m_pVehicleAnim->animId == ANIM_BIKE_HIT) {
+ if (autoZPos.z > GetPosition().z)
+ m_matrix.GetPosition().z += m_pVehicleAnim->GetProgress() * (autoZPos.z - GetPosition().z);
+
+ } else if (m_pVehicleAnim) {
+ if (m_pVehicleAnim->animId == ANIM_BIKE_GETOFF_BACK) {
+ if (autoZPos.z > GetPosition().z) {
+ m_matrix.GetPosition().z += (m_pVehicleAnim->currentTime * (20.f / 7.f)) * (autoZPos.z - GetPosition().z);
+ }
+ }
}
- bChangedSeat = true;
+ return;
}
if (phase == LINE_UP_TO_CAR_START) {
m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
@@ -3076,19 +3387,16 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
m_fRotationDest = veh->GetForward().Heading();
} else if (veh->bIsBus) {
m_fRotationDest = 0.5f * PI + veh->GetForward().Heading();
+ } else if (m_vehDoor == CAR_WINDSCREEN) {
+ m_fRotationDest = veh->GetForward().Heading() + PI;
} else {
m_fRotationDest = veh->GetForward().Heading();
}
}
- if (!bInVehicle)
- seatPosMult = 1.0f;
-
-#ifdef VC_PED_PORTS
bool multExtractedFromAnim = false;
bool multExtractedFromAnimBus = false;
float zBlend;
-#endif
if (m_pVehicleAnim) {
vehAnim = m_pVehicleAnim->animId;
@@ -3099,38 +3407,38 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
case ANIM_STD_JACKEDCAR_LO_LHS:
case ANIM_STD_VAN_GET_IN_REAR_LHS:
case ANIM_STD_VAN_GET_IN_REAR_RHS:
-#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_STD_QUICKJACKED:
case ANIM_STD_GETOUT_LHS:
case ANIM_STD_GETOUT_LO_LHS:
case ANIM_STD_GETOUT_RHS:
case ANIM_STD_GETOUT_LO_RHS:
-#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
+
case ANIM_STD_CRAWLOUT_LHS:
case ANIM_STD_CRAWLOUT_RHS:
case ANIM_STD_VAN_GET_OUT_REAR_LHS:
case ANIM_STD_VAN_GET_OUT_REAR_RHS:
- seatPosMult = m_pVehicleAnim->currentTime / m_pVehicleAnim->hierarchy->totalLength;
+ case ANIM_BIKE_GETOFF_LHS:
+ case ANIM_BIKE_GETOFF_RHS:
+ seatPosMult = m_pVehicleAnim->GetProgress();
break;
case ANIM_STD_CAR_GET_IN_RHS:
case ANIM_STD_CAR_GET_IN_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
+
case ANIM_STD_QUICKJACK:
case ANIM_STD_CAR_GET_IN_LO_LHS:
case ANIM_STD_CAR_GET_IN_LO_RHS:
@@ -3145,6 +3453,12 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
case ANIM_STD_CAR_SHUFFLE_LO_RHS:
seatPosMult = 0.0f;
break;
+ case ANIM_STD_CAR_JUMP_IN_LO_LHS:
+ {
+ float animLength = m_pVehicleAnim->hierarchy->totalLength;
+ seatPosMult = Max(0.0f, 0.5f * animLength - m_pVehicleAnim->currentTime) / animLength;
+ break;
+ }
case ANIM_STD_CAR_CLOSE_LHS:
case ANIM_STD_CAR_CLOSE_RHS:
case ANIM_STD_COACH_OPEN_LHS:
@@ -3155,8 +3469,25 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
seatPosMult = 1.0f;
break;
default:
+ if (veh->IsBike()) {
+ seatPosMult = 0.0f;
+ } else {
+ if (bInVehicle)
+ seatPosMult = 0.0f;
+ else
+ seatPosMult = 1.0f;
+ }
break;
}
+ } else {
+ if (veh->IsBike()) {
+ seatPosMult = 0.0f;
+ } else {
+ if (bInVehicle)
+ seatPosMult = 0.0f;
+ else
+ seatPosMult = 1.0f;
+ }
}
CVector neededPos;
@@ -3167,7 +3498,7 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
neededPos = GetPositionToOpenCarDoor(veh, m_vehDoor, seatPosMult);
}
- CVector autoZPos = neededPos;
+ autoZPos = neededPos;
if (veh->bIsInWater) {
if (veh->m_vehType == VEHICLE_TYPE_BOAT && veh->IsUpsideDown())
@@ -3197,11 +3528,24 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
}
if (autoZPos.z > neededPos.z) {
-#ifdef VC_PED_PORTS
- if (multExtractedFromAnim) {
+ vehAnim = m_pVehicleAnim->animId;
+ if (veh->IsBike() && (m_pVehicleAnim && vehAnim != ANIM_BIKE_KICK)) {
+ float zBlend;
+ if (vehAnim != ANIM_BIKE_GETOFF_LHS && vehAnim != ANIM_BIKE_GETOFF_RHS) {
+ if (vehAnim != ANIM_BIKE_JUMPON_LHS && vehAnim != ANIM_BIKE_JUMPON_RHS) {
+ zBlend = 0.0f;
+ } else {
+ float animLength = m_pVehicleAnim->hierarchy->totalLength;
+ zBlend = Min(1.0f, 2.0f * m_pVehicleAnim->currentTime / animLength);
+ }
+ } else {
+ zBlend = 1.0f - seatPosMult;
+ }
+ float curZ = veh->GetPosition().z + FEET_OFFSET;
+ neededPos.z = ((curZ - autoZPos.z) - veh->GetHeightAboveRoad()) * zBlend + autoZPos.z;
+ } else if (multExtractedFromAnim) {
neededPos.z += (autoZPos.z - neededPos.z) * zBlend;
} else {
-#endif
currentZ = GetPosition().z;
if (m_pVehicleAnim && vehAnim != ANIM_STD_VAN_GET_IN_REAR_LHS && vehAnim != ANIM_STD_VAN_CLOSE_DOOR_REAR_LHS && vehAnim != ANIM_STD_VAN_CLOSE_DOOR_REAR_RHS && vehAnim != ANIM_STD_VAN_GET_IN_REAR_RHS) {
neededPos.z = autoZPos.z;
@@ -3212,20 +3556,16 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
// Smoothly change ped position
neededPos.z = currentZ - (currentZ - neededPos.z) / (m_pVehicleAnim->GetTimeLeft() / adjustedTimeStep);
}
-#ifdef VC_PED_PORTS
}
-#endif
} else {
// We may need to raise up the ped
if (phase == LINE_UP_TO_CAR_START) {
currentZ = GetPosition().z;
if (neededPos.z > currentZ) {
-#ifdef VC_PED_PORTS
if (multExtractedFromAnimBus) {
neededPos.z = (neededPos.z - currentZ) * zBlend + currentZ;
} else {
-#endif
if (m_pVehicleAnim &&
(vehAnim == ANIM_STD_CAR_GET_IN_RHS || vehAnim == ANIM_STD_CAR_GET_IN_LO_RHS || vehAnim == ANIM_STD_CAR_GET_IN_LHS || vehAnim == ANIM_STD_CAR_GET_IN_LO_LHS
|| vehAnim == ANIM_STD_QUICKJACK || vehAnim == ANIM_STD_VAN_GET_IN_REAR_LHS || vehAnim == ANIM_STD_VAN_GET_IN_REAR_RHS)) {
@@ -3233,12 +3573,10 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
// Smoothly change ped position
neededPos.z = (neededPos.z - currentZ) / (m_pVehicleAnim->GetTimeLeft() / adjustedTimeStep) + currentZ;
- } else if (EnteringCar()) {
+ } else if (EnteringCar() || m_nPedState == PED_DRIVING && veh->IsBike()) {
neededPos.z = Max(currentZ, autoZPos.z);
}
-#ifdef VC_PED_PORTS
}
-#endif
}
}
}
@@ -3268,13 +3606,24 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
m_fRotationCur -= (m_fRotationCur - limitedDest) * (1.0f - timeUntilStateChange);
}
- if (seatPosMult > 0.2f || vehIsUpsideDown) {
+ if (seatPosMult > 0.2f || vehIsUpsideDown || veh->IsBike()) {
SetPosition(neededPos);
SetHeading(m_fRotationCur);
} else {
CMatrix vehDoorMat(veh->GetMatrix());
vehDoorMat.GetPosition() += Multiply3x3(vehDoorMat, GetLocalPositionToOpenCarDoor(veh, m_vehDoor, 0.0f));
- // VC couch anims are inverted, so they're fixing it here.
+
+ if (m_vehDoor == CAR_WINDSCREEN || veh->bIsBus) {
+ CMatrix correctionMat;
+ if (veh->bIsBus && (m_vehDoor == CAR_DOOR_LF || m_vehDoor == CAR_DOOR_LR))
+ correctionMat.SetRotateZ(-HALFPI);
+ else if (veh->bIsBus && (m_vehDoor == CAR_DOOR_RF || m_vehDoor == CAR_DOOR_RR))
+ correctionMat.SetRotateZ(HALFPI);
+ else
+ correctionMat.SetRotateZ(PI);
+
+ vehDoorMat = vehDoorMat * correctionMat;
+ }
GetMatrix() = vehDoorMat;
}
@@ -3290,41 +3639,71 @@ CPed::SetCarJack(CVehicle* car)
if (car->IsBoat())
return;
- switch (m_vehDoor) {
- case CAR_DOOR_RF:
- doorFlag = CAR_DOOR_FLAG_RF;
- door = DOOR_FRONT_RIGHT;
- if (car->pPassengers[0]) {
+ if (car->IsBike()) {
+ switch (m_vehDoor) {
+ case CAR_DOOR_RF:
+ doorFlag = CAR_DOOR_FLAG_LF | CAR_DOOR_FLAG_RF;
+ door = DOOR_FRONT_RIGHT;
+ pedInSeat = car->pDriver;
+ break;
+ case CAR_DOOR_RR:
+ doorFlag = CAR_DOOR_FLAG_LR | CAR_DOOR_FLAG_RR;
+ door = DOOR_REAR_RIGHT;
pedInSeat = car->pPassengers[0];
- } else if (m_nPedType == PEDTYPE_COP) {
+ break;
+ case CAR_DOOR_LF:
+ case CAR_WINDSCREEN:
+ doorFlag = CAR_DOOR_FLAG_LF | CAR_DOOR_FLAG_RF;
+ door = DOOR_FRONT_LEFT;
pedInSeat = car->pDriver;
- }
- break;
- case CAR_DOOR_RR:
- doorFlag = CAR_DOOR_FLAG_RR;
- door = DOOR_REAR_RIGHT;
- pedInSeat = car->pPassengers[2];
- break;
- case CAR_DOOR_LF:
- doorFlag = CAR_DOOR_FLAG_LF;
- door = DOOR_FRONT_LEFT;
- pedInSeat = car->pDriver;
- break;
- case CAR_DOOR_LR:
- doorFlag = CAR_DOOR_FLAG_LR;
- door = DOOR_REAR_LEFT;
- pedInSeat = car->pPassengers[1];
- break;
- default:
- doorFlag = CAR_DOOR_FLAG_UNKNOWN;
- break;
+ break;
+ case CAR_DOOR_LR:
+ doorFlag = CAR_DOOR_FLAG_LR | CAR_DOOR_FLAG_RR;
+ door = DOOR_REAR_LEFT;
+ pedInSeat = car->pPassengers[0];
+ break;
+ default:
+ doorFlag = CAR_DOOR_FLAG_UNKNOWN;
+ break;
+ }
+ } else {
+ switch (m_vehDoor) {
+ case CAR_DOOR_RF:
+ doorFlag = CAR_DOOR_FLAG_RF;
+ door = DOOR_FRONT_RIGHT;
+ if (car->pPassengers[0]) {
+ pedInSeat = car->pPassengers[0];
+ }
+ else if (m_nPedType == PEDTYPE_COP) {
+ pedInSeat = car->pDriver;
+ }
+ break;
+ case CAR_DOOR_RR:
+ doorFlag = CAR_DOOR_FLAG_RR;
+ door = DOOR_REAR_RIGHT;
+ pedInSeat = car->pPassengers[2];
+ break;
+ case CAR_DOOR_LF:
+ doorFlag = CAR_DOOR_FLAG_LF;
+ door = DOOR_FRONT_LEFT;
+ pedInSeat = car->pDriver;
+ break;
+ case CAR_DOOR_LR:
+ doorFlag = CAR_DOOR_FLAG_LR;
+ door = DOOR_REAR_LEFT;
+ pedInSeat = car->pPassengers[1];
+ break;
+ default:
+ doorFlag = CAR_DOOR_FLAG_UNKNOWN;
+ break;
+ }
}
if(car->bIsBus)
pedInSeat = car->pDriver;
if (m_fHealth > 0.0f && (IsPlayer() || m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT || m_objective == OBJECTIVE_KILL_CHAR_ANY_MEANS ||
- (car->VehicleCreatedBy != MISSION_VEHICLE && car->GetModelIndex() != MI_DODO)))
+ CharCreatedBy == MISSION_CHAR || (car->VehicleCreatedBy != MISSION_VEHICLE && car->GetModelIndex() != MI_DODO)))
if (pedInSeat && !pedInSeat->IsPedDoingDriveByShooting() && pedInSeat->m_nPedState == PED_DRIVING)
if (m_nPedState != PED_CARJACK && !m_pVehicleAnim)
if ((car->IsDoorReady(door) || car->IsDoorFullyOpen(door)))
@@ -3333,9 +3712,8 @@ CPed::SetCarJack(CVehicle* car)
}
void
-CPed::SetCarJack_AllClear(CVehicle *car, uint32 doorNode, uint32 doorFlag)
+CPed::SetCarJack_AllClear(CVehicle* car, uint32 doorNode, uint32 doorFlag)
{
- RemoveWeaponWhenEnteringVehicle();
if (m_nPedState != PED_SEEK_CAR)
SetStoredState();
@@ -3347,22 +3725,32 @@ CPed::SetCarJack_AllClear(CVehicle *car, uint32 doorNode, uint32 doorFlag)
m_pMyVehicle->RegisterReference((CEntity**)&m_pMyVehicle);
((CVehicle*)m_pSeekTarget)->m_nNumGettingIn++;
- Say(m_nPedType == PEDTYPE_COP ? SOUND_PED_ARREST_COP : SOUND_PED_CAR_JACKING);
+ if (m_nPedType == PEDTYPE_COP)
+ Say(SOUND_PED_ARREST_COP);
+ else if (car->m_nDoorLock == CARLOCK_UNLOCKED)
+ Say(SOUND_PED_CAR_JACKING, 1000);
+
CVector carEnterPos;
carEnterPos = GetPositionToOpenCarDoor(car, m_vehDoor);
car->m_nGettingInFlags |= doorFlag;
m_vecOffsetSeek = carEnterPos - GetPosition();
m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 600;
- float zDiff = Max(0.0f, carEnterPos.z - GetPosition().z);
- bUsesCollision = false;
- if (m_vehDoor == CAR_DOOR_LF || m_vehDoor == CAR_DOOR_LR)
- m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, zDiff > 4.4f ? ANIM_STD_CAR_ALIGNHI_DOOR_LHS : ANIM_STD_CAR_ALIGN_DOOR_LHS, 4.0f);
- else
- m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, zDiff > 4.4f ? ANIM_STD_CAR_ALIGNHI_DOOR_RHS : ANIM_STD_CAR_ALIGN_DOOR_RHS, 4.0f);
+ if(car->IsBike()){
+ bUsesCollision = false;
+ PedAnimAlignCB(nil, this);
+ } else {
+ float zDiff = Max(0.0f, carEnterPos.z - GetPosition().z);
+ bUsesCollision = false;
+
+ if (m_vehDoor == CAR_DOOR_LF || m_vehDoor == CAR_DOOR_LR)
+ m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, zDiff > 4.4f ? ANIM_STD_CAR_ALIGNHI_DOOR_LHS : ANIM_STD_CAR_ALIGN_DOOR_LHS, 4.0f);
+ else
+ m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, zDiff > 4.4f ? ANIM_STD_CAR_ALIGNHI_DOOR_RHS : ANIM_STD_CAR_ALIGN_DOOR_RHS, 4.0f);
- m_pVehicleAnim->SetFinishCallback(PedAnimAlignCB, this);
+ m_pVehicleAnim->SetFinishCallback(PedAnimAlignCB, this);
+ }
}
void
@@ -3377,7 +3765,17 @@ CPed::SetBeingDraggedFromCar(CVehicle *veh, uint32 vehEnterType, bool quickJack)
SetMoveState(PEDMOVE_STILL);
m_pSeekTarget = veh;
m_pSeekTarget->RegisterReference((CEntity **) &m_pSeekTarget);
- m_vehDoor = vehEnterType;
+
+ if (veh->IsBike()) {
+ ((CBike*)veh)->bIsBeingPickedUp = true;
+ if (veh->pPassengers[0] != this && (vehEnterType != CAR_WINDSCREEN || veh->pPassengers[0]))
+ m_vehDoor = CAR_DOOR_LF;
+ else
+ m_vehDoor = CAR_DOOR_LR;
+ } else {
+ m_vehDoor = vehEnterType;
+ }
+
if (m_vehDoor == CAR_DOOR_LF) {
if (veh->pDriver && veh->pDriver->IsPlayer())
veh->SetStatus(STATUS_PLAYER_DISABLED);
@@ -3386,7 +3784,7 @@ CPed::SetBeingDraggedFromCar(CVehicle *veh, uint32 vehEnterType, bool quickJack)
}
RemoveInCarAnims();
SetMoveState(PEDMOVE_NONE);
- LineUpPedWithCar(LINE_UP_TO_CAR_START);
+ LineUpPedWithCar(veh->IsBike() ? LINE_UP_TO_CAR_FALL : LINE_UP_TO_CAR_START);
m_pVehicleAnim = nil;
SetPedState(PED_DRAG_FROM_CAR);
bChangedSeat = false;
@@ -3396,68 +3794,76 @@ CPed::SetBeingDraggedFromCar(CVehicle *veh, uint32 vehEnterType, bool quickJack)
Say(SOUND_PED_CAR_JACKED);
SetRadioStation();
- veh->m_nGettingOutFlags |= GetCarDoorFlag(m_vehDoor);
+
+ if(veh->IsBike())
+ veh->m_nGettingOutFlags |= GetBikeDoorFlagInclJumpInFromFront(m_vehDoor);
+ else
+ veh->m_nGettingOutFlags |= GetCarDoorFlag(m_vehDoor);
}
void
CPed::BeingDraggedFromCar(void)
{
- CAnimBlendAssociation *animAssoc;
AnimationId enterAnim;
bool dontRunAnim = false;
- PedLineUpPhase lineUpType;
if (!m_pVehicleAnim) {
- CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_STD_IDLE, 100.0f);
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_SIT);
- if (!animAssoc) {
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_SIT_LO);
- if (!animAssoc) {
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_SIT_P);
- if (!animAssoc)
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_SIT_P_LO);
- }
- }
- if (animAssoc)
- animAssoc->blendDelta = -1000.0f;
-
- if (m_vehDoor == CAR_DOOR_LF || m_vehDoor == CAR_DOOR_LR) {
- if (bWillBeQuickJacked) {
- enterAnim = ANIM_STD_QUICKJACKED;
- } else if (m_pMyVehicle->bLowVehicle) {
- enterAnim = ANIM_STD_JACKEDCAR_LO_LHS;
- } else {
- enterAnim = ANIM_STD_JACKEDCAR_LHS;
- }
- } else if (m_vehDoor == CAR_DOOR_RF || m_vehDoor == CAR_DOOR_RR) {
- if (m_pMyVehicle->bLowVehicle)
- enterAnim = ANIM_STD_JACKEDCAR_LO_RHS;
- else
- enterAnim = ANIM_STD_JACKEDCAR_RHS;
- } else
- dontRunAnim = true;
+ CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_STD_IDLE, 1000.0f);
+ AssocGroupId assocGroup;
+ if (m_pMyVehicle && m_pMyVehicle->IsBike()) {
+ enterAnim = ANIM_BIKE_HIT;
+ assocGroup = ((CBike*)m_pMyVehicle)->m_bikeAnimType;
+
+ } else {
+ if (m_vehDoor == CAR_DOOR_LF || m_vehDoor == CAR_DOOR_LR) {
+ if (bWillBeQuickJacked && m_vehDoor == CAR_DOOR_LF) {
+ enterAnim = ANIM_STD_QUICKJACKED;
+ } else if (m_pMyVehicle->bLowVehicle) {
+ enterAnim = ANIM_STD_JACKEDCAR_LO_LHS;
+ } else {
+ enterAnim = ANIM_STD_JACKEDCAR_LHS;
+ }
+ } else if (m_vehDoor == CAR_DOOR_RF || m_vehDoor == CAR_DOOR_RR) {
+ if (m_pMyVehicle->bLowVehicle)
+ enterAnim = ANIM_STD_JACKEDCAR_LO_RHS;
+ else
+ enterAnim = ANIM_STD_JACKEDCAR_RHS;
+ } else
+ dontRunAnim = true;
+
+ assocGroup = ASSOCGRP_STD;
+ }
if (!dontRunAnim)
- m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, enterAnim);
+ m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), assocGroup, enterAnim);
m_pVehicleAnim->SetFinishCallback(PedSetDraggedOutCarCB, this);
- lineUpType = LINE_UP_TO_CAR_START;
+
+ if (m_pMyVehicle && m_pMyVehicle->IsBike()) {
+ LineUpPedWithCar(LINE_UP_TO_CAR_FALL);
+ } else {
+ LineUpPedWithCar(LINE_UP_TO_CAR_START);
+ }
+ return;
+
+ } else if (m_pVehicleAnim->animId == ANIM_BIKE_HIT) {
+ LineUpPedWithCar(LINE_UP_TO_CAR_FALL);
+
} else if (m_pVehicleAnim->currentTime <= 1.4f) {
m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
- lineUpType = LINE_UP_TO_CAR_START;
+ LineUpPedWithCar(LINE_UP_TO_CAR_START);
+
} else {
- lineUpType = LINE_UP_TO_CAR_2;
+ LineUpPedWithCar(LINE_UP_TO_CAR_2);
}
-
- LineUpPedWithCar(lineUpType);
-#ifdef VC_PED_PORTS
+
+ static float mult = 5.f;
if (m_objective == OBJECTIVE_LEAVE_CAR_AND_DIE) {
if (m_pMyVehicle) {
- m_pMyVehicle->ProcessOpenDoor(m_vehDoor, ANIM_STD_NUM, m_pVehicleAnim->currentTime * 5.0f);
+ m_pMyVehicle->ProcessOpenDoor(m_vehDoor, ANIM_STD_NUM, m_pVehicleAnim->currentTime * mult);
}
}
-#endif
}
void
@@ -3469,26 +3875,62 @@ CPed::SetEnterCar(CVehicle *car, uint32 unused)
} else {
uint8 doorFlag;
eDoors door;
- switch (m_vehDoor) {
- case CAR_DOOR_RF:
- doorFlag = CAR_DOOR_FLAG_RF;
- door = DOOR_FRONT_RIGHT;
- break;
- case CAR_DOOR_RR:
- doorFlag = CAR_DOOR_FLAG_RR;
- door = DOOR_REAR_RIGHT;
- break;
- case CAR_DOOR_LF:
- doorFlag = CAR_DOOR_FLAG_LF;
- door = DOOR_FRONT_LEFT;
- break;
- case CAR_DOOR_LR:
- doorFlag = CAR_DOOR_FLAG_LR;
- door = DOOR_REAR_LEFT;
- break;
- default:
- doorFlag = CAR_DOOR_FLAG_UNKNOWN;
- break;
+ if (car->IsBike()) {
+ switch (m_vehDoor) {
+ case CAR_DOOR_RF:
+ doorFlag = CAR_DOOR_FLAG_RF | CAR_DOOR_FLAG_LF;
+ door = DOOR_FRONT_RIGHT;
+ break;
+ case CAR_DOOR_RR:
+ doorFlag = CAR_DOOR_FLAG_RR | CAR_DOOR_FLAG_LR;
+ door = DOOR_REAR_RIGHT;
+ break;
+ case CAR_WING_LF:
+ case CAR_WING_LR:
+ case CAR_BONNET:
+ case CAR_BOOT:
+ doorFlag = CAR_DOOR_FLAG_UNKNOWN;
+ break;
+ case CAR_DOOR_LF:
+ case CAR_WINDSCREEN:
+ doorFlag = CAR_DOOR_FLAG_RF | CAR_DOOR_FLAG_LF;
+ door = DOOR_FRONT_LEFT;
+ break;
+ case CAR_DOOR_LR:
+ doorFlag = CAR_DOOR_FLAG_RR | CAR_DOOR_FLAG_LR;
+ door = DOOR_REAR_LEFT;
+ break;
+ }
+ } else {
+ switch (m_vehDoor) {
+ case CAR_DOOR_RF:
+ doorFlag = CAR_DOOR_FLAG_RF;
+ door = DOOR_FRONT_RIGHT;
+ break;
+ case CAR_DOOR_RR:
+ doorFlag = CAR_DOOR_FLAG_RR;
+ door = DOOR_REAR_RIGHT;
+ break;
+ case CAR_DOOR_LF:
+ if(car->m_nNumMaxPassengers != 0)
+ doorFlag = CAR_DOOR_FLAG_LF;
+ else
+ doorFlag = CAR_DOOR_FLAG_LF | CAR_DOOR_FLAG_LR;
+
+ door = DOOR_FRONT_LEFT;
+ break;
+ case CAR_DOOR_LR:
+ if (car->m_nNumMaxPassengers != 0)
+ doorFlag = CAR_DOOR_FLAG_LR;
+ else
+ doorFlag = CAR_DOOR_FLAG_LF | CAR_DOOR_FLAG_LR;
+
+ door = DOOR_REAR_LEFT;
+ break;
+ default:
+ doorFlag = CAR_DOOR_FLAG_UNKNOWN;
+ break;
+ }
}
if (!IsPedInControl() || m_fHealth <= 0.0f
|| doorFlag & car->m_nGettingInFlags || doorFlag & car->m_nGettingOutFlags
@@ -3504,7 +3946,6 @@ void
CPed::SetEnterCar_AllClear(CVehicle *car, uint32 doorNode, uint32 doorFlag)
{
float zDiff = 0.0f;
- RemoveWeaponWhenEnteringVehicle();
car->m_nGettingInFlags |= doorFlag;
bVehEnterDoorIsBlocked = false;
if (m_nPedState != PED_SEEK_CAR && m_nPedState != PED_SEEK_IN_BOAT)
@@ -3514,7 +3955,7 @@ CPed::SetEnterCar_AllClear(CVehicle *car, uint32 doorNode, uint32 doorFlag)
m_pSeekTarget->RegisterReference((CEntity **) &m_pSeekTarget);
m_vehDoor = doorNode;
SetPedState(PED_ENTER_CAR);
- if (m_vehDoor == CAR_DOOR_RF && m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER && car->m_vehType != VEHICLE_TYPE_BIKE) {
+ if (m_vehDoor == CAR_DOOR_RF && m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER && !car->IsBike()) {
car->bIsBeingCarJacked = true;
}
@@ -3530,43 +3971,26 @@ 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_STD_CAR_SIT, 100.0f);
else
m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_BOAT_DRIVE, 100.0f);
PedSetInCarCB(nil, this);
bVehExitWillBeInstant = true;
-#else
-#ifndef FIX_BUGS
- m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_BOAT_DRIVE, 100.0f);
-#else
- m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, car->GetDriverAnim(), 100.0f);
-#endif
+ } else if (car->IsBike()) {
+ PedAnimAlignCB(0, this);
+ car->AutoPilot.m_nCruiseSpeed = 0;
- m_pVehicleAnim->SetFinishCallback(PedSetInCarCB, this);
-#endif
- if (IsPlayer())
- CWaterLevel::AllocateBoatWakeArray();
} else {
- if (zDiff > 4.4f) {
- if (m_vehDoor == CAR_DOOR_RF || m_vehDoor == CAR_DOOR_RR)
- m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_ALIGNHI_DOOR_RHS, 4.0f);
- else
- m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_ALIGNHI_DOOR_LHS, 4.0f);
-
- } else {
- if (m_vehDoor == CAR_DOOR_RF || m_vehDoor == CAR_DOOR_RR)
- m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_ALIGN_DOOR_RHS, 4.0f);
- else
- m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_ALIGN_DOOR_LHS, 4.0f);
- }
+ if (m_vehDoor == CAR_DOOR_LF || m_vehDoor == CAR_DOOR_LR)
+ m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, zDiff > 4.4f ? ANIM_STD_CAR_ALIGNHI_DOOR_RHS : ANIM_STD_CAR_ALIGN_DOOR_RHS, 4.0f);
+ else
+ m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, zDiff > 4.4f ? ANIM_STD_CAR_ALIGNHI_DOOR_LHS : ANIM_STD_CAR_ALIGN_DOOR_LHS, 4.0f);
m_pVehicleAnim->SetFinishCallback(PedAnimAlignCB, this);
- car->AutoPilot.m_nCruiseSpeed = 0;
}
}
@@ -3574,7 +3998,7 @@ void
CPed::EnterCar(void)
{
if (IsNotInWreckedVehicle() && m_fHealth > 0.0f) {
- CVehicle *veh = (CVehicle*)m_pSeekTarget;
+ CVehicle *veh = m_pMyVehicle;
// Not used.
// CVector posForDoor = GetPositionToOpenCarDoor(veh, m_vehDoor);
@@ -3586,9 +4010,30 @@ CPed::EnterCar(void)
}
bIsInTheAir = false;
LineUpPedWithCar(LINE_UP_TO_CAR_START);
+ if (veh->IsBike()) {
+ CBike *bike = (CBike*)veh;
+ if (bike->GetStatus() == STATUS_ABANDONED && !bike->bIsBeingPickedUp && m_pVehicleAnim) {
+ int anim = m_pVehicleAnim->animId;
+
+ // One is pickup and other one is pullup, not same :p
+ if ((anim == ANIM_STD_BIKE_PICKUP_LHS || anim == ANIM_STD_BIKE_PICKUP_RHS) && m_pVehicleAnim->currentTime > 0.4667f)
+ bike->bIsBeingPickedUp = true;
+ else if ((anim == ANIM_STD_BIKE_PULLUP_LHS || anim == ANIM_STD_BIKE_PULLUP_RHS) && m_pVehicleAnim->currentTime > 0.4667f)
+ bike->bIsBeingPickedUp = true;
+ } else if (m_nPedState == PED_CARJACK && m_pVehicleAnim) {
+ if (m_pVehicleAnim->currentTime > 0.4f && m_pVehicleAnim->currentTime - m_pVehicleAnim->timeStep <= 0.4f) {
+ int anim = m_pVehicleAnim->animId;
+ if (anim == ANIM_BIKE_KICK) {
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_187, 3.0f);
+ } else if (anim == ANIM_STD_BIKE_ELBOW_LHS || anim == ANIM_STD_BIKE_ELBOW_RHS) {
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_186, 3.0f);
+ }
+ }
+ }
+ }
} else {
QuitEnteringCar();
- SetDie(ANIM_STD_KO_FRONT, 4.0f, 0.0f);
+ SetDie();
}
}
@@ -3611,18 +4056,18 @@ CPed::QuitEnteringCar(void)
if (veh->m_nNumGettingIn != 0)
veh->m_nNumGettingIn--;
-#ifdef VC_PED_PORTS
if (m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER || m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER)
RestorePreviousObjective();
-#endif
- veh->m_nGettingInFlags &= ~GetCarDoorFlag(m_vehDoor);
+ if (veh->IsBike()) {
+ veh->m_nGettingInFlags &= ~GetBikeDoorFlag(m_vehDoor);
+ ((CBike*)veh)->bIsBeingPickedUp = false;
+ } else
+ veh->m_nGettingInFlags &= ~GetEnterCarDoorFlag(m_vehDoor, veh->m_nNumMaxPassengers);
}
bUsesCollision = true;
- ReplaceWeaponWhenExitingVehicle();
-
if (DyingOrDead()) {
if (m_pVehicleAnim) {
m_pVehicleAnim->blendDelta = -4.0f;
@@ -3635,72 +4080,20 @@ CPed::QuitEnteringCar(void)
m_pVehicleAnim = nil;
if (veh) {
-#ifdef VC_PED_PORTS
if (veh->AutoPilot.m_nCruiseSpeed == 0 && veh->VehicleCreatedBy == RANDOM_VEHICLE)
-#else
- if (veh->AutoPilot.m_nCruiseSpeed == 0)
-#endif
veh->AutoPilot.m_nCruiseSpeed = 17;
}
}
void
-AddYardieDoorSmoke(CVehicle *veh, uint32 doorNode)
-{
- eDoors door;
- switch (doorNode) {
- case CAR_DOOR_RF:
- door = DOOR_FRONT_RIGHT;
- break;
- case CAR_DOOR_LF:
- door = DOOR_FRONT_LEFT;
- break;
- default:
- break;
- }
-
- if (!veh->IsDoorMissing(door) && veh->IsComponentPresent(doorNode)) {
- CVector pos;
-#ifdef FIX_BUGS
- veh->GetComponentWorldPosition(doorNode, pos);
-#else
- veh->GetComponentWorldPosition(CAR_DOOR_LF, pos);
-#endif
- CParticle::AddYardieDoorSmoke(pos, veh->GetMatrix());
- }
-}
-
-// Seperate function in VC, more logical. Not sure is it inlined in III.
-void
CPed::SetExitBoat(CVehicle *boat)
{
-#ifndef VC_PED_PORTS
- SetPedState(PED_IDLE);
- CVector firstPos = GetPosition();
- CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_STD_IDLE, 100.0f);
- if (boat->GetModelIndex() == MI_SPEEDER && boat->IsUpsideDown()) {
- m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_CRAWLOUT_LHS, 8.0f);
- m_pVehicleAnim->SetFinishCallback(PedSetOutCarCB, this);
- m_vehDoor = CAR_DOOR_RF;
- SetPedState(PED_EXIT_CAR);
- } else {
- m_vehDoor = CAR_DOOR_RF;
- PedSetOutCarCB(nil, this);
- bIsStanding = true;
- m_pCurSurface = boat;
- m_pCurSurface->RegisterReference((CEntity**)&m_pCurSurface);
- }
- SetPosition(firstPos);
- SetMoveState(PEDMOVE_STILL);
- m_vecMoveSpeed = boat->m_vecMoveSpeed;
- bTryingToReachDryLand = true;
-#else
SetPedState(PED_IDLE);
CVector newPos = GetPosition();
RemoveInCarAnims();
CColModel* boatCol = boat->GetColModel();
if (boat->IsUpsideDown()) {
- newPos = { 0.0f, 0.0f, boatCol->boundingBox.min.z };
+ newPos = CVector(0.0f, 0.0f, boatCol->boundingBox.min.z);
newPos = boat->GetMatrix() * newPos;
newPos.z += 1.0f;
m_vehDoor = CAR_DOOR_RF;
@@ -3710,47 +4103,43 @@ CPed::SetExitBoat(CVehicle *boat)
m_pCurSurface->RegisterReference((CEntity**)&m_pCurSurface);
m_pCurrentPhysSurface = boat;
} else {
-/* if (boat->m_modelIndex != MI_SKIMMER || boat->bIsInWater) {
- if (boat->m_modelIndex == MI_SKIMMER)
- newPos.z += 2.0f
-*/
- m_vehDoor = CAR_DOOR_RF;
- PedSetOutCarCB(nil, this);
- bIsStanding = true;
- m_pCurSurface = boat;
- m_pCurSurface->RegisterReference((CEntity**)&m_pCurSurface);
- m_pCurrentPhysSurface = boat;
- CColPoint foundCol;
- CEntity *foundEnt = nil;
- if (CWorld::ProcessVerticalLine(newPos, newPos.z - 1.4f, foundCol, foundEnt, false, true, false, false, false, false, nil))
- newPos.z = FEET_OFFSET + foundCol.point.z;
-/* // VC specific
- } else {
- m_vehDoor = CAR_DOOR_RF;
- PedSetOutCarCB(nil, this);
- bIsStanding = true;
- SetMoveState(PEDMOVE_STILL);
- bTryingToReachDryLand = true;
- float upMult = 1.04f + boatCol->boundingBox.min.z;
- float rightMult = 0.6f * boatCol->boundingBox.max.x;
- newPos = upMult * boat->GetUp() + rightMult * boat->GetRight() + boat->GetPosition();
- GetPosition() = newPos;
- if (m_pMyVehicle) {
- PositionPedOutOfCollision();
- } else {
- m_pMyVehicle = boat;
- PositionPedOutOfCollision();
- m_pMyVehicle = nil;
+ if (boat->m_modelIndex == MI_SKIMMER) {
+ if (!boat->bIsInWater) {
+ m_vehDoor = CAR_DOOR_RF;
+ PedSetOutCarCB(nil, this);
+ bIsStanding = true;
+ SetMoveState(PEDMOVE_STILL);
+ bTryingToReachDryLand = true;
+ float upMult = 1.04f + boatCol->boundingBox.min.z;
+ float rightMult = 0.6f * boatCol->boundingBox.max.x;
+ newPos = upMult * boat->GetUp() + rightMult * boat->GetRight() + boat->GetPosition();
+ SetPosition(newPos);
+ if (m_pMyVehicle) {
+ PositionPedOutOfCollision();
+ } else {
+ m_pMyVehicle = boat;
+ PositionPedOutOfCollision();
+ m_pMyVehicle = nil;
+ }
+ return;
}
- return;
+
+ newPos.z += 2.0f;
}
-*/ }
+ m_vehDoor = CAR_DOOR_RF;
+ PedSetOutCarCB(nil, this);
+ bIsStanding = true;
+ m_pCurSurface = boat;
+ m_pCurSurface->RegisterReference((CEntity**)&m_pCurSurface);
+ m_pCurrentPhysSurface = boat;
+ CColPoint foundCol;
+ CEntity *foundEnt = nil;
+ if (CWorld::ProcessVerticalLine(newPos, newPos.z - 1.4f, foundCol, foundEnt, false, true, false, false, false, false, nil))
+ newPos.z = FEET_OFFSET + foundCol.point.z;
+ }
SetPosition(newPos);
SetMoveState(PEDMOVE_STILL);
m_vecMoveSpeed = boat->m_vecMoveSpeed;
-#endif
- // Not there in VC.
- CWaterLevel::FreeBoatWakeArray();
}
// wantedDoorNode = 0 means that func. will determine it
@@ -3760,12 +4149,26 @@ CPed::SetExitCar(CVehicle *veh, uint32 wantedDoorNode)
uint32 optedDoorNode = wantedDoorNode;
bool teleportNeeded = false;
bool isLow = !!veh->bLowVehicle;
- if (!veh->CanPedExitCar()) {
- if (veh->pDriver && !veh->pDriver->IsPlayer()) {
- veh->AutoPilot.m_nCruiseSpeed = 0;
- veh->AutoPilot.m_nCarMission = MISSION_NONE;
+
+ bool canJumpOut = false;
+ if (!veh->CanPedExitCar(false) && !bBusJacked) {
+ if (IsPlayer()) {
+ canJumpOut = veh->IsBike() ? veh->CanPedJumpOffBike() : veh->CanPedJumpOutCar();
+ }
+ if (!canJumpOut) {
+ if (veh->pDriver) {
+ if (veh->pDriver->IsPlayer()) {
+ if (veh->pDriver != this) {
+ m_leaveCarTimer = CTimer::GetTimeInMilliseconds() + 5000;
+ bHeldHostageInCar = true;
+ }
+ } else {
+ veh->AutoPilot.m_nCruiseSpeed = 0;
+ veh->AutoPilot.m_nCarMission = MISSION_NONE;
+ }
+ }
+ return;
}
- return;
}
if (m_nPedState == PED_EXIT_CAR || m_nPedState == PED_DRAG_FROM_CAR)
@@ -3775,107 +4178,164 @@ CPed::SetExitCar(CVehicle *veh, uint32 wantedDoorNode)
m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f);
if (wantedDoorNode == 0) {
optedDoorNode = CAR_DOOR_LF;
- if (!veh->bIsBus) {
- if (veh->pDriver == this) {
- optedDoorNode = CAR_DOOR_LF;
+ if (veh->IsBike()) {
+ if (canJumpOut) {
+ optedDoorNode = veh->pPassengers[0] == this ? CAR_BUMP_REAR : CAR_BOOT;
} else if (veh->pPassengers[0] == this) {
- optedDoorNode = CAR_DOOR_RF;
- } else if (veh->pPassengers[1] == this) {
optedDoorNode = CAR_DOOR_LR;
- } else if (veh->pPassengers[2] == this) {
- optedDoorNode = CAR_DOOR_RR;
} else {
- for (int i = 3; i < veh->m_nNumMaxPassengers; ++i) {
- if (veh->pPassengers[i] == this) {
- if (i & 1)
- optedDoorNode = CAR_DOOR_RR;
- else
- optedDoorNode = CAR_DOOR_LR;
+ optedDoorNode = CAR_DOOR_LF;
+ }
+ } else if (veh->bIsBus) {
+ optedDoorNode = CAR_DOOR_LF;
+ } else if (veh->pDriver == this) {
+ optedDoorNode = CAR_DOOR_LF;
+ } else if (veh->pPassengers[0] == this) {
+ optedDoorNode = CAR_DOOR_RF;
+ } else if (veh->pPassengers[1] == this) {
+ optedDoorNode = CAR_DOOR_LR;
+ } else if (veh->pPassengers[2] == this) {
+ optedDoorNode = CAR_DOOR_RR;
+ } else {
+ for (int i = 3; i < veh->m_nNumMaxPassengers; ++i) {
+ if (veh->pPassengers[i] == this) {
+ if (i & 1)
+ optedDoorNode = CAR_DOOR_RR;
+ else
+ optedDoorNode = CAR_DOOR_LR;
- break;
- }
+ break;
}
}
}
}
bool someoneExitsFromOurExitDoor = false;
bool someoneEntersFromOurExitDoor = false;
- switch (optedDoorNode) {
- case CAR_DOOR_RF:
- if (veh->m_nGettingInFlags & CAR_DOOR_FLAG_RF)
- someoneEntersFromOurExitDoor = true;
- if (veh->m_nGettingOutFlags & CAR_DOOR_FLAG_RF)
- someoneExitsFromOurExitDoor = true;
- break;
- case CAR_DOOR_RR:
- if (veh->m_nGettingInFlags & CAR_DOOR_FLAG_RR)
- someoneEntersFromOurExitDoor = true;
- if (veh->m_nGettingOutFlags & CAR_DOOR_FLAG_RR)
- someoneExitsFromOurExitDoor = true;
- break;
- case CAR_DOOR_LF:
- if (veh->m_nGettingInFlags & CAR_DOOR_FLAG_LF)
- someoneEntersFromOurExitDoor = true;
- if (veh->m_nGettingOutFlags & CAR_DOOR_FLAG_LF)
- someoneExitsFromOurExitDoor = true;
- break;
- case CAR_DOOR_LR:
- if (veh->m_nGettingInFlags & CAR_DOOR_FLAG_LR)
- someoneEntersFromOurExitDoor = true;
- if (veh->m_nGettingOutFlags & CAR_DOOR_FLAG_LR)
- someoneExitsFromOurExitDoor = true;
- break;
- default:
- break;
+ if (veh->IsBike()) {
+ switch (optedDoorNode) {
+ case CAR_BUMP_REAR:
+ case CAR_DOOR_RR:
+ case CAR_DOOR_LR:
+ if (veh->m_nGettingInFlags & (CAR_DOOR_FLAG_LR | CAR_DOOR_FLAG_RR))
+ someoneEntersFromOurExitDoor = true;
+ break;
+ case CAR_DOOR_RF:
+ case CAR_DOOR_LF:
+ case CAR_BOOT:
+ if (veh->m_nGettingInFlags & (CAR_DOOR_FLAG_LF | CAR_DOOR_FLAG_RF))
+ someoneEntersFromOurExitDoor = true;
+ break;
+ default:
+ break;
+ }
+ } else {
+ switch (optedDoorNode) {
+ case CAR_DOOR_RF:
+ if (veh->m_nGettingInFlags & CAR_DOOR_FLAG_RF)
+ someoneEntersFromOurExitDoor = true;
+ if (veh->m_nGettingOutFlags & CAR_DOOR_FLAG_RF)
+ someoneExitsFromOurExitDoor = true;
+ break;
+ case CAR_DOOR_RR:
+ if (veh->m_nGettingInFlags & CAR_DOOR_FLAG_RR)
+ someoneEntersFromOurExitDoor = true;
+ if (veh->m_nGettingOutFlags & CAR_DOOR_FLAG_RR)
+ someoneExitsFromOurExitDoor = true;
+ break;
+ case CAR_DOOR_LF:
+ if (veh->m_nGettingInFlags & CAR_DOOR_FLAG_LF)
+ someoneEntersFromOurExitDoor = true;
+ if (veh->m_nGettingOutFlags & CAR_DOOR_FLAG_LF)
+ someoneExitsFromOurExitDoor = true;
+ break;
+ case CAR_DOOR_LR:
+ if (veh->m_nGettingInFlags & CAR_DOOR_FLAG_LR)
+ someoneEntersFromOurExitDoor = true;
+ if (veh->m_nGettingOutFlags & CAR_DOOR_FLAG_LR)
+ someoneExitsFromOurExitDoor = true;
+ break;
+ default:
+ break;
+ }
}
if (someoneEntersFromOurExitDoor && m_objective == OBJECTIVE_LEAVE_CAR) {
RestorePreviousObjective();
return;
}
if (!someoneExitsFromOurExitDoor || m_nPedType == PEDTYPE_COP && veh->bIsBus) {
- // Again, unused...
- // CVector exitPos = GetPositionToOpenCarDoor(veh, optedDoorNode);
- bool thereIsRoom = veh->IsRoomForPedToLeaveCar(optedDoorNode, nil);
- if (veh->IsOnItsSide()) {
- teleportNeeded = true;
- } else if (!thereIsRoom) {
+#if defined GTAVC_JP_PATCH || defined FIX_BUGS
+ if (veh->pDriver == this && !IsPlayer() && veh == CGameLogic::pShortCutTaxi) {
+ m_objective = OBJECTIVE_NONE;
+ return;
+ }
+#endif
+ bool thereIsRoom;
+ if (canJumpOut) {
+ thereIsRoom = 1;
+ } else {
+ // Again, unused...
+ // CVector exitPos = GetPositionToOpenCarDoor(veh, optedDoorNode);
+ thereIsRoom = veh->IsRoomForPedToLeaveCar(optedDoorNode, nil);
+ }
+
+ if (!thereIsRoom) {
bool trySideSeat = false;
- CPed *pedOnSideSeat = nil;
- switch (optedDoorNode) {
- case CAR_DOOR_RF:
- if (veh->pDriver || veh->m_nGettingInFlags & CAR_DOOR_FLAG_LF) {
- pedOnSideSeat = veh->pDriver;
- trySideSeat = true;
- } else
+ CPed *pedOnSideSeat;
+ int firstOptedDoor = optedDoorNode;
+ if (veh->IsBike()) {
+ switch (optedDoorNode) {
+ case CAR_DOOR_RF:
optedDoorNode = CAR_DOOR_LF;
-
- break;
- case CAR_DOOR_RR:
- if (veh->pPassengers[1] || veh->m_nGettingInFlags & CAR_DOOR_FLAG_LR) {
- pedOnSideSeat = veh->pPassengers[1];
- trySideSeat = true;
- } else
+ break;
+ case CAR_DOOR_RR:
optedDoorNode = CAR_DOOR_LR;
-
- break;
- case CAR_DOOR_LF:
- if (veh->pPassengers[0] || veh->m_nGettingInFlags & CAR_DOOR_FLAG_RF) {
- pedOnSideSeat = veh->pPassengers[0];
- trySideSeat = true;
- } else
+ break;
+ case CAR_DOOR_LF:
optedDoorNode = CAR_DOOR_RF;
-
- break;
- case CAR_DOOR_LR:
- if (veh->pPassengers[2] || veh->m_nGettingInFlags & CAR_DOOR_FLAG_RR) {
- pedOnSideSeat = (CPed*)veh->pPassengers[2];
- trySideSeat = true;
- } else
+ break;
+ case CAR_DOOR_LR:
optedDoorNode = CAR_DOOR_RR;
+ break;
+ default:
+ break;
+ }
+ } else {
+ switch (optedDoorNode) {
+ case CAR_DOOR_RF:
+ if (veh->pDriver || veh->m_nGettingInFlags & CAR_DOOR_FLAG_LF) {
+ pedOnSideSeat = veh->pDriver;
+ trySideSeat = true;
+ } else
+ optedDoorNode = CAR_DOOR_LF;
- break;
- default:
- break;
+ break;
+ case CAR_DOOR_RR:
+ if (veh->pPassengers[1] || veh->m_nGettingInFlags & CAR_DOOR_FLAG_LR) {
+ pedOnSideSeat = veh->pPassengers[1];
+ trySideSeat = true;
+ } else
+ optedDoorNode = CAR_DOOR_LR;
+
+ break;
+ case CAR_DOOR_LF:
+ if (veh->pPassengers[0] || veh->m_nGettingInFlags & CAR_DOOR_FLAG_RF) {
+ pedOnSideSeat = veh->pPassengers[0];
+ trySideSeat = true;
+ } else
+ optedDoorNode = CAR_DOOR_RF;
+
+ break;
+ case CAR_DOOR_LR:
+ if (veh->pPassengers[2] || veh->m_nGettingInFlags & CAR_DOOR_FLAG_RR) {
+ pedOnSideSeat = (CPed*)veh->pPassengers[2];
+ trySideSeat = true;
+ } else
+ optedDoorNode = CAR_DOOR_RR;
+
+ break;
+ default:
+ break;
+ }
}
if (trySideSeat) {
if (!pedOnSideSeat || !IsPlayer() && CharCreatedBy != MISSION_CHAR)
@@ -3904,9 +4364,20 @@ CPed::SetExitCar(CVehicle *veh, uint32 wantedDoorNode)
if (!IsPlayer() && CharCreatedBy != MISSION_CHAR)
return;
+ // needed for PositionPedOutOfCollision()
+ optedDoorNode = firstOptedDoor;
+ m_vehDoor = firstOptedDoor;
+ PositionPedOutOfCollision();
teleportNeeded = true;
}
}
+
+ if (!teleportNeeded && veh->IsOnItsSide()) {
+ m_vehDoor = optedDoorNode;
+ PositionPedOutOfCollision();
+ teleportNeeded = true;
+ }
+
if (m_nPedState == PED_FLEE_POS) {
m_nLastPedState = PED_FLEE_POS;
m_nPrevMoveState = PEDMOVE_RUN;
@@ -3917,7 +4388,6 @@ CPed::SetExitCar(CVehicle *veh, uint32 wantedDoorNode)
SetMoveState(PEDMOVE_STILL);
}
- ReplaceWeaponWhenExitingVehicle();
bUsesCollision = false;
m_pSeekTarget = veh;
m_pSeekTarget->RegisterReference((CEntity**) &m_pSeekTarget);
@@ -3925,61 +4395,85 @@ CPed::SetExitCar(CVehicle *veh, uint32 wantedDoorNode)
SetPedState(PED_EXIT_CAR);
if (m_pVehicleAnim && m_pVehicleAnim->flags & ASSOC_PARTIAL)
m_pVehicleAnim->blendDelta = -1000.0f;
+ RemoveInCarAnims();
SetMoveState(PEDMOVE_NONE);
CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_STD_IDLE, 100.0f);
- RemoveInCarAnims();
veh->AutoPilot.m_nCruiseSpeed = 0;
+
if (teleportNeeded) {
PedSetOutCarCB(nil, this);
+ } else {
+ if (veh->GetUp().z <= -0.8f && !veh->IsBike()) {
+ if (m_vehDoor == CAR_DOOR_RF || m_vehDoor == CAR_DOOR_RR) {
+ m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_CRAWLOUT_RHS);
+ } else if (m_vehDoor == CAR_DOOR_LF || m_vehDoor == CAR_DOOR_LR) {
+ m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_CRAWLOUT_LHS);
+ }
+ m_pVehicleAnim->SetFinishCallback(PedSetOutCarCB, this);
- // This is same code with CPedPlacement::FindZCoorForPed, except we start from z + 1.5 and also check vehicles.
- float zForPed;
- float startZ = GetPosition().z - 100.0f;
- float foundColZ = -100.0f;
- float foundColZ2 = -100.0f;
- CColPoint foundCol;
- CEntity* foundEnt;
-
- CVector vec = GetPosition();
- vec.z += 1.5f;
-
- if (CWorld::ProcessVerticalLine(vec, startZ, foundCol, foundEnt, true, true, false, false, true, false, nil))
- foundColZ = foundCol.point.z;
-
- // Adjust coords and do a second test
- vec.x += 0.1f;
- vec.y += 0.1f;
+ } else if (veh->IsBike()) {
+ CBike* bike = (CBike*)veh;
+ switch (m_vehDoor) {
+ case CAR_BUMP_REAR:
+ case CAR_BOOT:
+ m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), bike->m_bikeAnimType, ANIM_BIKE_GETOFF_BACK);
+ break;
+ case CAR_DOOR_RF:
+ case CAR_DOOR_RR:
+ m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), bike->m_bikeAnimType, ANIM_BIKE_GETOFF_RHS);
+ break;
+ case CAR_DOOR_LF:
+ case CAR_DOOR_LR:
+ m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), bike->m_bikeAnimType, ANIM_BIKE_GETOFF_LHS);
+ break;
+ default:
+ break;
+ }
+ int8 exitFlags = 0;
- if (CWorld::ProcessVerticalLine(vec, startZ, foundCol, foundEnt, true, true, false, false, true, false, nil))
- foundColZ2 = foundCol.point.z;
+ // Bike door flags incl. passenger jump off
+ switch (m_vehDoor) {
+ case CAR_BUMP_REAR:
+ case CAR_DOOR_RR:
+ case CAR_DOOR_LR:
+ exitFlags = CAR_DOOR_FLAG_RR | CAR_DOOR_FLAG_LR;
+ break;
+ case CAR_DOOR_RF:
+ case CAR_DOOR_LF:
+ case CAR_BOOT:
+ exitFlags = CAR_DOOR_FLAG_RF | CAR_DOOR_FLAG_LF;
+ break;
+ }
- zForPed = Max(foundColZ, foundColZ2);
+ // Passenger get off
+ if (m_vehDoor == CAR_BUMP_REAR || m_vehDoor == CAR_BOOT) {
+ m_pVehicleAnim->SetFinishCallback(RestoreHeadingRateCB, this);
+ m_headingRate = 0.0f;
- if (zForPed > -99.0f)
- GetMatrix().GetPosition().z = FEET_OFFSET + zForPed;
- } else {
- if (veh->GetUp().z > -0.8f) {
- bool addDoorSmoke = false;
- if (veh->GetModelIndex() == MI_YARDIE)
- addDoorSmoke = true;
+ } else {
+ veh->m_nGettingOutFlags |= exitFlags;
+ m_pVehicleAnim->SetFinishCallback(PedAnimStepOutCarCB, this);
+ }
+ } else {
switch (m_vehDoor) {
case CAR_DOOR_RF:
- if (veh->bIsBus) {
- m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_COACH_GET_OUT_LHS);
+ if (canJumpOut) {
+ m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_ROLLOUT_RHS);
+ } else if (veh->bIsBus) {
+ m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_COACH, ANIM_STD_COACH_GET_OUT_LHS);
} else {
if (isLow)
m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_GETOUT_LO_RHS);
else
m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_GETOUT_RHS);
-
- if (addDoorSmoke)
- AddYardieDoorSmoke(veh, CAR_DOOR_RF);
}
break;
case CAR_DOOR_RR:
- if (veh->bIsVan) {
- m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_VAN_GET_OUT_REAR_RHS);
+ if (canJumpOut) {
+ m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_ROLLOUT_RHS);
+ } else if (veh->bIsVan) {
+ m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_VAN, ANIM_STD_VAN_GET_OUT_REAR_RHS);
} else if (isLow) {
m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_GETOUT_LO_RHS);
} else {
@@ -3987,21 +4481,22 @@ CPed::SetExitCar(CVehicle *veh, uint32 wantedDoorNode)
}
break;
case CAR_DOOR_LF:
- if (veh->bIsBus) {
- m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_COACH_GET_OUT_LHS);
+ if (canJumpOut) {
+ m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_ROLLOUT_LHS);
+ } else if (veh->bIsBus) {
+ m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_COACH, ANIM_STD_COACH_GET_OUT_LHS);
} else {
if (isLow)
m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_GETOUT_LO_LHS);
else
m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_GETOUT_LHS);
-
- if (addDoorSmoke)
- AddYardieDoorSmoke(veh, CAR_DOOR_LF);
}
break;
case CAR_DOOR_LR:
- if (veh->bIsVan) {
- m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_VAN_GET_OUT_REAR_LHS);
+ if (canJumpOut) {
+ m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_ROLLOUT_LHS);
+ } else if (veh->bIsVan) {
+ m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_VAN, ANIM_STD_VAN_GET_OUT_REAR_LHS);
} else if (isLow) {
m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_GETOUT_LO_LHS);
} else {
@@ -4011,32 +4506,10 @@ CPed::SetExitCar(CVehicle *veh, uint32 wantedDoorNode)
default:
break;
}
- if (!bBusJacked) {
- switch (m_vehDoor) {
- case CAR_DOOR_RF:
- veh->m_nGettingOutFlags |= CAR_DOOR_FLAG_RF;
- break;
- case CAR_DOOR_RR:
- veh->m_nGettingOutFlags |= CAR_DOOR_FLAG_RR;
- break;
- case CAR_DOOR_LF:
- veh->m_nGettingOutFlags |= CAR_DOOR_FLAG_LF;
- break;
- case CAR_DOOR_LR:
- veh->m_nGettingOutFlags |= CAR_DOOR_FLAG_LR;
- break;
- default:
- break;
- }
- }
- m_pVehicleAnim->SetFinishCallback(PedAnimStepOutCarCB, this);
- } else {
- if (m_vehDoor == CAR_DOOR_RF || m_vehDoor == CAR_DOOR_RR) {
- m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_CRAWLOUT_RHS);
- } else if (m_vehDoor == CAR_DOOR_LF || m_vehDoor == CAR_DOOR_LR) {
- m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_CRAWLOUT_LHS);
+ if (!bBusJacked && !canJumpOut) {
+ veh->m_nGettingOutFlags |= GetCarDoorFlag(m_vehDoor);
}
- m_pVehicleAnim->SetFinishCallback(PedSetOutCarCB, this);
+ m_pVehicleAnim->SetFinishCallback(canJumpOut ? RestoreHeadingRateCB : PedAnimStepOutCarCB, this);
}
}
bChangedSeat = false;
@@ -4056,78 +4529,198 @@ CPed::SetExitCar(CVehicle *veh, uint32 wantedDoorNode)
void
CPed::ExitCar(void)
{
- if (!m_pVehicleAnim)
+ if (!m_pVehicleAnim) {
+ if (InVehicle()) {
+ if (m_pMyVehicle->IsBike()) {
+ if (m_vehDoor == CAR_BOOT || m_vehDoor == CAR_BUMP_REAR) {
+ ((CBike*)m_pMyVehicle)->KnockOffRider(WEAPONTYPE_UNARMED, 0, this, false);
+ }
+ } else if (m_pMyVehicle->IsCar()) {
+ if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_ROLLOUT_LHS)) {
+ ((CAutomobile*)m_pMyVehicle)->KnockPedOutCar(WEAPONTYPE_UNIDENTIFIED, CAR_DOOR_LF, this);
+ } else if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_ROLLOUT_RHS)) {
+ ((CAutomobile*)m_pMyVehicle)->KnockPedOutCar(WEAPONTYPE_UNIDENTIFIED, CAR_DOOR_RF, this);
+ }
+ }
+ }
return;
+ }
AnimationId exitAnim = (AnimationId) m_pVehicleAnim->animId;
float animTime = m_pVehicleAnim->currentTime;
- m_pMyVehicle->ProcessOpenDoor(m_vehDoor, exitAnim, animTime);
+ if (exitAnim == ANIM_BIKE_GETOFF_BACK) {
+ if (animTime > 0.35f && m_pMyVehicle && m_pMyVehicle->IsBike())
+ ((CBike*)m_pMyVehicle)->KnockOffRider(WEAPONTYPE_UNARMED, 0, this, false);
+ else
+ LineUpPedWithCar(LINE_UP_TO_CAR_FALL);
- if (m_pSeekTarget) {
- // Car is upside down
- if (m_pMyVehicle->GetUp().z > -0.8f) {
- if (exitAnim == ANIM_STD_CAR_CLOSE_RHS || exitAnim == ANIM_STD_CAR_CLOSE_LHS || animTime > 0.3f)
- LineUpPedWithCar(LINE_UP_TO_CAR_END);
- else
- LineUpPedWithCar((m_pMyVehicle->GetModelIndex() == MI_DODO ? LINE_UP_TO_CAR_END : LINE_UP_TO_CAR_START));
+ } else if (exitAnim == ANIM_STD_ROLLOUT_LHS || exitAnim == ANIM_STD_ROLLOUT_RHS) {
+ if (animTime > 0.07f && m_pMyVehicle && m_pMyVehicle->IsCar()) {
+ if (exitAnim == ANIM_STD_ROLLOUT_LHS) {
+ ((CAutomobile*)m_pMyVehicle)->KnockPedOutCar(WEAPONTYPE_UNIDENTIFIED, CAR_DOOR_LF, this);
+ } else {
+ ((CAutomobile*)m_pMyVehicle)->KnockPedOutCar(WEAPONTYPE_UNIDENTIFIED, CAR_DOOR_RF, this);
+ }
} else {
- LineUpPedWithCar(LINE_UP_TO_CAR_END);
+ LineUpPedWithCar(LINE_UP_TO_CAR_FALL);
}
- }
+ } else {
+ m_pMyVehicle->ProcessOpenDoor(m_vehDoor, exitAnim, animTime);
- // If there is someone in front of the door, make him fall while we exit.
- if (m_nPedState == PED_EXIT_CAR) {
- CPed *foundPed = nil;
- for (int i = 0; i < m_numNearPeds; i++) {
- if ((m_nearPeds[i]->GetPosition() - GetPosition()).MagnitudeSqr2D() < 0.04f) {
- foundPed = m_nearPeds[i];
- break;
+ if (m_pSeekTarget) {
+ // Car is upside down
+ if (m_pMyVehicle->GetUp().z > -0.8f) {
+ if (exitAnim == ANIM_STD_CAR_CLOSE_RHS || exitAnim == ANIM_STD_CAR_CLOSE_LHS || animTime > 0.3f)
+ LineUpPedWithCar(LINE_UP_TO_CAR_END);
+ else
+ LineUpPedWithCar((m_pMyVehicle->GetModelIndex() == MI_DODO ? LINE_UP_TO_CAR_END : LINE_UP_TO_CAR_START));
+ }
+ else {
+ LineUpPedWithCar(LINE_UP_TO_CAR_END);
}
}
- if (foundPed && animTime > 0.4f && foundPed->IsPedInControl())
- foundPed->SetFall(1000, ANIM_STD_HIGHIMPACT_FRONT, 1);
+
+ // If there is someone in front of the door, make him fall while we exit.
+ if (m_nPedState == PED_EXIT_CAR) {
+ CPed* foundPed = nil;
+ for (int i = 0; i < m_numNearPeds; i++) {
+ if ((m_nearPeds[i]->GetPosition() - GetPosition()).MagnitudeSqr2D() < SQR(0.2f)) {
+ foundPed = m_nearPeds[i];
+ break;
+ }
+ }
+ if(foundPed && (!foundPed->IsPlayer() || m_nPedType == PEDTYPE_COP || m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT || m_objective == OBJECTIVE_KILL_CHAR_ANY_MEANS))
+ if (animTime > 0.4f && foundPed->IsPedInControl())
+ foundPed->SetFall(1000, ANIM_STD_HIGHIMPACT_FRONT, 1);
+ }
}
}
-// This function was mostly duplicate of GetLocalPositionToOpenCarDoor, so I've used it.
CVector
CPed::GetPositionToOpenCarDoor(CVehicle *veh, uint32 component)
{
- CVector localPos;
- CVector vehDoorPos;
+ CVector doorPos;
+ CVector vehDoorOffset;
+ CVehicleModelInfo* vehModel = veh->GetModelInfo();
- localPos = GetLocalPositionToOpenCarDoor(veh, component, 1.0f);
- vehDoorPos = Multiply3x3(veh->GetMatrix(), localPos) + veh->GetPosition();
+ if (veh->IsBike()) {
+ CBike* bike = (CBike*)veh;
-/*
- // Not used.
- CVector localVehDoorOffset;
+ if (component == CAR_WINDSCREEN) {
+ doorPos = vehModel->GetFrontSeatPosn();
+ return bike->GetMatrix() * (doorPos +
+ CVector(-vecPedBikeKickAnimOffset.x, vecPedBikeKickAnimOffset.y, -vecPedBikeKickAnimOffset.z));
+ } else {
+ switch (bike->m_bikeAnimType) {
+ case ASSOCGRP_BIKE_VESPA:
+ vehDoorOffset = vecPedVespaBikeJumpRhsAnimOffset;
+ break;
+ case ASSOCGRP_BIKE_HARLEY:
+ vehDoorOffset = vecPedHarleyBikeJumpRhsAnimOffset;
+ break;
+ case ASSOCGRP_BIKE_DIRT:
+ vehDoorOffset = vecPedDirtBikeJumpRhsAnimOffset;
+ break;
+ default:
+ vehDoorOffset = vecPedStdBikeJumpRhsAnimOffset;
+ break;
+ }
+ }
- if (veh->bIsVan && (component == VEHICLE_ENTER_REAR_LEFT || component == VEHICLE_ENTER_REAR_RIGHT)) {
- localVehDoorOffset = vecPedVanRearDoorAnimOffset;
+ doorPos = vehModel->GetFrontSeatPosn();
+ if (component == CAR_DOOR_LR || component == CAR_DOOR_RR) {
+ doorPos = vehModel->m_positions[CAR_POS_BACKSEAT];
+ }
+
+ if (component == CAR_DOOR_LR || component == CAR_DOOR_LF) {
+ vehDoorOffset.x *= -1.f;
+ }
+
+ CVector correctedPos;
+ bike->GetCorrectedWorldDoorPosition(correctedPos, vehDoorOffset, doorPos);
+ return correctedPos;
} else {
- if (veh->bIsLow) {
- localVehDoorOffset = vecPedCarDoorLoAnimOffset;
+ float seatOffset;
+ if (veh->bIsVan && (component == CAR_DOOR_LR || component == CAR_DOOR_RR)) {
+ seatOffset = 0.0f;
+ vehDoorOffset = vecPedVanRearDoorAnimOffset;
} else {
- localVehDoorOffset = vecPedCarDoorAnimOffset;
+ seatOffset = veh->pHandling->fSeatOffsetDistance;
+ if (veh->bLowVehicle) {
+ vehDoorOffset = vecPedCarDoorLoAnimOffset;
+ } else {
+ vehDoorOffset = vecPedCarDoorAnimOffset;
+ }
}
- }
- vehDoorPosWithoutOffset = Multiply3x3(veh->GetMatrix(), localPos + localVehDoorOffset) + veh->GetPosition();
-*/
- return vehDoorPos;
+ switch (component) {
+ case CAR_DOOR_RF:
+ doorPos = vehModel->GetFrontSeatPosn();
+ doorPos.x += seatOffset;
+ vehDoorOffset.x = -vehDoorOffset.x;
+ break;
+
+ case CAR_DOOR_RR:
+ doorPos = vehModel->m_positions[CAR_POS_BACKSEAT];
+ doorPos.x += seatOffset;
+ vehDoorOffset.x = -vehDoorOffset.x;
+ break;
+
+ case CAR_DOOR_LF:
+ doorPos = vehModel->GetFrontSeatPosn();
+ doorPos.x += seatOffset;
+ doorPos.x = -doorPos.x;
+ break;
+
+ case CAR_DOOR_LR:
+ doorPos = vehModel->m_positions[CAR_POS_BACKSEAT];
+ doorPos.x += seatOffset;
+ doorPos.x = -doorPos.x;
+ break;
+
+ default:
+ doorPos = vehModel->GetFrontSeatPosn();
+ vehDoorOffset = CVector(0.0f, 0.0f, 0.0f);
+ break;
+ }
+
+ CVector diffVec = doorPos - vehDoorOffset;
+ return Multiply3x3(veh->GetMatrix(), diffVec) + veh->GetPosition();
+
+ //unused
+ //doorPos = Multiply3x3(veh->GetMatrix(), doorPos) + veh->GetMatrix();
+ }
}
void
CPed::GetNearestDoor(CVehicle *veh, CVector &posToOpen)
{
CVector *enterOffset = nil;
- if (m_vehDoor == CAR_DOOR_LF && veh->pDriver
- || m_vehDoor == CAR_DOOR_RF && veh->pPassengers[0]
- || m_vehDoor == CAR_DOOR_LR && veh->pPassengers[1]
- || m_vehDoor == CAR_DOOR_RR && veh->pPassengers[2])
- {
+ if (veh->IsBike()) {
+ if (m_objective != OBJECTIVE_ENTER_CAR_AS_PASSENGER) {
+
+ // If bike didn't fall to ground
+ if (Abs(veh->GetRight().z) < 0.1f) {
+ float angleDiff = (GetPosition() - veh->GetPosition()).Heading() - veh->GetForward().Heading();
+
+ if (angleDiff > PI)
+ angleDiff -= TWOPI;
+ else if (angleDiff < -PI)
+ angleDiff += TWOPI;
+
+ if (Abs(angleDiff) < DEGTORAD(30.f)
+ && (IsPlayer() && ((CPlayerPed*)this)->m_fMoveSpeed > 1.5f && !m_vehDoor ||
+ !IsPlayer() && m_nPedType != PEDTYPE_COP && m_nMoveState == PEDMOVE_RUN
+ && m_pedStats->m_temper > 65
+ && !m_vehDoor || m_vehDoor == CAR_WINDSCREEN)) {
+ m_vehDoor = CAR_WINDSCREEN;
+ posToOpen = GetPositionToOpenCarDoor(veh, CAR_WINDSCREEN);
+ return;
+ }
+ }
+ }
+ } else if (m_vehDoor == CAR_DOOR_LF && veh->pDriver && !veh->bLowVehicle && !veh->bIsBus) {
enterOffset = &vecPedQuickDraggedOutCarAnimOffset;
}
@@ -4149,7 +4742,8 @@ CPed::GetNearestDoor(CVehicle *veh, CVector &posToOpen)
if (veh->IsRoomForPedToLeaveCar(CAR_DOOR_RF, enterOffset)) {
CPed *rfPassenger = veh->pPassengers[0];
- if (rfPassenger && (rfPassenger->m_leader == this || rfPassenger->bDontDragMeOutCar ||
+ if (rfPassenger && !veh->IsBike()
+ && (rfPassenger->m_leader == this || rfPassenger->bDontDragMeOutCar ||
veh->VehicleCreatedBy == MISSION_VEHICLE && m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER)
&& veh->IsRoomForPedToLeaveCar(CAR_DOOR_LF, enterOffset)
|| (veh->m_nGettingInFlags & CAR_DOOR_FLAG_RF) && veh->IsRoomForPedToLeaveCar(CAR_DOOR_LF, enterOffset)) {
@@ -4189,7 +4783,22 @@ CPed::GetNearestPassengerDoor(CVehicle *veh, CVector &posToOpen)
CVector2D lrPosDist(999.0f, 999.0f);
CVector2D rrPosDist(999.0f, 999.0f);
- if (!veh->pPassengers[0]
+ if (veh->IsBike()) {
+ if (!veh->pPassengers[0]
+ && !(veh->m_nGettingInFlags & CAR_DOOR_FLAG_LR)
+ && veh->IsRoomForPedToLeaveCar(CAR_DOOR_LR, nil)) {
+ lrPos = GetPositionToOpenCarDoor(veh, CAR_DOOR_LR);
+ canEnter = true;
+ lrPosDist = lrPos - GetPosition();
+ }
+ if (!veh->pPassengers[0]
+ && !(veh->m_nGettingInFlags & CAR_DOOR_FLAG_RR)
+ && veh->IsRoomForPedToLeaveCar(CAR_DOOR_RR, nil)) {
+ rrPos = GetPositionToOpenCarDoor(veh, CAR_DOOR_RR);
+ canEnter = true;
+ rrPosDist = rrPos - GetPosition();
+ }
+ } else if (!veh->pPassengers[0]
&& !(veh->m_nGettingInFlags & CAR_DOOR_FLAG_RF)
&& veh->IsRoomForPedToLeaveCar(CAR_DOOR_RF, nil)) {
@@ -4197,6 +4806,7 @@ CPed::GetNearestPassengerDoor(CVehicle *veh, CVector &posToOpen)
canEnter = true;
rfPosDist = rfPos - GetPosition();
}
+
if (vehModel->m_numDoors == 4) {
if (!veh->pPassengers[1]
&& !(veh->m_nGettingInFlags & CAR_DOOR_FLAG_LR)
@@ -4243,10 +4853,40 @@ CPed::GoToNearestDoor(CVehicle *veh)
SetMoveState(PEDMOVE_RUN);
}
+// Unused
+void CPed::PedSetGetInCarPositionCB(CAnimBlendAssociation* assoc, void* arg)
+{
+ CPed* pPed = (CPed*)arg;
+ CMatrix mat(pPed->GetMatrix());
+ CVehicle* pVehicle = pPed->m_pMyVehicle;
+ const CVector& offset = (pVehicle->bIsVan && (pPed->m_vehDoor == CAR_DOOR_RR || pPed->m_vehDoor == CAR_DOOR_LR)) ? vecPedVanRearDoorAnimOffset : vecPedCarDoorAnimOffset;
+ CVector position = Multiply3x3(mat, offset) + pPed->GetPosition();
+ CPedPlacement::FindZCoorForPed(&position);
+ pPed->SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ pPed->SetPosition(position);
+}
+
void
CPed::SetAnimOffsetForEnterOrExitVehicle(void)
{
- // FIX: If there were no translations on enter anims, there were overflows all over this function.
+ // FIX_BUGS: If there were no translations on enter anims, there were overflows all over this function.
+
+ int vanBlock = CAnimManager::GetAnimationBlockIndex("van");
+ int bikesBlock = CAnimManager::GetAnimationBlockIndex("bikes");
+ int bikevBlock = CAnimManager::GetAnimationBlockIndex("bikev");
+ int bikehBlock = CAnimManager::GetAnimationBlockIndex("bikeh");
+ int bikedBlock = CAnimManager::GetAnimationBlockIndex("biked");
+ CStreaming::RequestAnim(vanBlock, STREAMFLAGS_DEPENDENCY);
+ CStreaming::RequestAnim(bikesBlock, STREAMFLAGS_DEPENDENCY);
+ CStreaming::RequestAnim(bikevBlock, STREAMFLAGS_DEPENDENCY);
+ CStreaming::RequestAnim(bikehBlock, STREAMFLAGS_DEPENDENCY);
+ CStreaming::RequestAnim(bikedBlock, STREAMFLAGS_DEPENDENCY);
+ CStreaming::LoadAllRequestedModels(false);
+ CAnimManager::AddAnimBlockRef(vanBlock);
+ CAnimManager::AddAnimBlockRef(bikesBlock);
+ CAnimManager::AddAnimBlockRef(bikevBlock);
+ CAnimManager::AddAnimBlockRef(bikehBlock);
+ CAnimManager::AddAnimBlockRef(bikedBlock);
CAnimBlendHierarchy *enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, ANIM_STD_JACKEDCAR_LHS)->hierarchy;
CAnimBlendSequence *seq = enterAssoc->sequences;
@@ -4296,7 +4936,7 @@ CPed::SetAnimOffsetForEnterOrExitVehicle(void)
}
}
- enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, ANIM_STD_VAN_GET_IN_REAR_LHS)->hierarchy;
+ enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_VAN, ANIM_STD_VAN_GET_IN_REAR_LHS)->hierarchy;
seq = enterAssoc->sequences;
CAnimManager::UncompressAnimation(enterAssoc);
if (seq->numFrames > 0) {
@@ -4319,6 +4959,72 @@ CPed::SetAnimOffsetForEnterOrExitVehicle(void)
vecPedTrainDoorAnimOffset = lastFrame->translation;
}
}
+
+ enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_BIKE_STANDARD, ANIM_BIKE_JUMPON_LHS)->hierarchy;
+ seq = enterAssoc->sequences;
+ CAnimManager::UncompressAnimation(enterAssoc);
+ if (seq->numFrames > 0) {
+ if (!seq->HasTranslation())
+ vecPedStdBikeJumpRhsAnimOffset = CVector(0.0f, 0.0f, 0.0f);
+ else {
+ KeyFrameTrans* lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1);
+ vecPedStdBikeJumpRhsAnimOffset = lastFrame->translation;
+ }
+ }
+
+ enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_BIKE_VESPA, ANIM_BIKE_JUMPON_LHS)->hierarchy;
+ seq = enterAssoc->sequences;
+ CAnimManager::UncompressAnimation(enterAssoc);
+ if (seq->numFrames > 0) {
+ if (!seq->HasTranslation())
+ vecPedVespaBikeJumpRhsAnimOffset = CVector(0.0f, 0.0f, 0.0f);
+ else {
+ KeyFrameTrans* lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1);
+ vecPedVespaBikeJumpRhsAnimOffset = lastFrame->translation;
+ }
+ }
+
+ enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_BIKE_HARLEY, ANIM_BIKE_JUMPON_LHS)->hierarchy;
+ seq = enterAssoc->sequences;
+ CAnimManager::UncompressAnimation(enterAssoc);
+ if (seq->numFrames > 0) {
+ if (!seq->HasTranslation())
+ vecPedHarleyBikeJumpRhsAnimOffset = CVector(0.0f, 0.0f, 0.0f);
+ else {
+ KeyFrameTrans* lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1);
+ vecPedHarleyBikeJumpRhsAnimOffset = lastFrame->translation;
+ }
+ }
+
+ enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_BIKE_DIRT, ANIM_BIKE_JUMPON_LHS)->hierarchy;
+ seq = enterAssoc->sequences;
+ CAnimManager::UncompressAnimation(enterAssoc);
+ if (seq->numFrames > 0) {
+ if (!seq->HasTranslation())
+ vecPedDirtBikeJumpRhsAnimOffset = CVector(0.0f, 0.0f, 0.0f);
+ else {
+ KeyFrameTrans* lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1);
+ vecPedDirtBikeJumpRhsAnimOffset = lastFrame->translation;
+ }
+ }
+
+ enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_BIKE_HARLEY, ANIM_BIKE_KICK)->hierarchy;
+ seq = enterAssoc->sequences;
+ CAnimManager::UncompressAnimation(enterAssoc);
+ if (seq->numFrames > 0) {
+ if (!seq->HasTranslation())
+ vecPedBikeKickAnimOffset = CVector(0.0f, 0.0f, 0.0f);
+ else {
+ KeyFrameTrans* lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1);
+ vecPedBikeKickAnimOffset = lastFrame->translation;
+ }
+ }
+
+ CAnimManager::RemoveAnimBlockRef(vanBlock);
+ CAnimManager::RemoveAnimBlockRef(bikesBlock);
+ CAnimManager::RemoveAnimBlockRef(bikevBlock);
+ CAnimManager::RemoveAnimBlockRef(bikehBlock);
+ CAnimManager::RemoveAnimBlockRef(bikedBlock);
}
void
@@ -4387,21 +5093,14 @@ CPed::PedSetQuickDraggedOutCarPositionCB(CAnimBlendAssociation *animAssoc, void
&& ped->CharCreatedBy != MISSION_CHAR && veh->VehicleCreatedBy != MISSION_VEHICLE
&& veh->pDriver && veh->pDriver->IsPlayer()
&& !CTheScripts::IsPlayerOnAMission()) {
+ ped->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, veh);
-#ifndef VC_PED_PORTS
- if (CGeneral::GetRandomNumber() < MYRAND_MAX / 2) {
- ped->SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, veh->pDriver);
- } else
-#endif
- ped->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, veh);
-
-#ifdef VC_PED_PORTS
} else if (ped->m_pedStats->m_temper > ped->m_pedStats->m_fear
&& ped->CharCreatedBy != MISSION_CHAR && veh->VehicleCreatedBy != MISSION_VEHICLE
&& !veh->pDriver && FindPlayerPed()->m_carInObjective == veh
&& !CTheScripts::IsPlayerOnAMission()) {
ped->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, veh);
-#endif
+
} else {
ped->SetFindPathAndFlee(veh->GetPosition(), 10000);
if (CGeneral::GetRandomNumber() & 1 || ped->m_pedStats->m_fear > 70) {
@@ -4423,22 +5122,38 @@ CPed::PedSetDraggedOutCarPositionCB(CAnimBlendAssociation* animAssoc, void* arg)
ped->bUsesCollision = true;
ped->RestartNonPartialAnims();
- bool itsRearDoor = false;
+ CMatrix pedMat(ped->GetMatrix());
+ CVector draggedOutOffset;
+ if (ped->m_pMyVehicle && ped->m_pMyVehicle->IsBike()) {
+ AssocGroupId animGroup = ((CBike*)ped->m_pMyVehicle)->m_bikeAnimType;
+ switch (animGroup) {
+ case ASSOCGRP_BIKE_VESPA:
+ draggedOutOffset = vecPedVespaBikeJumpRhsAnimOffset;
+ break;
+ case ASSOCGRP_BIKE_HARLEY:
+ draggedOutOffset = vecPedHarleyBikeJumpRhsAnimOffset;
+ break;
+ case ASSOCGRP_BIKE_DIRT:
+ draggedOutOffset = vecPedDirtBikeJumpRhsAnimOffset;
+ break;
+ default:
+ draggedOutOffset = vecPedStdBikeJumpRhsAnimOffset;
+ break;
+ }
+ } else {
+ draggedOutOffset = CVector(vecPedDraggedOutCarAnimOffset.x, vecPedDraggedOutCarAnimOffset.y, 0.0f);
+ }
if (ped->m_vehDoor == CAR_DOOR_RF || ped->m_vehDoor == CAR_DOOR_RR)
- itsRearDoor = true;
+ draggedOutOffset.x = -draggedOutOffset.x;
- CMatrix pedMat(ped->GetMatrix());
- CVector posAfterBeingDragged = Multiply3x3(pedMat, (itsRearDoor ? -vecPedDraggedOutCarAnimOffset : vecPedDraggedOutCarAnimOffset));
+ CVector posAfterBeingDragged = Multiply3x3(pedMat, draggedOutOffset);
posAfterBeingDragged += ped->GetPosition();
-#ifndef VC_PED_PORTS
- posAfterBeingDragged.z += 1.0f;
-#endif
CPedPlacement::FindZCoorForPed(&posAfterBeingDragged);
ped->m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
ped->SetPosition(posAfterBeingDragged);
- if (ped->m_pMyVehicle && !ped->m_pMyVehicle->IsRoomForPedToLeaveCar(ped->m_vehDoor, &vecPedDraggedOutCarAnimOffset)) {
+ if (ped->m_pMyVehicle && !ped->m_pMyVehicle->IsBike() && !ped->m_pMyVehicle->IsRoomForPedToLeaveCar(ped->m_vehDoor, &draggedOutOffset)) {
ped->PositionPedOutOfCollision();
}
@@ -4482,27 +5197,16 @@ CPed::PedSetDraggedOutCarPositionCB(CAnimBlendAssociation* animAssoc, void* arg)
} else if (ped->m_pedStats->m_temper > ped->m_pedStats->m_fear && ped->CharCreatedBy != MISSION_CHAR
&& ped->m_pMyVehicle->VehicleCreatedBy != MISSION_VEHICLE && driver
&& driver->IsPlayer() && !CTheScripts::IsPlayerOnAMission()) {
+ ped->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, ped->m_pMyVehicle);
-#ifndef VC_PED_PORTS
- if (CGeneral::GetRandomNumber() & 1)
- ped->SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, driver);
- else
-#endif
- ped->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, ped->m_pMyVehicle);
-
- } else {
-#ifdef VC_PED_PORTS
- if (ped->m_pedStats->m_temper > ped->m_pedStats->m_fear && ped->CharCreatedBy != MISSION_CHAR
- && ped->m_pMyVehicle->VehicleCreatedBy != MISSION_VEHICLE && !driver
- && FindPlayerPed()->m_carInObjective == ped->m_pMyVehicle && !CTheScripts::IsPlayerOnAMission())
- ped->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, ped->m_pMyVehicle);
- else
-#endif
- {
- ped->SetPedState(PED_NONE);
- ped->m_nLastPedState = PED_NONE;
- ped->SetFindPathAndFlee(ped->m_pMyVehicle->GetPosition(), 10000);
- }
+ } else if (ped->m_pedStats->m_temper > ped->m_pedStats->m_fear && ped->CharCreatedBy != MISSION_CHAR
+ && ped->m_pMyVehicle->VehicleCreatedBy != MISSION_VEHICLE && !driver
+ && FindPlayerPed()->m_carInObjective == ped->m_pMyVehicle && !CTheScripts::IsPlayerOnAMission())
+ ped->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, ped->m_pMyVehicle);
+ else {
+ ped->SetPedState(PED_NONE);
+ ped->m_nLastPedState = PED_NONE;
+ ped->SetFindPathAndFlee(ped->m_pMyVehicle->GetPosition(), 10000);
}
ped->SetGetUp();
}
@@ -4598,6 +5302,7 @@ CPed::PedSetInTrainCB(CAnimBlendAssociation* animAssoc, void* arg)
veh->AddPassenger(ped);
}
+#ifdef GTA_TRAIN
void
CPed::SetEnterTrain(CVehicle *train, uint32 unused)
{
@@ -4728,29 +5433,33 @@ CPed::PedSetOutTrainCB(CAnimBlendAssociation *animAssoc, void *arg)
ped->SetHeading(ped->m_fRotationCur);
veh->RemovePassenger(ped);
}
+#endif
void
CPed::RegisterThreatWithGangPeds(CEntity *attacker)
{
CPed *attackerPed = nil;
+ if ((CharCreatedBy == MISSION_CHAR && bIsPlayerFriend && (attacker == FindPlayerPed() || attacker == FindPlayerVehicle()))
+ || (attacker && m_leader == attacker)
+ || (m_nPedType == PEDTYPE_GANG7 && attacker == FindPlayerPed()))
+ return;
+
if (attacker) {
if (m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT && m_objective != OBJECTIVE_KILL_CHAR_ANY_MEANS) {
if (attacker->IsPed()) {
attackerPed = (CPed*)attacker;
- } else {
- if (!attacker->IsVehicle())
- return;
-
+ } else if (attacker->IsVehicle()) {
attackerPed = ((CVehicle*)attacker)->pDriver;
if (!attackerPed)
return;
- }
+ } else
+ return;
if (attackerPed && (attackerPed->IsPlayer() || attackerPed->IsGangMember())) {
for (int i = 0; i < m_numNearPeds; ++i) {
CPed *nearPed = m_nearPeds[i];
if (nearPed->IsPointerValid()) {
- if (nearPed != this && nearPed->m_nPedType == m_nPedType)
+ if (nearPed->CharCreatedBy == RANDOM_CHAR && nearPed != this && nearPed->m_nPedType == m_nPedType)
nearPed->m_fearFlags |= CPedType::GetFlag(attackerPed->m_nPedType);
}
}
@@ -4759,10 +5468,10 @@ CPed::RegisterThreatWithGangPeds(CEntity *attacker)
}
if (attackerPed && attackerPed->IsPlayer() && (attackerPed->m_nPedState == PED_CARJACK || attackerPed->bInVehicle)) {
- if (!attackerPed->m_pMyVehicle || attackerPed->m_pMyVehicle->GetModelIndex() != MI_TOYZ) {
+ if (!attackerPed->m_pMyVehicle || attackerPed->m_pMyVehicle->GetModelIndex() != MI_TOPFUN) {
int16 lastVehicle;
CEntity *vehicles[8];
- CWorld::FindObjectsInRange(GetPosition(), ENTER_CAR_MAX_DIST, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
+ CWorld::FindObjectsInRange(GetPosition(), 30.0f, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
if (lastVehicle > 8)
lastVehicle = 8;
@@ -4773,7 +5482,7 @@ CPed::RegisterThreatWithGangPeds(CEntity *attacker)
if (nearVeh->VehicleCreatedBy != MISSION_VEHICLE) {
CPed *nearVehDriver = nearVeh->pDriver;
- if (nearVehDriver && nearVehDriver != this && nearVehDriver->m_nPedType == m_nPedType) {
+ if (nearVehDriver && nearVehDriver != this && nearVehDriver->m_nPedType == m_nPedType && nearVehDriver->CharCreatedBy == RANDOM_CHAR) {
if (nearVeh->IsVehicleNormal() && nearVeh->IsCar()) {
nearVeh->AutoPilot.m_nCruiseSpeed = GAME_SPEED_TO_CARAI_SPEED * nearVeh->pHandling->Transmission.fMaxCruiseVelocity * 0.8f;
@@ -4803,12 +5512,12 @@ SelectClosestNodeForSeek(CPed *ped, CPathNode *node, CVector2D closeDist, CVecto
if (farDist.MagnitudeSqr() > dist) {
- if (closeDist.MagnitudeSqr() <= dist) {
- ped->m_pNextPathNode = closeNode;
- closeDist = posDiff;
- } else {
+ if (closeDist.MagnitudeSqr() > dist) {
ped->m_pNextPathNode = (closeNode2 ? closeNode2 : testNode);
farDist = posDiff;
+ } else {
+ ped->m_pNextPathNode = closeNode;
+ closeDist = posDiff;
}
}
@@ -4824,7 +5533,7 @@ CPed::FindBestCoordsFromNodes(CVector unused, CVector *bestCoords)
if (m_pNextPathNode || !bUsePedNodeSeek)
return false;
- CVector ourPos = GetPosition();
+ const CVector &ourPos = GetPosition();
int closestNodeId = ThePaths.FindNodeClosestToCoors(GetPosition(), 1, 999999.9f);
@@ -4843,12 +5552,13 @@ CPed::FindBestCoordsFromNodes(CVector unused, CVector *bestCoords)
SelectClosestNodeForSeek(this, closestNode, closeDist, seekPosDist, closestNode, nil);
- // Above function decided that going to the next node is more logical than seeking the object.
if (m_pNextPathNode) {
- CVector pathToNextNode = m_pNextPathNode->GetPosition() - ourPos;
- if (pathToNextNode.MagnitudeSqr2D() < seekPosDist.MagnitudeSqr()) {
- *bestCoords = m_pNextPathNode->GetPosition();
+ // Function above decided that directly going to next node makes more sense then seeking the object.
+ CVector correctedCoords = CPathFind::TakeWidthIntoAccountForWandering(m_pNextPathNode, m_randomSeed);
+
+ if ((correctedCoords - ourPos).MagnitudeSqr2D() < seekPosDist.MagnitudeSqr()) {
+ *bestCoords = CPathFind::TakeWidthIntoAccountForWandering(m_pNextPathNode, m_randomSeed);
return true;
}
m_pNextPathNode = nil;
@@ -4874,9 +5584,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);
@@ -4885,25 +5597,70 @@ CPed::DuckAndCover(void)
}
return false;
}
+
+ int16 lastVehicle = 0;
+ CEntity* vehicles[8];
bool justDucked = false;
CVehicle *foundVeh = nil;
float maxDist = 225.0f;
- bIsDucking = false;
+ if (bIsDucking)
+ ClearDuck(true);
+
bCrouchWhenShooting = false;
+ bool duckingWithoutVeh = false;
if (CTimer::GetTimeInMilliseconds() > m_leaveCarTimer) {
- CVector pos = GetPosition();
- int16 lastVehicle;
- CEntity *vehicles[8];
- CWorld::FindObjectsInRange(pos, CHECK_NEARBY_THINGS_MAX_DIST, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
+
+ for(int i = 0; i < 6; i++) {
+ CPlayerPed *player = (CPlayerPed*)m_pedInObjective;
+
+ if (player->m_pPedAtSafePos[i] == this) {
+ duckingWithoutVeh = true;
+ CVector &safePos = player->m_vecSafePos[i];
+ bool notRunningToSafePos = false;
+
+ if (m_vecSeekPos.x != safePos.x && m_vecSeekPos.y != safePos.y && m_vecSeekPos.z != safePos.z)
+ notRunningToSafePos = true;
+
+ if (!notRunningToSafePos) {
+ CVector target = player->m_vecSafePos[i];
+ SetSeek(target, 1.0f);
+ duckingWithoutVeh = true;
+ m_attackTimer = CTimer::GetTimeInMilliseconds() + 6000;
+ bDuckAndCover = true;
+ }
+ break;
+ }
+ }
+ if (!duckingWithoutVeh) {
+ for (int i = 0; i < 6; i++) {
+ CPlayerPed* player = (CPlayerPed*)m_pedInObjective;
+ if (!player->m_pPedAtSafePos[i] && player->m_vecSafePos[i].x != 0.0f) {
+ player->m_pPedAtSafePos[i] = this;
+ CVector target = player->m_vecSafePos[i];
+ SetSeek(target, 1.0f);
+ m_headingRate = 15.0f;
+ ClearPointGunAt();
+ duckingWithoutVeh = 1;
+ bIsRunning = true;
+ bDuckAndCover = true;
+ justDucked = true;
+ m_leaveCarTimer = CTimer::GetTimeInMilliseconds() + 500;
+ break;
+ }
+ }
+ }
+ if (!duckingWithoutVeh) {
+ CVector pos = GetPosition();
+ CWorld::FindObjectsInRange(pos, CHECK_NEARBY_THINGS_MAX_DIST, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
+ }
for (int i = 0; i < lastVehicle; i++) {
CVehicle *veh = (CVehicle*) vehicles[i];
- if (veh->m_vecMoveSpeed.Magnitude() <= 0.02f
- && !veh->bIsBus
- && !veh->bIsVan
- && !veh->bIsBig
+ if (veh->IsCar() && veh->m_vecMoveSpeed.Magnitude() <= 0.02f
+ && !veh->bIsBus && !veh->bIsVan && !veh->bIsBig
&& veh->m_numPedsUseItAsCover < 3) {
+
float dist = (GetPosition() - veh->GetPosition()).MagnitudeSqr();
if (dist < maxDist) {
maxDist = dist;
@@ -4944,25 +5701,25 @@ CPed::DuckAndCover(void)
else
duckPos = duckAtRightSide;
- if (CWorld::TestSphereAgainstWorld(duckPos, 0.5f, nil, true, true, true, false, false, false)
- && CWorld::GetIsLineOfSightClear(GetPosition(), duckPos, 1, 0, 0, 1, 0, 0, 0)) {
+ if (CWorld::TestSphereAgainstWorld(duckPos, 0.5f, nil, true, true, true, false, false, false)) {
SetSeek(duckPos, 1.0f);
m_headingRate = 15.0f;
bIsRunning = true;
bDuckAndCover = true;
justDucked = true;
m_leaveCarTimer = CTimer::GetTimeInMilliseconds() + 500;
- if (foundVeh->bIsLawEnforcer)
+ if (foundVeh->bIsLawEnforcer) {
m_carInObjective = foundVeh;
-
- // BUG? Shouldn't we register the reference?
+ m_carInObjective->RegisterReference((CEntity**)&m_carInObjective);
+ }
m_pSeekTarget = foundVeh;
+ m_pSeekTarget->RegisterReference((CEntity**)&m_pSeekTarget);
ClearPointGunAt();
} else {
m_duckAndCoverTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(10000, 15000);
bDuckAndCover = false;
}
- } else {
+ } else if (!duckingWithoutVeh) {
bDuckAndCover = false;
}
}
@@ -4970,8 +5727,13 @@ CPed::DuckAndCover(void)
if (!justDucked && !bDuckAndCover)
return false;
- if (!Seek())
- return true;
+ if (!Seek()) {
+ if (m_nMoveState == PEDMOVE_STILL) {
+ bDuckAndCover = false;
+ return false;
+ } else
+ return true;
+ }
bKindaStayInSamePlace = true;
bDuckAndCover = false;
@@ -4988,6 +5750,8 @@ CPed::DuckAndCover(void)
}
m_leaveCarTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(3000, 6000);
+ bCrouchWhenShooting = true;
+ SetDuck(CGeneral::GetRandomNumberInRange(2000, 5000), true);
return false;
}
@@ -4997,6 +5761,47 @@ CPed::GetPositionToOpenCarDoor(CVehicle *veh, uint32 component, float offset)
CVector doorPos;
CMatrix vehMat(veh->GetMatrix());
+ if (veh->IsBike()) {
+ CVehicleModelInfo* vehModel = (CVehicleModelInfo*)CModelInfo::GetModelInfo(veh->GetModelIndex());
+ CVector vehDoorOffset;
+ CBike* bike = (CBike*)veh;
+ doorPos = vehModel->GetFrontSeatPosn();
+
+ if (component == CAR_WINDSCREEN) {
+#ifdef FIX_BUGS
+ return bike->GetMatrix() * (doorPos +
+ CVector(-vecPedBikeKickAnimOffset.x, vecPedBikeKickAnimOffset.y, -vecPedBikeKickAnimOffset.z));
+#else
+ return bike->GetMatrix() * (doorPos + vecPedBikeKickAnimOffset);
+#endif
+ } else {
+ switch (bike->m_bikeAnimType) {
+ case ASSOCGRP_BIKE_VESPA:
+ vehDoorOffset = vecPedVespaBikeJumpRhsAnimOffset;
+ break;
+ case ASSOCGRP_BIKE_HARLEY:
+ vehDoorOffset = vecPedHarleyBikeJumpRhsAnimOffset;
+ break;
+ case ASSOCGRP_BIKE_DIRT:
+ vehDoorOffset = vecPedDirtBikeJumpRhsAnimOffset;
+ break;
+ default:
+ vehDoorOffset = vecPedStdBikeJumpRhsAnimOffset;
+ break;
+ }
+ vehDoorOffset.x += offset * bike->pHandling->fSeatOffsetDistance;
+ if (component == CAR_DOOR_LR || component == CAR_DOOR_RR) {
+ doorPos = vehModel->m_positions[CAR_POS_BACKSEAT];
+ }
+
+ if (component == CAR_DOOR_LR || component == CAR_DOOR_LF)
+ vehDoorOffset.x *= -1.f;
+
+ CVector correctedPos;
+ bike->GetCorrectedWorldDoorPosition(correctedPos, vehDoorOffset, doorPos);
+ return correctedPos;
+ }
+ }
doorPos = Multiply3x3(vehMat, GetLocalPositionToOpenCarDoor(veh, component, offset));
return veh->GetPosition() + doorPos;
@@ -5011,61 +5816,98 @@ CPed::GetLocalPositionToOpenCarDoor(CVehicle *veh, uint32 component, float seatP
float seatOffset;
vehModel = (CVehicleModelInfo *)CModelInfo::GetModelInfo(veh->GetModelIndex());
- if (veh->bIsVan && (component == CAR_DOOR_LR || component == CAR_DOOR_RR)) {
- seatOffset = 0.0f;
- vehDoorOffset = vecPedVanRearDoorAnimOffset;
+
+ if (veh->IsBike()) {
+ CBike *bike = (CBike*)veh;
+ vehDoorPos = vehModel->GetFrontSeatPosn();
+
+ if (component == CAR_WINDSCREEN) {
+ return bike->GetMatrix() * (vehDoorPos + vecPedBikeKickAnimOffset);
+ } else {
+ switch (bike->m_bikeAnimType) {
+ case ASSOCGRP_BIKE_VESPA:
+ vehDoorOffset = vecPedVespaBikeJumpRhsAnimOffset;
+ break;
+ case ASSOCGRP_BIKE_HARLEY:
+ vehDoorOffset = vecPedHarleyBikeJumpRhsAnimOffset;
+ break;
+ case ASSOCGRP_BIKE_DIRT:
+ vehDoorOffset = vecPedDirtBikeJumpRhsAnimOffset;
+ break;
+ default:
+ vehDoorOffset = vecPedStdBikeJumpRhsAnimOffset;
+ break;
+ }
+ float xOffsetFromAnim = vehDoorOffset.x + seatPosMult * bike->pHandling->fSeatOffsetDistance;
+ if (component == CAR_DOOR_LR || component == CAR_DOOR_RR) {
+ vehDoorPos = vehModel->m_positions[CAR_POS_BACKSEAT];
+ }
+
+ if (component == CAR_DOOR_LR || component == CAR_DOOR_LF)
+ xOffsetFromAnim *= -1.f;
+
+ return bike->GetMatrix() * (vehDoorPos + CVector(xOffsetFromAnim, vehDoorOffset.y, vehDoorOffset.z));
+ }
} else {
- seatOffset = veh->pHandling->fSeatOffsetDistance * seatPosMult;
- if (veh->bLowVehicle) {
- vehDoorOffset = vecPedCarDoorLoAnimOffset;
+ if (veh->bIsVan && (component == CAR_DOOR_LR || component == CAR_DOOR_RR)) {
+ seatOffset = 0.0f;
+ vehDoorOffset = vecPedVanRearDoorAnimOffset;
} else {
- vehDoorOffset = vecPedCarDoorAnimOffset;
+ seatOffset = veh->pHandling->fSeatOffsetDistance * seatPosMult;
+ if (veh->bLowVehicle) {
+ vehDoorOffset = vecPedCarDoorLoAnimOffset;
+ } else {
+ vehDoorOffset = vecPedCarDoorAnimOffset;
+ }
}
- }
- switch (component) {
- case CAR_DOOR_RF:
- vehDoorPos = vehModel->GetFrontSeatPosn();
- vehDoorPos.x += seatOffset;
- vehDoorOffset.x = -vehDoorOffset.x;
- break;
+ switch (component) {
+ case CAR_DOOR_RF:
+ vehDoorPos = vehModel->GetFrontSeatPosn();
+ vehDoorPos.x += seatOffset;
+ vehDoorOffset.x = -vehDoorOffset.x;
+ break;
- case CAR_DOOR_RR:
- vehDoorPos = vehModel->m_positions[CAR_POS_BACKSEAT];
- vehDoorPos.x += seatOffset;
- vehDoorOffset.x = -vehDoorOffset.x;
- break;
+ case CAR_DOOR_RR:
+ vehDoorPos = vehModel->m_positions[CAR_POS_BACKSEAT];
+ vehDoorPos.x += seatOffset;
+ vehDoorOffset.x = -vehDoorOffset.x;
+ break;
- case CAR_DOOR_LF:
- vehDoorPos = vehModel->GetFrontSeatPosn();
- vehDoorPos.x = -(vehDoorPos.x + seatOffset);
- break;
+ case CAR_DOOR_LF:
+ vehDoorPos = vehModel->GetFrontSeatPosn();
+ vehDoorPos.x = -(vehDoorPos.x + seatOffset);
+ break;
- case CAR_DOOR_LR:
- vehDoorPos = vehModel->m_positions[CAR_POS_BACKSEAT];
- vehDoorPos.x = -(vehDoorPos.x + seatOffset);
- break;
+ case CAR_DOOR_LR:
+ vehDoorPos = vehModel->m_positions[CAR_POS_BACKSEAT];
+ vehDoorPos.x = -(vehDoorPos.x + seatOffset);
+ break;
- default:
- vehDoorPos = vehModel->GetFrontSeatPosn();
- vehDoorOffset = CVector(0.0f, 0.0f, 0.0f);
+ default:
+ vehDoorPos = vehModel->GetFrontSeatPosn();
+ vehDoorOffset = CVector(0.0f, 0.0f, 0.0f);
+ }
+ return vehDoorPos - vehDoorOffset;
}
- return vehDoorPos - vehDoorOffset;
}
+// TODO: what is this parameter for?
void
-CPed::SetDuck(uint32 time)
+CPed::SetDuck(uint32 time, bool sth)
{
- if (bIsDucking || CTimer::GetTimeInMilliseconds() <= m_duckTimer)
+ if (bIsDucking || CTimer::GetTimeInMilliseconds() <= m_duckTimer && !sth) {
+ if (sth && CTimer::GetTimeInMilliseconds() + time > m_duckTimer)
+ m_duckTimer = CTimer::GetTimeInMilliseconds() + time;
return;
+ }
- if (bCrouchWhenShooting && (m_nPedState == PED_ATTACK || m_nPedState == PED_AIM_GUN)) {
- CAnimBlendAssociation *duckAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_DUCK_LOW);
- if (!duckAssoc || duckAssoc->blendDelta < 0.0f) {
- CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_DUCK_LOW, 4.0f);
- bIsDucking = true;
- m_duckTimer = CTimer::GetTimeInMilliseconds() + time;
- }
+ CAnimBlendAssociation *duckAssoc;
+ if (bCrouchWhenShooting) {
+ duckAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_DUCK_WEAPON, 4.0f);
+ duckAssoc->flags &= ~ASSOC_FADEOUTWHENDONE;
+ bIsDucking = true;
+ m_duckTimer = CTimer::GetTimeInMilliseconds() + time;
} else {
CAnimBlendAssociation *duckAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_DUCK_DOWN);
if (!duckAssoc || duckAssoc->blendDelta < 0.0f) {
@@ -5081,30 +5923,46 @@ CPed::Duck(void)
{
if (CTimer::GetTimeInMilliseconds() > m_duckTimer)
ClearDuck();
+ else if (bIsDucking && bCrouchWhenShooting) {
+ CWeaponInfo *weapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
+ CAnimBlendAssociation *crouchAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_DUCK_WEAPON);
+ if (!crouchAnim) {
+ if(GetCrouchFireAnim(weapon))
+ crouchAnim = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchFireAnim(weapon));
+ }
+ if (!crouchAnim) {
+ if(GetCrouchReloadAnim(weapon))
+ crouchAnim = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchReloadAnim(weapon));
+ }
+ if (!crouchAnim) {
+ bIsDucking = false;
+#if defined FIX_BUGS || defined FREE_CAM
+ if (IsPlayer())
+ bCrouchWhenShooting = false;
+#endif
+ }
+ }
}
void
-CPed::ClearDuck(void)
+CPed::ClearDuck(bool clearTimer)
{
CAnimBlendAssociation *animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_DUCK_DOWN);
if (!animAssoc) {
animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_DUCK_LOW);
-
- if (!animAssoc) {
- bIsDucking = false;
- return;
- }
+ }
+ if (!animAssoc) {
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_DUCK_WEAPON);
}
- if (!bCrouchWhenShooting)
- return;
-
- 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_STD_RBLOCK_SHOOT);
- if (!animAssoc || animAssoc->blendDelta < 0.0f) {
- CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_RBLOCK_SHOOT, 4.0f);
+ if (clearTimer) {
+ m_duckTimer = 0;
}
}
@@ -5134,8 +5992,7 @@ CPed::InformMyGangOfAttack(CEntity *attacker)
CPed *nearPed = m_nearPeds[i];
if (nearPed && nearPed != this) {
CPed *leader = nearPed->m_leader;
- if (leader && leader == this && nearPed->m_pedStats->m_fear < nearPed->m_pedStats->m_temper)
- {
+ if (leader && leader == this && nearPed->m_pedStats->m_fear < nearPed->m_pedStats->m_temper) {
nearPed->SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, attackerPed);
nearPed->SetObjectiveTimer(30000);
}
@@ -5168,11 +6025,7 @@ CPed::PedAnimDoorCloseRollingCB(CAnimBlendAssociation* animAssoc, void* arg)
void
CPed::SetSeekBoatPosition(CVehicle *boat)
{
- if (m_nPedState == PED_SEEK_IN_BOAT || boat->pDriver
-#if defined VC_PED_PORTS || defined FIX_BUGS
- || !IsPedInControl()
-#endif
- )
+ if (m_nPedState == PED_SEEK_IN_BOAT || boat->pDriver || !IsPedInControl())
return;
SetStoredState();
@@ -5212,7 +6065,9 @@ CPed::IsRoomToBeCarJacked(void)
return false;
CVector offset;
- if (m_pMyVehicle->bLowVehicle || m_nPedType == PEDTYPE_COP) {
+ if (m_pMyVehicle->IsBike()) {
+ offset = vecPedStdBikeJumpRhsAnimOffset;
+ } else if (m_pMyVehicle->bLowVehicle || m_nPedType == PEDTYPE_COP) {
offset = vecPedDraggedOutCarAnimOffset;
} else {
offset = vecPedQuickDraggedOutCarAnimOffset;
@@ -5227,55 +6082,220 @@ CPed::IsRoomToBeCarJacked(void)
}
void
-CPed::RemoveInCarAnims(void)
+CPed::AddInCarAnims(CVehicle* car, bool isDriver)
{
- if (!IsPlayer())
- return;
+ if (car->IsBoat()) {
+ if (car->pHandling->Flags & HANDLING_SIT_IN_BOAT) {
+ m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_SIT, 100.0f);
+ } else {
+ m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_BOAT_DRIVE, 100.0f);
+ }
+ } else if (car->IsBike()) {
+ if (isDriver) {
+ m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ((CBike*)car)->m_bikeAnimType, ANIM_BIKE_RIDE, 100.0f);
+ } else {
+ m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ((CBike*)car)->m_bikeAnimType, ANIM_BIKE_RIDE_P, 100.0f);
+ }
+ } else {
+ if (isDriver) {
+ if (car->bLowVehicle) {
+ m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_SIT_LO, 100.0f);
+ } else {
+ m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_SIT, 100.0f);
+ }
+ } else {
+ if (car->bLowVehicle) {
+ m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_SIT_P_LO, 100.0f);
+ } else {
+ m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_SIT_P, 100.0f);
+ }
+ }
+ }
+
+ StopNonPartialAnims();
+}
+void
+CPed::RemoveDrivebyAnims()
+{
CAnimBlendAssociation *animAssoc;
- if (m_pMyVehicle && m_pMyVehicle->bLowVehicle) {
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_DRIVE_LEFT_LO);
- if (animAssoc)
- animAssoc->blendDelta = -1000.0f;
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_DRIVE_RIGHT_LO);
- if (animAssoc)
- animAssoc->blendDelta = -1000.0f;
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_DRIVEBY_LEFT);
- if (animAssoc)
- animAssoc->blendDelta = -1000.0f;
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_DRIVEBY_RIGHT);
- if (animAssoc)
- animAssoc->blendDelta = -1000.0f;
- } else {
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_DRIVE_LEFT);
- if (animAssoc)
- animAssoc->blendDelta = -1000.0f;
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_DRIVE_RIGHT);
- if (animAssoc)
- animAssoc->blendDelta = -1000.0f;
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_DRIVEBY_LEFT);
- if (animAssoc)
- animAssoc->blendDelta = -1000.0f;
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_DRIVEBY_RIGHT);
- if (animAssoc)
- animAssoc->blendDelta = -1000.0f;
- }
-
-#ifdef VC_PED_PORTS
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_BOAT_DRIVE);
+ AnimationId LeftAnim = ANIM_STD_CAR_DRIVEBY_LEFT;
+ AnimationId RightAnim = ANIM_STD_CAR_DRIVEBY_RIGHT;
+
+ if (m_pMyVehicle->pHandling->Flags & HANDLING_IS_BIKE) {
+ LeftAnim = ANIM_BIKE_DRIVEBY_RHS;
+ RightAnim = ANIM_BIKE_DRIVEBY_LHS;
+ } else if (m_pMyVehicle->bLowVehicle) {
+ LeftAnim = ANIM_STD_CAR_DRIVEBY_LEFT_LO;
+ RightAnim = ANIM_STD_CAR_DRIVEBY_RIGHT_LO;
+ }
+
+ animAssoc = RpAnimBlendClumpGetAssociation((RpClump*)m_rwObject, ANIM_BIKE_DRIVEBY_RHS);
if (animAssoc)
animAssoc->blendDelta = -1000.0f;
-#endif
-
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_LOOKBEHIND);
+ animAssoc = RpAnimBlendClumpGetAssociation((RpClump*)m_rwObject, ANIM_BIKE_DRIVEBY_LHS);
+ if (animAssoc)
+ animAssoc->blendDelta = -1000.0f;
+ animAssoc = RpAnimBlendClumpGetAssociation((RpClump*)m_rwObject, ANIM_BIKE_DRIVEBY_FORWARD);
if (animAssoc)
animAssoc->blendDelta = -1000.0f;
}
+void
+CPed::RemoveInCarAnims(void)
+{
+ CAnimBlendAssociation* assoc;
+
+ for (assoc = RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_DRIVING); assoc;
+ assoc = RpAnimBlendGetNextAssociation(assoc, ASSOC_DRIVING)) {
+ assoc->flags |= ASSOC_DELETEFADEDOUT;
+ assoc->blendDelta = -1000.0f;
+ }
+}
+
bool
CPed::PositionPedOutOfCollision(void)
{
+ CVehicle *veh = m_pMyVehicle;
+ if (!veh)
+ return false;
+
+ if (bDonePositionOutOfCollision)
+ return true;
+
+ bool foundAPos = false;
+ CColModel *vehCol = veh->GetColModel();
+ CVector vehPos = veh->GetPosition();
+ CVector ourPos = GetPosition();
+ CVector newPos = ourPos;
+ CWorld::pIgnoreEntity = veh;
+ bUsesCollision = false;
+ bJustCheckCollision = true;
+ m_vecMoveSpeed = CVector(0.f, 0.f, 0.f);
+ if (veh->IsOnItsSide()) {
+ // Top of the veh.
+ newPos = vehPos;
+ newPos.z = FEET_OFFSET + vehCol->boundingBox.max.x + vehPos.z;
+ GetMatrix().SetTranslate(newPos);
+ if (!CheckCollision()) {
+ if (CWorld::GetIsLineOfSightClear(vehPos, newPos, true, false, false, true, false, false, false))
+ foundAPos = true;
+ }
+
+ } else if (m_vehDoor != 0) {
+ // Try the normal way
+ CVector pos = GetPositionToOpenCarDoor(m_pMyVehicle, m_vehDoor);
+ newPos = pos;
+ GetMatrix().SetTranslate(newPos);
+ if (!CheckCollision()) {
+ if (CWorld::GetIsLineOfSightClear(vehPos, newPos, true, false, false, true, false, false, false))
+ foundAPos = true;
+ }
+ }
+
+ float vehRelativeExitX = vehCol->boundingBox.min.x - 0.355f;
+ if (m_vehDoor == CAR_DOOR_RF || m_vehDoor == CAR_DOOR_RR)
+ vehRelativeExitX = 0.355f + vehCol->boundingBox.max.x;
+
+ if (!foundAPos) {
+ // Check sides of veh., respective to seat column-veh. center difference(why?)
+ float exitOffset = vehRelativeExitX - DotProduct(ourPos - vehPos, veh->GetRight());
+ newPos = exitOffset * veh->GetRight() + ourPos;
+ GetMatrix().SetTranslate(newPos);
+ if (!CheckCollision()) {
+ if (CWorld::GetIsLineOfSightClear(vehPos, newPos, true, false, false, true, false, false, false))
+ foundAPos = true;
+ }
+ }
+ if (!foundAPos) {
+ // Iterate through sections of veh. length + static offset on X
+ float minY = vehCol->boundingBox.min.y;
+ float ySection = (vehCol->boundingBox.max.y - minY) / 3.f;
+ for (int i = 0; i < 4; i++) {
+ float fwdMult = i * ySection + minY;
+ newPos = vehRelativeExitX * veh->GetRight() + fwdMult * veh->GetForward() + vehPos;
+ GetMatrix().SetTranslate(newPos);
+ if (!CheckCollision()) {
+ if (CWorld::GetIsLineOfSightClear(vehPos, newPos, true, false, false, true, false, false, false)) {
+ foundAPos = true;
+ break;
+ }
+ }
+ }
+ }
+ if (!foundAPos) {
+ // Back of veh.
+ newPos = (vehCol->boundingBox.min.y - 0.355f) * veh->GetForward() + vehPos;
+ GetMatrix().SetTranslate(newPos);
+ if (!CheckCollision()) {
+ if (CWorld::GetIsLineOfSightClear(vehPos, newPos, true, false, false, true, false, false, false))
+ foundAPos = true;
+ }
+ }
+ if (!foundAPos) {
+ // Front of veh.
+ newPos = (0.355f + vehCol->boundingBox.max.y) * veh->GetForward() + vehPos;
+ GetMatrix().SetTranslate(newPos);
+ if (!CheckCollision()) {
+ if (CWorld::GetIsLineOfSightClear(vehPos, newPos, true, false, false, true, false, false, false))
+ foundAPos = true;
+ }
+ }
+ if (!foundAPos) {
+ // Opposite X side + back
+ newPos = vehCol->boundingBox.min.y * veh->GetForward() + vehPos - vehRelativeExitX * veh->GetRight();
+ GetMatrix().SetTranslate(newPos);
+ if (!CheckCollision()) {
+ if (CWorld::GetIsLineOfSightClear(vehPos, newPos, true, false, false, true, false, false, false))
+ foundAPos = true;
+ }
+ }
+ if (!foundAPos) {
+ // Opposite X side + front
+ newPos = vehCol->boundingBox.max.y * veh->GetForward() + vehPos - vehRelativeExitX * veh->GetRight();
+ GetMatrix().SetTranslate(newPos);
+ if (!CheckCollision()) {
+ if (CWorld::GetIsLineOfSightClear(vehPos, newPos, true, false, false, true, false, false, false))
+ foundAPos = true;
+ }
+ }
+ if (!foundAPos) {
+ // Top of veh.
+ if (veh->m_vehType == 0) {
+ newPos = vehCol->boundingBox.max.z * veh->GetUp() + vehPos;
+ newPos.z += FEET_OFFSET;
+ GetMatrix().SetTranslate(newPos);
+ if (!CheckCollision()) {
+ if (CWorld::GetIsLineOfSightClear(vehPos, newPos, true, false, false, true, false, false, false))
+ foundAPos = true;
+ }
+ }
+ }
+ m_vecMoveSpeed = CVector(0.f, 0.f, 0.f);
+ m_vecTurnSpeed = CVector(0.f, 0.f, 0.f);
+ veh->m_vecMoveSpeed = CVector(0.f, 0.f, 0.f);
+ veh->m_vecTurnSpeed = CVector(0.f, 0.f, 0.f);
+ CWorld::pIgnoreEntity = nil;
+ bUsesCollision = true;
+ bJustCheckCollision = false;
+ bDonePositionOutOfCollision = true;
+ if (foundAPos)
+ return true;
+ int foundNode = ThePaths.FindNodeClosestToCoors(vehPos, PATH_PED, 999999.9f, true, false, false, false);
+ if (foundNode < 0)
+ return false;
+ newPos = ThePaths.m_pathNodes[foundNode].GetPosition();
+ CPedPlacement::FindZCoorForPed(&newPos);
+ GetMatrix().SetTranslate(newPos);
+ SetHeading(m_pMyVehicle->GetForward().Heading());
+ return true;
+}
+
+// "Any" means he shouldn't have to be in vehicle.
+bool
+CPed::PositionAnyPedOutOfCollision(void)
+{
CVehicle *veh;
CVector posNearVeh;
CVector posSomewhereClose;
@@ -5284,10 +6304,6 @@ CPed::PositionPedOutOfCollision(void)
int smallestDistNearVeh = 999;
int smallestDistSomewhereClose = 999;
- if (!m_pMyVehicle)
- return false;
-
- CVector vehPos = m_pMyVehicle->GetPosition();
CVector potentialPos;
potentialPos.y = GetPosition().y - 3.5f;
potentialPos.z = GetPosition().z;
@@ -5297,15 +6313,7 @@ CPed::PositionPedOutOfCollision(void)
for (int xTry = 0; xTry < 15; xTry++) {
CPedPlacement::FindZCoorForPed(&potentialPos);
- CVector distVec = potentialPos - vehPos;
- float dist = distVec.Magnitude();
-
- // Makes close distances bigger for some reason.
- float mult = (0.6f + dist) / dist;
- CVector adjustedPotentialPos = distVec * mult + vehPos;
- if (CWorld::GetIsLineOfSightClear(vehPos, adjustedPotentialPos, true, false, false, true, false, false, false)
- && !CWorld::TestSphereAgainstWorld(potentialPos, 0.6f, this, true, false, false, true, false, false)) {
-
+ if (!CWorld::TestSphereAgainstWorld(potentialPos, 0.6f, this, true, false, false, true, false, false)) {
float potentialChangeSqr = (potentialPos - GetPosition()).MagnitudeSqr();
veh = (CVehicle*)CWorld::TestSphereAgainstWorld(potentialPos, 0.6f, this, false, true, false, false, false, false);
if (veh) {
@@ -5352,21 +6360,20 @@ CPed::WarpPedToNearLeaderOffScreen(void)
CVector halfNormalizedDist = distVec / halfOfDist;
CVector appropriatePos = GetPosition();
- CVector zCorrectedPos = appropriatePos;
- int tryCount = Min(10, halfOfDist);
+ int tryCount = Min(10, (int)halfOfDist);
for (int i = 0; i < tryCount; ++i) {
appropriatePos += halfNormalizedDist;
+ CVector zCorrectedPos = appropriatePos;
CPedPlacement::FindZCoorForPed(&zCorrectedPos);
- if (Abs(zCorrectedPos.z - warpToPos.z) >= 3.0f && Abs(zCorrectedPos.z - appropriatePos.z) >= 3.0f)
- continue;
-
- appropriatePos.z = zCorrectedPos.z;
- if (!TheCamera.IsSphereVisible(appropriatePos, 0.6f)
- && CWorld::GetIsLineOfSightClear(appropriatePos, warpToPos, true, true, false, true, false, false, false)
- && !CWorld::TestSphereAgainstWorld(appropriatePos, 0.6f, this, true, true, false, true, false, false)) {
- teleported = true;
- Teleport(appropriatePos);
+ if (Abs(zCorrectedPos.z - warpToPos.z) < 3.0f || Abs(zCorrectedPos.z - appropriatePos.z) < 3.0f) {
+ appropriatePos.z = zCorrectedPos.z;
+ if (!TheCamera.IsSphereVisible(appropriatePos, 0.6f)
+ && CWorld::GetIsLineOfSightClear(appropriatePos, warpToPos, true, true, false, true, false, false, false)
+ && !CWorld::TestSphereAgainstWorld(appropriatePos, 0.6f, this, true, true, false, true, false, false)) {
+ teleported = true;
+ Teleport(appropriatePos);
+ }
}
}
m_leaveCarTimer = CTimer::GetTimeInMilliseconds() + 3000;
@@ -5386,23 +6393,556 @@ CPed::WarpPedToNearEntityOffScreen(CEntity *warpTo)
CVector halfNormalizedDist = distVec / halfOfDist;
CVector appropriatePos = GetPosition();
- CVector zCorrectedPos = appropriatePos;
- int tryCount = Min(10, halfOfDist);
+ int tryCount = Min(10, (int)halfOfDist);
for (int i = 0; i < tryCount; ++i) {
appropriatePos += halfNormalizedDist;
+ CVector zCorrectedPos = appropriatePos;
CPedPlacement::FindZCoorForPed(&zCorrectedPos);
- if (Abs(zCorrectedPos.z - warpToPos.z) >= 3.0f && Abs(zCorrectedPos.z - appropriatePos.z) >= 3.0f)
- continue;
-
- appropriatePos.z = zCorrectedPos.z;
- if (!TheCamera.IsSphereVisible(appropriatePos, 0.6f)
- && CWorld::GetIsLineOfSightClear(appropriatePos, warpToPos, true, true, false, true, false, false, false)
- && !CWorld::TestSphereAgainstWorld(appropriatePos, 0.6f, this, true, true, false, true, false, false)) {
- teleported = true;
- Teleport(appropriatePos);
+ if (Abs(zCorrectedPos.z - warpToPos.z) < 3.0f || Abs(zCorrectedPos.z - appropriatePos.z) < 3.0f) {
+ appropriatePos.z = zCorrectedPos.z;
+ if (!TheCamera.IsSphereVisible(appropriatePos, 0.6f)
+ && CWorld::GetIsLineOfSightClear(appropriatePos, warpToPos, true, true, false, true, false, false, false)
+ && !CWorld::TestSphereAgainstWorld(appropriatePos, 0.6f, this, true, true, false, true, false, false)) {
+ teleported = true;
+ Teleport(appropriatePos);
+ }
}
}
m_leaveCarTimer = CTimer::GetTimeInMilliseconds() + 3000;
return teleported;
-} \ No newline at end of file
+}
+
+int32
+CPed::KillCharOnFootArmed(CVector &ourPos, CVector &targetPos, CVector &distWithTarget)
+{
+ bool killPlayerInNoPoliceZone = false;
+ if (m_pedInObjective->IsPlayer() && CCullZones::NoPolice())
+ killPlayerInNoPoliceZone = true;
+
+ if (!bNotAllowedToDuck || killPlayerInNoPoliceZone) {
+ if (m_nPedType == PEDTYPE_COP && !m_pedInObjective->GetWeapon()->IsTypeMelee())
+ bNotAllowedToDuck = true;
+ } else {
+ if (!m_pedInObjective->bInVehicle) {
+ if (m_pedInObjective->GetWeapon()->IsTypeMelee()) {
+ bNotAllowedToDuck = false;
+ bCrouchWhenShooting = false;
+ } else if (DuckAndCover()) {
+ return CANT_ATTACK;
+ }
+ } else {
+ bNotAllowedToDuck = false;
+ bCrouchWhenShooting = false;
+ }
+ }
+ if (m_leaveCarTimer > CTimer::GetTimeInMilliseconds() && !bKindaStayInSamePlace) {
+ SetMoveState(PEDMOVE_STILL);
+ return CANT_ATTACK;
+ }
+ if (m_pedInObjective->IsPlayer()) {
+ CPlayerPed *player = FindPlayerPed();
+ if (m_nPedType == PEDTYPE_COP && player->m_pWanted->m_bIgnoredByCops
+ || player->m_pWanted->m_bIgnoredByEveryone
+ || m_pedInObjective->bIsInWater
+ || m_pedInObjective->m_nPedState == PED_ARRESTED) {
+
+ if (m_nPedState != PED_ARREST_PLAYER)
+ SetIdle();
+
+ return CANT_ATTACK;
+ }
+ }
+ if (m_pedInObjective->IsPlayer() && m_nPedType != PEDTYPE_COP
+ && CharCreatedBy != MISSION_CHAR && FindPlayerPed()->m_pWanted->m_CurrentCops != 0) {
+ SetObjective(OBJECTIVE_FLEE_ON_FOOT_TILL_SAFE);
+
+ return CANT_ATTACK;
+ }
+ if (m_pedInObjective->m_fHealth <= 0.0f) {
+ bObjectiveCompleted = true;
+ bScriptObjectiveCompleted = true;
+ return CANT_ATTACK;
+ }
+ CWeaponInfo *wepInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
+ float wepRange = wepInfo->m_fRange;
+ float wepRangeAdjusted = wepRange / 3.f;
+
+ float distWithTargetSc = distWithTarget.Magnitude();
+ if (m_pedInObjective->bInVehicle && m_pedInObjective->m_nPedState != PED_DRAG_FROM_CAR) {
+ CVehicle *vehOfTarget = m_pedInObjective->m_pMyVehicle;
+ if (vehOfTarget->bIsInWater || vehOfTarget->GetStatus() == STATUS_PLAYER_DISABLED
+ || m_pedInObjective->IsPlayer() && CPad::GetPad(0)->ArePlayerControlsDisabled()) {
+ SetIdle();
+ return WATCH_UNTIL_HE_DISAPPEARS;
+ }
+ SetLookFlag(vehOfTarget, false);
+ if (m_nMoveState == PEDMOVE_STILL && IsPedInControl())
+ TurnBody();
+
+ if (m_nPedState != PED_CARJACK) {
+ if (m_pedInObjective->m_nPedState != PED_ARRESTED) {
+ if (m_attackTimer < CTimer::GetTimeInMilliseconds() && distWithTargetSc < wepRange && distWithTargetSc > 3.0f) {
+
+ SetAttack(vehOfTarget);
+ SetWeaponLockOnTarget(vehOfTarget);
+ SetShootTimer(CGeneral::GetRandomNumberInRange(500, 2000));
+
+ CVector2D dirVehGoing = vehOfTarget->m_vecMoveSpeed;
+ if (dirVehGoing.Magnitude() > 0.2f) {
+ CVector2D vehDist = GetPosition() - vehOfTarget->GetPosition();
+ vehDist.Normalise();
+ dirVehGoing.Normalise();
+ if (DotProduct2D(vehDist, dirVehGoing) > 0.8f) {
+ SetAttackTimer(CGeneral::GetRandomNumberInRange(200, 500));
+ SetMoveState(PEDMOVE_STILL);
+ }
+ return ATTACK_IN_PROGRESS;
+ }
+ if (distWithTargetSc <= m_distanceToCountSeekDone) {
+ SetAttackTimer(CGeneral::GetRandomNumberInRange(200, 500));
+ SetMoveState(PEDMOVE_STILL);
+ } else {
+ SetAttackTimer(CGeneral::GetRandomNumberInRange(2000, 5000));
+ }
+ return ATTACK_IN_PROGRESS;
+ } else if (m_nPedState != PED_ATTACK && !bKindaStayInSamePlace && !killPlayerInNoPoliceZone) {
+ if (vehOfTarget) {
+ if (m_nPedType == PEDTYPE_COP || vehOfTarget->bIsBus) {
+ GoToNearestDoor(vehOfTarget);
+ } else {
+ m_vehDoor = 0;
+ if (m_pedInObjective == vehOfTarget->pDriver || vehOfTarget->bIsBus) {
+ m_vehDoor = CAR_DOOR_LF;
+ } else if (m_pedInObjective == vehOfTarget->pPassengers[0]) {
+ m_vehDoor = CAR_DOOR_RF;
+ } else if (m_pedInObjective == vehOfTarget->pPassengers[1]) {
+ m_vehDoor = CAR_DOOR_LR;
+ } else if (m_pedInObjective == vehOfTarget->pPassengers[2]) {
+ m_vehDoor = CAR_DOOR_RR;
+ }
+ // Unused
+ // GetPositionToOpenCarDoor(vehOfTarget, m_vehDoor);
+ SetSeekCar(vehOfTarget, m_vehDoor);
+ SetMoveState(PEDMOVE_RUN);
+ }
+ }
+ }
+ }
+ }
+ return ATTACK_IN_PROGRESS;
+ }
+ if (m_nMoveState == PEDMOVE_STILL && IsPedInControl()) {
+ SetLookFlag(m_pedInObjective, false);
+ TurnBody();
+ }
+ if (m_nPedType == PEDTYPE_COP && m_pedInObjective->IsPlayer()) {
+ float maxArrestDist = 1.5f;
+ if (((CCopPed*)this)->m_bDragsPlayerFromCar) {
+ if (m_nPedState == PED_FALL) {
+ maxArrestDist = 3.5f;
+ } else if (m_nPedState != PED_DRAG_FROM_CAR) {
+ ((CCopPed*)this)->m_bDragsPlayerFromCar = 0;
+ }
+ }
+
+ if (distWithTargetSc < maxArrestDist) {
+ if (m_pedInObjective->m_getUpTimer > CTimer::GetTimeInMilliseconds()
+ || m_pedInObjective->m_nPedState == PED_DRAG_FROM_CAR) {
+
+ ((CCopPed*)this)->SetArrestPlayer(m_pedInObjective);
+ return WATCH_UNTIL_HE_DISAPPEARS;
+ }
+ }
+ }
+ /*
+ if (distWithTargetSc > 0.1f) {
+ junk code
+ } */
+
+ if (m_shotTime != 0 && m_ceaseAttackTimer != 0) {
+ if (CTimer::GetTimeInMilliseconds() > m_ceaseAttackTimer + m_shotTime) {
+ ClearLookFlag();
+ bObjectiveCompleted = true;
+ m_shotTime = 0;
+ return CANT_ATTACK;
+ }
+ }
+
+ if (!bKindaStayInSamePlace && !bStopAndShoot && m_nPedState != PED_ATTACK && !bDuckAndCover && !killPlayerInNoPoliceZone) {
+ if (distWithTargetSc > wepRange
+ || m_pedInObjective->m_getUpTimer > CTimer::GetTimeInMilliseconds()
+ || m_pedInObjective->m_nPedState == PED_ARRESTED
+ || m_pedInObjective->EnteringCar() && distWithTargetSc < 3.0f) {
+
+ if (m_pedInObjective->EnteringCar())
+ wepRangeAdjusted = 2.0f;
+
+ if (bUsePedNodeSeek) {
+ CVector bestCoords(0.0f, 0.0f, 0.0f);
+ m_vecSeekPos = m_pedInObjective->GetPosition();
+
+ if (!m_pNextPathNode)
+ FindBestCoordsFromNodes(m_vecSeekPos, &bestCoords);
+
+ if (m_pNextPathNode)
+ m_vecSeekPos = CPathFind::TakeWidthIntoAccountForWandering(m_pNextPathNode, m_randomSeed);
+
+ SetSeek(m_vecSeekPos, m_distanceToCountSeekDone);
+ } else {
+ SetSeek(m_pedInObjective, wepRangeAdjusted);
+ }
+ if (m_pedInObjective->m_pCurrentPhysSurface && distWithTargetSc < 5.0f) {
+ bStopAndShoot = true;
+ b158_8 = true;
+ SetMoveState(PEDMOVE_STILL);
+ } else if (b158_8) {
+ bStopAndShoot = false;
+ b158_8 = false;
+ }
+ return ATTACK_IN_PROGRESS;
+ }
+ }
+ if (m_attackTimer < CTimer::GetTimeInMilliseconds()
+ && distWithTargetSc < wepRange && m_pedInObjective->m_nPedState != PED_GETUP && m_pedInObjective->m_nPedState != PED_DRAG_FROM_CAR) {
+
+ if (bIsDucking && !bCrouchWhenShooting) {
+ CAnimBlendAssociation* duckAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_DUCK_DOWN);
+ if (!duckAnim)
+ duckAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_DUCK_LOW);
+ if (!duckAnim)
+ duckAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_DUCK_WEAPON);
+
+ if (duckAnim) {
+ duckAnim->flags |= ASSOC_DELETEFADEDOUT;
+ duckAnim->blendDelta = -4.0f;
+ }
+ bIsDucking = false;
+ return CANT_ATTACK;
+ }
+ bObstacleShowedUpDuringKillObjective = false;
+ SetAttack(m_pedInObjective);
+ SetWeaponLockOnTarget(m_pedInObjective);
+ SetShootTimer(CGeneral::GetRandomNumberInRange(600.0f, 1500.0f));
+
+ int time;
+ if (distWithTargetSc <= wepRangeAdjusted)
+ time = CGeneral::GetRandomNumberInRange(100.0f, 500.0f);
+ else
+ time = CGeneral::GetRandomNumberInRange(1500.0f, 3000.0f);
+
+ SetAttackTimer(time);
+ } else {
+ if (!m_pedInObjective->m_pCurrentPhysSurface && b158_8) {
+ b158_8 = false;
+ bStopAndShoot = false;
+ }
+
+ if (m_nPedState != PED_ATTACK && m_nPedState != PED_FIGHT) {
+ if (bNotAllowedToDuck && bKindaStayInSamePlace && !bIsDucking && bCrouchWhenShooting) {
+ SetDuck(CGeneral::GetRandomNumberInRange(1000, 5000), false);
+ return CANT_ATTACK;
+ }
+ if (bObstacleShowedUpDuringKillObjective) {
+ if (m_nPedType == PEDTYPE_COP) {
+ if (GetWeapon()->m_eWeaponType > WEAPONTYPE_COLT45
+ || m_fleeFrom && m_fleeFrom->IsObject()) {
+ wepRangeAdjusted = 6.0f;
+ } else if (m_fleeFrom && m_fleeFrom->IsVehicle()) {
+ wepRangeAdjusted = 4.0f;
+ } else {
+ wepRangeAdjusted = 2.0f;
+ }
+ } else {
+ wepRangeAdjusted = 2.0f;
+ }
+ }
+ if (distWithTargetSc <= wepRangeAdjusted) {
+ SetMoveState(PEDMOVE_STILL);
+ bIsPointingGunAt = true;
+ if (m_nPedState != PED_AIM_GUN && !bDuckAndCover) {
+ m_attackTimer = CTimer::GetTimeInMilliseconds();
+ SetIdle();
+ }
+ } else {
+ if (m_nPedState != PED_SEEK_ENTITY && m_nPedState != PED_SEEK_POS
+ && !bStopAndShoot && !killPlayerInNoPoliceZone && !bKindaStayInSamePlace) {
+ Say(SOUND_PED_ATTACK);
+ SetSeek(m_pedInObjective, wepRangeAdjusted);
+ bIsRunning = true;
+ if (m_nPedType == PEDTYPE_COP && FindPlayerPed()->m_pWanted->m_CurrentCops > 1) {
+ if (CGeneral::GetRandomNumber() & 1)
+ Say(SOUND_PED_GUNAIMEDAT3);
+ else
+ Say(SOUND_PED_GUNAIMEDAT2);
+ }
+ }
+ }
+ }
+ }
+
+ if (CTimer::GetTimeInMilliseconds() > m_nPedStateTimer)
+ m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(m_pedInObjective->GetPosition().x, m_pedInObjective->GetPosition().y, GetPosition().x, GetPosition().y);
+
+ return ATTACK_IN_PROGRESS;
+}
+
+int32
+CPed::KillCharOnFootMelee(CVector &ourPos, CVector &targetPos, CVector &distWithTarget)
+{
+ bool killPlayerInNoPoliceZone = false;
+ float distWithTargetSc = distWithTarget.Magnitude();
+ CPlayerPed *victimPlayer = nil;
+ if (m_pedInObjective->IsPlayer())
+ victimPlayer = (CPlayerPed*)m_pedInObjective;
+
+ if (victimPlayer) {
+ if (CCullZones::NoPolice()
+ || m_pedInObjective->m_pCurrentPhysSurface
+ && m_pedInObjective->m_pCurrentPhysSurface != m_pCurrentPhysSurface
+ && distWithTargetSc < 5.f) {
+
+ if (victimPlayer && victimPlayer->m_bSpeedTimerFlag && (IsGangMember() || m_nPedType == PEDTYPE_COP)
+ && CharCreatedBy != MISSION_CHAR) {
+ GiveWeapon(WEAPONTYPE_COLT45, 1000, 1);
+ SetCurrentWeapon(WEAPONTYPE_COLT45);
+ SetMoveState(PEDMOVE_STILL);
+ bStopAndShoot = true;
+ b158_8 = true;
+ return CANT_ATTACK;
+ }
+ killPlayerInNoPoliceZone = true;
+ }
+ }
+ bNotAllowedToDuck = false;
+ bStopAndShoot = false;
+ b158_8 = false;
+ if (m_leaveCarTimer > CTimer::GetTimeInMilliseconds() && !bKindaStayInSamePlace) {
+ SetMoveState(PEDMOVE_STILL);
+ return CANT_ATTACK;
+ }
+ if (victimPlayer) {
+ CPlayerPed *player = FindPlayerPed();
+ if (m_nPedType == PEDTYPE_COP && player->m_pWanted->m_bIgnoredByCops
+ || player->m_pWanted->m_bIgnoredByEveryone
+ || m_pedInObjective->bIsInWater
+ || m_pedInObjective->m_nPedState == PED_ARRESTED) {
+
+ if (m_nPedState != PED_ARREST_PLAYER)
+ SetIdle();
+
+ return CANT_ATTACK;
+ }
+ }
+ if (victimPlayer && m_nPedType != PEDTYPE_COP && CharCreatedBy != MISSION_CHAR
+ && FindPlayerPed()->m_pWanted->m_CurrentCops != 0) {
+ SetObjective(OBJECTIVE_FLEE_ON_FOOT_TILL_SAFE);
+
+ return CANT_ATTACK;
+ }
+ if (m_pedInObjective->m_fHealth <= 0.0f) {
+ bObjectiveCompleted = true;
+ bScriptObjectiveCompleted = true;
+ return ATTACK_IN_PROGRESS;
+ }
+ bool canReachVictim = false;
+ uint32 endOfAttack = 0;
+ CWeaponInfo *wepInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
+
+ // Already calculated at the start
+ // float distWithTargetSc = distWithTarget.Magnitude();
+ float maxDistToKeep = 0.3f;
+ float wepRange = wepInfo->m_fRange / 2.f;
+
+ if (GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED && !IsPlayer() && !(m_pedStats->m_flags & STAT_CAN_KICK))
+ wepRange -= 0.3f;
+
+ if (distWithTargetSc <= 5.f && victimPlayer && !victimPlayer->m_bNoPosForMeleeAttack) {
+
+ if (m_pedInObjective->EnteringCar() && wepRange > 2.f) {
+ m_vecSeekPos = m_pedInObjective->GetPosition();
+ wepRange = 1.0f;
+ maxDistToKeep = 0.5f;
+ } else {
+ int8 attackDir = victimPlayer->FindMeleeAttackPoint(this, distWithTarget, endOfAttack);
+ if (attackDir == -1) {
+ m_vecSeekPos = victimPlayer->GetPosition();
+ maxDistToKeep = 4.0f;
+ } else {
+ victimPlayer->GetMeleeAttackCoords(m_vecSeekPos, attackDir, wepRange);
+ distWithTargetSc = (m_vecSeekPos - GetPosition()).Magnitude();
+ canReachVictim = true;
+ }
+ }
+ } else {
+ m_vecSeekPos = m_pedInObjective->GetPosition();
+ maxDistToKeep = Max(0.8f, 0.9f * wepRange);
+ wepRange *= 1.1f;
+ if (victimPlayer && victimPlayer->m_bNoPosForMeleeAttack)
+ victimPlayer = nil;
+ }
+
+ if (m_pedInObjective->bInVehicle && m_pedInObjective->m_nPedState != PED_DRAG_FROM_CAR) {
+ CVehicle *vehOfTarget = m_pedInObjective->m_pMyVehicle;
+
+ if (vehOfTarget){
+ if (vehOfTarget->bIsInWater || vehOfTarget->GetStatus() == STATUS_PLAYER_DISABLED
+ || m_pedInObjective->IsPlayer() && CPad::GetPad(0)->ArePlayerControlsDisabled()) {
+ SetIdle();
+ return WATCH_UNTIL_HE_DISAPPEARS;
+ }
+ SetLookFlag(vehOfTarget, false);
+
+ if (m_nPedState != PED_CARJACK) {
+ if (m_pedInObjective->m_nPedState != PED_ARRESTED) {
+ if (m_nPedState != PED_ATTACK && !bKindaStayInSamePlace && !killPlayerInNoPoliceZone) {
+
+ if (m_nPedType == PEDTYPE_COP || vehOfTarget->bIsBus) {
+ GoToNearestDoor(vehOfTarget);
+ } else {
+ m_vehDoor = 0;
+ if (m_pedInObjective == vehOfTarget->pDriver || vehOfTarget->bIsBus) {
+ m_vehDoor = CAR_DOOR_LF;
+ } else if (m_pedInObjective == vehOfTarget->pPassengers[0]) {
+ m_vehDoor = CAR_DOOR_RF;
+ } else if (m_pedInObjective == vehOfTarget->pPassengers[1]) {
+ m_vehDoor = CAR_DOOR_LR;
+ } else if (m_pedInObjective == vehOfTarget->pPassengers[2]) {
+ m_vehDoor = CAR_DOOR_RR;
+ }
+ // Unused
+ // GetPositionToOpenCarDoor(vehOfTarget, m_vehDoor);
+ SetSeekCar(vehOfTarget, m_vehDoor);
+ SetMoveState(PEDMOVE_RUN);
+ }
+ }
+ }
+ }
+ }
+ return ATTACK_IN_PROGRESS;
+ }
+ if (m_nMoveState == PEDMOVE_STILL && IsPedInControl()) {
+ SetLookFlag(m_pedInObjective, false);
+ if(m_nPedState == PED_IDLE || m_nPedState == PED_ATTACK || m_nPedState == PED_FIGHT)
+ TurnBody();
+ }
+ if (m_nPedType == PEDTYPE_COP && m_pedInObjective->IsPlayer()) {
+ float maxArrestDist = 1.5f;
+ if (((CCopPed*)this)->m_bDragsPlayerFromCar) {
+ if (m_nPedState == PED_FALL) {
+ maxArrestDist = 3.5f;
+ } else if (m_nPedState != PED_DRAG_FROM_CAR) {
+ ((CCopPed*)this)->m_bDragsPlayerFromCar = 0;
+ }
+ }
+
+ if (distWithTargetSc < maxArrestDist) {
+ if (m_pedInObjective->m_getUpTimer > CTimer::GetTimeInMilliseconds()
+ || m_pedInObjective->m_nPedState == PED_DRAG_FROM_CAR) {
+
+ ((CCopPed*)this)->SetArrestPlayer(m_pedInObjective);
+ return WATCH_UNTIL_HE_DISAPPEARS;
+ }
+ }
+ }
+
+ if (distWithTargetSc > maxDistToKeep && !bKindaStayInSamePlace && m_nPedState != PED_ATTACK &&
+ (m_nPedState != PED_FIGHT || m_curFightMove == FIGHTMOVE_IDLE) && !killPlayerInNoPoliceZone) {
+
+ bool goForward = false;
+
+ if (m_nPedState == PED_FIGHT) {
+ if (canReachVictim) {
+ CVector attackAndVictimDist = m_vecSeekPos - m_pedInObjective->GetPosition();
+ CVector victimFarness = attackAndVictimDist / wepRange;
+ CVector distVec = GetPosition() - m_pedInObjective->GetPosition();
+ float distSqr = distVec.MagnitudeSqr();
+ if (sq(wepRange) > distSqr && distSqr > 0.05f) {
+ distVec.Normalise();
+ if (DotProduct2D(victimFarness, distVec) > Cos(DEGTORAD(30.f)))
+ goForward = true;
+ }
+ }
+ }
+ if (goForward) {
+ m_curFightMove = FIGHTMOVE_SHUFFLE_F;
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_FIGHT_SHUFFLE_B, 16.f)->SetFinishCallback(FinishFightMoveCB,this);
+ m_fightState = FIGHTSTATE_NO_MOVE;
+ m_fightButtonPressure = 0;
+ m_takeAStepAfterAttack = false;
+
+ } else if (bUsePedNodeSeek && !canReachVictim) {
+ CVector bestCoords(0.0f, 0.0f, 0.0f);
+
+ if (!m_pNextPathNode)
+ FindBestCoordsFromNodes(m_vecSeekPos, &bestCoords);
+
+ if (m_pNextPathNode)
+ m_vecSeekPos = CPathFind::TakeWidthIntoAccountForWandering(m_pNextPathNode, m_randomSeed);
+
+ SetSeek(m_vecSeekPos, m_distanceToCountSeekDone);
+ } else {
+ if (canReachVictim)
+ SetSeek(m_vecSeekPos, maxDistToKeep);
+ else
+ SetSeek(m_pedInObjective, maxDistToKeep);
+ }
+ return ATTACK_IN_PROGRESS;
+ }
+
+ if (m_attackTimer < CTimer::GetTimeInMilliseconds()
+ && distWithTargetSc < wepRange && m_pedInObjective->m_nPedState != PED_GETUP && m_pedInObjective->m_nPedState != PED_DRAG_FROM_CAR) {
+
+ if (bIsDucking) {
+ CAnimBlendAssociation* duckAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_DUCK_DOWN);
+ if (!duckAnim)
+ duckAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_DUCK_LOW);
+ if (!duckAnim)
+ duckAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_DUCK_WEAPON);
+
+ if (duckAnim) {
+ duckAnim->flags |= ASSOC_DELETEFADEDOUT;
+ duckAnim->blendDelta = -4.0f;
+ }
+ bIsDucking = false;
+ return CANT_ATTACK;
+ }
+
+ if (canReachVictim || !victimPlayer) {
+ SetMoveState(PEDMOVE_STILL);
+ SetAttack(m_pedInObjective);
+ m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(
+ m_pedInObjective->GetPosition().x, m_pedInObjective->GetPosition().y,
+ GetPosition().x, GetPosition().y);
+ SetShootTimer(CGeneral::GetRandomNumberInRange(0.f, 500.f));
+
+ int time;
+ if (endOfAttack <= CTimer::GetTimeInMilliseconds())
+ time = CGeneral::GetRandomNumberInRange(100.0f, 1500.0f);
+ else
+ time = endOfAttack - CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(400.0f, 1500.0f);
+
+ SetAttackTimer(time);
+ bObstacleShowedUpDuringKillObjective = false;
+ }
+ return ATTACK_IN_PROGRESS;
+ } else {
+ if (!m_pedInObjective->m_pCurrentPhysSurface && m_pCurrentPhysSurface && b158_8) {
+ b158_8 = false;
+ bStopAndShoot = false;
+ }
+
+ if (m_nPedState != PED_ATTACK && m_nPedState != PED_FIGHT) {
+ SetMoveState(PEDMOVE_STILL);
+ if (GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED)
+ StartFightAttack(0);
+ }
+ return ATTACK_IN_PROGRESS;
+ }
+}
+
+bool
+CPed::CanBeDamagedByThisGangMember(CPed* who)
+{
+ return m_gangFlags & (1 << (who->m_nPedType - PEDTYPE_GANG1));
+}
diff --git a/src/peds/PedAttractor.cpp b/src/peds/PedAttractor.cpp
new file mode 100644
index 00000000..91139def
--- /dev/null
+++ b/src/peds/PedAttractor.cpp
@@ -0,0 +1,802 @@
+#include "common.h"
+#include "PedAttractor.h"
+
+#include "General.h"
+#include "Vehicle.h"
+#include "World.h"
+#include "MemoryHeap.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;
+
+std::vector<CVector> CPedShelterAttractor::ms_displacements;
+
+CPedAttractorManager* GetPedAttractorManager()
+{
+// mobile just has a static here:
+/*
+ static CPedAttractorManager pedAttrMgr;
+ return &pedAttrMgr;
+*/
+ static CPedAttractorManager *pedAttrMgr;
+ if(pedAttrMgr == nil){
+ PUSH_MEMID(MEMID_PED_ATTR);
+ pedAttrMgr = new CPedAttractorManager;
+ POP_MEMID();
+ }
+ return pedAttrMgr;
+}
+
+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[1];
+ else
+ return &m_effects[3];
+ }
+ else {
+ if (DotProduct(pos - m_pVehicle->GetPosition(), m_pVehicle->GetForward()) > 0.0f)
+ return &m_effects[0];
+ else
+ return &m_effects[2];
+ }
+}
+
+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<CVehicleToEffect>::const_iterator assoc = vVehicleToEffect.begin(); assoc != vVehicleToEffect.end(); ++assoc) {
+ if (assoc->GetVehicle() == pVehicle)
+ return assoc->ChooseEffect(pos);
+ }
+ }
+ PUSH_MEMID(MEMID_PED_ATTR);
+ CVehicleToEffect effect(pVehicle);
+ vVehicleToEffect.push_back(effect);
+ POP_MEMID();
+#ifdef FIX_BUGS
+ return vVehicleToEffect.back().ChooseEffect(pos);
+#else
+ return effect.ChooseEffect(pos);
+#endif
+}
+
+CVehicle* CPedAttractorManager::GetIceCreamVanForEffect(C2dEffect* pEffect)
+{
+ if (vVehicleToEffect.empty())
+ return nil;
+ for (std::vector<CVehicleToEffect>::const_iterator assoc = vVehicleToEffect.begin(); assoc != vVehicleToEffect.end(); ++assoc) {
+ if (assoc->HasThisEffect(pEffect))
+ return assoc->GetVehicle();
+ }
+ return nil;
+}
+
+const CPedAttractor* CPedAttractorManager::FindAssociatedAttractor(const C2dEffect* pEffect, std::vector<CPedAttractor*>& vecAttractors)
+{
+ if (vecAttractors.empty())
+ return nil;
+ for (std::vector<CPedAttractor*>::const_iterator attractor = vecAttractors.begin(); attractor != vecAttractors.end(); ++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<CVehicleToEffect>::iterator assoc = vVehicleToEffect.begin(); assoc != vVehicleToEffect.end();) {
+ if (assoc->GetVehicle() != pVehicle) {
+ ++assoc;
+ continue;
+ }
+ uint32 total = 0;
+ for (uint32 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<CVector>::const_iterator v = ms_displacements.begin(); v != ms_displacements.end(); ++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<CPed*>::iterator pPedIt = vApproachingQueue.begin(); pPedIt != vApproachingQueue.end(); ++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_GOTO_ATM_ON_FOOT)
+ return true;
+ break;
+ case ATTRACTOR_SEAT:
+ if (pPed->m_objective == OBJECTIVE_GOTO_SEAT_ON_FOOT)
+ return true;
+ break;
+ case ATTRACTOR_STOP:
+ if (pPed->m_objective == OBJECTIVE_GOTO_BUS_STOP_ON_FOOT || pPed->m_objective == OBJECTIVE_WAIT_ON_FOOT_AT_BUS_STOP || pPed->m_objective == OBJECTIVE_WAIT_ON_FOOT)
+ return true;
+ break;
+ case ATTRACTOR_PIZZA:
+ if (pPed->m_objective == OBJECTIVE_GOTO_PIZZA_ON_FOOT || pPed->m_objective == OBJECTIVE_WAIT_ON_FOOT)
+ return true;
+ break;
+ case ATTRACTOR_SHELTER:
+ if (pPed->m_objective == OBJECTIVE_GOTO_SHELTER_ON_FOOT || pPed->m_objective == OBJECTIVE_WAIT_ON_FOOT_AT_SHELTER)
+ return true;
+ break;
+ case ATTRACTOR_ICECREAM:
+ if (pPed->m_objective == OBJECTIVE_GOTO_ICE_CREAM_VAN_ON_FOOT || pPed->m_objective == OBJECTIVE_WAIT_ON_FOOT_AT_ICE_CREAM_VAN)
+ return true;
+ break;
+ }
+ return false;
+}
+
+bool CPedAttractor::DeRegisterPed(CPed* pPed)
+{
+ for (std::vector<CPed*>::iterator pPedIt = vApproachingQueue.begin(); pPedIt != vApproachingQueue.end(); ++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<CPed*>::const_iterator pPedIt = vWaitingQueue.begin(); pPedIt != vWaitingQueue.end(); ++pPedIt) {
+ if (*pPedIt == pPed)
+ return false;
+ }
+ vWaitingQueue.push_back(pPed);
+ for (std::vector<CPed*>::iterator pPedIt = vApproachingQueue.begin(); pPedIt != vApproachingQueue.end(); ++pPedIt) {
+ if (*pPedIt == pPed) {
+ vApproachingQueue.erase(pPedIt);
+ break;
+ }
+ }
+ for (std::vector<CPed*>::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 (uint32 i = 0; i < vWaitingQueue.size(); i++){
+ if (vWaitingQueue[i] == pPed)
+ qid = i;
+ }
+ if (qid < 0)
+ return false;
+ for (uint32 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 {
+ pPed->SetObjective(OBJECTIVE_NONE);
+ 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.x));
+ UpdatePedStateOnDeparture(pPed);
+ }
+ vWaitingQueue.erase(vWaitingQueue.begin() + qid);
+ for (std::vector<CPed*>::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 (uint32 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 {
+ pPed->SetObjective(OBJECTIVE_NONE);
+ 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.x));
+ UpdatePedStateOnDeparture(pPed);
+ }
+ vWaitingQueue.erase(vWaitingQueue.begin() + qid);
+ for (std::vector<CPed*>::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<CPed*>::const_iterator pPedIt = vWaitingQueue.begin(); pPedIt != vWaitingQueue.end(); ++pPedIt) {
+ if (*pPedIt == pPed)
+ return true;
+ }
+ for (std::vector<CPed*>::const_iterator pPedIt = vApproachingQueue.begin(); pPedIt != vApproachingQueue.end(); ++pPedIt) {
+ if (*pPedIt == pPed) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool CPedAttractor::IsInQueue(CPed* pPed) const
+{
+ for (std::vector<CPed*>::const_iterator pPedIt = vWaitingQueue.begin(); pPedIt != vWaitingQueue.end(); ++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<CPedAttractor*>& vecAttractors)
+{
+ CPedAttractor* pRegisteredAttractor = nil;
+ for (std::vector<CPedAttractor*>::const_iterator pAttractorIt = vecAttractors.begin(); pAttractorIt != vecAttractors.end(); ++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;
+ }
+ PUSH_MEMID(MEMID_PED_ATTR);
+ switch (pEffect->pedattr.type) {
+ case ATTRACTOR_ATM: pRegisteredAttractor = new CPedAtmAttractor(pEffect, matrix, gcMaxSizeOfAtmQueue, 1.0f, 30000.0f, 3000.0f, 0.2f, 0.15f, 0.1f, 0.1f); vecAttractors.push_back(pRegisteredAttractor); break;
+ case ATTRACTOR_SEAT: pRegisteredAttractor = new CPedSeatAttractor(pEffect, matrix, gcMaxSizeOfSeatQueue, 1.0f, 30000.0f, 3000.0f, 0.125f, 0.1f, 0.1f, 0.1f); vecAttractors.push_back(pRegisteredAttractor); break;
+ case ATTRACTOR_STOP: pRegisteredAttractor = new CPedStopAttractor(pEffect, matrix, gcMaxSizeOfStopQueue, 1.0f, 30000.0f, 3000.0f, 0.2f, 0.1f, 0.1f, 0.1f); vecAttractors.push_back(pRegisteredAttractor); break;
+ case ATTRACTOR_PIZZA: pRegisteredAttractor = new CPedPizzaAttractor(pEffect, matrix, gcMaxSizeOfPizzaQueue, 1.0f, 30000.0f, 3000.0f, 0.2f, 0.1f, 0.1f, 0.1f); vecAttractors.push_back(pRegisteredAttractor); break;
+ case ATTRACTOR_SHELTER: pRegisteredAttractor = new CPedShelterAttractor(pEffect, matrix, gcMaxSizeOfShelterQueue, 1.0f, 30000.0f, 3000.0f, 0.5f, 6.28f, 0.1f, 0.1f); vecAttractors.push_back(pRegisteredAttractor); break;
+ case ATTRACTOR_ICECREAM: pRegisteredAttractor = new CPedIceCreamAttractor(pEffect, matrix, gcMaxSizeOfIceCreamQueue, 1.0f, 30000.0f, 3000.0f, 0.2f, 0.3f, 0.1f, 0.1f); vecAttractors.push_back(pRegisteredAttractor); break;
+ }
+ POP_MEMID();
+ if (pRegisteredAttractor)
+ pRegisteredAttractor->RegisterPed(pPed);
+ return pRegisteredAttractor;
+}
+
+bool CPedAttractorManager::DeRegisterPed(CPed* pPed, CPedAttractor* pAttractor, std::vector<CPedAttractor*>& vecAttractors)
+{
+ if (!pAttractor)
+ return false;
+ CPedAttractor* pFound = nil;
+ for (std::vector<CPedAttractor*>::const_iterator pAttractorIt = vecAttractors.begin(); pAttractorIt != vecAttractors.end(); ++pAttractorIt) {
+ if (*pAttractorIt == pAttractor) {
+ pFound = *pAttractorIt;
+ break;
+ }
+ }
+ if (!pFound)
+ return false;
+ pFound->DeRegisterPed(pPed);
+ if (pFound->GetNoOfRegisteredPeds() != 0)
+ return true;
+ for (std::vector<CPedAttractor*>::iterator pAttractorIt = vecAttractors.begin(); pAttractorIt != vecAttractors.end(); ++pAttractorIt) {
+ if (*pAttractorIt == pAttractor) {
+ vecAttractors.erase(pAttractorIt);
+ break;
+ }
+ }
+ delete pAttractor;
+ return true;
+}
+
+bool CPedAttractorManager::BroadcastArrival(CPed* pPed, CPedAttractor* pAttractor, std::vector<CPedAttractor*>& vecAttractors)
+{
+ if (!pAttractor)
+ return false;
+ CPedAttractor* pFound = nil;
+ for (std::vector<CPedAttractor*>::const_iterator pAttractorIt = vecAttractors.begin(); pAttractorIt != vecAttractors.end(); ++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<CPedAttractor*>& vecAttractors)
+{
+ if (!pAttractor)
+ return false;
+ CPedAttractor* pFound = nil;
+ for (std::vector<CPedAttractor*>::const_iterator pAttractorIt = vecAttractors.begin(); pAttractorIt != vecAttractors.end(); ++pAttractorIt) {
+ if (*pAttractorIt == pAttractor) {
+ pFound = *pAttractorIt;
+ break;
+ }
+ }
+ if (!pFound)
+ return false;
+ pFound->DeRegisterPed(pPed);
+ if (pFound->GetNoOfRegisteredPeds() != 0)
+ return true;
+ for (std::vector<CPedAttractor*>::iterator pAttractorIt = vecAttractors.begin(); pAttractorIt != vecAttractors.end(); ++pAttractorIt) {
+ if (*pAttractorIt == pAttractor) {
+ vecAttractors.erase(pAttractorIt);
+ break;
+ }
+ }
+ delete pAttractor;
+ return true;
+}
+
+bool CPedAttractorManager::IsInQueue(CPed* pPed, CPedAttractor* pAttractor, std::vector<CPedAttractor*>& vecAttractors)
+{
+ if (!pAttractor)
+ return false;
+ for (std::vector<CPedAttractor*>::const_iterator pAttractorIt = vecAttractors.begin(); pAttractorIt != vecAttractors.end(); ++pAttractorIt) {
+ if (*pAttractorIt == pAttractor) {
+ return (*pAttractorIt)->IsInQueue(pPed);
+ }
+ }
+ return false;
+}
+
+bool CPedAttractorManager::IsAtHeadOfQueue(CPed* pPed, CPedAttractor* pAttractor, std::vector<CPedAttractor*>& vecAttractors)
+{
+ if (!pAttractor)
+ return false;
+ for (std::vector<CPedAttractor*>::const_iterator pAttractorIt = vecAttractors.begin(); pAttractorIt != vecAttractors.end(); ++pAttractorIt) {
+ if (*pAttractorIt == pAttractor) {
+ return (*pAttractorIt)->IsAtHeadOfQueue(pPed);
+ }
+ }
+ return false;
+}
+
+bool CPedAttractorManager::IsPedRegistered(CPed* pPed, std::vector<CPedAttractor*>& vecAttractors)
+{
+ for (std::vector<CPedAttractor*>::const_iterator pAttractorIt = vecAttractors.begin(); pAttractorIt != vecAttractors.end(); ++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..c55e4028
--- /dev/null
+++ b/src/peds/PedAttractor.h
@@ -0,0 +1,196 @@
+#pragma once
+#include "common.h"
+#include <vector>
+
+#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<CPedAttractor*> vAtmAttractors;
+ std::vector<CPedAttractor*> vSeatAttractors;
+ std::vector<CPedAttractor*> vStopAttractors;
+ std::vector<CPedAttractor*> vPizzaAttractors;
+ std::vector<CPedAttractor*> vShelterAttractors;
+ std::vector<CPedAttractor*> vIceCreamAttractors;
+ std::vector<CVehicleToEffect> vVehicleToEffect;
+
+public:
+ CPedAttractor* RegisterPedWithAttractor(CPed* pPed, C2dEffect* pEffect, const CMatrix& matrix);
+ CPedAttractor* RegisterPed(CPed* pPed, C2dEffect* pEffect, const CMatrix& matrix, std::vector<CPedAttractor*>& vecAttractors);
+ bool BroadcastArrival(CPed* pPed, CPedAttractor* pAttractor);
+ bool BroadcastArrival(CPed* pPed, CPedAttractor* pAttractor, std::vector<CPedAttractor*>& 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<CPedAttractor*>& vecAttractors);
+ bool IsInQueue(CPed* pPed, CPedAttractor* pAttractor);
+ bool IsInQueue(CPed* pPed, CPedAttractor* pAttractor, std::vector<CPedAttractor*>& vecAttractors);
+ bool IsAtHeadOfQueue(CPed* pPed, CPedAttractor* pAttractor);
+ bool IsAtHeadOfQueue(CPed* pPed, CPedAttractor* pAttractor, std::vector<CPedAttractor*>& vecAttractors);
+ bool BroadcastDeparture(CPed* pPed, CPedAttractor* pAttractor);
+ bool BroadcastDeparture(CPed* pPed, CPedAttractor* pAttractor, std::vector<CPedAttractor*>& vecAttractors);
+ bool DeRegisterPed(CPed* pPed, CPedAttractor* pAttractor);
+ bool DeRegisterPed(CPed* pPed, CPedAttractor* pAttractor, std::vector<CPedAttractor*>& vecAttractors);
+ bool IsPedRegisteredWithEffect(CPed* pPed);
+ bool IsPedRegistered(CPed* pPed, std::vector<CPedAttractor*>& 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<CPed*> vApproachingQueue;
+ std::vector<CPed*> 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 (int32)(vWaitingQueue.size() + vApproachingQueue.size()); }
+ int32 ComputeFreeSlot() const { return (int32)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 { return ATTRACTOR_ATM; };
+ virtual void UpdatePedStateOnDeparture(CPed* pPed) const;
+ 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() { GetPedAttractorManager()->RemoveIceCreamVanEffects(p2dEffect); }
+ virtual ePedAttractorType GetType() const { return ATTRACTOR_ICECREAM; }
+ virtual void UpdatePedStateOnDeparture(CPed* pPed) const {};
+ 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() { return 2000.0f; }
+ virtual ePedAttractorType GetType() const { return ATTRACTOR_PIZZA; }
+ virtual void UpdatePedStateOnDeparture(CPed* pPed) const;
+ 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 { return ATTRACTOR_SEAT; }
+ virtual void UpdatePedStateOnDeparture(CPed* pPed) const {};
+ 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<CVector> ms_displacements;
+public:
+ virtual ePedAttractorType GetType() const { return ATTRACTOR_SHELTER; }
+ virtual bool BroadcastDeparture(CPed*);
+ virtual void UpdatePedStateOnDeparture(CPed* pPed) const {};
+ virtual bool IsAtHeadOfQueue(CPed* pPed) const { return true; }
+ virtual void ComputeAttractPos(int qid, CVector& pos) const;
+ virtual void ComputeAttractHeading(int qid, float& heading) const;
+
+ 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 { return ATTRACTOR_STOP; }
+ virtual void UpdatePedStateOnDeparture(CPed* pPed) const {};
+
+ 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/PedChat.cpp b/src/peds/PedChat.cpp
index 907f5756..ec6719c6 100644
--- a/src/peds/PedChat.cpp
+++ b/src/peds/PedChat.cpp
@@ -5,46 +5,63 @@
#include "Ped.h"
// Corresponds to ped sounds (from SOUND_PED_DEATH to SOUND_PED_TAXI_CALL)
-PedAudioData CommentWaitTime[39] = {
- {500, 800, 500, 2},
- {500, 800, 500, 2},
- {500, 800, 500, 2},
- {500, 800, 500, 2},
- {100, 2, 100, 2},
- {700, 500, 1000, 500},
- {700, 500, 1000, 500},
- {5000, 2000, 15000, 3000},
- {5000, 2000, 15000, 3000},
- {5000, 2000, 15000, 3000},
- {6000, 6000, 6000, 6000},
- {1000, 1000, 2000, 2000},
- {1000, 500, 2000, 1500},
- {1000, 500, 2000, 1500},
- {800, 200, 1000, 500},
- {800, 200, 1000, 500},
- {800, 400, 2000, 1000},
- {800, 400, 2000, 1000},
- {400, 300, 2000, 1000},
- {2000, 1000, 2500, 1500},
- {200, 200, 200, 200},
- {6000, 3000, 5000, 6000},
- {6000, 3000, 9000, 5000},
- {6000, 3000, 9000, 5000},
- {6000, 3000, 9000, 5000},
- {400, 300, 4000, 1000},
- {400, 300, 4000, 1000},
- {400, 300, 4000, 1000},
- {1000, 500, 3000, 1000},
- {1000, 500, 1000, 1000},
- {3000, 2000, 3000, 2000},
- {1000, 500, 3000, 6000},
- {1000, 500, 2000, 4000},
- {1000, 500, 2000, 5000},
- {1000, 500, 3000, 2000},
- {1600, 1000, 2000, 2000},
- {3000, 2000, 5000, 3000},
- {1000, 1000, 1000, 1000},
- {1000, 1000, 5000, 5000},
+PedAudioData CommentWaitTime[56] = {
+ { 500, 800, 500, 2 },
+ { 500, 800, 500, 2 },
+ { 500, 800, 500, 2 },
+ { 500, 800, 500, 2 },
+ { 100, 2, 100, 2 },
+ { 500, 500, 2000, 1000 },
+ { 2000, 50, 2050, 1000 },
+ { 5000, 2000, 7000, 3000 },
+ { 5000, 2000, 7000, 3000 },
+ { 300, 200, 500, 200 },
+ { 3000, 1000, 4000, 1000 },
+ { 6000, 6000, 6000, 6000 },
+ { 4000, 1000, 5000, 1000 },
+ { 3000, 1000, 4000, 1000 },
+ { 1000, 1000, 2000, 2000 },
+ { 1000, 500, 2000, 1500 },
+ { 1700, 1000, 3000, 1000 },
+ { 800, 200, 1000, 500 },
+ { 800, 200, 1000, 500 },
+ { 800, 400, 2000, 1000 },
+ { 800, 400, 2000, 1000 },
+ { 2000, 2000, 4000, 4000 },
+ { 2000, 2000, 4000, 1000 },
+ { 4000, 1000, 5000, 1000 },
+ { 800, 400, 1200, 500 },
+ { 5000, 1000, 6000, 2000 },
+ { 5000, 1000, 6000, 2000 },
+ { 5000, 1000, 6000, 2000 },
+ { 5000, 1000, 6000, 2000 },
+ { 5000, 1000, 6000, 2000 },
+ { 5000, 1000, 6000, 2000 },
+ { 5000, 1000, 6000, 2000 },
+ { 4000, 2000, 7000, 2000 },
+ { 1000, 300, 2000, 1000 },
+ { 1500, 1000, 2500, 1000 },
+ { 200, 200, 200, 200 },
+ { 2000, 1000, 4000, 1000 },
+ { 2000, 1000, 4000, 1000 },
+ { 1000, 500, 3000, 1000 },
+ { 1000, 500, 1000, 1000 },
+ { 3000, 2000, 5000, 1000 },
+ { 3000, 2000, 5000, 1000 },
+ { 3000, 2000, 3000, 2000 },
+ { 2000, 1000, 3000, 1000 },
+ { 2500, 1000, 5000, 5000 },
+ { 2000, 1000, 3000, 2000 },
+ { 4000, 1000, 5000, 1000 },
+ { 1000, 500, 2000, 4000 },
+ { 1000, 500, 2000, 5000 },
+ { 2000, 500, 2500, 500 },
+ { 1000, 500, 3000, 2000 },
+ { 1600, 1000, 2000, 2000 },
+ { 2000, 1000, 4000, 2000 },
+ { 1500, 1000, 2500, 1000 },
+ { 1000, 1000, 5000, 5000 },
+ { 0, 0, 0, 0 }
};
bool
@@ -59,9 +76,7 @@ CPed::ServiceTalking(void)
if (bBodyPartJustCameOff && m_bodyPartBleeding == PED_HEAD)
return;
- if (!CGeneral::faststricmp(CModelInfo::GetModelInfo(GetModelIndex())->GetModelName(), "bomber"))
- m_queuedSound = SOUND_PED_BOMBER;
- else if (m_nPedState == PED_ON_FIRE)
+ if (!CGame::germanGame && m_pFire)
m_queuedSound = SOUND_PED_BURNING;
if (m_queuedSound != SOUND_NO_SOUND) {
@@ -75,6 +90,10 @@ CPed::ServiceTalking(void)
CommentWaitTime[m_queuedSound - SOUND_PED_DEATH].m_nFixedDelayTime
+ CTimer::GetTimeInMilliseconds()
+ CGeneral::GetRandomNumberInRange(0, CommentWaitTime[m_queuedSound - SOUND_PED_DEATH].m_nOverrideFixedDelayTime);
+
+ if (m_queuedSound == SOUND_PED_PLAYER_BEFORESEX && IsPlayer())
+ m_soundStart += 2000;
+
m_lastQueuedSound = m_queuedSound;
m_queuedSound = SOUND_NO_SOUND;
}
@@ -84,68 +103,50 @@ CPed::ServiceTalking(void)
void
CPed::Say(uint16 audio)
{
- if (IsPlayer()) {
+ if (3.0f + TheCamera.GetPosition().z < GetPosition().z)
+ return;
- // Ofc this part isn't in VC.
+ if (TheCamera.m_CameraAverageSpeed > 1.65f) {
+ if (audio != SOUND_PED_DAMAGE && audio != SOUND_PED_HIT && audio != SOUND_PED_LAND)
+ return;
+
+ } else if (TheCamera.m_CameraAverageSpeed > 1.25f) {
+ if (audio != SOUND_PED_DEATH &&
+ audio != SOUND_PED_DAMAGE && audio != SOUND_PED_HIT && audio != SOUND_PED_LAND &&
+ audio != SOUND_PED_TAXI_WAIT && audio != SOUND_PED_EVADE)
+ return;
+
+ } else if (TheCamera.m_CameraAverageSpeed > 0.9f) {
switch (audio) {
case SOUND_PED_DEATH:
- audio = SOUND_PED_DAMAGE;
- break;
case SOUND_PED_DAMAGE:
case SOUND_PED_HIT:
case SOUND_PED_LAND:
- break;
- case SOUND_PED_BULLET_HIT:
- case SOUND_PED_CAR_JACKED:
- case SOUND_PED_DEFEND:
- audio = SOUND_PED_HIT;
+ case SOUND_PED_BURNING:
+ case SOUND_PED_FLEE_SPRINT:
+ case SOUND_PED_TAXI_WAIT:
+ case SOUND_PED_EVADE:
+ case SOUND_PED_CRASH_VEHICLE:
+ case SOUND_PED_CRASH_CAR:
+ case SOUND_PED_ANNOYED_DRIVER:
break;
default:
return;
}
- } else {
- if (TheCamera.GetPosition().z + 3.0f < GetPosition().z)
- return;
-
- if (TheCamera.m_CameraAverageSpeed > 1.65f) {
-#ifdef VC_PED_PORTS
- if (audio != SOUND_PED_DAMAGE && audio != SOUND_PED_HIT && audio != SOUND_PED_LAND)
-#endif
- return;
-
- } else if (TheCamera.m_CameraAverageSpeed > 1.25f) {
- if (audio != SOUND_PED_DEATH &&
-#ifdef VC_PED_PORTS
- audio != SOUND_PED_DAMAGE && audio != SOUND_PED_HIT && audio != SOUND_PED_LAND &&
-#endif
- audio != SOUND_PED_TAXI_WAIT && audio != SOUND_PED_EVADE)
- return;
-
- } else if (TheCamera.m_CameraAverageSpeed > 0.9f) {
- switch (audio) {
- case SOUND_PED_DEATH:
-#ifdef VC_PED_PORTS
- case SOUND_PED_DAMAGE:
- case SOUND_PED_HIT:
- case SOUND_PED_LAND:
-#endif
- case SOUND_PED_BURNING:
- case SOUND_PED_FLEE_SPRINT:
- case SOUND_PED_TAXI_WAIT:
- case SOUND_PED_EVADE:
- case SOUND_PED_ANNOYED_DRIVER:
- break;
- default:
- return;
- }
- }
}
if (audio < m_queuedSound) {
if (audio != m_lastQueuedSound || audio == SOUND_PED_DEATH
+
+ // See VC Ped Speech patch
+#ifdef FIX_BUGS
|| CommentWaitTime[audio - SOUND_PED_DEATH].m_nOverrideMaxRandomDelayTime
- + m_lastSoundStart
- + (uint32) CGeneral::GetRandomNumberInRange(0, CommentWaitTime[audio - SOUND_PED_DEATH].m_nMaxRandomDelayTime) <= CTimer::GetTimeInMilliseconds()) {
+ + (uint32)CGeneral::GetRandomNumberInRange(0, CommentWaitTime[audio - SOUND_PED_DEATH].m_nMaxRandomDelayTime)
+#else
+ || CommentWaitTime[m_queuedSound - SOUND_PED_DEATH].m_nOverrideMaxRandomDelayTime
+ + (uint32)CGeneral::GetRandomNumberInRange(0, CommentWaitTime[m_queuedSound - SOUND_PED_DEATH].m_nMaxRandomDelayTime)
+#endif
+ + m_lastSoundStart <= CTimer::GetTimeInMilliseconds()) {
m_queuedSound = audio;
}
}
diff --git a/src/peds/PedDebug.cpp b/src/peds/PedDebug.cpp
index 1c22963e..0dbabb58 100644
--- a/src/peds/PedDebug.cpp
+++ b/src/peds/PedDebug.cpp
@@ -7,10 +7,10 @@
#include "Sprite.h"
#include "Text.h"
-
static char ObjectiveText[][28] = {
"No Obj",
"Wait on Foot",
+ "Wait on Foot for cop",
"Flee on Foot Till Safe",
"Guard Spot",
"Guard Area",
@@ -21,6 +21,8 @@ static char ObjectiveText[][28] = {
"Flee Char on Foot Till Safe",
"Flee Char on Foot Always",
"GoTo Char on Foot",
+ "GoTo Char on Foot walking",
+ "Hassle char",
"Follow Char in Formation",
"Leave Car",
"Enter Car as Passenger",
@@ -37,15 +39,30 @@ static char ObjectiveText[][28] = {
"Guard Attack",
"Set Leader",
"Follow Route",
- "Solicit",
+ "Solicit vehicle",
"Take Taxi",
"Catch Train",
"Buy IceCream",
"Steal Any Car",
+ "Steal any mission car",
"Mug Char",
-#ifdef VC_PED_PORTS
- "Leave Car and Die"
-#endif
+ "Lv car die",
+ "Goto seat",
+ "Goto atm",
+ "Flee car",
+ "Sunbathe",
+ "Goto bus stop",
+ "Goto pizza",
+ "Goto shelter",
+ "Aim gun at",
+ "Wander",
+ "Wait on foot at shltr",
+ "Sprint to area",
+ "Kill char on boat",
+ "Solicit ped",
+ "Wait at bus stop",
+ "Goto ice cream van foot",
+ "Wait foot icecream van"
};
static char StateText[][18] = {
@@ -82,8 +99,14 @@ static char StateText[][18] = {
"Investigate",
"Step away",
"On Fire",
- "Unknown",
+ "Bathe",
+ "Flash",
+ "Jog",
+ "Answer mobile",
+ "Hang out",
"STATES_NO_AI",
+ "Abseil",
+ "Sit",
"Jump",
"Fall",
"GetUp",
@@ -106,6 +129,7 @@ static char StateText[][18] = {
"Exit Car",
"Hands Up",
"Arrested",
+ "Deply stgr"
};
static char PersonalityTypeText[][18] = {
@@ -132,8 +156,10 @@ static char PersonalityTypeText[][18] = {
"Geek Girl",
"Old Girl",
"Tough Girl",
- "Tramp Male",
- "Tramp Female",
+ "Tramp",
+#ifdef FIX_BUGS // there's male and female ones
+ "Tramp",
+#endif
"Tourist",
"Prostitute",
"Criminal",
@@ -142,8 +168,6 @@ static char PersonalityTypeText[][18] = {
"Psycho",
"Steward",
"Sports Fan",
- "Shopper",
- "Old Shopper"
};
static char WaitStateText[][16] = {
@@ -168,6 +192,21 @@ static char WaitStateText[][16] = {
"Play HandsCower",
"Play Chat",
"Finish Flee",
+ "Sit down",
+ "Sit down rvrs",
+ "Sit up",
+ "Sit idle",
+ "Use atm",
+ "Sunbth pre",
+ "Sunbth down",
+ "Sunbth idle",
+ "Riot",
+ "Fast fall",
+ "Bomber",
+ "Stripper",
+ "Ground attack",
+ "Lance sitting",
+ "Handsup simple"
};
void
@@ -283,7 +322,7 @@ CPed::DebugRenderOnePedText(void)
CFont::SetJustifyOff();
CFont::SetColor(CRGBA(255, 255, 0, 255));
CFont::SetBackGroundOnlyTextOn();
- CFont::SetFontStyle(0);
+ CFont::SetFontStyle(1);
AsciiToUnicode(StateText[m_nPedState], gUString);
CFont::PrintString(screenCoords.x, screenCoords.y, gUString);
AsciiToUnicode(ObjectiveText[m_objective], gUString);
diff --git a/src/peds/PedFight.cpp b/src/peds/PedFight.cpp
index 13d3930c..43ded57a 100644
--- a/src/peds/PedFight.cpp
+++ b/src/peds/PedFight.cpp
@@ -22,37 +22,47 @@
#include "Automobile.h"
#include "WaterLevel.h"
#include "World.h"
+#include "Bike.h"
+#include "Glass.h"
+#include "SpecialFX.h"
uint16 nPlayerInComboMove;
+RpClump* flyingClumpTemp;
-RpClump *flyingClumpTemp;
-
-// This is beta fistfite.dat array. Not used anymore since they're being fetched from fistfite.dat.
-FightMove tFightMoves[NUM_FIGHTMOVES] = {
- {ANIM_STD_NUM, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0},
- {ANIM_STD_PUNCH, 0.2f, 8.0f / 30.0f, 0.0f, 0.3f, HITLEVEL_HIGH, 1, 0},
- {ANIM_STD_FIGHT_IDLE, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0},
- {ANIM_STD_FIGHT_SHUFFLE_F, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0},
- {ANIM_STD_FIGHT_KNEE, 4.0f / 30.0f, 0.2f, 0.0f, 0.6f, HITLEVEL_LOW, 2, 0},
- {ANIM_STD_FIGHT_HEAD, 4.0f / 30.0f, 0.2f, 0.0f, 0.7f, HITLEVEL_HIGH, 3, 0},
- {ANIM_STD_FIGHT_PUNCH, 4.0f / 30.0f, 7.0f / 30.0f, 10.0f / 30.0f, 0.4f, HITLEVEL_HIGH, 1, 0},
- {ANIM_STD_FIGHT_LHOOK, 8.0f / 30.0f, 10.0f / 30.0f, 0.0f, 0.4f, HITLEVEL_HIGH, 3, 0},
- {ANIM_STD_FIGHT_KICK, 8.0f / 30.0f, 10.0f / 30.0f, 0.0f, 0.5, HITLEVEL_MEDIUM, 2, 0},
- {ANIM_STD_FIGHT_LONGKICK, 8.0f / 30.0f, 10.0f / 30.0f, 0.0f, 0.5, HITLEVEL_MEDIUM, 4, 0},
- {ANIM_STD_FIGHT_ROUNDHOUSE, 8.0f / 30.0f, 10.0f / 30.0f, 0.0f, 0.6f, HITLEVEL_MEDIUM, 4, 0},
- {ANIM_STD_FIGHT_BODYBLOW, 5.0f / 30.0f, 7.0f / 30.0f, 0.0f, 0.35f, HITLEVEL_LOW, 2, 0},
- {ANIM_STD_KICKGROUND, 10.0f / 30.0f, 14.0f / 30.0f, 0.0f, 0.4f, HITLEVEL_GROUND, 1, 0},
- {ANIM_STD_HIT_FRONT, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0},
- {ANIM_STD_HIT_BACK, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0},
- {ANIM_STD_HIT_RIGHT, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0},
- {ANIM_STD_HIT_LEFT, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0},
- {ANIM_STD_HIT_BODYBLOW, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0},
- {ANIM_STD_HIT_CHEST, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0},
- {ANIM_STD_HIT_HEAD, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0},
- {ANIM_STD_HIT_WALK, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0},
- {ANIM_STD_HIT_FLOOR, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0},
- {ANIM_STD_HIT_BEHIND, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0},
- {ANIM_STD_FIGHT_2IDLE, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0},
+FightMove tFightMoves[NUM_FIGHTMOVES] =
+{
+ { ANIM_STD_NUM, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 },
+ { ANIM_STD_PUNCH, 0.2f, 8.f/30.f, 0.0f, 0.3f, 1.0f, HITLEVEL_HIGH, 1, 0 },
+ { ANIM_STD_FIGHT_IDLE, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 },
+ { ANIM_STD_FIGHT_SHUFFLE_F, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 },
+ { ANIM_STD_FIGHT_KNEE, 4.f/30.f, 0.2f, 0.0f, 0.6f, 1.0f, HITLEVEL_LOW, 2, 0 },
+ { ANIM_STD_FIGHT_LHOOK, 8.f/30.f, 10.f/30.f, 0.0f, 0.4f, 1.0f, HITLEVEL_HIGH, 3, 0 },
+ { ANIM_STD_FIGHT_JAB, 4.f/30.f, 0.2f, 0.0f, 0.7f, 1.0f, HITLEVEL_HIGH, 3, 0 },
+ { ANIM_STD_FIGHT_PUNCH, 4.f/30.f, 7.f/30.f, 10.f/30.f, 0.4f, 1.0f, HITLEVEL_HIGH, 1, 0 },
+ { ANIM_STD_FIGHT_LONGKICK, 8.f/30.f, 10.f/30.f, 0.0f, 0.5f, 1.0f, HITLEVEL_MEDIUM, 4, 0 },
+ { ANIM_STD_FIGHT_ROUNDHOUSE, 8.f/30.f, 10.f/30.f, 0.0f, 0.6f, 1.0f, HITLEVEL_MEDIUM, 4, 0 },
+ { ANIM_STD_FIGHT_KICK, 8.f/30.f, 10.f/30.f, 0.0f, 0.5f, 1.0f, HITLEVEL_HIGH, 2, 0 },
+ { ANIM_STD_FIGHT_HEAD, 8.f/30.f, 10.f/30.f, 0.0f, 0.5f, 1.0f, HITLEVEL_MEDIUM, 2, 0 },
+ { ANIM_STD_FIGHT_BKICK_L, 8.f/30.f, 10.f/30.f, 0.0f, 0.5f, 1.0f, HITLEVEL_LOW, 2, 0 },
+ { ANIM_STD_FIGHT_BKICK_L, 8.f/30.f, 10.f/30.f, 0.0f, 0.5f, 1.0f, HITLEVEL_LOW, 2, 0 },
+ { ANIM_STD_FIGHT_ELBOW_L, 8.f/30.f, 10.f/30.f, 0.0f, 0.5f, 1.0f, HITLEVEL_MEDIUM, 2, 0 },
+ { ANIM_STD_FIGHT_BKICK_R, 8.f/30.f, 10.f/30.f, 0.0f, 0.5f, 1.0f, HITLEVEL_MEDIUM, 2, 0 },
+ { ANIM_STD_FIGHT_ELBOW_R, 8.f/30.f, 10.f/30.f, 0.0f, 0.5f, 1.0f, HITLEVEL_HIGH, 2, 0 },
+ { ANIM_STD_KICKGROUND, 10.f/30.f, 14.f/30.f, 0.0f, 0.4f, 1.0f, HITLEVEL_GROUND, 1, 0 },
+ { ANIM_STD_HIT_FRONT, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 },
+ { ANIM_STD_HIT_BACK, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 },
+ { ANIM_STD_HIT_RIGHT, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 },
+ { ANIM_STD_HIT_LEFT, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 },
+ { ANIM_STD_HIT_BODYBLOW, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 },
+ { ANIM_STD_HIT_CHEST, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 },
+ { ANIM_STD_HIT_HEAD, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 },
+ { ANIM_STD_HIT_WALK, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 },
+ { ANIM_STD_HIT_FLOOR, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 },
+ { ANIM_STD_HIT_BEHIND, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 },
+ { ANIM_ATTACK_1, 4.f/30.f, 7.f/30.f, 10.f/30.f, 0.4f, 1.0f, HITLEVEL_HIGH, 1, 0 },
+ { ANIM_ATTACK_2, 4.f/30.f, 7.f/30.f, 10.f/30.f, 0.4f, 1.0f, HITLEVEL_HIGH, 1, 0 },
+ { ANIM_ATTACK_3, 4.f / 30.f, 7.f / 30.f, 10.f / 30.f, 0.4f, 1.0f, HITLEVEL_HIGH, 1, 0 },
+ { ANIM_STD_FIGHT_2IDLE, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 }
};
static PedOnGroundState
@@ -151,14 +161,13 @@ void
CPed::SetPointGunAt(CEntity *to)
{
if (to) {
- SetLookFlag(to, true);
+ SetLookFlag(to, true, true);
SetAimFlag(to);
-#ifdef VC_PED_PORTS
SetLookTimer(INT32_MAX);
-#endif
}
- if (m_nPedState == PED_AIM_GUN || bIsDucking || m_nWaitState == WAITSTATE_PLAYANIM_DUCK)
+ CWeaponInfo* curWeapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
+ if (m_nPedState == PED_AIM_GUN || (bIsDucking && !IsPlayer()) || m_nWaitState == WAITSTATE_PLAYANIM_DUCK || curWeapon->m_AnimToPlay == ASSOCGRP_STD)
return;
if (m_nPedState != PED_ATTACK)
@@ -166,26 +175,27 @@ CPed::SetPointGunAt(CEntity *to)
SetPedState(PED_AIM_GUN);
bIsPointingGunAt = true;
- CWeaponInfo *curWeapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
- SetMoveState(PEDMOVE_NONE);
+ SetMoveState(PEDMOVE_STILL);
CAnimBlendAssociation *aimAssoc;
- if (bCrouchWhenShooting)
- aimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), curWeapon->m_Anim2ToPlay);
- else
- aimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), curWeapon->m_AnimToPlay);
+ if (bCrouchWhenShooting && bIsDucking && GetCrouchFireAnim(curWeapon)) {
+ aimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchFireAnim(curWeapon));
+ } else {
+ aimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_FIRE);
+ }
if (!aimAssoc || aimAssoc->blendDelta < 0.0f) {
- if (bCrouchWhenShooting)
- aimAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, curWeapon->m_Anim2ToPlay, 4.0f);
- else
- aimAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, curWeapon->m_AnimToPlay);
+ if (bCrouchWhenShooting && bIsDucking && GetCrouchFireAnim(curWeapon)) {
+ aimAssoc = CAnimManager::BlendAnimation(GetClump(), curWeapon->m_AnimToPlay, GetCrouchFireAnim(curWeapon), 4.0f);
+ } else {
+ aimAssoc = CAnimManager::AddAnimation(GetClump(), curWeapon->m_AnimToPlay, ANIM_WEAPON_FIRE);
+ }
aimAssoc->blendAmount = 0.0f;
aimAssoc->blendDelta = 8.0f;
}
- if (to)
+ if (to && !IsPlayer())
Say(SOUND_PED_ATTACK);
}
@@ -193,14 +203,22 @@ void
CPed::PointGunAt(void)
{
CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
- CAnimBlendAssociation *weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), weaponInfo->m_AnimToPlay);
- if (!weaponAssoc || weaponAssoc->blendDelta < 0.0f)
- weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), weaponInfo->m_Anim2ToPlay);
+ float animLoopStart = weaponInfo->m_fAnimLoopStart;
+ CAnimBlendAssociation *weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_FIRE);
+ if (!weaponAssoc || weaponAssoc->blendDelta < 0.0f) {
+ if (weaponInfo->IsFlagSet(WEAPONFLAG_CROUCHFIRE)) {
+ weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchFireAnim(weaponInfo));
+ animLoopStart = weaponInfo->m_fAnim2LoopStart;
+ }
+ }
- if (weaponAssoc && weaponAssoc->currentTime > weaponInfo->m_fAnimLoopStart) {
- weaponAssoc->SetCurrentTime(weaponInfo->m_fAnimLoopStart);
+ if (weaponAssoc && weaponAssoc->currentTime > animLoopStart * 0.4f) {
+ weaponAssoc->SetCurrentTime(animLoopStart);
weaponAssoc->flags &= ~ASSOC_RUNNING;
+ if (bIsDucking)
+ m_pedIK.m_flags &= ~CPedIK::AIMS_WITH_ARM;
+
if (weaponInfo->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM))
m_pedIK.m_flags |= CPedIK::AIMS_WITH_ARM;
else
@@ -217,51 +235,38 @@ CPed::ClearPointGunAt(void)
ClearLookFlag();
ClearAimFlag();
bIsPointingGunAt = false;
-#ifndef VC_PED_PORTS
- if (m_nPedState == PED_AIM_GUN) {
- RestorePreviousState();
-#else
if (m_nPedState == PED_AIM_GUN || m_nPedState == PED_ATTACK) {
SetPedState(PED_IDLE);
RestorePreviousState();
}
-#endif
- weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), weaponInfo->m_AnimToPlay);
- if (!animAssoc || animAssoc->blendDelta < 0.0f) {
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), weaponInfo->m_Anim2ToPlay);
+ weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_FIRE);
+ if (!animAssoc || animAssoc->blendDelta < 0.0f) {
+ if (weaponInfo->IsFlagSet(WEAPONFLAG_CROUCHFIRE)) {
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchFireAnim(weaponInfo));
}
- if (animAssoc) {
- animAssoc->flags |= ASSOC_DELETEFADEDOUT;
- animAssoc->blendDelta = -4.0f;
- }
-#ifndef VC_PED_PORTS
}
-#endif
+ if (animAssoc) {
+ animAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ animAssoc->blendDelta = -4.0f;
+ }
}
void
CPed::SetAttack(CEntity *victim)
{
CPed *victimPed = nil;
+ CWeaponInfo *curWeapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
+ CAnimBlendAssociation *animAssoc;
+
if (victim && victim->IsPed())
victimPed = (CPed*)victim;
- CAnimBlendAssociation *animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_IDLE_BIGGUN);
- if (animAssoc) {
- animAssoc->blendDelta = -1000.0f;
- animAssoc->flags |= ASSOC_DELETEFADEDOUT;
- }
-
- if (m_attackTimer > CTimer::GetTimeInMilliseconds() || m_nWaitState == WAITSTATE_SURPRISE)
+ if (m_attackTimer > CTimer::GetTimeInMilliseconds() || m_nWaitState == WAITSTATE_SURPRISE || (bIsDucking && !bCrouchWhenShooting))
return;
- if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_HGUN_RELOAD)) {
- bIsAttacking = false;
- return;
- }
-
- if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_AK_RELOAD)) {
+ if (curWeapon->IsFlagSet(WEAPONFLAG_RELOAD) &&
+ (RpAnimBlendClumpGetAssociation(GetClump(), GetReloadAnim(curWeapon)) || RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchReloadAnim(curWeapon)))) {
if (!IsPlayer() || m_nPedState != PED_ATTACK || ((CPlayerPed*)this)->m_bHaveTargetSelected)
bIsAttacking = false;
else
@@ -270,20 +275,16 @@ CPed::SetAttack(CEntity *victim)
return;
}
- CWeaponInfo *curWeapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
- if (curWeapon->m_eWeaponFire == WEAPON_FIRE_INSTANT_HIT && !IsPlayer()) {
- if (GetWeapon()->HitsGround(this, nil, victim))
- return;
- }
-
- if (GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED) {
+ if (GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED || curWeapon->IsFlagSet(WEAPONFLAG_FIGHTMODE) || 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))) {
+ (m_nPedState != PED_FIGHT && m_nMoveState != PEDMOVE_NONE && m_nMoveState != PEDMOVE_STILL
+ && !(m_pedStats->m_flags & STAT_SHOPPING_BAGS) && curWeapon->IsFlagSet(WEAPONFLAG_PARTIALATTACK))) {
if (m_nPedState != PED_ATTACK) {
SetPedState(PED_ATTACK);
bIsAttacking = false;
- animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, curWeapon->m_AnimToPlay, 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);
@@ -291,38 +292,75 @@ CPed::SetAttack(CEntity *victim)
animAssoc->SetFinishCallback(FinishedAttackCB, this);
}
} else {
- StartFightAttack(CGeneral::GetRandomNumber() % 256);
+ StartFightAttack(CGeneral::GetRandomNumber());
}
return;
}
+ if (curWeapon->IsFlagSet(WEAPONFLAG_PARTIALATTACK) &&
+ (IsPlayer() && ((CPlayerPed*)this)->m_fMoveSpeed >= 1.0f ||
+ m_nMoveState == PEDMOVE_WALK || m_nMoveState == PEDMOVE_RUN)) {
+
+ if (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();
+ if (animAssoc->currentTime == animAssoc->hierarchy->totalLength)
+ animAssoc->SetCurrentTime(0.0f);
+
+ animAssoc->SetFinishCallback(FinishedAttackCB, this);
+ }
+ return;
+ }
+
+ if (m_pSeekTarget)
+ m_pSeekTarget->CleanUpOldReference(&m_pSeekTarget);
m_pSeekTarget = victim;
if (m_pSeekTarget)
m_pSeekTarget->RegisterReference((CEntity **) &m_pSeekTarget);
if (curWeapon->IsFlagSet(WEAPONFLAG_CANAIM)) {
CVector aimPos = GetRight() * 0.1f + GetForward() * 0.2f + GetPosition();
+ aimPos += GetUp() * 0.35f;
CEntity *obstacle = CWorld::TestSphereAgainstWorld(aimPos, 0.2f, nil, true, false, false, true, false, false);
- if (obstacle)
- return;
+ if (obstacle) {
+ 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;
+ SetAttackTimer(1500);
+ m_shotTime = CTimer::GetTimeInMilliseconds();
+ }
+ return;
+ }
+ }
m_pLookTarget = victim;
if (victim) {
m_pLookTarget->RegisterReference((CEntity **) &m_pLookTarget);
m_pSeekTarget->RegisterReference((CEntity **) &m_pSeekTarget);
}
+
if (m_pLookTarget) {
SetAimFlag(m_pLookTarget);
+#ifdef FREE_CAM
+ } else if (this != FindPlayerPed() || !((CPlayerPed*)this)->m_bFreeAimActive) {
+#else
} else {
- SetAimFlag(m_fRotationCur);
-
- if (FindPlayerPed() == this && TheCamera.Cams[0].Using3rdPersonMouseCam())
+#endif
+ if (this == FindPlayerPed() && TheCamera.Cams[0].Using3rdPersonMouseCam()) {
+ SetAimFlag(m_fRotationCur);
((CPlayerPed*)this)->m_fFPSMoveHeading = TheCamera.Find3rdPersonQuickAimPitch();
+ } else if (curWeapon->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM)) {
+ SetAimFlag(m_fRotationCur);
+ }
}
}
#ifdef FIX_BUGS
- // fix aiming for flamethrower while using PC controls
- else if (GetWeapon()->m_eWeaponType == WEAPONTYPE_FLAMETHROWER && TheCamera.Cams[0].Using3rdPersonMouseCam() && this == FindPlayerPed())
+ // fix aiming for flamethrower and minigun while using PC controls
+ else if (curWeapon->m_AnimToPlay == ASSOCGRP_FLAMETHROWER && TheCamera.Cams[0].Using3rdPersonMouseCam() && this == FindPlayerPed())
{
SetAimFlag(m_fRotationCur);
((CPlayerPed*)this)->m_fFPSMoveHeading = TheCamera.Find3rdPersonQuickAimPitch();
@@ -333,7 +371,7 @@ CPed::SetAttack(CEntity *victim)
return;
}
- if (IsPlayer() || !victimPed || victimPed->IsPedInControl()) {
+ if (IsPlayer() || (!victimPed || victimPed->IsPedInControl())) {
if (IsPlayer())
CPad::GetPad(0)->ResetAverageWeapon();
@@ -347,7 +385,7 @@ CPed::SetAttack(CEntity *victim)
ClearAimFlag();
// This condition is pointless
- if (pointBlankStatus == POINT_BLANK_FOR_WANTED_PED || !victimPed)
+ if (pointBlankStatus == POINT_BLANK_FOR_WANTED_PED || !victimPed && (IsPlayer() || !m_carInObjective))
StartFightAttack(200);
} else {
if (!curWeapon->IsFlagSet(WEAPONFLAG_CANAIM))
@@ -358,19 +396,40 @@ CPed::SetAttack(CEntity *victim)
SetPedState(PED_ATTACK);
SetMoveState(PEDMOVE_NONE);
- if (bCrouchWhenShooting) {
- animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_RBLOCK_SHOOT, 4.0f);
+ if (bCrouchWhenShooting && bIsDucking && curWeapon->IsFlagSet(WEAPONFLAG_CROUCHFIRE)) {
+ CAnimBlendAssociation* curMoveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchFireAnim(curWeapon));
+ if (curMoveAssoc) {
+ if (strcmp(CAnimManager::GetAnimAssociation(curWeapon->m_AnimToPlay, GetCrouchFireAnim(curWeapon))->hierarchy->name, curMoveAssoc->hierarchy->name) != 0) {
+ delete curMoveAssoc;
+ }
+ }
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), curWeapon->m_AnimToPlay, GetCrouchFireAnim(curWeapon), 8.0f);
} else {
float animDelta = 8.0f;
if (curWeapon->m_eWeaponFire == WEAPON_FIRE_MELEE)
animDelta = 1000.0f;
- if (GetWeapon()->m_eWeaponType != WEAPONTYPE_BASEBALLBAT
- || CheckForPedsOnGroundToAttack(this, nil) < PED_ON_THE_FLOOR) {
- animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, curWeapon->m_AnimToPlay, animDelta);
+ AnimationId fireAnim;
+ if (curWeapon->IsFlagSet(WEAPONFLAG_THROW))
+ fireAnim = ANIM_THROWABLE_START_THROW;
+ else if (CGame::nastyGame && (curWeapon->IsFlagSet(WEAPONFLAG_GROUND_2ND) || curWeapon->IsFlagSet(WEAPONFLAG_GROUND_3RD))) {
+ PedOnGroundState pedOnGround = CheckForPedsOnGroundToAttack(this, nil);
+ if (pedOnGround > PED_IN_FRONT_OF_ATTACKER || pedOnGround == NO_PED && bIsStanding && m_pCurSurface && m_pCurSurface->IsVehicle()) {
+ fireAnim = GetFireAnimGround(curWeapon, false);
+ } else {
+ fireAnim = GetFireAnimNotDucking(curWeapon);
+ }
} else {
- animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, curWeapon->m_Anim2ToPlay, animDelta);
+ fireAnim = GetFireAnimNotDucking(curWeapon);
+ }
+
+ CAnimBlendAssociation* curFireAssoc = RpAnimBlendClumpGetAssociation(GetClump(), fireAnim);
+ if (curFireAssoc) {
+ if (strcmp(CAnimManager::GetAnimAssociation(curWeapon->m_AnimToPlay, fireAnim)->hierarchy->name, curFireAssoc->hierarchy->name) != 0) {
+ delete curFireAssoc;
+ }
}
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), curWeapon->m_AnimToPlay, fireAnim, animDelta);
}
animAssoc->SetRun();
@@ -385,24 +444,19 @@ CPed::SetAttack(CEntity *victim)
if (GetWeapon()->m_eWeaponType == WEAPONTYPE_BASEBALLBAT && victimPed->m_nPedState == PED_GETUP)
SetWaitState(WAITSTATE_SURPRISE, nil);
- SetLookFlag(victim, false);
+ SetLookFlag(victim, true, true);
SetLookTimer(100);
}
void
CPed::ClearAttack(void)
{
- if (m_nPedState != PED_ATTACK || bIsDucking || m_nWaitState == WAITSTATE_PLAYANIM_DUCK)
+ if (m_nPedState != PED_ATTACK || (bIsDucking && !IsPlayer()) || m_nWaitState == WAITSTATE_PLAYANIM_DUCK)
return;
-#ifdef VC_PED_PORTS
- // VC uses CCamera::Using1stPersonWeaponMode
- if (FindPlayerPed() == this && (TheCamera.PlayerWeaponMode.Mode == CCam::MODE_SNIPER ||
- TheCamera.PlayerWeaponMode.Mode == CCam::MODE_M16_1STPERSON || TheCamera.PlayerWeaponMode.Mode == CCam::MODE_ROCKETLAUNCHER)) {
+ if (FindPlayerPed() == this && TheCamera.Using1stPersonWeaponMode()) {
SetPointGunAt(nil);
- } else
-#endif
- if (bIsPointingGunAt) {
+ } else if (bIsPointingGunAt) {
if (m_pLookTarget)
SetPointGunAt(m_pLookTarget);
else
@@ -417,70 +471,148 @@ CPed::ClearAttack(void)
void
CPed::ClearAttackByRemovingAnim(void)
{
- if (m_nPedState != PED_ATTACK || bIsDucking)
+ if (m_nPedState != PED_ATTACK)
return;
CWeaponInfo *weapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
- CAnimBlendAssociation *weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), weapon->m_AnimToPlay);
- if (!weaponAssoc) {
- weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), weapon->m_Anim2ToPlay);
+ CAnimBlendAssociation *weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetPrimaryFireAnim(weapon));
- if (!weaponAssoc && weapon->IsFlagSet(WEAPONFLAG_THROW))
- weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_THROW_UNDER);
-
- if (!weaponAssoc) {
- ClearAttack();
- return;
- }
+ if (!weaponAssoc) {
+ if (GetCrouchFireAnim(weapon))
+ weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchFireAnim(weapon));
+ }
+ if (!weaponAssoc) {
+ if(GetFinishingAttackAnim(weapon))
+ weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetFinishingAttackAnim(weapon));
+ }
+ if (!weaponAssoc) {
+ if(GetSecondFireAnim(weapon))
+ weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetSecondFireAnim(weapon));
+ }
+ if (!weaponAssoc) {
+ if(Get3rdFireAnim(weapon))
+ weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), Get3rdFireAnim(weapon));
+ }
+ if (weaponAssoc) {
+ weaponAssoc->blendDelta = -8.0f;
+ weaponAssoc->flags &= ~ASSOC_RUNNING;
+ weaponAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ weaponAssoc->SetDeleteCallback(FinishedAttackCB, this);
+ } else {
+ ClearAttack();
}
- weaponAssoc->blendDelta = -8.0f;
- weaponAssoc->flags &= ~ASSOC_RUNNING;
- weaponAssoc->flags |= ASSOC_DELETEFADEDOUT;
- weaponAssoc->SetDeleteCallback(FinishedAttackCB, this);
}
void
CPed::FinishedAttackCB(CAnimBlendAssociation *attackAssoc, void *arg)
{
- CWeaponInfo *currentWeapon;
- CAnimBlendAssociation *newAnim;
+ CAnimBlendAssociation *newAnim, *reloadAnimAssoc = nil;
CPed *ped = (CPed*)arg;
+ CWeaponInfo *currentWeapon = CWeaponInfo::GetWeaponInfo(ped->GetWeapon()->m_eWeaponType);
- if (attackAssoc) {
- switch (attackAssoc->animId) {
- case ANIM_STD_START_THROW:
- // what?!
- if ((!ped->IsPlayer() || ((CPlayerPed*)ped)->m_bHaveTargetSelected) && ped->IsPlayer()) {
- attackAssoc->blendDelta = -1000.0f;
- newAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_THROW_UNDER);
- } else {
- attackAssoc->blendDelta = -1000.0f;
- newAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_WEAPON_THROW);
+ if (ped->m_nPedState != PED_ATTACK) {
+ if (ped->bIsDucking && ped->IsPedInControl()) {
+ if (GetCrouchReloadAnim(currentWeapon)) {
+ reloadAnimAssoc = RpAnimBlendClumpGetAssociation(ped->GetClump(), GetCrouchReloadAnim(currentWeapon));
+ }
+ if (GetCrouchFireAnim(currentWeapon) && attackAssoc) {
+ if (attackAssoc->animId == GetCrouchFireAnim(currentWeapon) && !reloadAnimAssoc) {
+ newAnim = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_DUCK_WEAPON, 8.0f);
+ newAnim->SetCurrentTime(newAnim->hierarchy->totalLength);
+ newAnim->flags &= ~ASSOC_RUNNING;
}
+ }
+ }
+ } else if (attackAssoc && attackAssoc->animId == ANIM_THROWABLE_START_THROW && currentWeapon->m_AnimToPlay == ASSOCGRP_THROW) {
+ if ((!ped->IsPlayer() || ((CPlayerPed*)ped)->m_bHaveTargetSelected) && ped->IsPlayer()) {
+ attackAssoc->blendDelta = -1000.0f;
+ newAnim = CAnimManager::AddAnimation(ped->GetClump(), currentWeapon->m_AnimToPlay, ANIM_THROWABLE_THROWU);
+ } else {
+ attackAssoc->blendDelta = -1000.0;
+ newAnim = CAnimManager::AddAnimation(ped->GetClump(), currentWeapon->m_AnimToPlay, ANIM_THROWABLE_THROW);
+ }
+ newAnim->SetFinishCallback(FinishedAttackCB, ped);
- newAnim->SetFinishCallback(FinishedAttackCB, ped);
- return;
+ } else if (ped->bIsDucking && ped->bCrouchWhenShooting) {
+ if (GetCrouchReloadAnim(currentWeapon)) {
+ reloadAnimAssoc = RpAnimBlendClumpGetAssociation(ped->GetClump(), GetCrouchReloadAnim(currentWeapon));
+ }
+ if (GetCrouchFireAnim(currentWeapon) && attackAssoc) {
+ if (attackAssoc->animId == GetCrouchFireAnim(currentWeapon) && !reloadAnimAssoc) {
+ newAnim = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_DUCK_WEAPON, 8.0f);
+ newAnim->SetCurrentTime(newAnim->hierarchy->totalLength);
+ newAnim->flags &= ~ASSOC_RUNNING;
+ }
+ }
- case ANIM_STD_PARTIAL_PUNCH:
- attackAssoc->blendDelta = -8.0f;
- attackAssoc->flags |= ASSOC_DELETEFADEDOUT;
- ped->ClearAttack();
- return;
+ if (!ped->bIsAttacking)
+ ped->ClearAttack();
- case ANIM_STD_WEAPON_THROW:
- case ANIM_STD_THROW_UNDER:
- if (ped->GetWeapon()->m_nAmmoTotal > 0) {
- currentWeapon = CWeaponInfo::GetWeaponInfo(ped->GetWeapon()->m_eWeaponType);
+ } else if (GetSecondFireAnim(currentWeapon) && ped->bIsAttacking && currentWeapon->m_AnimToPlay != ASSOCGRP_THROW) {
+ AnimationId groundAnim = GetFireAnimGround(currentWeapon);
+ CAnimBlendAssociation *groundAnimAssoc = RpAnimBlendClumpGetAssociation(ped->GetClump(), groundAnim);
+ if (!(groundAnimAssoc && (groundAnimAssoc->blendAmount > 0.95f || groundAnimAssoc->blendDelta > 0.0f))) {
+ if (attackAssoc && attackAssoc->animId == ANIM_MELEE_ATTACK) {
+ newAnim = CAnimManager::BlendAnimation(
+ ped->GetClump(), currentWeapon->m_AnimToPlay, GetSecondFireAnim(currentWeapon), 8.0f);
+ } else {
+ newAnim = CAnimManager::BlendAnimation(
+ ped->GetClump(), currentWeapon->m_AnimToPlay, ANIM_MELEE_ATTACK, 8.0f);
+ }
+ newAnim->SetFinishCallback(FinishedAttackCB, ped);
+ }
+ } else {
+ if (attackAssoc && attackAssoc->animId == ANIM_MELEE_ATTACK && currentWeapon->m_AnimToPlay == ASSOCGRP_UNARMED) {
+ attackAssoc->blendDelta = -8.0f;
+ attackAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ ped->ClearAttack();
+ return;
+ }
+ if (attackAssoc) {
+ if (currentWeapon->m_AnimToPlay == ASSOCGRP_THROW) {
+ if ((attackAssoc->animId == ANIM_THROWABLE_THROW || attackAssoc->animId == ANIM_THROWABLE_THROWU) && ped->GetWeapon()->m_nAmmoTotal > 0) {
+ ped->RemoveWeaponModel(currentWeapon->m_nModelId);
ped->AddWeaponModel(currentWeapon->m_nModelId);
}
- break;
- default:
- break;
+ }
}
+
+ if (!ped->bIsAttacking)
+ ped->ClearAttack();
}
+}
+
+void
+CPed::FinishedReloadCB(CAnimBlendAssociation *reloadAssoc, void *arg)
+{
+ CPed *ped = (CPed*)arg;
+ CWeaponInfo *weapon = CWeaponInfo::GetWeaponInfo(ped->GetWeapon()->m_eWeaponType);
- if (!ped->bIsAttacking)
- ped->ClearAttack();
+ if (ped->DyingOrDead())
+ return;
+
+ if (ped->bIsDucking && ped->bCrouchWhenShooting) {
+ CAnimBlendAssociation *crouchFireAssoc = nil;
+ if (weapon->IsFlagSet(WEAPONFLAG_CROUCHFIRE)) {
+ crouchFireAssoc = RpAnimBlendClumpGetAssociation(ped->GetClump(), GetCrouchFireAnim(weapon));
+ }
+ if (weapon->IsFlagSet(WEAPONFLAG_RELOAD) && reloadAssoc) {
+ if (reloadAssoc->animId == GetCrouchReloadAnim(weapon) && !crouchFireAssoc) {
+ CAnimBlendAssociation *crouchAssoc = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_DUCK_WEAPON, 8.0f);
+ crouchAssoc->SetCurrentTime(crouchAssoc->hierarchy->totalLength);
+ crouchAssoc->flags &= ~ASSOC_RUNNING;
+ }
+ }
+ } else if (weapon->IsFlagSet(WEAPONFLAG_RELOAD_LOOP2START) && ped->bIsAttacking) {
+ CAnimBlendAssociation *fireAssoc =
+ CAnimManager::BlendAnimation(ped->GetClump(), weapon->m_AnimToPlay, GetPrimaryFireAnim(weapon), 8.0f);
+ fireAssoc->SetFinishCallback(FinishedAttackCB, ped);
+ fireAssoc->SetRun();
+ if (fireAssoc->currentTime == reloadAssoc->hierarchy->totalLength)
+ fireAssoc->SetCurrentTime(Max(weapon->m_fAnimLoopStart - 0.04f, 0.0f));
+ else if (fireAssoc->currentTime < weapon->m_fAnimLoopStart)
+ fireAssoc->SetCurrentTime(Max(weapon->m_fAnimLoopStart - 0.04f, 0.0f));
+ }
}
uint8
@@ -496,7 +628,7 @@ CPed::CheckForPointBlankPeds(CPed *pedToVerify)
if (!pedToVerify || pedToVerify == nearPed) {
CVector diff = nearPed->GetPosition() - GetPosition();
- if (diff.Magnitude() < pbDistance) {
+ if (diff.MagnitudeSqr() < SQR(pbDistance)) {
float neededAngle = CGeneral::GetRadianAngleBetweenPoints(
nearPed->GetPosition().x, nearPed->GetPosition().y,
@@ -509,7 +641,9 @@ CPed::CheckForPointBlankPeds(CPed *pedToVerify)
if (neededTurn > PI)
neededTurn = 2*PI - neededTurn;
- if (nearPed->OnGroundOrGettingUp() || nearPed->m_nPedState == PED_DIVE_AWAY)
+ PedState nearPedState = nearPed->m_nPedState;
+
+ if (nearPedState == PED_FALL || nearPedState == PED_GETUP || nearPedState == PED_DIE || nearPedState == PED_DEAD || nearPedState == PED_DIVE_AWAY)
return NO_POINT_BLANK_PED;
if (neededTurn < CAN_SEE_ENTITY_ANGLE_THRESHOLD) {
@@ -529,63 +663,135 @@ CPed::Attack(void)
{
CAnimBlendAssociation *weaponAnimAssoc;
int32 weaponAnim;
- float animStart;
float weaponAnimTime;
float animLoopEnd;
CWeaponInfo *ourWeapon;
bool attackShouldContinue;
- AnimationId reloadAnim;
CAnimBlendAssociation *reloadAnimAssoc;
+ CAnimBlendAssociation *throwAssoc;
float delayBetweenAnimAndFire;
+ float animLoopStart;
CVector firePos;
ourWeapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
- weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ourWeapon->m_AnimToPlay);
- attackShouldContinue = bIsAttacking;
+ weaponAnimAssoc = nil;
+ attackShouldContinue = !!bIsAttacking;
reloadAnimAssoc = nil;
- reloadAnim = ANIM_STD_NUM;
+ throwAssoc = nil;
+ animLoopStart = ourWeapon->m_fAnimLoopStart;
+ animLoopEnd = ourWeapon->m_fAnimLoopEnd;
delayBetweenAnimAndFire = ourWeapon->m_fAnimFrameFire;
weaponAnim = ourWeapon->m_AnimToPlay;
- if (weaponAnim == ANIM_STD_WEAPON_HGUN_BODY)
- reloadAnim = ANIM_STD_HGUN_RELOAD;
- else if (weaponAnim == ANIM_STD_WEAPON_AK_BODY)
- reloadAnim = ANIM_STD_AK_RELOAD;
+ if (bIsDucking) {
+ if(GetCrouchFireAnim(ourWeapon) && bCrouchWhenShooting) {
+ weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchFireAnim(ourWeapon));
+ if (weaponAnimAssoc) {
+ animLoopStart = ourWeapon->m_fAnim2LoopStart;
+ animLoopEnd = ourWeapon->m_fAnim2LoopEnd;
+ delayBetweenAnimAndFire = ourWeapon->m_fAnim2FrameFire;
+ }
+ }
+ } else if (m_nPedType == PEDTYPE_COP && Get3rdFireAnim(ourWeapon)){
+ weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), Get3rdFireAnim(ourWeapon));
+ if (weaponAnimAssoc) {
+ animLoopStart = 11.f/30.f;
+ animLoopEnd = 19.f/30.f;
+ delayBetweenAnimAndFire = 14.f/30.f;
+ }
+ } else {
+ weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetPrimaryFireAnim(ourWeapon));
+ }
- if (reloadAnim != ANIM_STD_NUM)
- reloadAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), reloadAnim);
+ if (GetReloadAnim(ourWeapon)) {
+ reloadAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetReloadAnim(ourWeapon));
+ }
- if (bIsDucking)
- return;
+ if (GetCrouchReloadAnim(ourWeapon) && !reloadAnimAssoc) {
+ reloadAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchReloadAnim(ourWeapon));
+ }
- if (reloadAnimAssoc) {
+ if ( reloadAnimAssoc && reloadAnimAssoc->IsRunning() ) {
if (!IsPlayer() || ((CPlayerPed*)this)->m_bHaveTargetSelected)
ClearAttack();
-
return;
}
- if (CTimer::GetTimeInMilliseconds() < m_shootTimer)
+ if ( reloadAnimAssoc ) {
+ reloadAnimAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ if ( reloadAnimAssoc->blendDelta >= 0.0f )
+ reloadAnimAssoc->blendDelta = -8.0f;
+ }
+
+ if (GetThrowAnim(ourWeapon)) {
+ throwAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetThrowAnim(ourWeapon));
+ }
+
+ if ( CTimer::GetTimeInMilliseconds() < m_shootTimer )
attackShouldContinue = true;
+ bool meleeAttackStarted = false;
+ if ( !weaponAnimAssoc ) {
+ if (GetMeleeStartAnim(ourWeapon)) {
+ weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetMeleeStartAnim(ourWeapon));
+ if ( weaponAnimAssoc ) {
+ if ( IsPlayer() )
+ meleeAttackStarted = true;
+
+ switch ( ourWeapon->m_AnimToPlay ) {
+ case ASSOCGRP_UNARMED:
+ case ASSOCGRP_SCREWDRIVER:
+ case ASSOCGRP_KNIFE:
+ case ASSOCGRP_BASEBALLBAT:
+ case ASSOCGRP_GOLFCLUB:
+ case ASSOCGRP_CHAINSAW:
+ delayBetweenAnimAndFire = 0.2f;
+ animLoopStart = 0.1f;
+ break;
+ default:
+ break;
+ }
+ animLoopEnd = 99.9f;
+ }
+ }
+ }
if (!weaponAnimAssoc) {
- weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ourWeapon->m_Anim2ToPlay);
- delayBetweenAnimAndFire = ourWeapon->m_fAnim2FrameFire;
-
- // Long throw granade, molotov
- if (!weaponAnimAssoc && ourWeapon->IsFlagSet(WEAPONFLAG_THROW)) {
- weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_THROW_UNDER);
- delayBetweenAnimAndFire = 0.2f;
+ if (GetSecondFireAnim(ourWeapon)) {
+ weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetSecondFireAnim(ourWeapon));
+ if (weaponAnimAssoc) {
+ animLoopStart = ourWeapon->m_fAnim2LoopStart;
+ animLoopEnd = ourWeapon->m_fAnim2LoopEnd;
+ delayBetweenAnimAndFire = ourWeapon->m_fAnim2FrameFire;
+ }
+ }
+ }
+ if (!weaponAnimAssoc) {
+ weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetFireAnimGround(ourWeapon));
+ if (weaponAnimAssoc) {
+ animLoopStart = ourWeapon->m_fAnim2LoopStart;
+ animLoopEnd = ourWeapon->m_fAnim2LoopEnd;
+ delayBetweenAnimAndFire = ourWeapon->m_fAnim2FrameFire;
}
+ }
- if (!weaponAnimAssoc) {
+ if (!weaponAnimAssoc) {
+ if (!throwAssoc) {
if (attackShouldContinue) {
if (ourWeapon->m_eWeaponFire != WEAPON_FIRE_PROJECTILE || !IsPlayer() || ((CPlayerPed*)this)->m_bHaveTargetSelected) {
- if (!CGame::nastyGame || ourWeapon->m_eWeaponFire != WEAPON_FIRE_MELEE || CheckForPedsOnGroundToAttack(this, nil) < PED_ON_THE_FLOOR) {
- weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ourWeapon->m_AnimToPlay, 8.0f);
- }
- else {
- weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ourWeapon->m_Anim2ToPlay, 8.0f);
+ if (bCrouchWhenShooting && bIsDucking && GetCrouchFireAnim(ourWeapon)) {
+ weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ourWeapon->m_AnimToPlay, GetCrouchFireAnim(ourWeapon), 8.0f);
+
+ } else if(GetSecondFireAnim(ourWeapon) && CGeneral::GetRandomNumber() & 1){
+ weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ourWeapon->m_AnimToPlay, GetSecondFireAnim(ourWeapon), 8.0f);
+
+ } else if(!CGame::nastyGame || ourWeapon->m_eWeaponFire != WEAPON_FIRE_MELEE ||
+ !GetFireAnimGround(ourWeapon, false) ||
+ CheckForPedsOnGroundToAttack(this, nil) < PED_ON_THE_FLOOR) {
+
+ weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ourWeapon->m_AnimToPlay, GetFireAnimNotDucking(ourWeapon), 8.0f);
+
+ } else {
+ weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ourWeapon->m_AnimToPlay, GetFireAnimGround(ourWeapon, false), 8.0f);
}
weaponAnimAssoc->SetFinishCallback(FinishedAttackCB, this);
@@ -602,79 +808,125 @@ CPed::Attack(void)
} else
FinishedAttackCB(nil, this);
- return;
}
+ return;
}
- animStart = ourWeapon->m_fAnimLoopStart;
+ if (meleeAttackStarted && IsPlayer()) {
+ if (((CPlayerPed*)this)->m_bHaveTargetSelected || ((CPlayerPed*)this)->m_fMoveSpeed < 0.5f) {
+ weaponAnimAssoc->SetRun();
+ } else {
+ if (weaponAnimAssoc->currentTime > animLoopStart && weaponAnimAssoc->currentTime - weaponAnimAssoc->timeStep <= animLoopStart)
+ weaponAnimAssoc->flags &= ~ASSOC_RUNNING;
+ }
+ }
+
+ float animStart = animLoopStart * 0.4f;
weaponAnimTime = weaponAnimAssoc->currentTime;
if (weaponAnimTime > animStart && weaponAnimTime - weaponAnimAssoc->timeStep <= animStart) {
- if (ourWeapon->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM))
+ if (!bIsDucking && !GetFireAnimNotDucking(ourWeapon) && ourWeapon->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM))
m_pedIK.m_flags |= CPedIK::AIMS_WITH_ARM;
else
+#ifdef FREE_CAM
+ if (!IsPlayer() || !((CPlayerPed*)this)->m_bFreeAimActive)
+#endif
m_pedIK.m_flags &= ~CPedIK::AIMS_WITH_ARM;
}
- if (weaponAnimTime <= delayBetweenAnimAndFire || weaponAnimTime - weaponAnimAssoc->timeStep > delayBetweenAnimAndFire || !weaponAnimAssoc->IsRunning()) {
- if (weaponAnimAssoc->speed < 1.0f)
- weaponAnimAssoc->speed = 1.0f;
+ if (GetWeapon()->m_eWeaponType != WEAPONTYPE_CHAINSAW
+ || !meleeAttackStarted && delayBetweenAnimAndFire - 0.5f >= weaponAnimAssoc->currentTime
+ || weaponAnimAssoc->currentTime - weaponAnimAssoc->timeStep > delayBetweenAnimAndFire) {
+
+ if (GetWeapon()->m_eWeaponType == WEAPONTYPE_CHAINSAW) {
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_CHAINSAW_IDLE, 0.0f);
+ } else if (weaponAnimTime <= delayBetweenAnimAndFire || weaponAnimTime - weaponAnimAssoc->timeStep > delayBetweenAnimAndFire || !weaponAnimAssoc->IsRunning()) {
+ if (weaponAnimAssoc->speed < 1.0f)
+ weaponAnimAssoc->speed = 1.0f;
- } else {
- firePos = ourWeapon->m_vecFireOffset;
- if (GetWeapon()->m_eWeaponType == WEAPONTYPE_BASEBALLBAT) {
- if (weaponAnimAssoc->animId == ourWeapon->m_Anim2ToPlay)
- firePos.z = 0.7f * ourWeapon->m_fRadius - 1.0f;
-
- firePos = GetMatrix() * firePos;
- } else if (GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED) {
- TransformToNode(firePos, weaponAnimAssoc->animId == ANIM_STD_KICKGROUND ? PED_FOOTR : PED_HANDR);
} else {
- firePos = GetMatrix() * firePos;
- }
-
- GetWeapon()->Fire(this, &firePos);
+ firePos = ourWeapon->m_vecFireOffset;
- if (GetWeapon()->m_eWeaponType == WEAPONTYPE_MOLOTOV || GetWeapon()->m_eWeaponType == WEAPONTYPE_GRENADE) {
- RemoveWeaponModel(ourWeapon->m_nModelId);
- }
- if (!GetWeapon()->m_nAmmoTotal && ourWeapon->m_eWeaponFire != WEAPON_FIRE_MELEE && FindPlayerPed() != this) {
- SelectGunIfArmed();
- }
+ if(ourWeapon->m_AnimToPlay != ASSOCGRP_BASEBALLBAT && ourWeapon->m_AnimToPlay != ASSOCGRP_GOLFCLUB) {
+ 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;
- if (GetWeapon()->m_eWeaponState != WEAPONSTATE_MELEE_MADECONTACT) {
- // If reloading just began, start the animation
- // Last condition will always return true, even IDA hides it
- if (GetWeapon()->m_eWeaponState == WEAPONSTATE_RELOADING && reloadAnim != ANIM_STD_NUM /* && !reloadAnimAssoc*/) {
- CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, reloadAnim, 8.0f);
- ClearLookFlag();
- ClearAimFlag();
- bIsAttacking = false;
- bIsPointingGunAt = false;
- m_shootTimer = CTimer::GetTimeInMilliseconds();
- return;
+ firePos = GetMatrix() * firePos;
}
- } else {
- if (weaponAnimAssoc->animId == ANIM_STD_WEAPON_BAT_V || weaponAnimAssoc->animId == ANIM_STD_WEAPON_BAT_H) {
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_BAT_ATTACK, 1.0f);
- } else if (weaponAnimAssoc->animId == ANIM_STD_PARTIAL_PUNCH) {
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_FIGHT_PUNCH_39, 0.0f);
+
+ GetWeapon()->Fire(this, &firePos);
+
+ if (GetWeapon()->m_eWeaponType == WEAPONTYPE_MOLOTOV || GetWeapon()->m_eWeaponType == WEAPONTYPE_GRENADE || GetWeapon()->m_eWeaponType == WEAPONTYPE_DETONATOR_GRENADE ||
+ GetWeapon()->m_eWeaponType == WEAPONTYPE_TEARGAS) {
+ RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_nModelId);
+ }
+ if (GetWeapon()->m_nAmmoTotal == 0 && ourWeapon->m_eWeaponFire != WEAPON_FIRE_MELEE && FindPlayerPed() != this) {
+ SelectGunIfArmed();
}
- weaponAnimAssoc->speed = 0.5f;
+ 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)
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_FIGHT_46, (damagerType | (GetWeapon()->m_eWeaponType << 8)));
+ break;
+ case ASSOCGRP_KNIFE:
+ case ASSOCGRP_BASEBALLBAT:
+ case ASSOCGRP_GOLFCLUB:
+ case ASSOCGRP_CHAINSAW:
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_BAT_ATTACK, (damagerType | (GetWeapon()->m_eWeaponType << 8)));
+ break;
+ default:
+ break;
+ }
- if (bIsAttacking || CTimer::GetTimeInMilliseconds() < m_shootTimer) {
- weaponAnimAssoc->callbackType = 0;
+ if (bIsAttacking || CTimer::GetTimeInMilliseconds() < m_shootTimer) {
+ weaponAnimAssoc->callbackType = 0;
+ }
}
+
+ attackShouldContinue = false;
}
+ } else {
+ CVector firePos = ourWeapon->m_vecFireOffset;
+ if (weaponAnimAssoc->animId == ANIM_MELEE_ATTACK_2ND)
+ firePos.z = 0.7f * ourWeapon->m_fRadius - 1.0f;
+
+ firePos = GetMatrix() * firePos;
+ GetWeapon()->Fire(this, &firePos);
+ if (GetWeapon()->m_eWeaponState == WEAPONSTATE_MELEE_MADECONTACT) {
+ int damagerType = ENTITY_TYPE_PED;
+ if (m_pDamageEntity)
+ damagerType = m_pDamageEntity->GetType();
+
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_CHAINSAW_MADECONTACT, (float)damagerType);
+ if (IsPlayer()) {
+ CPad::GetPad(0)->StartShake(240, 180);
+ }
+ } else {
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_CHAINSAW_ATTACK, 0.0f);
+ if (IsPlayer()) {
+ CPad::GetPad(0)->StartShake(240, 90);
+ }
+ }
attackShouldContinue = false;
}
- if (GetWeapon()->m_eWeaponType == WEAPONTYPE_SHOTGUN) {
+ if (ourWeapon->m_eWeaponFire == WEAPON_FIRE_INSTANT_HIT && ourWeapon->m_AnimToPlay == ASSOCGRP_SHOTGUN) {
weaponAnimTime = weaponAnimAssoc->currentTime;
- firePos = ourWeapon->m_vecFireOffset;
if (weaponAnimTime > 1.0f && weaponAnimTime - weaponAnimAssoc->timeStep <= 1.0f && weaponAnimAssoc->IsRunning()) {
+ firePos = ourWeapon->m_vecFireOffset;
TransformToNode(firePos, PED_HANDR);
CVector gunshellPos(
@@ -692,70 +944,103 @@ CPed::Attack(void)
GetWeapon()->AddGunshell(this, gunshellPos, gunshellRot, 0.025f);
}
}
-#ifdef VC_PED_PORTS
+
+ if (IsPlayer()) {
+ if (GetWeapon()->m_eWeaponType == WEAPONTYPE_BASEBALLBAT || GetWeapon()->m_eWeaponType == WEAPONTYPE_GOLFCLUB || GetWeapon()->m_eWeaponType == WEAPONTYPE_KATANA) {
+ float loopEndWithDelay = animLoopEnd;
+ if (loopEndWithDelay >= 98.0f)
+ loopEndWithDelay = (14.0f / 30.0f) + delayBetweenAnimAndFire;
+ if (weaponAnimAssoc->flags & ASSOC_RUNNING) {
+ if (weaponAnimAssoc->currentTime >= animLoopStart && weaponAnimAssoc->currentTime <= loopEndWithDelay)
+ CSpecialFX::AddWeaponStreak(GetWeapon()->m_eWeaponType);
+ }
+ }
+ }
+
+ // Anim breakout on running
if (IsPlayer()) {
if (CPad::GetPad(0)->GetSprint()) {
- // animBreakout is a member of WeaponInfo in VC, so it's me that added the below line.
- float animBreakOut = ((GetWeapon()->m_eWeaponType == WEAPONTYPE_FLAMETHROWER || GetWeapon()->m_eWeaponType == WEAPONTYPE_UZI || GetWeapon()->m_eWeaponType == WEAPONTYPE_SHOTGUN) ? 25 / 30.0f : 99 / 30.0f);
- if (!attackShouldContinue && weaponAnimAssoc->currentTime > animBreakOut) {
+ if (!attackShouldContinue && weaponAnimAssoc->currentTime > ourWeapon->m_fAnimBreakout) {
weaponAnimAssoc->blendDelta = -4.0f;
FinishedAttackCB(nil, this);
return;
}
}
}
-#endif
- animLoopEnd = ourWeapon->m_fAnimLoopEnd;
- if (ourWeapon->m_eWeaponFire == WEAPON_FIRE_MELEE && weaponAnimAssoc->animId == ourWeapon->m_Anim2ToPlay)
- animLoopEnd = 3.4f/6.0f;
weaponAnimTime = weaponAnimAssoc->currentTime;
// Anim loop end, either start the loop again or finish the attack
if (weaponAnimTime > animLoopEnd || !weaponAnimAssoc->IsRunning() && ourWeapon->m_eWeaponFire != WEAPON_FIRE_PROJECTILE) {
-
+ if (GetWeapon()->m_eWeaponState == WEAPONSTATE_RELOADING) {
+ if (GetReloadAnim(ourWeapon) && !reloadAnimAssoc) {
+ if (!CWorld::Players[CWorld::PlayerInFocus].m_bFastReload) {
+ CAnimBlendAssociation *newReloadAssoc = CAnimManager::BlendAnimation(
+ GetClump(), ourWeapon->m_AnimToPlay,
+ bIsDucking && GetCrouchReloadAnim(ourWeapon) ? GetCrouchReloadAnim(ourWeapon) : GetReloadAnim(ourWeapon),
+ 8.0f);
+ newReloadAssoc->SetFinishCallback(FinishedReloadCB, this);
+ }
+ ClearLookFlag();
+ ClearAimFlag();
+ bIsAttacking = false;
+ bIsPointingGunAt = false;
+ m_shootTimer = CTimer::GetTimeInMilliseconds();
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_AK47_BULLET_ECHO, GetWeapon()->m_eWeaponType);
+ return;
+ }
+ }
if (weaponAnimTime - 2.0f * weaponAnimAssoc->timeStep <= animLoopEnd
&& (bIsAttacking || CTimer::GetTimeInMilliseconds() < m_shootTimer)
- && GetWeapon()->m_eWeaponState != WEAPONSTATE_RELOADING) {
+ && (GetWeapon()->m_eWeaponState != WEAPONSTATE_RELOADING
+ || 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())) {
- weaponAnim = weaponAnimAssoc->animId;
- if (ourWeapon->m_eWeaponFire != WEAPON_FIRE_MELEE || CheckForPedsOnGroundToAttack(this, nil) < PED_ON_THE_FLOOR) {
- if (weaponAnim != ourWeapon->m_Anim2ToPlay || weaponAnim == ANIM_STD_RBLOCK_SHOOT) {
- weaponAnimAssoc->Start(ourWeapon->m_fAnimLoopStart);
+ AnimationId fireAnim = GetFireAnimGround(ourWeapon, false);
+ if (weaponAnimAssoc->animId == fireAnim)
+ weaponAnimAssoc->SetCurrentTime(0.1f);
+ else {
+ if (GetFireAnimGround(ourWeapon, false)) {
+ weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ourWeapon->m_AnimToPlay, fireAnim, 8.0f);
+ } else {
+ weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_KICKGROUND, 8.0f);
+ }
+ }
+ weaponAnimAssoc->SetFinishCallback(FinishedAttackCB, this);
+ } else if (GetSecondFireAnim(ourWeapon)) {
+ if (weaponAnimAssoc->animId == GetSecondFireAnim(ourWeapon)) {
+ weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ourWeapon->m_AnimToPlay, ANIM_WEAPON_FIRE, 8.0f);
} else {
- CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ourWeapon->m_AnimToPlay, 8.0f);
+ weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ourWeapon->m_AnimToPlay, GetSecondFireAnim(ourWeapon), 8.0f);
}
+ weaponAnimAssoc->SetFinishCallback(FinishedAttackCB, this);
} else {
- if (weaponAnim == ourWeapon->m_Anim2ToPlay)
- weaponAnimAssoc->SetCurrentTime(0.1f);
- else
- CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ourWeapon->m_Anim2ToPlay, 8.0f);
+ weaponAnimAssoc->SetCurrentTime(animLoopStart);
+ weaponAnimAssoc->SetRun();
}
-#ifdef VC_PED_PORTS
} else if (IsPlayer() && m_pPointGunAt && bIsAimingGun && GetWeapon()->m_eWeaponState != WEAPONSTATE_RELOADING) {
- weaponAnimAssoc->SetCurrentTime(ourWeapon->m_fAnimLoopEnd);
+ weaponAnimAssoc->SetCurrentTime(animLoopEnd);
weaponAnimAssoc->flags &= ~ASSOC_RUNNING;
SetPointGunAt(m_pPointGunAt);
+#ifdef FREE_CAM
+ } else if (IsPlayer() && ((CPlayerPed*)this)->m_bFreeAimActive && GetWeapon()->m_eWeaponState != WEAPONSTATE_RELOADING) {
+ float limitedCam = CGeneral::LimitRadianAngle(-TheCamera.Orientation);
+ SetLookFlag(limitedCam, true, true);
+ SetAimFlag(limitedCam);
+ SetLookTimer(INT32_MAX);
+ SetPointGunAt(nil);
+ ((CPlayerPed*)this)->m_fFPSMoveHeading = TheCamera.Find3rdPersonQuickAimPitch();
#endif
} else {
ClearAimFlag();
// Echoes of bullets, at the end of the attack. (Bug: doesn't play while reloading)
- if (weaponAnimAssoc->currentTime - weaponAnimAssoc->timeStep <= ourWeapon->m_fAnimLoopEnd) {
- switch (GetWeapon()->m_eWeaponType) {
- case WEAPONTYPE_UZI:
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_UZI_BULLET_ECHO, 0.0f);
- break;
- case WEAPONTYPE_AK47:
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_AK47_BULLET_ECHO, 0.0f);
- break;
- case WEAPONTYPE_M16:
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_M16_BULLET_ECHO, 0.0f);
- break;
- default:
- break;
- }
- }
+ if (weaponAnimAssoc->currentTime - weaponAnimAssoc->timeStep < animLoopEnd)
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_AK47_BULLET_ECHO, GetWeapon()->m_eWeaponType);
// Fun fact: removing this part leds to reloading flamethrower
if (GetWeapon()->m_eWeaponType == WEAPONTYPE_FLAMETHROWER && weaponAnimAssoc->IsRunning()) {
@@ -765,6 +1050,7 @@ CPed::Attack(void)
}
}
}
+
if (weaponAnimAssoc->currentTime > delayBetweenAnimAndFire)
attackShouldContinue = false;
@@ -774,7 +1060,7 @@ CPed::Attack(void)
void
CPed::StartFightAttack(uint8 buttonPressure)
{
- if (!IsPedInControl() || m_attackTimer > CTimer::GetTimeInMilliseconds())
+ if (!IsPedInControl() || (m_attackTimer > CTimer::GetTimeInMilliseconds() && buttonPressure != 0))
return;
if (m_nPedState == PED_FIGHT) {
@@ -786,57 +1072,75 @@ CPed::StartFightAttack(uint8 buttonPressure)
SetStoredState();
if (m_nWaitState != WAITSTATE_FALSE) {
- m_nWaitState = WAITSTATE_FALSE;
+ ClearWaitState();
RestoreHeadingRate();
}
- SetPedState(PED_FIGHT);
- m_fightButtonPressure = 0;
- RpAnimBlendClumpRemoveAssociations(GetClump(), ASSOC_REPEAT);
- CAnimBlendAssociation *animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_STARTWALK);
-
- if (animAssoc) {
- animAssoc->flags |= ASSOC_DELETEFADEDOUT;
- animAssoc->blendDelta = -1000.0f;
- }
-
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_RUNSTOP1);
+ CAnimBlendAssociation* animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_RUNSTOP1);
if (!animAssoc)
animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_RUNSTOP2);
if (animAssoc) {
- animAssoc->flags |= ASSOC_DELETEFADEDOUT;
- animAssoc->blendDelta = -1000.0f;
RestoreHeadingRate();
}
-
SetMoveState(PEDMOVE_NONE);
m_nStoredMoveState = PEDMOVE_NONE;
-
- CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_FIGHT_IDLE)->blendAmount = 1.0f;
-
- CPed *pedOnGround = nil;
- if (IsPlayer() && CheckForPedsOnGroundToAttack(this, &pedOnGround) > PED_IN_FRONT_OF_ATTACKER) {
- m_curFightMove = FIGHTMOVE_GROUNDKICK;
- } else if (m_pedStats->m_flags & STAT_SHOPPING_BAGS) {
- m_curFightMove = FIGHTMOVE_ROUNDHOUSE;
+ bool fightWithWeapon = false;
+ CAnimBlendAssociation *fightIdleAssoc;
+
+ CWeaponInfo* weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
+ if (GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED) {
+ if (GetFightIdleWithMeleeAnim(weaponInfo)) {
+ fightIdleAssoc = CAnimManager::BlendAnimation(GetClump(), weaponInfo->m_AnimToPlay, GetFightIdleWithMeleeAnim(weaponInfo), 1000.0f);
+ fightWithWeapon = true;
+ } else {
+ fightIdleAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_FIGHT_IDLE, 1000.0f);
+ }
} else {
- m_curFightMove = FIGHTMOVE_STDPUNCH;
+ fightIdleAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_FIGHT_IDLE, 1000.0f);
}
+ m_lastFightMove = FIGHTMOVE_IDLE;
+ m_curFightMove = IsPlayer() ? ChooseAttackPlayer(buttonPressure, fightWithWeapon) : ChooseAttackAI(buttonPressure, fightWithWeapon);
- if (pedOnGround && IsPlayer()) {
- m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(
- pedOnGround->GetPosition().x, pedOnGround->GetPosition().y,
- GetPosition().x, GetPosition().y);
+ SetPedState(PED_FIGHT);
+ m_fightButtonPressure = 0;
- m_fRotationDest = CGeneral::LimitRadianAngle(m_fRotationDest);
- m_fRotationCur = m_fRotationDest;
- m_lookTimer = 0;
- SetLookFlag(pedOnGround, true);
- SetLookTimer(1500);
+ if (m_curFightMove > FIGHTMOVE_NULL && m_curFightMove != FIGHTMOVE_IDLE) {
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), m_curFightMove < FIGHTMOVE_MELEE1 ? ASSOCGRP_STD : weaponInfo->m_AnimToPlay,
+ tFightMoves[m_curFightMove].animId, 8.0f);
+
+ if (weaponInfo->m_AnimToPlay == ASSOCGRP_KNIFE && m_curFightMove >= FIGHTMOVE_MELEE1) {
+ switch (GetWeapon()->m_eWeaponType) {
+ case WEAPONTYPE_SCREWDRIVER:
+ case WEAPONTYPE_KNIFE:
+ animAssoc->speed = 1.05f;
+ break;
+ case WEAPONTYPE_GOLFCLUB:
+ case WEAPONTYPE_NIGHTSTICK:
+ case WEAPONTYPE_BASEBALLBAT:
+ case WEAPONTYPE_HAMMER:
+ case WEAPONTYPE_KATANA:
+ animAssoc->speed = 0.8f;
+ break;
+ case WEAPONTYPE_CLEAVER:
+ case WEAPONTYPE_MACHETE:
+ animAssoc->speed = 0.9f;
+ break;
+ }
+ } else {
+ if (m_curFightMove == FIGHTMOVE_BACKKICK)
+ animAssoc->speed = 1.15f;
+ else
+ animAssoc->speed = 0.8f;
+ }
+ if (IsPlayer())
+ animAssoc->SetCurrentTime(0.08f);
+
+ animAssoc->SetFinishCallback(FinishFightMoveCB, this);
+ } else {
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 2000;
}
- animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, tFightMoves[m_curFightMove].animId, 4.0f);
- animAssoc->SetFinishCallback(FinishFightMoveCB, this);
+
m_fightState = FIGHTSTATE_NO_MOVE;
m_takeAStepAfterAttack = false;
bIsAttacking = true;
@@ -885,13 +1189,9 @@ CPed::StartFightDefend(uint8 direction, uint8 hitLevel, uint8 unk)
} else if (IsPedInControl()) {
if ((IsPlayer() && m_nPedState != PED_FIGHT && ((CPlayerPed*)this)->m_fMoveSpeed > 1.0f)
|| (!IsPlayer() && m_objective == OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE)) {
-#ifndef VC_PED_PORTS
- if (hitLevel != HITLEVEL_HIGH && hitLevel != HITLEVEL_LOW || (IsPlayer() || CGeneral::GetRandomNumber() & 3) && CGeneral::GetRandomNumber() & 7) {
- if (IsPlayer() || CGeneral::GetRandomNumber() & 3) {
-#else
+
if (hitLevel != HITLEVEL_HIGH && hitLevel != HITLEVEL_LOW || (IsPlayer() || CGeneral::GetRandomNumber() & 1) && CGeneral::GetRandomNumber() & 7) {
if (IsPlayer() || CGeneral::GetRandomNumber() & 1) {
-#endif
AnimationId shotAnim;
switch (direction) {
case 1:
@@ -919,22 +1219,6 @@ CPed::StartFightDefend(uint8 direction, uint8 hitLevel, uint8 unk)
SetWaitState(WAITSTATE_PLAYANIM_DUCK, &time);
}
} else {
-#ifndef VC_PED_PORTS
- switch (direction) {
- case 1:
- SetFall(500, ANIM_STD_HIGHIMPACT_LEFT, false);
- break;
- case 2:
- SetFall(500, ANIM_STD_HIGHIMPACT_BACK, false);
- break;
- case 3:
- SetFall(500, ANIM_STD_HIGHIMPACT_RIGHT, false);
- break;
- default:
- SetFall(500, ANIM_STD_KO_SHOT_STOMACH, false);
- break;
- }
-#else
bool fall = true;
AnimationId hitAnim;
switch (direction) {
@@ -977,7 +1261,6 @@ CPed::StartFightDefend(uint8 direction, uint8 hitLevel, uint8 unk)
hitAssoc->SetRun();
hitAssoc->flags |= ASSOC_FADEOUTWHENDONE;
}
-#endif
}
Say(SOUND_PED_DEFEND);
} else {
@@ -987,20 +1270,15 @@ CPed::StartFightDefend(uint8 direction, uint8 hitLevel, uint8 unk)
m_curFightMove = FIGHTMOVE_HITONFLOOR;
break;
case HITLEVEL_LOW:
-#ifndef VC_PED_PORTS
- if (direction == 2) {
- SetFall(1000, ANIM_STD_HIGHIMPACT_BACK, false);
- return;
- }
-#else
if (direction == 2 && (!IsPlayer() || ((CGeneral::GetRandomNumber() & 1) && m_fHealth < 30.0f))) {
SetFall(1000, ANIM_STD_HIGHIMPACT_BACK, false);
+ Say(SOUND_PED_DEFEND);
return;
} else if (direction != 2 && !IsPlayer() && (CGeneral::GetRandomNumber() & 1) && m_fHealth < 30.0f) {
SetFall(1000, ANIM_STD_KO_SHOT_STOMACH, false);
+ Say(SOUND_PED_DEFEND);
return;
}
-#endif
m_curFightMove = FIGHTMOVE_HITBODY;
break;
case HITLEVEL_HIGH:
@@ -1050,24 +1328,28 @@ CPed::StartFightDefend(uint8 direction, uint8 hitLevel, uint8 unk)
moveAssoc->SetCurrentTime(0.0f);
moveAssoc->SetFinishCallback(FinishFightMoveCB, this);
if (IsPlayer())
- moveAssoc->speed = 1.3f;
+ moveAssoc->speed = 1.2f;
m_takeAStepAfterAttack = false;
m_fightButtonPressure = 0;
- } else if (IsPlayer() && m_currentWeapon != WEAPONTYPE_UNARMED) {
+
+ } else if (IsPlayer() && GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED && GetWeapon()->m_eWeaponType != WEAPONTYPE_BRASSKNUCKLE &&
+ !CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_FIGHTMODE)) {
CAnimBlendAssociation *moveAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, tFightMoves[m_curFightMove].animId, 4.0f);
moveAssoc->SetCurrentTime(0.0f);
- moveAssoc->speed = 1.3f;
+ moveAssoc->speed = 1.2f;
+
} else {
if (m_nPedState != PED_AIM_GUN && m_nPedState != PED_ATTACK)
SetStoredState();
if (m_nWaitState != WAITSTATE_FALSE) {
- m_nWaitState = WAITSTATE_FALSE;
+ ClearWaitState();
RestoreHeadingRate();
}
SetPedState(PED_FIGHT);
m_fightButtonPressure = 0;
+ m_lastFightMove = FIGHTMOVE_IDLE;
RpAnimBlendClumpRemoveAssociations(GetClump(), ASSOC_REPEAT);
CAnimBlendAssociation *walkStartAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_STARTWALK);
if (walkStartAssoc) {
@@ -1084,13 +1366,28 @@ CPed::StartFightDefend(uint8 direction, uint8 hitLevel, uint8 unk)
}
SetMoveState(PEDMOVE_NONE);
m_nStoredMoveState = PEDMOVE_NONE;
- CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_FIGHT_IDLE)->blendAmount = 1.0f;
+ CAnimBlendAssociation *fightIdleAssoc;
+
+ if (GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED) {
+ CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
+ if (GetFightIdleWithMeleeAnim(weaponInfo)) {
+ fightIdleAssoc = CAnimManager::AddAnimation(GetClump(), weaponInfo->m_AnimToPlay, GetFightIdleWithMeleeAnim(weaponInfo));
+ } else {
+ fightIdleAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_FIGHT_IDLE);
+ }
+ } else {
+ fightIdleAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_FIGHT_IDLE);
+ }
+ fightIdleAssoc->blendAmount = 1.0f;
CAnimBlendAssociation *moveAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, tFightMoves[m_curFightMove].animId, 8.0f);
moveAssoc->SetFinishCallback(FinishFightMoveCB, this);
m_fightState = FIGHTSTATE_NO_MOVE;
m_takeAStepAfterAttack = false;
bIsAttacking = true;
}
+
+ if (m_pedInObjective && m_pedInObjective->IsPlayer() && !IsPlayer())
+ ((CPlayerPed*)m_pedInObjective)->RemovePedFromMeleeList(this);
}
}
}
@@ -1099,10 +1396,20 @@ void
CPed::Fight(void)
{
CAnimBlendAssociation *currentAssoc, *animAssoc;
- bool hasShoppingBags, punchOnly, canKick, canKneeHead, canRoundhouse;
- float angleToFace, nextAngle;
- bool goForward = false;
- int nextFightMove;
+ bool fightWithWeapon = false;
+
+ eWeaponType weapon = GetWeapon()->m_eWeaponType;
+ CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(weapon);
+
+ if (weaponInfo->IsFlagSet(WEAPONFLAG_FIGHTMODE) && weapon != WEAPONTYPE_UNARMED) {
+ fightWithWeapon = true;
+ tFightMoves[FIGHTMOVE_MELEE1].startFireTime = weaponInfo->m_fAnimFrameFire;
+ tFightMoves[FIGHTMOVE_MELEE1].endFireTime = weaponInfo->m_fAnimLoopEnd;
+ tFightMoves[FIGHTMOVE_MELEE2].startFireTime = weaponInfo->m_fAnim2FrameFire;
+ tFightMoves[FIGHTMOVE_MELEE2].endFireTime = weaponInfo->m_fAnim2LoopEnd;
+ tFightMoves[FIGHTMOVE_MELEE3].startFireTime = weaponInfo->m_fAnim2FrameFire;
+ tFightMoves[FIGHTMOVE_MELEE3].endFireTime = weaponInfo->m_fAnim2LoopEnd;
+ }
switch (m_curFightMove) {
case FIGHTMOVE_NULL:
@@ -1122,6 +1429,20 @@ CPed::Fight(void)
break;
}
+ if (m_curFightMove == FIGHTMOVE_SHUFFLE_F && !currentAssoc)
+ currentAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_FIGHT_SHUFFLE_B);
+
+ if (IsPlayer() && currentAssoc && weapon == WEAPONTYPE_KATANA) {
+ if (m_curFightMove == FIGHTMOVE_MELEE1 || m_curFightMove == FIGHTMOVE_MELEE2) {
+ static float streakDelay = 0.2f;
+
+ if (tFightMoves[m_curFightMove].startFireTime - streakDelay < currentAssoc->currentTime &&
+ streakDelay + tFightMoves[m_curFightMove].endFireTime > currentAssoc->currentTime) {
+ CSpecialFX::AddWeaponStreak(GetWeapon()->m_eWeaponType);
+ }
+ }
+ }
+
if (!bIsAttacking && IsPlayer()) {
if (currentAssoc) {
currentAssoc->blendDelta = -1000.0f;
@@ -1138,272 +1459,123 @@ CPed::Fight(void)
FightMove &curMove = tFightMoves[m_curFightMove];
if (curMove.hitLevel != HITLEVEL_NULL && animTime > curMove.startFireTime && animTime <= curMove.endFireTime && m_fightState >= FIGHTSTATE_NO_MOVE) {
+ if (animTime > curMove.startFireTime && animTime - currentAssoc->timeStep < curMove.startFireTime &&
+ (IsPlayer() || weapon != WEAPONTYPE_UNARMED)) {
+
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_MELEE_ATTACK_START, weapon << 8);
+ }
+
CVector touchingNodePos(0.0f, 0.0f, 0.0f);
switch (m_curFightMove) {
- case FIGHTMOVE_STDPUNCH:
- case FIGHTMOVE_PUNCHHOOK:
- case FIGHTMOVE_BODYBLOW:
- TransformToNode(touchingNodePos, PED_HANDR);
- break;
- case FIGHTMOVE_IDLE:
- case FIGHTMOVE_SHUFFLE_F:
- break;
case FIGHTMOVE_KNEE:
TransformToNode(touchingNodePos, PED_LOWERLEGR);
break;
- case FIGHTMOVE_HEADBUTT:
- TransformToNode(touchingNodePos, PED_HEAD);
- break;
+ case FIGHTMOVE_PUNCHHOOK:
case FIGHTMOVE_PUNCHJAB:
TransformToNode(touchingNodePos, PED_HANDL);
break;
- case FIGHTMOVE_KICK:
case FIGHTMOVE_LONGKICK:
case FIGHTMOVE_ROUNDHOUSE:
+ case FIGHTMOVE_FWDLEFT:
+ case FIGHTMOVE_BACKRIGHT:
case FIGHTMOVE_GROUNDKICK:
TransformToNode(touchingNodePos, PED_FOOTR);
break;
+ case FIGHTMOVE_FWDRIGHT:
+ TransformToNode(touchingNodePos, PED_HEAD);
+ break;
+ case FIGHTMOVE_BACKKICK:
+ case FIGHTMOVE_BACKFLIP:
+ TransformToNode(touchingNodePos, PED_FOOTL);
+ break;
+ case FIGHTMOVE_BACKLEFT:
+ TransformToNode(touchingNodePos, PED_UPPERARML);
+ break;
+ default:
+ TransformToNode(touchingNodePos, PED_HANDR);
+ break;
}
- if (m_curFightMove == FIGHTMOVE_PUNCHJAB) {
- touchingNodePos += 0.1f * GetForward();
- } else if (m_curFightMove == FIGHTMOVE_PUNCHHOOK) {
- touchingNodePos += 0.22f * GetForward();
- }
- FightStrike(touchingNodePos);
+ FightStrike(touchingNodePos, fightWithWeapon);
m_fightButtonPressure = 0;
return;
}
if (curMove.hitLevel != HITLEVEL_NULL) {
- if (animTime > curMove.endFireTime) {
+ if (animTime > curMove.endFireTime && weaponInfo->m_AnimToPlay != ASSOCGRP_KNIFE) {
if (IsPlayer())
currentAssoc->speed = 1.0f;
else
currentAssoc->speed = 0.8f;
}
- if (IsPlayer() && !nPlayerInComboMove) {
+ if (IsPlayer() && !nPlayerInComboMove && !fightWithWeapon) {
if (curMove.comboFollowOnTime > 0.0f && m_fightButtonPressure != 0 && animTime > curMove.comboFollowOnTime) {
+ m_lastFightMove = m_curFightMove;
// Notice that it increases fight move index, because we're in combo!
animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, tFightMoves[++m_curFightMove].animId, 8.0f);
animAssoc->SetFinishCallback(FinishFightMoveCB, this);
animAssoc->SetCurrentTime(0.1f * animAssoc->hierarchy->totalLength);
+ animAssoc->speed = 0.8f;
m_fightButtonPressure = 0;
nPlayerInComboMove = 1;
}
}
- } else {
- if (curMove.startFireTime > 0.0f && m_curFightMove != FIGHTMOVE_SHUFFLE_F && animTime > curMove.startFireTime) {
- if (IsPlayer())
- currentAssoc->speed = 1.3f;
- else
- currentAssoc->speed = 0.8f;
- }
}
- } else if (GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED) {
+
+ } else if (GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED && GetWeapon()->m_eWeaponType != WEAPONTYPE_BRASSKNUCKLE && !fightWithWeapon) {
EndFight(ENDFIGHT_FAST);
} else if (m_fightButtonPressure != 0) {
- bool canAffectMultiplePeople = true;
- nextAngle = m_fRotationCur;
- bool kickGround = false;
- float angleForGroundKick = 0.0f;
- CPed *pedOnGround = nil;
-
- Say(SOUND_PED_ATTACK);
-
- if (IsPlayer()) {
- canRoundhouse = false;
- punchOnly = false;
- canKick = true;
- nextFightMove = (m_fightButtonPressure > 190 ? FIGHTMOVE_HEADBUTT : FIGHTMOVE_KNEE);
- hasShoppingBags = false;
- canKneeHead = true;
- nPlayerInComboMove = 0;
- } else {
- nextFightMove = (m_fightButtonPressure > 120 ? FIGHTMOVE_HEADBUTT : FIGHTMOVE_KNEE);
- uint16 pedFeatures = m_pedStats->m_flags;
- punchOnly = pedFeatures & STAT_PUNCH_ONLY;
- canRoundhouse = pedFeatures & STAT_CAN_ROUNDHOUSE;
- canKneeHead = pedFeatures & STAT_CAN_KNEE_HEAD;
- canKick = pedFeatures & STAT_CAN_KICK;
- hasShoppingBags = pedFeatures & STAT_SHOPPING_BAGS;
- }
-
- // Attack isn't scripted, find the victim
- if (IsPlayer() || !m_pedInObjective) {
-
- for (int i = 0; i < m_numNearPeds; i++) {
-
- CPed *nearPed = m_nearPeds[i];
- float nearPedDist = (nearPed->GetPosition() - GetPosition()).Magnitude();
- if (nearPedDist < 3.0f) {
- float angleToFace = CGeneral::GetRadianAngleBetweenPoints(
- nearPed->GetPosition().x, nearPed->GetPosition().y,
- GetPosition().x, GetPosition().y);
-
- nextAngle = CGeneral::LimitRadianAngle(angleToFace);
- m_fRotationCur = CGeneral::LimitRadianAngle(m_fRotationCur);
-
- float neededTurn = Abs(nextAngle - m_fRotationCur);
- if (neededTurn > PI)
- neededTurn = TWOPI - neededTurn;
+ if (!IsPlayer())
+ Say(SOUND_PED_ATTACK);
- if (!nearPed->OnGroundOrGettingUp()) {
+ if (m_curFightMove != FIGHTMOVE_IDLE)
+ m_lastFightMove = m_curFightMove;
- if (nearPedDist < 0.8f && neededTurn < DEGTORAD(75.0f) && canKneeHead) {
- canAffectMultiplePeople = false;
- } else if (nearPedDist >= 1.3f || neededTurn >= DEGTORAD(55.0f) || hasShoppingBags) {
+ m_curFightMove = IsPlayer() ? ChooseAttackPlayer(m_fightButtonPressure, fightWithWeapon) : ChooseAttackAI(m_fightButtonPressure, fightWithWeapon);
- if (nearPedDist < 1.7f
- && neededTurn < DEGTORAD(35.0f)
- && (canKick || hasShoppingBags)) {
+ if (m_curFightMove != FIGHTMOVE_IDLE) {
- nextFightMove = FIGHTMOVE_KICK;
- if (hasShoppingBags) {
- nextFightMove = FIGHTMOVE_ROUNDHOUSE;
- } else if (canRoundhouse && CGeneral::GetRandomNumber() & 1) {
- nextFightMove = FIGHTMOVE_ROUNDHOUSE;
- }
- canAffectMultiplePeople = false;
- } else if (nearPedDist < 2.0f && neededTurn < DEGTORAD(30.0f) && canKick) {
- canAffectMultiplePeople = false;
- nextFightMove = FIGHTMOVE_LONGKICK;
- } else if (neededTurn < DEGTORAD(30.0f)) {
- goForward = true;
- }
- } else {
- nextFightMove += 2; // Makes it 6 or 7
- if (punchOnly)
- nextFightMove = FIGHTMOVE_PUNCHJAB;
-
- canAffectMultiplePeople = false;
- }
- } else if (!CGame::nastyGame
- || nearPedDist >= 1.3f
- || neededTurn >= DEGTORAD(55.0f)
- || punchOnly) {
-
- if (nearPedDist > 0.8f
- && nearPedDist < 3.0f
- && neededTurn < DEGTORAD(30.0f)) {
- goForward = true;
- }
-
- } else if (nearPed->m_nPedState != PED_DEAD || pedOnGround) {
- if (!nearPed->IsPedHeadAbovePos(-0.3f)) {
- canAffectMultiplePeople = false;
- nextFightMove = FIGHTMOVE_GROUNDKICK;
- }
-
- } else {
- pedOnGround = nearPed;
- kickGround = true;
- angleForGroundKick = nextAngle;
- }
- }
-
- if (!canAffectMultiplePeople) {
- m_fRotationDest = nextAngle;
- if (IsPlayer()) {
- m_fRotationCur = m_fRotationDest;
- m_lookTimer = 0;
- SetLookFlag(nearPed, true);
- SetLookTimer(1500);
- }
- break;
- }
- }
- } else {
- // Because we're in a scripted fight with some particular ped.
- canAffectMultiplePeople = false;
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), m_curFightMove < FIGHTMOVE_MELEE1 ? ASSOCGRP_STD : weaponInfo->m_AnimToPlay,
+ tFightMoves[m_curFightMove].animId, 8.0f);
- float fightingPedDist = (m_pedInObjective->GetPosition() - GetPosition()).Magnitude();
- if (hasShoppingBags) {
- if (fightingPedDist >= 1.7f)
- nextFightMove = FIGHTMOVE_SHUFFLE_F;
+ if (weaponInfo->m_AnimToPlay != ASSOCGRP_KNIFE || m_curFightMove < FIGHTMOVE_MELEE1) {
+ if (m_curFightMove == FIGHTMOVE_BACKKICK)
+ animAssoc->speed = 1.15f;
else
- nextFightMove = FIGHTMOVE_ROUNDHOUSE;
-
- } else if (punchOnly) {
- if (fightingPedDist >= 1.3f)
- nextFightMove = FIGHTMOVE_SHUFFLE_F;
- else
- nextFightMove = FIGHTMOVE_PUNCHJAB;
-
- } else if (fightingPedDist >= 3.0f) {
- nextFightMove = FIGHTMOVE_STDPUNCH;
-
+ animAssoc->speed = 0.8f;
} else {
- angleToFace = CGeneral::GetRadianAngleBetweenPoints(
- m_pedInObjective->GetPosition().x,
- m_pedInObjective->GetPosition().y,
- GetPosition().x,
- GetPosition().y);
-
- nextAngle = CGeneral::LimitRadianAngle(angleToFace);
- m_fRotationDest = nextAngle;
- m_fRotationCur = m_fRotationDest;
- if (!m_pedInObjective->OnGroundOrGettingUp()) {
-
- if (fightingPedDist >= 0.8f || !canKneeHead) {
-
- if (fightingPedDist >= 1.3f) {
-
- if (fightingPedDist < 1.7f && canKick) {
- nextFightMove = FIGHTMOVE_KICK;
- if (canRoundhouse && CGeneral::GetRandomNumber() & 1)
- nextFightMove = FIGHTMOVE_ROUNDHOUSE;
-
- } else if (fightingPedDist < 2.0f && canKick) {
- nextFightMove += 5; // Makes it 9 or 10
-
- } else {
- nextFightMove = FIGHTMOVE_SHUFFLE_F;
-
- }
- } else {
- nextFightMove += 2; // Makes it 6 or 7
- }
- }
- } else if (!CGame::nastyGame
- || fightingPedDist >= 1.3f
- || m_pedInObjective->IsPlayer()
- || m_pedInObjective->m_nPedState != PED_DEAD && m_pedInObjective->IsPedHeadAbovePos(-0.3f)) {
- nextFightMove = FIGHTMOVE_IDLE;
- } else {
- nextFightMove = FIGHTMOVE_GROUNDKICK;
+ switch (GetWeapon()->m_eWeaponType) {
+ case WEAPONTYPE_SCREWDRIVER:
+ case WEAPONTYPE_KNIFE:
+ animAssoc->speed = 1.05f;
+ break;
+ case WEAPONTYPE_GOLFCLUB:
+ case WEAPONTYPE_NIGHTSTICK:
+ case WEAPONTYPE_BASEBALLBAT:
+ case WEAPONTYPE_HAMMER:
+ case WEAPONTYPE_KATANA:
+ animAssoc->speed = 0.8f;
+ break;
+ case WEAPONTYPE_CLEAVER:
+ case WEAPONTYPE_MACHETE:
+ animAssoc->speed = 0.9f;
+ break;
}
}
- }
-
- if (canAffectMultiplePeople) {
- if (kickGround && IsPlayer()) {
- m_fRotationDest = angleForGroundKick;
- nextFightMove = FIGHTMOVE_GROUNDKICK;
- m_fRotationCur = m_fRotationDest;
- m_lookTimer = 0;
- SetLookFlag(pedOnGround, true);
- SetLookTimer(1500);
- } else if (goForward) {
- nextFightMove = FIGHTMOVE_SHUFFLE_F;
- } else {
- nextFightMove = FIGHTMOVE_STDPUNCH;
- }
- }
-
- if (nextFightMove != FIGHTMOVE_IDLE) {
- m_curFightMove = nextFightMove;
- animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, tFightMoves[m_curFightMove].animId, 4.0f);
- animAssoc->SetFinishCallback(FinishFightMoveCB, this);
if (m_fightState == FIGHTSTATE_MOVE_FINISHED && animAssoc->currentTime != 0.0f) {
- animAssoc->SetCurrentTime(0.0f);
animAssoc->SetRun();
+ if (!IsPlayer())
+ animAssoc->SetCurrentTime(0.0f);
}
+ if (IsPlayer())
+ animAssoc->SetCurrentTime(0.08f);
+
+ animAssoc->SetFinishCallback(FinishFightMoveCB, this);
m_fightButtonPressure = 0;
}
m_fightState = FIGHTSTATE_NO_MOVE;
@@ -1413,6 +1585,7 @@ CPed::Fight(void)
#else
&& CheckForPedsOnGroundToAttack(this, nil) == PED_IN_FRONT_OF_ATTACKER) {
#endif
+ m_lastFightMove = m_curFightMove;
m_curFightMove = FIGHTMOVE_SHUFFLE_F;
animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), tFightMoves[m_curFightMove].animId);
@@ -1437,6 +1610,7 @@ CPed::Fight(void)
}
} else {
+ m_lastFightMove = m_curFightMove;
m_curFightMove = FIGHTMOVE_IDLE;
if (IsPlayer())
m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 500;
@@ -1445,6 +1619,332 @@ CPed::Fight(void)
}
}
+int32
+CPed::ChooseAttackAI(uint8 buttonPressure, bool fightWithWeapon)
+{
+ eWeaponType weapon = GetWeapon()->m_eWeaponType;
+ CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(weapon);
+ if (!fightWithWeapon && weapon != WEAPONTYPE_UNARMED && weapon != WEAPONTYPE_BRASSKNUCKLE) {
+ return FIGHTMOVE_PUNCH;
+ }
+
+ if (!m_pedInObjective)
+ return FIGHTMOVE_IDLE;
+ if (buttonPressure == 0)
+ return FIGHTMOVE_IDLE;
+
+ uint16 pedFeatures = m_pedStats->m_flags;
+ bool punchOnly = !!(pedFeatures & STAT_PUNCH_ONLY);
+ bool canRoundhouse = !!(pedFeatures & STAT_CAN_ROUNDHOUSE);
+ bool canKneeHead = !!(pedFeatures & STAT_CAN_KNEE_HEAD);
+ bool canKick = !!(pedFeatures & STAT_CAN_KICK);
+ bool hasShoppingBags = !!(pedFeatures & STAT_SHOPPING_BAGS);
+
+ CVector distVec(m_pedInObjective->GetPosition() - GetPosition());
+ float dist = distVec.Magnitude();
+ m_fRotationDest = CGeneral::LimitRadianAngle(distVec.Heading());
+ m_fRotationCur = m_fRotationDest;
+
+ if (fightWithWeapon) {
+ if (m_pedInObjective->OnGroundOrGettingUp()) {
+ if (CGame::nastyGame && dist < 1.2f && !m_pedInObjective->IsPlayer()
+ && (m_pedInObjective->m_nPedState == PED_DEAD || !m_pedInObjective->IsPedHeadAbovePos(-0.3f))) {
+ if (weaponInfo->IsFlagSet(WEAPONFLAG_GROUND_2ND))
+ return FIGHTMOVE_MELEE2;
+ if (weaponInfo->IsFlagSet(WEAPONFLAG_GROUND_3RD))
+ return FIGHTMOVE_MELEE3;
+
+ return FIGHTMOVE_GROUNDKICK;
+ } else {
+ return FIGHTMOVE_IDLE;
+ }
+ }
+ if (dist < 2.f) {
+ if (m_curFightMove == FIGHTMOVE_MELEE1) {
+ if (GetSecondFireAnim(weaponInfo))
+ return FIGHTMOVE_MELEE2;
+ }
+ if (m_curFightMove == FIGHTMOVE_MELEE2) {
+ if (GetFinishingAttackAnim(weaponInfo))
+ return FIGHTMOVE_MELEE3;
+ }
+ return FIGHTMOVE_MELEE1;
+ }
+ return FIGHTMOVE_SHUFFLE_F;
+ }
+ if (!hasShoppingBags) {
+ if (punchOnly) {
+ if (dist < 1.4f)
+ return FIGHTMOVE_PUNCH;
+ } else {
+ if (m_pedInObjective->OnGroundOrGettingUp()) {
+ if (CGame::nastyGame && dist < 1.2f && !m_pedInObjective->IsPlayer()
+ && (m_pedInObjective->m_nPedState == PED_DEAD || !m_pedInObjective->IsPedHeadAbovePos(-0.3f))) {
+
+ return FIGHTMOVE_GROUNDKICK;
+ } else {
+ return FIGHTMOVE_IDLE;
+ }
+ }
+ if (dist < 0.95f && canKneeHead)
+ return FIGHTMOVE_KNEE;
+ if (dist < 1.4f)
+ return FIGHTMOVE_PUNCH;
+ if (dist < 2.f && canKick) {
+ int nextMove = FIGHTMOVE_LONGKICK;
+ if (canRoundhouse && CGeneral::GetRandomNumber() & 1)
+ nextMove = FIGHTMOVE_ROUNDHOUSE;
+ return nextMove;
+ }
+ }
+ return FIGHTMOVE_SHUFFLE_F;
+ }
+ if (dist < 2.f)
+ return FIGHTMOVE_ROUNDHOUSE;
+ else
+ return FIGHTMOVE_SHUFFLE_F;
+}
+
+int32
+CPed::ChooseAttackPlayer(uint8 buttonPressure, bool fightWithWeapon)
+{
+ CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
+ const float maxAttackDist = 2.7f;
+ float weaponAttackDist = 2.0f;
+ CPed *victimPed = nil;
+ CPed *walkUpTo = nil;
+ CPed *groundAttackDeadPed = nil;
+ CPed *groundAttackAlivePed = nil;
+ if (fightWithWeapon)
+ weaponAttackDist = weaponInfo->m_fRange;
+
+ bool willWalkUp = false;
+ PedFightMoves choosenMove = FIGHTMOVE_IDLE;
+ int numPedsWeCanReach = 0;
+ if (m_takeAStepAfterAttack)
+ willWalkUp = true;
+
+ float groundAttackDeadAngle, groundAttackAliveAngle, walkAngle, victimAngle, distToVictim;
+
+ for (int i = 0; i < m_numNearPeds; ++i) {
+ CPed *nearPed = m_nearPeds[i];
+ CVector distVec(nearPed->GetPosition() - GetPosition());
+ float dist = distVec.Magnitude();
+ if (dist < maxAttackDist) {
+ float nearPedAngle = CGeneral::LimitRadianAngle(distVec.Heading());
+ m_fRotationCur = CGeneral::LimitRadianAngle(m_fRotationCur);
+ float neededTurn = Abs(nearPedAngle - m_fRotationCur);
+ if (neededTurn > PI)
+ neededTurn = TWOPI - neededTurn;
+
+ if (!nearPed->OnGroundOrGettingUp() && nearPed->m_nWaitState != WAITSTATE_SUN_BATHE_IDLE) {
+ if (!willWalkUp || neededTurn <= DEGTORAD(45.0f)) {
+
+ if (neededTurn <= DEGTORAD(30.0f) || nearPed->m_pedInObjective == this
+ && (nearPed->m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT || nearPed->m_objective == OBJECTIVE_KILL_CHAR_ANY_MEANS)) {
+
+ if (dist < weaponAttackDist) {
+ if (!victimPed
+ || nearPed->m_attackTimer < victimPed->m_attackTimer && nearPed->m_attackTimer > CTimer::GetTimeInMilliseconds() - 100) {
+ victimPed = nearPed;
+ victimAngle = nearPedAngle;
+ distToVictim = dist;
+ }
+ ++numPedsWeCanReach;
+
+ } else {
+ if (neededTurn < DEGTORAD(30.0f)) {
+ walkUpTo = nearPed;
+ walkAngle = nearPedAngle;
+ }
+ }
+ }
+ }
+ } else if (CGame::nastyGame && dist < 1.2f && neededTurn < DEGTORAD(55.0f)) {
+ if (!nearPed->DyingOrDead() || groundAttackDeadPed) {
+ if (!nearPed->IsPedHeadAbovePos(-0.3f)) {
+ groundAttackAlivePed = nearPed;
+ groundAttackAliveAngle = nearPedAngle;
+ }
+ } else {
+ groundAttackDeadPed = nearPed;
+ groundAttackDeadAngle = nearPedAngle;
+ }
+ ++numPedsWeCanReach;
+
+ } else if (dist > 1.4f && dist < maxAttackDist && neededTurn < DEGTORAD(30.0f)) {
+ if (!walkUpTo) {
+ walkUpTo = nearPed;
+ walkAngle = nearPedAngle;
+ }
+#ifdef FIX_BUGS
+ if(dist < 2.1f)
+#endif
+ ++numPedsWeCanReach;
+ }
+ }
+ }
+
+ if (victimPed) {
+ float adjustedAngleDiff = victimAngle - m_fRotationCur + DEGTORAD(30.0f);
+ if (adjustedAngleDiff < 0.0f)
+ adjustedAngleDiff += TWOPI;
+
+ int16 dir = Floor(adjustedAngleDiff / DEGTORAD(60.0f));
+
+ // Just focus on who we're fighting with, don't care peds on ground
+ if (numPedsWeCanReach < 2 || fightWithWeapon) {
+ float angleDiff = Abs(victimAngle - m_fRotationCur);
+ if (angleDiff > PI)
+ angleDiff = TWOPI - angleDiff;
+
+ if (angleDiff < DEGTORAD(60.0f))
+ dir = 0; // forward
+ }
+ int16 randVal = CGeneral::GetRandomNumber() & 3;
+ switch (dir) {
+ case 0: // forward
+ if (fightWithWeapon) {
+ if (distToVictim < 0.95f - 0.2f && m_nPedState == PED_FIGHT) {
+ choosenMove = FIGHTMOVE_KNEE;
+ } else {
+ if (GetWeapon()->m_eWeaponType == WEAPONTYPE_CLEAVER) {
+ if (distToVictim < 0.85f * weaponInfo->m_fRange)
+ choosenMove = FIGHTMOVE_MELEE1;
+ else
+ choosenMove = FIGHTMOVE_SHUFFLE_F;
+ } else {
+ float weaponRange = weaponInfo->m_fRange;
+ if (distToVictim < 0.75f * weaponRange && GetWeapon()->m_eWeaponType != WEAPONTYPE_SCREWDRIVER) {
+ if (m_lastFightMove == FIGHTMOVE_MELEE1 && GetFinishingAttackAnim(weaponInfo)) {
+ choosenMove = FIGHTMOVE_MELEE2;
+ } else if (m_lastFightMove == FIGHTMOVE_MELEE2 && GetFinishingAttackAnim(weaponInfo)) {
+ choosenMove = FIGHTMOVE_MELEE3;
+ } else {
+ choosenMove = FIGHTMOVE_MELEE1;
+ }
+ } else if (distToVictim < weaponRange && GetFinishingAttackAnim(weaponInfo)) {
+ choosenMove = FIGHTMOVE_MELEE3;
+ } else {
+ choosenMove = FIGHTMOVE_SHUFFLE_F;
+ }
+ }
+ }
+ } else if (distToVictim < 0.95f && m_nPedState == PED_FIGHT) {
+ choosenMove = FIGHTMOVE_KNEE;
+
+ } else if (distToVictim < 1.4f) {
+ if (m_curFightMove == FIGHTMOVE_PUNCHJAB) {
+ choosenMove = FIGHTMOVE_PUNCH;
+
+ } else if (m_curFightMove != FIGHTMOVE_PUNCH || randVal != 1) {
+ if (randVal == 2)
+ choosenMove = FIGHTMOVE_PUNCH;
+ else
+ choosenMove = FIGHTMOVE_PUNCHJAB;
+ } else {
+ choosenMove = FIGHTMOVE_LONGKICK;
+ }
+ } else {
+ choosenMove = FIGHTMOVE_LONGKICK;
+ }
+ break;
+ case 1:
+ choosenMove = FIGHTMOVE_FWDLEFT;
+ break;
+ case 2:
+ choosenMove = FIGHTMOVE_BACKLEFT;
+ break;
+ case 3:
+ choosenMove = FIGHTMOVE_BACKKICK;
+ break;
+ case 4:
+ choosenMove = FIGHTMOVE_BACKRIGHT;
+ break;
+ default:
+ choosenMove = FIGHTMOVE_FWDRIGHT;
+ break;
+ }
+
+ // forward
+ if (dir == 0) {
+ m_fRotationDest = CGeneral::LimitRadianAngle(victimAngle);
+ } else {
+ m_fRotationDest = victimAngle - dir * DEGTORAD(60.0f);
+ m_fRotationDest = CGeneral::LimitRadianAngle(m_fRotationDest);
+ }
+
+ m_fRotationCur = m_fRotationDest;
+ Say(SOUND_PED_ATTACK);
+
+ } else if (groundAttackAlivePed || groundAttackDeadPed) {
+ if (fightWithWeapon && weaponInfo->IsFlagSet(WEAPONFLAG_GROUND_2ND)) {
+ choosenMove = FIGHTMOVE_MELEE2;
+ } else if (fightWithWeapon && weaponInfo->IsFlagSet(WEAPONFLAG_GROUND_3RD)) {
+ choosenMove = FIGHTMOVE_MELEE3;
+ } else {
+ choosenMove = FIGHTMOVE_GROUNDKICK;
+ }
+ if (groundAttackAlivePed)
+ m_fRotationDest = groundAttackAliveAngle;
+ else
+ m_fRotationDest = groundAttackDeadAngle;
+
+ m_fRotationCur = m_fRotationDest;
+ m_lookTimer = 0;
+ if (groundAttackAlivePed)
+ SetLookFlag(groundAttackAlivePed, 1, 0);
+ else
+ SetLookFlag(groundAttackDeadPed, 1, 0);
+
+ SetLookTimer(1500u);
+
+ } else if (walkUpTo) {
+ choosenMove = FIGHTMOVE_SHUFFLE_F;
+ m_fRotationCur = m_fRotationDest = walkAngle;
+ m_lookTimer = 0;
+ SetLookFlag(walkUpTo, true);
+ SetLookTimer(1500);
+
+ } else if (fightWithWeapon) {
+ // No enemy, fight with space
+ if (GetWeapon()->m_eWeaponType == WEAPONTYPE_SCREWDRIVER) {
+ choosenMove = FIGHTMOVE_MELEE3;
+ } else {
+ if (m_lastFightMove == FIGHTMOVE_MELEE1 && GetFinishingAttackAnim(weaponInfo)) {
+ choosenMove = FIGHTMOVE_MELEE2;
+ } else if (m_lastFightMove == FIGHTMOVE_MELEE2 && GetFinishingAttackAnim(weaponInfo)) {
+ choosenMove = FIGHTMOVE_MELEE3;
+ } else {
+ choosenMove = FIGHTMOVE_MELEE1;
+ }
+ }
+ } else {
+ // Max number GetRandomNumberInRange returns is max-1
+#ifdef FIX_BUGS
+ switch (CGeneral::GetRandomNumberInRange(0,4)) {
+#else
+ switch (CGeneral::GetRandomNumberInRange(0,3)) {
+#endif
+ case 0:
+ choosenMove = FIGHTMOVE_PUNCHJAB;
+ break;
+ case 1:
+ choosenMove = FIGHTMOVE_PUNCH;
+ break;
+ case 2:
+ choosenMove = FIGHTMOVE_LONGKICK;
+ break;
+ case 3:
+ choosenMove = FIGHTMOVE_KNEE;
+ break;
+ default:
+ break;
+ }
+ }
+ return choosenMove;
+}
+
void
CPed::EndFight(uint8 endType)
{
@@ -1454,6 +1954,9 @@ CPed::EndFight(uint8 endType)
m_curFightMove = FIGHTMOVE_NULL;
RestorePreviousState();
CAnimBlendAssociation *animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_FIGHT_IDLE);
+ if (!animAssoc)
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_MELEE_IDLE_FIGHTMODE);
+
if (animAssoc)
animAssoc->flags |= ASSOC_DELETEFADEDOUT;
@@ -1476,49 +1979,66 @@ CPed::EndFight(uint8 endType)
m_nWaitTimer = 0;
}
-
void
CPed::PlayHitSound(CPed *hitTo)
{
// That was very complicated to reverse for me...
- // First index is our fight move ID (from 1 to 12, total 12), second is the one of we fight with (from 13 to 22, total 10).
+ // First index is our fight move ID (from 1 to 17, total 17), second is the one of we fight with (from 18 to 27, total 10).
enum {
- S33 = SOUND_FIGHT_PUNCH_33,
- S34 = SOUND_FIGHT_KICK_34,
- S35 = SOUND_FIGHT_HEADBUTT_35,
- S36 = SOUND_FIGHT_PUNCH_36,
- S37 = SOUND_FIGHT_PUNCH_37,
- S38 = SOUND_FIGHT_CLOSE_PUNCH_38,
- S39 = SOUND_FIGHT_PUNCH_39,
- S40 = SOUND_FIGHT_PUNCH_OR_KICK_BELOW_40 ,
- S41 = SOUND_FIGHT_PUNCH_41,
- S42 = SOUND_FIGHT_PUNCH_FROM_BEHIND_42,
- S43 = SOUND_FIGHT_KNEE_OR_KICK_43,
- S44 = SOUND_FIGHT_KICK_44,
+ S37 = SOUND_FIGHT_37,
+ S38 = SOUND_FIGHT_38,
+ S39 = SOUND_FIGHT_39,
+ S40 = SOUND_FIGHT_40,
+ S41 = SOUND_FIGHT_41,
+ S42 = SOUND_FIGHT_42,
+ S43 = SOUND_FIGHT_43,
+ S44 = SOUND_FIGHT_44,
+ S45 = SOUND_FIGHT_45,
+ S46 = SOUND_FIGHT_46,
+ S47 = SOUND_FIGHT_47,
+ S48 = SOUND_FIGHT_48,
NO_SND = SOUND_NO_SOUND
};
- uint16 hitSoundsByFightMoves[12][10] = {
- {S39,S42,S43,S43,S39,S39,S39,S39,S39,S42},
- {NO_SND,NO_SND,NO_SND,NO_SND,NO_SND,NO_SND,NO_SND,NO_SND,NO_SND,NO_SND},
- {NO_SND,NO_SND,NO_SND,NO_SND,NO_SND,NO_SND,NO_SND,NO_SND,NO_SND,NO_SND},
- {S39,S39,S39,S39,S33,S43,S39,S39,S39,S39},
- {S39,S39,S39,S39,S35,S39,S38,S38,S39,S39},
- {S39,S39,S39,S39,S33,S39,S41,S36,S39,S39},
- {S39,S39,S39,S39,S37,S40,S38,S38,S39,S39},
- {S39,S39,S39,S39,S34,S43,S44,S37,S39,S39},
- {S39,S39,S39,S39,S34,S43,S44,S37,S39,S39},
- {S39,S39,S39,S39,S34,S43,S44,S37,S39,S40},
- {S39,S39,S39,S39,S33,S39,S41,S37,S39,S40},
- {S39,S39,S39,S39,S39,S39,S39,S39,S33,S33}
+ const uint16 hitSoundsByFightMoves[17][10] = {
+ { S37, S46, S41, S41, S46, S46, S40, S41, S43, S40 },
+ { NO_SND, NO_SND, NO_SND, NO_SND, NO_SND, NO_SND, NO_SND, NO_SND, NO_SND, NO_SND },
+ { NO_SND, NO_SND, NO_SND, NO_SND, NO_SND, NO_SND, NO_SND, NO_SND, NO_SND, NO_SND },
+ { S46, S46, S46, S46, S37, S47, S37, S38, S43, S38 },
+ { S46, S46, S46, S46, S46, S46, S40, S41, S43, S46 },
+ { S46, S46, S46, S46, S46, S46, S40, S41, S43, S40 },
+ { S46, S46, S46, S46, S46, S46, S40, S41, S43, S40 },
+ { S46, S46, S37, S46, S37, S47, S40, S47, S43, S37 },
+ { S46, S46, S46, S46, S46, S46, S43, S44, S43, S43 },
+ { S37, S46, S46, S46, S38, S47, S40, S38, S43, S46 },
+ { S46, S37, S46, S37, S39, S46, S40, S39, S43, S37 },
+ { S46, S37, S46, S46, S38, S47, S40, S38, S43, S46 },
+ { S37, S37, S46, S46, S38, S47, S48, S38, S43, S37 },
+ { S46, S46, S46, S46, S37, S46, S40, S38, S43, S46 },
+ { S46, S46, S46, S37, S39, S46, S40, S39, S43, S46 },
+ { S37, S46, S46, S46, S37, S46, S40, S37, S43, S46 },
+ { S43, S43, S43, S43, S43, S43, S43, S43, S43, S43 }
};
- // This is why first dimension is between FightMove 1 and 12.
- if (m_curFightMove == FIGHTMOVE_NULL || m_curFightMove >= FIGHTMOVE_HITFRONT)
+ eWeaponType weapon = GetWeapon()->m_eWeaponType;
+ CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(weapon);
+ if (weaponInfo->m_AnimToPlay == ASSOCGRP_KNIFE) {
+ if (m_curFightMove >= FIGHTMOVE_MELEE1) {
+ if (m_curFightMove == FIGHTMOVE_MELEE3) {
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_BAT_ATTACK, (weapon << 8) | ENTITY_TYPE_PED);
+ } else {
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_KNIFE_ATTACK, (weapon << 8) | ENTITY_TYPE_PED);
+ }
+ return;
+ }
+ }
+
+ // This is why first dimension is between FightMove 1 and 17.
+ if (m_curFightMove <= FIGHTMOVE_NULL || m_curFightMove >= FIGHTMOVE_HITFRONT)
return;
uint16 soundId;
- // And this is why second dimension is between 13 and 22.
+ // And this is why second dimension is between 18 and 27.
if (hitTo->m_curFightMove > FIGHTMOVE_GROUNDKICK && hitTo->m_curFightMove < FIGHTMOVE_IDLE2NORM) {
soundId = hitSoundsByFightMoves[m_curFightMove - FIGHTMOVE_STDPUNCH][hitTo->m_curFightMove - FIGHTMOVE_HITFRONT];
@@ -1531,171 +2051,252 @@ CPed::PlayHitSound(CPed *hitTo)
}
if (soundId != NO_SND)
- DMAudio.PlayOneShot(m_audioEntityId, soundId, 0.0f);
+ DMAudio.PlayOneShot(m_audioEntityId, soundId, (weapon << 8) | ENTITY_TYPE_PED);
}
bool
-CPed::FightStrike(CVector &touchedNodePos)
+CPed::FightStrike(CVector &touchedNodePos, bool fightWithWeapon)
{
- CColModel *ourCol;
+ CColModel *hisCol;
CVector attackDistance;
- ePedPieceTypes closestPedPiece = PEDPIECE_TORSO;
- float maxDistanceToBeBeaten;
+ float maxDistanceToBeat;
CPed *nearPed;
- int state = m_fightState;
- bool pedFound = false;
+ CVector extendedTouchPoint;
+
+ CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
+ float radius = tFightMoves[m_curFightMove].strikeRadius;
+ if (fightWithWeapon)
+ radius = weaponInfo->m_fRadius;
- if (state == FIGHTSTATE_JUST_ATTACKED)
+ if (m_fightState == FIGHTSTATE_JUST_ATTACKED)
return false;
- // Pointless code
- if (state > FIGHTSTATE_NO_MOVE)
- attackDistance = touchedNodePos - m_vecHitLastPos;
+ if (this == FindPlayerPed() && fightWithWeapon && GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED)
+ CGlass::BreakGlassPhysically(touchedNodePos, radius);
for (int i = 0; i < m_numNearPeds; i++) {
+ int8 pedFound = 0;
nearPed = m_nearPeds[i];
- if (GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED)
- maxDistanceToBeBeaten = nearPed->GetBoundRadius() + tFightMoves[m_curFightMove].strikeRadius + 0.1f;
+ if (!fightWithWeapon && GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED && GetWeapon()->m_eWeaponType != WEAPONTYPE_BRASSKNUCKLE)
+ maxDistanceToBeat = nearPed->GetBoundRadius() + radius + 0.1f;
else
- maxDistanceToBeBeaten = nearPed->GetBoundRadius() + tFightMoves[m_curFightMove].strikeRadius;
+ maxDistanceToBeat = nearPed->GetBoundRadius() + radius;
- if (nearPed->bUsesCollision || nearPed->m_nPedState == PED_DEAD) {
+ if ((nearPed->bUsesCollision || nearPed->m_nPedState == PED_DEAD) && (m_pedInObjective != FindPlayerPed() || nearPed == FindPlayerPed())) {
CVector nearPedCentre;
+
+ // Have to animate a skinned clump because the initial col model is useless
+ hisCol = ((CPedModelInfo*)CModelInfo::GetModelInfo(nearPed->GetModelIndex()))->AnimatePedColModelSkinnedWorld(nearPed->GetClump());
+
nearPed->GetBoundCentre(nearPedCentre);
CVector potentialAttackDistance = nearPedCentre - touchedNodePos;
// He can beat us
- if (sq(maxDistanceToBeBeaten) > potentialAttackDistance.MagnitudeSqr()) {
-
-#ifdef PED_SKIN
- // Have to animate a skinned clump because the initial col model is useless
- if(IsClumpSkinned(GetClump()))
- ourCol = ((CPedModelInfo *)CModelInfo::GetModelInfo(GetModelIndex()))->AnimatePedColModelSkinned(GetClump());
- else
-#endif
- if (nearPed->OnGround() || !nearPed->IsPedHeadAbovePos(-0.3f)) {
- ourCol = &CTempColModels::ms_colModelPedGroundHit;
- } else {
-#ifdef ANIMATE_PED_COL_MODEL
- ourCol = CPedModelInfo::AnimatePedColModel(((CPedModelInfo *)CModelInfo::GetModelInfo(GetModelIndex()))->GetHitColModel(),
- RpClumpGetFrame(GetClump()));
-#else
- ourCol = ((CPedModelInfo*)CModelInfo::GetModelInfo(m_modelIndex))->GetHitColModel();
-#endif
- }
+ if (sq(maxDistanceToBeat) > potentialAttackDistance.MagnitudeSqr()) {
- for (int j = 0; j < ourCol->numSpheres; j++) {
- attackDistance = nearPed->GetPosition() + ourCol->spheres[j].center;
+ for (int j = 0; j < hisCol->numSpheres; j++) {
+ attackDistance = hisCol->spheres[j].center;
attackDistance -= touchedNodePos;
- CColSphere *ourPieces = ourCol->spheres;
- float maxDistanceToBeat = ourPieces[j].radius + tFightMoves[m_curFightMove].strikeRadius;
+ CColSphere *hisPieces = hisCol->spheres;
+ maxDistanceToBeat = hisPieces[j].radius + radius;
// We can beat him too
if (sq(maxDistanceToBeat) > attackDistance.MagnitudeSqr()) {
- pedFound = true;
- closestPedPiece = (ePedPieceTypes) ourPieces[j].piece;
+ FightHitPed(nearPed, touchedNodePos, attackDistance, hisPieces[j].piece);
+ pedFound = 1;
break;
}
}
}
+ if (!pedFound && !fightWithWeapon) {
+ extendedTouchPoint = touchedNodePos - GetPosition();
+ if (DotProduct(touchedNodePos - GetPosition(), nearPed->GetPosition() - GetPosition()) > 0.f) {
+ if (m_curFightMove == FIGHTMOVE_GROUNDKICK) {
+ extendedTouchPoint += tFightMoves[FIGHTMOVE_GROUNDKICK].extendReachMultiplier * GetForward();
+ } else {
+ extendedTouchPoint.x *= tFightMoves[m_curFightMove].extendReachMultiplier;
+ extendedTouchPoint.y *= tFightMoves[m_curFightMove].extendReachMultiplier;
+ }
+ pedFound = -1;
+ extendedTouchPoint += GetPosition();
+ }
+ }
+ if (pedFound == -1) {
+ CVector nearPedCentre = nearPed->GetBoundCentre();
+ if (sq(maxDistanceToBeat) > (nearPedCentre - extendedTouchPoint).MagnitudeSqr()) {
+
+ for (int j = 0; j < hisCol->numSpheres; j++) {
+ attackDistance = hisCol->spheres[j].center;
+ attackDistance -= extendedTouchPoint;
+ CColSphere* hisPieces = hisCol->spheres;
+ float maxDistanceToBeat2 = hisPieces[j].radius + tFightMoves[m_curFightMove].strikeRadius;
+
+ // We can beat him too
+ if (sq(maxDistanceToBeat2) > attackDistance.MagnitudeSqr()) {
+ FightHitPed(nearPed, extendedTouchPoint, attackDistance, hisPieces[j].piece);
+ break;
+ }
+ }
+ }
+ }
}
- if (pedFound)
- break;
}
- if (pedFound) {
- if (nearPed->IsPlayer() && nearPed->m_nPedState == PED_GETUP)
- return false;
- float oldVictimHealth = nearPed->m_fHealth;
- CVector bloodPos = 0.5f * attackDistance + touchedNodePos;
- int damageMult = tFightMoves[m_curFightMove].damage * ((CGeneral::GetRandomNumber() & 1) + 2) + 1;
+ if (m_fightState == FIGHTSTATE_NO_MOVE)
+ m_fightState = FIGHTSTATE_1;
+
+ m_vecHitLastPos = touchedNodePos;
+ return false;
+}
- CVector2D diff (GetPosition() - nearPed->GetPosition());
- int direction = nearPed->GetLocalDirection(diff);
- if (IsPlayer()) {
- if (((CPlayerPed*)this)->m_bAdrenalineActive)
- damageMult = 20;
- } else {
- damageMult *= m_pedStats->m_attackStrength;
+void
+CPed::FightHitPed(CPed *victim, CVector &touchPoint, CVector &dir, int16 piece)
+{
+ if (victim->IsPlayer() && victim->m_nPedState == PED_GETUP)
+ return;
+
+ CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
+ bool fightingWithWeapon = false;
+ int damageMult = tFightMoves[m_curFightMove].damage * ((CGeneral::GetRandomNumber() & 1) + 2) + 1;
+
+ if (weaponInfo->IsFlagSet(WEAPONFLAG_FIGHTMODE)) {
+ fightingWithWeapon = true;
+ if (m_curFightMove >= FIGHTMOVE_MELEE1) {
+ damageMult = weaponInfo->m_nDamage;
+ if (m_curFightMove == FIGHTMOVE_MELEE3 && GetWeapon()->m_eWeaponType != WEAPONTYPE_SCREWDRIVER)
+ damageMult *= 5;
}
+ }
- // Change direction if we used kick.
- if (m_curFightMove == FIGHTMOVE_KICK) {
- if (CGeneral::GetRandomNumber() & 1) {
- direction++;
- if (direction > 3)
- direction -= 4;
- }
+ if (IsPlayer()) {
+ if (((CPlayerPed*)this)->m_bAdrenalineActive)
+ damageMult = 20;
+ } else if (!fightingWithWeapon) {
+ damageMult *= m_pedStats->m_attackStrength;
+ }
+
+ float oldVictimHealth = victim->m_fHealth;
+ CVector bloodPos = 0.5f * dir + touchPoint;
+ CVector2D diff(GetPosition() - victim->GetPosition());
+ int direction = victim->GetLocalDirection(diff);
+
+ bool brassKnucklePunch = false;
+ if (GetWeapon()->m_eWeaponType == WEAPONTYPE_BRASSKNUCKLE) {
+ if (m_curFightMove == FIGHTMOVE_PUNCHHOOK || m_curFightMove == FIGHTMOVE_PUNCHJAB || m_curFightMove == FIGHTMOVE_BACKLEFT ||
+ m_curFightMove == FIGHTMOVE_STDPUNCH || m_curFightMove == FIGHTMOVE_PUNCH) {
+ brassKnucklePunch = true;
+ damageMult *= 1.5f;
}
- nearPed->ReactToAttack(this);
+ }
+ victim->ReactToAttack(this);
+
+ // Mostly unused. if > 5, ANIM_HIT_BIGSTEP will be run, that's it.
+ int unk2;
+ if (GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED && GetWeapon()->m_eWeaponType != WEAPONTYPE_BRASSKNUCKLE &&
+ !victim->IsPlayer() && !fightingWithWeapon)
+ unk2 = 101;
+ else
+ unk2 = damageMult;
- // Mostly unused. if > 5, ANIM_HIT_WALK will be run, that's it.
- int unk2;
- if (GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED && !nearPed->IsPlayer())
- unk2 = 101;
+ victim->StartFightDefend(direction, tFightMoves[m_curFightMove].hitLevel, unk2);
+ PlayHitSound(victim);
+ m_fightState = FIGHTSTATE_JUST_ATTACKED;
+ RpAnimBlendClumpGetAssociation(GetClump(), tFightMoves[m_curFightMove].animId)->speed = 0.6f;
+
+ if (!victim->DyingOrDead()) {
+ if(fightingWithWeapon)
+ victim->InflictDamage(this, GetWeapon()->m_eWeaponType, damageMult, (ePedPieceTypes)piece, direction);
else
- unk2 = damageMult;
+ victim->InflictDamage(this, WEAPONTYPE_UNARMED, damageMult * 3.0f, (ePedPieceTypes)piece, direction);
+ }
- nearPed->StartFightDefend(direction, tFightMoves[m_curFightMove].hitLevel, unk2);
- PlayHitSound(nearPed);
- m_fightState = FIGHTSTATE_JUST_ATTACKED;
- RpAnimBlendClumpGetAssociation(GetClump(), tFightMoves[m_curFightMove].animId)->speed = 0.6f;
- if (!nearPed->DyingOrDead()) {
- nearPed->InflictDamage(this, WEAPONTYPE_UNARMED, damageMult * 3.0f, closestPedPiece, direction);
- }
+ if (CGame::nastyGame && weaponInfo->m_AnimToPlay == ASSOCGRP_KNIFE && m_curFightMove >= FIGHTMOVE_MELEE1
+ && victim->GetIsOnScreen()) {
- if (CGame::nastyGame
- && tFightMoves[m_curFightMove].hitLevel > HITLEVEL_MEDIUM
- && nearPed->m_nPedState == PED_DIE
- && nearPed->GetIsOnScreen()) {
+ static float particleRightLen = 0.05f;
+ static float particleUpLen = 0.05f;
- // Just for blood particle. We will restore it below.
- attackDistance /= (10.0f * attackDistance.Magnitude());
- for(int i=0; i<4; i++) {
- CParticle::AddParticle(PARTICLE_BLOOD, bloodPos, attackDistance, nil, 0.0f, 0, 0, 0, 0);
- }
+ // Just for particles. We will restore it below.
+ dir /= (20.0f * dir.Magnitude());
+ if (m_curFightMove == FIGHTMOVE_MELEE1) {
+ float rightMult = -particleRightLen;
+ dir += particleUpLen * GetUp() + rightMult * GetRight();
+
+ } else if (m_curFightMove == FIGHTMOVE_MELEE2) {
+ float upMult = 2.0f * particleUpLen;
+ dir += particleRightLen * GetRight() + upMult * GetUp();
+ }
+ CParticle::AddParticle(PARTICLE_BLOOD_SPURT, bloodPos, dir, nil, 0.0f, 0, 0, 0, 0);
+ CParticle::AddParticle(PARTICLE_BLOOD_SPURT, bloodPos, dir, nil, 0.0f, 0, 0, 0, 0);
+ if (IsPlayer()) {
+ CParticle::AddParticle(PARTICLE_BLOOD_SPURT, bloodPos, dir, nil, 0.0f, 0, 0, 0, 0);
+ CParticle::AddParticle(PARTICLE_BLOOD_SPURT, bloodPos, dir, nil, 0.0f, 0, 0, 0, 0);
+ }
+ if (!(CGeneral::GetRandomNumber() & 3)) {
+ CParticle::AddParticle(PARTICLE_TEST, bloodPos, dir, nil, 0.0f, 0, 0, 0, 0);
+ }
+ } else if (CGame::nastyGame && (tFightMoves[m_curFightMove].hitLevel > HITLEVEL_MEDIUM || fightingWithWeapon)
+ && victim->GetIsOnScreen()) {
+
+ // Just for particles. We will restore it below.
+ dir /= (10.0f * dir.Magnitude());
+ for (int i = 0; i < 4; i++) {
+ CParticle::AddParticle(PARTICLE_BLOOD, bloodPos, dir, nil, 0.0f, 0, 0, 0, 0);
}
- if (!nearPed->OnGround()) {
- float curVictimHealth = nearPed->m_fHealth;
+ }
+
+ eWeaponType weaponType = GetWeapon()->m_eWeaponType;
+ if (!fightingWithWeapon) {
+ if (!victim->OnGround()) {
+ float curVictimHealth = victim->m_fHealth;
if (curVictimHealth > 0.0f
- && (curVictimHealth < 40.0f && oldVictimHealth > 40.0f && !nearPed->IsPlayer()
- || nearPed->m_fHealth < 20.0f && oldVictimHealth > 20.0f
- || GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED && IsPlayer()
- || nearPed->m_pedStats->m_flags & STAT_ONE_HIT_KNOCKDOWN)) {
+ && (curVictimHealth < 30.0f && oldVictimHealth > 30.0f
+ || weaponType != WEAPONTYPE_UNARMED && weaponType != WEAPONTYPE_BRASSKNUCKLE && IsPlayer()
+ || victim->m_pedStats->m_flags & STAT_ONE_HIT_KNOCKDOWN || brassKnucklePunch)) {
- nearPed->SetFall(0, (AnimationId)(direction + ANIM_STD_HIGHIMPACT_FRONT), 0);
- if (nearPed->m_nPedState == PED_FALL)
- nearPed->bIsStanding = false;
+ victim->SetFall(0, (AnimationId)(direction + ANIM_STD_HIGHIMPACT_FRONT), 0);
+ if (victim->m_nPedState == PED_FALL)
+ victim->bIsStanding = false;
}
}
- if (nearPed->m_nPedState == PED_DIE || !nearPed->bIsStanding) {
- attackDistance = nearPed->GetPosition() - GetPosition();
- attackDistance.Normalise();
- attackDistance.z = 1.0f;
- nearPed->bIsStanding = false;
+ }
- float moveMult;
- if (m_curFightMove == FIGHTMOVE_GROUNDKICK) {
- moveMult = Min(damageMult * 0.6f, 4.0f);
+ if (victim->m_nPedState == PED_DIE || !victim->bIsStanding) {
+ dir = victim->GetPosition() - GetPosition();
+ dir.Normalise();
+ dir.z = 1.0f;
+ victim->bIsStanding = false;
+
+ float moveMult;
+ if (fightingWithWeapon) {
+ moveMult = Min(damageMult * 0.02f, 1.0f);
+ } else if (m_curFightMove == FIGHTMOVE_GROUNDKICK) {
+ moveMult = Min(damageMult * 0.6f, 4.0f);
+ } else {
+ if (victim->m_nPedState != PED_DIE || damageMult >= 20) {
+ moveMult = damageMult;
} else {
- if (nearPed->m_nPedState != PED_DIE || damageMult >= 20) {
- moveMult = damageMult;
- } else {
- moveMult = Min(damageMult * 2.0f, 14.0f);
- }
+ moveMult = Min(damageMult * 2.0f, 14.0f);
}
-
- nearPed->ApplyMoveForce(moveMult * 0.6f * attackDistance);
}
- CEventList::RegisterEvent(nearPed->m_nPedType == PEDTYPE_COP ? EVENT_ASSAULT_POLICE : EVENT_ASSAULT, EVENT_ENTITY_PED, nearPed, this, 2000);
+
+ victim->ApplyMoveForce(moveMult * 0.6 * dir);
}
- if (m_fightState == FIGHTSTATE_NO_MOVE)
- m_fightState = FIGHTSTATE_1;
+ if (weaponType != WEAPONTYPE_KNIFE && weaponType != WEAPONTYPE_MACHETE
+ && weaponType != WEAPONTYPE_KATANA && weaponType != WEAPONTYPE_CHAINSAW) {
- m_vecHitLastPos = touchedNodePos;
- return false;
+ if (victim->m_nPedType == PEDTYPE_COP)
+ CEventList::RegisterEvent(EVENT_ASSAULT_POLICE, EVENT_ENTITY_PED, victim, this, 2000);
+ else
+ CEventList::RegisterEvent(EVENT_ASSAULT, EVENT_ENTITY_PED, victim, this, 2000);
+ } else {
+ if (victim->m_nPedType == PEDTYPE_COP)
+ CEventList::RegisterEvent(EVENT_ASSAULT_NASTYWEAPON_POLICE, EVENT_ENTITY_PED, victim, this, 2000);
+ else
+ CEventList::RegisterEvent(EVENT_ASSAULT_NASTYWEAPON, EVENT_ENTITY_PED, victim, this, 2000);
+ }
}
void
@@ -1712,7 +2313,7 @@ CPed::FinishFightMoveCB(CAnimBlendAssociation *animAssoc, void *arg)
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;
@@ -1741,12 +2342,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,
@@ -1759,6 +2361,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;
@@ -1782,11 +2385,13 @@ CPed::LoadFightData(void)
break;
}
- if (strcmp(animName, "null") != 0) {
- animAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, animName);
- tFightMoves[moveId].animId = (AnimationId)animAssoc->animId;
- } else {
- tFightMoves[moveId].animId = ANIM_STD_WALK;
+ if (strcmp(animName, "default") != 0) {
+ if (strcmp(animName, "null") != 0) {
+ animAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, animName);
+ tFightMoves[moveId].animId = (AnimationId)animAssoc->animId;
+ } else {
+ tFightMoves[moveId].animId = ANIM_STD_WALK;
+ }
}
moveId++;
}
@@ -1827,7 +2432,7 @@ CPed::InvestigateEvent(void)
if (CTimer::GetTimeInMilliseconds() > m_chatTimer) {
if (m_chatTimer) {
- if (m_eventType < EVENT_ASSAULT_NASTYWEAPON)
+ if (m_eventType < EVENT_UNK)
SetWaitState(WAITSTATE_TURN180, nil);
m_chatTimer = 0;
@@ -1887,7 +2492,8 @@ CPed::InvestigateEvent(void)
} else if (CGeneral::GetRandomNumber() & 3) {
CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_IDLE_CAM, 4.0f);
SetLookTimer(CGeneral::GetRandomNumberInRange(2500, 5000));
- Say(SOUND_PED_CHAT_EVENT);
+ if (!CGame::germanGame)
+ Say(SOUND_PED_CHAT_EVENT);
} else {
m_chatTimer = 0;
@@ -1936,7 +2542,8 @@ CPed::InvestigateEvent(void)
CAnimManager::BlendAnimation(GetClump(), animGroup, animToPlay, 4.0f);
SetLookTimer(CGeneral::GetRandomNumberInRange(1000, 2500));
}
- Say(SOUND_PED_CHAT_EVENT);
+ if (!CGame::germanGame)
+ Say(SOUND_PED_CHAT_EVENT);
}
break;
case EVENT_ICECREAM:
@@ -2003,14 +2610,17 @@ CPed::InvestigateEvent(void)
return;
}
+ bool willStandStill = false;
for (int i = 0; i < m_numNearPeds; i++) {
if ((m_eventOrThreat - m_nearPeds[i]->GetPosition()).MagnitudeSqr() < sq(0.4f)) {
SetMoveState(PEDMOVE_STILL);
- return;
+ willStandStill = true;
+ break;
}
}
- SetMoveState(PEDMOVE_WALK);
+ if (!willStandStill)
+ SetMoveState(PEDMOVE_WALK);
}
}
@@ -2050,17 +2660,29 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi
bool willLinger = false;
int random;
+ if (damagedBy == FindPlayerPed() && damagedBy != this && damage > 3.0f)
+ ++CWorld::Players[CWorld::PlayerInFocus].m_nHavocLevel;
+
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() &&
@@ -2073,8 +2695,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_STD_HIT_FLOOR_FRONT;
@@ -2083,14 +2709,30 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi
dieDelta *= 2.0f;
dieSpeed = 0.5f;
detectDieAnim = false;
- } else if (m_nPedState == PED_FALL) {
- dieAnim = ANIM_STD_NUM;
- 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 = ANIM_STD_NUM;
+ else
+ dieAnim = ANIM_STD_KO_FRONT;
+ } else {
+ if (fallAssoc->flags & ASSOC_FRONTAL)
+ dieAnim = ANIM_STD_HIT_FLOOR_FRONT;
+ else
+ dieAnim = ANIM_STD_HIT_FLOOR;
+
+ dieDelta *= 2.0f;
+ dieSpeed = 0.5f;
+ }
+ detectDieAnim = false;
}
+
if (detectDieAnim) {
switch (method) {
case WEAPONTYPE_UNARMED:
+ case WEAPONTYPE_BRASSKNUCKLE:
if (bMeleeProof)
return false;
@@ -2124,68 +2766,97 @@ 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;
- if (m_nPedState == PED_FALL) {
- if (IsPedHeadAbovePos(-0.3f)) {
- dieAnim = ANIM_STD_NUM;
+ if (method != WEAPONTYPE_KATANA ||
+ damagedBy != FindPlayerPed()
+ || FindPlayerPed()->m_nPedState != PED_FIGHT
+ || FindPlayerPed()->m_curFightMove != FIGHTMOVE_MELEE1 && FindPlayerPed()->m_curFightMove != FIGHTMOVE_MELEE2
+ || CGeneral::GetRandomNumber() & 3) {
+
+ if (m_nPedState == PED_FALL) {
+ if (IsPedHeadAbovePos(-0.3f)) {
+ dieAnim = ANIM_STD_NUM;
+ } else {
+ if (RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_FRONTAL))
+ dieAnim = ANIM_STD_HIT_FLOOR_FRONT;
+ else
+ dieAnim = ANIM_STD_HIT_FLOOR;
+ dieDelta = dieDelta * 2.0f;
+ dieSpeed = 0.5f;
+ }
+ } else if (damagedBy != FindPlayerPed() || FindPlayerPed()->m_curFightMove != FIGHTMOVE_MELEE2) {
+ if (damagedBy != FindPlayerPed() || FindPlayerPed()->m_curFightMove != FIGHTMOVE_MELEE3) {
+ switch (direction) {
+ case 0:
+ dieAnim = ANIM_STD_HIGHIMPACT_FRONT;
+ break;
+ case 1:
+ dieAnim = ANIM_STD_HIGHIMPACT_LEFT;
+ break;
+ case 2:
+ dieAnim = ANIM_STD_HIGHIMPACT_BACK;
+ break;
+ case 3:
+ dieAnim = ANIM_STD_HIGHIMPACT_RIGHT;
+ break;
+ default:
+ break;
+ }
+ } else {
+ dieAnim = ANIM_STD_KO_SHOT_STOMACH;
+ }
} else {
- if (RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_FRONTAL))
- dieAnim = ANIM_STD_HIT_FLOOR_FRONT;
- else
- dieAnim = ANIM_STD_HIT_FLOOR;
- dieDelta = dieDelta * 2.0f;
- dieSpeed = 0.5f;
+ dieAnim = ANIM_STD_KO_SHOT_FACE;
}
} else {
- switch (direction) {
- case 0:
- dieAnim = ANIM_STD_HIGHIMPACT_FRONT;
- break;
- case 1:
- dieAnim = ANIM_STD_HIGHIMPACT_LEFT;
- break;
- case 2:
- dieAnim = ANIM_STD_HIGHIMPACT_BACK;
- break;
- case 3:
- dieAnim = ANIM_STD_HIGHIMPACT_RIGHT;
- break;
- default:
- break;
- }
+ dieAnim = ANIM_STD_KO_SHOT_FACE;
+ RemoveBodyPart(PED_HEAD, direction);
+ headShot = true;
+ willLinger = true;
}
break;
case WEAPONTYPE_COLT45:
- case WEAPONTYPE_UZI:
case WEAPONTYPE_SHOTGUN:
- case WEAPONTYPE_AK47:
- case WEAPONTYPE_M16:
+ case WEAPONTYPE_STUBBY_SHOTGUN:
+ case WEAPONTYPE_SPAS12_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_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) {
@@ -2250,8 +2921,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;
@@ -2348,7 +3019,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();
@@ -2407,6 +3078,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_STD_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) {
@@ -2416,40 +3097,49 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi
if (bInVehicle) {
if (method != WEAPONTYPE_DROWNING) {
-#ifdef VC_PED_PORTS
if (m_pMyVehicle) {
- if (m_pMyVehicle->IsCar() && m_pMyVehicle->pDriver == this) {
- if (m_pMyVehicle->GetStatus() == STATUS_SIMPLE) {
- m_pMyVehicle->SetStatus(STATUS_PHYSICS);
- CCarCtrl::SwitchVehicleToRealPhysics(m_pMyVehicle);
- }
- m_pMyVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
- m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0;
- m_pMyVehicle->AutoPilot.m_nTempAction = TEMPACT_HANDBRAKESTRAIGHT;
- m_pMyVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 2000;
- }
- if (m_pMyVehicle->CanPedExitCar()) {
- SetObjective(OBJECTIVE_LEAVE_CAR_AND_DIE, m_pMyVehicle);
- } else {
+ CVehicle* pVehicle = m_pMyVehicle;
+ bool bDone = false;
+ if (m_pMyVehicle->IsBike()) {
m_fHealth = 0.0f;
- if (m_pMyVehicle && m_pMyVehicle->pDriver == this) {
- SetRadioStation();
- m_pMyVehicle->SetStatus(STATUS_ABANDONED);
+ ((CBike*)m_pMyVehicle)->KnockOffRider(method, direction, this, false);
+ bDone = true;
+ } else {
+ if (m_pMyVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_CAR) {
+ if (m_pMyVehicle->pDriver == this) {
+ if (m_pMyVehicle->GetStatus() == STATUS_SIMPLE) {
+ m_pMyVehicle->SetStatus(STATUS_PHYSICS);
+ CCarCtrl::SwitchVehicleToRealPhysics(m_pMyVehicle);
+ }
+ m_pMyVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
+ m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0;
+ m_pMyVehicle->AutoPilot.m_nTempAction = TEMPACT_HANDBRAKESTRAIGHT;
+ m_pMyVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 2000;
+ }
}
- SetDie(dieAnim, dieDelta, dieSpeed);
- /*
- if (damagedBy == FindPlayerPed() && damagedBy != this) {
- // PlayerInfo stuff
+ if (m_pMyVehicle->CanPedExitCar(true)) {
+ SetObjective(OBJECTIVE_LEAVE_CAR_AND_DIE, m_pMyVehicle);
+ } else {
+ m_fHealth = 0.0f;
+ if (m_pMyVehicle && m_pMyVehicle->pDriver == this) {
+ SetRadioStation();
+ m_pMyVehicle->SetStatus(STATUS_ABANDONED);
+ }
+ SetDie(dieAnim, dieDelta, dieSpeed);
+
+ if (damagedBy == FindPlayerPed() && damagedBy != this) {
+ CWorld::Players[CWorld::PlayerInFocus].m_nHavocLevel += 10;
+ CWorld::Players[CWorld::PlayerInFocus].m_fMediaAttention += 5.f;
+ }
}
- */
}
- for (int i = 0; i < ARRAY_SIZE(m_pMyVehicle->pPassengers); i++) {
- CPed* passenger = m_pMyVehicle->pPassengers[i];
+ for (int i = 0; i < ARRAY_SIZE(pVehicle->pPassengers); i++) {
+ CPed* passenger = pVehicle->pPassengers[i];
if (passenger && passenger != this && damagedBy)
passenger->ReactToAttack(damagedBy);
}
- CPed *driverOfVeh = m_pMyVehicle->pDriver;
+ CPed *driverOfVeh = pVehicle->pDriver;
if (driverOfVeh && driverOfVeh != this && damagedBy)
driverOfVeh->ReactToAttack(damagedBy);
@@ -2459,8 +3149,9 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi
} else {
CDarkel::RegisterKillNotByPlayer(this, method);
}
+ if (bDone)
+ return true;
}
-#endif
m_fHealth = 1.0f;
return false;
}
@@ -2475,15 +3166,18 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi
SetDie(dieAnim, dieDelta, dieSpeed);
if (damagedBy == player || damagedBy && damagedBy == FindPlayerVehicle()) {
-
- // There are PlayerInfo stuff here in VC
CDarkel::RegisterKillByPlayer(this, method, headShot);
+ CWorld::Players[CWorld::PlayerInFocus].m_nHavocLevel += 10;
+ CWorld::Players[CWorld::PlayerInFocus].m_fMediaAttention += 5.f;
m_threatEntity = player;
} else {
CDarkel::RegisterKillNotByPlayer(this, method);
}
- if (method == WEAPONTYPE_DROWNING)
+ if (method == WEAPONTYPE_DROWNING) {
bIsInTheAir = false;
+ if (FindPlayerPed() == this)
+ CStats::TimesDrowned++;
+ }
return true;
}
@@ -2535,25 +3229,8 @@ CPed::RemoveBodyPart(PedNode nodeId, int8 direction)
frame = m_pFrames[nodeId]->frame;
if (frame) {
if (CGame::nastyGame) {
-#ifdef PED_SKIN
- if(!IsClumpSkinned(GetClump()))
-#endif
- {
-#ifdef DEBUGMENU
- if (bPopHeadsOnHeadshot || nodeId != PED_HEAD)
-#else
- if (nodeId != PED_HEAD)
-#endif
- SpawnFlyingComponent(nodeId, direction);
-
- RecurseFrameChildrenVisibilityCB(frame, nil);
- }
- pos.x = 0.0f;
- pos.y = 0.0f;
- pos.z = 0.0f;
- TransformToNode(pos, PED_HEAD);
-
if (CEntity::GetIsOnScreen()) {
+ m_pedIK.GetComponentPosition(pos, nodeId);
CParticle::AddParticle(PARTICLE_TEST, pos,
CVector(0.0f, 0.0f, 0.0f),
nil, 0.1f, 0, 0, 0, 0);
@@ -2576,87 +3253,11 @@ CPed::RemoveBodyPart(PedNode nodeId, int8 direction)
CObject*
CPed::SpawnFlyingComponent(int pedNode, int8 direction)
{
- if (CObject::nNoTempObjects >= NUMTEMPOBJECTS)
- return nil;
-
-#ifdef PED_SKIN
- assert(!IsClumpSkinned(GetClump()));
-#endif
-
- CObject *obj = new CObject();
- if (!obj)
- return nil;
-
- RwFrame *frame = RwFrameCreate();
- RpClump *clump = RpClumpCreate();
- RpClumpSetFrame(clump, frame);
- RwMatrix *matrix = RwFrameGetLTM(m_pFrames[pedNode]->frame);
- *RwFrameGetMatrix(frame) = *matrix;
-
- flyingClumpTemp = clump;
- RwFrameForAllObjects(m_pFrames[pedNode]->frame, CloneAtomicToFrameCB, frame);
- RwFrameForAllChildren(m_pFrames[pedNode]->frame, RecurseFrameChildrenToCloneCB, frame);
- flyingClumpTemp = nil;
- switch (pedNode) {
- case PED_HEAD:
- // So popping head would have wheel collision. They disabled it anyway
- obj->SetModelIndexNoCreate(MI_CAR_WHEEL);
- break;
- case PED_UPPERARML:
- case PED_UPPERARMR:
- obj->SetModelIndexNoCreate(MI_BODYPARTB);
- obj->SetCenterOfMass(0.25f, 0.0f, 0.0f);
- break;
- case PED_UPPERLEGL:
- case PED_UPPERLEGR:
- obj->SetModelIndexNoCreate(MI_BODYPARTA);
- obj->SetCenterOfMass(0.4f, 0.0f, 0.0f);
- break;
- default:
- break;
- }
- obj->RefModelInfo(GetModelIndex());
- obj->AttachToRwObject((RwObject*)clump);
- obj->m_fMass = 15.0f;
- obj->m_fTurnMass = 5.0f;
- obj->m_fAirResistance = 0.99f;
- obj->m_fElasticity = 0.03f;
- obj->m_fBuoyancy = m_fMass*GRAVITY/0.75f;
- obj->ObjectCreatedBy = TEMP_OBJECT;
- obj->SetIsStatic(false);
- obj->bIsPickup = false;
- obj->m_nSpecialCollisionResponseCases = COLLRESPONSE_SMALLBOX;
-
- // life time - the more objects the are, the shorter this one will live
- CObject::nNoTempObjects++;
- if (CObject::nNoTempObjects > 20)
- obj->m_nEndOfLifeTime = CTimer::GetTimeInMilliseconds() + 12000;
- else if (CObject::nNoTempObjects > 10)
- obj->m_nEndOfLifeTime = CTimer::GetTimeInMilliseconds() + 30000;
- else
- obj->m_nEndOfLifeTime = CTimer::GetTimeInMilliseconds() + 60000;
-
- CVector localForcePos, forceDir;
-
- if (direction == 2) {
- obj->m_vecMoveSpeed = 0.03f * GetForward();
- obj->m_vecMoveSpeed.z = (CGeneral::GetRandomNumber() & 0x3F) * 0.001f;
- obj->m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f);
- localForcePos = CVector(0.0f, 0.0f, 0.0f);
- forceDir = GetForward();
- } else {
- obj->m_vecMoveSpeed = -0.03f * GetForward();
- obj->m_vecMoveSpeed.z = (CGeneral::GetRandomNumber() & 0x3F) * 0.001f;
- obj->m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f);
- localForcePos = CVector(0.0f, 0.0f, 0.0f);
- forceDir = -GetForward();
- }
- obj->ApplyTurnForce(forceDir, localForcePos);
- CWorld::Add(obj);
-
- return obj;
+ // VC doesn't have detachable limbs :shrug:
+ return nil;
}
+// III leftover and unused
void
CPed::ApplyHeadShot(eWeaponType weaponType, CVector pos, bool evenOnPlayer)
{
@@ -2671,12 +3272,13 @@ CPed::ApplyHeadShot(eWeaponType weaponType, CVector pos, bool evenOnPlayer)
// BUG: This condition will always return true. Even fixing it won't work, because these states are unused.
// if (m_nPedState != PED_PASSENGER || m_nPedState != PED_TAXI_PASSENGER) {
- SetDie(ANIM_STD_KO_FRONT, 4.0f, 0.0f);
+ SetDie();
// }
bBodyPartJustCameOff = true;
m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 150;
+ RemoveBodyPart(PED_HEAD, 0);
CParticle::AddParticle(PARTICLE_TEST, pos2,
CVector(0.0f, 0.0f, 0.0f), nil, 0.2f, 0, 0, 0, 0);
@@ -2697,30 +3299,6 @@ CPed::ApplyHeadShot(eWeaponType weaponType, CVector pos, bool evenOnPlayer)
}
}
-uint8
-CPed::DoesLOSBulletHitPed(CColPoint &colPoint)
-{
-#ifdef FIX_BUGS
- return 1;
-#else
- uint8 retVal = 2;
-
- float headZ = GetNodePosition(PED_HEAD).z;
-
- if (m_nPedState == PED_FALL)
- retVal = 1;
-
- float colZ = colPoint.point.z;
- if (colZ < headZ)
- retVal = 1;
-
- if (headZ + 0.2f <= colZ)
- retVal = 0;
-
- return retVal;
-#endif
-}
-
bool
CPed::IsPedHeadAbovePos(float zOffset)
{
@@ -2790,6 +3368,15 @@ CPed::CollideWithPed(CPed *collideWith)
int waitTime = 0;
if (weAreMissionChar || !collideWith->IsPlayer() || collideWith->m_nPedState != PED_MAKE_CALL) {
+ if (m_nWaitState == WAITSTATE_SUN_BATHE_IDLE) {
+ SetGetUp();
+ return;
+ }
+ if (collideWith->m_nWaitState == WAITSTATE_SUN_BATHE_IDLE) {
+ collideWith->SetGetUp();
+ return;
+ }
+
bool weDontLookToHim = DotProduct(posDiff, GetForward()) > 0.0f;
bool heLooksToUs = DotProduct(posDiff, collideWith->GetForward()) < 0.0f;
@@ -2797,10 +3384,8 @@ CPed::CollideWithPed(CPed *collideWith)
if ((!IsPlayer() || ((CPlayerPed*)this)->m_fMoveSpeed <= 1.8f)
&& (IsPlayer() || heIsMissionChar && weAreMissionChar || m_nMoveState != PEDMOVE_RUN && m_nMoveState != PEDMOVE_SPRINT
-#ifdef VC_PED_PORTS
|| m_objective == OBJECTIVE_FOLLOW_CHAR_IN_FORMATION && m_pedInObjective == collideWith
- || collideWith->m_objective == OBJECTIVE_FOLLOW_CHAR_IN_FORMATION && collideWith->m_pedInObjective == this
-#endif
+ || collideWith->m_objective == OBJECTIVE_FOLLOW_CHAR_IN_FORMATION && collideWith->m_pedInObjective == this
)) {
if (m_objective != OBJECTIVE_FOLLOW_CHAR_IN_FORMATION && m_objective != OBJECTIVE_GOTO_CHAR_ON_FOOT) {
@@ -2829,14 +3414,55 @@ CPed::CollideWithPed(CPed *collideWith)
SetDirectionToWalkAroundObject(collideWith);
}
} else {
- if (weAreMissionChar || m_pedStats->m_fear <= 100 - collideWith->m_pedStats->m_temper
- || (collideWith->IsPlayer() || collideWith->m_nMoveState == PEDMOVE_NONE || collideWith->m_nMoveState == PEDMOVE_STILL) &&
- (!collideWith->IsPlayer() || ((CPlayerPed*)collideWith)->m_fMoveSpeed <= 1.0f)) {
- SetDirectionToWalkAroundObject(collideWith);
- if (!weAreMissionChar)
- Say(SOUND_PED_CHAT);
+ if (FindPlayerPed() != m_pedInObjective
+ || m_objective != OBJECTIVE_KILL_CHAR_ANY_MEANS && m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT
+ || collideWith == m_pedInObjective) {
+
+ if (weAreMissionChar || m_pedStats->m_fear <= 100 - collideWith->m_pedStats->m_temper
+ || (collideWith->IsPlayer() || collideWith->m_nMoveState == PEDMOVE_NONE || collideWith->m_nMoveState == PEDMOVE_STILL) &&
+ (!collideWith->IsPlayer() || ((CPlayerPed*)collideWith)->m_fMoveSpeed <= 1.0f)) {
+ SetDirectionToWalkAroundObject(collideWith);
+ if (!weAreMissionChar)
+ Say(SOUND_PED_CHAT);
+ } else {
+ SetEvasiveStep(collideWith, 2);
+ }
+ } else if (collideWith->m_nMoveState != PEDMOVE_STILL && GetWeapon()->IsTypeMelee()
+ && collideWith->m_pedInObjective == m_pedInObjective) {
+
+ int colliderIndexAtPlayersKillList = -1;
+ int ourIndexAtPlayersKillList = -1;
+ for (int i = 0; i < ARRAY_SIZE(((CPlayerPed*)m_pedInObjective)->m_pMeleeList); i++) {
+ CPed *pedInKillList = ((CPlayerPed*)m_pedInObjective)->m_pMeleeList[i];
+ if (pedInKillList == this) {
+ ourIndexAtPlayersKillList = i;
+ } else if (pedInKillList == collideWith) {
+ colliderIndexAtPlayersKillList = i;
+ }
+ }
+ bool weAreCloserToTargetThenCollider = false;
+ if ((GetPosition() - m_vecSeekPos).MagnitudeSqr2D() < (collideWith->GetPosition() - m_vecSeekPos).MagnitudeSqr2D())
+ weAreCloserToTargetThenCollider = true;
+
+ if (ourIndexAtPlayersKillList > 0 && !weAreCloserToTargetThenCollider) {
+ if (colliderIndexAtPlayersKillList > 0) {
+ int time = 300;
+ SetWaitState(WAITSTATE_CROSS_ROAD_LOOK, &time);
+ m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + time;
+
+ } else if (collideWith->m_pedInObjective == FindPlayerPed()) {
+ ((CPlayerPed*)m_pedInObjective)->RemovePedFromMeleeList(this);
+ int time = 500;
+ SetWaitState(WAITSTATE_CROSS_ROAD_LOOK, &time);
+ m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + time;
+ }
+ } else if (!weAreCloserToTargetThenCollider) {
+ int time = 300;
+ SetWaitState(WAITSTATE_CROSS_ROAD_LOOK, &time);
+ m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + time;
+ }
} else {
- SetEvasiveStep(collideWith, 2);
+ SetDirectionToWalkAroundObject(collideWith);
}
}
} else {
@@ -2851,20 +3477,14 @@ CPed::CollideWithPed(CPed *collideWith)
} else {
TurnBody();
SetAttack(collideWith);
-#ifdef VC_PED_PORTS
m_fRotationCur = 0.3f + m_fRotationCur;
m_fRotationDest = m_fRotationCur;
-#endif
}
m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(250, 450);
}
}
} else {
-#ifdef VC_PED_PORTS
if (m_pedInObjective && (collideWith == m_pedInObjective || collideWith->m_pedInObjective == m_pedInObjective) && CTimer::GetTimeInMilliseconds() > m_nPedStateTimer) {
-#else
- if (m_pedInObjective && collideWith == m_pedInObjective && CTimer::GetTimeInMilliseconds() > m_nPedStateTimer) {
-#endif
if (heLooksToUs) {
SetEvasiveStep(collideWith, 1);
m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 3000;
@@ -2873,11 +3493,8 @@ CPed::CollideWithPed(CPed *collideWith)
if (m_pedStats != collideWith->m_pedStats) {
- if (collideWith->m_pedStats->m_fear <= 100 - m_pedStats->m_temper
-#ifdef VC_PED_PORTS
- || collideWith->IsPlayer() || CTimer::GetTimeInMilliseconds() < m_nPedStateTimer
-#endif
- ) {
+ if (collideWith->m_pedStats->m_fear <= 100 - m_pedStats->m_temper || collideWith->IsPlayer()
+ || CTimer::GetTimeInMilliseconds() < m_nPedStateTimer) {
if (collideWith->IsPlayer()) {
// He's on our right side
@@ -2897,9 +3514,7 @@ CPed::CollideWithPed(CPed *collideWith)
TurnBody();
animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_PARTIAL_PUNCH, 8.0f);
animAssoc->flags |= ASSOC_FADEOUTWHENDONE;
-#ifdef VC_PED_PORTS
m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 2000;
-#endif
if (!heIsMissionChar) {
CVector2D posDiff2D(posDiff);
int direction = collideWith->GetLocalDirection(posDiff2D);
@@ -2909,11 +3524,9 @@ CPed::CollideWithPed(CPed *collideWith)
}
}
}
- } else if (collideWith->m_pedStats->m_defendWeakness <= 1.5f || heIsMissionChar
-#ifdef VC_PED_PORTS
- || m_pedStats->m_defendWeakness <= collideWith->m_pedStats->m_defendWeakness
-#endif
- ) {
+ } else if (collideWith->m_pedStats->m_defendWeakness <= 1.5f || heIsMissionChar ||
+ m_pedStats->m_defendWeakness <= collideWith->m_pedStats->m_defendWeakness) {
+
// He looks us and we're not at his right side
if (heLooksToUs && DotProduct(posDiff,collideWith->GetRight()) > 0.0f) {
CVector moveForce = GetRight();
@@ -2943,7 +3556,7 @@ CPed::CollideWithPed(CPed *collideWith)
animAssoc->flags |= ASSOC_FADEOUTWHENDONE;
collideWith->m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 1000;
if (m_nPedState == PED_ATTACK)
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_FIGHT_PUNCH_39, 0.0f);
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_49, 0.0f);
}
} else {
// We're at his right side
@@ -2966,7 +3579,7 @@ CPed::CollideWithPed(CPed *collideWith)
}
if (m_nPedState == PED_ATTACK && collideWith->IsPedInControl())
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_FIGHT_PUNCH_39, 0.0f);
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_49, 0.0f);
collideWith->SetFall(3000, animToPlay, 0);
}
@@ -3019,8 +3632,8 @@ CPed::KillPedWithCar(CVehicle *car, float impulse)
eWeaponType killMethod;
if (m_nPedState == PED_FALL || m_nPedState == PED_DIE) {
- if (!this->m_pCollidingEntity || car->GetStatus() == STATUS_PLAYER)
- this->m_pCollidingEntity = car;
+ if (!m_pCollidingEntity || car->GetStatus() == STATUS_PLAYER)
+ m_pCollidingEntity = car;
return;
}
@@ -3028,7 +3641,7 @@ CPed::KillPedWithCar(CVehicle *car, float impulse)
return;
if (m_pCurSurface) {
- if (m_pCurSurface->IsVehicle() && (((CVehicle*)m_pCurSurface)->m_vehType == VEHICLE_TYPE_BOAT || IsPlayer()))
+ if (m_pCurSurface->IsVehicle() && (((CVehicle*)m_pCurSurface)->IsBoat()|| IsPlayer()))
return;
}
@@ -3090,7 +3703,7 @@ CPed::KillPedWithCar(CVehicle *car, float impulse)
float carFrontAndDistDotProd = DotProduct(distVec, car->GetForward());
// carFrontAndDistDotProd <= 0.0 car looks to us
- if ((carFrontAndDistDotProd <= 0.1 || randVal == 1) && randVal != 0) {
+ if ((carFrontAndDistDotProd <= 0.1 || randVal <= 1) && randVal != 0) {
killMethod = WEAPONTYPE_RUNOVERBYCAR;
nodeToDamage = PED_HEAD;
m_vecMoveSpeed = 0.9f * car->m_vecMoveSpeed;
@@ -3135,7 +3748,7 @@ CPed::KillPedWithCar(CVehicle *car, float impulse)
// TODO: What are we doing down here?
float unknown = ((CGeneral::GetRandomNumber() % 256) * 0.002 + 1.5) * pedJumpSpeedToReachHighestZ;
- // After this point, distVec isn't distVec anymore.
+ // After this point distVec isn't really distVec.
distVec = car->m_vecMoveSpeed;
distVec.Normalise();
distVec *= 0.2 * unknown;
@@ -3150,7 +3763,7 @@ CPed::KillPedWithCar(CVehicle *car, float impulse)
if (damageDir > 3)
damageDir = damageDir - 4;
- if (car->m_vehType == VEHICLE_TYPE_CAR) {
+ if (car->IsCar()) {
CObject *bonnet = ((CAutomobile*)car)->RemoveBonnetInPedCollision();
if (bonnet) {
@@ -3199,9 +3812,7 @@ CPed::KillPedWithCar(CVehicle *car, float impulse)
distVec.Normalise();
-#ifdef VC_PED_PORTS
distVec *= Min(car->m_fMass / 1400.0f, 1.0f);
-#endif
car->ApplyMoveForce(distVec * -100.0f);
Say(SOUND_PED_DEFEND);
@@ -3220,7 +3831,7 @@ CPed::KillPedWithCar(CVehicle *car, float impulse)
SetFall(1000, (AnimationId)(fallDirection + ANIM_STD_HIGHIMPACT_FRONT), true);
if (OnGround() && !m_pCollidingEntity &&
- (!IsPlayer() || bHasHitWall || car->GetModelIndex() == MI_TRAIN || m_vecDamageNormal.z < -0.8f)) {
+ (!IsPlayer() || bHasHitWall || car->GetModelIndex() == MI_TRAIN || m_vecDamageNormal.z < -0.8f)) {
m_pCollidingEntity = car;
}
@@ -3231,15 +3842,11 @@ CPed::KillPedWithCar(CVehicle *car, float impulse)
}
m_vecMoveSpeed.z = 0.0f;
distVec.Normalise();
-#ifdef VC_PED_PORTS
distVec *= Min(car->m_fMass / 1400.0f, 1.0f);
-#endif
car->ApplyMoveForce(distVec * -60.0f);
Say(SOUND_PED_DEFEND);
}
-#ifdef VC_PED_PORTS
- // Killing gang members with car wasn't triggering a fight, until now... Taken from VC.
if (IsGangMember()) {
CPed *driver = car->pDriver;
if (driver && driver->IsPlayer()
@@ -3250,5 +3857,347 @@ CPed::KillPedWithCar(CVehicle *car, float impulse)
RegisterThreatWithGangPeds(driver);
}
}
-#endif
-} \ No newline at end of file
+}
+
+void
+CPed::DriveVehicle(void)
+{
+ if (bOffscreen)
+ return;
+
+ CVehicle *veh = m_pMyVehicle;
+ if (veh->IsBike()) {
+ CBike *bike = (CBike*)veh;
+ float blendDelta = 1.0f;
+ float targetUDLean = 0.0f;
+ CAnimBlendAssociation *leftAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_LEFT);
+ CAnimBlendAssociation *rightAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_RIGHT);
+ CAnimBlendAssociation *stillAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_READY);
+ CAnimBlendAssociation *fwdAssoc, *backAssoc;
+ if (IsPlayer()) {
+ fwdAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_LEANF);
+ backAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_LEANB);
+ }
+ CAnimBlendAssociation *walkbackAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_WALKBACK);
+ CAnimBlendAssociation *drivebyAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_DRIVEBY_LHS);
+ if (!drivebyAssoc)
+ drivebyAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_DRIVEBY_RHS);
+ if (!drivebyAssoc)
+ drivebyAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_DRIVEBY_FORWARD);
+
+ float velocityFwdDotProd = DotProduct(bike->m_vecMoveSpeed, bike->GetForward());
+ if (m_vecTurnSpeed.MagnitudeSqr() > 0.09f) {
+ bike->KnockOffRider(WEAPONTYPE_FALL, 2, this, false);
+ if (bike->pPassengers[0])
+ bike->KnockOffRider(WEAPONTYPE_FALL, 2, bike->pPassengers[0], false);
+ return;
+ }
+ if (!drivebyAssoc && Abs(velocityFwdDotProd) < 0.02f) {
+ if (!stillAssoc || stillAssoc->blendAmount < 1.0 && stillAssoc->blendDelta <= 0.0) {
+ stillAssoc = CAnimManager::BlendAnimation(GetClump(), bike->m_bikeAnimType, ANIM_BIKE_READY, 2.0f);
+ }
+ } else {
+ if (velocityFwdDotProd >= 0.0f) {
+ if (stillAssoc && stillAssoc->blendDelta >= 0.0f)
+ stillAssoc->blendDelta = -4.0f;
+ if (walkbackAssoc && walkbackAssoc->blendDelta >= 0.0f)
+ walkbackAssoc->blendDelta = -4.0f;
+ } else {
+ float maxReverseSpeed = bike->pHandling->Transmission.fMaxReverseVelocity;
+ if (3.5f * maxReverseSpeed > velocityFwdDotProd && (bike->m_nWheelsOnGround || bike->GetUp().z < -0.5f)) {
+ bike->KnockOffRider(WEAPONTYPE_FALL, 2, this, false);
+ if (bike->pPassengers[0])
+ bike->KnockOffRider(WEAPONTYPE_FALL, 2, bike->pPassengers[0], false);
+ return;
+ }
+ if (bike->m_fGasPedal >= 0.0 || velocityFwdDotProd <= maxReverseSpeed * 1.5) {
+ if (IsPlayer() && velocityFwdDotProd < maxReverseSpeed * 1.5)
+ targetUDLean = -1.0f;
+
+ if (stillAssoc && stillAssoc->blendDelta >= 0.0f)
+ stillAssoc->blendDelta = -4.0f;
+
+ if (walkbackAssoc && walkbackAssoc->blendDelta >= 0.0f) {
+ walkbackAssoc->blendDelta = -4.0f;
+ }
+ } else if (!walkbackAssoc || walkbackAssoc->blendAmount < 1.0f && walkbackAssoc->blendDelta <= 0.0f) {
+ walkbackAssoc = CAnimManager::BlendAnimation(GetClump(), bike->m_bikeAnimType, ANIM_BIKE_WALKBACK, 4.0f);
+ }
+ }
+ }
+ if (stillAssoc)
+ blendDelta -= Min(1.0f, CTimer::GetTimeStepNonClipped() * 0.02f * stillAssoc->blendDelta + stillAssoc->blendAmount);
+
+ if (drivebyAssoc)
+ blendDelta -= Min(blendDelta, CTimer::GetTimeStepNonClipped() * 0.02f * drivebyAssoc->blendDelta + drivebyAssoc->blendAmount);
+
+ if (walkbackAssoc)
+ blendDelta -= Min(blendDelta, CTimer::GetTimeStepNonClipped() * 0.02f * walkbackAssoc->blendDelta + walkbackAssoc->blendAmount);
+
+ float targetLRLean, timeBlend, neededAngForWheelie, stoppieAng;
+
+ // Smooth the lean amount
+ if (targetUDLean == -1.0f) {
+ targetLRLean = 0.0f;
+ timeBlend = Pow(0.86f, CTimer::GetTimeStep());
+ } else {
+ targetLRLean = Clamp(bike->m_fLeanLRAngle / bike->pBikeHandling->fFullAnimLean, -1.0f, 1.0f);
+ timeBlend = Pow(0.86f, CTimer::GetTimeStep());
+ }
+
+ bike->m_fPedLeanAmountLR = bike->m_fPedLeanAmountLR * timeBlend + (1.0 - timeBlend) * targetLRLean;
+
+ if (!IsPlayer()) {
+ targetUDLean = 0.0f;
+
+ } else if (targetUDLean > -1.0f) {
+ targetUDLean = bike->m_fLeanInput;
+ bike->bWheelieCam = false;
+ neededAngForWheelie = 1.0f;
+ if (bike->m_aWheelTimer[0] != 0.0f || bike->m_aWheelTimer[1] != 0.0f || bike->GetForward().z <= 0.0f ||
+ (0.0f == bike->m_aWheelTimer[2] && 0.0f == bike->m_aWheelTimer[3])) {
+
+ if (0.0f == bike->m_aWheelTimer[2] && 0.0f == bike->m_aWheelTimer[3] &&
+ (bike->GetForward().z < 0.0f && (bike->m_aWheelTimer[0] != 0.0f || bike->m_aWheelTimer[1] != 0.0f))) {
+
+ stoppieAng = bike->pBikeHandling->fStoppieAng;
+ if (stoppieAng - bike->GetForward().z > 0.6f * stoppieAng)
+ bike->bWheelieCam = true;
+ }
+ } else {
+ float wheelieAng = bike->pBikeHandling->fWheelieAng;
+ neededAngForWheelie = wheelieAng - bike->GetForward().z;
+ if (neededAngForWheelie < wheelieAng / 2.f)
+ bike->bWheelieCam = true;
+ }
+ if (neededAngForWheelie >= 0.15f) {
+ if (bike->m_fBrakePedal <= 0.5f || velocityFwdDotProd <= 0.01f) {
+ if (bike->m_fGasPedal > 0.5f && targetUDLean <= 0.0f && 0.3f * bike->pHandling->Transmission.fMaxCruiseVelocity > velocityFwdDotProd) {
+ targetUDLean = Min(0.1f, targetUDLean);
+ }
+ } else {
+ targetUDLean = Max(0.1f, targetUDLean);
+ }
+ } else {
+ targetUDLean = Max(0.25f, targetUDLean);
+ }
+ float targetLRLeanABS = Abs(targetLRLean);
+ if (targetLRLeanABS > 0.3f) {
+ // Yes, UD
+ targetUDLean *= Max(0.0f, 1.0f - (targetLRLeanABS - 0.3f) * 50.f / 13.f);
+ }
+ }
+ if (IsPlayer()) {
+ float timeBlend = Pow(0.89f, CTimer::GetTimeStep());
+ bike->m_fPedLeanAmountUD = (timeBlend * bike->m_fPedLeanAmountUD) + ((1.0f - timeBlend) * targetUDLean);
+ } else {
+ bike->m_fPedLeanAmountUD = 0.0f;
+ }
+
+ float fwdBackLeanAmount, leftRightLeanAmount;
+ if (Abs(bike->m_fPedLeanAmountLR) <= 0.56f && IsPlayer()) {
+
+ if (Abs(bike->m_fPedLeanAmountUD) <= 0.56f) {
+ CVector2D smoothedLean(bike->m_fPedLeanAmountLR, bike->m_fPedLeanAmountUD);
+ float smoothLeanMag = smoothedLean.Magnitude();
+ if (smoothLeanMag <= 0.01f) {
+ fwdBackLeanAmount = Abs(smoothedLean.y);
+ leftRightLeanAmount = Abs(smoothedLean.x);
+ } else {
+ fwdBackLeanAmount = Abs(smoothedLean.y / smoothLeanMag);
+ leftRightLeanAmount = Abs(smoothedLean.x / smoothLeanMag);
+ }
+ } else {
+ fwdBackLeanAmount = 1.0f;
+ leftRightLeanAmount = 0.0f;
+ }
+ } else {
+ fwdBackLeanAmount = 0.0f;
+ leftRightLeanAmount = 1.0f;
+ }
+ float fwdBackBlend = fwdBackLeanAmount * blendDelta;
+ float leftRightBlend = leftRightLeanAmount * blendDelta;
+ if (IsPlayer()) {
+ if (!fwdAssoc)
+ fwdAssoc = CAnimManager::AddAnimation(GetClump(), bike->m_bikeAnimType, ANIM_BIKE_LEANF);
+ if (!backAssoc)
+ backAssoc = CAnimManager::AddAnimation(GetClump(), bike->m_bikeAnimType, ANIM_BIKE_LEANB);
+
+ if (bike->m_fPedLeanAmountUD < 0.0f) {
+ backAssoc->blendAmount = fwdBackBlend;
+ backAssoc->SetCurrentTime(-(bike->m_fPedLeanAmountUD * backAssoc->hierarchy->totalLength));
+ backAssoc->flags &= ~ASSOC_RUNNING;
+ fwdAssoc->blendAmount = 0.0f;
+ } else {
+ fwdAssoc->blendAmount = fwdBackBlend;
+ fwdAssoc->SetCurrentTime(bike->m_fPedLeanAmountUD* fwdAssoc->hierarchy->totalLength);
+ fwdAssoc->flags &= ~ASSOC_RUNNING;
+ backAssoc->blendAmount = 0.0f;
+ }
+ }
+ if (!leftAssoc)
+ leftAssoc = CAnimManager::AddAnimation(GetClump(), bike->m_bikeAnimType, ANIM_BIKE_LEFT);
+ if (!rightAssoc)
+ rightAssoc = CAnimManager::AddAnimation(GetClump(), bike->m_bikeAnimType, ANIM_BIKE_RIGHT);
+
+ if (bike->m_fPedLeanAmountLR < 0.0f) {
+ leftAssoc->blendAmount = leftRightBlend;
+ leftAssoc->SetCurrentTime(-(bike->m_fPedLeanAmountLR * leftAssoc->hierarchy->totalLength));
+ leftAssoc->flags &= ~ASSOC_RUNNING;
+ rightAssoc->blendAmount = 0.0f;
+ } else {
+ rightAssoc->blendAmount = leftRightBlend;
+ rightAssoc->SetCurrentTime(bike->m_fPedLeanAmountLR* rightAssoc->hierarchy->totalLength);
+ rightAssoc->flags &= ~ASSOC_RUNNING;
+ leftAssoc->blendAmount = 0.0f;
+ }
+ if (velocityFwdDotProd > 0.3f) {
+ RwV3d Xaxis = { 1.0f, 0.0f, 0.0f };
+ RwV3d Yaxis = { 0.0f, 1.0f, 0.0f };
+ RtQuatRotate(&m_pFrames[PED_HEAD]->hanimFrame->q, &Xaxis, CGeneral::GetRandomNumberInRange(-6.0f * velocityFwdDotProd, 6.0f * velocityFwdDotProd), rwCOMBINEPOSTCONCAT);
+ RtQuatRotate(&m_pFrames[PED_HEAD]->hanimFrame->q, &Yaxis, CGeneral::GetRandomNumberInRange(-6.0f * velocityFwdDotProd, 6.0f * velocityFwdDotProd), rwCOMBINEPOSTCONCAT);
+ bDontAcceptIKLookAts = true;
+ }
+ return;
+ }
+
+ if (!IsPlayer())
+ return;
+
+ float steerAngle = m_pMyVehicle->m_fSteerAngle;
+ CAnimBlendAssociation* lDriveAssoc;
+ CAnimBlendAssociation* rDriveAssoc;
+ CAnimBlendAssociation* lbAssoc;
+ CAnimBlendAssociation* sitAssoc;
+ if (m_pMyVehicle->IsBoat() && !(m_pMyVehicle->pHandling->Flags & HANDLING_SIT_IN_BOAT)) {
+ sitAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_BOAT_DRIVE);
+
+ if (!sitAssoc || sitAssoc->blendAmount < 1.0f) {
+ return;
+ }
+
+ lDriveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_BOAT_DRIVE_LEFT);
+ rDriveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_BOAT_DRIVE_RIGHT);
+ lbAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_BOAT_LOOKBEHIND);
+ } else if (m_pMyVehicle->bLowVehicle) {
+ sitAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_SIT_LO);
+
+ if (!sitAssoc || sitAssoc->blendAmount < 1.0f) {
+ return;
+ }
+
+ lDriveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_DRIVE_LEFT_LO);
+ lbAssoc = nil;
+ rDriveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_DRIVE_RIGHT_LO);
+ } else {
+ sitAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_SIT);
+
+ if (!sitAssoc || sitAssoc->blendAmount < 1.0f) {
+ return;
+ }
+
+ lDriveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_DRIVE_LEFT);
+ rDriveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_DRIVE_RIGHT);
+ lbAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_LOOKBEHIND);
+ }
+
+ 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_STD_CAR_DRIVEBY_LEFT);
+ if (!driveByAssoc)
+ driveByAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_DRIVEBY_RIGHT);
+ if (!driveByAssoc)
+ driveByAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_DRIVEBY_LEFT_LO);
+ if (!driveByAssoc)
+ driveByAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_DRIVEBY_RIGHT_LO);
+
+ if (m_pMyVehicle->bLowVehicle || m_pMyVehicle->m_fGasPedal >= 0.0f || driveByAssoc ||
+ m_pMyVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI || m_pMyVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_PLANE) {
+ if (steerAngle == 0.0f || driveByAssoc) {
+ if (lDriveAssoc)
+ lDriveAssoc->blendAmount = 0.0f;
+ if (rDriveAssoc)
+ rDriveAssoc->blendAmount = 0.0f;
+
+ } else if (steerAngle <= 0.0f) {
+ if (lDriveAssoc)
+ lDriveAssoc->blendAmount = 0.0f;
+
+ 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_STD_BOAT_DRIVE_RIGHT);
+ else if (m_pMyVehicle->bLowVehicle)
+ CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_DRIVE_RIGHT_LO);
+ else
+ CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_DRIVE_RIGHT);
+
+ } else {
+ if (rDriveAssoc)
+ rDriveAssoc->blendAmount = 0.0f;
+
+ 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_STD_BOAT_DRIVE_LEFT);
+ else if (m_pMyVehicle->bLowVehicle)
+ CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_DRIVE_LEFT_LO);
+ else
+ CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_DRIVE_LEFT);
+ }
+
+ if (lbAssoc)
+ lbAssoc->blendDelta = -4.0f;
+ } else {
+
+ if ((TheCamera.Cams[TheCamera.ActiveCam].Mode != CCam::MODE_1STPERSON
+ || TheCamera.Cams[TheCamera.ActiveCam].DirectionWasLooking != LOOKING_LEFT)
+ && (!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_STD_BOAT_LOOKBEHIND, 4.0f);
+ else
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_LOOKBEHIND, 4.0f);
+ }
+ }
+}
+
+void
+CPed::RemoveWeaponAnims(int unused, float animDelta)
+{
+ CAnimBlendAssociation *weaponAssoc;
+ //CWeaponInfo::GetWeaponInfo(unused);
+
+ weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_FIRE);
+ if (weaponAssoc) {
+ weaponAssoc->blendDelta = animDelta;
+ weaponAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ }
+ weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_FIRE_2ND);
+ if (weaponAssoc) {
+ weaponAssoc->blendDelta = animDelta;
+ weaponAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ }
+ weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_FIRE_3RD);
+ if (weaponAssoc) {
+ weaponAssoc->blendDelta = animDelta;
+ weaponAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ }
+ weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_RELOAD);
+ if (weaponAssoc) {
+ weaponAssoc->blendDelta = animDelta;
+ weaponAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ }
+ weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_MELEE_IDLE_FIGHTMODE);
+ if (weaponAssoc) {
+ weaponAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ if (weaponAssoc->flags & ASSOC_PARTIAL)
+ weaponAssoc->blendDelta = animDelta;
+ else
+ CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_STD_IDLE, -animDelta);
+ }
+}
diff --git a/src/peds/PedIK.cpp b/src/peds/PedIK.cpp
index 8358a196..cf2e4ed5 100644
--- a/src/peds/PedIK.cpp
+++ b/src/peds/PedIK.cpp
@@ -7,11 +7,11 @@
#include "General.h"
#include "RwHelper.h"
-LimbMovementInfo CPedIK::ms_torsoInfo = { DEGTORAD(50.0f), DEGTORAD(-50.0f), DEGTORAD(15.0f), DEGTORAD(45.0f), DEGTORAD(-45.0f), DEGTORAD(7.0f) };
-LimbMovementInfo CPedIK::ms_headInfo = { DEGTORAD(90.0f), DEGTORAD(-90.0f), DEGTORAD(10.0f), DEGTORAD(45.0f), DEGTORAD(-45.0f), DEGTORAD(5.0f) };
+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) };
LimbMovementInfo CPedIK::ms_headRestoreInfo = { DEGTORAD(90.0f), DEGTORAD(-90.0f), DEGTORAD(10.0f), DEGTORAD(45.0f), DEGTORAD(-45.0f), DEGTORAD(5.0f) };
-LimbMovementInfo CPedIK::ms_upperArmInfo = { DEGTORAD(20.0f), DEGTORAD(-100.0f), DEGTORAD(20.0f), DEGTORAD(70.0f), DEGTORAD(-70.0f), DEGTORAD(10.0f) };
-LimbMovementInfo CPedIK::ms_lowerArmInfo = { DEGTORAD(80.0f), DEGTORAD(0.0f), DEGTORAD(20.0f), DEGTORAD(90.0f), DEGTORAD(-90.0f), DEGTORAD(5.0f) };
+LimbMovementInfo CPedIK::ms_upperArmInfo = { DEGTORAD(5.0f), DEGTORAD(-120.0f), DEGTORAD(20.0f), DEGTORAD(70.0f), DEGTORAD(-70.0f), DEGTORAD(20.0f) };
+LimbMovementInfo CPedIK::ms_lowerArmInfo = { DEGTORAD(60.0f), DEGTORAD(0.0f), DEGTORAD(15.0f), DEGTORAD(90.0f), DEGTORAD(-90.0f), DEGTORAD(10.0f) };
const RwV3d XaxisIK = { 1.0f, 0.0f, 0.0f};
const RwV3d YaxisIK = { 0.0f, 1.0f, 0.0f};
@@ -31,7 +31,6 @@ CPedIK::CPedIK(CPed *ped) : m_ped(ped)
m_lowerArmOrient.pitch = 0.0f;
}
-#ifdef PED_SKIN
inline RwMatrix*
GetBoneMatrix(CPed *ped, int32 bone)
{
@@ -45,134 +44,20 @@ GetComponentMatrix(CPed *ped, int32 node)
{
return GetBoneMatrix(ped, ped->m_pFrames[node]->nodeID);
}
-#endif
void
CPedIK::RotateTorso(AnimBlendFrameData *node, LimbOrientation *limb, bool changeRoll)
{
-#ifdef PED_SKIN
- if(IsClumpSkinned(m_ped->GetClump())){
- RtQuat *q = &node->hanimFrame->q;
-#ifndef FIX_BUGS
- // this is what the game does (also VC), but it does not look great
- RtQuatRotate(q, &XaxisIK, RADTODEG(limb->yaw), rwCOMBINEPRECONCAT);
- RtQuatRotate(q, &ZaxisIK, RADTODEG(limb->pitch), rwCOMBINEPRECONCAT); // pitch
-#else
- // copied the code from the non-skinned case
- // this seems to work ok
-
- // We can't get the parent matrix of an hanim frame but
- // this function is always called with PED_MID, so we know the parent frame.
- // Trouble is that PED_MID is "Smid" on PS2/PC but BONE_torso on mobile/xbox...
- // Assuming BONE_torso, the parent is BONE_mid, so let's use that:
- RwMatrix *mat = GetBoneMatrix(m_ped, BONE_mid);
-
- RwV3d vec1, vec2;
- vec1.x = mat->right.z;
- vec1.y = mat->up.z;
- vec1.z = mat->at.z;
- float c = Cos(m_ped->m_fRotationCur);
- float s = Sin(m_ped->m_fRotationCur);
- vec2.x = -(c*mat->right.x + s*mat->right.y);
- vec2.y = -(c*mat->up.x + s*mat->up.y);
- vec2.z = -(c*mat->at.x + s*mat->at.y);
-
- // Not sure what exactly to do here
- RtQuatRotate(q, &vec1, RADTODEG(limb->yaw), rwCOMBINEPRECONCAT);
- RtQuatRotate(q, &vec2, RADTODEG(limb->pitch), rwCOMBINEPRECONCAT);
-#endif
- m_ped->bDontAcceptIKLookAts = true;
- }else
-#endif
- {
- RwFrame *f = node->frame;
- RwMatrix *mat = GetWorldMatrix(RwFrameGetParent(f), RwMatrixCreate());
-
- RwV3d upVector = { mat->right.z, mat->up.z, mat->at.z };
- RwV3d rightVector;
- RwV3d pos = RwFrameGetMatrix(f)->pos;
-
- // rotation == 0 -> looking in y direction
- // left? vector
- float c = Cos(m_ped->m_fRotationCur);
- float s = Sin(m_ped->m_fRotationCur);
- rightVector.x = -(c*mat->right.x + s*mat->right.y);
- rightVector.y = -(c*mat->up.x + s*mat->up.y);
- rightVector.z = -(c*mat->at.x + s*mat->at.y);
-
- if(changeRoll){
- // Used when aiming only involves over the legs.(canAimWithArm)
- // Automatically changes roll(forward rotation) axis of the parts above upper legs while moving, based on position of upper legs.
- // Not noticeable in normal conditions...
-
- RwV3d forwardVector;
- CVector inversedForward = CrossProduct(CVector(0.0f, 0.0f, 1.0f), mat->up);
- inversedForward.Normalise();
- float dotProduct = DotProduct(mat->at, inversedForward);
- if(dotProduct > 1.0f) dotProduct = 1.0f;
- if(dotProduct < -1.0f) dotProduct = -1.0f;
- float alpha = Acos(dotProduct);
-
- if(mat->at.z < 0.0f)
- alpha = -alpha;
-
- forwardVector.x = s * mat->right.x - c * mat->right.y;
- forwardVector.y = s * mat->up.x - c * mat->up.y;
- forwardVector.z = s * mat->at.x - c * mat->at.y;
-
- float curYaw, curPitch;
- ExtractYawAndPitchWorld(mat, &curYaw, &curPitch);
- RwMatrixRotate(RwFrameGetMatrix(f), &rightVector, RADTODEG(limb->pitch), rwCOMBINEPOSTCONCAT);
- RwMatrixRotate(RwFrameGetMatrix(f), &upVector, RADTODEG(limb->yaw - (curYaw - m_ped->m_fRotationCur)), rwCOMBINEPOSTCONCAT);
- RwMatrixRotate(RwFrameGetMatrix(f), &forwardVector, RADTODEG(alpha), rwCOMBINEPOSTCONCAT);
- }else{
- // pitch
- RwMatrixRotate(RwFrameGetMatrix(f), &rightVector, RADTODEG(limb->pitch), rwCOMBINEPOSTCONCAT);
- // yaw
- RwMatrixRotate(RwFrameGetMatrix(f), &upVector, RADTODEG(limb->yaw), rwCOMBINEPOSTCONCAT);
- }
- RwFrameGetMatrix(f)->pos = pos;
- RwMatrixDestroy(mat);
- }
+ RtQuat *q = &node->hanimFrame->q;
+ RtQuatRotate(q, &XaxisIK, RADTODEG(limb->yaw), rwCOMBINEREPLACE);
+ RtQuatRotate(q, &ZaxisIK, RADTODEG(limb->pitch), rwCOMBINEPRECONCAT);
+ m_ped->bDontAcceptIKLookAts = true;
}
void
CPedIK::GetComponentPosition(RwV3d &pos, uint32 node)
{
- RwFrame *f;
- RwMatrix *mat;
-
-#ifdef PED_SKIN
- if(IsClumpSkinned(m_ped->GetClump())){
- pos.x = 0.0f;
- pos.y = 0.0f;
- pos.z = 0.0f;
- mat = GetComponentMatrix(m_ped, node);
- // could just copy the position out of the matrix...
- RwV3dTransformPoints(&pos, &pos, 1, mat);
- }else
-#endif
- {
- f = m_ped->m_pFrames[node]->frame;
- mat = RwFrameGetMatrix(f);
- pos = mat->pos;
-
- for (f = RwFrameGetParent(f); f; f = RwFrameGetParent(f))
- RwV3dTransformPoints(&pos, &pos, 1, RwFrameGetMatrix(f));
- }
-}
-
-RwMatrix*
-CPedIK::GetWorldMatrix(RwFrame *source, RwMatrix *destination)
-{
- RwFrame *i;
-
- *destination = *RwFrameGetMatrix(source);
-
- for (i = RwFrameGetParent(source); i; i = RwFrameGetParent(i))
- RwMatrixTransform(destination, RwFrameGetMatrix(i), rwCOMBINEPOSTCONCAT);
-
- return destination;
+ pos = GetComponentMatrix(m_ped, node)->pos;
}
LimbMoveStatus
@@ -182,15 +67,15 @@ CPedIK::MoveLimb(LimbOrientation &limb, float targetYaw, float targetPitch, Limb
// yaw
- if (limb.yaw > targetYaw) {
- limb.yaw -= moveInfo.yawD;
- } else if (limb.yaw < targetYaw) {
- limb.yaw += moveInfo.yawD;
- }
-
- if (Abs(limb.yaw - targetYaw) < moveInfo.yawD) {
+ if(Abs(limb.yaw-targetYaw) < moveInfo.yawD){
limb.yaw = targetYaw;
result = ANGLES_SET_EXACTLY;
+ }else{
+ if (limb.yaw > targetYaw) {
+ limb.yaw -= moveInfo.yawD;
+ } else if (limb.yaw < targetYaw) {
+ limb.yaw += moveInfo.yawD;
+ }
}
if (limb.yaw > moveInfo.maxYaw || limb.yaw < moveInfo.minYaw) {
@@ -200,16 +85,16 @@ CPedIK::MoveLimb(LimbOrientation &limb, float targetYaw, float targetPitch, Limb
// pitch
- if (limb.pitch > targetPitch) {
- limb.pitch -= moveInfo.pitchD;
- } else if (limb.pitch < targetPitch) {
- limb.pitch += moveInfo.pitchD;
- }
-
- if (Abs(limb.pitch - targetPitch) < moveInfo.pitchD)
+ if (Abs(limb.pitch - targetPitch) < moveInfo.pitchD){
limb.pitch = targetPitch;
- else
+ }else{
+ if (limb.pitch > targetPitch) {
+ limb.pitch -= moveInfo.pitchD;
+ } else if (limb.pitch < targetPitch) {
+ limb.pitch += moveInfo.pitchD;
+ }
result = ONE_ANGLE_COULDNT_BE_SET_EXACTLY;
+ }
if (limb.pitch > moveInfo.maxPitch || limb.pitch < moveInfo.minPitch) {
limb.pitch = Clamp(limb.pitch, moveInfo.minPitch, moveInfo.maxPitch);
@@ -226,107 +111,60 @@ CPedIK::RestoreGunPosn(void)
return limbStatus == ANGLES_SET_EXACTLY;
}
-#ifdef PED_SKIN
-void
-CPedIK::RotateHead(void)
-{
- RtQuat *q = &m_ped->m_pFrames[PED_HEAD]->hanimFrame->q;
- RtQuatRotate(q, &XaxisIK, RADTODEG(m_headOrient.yaw), rwCOMBINEREPLACE);
- RtQuatRotate(q, &ZaxisIK, RADTODEG(m_headOrient.pitch), rwCOMBINEPOSTCONCAT);
- m_ped->bDontAcceptIKLookAts = true;
-}
-#endif
-
bool
CPedIK::LookInDirection(float targetYaw, float targetPitch)
{
bool success = true;
float yaw, pitch;
-#ifdef PED_SKIN
- if(IsClumpSkinned(m_ped->GetClump())){
- if (!(m_ped->m_pFrames[PED_HEAD]->flag & AnimBlendFrameData::IGNORE_ROTATION)) {
- m_ped->m_pFrames[PED_HEAD]->flag |= AnimBlendFrameData::IGNORE_ROTATION;
- ExtractYawAndPitchLocalSkinned(m_ped->m_pFrames[PED_HEAD], &m_headOrient.yaw, &m_headOrient.pitch);
- }
-
- // parent of head is torso
- RwMatrix worldMat = *GetBoneMatrix(m_ped, BONE_torso);
- ExtractYawAndPitchWorld(&worldMat, &yaw, &pitch);
-
- LimbMoveStatus headStatus = MoveLimb(m_headOrient, CGeneral::LimitRadianAngle(targetYaw - yaw),
- CGeneral::LimitRadianAngle(DEGTORAD(10.0f)), ms_headInfo);
- if (headStatus == ANGLES_SET_TO_MAX)
- success = false;
-
- if (headStatus != ANGLES_SET_EXACTLY){
- if (!(m_flags & LOOKAROUND_HEAD_ONLY)){
- if (MoveLimb(m_torsoOrient, CGeneral::LimitRadianAngle(targetYaw), targetPitch, ms_torsoInfo))
- success = true;
- }else{
- RotateHead();
- return success;
- }
- }
-
- if (!(m_flags & LOOKAROUND_HEAD_ONLY))
- RotateTorso(m_ped->m_pFrames[PED_MID], &m_torsoOrient, false);
- RotateHead();
- }else
-#endif
- {
- RwFrame *frame = m_ped->m_pFrames[PED_HEAD]->frame;
- RwMatrix *frameMat = RwFrameGetMatrix(frame);
-
- if (!(m_ped->m_pFrames[PED_HEAD]->flag & AnimBlendFrameData::IGNORE_ROTATION)) {
- m_ped->m_pFrames[PED_HEAD]->flag |= AnimBlendFrameData::IGNORE_ROTATION;
- ExtractYawAndPitchLocal(frameMat, &m_headOrient.yaw, &m_headOrient.pitch);
- }
-
- RwMatrix *worldMat = RwMatrixCreate();
- worldMat = GetWorldMatrix(RwFrameGetParent(frame), worldMat);
-
- ExtractYawAndPitchWorld(worldMat, &yaw, &pitch);
- RwMatrixDestroy(worldMat);
-
- yaw += m_torsoOrient.yaw;
- float neededYawTurn = CGeneral::LimitRadianAngle(targetYaw - yaw);
- pitch *= Cos(neededYawTurn);
+ if (!(m_ped->m_pFrames[PED_HEAD]->flag & AnimBlendFrameData::IGNORE_ROTATION)) {
+ m_ped->m_pFrames[PED_HEAD]->flag |= AnimBlendFrameData::IGNORE_ROTATION;
+ RwMatrix *m = GetComponentMatrix(m_ped, PED_NECK);
+ m_headOrient.yaw = Atan2(-m->at.y, -m->at.x);
+ m_headOrient.yaw -= m_ped->m_fRotationCur;
+ m_headOrient.yaw = CGeneral::LimitRadianAngle(m_headOrient.yaw);
+ float up = Clamp(m->up.z, -1.0f, 1.0f);
+ m_headOrient.pitch = Atan2(-up, Sqrt(1.0f - SQR(-up)));
+ }
- float neededPitchTurn = CGeneral::LimitRadianAngle(targetPitch - pitch);
- LimbMoveStatus headStatus = MoveLimb(m_headOrient, neededYawTurn, neededPitchTurn, ms_headInfo);
- if (headStatus == ANGLES_SET_TO_MAX)
- success = false;
+ // parent of head is neck
+ RwMatrix *m = GetComponentMatrix(m_ped, PED_NECK);
+ yaw = CGeneral::LimitRadianAngle(Atan2(-m->at.y, -m->at.x));
+ float up = Clamp(m->up.z, -1.0f, 1.0f);
+ pitch = Atan2(-up, Sqrt(1.0f - SQR(-up)));
+ float headYaw = CGeneral::LimitRadianAngle(targetYaw - (yaw + m_torsoOrient.yaw));
+ float headPitch = CGeneral::LimitRadianAngle(targetPitch - pitch) * Cos(Min(Abs(headYaw), HALFPI));
- if (headStatus != ANGLES_SET_EXACTLY && !(m_flags & LOOKAROUND_HEAD_ONLY)) {
- float remainingTurn = CGeneral::LimitRadianAngle(targetYaw - m_ped->m_fRotationCur);
- if (MoveLimb(m_torsoOrient, remainingTurn, targetPitch, ms_torsoInfo))
- success = true;
- }
- CMatrix nextFrame = CMatrix(frameMat);
- CVector framePos = nextFrame.GetPosition();
+ LimbMoveStatus headStatus = MoveLimb(m_headOrient, headYaw, headPitch, ms_headInfo);
+ if (headStatus == ANGLES_SET_TO_MAX)
+ success = false;
- nextFrame.SetRotateZ(m_headOrient.pitch);
- nextFrame.RotateX(m_headOrient.yaw);
- nextFrame.GetPosition() += framePos;
- nextFrame.UpdateRW();
+ if (headStatus != ANGLES_SET_EXACTLY && !(m_flags & LOOKAROUND_HEAD_ONLY))
+ if (MoveLimb(m_torsoOrient, CGeneral::LimitRadianAngle(targetYaw-m_ped->m_fRotationCur), targetPitch, ms_torsoInfo))
+ success = true;
- if (!(m_flags & LOOKAROUND_HEAD_ONLY))
- RotateTorso(m_ped->m_pFrames[PED_MID], &m_torsoOrient, false);
+ // This was RotateHead
+ RtQuat *q = &m_ped->m_pFrames[PED_HEAD]->hanimFrame->q;
+ RtQuatRotate(q, &ZaxisIK, RADTODEG(m_headOrient.pitch), rwCOMBINEREPLACE);
+ RtQuatRotate(q, &XaxisIK, RADTODEG(m_headOrient.yaw), rwCOMBINEPRECONCAT);
+ m_ped->bDontAcceptIKLookAts = true;
- }
+ if (!(m_flags & LOOKAROUND_HEAD_ONLY))
+ RotateTorso(m_ped->m_pFrames[PED_MID], &m_torsoOrient, false);
return success;
}
bool
CPedIK::LookAtPosition(CVector const &pos)
{
+ RwV3d *pedpos = &GetComponentMatrix(m_ped, PED_MID)->pos;
float yawToFace = CGeneral::GetRadianAngleBetweenPoints(
pos.x, pos.y,
- m_ped->GetPosition().x, m_ped->GetPosition().y);
+ pedpos->x, pedpos->y);
float pitchToFace = CGeneral::GetRadianAngleBetweenPoints(
+ // BUG? not using pedpos here
pos.z, (m_ped->GetPosition() - pos).Magnitude2D(),
- m_ped->GetPosition().z, 0.0f);
+ pedpos->z, 0.0f);
return LookInDirection(yawToFace, pitchToFace);
}
@@ -336,12 +174,12 @@ CPedIK::PointGunInDirection(float targetYaw, float targetPitch)
{
bool result = true;
bool armPointedToGun = false;
- float angle = CGeneral::LimitRadianAngle(targetYaw - m_ped->m_fRotationCur);
- m_flags &= (~GUN_POINTED_SUCCESSFULLY);
+ targetYaw = CGeneral::LimitRadianAngle(targetYaw - m_ped->GetForward().Heading());
+ m_flags &= ~GUN_POINTED_SUCCESSFULLY;
m_flags |= LOOKAROUND_HEAD_ONLY;
if (m_flags & AIMS_WITH_ARM) {
- armPointedToGun = PointGunInDirectionUsingArm(angle, targetPitch);
- angle = CGeneral::LimitRadianAngle(angle - m_upperArmOrient.yaw);
+ armPointedToGun = PointGunInDirectionUsingArm(targetYaw, targetPitch);
+ targetYaw = CGeneral::LimitRadianAngle(targetYaw - (m_upperArmOrient.yaw + m_lowerArmOrient.yaw));
}
if (armPointedToGun) {
if (m_flags & AIMS_WITH_ARM && m_torsoOrient.yaw * m_upperArmOrient.yaw < 0.0f)
@@ -350,31 +188,35 @@ CPedIK::PointGunInDirection(float targetYaw, float targetPitch)
// Unused code
RwMatrix *matrix;
float yaw, pitch;
-#ifdef PED_SKIN
- if(IsClumpSkinned(m_ped->GetClump())){
- matrix = RwMatrixCreate();
- *matrix = *GetComponentMatrix(m_ped, PED_UPPERARMR);
- ExtractYawAndPitchWorld(matrix, &yaw, &pitch);
- RwMatrixDestroy(matrix);
- }else
-#endif
- {
- matrix = GetWorldMatrix(RwFrameGetParent(m_ped->m_pFrames[PED_UPPERARMR]->frame), RwMatrixCreate());
- ExtractYawAndPitchWorld(matrix, &yaw, &pitch);
- RwMatrixDestroy(matrix);
- }
- //
+ matrix = RwMatrixCreate();
+ *matrix = *GetComponentMatrix(m_ped, PED_CLAVICLER);
+ ExtractYawAndPitchWorld(matrix, &yaw, &pitch);
+ RwMatrixDestroy(matrix);
- LimbMoveStatus status = MoveLimb(m_torsoOrient, angle, targetPitch, ms_torsoInfo);
+ if(m_flags & AIMS_WITH_ARM){
+ if(targetPitch > 0.0f)
+ targetPitch = Max(targetPitch - Abs(targetYaw), 0.0f);
+ else
+ targetPitch = Min(targetPitch + Abs(targetYaw), 0.0f);
+ }
+ LimbMoveStatus status = MoveLimb(m_torsoOrient, targetYaw, targetPitch, ms_torsoInfo);
if (status == ANGLES_SET_TO_MAX)
result = false;
else if (status == ANGLES_SET_EXACTLY)
m_flags |= GUN_POINTED_SUCCESSFULLY;
}
- if (TheCamera.Cams[TheCamera.ActiveCam].Using3rdPersonMouseCam() && m_flags & AIMS_WITH_ARM)
- RotateTorso(m_ped->m_pFrames[PED_MID], &m_torsoOrient, true);
- else
- RotateTorso(m_ped->m_pFrames[PED_MID], &m_torsoOrient, false);
+ RwMatrix *m = GetBoneMatrix(m_ped, BONE_spine); // BUG: game uses index 2 directly, which happens to be identical to BONE_spine
+ RwV3d axis = { 0.0f, 0.0f, 0.0f };
+ float axisangle = -CGeneral::LimitRadianAngle(Atan2(-m->at.y, -m->at.x) - m_ped->m_fRotationCur);
+ axis.y = -Sin(axisangle);
+ axis.z = Cos(axisangle);
+
+ // this was RotateTorso
+ RtQuat *q = &m_ped->m_pFrames[PED_MID]->hanimFrame->q;
+ RtQuatRotate(q, &axis, RADTODEG(m_torsoOrient.pitch), rwCOMBINEPOSTCONCAT);
+ RtQuatRotate(q, &XaxisIK, RADTODEG(m_torsoOrient.yaw), rwCOMBINEPOSTCONCAT);
+ m_ped->bDontAcceptIKLookAts = true;
+
return result;
}
@@ -382,103 +224,86 @@ bool
CPedIK::PointGunInDirectionUsingArm(float targetYaw, float targetPitch)
{
bool result = false;
-
- RwV3d upVector; // only for non-skinned
RwMatrix *matrix;
float yaw, pitch;
-#ifdef PED_SKIN
- if(IsClumpSkinned(m_ped->GetClump())){
- matrix = RwMatrixCreate();
- *matrix = *GetComponentMatrix(m_ped, PED_UPPERARMR);
- ExtractYawAndPitchWorld(matrix, &yaw, &pitch);
- RwMatrixDestroy(matrix);
- }else
-#endif
- {
- RwFrame *frame = m_ped->m_pFrames[PED_UPPERARMR]->frame;
- matrix = GetWorldMatrix(RwFrameGetParent(frame), RwMatrixCreate());
-
- // with PED_SKIN this is actually done below (with a memory leak)
- upVector.x = matrix->right.z;
- upVector.y = matrix->up.z;
- upVector.z = matrix->at.z;
- ExtractYawAndPitchWorld(matrix, &yaw, &pitch);
- RwMatrixDestroy(matrix);
- }
+ float uaRoll = 45.0f;
+ float handRoll = 30.0f;
- RwV3d rightVector = { 0.0f, 0.0f, 1.0f };
- RwV3d forwardVector = { 1.0f, 0.0f, 0.0f };
+ matrix = GetComponentMatrix(m_ped, PED_CLAVICLER);
+ yaw = CGeneral::LimitRadianAngle(Atan2(matrix->right.y, matrix->right.x) - m_ped->m_fRotationCur);
+ pitch = Atan2(matrix->up.z, Sqrt(1.0f - SQR(matrix->up.z)));
float uaYaw, uaPitch;
-#ifdef PED_SKIN
- if(IsClumpSkinned(m_ped->GetClump())){
- uaYaw = targetYaw;
- uaPitch = targetPitch + DEGTORAD(10.0f);
- }else
-#endif
- {
- uaYaw = targetYaw - m_torsoOrient.yaw - DEGTORAD(15.0f);
- uaPitch = CGeneral::LimitRadianAngle(targetPitch - pitch);
- }
+ uaYaw = CGeneral::LimitRadianAngle(targetYaw - yaw - DEGTORAD(15.0f));
+ uaPitch = CGeneral::LimitRadianAngle(targetPitch - pitch + DEGTORAD(10.0f));
LimbMoveStatus uaStatus = MoveLimb(m_upperArmOrient, uaYaw, uaPitch, ms_upperArmInfo);
if (uaStatus == ANGLES_SET_EXACTLY) {
m_flags |= GUN_POINTED_SUCCESSFULLY;
result = true;
}
-#ifdef PED_SKIN
- // this code is completely missing on xbox & android, but we can keep it with the check
- // TODO? implement it for skinned geometry?
- if(!IsClumpSkinned(m_ped->GetClump()))
-#endif
if (uaStatus == ANGLES_SET_TO_MAX) {
float laYaw = uaYaw - m_upperArmOrient.yaw;
LimbMoveStatus laStatus;
- if (laYaw > 0.0f)
- laStatus = MoveLimb(m_lowerArmOrient, laYaw, -DEGTORAD(45.0f), ms_lowerArmInfo);
- else
+ if (laYaw > 0.0f){
+ float rollReduce = laYaw/DEGTORAD(30.0f);
+ uaRoll *= 1.0f - Min(rollReduce, 1.0f);
+ handRoll *= 1.0f - Min(rollReduce, 1.0f);
+
+ laYaw *= 1.9f;
+ laStatus = MoveLimb(m_lowerArmOrient, laYaw, 0.0f, ms_lowerArmInfo);
+
+ // some unused statics here
+ float uaPitchAmount = 1.0f - (m_lowerArmOrient.yaw + m_upperArmOrient.yaw) * 0.34f;
+ float f1 = ms_upperArmInfo.maxPitch * Max(uaPitchAmount, 0.0f);
+ float f2 = 0.2f*m_lowerArmOrient.yaw + m_upperArmOrient.pitch;
+ m_upperArmOrient.pitch = Min(f1, f2);
+ }else
laStatus = MoveLimb(m_lowerArmOrient, laYaw, 0.0f, ms_lowerArmInfo);
if (laStatus == ANGLES_SET_EXACTLY) {
m_flags |= GUN_POINTED_SUCCESSFULLY;
result = true;
}
- RwFrame *child = GetFirstChild(m_ped->m_pFrames[PED_UPPERARMR]->frame);
- RwV3d pos = RwFrameGetMatrix(child)->pos;
- RwMatrixRotate(RwFrameGetMatrix(child), &forwardVector, RADTODEG(m_lowerArmOrient.pitch), rwCOMBINEPOSTCONCAT);
- RwMatrixRotate(RwFrameGetMatrix(child), &rightVector, RADTODEG(-m_lowerArmOrient.yaw), rwCOMBINEPOSTCONCAT);
- RwFrameGetMatrix(child)->pos = pos;
- }
-#ifdef PED_SKIN
- if(IsClumpSkinned(m_ped->GetClump())){
- RtQuat *q = &m_ped->m_pFrames[PED_UPPERARMR]->hanimFrame->q;
- RtQuatRotate(q, &XaxisIK, RADTODEG(m_upperArmOrient.yaw), rwCOMBINEPOSTCONCAT);
- RtQuatRotate(q, &ZaxisIK, RADTODEG(m_upperArmOrient.pitch), rwCOMBINEPOSTCONCAT);
+ // game does this stupidly by going through the clump extension...
+ RtQuat *q = &m_ped->m_pFrames[PED_FOREARMR]->hanimFrame->q;
+ RtQuatRotate(q, &ZaxisIK, -RADTODEG(m_lowerArmOrient.yaw), rwCOMBINEREPLACE);
+ RtQuatRotate(q, &XaxisIK, -RADTODEG(m_lowerArmOrient.pitch), rwCOMBINEPOSTCONCAT);
m_ped->bDontAcceptIKLookAts = true;
- }else
-#endif
- {
- RwFrame *frame = m_ped->m_pFrames[PED_UPPERARMR]->frame;
- // with PED_SKIN we're also getting upVector here
- RwV3d pos = RwFrameGetMatrix(frame)->pos;
- RwMatrixRotate(RwFrameGetMatrix(frame), &rightVector, RADTODEG(m_upperArmOrient.pitch), rwCOMBINEPOSTCONCAT);
- RwMatrixRotate(RwFrameGetMatrix(frame), &upVector, RADTODEG(m_upperArmOrient.yaw), rwCOMBINEPOSTCONCAT);
- RwFrameGetMatrix(frame)->pos = pos;
}
+
+ RtQuat *q = &m_ped->m_pFrames[PED_UPPERARMR]->hanimFrame->q;
+ RtQuatRotate(q, &XaxisIK, uaRoll, rwCOMBINEREPLACE);
+ RtQuatRotate(q, &YaxisIK, -RADTODEG(m_upperArmOrient.pitch), rwCOMBINEPOSTCONCAT);
+ RtQuatRotate(q, &ZaxisIK, -RADTODEG(m_upperArmOrient.yaw+HALFPI), rwCOMBINEPOSTCONCAT);
+ m_ped->bDontAcceptIKLookAts = true;
+
+ q = &m_ped->m_pFrames[PED_HANDR]->hanimFrame->q;
+ RtQuatRotate(q, &XaxisIK, handRoll, rwCOMBINEPRECONCAT);
+
return result;
}
bool
CPedIK::PointGunAtPosition(CVector const& position)
{
+ 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
@@ -487,40 +312,24 @@ CPedIK::RestoreLookAt(void)
bool result = false;
float yaw, pitch;
-#ifdef PED_SKIN
- if(IsClumpSkinned(m_ped->GetClump())){
- if (m_ped->m_pFrames[PED_HEAD]->flag & AnimBlendFrameData::IGNORE_ROTATION) {
- m_ped->m_pFrames[PED_HEAD]->flag &= (~AnimBlendFrameData::IGNORE_ROTATION);
- } else {
- ExtractYawAndPitchLocalSkinned(m_ped->m_pFrames[PED_HEAD], &yaw, &pitch);
- if (MoveLimb(m_headOrient, yaw, pitch, ms_headRestoreInfo) == ANGLES_SET_EXACTLY)
- result = true;
- }
- RotateHead();
- }else
-#endif
- {
- RwMatrix *mat = RwFrameGetMatrix(m_ped->m_pFrames[PED_HEAD]->frame);
- if (m_ped->m_pFrames[PED_HEAD]->flag & AnimBlendFrameData::IGNORE_ROTATION) {
- m_ped->m_pFrames[PED_HEAD]->flag &= (~AnimBlendFrameData::IGNORE_ROTATION);
- } else {
- ExtractYawAndPitchLocal(mat, &yaw, &pitch);
- if (MoveLimb(m_headOrient, yaw, pitch, ms_headRestoreInfo) == ANGLES_SET_EXACTLY)
- result = true;
- }
-
- CMatrix matrix(mat);
- CVector pos = matrix.GetPosition();
- matrix.SetRotateZ(m_headOrient.pitch);
- matrix.RotateX(m_headOrient.yaw);
- matrix.Translate(pos);
- matrix.UpdateRW();
+ if (m_ped->m_pFrames[PED_HEAD]->flag & AnimBlendFrameData::IGNORE_ROTATION) {
+ m_ped->m_pFrames[PED_HEAD]->flag &= (~AnimBlendFrameData::IGNORE_ROTATION);
+ } else {
+ ExtractYawAndPitchLocalSkinned(m_ped->m_pFrames[PED_HEAD], &yaw, &pitch);
+ if (MoveLimb(m_headOrient, yaw, pitch, ms_headRestoreInfo) == ANGLES_SET_EXACTLY)
+ result = true;
}
- if (!(m_flags & LOOKAROUND_HEAD_ONLY)){
+
+ // This was RotateHead
+ RtQuat *q = &m_ped->m_pFrames[PED_HEAD]->hanimFrame->q;
+ RtQuatRotate(q, &XaxisIK, RADTODEG(m_headOrient.yaw), rwCOMBINEREPLACE);
+ RtQuatRotate(q, &ZaxisIK, RADTODEG(m_headOrient.pitch), rwCOMBINEPRECONCAT);
+ m_ped->bDontAcceptIKLookAts = true;
+
+ if (!(m_flags & LOOKAROUND_HEAD_ONLY))
MoveLimb(m_torsoOrient, 0.0f, 0.0f, ms_torsoInfo);
- if (!(m_flags & LOOKAROUND_HEAD_ONLY))
- RotateTorso(m_ped->m_pFrames[PED_MID], &m_torsoOrient, false);
- }
+ if (!(m_flags & LOOKAROUND_HEAD_ONLY))
+ RotateTorso(m_ped->m_pFrames[PED_MID], &m_torsoOrient, false);
return result;
}
@@ -548,7 +357,6 @@ CPedIK::ExtractYawAndPitchLocal(RwMatrix *mat, float *yaw, float *pitch)
if (mat->up.x > 0.0f) *pitch = -*pitch;
}
-#ifdef PED_SKIN
void
CPedIK::ExtractYawAndPitchLocalSkinned(AnimBlendFrameData *node, float *yaw, float *pitch)
{
@@ -557,4 +365,3 @@ CPedIK::ExtractYawAndPitchLocalSkinned(AnimBlendFrameData *node, float *yaw, flo
ExtractYawAndPitchLocal(mat, yaw, pitch);
RwMatrixDestroy(mat);
}
-#endif
diff --git a/src/peds/PedIK.h b/src/peds/PedIK.h
index 1543fa34..3011dd5f 100644
--- a/src/peds/PedIK.h
+++ b/src/peds/PedIK.h
@@ -52,14 +52,12 @@ public:
bool PointGunInDirectionUsingArm(float targetYaw, float targetPitch);
bool PointGunAtPosition(CVector const& position);
void GetComponentPosition(RwV3d &pos, uint32 node);
- static RwMatrix *GetWorldMatrix(RwFrame *source, RwMatrix *destination);
void RotateTorso(AnimBlendFrameData* animBlend, LimbOrientation* limb, bool changeRoll);
void ExtractYawAndPitchLocal(RwMatrix *mat, float *yaw, float *pitch);
void ExtractYawAndPitchLocalSkinned(AnimBlendFrameData *node, float *yaw, float *pitch);
void ExtractYawAndPitchWorld(RwMatrix *mat, float *yaw, float *pitch);
LimbMoveStatus MoveLimb(LimbOrientation &limb, float targetYaw, float targetPitch, LimbMovementInfo &moveInfo);
bool RestoreGunPosn(void);
- void RotateHead(void);
bool LookInDirection(float targetYaw, float targetPitch);
bool LookAtPosition(CVector const& pos);
bool RestoreLookAt(void);
diff --git a/src/peds/PedPlacement.cpp b/src/peds/PedPlacement.cpp
index 2d4a92fa..840d33fc 100644
--- a/src/peds/PedPlacement.cpp
+++ b/src/peds/PedPlacement.cpp
@@ -4,7 +4,7 @@
#include "PedPlacement.h"
#include "World.h"
-void
+bool
CPedPlacement::FindZCoorForPed(CVector* pos)
{
float zForPed;
@@ -32,8 +32,11 @@ CPedPlacement::FindZCoorForPed(CVector* pos)
zForPed = Max(foundColZ, foundColZ2);
- if (zForPed > -99.0f)
+ if (zForPed > -99.0f) {
pos->z = FEET_OFFSET + zForPed;
+ return true;
+ }
+ return false;
}
CEntity*
@@ -43,9 +46,13 @@ CPedPlacement::IsPositionClearOfCars(Const CVector *pos)
}
bool
-CPedPlacement::IsPositionClearForPed(CVector* pos)
+CPedPlacement::IsPositionClearForPed(const CVector& pos, float radius, int total, CEntity** entities)
{
int16 count;
- CWorld::FindObjectsKindaColliding(*pos, 0.75f, true, &count, 2, nil, false, true, true, false, false);
+ if (radius == -1.0f)
+ radius = 0.75f;
+ if (total == -1)
+ total = 2;
+ CWorld::FindObjectsKindaColliding(pos, radius, true, &count, total, entities, false, true, true, false, false);
return count == 0;
}
diff --git a/src/peds/PedPlacement.h b/src/peds/PedPlacement.h
index b51e2aad..d1b0cd16 100644
--- a/src/peds/PedPlacement.h
+++ b/src/peds/PedPlacement.h
@@ -2,7 +2,7 @@
class CPedPlacement {
public:
- static void FindZCoorForPed(CVector* pos);
+ static bool FindZCoorForPed(CVector* pos);
static CEntity* IsPositionClearOfCars(Const CVector*);
- static bool IsPositionClearForPed(CVector*);
+ static bool IsPositionClearForPed(const CVector& pos, float radius = -1.0f, int total = -1, CEntity** entities = nil);
}; \ No newline at end of file
diff --git a/src/peds/PedType.h b/src/peds/PedType.h
index 3e23c249..a4698bbb 100644
--- a/src/peds/PedType.h
+++ b/src/peds/PedType.h
@@ -14,9 +14,9 @@ enum ePedType
PEDTYPE_GANG2,
PEDTYPE_GANG3,
PEDTYPE_GANG4,
- PEDTYPE_GANG5,
+ PEDTYPE_GANG5, // Security - hardcoded
PEDTYPE_GANG6,
- PEDTYPE_GANG7,
+ PEDTYPE_GANG7, // Vercetti gang - hardcoded
PEDTYPE_GANG8,
PEDTYPE_GANG9,
PEDTYPE_EMERGENCY,
@@ -130,6 +130,11 @@ enum ePedStats
PEDSTAT_SPORTSFAN,
PEDSTAT_SHOPPER,
PEDSTAT_OLDSHOPPER,
+ PEDSTAT_BEACH_GUY,
+ PEDSTAT_BEACH_GIRL,
+ PEDSTAT_SKATER,
+ PEDSTAT_STD_MISSION,
+ PEDSTAT_COWARD,
NUM_PEDSTATS
};
@@ -170,4 +175,4 @@ public:
static ePedStats GetPedStatType(char *name);
};
-VALIDATE_SIZE(CPedStats, 0x34); \ No newline at end of file
+VALIDATE_SIZE(CPedStats, 0x34);
diff --git a/src/peds/PlayerPed.cpp b/src/peds/PlayerPed.cpp
index 416fb949..b0b82640 100644
--- a/src/peds/PlayerPed.cpp
+++ b/src/peds/PlayerPed.cpp
@@ -16,17 +16,37 @@
#include "Pools.h"
#include "Darkel.h"
#include "CarCtrl.h"
+#include "MBlur.h"
+#include "Streaming.h"
+#include "Population.h"
+#include "Script.h"
+#include "Replay.h"
+#include "PedPlacement.h"
+#include "VarConsole.h"
#include "SaveBuf.h"
#define PAD_MOVE_TO_GAME_WORLD_MOVE 60.0f
+bool CPlayerPed::bDontAllowWeaponChange;
+#ifndef MASTER
+bool CPlayerPed::bDebugPlayerInfo;
+#endif
+
const uint32 CPlayerPed::nSaveStructSize =
#ifdef COMPATIBLE_SAVES
- 1520;
+ 1752;
#else
sizeof(CPlayerPed);
#endif
+int32 idleAnimBlockIndex;
+
+CPad*
+GetPadFromPlayer(CPlayerPed*)
+{
+ return CPad::GetPad(0);
+}
+
CPlayerPed::~CPlayerPed()
{
delete m_pWanted;
@@ -45,7 +65,7 @@ CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1)
m_pWanted->Initialise();
m_pArrestingCop = nil;
m_currentWeapon = WEAPONTYPE_UNARMED;
- m_nSelectedWepSlot = WEAPONTYPE_UNARMED;
+ m_nSelectedWepSlot = WEAPONSLOT_UNARMED;
m_nSpeedTimer = 0;
m_bSpeedTimerFlag = false;
SetWeaponLockOnTarget(nil);
@@ -55,23 +75,36 @@ CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1)
#endif
m_fStaminaProgress = 0.0f;
m_nEvadeAmount = 0;
- field_1367 = 0;
+ m_pEvadingFrom = nil;
m_nHitAnimDelayTimer = 0;
m_fAttackButtonCounter = 0.0f;
m_bHaveTargetSelected = false;
m_bHasLockOnTarget = false;
m_bCanBeDamaged = true;
+ m_bNoPosForMeleeAttack = false;
m_fWalkAngle = 0.0f;
m_fFPSMoveHeading = 0.0f;
+ m_pMinigunTopAtomic = nil;
+ m_fGunSpinSpeed = 0.0;
+ m_fGunSpinAngle = 0.0;
+ m_nPadDownPressedInMilliseconds = 0;
m_nTargettableObjects[0] = m_nTargettableObjects[1] = m_nTargettableObjects[2] = m_nTargettableObjects[3] = -1;
- field_1413 = 0;
+ unk1 = false;
for (int i = 0; i < 6; i++) {
m_vecSafePos[i] = CVector(0.0f, 0.0f, 0.0f);
m_pPedAtSafePos[i] = nil;
+ m_pMeleeList[i] = nil;
}
+ m_nAttackDirToCheck = 0;
+ m_nLastBusFareCollected = 0;
+ idleAnimBlockIndex = CAnimManager::GetAnimationBlockIndex("playidles");
+#ifdef FREE_CAM
+ m_bFreeAimActive = false;
+#endif
}
-void CPlayerPed::ClearWeaponTarget()
+void
+CPlayerPed::ClearWeaponTarget()
{
if (m_nPedType == PEDTYPE_PLAYER1) {
SetWeaponLockOnTarget(nil);
@@ -97,11 +130,7 @@ void
CPlayerPed::MakeObjectTargettable(int32 handle)
{
for (int i = 0; i < ARRAY_SIZE(m_nTargettableObjects); i++) {
- if (
-#ifdef FIX_BUGS
- m_nTargettableObjects[i] == -1 ||
-#endif
- CPools::GetObjectPool()->GetAt(m_nTargettableObjects[i]) == nil) {
+ if (CPools::GetObjectPool()->GetAt(m_nTargettableObjects[i]) == nil) {
m_nTargettableObjects[i] = handle;
return;
}
@@ -152,6 +181,11 @@ CPlayerPed::SetupPlayerPed(int32 index)
CWorld::Add(player);
player->m_wepAccuracy = 100;
+
+#ifndef MASTER
+ VarConsole.Add("Debug PlayerPed", &CPlayerPed::bDebugPlayerInfo, true);
+ VarConsole.Add("Tweak Vehicle Handling", &CVehicle::m_bDisplayHandlingInfo, true);
+#endif
}
void
@@ -183,20 +217,22 @@ CPlayerPed::UseSprintEnergy(void)
}
void
-CPlayerPed::MakeChangesForNewWeapon(int8 weapon)
+CPlayerPed::MakeChangesForNewWeapon(eWeaponType weapon)
{
if (m_nPedState == PED_SNIPER_MODE) {
RestorePreviousState();
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)->IsFlagSet(WEAPONFLAG_CANAIM))
+ if (CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_CANAIM))
ClearWeaponTarget();
- CAnimBlendAssociation *weaponAnim = RpAnimBlendClumpGetAssociation(GetClump(), CWeaponInfo::GetWeaponInfo(WEAPONTYPE_SNIPERRIFLE)->m_AnimToPlay);
+ // WEAPONTYPE_SNIPERRIFLE? Wut?
+ CAnimBlendAssociation* weaponAnim = RpAnimBlendClumpGetAssociation(GetClump(), GetPrimaryFireAnim(CWeaponInfo::GetWeaponInfo(WEAPONTYPE_SNIPERRIFLE)));
if (weaponAnim) {
weaponAnim->SetRun();
weaponAnim->flags |= ASSOC_FADEOUTWHENDONE;
@@ -205,6 +241,13 @@ CPlayerPed::MakeChangesForNewWeapon(int8 weapon)
}
void
+CPlayerPed::MakeChangesForNewWeapon(int32 slot)
+{
+ if(slot != -1)
+ MakeChangesForNewWeapon(m_weapons[slot].m_eWeaponType);
+}
+
+void
CPlayerPed::ReApplyMoveAnims(void)
{
static AnimationId moveAnims[] = { ANIM_STD_WALK, ANIM_STD_RUN, ANIM_STD_RUNFAST, ANIM_STD_IDLE, ANIM_STD_STARTWALK };
@@ -226,13 +269,16 @@ CPlayerPed::ReApplyMoveAnims(void)
void
CPlayerPed::SetInitialState(void)
{
+ m_nDrunkenness = 0;
+ m_nFadeDrunkenness = 0;
+ CMBlur::ClearDrunkBlur();
+ m_nDrunkCountdown = 0;
m_bAdrenalineActive = false;
m_nAdrenalineTime = 0;
CTimer::SetTimeScale(1.0f);
m_pSeekTarget = nil;
m_vecSeekPos = CVector(0.0f, 0.0f, 0.0f);
- m_fleeFromPosX = 0.0f;
- m_fleeFromPosY = 0.0f;
+ m_fleeFromPos = CVector2D(0.0f, 0.0f);
m_fleeFrom = nil;
m_fleeTimer = 0;
m_objective = OBJECTIVE_NONE;
@@ -244,13 +290,14 @@ CPlayerPed::SetInitialState(void)
bRenderPedInCar = true;
if (m_pFire)
m_pFire->Extinguish();
+
RpAnimBlendClumpRemoveAllAssociations(GetClump());
SetPedState(PED_IDLE);
SetMoveState(PEDMOVE_STILL);
m_nLastPedState = PED_NONE;
m_animGroup = ASSOCGRP_PLAYER;
m_fMoveSpeed = 0.0f;
- m_nSelectedWepSlot = WEAPONTYPE_UNARMED;
+ m_nSelectedWepSlot = WEAPONSLOT_UNARMED;
m_nEvadeAmount = 0;
m_pEvadingFrom = nil;
bIsPedDieAnimPlaying = false;
@@ -258,6 +305,11 @@ CPlayerPed::SetInitialState(void)
m_bCanBeDamaged = true;
m_pedStats->m_temper = 50;
m_fWalkAngle = 0.0f;
+ if (m_attachedTo && !bUsesCollision)
+ bUsesCollision = true;
+
+ m_attachedTo = nil;
+ m_attachWepAmmo = 0;
}
void
@@ -284,6 +336,8 @@ CPlayerPed::SetRealMoveAnim(void)
curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_IDLE_TIRED);
if (!curIdleAssoc)
curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_FIGHT_IDLE);
+ if (!curIdleAssoc)
+ curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_MELEE_IDLE_FIGHTMODE);
if (!((curRunStopAssoc && curRunStopAssoc->IsRunning()) || (curRunStopRAssoc && curRunStopRAssoc->IsRunning()))) {
@@ -300,7 +354,7 @@ CPlayerPed::SetRealMoveAnim(void)
RestoreHeadingRate();
if (!curIdleAssoc) {
- if (m_fCurrentStamina < 0.0f && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.5f,
+ if (m_fCurrentStamina < 0.0f && !bIsAimingGun && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.5f,
nil, true, false, false, false, false, false)) {
curIdleAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_IDLE_TIRED, 8.0f);
@@ -314,7 +368,7 @@ CPlayerPed::SetRealMoveAnim(void)
} else if (m_fMoveSpeed == 0.0f && !curSprintAssoc) {
if (!curIdleAssoc) {
- if (m_fCurrentStamina < 0.0f && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.5f,
+ if (m_fCurrentStamina < 0.0f && !bIsAimingGun && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.5f,
nil, true, false, false, false, false, false)) {
curIdleAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_IDLE_TIRED, 4.0f);
@@ -325,11 +379,11 @@ CPlayerPed::SetRealMoveAnim(void)
m_nWaitTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(2500, 4000);
}
- if (m_fCurrentStamina > 0.0f && curIdleAssoc->animId == ANIM_STD_IDLE_TIRED) {
+ if ((m_fCurrentStamina > 0.0f || bIsAimingGun) && curIdleAssoc->animId == ANIM_STD_IDLE_TIRED) {
CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_STD_IDLE, 4.0f);
} else if (m_nPedState != PED_FIGHT) {
- if (m_fCurrentStamina < 0.0f && curIdleAssoc->animId != ANIM_STD_IDLE_TIRED
+ if (m_fCurrentStamina < 0.0f && !bIsAimingGun && curIdleAssoc->animId != ANIM_STD_IDLE_TIRED
&& !CWorld::TestSphereAgainstWorld(GetPosition(), 0.5f, nil, true, false, false, false, false, false)) {
CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_IDLE_TIRED, 4.0f);
@@ -354,7 +408,10 @@ CPlayerPed::SetRealMoveAnim(void)
delete curIdleAssoc;
delete RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_IDLE_TIRED);
- delete RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_FIGHT_IDLE);
+ CAnimBlendAssociation *fightIdleAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_FIGHT_IDLE);
+ if (!fightIdleAnim)
+ fightIdleAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_MELEE_IDLE_FIGHTMODE);
+ delete fightIdleAnim;
delete curSprintAssoc;
curSprintAssoc = nil;
@@ -399,7 +456,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_STD_RUNSTOP1;
else
runStopAnim = ANIM_STD_RUNSTOP2;
@@ -416,7 +473,7 @@ CPlayerPed::SetRealMoveAnim(void)
curRunAssoc->blendAmount = 0.0f;
curRunAssoc->blendDelta = 0.0f;
- } else if (curSprintAssoc->blendDelta >= 0.0f) {
+ } else if (curSprintAssoc->blendDelta >= 0.0f) { // this condition is absent on mobile
// Stop sprinting when tired
curSprintAssoc->flags |= ASSOC_DELETEFADEDOUT;
curSprintAssoc->blendDelta = -1.0f;
@@ -462,6 +519,8 @@ CPlayerPed::SetRealMoveAnim(void)
curRunAssoc->blendAmount = 1.0f;
m_nMoveState = PEDMOVE_RUN;
}
+ curWalkAssoc->blendDelta = 0.0f;
+ curRunAssoc->blendDelta = 0.0f;
}
}
}
@@ -488,6 +547,11 @@ CPlayerPed::SetRealMoveAnim(void)
if (curSprintAssoc)
curSprintAssoc->speed = 2.0f;
}
+ } else if (curSprintAssoc) {
+ if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_FIXED) {
+ curSprintAssoc->speed = 0.7f;
+ } else
+ curSprintAssoc->speed = 1.0f;
}
}
@@ -498,20 +562,57 @@ CPlayerPed::RestoreSprintEnergy(float restoreSpeed)
m_fCurrentStamina += restoreSpeed * CTimer::GetTimeStep() * 0.5f;
}
-bool
+float
CPlayerPed::DoWeaponSmoothSpray(void)
{
if (m_nPedState == PED_ATTACK && !m_pPointGunAt) {
- eWeaponType weapon = GetWeapon()->m_eWeaponType;
+ CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
+ switch (GetWeapon()->m_eWeaponType) {
+ case WEAPONTYPE_GOLFCLUB:
+ case WEAPONTYPE_NIGHTSTICK:
+ case WEAPONTYPE_BASEBALLBAT:
+ if (GetFireAnimGround(weaponInfo, false) && RpAnimBlendClumpGetAssociation(GetClump(), GetFireAnimGround(weaponInfo, false)))
+ return PI / 176.f;
+ else
+ return -1.0f;
+
+ case WEAPONTYPE_CHAINSAW:
+ if (GetMeleeStartAnim(weaponInfo) && RpAnimBlendClumpGetAssociation(GetClump(), GetMeleeStartAnim(weaponInfo))) {
#ifdef FREE_CAM
- if(TheCamera.Cams[0].Using3rdPersonMouseCam() && (weapon == WEAPONTYPE_COLT45 || weapon == WEAPONTYPE_UZI))
- return false;
+ if (TheCamera.Cams[0].Using3rdPersonMouseCam()) return -1.0f;
#endif
- if (weapon == WEAPONTYPE_FLAMETHROWER || weapon == WEAPONTYPE_COLT45 || weapon == WEAPONTYPE_UZI || weapon == WEAPONTYPE_SHOTGUN ||
- weapon == WEAPONTYPE_AK47 || weapon == WEAPONTYPE_M16 || weapon == WEAPONTYPE_HELICANNON)
- return true;
- }
- return false;
+ return PI / 128.0f;
+ }
+ else if (GetFireAnimGround(weaponInfo, false) && RpAnimBlendClumpGetAssociation(GetClump(), GetFireAnimGround(weaponInfo, false)))
+ return PI / 176.f;
+ else
+ return PI / 80.f;
+
+ case WEAPONTYPE_PYTHON:
+ return PI / 112.f;
+ case WEAPONTYPE_SHOTGUN:
+ case WEAPONTYPE_SPAS12_SHOTGUN:
+ case WEAPONTYPE_STUBBY_SHOTGUN:
+ return PI / 112.f;
+ case WEAPONTYPE_UZI:
+ case WEAPONTYPE_MP5:
+ return PI / 112.f;
+ case WEAPONTYPE_M4:
+ case WEAPONTYPE_RUGER:
+ return PI / 112.f;
+ case WEAPONTYPE_FLAMETHROWER:
+ return PI / 80.f;
+ case WEAPONTYPE_M60:
+ case WEAPONTYPE_MINIGUN:
+ case WEAPONTYPE_HELICANNON:
+ return PI / 176.f;
+ default:
+ return -1.0f;
+ }
+ } else if (bIsDucking)
+ return PI / 112.f;
+ else
+ return -1.0f;
}
void
@@ -529,14 +630,6 @@ 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)
- return false;
-
- distVec.Normalise();
-
- if (DotProduct(distVec,GetForward()) < 0.4f)
- return true;
-
return false;
}
@@ -559,8 +652,11 @@ CPlayerPed::RunningLand(CPad *padUsed)
}
bool
-CPlayerPed::IsThisPedAttackingPlayer(CPed *suspect)
+CPlayerPed::IsThisPedAnAimingPriority(CPed *suspect)
{
+ if (!suspect->bIsPlayerFriend)
+ return true;
+
if (suspect->m_pPointGunAt == this)
return true;
@@ -574,7 +670,7 @@ CPlayerPed::IsThisPedAttackingPlayer(CPed *suspect)
default:
break;
}
- return false;
+ return suspect->m_nPedState == PED_ABSEIL;
}
void
@@ -583,78 +679,123 @@ CPlayerPed::PlayerControlSniper(CPad *padUsed)
ProcessWeaponSwitch(padUsed);
TheCamera.PlayerExhaustion = (1.0f - (m_fCurrentStamina - -150.0f) / 300.0f) * 0.9f + 0.1f;
- if (!padUsed->GetTarget()) {
+ if (padUsed->DuckJustDown() && !bIsDucking && m_nMoveState != PEDMOVE_SPRINT) {
+ bCrouchWhenShooting = true;
+ SetDuck(60000, true);
+ } else if (bIsDucking && (padUsed->DuckJustDown() || m_nMoveState == PEDMOVE_SPRINT)) {
+ ClearDuck(true);
+ bCrouchWhenShooting = false;
+ }
+
+ if (!padUsed->GetTarget() && !m_attachedTo) {
RestorePreviousState();
TheCamera.ClearPlayerWeaponMode();
+ return;
}
- if (padUsed->WeaponJustDown()) {
+ int firingRate = GetWeapon()->m_eWeaponType == WEAPONTYPE_LASERSCOPE ? 333 : 266;
+ if (padUsed->WeaponJustDown() && CTimer::GetTimeInMilliseconds() > GetWeapon()->m_nTimer) {
CVector firePos(0.0f, 0.0f, 0.6f);
firePos = GetMatrix() * firePos;
GetWeapon()->Fire(this, &firePos);
+ m_nPadDownPressedInMilliseconds = CTimer::GetTimeInMilliseconds();
+ } else if (CTimer::GetTimeInMilliseconds() > m_nPadDownPressedInMilliseconds + firingRate &&
+ CTimer::GetTimeInMilliseconds() - CTimer::GetTimeStepInMilliseconds() < m_nPadDownPressedInMilliseconds + firingRate && padUsed->GetWeapon()) {
+
+ if (GetWeapon()->m_nAmmoTotal > 0) {
+ DMAudio.PlayFrontEndSound(SOUND_WEAPON_AK47_BULLET_ECHO, GetWeapon()->m_eWeaponType);
+ }
}
- GetWeapon()->Update(m_audioEntityId);
+ GetWeapon()->Update(m_audioEntityId, nil);
}
// I think R* also used goto in here.
void
CPlayerPed::ProcessWeaponSwitch(CPad *padUsed)
{
- if (CDarkel::FrenzyOnGoing())
+ if (CDarkel::FrenzyOnGoing() || m_attachedTo)
goto switchDetectDone;
- if (padUsed->CycleWeaponRightJustDown() && !m_pPointGunAt) {
+ if (!m_pPointGunAt && !bDontAllowWeaponChange && GetWeapon()->m_eWeaponType != WEAPONTYPE_DETONATOR) {
+ if (padUsed->CycleWeaponRightJustDown()) {
- if (TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON
- && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON_RUNABOUT
- && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER
- && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER_RUNABOUT
- && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER
- && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER_RUNABOUT) {
+ if (TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON
+ && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON_RUNABOUT
+ && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER
+ && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER_RUNABOUT
+ && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER
+ && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER_RUNABOUT
+ && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_CAMERA) {
- for (m_nSelectedWepSlot = m_currentWeapon + 1; m_nSelectedWepSlot < WEAPONTYPE_TOTAL_INVENTORY_WEAPONS; ++m_nSelectedWepSlot) {
- if (HasWeapon(m_nSelectedWepSlot) && GetWeapon(m_nSelectedWepSlot).HasWeaponAmmoToBeUsed()) {
- goto switchDetectDone;
+ for (m_nSelectedWepSlot = m_currentWeapon + 1; m_nSelectedWepSlot < TOTAL_WEAPON_SLOTS; ++m_nSelectedWepSlot) {
+ if (HasWeaponSlot(m_nSelectedWepSlot) && GetWeapon(m_nSelectedWepSlot).HasWeaponAmmoToBeUsed()) {
+ goto spentAmmoCheck;
+ }
}
+ m_nSelectedWepSlot = 0;
}
- m_nSelectedWepSlot = WEAPONTYPE_UNARMED;
- }
- } else if (padUsed->CycleWeaponLeftJustDown() && !m_pPointGunAt) {
- if (TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON
- && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER
- && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER) {
-
- for (m_nSelectedWepSlot = m_currentWeapon - 1; ; --m_nSelectedWepSlot) {
- if (m_nSelectedWepSlot < WEAPONTYPE_UNARMED)
- m_nSelectedWepSlot = WEAPONTYPE_DETONATOR;
-
- if (HasWeapon(m_nSelectedWepSlot) && GetWeapon(m_nSelectedWepSlot).HasWeaponAmmoToBeUsed()) {
- goto switchDetectDone;
- }
+ } else if (padUsed->CycleWeaponLeftJustDown()) {
+ if (TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON
+ && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER
+ && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER
+ && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_CAMERA) {
+
+ // I don't know what kind of loop that was
+ m_nSelectedWepSlot = m_currentWeapon - 1;
+ do {
+ if (m_nSelectedWepSlot < 0)
+ m_nSelectedWepSlot = TOTAL_WEAPON_SLOTS - 1;
+
+ if (m_nSelectedWepSlot == WEAPONSLOT_UNARMED)
+ break;
+
+ if (HasWeaponSlot(m_nSelectedWepSlot) && GetWeapon(m_nSelectedWepSlot).HasWeaponAmmoToBeUsed())
+ break;
+
+ --m_nSelectedWepSlot;
+ } while (m_nSelectedWepSlot != WEAPONSLOT_UNARMED);
}
}
- // Out of ammo, switch to another weapon
- } else if (CWeaponInfo::GetWeaponInfo((eWeaponType)m_currentWeapon)->m_eWeaponFire != WEAPON_FIRE_MELEE) {
- if (GetWeapon(m_currentWeapon).m_nAmmoTotal <= 0) {
+ }
+
+spentAmmoCheck:
+ if (CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_eWeaponFire != WEAPON_FIRE_MELEE
+ && (!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
|| TheCamera.PlayerWeaponMode.Mode == CCam::MODE_ROCKETLAUNCHER)
return;
- for (m_nSelectedWepSlot = m_currentWeapon - 1; m_nSelectedWepSlot >= 0; --m_nSelectedWepSlot) {
- if (m_nSelectedWepSlot == WEAPONTYPE_BASEBALLBAT && HasWeapon(WEAPONTYPE_BASEBALLBAT)
- || GetWeapon(m_nSelectedWepSlot).m_nAmmoTotal > 0 && m_nSelectedWepSlot != WEAPONTYPE_MOLOTOV && m_nSelectedWepSlot != WEAPONTYPE_GRENADE) {
+ if (GetWeapon()->m_eWeaponType == WEAPONTYPE_DETONATOR
+ && GetWeapon(WEAPONSLOT_PROJECTILE).m_eWeaponType == WEAPONTYPE_DETONATOR_GRENADE)
+ m_nSelectedWepSlot = WEAPONSLOT_PROJECTILE;
+ else
+ m_nSelectedWepSlot = m_currentWeapon - 1;
+
+ for (; m_nSelectedWepSlot >= WEAPONSLOT_UNARMED; --m_nSelectedWepSlot) {
+
+ // 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 == WEAPONSLOT_MELEE || GetWeapon(m_nSelectedWepSlot).m_nAmmoTotal > 0 && m_nSelectedWepSlot != WEAPONSLOT_PROJECTILE) {
+#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) {
+#endif
goto switchDetectDone;
}
}
- m_nSelectedWepSlot = WEAPONTYPE_UNARMED;
+ m_nSelectedWepSlot = WEAPONSLOT_UNARMED;
}
}
switchDetectDone:
if (m_nSelectedWepSlot != m_currentWeapon) {
- if (m_nPedState != PED_ATTACK && m_nPedState != PED_AIM_GUN && m_nPedState != PED_FIGHT)
+ if (m_nPedState != PED_ATTACK && m_nPedState != PED_AIM_GUN && m_nPedState != PED_FIGHT) {
+ RemoveWeaponAnims(m_currentWeapon, -1000.0f);
MakeChangesForNewWeapon(m_nSelectedWepSlot);
+ }
}
}
@@ -664,17 +805,34 @@ CPlayerPed::PlayerControlM16(CPad *padUsed)
ProcessWeaponSwitch(padUsed);
TheCamera.PlayerExhaustion = (1.0f - (m_fCurrentStamina - -150.0f) / 300.0f) * 0.9f + 0.1f;
- if (!padUsed->GetTarget()) {
+ if (padUsed->DuckJustDown() && !bIsDucking && m_nMoveState != PEDMOVE_SPRINT) {
+ bCrouchWhenShooting = true;
+ SetDuck(60000, true);
+ } else if (bIsDucking && (padUsed->DuckJustDown() || m_nMoveState == PEDMOVE_SPRINT)) {
+ ClearDuck(true);
+ bCrouchWhenShooting = false;
+ }
+
+ if (!padUsed->GetTarget() && !m_attachedTo) {
RestorePreviousState();
TheCamera.ClearPlayerWeaponMode();
}
- if (padUsed->GetWeapon()) {
- CVector firePos(0.0f, 0.0f, 0.6f);
- firePos = GetMatrix() * firePos;
- GetWeapon()->Fire(this, &firePos);
+ if (padUsed->GetWeapon() && CTimer::GetTimeInMilliseconds() > GetWeapon()->m_nTimer) {
+ if (GetWeapon()->m_eWeaponState == WEAPONSTATE_OUT_OF_AMMO) {
+ DMAudio.PlayFrontEndSound(SOUND_WEAPON_SNIPER_SHOT_NO_ZOOM, 0.f);
+ GetWeapon()->m_nTimer = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_nFiringRate + CTimer::GetTimeInMilliseconds();
+ } else {
+ CVector firePos(0.0f, 0.0f, 0.6f);
+ firePos = GetMatrix() * firePos;
+ GetWeapon()->Fire(this, &firePos);
+ m_nPadDownPressedInMilliseconds = CTimer::GetTimeInMilliseconds();
+ }
+ } else if (CTimer::GetTimeInMilliseconds() > GetWeapon()->m_nTimer &&
+ CTimer::GetTimeInMilliseconds() - CTimer::GetTimeStepInMilliseconds() < GetWeapon()->m_nTimer && GetWeapon()->m_eWeaponState != WEAPONSTATE_OUT_OF_AMMO) {
+ DMAudio.PlayFrontEndSound(SOUND_WEAPON_AK47_BULLET_ECHO, GetWeapon()->m_eWeaponType);
}
- GetWeapon()->Update(m_audioEntityId);
+ GetWeapon()->Update(m_audioEntityId, nil);
}
void
@@ -729,14 +887,21 @@ CPlayerPed::PlayerControl1stPersonRunAround(CPad *padUsed)
m_fMoveSpeed = 0.0f;
}
}
+
+ if (m_nPedState == PED_ANSWER_MOBILE) {
+ SetRealMoveAnim();
+ return;
+ }
+
if (!CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_HEAVY) && padUsed->GetSprint()) {
m_nMoveState = PEDMOVE_SPRINT;
}
if (m_nPedState != PED_FIGHT)
SetRealMoveAnim();
- if (!bIsInTheAir && !(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_HEAVY))
- && padUsed->JumpJustDown() && m_nPedState != PED_JUMP) {
+ if (!bIsInTheAir && !(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_HEAVY)) &&
+ padUsed->JumpJustDown() && m_nPedState != PED_JUMP) {
+
ClearAttack();
ClearWeaponTarget();
if (m_nEvadeAmount != 0 && m_pEvadingFrom) {
@@ -747,6 +912,12 @@ CPlayerPed::PlayerControl1stPersonRunAround(CPad *padUsed)
SetJump();
}
}
+
+ // FIX: Fact that PlayIdleAnimations only called through PlayerControlZelda was making it visible to only Classic control players. This isn't fair!
+#ifdef FIX_BUGS
+ if (m_nPedState != PED_FIGHT)
+ PlayIdleAnimations(padUsed);
+#endif
}
void
@@ -755,7 +926,7 @@ CPlayerPed::KeepAreaAroundPlayerClear(void)
BuildPedLists();
for (int i = 0; i < m_numNearPeds; ++i) {
CPed *nearPed = m_nearPeds[i];
- if (nearPed->CharCreatedBy == RANDOM_CHAR && !nearPed->DyingOrDead()) {
+ if (nearPed->CharCreatedBy == RANDOM_CHAR && nearPed->m_nPedState != PED_DRIVING && !nearPed->DyingOrDead()) {
if (nearPed->GetIsOnScreen()) {
if (nearPed->m_objective == OBJECTIVE_NONE) {
nearPed->SetFindPathAndFlee(this, 5000, true);
@@ -799,17 +970,15 @@ CPlayerPed::KeepAreaAroundPlayerClear(void)
}
void
-CPlayerPed::EvaluateNeighbouringTarget(CEntity *candidate, CEntity **targetPtr, float *lastCloseness, float distLimit, float angleOffset, bool lookToLeft)
+CPlayerPed::EvaluateNeighbouringTarget(CEntity *candidate, CEntity **targetPtr, float *lastCloseness, float distLimit, float angleOffset, bool lookToLeft, bool priority)
{
+ // priority param is unused
CVector distVec = candidate->GetPosition() - GetPosition();
if (distVec.Magnitude2D() <= distLimit) {
if (!DoesTargetHaveToBeBroken(candidate->GetPosition(), GetWeapon())) {
-#ifdef VC_PED_PORTS
float angleBetweenUs = CGeneral::GetATanOfXY(candidate->GetPosition().x - TheCamera.GetPosition().x,
- candidate->GetPosition().y - TheCamera.GetPosition().y);
-#else
- float angleBetweenUs = CGeneral::GetATanOfXY(distVec.x, distVec.y);
-#endif
+ candidate->GetPosition().y - TheCamera.GetPosition().y);
+
angleBetweenUs = CGeneral::LimitAngle(angleBetweenUs - angleOffset);
float closeness;
if (lookToLeft) {
@@ -838,7 +1007,7 @@ CPlayerPed::EvaluateTarget(CEntity *candidate, CEntity **targetPtr, float *lastC
float closeness = -dist - 5.0f * Abs(angleBetweenUs);
if (priority) {
- closeness += 5.0f;
+ closeness += 30.0f;
}
if (closeness > *lastCloseness) {
@@ -850,6 +1019,37 @@ CPlayerPed::EvaluateTarget(CEntity *candidate, CEntity **targetPtr, float *lastC
}
bool
+CPlayerPed::CanIKReachThisTarget(CVector target, CWeapon* weapon, bool zRotImportant)
+{
+ float angleToFace = CGeneral::GetRadianAngleBetweenPoints(target.x, target.y, GetPosition().x, GetPosition().y);
+ float angleDiff = CGeneral::LimitRadianAngle(angleToFace - m_fRotationCur);
+
+ return (!zRotImportant || CWeaponInfo::GetWeaponInfo(weapon->m_eWeaponType)->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM) || Abs(angleDiff) <= HALFPI) &&
+ (CWeaponInfo::GetWeaponInfo(weapon->m_eWeaponType)->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM) || Abs(target.z - GetPosition().z) <= (target - GetPosition()).Magnitude2D());
+}
+
+void
+CPlayerPed::RotatePlayerToTrackTarget(void)
+{
+ if (CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM))
+ return;
+
+ float angleToFace = CGeneral::GetRadianAngleBetweenPoints(
+ m_pPointGunAt->GetPosition().x, m_pPointGunAt->GetPosition().y,
+ GetPosition().x, GetPosition().y);
+
+ float angleDiff = CGeneral::LimitRadianAngle(m_fRotationCur - angleToFace);
+ if (angleDiff < -DEGTORAD(25.0f)) {
+ m_fRotationCur -= angleDiff + DEGTORAD(25.0f);
+ m_fRotationDest -= angleDiff + DEGTORAD(25.0f);
+
+ } else if (angleDiff > DEGTORAD(25.0f)) {
+ m_fRotationCur -= angleDiff - DEGTORAD(25.0f);
+ m_fRotationDest -= angleDiff - DEGTORAD(25.0f);
+ }
+}
+
+bool
CPlayerPed::FindNextWeaponLockOnTarget(CEntity *previousTarget, bool lookToLeft)
{
CEntity *nextTarget = nil;
@@ -863,25 +1063,30 @@ CPlayerPed::FindNextWeaponLockOnTarget(CEntity *previousTarget, bool lookToLeft)
for (int h = CPools::GetPedPool()->GetSize() - 1; h >= 0; h--) {
CPed *pedToCheck = CPools::GetPedPool()->GetSlot(h);
if (pedToCheck) {
- if (pedToCheck != FindPlayerPed() && pedToCheck != previousTarget) {
- if (!pedToCheck->DyingOrDead() && !pedToCheck->bInVehicle
- && pedToCheck->m_leader != FindPlayerPed() && OurPedCanSeeThisOne(pedToCheck)) {
+ if (pedToCheck != this && pedToCheck != previousTarget) {
+ if (!pedToCheck->DyingOrDead()
+#ifndef AIMING_VEHICLE_OCCUPANTS // Mobile thing
+ && (!pedToCheck->bInVehicle || (pedToCheck->m_pMyVehicle && pedToCheck->m_pMyVehicle->IsBike()))
+#endif
+ && pedToCheck->m_leader != this && !pedToCheck->bNeverEverTargetThisPed
+ && OurPedCanSeeThisOne(pedToCheck) && CanIKReachThisTarget(pedToCheck->GetPosition(), GetWeapon(), true)) {
EvaluateNeighbouringTarget(pedToCheck, &nextTarget, &lastCloseness,
- weaponRange, referenceBeta, lookToLeft);
+ weaponRange, referenceBeta, lookToLeft, IsThisPedAnAimingPriority(pedToCheck));
}
}
}
}
for (int i = 0; i < ARRAY_SIZE(m_nTargettableObjects); i++) {
CObject *obj = CPools::GetObjectPool()->GetAt(m_nTargettableObjects[i]);
- if (obj)
- EvaluateNeighbouringTarget(obj, &nextTarget, &lastCloseness, weaponRange, referenceBeta, lookToLeft);
+ if (obj && !obj->bHasBeenDamaged && CanIKReachThisTarget(obj->GetPosition(), GetWeapon(), true))
+ EvaluateNeighbouringTarget(obj, &nextTarget, &lastCloseness, weaponRange, referenceBeta, lookToLeft, true);
}
if (!nextTarget)
return false;
SetWeaponLockOnTarget(nextTarget);
+ bDontAllowWeaponChange = true;
SetPointGunAt(nextTarget);
return true;
}
@@ -908,26 +1113,32 @@ CPlayerPed::FindWeaponLockOnTarget(void)
for (int h = CPools::GetPedPool()->GetSize() - 1; h >= 0; h--) {
CPed *pedToCheck = CPools::GetPedPool()->GetSlot(h);
if (pedToCheck) {
- if (pedToCheck != FindPlayerPed()) {
- if (!pedToCheck->DyingOrDead() && !pedToCheck->bInVehicle
- && pedToCheck->m_leader != FindPlayerPed() && OurPedCanSeeThisOne(pedToCheck)) {
+ if (pedToCheck != this) {
+ if (!pedToCheck->DyingOrDead()
+#ifndef AIMING_VEHICLE_OCCUPANTS // Mobile thing
+ && (!pedToCheck->bInVehicle || (pedToCheck->m_pMyVehicle && pedToCheck->m_pMyVehicle->IsBike()))
+#endif
+ && pedToCheck->m_leader != this && !pedToCheck->bNeverEverTargetThisPed
+ && OurPedCanSeeThisOne(pedToCheck) && CanIKReachThisTarget(pedToCheck->GetPosition(), GetWeapon(), true)) {
EvaluateTarget(pedToCheck, &nextTarget, &lastCloseness,
- weaponRange, referenceBeta, IsThisPedAttackingPlayer(pedToCheck));
+ weaponRange, referenceBeta, IsThisPedAnAimingPriority(pedToCheck));
}
}
}
}
for (int i = 0; i < ARRAY_SIZE(m_nTargettableObjects); i++) {
CObject *obj = CPools::GetObjectPool()->GetAt(m_nTargettableObjects[i]);
- if (obj)
- EvaluateTarget(obj, &nextTarget, &lastCloseness, weaponRange, referenceBeta, false);
+ if (obj && !obj->bHasBeenDamaged && CanIKReachThisTarget(obj->GetPosition(), GetWeapon(), true))
+ EvaluateTarget(obj, &nextTarget, &lastCloseness, weaponRange, referenceBeta, true);
}
if (!nextTarget)
return false;
SetWeaponLockOnTarget(nextTarget);
+ bDontAllowWeaponChange = true;
SetPointGunAt(nextTarget);
+ Say(SOUND_PED_AIMING);
return true;
}
@@ -935,7 +1146,6 @@ void
CPlayerPed::ProcessAnimGroups(void)
{
AssocGroupId groupToSet;
-
#ifdef PC_PLAYER_CONTROLS
if ((m_fWalkAngle <= -DEGTORAD(50.0f) || m_fWalkAngle >= DEGTORAD(50.0f))
&& TheCamera.Cams[TheCamera.ActiveCam].Using3rdPersonMouseCam()
@@ -945,17 +1155,29 @@ 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)
+ 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)
+ groupToSet = ASSOCGRP_CHAINSAWRIGHT;
else
groupToSet = ASSOCGRP_PLAYERRIGHT;
}
} 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)
+ groupToSet = ASSOCGRP_CHAINSAWBACK;
else
groupToSet = ASSOCGRP_PLAYERBACK;
}
@@ -965,9 +1187,19 @@ CPlayerPed::ProcessAnimGroups(void)
if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER) {
groupToSet = ASSOCGRP_PLAYERROCKET;
} else {
- if (GetWeapon()->m_eWeaponType == WEAPONTYPE_BASEBALLBAT) {
+ if (GetWeapon()->m_eWeaponType == WEAPONTYPE_BASEBALLBAT
+ || GetWeapon()->m_eWeaponType == WEAPONTYPE_MACHETE)
groupToSet = ASSOCGRP_PLAYERBBBAT;
- } else if (GetWeapon()->m_eWeaponType != WEAPONTYPE_COLT45 && GetWeapon()->m_eWeaponType != WEAPONTYPE_UZI) {
+ 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 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) {
if (!GetWeapon()->IsType2Handed()) {
groupToSet = ASSOCGRP_PLAYER;
} else {
@@ -994,44 +1226,76 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
CWeaponEffects::ClearCrossHair();
ClearPointGunAt();
}
+
+ if (padUsed->DuckJustDown() && !bIsDucking && m_nMoveState != PEDMOVE_SPRINT) {
+#ifdef FIX_BUGS
+ // fix tommy being locked into looking at the same spot if you duck just after starting to shoot
+ if(!m_pPointGunAt)
+ ClearPointGunAt();
+#endif
+ bCrouchWhenShooting = true;
+ SetDuck(60000, true);
+ } else if (bIsDucking && (padUsed->DuckJustDown() || m_nMoveState == PEDMOVE_SPRINT ||
+ padUsed->GetSprint() || padUsed->JumpJustDown() || padUsed->ExitVehicleJustDown())) {
+
+#ifdef FIX_BUGS
+ // same fix as above except for standing up
+ if(!m_pPointGunAt)
+ ClearPointGunAt();
+#endif
+ ClearDuck(true);
+ bCrouchWhenShooting = false;
+ }
+
+ if(weaponInfo->IsFlagSet(WEAPONFLAG_CANAIM))
+ m_wepAccuracy = 95;
+ else
+ m_wepAccuracy = 100;
+
if (!m_pFire) {
- if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER ||
- GetWeapon()->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE || GetWeapon()->m_eWeaponType == WEAPONTYPE_M16) {
- if (padUsed->TargetJustDown()) {
- SetStoredState();
- SetPedState(PED_SNIPER_MODE);
+ eWeaponType weapon = GetWeapon()->m_eWeaponType;
+ if (weapon == WEAPONTYPE_ROCKETLAUNCHER || weapon == WEAPONTYPE_SNIPERRIFLE ||
+ weapon == WEAPONTYPE_LASERSCOPE || weapon == WEAPONTYPE_M4 ||
+ weapon == WEAPONTYPE_RUGER || weapon == WEAPONTYPE_M60 ||
+ weapon == WEAPONTYPE_CAMERA) {
+
+ if (padUsed->TargetJustDown() || TheCamera.m_bJustJumpedOutOf1stPersonBecauseOfTarget) {
#ifdef FREE_CAM
if (CCamera::bFreeCam && TheCamera.Cams[0].Using3rdPersonMouseCam()) {
m_fRotationCur = CGeneral::LimitRadianAngle(-TheCamera.Orientation);
SetHeading(m_fRotationCur);
}
#endif
- if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER)
+ if (weapon == WEAPONTYPE_ROCKETLAUNCHER)
TheCamera.SetNewPlayerWeaponMode(CCam::MODE_ROCKETLAUNCHER, 0, 0);
- else if (GetWeapon()->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE)
+ else if (weapon == WEAPONTYPE_SNIPERRIFLE || weapon == WEAPONTYPE_LASERSCOPE)
TheCamera.SetNewPlayerWeaponMode(CCam::MODE_SNIPER, 0, 0);
+ else if (weapon == WEAPONTYPE_CAMERA)
+ TheCamera.SetNewPlayerWeaponMode(CCam::MODE_CAMERA, 0, 0);
else
TheCamera.SetNewPlayerWeaponMode(CCam::MODE_M16_1STPERSON, 0, 0);
m_fMoveSpeed = 0.0f;
CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_IDLE, 1000.0f);
- }
- if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER || GetWeapon()->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE
- || TheCamera.PlayerWeaponMode.Mode == CCam::MODE_M16_1STPERSON)
+ SetPedState(PED_SNIPER_MODE);
return;
+ }
+ if (!TheCamera.Using1stPersonWeaponMode())
+ if (weapon == WEAPONTYPE_ROCKETLAUNCHER || weapon == WEAPONTYPE_SNIPERRIFLE || weapon == WEAPONTYPE_LASERSCOPE || weapon == WEAPONTYPE_CAMERA)
+ return;
}
}
if (padUsed->GetWeapon() && m_nMoveState != PEDMOVE_SPRINT) {
if (m_nSelectedWepSlot == m_currentWeapon) {
if (m_pPointGunAt) {
-#ifdef FREE_CAM
- if (CCamera::bFreeCam && weaponInfo->m_eWeaponFire == WEAPON_FIRE_MELEE && m_fMoveSpeed < 1.0f)
- StartFightAttack(padUsed->GetWeapon());
- else
-#endif
- SetAttack(m_pPointGunAt);
- } else if (m_currentWeapon != WEAPONTYPE_UNARMED) {
+ if (m_nPedState == PED_ATTACK) {
+ m_fAttackButtonCounter *= Pow(0.94f, CTimer::GetTimeStep());
+ } else {
+ m_fAttackButtonCounter = 0.0f;
+ }
+ SetAttack(m_pPointGunAt);
+ } else {
if (m_nPedState == PED_ATTACK) {
if (padUsed->WeaponJustDown()) {
m_bHaveTargetSelected = true;
@@ -1042,12 +1306,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->IsFlagSet(WEAPONFLAG_FIGHTMODE)) {
+
+ 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 {
@@ -1060,33 +1331,40 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
#ifdef FREE_CAM
static int8 changedHeadingRate = 0;
+ static int8 pointedGun = 0;
if (changedHeadingRate == 2) changedHeadingRate = 1;
+ if (pointedGun == 2) pointedGun = 1;
// Rotate player/arm when shooting. We don't have auto-rotation anymore
if (CCamera::m_bUseMouse3rdPerson && CCamera::bFreeCam &&
m_nSelectedWepSlot == m_currentWeapon && m_nMoveState != PEDMOVE_SPRINT) {
+#define CAN_AIM_WITH_ARM (weaponInfo->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM) && !bIsDucking && !bCrouchWhenShooting)
// Weapons except throwable and melee ones
- if (weaponInfo->IsFlagSet(WEAPONFLAG_CANAIM) || weaponInfo->IsFlagSet(WEAPONFLAG_1ST_PERSON) || weaponInfo->IsFlagSet(WEAPONFLAG_EXPANDS)) {
- if ((padUsed->GetTarget() && weaponInfo->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM)) || padUsed->GetWeapon()) {
+ if (weaponInfo->m_nWeaponSlot > 2) {
+ if ((padUsed->GetTarget() && CAN_AIM_WITH_ARM) || padUsed->GetWeapon()) {
float limitedCam = CGeneral::LimitRadianAngle(-TheCamera.Orientation);
+ m_cachedCamSource = TheCamera.Cams[TheCamera.ActiveCam].Source;
+ m_cachedCamFront = TheCamera.Cams[TheCamera.ActiveCam].Front;
+ m_cachedCamUp = TheCamera.Cams[TheCamera.ActiveCam].Up;
+
// On this one we can rotate arm.
- if (weaponInfo->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM)) {
- if (!padUsed->GetWeapon()) { // making this State != ATTACK still stops it after attack. Re-start it immediately!
+ if (CAN_AIM_WITH_ARM) {
+ pointedGun = 2;
+ m_bFreeAimActive = true;
+ SetLookFlag(limitedCam, true, true);
+ SetAimFlag(limitedCam);
+ SetLookTimer(INT32_MAX);
+ ((CPlayerPed*)this)->m_fFPSMoveHeading = TheCamera.Find3rdPersonQuickAimPitch();
+ if (m_nPedState != PED_ATTACK && m_nPedState != PED_AIM_GUN) {
+ // This is a seperate ped state just for pointing gun. Used for target button
SetPointGunAt(nil);
- bIsPointingGunAt = false; // to not stop after attack
}
-
- SetLookFlag(limitedCam, true);
- SetAimFlag(limitedCam);
-#ifdef VC_PED_PORTS
- SetLookTimer(INT32_MAX); // removing this makes head move for real, but I experinced some bugs.
-#endif
} else {
m_fRotationDest = limitedCam;
changedHeadingRate = 2;
- m_headingRate = 50.0f;
+ m_headingRate = 12.5f;
// Anim. fix for shotgun, ak47 and m16 (we must finish rot. it quickly)
if (weaponInfo->IsFlagSet(WEAPONFLAG_CANAIM) && padUsed->WeaponJustDown()) {
@@ -1102,17 +1380,31 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
m_fRotationCur += (limitedRotDest - m_fRotationCur) / 2;
}
}
- } else if (weaponInfo->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM) && m_nPedState != PED_ATTACK)
- ClearPointGunAt();
+ }
}
+#undef CAN_AIM_WITH_ARM
}
if (changedHeadingRate == 1) {
changedHeadingRate = 0;
RestoreHeadingRate();
}
+ if (pointedGun == 1) {
+ if (m_nPedState == PED_ATTACK) {
+ if (!padUsed->GetWeapon() && (m_pedIK.m_flags & CPedIK::GUN_POINTED_SUCCESSFULLY) == 0) {
+ float limitedCam = CGeneral::LimitRadianAngle(-TheCamera.Orientation);
+
+ SetAimFlag(limitedCam);
+ ((CPlayerPed*)this)->m_fFPSMoveHeading = TheCamera.Find3rdPersonQuickAimPitch();
+ m_bFreeAimActive = true;
+ }
+ } else {
+ pointedGun = 0;
+ ClearPointGunAt();
+ }
+ }
#endif
- if (padUsed->GetTarget() && m_nSelectedWepSlot == m_currentWeapon && m_nMoveState != PEDMOVE_SPRINT) {
+ if (padUsed->GetTarget() && m_nSelectedWepSlot == m_currentWeapon && m_nMoveState != PEDMOVE_SPRINT && !TheCamera.Using1stPersonWeaponMode() && weaponInfo->IsFlagSet(WEAPONFLAG_CANAIM)) {
if (m_pPointGunAt) {
// what??
if (!m_pPointGunAt
@@ -1120,15 +1412,30 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
|| (!CCamera::bFreeCam && CCamera::m_bUseMouse3rdPerson)
#else
|| CCamera::m_bUseMouse3rdPerson
+#endif
+ ) {
+ ClearWeaponTarget();
+ return;
+ }
+
+ if (m_pPointGunAt->IsPed() && (
+#ifndef AIMING_VEHICLE_OCCUPANTS
+ (((CPed*)m_pPointGunAt)->bInVehicle && (!((CPed*)m_pPointGunAt)->m_pMyVehicle || !((CPed*)m_pPointGunAt)->m_pMyVehicle->IsBike())) ||
#endif
- || m_pPointGunAt->IsPed() && ((CPed*)m_pPointGunAt)->bInVehicle) {
+ !CGame::nastyGame && ((CPed*)m_pPointGunAt)->DyingOrDead())) {
ClearWeaponTarget();
return;
}
- if (CPlayerPed::DoesTargetHaveToBeBroken(m_pPointGunAt->GetPosition(), GetWeapon())) {
+ if (CPlayerPed::DoesTargetHaveToBeBroken(m_pPointGunAt->GetPosition(), GetWeapon()) ||
+ (!bCanPointGunAtTarget && !weaponInfo->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM))) { // this line isn't on Mobile, idk why
ClearWeaponTarget();
return;
}
+
+ if (m_pPointGunAt) {
+ RotatePlayerToTrackTarget();
+ }
+
if (m_pPointGunAt) {
if (padUsed->ShiftTargetLeftJustDown())
FindNextWeaponLockOnTarget(m_pPointGunAt, true);
@@ -1137,13 +1444,9 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
}
TheCamera.SetNewPlayerWeaponMode(CCam::MODE_SYPHON, 0, 0);
TheCamera.UpdateAimingCoors(m_pPointGunAt->GetPosition());
- }
-#ifdef FREE_CAM
- else if ((CCamera::bFreeCam && weaponInfo->m_eWeaponFire == WEAPON_FIRE_MELEE) || (weaponInfo->IsFlagSet(WEAPONFLAG_CANAIM) && !CCamera::m_bUseMouse3rdPerson)) {
-#else
- else if (weaponInfo->IsFlagSet(WEAPONFLAG_CANAIM) && !CCamera::m_bUseMouse3rdPerson) {
-#endif
- if (padUsed->TargetJustDown())
+
+ } else if (!CCamera::m_bUseMouse3rdPerson) {
+ if (padUsed->TargetJustDown() || TheCamera.m_bJustJumpedOutOf1stPersonBecauseOfTarget)
FindWeaponLockOnTarget();
}
} else if (m_pPointGunAt) {
@@ -1151,16 +1454,12 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
}
if (m_pPointGunAt) {
-#ifndef VC_PED_PORTS
- CVector markPos = m_pPointGunAt->GetPosition();
-#else
CVector markPos;
if (m_pPointGunAt->IsPed()) {
((CPed*)m_pPointGunAt)->m_pedIK.GetComponentPosition(markPos, PED_MID);
} else {
markPos = m_pPointGunAt->GetPosition();
}
-#endif
if (bCanPointGunAtTarget) {
CWeaponEffects::MarkTarget(markPos, 64, 0, 0, 255, 0.8f);
} else {
@@ -1170,17 +1469,28 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
m_bHasLockOnTarget = m_pPointGunAt != nil;
}
+bool
+CPlayerPed::MovementDisabledBecauseOfTargeting(void)
+{
+ return m_pPointGunAt && !CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM);
+}
+
void
CPlayerPed::PlayerControlZelda(CPad *padUsed)
{
- bool doSmoothSpray = DoWeaponSmoothSpray();
+ float smoothSprayRate = DoWeaponSmoothSpray();
float camOrientation = TheCamera.Orientation;
float leftRight = padUsed->GetPedWalkLeftRight();
float upDown = padUsed->GetPedWalkUpDown();
float padMoveInGameUnit;
bool smoothSprayWithoutMove = false;
- if (doSmoothSpray && upDown > 0.0f) {
+ if (MovementDisabledBecauseOfTargeting()) {
+ upDown = 0.0f;
+ leftRight = 0.0f;
+ }
+
+ if (smoothSprayRate > 0.0f && upDown > 0.0f) {
padMoveInGameUnit = 0.0f;
smoothSprayWithoutMove = true;
} else {
@@ -1188,7 +1498,7 @@ CPlayerPed::PlayerControlZelda(CPad *padUsed)
}
#ifdef FREE_CAM
- if(TheCamera.Cams[0].Using3rdPersonMouseCam() && doSmoothSpray) {
+ if (TheCamera.Cams[0].Using3rdPersonMouseCam() && smoothSprayRate > 0.0f) {
padMoveInGameUnit = 0.0f;
smoothSprayWithoutMove = false;
}
@@ -1197,12 +1507,8 @@ CPlayerPed::PlayerControlZelda(CPad *padUsed)
if (padMoveInGameUnit > 0.0f || smoothSprayWithoutMove) {
float padHeading = CGeneral::GetRadianAngleBetweenPoints(0.0f, 0.0f, -leftRight, upDown);
float neededTurn = CGeneral::LimitRadianAngle(padHeading - camOrientation);
- if (doSmoothSpray) {
- if (GetWeapon()->m_eWeaponType == WEAPONTYPE_FLAMETHROWER || GetWeapon()->m_eWeaponType == WEAPONTYPE_COLT45
- || GetWeapon()->m_eWeaponType == WEAPONTYPE_UZI)
- m_fRotationDest = m_fRotationCur - leftRight / 128.0f * (PI / 80.0f) * CTimer::GetTimeStep();
- else
- m_fRotationDest = m_fRotationCur - leftRight / 128.0f * (PI / 128.0f) * CTimer::GetTimeStep();
+ if (smoothSprayRate > 0.0f) {
+ m_fRotationDest = m_fRotationCur - leftRight / 128.0f * smoothSprayRate * CTimer::GetTimeStep();
} else {
m_fRotationDest = neededTurn;
}
@@ -1228,13 +1534,20 @@ CPlayerPed::PlayerControlZelda(CPad *padUsed)
}
}
+ if (m_nPedState == PED_ANSWER_MOBILE) {
+ SetRealMoveAnim();
+ return;
+ }
+
if (!CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_HEAVY) && padUsed->GetSprint()) {
- m_nMoveState = PEDMOVE_SPRINT;
+ if (!m_pCurrentPhysSurface || (!m_pCurrentPhysSurface->bInfiniteMass || m_pCurrentPhysSurface->m_phy_flagA08))
+ m_nMoveState = PEDMOVE_SPRINT;
}
+
if (m_nPedState != PED_FIGHT)
SetRealMoveAnim();
- if (!bIsInTheAir && !(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_HEAVY))
+ if (!bIsInTheAir && !CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_HEAVY)
&& padUsed->JumpJustDown() && m_nPedState != PED_JUMP) {
ClearAttack();
ClearWeaponTarget();
@@ -1246,34 +1559,168 @@ CPlayerPed::PlayerControlZelda(CPad *padUsed)
SetJump();
}
}
+ PlayIdleAnimations(padUsed);
+}
+
+// Finds nice positions for peds to duck and shoot player. And it's inside PlayerPed, this is treachery!
+void
+CPlayerPed::FindNewAttackPoints(void)
+{
+ for (int i=0; i<ARRAY_SIZE(m_pPedAtSafePos); i++) {
+ CPed *safeNeighbour = m_pPedAtSafePos[i];
+ if (safeNeighbour) {
+ if (safeNeighbour->m_nPedState == PED_DEAD || safeNeighbour->m_pedInObjective != this) {
+ m_vecSafePos[i].x = 0.0f;
+ m_vecSafePos[i].y = 0.0f;
+ m_vecSafePos[i].z = 0.0f;
+ m_pPedAtSafePos[i] = nil;
+ }
+ } else {
+ m_vecSafePos[i].x = 0.0f;
+ m_vecSafePos[i].y = 0.0f;
+ m_vecSafePos[i].z = 0.0f;
+ }
+ }
+ CEntity *entities[6];
+ int16 numEnts;
+ float rightMult, fwdMult;
+ CWorld::FindObjectsInRange(GetPosition(), 18.0f, true, &numEnts, 6, entities, true, false, false, true, false);
+ for (int i = 0; i < numEnts; ++i) {
+ CEntity *ent = entities[i];
+ int16 mi = ent->GetModelIndex();
+ if (!ent->IsObject() || ((CObject*)ent)->m_nSpecialCollisionResponseCases == COLLRESPONSE_FENCEPART)
+ if (!IsTreeModel(mi))
+ continue;
+
+ if (mi == MI_TRAFFICLIGHTS) {
+ rightMult = 2.957f;
+ fwdMult = 0.147f;
+
+ } else if (mi == MI_SINGLESTREETLIGHTS1) {
+ rightMult = 0.744f;
+ fwdMult = 0.0f;
+
+ } else if (mi == MI_SINGLESTREETLIGHTS2) {
+ rightMult = 0.043f;
+ fwdMult = 0.0f;
+
+ } else if (mi == MI_SINGLESTREETLIGHTS3) {
+ rightMult = 1.143f;
+ fwdMult = 0.145f;
+
+ } else if (mi == MI_DOUBLESTREETLIGHTS) {
+ rightMult = 0.744f;
+ fwdMult = 0.0f;
+
+ } else if (mi == MI_LAMPPOST1) {
+ rightMult = 0.744f;
+ fwdMult = 0.0f;
+
+ } else if (mi == MI_TRAFFICLIGHT01) {
+ rightMult = 2.957f;
+ fwdMult = 0.147f;
+
+ } else if (mi == MI_LITTLEHA_POLICE) {
+ rightMult = 0.0f;
+ fwdMult = 0.0f;
+
+ } else if (mi == MI_PARKBENCH) {
+ rightMult = 0.0f;
+ fwdMult = 0.0f;
+
+ } else if (IsTreeModel(mi)) {
+ rightMult = 0.0f;
+ fwdMult = 0.0f;
+ } else
+ continue;
+
+ CVector entAttackPoint(rightMult * ent->GetRight().x + fwdMult * ent->GetForward().x + ent->GetPosition().x,
+ rightMult * ent->GetRight().y + fwdMult * ent->GetForward().y + ent->GetPosition().y,
+ ent->GetPosition().z);
+ CVector attackerPos = GetPosition() - entAttackPoint; // for now it's dist, not attackerPos
+ CVector dirTowardsUs = attackerPos;
+ dirTowardsUs.Normalise();
+ dirTowardsUs *= 2.0f;
+ attackerPos = entAttackPoint - dirTowardsUs; // to make cop farther from us
+ CPedPlacement::FindZCoorForPed(&attackerPos);
+ if (CPedPlacement::IsPositionClearForPed(attackerPos))
+ m_vecSafePos[i] = attackerPos;
+ }
}
void
CPlayerPed::ProcessControl(void)
{
+ // Mobile has some debug/abandoned cheat thing in here: "gbFrankenTommy"
+
if (m_nEvadeAmount != 0)
--m_nEvadeAmount;
if (m_nEvadeAmount == 0)
m_pEvadingFrom = nil;
+ if (m_pWanted->GetWantedLevel() > 0)
+ FindNewAttackPoints();
+
+ UpdateMeleeAttackers();
+
if (m_pCurrentPhysSurface && m_pCurrentPhysSurface->IsVehicle() && ((CVehicle*)m_pCurrentPhysSurface)->IsBoat()) {
bTryingToReachDryLand = true;
+
} else if (!(((uint8)CTimer::GetFrameCounter() + m_randomSeed) & 0xF)) {
- CVehicle *nearVeh = (CVehicle*)CWorld::TestSphereAgainstWorld(GetPosition(), 7.0f, nil,
- false, true, false, false, false, false);
+ CVehicle *nearVeh = (CVehicle*)CWorld::TestSphereAgainstWorld(GetPosition(), 7.0f, nil, false, true, false, false, false, false);
if (nearVeh && nearVeh->IsBoat())
bTryingToReachDryLand = true;
else
bTryingToReachDryLand = false;
}
+
+ if (m_nFadeDrunkenness) {
+ if (m_nDrunkenness - 1 > 0) {
+ --m_nDrunkenness;
+ } else {
+ m_nDrunkenness = 0;
+ CMBlur::ClearDrunkBlur();
+ m_nFadeDrunkenness = 0;
+ }
+ }
+ if (m_nDrunkenness != 0) {
+ CMBlur::SetDrunkBlur(m_nDrunkenness / 255.f);
+ }
CPed::ProcessControl();
+ SetNearbyPedsToInteractWithPlayer();
if (bWasPostponed)
return;
- CPad *padUsed = CPad::GetPad(0);
+ CPad *padUsed = GetPadFromPlayer(this);
m_pWanted->Update();
- CEntity::PruneReferences();
+ PruneReferences();
+
+ if (GetWeapon()->m_eWeaponType == WEAPONTYPE_MINIGUN) {
+ CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
+ CAnimBlendAssociation *fireAnim = RpAnimBlendClumpGetAssociation(GetClump(), GetPrimaryFireAnim(weaponInfo));
+ if (fireAnim && fireAnim->currentTime - fireAnim->timeStep < weaponInfo->m_fAnimLoopEnd && m_nPedState == PED_ATTACK) {
+ if (m_fGunSpinSpeed < 0.45f) {
+ m_fGunSpinSpeed = Min(0.45f, m_fGunSpinSpeed + CTimer::GetTimeStep() * 0.013f);
+ }
+
+ if (padUsed->GetWeapon() && GetWeapon()->m_nAmmoTotal > 0 && fireAnim->currentTime >= weaponInfo->m_fAnimLoopStart) {
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_MINIGUN_ATTACK, 0.0f);
+ } else {
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_MINIGUN_2, m_fGunSpinSpeed * (20.f / 9));
+ }
+ } else {
+ if (m_fGunSpinSpeed > 0.0f) {
+ if (m_fGunSpinSpeed >= 0.45f) {
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_MINIGUN_3, 0.0f);
+ }
+ m_fGunSpinSpeed = Max(0.0f, m_fGunSpinSpeed - CTimer::GetTimeStep() * 0.003f);
+ }
+ }
+ }
+ if (GetWeapon()->m_eWeaponType == WEAPONTYPE_CHAINSAW && m_nPedState != PED_ATTACK && !bInVehicle) {
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_CHAINSAW_IDLE, 0.0f);
+ }
if (m_nMoveState != PEDMOVE_RUN && m_nMoveState != PEDMOVE_SPRINT)
RestoreSprintEnergy(1.0f);
@@ -1291,27 +1738,29 @@ CPlayerPed::ProcessControl(void)
return;
}
if (m_nPedState == PED_DRIVING && m_objective != OBJECTIVE_LEAVE_CAR) {
- if (m_pMyVehicle->IsCar() && ((CAutomobile*)m_pMyVehicle)->Damage.GetDoorStatus(DOOR_FRONT_LEFT) == DOOR_STATUS_SWINGING) {
- CAnimBlendAssociation *rollDoorAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_CLOSE_DOOR_ROLLING_LHS);
-
- if (m_pMyVehicle->m_nGettingOutFlags & CAR_DOOR_FLAG_LF || rollDoorAssoc || (rollDoorAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_CLOSE_DOOR_ROLLING_LO_LHS))) {
- if (rollDoorAssoc)
- m_pMyVehicle->ProcessOpenDoor(CAR_DOOR_LF, ANIM_STD_CAR_CLOSE_DOOR_ROLLING_LHS, rollDoorAssoc->currentTime);
+ if (!CReplay::IsPlayingBack() || m_pMyVehicle) {
+ if (m_pMyVehicle->IsCar() && ((CAutomobile*)m_pMyVehicle)->Damage.GetDoorStatus(DOOR_FRONT_LEFT) == DOOR_STATUS_SWINGING) {
+ CAnimBlendAssociation *rollDoorAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_CLOSE_DOOR_ROLLING_LHS);
- } else {
- // These comparisons are wrong, they return uint16
- if (padUsed && (padUsed->GetAccelerate() != 0.0f || padUsed->GetSteeringLeftRight() != 0.0f || padUsed->GetBrake() != 0.0f)) {
+ if (m_pMyVehicle->m_nGettingOutFlags & CAR_DOOR_FLAG_LF || rollDoorAssoc || (rollDoorAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_CAR_CLOSE_DOOR_ROLLING_LO_LHS))) {
if (rollDoorAssoc)
m_pMyVehicle->ProcessOpenDoor(CAR_DOOR_LF, ANIM_STD_CAR_CLOSE_DOOR_ROLLING_LHS, rollDoorAssoc->currentTime);
} else {
- m_pMyVehicle->m_nGettingOutFlags |= CAR_DOOR_FLAG_LF;
- if (m_pMyVehicle->bLowVehicle)
- rollDoorAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_CLOSE_DOOR_ROLLING_LO_LHS);
- else
- rollDoorAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_CLOSE_DOOR_ROLLING_LHS);
+ // These comparisons are wrong, they return uint16
+ if (padUsed && (padUsed->GetAccelerate() != 0.0f || padUsed->GetSteeringLeftRight() != 0.0f || padUsed->GetBrake() != 0.0f)) {
+ if (rollDoorAssoc)
+ m_pMyVehicle->ProcessOpenDoor(CAR_DOOR_LF, ANIM_STD_CAR_CLOSE_DOOR_ROLLING_LHS, rollDoorAssoc->currentTime);
+
+ } else {
+ m_pMyVehicle->m_nGettingOutFlags |= CAR_DOOR_FLAG_LF;
+ if (m_pMyVehicle->bLowVehicle)
+ rollDoorAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_CLOSE_DOOR_ROLLING_LO_LHS);
+ else
+ rollDoorAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_CLOSE_DOOR_ROLLING_LHS);
- rollDoorAssoc->SetFinishCallback(PedAnimDoorCloseRollingCB, this);
+ rollDoorAssoc->SetFinishCallback(PedAnimDoorCloseRollingCB, this);
+ }
}
}
}
@@ -1321,11 +1770,11 @@ CPlayerPed::ProcessControl(void)
m_nMoveState = PEDMOVE_STILL;
if (bIsLanding)
RunningLand(padUsed);
- if (padUsed && padUsed->WeaponJustDown() && m_nPedState != PED_SNIPER_MODE) {
+ if (padUsed && padUsed->WeaponJustDown() && !TheCamera.Using1stPersonWeaponMode()) {
// ...Really?
eWeaponType playerWeapon = FindPlayerPed()->GetWeapon()->m_eWeaponType;
- if (playerWeapon == WEAPONTYPE_SNIPERRIFLE) {
+ if (playerWeapon == WEAPONTYPE_SNIPERRIFLE || playerWeapon == WEAPONTYPE_LASERSCOPE) {
DMAudio.PlayFrontEndSound(SOUND_WEAPON_SNIPER_SHOT_NO_ZOOM, 0);
} else if (playerWeapon == WEAPONTYPE_ROCKETLAUNCHER) {
DMAudio.PlayFrontEndSound(SOUND_WEAPON_ROCKET_SHOT_NO_ZOOM, 0);
@@ -1340,8 +1789,13 @@ CPlayerPed::ProcessControl(void)
case PED_ATTACK:
case PED_FIGHT:
case PED_AIM_GUN:
- if (!RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_BLOCK)) {
- if (TheCamera.Cams[0].Using3rdPersonMouseCam()
+ case PED_ANSWER_MOBILE:
+ if (!RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_BLOCK) && !m_attachedTo) {
+ if (TheCamera.Using1stPersonWeaponMode()) {
+ if (padUsed)
+ PlayerControlSniper(padUsed);
+
+ } else if (TheCamera.Cams[0].Using3rdPersonMouseCam()
#ifdef FREE_CAM
&& !CCamera::bFreeCam
#endif
@@ -1357,7 +1811,7 @@ CPlayerPed::ProcessControl(void)
PlayerControlZelda(padUsed);
}
}
- if (IsPedInControl() && padUsed)
+ if (IsPedInControl() && m_nPedState != PED_ANSWER_MOBILE && padUsed)
ProcessPlayerWeapon(padUsed);
break;
case PED_SEEK_ENTITY:
@@ -1386,12 +1840,12 @@ CPlayerPed::ProcessControl(void)
}
break;
case PED_SNIPER_MODE:
- if (FindPlayerPed()->GetWeapon()->m_eWeaponType == WEAPONTYPE_M16) {
+ if (GetWeapon()->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE || GetWeapon()->m_eWeaponType == WEAPONTYPE_LASERSCOPE) {
if (padUsed)
- PlayerControlM16(padUsed);
+ PlayerControlSniper(padUsed);
} else if (padUsed) {
- PlayerControlSniper(padUsed);
+ PlayerControlM16(padUsed);
}
break;
case PED_SEEK_CAR:
@@ -1442,9 +1896,9 @@ CPlayerPed::ProcessControl(void)
default:
break;
}
- if (padUsed && IsPedShootable()) {
+ if (padUsed && IsPedShootable() && m_nPedState != PED_ANSWER_MOBILE && m_nLastPedState != PED_ANSWER_MOBILE) {
ProcessWeaponSwitch(padUsed);
- GetWeapon()->Update(m_audioEntityId);
+ GetWeapon()->Update(m_audioEntityId, this);
}
ProcessAnimGroups();
if (padUsed) {
@@ -1454,12 +1908,13 @@ CPlayerPed::ProcessControl(void)
m_lookTimer = 0;
float camAngle = CGeneral::LimitRadianAngle(TheCamera.Cams[TheCamera.ActiveCam].Front.Heading());
float angleBetweenPlayerAndCam = Abs(camAngle - m_fRotationCur);
- if (m_nPedState != PED_ATTACK && angleBetweenPlayerAndCam > DEGTORAD(30.0f) && angleBetweenPlayerAndCam < DEGTORAD(330.0f)) {
+ if (m_nPedState != PED_ATTACK && angleBetweenPlayerAndCam > DEGTORAD(30.0f) && angleBetweenPlayerAndCam < DEGTORAD(330.0f)) {
if (angleBetweenPlayerAndCam > DEGTORAD(150.0f) && angleBetweenPlayerAndCam < DEGTORAD(210.0f)) {
float rightTurnAngle = CGeneral::LimitRadianAngle(m_fRotationCur - DEGTORAD(150.0f));
float leftTurnAngle = CGeneral::LimitRadianAngle(DEGTORAD(150.0f) + m_fRotationCur);
- if (m_fLookDirection == 999999.0f)
+
+ if (m_fLookDirection == 999999.0f || bIsDucking)
camAngle = rightTurnAngle;
else if (Abs(rightTurnAngle - m_fLookDirection) < Abs(leftTurnAngle - m_fLookDirection))
camAngle = rightTurnAngle;
@@ -1490,10 +1945,279 @@ CPlayerPed::ProcessControl(void)
m_bSpeedTimerFlag = false;
}
-#ifdef PED_SKIN
- if (!bIsVisible && IsClumpSkinned(GetClump()))
+ if (bDontAllowWeaponChange && FindPlayerPed() == this) {
+ if (!CPad::GetPad(0)->GetTarget())
+ bDontAllowWeaponChange = false;
+ }
+
+ if (m_nPedState != PED_SNIPER_MODE && (GetWeapon()->m_eWeaponState == WEAPONSTATE_FIRING || m_nPedState == PED_ATTACK))
+ m_nPadDownPressedInMilliseconds = CTimer::GetTimeInMilliseconds();
+
+ if (!bIsVisible)
UpdateRpHAnim();
+}
+
+bool
+CPlayerPed::DoesPlayerWantNewWeapon(eWeaponType weapon, bool onlyIfSlotIsEmpty)
+{
+ // GetPadFromPlayer(); // unused
+ 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;
+}
+
+void
+CPlayerPed::PlayIdleAnimations(CPad *padUsed)
+{
+ CAnimBlendAssociation* assoc;
+
+ if (TheCamera.m_WideScreenOn || bIsDucking)
+ return;
+
+ struct animAndGroup {
+ AnimationId animId;
+ AssocGroupId groupId;
+ };
+
+ const animAndGroup idleAnims[] = {
+ {ANIM_PLAYER_IDLE1, ASSOCGRP_PLAYER_IDLE},
+ {ANIM_PLAYER_IDLE2, ASSOCGRP_PLAYER_IDLE},
+ {ANIM_PLAYER_IDLE3, ASSOCGRP_PLAYER_IDLE},
+ {ANIM_PLAYER_IDLE4, ASSOCGRP_PLAYER_IDLE},
+ {ANIM_STD_XPRESS_SCRATCH, ASSOCGRP_STD},
+ };
+
+ static int32 lastTime = 0;
+ static int32 lastAnim = -1;
+
+ bool hasIdleAnim = false;
+ CAnimBlock *idleAnimBlock = CAnimManager::GetAnimationBlock(idleAnimBlockIndex);
+ uint32 sinceLastInput = padUsed->InputHowLongAgo();
+ if (sinceLastInput <= 30000) {
+ if (idleAnimBlock->isLoaded) {
+ for (assoc = RpAnimBlendClumpGetFirstAssociation(GetClump()); assoc; assoc = RpAnimBlendGetNextAssociation(assoc)) {
+ if (assoc->flags & ASSOC_IDLE) {
+ hasIdleAnim = true;
+ assoc->blendDelta = -8.0f;
+ }
+ }
+ if (!hasIdleAnim)
+ CStreaming::RemoveAnim(idleAnimBlockIndex);
+ } else {
+ lastTime = 0;
+ }
+ } else {
+ CStreaming::RequestAnim(idleAnimBlockIndex, STREAMFLAGS_DONT_REMOVE);
+ if (idleAnimBlock->isLoaded) {
+ for(CAnimBlendAssociation *assoc = RpAnimBlendClumpGetFirstAssociation(GetClump()); assoc; assoc = RpAnimBlendGetNextAssociation(assoc)) {
+ int firstIdle = idleAnimBlock->firstIndex;
+ int index = assoc->hierarchy - CAnimManager::GetAnimation(0);
+ if (index >= firstIdle && index < firstIdle + idleAnimBlock->numAnims) {
+ hasIdleAnim = true;
+ break;
+ }
+ }
+
+ if (!hasIdleAnim && !bIsLooking && !bIsRestoringLook && sinceLastInput - lastTime > 25000) {
+ int anim;
+ do
+ anim = CGeneral::GetRandomNumberInRange(0, ARRAY_SIZE(idleAnims));
+ while (lastAnim == anim);
+
+ assoc = CAnimManager::BlendAnimation(GetClump(), idleAnims[anim].groupId, idleAnims[anim].animId, 8.0f);
+ assoc->flags |= ASSOC_IDLE;
+ lastAnim = anim;
+ lastTime = sinceLastInput;
+ }
+ }
+ }
+}
+
+void
+CPlayerPed::SetNearbyPedsToInteractWithPlayer(void)
+{
+ if (CGame::noProstitutes)
+ return;
+
+ for (int i = 0; i < m_numNearPeds; ++i) {
+ CPed *nearPed = m_nearPeds[i];
+ if (nearPed && nearPed->m_objectiveTimer < CTimer::GetTimeInMilliseconds() && !CTheScripts::IsPlayerOnAMission()) {
+ int mi = nearPed->GetModelIndex();
+ if (CPopulation::CanSolicitPlayerOnFoot(mi)) {
+ CVector distToMe = nearPed->GetPosition() - GetPosition();
+ CVector dirToMe = GetPosition() - nearPed->GetPosition();
+ dirToMe.Normalise();
+ if (DotProduct(dirToMe, nearPed->GetForward()) > 0.707 && DotProduct(GetForward(), nearPed->GetForward()) < -0.707 // those are double
+ && distToMe.MagnitudeSqr() < 9.0f && nearPed->m_objective == OBJECTIVE_NONE) {
+ nearPed->SetObjective(OBJECTIVE_SOLICIT_FOOT, this);
+ nearPed->m_objectiveTimer = CTimer::GetTimeInMilliseconds() + 10000;
+ nearPed->Say(SOUND_PED_SOLICIT);
+ }
+ } else if (CPopulation::CanSolicitPlayerInCar(mi)) {
+ if (InVehicle() && m_pMyVehicle->IsVehicleNormal()) {
+ if (m_pMyVehicle->IsCar()) {
+ CVector distToVeh = nearPed->GetPosition() - m_pMyVehicle->GetPosition();
+ if (distToVeh.MagnitudeSqr() < 25.0f && m_pMyVehicle->IsRoomForPedToLeaveCar(CAR_DOOR_LF, nil) && nearPed->m_objective == OBJECTIVE_NONE) {
+ nearPed->SetObjective(OBJECTIVE_SOLICIT_VEHICLE, m_pMyVehicle);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void
+CPlayerPed::UpdateMeleeAttackers(void)
+{
+ CVector attackCoord;
+ if (((CTimer::GetFrameCounter() + m_randomSeed + 7) & 3) == 0) {
+ GetMeleeAttackCoords(attackCoord, m_nAttackDirToCheck, 2.0f);
+
+ // Check if there is any vehicle/building inbetween us and m_nAttackDirToCheck. Peds will be able to attack us from those available directions.
+ if (CWorld::GetIsLineOfSightClear(GetPosition(), attackCoord, true, true, false, true, false, false, false)
+ && !CWorld::TestSphereAgainstWorld(attackCoord, 0.4f, m_pMeleeList[m_nAttackDirToCheck], true, true, false, true, false, false)) {
+ if (m_pMeleeList[m_nAttackDirToCheck] == this)
+ m_pMeleeList[m_nAttackDirToCheck] = nil; // mark it as available
+ } else {
+ m_pMeleeList[m_nAttackDirToCheck] = this; // slot not available. useful for m_bNoPosForMeleeAttack
+ }
+ if (++m_nAttackDirToCheck >= ARRAY_SIZE(m_pMeleeList))
+ m_nAttackDirToCheck = 0;
+ }
+ // 6 directions
+ for (int i = 0; i < ARRAY_SIZE(m_pMeleeList); ++i) {
+ CPed *victim = m_pMeleeList[i];
+ if (victim && victim != this) {
+ if (victim->m_nPedState != PED_DEAD && victim->m_pedInObjective == this) {
+ if (victim->m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT || victim->m_objective == OBJECTIVE_KILL_CHAR_ANY_MEANS || victim->m_objective == OBJECTIVE_KILL_CHAR_ON_BOAT) {
+ GetMeleeAttackCoords(attackCoord, i, 2.0f);
+ if ((attackCoord - GetPosition()).MagnitudeSqr() > 12.25f)
+ m_pMeleeList[i] = nil;
+ } else {
+ m_pMeleeList[i] = nil;
+ }
+ } else {
+ m_pMeleeList[i] = nil;
+ }
+ }
+ }
+ m_bNoPosForMeleeAttack = m_pMeleeList[0] == this && m_pMeleeList[1] == this && m_pMeleeList[2] == this
+#ifdef FIX_BUGS
+ && m_pMeleeList[3] == this
#endif
+ && m_pMeleeList[4] == this && m_pMeleeList[5] == this;
+}
+
+void
+CPlayerPed::RemovePedFromMeleeList(CPed *ped)
+{
+ for (uint16 i = 0; i < ARRAY_SIZE(m_pMeleeList); i++) {
+ if (m_pMeleeList[i] == ped) {
+ m_pMeleeList[i] = nil;
+ ped->m_attackTimer = 0;
+ return;
+ }
+ }
+}
+
+void
+CPlayerPed::GetMeleeAttackCoords(CVector& coords, int8 dir, float dist)
+{
+ coords = GetPosition();
+ switch (dir) {
+ case 0:
+ coords.y += dist;
+ break;
+ case 1:
+ coords.x += Sqrt(3.f / 4.f) * dist;
+ coords.y += 0.5f * dist;
+ break;
+ case 2:
+ coords.x += Sqrt(3.f / 4.f) * dist;
+ coords.y -= 0.5f * dist;
+ break;
+ case 3:
+ coords.y -= dist;
+ break;
+ case 4:
+ coords.x -= Sqrt(3.f / 4.f) * dist;
+ coords.y -= 0.5f * dist;
+ break;
+ case 5:
+ coords.x -= Sqrt(3.f / 4.f) * dist;
+ coords.y += 0.5f * dist;
+ break;
+ default:
+ break;
+ }
+}
+
+int32
+CPlayerPed::FindMeleeAttackPoint(CPed *victim, CVector &dist, uint32 &endOfAttackOut)
+{
+ endOfAttackOut = 0;
+ bool thereIsAnEmptySlot = false;
+ int dirToAttack = -1;
+ for (int i = 0; i < ARRAY_SIZE(m_pMeleeList); i++) {
+ CPed* pedAtThisDir = m_pMeleeList[i];
+ if (pedAtThisDir) {
+ if (pedAtThisDir == victim) {
+ dirToAttack = i;
+ } else {
+ if (pedAtThisDir->m_attackTimer > endOfAttackOut)
+ endOfAttackOut = pedAtThisDir->m_attackTimer;
+ }
+ } else {
+ thereIsAnEmptySlot = true;
+ }
+ }
+
+ // We don't have victim ped in our melee list
+ if (dirToAttack == -1 && thereIsAnEmptySlot) {
+ float angle = Atan2(-dist.x, -dist.y);
+ float adjustedAngle = angle + DEGTORAD(30.0f);
+ if (adjustedAngle < 0.f)
+ adjustedAngle += TWOPI;
+
+ int wantedDir = Floor(adjustedAngle / DEGTORAD(60.0f));
+
+ // And we have another ped at the direction of victim ped, so store victim to next empty direction to it's real direction. (Bollocks)
+ if (m_pMeleeList[wantedDir]) {
+ int closestDirToPreferred = -99;
+ int preferredDir = wantedDir;
+
+ for (int i = 0; i < ARRAY_SIZE(m_pMeleeList); i++) {
+ if (!m_pMeleeList[i]) {
+ if (Abs(i - preferredDir) < Abs(closestDirToPreferred - preferredDir))
+ closestDirToPreferred = i;
+ }
+ }
+ if (closestDirToPreferred > 0)
+ dirToAttack = closestDirToPreferred;
+ } else {
+
+ // Luckily the direction of victim ped is already empty, good
+ dirToAttack = wantedDir;
+ }
+
+ if (dirToAttack != -1) {
+ m_pMeleeList[dirToAttack] = victim;
+ victim->RegisterReference((CEntity**) &m_pMeleeList[dirToAttack]);
+ if (endOfAttackOut > CTimer::GetTimeInMilliseconds())
+ victim->m_attackTimer = endOfAttackOut + CGeneral::GetRandomNumberInRange(1000, 2000);
+ else
+ victim->m_attackTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(500, 1000);
+ }
+ }
+ return dirToAttack;
}
#ifdef COMPATIBLE_SAVES
@@ -1510,7 +2234,7 @@ CPlayerPed::Save(uint8*& buf)
CopyToBuf(buf, m_nTargettableObjects[1]);
CopyToBuf(buf, m_nTargettableObjects[2]);
CopyToBuf(buf, m_nTargettableObjects[3]);
- ZeroSaveBuf(buf, 116);
+ ZeroSaveBuf(buf, 164);
}
void
@@ -1524,7 +2248,7 @@ CPlayerPed::Load(uint8*& buf)
CopyFromBuf(buf, m_nTargettableObjects[1]);
CopyFromBuf(buf, m_nTargettableObjects[2]);
CopyFromBuf(buf, m_nTargettableObjects[3]);
- SkipSaveBuf(buf, 116);
+ SkipSaveBuf(buf, 164);
}
#undef CopyFromBuf
#undef CopyToBuf
diff --git a/src/peds/PlayerPed.h b/src/peds/PlayerPed.h
index e8173c8c..30b67199 100644
--- a/src/peds/PlayerPed.h
+++ b/src/peds/PlayerPed.h
@@ -15,25 +15,46 @@ public:
float m_fCurrentStamina;
float m_fMaxStamina;
float m_fStaminaProgress;
- int8 m_nSelectedWepSlot; // eWeaponType
+ int8 m_nSelectedWepSlot;
bool m_bSpeedTimerFlag;
uint8 m_nEvadeAmount;
- int8 field_1367;
- uint32 m_nSpeedTimer;
- uint32 m_nHitAnimDelayTimer;
+ uint32 m_nSpeedTimer; // m_nStandStillTimer?
+ uint32 m_nHitAnimDelayTimer; // m_nShotDelay?
float m_fAttackButtonCounter;
bool m_bHaveTargetSelected; // may have better name
CEntity *m_pEvadingFrom; // is this CPhysical?
int32 m_nTargettableObjects[4];
+ uint32 m_nAdrenalineTime;
+ uint8 m_nDrunkenness; // Needed to work out whether we lost target this frame
+ uint8 m_nFadeDrunkenness;
+ uint8 m_nDrunkCountdown; //countdown in frames when the drunk effect ends
bool m_bAdrenalineActive;
bool m_bHasLockOnTarget;
- uint32 m_nAdrenalineTime;
bool m_bCanBeDamaged;
- int8 field_1413;
+ bool m_bNoPosForMeleeAttack;
+ bool unk1;
CVector m_vecSafePos[6]; // safe places from the player, for example behind a tree
CPed *m_pPedAtSafePos[6];
- float m_fWalkAngle;
+ CPed *m_pMeleeList[6]; // reachable peds at each direction(6)
+ int16 m_nAttackDirToCheck;
+ float m_fWalkAngle; //angle between heading and walking direction
float m_fFPSMoveHeading;
+ RpAtomic* m_pMinigunTopAtomic; //atomic for the spinning part of the minigun model
+ float m_fGunSpinSpeed; // for minigun
+ float m_fGunSpinAngle;
+ unsigned int m_nPadDownPressedInMilliseconds;
+ unsigned int m_nLastBusFareCollected;
+#ifdef FREE_CAM
+ bool m_bFreeAimActive;
+ CVector m_cachedCamSource;
+ CVector m_cachedCamFront;
+ CVector m_cachedCamUp;
+#endif
+
+ static bool bDontAllowWeaponChange;
+#ifndef MASTER
+ static bool bDebugPlayerInfo;
+#endif
CPlayerPed();
~CPlayerPed();
@@ -45,7 +66,8 @@ public:
void SetWantedLevelNoDrop(int32 level);
void KeepAreaAroundPlayerClear(void);
void AnnoyPlayerPed(bool);
- void MakeChangesForNewWeapon(int8);
+ void MakeChangesForNewWeapon(int32);
+ void MakeChangesForNewWeapon(eWeaponType);
void SetInitialState(void);
void ProcessControl(void);
void ClearAdrenaline(void);
@@ -53,24 +75,35 @@ public:
class CPlayerInfo *GetPlayerInfoForThisPlayerPed();
void SetRealMoveAnim(void);
void RestoreSprintEnergy(float);
- bool DoWeaponSmoothSpray(void);
+ float DoWeaponSmoothSpray(void);
void DoStuffToGoOnFire(void);
bool DoesTargetHaveToBeBroken(CVector, CWeapon*);
void RunningLand(CPad*);
- bool IsThisPedAttackingPlayer(CPed*);
+ bool IsThisPedAnAimingPriority(CPed*);
void PlayerControlSniper(CPad*);
void PlayerControlM16(CPad*);
void PlayerControlFighter(CPad*);
void ProcessWeaponSwitch(CPad*);
void MakeObjectTargettable(int32);
void PlayerControl1stPersonRunAround(CPad *padUsed);
- void EvaluateNeighbouringTarget(CEntity*, CEntity**, float*, float, float, bool);
+ void EvaluateNeighbouringTarget(CEntity*, CEntity**, float*, float, float, bool, bool);
void EvaluateTarget(CEntity*, CEntity**, float*, float, float, bool);
bool FindNextWeaponLockOnTarget(CEntity*, bool);
bool FindWeaponLockOnTarget(void);
void ProcessAnimGroups(void);
void ProcessPlayerWeapon(CPad*);
void PlayerControlZelda(CPad*);
+ bool DoesPlayerWantNewWeapon(eWeaponType, bool);
+ void PlayIdleAnimations(CPad*);
+ void RemovePedFromMeleeList(CPed*);
+ void GetMeleeAttackCoords(CVector&, int8, float);
+ int32 FindMeleeAttackPoint(CPed*, CVector&, uint32&);
+ bool CanIKReachThisTarget(CVector, CWeapon*, bool);
+ void RotatePlayerToTrackTarget(void);
+ bool MovementDisabledBecauseOfTargeting(void);
+ void FindNewAttackPoints(void);
+ void SetNearbyPedsToInteractWithPlayer(void);
+ void UpdateMeleeAttackers(void);
static void SetupPlayerPed(int32);
static void DeactivatePlayerPed(int32);
@@ -84,6 +117,4 @@ public:
static const uint32 nSaveStructSize;
};
-#ifndef PED_SKIN
-VALIDATE_SIZE(CPlayerPed, 0x5F0);
-#endif
+//VALIDATE_SIZE(CPlayerPed, 0x5F0);
diff --git a/src/peds/Population.cpp b/src/peds/Population.cpp
index 5c80702f..495cad16 100644
--- a/src/peds/Population.cpp
+++ b/src/peds/Population.cpp
@@ -22,7 +22,12 @@
#include "DummyObject.h"
#include "Script.h"
#include "Shadows.h"
-#include "Bike.h"
+#include "SurfaceTable.h"
+#include "Weather.h"
+#include "Darkel.h"
+#include "Streaming.h"
+#include "Clock.h"
+#include "WaterLevel.h"
#define MIN_CREATION_DIST 40.0f // not for start of the game (look at the GeneratePedsAtStartOfGame)
#define CREATION_RANGE 10.0f // added over the MIN_CREATION_DIST.
@@ -30,32 +35,13 @@
#define PED_REMOVE_DIST (MIN_CREATION_DIST + CREATION_RANGE + 1.0f)
#define PED_REMOVE_DIST_SPECIAL (MIN_CREATION_DIST + CREATION_RANGE + 15.0f) // for peds with bCullExtraFarAway flag
-// Transition areas between zones
-const RegenerationPoint aSafeZones[] = {
- LEVEL_INDUSTRIAL, LEVEL_COMMERCIAL, 400.0f, 814.0f, -954.0f, -903.0f, 30.0f, 100.0f,
- 790.0f, -917.0f, 39.0f, 775.0f, -921.0f, 39.0f, 424.0f, -942.0f, 38.0f, 439.0f, -938.0f, 38.0f,
- LEVEL_INDUSTRIAL, LEVEL_COMMERCIAL, 555.0f, 711.0f, 118.0f, 186.0f, -30.0f, -10.0f,
- CVector(698.0f, 182.0f, -20.0f), CVector(681.0f, 178.0f, -20.0f), CVector(586.0f, 144.0f, -20.0f), CVector(577.0f, 135.0f, -20.0f),
- LEVEL_INDUSTRIAL, LEVEL_COMMERCIAL, 626.0f, 744.0f, -124.0f, -87.0f, -20.0f, -6.0f,
- CVector(736.0f, -117.0f, -13.0f), CVector(730.0f, -115.0f, -13.0f), CVector(635.0f, -93.0f, -12.5f), CVector(650.0f, -89.0f, -12.5f),
- LEVEL_INDUSTRIAL, LEVEL_COMMERCIAL, 645.0f, 734.0f, -780.0f, -750.0f, -25.0f, -6.0f,
- CVector(729.0f, -764.0f, -18.0f), CVector(720.0f, -769.0f, -17.0f), CVector(652.0f, -774.0f, -10.5f), CVector(659.0f, -770.0f, -10.5f),
- LEVEL_COMMERCIAL, LEVEL_SUBURBAN, -532.0f, -136.0f, -668.0f, -599.0f, 34.0f, 60.0f,
- CVector(-172.0f, -619.0f, 44.0f), CVector(-183.0f, -623.0f, 44.0f), CVector(-511.0f, -645.0f, 41.0f), CVector(-493.0f, -639.0f, 41.5f),
- LEVEL_COMMERCIAL, LEVEL_SUBURBAN, -325.0f, -175.0f, 27.0f, 75.0f, -30.0f, -10.0f,
- CVector(-185.0f, 40.8f, -20.5f), CVector(-202.0f, 37.0f, -20.5f), CVector(-315.0f, 65.5f, -20.5f), CVector(-306.0f, 62.4f, -20.5f),
- LEVEL_COMMERCIAL, LEVEL_SUBURBAN, -410.0f, -310.0f, -1055.0f, -1030.0f, -20.0f, -6.0f,
- CVector(-321.0f, -1043.0f, -13.2f), CVector(-328.0f, -1045.0f, -13.2f), CVector(-398.0f, -1044.0f, -13.5f), CVector(-390.0f, -1040.5f, -13.5f),
- LEVEL_COMMERCIAL, LEVEL_SUBURBAN, -425.0f, -280.0f, -471.0f, -447.0f, -20.0f, -5.0f,
- CVector(-292.0f, -457.0f, -11.6f), CVector(-310.0f, -461.0f, -11.6f), CVector(-413.0f, -461.0f, -11.5f), CVector(-399.0f, -457.0f, -11.3f)
-};
-
PedGroup CPopulation::ms_pPedGroups[NUMPEDGROUPS];
bool CPopulation::ms_bGivePedsWeapons;
int32 CPopulation::m_AllRandomPedsThisType = -1;
float CPopulation::PedDensityMultiplier = 1.0f;
uint32 CPopulation::ms_nTotalMissionPeds;
int32 CPopulation::MaxNumberOfPedsInUse = DEFAULT_MAX_NUMBER_OF_PEDS;
+int32 CPopulation::MaxNumberOfPedsInUseInterior = DEFAULT_MAX_NUMBER_OF_PEDS_INTERIOR;
uint32 CPopulation::ms_nNumCivMale;
uint32 CPopulation::ms_nNumCivFemale;
uint32 CPopulation::ms_nNumCop;
@@ -75,9 +61,13 @@ uint32 CPopulation::ms_nNumGang6;
uint32 CPopulation::ms_nNumGang9;
uint32 CPopulation::ms_nNumGang7;
uint32 CPopulation::ms_nNumGang8;
-CVector CPopulation::RegenerationPoint_a;
-CVector CPopulation::RegenerationPoint_b;
-CVector CPopulation::RegenerationFront;
+
+uint32 CPopulation::ms_nTotalCarPassengerPeds;
+uint32 CPopulation::NumMiamiViceCops;
+
+uint32 gLastSelectedCivilianIndex;
+CEntity *gSunbatheObstacles[2];
+CEntity *gCoupleObstacles[3];
void
CPopulation::Initialise()
@@ -99,18 +89,19 @@ CPopulation::Initialise()
ms_nNumGang9 = 0;
ms_nNumDummy = 0;
+ ms_nTotalCarPassengerPeds = 0;
+ ms_nTotalCivPeds = 0;
+ ms_nTotalGangPeds = 0;
+ ms_nTotalPeds = 0;
+ ms_nTotalMissionPeds = 0;
+ m_CountDownToPedsAtStart = 2;
+ bZoneChangeHasHappened = false; // III leftover
+
m_AllRandomPedsThisType = -1;
PedDensityMultiplier = 1.0f;
- bZoneChangeHasHappened = false;
- m_CountDownToPedsAtStart = 2;
- ms_nTotalMissionPeds = 0;
- ms_nTotalPeds = 0;
- ms_nTotalGangPeds = 0;
- ms_nTotalCivPeds = 0;
LoadPedGroups();
- DealWithZoneChange(LEVEL_COMMERCIAL, LEVEL_INDUSTRIAL, true);
debug("CPopulation ready\n");
}
@@ -125,7 +116,45 @@ CPopulation::RemovePed(CPed *ent)
int32
CPopulation::ChooseCivilianOccupation(int32 group)
{
- return ms_pPedGroups[group].models[CGeneral::GetRandomNumberInRange(0, NUMMODELSPERPEDGROUP)];
+ if (CWeather::Rain > 0.1f) {
+ int32 lastModel;
+ for (int i = 0; i < 8; i++) {
+ gLastSelectedCivilianIndex = CGeneral::GetRandomNumberInRange(0, NUMMODELSPERPEDGROUP);
+ lastModel = ms_pPedGroups[group].models[gLastSelectedCivilianIndex];
+
+ if (!CPopulation::IsSunbather(lastModel))
+ break;
+ }
+ return lastModel;
+
+ } else {
+ gLastSelectedCivilianIndex = CGeneral::GetRandomNumberInRange(0, NUMMODELSPERPEDGROUP);
+ return ms_pPedGroups[group].models[gLastSelectedCivilianIndex];
+ }
+}
+
+int32
+CPopulation::ChooseNextCivilianOccupation(int32 group)
+{
+ if (CWeather::Rain > 0.1f) {
+ int32 lastModel;
+ for (int i = 0; i < NUMMODELSPERPEDGROUP; i++) {
+ ++gLastSelectedCivilianIndex;
+ if (gLastSelectedCivilianIndex >= NUMMODELSPERPEDGROUP)
+ gLastSelectedCivilianIndex = 0;
+ lastModel = ms_pPedGroups[group].models[gLastSelectedCivilianIndex];
+
+ if (!CPopulation::IsSunbather(ms_pPedGroups[group].models[gLastSelectedCivilianIndex]))
+ break;
+ }
+ return lastModel;
+
+ } else {
+ ++gLastSelectedCivilianIndex;
+ if (gLastSelectedCivilianIndex >= NUMMODELSPERPEDGROUP)
+ gLastSelectedCivilianIndex = 0;
+ return ms_pPedGroups[group].models[gLastSelectedCivilianIndex];
+ }
}
// returns eCopType
@@ -320,108 +349,20 @@ 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);
}
void
CPopulation::DealWithZoneChange(eLevelName oldLevel, eLevelName newLevel, bool forceIndustrialZone)
{
- bZoneChangeHasHappened = true;
-
- CVector findSafeZoneAround;
- int safeZone;
-
- if (forceIndustrialZone) {
- // Commercial to industrial transition area on Callahan Bridge
- findSafeZoneAround.x = 690.0f;
- findSafeZoneAround.y = -920.0f;
- findSafeZoneAround.z = 42.0f;
- } else {
- findSafeZoneAround = FindPlayerCoors();
- }
- eLevelName level;
- FindCollisionZoneForCoors(&findSafeZoneAround, &safeZone, &level);
-
- // We aren't in a "safe zone", find closest one
- if (safeZone < 0)
- FindClosestZoneForCoors(&findSafeZoneAround, &safeZone, oldLevel, newLevel);
-
- // No, there should be one!
- if (safeZone < 0) {
- if (newLevel == LEVEL_INDUSTRIAL) {
- safeZone = 0;
- } else if (newLevel == LEVEL_SUBURBAN) {
- safeZone = 4;
- }
- }
-
- if (aSafeZones[safeZone].srcLevel == newLevel) {
- CPopulation::RegenerationPoint_a = aSafeZones[safeZone].srcPosA;
- CPopulation::RegenerationPoint_b = aSafeZones[safeZone].srcPosB;
- CPopulation::RegenerationFront = aSafeZones[safeZone].destPosA - aSafeZones[safeZone].srcPosA;
- RegenerationFront.Normalise();
- } else if (aSafeZones[safeZone].destLevel == newLevel) {
- CPopulation::RegenerationPoint_a = aSafeZones[safeZone].destPosA;
- CPopulation::RegenerationPoint_b = aSafeZones[safeZone].destPosB;
- CPopulation::RegenerationFront = aSafeZones[safeZone].srcPosA - aSafeZones[safeZone].destPosA;
- RegenerationFront.Normalise();
- }
-}
-
-void
-CPopulation::FindCollisionZoneForCoors(CVector *coors, int *safeZoneOut, eLevelName *levelOut)
-{
- *safeZoneOut = -1;
- for (int i = 0; i < ARRAY_SIZE(aSafeZones); i++) {
- if (coors->x > aSafeZones[i].x1 && coors->x < aSafeZones[i].x2) {
- if (coors->y > aSafeZones[i].y1 && coors->y < aSafeZones[i].y2) {
- if (coors->z > aSafeZones[i].z1 && coors->z < aSafeZones[i].z2)
- *safeZoneOut = i;
- }
- }
- }
- // Then it's transition area
- if (*safeZoneOut >= 0)
- *levelOut = LEVEL_GENERIC;
- else
- *levelOut = CTheZones::GetLevelFromPosition(coors);
}
void
-CPopulation::FindClosestZoneForCoors(CVector *coors, int *safeZoneOut, eLevelName level1, eLevelName level2)
-{
- float minDist = 10000000.0f;
- int closestSafeZone = -1;
- for (int i = 0; i < ARRAY_SIZE(aSafeZones); i++) {
- if ((level1 == aSafeZones[i].srcLevel || level1 == aSafeZones[i].destLevel) && (level2 == aSafeZones[i].srcLevel || level2 == aSafeZones[i].destLevel)) {
- CVector2D safeZoneDistVec(coors->x - (aSafeZones[i].x1 + aSafeZones[i].x2) * 0.5f, coors->y - (aSafeZones[i].y1 + aSafeZones[i].y2) * 0.5f);
- float safeZoneDist = safeZoneDistVec.Magnitude();
- if (safeZoneDist < minDist) {
- minDist = safeZoneDist;
- closestSafeZone = i;
- }
- }
- }
- *safeZoneOut = closestSafeZone;
-}
-
-void
-CPopulation::Update()
+CPopulation::Update(bool addPeds)
{
if (!CReplay::IsPlayingBack()) {
ManagePopulation();
+ RemovePedsIfThePoolGetsFull();
MoveCarsAndPedsOutOfAbandonedZones();
if (m_CountDownToPedsAtStart != 0) {
if (--m_CountDownToPedsAtStart == 0)
@@ -433,7 +374,8 @@ CPopulation::Update()
+ ms_nNumGang2 + ms_nNumGang1;
ms_nTotalPeds = ms_nNumDummy + ms_nNumEmergency + ms_nNumCop
+ ms_nTotalGangPeds + ms_nNumCivFemale + ms_nNumCivMale;
- if (!CCutsceneMgr::IsRunning()) {
+ ms_nTotalPeds -= ms_nTotalCarPassengerPeds;
+ if (!CCutsceneMgr::IsRunning() && addPeds) {
float pcdm = PedCreationDistMultiplier();
AddToPopulation(pcdm * (MIN_CREATION_DIST * TheCamera.GenerationDistMultiplier),
pcdm * ((MIN_CREATION_DIST + CREATION_RANGE) * TheCamera.GenerationDistMultiplier),
@@ -447,13 +389,14 @@ CPopulation::Update()
void
CPopulation::GeneratePedsAtStartOfGame()
{
- for (int i = 0; i < 50; i++) {
+ for (int i = 0; i < 100; i++) {
ms_nTotalCivPeds = ms_nNumCivFemale + ms_nNumCivMale;
ms_nTotalGangPeds = ms_nNumGang9 + ms_nNumGang8 + ms_nNumGang7
+ ms_nNumGang6 + ms_nNumGang5 + ms_nNumGang4
+ ms_nNumGang3 + ms_nNumGang2 + ms_nNumGang1;
ms_nTotalPeds = ms_nNumDummy + ms_nNumEmergency + ms_nNumCop
+ ms_nTotalGangPeds + ms_nNumCivFemale + ms_nNumCivMale;
+ ms_nTotalPeds -= ms_nTotalCarPassengerPeds;
// Min dist is 10.0f only for start of the game (naturally)
AddToPopulation(10.0f, PedCreationDistMultiplier() * (MIN_CREATION_DIST + CREATION_RANGE),
@@ -461,20 +404,6 @@ CPopulation::GeneratePedsAtStartOfGame()
}
}
-bool
-CPopulation::IsPointInSafeZone(CVector *coors)
-{
- for (int i = 0; i < ARRAY_SIZE(aSafeZones); i++) {
- if (coors->x > aSafeZones[i].x1 && coors->x < aSafeZones[i].x2) {
- if (coors->y > aSafeZones[i].y1 && coors->y < aSafeZones[i].y2) {
- if (coors->z > aSafeZones[i].z1 && coors->z < aSafeZones[i].z2)
- return true;
- }
- }
- }
- return false;
-}
-
// More speed = wider area to spawn peds
float
CPopulation::PedCreationDistMultiplier()
@@ -488,7 +417,7 @@ CPopulation::PedCreationDistMultiplier()
}
CPed*
-CPopulation::AddPed(ePedType pedType, uint32 miOrCopType, CVector const &coors)
+CPopulation::AddPed(ePedType pedType, uint32 miOrCopType, CVector const &coors, int32 modifier)
{
switch (pedType) {
case PEDTYPE_CIVMALE:
@@ -499,16 +428,34 @@ CPopulation::AddPed(ePedType pedType, uint32 miOrCopType, CVector const &coors)
ped->SetOrientation(0.0f, 0.0f, 0.0f);
CWorld::Add(ped);
if (ms_bGivePedsWeapons) {
- eWeaponType weapon = (eWeaponType)CGeneral::GetRandomNumberInRange(WEAPONTYPE_UNARMED, WEAPONTYPE_DETONATOR);
+ eWeaponType weapon;
+
+ switch (CGeneral::GetRandomNumber() & 3) {
+ case 0:
+ weapon = WEAPONTYPE_COLT45;
+ break;
+ case 1:
+ weapon = WEAPONTYPE_NIGHTSTICK;
+ break;
+ case 2:
+ weapon = WEAPONTYPE_GOLFCLUB;
+ break;
+ case 3:
+ weapon = WEAPONTYPE_TEC9;
+ break;
+ default:
+ break;
+ }
if (weapon != WEAPONTYPE_UNARMED) {
- ped->SetCurrentWeapon(ped->GiveWeapon(weapon, 25001));
+ ped->GiveDelayedWeapon(weapon, 25001);
+ ped->SetCurrentWeapon(CWeaponInfo::GetWeaponInfo(weapon)->m_nWeaponSlot);
}
}
return ped;
}
case PEDTYPE_COP:
{
- CCopPed *ped = new CCopPed((eCopType)miOrCopType);
+ CCopPed *ped = new CCopPed((eCopType)miOrCopType, modifier);
ped->SetPosition(coors);
ped->SetOrientation(0.0f, 0.0f, 0.0f);
CWorld::Add(ped);
@@ -529,12 +476,14 @@ CPopulation::AddPed(ePedType pedType, uint32 miOrCopType, CVector const &coors)
ped->SetOrientation(0.0f, 0.0f, 0.0f);
CWorld::Add(ped);
- uint32 weapon;
+ eWeaponType weapon;
if (CGeneral::GetRandomNumberInRange(0, 100) >= 50)
- weapon = ped->GiveWeapon((eWeaponType)CGangs::GetGangInfo(pedType - PEDTYPE_GANG1)->m_Weapon2, 25001);
+ weapon = (eWeaponType)CGangs::GetGangInfo(pedType - PEDTYPE_GANG1)->m_Weapon2;
else
- weapon = ped->GiveWeapon((eWeaponType)CGangs::GetGangInfo(pedType - PEDTYPE_GANG1)->m_Weapon1, 25001);
- ped->SetCurrentWeapon(weapon);
+ weapon = (eWeaponType)CGangs::GetGangInfo(pedType - PEDTYPE_GANG1)->m_Weapon1;
+
+ ped->GiveDelayedWeapon(weapon, 25001);
+ ped->SetCurrentWeapon(CWeaponInfo::GetWeaponInfo(weapon)->m_nWeaponSlot);
return ped;
}
case PEDTYPE_EMERGENCY:
@@ -576,68 +525,97 @@ CPopulation::AddToPopulation(float minDist, float maxDist, float minDistOffScree
int pedAmount;
CZoneInfo zoneInfo;
+ int32 man = -1, woman = -1;
CPed *gangLeader = nil;
bool addCop = false;
+ bool isSecurityGuard = false;
+ bool forceAddingCop = false;
CPlayerInfo *playerInfo = &CWorld::Players[CWorld::PlayerInFocus];
CVector playerCentreOfWorld = FindPlayerCentreOfWorld(CWorld::PlayerInFocus);
CTheZones::GetZoneInfoForTimeOfDay(&playerCentreOfWorld, &zoneInfo);
CWanted *wantedInfo = playerInfo->m_pPed->m_pWanted;
+
if (wantedInfo->GetWantedLevel() > 2) {
- if (ms_nNumCop < wantedInfo->m_MaxCops && !playerInfo->m_pPed->bInVehicle
- && (CCarCtrl::NumLawEnforcerCars >= wantedInfo->m_MaximumLawEnforcerVehicles
+ if (!CGame::IsInInterior() && (CGeneral::GetRandomNumber() % 32 == 0) && FindPlayerVehicle())
+ forceAddingCop = true;
+
+ uint32 maxCops = CGame::IsInInterior() ? wantedInfo->m_MaxCops * 1.6f : wantedInfo->m_MaxCops;
+ if ((ms_nNumCop < maxCops || forceAddingCop) &&
+ (!playerInfo->m_pPed->bInVehicle &&
+ (CCarCtrl::NumLawEnforcerCars >= wantedInfo->m_MaximumLawEnforcerVehicles
|| CCarCtrl::NumRandomCars >= playerInfo->m_nTrafficMultiplier * CCarCtrl::CarDensityMultiplier
|| CCarCtrl::NumFiretrucksOnDuty + CCarCtrl::NumAmbulancesOnDuty + CCarCtrl::NumParkedCars
- + CCarCtrl::NumMissionCars + CCarCtrl::NumLawEnforcerCars + CCarCtrl::NumRandomCars >= CCarCtrl::MaxNumberOfCarsInUse)) {
+ + CCarCtrl::NumMissionCars + CCarCtrl::NumLawEnforcerCars + CCarCtrl::NumRandomCars >= CCarCtrl::MaxNumberOfCarsInUse) || forceAddingCop)) {
addCop = true;
minDist = PedCreationDistMultiplier() * MIN_CREATION_DIST;
maxDist = PedCreationDistMultiplier() * (MIN_CREATION_DIST + CREATION_RANGE);
}
}
+ float missionAndWeatherMult = -0.8f * Sqrt(CWeather::Rain) + 1.0f;
+
+ // Taxi side mission
+ if (CTheScripts::IsPlayerOnAMission()) {
+ CPed *player = FindPlayerPed();
+ if (player && player->InVehicle() && player->m_pMyVehicle->IsTaxi())
+ missionAndWeatherMult = 1.0f;
+ }
+ if (CDarkel::FrenzyOnGoing())
+ missionAndWeatherMult = 1.0f;
+ int selectedMaxPeds = CGame::IsInInterior() ? CPopulation::MaxNumberOfPedsInUseInterior : CPopulation::MaxNumberOfPedsInUse;
+
// Yeah, float
- float maxPossiblePedsForArea = (zoneInfo.pedDensity + zoneInfo.carDensity) * playerInfo->m_fRoadDensity * PedDensityMultiplier * CIniFile::PedNumberMultiplier;
- maxPossiblePedsForArea = Min(maxPossiblePedsForArea, MaxNumberOfPedsInUse);
+ float maxPossiblePedsForArea = (zoneInfo.pedDensity + zoneInfo.carDensity) * playerInfo->m_fRoadDensity * PedDensityMultiplier
+ * (CDarkel::FrenzyOnGoing() ? 1.f : CIniFile::PedNumberMultiplier) * missionAndWeatherMult;
+ maxPossiblePedsForArea = Min(maxPossiblePedsForArea, selectedMaxPeds);
if (ms_nTotalPeds < maxPossiblePedsForArea || addCop) {
int decisionThreshold = CGeneral::GetRandomNumberInRange(0, 1000);
- if (decisionThreshold < zoneInfo.copDensity || addCop) {
+ if (decisionThreshold < zoneInfo.copPedThreshold || addCop) {
pedTypeToAdd = PEDTYPE_COP;
modelToAdd = ChoosePolicePedOccupation();
} else {
- int16 density = zoneInfo.copDensity;
- for (int i = 0; i < NUM_GANGS; i++) {
- density += zoneInfo.gangDensity[i];
- if (decisionThreshold < density) {
- pedTypeToAdd = PEDTYPE_GANG1 + i;
+ int i = 0;
+ for (i = 0; i < NUM_GANGS; i++) {
+ if (decisionThreshold < zoneInfo.gangPedThreshold[i]) {
break;
}
+ }
- if (i == NUM_GANGS - 1) {
+ if (i == NUM_GANGS) {
+ if (CGeneral::GetRandomNumberInRange(0.0f, 1.0f) <= 0.95f) {
modelToAdd = ChooseCivilianOccupation(zoneInfo.pedGroup);
+
if (modelToAdd == -1)
return;
pedTypeToAdd = ((CPedModelInfo*)CModelInfo::GetModelInfo(modelToAdd))->m_pedType;
+
+ } else {
+ ChooseCivilianCoupleOccupations(zoneInfo.pedGroup, man, woman);
+ if (man == -1 || woman == -1)
+ return;
+ pedTypeToAdd = ((CPedModelInfo*)CModelInfo::GetModelInfo(woman))->m_pedType;
}
+ } else {
+ pedTypeToAdd = PEDTYPE_GANG1 + i;
+
+ if (IsSecurityGuard((ePedType)pedTypeToAdd)) {
+ isSecurityGuard = true;
+ modelToAdd = ChooseGangOccupation(pedTypeToAdd - PEDTYPE_GANG1);
+
+ if (modelToAdd == -1)
+ return;
+ pedTypeToAdd = ((CPedModelInfo*)CModelInfo::GetModelInfo(modelToAdd))->m_pedType;
+ }
}
}
if (!addCop && m_AllRandomPedsThisType > PEDTYPE_PLAYER1)
pedTypeToAdd = m_AllRandomPedsThisType;
- if (pedTypeToAdd >= PEDTYPE_GANG1 && pedTypeToAdd <= PEDTYPE_GANG9) {
- int randVal = CGeneral::GetRandomNumber() % 100;
- if (randVal < 50)
- return;
-
- if (randVal < 57) {
- pedAmount = 1;
- } else if (randVal >= 74) {
- if (randVal >= 85)
- pedAmount = 4;
- else
- pedAmount = 3;
- } else {
- pedAmount = 2;
- }
+ if (pedTypeToAdd >= PEDTYPE_GANG1 && pedTypeToAdd <= PEDTYPE_GANG9 && !isSecurityGuard) {
+ minDist += 30.0f;
+ maxDist += 30.0f;
+ pedAmount = ComputeRandomisedGangSize();
} else
pedAmount = 1;
@@ -650,35 +628,59 @@ CPopulation::AddToPopulation(float minDist, float maxDist, float minDistOffScree
if (!foundCoors)
return;
+ uint8 nodeSpawnRate = Min(ThePaths.m_pathNodes[node1].spawnRate, ThePaths.m_pathNodes[node2].spawnRate);
+ int randomRate = CGeneral::GetRandomNumber() & 0xF;
+ if (randomRate > nodeSpawnRate)
+ return;
+
+ CPathFind::TakeWidthIntoAccountForCoors(&ThePaths.m_pathNodes[node1], &ThePaths.m_pathNodes[node2], CGeneral::GetRandomNumber(), &generatedCoors.x, &generatedCoors.y);
+ if (CGame::currArea == AREA_MALL && (pedTypeToAdd == PEDTYPE_CIVMALE || pedTypeToAdd == PEDTYPE_CIVFEMALE || pedTypeToAdd == PEDTYPE_CRIMINAL) &&
+ CGeneral::GetRandomNumberInRange(0.f, 1.f) > 0.5f) {
+
+ PlaceMallPedsAsStationaryGroup(generatedCoors, zoneInfo.pedGroup);
+ return;
+ }
+
+ if (pedTypeToAdd >= PEDTYPE_GANG1 && pedTypeToAdd <= PEDTYPE_GANG9 && !isSecurityGuard) {
+ PlaceGangMembers((ePedType)pedTypeToAdd, pedAmount, generatedCoors);
+ return;
+ }
+
+ if (man > -1 && woman > -1) {
+ PlaceCouple(PEDTYPE_CIVMALE, man, PEDTYPE_CIVFEMALE, woman, generatedCoors);
+ return;
+ }
+
for (int i = 0; i < pedAmount; ++i) {
- if (pedTypeToAdd >= PEDTYPE_GANG1 && pedTypeToAdd <= PEDTYPE_GANG9)
- modelToAdd = ChooseGangOccupation(pedTypeToAdd - PEDTYPE_GANG1);
if (pedTypeToAdd == PEDTYPE_COP) {
// Unused code, ChoosePolicePedOccupation returns COP_STREET. Spawning FBI/SWAT/Army done in somewhere else.
if (modelToAdd == COP_STREET) {
- if (!CModelInfo::GetModelInfo(MI_COP)->GetRwObject())
+ if (!CStreaming::HasModelLoaded(MI_COP))
return;
} else if (modelToAdd == COP_FBI) {
- if (!CModelInfo::GetModelInfo(MI_FBI)->GetRwObject())
+ if (!CStreaming::HasModelLoaded(MI_COP) || !CStreaming::HasModelLoaded(CWeaponInfo::GetWeaponInfo(WEAPONTYPE_MP5)->m_nModelId))
return;
} else if (modelToAdd == COP_SWAT) {
- if (!CModelInfo::GetModelInfo(MI_SWAT)->GetRwObject())
+ if (!CStreaming::HasModelLoaded(MI_SWAT) || !CStreaming::HasModelLoaded(CWeaponInfo::GetWeaponInfo(WEAPONTYPE_UZI)->m_nModelId))
return;
- } else if (modelToAdd == COP_ARMY && !CModelInfo::GetModelInfo(MI_ARMY)->GetRwObject()) {
- return;
+ } else if (modelToAdd == COP_ARMY) {
+ if (!CStreaming::HasModelLoaded(MI_ARMY) ||
+ !CStreaming::HasModelLoaded(CWeaponInfo::GetWeaponInfo(WEAPONTYPE_MP5)->m_nModelId) || !CStreaming::HasModelLoaded(CWeaponInfo::GetWeaponInfo(WEAPONTYPE_GRENADE)->m_nModelId))
+ return;
}
- } else if (!CModelInfo::GetModelInfo(modelToAdd)->GetRwObject()) {
+ } else if (!CStreaming::HasModelLoaded(modelToAdd)) {
return;
}
generatedCoors.z += 0.7f;
// What? How can this not be met?
if (i < pedAmount) {
- //rand()
+ // rand()
+ // III leftover, unused
if (gangLeader) {
// Align gang members in formation. (btw i can't be 0 in here)
float offsetMin = i * 0.75f;
@@ -693,7 +695,7 @@ CPopulation::AddToPopulation(float minDist, float maxDist, float minDistOffScree
generatedCoors.y = yOffset + gangLeader->GetPosition().y;
}
}
- if (!CPedPlacement::IsPositionClearForPed(&generatedCoors))
+ if (!CPedPlacement::IsPositionClearForPed(generatedCoors))
break;
// Why no love for last gang member?!
@@ -705,28 +707,81 @@ CPopulation::AddToPopulation(float minDist, float maxDist, float minDistOffScree
generatedCoors.z = Max(generatedCoors.z, groundZ);
}
- bool farEnoughToAdd = true;
+ bool surfaceAndDistIsOk = true;
if (TheCamera.IsSphereVisible(generatedCoors, 2.0f)) {
if (PedCreationDistMultiplier() * MIN_CREATION_DIST > (generatedCoors - playerCentreOfWorld).Magnitude2D())
- farEnoughToAdd = false;
+ surfaceAndDistIsOk = false;
+ }
+
+ // Place skaters if only they're on tarmac.
+ if (((CPedModelInfo*)CModelInfo::GetModelInfo(modelToAdd))->m_pedStatType == PEDSTAT_SKATER) {
+ CEntity* foundEnt = nil;
+ CColPoint foundCol;
+ CWorld::ProcessVerticalLine(generatedCoors + CVector(0.f, 0.f, 2.f), generatedCoors.z - 2.0f, foundCol, foundEnt, true, false, false, false, false, false, nil);
+ if (foundEnt) {
+ if (foundCol.surfaceB == SURFACE_TARMAC || foundCol.surfaceB == SURFACE_PAVEMENT)
+ surfaceAndDistIsOk = true;
+ else
+ surfaceAndDistIsOk = false;
+
+ } else {
+ surfaceAndDistIsOk = false;
+ }
}
- if (!farEnoughToAdd)
+ if (!surfaceAndDistIsOk)
break;
CPed *newPed = AddPed((ePedType)pedTypeToAdd, modelToAdd, generatedCoors);
- newPed->SetWanderPath(CGeneral::GetRandomNumberInRange(0, 8));
-
+ if (forceAddingCop && newPed->m_nPedType == PEDTYPE_COP)
+ ((CCopPed*)newPed)->m_bThrowsSpikeTrap = true;
+
+ bool gonnaSunbathe = false;
+ if (CPopulation::IsSunbather(modelToAdd)) {
+ CEntity* foundEnt = nil;
+ CColPoint foundCol;
+ CWorld::ProcessVerticalLine(generatedCoors + CVector(0.f, 0.f, 2.f), generatedCoors.z - 2.0f, foundCol, foundEnt, true, false, false, false, false, false, nil);
+ if (foundEnt) {
+ if ((foundCol.surfaceB == SURFACE_CONCRETE_BEACH || foundCol.surfaceB == SURFACE_SAND)
+ && CClock::GetHours() >= 10 && CClock::GetHours() <= 18 && 0.0f == CWeather::Rain) {
+ gonnaSunbathe = true;
+ if (CPedPlacement::IsPositionClearForPed(generatedCoors, 3.0f, ARRAY_SIZE(gSunbatheObstacles), gSunbatheObstacles)) {
+ for (int j = 0; j < ARRAY_SIZE(gSunbatheObstacles); j++) {
+ if (gSunbatheObstacles[j] && gSunbatheObstacles[j] != newPed)
+ gonnaSunbathe = false;
+ }
+ }
+ }
+ }
+ }
+ if (gonnaSunbathe) {
+ float heading = CGeneral::GetRandomNumberInRange(0.f, 1.f) * TWOPI;
+ newPed->m_fRotationDest = heading;
+ newPed->m_fRotationCur = heading;
+ // unused
+ // v61 = CGeneral::GetRandomTrueFalse();
+ newPed->SetWaitState(WAITSTATE_SUN_BATHE_IDLE, nil);
+ CVector toyPos(newPed->GetPosition());
+ float waterLevel;
+ if (CWaterLevel::GetGroundLevel(toyPos, &waterLevel, nil, 30.0f)) {
+ toyPos.z = 0.04f + waterLevel;
+ CEntity *toy = CWaterLevel::CreateBeachToy(toyPos, BEACHTOY_ANY_TOWEL);
+ if (toy)
+ toy->SetHeading(heading);
+
+ if (!(CGeneral::GetRandomNumber() & 3)) {
+ CWaterLevel::CreateBeachToy(toyPos + CVector(CGeneral::GetRandomNumberInRange(-2.f, 2.f), CGeneral::GetRandomNumberInRange(-2.f, 2.f), 0.f), BEACHTOY_LOTION);
+ }
+ }
+ } else {
+ newPed->SetWanderPath(CGeneral::GetRandomNumberInRange(0, 8));
+ }
+
if (i != 0) {
// Gang member
newPed->SetLeader(gangLeader);
-#if !defined(FIX_BUGS) && GTA_VERSION >= GTA3_PC_10
- // seems to be a miami leftover (this code is not on PS2) but gang peds end up just being frozen
+
newPed->SetPedState(PED_UNKNOWN);
gangLeader->SetPedState(PED_UNKNOWN);
- newPed->m_fRotationCur = CGeneral::GetRadianAngleBetweenPoints(
- gangLeader->GetPosition().x, gangLeader->GetPosition().y,
- newPed->GetPosition().x, newPed->GetPosition().y);
- newPed->m_fRotationDest = newPed->m_fRotationCur;
-#endif
+
} else {
gangLeader = newPed;
}
@@ -742,9 +797,10 @@ CPopulation::AddToPopulation(float minDist, float maxDist, float minDistOffScree
}
CPed*
-CPopulation::AddPedInCar(CVehicle* car)
+CPopulation::AddPedInCar(CVehicle* car, bool isDriver)
{
- int defaultModel = MI_MALE01;
+ const int defaultModel = MI_MALE01;
+ int miamiViceIndex = 0;
bool imSureThatModelIsLoaded = true;
CVector coors = FindPlayerCoors();
CZoneInfo zoneInfo;
@@ -763,11 +819,8 @@ CPopulation::AddPedInCar(CVehicle* car)
preferredModel = 0;
pedType = PEDTYPE_EMERGENCY;
break;
- case MI_FBICAR:
- preferredModel = COP_FBI;
- pedType = PEDTYPE_COP;
- break;
case MI_POLICE:
+ case MI_PREDATOR:
preferredModel = COP_STREET;
pedType = PEDTYPE_COP;
break;
@@ -780,18 +833,28 @@ CPopulation::AddPedInCar(CVehicle* car)
preferredModel = COP_ARMY;
pedType = PEDTYPE_COP;
break;
- case MI_TAXI:
- case MI_CABBIE:
- case MI_BORGNINE:
- if (CGeneral::GetRandomTrueFalse()) {
- pedType = PEDTYPE_CIVMALE;
- preferredModel = MI_TAXI_D;
- break;
+ case MI_FBIRANCH:
+ preferredModel = COP_FBI;
+ pedType = PEDTYPE_COP;
+ break;
+ default:
+ if (car->IsTaxi()) {
+ if (isDriver) {
+ pedType = PEDTYPE_CIVMALE;
+ preferredModel = MI_TAXI_D;
+ break;
+ }
+ // fall through if not
+ } else if (car->GetModelIndex() == MI_VICECHEE) {
+ if (car->bIsLawEnforcer) {
+ preferredModel = COP_MIAMIVICE;
+ pedType = PEDTYPE_COP;
+ miamiViceIndex = (isDriver ? 2 * CCarCtrl::MiamiViceCycle : 2 * CCarCtrl::MiamiViceCycle + 1);
+ break;
+ }
+ // fall through if not
}
- defaultModel = MI_TAXI_D;
- // fall through
- default:
int gangOfPed = 0;
imSureThatModelIsLoaded = false;
@@ -802,16 +865,20 @@ CPopulation::AddPedInCar(CVehicle* car)
pedType = gangOfPed + PEDTYPE_GANG1;
preferredModel = ChooseGangOccupation(gangOfPed);
} else if (gangOfPed == NUM_GANGS) {
- CVehicleModelInfo *carModelInfo = ((CVehicleModelInfo *)CModelInfo::GetModelInfo(car->GetModelIndex()));
+ CVehicleModelInfo *carModel = ((CVehicleModelInfo *)CModelInfo::GetModelInfo(car->GetModelIndex()));
+ preferredModel = ChooseCivilianOccupation(zoneInfo.pedGroup);
int i = 15;
for(; i >= 0; i--) {
- // Should return random model each time
- preferredModel = ChooseCivilianOccupation(zoneInfo.pedGroup);
- if (preferredModel == -1)
- preferredModel = defaultModel;
+ CPedModelInfo* pedModel = (CPedModelInfo*)CModelInfo::GetModelInfo(preferredModel);
- if (((CPedModelInfo*)CModelInfo::GetModelInfo(preferredModel))->m_carsCanDrive & (1 << carModelInfo->m_vehicleClass))
- break;
+ if (pedModel->GetRwObject()) {
+ if (!car->IsPassenger(preferredModel) && !car->IsDriver(preferredModel)) {
+ if (((CPedModelInfo*)CModelInfo::GetModelInfo(preferredModel))->m_carsCanDrive & (1 << carModel->m_vehicleClass))
+ break;
+ }
+ }
+
+ preferredModel = ChooseNextCivilianOccupation(zoneInfo.pedGroup);
}
if (i == -1)
preferredModel = defaultModel;
@@ -825,120 +892,20 @@ CPopulation::AddPedInCar(CVehicle* car)
pedType = ((CPedModelInfo*)CModelInfo::GetModelInfo(defaultModel))->m_pedType;
}
- CPed *newPed = CPopulation::AddPed((ePedType)pedType, preferredModel, car->GetPosition());
+ 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)->m_bikeSitAnimation, 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_STD_CAR_SIT, 100.0f);
- }
-#endif
-
- newPed->StopNonPartialAnims();
+ newPed->AddInCarAnims(car, isDriver);
return newPed;
}
void
CPopulation::MoveCarsAndPedsOutOfAbandonedZones()
{
- eLevelName level;
- int zone;
- int frame = CTimer::GetFrameCounter() & 7;
- if (frame == 1) {
- int movedVehicleCount = 0;
- int poolSize = CPools::GetVehiclePool()->GetSize();
- for (int poolIndex = poolSize - 1; poolIndex >= 0; poolIndex--) {
-
- CVehicle* veh = CPools::GetVehiclePool()->GetSlot(poolIndex);
- if (veh && veh->m_nZoneLevel == LEVEL_GENERIC && veh->IsCar()) {
-
- if(veh->GetStatus() != STATUS_ABANDONED && veh->GetStatus() != STATUS_WRECKED && veh->GetStatus() != STATUS_PLAYER &&
- veh->GetStatus() != STATUS_PLAYER_REMOTE) {
-
- CVector vehPos(veh->GetPosition());
- CPopulation::FindCollisionZoneForCoors(&vehPos, &zone, &level);
-
- // Level 0 is transition zones, and we don't wanna touch cars on transition zones.
- if (level != LEVEL_GENERIC && level != CCollision::ms_collisionInMemory && vehPos.z > -4.0f) {
- if (veh->bIsLocked || !veh->CanBeDeleted()) {
- switch (movedVehicleCount & 3) {
- case 0:
- veh->SetPosition(RegenerationPoint_a);
- break;
- case 1:
- veh->SetPosition(RegenerationPoint_b);
- break;
- case 2:
- veh->SetPosition(RegenerationPoint_a.x, RegenerationPoint_b.y, RegenerationPoint_a.z);
- break;
- case 3:
- veh->SetPosition(RegenerationPoint_b.x, RegenerationPoint_a.y, RegenerationPoint_a.z);
- break;
- default:
- break;
- }
- veh->GetMatrix().GetPosition().z += (movedVehicleCount / 4) * 7.0f;
- veh->GetMatrix().GetForward() = RegenerationFront;
- ((CAutomobile*)veh)->PlaceOnRoadProperly();
- CCarCtrl::JoinCarWithRoadSystem(veh);
- CTheScripts::ClearSpaceForMissionEntity(veh->GetPosition(), veh);
- ++movedVehicleCount;
- } else {
- CWorld::Remove(veh);
- delete veh;
- }
- }
- }
- }
- }
- } else if (frame == 5) {
- int poolSize = CPools::GetPedPool()->GetSize();
- for (int poolIndex = poolSize - 1; poolIndex >= 0; poolIndex--) {
-
- CPed *ped = CPools::GetPedPool()->GetSlot(poolIndex);
- if (ped && ped->m_nZoneLevel == LEVEL_GENERIC && !ped->bInVehicle) {
-
- CVector pedPos(ped->GetPosition());
- CPopulation::FindCollisionZoneForCoors(&pedPos, &zone, &level);
-
- // Level 0 is transition zones, and we don't wanna touch peds on transition zones.
- if (level != LEVEL_GENERIC && level != CCollision::ms_collisionInMemory && pedPos.z > -4.0f) {
- if (ped->CanBeDeleted()) {
- CWorld::Remove(ped);
- delete ped;
- } else if (ped->m_nPedType != PEDTYPE_PLAYER1 && ped->m_nPedType != PEDTYPE_PLAYER2) {
- ped->SetPosition(RegenerationPoint_a);
-
- bool foundGround;
- float groundZ = CWorld::FindGroundZFor3DCoord(ped->GetPosition().x, ped->GetPosition().y,
- ped->GetPosition().z + 2.0f, &foundGround);
-
- if (foundGround) {
- ped->GetMatrix().GetPosition().z = 1.0f + groundZ;
- //ped->GetPosition().z += 0.0f;
- CTheScripts::ClearSpaceForMissionEntity(ped->GetPosition(), ped);
- }
- }
- }
- }
- }
- }
}
void
@@ -968,7 +935,8 @@ CPopulation::ConvertToRealObject(CDummyObject *dummy)
delete dummy;
CWorld::Add(obj);
- if (IsGlass(obj->GetModelIndex())) {
+ CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(obj->GetModelIndex());
+ if (IsGlass(obj->GetModelIndex()) && !mi->m_isArtistGlass) {
obj->bIsVisible = false;
} else if (obj->GetModelIndex() == MI_BUOY) {
obj->SetIsStatic(false);
@@ -987,7 +955,8 @@ CPopulation::ConvertToDummyObject(CObject *obj)
dummy->GetMatrix().UpdateRW();
dummy->UpdateRwFrame();
- if (IsGlass(obj->GetModelIndex()))
+ CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(obj->GetModelIndex());
+ if (IsGlass(obj->GetModelIndex()) && !mi->m_isArtistGlass)
dummy->bIsVisible = false;
CWorld::Remove(obj);
@@ -999,7 +968,7 @@ bool
CPopulation::TestRoomForDummyObject(CObject *obj)
{
int16 collidingObjs;
- CWorld::FindObjectsKindaColliding(obj->m_objectMatrix.GetPosition(), CModelInfo::GetColModel(obj->GetModelIndex())->boundingSphere.radius,
+ CWorld::FindObjectsKindaColliding(obj->m_objectMatrix.GetPosition(), obj->GetBoundRadius(),
false, &collidingObjs, 2, nil, false, true, true, false, false);
return collidingObjs == 0;
@@ -1077,17 +1046,20 @@ CPopulation::ManagePopulation(void)
for (int i = objectPoolSize * frameMod32 / 32; i < objectPoolSize * (frameMod32 + 1) / 32; i++) {
CObject *obj = CPools::GetObjectPool()->GetSlot(i);
if (obj && obj->CanBeDeleted()) {
- if ((obj->GetPosition() - playerPos).Magnitude() <= 80.0f ||
- (obj->m_objectMatrix.GetPosition() - playerPos).Magnitude() <= 80.0f) {
- if (obj->ObjectCreatedBy == TEMP_OBJECT && CTimer::GetTimeInMilliseconds() > obj->m_nEndOfLifeTime) {
+ float objPlayerDist = (obj->GetPosition() - playerPos).Magnitude();
+ if (obj->ObjectCreatedBy == TEMP_OBJECT) {
+ if (obj->GetModelIndex() != MI_ROADWORKBARRIER1 && obj->GetModelIndex() != MI_BEACHBALL) {
+ if (objPlayerDist > 51.0f || objPlayerDist > 25.0f && !obj->GetIsOnScreen() || CTimer::GetTimeInMilliseconds() > obj->m_nEndOfLifeTime) {
+ CWorld::Remove(obj);
+ delete obj;
+ }
+ } else if (objPlayerDist > 120.0f) {
CWorld::Remove(obj);
delete obj;
}
- } else {
- if (obj->ObjectCreatedBy == TEMP_OBJECT) {
- CWorld::Remove(obj);
- delete obj;
- } else if (obj->ObjectCreatedBy != CUTSCENE_OBJECT && TestRoomForDummyObject(obj)) {
+
+ } else if (objPlayerDist > 80.0f && (obj->m_objectMatrix.GetPosition() - playerPos).Magnitude() > 80.0f) {
+ if (obj->ObjectCreatedBy != CUTSCENE_OBJECT && TestRoomForDummyObject(obj)) {
ConvertToDummyObject(obj);
}
}
@@ -1098,7 +1070,7 @@ CPopulation::ManagePopulation(void)
int dummyPoolSize = CPools::GetDummyPool()->GetSize();
for (int i = dummyPoolSize * frameMod32 / 32; i < dummyPoolSize * (frameMod32 + 1) / 32; i++) {
CDummy *dummy = CPools::GetDummyPool()->GetSlot(i);
- if (dummy) {
+ if (dummy && (dummy->m_area == CGame::currArea || dummy->m_area == AREA_EVERYWHERE)) {
if ((dummy->GetPosition() - playerPos).Magnitude() < 80.0f)
ConvertToRealObject((CDummyObject*)dummy);
}
@@ -1113,7 +1085,8 @@ CPopulation::ManagePopulation(void)
CPed *ped = CPools::GetPedPool()->GetSlot(poolIndex);
if (ped && !ped->IsPlayer() && ped->CanBeDeleted() && !ped->bInVehicle) {
- if (ped->m_nPedState == PED_DEAD && CTimer::GetTimeInMilliseconds() - ped->m_bloodyFootprintCountOrDeathTime > 60000)
+ uint32 timeSinceDeath = CTimer::GetTimeInMilliseconds() - ped->m_bloodyFootprintCountOrDeathTime;
+ if (ped->m_nPedState == PED_DEAD && (timeSinceDeath > 30000 || CDarkel::FrenzyOnGoing() && timeSinceDeath > 15000))
ped->bFadeOut = true;
if (ped->bFadeOut && CVisibilityPlugins::GetClumpAlpha(ped->GetClump()) == 0) {
@@ -1124,19 +1097,34 @@ CPopulation::ManagePopulation(void)
float dist = (ped->GetPosition() - playerPos).Magnitude2D();
bool pedIsFarAway = false;
- if (PedCreationDistMultiplier() * (PED_REMOVE_DIST_SPECIAL * TheCamera.GenerationDistMultiplier) < dist
- || (!ped->bCullExtraFarAway && PedCreationDistMultiplier() * PED_REMOVE_DIST * TheCamera.GenerationDistMultiplier < dist)
+
+ if (ped->IsGangMember())
+ dist -= 30.0f;
+ else if (ped->bDeadPedInFrontOfCar && ped->m_vehicleInAccident)
+ dist = 0.0f;
+
+ if (PedCreationDistMultiplier() * (PED_REMOVE_DIST_SPECIAL * TheCamera.GenerationDistMultiplier) < dist ||
+ (!ped->bCullExtraFarAway && PedCreationDistMultiplier() * PED_REMOVE_DIST * TheCamera.GenerationDistMultiplier < dist)) {
+ pedIsFarAway = true;
+ }
#ifndef EXTENDED_OFFSCREEN_DESPAWN_RANGE
- || (PedCreationDistMultiplier() * (MIN_CREATION_DIST + CREATION_RANGE) * OFFSCREEN_CREATION_MULT < dist
- && !ped->GetIsOnScreen()
- && TheCamera.Cams[TheCamera.ActiveCam].Mode != CCam::MODE_SNIPER
- && TheCamera.Cams[TheCamera.ActiveCam].Mode != CCam::MODE_SNIPER_RUNABOUT
- && !TheCamera.Cams[TheCamera.ActiveCam].LookingLeft
- && !TheCamera.Cams[TheCamera.ActiveCam].LookingRight
- && !TheCamera.Cams[TheCamera.ActiveCam].LookingBehind)
+ else if (PedCreationDistMultiplier() * (MIN_CREATION_DIST + CREATION_RANGE) * OFFSCREEN_CREATION_MULT < dist) {
+ if (CTimer::GetTimeInMilliseconds() > ped->m_nExtendedRangeTimer && !ped->GetIsOnScreen()) {
+ if (TheCamera.Cams[TheCamera.ActiveCam].Mode != CCam::MODE_SNIPER
+ && TheCamera.Cams[TheCamera.ActiveCam].Mode != CCam::MODE_SNIPER_RUNABOUT
+ && TheCamera.Cams[TheCamera.ActiveCam].Mode != CCam::MODE_CAMERA
+ && !TheCamera.Cams[TheCamera.ActiveCam].LookingLeft
+ && !TheCamera.Cams[TheCamera.ActiveCam].LookingRight
+ && !TheCamera.Cams[TheCamera.ActiveCam].LookingBehind) {
+ pedIsFarAway = true;
+ }
+ }
+
+ }
#endif
- )
- pedIsFarAway = true;
+ else {
+ ped->m_nExtendedRangeTimer = ped->m_nPedType == PEDTYPE_COP ? CTimer::GetTimeInMilliseconds() + 10000 : CTimer::GetTimeInMilliseconds() + 4000;
+ }
if (!pedIsFarAway)
continue;
@@ -1172,3 +1160,656 @@ CPopulation::ManagePopulation(void)
}
}
}
+
+CPed*
+CPopulation::AddDeadPedInFrontOfCar(const CVector& pos, CVehicle* pCulprit)
+{
+ if (TheCamera.IsSphereVisible(pos, 2.0f) && MIN_CREATION_DIST * PedCreationDistMultiplier() > (pos - FindPlayerPed()->GetPosition()).Magnitude2D()) {
+ return nil;
+ }
+
+ bool found;
+ float z = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z, &found) + 1.0f;
+ if (!found)
+ return nil;
+ z = Max(z, pos.z);
+ if (!CModelInfo::GetModelInfo(MI_MALE01)->GetRwObject())
+ return nil;
+ CPed* pPed = CPopulation::AddPed(PEDTYPE_CIVMALE, MI_MALE01, pos);
+ pPed->SetDie();
+ pPed->m_nPedMoney = 0;
+ pPed->bDeadPedInFrontOfCar = true;
+ pPed->m_vehicleInAccident = pCulprit;
+ pCulprit->RegisterReference((CEntity**)&pPed->m_vehicleInAccident);
+ CEntity* pEntities[3] = { 0 };
+ if (!CPedPlacement::IsPositionClearForPed(pos, 2.0f, 3, pEntities)) {
+ for (int i = 0; i < 3; i++) {
+ if (pEntities[i] && pEntities[i] != pCulprit && pEntities[i] != pPed) {
+ RemovePed(pPed);
+ return nil;
+ }
+ }
+ }
+ CColPoint colpts[MAX_COLLISION_POINTS];
+ if (CCollision::ProcessColModels(pCulprit->GetMatrix(), *pCulprit->GetColModel(), pPed->GetMatrix(), *pPed->GetColModel(), colpts, nil, nil)) {
+ RemovePed(pPed);
+ return nil;
+ }
+ CVisibilityPlugins::SetClumpAlpha(pPed->GetClump(), 0);
+ return pPed;
+}
+
+bool
+CPopulation::IsSkateable(CVector const& pos)
+{
+ CColPoint foundCol;
+ CEntity* foundEnt = nil;
+ CWorld::ProcessVerticalLine(pos + CVector(0.f, 0.f, 2.f), pos.z - 2.0f, foundCol, foundEnt, true, false, false, false, false, false, nil);
+ if (!foundEnt)
+ return false;
+
+ return foundCol.surfaceB == SURFACE_TARMAC || foundCol.surfaceB == SURFACE_PAVEMENT;
+}
+
+bool
+CPopulation::CanJeerAtStripper(int32 model)
+{
+ return model == MI_WMOBE || model == MI_WMYBE || model == MI_WMOST || model == MI_BMYBB;
+}
+
+void
+CPopulation::RemovePedsIfThePoolGetsFull(void)
+{
+ if ((CTimer::GetFrameCounter() & 7) == 5) {
+ if (CPools::GetPedPool()->GetNoOfFreeSpaces() < 8) {
+ CPed *closestPed = nil;
+ float closestDist = 10000000.0;
+ int poolSize = CPools::GetPedPool()->GetSize();
+ for (int i = poolSize - 1; i >= 0; i--) {
+ CPed* ped = CPools::GetPedPool()->GetSlot(i);
+ if (ped && ped->CanBeDeleted()) {
+ float dist = (TheCamera.GetPosition() - ped->GetPosition()).Magnitude();
+ if (dist < closestDist) {
+ closestDist = dist;
+ closestPed = ped;
+ }
+ }
+ }
+ if (closestPed) {
+ RemovePed(closestPed);
+ }
+ }
+ }
+}
+
+bool
+CPopulation::IsMale(int32 model)
+{
+ switch (model) {
+ case MI_HMYST:
+ case MI_HMOST:
+ case MI_HMYRI:
+ case MI_HMORI:
+ case MI_HMYBE:
+ case MI_HMOBE:
+ case MI_HMOTR:
+ case MI_HMYAP:
+ case MI_HMOCA:
+ case MI_BMODK:
+ case MI_BMYKR:
+ case MI_BMYST:
+ case MI_BMOST:
+ case MI_BMYRI:
+ case MI_BMYBE:
+ case MI_BMOBE:
+ case MI_BMYBU:
+ case MI_BMOTR:
+ case MI_BMYPI:
+ case MI_BMYBB:
+ case MI_WMYCR:
+ case MI_WMYST:
+ case MI_WMOST:
+ case MI_WMYRI:
+ case MI_WMORI:
+ case MI_WMYBE:
+ case MI_WMOBE:
+ case MI_WMYCW:
+ case MI_WMYGO:
+ case MI_WMOGO:
+ case MI_WMYLG:
+ case MI_WMYBU:
+ case MI_WMOBU:
+ case MI_WMOTR:
+ case MI_WMYPI:
+ case MI_WMOCA:
+ case MI_WMYJG:
+ case MI_WMYSK:
+
+ // BUG? Why no JMOTO?
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool
+CPopulation::IsFemale(int32 model)
+{
+ switch (model) {
+ case MI_HFYST:
+ case MI_HFOST:
+ case MI_HFYRI:
+ case MI_HFORI:
+ case MI_HFYBE:
+ case MI_HFOBE:
+ case MI_HFYBU:
+ case MI_HFYMD:
+ case MI_HFYCG:
+ case MI_HFYPR:
+ case MI_HFOTR:
+ case MI_BFYST:
+ case MI_BFOST:
+ case MI_BFYRI:
+ case MI_BFORI:
+ case MI_BFYBE:
+ case MI_BFOBE:
+ case MI_BFYPR:
+ case MI_BFOTR:
+ case MI_WFYST:
+ case MI_WFOST:
+ case MI_WFYRI:
+ case MI_WFORI:
+ case MI_WFYBE:
+ case MI_WFOBE:
+ case MI_WFOGO:
+ case MI_WFYLG:
+ case MI_WFYBU:
+ case MI_WFYPR:
+ case MI_WFOTR:
+ case MI_WFYJG:
+ case MI_WFYSK:
+ case MI_WFYSH:
+ case MI_WFOSH:
+ case MI_JFOTO:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool
+CPopulation::IsSunbather(int32 model)
+{
+ switch (model) {
+ case MI_HFYBE:
+ case MI_HFOBE:
+ case MI_HMYBE:
+ case MI_HMOBE:
+ case MI_BFYBE:
+ case MI_BMYBE:
+ case MI_BFOBE:
+ case MI_BMOBE:
+ case MI_WFYBE:
+ case MI_WMYBE:
+ case MI_WFOBE:
+ case MI_WMOBE:
+ return true;
+ default:
+ return false;
+ }
+}
+
+int32
+CPopulation::ComputeRandomisedGangSize(void)
+{
+ return CGeneral::GetRandomNumberInRange(3, 6);
+}
+
+bool
+CPopulation::CanSolicitPlayerInCar(int32 model)
+{
+ return model == MI_HFYPR || model == MI_BFYPR || model == MI_WFYPR;
+}
+
+bool
+CPopulation::CanSolicitPlayerOnFoot(int32 model)
+{
+ return model == MI_HFYMD || model == MI_HFYCG || model == MI_BFOTR || model == MI_BMOTR || model == MI_WFOTR || model == MI_WMOTR;
+}
+
+bool
+CPopulation::IsSecurityGuard(ePedType pedType)
+{
+ return pedType == PEDTYPE_GANG5;
+}
+
+void
+CPopulation::ChooseCivilianCoupleOccupations(int32 group, int32& man, int32& woman)
+{
+ man = -1;
+ woman = -1;
+
+ for (int i = 0; i < 8; i++) {
+ if (man > -1)
+ break;
+
+ int32 model = ms_pPedGroups[group].models[CGeneral::GetRandomNumberInRange(0, NUMMODELSPERPEDGROUP)];
+ if (man == -1 && IsMale(model) && ((CPedModelInfo*)CModelInfo::GetModelInfo(model))->m_pedType == PEDTYPE_CIVMALE) {
+ man = model;
+ }
+ }
+
+ if (man != -1) {
+ int32 model;
+ for (int i = 0; i < NUMMODELSPERPEDGROUP; i++) {
+ model = ms_pPedGroups[group].models[i];
+ if (IsFemale(model)) {
+ CPedModelInfo* womanModelInfo = (CPedModelInfo*)CModelInfo::GetModelInfo(model);
+ if (womanModelInfo->m_pedType == PEDTYPE_CIVFEMALE) {
+ CPedModelInfo* manModelInfo = (CPedModelInfo*)CModelInfo::GetModelInfo(man);
+
+ // If both are skater or not, finalize the decision
+ if (manModelInfo && womanModelInfo) {
+ if (manModelInfo->m_animGroup == womanModelInfo->m_animGroup) {
+ if (manModelInfo->m_pedStatType != PEDSTAT_SKATER && womanModelInfo->m_pedStatType != PEDSTAT_SKATER)
+ break;
+
+ if (manModelInfo->m_pedStatType == PEDSTAT_SKATER && womanModelInfo->m_pedStatType == PEDSTAT_SKATER)
+ break;
+ }
+ }
+ }
+ }
+ }
+ woman = model;
+ }
+}
+
+void
+CPopulation::PlaceGangMembers(ePedType pedType, int pedAmount, CVector const& coors)
+{
+ if (CGeneral::GetRandomNumberInRange(0.f, 1.f) < 0.333f) {
+ PlaceGangMembersInFormation(pedType, pedAmount, coors);
+ } else {
+ PlaceGangMembersInCircle(pedType, pedAmount, coors);
+ }
+}
+
+void
+CPopulation::PlaceGangMembersInFormation(ePedType pedType, int pedAmount, CVector const& coors)
+{
+ CPed *createdPeds[5];
+
+ if (!TheCamera.IsSphereVisible(coors, 3.0f) || MIN_CREATION_DIST * PedCreationDistMultiplier() <= (coors - FindPlayerPed()->GetPosition()).Magnitude2D()) {
+ if (CPedPlacement::IsPositionClearForPed(coors, 3.0f, -1, nil)) {
+ bool leaderFoundGround;
+ float leaderGroundZ = CWorld::FindGroundZFor3DCoord(coors.x, coors.y, coors.z, &leaderFoundGround) + 1.0f;
+ if (leaderFoundGround) {
+ float finalZ = coors.z > leaderGroundZ ? coors.z : leaderGroundZ;
+ int leaderModel = ChooseGangOccupation(pedType - PEDTYPE_GANG1);
+ if (((CPedModelInfo*)CModelInfo::GetModelInfo(leaderModel))->GetRwObject()) {
+ CPed *leader = AddPed(pedType, leaderModel, CVector(coors.x, coors.y, finalZ));
+ if (leader) {
+ leader->SetObjective(OBJECTIVE_NONE);
+ leader->SetWanderPath(CGeneral::GetRandomNumberInRange(0, 8));
+ leader->bIsLeader = true;
+ if (CGangs::GetWillAttackPlayerWithCops(pedType))
+ leader->bCanAttackPlayerWithCops = true;
+
+ int pedIdx = 1;
+ createdPeds[0] = leader;
+ for (int i = 1; i < pedAmount; ++i) {
+ int memberModel = ChooseGangOccupation(pedType - PEDTYPE_GANG1);
+ if (!((CPedModelInfo*)CModelInfo::GetModelInfo(memberModel))->GetRwObject())
+ continue;
+
+ CPed* memberPed = AddPed(pedType, memberModel, CVector(coors.x, coors.y, finalZ));
+ if (!memberPed)
+ continue;
+
+ memberPed->SetObjective(OBJECTIVE_FOLLOW_CHAR_IN_FORMATION, leader);
+ memberPed->SetFormation((eFormation)i);
+ CVector formationPos = memberPed->GetFormationPosition();
+ CVector finalFormationPos = formationPos;
+ bool formationFoundGround;
+ float formationGroundZ = CWorld::FindGroundZFor3DCoord(formationPos.x, formationPos.y, 1.0f + formationPos.z, &formationFoundGround) + 1.0f;
+
+ finalFormationPos.z = Max(finalFormationPos.z, formationGroundZ);
+ if (formationFoundGround) {
+ if (Abs(finalFormationPos.z - leader->GetPosition().z) <= 1.0f) {
+ if (CWorld::GetIsLineOfSightClear(finalFormationPos, leader->GetPosition(), true, false, false, false, false, false, false)) {
+ memberPed->SetPosition(finalFormationPos);
+ createdPeds[pedIdx++] = memberPed;
+ if (CGangs::GetWillAttackPlayerWithCops(pedType))
+ leader->bCanAttackPlayerWithCops = true;
+
+ CVisibilityPlugins::SetClumpAlpha(memberPed->GetClump(), 0);
+ continue;
+ }
+ }
+ }
+ RemovePed(memberPed);
+ }
+ if (pedIdx >= 3) {
+ for (int j = 1; j < pedIdx; ++j)
+ createdPeds[j]->SetLeader(createdPeds[0]);
+
+ } else {
+ for (int k = 0; k < pedIdx; ++k) {
+ RemovePed(createdPeds[k]);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void
+CPopulation::PlaceGangMembersInCircle(ePedType pedType, int pedAmount, CVector const& coors)
+{
+ CPed *createdPeds[5];
+
+ if (pedAmount < 2)
+ return;
+
+ float circleSector = TWOPI / pedAmount;
+
+ float circleR = Sqrt(0.5f / (1.0f - Cos(circleSector)));
+
+ if (!TheCamera.IsSphereVisible(coors, circleR) ||
+ MIN_CREATION_DIST * PedCreationDistMultiplier() <= (coors - FindPlayerPed()->GetPosition()).Magnitude2D()) {
+
+ if (CPedPlacement::IsPositionClearForPed(coors, circleR, -1, nil)) {
+ int pedIdx = 0;
+ CVector leaderPos;
+#ifdef FIX_BUGS
+ bool createLeader = true;
+#endif
+
+ for (int i = 0; i < pedAmount; i++) {
+ float angleMult = i + CGeneral::GetRandomNumberInRange(-0.2f, 0.2f);
+ float randomR = circleR + CGeneral::GetRandomNumberInRange(-0.2f, 0.2f) * circleR;
+ float xOffset = randomR * Cos(angleMult * circleSector);
+ float yOffset = randomR * Sin(angleMult * circleSector);
+ bool foundGround;
+ float groundZ = CWorld::FindGroundZFor3DCoord(xOffset + coors.x, yOffset + coors.y, coors.z + 1.0, &foundGround) + 1.0f;
+ if (foundGround) {
+ CVector finalPos(coors.x + xOffset, coors.y + yOffset, coors.z > groundZ ? coors.z : groundZ);
+#ifndef FIX_BUGS
+ const bool createLeader = i == 0;
+#endif
+ if (createLeader)
+ leaderPos = finalPos;
+
+ int gangModel = ChooseGangOccupation(pedType - PEDTYPE_GANG1);
+ if (((CPedModelInfo*)CModelInfo::GetModelInfo(gangModel))->GetRwObject()) {
+ CEntity* obstacles[6] = { nil, nil, nil, nil, nil, nil };
+ CPedPlacement::IsPositionClearForPed(finalPos, CModelInfo::GetColModel(gangModel)->boundingSphere.radius, ARRAY_SIZE(obstacles), obstacles);
+ bool foundObstacle = false;
+ for (int m = 0; m < ARRAY_SIZE(obstacles); m++) {
+ CEntity* obstacle = obstacles[m];
+ if (obstacle) {
+ int n = 0;
+ bool obstacleIsHarmless = false;
+ for (int n = 0; n < pedIdx; n++) {
+ if (obstacle == createdPeds[n])
+ obstacleIsHarmless = true;
+ }
+ if (!obstacleIsHarmless) {
+ foundObstacle = true;
+ break;
+ }
+ }
+ }
+ bool memberCanSeeLeader = createLeader ? true : CWorld::GetIsLineOfSightClear(finalPos, leaderPos, true, false, false, false, false, false, false);
+
+ bool notTooHighFromLeader = createLeader ? true : !(Abs(finalPos.z - leaderPos.z) >= 1.0f);
+
+ if (!foundObstacle && memberCanSeeLeader && notTooHighFromLeader) {
+ CPed* newPed = AddPed(pedType, gangModel, finalPos);
+ if (newPed) {
+ createdPeds[pedIdx++] = newPed;
+ float angle = CGeneral::GetRadianAngleBetweenPoints(
+ coors.x, coors.y,
+ finalPos.x, finalPos.y);
+ newPed->m_fRotationDest = angle;
+ newPed->m_fRotationCur = angle;
+ if (CGangs::GetWillAttackPlayerWithCops(pedType))
+ newPed->bCanAttackPlayerWithCops = true;
+
+ CVisibilityPlugins::SetClumpAlpha(newPed->GetClump(), 0);
+#ifdef FIX_BUGS
+ createLeader = false;
+#endif
+ }
+ // No.
+#ifndef FIX_BUGS
+ else
+ CWorld::Remove(nil);
+#endif
+ }
+ }
+ }
+ }
+ if (pedIdx >= 3) {
+ for (int j = 0; j < pedIdx / 2; ++j) {
+ createdPeds[j]->SetChat(createdPeds[pedIdx - 1 - j], 100000);
+ createdPeds[pedIdx - 1 - j]->SetChat(createdPeds[j], 100000);
+ }
+
+ // Make that extra guy in the middle stand there(PED_UNKNOWN locks him) and do nothing :lmao:
+ if (pedIdx % 2 != 0) {
+ CPed *tmim = createdPeds[(pedIdx - 1) / 2];
+ float angle = CGeneral::GetRadianAngleBetweenPoints(
+ tmim->GetPosition().x, tmim->GetPosition().y,
+ createdPeds[0]->GetPosition().x, createdPeds[0]->GetPosition().y);
+ tmim->SetHeading(angle);
+ tmim->SetPedState(PED_UNKNOWN);
+ }
+ createdPeds[0]->bIsLeader = true;
+
+ for (int l = 1; l < pedIdx; ++l)
+ createdPeds[l]->SetLeader(createdPeds[0]);
+
+ } else {
+ for (int k = 0; k < pedIdx; ++k) {
+ RemovePed(createdPeds[k]);
+ }
+ }
+ }
+ }
+}
+
+void
+CPopulation::PlaceCouple(ePedType manType, int32 manModel, ePedType womanType, int32 womanModel, CVector coors)
+{
+ // Homosexuality filter!!!! Homophobic R* >>>:(
+ if (manType != PEDTYPE_CIVMALE || womanType != PEDTYPE_CIVFEMALE)
+ return;
+
+ if (!TheCamera.IsSphereVisible(coors, 1.5f) || MIN_CREATION_DIST * PedCreationDistMultiplier() <= (coors - FindPlayerPed()->GetPosition()).Magnitude2D()) {
+ if (CPedPlacement::IsPositionClearForPed(coors, CModelInfo::GetColModel(manModel)->boundingSphere.radius, -1, nil)) {
+ bool manFoundGround;
+ float manGroundZ = CWorld::FindGroundZFor3DCoord(coors.x, coors.y, coors.z, &manFoundGround) + 1.0f;
+ if (manFoundGround) {
+ CVector correctedManPos = coors;
+ correctedManPos.z = Max(coors.z, manGroundZ);
+ if (((CPedModelInfo*)CModelInfo::GetModelInfo(manModel))->GetRwObject()) {
+ CPed *man = AddPed(PEDTYPE_CIVMALE, manModel, correctedManPos);
+ if (man) {
+ man->SetObjective(OBJECTIVE_NONE);
+ man->SetWanderPath(CGeneral::GetRandomNumberInRange(0, 8));
+ man->bIsLeader = true;
+ CVisibilityPlugins::SetClumpAlpha(man->GetClump(), 0);
+
+ if (((CPedModelInfo*)CModelInfo::GetModelInfo(womanModel))->GetRwObject()) {
+ CPed* woman = AddPed(PEDTYPE_CIVFEMALE, womanModel, correctedManPos); // will set the correct position later
+ if (woman) {
+ woman->SetObjective(OBJECTIVE_FOLLOW_CHAR_IN_FORMATION, man);
+ woman->SetFormation(FORMATION_RIGHT);
+
+ CVector formationPos = woman->GetFormationPosition();
+ CVector womanPos = formationPos;
+ bool womanFoundGround;
+ float formationGroundZ = CWorld::FindGroundZFor3DCoord(formationPos.x, formationPos.y, 1.0f + formationPos.z, &womanFoundGround) + 1.0f;
+
+ if (womanFoundGround) {
+ CVector correctedWomanPos = womanPos;
+ correctedWomanPos.z = Max(womanPos.z, formationGroundZ);
+ woman->SetPosition(correctedWomanPos);
+
+ // What's the point of this??
+ CEntity* obstacles[3];
+ memcpy(obstacles, gCoupleObstacles, sizeof(gCoupleObstacles));
+
+ CPedPlacement::IsPositionClearForPed(womanPos, CModelInfo::GetColModel(womanModel)->boundingSphere.radius, ARRAY_SIZE(obstacles), obstacles);
+ for (int i = 0; i < ARRAY_SIZE(obstacles); i++) {
+ CEntity *obstacle = obstacles[i];
+ if (obstacle) {
+
+ // We found a real obstacle, so let's break and we can delete them...
+ if (obstacle != man && obstacle != woman)
+ break;
+ }
+ if (i == ARRAY_SIZE(obstacles) - 1) {
+ CVisibilityPlugins::SetClumpAlpha(woman->GetClump(), 0);
+ return;
+ }
+ }
+ }
+ RemovePed(woman);
+ RemovePed(man);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+// Mostly copy paste of PlaceGangMembersInFormation.
+void
+CPopulation::PlaceMallPedsAsStationaryGroup(CVector const& coors, int32 group)
+{
+#ifdef FIX_BUGS
+ CPed *createdPeds[6];
+#else
+ CPed *createdPeds[5];
+#endif
+
+ if (CGame::currArea != AREA_MALL)
+ return;
+
+ int pedAmount = CGeneral::GetRandomNumberInRange(0, 4) + 3;
+
+ float circleSector = TWOPI / pedAmount;
+
+ float circleR = Sqrt(0.5f / (1.0f - Cos(circleSector)));
+
+ if (!TheCamera.IsSphereVisible(coors, circleR) ||
+ MIN_CREATION_DIST * PedCreationDistMultiplier() <= (coors - FindPlayerPed()->GetPosition()).Magnitude2D()) {
+
+ if (CPedPlacement::IsPositionClearForPed(coors, circleR, -1, nil)) {
+ int pedIdx = 0;
+ CVector leaderPos;
+#ifdef FIX_BUGS
+ bool createLeader = true;
+#endif
+
+ for (int i = 0; i < pedAmount; i++) {
+ float angleMult = i + CGeneral::GetRandomNumberInRange(-0.2f, 0.2f);
+ float randomR = circleR + CGeneral::GetRandomNumberInRange(-0.2f, 0.2f) * circleR;
+ float xOffset = randomR * Cos(angleMult * circleSector);
+ float yOffset = randomR * Sin(angleMult * circleSector);
+ bool foundGround;
+ float groundZ = CWorld::FindGroundZFor3DCoord(xOffset + coors.x, yOffset + coors.y, coors.z + 1.0, &foundGround) + 1.0f;
+ if (foundGround) {
+ CVector finalPos(coors.x + xOffset, coors.y + yOffset, coors.z > groundZ ? coors.z : groundZ);
+
+#ifndef FIX_BUGS
+ const bool createLeader = i == 0;
+#endif
+ if (createLeader)
+ leaderPos = finalPos;
+
+ int pedModel = ChooseCivilianOccupation(group);
+ CPedModelInfo *pedModelInfo = (CPedModelInfo*)CModelInfo::GetModelInfo(pedModel);
+
+ if (pedModelInfo->GetRwObject()) {
+ CEntity* obstacles[6] = { nil, nil, nil, nil, nil, nil };
+ CPedPlacement::IsPositionClearForPed(finalPos, CModelInfo::GetColModel(pedModel)->boundingSphere.radius, ARRAY_SIZE(obstacles), obstacles);
+ bool foundObstacle = false;
+ for (int m = 0; m < ARRAY_SIZE(obstacles); m++) {
+ CEntity* obstacle = obstacles[m];
+ if (obstacle) {
+ int n = 0;
+ bool obstacleIsHarmless = false;
+ for (int n = 0; n < pedIdx; n++) {
+ if (obstacle == createdPeds[n])
+ obstacleIsHarmless = true;
+ }
+ if (!obstacleIsHarmless) {
+ foundObstacle = true;
+ break;
+ }
+ }
+ }
+ bool memberCanSeeLeader = createLeader ? true : CWorld::GetIsLineOfSightClear(finalPos, leaderPos, true, false, false, false, false, false, false);
+
+ bool notTooHighFromLeader = createLeader ? true : !(Abs(finalPos.z - leaderPos.z) >= 1.0f);
+
+ if (!foundObstacle && memberCanSeeLeader && notTooHighFromLeader) {
+ CPed *newPed = AddPed(pedModelInfo->m_pedType, pedModel, finalPos);
+ if (newPed) {
+ createdPeds[pedIdx++] = newPed;
+ float angle = CGeneral::GetRadianAngleBetweenPoints(
+ coors.x, coors.y,
+ finalPos.x, finalPos.y);
+ newPed->m_fRotationDest = angle;
+ newPed->m_fRotationCur = angle;
+ newPed->m_fearFlags = 0;
+ CVisibilityPlugins::SetClumpAlpha(newPed->GetClump(), 0);
+#ifdef FIX_BUGS
+ createLeader = false;
+#endif
+ }
+ // No.
+#ifndef FIX_BUGS
+ else
+ CWorld::Remove(nil);
+#endif
+ }
+ }
+ }
+ }
+ if (pedIdx >= 3) {
+ for (int j = 0; j < pedIdx / 2; ++j) {
+ createdPeds[j]->SetChat(createdPeds[pedIdx - 1 - j], 100000);
+ createdPeds[pedIdx - 1 - j]->SetChat(createdPeds[j], 100000);
+ }
+
+ // Make that extra guy in the middle stand there(PED_UNKNOWN locks him) and do nothing :lmao:
+ if (pedIdx % 2 != 0) {
+ CPed *tmim = createdPeds[(pedIdx - 1) / 2];
+ float angle = CGeneral::GetRadianAngleBetweenPoints(
+ tmim->GetPosition().x, tmim->GetPosition().y,
+ createdPeds[0]->GetPosition().x, createdPeds[0]->GetPosition().y);
+ tmim->SetHeading(angle);
+ tmim->SetPedState(PED_UNKNOWN);
+ }
+ createdPeds[0]->bIsLeader = true;
+
+ for (int l = 1; l < pedIdx; ++l)
+ createdPeds[l]->SetLeader(createdPeds[0]);
+
+ } else {
+ for (int k = 0; k < pedIdx; ++k) {
+ RemovePed(createdPeds[k]);
+ }
+ }
+ }
+ }
+}
diff --git a/src/peds/Population.h b/src/peds/Population.h
index 61f0bdb7..8c58f1b6 100644
--- a/src/peds/Population.h
+++ b/src/peds/Population.h
@@ -13,23 +13,6 @@ struct PedGroup
int32 models[NUMMODELSPERPEDGROUP];
};
-// Don't know the original name
-struct RegenerationPoint
-{
- eLevelName srcLevel; // this and below one may need to be exchanged
- eLevelName destLevel;
- float x1;
- float x2;
- float y1;
- float y2;
- float z1;
- float z2;
- RwV3d destPosA;
- RwV3d destPosB;
- RwV3d srcPosA;
- RwV3d srcPosB;
-};
-
class CPopulation
{
public:
@@ -39,6 +22,7 @@ public:
static float PedDensityMultiplier;
static uint32 ms_nTotalMissionPeds;
static int32 MaxNumberOfPedsInUse;
+ static int32 MaxNumberOfPedsInUseInterior;
static uint32 ms_nNumCivMale;
static uint32 ms_nNumCivFemale;
static uint32 ms_nNumCop;
@@ -58,26 +42,25 @@ public:
static uint32 ms_nNumGang9;
static uint32 ms_nNumGang7;
static uint32 ms_nNumGang8;
- static CVector RegenerationPoint_a;
- static CVector RegenerationPoint_b;
- static CVector RegenerationFront;
+
+ static uint32 ms_nTotalCarPassengerPeds;
+ static uint32 NumMiamiViceCops;
static void Initialise();
- static void Update(void);
+ static void Update(bool);
static void LoadPedGroups();
static void UpdatePedCount(ePedType, bool);
static void DealWithZoneChange(eLevelName oldLevel, eLevelName newLevel, bool);
- static CPed *AddPedInCar(CVehicle *car);
- static bool IsPointInSafeZone(CVector *coors);
+ static CPed *AddPedInCar(CVehicle *car, bool isDriver);
static void RemovePed(CPed *ent);
static int32 ChooseCivilianOccupation(int32);
+ static int32 ChooseNextCivilianOccupation(int32);
+ static void ChooseCivilianCoupleOccupations(int32, int32&, int32&);
static int32 ChoosePolicePedOccupation();
static int32 ChooseGangOccupation(int);
- static void FindCollisionZoneForCoors(CVector*, int*, eLevelName*);
- static void FindClosestZoneForCoors(CVector*, int*, eLevelName, eLevelName);
static void GeneratePedsAtStartOfGame();
static float PedCreationDistMultiplier();
- static CPed *AddPed(ePedType pedType, uint32 mi, CVector const &coors);
+ static CPed *AddPed(ePedType pedType, uint32 mi, CVector const &coors, int32 modifier = 0);
static void AddToPopulation(float, float, float, float);
static void ManagePopulation(void);
static void MoveCarsAndPedsOutOfAbandonedZones(void);
@@ -86,4 +69,20 @@ public:
static void ConvertAllObjectsToDummyObjects(void);
static bool TestRoomForDummyObject(CObject*);
static bool TestSafeForRealObject(CDummyObject*);
+ static bool IsSkateable(CVector const&);
+ static bool CanJeerAtStripper(int32 model);
+ static void RemovePedsIfThePoolGetsFull(void);
+ static bool IsMale(int32);
+ static bool IsFemale(int32);
+ static bool IsSunbather(int32);
+ static int32 ComputeRandomisedGangSize(void);
+ static bool CanSolicitPlayerInCar(int32);
+ static bool CanSolicitPlayerOnFoot(int32);
+ static bool IsSecurityGuard(ePedType);
+ static void PlaceGangMembers(ePedType, int32, CVector const&);
+ static void PlaceGangMembersInFormation(ePedType, int32, CVector const&);
+ static void PlaceGangMembersInCircle(ePedType, int32, CVector const&);
+ static void PlaceCouple(ePedType, int32, ePedType, int32, CVector);
+ static void PlaceMallPedsAsStationaryGroup(CVector const&, int32);
+ static CPed* AddDeadPedInFrontOfCar(const CVector& pos, CVehicle* pCulprit);
};
diff --git a/src/renderer/2dEffect.h b/src/renderer/2dEffect.h
index a8013b34..8ad2b946 100644
--- a/src/renderer/2dEffect.h
+++ b/src/renderer/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:
int8 type;
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) {}
@@ -78,14 +88,10 @@ public:
if(type == EFFECT_LIGHT){
if(light.corona)
RwTextureDestroy(light.corona);
-#if GTA_VERSION >= GTA3_PC_11
light.corona = nil;
-#endif
if(light.shadow)
RwTextureDestroy(light.shadow);
-#if GTA_VERSION >= GTA3_PC_11
light.shadow = nil;
-#endif
}
}
};
diff --git a/src/renderer/Clouds.cpp b/src/renderer/Clouds.cpp
index 957844a5..9cd32c5f 100644
--- a/src/renderer/Clouds.cpp
+++ b/src/renderer/Clouds.cpp
@@ -4,6 +4,7 @@
#include "Sprite.h"
#include "Sprite2d.h"
#include "General.h"
+#include "Game.h"
#include "Coronas.h"
#include "Camera.h"
#include "TxdStore.h"
@@ -24,8 +25,10 @@ uint32 CClouds::IndividualRotation;
float CClouds::ms_cameraRoll;
float CClouds::ms_horizonZ;
+float CClouds::ms_HorizonTilt;
CRGBA CClouds::ms_colourTop;
CRGBA CClouds::ms_colourBottom;
+CRGBA CClouds::ms_colourBkGrd;
void
CClouds::Init(void)
@@ -45,25 +48,15 @@ void
CClouds::Shutdown(void)
{
RwTextureDestroy(gpCloudTex[0]);
-#if GTA_VERSION >= GTA3_PC_11
gpCloudTex[0] = nil;
-#endif
RwTextureDestroy(gpCloudTex[1]);
-#if GTA_VERSION >= GTA3_PC_11
gpCloudTex[1] = nil;
-#endif
RwTextureDestroy(gpCloudTex[2]);
-#if GTA_VERSION >= GTA3_PC_11
gpCloudTex[2] = nil;
-#endif
RwTextureDestroy(gpCloudTex[3]);
-#if GTA_VERSION >= GTA3_PC_11
gpCloudTex[3] = nil;
-#endif
RwTextureDestroy(gpCloudTex[4]);
-#if GTA_VERSION >= GTA3_PC_11
gpCloudTex[4] = nil;
-#endif
}
void
@@ -71,15 +64,15 @@ CClouds::Update(void)
{
float s = Sin(TheCamera.Orientation - 0.85f);
#ifdef FIX_BUGS
- CloudRotation += CWeather::Wind*s*0.0025f*CTimer::GetTimeStepFix();
- IndividualRotation += (CWeather::Wind*CTimer::GetTimeStep() + 0.3f*CTimer::GetTimeStepFix()) * 60.0f;
+ 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.0025f;
- IndividualRotation += (CWeather::Wind*CTimer::GetTimeStep() + 0.3f) * 60.0f;
+ CloudRotation += CWeather::Wind*s*0.001f;
+ IndividualRotation += (CWeather::Wind*CTimer::GetTimeStep()*0.5f + 0.3f) * 60.0f;
#endif
}
-float StarCoorsX[9] = { 0.0f, 0.05f, 0.12f, 0.5f, 0.8f, 0.6f, 0.27f, 0.55f, 0.75f };
+float StarCoorsX[9] = { 0.0f, 0.05f, 0.13f, 0.4f, 0.7f, 0.6f, 0.27f, 0.55f, 0.75f };
float StarCoorsY[9] = { 0.0f, 0.45f, 0.9f, 1.0f, 0.85f, 0.52f, 0.48f, 0.35f, 0.2f };
float StarSizes[9] = { 1.0f, 1.4f, 0.9f, 1.0f, 0.6f, 1.5f, 1.3f, 1.0f, 0.8f };
@@ -124,6 +117,9 @@ CClouds::Render(void)
RwV3d screenpos;
RwV3d worldpos;
+ if(!CGame::CanSeeOutSideFromCurrArea())
+ return;
+
PUSH_RENDERGROUP("CClouds::Render");
CCoronas::SunBlockedByClouds = false;
@@ -135,25 +131,20 @@ CClouds::Render(void)
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
CSprite::InitSpriteBuffer();
- int minute = CClock::GetHours()*60 + CClock::GetMinutes();
+ float minute = CClock::GetHours()*60 + CClock::GetMinutes() + CClock::GetSeconds()/60.0f;
RwV3d campos = TheCamera.GetPosition();
// Moon
- int moonfadeout = Abs(minute - 180); // fully visible at 3AM
- if(moonfadeout < 180){ // fade in/out 3 hours
+ float moonfadeout = Abs(minute - 180.0f); // fully visible at 3AM
+ if((int)moonfadeout < 180){ // fade in/out 3 hours
float coverage = Max(CWeather::Foggyness, CWeather::CloudCoverage);
- int brightness = (1.0f - coverage) * (180 - moonfadeout);
+ int brightness = (1.0f - coverage) * (180 - (int)moonfadeout);
RwV3d pos = { 0.0f, -100.0f, 15.0f };
RwV3dAdd(&worldpos, &campos, &pos);
if(CSprite::CalcScreenCoors(worldpos, &screenpos, &szx, &szy, false)){
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[2]));
- if(CCoronas::bSmallMoon){
- szx *= 4.0f;
- szy *= 4.0f;
- }else{
- szx *= 10.0f;
- szy *= 10.0f;
- }
+ szx *= CCoronas::MoonSize*2.0f + 4.0f;
+ szy *= CCoronas::MoonSize*2.0f + 4.0f;
CSprite::RenderOneXLUSprite(screenpos.x, screenpos.y, screenpos.z,
szx, szy, brightness, brightness, brightness, 255, 1.0f/screenpos.z, 255);
}
@@ -202,7 +193,7 @@ CClouds::Render(void)
}
// Low clouds
- float lowcloudintensity = 1.0f - Max(CWeather::Foggyness, CWeather::CloudCoverage);
+ float lowcloudintensity = 1.0f - Max(Max(CWeather::Foggyness, CWeather::CloudCoverage), CWeather::ExtraSunnyness);
int r = CTimeCycle::GetLowCloudsRed() * lowcloudintensity;
int g = CTimeCycle::GetLowCloudsGreen() * lowcloudintensity;
int b = CTimeCycle::GetLowCloudsBlue() * lowcloudintensity;
@@ -223,10 +214,10 @@ CClouds::Render(void)
// Fluffy clouds
float rot_sin = Sin(CloudRotation);
float rot_cos = Cos(CloudRotation);
- int fluffyalpha = 160 * (1.0f - CWeather::Foggyness);
+ int fluffyalpha = 160 * (1.0f - Max(CWeather::Foggyness, CWeather::ExtraSunnyness));
if(fluffyalpha != 0){
static bool bCloudOnScreen[37];
- float hilight;
+ float sundist, hilight;
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
@@ -238,15 +229,16 @@ CClouds::Render(void)
worldpos.z = pos.z;
if(CSprite::CalcScreenCoors(worldpos, &screenpos, &szx, &szy, false)){
- float sundist = Sqrt(sq(screenpos.x-CCoronas::SunScreenX) + sq(screenpos.y-CCoronas::SunScreenY));
+ sundist = Sqrt(sq(screenpos.x-CCoronas::SunScreenX) + sq(screenpos.y-CCoronas::SunScreenY));
int tr = CTimeCycle::GetFluffyCloudsTopRed();
int tg = CTimeCycle::GetFluffyCloudsTopGreen();
int tb = CTimeCycle::GetFluffyCloudsTopBlue();
int br = CTimeCycle::GetFluffyCloudsBottomRed();
int bg = CTimeCycle::GetFluffyCloudsBottomGreen();
int bb = CTimeCycle::GetFluffyCloudsBottomBlue();
- if(sundist < SCREEN_WIDTH/2){
- hilight = (1.0f - Max(CWeather::Foggyness, CWeather::CloudCoverage)) * (1.0f - sundist/(SCREEN_WIDTH/2));
+ int distLimit = (3*SCREEN_WIDTH)/4;
+ if(sundist < distLimit){
+ hilight = (1.0f - Max(CWeather::Foggyness, CWeather::CloudCoverage)) * (1.0f - sundist/(float)distLimit);
tr = tr*(1.0f-hilight) + 255*hilight;
tg = tg*(1.0f-hilight) + 190*hilight;
tb = tb*(1.0f-hilight) + 190*hilight;
@@ -277,11 +269,10 @@ CClouds::Render(void)
for(i = 0; i < 37; i++){
RwV3d pos = { 2.0f*CoorsOffsetX[i], 2.0f*CoorsOffsetY[i], 40.0f*CoorsOffsetZ[i] + 40.0f };
worldpos.x = pos.x*rot_cos + pos.y*rot_sin + campos.x;
- worldpos.y = pos.x*rot_sin - pos.y*rot_cos + campos.y;
+ worldpos.y = pos.x*rot_sin + pos.y*rot_cos + campos.y;
worldpos.z = pos.z;
if(bCloudOnScreen[i] && CSprite::CalcScreenCoors(worldpos, &screenpos, &szx, &szy, false)){
- // BUG: this is stupid....would have to do this for each cloud individually
- if(hilight > 0.0f){
+ if(sundist < SCREEN_WIDTH/3){
CSprite::RenderBufferedOneXLUSprite_Rotate_Aspect(screenpos.x, screenpos.y, screenpos.z,
szx*30.0f, szy*30.0f,
200*hilight, 0, 0, 255, 1.0f/screenpos.z,
@@ -329,14 +320,17 @@ CClouds::RenderBackground(int16 topred, int16 topgreen, int16 topblue,
{
PUSH_RENDERGROUP("CClouds::RenderBackground");
- CVector left = TheCamera.GetRight();
- float c = left.Magnitude2D();
+ CVector right = CrossProduct(TheCamera.GetUp(), TheCamera.GetForward());
+ right.Normalise();
+ float c = right.Magnitude2D();
if(c > 1.0f)
c = 1.0f;
ms_cameraRoll = Acos(c);
- if(left.z < 0.0f)
+ if(right.z < 0.0f)
ms_cameraRoll = -ms_cameraRoll;
+ ms_HorizonTilt = SCREEN_WIDTH/2.0f * Tan(ms_cameraRoll);
+
if(UseDarkBackground()){
ms_colourTop.r = 50;
ms_colourTop.g = 50;
@@ -359,75 +353,74 @@ CClouds::RenderBackground(int16 topred, int16 topgreen, int16 topblue,
}else{
ms_horizonZ = CSprite::CalcHorizonCoors();
+ int fogr = (topred + 2 * botred) / 3;
+ int fogg = (topgreen + 2 * botgreen) / 3;
+ int fogb = (topblue + 2 * botblue) / 3;
+
// Draw top/bottom gradient
float gradheight = SCREEN_HEIGHT/2.0f;
- float topedge = ms_horizonZ - gradheight;
- float botpos, toppos;
- if(ms_horizonZ > 0.0f && topedge < SCREEN_HEIGHT){
- ms_colourTop.r = topred;
- ms_colourTop.g = topgreen;
- ms_colourTop.b = topblue;
- ms_colourTop.a = alpha;
- ms_colourBottom.r = botred;
- ms_colourBottom.g = botgreen;
- ms_colourBottom.b = botblue;
- ms_colourBottom.a = alpha;
-
- if(ms_horizonZ < SCREEN_HEIGHT)
- botpos = ms_horizonZ;
- else{
- float f = (ms_horizonZ - SCREEN_HEIGHT)/gradheight;
- ms_colourBottom.r = topred*f + (1.0f-f)*botred;
- ms_colourBottom.g = topgreen*f + (1.0f-f)*botgreen;
- ms_colourBottom.b = topblue*f + (1.0f-f)*botblue;
- botpos = SCREEN_HEIGHT;
- }
- if(topedge >= 0.0f)
- toppos = topedge;
- else{
- float f = (0.0f - topedge)/gradheight;
- ms_colourTop.r = botred*f + (1.0f-f)*topred;
- ms_colourTop.g = botgreen*f + (1.0f-f)*topgreen;
- ms_colourTop.b = botblue*f + (1.0f-f)*topblue;
- toppos = 0.0f;
- }
- CSprite2d::DrawRect(CRect(0, toppos, SCREEN_WIDTH, botpos),
- ms_colourBottom, ms_colourBottom, ms_colourTop, ms_colourTop);
- }
+
+ ms_colourTop.r = topred;
+ ms_colourTop.g = topgreen;
+ ms_colourTop.b = topblue;
+ ms_colourTop.a = alpha;
+ ms_colourBottom.r = botred;
+ ms_colourBottom.g = botgreen;
+ ms_colourBottom.b = botblue;
+ ms_colourBottom.a = alpha;
+
+ float botright = ms_horizonZ - ms_HorizonTilt;
+ float botleft = ms_horizonZ + ms_HorizonTilt;
+ float topright = botright - gradheight;
+ float topleft = botleft - gradheight;
+
+ CSprite2d::DrawAnyRect(0.0f, topleft, SCREEN_WIDTH, topright, 0.0f, botleft, SCREEN_WIDTH, botright,
+ ms_colourTop, ms_colourTop, ms_colourBottom, ms_colourBottom);
// draw the small stripe (whatever it's supposed to be)
- if(ms_horizonZ > -SMALLSTRIPHEIGHT && ms_horizonZ < SCREEN_HEIGHT){
- // Same colour as fog
- ms_colourTop.r = (topred + 2 * botred) / 3;
- ms_colourTop.g = (topgreen + 2 * botgreen) / 3;
- ms_colourTop.b = (topblue + 2 * botblue) / 3;
- CSprite2d::DrawRect(CRect(0, ms_horizonZ, SCREEN_WIDTH, ms_horizonZ+SMALLSTRIPHEIGHT),
- ms_colourTop, ms_colourTop, ms_colourTop, ms_colourTop);
- }
+ ms_colourTop.r = fogr;
+ ms_colourTop.g = fogg;
+ ms_colourTop.b = fogb;
+ ms_colourTop.a = alpha;
+ topright = ms_horizonZ - ms_HorizonTilt;
+ topleft = ms_horizonZ + ms_HorizonTilt;
+ botright = topright + SMALLSTRIPHEIGHT;
+ botleft = topleft + SMALLSTRIPHEIGHT;
+ CSprite2d::DrawAnyRect(0.0f, topleft, SCREEN_WIDTH, topright, 0.0f, botleft, SCREEN_WIDTH, botright,
+ ms_colourTop, ms_colourTop, ms_colourTop, ms_colourTop);
// Only top
- if(topedge > 0.0f){
+ if(ms_horizonZ + ms_HorizonTilt - gradheight > 0.0f ||
+ ms_horizonZ - ms_HorizonTilt - gradheight > 0.0f){
ms_colourTop.r = topred;
ms_colourTop.g = topgreen;
ms_colourTop.b = topblue;
ms_colourTop.a = alpha;
- ms_colourBottom.r = topred;
- ms_colourBottom.g = topgreen;
- ms_colourBottom.b = topblue;
- ms_colourBottom.a = alpha;
-
- botpos = Min(SCREEN_HEIGHT, topedge);
- CSprite2d::DrawRect(CRect(0, 0, SCREEN_WIDTH, botpos),
- ms_colourBottom, ms_colourBottom, ms_colourTop, ms_colourTop);
+
+ if(ms_horizonZ - Abs(ms_HorizonTilt) - gradheight > SCREEN_HEIGHT){
+ // only top is visible
+ topleft = 0.0f;
+ topright = 0.0f;
+ botleft = SCREEN_HEIGHT;
+ botright = SCREEN_HEIGHT;
+ }else{
+ botright = ms_horizonZ - ms_HorizonTilt - gradheight;
+ botleft = ms_horizonZ + ms_HorizonTilt - gradheight;
+ topright = Min(ms_horizonZ - ms_HorizonTilt - 2*SCREEN_HEIGHT, 0.0f);
+ topleft = Min(ms_horizonZ + ms_HorizonTilt - 2*SCREEN_HEIGHT, 0.0f);
+ }
+
+ CSprite2d::DrawAnyRect(0.0f, topleft, SCREEN_WIDTH, topright, 0.0f, botleft, SCREEN_WIDTH, botright,
+ ms_colourTop, ms_colourTop, ms_colourTop, ms_colourTop);
}
// Set both to fog colour for RenderHorizon
- ms_colourTop.r = (topred + 2 * botred) / 3;
- ms_colourTop.g = (topgreen + 2 * botgreen) / 3;
- ms_colourTop.b = (topblue + 2 * botblue) / 3;
- ms_colourBottom.r = (topred + 2 * botred) / 3;
- ms_colourBottom.g = (topgreen + 2 * botgreen) / 3;
- ms_colourBottom.b = (topblue + 2 * botblue) / 3;
+ ms_colourTop.r = fogr;
+ ms_colourTop.g = fogg;
+ ms_colourTop.b = fogb;
+ ms_colourBottom.r = fogr;
+ ms_colourBottom.g = fogg;
+ ms_colourBottom.b = fogb;
}
POP_RENDERGROUP();
@@ -439,28 +432,42 @@ CClouds::RenderHorizon(void)
if(UseDarkBackground())
return;
+ PUSH_RENDERGROUP("CClouds::RenderHorizon");
+
ms_colourBottom.a = 230;
ms_colourTop.a = 80;
- if(ms_horizonZ > SCREEN_HEIGHT)
- return;
+ float topright = ms_horizonZ - ms_HorizonTilt;
+ float topleft = ms_horizonZ + ms_HorizonTilt;
+ float botright = topright + SMALLSTRIPHEIGHT;
+ float botleft = topleft + SMALLSTRIPHEIGHT;
- PUSH_RENDERGROUP("CClouds::RenderHorizon");
+ CSprite2d::DrawAnyRect(0.0f, topleft, SCREEN_WIDTH, topright, 0.0f, botleft, SCREEN_WIDTH, botright,
+ ms_colourTop, ms_colourTop, ms_colourBottom, ms_colourBottom);
+
+
+ ms_colourBkGrd.r = 128.0f*CTimeCycle::GetAmbientRed();
+ ms_colourBkGrd.g = 128.0f*CTimeCycle::GetAmbientGreen();
+ ms_colourBkGrd.b = 128.0f*CTimeCycle::GetAmbientBlue();
+ ms_colourBkGrd.a = 255;
+
+ float horzstrip = SCREEN_STRETCH_Y(HORIZSTRIPHEIGHT);
+ topright = botright;
+ topleft = botleft;
+ botright = topright + horzstrip;
+ botleft = topleft + horzstrip;
+
+ CSprite2d::DrawAnyRect(0.0f, topleft, SCREEN_WIDTH, topright, 0.0f, botleft, SCREEN_WIDTH, botright,
+ ms_colourBottom, ms_colourBottom, ms_colourBkGrd, ms_colourBkGrd);
+
+
+ topright = botright;
+ topleft = botleft;
+ botright = Max(topright, SCREEN_HEIGHT);
+ botleft = Max(topleft, SCREEN_HEIGHT);
- float z1 = Min(ms_horizonZ + SMALLSTRIPHEIGHT, SCREEN_HEIGHT);
- CSprite2d::DrawRectXLU(CRect(0, ms_horizonZ, SCREEN_WIDTH, z1),
- ms_colourBottom, ms_colourBottom, ms_colourTop, ms_colourTop);
-
- // This is just weird
- float a = SCREEN_HEIGHT/400.0f * HORIZSTRIPHEIGHT +
- SCREEN_HEIGHT/300.0f * Max(TheCamera.GetPosition().z, 0.0f);
- float b = TheCamera.GetUp().z < 0.0f ?
- SCREEN_HEIGHT :
- SCREEN_HEIGHT * Abs(TheCamera.GetRight().z);
- float z2 = z1 + (a + b)*TheCamera.LODDistMultiplier;
- z2 = Min(z2, SCREEN_HEIGHT);
- CSprite2d::DrawRect(CRect(0, z1, SCREEN_WIDTH, z2),
- ms_colourBottom, ms_colourBottom, ms_colourTop, ms_colourTop);
+ CSprite2d::DrawAnyRect(0.0f, topleft, SCREEN_WIDTH, topright, 0.0f, botleft, SCREEN_WIDTH, botright,
+ ms_colourBkGrd, ms_colourBkGrd, ms_colourBkGrd, ms_colourBkGrd);
POP_RENDERGROUP();
}
diff --git a/src/renderer/Clouds.h b/src/renderer/Clouds.h
index 4d8cd2c8..ef33030b 100644
--- a/src/renderer/Clouds.h
+++ b/src/renderer/Clouds.h
@@ -8,8 +8,10 @@ public:
static float ms_cameraRoll;
static float ms_horizonZ;
+ static float ms_HorizonTilt;
static CRGBA ms_colourTop;
static CRGBA ms_colourBottom;
+ static CRGBA ms_colourBkGrd;
static void Init(void);
static void Shutdown(void);
diff --git a/src/renderer/Console.cpp b/src/renderer/Console.cpp
index 8ea5b7a3..244bfb17 100644
--- a/src/renderer/Console.cpp
+++ b/src/renderer/Console.cpp
@@ -63,7 +63,7 @@ CConsole::Display()
CFont::SetJustifyOn();
CFont::SetRightJustifyWrap(0.0f);
CFont::SetBackGroundOnlyTextOff();
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
#ifndef FIX_BUGS
CFont::SetPropOff(); // not sure why this is here anyway
#endif
diff --git a/src/renderer/Coronas.cpp b/src/renderer/Coronas.cpp
index e9f9e662..d9bf88d1 100644
--- a/src/renderer/Coronas.cpp
+++ b/src/renderer/Coronas.cpp
@@ -3,6 +3,7 @@
#include "main.h"
#include "General.h"
#include "Entity.h"
+#include "RenderBuffer.h"
#include "TxdStore.h"
#include "Camera.h"
#include "Sprite.h"
@@ -58,7 +59,7 @@ RwTexture *gpCoronaTexture[9] = { nil, nil, nil, nil, nil, nil, nil, nil, nil };
float CCoronas::LightsMult = 1.0f;
float CCoronas::SunScreenX;
float CCoronas::SunScreenY;
-bool CCoronas::bSmallMoon;
+int CCoronas::MoonSize;
bool CCoronas::SunBlockedByClouds;
int CCoronas::bChangeBrightnessImmediately;
@@ -134,13 +135,22 @@ 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 useNearDist, float nearDist)
{
int i;
if(sq(drawDist) < (TheCamera.GetPosition() - coors).MagnitudeSqr2D())
return;
+ if(useNearDist){
+ float dist = (TheCamera.GetPosition() - coors).Magnitude();
+ if(dist < 35.0f)
+ return;
+ if(dist < 50.0f)
+ alpha *= (dist - 35.0f)/(50.0f - 35.0f);
+ }
+
for(i = 0; i < NUMCORONAS; i++)
if(aCoronas[i].id == id)
break;
@@ -193,15 +203,19 @@ CCoronas::RegisterCorona(uint32 id, uint8 red, uint8 green, uint8 blue, uint8 al
aCoronas[i].reflection = reflection;
aCoronas[i].LOScheck = LOScheck;
aCoronas[i].drawStreak = drawStreak;
+ aCoronas[i].useNearDist = useNearDist;
+ aCoronas[i].nearDist = nearDist;
}
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 useNearDist, 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,
+ useNearDist, nearDist);
}
void
@@ -316,7 +330,7 @@ CCoronas::Render(void)
if(CCoronas::aCoronas[i].id == SUN_CORE)
spriteCoors.z = 0.95f * RwCameraGetFarClipPlane(Scene.camera);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(aCoronas[i].texture));
- spriteCoors.z -= 1.5f;
+ spriteCoors.z -= aCoronas[i].nearDist;
if(aCoronas[i].texture == gpCoronaTexture[8]){
// what's this?
@@ -378,7 +392,7 @@ CCoronas::Render(void)
}
}
- RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
@@ -434,9 +448,7 @@ CCoronas::RenderReflections(void)
if(CWeather::WetRoads > 0.0f){
PUSH_RENDERGROUP("CCoronas::RenderReflections");
-#ifdef FIX_BUGS
CSprite::InitSpriteBuffer();
-#endif
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
@@ -475,7 +487,7 @@ CCoronas::RenderReflections(void)
CVector spriteCoors;
float spritew, spriteh;
- if(CSprite::CalcScreenCoors(coors, &spriteCoors, &spritew, &spriteh, true)){
+ if(CSprite::CalcScreenCoors(coors, &spriteCoors, &spritew, &spriteh, true)) {
float drawDist = 0.75f * aCoronas[i].drawDist;
drawDist = Min(drawDist, 55.0f);
if(spriteCoors.z < drawDist){
@@ -519,6 +531,130 @@ CCoronas::RenderReflections(void)
}
}
+void
+CCoronas::RenderSunReflection(void)
+{
+ float sunZDir = CTimeCycle::GetSunDirection().z;
+ if(sunZDir > -0.05f){
+ float intensity = (0.3f - Abs(sunZDir - 0.25f))/0.3f *
+ (1.0f - CWeather::CloudCoverage) *
+ (1.0f - CWeather::Foggyness) *
+ (1.0f - CWeather::Wind);
+ if(intensity > 0.0f){
+ int r = (CTimeCycle::GetSunCoreRed() + CTimeCycle::GetSunCoronaRed())*intensity*0.25f;
+ int g = (CTimeCycle::GetSunCoreGreen() + CTimeCycle::GetSunCoronaGreen())*intensity*0.25f;
+ int b = (CTimeCycle::GetSunCoreBlue() + CTimeCycle::GetSunCoronaBlue())*intensity*0.25f;
+
+ CVector sunPos = 40.0f*CTimeCycle::GetSunDirection() + TheCamera.GetPosition();
+ sunPos.z = 0.5f*CWeather::Wind + 6.1f;
+ CVector sunDir = CTimeCycle::GetSunDirection();
+ sunDir.z = 0.0;
+ sunDir.Normalise();
+
+ TempBufferIndicesStored = 6;
+ TempBufferRenderIndexList[0] = 2;
+ TempBufferRenderIndexList[1] = 1;
+ TempBufferRenderIndexList[2] = 0;
+ TempBufferRenderIndexList[3] = 2;
+ TempBufferRenderIndexList[4] = 3;
+ TempBufferRenderIndexList[5] = 1;
+
+ // 60 unit square in sun direction
+ TempBufferVerticesStored = 4;
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[0], r, g, b, 255);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[0],
+ sunPos.x + 30.0f*sunDir.y,
+ sunPos.y - 30.0f*sunDir.x,
+ sunPos.z);
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[1], r, g, b, 255);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[1],
+ sunPos.x - 30.0f*sunDir.y,
+ sunPos.y + 30.0f*sunDir.x,
+ sunPos.z);
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[2], r, g, b, 255);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[2],
+ sunPos.x + 60.0f*sunDir.x + 30.0f*sunDir.y,
+ sunPos.y + 60.0f*sunDir.y - 30.0f*sunDir.x,
+ sunPos.z);
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[3], r, g, b, 255);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[3],
+ sunPos.x + 60.0f*sunDir.x - 30.0f*sunDir.y,
+ sunPos.y + 60.0f*sunDir.y + 30.0f*sunDir.x,
+ sunPos.z);
+
+ RwIm3DVertexSetU(&TempBufferRenderVertices[0], 0.0f);
+ RwIm3DVertexSetV(&TempBufferRenderVertices[0], 1.0f);
+ RwIm3DVertexSetU(&TempBufferRenderVertices[1], 1.0f);
+ RwIm3DVertexSetV(&TempBufferRenderVertices[1], 1.0f);
+ RwIm3DVertexSetU(&TempBufferRenderVertices[2], 0.0f);
+ RwIm3DVertexSetV(&TempBufferRenderVertices[2], 0.5f);
+ RwIm3DVertexSetU(&TempBufferRenderVertices[3], 1.0f);
+ RwIm3DVertexSetV(&TempBufferRenderVertices[3], 0.5f);
+
+ int timeInc = 0;
+ int sideInc = 0;
+ int fwdInc = 0;
+ for(int i = 0; i < 20; i++){
+ TempBufferRenderIndexList[TempBufferIndicesStored + 0] = TempBufferVerticesStored;
+ TempBufferRenderIndexList[TempBufferIndicesStored + 1] = TempBufferVerticesStored-1;
+ TempBufferRenderIndexList[TempBufferIndicesStored + 2] = TempBufferVerticesStored-2;
+ TempBufferRenderIndexList[TempBufferIndicesStored + 3] = TempBufferVerticesStored;
+ TempBufferRenderIndexList[TempBufferIndicesStored + 4] = TempBufferVerticesStored+1;
+ TempBufferRenderIndexList[TempBufferIndicesStored + 5] = TempBufferVerticesStored-1;
+ TempBufferIndicesStored += 6;
+
+ // What a weird way to do it...
+ float fwdLen = fwdInc/20 + 60;
+ float sideLen = sideInc/20 + 30;
+ sideLen += 10.0f*Sin((float)(CTimer::GetTimeInMilliseconds()+timeInc & 0x7FF)/0x800*TWOPI);
+ timeInc += 900;
+ sideInc += 970;
+ fwdInc += 1440;
+
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored+0], r, g, b, 255);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored+0],
+ sunPos.x + fwdLen*sunDir.x + sideLen*sunDir.y,
+ sunPos.y + fwdLen*sunDir.y - sideLen*sunDir.x,
+ sunPos.z);
+
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored+1], r, g, b, 255);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored+1],
+ sunPos.x + fwdLen*sunDir.x - sideLen*sunDir.y,
+ sunPos.y + fwdLen*sunDir.y + sideLen*sunDir.x,
+ sunPos.z);
+
+ RwIm3DVertexSetU(&TempBufferRenderVertices[TempBufferVerticesStored+0], 0.0f);
+ RwIm3DVertexSetV(&TempBufferRenderVertices[TempBufferVerticesStored+0], 0.5f);
+ RwIm3DVertexSetU(&TempBufferRenderVertices[TempBufferVerticesStored+1], 1.0f);
+ RwIm3DVertexSetV(&TempBufferRenderVertices[TempBufferVerticesStored+1], 0.5f);
+ TempBufferVerticesStored += 2;
+ }
+
+
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEFOGTYPE, (void*)rwFOGTYPELINEAR);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[4]));
+ if(RwIm3DTransform(TempBufferRenderVertices, TempBufferVerticesStored, nil, rwIM3D_VERTEXUV)){
+ RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TempBufferRenderIndexList, TempBufferIndicesStored);
+ RwIm3DEnd();
+ }
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
+ TempBufferVerticesStored = 0;
+ TempBufferIndicesStored = 0;
+ }
+ }
+}
+
void
CCoronas::DoSunAndMoon(void)
{
@@ -535,7 +671,7 @@ CCoronas::DoSunAndMoon(void)
255, sunCoors, size,
999999.88f, TYPE_STAR, FLARE_NONE, REFLECTION_OFF, LOSCHECK_OFF, STREAK_OFF, 0.0f);
- if(CTimeCycle::GetSunDirection().z > 0.0f)
+ if(CTimeCycle::GetSunDirection().z > 0.0f && !CGame::IsInInterior())
RegisterCorona(SUN_CORONA,
CTimeCycle::GetSunCoronaRed(), CTimeCycle::GetSunCoronaGreen(), CTimeCycle::GetSunCoronaBlue(),
255, sunCoors, 25.0f * CTimeCycle::GetSunSize(),
@@ -544,7 +680,7 @@ CCoronas::DoSunAndMoon(void)
CVector spriteCoors;
float spritew, spriteh;
- if(CSprite::CalcScreenCoors(sunCoors, &spriteCoors, &spritew, &spriteh, true)){
+ if(CSprite::CalcScreenCoors(sunCoors, &spriteCoors, &spritew, &spriteh, true)) {
SunScreenX = spriteCoors.x;
SunScreenY = spriteCoors.y;
}else{
@@ -611,80 +747,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 = true;
- break;
- case LIGHT_FLICKER:
- if((CTimer::GetTimeInMilliseconds() ^ m_randomSeed) & 0x60)
- lightOn = true;
- else
- lightFlickering = true;
- if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed) & 3)
+ lightOn = false;
+ lightFlickering = false;
+ switch(effect->light.lightType){
+ case LIGHT_ON:
lightOn = true;
- break;
- case LIGHT_FLICKER_NIGHT:
- if(CClock::GetHours() > 18 || CClock::GetHours() < 7 || CWeather::WetRoads > 0.5f){
+ 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{
@@ -695,85 +817,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;
+ }
}
- 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);
+ 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.shadowSize != 0.0f){
- if(lightOn){
- CShadows::StoreStaticShadow((uintptr)this + i, SHADOWTYPE_ADDITIVE,
- effect->light.shadow, &pos,
- effect->light.shadowSize, 0.0f,
- 0.0f, -effect->light.shadowSize,
- 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.shadowSize, 0.0f,
- 0.0f, -effect->light.shadowSize,
- 0, 0.0f, 0.0f, 0.0f,
- 15.0f, 1.0f, 40.0f, false, 0.0f);
+ // Light shadow
+ if(effect->light.shadowSize != 0.0f){
+ if(lightOn){
+ CShadows::StoreStaticShadow((uintptr)this + i, SHADOWTYPE_ADDITIVE,
+ effect->light.shadow, &pos,
+ effect->light.shadowSize, 0.0f,
+ 0.0f, -effect->light.shadowSize,
+ 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.shadowSize, 0.0f,
+ 0.0f, -effect->light.shadowSize,
+ 0, 0.0f, 0.0f, 0.0f,
+ 15.0f, 1.0f, 40.0f, false, 0.0f);
+ }
}
+ break;
+
+ 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;
}
}
-}
+} \ No newline at end of file
diff --git a/src/renderer/Coronas.h b/src/renderer/Coronas.h
index 46eb4315..45f027d8 100644
--- a/src/renderer/Coronas.h
+++ b/src/renderer/Coronas.h
@@ -4,19 +4,21 @@ extern RwTexture *gpCoronaTexture[9];
struct CRegisteredCorona
{
+ CVector coors;
uint32 id;
uint32 lastLOScheck;
RwTexture *texture;
+ float size;
+ float someAngle;
+ float drawDist;
+ float nearDist;
+ float heightAboveRoad;
uint8 red;
uint8 green;
uint8 blue;
uint8 alpha; // alpha when fully visible
uint8 fadeAlpha; // actual value used for rendering, faded
- CVector coors;
- float size;
- float someAngle;
bool registeredThisFrame;
- float drawDist;
int8 flareType;
int8 reflection;
@@ -25,12 +27,11 @@ struct CRegisteredCorona
uint8 firstUpdate : 1;
uint8 drawStreak : 1;
uint8 sightClear : 1;
+ uint8 useNearDist : 1;
+ uint8 renderReflection : 1;
- bool renderReflection;
- float heightAboveRoad;
-
- float prevX[6];
- float prevY[6];
+ int16 prevX[6];
+ int16 prevY[6];
uint8 prevRed[6];
uint8 prevGreen[6];
uint8 prevBlue[6];
@@ -39,7 +40,7 @@ struct CRegisteredCorona
void Update(void);
};
-VALIDATE_SIZE(CRegisteredCorona, 0x80);
+VALIDATE_SIZE(CRegisteredCorona, 0x68);
class CCoronas
{
@@ -81,7 +82,7 @@ public:
static float LightsMult;
static float SunScreenY;
static float SunScreenX;
- static bool bSmallMoon;
+ static int MoonSize;
static bool SunBlockedByClouds;
static int bChangeBrightnessImmediately;
@@ -90,12 +91,15 @@ 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 useNearDist = false, float nearDist = 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 useNearDist = false, float nearDist = 1.5f);
static void UpdateCoronaCoors(uint32 id, const CVector &coors, float drawDist, float someAngle);
static void Render(void);
static void RenderReflections(void);
+ static void RenderSunReflection(void);
static void DoSunAndMoon(void);
};
diff --git a/src/renderer/Credits.cpp b/src/renderer/Credits.cpp
index 60581793..81e76625 100644
--- a/src/renderer/Credits.cpp
+++ b/src/renderer/Credits.cpp
@@ -7,6 +7,7 @@
#include "Camera.h"
#include "Text.h"
#include "Credits.h"
+#include "Pad.h"
bool CCredits::bCreditsGoing;
uint32 CCredits::CreditsStartTime;
@@ -39,22 +40,21 @@ CCredits::PrintCreditSpace(float space, uint32 &line)
void
CCredits::PrintCreditText(float scaleX, float scaleY, wchar *text, uint32 &lineoffset, float scrolloffset)
{
-#ifdef FIX_BUGS
- float start = DEFAULT_SCREEN_HEIGHT + 50.0f;
-#else
- float start = SCREEN_HEIGHT + 50.0f;
-#endif
- float y = lineoffset + start - scrolloffset;
- if(y > -50.0f && y < start){
-#ifdef FIX_BUGS
- CFont::SetScale(SCREEN_SCALE_X(scaleX), SCREEN_SCALE_Y(scaleY));
- CFont::PrintString(SCREEN_WIDTH/2.0f, SCREEN_SCALE_Y(y), (uint16*)text);
-#else
- CFont::SetScale(scaleX, scaleY);
- CFont::PrintString(SCREEN_WIDTH/2.0f, y, (uint16*)text);
-#endif
+ CPad::UpdatePads();
+ if (CPad::GetPad(0)->GetCrossJustDown())
+ bCreditsGoing = false;
+ else {
+ float start = DEFAULT_SCREEN_HEIGHT + 20.0f;
+ float y = lineoffset + start - scrolloffset;
+ if (y > 20.0f && DEFAULT_SCREEN_HEIGHT - 20.0f > y) {
+ CFont::SetScale(SCREEN_SCALE_X(scaleX), SCREEN_SCALE_Y(scaleY));
+ CFont::SetColor(CRGBA(0, 0, 0, 255));
+ CFont::PrintString(SCREEN_WIDTH / 2.0f, SCREEN_SCALE_Y(y), (uint16*)text);
+ CFont::SetColor(CRGBA(220, 220, 220, 220));
+ CFont::PrintString(SCREEN_WIDTH / 2.0f - SCREEN_SCALE_X(1.0f), SCREEN_SCALE_Y(y - 1.0f), (uint16*)text);
+ }
+ lineoffset += scaleY*25.0f;
}
- lineoffset += scaleY*25.0f;
}
void
@@ -71,434 +71,736 @@ CCredits::Render(void)
scrolloffset = (CTimer::GetTimeInMilliseconds() - CreditsStartTime) / 24.0f;
CFont::SetJustifyOff();
CFont::SetBackgroundOff();
-#ifdef FIX_BUGS
- CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH - 20));
-#else
- CFont::SetCentreSize(SCREEN_WIDTH - 20);
-#endif
+ CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH * 0.75f));
CFont::SetCentreOn();
CFont::SetPropOn();
- CFont::SetColor(CRGBA(220, 220, 220, 220));
- CFont::SetFontStyle(FONT_HEADING);
-
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.7f, 1.0f, TheText.Get("CRED002"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED003"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.7f, 1.0f, TheText.Get("CRED004"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED005"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.7f, 1.0f, TheText.Get("CRED006"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED007"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED008"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.7f, 1.0f, TheText.Get("CRED009"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED010"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED011"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED012"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED013"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.7f, 1.0f, TheText.Get("CRED014"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED015"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED016"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED017"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.7f, 1.0f, TheText.Get("CRED018"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED019"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.4f, 0.82f, TheText.Get("CRED020"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED021"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED022"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED245"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.7f, 1.0f, TheText.Get("CRED023"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED024"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.7f, 1.0f, TheText.Get("CRED025"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED026"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED027"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED028"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED257"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED029"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED030"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED031"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.7f, 1.0f, TheText.Get("CRED032"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED033"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED244"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED034"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED035"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED247"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED036"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED037"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.7f, 1.0f, TheText.Get("CRED038"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED039"), lineoffset, scrolloffset);
- 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 == CMenuManager::LANGUAGE_ITALIAN)
- PrintCreditSpace(1.5f, 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 == CMenuManager::LANGUAGE_ITALIAN)
- PrintCreditSpace(1.5f, lineoffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED044"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.7f, 1.0f, TheText.Get("CRED045"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED046"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.7f, 1.0f, TheText.Get("CRED047"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED048"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED049"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED050"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.7f, 1.0f, TheText.Get("CRD050A"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED051"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED052"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED053"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED054"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED055"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED056"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED248"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED249"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED250"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED251"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED252"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED253"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.7f, 1.0f, TheText.Get("CRED057"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED058"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED059"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.7f, 1.0f, TheText.Get("CRED254"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED255"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.7f, 1.0f, TheText.Get("CRED060"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.7f, 1.0f, TheText.Get("CRED061"), lineoffset, scrolloffset);
- if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
- PrintCreditSpace(1.5f, lineoffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED062"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.7f, 1.0f, TheText.Get("CRED063"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED064"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.7f, 1.0f, TheText.Get("CRED065"), lineoffset, scrolloffset);
- PrintCreditSpace(1.5f, lineoffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED066"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.7f, 1.0f, TheText.Get("CRED067"), lineoffset, scrolloffset);
- 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 == CMenuManager::LANGUAGE_ITALIAN)
- PrintCreditSpace(1.5f, lineoffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED070"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.7f, 1.0f, TheText.Get("CRED071"), lineoffset, scrolloffset);
- PrintCreditSpace(1.5f, lineoffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED072"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.7f, 1.0f, TheText.Get("CRED073"), lineoffset, scrolloffset);
- PrintCreditSpace(1.5f, lineoffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED074"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED075"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED076"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED077"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED078"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED079"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED080"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED081"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED082"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED083"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED084"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED242"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED259"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED260"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED261"), lineoffset, scrolloffset);
- 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 == CMenuManager::LANGUAGE_ITALIAN)
- PrintCreditSpace(1.5f, lineoffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED086"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.4f, 0.82f, TheText.Get("CRED087"), lineoffset, scrolloffset);
- PrintCreditSpace(1.5f, lineoffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED088"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.7f, 1.0f, TheText.Get("CRED089"), lineoffset, scrolloffset);
- PrintCreditSpace(1.5f, lineoffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED090"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.7f, 1.0f, TheText.Get("CRED091"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED094"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.7f, 1.0f, TheText.Get("CRED095"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED096"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED097"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED098"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED099"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED263"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED264"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED265"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED267"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED270"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED266"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.4f, 0.82f, TheText.Get("CRED100"), lineoffset, scrolloffset);
- PrintCreditSpace(1.5f, lineoffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED101"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED102"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED103"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED104"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED105"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED106"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED268"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED269"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.7f, 1.0f, TheText.Get("CRED107"), lineoffset, scrolloffset);
- PrintCreditSpace(1.5f, lineoffset);
- PrintCreditText(1.0f, 1.0f, TheText.Get("CRED108"), lineoffset, scrolloffset);
- PrintCreditSpace(1.0f, lineoffset);
- PrintCreditText(1.0f, 1.0f, TheText.Get("CRED109"), lineoffset, scrolloffset);
- if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
- PrintCreditSpace(1.0f, lineoffset);
- PrintCreditText(1.0f, 1.0f, TheText.Get("CRED110"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.7f, 1.0f, TheText.Get("CRED111"), lineoffset, scrolloffset);
- PrintCreditText(1.0f, 1.0f, TheText.Get("CRED112"), lineoffset, scrolloffset);
- if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
- PrintCreditSpace(1.0f, lineoffset);
- PrintCreditText(1.0f, 1.0f, TheText.Get("CRED113"), lineoffset, scrolloffset);
- if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
- PrintCreditSpace(1.0f, lineoffset);
- PrintCreditText(1.0f, 1.0f, TheText.Get("CRED114"), lineoffset, scrolloffset);
- if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
- PrintCreditSpace(1.0f, lineoffset);
- PrintCreditText(1.0f, 1.0f, TheText.Get("CRED115"), lineoffset, scrolloffset);
- if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
- PrintCreditSpace(1.0f, lineoffset);
- PrintCreditText(1.0f, 1.0f, TheText.Get("CRED116"), lineoffset, scrolloffset);
- if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
- PrintCreditSpace(1.0f, lineoffset);
- PrintCreditText(1.0f, 1.0f, TheText.Get("CRED117"), lineoffset, scrolloffset);
- if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
- PrintCreditSpace(1.0f, lineoffset);
- PrintCreditText(1.0f, 1.0f, TheText.Get("CRED118"), lineoffset, scrolloffset);
- if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
- PrintCreditSpace(1.0f, lineoffset);
- PrintCreditText(1.0f, 1.0f, TheText.Get("CRED119"), lineoffset, scrolloffset);
- if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
- PrintCreditSpace(1.0f, lineoffset);
- PrintCreditText(1.0f, 1.0f, TheText.Get("CRED120"), lineoffset, scrolloffset);
- if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
- PrintCreditSpace(1.0f, lineoffset);
- PrintCreditText(1.0f, 1.0f, TheText.Get("CRED121"), lineoffset, scrolloffset);
- if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
- PrintCreditSpace(1.0f, lineoffset);
- PrintCreditText(1.0f, 1.0f, TheText.Get("CRED122"), lineoffset, scrolloffset);
- if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
- PrintCreditSpace(1.0f, lineoffset);
- PrintCreditText(1.0f, 1.0f, TheText.Get("CRED123"), lineoffset, scrolloffset);
- if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
- PrintCreditSpace(1.0f, lineoffset);
- PrintCreditText(1.0f, 1.0f, TheText.Get("CRED124"), lineoffset, scrolloffset);
- if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
- PrintCreditSpace(1.0f, lineoffset);
- PrintCreditText(1.0f, 1.0f, TheText.Get("CRED125"), lineoffset, scrolloffset);
- if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
- PrintCreditSpace(1.0f, lineoffset);
- PrintCreditText(1.0f, 1.0f, TheText.Get("CRED126"), lineoffset, scrolloffset);
- if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
- PrintCreditSpace(1.0f, lineoffset);
- PrintCreditText(1.0f, 1.0f, TheText.Get("CRED127"), lineoffset, scrolloffset);
- if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
- PrintCreditSpace(1.0f, lineoffset);
- PrintCreditText(1.0f, 1.0f, TheText.Get("CRED128"), lineoffset, scrolloffset);
- if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
- PrintCreditSpace(1.0f, lineoffset);
- PrintCreditText(1.0f, 1.0f, TheText.Get("CRED129"), lineoffset, scrolloffset);
- if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
- PrintCreditSpace(1.0f, lineoffset);
- PrintCreditText(1.0f, 1.0f, TheText.Get("CRED130"), lineoffset, scrolloffset);
- if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
- PrintCreditSpace(1.0f, lineoffset);
- PrintCreditText(1.0f, 1.0f, TheText.Get("CRED131"), lineoffset, scrolloffset);
- if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
- PrintCreditSpace(1.0f, lineoffset);
- PrintCreditText(1.0f, 1.0f, TheText.Get("CRED132"), lineoffset, scrolloffset);
- if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
- PrintCreditSpace(1.0f, lineoffset);
- PrintCreditText(1.0f, 1.0f, TheText.Get("CRED133"), lineoffset, scrolloffset);
- if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
- PrintCreditSpace(1.0f, lineoffset);
- PrintCreditText(1.0f, 1.0f, TheText.Get("CRED134"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.7f, 1.0f, TheText.Get("CRED135"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.0f, TheText.Get("CRED136"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRD136A"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.7f, 1.0f, TheText.Get("CRED137"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRD137A"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.7f, 1.0f, TheText.Get("CRED138"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRD138A"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRD138B"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.0f, 1.0f, TheText.Get("CRED139"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.7f, 1.0f, TheText.Get("CRED140"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRD140A"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRD140B"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRD140C"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRD140D"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRD140E"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.4f, 0.82f, TheText.Get("CRED141"), lineoffset, scrolloffset);
- PrintCreditText(1.0f, 1.0f, TheText.Get("CRED142"), lineoffset, scrolloffset);
- PrintCreditSpace(1.0f, lineoffset);
- PrintCreditText(1.0f, 1.0f, TheText.Get("CRED143"), lineoffset, scrolloffset);
- PrintCreditSpace(1.0f, lineoffset);
- PrintCreditText(1.0f, 1.0f, TheText.Get("CRED144"), lineoffset, scrolloffset);
- PrintCreditSpace(1.0f, lineoffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.4f, 0.82f, TheText.Get("CRED145"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED146"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED147"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED148"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED149"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED150"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED151"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED152"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED153"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED154"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED155"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED156"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED157"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED158"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED159"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED160"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED161"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED162"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED163"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED164"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED165"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED166"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED167"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED168"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED169"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED170"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED171"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED172"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED173"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED174"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED175"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED176"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED177"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED178"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED179"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED180"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED181"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED182"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED183"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED184"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED185"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED186"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED187"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED188"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED189"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED190"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED191"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED192"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED193"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED194"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED195"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED196"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED197"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED198"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED199"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED200"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED201"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED202"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED203"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED204"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED205"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED206"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED207"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED208"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED209"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED210"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED211"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED212"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED213"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED214"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED215"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED216"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED241"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.4f, 0.82f, TheText.Get("CRED217"), lineoffset, scrolloffset);
- PrintCreditSpace(1.5f, lineoffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.4f, 0.82f, TheText.Get("CRED218"), lineoffset, scrolloffset);
- PrintCreditSpace(1.5f, lineoffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRD218A"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRD218B"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.4f, 0.82f, TheText.Get("CRED219"), lineoffset, scrolloffset);
- PrintCreditSpace(1.5f, lineoffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED220"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.4f, 0.82f, TheText.Get("CRED221"), lineoffset, scrolloffset);
- PrintCreditSpace(1.5f, lineoffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED222"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.4f, 0.82f, TheText.Get("CRED223"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED224"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED225"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED226"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.4f, 0.82f, TheText.Get("CRED227"), lineoffset, scrolloffset);
- PrintCreditSpace(1.5f, lineoffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED228"), lineoffset, scrolloffset);
- PrintCreditText(1.7f, 1.7f, TheText.Get("CRED229"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditText(1.4f, 0.82f, TheText.Get("CRED230"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED231"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED232"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED233"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED234"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED235"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED236"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED237"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED238"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED239"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED240"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("LITTLE"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("NICK"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED243"), lineoffset, scrolloffset);
- PrintCreditText(1.4f, 1.4f, TheText.Get("CRED244"), lineoffset, scrolloffset);
- PrintCreditSpace(2.0f, lineoffset);
- PrintCreditSpace(2.0f, lineoffset);
-
-
- CFont::DrawFonts();
+ CFont::SetFontStyle(FONT_STANDARD);
+
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRED001"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRED002"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED003"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRED004"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED005"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRED006"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED007"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED008"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRED025"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED026"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED027"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED028"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED029"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED030"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED031"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD031A"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD031B"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD031C"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRD031D"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD031E"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRD024A"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_FRENCH || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_SPANISH)
+ PrintCreditSpace(0.5f, lineoffset);
+
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED024"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRED023"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_FRENCH)
+ PrintCreditSpace(0.5f, lineoffset);
+
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD023A"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD023B"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRED018"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED019"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRD018A"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_FRENCH)
+ PrintCreditSpace(0.5f, lineoffset);
+
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD019A"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD019B"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRED020"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED021"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRD022A"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED022"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD022B"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD022C"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRED032"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED033"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRD032A"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED034"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED035"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED036"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED037"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD037A"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD037B"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD037C"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRD041B"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED042"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED039"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED044"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED040"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD042A"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRED142"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD142A"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRED009"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_FRENCH)
+ PrintCreditSpace(0.5f, lineoffset);
+
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED010"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED011"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED012"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED013"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD013A"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD013B"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD013C"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRED089"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_SPANISH)
+ PrintCreditSpace(0.5f, lineoffset);
+
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED090"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED347"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRED047"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_SPANISH)
+ PrintCreditSpace(0.5f, lineoffset);
+
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED048"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED049"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED348"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRED050"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED051"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED052"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED053"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED054"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED055"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED056"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD056A"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD056B"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD056C"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD056D"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED349"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED350"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED351"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED352"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED353"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED354"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED355"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED356"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED357"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED359"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED360"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED361"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED362"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED363"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED364"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED365"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED366"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED367"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED368"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED369"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED370"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED371"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED372"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED373"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRED256"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_FRENCH)
+ PrintCreditSpace(0.5f, lineoffset);
+
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED257"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED258"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRED057"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_FRENCH || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_SPANISH)
+ PrintCreditSpace(0.5f, lineoffset);
+
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED058"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRD057A"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED059"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRD060A"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD060B"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD060C"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRD002A"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_FRENCH || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_SPANISH)
+ PrintCreditSpace(0.5f, lineoffset);
+
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED003"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRD001A"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD001B"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRED060"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRED061"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED062"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRED063"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED064"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRED069"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED070"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRED065"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_FRENCH || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_SPANISH)
+ PrintCreditSpace(0.5f, lineoffset);
+
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED066"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRED067"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED068"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRD071A"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD072A"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRED091"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED094"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRED095"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_SPANISH || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_FRENCH)
+ PrintCreditSpace(0.5f, lineoffset);
+
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED097"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED098"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD098A"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD098B"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD098C"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED099"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED096"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRED273"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD092A"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED092"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD092B"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRED073"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED074"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED076"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED075"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED077"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED078"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED081"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED082"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED079"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED080"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED083"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED084"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD084A"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD084B"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD084C"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRD084D"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD084E"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(0.95f, 0.7f, TheText.Get("CRED085"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED086"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRD086A"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(0.95f, 0.7f, TheText.Get("CRED087"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED088"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRD088A"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRD088B"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRD088C"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRD088D"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRD088E"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRD088F"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRD088G"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRED107"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED108"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED109"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
+ PrintCreditSpace(0.5f, lineoffset);
+
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED110"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRD110A"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRED111"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED112"), lineoffset, scrolloffset);
+
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED113"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED114"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED115"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED116"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED117"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED118"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED119"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED120"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED121"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED122"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED123"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED124"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED125"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED126"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED127"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED128"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
+ PrintCreditSpace(0.5f, lineoffset);
+
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED129"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+
+ CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH * 0.8f));
+
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRD111A"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_SPANISH || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_FRENCH)
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED130"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_SPANISH || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_FRENCH)
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED131"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_SPANISH || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_FRENCH)
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED132"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_SPANISH || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_FRENCH)
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED133"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_SPANISH || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_FRENCH)
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED134"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_SPANISH || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_FRENCH)
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRD134A"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_SPANISH || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_FRENCH)
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRD134B"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_SPANISH || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_FRENCH)
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRD134C"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_SPANISH || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_FRENCH)
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRD134D"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_SPANISH || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_FRENCH)
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRD134E"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_SPANISH || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_FRENCH)
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRD134F"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_SPANISH || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_FRENCH)
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRD134G"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_SPANISH || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_FRENCH)
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRD134H"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_SPANISH || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_FRENCH)
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRD134I"), lineoffset, scrolloffset);
+
+ CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH * 0.7f));
+
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRED135"), lineoffset, scrolloffset);
+
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_FRENCH || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_SPANISH)
+ PrintCreditSpace(0.5f, lineoffset);
+
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD136A"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD137A"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRED138"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED066"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD138B"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED139"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(1.1f, 0.8f, TheText.Get("CRED140"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_FRENCH)
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD140A"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD140B"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD140C"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD140D"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD140E"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD140F"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD140G"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD140H"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD140I"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD140J"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD140K"), lineoffset, scrolloffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD140L"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+
+ CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH * 0.85f));
+
+ PrintCreditText(0.95f, 0.7f, TheText.Get("CRED259"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED260"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED261"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED262"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED263"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED264"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED265"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED266"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(0.95f, 0.7f, TheText.Get("CRED141"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRD141A"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRD141B"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED143"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED144"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(0.95f, 0.7f, TheText.Get("CRED145"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED146"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED147"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED148"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED149"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED150"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED151"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED152"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED153"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED154"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED155"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED156"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED157"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED158"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED159"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED160"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED161"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED162"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED163"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED164"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED165"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED166"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED167"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED168"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED169"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED170"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED171"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED172"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+
+ CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH * 0.75f));
+
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(0.95f, 0.7f, TheText.Get("CRED217"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(0.95f, 0.7f, TheText.Get("CRED218"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.0f, lineoffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRD218A"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(0.95f, 0.7f, TheText.Get("CRED219"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.0f, lineoffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED220"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(0.95f, 0.7f, TheText.Get("CRED221"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.0f, lineoffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED222"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(0.95f, 0.7f, TheText.Get("CRED223"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.0f, lineoffset);
+ PrintCreditText(1.1f, 1.1f, TheText.Get("CRED224"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(0.95f, 0.7f, TheText.Get("CRED227"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.0f, lineoffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED228"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(0.95f, 0.7f, TheText.Get("CRED229"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRD229A"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRD229B"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(0.95f, 0.7f, TheText.Get("CRED274"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED275"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED276"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED277"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(0.95f, 0.7f, TheText.Get("CRED278"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED279"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED280"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED281"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(0.95f, 0.7f, TheText.Get("CRED282"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED283"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED284"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED285"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED286"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(0.95f, 0.7f, TheText.Get("CRED287"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED288"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED289"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED290"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(0.95f, 0.7f, TheText.Get("CRED291"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED292"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(0.95f, 0.7f, TheText.Get("CRED293"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED294"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED295"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED296"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(0.95f, 0.7f, TheText.Get("CRED297"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED298"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED299"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED300"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED301"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED302"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED303"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED304"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED305"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED306"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED307"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED308"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(0.95f, 0.7f, TheText.Get("CRED309"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED310"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(0.95f, 0.7f, TheText.Get("CRED314"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.95f, 0.7f, TheText.Get("CRED315"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.95f, 0.7f, TheText.Get("CRED316"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.0f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED317"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED318"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED319"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED320"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED321"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED322"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED323"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED324"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED325"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED326"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED327"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED328"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(0.95f, 0.7f, TheText.Get("CRED329"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED330"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED331"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED332"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+
+ CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH * 0.8f));
+
+ PrintCreditText(0.95f, 0.7f, TheText.Get("CRED333"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED334"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED335"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED336"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED337"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED338"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED339"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED340"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED341"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED342"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditSpace(1.0f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRD344A"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
+ PrintCreditSpace(0.5f, lineoffset);
+
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED344"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED345"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRD345A"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.0f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED346"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
+ PrintCreditSpace(1.0f, lineoffset);
+
+ PrintCreditSpace(1.5f, lineoffset);
+
+ CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH * 0.75f));
+
+ PrintCreditText(0.95f, 0.7f, TheText.Get("CRED267"), lineoffset, scrolloffset);
+ PrintCreditSpace(0.5f, lineoffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED268"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(0.95f, 0.7f, TheText.Get("CRED269"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED270"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED271"), lineoffset, scrolloffset);
+ PrintCreditText(0.65f, 0.65f, TheText.Get("CRED272"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditText(0.95f, 0.7f, TheText.Get("CRED230"), lineoffset, scrolloffset);
+ if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
+ PrintCreditSpace(0.5f, lineoffset);
+
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED231"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED232"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED233"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED234"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED235"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED236"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED237"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED238"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED239"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED240"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED241"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED242"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED243"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED244"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED245"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED246"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED247"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED248"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED249"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED358"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED250"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED251"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED252"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRD251A"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRD252A"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED253"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED254"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED374"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED375"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED376"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED377"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED378"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED379"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED380"), lineoffset, scrolloffset);
+ PrintCreditText(0.95f, 0.95f, TheText.Get("CRED381"), lineoffset, scrolloffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ PrintCreditSpace(1.5f, lineoffset);
+ CFont::DrawFonts();
+#ifdef CUTSCENE_BORDERS_SWITCH
+ if (CMenuManager::m_PrefsCutsceneBorders)
+#endif
if(TheCamera.m_WideScreenOn)
TheCamera.DrawBordersForWideScreen();
diff --git a/src/renderer/CutsceneShadow.cpp b/src/renderer/CutsceneShadow.cpp
new file mode 100644
index 00000000..8cb33896
--- /dev/null
+++ b/src/renderer/CutsceneShadow.cpp
@@ -0,0 +1,269 @@
+#include "common.h"
+#include "main.h"
+#include "rwcore.h"
+#include "rwplcore.h"
+#include "CutsceneShadow.h"
+#include "RwHelper.h"
+
+#define DLIGHT_VALUE 0.8f /* Directional light intensity */
+
+
+CCutsceneShadow::CCutsceneShadow()
+{
+ m_pAtomic = nil;
+ m_nRwObjectType = -1;
+ m_pLight = nil;
+ m_nBlurPasses = 0;
+ m_bResample = false;
+ m_bGradient = false;
+}
+
+CCutsceneShadow::~CCutsceneShadow()
+{
+ Destroy();
+}
+
+bool
+CCutsceneShadow::Create(RwObject *object, int32 rasterSize, bool resample, int32 blurPasses, bool gradient)
+{
+ ASSERT(object != nil);
+
+ RwRGBAReal color;
+ RwFrame *frame;
+
+ if (!object)
+ return false;
+
+ m_pLight = RpLightCreate(rpLIGHTDIRECTIONAL);
+ ASSERT(m_pLight != nil);
+
+ if (!m_pLight)
+ return false;
+
+ color.red = color.green = color.blue = DLIGHT_VALUE;
+ color.alpha = 0.0f;
+
+ RpLightSetColor(m_pLight, &color);
+
+ frame = RwFrameCreate();
+ ASSERT(frame != nil);
+
+ RpLightSetFrame(m_pLight, frame);
+
+ SetLightProperties(180.0f, 90.0f, false);
+
+ m_pObject = object;
+ m_nRwObjectType = RwObjectGetType(m_pObject);
+
+ switch ( m_nRwObjectType )
+ {
+ case rpCLUMP:
+ {
+ RpClumpGetBoundingSphere(m_pClump, &m_BoundingSphere, 1);
+ m_BaseSphere.radius = m_BoundingSphere.radius;
+ RwV3dTransformPoints(&m_BaseSphere.center, &m_BoundingSphere.center, 1, RwFrameGetMatrix(RpClumpGetFrame(m_pClump)));
+ break;
+ }
+
+ case rpATOMIC:
+ {
+ m_BoundingSphere = *RpAtomicGetBoundingSphere(m_pAtomic);
+ m_BaseSphere.radius = m_BoundingSphere.radius;
+ RwV3dTransformPoints(&m_BaseSphere.center, &m_BoundingSphere.center, 1, RwFrameGetMatrix(RpAtomicGetFrame(m_pAtomic)));
+ break;
+ }
+
+ default:
+ {
+ Destroy();
+ return false;
+ break;
+ }
+ }
+
+ if ( !m_Camera.Create(rasterSize) )
+ {
+ Destroy();
+ return false;
+ }
+
+ m_nBlurPasses = blurPasses;
+ m_bResample = resample;
+ m_bGradient = gradient;
+
+ if ( m_bResample && !m_ResampleCamera.Create(rasterSize - 1) )
+ {
+ Destroy();
+ return false;
+ }
+
+ if ( m_nBlurPasses != 0 )
+ {
+ if ( !m_BlurCamera.Create(resample ? rasterSize - 1 : rasterSize) )
+ {
+ Destroy();
+ return false;
+ }
+ }
+
+ if ( m_bGradient )
+ {
+ if ( !m_GradientCamera.Create(resample ? rasterSize - 1 : rasterSize) )
+ {
+ Destroy();
+ return false;
+ }
+
+ m_GradientCamera.MakeGradientRaster();
+ }
+
+ m_Camera.SetLight(m_pLight);
+
+ switch ( m_nRwObjectType )
+ {
+ case rpATOMIC:
+ m_Camera.SetFrustum(1.1f * m_BoundingSphere.radius);
+ break;
+
+ case rpCLUMP:
+ m_Camera.SetFrustum(1.1f * m_BoundingSphere.radius);
+ break;
+ }
+
+ m_Camera.SetCenter(&m_BaseSphere.center);
+ return true;
+}
+
+RwFrame *
+CCutsceneShadow::SetLightProperties(float angleY, float angleX, bool setLight)
+{
+ ASSERT(m_pLight != nil);
+
+ RwFrame *frame;
+ static RwV3d Xaxis = { 1.0f, 0.0f, 0.0f };
+ static RwV3d Yaxis = { 0.0f, 1.0f, 0.0f };
+
+ frame = RpLightGetFrame(m_pLight);
+ ASSERT(frame != nil);
+
+ if ( !frame )
+ return nil;
+
+ RwFrameRotate(frame, &Yaxis, angleY, rwCOMBINEREPLACE);
+ RwFrameRotate(frame, &Xaxis, angleX, rwCOMBINEPOSTCONCAT);
+
+ if ( setLight )
+ m_Camera.SetLight(m_pLight);
+
+ return frame;
+}
+
+bool
+CCutsceneShadow::IsInitialized()
+{
+ return m_pObject != nil;
+}
+
+void
+CCutsceneShadow::Destroy()
+{
+ m_Camera.Destroy();
+ m_ResampleCamera.Destroy();
+ m_BlurCamera.Destroy();
+ m_GradientCamera.Destroy();
+
+ m_pAtomic = nil;
+
+ m_nRwObjectType = -1;
+
+ if (m_pLight)
+ {
+ RwFrame *frame = RpLightGetFrame(m_pLight);
+ RpLightSetFrame(m_pLight, nil);
+ RwFrameDestroy(frame);
+ RpLightDestroy(m_pLight);
+ m_pLight = nil;
+ }
+}
+
+RwRaster *
+CCutsceneShadow::Update()
+{
+ switch ( m_nRwObjectType )
+ {
+ case rpCLUMP:
+ ASSERT(m_pClump != nil);
+ RwV3dTransformPoints(&m_BaseSphere.center, &m_BoundingSphere.center, 1, RwFrameGetMatrix(RpClumpGetFrame(m_pClump)));
+ break;
+
+ case rpATOMIC:
+ ASSERT(m_pAtomic != nil);
+ RwV3dTransformPoints(&m_BaseSphere.center, &m_BoundingSphere.center, 1, RwFrameGetMatrix(RpAtomicGetFrame(m_pAtomic)));
+ break;
+ }
+
+ m_Camera.SetCenter(&m_BaseSphere.center);
+
+ switch ( m_nRwObjectType )
+ {
+ case rpCLUMP:
+ m_Camera.Update(m_pClump);
+ break;
+
+ case rpATOMIC:
+ m_Camera.Update(m_pAtomic);
+ break;
+ }
+
+ RwRaster *raster = m_Camera.GetRwRenderRaster();
+ ASSERT(raster != nil);
+
+ if ( m_bResample )
+ return m_ResampleCamera.RasterResample(raster);
+
+ if ( m_nBlurPasses )
+ return m_BlurCamera.RasterBlur(raster, m_nBlurPasses);
+
+ if ( m_bGradient )
+ return m_GradientCamera.RasterGradient(raster);
+
+ return raster;
+}
+
+RwTexture *
+CCutsceneShadow::UpdateForCutscene()
+{
+ Update();
+ return GetShadowRwTexture();
+}
+
+CShadowCamera *
+CCutsceneShadow::GetShadowCamera(int32 camType)
+{
+ switch ( camType )
+ {
+ case RESAMPLE: return &m_ResampleCamera;
+ case BLUR: return &m_BlurCamera;
+ case GRADIENT: return &m_GradientCamera;
+ }
+
+ return &m_Camera;
+}
+
+RwTexture *
+CCutsceneShadow::GetShadowRwTexture()
+{
+ if ( m_bResample )
+ return m_ResampleCamera.GetRwRenderTexture();
+ else
+ return m_Camera.GetRwRenderTexture();
+}
+
+void
+CCutsceneShadow::DrawBorderAroundTexture(RwRGBA const& color)
+{
+ if ( m_bResample )
+ m_ResampleCamera.DrawOutlineBorder(color);
+ else
+ m_Camera.DrawOutlineBorder(color);
+} \ No newline at end of file
diff --git a/src/renderer/CutsceneShadow.h b/src/renderer/CutsceneShadow.h
new file mode 100644
index 00000000..a59fe78f
--- /dev/null
+++ b/src/renderer/CutsceneShadow.h
@@ -0,0 +1,52 @@
+#pragma once
+#include "ShadowCamera.h"
+
+class CCutsceneShadow
+{
+public:
+ enum
+ {
+ RASTER = 0,
+ RESAMPLE,
+ BLUR,
+ GRADIENT,
+ };
+
+ CShadowCamera m_Camera;
+ bool m_bResample;
+ CShadowCamera m_ResampleCamera;
+ int32 m_nBlurPasses;
+ CShadowCamera m_BlurCamera;
+ bool m_bGradient;
+ CShadowCamera m_GradientCamera;
+
+ union
+ {
+ RwObject *m_pObject;
+ RpAtomic *m_pAtomic;
+ RpClump *m_pClump;
+ };
+
+ int32 m_nRwObjectType;
+ RpLight *m_pLight;
+ RwSphere m_BoundingSphere;
+ RwSphere m_BaseSphere;
+
+ CCutsceneShadow();
+ ~CCutsceneShadow();
+
+ RwSphere GetBaseSphere()
+ {
+ return m_BaseSphere;
+ }
+
+ bool Create(RwObject *object, int32 rasterSize, bool resample, int32 blurPasses, bool gradient);
+ RwFrame *SetLightProperties(float angleY, float angleX, bool setLight);
+ bool IsInitialized();
+ void Destroy();
+ RwRaster *Update();
+ RwTexture *UpdateForCutscene();
+ CShadowCamera *GetShadowCamera(int32 camType = RASTER);
+ RwTexture *GetShadowRwTexture();
+ void DrawBorderAroundTexture(RwRGBA const& color);
+};
diff --git a/src/renderer/Draw.cpp b/src/renderer/Draw.cpp
index f702f188..a5e7504b 100644
--- a/src/renderer/Draw.cpp
+++ b/src/renderer/Draw.cpp
@@ -5,8 +5,8 @@
#include "Camera.h"
#include "CutsceneMgr.h"
-#ifdef ASPECT_RATIO_SCALE
float CDraw::ms_fAspectRatio = DEFAULT_ASPECT_RATIO;
+#ifdef ASPECT_RATIO_SCALE
float CDraw::ms_fScaledFOV = 45.0f;
#endif
@@ -30,15 +30,10 @@ bool CDraw::ms_bFixRadar = true;
bool CDraw::ms_bFixSprites = true;
#endif
+#ifdef ASPECT_RATIO_SCALE
float
-CDraw::FindAspectRatio(void)
+FindAspectRatio(void)
{
-#ifndef ASPECT_RATIO_SCALE
- if(FrontEndMenuManager.m_PrefsUseWideScreen)
- return 16.0f/9.0f;
- else
- return 4.0f/3.0f;
-#else
switch (FrontEndMenuManager.m_PrefsUseWideScreen) {
case AR_AUTO:
return SCREEN_WIDTH / SCREEN_HEIGHT;
@@ -54,7 +49,30 @@ CDraw::FindAspectRatio(void)
case AR_21_9:
return 21.0f / 9.0f;
};
+}
+#endif
+
+float
+CDraw::CalculateAspectRatio(void)
+{
+#ifdef ASPECT_RATIO_SCALE
+ if (TheCamera.m_WideScreenOn)
+ CDraw::ms_fAspectRatio = (5.f / 3.f) * FindAspectRatio() / (16.f / 9.f); // It's used on theatrical showings according to Wiki
+ else
+ CDraw::ms_fAspectRatio = FindAspectRatio();
+#else
+ 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
+ CDraw::ms_fAspectRatio = 16.f / 9.f;
+ } else if (TheCamera.m_WideScreenOn) {
+ CDraw::ms_fAspectRatio = 5.f/4.f;
+ } else {
+ CDraw::ms_fAspectRatio = 4.f/3.f;
+ }
#endif
+ return CDraw::ms_fAspectRatio;
}
#ifdef ASPECT_RATIO_SCALE
diff --git a/src/renderer/Draw.h b/src/renderer/Draw.h
index 8727e0e0..b96fa813 100644
--- a/src/renderer/Draw.h
+++ b/src/renderer/Draw.h
@@ -10,7 +10,7 @@ enum eAspectRatio
AR_16_10,
AR_16_9,
AR_21_9,
-
+
AR_MAX,
};
@@ -20,10 +20,10 @@ private:
static float ms_fNearClipZ;
static float ms_fFarClipZ;
static float ms_fFOV;
-#ifdef ASPECT_RATIO_SCALE
// we use this variable to scale a lot of 2D elements
// so better cache it
static float ms_fAspectRatio;
+#ifdef ASPECT_RATIO_SCALE
// similar thing for 3D rendering
static float ms_fScaledFOV;
#endif
@@ -58,15 +58,12 @@ public:
static float GetScaledFOV(void) { return ms_fFOV; }
#endif
- 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
-
#ifdef PROPER_SCALING
static float ScaleY(float y);
#endif
diff --git a/src/renderer/Fluff.cpp b/src/renderer/Fluff.cpp
index c4cfe7f7..59d3668d 100644
--- a/src/renderer/Fluff.cpp
+++ b/src/renderer/Fluff.cpp
@@ -1,11 +1,15 @@
#include "common.h"
#include "main.h"
+#include "RenderBuffer.h"
#include "Entity.h"
#include "Fluff.h"
#include "Camera.h"
#include "Sprite.h"
#include "Coronas.h"
+#include "PointLights.h"
+#include "Rubbish.h"
+#include "Timecycle.h"
#include "General.h"
#include "Timer.h"
#include "Clock.h"
@@ -13,6 +17,300 @@
#include "Stats.h"
#include "maths.h"
#include "Frontend.h"
+#include "CutsceneMgr.h"
+#include "PlayerPed.h"
+#include "Bones.h"
+#include "World.h"
+#include "Replay.h"
+#include "Coronas.h"
+#include "SaveBuf.h"
+
+#ifdef COMPATIBLE_SAVES
+#define SCRIPTPATHS_SAVE_SIZE 0x9C
+#else
+#define SCRIPTPATHS_SAVE_SIZE sizeof(aArray)
+#endif
+
+CPlaneTrail CPlaneTrails::aArray[6];
+RwImVertexIndex TrailIndices[32] = {
+ 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,
+ 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16
+};
+
+void
+CPlaneTrail::Init(void)
+{
+ int i;
+ for(i = 0; i < ARRAY_SIZE(m_time); i++)
+ m_time[i] = 0;
+}
+
+void
+CPlaneTrail::Render(float visibility)
+{
+ int i;
+ int numVerts = 0;
+ if(!TheCamera.IsSphereVisible(m_pos[0], 1000.0f))
+ return;
+
+ int alpha = visibility*110.0f;
+ if(alpha == 0)
+ return;
+
+ for(i = 0; i < ARRAY_SIZE(m_pos); i++){
+ int32 time = CTimer::GetTimeInMilliseconds() - m_time[i];
+ if(time > 30000)
+ m_time[i] = 0;
+ if(m_time[i] != 0){
+ float fade = (30000.0f - time) / 10000.0f;
+ fade = Min(fade, 1.0f);
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[numVerts], 255, 255, 255, (int)(alpha*fade));
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[numVerts], m_pos[i].x, m_pos[i].y, m_pos[i].z);
+ numVerts++;
+ }
+ }
+ if(numVerts > 1){
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
+
+ if(RwIm3DTransform(TempBufferRenderVertices, numVerts, nil, rwIM3D_VERTEXXYZ|rwIM3D_VERTEXRGBA)){
+ RwIm3DRenderIndexedPrimitive(rwPRIMTYPELINELIST, TrailIndices, (numVerts-1)*2);
+ RwIm3DEnd();
+ }
+ }
+}
+
+void
+CPlaneTrail::RegisterPoint(CVector pos)
+{
+ int i;
+ bool bNewPoint = false;
+ if(m_time[0] != 0 && CTimer::GetTimeInMilliseconds() - m_time[0] > 2000){
+ bNewPoint = true;
+ for(i = ARRAY_SIZE(m_pos)-1; i > 0; i--){
+ m_pos[i] = m_pos[i-1];
+ m_time[i] = m_time[i-1];
+ }
+ }
+ m_pos[0] = pos;
+ if(bNewPoint || m_time[0] == 0)
+ m_time[0] = CTimer::GetTimeInMilliseconds();
+}
+
+void
+CPlaneTrails::Init(void)
+{
+ int i;
+ for(i = 0; i < ARRAY_SIZE(aArray); i++)
+ aArray[i].Init();
+}
+
+void
+CPlaneTrails::Update(void)
+{
+ CVector planePos;
+
+ planePos.x = 1590.0f * Sin((float)(CTimer::GetTimeInMilliseconds() & 0x1FFFF)/0x20000 * TWOPI);
+ planePos.y = 1200.0f * Cos((float)(CTimer::GetTimeInMilliseconds() & 0x1FFFF)/0x20000 * TWOPI);
+ planePos.z = 550.0f;
+ RegisterPoint(planePos, 3);
+ if(CClock::GetHours() > 22 || CClock::GetHours() < 7){
+ if(CTimer::GetTimeInMilliseconds() & 0x200)
+ CCoronas::RegisterCorona(101, 255, 0, 0, 255, planePos, 5.0f, 2000.0f,
+ CCoronas::TYPE_NORMAL, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF,
+ CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
+ else
+ CCoronas::UpdateCoronaCoors(101, planePos, 2000.0f, 0.0f);
+ }
+
+ planePos.x = 1000.0f * Sin((float)(CTimer::GetTimeInMilliseconds() & 0x1FFFF)/0x20000 * TWOPI);
+ planePos.y = -1600.0f * Cos((float)(CTimer::GetTimeInMilliseconds() & 0x1FFFF)/0x20000 * TWOPI);
+ planePos.z = 500.0f;
+ RegisterPoint(planePos, 4);
+ if(CClock::GetHours() > 22 || CClock::GetHours() < 7){
+ if(CTimer::GetTimeInMilliseconds() & 0x200)
+ CCoronas::RegisterCorona(102, 255, 0, 0, 255, planePos, 5.0f, 2000.0f,
+ CCoronas::TYPE_NORMAL, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF,
+ CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
+ else
+ CCoronas::UpdateCoronaCoors(102, planePos, 2000.0f, 0.0f);
+ }
+
+ planePos.x = 1100.0f * Cos((float)(CTimer::GetTimeInMilliseconds() & 0x1FFFF)/0x20000 * TWOPI);
+ planePos.y = 700.0f * Sin((float)(CTimer::GetTimeInMilliseconds() & 0x1FFFF)/0x20000 * TWOPI);
+ planePos.z = 600.0f;
+ RegisterPoint(planePos, 5);
+ if(CClock::GetHours() > 22 || CClock::GetHours() < 7){
+ if(CTimer::GetTimeInMilliseconds() & 0x200)
+ CCoronas::RegisterCorona(103, 255, 0, 0, 255, planePos, 5.0f, 2000.0f,
+ CCoronas::TYPE_NORMAL, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF,
+ CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
+ else
+ CCoronas::UpdateCoronaCoors(103, planePos, 2000.0f, 0.0f);
+ }
+}
+
+void
+CPlaneTrails::Render(void)
+{
+ int i;
+ float visibility = Min(1.0f-CWeather::Foggyness, 1.0f-CWeather::CloudCoverage);
+ visibility = Min(visibility, 1.0f-CWeather::Rain);
+ visibility = Min(Max(Max(CTimeCycle::GetSkyTopRed(), CTimeCycle::GetSkyTopGreen()), CTimeCycle::GetSkyTopBlue())/256.0f, visibility);
+ if(visibility > 0.0001f)
+ for(i = 0; i < ARRAY_SIZE(aArray); i++)
+ aArray[i].Render(visibility);
+}
+
+void
+CPlaneTrails::RegisterPoint(CVector pos, uint32 id)
+{
+ aArray[id].RegisterPoint(pos);
+}
+
+
+
+CPlaneBanner CPlaneBanners::aArray[5];
+
+void
+CPlaneBanner::Init(void)
+{
+ int i;
+ for(i = 0; i < ARRAY_SIZE(m_pos); i++){
+ m_pos[i].x = i;
+ m_pos[i].y = 0.0f;
+ m_pos[i].z = -60.0f;
+ }
+}
+
+void
+CPlaneBanner::Update(void)
+{
+ int i;
+ if(m_pos[0].z > -50.0f){
+ m_pos[0].z -= 0.05f*CTimer::GetTimeStep();
+ m_pos[0].z = Max(m_pos[0].z, -100.0f);
+ for(i = 1; i < ARRAY_SIZE(m_pos); i++){
+ CVector dist = m_pos[i] - m_pos[i-1];
+ float len = dist.Magnitude();
+ if(len > 8.0f)
+ m_pos[i] = m_pos[i-1] + dist/len*8.0f;
+ }
+ }
+}
+
+void
+CPlaneBanner::Render(void)
+{
+ int i;
+ if(m_pos[0].z > -50.0f){
+ float camDist = (TheCamera.GetPosition() - m_pos[0]).Magnitude();
+ if(TheCamera.IsSphereVisible(m_pos[4], 32.0f) && camDist < 300.0f){
+ TempBufferVerticesStored = 0;
+ TempBufferIndicesStored = 0;
+ int alpha = camDist < 250.0f ? 160 : (300.0f-camDist)/(300.0f-250.0f)*160;
+
+ TempBufferVerticesStored += 2;
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[0], 255, 255, 255, alpha);
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[1], 255, 255, 255, alpha);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[0], m_pos[2].x, m_pos[2].y, m_pos[2].z);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[1], m_pos[2].x, m_pos[2].y, m_pos[2].z - 4.0f);
+ RwIm3DVertexSetU(&TempBufferRenderVertices[0], 0.0f);
+ RwIm3DVertexSetV(&TempBufferRenderVertices[0], 0.0f);
+ RwIm3DVertexSetU(&TempBufferRenderVertices[1], 0.0f);
+ RwIm3DVertexSetV(&TempBufferRenderVertices[1], 1.0f);
+ for(i = 2; i < 8; i++){
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored+0], 255, 255, 255, alpha);
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored+1], 255, 255, 255, alpha);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored+0], m_pos[i].x, m_pos[i].y, m_pos[i].z);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored+1], m_pos[i].x, m_pos[i].y, m_pos[i].z - 4.0f);
+ RwIm3DVertexSetU(&TempBufferRenderVertices[TempBufferVerticesStored+0], (i-2)/5.0f);
+ RwIm3DVertexSetV(&TempBufferRenderVertices[TempBufferVerticesStored+0], 0.0f);
+ RwIm3DVertexSetU(&TempBufferRenderVertices[TempBufferVerticesStored+1], (i-2)/5.0f);
+ RwIm3DVertexSetV(&TempBufferRenderVertices[TempBufferVerticesStored+1], 1.0f);
+ TempBufferRenderIndexList[TempBufferIndicesStored+0] = TempBufferVerticesStored-2;
+ TempBufferRenderIndexList[TempBufferIndicesStored+1] = TempBufferVerticesStored-1;
+ TempBufferRenderIndexList[TempBufferIndicesStored+2] = TempBufferVerticesStored+1;
+ TempBufferRenderIndexList[TempBufferIndicesStored+3] = TempBufferVerticesStored-2;
+ TempBufferRenderIndexList[TempBufferIndicesStored+4] = TempBufferVerticesStored+1;
+ TempBufferRenderIndexList[TempBufferIndicesStored+5] = TempBufferVerticesStored;
+ TempBufferVerticesStored += 2;
+ TempBufferIndicesStored += 6;
+ }
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpRubbishTexture[2]));
+
+#ifdef FIX_BUGS
+ if(RwIm3DTransform(TempBufferRenderVertices, TempBufferVerticesStored, nil, rwIM3D_VERTEXXYZ|rwIM3D_VERTEXUV|rwIM3D_VERTEXRGBA)){
+#else
+ if(RwIm3DTransform(TempBufferRenderVertices, TempBufferVerticesStored, nil, 0)){
+#endif
+ RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TempBufferRenderIndexList, TempBufferIndicesStored);
+ RwIm3DEnd();
+ }
+
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
+
+ TempBufferVerticesStored = 0;
+ TempBufferIndicesStored = 0;
+ }
+ }
+}
+
+void
+CPlaneBanner::RegisterPoint(CVector pos)
+{
+ m_pos[0] = pos;
+}
+
+void
+CPlaneBanners::Init(void)
+{
+ int i;
+ for(i = 0; i < ARRAY_SIZE(aArray); i++)
+ aArray[i].Init();
+}
+
+void
+CPlaneBanners::Update(void)
+{
+ int i;
+ for(i = 0; i < ARRAY_SIZE(aArray); i++)
+ aArray[i].Update();
+}
+
+void
+CPlaneBanners::Render(void)
+{
+ int i;
+ for(i = 0; i < ARRAY_SIZE(aArray); i++)
+ aArray[i].Render();
+}
+
+void
+CPlaneBanners::RegisterPoint(CVector pos, uint32 id)
+{
+ aArray[id].RegisterPoint(pos);
+}
+
+bool CSmokeTrails::CigOn = false;
+CSmokeTrail CSmokeTrails::aSmoke[3];
+
+RwImVertexIndex SmokeTrailIndices[32] = { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
+9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16 };
+
+float RandomSmoke[16] = { 10.0f, 5.0f, -1.0f, -9.0f, -7.0f, -1.0f, 0.0f, 3.0f, 6.0f, 7.0f, 4.0f, 2.0f,
+5.0f, 7.0f };
uint8 ScrollCharSet[59][5] = {
{ 0x00, 0x00, 0x00, 0x00, 0x00 }, // ' '
@@ -79,23 +377,17 @@ uint8 ScrollCharSet[59][5] = {
// ---------- CMovingThings ----------
enum eScrollBarTypes
{
- SCROLL_BUSINESS,
- SCROLL_TRAFFIC,
- SCROLL_ENTERTAINMENT,
- SCROLL_AIRPORT_DOORS,
- SCROLL_AIRPORT_FRONT,
- SCROLL_STORE,
- SCROLL_USED_CARS
+ SCROLL_ARENA_STRING
};
-CScrollBar aScrollBars[11];
-CTowerClock aTowerClocks[2];
-CDigitalClock aDigitalClocks[3];
+CScrollBar aScrollBars[1];
CMovingThing CMovingThings::StartCloseList;
CMovingThing CMovingThings::EndCloseList;
int16 CMovingThings::Num;
CMovingThing CMovingThings::aMovingThings[NUMMOVINGTHINGS];
+
+int32 CScrollBar::TonightsEvent;
void CMovingThings::Init()
{
@@ -103,126 +395,194 @@ void CMovingThings::Init()
StartCloseList.m_pPrev = nil;
EndCloseList.m_pNext = nil;
EndCloseList.m_pPrev = &CMovingThings::StartCloseList;
+
+ CPlaneTrails::Init();
+ CSmokeTrails::Init();
+ CPlaneBanners::Init();
+ CPointLights::Init();
+
Num = 0;
-
- // Initialize scroll bars
- aScrollBars[0].Init(CVector( 228.3f, -669.0f, 39.0f ), SCROLL_BUSINESS, 0.0f, 0.5f, 0.5f, 255, 128, 0, 0.3f);
- aScrollBars[1].Init(CVector( 772.0f, 164.0f, -9.5f ), SCROLL_TRAFFIC, 0.0f, 0.5f, 0.25f, 128, 255, 0, 0.3f);
- aScrollBars[2].Init(CVector(-1089.61f, -584.224f, 13.246f), SCROLL_AIRPORT_DOORS, 0.0f, -0.1706f, 0.107f, 255, 0, 0, 0.11f);
- aScrollBars[3].Init(CVector(-1089.61f, -602.04602f, 13.246f), SCROLL_AIRPORT_DOORS, 0.0f, -0.1706f, 0.107f, 0, 255, 0, 0.11f);
- aScrollBars[4].Init(CVector(-1089.61f, -619.81702f, 13.246f), SCROLL_AIRPORT_DOORS, 0.0f, -0.1706f, 0.107f, 255, 128, 0, 0.11f);
- aScrollBars[5].Init(CVector(-754.578f, -633.50897f, 18.411f), SCROLL_AIRPORT_FRONT, 0.0f, 0.591f, 0.52f, 100, 100, 255, 0.3f);
- aScrollBars[6].Init(CVector( -754.578f, -586.672f, 18.411f), SCROLL_AIRPORT_FRONT, 0.0f, 0.591f, 0.52f, 100, 100, 255, 0.3f);
- aScrollBars[7].Init(CVector( 85.473f, -1069.512f, 30.5f ), SCROLL_STORE, 0.625f, -0.3125f, 0.727f, 100, 100, 255, 0.5f);
- aScrollBars[8].Init(CVector( 74.823f, -1086.879f, 31.495f), SCROLL_ENTERTAINMENT, -0.2083f, 0.1041f, 0.5f, 255, 255, 128, 0.3f);
- aScrollBars[9].Init(CVector( -36.459f, -1031.2371f, 32.534f), SCROLL_ENTERTAINMENT, -0.1442f, 0.0721f, 0.229f, 150, 255, 50, 0.3f);
- aScrollBars[10].Init(CVector( 1208.0f, -62.208f, 19.157f), SCROLL_USED_CARS, 0.0642f, -0.20365f, 0.229f, 255, 128, 0, 0.3f);
-
- // Initialize tower clocks
- aTowerClocks[0].Init(CVector(59.4f, -1081.3f, 54.15f), -1.0f, 0.0f, 0, 0, 0, 80.0f, 2.0f);
- aTowerClocks[1].Init(CVector(55.4f, -1083.6f, 54.15f), 0.0f, -1.0f, 0, 0, 0, 80.0f, 2.0f);
-
- // Initialize digital clocks
- CVector2D sz(3.7f, 2.144f);
- sz.Normalise();
- aDigitalClocks[0].Init(
- CVector(54.485f - sz.x * 0.05f + sz.y * 0.3f, -1081.679f - sz.y * 0.05f - sz.x * 0.3f, 32.803f),
- sz.y, -sz.x, 255, 0, 0, 100.0f, 0.8f
- );
- aDigitalClocks[1].Init(
- CVector(60.564f + sz.x * 0.05f - sz.y * 0.3f, -1083.089f + sz.y * 0.05f + sz.x * 0.3f, 32.803f),
- -sz.y, sz.x, 0, 0, 255, 100.0f, 0.8f
- );
- aDigitalClocks[2].Init(
- CVector(58.145f - sz.y * 0.05f - sz.x * 0.3f, -1079.268f + sz.x * 0.05f - sz.y * 0.3f, 32.803f),
- -sz.x, -sz.y, 0, 255, 0, 100.0f, 0.8f
- );
+
+ for (int32 i = 0; i < NUMMOVINGTHINGS; i++) {
+ aMovingThings[i].m_nType = 0;
+ aMovingThings[i].m_farAway = 0;
+ }
+
+ for (int i = 0; i < NUMSECTORS_X; i++) {
+ for (int j = 0; j < NUMSECTORS_Y; j++) {
+ for (CPtrNode *pNode = CWorld::GetSector(i, j)->m_lists[ENTITYLIST_BUILDINGS].first; pNode; pNode = pNode->next) {
+ CEntity *pEntity = (CEntity *)pNode->item;
+ PossiblyAddThisEntity(pEntity);
+ }
+ }
+ }
+
+ for (int32 i = 0; i < NUM_LEVELS; i++) {
+ for (CPtrNode *pNode = CWorld::GetBigBuildingList((eLevelName)i).first; pNode; pNode = pNode->next) {
+ CEntity *pEntity = (CEntity *)pNode->item;
+ PossiblyAddThisEntity(pEntity);
+ }
+ }
+
+ CEscalators::Init();
+ aScrollBars[0].Init(CVector(-1069.209f, 1320.126f, 18.848f), CVector(-1069.209f, 1342.299f, 22.612f), SCROLL_ARENA_STRING, 128, 255, 0, 0.3f);
}
void CMovingThings::Shutdown()
{
- int i;
- for (i = 0; i < ARRAY_SIZE(aScrollBars); ++i)
- aScrollBars[i].SetVisibility(false);
- for (i = 0; i < ARRAY_SIZE(aTowerClocks); ++i)
- aTowerClocks[i].SetVisibility(false);
- for (i = 0; i < ARRAY_SIZE(aDigitalClocks); ++i)
- aDigitalClocks[i].SetVisibility(false);
+
+ aScrollBars[0].SetVisibility(false);
+ CEscalators::Shutdown();
}
void CMovingThings::Update()
{
+ CPlaneBanners::Update();
+ CPlaneTrails::Update();
+ CEscalators::Update();
+
+ const int TIME_SPAN = 8; // frames to process all aMovingThings
+
int16 i;
-#ifndef SQUEEZE_PERFORMANCE
- const int TIME_SPAN = 64; // frames to process all aMovingThings
int block = CTimer::GetFrameCounter() % TIME_SPAN;
for (i = (block * NUMMOVINGTHINGS) / TIME_SPAN; i < ((block + 1) * NUMMOVINGTHINGS) / TIME_SPAN; i++) {
- if (aMovingThings[i].m_nHidden == 1)
+ if (aMovingThings[i].m_farAway == 1)
aMovingThings[i].Update();
}
for (i = 0; i < CMovingThings::Num; i++) {
- if (aMovingThings[i].m_nHidden == 0)
+ if (aMovingThings[i].m_farAway == 0)
aMovingThings[i].Update();
}
-#endif
for (i = 0; i < ARRAY_SIZE(aScrollBars); ++i)
{
if (aScrollBars[i].IsVisible() || (CTimer::GetFrameCounter() + i) % 8 == 0)
aScrollBars[i].Update();
}
- for (i = 0; i < ARRAY_SIZE(aTowerClocks); ++i)
- {
- if (aTowerClocks[i].IsVisible() || (CTimer::GetFrameCounter() + i) % 8 == 0)
- aTowerClocks[i].Update();
- }
- for (i = 0; i < ARRAY_SIZE(aDigitalClocks); ++i)
- {
- if (aDigitalClocks[i].IsVisible() || (CTimer::GetFrameCounter() + i) % 8 == 0)
- aDigitalClocks[i].Update();
- }
}
void CMovingThings::Render()
{
- int i;
PUSH_RENDERGROUP("CMovingThings::Render");
+ CSmokeTrails::Update();
+
+ int i;
for (i = 0; i < ARRAY_SIZE(aScrollBars); ++i)
{
if (aScrollBars[i].IsVisible())
aScrollBars[i].Render();
}
- for (i = 0; i < ARRAY_SIZE(aTowerClocks); ++i)
- {
- if (aTowerClocks[i].IsVisible())
- aTowerClocks[i].Render();
+
+ CPlaneTrails::Render();
+ CSmokeTrails::Render();
+ CPlaneBanners::Render();
+ POP_RENDERGROUP();
+}
+
+void CMovingThings::RegisterOne(CEntity *pEnt, uint16 nType) {
+ if (Num >= NUMMOVINGTHINGS)
+ return;
+
+ aMovingThings[Num].m_pEntity = pEnt;
+ aMovingThings[Num].m_nType = nType;
+ aMovingThings[Num].m_farAway = 0;
+ aMovingThings[Num].m_vecPosn = pEnt->GetPosition();
+ aMovingThings[Num].AddToList(&CMovingThings::StartCloseList);
+ Num++;
+}
+
+void CMovingThings::PossiblyAddThisEntity(CEntity *pEnt) {
+ if (pEnt->GetModelIndex() == MI_LIGHTBEAM) {
+ RegisterOne(pEnt, 1);
}
- for (i = 0; i < ARRAY_SIZE(aDigitalClocks); ++i)
- {
- if (aDigitalClocks[i].IsVisible())
- aDigitalClocks[i].Render();
+ else if (pEnt->GetModelIndex() == MI_AIRPORTRADAR) {
+ RegisterOne(pEnt, 2);
+ }
+ else if (pEnt->GetModelIndex() == MI_MALLFAN || pEnt->GetModelIndex() == MI_HOTELFAN_NIGHT
+ || pEnt->GetModelIndex() == MI_HOTELFAN_DAY || pEnt->GetModelIndex() == MI_HOTROOMFAN) {
+ RegisterOne(pEnt, 3);
+ }
+ else if (pEnt->GetModelIndex() == MI_BLIMP_NIGHT || pEnt->GetModelIndex() == MI_BLIMP_DAY) {
+ RegisterOne(pEnt, 4);
}
- POP_RENDERGROUP();
}
// ---------- CMovingThing ----------
+static float maxUpdateDists[5] = { 100.0f, 1500.0f, 400.0f, 100.0f, 2000.0f };
+
void CMovingThing::Update()
{
+ switch (m_nType) {
+ case 1: {
+ float angle = (CTimer::GetTimeInMilliseconds() % 0x3FFF) * TWOPI / 0x3FFF;
+ float s = Sin(angle);
+ float c = Cos(angle);
+ m_pEntity->GetRight() = CVector(-s, c, 0.0f);
+ m_pEntity->GetForward() = CVector(0.0f, 0.0f, 1.0f);
+ m_pEntity->GetUp() = CVector(c, s, 0.0f);
+
+ if (CClock::GetHours() >= 20 || CClock::GetHours() < 5) {
+ if (Abs(TheCamera.GetPosition().x - m_pEntity->GetPosition().x) < 600.0f &&
+ Abs(TheCamera.GetPosition().y - m_pEntity->GetPosition().y) < 600.0f) {
+ CVector delta = m_pEntity->GetPosition() - TheCamera.GetPosition();
+ delta /= delta.Magnitude();
+
+ if (DotProduct(delta, CVector(c, s, 0.0f)) < -0.92f) {
+ CVector coors = m_pEntity->GetPosition() - 10.0f * delta;
+ CCoronas::RegisterCorona(43, 128, 128, 100, 255, coors, 70.0f, 600.0f, 0.0f, CCoronas::TYPE_STAR, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
+ }
+ }
+ }
+ }
+ break;
+ case 2: {
+ float angle = (CTimer::GetTimeInMilliseconds() % 0x7FF) * TWOPI / 0x7FF;
+ float s = Sin(angle);
+ float c = Cos(angle);
+ m_pEntity->GetRight() = CVector(c, s, 0.0f);
+ m_pEntity->GetForward() = CVector(-s, c, 0.0f);
+ m_pEntity->GetUp() = CVector(0.0f, 0.0f, 1.0f);
+ }
+ break;
+ case 3: {
+ float angle = (CTimer::GetTimeInMilliseconds() % 0x3FF) * TWOPI / 0x3FF;
+ float s = Sin(angle);
+ float c = Cos(angle);
+ m_pEntity->GetRight() = CVector(c, s, 0.0f);
+ m_pEntity->GetForward() = CVector(-s, c, 0.0f);
+ m_pEntity->GetUp() = CVector(0.0f, 0.0f, 1.0f);
+ }
+ break;
+ case 4: {
+ float angle = (CTimer::GetTimeInMilliseconds() % 0x3FFFF) * TWOPI / 0x3FFFF;
+ float s = Sin(angle);
+ float c = Cos(angle);
+ m_pEntity->GetRight() = CVector(-c, -s, 0.0f);
+ m_pEntity->GetForward() = CVector(s, -c, 0.0f);
+ m_pEntity->GetUp() = CVector(0.0f, 0.0f, 1.0f);
+ m_pEntity->SetPosition(CVector(350.0f * c - 465.0f, 350.0f * s + 1163.0f, 260.0f));
+ }
+ break;
+ default:
+ break;
+ }
+
m_pEntity->GetMatrix().UpdateRW();
m_pEntity->UpdateRwFrame();
- if (SQR(m_pEntity->GetPosition().x - TheCamera.GetPosition().x) + SQR(m_pEntity->GetPosition().y - TheCamera.GetPosition().y) < 40000.0f) {
- if (m_nHidden == 1) {
+ if (SQR(m_pEntity->GetPosition().x - TheCamera.GetPosition().x) + SQR(m_pEntity->GetPosition().y - TheCamera.GetPosition().y) < SQR(maxUpdateDists[m_nType])) {
+ if (m_farAway == 1) {
AddToList(&CMovingThings::StartCloseList);
- m_nHidden = 0;
+ m_farAway = 0;
}
- } else {
- if (m_nHidden == 0) {
+ }
+ else {
+ if (m_farAway == 0) {
RemoveFromList();
- m_nHidden = 1;
+ m_farAway = 1;
}
}
}
@@ -254,29 +614,6 @@ int16 CMovingThing::SizeList()
return count;
}
-// ---------- Find message functions ----------
-const char* FindTunnelMessage()
-{
- if (CStats::CommercialPassed)
- return "LIBERTY TUNNEL HAS BEEN OPENED TO ALL TRAFFIC . . . ";
-
- if (CStats::IndustrialPassed)
- return "FIRST PHASE LIBERTY TUNNEL HAS BEEN COMPLETED . . . ";
-
- return "FIRST PHASE LIBERTY TUNNEL ABOUT TO BE COMPLETED . . . ";
-}
-
-const char* FindBridgeMessage()
-{
- if (CStats::CommercialPassed)
- return "STAUNTON LIFT BRIDGE IS OPERATIONAL AGAIN ";
-
- if (CStats::IndustrialPassed)
- return "LONG DELAYS BEHIND US AS CALLAHAN BRIDGE IS FIXED . . . STAUNTON LIFT BRIDGE STUCK OPEN ";
-
- return "CHAOS AS CALLAHAN BRIDGE IS UNDER REPAIR. . . ";
-}
-
char String_Time[] = "THE TIME IS 12:34 ";
const char* FindTimeMessage()
{
@@ -287,49 +624,23 @@ const char* FindTimeMessage()
return String_Time;
}
-char String_DigitalClock[] = "12:34";
-const char* FindDigitalClockMessage()
-{
- if (((CTimer::GetTimeInMilliseconds() >> 10) & 7) < 6)
- {
- String_DigitalClock[0] = '0' + CClock::GetHours() / 10;
- String_DigitalClock[1] = '0' + CClock::GetHours() % 10;
- String_DigitalClock[2] = CTimer::GetTimeInMilliseconds() & 0x200 ? ':' : ' ';
- String_DigitalClock[3] = '0' + CClock::GetMinutes() / 10;
- String_DigitalClock[4] = '0' + CClock::GetMinutes() % 10;
- }
- else
- {
- // they didn't use rad2deg here because of 3.14
- int temperature = 13.0f - 6.0f * Cos((CClock::GetMinutes() + 60.0f * CClock::GetHours()) / (4.0f * 180.0f / 3.14f) - 1.0f);
- String_DigitalClock[0] = '0' + temperature / 10;
- if (String_DigitalClock[0] == '0')
- String_DigitalClock[0] = ' ';
- String_DigitalClock[1] = '0' + temperature % 10;
- String_DigitalClock[2] = ' ';
- String_DigitalClock[3] = '@';
- String_DigitalClock[4] = 'C';
- }
- return String_DigitalClock;
-}
-
// ---------- CScrollBar ----------
-void CScrollBar::Init(CVector position, uint8 type, float sizeX, float sizeY, float sizeZ, uint8 red, uint8 green, uint8 blue, float scale)
+void CScrollBar::Init(CVector pos1, CVector pos2, uint8 type, uint8 red, uint8 green, uint8 blue, float scale)
{
for (int i = 0; i < ARRAY_SIZE(m_MessageBar); ++i)
m_MessageBar[i] = 0;
m_pMessage = ". ";
m_MessageCurrentChar = 0;
- m_MessageLength = 2;
+ m_MessageLength = strlen(m_pMessage);
m_Counter = 0;
m_bVisible = false;
- m_Position = position;
+ m_Position = pos1;
m_Type = type;
- m_Size.x = sizeX;
- m_Size.y = sizeY;
- m_Size.z = sizeZ;
+ m_Size.x = (pos2.x - pos1.x) * 0.025f;
+ m_Size.y = (pos2.y - pos1.y) * 0.025f;
+ m_Size.z = (pos2.z - pos1.z) * 0.2f;
m_uRed = red;
m_uGreen = green;
m_uBlue = blue;
@@ -358,263 +669,48 @@ void CScrollBar::Update()
if (m_Counter == 0 && ++m_MessageCurrentChar >= m_MessageLength)
{
const char* previousMessage = m_pMessage;
- switch (m_Type)
- {
- case SCROLL_BUSINESS:
- while (previousMessage == m_pMessage)
- {
- switch (CGeneral::GetRandomNumber() % 7)
- {
- case 0:
- m_pMessage = "SHARES UYE<10% DWD<20% NDWE>22% . . . ";
- break;
- case 1:
- m_pMessage = "CRIME WAVE HITS LIBERTY CITY . . . ";
- break;
- case 2:
- m_pMessage = "SHARES OBR>29% MADD<76% LEZ<11% ADAMSKI>53% AAG>110%. . . ";
- break;
- case 3:
- m_pMessage = FindTunnelMessage();
- break;
- case 4:
- m_pMessage = FindBridgeMessage();
- break;
- case 5:
- m_pMessage = FindTimeMessage();
- break;
- case 6:
- if (CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_FRENCH || CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_GERMAN)
- m_pMessage = FindTimeMessage();
- else
- m_pMessage = "WWW.GRANDTHEFTAUTO3.COM ";
- break;
- }
- }
- break;
- case SCROLL_TRAFFIC:
- while (previousMessage == m_pMessage)
- {
- switch (CGeneral::GetRandomNumber() % 8)
- {
- case 0:
- m_pMessage = "DRIVE CAREFULLY . . . ";
- break;
- case 1:
- m_pMessage = "RECENT WAVE OF CARJACKINGS. KEEP YOUR DOORS LOCKED !!! ";
- break;
- case 2:
- m_pMessage = "CHECK YOUR SPEED . . . ";
- break;
- case 3:
- m_pMessage = "KEEP YOUR EYES ON THE ROAD AND NOT ON THIS SIGN ";
- break;
- case 4:
- if (CWeather::Foggyness > 0.5f)
- m_pMessage = "POOR VISIBILITY ! ";
- else if (CWeather::WetRoads > 0.5f)
- m_pMessage = "ROADS ARE SLIPPERY ! ";
- else
- m_pMessage = "ENJOY YOUR TRIP ";
- break;
- case 5:
- m_pMessage = FindTunnelMessage();
- break;
- case 6:
- m_pMessage = FindBridgeMessage();
- break;
- case 7:
- m_pMessage = FindTimeMessage();
- break;
- }
- }
- break;
- case SCROLL_ENTERTAINMENT:
- while (previousMessage == m_pMessage)
- {
- switch (CGeneral::GetRandomNumber() % 12)
- {
- case 0:
- m_pMessage = " )69TH STREET) STILL HOLDS TOP POSITION THIS MONTH AT THE BOX-OFFICE WITH )MY FAIR LADYBOY) JUST CREEPING UP BEHIND. ";
- break;
- case 1:
- m_pMessage = " TALKING OF )FANNIE). THERE IS STILL TIME TO CATCH THIS LOVELY FAMILY MUSICAL, ABOUT THE ORPHAN WHO IS SO EASILY TAKEN IN BY ANY MAN WITH LOADS OF MONEY. ";
- break;
- case 2:
- m_pMessage = " DO NOT MISS )GTA3, THE MUSICAL) . . . ";
- break;
- case 3:
- m_pMessage =
- " STILL RUNNING ARE )RATS) AND )GUYS AND DOGS), BETWEEN THEN THEY SHOULD HAVE THE LEGS TO LAST TILL THE AND OF THE YEAR. . . "
- " ALSO FOR FOUR LEGGED FANS, THE STAGE VERSION OF THE GRITTY REALISTIC )SATERDAY NIGHT BEAVER) OPENED LAST WEEKEND,"
- " AND I FOR ONE CERTAINLY ENJOYED THAT. ";
- break;
- case 4:
- m_pMessage =
- " NOW SHOWING STATE-WIDE, ARNOLD STEELONE, HOLLYWOODS BEST LIVING SPECIAL EFFECT, APPEARS AGAIN AS A HALF_MAN,"
- " HALF ANDROID IN THE HALF-BAKED ROMP, )TOP DOWN CITY). AN HOMAGE TO HIS EARLIER TWO MULTI_MILLION MAKING MOVIES,"
- " IN WHICH HE PLAYED TWO-DEE, AN OUT OF CONTROL MONSTER, INTENT ON CORRUPTING CIVILISATION! ";
- break;
- case 5:
- m_pMessage =
- " ALSO APPEARING THIS WEEK )HALF-COCKED) SEES CHUCK SCHWARTZ UP TO HIS USUAL NONSENSE AS HE TAKES ON HALF OF LIBERTY CITY"
- " IN AN ATTEMPT TO SAVE HIS CROSS-DRESSING LADY-BOY SIDEKICK, )MISS PING-PONG), FROM A GANG OF RUTHLESS COSMETIC SURGEONS. ";
- break;
- case 6:
- m_pMessage =
- " STILL SHOWING: )SOLDIERS OF MISFORTUNE), ATTROCIOUS ACTING WHICH SEES BOYZ 2 GIRLZ) TRANSITION FROM THE CHARTS TO THE BIG SCREEN,"
- " AT LEAST THEY ALL DIE AT THE END. . . ";
- break;
- case 7:
- m_pMessage =
- " )BADFELLAS) IS STILL GOING STRONG WITH CROWDS ALMOST BEING PUSHED INTO CINEMAS TO SEE THIS ONE."
- " ANOTHER ONE WORTH LOOKING INTO IS )THE TUNNEL). ";
- break;
- case 8:
- m_pMessage = FindTunnelMessage();
- break;
- case 9:
- m_pMessage = FindBridgeMessage();
- break;
- case 10:
- m_pMessage = FindTimeMessage();
- break;
- case 11:
- m_pMessage = "WWW.ROCKSTARGAMES.COM ";
- break;
- }
- }
- break;
- case SCROLL_AIRPORT_DOORS:
- while (previousMessage == m_pMessage)
- {
- switch (CGeneral::GetRandomNumber() % 4)
- {
- case 0:
- m_pMessage = "WELCOME TO LIBERTY CITY . . . ";
- break;
- case 1:
- m_pMessage = "PLEASE HAVE YOUR PASSPORT READY . . . ";
- break;
- case 2:
- m_pMessage = "PLACE KEYS, FIREARMS, CHANGE AND OTHER METAL OBJECTS ON THE TRAY PLEASE . . . ";
- break;
- case 3:
- m_pMessage = FindTimeMessage();
- break;
- }
- }
- break;
- case SCROLL_AIRPORT_FRONT:
+ if (m_Type == SCROLL_ARENA_STRING) {
while (previousMessage == m_pMessage)
{
switch (CGeneral::GetRandomNumber() % 4)
{
case 0:
- m_pMessage = "WELCOME TO FRANCIS INTERNATIONAL AIRPORT . . . ";
+ switch (TonightsEvent) {
+ case 0:
+ m_pMessage = "MAIN EVENT TONIGHT: CAR RACING . . . ";
+ break;
+ case 1:
+ m_pMessage = "MAIN EVENT TONIGHT: DESTRUCTION DERBY . . . ";
+ break;
+ case 2:
+ m_pMessage = "MAIN EVENT TONIGHT: BIKE RACING . . . ";
+ break;
+ }
break;
case 1:
- m_pMessage = "PLEASE DO NOT LEAVE LUGGAGE UNATTENDED . . . ";
+ switch (TonightsEvent) {
+ case 0:
+ m_pMessage = "FOR TICKETS TO THE HOT RING EVENT CALL 555-3764 . . . ";
+ break;
+ case 1:
+ m_pMessage = "FOR TICKETS TO THE BLOOD RING EVENT CALL 555-3765 . . . ";
+ break;
+ case 2:
+ m_pMessage = "FOR TICKETS TO THE DIRT RING EVENT CALL 555-3766 . . . ";
+ break;
+ }
break;
case 2:
- m_pMessage = "FOLLOW 1 FOR LONG AND SHORT TERM PARKING ";
+ m_pMessage = "HYMAN MEMORIAL STADIUM. HOME TO SOME OF THE BIGGEST EVENTS OF"
+ " THE WESTERN HEMISPHERE. ALSO AVAILABLE FOR CHILDREN PARTIES. . . ";
break;
case 3:
m_pMessage = FindTimeMessage();
break;
- }
- }
- break;
- case SCROLL_STORE:
- while (previousMessage == m_pMessage)
- {
- switch (CGeneral::GetRandomNumber() % 10)
- {
- case 0:
- m_pMessage = "WWW.ROCKSTARGAMES.COM ";
- break;
- case 1:
- m_pMessage = "GTA3 OUT NOW . . . ";
- break;
- case 2:
- m_pMessage = "OUR STUFF IS CHEAP CHEAP CHEAP ";
- break;
- case 3:
- m_pMessage = "BUY 12 CDS GET ONE FREE . . . ";
- break;
- case 4:
- m_pMessage = "APPEARING IN SHOP SOON, )THE BLOODY CHOPPERS), WITH THEIR NEW ALBUM, )IS THAT MY DAUGHTER?) ";
- break;
- case 5:
- m_pMessage = "THIS MONTH IS OUR CRAZY CLEAROUT MONTH, EVERYTHING MUST GO, CDS, DVDS, STAFF, EVEN OUR CARPETS! ";
- break;
- case 6:
- m_pMessage =
- "OUT THIS WEEK: THE THEME TUNE TO )BOYS TO GIRLS) FIRST MOVIE )SOLDIERS OF MISFORTUNE), "
- "THE SINGLE )LET ME IN YOU)RE BODY-BAG) IS TAKEN FROM THE SOUNDTRACK ALBUM, )BOOT CAMP BOYS). "
- "ALSO INCLUDES THE SMASH SINGLE, )PRAY IT GOES OK). ";
- break;
- case 7:
- m_pMessage =
- "ALBUMS OUT THIS WEEK: MARYDANCING, )MUTHA O) CHRIST), FEATURING THE SINGLE )WASH HIM OFF), "
- "ALSO CRAIG GRAYS) DEBUT, )FADE AWAY), INCLUDES THE SINGLE OF THE SAME NAME. . . ";
- break;
- case 8:
- m_pMessage =
- "ON THE FILM FRONT, A NELY COMPILED COMPILATION OF ARNOLD STEELONES GREATEST MOVIES ON DVD. "
- "THE PACK INCLUDES THE EARLY )BY-CEP), THE CULT CLASSIC )FUTURE ANNHILATOR), AND THE HILARIOUS CROSS-DRESSING COMEDY )SISTERS). "
- "ONE FOR ALL THE FAMILY. . . ";
- break;
- case 9:
- m_pMessage = FindTimeMessage();
+ default:
break;
}
}
- break;
- case SCROLL_USED_CARS:
- while (previousMessage == m_pMessage)
- {
- switch (CGeneral::GetRandomNumber() % 11)
- {
- case 0:
- m_pMessage = "QUICK, TAKE A LOOK AT OUR CURRENT STOCK )CAUSE THESE AUTOS ARE MOVIN) FAST . . . ";
- break;
- case 1:
- m_pMessage = "THAT)S RIGHT, HERE AT )CAPITAL AUTO SALES) OUR VEHICLES ARE SO GOOD THAT THEY PRACTICALLY DRIVE THEMSELVES OFF OUR LOT . . . ";
- break;
- case 2:
- m_pMessage = "EASY CREDIT ON ALL CARS . . . ";
- break;
- case 3:
- m_pMessage = "FEEL LIKE A STUD IN ONE OF OUR STALLIONS OR TEST-DRIVE OUR BANSHEE, IT)S A REAL STEAL!!! ";
- break;
- case 4:
- m_pMessage = "TRY OUR HARDY PERENNIAL, IT)LL LAST YOU THE WHOLE YEAR. OUR BOBCATS AIN)T NO PUSSIES EITHER!!! ";
- break;
- case 5:
- m_pMessage = "IF IT)S A GUARANTEE YOU'RE AFTER, GO SOMEWHERE ELSE, )CAPITAL) CARS ARE THAT GOOD THEY DON)T NEED GUARANTEES!!! ";
- break;
- case 6:
- m_pMessage = "TOP DOLLAR OFFERED FOR YOUR OLD WHEELS, NOT YOUR CAR, JUST IT)S WHEELS. . . ";
- break;
- case 7:
- m_pMessage = "THAT)S RIGHT WE)RE CAR SILLY. TEST DRIVE ANY CAR, YOU WON)T WANT TO BRING IT BACK!!! ";
- break;
- case 8:
- m_pMessage = "FREE FLUFFY DICE WITH ALL PURCHASES. . .";
- break;
- case 9:
- if (CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_FRENCH || CMenuManager::m_PrefsLanguage == CMenuManager::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 ";
- break;
- case 10:
- m_pMessage = FindTimeMessage();
- break;
- }
- }
- break;
}
m_MessageLength = (uint32)strlen(m_pMessage);
@@ -699,172 +795,570 @@ void CScrollBar::Render()
CSprite::FlushSpriteBuffer();
}
-// ---------- CTowerClock ----------
-void CTowerClock::Init(CVector position, float sizeX, float sizeY, uint8 red, uint8 green, uint8 blue, float drawDistance, float scale)
-{
- m_bVisible = false;
- m_Position = position;
- m_Size.x = sizeX;
- m_Size.y = sizeY;
- m_Size.z = 0.0f;
- m_uRed = red;
- m_uGreen = green;
- m_uBlue = blue;
- m_fDrawDistance = drawDistance;
- m_fScale = scale;
-}
-
-void CTowerClock::Update()
-{
- float distanceFromCamera = (TheCamera.GetPosition() - m_Position).Magnitude();
- if (distanceFromCamera < m_fDrawDistance)
- {
- m_bVisible = true;
- if (distanceFromCamera < 0.75f * m_fDrawDistance)
- m_fIntensity = 1.0f;
- else
- m_fIntensity = 1.0f - (distanceFromCamera - 0.75f * m_fDrawDistance) * 4.0f / m_fDrawDistance;
+void
+CSmokeTrail::RegisterPoint(CVector regPosition, float opacity) {
+ bool bAddedNewPoint = false;
+
+ if (m_time[0] && CTimer::GetTimeInMilliseconds() - m_time[0] > 150) {
+ bAddedNewPoint = true;
+ for (int32 i = 15; i > 0; i--) {
+ m_pos[i] = m_pos[i - 1];
+ m_time[i] = m_time[i - 1];
+ m_opacity[i] = m_opacity[i - 1];
+ }
+ ++m_seed;
}
- else
- m_bVisible = false;
+ m_pos[0] = regPosition;
+
+ if (bAddedNewPoint || !m_time[0]) {
+ m_time[0] = CTimer::GetTimeInMilliseconds();
+ float density = 0.1f / (m_pos[1] - m_pos[2]).Magnitude();
+ m_opacity[1] = opacity * Min(density, 1.0f);
+ }
+ m_opacity[0] = 0.0f;
}
-RwIm3DVertex TempV[4];
-void CTowerClock::Render()
-{
- if (TheCamera.IsSphereVisible(m_Position, m_fScale))
- {
- // Calculate angle for each clock index
- float angleHour = 2.0f * (float)PI * (CClock::GetMinutes() + 60.0f * CClock::GetHours()) / 720.0f;
- float angleMinute = 2.0f * (float)PI * (CClock::GetSeconds() + 60.0f * CClock::GetMinutes()) / 3600.0f;
+void
+CSmokeTrail::Init(int num) {
+ for (int32 i = 0; i < 16; i++)
+ m_time[i] = 0;
+ m_seed = num * 2;
+}
+
+void
+CSmokeTrails::Init(void) {
+ for (int32 i = 0; i < 3; i++)
+ aSmoke[i].Init(i);
+}
+
+void
+CSmokeTrails::Render(void) {
+ for (int32 i = 0; i < 3; i++)
+ aSmoke[i].Render();
+}
+
+void
+CSmokeTrail::Render(void) {
+ int numVerts = 0;
+
+ if (TheCamera.IsSphereVisible(m_pos[0], 10.0f)) {
+ for (int32 i = 0; i < 16; i++) {
+ int timeSinceSpawned = CTimer::GetTimeInMilliseconds() - m_time[i];
+
+ if (timeSinceSpawned > 2250)
+ m_time[i] = 0;
+
+ if (m_time[i]) {
+ int alpha = (1.0f - timeSinceSpawned / 2250.0f) * 110.0f * m_opacity[i];
+ float offset = timeSinceSpawned * CWeather::Wind * 0.0001f;
+ float posX = (m_pos[i].x + timeSinceSpawned * RandomSmoke[(i - m_seed) & 0xF] * 0.00001f) - offset;
+ float posY = (m_pos[i].y + timeSinceSpawned * RandomSmoke[(i - m_seed + 5) & 0xF] * 0.00001f) - offset;
+ float posZ = m_pos[i].z + timeSinceSpawned * 0.0004f;
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[i], 200, 200, 200, alpha);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[i], posX, posY, posZ);
+ numVerts++;
+ }
+ }
+ }
- // Prepare render states
- RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
- RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
+ if (numVerts > 1) {
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
- RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
- RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
- RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR);
- RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
-
- // Set vertices colors
- RwIm3DVertexSetRGBA(&TempV[0], m_uRed, m_uGreen, m_uBlue, (uint8)(m_fIntensity * 255.0f));
- RwIm3DVertexSetRGBA(&TempV[1], m_uRed, m_uGreen, m_uBlue, (uint8)(m_fIntensity * 255.0f));
- RwIm3DVertexSetRGBA(&TempV[2], m_uRed, m_uGreen, m_uBlue, (uint8)(m_fIntensity * 255.0f));
- RwIm3DVertexSetRGBA(&TempV[3], m_uRed, m_uGreen, m_uBlue, (uint8)(m_fIntensity * 255.0f));
-
- // Set vertices position
- RwIm3DVertexSetPos(&TempV[0], m_Position.x, m_Position.y, m_Position.z);
- RwIm3DVertexSetPos(
- &TempV[1],
- m_Position.x + Sin(angleMinute) * m_fScale * m_Size.x,
- m_Position.y + Sin(angleMinute) * m_fScale * m_Size.y,
- m_Position.z + Cos(angleMinute) * m_fScale
- );
- RwIm3DVertexSetPos(&TempV[2], m_Position.x, m_Position.y, m_Position.z);
- RwIm3DVertexSetPos(
- &TempV[3],
- m_Position.x + Sin(angleHour) * 0.75f * m_fScale * m_Size.x,
- m_Position.y + Sin(angleHour) * 0.75f * m_fScale * m_Size.y,
- m_Position.z + Cos(angleHour) * 0.75f * m_fScale
- );
-
- LittleTest();
-
- // Draw lines
- if (RwIm3DTransform(TempV, 4, nil, 0))
- {
- RwIm3DRenderLine(0, 1);
- RwIm3DRenderLine(2, 3);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
+
+ if (RwIm3DTransform(TempBufferRenderVertices, numVerts, nil, rwIM3D_VERTEXXYZ | rwIM3D_VERTEXRGBA)) {
+ RwIm3DRenderIndexedPrimitive(rwPRIMTYPEPOLYLINE, SmokeTrailIndices, 2 * (numVerts - 1));
RwIm3DEnd();
}
}
}
-// ---------- CDigitalClock ----------
-void CDigitalClock::Init(CVector position, float sizeX, float sizeY, uint8 red, uint8 green, uint8 blue, float drawDistance, float scale)
-{
- m_bVisible = false;
- m_Position = position;
- m_Size.x = sizeX;
- m_Size.y = sizeY;
- m_Size.z = 0.0f;
- m_uRed = red;
- m_uGreen = green;
- m_uBlue = blue;
- m_fDrawDistance = drawDistance;
- m_fScale = scale;
-}
-
-void CDigitalClock::Update()
-{
- float distanceFromCamera = (TheCamera.GetPosition() - m_Position).Magnitude();
- if (distanceFromCamera < m_fDrawDistance)
- {
- m_bVisible = true;
- if (distanceFromCamera < 0.75f * m_fDrawDistance)
- m_fIntensity = 1.0f;
- else
- m_fIntensity = 1.0f - (distanceFromCamera - 0.75f * m_fDrawDistance) * 4.0f / m_fDrawDistance;
+void
+CSmokeTrails::Update(void) {
+
+ if (!CSmokeTrails::CigOn || TheCamera.Using1stPersonWeaponMode() || !FindPlayerPed() ||
+ FindPlayerVehicle() || CCutsceneMgr::IsRunning() || !FindPlayerPed()->GetClump())
+ return;
+
+ RwV3d startPos = { 0.026f, 0.15f, 0.02f };
+ RwV3d endPos = { 0.026f, 0.05f, 0.02f };
+
+ RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(FindPlayerPed()->GetClump());
+ int32 idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_HEAD));
+ RwMatrix *head = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwV3dTransformPoints(&startPos, &startPos, 1, head);
+ RwV3dTransformPoints(&endPos, &endPos, 1, head);
+
+ aSmoke[0].RegisterPoint(startPos, 1.0f);
+ aSmoke[1].RegisterPoint(startPos, 0.75f);
+ aSmoke[2].RegisterPoint(startPos, 0.5f);
+
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
+
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[0], 255, 255, 255, 255);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[0], startPos.x, startPos.y, startPos.z);
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[1], 255, 255, 255, 255);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[1], endPos.x, endPos.y, endPos.z);
+
+ if (RwIm3DTransform(TempBufferRenderVertices, 2, nil, rwIM3D_VERTEXXYZ | rwIM3D_VERTEXRGBA)) {
+ RwIm3DRenderIndexedPrimitive(rwPRIMTYPEPOLYLINE, SmokeTrailIndices, 2);
+ RwIm3DEnd();
}
- else
- m_bVisible = false;
}
-void CDigitalClock::Render()
-{
- if (TheCamera.IsSphereVisible(m_Position, 5.0f * m_fScale))
- {
- CSprite::InitSpriteBuffer();
+CEscalator CEscalators::aEscalators[NUM_ESCALATORS];
+int32 CEscalators::NumEscalators;
- // Simulate flicker
- float currentIntensity = m_fIntensity * CGeneral::GetRandomNumberInRange(0x300, 0x400) / 1024.0f;
+CEscalator::CEscalator() {
+ m_bIsActive = false;
- uint8 r = currentIntensity * m_uRed;
- uint8 g = currentIntensity * m_uGreen;
- uint8 b = currentIntensity * m_uBlue;
+ for (int i = 0; i < 24; i++) {
+ m_pSteps[i] = nil;
+ }
+}
- // Set render states
- RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
- RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
- RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
- RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
- RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR);
- RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[0]));
- RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
+void
+CEscalator::AddThisOne(CVector pos0, CVector pos1, CVector pos2, CVector pos3, bool b_isMovingDown) {
+ m_pos0 = pos0;
+ m_pos1 = pos1;
+ m_pos2 = pos2;
+ m_pos3 = pos3;
- const char* clockMessage = FindDigitalClockMessage();
+ float escalatorStepHeight = CModelInfo::GetColModel(MI_ESCALATORSTEP)->boundingBox.max.z;
+ m_pos0.z -= escalatorStepHeight;
+ m_pos1.z -= escalatorStepHeight;
+ m_pos2.z -= escalatorStepHeight;
+ m_pos3.z -= escalatorStepHeight;
- CVector coronaCoord, screenCoord;
- float screenW, screenH;
- for (int c = 0; c < 5; ++c) // for each char to be displayed
- {
- for (int i = 0; i < 5; ++i) // for each column of coronas
- {
- for (int j = 0; j < 5; ++j) // for each row of coronas
- {
- if (ScrollCharSet[clockMessage[c] - ' '][i] & (1 << j))
- {
- coronaCoord.x = m_Position.x + (8 * c + i) * m_Size.x * m_fScale / 8.0f;
- coronaCoord.y = m_Position.y + (8 * c + i) * m_Size.y * m_fScale / 8.0f;
- coronaCoord.z = m_Position.z + j * m_fScale / 8.0f;
-
- if (CSprite::CalcScreenCoors(coronaCoord, &screenCoord, &screenW, &screenH, true))
- {
- CSprite::RenderBufferedOneXLUSprite(
- screenCoord.x, screenCoord.y, screenCoord.z,
- screenW * m_fScale * 0.12f,
- screenW * m_fScale * 0.12f,
- r, g, b,
- 255,
- 1.0f / screenCoord.z,
- 255);
- }
+ float magnitudes[3];
+ magnitudes[0] = (m_pos0 - m_pos1).Magnitude();
+ magnitudes[1] = (m_pos1 - m_pos2).Magnitude();
+ magnitudes[2] = (m_pos2 - m_pos3).Magnitude();
+
+ float length = magnitudes[0] + magnitudes[1] + magnitudes[2];
+
+ m_lowerEnd = magnitudes[0] / length;
+ m_upperEnd = (magnitudes[0] + magnitudes[1]) / length;
+
+ m_stepsCount = Min(24.0f, length / 0.6f);
+
+ CVector direction(m_pos0.x - m_pos1.x, m_pos0.y - m_pos1.y, 0.0f);
+ direction.Normalise();
+
+ m_matrix.GetUp() = CVector(0.0f, 0.0f, 1.0f);
+ m_matrix.GetForward() = CVector(direction.x, direction.y, 0.0f);
+ m_matrix.GetRight() = CVector(direction.y, -direction.x, 0.0f);
+ m_matrix.GetPosition() = CVector(0.0f, 0.0f, 0.0f);
+
+ m_bIsMovingDown = b_isMovingDown;
+
+ m_midPoint = (m_pos0 + m_pos3) / 2.0f;
+
+ m_radius = (m_pos0 - m_midPoint).Magnitude();
+}
+
+void
+CEscalator::Update(void) {
+ if (!m_bIsActive) {
+ if ((TheCamera.GetPosition() - m_midPoint).Magnitude() < 25.0f) {
+ if (TheCamera.IsSphereVisible(m_midPoint, m_radius) && (m_stepsCount + 10 < CPools::GetObjectPool()->GetNoOfFreeSpaces())) {
+ m_bIsActive = true;
+ for (int i = 0; i < m_stepsCount; i++) {
+ m_pSteps[i] = new CObject(MI_ESCALATORSTEP, TRUE);
+ if (m_pSteps[i]) {
+ m_pSteps[i]->SetPosition(m_pos1);
+ CWorld::Add(m_pSteps[i]);
+ m_pSteps[i]->ObjectCreatedBy = CONTROLLED_SUB_OBJECT;
}
}
}
}
+ }
+
+ if (m_bIsActive) {
+ float time = (CTimer::GetTimeInMilliseconds() % 16384) / 16384.0f;
+ for (int i = 0; i < m_stepsCount; i++) {
+ if (m_pSteps[i]) {
+ float t = i / (float)m_stepsCount + time;
+
+ if (t > 1.0f)
+ t -= 1.0f;
- CSprite::FlushSpriteBuffer();
+ if (m_bIsMovingDown)
+ t = 1.0f - t;
+
+ CVector oldPosition = m_pSteps[i]->GetPosition();
+ m_pSteps[i]->GetMatrix() = m_matrix;
+
+ CVector newPosition;
+ if (t < m_lowerEnd) {
+ float ratio = t / m_lowerEnd;
+ newPosition = (ratio * m_pos1) + ((1.0f - ratio) * m_pos0);
+ }
+ else if (t < m_upperEnd) {
+ float ratio = (t - m_lowerEnd) / (m_upperEnd - m_lowerEnd);
+ newPosition = (ratio * m_pos2) + ((1.0f - ratio) * m_pos1);
+ }
+ else {
+ float ratio = (t - m_upperEnd) / (1.0f - m_upperEnd);
+ newPosition = (ratio * m_pos3) + ((1.0f - ratio) * m_pos2);
+ }
+
+ m_pSteps[i]->SetPosition(newPosition);
+ m_pSteps[i]->m_vecMoveSpeed = (newPosition - oldPosition) / Max(CTimer::GetTimeStep(), 1.0f);
+ m_pSteps[i]->GetMatrix().UpdateRW();
+ m_pSteps[i]->UpdateRwFrame();
+ }
+ if ((TheCamera.GetPosition() - m_midPoint).Magnitude() > 28.0f || !TheCamera.IsSphereVisible(m_midPoint, m_radius))
+ SwitchOff();
+ }
+ }
+}
+
+bool deletingEscalator;
+
+void
+CEscalator::SwitchOff(void) {
+ if (m_bIsActive) {
+ for (int i = 0; i < m_stepsCount; i++) {
+ if (m_pSteps[i]) {
+ CWorld::Remove(m_pSteps[i]);
+ deletingEscalator = true;
+ delete m_pSteps[i];
+ m_pSteps[i] = nil;
+ deletingEscalator = false;
+ }
+ }
+ m_bIsActive = false;
+ }
+}
+
+void
+CEscalators::AddOne(CVector pos0, CVector pos1, CVector pos2, CVector pos3, bool b_isMovingDown) {
+ aEscalators[NumEscalators++].AddThisOne(pos0, pos1, pos2, pos3, b_isMovingDown);
+}
+
+void
+CEscalators::Init(void) {
+ Shutdown();
+ NumEscalators = 0;
+
+ AddOne(CVector(-9.82999f, -938.04498f, 9.4219f), CVector(-8.573f, -938.04498f, 9.4219f),
+ CVector(-0.747f, -938.045f, 15.065f), CVector(0.88f, -938.045f, 15.065f), TRUE);
+
+ AddOne(CVector(-9.83f, -939.966f, 9.422f), CVector(-8.573f, -939.966f, 9.422f),
+ CVector(-0.747f, -939.966f, 15.065f), CVector(0.880f, -939.966f, 15.065f), FALSE);
+
+ AddOne(CVector(408.116f, 1058.36f, 18.261f), CVector(408.094f, 1057.04f, 18.261f),
+ CVector(408.116f, 1048.0f, 24.765f), CVector(408.094f, 1046.57f, 24.799f), TRUE);
+
+ AddOne(CVector(406.195f, 1058.36f, 18.261f), CVector(406.173f, 1057.04f, 18.261f),
+ CVector(406.195f, 1048.0f, 24.729f), CVector(406.173f, 1046.57f, 24.79f), FALSE);
+
+ AddOne(CVector(421.729f, 1058.3789f, 18.075f), CVector(421.707f, 1057.052f, 18.099f),
+ CVector(421.729f, 1048.016f, 24.604f), CVector(421.707f, 1046.589f, 24.637f), TRUE);
+
+ AddOne(CVector(419.808f, 1058.378f, 18.099f), CVector(419.786f, 1057.052f, 18.099f),
+ CVector(419.808f, 1048.016f, 24.568f), CVector(419.786f, 1046.589f, 24.637f), FALSE);
+
+ AddOne(CVector(412.69901f, 1102.729f, 17.569f), CVector(412.72198f, 1104.057f, 17.57f),
+ CVector(412.69901f, 1113.092f, 24.073f), CVector(412.72198f, 1114.3201f, 24.108f), TRUE);
+
+ AddOne(CVector(414.62f, 1102.729f, 17.569f), CVector(414.64301f, 1104.057f, 17.57f),
+ CVector(414.62f, 1113.092f, 24.037001f), CVector(414.64301f, 1114.3201f, 24.099001f), FALSE);
+
+ AddOne(CVector(414.64301f, 1145.589f, 17.57f), CVector(414.62f, 1144.261f, 17.569f),
+ CVector(414.64301f, 1135.226f, 24.073999f), CVector(414.62f, 1133.798f, 24.107f), TRUE);
+
+ AddOne(CVector(412.72198f, 1145.589f, 17.57f), CVector(412.69901f, 1144.261f, 17.569f),
+ CVector(412.72198f, 1135.226f, 24.038f), CVector(412.69901f, 1133.798f, 24.098f), FALSE);
+
+ AddOne(CVector(406.05099f, 1193.4771f, 18.016001f), CVector(406.07401f, 1194.8051f, 18.017f),
+ CVector(406.05099f, 1203.84f, 24.52f), CVector(406.07401f, 1205.2679f, 24.555f), TRUE);
+
+ AddOne(CVector(407.97198f, 1193.4771f, 18.016001f), CVector(407.995f, 1194.8051f, 18.017f),
+ CVector(407.97198f, 1203.84f, 24.483999f), CVector(407.995f, 1205.2679f, 24.546f), FALSE);
+
+ AddOne(CVector(419.659f, 1193.479f, 17.979f), CVector(419.68201f, 1194.807f, 17.98f),
+ CVector(419.659f, 1203.842f, 24.483f), CVector(419.68201f, 1205.27f, 24.518f), TRUE);
+
+ AddOne(CVector(421.57999f, 1193.479f, 17.979f), CVector(421.603f, 1194.807f, 17.98f),
+ CVector(421.57999f, 1203.842f, 24.447001f), CVector(421.603f, 1205.27f, 24.509001f), FALSE);
+
+ AddOne(CVector(406.23199f, 1022.857f, 17.917f), CVector(406.23199f, 1024.1851f, 17.917f),
+ CVector(406.23199f, 1033.22f, 24.521f), CVector(406.23199f, 1034.647f, 24.555f), TRUE);
+
+ AddOne(CVector(408.15302f, 1022.857f, 17.917f), CVector(408.15302f, 1024.1851f, 17.916f),
+ CVector(408.15302f, 1033.22f, 24.486f), CVector(408.15302f, 1034.647f, 24.52f), FALSE);
+
+ AddOne(CVector(-1506.39f, -813.13f, 13.834f), CVector(-1506.177f, -814.51703f, 13.834f),
+ CVector(-1504.566f, -823.20898f, 19.836f), CVector(-1504.329f, -824.48499f, 19.837f), FALSE);
+
+ AddOne(CVector(-1481.951f, -859.05402f, 13.834f), CVector(-1482.7791f, -858.22498f, 13.834f),
+ CVector(-1489.03f, -851.974f, 19.836f), CVector(-1489.948f, -851.05701f, 19.837f), TRUE);
+
+ AddOne(CVector(-1461.743f, -871.35901f, 13.834f), CVector(-1460.62f, -871.69202f, 13.834f),
+ CVector(-1452.144f, -874.20203f, 19.836f), CVector(-1450.9f, -874.57098f, 19.837f), FALSE);
+
+ AddOne(CVector(-1409.889f, -871.41498f, 13.834f), CVector(-1411.0129f, -871.74701f, 13.834f),
+ CVector(-1419.489f, -874.258f, 19.836f), CVector(-1420.733f, -874.62701f, 19.837f), TRUE);
+
+ AddOne(CVector(-1389.577f, -858.89301f, 13.834f), CVector(-1388.7271f, -858.08698f, 13.834f),
+ CVector(-1382.314f, -852.00201f, 19.836f), CVector(-1381.373f, -851.10797f, 19.837f), FALSE);
+
+ AddOne(CVector(-1364.981f, -813.13f, 13.834f), CVector(-1365.204f, -814.28003f, 13.834f),
+ CVector(-1366.891f, -822.95801f, 19.83f), CVector(-1367.139f, -824.23199f, 19.837f), TRUE);
+
+ for (int i = 0; i < NUM_ESCALATORS; i++) {
+ aEscalators[i].SwitchOff();
+ }
+}
+
+void
+CEscalators::Update(void) {
+ if (CReplay::IsPlayingBack())
+ return;
+
+ for (int i = 0; i < NUM_ESCALATORS; i++) {
+ aEscalators[i].Update();
+ }
+}
+
+void
+CEscalators::Shutdown(void) {
+ for (int i = 0; i < NUM_ESCALATORS; i++) {
+ aEscalators[i].SwitchOff();
+ }
+ NumEscalators = 0;
+}
+
+
+CScriptPath CScriptPaths::aArray[3];
+
+void CScriptPath::FindCoorsFromDistanceOnPath(float t, float *pX, float *pY, float *pZ)
+{
+ int32 i;
+ for (i = 0; m_pNode[i + 1].t < t; i++)
+ if (i == m_numNodes - 1) {
+ // don't go beyond last node
+ *pX = m_pNode[m_numNodes - 1].p.x;
+ *pY = m_pNode[m_numNodes - 1].p.y;
+ *pZ = m_pNode[m_numNodes - 1].p.z;
+ return;
+ }
+ float f = (t - m_pNode[i].t) / (m_pNode[i + 1].t - m_pNode[i].t);
+ *pX = (1.0f - f)*m_pNode[i].p.x + f*m_pNode[i + 1].p.x;
+ *pY = (1.0f - f)*m_pNode[i].p.y + f*m_pNode[i + 1].p.y;
+ *pZ = (1.0f - f)*m_pNode[i].p.z + f*m_pNode[i + 1].p.z;
+}
+
+void CScriptPath::Update(void) {
+ if (m_state != SCRIPT_PATH_ACTIVE)
+ return;
+
+ m_fPosition += m_fSpeed * CTimer::GetTimeStepInSeconds();
+ m_fPosition = Clamp(m_fPosition, 0.0f, m_fTotalLength);
+
+ if (m_pObjects[0] || m_pObjects[1] || m_pObjects[2] || m_pObjects[3]
+ || m_pObjects[4] || m_pObjects[5]) {
+
+ float t1, t2;
+ CVector pos1, pos2;
+
+ t1 = Max(m_fPosition - m_fObjectLength / 2.0f, 0.0f);
+ FindCoorsFromDistanceOnPath(t1, &pos1.x, &pos1.y, &pos1.z);
+ t2 = Min(m_fPosition + m_fObjectLength / 2.0f, m_fTotalLength);
+ FindCoorsFromDistanceOnPath(t2, &pos2.x, &pos2.y, &pos2.z);
+
+ CVector newForward, newUp(0.0f, 0.0f, 1.0f), newRight;
+
+ newForward = pos2 - pos1;
+ newForward.Normalise();
+ newRight = CrossProduct(newForward, newUp);
+ newRight.Normalise();
+ newUp = CrossProduct(newRight, newForward);
+
+ for (int i = 0; i < 6; i++) {
+ if (m_pObjects[i]) {
+ CMatrix prevMat(m_pObjects[i]->GetMatrix());
+ CVector prevPosition = m_pObjects[i]->GetPosition();
+
+ m_pObjects[i]->SetPosition((pos1 + pos2) / 2.0f);
+ m_pObjects[i]->GetRight() = newRight;
+ m_pObjects[i]->GetUp() = newUp;
+ m_pObjects[i]->GetForward() = newForward;
+ m_pObjects[i]->GetMatrix().UpdateRW();
+ m_pObjects[i]->UpdateRwFrame();
+
+ if (!m_pObjects[i]->bIsBIGBuilding && prevPosition != m_pObjects[i]->GetPosition())
+ m_pObjects[i]->RemoveAndAdd();
+
+ m_pObjects[i]->GetMatrix().UpdateRW();
+ m_pObjects[i]->UpdateRwFrame();
+
+ m_pObjects[i]->m_vecMoveSpeed = (m_pObjects[i]->GetPosition() - prevMat.GetPosition()) / CTimer::GetTimeStep();
+
+ float deltaAngle = m_pObjects[i]->GetForward().Heading() - prevMat.GetForward().Heading();
+ while (deltaAngle < (float)PI) deltaAngle += (float)TWOPI;
+ while (deltaAngle > (float)PI) deltaAngle -= (float)TWOPI;
+ float zTurnSpeed = deltaAngle / CTimer::GetTimeStep();
+
+ m_pObjects[i]->m_vecTurnSpeed = CVector(0.0f, 0.0f, zTurnSpeed);
+ m_pObjects[i]->m_vecMoveFriction = CVector(0.0f, 0.0f, 0.0f);
+ m_pObjects[i]->m_vecTurnFriction = CVector(0.0f, 0.0f, 0.0f);
+ }
+ }
+ }
+}
+
+void CScriptPath::Clear(void) {
+ if (m_pNode)
+ delete[] m_pNode;
+ m_pNode = nil;
+ m_numNodes = 0;
+ for (int i = 0; i < 6; i++)
+ m_pObjects[i] = nil;
+ m_state = SCRIPT_PATH_DISABLED;
+}
+
+void CScriptPath::InitialiseOne(int32 numNodes, float length) {
+ char Dest[32];
+ sprintf(Dest, "data\\paths\\spath%d.dat", numNodes);
+ m_pNode = CPlane::LoadPath(Dest, m_numNodes, m_fTotalLength, false);
+ m_fSpeed = 1.0f;
+ m_fPosition = 0.0f;
+ m_fObjectLength = length;
+ m_state = SCRIPT_PATH_INITIALIZED;
+}
+
+void CScriptPath::SetObjectToControl(CObject *pObj) {
+ int32 i = 0;
+ while (i < 6 && m_pObjects[i])
+ i++;
+ m_pObjects[i] = pObj;
+ pObj->RegisterReference((CEntity**)&m_pObjects[i]);
+ pObj->m_phy_flagA08 = false;
+ m_state = SCRIPT_PATH_ACTIVE;
+}
+
+void CScriptPaths::Init(void) {
+ for (int i = 0; i < 3; i++)
+ aArray[i].Clear();
+}
+
+void CScriptPaths::Shutdown(void) {
+ for (int i = 0; i < 3; i++)
+ aArray[i].Clear();
+}
+
+void CScriptPaths::Update(void) {
+ for (int i = 0; i < 3; i++)
+ aArray[i].Update();
+}
+
+bool CScriptPaths::IsOneActive(void) {
+ for (int i = 0; i < 3; i++)
+ if (aArray[i].m_state == SCRIPT_PATH_ACTIVE && aArray[i].m_fSpeed != 0.0f)
+ return true;
+
+ return false;
+}
+
+void CScriptPaths::Load(uint8 *buf, uint32 size) {
+INITSAVEBUF
+ for (int32 i = 0; i < 3; i++)
+ aArray[i].Clear();
+
+ for (int32 i = 0; i < 3; i++) {
+#ifdef COMPATIBLE_SAVES
+ ReadSaveBuf(&aArray[i].m_numNodes, buf);
+ SkipSaveBuf(buf, 4);
+ ReadSaveBuf(&aArray[i].m_fTotalLength, buf);
+ ReadSaveBuf(&aArray[i].m_fSpeed, buf);
+ ReadSaveBuf(&aArray[i].m_fPosition, buf);
+ ReadSaveBuf(&aArray[i].m_fObjectLength, buf);
+ ReadSaveBuf(&aArray[i].m_state, buf);
+#else
+ ReadSaveBuf(&aArray[i], buf);
+#endif
+
+ for (int32 j = 0; j < 6; j++) {
+#ifdef COMPATIBLE_SAVES
+ aArray[i].m_pObjects[j] = nil;
+ int32 tmp;
+ ReadSaveBuf(&tmp, buf);
+ if (tmp != 0) {
+ aArray[i].m_pObjects[j] = CPools::GetObjectPool()->GetSlot(tmp - 1);
+ aArray[i].m_pObjects[j]->m_phy_flagA08 = false;
+ }
+#else
+ CScriptPath *pPath = &aArray[i];
+ if (pPath->m_pObjects[j] != nil) {
+ pPath->m_pObjects[j] = CPools::GetObjectPool()->GetSlot((uintptr)pPath->m_pObjects[j] - 1);
+ pPath->m_pObjects[j]->m_phy_flagA08 = false;
+ }
+#endif
+ }
+
+ aArray[i].m_pNode = new CPlaneNode[aArray[i].m_numNodes];
+ for (int32 j = 0; j < aArray[i].m_numNodes; j++) {
+ ReadSaveBuf(&aArray[i].m_pNode[j], buf);
+ }
+ }
+VALIDATESAVEBUF(size)
+}
+
+void CScriptPaths::Save(uint8 *buf, uint32 *size) {
+ *size = SCRIPTPATHS_SAVE_SIZE;
+INITSAVEBUF
+ for (int32 i = 0; i < 3; i++) {
+#ifdef COMPATIBLE_SAVES
+ WriteSaveBuf(buf, aArray[i].m_numNodes);
+ ZeroSaveBuf(buf, 4);
+ WriteSaveBuf(buf, aArray[i].m_fTotalLength);
+ WriteSaveBuf(buf, aArray[i].m_fSpeed);
+ WriteSaveBuf(buf, aArray[i].m_fPosition);
+ WriteSaveBuf(buf, aArray[i].m_fObjectLength);
+ WriteSaveBuf(buf, aArray[i].m_state);
+#else
+ CScriptPath *pPath = WriteSaveBuf(buf, aArray[i]);
+#endif
+
+ for (int32 j = 0; j < 6; j++) {
+#ifdef COMPATIBLE_SAVES
+ WriteSaveBuf(buf, aArray[i].m_pObjects[j] != nil ? CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(aArray[i].m_pObjects[j]) + 1 : 0);
+#else
+ if (pPath->m_pObjects[j] != nil)
+ pPath->m_pObjects[j] = (CObject*)(CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(pPath->m_pObjects[j]) + 1);
+#endif
+ }
+
+ for (int32 j = 0; j < aArray[i].m_numNodes; j++) {
+ WriteSaveBuf(buf, aArray[i].m_pNode[j]);
+ *size += sizeof(aArray[i].m_pNode[j]);
+ }
+ }
+VALIDATESAVEBUF(*size);
+}
+
+CObject *g_pScriptPathObjects[18];
+
+void CScriptPaths::Load_ForReplay(void) {
+ for (int i = 0; i < 3; i++) {
+ for (int32 j = 0; j < 6; j++) {
+ aArray[i].m_pObjects[j] = g_pScriptPathObjects[6 * i + j];
+ }
+ }
+}
+
+void CScriptPaths::Save_ForReplay(void) {
+ for (int i = 0; i < 3; i++) {
+ for (int32 j = 0; j < 6; j++) {
+ g_pScriptPathObjects[6 * i + j] = aArray[i].m_pObjects[j];
+ }
}
}
diff --git a/src/renderer/Fluff.h b/src/renderer/Fluff.h
index fe3ab256..58c8410c 100644
--- a/src/renderer/Fluff.h
+++ b/src/renderer/Fluff.h
@@ -1,6 +1,123 @@
#pragma once
#include "common.h"
#include "Vector.h"
+#include "Object.h"
+#include "Plane.h"
+
+enum {
+ SCRIPT_PATH_DISABLED = 0,
+ SCRIPT_PATH_INITIALIZED,
+ SCRIPT_PATH_ACTIVE
+};
+
+class CScriptPath
+{
+public:
+ int32 m_numNodes;
+ CPlaneNode *m_pNode;
+ float m_fTotalLength;
+ float m_fSpeed;
+ float m_fPosition;
+ float m_fObjectLength;
+ int32 m_state;
+ CObject *m_pObjects[6];
+
+ void Clear(void);
+ void Update(void);
+ void InitialiseOne(int32 numNodes, float length);
+ void FindCoorsFromDistanceOnPath(float t, float *pX, float *pY, float *pZ);
+ void SetObjectToControl(CObject *pObj);
+};
+
+class CScriptPaths
+{
+public:
+ static CScriptPath aArray[3];
+ static void Init(void);
+ static void Shutdown(void);
+ static void Update(void);
+ static bool IsOneActive(void);
+ static void Save(uint8 *buf, uint32 *size);
+ static void Load(uint8 *buf, uint32 size);
+ static void Save_ForReplay();
+ static void Load_ForReplay();
+};
+
+class CPlaneTrail
+{
+ CVector m_pos[16];
+ int32 m_time[16];
+public:
+ void Init(void);
+ void Render(float visibility);
+ void RegisterPoint(CVector pos);
+};
+
+class CPlaneTrails
+{
+ static CPlaneTrail aArray[6]; // NB: 3 CPlanes and 3 hardcoded far away ones
+public:
+ static void Init(void);
+ static void Update(void);
+ static void Render(void);
+ static void RegisterPoint(CVector pos, uint32 id);
+};
+
+class CPlaneBanner
+{
+ CVector m_pos[8];
+public:
+ void Init(void);
+ void Update(void);
+ void Render(void);
+ void RegisterPoint(CVector pos);
+};
+
+class CPlaneBanners
+{
+ static CPlaneBanner aArray[5];
+public:
+ static void Init(void);
+ static void Update(void);
+ static void Render(void);
+ static void RegisterPoint(CVector pos, uint32 id);
+};
+
+class CEscalator
+{
+ CVector m_pos0;
+ CVector m_pos1;
+ CVector m_pos2;
+ CVector m_pos3;
+ CMatrix m_matrix;
+ bool m_bIsActive;
+ bool m_bIsMovingDown;
+ int32 m_stepsCount;
+ float m_lowerEnd;
+ float m_upperEnd;
+ CVector m_midPoint;
+ float m_radius;
+ CObject *m_pSteps[24];
+public:
+ CEscalator();
+ void Update(void);
+ void SwitchOff(void);
+ void AddThisOne(CVector pos0, CVector pos1, CVector pos2, CVector pos3, bool b_isMovingDown);
+ bool IsActive() const { return m_bIsActive; };
+ const CVector& GetPosition() const { return m_midPoint; };
+};
+
+class CEscalators
+{
+ static CEscalator aEscalators[NUM_ESCALATORS];
+public:
+ static int32 NumEscalators;
+ static void Init(void);
+ static void Update(void);
+ static void AddOne(CVector pos0, CVector pos1, CVector pos2, CVector pos3, bool b_isMovingDown);
+ static void Shutdown(void);
+ static const CEscalator& GetEscalator(int ind) { return aEscalators[ind]; };
+};
class CMovingThing
{
@@ -8,7 +125,7 @@ public:
CMovingThing *m_pNext;
CMovingThing *m_pPrev;
int16 m_nType;
- int16 m_nHidden;
+ int16 m_farAway;
CVector m_vecPosn;
CEntity* m_pEntity;
@@ -18,7 +135,7 @@ public:
int16 SizeList();
};
-#define NUMMOVINGTHINGS 128
+#define NUMMOVINGTHINGS 48
class CMovingThings
{
@@ -32,6 +149,8 @@ public:
static void Shutdown();
static void Update();
static void Render();
+ static void PossiblyAddThisEntity(CEntity *pEnt);
+ static void RegisterOne(CEntity *pEnt, uint16 nType);
};
class CScrollBar
@@ -53,54 +172,34 @@ private:
float m_fScale;
public:
- void SetVisibility(bool visible) { m_bVisible = visible; }
- bool IsVisible() { return m_bVisible; }
-
- void Init(CVector, uint8, float, float, float, uint8, uint8, uint8, float);
- void Update();
- void Render();
-};
-
-class CTowerClock
-{
-private:
- CVector m_Position;
- CVector m_Size;
- float m_fDrawDistance;
- float m_fScale;
- uint8 m_uRed;
- uint8 m_uGreen;
- uint8 m_uBlue;
- bool m_bVisible;
- float m_fIntensity;
+ static int TonightsEvent;
public:
void SetVisibility(bool visible) { m_bVisible = visible; }
bool IsVisible() { return m_bVisible; }
- void Init(CVector, float, float, uint8, uint8, uint8, float, float);
+ void Init(CVector pos1, CVector pos2, uint8 type, uint8 red, uint8 green, uint8 blue, float scale);
void Update();
void Render();
};
-class CDigitalClock
-{
-private:
- CVector m_Position;
- CVector m_Size;
- float m_fDrawDistance;
- float m_fScale;
- uint8 m_uRed;
- uint8 m_uGreen;
- uint8 m_uBlue;
- bool m_bVisible;
- float m_fIntensity;
-
+class CSmokeTrail {
+ CVector m_pos[16];
+ float m_opacity[16];
+ int m_time[16];
+ char m_unused[536];
+ int m_seed;
public:
- void SetVisibility(bool visible) { m_bVisible = visible; }
- bool IsVisible() { return m_bVisible; }
+ void Render(void);
+ void RegisterPoint(CVector position, float a);
+ void Init(int num);
+};
- void Init(CVector, float, float, uint8, uint8, uint8, float, float);
- void Update();
- void Render();
+class CSmokeTrails {
+ static CSmokeTrail aSmoke[3];
+public:
+ static bool CigOn;
+ static void Update(void);
+ static void Render(void);
+ static void Init(void);
}; \ No newline at end of file
diff --git a/src/renderer/Font.cpp b/src/renderer/Font.cpp
index 6a9944e1..6ae10011 100644
--- a/src/renderer/Font.cpp
+++ b/src/renderer/Font.cpp
@@ -6,6 +6,7 @@
#ifdef BUTTON_ICONS
#include "FileMgr.h"
#endif
+#include "Timer.h"
void
AsciiToUnicode(const char *src, wchar *dst)
@@ -33,216 +34,216 @@ UnicodeStrlen(const wchar *str)
return len;
}
+void
+UnicodeMakeUpperCase(wchar *dst, const wchar *src) //idk what to do with it, seems to be incorrect implementation by R*
+{
+ while (*src != '\0') {
+ if (*src < 'a' || *src > 'z')
+ *dst = *src;
+ else
+ *dst = *src - 32;
+ dst++;
+ src++;
+ }
+ *dst = '\0';
+}
+
CFontDetails CFont::Details;
bool16 CFont::NewLine;
CSprite2d CFont::Sprite[MAX_FONTS];
+CFontRenderState CFont::RenderState;
#ifdef MORE_LANGUAGES
uint8 CFont::LanguageSet = FONT_LANGSET_EFIGS;
int32 CFont::Slot = -1;
#define JAP_TERMINATION (0x8000 | '~')
-int16 CFont::Size[LANGSET_MAX][MAX_FONTS][193] = {
+int16 CFont::Size[LANGSET_MAX][MAX_FONTS][210] = {
{
#else
-int16 CFont::Size[MAX_FONTS][193] = {
+int16 CFont::Size[MAX_FONTS][210] = {
#endif
-
-#if !defined(GTA_PS2) || defined(FIX_BUGS)
- {
- 13, 12, 31, 35, 23, 35, 31, 9, 14, 15, 25, 30, 11, 17, 13, 31,
- 23, 16, 22, 21, 24, 23, 23, 20, 23, 22, 10, 35, 26, 26, 26, 26,
- 30, 26, 24, 23, 24, 22, 21, 24, 26, 10, 20, 26, 22, 29, 26, 25,
- 23, 25, 24, 24, 22, 25, 24, 29, 29, 23, 25, 37, 22, 37, 35, 37,
- 35, 21, 22, 21, 21, 22, 13, 22, 21, 10, 16, 22, 11, 32, 21, 21,
- 23, 22, 16, 20, 14, 21, 20, 30, 25, 21, 21, 33, 33, 33, 33, 35,
- 27, 27, 27, 27, 32, 24, 23, 23, 23, 23, 11, 11, 11, 11, 26, 26,
- 26, 26, 26, 26, 26, 25, 26, 21, 21, 21, 21, 32, 23, 22, 22, 22,
- 22, 11, 11, 11, 11, 22, 22, 22, 22, 22, 22, 22, 22, 26, 21, 24,
- 12, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 18, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
- 20
- },
-
- {
- 13, 9, 21, 35, 23, 35, 35, 11, 35, 35, 25, 35, 11, 17, 13, 33,
- 28, 14, 22, 21, 24, 23, 23, 21, 23, 22, 10, 35, 13, 35, 13, 33,
- 5, 25, 22, 23, 24, 21, 21, 24, 24, 9, 20, 24, 21, 27, 25, 25,
- 22, 25, 23, 20, 23, 23, 23, 31, 23, 23, 23, 37, 33, 37, 35, 37,
- 35, 21, 19, 19, 21, 19, 17, 21, 21, 8, 17, 18, 14, 24, 21, 21,
- 20, 22, 19, 20, 20, 19, 20, 26, 21, 20, 21, 33, 33, 33, 33, 35,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 16
- },
-
- {
- 15, 14, 16, 25, 19, 26, 22, 11, 18, 18, 27, 26, 13, 19, 9, 27,
- 19, 18, 19, 19, 22, 19, 20, 18, 19, 20, 12, 32, 15, 32, 15, 35,
- 15, 19, 19, 19, 19, 19, 16, 19, 20, 9, 19, 20, 14, 29, 19, 20,
- 19, 19, 19, 19, 21, 19, 20, 32, 20, 19, 19, 33, 31, 39, 37, 39,
- 37, 21, 21, 21, 23, 21, 19, 23, 23, 10, 19, 20, 16, 26, 23, 23,
- 20, 20, 20, 22, 21, 22, 22, 26, 22, 22, 23, 35, 35, 35, 35, 37,
- 19, 19, 19, 19, 29, 19, 19, 19, 19, 19, 9, 9, 9, 9, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 30, 19, 19, 19, 19,
- 19, 10, 10, 10, 10, 19, 19, 19, 19, 19, 19, 19, 19, 19, 23, 35,
- 12, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 11, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19
- }
-#else // #if defined(GTA_PS2) && !defined(FIX_BUGS)
- {
- 13, 12, 31, 35, 23, 35, 31, 9, 14, 15, 25, 30, 11, 17, 13, 31,
- 23, 16, 22, 21, 24, 23, 23, 20, 23, 22, 10, 35, 26, 26, 26, 26,
- 30, 26, 24, 23, 24, 22, 21, 24, 26, 10, 20, 26, 22, 29, 26, 25,
- 24, 25, 24, 24, 22, 25, 24, 29, 29, 23, 25, 37, 22, 37, 35, 37,
- 35, 21, 22, 21, 21, 22, 13, 22, 21, 10, 16, 22, 11, 32, 21, 21,
- 23, 22, 16, 20, 14, 21, 20, 30, 25, 21, 21, 33, 33, 33, 33, 35,
- 27, 27, 27, 27, 32, 24, 23, 23, 23, 23, 11, 11, 11, 11, 26, 26,
- 26, 26, 26, 26, 26, 25, 26, 21, 21, 21, 21, 32, 23, 22, 22, 22,
- 22, 11, 11, 11, 11, 22, 22, 22, 22, 22, 22, 22, 22, 26, 21, 24,
- 12, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 18, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
- 20
- },
-
- {
- 13, 9, 21, 35, 23, 35, 35, 11, 35, 35, 25, 35, 11, 17, 13, 33,
- 28, 14, 22, 21, 24, 23, 23, 21, 23, 22, 10, 35, 13, 35, 13, 33,
- 5, 25, 22, 23, 24, 21, 21, 24, 24, 9, 20, 24, 21, 27, 25, 25,
- 22, 25, 23, 20, 23, 23, 23, 31, 23, 23, 23, 37, 33, 37, 35, 37,
- 35, 21, 19, 19, 21, 19, 17, 21, 21, 8, 17, 18, 14, 24, 21, 21,
- 20, 22, 19, 20, 20, 19, 20, 26, 21, 20, 21, 33, 33, 33, 33, 35,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ {
+ //FONT2 EFIGS
+ //SPC,!, $, %, &, ', [, ], +, , -, .,
+ 12, 9, 22, 17, 19, 19, 25, 4, 33, 33, 25, 35, 11, 10, 6, 33,
+ //0, 1, 2, 3, 4, 5, 6, 7, 8, 9, :, ??,
+ 18, 10, 17, 17, 17, 17, 17, 15, 12, 16, 5, 30, 30, 30, 30, 30,
+ // A, B, C, D, E, F, G, H, I, J, K, L, M, N, O,
+ 12, 16, 19, 16, 19, 18, 18, 17, 22, 11, 17, 18, 18, 30, 22, 19,
+ //P, Q, R, S, T, U, V, W, X, Y, Z, ??, ??, ??, ¡, \,
+ #ifdef FIX_BUGS
+ 22, 19, 19, 20, 18, 19, 19, 29, 19, 18, 19, 19, 33, 33, 10, 19,
+ #else
+ 22, 19, 19, 20, 18, 19, 19, 29, 19, 18, 19, 19, 33, 33, 19, 19,
+ #endif
+ //??,a, b, c, d, e, f, g, h, i, j, k, l, m, n, o,
+ 12, 14, 11, 11, 16, 11, 12, 14, 14, 10, 13, 12, 10, 19, 18, 12,
+ //p, q, r, s, t, u, v, w, x, y, z, ??, ??, ??, ??, ??,
+ 16, 13, 13, 11, 12, 15, 12, 15, 13, 12, 12, 37, 33, 37, 35, 37,
+ //À, Á, Â, Ä, Æ, Ç, È, É, Ê, Ë, Ì, Í, Î, Ï, Ò, Ó,
+ 16, 16, 16, 16, 33, 17, 18, 18, 18, 18, 11, 11, 11, 11, 19, 19,
+ //Ô, Ö, Ù, Ú, Û, Ü, ß, à, á, â, ä, æ, ç, è, é, ê,
+ 19, 19, 19, 19, 19, 19, 15, 14, 14, 14, 14, 20, 14, 11, 11, 11,
+ //ë, ì, í, î, ï, ò, ó, ô, ö, ù, ú, û, ü, Ñ, ñ, ¿,
+ #ifdef FIX_BUGS
+ 11, 10, 10, 10, 10, 12, 12, 12, 12, 15, 15, 15, 15, 22, 18, 21,
+ #else
+ 11, 10, 10, 10, 10, 12, 12, 12, 12, 15, 15, 15, 15, 24, 18, 21,
+ #endif
+ //i,BLANKS
+ 10, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 16
- },
-
- {
- 15, 14, 16, 25, 19, 26, 22, 11, 18, 18, 27, 26, 13, 19, 9, 27,
- 19, 18, 19, 19, 21, 19, 20, 18, 19, 20, 12, 32, 15, 32, 15, 35,
- 15, 19, 19, 19, 19, 19, 16, 19, 20, 9, 19, 20, 14, 29, 19, 19,
- 19, 19, 19, 19, 21, 19, 20, 32, 20, 19, 19, 33, 31, 39, 37, 39,
- 37, 21, 21, 21, 23, 21, 19, 23, 23, 10, 19, 20, 16, 26, 23, 23,
- 20, 20, 20, 22, 21, 22, 22, 26, 22, 22, 23, 35, 35, 35, 35, 37,
- 19, 19, 19, 19, 29, 19, 19, 19, 19, 19, 9, 9, 9, 9, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 30, 19, 19, 19, 19, 19,
- 10, 10, 10, 10, 19, 19, 19, 19, 19, 19, 19, 19, 19, 23, 35, 12,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 11, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19
- }
-#endif
-
-#ifdef MORE_LANGUAGES
+ //space, unprop
+ 19, 16
},
{
- { 13, 12, 31, 35, 23, 35, 31, 9, 14, 15, 25, 30, 11, 17,
- 13, 31, 23, 16, 22, 21, 24, 23, 23, 20, 23, 22, 10,
- 35, 26, 26, 26, 26, 30, 26, 24, 23, 24, 22, 21, 24,
- 26, 10, 20, 26, 22, 29, 26, 25, 23, 25, 24, 24, 22,
- 25, 24, 29, 29, 23, 25, 37, 22, 37, 35, 37, 35, 21,
- 22, 21, 21, 22, 13, 22, 21, 10, 16, 22, 11, 32, 21,
- 21, 23, 22, 16, 20, 14, 21, 20, 30, 25, 21, 21, 13,
- 33, 13, 13, 13, 24, 22, 22, 19, 26, 21, 30, 20, 23,
- 23, 21, 24, 26, 23, 22, 23, 21, 22, 20, 20, 26, 25,
- 24, 22, 31, 32, 23, 30, 22, 22, 32, 23, 19, 18, 18,
- 15, 22, 19, 27, 19, 20, 20, 18, 22, 24, 20, 19, 19,
- 20, 19, 16, 19, 28, 20, 20, 18, 26, 27, 19, 26, 18,
- 19, 27, 19, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 18, 26, 26, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 26, 20 },
- { 13, 9, 21, 35, 23, 35, 35, 11, 35, 35, 25, 35, 11,
- 17, 13, 33, 28, 14, 22, 21, 24, 23, 23, 21, 23, 22,
- 10, 35, 13, 35, 13, 33, 5, 25, 22, 23, 24, 21, 21, 24,
- 24, 9, 20, 24, 21, 27, 25, 25, 22, 25, 23, 20, 23, 23,
- 23, 31, 23, 23, 23, 37, 33, 37, 35, 37, 35, 21, 19,
- 19, 21, 19, 17, 21, 21, 8, 17, 18, 14, 24, 21, 21, 20,
- 22, 19, 20, 20, 19, 20, 26, 21, 20, 21, 33, 33, 33,
- 33, 35, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 16, },
- { 15, 14, 16, 25, 19,
- 26, 22, 11, 18, 18, 27, 26, 13, 19, 9, 27, 19, 18, 19,
- 19, 22, 19, 20, 18, 19, 20, 12, 32, 15, 32, 15, 35,
- 15, 19, 19, 19, 19, 19, 16, 19, 20, 9, 19, 20, 14, 29,
- 19, 20, 19, 19, 19, 19, 21, 19, 20, 32, 20, 19, 19,
- 33, 31, 39, 37, 39, 37, 21, 21, 21, 23, 21, 19, 23, 23, 10, 19, 20, 16, 26, 23,
- 21, 21, 20, 20, 22, 21, 22, 22, 26, 22, 22, 23, 35,
- 35, 35, 35, 37, 19, 19, 19, 19, 19, 19, 29, 19, 19,
- 19, 20, 22, 31, 19, 19, 19, 19, 19, 29, 19, 29, 19,
- 21, 19, 30, 31, 21, 29, 19, 19, 29, 19, 21, 23, 32,
- 21, 21, 30, 31, 22, 21, 32, 33, 23, 32, 21, 21, 32,
- 21, 19, 19, 30, 31, 22, 22, 21, 32, 33, 23, 32, 21,
- 21, 32, 21, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 11, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19 },
- },
+ //FONT1 EFIGS
+ //Characters with a '2' refer to the Pricedown font.
+ //Characters that are referred as '*I' are characters that contain icons for PS2/XBOX, but contain regular characters on PC
+ //in order to display them properly in the Keyboard controls menu.
+ //!2,!, *I,(R), $, %, &, ', [, ], *I, +, , -, ., *I,
+ 15, 7, 31, 25, 20, 23, 21, 7, 11, 10, 26, 14, 6, 12, 6, 26,
+ //0, 1, 2, 3, 4, 5, 6, 7, 8, 9, :, *I, *I, *I, *I, ?,
+ 20, 7, 20, 20, 21, 20, 20, 19, 21, 20, 8, 30, 24, 30, 24, 19,
+ //TM,A, B, C, D, E, F, G, H, I, J, K, L, M, N, O,
+ 20, 22, 22, 21, 22, 18, 18, 22, 22, 9, 14, 21, 18, 27, 21, 24,
+ //P, Q, R, S, T, U, V, W, X, Y, Z, *I, \, *I, ¡, °,
+ #ifdef FIX_BUGS
+ 22, 22, 23, 20, 19, 23, 22, 31, 23, 23, 21, 25, 13, 30, 7, 19,
+ #else
+ 22, 22, 23, 20, 19, 23, 22, 31, 23, 23, 21, 25, 13, 30, 10, 19,
+ #endif
+ //(C),a, b, c, d, e, f, g, h, i, j, k, l, m, n, o,
+ 10, 17, 17, 16, 17, 17, 11, 17, 17, 7, 7, 18, 7, 25, 17, 17,
+ //p, q, r, s, t, u, v, w, x, y, z, *I, *I, $2, (2, )2,
+ 17, 17, 11, 17, 11, 17, 18, 25, 19, 18, 17, 28, 26, 20, 15, 15,
+ //À, Á, Â, Ä, Æ, Ç, È, É, Ê, Ë, Ì, Í, Î, Ï, Ò, Ó,
+ 20, 20, 20, 20, 29, 22, 19, 19, 19, 19, 9, 9, 9, 9, 23, 23,
+ //Ô, Ö, Ù, Ú, Û, Ü, ß, à, á, â, ä, æ, ç, è, é, ê,
+ 23, 23, 24, 24, 24, 24, 20, 19, 17, 17, 17, 30, 16, 17, 17, 17,
+ //ë, ì, í, î, ï, ò, ó, ô, ö, ù, ú, û, ü, Ñ, ñ, ¿,
+ #ifdef FIX_BUGS
+ 17, 11, 11, 15, 12, 17, 17, 17, 17, 17, 17, 17, 17, 21, 17, 19,
+ #else
+ 17, 11, 11, 15, 12, 17, 17, 17, 17, 17, 17, 17, 17, 19, 20, 20,
+ #endif
+ //02,12,22, 32, 42, 52, 62, 72, 82, 92, :2, A2, B2, C2, D2, E2,
+ 20, 18, 19, 19, 21, 19, 19, 19, 19, 19, 16, 19, 19, 19, 20, 19,
+ //F2,G2,H2, I2, J2, K2, L2, M2, N2, O2, P2, Q2, R2, S2, T2, U2,
+ 16, 19, 19, 9, 19, 20, 14, 29, 19, 19, 19, 19, 19, 19, 21, 19,
+ //V2,W2,X2, Y2, Z2, À2, Á2, Â2, Ä2, Æ2, Ç2, È2, É2, Ê2, Ë2, Ì2,
+ 20, 32, 20, 19, 19, 19, 19, 19, 19, 29, 19, 19, 19, 19, 19, 9,
+ //Í2,Î2,Ï2, Ò2, Ó2, Ô2, Ö2, Ù2, Ú2, Û2, Ü2, ß2, Ñ2, ¿2, '2, .2,
+ #ifdef FIX_BUGS
+ 9, 9, 9, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 10, 9,
+ #else
+ 9, 9, 9, 19, 19, 19, 19, 19, 19, 19, 19, 19, 21, 21, 10, 9,
+ #endif
+ //space, unprop
+ 10, 20
+ }
+#ifdef MORE_LANGUAGES
+ },
{
- {
- 13, 12, 31, 35, 23, 35, 31, 9, 14, 15, 25, 30, 11, 17, 13, 31,
- 23, 16, 22, 21, 24, 23, 23, 20, 23, 22, 10, 35, 26, 26, 26, 26,
- 30, 26, 24, 23, 24, 22, 21, 24, 26, 10, 20, 26, 22, 29, 26, 25,
- 23, 25, 24, 24, 22, 25, 24, 29, 29, 23, 25, 37, 22, 37, 35, 37,
- 35, 21, 22, 21, 21, 22, 13, 22, 21, 10, 16, 22, 11, 32, 21, 21,
- 23, 22, 16, 20, 14, 21, 20, 30, 25, 21, 21, 33, 33, 33, 33, 35,
- 27, 27, 27, 27, 32, 24, 23, 23, 23, 23, 11, 11, 11, 11, 26, 26,
- 26, 26, 26, 26, 26, 25, 26, 21, 21, 21, 21, 32, 23, 22, 22, 22,
- 22, 11, 11, 11, 11, 22, 22, 22, 22, 22, 22, 22, 22, 26, 21, 24,
- 12, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 18, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
- 20
+ {
+ 5, 9, 9, 0, 17, 17, 23, 3, 21, 18, 0, 8, 3, 8, 3, 0,
+ 16, 9, 16, 16, 15, 19, 15, 14, 17, 17, 4, 4, 0, 0, 0, 17,
+ 19, 17, 19, 15, 21, 18, 19, 16, 21, 13, 15, 21, 20, 28, 21, 18,
+ 22, 17, 21, 20, 18, 18, 20, 26, 22, 18, 18, 0, 8, 0, 9, 8,
+ 0, 14, 11, 12, 16, 11, 13, 13, 15, 10, 14, 15, 11, 21, 17, 10,
+ 20, 15, 12, 12, 16, 17, 13, 16, 13, 21, 11, 0, 0, 0, 0, 0,
+ 20, 19, 19, 22, 27, 15, 18, 18, 20, 26, 21, 23, 17, 22, 21, 17,
+ 26, 25, 26, 17, 20, 26, 17, 16, 11, 12, 13, 21, 11, 17, 17, 12,
+ 21, 17, 17, 15, 24, 16, 10, 20, 23, 16, 7, 9, 16, 23, 12, 11,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19,
+ 19, 16
},
-
+ {
+ 11, 5, 10, 15, 19, 22, 20, 5, 9, 8, 11, 12, 5, 12, 6, 12,
+ 19, 5, 18, 19, 20, 18, 19, 18, 20, 19, 5, 6, 26, 12, 30, 19,
+ 23, 21, 20, 20, 20, 16, 16, 21, 19, 5, 13, 19, 16, 24, 20, 21,
+ 20, 21, 20, 19, 17, 20, 21, 30, 22, 21, 20, 25, 13, 30, 5, 9,
+ 10, 15, 15, 14, 15, 16, 10, 15, 15, 5, 5, 15, 5, 23, 15, 16,
+ 15, 15, 9, 16, 10, 15, 17, 24, 18, 15, 15, 27, 5, 19, 2, 2,
+ 20, 20, 16, 23, 30, 19, 20, 20, 21, 24, 19, 19, 20, 23, 22, 19,
+ 27, 29, 25, 20, 20, 28, 24, 16, 16, 14, 19, 25, 16, 16, 16, 17,
+ 19, 16, 16, 17, 25, 19, 15, 23, 26, 21, 16, 14, 22, 20, 16, 19,
+ 15, 14, 15, 16, 17, 15, 15, 15, 15, 15, 7, 15, 15, 15, 15, 15,
+ 13, 15, 15, 7, 15, 16, 13, 23, 15, 15, 15, 15, 15, 15, 17, 15,
+ 16, 24, 17, 17, 17, 15, 15, 13, 20, 23, 15, 17, 17, 16, 24, 15,
+ 15, 15, 23, 18, 15, 23, 26, 23, 16, 15, 23, 15, 15, 19, 2, 2,
+ 10, 20
+ },
+ },
+ {
{
- 13, 9, 21, 35, 23, 35, 35, 11, 35, 35, 25, 35, 11, 17, 13, 33,
- 28, 14, 22, 21, 24, 23, 23, 21, 23, 22, 10, 35, 13, 35, 13, 33,
- 5, 25, 22, 23, 24, 21, 21, 24, 24, 9, 20, 24, 21, 27, 25, 25,
- 22, 25, 23, 20, 23, 23, 23, 31, 23, 23, 23, 37, 33, 37, 35, 37,
- 35, 21, 19, 19, 21, 19, 17, 21, 21, 8, 17, 18, 14, 24, 21, 21,
- 20, 22, 19, 20, 20, 19, 20, 26, 21, 20, 21, 33, 33, 33, 33, 35,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ //FONT2 EFIGS
+ //SPC,!, $, %, &, ', [, ], +, , -, .,
+ 12, 9, 22, 17, 19, 19, 25, 4, 33, 33, 25, 35, 11, 10, 6, 33,
+ //0, 1, 2, 3, 4, 5, 6, 7, 8, 9, :, ??,
+ 18, 10, 17, 17, 17, 17, 17, 15, 12, 16, 5, 30, 30, 30, 30, 30,
+ // A, B, C, D, E, F, G, H, I, J, K, L, M, N, O,
+ 12, 16, 19, 16, 19, 18, 18, 17, 22, 11, 17, 18, 18, 30, 22, 19,
+ //P, Q, R, S, T, U, V, W, X, Y, Z, ??, ??, ??, ¡, \,
+ 22, 19, 19, 20, 18, 19, 19, 29, 19, 18, 19, 19, 33, 33, 10, 19,
+ //??,a, b, c, d, e, f, g, h, i, j, k, l, m, n, o,
+ 12, 14, 11, 11, 16, 11, 12, 14, 14, 10, 13, 12, 10, 19, 18, 12,
+ //p, q, r, s, t, u, v, w, x, y, z, ??, ??, ??, ??, ??,
+ 16, 13, 13, 11, 12, 15, 12, 15, 13, 12, 12, 37, 33, 37, 35, 37,
+ //À, Á, Â, Ä, Æ, Ç, È, É, Ê, Ë, Ì, Í, Î, Ï, Ò, Ó,
+ 16, 16, 16, 16, 33, 17, 18, 18, 18, 18, 11, 11, 11, 11, 19, 19,
+ //Ô, Ö, Ù, Ú, Û, Ü, ß, à, á, â, ä, æ, ç, è, é, ê,
+ 19, 19, 19, 19, 19, 19, 15, 14, 14, 14, 14, 20, 14, 11, 11, 11,
+ //ë, ì, í, î, ï, ò, ó, ô, ö, ù, ú, û, ü, Ñ, ñ, ¿,
+ 11, 10, 10, 10, 10, 12, 12, 12, 12, 15, 15, 15, 15, 22, 18, 21,
+ //i,BLANKS
+ 10, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 16
+ //space, unprop
+ 19, 16
},
-
{
- 15, 14, 16, 25, 19, 26, 22, 11, 18, 18, 27, 26, 13, 19, 9, 27,
- 19, 18, 19, 19, 22, 19, 20, 18, 19, 20, 12, 32, 15, 32, 15, 35,
- 15, 19, 19, 19, 19, 19, 16, 19, 20, 9, 19, 20, 14, 29, 19, 20,
- 19, 19, 19, 19, 21, 19, 20, 32, 20, 19, 19, 33, 31, 39, 37, 39,
- 37, 21, 21, 21, 23, 21, 19, 23, 23, 10, 19, 20, 16, 26, 23, 23,
- 20, 20, 20, 22, 21, 22, 22, 26, 22, 22, 23, 35, 35, 35, 35, 37,
- 19, 19, 19, 19, 29, 19, 19, 19, 19, 19, 9, 9, 9, 9, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 30, 19, 19, 19, 19,
- 19, 10, 10, 10, 10, 19, 19, 19, 19, 19, 19, 19, 19, 19, 23, 35,
- 12, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 11, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19
+ //FONT1 EFIGS
+ //Characters with a '2' refer to the Pricedown font.
+ //Characters that are referred as '*I' are characters that contain icons for PS2/XBOX, but contain regular characters on PC
+ //in order to display them properly in the Keyboard controls menu.
+ //!2,!, *I,(R), $, %, &, ', [, ], *I, +, , -, ., *I,
+ 15, 7, 31, 25, 20, 23, 21, 7, 11, 10, 26, 14, 6, 12, 6, 26,
+ //0, 1, 2, 3, 4, 5, 6, 7, 8, 9, :, *I, *I, *I, *I, ?,
+ 20, 7, 20, 20, 21, 20, 20, 19, 21, 20, 8, 30, 24, 30, 24, 19,
+ //TM,A, B, C, D, E, F, G, H, I, J, K, L, M, N, O,
+ 20, 22, 22, 21, 22, 18, 18, 22, 22, 9, 14, 21, 18, 27, 21, 24,
+ //P, Q, R, S, T, U, V, W, X, Y, Z, *I, \, *I, ¡, °,
+ 22, 22, 23, 20, 19, 23, 22, 31, 23, 23, 21, 25, 13, 30, 7, 19,
+ //(C),a, b, c, d, e, f, g, h, i, j, k, l, m, n, o,
+ 10, 17, 17, 16, 17, 17, 11, 17, 17, 7, 7, 18, 7, 25, 17, 17,
+ //p, q, r, s, t, u, v, w, x, y, z, *I, *I, $2, (2, )2,
+ 17, 17, 11, 17, 11, 17, 18, 25, 19, 18, 17, 28, 26, 20, 15, 15,
+ //À, Á, Â, Ä, Æ, Ç, È, É, Ê, Ë, Ì, Í, Î, Ï, Ò, Ó,
+ 20, 20, 20, 20, 29, 22, 19, 19, 19, 19, 9, 9, 9, 9, 23, 23,
+ //Ô, Ö, Ù, Ú, Û, Ü, ß, à, á, â, ä, æ, ç, è, é, ê,
+ 23, 23, 24, 24, 24, 24, 20, 19, 17, 17, 17, 30, 16, 17, 17, 17,
+ //ë, ì, í, î, ï, ò, ó, ô, ö, ù, ú, û, ü, Ñ, ñ, ¿,
+ 17, 11, 11, 15, 12, 17, 17, 17, 17, 17, 17, 17, 17, 21, 17, 19,
+ //02,12,22, 32, 42, 52, 62, 72, 82, 92, :2, A2, B2, C2, D2, E2,
+ 20, 18, 19, 19, 21, 19, 19, 19, 19, 19, 16, 19, 19, 19, 20, 19,
+ //F2,G2,H2, I2, J2, K2, L2, M2, N2, O2, P2, Q2, R2, S2, T2, U2,
+ 16, 19, 19, 9, 19, 20, 14, 29, 19, 19, 19, 19, 19, 19, 21, 19,
+ //V2,W2,X2, Y2, Z2, À2, Á2, Â2, Ä2, Æ2, Ç2, È2, É2, Ê2, Ë2, Ì2,
+ 20, 32, 20, 19, 19, 19, 19, 19, 19, 29, 19, 19, 19, 19, 19, 9,
+ //Í2,Î2,Ï2, Ò2, Ó2, Ô2, Ö2, Ù2, Ú2, Û2, Ü2, ß2, Ñ2, ¿2, '2, .2,
+ 9, 9, 9, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 10, 9,
+ //space, unprop
+ 10, 20
}
}
#endif
@@ -279,6 +280,21 @@ wchar foreign_table[128] = {
0, 174, 165, 166, 167, 0, 168, 0, 0, 169, 170, 171, 172, 0, 0, 0,
};
+union tFontRenderStatePointer
+{
+ CFontRenderState *pRenderState;
+ wchar *pStr;
+
+ void Align()
+ {
+ if ((uintptr)pStr % 4)
+ pStr++;
+ }
+};
+
+tFontRenderStatePointer FontRenderStatePointer;
+uint8 FontRenderStateBuf[1024];
+
#ifdef BUTTON_ICONS
CSprite2d CFont::ButtonSprite[MAX_BUTTON_ICONS];
int CFont::PS2Symbol = BUTTON_NONE;
@@ -315,29 +331,22 @@ CFont::Initialise(void)
CTxdStore::AddRef(slot);
CTxdStore::PushCurrentTxd();
CTxdStore::SetCurrentTxd(slot);
- Sprite[0].SetTexture("font2", "font2_mask");
+ Sprite[0].SetTexture("font2", "font2m");
#ifdef MORE_LANGUAGES
if (IsJapanese()) {
Sprite[1].SetTexture("FONTJAP", "FONTJAP_mask");
Sprite[3].SetTexture("FONTJAP", "FONTJAP_mask");
}
- else
#endif // MORE_LANGUAGES
- Sprite[1].SetTexture("pager", "pager_mask");
- Sprite[2].SetTexture("font1", "font1_mask");
+ Sprite[1].SetTexture("font1", "font1m");
SetScale(1.0f, 1.0f);
SetSlantRefPoint(SCREEN_WIDTH, 0.0f);
SetSlant(0.0f);
SetColor(CRGBA(255, 255, 255, 0));
SetJustifyOff();
SetCentreOff();
-#ifdef FIX_BUGS
- SetWrapx(SCREEN_STRETCH_X(DEFAULT_SCREEN_WIDTH));
- SetCentreSize(SCREEN_STRETCH_X(DEFAULT_SCREEN_WIDTH));
-#else
- SetWrapx(DEFAULT_SCREEN_WIDTH);
- SetCentreSize(DEFAULT_SCREEN_WIDTH);
-#endif
+ SetWrapx(SCREEN_WIDTH);
+ SetCentreSize(SCREEN_WIDTH);
SetBackgroundOff();
SetBackgroundColor(CRGBA(128, 128, 128, 128));
SetBackGroundOnlyTextOff();
@@ -356,7 +365,7 @@ CFont::Initialise(void)
#ifdef BUTTON_ICONS
void
-CFont::LoadButtons(const char* txdPath)
+CFont::LoadButtons(const char *txdPath)
{
if (int file = CFileMgr::OpenFile(txdPath)) {
CFileMgr::CloseFile(file);
@@ -371,12 +380,10 @@ CFont::LoadButtons(const char* txdPath)
CTxdStore::AddRef(ButtonsSlot);
CTxdStore::PushCurrentTxd();
CTxdStore::SetCurrentTxd(ButtonsSlot);
-#if 0 // unused
- ButtonSprite[BUTTON_UP].SetTexture("up");
- ButtonSprite[BUTTON_DOWN].SetTexture("down");
- ButtonSprite[BUTTON_LEFT].SetTexture("left");
- ButtonSprite[BUTTON_RIGHT].SetTexture("right");
-#endif
+ ButtonSprite[BUTTON_UP].SetTexture("thumblyu");
+ ButtonSprite[BUTTON_DOWN].SetTexture("thumblyd");
+ ButtonSprite[BUTTON_LEFT].SetTexture("thumblxl");
+ ButtonSprite[BUTTON_RIGHT].SetTexture("thumblxr");
ButtonSprite[BUTTON_CROSS].SetTexture("cross");
ButtonSprite[BUTTON_CIRCLE].SetTexture("circle");
ButtonSprite[BUTTON_SQUARE].SetTexture("square");
@@ -387,6 +394,10 @@ CFont::LoadButtons(const char* txdPath)
ButtonSprite[BUTTON_R1].SetTexture("r1");
ButtonSprite[BUTTON_R2].SetTexture("r2");
ButtonSprite[BUTTON_R3].SetTexture("r3");
+ ButtonSprite[BUTTON_RSTICK_UP].SetTexture("thumbryu");
+ ButtonSprite[BUTTON_RSTICK_DOWN].SetTexture("thumbryd");
+ ButtonSprite[BUTTON_RSTICK_LEFT].SetTexture("thumbrxl");
+ ButtonSprite[BUTTON_RSTICK_RIGHT].SetTexture("thumbrxr");
CTxdStore::PopCurrentTxd();
}
else {
@@ -407,9 +418,8 @@ CFont::ReloadFonts(uint8 set)
if (Slot != -1 && LanguageSet != set) {
Sprite[0].Delete();
Sprite[1].Delete();
- Sprite[2].Delete();
if (IsJapanese())
- Sprite[3].Delete();
+ Sprite[2].Delete();
CTxdStore::PushCurrentTxd();
CTxdStore::RemoveTxd(Slot);
switch (set)
@@ -431,12 +441,9 @@ CFont::ReloadFonts(uint8 set)
CTxdStore::SetCurrentTxd(Slot);
Sprite[0].SetTexture("font2", "font2_mask");
if (set == FONT_LANGSET_JAPANESE) {
- Sprite[1].SetTexture("FONTJAP", "FONTJAP_mask");
- Sprite[3].SetTexture("FONTJAP", "FONTJAP_mask");
+ Sprite[2].SetTexture("FONTJAP", "FONTJAP_mask");
}
- else
- Sprite[1].SetTexture("pager", "pager_mask");
- Sprite[2].SetTexture("font1", "font1_mask");
+ Sprite[1].SetTexture("font1", "font1_mask");
CTxdStore::PopCurrentTxd();
}
LanguageSet = set;
@@ -456,7 +463,6 @@ CFont::Shutdown(void)
#endif
Sprite[0].Delete();
Sprite[1].Delete();
- Sprite[2].Delete();
#ifdef MORE_LANGUAGES
if (IsJapanese())
Sprite[3].Delete();
@@ -470,13 +476,9 @@ CFont::Shutdown(void)
void
CFont::InitPerFrame(void)
{
- Details.bank = CSprite2d::GetBank(30, Sprite[0].m_pTexture);
- CSprite2d::GetBank(15, Sprite[1].m_pTexture);
- CSprite2d::GetBank(15, Sprite[2].m_pTexture);
-#ifdef MORE_LANGUAGES
- if (IsJapanese())
- CSprite2d::GetBank(15, Sprite[3].m_pTexture);
-#endif
+ RenderState.style = -1;
+ Details.anonymous_25 = 0;
+ FontRenderStatePointer.pRenderState = (CFontRenderState*)FontRenderStateBuf;
SetDropShadowPosition(0);
NewLine = false;
#ifdef BUTTON_ICONS
@@ -494,14 +496,20 @@ CFont::DrawButton(float x, float y)
if (PS2Symbol != BUTTON_NONE) {
CRect rect;
rect.left = x;
- rect.top = Details.scaleY + Details.scaleY + y;
- rect.right = Details.scaleY * 17.0f + x;
- rect.bottom = Details.scaleY * 19.0f + y;
+ rect.top = RenderState.scaleY + RenderState.scaleY + y;
+ rect.right = RenderState.scaleY * 17.0f + x;
+ rect.bottom = RenderState.scaleY * 19.0f + y;
int vertexAlphaState;
+ void *raster;
RwRenderStateGet(rwRENDERSTATEVERTEXALPHAENABLE, &vertexAlphaState);
+ RwRenderStateGet(rwRENDERSTATETEXTURERASTER, &raster);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)TRUE);
- ButtonSprite[PS2Symbol].Draw(rect, CRGBA(255, 255, 255, Details.color.a));
+ if (RenderState.bIsShadow)
+ ButtonSprite[PS2Symbol].Draw(rect, RenderState.color);
+ else
+ ButtonSprite[PS2Symbol].Draw(rect, CRGBA(255, 255, 255, RenderState.color.a));
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, raster);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)vertexAlphaState);
}
}
@@ -510,15 +518,15 @@ CFont::DrawButton(float x, float y)
void
CFont::PrintChar(float x, float y, wchar c)
{
+ bool bDontPrint = false;
if(x <= 0.0f || x > SCREEN_WIDTH ||
-#ifdef FIX_BUGS
- y <= 0.0f || y > SCREEN_HEIGHT)
-#else
- y <= 0.0f || y > SCREEN_WIDTH)
-#endif
+ y <= 0.0f || y > SCREEN_HEIGHT) // BUG: game uses SCREENW again
return;
+ bDontPrint = c == '\0';
float w = GetCharacterWidth(c) / 32.0f;
+ if (Details.bFontHalfTexture && c == 208)
+ c = '\0';
float xoff = c % 16;
float yoff = c / 16;
#ifdef MORE_LANGUAGES
@@ -529,65 +537,52 @@ CFont::PrintChar(float x, float y, wchar c)
}
#endif
- if(Details.style == FONT_BANK || Details.style == FONT_HEADING){
- if(Details.dropShadowPosition != 0){
- CSprite2d::AddSpriteToBank(
-#ifdef FIX_BUGS
- Details.bank + Details.style,
-#else
- Details.style, // BUG: game doesn't add bank
-#endif
-#ifdef FIX_BUGS
- CRect(x + SCREEN_SCALE_X(Details.dropShadowPosition),
- y + SCREEN_SCALE_Y(Details.dropShadowPosition),
- x + SCREEN_SCALE_X(Details.dropShadowPosition) + 32.0f * Details.scaleX * 1.0f,
- y + SCREEN_SCALE_Y(Details.dropShadowPosition) + 40.0f * Details.scaleY * 0.5f),
-#else
- CRect(x + Details.dropShadowPosition,
- y + Details.dropShadowPosition,
- x + Details.dropShadowPosition + 32.0f * Details.scaleX * 1.0f,
- y + Details.dropShadowPosition + 40.0f * Details.scaleY * 0.5f),
-#endif
- Details.dropColor,
- xoff/16.0f, yoff/12.8f,
- (xoff+1.0f)/16.0f - 0.001f, yoff/12.8f,
- xoff/16.0f, (yoff+1.0f)/12.8f,
- (xoff+1.0f)/16.0f - 0.001f, (yoff+1.0f)/12.8f - 0.0001f);
- }
- CSprite2d::AddSpriteToBank(
+ if(RenderState.style == FONT_BANK || RenderState.style == FONT_STANDARD){
+ if (bDontPrint) return;
+ if (RenderState.slant == 0.0f) {
#ifdef FIX_BUGS
- Details.bank + Details.style,
+ if (c < 192) {
#else
- Details.style, // BUG: game doesn't add bank
-#endif
- CRect(x, y,
- x + 32.0f * Details.scaleX * 1.0f,
- y + 40.0f * Details.scaleY * 0.5f),
- Details.color,
- xoff/16.0f, yoff/12.8f,
- (xoff+1.0f)/16.0f - 0.001f, yoff/12.8f,
- xoff/16.0f, (yoff+1.0f)/12.8f - 0.002f,
- (xoff+1.0f)/16.0f - 0.001f, (yoff+1.0f)/12.8f - 0.002f);
+ if (c < 193) {
+#endif
+ CSprite2d::AddToBuffer(
+ CRect(x, y,
+ x + 32.0f * RenderState.scaleX * 1.0f,
+ y + 40.0f * RenderState.scaleY * 0.5f),
+ RenderState.color,
+ xoff / 16.0f, yoff / 12.8f + 0.0021f,
+ (xoff + 1.0f) / 16.0f - 0.001f, yoff / 12.8f + 0.0021f,
+ xoff / 16.0f, (yoff + 1.0f) / 12.8f - 0.0021f,
+ (xoff + 1.0f) / 16.0f - 0.001f, (yoff + 1.0f) / 12.8f - 0.0021f);
+ } else {
+ CSprite2d::AddToBuffer(
+ CRect(x, y,
+ x + 32.0f * RenderState.scaleX * 1.0f,
+ y + 33.0f * RenderState.scaleY * 0.5f),
+ RenderState.color,
+ xoff / 16.0f, yoff / 12.8f + 0.0021f,
+ (xoff + 1.0f) / 16.0f - 0.001f, yoff / 12.8f + 0.0021f,
+ xoff / 16.0f, (yoff + 1.0f) / 12.8f - 0.017f,
+ (xoff + 1.0f) / 16.0f - 0.001f, (yoff + 1.0f) / 12.8f - 0.017f);
+ }
+ } else
+ CSprite2d::AddToBuffer(
+ CRect(x, y,
+ x + 32.0f * RenderState.scaleX * 1.0f,
+ y + 40.0f * RenderState.scaleY * 0.5f),
+ RenderState.color,
+ xoff / 16.0f, yoff / 12.8f + 0.00055f,
+ (xoff + 1.0f) / 16.0f - 0.001f, yoff / 12.8f + 0.0021f + 0.01f,
+ xoff / 16.0f, (yoff + 1.0f) / 12.8f - 0.009f,
+ (xoff + 1.0f) / 16.0f - 0.001f, (yoff + 1.0f) / 12.8f - 0.0021f + 0.01f);
#ifdef MORE_LANGUAGES
- }else if (IsJapaneseFont()) {
+ /*}else if (IsJapaneseFont()) {
if (Details.dropShadowPosition != 0) {
- CSprite2d::AddSpriteToBank(
-#ifdef FIX_BUGS
- Details.bank + Details.style,
-#else
- Details.style, // BUG: game doesn't add bank
-#endif
-#ifdef FIX_BUGS
+ CSprite2d::AddSpriteToBank(Details.bank + Details.style, // BUG: game doesn't add bank
CRect(x + SCREEN_SCALE_X(Details.dropShadowPosition),
y + SCREEN_SCALE_Y(Details.dropShadowPosition),
x + SCREEN_SCALE_X(Details.dropShadowPosition) + 32.0f * Details.scaleX * 1.0f,
y + SCREEN_SCALE_Y(Details.dropShadowPosition) + 40.0f * Details.scaleY / 2.75f),
-#else
- CRect(x + Details.dropShadowPosition,
- y + Details.dropShadowPosition,
- x + Details.dropShadowPosition + 32.0f * Details.scaleX * 1.0f,
- y + Details.dropShadowPosition + 40.0f * Details.scaleY / 2.75f),
-#endif
Details.dropColor,
xoff * w / 1024.0f, yoff / 25.6f,
xoff * w / 1024.0f + (1.0f / 48.0f) - 0.001f, yoff / 25.6f,
@@ -602,24 +597,19 @@ CFont::PrintChar(float x, float y, wchar c)
xoff * w / 1024.0f, yoff / 25.6f,
xoff * w / 1024.0f + (1.0f / 48.0f) - 0.001f, yoff / 25.6f,
xoff * w / 1024.0f, (yoff + 1.0f) / 25.6f - 0.002f,
- xoff * w / 1024.0f + (1.0f / 48.0f) - 0.001f, (yoff + 1.0f) / 25.6f - 0.0001f);
-#endif
- }else
- {
- CSprite2d::AddSpriteToBank(
-#ifdef FIX_BUGS
- Details.bank + Details.style,
-#else
- Details.style, // BUG: game doesn't add bank
+ xoff * w / 1024.0f + (1.0f / 48.0f) - 0.001f, (yoff + 1.0f) / 25.6f - 0.0001f);*/
#endif
+ } else {
+ if (bDontPrint) return;
+ CSprite2d::AddToBuffer(
CRect(x, y,
- x + 32.0f * Details.scaleX * w,
- y + 32.0f * Details.scaleY * 0.5f),
- Details.color,
- xoff/16.0f, yoff/16.0f,
- (xoff+w)/16.0f, yoff/16.0f,
- xoff/16.0f, (yoff+1.0f)/16.0f,
- (xoff+w)/16.0f - 0.0001f, (yoff+1.0f)/16.0f - 0.0001f);
+ x + 32.0f * RenderState.scaleX * w,
+ y + 32.0f * RenderState.scaleY * 0.5f),
+ RenderState.color,
+ xoff / 16.0f, yoff / 16.0f,
+ (xoff + w) / 16.0f, yoff / 16.0f,
+ xoff / 16.0f, (yoff + 1.0f) / 16.0f,
+ (xoff + w) / 16.0f - 0.0001f, (yoff + 1.0f) / 16.0f - 0.0001f);
}
}
@@ -646,6 +636,210 @@ bool CFont::IsAnsiCharacter(wchar *s)
#endif
void
+CFont::RenderFontBuffer()
+{
+ if (FontRenderStatePointer.pRenderState == (CFontRenderState*)FontRenderStateBuf) return;
+
+ float textPosX;
+ float textPosY;
+ CRGBA color;
+ bool bBold = false;
+ bool bFlash = false;
+
+ Sprite[RenderState.style].SetRenderState();
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ RenderState = *(CFontRenderState*)&FontRenderStateBuf[0];
+ textPosX = RenderState.fTextPosX;
+ textPosY = RenderState.fTextPosY;
+ color = RenderState.color;
+ tFontRenderStatePointer pRenderStateBufPointer;
+ pRenderStateBufPointer.pRenderState = (CFontRenderState*)&FontRenderStateBuf[0];
+ for (++pRenderStateBufPointer.pRenderState; pRenderStateBufPointer.pStr < FontRenderStatePointer.pStr; pRenderStateBufPointer.pStr++) {
+ if (*pRenderStateBufPointer.pStr == '\0') {
+ tFontRenderStatePointer tmpPointer = pRenderStateBufPointer;
+ tmpPointer.pStr++;
+ tmpPointer.Align();
+ if (tmpPointer.pStr >= FontRenderStatePointer.pStr)
+ break;
+
+ RenderState = *(tmpPointer.pRenderState++);
+
+ pRenderStateBufPointer = tmpPointer;
+
+ textPosX = RenderState.fTextPosX;
+ textPosY = RenderState.fTextPosY;
+ color = RenderState.color;
+ }
+ if (*pRenderStateBufPointer.pStr == '~') {
+#ifdef BUTTON_ICONS
+ PS2Symbol = BUTTON_NONE;
+#endif
+ pRenderStateBufPointer.pStr = ParseToken(pRenderStateBufPointer.pStr, color, bFlash, bBold);
+#ifdef BUTTON_ICONS
+ if(PS2Symbol != BUTTON_NONE) {
+ DrawButton(textPosX, textPosY);
+ textPosX += RenderState.scaleY * 17.0f;
+ PS2Symbol = BUTTON_NONE;
+ }
+#endif
+ if (bFlash) {
+ if (CTimer::GetTimeInMilliseconds() - Details.nFlashTimer > 300) {
+ Details.bFlashState = !Details.bFlashState;
+ Details.nFlashTimer = CTimer::GetTimeInMilliseconds();
+ }
+ Details.color.alpha = Details.bFlashState ? 0 : 255;
+ }
+ if (!RenderState.bIsShadow)
+ RenderState.color = color;
+ }
+ wchar c = *pRenderStateBufPointer.pStr;
+ c -= ' ';
+ if (RenderState.bFontHalfTexture)
+ c = FindNewCharacter(c);
+ else if (c > 155)
+ c = '\0';
+
+ if (RenderState.slant != 0.0f)
+ textPosY = (RenderState.slantRefX - textPosX) * RenderState.slant + RenderState.slantRefY;
+ PrintChar(textPosX, textPosY, c);
+ if (bBold) {
+ PrintChar(textPosX + 1.0f, textPosY, c);
+ PrintChar(textPosX + 2.0f, textPosY, c);
+ textPosX += 2.0f;
+ }
+#ifdef FIX_BUGS
+ // PS2 uses different chars for some symbols
+ if (!RenderState.bFontHalfTexture && c == 30) c = 61; // wanted star
+#endif
+ textPosX += RenderState.scaleX * GetCharacterWidth(c);
+ if (c == '\0')
+ textPosX += RenderState.fExtraSpace;
+ }
+ CSprite2d::RenderVertexBuffer();
+ FontRenderStatePointer.pRenderState = (CFontRenderState*)FontRenderStateBuf;
+}
+
+#if 0 //def MORE_LANGUAGES
+bool
+CFont::PrintString(float x, float y, wchar *start, wchar *&end, float spwidth, float japX)
+{
+ wchar *s, c, unused;
+
+ if (IsJapanese()) {
+ float jx = 0.0f;
+ for (s = start; s < end; s++) {
+ if (*s == JAP_TERMINATION || *s == '~')
+ s = ParseToken(s, &unused, true);
+ if (NewLine) {
+ NewLine = false;
+ break;
+ }
+ jx += GetCharacterSize(*s - ' ');
+ }
+ s = start;
+ if (Details.centre)
+ x = japX - jx / 2.0f;
+ else if (Details.rightJustify)
+ x = japX - jx;
+ }
+
+ for (s = start; s < end; s++) {
+ if (*s == '~' || (IsJapanese() && *s == JAP_TERMINATION))
+ s = ParseToken(s, &unused);
+ if (NewLine && IsJapanese()) {
+ NewLine = false;
+ end = s;
+ return true;
+ }
+ c = *s - ' ';
+ if (Details.slant != 0.0f && !IsJapanese())
+ y = (Details.slantRefX - x) * Details.slant + Details.slantRefY;
+
+ PrintChar(x, y, c);
+ x += GetCharacterSize(c);
+ if (c == 0 && (!NewLine || !IsJapanese())) // space
+ x += spwidth;
+ }
+ return false;
+}
+#else
+void
+CFont::PrintString(float x, float y, uint32, wchar *start, wchar *end, float spwidth)
+{
+ wchar *s;
+
+ if (RenderState.style != Details.style) {
+ RenderFontBuffer();
+ RenderState.style = Details.style;
+ }
+
+ float dropShadowPosition = Details.dropShadowPosition;
+ if (dropShadowPosition != 0.0f && (Details.style == FONT_BANK || Details.style == FONT_STANDARD)) {
+ CRGBA color = Details.color;
+ Details.color = Details.dropColor;
+ Details.dropShadowPosition = 0;
+ Details.bIsShadow = true;
+ if (Details.slant != 0.0f) {
+ Details.slantRefX += SCREEN_SCALE_X(dropShadowPosition);
+ Details.slantRefY += SCREEN_SCALE_Y(dropShadowPosition);
+ PrintString(SCREEN_SCALE_X(dropShadowPosition) + x, SCREEN_SCALE_Y(dropShadowPosition) + y, Details.anonymous_25, start, end, spwidth);
+ Details.slantRefX -= SCREEN_SCALE_X(dropShadowPosition);
+ Details.slantRefY -= SCREEN_SCALE_Y(dropShadowPosition);
+ } else {
+ PrintString(SCREEN_SCALE_X(dropShadowPosition) + x, SCREEN_SCALE_Y(dropShadowPosition) + y, Details.anonymous_25, start, end, spwidth);
+ }
+ Details.color = color;
+ Details.dropShadowPosition = dropShadowPosition;
+ Details.bIsShadow = false;
+ }
+ if (FontRenderStatePointer.pStr >= (wchar*)&FontRenderStateBuf[ARRAY_SIZE(FontRenderStateBuf)] - (end - start + 26)) // why 26?
+ RenderFontBuffer();
+ CFontRenderState *pRenderState = FontRenderStatePointer.pRenderState;
+ pRenderState->fTextPosX = x;
+ pRenderState->fTextPosY = y;
+ pRenderState->scaleX = Details.scaleX;
+ pRenderState->scaleY = Details.scaleY;
+ pRenderState->color = Details.color;
+ pRenderState->fExtraSpace = spwidth;
+ pRenderState->slant = Details.slant;
+ pRenderState->slantRefX = Details.slantRefX;
+ pRenderState->slantRefY = Details.slantRefY;
+ pRenderState->bFontHalfTexture = Details.bFontHalfTexture;
+ pRenderState->proportional = Details.proportional;
+ pRenderState->style = Details.style;
+ pRenderState->bIsShadow = Details.bIsShadow;
+ FontRenderStatePointer.pRenderState++;
+
+ for(s = start; s < end;){
+ if (*s == '~') {
+ for (wchar *i = ParseToken(s); s != i; FontRenderStatePointer.pStr++) {
+ *FontRenderStatePointer.pStr = *(s++);
+ }
+ if (Details.bFlash) {
+ if (CTimer::GetTimeInMilliseconds() - Details.nFlashTimer > 300) {
+ Details.bFlashState = !Details.bFlashState;
+ Details.nFlashTimer = CTimer::GetTimeInMilliseconds();
+ }
+ Details.color.a = Details.bFlashState ? 0 : 255;
+ }
+ } else
+ *(FontRenderStatePointer.pStr++) = *(s++);
+ }
+ *(FontRenderStatePointer.pStr++) = '\0';
+ FontRenderStatePointer.Align();
+}
+#endif
+
+void
+CFont::PrintStringFromBottom(float x, float y, wchar *str)
+{
+ y -= (32.0f * Details.scaleY / 2.0f + 2.0f * Details.scaleY) * GetNumberLines(x, y, str);
+ if (Details.slant != 0.0f)
+ y -= ((Details.slantRefX - x) * Details.slant + Details.slantRefY);
+ PrintString(x, y, str);
+}
+
+void
CFont::PrintString(float xstart, float ystart, wchar *s)
{
CRect rect;
@@ -655,10 +849,14 @@ CFont::PrintString(float xstart, float ystart, wchar *s)
bool first;
wchar *start, *t;
+ Details.bFlash = false;
+
if(*s == '*')
return;
+ Details.anonymous_25++;
if(Details.background){
+ RenderState.color = Details.color;
GetNumberLines(xstart, ystart, s); // BUG: result not used
GetTextRect(&rect, xstart, ystart, s);
CSprite2d::DrawRect(rect, Details.backgroundColor);
@@ -698,10 +896,10 @@ CFont::PrintString(float xstart, float ystart, wchar *s)
float xleft = Details.centre ? xstart - x/2 :
Details.rightJustify ? xstart - x :
xstart;
-#ifdef MORE_LANGUAGES
+#if 0//def MORE_LANGUAGES
PrintString(xleft, y, start, s, spaceWidth, xstart);
#else
- PrintString(xleft, y, start, s, spaceWidth);
+ PrintString(xleft, y, Details.anonymous_25, start, s, spaceWidth);
#endif
// reset things
lineLength = 0.0f;
@@ -713,10 +911,10 @@ CFont::PrintString(float xstart, float ystart, wchar *s)
x = xstart;
#ifdef MORE_LANGUAGES
if (IsJapaneseFont())
- y += 32.0f * CFont::Details.scaleY / 2.75f + 2.0f * CFont::Details.scaleY;
+ y += 32.0f * Details.scaleY / 2.75f + 2.0f * Details.scaleY;
else
#endif
- y += 32.0f * CFont::Details.scaleY * 0.5f + 2.0f * CFont::Details.scaleY;
+ y += 32.0f * Details.scaleY * 0.5f + 2.0f * Details.scaleY;
start = s;
}else
break;
@@ -736,7 +934,7 @@ CFont::PrintString(float xstart, float ystart, wchar *s)
#endif
lineLength = x;
s = t+1;
-#ifdef MORE_LANGUAGES
+#if 0 //def MORE_LANGUAGES
if (IsJapaneseFont() && !*s) {
x += GetStringWidth(s);
if (IsAnsiCharacter(s))
@@ -752,7 +950,7 @@ CFont::PrintString(float xstart, float ystart, wchar *s)
else
x = 0.0f;
- y += 32.0f * CFont::Details.scaleY / 2.75f + 2.0f * CFont::Details.scaleY;
+ y += 32.0f * Details.scaleY / 2.75f + 2.0f * Details.scaleY;
numSpaces = 0;
first = true;
lineLength = 0.0f;
@@ -768,20 +966,20 @@ CFont::PrintString(float xstart, float ystart, wchar *s)
float xleft = Details.centre ? xstart - x/2 :
Details.rightJustify ? xstart - x :
xstart;
-#ifdef MORE_LANGUAGES
+#if 0 //def MORE_LANGUAGES
if (PrintString(xleft, y, start, s, 0.0f, xstart) && IsJapaneseFont()) {
start = s;
if (!Details.centre && !Details.rightJustify)
x = xstart;
else
x = 0.0f;
- y += 32.0f * CFont::Details.scaleY / 2.75f + 2.0f * CFont::Details.scaleY;
+ y += 32.0f * Details.scaleY / 2.75f + 2.0f * Details.scaleY;
numSpaces = 0;
first = true;
lineLength = 0.0f;
}
#else
- PrintString(xleft, y, start, s, 0.0f);
+ PrintString(xleft, y, Details.anonymous_25, start, s, 0.0f);
#endif
}
}
@@ -794,7 +992,7 @@ CFont::GetNumberLines(float xstart, float ystart, wchar *s)
wchar *t;
n = 0;
-#ifdef MORE_LANGUAGES
+#if 0//def MORE_LANGUAGES
bool bSomeJapBool = false;
if (IsJapanese()) {
@@ -852,10 +1050,10 @@ CFont::GetNumberLines(float xstart, float ystart, wchar *s)
// Why even?
#ifdef MORE_LANGUAGES
if (IsJapanese())
- y += 32.0f * CFont::Details.scaleY / 2.75f + 2.0f * CFont::Details.scaleY;
+ y += 32.0f * Details.scaleY / 2.75f + 2.0f * Details.scaleY;
else
#endif
- y += 32.0f * CFont::Details.scaleY * 0.5f + 2.0f * CFont::Details.scaleY;
+ y += 32.0f * Details.scaleY * 0.5f + 2.0f * Details.scaleY;
}else{
// still space in current line
t = GetNextSpace(s);
@@ -903,12 +1101,7 @@ CFont::GetTextRect(CRect *rect, float xstart, float ystart, wchar *s)
numLines = GetNumberLines(xstart, ystart, s);
}else{
#endif
-
-#ifdef FIX_BUGS
if(Details.centre || Details.rightJustify)
-#else
- if(Details.centre)
-#endif
x = 0.0f;
else
x = xstart;
@@ -926,16 +1119,12 @@ CFont::GetTextRect(CRect *rect, float xstart, float ystart, wchar *s)
// reached end of line
if(x > maxlength)
maxlength = x;
-#ifdef FIX_BUGS
if(Details.centre || Details.rightJustify)
-#else
- if(Details.centre)
-#endif
x = 0.0f;
else
x = xstart;
numLines++;
- y += 32.0f * CFont::Details.scaleY * 0.5f + 2.0f * CFont::Details.scaleY;
+ y += 32.0f * Details.scaleY * 0.5f + 2.0f * Details.scaleY;
}else{
// still space in current line
t = GetNextSpace(s);
@@ -963,11 +1152,11 @@ CFont::GetTextRect(CRect *rect, float xstart, float ystart, wchar *s)
rect->right = xstart + maxlength/2 + 4.0f;
#ifdef MORE_LANGUAGES
if (IsJapaneseFont()) {
- rect->bottom = (32.0f * CFont::Details.scaleY / 2.75f + 2.0f * CFont::Details.scaleY) * numLines + ystart + (4.0f / 2.75f);
+ rect->bottom = (32.0f * Details.scaleY / 2.75f + 2.0f * Details.scaleY) * numLines + ystart + (4.0f / 2.75f);
rect->top = ystart - (4.0f / 2.75f);
} else {
#endif
- rect->bottom = (32.0f * CFont::Details.scaleY * 0.5f + 2.0f * CFont::Details.scaleY) * numLines + ystart + 2.0f;
+ rect->bottom = (32.0f * Details.scaleY * 0.5f + 2.0f * Details.scaleY) * numLines + ystart + 2.0f;
rect->top = ystart - 2.0f;
#ifdef MORE_LANGUAGES
}
@@ -977,11 +1166,11 @@ CFont::GetTextRect(CRect *rect, float xstart, float ystart, wchar *s)
rect->right = xstart + Details.centreSize*0.5f + 4.0f;
#ifdef MORE_LANGUAGES
if (IsJapaneseFont()) {
- rect->bottom = (32.0f * CFont::Details.scaleY / 2.75f + 2.0f * CFont::Details.scaleY) * numLines + ystart + (4.0f / 2.75f);
+ rect->bottom = (32.0f * Details.scaleY / 2.75f + 2.0f * Details.scaleY) * numLines + ystart + (4.0f / 2.75f);
rect->top = ystart - (4.0f / 2.75f);
} else {
#endif
- rect->bottom = (32.0f * CFont::Details.scaleY * 0.5f + 2.0f * CFont::Details.scaleY) * numLines + ystart + 2.0f;
+ rect->bottom = (32.0f * Details.scaleY * 0.5f + 2.0f * Details.scaleY) * numLines + ystart + 2.0f;
rect->top = ystart - 2.0f;
#ifdef MORE_LANGUAGES
}
@@ -994,159 +1183,51 @@ CFont::GetTextRect(CRect *rect, float xstart, float ystart, wchar *s)
rect->bottom = ystart - 4.0f + 4.0f;
#ifdef MORE_LANGUAGES
if (IsJapaneseFont())
- rect->top = (32.0f * CFont::Details.scaleY / 2.75f + 2.0f * CFont::Details.scaleY) * numLines + ystart + 2.0f + (4.0f / 2.75f);
+ rect->top = (32.0f * Details.scaleY / 2.75f + 2.0f * Details.scaleY) * numLines + ystart + 2.0f + (4.0f / 2.75f);
else
#endif
- rect->top = (32.0f * CFont::Details.scaleY * 0.5f + 2.0f * CFont::Details.scaleY) * numLines + ystart + 2.0f + 2.0f;
+ rect->top = (32.0f * Details.scaleY * 0.5f + 2.0f * Details.scaleY) * numLines + ystart + 2.0f + 2.0f;
}
}
-#ifdef MORE_LANGUAGES
-bool
-CFont::PrintString(float x, float y, wchar *start, wchar *&end, float spwidth, float japX)
-{
- wchar *s, c, unused;
-
- if (IsJapanese()) {
- float jx = 0.0f;
- for (s = start; s < end; s++) {
- if (*s == JAP_TERMINATION || *s == '~')
- s = ParseToken(s, &unused, true);
- if (NewLine) {
- NewLine = false;
- break;
- }
- jx += GetCharacterSize(*s - ' ');
- }
- s = start;
- if (Details.centre)
- x = japX - jx / 2.0f;
- else if (Details.rightJustify)
- x = japX - jx;
- }
-
- for (s = start; s < end; s++) {
- if (*s == '~' || (IsJapanese() && *s == JAP_TERMINATION))
- s = ParseToken(s, &unused);
- if (NewLine && IsJapanese()) {
- NewLine = false;
- end = s;
- return true;
- }
- c = *s - ' ';
- if (Details.slant != 0.0f && !IsJapanese())
- y = (Details.slantRefX - x) * Details.slant + Details.slantRefY;
-
-#ifdef BUTTON_ICONS
- if (PS2Symbol != BUTTON_NONE) {
- DrawButton(x, y);
- x += Details.scaleY * 17.0f;
- PS2Symbol = BUTTON_NONE;
- }
-#endif
-
- PrintChar(x, y, c);
- x += GetCharacterSize(c);
- if (c == 0 && (!NewLine || !IsJapanese())) // space
- x += spwidth;
- }
- return false;
-}
-#else
-void
-CFont::PrintString(float x, float y, wchar *start, wchar *end, float spwidth)
-{
- wchar *s, c, unused;
-
- for(s = start; s < end; s++){
- if(*s == '~')
- s = ParseToken(s, &unused);
- c = *s - ' ';
- if(Details.slant != 0.0f)
- y = (Details.slantRefX - x)*Details.slant + Details.slantRefY;
- PrintChar(x, y, c);
- x += GetCharacterSize(c);
- if(c == 0) // space
- x += spwidth;
- }
-}
-#endif
-
-void
-CFont::PrintStringFromBottom(float x, float y, wchar *str)
-{
-#ifdef MORE_LANGUAGES
- if (IsJapaneseFont())
- y -= (32.0f * CFont::Details.scaleY / 2.75f + 2.0f * CFont::Details.scaleY) * GetNumberLines(x, y, str);
- else
-#endif
- y -= (32.0f * CFont::Details.scaleY * 0.5f + 2.0f * CFont::Details.scaleY) * GetNumberLines(x, y, str);
- PrintString(x, y, str);
-}
-
-#ifdef XBOX_SUBTITLES
-void
-CFont::PrintOutlinedString(float x, float y, wchar *str, float outlineStrength, bool fromBottom, CRGBA outlineColor)
-{
- CRGBA textColor = Details.color;
- SetColor(outlineColor);
- CVector2D offsets[] = { {1.f, 1.f}, {1.f, -1.f}, {-1.f, 1.f}, {-1.f, -1.f} };
- for(int i = 0; i < ARRAY_SIZE(offsets); i++){
- if (fromBottom)
- PrintStringFromBottom(x + SCREEN_SCALE_X(offsets[i].x * outlineStrength), y + SCREEN_SCALE_Y(offsets[i].y * outlineStrength), str);
- else
- PrintString(x + SCREEN_SCALE_X(offsets[i].x * outlineStrength), y + SCREEN_SCALE_Y(offsets[i].y * outlineStrength), str);
- }
- SetColor(textColor);
-
- if (fromBottom)
- PrintStringFromBottom(x, y, str);
- else
- PrintString(x, y, str);
-}
-#endif
-
float
CFont::GetCharacterWidth(wchar c)
{
#ifdef MORE_LANGUAGES
if (IsJapanese()) {
- if (!Details.proportional)
+ if (!RenderState.proportional)
return Size[0][Details.style][192];
- if (c <= 94 || Details.style == FONT_HEADING || Details.style == FONT_BANK) {
- switch (Details.style)
+ if (c <= 94 || Details.style == FONT_HEADING || RenderState.style == FONT_BANK) {
+ switch (RenderState.style)
{
case FONT_JAPANESE:
return Size_jp[c];
default:
- return Size[0][Details.style][c];
+ return Size[0][RenderState.style][c];
}
}
- if (c < 254 && Details.style == FONT_PAGER)
- return 29.4f;
- switch (Details.style)
+ switch (RenderState.style)
{
case FONT_JAPANESE:
return 29.4f;
case FONT_BANK:
return 10.0f;
- case FONT_PAGER:
- return 31.5f;
default:
- return Size[0][Details.style][c];
+ return Size[0][RenderState.style][c];
}
}
- else if (Details.proportional)
- return Size[LanguageSet][Details.style][c];
+ else if (RenderState.proportional)
+ return Size[LanguageSet][RenderState.style][c];
else
- return Size[LanguageSet][Details.style][192];
+ return Size[LanguageSet][RenderState.style][209];
#else
- if (Details.proportional)
- return Size[Details.style][c];
+
+ if (RenderState.proportional)
+ return Size[RenderState.style][c];
else
- return Size[Details.style][192];
+ return Size[RenderState.style][209];
#endif // MORE_LANGUAGES
}
@@ -1158,7 +1239,7 @@ CFont::GetCharacterSize(wchar c)
if (IsJapanese())
{
if (!Details.proportional)
- return Size[0][Details.style][192] * Details.scaleX;
+ return Size[0][Details.style][209] * Details.scaleX;
if (c <= 94 || Details.style == FONT_HEADING || Details.style == FONT_BANK) {
switch (Details.style)
{
@@ -1168,8 +1249,6 @@ CFont::GetCharacterSize(wchar c)
return Size[0][Details.style][c] * Details.scaleX;
}
}
- if (c < 254 && (Details.style == FONT_PAGER))
- return 29.4f * Details.scaleX;
switch (Details.style)
{
@@ -1177,21 +1256,32 @@ CFont::GetCharacterSize(wchar c)
return 29.4f * Details.scaleX;
case FONT_BANK:
return 10.0f * Details.scaleX;
- case FONT_PAGER:
- return 31.5f * Details.scaleX;
default:
return Size[0][Details.style][c] * Details.scaleX;
}
}
- else if(Details.proportional)
- return Size[LanguageSet][Details.style][c] * Details.scaleX;
else
- return Size[LanguageSet][Details.style][192] * Details.scaleX;
+ {
+ if (!Details.bFontHalfTexture && c == 30) c = 61; // wanted star
+ if (Details.bFontHalfTexture)
+ c = FindNewCharacter(c);
+ if (Details.proportional)
+ return Size[LanguageSet][Details.style][c] * Details.scaleX;
+ else
+ return Size[LanguageSet][Details.style][209] * Details.scaleX;
+ }
#else
+
+#ifdef FIX_BUGS
+ // PS2 don't call FindNewCharacter in here at all, and also uses different chars for some symbols
+ if (!Details.bFontHalfTexture && c == 30) c = 61; // wanted star
+#endif
+ if (Details.bFontHalfTexture)
+ c = FindNewCharacter(c);
if (Details.proportional)
return Size[Details.style][c] * Details.scaleX;
else
- return Size[Details.style][192] * Details.scaleX;
+ return Size[Details.style][209] * Details.scaleX;
#endif // MORE_LANGUAGES
}
@@ -1212,12 +1302,10 @@ CFont::GetStringWidth(wchar *s, bool spaces)
s++;
#ifdef BUTTON_ICONS
switch (*s) {
-#if 0 // unused
case 'U':
case 'D':
case '<':
case '>':
-#endif
case 'X':
case 'O':
case 'Q':
@@ -1228,6 +1316,8 @@ CFont::GetStringWidth(wchar *s, bool spaces)
case 'J':
case 'V':
case 'C':
+ case '(':
+ case ')':
w += 17.0f * Details.scaleY;
break;
default:
@@ -1245,17 +1335,15 @@ CFont::GetStringWidth(wchar *s, bool spaces)
} else
#endif
{
- for (; (*s != ' ' || spaces) && *s != '\0'; s++) {
- if (*s == '~') {
+ for (wchar c = *s; (c != ' ' || spaces) && c != '\0'; c = *(++s)) {
+ if (c == '~') {
s++;
#ifdef BUTTON_ICONS
switch (*s) {
-#if 0 // unused
case 'U':
case 'D':
case '<':
case '>':
-#endif
case 'X':
case 'O':
case 'Q':
@@ -1266,27 +1354,27 @@ CFont::GetStringWidth(wchar *s, bool spaces)
case 'J':
case 'V':
case 'C':
+ case '(':
+ case ')':
w += 17.0f * Details.scaleY;
break;
default:
break;
}
#endif
- while (*s != '~') s++;
-#ifndef FIX_BUGS
- s++;
- if (*s == ' ' && !spaces)
- break;
- }
-#else
- } else
-#endif
- w += GetCharacterSize(*s - ' ');
+ while (*s != '~') {
+ s++;
+ }
+ }
+ else {
+ w += GetCharacterSize(c - ' ');
+ }
}
}
return w;
}
+
#ifdef MORE_LANGUAGES
float
CFont::GetStringWidth_Jap(wchar* s)
@@ -1334,19 +1422,128 @@ CFont::GetNextSpace(wchar *s)
if(*s == '~'){
s++;
while(*s != '~') s++;
-#ifndef FIX_BUGS
- s++;
- if(*s == ' ')
- break;
-#endif
}
}
return s;
}
-#ifdef MORE_LANGUAGES
wchar*
-CFont::ParseToken(wchar *s, wchar* ss, bool japShit)
+CFont::ParseToken(wchar* str, CRGBA &color, bool &flash, bool &bold)
+{
+ Details.anonymous_23 = false;
+ wchar *s = str + 1;
+ if (Details.color.r || Details.color.g || Details.color.b)
+ {
+ switch (*s)
+ {
+ case 'B':
+ bold = !bold;
+ break;
+ case 'b':
+ color.r = 27;
+ color.g = 89;
+ color.b = 130;
+ break;
+ case 'f':
+ flash = !flash;
+ break;
+ case 'g':
+ color.r = 255;
+ color.g = 150;
+ color.b = 225;
+ break;
+ case 'h':
+ color.r = 225;
+ color.g = 225;
+ color.b = 225;
+ break;
+ case 'l':
+ color.r = 0;
+ color.g = 0;
+ color.b = 0;
+ break;
+ case 'o':
+ color.r = 229;
+ color.g = 125;
+ color.b = 126;
+ break;
+ case 'p':
+ color.r = 168;
+ color.g = 110;
+ color.b = 252;
+ break;
+ case 'q':
+ color.r = 199;
+ color.g = 144;
+ color.b = 203;
+ break;
+ case 'r':
+ color.r = 255;
+ color.g = 150;
+ color.b = 225;
+ break;
+ case 't':
+ color.r = 86;
+ color.g = 212;
+ color.b = 146;
+ break;
+ case 'w':
+ color.r = 175;
+ color.g = 175;
+ color.b = 175;
+ break;
+#ifdef FIX_BUGS
+ case 'x':
+ color.r = 0;
+ color.g = 255;
+ color.b = 255;
+ break;
+#else
+ case 'x':
+ color.r = 132;
+ color.g = 146;
+ color.b = 197;
+ break;
+#endif
+ case 'y':
+ color.r = 255;
+ color.g = 227;
+ color.b = 79;
+ break;
+#ifdef BUTTON_ICONS
+ case 'U': PS2Symbol = BUTTON_UP; break;
+ case 'D': PS2Symbol = BUTTON_DOWN; break;
+ case '<': PS2Symbol = BUTTON_LEFT; break;
+ case '>': PS2Symbol = BUTTON_RIGHT; break;
+ case 'X': PS2Symbol = BUTTON_CROSS; break;
+ case 'O': PS2Symbol = BUTTON_CIRCLE; break;
+ case 'Q': PS2Symbol = BUTTON_SQUARE; break;
+ case 'T': PS2Symbol = BUTTON_TRIANGLE; break;
+ case 'K': PS2Symbol = BUTTON_L1; break;
+ case 'M': PS2Symbol = BUTTON_L2; break;
+ case 'A': PS2Symbol = BUTTON_L3; break;
+ case 'J': PS2Symbol = BUTTON_R1; break;
+ case 'V': PS2Symbol = BUTTON_R2; break;
+ case 'C': PS2Symbol = BUTTON_R3; break;
+ case 'H': PS2Symbol = BUTTON_RSTICK_UP; break;
+ case 'L': PS2Symbol = BUTTON_RSTICK_DOWN; break;
+ case '(': PS2Symbol = BUTTON_RSTICK_LEFT; break;
+ case ')': PS2Symbol = BUTTON_RSTICK_RIGHT; break;
+#endif
+ default:
+ break;
+ }
+ }
+ while (*s != '~')
+ ++s;
+ if (*(++s) == '~')
+ s = ParseToken(s, color, flash, bold);
+ return s;
+}
+
+#if 0//def MORE_LANGUAGES
+wchar*
+CFont::ParseToken(wchar *s, bool japShit)
{
s++;
if ((Details.color.r || Details.color.g || Details.color.b) && !japShit) {
@@ -1367,12 +1564,10 @@ CFont::ParseToken(wchar *s, wchar* ss, bool japShit)
case 'w': SetColor(CRGBA(175, 175, 175, 255)); break;
case 'y': SetColor(CRGBA(210, 196, 106, 255)); break;
#ifdef BUTTON_ICONS
-#if 0 // unused
case 'U': PS2Symbol = BUTTON_UP; break;
case 'D': PS2Symbol = BUTTON_DOWN; break;
case '<': PS2Symbol = BUTTON_LEFT; break;
case '>': PS2Symbol = BUTTON_RIGHT; break;
-#endif
case 'X': PS2Symbol = BUTTON_CROSS; break;
case 'O': PS2Symbol = BUTTON_CIRCLE; break;
case 'Q': PS2Symbol = BUTTON_SQUARE; break;
@@ -1383,6 +1578,10 @@ CFont::ParseToken(wchar *s, wchar* ss, bool japShit)
case 'J': PS2Symbol = BUTTON_R1; break;
case 'V': PS2Symbol = BUTTON_R2; break;
case 'C': PS2Symbol = BUTTON_R3; break;
+ case 'H': PS2Symbol = BUTTON_RSTICK_UP; break;
+ case 'L': PS2Symbol = BUTTON_RSTICK_DOWN; break;
+ case '(': PS2Symbol = BUTTON_RSTICK_LEFT; break;
+ case ')': PS2Symbol = BUTTON_RSTICK_RIGHT; break;
#endif
}
} else if (IsJapanese()) {
@@ -1390,40 +1589,111 @@ CFont::ParseToken(wchar *s, wchar* ss, bool japShit)
NewLine = true;
}
while ((!IsJapanese() || (*s != JAP_TERMINATION)) && *s != '~') s++;
-#ifdef FIX_BUGS
- if (*(++s) == '~')
- s = ParseToken(s, ss, japShit);
- return s;
-#else
return s + 1;
-#endif
}
#else
wchar*
-CFont::ParseToken(wchar *s, wchar*)
+CFont::ParseToken(wchar *s)
{
+ Details.anonymous_23 = false;
s++;
if(Details.color.r || Details.color.g || Details.color.b)
switch(*s){
+ case 'B':
+ Details.bBold = !Details.bBold;
+ break;
case 'N':
case 'n':
NewLine = true;
break;
- case 'b': SetColor(CRGBA(128, 167, 243, 255)); break;
- case 'g': SetColor(CRGBA(95, 160, 106, 255)); break;
- case 'h': SetColor(CRGBA(225, 225, 225, 255)); break;
- case 'l': SetColor(CRGBA(0, 0, 0, 255)); break;
- case 'p': SetColor(CRGBA(168, 110, 252, 255)); break;
- case 'r': SetColor(CRGBA(113, 43, 73, 255)); break;
- case 'w': SetColor(CRGBA(175, 175, 175, 255)); break;
- case 'y': SetColor(CRGBA(210, 196, 106, 255)); break;
+ case 'b':
+ Details.color.r = 27;
+ Details.color.g = 89;
+ Details.color.b = 130;
+ Details.anonymous_23 = true;
+ break;
+ case 'f':
+ Details.bFlash = !Details.bFlash;
+ if (!Details.bFlash)
+ Details.color.a = 255;
+ break;
+ case 'g':
+ Details.color.r = 255;
+ Details.color.g = 150;
+ Details.color.b = 225;
+ Details.anonymous_23 = true;
+ break;
+ case 'h':
+ Details.color.r = 225;
+ Details.color.g = 225;
+ Details.color.b = 225;
+ Details.anonymous_23 = true;
+ break;
+ case 'l':
+ Details.color.r = 0;
+ Details.color.g = 0;
+ Details.color.b = 0;
+ Details.anonymous_23 = true;
+ break;
+ case 'o':
+ Details.color.r = 229;
+ Details.color.g = 125;
+ Details.color.b = 126;
+ Details.anonymous_23 = true;
+ break;
+ case 'p':
+ Details.color.r = 168;
+ Details.color.g = 110;
+ Details.color.b = 252;
+ Details.anonymous_23 = true;
+ break;
+ case 'q':
+ Details.color.r = 199;
+ Details.color.g = 144;
+ Details.color.b = 203;
+ Details.anonymous_23 = true;
+ break;
+ case 'r':
+ Details.color.r = 255;
+ Details.color.g = 150;
+ Details.color.b = 225;
+ Details.anonymous_23 = true;
+ break;
+ case 't':
+ Details.color.r = 86;
+ Details.color.g = 212;
+ Details.color.b = 146;
+ Details.anonymous_23 = true;
+ break;
+ case 'w':
+ Details.color.r = 175;
+ Details.color.g = 175;
+ Details.color.b = 175;
+ Details.anonymous_23 = true;
+ break;
+ case 'x':
+#ifdef FIX_BUGS
+ Details.color.r = 0;
+ Details.color.g = 255;
+ Details.color.b = 255;
+#else
+ Details.color.r = 132;
+ Details.color.g = 146;
+ Details.color.b = 197;
+#endif
+ Details.anonymous_23 = true;
+ break;
+ case 'y':
+ Details.color.r = 255;
+ Details.color.g = 227;
+ Details.color.b = 79;
+ Details.anonymous_23 = true;
+ break;
#ifdef BUTTON_ICONS
-#if 0 // unused
case 'U': PS2Symbol = BUTTON_UP; break;
case 'D': PS2Symbol = BUTTON_DOWN; break;
case '<': PS2Symbol = BUTTON_LEFT; break;
case '>': PS2Symbol = BUTTON_RIGHT; break;
-#endif
case 'X': PS2Symbol = BUTTON_CROSS; break;
case 'O': PS2Symbol = BUTTON_CIRCLE; break;
case 'Q': PS2Symbol = BUTTON_SQUARE; break;
@@ -1434,25 +1704,42 @@ CFont::ParseToken(wchar *s, wchar*)
case 'J': PS2Symbol = BUTTON_R1; break;
case 'V': PS2Symbol = BUTTON_R2; break;
case 'C': PS2Symbol = BUTTON_R3; break;
+ case 'H': PS2Symbol = BUTTON_RSTICK_UP; break;
+ case 'L': PS2Symbol = BUTTON_RSTICK_DOWN; break;
+ case '(': PS2Symbol = BUTTON_RSTICK_LEFT; break;
+ case ')': PS2Symbol = BUTTON_RSTICK_RIGHT; break;
#endif
}
while(*s != '~') s++;
- return s+1;
+ if (*(++s) == '~')
+ s = ParseToken(s);
+ return s;
}
#endif
void
-CFont::DrawFonts(void)
+CFont::FilterOutTokensFromString(wchar *str)
{
- CSprite2d::DrawBank(Details.bank);
- CSprite2d::DrawBank(Details.bank+1);
- CSprite2d::DrawBank(Details.bank+2);
-#ifdef MORE_LANGUAGES
- if (IsJapanese())
- CSprite2d::DrawBank(Details.bank+3);
-#endif
+ int newIdx = 0;
+ wchar copy[256], *c;
+ UnicodeStrcpy(copy, str);
+
+ for (c = copy; *c != '\0'; c++) {
+ if (*c == '~') {
+ c++;
+ while (*c != '~') c++;
+ } else {
+ str[newIdx++] = *c;
+ }
+ }
+ str[newIdx] = '\0';
}
+void
+CFont::DrawFonts(void)
+{
+ RenderFontBuffer();
+}
void
CFont::SetScale(float x, float y)
@@ -1576,21 +1863,27 @@ CFont::SetRightJustifyOff(void)
}
void
-CFont::SetPropOn(void)
+CFont::SetPropOff(void)
{
- Details.proportional = true;
+ Details.proportional = false;
}
void
-CFont::SetPropOff(void)
+CFont::SetPropOn(void)
{
- Details.proportional = false;
+ Details.proportional = true;
}
void
CFont::SetFontStyle(int16 style)
{
- Details.style = style;
+ if (style == FONT_HEADING) {
+ Details.style = FONT_STANDARD;
+ Details.bFontHalfTexture = true;
+ } else {
+ Details.style = style;
+ Details.bFontHalfTexture = false;
+ }
}
void
@@ -1619,6 +1912,23 @@ CFont::SetDropShadowPosition(int16 pos)
Details.dropShadowPosition = pos;
}
+wchar CFont::FindNewCharacter(wchar c)
+{
+ if (c >= 16 && c <= 26) return c + 128;
+ if (c >= 8 && c <= 9) return c + 86;
+ if (c == 4) return c + 89;
+ if (c == 7) return 206;
+ if (c == 14) return 207;
+ if (c >= 33 && c <= 58) return c + 122;
+ if (c >= 65 && c <= 90) return c + 90;
+ if (c >= 96 && c <= 118) return c + 85;
+ if (c >= 119 && c <= 140) return c + 62;
+ if (c >= 141 && c <= 142) return 204;
+ if (c == 143) return 205;
+ if (c == 1) return 208;
+ return c;
+}
+
wchar
CFont::character_code(uint8 c)
{
diff --git a/src/renderer/Font.h b/src/renderer/Font.h
index 9316ed34..02e7df3b 100644
--- a/src/renderer/Font.h
+++ b/src/renderer/Font.h
@@ -6,6 +6,7 @@ void AsciiToUnicode(const char *src, wchar *dst);
void UnicodeStrcpy(wchar *dst, const wchar *src);
void UnicodeStrcat(wchar *dst, wchar *append);
int UnicodeStrlen(const wchar *str);
+void UnicodeMakeUpperCase(wchar *dst, const wchar *src);
struct CFontDetails
{
@@ -21,27 +22,54 @@ struct CFontDetails
bool8 background;
bool8 backgroundOnlyText;
bool8 proportional;
+ bool8 bIsShadow;
+ bool8 bFlash;
+ bool8 bBold;
float alphaFade;
CRGBA backgroundColor;
float wrapX;
float centreSize;
float rightJustifyWrap;
int16 style;
- int32 bank;
+ bool8 bFontHalfTexture;
+ uint32 bank;
int16 dropShadowPosition;
CRGBA dropColor;
+ bool8 bFlashState;
+ int nFlashTimer;
+ bool8 anonymous_23;
+ uint32 anonymous_25;
+};
+
+struct CFontRenderState
+{
+ uint32 anonymous_0;
+ float fTextPosX;
+ float fTextPosY;
+ float scaleX;
+ float scaleY;
+ CRGBA color;
+ float fExtraSpace;
+ float slant;
+ float slantRefX;
+ float slantRefY;
+ bool8 bIsShadow;
+ bool8 bFontHalfTexture;
+ bool8 proportional;
+ bool8 anonymous_14;
+ int16 style;
};
class CSprite2d;
enum {
FONT_BANK,
- FONT_PAGER,
+ FONT_STANDARD,
FONT_HEADING,
#ifdef MORE_LANGUAGES
FONT_JAPANESE,
#endif
- MAX_FONTS
+ MAX_FONTS = FONT_HEADING
};
enum {
@@ -69,12 +97,10 @@ enum
enum
{
BUTTON_NONE = -1,
-#if 0 // unused
BUTTON_UP,
BUTTON_DOWN,
BUTTON_LEFT,
BUTTON_RIGHT,
-#endif
BUTTON_CROSS,
BUTTON_CIRCLE,
BUTTON_SQUARE,
@@ -85,6 +111,10 @@ enum
BUTTON_R1,
BUTTON_R2,
BUTTON_R3,
+ BUTTON_RSTICK_UP,
+ BUTTON_RSTICK_DOWN,
+ BUTTON_RSTICK_LEFT,
+ BUTTON_RSTICK_RIGHT,
MAX_BUTTON_ICONS
};
#endif // BUTTON_ICONS
@@ -93,22 +123,23 @@ enum
class CFont
{
#ifdef MORE_LANGUAGES
- static int16 Size[LANGSET_MAX][MAX_FONTS][193];
+ static int16 Size[LANGSET_MAX][MAX_FONTS][210];
static uint8 LanguageSet;
static int32 Slot;
#else
- static int16 Size[MAX_FONTS][193];
+ static int16 Size[MAX_FONTS][210];
#endif
static bool16 NewLine;
public:
static CSprite2d Sprite[MAX_FONTS];
static CFontDetails Details;
+ static CFontRenderState RenderState;
#ifdef BUTTON_ICONS
static int32 ButtonsSlot;
static CSprite2d ButtonSprite[MAX_BUTTON_ICONS];
static int PS2Symbol;
-
+
static void LoadButtons(const char *txdPath);
static void DrawButton(float x, float y);
#endif // BUTTON_ICONS
@@ -119,17 +150,18 @@ public:
static void InitPerFrame(void);
static void PrintChar(float x, float y, wchar c);
static void PrintString(float x, float y, wchar *s);
- static void PrintStringFromBottom(float x, float y, wchar *str);
#ifdef XBOX_SUBTITLES
+ static void PrintStringFromBottom(float x, float y, wchar *str);
static void PrintOutlinedString(float x, float y, wchar *str, float outlineStrength, bool fromBottom, CRGBA outlineColor);
#endif
static int GetNumberLines(float xstart, float ystart, wchar *s);
static void GetTextRect(CRect *rect, float xstart, float ystart, wchar *s);
-#ifdef MORE_LANGUAGES
- static bool PrintString(float x, float y, wchar *start, wchar* &end, float spwidth, float japX);
-#else
- static void PrintString(float x, float y, wchar *start, wchar *end, float spwidth);
-#endif
+//#ifdef MORE_LANGUAGES
+// static bool PrintString(float x, float y, wchar *start, wchar* &end, float spwidth, float japX);
+//#else
+ static void PrintString(float x, float y, uint32, wchar *start, wchar *end, float spwidth);
+//#endif
+ static void PrintStringFromBottom(float x, float y, wchar *str);
static float GetCharacterWidth(wchar c);
static float GetCharacterSize(wchar c);
static float GetStringWidth(wchar *s, bool spaces = false);
@@ -137,12 +169,14 @@ public:
static float GetStringWidth_Jap(wchar* s);
#endif
static uint16 *GetNextSpace(wchar *s);
-#ifdef MORE_LANGUAGES
- static uint16 *ParseToken(wchar *s, wchar*, bool japShit = false);
-#else
- static uint16 *ParseToken(wchar *s, wchar*);
-#endif
+//#ifdef MORE_LANGUAGES
+// static uint16 *ParseToken(wchar *s, bool japShit = false);
+//#else
+ static uint16 *ParseToken(wchar *s);
+ static uint16 *ParseToken(wchar *s, CRGBA &color, bool &flash, bool &bold);
+//#endif
static void DrawFonts(void);
+ static void RenderFontBuffer(void);
static uint16 character_code(uint8 c);
static void SetScale(float x, float y);
@@ -169,7 +203,8 @@ public:
static void SetBackgroundColor(CRGBA col);
static void SetColor(CRGBA col);
static void SetDropColor(CRGBA col);
-
+ static wchar FindNewCharacter(wchar c);
+ static void FilterOutTokensFromString(wchar*);
#ifdef MORE_LANGUAGES
static void ReloadFonts(uint8 set);
@@ -177,6 +212,6 @@ public:
static bool IsAnsiCharacter(wchar* s);
static bool IsJapanesePunctuation(wchar* str);
static bool IsJapanese() { return LanguageSet == FONT_LANGSET_JAPANESE; }
- static bool IsJapaneseFont() { return IsJapanese() && (Details.style == FONT_JAPANESE || Details.style == FONT_PAGER); }
+ static bool IsJapaneseFont() { return IsJapanese() && (Details.style == FONT_JAPANESE); }
#endif
};
diff --git a/src/renderer/Glass.cpp b/src/renderer/Glass.cpp
index cc45648c..b4ec8c7e 100644
--- a/src/renderer/Glass.cpp
+++ b/src/renderer/Glass.cpp
@@ -3,6 +3,8 @@
#include "Glass.h"
#include "Timer.h"
#include "Object.h"
+#include "Vehicle.h"
+#include "Pools.h"
#include "General.h"
#include "AudioScriptObject.h"
#include "World.h"
@@ -14,6 +16,7 @@
#include "ModelIndices.h"
#include "main.h"
#include "soundlist.h"
+#include "SurfaceTable.h"
uint32 CGlass::NumGlassEntities;
@@ -57,17 +60,17 @@ const CVector2D CoorsWithTriangle[NUM_GLASSTRIANGLES][3] =
#define TEMPBUFFERVERTHILIGHTOFFSET 0
#define TEMPBUFFERINDEXHILIGHTOFFSET 0
-#define TEMPBUFFERVERTHILIGHTSIZE 128
+#define TEMPBUFFERVERTHILIGHTSIZE 256
#define TEMPBUFFERINDEXHILIGHTSIZE 512
#define TEMPBUFFERVERTSHATTEREDOFFSET TEMPBUFFERVERTHILIGHTSIZE
#define TEMPBUFFERINDEXSHATTEREDOFFSET TEMPBUFFERINDEXHILIGHTSIZE
-#define TEMPBUFFERVERTSHATTEREDSIZE 192
+#define TEMPBUFFERVERTSHATTEREDSIZE 384
#define TEMPBUFFERINDEXSHATTEREDSIZE 768
#define TEMPBUFFERVERTREFLECTIONOFFSET TEMPBUFFERVERTSHATTEREDSIZE
#define TEMPBUFFERINDEXREFLECTIONOFFSET TEMPBUFFERINDEXSHATTEREDSIZE
-#define TEMPBUFFERVERTREFLECTIONSIZE 256
+#define TEMPBUFFERVERTREFLECTIONSIZE 512
#define TEMPBUFFERINDEXREFLECTIONSIZE 1024
int32 TempBufferIndicesStoredHiLight = 0;
@@ -83,10 +86,16 @@ CFallingGlassPane::Update(void)
if ( CTimer::GetTimeInMilliseconds() >= m_nTimer )
{
// Apply MoveSpeed
- GetPosition() += m_vecMoveSpeed * CTimer::GetTimeStep();
+ if ( m_bCarGlass )
+ GetPosition() += m_vecMoveSpeed * CTimer::GetTimeStep() * 0.35f;
+ else
+ GetPosition() += m_vecMoveSpeed * CTimer::GetTimeStep();
// Apply Gravity
- m_vecMoveSpeed.z -= 0.02f * CTimer::GetTimeStep();
+ if ( m_bCarGlass )
+ m_vecMoveSpeed.z -= 0.01f * CTimer::GetTimeStep();
+ else
+ m_vecMoveSpeed.z -= 0.02f * CTimer::GetTimeStep();
// Apply TurnSpeed
GetRight() += CrossProduct(m_vecTurn, GetRight());
@@ -106,24 +115,27 @@ CFallingGlassPane::Update(void)
RwRGBA color = { 255, 255, 255, 255 };
- static int32 nFrameGen = 0;
-
- for ( int32 i = 0; i < 4; i++ )
+ if ( !m_bCarGlass )
{
- dir.x = CGeneral::GetRandomNumberInRange(-0.35f, 0.35f);
- dir.y = CGeneral::GetRandomNumberInRange(-0.35f, 0.35f);
- dir.z = CGeneral::GetRandomNumberInRange(0.05f, 0.20f);
-
- CParticle::AddParticle(PARTICLE_CAR_DEBRIS,
- pos,
- dir,
- nil,
- CGeneral::GetRandomNumberInRange(0.02f, 0.2f),
- color,
- CGeneral::GetRandomNumberInRange(-40, 40),
- 0,
- ++nFrameGen & 3,
- 500);
+ static int32 nFrameGen = 0;
+
+ for ( int32 i = 0; i < 4; i++ )
+ {
+ dir.x = CGeneral::GetRandomNumberInRange(-0.35f, 0.35f);
+ dir.y = CGeneral::GetRandomNumberInRange(-0.35f, 0.35f);
+ dir.z = CGeneral::GetRandomNumberInRange(0.05f, 0.20f);
+
+ CParticle::AddParticle(PARTICLE_CAR_DEBRIS,
+ pos,
+ dir,
+ nil,
+ CGeneral::GetRandomNumberInRange(0.02f, 0.2f),
+ color,
+ CGeneral::GetRandomNumberInRange(-40, 40),
+ 0,
+ ++nFrameGen & 3,
+ 500);
+ }
}
}
}
@@ -150,7 +162,10 @@ CFallingGlassPane::Render(void)
CGlass::RenderHiLightPolys();
// HiLight Polys
-
+
+ if ( m_bCarGlass && color < 64 )
+ color = 64;
+
RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredHiLight + 0], color, color, color, color);
RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredHiLight + 1], color, color, color, color);
RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredHiLight + 2], color, color, color, color);
@@ -190,9 +205,9 @@ CFallingGlassPane::Render(void)
if ( TempBufferIndicesStoredShattered >= TEMPBUFFERINDEXSHATTEREDSIZE-7 || TempBufferVerticesStoredShattered >= TEMPBUFFERVERTSHATTEREDSIZE-4 )
CGlass::RenderShatteredPolys();
- uint8 shatteredColor = 255;
+ uint8 shatteredColor = 140;
if ( distToCamera > 30.0f )
- shatteredColor = int32((1.0f - (distToCamera - 30.0f) * 4.0f / 40.0f) * 255);
+ shatteredColor = int32((1.0f - (distToCamera - 30.0f) * 4.0f / 40.0f) * 140);
RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 0], shatteredColor, shatteredColor, shatteredColor, shatteredColor);
RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 1], shatteredColor, shatteredColor, shatteredColor, shatteredColor);
@@ -300,8 +315,8 @@ CGlass::FindFreePane(void)
}
void
-CGlass::GeneratePanesForWindow(uint32 type, CVector pos, CVector up, CVector right, CVector speed, CVector point,
- float moveSpeed, bool cracked, bool explosion)
+CGlass::GeneratePanesForWindow(uint32 type, CVector pos, CVector up, CVector right, CVector speed, CVector center,
+ float moveSpeed, bool cracked, bool explosion, int32 stepmul, bool carGlass)
{
float upLen = up.Magnitude();
float rightLen = right.Magnitude();
@@ -312,10 +327,10 @@ CGlass::GeneratePanesForWindow(uint32 type, CVector pos, CVector up, CVector rig
float rightSteps = rightLen + 0.75f;
if ( rightSteps < 1.0f ) rightSteps = 1.0f;
- uint32 ysteps = (uint32)upSteps;
+ uint32 ysteps = stepmul * (uint32)upSteps;
if ( ysteps > 3 ) ysteps = 3;
- uint32 xsteps = (uint32)rightSteps;
+ uint32 xsteps = stepmul * (uint32)rightSteps;
if ( xsteps > 3 ) xsteps = 3;
if ( explosion )
@@ -346,11 +361,8 @@ CGlass::GeneratePanesForWindow(uint32 type, CVector pos, CVector up, CVector rig
pane->m_nTriIndex = i;
pane->GetRight() = (right * rightScl) / rightLen;
-#ifdef FIX_BUGS
pane->GetUp() = (up * upScl) / upLen;
-#else
- pane->GetUp() = (up * upScl) / rightLen; // copypaste bug
-#endif
+
CVector fwd = CrossProduct(pane->GetRight(), pane->GetUp());
fwd.Normalise();
@@ -366,7 +378,7 @@ CGlass::GeneratePanesForWindow(uint32 type, CVector pos, CVector up, CVector rig
if ( moveSpeed != 0.0f )
{
- CVector dist = pane->GetPosition() - point;
+ CVector dist = pane->GetPosition() - center;
dist.Normalise();
pane->m_vecMoveSpeed += moveSpeed * dist;
@@ -379,10 +391,11 @@ CGlass::GeneratePanesForWindow(uint32 type, CVector pos, CVector up, CVector rig
switch ( type )
{
case 0:
+ case 2:
pane->m_nTimer = CTimer::GetTimeInMilliseconds();
break;
case 1:
- float dist = (pane->GetPosition() - point).Magnitude();
+ float dist = (pane->GetPosition() - center).Magnitude();
pane->m_nTimer = uint32(dist*100 + CTimer::GetTimeInMilliseconds());
break;
}
@@ -390,6 +403,7 @@ CGlass::GeneratePanesForWindow(uint32 type, CVector pos, CVector up, CVector rig
pane->m_fGroundZ = groundZ;
pane->m_bShattered = cracked;
pane->m_fStep = upLen / float(ysteps);
+ pane->m_bCarGlass = carGlass;
pane->m_bActive = true;
}
}
@@ -621,42 +635,48 @@ CGlass::WindowRespondsToCollision(CEntity *entity, float amount, CVector speed,
CColModel *col = object->GetColModel();
ASSERT(col!=nil);
- CVector a = object->GetMatrix() * col->vertices[0].Get();
- CVector b = object->GetMatrix() * col->vertices[1].Get();
- CVector c = object->GetMatrix() * col->vertices[2].Get();
- CVector d = object->GetMatrix() * col->vertices[3].Get();
-
- float minx = Min(Min(a.x, b.x), Min(c.x, d.x));
- float maxx = Max(Max(a.x, b.x), Max(c.x, d.x));
- float miny = Min(Min(a.y, b.y), Min(c.y, d.y));
- float maxy = Max(Max(a.y, b.y), Max(c.y, d.y));
- float minz = Min(Min(a.z, b.z), Min(c.z, d.z));
- float maxz = Max(Max(a.z, b.z), Max(c.z, d.z));
-
-
- if ( amount > 300.0f )
- {
- PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_BREAK_L, object->GetPosition());
-
- GeneratePanesForWindow(0,
- CVector(minx, miny, minz),
- CVector(0.0f, 0.0f, maxz-minz),
- CVector(maxx-minx, maxy-miny, 0.0f),
- speed, point, 0.1f, !!object->bGlassCracked, explosion);
- }
- else
+ if ( col->numTriangles == 2 )
{
- PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_BREAK_S, object->GetPosition());
-
- GeneratePanesForWindow(1,
- CVector(minx, miny, minz),
- CVector(0.0f, 0.0f, maxz-minz),
- CVector(maxx-minx, maxy-miny, 0.0f),
- speed, point, 0.1f, !!object->bGlassCracked, explosion);
+ CVector a = col->vertices[0].Get();
+ CVector b = col->vertices[1].Get();
+ CVector c = col->vertices[2].Get();
+ CVector d = col->vertices[3].Get();
+
+ float minx = Min(Min(a.x, b.x), Min(c.x, d.x));
+ float maxx = Max(Max(a.x, b.x), Max(c.x, d.x));
+ float miny = Min(Min(a.y, b.y), Min(c.y, d.y));
+ float maxy = Max(Max(a.y, b.y), Max(c.y, d.y));
+ float minz = Min(Min(a.z, b.z), Min(c.z, d.z));
+ float maxz = Max(Max(a.z, b.z), Max(c.z, d.z));
+
+ CVector pa = object->GetMatrix() * CVector(minx, miny, minz);
+ CVector pb = object->GetMatrix() * CVector(maxx, maxy, minz);
+
+ if ( amount > 300.0f )
+ {
+ PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_BREAK_L, object->GetPosition());
+
+ GeneratePanesForWindow(0,
+ pa,
+ CVector(0.0f, 0.0f, maxz-minz),
+ pb - pa,
+ speed, point, 0.1f, !!object->bGlassCracked, explosion, 1, false);
+ }
+ else
+ {
+ PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_BREAK_S, object->GetPosition());
+
+ GeneratePanesForWindow(1,
+ pa,
+ CVector(0.0f, 0.0f, maxz-minz),
+ pb - pa,
+ speed, point, 0.1f, !!object->bGlassCracked, explosion, 1, false);
+ }
}
-
+
object->bGlassBroken = true;
- object->GetMatrix().GetPosition().z = -100.0f;
+ object->bIsVisible = false;
+ object->bUsesCollision = false;
}
void
@@ -666,7 +686,7 @@ CGlass::WindowRespondsToSoftCollision(CEntity *entity, float amount)
CObject *object = (CObject *)entity;
- if ( amount > 50.0f && !object->bGlassCracked )
+ if ( entity->bUsesCollision && amount > 50.0f && !object->bGlassCracked )
{
PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_CRACK, object->GetPosition());
object->bGlassCracked = true;
@@ -682,15 +702,18 @@ CGlass::WasGlassHitByBullet(CEntity *entity, CVector point)
if ( IsGlass(object->GetModelIndex()) )
{
- if ( !object->bGlassCracked )
- {
- PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_CRACK, object->GetPosition());
- object->bGlassCracked = true;
- }
- else
+ if ( object->bUsesCollision )
{
- if ( (CGeneral::GetRandomNumber() & 3) == 2 )
- WindowRespondsToCollision(object, 0.0f, CVector(0.0f, 0.0f, 0.0f), point, false);
+ if ( !object->bGlassCracked )
+ {
+ PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_CRACK, object->GetPosition());
+ object->bGlassCracked = true;
+ }
+ else
+ {
+ if ( (CGeneral::GetRandomNumber() & 3) == 2 )
+ WindowRespondsToCollision(object, 0.0f, CVector(0.0f, 0.0f, 0.0f), point, false);
+ }
}
}
}
@@ -701,19 +724,304 @@ CGlass::WindowRespondsToExplosion(CEntity *entity, CVector point)
ASSERT(entity!=nil);
CObject *object = (CObject *)entity;
+
+ if ( object->bUsesCollision )
+ {
+ CVector distToGlass = object->GetPosition() - point;
+
+ float fDistToGlass = distToGlass.Magnitude();
+
+ if ( fDistToGlass < 10.0f )
+ {
+ distToGlass *= (0.3f / fDistToGlass); // normalise
+ WindowRespondsToCollision(object, 10000.0f, distToGlass, object->GetPosition(), true);
+ }
+ else
+ {
+ if ( fDistToGlass < 30.0f )
+ object->bGlassCracked = true;
+ }
+ }
+}
- CVector distToGlass = object->GetPosition() - point;
- float fDistToGlass = distToGlass.Magnitude();
+void
+CGlass::CarWindscreenShatters(CVehicle *vehicle, bool unk)
+{
+ ASSERT(vehicle!=nil);
+
+ CColModel *col = vehicle->GetColModel();
+ ASSERT(col!=nil);
+
+ if ( col->numTriangles < 2 )
+ return;
+
+ CColTriangle *tria = nil;
+ int32 triIndex = -1;
+ CColTriangle *trib = nil;
+
+ for ( int32 i = 0; i < col->numTriangles; i++ )
+ {
+ CColTriangle *tri = &col->triangles[i];
+ if ( tri->surface == SURFACE_GLASS )
+ {
+ if ( tria )
+ {
+ trib = tri;
+ break;
+ }
+
+ triIndex = i;
+ tria = tri;
+ }
+ }
+
+ if ( trib == nil )
+ return;
+
+ CCollision::CalculateTrianglePlanes(col);
+
+ CColTrianglePlane *triPlanes = col->trianglePlanes;
+
+ if ( triPlanes == nil )
+ return;
+
+ CVector planeNormal;
+ triPlanes[triIndex].GetNormal(planeNormal);
+ planeNormal = Multiply3x3(vehicle->GetMatrix(), planeNormal);
+
+ CVector vec1 = CrossProduct(vehicle->GetRight(), planeNormal);
+ vec1.Normalise();
+
+ CVector vec2 = CrossProduct(planeNormal, vehicle->GetUp());
+ vec2.Normalise();
+
+ CVector v[6];
+ float proj1[6];
+ float proj2[6];
+
+ v[0] = col->vertices[tria->a].Get();
+ v[1] = col->vertices[tria->b].Get();
+ v[2] = col->vertices[tria->c].Get();
+
+ v[3] = col->vertices[trib->a].Get();
+ v[4] = col->vertices[trib->b].Get();
+ v[5] = col->vertices[trib->c].Get();
+
+ v[0] = vehicle->GetMatrix() * v[0];
+ v[1] = vehicle->GetMatrix() * v[1];
+ v[2] = vehicle->GetMatrix() * v[2];
+ v[3] = vehicle->GetMatrix() * v[3];
+ v[4] = vehicle->GetMatrix() * v[4];
+ v[5] = vehicle->GetMatrix() * v[5];
+
+ proj1[0] = DotProduct(v[0], vec1);
+ proj2[0] = DotProduct(v[0], vec2);
+ proj1[1] = DotProduct(v[1], vec1);
+ proj2[1] = DotProduct(v[1], vec2);
+ proj1[2] = DotProduct(v[2], vec1);
+ proj2[2] = DotProduct(v[2], vec2);
+
+ proj1[3] = DotProduct(v[3], vec1);
+ proj2[3] = DotProduct(v[3], vec2);
+ proj1[4] = DotProduct(v[4], vec1);
+ proj2[4] = DotProduct(v[4], vec2);
+ proj1[5] = DotProduct(v[5], vec1);
+ proj2[5] = DotProduct(v[5], vec2);
+
+ int32 originIndex = 0;
+ float max1 = proj1[0];
+ float max2 = proj2[0];
+ float origin = proj1[0] + proj2[0];
+
+ for ( int32 i = 1; i < 6; i++ )
+ {
+ float o = proj1[i] + proj2[i];
+ if ( o < origin )
+ {
+ origin = o;
+ originIndex = i;
+ }
+
+ if ( proj1[i] > max1 )
+ max1 = proj1[i];
+ if ( proj2[i] > max2 )
+ max2 = proj2[i];
+ }
+
+ float bound1 = max1 - proj1[originIndex];
+ float bound2 = max2 - proj2[originIndex];
+
+ PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_BREAK_L, vehicle->GetPosition());
+
+ CVector center = v[originIndex] + ((0.5f*bound1) * vec1) + ((0.5f*bound2) * vec2);
+ CVector speed = vehicle->m_vecMoveSpeed;
+ CVector right = bound2 * vec2;
+ CVector up = bound1 * vec1;
+ CVector pos = v[originIndex];
+
+ GeneratePanesForWindow(2, pos, up, right, speed, center, 0.1f, false, false, 2, true);
+}
- if ( fDistToGlass < 10.0f )
+bool
+CGlass::HasGlassBeenShatteredAtCoors(float x, float y, float z)
+{
+ CEntity *entity = nil;
+ float dist = 20.0f;
+
+ int32 nStartX = Max(CWorld::GetSectorIndexX(x - 30.0f), 0);
+ int32 nStartY = Max(CWorld::GetSectorIndexY(y - 30.0f), 0);
+ int32 nEndX = Min(CWorld::GetSectorIndexX(x + 30.0f), NUMSECTORS_X-1);
+ int32 nEndY = Min(CWorld::GetSectorIndexY(y + 30.0f), NUMSECTORS_Y-1);
+
+ CWorld::AdvanceCurrentScanCode();
+
+ for ( int32 ys = nStartY; ys <= nEndY; ys++ )
{
- distToGlass *= (0.3f / fDistToGlass); // normalise
- WindowRespondsToCollision(object, 10000.0f, distToGlass, object->GetPosition(), true);
+ for ( int32 xs = nStartX; xs <= nEndX; xs++ )
+ {
+ CSector *sector = CWorld::GetSector(xs, ys);
+
+ ASSERT(sector != nil);
+
+ FindWindowSectorList(sector->m_lists[ENTITYLIST_OBJECTS], &dist, &entity, x, y, z);
+ FindWindowSectorList(sector->m_lists[ENTITYLIST_DUMMIES], &dist, &entity, x, y, z);
+ }
}
- else
+
+ if ( entity )
{
- if ( fDistToGlass < 30.0f )
- object->bGlassCracked = true;
+ if ( entity->GetType() == ENTITY_TYPE_DUMMY )
+ return false;
+
+ return !!((CObject*)entity)->bGlassBroken;
}
+
+ return false;
}
+
+void
+CGlass::FindWindowSectorList(CPtrList &list, float *dist, CEntity **entity, float x, float y, float z)
+{
+ ASSERT(dist!=nil);
+ ASSERT(entity!=nil);
+
+ CPtrNode *node = list.first;
+
+ while ( node != nil )
+ {
+ CEntity *ent = (CEntity *)node->item;
+ uint16 scanCode = ent->m_scanCode;
+ node = node->next;
+
+ ASSERT(ent!=nil);
+
+ if ( IsGlass(ent->GetModelIndex()) )
+ {
+ if ( scanCode != CWorld::GetCurrentScanCode() )
+ {
+ ent->m_scanCode = CWorld::GetCurrentScanCode();
+
+ float dst = (CVector(x,y,z) - ent->GetPosition()).Magnitude();
+
+ if ( dst < *dist )
+ {
+ *dist = dst;
+ *entity = ent;
+ }
+ }
+ }
+ }
+}
+
+void
+CGlass::BreakGlassPhysically(CVector pos, float radius)
+{
+ static uint32 breakTime = 0;
+
+ if ( CTimer::GetTimeInMilliseconds() < breakTime + 1000 && CTimer::GetTimeInMilliseconds() >= breakTime )
+ return;
+
+ CColSphere sphere;
+ sphere.piece = 0;
+ sphere.radius = radius;
+ sphere.surface = 0;
+
+ for ( int32 i = CPools::GetObjectPool()->GetSize() - 1; i >= 0; i-- )
+ {
+ CObject *object = CPools::GetObjectPool()->GetSlot(i);
+ if (object)
+ {
+ if ( IsGlass(object->GetModelIndex()) )
+ {
+ if ( object->bUsesCollision )
+ {
+ CColModel *col = object->GetColModel();
+ ASSERT(col!=nil);
+
+ if ( col->numTriangles < 2 )
+ continue;
+
+ bool hit = false;
+
+ CVector dist = pos - object->GetPosition();
+
+ sphere.center.x = DotProduct(dist, object->GetRight());
+ sphere.center.y = DotProduct(dist, object->GetForward());
+ sphere.center.z = DotProduct(dist, object->GetUp());
+
+ CCollision::CalculateTrianglePlanes(col);
+
+ for ( int32 j = 0; j < col->numTriangles; j++ )
+ {
+ if ( CCollision::TestSphereTriangle(sphere,
+ col->vertices, col->triangles[j], col->trianglePlanes[j]) )
+ {
+ hit = true;
+ }
+ }
+
+ if ( hit )
+ {
+ breakTime = CTimer::GetTimeInMilliseconds();
+
+ if ( object->bGlassCracked )
+ {
+ CVector a = col->vertices[0].Get();
+ CVector b = col->vertices[1].Get();
+ CVector c = col->vertices[2].Get();
+ CVector d = col->vertices[3].Get();
+
+ float minx = Min(Min(a.x, b.x), Min(c.x, d.x));
+ float maxx = Max(Max(a.x, b.x), Max(c.x, d.x));
+ float miny = Min(Min(a.y, b.y), Min(c.y, d.y));
+ float maxy = Max(Max(a.y, b.y), Max(c.y, d.y));
+ float minz = Min(Min(a.z, b.z), Min(c.z, d.z));
+ float maxz = Max(Max(a.z, b.z), Max(c.z, d.z));
+
+ CVector pa = object->GetMatrix() * CVector(minx, miny, minz);
+ CVector pb = object->GetMatrix() * CVector(maxx, maxy, minz);
+
+ PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_BREAK_S, object->GetPosition());
+
+ GeneratePanesForWindow(1,
+ pa,
+ CVector(0.0f, 0.0f, maxz-minz),
+ pb - pa,
+ CVector(0.0f, 0.0f, 0.0f), pos, 0.1f, !!object->bGlassCracked, false, 1, false);
+
+ object->bGlassBroken = true;
+ object->bIsVisible = false;
+ object->bUsesCollision = false;
+ }
+ else
+ {
+ PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_CRACK, object->GetPosition());
+ object->bGlassCracked = true;
+ }
+ }
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/renderer/Glass.h b/src/renderer/Glass.h
index 51c5aae9..f1c85779 100644
--- a/src/renderer/Glass.h
+++ b/src/renderer/Glass.h
@@ -1,6 +1,8 @@
#pragma once
class CEntity;
+class CVehicle;
+class CPtrList;
class CFallingGlassPane : public CMatrix
{
@@ -13,6 +15,7 @@ public:
uint8 m_nTriIndex;
bool m_bActive;
bool m_bShattered;
+ bool m_bCarGlass;
CFallingGlassPane() { }
~CFallingGlassPane() { }
@@ -38,7 +41,7 @@ public:
static void Update(void);
static void Render(void);
static CFallingGlassPane *FindFreePane(void);
- static void GeneratePanesForWindow(uint32 type, CVector pos, CVector up, CVector right, CVector speed, CVector point, float moveSpeed, bool cracked, bool explosion);
+ static void GeneratePanesForWindow(uint32 type, CVector pos, CVector up, CVector right, CVector speed, CVector center, float moveSpeed, bool cracked, bool explosion, int32 stepmul, bool carGlass);
static void AskForObjectToBeRenderedInGlass(CEntity *entity);
static void RenderEntityInGlass(CEntity *entity);
static int32 CalcAlphaWithNormal(CVector *normal);
@@ -49,4 +52,8 @@ public:
static void WindowRespondsToSoftCollision(CEntity *entity, float amount);
static void WasGlassHitByBullet(CEntity *entity, CVector point);
static void WindowRespondsToExplosion(CEntity *entity, CVector point);
+ static void CarWindscreenShatters(CVehicle *vehicle, bool unk);
+ static bool HasGlassBeenShatteredAtCoors(float x, float y, float z);
+ static void FindWindowSectorList(CPtrList &list, float *dist, CEntity **entity, float x, float y, float z);
+ static void BreakGlassPhysically(CVector pos, float radius);
}; \ No newline at end of file
diff --git a/src/renderer/Hud.cpp b/src/renderer/Hud.cpp
index bba8c525..d7d8050f 100644
--- a/src/renderer/Hud.cpp
+++ b/src/renderer/Hud.cpp
@@ -20,50 +20,11 @@
#include "TxdStore.h"
#include "User.h"
#include "World.h"
-
-#ifdef PS2_HUD
-#define MONEY_X 100.0f
-#define WEAPON_X 91.0f
-#define AMMO_X 59.0f
-#define HEALTH_X 100.0f
-#define STARS_X 49.0f
-#define ZONE_Y 61.0f
-#define VEHICLE_Y 81.0f
-#define CLOCK_X 101.0f
-#define SUBS_Y 83.0f
-#define WASTEDBUSTED_Y 122.0f
-#define BIGMESSAGE_Y 80.0f
-#else
-#define MONEY_X 110.0f
-#define WEAPON_X 99.0f
-#define AMMO_X 66.0f
-#define HEALTH_X 110.0f
-#define STARS_X 60.0f
-#define ZONE_Y 30.0f
-#define VEHICLE_Y 55.0f
-#define CLOCK_X 111.0f
-#define SUBS_Y 68.0f
-#define WASTEDBUSTED_Y 82.0f
-#define BIGMESSAGE_Y 84.0f
-#endif
-
-#ifdef FIX_BUGS
-#define TIMER_RIGHT_OFFSET 34.0f // Taken from VC frenzy timer
-#define BIGMESSAGE_Y_OFFSET 18.0f
-#else
-#define TIMER_RIGHT_OFFSET 27.0f
-#define BIGMESSAGE_Y_OFFSET 20.0f
-#endif
-
-#if defined(PS2_HUD) && !defined(FIX_BUGS)
- #define SCREEN_SCALE_X_PC(a) (a)
- #define SCREEN_SCALE_Y_PC(a) (a)
- #define SCALE_AND_CENTER_X_PC(a) (a)
-#else
- #define SCREEN_SCALE_X_PC(a) SCREEN_SCALE_X(a)
- #define SCREEN_SCALE_Y_PC(a) SCREEN_SCALE_Y(a)
- #define SCALE_AND_CENTER_X_PC(a) SCALE_AND_CENTER_X(a)
-#endif
+#include "CutsceneMgr.h"
+#include "Stats.h"
+#include "main.h"
+#include "General.h"
+#include "VarConsole.h"
#if defined(FIX_BUGS)
#define SCREEN_SCALE_X_FIX(a) SCREEN_SCALE_X(a)
@@ -83,295 +44,222 @@
// Game has colors inlined in code.
// For easier modification we collect them here:
-CRGBA MONEY_COLOR(89, 115, 150, 255);
-CRGBA AMMO_COLOR(0, 0, 0, 255);
-CRGBA HEALTH_COLOR(186, 101, 50, 255);
-CRGBA ARMOUR_COLOR(124, 140, 95, 255);
-CRGBA WANTED_COLOR(193, 164, 120, 255);
-CRGBA ZONE_COLOR(152, 154, 82, 255);
-CRGBA VEHICLE_COLOR(194, 165, 120, 255);
-CRGBA CLOCK_COLOR(194, 165, 120, 255);
-CRGBA TIMER_COLOR(186, 101, 50, 255);
-CRGBA COUNTER_COLOR(0, 106, 164, 255);
+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(0, 0, 0, 255);
-CRGBA BIGMESSAGE_COLOR(85, 119, 133, 255);
-CRGBA WASTEDBUSTED_COLOR(170, 123, 87, 255);
-CRGBA ODDJOB_COLOR(89, 115, 150, 255);
-CRGBA ODDJOB2_COLOR(156, 91, 40, 255);
+CRGBA RADARDISC_COLOR(255, 255, 255, 255);
+CRGBA BIGMESSAGE_COLOR(255, 150, 225, 255);
+CRGBA WASTEDBUSTED_COLOR(0, 207, 133, 255);
+CRGBA ODDJOB_COLOR(0, 207, 133, 255);
+CRGBA ODDJOB2_COLOR(97, 194, 247, 255);
CRGBA MISSIONTITLE_COLOR(220, 172, 2, 255);
-
-int16 CHud::m_ItemToFlash;
-CSprite2d CHud::Sprites[NUM_HUD_SPRITES];
-wchar *CHud::m_pZoneName;
-wchar *CHud::m_pLastZoneName;
-wchar *CHud::m_ZoneToPrint;
-wchar CHud::m_Message[256];
-wchar CHud::m_BigMessage[6][128];
-wchar LastBigMessage[6][128];
-wchar CHud::m_PagerMessage[256];
-uint32 CHud::m_ZoneNameTimer;
-int32 CHud::m_ZoneFadeTimer;
-uint32 CHud::m_ZoneState;
wchar CHud::m_HelpMessage[HELP_MSG_LENGTH];
wchar CHud::m_LastHelpMessage[HELP_MSG_LENGTH];
-wchar CHud::m_HelpMessageToPrint[HELP_MSG_LENGTH];
+uint32 CHud::m_HelpMessageState;
uint32 CHud::m_HelpMessageTimer;
int32 CHud::m_HelpMessageFadeTimer;
-uint32 CHud::m_HelpMessageState;
-bool CHud::m_HelpMessageQuick;
+wchar CHud::m_HelpMessageToPrint[HELP_MSG_LENGTH];
float CHud::m_HelpMessageDisplayTime;
-int32 CHud::SpriteBrightness;
-bool CHud::m_Wants_To_Draw_Hud;
-bool CHud::m_Wants_To_Draw_3dMarkers;
-wchar *CHud::m_pVehicleName;
-wchar *CHud::m_pLastVehicleName;
-uint32 CHud::m_VehicleNameTimer;
-int32 CHud::m_VehicleFadeTimer;
+bool CHud::m_HelpMessageDisplayForever;
+bool CHud::m_HelpMessageQuick;
+uint32 CHud::m_ZoneState;
+int32 CHud::m_ZoneFadeTimer;
+uint32 CHud::m_ZoneNameTimer;
+wchar *CHud::m_pZoneName;
+wchar *CHud::m_pLastZoneName;
+wchar *CHud::m_ZoneToPrint;
uint32 CHud::m_VehicleState;
+int32 CHud::m_VehicleFadeTimer;
+uint32 CHud::m_VehicleNameTimer;
+wchar *CHud::m_VehicleName;
+wchar *CHud::m_pLastVehicleName;
wchar *CHud::m_pVehicleNameToPrint;
+wchar CHud::m_Message[256];
+wchar CHud::m_PagerMessage[256];
+bool CHud::m_Wants_To_Draw_Hud;
+bool CHud::m_Wants_To_Draw_3dMarkers;
+wchar CHud::m_BigMessage[6][128];
+int16 CHud::m_ItemToFlash;
+bool CHud::m_HideRadar;
+int32 CHud::m_ClockState;
// These aren't really in CHud
-float BigMessageInUse[6];
-float BigMessageX[6];
-float BigMessageAlpha[6];
-int16 PagerOn;
-int16 PagerTimer;
-float PagerXOffset;
-int16 PagerSoundPlayed;
-int16 OddJob2On;
-uint16 OddJob2Timer;
-float OddJob2XOffset;
-float OddJob2OffTimer;
-bool CounterOnLastFrame;
-uint16 CounterFlashTimer;
-bool TimerOnLastFrame;
-uint16 TimerFlashTimer;
+float CHud::BigMessageInUse[6];
+float CHud::BigMessageAlpha[6];
+float CHud::BigMessageX[6];
+float CHud::OddJob2OffTimer;
+bool CHud::CounterOnLastFrame[NUMONSCREENCOUNTERS];
+float CHud::OddJob2XOffset;
+uint16 CHud::CounterFlashTimer[NUMONSCREENCOUNTERS];
+uint16 CHud::OddJob2Timer;
+bool CHud::TimerOnLastFrame;
+int16 CHud::OddJob2On;
+uint16 CHud::TimerFlashTimer;
+int16 CHud::PagerSoundPlayed;
+int32 CHud::SpriteBrightness;
+float CHud::PagerXOffset;
+int16 CHud::PagerTimer;
+int16 CHud::PagerOn;
+
+wchar *prevChaseString;
+
+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;
+uint32 CHud::m_LastWeapon;
+uint32 CHud::m_LastTimeEnergyLost;
-RwTexture *gpSniperSightTex;
-RwTexture *gpRocketSightTex;
+CSprite2d CHud::Sprites[NUM_HUD_SPRITES];
struct
{
const char *name;
const char *mask;
} WeaponFilenames[] = {
- {"fist", "fistm"},
- {"bat", "batm"},
- {"pistol", "pistolm" },
- {"uzi", "uzim"},
- {"shotgun", "shotgunm"},
- {"ak47", "ak47m"},
- {"m16", "m16m"},
- {"sniper", "sniperm"},
- {"rocket", "rocketm"},
- {"flame", "flamem"},
- {"molotov", "molotovm"},
- {"grenade", "grenadem"},
- {"detonator", "detonator_mask"},
- {"", ""},
- {"", ""},
- {"radardisc", "radardisc"},
- {"pager", "pagerm"},
- {"", ""},
- {"", ""},
- {"bleeder", ""},
- {"sitesniper", "sitesniperm"},
- {"siteM16", "siteM16m"},
- {"siterocket", "siterocket"}
+ { "fist", "fistm" },
+ { "brassk", "brasskA" },
+ { "screw", "screwA" },
+ { "golf", "golfA" },
+ { "nightstick", "nightstickA" },
+ { "knife", "knifeA" },
+ { "bat", "batm" },
+ { "hammer", "hammerA" },
+ { "cleaver", "cleaverA" },
+ { "machete", "macheteA" },
+ { "sword", "swordA" },
+ { "chainsaw", "chainsawA" },
+ { "grenade", "grenadeA" },
+ { "grenade", "grenadeA" },
+ { "teargas", "teargasA" },
+ { "molotov", "molotovA" },
+ { "rocket", "rocketA" },
+ { "handGun1", "handGun1A" },
+ { "", "" },
+ { "python", "pythonA" },
+ { "chromegun", "chromegunA" },
+ { "spasshotGun", "spasshotGunA" },
+ { "stubshotGun", "stubshotGunA" },
+ { "tec9", "tec9A" },
+ { "uzi1", "uzi1A" },
+ { "uzi2", "uzi2A" },
+ { "mp5", "mp5A" },
+ { "", "" },
+ { "m4", "m4A" },
+ { "ruger", "rugerA" },
+ { "sniper", "sniperA" },
+ { "laserscope", "laserscopeA" },
+ { "", "" },
+ { "rocket", "rocketA" },
+ { "flamer", "flamerA" },
+ { "m60", "m60A" },
+ { "minigun", "minigunA" },
+ { "bomb", "bombA" },
+ { "", "" },
+ { "camera", "cameraA" },
+ { "", "" },
+ { "siterocket", "siterocket" },
+ { "", "" },
+ { "", "" },
+ { "", "" },
+ { "", "" },
+ { "", "" },
+ { "", "" },
+ { "", "" },
+ { "", "" },
+ { "radardisc", "radardisc" },
+ { "", "" },
+ { "", "" },
+ { "", "" },
+ { "", "" },
+ { "", "" },
+ { "", "" },
+ { "", "" },
+ { "", "" },
+ { "", "" },
+ { "", "" },
+ { "", "" },
+ { "", "" },
+ { "sitesniper", "sitesniperm" },
+ { "siteM16", "siteM16m" },
+ { "sitelaser", "sitelaserm" },
+ { "laserdot", "laserdotm" },
+ { "viewfinder_128", "viewfinder_128m" },
+ { "bleeder", "" }
};
-void CHud::Initialise()
-{
- m_Wants_To_Draw_Hud = true;
- m_Wants_To_Draw_3dMarkers = true;
-
- int 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);
- }
-
- GetRidOfAllHudMessages();
-
- if (gpSniperSightTex == nil)
- gpSniperSightTex = RwTextureRead("sitesniper", nil);
- if (gpRocketSightTex == nil)
- gpRocketSightTex = RwTextureRead("siterocket", nil);
-
- CounterOnLastFrame = false;
- m_ItemToFlash = ITEM_NONE;
- OddJob2Timer = 0;
- OddJob2OffTimer = 0.0f;
- OddJob2On = 0;
- OddJob2XOffset = 0.0f;
- CounterFlashTimer = 0;
- TimerOnLastFrame = false;
- TimerFlashTimer = 0;
- SpriteBrightness = 0;
- PagerOn = 0;
- PagerTimer = 0;
- PagerSoundPlayed = 0;
- PagerXOffset = 150.0f;
-
- CTxdStore::PopCurrentTxd();
-}
-
-void CHud::Shutdown()
-{
- for (int i = 0; i < NUM_HUD_SPRITES; ++i) {
- Sprites[i].Delete();
- }
-
- RwTextureDestroy(gpSniperSightTex);
- gpSniperSightTex = nil;
-
- RwTextureDestroy(gpRocketSightTex);
- gpRocketSightTex = nil;
-
- int HudTXD = CTxdStore::FindTxdSlot("hud");
- CTxdStore::RemoveTxdSlot(HudTXD);
-}
-
-void CHud::ReInitialise() {
- m_Wants_To_Draw_Hud = true;
- m_Wants_To_Draw_3dMarkers = true;
-
- GetRidOfAllHudMessages();
-
- CounterOnLastFrame = false;
- m_ItemToFlash = ITEM_NONE;
- OddJob2Timer = 0;
- OddJob2OffTimer = 0.0f;
- OddJob2On = 0;
- OddJob2XOffset = 0.0f;
- CounterFlashTimer = 0;
- TimerOnLastFrame = false;
- TimerFlashTimer = 0;
- SpriteBrightness = 0;
- PagerOn = 0;
- PagerTimer = 0;
- PagerSoundPlayed = 0;
- PagerXOffset = 150.0f;
-}
-
-void CHud::GetRidOfAllHudMessages()
-{
- m_ZoneState = 0;
- m_pLastZoneName = nil;
- m_ZoneNameTimer = 0;
- m_pZoneName = nil;
-
- for (int i = 0; i < HELP_MSG_LENGTH; i++) {
- m_HelpMessage[i] = 0;
- m_LastHelpMessage[i] = 0;
- m_HelpMessageToPrint[i] = 0;
- }
-
- m_HelpMessageTimer = 0;
- m_HelpMessageFadeTimer = 0;
- m_HelpMessageState = 0;
- m_HelpMessageQuick = 0;
- m_HelpMessageDisplayTime = 1.0f;
- m_pVehicleName = nil;
- m_pLastVehicleName = nil;
- m_pVehicleNameToPrint = nil;
- m_VehicleNameTimer = 0;
- m_VehicleFadeTimer = 0;
- m_VehicleState = 0;
-
- for (int i = 0; i < ARRAY_SIZE(m_Message); i++)
- m_Message[i] = 0;
-
- for (int i = 0; i < 6; i++) {
- BigMessageInUse[i] = 0.0f;
-
- for (int j = 0; j < 128; j++)
- m_BigMessage[i][j] = 0;
- }
-}
-
-void CHud::SetZoneName(wchar *name)
-{
- m_pZoneName = name;
-}
-
-void CHud::SetHelpMessage(wchar *message, bool quick)
-{
- if (!CReplay::IsPlayingBack()) {
- CMessages::WideStringCopy(m_HelpMessage, message, HELP_MSG_LENGTH);
- CMessages::InsertPlayerControlKeysInString(m_HelpMessage);
-
- for (int i = 0; i < HELP_MSG_LENGTH; i++) {
- m_LastHelpMessage[i] = 0;
- }
-
- m_HelpMessageState = 0;
- m_HelpMessageQuick = quick;
- }
-}
-
-void CHud::SetVehicleName(wchar *name)
-{
- m_pVehicleName = name;
-}
+RwTexture *gpSniperSightTex;
+RwTexture *gpRocketSightTex;
+RwTexture *gpLaserSightTex;
+RwTexture *gpLaserDotTex;
+RwTexture *gpViewFinderTex;
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;
-#ifdef GTA_PC
if (CReplay::IsPlayingBack())
return;
-#endif
if (m_Wants_To_Draw_Hud && !TheCamera.m_WideScreenOn) {
+ // unused statics in here
bool DrawCrossHair = false;
-#ifdef GTA_PC
+ bool CrossHairHidesHud = false;
bool DrawCrossHairPC = false;
-#endif
- 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
-#ifdef GTA_PC
- || Mode == CCam::MODE_HELICANNON_1STPERSON
-#endif
- )
- {
+ if ((Mode == CCam::MODE_SNIPER || Mode == CCam::MODE_ROCKETLAUNCHER || Mode == CCam::MODE_M16_1STPERSON || Mode == CCam::MODE_HELICANNON_1STPERSON || Mode == CCam::MODE_CAMERA)
+ && playerPed && !playerPed->GetWeapon()->IsTypeMelee())
DrawCrossHair = true;
- }
-
-#ifdef GTA_PC
+
if (Mode == CCam::MODE_M16_1STPERSON_RUNABOUT || Mode == CCam::MODE_ROCKETLAUNCHER_RUNABOUT || Mode == CCam::MODE_SNIPER_RUNABOUT)
DrawCrossHairPC = 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 = 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;
+ }
+ }
}
}
-#endif
- if ( DrawCrossHair
-#ifdef GTA_PC
- || DrawCrossHairPC
-#endif
- )
- {
+ if (DrawCrossHair || DrawCrossHairPC) {
RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void *)rwFILTERLINEAR);
SpriteBrightness = Min(SpriteBrightness+1, 30);
@@ -379,16 +267,15 @@ void CHud::Draw()
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
float fStep = Sin((CTimer::GetTimeInMilliseconds() & 1023)/1024.0f * 6.28f);
- float fMultBright = SpriteBrightness / 30.0f * (0.25f * fStep + 0.75f);
+ float fMultBright = SpriteBrightness * 0.03f * (0.25f * fStep + 0.75f);
CRect rect;
-#ifdef GTA_PC
if (DrawCrossHairPC && TheCamera.Cams[TheCamera.ActiveCam].Using3rdPersonMouseCam()) {
float f3rdX = SCREEN_WIDTH * TheCamera.m_f3rdPersonCHairMultX;
float f3rdY = SCREEN_HEIGHT * TheCamera.m_f3rdPersonCHairMultY;
#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);
@@ -406,17 +293,10 @@ void CHud::Draw()
Sprites[HUD_SITEM16].Draw(CRect(rect), CRGBA(255, 255, 255, 255),
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f);
}
- }
- else
-#endif
- {
- if (Mode == CCam::MODE_M16_1STPERSON
-#ifdef GTA_PC
- || Mode == CCam::MODE_M16_1STPERSON_RUNABOUT
- || Mode == CCam::MODE_HELICANNON_1STPERSON
-#endif
- )
- {
+ } else {
+ if (Mode == CCam::MODE_M16_1STPERSON ||
+ Mode == CCam::MODE_M16_1STPERSON_RUNABOUT ||
+ Mode == CCam::MODE_HELICANNON_1STPERSON) {
rect.left = (SCREEN_WIDTH / 2) - SCREEN_SCALE_X(32.0f);
rect.top = (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(32.0f);
rect.right = (SCREEN_WIDTH / 2) + SCREEN_SCALE_X(32.0f);
@@ -424,7 +304,6 @@ void CHud::Draw()
Sprites[HUD_SITEM16].Draw(CRect(rect), CRGBA(255, 255, 255, 255),
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f);
}
-#ifdef GTA_PC
else if (Mode == CCam::MODE_1STPERSON_RUNABOUT) {
rect.left = (SCREEN_WIDTH / 2) - SCREEN_SCALE_X(32.0f * 0.7f);
rect.top = (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(32.0f * 0.7f);
@@ -434,210 +313,309 @@ void CHud::Draw()
Sprites[HUD_SITEM16].Draw(CRect(rect), CRGBA(255, 255, 255, 255),
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f);
}
-#endif
- else if (Mode == CCam::MODE_ROCKETLAUNCHER
-#ifdef GTA_PC
- || Mode == CCam::MODE_ROCKETLAUNCHER_RUNABOUT
-#endif
- )
- {
+ else if (Mode == CCam::MODE_ROCKETLAUNCHER || Mode == CCam::MODE_ROCKETLAUNCHER_RUNABOUT) {
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)TRUE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDONE);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDONE);
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpRocketSightTex));
- CSprite::RenderOneXLUSprite(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, 1.0f, SCREEN_SCALE_X_PC(40.0f), SCREEN_SCALE_Y_PC(40.0f), (100.0f * fMultBright), (200.0f * fMultBright), (100.0f * fMultBright), 255, 1.0f, 255);
+
+ 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);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
}
else {
- // Sniper
- rect.left = SCREEN_WIDTH/2 - SCREEN_SCALE_X(210.0f);
- rect.top = SCREEN_HEIGHT/2 - SCREEN_SCALE_Y(210.0f);
+ int sprite = HUD_SITESNIPER;
+ float xOffset = SCREEN_SCALE_X(210.0f);
+ float yOffset = SCREEN_SCALE_Y(210.0f);
+
+ if (FindPlayerPed()->GetWeapon()->m_eWeaponType == WEAPONTYPE_LASERSCOPE)
+ sprite = HUD_SITELASER;
+
+ if (FindPlayerPed()->GetWeapon()->m_eWeaponType == WEAPONTYPE_CAMERA) {
+ sprite = HUD_VIEWFINDER;
+ CrossHairHidesHud = true;
+ xOffset = SCREEN_SCALE_X(256.0f);
+ yOffset = SCREEN_SCALE_Y(192.0f);
+ }
+
+ rect.left = SCREEN_WIDTH/2 - xOffset;
+ rect.top = SCREEN_HEIGHT/2 - yOffset;
rect.right = SCREEN_WIDTH/2;
rect.bottom = SCREEN_HEIGHT/2;
- Sprites[HUD_SITESNIPER].Draw(CRect(rect), CRGBA(255, 255, 255, 255),
+ Sprites[sprite].Draw(CRect(rect), CRGBA(255, 255, 255, 255),
0.01f, 0.01f, 1.0f, 0.0f, 0.01f, 1.0f, 1.0f, 1.0f);
rect.left = SCREEN_WIDTH/2;
- rect.top = SCREEN_HEIGHT/2 - SCREEN_SCALE_Y(210.0f);
- rect.right = SCREEN_WIDTH/2 + SCREEN_SCALE_X(210.0f);
+ rect.top = SCREEN_HEIGHT/2 - yOffset;
+ rect.right = SCREEN_WIDTH/2 + xOffset;
rect.bottom = SCREEN_HEIGHT/2;
- Sprites[HUD_SITESNIPER].Draw(CRect(rect), CRGBA(255, 255, 255, 255),
+ Sprites[sprite].Draw(CRect(rect), CRGBA(255, 255, 255, 255),
0.99f, 0.0f, 0.01f, 0.01f, 0.99f, 1.0f, 0.01f, 1.0f);
- rect.left = SCREEN_WIDTH/2 - SCREEN_SCALE_X(210.0f);
+ rect.left = SCREEN_WIDTH/2 - xOffset;
rect.top = SCREEN_HEIGHT/2;
rect.right = SCREEN_WIDTH/2;
- rect.bottom = SCREEN_HEIGHT/2 + SCREEN_SCALE_Y(210.0f);
- Sprites[HUD_SITESNIPER].Draw(CRect(rect), CRGBA(255, 255, 255, 255),
+ rect.bottom = SCREEN_HEIGHT/2 + yOffset;
+ Sprites[sprite].Draw(CRect(rect), CRGBA(255, 255, 255, 255),
0.01f, 0.99f, 1.0f, 0.99f, 0.01f, 0.01f, 1.0f, 0.01f);
rect.left = SCREEN_WIDTH/2;
rect.top = SCREEN_HEIGHT/2;
- rect.right = SCREEN_WIDTH/2 + SCREEN_SCALE_X(210.0f);
- rect.bottom = SCREEN_HEIGHT/2 + SCREEN_SCALE_Y(210.0f);
- Sprites[HUD_SITESNIPER].Draw(CRect(rect), CRGBA(255, 255, 255, 255),
+ rect.right = SCREEN_WIDTH/2 + xOffset;
+ rect.bottom = SCREEN_HEIGHT/2 + yOffset;
+ Sprites[sprite].Draw(CRect(rect), CRGBA(255, 255, 255, 255),
0.99f, 0.99f, 0.01f, 0.99f, 0.99f, 0.01f, 0.01f, 0.01f);
+
+ CVector dotPos;
+ float size = 25.0f;
+ if (FindPlayerPed()->GetWeapon()->m_eWeaponType == WEAPONTYPE_LASERSCOPE && FindPlayerPed()->GetWeapon()->LaserScopeDot(&dotPos, &size)) {
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+#ifdef FIX_BUGS
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+#else
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVDESTALPHA);
+#endif
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpLaserDotTex));
+#ifdef FIX_BUGS
+ int intensity = CGeneral::GetRandomNumberInRange(0, 37);
+#else
+ int intensity = CGeneral::GetRandomNumberInRange(0, 35);
+#endif
+ CSprite::RenderOneXLUSprite(dotPos.x, dotPos.y, dotPos.z,
+ SCREEN_SCALE_X(size), SCREEN_SCALE_Y(size), intensity - 36, 0, 0, intensity - 36, 1.0f, 127);
+
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
+ }
}
}
- RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void *)rwFILTERLINEAR);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
}
else {
SpriteBrightness = 0;
}
+ if (CrossHairHidesHud)
+ return;
+
/*
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 = DrawFadeState(HUD_SCORE_FADING, 0);
+ } else {
+ alpha = 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::PrintString(SCREEN_SCALE_FROM_RIGHT(MONEY_X) + SCREEN_SCALE_X_FIX(2.0f), SCREEN_SCALE_Y(43.0f) + SCREEN_SCALE_Y_FIX(2.0f), sPrint);
- CFont::SetColor(MONEY_COLOR);
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MONEY_X), SCREEN_SCALE_Y(43.0f), sPrint);
+ 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);
+
+ if (FrontEndMenuManager.m_PrefsShowHud) {
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f), SCREEN_SCALE_Y(43.0f), sPrint);
+ }
+ }
/*
DrawAmmo
*/
- int32 AmmoAmount = CWeaponInfo::GetWeaponInfo(FindPlayerPed()->GetWeapon()->m_eWeaponType)->m_nAmountofAmmunition;
- int32 AmmoInClip = FindPlayerPed()->m_weapons[FindPlayerPed()->m_currentWeapon].m_nAmmoInClip;
- int32 TotalAmmo = FindPlayerPed()->m_weapons[FindPlayerPed()->m_currentWeapon].m_nAmmoTotal;
- int32 Ammo, Clip;
-
- if (AmmoAmount <= 1 || AmmoAmount >= 1000)
- sprintf(sTemp, "%d", TotalAmmo);
- else {
- if (WeaponType == WEAPONTYPE_FLAMETHROWER) {
- Clip = AmmoInClip / 10;
-
- Ammo = Min((TotalAmmo - AmmoInClip) / 10, 9999);
- }
+ if (m_LastWeapon == playerPed->GetWeapon()->m_eWeaponType) {
+ alpha = CHud::DrawFadeState(HUD_WEAPON_FADING, 0);
+ } else {
+ alpha = CHud::DrawFadeState(HUD_WEAPON_FADING, 1);
+ m_LastWeapon = playerPed->GetWeapon()->m_eWeaponType;
+ }
+ if (m_WeaponState != FADED_OUT) {
+ CWeapon *weapon = playerPed->GetWeapon();
+ int32 AmmoAmount = CWeaponInfo::GetWeaponInfo((eWeaponType)WeaponType)->m_nAmountofAmmunition;
+ int32 AmmoInClip = weapon->m_nAmmoInClip;
+ int32 TotalAmmo = weapon->m_nAmmoTotal;
+ int32 Ammo, Clip;
+
+ if (AmmoAmount <= 1 || AmmoAmount >= 1000)
+ sprintf(sTemp, "%d", TotalAmmo);
else {
- Clip = AmmoInClip;
+ if (WeaponType == WEAPONTYPE_FLAMETHROWER) {
+ Clip = AmmoInClip / 10;
- Ammo = Min(TotalAmmo - AmmoInClip, 9999);
- }
+ Ammo = Min((TotalAmmo - AmmoInClip) / 10, 9999);
+ } else {
+ Clip = AmmoInClip;
- sprintf(sTemp, "%d-%d", Ammo, Clip);
- }
+ Ammo = Min(TotalAmmo - AmmoInClip, 9999);
+ }
- AsciiToUnicode(sTemp, sPrint);
+ sprintf(sTemp, "%d-%d", Ammo, Clip);
+ }
- /*
- DrawWeaponIcon
- */
- Sprites[WeaponType].Draw(
- CRect(
- SCREEN_SCALE_FROM_RIGHT(WEAPON_X),
- SCREEN_SCALE_Y(27.0f),
- SCREEN_SCALE_FROM_RIGHT(WEAPON_X)+SCREEN_SCALE_X(64.0f),
- SCREEN_SCALE_Y(27.0f)+SCREEN_SCALE_Y(64.0f)),
- CRGBA(255, 255, 255, 255),
- 0.015f,
- 0.015f,
- 1.0f,
- 0.0f,
- 0.015f,
- 1.0f,
- 1.0f,
- 1.0f);
-
- CFont::SetBackgroundOff();
- CFont::SetScale(SCREEN_SCALE_X(0.4f), SCREEN_SCALE_Y(0.6f));
- CFont::SetJustifyOff();
- CFont::SetCentreOn();
- CFont::SetCentreSize(SCREEN_WIDTH);
- CFont::SetPropOn();
- CFont::SetFontStyle(FONT_BANK);
+ AsciiToUnicode(sTemp, sPrint);
+ CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo((eWeaponType)WeaponType);
+ /*
+ DrawWeaponIcon
+ */
+
+ if (FrontEndMenuManager.m_PrefsShowHud) {
+ if (weaponInfo->m_nModelId <= 0) {
+ RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR);
+ if (FrontEndMenuManager.m_PrefsShowHud)
+ Sprites[WeaponType].Draw(
+ CRect(SCREEN_SCALE_FROM_RIGHT(99.0f), SCREEN_SCALE_Y(27.0f), SCREEN_SCALE_FROM_RIGHT(35.0f), SCREEN_SCALE_Y(91.0f)),
+ CRGBA(255, 255, 255, alpha),
+ 0.015f, 0.015f,
+ 1.0f, 0.0f,
+ 0.015f, 1.0f,
+ 1.0f, 1.0f);
+ } else {
+ CBaseModelInfo *weaponModel = CModelInfo::GetModelInfo(weaponInfo->m_nModelId);
+ RwTexDictionary *weaponTxd = CTxdStore::GetSlot(weaponModel->GetTxdSlot())->texDict;
+ if (weaponTxd) {
+ RwTexture *weaponIcon = RwTexDictionaryFindNamedTexture(weaponTxd, weaponModel->GetModelName());
+ if (weaponIcon) {
+ RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR);
+#ifndef FIX_BUGS
+ const float xSize = SCREEN_SCALE_X(64.0f / 2.0f);
+ const float ySize = SCREEN_SCALE_Y(64.0f / 2.0f);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(weaponIcon));
+ CSprite::RenderOneXLUSprite(SCREEN_SCALE_FROM_RIGHT(99.0f) + xSize, SCREEN_SCALE_Y(25.0f) + ySize, 1.0f, xSize, ySize,
+ 255, 255, 255, 255, 1.0f, 255);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
+#else
+ static CSprite2d sprite;
+ sprite.m_pTexture = weaponIcon;
+ sprite.Draw(
+ CRect(SCREEN_SCALE_FROM_RIGHT(99.0f), SCREEN_SCALE_Y(27.0f), SCREEN_SCALE_FROM_RIGHT(35.0f), SCREEN_SCALE_Y(91.0f)),
+ CRGBA(255, 255, 255, alpha),
+ 0.015f, 0.015f,
+ 1.0f, 0.0f,
+ 0.015f, 1.0f,
+ 1.0f, 1.0f);
+ sprite.m_pTexture = nil;
+#endif
+ }
+ }
+ }
- if (!CDarkel::FrenzyOnGoing() && WeaponType != WEAPONTYPE_UNARMED && WeaponType != WEAPONTYPE_BASEBALLBAT) {
- CFont::SetColor(AMMO_COLOR);
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(AMMO_X), SCREEN_SCALE_Y(73.0f), sPrint);
+ CFont::SetBackgroundOff();
+ CFont::SetScale(SCREEN_SCALE_X(0.5f), SCREEN_SCALE_Y(0.8f));
+ CFont::SetJustifyOff();
+ CFont::SetCentreOn();
+ CFont::SetCentreSize(SCREEN_STRETCH_X(DEFAULT_SCREEN_WIDTH));
+ CFont::SetPropOn();
+ CFont::SetDropShadowPosition(0);
+ CFont::SetFontStyle(FONT_STANDARD);
+
+ 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, alpha));
+ AMMO_COLOR.a = alpha;
+ CFont::SetColor(AMMO_COLOR);
+ if (FrontEndMenuManager.m_PrefsShowHud)
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(66.0f), SCREEN_SCALE_Y(90.0f), sPrint);
+ CFont::SetDropShadowPosition(0);
+ }
+ }
}
/*
DrawHealth
*/
- CFont::SetBackgroundOff();
- CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f));
- CFont::SetJustifyOff();
- CFont::SetCentreOff();
- CFont::SetRightJustifyWrap(0.0f);
- CFont::SetRightJustifyOn();
- CFont::SetPropOff();
- CFont::SetFontStyle(FONT_HEADING);
-
- if (m_ItemToFlash == ITEM_HEALTH && FRAMECOUNTER & 8
- || m_ItemToFlash != ITEM_HEALTH
- || FindPlayerPed()->m_fHealth < 10
- && FRAMECOUNTER & 8) {
- if (FindPlayerPed()->m_fHealth >= 10
- || FindPlayerPed()->m_fHealth < 10 && FRAMECOUNTER & 8) {
-
- AsciiToUnicode("{", sPrintIcon);
+ if ( m_LastTimeEnergyLost == CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastHealthLoss ) {
+ CHud::DrawFadeState(HUD_ENERGY_FADING, 0);
+ } else {
+ CHud::DrawFadeState(HUD_ENERGY_FADING, 1);
+ m_LastTimeEnergyLost = CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastHealthLoss;
+ }
+
+ if (m_EnergyLostState != 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::SetRightJustifyWrap(0.0f);
+ CFont::SetRightJustifyOn();
+ CFont::SetPropOff();
+ CFont::SetFontStyle(FONT_HEADING);
+ CFont::SetDropShadowPosition(2);
+ CFont::SetDropColor(CRGBA(0, 0, 0, 255));
+
+ if (m_ItemToFlash == ITEM_HEALTH && FRAMECOUNTER & 8
+ || m_ItemToFlash != ITEM_HEALTH
+ || playerPed->m_fHealth < 10
+ && FRAMECOUNTER & 8) {
+ if (playerPed->m_fHealth >= 10
+ || playerPed->m_fHealth < 10 && FRAMECOUNTER & 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);
- CFont::SetColor(CRGBA(0, 0, 0, 255));
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(HEALTH_X) + SCREEN_SCALE_X_FIX(2.0f), SCREEN_SCALE_Y(65.0f) + SCREEN_SCALE_Y_FIX(2.0f), sPrint);
+ AsciiToUnicode(sTemp, sPrint);
- if (!CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastHealthLoss || CTimer::GetTimeInMilliseconds() > CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastHealthLoss + 2000 || FRAMECOUNTER & 4)
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(HEALTH_X) + SCREEN_SCALE_X_FIX(2.0f) - SCREEN_SCALE_X(56.0f) + SCREEN_SCALE_X(2.0f), SCREEN_SCALE_Y(65.0f) + SCREEN_SCALE_Y_FIX(2.0f), sPrintIcon);
-
- CFont::SetColor(HEALTH_COLOR);
-
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(HEALTH_X), SCREEN_SCALE_Y(65.0f), sPrint);
+ CFont::SetColor(HEALTH_COLOR);
+ if (FrontEndMenuManager.m_PrefsShowHud) {
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f), SCREEN_SCALE_Y(65.0f), sPrint);
- if (!CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastHealthLoss || CTimer::GetTimeInMilliseconds() > CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastHealthLoss + 2000 || FRAMECOUNTER & 4)
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(HEALTH_X) + SCREEN_SCALE_X_FIX(2.0f) - SCREEN_SCALE_X(56.0f), SCREEN_SCALE_Y(65.0f), sPrintIcon);
+ if (!CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastHealthLoss || CTimer::GetTimeInMilliseconds() > CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastHealthLoss + 2000 || FRAMECOUNTER & 4) {
+ // CFont::SetColor(HEALTH_COLOR);
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f + 54.0f), SCREEN_SCALE_Y(65.0f), sPrintIcon);
+ }
+ }
+ }
}
- }
- /*
- DrawArmour
- */
- if (m_ItemToFlash == ITEM_ARMOUR && FRAMECOUNTER & 8 || m_ItemToFlash != ITEM_ARMOUR) {
- CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f));
- if (FindPlayerPed()->m_fArmour > 1.0f) {
- AsciiToUnicode("[", sPrintIcon);
+ /*
+ DrawArmour
+ */
+ if (m_ItemToFlash == ITEM_ARMOUR && FRAMECOUNTER & 8 || m_ItemToFlash != ITEM_ARMOUR) {
+ 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);
-
- CFont::SetColor(CRGBA(0, 0, 0, 255));
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(182.0f) + SCREEN_SCALE_X_FIX(2.0f), SCREEN_SCALE_Y(65.0f) + SCREEN_SCALE_Y_FIX(2.0f), sPrint);
-
- if (!CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastArmourLoss || CTimer::GetTimeInMilliseconds() > CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastArmourLoss + 2000 || FRAMECOUNTER & 4)
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(182.0f) + SCREEN_SCALE_X_FIX(2.0f) - SCREEN_SCALE_X(54.0f) + SCREEN_SCALE_X(2.0f), SCREEN_SCALE_Y(65.0f) + SCREEN_SCALE_Y_FIX(2.0f), sPrintIcon);
+ AsciiToUnicode(sTemp, sPrint);
- CFont::SetColor(ARMOUR_COLOR);
+ CFont::SetColor(ARMOUR_COLOR);
+ if (FrontEndMenuManager.m_PrefsShowHud) {
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(182.0f), SCREEN_SCALE_Y(65.0f), sPrint);
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(182.0f), SCREEN_SCALE_Y(65.0f), sPrint);
- if (!CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastArmourLoss || CTimer::GetTimeInMilliseconds() > CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastArmourLoss + 2000 || FRAMECOUNTER & 1) {
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(182.0f) - SCREEN_SCALE_X(54.0f) + SCREEN_SCALE_X(2.0f), SCREEN_SCALE_Y(65.0f), sPrintIcon);
+ if (!CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastArmourLoss || CTimer::GetTimeInMilliseconds() > CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastArmourLoss + 2000 || FRAMECOUNTER & 4) {
+ // CFont::SetColor(ARMOUR_COLOR);
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(182.0f + 52.0f), SCREEN_SCALE_Y(65.0f), sPrintIcon);
+ }
+ }
}
}
}
@@ -645,38 +623,99 @@ void CHud::Draw()
/*
DrawWantedLevel
*/
- CFont::SetBackgroundOff();
- CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f));
- CFont::SetJustifyOff();
- CFont::SetCentreOff();
- CFont::SetRightJustifyOff();
- CFont::SetPropOn();
- CFont::SetFontStyle(FONT_HEADING);
+ if (m_LastWanted == playerPed->m_pWanted->GetWantedLevel()) {
+ alpha = DrawFadeState(HUD_WANTED_FADING, 0);
+ } else {
+ alpha = DrawFadeState(HUD_WANTED_FADING, 1);
+ m_LastWanted = playerPed->m_pWanted->GetWantedLevel();
+ }
- AsciiToUnicode("]", sPrintIcon);
-
- float fStarsX = SCREEN_SCALE_FROM_RIGHT(STARS_X);
+ 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_STANDARD);
+
+ AsciiToUnicode(">", sPrintIcon);
+
+ for (int i = 0; i < 6; i++) {
+ if (FrontEndMenuManager.m_PrefsShowHud) {
+ if (playerPed->m_pWanted->GetWantedLevel() > i
+ && (CTimer::GetTimeInMilliseconds() > playerPed->m_pWanted->m_nLastWantedLevelChange
+ + 2000 || FRAMECOUNTER & 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);
+
+ } else if (playerPed->m_pWanted->m_nMinWantedLevel > i && FRAMECOUNTER & 4) {
+ WANTED_COLOR_FLASH.a = alpha;
+ CFont::SetColor(WANTED_COLOR_FLASH);
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f + 23.0f * i), SCREEN_SCALE_Y(87.0f), sPrintIcon);
- for (int i = 0; i < 6; i++) {
- CFont::SetColor(CRGBA(0, 0, 0, 255));
- CFont::PrintString(fStarsX + SCREEN_SCALE_X_FIX(2.0f), SCREEN_SCALE_Y(87.0f) + SCREEN_SCALE_Y_FIX(2.0f), sPrintIcon);
+ } else if (playerPed->m_pWanted->GetWantedLevel() <= 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);
+ }
+ }
+ }
+ }
+
+ static int32 nMediaLevelCounter = 0;
+ if (CStats::ShowChaseStatOnScreen != 0) {
+ float fCurAttentionLevel = CWorld::Players[CWorld::PlayerInFocus].m_fMediaAttention;
+ if (0.7f * CStats::HighestChaseValue > fCurAttentionLevel
+ || fCurAttentionLevel <= 40.0f || CTheScripts::IsPlayerOnAMission()) {
+ nMediaLevelCounter = 0;
+ }
+ else {
+ if (fCurAttentionLevel == CStats::HighestChaseValue) {
+ sprintf(gString, "%s %d", UnicodeToAscii(TheText.Get("CHSE")), (int32)fCurAttentionLevel);
+ }
+ else {
+ sprintf(gString, "%s %d" "-%d-", UnicodeToAscii(TheText.Get("CHSE")), (int32)fCurAttentionLevel, (int32)CStats::HighestChaseValue);
+ }
+ AsciiToUnicode(gString, gUString);
+ 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, 255));
- if (FindPlayerPed()->m_pWanted->GetWantedLevel() > i
- && (CTimer::GetTimeInMilliseconds() > FindPlayerPed()->m_pWanted->m_nLastWantedLevelChange
- + 2000 || FRAMECOUNTER & 4)) {
+ CRGBA colour;
+ if (CTimer::GetTimeInMilliseconds() & 0x200)
+ colour = CRGBA(204, 0, 185, 180);
+ else
+ colour = CRGBA(178, 0, 162, 180);
+ CFont::SetColor(colour);
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f), SCREEN_SCALE_Y(113.0f), gUString);
+
+ if (CStats::FindChaseString(fCurAttentionLevel) != prevChaseString) {
+ prevChaseString = CStats::FindChaseString(fCurAttentionLevel);
+ nMediaLevelCounter = 100;
+ }
- CFont::SetColor(WANTED_COLOR);
- CFont::PrintString(fStarsX, SCREEN_SCALE_Y(87.0f), sPrintIcon);
+ if (nMediaLevelCounter != 0) {
+ nMediaLevelCounter--;
+ UnicodeMakeUpperCase(gUString, CStats::FindChaseString(fCurAttentionLevel));
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f), SCREEN_SCALE_Y(138.0f), gUString);
+ }
}
-
- fStarsX -= SCREEN_SCALE_X(23.0f);
}
/*
DrawZoneName
*/
if (m_pZoneName) {
- float fZoneAlpha = 255.0f;
if (m_pZoneName != m_pLastZoneName) {
switch (m_ZoneState) {
@@ -685,6 +724,8 @@ void CHud::Draw()
m_ZoneToPrint = m_pZoneName;
m_ZoneNameTimer = 0;
m_ZoneFadeTimer = 0;
+ if (m_VehicleState == 1 || m_VehicleState == 2)
+ m_VehicleState = 3;
break;
case 1:
case 2:
@@ -699,70 +740,76 @@ void CHud::Draw()
m_pLastZoneName = m_pZoneName;
}
+ float fZoneAlpha = 255.0f;
if (m_ZoneState) {
switch (m_ZoneState) {
case 1:
+ fZoneAlpha = 255.0f;
m_ZoneFadeTimer = 1000;
- if (m_ZoneNameTimer > 10000) {
+ if (m_ZoneNameTimer > 10000.0f) {
m_ZoneFadeTimer = 1000;
m_ZoneState = 3;
}
- fZoneAlpha = 255.0f;
break;
case 2:
m_ZoneFadeTimer += CTimer::GetTimeStepInMilliseconds();
- if (m_ZoneFadeTimer > 1000) {
+ if (m_ZoneFadeTimer > 1000.0f) {
m_ZoneState = 1;
m_ZoneFadeTimer = 1000;
}
- fZoneAlpha = m_ZoneFadeTimer / 1000.0f * 255.0f;
+ fZoneAlpha = m_ZoneFadeTimer * 0.001f * 255.0f;
break;
case 3:
m_ZoneFadeTimer -= CTimer::GetTimeStepInMilliseconds();
- if (m_ZoneFadeTimer < 0) {
+ if (m_ZoneFadeTimer < 0.0f) {
m_ZoneState = 0;
m_ZoneFadeTimer = 0;
}
- fZoneAlpha = m_ZoneFadeTimer / 1000.0f * 255.0f;
+ fZoneAlpha = m_ZoneFadeTimer * 0.001f * 255.0f;
break;
case 4:
m_ZoneFadeTimer -= CTimer::GetTimeStepInMilliseconds();
- if (m_ZoneFadeTimer < 0) {
+ if (m_ZoneFadeTimer < 0.0f) {
m_ZoneFadeTimer = 0;
m_ZoneToPrint = m_pLastZoneName;
m_ZoneState = 2;
}
- fZoneAlpha = m_ZoneFadeTimer / 1000.0f * 255.0f;
+ fZoneAlpha = m_ZoneFadeTimer * 0.001f * 255.0f;
break;
default:
break;
}
-#ifndef HUD_ENHANCEMENTS
- if (!m_Message[0])
-#else
- if (!m_Message[0] && !m_BigMessage[2][0]) // Hide zone name if wasted/busted text is displaying
-#endif
- {
+ if (!m_Message[0] && BigMessageInUse[1] == 0.0f && BigMessageInUse[2] == 0.0f) {
+
m_ZoneNameTimer += CTimer::GetTimeStepInMilliseconds();
CFont::SetJustifyOff();
CFont::SetPropOn();
CFont::SetBackgroundOff();
if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_SPANISH)
- CFont::SetScale(SCREEN_SCALE_X(1.2f * 0.8f), SCREEN_SCALE_Y(1.2f));
+ CFont::SetScale(SCREEN_SCALE_X(1.7f * 0.8f), SCREEN_SCALE_Y(1.8f));
else
- CFont::SetScale(SCREEN_SCALE_X(1.2f), SCREEN_SCALE_Y(1.2f));
+ CFont::SetScale(SCREEN_SCALE_X(1.7f), SCREEN_SCALE_Y(1.8f));
+
+ 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::SetDropShadowPosition(2);
+ CFont::SetDropColor(CRGBA(0, 0, 0, fZoneAlpha));
CFont::SetFontStyle(FONT_BANK);
- CFont::SetColor(CRGBA(0, 0, 0, fZoneAlpha));
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(32.0f) + SCREEN_SCALE_X_FIX(1.0f), SCREEN_SCALE_FROM_BOTTOM(ZONE_Y) + SCREEN_SCALE_Y_FIX(1.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(ZONE_Y), m_ZoneToPrint);
+
+ if (!CTheScripts::bPlayerIsInTheStatium)
+ CFont::PrintStringFromBottom(SCREEN_SCALE_FROM_RIGHT(32.0f), SCREEN_SCALE_FROM_BOTTOM(128.0f), m_ZoneToPrint);
+
+ CFont::SetSlant(0.f);
+ } else {
+ m_ZoneState = 3;
}
}
}
@@ -770,16 +817,18 @@ void CHud::Draw()
/*
DrawVehicleName
*/
- if (m_pVehicleName) {
+ if (m_VehicleName) {
float fVehicleAlpha = 0.0f;
- if (m_pVehicleName != m_pLastVehicleName) {
+ if (m_VehicleName != m_pLastVehicleName) {
switch (m_VehicleState) {
case 0:
m_VehicleState = 2;
- m_pVehicleNameToPrint = m_pVehicleName;
+ m_pVehicleNameToPrint = m_VehicleName;
m_VehicleNameTimer = 0;
m_VehicleFadeTimer = 0;
+ if (m_ZoneState == 1 || m_ZoneState == 2)
+ m_ZoneState = 3;
break;
case 1:
case 2:
@@ -791,7 +840,7 @@ void CHud::Draw()
default:
break;
}
- m_pLastVehicleName = m_pVehicleName;
+ m_pLastVehicleName = m_VehicleName;
}
if (m_VehicleState) {
@@ -809,7 +858,7 @@ void CHud::Draw()
m_VehicleState = 1;
m_VehicleFadeTimer = 1000;
}
- fVehicleAlpha = m_VehicleFadeTimer / 1000.0f * 255.0f;
+ fVehicleAlpha = m_VehicleFadeTimer * 0.001f * 255.0f;
break;
case 3:
m_VehicleFadeTimer -= CTimer::GetTimeStepInMilliseconds();
@@ -817,7 +866,7 @@ void CHud::Draw()
m_VehicleState = 0;
m_VehicleFadeTimer = 0;
}
- fVehicleAlpha = m_VehicleFadeTimer / 1000.0f * 255.0f;
+ fVehicleAlpha = m_VehicleFadeTimer * 0.001f * 255.0f;
break;
case 4:
m_VehicleFadeTimer -= CTimer::GetTimeStepInMilliseconds();
@@ -827,36 +876,37 @@ void CHud::Draw()
m_VehicleNameTimer = 0;
m_VehicleState = 2;
}
- fVehicleAlpha = m_VehicleFadeTimer / 1000.0f * 255.0f;
+ fVehicleAlpha = m_VehicleFadeTimer * 0.001f * 255.0f;
break;
default:
break;
}
-#ifndef HUD_ENHANCEMENTS
- if (!m_Message[0])
-#else
- if (!m_Message[0] && !m_BigMessage[2][0]) // Hide vehicle name if wasted/busted text is displaying
-#endif
- {
+ if (!m_Message[0]) {
m_VehicleNameTimer += CTimer::GetTimeStepInMilliseconds();
CFont::SetJustifyOff();
CFont::SetPropOn();
CFont::SetBackgroundOff();
if (FrontEndMenuManager.m_PrefsLanguage != CMenuManager::LANGUAGE_ITALIAN && FrontEndMenuManager.m_PrefsLanguage != CMenuManager::LANGUAGE_SPANISH)
- CFont::SetScale(SCREEN_SCALE_X(1.2f), SCREEN_SCALE_Y(1.2f));
+ CFont::SetScale(SCREEN_SCALE_X(1.7f), SCREEN_SCALE_Y(1.8f));
else
- CFont::SetScale(SCREEN_SCALE_X(1.2f * 0.85f), SCREEN_SCALE_Y(1.2f));
+ CFont::SetScale(SCREEN_SCALE_X(1.7f * 0.85f), SCREEN_SCALE_Y(1.8f));
+
+ 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_FIX(1.0f), SCREEN_SCALE_FROM_BOTTOM(VEHICLE_Y) + SCREEN_SCALE_Y_FIX(1.0f), m_pVehicleNameToPrint);
+ CFont::SetDropShadowPosition(2);
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(VEHICLE_Y), m_pVehicleNameToPrint);
+ CFont::SetDropColor(CRGBA(0, 0, 0, fVehicleAlpha));
+
+ CFont::PrintStringFromBottom(SCREEN_SCALE_FROM_RIGHT(32.0f), SCREEN_SCALE_FROM_BOTTOM(105.0f), m_pVehicleNameToPrint);
+
+ CFont::SetSlant(0.f);
}
}
}
@@ -870,214 +920,165 @@ void CHud::Draw()
/*
DrawClock
*/
- CFont::SetJustifyOff();
- CFont::SetCentreOff();
- CFont::SetBackgroundOff();
- CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f));
- CFont::SetBackGroundOnlyTextOff();
- CFont::SetPropOff();
- CFont::SetFontStyle(FONT_HEADING);
- CFont::SetRightJustifyOn();
- CFont::SetRightJustifyWrap(0.0f);
+ if (m_ClockState) {
+ CFont::SetJustifyOff();
+ CFont::SetCentreOff();
+ CFont::SetBackgroundOff();
+ CFont::SetScale(SCREEN_SCALE_X(HUD_TEXT_SCALE_X), SCREEN_SCALE_Y(HUD_TEXT_SCALE_Y));
+ CFont::SetBackGroundOnlyTextOff();
+ CFont::SetPropOff();
+ CFont::SetFontStyle(FONT_HEADING);
+ CFont::SetRightJustifyOn();
+ CFont::SetRightJustifyWrap(0.0f);
+ CFont::SetDropShadowPosition(2);
+ CFont::SetDropColor(CRGBA(0, 0, 0, 255));
- sprintf(sTemp, "%02d:%02d", CClock::GetHours(), CClock::GetMinutes());
- AsciiToUnicode(sTemp, sPrint);
+ sprintf(sTemp, "%02d:%02d", CClock::GetHours(), CClock::GetMinutes());
+ AsciiToUnicode(sTemp, sPrint);
- CFont::SetColor(CRGBA(0, 0, 0, 255));
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(CLOCK_X) + SCREEN_SCALE_X_FIX(2.0f), SCREEN_SCALE_Y(22.0f) + SCREEN_SCALE_Y_FIX(2.0f), sPrint);
- CFont::SetColor(CLOCK_COLOR);
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(CLOCK_X), SCREEN_SCALE_Y(22.0f), sPrint);
+ CFont::SetColor(CLOCK_COLOR);
+ if (FrontEndMenuManager.m_PrefsShowHud)
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(111.0f), SCREEN_SCALE_Y(22.0f), sPrint);
+ }
/*
DrawOnScreenTimer
*/
+
wchar sTimer[16];
- if (!CUserDisplay::OnscnTimer.m_sEntries[0].m_bTimerProcessed)
+ if (!CUserDisplay::OnscnTimer.m_sClocks[0].m_bClockProcessed)
TimerOnLastFrame = false;
- if (!CUserDisplay::OnscnTimer.m_sEntries[0].m_bCounterProcessed)
- CounterOnLastFrame = false;
+
+ for(uint32 i = 0; i < NUMONSCREENCOUNTERS; i++) {
+ if (!CUserDisplay::OnscnTimer.m_sCounters[0].m_bCounterProcessed)
+ CounterOnLastFrame[i] = false;
+ }
if (CUserDisplay::OnscnTimer.m_bProcessed) {
- if (CUserDisplay::OnscnTimer.m_sEntries[0].m_bTimerProcessed) {
+ if (CUserDisplay::OnscnTimer.m_sClocks[0].m_bClockProcessed) {
if (!TimerOnLastFrame)
TimerFlashTimer = 1;
TimerOnLastFrame = true;
- if (TimerFlashTimer) {
+ if (TimerFlashTimer != 0) {
if (++TimerFlashTimer > 50)
TimerFlashTimer = 0;
}
- if (FRAMECOUNTER & 4 || !TimerFlashTimer) {
- AsciiToUnicode(CUserDisplay::OnscnTimer.m_sEntries[0].m_bTimerBuffer, sTimer);
+ if (FRAMECOUNTER & 4 || TimerFlashTimer == 0) {
+ AsciiToUnicode(CUserDisplay::OnscnTimer.m_sClocks[0].m_aClockBuffer, 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));
CFont::SetPropOff();
CFont::SetBackGroundOnlyTextOn();
- CFont::SetColor(CRGBA(0, 0, 0, 255));
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(TIMER_RIGHT_OFFSET) + SCREEN_SCALE_X_FIX(2.0f), SCREEN_SCALE_Y(110.0f) + SCREEN_SCALE_Y_FIX(2.0f), sTimer);
- CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f));
+ CFont::SetDropShadowPosition(2);
+ CFont::SetDropColor(CRGBA(0, 0, 0, 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);
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(37.0f), SCREEN_SCALE_Y(110.0f), sTimer);
+ CFont::SetPropOn();
- if (CUserDisplay::OnscnTimer.m_sEntries[0].m_aTimerText[0]) {
- CFont::SetPropOn();
- CFont::SetColor(CRGBA(0, 0, 0, 255));
- CFont::SetScale(SCREEN_SCALE_X(0.8f * 0.8f), 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_FIX(2.0f), TheText.Get(CUserDisplay::OnscnTimer.m_sEntries[0].m_aTimerText));
+ if (CUserDisplay::OnscnTimer.m_sClocks[0].m_aClockText[0]) {
+ CFont::SetDropShadowPosition(2);
+ CFont::SetDropColor(CRGBA(0, 0, 0, 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));
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(37.0f) - SCREEN_SCALE_X(80.0f), SCREEN_SCALE_Y(110.0f), TheText.Get(CUserDisplay::OnscnTimer.m_sClocks[0].m_aClockText));
}
}
}
- if (CUserDisplay::OnscnTimer.m_sEntries[0].m_bCounterProcessed) {
- if (!CounterOnLastFrame)
- CounterFlashTimer = 1;
- CounterOnLastFrame = true;
+ for(uint32 i = 0; i < NUMONSCREENCOUNTERS; i++) {
+ if (CUserDisplay::OnscnTimer.m_sCounters[i].m_bCounterProcessed) {
+ if (!CounterOnLastFrame[i])
+ CounterFlashTimer[i] = 1;
- if (CounterFlashTimer) {
- if (++CounterFlashTimer > 50)
- CounterFlashTimer = 0;
- }
+ CounterOnLastFrame[i] = true;
- if (FRAMECOUNTER & 4 || !CounterFlashTimer) {
- if (CUserDisplay::OnscnTimer.m_sEntries[0].m_nType == COUNTER_DISPLAY_NUMBER) {
- AsciiToUnicode(CUserDisplay::OnscnTimer.m_sEntries[0].m_bCounterBuffer, sTimer);
- CFont::SetPropOn();
- CFont::SetBackgroundOff();
- CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f));
- CFont::SetCentreOff();
- CFont::SetRightJustifyOn();
- CFont::SetRightJustifyWrap(0.0f);
- CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING));
- CFont::SetColor(CRGBA(244, 20, 20, 255));
- CFont::SetWrapx(SCREEN_STRETCH_X(DEFAULT_SCREEN_WIDTH));
- CFont::SetPropOff();
- CFont::SetBackGroundOnlyTextOn();
- CFont::SetColor(CRGBA(0, 0, 0, 255));
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(TIMER_RIGHT_OFFSET) + SCREEN_SCALE_X_FIX(2.0f), SCREEN_SCALE_Y(132.0f) + SCREEN_SCALE_Y_FIX(2.0f), sTimer);
- 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);
-#ifdef FIX_BUGS
- counter = Min(counter, 100);
-#endif
- CSprite2d::DrawRect
- (
- CRect
- (
- SCREEN_SCALE_FROM_RIGHT(TIMER_RIGHT_OFFSET) - SCREEN_SCALE_X(100.0f) / 2 + SCREEN_SCALE_X_FIX(4.0f),
- SCREEN_SCALE_Y(132.0f) + SCREEN_SCALE_Y(8.0f),
- SCREEN_SCALE_FROM_RIGHT(TIMER_RIGHT_OFFSET) + SCREEN_SCALE_X_FIX(4.0f),
- SCREEN_SCALE_Y(132.0f) + SCREEN_SCALE_Y_PC(11.0f) + SCREEN_SCALE_Y(8.0f)
- ),
- CRGBA(0, 106, 164, 80)
- );
-
- CSprite2d::DrawRect
- (
- CRect
- (
- SCREEN_SCALE_FROM_RIGHT(TIMER_RIGHT_OFFSET) - SCREEN_SCALE_X(100.0f) / 2 + SCREEN_SCALE_X_FIX(4.0f),
- SCREEN_SCALE_Y(132.0f) + SCREEN_SCALE_Y(8.0f),
- SCREEN_SCALE_X_PC((float)counter) / 2.0f + SCREEN_SCALE_FROM_RIGHT(TIMER_RIGHT_OFFSET) - SCREEN_SCALE_X(100.0f) / 2.0f + SCREEN_SCALE_X_FIX(4.0f),
- SCREEN_SCALE_Y(132.0f) + SCREEN_SCALE_Y_PC(11.0f) + SCREEN_SCALE_Y(8.0f)
- ),
- CRGBA(0, 106, 164, 255)
- );
+ if (CounterFlashTimer[i] != 0) {
+ if (++CounterFlashTimer[i] > 50)
+ CounterFlashTimer[i] = 0;
}
- if (CUserDisplay::OnscnTimer.m_sEntries[0].m_aCounterText[0]) {
- CFont::SetPropOn();
- CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f));
- CFont::SetColor(CRGBA(0, 0, 0, 255));
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(TIMER_RIGHT_OFFSET) - SCREEN_SCALE_X(61.0f) + SCREEN_SCALE_X(2.0f), SCREEN_SCALE_Y(132.0f) + SCREEN_SCALE_Y_FIX(2.0f), TheText.Get(CUserDisplay::OnscnTimer.m_sEntries[0].m_aCounterText));
- 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));
+ if (FRAMECOUNTER & 4 || CounterFlashTimer[i] == 0) {
+ if (CUserDisplay::OnscnTimer.m_sCounters[i].m_nType == COUNTER_DISPLAY_NUMBER) {
+ AsciiToUnicode(CUserDisplay::OnscnTimer.m_sCounters[i].m_aCounterBuffer, sTimer);
+ CFont::SetPropOn();
+ 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::SetFontStyle(FONT_LOCALE(FONT_HEADING));
+ CFont::SetWrapx(SCREEN_STRETCH_X(DEFAULT_SCREEN_WIDTH));
+ CFont::SetPropOn();
+ CFont::SetBackGroundOnlyTextOn();
+ CFont::SetDropShadowPosition(2);
+ CFont::SetDropColor(CRGBA(0, 0, 0, 255));
+ CFont::SetColor(COUNTER_COLOR);
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(37.0f), SCREEN_SCALE_Y(HUD_TEXT_SCALE_Y * 20.f * i) + SCREEN_SCALE_Y(132.0f), sTimer);
+ } else {
+ int counter = atoi(CUserDisplay::OnscnTimer.m_sCounters[i].m_aCounterBuffer);
+
+ const float barWidth = SCREEN_SCALE_X(100.f / 2.f);
+ const float right = SCREEN_SCALE_FROM_RIGHT(37.0f);
+ const float left = right - barWidth;
+
+ const float barHeight = SCREEN_SCALE_Y(11.0f);
+ const float top = SCREEN_SCALE_Y(132.0f) + SCREEN_SCALE_Y(8.0f) + SCREEN_SCALE_Y(HUD_TEXT_SCALE_Y * 20.f * i);
+ const float bottom = top + barHeight;
+
+ // shadow
+ CSprite2d::DrawRect(CRect(left + SCREEN_SCALE_X(6.0f), top + SCREEN_SCALE_Y(2.0f), right + SCREEN_SCALE_X(6.0f), bottom + SCREEN_SCALE_Y(2.0f)), CRGBA(0, 0, 0, 255));
+
+ CSprite2d::DrawRect(CRect(left + SCREEN_SCALE_X(4.0f), top, right + SCREEN_SCALE_X(4.0f), bottom), CRGBA(27, 89, 130, 255));
+ CSprite2d::DrawRect(CRect(left + SCREEN_SCALE_X(4.0f), top, left + SCREEN_SCALE_X(counter) / 2.0f + SCREEN_SCALE_X(4.0f), bottom), CRGBA(97, 194, 247, 255));
+ }
+
+ if (CUserDisplay::OnscnTimer.m_sCounters[i].m_aCounterText[0]) {
+ CFont::SetPropOn();
+ CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING));
+ CFont::SetScale(SCREEN_SCALE_X(HUD_TEXT_SCALE_X), SCREEN_SCALE_Y(HUD_TEXT_SCALE_Y));
+ CFont::SetDropShadowPosition(2);
+ CFont::SetDropColor(CRGBA(0, 0, 0, 255));
+ CFont::SetColor(COUNTER_COLOR);
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(37.0f) - SCREEN_SCALE_X(61.0f), SCREEN_SCALE_Y(HUD_TEXT_SCALE_Y * 20.f * i) + SCREEN_SCALE_Y(132.0f), TheText.Get(CUserDisplay::OnscnTimer.m_sCounters[i].m_aCounterText));
+ }
+ // unused/leftover color. I wonder what was it for
+ CFont::SetColor(CRGBA(244, 225, 91, 255));
}
}
}
}
- /////////////////////////////////
- /*
- DrawPager
- */
- if (!m_PagerMessage[0] && PagerOn == 1) {
- PagerSoundPlayed = false;
- PagerOn = 2;
- }
- if (m_PagerMessage[0] || PagerOn == 2) {
- if (!PagerOn) {
- PagerOn = 1;
- PagerXOffset = 150.0f;
- }
- if (PagerOn == 1) {
- if (PagerXOffset > 0.0f) {
- float fStep = PagerXOffset * 0.1f;
- if (fStep > 10.0f)
- fStep = 10.0f;
- PagerXOffset -= fStep * CTimer::GetTimeStep();
- }
- if (!PagerSoundPlayed) {
- DMAudio.PlayFrontEndSound(SOUND_PAGER, 0);
- PagerSoundPlayed = 1;
- }
- }
- else if (PagerOn == 2) {
- float fStep = PagerXOffset * 0.1f;
- if (fStep < 2.0f)
- fStep = 2.0f;
- PagerXOffset += fStep;
- if (PagerXOffset > 150.0f) {
- PagerXOffset = 150.0f;
- PagerOn = 0;
- }
- }
- Sprites[HUD_PAGER].Draw(CRect(SCREEN_SCALE_X(26.0f) - SCREEN_SCALE_X_FIX(PagerXOffset), SCREEN_SCALE_Y(27.0f), SCREEN_SCALE_X(160.0f) + SCREEN_SCALE_X(26.0f) - SCREEN_SCALE_X_FIX(PagerXOffset), SCREEN_SCALE_Y(80.0f) + SCREEN_SCALE_Y(27.0f)), CRGBA(255, 255, 255, 255));
- CFont::SetBackgroundOff();
- CFont::SetScale(SCREEN_SCALE_X(0.84f), SCREEN_SCALE_Y(1.0f));
- CFont::SetColor(PAGER_COLOR);
- CFont::SetRightJustifyOff();
- CFont::SetBackgroundOff();
- CFont::SetCentreOff();
- CFont::SetWrapx(SCREEN_STRETCH_X(DEFAULT_SCREEN_WIDTH));
- CFont::SetJustifyOff();
- CFont::SetPropOff();
- CFont::SetFontStyle(FONT_PAGER);
- CFont::PrintString(SCREEN_SCALE_X(52.0f) - SCREEN_SCALE_X_FIX(PagerXOffset), SCREEN_SCALE_Y(54.0f), m_PagerMessage);
- }
-
/*
DrawRadar
*/
- if (m_ItemToFlash == ITEM_RADAR && FRAMECOUNTER & 8 || m_ItemToFlash != ITEM_RADAR) {
+ if (FrontEndMenuManager.m_PrefsRadarMode != 2 &&
+ !m_HideRadar && (m_ItemToFlash == ITEM_RADAR && FRAMECOUNTER & 8 || m_ItemToFlash != ITEM_RADAR)) {
+
+ RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERNEAREST);
CRadar::DrawMap();
- CRect rect(0.0f, 0.0f, SCREEN_SCALE_X(RADAR_WIDTH), SCREEN_SCALE_Y(RADAR_HEIGHT));
- rect.Translate(SCREEN_SCALE_X_FIX(RADAR_LEFT), SCREEN_SCALE_FROM_BOTTOM(RADAR_BOTTOM + RADAR_HEIGHT));
-
-#ifdef PS2_HUD
- #ifdef FIX_BUGS
- rect.Grow(SCREEN_SCALE_X(2.0f), SCREEN_SCALE_X(4.0f), SCREEN_SCALE_Y(2.0f), SCREEN_SCALE_Y(4.0f));
- #else
- rect.Grow(2.0f, 4.0f);
- #endif
+ if (FrontEndMenuManager.m_PrefsRadarMode != 1) {
+ CRect rect(0.0f, 0.0f, SCREEN_SCALE_X(RADAR_WIDTH), SCREEN_SCALE_Y(RADAR_HEIGHT));
+
+ rect.Translate(SCREEN_SCALE_X_FIX(RADAR_LEFT), SCREEN_SCALE_FROM_BOTTOM(RADAR_BOTTOM + RADAR_HEIGHT));
+
+#ifdef FIX_BUGS
+ rect.Grow(SCREEN_SCALE_X(6.0f), SCREEN_SCALE_X(6.0f), SCREEN_SCALE_Y(6.0f), SCREEN_SCALE_Y(6.0f));
#else
- #ifdef FIX_BUGS
- rect.Grow(SCREEN_SCALE_X(4.0f), SCREEN_SCALE_X(4.0f), SCREEN_SCALE_Y(4.0f), SCREEN_SCALE_Y(4.0f));
- #else
- rect.Grow(4.0f);
- #endif
+ rect.Grow(6.0f);
#endif
- Sprites[HUD_RADARDISC].Draw(rect, RADARDISC_COLOR);
+ rect.Translate(SCREEN_SCALE_X_FIX(0.0f), SCREEN_SCALE_Y_FIX(2.0f));
+ Sprites[HUD_RADARDISC].Draw(rect, CRGBA(0, 0, 0, 255));
+ rect.Translate(SCREEN_SCALE_X_FIX(0.0f), SCREEN_SCALE_Y_FIX(-2.0f));
+ Sprites[HUD_RADARDISC].Draw(rect, RADARDISC_COLOR);
+ }
CRadar::DrawBlips();
}
}
@@ -1095,12 +1096,7 @@ void CHud::Draw()
if (!CTimer::GetIsUserPaused()) {
for (int i = 0; i < ARRAY_SIZE(CTheScripts::IntroTextLines); i++) {
if (CTheScripts::IntroTextLines[i].m_Text[0] && CTheScripts::IntroTextLines[i].m_bTextBeforeFade) {
- CFont::SetScale(SCREEN_SCALE_X_PC(CTheScripts::IntroTextLines[i].m_fScaleX), SCREEN_SCALE_Y_PC(CTheScripts::IntroTextLines[i].m_fScaleY)
-#if !defined(PS2_HUD) || defined(FIX_BUGS)
- * 0.5f
-#endif
- );
-
+ CFont::SetScale(SCREEN_SCALE_X(CTheScripts::IntroTextLines[i].m_fScaleX), SCREEN_SCALE_Y(CTheScripts::IntroTextLines[i].m_fScaleY * 0.5f));
CFont::SetColor(CTheScripts::IntroTextLines[i].m_sColor);
if (CTheScripts::IntroTextLines[i].m_bJustify)
@@ -1118,10 +1114,9 @@ void CHud::Draw()
else
CFont::SetCentreOff();
- CFont::SetWrapx(SCALE_AND_CENTER_X_PC(CTheScripts::IntroTextLines[i].m_fWrapX));
-
- CFont::SetCentreSize(SCREEN_SCALE_X_PC(CTheScripts::IntroTextLines[i].m_fCenterSize));
-
+ CFont::SetWrapx(SCALE_AND_CENTER_X(CTheScripts::IntroTextLines[i].m_fWrapX));
+ CFont::SetCentreSize(SCREEN_SCALE_X(CTheScripts::IntroTextLines[i].m_fCenterSize));
+
if (CTheScripts::IntroTextLines[i].m_bBackground)
CFont::SetBackgroundOn();
else
@@ -1140,12 +1135,7 @@ void CHud::Draw()
CFont::SetPropOff();
CFont::SetFontStyle(FONT_LOCALE(CTheScripts::IntroTextLines[i].m_nFont));
-
-#if defined(PS2_HUD) && !defined(FIX_BUGS)
- CFont::PrintString(CTheScripts::IntroTextLines[i].m_fAtX, CTheScripts::IntroTextLines[i].m_fAtY, CTheScripts::IntroTextLines[i].m_Text);
-#else
- CFont::PrintString(SCALE_AND_CENTER_X(DEFAULT_SCREEN_WIDTH - CTheScripts::IntroTextLines[i].m_fAtX), SCREEN_SCALE_Y(DEFAULT_SCREEN_HEIGHT - CTheScripts::IntroTextLines[i].m_fAtY), CTheScripts::IntroTextLines[i].m_Text);
-#endif
+ CFont::PrintString(SCREEN_WIDTH - SCALE_AND_CENTER_X(DEFAULT_SCREEN_WIDTH - CTheScripts::IntroTextLines[i].m_fAtX), SCREEN_HEIGHT - SCREEN_SCALE_Y(DEFAULT_SCREEN_HEIGHT - CTheScripts::IntroTextLines[i].m_fAtY), CTheScripts::IntroTextLines[i].m_Text);
}
}
for (int i = 0; i < ARRAY_SIZE(CTheScripts::IntroRectangles); i++) {
@@ -1177,41 +1167,173 @@ void CHud::Draw()
/*
DrawSubtitles
*/
- if (m_Message[0] && !m_BigMessage[2][0] && (FrontEndMenuManager.m_PrefsShowSubtitles == 1 || !TheCamera.m_WideScreenOn)) {
+ if (m_Message[0] && !m_BigMessage[2][0]) {
+ if (m_VehicleState != 0)
+ m_VehicleState = 3;
+ if (m_ZoneState != 0)
+ m_ZoneState = 3;
+
CFont::SetJustifyOff();
CFont::SetBackgroundOff();
CFont::SetBackgroundColor(CRGBA(0, 0, 0, 128));
- CFont::SetScale(SCREEN_SCALE_X_PC(0.48f), SCREEN_SCALE_Y_PC(1.12f));
CFont::SetCentreOn();
CFont::SetPropOn();
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
+#ifdef CUTSCENE_BORDERS_SWITCH
+ if (!FrontEndMenuManager.m_PrefsCutsceneBorders) {
+ CFont::SetDropColor(CRGBA(0, 0, 0, 255));
+ CFont::SetDropShadowPosition(2);
+ }
+ else
+#endif
+ CFont::SetDropShadowPosition(0);
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
+ CFont::SetColor(CRGBA(225, 225, 225, 255));
-#ifdef XBOX_SUBTITLES
- float radarBulge = SCREEN_SCALE_X(45.0f) + SCREEN_SCALE_X(16.0f);
- float rectWidth = SCREEN_WIDTH - SCREEN_SCALE_X(45.0f) - SCREEN_SCALE_X(16.0f) - radarBulge;
- CFont::SetCentreSize(rectWidth);
- CFont::SetColor(CRGBA(180, 180, 180, 255));
+ static bool onceItWasWidescreen = false;
- CFont::PrintOutlinedString(rectWidth / 2.0f + radarBulge, SCREEN_SCALE_Y(4.0f) + SCREEN_SCALE_FROM_BOTTOM(48.0f) - SCREEN_SCALE_Y(1), m_Message,
- 2.0f, true, CRGBA(0, 0, 0, 255));
-#else
- float radarBulge = SCREEN_SCALE_X(40.0f) + SCREEN_SCALE_X(8.0f);
- float rectWidth = SCREEN_SCALE_FROM_RIGHT(50.0f) - SCREEN_SCALE_X(8.0f) - radarBulge;
-
- CFont::SetCentreSize(rectWidth);
+ if (TheCamera.m_WideScreenOn) {
+ onceItWasWidescreen = true;
+
+ if (FrontEndMenuManager.m_PrefsShowSubtitles || !CCutsceneMgr::IsRunning()) {
+ CFont::SetCentreSize(SCREEN_WIDTH - SCREEN_SCALE_X(60.0f));
+ CFont::SetScale(SCREEN_SCALE_X(0.58f), SCREEN_SCALE_Y(1.2f));
+ CFont::PrintString(SCREEN_WIDTH / 2.f, SCREEN_SCALE_FROM_BOTTOM(80.0f), m_Message);
+ }
+ } else {
+ if (onceItWasWidescreen)
+ m_Message[0] = '\0';
- const int16 shadow = 1;
- CFont::SetDropShadowPosition(shadow);
- CFont::SetDropColor(CRGBA(0, 0, 0, 255));
- CFont::SetColor(CRGBA(235, 235, 235, 255));
+ onceItWasWidescreen = false;
+ CFont::DrawFonts();
+ CFont::SetDropShadowPosition(2);
+ CFont::SetDropColor(CRGBA(0, 0, 0, 255));
+ CFont::SetScale(SCREEN_SCALE_X(0.58f), SCREEN_SCALE_Y(1.22f));
+
+ float radarBulge = SCREEN_SCALE_X(140.0f) + SCREEN_SCALE_X(8.0f);
+ float rectWidth = SCREEN_WIDTH - SCREEN_SCALE_X(20.0f) - SCREEN_SCALE_X(8.0f) - radarBulge;
+ CFont::SetCentreSize(rectWidth);
- // I'm not sure shadow substaction was intentional here, might be a leftover if CFont::PrintString was used for a shadow draw call
- CFont::PrintString(rectWidth / 2.0f + radarBulge - SCREEN_SCALE_X_FIX(shadow), SCREEN_SCALE_Y_PC(4.0f) + SCREEN_SCALE_FROM_BOTTOM(SUBS_Y) - SCREEN_SCALE_Y_FIX(shadow), m_Message);
+ CFont::PrintString(rectWidth / 2.0f + radarBulge, SCREEN_SCALE_FROM_BOTTOM(105.f + 2.0f), m_Message);
+ }
CFont::SetDropShadowPosition(0);
-#endif // #ifdef XBOX_SUBTITLES
}
/*
+ HelpMessage
+ */
+
+ if (m_HelpMessage[0]) {
+ if (!CMessages::WideStringCompare(m_HelpMessage, m_LastHelpMessage, HELP_MSG_LENGTH)) {
+ switch (m_HelpMessageState) {
+ case 0:
+ m_HelpMessageFadeTimer = 0;
+ m_HelpMessageState = 2;
+ m_HelpMessageTimer = 0;
+ CMessages::WideStringCopy(m_HelpMessageToPrint, m_HelpMessage, HELP_MSG_LENGTH);
+ m_HelpMessageDisplayTime = CMessages::GetWideStringLength(m_HelpMessage) * 0.05f + 3.0f;
+
+ if (TheCamera.m_ScreenReductionPercentage == 0.0f)
+ DMAudio.PlayFrontEndSound(SOUND_HUD, 0);
+ break;
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ m_HelpMessageTimer = 5;
+ m_HelpMessageState = 4;
+ break;
+ default:
+ break;
+ }
+ CMessages::WideStringCopy(m_LastHelpMessage, m_HelpMessage, HELP_MSG_LENGTH);
+ }
+
+ float fAlpha = 225.0f;
+
+ if (m_HelpMessageState != 0) {
+ switch (m_HelpMessageState) {
+ case 1:
+ fAlpha = 225.0f;
+ m_HelpMessageFadeTimer = 600;
+ if (!m_HelpMessageDisplayForever && m_HelpMessageTimer > m_HelpMessageDisplayTime * 1000.0f ||
+ m_HelpMessageQuick && m_HelpMessageTimer > 1500.0f) {
+
+ m_HelpMessageFadeTimer = 600;
+ m_HelpMessageState = 3;
+ }
+ break;
+ case 2:
+ if (TheCamera.m_WideScreenOn)
+ break;
+
+ m_HelpMessageFadeTimer += 2 * CTimer::GetTimeStepInMilliseconds();
+ if (m_HelpMessageFadeTimer > 0) {
+ m_HelpMessageState = 1;
+ m_HelpMessageFadeTimer = 0;
+ }
+ fAlpha = m_HelpMessageFadeTimer * 0.001f * 225.0f;
+ break;
+ case 3:
+ m_HelpMessageFadeTimer -= 2 * CTimer::GetTimeStepInMilliseconds();
+ if (m_HelpMessageFadeTimer < 0 || TheCamera.m_WideScreenOn) {
+ m_HelpMessageState = 0;
+ m_HelpMessageFadeTimer = 0;
+ }
+ fAlpha = m_HelpMessageFadeTimer * 0.001f * 225.0f;
+ break;
+ case 4:
+ m_HelpMessageFadeTimer -= 2 * CTimer::GetTimeStepInMilliseconds();
+ if (m_HelpMessageFadeTimer < 0) {
+ m_HelpMessageState = 2;
+ m_HelpMessageFadeTimer = 0;
+ CMessages::WideStringCopy(m_HelpMessageToPrint, m_LastHelpMessage, HELP_MSG_LENGTH);
+ }
+ fAlpha = m_HelpMessageFadeTimer * 0.001f * 225.0f;
+ break;
+ default:
+ break;
+ }
+
+ if (!TheCamera.m_WideScreenOn) {
+ m_HelpMessageTimer += CTimer::GetTimeStepInMilliseconds();
+
+ CFont::SetAlphaFade(fAlpha);
+ CFont::SetCentreOff();
+ CFont::SetPropOn();
+
+ if (CGame::germanGame)
+ CFont::SetScale(SCREEN_SCALE_X(0.52f * 0.85f), SCREEN_SCALE_Y(1.1f * 0.85f));
+#ifdef MORE_LANGUAGES
+ else if (CFont::IsJapanese())
+ CFont::SetScale(SCREEN_SCALE_X(0.52f) * 1.35f, SCREEN_SCALE_Y(1.1f) * 1.25f);
+#endif
+ else
+ CFont::SetScale(SCREEN_SCALE_X(0.52f), SCREEN_SCALE_Y(1.1f));
+
+ CFont::DrawFonts();
+ CFont::SetColor(CRGBA(175, 175, 175, 255));
+ CFont::SetJustifyOff();
+#ifdef MORE_LANGUAGES
+ if (CFont::IsJapanese())
+ CFont::SetWrapx(SCREEN_SCALE_X(229.0f + 34.0f - 4.0f));
+ else
+#endif
+ CFont::SetWrapx(SCREEN_SCALE_X(200.0f + 34.0f - 4.0f));
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
+ CFont::SetBackgroundOn();
+ CFont::SetBackGroundOnlyTextOff();
+ CFont::SetDropShadowPosition(0);
+ CFont::SetBackgroundColor(CRGBA(0, 0, 0, fAlpha * 0.9f));
+ CFont::SetColor(CRGBA(175, 175, 175, 255));
+ CFont::PrintString(SCREEN_SCALE_X(34.0f), SCREEN_SCALE_Y(28.0f + (150.0f - PagerXOffset) * 0.6f), m_HelpMessageToPrint);
+ CFont::SetAlphaFade(255.0f);
+ CFont::SetWrapx(SCREEN_WIDTH);
+ }
+ }
+ } else
+ m_HelpMessageState = 0;
+
+ /*
DrawBigMessage
*/
// MissionCompleteFailedText
@@ -1220,25 +1342,20 @@ void CHud::Draw()
CFont::SetJustifyOff();
CFont::SetBackgroundOff();
CFont::SetBackGroundOnlyTextOff();
-
- if (CGame::frenchGame || CGame::germanGame)
- CFont::SetScale(SCREEN_SCALE_X_PC(1.8f), SCREEN_SCALE_Y_PC(1.8f));
- else
- CFont::SetScale(SCREEN_SCALE_X_PC(1.8f), SCREEN_SCALE_Y_PC(1.8f));
-
+ if (CGame::frenchGame || CGame::germanGame) {
+ CFont::SetScale(SCREEN_SCALE_X(1.6f), SCREEN_SCALE_Y(1.8f));
+ } else {
+ CFont::SetScale(SCREEN_SCALE_X(1.8f), SCREEN_SCALE_Y(1.8f));
+ }
CFont::SetPropOn();
CFont::SetCentreOn();
- CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH - 25));
- CFont::SetColor(CRGBA(255, 255, 0, 255));
+ CFont::SetCentreSize(SCREEN_SCALE_X(590.0f));
+ CFont::SetColor(CRGBA(255, 255, 0, BigMessageAlpha[0])); // unused color
CFont::SetFontStyle(FONT_HEADING);
// Appearently sliding text in here was abandoned very early, since this text is centered now.
-#ifdef FIX_BUGS
- if (BigMessageX[0] >= SCALE_AND_CENTER_X(DEFAULT_SCREEN_WIDTH-20))
-#else
- if (BigMessageX[0] >= SCREEN_WIDTH-20)
-#endif
- {
+
+ if (BigMessageX[0] >= SCALE_AND_CENTER_X(620.0f)) {
BigMessageInUse[0] += CTimer::GetTimeStep();
if (BigMessageInUse[0] >= 120.0f) {
@@ -1252,29 +1369,21 @@ void CHud::Draw()
}
}
else {
- BigMessageX[0] += SCREEN_SCALE_X_FIX(CTimer::GetTimeStepInMilliseconds() * 0.3f);
+ BigMessageX[0] += SCREEN_SCALE_X((CTimer::GetTimeStepInMilliseconds() * 0.3f));
BigMessageAlpha[0] += (CTimer::GetTimeStepInMilliseconds() * 0.3f);
if (BigMessageAlpha[0] > 255.0f)
BigMessageAlpha[0] = 255.0f;
}
- CFont::SetColor(CRGBA(0, 0, 0, BigMessageAlpha[0]));
-
-#if defined(PS2_HUD) && !defined(FIX_BUGS) // yeah, that's right. ps2 uses y=ScaleX(a)
- CFont::PrintString(SCREEN_WIDTH / 2 + SCREEN_SCALE_X_FIX(2.0f), (SCREEN_WIDTH / 2) - SCREEN_SCALE_X(120.0f) + SCREEN_SCALE_Y_FIX(2.0f), m_BigMessage[0]);
-#else
- CFont::PrintString(SCREEN_WIDTH / 2 + SCREEN_SCALE_X_FIX(2.0f), (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(BIGMESSAGE_Y_OFFSET) + SCREEN_SCALE_Y_FIX(2.0f), m_BigMessage[0]);
-#endif
+ CFont::DrawFonts();
+ CFont::SetDropShadowPosition(2);
+ CFont::SetDropColor(CRGBA(0, 0, 0, BigMessageAlpha[0]));
CFont::SetColor(CRGBA(BIGMESSAGE_COLOR.r, BIGMESSAGE_COLOR.g, BIGMESSAGE_COLOR.b, BigMessageAlpha[0]));
-#if defined(PS2_HUD) && !defined(FIX_BUGS) // same
- CFont::PrintString(SCREEN_WIDTH / 2, (SCREEN_WIDTH / 2) - SCREEN_SCALE_X(120.0f), m_BigMessage[0]);
-#else
CFont::PrintString(SCREEN_WIDTH / 2, (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(18.0f), m_BigMessage[0]);
-#endif
}
else {
BigMessageAlpha[0] = 0.0f;
- BigMessageX[0] = SCALE_AND_CENTER_X_FIX(-60.0f);
+ BigMessageX[0] = SCALE_AND_CENTER_X(-60.0f);
BigMessageInUse[0] = 1.0f;
}
}
@@ -1293,22 +1402,27 @@ void CHud::Draw()
CFont::SetBackgroundOff();
if (CGame::frenchGame || CGame::germanGame)
- CFont::SetScale(SCREEN_SCALE_X_PC(1.4f), SCREEN_SCALE_Y_PC(1.4f));
+ CFont::SetScale(SCREEN_SCALE_X(1.4f), SCREEN_SCALE_Y(1.4f));
else
- CFont::SetScale(SCREEN_SCALE_X_PC(2.0f), SCREEN_SCALE_Y_PC(2.0f));
+ CFont::SetScale(SCREEN_SCALE_X(2.0f), SCREEN_SCALE_Y(2.0f));
CFont::SetPropOn();
CFont::SetRightJustifyOn();
CFont::SetFontStyle(FONT_HEADING);
- CFont::SetColor(CRGBA(0, 0, 0, BigMessageAlpha[2]*0.75f));
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f) + SCREEN_SCALE_X_FIX(4.0f), SCREEN_SCALE_FROM_BOTTOM(WASTEDBUSTED_Y) + SCREEN_SCALE_Y(4.0f), m_BigMessage[2]);
+ CFont::SetDropShadowPosition(2);
+ CFont::SetDropColor(CRGBA(0, 0, 0, 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(WASTEDBUSTED_Y), m_BigMessage[2]);
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f), SCREEN_SCALE_FROM_BOTTOM(90.0f), m_BigMessage[2]);
}
else {
- BigMessageAlpha[2] = 0.0f;
BigMessageInUse[2] = 1.0f;
+ BigMessageAlpha[2] = 0.0f;
+ if (m_VehicleState != 0) // Hide vehicle name if wasted/busted text is displaying
+ m_VehicleState = 0;
+ if (m_ZoneState != 0)
+ m_ZoneState = 0;
}
}
else {
@@ -1319,118 +1433,18 @@ void CHud::Draw()
void CHud::DrawAfterFade()
{
+ RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERNEAREST);
+ RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
+
if (CTimer::GetIsUserPaused() || CReplay::IsPlayingBack())
return;
- if (m_HelpMessage[0]) {
- if (!CMessages::WideStringCompare(m_HelpMessage, m_LastHelpMessage, HELP_MSG_LENGTH)) {
- switch (m_HelpMessageState) {
- case 0:
- m_HelpMessageFadeTimer = 0;
- m_HelpMessageState = 2;
- m_HelpMessageTimer = 0;
- CMessages::WideStringCopy(m_HelpMessageToPrint, m_HelpMessage, HELP_MSG_LENGTH);
- m_HelpMessageDisplayTime = CMessages::GetWideStringLength(m_HelpMessage) / 20.0f + 3.0f;
-
- if (TheCamera.m_ScreenReductionPercentage == 0.0f)
- DMAudio.PlayFrontEndSound(SOUND_HUD, 0);
- break;
- case 1:
- case 2:
- case 3:
- case 4:
- m_HelpMessageTimer = 5;
- m_HelpMessageState = 4;
- break;
- default:
- break;
- }
- CMessages::WideStringCopy(m_LastHelpMessage, m_HelpMessage, HELP_MSG_LENGTH);
- }
-
- float fAlpha = 225.0f;
-
- if (m_HelpMessageState != 0) {
- switch (m_HelpMessageState) {
- case 1:
- fAlpha = 225.0f;
- m_HelpMessageFadeTimer = 600;
- if (m_HelpMessageTimer > m_HelpMessageDisplayTime * 1000.0f || m_HelpMessageQuick && m_HelpMessageTimer > 1500.0f) {
- m_HelpMessageFadeTimer = 600;
- m_HelpMessageState = 3;
- }
- break;
- case 2:
- m_HelpMessageFadeTimer += 2 * CTimer::GetTimeStepInMilliseconds();
- if (m_HelpMessageFadeTimer > 0) {
- m_HelpMessageState = 1;
- m_HelpMessageFadeTimer = 0;
- }
- fAlpha = m_HelpMessageFadeTimer / 1000.0f * 225.0f;
- break;
- case 3:
- m_HelpMessageFadeTimer -= 2 * CTimer::GetTimeStepInMilliseconds();
- if (m_HelpMessageFadeTimer < 0) {
- m_HelpMessageState = 0;
- m_HelpMessageFadeTimer = 0;
- }
- fAlpha = m_HelpMessageFadeTimer / 1000.0f * 225.0f;
- break;
- case 4:
- m_HelpMessageFadeTimer -= 2 * CTimer::GetTimeStepInMilliseconds();
- if (m_HelpMessageFadeTimer < 0) {
- m_HelpMessageState = 2;
- m_HelpMessageFadeTimer = 0;
- CMessages::WideStringCopy(m_HelpMessageToPrint, m_LastHelpMessage, HELP_MSG_LENGTH);
- }
- fAlpha = m_HelpMessageFadeTimer / 1000.0f * 225.0f;
- break;
- default:
- break;
- }
-
- m_HelpMessageTimer += CTimer::GetTimeStepInMilliseconds();
-
- CFont::SetAlphaFade(fAlpha);
- CFont::SetCentreOff();
- CFont::SetPropOn();
-
- if (CGame::germanGame)
- CFont::SetScale(SCREEN_SCALE_X(0.52f * 0.85f), SCREEN_SCALE_Y(1.1f * 0.85f));
-#ifdef MORE_LANGUAGES
- else if (CFont::IsJapanese())
- CFont::SetScale(SCREEN_SCALE_X(0.52f) * 1.35f, SCREEN_SCALE_Y(1.1f) * 1.25f);
-#endif
- else
- CFont::SetScale(SCREEN_SCALE_X(0.52f), SCREEN_SCALE_Y(1.1f));
-
- CFont::SetColor(CRGBA(175, 175, 175, 255));
- CFont::SetJustifyOff();
-#ifdef MORE_LANGUAGES
- if (CFont::IsJapanese())
- CFont::SetWrapx(SCREEN_SCALE_X(229.0f) + SCREEN_SCALE_X(26.0f) - SCREEN_SCALE_X_FIX(4.0f));
- else
-#endif
- CFont::SetWrapx(SCREEN_SCALE_X(200.0f) + SCREEN_SCALE_X(26.0f) - SCREEN_SCALE_X_FIX(4.0f));
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
- CFont::SetBackgroundOn();
- CFont::SetBackGroundOnlyTextOff();
- CFont::SetBackgroundColor(CRGBA(0, 0, 0, fAlpha * 0.9f));
- CFont::SetColor(CRGBA(175, 175, 175, 255));
- CFont::PrintString(SCREEN_SCALE_X(26.0f), SCREEN_SCALE_Y(28.0f) + SCREEN_SCALE_Y_FIX((150.0f - PagerXOffset) * 0.6f), m_HelpMessageToPrint);
- CFont::SetAlphaFade(255.0f);
- }
- }
-
for (int i = 0; i < ARRAY_SIZE(CTheScripts::IntroTextLines); i++) {
intro_text_line &line = CTheScripts::IntroTextLines[i];
if (line.m_Text[0] != '\0' && !line.m_bTextBeforeFade) {
+ CFont::SetScale(SCREEN_SCALE_X(line.m_fScaleX), SCREEN_SCALE_Y(line.m_fScaleY) / 2);
- CFont::SetScale(SCREEN_SCALE_X_PC(line.m_fScaleX), SCREEN_SCALE_Y_PC(line.m_fScaleY)
-#if !defined(PS2_HUD) || defined(FIX_BUGS)
- / 2
-#endif
- );
CFont::SetColor(line.m_sColor);
if (line.m_bJustify)
CFont::SetJustifyOn();
@@ -1447,9 +1461,8 @@ void CHud::DrawAfterFade()
else
CFont::SetCentreOff();
- CFont::SetWrapx(SCALE_AND_CENTER_X_PC(line.m_fWrapX));
- CFont::SetCentreSize(SCREEN_SCALE_X_PC(line.m_fCenterSize));
-
+ CFont::SetWrapx(SCALE_AND_CENTER_X(line.m_fWrapX));
+ CFont::SetCentreSize(SCREEN_SCALE_X(line.m_fCenterSize));
if (line.m_bBackground)
CFont::SetBackgroundOn();
else
@@ -1467,11 +1480,7 @@ void CHud::DrawAfterFade()
CFont::SetPropOff();
CFont::SetFontStyle(line.m_nFont);
-#if defined(PS2_HUD) && !defined(FIX_BUGS)
- CFont::PrintString(line.m_fAtX, line.m_fAtY, line.m_Text);
-#else
- CFont::PrintString(SCALE_AND_CENTER_X(DEFAULT_SCREEN_WIDTH - line.m_fAtX), SCREEN_SCALE_Y(DEFAULT_SCREEN_HEIGHT - line.m_fAtY), line.m_Text);
-#endif
+ CFont::PrintString(SCREEN_WIDTH - SCALE_AND_CENTER_X(DEFAULT_SCREEN_WIDTH - line.m_fAtX), SCREEN_HEIGHT - SCREEN_SCALE_Y(DEFAULT_SCREEN_HEIGHT - line.m_fAtY), line.m_Text);
}
}
for (int i = 0; i < ARRAY_SIZE(CTheScripts::IntroRectangles); i++) {
@@ -1496,29 +1505,29 @@ void CHud::DrawAfterFade()
if (m_BigMessage[3][0]) {
CFont::SetJustifyOff();
CFont::SetBackgroundOff();
- CFont::SetScale(SCREEN_SCALE_X_PC(1.2f), SCREEN_SCALE_Y_PC(1.5f));
+ CFont::SetScale(SCREEN_SCALE_X(1.2f), SCREEN_SCALE_Y(1.5f));
CFont::SetCentreOn();
CFont::SetPropOn();
- CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH - 40));
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
- CFont::SetColor(CRGBA(0, 0, 0, 255));
- CFont::PrintString((SCREEN_WIDTH / 2) + SCREEN_SCALE_X_FIX(2.0f), (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(BIGMESSAGE_Y) + SCREEN_SCALE_Y_FIX(2.0f), m_BigMessage[3]);
+ CFont::SetCentreSize(SCREEN_SCALE_X(600.0f));
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
+ CFont::SetDropShadowPosition(2);
+ CFont::SetDropColor(CRGBA(0, 0, 0, 255));
CFont::SetColor(ODDJOB_COLOR);
- CFont::PrintString((SCREEN_WIDTH / 2), (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(BIGMESSAGE_Y), m_BigMessage[3]);
+ CFont::PrintString((SCREEN_WIDTH / 2), SCREEN_SCALE_Y(140.0f) - SCREEN_SCALE_Y(16.0f), m_BigMessage[3]);
}
if (!m_BigMessage[1][0] && m_BigMessage[4][0]) {
CFont::SetJustifyOff();
CFont::SetBackgroundOff();
- CFont::SetScale(SCREEN_SCALE_X_PC(1.2f), SCREEN_SCALE_Y_PC(1.5f));
+ CFont::SetScale(SCREEN_SCALE_X(1.2f), SCREEN_SCALE_Y(1.5f));
CFont::SetCentreOn();
CFont::SetPropOn();
- CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH - 20));
- CFont::SetColor(CRGBA(0, 0, 0, 255));
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
- CFont::PrintString((SCREEN_WIDTH / 2) - SCREEN_SCALE_X_FIX(2.0f), (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(BIGMESSAGE_Y) - SCREEN_SCALE_Y_FIX(2.0f), m_BigMessage[4]);
+ CFont::SetCentreSize(SCREEN_SCALE_X(580.0f));
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
+ CFont::SetDropShadowPosition(2);
+ CFont::SetDropColor(CRGBA(0, 0, 0, 255));
CFont::SetColor(ODDJOB_COLOR);
- CFont::PrintString((SCREEN_WIDTH / 2), (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(BIGMESSAGE_Y), m_BigMessage[4]);
+ CFont::PrintString((SCREEN_WIDTH / 2), SCREEN_SCALE_Y(140.0f), m_BigMessage[4]);
}
// Oddjob result
@@ -1568,24 +1577,12 @@ void CHud::DrawAfterFade()
CFont::SetScale(SCREEN_SCALE_X(1.0f), SCREEN_SCALE_Y(1.2f));
CFont::SetCentreOn();
CFont::SetPropOn();
- // Not bug, we just want these kind of texts to be wrapped at the center.
-#ifdef ASPECT_RATIO_SCALE
- CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH - 20.0f));
-#else
- CFont::SetCentreSize(SCREEN_SCALE_FROM_RIGHT(20.0f));
-#endif
- CFont::SetColor(CRGBA(0, 0, 0, 255));
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
-
-#ifdef BETA_SLIDING_TEXT
- CFont::PrintString(SCREEN_WIDTH / 2 + SCREEN_SCALE_X_PC(2.0f) - SCREEN_SCALE_X(OddJob2XOffset), SCREEN_HEIGHT / 2 - SCREEN_SCALE_Y(20.0f) + SCREEN_SCALE_Y_PC(2.0f), m_BigMessage[5]);
- 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_PC(2.0f), SCREEN_HEIGHT / 2 - SCREEN_SCALE_Y(20.0f) + SCREEN_SCALE_Y_PC(2.0f), m_BigMessage[5]);
+ CFont::SetCentreSize(SCREEN_SCALE_X(560.0f));
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
+ CFont::SetDropShadowPosition(2);
+ CFont::SetDropColor(CRGBA(0, 0, 0, 255));
CFont::SetColor(ODDJOB2_COLOR);
- CFont::PrintString(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2 - SCREEN_SCALE_Y(20.0f), m_BigMessage[5]);
-#endif
+ CFont::PrintString(SCREEN_WIDTH / 2, SCREEN_SCALE_Y(217.0f), m_BigMessage[5]);
}
}
@@ -1597,82 +1594,261 @@ void CHud::DrawAfterFade()
CFont::SetJustifyOff();
CFont::SetBackgroundOff();
+ // will be overwritten below
if (CGame::frenchGame || FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_SPANISH)
- CFont::SetScale(SCREEN_SCALE_X_PC(0.884f), SCREEN_SCALE_Y_PC(1.36f));
+ CFont::SetScale(SCREEN_SCALE_X(0.884f), SCREEN_SCALE_Y(1.36f));
else
- CFont::SetScale(SCREEN_SCALE_X_PC(1.04f), SCREEN_SCALE_Y_PC(1.6f));
+ CFont::SetScale(SCREEN_SCALE_X(1.04f), SCREEN_SCALE_Y(1.6f));
CFont::SetPropOn();
-#ifdef FIX_BUGS
- CFont::SetRightJustifyWrap(SCREEN_SCALE_FROM_RIGHT(DEFAULT_SCREEN_WIDTH + 500.0f));
-#else
- CFont::SetRightJustifyWrap(-500.0f);
-#endif
+ CFont::SetRightJustifyWrap(SCALE_AND_CENTER_X(0.0f));
CFont::SetRightJustifyOn();
- CFont::SetFontStyle(FONT_HEADING);
-
- if (BigMessageX[1] >= SCREEN_WIDTH - SCREEN_SCALE_X_FIX(20.0f))
- {
+ CFont::SetFontStyle(FONT_BANK);
+ CFont::SetScale(FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_AMERICAN ? SCREEN_SCALE_X(1.7f) : SCREEN_SCALE_X(1.5f), SCREEN_SCALE_Y(1.8f));
+
+ if (BigMessageX[1] >= SCREEN_SCALE_FROM_RIGHT(20.0f)) {
BigMessageInUse[1] += CTimer::GetTimeStep();
if (BigMessageInUse[1] >= 120.0f) {
BigMessageInUse[1] = 120.0f;
- BigMessageAlpha[1] -= (CTimer::GetTimeStepInMilliseconds() * 0.3f);
+ BigMessageAlpha[1] -= CTimer::GetTimeStepInMilliseconds();
}
- if (BigMessageAlpha[1] <= 0) {
+ if (BigMessageAlpha[1] <= 0.0f) {
m_BigMessage[1][0] = 0;
+ BigMessageInUse[1] = 0.0f;
BigMessageAlpha[1] = 0.0f;
}
} else {
- BigMessageX[1] += SCREEN_SCALE_X_FIX(CTimer::GetTimeStepInMilliseconds() * 0.3f);
- BigMessageAlpha[1] += (CTimer::GetTimeStepInMilliseconds() * 0.3f);
+ BigMessageX[1] += SCREEN_SCALE_X((CTimer::GetTimeStepInMilliseconds() * 0.3f));
+ BigMessageAlpha[1] += CTimer::GetTimeStepInMilliseconds();
if (BigMessageAlpha[1] > 255.0f)
BigMessageAlpha[1] = 255.0f;
}
- CFont::SetColor(CRGBA(40, 40, 40, BigMessageAlpha[1]));
-#ifdef BETA_SLIDING_TEXT
- CFont::PrintString(SCREEN_SCALE_X(2.0f) + BigMessageX[1], SCREEN_SCALE_FROM_BOTTOM(120.0f) + SCREEN_SCALE_Y_PC(2.0f), m_BigMessage[1]);
- CFont::SetColor(CRGBA(MISSIONTITLE_COLOR.r, MISSIONTITLE_COLOR.g, MISSIONTITLE_COLOR.b, BigMessageAlpha[1]));
- CFont::PrintString(BigMessageX[1], SCREEN_SCALE_FROM_BOTTOM(120.0f), m_BigMessage[1]);
-#else
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f) + SCREEN_SCALE_X_FIX(2.0f), SCREEN_SCALE_FROM_BOTTOM(120.0f) + SCREEN_SCALE_Y_PC(2.0f), m_BigMessage[1]);
+ CFont::SetColor(CRGBA(40, 40, 40, BigMessageAlpha[1])); // what was that for?
+
+ CFont::SetDropShadowPosition(2);
+ CFont::SetDropColor(CRGBA(0, 0, 0, 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]);
-#endif
- }
- else {
- BigMessageAlpha[1] = 0.0f;
-#ifdef FIX_BUGS
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f), SCREEN_SCALE_FROM_BOTTOM(140.0f), m_BigMessage[1]);
+ } else {
+ m_ZoneFadeTimer = 0;
BigMessageX[1] = SCREEN_SCALE_FROM_RIGHT(DEFAULT_SCREEN_WIDTH + 60.0f);
-#else
- BigMessageX[1] = -60.0f;
-#endif
BigMessageInUse[1] = 1.0f;
+ m_ZoneState = 0;
}
- }
- else {
+ } else {
BigMessageInUse[1] = 0.0f;
}
}
-void CHud::SetMessage(wchar *message)
+void CHud::GetRidOfAllHudMessages()
{
- int i = 0;
- for (i = 0; i < ARRAY_SIZE(m_Message); i++) {
- if (message[i] == 0)
- break;
+ m_ZoneNameTimer = 0;
+ m_pZoneName = nil;
+ m_ZoneState = 0;
- m_Message[i] = message[i];
+ for (int i = 0; i < HELP_MSG_LENGTH; i++) {
+ m_HelpMessage[i] = 0;
+ m_LastHelpMessage[i] = 0;
+ m_HelpMessageToPrint[i] = 0;
+ }
+
+ m_HelpMessageTimer = 0;
+ m_HelpMessageFadeTimer = 0;
+ m_HelpMessageState = 0;
+ m_HelpMessageQuick = 0;
+ m_HelpMessageDisplayForever = false;
+ m_HelpMessageDisplayTime = 1.0f;
+ m_VehicleName = nil;
+ m_pVehicleNameToPrint = nil;
+ m_VehicleNameTimer = 0;
+ m_VehicleFadeTimer = 0;
+ m_VehicleState = 0;
+
+ for (int i = 0; i < ARRAY_SIZE(m_Message); i++)
+ m_Message[i] = 0;
+
+ for (int i = 0; i < 6; i++) {
+ BigMessageInUse[i] = 0.0f;
+
+ for (int j = 0; j < 128; j++)
+ m_BigMessage[i][j] = 0;
}
- m_Message[i] = 0;
}
+#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;
+ m_Wants_To_Draw_3dMarkers = true;
+
+ int 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);
+ }
+
+ m_pLastZoneName = nil;
+ GetRidOfAllHudMessages();
+ m_pLastVehicleName = nil;
+
+ if (gpSniperSightTex == nil)
+ gpSniperSightTex = RwTextureRead("sitesniper", nil); // unused
+ if (gpRocketSightTex == nil)
+ gpRocketSightTex = RwTextureRead("siterocket", nil);
+ if (gpLaserSightTex == nil)
+ gpLaserSightTex = RwTextureRead("sitelaser", nil); // unused
+ if (gpLaserDotTex == nil)
+ gpLaserDotTex = RwTextureRead("laserdot", "laserdotm");
+ if (gpViewFinderTex == nil)
+ gpViewFinderTex = RwTextureRead("viewfinder_128", "viewfinder_128m"); // unused
+
+ m_ClockState = 1;
+ CounterOnLastFrame[0] = false;
+ CounterOnLastFrame[1] = false;
+ CounterOnLastFrame[2] = false;
+
+ m_ItemToFlash = ITEM_NONE;
+ OddJob2Timer = 0;
+ OddJob2OffTimer = 0.0f;
+ OddJob2On = 0;
+ OddJob2XOffset = 0.0f;
+ CounterFlashTimer[0] = 0;
+ CounterFlashTimer[1] = 0;
+ CounterFlashTimer[2] = 0;
+ TimerOnLastFrame = false;
+ TimerFlashTimer = 0;
+ SpriteBrightness = 0;
+ PagerOn = 0;
+ 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_HideRadar = false;
+ m_LastDisplayScore = CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney;
+ m_LastTimeEnergyLost = CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastHealthLoss;
+ m_LastWanted = 0;
+ m_LastWeapon = 0;
+
+#ifndef MASTER
+ VarConsole.Add("Draw HUD", &m_Wants_To_Draw_Hud, false);
+#endif
+ CTxdStore::PopCurrentTxd();
+}
+
+void CHud::ReInitialise() {
+ m_Wants_To_Draw_Hud = true;
+ m_Wants_To_Draw_3dMarkers = true;
+
+ m_pLastZoneName = nil;
+ GetRidOfAllHudMessages();
+ m_pLastVehicleName = nil;
+
+ CounterOnLastFrame[0] = false;
+ CounterOnLastFrame[1] = false;
+ CounterOnLastFrame[2] = false;
+ m_ItemToFlash = ITEM_NONE;
+ m_ClockState = 1;
+ OddJob2Timer = 0;
+ OddJob2OffTimer = 0.0f;
+ OddJob2On = 0;
+ OddJob2XOffset = 0.0f;
+ CounterFlashTimer[0] = 0;
+ CounterFlashTimer[1] = 0;
+ CounterFlashTimer[2] = 0;
+ TimerOnLastFrame = false;
+ TimerFlashTimer = 0;
+ SpriteBrightness = 0;
+ PagerOn = 0;
+ 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_HideRadar = false;
+ m_LastDisplayScore = CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney;
+ m_LastTimeEnergyLost = CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastHealthLoss;
+ m_LastWanted = 0;
+ m_LastWeapon = 0;
+}
+
+wchar LastBigMessage[6][128];
+
void CHud::SetBigMessage(wchar *message, uint16 style)
{
int i = 0;
+ if (BigMessageInUse[style] != 0.0f)
+ return;
+
if (style == 5) {
for (i = 0; i < 128; i++) {
if (message[i] == 0)
@@ -1695,9 +1871,62 @@ void CHud::SetBigMessage(wchar *message, uint16 style)
}
LastBigMessage[style][i] = 0;
m_BigMessage[style][i] = 0;
-#ifndef FIX_BUGS
- m_BigMessage[style][i] = 0;
-#endif
+}
+
+void CHud::SetHelpMessage(wchar *message, bool quick, bool displayForever)
+{
+ if (!CReplay::IsPlayingBack()) {
+ for (int i = 0; i < HELP_MSG_LENGTH; i++) {
+ m_HelpMessage[i] = 0;
+ }
+ for (int i = 0; i < HELP_MSG_LENGTH; i++) {
+ m_LastHelpMessage[i] = 0;
+ }
+ for (int i = 0; i < HELP_MSG_LENGTH; i++) {
+ m_HelpMessageToPrint[i] = 0;
+ }
+
+ CMessages::WideStringCopy(m_HelpMessage, message, HELP_MSG_LENGTH);
+ CMessages::InsertPlayerControlKeysInString(m_HelpMessage);
+ if (m_HelpMessageState == 0 || !CMessages::WideStringCompare(m_HelpMessage, m_HelpMessageToPrint, HELP_MSG_LENGTH)) {
+ for (int i = 0; i < HELP_MSG_LENGTH; i++) {
+ m_LastHelpMessage[i] = 0;
+ }
+
+ if (!message) {
+ m_HelpMessage[0] = 0;
+ m_HelpMessageToPrint[0] = 0;
+ }
+ if (!displayForever) {
+ m_HelpMessageState = displayForever;
+ } else {
+ m_HelpMessageState = 1;
+ CMessages::WideStringCopy(m_HelpMessageToPrint, m_HelpMessage, HELP_MSG_LENGTH);
+ CMessages::WideStringCopy(m_LastHelpMessage, m_HelpMessage, HELP_MSG_LENGTH);
+ }
+
+ m_HelpMessageQuick = quick;
+ m_HelpMessageDisplayForever = displayForever;
+ }
+
+ }
+}
+
+bool CHud::IsHelpMessageBeingDisplayed(void)
+{
+ return m_HelpMessageState != 0;
+}
+
+void CHud::SetMessage(wchar *message)
+{
+ int i = 0;
+ for (i = 0; i < ARRAY_SIZE(m_Message); i++) {
+ if (message[i] == 0)
+ break;
+
+ m_Message[i] = message[i];
+ }
+ m_Message[i] = 0;
}
void CHud::SetPagerMessage(wchar *message)
@@ -1710,4 +1939,151 @@ void CHud::SetPagerMessage(wchar *message)
m_PagerMessage[i] = message[i];
}
m_PagerMessage[i] = 0;
-} \ No newline at end of file
+}
+
+void CHud::SetVehicleName(wchar *name)
+{
+ m_VehicleName = name;
+}
+
+void CHud::SetZoneName(wchar *name)
+{
+ m_pZoneName = name;
+}
+
+void CHud::Shutdown()
+{
+ for (int i = 0; i < NUM_HUD_SPRITES; ++i) {
+ Sprites[i].Delete();
+ }
+
+ RwTextureDestroy(gpSniperSightTex);
+ gpSniperSightTex = nil;
+
+ RwTextureDestroy(gpRocketSightTex);
+ gpRocketSightTex = nil;
+
+ RwTextureDestroy(gpLaserSightTex);
+ gpLaserSightTex = nil;
+
+ RwTextureDestroy(gpLaserDotTex);
+ gpLaserDotTex = nil;
+
+ RwTextureDestroy(gpViewFinderTex);
+ gpViewFinderTex = nil;
+
+ 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);
+}
+
+void
+CHud::ResetWastedText(void)
+{
+ BigMessageInUse[2] = 0.0f;
+ BigMessageInUse[0] = 0.0f;
+ m_BigMessage[2][0] = 0;
+ m_BigMessage[0][0] = 0;
+}
diff --git a/src/renderer/Hud.h b/src/renderer/Hud.h
index adfdf1fc..a4b9609a 100644
--- a/src/renderer/Hud.h
+++ b/src/renderer/Hud.h
@@ -3,6 +3,9 @@
#define HELP_MSG_LENGTH 256
+#define HUD_TEXT_SCALE_X 0.7f
+#define HUD_TEXT_SCALE_Y 1.25f
+
enum eItems
{
ITEM_NONE = -1,
@@ -11,71 +14,126 @@ 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,
- HUD_BAT,
- HUD_PISTOL,
- HUD_UZI,
- HUD_SHOTGUN,
- HUD_AK47,
- HUD_M16,
- HUD_SNIPER,
- HUD_ROCKET,
- HUD_FLAME,
- HUD_MOLOTOV,
- HUD_GRENADE,
- HUD_DETONATOR,
- HUD_RADARDISC = 15,
- HUD_PAGER = 16,
- HUD_SITESNIPER = 20,
+ HUD_SITEROCKET = 41,
+ HUD_RADARDISC = 50,
+ HUD_SITESNIPER = 63,
HUD_SITEM16,
- HUD_SITEROCKET,
- NUM_HUD_SPRITES,
+ HUD_SITELASER,
+ HUD_LASERDOT,
+ HUD_VIEWFINDER,
+ HUD_BLEEDER,
+ NUM_HUD_SPRITES = 69,
};
class CHud
{
public:
- static int16 m_ItemToFlash;
static CSprite2d Sprites[NUM_HUD_SPRITES];
- static wchar *m_pZoneName;
- static wchar *m_pLastZoneName;
- static wchar *m_ZoneToPrint;
- static wchar m_Message[256];
- static wchar m_BigMessage[6][128];
- static wchar m_PagerMessage[256];
- static uint32 m_ZoneNameTimer;
- static int32 m_ZoneFadeTimer;
- static uint32 m_ZoneState;
static wchar m_HelpMessage[HELP_MSG_LENGTH];
static wchar m_LastHelpMessage[HELP_MSG_LENGTH];
- static wchar m_HelpMessageToPrint[HELP_MSG_LENGTH];
+ static uint32 m_HelpMessageState;
static uint32 m_HelpMessageTimer;
static int32 m_HelpMessageFadeTimer;
- static uint32 m_HelpMessageState;
- static bool m_HelpMessageQuick;
+ static wchar m_HelpMessageToPrint[HELP_MSG_LENGTH];
static float m_HelpMessageDisplayTime;
- static int32 SpriteBrightness;
- static bool m_Wants_To_Draw_Hud;
- static bool m_Wants_To_Draw_3dMarkers;
- static wchar *m_pVehicleName;
+ static bool m_HelpMessageDisplayForever;
+ static bool m_HelpMessageQuick;
+ static uint32 m_ZoneState;
+ static int32 m_ZoneFadeTimer;
+ static uint32 m_ZoneNameTimer;
+ static wchar *m_pZoneName;
+ static wchar *m_pLastZoneName;
+ static wchar *m_ZoneToPrint;
+ static wchar *m_VehicleName;
static wchar *m_pLastVehicleName;
- static uint32 m_VehicleNameTimer;
- static int32 m_VehicleFadeTimer;
- static uint32 m_VehicleState;
static wchar *m_pVehicleNameToPrint;
+ static uint32 m_VehicleState;
+ static int32 m_VehicleFadeTimer;
+ static uint32 m_VehicleNameTimer;
+ static wchar m_Message[256];
+ static wchar m_PagerMessage[256];
+ static bool m_Wants_To_Draw_Hud;
+ static bool m_Wants_To_Draw_3dMarkers;
+ static wchar m_BigMessage[6][128];
+ static int16 m_ItemToFlash;
+ static bool m_HideRadar;
+ static int32 m_ClockState;
+
+ // These aren't really in CHud
+ static float BigMessageInUse[6];
+ static float BigMessageAlpha[6];
+ static float BigMessageX[6];
+ static float OddJob2OffTimer;
+ static bool CounterOnLastFrame[NUMONSCREENCOUNTERS];
+ static float OddJob2XOffset;
+ static uint16 CounterFlashTimer[NUMONSCREENCOUNTERS];
+ static uint16 OddJob2Timer;
+ static bool TimerOnLastFrame;
+ static int16 OddJob2On;
+ static uint16 TimerFlashTimer;
+ static int16 PagerSoundPlayed;
+ static int32 SpriteBrightness;
+ static float PagerXOffset;
+ 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;
+ static uint32 m_LastWeapon;
+ static uint32 m_LastTimeEnergyLost;
+
public:
- static void Initialise();
- static void Shutdown();
- static void ReInitialise();
- static void GetRidOfAllHudMessages();
- static void SetZoneName(wchar *name);
- static void SetHelpMessage(wchar *message, bool quick);
- static void SetVehicleName(wchar *name);
static void Draw();
static void DrawAfterFade();
- static void SetMessage(wchar *message);
+ static void GetRidOfAllHudMessages();
+#ifdef RELOADABLES
+ static void ReloadTXD();
+#endif
+ static void Initialise();
+ static void ReInitialise();
static void SetBigMessage(wchar *message, uint16 style);
+ static void SetHelpMessage(wchar *message, bool quick, bool displayForever = false);
+ static bool IsHelpMessageBeingDisplayed(void);
+ static void SetMessage(wchar *message);
static void SetPagerMessage(wchar *message);
+ static void SetVehicleName(wchar *name);
+ static void SetZoneName(wchar *name);
+ static void Shutdown();
+ static float DrawFadeState(DRAW_FADE_STATE, int);
+ static void ResetWastedText(void);
};
diff --git a/src/renderer/MBlur.cpp b/src/renderer/MBlur.cpp
index 8e5fba2a..cc8270ce 100644
--- a/src/renderer/MBlur.cpp
+++ b/src/renderer/MBlur.cpp
@@ -7,8 +7,14 @@
#endif
#include "main.h"
+#include "General.h"
#include "RwHelper.h"
#include "Camera.h"
+#include "Timecycle.h"
+#include "Particle.h"
+#include "Timer.h"
+#include "Hud.h"
+#include "Frontend.h"
#include "MBlur.h"
#include "postfx.h"
@@ -18,8 +24,12 @@ RwRaster *CMBlur::pFrontBuffer;
bool CMBlur::ms_bJustInitialised;
bool CMBlur::ms_bScaledBlur;
bool CMBlur::BlurOn;
+float CMBlur::Drunkness;
+
+int32 CMBlur::pBufVertCount;
static RwIm2DVertex Vertex[4];
+static RwIm2DVertex Vertex2[4];
static RwImVertexIndex Index[6] = { 0, 1, 2, 0, 2, 3 };
#ifndef LIBRW
@@ -201,6 +211,121 @@ CMBlur::CreateImmediateModeData(RwCamera *cam, RwRect *rect)
RwIm2DVertexSetU(&Vertex[3], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam));
RwIm2DVertexSetV(&Vertex[3], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam));
RwIm2DVertexSetIntRGBA(&Vertex[3], 255, 255, 255, 255);
+
+
+ RwIm2DVertexSetScreenX(&Vertex2[0], zero + 2.0f);
+ RwIm2DVertexSetScreenY(&Vertex2[0], zero + 2.0f);
+ RwIm2DVertexSetScreenZ(&Vertex2[0], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&Vertex2[0], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&Vertex2[0], 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetU(&Vertex2[0], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetV(&Vertex2[0], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetIntRGBA(&Vertex2[0], 255, 255, 255, 255);
+
+ RwIm2DVertexSetScreenX(&Vertex2[1], 2.0f);
+ RwIm2DVertexSetScreenY(&Vertex2[1], ymax + 2.0f);
+ RwIm2DVertexSetScreenZ(&Vertex2[1], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&Vertex2[1], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&Vertex2[1], 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetU(&Vertex2[1], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetV(&Vertex2[1], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetIntRGBA(&Vertex2[1], 255, 255, 255, 255);
+
+ RwIm2DVertexSetScreenX(&Vertex2[2], xmax + 2.0f);
+ RwIm2DVertexSetScreenY(&Vertex2[2], ymax + 2.0f);
+ RwIm2DVertexSetScreenZ(&Vertex2[2], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&Vertex2[2], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&Vertex2[2], 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetU(&Vertex2[2], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetV(&Vertex2[2], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetIntRGBA(&Vertex2[2], 255, 255, 255, 255);
+
+ RwIm2DVertexSetScreenX(&Vertex2[3], xmax + 2.0f);
+ RwIm2DVertexSetScreenY(&Vertex2[3], zero + 2.0f);
+ RwIm2DVertexSetScreenZ(&Vertex2[3], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&Vertex2[3], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&Vertex2[3], 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetU(&Vertex2[3], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetV(&Vertex2[3], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetIntRGBA(&Vertex2[3], 255, 255, 255, 255);
+}
+
+void
+CMBlur::CreateImmediateModeData(RwCamera *cam, RwRect *rect, RwIm2DVertex *verts, RwRGBA color, float u1Off, float v1Off, float u2Off, float v2Off, float z, int fullTexture)
+{
+ float x1 = rect->x;
+ float y1 = rect->y;
+ float x2 = rect->w;
+ float y2 = rect->h;
+
+ float u1, v1, u2, v2;
+ if(fullTexture){
+ u1 = 0.0f;
+ v1 = 0.0f;
+ u2 = 1.0f;
+ v2 = 1.0f;
+ }else{
+ if(RwRasterGetDepth(RwCameraGetRaster(cam)) == 16){
+ x1 += HALFPX;
+ y1 += HALFPX;
+ x2 += HALFPX;
+ y2 += HALFPX;
+ }else{
+ x1 -= HALFPX;
+ y1 -= HALFPX;
+ x2 -= HALFPX;
+ y2 -= HALFPX;
+ }
+
+ int32 width = Pow(2.0f, int32(log2(RwRasterGetWidth (RwCameraGetRaster(cam))))+1);
+ int32 height = Pow(2.0f, int32(log2(RwRasterGetHeight(RwCameraGetRaster(cam))))+1);
+ u1 = x1/width + u1Off;
+ v1 = y1/height + v1Off;
+ u2 = x2/width + u2Off;
+ v2 = y2/height + v2Off;
+ u1 = Clamp(u1, 0.0f, 1.0f);
+ v1 = Clamp(v1, 0.0f, 1.0f);
+ u2 = Clamp(u2, 0.0f, 1.0f);
+ v2 = Clamp(v2, 0.0f, 1.0f);
+ }
+
+ float recipz = 1.0f/z;
+ // TODO: CameraZ is wrong, what should we do?
+ RwIm2DVertexSetScreenX(&verts[0], x1);
+ RwIm2DVertexSetScreenY(&verts[0], y1);
+ RwIm2DVertexSetScreenZ(&verts[0], z);
+ RwIm2DVertexSetCameraZ(&verts[0], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&verts[0], recipz);
+ RwIm2DVertexSetU(&verts[0], u1, recipz);
+ RwIm2DVertexSetV(&verts[0], v1, recipz);
+ RwIm2DVertexSetIntRGBA(&verts[0], color.red, color.green, color.blue, color.alpha);
+
+ RwIm2DVertexSetScreenX(&verts[1], x1);
+ RwIm2DVertexSetScreenY(&verts[1], y2);
+ RwIm2DVertexSetScreenZ(&verts[1], z);
+ RwIm2DVertexSetCameraZ(&verts[1], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&verts[1], recipz);
+ RwIm2DVertexSetU(&verts[1], u1, recipz);
+ RwIm2DVertexSetV(&verts[1], v2, recipz);
+ RwIm2DVertexSetIntRGBA(&verts[1], color.red, color.green, color.blue, color.alpha);
+
+ RwIm2DVertexSetScreenX(&verts[2], x2);
+ RwIm2DVertexSetScreenY(&verts[2], y2);
+ RwIm2DVertexSetScreenZ(&verts[2], z);
+ RwIm2DVertexSetCameraZ(&verts[2], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&verts[2], recipz);
+ RwIm2DVertexSetU(&verts[2], u2, recipz);
+ RwIm2DVertexSetV(&verts[2], v2, recipz);
+ RwIm2DVertexSetIntRGBA(&verts[2], color.red, color.green, color.blue, color.alpha);
+
+ RwIm2DVertexSetScreenX(&verts[3], x2);
+ RwIm2DVertexSetScreenY(&verts[3], y1);
+ RwIm2DVertexSetScreenZ(&verts[3], z);
+ RwIm2DVertexSetCameraZ(&verts[3], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&verts[3], recipz);
+ RwIm2DVertexSetU(&verts[3], u2, recipz);
+ RwIm2DVertexSetV(&verts[3], v1, recipz);
+ RwIm2DVertexSetIntRGBA(&verts[3], color.red, color.green, color.blue, color.alpha);
}
void
@@ -215,24 +340,25 @@ CMBlur::MotionBlurRender(RwCamera *cam, uint32 red, uint32 green, uint32 blue, u
if( pFrontBuffer )
OverlayRender(cam, pFrontBuffer, color, type, bluralpha);
#else
+ if(ms_bJustInitialised)
+ ms_bJustInitialised = false;
+ else
+ OverlayRender(cam, pFrontBuffer, color, type, bluralpha);
if(BlurOn){
- if(pFrontBuffer){
- if(ms_bJustInitialised)
- ms_bJustInitialised = false;
- else
- OverlayRender(cam, pFrontBuffer, color, type, bluralpha);
- }
RwRasterPushContext(pFrontBuffer);
RwRasterRenderFast(RwCameraGetRaster(cam), 0, 0);
RwRasterPopContext();
- }else{
- OverlayRender(cam, nil, color, type, bluralpha);
}
#endif
POP_RENDERGROUP();
#endif
}
+static uint8 DrunkBlurRed = 128;
+static uint8 DrunkBlurGreen = 128;
+static uint8 DrunkBlurBlue = 128;
+static int32 DrunkBlurIncrement = 1;
+
void
CMBlur::OverlayRender(RwCamera *cam, RwRaster *raster, RwRGBA color, int32 type, int32 bluralpha)
{
@@ -280,41 +406,105 @@ CMBlur::OverlayRender(RwCamera *cam, RwRaster *raster, RwRGBA color, int32 type,
}
if(!BlurOn){
- r = Min(r*0.6f, 255.0f);
- g = Min(g*0.6f, 255.0f);
- b = Min(b*0.6f, 255.0f);
- if(type != MOTION_BLUR_SNIPER)
- a = Min(a*0.6f, 255.0f);
- // game clamps to 255 here, but why?
+ // gta clamps these to 255 (probably a macro or inlined function)
+ int ovR = r * 0.6f;
+ int ovG = g * 0.6f;
+ int ovB = b * 0.6f;
+ int ovA = type == MOTION_BLUR_SNIPER ? a : a*0.6f;
+ RwIm2DVertexSetIntRGBA(&Vertex[0], ovR, ovG, ovB, ovA);
+ RwIm2DVertexSetIntRGBA(&Vertex[1], ovR, ovG, ovB, ovA);
+ RwIm2DVertexSetIntRGBA(&Vertex[2], ovR, ovG, ovB, ovA);
+ RwIm2DVertexSetIntRGBA(&Vertex[3], ovR, ovG, ovB, ovA);
+ }else{
+ RwIm2DVertexSetIntRGBA(&Vertex2[0], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex[0], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex2[1], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex[1], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex2[2], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex[2], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex2[3], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex[3], r, g, b, a);
}
- RwIm2DVertexSetIntRGBA(&Vertex[0], r, g, b, a);
- RwIm2DVertexSetIntRGBA(&Vertex[1], r, g, b, a);
- RwIm2DVertexSetIntRGBA(&Vertex[2], r, g, b, a);
- RwIm2DVertexSetIntRGBA(&Vertex[3], r, g, b, a);
RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERNEAREST);
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
- RwRenderStateSet(rwRENDERSTATETEXTURERASTER, BlurOn ? raster : nil);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, raster);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
- RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
- RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
- RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, Vertex, 4, Index, 6);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
+
+ if(BlurOn){
+ if(type == MOTION_BLUR_SNIPER){
+ RwIm2DVertexSetIntRGBA(&Vertex2[0], r, g, b, 80);
+ RwIm2DVertexSetIntRGBA(&Vertex2[1], r, g, b, 80);
+ RwIm2DVertexSetIntRGBA(&Vertex2[2], r, g, b, 80);
+ RwIm2DVertexSetIntRGBA(&Vertex2[3], r, g, b, 80);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ pBufVertCount = 0;
+ }else{
+ RwIm2DVertexSetIntRGBA(&Vertex2[0], r*2, g*2, b*2, 30);
+ RwIm2DVertexSetIntRGBA(&Vertex2[1], r*2, g*2, b*2, 30);
+ RwIm2DVertexSetIntRGBA(&Vertex2[2], r*2, g*2, b*2, 30);
+ RwIm2DVertexSetIntRGBA(&Vertex2[3], r*2, g*2, b*2, 30);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, Vertex2, 4, Index, 6);
- a = bluralpha/2;
- if(a < 30)
- a = 30;
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
+
+ RwIm2DVertexSetIntRGBA(&Vertex2[0], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex[0], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex2[1], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex[1], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex2[2], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex[2], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex2[3], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex[3], r, g, b, a);
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, Vertex, 4, Index, 6);
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, Vertex2, 4, Index, 6);
+ }
+ }
- if(BlurOn && a != 0){ // the second condition should always be true
- RwIm2DVertexSetIntRGBA(&Vertex[0], 255, 255, 255, a);
- RwIm2DVertexSetIntRGBA(&Vertex[1], 255, 255, 255, a);
- RwIm2DVertexSetIntRGBA(&Vertex[2], 255, 255, 255, a);
- RwIm2DVertexSetIntRGBA(&Vertex[3], 255, 255, 255, a);
+ int DrunkBlurAlpha = 175.0f * Drunkness;
+ if(DrunkBlurAlpha != 0){
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ if(BlurOn){
+ RwIm2DVertexSetIntRGBA(&Vertex[0], 255, 255, 255, DrunkBlurAlpha);
+ RwIm2DVertexSetIntRGBA(&Vertex[1], 255, 255, 255, DrunkBlurAlpha);
+ RwIm2DVertexSetIntRGBA(&Vertex[2], 255, 255, 255, DrunkBlurAlpha);
+ RwIm2DVertexSetIntRGBA(&Vertex[3], 255, 255, 255, DrunkBlurAlpha);
+ }else{
+ RwIm2DVertexSetIntRGBA(&Vertex[0], DrunkBlurRed, DrunkBlurGreen, DrunkBlurBlue, DrunkBlurAlpha);
+ RwIm2DVertexSetIntRGBA(&Vertex[1], DrunkBlurRed, DrunkBlurGreen, DrunkBlurBlue, DrunkBlurAlpha);
+ RwIm2DVertexSetIntRGBA(&Vertex[2], DrunkBlurRed, DrunkBlurGreen, DrunkBlurBlue, DrunkBlurAlpha);
+ RwIm2DVertexSetIntRGBA(&Vertex[3], DrunkBlurRed, DrunkBlurGreen, DrunkBlurBlue, DrunkBlurAlpha);
+ if(DrunkBlurIncrement){
+ if(DrunkBlurRed < 255) DrunkBlurRed++;
+ if(DrunkBlurGreen < 255) DrunkBlurGreen++;
+ if(DrunkBlurBlue < 255) DrunkBlurBlue++;
+ if(DrunkBlurRed == 255)
+ DrunkBlurIncrement = 0;
+ }else{
+ if(DrunkBlurRed > 128) DrunkBlurRed--;
+ if(DrunkBlurGreen > 128) DrunkBlurGreen--;
+ if(DrunkBlurBlue > 128) DrunkBlurBlue--;
+ if(DrunkBlurRed == 128)
+ DrunkBlurIncrement = 1;
+ }
+ }
RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, Vertex, 4, Index, 6);
}
+ if(type != MOTION_BLUR_SNIPER)
+ OverlayRenderFx(cam, pFrontBuffer);
+
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
@@ -323,3 +513,289 @@ CMBlur::OverlayRender(RwCamera *cam, RwRaster *raster, RwRGBA color, int32 type,
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
}
+
+void
+CMBlur::SetDrunkBlur(float drunkness)
+{
+ Drunkness = Clamp(drunkness, 0.0f, 1.0f);
+}
+
+void
+CMBlur::ClearDrunkBlur()
+{
+ Drunkness = 0.0f;
+ CTimer::SetTimeScale(1.0f);
+}
+
+#define NUM_RENDER_FX 64
+
+static RwRect fxRect[NUM_RENDER_FX];
+static FxType fxType[NUM_RENDER_FX];
+static float fxZ[NUM_RENDER_FX];
+
+bool
+CMBlur::PosInside(RwRect *rect, float x1, float y1, float x2, float y2)
+{
+ if((rect->x < x1 - 10.0f || rect->x > x2 + 10.0f || rect->y < y1 - 10.0f || rect->y > y2 + 10.0f) &&
+ (rect->w < x1 - 10.0f || rect->w > x2 + 10.0f || rect->h < y1 - 10.0f || rect->h > y2 + 10.0f) &&
+ (rect->x < x1 - 10.0f || rect->x > x2 + 10.0f || rect->h < y1 - 10.0f || rect->h > y2 + 10.0f) &&
+ (rect->w < x1 - 10.0f || rect->w > x2 + 10.0f || rect->y < y1 - 10.0f || rect->y > y2 + 10.0f))
+ return false;
+ return true;
+}
+
+bool
+CMBlur::AddRenderFx(RwCamera *cam, RwRect *rect, float z, FxType type)
+{
+ if(pBufVertCount >= NUM_RENDER_FX)
+ return false;
+
+ rect->x = Max(rect->x, 0);
+ rect->y = Max(rect->y, 0);
+ rect->w = Min(rect->w, SCREEN_WIDTH);
+ rect->h = Min(rect->h, SCREEN_HEIGHT);
+ if(rect->x >= rect->w || rect->y >= rect->h)
+ return false;
+
+ switch(type){
+ case FXTYPE_WATER1:
+ case FXTYPE_WATER2:
+ case FXTYPE_BLOOD1:
+ case FXTYPE_BLOOD2:
+ case FXTYPE_HEATHAZE: // code seems to be duplicated for this case
+ for(int i = 0; i < pBufVertCount; i++)
+ if(fxType[i] == type && PosInside(rect, fxRect[i].x-10.0f, fxRect[i].y-10.0f, fxRect[i].w+10.0f, fxRect[i].h+10.0f))
+ return false;
+ // TODO: fix aspect ratio scaling
+ // radar
+ if(PosInside(rect, 40.0f, SCREEN_SCALE_FROM_BOTTOM(116.0f), 40.0f + SCREEN_SCALE_X(94.0f), SCREEN_SCALE_FROM_BOTTOM(116.0f - 76.0f)))
+ return false;
+ // HUD
+ if(PosInside(rect, 400.0f, 0.0f, SCREEN_WIDTH, 90.0f))
+ return false;
+ // vehicle name
+ if(CHud::m_VehicleState != 0 && PosInside(rect, SCREEN_WIDTH/2, 350.0f, SCREEN_WIDTH, SCREEN_HEIGHT))
+ return false;
+ // zone name
+ if(CHud::m_ZoneState != 0 && PosInside(rect, SCREEN_WIDTH/2, 350.0f, SCREEN_WIDTH, SCREEN_HEIGHT))
+ return false;
+ break;
+ }
+
+ fxRect[pBufVertCount] = *rect;
+ fxZ[pBufVertCount] = z;
+ fxType[pBufVertCount] = type;
+ pBufVertCount++;
+
+ return true;
+}
+
+void
+CMBlur::OverlayRenderFx(RwCamera *cam, RwRaster *frontBuf)
+{
+ bool drawWaterDrops = false;
+ RwIm2DVertex verts[4];
+ int red = (0.75f*CTimeCycle::GetDirectionalRed() + CTimeCycle::GetAmbientRed())*0.55f * 255;
+ int green = (0.75f*CTimeCycle::GetDirectionalGreen() + CTimeCycle::GetAmbientGreen())*0.55f * 255;
+ int blue = (0.75f*CTimeCycle::GetDirectionalBlue() + CTimeCycle::GetAmbientBlue())*0.55f * 255;
+ red = Clamp(red, 0, 255);
+ green = Clamp(green, 0, 255);
+ blue = Clamp(blue, 0, 255);
+
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+
+#ifdef LIBRW
+ rw::SetRenderState(rw::STENCILENABLE, TRUE);
+#else
+ RwD3D8SetRenderState(D3DRS_STENCILENABLE, TRUE);
+#endif
+
+ for(int i = 0; i < pBufVertCount; i++)
+ switch(fxType[i]){
+ case FXTYPE_WATER1:
+ case FXTYPE_WATER2:
+ case FXTYPE_BLOOD1:
+ case FXTYPE_BLOOD2: {
+ drawWaterDrops = true;
+ int32 width = Pow(2.0f, int32(log2(RwRasterGetWidth (RwCameraGetRaster(cam))))+1);
+ int32 height = Pow(2.0f, int32(log2(RwRasterGetHeight(RwCameraGetRaster(cam))))+1);
+
+ float u1Off = (fxRect[i].w - fxRect[i].x)/width;
+ float u2Off = u1Off - (fxRect[i].w - fxRect[i].x + 0.5f)*0.66f/width;
+ float halfHeight = (fxRect[i].h - fxRect[i].y + 0.5f)*0.25f/height;
+
+ if(RwRasterGetDepth(RwCameraGetRaster(cam)) == 16){
+ if(fxType[i] == FXTYPE_BLOOD1 || fxType[i] == FXTYPE_BLOOD2)
+ CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(255, 0, 0, 128), 0.0f, 0.0f, 0.0f, 0.0f, fxZ[i], true);
+ else
+ CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(32, 32, 32, 225), 0.0f, 0.0f, 0.0f, 0.0f, fxZ[i], true);
+ }else{
+ CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(32, 32, 32, 225), 0.0f, 0.0f, 0.0f, 0.0f, fxZ[i], true);
+ }
+
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpDotRaster);
+#ifdef LIBRW
+ rw::SetRenderState(rw::STENCILFUNCTION, rw::STENCILALWAYS);
+ rw::SetRenderState(rw::STENCILFUNCTIONREF, 1);
+ rw::SetRenderState(rw::STENCILFUNCTIONMASK, 0xFFFFFFFF);
+ rw::SetRenderState(rw::STENCILFUNCTIONWRITEMASK, 0xFFFFFFFF);
+ rw::SetRenderState(rw::STENCILZFAIL, rw::STENCILKEEP);
+ rw::SetRenderState(rw::STENCILFAIL, rw::STENCILKEEP);
+ rw::SetRenderState(rw::STENCILPASS, rw::STENCILREPLACE);
+#else
+ RwD3D8SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
+ RwD3D8SetRenderState(D3DRS_STENCILREF, 1);
+ RwD3D8SetRenderState(D3DRS_STENCILMASK, 0xFFFFFFFF);
+ RwD3D8SetRenderState(D3DRS_STENCILWRITEMASK, 0xFFFFFFFF);
+ RwD3D8SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
+ RwD3D8SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
+ RwD3D8SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
+#endif
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, verts, 4, Index, 6);
+
+ if(RwRasterGetDepth(RwCameraGetRaster(cam)) != 16){
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, frontBuf);
+#ifdef LIBRW
+ rw::SetRenderState(rw::STENCILFUNCTION, rw::STENCILEQUAL);
+ rw::SetRenderState(rw::STENCILPASS, rw::STENCILKEEP);
+#else
+ RwD3D8SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL);
+ RwD3D8SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
+#endif
+ if(BlurOn){
+ if(fxType[i] == FXTYPE_BLOOD1 || fxType[i] == FXTYPE_BLOOD2)
+ CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(255, 0, 0, 255), u1Off, 0.0f+halfHeight, u2Off, 0.0f-halfHeight, fxZ[i], false);
+ else
+ CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(225, 225, 225, 160), u1Off, 0.0f+halfHeight, u2Off, 0.0f-halfHeight, fxZ[i], false);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDDESTALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVDESTALPHA);
+ }else{
+ if(fxType[i] == FXTYPE_BLOOD1 || fxType[i] == FXTYPE_BLOOD2)
+ CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(255, 0, 0, 128), u1Off, 0.0f+halfHeight, u2Off, 0.0f-halfHeight, fxZ[i], false);
+ else
+ CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(128, 128, 128, 32), u1Off, 0.0f+halfHeight, u2Off, 0.0f-halfHeight, fxZ[i], false);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ }
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, verts, 4, Index, 6);
+ }
+ break;
+ }
+ case FXTYPE_SPLASH1:
+ case FXTYPE_SPLASH2:
+ case FXTYPE_SPLASH3:
+ drawWaterDrops = true;
+ break;
+
+ case FXTYPE_HEATHAZE:
+ if(TheCamera.GetScreenFadeStatus() == FADE_0 && frontBuf){
+ int alpha = FrontEndMenuManager.m_PrefsBrightness > 255 ?
+ FrontEndMenuManager.m_PrefsBrightness - 90 :
+ FrontEndMenuManager.m_PrefsBrightness - 130;
+ alpha = Clamp(alpha, 16, 200)/2;
+
+ CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(0, 0, 0, alpha), 0.0f, 0.0f, 0.0f, 0.0f, fxZ[i], true);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpHeatHazeRaster);
+#ifdef LIBRW
+ rw::SetRenderState(rw::STENCILFUNCTION, rw::STENCILALWAYS);
+ rw::SetRenderState(rw::STENCILFUNCTIONREF, 1);
+ rw::SetRenderState(rw::STENCILFUNCTIONMASK, 0xFFFFFFFF);
+ rw::SetRenderState(rw::STENCILFUNCTIONWRITEMASK, 0xFFFFFFFF);
+ rw::SetRenderState(rw::STENCILZFAIL, rw::STENCILKEEP);
+ rw::SetRenderState(rw::STENCILFAIL, rw::STENCILKEEP);
+ rw::SetRenderState(rw::STENCILPASS, rw::STENCILREPLACE);
+#else
+ RwD3D8SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
+ RwD3D8SetRenderState(D3DRS_STENCILREF, 1);
+ RwD3D8SetRenderState(D3DRS_STENCILMASK, 0xFFFFFFFF);
+ RwD3D8SetRenderState(D3DRS_STENCILWRITEMASK, 0xFFFFFFFF);
+ RwD3D8SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
+ RwD3D8SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
+ RwD3D8SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
+#endif
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, verts, 4, Index, 6);
+
+ CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(255, 255, 255, alpha),
+ CGeneral::GetRandomNumberInRange(-0.002f, 0.002f),
+ CGeneral::GetRandomNumberInRange(-0.002f, 0.002f),
+ CGeneral::GetRandomNumberInRange(-0.002f, 0.002f),
+ CGeneral::GetRandomNumberInRange(-0.002f, 0.002f),
+ fxZ[i], false);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, frontBuf);
+#ifdef LIBRW
+ rw::SetRenderState(rw::STENCILFUNCTION, rw::STENCILEQUAL);
+ rw::SetRenderState(rw::STENCILPASS, rw::STENCILKEEP);
+#else
+ RwD3D8SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL);
+ RwD3D8SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
+#endif
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, verts, 4, Index, 6);
+ }
+ break;
+ }
+#ifdef LIBRW
+ rw::SetRenderState(rw::STENCILENABLE, FALSE);
+#else
+ RwD3D8SetRenderState(D3DRS_STENCILENABLE, FALSE);
+#endif
+
+ if(drawWaterDrops){
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
+
+ // Draw drops
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpRainDripRaster[0]);
+ for(int i = 0; i < pBufVertCount; i++)
+ if(fxType[i] == FXTYPE_WATER1 || fxType[i] == FXTYPE_BLOOD1){
+ CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(red, green, blue, fxType[i] == FXTYPE_BLOOD1 ? 255 : 192),
+ 0.0f, 0.0f, 0.0f, 0.0f, fxZ[i], true);
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, verts, 4, Index, 6);
+ }
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpRainDripRaster[1]);
+ for(int i = 0; i < pBufVertCount; i++)
+ if(fxType[i] == FXTYPE_WATER2 || fxType[i] == FXTYPE_BLOOD2){
+ CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(red, green, blue, fxType[i] == FXTYPE_BLOOD2 ? 255 : 192),
+ 0.0f, 0.0f, 0.0f, 0.0f, fxZ[i], true);
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, verts, 4, Index, 6);
+ }
+
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCarSplashRaster[0]);
+ for(int i = 0; i < pBufVertCount; i++)
+ if(fxType[i] == FXTYPE_SPLASH1 || fxType[i] == FXTYPE_SPLASH2 || fxType[i] == FXTYPE_SPLASH3){
+ CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(200, 200, 200, 255),
+ 0.0f, 0.0f, 0.0f, 0.0f, fxZ[i], true);
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, verts, 4, Index, 6);
+ }
+
+ // Darken the water drops
+ int alpha = 192*0.5f;
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpRainDripDarkRaster[0]);
+ for(int i = 0; i < pBufVertCount; i++)
+ if(fxType[i] == FXTYPE_WATER1){
+ CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(red, green, blue, alpha),
+ 0.0f, 0.0f, 0.0f, 0.0f, fxZ[i], true);
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, verts, 4, Index, 6);
+ }
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpRainDripDarkRaster[1]);
+ for(int i = 0; i < pBufVertCount; i++)
+ if(fxType[i] == FXTYPE_WATER2){
+ CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(red, green, blue, alpha),
+ 0.0f, 0.0f, 0.0f, 0.0f, fxZ[i], true);
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, verts, 4, Index, 6);
+ }
+ }
+
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
+ pBufVertCount = 0;
+}
diff --git a/src/renderer/MBlur.h b/src/renderer/MBlur.h
index e2e5d38c..3dc53082 100644
--- a/src/renderer/MBlur.h
+++ b/src/renderer/MBlur.h
@@ -1,5 +1,17 @@
#pragma once
+enum FxType
+{
+ FXTYPE_WATER1,
+ FXTYPE_WATER2,
+ FXTYPE_BLOOD1,
+ FXTYPE_BLOOD2,
+ FXTYPE_HEATHAZE,
+ FXTYPE_SPLASH1,
+ FXTYPE_SPLASH2,
+ FXTYPE_SPLASH3
+};
+
class CMBlur
{
public:
@@ -7,11 +19,21 @@ public:
static bool ms_bJustInitialised;
static bool ms_bScaledBlur;
static bool BlurOn;
+ static float Drunkness;
+
+ static int32 pBufVertCount;
public:
static RwBool MotionBlurOpen(RwCamera *cam);
static RwBool MotionBlurClose(void);
static void CreateImmediateModeData(RwCamera *cam, RwRect *rect);
+ static void CreateImmediateModeData(RwCamera *cam, RwRect *rect, RwIm2DVertex *verts, RwRGBA color, float u1Off, float v1Off, float u2Off, float v2Off, float z, int fullTexture);
static void MotionBlurRender(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 blur, int32 type, uint32 bluralpha);
static void OverlayRender(RwCamera *cam, RwRaster *raster, RwRGBA color, int32 type, int32 bluralpha);
+ static void SetDrunkBlur(float drunkness);
+ static void ClearDrunkBlur();
+
+ static bool PosInside(RwRect *rect, float x1, float y1, float x2, float y2);
+ static bool AddRenderFx(RwCamera *cam, RwRect *rect, float z, FxType type);
+ static void OverlayRenderFx(RwCamera *cam, RwRaster *frontBuf);
};
diff --git a/src/renderer/Occlusion.cpp b/src/renderer/Occlusion.cpp
new file mode 100644
index 00000000..ec7101a6
--- /dev/null
+++ b/src/renderer/Occlusion.cpp
@@ -0,0 +1,530 @@
+#include "common.h"
+
+#include "main.h"
+#include "Entity.h"
+#include "Occlusion.h"
+#include "Game.h"
+#include "Camera.h"
+#include "Vector.h"
+#include "Draw.h"
+#include "Timer.h"
+#include "RwHelper.h"
+#include "VarConsole.h"
+
+int32 COcclusion::NumOccludersOnMap;
+int16 COcclusion::FarAwayList;
+int16 COcclusion::NearbyList;
+int16 COcclusion::ListWalkThroughFA;
+int16 COcclusion::PreviousListWalkThroughFA;
+int16 COcclusion::NumActiveOccluders;
+COccluder COcclusion::aOccluders[NUMOCCLUSIONVOLUMES];
+CActiveOccluder COcclusion::aActiveOccluders[NUMACTIVEOCCLUDERS];
+
+CVector gCenterOnScreen;
+
+float gMinYInOccluder;
+float gMinXInOccluder;
+float gMaxYInOccluder;
+float gMaxXInOccluder;
+
+bool gOccluderCoorsValid[8];
+CVector gOccluderCoorsOnScreen[8];
+CVector gOccluderCoors[8];
+
+#ifndef MASTER
+bool bDispayOccDebugStuff; // disPAY, yeah
+#endif
+
+void
+COcclusion::Init(void)
+{
+ NumOccludersOnMap = 0;
+#ifndef MASTER
+ VarConsole.Add("Occlusion debug", &bDispayOccDebugStuff, true);
+#endif
+ 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/360.0f * UINT16_MAX;
+ aOccluders[NumOccludersOnMap].listIndex = FarAwayList;
+ FarAwayList = NumOccludersOnMap++;
+}
+
+bool
+COccluder::NearCamera() {
+ return (TheCamera.GetPosition() - CVector(x, y, z)).Magnitude() - (Max(width, length) / 2.0f) < 250.0f;
+}
+
+bool
+DoesInfiniteLineCrossFiniteLine(float p1X, float p1Y, float p2X, float p2Y, float lineX, float lineY, float lineDX, float lineDY)
+{
+ float side1 = (p1X - lineX) * lineDY - (p1Y - lineY) * lineDX;
+ float side2 = (p2X - lineX) * lineDY - (p2Y - lineY) * lineDX;
+ return side1 * side2 < 0.0f; // if points lie on opposite sides of the infinte line, the line between them crosses it
+}
+
+bool DoesInfiniteLineTouchScreen(float lineX, float lineY, float lineDX, float lineDY) {
+ if (lineX > 0.0f && lineY > 0.0f && SCREEN_WIDTH > lineX && SCREEN_HEIGHT > lineY)
+ return true;
+
+ return (DoesInfiniteLineCrossFiniteLine(0.0f, 0.0f, SCREEN_WIDTH, 0.0f, lineX, lineY, lineDX, lineDY) ||
+ DoesInfiniteLineCrossFiniteLine(0.0f, 0.0f, 0.0f, SCREEN_HEIGHT, lineX, lineY, lineDX, lineDY) ||
+ DoesInfiniteLineCrossFiniteLine(SCREEN_WIDTH, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, lineX, lineY, lineDX, lineDY) ||
+ DoesInfiniteLineCrossFiniteLine(0.0f, SCREEN_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT, lineX, lineY, lineDX, lineDY));
+}
+
+bool IsPointInsideLine(float lineX, float lineY, float lineDX, float lineDY, float pX, float pY, float area = 0.0f) {
+ return (pX - lineX) * lineDY - (pY - lineY) * lineDX >= area;
+}
+
+bool CalcScreenCoors(CVector const &in, CVector *out, float *outw, float *outh) {
+ *out = TheCamera.m_viewMatrix * in;
+
+ if (out->z <= 1.0f) return false;
+
+ float recip = 1.0f / out->z;
+ out->x *= SCREEN_WIDTH * recip;
+ out->y *= SCREEN_HEIGHT * recip;
+
+ float fovScale = DefaultFOV / CDraw::GetFOV();
+
+ *outw = fovScale * recip * SCREEN_WIDTH;
+ *outh = fovScale * recip * SCREEN_HEIGHT;
+
+ return true;
+}
+
+bool CalcScreenCoors(CVector const &in, CVector *out) {
+ *out = TheCamera.m_viewMatrix * in;
+
+ if (out->z <= 1.0f) return false;
+
+ float recip = 1.0f / out->z;
+ out->x *= SCREEN_WIDTH * recip;
+ out->y *= SCREEN_HEIGHT * recip;
+
+ return true;
+}
+
+bool
+COccluder::ProcessLineSegment(int corner1, int corner2, CActiveOccluder *occl) {
+ if (!gOccluderCoorsValid[corner1] && !gOccluderCoorsValid[corner2])
+ return false;
+
+ float x1, y1, x2, y2;
+
+ CVector p1, p2;
+ if (!gOccluderCoorsValid[corner1]) {
+ float clipDist1 = Abs((TheCamera.m_viewMatrix * gOccluderCoors[corner1]).z - 1.1f);
+ float clipDist2 = Abs((TheCamera.m_viewMatrix * gOccluderCoors[corner2]).z - 1.1f);
+ float ratio = clipDist2 / (clipDist1 + clipDist2);
+ CVector clippedCoors = (1.0f - ratio) * gOccluderCoors[corner2] + ratio * gOccluderCoors[corner1];
+
+ if (!CalcScreenCoors(clippedCoors, &p1, &x1, &y1))
+ return true;
+ }
+ else {
+ p1 = gOccluderCoorsOnScreen[corner1];
+ }
+
+ if (!gOccluderCoorsValid[corner2]) {
+ float clipDist1 = Abs((TheCamera.m_viewMatrix * gOccluderCoors[corner1]).z - 1.1f);
+ float clipDist2 = Abs((TheCamera.m_viewMatrix * gOccluderCoors[corner2]).z - 1.1f);
+ float ratio = clipDist1 / (clipDist1 + clipDist2);
+ CVector clippedCoors = (1.0f - ratio) * gOccluderCoors[corner2] + ratio * gOccluderCoors[corner1];
+
+ if (!CalcScreenCoors(clippedCoors, &p2, &x2, &y2))
+ return true;
+ }
+ else {
+ p2 = gOccluderCoorsOnScreen[corner2];
+ }
+
+ gMinXInOccluder = Min(Min(gMinXInOccluder, p1.x), p2.x);
+ gMaxXInOccluder = Max(Max(gMaxXInOccluder, p1.x), p2.x);
+ gMinYInOccluder = Min(Min(gMinYInOccluder, p1.y), p2.y);
+ gMaxYInOccluder = Max(Max(gMaxYInOccluder, p1.y), p2.y);
+
+ CVector2D origin = p1;
+ CVector2D direction = p2 - p1;
+
+ // Make sure lines are counter-clockwise around center
+ if (!IsPointInsideLine(origin.x, origin.y, direction.x, direction.y, gCenterOnScreen.x, gCenterOnScreen.y, 0.0f)) {
+ origin += direction;
+ direction *= -1.0f;
+ }
+
+ float magnitude = direction.Magnitude();
+
+ occl->lines[occl->linesCount].origin = origin;
+ occl->lines[occl->linesCount].direction = direction / magnitude;
+ occl->lines[occl->linesCount].length = magnitude;
+
+ if (!DoesInfiniteLineTouchScreen(origin.x, origin.y, direction.x, direction.y))
+ return !IsPointInsideLine(origin.x, origin.y, direction.x, direction.y, SCREEN_WIDTH / 2.0f, SCREEN_HEIGHT / 2.0f, 0.0f);
+
+ occl->linesCount++;
+
+ return false;
+}
+
+bool
+COccluder::ProcessOneOccluder(CActiveOccluder *occl) {
+ float outX, outY;
+
+ occl->linesCount = 0;
+ CVector pos(x, y, z);
+
+ if (!CalcScreenCoors(pos, &gCenterOnScreen, &outX, &outY) || gCenterOnScreen.z < -150.0f || gCenterOnScreen.z > 300.0f) {
+ return false;
+ }
+
+ occl->radius = Max(width, length) * 0.35f + gCenterOnScreen.z;
+
+ CVector vec[3];
+
+ vec[0].x = length / 2.0f * Sin(GetAngle());
+ vec[0].y = -length / 2.0f * Cos(GetAngle());
+ vec[0].z = 0.0f;
+
+ vec[1].x = width / 2.0f * Cos(GetAngle());
+ vec[1].y = width / 2.0f * Sin(GetAngle());
+ vec[1].z = 0.0f;
+
+ vec[2].x = 0.0f;
+ vec[2].y = 0.0f;
+ vec[2].z = height / 2.0f;
+
+ // Figure out if we see the front or back of a face
+ bool bFrontFace[6];
+ for (int i = 0; i < 3; i++) {
+ bFrontFace[i*2+0] = DotProduct((pos + vec[i] - TheCamera.GetPosition()), vec[i]) < 0.0f;
+ bFrontFace[i*2+1] = DotProduct((pos - vec[i] - TheCamera.GetPosition()), -vec[i]) < 0.0f;
+ }
+
+ //calculating vertices of a box
+ gOccluderCoors[0] = pos + vec[0] + vec[1] + vec[2];
+ gOccluderCoors[1] = pos - vec[0] + vec[1] + vec[2];
+ gOccluderCoors[2] = pos + vec[0] - vec[1] + vec[2];
+ gOccluderCoors[3] = pos - vec[0] - vec[1] + vec[2];
+ gOccluderCoors[4] = pos + vec[0] + vec[1] - vec[2];
+ gOccluderCoors[5] = pos - vec[0] + vec[1] - vec[2];
+ gOccluderCoors[6] = pos + vec[0] - vec[1] - vec[2];
+ gOccluderCoors[7] = pos - vec[0] - vec[1] - vec[2];
+
+ for(int i = 0; i < 8; i++)
+ gOccluderCoorsValid[i] = CalcScreenCoors(gOccluderCoors[i], &gOccluderCoorsOnScreen[i], &outX, &outY);
+
+ gMinYInOccluder = 999999.875f;
+ gMinXInOccluder = 999999.875f;
+ gMaxYInOccluder = -999999.875f;
+ gMaxXInOccluder = -999999.875f;
+
+ // Between two differently facing sides we see an edge, so process those
+ if (bFrontFace[2] != bFrontFace[0] && ProcessLineSegment(0, 4, occl))
+ return false;
+ if (bFrontFace[3] != bFrontFace[0] && ProcessLineSegment(2, 6, occl))
+ return false;
+ if (bFrontFace[4] != bFrontFace[0] && ProcessLineSegment(0, 2, occl))
+ return false;
+ if (bFrontFace[5] != bFrontFace[0] && ProcessLineSegment(4, 6, occl))
+ return false;
+ if (bFrontFace[2] != bFrontFace[1] && ProcessLineSegment(1, 5, occl))
+ return false;
+ if (bFrontFace[3] != bFrontFace[1] && ProcessLineSegment(3, 7, occl))
+ return false;
+ if (bFrontFace[4] != bFrontFace[1] && ProcessLineSegment(1, 3, occl))
+ return false;
+ if (bFrontFace[5] != bFrontFace[1] && ProcessLineSegment(5, 7, occl))
+ return false;
+ if (bFrontFace[4] != bFrontFace[2] && ProcessLineSegment(0, 1, occl))
+ return false;
+ if (bFrontFace[3] != bFrontFace[4] && ProcessLineSegment(2, 3, occl))
+ return false;
+ if (bFrontFace[5] != bFrontFace[3] && ProcessLineSegment(6, 7, occl))
+ return false;
+ if (bFrontFace[2] != bFrontFace[5] && ProcessLineSegment(4, 5, occl))
+ return false;
+
+ if (gMaxXInOccluder - gMinXInOccluder < SCREEN_WIDTH * 0.1f ||
+ gMaxYInOccluder - gMinYInOccluder < SCREEN_HEIGHT * 0.07f)
+ return false;
+
+ return true;
+}
+
+bool
+COcclusion::OccluderHidesBehind(CActiveOccluder *occl1, CActiveOccluder *occl2) {
+ for (int i = 0; i < occl1->linesCount; i++) {
+ for (int j = 0; j < occl2->linesCount; j++) {
+ if (!IsPointInsideLine(occl2->lines[j].origin.x, occl2->lines[j].origin.y, occl2->lines[j].direction.x,
+ occl2->lines[j].direction.y, occl1->lines[i].origin.x, occl1->lines[i].origin.y, 0.0f))
+ return false;
+
+
+ if (!IsPointInsideLine(occl2->lines[j].origin.x, occl2->lines[j].origin.y, occl2->lines[j].direction.x,
+ occl2->lines[j].direction.y, (occl1->lines[i].origin.x + occl1->lines[i].direction.x * occl1->lines[i].length),
+ (occl1->lines[i].origin.y + occl1->lines[i].direction.y * occl1->lines[i].length), 0.0f))
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void
+COcclusion::ProcessBeforeRendering(void)
+{
+ NumActiveOccluders = 0;
+
+#ifndef MASTER
+ if (gbModelViewer)
+ return;
+#endif
+
+ if (CGame::currArea != AREA_MAIN_MAP)
+ return;
+
+ if (ListWalkThroughFA == -1) {
+ PreviousListWalkThroughFA = -1;
+ ListWalkThroughFA = FarAwayList;
+ }
+
+ int i;
+ for (i = 0; i < 16 && ListWalkThroughFA != -1; i++) {
+ if (aOccluders[ListWalkThroughFA].NearCamera()) {
+ int prevListWalkThroughFA = ListWalkThroughFA;
+
+ if (PreviousListWalkThroughFA == -1) {
+ FarAwayList = aOccluders[ListWalkThroughFA].listIndex;
+ }
+ else {
+ aOccluders[PreviousListWalkThroughFA].listIndex = aOccluders[ListWalkThroughFA].listIndex;
+ }
+
+ int prevNearbyList = NearbyList;
+ ListWalkThroughFA = aOccluders[ListWalkThroughFA].listIndex;
+ NearbyList = prevListWalkThroughFA;
+ aOccluders[prevListWalkThroughFA].listIndex = prevNearbyList;
+ }
+ else {
+ PreviousListWalkThroughFA = ListWalkThroughFA;
+ ListWalkThroughFA = aOccluders[ListWalkThroughFA].listIndex;
+ }
+ }
+
+ int prevNearbyList = -1;
+ int tmpNearbyList = NearbyList;
+ int indexTmpNearbyList, storeTmpNearbyList, prevFarAwayList;
+ while (tmpNearbyList != -1)
+ {
+ if (NumActiveOccluders < NUMACTIVEOCCLUDERS && aOccluders[tmpNearbyList].ProcessOneOccluder(&aActiveOccluders[NumActiveOccluders]))
+ ++NumActiveOccluders;
+
+ indexTmpNearbyList = tmpNearbyList;
+ if (aOccluders[indexTmpNearbyList].NearCamera())
+ {
+ prevNearbyList = tmpNearbyList;
+ tmpNearbyList = aOccluders[indexTmpNearbyList].listIndex;
+
+ }
+ else
+ {
+ storeTmpNearbyList = tmpNearbyList;
+ if (prevNearbyList == -1) {
+ NearbyList = aOccluders[indexTmpNearbyList].listIndex;
+ }
+ else {
+ aOccluders[prevNearbyList].listIndex = aOccluders[indexTmpNearbyList].listIndex;
+ }
+ tmpNearbyList = aOccluders[indexTmpNearbyList].listIndex;
+ prevFarAwayList = FarAwayList;
+ FarAwayList = storeTmpNearbyList;
+ aOccluders[storeTmpNearbyList].listIndex = prevFarAwayList;
+ }
+ }
+
+ for (i = 0; i < NumActiveOccluders; i++) {
+ for (int j = 0; j < NumActiveOccluders; j++) {
+ if (i != j && aActiveOccluders[j].radius < aActiveOccluders[i].radius) {
+ if (OccluderHidesBehind(&aActiveOccluders[i], &aActiveOccluders[j])) {
+ for (int k = i; k < NumActiveOccluders - 1; k++) {
+ for (int l = 0; l < aActiveOccluders[k + 1].linesCount; l++)
+ aActiveOccluders[k].lines[l] = aActiveOccluders[k + 1].lines[l];
+ aActiveOccluders[k].linesCount = aActiveOccluders[k + 1].linesCount;
+ aActiveOccluders[k].radius = aActiveOccluders[k + 1].radius;
+ }
+ NumActiveOccluders--;
+ i--;
+ // Taken from Mobile!
+#ifdef FIX_BUGS
+ if (i == -1) {
+ i = 0;
+ }
+#endif
+ }
+ }
+ }
+ }
+}
+
+bool CActiveOccluder::IsPointWithinOcclusionArea(float pX, float pY, float area) {
+ for (int i = 0; i < linesCount; i++) {
+ if (!IsPointInsideLine(lines[i].origin.x, lines[i].origin.y, lines[i].direction.x, lines[i].direction.y, pX, pY, area))
+ return false;
+ }
+
+ return true;
+}
+
+bool COcclusion::IsAABoxOccluded(CVector pos, float width, float length, float height) {
+
+ CVector coors;
+ float outW, outH;
+
+ if (!NumActiveOccluders || !CalcScreenCoors(pos, &coors, &outW, &outH))
+ return false;
+
+ float side = CVector(width, length, height).Magnitude() / 4.0f;
+ float area = Max(outW, outH) * side;
+
+ CVector minCorner, maxCorner;
+
+ minCorner.x = pos.x - width / 2.0f;
+ minCorner.y = pos.y - length / 2.0f;
+ minCorner.z = pos.z - height / 2.0f;
+
+ maxCorner.x = pos.x + width / 2.0f;
+ maxCorner.y = pos.y + length / 2.0f;
+ maxCorner.z = pos.z + height / 2.0f;
+
+ for (int i = 0; i < NumActiveOccluders; i++) {
+ if (coors.z - (side * 0.85f) > aActiveOccluders[i].radius) {
+ if (aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, area))
+ return true;
+
+ if (aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, 0.0f)) {
+ if (CalcScreenCoors(minCorner, &coors) && !aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, 0.0f)) continue;
+ if (CalcScreenCoors(CVector(maxCorner.x, maxCorner.y, minCorner.z), &coors) && !aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, 0.0f)) continue;
+ if (CalcScreenCoors(CVector(maxCorner.x, minCorner.y, maxCorner.z), &coors) && !aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, 0.0f)) continue;
+ if (CalcScreenCoors(CVector(minCorner.x, maxCorner.y, maxCorner.z), &coors, &outW, &outH) && !aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, 0.0f)) continue;
+
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+bool COcclusion::IsPositionOccluded(CVector pos, float side) {
+
+ CVector coors;
+ float width, height;
+
+ if (!NumActiveOccluders || !CalcScreenCoors(pos, &coors, &width, &height))
+ return false;
+
+ float area = Max(width, height) * side;
+
+ for (int i = 0; i < NumActiveOccluders; i++) {
+ if (coors.z - (side * 0.85f) > aActiveOccluders[i].radius)
+ if (aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, area))
+ return true;
+ }
+
+ return false;
+}
+
+#ifndef MASTER
+#include "Lines.h"
+
+RwIm2DVertex vertexbufferT[2];
+
+void COcclusion::Render() {
+ if (!bDispayOccDebugStuff || !(CTimer::GetTimeInMilliseconds() & 0x200))
+ return;
+
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, FALSE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, FALSE);
+
+ float recipz = 1.0f/RwCameraGetNearClipPlane(Scene.camera);
+ for (int i = 0; i < NumActiveOccluders; i++) {
+ for (int j = 0; j < aActiveOccluders[i].linesCount; j++) {
+ RwIm2DVertexSetScreenX(&vertexbufferT[0], aActiveOccluders[i].lines[j].origin.x);
+ RwIm2DVertexSetScreenY(&vertexbufferT[0], aActiveOccluders[i].lines[j].origin.y);
+ RwIm2DVertexSetScreenZ(&vertexbufferT[0], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&vertexbufferT[0], RwCameraGetNearClipPlane(Scene.camera));
+ RwIm2DVertexSetRecipCameraZ(&vertexbufferT[0], recipz);
+
+ RwIm2DVertexSetScreenX(&vertexbufferT[1],
+ aActiveOccluders[i].lines[j].origin.x + aActiveOccluders[i].lines[j].direction.x * aActiveOccluders[i].lines[j].length);
+ RwIm2DVertexSetScreenY(&vertexbufferT[1],
+ aActiveOccluders[i].lines[j].origin.y + aActiveOccluders[i].lines[j].direction.y * aActiveOccluders[i].lines[j].length);
+ RwIm2DVertexSetScreenZ(&vertexbufferT[1], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&vertexbufferT[1], RwCameraGetNearClipPlane(Scene.camera));
+ RwIm2DVertexSetRecipCameraZ(&vertexbufferT[1], recipz);
+
+ RwIm2DVertexSetIntRGBA(&vertexbufferT[0], 255, 255, 0, 255);
+ RwIm2DVertexSetIntRGBA(&vertexbufferT[1], 255, 255, 0, 255);
+ RwIm2DRenderLine(vertexbufferT, 2, 0, 1);
+ }
+ }
+
+ DefinedState();
+}
+#endif
+
+bool CEntity::IsEntityOccluded(void) {
+
+ CVector coors;
+ float width, height;
+
+ if (COcclusion::NumActiveOccluders == 0 || !CalcScreenCoors(GetBoundCentre(), &coors, &width, &height))
+ return false;
+
+ float area = Max(width, height) * GetBoundRadius() * 0.9f;
+
+ for (int i = 0; i < COcclusion::NumActiveOccluders; i++) {
+ if (coors.z - (GetBoundRadius() * 0.85f) > COcclusion::aActiveOccluders[i].radius) {
+ if (COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, area)) {
+ return true;
+ }
+
+ if (COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, 0.0f)) {
+ CVector min = m_matrix * CModelInfo::GetColModel(m_modelIndex)->boundingBox.min;
+ CVector max = m_matrix * CModelInfo::GetColModel(m_modelIndex)->boundingBox.max;
+
+ if (CalcScreenCoors(min, &coors) && !COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, 0.0f)) continue;
+ if (CalcScreenCoors(CVector(max.x, max.y, min.z), &coors) && !COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, 0.0f)) continue;
+ if (CalcScreenCoors(CVector(max.x, min.y, max.z), &coors) && !COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, 0.0f)) continue;
+ if (CalcScreenCoors(CVector(min.x, max.y, max.z), &coors) && !COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, 0.0f)) continue;
+
+ return true;
+ }
+ }
+ }
+
+ return false;
+} \ No newline at end of file
diff --git a/src/renderer/Occlusion.h b/src/renderer/Occlusion.h
new file mode 100644
index 00000000..e0edef53
--- /dev/null
+++ b/src/renderer/Occlusion.h
@@ -0,0 +1,62 @@
+#pragma once
+
+struct ActiveOccluderLine {
+ CVector2D origin;
+ CVector2D direction;
+ float length;
+};
+
+class CActiveOccluder {
+
+public:
+ ActiveOccluderLine lines[6];
+ int32 linesCount;
+ float radius;
+
+ bool IsPointWithinOcclusionArea(float x, float y, float area);
+};
+
+class COccluder
+{
+public:
+ int16 length, width, height;
+ int16 x, y, z;
+ uint16 angle;
+ int16 listIndex;
+
+ bool NearCamera();
+ bool ProcessOneOccluder(CActiveOccluder *occl);
+ bool ProcessLineSegment(int corner1, int corner2, CActiveOccluder* occl);
+ float GetAngle(void) { return angle*TWOPI/UINT16_MAX; }
+};
+
+class COcclusion
+{
+public:
+ static int32 NumOccludersOnMap;
+ static int16 FarAwayList;
+ static int16 NearbyList;
+ static int16 ListWalkThroughFA;
+ static int16 PreviousListWalkThroughFA;
+ static int16 NumActiveOccluders;
+
+ static COccluder aOccluders[NUMOCCLUSIONVOLUMES];
+ static CActiveOccluder aActiveOccluders[NUMACTIVEOCCLUDERS];
+
+ 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);
+ static bool OccluderHidesBehind(CActiveOccluder *occl1, CActiveOccluder *occl2);
+ static bool IsAABoxOccluded(CVector pos, float width, float length, float height);
+ static bool IsPositionOccluded(CVector pos, float side);
+#ifndef MASTER
+ static void Render();
+#endif
+};
+
+bool CalcScreenCoors(CVector const &in, CVector *out, float *outw, float *outh);
+bool CalcScreenCoors(CVector const &in, CVector *out);
+
+#ifndef MASTER
+extern bool bDispayOccDebugStuff;
+#endif \ No newline at end of file
diff --git a/src/renderer/Particle.cpp b/src/renderer/Particle.cpp
index 76ddde50..461a10a6 100644
--- a/src/renderer/Particle.cpp
+++ b/src/renderer/Particle.cpp
@@ -4,27 +4,30 @@
#include "General.h"
#include "Timer.h"
#include "TxdStore.h"
-#include "Entity.h"
#include "Sprite.h"
#include "Camera.h"
+#include "Clock.h"
#include "Collision.h"
#include "World.h"
#include "Shadows.h"
+#include "Replay.h"
+#include "Stats.h"
+#include "Weather.h"
+#include "MBlur.h"
+#include "main.h"
#include "AudioScriptObject.h"
#include "ParticleObject.h"
#include "Particle.h"
#include "soundlist.h"
+#include "SaveBuf.h"
#include "debugmenu.h"
-
-#define MAX_PARTICLES_ON_SCREEN (1000)
+#define MAX_PARTICLES_ON_SCREEN (750)
//(5)
#define MAX_SMOKE_FILES ARRAY_SIZE(SmokeFiles)
-//(5)
-#define MAX_SMOKE2_FILES ARRAY_SIZE(Smoke2Files)
//(5)
#define MAX_RUBBER_FILES ARRAY_SIZE(RubberFiles)
//(5)
@@ -39,16 +42,18 @@
#define MAX_RAINSPLASHUP_FILES ARRAY_SIZE(RainSplashupFiles)
//(4)
#define MAX_BIRDFRONT_FILES ARRAY_SIZE(BirdfrontFiles)
+//(8)
+#define MAX_BOAT_FILES ARRAY_SIZE(BoatFiles)
//(4)
#define MAX_CARDEBRIS_FILES ARRAY_SIZE(CardebrisFiles)
//(4)
#define MAX_CARSPLASH_FILES ARRAY_SIZE(CarsplashFiles)
-//(4)
-#define MAX_RAINDROP_FILES ARRAY_SIZE(RaindropFiles)
-
+#define MAX_RAINDRIP_FILES (2)
+#define MAX_LEAF_FILES (2)
+
const char SmokeFiles[][6+1] =
{
"smoke1",
@@ -59,15 +64,6 @@ const char SmokeFiles[][6+1] =
};
-const char Smoke2Files[][9+1] =
-{
- "smokeII_1",
- "smokeII_2",
- "smokeII_3",
- "smokeII_4",
- "smokeII_5"
-};
-
const char RubberFiles[][7+1] =
{
"rubber1",
@@ -111,14 +107,6 @@ const char GunFlashFiles[][9+1] =
"gunflash4"
};
-const char RaindropFiles[][9+1] =
-{
- "raindrop1",
- "raindrop2",
- "raindrop3",
- "raindrop4"
-};
-
const char RainSplashupFiles[][10+1] =
{
"splash_up1",
@@ -133,6 +121,18 @@ const char BirdfrontFiles[][8+1] =
"birdf_04"
};
+const char BoatFiles[][8+1] =
+{
+ "boats_01",
+ "boats_02",
+ "boats_03",
+ "boats_04",
+ "boats_05",
+ "boats_06",
+ "boats_07",
+ "boats_08"
+};
+
const char CardebrisFiles[][12+1] =
{
"cardebris_01",
@@ -152,7 +152,7 @@ const char CarsplashFiles[][12+1] =
CParticle gParticleArray[MAX_PARTICLES_ON_SCREEN];
RwTexture *gpSmokeTex[MAX_SMOKE_FILES];
-RwTexture *gpSmoke2Tex[MAX_SMOKE2_FILES];
+RwTexture *gpSmoke2Tex;
RwTexture *gpRubberTex[MAX_RUBBER_FILES];
RwTexture *gpRainSplashTex[MAX_RAINSPLASH_FILES];
RwTexture *gpWatersprayTex[MAX_WATERSPRAY_FILES];
@@ -160,26 +160,27 @@ RwTexture *gpExplosionMediumTex[MAX_EXPLOSIONMEDIUM_FILES];
RwTexture *gpGunFlashTex[MAX_GUNFLASH_FILES];
RwTexture *gpRainSplashupTex[MAX_RAINSPLASHUP_FILES];
RwTexture *gpBirdfrontTex[MAX_BIRDFRONT_FILES];
+RwTexture *gpBoatTex[MAX_BOAT_FILES];
RwTexture *gpCarDebrisTex[MAX_CARDEBRIS_FILES];
RwTexture *gpCarSplashTex[MAX_CARSPLASH_FILES];
+RwTexture *gpBoatWakeTex;
RwTexture *gpFlame1Tex;
RwTexture *gpFlame5Tex;
RwTexture *gpRainDropSmallTex;
RwTexture *gpBloodTex;
-RwTexture *gpLeafTex;
-RwTexture *gpCloudTex1; // unused
+RwTexture *gpLeafTex[MAX_LEAF_FILES];
+RwTexture *gpCloudTex1;
RwTexture *gpCloudTex4;
RwTexture *gpBloodSmallTex;
RwTexture *gpGungeTex;
RwTexture *gpCollisionSmokeTex;
RwTexture *gpBulletHitTex;
RwTexture *gpGunShellTex;
-RwTexture *gpWakeOldTex;
RwTexture *gpPointlightTex;
RwRaster *gpSmokeRaster[MAX_SMOKE_FILES];
-RwRaster *gpSmoke2Raster[MAX_SMOKE2_FILES];
+RwRaster *gpSmoke2Raster;
RwRaster *gpRubberRaster[MAX_RUBBER_FILES];
RwRaster *gpRainSplashRaster[MAX_RAINSPLASH_FILES];
RwRaster *gpWatersprayRaster[MAX_WATERSPRAY_FILES];
@@ -187,45 +188,59 @@ RwRaster *gpExplosionMediumRaster[MAX_EXPLOSIONMEDIUM_FILES];
RwRaster *gpGunFlashRaster[MAX_GUNFLASH_FILES];
RwRaster *gpRainSplashupRaster[MAX_RAINSPLASHUP_FILES];
RwRaster *gpBirdfrontRaster[MAX_BIRDFRONT_FILES];
+RwRaster *gpBoatRaster[MAX_BOAT_FILES];
RwRaster *gpCarDebrisRaster[MAX_CARDEBRIS_FILES];
RwRaster *gpCarSplashRaster[MAX_CARSPLASH_FILES];
+RwRaster *gpBoatWakeRaster;
RwRaster *gpFlame1Raster;
RwRaster *gpFlame5Raster;
RwRaster *gpRainDropSmallRaster;
RwRaster *gpBloodRaster;
-RwRaster *gpLeafRaster;
-RwRaster *gpCloudRaster1; // unused
+RwRaster *gpLeafRaster[MAX_LEAF_FILES];
+RwRaster *gpCloudRaster1;
RwRaster *gpCloudRaster4;
RwRaster *gpBloodSmallRaster;
RwRaster *gpGungeRaster;
RwRaster *gpCollisionSmokeRaster;
RwRaster *gpBulletHitRaster;
RwRaster *gpGunShellRaster;
-RwRaster *gpWakeOldRaster;
-
-
-RwRaster *gpPointlightRaster; // CPointLights::RenderFogEffect
-
-RwTexture *gpRainDropTex[MAX_RAINDROP_FILES]; // CWeather::RenderRainStreaks
-
-
-RwRaster *gpRainDropRaster[MAX_RAINDROP_FILES];
+RwRaster *gpPointlightRaster;
+
+RwTexture *gpRainDropTex;
+RwRaster *gpRainDropRaster;
+
+RwTexture *gpSparkTex;
+RwTexture *gpNewspaperTex;
+RwTexture *gpGunSmokeTex;
+RwTexture *gpDotTex;
+RwTexture *gpHeatHazeTex;
+RwTexture *gpBeastieTex;
+RwTexture *gpRainDripTex[MAX_RAINDRIP_FILES];
+RwTexture *gpRainDripDarkTex[MAX_RAINDRIP_FILES];
+
+RwRaster *gpSparkRaster;
+RwRaster *gpNewspaperRaster;
+RwRaster *gpGunSmokeRaster;
+RwRaster *gpDotRaster;
+RwRaster *gpHeatHazeRaster;
+RwRaster *gpBeastieRaster;
+RwRaster *gpRainDripRaster[MAX_RAINDRIP_FILES];
+RwRaster *gpRainDripDarkRaster[MAX_RAINDRIP_FILES];
float CParticle::ms_afRandTable[CParticle::RAND_TABLE_SIZE];
-
-
CParticle *CParticle::m_pUnusedListHead;
-
-
float CParticle::m_SinTable[CParticle::SIN_COS_TABLE_SIZE];
float CParticle::m_CosTable[CParticle::SIN_COS_TABLE_SIZE];
int32 Randomizer;
-
int32 nParticleCreationInterval = 1;
+float PARTICLE_WIND_TEST_SCALE = 0.002f;
float fParticleScaleLimit = 0.5f;
+bool clearWaterDrop;
+int32 numWaterDropOnScreen;
+
#ifdef DEBUGMENU
SETTWEAKPATH("Particle");
TWEAKINT32(nParticleCreationInterval, 0, 5, 1);
@@ -233,6 +248,8 @@ TWEAKFLOAT(fParticleScaleLimit, 0.0f, 1.0f, 0.1f);
TWEAKFUNC(CParticle::ReloadConfig);
#endif
+
+
void CParticle::ReloadConfig()
{
debug("Initialising CParticleMgr...");
@@ -320,11 +337,8 @@ void CParticle::Initialise()
gpSmokeRaster[i] = RwTextureGetRaster(gpSmokeTex[i]);
}
- for ( int32 i = 0; i < MAX_SMOKE2_FILES; i++ )
- {
- gpSmoke2Tex[i] = RwTextureRead(Smoke2Files[i], nil);
- gpSmoke2Raster[i] = RwTextureGetRaster(gpSmoke2Tex[i]);
- }
+ gpSmoke2Tex = RwTextureRead("smokeII_3", nil);
+ gpSmoke2Raster = RwTextureGetRaster(gpSmoke2Tex);
for ( int32 i = 0; i < MAX_RUBBER_FILES; i++ )
{
@@ -352,15 +366,13 @@ void CParticle::Initialise()
for ( int32 i = 0; i < MAX_GUNFLASH_FILES; i++ )
{
- gpGunFlashTex[i] = RwTextureRead(GunFlashFiles[i], NULL);
+ gpGunFlashTex[i] = RwTextureRead(GunFlashFiles[i], nil);
gpGunFlashRaster[i] = RwTextureGetRaster(gpGunFlashTex[i]);
}
- for ( int32 i = 0; i < MAX_RAINDROP_FILES; i++ )
- {
- gpRainDropTex[i] = RwTextureRead(RaindropFiles[i], nil);
- gpRainDropRaster[i] = RwTextureGetRaster(gpRainDropTex[i]);
- }
+ gpRainDropTex = RwTextureRead("raindrop4", nil);
+ gpRainDropRaster = RwTextureGetRaster(gpRainDropTex);
+
for ( int32 i = 0; i < MAX_RAINSPLASHUP_FILES; i++ )
{
@@ -370,10 +382,16 @@ void CParticle::Initialise()
for ( int32 i = 0; i < MAX_BIRDFRONT_FILES; i++ )
{
- gpBirdfrontTex[i] = RwTextureRead(BirdfrontFiles[i], NULL);
+ gpBirdfrontTex[i] = RwTextureRead(BirdfrontFiles[i], nil);
gpBirdfrontRaster[i] = RwTextureGetRaster(gpBirdfrontTex[i]);
}
+ for ( int32 i = 0; i < MAX_BOAT_FILES; i++ )
+ {
+ gpBoatTex[i] = RwTextureRead(BoatFiles[i], nil);
+ gpBoatRaster[i] = RwTextureGetRaster(gpBoatTex[i]);
+ }
+
for ( int32 i = 0; i < MAX_CARDEBRIS_FILES; i++ )
{
gpCarDebrisTex[i] = RwTextureRead(CardebrisFiles[i], nil);
@@ -386,7 +404,10 @@ void CParticle::Initialise()
gpCarSplashRaster[i] = RwTextureGetRaster(gpCarSplashTex[i]);
}
- gpFlame1Tex = RwTextureRead("flame1", NULL);
+ gpBoatWakeTex = RwTextureRead("boatwake2", nil);
+ gpBoatWakeRaster = RwTextureGetRaster(gpBoatWakeTex);
+
+ gpFlame1Tex = RwTextureRead("flame1", nil);
gpFlame1Raster = RwTextureGetRaster(gpFlame1Tex);
gpFlame5Tex = RwTextureRead("flame5", nil);
@@ -405,8 +426,11 @@ void CParticle::Initialise()
gpBloodTex = RwTextureRead("blood", nil);
gpBloodRaster = RwTextureGetRaster(gpBloodTex);
- gpLeafTex = RwTextureRead("gameleaf01_64", nil);
- gpLeafRaster = RwTextureGetRaster(gpLeafTex);
+ gpLeafTex[0] = RwTextureRead("gameleaf01_64", nil);
+ gpLeafRaster[0] = RwTextureGetRaster(gpLeafTex[0]);
+
+ gpLeafTex[1] = RwTextureRead("letter", nil);
+ gpLeafRaster[1] = RwTextureGetRaster(gpLeafTex[1]);
gpCloudTex1 = RwTextureRead("cloud3", nil);
gpCloudRaster1 = RwTextureGetRaster(gpCloudTex1);
@@ -429,12 +453,39 @@ void CParticle::Initialise()
gpGunShellTex = RwTextureRead("gunshell", nil);
gpGunShellRaster = RwTextureGetRaster(gpGunShellTex);
- gpWakeOldTex = RwTextureRead("wake_old", nil);
- gpWakeOldRaster = RwTextureGetRaster(gpWakeOldTex);
-
gpPointlightTex = RwTextureRead("pointlight", nil);
gpPointlightRaster = RwTextureGetRaster(gpPointlightTex);
+ gpSparkTex = RwTextureRead("spark", nil);
+ gpSparkRaster = RwTextureGetRaster(gpSparkTex);
+
+ gpNewspaperTex = RwTextureRead("newspaper02_64", nil);
+ gpNewspaperRaster = RwTextureGetRaster(gpNewspaperTex);
+
+ gpGunSmokeTex = RwTextureRead("gunsmoke3", nil);
+ gpGunSmokeRaster = RwTextureGetRaster(gpGunSmokeTex);
+
+ gpDotTex = RwTextureRead("dot", nil);
+ gpDotRaster = RwTextureGetRaster(gpDotTex);
+
+ gpHeatHazeTex = RwTextureRead("heathaze", nil);
+ gpHeatHazeRaster = RwTextureGetRaster(gpHeatHazeTex);
+
+ gpBeastieTex = RwTextureRead("beastie", nil);
+ gpBeastieRaster = RwTextureGetRaster(gpBeastieTex);
+
+ gpRainDripTex[0] = RwTextureRead("raindrip64", nil);
+ gpRainDripRaster[0] = RwTextureGetRaster(gpRainDripTex[0]);
+
+ gpRainDripTex[1] = RwTextureRead("raindripb64", nil);
+ gpRainDripRaster[1] = RwTextureGetRaster(gpRainDripTex[1]);
+
+ gpRainDripDarkTex[0] = RwTextureRead("raindrip64_d", nil);
+ gpRainDripDarkRaster[0] = RwTextureGetRaster(gpRainDripDarkTex[0]);
+
+ gpRainDripDarkTex[1] = RwTextureRead("raindripb64_d", nil);
+ gpRainDripDarkRaster[1] = RwTextureGetRaster(gpRainDripDarkTex[1]);
+
CTxdStore::PopCurrentTxd();
for ( int32 i = 0; i < MAX_PARTICLES; i++ )
@@ -443,185 +494,186 @@ void CParticle::Initialise()
switch ( i )
{
+ case PARTICLE_SPARK:
+ case PARTICLE_SPARK_SMALL:
+ case PARTICLE_RAINDROP_SMALL:
+ case PARTICLE_HELI_ATTACK:
+ entry->m_ppRaster = &gpRainDropSmallRaster;
+ break;
+
+ case PARTICLE_WATER_SPARK:
+ entry->m_ppRaster = &gpSparkRaster;
+ break;
+
+ case PARTICLE_WHEEL_DIRT:
+ case PARTICLE_SAND:
+ case PARTICLE_STEAM2:
+ case PARTICLE_STEAM_NY:
+ case PARTICLE_STEAM_NY_SLOWMOTION:
+ case PARTICLE_GROUND_STEAM:
+ case PARTICLE_ENGINE_STEAM:
+ case PARTICLE_PEDFOOT_DUST:
+ case PARTICLE_CAR_DUST:
+ case PARTICLE_EXHAUST_FUMES:
+ entry->m_ppRaster = &gpSmoke2Raster;
+ break;
+
+ case PARTICLE_WHEEL_WATER:
+ case PARTICLE_WATER:
+ case PARTICLE_SMOKE:
+ case PARTICLE_SMOKE_SLOWMOTION:
+ case PARTICLE_DRY_ICE:
+ case PARTICLE_GARAGEPAINT_SPRAY:
+ case PARTICLE_STEAM:
+ case PARTICLE_WATER_CANNON:
+ case PARTICLE_EXTINGUISH_STEAM:
+ case PARTICLE_HELI_DUST:
+ case PARTICLE_PAINT_SMOKE:
+ case PARTICLE_BULLETHIT_SMOKE:
+ entry->m_ppRaster = gpSmokeRaster;
+ break;
+
case PARTICLE_BLOOD:
entry->m_ppRaster = &gpBloodRaster;
break;
-
+
case PARTICLE_BLOOD_SMALL:
case PARTICLE_BLOOD_SPURT:
entry->m_ppRaster = &gpBloodSmallRaster;
break;
-
+
+ case PARTICLE_DEBRIS:
+ case PARTICLE_TREE_LEAVES:
+ entry->m_ppRaster = gpLeafRaster;
+ break;
+
case PARTICLE_DEBRIS2:
entry->m_ppRaster = &gpGungeRaster;
break;
-
+
+ case PARTICLE_FLYERS:
+ entry->m_ppRaster = &gpNewspaperRaster;
+ break;
+
+ case PARTICLE_FLAME:
+ case PARTICLE_CARFLAME:
+ entry->m_ppRaster = &gpFlame1Raster;
+ break;
+
+ case PARTICLE_FIREBALL:
+ entry->m_ppRaster = &gpFlame5Raster;
+ break;
+
case PARTICLE_GUNFLASH:
case PARTICLE_GUNFLASH_NOANIM:
entry->m_ppRaster = gpGunFlashRaster;
break;
-
+
+
case PARTICLE_GUNSMOKE:
- case PARTICLE_SPLASH:
+ case PARTICLE_WATERDROP:
+ case PARTICLE_BLOODDROP:
+ case PARTICLE_HEATHAZE:
+ case PARTICLE_HEATHAZE_IN_DIST:
entry->m_ppRaster = nil;
break;
-
- case PARTICLE_FLAME:
- case PARTICLE_CARFLAME:
- entry->m_ppRaster = &gpFlame1Raster;
+
+ case PARTICLE_GUNSMOKE2:
+ case PARTICLE_BOAT_THRUSTJET:
+ case PARTICLE_RUBBER_SMOKE:
+ entry->m_ppRaster = gpRubberRaster;
break;
-
- case PARTICLE_FIREBALL:
- entry->m_ppRaster = &gpFlame5Raster;
+
+ case PARTICLE_CIGARETTE_SMOKE:
+ entry->m_ppRaster = &gpGunSmokeRaster;
break;
-
+
+ case PARTICLE_TEARGAS:
+ entry->m_ppRaster = &gpHeatHazeRaster;
+ break;
+
+ case PARTICLE_SHARD:
+ case PARTICLE_RAINDROP:
+ case PARTICLE_RAINDROP_2D:
+ entry->m_ppRaster = &gpRainDropRaster;
+ break;
+
+ case PARTICLE_SPLASH:
+ case PARTICLE_PED_SPLASH:
+ case PARTICLE_CAR_SPLASH:
+ case PARTICLE_WATER_HYDRANT:
+ entry->m_ppRaster = gpCarSplashRaster;
+ break;
+
case PARTICLE_RAIN_SPLASH:
case PARTICLE_RAIN_SPLASH_BIGGROW:
entry->m_ppRaster = gpRainSplashRaster;
break;
-
+
case PARTICLE_RAIN_SPLASHUP:
entry->m_ppRaster = gpRainSplashupRaster;
break;
-
+
case PARTICLE_WATERSPRAY:
entry->m_ppRaster = gpWatersprayRaster;
break;
-
- case PARTICLE_SHARD:
- case PARTICLE_RAINDROP:
- case PARTICLE_RAINDROP_2D:
- entry->m_ppRaster = gpRainDropRaster;
- break;
-
+
case PARTICLE_EXPLOSION_MEDIUM:
case PARTICLE_EXPLOSION_LARGE:
case PARTICLE_EXPLOSION_MFAST:
case PARTICLE_EXPLOSION_LFAST:
entry->m_ppRaster = gpExplosionMediumRaster;
break;
-
- case PARTICLE_BOAT_WAKE:
- entry->m_ppRaster = &gpWakeOldRaster;
- break;
-
- case PARTICLE_CAR_SPLASH:
- case PARTICLE_WATER_HYDRANT:
- case PARTICLE_PED_SPLASH:
- entry->m_ppRaster = gpCarSplashRaster;
- break;
-
- case PARTICLE_SPARK:
- case PARTICLE_SPARK_SMALL:
- case PARTICLE_RAINDROP_SMALL:
- case PARTICLE_HELI_ATTACK:
- entry->m_ppRaster = &gpRainDropSmallRaster;
- break;
-
- case PARTICLE_DEBRIS:
- case PARTICLE_TREE_LEAVES:
- entry->m_ppRaster = &gpLeafRaster;
- break;
-
- case PARTICLE_CAR_DEBRIS:
- case PARTICLE_HELI_DEBRIS:
- entry->m_ppRaster = gpCarDebrisRaster;
- break;
-
- case PARTICLE_WHEEL_DIRT:
- case PARTICLE_STEAM2:
- case PARTICLE_STEAM_NY:
- case PARTICLE_STEAM_NY_SLOWMOTION:
- case PARTICLE_ENGINE_STEAM:
- case PARTICLE_BOAT_THRUSTJET:
- case PARTICLE_PEDFOOT_DUST:
- case PARTICLE_EXHAUST_FUMES:
- entry->m_ppRaster = gpSmoke2Raster;
+
+ case PARTICLE_BOAT_SPLASH:
+ entry->m_ppRaster = &gpBoatWakeRaster;
break;
-
- case PARTICLE_GUNSMOKE2:
- case PARTICLE_RUBBER_SMOKE:
- entry->m_ppRaster = gpRubberRaster;
+
+ case PARTICLE_ENGINE_SMOKE:
+ case PARTICLE_ENGINE_SMOKE2:
+ case PARTICLE_CARFLAME_SMOKE:
+ case PARTICLE_FIREBALL_SMOKE:
+ case PARTICLE_ROCKET_SMOKE:
+ case PARTICLE_TEST:
+ entry->m_ppRaster = &gpCloudRaster4;
break;
-
+
case PARTICLE_CARCOLLISION_DUST:
case PARTICLE_BURNINGRUBBER_SMOKE:
entry->m_ppRaster = &gpCollisionSmokeRaster;
break;
-
- case PARTICLE_WHEEL_WATER:
- case PARTICLE_WATER:
- case PARTICLE_SMOKE:
- case PARTICLE_SMOKE_SLOWMOTION:
- case PARTICLE_GARAGEPAINT_SPRAY:
- case PARTICLE_STEAM:
- case PARTICLE_BOAT_SPLASH:
- case PARTICLE_WATER_CANNON:
- case PARTICLE_EXTINGUISH_STEAM:
- case PARTICLE_HELI_DUST:
- case PARTICLE_PAINT_SMOKE:
- case PARTICLE_BULLETHIT_SMOKE:
- entry->m_ppRaster = gpSmokeRaster;
+
+ case PARTICLE_CAR_DEBRIS:
+ case PARTICLE_HELI_DEBRIS:
+ case PARTICLE_BIRD_DEBRIS:
+ entry->m_ppRaster = gpCarDebrisRaster;
break;
-
+
case PARTICLE_GUNSHELL_FIRST:
case PARTICLE_GUNSHELL:
case PARTICLE_GUNSHELL_BUMP1:
case PARTICLE_GUNSHELL_BUMP2:
entry->m_ppRaster = &gpGunShellRaster;
break;
-
- case PARTICLE_ENGINE_SMOKE:
- case PARTICLE_ENGINE_SMOKE2:
- case PARTICLE_CARFLAME_SMOKE:
- case PARTICLE_FIREBALL_SMOKE:
- case PARTICLE_TEST:
- entry->m_ppRaster = &gpCloudRaster4;
- break;
-
+
+
case PARTICLE_BIRD_FRONT:
entry->m_ppRaster = gpBirdfrontRaster;
break;
+
+ case PARTICLE_SHIP_SIDE:
+ entry->m_ppRaster = gpBoatRaster;
+ break;
+
+ case PARTICLE_BEASTIE:
+ entry->m_ppRaster = &gpBeastieRaster;
+ break;
}
}
debug("CParticle ready");
}
-void
-CEntity::AddSteamsFromGround(CVector *unused)
-{
- int i, n;
- C2dEffect *effect;
- CVector pos;
-
- n = CModelInfo::GetModelInfo(GetModelIndex())->GetNum2dEffects();
- for(i = 0; i < n; i++){
- effect = CModelInfo::GetModelInfo(GetModelIndex())->Get2dEffect(i);
- if(effect->type != EFFECT_PARTICLE)
- continue;
-
- pos = GetMatrix() * effect->pos;
- switch(effect->particle.particleType){
- case 0:
- CParticleObject::AddObject(POBJECT_PAVEMENT_STEAM, pos, effect->particle.dir, effect->particle.scale, false);
- break;
- case 1:
- CParticleObject::AddObject(POBJECT_WALL_STEAM, pos, effect->particle.dir, effect->particle.scale, false);
- break;
- case 2:
- CParticleObject::AddObject(POBJECT_DRY_ICE, pos, effect->particle.scale, false);
- break;
- case 3:
- CParticleObject::AddObject(POBJECT_SMALL_FIRE, pos, effect->particle.dir, effect->particle.scale, false);
- break;
- case 4:
- CParticleObject::AddObject(POBJECT_DARK_SMOKE, pos, effect->particle.dir, effect->particle.scale, false);
- break;
- }
- }
-}
-
void CParticle::Shutdown()
{
debug("Shutting down CParticle...");
@@ -629,168 +681,145 @@ void CParticle::Shutdown()
for ( int32 i = 0; i < MAX_SMOKE_FILES; i++ )
{
RwTextureDestroy(gpSmokeTex[i]);
-#if GTA_VERSION >= GTA3_PC_11
gpSmokeTex[i] = nil;
-#endif
}
- for ( int32 i = 0; i < MAX_SMOKE2_FILES; i++ )
- {
- RwTextureDestroy(gpSmoke2Tex[i]);
-#if GTA_VERSION >= GTA3_PC_11
- gpSmoke2Tex[i] = nil;
-#endif
- }
+ RwTextureDestroy(gpSmoke2Tex);
+ gpSmoke2Tex = nil;
for ( int32 i = 0; i < MAX_RUBBER_FILES; i++ )
{
RwTextureDestroy(gpRubberTex[i]);
-#if GTA_VERSION >= GTA3_PC_11
gpRubberTex[i] = nil;
-#endif
}
for ( int32 i = 0; i < MAX_RAINSPLASH_FILES; i++ )
{
RwTextureDestroy(gpRainSplashTex[i]);
-#if GTA_VERSION >= GTA3_PC_11
gpRainSplashTex[i] = nil;
-#endif
}
for ( int32 i = 0; i < MAX_WATERSPRAY_FILES; i++ )
{
RwTextureDestroy(gpWatersprayTex[i]);
-#if GTA_VERSION >= GTA3_PC_11
gpWatersprayTex[i] = nil;
-#endif
}
for ( int32 i = 0; i < MAX_EXPLOSIONMEDIUM_FILES; i++ )
{
RwTextureDestroy(gpExplosionMediumTex[i]);
-#if GTA_VERSION >= GTA3_PC_11
gpExplosionMediumTex[i] = nil;
-#endif
}
for ( int32 i = 0; i < MAX_GUNFLASH_FILES; i++ )
{
RwTextureDestroy(gpGunFlashTex[i]);
-#if GTA_VERSION >= GTA3_PC_11
gpGunFlashTex[i] = nil;
-#endif
}
- for ( int32 i = 0; i < MAX_RAINDROP_FILES; i++ )
- {
- RwTextureDestroy(gpRainDropTex[i]);
-#if GTA_VERSION >= GTA3_PC_11
- gpRainDropTex[i] = nil;
-#endif
- }
+ RwTextureDestroy(gpRainDropTex);
+ gpRainDropTex = nil;
for ( int32 i = 0; i < MAX_RAINSPLASHUP_FILES; i++ )
{
RwTextureDestroy(gpRainSplashupTex[i]);
-#if GTA_VERSION >= GTA3_PC_11
gpRainSplashupTex[i] = nil;
-#endif
}
for ( int32 i = 0; i < MAX_BIRDFRONT_FILES; i++ )
{
RwTextureDestroy(gpBirdfrontTex[i]);
-#if GTA_VERSION >= GTA3_PC_11
gpBirdfrontTex[i] = nil;
-#endif
+ }
+
+ for ( int32 i = 0; i < MAX_BOAT_FILES; i++ )
+ {
+ RwTextureDestroy(gpBoatTex[i]);
+ gpBoatTex[i] = nil;
}
for ( int32 i = 0; i < MAX_CARDEBRIS_FILES; i++ )
{
RwTextureDestroy(gpCarDebrisTex[i]);
-#if GTA_VERSION >= GTA3_PC_11
gpCarDebrisTex[i] = nil;
-#endif
}
for ( int32 i = 0; i < MAX_CARSPLASH_FILES; i++ )
{
RwTextureDestroy(gpCarSplashTex[i]);
-#if GTA_VERSION >= GTA3_PC_11
gpCarSplashTex[i] = nil;
-#endif
}
+ for ( int32 i = 0; i < MAX_RAINDRIP_FILES; i++ )
+ {
+ RwTextureDestroy(gpRainDripTex[i]);
+ gpRainDripTex[i] = nil;
+
+ RwTextureDestroy(gpRainDripDarkTex[i]);
+ gpRainDripDarkTex[i] = nil;
+ }
+
+ RwTextureDestroy(gpBoatWakeTex);
+ gpBoatWakeTex = nil;
+
RwTextureDestroy(gpFlame1Tex);
-#if GTA_VERSION >= GTA3_PC_11
gpFlame1Tex = nil;
-#endif
RwTextureDestroy(gpFlame5Tex);
-#if GTA_VERSION >= GTA3_PC_11
gpFlame5Tex = nil;
-#endif
RwTextureDestroy(gpRainDropSmallTex);
-#if GTA_VERSION >= GTA3_PC_11
gpRainDropSmallTex = nil;
-#endif
RwTextureDestroy(gpBloodTex);
-#if GTA_VERSION >= GTA3_PC_11
gpBloodTex = nil;
-#endif
- RwTextureDestroy(gpLeafTex);
-#if GTA_VERSION >= GTA3_PC_11
- gpLeafTex = nil;
-#endif
+ RwTextureDestroy(gpLeafTex[0]);
+ gpLeafTex[0] = nil;
+
+ RwTextureDestroy(gpLeafTex[1]);
+ gpLeafTex[1] = nil;
RwTextureDestroy(gpCloudTex1);
-#if GTA_VERSION >= GTA3_PC_11
gpCloudTex1 = nil;
-#endif
RwTextureDestroy(gpCloudTex4);
-#if GTA_VERSION >= GTA3_PC_11
gpCloudTex4 = nil;
-#endif
RwTextureDestroy(gpBloodSmallTex);
-#if GTA_VERSION >= GTA3_PC_11
gpBloodSmallTex = nil;
-#endif
RwTextureDestroy(gpGungeTex);
-#if GTA_VERSION >= GTA3_PC_11
gpGungeTex = nil;
-#endif
RwTextureDestroy(gpCollisionSmokeTex);
-#if GTA_VERSION >= GTA3_PC_11
gpCollisionSmokeTex = nil;
-#endif
RwTextureDestroy(gpBulletHitTex);
-#if GTA_VERSION >= GTA3_PC_11
gpBulletHitTex = nil;
-#endif
RwTextureDestroy(gpGunShellTex);
-#if GTA_VERSION >= GTA3_PC_11
gpGunShellTex = nil;
-#endif
-
- RwTextureDestroy(gpWakeOldTex);
-#if GTA_VERSION >= GTA3_PC_11
- gpWakeOldTex = nil;
-#endif
RwTextureDestroy(gpPointlightTex);
-#if GTA_VERSION >= GTA3_PC_11
gpPointlightTex = nil;
-#endif
+
+ RwTextureDestroy(gpSparkTex);
+ gpSparkTex = nil;
+
+ RwTextureDestroy(gpNewspaperTex);
+ gpNewspaperTex = nil;
+
+ RwTextureDestroy(gpGunSmokeTex);
+ gpGunSmokeTex = nil;
+
+ RwTextureDestroy(gpDotTex);
+ gpDotTex = nil;
+ RwTextureDestroy(gpHeatHazeTex);
+ gpHeatHazeTex = nil;
+
+ RwTextureDestroy(gpBeastieTex);
+ gpBeastieTex = nil;
int32 slot;
@@ -800,6 +829,40 @@ void CParticle::Shutdown()
debug("CParticle shut down");
}
+
+void CParticle::AddParticlesAlongLine(tParticleType type, CVector const &vecStart, CVector const &vecEnd, CVector const &vecDir, float fPower, CEntity *pEntity, float fSize, int32 nRotationSpeed, int32 nRotation, int32 nCurFrame, int32 nLifeSpan)
+{
+ CVector vecDist = vecEnd - vecStart;
+ float fDist = vecDist.Magnitude();
+ float fSteps = Max(fDist / fPower, 1.0f);
+ int32 nSteps = (int32)fSteps;
+
+ CVector vecStep = vecDist * (1.0f / (float)nSteps);
+
+ for ( int32 i = 0; i < nSteps; i++ )
+ {
+ CVector vecPos = float(i) * vecStep + vecStart;
+ AddParticle(type, vecPos, vecDir, pEntity, fSize, nRotationSpeed, nRotation, nCurFrame, nLifeSpan);
+ }
+}
+
+void CParticle::AddParticlesAlongLine(tParticleType type, CVector const &vecStart, CVector const &vecEnd, CVector const &vecDir, float fPower, CEntity *pEntity, float fSize, RwRGBA const &color, int32 nRotationSpeed, int32 nRotation, int32 nCurFrame, int32 nLifeSpan)
+{
+ CVector vecDist = vecEnd - vecStart;
+ float fDist = vecDist.Magnitude();
+ float fSteps = Max(fDist / fPower, 1.0f);
+ int32 nSteps = (int32)fSteps;
+
+ CVector vecStep = vecDist * (1.0f / (float)nSteps);
+
+ for ( int32 i = 0; i < nSteps; i++ )
+ {
+ CVector vecPos = float(i) * vecStep + vecStart;
+
+ AddParticle(type, vecPos, vecDir, pEntity, fSize, color, nRotationSpeed, nRotation, nCurFrame, nLifeSpan);
+ }
+}
+
CParticle *CParticle::AddParticle(tParticleType type, CVector const &vecPos, CVector const &vecDir, CEntity *pEntity, float fSize, int32 nRotationSpeed, int32 nRotation, int32 nCurFrame, int32 nLifeSpan)
{
CRGBA color(0, 0, 0, 0);
@@ -809,9 +872,8 @@ CParticle *CParticle::AddParticle(tParticleType type, CVector const &vecPos, CVe
CParticle *CParticle::AddParticle(tParticleType type, CVector const &vecPos, CVector const &vecDir, CEntity *pEntity, float fSize, RwRGBA const &color, int32 nRotationSpeed, int32 nRotation, int32 nCurFrame, int32 nLifeSpan)
{
if ( CTimer::GetIsPaused() )
- return NULL;
+ return nil;
-#ifdef PC_PARTICLE
if ( ( type == PARTICLE_ENGINE_SMOKE
|| type == PARTICLE_ENGINE_SMOKE2
|| type == PARTICLE_ENGINE_STEAM
@@ -824,8 +886,10 @@ CParticle *CParticle::AddParticle(tParticleType type, CVector const &vecPos, CVe
{
return nil;
}
-#endif
+ if ( !CReplay::IsPlayingBack() )
+ CReplay::RecordParticle(type, vecPos, vecDir, fSize, color);
+
CParticle *pParticle = m_pUnusedListHead;
if ( pParticle == nil )
@@ -846,7 +910,19 @@ CParticle *CParticle::AddParticle(tParticleType type, CVector const &vecPos, CVe
pParticle->m_nTimeWhenWillBeDestroyed = CTimer::GetTimeInMilliseconds() + psystem->m_nLifeSpan;
pParticle->m_nColorIntensity = psystem->m_nFadeToBlackInitialIntensity;
+
+ pParticle->m_nFadeToBlackTimer = psystem->m_nFadeToBlackAmount;
+
+ if ( psystem->m_nFadeToBlackTime )
+ pParticle->m_nFadeToBlackTimer /= psystem->m_nFadeToBlackTime;
+
pParticle->m_nAlpha = psystem->m_nFadeAlphaInitialIntensity;
+
+ pParticle->m_nFadeAlphaTimer = psystem->m_nFadeAlphaAmount;
+
+ if ( psystem->m_nFadeAlphaTime )
+ pParticle->m_nFadeAlphaTimer /= psystem->m_nFadeAlphaTime;
+
pParticle->m_nCurrentZRotation = psystem->m_nZRotationInitialAngle;
pParticle->m_fCurrentZRadius = psystem->m_fInitialZRadius;
@@ -855,14 +931,29 @@ CParticle *CParticle::AddParticle(tParticleType type, CVector const &vecPos, CVe
else
pParticle->m_nCurrentFrame = psystem->m_nStartAnimationFrame;
- pParticle->m_nFadeToBlackTimer = 0;
- pParticle->m_nFadeAlphaTimer = 0;
+
pParticle->m_nZRotationTimer = 0;
pParticle->m_nZRadiusTimer = 0;
pParticle->m_nAnimationSpeedTimer = 0;
pParticle->m_fZGround = 0.0f;
- pParticle->m_vecPosition = vecPos;
+
+ if ( type != PARTICLE_HEATHAZE )
+ pParticle->m_vecPosition = vecPos;
+ else
+ {
+ CVector screen;
+ float w, h;
+
+ if ( !CSprite::CalcScreenCoors(vecPos, &screen, &w, &h, true) )
+ return nil;
+
+ pParticle->m_vecPosition = screen;
+ psystem->m_vecTextureStretch.x = w;
+ psystem->m_vecTextureStretch.y = h;
+ }
+
pParticle->m_vecVelocity = vecDir;
+
pParticle->m_vecParticleMovementOffset = CVector(0.0f, 0.0f, 0.0f);
pParticle->m_nTimeWhenColorWillBeChanged = 0;
@@ -870,7 +961,7 @@ CParticle *CParticle::AddParticle(tParticleType type, CVector const &vecPos, CVe
RwRGBAAssign(&pParticle->m_Color, &color);
else
{
- RwRGBAAssign(&pParticle->m_Color, &psystem->m_RenderColouring);
+ RwRGBAAssign(&pParticle->m_Color, psystem->m_RenderColouring);
if ( psystem->m_ColorFadeTime != 0 )
pParticle->m_nTimeWhenColorWillBeChanged = CTimer::GetTimeInMilliseconds() + psystem->m_ColorFadeTime;
@@ -878,7 +969,7 @@ CParticle *CParticle::AddParticle(tParticleType type, CVector const &vecPos, CVe
if ( psystem->m_InitialColorVariation != 0 )
{
int32 ColorVariation = CGeneral::GetRandomNumberInRange(-psystem->m_InitialColorVariation, psystem->m_InitialColorVariation);
- //Float ColorVariation = CGeneral::GetRandomNumberInRange((float)-psystem->m_InitialColorVariation, (float)psystem->m_InitialColorVariation);
+ //float ColorVariation = CGeneral::GetRandomNumberInRange((float)-psystem->m_InitialColorVariation, (float)psystem->m_InitialColorVariation);
pParticle->m_Color.red = Clamp(pParticle->m_Color.red +
PERCENT(pParticle->m_Color.red, ColorVariation),
@@ -895,13 +986,7 @@ CParticle *CParticle::AddParticle(tParticleType type, CVector const &vecPos, CVe
}
pParticle->m_nRotation = nRotation;
-
-// PC only
- if ( pParticle->m_nRotation >= 360 )
- pParticle->m_nRotation -= 360;
- else if ( pParticle->m_nRotation < 0 )
- pParticle->m_nRotation += 360;
-
+
if ( nRotationSpeed != 0 )
pParticle->m_nRotationStep = nRotationSpeed;
else
@@ -910,8 +995,6 @@ CParticle *CParticle::AddParticle(tParticleType type, CVector const &vecPos, CVe
if ( CGeneral::GetRandomNumber() & 1 )
pParticle->m_nRotationStep = -pParticle->m_nRotationStep;
- pParticle->m_vecScreenPosition.x = 0.0f; // bug ?
-
if ( psystem->m_fPositionRandomError != 0.0f )
{
pParticle->m_vecPosition.x += psystem->m_fPositionRandomError * ms_afRandTable[CGeneral::GetRandomNumber() % RAND_TABLE_SIZE];
@@ -930,7 +1013,7 @@ CParticle *CParticle::AddParticle(tParticleType type, CVector const &vecPos, CVe
pParticle->m_vecVelocity.z += psystem->m_fVelocityRandomError * ms_afRandTable[CGeneral::GetRandomNumber() % RAND_TABLE_SIZE];
}
- if ( psystem->m_fExpansionRateError != 0.0f )
+ if ( psystem->m_fExpansionRateError != 0.0f && !(psystem->Flags & SCREEN_TRAIL) )
pParticle->m_fExpansionRate += psystem->m_fExpansionRateError * ms_afRandTable[CGeneral::GetRandomNumber() % RAND_TABLE_SIZE] + psystem->m_fExpansionRateError;
if ( psystem->m_nRotationRateError != 0 )
@@ -1054,6 +1137,25 @@ void CParticle::Update()
float fFricDeccel99 = pow(0.99f, CTimer::GetTimeStep());
CParticleObject::UpdateAll();
+
+ // ejaculation at 23:00, 23:15, 23:30, 23:45
+ if ( CClock::ms_nGameClockHours == 23 &&
+ ( CClock::ms_nGameClockMinutes == 0
+ || CClock::ms_nGameClockMinutes == 15
+ || CClock::ms_nGameClockMinutes == 30
+ || CClock::ms_nGameClockMinutes == 45 ) )
+ {
+ AddParticle(PARTICLE_CAR_SPLASH,
+ CVector(557.03f, -4.0f, 151.46f),
+ CVector(0.0f, 0.0f, 2.5f),
+ NULL,
+ 2.0f,
+ CRGBA(255, 255, 255, 255),
+ 0,
+ 0,
+ 1,
+ 1000);
+ }
for ( int32 i = 0; i < MAX_PARTICLES; i++ )
{
@@ -1067,9 +1169,209 @@ void CParticle::Update()
for ( ; particle != nil; _Next(particle, prevParticle, psystem, bRemoveParticle) )
{
+ CVector vecWind(0.0f, 0.0f, 0.0f);
+
bRemoveParticle = false;
- CVector moveStep = particle->m_vecPosition + ( particle->m_vecVelocity * CTimer::GetTimeStep() );
+ CVector vecMoveStep = particle->m_vecVelocity * CTimer::GetTimeStep();
+ CVector vecPos = particle->m_vecPosition;
+
+ if ( numWaterDropOnScreen == 0 )
+ clearWaterDrop = false;
+
+ if ( psystem->m_Type == PARTICLE_WATERDROP )
+ {
+ if ( CGame::IsInInterior() || clearWaterDrop == true )
+ {
+ bRemoveParticle = true;
+ continue;
+ }
+
+ static uint8 nWaterDropCount;
+
+ if ( nWaterDropCount == 5 )
+ {
+ vecMoveStep = CVector(0.0f, 0.0f, 0.0f);
+ particle->m_nTimeWhenWillBeDestroyed += 1250;
+ nWaterDropCount = 0;
+ }
+ else
+ {
+ if ( TheCamera.m_CameraAverageSpeed > 0.35f )
+ {
+ if ( vecMoveStep.Magnitude() > 0.5f )
+ {
+ if ( vecMoveStep.Magnitude() > 0.4f && vecMoveStep.Magnitude() < 0.8f )
+ {
+ vecMoveStep.x += TheCamera.m_CameraAverageSpeed * 1.5f;
+ vecMoveStep.y += TheCamera.m_CameraAverageSpeed * 1.5f;
+ }
+ else if ( vecMoveStep.Magnitude() != 0.0f )
+ {
+ vecMoveStep.x += CGeneral::GetRandomNumberInRange(0.01f, 0.05f);
+ vecMoveStep.y += CGeneral::GetRandomNumberInRange(0.01f, 0.05f);
+ }
+ }
+ }
+
+ nWaterDropCount++;
+ }
+
+ if ( vecPos.z <= 1.5f )
+ vecMoveStep.z = 0.0f;
+ }
+
+ if ( psystem->m_Type == PARTICLE_HEATHAZE || psystem->m_Type == PARTICLE_HEATHAZE_IN_DIST )
+ {
+#ifdef FIX_BUGS
+ int32 nSinCosIndex = (int32(DEGTORAD((float)particle->m_nRotation) * float(SIN_COS_TABLE_SIZE) / TWOPI) + SIN_COS_TABLE_SIZE) % SIN_COS_TABLE_SIZE;
+#else
+ int32 nSinCosIndex = int32(DEGTORAD((float)particle->m_nRotation) * float(SIN_COS_TABLE_SIZE) / TWOPI) % SIN_COS_TABLE_SIZE;
+#endif
+ vecMoveStep.x = Sin(nSinCosIndex);
+ vecMoveStep.y = Sin(nSinCosIndex);
+
+ if ( psystem->m_Type == PARTICLE_HEATHAZE_IN_DIST )
+ particle->m_nRotation = int16((float)particle->m_nRotation + 0.75f);
+ else
+ particle->m_nRotation = int16((float)particle->m_nRotation + 1.0f);
+ }
+
+ if ( psystem->m_Type == PARTICLE_BEASTIE )
+ {
+#ifdef FIX_BUGS
+ int32 nSinCosIndex = (int32(DEGTORAD((float)particle->m_nRotation) * float(SIN_COS_TABLE_SIZE) / TWOPI) + SIN_COS_TABLE_SIZE) % SIN_COS_TABLE_SIZE;
+#else
+ int32 nSinCosIndex = int32(DEGTORAD((float)particle->m_nRotation) * float(SIN_COS_TABLE_SIZE) / TWOPI) % SIN_COS_TABLE_SIZE;
+#endif
+ particle->m_vecVelocity.x = 0.50f * Cos(nSinCosIndex);
+ particle->m_vecVelocity.y = Cos(nSinCosIndex);
+ particle->m_vecVelocity.z = 0.25f * Sin(nSinCosIndex);
+
+ if ( particle->m_vecVelocity.Magnitude() > 2.0f
+ || vecPos.z > 40.0f
+ || (TheCamera.GetPosition() - vecPos).Magnitude() < 60.0f
+ )
+ {
+ bRemoveParticle = true;
+ continue;
+ }
+ }
+
+ vecPos += vecMoveStep;
+
+ if ( psystem->m_Type == PARTICLE_FIREBALL )
+ {
+ AddParticle(PARTICLE_HEATHAZE, particle->m_vecPosition, CVector(0.0f, 0.0f, 0.0f),
+ nil, particle->m_fSize * 5.0f);
+ }
+
+ if ( psystem->m_Type == PARTICLE_GUNSMOKE2 )
+ {
+ if ( CTimer::GetFrameCounter() & 10 )
+ {
+#ifdef FIX_BUGS
+ if ( FindPlayerPed() && FindPlayerPed()->GetWeapon()->m_eWeaponType == WEAPONTYPE_MINIGUN )
+#else
+ if ( FindPlayerPed()->GetWeapon()->m_eWeaponType == WEAPONTYPE_MINIGUN )
+#endif
+ {
+ AddParticle(PARTICLE_HEATHAZE, particle->m_vecPosition, CVector(0.0f, 0.0f, 0.0f));
+ }
+ }
+ }
+
+ if ( CWeather::Wind > 0.0f )
+ {
+ if ( vecMoveStep.Magnitude() != 0.0f )
+ {
+ vecWind.x = CGeneral::GetRandomNumberInRange(0.75f, 1.25f) * -CWeather::Wind;
+ vecWind.y = CGeneral::GetRandomNumberInRange(0.75f, 1.25f) * -CWeather::Wind;
+ vecWind *= PARTICLE_WIND_TEST_SCALE * psystem->m_fWindFactor * CTimer::GetTimeStep();
+ particle->m_vecVelocity += vecWind;
+ }
+ }
+
+ if ( psystem->m_Type == PARTICLE_RAINDROP
+ || psystem->m_Type == PARTICLE_RAINDROP_SMALL
+ || psystem->m_Type == PARTICLE_RAIN_SPLASH
+ || psystem->m_Type == PARTICLE_RAIN_SPLASH_BIGGROW
+ || psystem->m_Type == PARTICLE_CAR_SPLASH
+ || psystem->m_Type == PARTICLE_BOAT_SPLASH
+ || psystem->m_Type == PARTICLE_RAINDROP_2D )
+ {
+ int32 nMaxDrops = int32(6.0f * TheCamera.m_CameraAverageSpeed + 1.0f);
+ float fDistToCam = 0.0f;
+
+ if ( psystem->m_Type == PARTICLE_BOAT_SPLASH || psystem->m_Type == PARTICLE_CAR_SPLASH )
+ {
+ if ( vecPos.z + particle->m_fSize < 5.0f )
+ {
+ bRemoveParticle = true;
+ continue;
+ }
+
+ switch ( TheCamera.GetLookDirection() )
+ {
+ case LOOKING_LEFT:
+ case LOOKING_RIGHT:
+ case LOOKING_FORWARD:
+ nMaxDrops /= 2;
+ break;
+
+ default:
+ nMaxDrops = 0;
+ break;
+ }
+
+ fDistToCam = (TheCamera.GetPosition() - vecPos).Magnitude();
+ }
+
+ if ( numWaterDropOnScreen < nMaxDrops && numWaterDropOnScreen < 63
+ && fDistToCam < 10.0f
+ && clearWaterDrop == false
+ && !CGame::IsInInterior() )
+ {
+ CVector vecWaterdropTarget
+ (
+ CGeneral::GetRandomNumberInRange(-0.25f, 0.25f),
+ CGeneral::GetRandomNumberInRange(0.1f, 0.75f),
+ -0.01f
+ );
+
+ CVector vecWaterdropPos;
+
+ if ( TheCamera.m_CameraAverageSpeed < 0.35f )
+ vecWaterdropPos.x = (float)CGeneral::GetRandomNumberInRange(50, int32(SCREEN_WIDTH) - 50);
+ else
+ vecWaterdropPos.x = (float)CGeneral::GetRandomNumberInRange(200, int32(SCREEN_WIDTH) - 200);
+
+ if ( psystem->m_Type == PARTICLE_BOAT_SPLASH || psystem->m_Type == PARTICLE_CAR_SPLASH )
+ vecWaterdropPos.y = (float)CGeneral::GetRandomNumberInRange(SCREEN_HEIGHT / 2, SCREEN_HEIGHT);
+ else
+ {
+ if ( TheCamera.m_CameraAverageSpeed < 0.35f )
+ vecWaterdropPos.y = (float)CGeneral::GetRandomNumberInRange(0, int32(SCREEN_HEIGHT));
+ else
+ vecWaterdropPos.y = (float)CGeneral::GetRandomNumberInRange(150, int32(SCREEN_HEIGHT) - 200);
+ }
+
+ vecWaterdropPos.z = 2.0f;
+
+ if ( AddParticle(PARTICLE_WATERDROP,
+ vecWaterdropPos,
+ vecWaterdropTarget,
+ nil,
+ CGeneral::GetRandomNumberInRange(0.1f, 0.15f),
+ 0,
+ 0,
+ CGeneral::GetRandomNumber() & 1,
+ 0) != nil )
+ {
+ numWaterDropOnScreen++;
+ }
+ }
+ }
if ( CTimer::GetTimeInMilliseconds() > particle->m_nTimeWhenWillBeDestroyed || particle->m_nAlpha == 0 )
{
@@ -1096,7 +1398,7 @@ void CParticle::Update()
0, 255);
}
else
- RwRGBAAssign(&particle->m_Color, &psystem->m_FadeDestinationColor);
+ RwRGBAAssign(&particle->m_Color, psystem->m_FadeDestinationColor);
}
if ( psystem->Flags & CLIPOUT2D )
@@ -1109,16 +1411,41 @@ void CParticle::Update()
}
}
- float size = particle->m_fSize + particle->m_fExpansionRate;
-
- if ( size < 0.0f )
+ if ( !(psystem->Flags & SCREEN_TRAIL) )
{
- bRemoveParticle = true;
- continue;
+ float size;
+
+ if ( particle->m_fExpansionRate > 0.0f )
+ {
+ float speed = Max(vecWind.Magnitude(), vecMoveStep.Magnitude());
+
+ if ( psystem->m_Type == PARTICLE_EXHAUST_FUMES || psystem->m_Type == PARTICLE_ENGINE_STEAM )
+ speed *= 2.0f;
+
+ if ( ( psystem->m_Type == PARTICLE_BOAT_SPLASH || psystem->m_Type == PARTICLE_CAR_SPLASH )
+ && particle->m_fSize > 1.2f )
+ {
+ size = particle->m_fSize - (1.0f + speed) * particle->m_fExpansionRate;
+ particle->m_vecVelocity.z -= 0.15f;
+ }
+ else
+ size = particle->m_fSize + (1.0f + speed) * particle->m_fExpansionRate;
+ }
+ else
+ size = particle->m_fSize + particle->m_fExpansionRate;
+
+ if ( psystem->m_Type == PARTICLE_WATERDROP )
+ size = (size - Abs(vecMoveStep.x) * 0.000150000007f) + (Abs(vecMoveStep.z) * 0.0500000007f); //TODO:
+
+ if ( size < 0.0f )
+ {
+ bRemoveParticle = true;
+ continue;
+ }
+
+ particle->m_fSize = size;
}
- particle->m_fSize = size;
-
switch ( psystem->m_nFrictionDecceleration )
{
case 50:
@@ -1238,7 +1565,7 @@ void CParticle::Update()
if ( randVal == 5 )
{
- CShadows::AddPermanentShadow(1, gpBloodPoolTex, &vecPosn,
+ CShadows::AddPermanentShadow(SHADOWTYPE_DARK, gpBloodPoolTex, &vecPosn,
0.1f, 0.0f, 0.0f, -0.1f,
255,
255, 0, 0,
@@ -1246,7 +1573,7 @@ void CParticle::Update()
}
else if ( randVal == 2 )
{
- CShadows::AddPermanentShadow(1, gpBloodPoolTex, &vecPosn,
+ CShadows::AddPermanentShadow(SHADOWTYPE_DARK, gpBloodPoolTex, &vecPosn,
0.2f, 0.0f, 0.0f, -0.2f,
255,
255, 0, 0,
@@ -1264,12 +1591,12 @@ void CParticle::Update()
CColPoint point;
CEntity *entity;
- if ( CWorld::ProcessVerticalLine(particle->m_vecPosition, moveStep.z, point, entity,
+ if ( CWorld::ProcessVerticalLine(particle->m_vecPosition, vecPos.z, point, entity,
true, true, false, false, true, false, nil) )
{
- if ( moveStep.z <= point.point.z )
+ if ( vecPos.z <= point.point.z )
{
- moveStep.z = point.point.z;
+ vecPos.z = point.point.z;
if ( psystem->m_Type == PARTICLE_DEBRIS2 )
{
particle->m_vecVelocity.x *= 0.8f;
@@ -1356,16 +1683,16 @@ void CParticle::Update()
CColPoint point;
CEntity *entity;
- if ( CWorld::ProcessVerticalLine(particle->m_vecPosition, moveStep.z, point, entity,
+ if ( CWorld::ProcessVerticalLine(particle->m_vecPosition, vecPos.z, point, entity,
true, false, false, false, true, false, nil) )
{
- if ( moveStep.z <= point.point.z )
+ if ( vecPos.z <= point.point.z )
{
- moveStep.z = point.point.z;
+ vecPos.z = point.point.z;
if ( psystem->m_Type == PARTICLE_HELI_ATTACK )
{
bRemoveParticle = true;
- AddParticle(PARTICLE_STEAM, moveStep, CVector(0.0f, 0.0f, 0.05f), nil, 0.2f, 0, 0, 0, 0);
+ AddParticle(PARTICLE_STEAM, vecPos, CVector(0.0f, 0.0f, 0.05f), nil, 0.2f, 0, 0, 0, 0);
continue;
}
}
@@ -1374,37 +1701,21 @@ void CParticle::Update()
}
}
- if ( psystem->m_nFadeToBlackAmount != 0 )
+ if ( particle->m_nFadeToBlackTimer != 0 )
{
- if ( particle->m_nFadeToBlackTimer >= psystem->m_nFadeToBlackTime )
- {
- particle->m_nFadeToBlackTimer = 0;
-
- particle->m_nColorIntensity = Clamp(particle->m_nColorIntensity - psystem->m_nFadeToBlackAmount,
+ particle->m_nColorIntensity = Clamp(particle->m_nColorIntensity - particle->m_nFadeToBlackTimer,
0, 255);
- }
- else
- ++particle->m_nFadeToBlackTimer;
}
- if ( psystem->m_nFadeAlphaAmount != 0 )
+ if ( particle->m_nFadeAlphaTimer != 0 )
{
- if ( particle->m_nFadeAlphaTimer >= psystem->m_nFadeAlphaTime )
- {
- particle->m_nFadeAlphaTimer = 0;
-
- particle->m_nAlpha = Clamp(particle->m_nAlpha - psystem->m_nFadeAlphaAmount,
+ particle->m_nAlpha = Clamp(particle->m_nAlpha - particle->m_nFadeAlphaTimer,
0, 255);
-#ifdef PC_PARTICLE
- if ( particle->m_nAlpha == 0 )
- {
- bRemoveParticle = true;
- continue;
- }
-#endif
+ if ( particle->m_nAlpha == 0 )
+ {
+ bRemoveParticle = true;
+ continue;
}
- else
- ++particle->m_nFadeAlphaTimer;
}
if ( psystem->m_nZRotationAngleChangeAmount != 0 )
@@ -1448,31 +1759,28 @@ void CParticle::Update()
}
if ( particle->m_nRotationStep != 0 )
- {
+#ifdef FIX_BUGS
+ particle->m_nRotation = CGeneral::LimitAngle(particle->m_nRotation + particle->m_nRotationStep);
+#else
particle->m_nRotation += particle->m_nRotationStep;
-
- if ( particle->m_nRotation >= 360 )
- particle->m_nRotation -= 360;
- else if ( particle->m_nRotation < 0 )
- particle->m_nRotation += 360;
- }
+#endif
if ( particle->m_fCurrentZRadius != 0.0f )
{
- int32 nRot = particle->m_nCurrentZRotation % (SIN_COS_TABLE_SIZE - 1);
+ int32 nSinCosIndex = particle->m_nCurrentZRotation % SIN_COS_TABLE_SIZE;
- float fX = (Cos(nRot) - Sin(nRot)) * particle->m_fCurrentZRadius;
+ float fX = (Cos(nSinCosIndex) - Sin(nSinCosIndex)) * particle->m_fCurrentZRadius;
- float fY = (Sin(nRot) + Cos(nRot)) * particle->m_fCurrentZRadius;
+ float fY = (Sin(nSinCosIndex) + Cos(nSinCosIndex)) * particle->m_fCurrentZRadius;
- moveStep -= particle->m_vecParticleMovementOffset;
+ vecPos -= particle->m_vecParticleMovementOffset;
- moveStep += CVector(fX, fY, 0.0f);
+ vecPos += CVector(fX, fY, 0.0f);
particle->m_vecParticleMovementOffset = CVector(fX, fY, 0.0f);
}
- particle->m_vecPosition = moveStep;
+ particle->m_vecPosition = vecPos;
}
}
}
@@ -1498,13 +1806,10 @@ void CParticle::Render()
for ( int32 i = 0; i < MAX_PARTICLES; i++ )
{
tParticleSystemData *psystem = &mod_ParticleSystemManager.m_aParticles[i];
-#ifdef PC_PARTICLE
bool particleBanned = false;
-#endif
CParticle *particle = psystem->m_pParticles;
RwRaster **frames = psystem->m_ppRaster;
-#ifdef PC_PARTICLE
tParticleType type = psystem->m_Type;
if ( type == PARTICLE_ENGINE_SMOKE
@@ -1518,7 +1823,6 @@ void CParticle::Render()
{
particleBanned = true;
}
-#endif
if ( particle )
{
@@ -1560,11 +1864,10 @@ void CParticle::Render()
while ( particle != nil )
{
bool canDraw = true;
-#ifdef PC_PARTICLE
if ( particle->m_nAlpha == 0 )
canDraw = false;
-#endif
+
if ( canDraw && psystem->m_nFinalAnimationFrame != 0 && frames != nil )
{
RwRaster *curFrame = frames[particle->m_nCurrentFrame];
@@ -1578,28 +1881,168 @@ void CParticle::Render()
if ( canDraw && psystem->Flags & DRAWTOP2D )
{
- if ( particle->m_nRotation != 0 )
+ float screenZ;
+#ifdef FIX_BUGS
+ bool zIsZero = true;
+ if ( particle->m_vecPosition.z != 0.0f ) {
+#endif
+ screenZ = (particle->m_vecPosition.z - CDraw::GetNearClipZ())
+ * (CSprite::GetFarScreenZ() - CSprite::GetNearScreenZ())
+ * CDraw::GetFarClipZ()
+ / ( (CDraw::GetFarClipZ() - CDraw::GetNearClipZ()) * particle->m_vecPosition.z )
+ + CSprite::GetNearScreenZ();
+#ifdef FIX_BUGS
+ zIsZero = false;
+ }
+#endif
+
+ float stretchTexW;
+ float stretchTexH;
+
+ if ( i == PARTICLE_RAINDROP || i == PARTICLE_RAINDROP_SMALL || i == PARTICLE_RAINDROP_2D )
{
- CSprite::RenderBufferedOneXLUSprite2D_Rotate_Dimension(
- particle->m_vecPosition.x,
- particle->m_vecPosition.y,
- particle->m_fSize * 63.0f,
- particle->m_fSize * 63.0f,
- particle->m_Color,
- particle->m_nColorIntensity,
- (float)particle->m_nRotation, //DEGTORAD((float)particle->m_nRotation) ps2
- particle->m_nAlpha);
+ stretchTexW = CGeneral::GetRandomNumberInRange(0.1f, 1.0f) * psystem->m_vecTextureStretch.x * (float)particle->m_nCurrentFrame + 63.0f;
+ stretchTexH = CGeneral::GetRandomNumberInRange(0.1f, 1.0f) * psystem->m_vecTextureStretch.y * (float)particle->m_nCurrentFrame + 63.0f;
}
else
{
- CSprite::RenderBufferedOneXLUSprite2D(
- particle->m_vecPosition.x,
- particle->m_vecPosition.y,
- particle->m_fSize * 63.0f,
- particle->m_fSize * 63.0f,
- particle->m_Color,
- particle->m_nColorIntensity,
- particle->m_nAlpha);
+ stretchTexW = CGeneral::GetRandomNumberInRange(0.1f, 1.0f) * psystem->m_vecTextureStretch.x + 63.0f;
+ stretchTexH = CGeneral::GetRandomNumberInRange(0.1f, 1.0f) * psystem->m_vecTextureStretch.y + 63.0f;
+ }
+
+#ifdef FIX_BUGS
+ if (!zIsZero) {
+#endif
+
+ if ( i == PARTICLE_WATERDROP )
+ {
+ int32 timeLeft = (particle->m_nTimeWhenWillBeDestroyed - CTimer::GetTimeInMilliseconds()) / particle->m_nTimeWhenWillBeDestroyed;
+
+ stretchTexH += (1.0f - (float)timeLeft ) * psystem->m_vecTextureStretch.y;
+
+ RwRect rect;
+
+ rect.x = int32(particle->m_vecPosition.x - SCREEN_STRETCH_X(particle->m_fSize * stretchTexW));
+ rect.y = int32(particle->m_vecPosition.y - SCREEN_STRETCH_Y(particle->m_fSize * stretchTexH));
+ rect.w = int32(particle->m_vecPosition.x + SCREEN_STRETCH_X(particle->m_fSize * stretchTexW));
+ rect.h = int32(particle->m_vecPosition.y + SCREEN_STRETCH_Y(particle->m_fSize * stretchTexH));
+
+ FxType fxtype;
+
+ if ( particle->m_nCurrentFrame != 0 )
+ fxtype = FXTYPE_WATER2;
+ else
+ fxtype = FXTYPE_WATER1;
+
+ CMBlur::AddRenderFx(Scene.camera, &rect, screenZ, fxtype);
+
+ canDraw = false;
+ }
+
+ if ( i == PARTICLE_BLOODDROP )
+ {
+ int32 timeLeft = (particle->m_nTimeWhenWillBeDestroyed - CTimer::GetTimeInMilliseconds()) / particle->m_nTimeWhenWillBeDestroyed;
+
+ stretchTexH += (1.0f + (float)timeLeft) * psystem->m_vecTextureStretch.y;
+ stretchTexW += (1.0f - (float)timeLeft) * psystem->m_vecTextureStretch.x;
+
+ RwRect rect;
+
+ rect.x = int32(particle->m_vecPosition.x - SCREEN_STRETCH_X(particle->m_fSize * stretchTexW));
+ rect.y = int32(particle->m_vecPosition.y - SCREEN_STRETCH_Y(particle->m_fSize * stretchTexH));
+ rect.w = int32(particle->m_vecPosition.x + SCREEN_STRETCH_X(particle->m_fSize * stretchTexW));
+ rect.h = int32(particle->m_vecPosition.y + SCREEN_STRETCH_Y(particle->m_fSize * stretchTexH));
+
+ FxType fxtype;
+
+ if ( particle->m_nCurrentFrame )
+ fxtype = FXTYPE_BLOOD2;
+ else
+ fxtype = FXTYPE_BLOOD1;
+
+ CMBlur::AddRenderFx(Scene.camera, &rect, screenZ, fxtype);
+
+ canDraw = false;
+ }
+
+ if ( i == PARTICLE_HEATHAZE_IN_DIST )
+ {
+ RwRect rect;
+
+ rect.x = int32(particle->m_vecPosition.x - SCREEN_STRETCH_X(particle->m_fSize * stretchTexW));
+ rect.y = int32(particle->m_vecPosition.y - SCREEN_STRETCH_Y(particle->m_fSize * stretchTexH * 0.15f));
+ rect.w = int32(particle->m_vecPosition.x + SCREEN_STRETCH_X(particle->m_fSize * stretchTexW));
+ rect.h = int32(particle->m_vecPosition.y + SCREEN_STRETCH_Y(particle->m_fSize * stretchTexH * 0.15f));
+
+ CMBlur::AddRenderFx(Scene.camera, &rect, screenZ, FXTYPE_HEATHAZE);
+
+ canDraw = false;
+ }
+
+ if ( i == PARTICLE_HEATHAZE )
+ {
+ RwRect rect;
+
+ switch ( TheCamera.GetLookDirection() )
+ {
+ case LOOKING_LEFT:
+ rect.x = int32(particle->m_vecPosition.x - SCREEN_STRETCH_X(particle->m_fSize * psystem->m_vecTextureStretch.x * 2.0f));
+ rect.y = int32(particle->m_vecPosition.y - SCREEN_STRETCH_Y(particle->m_fSize * psystem->m_vecTextureStretch.y));
+ rect.w = int32(particle->m_vecPosition.x - SCREEN_STRETCH_X(particle->m_fSize * psystem->m_vecTextureStretch.x));
+ rect.h = int32(particle->m_vecPosition.y + SCREEN_STRETCH_Y(particle->m_fSize * psystem->m_vecTextureStretch.y));
+
+ break;
+
+ case LOOKING_RIGHT:
+ rect.x = int32(particle->m_vecPosition.x + SCREEN_STRETCH_X(particle->m_fSize * psystem->m_vecTextureStretch.x));
+ rect.y = int32(particle->m_vecPosition.y - SCREEN_STRETCH_Y(particle->m_fSize * psystem->m_vecTextureStretch.y));
+ rect.w = int32(particle->m_vecPosition.x + SCREEN_STRETCH_X(particle->m_fSize * psystem->m_vecTextureStretch.x * 4.0f));
+ rect.h = int32(particle->m_vecPosition.y + SCREEN_STRETCH_Y(particle->m_fSize * psystem->m_vecTextureStretch.y));
+
+ break;
+
+ default:
+ rect.x = int32(particle->m_vecPosition.x - SCREEN_STRETCH_X(particle->m_fSize * psystem->m_vecTextureStretch.x));
+ rect.y = int32(particle->m_vecPosition.y - SCREEN_STRETCH_Y(particle->m_fSize * psystem->m_vecTextureStretch.y));
+ rect.w = int32(particle->m_vecPosition.x + SCREEN_STRETCH_X(particle->m_fSize * psystem->m_vecTextureStretch.x));
+ rect.h = int32(particle->m_vecPosition.y + SCREEN_STRETCH_Y(particle->m_fSize * psystem->m_vecTextureStretch.y));
+
+ break;
+ }
+
+ CMBlur::AddRenderFx(Scene.camera, &rect, screenZ, FXTYPE_HEATHAZE);
+
+ canDraw = false;
+ }
+#ifdef FIX_BUGS
+ }
+ if ( !(zIsZero && (i == PARTICLE_WATERDROP || i == PARTICLE_BLOODDROP || i == PARTICLE_HEATHAZE_IN_DIST || i == PARTICLE_HEATHAZE) ) )
+#endif
+ if ( canDraw )
+ {
+ if ( particle->m_nRotation != 0 )
+ {
+ CSprite::RenderBufferedOneXLUSprite2D_Rotate_Dimension(
+ particle->m_vecPosition.x,
+ particle->m_vecPosition.y,
+ particle->m_fSize * stretchTexW,
+ particle->m_fSize * stretchTexH,
+ particle->m_Color,
+ particle->m_nColorIntensity,
+ DEGTORAD((float)particle->m_nRotation),
+ particle->m_nAlpha);
+ }
+ else
+ {
+ CSprite::RenderBufferedOneXLUSprite2D(
+ particle->m_vecPosition.x,
+ particle->m_vecPosition.y,
+ particle->m_fSize * stretchTexW,
+ particle->m_fSize * stretchTexH,
+ particle->m_Color,
+ particle->m_nColorIntensity,
+ particle->m_nAlpha);
+ }
}
canDraw = false;
@@ -1613,174 +2056,234 @@ void CParticle::Render()
if ( CSprite::CalcScreenCoors(particle->m_vecPosition, &coors, &w, &h, true) )
{
-#ifdef PC_PARTICLE
- if ( (!particleBanned || SCREEN_WIDTH * fParticleScaleLimit >= w)
- && SCREEN_HEIGHT * fParticleScaleLimit >= h )
-#endif
+
+ if ( i == PARTICLE_ENGINE_STEAM
+ || i == PARTICLE_ENGINE_SMOKE
+ || i == PARTICLE_ENGINE_SMOKE2
+ || i == PARTICLE_CARFLAME_SMOKE
+ || i == PARTICLE_CARCOLLISION_DUST
+ || i == PARTICLE_EXHAUST_FUMES
+ || i == PARTICLE_RUBBER_SMOKE
+ || i == PARTICLE_BURNINGRUBBER_SMOKE )
{
- if ( particle->m_nRotation != 0 )
- {
- CSprite::RenderBufferedOneXLUSprite_Rotate_Dimension(coors.x, coors.y, coors.z,
- particle->m_fSize * w, particle->m_fSize * h,
- particle->m_Color.red,
- particle->m_Color.green,
- particle->m_Color.blue,
- particle->m_nColorIntensity,
- 1.0f / coors.z,
- float(particle->m_nRotation), // DEGTORAD((float)particle->m_nRotation) ps2
- particle->m_nAlpha);
+ switch ( TheCamera.GetLookDirection() )
+ {
+ case LOOKING_LEFT:
+ case LOOKING_RIGHT:
+ w += CGeneral::GetRandomNumberInRange(1.0f, 7.5f) * psystem->m_vecTextureStretch.x;
+ h += CGeneral::GetRandomNumberInRange(0.1f, 1.0f) * psystem->m_vecTextureStretch.y;
+ break;
+
+ default:
+ w += CGeneral::GetRandomNumberInRange(0.1f, 1.0f) * psystem->m_vecTextureStretch.x;
+ h += CGeneral::GetRandomNumberInRange(0.1f, 1.0f) * psystem->m_vecTextureStretch.y;
+ break;
}
- else if ( psystem->Flags & SCREEN_TRAIL )
+ }
+ else if ( i == PARTICLE_WATER_HYDRANT )
+ {
+ int32 timeLeft = (particle->m_nTimeWhenWillBeDestroyed - CTimer::GetTimeInMilliseconds()) / particle->m_nTimeWhenWillBeDestroyed;
+
+ w += (1.0f - (float)timeLeft) * psystem->m_vecTextureStretch.x;
+ h += (1.0f - (float)timeLeft) * psystem->m_vecTextureStretch.y;
+ }
+ else if ( i == PARTICLE_FLYERS )
+ {
+ w += psystem->m_vecTextureStretch.x;
+ h += psystem->m_vecTextureStretch.y;
+
+ w = Max(w, 12.0f);
+ h = Max(h, 12.0f);
+ }
+ else
+ {
+ w += CGeneral::GetRandomNumberInRange(0.1f, 1.0f) * psystem->m_vecTextureStretch.x;
+ h += CGeneral::GetRandomNumberInRange(0.1f, 1.0f) * psystem->m_vecTextureStretch.y;
+ }
+
+ if ( i == PARTICLE_WATER_HYDRANT
+ || (!particleBanned || SCREEN_WIDTH * fParticleScaleLimit >= w)
+ && SCREEN_HEIGHT * fParticleScaleLimit >= h )
+ {
+ if ( i == PARTICLE_WATER_HYDRANT )
{
- float fRotation;
- float fTrailLength;
+ RwRect rect;
- if ( particle->m_vecScreenPosition.x == 0.0f )
+ if ( w > 0.0f )
{
- fTrailLength = 0.0f;
- fRotation = 0.0f;
+ rect.x = int32(coors.x - SCREEN_STRETCH_X(particle->m_fSize * w));
+ rect.w = int32(coors.x + SCREEN_STRETCH_X(particle->m_fSize * w));
}
else
{
- CVector2D vecDist
- (
- coors.x - particle->m_vecScreenPosition.x,
- coors.y - particle->m_vecScreenPosition.y
- );
-
- float fDist = vecDist.Magnitude();
-
- fTrailLength = fDist;
-
- float fRot = Asin(vecDist.x / fDist);
-
- fRotation = fRot;
-
- if ( vecDist.y < 0.0f )
- fRotation = -1.0f * fRot + DEGTORAD(180.0f);
-
- fRotation = RADTODEG(fRotation);
-
- if ( fRotation < 0.0f )
- fRotation += 360.0f;
-
- float fSpeed = particle->m_vecVelocity.Magnitude();
-
- float fNewTrailLength = fSpeed * CTimer::GetTimeStep() * w * 2.0f;
-
- if ( fDist > fNewTrailLength )
- fTrailLength = fNewTrailLength;
+ rect.w = int32(coors.x - SCREEN_STRETCH_X(particle->m_fSize * w));
+ rect.x = int32(coors.x + SCREEN_STRETCH_X(particle->m_fSize * w));
+ }
+
+ if ( h > 0.0f )
+ {
+ rect.y = int32(coors.y - SCREEN_STRETCH_Y(particle->m_fSize * h));
+ rect.h = int32(coors.y + SCREEN_STRETCH_Y(particle->m_fSize * h));
+ }
+ else
+ {
+ rect.h = int32(coors.y - SCREEN_STRETCH_Y(particle->m_fSize * h));
+ rect.y = int32(coors.y + SCREEN_STRETCH_Y(particle->m_fSize * h));
}
- CSprite::RenderBufferedOneXLUSprite_Rotate_Dimension(coors.x, coors.y, coors.z,
- particle->m_fSize * w,
- particle->m_fSize * h + fTrailLength * psystem->m_fTrailLengthMultiplier,
- particle->m_Color.red,
- particle->m_Color.green,
- particle->m_Color.blue,
- particle->m_nColorIntensity,
- 1.0f / coors.z,
- fRotation,
- particle->m_nAlpha);
-
- particle->m_vecScreenPosition = coors;
+ float screenZ = (coors.z - CDraw::GetNearClipZ())
+ * (CSprite::GetFarScreenZ() - CSprite::GetNearScreenZ()) * CDraw::GetFarClipZ()
+ / ( (CDraw::GetFarClipZ() - CDraw::GetNearClipZ()) * coors.z ) + CSprite::GetNearScreenZ();
+
+ CMBlur::AddRenderFx(Scene.camera, &rect, screenZ, FXTYPE_SPLASH1);
}
- else if ( psystem->Flags & SPEED_TRAIL )
+ else
{
- CVector vecPrevPos = particle->m_vecPosition - particle->m_vecVelocity;
- float fRotation;
- float fTrailLength;
-
- if ( CSprite::CalcScreenCoors(vecPrevPos, &particle->m_vecScreenPosition, &fTrailLength, &fRotation, true) )
+ if ( particle->m_nRotation != 0 && i != PARTICLE_BEASTIE )
+ {
+ CSprite::RenderBufferedOneXLUSprite_Rotate_Dimension(coors.x, coors.y, coors.z,
+ particle->m_fSize * w, particle->m_fSize * h,
+ particle->m_Color.red,
+ particle->m_Color.green,
+ particle->m_Color.blue,
+ particle->m_nColorIntensity,
+ 1.0f / coors.z,
+ DEGTORAD((float)particle->m_nRotation),
+ particle->m_nAlpha);
+ }
+ else if ( psystem->Flags & SCREEN_TRAIL )
{
- CVector2D vecDist
- (
- coors.x - particle->m_vecScreenPosition.x,
- coors.y - particle->m_vecScreenPosition.y
- );
-
- float fDist = vecDist.Magnitude();
-
- fTrailLength = fDist;
+ float fRotation;
+ float fTrailLength;
- float fRot = Asin(vecDist.x / fDist);
-
- fRotation = fRot;
+ if ( particle->m_fZGround == 0.0f )
+ {
+ fTrailLength = 0.0f;
+ fRotation = 0.0f;
+ }
+ else
+ {
+ CVector2D vecDist
+ (
+ coors.x - particle->m_fZGround,
+ coors.y - particle->m_fExpansionRate
+ );
+
+ float fDist = vecDist.Magnitude();
+
+ fTrailLength = fDist;
+
+ float fRot = Asin(vecDist.x / fDist);
+
+ fRotation = fRot;
+
+ if ( vecDist.y < 0.0f )
+ fRotation = -1.0f * fRot + DEGTORAD(180.0f);
+
+ float fSpeed = particle->m_vecVelocity.Magnitude();
+
+ float fNewTrailLength = fSpeed * CTimer::GetTimeStep() * w * 2.0f;
+
+ if ( fDist > fNewTrailLength )
+ fTrailLength = fNewTrailLength;
+ }
- if ( vecDist.y < 0.0f )
- fRotation = -1.0f * fRot + DEGTORAD(180.0f);
+ CSprite::RenderBufferedOneXLUSprite_Rotate_Dimension(coors.x, coors.y, coors.z,
+ particle->m_fSize * w,
+ particle->m_fSize * h + fTrailLength * psystem->m_fTrailLengthMultiplier,
+ particle->m_Color.red,
+ particle->m_Color.green,
+ particle->m_Color.blue,
+ particle->m_nColorIntensity,
+ 1.0f / coors.z,
+ fRotation,
+ particle->m_nAlpha);
+
+ particle->m_fZGround = coors.x; // WTF ?
+ particle->m_fExpansionRate = coors.y; // WTF ?
+ }
+ else if ( psystem->Flags & SPEED_TRAIL )
+ {
+ CVector vecPrevPos = particle->m_vecPosition - particle->m_vecVelocity;
+ float fRotation;
+ float fTrailLength;
+ CVector vecScreenPosition;
- fRotation = RADTODEG(fRotation);
+ if ( CSprite::CalcScreenCoors(vecPrevPos, &vecScreenPosition, &fTrailLength, &fRotation, true) )
+ {
+ CVector2D vecDist
+ (
+ coors.x - vecScreenPosition.x,
+ coors.y - vecScreenPosition.y
+ );
+
+ float fDist = vecDist.Magnitude();
+
+ fTrailLength = fDist;
+
+ float fRot = Asin(vecDist.x / fDist);
+
+ fRotation = fRot;
+
+ if ( vecDist.y < 0.0f )
+ fRotation = -1.0f * fRot + DEGTORAD(180.0f);
+ }
+ else
+ {
+ fRotation = 0.0f;
+ fTrailLength = 0.0f;
+ }
- if ( fRotation < 0.0f )
- fRotation += 360.0f;
+ CSprite::RenderBufferedOneXLUSprite_Rotate_Dimension(coors.x, coors.y, coors.z,
+ particle->m_fSize * w,
+ particle->m_fSize * h + fTrailLength * psystem->m_fTrailLengthMultiplier,
+ particle->m_Color.red,
+ particle->m_Color.green,
+ particle->m_Color.blue,
+ particle->m_nColorIntensity,
+ 1.0f / coors.z,
+ fRotation,
+ particle->m_nAlpha);
}
- else
+ else if ( psystem->Flags & VERT_TRAIL )
{
- fRotation = 0.0f;
- fTrailLength = 0.0f;
+ float fTrailLength = fabsf(particle->m_vecVelocity.z * 10.0f);
+
+ CSprite::RenderBufferedOneXLUSprite(coors.x, coors.y, coors.z,
+ particle->m_fSize * w,
+ (particle->m_fSize + fTrailLength * psystem->m_fTrailLengthMultiplier) * h,
+ particle->m_Color.red,
+ particle->m_Color.green,
+ particle->m_Color.blue,
+ particle->m_nColorIntensity,
+ 1.0f / coors.z,
+ particle->m_nAlpha);
+ }
+ else if ( i == PARTICLE_RAINDROP_SMALL )
+ {
+ CSprite::RenderBufferedOneXLUSprite(coors.x, coors.y, coors.z,
+ particle->m_fSize * w * 0.05f,
+ particle->m_fSize * h,
+ particle->m_Color.red,
+ particle->m_Color.green,
+ particle->m_Color.blue,
+ particle->m_nColorIntensity,
+ 1.0f / coors.z,
+ particle->m_nAlpha);
+ }
+ /*else if ( i == PARTICLE_BOAT_WAKE )*/
+ else
+ {
+ CSprite::RenderBufferedOneXLUSprite(coors.x, coors.y, coors.z,
+ particle->m_fSize * w,
+ particle->m_fSize * h,
+ particle->m_Color.red,
+ particle->m_Color.green,
+ particle->m_Color.blue,
+ particle->m_nColorIntensity,
+ 1.0f / coors.z,
+ particle->m_nAlpha);
}
-
- CSprite::RenderBufferedOneXLUSprite_Rotate_Dimension(coors.x, coors.y, coors.z,
- particle->m_fSize * w,
- particle->m_fSize * h + fTrailLength * psystem->m_fTrailLengthMultiplier,
- particle->m_Color.red,
- particle->m_Color.green,
- particle->m_Color.blue,
- particle->m_nColorIntensity,
- 1.0f / coors.z,
- fRotation,
- particle->m_nAlpha);
- }
- else if ( psystem->Flags & VERT_TRAIL )
- {
- float fTrailLength = fabsf(particle->m_vecVelocity.z * 10.0f);
-
- CSprite::RenderBufferedOneXLUSprite(coors.x, coors.y, coors.z,
- particle->m_fSize * w,
- (particle->m_fSize + fTrailLength * psystem->m_fTrailLengthMultiplier) * h,
- particle->m_Color.red,
- particle->m_Color.green,
- particle->m_Color.blue,
- particle->m_nColorIntensity,
- 1.0f / coors.z,
- particle->m_nAlpha);
- }
- else if ( i == PARTICLE_RAINDROP_SMALL )
- {
- CSprite::RenderBufferedOneXLUSprite(coors.x, coors.y, coors.z,
- particle->m_fSize * w * 0.05f,
- particle->m_fSize * h,
- particle->m_Color.red,
- particle->m_Color.green,
- particle->m_Color.blue,
- particle->m_nColorIntensity,
- 1.0f / coors.z,
- particle->m_nAlpha);
- }
- else if ( i == PARTICLE_BOAT_WAKE )
- {
- CSprite::RenderBufferedOneXLUSprite(coors.x, coors.y, coors.z,
- particle->m_fSize * w,
- psystem->m_fDefaultInitialRadius * h,
- particle->m_Color.red,
- particle->m_Color.green,
- particle->m_Color.blue,
- particle->m_nColorIntensity,
- 1.0f / coors.z,
- particle->m_nAlpha);
- }
- else
- {
- CSprite::RenderBufferedOneXLUSprite(coors.x, coors.y, coors.z,
- particle->m_fSize * w,
- particle->m_fSize * h,
- particle->m_Color.red,
- particle->m_Color.green,
- particle->m_Color.blue,
- particle->m_nColorIntensity,
- 1.0f / coors.z,
- particle->m_nAlpha);
}
}
}
@@ -1812,6 +2315,9 @@ void CParticle::RemovePSystem(tParticleType type)
void CParticle::RemoveParticle(CParticle *pParticle, CParticle *pPrevParticle, tParticleSystemData *pPSystemData)
{
+ if ( pPSystemData->m_Type == PARTICLE_WATERDROP )
+ --numWaterDropOnScreen;
+
if ( pPrevParticle )
pPrevParticle->m_pNext = pParticle->m_pNext;
else
@@ -1900,3 +2406,129 @@ void CParticle::AddYardieDoorSmoke(CVector const &vecPos, CMatrix const &matMatr
0.3f, color, 0, 0, 0, 0);
}
}
+
+void CParticle::CalWindDir(CVector *vecDirIn, CVector *vecDirOut)
+{
+ vecDirOut->x = (Cos(128) * vecDirIn->x) + (Sin(128) * vecDirIn->y);
+
+ vecDirOut->x = (Cos(128) * vecDirIn->x) + (Sin(128) * vecDirIn->y) * CWeather::Wind;
+ vecDirOut->y = (Sin(128) * vecDirIn->x) - (Cos(128) * vecDirIn->y) * CWeather::Wind;
+}
+
+void CParticle::HandleShipsAtHorizonStuff()
+{
+ tParticleSystemData *psystemdata = &mod_ParticleSystemManager.m_aParticles[PARTICLE_SHIP_SIDE];
+
+ for ( CParticle *particle = psystemdata->m_pParticles; particle; particle = particle->m_pNext )
+ {
+ if ( CTimer::GetTimeInMilliseconds() > particle->m_nTimeWhenWillBeDestroyed - 32000
+ && CTimer::GetTimeInMilliseconds() < particle->m_nTimeWhenWillBeDestroyed - 22000 )
+ {
+ particle->m_nAlpha = Min(particle->m_nAlpha + 1, 96);
+ }
+ if ( CTimer::GetTimeInMilliseconds() > particle->m_nTimeWhenWillBeDestroyed - 10000 )
+ particle->m_nFadeAlphaTimer = 1;
+ }
+}
+
+void CParticle::HandleShootableBirdsStuff(CEntity *entity, CVector const&camPos)
+{
+ float fHeadingRad = entity->GetForward().Heading();
+ float fHeading = RADTODEG(fHeadingRad);
+ float fBirdAngle = ::Cos(DEGTORAD(1.5f));
+
+ tParticleSystemData *psystem = &mod_ParticleSystemManager.m_aParticles[PARTICLE_BIRD_FRONT];
+ CParticle *particle = psystem->m_pParticles;
+ CParticle *prevParticle = nil;
+ bool bRemoveParticle;
+
+ for ( ; particle != nil; _Next(particle, prevParticle, psystem, bRemoveParticle) )
+ {
+ bRemoveParticle = false;
+
+ CVector2D vecPos(particle->m_vecPosition.x, particle->m_vecPosition.y);
+ CVector2D vecCamPos(camPos.x, camPos.y);
+
+ CVector2D vecDist = vecPos - vecCamPos;
+ vecDist.Normalise();
+
+ float fHead = DEGTORAD(fHeading);
+
+ CVector2D vecDir(-::Sin(fHead), ::Cos(fHead));
+ vecDir.Normalise();
+
+ float fDot = DotProduct2D(vecDir, vecDist);
+
+ if ( fDot > 0.0f && fDot > fBirdAngle )
+ {
+ if ( (camPos - particle->m_vecPosition).MagnitudeSqr() < 40000.0f )
+ {
+ CStats::SeagullsKilled++;
+
+ bRemoveParticle = true;
+
+ for ( int32 i = 0; i < 8; i++ )
+ {
+ CParticle *pBirdDerbis = AddParticle(PARTICLE_BIRD_DEBRIS,
+ particle->m_vecPosition,
+ CVector
+ (
+ CGeneral::GetRandomNumberInRange(-3.0f, 3.0f),
+ CGeneral::GetRandomNumberInRange(-3.0f, 3.0f),
+ CGeneral::GetRandomNumberInRange(-3.0f, 3.0f)
+ ),
+ nil,
+ 0.3f,
+ particle->m_Color,
+ CGeneral::GetRandomNumberInRange(20, 40),
+ 0,
+ CGeneral::GetRandomNumber() & 3,
+ 200);
+ if ( pBirdDerbis )
+ pBirdDerbis->m_nAlpha = particle->m_nAlpha;
+ }
+ }
+ }
+ }
+
+}
+
+void
+CEntity::AddSteamsFromGround(CVector *unused)
+{
+ int i, n;
+ C2dEffect *effect;
+ CVector pos;
+
+ n = CModelInfo::GetModelInfo(GetModelIndex())->GetNum2dEffects();
+ for(i = 0; i < n; i++){
+ effect = CModelInfo::GetModelInfo(GetModelIndex())->Get2dEffect(i);
+ if(effect->type != EFFECT_PARTICLE)
+ continue;
+
+ pos = GetMatrix() * effect->pos;
+ switch(effect->particle.particleType){
+ case 0:
+ CParticleObject::AddObject(POBJECT_PAVEMENT_STEAM, pos, effect->particle.dir, effect->particle.scale, false);
+ break;
+ case 1:
+ CParticleObject::AddObject(POBJECT_WALL_STEAM, pos, effect->particle.dir, effect->particle.scale, false);
+ break;
+ case 2:
+ CParticleObject::AddObject(POBJECT_DRY_ICE, pos, effect->particle.scale, false);
+ break;
+ case 3:
+ CParticleObject::AddObject(POBJECT_SMALL_FIRE, pos, effect->particle.dir, effect->particle.scale, false);
+ break;
+ case 4:
+ CParticleObject::AddObject(POBJECT_DARK_SMOKE, pos, effect->particle.dir, effect->particle.scale, false);
+ break;
+ 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;
+ }
+ }
+}
diff --git a/src/renderer/Particle.h b/src/renderer/Particle.h
index 7f02e318..5542dc02 100644
--- a/src/renderer/Particle.h
+++ b/src/renderer/Particle.h
@@ -15,25 +15,24 @@ public:
CVector m_vecPosition;
CVector m_vecVelocity;
- CVector m_vecScreenPosition;
- uint32 m_nTimeWhenWillBeDestroyed;
- uint32 m_nTimeWhenColorWillBeChanged;
+ uint32 m_nTimeWhenWillBeDestroyed;
+ uint32 m_nTimeWhenColorWillBeChanged;
float m_fZGround;
CVector m_vecParticleMovementOffset;
int16 m_nCurrentZRotation;
- uint16 m_nZRotationTimer;
+ uint16 m_nZRotationTimer;
float m_fCurrentZRadius;
- uint16 m_nZRadiusTimer;
- float m_fSize;
- float m_fExpansionRate;
- uint16 m_nFadeToBlackTimer;
- uint16 m_nFadeAlphaTimer;
+ uint16 m_nZRadiusTimer;
uint8 m_nColorIntensity;
uint8 m_nAlpha;
- uint16 m_nCurrentFrame;
+ float m_fSize;
+ float m_fExpansionRate;
+ int16 m_nFadeToBlackTimer;
+ int16 m_nFadeAlphaTimer;
int16 m_nAnimationSpeedTimer;
int16 m_nRotationStep;
int16 m_nRotation;
+ uint8 m_nCurrentFrame;
RwRGBA m_Color;
CParticle *m_pNext;
@@ -60,8 +59,11 @@ public:
static void Initialise();
static void Shutdown();
- static CParticle *AddParticle(tParticleType type, CVector const &vecPos, CVector const &vecDir, CEntity *pEntity = nil, float fSize = 0.0f, int32 nRotationSpeed = 0, int32 nRotation = 0, int32 nCurFrame = 0, int32 nLifeSpan = 0);
- static CParticle *AddParticle(tParticleType type, CVector const &vecPos, CVector const &vecDir, CEntity *pEntity, float fSize, RwRGBA const &color, int32 nRotationSpeed = 0, int32 nRotation = 0, int32 nCurFrame = 0, int32 nLifeSpan = 0);
+ static void AddParticlesAlongLine(tParticleType type, CVector const &vecStart, CVector const &vecEnd, CVector const &vecDir, float fPower, CEntity *pEntity = nil, float fSize = 0.0f, int32 nRotationSpeed = 0, int32 nRotation = 0, int32 nCurFrame = 0, int32 nLifeSpan = 0);
+ static void AddParticlesAlongLine(tParticleType type, CVector const &vecStart, CVector const &vecEnd, CVector const &vecDir, float fPower, CEntity *pEntity, float fSize, RwRGBA const&color, int32 nRotationSpeed = 0, int32 nRotation = 0, int32 nCurFrame = 0, int32 nLifeSpan = 0);
+
+ static CParticle *AddParticle(tParticleType type, CVector const &vecPos, CVector const &vecDir, CEntity *pEntity = nil, float fSize = 0.0f, int32 nRotationSpeed = 0, int32 nRotation = 0, int32 nCurFrame = 0, int32 nLifeSpan = 0);
+ static CParticle *AddParticle(tParticleType type, CVector const &vecPos, CVector const &vecDir, CEntity *pEntity, float fSize, RwRGBA const &color, int32 nRotationSpeed = 0, int32 nRotation = 0, int32 nCurFrame = 0, int32 nLifeSpan = 0);
static void Update();
static void Render();
@@ -89,6 +91,18 @@ public:
static void AddJetExplosion(CVector const &vecPos, float fPower, float fSize);
static void AddYardieDoorSmoke(CVector const &vecPos, CMatrix const &matMatrix);
+ static void CalWindDir(CVector *vecDirIn, CVector *vecDirOut);
+
+ static void HandleShipsAtHorizonStuff();
+ static void HandleShootableBirdsStuff(CEntity *entity, CVector const&camPos);
};
-VALIDATE_SIZE(CParticle, 0x68);
+extern bool clearWaterDrop;
+extern int32 numWaterDropOnScreen;
+extern RwRaster *gpCarSplashRaster[];
+extern RwRaster *gpHeatHazeRaster;
+extern RwRaster *gpDotRaster;
+extern RwRaster *gpRainDripRaster[];
+extern RwRaster *gpRainDripDarkRaster[];
+
+VALIDATE_SIZE(CParticle, 0x58);
diff --git a/src/renderer/ParticleMgr.cpp b/src/renderer/ParticleMgr.cpp
index 3387d471..f6919435 100644
--- a/src/renderer/ParticleMgr.cpp
+++ b/src/renderer/ParticleMgr.cpp
@@ -216,6 +216,18 @@ void cParticleSystemMgr::LoadParticleData()
case CFG_PARAM_TRAIL_LENGTH_MULTIPLIER:
entry->m_fTrailLengthMultiplier = atof(value);
break;
+
+ case CFG_PARAM_STRETCH_VALUE_X:
+ entry->m_vecTextureStretch.x = atof(value);
+ break;
+
+ case CFG_PARAM_STRETCH_VALUE_Y:
+ entry->m_vecTextureStretch.y = atof(value);
+ break;
+
+ case CFG_PARAM_WIND_FACTOR:
+ entry->m_fWindFactor = atof(value);
+ break;
case CFG_PARAM_PARTICLE_CREATE_RANGE:
entry->m_fCreateRange = SQR(atof(value));
diff --git a/src/renderer/ParticleMgr.h b/src/renderer/ParticleMgr.h
index 0100bb65..f4afc018 100644
--- a/src/renderer/ParticleMgr.h
+++ b/src/renderer/ParticleMgr.h
@@ -36,14 +36,14 @@ struct tParticleSystemData
uint16 m_nZRadiusChangeTime;
float m_fInitialZRadius;
float m_fZRadiusChangeAmount;
- uint16 m_nFadeToBlackTime;
- int16 m_nFadeToBlackAmount;
+ int16 m_nFadeToBlackTime;
uint8 m_nFadeToBlackInitialIntensity;
+ int16 m_nFadeToBlackAmount;
uint8 m_nFadeAlphaInitialIntensity;
- uint16 m_nFadeAlphaTime;
+ int16 m_nFadeAlphaTime;
int16 m_nFadeAlphaAmount;
- uint16 m_nStartAnimationFrame;
- uint16 m_nFinalAnimationFrame;
+ uint8 m_nStartAnimationFrame;
+ uint8 m_nFinalAnimationFrame;
uint16 m_nAnimationSpeed;
uint16 m_nRotationSpeed;
float m_fGravitationalAcceleration;
@@ -56,16 +56,19 @@ struct tParticleSystemData
uint32 m_nLifeSpanErrorShape;
float m_fTrailLengthMultiplier;
uint32 Flags;
- RwRGBA m_RenderColouring;
+ CRGBA m_RenderColouring;
uint8 m_InitialColorVariation;
- RwRGBA m_FadeDestinationColor;
+ CRGBA m_FadeDestinationColor;
uint32 m_ColorFadeTime;
+
+ CVector2D m_vecTextureStretch;
+ float m_fWindFactor;
RwRaster **m_ppRaster;
CParticle *m_pParticles;
};
-VALIDATE_SIZE(tParticleSystemData, 0x88);
+VALIDATE_SIZE(tParticleSystemData, 0x94);
class cParticleSystemMgr
{
@@ -107,6 +110,11 @@ class cParticleSystemMgr
CFG_PARAM_ROTATION_RATE_ERROR,
CFG_PARAM_LIFE_SPAN_ERROR_SHAPE,
CFG_PARAM_TRAIL_LENGTH_MULTIPLIER,
+
+ CFG_PARAM_STRETCH_VALUE_X,
+ CFG_PARAM_STRETCH_VALUE_Y,
+ CFG_PARAM_WIND_FACTOR,
+
CFG_PARAM_PARTICLE_CREATE_RANGE,
CFG_PARAM_FLAGS,
@@ -125,6 +133,6 @@ public:
void RangeCheck(tParticleSystemData *pData) { }
};
-VALIDATE_SIZE(cParticleSystemMgr, 0x2420);
+VALIDATE_SIZE(cParticleSystemMgr, 0x2FFC);
extern cParticleSystemMgr mod_ParticleSystemManager;
diff --git a/src/renderer/ParticleType.h b/src/renderer/ParticleType.h
index 8d352c44..9578083d 100644
--- a/src/renderer/ParticleType.h
+++ b/src/renderer/ParticleType.h
@@ -4,13 +4,16 @@ enum tParticleType
{
PARTICLE_SPARK = 0,
PARTICLE_SPARK_SMALL,
+ PARTICLE_WATER_SPARK,
PARTICLE_WHEEL_DIRT,
+ PARTICLE_SAND,
PARTICLE_WHEEL_WATER,
PARTICLE_BLOOD,
PARTICLE_BLOOD_SMALL,
PARTICLE_BLOOD_SPURT,
PARTICLE_DEBRIS,
PARTICLE_DEBRIS2,
+ PARTICLE_FLYERS,
PARTICLE_WATER,
PARTICLE_FLAME,
PARTICLE_FIREBALL,
@@ -18,8 +21,11 @@ enum tParticleType
PARTICLE_GUNFLASH_NOANIM,
PARTICLE_GUNSMOKE,
PARTICLE_GUNSMOKE2,
+ PARTICLE_CIGARETTE_SMOKE,
PARTICLE_SMOKE,
PARTICLE_SMOKE_SLOWMOTION,
+ PARTICLE_DRY_ICE,
+ PARTICLE_TEARGAS,
PARTICLE_GARAGEPAINT_SPRAY,
PARTICLE_SHARD,
PARTICLE_SPLASH,
@@ -28,6 +34,7 @@ enum tParticleType
PARTICLE_STEAM2,
PARTICLE_STEAM_NY,
PARTICLE_STEAM_NY_SLOWMOTION,
+ PARTICLE_GROUND_STEAM,
PARTICLE_ENGINE_STEAM,
PARTICLE_RAINDROP,
PARTICLE_RAINDROP_SMALL,
@@ -35,6 +42,8 @@ enum tParticleType
PARTICLE_RAIN_SPLASH_BIGGROW,
PARTICLE_RAIN_SPLASHUP,
PARTICLE_WATERSPRAY,
+ PARTICLE_WATERDROP,
+ PARTICLE_BLOODDROP,
PARTICLE_EXPLOSION_MEDIUM,
PARTICLE_EXPLOSION_LARGE,
PARTICLE_EXPLOSION_MFAST,
@@ -42,12 +51,12 @@ enum tParticleType
PARTICLE_CAR_SPLASH,
PARTICLE_BOAT_SPLASH,
PARTICLE_BOAT_THRUSTJET,
- PARTICLE_BOAT_WAKE,
PARTICLE_WATER_HYDRANT,
PARTICLE_WATER_CANNON,
PARTICLE_EXTINGUISH_STEAM,
PARTICLE_PED_SPLASH,
PARTICLE_PEDFOOT_DUST,
+ PARTICLE_CAR_DUST,
PARTICLE_HELI_DUST,
PARTICLE_HELI_ATTACK,
PARTICLE_ENGINE_SMOKE,
@@ -58,6 +67,7 @@ enum tParticleType
PARTICLE_TREE_LEAVES,
PARTICLE_CARCOLLISION_DUST,
PARTICLE_CAR_DEBRIS,
+ PARTICLE_BIRD_DEBRIS,
PARTICLE_HELI_DEBRIS,
PARTICLE_EXHAUST_FUMES,
PARTICLE_RUBBER_SMOKE,
@@ -67,11 +77,16 @@ enum tParticleType
PARTICLE_GUNSHELL,
PARTICLE_GUNSHELL_BUMP1,
PARTICLE_GUNSHELL_BUMP2,
+ PARTICLE_ROCKET_SMOKE,
PARTICLE_TEST,
PARTICLE_BIRD_FRONT,
+ PARTICLE_SHIP_SIDE,
+ PARTICLE_BEASTIE,
PARTICLE_RAINDROP_2D,
+ PARTICLE_HEATHAZE,
+ PARTICLE_HEATHAZE_IN_DIST,
MAX_PARTICLES,
PARTICLE_FIRST = PARTICLE_SPARK,
- PARTICLE_LAST = PARTICLE_RAINDROP_2D
+ PARTICLE_LAST = PARTICLE_HEATHAZE_IN_DIST
}; \ No newline at end of file
diff --git a/src/renderer/PlayerSkin.cpp b/src/renderer/PlayerSkin.cpp
index f0fae45a..ee944ca7 100644
--- a/src/renderer/PlayerSkin.cpp
+++ b/src/renderer/PlayerSkin.cpp
@@ -74,6 +74,7 @@ LoadPlayerDff(void)
void
CPlayerSkin::Initialise(void)
{
+ // empty on PS2
m_txdSlot = CTxdStore::AddTxdSlot("skin");
CTxdStore::Create(m_txdSlot);
CTxdStore::AddRef(m_txdSlot);
@@ -82,6 +83,7 @@ CPlayerSkin::Initialise(void)
void
CPlayerSkin::Shutdown(void)
{
+ // empty on PS2
CTxdStore::RemoveTxdSlot(m_txdSlot);
}
@@ -98,7 +100,7 @@ CPlayerSkin::GetSkinTexture(const char *texName)
CTxdStore::PopCurrentTxd();
if (tex != nil) return tex;
- if (strcmp(DEFAULT_SKIN_NAME, texName) == 0)
+ if (strcmp(DEFAULT_SKIN_NAME, texName) == 0 || texName[0] == '\0')
sprintf(gString, "models\\generic\\player.bmp");
else
sprintf(gString, "skins\\%s.bmp", texName);
@@ -110,9 +112,7 @@ CPlayerSkin::GetSkinTexture(const char *texName)
tex = RwTextureCreate(raster);
RwTextureSetName(tex, texName);
-#ifdef FIX_BUGS
- RwTextureSetFilterMode(tex, rwFILTERLINEAR); // filtering bugfix from VC
-#endif
+ RwTextureSetFilterMode(tex, rwFILTERLINEAR);
RwTexDictionaryAddTexture(CTxdStore::GetSlot(m_txdSlot)->texDict, tex);
RwImageDestroy(image);
@@ -144,8 +144,7 @@ CPlayerSkin::RenderFrontendSkinEdit(void)
static float rotation = 0.0f;
RwRGBAReal AmbientColor = { 0.65f, 0.65f, 0.65f, 1.0f };
const RwV3d pos = { 1.35f, 0.35f, 7.725f };
- const RwV3d axis1 = { 1.0f, 0.0f, 0.0f };
- const RwV3d axis2 = { 0.0f, 0.0f, 1.0f };
+ const RwV3d axis = { 0.0f, 1.0f, 0.0f };
static uint32 LastFlash = 0;
RwFrame *frame = RpClumpGetFrame(gpPlayerClump);
@@ -158,8 +157,7 @@ CPlayerSkin::RenderFrontendSkinEdit(void)
}
RwFrameTransform(frame, RwFrameGetMatrix(RwCameraGetFrame(Scene.camera)), rwCOMBINEREPLACE);
RwFrameTranslate(frame, &pos, rwCOMBINEPRECONCAT);
- RwFrameRotate(frame, &axis1, -90.0f, rwCOMBINEPRECONCAT);
- RwFrameRotate(frame, &axis2, rotation, rwCOMBINEPRECONCAT);
+ RwFrameRotate(frame, &axis, rotation, rwCOMBINEPRECONCAT);
RwFrameUpdateObjects(frame);
SetAmbientColours(&AmbientColor);
RpClumpRender(gpPlayerClump);
diff --git a/src/renderer/PointLights.cpp b/src/renderer/PointLights.cpp
index 84ac4ab2..13872401 100644
--- a/src/renderer/PointLights.cpp
+++ b/src/renderer/PointLights.cpp
@@ -1,6 +1,7 @@
#include "common.h"
#include "main.h"
+#include "CutsceneMgr.h"
#include "Lights.h"
#include "Camera.h"
#include "Weather.h"
@@ -12,6 +13,19 @@
int16 CPointLights::NumLights;
CRegisteredPointLight CPointLights::aLights[NUMPOINTLIGHTS];
+CVector CPointLights::aCachedMapReads[32];
+float CPointLights::aCachedMapReadResults[32];
+int32 CPointLights::NextCachedValue;
+
+void
+CPointLights::Init(void)
+{
+ for(int i = 0; i < ARRAY_SIZE(aCachedMapReads); i++){
+ aCachedMapReads[i] = CVector(0.0f, 0.0f, 0.0f);
+ aCachedMapReadResults[i] = 0.0f;
+ }
+ NextCachedValue = 0;
+}
void
CPointLights::InitPerFrame(void)
@@ -142,6 +156,9 @@ CPointLights::RenderFogEffect(void)
CVector spriteCoors;
float spritew, spriteh;
+ if(CCutsceneMgr::IsRunning())
+ return;
+
PUSH_RENDERGROUP("CPointLights::RenderFogEffect");
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
@@ -150,6 +167,8 @@ CPointLights::RenderFogEffect(void)
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpPointlightRaster);
+ CSprite::InitSpriteBuffer();
+
for(i = 0; i < NumLights; i++){
if(aLights[i].fogType != FOG_NORMAL && aLights[i].fogType != FOG_ALWAYS)
continue;
@@ -220,10 +239,10 @@ CPointLights::RenderFogEffect(void)
// more intensity the closer to line
intensity *= 1.0f - sq(Sqrt(linedistsq) / FOG_AREA_WIDTH);
- if(CSprite::CalcScreenCoors(fogcoors, &spriteCoors, &spritew, &spriteh, true)){
+ if(CSprite::CalcScreenCoors(fogcoors, &spriteCoors, &spritew, &spriteh, true)) {
float rotation = (CTimer::GetTimeInMilliseconds()&0x1FFF) * 2*3.14f / 0x2000;
float size = FogSizes[r>>1];
- CSprite::RenderOneXLUSprite_Rotate_Aspect(spriteCoors.x, spriteCoors.y, spriteCoors.z,
+ CSprite::RenderBufferedOneXLUSprite_Rotate_Aspect(spriteCoors.x, spriteCoors.y, spriteCoors.z,
spritew * size, spriteh * size,
aLights[i].red * intensity, aLights[i].green * intensity, aLights[i].blue * intensity,
intensity, 1/spriteCoors.z, rotation, 255);
@@ -235,9 +254,8 @@ CPointLights::RenderFogEffect(void)
}
}else if(aLights[i].type == LIGHT_POINT || aLights[i].type == LIGHT_FOGONLY || aLights[i].type == LIGHT_FOGONLY_ALWAYS){
- if(CWorld::ProcessVerticalLine(aLights[i].coors, aLights[i].coors.z - 20.0f,
- point, entity, true, false, false, false, true, false, nil)){
-
+ float groundZ;
+ if(ProcessVerticalLineUsingCache(aLights[i].coors, &groundZ)){
xmin = aLights[i].coors.x - FOG_AREA_RADIUS;
ymin = aLights[i].coors.y - FOG_AREA_RADIUS;
xmax = aLights[i].coors.x + FOG_AREA_RADIUS;
@@ -268,11 +286,11 @@ CPointLights::RenderFogEffect(void)
// more intensity the closer to light source
intensity *= 1.0f - sq(lightdist / FOG_AREA_RADIUS);
- CVector fogcoors(xi, yi, point.point.z + 1.6f);
- if(CSprite::CalcScreenCoors(fogcoors, &spriteCoors, &spritew, &spriteh, true)){
+ CVector fogcoors(xi, yi, groundZ + 1.6f);
+ if(CSprite::CalcScreenCoors(fogcoors, &spriteCoors, &spritew, &spriteh, true)) {
float rotation = (CTimer::GetTimeInMilliseconds()&0x3FFF) * 2*3.14f / 0x4000;
float size = FogSizes[r>>1];
- CSprite::RenderOneXLUSprite_Rotate_Aspect(spriteCoors.x, spriteCoors.y, spriteCoors.z,
+ CSprite::RenderBufferedOneXLUSprite_Rotate_Aspect(spriteCoors.x, spriteCoors.y, spriteCoors.z,
spritew * size, spriteh * size,
aLights[i].red * intensity, aLights[i].green * intensity, aLights[i].blue * intensity,
intensity, 1/spriteCoors.z, rotation, 255);
@@ -285,5 +303,28 @@ CPointLights::RenderFogEffect(void)
}
}
+ CSprite::FlushSpriteBuffer();
+
POP_RENDERGROUP();
}
+
+bool
+CPointLights::ProcessVerticalLineUsingCache(CVector coors, float *groundZ)
+{
+ for(int i = 0; i < ARRAY_SIZE(aCachedMapReads); i++)
+ if(aCachedMapReads[i] == coors){
+ *groundZ = aCachedMapReadResults[i];
+ return true;
+ }
+
+ CColPoint point;
+ CEntity *entity;
+ if(CWorld::ProcessVerticalLine(coors, coors.z - 20.0f, point, entity, true, false, false, false, true, false, nil)){
+ aCachedMapReads[NextCachedValue] = coors;
+ aCachedMapReadResults[NextCachedValue] = point.point.z;
+ NextCachedValue = (NextCachedValue+1) % ARRAY_SIZE(aCachedMapReads);
+ *groundZ = point.point.z;
+ return true;
+ }
+ return false;
+}
diff --git a/src/renderer/PointLights.h b/src/renderer/PointLights.h
index 9e94328f..827200b9 100644
--- a/src/renderer/PointLights.h
+++ b/src/renderer/PointLights.h
@@ -20,6 +20,9 @@ class CPointLights
public:
static int16 NumLights;
static CRegisteredPointLight aLights[NUMPOINTLIGHTS];
+ static CVector aCachedMapReads[32];
+ static float aCachedMapReadResults[32];
+ static int32 NextCachedValue;
enum {
LIGHT_POINT,
@@ -37,9 +40,11 @@ public:
FOG_ALWAYS
};
+ static void Init(void);
static void InitPerFrame(void);
static void AddLight(uint8 type, CVector coors, CVector dir, float radius, float red, float green, float blue, uint8 fogType, bool castExtraShadows);
static float GenerateLightsAffectingObject(Const CVector *objCoors);
static void RemoveLightsAffectingObject(void);
static void RenderFogEffect(void);
+ static bool ProcessVerticalLineUsingCache(CVector coors, float *groundZ);
};
diff --git a/src/renderer/RenderBuffer.cpp b/src/renderer/RenderBuffer.cpp
index 6120dfe2..687cc76b 100644
--- a/src/renderer/RenderBuffer.cpp
+++ b/src/renderer/RenderBuffer.cpp
@@ -5,7 +5,7 @@
int32 TempBufferVerticesStored;
int32 TempBufferIndicesStored;
-RwIm3DVertex TempBufferRenderVertices[TEMPBUFFERVERTSIZE];
+VertexBufferUnion TempVertexBuffer;
RwImVertexIndex TempBufferRenderIndexList[TEMPBUFFERINDEXSIZE];
int RenderBuffer::VerticesToBeStored;
diff --git a/src/renderer/RenderBuffer.h b/src/renderer/RenderBuffer.h
index 485d24e3..a0f3e7b9 100644
--- a/src/renderer/RenderBuffer.h
+++ b/src/renderer/RenderBuffer.h
@@ -9,10 +9,17 @@ public:
static void RenderStuffInBuffer(void);
};
-#define TEMPBUFFERVERTSIZE 256
+#define TEMPBUFFERVERTSIZE 512
#define TEMPBUFFERINDEXSIZE 1024
+struct VertexBufferUnion
+{
+ RwIm2DVertex im2d[TEMPBUFFERVERTSIZE];
+ RwIm3DVertex im3d[TEMPBUFFERVERTSIZE];
+};
+
extern int32 TempBufferVerticesStored;
extern int32 TempBufferIndicesStored;
-extern RwIm3DVertex TempBufferRenderVertices[TEMPBUFFERVERTSIZE];
+extern VertexBufferUnion TempVertexBuffer;
+#define TempBufferRenderVertices (TempVertexBuffer.im3d)
extern RwImVertexIndex TempBufferRenderIndexList[TEMPBUFFERINDEXSIZE]; \ No newline at end of file
diff --git a/src/renderer/Renderer.cpp b/src/renderer/Renderer.cpp
index 334f3954..96e3a329 100644
--- a/src/renderer/Renderer.cpp
+++ b/src/renderer/Renderer.cpp
@@ -9,6 +9,7 @@
#include "Vehicle.h"
#include "Boat.h"
#include "Heli.h"
+#include "Bike.h"
#include "Object.h"
#include "PathFind.h"
#include "Collision.h"
@@ -20,17 +21,17 @@
#include "Streaming.h"
#include "Shadows.h"
#include "PointLights.h"
+#include "Occlusion.h"
#include "Renderer.h"
-#include "Frontend.h"
#include "custompipes.h"
-#include "Debug.h"
+#include "Frontend.h"
bool gbShowPedRoadGroups;
bool gbShowCarRoadGroups;
bool gbShowCollisionPolys;
+bool gbShowCollisionPolysReflections;
+bool gbShowCollisionPolysNoShadows;
bool gbShowCollisionLines;
-bool gbShowCullZoneDebugStuff;
-bool gbDisableZoneCull; // not original
bool gbBigWhiteDebugLightSwitchedOn;
bool gbDontRenderBuildings;
@@ -39,21 +40,6 @@ bool gbDontRenderPeds;
bool gbDontRenderObjects;
bool gbDontRenderVehicles;
-int32 EntitiesRendered;
-int32 EntitiesNotRendered;
-int32 RenderedBigBuildings;
-int32 RenderedBuildings;
-int32 RenderedCars;
-int32 RenderedPeds;
-int32 RenderedObjects;
-int32 RenderedDummies;
-int32 TestedBigBuildings;
-int32 TestedBuildings;
-int32 TestedCars;
-int32 TestedPeds;
-int32 TestedObjects;
-int32 TestedDummies;
-
// unused
int16 TestCloseThings;
int16 TestBigThings;
@@ -75,8 +61,6 @@ int32 CRenderer::ms_nNoOfVisibleVehicles;
CEntity *CRenderer::ms_aVisibleVehiclePtrs[NUMVISIBLEENTITIES];
int32 CRenderer::ms_nNoOfVisibleBuildings;
CEntity *CRenderer::ms_aVisibleBuildingPtrs[NUMVISIBLEENTITIES];
-
-CLinkList<EntityInfo> gSortedBuildings;
#endif
CVector CRenderer::ms_vecCameraPosition;
@@ -86,26 +70,20 @@ float CRenderer::ms_lodDistScale = 1.2f;
// unused
BlockedRange CRenderer::aBlockedRanges[16];
-BlockedRange *CRenderer::pFullBlockedRanges;
-BlockedRange *CRenderer::pEmptyBlockedRanges;
+BlockedRange* CRenderer::pFullBlockedRanges;
+BlockedRange* CRenderer::pEmptyBlockedRanges;
void
CRenderer::Init(void)
{
gSortedVehiclesAndPeds.Init(40);
SortBIGBuildings();
-#ifdef NEW_RENDERER
- gSortedBuildings.Init(NUMVISIBLEENTITIES);
-#endif
}
void
CRenderer::Shutdown(void)
{
gSortedVehiclesAndPeds.Shutdown();
-#ifdef NEW_RENDERER
- gSortedBuildings.Shutdown();
-#endif
}
void
@@ -122,12 +100,8 @@ CRenderer::PreRender(void)
for(i = 0; i < ms_nNoOfVisibleVehicles; i++)
ms_aVisibleVehiclePtrs[i]->PreRender();
// How is this done with cWorldStream?
- //for(i = 0; i < ms_nNoOfVisibleBuildings; i++)
- // ms_aVisibleBuildingPtrs[i]->PreRender();
- for(CLink<EntityInfo> *node = gSortedBuildings.head.next;
- node != &gSortedBuildings.tail;
- node = node->next)
- ((CEntity*)node->item.ent)->PreRender();
+ for(i = 0; i < ms_nNoOfVisibleBuildings; i++)
+ ms_aVisibleBuildingPtrs[i]->PreRender();
for(node = CVisibilityPlugins::m_alphaBuildingList.head.next;
node != &CVisibilityPlugins::m_alphaBuildingList.tail;
node = node->next)
@@ -154,26 +128,18 @@ CRenderer::PreRender(void)
void
CRenderer::RenderOneRoad(CEntity *e)
{
-#ifndef MASTER
+#ifndef FINAL
if(gbDontRenderBuildings)
return;
- if(gbShowCollisionPolys)
+#endif
+#ifndef MASTER
+ if(gbShowCollisionPolys || gbShowCollisionPolysReflections || gbShowCollisionPolysNoShadows)
CCollision::DrawColModel_Coloured(e->GetMatrix(), *CModelInfo::GetColModel(e->GetModelIndex()), e->GetModelIndex());
else
#endif
{
-#ifdef EXTENDED_PIPELINES
- CustomPipes::AttachGlossPipe(e->GetAtomic());
-#endif
PUSH_RENDERGROUP(CModelInfo::GetModelInfo(e->GetModelIndex())->GetModelName());
-#ifdef EXTRA_MODEL_FLAGS
- if(!e->IsBuilding() || CModelInfo::GetModelInfo(e->GetModelIndex())->RenderDoubleSided()){
- BACKFACE_CULLING_OFF;
- e->Render();
- BACKFACE_CULLING_ON;
- }else
-#endif
e->Render();
POP_RENDERGROUP();
@@ -189,12 +155,15 @@ CRenderer::RenderOneNonRoad(CEntity *e)
bool resetLights;
#ifndef MASTER
- if(gbShowCollisionPolys){
+ if(gbShowCollisionPolys || gbShowCollisionPolysReflections || gbShowCollisionPolysNoShadows){
if(!e->IsVehicle()){
CCollision::DrawColModel_Coloured(e->GetMatrix(), *CModelInfo::GetColModel(e->GetModelIndex()), e->GetModelIndex());
return;
}
- }else if(e->IsBuilding()){
+ }else
+#endif
+#ifndef FINAL
+ if(e->IsBuilding()){
if(e->bIsBIGBuilding){
if(gbDontRenderBigBuildings)
return;
@@ -205,7 +174,7 @@ CRenderer::RenderOneNonRoad(CEntity *e)
}else
#endif
if(e->IsPed()){
-#ifndef MASTER
+#ifndef FINAL
if(gbDontRenderPeds)
return;
#endif
@@ -213,7 +182,7 @@ CRenderer::RenderOneNonRoad(CEntity *e)
if(ped->m_nPedState == PED_DRIVING)
return;
}
-#ifndef MASTER
+#ifndef FINAL
else if(e->IsObject() || e->IsDummy()){
if(gbDontRenderObjects)
return;
@@ -228,8 +197,11 @@ CRenderer::RenderOneNonRoad(CEntity *e)
resetLights = e->SetupLighting();
- if(e->IsVehicle())
+ if(e->IsVehicle()){
+ // unfortunately can't use GetClump here
+ CVisibilityPlugins::SetupVehicleVariables((RpClump*)e->m_rwObject);
CVisibilityPlugins::InitAlphaAtomicList();
+ }
// Render Peds in vehicle before vehicle itself
if(e->IsVehicle()){
@@ -239,23 +211,15 @@ CRenderer::RenderOneNonRoad(CEntity *e)
for(i = 0; i < 8; i++)
if(veh->pPassengers[i] && veh->pPassengers[i]->m_nPedState == PED_DRIVING)
veh->pPassengers[i]->Render();
- BACKFACE_CULLING_OFF;
+ SetCullMode(rwCULLMODECULLNONE);
}
-#ifdef EXTRA_MODEL_FLAGS
- if(!e->IsBuilding() || CModelInfo::GetModelInfo(e->GetModelIndex())->RenderDoubleSided()){
- BACKFACE_CULLING_OFF;
- e->Render();
- BACKFACE_CULLING_ON;
- }else
-#endif
e->Render();
if(e->IsVehicle()){
- BACKFACE_CULLING_OFF;
e->bImBeingRendered = true;
CVisibilityPlugins::RenderAlphaAtomics();
e->bImBeingRendered = false;
- BACKFACE_CULLING_ON;
+ SetCullMode(rwCULLMODECULLBACK);
}
e->RemoveLighting(resetLights);
@@ -278,53 +242,53 @@ CRenderer::RenderFirstPersonVehicle(void)
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
}
-inline bool IsRoad(CEntity *e) { return e->IsBuilding() && ((CBuilding*)e)->GetIsATreadable(); }
+inline bool IsRoad(CEntity *e) { return e->IsBuilding() && ((CSimpleModelInfo*)CModelInfo::GetModelInfo(e->GetModelIndex()))->m_wetRoadReflection; }
void
CRenderer::RenderRoads(void)
{
int i;
- CTreadable *t;
+ CEntity *e;
PUSH_RENDERGROUP("CRenderer::RenderRoads");
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE);
- BACKFACE_CULLING_ON;
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ SetCullMode(rwCULLMODECULLBACK);
DeActivateDirectional();
SetAmbientColours();
for(i = 0; i < ms_nNoOfVisibleEntities; i++){
- t = (CTreadable*)ms_aVisibleEntityPtrs[i];
- if(IsRoad(t)){
-#ifndef MASTER
- if(gbShowCarRoadGroups || gbShowPedRoadGroups){
- int ind = 0;
- if(gbShowCarRoadGroups)
- ind += ThePaths.m_pathNodes[t->m_nodeIndices[PATH_CAR][0]].group;
- if(gbShowPedRoadGroups)
- ind += ThePaths.m_pathNodes[t->m_nodeIndices[PATH_PED][0]].group;
- SetAmbientColoursToIndicateRoadGroup(ind);
- }
-#endif
- RenderOneRoad(t);
-#ifndef MASTER
- if(gbShowCarRoadGroups || gbShowPedRoadGroups)
- ReSetAmbientAndDirectionalColours();
-#endif
- }
+ e = ms_aVisibleEntityPtrs[i];
+ if(IsRoad(e))
+ RenderOneRoad(e);
}
POP_RENDERGROUP();
}
+inline bool PutIntoSortedVehicleList(CVehicle *veh)
+{
+ if(veh->IsBoat()){
+ int mode = TheCamera.Cams[TheCamera.ActiveCam].Mode;
+ if(mode == CCam::MODE_WHEELCAM ||
+ mode == CCam::MODE_1STPERSON && TheCamera.GetLookDirection() != LOOKING_FORWARD && TheCamera.GetLookDirection() != LOOKING_BEHIND ||
+ CVisibilityPlugins::GetClumpAlpha(veh->GetClump()) != 255)
+ return false;
+ return true;
+ }else
+ return veh->bTouchingWater;
+}
+
void
CRenderer::RenderEverythingBarRoads(void)
{
int i;
CEntity *e;
- CVector dist;
EntityInfo ei;
PUSH_RENDERGROUP("CRenderer::RenderEverythingBarRoads");
- BACKFACE_CULLING_ON;
+ RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ SetCullMode(rwCULLMODECULLBACK);
gSortedVehiclesAndPeds.Clear();
for(i = 0; i < ms_nNoOfVisibleEntities; i++){
@@ -340,14 +304,12 @@ CRenderer::RenderEverythingBarRoads(void)
if(e->IsVehicle() ||
e->IsPed() && CVisibilityPlugins::GetClumpAlpha((RpClump*)e->m_rwObject) != 255){
- if(e->IsVehicle() && ((CVehicle*)e)->IsBoat()){
+ if(e->IsVehicle() && PutIntoSortedVehicleList((CVehicle*)e)){
ei.ent = e;
- dist = ms_vecCameraPosition - e->GetPosition();
- ei.sort = dist.MagnitudeSqr();
+ ei.sort = (ms_vecCameraPosition - e->GetPosition()).MagnitudeSqr();
gSortedVehiclesAndPeds.InsertSorted(ei);
}else{
- dist = ms_vecCameraPosition - e->GetPosition();
- if(!CVisibilityPlugins::InsertEntityIntoSortedList(e, dist.Magnitude())){
+ if(!CVisibilityPlugins::InsertEntityIntoSortedList(e, (ms_vecCameraPosition - e->GetPosition()).Magnitude())){
printf("Ran out of space in alpha entity list");
RenderOneNonRoad(e);
}
@@ -359,37 +321,38 @@ CRenderer::RenderEverythingBarRoads(void)
}
void
-CRenderer::RenderVehiclesButNotBoats(void)
-{
- // This function doesn't do anything
- // because only boats are inserted into the list
- CLink<EntityInfo> *node;
-
- for(node = gSortedVehiclesAndPeds.tail.prev;
- node != &gSortedVehiclesAndPeds.head;
- node = node->prev){
- // only boats in this list
- CVehicle *v = (CVehicle*)node->item.ent;
- if(!v->IsBoat())
- RenderOneNonRoad(v);
- }
-}
-
-void
CRenderer::RenderBoats(void)
{
CLink<EntityInfo> *node;
PUSH_RENDERGROUP("CRenderer::RenderBoats");
- BACKFACE_CULLING_ON;
+ RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ SetCullMode(rwCULLMODECULLBACK);
+
+#ifdef NEW_RENDERER
+ int i;
+ CEntity *e;
+ EntityInfo ei;
+ if(gbNewRenderer){
+ gSortedVehiclesAndPeds.Clear();
+ // not the real thing
+ for(i = 0; i < ms_nNoOfVisibleVehicles; i++){
+ e = ms_aVisibleVehiclePtrs[i];
+ if(e->IsVehicle() && PutIntoSortedVehicleList((CVehicle*)e)){
+ ei.ent = e;
+ ei.sort = (ms_vecCameraPosition - e->GetPosition()).MagnitudeSqr();
+ gSortedVehiclesAndPeds.InsertSorted(ei);
+ }
+ }
+ }
+#endif
for(node = gSortedVehiclesAndPeds.tail.prev;
node != &gSortedVehiclesAndPeds.head;
node = node->prev){
- // only boats in this list
CVehicle *v = (CVehicle*)node->item.ent;
- if(v->IsBoat())
- RenderOneNonRoad(v);
+ RenderOneNonRoad(v);
}
POP_RENDERGROUP();
}
@@ -407,8 +370,6 @@ enum {
PASS_BLEND // normal blend
};
-static RwRGBAReal black;
-
static void
SetStencilState(int state)
{
@@ -449,14 +410,6 @@ CRenderer::RenderOneBuilding(CEntity *ent, float camdist)
RpAtomic *atomic = (RpAtomic*)ent->m_rwObject;
CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(ent->GetModelIndex());
-#ifdef EXTRA_MODEL_FLAGS
- bool resetCull = false;
- if(!ent->IsBuilding() || mi->RenderDoubleSided()){
- resetCull = true;
- BACKFACE_CULLING_OFF;
- }
-#endif
-
int pass = PASS_BLEND;
if(mi->m_additive) // very questionable
pass = PASS_ADD;
@@ -486,11 +439,6 @@ CRenderer::RenderOneBuilding(CEntity *ent, float camdist)
}else
WorldRender::AtomicFirstPass(atomic, pass);
-#ifdef EXTRA_MODEL_FLAGS
- if(resetCull)
- BACKFACE_CULLING_ON;
-#endif
-
ent->bImBeingRendered = false; // TODO: this seems wrong, but do we even need it?
}
@@ -502,7 +450,7 @@ CRenderer::RenderWorld(int pass)
CLink<CVisibilityPlugins::AlphaObjectInfo> *node;
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE);
- BACKFACE_CULLING_ON;
+ SetCullMode(rwCULLMODECULLBACK);
DeActivateDirectional();
SetAmbientColours();
@@ -512,20 +460,11 @@ CRenderer::RenderWorld(int pass)
// Roads
PUSH_RENDERGROUP("CRenderer::RenderWorld - Roads");
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
-/*
for(i = 0; i < ms_nNoOfVisibleBuildings; i++){
e = ms_aVisibleBuildingPtrs[i];
if(e->bIsBIGBuilding || IsRoad(e))
RenderOneBuilding(e);
}
-*/
- for(CLink<EntityInfo> *node = gSortedBuildings.tail.prev;
- node != &gSortedBuildings.head;
- node = node->prev){
- e = node->item.ent;
- if(e->bIsBIGBuilding || IsRoad(e))
- RenderOneBuilding(e);
- }
for(node = CVisibilityPlugins::m_alphaBuildingList.tail.prev;
node != &CVisibilityPlugins::m_alphaBuildingList.head;
node = node->prev){
@@ -533,33 +472,17 @@ CRenderer::RenderWorld(int pass)
if(e->bIsBIGBuilding || IsRoad(e))
RenderOneBuilding(e, node->item.sort);
}
-
- // KLUDGE for road puddles which have to be rendered at road-time
- // only very temporary, there are more rendering issues
- RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
- RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
- WorldRender::RenderBlendPass(PASS_BLEND);
- WorldRender::numBlendInsts[PASS_BLEND] = 0;
POP_RENDERGROUP();
break;
case 1:
// Opaque
PUSH_RENDERGROUP("CRenderer::RenderWorld - Opaque");
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
-/*
for(i = 0; i < ms_nNoOfVisibleBuildings; i++){
e = ms_aVisibleBuildingPtrs[i];
if(!(e->bIsBIGBuilding || IsRoad(e)))
RenderOneBuilding(e);
}
-*/
- for(CLink<EntityInfo> *node = gSortedBuildings.tail.prev;
- node != &gSortedBuildings.head;
- node = node->prev){
- e = node->item.ent;
- if(!(e->bIsBIGBuilding || IsRoad(e)))
- RenderOneBuilding(e);
- }
for(node = CVisibilityPlugins::m_alphaBuildingList.tail.prev;
node != &CVisibilityPlugins::m_alphaBuildingList.head;
node = node->prev){
@@ -618,8 +541,8 @@ CRenderer::RenderVehicles(void)
e = ms_aVisibleVehiclePtrs[i];
if(!e->IsVehicle())
continue;
-// if(PutIntoSortedVehicleList((CVehicle*)e))
-// continue; // boats handled elsewhere
+ if(PutIntoSortedVehicleList((CVehicle*)e))
+ continue; // boats handled elsewhere
ei.ent = e;
ei.sort = (ms_vecCameraPosition - e->GetPosition()).MagnitudeSqr();
gSortedVehiclesAndPeds.InsertSorted(ei);
@@ -633,12 +556,12 @@ CRenderer::RenderVehicles(void)
}
void
-CRenderer::RenderWater(void)
+CRenderer::RenderTransparentWater(void)
{
int i;
CEntity *e;
- PUSH_RENDERGROUP("CRenderer::RenderWater");
+ PUSH_RENDERGROUP("CRenderer::RenderTransparentWater");
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
@@ -659,7 +582,7 @@ CRenderer::RenderWater(void)
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
SetStencilState(1);
- CWaterLevel::RenderWater();
+ CWaterLevel::RenderTransparentWater();
SetStencilState(0);
POP_RENDERGROUP();
@@ -673,7 +596,6 @@ CRenderer::ClearForFrame(void)
ms_nNoOfVisibleBuildings = 0;
ms_nNoOfInVisibleEntities = 0;
gSortedVehiclesAndPeds.Clear();
- gSortedBuildings.Clear();
WorldRender::numBlendInsts[PASS_NOZ] = 0;
WorldRender::numBlendInsts[PASS_ADD] = 0;
@@ -686,7 +608,8 @@ CRenderer::RenderFadingInEntities(void)
{
PUSH_RENDERGROUP("CRenderer::RenderFadingInEntities");
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE);
- BACKFACE_CULLING_ON;
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ SetCullMode(rwCULLMODECULLBACK);
DeActivateDirectional();
SetAmbientColours();
CVisibilityPlugins::RenderFadingEntities();
@@ -694,6 +617,16 @@ CRenderer::RenderFadingInEntities(void)
}
void
+CRenderer::RenderFadingInUnderwaterEntities(void)
+{
+ PUSH_RENDERGROUP("CRenderer::RenderFadingInUnderwaterEntities");
+ DeActivateDirectional();
+ SetAmbientColours();
+ CVisibilityPlugins::RenderFadingUnderwaterEntities();
+ POP_RENDERGROUP();
+}
+
+void
CRenderer::RenderCollisionLines(void)
{
int i;
@@ -708,14 +641,6 @@ CRenderer::RenderCollisionLines(void)
}
}
-// unused
-void
-CRenderer::RenderBlockBuildingLines(void)
-{
- for(BlockedRange *br = pFullBlockedRanges; br; br = br->next)
- printf("Blocked: %f %f\n", br->a, br->b);
-}
-
enum Visbility
{
VIS_INVISIBLE,
@@ -741,7 +666,7 @@ CRenderer::SetupEntityVisibility(CEntity *ent)
float dist;
bool request = true;
- if (mi->GetModelType() == MITYPE_TIME) {
+ if(mi->GetModelType() == MITYPE_TIME){
ti = (CTimeModelInfo*)mi;
other = ti->GetOtherTimeModel();
if(CClock::GetIsTimeInRange(ti->GetTimeOn(), ti->GetTimeOff())){
@@ -750,32 +675,44 @@ CRenderer::SetupEntityVisibility(CEntity *ent)
ti->m_alpha = 255;
}else{
// Hide if possible
- if(CANTIMECULL)
+ if(CANTIMECULL){
+ ent->DeleteRwObject();
return VIS_INVISIBLE;
+ }
// can't cull, so we'll try to draw this one, but don't request
// it since what we really want is the other one.
request = false;
}
}else{
- if (mi->GetModelType() != MITYPE_SIMPLE) {
+ if(mi->GetModelType() != MITYPE_SIMPLE && mi->GetModelType() != MITYPE_WEAPON){
if(FindPlayerVehicle() == ent &&
- TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON){
+ TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON &&
+ !(FindPlayerVehicle()->IsBike() && ((CBike*)FindPlayerVehicle())->bWheelieCam)){
// Player's vehicle in first person mode
- if(TheCamera.Cams[TheCamera.ActiveCam].DirectionWasLooking == LOOKING_FORWARD ||
+ CVehicle *veh = (CVehicle*)ent;
+ int model = veh->GetModelIndex();
+ int direction = TheCamera.Cams[TheCamera.ActiveCam].DirectionWasLooking;
+ if(direction == LOOKING_FORWARD ||
ent->GetModelIndex() == MI_RHINO ||
ent->GetModelIndex() == MI_COACH ||
- TheCamera.m_bInATunnelAndABigVehicle){
+ TheCamera.m_bInATunnelAndABigVehicle ||
+ direction == LOOKING_BEHIND && veh->pHandling->Flags & HANDLING_UNKNOWN){
ent->bNoBrightHeadLights = true;
- }else{
+ return VIS_OFFSCREEN;
+ }
+
+ if(direction != LOOKING_BEHIND ||
+ !veh->IsBoat() || model == MI_REEFER || model == MI_TROPIC || model == MI_PREDATOR || model == MI_SKIMMER){
m_pFirstPersonVehicle = (CVehicle*)ent;
ent->bNoBrightHeadLights = false;
+ return VIS_OFFSCREEN;
}
- return VIS_OFFSCREEN;
}
+
// All sorts of Clumps
if(ent->m_rwObject == nil || !ent->bIsVisible)
return VIS_INVISIBLE;
- if(!ent->GetIsOnScreen())
+ if(!ent->GetIsOnScreen() || ent->IsEntityOccluded())
return VIS_OFFSCREEN;
if(ent->bDrawLast){
dist = (ent->GetPosition() - ms_vecCameraPosition).Magnitude();
@@ -785,22 +722,38 @@ CRenderer::SetupEntityVisibility(CEntity *ent)
}
return VIS_VISIBLE;
}
- if(ent->IsObject() &&
- ((CObject*)ent)->ObjectCreatedBy == TEMP_OBJECT){
+ if(ent->bDontStream){
if(ent->m_rwObject == nil || !ent->bIsVisible)
return VIS_INVISIBLE;
- return ent->GetIsOnScreen() ? VIS_VISIBLE : VIS_OFFSCREEN;
+ if(!ent->GetIsOnScreen() || ent->IsEntityOccluded())
+ return VIS_OFFSCREEN;
+ if(ent->bDrawLast){
+ dist = (ent->GetPosition() - ms_vecCameraPosition).Magnitude();
+ CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist);
+ ent->bDistanceFade = false;
+ return VIS_INVISIBLE;
+ }
+ return VIS_VISIBLE;
}
}
// Simple ModelInfo
+ if(!IsAreaVisible(ent->m_area))
+ return VIS_INVISIBLE;
+
dist = (ent->GetPosition() - ms_vecCameraPosition).Magnitude();
- // This can only happen with multi-atomic models (e.g. railtracks)
- // but why do we bump up the distance? can only be fading...
- if(LOD_DISTANCE + STREAM_DISTANCE < dist && dist < mi->GetLargestLodDistance())
- dist = mi->GetLargestLodDistance();
+#ifndef FIX_BUGS
+ // Whatever this is supposed to do, it breaks fading for objects
+ // whose draw dist is > LOD_DISTANCE-FADE_DISTANCE, i.e. 280
+ // because decreasing dist here makes the object visible above LOD_DISTANCE
+ // before fading normally once below LOD_DISTANCE.
+ // aha! this must be a workaround for the fact that we're not taking
+ // the LOD multiplier into account here anywhere
+ if(LOD_DISTANCE < dist && dist < mi->GetLargestLodDistance() + FADE_DISTANCE)
+ dist += mi->GetLargestLodDistance() - LOD_DISTANCE;
+#endif
if(ent->IsObject() && ent->bRenderDamaged)
mi->m_isDamaged = true;
@@ -820,7 +773,7 @@ CRenderer::SetupEntityVisibility(CEntity *ent)
if(ent->m_rwObject == nil || !ent->bIsVisible)
return VIS_INVISIBLE;
- if(!ent->GetIsOnScreen()){
+ if(!ent->GetIsOnScreen() || ent->IsEntityOccluded()){
mi->m_alpha = 255;
return VIS_OFFSCREEN;
}
@@ -832,9 +785,10 @@ CRenderer::SetupEntityVisibility(CEntity *ent)
}
if(mi->m_drawLast || ent->bDrawLast){
- CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist);
- ent->bDistanceFade = false;
- return VIS_INVISIBLE;
+ if(CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist)){
+ ent->bDistanceFade = false;
+ return VIS_INVISIBLE;
+ }
}
return VIS_VISIBLE;
}
@@ -870,7 +824,7 @@ CRenderer::SetupEntityVisibility(CEntity *ent)
if(ent->m_rwObject == nil || !ent->bIsVisible)
return VIS_INVISIBLE;
- if(!ent->GetIsOnScreen()){
+ if(!ent->GetIsOnScreen() || ent->IsEntityOccluded()){
mi->m_alpha = 255;
return VIS_OFFSCREEN;
}else{
@@ -883,19 +837,32 @@ CRenderer::SetupEntityVisibility(CEntity *ent)
int32
CRenderer::SetupBigBuildingVisibility(CEntity *ent)
{
- CSimpleModelInfo *mi = (CSimpleModelInfo *)CModelInfo::GetModelInfo(ent->GetModelIndex());
+ CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(ent->m_modelIndex);
CTimeModelInfo *ti;
int32 other;
- if (mi->GetModelType() == MITYPE_TIME) {
- ti = (CTimeModelInfo*)mi;
+ if(!IsAreaVisible(ent->m_area))
+ return VIS_INVISIBLE;
+
+ bool request = true;
+ if(mi->GetModelType() == MITYPE_TIME){
+ ti = (CTimeModelInfo*)mi;
other = ti->GetOtherTimeModel();
- // Hide objects not in time range if possible
- if(CANTIMECULL)
- if(!CClock::GetIsTimeInRange(ti->GetTimeOn(), ti->GetTimeOff()))
+ if(CClock::GetIsTimeInRange(ti->GetTimeOn(), ti->GetTimeOff())){
+ // don't fade in, or between time objects
+ if(CANTIMECULL)
+ ti->m_alpha = 255;
+ }else{
+ // Hide if possible
+ if(CANTIMECULL){
+ ent->DeleteRwObject();
return VIS_INVISIBLE;
- // Draw like normal
- } else if (mi->GetModelType() == MITYPE_VEHICLE)
+ }
+ // can't cull, so we'll try to draw this one, but don't request
+ // it since what we really want is the other one.
+ request = false;
+ }
+ }else if(mi->GetModelType() == MITYPE_VEHICLE)
return ent->IsVisible() ? VIS_VISIBLE : VIS_INVISIBLE;
float dist = (ms_vecCameraPosition-ent->GetPosition()).Magnitude();
@@ -904,7 +871,7 @@ CRenderer::SetupBigBuildingVisibility(CEntity *ent)
// Find out whether to draw below near distance.
// This is only the case if there is a non-LOD which is either not
// loaded or not completely faded in yet.
- if(dist < mi->GetNearDistance() && dist < LOD_DISTANCE + STREAM_DISTANCE){
+ if(dist < mi->GetNearDistance() && dist < LOD_DISTANCE){
// No non-LOD or non-LOD is completely visible.
if(nonLOD == nil ||
nonLOD->GetRwObject() && nonLOD->m_alpha == 255)
@@ -912,7 +879,7 @@ CRenderer::SetupBigBuildingVisibility(CEntity *ent)
// But if it is a time object, we'd rather draw the wrong
// non-LOD than the right LOD.
- if (nonLOD->GetModelType() == MITYPE_TIME) {
+ if(nonLOD->GetModelType() == MITYPE_TIME){
ti = (CTimeModelInfo*)nonLOD;
other = ti->GetOtherTimeModel();
if(other != -1 && CModelInfo::GetModelInfo(other)->GetRwObject())
@@ -920,7 +887,7 @@ CRenderer::SetupBigBuildingVisibility(CEntity *ent)
}
}
- RpAtomic *a = mi->GetAtomicFromDistance(dist);
+ RpAtomic *a = mi->GetFirstAtomicFromDistance(dist);
if(a){
if(ent->m_rwObject == nil)
ent->CreateRwObject();
@@ -931,8 +898,18 @@ CRenderer::SetupBigBuildingVisibility(CEntity *ent)
// that of an atomic for another draw distance.
if(RpAtomicGetGeometry(a) != RpAtomicGetGeometry(rwobj))
RpAtomicSetGeometry(rwobj, RpAtomicGetGeometry(a), rpATOMICSAMEBOUNDINGSPHERE); // originally 5 (mistake?)
- if (!ent->IsVisible() || !ent->GetIsOnScreenComplex())
+ mi->IncreaseAlpha();
+ if(!ent->IsVisible() || !ent->GetIsOnScreenComplex() || ent->IsEntityOccluded()){
+ mi->m_alpha = 255;
return VIS_INVISIBLE;
+ }
+
+ if(mi->m_alpha != 255){
+ CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist);
+ ent->bDistanceFade = true;
+ return VIS_INVISIBLE;
+ }
+
if(mi->m_drawLast){
CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist);
ent->bDistanceFade = false;
@@ -948,10 +925,14 @@ CRenderer::SetupBigBuildingVisibility(CEntity *ent)
// get faded atomic
- a = mi->GetAtomicFromDistance(dist - FADE_DISTANCE);
+ a = mi->GetFirstAtomicFromDistance(dist - FADE_DISTANCE);
if(a == nil){
- ent->DeleteRwObject();
- return VIS_INVISIBLE;
+ if(ent->bStreamBIGBuilding && dist-STREAM_DISTANCE < mi->GetLodDistance(0) && request){
+ return ent->GetIsOnScreen() ? VIS_STREAMME : VIS_INVISIBLE;
+ }else{
+ ent->DeleteRwObject();
+ return VIS_INVISIBLE;
+ }
}
// Fade...
@@ -961,14 +942,20 @@ CRenderer::SetupBigBuildingVisibility(CEntity *ent)
RpAtomic *rwobj = (RpAtomic*)ent->m_rwObject;
if(RpAtomicGetGeometry(a) != RpAtomicGetGeometry(rwobj))
RpAtomicSetGeometry(rwobj, RpAtomicGetGeometry(a), rpATOMICSAMEBOUNDINGSPHERE); // originally 5 (mistake?)
- if (ent->IsVisible() && ent->GetIsOnScreenComplex())
- CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist);
+ mi->IncreaseAlpha();
+ if(!ent->IsVisible() || !ent->GetIsOnScreenComplex() || ent->IsEntityOccluded()){
+ mi->m_alpha = 255;
+ return VIS_INVISIBLE;
+ }
+ CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist);
+ ent->bDistanceFade = true;
return VIS_INVISIBLE;
}
void
CRenderer::ConstructRenderList(void)
{
+ COcclusion::ProcessBeforeRendering();
#ifdef NEW_RENDERER
if(!gbNewRenderer)
#endif
@@ -1027,24 +1014,6 @@ CRenderer::ScanWorld(void)
RwMatrix *cammatrix;
RwV2d poly[3];
-#ifndef MASTER
- // missing in game but has to be done somewhere
- EntitiesRendered = 0;
- EntitiesNotRendered = 0;
- RenderedBigBuildings = 0;
- RenderedBuildings = 0;
- RenderedCars = 0;
- RenderedPeds = 0;
- RenderedObjects = 0;
- RenderedDummies = 0;
- TestedBigBuildings = 0;
- TestedBuildings = 0;
- TestedCars = 0;
- TestedPeds = 0;
- TestedObjects = 0;
- TestedDummies = 0;
-#endif
-
memset(vectors, 0, sizeof(vectors));
vectors[CORNER_FAR_TOPLEFT].x = -vw.x * f;
vectors[CORNER_FAR_TOPLEFT].y = vw.y * f;
@@ -1065,6 +1034,15 @@ CRenderer::ScanWorld(void)
CVisibilityPlugins::InitAlphaEntityList();
CWorld::AdvanceCurrentScanCode();
+ // unused
+ static CVector prevPos;
+ static CVector prevFwd;
+ static bool smallMovement;
+ smallMovement = (TheCamera.GetPosition() - prevPos).MagnitudeSqr() < SQR(4.0f) &&
+ DotProduct(TheCamera.GetForward(), prevFwd) > 0.98f;
+ prevPos = TheCamera.GetPosition();
+ prevFwd = TheCamera.GetForward();
+
if(cammatrix->at.z > 0.0f){
// looking up, bottom corners are further away
vectors[CORNER_LOD_LEFT] = vectors[CORNER_FAR_BOTLEFT] * LOD_DISTANCE/f;
@@ -1110,6 +1088,7 @@ CRenderer::ScanWorld(void)
for(int y = y1; y <= y2; y++)
ScanSectorList(CWorld::GetSector(x1, y)->m_lists);
}else{
+#ifdef GTA_TRAIN
CVehicle *train = FindPlayerTrain();
if(train && train->GetPosition().z < 0.0f){
poly[0].x = CWorld::GetSectorX(vectors[CORNER_CAM].x);
@@ -1119,7 +1098,9 @@ CRenderer::ScanWorld(void)
poly[2].x = CWorld::GetSectorX(vectors[CORNER_LOD_RIGHT].x);
poly[2].y = CWorld::GetSectorY(vectors[CORNER_LOD_RIGHT].y);
ScanSectorPoly(poly, 3, ScanSectorList_Subway);
- }else{
+ }else
+#endif
+ {
if(f > LOD_DISTANCE){
// priority
poly[0].x = CWorld::GetSectorX(vectors[CORNER_CAM].x);
@@ -1147,35 +1128,22 @@ CRenderer::ScanWorld(void)
poly[2].y = CWorld::GetSectorY(vectors[CORNER_FAR_TOPRIGHT].y);
ScanSectorPoly(poly, 3, ScanSectorList);
}
+
#ifdef NO_ISLAND_LOADING
- if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_HIGH) {
- ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_INDUSTRIAL));
- ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_COMMERCIAL));
- ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_SUBURBAN));
+ if (FrontEndMenuManager.m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_HIGH) {
+ ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_BEACH));
+ ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_MAINLAND));
} else
#endif
{
- #ifdef FIX_BUGS
- if (CCollision::ms_collisionInMemory != LEVEL_GENERIC)
- #endif
- ScanBigBuildingList(CWorld::GetBigBuildingList(CCollision::ms_collisionInMemory));
+#ifdef FIX_BUGS
+ if(CCollision::ms_collisionInMemory != LEVEL_GENERIC)
+#endif
+ ScanBigBuildingList(CWorld::GetBigBuildingList(CGame::currLevel));
}
ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_GENERIC));
}
}
-
-#ifndef MASTER
- if(gbShowCullZoneDebugStuff){
- sprintf(gString, "Rejected: %d/%d.", EntitiesNotRendered, EntitiesNotRendered + EntitiesRendered);
- CDebug::PrintAt(gString, 10, 10);
- sprintf(gString, "Tested:BBuild:%d Build:%d Peds:%d Cars:%d Obj:%d Dummies:%d",
- TestedBigBuildings, TestedBuildings, TestedPeds, TestedCars, TestedObjects, TestedDummies);
- CDebug::PrintAt(gString, 10, 11);
- sprintf(gString, "Rendered:BBuild:%d Build:%d Peds:%d Cars:%d Obj:%d Dummies:%d",
- RenderedBigBuildings, RenderedBuildings, RenderedPeds, RenderedCars, RenderedObjects, RenderedDummies);
- CDebug::PrintAt(gString, 10, 12);
- }
-#endif
}
void
@@ -1204,6 +1172,7 @@ CRenderer::RequestObjectsInFrustum(void)
cammatrix = RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera));
CWorld::AdvanceCurrentScanCode();
+ ms_vecCameraPosition = TheCamera.GetPosition();
if(cammatrix->at.z > 0.0f){
// looking up, bottom corners are further away
@@ -1262,8 +1231,6 @@ CRenderer::RequestObjectsInFrustum(void)
bool
CEntity::SetupLighting(void)
{
- DeActivateDirectional();
- SetAmbientColours();
return false;
}
@@ -1289,7 +1256,7 @@ CPed::SetupLighting(void)
} else {
// Note that this lightMult is only affected by LIGHT_DARKEN. If there's no LIGHT_DARKEN, it will be 1.0.
float lightMult = CPointLights::GenerateLightsAffectingObject(&GetPosition());
- if (!bHasBlip && lightMult != 1.0f) {
+ if (lightMult != 1.0f) {
SetAmbientAndDirectionalColours(lightMult);
return true;
}
@@ -1300,7 +1267,13 @@ CPed::SetupLighting(void)
void
CPed::RemoveLighting(bool reset)
{
- CRenderer::RemoveVehiclePedLights(this, reset);
+ if (!bRenderScorched) {
+ CRenderer::RemoveVehiclePedLights(this, reset);
+ if (reset)
+ ReSetAmbientAndDirectionalColours();
+ }
+ SetAmbientColours();
+ DeActivateDirectional();
}
float
@@ -1472,13 +1445,9 @@ CRenderer::InsertEntityIntoList(CEntity *ent)
// TODO: there are more flags being checked here
if(gbNewRenderer && (ent->IsVehicle() || ent->IsPed()))
ms_aVisibleVehiclePtrs[ms_nNoOfVisibleVehicles++] = ent;
- else if(gbNewRenderer && ent->IsBuilding()){
- EntityInfo info;
- info.ent = ent;
- info.sort = -(ent->GetPosition() - ms_vecCameraPosition).MagnitudeSqr();
- gSortedBuildings.InsertSorted(info);
-// ms_aVisibleBuildingPtrs[ms_nNoOfVisibleBuildings++] = ent;
- }else
+ else if(gbNewRenderer && ent->IsBuilding())
+ ms_aVisibleBuildingPtrs[ms_nNoOfVisibleBuildings++] = ent;
+ else
#endif
ms_aVisibleEntityPtrs[ms_nNoOfVisibleEntities++] = ent;
}
@@ -1488,22 +1457,25 @@ CRenderer::ScanBigBuildingList(CPtrList &list)
{
CPtrNode *node;
CEntity *ent;
+ int vis;
+ int f = CTimer::GetFrameCounter() & 3;
for(node = list.first; node; node = node->next){
ent = (CEntity*)node->item;
-#ifndef MASTER
- // all missing from game actually
- TestedBigBuildings++;
-#endif
- if(!ent->bZoneCulled || gbDisableZoneCull){
- if(SetupBigBuildingVisibility(ent) == VIS_VISIBLE)
- InsertEntityIntoList(ent);
-#ifndef MASTER
- EntitiesRendered++;
- RenderedBigBuildings++;
- }else{
- EntitiesNotRendered++;
-#endif
+ if(ent->bOffscreen || (ent->m_randomSeed&3) != f){
+ ent->bOffscreen = true;
+ vis = SetupBigBuildingVisibility(ent);
+ }else
+ vis = VIS_VISIBLE;
+ switch(vis){
+ case VIS_VISIBLE:
+ InsertEntityIntoList(ent);
+ ent->bOffscreen = false;
+ break;
+ case VIS_STREAMME:
+ if(!CStreaming::ms_disableStreaming)
+ CStreaming::RequestModel(ent->GetModelIndex(), 0);
+ break;
}
}
}
@@ -1524,61 +1496,30 @@ CRenderer::ScanSectorList(CPtrList *lists)
if(ent->m_scanCode == CWorld::GetCurrentScanCode())
continue; // already seen
ent->m_scanCode = CWorld::GetCurrentScanCode();
+ ent->bOffscreen = false;
- if(IsEntityCullZoneVisible(ent)){
- switch(SetupEntityVisibility(ent)){
- case VIS_VISIBLE:
- InsertEntityIntoList(ent);
- break;
- case VIS_INVISIBLE:
- if(!IsGlass(ent->GetModelIndex()))
- break;
- // fall through
- case VIS_OFFSCREEN:
- dx = ms_vecCameraPosition.x - ent->GetPosition().x;
- dy = ms_vecCameraPosition.y - ent->GetPosition().y;
- if(dx > -65.0f && dx < 65.0f &&
- dy > -65.0f && dy < 65.0f &&
- ms_nNoOfInVisibleEntities < NUMINVISIBLEENTITIES - 1)
- ms_aInVisibleEntityPtrs[ms_nNoOfInVisibleEntities++] = ent;
- break;
- case VIS_STREAMME:
- if(!CStreaming::ms_disableStreaming)
- if(!m_loadingPriority || CStreaming::ms_numModelsRequested < 10)
- CStreaming::RequestModel(ent->GetModelIndex(), 0);
- break;
- }
-#ifndef MASTER
- EntitiesRendered++;
- switch(ent->GetType()){
- case ENTITY_TYPE_BUILDING:
- if(ent->bIsBIGBuilding)
- RenderedBigBuildings++;
- else
- RenderedBuildings++;
- break;
- case ENTITY_TYPE_VEHICLE:
- RenderedCars++;
- break;
- case ENTITY_TYPE_PED:
- RenderedPeds++;
- break;
- case ENTITY_TYPE_OBJECT:
- RenderedObjects++;
- break;
- case ENTITY_TYPE_DUMMY:
- RenderedDummies++;
+ switch(SetupEntityVisibility(ent)){
+ case VIS_VISIBLE:
+ InsertEntityIntoList(ent);
+ break;
+ case VIS_INVISIBLE:
+ if(!IsGlass(ent->GetModelIndex()))
break;
- }
-#endif
- }else if(IsRoad(ent) && !CStreaming::ms_disableStreaming){
- if(SetupEntityVisibility(ent) == VIS_STREAMME)
+ // fall through
+ case VIS_OFFSCREEN:
+ ent->bOffscreen = true;
+ dx = ms_vecCameraPosition.x - ent->GetPosition().x;
+ dy = ms_vecCameraPosition.y - ent->GetPosition().y;
+ if(dx > -30.0f && dx < 30.0f &&
+ dy > -30.0f && dy < 30.0f &&
+ ms_nNoOfInVisibleEntities < NUMINVISIBLEENTITIES - 1)
+ ms_aInVisibleEntityPtrs[ms_nNoOfInVisibleEntities++] = ent;
+ break;
+ case VIS_STREAMME:
+ if(!CStreaming::ms_disableStreaming)
if(!m_loadingPriority || CStreaming::ms_numModelsRequested < 10)
CStreaming::RequestModel(ent->GetModelIndex(), 0);
- }else{
-#ifndef MASTER
- EntitiesNotRendered++;
-#endif
+ break;
}
}
}
@@ -1600,69 +1541,38 @@ CRenderer::ScanSectorList_Priority(CPtrList *lists)
if(ent->m_scanCode == CWorld::GetCurrentScanCode())
continue; // already seen
ent->m_scanCode = CWorld::GetCurrentScanCode();
+ ent->bOffscreen = false;
- if(IsEntityCullZoneVisible(ent)){
- switch(SetupEntityVisibility(ent)){
- case VIS_VISIBLE:
- InsertEntityIntoList(ent);
- break;
- case VIS_INVISIBLE:
- if(!IsGlass(ent->GetModelIndex()))
- break;
- // fall through
- case VIS_OFFSCREEN:
- dx = ms_vecCameraPosition.x - ent->GetPosition().x;
- dy = ms_vecCameraPosition.y - ent->GetPosition().y;
- if(dx > -65.0f && dx < 65.0f &&
- dy > -65.0f && dy < 65.0f &&
- ms_nNoOfInVisibleEntities < NUMINVISIBLEENTITIES - 1)
- ms_aInVisibleEntityPtrs[ms_nNoOfInVisibleEntities++] = ent;
- break;
- case VIS_STREAMME:
- if(!CStreaming::ms_disableStreaming){
- CStreaming::RequestModel(ent->GetModelIndex(), 0);
- if(CStreaming::ms_aInfoForModel[ent->GetModelIndex()].m_loadState != STREAMSTATE_LOADED)
- m_loadingPriority = true;
- }
- break;
- }
-#ifndef MASTER
- // actually missing in game
- EntitiesRendered++;
- switch(ent->GetType()){
- case ENTITY_TYPE_BUILDING:
- if(ent->bIsBIGBuilding)
- RenderedBigBuildings++;
- else
- RenderedBuildings++;
- break;
- case ENTITY_TYPE_VEHICLE:
- RenderedCars++;
- break;
- case ENTITY_TYPE_PED:
- RenderedPeds++;
- break;
- case ENTITY_TYPE_OBJECT:
- RenderedObjects++;
- break;
- case ENTITY_TYPE_DUMMY:
- RenderedDummies++;
+ switch(SetupEntityVisibility(ent)){
+ case VIS_VISIBLE:
+ InsertEntityIntoList(ent);
+ break;
+ case VIS_INVISIBLE:
+ if(!IsGlass(ent->GetModelIndex()))
break;
- }
-#endif
- }else if(IsRoad(ent) && !CStreaming::ms_disableStreaming){
- if(SetupEntityVisibility(ent) == VIS_STREAMME)
+ // fall through
+ case VIS_OFFSCREEN:
+ ent->bOffscreen = true;
+ dx = ms_vecCameraPosition.x - ent->GetPosition().x;
+ dy = ms_vecCameraPosition.y - ent->GetPosition().y;
+ if(dx > -30.0f && dx < 30.0f &&
+ dy > -30.0f && dy < 30.0f &&
+ ms_nNoOfInVisibleEntities < NUMINVISIBLEENTITIES - 1)
+ ms_aInVisibleEntityPtrs[ms_nNoOfInVisibleEntities++] = ent;
+ break;
+ case VIS_STREAMME:
+ if(!CStreaming::ms_disableStreaming){
CStreaming::RequestModel(ent->GetModelIndex(), 0);
- }else{
-#ifndef MASTER
- // actually missing in game
- EntitiesNotRendered++;
-#endif
+ if(CStreaming::ms_aInfoForModel[ent->GetModelIndex()].m_loadState != STREAMSTATE_LOADED)
+ m_loadingPriority = true;
+ }
+ break;
}
}
}
}
+#ifdef GTA_TRAIN
void
CRenderer::ScanSectorList_Subway(CPtrList *lists)
{
@@ -1679,15 +1589,17 @@ CRenderer::ScanSectorList_Subway(CPtrList *lists)
if(ent->m_scanCode == CWorld::GetCurrentScanCode())
continue; // already seen
ent->m_scanCode = CWorld::GetCurrentScanCode();
+ ent->bOffscreen = false;
switch(SetupEntityVisibility(ent)){
case VIS_VISIBLE:
InsertEntityIntoList(ent);
break;
case VIS_OFFSCREEN:
+ ent->bOffscreen = true;
dx = ms_vecCameraPosition.x - ent->GetPosition().x;
dy = ms_vecCameraPosition.y - ent->GetPosition().y;
- if(dx > -65.0f && dx < 65.0f &&
- dy > -65.0f && dy < 65.0f &&
+ if(dx > -30.0f && dx < 30.0f &&
+ dy > -30.0f && dy < 30.0f &&
ms_nNoOfInVisibleEntities < NUMINVISIBLEENTITIES - 1)
ms_aInVisibleEntityPtrs[ms_nNoOfInVisibleEntities++] = ent;
break;
@@ -1695,6 +1607,7 @@ CRenderer::ScanSectorList_Subway(CPtrList *lists)
}
}
}
+#endif
void
CRenderer::ScanSectorList_RequestModels(CPtrList *lists)
@@ -1711,8 +1624,7 @@ CRenderer::ScanSectorList_RequestModels(CPtrList *lists)
if(ent->m_scanCode == CWorld::GetCurrentScanCode())
continue; // already seen
ent->m_scanCode = CWorld::GetCurrentScanCode();
- if(IsEntityCullZoneVisible(ent))
- if(ShouldModelBeStreamed(ent))
+ if(ShouldModelBeStreamed(ent, ms_vecCameraPosition))
CStreaming::RequestModel(ent->GetModelIndex(), 0);
}
}
@@ -1747,95 +1659,29 @@ CRenderer::SortBIGBuildingsForSectorList(CPtrList *list)
}
bool
-CRenderer::ShouldModelBeStreamed(CEntity *ent)
+CRenderer::ShouldModelBeStreamed(CEntity *ent, const CVector &campos)
{
- CSimpleModelInfo *mi = (CSimpleModelInfo *)CModelInfo::GetModelInfo(ent->GetModelIndex());
- float dist = (ent->GetPosition() - ms_vecCameraPosition).Magnitude();
+ if(!IsAreaVisible(ent->m_area))
+ return false;
+ CTimeModelInfo *mi = (CTimeModelInfo *)CModelInfo::GetModelInfo(ent->GetModelIndex());
+ if(mi->GetModelType() == MITYPE_TIME)
+ if(!CClock::GetIsTimeInRange(mi->GetTimeOn(), mi->GetTimeOff()))
+ return false;
+ float dist = (ent->GetPosition() - campos).Magnitude();
if(mi->m_noFade)
return dist - STREAM_DISTANCE < mi->GetLargestLodDistance();
else
return dist - FADE_DISTANCE - STREAM_DISTANCE < mi->GetLargestLodDistance();
}
-bool
-CRenderer::IsEntityCullZoneVisible(CEntity *ent)
-{
- CPed *ped;
- CObject *obj;
-
- if(gbDisableZoneCull) return true;
-
-#ifndef MASTER
- switch(ent->GetType()){
- case ENTITY_TYPE_BUILDING:
- if(ent->bIsBIGBuilding)
- TestedBigBuildings++;
- else
- TestedBuildings++;
- break;
- case ENTITY_TYPE_VEHICLE:
- TestedCars++;
- break;
- case ENTITY_TYPE_PED:
- TestedPeds++;
- break;
- case ENTITY_TYPE_OBJECT:
- TestedObjects++;
- break;
- case ENTITY_TYPE_DUMMY:
- TestedDummies++;
- break;
- }
-#endif
- if(ent->bZoneCulled)
- return false;
-
-
- switch(ent->GetType()){
- case ENTITY_TYPE_VEHICLE:
- return IsVehicleCullZoneVisible(ent);
- case ENTITY_TYPE_PED:
- ped = (CPed*)ent;
- if (ped->bInVehicle) {
- if (ped->m_pMyVehicle)
- return IsVehicleCullZoneVisible(ped->m_pMyVehicle);
- else
- return true;
- }
- return !(ped->m_pCurSurface && ped->m_pCurSurface->bZoneCulled2);
- case ENTITY_TYPE_OBJECT:
- obj = (CObject*)ent;
- if(!obj->GetIsStatic())
- return true;
- return !(obj->m_pCurSurface && obj->m_pCurSurface->bZoneCulled2);
- default: break;
- }
- return true;
-}
-
-bool
-CRenderer::IsVehicleCullZoneVisible(CEntity *ent)
-{
- CVehicle *v = (CVehicle*)ent;
- switch(v->GetStatus()) {
- case STATUS_SIMPLE:
- case STATUS_PHYSICS:
- case STATUS_ABANDONED:
- case STATUS_WRECKED:
- return !(v->m_pCurGroundEntity && v->m_pCurGroundEntity->bZoneCulled2);
- default: break;
- }
- return true;
-}
-
void
CRenderer::RemoveVehiclePedLights(CEntity *ent, bool reset)
{
- if(ent->bRenderScorched){
- WorldReplaceScorchedLightsWithNormal(Scene.world);
- return;
+ if(!ent->bRenderScorched){
+ CPointLights::RemoveLightsAffectingObject();
+ if(reset)
+ ReSetAmbientAndDirectionalColours();
}
- CPointLights::RemoveLightsAffectingObject();
- if(reset)
- ReSetAmbientAndDirectionalColours();
+ SetAmbientColours();
+ DeActivateDirectional();
}
diff --git a/src/renderer/Renderer.h b/src/renderer/Renderer.h
index 0322939c..9b202098 100644
--- a/src/renderer/Renderer.h
+++ b/src/renderer/Renderer.h
@@ -10,20 +10,10 @@ class CEntity;
#define FADE_DISTANCE 20.0f
#define STREAM_DISTANCE 30.0f
-#ifdef EXTRA_MODEL_FLAGS
-#define BACKFACE_CULLING_ON SetCullMode(rwCULLMODECULLBACK)
-#define BACKFACE_CULLING_OFF SetCullMode(rwCULLMODECULLNONE)
-#else
-#define BACKFACE_CULLING_ON
-#define BACKFACE_CULLING_OFF
-#endif
-
extern bool gbShowPedRoadGroups;
extern bool gbShowCarRoadGroups;
extern bool gbShowCollisionPolys;
extern bool gbShowCollisionLines;
-extern bool gbShowCullZoneDebugStuff;
-extern bool gbDisableZoneCull; // not original
extern bool gbBigWhiteDebugLightSwitchedOn;
extern bool gbDontRenderBuildings;
@@ -73,16 +63,14 @@ public:
static void RenderRoads(void);
static void RenderFadingInEntities(void);
+ static void RenderFadingInUnderwaterEntities(void);
static void RenderEverythingBarRoads(void);
- static void RenderVehiclesButNotBoats(void);
static void RenderBoats(void);
static void RenderOneRoad(CEntity *);
static void RenderOneNonRoad(CEntity *);
static void RenderFirstPersonVehicle(void);
static void RenderCollisionLines(void);
- // unused
- static void RenderBlockBuildingLines(void);
static int32 SetupEntityVisibility(CEntity *ent);
static int32 SetupBigBuildingVisibility(CEntity *ent);
@@ -100,9 +88,7 @@ public:
static void SortBIGBuildings(void);
static void SortBIGBuildingsForSectorList(CPtrList *list);
- static bool ShouldModelBeStreamed(CEntity *ent);
- static bool IsEntityCullZoneVisible(CEntity *ent);
- static bool IsVehicleCullZoneVisible(CEntity *ent);
+ static bool ShouldModelBeStreamed(CEntity *ent, const CVector &campos);
static void RemoveVehiclePedLights(CEntity *ent, bool reset);
@@ -113,7 +99,7 @@ public:
static void RenderVehicles(void); // also renders peds in LCS
static void RenderOneBuilding(CEntity *ent, float camdist = 0.0f);
static void RenderWorld(int pass); // like cWorldStream::Render(int)
- static void RenderWater(void); // keep-out polys and water
+ static void RenderTransparentWater(void); // keep-out polys and transparent water
#endif
static void InsertEntityIntoList(CEntity *ent);
};
diff --git a/src/renderer/Rubbish.cpp b/src/renderer/Rubbish.cpp
index 8da6b025..147c97b1 100644
--- a/src/renderer/Rubbish.cpp
+++ b/src/renderer/Rubbish.cpp
@@ -8,17 +8,16 @@
#include "World.h"
#include "Vehicle.h"
#include "ZoneCull.h"
+#include "Stats.h"
#include "TxdStore.h"
#include "RenderBuffer.h"
#include "Rubbish.h"
-#define RUBBISH_MAX_DIST (18.0f)
-#define RUBBISH_FADE_DIST (16.5f)
+#define RUBBISH_MAX_DIST (23.0f)
+#define RUBBISH_FADE_DIST (20.0f)
RwTexture *gpRubbishTexture[4];
RwImVertexIndex RubbishIndexList[6];
-RwImVertexIndex RubbishIndexList2[6]; // unused
-RwIm3DVertex RubbishVertices[4];
bool CRubbish::bRubbishInvisible;
int CRubbish::RubbishVisibility;
COneSheet CRubbish::aSheets[NUM_RUBBISH_SHEETS];
@@ -52,6 +51,9 @@ CRubbish::Render(void)
{
int type;
+ if(RubbishVisibility == 0)
+ return;
+
PUSH_RENDERGROUP("CRubbish::Render");
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
@@ -59,7 +61,8 @@ CRubbish::Render(void)
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE);
for(type = 0; type < 4; type++){
- RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpRubbishTexture[type]));
+ if(type < 3 || CStats::PamphletMissionPassed)
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpRubbishTexture[type]));
TempBufferIndicesStored = 0;
TempBufferVerticesStored = 0;
@@ -71,7 +74,7 @@ CRubbish::Render(void)
if(sheet->m_state == 0)
continue;
- uint32 alpha = 128;
+ uint32 alpha = 100;
CVector pos;
if(sheet->m_state == 1){
pos = sheet->m_basePos;
@@ -84,7 +87,7 @@ CRubbish::Render(void)
float t = (float)(CTimer::GetTimeInMilliseconds() - sheet->m_moveStart)/sheet->m_moveDuration;
float f1 = sheet->m_isVisible ? 1.0f-t : 0.0f;
float f2 = sheet->m_targetIsVisible ? t : 0.0f;
- alpha = 128 * (f1+f2);
+ alpha = 100 * (f1+f2);
}
}
@@ -94,17 +97,27 @@ CRubbish::Render(void)
alpha -= alpha*(camDist-RUBBISH_FADE_DIST)/(RUBBISH_MAX_DIST-RUBBISH_FADE_DIST);
alpha = (RubbishVisibility*alpha)/256;
- float vx = Sin(sheet->m_angle) * 0.4f;
- float vy = Cos(sheet->m_angle) * 0.4f;
+ float vx1, vy1, vx2, vy2;
+ if(type == 0 || type == 1){
+ vx1 = 0.9f*Sin(sheet->m_angle);
+ vy1 = 0.9f*Cos(sheet->m_angle);
+ vx2 = 0.3f*Cos(sheet->m_angle);
+ vy2 = -0.3f*Sin(sheet->m_angle);
+ }else{
+ vx1 = 0.3f*Sin(sheet->m_angle);
+ vy1 = 0.3f*Cos(sheet->m_angle);
+ vx2 = 0.3f*Cos(sheet->m_angle);
+ vy2 = -0.3f*Sin(sheet->m_angle);
+ }
int v = TempBufferVerticesStored;
- RwIm3DVertexSetPos(&TempBufferRenderVertices[v+0], pos.x + vx, pos.y + vy, pos.z);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[v+0], pos.x + vx1 + vx2, pos.y + vy1 + vy2, pos.z);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[v+1], pos.x + vx1 - vx2, pos.y + vy1 - vy2, pos.z);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[v+2], pos.x - vx1 + vx2, pos.y - vy1 + vy2, pos.z);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[v+3], pos.x - vx1 - vx2, pos.y - vy1 - vy2, pos.z);
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[v+0], 255, 255, 255, alpha);
- RwIm3DVertexSetPos(&TempBufferRenderVertices[v+1], pos.x - vy, pos.y + vx, pos.z);
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[v+1], 255, 255, 255, alpha);
- RwIm3DVertexSetPos(&TempBufferRenderVertices[v+2], pos.x + vy, pos.y - vx, pos.z);
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[v+2], 255, 255, 255, alpha);
- RwIm3DVertexSetPos(&TempBufferRenderVertices[v+3], pos.x - vx, pos.y - vy, pos.z);
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[v+3], 255, 255, 255, alpha);
RwIm3DVertexSetU(&TempBufferRenderVertices[v+0], 0.0f);
RwIm3DVertexSetV(&TempBufferRenderVertices[v+0], 0.0f);
@@ -377,24 +390,6 @@ CRubbish::Init(void)
EndMoversList.m_next = nil;
EndMoversList.m_prev = &StartMoversList;
- // unused
- RwIm3DVertexSetU(&RubbishVertices[0], 0.0f);
- RwIm3DVertexSetV(&RubbishVertices[0], 0.0f);
- RwIm3DVertexSetU(&RubbishVertices[1], 1.0f);
- RwIm3DVertexSetV(&RubbishVertices[1], 0.0f);
- RwIm3DVertexSetU(&RubbishVertices[2], 0.0f);
- RwIm3DVertexSetV(&RubbishVertices[2], 1.0f);
- RwIm3DVertexSetU(&RubbishVertices[3], 1.0f);
- RwIm3DVertexSetV(&RubbishVertices[3], 1.0f);
-
- // unused
- RubbishIndexList2[0] = 0;
- RubbishIndexList2[1] = 2;
- RubbishIndexList2[2] = 1;
- RubbishIndexList2[3] = 1;
- RubbishIndexList2[4] = 2;
- RubbishIndexList2[5] = 3;
-
RubbishIndexList[0] = 0;
RubbishIndexList[1] = 1;
RubbishIndexList[2] = 2;
@@ -418,19 +413,11 @@ void
CRubbish::Shutdown(void)
{
RwTextureDestroy(gpRubbishTexture[0]);
-#if GTA_VERSION >= GTA3_PC_11
gpRubbishTexture[0] = nil;
-#endif
RwTextureDestroy(gpRubbishTexture[1]);
-#if GTA_VERSION >= GTA3_PC_11
gpRubbishTexture[1] = nil;
-#endif
RwTextureDestroy(gpRubbishTexture[2]);
-#if GTA_VERSION >= GTA3_PC_11
gpRubbishTexture[2] = nil;
-#endif
RwTextureDestroy(gpRubbishTexture[3]);
-#if GTA_VERSION >= GTA3_PC_11
gpRubbishTexture[3] = nil;
-#endif
}
diff --git a/src/renderer/Rubbish.h b/src/renderer/Rubbish.h
index 37f895f3..5a4e479b 100644
--- a/src/renderer/Rubbish.h
+++ b/src/renderer/Rubbish.h
@@ -53,3 +53,5 @@ public:
static void Init(void);
static void Shutdown(void);
};
+
+extern RwTexture *gpRubbishTexture[4];
diff --git a/src/renderer/ShadowCamera.cpp b/src/renderer/ShadowCamera.cpp
new file mode 100644
index 00000000..f69c234f
--- /dev/null
+++ b/src/renderer/ShadowCamera.cpp
@@ -0,0 +1,549 @@
+#include "common.h"
+#include "rwcore.h"
+#include "ShadowCamera.h"
+#include "RwHelper.h"
+
+#define TEXELOFFSET 0.5f
+
+RpAtomic *ShadowRenderCallBack(RpAtomic *atomic, void *data)
+{
+ RpAtomicCallBackRender savedCB = RpAtomicGetRenderCallBack(atomic);
+ RpAtomicSetRenderCallBack(atomic, AtomicDefaultRenderCallBack);
+ RpAtomicRender(atomic);
+ RpAtomicSetRenderCallBack(atomic, savedCB);
+ return atomic;
+}
+
+CShadowCamera::CShadowCamera()
+{
+ m_pCamera = nil;
+ m_pTexture = nil;
+}
+
+CShadowCamera::~CShadowCamera()
+{
+ Destroy();
+}
+
+void
+CShadowCamera::Destroy()
+{
+ if ( m_pCamera )
+ {
+ RwRaster *raster;
+ RwFrame *frame;
+
+ frame = RwCameraGetFrame(m_pCamera);
+
+ if ( frame )
+ {
+ RwCameraSetFrame(m_pCamera, nil);
+ RwFrameDestroy(frame);
+ }
+
+ raster = RwCameraGetZRaster(m_pCamera);
+ if ( raster )
+ {
+ RwCameraSetZRaster(m_pCamera, nil);
+ RwRasterDestroy(raster);
+ }
+
+ raster = RwCameraGetRaster(m_pCamera);
+ if ( raster )
+ {
+ RwCameraSetRaster(m_pCamera, nil);
+ RwRasterDestroy(raster);
+ }
+
+ if ( m_pTexture )
+ {
+ RwTextureSetRaster(m_pTexture, nil);
+ RwTextureDestroy(m_pTexture);
+ m_pTexture = nil;
+ }
+
+ RwCameraDestroy(m_pCamera);
+ m_pCamera = nil;
+ }
+ return;
+}
+
+RwCamera *
+CShadowCamera::Create(int32 rasterSize)
+{
+ int32 size = 1 << rasterSize;
+
+ m_pCamera = RwCameraCreate();
+ ASSERT(m_pCamera != nil);
+
+ if ( m_pCamera )
+ {
+ RwCameraSetFrame(m_pCamera, RwFrameCreate());
+
+ if( RwCameraGetFrame(m_pCamera) )
+ {
+ RwRaster *zRaster = RwRasterCreate(size, size, 0, rwRASTERTYPEZBUFFER);
+ ASSERT(zRaster != nil);
+
+ if ( zRaster )
+ {
+ RwCameraSetZRaster(m_pCamera, zRaster);
+
+ RwRaster *raster = RwRasterCreate(size, size, 0, rwRASTERTYPECAMERATEXTURE);
+ ASSERT(raster != nil);
+
+ if ( raster )
+ {
+ RwCameraSetRaster(m_pCamera, raster);
+ m_pTexture = RwTextureCreate(raster);
+ ASSERT(m_pTexture != nil);
+
+ if ( m_pTexture )
+ {
+ RwTextureSetAddressing(m_pTexture, rwTEXTUREADDRESSCLAMP);
+ RwTextureSetFilterMode(m_pTexture, rwFILTERLINEAR);
+ RwCameraSetProjection(m_pCamera, rwPARALLEL);
+ return (m_pCamera);
+ }
+ }
+ }
+ }
+ }
+
+ Destroy();
+
+ return (nil);
+}
+
+RwCamera *
+CShadowCamera::SetFrustum(float objectRadius)
+{
+ ASSERT(m_pCamera != nil);
+
+ RwV2d vw;
+
+ RwCameraSetFarClipPlane (m_pCamera, 2.0f * objectRadius);
+ RwCameraSetNearClipPlane(m_pCamera, 0.001f * objectRadius);
+
+ vw.x = objectRadius;
+ vw.y = objectRadius;
+ RwCameraSetViewWindow(m_pCamera, &vw);
+
+ return m_pCamera;
+}
+
+RwCamera *
+CShadowCamera::SetLight(RpLight *light)
+{
+ ASSERT(light != nil);
+ ASSERT(m_pCamera != nil);
+
+ RwFrame *camFrame = RwCameraGetFrame(m_pCamera);
+ RwMatrix *camMatrix = RwFrameGetMatrix(camFrame);
+ RwFrame *lightFrame = RpLightGetFrame(light);
+ RwMatrix *lightMatrix = RwFrameGetMatrix(lightFrame);
+
+ *RwMatrixGetRight(camMatrix) = *RwMatrixGetRight(lightMatrix);
+ *RwMatrixGetUp(camMatrix) = *RwMatrixGetUp(lightMatrix);
+ *RwMatrixGetAt(camMatrix) = *RwMatrixGetAt(lightMatrix);
+
+ RwMatrixUpdate(camMatrix);
+ RwFrameUpdateObjects(camFrame);
+
+ return m_pCamera;
+}
+
+RwCamera *
+CShadowCamera::SetCenter(RwV3d *center)
+{
+ ASSERT(center != nil);
+ ASSERT(m_pCamera != nil);
+
+ RwFrame *camFrame = RwCameraGetFrame(m_pCamera);
+ RwMatrix *camMatrix = RwFrameGetMatrix(camFrame);
+
+ *RwMatrixGetPos(camMatrix) = *center;
+
+ RwV3dIncrementScaled(RwMatrixGetPos(camMatrix), RwMatrixGetAt(camMatrix), -0.5f * RwCameraGetFarClipPlane(m_pCamera));
+
+ RwMatrixUpdate(camMatrix);
+ RwFrameUpdateObjects(camFrame);
+ RwFrameOrthoNormalize(camFrame);
+
+ return m_pCamera;
+}
+
+RwCamera *
+CShadowCamera::Update(RpClump *clump)
+{
+ ASSERT(clump != nil);
+ ASSERT(m_pCamera != nil);
+
+ RwUInt32 flags;
+ RpGeometry *geometry;
+
+ RwRGBA bgColor = { 255, 255, 255, 0 };
+
+ RwCameraClear(m_pCamera, &bgColor, rwCAMERACLEARZ | rwCAMERACLEARIMAGE);
+
+ if ( RwCameraBeginUpdate(m_pCamera) )
+ {
+ geometry = RpAtomicGetGeometry(GetFirstAtomic(clump));
+ ASSERT(geometry != nil);
+
+ flags = RpGeometryGetFlags(geometry);
+
+ RpGeometrySetFlags(geometry, flags & ~(rpGEOMETRYPRELIT|rpGEOMETRYLIGHT
+ |rpGEOMETRYTEXTURED|rpGEOMETRYTEXTURED2|rpGEOMETRYMODULATEMATERIALCOLOR));
+
+ RpClumpForAllAtomics(clump, ShadowRenderCallBack, nil);
+
+ RpGeometrySetFlags(geometry, flags);
+
+ InvertRaster();
+ RwCameraEndUpdate(m_pCamera);
+ }
+
+ return m_pCamera;
+}
+
+RwCamera *
+CShadowCamera::Update(RpAtomic *atomic)
+{
+ ASSERT(atomic != nil);
+ ASSERT(m_pCamera != nil);
+
+ RwUInt32 flags;
+ RpGeometry *geometry;
+
+ RwRGBA bgColor = { 255, 255, 255, 0 };
+
+ RwCameraClear(m_pCamera, &bgColor, rwCAMERACLEARZ | rwCAMERACLEARIMAGE);
+
+ if ( RwCameraBeginUpdate(m_pCamera) )
+ {
+ geometry = RpAtomicGetGeometry(atomic);
+ ASSERT(geometry != nil);
+ flags = RpGeometryGetFlags(geometry);
+
+ RpGeometrySetFlags(geometry, flags & ~(rpGEOMETRYPRELIT|rpGEOMETRYLIGHT
+ |rpGEOMETRYTEXTURED|rpGEOMETRYTEXTURED2|rpGEOMETRYMODULATEMATERIALCOLOR|rpGEOMETRYNORMALS));
+
+ ShadowRenderCallBack(atomic, nil);
+
+ RpGeometrySetFlags(geometry, flags);
+
+ InvertRaster();
+ RwCameraEndUpdate(m_pCamera);
+ }
+
+ return m_pCamera;
+}
+
+void
+CShadowCamera::InvertRaster()
+{
+ ASSERT(m_pCamera != nil);
+
+ RwIm2DVertex vx[4];
+ float crw, crh;
+ RwRaster *raster;
+ float recipZ;
+
+ raster = RwCameraGetRaster(m_pCamera);
+ ASSERT(raster != nil);
+
+ crw = (float)RwRasterGetWidth(raster);
+ crh = (float)RwRasterGetHeight(raster);
+
+ recipZ = 1.0f / RwCameraGetNearClipPlane(m_pCamera);
+
+ RwIm2DVertexSetScreenX (&vx[0], 0.0f);
+ RwIm2DVertexSetScreenY (&vx[0], 0.0f);
+ RwIm2DVertexSetScreenZ (&vx[0], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetRecipCameraZ(&vx[0], recipZ);
+ RwIm2DVertexSetIntRGBA (&vx[0], 255, 255, 255, 255);
+
+ RwIm2DVertexSetScreenX (&vx[1], 0.0f);
+ RwIm2DVertexSetScreenY (&vx[1], crh);
+ RwIm2DVertexSetScreenZ (&vx[1], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetRecipCameraZ(&vx[1], recipZ);
+ RwIm2DVertexSetIntRGBA (&vx[1], 255, 255, 255, 255);
+
+ RwIm2DVertexSetScreenX (&vx[2], crw);
+ RwIm2DVertexSetScreenY (&vx[2], 0.0f);
+ RwIm2DVertexSetScreenZ (&vx[2], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetRecipCameraZ(&vx[2], recipZ);
+ RwIm2DVertexSetIntRGBA (&vx[2], 255, 255, 255, 255);
+
+ RwIm2DVertexSetScreenX (&vx[3], crw);
+ RwIm2DVertexSetScreenY (&vx[3], crh);
+ RwIm2DVertexSetScreenZ (&vx[3], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetRecipCameraZ(&vx[3], recipZ);
+ RwIm2DVertexSetIntRGBA (&vx[3], 255, 255, 255, 255);
+
+
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)FALSE);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)nil);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)TRUE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDINVDESTCOLOR);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDZERO);
+
+ RwIm2DRenderPrimitive(rwPRIMTYPETRISTRIP, vx, 4);
+
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)TRUE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA);
+}
+
+RwRaster *
+CShadowCamera::MakeGradientRaster()
+{
+ ASSERT(m_pCamera != nil);
+
+ RwIm2DVertex vx[2];
+
+ if ( !m_pCamera )
+ return nil;
+
+ float recipCamZ = 1.0f / RwCameraGetNearClipPlane(m_pCamera);
+
+ RwRaster *raster = RwCameraGetRaster(m_pCamera);
+ ASSERT(raster != nil);
+
+ float width = (float)RwRasterGetWidth(raster);
+ float height = (float)RwRasterGetHeight(raster);
+
+ if ( height < 1 )
+ return nil;
+
+ if ( RwCameraBeginUpdate(m_pCamera) )
+ {
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)rwFILTERNAFILTERMODE);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)FALSE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)FALSE);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDZERO);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDINVDESTCOLOR);
+ RwRenderStateSet(rwRENDERSTATESHADEMODE, (void *)rwSHADEMODEFLAT);
+
+ float color = 255.0f;
+ float step = (-191.0f / height);
+
+ for ( int32 i = 0; i < height; i++ )
+ {
+ RwIm2DVertexSetScreenX (&vx[0], 0.0f);
+ RwIm2DVertexSetScreenY (&vx[0], i);
+ RwIm2DVertexSetScreenZ (&vx[0], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetRecipCameraZ(&vx[0], recipCamZ);
+ RwIm2DVertexSetIntRGBA (&vx[0], (uint32)color, (uint32)color, (uint32)color, (uint32)color);
+
+ RwIm2DVertexSetScreenX (&vx[1], width - 1);
+ RwIm2DVertexSetScreenY (&vx[1], i);
+ RwIm2DVertexSetScreenZ (&vx[1], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetRecipCameraZ(&vx[1], recipCamZ);
+ RwIm2DVertexSetIntRGBA (&vx[1], (uint32)color, (uint32)color, (uint32)color, (uint32)color);
+
+ RwIm2DRenderLine(vx, 2, 0, 1);
+
+ color += step;
+ }
+
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)TRUE);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATESHADEMODE, (void *)rwSHADEMODEGOURAUD);
+
+ RwCameraEndUpdate(m_pCamera);
+ }
+
+ return raster;
+}
+
+RwRaster *
+CShadowCamera::RasterResample(RwRaster *dstRaster)
+{
+ ASSERT(dstRaster != nil);
+ ASSERT(m_pCamera != nil);
+
+ if ( !m_pCamera )
+ return nil;
+
+ RwRaster *raster = RwCameraGetRaster(m_pCamera);
+ ASSERT(raster != nil);
+
+ float size = (float) RwRasterGetWidth(raster);
+ float uvOffset = TEXELOFFSET / size;
+ float recipCamZ = 1.0f / RwCameraGetNearClipPlane(m_pCamera);
+
+ if ( RwCameraBeginUpdate(m_pCamera) )
+ {
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDONE);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDZERO);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)FALSE);
+ RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void *)rwFILTERLINEAR);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)dstRaster);
+
+ Im2DRenderQuad(0.0f, 0.0f, size, size, RwIm2DGetNearScreenZ(), recipCamZ, uvOffset);
+
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)TRUE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA);
+
+ RwCameraEndUpdate(m_pCamera);
+ }
+
+ return raster;
+}
+
+RwRaster *
+CShadowCamera::RasterBlur(RwRaster *dstRaster, int32 numPasses)
+{
+ ASSERT(dstRaster != nil);
+ ASSERT(m_pCamera != nil);
+
+ if ( !m_pCamera )
+ return nil;
+
+ RwRaster *raster = RwCameraGetRaster(m_pCamera);
+ ASSERT(raster != nil);
+
+ float size = (float) RwRasterGetWidth(dstRaster);
+ float recipCamZ = 1.0f / RwCameraGetNearClipPlane(m_pCamera);
+
+ for (int i = 0; i < numPasses; i++ )
+ {
+ RwCameraSetRaster(m_pCamera, raster);
+
+ if ( RwCameraBeginUpdate(m_pCamera) )
+ {
+ if ( i == 0 )
+ {
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDONE);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDZERO);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)FALSE);
+ RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void *)rwFILTERLINEAR);
+ }
+
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)dstRaster);
+ Im2DRenderQuad(0.0f, 0.0f, size, size, RwIm2DGetNearScreenZ(), recipCamZ, 1.0f / size);
+ RwCameraEndUpdate(m_pCamera);
+ }
+
+ RwCameraSetRaster(m_pCamera, dstRaster);
+
+ if ( RwCameraBeginUpdate(m_pCamera) )
+ {
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)raster);
+ Im2DRenderQuad(0.0f, 0.0f, size, size, RwIm2DGetNearScreenZ(), recipCamZ, 0);
+
+ if ( i == numPasses - 1 )
+ {
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)TRUE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA);
+ }
+
+ RwCameraEndUpdate(m_pCamera);
+ }
+ }
+
+ RwCameraSetRaster(m_pCamera, raster);
+
+ return dstRaster;
+}
+
+RwRaster *
+CShadowCamera::RasterGradient(RwRaster *dstRaster)
+{
+ ASSERT(dstRaster != nil);
+ ASSERT(m_pCamera != nil);
+
+ RwRaster *raster = RwCameraGetRaster(m_pCamera);
+ ASSERT(raster != nil);
+
+ float size = (float)RwRasterGetWidth(dstRaster);
+ float recipCamZ = 1.0f / RwCameraGetNearClipPlane(m_pCamera);
+
+ RwCameraSetRaster(m_pCamera, dstRaster);
+
+ if ( RwCameraBeginUpdate(m_pCamera) )
+ {
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDZERO);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDSRCCOLOR);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)FALSE);
+ RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void *)rwFILTERLINEAR);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)raster);
+
+ Im2DRenderQuad(0, 0, size, size, RwIm2DGetNearScreenZ(), recipCamZ, 0);
+
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)TRUE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA);
+
+ RwCameraEndUpdate(m_pCamera);
+ }
+
+ RwCameraSetRaster(m_pCamera, raster);
+
+ return dstRaster;
+}
+
+RwRaster *CShadowCamera::DrawOutlineBorder(RwRGBA const& color)
+{
+ ASSERT(m_pCamera != nil);
+
+ RwIm2DVertex vx[4];
+ RwImVertexIndex ix[5];
+
+ RwRaster *raster = RwCameraGetRaster(m_pCamera);
+ ASSERT(raster != nil);
+
+ float size = (float)RwRasterGetWidth(raster) - 1.0f;
+ float recipCamZ = 1.0f / RwCameraGetNearClipPlane(m_pCamera);
+
+ RwIm2DVertexSetScreenX (&vx[0], 0.0f);
+ RwIm2DVertexSetScreenY (&vx[0], 0.0f);
+ RwIm2DVertexSetScreenZ (&vx[0], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetIntRGBA (&vx[0], color.red, color.green, color.blue, color.alpha);
+ RwIm2DVertexSetRecipCameraZ(&vx[0], recipCamZ);
+
+ RwIm2DVertexSetScreenX (&vx[1], size);
+ RwIm2DVertexSetScreenY (&vx[1], 0.0f);
+ RwIm2DVertexSetScreenZ (&vx[1], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetIntRGBA (&vx[1], color.red, color.green, color.blue, color.alpha);
+ RwIm2DVertexSetRecipCameraZ(&vx[1], recipCamZ);
+
+ RwIm2DVertexSetScreenX (&vx[2], size);
+ RwIm2DVertexSetScreenY (&vx[2], size);
+ RwIm2DVertexSetScreenZ (&vx[2], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetIntRGBA (&vx[2], color.red, color.green, color.blue, color.alpha);
+ RwIm2DVertexSetRecipCameraZ(&vx[2], recipCamZ);
+
+ RwIm2DVertexSetScreenX (&vx[3], 0.0f);
+ RwIm2DVertexSetScreenY (&vx[3], size);
+ RwIm2DVertexSetScreenZ (&vx[3], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetIntRGBA (&vx[3], color.red, color.green, color.blue, color.alpha);
+ RwIm2DVertexSetRecipCameraZ(&vx[3], recipCamZ);
+
+ ix[0] = 0;
+ ix[4] = 0;
+ ix[1] = 1;
+ ix[2] = 2;
+ ix[3] = 3;
+
+ if ( RwCameraBeginUpdate(m_pCamera) )
+ {
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)FALSE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)FALSE);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)nil);
+
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPEPOLYLINE, vx, 4, ix, 5);
+
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)TRUE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)TRUE);
+
+ RwCameraEndUpdate(m_pCamera);
+ }
+
+ return raster;
+} \ No newline at end of file
diff --git a/src/renderer/ShadowCamera.h b/src/renderer/ShadowCamera.h
new file mode 100644
index 00000000..a2149db7
--- /dev/null
+++ b/src/renderer/ShadowCamera.h
@@ -0,0 +1,54 @@
+#pragma once
+
+
+class CShadowCamera
+{
+public:
+ RwCamera *m_pCamera;
+ RwTexture *m_pTexture;
+
+ CShadowCamera();
+ ~CShadowCamera();
+
+ RwCamera *Create(int32 rasterSize);
+ void Destroy();
+
+ RwCamera *SetFrustum(float objectRadius);
+ RwCamera *SetLight(RpLight *light);
+ RwCamera *SetCenter(RwV3d *center);
+
+ RwCamera *Update(RpClump *clump);
+ RwCamera *Update(RpAtomic *atomic);
+
+ void InvertRaster();
+
+ RwRaster* GetRwRenderRaster()
+ {
+ return RwCameraGetRaster(m_pCamera);
+ }
+
+ // ShadowRasterRender(RwV2d *)
+ // ApplyAlphaMapToRaster(void)
+
+ RwRaster *MakeGradientRaster();
+
+ RwTexture *GetRwRenderTexture()
+ {
+ return m_pTexture;
+ }
+
+ RwRaster* GetRwZRaster()
+ {
+ return RwCameraGetZRaster(m_pCamera);
+ }
+
+ RwRaster *RasterResample(RwRaster *dstRaster);
+ RwRaster *RasterBlur(RwRaster *dstRaster, int32 numPasses);
+ RwRaster *RasterGradient(RwRaster *dstRaster);
+ RwRaster *DrawOutlineBorder(RwRGBA const& color);
+
+ RwCamera *GetRwCamera()
+ {
+ return m_pCamera;
+ }
+}; \ No newline at end of file
diff --git a/src/renderer/Shadows.cpp b/src/renderer/Shadows.cpp
index 3884d3bb..dd87bff6 100644
--- a/src/renderer/Shadows.cpp
+++ b/src/renderer/Shadows.cpp
@@ -7,6 +7,7 @@
#include "Timecycle.h"
#include "CutsceneMgr.h"
#include "Automobile.h"
+#include "Bike.h"
#include "Ped.h"
#include "PlayerPed.h"
#include "World.h"
@@ -18,7 +19,13 @@
#endif
#include "PointLights.h"
#include "SpecialFX.h"
+#include "Script.h"
+#include "TimeStep.h"
#include "Shadows.h"
+#include "CutsceneObject.h"
+#include "CutsceneShadow.h"
+#include "Clock.h"
+#include "VarConsole.h"
#ifdef DEBUGMENU
//SETTWEAKPATH("Shadows");
@@ -30,6 +37,8 @@ RwImVertexIndex ShadowIndexList[24];
RwTexture *gpShadowCarTex;
RwTexture *gpShadowPedTex;
RwTexture *gpShadowHeliTex;
+RwTexture *gpShadowBikeTex;
+RwTexture *gpShadowBaronTex;
RwTexture *gpShadowExplosionTex;
RwTexture *gpShadowHeadLightsTex;
RwTexture *gpOutline1Tex;
@@ -37,7 +46,6 @@ RwTexture *gpOutline2Tex;
RwTexture *gpOutline3Tex;
RwTexture *gpBloodPoolTex;
RwTexture *gpReflectionTex;
-RwTexture *gpGoalMarkerTex;
RwTexture *gpWalkDontTex;
RwTexture *gpCrackedGlassTex;
RwTexture *gpPostShadowTex;
@@ -50,6 +58,9 @@ CStaticShadow CShadows::aStaticShadows [MAX_STATICSHADOWS];
CPolyBunch *CShadows::pEmptyBunchList;
CPermanentShadow CShadows::aPermanentShadows[MAX_PERMAMENTSHADOWS];
+#ifndef MASTER
+bool gbCountPolysInShadow;
+#endif
void
CShadows::Init(void)
@@ -59,37 +70,39 @@ CShadows::Init(void)
int32 slut = CTxdStore::FindTxdSlot("particle");
CTxdStore::SetCurrentTxd(slut);
- gpShadowCarTex = RwTextureRead("shad_car", NULL);
- gpShadowPedTex = RwTextureRead("shad_ped", NULL);
- gpShadowHeliTex = RwTextureRead("shad_heli", NULL);
- gpShadowExplosionTex = RwTextureRead("shad_exp", NULL);
- gpShadowHeadLightsTex = RwTextureRead("headlight", NULL);
- gpOutline1Tex = RwTextureRead("outline_64", NULL);
- gpOutline2Tex = RwTextureRead("outline2_64", NULL);
- gpOutline3Tex = RwTextureRead("outline3_64", NULL);
- gpBloodPoolTex = RwTextureRead("bloodpool_64", NULL);
- gpReflectionTex = RwTextureRead("reflection01", NULL);
- gpGoalMarkerTex = RwTextureRead("goal", NULL);
- gpWalkDontTex = RwTextureRead("walk_dont", NULL);
- gpCrackedGlassTex = RwTextureRead("wincrack_32", NULL);
- gpPostShadowTex = RwTextureRead("lamp_shad_64", NULL);
+ gpShadowCarTex = RwTextureRead("shad_car", nil);
+ gpShadowPedTex = RwTextureRead("shad_ped", nil);
+ gpShadowHeliTex = RwTextureRead("shad_heli", nil);
+ gpShadowBikeTex = RwTextureRead("shad_bike", nil);
+ gpShadowBaronTex = RwTextureRead("shad_rcbaron", nil);
+ gpShadowExplosionTex = RwTextureRead("shad_exp", nil);
+ gpShadowHeadLightsTex = RwTextureRead("headlight", nil);
+ gpOutline1Tex = RwTextureRead("outline_64", nil);
+ gpOutline2Tex = RwTextureRead("outline2_64", nil);
+ gpOutline3Tex = RwTextureRead("outline3_64", nil);
+ gpBloodPoolTex = RwTextureRead("bloodpool_64", nil);
+ gpReflectionTex = RwTextureRead("reflection01", nil);
+ gpWalkDontTex = RwTextureRead("walk_dont", nil);
+ gpCrackedGlassTex = RwTextureRead("wincrack_32", nil);
+ gpPostShadowTex = RwTextureRead("lamp_shad_64", nil);
CTxdStore::PopCurrentTxd();
- ASSERT(gpShadowCarTex != NULL);
- ASSERT(gpShadowPedTex != NULL);
- ASSERT(gpShadowHeliTex != NULL);
- ASSERT(gpShadowExplosionTex != NULL);
- ASSERT(gpShadowHeadLightsTex != NULL);
- ASSERT(gpOutline1Tex != NULL);
- ASSERT(gpOutline2Tex != NULL);
- ASSERT(gpOutline3Tex != NULL);
- ASSERT(gpBloodPoolTex != NULL);
- ASSERT(gpReflectionTex != NULL);
- ASSERT(gpGoalMarkerTex != NULL);
- ASSERT(gpWalkDontTex != NULL);
- ASSERT(gpCrackedGlassTex != NULL);
- ASSERT(gpPostShadowTex != NULL);
+ ASSERT(gpShadowCarTex != nil);
+ ASSERT(gpShadowPedTex != nil);
+ ASSERT(gpShadowHeliTex != nil);
+ ASSERT(gpShadowBikeTex != nil);
+ ASSERT(gpShadowBaronTex != nil);
+ ASSERT(gpShadowExplosionTex != nil);
+ ASSERT(gpShadowHeadLightsTex != nil);
+ ASSERT(gpOutline1Tex != nil);
+ ASSERT(gpOutline2Tex != nil);
+ ASSERT(gpOutline3Tex != nil);
+ ASSERT(gpBloodPoolTex != nil);
+ ASSERT(gpReflectionTex != nil);
+ ASSERT(gpWalkDontTex != nil);
+ ASSERT(gpCrackedGlassTex != nil);
+ ASSERT(gpPostShadowTex != nil);
ShadowIndexList[0] = 0;
@@ -128,7 +141,7 @@ CShadows::Init(void)
for ( int32 i = 0; i < MAX_STATICSHADOWS; i++ )
{
aStaticShadows[i].m_nId = 0;
- aStaticShadows[i].m_pPolyBunch = NULL;
+ aStaticShadows[i].m_pPolyBunch = nil;
}
pEmptyBunchList = &aPolyBunches[0];
@@ -136,7 +149,7 @@ CShadows::Init(void)
for ( int32 i = 0; i < MAX_POLYBUNCHES; i++ )
{
if ( i == MAX_POLYBUNCHES - 1 )
- aPolyBunches[i].m_pNext = NULL;
+ aPolyBunches[i].m_pNext = nil;
else
aPolyBunches[i].m_pNext = &aPolyBunches[i + 1];
}
@@ -145,29 +158,36 @@ CShadows::Init(void)
{
aPermanentShadows[i].m_nType = SHADOWTYPE_NONE;
}
+
+#ifndef MASTER
+ VarConsole.Add("Count polys in shadow", &gbCountPolysInShadow, true);
+#endif
}
void
CShadows::Shutdown(void)
{
- ASSERT(gpShadowCarTex != NULL);
- ASSERT(gpShadowPedTex != NULL);
- ASSERT(gpShadowHeliTex != NULL);
- ASSERT(gpShadowExplosionTex != NULL);
- ASSERT(gpShadowHeadLightsTex != NULL);
- ASSERT(gpOutline1Tex != NULL);
- ASSERT(gpOutline2Tex != NULL);
- ASSERT(gpOutline3Tex != NULL);
- ASSERT(gpBloodPoolTex != NULL);
- ASSERT(gpReflectionTex != NULL);
- ASSERT(gpGoalMarkerTex != NULL);
- ASSERT(gpWalkDontTex != NULL);
- ASSERT(gpCrackedGlassTex != NULL);
- ASSERT(gpPostShadowTex != NULL);
+ ASSERT(gpShadowCarTex != nil);
+ ASSERT(gpShadowPedTex != nil);
+ ASSERT(gpShadowHeliTex != nil);
+ ASSERT(gpShadowBikeTex != nil);
+ ASSERT(gpShadowBaronTex != nil);
+ ASSERT(gpShadowExplosionTex != nil);
+ ASSERT(gpShadowHeadLightsTex != nil);
+ ASSERT(gpOutline1Tex != nil);
+ ASSERT(gpOutline2Tex != nil);
+ ASSERT(gpOutline3Tex != nil);
+ ASSERT(gpBloodPoolTex != nil);
+ ASSERT(gpReflectionTex != nil);
+ ASSERT(gpWalkDontTex != nil);
+ ASSERT(gpCrackedGlassTex != nil);
+ ASSERT(gpPostShadowTex != nil);
RwTextureDestroy(gpShadowCarTex);
RwTextureDestroy(gpShadowPedTex);
RwTextureDestroy(gpShadowHeliTex);
+ RwTextureDestroy(gpShadowBikeTex);
+ RwTextureDestroy(gpShadowBaronTex);
RwTextureDestroy(gpShadowExplosionTex);
RwTextureDestroy(gpShadowHeadLightsTex);
RwTextureDestroy(gpOutline1Tex);
@@ -175,7 +195,6 @@ CShadows::Shutdown(void)
RwTextureDestroy(gpOutline3Tex);
RwTextureDestroy(gpBloodPoolTex);
RwTextureDestroy(gpReflectionTex);
- RwTextureDestroy(gpGoalMarkerTex);
RwTextureDestroy(gpWalkDontTex);
RwTextureDestroy(gpCrackedGlassTex);
RwTextureDestroy(gpPostShadowTex);
@@ -187,8 +206,8 @@ CShadows::AddPermanentShadow(uint8 ShadowType, RwTexture *pTexture, CVector *pPo
int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue,
float fZDistance, uint32 nTime, float fScale)
{
- ASSERT(pTexture != NULL);
- ASSERT(pPosn != NULL);
+ ASSERT(pTexture != nil);
+ ASSERT(pPosn != nil);
// find free slot
@@ -215,36 +234,39 @@ CShadows::AddPermanentShadow(uint8 ShadowType, RwTexture *pTexture, CVector *pPo
}
}
-void
+bool
CShadows::StoreStaticShadow(uint32 nID, uint8 ShadowType, RwTexture *pTexture, Const CVector *pPosn,
float fFrontX, float fFrontY, float fSideX, float fSideY,
int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue,
float fZDistance, float fScale, float fDrawDistance, bool bTempShadow, float fUpDistance)
{
- ASSERT(pPosn != NULL);
+ ASSERT(pPosn != nil);
float fDistToCamSqr = (*pPosn - TheCamera.GetPosition()).MagnitudeSqr2D();
- if ( SQR(fDrawDistance) > fDistToCamSqr)
+ if ( SQR(fDrawDistance) > fDistToCamSqr || fDrawDistance == 0.0f )
{
- float fDistToCam = Sqrt(fDistToCamSqr);
-
- if ( fDistToCam >= (fDrawDistance*(1.0f-(1.0f/4.0f))) )
+ if ( fDrawDistance != 0.0f )
{
- //fDistToCam == 0 -> 4
- //fDistToCam == fDrawDistance -> 0
- float fMult = 1.0f - (4.0f / fDrawDistance) * (fDistToCam - (fDrawDistance*(1.0f-(1.0f/4.0f))));
+ float fDistToCam = Sqrt(fDistToCamSqr);
- nIntensity = (int32)(nIntensity * fMult);
- nRed = (int32)(nRed * fMult);
- nGreen = (int32)(nGreen * fMult);
- nBlue = (int32)(nBlue * fMult);
+ if ( fDistToCam >= (fDrawDistance*(1.0f-(1.0f/4.0f))) )
+ {
+ //fDistToCam == 0 -> 4
+ //fDistToCam == fDrawDistance -> 0
+ float fMult = 1.0f - (4.0f / fDrawDistance) * (fDistToCam - (fDrawDistance*(1.0f-(1.0f/4.0f))));
+
+ nIntensity = (int32)(nIntensity * fMult);
+ nRed = (int32)(nRed * fMult);
+ nGreen = (int32)(nGreen * fMult);
+ nBlue = (int32)(nBlue * fMult);
+ }
}
int32 nSlot;
nSlot = 0;
- while ( nSlot < MAX_STATICSHADOWS && !(nID == aStaticShadows[nSlot].m_nId && aStaticShadows[nSlot].m_pPolyBunch != NULL) )
+ while ( nSlot < MAX_STATICSHADOWS && !(nID == aStaticShadows[nSlot].m_nId && aStaticShadows[nSlot].m_pPolyBunch != nil) )
nSlot++;
if ( nSlot < MAX_STATICSHADOWS )
@@ -263,8 +285,10 @@ CShadows::StoreStaticShadow(uint32 nID, uint8 ShadowType, RwTexture *pTexture, C
aStaticShadows[nSlot].m_fScale = fScale;
aStaticShadows[nSlot].m_bTemp = bTempShadow;
aStaticShadows[nSlot].m_nTimeCreated = CTimer::GetTimeInMilliseconds();
+
+ return true;
}
- else if ( Abs(pPosn->x - aStaticShadows[nSlot].m_vecPosn.x) < 0.05f
+ else if ( Abs(pPosn->x - aStaticShadows[nSlot].m_vecPosn.x) < 0.05f
&& Abs(pPosn->y - aStaticShadows[nSlot].m_vecPosn.y) < 0.05f
&& Abs(pPosn->z - aStaticShadows[nSlot].m_vecPosn.z) < 2.0f
@@ -284,6 +308,8 @@ CShadows::StoreStaticShadow(uint32 nID, uint8 ShadowType, RwTexture *pTexture, C
aStaticShadows[nSlot].m_fScale = fScale;
aStaticShadows[nSlot].m_bTemp = bTempShadow;
aStaticShadows[nSlot].m_nTimeCreated = CTimer::GetTimeInMilliseconds();
+
+ return true;
}
else
{
@@ -308,12 +334,14 @@ CShadows::StoreStaticShadow(uint32 nID, uint8 ShadowType, RwTexture *pTexture, C
aStaticShadows[nSlot].m_nTimeCreated = CTimer::GetTimeInMilliseconds();
GeneratePolysForStaticShadow(nSlot);
+
+ return aStaticShadows[nSlot].m_pPolyBunch != nil;
}
}
else
{
nSlot = 0;
- while ( nSlot < MAX_STATICSHADOWS && aStaticShadows[nSlot].m_pPolyBunch != NULL )
+ while ( nSlot < MAX_STATICSHADOWS && aStaticShadows[nSlot].m_pPolyBunch != nil )
nSlot++;
if ( nSlot != MAX_STATICSHADOWS )
@@ -337,9 +365,13 @@ CShadows::StoreStaticShadow(uint32 nID, uint8 ShadowType, RwTexture *pTexture, C
aStaticShadows[nSlot].m_nTimeCreated = CTimer::GetTimeInMilliseconds();
GeneratePolysForStaticShadow(nSlot);
+
+ return aStaticShadows[nSlot].m_pPolyBunch != nil;
}
}
}
+
+ return true;
}
void
@@ -347,7 +379,7 @@ CShadows::StoreShadowToBeRendered(uint8 ShadowTexture, CVector *pPosn,
float fFrontX, float fFrontY, float fSideX, float fSideY,
int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue)
{
- ASSERT(pPosn != NULL);
+ ASSERT(pPosn != nil);
switch ( ShadowTexture )
{
@@ -361,7 +393,7 @@ CShadows::StoreShadowToBeRendered(uint8 ShadowTexture, CVector *pPosn,
StoreShadowToBeRendered(SHADOWTYPE_DARK, gpShadowCarTex, pPosn,
fFrontX, fFrontY, fSideX, fSideY,
nIntensity, nRed, nGreen, nBlue,
- 15.0f, false, 1.0f);
+ 15.0f, false, 1.0f, nil, false);
break;
}
@@ -371,7 +403,7 @@ CShadows::StoreShadowToBeRendered(uint8 ShadowTexture, CVector *pPosn,
StoreShadowToBeRendered(SHADOWTYPE_DARK, gpShadowPedTex, pPosn,
fFrontX, fFrontY, fSideX, fSideY,
nIntensity, nRed, nGreen, nBlue,
- 15.0f, false, 1.0f);
+ 15.0f, false, 1.0f, nil, false);
break;
}
@@ -381,7 +413,7 @@ CShadows::StoreShadowToBeRendered(uint8 ShadowTexture, CVector *pPosn,
StoreShadowToBeRendered(SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, pPosn,
fFrontX, fFrontY, fSideX, fSideY,
nIntensity, nRed, nGreen, nBlue,
- 15.0f, false, 1.0f);
+ 15.0f, false, 1.0f, nil, false);
break;
}
@@ -391,7 +423,7 @@ CShadows::StoreShadowToBeRendered(uint8 ShadowTexture, CVector *pPosn,
StoreShadowToBeRendered(SHADOWTYPE_DARK, gpShadowHeliTex, pPosn,
fFrontX, fFrontY, fSideX, fSideY,
nIntensity, nRed, nGreen, nBlue,
- 15.0f, false, 1.0f);
+ 15.0f, false, 1.0f, nil, false);
break;
}
@@ -401,7 +433,7 @@ CShadows::StoreShadowToBeRendered(uint8 ShadowTexture, CVector *pPosn,
StoreShadowToBeRendered(SHADOWTYPE_ADDITIVE, gpShadowHeadLightsTex, pPosn,
fFrontX, fFrontY, fSideX, fSideY,
nIntensity, nRed, nGreen, nBlue,
- 15.0f, false, 1.0f);
+ 15.0f, false, 1.0f, nil, false);
break;
}
@@ -410,8 +442,8 @@ CShadows::StoreShadowToBeRendered(uint8 ShadowTexture, CVector *pPosn,
{
StoreShadowToBeRendered(SHADOWTYPE_DARK, gpBloodPoolTex, pPosn,
fFrontX, fFrontY, fSideX, fSideY,
- nIntensity, nRed, nGreen, nBlue,
- 15.0f, false, 1.0f);
+ nIntensity, nRed, 150, 0,
+ 15.0f, false, 1.0f, nil, false);
break;
}
@@ -424,36 +456,39 @@ void
CShadows::StoreShadowToBeRendered(uint8 ShadowType, RwTexture *pTexture, CVector *pPosn,
float fFrontX, float fFrontY, float fSideX, float fSideY,
int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue,
- float fZDistance, bool bDrawOnWater, float fScale)
+ float fZDistance, bool bDrawOnWater, float fScale, CCutsceneShadow *pShadow, bool bDrawOnBuildings)
{
- ASSERT(pTexture != NULL);
- ASSERT(pPosn != NULL);
+ ASSERT(pTexture != nil);
+ ASSERT(pPosn != nil);
if ( ShadowsStoredToBeRendered < MAX_STOREDSHADOWS )
{
- asShadowsStored[ShadowsStoredToBeRendered].m_ShadowType = ShadowType;
- asShadowsStored[ShadowsStoredToBeRendered].m_pTexture = pTexture;
- asShadowsStored[ShadowsStoredToBeRendered].m_vecPos = *pPosn;
- asShadowsStored[ShadowsStoredToBeRendered].m_vecFront.x = fFrontX;
- asShadowsStored[ShadowsStoredToBeRendered].m_vecFront.y = fFrontY;
- asShadowsStored[ShadowsStoredToBeRendered].m_vecSide.x = fSideX;
- asShadowsStored[ShadowsStoredToBeRendered].m_vecSide.y = fSideY;
- asShadowsStored[ShadowsStoredToBeRendered].m_nIntensity = nIntensity;
- asShadowsStored[ShadowsStoredToBeRendered].m_nRed = nRed;
- asShadowsStored[ShadowsStoredToBeRendered].m_nGreen = nGreen;
- asShadowsStored[ShadowsStoredToBeRendered].m_nBlue = nBlue;
- asShadowsStored[ShadowsStoredToBeRendered].m_fZDistance = fZDistance;
- asShadowsStored[ShadowsStoredToBeRendered].m_nFlags.bDrawOnWater = bDrawOnWater;
- asShadowsStored[ShadowsStoredToBeRendered].m_fScale = fScale;
+ asShadowsStored[ShadowsStoredToBeRendered].m_ShadowType = ShadowType;
+ asShadowsStored[ShadowsStoredToBeRendered].m_pTexture = pTexture;
+ asShadowsStored[ShadowsStoredToBeRendered].m_vecPos = *pPosn;
+ asShadowsStored[ShadowsStoredToBeRendered].m_vecFront.x = fFrontX;
+ asShadowsStored[ShadowsStoredToBeRendered].m_vecFront.y = fFrontY;
+ asShadowsStored[ShadowsStoredToBeRendered].m_vecSide.x = fSideX;
+ asShadowsStored[ShadowsStoredToBeRendered].m_vecSide.y = fSideY;
+ asShadowsStored[ShadowsStoredToBeRendered].m_nIntensity = nIntensity;
+ asShadowsStored[ShadowsStoredToBeRendered].m_nRed = nRed;
+ asShadowsStored[ShadowsStoredToBeRendered].m_nGreen = nGreen;
+ asShadowsStored[ShadowsStoredToBeRendered].m_nBlue = nBlue;
+ asShadowsStored[ShadowsStoredToBeRendered].m_fZDistance = fZDistance;
+ asShadowsStored[ShadowsStoredToBeRendered].m_nFlags.bDrawOnWater = bDrawOnWater;
+ asShadowsStored[ShadowsStoredToBeRendered].m_nFlags.bDrawOnBuildings = bDrawOnBuildings;
+ asShadowsStored[ShadowsStoredToBeRendered].m_fScale = fScale;
+ asShadowsStored[ShadowsStoredToBeRendered].m_pCutsceneShadow = pShadow;
ShadowsStoredToBeRendered++;
}
}
+
void
-CShadows::StoreShadowForCar(CAutomobile *pCar)
+CShadows::StoreShadowForVehicle(CVehicle *pCar, VEH_SHD_TYPE type)
{
- ASSERT(pCar != NULL);
+ ASSERT(pCar != nil);
if ( CTimeCycle::GetShadowStrength() != 0 )
{
@@ -463,7 +498,22 @@ CShadows::StoreShadowForCar(CAutomobile *pCar)
if ( CCutsceneMgr::IsRunning() )
fDistToCamSqr /= SQR(TheCamera.LODDistMultiplier) * 4.0f;
- float fDrawDistance = 18.0f;
+ float fDrawDistance;
+ switch ( type )
+ {
+ case VEH_SHD_TYPE_SEAPLANE:
+ case VEH_SHD_TYPE_RCPLANE:
+ fDrawDistance = 144.0f;
+ break;
+
+ case VEH_SHD_TYPE_HELI:
+ fDrawDistance = 144.0f;
+ break;
+
+ default:
+ fDrawDistance = 18.0f;
+ break;
+ }
if ( fDistToCamSqr < SQR(fDrawDistance) )
{
@@ -471,58 +521,214 @@ CShadows::StoreShadowForCar(CAutomobile *pCar)
//fDistToCam == 0 -> 4
//fDistToCam == fDrawDistance -> 0
- float fMult = 1.0f - (4.0f / fDrawDistance) * (fDistToCam - (fDrawDistance*(1.0f-(1.0f/4.0f))) );
+ float fMult = 1.0f - (fDistToCam - (fDrawDistance*(1.0f-(1.0f/4.0f)))) / (fDrawDistance*(1.0f/4.0f));
int32 nColorStrength;
if ( fDistToCam >= (fDrawDistance*(1.0f-(1.0f/4.0f))) )
- nColorStrength = (int32)(CTimeCycle::GetShadowStrength() * fMult);
+ nColorStrength = (int32)(fMult * CTimeCycle::GetShadowStrength());
else
nColorStrength = CTimeCycle::GetShadowStrength();
-
+
+
float fVehicleHeight = pCar->GetColModel()->boundingBox.GetSize().y;
float fVehicleWidth = pCar->GetColModel()->boundingBox.GetSize().x;
-
- if ( pCar->GetModelIndex() == MI_DODO )
+
+ float size = 1.0f;
+
+ if ( pCar->GetModelIndex() == MI_HUNTER )
+ {
+ fVehicleWidth *= 3.0f;
+ fVehicleHeight *= 1.4f;
+ size *= 0.5f;
+ }
+ else if ( pCar->GetModelIndex() == MI_ANGEL )
+ {
+ fVehicleHeight = fVehicleHeight * 1.5f;
+ size = 0.03f;
+ }
+ else if ( pCar->GetModelIndex() == MI_SEASPAR )
+ {
+ fVehicleWidth *= 3.0f;
+ fVehicleHeight *= 1.4f;
+ size *= 0.5f;
+ }
+ else if ( pCar->GetModelIndex() == MI_PIZZABOY || pCar->GetModelIndex() == MI_PCJ600 || pCar->GetModelIndex() == MI_FAGGIO )
+ {
+ fVehicleHeight *= 1.2f;
+ size = 0.05f;
+ }
+ else if ( pCar->GetModelIndex() == MI_FREEWAY )
+ {
+ fVehicleHeight *= 1.5f;
+ size = 0.03f;
+ }
+ else if ( pCar->GetModelIndex() == MI_RCRAIDER )
+ {
+ fVehicleHeight *= 1.5f;
+ fVehicleWidth *= 2.0f;
+ size = 0.2f;
+ }
+ else if ( pCar->GetModelIndex() == MI_SANCHEZ )
+ {
+ fVehicleHeight *= 1.5f;
+ size = 0.03f;
+ }
+ else if ( pCar->GetModelIndex() == MI_SPARROW || pCar->GetModelIndex() == MI_MAVERICK || pCar->GetModelIndex() == MI_VCNMAV || pCar->GetModelIndex() == MI_POLMAV )
+ {
+ fVehicleWidth *= 3.0f;
+ fVehicleHeight *= 1.4f;
+ size *= 0.5f;
+ }
+ else if ( pCar->GetModelIndex() == MI_RCGOBLIN )
+ {
+ fVehicleHeight *= 1.5f;
+ fVehicleWidth *= 2.0f;
+ size = 0.2f;
+ }
+ else if ( pCar->GetModelIndex() == MI_DODO )
{
fVehicleHeight *= 0.9f;
fVehicleWidth *= 0.4f;
}
+
+ CarPos.x -= pCar->GetForward().x * (((fVehicleHeight/2) - pCar->GetColModel()->boundingBox.max.y)*size);
+ CarPos.y -= pCar->GetForward().y * (((fVehicleHeight/2) - pCar->GetColModel()->boundingBox.max.y)*size);
+
+ RwTexture *tex = gpShadowCarTex;
+ switch ( type )
+ {
+ case VEH_SHD_TYPE_BIKE:
+ {
+ float wheelZ = Abs(((CBike*)pCar)->m_fLeanLRAngle);
+ float mul = 5.092958f * wheelZ + 1.0f;
+ if (pCar->GetStatus() == STATUS_PHYSICS)
+ {
+ float z = pCar->GetRight().z;
+ if (z > 0.6f)
+ mul += 4.0f * z;
+ }
+ fVehicleWidth *= mul;
+ tex = gpShadowBikeTex;
+ break;
+ }
+
+ case VEH_SHD_TYPE_HELI:
+ tex = gpShadowHeliTex;
+ break;
+
+ case VEH_SHD_TYPE_SEAPLANE:
+ nColorStrength = CTimeCycle::GetShadowStrength();
+ tex = gpShadowBaronTex;
+ break;
+
+ case VEH_SHD_TYPE_RCPLANE:
+ tex = gpShadowBaronTex;
+ fVehicleHeight *= 1.5f;
+ fVehicleWidth *= 2.2f;
+ break;
+
+ case VEH_SHD_TYPE_CAR:
+ tex = gpShadowCarTex;
+ break;
+ }
+
+ float frontx = pCar->GetForward().x;
+ float fronty = pCar->GetForward().y;
+ float sidex = pCar->GetRight().x;
+ float sidey = pCar->GetRight().y;
+
+ switch ( type )
+ {
+ case VEH_SHD_TYPE_BIKE:
+ if ( Abs(pCar->GetRight().z) > 0.6f )
+ {
+ sidex = pCar->GetUp().x;
+ sidey = pCar->GetUp().y;
+ }
+ break;
+
+ case VEH_SHD_TYPE_HELI:
+ if ( Abs(pCar->GetRight().z) > 0.57f )
+ {
+ sidex = pCar->GetUp().x;
+ sidey = pCar->GetUp().y;
+ }
+ if ( Abs(pCar->GetForward().z) > 0.57f )
+ {
+ frontx = pCar->GetUp().x;
+ fronty = pCar->GetUp().y;
+ }
+ break;
+ }
- CarPos.x -= pCar->GetForward().x * ((fVehicleHeight / 2) - pCar->GetColModel()->boundingBox.max.y);
- CarPos.y -= pCar->GetForward().y * ((fVehicleHeight / 2) - pCar->GetColModel()->boundingBox.max.y);
-
- if ( pCar->GetUp().z > 0.0f )
+ bool bDrawOnBuildings = false;
+ if ( pCar->GetModelIndex() == MI_RCBANDIT
+ || pCar->GetModelIndex() == MI_RCBARON
+ || pCar->GetModelIndex() == MI_RCRAIDER
+ || pCar->GetModelIndex() == MI_RCGOBLIN
+ || pCar == FindPlayerVehicle() )
{
- StoreShadowToBeRendered(SHADOWTYPE_DARK, gpShadowCarTex, &CarPos,
- pCar->GetForward().x * (fVehicleHeight / 2),
- pCar->GetForward().y * (fVehicleHeight / 2),
- pCar->GetRight().x * (fVehicleWidth / 2),
- pCar->GetRight().y * (fVehicleWidth / 2),
- nColorStrength, nColorStrength, nColorStrength, nColorStrength,
- 4.5f, false, 1.0f);
+ bDrawOnBuildings = true;
+ }
+
+ if ( pCar->m_vecMoveSpeed.Magnitude() * CTimeStep::ms_fTimeStep > 0.1f || bDrawOnBuildings )
+ {
+ if ( pCar->GetUp().z > 0.0f )
+ {
+ StoreShadowToBeRendered(SHADOWTYPE_DARK, tex, &CarPos,
+ frontx * (fVehicleHeight / 2),
+ fronty * (fVehicleHeight / 2),
+ sidex * (fVehicleWidth / 2),
+ sidey * (fVehicleWidth / 2),
+ nColorStrength, nColorStrength, nColorStrength, nColorStrength,
+ 4.5f, false, 1.0f, nil, bDrawOnBuildings);
+ }
+ else
+ {
+ StoreShadowToBeRendered(SHADOWTYPE_DARK, tex, &CarPos,
+ frontx * (fVehicleHeight / 2),
+ fronty * (fVehicleHeight / 2),
+ -sidex * (fVehicleWidth / 2),
+ -sidey * (fVehicleWidth / 2),
+ nColorStrength, nColorStrength, nColorStrength, nColorStrength,
+ 4.5f, false, 1.0f, nil, bDrawOnBuildings);
+ }
}
else
{
- StoreShadowToBeRendered(SHADOWTYPE_DARK, gpShadowCarTex, &CarPos,
- pCar->GetForward().x * (fVehicleHeight / 2),
- pCar->GetForward().y * (fVehicleHeight / 2),
- -pCar->GetRight().x * (fVehicleWidth / 2),
- -pCar->GetRight().y * (fVehicleWidth / 2),
- nColorStrength, nColorStrength, nColorStrength, nColorStrength,
- 4.5f, false, 1.0f);
+ if ( pCar->GetUp().z > 0.0f )
+ {
+ StoreStaticShadow((uintptr)pCar + 1, SHADOWTYPE_DARK, tex, &CarPos,
+ frontx * (fVehicleHeight / 2),
+ fronty * (fVehicleHeight / 2),
+ sidex * (fVehicleWidth / 2),
+ sidey * (fVehicleWidth / 2),
+ nColorStrength, nColorStrength, nColorStrength, nColorStrength,
+ 4.5f, 1.0f, 0.0f, false, 0.1f);
+ }
+ else
+ {
+ StoreStaticShadow((uintptr)pCar + 1, SHADOWTYPE_DARK, tex, &CarPos,
+ frontx * (fVehicleHeight / 2),
+ fronty * (fVehicleHeight / 2),
+ -sidex * (fVehicleWidth / 2),
+ -sidey * (fVehicleWidth / 2),
+ nColorStrength, nColorStrength, nColorStrength, nColorStrength,
+ 4.5f, 1.0f, 0.0f, false, 0.1f);
+ }
}
}
}
}
void
-CShadows::StoreCarLightShadow(CAutomobile *pCar, int32 nID, RwTexture *pTexture, CVector *pPosn,
+CShadows::StoreCarLightShadow(CVehicle *pCar, int32 nID, RwTexture *pTexture, CVector *pPosn,
float fFrontX, float fFrontY, float fSideX, float fSideY, uint8 nRed, uint8 nGreen, uint8 nBlue,
float fMaxViewAngle)
{
- ASSERT(pCar != NULL);
- ASSERT(pPosn != NULL);
+ ASSERT(pCar != nil);
+ ASSERT(pPosn != nil);
float fDistToCamSqr = (*pPosn - TheCamera.GetPosition()).MagnitudeSqr2D();
@@ -550,31 +756,131 @@ CShadows::StoreCarLightShadow(CAutomobile *pCar, int32 nID, RwTexture *pTexture,
nBlue = (int32)(nBlue * fMult);
}
- StoreShadowToBeRendered(SHADOWTYPE_ADDITIVE, pTexture, pPosn,
- fFrontX, fFrontY,
- fSideX, fSideY,
- 128, nRed, nGreen, nBlue,
- 6.0f, false, 1.0f);
+ if ( pCar->m_vecMoveSpeed.Magnitude() * CTimeStep::ms_fTimeStep > 0.4f || pCar == FindPlayerVehicle() )
+ {
+ StoreShadowToBeRendered(SHADOWTYPE_ADDITIVE, pTexture, pPosn,
+ fFrontX, fFrontY,
+ fSideX, fSideY,
+ 128, nRed, nGreen, nBlue,
+ 6.0f, false, 1.0f,
+ nil, pCar == FindPlayerVehicle());
+ }
+ else
+ {
+ StoreStaticShadow((uintptr)pCar + nID, SHADOWTYPE_ADDITIVE, pTexture, pPosn,
+ fFrontX, fFrontY,
+ fSideX, fSideY,
+ 128, nRed, nGreen, nBlue,
+ 6.0f, 1.0f, 27.0f,
+ false, 0.4f);
+ }
+ }
+ }
+}
+
+
+#ifdef USE_CUTSCENE_SHADOW_FOR_PED
+void
+StoreShadowForCutscenePedObject(CPed *pObject, float fDisplacementX, float fDisplacementY,
+ float fFrontX, float fFrontY, float fSideX, float fSideY)
+{
+ ASSERT(pObject != nil);
+
+ CCutsceneShadow *shadow = pObject->m_pRTShadow;
+
+ if ( shadow == nil )
+ return;
+
+ if ( !shadow->IsInitialized() )
+ return;
+
+ CVector pos = pObject->GetPosition();
+
+ float fDistToCamSqr = (pos - TheCamera.GetPosition()).MagnitudeSqr2D();
+
+ float fDrawDistance = 100.0f;
+
+ if ( fDistToCamSqr < SQR(fDrawDistance*0.5f) )
+ {
+ if ( (CEntity*)pObject == FindPlayerPed() || TheCamera.IsSphereVisible(pos, 2.0f) )
+ {
+ float fDistToCam = Sqrt(fDistToCamSqr);
+
+ float fMult = 1.0f - (4.0f / fDrawDistance) * (fDistToCam - (fDrawDistance*(1.0f/4.0f)));
+ int32 nColorStrength;
+ if ( fDistToCam >= (fDrawDistance*(1.0f/4.0f)) )
+ nColorStrength = (int32)(CTimeCycle::GetShadowStrength() * fMult);
+ else
+ nColorStrength = CTimeCycle::GetShadowStrength();
+
+ int32 color = int32(nColorStrength * 0.8f);
+
+ pos.x += fDisplacementX;
+ pos.y += fDisplacementY;
+
+ RwTexture *texture = shadow->GetShadowRwTexture();
+ ASSERT(texture);
+ RwRGBA bordercolor = {0, 0, 0, 0};
+ shadow->DrawBorderAroundTexture(bordercolor);
+
+ pos.x -= fDisplacementX;
+ pos.y -= fDisplacementY;
+
+ float angleY = 360.0f - RADTODEG((CClock::ms_nGameClockMinutes
+ +60*CClock::ms_nGameClockHours+CClock::ms_nGameClockSeconds/60)*(HALFPI/360.0f));
+
+ RwFrame *frame = shadow->SetLightProperties(angleY, -85.0f, true);
+ ASSERT(frame);
+ CVector at(RwFrameGetMatrix(frame)->at);
+ at.Normalise();
+
+ CShadows::CalcPedShadowValues(at, &fFrontX, &fFrontY, &fSideX, &fSideY, &fDisplacementX, &fDisplacementY);
+
+ pos.x -= 2.5f * fDisplacementX;
+ pos.y -= 2.5f * fDisplacementY;
+
+ CShadows::StoreShadowToBeRendered(SHADOWTYPE_INVCOLOR, texture, &pos,
+ fFrontX * 1.5f, fFrontY * 1.5f,
+ fSideX * 1.5f, fSideY * 1.5f,
+ color, color, color, color,
+ 4.0f, false, 1.0f, shadow, false);
}
}
}
+#endif
+
void
CShadows::StoreShadowForPed(CPed *pPed, float fDisplacementX, float fDisplacementY,
float fFrontX, float fFrontY, float fSideX, float fSideY)
{
- ASSERT(pPed != NULL);
+ ASSERT(pPed != nil);
if ( pPed->bIsVisible )
{
if ( !(pPed->bInVehicle && pPed->m_nPedState != PED_DRAG_FROM_CAR && pPed->m_nPedState != PED_EXIT_CAR) )
{
if ( CTimeCycle::GetShadowStrength() != 0 )
+ {
+#ifdef USE_CUTSCENE_SHADOW_FOR_PED
+ CCutsceneShadow *pShadow = pPed->m_pRTShadow;
+
+ if (pShadow)
+ {
+ if (pShadow->IsInitialized())
+ pShadow->UpdateForCutscene();
+ ::StoreShadowForCutscenePedObject(pPed, fDisplacementX, fDisplacementY, fFrontX, fFrontY, fSideX, fSideY);
+ }
+
+ return;
+#endif
+
StoreShadowForPedObject(pPed,
fDisplacementX, fDisplacementY,
fFrontX, fFrontY,
fSideX, fSideY);
+ }
}
}
}
@@ -582,8 +888,8 @@ CShadows::StoreShadowForPed(CPed *pPed, float fDisplacementX, float fDisplacemen
void
CShadows::StoreShadowForPedObject(CEntity *pPedObject, float fDisplacementX, float fDisplacementY,
float fFrontX, float fFrontY, float fSideX, float fSideY)
-{
- ASSERT(pPedObject != NULL);
+{
+ ASSERT(pPedObject != nil);
CVector PedPos = pPedObject->GetPosition();
@@ -591,7 +897,7 @@ CShadows::StoreShadowForPedObject(CEntity *pPedObject, float fDisplacementX, flo
float fDrawDistance = 26.0f;
- if ( fDistToCamSqr < SQR(fDrawDistance*0.5f)/*?*/ )
+ if ( fDistToCamSqr < SQR(fDrawDistance*0.5f) )
{
if ( pPedObject == FindPlayerPed() || TheCamera.IsSphereVisible(PedPos, 2.0f) != false )
{
@@ -614,7 +920,80 @@ CShadows::StoreShadowForPedObject(CEntity *pPedObject, float fDisplacementX, flo
fFrontX, fFrontY,
fSideX, fSideY,
nColorStrength, nColorStrength, nColorStrength, nColorStrength,
- 4.0f, false, 1.0f);
+ 4.0f, false, 1.0f, nil, pPedObject == FindPlayerPed());
+ }
+ }
+}
+
+
+void
+CShadows::StoreShadowForCutscenePedObject(CCutsceneObject *pObject, float fDisplacementX, float fDisplacementY,
+ float fFrontX, float fFrontY, float fSideX, float fSideY)
+{
+#ifdef DISABLE_CUTSCENE_SHADOWS
+ return;
+#endif
+ ASSERT(pObject != nil);
+
+ CCutsceneShadow *shadow = pObject->m_pShadow;
+
+ if ( shadow == nil )
+ return;
+
+ if ( !shadow->IsInitialized() )
+ return;
+
+ CVector pos = pObject->GetPosition();
+
+ float fDistToCamSqr = (pos - TheCamera.GetPosition()).MagnitudeSqr2D();
+
+ float fDrawDistance = 100.0f;
+
+ if ( fDistToCamSqr < SQR(fDrawDistance*0.5f) )
+ {
+ if ( (CEntity*)pObject == FindPlayerPed() || TheCamera.IsSphereVisible(pos, 2.0f) )
+ {
+ float fDistToCam = Sqrt(fDistToCamSqr);
+
+ float fMult = 1.0f - (4.0f / fDrawDistance) * (fDistToCam - (fDrawDistance*(1.0f/4.0f)));
+ int32 nColorStrength;
+
+ if ( fDistToCam >= (fDrawDistance*(1.0f/4.0f)) )
+ nColorStrength = (int32)(CTimeCycle::GetShadowStrength() * fMult);
+ else
+ nColorStrength = CTimeCycle::GetShadowStrength();
+
+ int32 color = int32(nColorStrength * 0.8f);
+
+ pos.x += fDisplacementX;
+ pos.y += fDisplacementY;
+
+ RwTexture *texture = shadow->GetShadowRwTexture();
+ ASSERT(texture);
+ RwRGBA bordercolor = {0, 0, 0, 0};
+ shadow->DrawBorderAroundTexture(bordercolor);
+
+ pos.x -= fDisplacementX;
+ pos.y -= fDisplacementY;
+
+ float angleY = 360.0f - RADTODEG((CClock::ms_nGameClockMinutes+60*
+ CClock::ms_nGameClockHours+CClock::ms_nGameClockSeconds/60)*(HALFPI/360.0f));
+
+ RwFrame *frame = shadow->SetLightProperties(angleY, -85.0f, true);
+ ASSERT(frame);
+ CVector at(RwFrameGetMatrix(frame)->at);
+ at.Normalise();
+
+ CalcPedShadowValues(at, &fFrontX, &fFrontY, &fSideX, &fSideY, &fDisplacementX, &fDisplacementY);
+
+ pos.x -= 2.5f * fDisplacementX;
+ pos.y -= 2.5f * fDisplacementY;
+
+ StoreShadowToBeRendered(SHADOWTYPE_INVCOLOR, texture, &pos,
+ fFrontX * 1.5f, fFrontY * 1.5f,
+ fSideX * 1.5f, fSideY * 1.5f,
+ color, color, color, color,
+ 4.0f, false, 1.0f, shadow, false);
}
}
}
@@ -622,14 +1001,15 @@ CShadows::StoreShadowForPedObject(CEntity *pPedObject, float fDisplacementX, flo
void
CShadows::StoreShadowForTree(CEntity *pTree)
{
- ASSERT(pTree != NULL);
+ ASSERT(pTree != nil);
}
+
void
CShadows::StoreShadowForPole(CEntity *pPole, float fOffsetX, float fOffsetY, float fOffsetZ,
float fPoleHeight, float fPoleWidth, uint32 nID)
{
- ASSERT(pPole != NULL);
+ ASSERT(pPole != nil);
if ( CTimeCycle::GetShadowStrength() != 0 )
{
@@ -684,6 +1064,7 @@ CShadows::SetRenderModeForShadowType(uint8 ShadowType)
}
}
+
void
CShadows::RenderStoredShadows(void)
{
@@ -694,17 +1075,20 @@ CShadows::RenderStoredShadows(void)
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void *)FALSE);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)TRUE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)TRUE);
+ RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void *)rwTEXTUREADDRESSCLAMP);
+
for ( int32 i = 0; i < ShadowsStoredToBeRendered; i++ )
asShadowsStored[i].m_nFlags.bRendered = false;
+
for ( int32 i = 0; i < ShadowsStoredToBeRendered; i++ )
{
if ( !asShadowsStored[i].m_nFlags.bRendered )
{
SetRenderModeForShadowType(asShadowsStored[i].m_ShadowType);
- ASSERT(asShadowsStored[i].m_pTexture != NULL);
+ ASSERT(asShadowsStored[i].m_pTexture != nil);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(asShadowsStored[i].m_pTexture));
@@ -736,39 +1120,112 @@ CShadows::RenderStoredShadows(void)
{
CSector *pCurSector = CWorld::GetSector(x, y);
- ASSERT(pCurSector != NULL);
-
- CastShadowSectorList(pCurSector->m_lists[ENTITYLIST_BUILDINGS],
- fStartX, fStartY,
- fEndX, fEndY,
- &shadowPos,
- asShadowsStored[j].m_vecFront.x,
- asShadowsStored[j].m_vecFront.y,
- asShadowsStored[j].m_vecSide.x,
- asShadowsStored[j].m_vecSide.y,
- asShadowsStored[j].m_nIntensity,
- asShadowsStored[j].m_nRed,
- asShadowsStored[j].m_nGreen,
- asShadowsStored[j].m_nBlue,
- asShadowsStored[j].m_fZDistance,
- asShadowsStored[j].m_fScale,
- NULL);
-
- CastShadowSectorList(pCurSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP],
- fStartX, fStartY,
- fEndX, fEndY,
- &shadowPos,
- asShadowsStored[j].m_vecFront.x,
- asShadowsStored[j].m_vecFront.y,
- asShadowsStored[j].m_vecSide.x,
- asShadowsStored[j].m_vecSide.y,
- asShadowsStored[j].m_nIntensity,
- asShadowsStored[j].m_nRed,
- asShadowsStored[j].m_nGreen,
- asShadowsStored[j].m_nBlue,
- asShadowsStored[j].m_fZDistance,
- asShadowsStored[j].m_fScale,
- NULL);
+ ASSERT(pCurSector != nil);
+
+ if ( asShadowsStored[j].m_pCutsceneShadow )
+ {
+ CastCutsceneShadowSectorList(pCurSector->m_lists[ENTITYLIST_BUILDINGS],
+ fStartX, fStartY,
+ fEndX, fEndY,
+ &shadowPos,
+ asShadowsStored[j].m_vecFront.x,
+ asShadowsStored[j].m_vecFront.y,
+ asShadowsStored[j].m_vecSide.x,
+ asShadowsStored[j].m_vecSide.y,
+ asShadowsStored[j].m_nIntensity,
+ asShadowsStored[j].m_nRed,
+ asShadowsStored[j].m_nGreen,
+ asShadowsStored[j].m_nBlue,
+ asShadowsStored[j].m_fZDistance,
+ asShadowsStored[j].m_fScale,
+ nil,
+ asShadowsStored[j].m_pCutsceneShadow);
+
+ CastCutsceneShadowSectorList(pCurSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP],
+ fStartX, fStartY,
+ fEndX, fEndY,
+ &shadowPos,
+ asShadowsStored[j].m_vecFront.x,
+ asShadowsStored[j].m_vecFront.y,
+ asShadowsStored[j].m_vecSide.x,
+ asShadowsStored[j].m_vecSide.y,
+ asShadowsStored[j].m_nIntensity,
+ asShadowsStored[j].m_nRed,
+ asShadowsStored[j].m_nGreen,
+ asShadowsStored[j].m_nBlue,
+ asShadowsStored[j].m_fZDistance,
+ asShadowsStored[j].m_fScale,
+ nil,
+ asShadowsStored[j].m_pCutsceneShadow);
+ }
+ else if ( asShadowsStored[j].m_nFlags.bDrawOnBuildings )
+ {
+ CastPlayerShadowSectorList(pCurSector->m_lists[ENTITYLIST_BUILDINGS],
+ fStartX, fStartY,
+ fEndX, fEndY,
+ &shadowPos,
+ asShadowsStored[j].m_vecFront.x,
+ asShadowsStored[j].m_vecFront.y,
+ asShadowsStored[j].m_vecSide.x,
+ asShadowsStored[j].m_vecSide.y,
+ asShadowsStored[j].m_nIntensity,
+ asShadowsStored[j].m_nRed,
+ asShadowsStored[j].m_nGreen,
+ asShadowsStored[j].m_nBlue,
+ asShadowsStored[j].m_fZDistance,
+ asShadowsStored[j].m_fScale,
+ nil);
+
+ CastPlayerShadowSectorList(pCurSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP],
+ fStartX, fStartY,
+ fEndX, fEndY,
+ &shadowPos,
+ asShadowsStored[j].m_vecFront.x,
+ asShadowsStored[j].m_vecFront.y,
+ asShadowsStored[j].m_vecSide.x,
+ asShadowsStored[j].m_vecSide.y,
+ asShadowsStored[j].m_nIntensity,
+ asShadowsStored[j].m_nRed,
+ asShadowsStored[j].m_nGreen,
+ asShadowsStored[j].m_nBlue,
+ asShadowsStored[j].m_fZDistance,
+ asShadowsStored[j].m_fScale,
+ nil);
+ }
+ else
+ {
+ CastShadowSectorList(pCurSector->m_lists[ENTITYLIST_BUILDINGS],
+ fStartX, fStartY,
+ fEndX, fEndY,
+ &shadowPos,
+ asShadowsStored[j].m_vecFront.x,
+ asShadowsStored[j].m_vecFront.y,
+ asShadowsStored[j].m_vecSide.x,
+ asShadowsStored[j].m_vecSide.y,
+ asShadowsStored[j].m_nIntensity,
+ asShadowsStored[j].m_nRed,
+ asShadowsStored[j].m_nGreen,
+ asShadowsStored[j].m_nBlue,
+ asShadowsStored[j].m_fZDistance,
+ asShadowsStored[j].m_fScale,
+ nil);
+
+ CastShadowSectorList(pCurSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP],
+ fStartX, fStartY,
+ fEndX, fEndY,
+ &shadowPos,
+ asShadowsStored[j].m_vecFront.x,
+ asShadowsStored[j].m_vecFront.y,
+ asShadowsStored[j].m_vecSide.x,
+ asShadowsStored[j].m_vecSide.y,
+ asShadowsStored[j].m_nIntensity,
+ asShadowsStored[j].m_nRed,
+ asShadowsStored[j].m_nGreen,
+ asShadowsStored[j].m_nBlue,
+ asShadowsStored[j].m_fZDistance,
+ asShadowsStored[j].m_fScale,
+ nil);
+ }
}
}
@@ -778,18 +1235,19 @@ CShadows::RenderStoredShadows(void)
RenderBuffer::RenderStuffInBuffer();
}
-
}
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)FALSE);
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void *)TRUE);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)TRUE);
+ RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void *)rwTEXTUREADDRESSWRAP);
ShadowsStoredToBeRendered = 0;
POP_RENDERGROUP();
}
+
void
CShadows::RenderStaticShadows(void)
{
@@ -817,19 +1275,19 @@ CShadows::RenderStaticShadows(void)
// optimization trick, render all shadows with same renderstate and texture
for ( int32 j = i; j < MAX_STATICSHADOWS; j++ )
{
- if ( aStaticShadows[j].m_pPolyBunch != NULL
+ if ( aStaticShadows[j].m_pPolyBunch != nil
&& aStaticShadows[i].m_nType == aStaticShadows[j].m_nType
&& aStaticShadows[i].m_pTexture == aStaticShadows[j].m_pTexture )
{
- for ( CPolyBunch *bunch = aStaticShadows[j].m_pPolyBunch; bunch != NULL; bunch = bunch->m_pNext )
+ for ( CPolyBunch *bunch = aStaticShadows[j].m_pPolyBunch; bunch != nil; bunch = bunch->m_pNext )
{
RwImVertexIndex *pIndexes;
RwIm3DVertex *pVerts;
RenderBuffer::StartStoring(3 * (bunch->m_nNumVerts - 2), bunch->m_nNumVerts, &pIndexes, &pVerts);
- ASSERT(pIndexes != NULL);
- ASSERT(pVerts != NULL);
+ ASSERT(pIndexes != nil);
+ ASSERT(pVerts != nil);
for ( int32 k = 0; k < bunch->m_nNumVerts; k++ )
{
@@ -865,6 +1323,7 @@ CShadows::RenderStaticShadows(void)
POP_RENDERGROUP();
}
+
void
CShadows::GeneratePolysForStaticShadow(int16 nStaticShadowID)
{
@@ -891,7 +1350,7 @@ CShadows::GeneratePolysForStaticShadow(int16 nStaticShadowID)
{
CSector *pCurSector = CWorld::GetSector(x, y);
- ASSERT(pCurSector != NULL);
+ ASSERT(pCurSector != nil);
CastShadowSectorList(pCurSector->m_lists[ENTITYLIST_BUILDINGS],
fStartX, fStartY,
@@ -922,50 +1381,109 @@ CShadows::GeneratePolysForStaticShadow(int16 nStaticShadowID)
}
}
+
void
CShadows::CastShadowSectorList(CPtrList &PtrList, float fStartX, float fStartY, float fEndX, float fEndY, CVector *pPosn,
float fFrontX, float fFrontY, float fSideX, float fSideY,
int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue,
float fZDistance, float fScale, CPolyBunch **ppPolyBunch)
{
- ASSERT(pPosn != NULL);
+ ASSERT(pPosn != nil);
CPtrNode *pNode = PtrList.first;
CRect Bound;
- while ( pNode != NULL )
+ while ( pNode != nil )
{
CEntity *pEntity = (CEntity *)pNode->item;
uint16 nScanCode = pEntity->m_scanCode;
pNode = pNode->next;
- ASSERT( pEntity != NULL );
+ ASSERT( pEntity != nil );
if ( nScanCode != CWorld::GetCurrentScanCode() )
{
- if ( pEntity->bUsesCollision && pEntity->IsBuilding() )
+ pEntity->m_scanCode = CWorld::GetCurrentScanCode();
+
+ if ( pEntity->bUsesCollision && !pEntity->bDontCastShadowsOn)
{
- pEntity->m_scanCode = CWorld::GetCurrentScanCode();
+ if ( IsAreaVisible(pEntity->m_area) )
+ {
+ Bound = pEntity->GetBoundRect();
+
+ if ( fStartX < Bound.right
+ && fEndX > Bound.left
+ && fStartY < Bound.bottom
+ && fEndY > Bound.top )
+ {
+ if ( pPosn->z - fZDistance < pEntity->GetPosition().z + pEntity->GetColModel()->boundingBox.max.z
+ && pEntity->GetPosition().z + pEntity->GetColModel()->boundingBox.min.z < pPosn->z )
+ {
+ CastShadowEntityXY(pEntity,
+ fStartX, fStartY,
+ fEndX, fEndY,
+ pPosn,
+ fFrontX, fFrontY,
+ fSideX, fSideY,
+ nIntensity, nRed, nGreen, nBlue,
+ fZDistance, fScale, ppPolyBunch);
+ }
+ }
+ }
+ }
+ }
+ }
+}
- Bound = pEntity->GetBoundRect();
- if ( fStartX < Bound.right
- && fEndX > Bound.left
- && fStartY < Bound.bottom
- && fEndY > Bound.top )
+void
+CShadows::CastPlayerShadowSectorList(CPtrList &PtrList, float fStartX, float fStartY, float fEndX, float fEndY, CVector *pPosn,
+ float fFrontX, float fFrontY, float fSideX, float fSideY,
+ int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue,
+ float fZDistance, float fScale, CPolyBunch **ppPolyBunch)
+{
+ ASSERT(pPosn != nil);
+
+ CPtrNode *pNode = PtrList.first;
+
+ CRect Bound;
+
+ while ( pNode != nil )
+ {
+ CEntity *pEntity = (CEntity *)pNode->item;
+ uint16 nScanCode = pEntity->m_scanCode;
+ pNode = pNode->next;
+
+ ASSERT( pEntity != nil );
+
+ if ( nScanCode != CWorld::GetCurrentScanCode() )
+ {
+ pEntity->m_scanCode = CWorld::GetCurrentScanCode();
+
+ if ( pEntity->bUsesCollision )
+ {
+ if ( IsAreaVisible(pEntity->m_area) )
{
- if ( pPosn->z - fZDistance < pEntity->GetPosition().z + pEntity->GetColModel()->boundingBox.max.z
- && pEntity->GetPosition().z + pEntity->GetColModel()->boundingBox.min.z < pPosn->z )
+ Bound = pEntity->GetBoundRect();
+
+ if ( fStartX < Bound.right
+ && fEndX > Bound.left
+ && fStartY < Bound.bottom
+ && fEndY > Bound.top )
{
- CastShadowEntity(pEntity,
- fStartX, fStartY,
- fEndX, fEndY,
- pPosn,
- fFrontX, fFrontY,
- fSideX, fSideY,
- nIntensity, nRed, nGreen, nBlue,
- fZDistance, fScale, ppPolyBunch);
+ if ( pPosn->z - fZDistance < pEntity->GetPosition().z + pEntity->GetColModel()->boundingBox.max.z
+ && pEntity->GetPosition().z + pEntity->GetColModel()->boundingBox.min.z < pPosn->z )
+ {
+ CastShadowEntityXY(pEntity,
+ fStartX, fStartY,
+ fEndX, fEndY,
+ pPosn,
+ fFrontX, fFrontY,
+ fSideX, fSideY,
+ nIntensity, nRed, nGreen, nBlue,
+ fZDistance, fScale, ppPolyBunch);
+ }
}
}
}
@@ -973,21 +1491,74 @@ CShadows::CastShadowSectorList(CPtrList &PtrList, float fStartX, float fStartY,
}
}
+
void
-CShadows::CastShadowEntity(CEntity *pEntity, float fStartX, float fStartY, float fEndX, float fEndY, CVector *pPosn,
+CShadows::CastCutsceneShadowSectorList(CPtrList &PtrList, float fStartX, float fStartY, float fEndX, float fEndY, CVector *pPosn,
+ float fFrontX, float fFrontY, float fSideX, float fSideY,
+ int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue,
+ float fZDistance, float fScale, CPolyBunch **ppPolyBunch, CCutsceneShadow *pShadow)
+{
+ ASSERT(pPosn != nil);
+ ASSERT(pShadow != nil);
+
+ CPtrNode *pNode = PtrList.first;
+
+ CRect Bound;
+
+ while ( pNode != nil )
+ {
+ CEntity *pEntity = (CEntity *)pNode->item;
+ uint16 nScanCode = pEntity->m_scanCode;
+ pNode = pNode->next;
+
+ ASSERT( pEntity != nil );
+
+ if ( nScanCode != CWorld::GetCurrentScanCode() )
+ {
+ pEntity->m_scanCode = CWorld::GetCurrentScanCode();
+
+ if ( pEntity->bUsesCollision )
+ {
+ if ( IsAreaVisible(pEntity->m_area) )
+ {
+ Bound = pEntity->GetBoundRect();
+
+ if ( fStartX < Bound.right
+ && fEndX > Bound.left
+ && fStartY < Bound.bottom
+ && fEndY > Bound.top )
+ {
+ if ( pPosn->z - fZDistance < pEntity->GetPosition().z + pEntity->GetColModel()->boundingBox.max.z
+ && pEntity->GetPosition().z + pEntity->GetColModel()->boundingBox.min.z < pPosn->z )
+ {
+ CastShadowEntityXYZ(pEntity, pPosn,
+ fFrontX, fFrontY,
+ fSideX, fSideY,
+ nIntensity, nRed, nGreen, nBlue,
+ fZDistance, fScale, ppPolyBunch, pShadow);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void
+CShadows::CastShadowEntityXY(CEntity *pEntity, float fStartX, float fStartY, float fEndX, float fEndY, CVector *pPosn,
float fFrontX, float fFrontY, float fSideX, float fSideY,
int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue,
float fZDistance, float fScale, CPolyBunch **ppPolyBunch)
-{
- ASSERT(pEntity != NULL);
- ASSERT(pPosn != NULL);
+{
+ ASSERT(pEntity != nil);
+ ASSERT(pPosn != nil);
static CVector List [20];
static CVector Texture[20];
static CVector Points [4];
CColModel *pCol = pEntity->GetColModel();
- ASSERT(pCol != NULL);
+ ASSERT(pCol != nil);
#ifndef MASTER
if ( gbPrintShite )
@@ -1033,14 +1604,14 @@ CShadows::CastShadowEntity(CEntity *pEntity, float fStartX, float fStartY, floa
for ( int32 i = 0; i < pCol->numTriangles; i++ )
{
CColTrianglePlane *pColTriPlanes = pCol->trianglePlanes;
- ASSERT(pColTriPlanes != NULL);
+ ASSERT(pColTriPlanes != nil);
CVector normal;
pColTriPlanes[i].GetNormal(normal);
if ( Abs(normal.z) > 0.1f )
{
CColTriangle *pColTri = pCol->triangles;
- ASSERT(pColTri != NULL);
+ ASSERT(pColTri != nil);
CVector PointA, PointB, PointC;
@@ -1440,12 +2011,12 @@ CShadows::CastShadowEntity(CEntity *pEntity, float fStartX, float fStartY, floa
}
- if ( ppPolyBunch != NULL )
+ if ( ppPolyBunch != nil )
{
- if ( pEmptyBunchList != NULL )
+ if ( pEmptyBunchList != nil )
{
CPolyBunch *pBunch = pEmptyBunchList;
- ASSERT(pBunch != NULL);
+ ASSERT(pBunch != nil);
pEmptyBunchList = pEmptyBunchList->m_pNext;
pBunch->m_pNext = *ppPolyBunch;
*ppPolyBunch = pBunch;
@@ -1470,8 +2041,8 @@ CShadows::CastShadowEntity(CEntity *pEntity, float fStartX, float fStartY, floa
RenderBuffer::StartStoring(3 * (numVerts3 - 2), numVerts3, &pIndexes, &pVerts);
- ASSERT(pIndexes != NULL);
- ASSERT(pVerts != NULL);
+ ASSERT(pIndexes != nil);
+ ASSERT(pVerts != nil);
for ( int32 j = 0; j < numVerts3; j++ )
@@ -1495,12 +2066,222 @@ CShadows::CastShadowEntity(CEntity *pEntity, float fStartX, float fStartY, floa
}
}
+
+typedef struct _ProjectionParam
+{
+ RwV3d at; /* Camera at vector */
+ RwMatrix invMatrix; /* Transforms to shadow camera space */
+ RwUInt8 shadowValue; /* Shadow opacity value */
+ RwBool fade; /* Shadow fades with distance */
+ RwUInt32 numIm3DBatch; /* Number of buffer flushes */
+ RwMatrix entityMatrix;
+}
+ProjectionParam;
+
+RwV3d *ShadowRenderTriangleCB(RwV3d *points, RwV3d *normal, ProjectionParam *param)
+{
+ RwV3d vIn[3];
+ RwV3d vShad[3];
+
+ RwV3dTransformPoints(&vIn[0], points, 3, &param->entityMatrix);
+
+ /*
+ * Reject backfacing triangles
+ * This reject the triangles parallel to the light as well
+ */
+ if (RwV3dDotProduct(normal, &param->at) > 0.0f)
+ {
+ return points;
+ }
+
+ RwV3dTransformPoints(&vShad[0], &vIn[0], 3, &param->invMatrix);
+
+ /*
+ * Reject triangles behind the camera (z test). Note that any world
+ * triangles lying in front of the camera but before the object may
+ * have a shadow applied. To minimize such artefacts, this test could
+ * be modified to use a specific value rather than 0.0f, perhaps
+ * to reject triangles behind the center plane of the object.
+ *
+ * Reject triangles that lie entirely outside the shadow texture range
+ * (x,y test).
+ */
+ if (((vShad[0].z < 0.0f) && (vShad[1].z < 0.0f)
+ && (vShad[2].z < 0.0f)) || ((vShad[0].x < 0.0f)
+ && (vShad[1].x < 0.0f)
+ && (vShad[2].x < 0.0f))
+ || ((vShad[0].x > 1.0f) && (vShad[1].x > 1.0f)
+ && (vShad[2].x > 1.0f)) || ((vShad[0].y < 0.0f)
+ && (vShad[1].y < 0.0f)
+ && (vShad[2].y < 0.0f))
+ || ((vShad[0].y > 1.0f) && (vShad[1].y > 1.0f)
+ && (vShad[2].y > 1.0f)))
+ {
+ return points;
+ }
+
+ RwIm3DVertex *imv = nil;
+ RwImVertexIndex *imi = nil;
+
+ RenderBuffer::StartStoring(3, 3, &imi, &imv);
+
+ /*
+ * Set the immediate mode vertices for this triangle
+ */
+
+ RwIm3DVertexSetPos(imv, vIn[0].x, vIn[0].y, vIn[0].z);
+ RwIm3DVertexSetPos(imv + 1, vIn[1].x, vIn[1].y, vIn[1].z);
+ RwIm3DVertexSetPos(imv + 2, vIn[2].x, vIn[2].y, vIn[2].z);
+
+ RwIm3DVertexSetU(imv, vShad[0].x);
+ RwIm3DVertexSetU(imv + 1, vShad[1].x);
+ RwIm3DVertexSetU(imv + 2, vShad[2].x);
+
+ RwIm3DVertexSetV(imv, vShad[0].y);
+ RwIm3DVertexSetV(imv + 1, vShad[1].y);
+ RwIm3DVertexSetV(imv + 2, vShad[2].y);
+
+ /*
+ * Do we fade out the shadow with distance?
+ */
+ if (param->fade)
+ {
+ RwReal fadeVal;
+ RwUInt8 val;
+
+ fadeVal = 1.0f - vShad[0].z * vShad[0].z;
+ val =
+ (fadeVal <
+ 0.0f) ? 0 : (RwUInt8) (fadeVal * param->shadowValue);
+ RwIm3DVertexSetRGBA(imv, val, val, val, val);
+
+ fadeVal = 1.0f - vShad[1].z * vShad[1].z;
+ val =
+ (fadeVal <
+ 0.0f) ? 0 : (RwUInt8) (fadeVal * param->shadowValue);
+ RwIm3DVertexSetRGBA(imv + 1, val, val, val, val);
+
+ fadeVal = 1.0f - vShad[2].z * vShad[2].z;
+ val =
+ (fadeVal <
+ 0.0f) ? 0 : (RwUInt8) (fadeVal * param->shadowValue);
+ RwIm3DVertexSetRGBA(imv + 2, val, val, val, val);
+ }
+ else
+ {
+ RwUInt8 val = param->shadowValue;
+
+ RwIm3DVertexSetRGBA(imv, val, val, val, val);
+ RwIm3DVertexSetRGBA(imv + 1, val, val, val, val);
+ RwIm3DVertexSetRGBA(imv + 2, val, val, val, val);
+ }
+
+ /*
+ * Update buffer position
+ */
+ imi[0] = 0;
+ imi[1] = 1;
+ imi[2] = 2;
+
+ RenderBuffer::StopStoring();
+
+ return points;
+}
+
+void
+CShadows::CastShadowEntityXYZ(CEntity *pEntity, CVector *pPosn,
+ float fFrontX, float fFrontY, float fSideX, float fSideY,
+ int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue,
+ float fZDistance, float fScale, CPolyBunch **ppPolyBunch, CCutsceneShadow *pShadow)
+{
+ ASSERT(pEntity != nil);
+ ASSERT(pPosn != nil);
+
+ if ( pShadow )
+ {
+ ProjectionParam proj;
+ RwV3d scl;
+ RwV3d tr;
+
+ CShadowCamera *shadow = pShadow->GetShadowCamera();
+ CColModel *collision = pEntity->GetColModel();
+
+ CCollision::CalculateTrianglePlanes(collision);
+
+ RwMatrix mat;
+ mat = *RwFrameGetMatrix(RwCameraGetFrame(shadow->GetRwCamera()));
+
+ RwV3d Xaxis = { 1.0f, 0.0f, 0.0f };
+
+ RwMatrixRotate(&mat, &Xaxis, -45.0f, rwCOMBINEPRECONCAT);
+
+ proj.at = mat.at;
+ pEntity->GetMatrix().CopyToRwMatrix(&proj.entityMatrix);
+
+ RwMatrixInvert(&proj.invMatrix, &mat);
+ RwReal radius = RwCameraGetViewWindow(shadow->GetRwCamera())->x;
+
+ scl.x = scl.y = -0.5f / (radius*0.9f);
+ scl.z = 1.0f / (radius*0.8f);
+ RwMatrixScale(&proj.invMatrix, &scl, rwCOMBINEPOSTCONCAT);
+
+ tr.x = 0.5f;
+ tr.y = tr.z = 0.0f;
+ RwMatrixTranslate(&proj.invMatrix, &tr, rwCOMBINEPOSTCONCAT);
+
+ proj.shadowValue = nIntensity;
+ proj.fade = 0;
+
+ RwMatrix matrix;
+ pEntity->GetMatrix().CopyToRwMatrix(&matrix);
+ RwMatrix invMatrix;
+ RwMatrixInvert(&invMatrix, &matrix);
+
+
+ CVector center(pShadow->GetBaseSphere().center);
+ center += CVector(-fFrontX * 1.1f, -fFrontY * 1.1f, -0.5f);
+
+ CSphere sphere;
+ sphere.Set(2.0f, center);
+
+ RwV3d point;
+ RwV3dTransformPoints(&point, &center, 1, &invMatrix);
+
+ CColSphere colSphere;
+ colSphere.Set(2.0f, CVector(point), 0, 0);
+
+ int i = 0;
+ while ( i < collision->numTriangles )
+ {
+ CVector p[3];
+
+ collision->GetTrianglePoint(p[0], collision->triangles[i].a);
+ collision->GetTrianglePoint(p[1], collision->triangles[i].b);
+ collision->GetTrianglePoint(p[2], collision->triangles[i].c);
+
+ if ( CCollision::TestSphereTriangle(colSphere, collision->vertices, collision->triangles[i], collision->trianglePlanes[i]) )
+ {
+ CVector n(collision->trianglePlanes[i].GetNormalX(), collision->trianglePlanes[i].GetNormalY(), collision->trianglePlanes[i].GetNormalZ());
+ CVector offset = n * 0.028f;
+
+ p[0] += offset;
+ p[1] += offset;
+ p[2] += offset;
+
+ if ( !ShadowRenderTriangleCB(p, &n, &proj) )
+ break;
+ }
+ i++;
+ }
+ }
+}
+
void
CShadows::UpdateStaticShadows(void)
{
for ( int32 i = 0; i < MAX_STATICSHADOWS; i++ )
{
- if ( aStaticShadows[i].m_pPolyBunch != NULL && !aStaticShadows[i].m_bJustCreated
+ if ( aStaticShadows[i].m_pPolyBunch != nil && !aStaticShadows[i].m_bJustCreated
&& (!aStaticShadows[i].m_bTemp || CTimer::GetTimeInMilliseconds() > aStaticShadows[i].m_nTimeCreated + 5000) )
{
aStaticShadows[i].Free();
@@ -1523,13 +2304,14 @@ CShadows::UpdatePermanentShadows(void)
aPermanentShadows[i].m_nType = SHADOWTYPE_NONE;
else
{
+ bool bOk;
if ( timePassed >= (aPermanentShadows[i].m_nLifeTime * 3 / 4) )
{
// timePassed == 0 -> 4
// timePassed == aPermanentShadows[i].m_nLifeTime -> 0
float fMult = 1.0f - float(timePassed - (aPermanentShadows[i].m_nLifeTime * 3 / 4)) / (aPermanentShadows[i].m_nLifeTime / 4);
- StoreStaticShadow((uintptr)&aPermanentShadows[i],
+ bOk = StoreStaticShadow((uintptr)&aPermanentShadows[i],
aPermanentShadows[i].m_nType,
aPermanentShadows[i].m_pTexture,
&aPermanentShadows[i].m_vecPos,
@@ -1546,7 +2328,7 @@ CShadows::UpdatePermanentShadows(void)
}
else
{
- StoreStaticShadow((uintptr)&aPermanentShadows[i],
+ bOk = StoreStaticShadow((uintptr)&aPermanentShadows[i],
aPermanentShadows[i].m_nType,
aPermanentShadows[i].m_pTexture,
&aPermanentShadows[i].m_vecPos,
@@ -1561,6 +2343,9 @@ CShadows::UpdatePermanentShadows(void)
aPermanentShadows[i].m_fZDistance,
1.0f, 40.0f, false, 0.0f);
}
+
+ if ( !bOk )
+ aPermanentShadows[i].m_nType = SHADOWTYPE_NONE;
}
}
}
@@ -1569,19 +2354,19 @@ CShadows::UpdatePermanentShadows(void)
void
CStaticShadow::Free(void)
{
- if ( m_pPolyBunch != NULL )
+ if ( m_pPolyBunch != nil )
{
CPolyBunch *pFree = CShadows::pEmptyBunchList;
CShadows::pEmptyBunchList = m_pPolyBunch;
CPolyBunch *pUsed = m_pPolyBunch;
- while (pUsed->m_pNext != NULL)
+ while (pUsed->m_pNext != nil)
pUsed = pUsed->m_pNext;
pUsed->m_pNext = pFree;
}
- m_pPolyBunch = NULL;
+ m_pPolyBunch = nil;
m_nId = 0;
}
@@ -1625,6 +2410,7 @@ CShadows::CalcPedShadowValues(CVector vecLightDir,
}
+
void
CShadows::RenderExtraPlayerShadows(void)
{
@@ -1635,64 +2421,13 @@ CShadows::RenderExtraPlayerShadows(void)
if ( CTimeCycle::GetLightShadowStrength() != 0 )
{
CVehicle *pCar = FindPlayerVehicle();
-
- if ( pCar == NULL )
- {
- for ( int32 i = 0; i < CPointLights::NumLights; i++ )
- {
- if ( 0.0f != CPointLights::aLights[i].red
- || 0.0f != CPointLights::aLights[i].green
- || 0.0f != CPointLights::aLights[i].blue )
- {
- if ( CPointLights::aLights[i].castExtraShadows )
- {
- CVector vecLight = CPointLights::aLights[i].coors - FindPlayerCoors();
- float fLightDist = vecLight.Magnitude();
- float fRadius = CPointLights::aLights[i].radius;
-
- if ( fLightDist < fRadius )
- {
- // fLightDist == fRadius -> 2.0f
- // fLightDist == 0 -> 0.0f
- float fMult = (1.0f - (2.0f * fLightDist - fRadius) / fRadius);
-
- int32 nColorStrength;
- if ( fLightDist < fRadius*0.5f )
- nColorStrength = (5*CTimeCycle::GetLightShadowStrength()/8);
- else
- nColorStrength = int32((5*CTimeCycle::GetLightShadowStrength()/8) * fMult);
-
- float fInv = 1.0f / fLightDist;
- vecLight.x *= fInv;
- vecLight.y *= fInv;
- vecLight.z *= fInv;
-
- float fFrontX, fFrontY, fSideX, fSideY, fDisplacementX, fDisplacementY;
-
- CalcPedShadowValues(vecLight,
- &fFrontX, &fFrontY,
- &fSideX, &fSideY,
- &fDisplacementX, &fDisplacementY);
-
- CVector shadowPos = FindPlayerCoors();
-
- shadowPos.x += fDisplacementX;
- shadowPos.y += fDisplacementY;
-
-
- StoreShadowToBeRendered(SHADOWTYPE_DARK, gpShadowPedTex, &shadowPos,
- fFrontX, fFrontY,
- fSideX, fSideY,
- nColorStrength, 0, 0, 0,
- 4.0f, false, 1.0f);
- }
- }
- }
- }
- }
+ if ( pCar == nil )
+ ; // R* cut it out for playerped
else
{
- if ( pCar->GetModelIndex() != MI_RCBANDIT )
+ if ( pCar->GetModelIndex() != MI_RCBANDIT
+ && pCar->GetVehicleAppearance() != VEHICLE_APPEARANCE_BIKE
+ && !pCar->IsBike() && !pCar->IsPlane() && !pCar->IsBoat() )
{
for ( int32 i = 0; i < CPointLights::NumLights; i++ )
{
@@ -1745,7 +2480,7 @@ CShadows::RenderExtraPlayerShadows(void)
pCar->GetRight().x * (fVehicleWidth/3),
pCar->GetRight().y * (fVehicleWidth/3),
nColorStrength, 0, 0, 0,
- 4.5f, false, 1.0f);
+ 4.5f, false, 1.0f, nil, false);
}
else
{
@@ -1755,7 +2490,7 @@ CShadows::RenderExtraPlayerShadows(void)
-pCar->GetRight().x * (fVehicleWidth/2),
-pCar->GetRight().y * (fVehicleWidth/2),
nColorStrength, 0, 0, 0,
- 4.5f, false, 1.0f);
+ 4.5f, false, 1.0f, nil, false);
}
}
}
@@ -1777,9 +2512,9 @@ CShadows::RenderIndicatorShadow(uint32 nID, uint8 ShadowType, RwTexture *pTextur
float fFrontX, float fFrontY, float fSideX, float fSideY,
int16 nIntensity)
{
- ASSERT(pPosn != NULL);
+ ASSERT(pPosn != nil);
C3dMarkers::PlaceMarkerSet(nID, MARKERTYPE_CYLINDER, *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/renderer/Shadows.h b/src/renderer/Shadows.h
index 8c909df3..937ff4eb 100644
--- a/src/renderer/Shadows.h
+++ b/src/renderer/Shadows.h
@@ -1,12 +1,19 @@
#pragma once
#define MAX_STOREDSHADOWS 48
-#define MAX_POLYBUNCHES 300
-#define MAX_STATICSHADOWS 64
+#define MAX_POLYBUNCHES 380
+#define MAX_STATICSHADOWS 48
#define MAX_PERMAMENTSHADOWS 48
+
class CEntity;
+class CPtrList;
+class CAutomobile;
+class CVehicle;
+class CPed;
+class CCutsceneShadow;
+class CCutsceneObject;
enum eShadowType
{
@@ -27,6 +34,16 @@ enum eShadowTextureType
SHADOWTEX_BLOOD
};
+enum VEH_SHD_TYPE
+{
+ VEH_SHD_TYPE_CAR = 0,
+ VEH_SHD_TYPE_BIKE,
+ VEH_SHD_TYPE_HELI,
+ VEH_SHD_TYPE_SEAPLANE,
+ VEH_SHD_TYPE_RCPLANE,
+};
+
+
class CStoredShadow
{
public:
@@ -35,6 +52,8 @@ public:
CVector2D m_vecSide;
float m_fZDistance;
float m_fScale;
+ RwTexture *m_pTexture;
+ CCutsceneShadow *m_pCutsceneShadow;
int16 m_nIntensity;
uint8 m_ShadowType;
uint8 m_nRed;
@@ -44,9 +63,9 @@ public:
{
uint8 bDrawOnWater : 1;
uint8 bRendered : 1;
- //uint8 bDrawOnBuildings : 1;
+ uint8 bDrawOnBuildings : 1;
} m_nFlags;
- RwTexture *m_pTexture;
+
CStoredShadow()
{ }
@@ -57,11 +76,11 @@ VALIDATE_SIZE(CStoredShadow, 0x30);
class CPolyBunch
{
public:
- int16 m_nNumVerts;
CVector m_aVerts[7];
+ CPolyBunch *m_pNext;
+ int16 m_nNumVerts;
uint8 m_aU[7];
uint8 m_aV[7];
- CPolyBunch *m_pNext;
CPolyBunch()
{ }
@@ -80,15 +99,16 @@ public:
CVector2D m_vecSide;
float m_fZDistance;
float m_fScale;
- uint8 m_nType;
+ RwTexture *m_pTexture;
int16 m_nIntensity; // unsigned ?
+ uint8 m_nType;
uint8 m_nRed;
uint8 m_nGreen;
uint8 m_nBlue;
bool m_bJustCreated;
bool m_bRendered;
bool m_bTemp;
- RwTexture *m_pTexture;
+
CStaticShadow()
{ }
@@ -106,14 +126,14 @@ public:
CVector2D m_vecSide;
float m_fZDistance;
float m_fScale;
+ uint32 m_nTimeCreated;
+ uint32 m_nLifeTime;
+ RwTexture *m_pTexture;
int16 m_nIntensity;
uint8 m_nType; // eShadowType
uint8 m_nRed;
uint8 m_nGreen;
uint8 m_nBlue;
- uint32 m_nTimeCreated;
- uint32 m_nLifeTime;
- RwTexture *m_pTexture;
CPermanentShadow()
{ }
@@ -121,10 +141,6 @@ public:
VALIDATE_SIZE(CPermanentShadow, 0x38);
-class CPtrList;
-class CAutomobile;
-class CPed;
-
class CShadows
{
public:
@@ -135,37 +151,52 @@ public:
static CPolyBunch *pEmptyBunchList;
static CPermanentShadow aPermanentShadows[MAX_PERMAMENTSHADOWS];
- static void Init (void);
- static void Shutdown (void);
- static void AddPermanentShadow ( uint8 ShadowType, RwTexture *pTexture, CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, float fZDistance, uint32 nTime, float fScale);
- static void StoreStaticShadow (uint32 nID, uint8 ShadowType, RwTexture *pTexture, Const CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, float fZDistance, float fScale, float fDrawDistance, bool bTempShadow, float fUpDistance);
- static void StoreShadowToBeRendered ( uint8 ShadowType, CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue);
- static void StoreShadowToBeRendered ( uint8 ShadowType, RwTexture *pTexture, CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, float fZDistance, bool bDrawOnWater, float fScale);
- static void StoreShadowForCar (CAutomobile *pCar);
- static void StoreCarLightShadow (CAutomobile *pCar, int32 nID, RwTexture *pTexture, CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, uint8 nRed, uint8 nGreen, uint8 nBlue, float fMaxViewAngle);
- static void StoreShadowForPed (CPed *pPed, float fDisplacementX, float fDisplacementY, float fFrontX, float fFrontY, float fSideX, float fSideY);
- static void StoreShadowForPedObject (CEntity *pPedObject, float fDisplacementX, float fDisplacementY, float fFrontX, float fFrontY, float fSideX, float fSideY);
- static void StoreShadowForTree (CEntity *pTree);
- static void StoreShadowForPole (CEntity *pPole, float fOffsetX, float fOffsetY, float fOffsetZ, float fPoleHeight, float fPoleWidth, uint32 nID);
- static void SetRenderModeForShadowType (uint8 ShadowType);
- static void RenderStoredShadows (void);
- static void RenderStaticShadows (void);
- static void GeneratePolysForStaticShadow (int16 nStaticShadowID);
- static void CastShadowSectorList (CPtrList &PtrList, float fStartX, float fStartY, float fEndX, float fEndY,
+ static void Init (void);
+ static void Shutdown (void);
+ static void AddPermanentShadow ( uint8 ShadowType, RwTexture *pTexture, CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, float fZDistance, uint32 nTime, float fScale);
+
+ static bool StoreStaticShadow (uint32 nID, uint8 ShadowType, RwTexture *pTexture, Const CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, float fZDistance, float fScale, float fDrawDistance, bool bTempShadow, float fUpDistance);
+ static void StoreShadowToBeRendered ( uint8 ShadowType, CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue);
+ static void StoreShadowToBeRendered ( uint8 ShadowType, RwTexture *pTexture, CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, float fZDistance, bool bDrawOnWater, float fScale, CCutsceneShadow *pShadow, bool bDrawOnBuildings);
+ static void StoreShadowForVehicle (CVehicle *pCar, VEH_SHD_TYPE type);
+ static void StoreCarLightShadow (CVehicle *pCar, int32 nID, RwTexture *pTexture, CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, uint8 nRed, uint8 nGreen, uint8 nBlue, float fMaxViewAngle);
+ static void StoreShadowForPed (CPed *pPed, float fDisplacementX, float fDisplacementY, float fFrontX, float fFrontY, float fSideX, float fSideY);
+ static void StoreShadowForPedObject (CEntity *pPedObject, float fDisplacementX, float fDisplacementY, float fFrontX, float fFrontY, float fSideX, float fSideY);
+ static void StoreShadowForCutscenePedObject(CCutsceneObject *pObject, float fDisplacementX, float fDisplacementY, float fFrontX, float fFrontY, float fSideX, float fSideY);
+ static void StoreShadowForTree (CEntity *pTree);
+ static void StoreShadowForPole (CEntity *pPole, float fOffsetX, float fOffsetY, float fOffsetZ, float fPoleHeight, float fPoleWidth, uint32 nID);
+ static void SetRenderModeForShadowType (uint8 ShadowType);
+ static void RenderStoredShadows (void);
+ static void RenderStaticShadows (void);
+
+ static void GeneratePolysForStaticShadow (int16 nStaticShadowID);
+ static void CastShadowSectorList (CPtrList &PtrList, float fStartX, float fStartY, float fEndX, float fEndY,
CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, float fZDistance, float fScale, CPolyBunch **ppPolyBunch);
- static void CastShadowEntity (CEntity *pEntity, float fStartX, float fStartY, float fEndX, float fEndY,
+
+ static void CastPlayerShadowSectorList (CPtrList &PtrList, float fStartX, float fStartY, float fEndX, float fEndY,
+ CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, float fZDistance, float fScale, CPolyBunch **ppPolyBunch);
+
+ static void CastCutsceneShadowSectorList (CPtrList &PtrList, float fStartX, float fStartY, float fEndX, float fEndY,
+ CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, float fZDistance, float fScale, CPolyBunch **ppPolyBunch, CCutsceneShadow *pShadow);
+
+ static void CastShadowEntityXY (CEntity *pEntity, float fStartX, float fStartY, float fEndX, float fEndY,
CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, float fZDistance, float fScale, CPolyBunch **ppPolyBunch);
- static void UpdateStaticShadows (void);
- static void UpdatePermanentShadows (void);
+
+ static void CastShadowEntityXYZ (CEntity *pEntity, CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, float fZDistance, float fScale, CPolyBunch **ppPolyBunch, CCutsceneShadow *pShadow);
+
+ static void UpdateStaticShadows (void);
+ static void UpdatePermanentShadows (void);
static void CalcPedShadowValues (CVector vecLightDir, float *pfFrontX, float *pfFrontY, float *pfSideX, float *pfSideY, float *pfDisplacementX, float *pfDisplacementY);
- static void RenderExtraPlayerShadows (void);
- static void TidyUpShadows (void);
- static void RenderIndicatorShadow (uint32 nID, uint8 ShadowType, RwTexture *pTexture, CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity);
+ static void RenderExtraPlayerShadows (void);
+ static void TidyUpShadows (void);
+ static void RenderIndicatorShadow (uint32 nID, uint8 ShadowType, RwTexture *pTexture, CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity);
};
extern RwTexture *gpShadowCarTex;
extern RwTexture *gpShadowPedTex;
extern RwTexture *gpShadowHeliTex;
+extern RwTexture *gpShadowBikeTex;
+extern RwTexture *gpShadowBaronTex;
extern RwTexture *gpShadowExplosionTex;
extern RwTexture *gpShadowHeadLightsTex;
extern RwTexture *gpOutline1Tex;
@@ -173,7 +204,6 @@ extern RwTexture *gpOutline2Tex;
extern RwTexture *gpOutline3Tex;
extern RwTexture *gpBloodPoolTex;
extern RwTexture *gpReflectionTex;
-extern RwTexture *gpGoalMarkerTex;
extern RwTexture *gpWalkDontTex;
extern RwTexture *gpCrackedGlassTex;
extern RwTexture *gpPostShadowTex;
diff --git a/src/renderer/Skidmarks.cpp b/src/renderer/Skidmarks.cpp
index 4c662a79..08df330d 100644
--- a/src/renderer/Skidmarks.cpp
+++ b/src/renderer/Skidmarks.cpp
@@ -11,8 +11,6 @@ CSkidmark CSkidmarks::aSkidmarks[NUMSKIDMARKS];
RwImVertexIndex SkidmarkIndexList[SKIDMARK_LENGTH * 6];
RwIm3DVertex SkidmarkVertices[SKIDMARK_LENGTH * 2];
RwTexture *gpSkidTex;
-RwTexture *gpSkidBloodTex;
-RwTexture *gpSkidMudTex;
void
CSkidmarks::Init(void)
@@ -22,8 +20,6 @@ CSkidmarks::Init(void)
slot = CTxdStore::FindTxdSlot("particle");
CTxdStore::SetCurrentTxd(slot);
gpSkidTex = RwTextureRead("particleskid", nil);
- gpSkidBloodTex = RwTextureRead("particleskidblood", nil);
- gpSkidMudTex = RwTextureRead("particleskidmud", nil);
CTxdStore::PopCurrentTxd();
for(i = 0; i < NUMSKIDMARKS; i++){
@@ -41,30 +37,13 @@ CSkidmarks::Init(void)
SkidmarkIndexList[i*6+5] = ix+3;
ix += 2;
}
-
- for(i = 0; i < SKIDMARK_LENGTH; i++){
- RwIm3DVertexSetU(&SkidmarkVertices[i*2 + 0], 0.0f);
- RwIm3DVertexSetV(&SkidmarkVertices[i*2 + 0], i*5.01f);
- RwIm3DVertexSetU(&SkidmarkVertices[i*2 + 1], 1.0f);
- RwIm3DVertexSetV(&SkidmarkVertices[i*2 + 1], i*5.01f);
- }
}
void
CSkidmarks::Shutdown(void)
{
RwTextureDestroy(gpSkidTex);
-#if GTA_VERSION >= GTA3_PC_11
gpSkidTex = nil;
-#endif
- RwTextureDestroy(gpSkidBloodTex);
-#if GTA_VERSION >= GTA3_PC_11
- gpSkidBloodTex = nil;
-#endif
- RwTextureDestroy(gpSkidMudTex);
-#if GTA_VERSION >= GTA3_PC_11
- gpSkidMudTex = nil;
-#endif
}
void
@@ -116,7 +95,6 @@ void
CSkidmarks::Render(void)
{
int i, j;
- RwTexture *lastTex = nil;
PUSH_RENDERGROUP("CSkidmarks::Render");
@@ -124,26 +102,18 @@ CSkidmarks::Render(void)
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpSkidTex));
for(i = 0; i < NUMSKIDMARKS; i++){
if(aSkidmarks[i].m_state == 0 || aSkidmarks[i].m_last < 1)
continue;
- if(aSkidmarks[i].m_isBloody){
- if(lastTex != gpSkidBloodTex){
- RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpSkidBloodTex));
- lastTex = gpSkidBloodTex;
- }
- }else if(aSkidmarks[i].m_isMuddy){
- if(lastTex != gpSkidMudTex){
- RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpSkidMudTex));
- lastTex = gpSkidMudTex;
- }
- }else{
- if(lastTex != gpSkidTex){
- RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpSkidTex));
- lastTex = gpSkidTex;
- }
+ CRGBA color(0, 0, 0, 255);
+ switch(aSkidmarks[i].m_type){
+ case SKIDMARK_NORMAL: color = CRGBA(0, 0, 0, 255); break;
+ case SKIDMARK_MUDDY: color = CRGBA(90, 62, 9, 255); break;
+ case SKIDMARK_SANDY: color = CRGBA(108, 108, 96, 255); break;
+ case SKIDMARK_BLOODY: color = CRGBA(132, 34, 11, 255); break;
}
uint32 fade, alpha;
@@ -158,12 +128,20 @@ CSkidmarks::Render(void)
alpha = 0;
alpha = alpha*fade/256;
- CVector p1 = aSkidmarks[i].m_pos[j] + aSkidmarks[i].m_side[j];
- CVector p2 = aSkidmarks[i].m_pos[j] - aSkidmarks[i].m_side[j];
- RwIm3DVertexSetRGBA(&SkidmarkVertices[j*2+0], 255, 255, 255, alpha);
+ CVector p1 = aSkidmarks[i].m_pos[j];
+ p1.x += aSkidmarks[i].m_sideX[j];
+ p1.y += aSkidmarks[i].m_sideY[j];
+ CVector p2 = aSkidmarks[i].m_pos[j];
+ p2.x -= aSkidmarks[i].m_sideX[j];
+ p2.y -= aSkidmarks[i].m_sideY[j];
+ RwIm3DVertexSetRGBA(&SkidmarkVertices[j*2+0], color.red, color.green, color.blue, alpha);
RwIm3DVertexSetPos(&SkidmarkVertices[j*2+0], p1.x, p1.y, p1.z+0.1f);
- RwIm3DVertexSetRGBA(&SkidmarkVertices[j*2+1], 255, 255, 255, alpha);
+ RwIm3DVertexSetU(&SkidmarkVertices[j*2+0], 0.0f);
+ RwIm3DVertexSetV(&SkidmarkVertices[j*2+0], j*5.01f);
+ RwIm3DVertexSetRGBA(&SkidmarkVertices[j*2+1], color.red, color.green, color.blue, alpha);
RwIm3DVertexSetPos(&SkidmarkVertices[j*2+1], p2.x, p2.y, p2.z+0.1f);
+ RwIm3DVertexSetU(&SkidmarkVertices[j*2+1], 1.0f);
+ RwIm3DVertexSetV(&SkidmarkVertices[j*2+1], j*5.01f);
}
LittleTest();
@@ -181,7 +159,20 @@ CSkidmarks::Render(void)
}
void
-CSkidmarks::RegisterOne(uintptr id, CVector pos, float fwdX, float fwdY, bool *isMuddy, bool *isBloody)
+CSkidmarks::RegisterOne(uintptr id, const CVector &pos, float fwdX, float fwdY, bool *isMuddy, bool *isBloody)
+{
+ eSkidmarkType type;
+ if(*isBloody)
+ type = SKIDMARK_BLOODY;
+ else if(*isMuddy)
+ type = SKIDMARK_MUDDY;
+ else
+ type = SKIDMARK_NORMAL;
+ RegisterOne(id, pos, fwdX, fwdY, type, isBloody);
+}
+
+void
+CSkidmarks::RegisterOne(uintptr id, const CVector &pos, float fwdX, float fwdY, eSkidmarkType type, bool *isBloody)
{
int i;
CVector2D fwd(fwdX, fwdY);
@@ -197,7 +188,7 @@ CSkidmarks::RegisterOne(uintptr id, CVector pos, float fwdX, float fwdY, bool *i
if(i < NUMSKIDMARKS){
// Continue this one
- if(aSkidmarks[i].m_isBloody != *isBloody){
+ if((aSkidmarks[i].m_type==SKIDMARK_BLOODY) != *isBloody){
// Blood-status changed, end this one
aSkidmarks[i].m_state = 2;
aSkidmarks[i].m_fadeStart = CTimer::GetTimeInMilliseconds() + 10000;
@@ -229,13 +220,16 @@ CSkidmarks::RegisterOne(uintptr id, CVector pos, float fwdX, float fwdY, bool *i
CVector2D right(aSkidmarks[i].m_pos[aSkidmarks[i].m_last].y - aSkidmarks[i].m_pos[aSkidmarks[i].m_last - 1].y,
aSkidmarks[i].m_pos[aSkidmarks[i].m_last - 1].x - aSkidmarks[i].m_pos[aSkidmarks[i].m_last].x);
- right.NormaliseSafe();
- fwd.NormaliseSafe();
+ right.Normalise();
+ fwd.Normalise();
float turn = DotProduct2D(fwd, right);
turn = Abs(turn) + 1.0f;
- aSkidmarks[i].m_side[aSkidmarks[i].m_last] = CVector(right.x, right.y, 0.0f) * turn * 0.125f;
- if(aSkidmarks[i].m_last == 1)
- aSkidmarks[i].m_side[0] = aSkidmarks[i].m_side[1];
+ aSkidmarks[i].m_sideX[aSkidmarks[i].m_last] = right.x * turn * 0.125f;
+ aSkidmarks[i].m_sideY[aSkidmarks[i].m_last] = right.y * turn * 0.125f;
+ if(aSkidmarks[i].m_last == 1){
+ aSkidmarks[i].m_sideX[0] = aSkidmarks[i].m_sideX[1];
+ aSkidmarks[i].m_sideY[0] = aSkidmarks[i].m_sideY[1];
+ }
if(aSkidmarks[i].m_last > 8)
*isBloody = false; // stop blood marks after 8
@@ -251,12 +245,15 @@ CSkidmarks::RegisterOne(uintptr id, CVector pos, float fwdX, float fwdY, bool *i
aSkidmarks[i].m_state = 1;
aSkidmarks[i].m_id = id;
aSkidmarks[i].m_pos[0] = pos;
- aSkidmarks[i].m_side[0] = CVector(0.0f, 0.0f, 0.0f);
+ aSkidmarks[i].m_sideX[0] = 0.0f;
+ aSkidmarks[i].m_sideY[0] = 0.0f;
aSkidmarks[i].m_wasUpdated = true;
aSkidmarks[i].m_last = 0;
aSkidmarks[i].m_lastUpdate = CTimer::GetTimeInMilliseconds() - 1000;
- aSkidmarks[i].m_isBloody = *isBloody;
- aSkidmarks[i].m_isMuddy = *isMuddy;
+ if(*isBloody)
+ aSkidmarks[i].m_type = SKIDMARK_BLOODY;
+ else
+ aSkidmarks[i].m_type = type;
}else
*isBloody = false; // stop blood marks if no space
}
diff --git a/src/renderer/Skidmarks.h b/src/renderer/Skidmarks.h
index c061782d..28082f08 100644
--- a/src/renderer/Skidmarks.h
+++ b/src/renderer/Skidmarks.h
@@ -2,20 +2,28 @@
enum { SKIDMARK_LENGTH = 16 };
+enum eSkidmarkType
+{
+ SKIDMARK_NORMAL,
+ SKIDMARK_MUDDY,
+ SKIDMARK_SANDY,
+ SKIDMARK_BLOODY
+};
+
class CSkidmark
{
public:
- uint8 m_state;
- bool m_wasUpdated;
- bool m_isBloody;
- bool m_isMuddy;
+ CVector m_pos[SKIDMARK_LENGTH];
+ float m_sideX[SKIDMARK_LENGTH];
+ float m_sideY[SKIDMARK_LENGTH];
uintptr m_id;
- int16 m_last;
uint32 m_lastUpdate;
uint32 m_fadeStart;
uint32 m_fadeEnd;
- CVector m_pos[SKIDMARK_LENGTH];
- CVector m_side[SKIDMARK_LENGTH];
+ uint32 m_type;
+ int16 m_last;
+ uint8 m_state;
+ bool m_wasUpdated;
};
class CSkidmarks
@@ -28,5 +36,6 @@ public:
static void Clear(void);
static void Update(void);
static void Render(void);
- static void RegisterOne(uintptr id, CVector pos, float fwdX, float fwdY, bool *isMuddy, bool *isBloody);
+ static void RegisterOne(uintptr id, const CVector &pos, float fwdX, float fwdY, eSkidmarkType type, bool *isBloody);
+ static void RegisterOne(uintptr id, const CVector &pos, float fwdX, float fwdY, bool *isMuddy, bool *isBloody);
};
diff --git a/src/renderer/SpecialFX.cpp b/src/renderer/SpecialFX.cpp
index 6d96d21a..61750f85 100644
--- a/src/renderer/SpecialFX.cpp
+++ b/src/renderer/SpecialFX.cpp
@@ -21,12 +21,24 @@
#include "Camera.h"
#include "Shadows.h"
#include "main.h"
+#include "ColStore.h"
+#include "Coronas.h"
+#include "Script.h"
+#include "DMAudio.h"
RwIm3DVertex StreakVertices[4];
RwImVertexIndex StreakIndexList[12];
-RwIm3DVertex TraceVertices[6];
-RwImVertexIndex TraceIndexList[12];
+RwIm3DVertex TraceVertices[10];
+static RwImVertexIndex TraceIndexList[48] = {0, 5, 7, 0, 7, 2, 0, 7, 5, 0, 2, 7, 0, 4, 9, 0,
+ 9, 5, 0, 9, 4, 0, 5, 9, 0, 1, 6, 0, 6, 5, 0, 6,
+ 1, 0, 5, 6, 0, 3, 8, 0, 8, 5, 0, 8, 3, 0, 5, 8 };
+
+bool CSpecialFX::bVideoCam;
+bool CSpecialFX::bLiftCam;
+bool CSpecialFX::bSnapShotActive;
+int32 CSpecialFX::SnapShotFrames;
+static RwTexture* gpSmokeTrailTexture;
void
@@ -34,6 +46,22 @@ CSpecialFX::Init(void)
{
CBulletTraces::Init();
+ RwIm3DVertexSetU(&TraceVertices[0], 0.0);
+ RwIm3DVertexSetV(&TraceVertices[0], 0.0);
+ RwIm3DVertexSetU(&TraceVertices[1], 1.0);
+ RwIm3DVertexSetV(&TraceVertices[1], 0.0);
+ RwIm3DVertexSetU(&TraceVertices[2], 1.0);
+ RwIm3DVertexSetV(&TraceVertices[2], 0.0);
+ RwIm3DVertexSetU(&TraceVertices[3], 1.0);
+ RwIm3DVertexSetV(&TraceVertices[3], 0.0);
+ RwIm3DVertexSetU(&TraceVertices[4], 1.0);
+ RwIm3DVertexSetV(&TraceVertices[4], 0.0);
+ RwIm3DVertexSetU(&TraceVertices[5], 0.0);
+ RwIm3DVertexSetU(&TraceVertices[6], 1.0);
+ RwIm3DVertexSetU(&TraceVertices[7], 1.0);
+ RwIm3DVertexSetU(&TraceVertices[8], 1.0);
+ RwIm3DVertexSetU(&TraceVertices[9], 1.0);
+
RwIm3DVertexSetU(&StreakVertices[0], 0.0f);
RwIm3DVertexSetV(&StreakVertices[0], 0.0f);
RwIm3DVertexSetU(&StreakVertices[1], 1.0f);
@@ -42,7 +70,6 @@ CSpecialFX::Init(void)
RwIm3DVertexSetV(&StreakVertices[2], 0.0f);
RwIm3DVertexSetU(&StreakVertices[3], 1.0f);
RwIm3DVertexSetV(&StreakVertices[3], 0.0f);
-
StreakIndexList[0] = 0;
StreakIndexList[1] = 1;
StreakIndexList[2] = 2;
@@ -56,43 +83,51 @@ CSpecialFX::Init(void)
StreakIndexList[10] = 2;
StreakIndexList[11] = 3;
- RwIm3DVertexSetRGBA(&TraceVertices[0], 20, 20, 20, 255);
- RwIm3DVertexSetRGBA(&TraceVertices[1], 20, 20, 20, 255);
- RwIm3DVertexSetRGBA(&TraceVertices[2], 70, 70, 70, 255);
- RwIm3DVertexSetRGBA(&TraceVertices[3], 70, 70, 70, 255);
- RwIm3DVertexSetRGBA(&TraceVertices[4], 10, 10, 10, 255);
- RwIm3DVertexSetRGBA(&TraceVertices[5], 10, 10, 10, 255);
- RwIm3DVertexSetU(&TraceVertices[0], 0.0);
- RwIm3DVertexSetV(&TraceVertices[0], 0.0);
- RwIm3DVertexSetU(&TraceVertices[1], 1.0);
- RwIm3DVertexSetV(&TraceVertices[1], 0.0);
- RwIm3DVertexSetU(&TraceVertices[2], 0.0);
- RwIm3DVertexSetV(&TraceVertices[2], 0.5);
- RwIm3DVertexSetU(&TraceVertices[3], 1.0);
- RwIm3DVertexSetV(&TraceVertices[3], 0.5);
- RwIm3DVertexSetU(&TraceVertices[4], 0.0);
- RwIm3DVertexSetV(&TraceVertices[4], 1.0);
- RwIm3DVertexSetU(&TraceVertices[5], 1.0);
- RwIm3DVertexSetV(&TraceVertices[5], 1.0);
-
- TraceIndexList[0] = 0;
- TraceIndexList[1] = 2;
- TraceIndexList[2] = 1;
- TraceIndexList[3] = 1;
- TraceIndexList[4] = 2;
- TraceIndexList[5] = 3;
- TraceIndexList[6] = 2;
- TraceIndexList[7] = 4;
- TraceIndexList[8] = 3;
- TraceIndexList[9] = 3;
- TraceIndexList[10] = 4;
- TraceIndexList[11] = 5;
-
CMotionBlurStreaks::Init();
CBrightLights::Init();
CShinyTexts::Init();
CMoneyMessages::Init();
C3dMarkers::Init();
+ CSpecialFX::bSnapShotActive = false;
+ CSpecialFX::bVideoCam = false;
+ CSpecialFX::SnapShotFrames = 0;
+ CSpecialFX::bLiftCam = false;
+ CTxdStore::PushCurrentTxd();
+ CTxdStore::SetCurrentTxd(CTxdStore::FindTxdSlot("particle"));
+ if(gpSmokeTrailTexture == nil)
+ gpSmokeTrailTexture = RwTextureRead("smoketrail", 0);
+ CTxdStore::PopCurrentTxd();
+}
+
+void
+CSpecialFX::AddWeaponStreak(int type)
+{
+ static CMatrix matrix;
+ CVector start;
+ CVector end;
+
+ if (FindPlayerPed() != nil && FindPlayerPed()->m_pWeaponModel != nil) {
+ switch (type) {
+ case WEAPONTYPE_BASEBALLBAT:
+ matrix = RwFrameGetLTM(RpAtomicGetFrame(FindPlayerPed()->m_pWeaponModel));
+ start = matrix * CVector(0.02f, 0.05f, 0.07f);
+ end = matrix * CVector(0.246f, 0.0325f, 0.796f);
+ break;
+ case WEAPONTYPE_GOLFCLUB:
+ matrix = RwFrameGetLTM(RpAtomicGetFrame(FindPlayerPed()->m_pWeaponModel));
+ start = matrix * CVector(0.02f, 0.05f, 0.07f);
+ end = matrix * CVector(-0.054f, 0.0325f, 0.796f);
+ break;
+ case WEAPONTYPE_KATANA:
+ matrix = RwFrameGetLTM(RpAtomicGetFrame(FindPlayerPed()->m_pWeaponModel));
+ start = matrix * CVector(0.02f, 0.05f, 0.07f);
+ end = matrix * CVector(0.096f, -0.0175f, 1.096f);
+ break;
+ default:
+ return;
+ }
+ CMotionBlurStreaks::RegisterStreak((uintptr)FindPlayerPed()->m_pWeaponModel, 100, 100, 100, start, end);
+ }
}
RwObject*
@@ -114,23 +149,16 @@ CSpecialFX::Update(void)
{
CMotionBlurStreaks::Update();
CBulletTraces::Update();
-
- if(FindPlayerPed() &&
- FindPlayerPed()->GetWeapon()->m_eWeaponType == WEAPONTYPE_BASEBALLBAT &&
- FindPlayerPed()->GetWeapon()->m_eWeaponState == WEAPONSTATE_FIRING){
-#ifdef PED_SKIN
- if(IsClumpSkinned(FindPlayerPed()->GetClump())){
- LookForBatCB((RwObject*)FindPlayerPed()->m_pWeaponModel, CModelInfo::GetModelInfo(MI_BASEBALL_BAT));
- }else
-#endif
- RwFrameForAllObjects(FindPlayerPed()->m_pFrames[PED_HANDR]->frame, LookForBatCB, CModelInfo::GetModelInfo(MI_BASEBALL_BAT));
- }
}
void
CSpecialFX::Shutdown(void)
{
C3dMarkers::Shutdown();
+ if (gpSmokeTrailTexture) {
+ RwTextureDestroy(gpSmokeTrailTexture);
+ gpSmokeTrailTexture = nil;
+ }
}
void
@@ -149,6 +177,79 @@ CSpecialFX::Render(void)
POP_RENDERGROUP();
}
+void
+CSpecialFX::Render2DFXs(void)
+{
+ if (CSpecialFX::bVideoCam) {
+ CFont::SetScale(SCREEN_SCALE_X(1.5f), SCREEN_SCALE_Y(1.5f));
+ CFont::SetJustifyOff();
+ CFont::SetBackgroundOff();
+ CFont::SetCentreSize(SCREEN_SCALE_X(620.0f)); // unused
+ CFont::SetCentreOff();
+ CFont::SetPropOn();
+ CFont::SetColor(CRGBA(0, 255, 0, 200));
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
+ sprintf(gString, "%d", CTimer::GetFrameCounter() & 0x3F); // mb % 63
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(SCREEN_WIDTH * 8 / 10, SCREEN_HEIGHT * 8 / 10, gUString);
+ for (int32 i = 0; i < SCREEN_HEIGHT; i += 4) {
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDONE);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDONE);
+ CSprite2d::Draw2DPolygon(0.0f, i, SCREEN_WIDTH, i, 0.0f, i+1, SCREEN_WIDTH, i+1, CRGBA(0, 100, 0, 100));
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ CSprite2d::Draw2DPolygon(0.0f, i+2, SCREEN_WIDTH, i+2, 0.0f, i+3, SCREEN_WIDTH, i+3, CRGBA(0, 0, 0, 150));
+ }
+ int32 tmp = (CTimer::GetTimeInMilliseconds() & 0x7ff) * (SCREEN_HEIGHT + 70.0f) / 2048 - 70.0f; //mb % 2048
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ CSprite2d::Draw2DPolygon(0.0, tmp, SCREEN_WIDTH, tmp, 0.0, tmp + 70.0f, SCREEN_WIDTH, tmp + 70.0f , CRGBA(0, 100, 0, 60));
+ }
+ if (CSpecialFX::bLiftCam) {
+ CFont::SetScale(SCREEN_SCALE_X(1.5f), SCREEN_SCALE_Y(1.5f));
+ CFont::SetJustifyOff();
+ CFont::SetBackgroundOff();
+ CFont::SetCentreSize(SCREEN_SCALE_X(620.0f)); // unused
+ CFont::SetCentreOff();
+ CFont::SetPropOn();
+ CFont::SetColor(CRGBA(100, 100, 100, 200));
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
+ for (int32 i = 0; i < SCREEN_HEIGHT; i += 4) {
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
+ CSprite2d::Draw2DPolygon(0.0f, i, SCREEN_WIDTH, i, 0.0f, i + 1, SCREEN_WIDTH, i + 1, CRGBA(100, 100, 100, 100));
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ CSprite2d::Draw2DPolygon(0.0f, i + 2, SCREEN_WIDTH, i + 2, 0.0f, i + 3, SCREEN_WIDTH, i + 3, CRGBA(0, 0, 0, 150));
+ }
+ int32 tmp = (CTimer::GetTimeInMilliseconds() & 0x7ff) * (SCREEN_HEIGHT + 70.0f) / 2048 - 70.0f; //mb % 2048
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ CSprite2d::Draw2DPolygon(0.0, tmp, SCREEN_WIDTH, tmp, 0.0, tmp + 70.0f, SCREEN_WIDTH, tmp + 70.0f, CRGBA(100, 100, 100, 60));
+ for (int32 i = 0; i < 200; i++) {
+ int32 posX = CGeneral::GetRandomNumber() % (int32)SCREEN_WIDTH;
+ int32 posY = CGeneral::GetRandomNumber() % (int32)SCREEN_HEIGHT;
+ CSprite2d::DrawRect(CRect(posX, posY + 2, posX+20, posY), CRGBA(255, 255, 255, 64));
+ }
+ }
+ if (CSpecialFX::bSnapShotActive) {
+ if (++CSpecialFX::SnapShotFrames > 20) {
+ CSpecialFX::bSnapShotActive = false;
+ CTimer::SetTimeScale(1.0f);
+ } else {
+ CTimer::SetTimeScale(0.0f); //in andro it's 0.00001
+ if (CSpecialFX::SnapShotFrames < 10) {
+ int32 tmp = (255 - 255 * CSpecialFX::SnapShotFrames / 10) * 0.65f;
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
+ CSprite2d::Draw2DPolygon(0.0f, 0.0f, SCREEN_WIDTH, 0.0f, 0.0f, SCREEN_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT, CRGBA(tmp, tmp, tmp, tmp));
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ }
+ }
+ }
+}
+
CRegisteredMotionBlurStreak CMotionBlurStreaks::aStreaks[NUMMBLURSTREAKS];
void
@@ -217,6 +318,7 @@ void
CMotionBlurStreaks::RegisterStreak(uintptr id, uint8 r, uint8 g, uint8 b, CVector p1, CVector p2)
{
int i;
+
for(i = 0; i < NUMMBLURSTREAKS; i++){
if(aStreaks[i].m_id == id){
// Found a streak from last frame, update
@@ -229,10 +331,12 @@ CMotionBlurStreaks::RegisterStreak(uintptr id, uint8 r, uint8 g, uint8 b, CVecto
return;
}
}
+
// Find free slot
- for(i = 0; aStreaks[i].m_id != 0; i++)
+ for(i = 0; aStreaks[i].m_id != 0 ; i++)
if(i == NUMMBLURSTREAKS-1)
return;
+
// Create a new streak
aStreaks[i].m_id = id;
aStreaks[i].m_red = r;
@@ -281,20 +385,103 @@ void CBulletTraces::Init(void)
aTraces[i].m_bInUse = false;
}
-void CBulletTraces::AddTrace(CVector* vecStart, CVector* vecTarget)
+void CBulletTraces::AddTrace(CVector* start, CVector* end, float thickness, uint32 lifeTime, uint8 visibility)
{
- int index;
- for (index = 0; index < NUMBULLETTRACES; index++) {
- if (!aTraces[index].m_bInUse)
- break;
+ int32 enabledCount;
+ uint32 modifiedLifeTime;
+ int32 nextSlot;
+
+ enabledCount = 0;
+ for (int i = 0; i < NUMBULLETTRACES; i++)
+ if (aTraces[i].m_bInUse)
+ enabledCount++;
+ if (enabledCount >= 10)
+ modifiedLifeTime = lifeTime / 4;
+ else if (enabledCount >= 5)
+ modifiedLifeTime = lifeTime / 2;
+ else
+ modifiedLifeTime = lifeTime;
+
+ nextSlot = 0;
+ for (int i = 0; nextSlot < NUMBULLETTRACES && aTraces[i].m_bInUse; i++)
+ nextSlot++;
+ if (nextSlot < 16) {
+ aTraces[nextSlot].m_vecStartPos = *start;
+ aTraces[nextSlot].m_vecEndPos = *end;
+ aTraces[nextSlot].m_bInUse = true;
+ aTraces[nextSlot].m_nCreationTime = CTimer::GetTimeInMilliseconds();
+ aTraces[nextSlot].m_fVisibility = visibility;
+ aTraces[nextSlot].m_fThickness = thickness;
+ aTraces[nextSlot].m_nLifeTime = modifiedLifeTime;
+ }
+
+ float startProjFwd = DotProduct(TheCamera.GetForward(), *start - TheCamera.GetPosition());
+ float endProjFwd = DotProduct(TheCamera.GetForward(), *end - TheCamera.GetPosition());
+ if (startProjFwd * endProjFwd < 0.0f) { //if one of point behind us and second before us
+ float fStartDistFwd = Abs(startProjFwd) / (Abs(startProjFwd) + Abs(endProjFwd));
+
+ float startProjUp = DotProduct(TheCamera.GetUp(), *start - TheCamera.GetPosition());
+ float endProjUp = DotProduct(TheCamera.GetUp(), *end - TheCamera.GetPosition());
+ float distUp = (endProjUp - startProjUp) * fStartDistFwd + startProjUp;
+
+ float startProjRight = DotProduct(TheCamera.GetRight(), *start - TheCamera.GetPosition());
+ float endProjRight = DotProduct(TheCamera.GetRight(), *end - TheCamera.GetPosition());
+ float distRight = (endProjRight - startProjRight) * fStartDistFwd + startProjRight;
+
+ float dist = Sqrt(SQR(distUp) + SQR(distRight));
+ if (dist < 2.0f) {
+ if(distRight < 0.0f)
+ DMAudio.PlayFrontEndSound(SOUND_BULLETTRACE_2, 127 * (1.0f - dist * 0.5f));
+ else
+ DMAudio.PlayFrontEndSound(SOUND_BULLETTRACE_1, 127 * (1.0f - dist * 0.5f));
+ }
+ }
+}
+
+void CBulletTraces::AddTrace(CVector* start, CVector* end, int32 weaponType, class CEntity* shooter)
+{
+ CPhysical* player;
+ float speed;
+ int16 camMode;
+
+ if (shooter == (CEntity*)FindPlayerPed() || (FindPlayerVehicle() != nil && FindPlayerVehicle() == (CVehicle*)shooter)) {
+ camMode = TheCamera.Cams[TheCamera.ActiveCam].Mode;
+ if (camMode == CCam::MODE_M16_1STPERSON
+ || camMode == CCam::MODE_CAMERA
+ || camMode == CCam::MODE_SNIPER
+ || camMode == CCam::MODE_M16_1STPERSON_RUNABOUT
+ || camMode == CCam::MODE_ROCKETLAUNCHER
+ || camMode == CCam::MODE_ROCKETLAUNCHER_RUNABOUT
+ || camMode == CCam::MODE_SNIPER_RUNABOUT
+ || camMode == CCam::MODE_HELICANNON_1STPERSON) {
+
+ player = FindPlayerVehicle() ? (CPhysical*)FindPlayerVehicle() : (CPhysical*)FindPlayerPed();
+ speed = player->m_vecMoveSpeed.Magnitude();
+ if (speed < 0.05f)
+ return;
+ }
+ }
+
+ switch (weaponType) {
+ case WEAPONTYPE_PYTHON:
+ case WEAPONTYPE_SHOTGUN:
+ case WEAPONTYPE_SPAS12_SHOTGUN:
+ case WEAPONTYPE_STUBBY_SHOTGUN:
+ CBulletTraces::AddTrace(start, end, 0.7f, 1000, 200);
+ break;
+ case WEAPONTYPE_M4:
+ case WEAPONTYPE_RUGER:
+ case WEAPONTYPE_SNIPERRIFLE:
+ case WEAPONTYPE_LASERSCOPE:
+ case WEAPONTYPE_M60:
+ case WEAPONTYPE_MINIGUN:
+ case WEAPONTYPE_HELICANNON:
+ CBulletTraces::AddTrace(start, end, 1.0f, 2000, 220);
+ break;
+ default:
+ CBulletTraces::AddTrace(start, end, 0.4f, 750, 150);
+ break;
}
- if (index == NUMBULLETTRACES)
- return;
- aTraces[index].m_vecCurrentPos = *vecStart;
- aTraces[index].m_vecTargetPos = *vecTarget;
- aTraces[index].m_bInUse = true;
- aTraces[index].m_framesInUse = 0;
- aTraces[index].m_lifeTime = 25 + CGeneral::GetRandomNumber() % 32;
}
void CBulletTraces::Render(void)
@@ -303,31 +490,131 @@ void CBulletTraces::Render(void)
if (!aTraces[i].m_bInUse)
continue;
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpSmokeTrailTexture));
+
+ float timeAlive = CTimer::GetTimeInMilliseconds() - aTraces[i].m_nCreationTime;
+
+ float traceThickness = aTraces[i].m_fThickness * timeAlive / aTraces[i].m_nLifeTime;
+ CVector horizontalOffset = aTraces[i].m_vecEndPos - aTraces[i].m_vecStartPos;
+ horizontalOffset.Normalise();
+ horizontalOffset *= traceThickness;
+
+ //then closer trace to die then it more transparent
+ uint8 nAlphaValue = aTraces[i].m_fVisibility * (aTraces[i].m_nLifeTime - timeAlive) / aTraces[i].m_nLifeTime;
+
+ CVector start = aTraces[i].m_vecStartPos;
+ CVector end = aTraces[i].m_vecEndPos;
+ float startProj = DotProduct(start - TheCamera.GetPosition(), TheCamera.GetForward()) - 0.7f;
+ float endProj = DotProduct(end - TheCamera.GetPosition(), TheCamera.GetForward()) - 0.7f;
+ if (startProj < 0.0f && endProj < 0.0f) //we dont need render trace behind us
+ continue;
+
+ if (startProj < 0.0f) { //if strat behind us move it closer
+ float absStartProj = Abs(startProj);
+ float absEndProj = Abs(endProj);
+ start = (absEndProj * start + absStartProj * end) / (absStartProj + absEndProj);
+ } else if (endProj < 0.0f) {
+ float absStartProj = Abs(startProj);
+ float absEndProj = Abs(endProj);
+ end = (absEndProj * start + absStartProj * end) / (absStartProj + absEndProj);
+ }
+
+ //we divide trace at three parts
+ CVector start2 = (7.0f * start + end) / 8;
+ CVector end2 = (7.0f * end + start) / 8;
+
+ RwIm3DVertexSetV(&TraceVertices[5], 10.0f);
+ RwIm3DVertexSetV(&TraceVertices[6], 10.0f);
+ RwIm3DVertexSetV(&TraceVertices[7], 10.0f);
+ RwIm3DVertexSetV(&TraceVertices[8], 10.0f);
+ RwIm3DVertexSetV(&TraceVertices[9], 10.0f);
+
+ RwIm3DVertexSetRGBA(&TraceVertices[0], 255, 255, 255, nAlphaValue);
+ RwIm3DVertexSetRGBA(&TraceVertices[1], 255, 255, 255, nAlphaValue);
+ RwIm3DVertexSetRGBA(&TraceVertices[2], 255, 255, 255, nAlphaValue);
+ RwIm3DVertexSetRGBA(&TraceVertices[3], 255, 255, 255, nAlphaValue);
+ RwIm3DVertexSetRGBA(&TraceVertices[4], 255, 255, 255, nAlphaValue);
+ RwIm3DVertexSetRGBA(&TraceVertices[5], 255, 255, 255, nAlphaValue);
+ RwIm3DVertexSetRGBA(&TraceVertices[6], 255, 255, 255, nAlphaValue);
+ RwIm3DVertexSetRGBA(&TraceVertices[7], 255, 255, 255, nAlphaValue);
+ RwIm3DVertexSetRGBA(&TraceVertices[8], 255, 255, 255, nAlphaValue);
+ RwIm3DVertexSetRGBA(&TraceVertices[9], 255, 255, 255, nAlphaValue);
+ //two points in center
+ RwIm3DVertexSetPos(&TraceVertices[0], start2.x, start2.y, start2.z);
+ RwIm3DVertexSetPos(&TraceVertices[5], end2.x, end2.y, end2.z);
+ //vertical planes
+ RwIm3DVertexSetPos(&TraceVertices[1], start2.x, start2.y, start2.z + traceThickness);
+ RwIm3DVertexSetPos(&TraceVertices[3], start2.x, start2.y, start2.z - traceThickness);
+ RwIm3DVertexSetPos(&TraceVertices[6], end2.x, end2.y, end2.z + traceThickness);
+ RwIm3DVertexSetPos(&TraceVertices[8], end2.x, end2.y, end2.z - traceThickness);
+ //horizontal planes
+ RwIm3DVertexSetPos(&TraceVertices[2], start2.x + horizontalOffset.y, start2.y - horizontalOffset.x, start2.z);
+ RwIm3DVertexSetPos(&TraceVertices[7], end2.x + horizontalOffset.y, end2.y - horizontalOffset.x, end2.z);
+#ifdef FIX_BUGS //this point calculated wrong for some reason
+ RwIm3DVertexSetPos(&TraceVertices[4], start2.x - horizontalOffset.y, start2.y + horizontalOffset.x, start2.z);
+ RwIm3DVertexSetPos(&TraceVertices[9], end2.x - horizontalOffset.y, end2.y + horizontalOffset.x, end2.z);
+#else
+ RwIm3DVertexSetPos(&TraceVertices[4], start2.x - horizontalOffset.y, start2.y - horizontalOffset.y, start2.z);
+ RwIm3DVertexSetPos(&TraceVertices[9], end2.x - horizontalOffset.y, end2.y - horizontalOffset.y, end2.z);
+#endif
+
+ if (RwIm3DTransform(TraceVertices, ARRAY_SIZE(TraceVertices), nil, 1)) {
+ RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TraceIndexList, ARRAY_SIZE(TraceIndexList));
+ RwIm3DEnd();
+ }
+
+ RwIm3DVertexSetV(&TraceVertices[5], 2.0f);
+ RwIm3DVertexSetV(&TraceVertices[6], 2.0f);
+ RwIm3DVertexSetV(&TraceVertices[7], 2.0f);
+ RwIm3DVertexSetV(&TraceVertices[8], 2.0f);
+ RwIm3DVertexSetV(&TraceVertices[9], 2.0f);
+ RwIm3DVertexSetRGBA(&TraceVertices[0], 255, 255, 255, 0);
+ RwIm3DVertexSetRGBA(&TraceVertices[1], 255, 255, 255, 0);
+ RwIm3DVertexSetRGBA(&TraceVertices[2], 255, 255, 255, 0);
+ RwIm3DVertexSetRGBA(&TraceVertices[3], 255, 255, 255, 0);
+ RwIm3DVertexSetRGBA(&TraceVertices[4], 255, 255, 255, 0);
+
+ RwIm3DVertexSetPos(&TraceVertices[0], start.x, start.y, start.z);
+ RwIm3DVertexSetPos(&TraceVertices[1], start.x, start.y, start.z + traceThickness);
+ RwIm3DVertexSetPos(&TraceVertices[3], start.x, start.y, start.z - traceThickness);
+ RwIm3DVertexSetPos(&TraceVertices[2], start.x + horizontalOffset.y, start.y - horizontalOffset.x, start.z);
+
+ RwIm3DVertexSetPos(&TraceVertices[5], start2.x, start2.y, start2.z);
+ RwIm3DVertexSetPos(&TraceVertices[6], start2.x, start2.y, start2.z + traceThickness);
+ RwIm3DVertexSetPos(&TraceVertices[8], start2.x, start2.y, start2.z - traceThickness);
+ RwIm3DVertexSetPos(&TraceVertices[7], start2.x + horizontalOffset.y, start2.y - horizontalOffset.x, start2.z);
#ifdef FIX_BUGS
- // Raster has no transparent pixels so it relies on the raster format having alpha
- // to turn on blending. librw image conversion might get rid of it right now so let's
- // just force it on.
- RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ RwIm3DVertexSetPos(&TraceVertices[4], start.x - horizontalOffset.y, start.y + horizontalOffset.x, start.z);
+ RwIm3DVertexSetPos(&TraceVertices[9], start2.x - horizontalOffset.y, start2.y + horizontalOffset.x, start2.z);
+#else
+ RwIm3DVertexSetPos(&TraceVertices[4], start.x - horizontalOffset.y, start.y - horizontalOffset.y, start.z);
+ RwIm3DVertexSetPos(&TraceVertices[9], start2.x - horizontalOffset.y, start2.y - horizontalOffset.y, start2.z);
#endif
- RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
- RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
- RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpShadowExplosionTex));
- CVector inf = aTraces[i].m_vecCurrentPos;
- CVector sup = aTraces[i].m_vecTargetPos;
- CVector center = (inf + sup) / 2;
- CVector width = CrossProduct(TheCamera.GetForward(), (sup - inf));
- width.Normalise();
- width /= 20;
- uint8 intensity = aTraces[i].m_lifeTime;
- for (int i = 0; i < ARRAY_SIZE(TraceVertices); i++)
- RwIm3DVertexSetRGBA(&TraceVertices[i], intensity, intensity, intensity, 0xFF);
- RwIm3DVertexSetPos(&TraceVertices[0], inf.x + width.x, inf.y + width.y, inf.z + width.z);
- RwIm3DVertexSetPos(&TraceVertices[1], inf.x - width.x, inf.y - width.y, inf.z - width.z);
- RwIm3DVertexSetPos(&TraceVertices[2], center.x + width.x, center.y + width.y, center.z + width.z);
- RwIm3DVertexSetPos(&TraceVertices[3], center.x - width.x, center.y - width.y, center.z - width.z);
- RwIm3DVertexSetPos(&TraceVertices[4], sup.x + width.x, sup.y + width.y, sup.z + width.z);
- RwIm3DVertexSetPos(&TraceVertices[5], sup.x - width.x, sup.y - width.y, sup.z - width.z);
- LittleTest();
+
+ if (RwIm3DTransform(TraceVertices, ARRAY_SIZE(TraceVertices), nil, rwIM3D_VERTEXUV)) {
+ RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TraceIndexList, ARRAY_SIZE(TraceIndexList));
+ RwIm3DEnd();
+ }
+
+ RwIm3DVertexSetPos(&TraceVertices[1], end.x, end.y, end.z);
+ RwIm3DVertexSetPos(&TraceVertices[2], end.x, end.y, end.z + traceThickness);
+ RwIm3DVertexSetPos(&TraceVertices[4], end.x, end.y, end.z - traceThickness);
+ RwIm3DVertexSetPos(&TraceVertices[3], end.x + horizontalOffset.y, end.y - horizontalOffset.x, end.z);
+
+ RwIm3DVertexSetPos(&TraceVertices[5], end2.x, end2.y, end2.z);
+ RwIm3DVertexSetPos(&TraceVertices[6], end2.x, end2.y, end2.z + traceThickness);
+ RwIm3DVertexSetPos(&TraceVertices[8], end2.x, end2.y, end2.z - traceThickness);
+ RwIm3DVertexSetPos(&TraceVertices[7], end2.x + horizontalOffset.y, end2.y - horizontalOffset.x, end2.z);
+#ifdef FIX_BUGS
+ RwIm3DVertexSetPos(&TraceVertices[5], end.x - horizontalOffset.y, end.y + horizontalOffset.x, end.z);
+ RwIm3DVertexSetPos(&TraceVertices[9], end2.x - horizontalOffset.y, end2.y + horizontalOffset.x, end2.z);
+#else
+ RwIm3DVertexSetPos(&TraceVertices[5], end.x - horizontalOffset.y, end.y - horizontalOffset.y, end.z);
+ RwIm3DVertexSetPos(&TraceVertices[9], end2.x - horizontalOffset.y, end2.y - horizontalOffset.y, end2.z);
+#endif
+
if (RwIm3DTransform(TraceVertices, ARRAY_SIZE(TraceVertices), nil, rwIM3D_VERTEXUV)) {
RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TraceIndexList, ARRAY_SIZE(TraceIndexList));
RwIm3DEnd();
@@ -348,23 +635,8 @@ void CBulletTraces::Update(void)
void CBulletTrace::Update(void)
{
- if (m_framesInUse == 0) {
- m_framesInUse++;
- return;
- }
- if (m_framesInUse > 60) {
+ if (CTimer::GetTimeInMilliseconds() - m_nCreationTime >= m_nLifeTime)
m_bInUse = false;
- return;
- }
- CVector diff = m_vecCurrentPos - m_vecTargetPos;
- float remaining = diff.Magnitude();
- if (remaining > 0.8f)
- m_vecCurrentPos = m_vecTargetPos + (remaining - 0.8f) / remaining * diff;
- else
- m_bInUse = false;
- if (--m_lifeTime == 0)
- m_bInUse = false;
- m_framesInUse++;
}
RpAtomic *
@@ -418,6 +690,7 @@ C3dMarker::DeleteMarkerObject()
m_nIdentifier = 0;
m_nStartTime = 0;
m_bIsUsed = false;
+ m_bFindZOnNextPlacement = false;
m_nType = MARKERTYPE_INVALID;
frame = RpAtomicGetFrame(m_pAtomic);
@@ -461,6 +734,7 @@ C3dMarkers::Init()
m_aMarkerArray[i].m_pAtomic = nil;
m_aMarkerArray[i].m_nType = MARKERTYPE_INVALID;
m_aMarkerArray[i].m_bIsUsed = false;
+ m_aMarkerArray[i].m_bFindZOnNextPlacement = false;
m_aMarkerArray[i].m_nIdentifier = 0;
m_aMarkerArray[i].m_Color.red = 255;
m_aMarkerArray[i].m_Color.green = 255;
@@ -506,8 +780,15 @@ C3dMarkers::Render()
ActivateDirectional();
for (int i = 0; i < NUM3DMARKERS; i++) {
if (m_aMarkerArray[i].m_bIsUsed) {
- if (m_aMarkerArray[i].m_fCameraRange < 120.0f)
+ if (m_aMarkerArray[i].m_fCameraRange < 150.0f) {
m_aMarkerArray[i].Render();
+ if (m_aMarkerArray[i].m_nType == MARKERTYPE_ARROW) {
+ CCoronas::RegisterCorona((uintptr)&m_aMarkerArray[i],
+ SPHERE_MARKER_R, SPHERE_MARKER_G, SPHERE_MARKER_B, 192,
+ m_aMarkerArray[i].m_Matrix.GetPosition(), 1.2f * m_aMarkerArray[i].m_fSize, 50.0f * TheCamera.LODDistMultiplier,
+ CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, 0.0f, false);
+ }
+ }
NumActiveMarkers++;
m_aMarkerArray[i].m_bIsUsed = false;
} else if (m_aMarkerArray[i].m_pAtomic != nil) {
@@ -520,9 +801,9 @@ C3dMarker *
C3dMarkers::PlaceMarker(uint32 identifier, uint16 type, CVector &pos, float size, uint8 r, uint8 g, uint8 b, uint8 a, uint16 pulsePeriod, float pulseFraction, int16 rotateRate)
{
C3dMarker *pMarker;
-
+ CVector2D playerPos = FindPlayerCentreOfWorld(0);
pMarker = nil;
- float dist = Sqrt((pos.x - FindPlayerCentreOfWorld(0).x) * (pos.x - FindPlayerCentreOfWorld(0).x) + (pos.y - FindPlayerCentreOfWorld(0).y) * (pos.y - FindPlayerCentreOfWorld(0).y));
+ float dist = ((CVector2D)pos - playerPos).Magnitude();
if (type != MARKERTYPE_ARROW && type != MARKERTYPE_CYLINDER) return nil;
@@ -588,13 +869,22 @@ C3dMarkers::PlaceMarker(uint32 identifier, uint16 type, CVector &pos, float size
else
pMarker->m_Color.alpha = (float)a * 0.4f * someSin + a;
}
- if (pMarker->m_nRotateRate) {
+ if (pMarker->m_nRotateRate != 0) {
CVector pos = pMarker->m_Matrix.GetPosition();
pMarker->m_Matrix.RotateZ(DEGTORAD(pMarker->m_nRotateRate * CTimer::GetTimeStep()));
pMarker->m_Matrix.GetPosition() = pos;
}
if (type == MARKERTYPE_ARROW)
pMarker->m_Matrix.GetPosition() = pos;
+
+ if (pMarker->m_bFindZOnNextPlacement) {
+ if ((playerPos - pos).MagnitudeSqr() < sq(100.f) && CColStore::HasCollisionLoaded(CVector2D(pos))) {
+ float z = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z + 1.0f, nil);
+ if (z != 0.0f)
+ pMarker->m_Matrix.GetPosition().z = z - 0.05f * size;
+ pMarker->m_bFindZOnNextPlacement = false;
+ }
+ }
pMarker->m_bIsUsed = true;
return pMarker;
}
@@ -604,9 +894,14 @@ C3dMarkers::PlaceMarker(uint32 identifier, uint16 type, CVector &pos, float size
pMarker->AddMarker(identifier, type, size, r, g, b, a, pulsePeriod, pulseFraction, rotateRate);
if (type == MARKERTYPE_CYLINDER || type == MARKERTYPE_0 || type == MARKERTYPE_2) {
- float z = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z + 1.0f, nil);
- if (z != 0.0f)
- pos.z = z - 0.05f * size;
+ if ((playerPos - pos).MagnitudeSqr() < sq(100.f) && CColStore::HasCollisionLoaded(CVector2D(pos))) {
+ float z = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z + 1.0f, nil);
+ if (z != 0.0f)
+ pos.z = z - 0.05f * size;
+ pMarker->m_bFindZOnNextPlacement = false;
+ } else {
+ pMarker->m_bFindZOnNextPlacement = true;
+ }
}
pMarker->m_Matrix.SetTranslate(pos.x, pos.y, pos.z);
if (type == MARKERTYPE_2) {
@@ -766,6 +1061,10 @@ CBrightLights::Render(void)
g = aBrightLights[i].m_green;
b = aBrightLights[i].m_blue;
break;
+#ifdef FIX_BUGS //just to make sure that color never will be undefined
+ default:
+ return;
+#endif
}
if(aBrightLights[i].m_camDist < BRIGHTLIGHTS_FADE_DIST)
@@ -832,18 +1131,18 @@ CBrightLights::Render(void)
case BRIGHTLIGHT_FRONT_BIG:
case BRIGHTLIGHT_REAR_BIG:
for (j = 0; j < 8; j++) {
- pos = BigCarHeadLightsSide[j] * aBrightLights[i].m_side +
- BigCarHeadLightsUp[j] * aBrightLights[i].m_up +
- BigCarHeadLightsFront[j] * aBrightLights[i].m_front +
- aBrightLights[i].m_pos;
- RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + j], r, g, b, a);
- RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + j], pos.x, pos.y, pos.z);
- }
- for (j = 0; j < 12 * 3; j++)
- TempBufferRenderIndexList[TempBufferIndicesStored + j] = CubeIndices[j] + TempBufferVerticesStored;
- TempBufferVerticesStored += 8;
- TempBufferIndicesStored += 12 * 3;
- break;
+ pos = BigCarHeadLightsSide[j] * aBrightLights[i].m_side +
+ BigCarHeadLightsUp[j] * aBrightLights[i].m_up +
+ BigCarHeadLightsFront[j] * aBrightLights[i].m_front +
+ aBrightLights[i].m_pos;
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + j], r, g, b, a);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + j], pos.x, pos.y, pos.z);
+ }
+ for (j = 0; j < 12 * 3; j++)
+ TempBufferRenderIndexList[TempBufferIndicesStored + j] = CubeIndices[j] + TempBufferVerticesStored;
+ TempBufferVerticesStored += 8;
+ TempBufferIndicesStored += 12 * 3;
+ break;
case BRIGHTLIGHT_FRONT_TALL:
case BRIGHTLIGHT_REAR_TALL:
@@ -1050,8 +1349,9 @@ CMoneyMessage::Render()
{
const float MAX_SCALE = 4.0f;
uint32 nLifeTime = CTimer::GetTimeInMilliseconds() - m_nTimeRegistered;
- if (nLifeTime >= MONEY_MESSAGE_LIFETIME_MS) m_nTimeRegistered = 0;
- else {
+ if (nLifeTime >= MONEY_MESSAGE_LIFETIME_MS) {
+ m_nTimeRegistered = 0;
+ } else {
float fLifeTime = (float)nLifeTime / MONEY_MESSAGE_LIFETIME_MS;
RwV3d vecOut;
float fDistX, fDistY;
@@ -1060,7 +1360,6 @@ CMoneyMessage::Render()
fDistY *= (0.7f * fLifeTime + 2.0f) * m_fSize;
CFont::SetPropOn();
CFont::SetBackgroundOff();
-
float fScaleY = Min(fDistY / 100.0f, MAX_SCALE);
float fScaleX = Min(fDistX / 100.0f, MAX_SCALE);
@@ -1074,7 +1373,7 @@ CMoneyMessage::Render()
CFont::SetJustifyOff();
CFont::SetColor(CRGBA(m_Colour.r, m_Colour.g, m_Colour.b, (255.0f - 255.0f * fLifeTime) * m_fOpacity));
CFont::SetBackGroundOnlyTextOff();
- CFont::SetFontStyle(FONT_BANK);
+ FONT_LOCALE(FONT_STANDARD);
CFont::PrintString(vecOut.x, vecOut.y, m_aText);
}
}
diff --git a/src/renderer/SpecialFX.h b/src/renderer/SpecialFX.h
index 2d9f18b1..f163d8ca 100644
--- a/src/renderer/SpecialFX.h
+++ b/src/renderer/SpecialFX.h
@@ -1,14 +1,24 @@
#pragma once
+//file done
+
class CSpecialFX
{
public:
+ static bool bVideoCam;
+ static bool bLiftCam;
+ static bool bSnapShotActive;
+ static int32 SnapShotFrames;
+
static void Render(void);
static void Update(void);
static void Init(void);
static void Shutdown(void);
+ static void AddWeaponStreak(int type);
+ static void Render2DFXs();
};
+
class CRegisteredMotionBlurStreak
{
public:
@@ -24,6 +34,7 @@ public:
void Render(void);
};
+
class CMotionBlurStreaks
{
static CRegisteredMotionBlurStreak aStreaks[NUMMBLURSTREAKS];
@@ -34,26 +45,31 @@ public:
static void Render(void);
};
+
struct CBulletTrace
{
- CVector m_vecCurrentPos;
- CVector m_vecTargetPos;
+ CVector m_vecStartPos;
+ CVector m_vecEndPos;
bool m_bInUse;
- uint8 m_framesInUse;
- uint8 m_lifeTime;
+ uint32 m_nCreationTime;
+ uint32 m_nLifeTime;
+ float m_fThickness;
+ uint8 m_fVisibility;
void Update(void);
};
+
class CBulletTraces
{
public:
static CBulletTrace aTraces[NUMBULLETTRACES];
static void Init(void);
- static void AddTrace(CVector*, CVector*);
static void Render(void);
static void Update(void);
+ static void AddTrace(CVector* start, CVector* end, float thickness, uint32 lifeTime, uint8 visibility);
+ static void AddTrace(CVector* start, CVector* end, int32 weaponType, class CEntity* shooter);
};
enum
@@ -77,6 +93,7 @@ public:
RpMaterial *m_pMaterial;
uint16 m_nType;
bool m_bIsUsed;
+ bool m_bFindZOnNextPlacement;
uint32 m_nIdentifier;
RwRGBA m_Color;
uint16 m_nPulsePeriod;
@@ -93,6 +110,7 @@ public:
void Render();
};
+
class C3dMarkers
{
public:
@@ -133,6 +151,7 @@ enum
BRIGHTLIGHT_REAR = BRIGHTLIGHT_REAR_LONG,
};
+
class CBrightLight
{
public:
@@ -147,6 +166,7 @@ public:
uint8 m_blue;
};
+
class CBrightLights
{
static int NumBrightLights;
@@ -166,6 +186,7 @@ enum
SHINYTEXT_FLAT
};
+
class CShinyText
{
public:
@@ -178,7 +199,8 @@ public:
uint8 m_blue;
};
-class CShinyTexts
+
+class CShinyTexts
{
static int NumShinyTexts;
static CShinyText aShinyTexts[NUMSHINYTEXTS];
@@ -186,11 +208,12 @@ public:
static void Init(void);
static void RegisterOne(CVector p0, CVector p1, CVector p2, CVector p3,
float u0, float v0, float u1, float v1, float u2, float v2, float u3, float v3,
- uint8 type, uint8 red, uint8 green, uint8 blue, float maxDist);
+ uint8 type, uint8 red, uint8 green, uint8 blue, float maxDist); //not used
static void Render(void);
static void RenderOutGeometryBuffer(void);
};
+
class CMoneyMessage
{
friend class CMoneyMessages;
@@ -205,6 +228,7 @@ public:
void Render();
};
+
class CMoneyMessages
{
static CMoneyMessage aMoneyMessages[NUMMONEYMESSAGES];
@@ -214,11 +238,12 @@ public:
static void RegisterOne(CVector vecPos, const char *pText, uint8 bRed, uint8 bGreen, uint8 bBlue, float fSize, float fOpacity);
};
+
class CSpecialParticleStuff
{
static uint32 BoatFromStart;
public:
- static void CreateFoamAroundObject(CMatrix*, float, float, float, int32);
- static void StartBoatFoamAnimation();
- static void UpdateBoatFoamAnimation(CMatrix*);
+ static void CreateFoamAroundObject(CMatrix*, float, float, float, int32); //not used
+ static void StartBoatFoamAnimation(); //not used
+ static void UpdateBoatFoamAnimation(CMatrix*); //not used
};
diff --git a/src/renderer/Sprite.cpp b/src/renderer/Sprite.cpp
index 3fef0733..ecfd3fdc 100644
--- a/src/renderer/Sprite.cpp
+++ b/src/renderer/Sprite.cpp
@@ -156,10 +156,10 @@ CSprite::RenderOneXLUSprite_Rotate_Aspect(float x, float y, float z, float w, fl
// Fade out when too near
// why not in buffered version?
- if(z < 3.0f){
- if(z < 1.5f)
+ if(z < 2.3f){
+ if(z < 1.3f)
return;
- int f = (z - 1.5f)/1.5f * 255;
+ int f = (z - 1.3f)/(2.3f-1.3f) * 255;
r = f*r >> 8;
g = f*g >> 8;
b = f*b >> 8;
@@ -271,8 +271,8 @@ CSprite::RenderBufferedOneXLUSprite_Rotate_Dimension(float x, float y, float z,
{
m_bFlushSpriteBufferSwitchZTest = 0;
// TODO: replace with lookup
- float c = Cos(DEGTORAD(rotation));
- float s = Sin(DEGTORAD(rotation));
+ float c = Cos(rotation);
+ float s = Sin(rotation);
float xs[4];
float ys[4];
@@ -584,8 +584,8 @@ CSprite::RenderBufferedOneXLUSprite2D_Rotate_Dimension(float x, float y, float w
{
m_bFlushSpriteBufferSwitchZTest = 1;
CRGBA col(intens * colour.red >> 8, intens * colour.green >> 8, intens * colour.blue >> 8, alpha);
- float c = Cos(DEGTORAD(rotation));
- float s = Sin(DEGTORAD(rotation));
+ float c = Cos(rotation);
+ float s = Sin(rotation);
Set6Vertices2D(&SpriteBufferVerts[6 * nSpriteBufferIndex],
x + c*w - s*h,
diff --git a/src/renderer/Sprite.h b/src/renderer/Sprite.h
index ec4c1d1b..fae6684e 100644
--- a/src/renderer/Sprite.h
+++ b/src/renderer/Sprite.h
@@ -7,6 +7,9 @@ class CSprite
static float m_fRecipNearClipPlane;
static int32 m_bFlushSpriteBufferSwitchZTest;
public:
+ static float GetNearScreenZ(void) { return m_f2DNearScreenZ; }
+ static float GetFarScreenZ(void) { return m_f2DFarScreenZ; }
+
static float CalcHorizonCoors(void);
static bool CalcScreenCoors(const RwV3d &in, RwV3d *out, float *outw, float *outh, bool farclip);
static void InitSpriteBuffer(void);
diff --git a/src/renderer/Sprite2d.cpp b/src/renderer/Sprite2d.cpp
index 59622516..92f326f8 100644
--- a/src/renderer/Sprite2d.cpp
+++ b/src/renderer/Sprite2d.cpp
@@ -5,79 +5,32 @@
#include "Camera.h"
#include "Sprite2d.h"
#include "Font.h"
+#include "RenderBuffer.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];
+float CSprite2d::NearScreenZ;
+float CSprite2d::NearCamZ;
+int CSprite2d::nextBufferVertex;
+int CSprite2d::nextBufferIndex;
+RwIm2DVertex CSprite2d::maVertices[8];
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
CSprite2d::InitPerFrame(void)
{
- int i;
-
- mCurrentBank = 0;
- for(i = 0; i < 10; i++)
- mCurrentSprite[i] = 0;
-#ifndef SQUEEZE_PERFORMANCE
- for(i = 0; i < 10; i++)
- mpBankTextures[i] = nil;
-#endif
-}
-
-int32
-CSprite2d::GetBank(int32 n, RwTexture *tex)
-{
-#ifndef SQUEEZE_PERFORMANCE
- mpBankTextures[mCurrentBank] = tex;
-#endif
- mCurrentSprite[mCurrentBank] = 0;
- mBankStart[mCurrentBank+1] = mBankStart[mCurrentBank] + n;
- return mCurrentBank++;
-}
-
-void
-CSprite2d::AddSpriteToBank(int32 bank, const CRect &rect, const CRGBA &col,
- float u0, float v0, float u1, float v1, float u3, float v3, float u2, float v2)
-{
- SetVertices(&maBankVertices[6 * (mCurrentSprite[bank] + mBankStart[bank])],
- rect, col, col, col, col,
- u0, v0, u1, v1, u2, v2, u3, v3);
- mCurrentSprite[bank]++;
- if(mCurrentSprite[bank] + mBankStart[bank] >= mBankStart[bank+1]){
- DrawBank(bank);
- mCurrentSprite[bank] = 0;
- }
-}
-
-void
-CSprite2d::DrawBank(int32 bank)
-{
- if(mCurrentSprite[bank] == 0)
- return;
-#ifndef SQUEEZE_PERFORMANCE
- RwRenderStateSet(rwRENDERSTATETEXTURERASTER,
- mpBankTextures[bank] ? RwTextureGetRaster(mpBankTextures[bank]) : nil);
-#else
- CFont::Sprite[bank].SetRenderState();
-#endif
- RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
- RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR);
- RwIm2DRenderPrimitive(rwPRIMTYPETRILIST, &maBankVertices[6*mBankStart[bank]], 6*mCurrentSprite[bank]);
- mCurrentSprite[bank] = 0;
- RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
+ nextBufferVertex = 0;
+ nextBufferIndex = 0;
+ RecipNearClip = 1.0f / RwCameraGetNearClipPlane(Scene.camera);
+ NearScreenZ = RwIm2DGetNearScreenZ();
+ // not original but you're supposed to set camera z too
+ // wrapping all this in FIX_BUGS is too ugly
+ NearCamZ = RwCameraGetNearClipPlane(Scene.camera);
}
-
-
void
CSprite2d::Delete(void)
{
@@ -122,7 +75,7 @@ CSprite2d::SetRenderState(void)
void
CSprite2d::Draw(float x, float y, float w, float h, const CRGBA &col)
{
- SetVertices(CRect(x, y, x + w, y + h), col, col, col, col, 0);
+ SetVertices(CRect(x, y, x + w, y + h), col, col, col, col);
SetRenderState();
RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::maVertices, 4);
}
@@ -130,7 +83,7 @@ CSprite2d::Draw(float x, float y, float w, float h, const CRGBA &col)
void
CSprite2d::Draw(const CRect &rect, const CRGBA &col)
{
- SetVertices(rect, col, col, col, col, 0);
+ SetVertices(rect, col, col, col, col);
SetRenderState();
RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::maVertices, 4);
}
@@ -147,7 +100,7 @@ CSprite2d::Draw(const CRect &rect, const CRGBA &col,
void
CSprite2d::Draw(const CRect &rect, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3)
{
- SetVertices(rect, c0, c1, c2, c3, 0);
+ SetVertices(rect, c0, c1, c2, c3);
SetRenderState();
RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::maVertices, 4);
}
@@ -160,24 +113,13 @@ CSprite2d::Draw(float x1, float y1, float x2, float y2, float x3, float y3, floa
RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::maVertices, 4);
}
-
// Arguments:
// 2---3
// | |
// 0---1
void
-CSprite2d::SetVertices(const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3, uint32 far)
+CSprite2d::SetVertices(const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3)
{
- float screenz, z, recipz;
-
- if(far){
- screenz = RwIm2DGetFarScreenZ();
- z = RwCameraGetFarClipPlane(Scene.camera);
- }else{
- screenz = RwIm2DGetNearScreenZ();
- z = 1.0f/RecipNearClip;
- }
- recipz = 1.0f/z;
float offset = 1.0f/1024.0f;
// This is what we draw:
@@ -186,159 +128,141 @@ CSprite2d::SetVertices(const CRect &r, const CRGBA &c0, const CRGBA &c1, const C
// 3---2
RwIm2DVertexSetScreenX(&maVertices[0], r.left);
RwIm2DVertexSetScreenY(&maVertices[0], r.top);
- RwIm2DVertexSetScreenZ(&maVertices[0], screenz);
- RwIm2DVertexSetCameraZ(&maVertices[0], z);
- RwIm2DVertexSetRecipCameraZ(&maVertices[0], recipz);
+ RwIm2DVertexSetScreenZ(&maVertices[0], NearScreenZ);
+ RwIm2DVertexSetCameraZ(&maVertices[0], NearCamZ);
+ RwIm2DVertexSetRecipCameraZ(&maVertices[0], RecipNearClip);
RwIm2DVertexSetIntRGBA(&maVertices[0], c2.r, c2.g, c2.b, c2.a);
- RwIm2DVertexSetU(&maVertices[0], 0.0f+offset, recipz);
- RwIm2DVertexSetV(&maVertices[0], 0.0f+offset, recipz);
+ RwIm2DVertexSetU(&maVertices[0], 0.0f+offset, RecipNearClip);
+ RwIm2DVertexSetV(&maVertices[0], 0.0f+offset, RecipNearClip);
RwIm2DVertexSetScreenX(&maVertices[1], r.right);
RwIm2DVertexSetScreenY(&maVertices[1], r.top);
- RwIm2DVertexSetScreenZ(&maVertices[1], screenz);
- RwIm2DVertexSetCameraZ(&maVertices[1], z);
- RwIm2DVertexSetRecipCameraZ(&maVertices[1], recipz);
+ RwIm2DVertexSetScreenZ(&maVertices[1], NearScreenZ);
+ RwIm2DVertexSetCameraZ(&maVertices[1], NearCamZ);
+ RwIm2DVertexSetRecipCameraZ(&maVertices[1], RecipNearClip);
RwIm2DVertexSetIntRGBA(&maVertices[1], c3.r, c3.g, c3.b, c3.a);
- RwIm2DVertexSetU(&maVertices[1], 1.0f+offset, recipz);
- RwIm2DVertexSetV(&maVertices[1], 0.0f+offset, recipz);
+ RwIm2DVertexSetU(&maVertices[1], 1.0f+offset, RecipNearClip);
+ RwIm2DVertexSetV(&maVertices[1], 0.0f+offset, RecipNearClip);
RwIm2DVertexSetScreenX(&maVertices[2], r.right);
RwIm2DVertexSetScreenY(&maVertices[2], r.bottom);
- RwIm2DVertexSetScreenZ(&maVertices[2], screenz);
- RwIm2DVertexSetCameraZ(&maVertices[2], z);
- RwIm2DVertexSetRecipCameraZ(&maVertices[2], recipz);
+ RwIm2DVertexSetScreenZ(&maVertices[2], NearScreenZ);
+ RwIm2DVertexSetCameraZ(&maVertices[2], NearCamZ);
+ RwIm2DVertexSetRecipCameraZ(&maVertices[2], RecipNearClip);
RwIm2DVertexSetIntRGBA(&maVertices[2], c1.r, c1.g, c1.b, c1.a);
- RwIm2DVertexSetU(&maVertices[2], 1.0f+offset, recipz);
- RwIm2DVertexSetV(&maVertices[2], 1.0f+offset, recipz);
+ RwIm2DVertexSetU(&maVertices[2], 1.0f+offset, RecipNearClip);
+ RwIm2DVertexSetV(&maVertices[2], 1.0f+offset, RecipNearClip);
RwIm2DVertexSetScreenX(&maVertices[3], r.left);
RwIm2DVertexSetScreenY(&maVertices[3], r.bottom);
- RwIm2DVertexSetScreenZ(&maVertices[3], screenz);
- RwIm2DVertexSetCameraZ(&maVertices[3], z);
- RwIm2DVertexSetRecipCameraZ(&maVertices[3], recipz);
+ RwIm2DVertexSetScreenZ(&maVertices[3], NearScreenZ);
+ RwIm2DVertexSetCameraZ(&maVertices[3], NearCamZ);
+ RwIm2DVertexSetRecipCameraZ(&maVertices[3], RecipNearClip);
RwIm2DVertexSetIntRGBA(&maVertices[3], c0.r, c0.g, c0.b, c0.a);
- RwIm2DVertexSetU(&maVertices[3], 0.0f+offset, recipz);
- RwIm2DVertexSetV(&maVertices[3], 1.0f+offset, recipz);
+ RwIm2DVertexSetU(&maVertices[3], 0.0f+offset, RecipNearClip);
+ RwIm2DVertexSetV(&maVertices[3], 1.0f+offset, RecipNearClip);
}
void
CSprite2d::SetVertices(const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3,
float u0, float v0, float u1, float v1, float u3, float v3, float u2, float v2)
{
- float screenz, z, recipz;
-
- screenz = RwIm2DGetNearScreenZ();
- z = 1.0f/RecipNearClip;
- recipz = 1.0f/z;
-
// This is what we draw:
// 0---1
// | / |
// 3---2
RwIm2DVertexSetScreenX(&maVertices[0], r.left);
RwIm2DVertexSetScreenY(&maVertices[0], r.top);
- RwIm2DVertexSetScreenZ(&maVertices[0], screenz);
- RwIm2DVertexSetCameraZ(&maVertices[0], z);
- RwIm2DVertexSetRecipCameraZ(&maVertices[0], recipz);
+ RwIm2DVertexSetScreenZ(&maVertices[0], NearScreenZ);
+ RwIm2DVertexSetCameraZ(&maVertices[0], NearCamZ);
+ RwIm2DVertexSetRecipCameraZ(&maVertices[0], RecipNearClip);
RwIm2DVertexSetIntRGBA(&maVertices[0], c2.r, c2.g, c2.b, c2.a);
- RwIm2DVertexSetU(&maVertices[0], u0, recipz);
- RwIm2DVertexSetV(&maVertices[0], v0, recipz);
+ RwIm2DVertexSetU(&maVertices[0], u0, RecipNearClip);
+ RwIm2DVertexSetV(&maVertices[0], v0, RecipNearClip);
RwIm2DVertexSetScreenX(&maVertices[1], r.right);
RwIm2DVertexSetScreenY(&maVertices[1], r.top);
- RwIm2DVertexSetScreenZ(&maVertices[1], screenz);
- RwIm2DVertexSetCameraZ(&maVertices[1], z);
- RwIm2DVertexSetRecipCameraZ(&maVertices[1], recipz);
+ RwIm2DVertexSetScreenZ(&maVertices[1], NearScreenZ);
+ RwIm2DVertexSetCameraZ(&maVertices[1], NearCamZ);
+ RwIm2DVertexSetRecipCameraZ(&maVertices[1], RecipNearClip);
RwIm2DVertexSetIntRGBA(&maVertices[1], c3.r, c3.g, c3.b, c3.a);
- RwIm2DVertexSetU(&maVertices[1], u1, recipz);
- RwIm2DVertexSetV(&maVertices[1], v1, recipz);
+ RwIm2DVertexSetU(&maVertices[1], u1, RecipNearClip);
+ RwIm2DVertexSetV(&maVertices[1], v1, RecipNearClip);
RwIm2DVertexSetScreenX(&maVertices[2], r.right);
RwIm2DVertexSetScreenY(&maVertices[2], r.bottom);
- RwIm2DVertexSetScreenZ(&maVertices[2], screenz);
- RwIm2DVertexSetCameraZ(&maVertices[2], z);
- RwIm2DVertexSetRecipCameraZ(&maVertices[2], recipz);
+ RwIm2DVertexSetScreenZ(&maVertices[2], NearScreenZ);
+ RwIm2DVertexSetCameraZ(&maVertices[2], NearCamZ);
+ RwIm2DVertexSetRecipCameraZ(&maVertices[2], RecipNearClip);
RwIm2DVertexSetIntRGBA(&maVertices[2], c1.r, c1.g, c1.b, c1.a);
- RwIm2DVertexSetU(&maVertices[2], u2, recipz);
- RwIm2DVertexSetV(&maVertices[2], v2, recipz);
+ RwIm2DVertexSetU(&maVertices[2], u2, RecipNearClip);
+ RwIm2DVertexSetV(&maVertices[2], v2, RecipNearClip);
RwIm2DVertexSetScreenX(&maVertices[3], r.left);
RwIm2DVertexSetScreenY(&maVertices[3], r.bottom);
- RwIm2DVertexSetScreenZ(&maVertices[3], screenz);
- RwIm2DVertexSetCameraZ(&maVertices[3], z);
- RwIm2DVertexSetRecipCameraZ(&maVertices[3], recipz);
+ RwIm2DVertexSetScreenZ(&maVertices[3], NearScreenZ);
+ RwIm2DVertexSetCameraZ(&maVertices[3], NearCamZ);
+ RwIm2DVertexSetRecipCameraZ(&maVertices[3], RecipNearClip);
RwIm2DVertexSetIntRGBA(&maVertices[3], c0.r, c0.g, c0.b, c0.a);
- RwIm2DVertexSetU(&maVertices[3], u3, recipz);
- RwIm2DVertexSetV(&maVertices[3], v3, recipz);
+ RwIm2DVertexSetU(&maVertices[3], u3, RecipNearClip);
+ RwIm2DVertexSetV(&maVertices[3], v3, RecipNearClip);
}
void
CSprite2d::SetVertices(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4,
const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3)
{
- float screenz, recipz;
- float z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
-
- screenz = RwIm2DGetNearScreenZ();
- recipz = RecipNearClip;
-
RwIm2DVertexSetScreenX(&maVertices[0], x3);
RwIm2DVertexSetScreenY(&maVertices[0], y3);
- RwIm2DVertexSetScreenZ(&maVertices[0], screenz);
- RwIm2DVertexSetCameraZ(&maVertices[0], z);
- RwIm2DVertexSetRecipCameraZ(&maVertices[0], recipz);
+ RwIm2DVertexSetScreenZ(&maVertices[0], NearScreenZ);
+ RwIm2DVertexSetCameraZ(&maVertices[0], NearCamZ);
+ RwIm2DVertexSetRecipCameraZ(&maVertices[0], RecipNearClip);
RwIm2DVertexSetIntRGBA(&maVertices[0], c2.r, c2.g, c2.b, c2.a);
- RwIm2DVertexSetU(&maVertices[0], 0.0f, recipz);
- RwIm2DVertexSetV(&maVertices[0], 0.0f, recipz);
+ RwIm2DVertexSetU(&maVertices[0], 0.0f, RecipNearClip);
+ RwIm2DVertexSetV(&maVertices[0], 0.0f, RecipNearClip);
RwIm2DVertexSetScreenX(&maVertices[1], x4);
RwIm2DVertexSetScreenY(&maVertices[1], y4);
- RwIm2DVertexSetScreenZ(&maVertices[1], screenz);
- RwIm2DVertexSetCameraZ(&maVertices[1], z);
- RwIm2DVertexSetRecipCameraZ(&maVertices[1], recipz);
+ RwIm2DVertexSetScreenZ(&maVertices[1], NearScreenZ);
+ RwIm2DVertexSetCameraZ(&maVertices[1], NearCamZ);
+ RwIm2DVertexSetRecipCameraZ(&maVertices[1], RecipNearClip);
RwIm2DVertexSetIntRGBA(&maVertices[1], c3.r, c3.g, c3.b, c3.a);
- RwIm2DVertexSetU(&maVertices[1], 1.0f, recipz);
- RwIm2DVertexSetV(&maVertices[1], 0.0f, recipz);
+ RwIm2DVertexSetU(&maVertices[1], 1.0f, RecipNearClip);
+ RwIm2DVertexSetV(&maVertices[1], 0.0f, RecipNearClip);
RwIm2DVertexSetScreenX(&maVertices[2], x2);
RwIm2DVertexSetScreenY(&maVertices[2], y2);
- RwIm2DVertexSetScreenZ(&maVertices[2], screenz);
- RwIm2DVertexSetCameraZ(&maVertices[2], z);
- RwIm2DVertexSetRecipCameraZ(&maVertices[2], recipz);
+ RwIm2DVertexSetScreenZ(&maVertices[2], NearScreenZ);
+ RwIm2DVertexSetCameraZ(&maVertices[2], NearCamZ);
+ RwIm2DVertexSetRecipCameraZ(&maVertices[2], RecipNearClip);
RwIm2DVertexSetIntRGBA(&maVertices[2], c1.r, c1.g, c1.b, c1.a);
- RwIm2DVertexSetU(&maVertices[2], 1.0f, recipz);
- RwIm2DVertexSetV(&maVertices[2], 1.0f, recipz);
+ RwIm2DVertexSetU(&maVertices[2], 1.0f, RecipNearClip);
+ RwIm2DVertexSetV(&maVertices[2], 1.0f, RecipNearClip);
RwIm2DVertexSetScreenX(&maVertices[3], x1);
RwIm2DVertexSetScreenY(&maVertices[3], y1);
- RwIm2DVertexSetScreenZ(&maVertices[3], screenz);
- RwIm2DVertexSetCameraZ(&maVertices[3], z);
- RwIm2DVertexSetRecipCameraZ(&maVertices[3], recipz);
+ RwIm2DVertexSetScreenZ(&maVertices[3], NearScreenZ);
+ RwIm2DVertexSetCameraZ(&maVertices[3], NearCamZ);
+ RwIm2DVertexSetRecipCameraZ(&maVertices[3], RecipNearClip);
RwIm2DVertexSetIntRGBA(&maVertices[3], c0.r, c0.g, c0.b, c0.a);
- RwIm2DVertexSetU(&maVertices[3], 0.0f, recipz);
- RwIm2DVertexSetV(&maVertices[3], 1.0f, recipz);
+ RwIm2DVertexSetU(&maVertices[3], 0.0f, RecipNearClip);
+ RwIm2DVertexSetV(&maVertices[3], 1.0f, RecipNearClip);
}
void
CSprite2d::SetVertices(int n, float *positions, float *uvs, const CRGBA &col)
{
int i;
- float screenz, recipz, z;
-
- screenz = RwIm2DGetNearScreenZ();
- recipz = RecipNearClip;
- z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
-
for(i = 0; i < n; i++){
RwIm2DVertexSetScreenX(&maVertices[i], positions[i*2 + 0]);
RwIm2DVertexSetScreenY(&maVertices[i], positions[i*2 + 1]);
- RwIm2DVertexSetScreenZ(&maVertices[i], screenz + 0.0001f);
- RwIm2DVertexSetCameraZ(&maVertices[i], z);
- RwIm2DVertexSetRecipCameraZ(&maVertices[i], recipz);
+ RwIm2DVertexSetScreenZ(&maVertices[i], NearScreenZ + 0.0001f);
+ RwIm2DVertexSetCameraZ(&maVertices[i], NearCamZ);
+ RwIm2DVertexSetRecipCameraZ(&maVertices[i], RecipNearClip);
RwIm2DVertexSetIntRGBA(&maVertices[i], col.r, col.g, col.b, col.a);
- RwIm2DVertexSetU(&maVertices[i], uvs[i*2 + 0], recipz);
- RwIm2DVertexSetV(&maVertices[i], uvs[i*2 + 1], recipz);
+ RwIm2DVertexSetU(&maVertices[i], uvs[i*2 + 0], RecipNearClip);
+ RwIm2DVertexSetV(&maVertices[i], uvs[i*2 + 1], RecipNearClip);
}
}
@@ -346,18 +270,13 @@ void
CSprite2d::SetMaskVertices(int n, float *positions)
{
int i;
- float screenz, recipz, z;
-
- screenz = RwIm2DGetNearScreenZ();
- recipz = RecipNearClip;
- z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
for(i = 0; i < n; i++){
RwIm2DVertexSetScreenX(&maVertices[i], positions[i*2 + 0]);
RwIm2DVertexSetScreenY(&maVertices[i], positions[i*2 + 1]);
- RwIm2DVertexSetScreenZ(&maVertices[i], screenz);
- RwIm2DVertexSetCameraZ(&maVertices[i], z);
- RwIm2DVertexSetRecipCameraZ(&maVertices[i], recipz);
+ RwIm2DVertexSetScreenZ(&maVertices[i], NearScreenZ);
+ RwIm2DVertexSetCameraZ(&maVertices[i], NearCamZ);
+ RwIm2DVertexSetRecipCameraZ(&maVertices[i], RecipNearClip);
#if !defined(GTA_PS2_STUFF) && defined(RWLIBS)
RwIm2DVertexSetIntRGBA(&maVertices[i], 0, 0, 0, 0);
#else
@@ -370,72 +289,47 @@ void
CSprite2d::SetVertices(RwIm2DVertex *verts, const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3,
float u0, float v0, float u1, float v1, float u3, float v3, float u2, float v2)
{
- float screenz, recipz, z;
-
- screenz = RwIm2DGetNearScreenZ();
- recipz = RecipNearClip;
- z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
-
RwIm2DVertexSetScreenX(&verts[0], r.left);
RwIm2DVertexSetScreenY(&verts[0], r.top);
- RwIm2DVertexSetScreenZ(&verts[0], screenz);
- RwIm2DVertexSetCameraZ(&verts[0], z);
- RwIm2DVertexSetRecipCameraZ(&verts[0], recipz);
+ RwIm2DVertexSetScreenZ(&verts[0], NearScreenZ);
+ RwIm2DVertexSetCameraZ(&verts[0], NearCamZ);
+ RwIm2DVertexSetRecipCameraZ(&verts[0], RecipNearClip);
RwIm2DVertexSetIntRGBA(&verts[0], c2.r, c2.g, c2.b, c2.a);
- RwIm2DVertexSetU(&verts[0], u0, recipz);
- RwIm2DVertexSetV(&verts[0], v0, recipz);
-
- RwIm2DVertexSetScreenX(&verts[1], r.left);
- RwIm2DVertexSetScreenY(&verts[1], r.bottom);
- RwIm2DVertexSetScreenZ(&verts[1], screenz);
- RwIm2DVertexSetCameraZ(&verts[1], z);
- RwIm2DVertexSetRecipCameraZ(&verts[1], recipz);
- RwIm2DVertexSetIntRGBA(&verts[1], c0.r, c0.g, c0.b, c0.a);
- RwIm2DVertexSetU(&verts[1], u2, recipz);
- RwIm2DVertexSetV(&verts[1], v2, recipz);
+ RwIm2DVertexSetU(&verts[0], u0, RecipNearClip);
+ RwIm2DVertexSetV(&verts[0], v0, RecipNearClip);
+
+ RwIm2DVertexSetScreenX(&verts[1], r.right);
+ RwIm2DVertexSetScreenY(&verts[1], r.top);
+ RwIm2DVertexSetScreenZ(&verts[1], NearScreenZ);
+ RwIm2DVertexSetCameraZ(&verts[1], NearCamZ);
+ RwIm2DVertexSetRecipCameraZ(&verts[1], RecipNearClip);
+ RwIm2DVertexSetIntRGBA(&verts[1], c3.r, c3.g, c3.b, c3.a);
+ RwIm2DVertexSetU(&verts[1], u1, RecipNearClip);
+ RwIm2DVertexSetV(&verts[1], v1, RecipNearClip);
RwIm2DVertexSetScreenX(&verts[2], r.right);
RwIm2DVertexSetScreenY(&verts[2], r.bottom);
- RwIm2DVertexSetScreenZ(&verts[2], screenz);
- RwIm2DVertexSetCameraZ(&verts[2], z);
- RwIm2DVertexSetRecipCameraZ(&verts[2], recipz);
+ RwIm2DVertexSetScreenZ(&verts[2], NearScreenZ);
+ RwIm2DVertexSetCameraZ(&verts[2], NearCamZ);
+ RwIm2DVertexSetRecipCameraZ(&verts[2], RecipNearClip);
RwIm2DVertexSetIntRGBA(&verts[2], c1.r, c1.g, c1.b, c1.a);
- RwIm2DVertexSetU(&verts[2], u3, recipz);
- RwIm2DVertexSetV(&verts[2], v3, recipz);
+ RwIm2DVertexSetU(&verts[2], u2, RecipNearClip);
+ RwIm2DVertexSetV(&verts[2], v2, RecipNearClip);
RwIm2DVertexSetScreenX(&verts[3], r.left);
- RwIm2DVertexSetScreenY(&verts[3], r.top);
- RwIm2DVertexSetScreenZ(&verts[3], screenz);
- RwIm2DVertexSetCameraZ(&verts[3], z);
- RwIm2DVertexSetRecipCameraZ(&verts[3], recipz);
- RwIm2DVertexSetIntRGBA(&verts[3], c2.r, c2.g, c2.b, c2.a);
- RwIm2DVertexSetU(&verts[3], u0, recipz);
- RwIm2DVertexSetV(&verts[3], v0, recipz);
-
- RwIm2DVertexSetScreenX(&verts[4], r.right);
- RwIm2DVertexSetScreenY(&verts[4], r.bottom);
- RwIm2DVertexSetScreenZ(&verts[4], screenz);
- RwIm2DVertexSetCameraZ(&verts[4], z);
- RwIm2DVertexSetRecipCameraZ(&verts[4], recipz);
- RwIm2DVertexSetIntRGBA(&verts[4], c1.r, c1.g, c1.b, c1.a);
- RwIm2DVertexSetU(&verts[4], u3, recipz);
- RwIm2DVertexSetV(&verts[4], v3, recipz);
-
- RwIm2DVertexSetScreenX(&verts[5], r.right);
- RwIm2DVertexSetScreenY(&verts[5], r.top);
- RwIm2DVertexSetScreenZ(&verts[5], screenz);
- RwIm2DVertexSetCameraZ(&verts[5], z);
- RwIm2DVertexSetRecipCameraZ(&verts[5], recipz);
- RwIm2DVertexSetIntRGBA(&verts[5], c3.r, c3.g, c3.b, c3.a);
- RwIm2DVertexSetU(&verts[5], u1, recipz);
- RwIm2DVertexSetV(&verts[5], v1, recipz);
-
+ RwIm2DVertexSetScreenY(&verts[3], r.bottom);
+ RwIm2DVertexSetScreenZ(&verts[3], NearScreenZ);
+ RwIm2DVertexSetCameraZ(&verts[3], NearCamZ);
+ RwIm2DVertexSetRecipCameraZ(&verts[3], RecipNearClip);
+ RwIm2DVertexSetIntRGBA(&verts[3], c0.r, c0.g, c0.b, c0.a);
+ RwIm2DVertexSetU(&verts[3], u3, RecipNearClip);
+ RwIm2DVertexSetV(&verts[3], v3, RecipNearClip);
}
void
CSprite2d::DrawRect(const CRect &r, const CRGBA &col)
{
- SetVertices(r, col, col, col, col, false);
+ SetVertices(r, col, col, col, col);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEFLAT);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
@@ -450,7 +344,7 @@ CSprite2d::DrawRect(const CRect &r, const CRGBA &col)
void
CSprite2d::DrawRect(const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3)
{
- SetVertices(r, c0, c1, c2, c3, false);
+ SetVertices(r, c0, c1, c2, c3);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
@@ -463,7 +357,7 @@ CSprite2d::DrawRect(const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGB
void
CSprite2d::DrawRectXLU(const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3)
{
- SetVertices(r, c0, c1, c2, c3, false);
+ SetVertices(r, c0, c1, c2, c3);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
@@ -475,6 +369,22 @@ CSprite2d::DrawRectXLU(const CRect &r, const CRGBA &c0, const CRGBA &c1, const C
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
}
+void
+CSprite2d::DrawAnyRect(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4,
+ const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3)
+{
+ SetVertices(x1, y1, x2, y2, x3, y3, x4, y4, c0, c1, c2, c3);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
+ RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEGOURAUD);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)(c0.alpha != 255 || c1.alpha != 255 || c2.alpha != 255 || c3.alpha != 255));
+ RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::maVertices, 4);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEGOURAUD);
+}
+
void CSprite2d::Draw2DPolygon(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, const CRGBA &color)
{
SetVertices(x1, y1, x2, y2, x3, y3, x4, y4, color, color, color, color);
@@ -488,3 +398,37 @@ void CSprite2d::Draw2DPolygon(float x1, float y1, float x2, float y2, float x3,
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEGOURAUD);
}
+
+void
+CSprite2d::AddToBuffer(const CRect &r, const CRGBA &c, float u0, float v0, float u1, float v1, float u3, float v3, float u2, float v2)
+{
+ SetVertices(&TempVertexBuffer.im2d[nextBufferVertex], r, c, c, c, c, u0, v0, u1, v1, u3, v3, u2, v2);
+ RwImVertexIndex *pIndexList = &TempBufferRenderIndexList[nextBufferIndex];
+ pIndexList[0] = nextBufferVertex;
+ pIndexList[1] = nextBufferVertex + 1;
+ pIndexList[2] = nextBufferVertex + 2;
+ pIndexList[3] = nextBufferVertex + 3;
+ pIndexList[4] = nextBufferVertex;
+ pIndexList[5] = nextBufferVertex + 2;
+ nextBufferIndex += 6;
+ nextBufferVertex += 4;
+ if (IsVertexBufferFull())
+ RenderVertexBuffer();
+}
+
+bool
+CSprite2d::IsVertexBufferFull()
+{
+ return (nextBufferVertex > TEMPBUFFERVERTSIZE-128-4 || nextBufferIndex > ARRAY_SIZE(TempBufferRenderIndexList)-6);
+}
+
+void
+CSprite2d::RenderVertexBuffer()
+{
+ if (nextBufferVertex > 0) {
+ RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR);
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TempVertexBuffer.im2d, nextBufferVertex, TempBufferRenderIndexList, nextBufferIndex);
+ nextBufferVertex = 0;
+ nextBufferIndex = 0;
+ }
+} \ No newline at end of file
diff --git a/src/renderer/Sprite2d.h b/src/renderer/Sprite2d.h
index 0e12d441..5abd8d71 100644
--- a/src/renderer/Sprite2d.h
+++ b/src/renderer/Sprite2d.h
@@ -3,21 +3,16 @@
class CSprite2d
{
static float RecipNearClip;
- static int32 mCurrentBank;
- static RwTexture *mpBankTextures[10];
- static int32 mCurrentSprite[10];
- static int32 mBankStart[10];
- static RwIm2DVertex maBankVertices[500];
+ static float NearScreenZ;
+ static float NearCamZ; // not original
+ static int nextBufferVertex;
+ static int nextBufferIndex;
static RwIm2DVertex maVertices[8];
public:
RwTexture *m_pTexture;
static void SetRecipNearClip(void);
static void InitPerFrame(void);
- static int32 GetBank(int32 n, RwTexture *tex);
- static void AddSpriteToBank(int32 bank, const CRect &rect, const CRGBA &col,
- float u0, float v0, float u1, float v1, float u3, float v3, float u2, float v2);
- static void DrawBank(int32 bank);
CSprite2d(void) : m_pTexture(nil) {};
~CSprite2d(void) { Delete(); };
@@ -33,7 +28,7 @@ public:
void Draw(const CRect &rect, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3);
void Draw(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, const CRGBA &col);
- static void SetVertices(const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3, uint32 far);
+ static void SetVertices(const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3);
static void SetVertices(const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3,
float u0, float v0, float u1, float v1, float u3, float v3, float u2, float v2);
static void SetVertices(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4,
@@ -46,8 +41,14 @@ public:
static void DrawRect(const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3);
static void DrawRect(const CRect &r, const CRGBA &col);
static void DrawRectXLU(const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3);
+ static void DrawAnyRect(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4,
+ const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3);
static void Draw2DPolygon(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, const CRGBA &color);
static RwIm2DVertex* GetVertices() { return maVertices; };
+
+ static bool IsVertexBufferFull();
+ static void AddToBuffer(const CRect &a1, const CRGBA &a2, float a3, float a4, float a5, float a6, float a7, float a8, float a9, float a10);
+ static void RenderVertexBuffer();
};
diff --git a/src/renderer/Timecycle.cpp b/src/renderer/Timecycle.cpp
index 0d94dbd6..95d9fe3c 100644
--- a/src/renderer/Timecycle.cpp
+++ b/src/renderer/Timecycle.cpp
@@ -10,50 +10,72 @@
#include "FileMgr.h"
#include "Timecycle.h"
-int32 CTimeCycle::m_nAmbientRed[NUMHOURS][NUMWEATHERS];
-int32 CTimeCycle::m_nAmbientGreen[NUMHOURS][NUMWEATHERS];
-int32 CTimeCycle::m_nAmbientBlue[NUMHOURS][NUMWEATHERS];
-int32 CTimeCycle::m_nDirectionalRed[NUMHOURS][NUMWEATHERS];
-int32 CTimeCycle::m_nDirectionalGreen[NUMHOURS][NUMWEATHERS];
-int32 CTimeCycle::m_nDirectionalBlue[NUMHOURS][NUMWEATHERS];
-int32 CTimeCycle::m_nSkyTopRed[NUMHOURS][NUMWEATHERS];
-int32 CTimeCycle::m_nSkyTopGreen[NUMHOURS][NUMWEATHERS];
-int32 CTimeCycle::m_nSkyTopBlue[NUMHOURS][NUMWEATHERS];
-int32 CTimeCycle::m_nSkyBottomRed[NUMHOURS][NUMWEATHERS];
-int32 CTimeCycle::m_nSkyBottomGreen[NUMHOURS][NUMWEATHERS];
-int32 CTimeCycle::m_nSkyBottomBlue[NUMHOURS][NUMWEATHERS];
-int32 CTimeCycle::m_nSunCoreRed[NUMHOURS][NUMWEATHERS];
-int32 CTimeCycle::m_nSunCoreGreen[NUMHOURS][NUMWEATHERS];
-int32 CTimeCycle::m_nSunCoreBlue[NUMHOURS][NUMWEATHERS];
-int32 CTimeCycle::m_nSunCoronaRed[NUMHOURS][NUMWEATHERS];
-int32 CTimeCycle::m_nSunCoronaGreen[NUMHOURS][NUMWEATHERS];
-int32 CTimeCycle::m_nSunCoronaBlue[NUMHOURS][NUMWEATHERS];
-float CTimeCycle::m_fSunSize[NUMHOURS][NUMWEATHERS];
-float CTimeCycle::m_fSpriteSize[NUMHOURS][NUMWEATHERS];
-float CTimeCycle::m_fSpriteBrightness[NUMHOURS][NUMWEATHERS];
-int16 CTimeCycle::m_nShadowStrength[NUMHOURS][NUMWEATHERS];
-int16 CTimeCycle::m_nLightShadowStrength[NUMHOURS][NUMWEATHERS];
-int16 CTimeCycle::m_nTreeShadowStrength[NUMHOURS][NUMWEATHERS];
-float CTimeCycle::m_fFogStart[NUMHOURS][NUMWEATHERS];
-float CTimeCycle::m_fFarClip[NUMHOURS][NUMWEATHERS];
-float CTimeCycle::m_fLightsOnGroundBrightness[NUMHOURS][NUMWEATHERS];
-int32 CTimeCycle::m_nLowCloudsRed[NUMHOURS][NUMWEATHERS];
-int32 CTimeCycle::m_nLowCloudsGreen[NUMHOURS][NUMWEATHERS];
-int32 CTimeCycle::m_nLowCloudsBlue[NUMHOURS][NUMWEATHERS];
-int32 CTimeCycle::m_nFluffyCloudsTopRed[NUMHOURS][NUMWEATHERS];
-int32 CTimeCycle::m_nFluffyCloudsTopGreen[NUMHOURS][NUMWEATHERS];
-int32 CTimeCycle::m_nFluffyCloudsTopBlue[NUMHOURS][NUMWEATHERS];
-int32 CTimeCycle::m_nFluffyCloudsBottomRed[NUMHOURS][NUMWEATHERS];
-int32 CTimeCycle::m_nFluffyCloudsBottomGreen[NUMHOURS][NUMWEATHERS];
-int32 CTimeCycle::m_nFluffyCloudsBottomBlue[NUMHOURS][NUMWEATHERS];
-float CTimeCycle::m_fBlurRed[NUMHOURS][NUMWEATHERS];
-float CTimeCycle::m_fBlurGreen[NUMHOURS][NUMWEATHERS];
-float CTimeCycle::m_fBlurBlue[NUMHOURS][NUMWEATHERS];
-float CTimeCycle::m_fBlurAlpha[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nAmbientRed[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nAmbientGreen[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nAmbientBlue[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nAmbientRed_Obj[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nAmbientGreen_Obj[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nAmbientBlue_Obj[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nAmbientRed_Bl[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nAmbientGreen_Bl[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nAmbientBlue_Bl[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nAmbientRed_Obj_Bl[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nAmbientGreen_Obj_Bl[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nAmbientBlue_Obj_Bl[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nDirectionalRed[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nDirectionalGreen[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nDirectionalBlue[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nSkyTopRed[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nSkyTopGreen[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nSkyTopBlue[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nSkyBottomRed[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nSkyBottomGreen[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nSkyBottomBlue[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nSunCoreRed[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nSunCoreGreen[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nSunCoreBlue[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nSunCoronaRed[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nSunCoronaGreen[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nSunCoronaBlue[NUMHOURS][NUMWEATHERS];
+int8 CTimeCycle::m_fSunSize[NUMHOURS][NUMWEATHERS];
+int8 CTimeCycle::m_fSpriteSize[NUMHOURS][NUMWEATHERS];
+int8 CTimeCycle::m_fSpriteBrightness[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nShadowStrength[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nLightShadowStrength[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nPoleShadowStrength[NUMHOURS][NUMWEATHERS];
+int16 CTimeCycle::m_fFogStart[NUMHOURS][NUMWEATHERS];
+int16 CTimeCycle::m_fFarClip[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_fLightsOnGroundBrightness[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nLowCloudsRed[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nLowCloudsGreen[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nLowCloudsBlue[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nFluffyCloudsTopRed[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nFluffyCloudsTopGreen[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nFluffyCloudsTopBlue[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nFluffyCloudsBottomRed[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nFluffyCloudsBottomGreen[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_nFluffyCloudsBottomBlue[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_fBlurRed[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_fBlurGreen[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_fBlurBlue[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_fWaterRed[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_fWaterGreen[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_fWaterBlue[NUMHOURS][NUMWEATHERS];
+uint8 CTimeCycle::m_fWaterAlpha[NUMHOURS][NUMWEATHERS];
+
float CTimeCycle::m_fCurrentAmbientRed;
float CTimeCycle::m_fCurrentAmbientGreen;
float CTimeCycle::m_fCurrentAmbientBlue;
+float CTimeCycle::m_fCurrentAmbientRed_Obj;
+float CTimeCycle::m_fCurrentAmbientGreen_Obj;
+float CTimeCycle::m_fCurrentAmbientBlue_Obj;
+float CTimeCycle::m_fCurrentAmbientRed_Bl;
+float CTimeCycle::m_fCurrentAmbientGreen_Bl;
+float CTimeCycle::m_fCurrentAmbientBlue_Bl;
+float CTimeCycle::m_fCurrentAmbientRed_Obj_Bl;
+float CTimeCycle::m_fCurrentAmbientGreen_Obj_Bl;
+float CTimeCycle::m_fCurrentAmbientBlue_Obj_Bl;
float CTimeCycle::m_fCurrentDirectionalRed;
float CTimeCycle::m_fCurrentDirectionalGreen;
float CTimeCycle::m_fCurrentDirectionalBlue;
@@ -74,7 +96,7 @@ float CTimeCycle::m_fCurrentSpriteSize;
float CTimeCycle::m_fCurrentSpriteBrightness;
int32 CTimeCycle::m_nCurrentShadowStrength;
int32 CTimeCycle::m_nCurrentLightShadowStrength;
-int32 CTimeCycle::m_nCurrentTreeShadowStrength;
+int32 CTimeCycle::m_nCurrentPoleShadowStrength;
float CTimeCycle::m_fCurrentFogStart;
float CTimeCycle::m_fCurrentFarClip;
float CTimeCycle::m_fCurrentLightsOnGroundBrightness;
@@ -90,12 +112,18 @@ int32 CTimeCycle::m_nCurrentFluffyCloudsBottomBlue;
float CTimeCycle::m_fCurrentBlurRed;
float CTimeCycle::m_fCurrentBlurGreen;
float CTimeCycle::m_fCurrentBlurBlue;
-float CTimeCycle::m_fCurrentBlurAlpha;
+float CTimeCycle::m_fCurrentWaterRed;
+float CTimeCycle::m_fCurrentWaterGreen;
+float CTimeCycle::m_fCurrentWaterBlue;
+float CTimeCycle::m_fCurrentWaterAlpha;
int32 CTimeCycle::m_nCurrentFogColourRed;
int32 CTimeCycle::m_nCurrentFogColourGreen;
int32 CTimeCycle::m_nCurrentFogColourBlue;
int32 CTimeCycle::m_FogReduction;
+int32 CTimeCycle::m_bExtraColourOn;
+int32 CTimeCycle::m_ExtraColour;
+float CTimeCycle::m_ExtraColourInter;
int32 CTimeCycle::m_CurrentStoredValue;
CVector CTimeCycle::m_VectorToSun[16];
@@ -106,7 +134,6 @@ float CTimeCycle::m_fShadowSideY[16];
float CTimeCycle::m_fShadowDisplacementX[16];
float CTimeCycle::m_fShadowDisplacementY[16];
-
void
CTimeCycle::Initialise(void)
{
@@ -115,18 +142,22 @@ CTimeCycle::Initialise(void)
char line[1040];
int ambR, ambG, ambB;
+ int ambobjR, ambobjG, ambobjB;
+ int ambblR, ambblG, ambblB;
+ int ambobjblR, ambobjblG, ambobjblB;
int dirR, dirG, dirB;
int skyTopR, skyTopG, skyTopB;
int skyBotR, skyBotG, skyBotB;
int sunCoreR, sunCoreG, sunCoreB;
int sunCoronaR, sunCoronaG, sunCoronaB;
float sunSz, sprSz, sprBght;
- int shad, lightShad, treeShad;
+ int shad, lightShad, poleShad;
float farClp, fogSt, lightGnd;
int cloudR, cloudG, cloudB;
int fluffyTopR, fluffyTopG, fluffyTopB;
int fluffyBotR, fluffyBotG, fluffyBotB;
- float blurR, blurG, blurB, blurA;
+ float blurR, blurG, blurB;
+ float waterR, waterG, waterB, waterA;
debug("Intialising CTimeCycle...\n");
@@ -139,36 +170,55 @@ CTimeCycle::Initialise(void)
for(w = 0; w < NUMWEATHERS; w++)
for(h = 0; h < NUMHOURS; h++){
li = 0;
- while(work_buff[bi] == '/'){
- while(work_buff[bi] != '\n')
+ while(work_buff[bi] == '/' || work_buff[bi] == '\n' ||
+ work_buff[bi] == '\0' || work_buff[bi] == ' ' || work_buff[bi] == '\r'){
+ while(work_buff[bi] != '\n' && work_buff[bi] != '\0' && work_buff[bi] != '\r')
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++;
sscanf(line, "%d %d %d %d %d %d %d %d %d %d %d %d "
+ "%d %d %d %d %d %d %d %d %d "
"%d %d %d %d %d %d %f %f %f %d %d %d %f %f %f "
- "%d %d %d %d %d %d %d %d %d %f %f %f %f",
+ "%d %d %d %d %d %d %d %d %d %f %f %f %f %f %f %f",
&ambR, &ambG, &ambB,
- &dirR, &dirG, &dirB,
+ &ambobjR, &ambobjG, &ambobjB,
+ &ambblR, &ambblG, &ambblB,
+ &ambobjblR, &ambobjblG, &ambobjblB,
+ &dirR, &dirG, &dirB,
&skyTopR, &skyTopG, &skyTopB,
&skyBotR, &skyBotG, &skyBotB,
&sunCoreR, &sunCoreG, &sunCoreB,
&sunCoronaR, &sunCoronaG, &sunCoronaB,
&sunSz, &sprSz, &sprBght,
- &shad, &lightShad, &treeShad,
+ &shad, &lightShad, &poleShad,
&farClp, &fogSt, &lightGnd,
&cloudR, &cloudG, &cloudB,
&fluffyTopR, &fluffyTopG, &fluffyTopB,
&fluffyBotR, &fluffyBotG, &fluffyBotB,
- &blurR, &blurG, &blurB, &blurA);
+ &blurR, &blurG, &blurB,
+ &waterR, &waterG, &waterB, &waterA);
m_nAmbientRed[h][w] = ambR;
m_nAmbientGreen[h][w] = ambG;
m_nAmbientBlue[h][w] = ambB;
+ m_nAmbientRed_Obj[h][w] = ambobjR;
+ m_nAmbientGreen_Obj[h][w] = ambobjG;
+ m_nAmbientBlue_Obj[h][w] = ambobjB;
+ m_nAmbientRed_Bl[h][w] = ambblR;
+ m_nAmbientGreen_Bl[h][w] = ambblG;
+ m_nAmbientBlue_Bl[h][w] = ambblB;
+ m_nAmbientRed_Obj_Bl[h][w] = ambobjblR;
+ m_nAmbientGreen_Obj_Bl[h][w] = ambobjblG;
+ m_nAmbientBlue_Obj_Bl[h][w] = ambobjblB;
m_nDirectionalRed[h][w] = dirR;
m_nDirectionalGreen[h][w] = dirG;
m_nDirectionalBlue[h][w] = dirB;
@@ -184,15 +234,15 @@ CTimeCycle::Initialise(void)
m_nSunCoronaRed[h][w] = sunCoronaR;
m_nSunCoronaGreen[h][w] = sunCoronaG;
m_nSunCoronaBlue[h][w] = sunCoronaB;
- m_fSunSize[h][w] = sunSz;
- m_fSpriteSize[h][w] = sprSz;
- m_fSpriteBrightness[h][w] = sprBght;
+ m_fSunSize[h][w] = sunSz * 10.0f;
+ m_fSpriteSize[h][w] = sprSz * 10.0f;
+ m_fSpriteBrightness[h][w] = sprBght * 10.0f;
m_nShadowStrength[h][w] = shad;
m_nLightShadowStrength[h][w] = lightShad;
- m_nTreeShadowStrength[h][w] = treeShad;
+ m_nPoleShadowStrength[h][w] = poleShad;
m_fFarClip[h][w] = farClp;
m_fFogStart[h][w] = fogSt;
- m_fLightsOnGroundBrightness[h][w] = lightGnd;
+ m_fLightsOnGroundBrightness[h][w] = lightGnd * 10.0f;
m_nLowCloudsRed[h][w] = cloudR;
m_nLowCloudsGreen[h][w] = cloudG;
m_nLowCloudsBlue[h][w] = cloudB;
@@ -205,7 +255,10 @@ CTimeCycle::Initialise(void)
m_fBlurRed[h][w] = blurR;
m_fBlurGreen[h][w] = blurG;
m_fBlurBlue[h][w] = blurB;
- m_fBlurAlpha[h][w] = blurA;
+ m_fWaterRed[h][w] = waterR;
+ m_fWaterGreen[h][w] = waterG;
+ m_fWaterBlue[h][w] = waterB;
+ m_fWaterAlpha[h][w] = waterA;
}
m_FogReduction = 0;
@@ -213,6 +266,51 @@ CTimeCycle::Initialise(void)
debug("CTimeCycle ready\n");
}
+static float interp_c0, interp_c1, interp_c2, interp_c3;
+
+float CTimeCycle::Interpolate(int8 *a, int8 *b)
+{
+ return a[CWeather::OldWeatherType] * interp_c0 +
+ b[CWeather::OldWeatherType] * interp_c1 +
+ a[CWeather::NewWeatherType] * interp_c2 +
+ b[CWeather::NewWeatherType] * interp_c3;
+}
+
+float CTimeCycle::Interpolate(uint8 *a, uint8 *b)
+{
+ return a[CWeather::OldWeatherType] * interp_c0 +
+ b[CWeather::OldWeatherType] * interp_c1 +
+ a[CWeather::NewWeatherType] * interp_c2 +
+ b[CWeather::NewWeatherType] * interp_c3;
+}
+
+float CTimeCycle::Interpolate(int16 *a, int16 *b)
+{
+ return a[CWeather::OldWeatherType] * interp_c0 +
+ b[CWeather::OldWeatherType] * interp_c1 +
+ a[CWeather::NewWeatherType] * interp_c2 +
+ b[CWeather::NewWeatherType] * interp_c3;
+}
+
+void
+CTimeCycle::StartExtraColour(int32 c, bool fade)
+{
+ m_bExtraColourOn = true;
+ m_ExtraColour = c;
+ if(fade)
+ m_ExtraColourInter = 0.0f;
+ else
+ m_ExtraColourInter = 1.0f;
+}
+
+void
+CTimeCycle::StopExtraColour(bool fade)
+{
+ m_bExtraColourOn = false;
+ if(!fade)
+ m_ExtraColourInter = 0.0f;
+}
+
void
CTimeCycle::Update(void)
{
@@ -220,14 +318,14 @@ CTimeCycle::Update(void)
int h2 = (h1+1)%24;
int w1 = CWeather::OldWeatherType;
int w2 = CWeather::NewWeatherType;
- float timeInterp = CClock::GetMinutes()/60.0f;
+ float timeInterp = (CClock::GetMinutes() + CClock::GetSeconds()/60.0f)/60.0f;
// coefficients for a bilinear interpolation
- float c0 = (1.0f-timeInterp) * (1.0f-CWeather::InterpolationValue);
- float c1 = timeInterp * (1.0f-CWeather::InterpolationValue);
- float c2 = (1.0f-timeInterp) * CWeather::InterpolationValue;
- float c3 = timeInterp * CWeather::InterpolationValue;
+ interp_c0 = (1.0f-timeInterp) * (1.0f-CWeather::InterpolationValue);
+ interp_c1 = timeInterp * (1.0f-CWeather::InterpolationValue);
+ interp_c2 = (1.0f-timeInterp) * CWeather::InterpolationValue;
+ interp_c3 = timeInterp * CWeather::InterpolationValue;
-#define INTERP(v) v[h1][w1]*c0 + v[h2][w1]*c1 + v[h1][w2]*c2 + v[h2][w2]*c3
+#define INTERP(v) Interpolate(v[h1], v[h2])
m_nCurrentSkyTopRed = INTERP(m_nSkyTopRed);
m_nCurrentSkyTopGreen = INTERP(m_nSkyTopGreen);
@@ -240,16 +338,22 @@ CTimeCycle::Update(void)
m_fCurrentAmbientRed = INTERP(m_nAmbientRed);
m_fCurrentAmbientGreen = INTERP(m_nAmbientGreen);
m_fCurrentAmbientBlue = INTERP(m_nAmbientBlue);
- m_fCurrentAmbientRed /= 255.0f;
- m_fCurrentAmbientGreen /= 255.0f;
- m_fCurrentAmbientBlue /= 255.0f;
+
+ m_fCurrentAmbientRed_Obj = INTERP(m_nAmbientRed_Obj);
+ m_fCurrentAmbientGreen_Obj = INTERP(m_nAmbientGreen_Obj);
+ m_fCurrentAmbientBlue_Obj = INTERP(m_nAmbientBlue_Obj);
+
+ m_fCurrentAmbientRed_Bl = INTERP(m_nAmbientRed_Bl);
+ m_fCurrentAmbientGreen_Bl = INTERP(m_nAmbientGreen_Bl);
+ m_fCurrentAmbientBlue_Bl = INTERP(m_nAmbientBlue_Bl);
+
+ m_fCurrentAmbientRed_Obj_Bl = INTERP(m_nAmbientRed_Obj_Bl);
+ m_fCurrentAmbientGreen_Obj_Bl = INTERP(m_nAmbientGreen_Obj_Bl);
+ m_fCurrentAmbientBlue_Obj_Bl = INTERP(m_nAmbientBlue_Obj_Bl);
m_fCurrentDirectionalRed = INTERP(m_nDirectionalRed);
m_fCurrentDirectionalGreen = INTERP(m_nDirectionalGreen);
m_fCurrentDirectionalBlue = INTERP(m_nDirectionalBlue);
- m_fCurrentDirectionalRed /= 255.0f;
- m_fCurrentDirectionalGreen /= 255.0f;
- m_fCurrentDirectionalBlue /= 255.0f;
m_nCurrentSunCoreRed = INTERP(m_nSunCoreRed);
m_nCurrentSunCoreGreen = INTERP(m_nSunCoreGreen);
@@ -259,15 +363,15 @@ CTimeCycle::Update(void)
m_nCurrentSunCoronaGreen = INTERP(m_nSunCoronaGreen);
m_nCurrentSunCoronaBlue = INTERP(m_nSunCoronaBlue);
- m_fCurrentSunSize = INTERP(m_fSunSize);
- m_fCurrentSpriteSize = INTERP(m_fSpriteSize);
- m_fCurrentSpriteBrightness = INTERP(m_fSpriteBrightness);
+ m_fCurrentSunSize = INTERP(m_fSunSize)/10.0f;
+ m_fCurrentSpriteSize = INTERP(m_fSpriteSize)/10.0f;
+ m_fCurrentSpriteBrightness = INTERP(m_fSpriteBrightness)/10.0f;
m_nCurrentShadowStrength = INTERP(m_nShadowStrength);
m_nCurrentLightShadowStrength = INTERP(m_nLightShadowStrength);
- m_nCurrentTreeShadowStrength = INTERP(m_nTreeShadowStrength);
+ m_nCurrentPoleShadowStrength = INTERP(m_nPoleShadowStrength);
m_fCurrentFarClip = INTERP(m_fFarClip);
m_fCurrentFogStart = INTERP(m_fFogStart);
- m_fCurrentLightsOnGroundBrightness = INTERP(m_fLightsOnGroundBrightness);
+ m_fCurrentLightsOnGroundBrightness = INTERP(m_fLightsOnGroundBrightness)/10.0f;
m_nCurrentLowCloudsRed = INTERP(m_nLowCloudsRed);
m_nCurrentLowCloudsGreen = INTERP(m_nLowCloudsGreen);
@@ -284,26 +388,131 @@ CTimeCycle::Update(void)
m_fCurrentBlurRed = INTERP(m_fBlurRed);
m_fCurrentBlurGreen = INTERP(m_fBlurGreen);
m_fCurrentBlurBlue = INTERP(m_fBlurBlue);
- m_fCurrentBlurAlpha = INTERP(m_fBlurAlpha);
- if(TheCamera.m_BlurType == MOTION_BLUR_NONE || TheCamera.m_BlurType == MOTION_BLUR_LIGHT_SCENE)
- TheCamera.SetMotionBlur(m_fCurrentBlurRed, m_fCurrentBlurGreen, m_fCurrentBlurBlue, m_fCurrentBlurAlpha, MOTION_BLUR_LIGHT_SCENE);
+ m_fCurrentWaterRed = INTERP(m_fWaterRed);
+ m_fCurrentWaterGreen = INTERP(m_fWaterGreen);
+ m_fCurrentWaterBlue = INTERP(m_fWaterBlue);
+ m_fCurrentWaterAlpha = INTERP(m_fWaterAlpha);
+#undef INTERP
if(m_FogReduction != 0)
m_fCurrentFarClip = Max(m_fCurrentFarClip, m_FogReduction/64.0f * 650.0f);
- m_nCurrentFogColourRed = (m_nCurrentSkyTopRed + 2*m_nCurrentSkyBottomRed) / 3;
- m_nCurrentFogColourGreen = (m_nCurrentSkyTopGreen + 2*m_nCurrentSkyBottomGreen) / 3;
- m_nCurrentFogColourBlue = (m_nCurrentSkyTopBlue + 2*m_nCurrentSkyBottomBlue) / 3;
m_CurrentStoredValue = (m_CurrentStoredValue+1)&0xF;
- float sunAngle = 2*PI*(CClock::GetMinutes() + CClock::GetHours()*60)/(24*60);
+ float sunAngle = 2*PI*(CClock::GetSeconds()/60.0f + CClock::GetMinutes() + CClock::GetHours()*60)/(24*60);
CVector &sunPos = GetSunDirection();
sunPos.x = Sin(sunAngle);
sunPos.y = 1.0f;
sunPos.z = 0.2f - Cos(sunAngle);
sunPos.Normalise();
+ if(m_bExtraColourOn)
+ m_ExtraColourInter = Min(1.0f, m_ExtraColourInter + CTimer::GetTimeStep()/120.0f);
+ else
+ m_ExtraColourInter = Max(-.0f, m_ExtraColourInter - CTimer::GetTimeStep()/120.0f);
+ if(m_ExtraColourInter > 0.0f){
+#define INTERP(extra,cur) (m_ExtraColourInter*extra[m_ExtraColour][WEATHER_EXTRACOLOURS] + (1.0f-m_ExtraColourInter)*cur)
+#define INTERPscl(extra,scl,cur) (m_ExtraColourInter*extra[m_ExtraColour][WEATHER_EXTRACOLOURS]/scl + (1.0f-m_ExtraColourInter)*cur)
+ if(m_nSkyTopRed[m_ExtraColour][WEATHER_EXTRACOLOURS] != 0 ||
+ m_nSkyTopGreen[m_ExtraColour][WEATHER_EXTRACOLOURS] != 0 ||
+ m_nSkyTopBlue[m_ExtraColour][WEATHER_EXTRACOLOURS] != 0){
+ m_nCurrentSkyTopRed = INTERP(m_nSkyTopRed,m_nCurrentSkyTopRed);
+ m_nCurrentSkyTopGreen = INTERP(m_nSkyTopGreen,m_nCurrentSkyTopGreen);
+ m_nCurrentSkyTopBlue = INTERP(m_nSkyTopBlue,m_nCurrentSkyTopBlue);
+
+ m_nCurrentSkyBottomRed = INTERP(m_nSkyBottomRed,m_nCurrentSkyBottomRed);
+ m_nCurrentSkyBottomGreen = INTERP(m_nSkyBottomGreen,m_nCurrentSkyBottomGreen);
+ m_nCurrentSkyBottomBlue = INTERP(m_nSkyBottomBlue,m_nCurrentSkyBottomBlue);
+
+ m_nCurrentSunCoreRed = INTERP(m_nSunCoreRed,m_nCurrentSunCoreRed);
+ m_nCurrentSunCoreGreen = INTERP(m_nSunCoreGreen,m_nCurrentSunCoreGreen);
+ m_nCurrentSunCoreBlue = INTERP(m_nSunCoreBlue,m_nCurrentSunCoreBlue);
+
+ m_nCurrentSunCoronaRed = INTERP(m_nSunCoronaRed,m_nCurrentSunCoronaRed);
+ m_nCurrentSunCoronaGreen = INTERP(m_nSunCoronaGreen,m_nCurrentSunCoronaGreen);
+ m_nCurrentSunCoronaBlue = INTERP(m_nSunCoronaBlue,m_nCurrentSunCoronaBlue);
+
+ m_fCurrentSunSize = INTERPscl(m_fSunSize,10.0f,m_fCurrentSunSize);
+
+ m_nCurrentLowCloudsRed = INTERP(m_nLowCloudsRed,m_nCurrentLowCloudsRed);
+ m_nCurrentLowCloudsGreen = INTERP(m_nLowCloudsGreen,m_nCurrentLowCloudsGreen);
+ m_nCurrentLowCloudsBlue = INTERP(m_nLowCloudsBlue,m_nCurrentLowCloudsBlue);
+
+ m_nCurrentFluffyCloudsTopRed = INTERP(m_nFluffyCloudsTopRed,m_nCurrentFluffyCloudsTopRed);
+ m_nCurrentFluffyCloudsTopGreen = INTERP(m_nFluffyCloudsTopGreen,m_nCurrentFluffyCloudsTopGreen);
+ m_nCurrentFluffyCloudsTopBlue = INTERP(m_nFluffyCloudsTopBlue,m_nCurrentFluffyCloudsTopBlue);
+
+ m_nCurrentFluffyCloudsBottomRed = INTERP(m_nFluffyCloudsBottomRed,m_nCurrentFluffyCloudsBottomRed);
+ m_nCurrentFluffyCloudsBottomGreen = INTERP(m_nFluffyCloudsBottomGreen,m_nCurrentFluffyCloudsBottomGreen);
+ m_nCurrentFluffyCloudsBottomBlue = INTERP(m_nFluffyCloudsBottomBlue,m_nCurrentFluffyCloudsBottomBlue);
+
+ m_fCurrentWaterRed = INTERP(m_fWaterRed,m_fCurrentWaterRed);
+ m_fCurrentWaterGreen = INTERP(m_fWaterGreen,m_fCurrentWaterGreen);
+ m_fCurrentWaterBlue = INTERP(m_fWaterBlue,m_fCurrentWaterBlue);
+ m_fCurrentWaterAlpha = INTERP(m_fWaterAlpha,m_fCurrentWaterAlpha);
+ }
+
+ m_fCurrentAmbientRed = INTERP(m_nAmbientRed,m_fCurrentAmbientRed);
+ m_fCurrentAmbientGreen = INTERP(m_nAmbientGreen,m_fCurrentAmbientGreen);
+ m_fCurrentAmbientBlue = INTERP(m_nAmbientBlue,m_fCurrentAmbientBlue);
+
+ m_fCurrentAmbientRed_Obj = INTERP(m_nAmbientRed_Obj,m_fCurrentAmbientRed_Obj);
+ m_fCurrentAmbientGreen_Obj = INTERP(m_nAmbientGreen_Obj,m_fCurrentAmbientGreen_Obj);
+ m_fCurrentAmbientBlue_Obj = INTERP(m_nAmbientBlue_Obj,m_fCurrentAmbientBlue_Obj);
+
+ m_fCurrentAmbientRed_Bl = INTERP(m_nAmbientRed_Bl,m_fCurrentAmbientRed_Bl);
+ m_fCurrentAmbientGreen_Bl = INTERP(m_nAmbientGreen_Bl,m_fCurrentAmbientGreen_Bl);
+ m_fCurrentAmbientBlue_Bl = INTERP(m_nAmbientBlue_Bl,m_fCurrentAmbientBlue_Bl);
+
+ m_fCurrentAmbientRed_Obj_Bl = INTERP(m_nAmbientRed_Obj_Bl,m_fCurrentAmbientRed_Obj_Bl);
+ m_fCurrentAmbientGreen_Obj_Bl = INTERP(m_nAmbientGreen_Obj_Bl,m_fCurrentAmbientGreen_Obj_Bl);
+ m_fCurrentAmbientBlue_Obj_Bl = INTERP(m_nAmbientBlue_Obj_Bl,m_fCurrentAmbientBlue_Obj_Bl);
+
+ m_fCurrentDirectionalRed = INTERP(m_nDirectionalRed,m_fCurrentDirectionalRed);
+ m_fCurrentDirectionalGreen = INTERP(m_nDirectionalGreen,m_fCurrentDirectionalGreen);
+ m_fCurrentDirectionalBlue = INTERP(m_nDirectionalBlue,m_fCurrentDirectionalBlue);
+
+ m_fCurrentSpriteSize = INTERPscl(m_fSpriteSize,10.0f,m_fCurrentSpriteSize);
+ m_fCurrentSpriteBrightness = INTERPscl(m_fSpriteBrightness,10.0f,m_fCurrentSpriteBrightness);
+ m_nCurrentShadowStrength = INTERP(m_nShadowStrength,m_nCurrentShadowStrength);
+ m_nCurrentLightShadowStrength = INTERP(m_nLightShadowStrength,m_nCurrentLightShadowStrength);
+ m_nCurrentPoleShadowStrength = INTERP(m_nPoleShadowStrength,m_nCurrentPoleShadowStrength);
+ m_fCurrentFarClip = INTERP(m_fFarClip,m_fCurrentFarClip);
+ m_fCurrentFogStart = INTERP(m_fFogStart,m_fCurrentFogStart);
+ m_fCurrentLightsOnGroundBrightness = INTERPscl(m_fLightsOnGroundBrightness,10.0f,m_fCurrentLightsOnGroundBrightness);
+
+ m_fCurrentBlurRed = INTERP(m_fBlurRed,m_fCurrentBlurRed);
+ m_fCurrentBlurGreen = INTERP(m_fBlurGreen,m_fCurrentBlurGreen);
+ m_fCurrentBlurBlue = INTERP(m_fBlurBlue,m_fCurrentBlurBlue);
+
+#undef INTERP
+#undef INTERPscl
+ }
+
+ if(TheCamera.m_BlurType == MOTION_BLUR_NONE || TheCamera.m_BlurType == MOTION_BLUR_LIGHT_SCENE)
+ TheCamera.SetMotionBlur(m_fCurrentBlurRed, m_fCurrentBlurGreen, m_fCurrentBlurBlue, 5, MOTION_BLUR_LIGHT_SCENE);
+
+ m_nCurrentFogColourRed = (m_nCurrentSkyTopRed + 2*m_nCurrentSkyBottomRed) / 3;
+ m_nCurrentFogColourGreen = (m_nCurrentSkyTopGreen + 2*m_nCurrentSkyBottomGreen) / 3;
+ m_nCurrentFogColourBlue = (m_nCurrentSkyTopBlue + 2*m_nCurrentSkyBottomBlue) / 3;
+
+ m_fCurrentAmbientRed /= 255.0f;
+ m_fCurrentAmbientGreen /= 255.0f;
+ m_fCurrentAmbientBlue /= 255.0f;
+ m_fCurrentAmbientRed_Obj /= 255.0f;
+ m_fCurrentAmbientGreen_Obj /= 255.0f;
+ m_fCurrentAmbientBlue_Obj /= 255.0f;
+ m_fCurrentAmbientRed_Bl /= 255.0f;
+ m_fCurrentAmbientGreen_Bl /= 255.0f;
+ m_fCurrentAmbientBlue_Bl /= 255.0f;
+ m_fCurrentAmbientRed_Obj_Bl /= 255.0f;
+ m_fCurrentAmbientGreen_Obj_Bl /= 255.0f;
+ m_fCurrentAmbientBlue_Obj_Bl /= 255.0f;
+ m_fCurrentDirectionalRed /= 255.0f;
+ m_fCurrentDirectionalGreen /= 255.0f;
+ m_fCurrentDirectionalBlue /= 255.0f;
+
CShadows::CalcPedShadowValues(sunPos,
&m_fShadowFrontX[m_CurrentStoredValue], &m_fShadowFrontY[m_CurrentStoredValue],
&m_fShadowSideX[m_CurrentStoredValue], &m_fShadowSideY[m_CurrentStoredValue],
diff --git a/src/renderer/Timecycle.h b/src/renderer/Timecycle.h
index d5d7b67a..da911b75 100644
--- a/src/renderer/Timecycle.h
+++ b/src/renderer/Timecycle.h
@@ -2,50 +2,71 @@
class CTimeCycle
{
- static int32 m_nAmbientRed[NUMHOURS][NUMWEATHERS];
- static int32 m_nAmbientGreen[NUMHOURS][NUMWEATHERS];
- static int32 m_nAmbientBlue[NUMHOURS][NUMWEATHERS];
- static int32 m_nDirectionalRed[NUMHOURS][NUMWEATHERS];
- static int32 m_nDirectionalGreen[NUMHOURS][NUMWEATHERS];
- static int32 m_nDirectionalBlue[NUMHOURS][NUMWEATHERS];
- static int32 m_nSkyTopRed[NUMHOURS][NUMWEATHERS];
- static int32 m_nSkyTopGreen[NUMHOURS][NUMWEATHERS];
- static int32 m_nSkyTopBlue[NUMHOURS][NUMWEATHERS];
- static int32 m_nSkyBottomRed[NUMHOURS][NUMWEATHERS];
- static int32 m_nSkyBottomGreen[NUMHOURS][NUMWEATHERS];
- static int32 m_nSkyBottomBlue[NUMHOURS][NUMWEATHERS];
- static int32 m_nSunCoreRed[NUMHOURS][NUMWEATHERS];
- static int32 m_nSunCoreGreen[NUMHOURS][NUMWEATHERS];
- static int32 m_nSunCoreBlue[NUMHOURS][NUMWEATHERS];
- static int32 m_nSunCoronaRed[NUMHOURS][NUMWEATHERS];
- static int32 m_nSunCoronaGreen[NUMHOURS][NUMWEATHERS];
- static int32 m_nSunCoronaBlue[NUMHOURS][NUMWEATHERS];
- static float m_fSunSize[NUMHOURS][NUMWEATHERS];
- static float m_fSpriteSize[NUMHOURS][NUMWEATHERS];
- static float m_fSpriteBrightness[NUMHOURS][NUMWEATHERS];
- static int16 m_nShadowStrength[NUMHOURS][NUMWEATHERS];
- static int16 m_nLightShadowStrength[NUMHOURS][NUMWEATHERS];
- static int16 m_nTreeShadowStrength[NUMHOURS][NUMWEATHERS];
- static float m_fFogStart[NUMHOURS][NUMWEATHERS];
- static float m_fFarClip[NUMHOURS][NUMWEATHERS];
- static float m_fLightsOnGroundBrightness[NUMHOURS][NUMWEATHERS];
- static int32 m_nLowCloudsRed[NUMHOURS][NUMWEATHERS];
- static int32 m_nLowCloudsGreen[NUMHOURS][NUMWEATHERS];
- static int32 m_nLowCloudsBlue[NUMHOURS][NUMWEATHERS];
- static int32 m_nFluffyCloudsTopRed[NUMHOURS][NUMWEATHERS];
- static int32 m_nFluffyCloudsTopGreen[NUMHOURS][NUMWEATHERS];
- static int32 m_nFluffyCloudsTopBlue[NUMHOURS][NUMWEATHERS];
- static int32 m_nFluffyCloudsBottomRed[NUMHOURS][NUMWEATHERS];
- static int32 m_nFluffyCloudsBottomGreen[NUMHOURS][NUMWEATHERS];
- static int32 m_nFluffyCloudsBottomBlue[NUMHOURS][NUMWEATHERS];
- static float m_fBlurRed[NUMHOURS][NUMWEATHERS];
- static float m_fBlurGreen[NUMHOURS][NUMWEATHERS];
- static float m_fBlurBlue[NUMHOURS][NUMWEATHERS];
- static float m_fBlurAlpha[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nAmbientRed[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nAmbientGreen[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nAmbientBlue[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nAmbientRed_Obj[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nAmbientGreen_Obj[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nAmbientBlue_Obj[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nAmbientRed_Bl[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nAmbientGreen_Bl[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nAmbientBlue_Bl[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nAmbientRed_Obj_Bl[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nAmbientGreen_Obj_Bl[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nAmbientBlue_Obj_Bl[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nDirectionalRed[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nDirectionalGreen[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nDirectionalBlue[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nSkyTopRed[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nSkyTopGreen[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nSkyTopBlue[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nSkyBottomRed[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nSkyBottomGreen[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nSkyBottomBlue[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nSunCoreRed[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nSunCoreGreen[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nSunCoreBlue[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nSunCoronaRed[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nSunCoronaGreen[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nSunCoronaBlue[NUMHOURS][NUMWEATHERS];
+ static int8 m_fSunSize[NUMHOURS][NUMWEATHERS];
+ static int8 m_fSpriteSize[NUMHOURS][NUMWEATHERS];
+ static int8 m_fSpriteBrightness[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nShadowStrength[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nLightShadowStrength[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nPoleShadowStrength[NUMHOURS][NUMWEATHERS];
+ static int16 m_fFogStart[NUMHOURS][NUMWEATHERS];
+ static int16 m_fFarClip[NUMHOURS][NUMWEATHERS];
+ static uint8 m_fLightsOnGroundBrightness[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nLowCloudsRed[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nLowCloudsGreen[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nLowCloudsBlue[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nFluffyCloudsTopRed[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nFluffyCloudsTopGreen[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nFluffyCloudsTopBlue[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nFluffyCloudsBottomRed[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nFluffyCloudsBottomGreen[NUMHOURS][NUMWEATHERS];
+ static uint8 m_nFluffyCloudsBottomBlue[NUMHOURS][NUMWEATHERS];
+ static uint8 m_fBlurRed[NUMHOURS][NUMWEATHERS];
+ static uint8 m_fBlurGreen[NUMHOURS][NUMWEATHERS];
+ static uint8 m_fBlurBlue[NUMHOURS][NUMWEATHERS];
+ static uint8 m_fWaterRed[NUMHOURS][NUMWEATHERS];
+ static uint8 m_fWaterGreen[NUMHOURS][NUMWEATHERS];
+ static uint8 m_fWaterBlue[NUMHOURS][NUMWEATHERS];
+ static uint8 m_fWaterAlpha[NUMHOURS][NUMWEATHERS];
static float m_fCurrentAmbientRed;
static float m_fCurrentAmbientGreen;
static float m_fCurrentAmbientBlue;
+ static float m_fCurrentAmbientRed_Obj;
+ static float m_fCurrentAmbientGreen_Obj;
+ static float m_fCurrentAmbientBlue_Obj;
+ static float m_fCurrentAmbientRed_Bl;
+ static float m_fCurrentAmbientGreen_Bl;
+ static float m_fCurrentAmbientBlue_Bl;
+ static float m_fCurrentAmbientRed_Obj_Bl;
+ static float m_fCurrentAmbientGreen_Obj_Bl;
+ static float m_fCurrentAmbientBlue_Obj_Bl;
static float m_fCurrentDirectionalRed;
static float m_fCurrentDirectionalGreen;
static float m_fCurrentDirectionalBlue;
@@ -66,7 +87,7 @@ class CTimeCycle
static float m_fCurrentSpriteBrightness;
static int32 m_nCurrentShadowStrength;
static int32 m_nCurrentLightShadowStrength;
- static int32 m_nCurrentTreeShadowStrength;
+ static int32 m_nCurrentPoleShadowStrength;
static float m_fCurrentFogStart;
static float m_fCurrentFarClip;
static float m_fCurrentLightsOnGroundBrightness;
@@ -82,7 +103,10 @@ class CTimeCycle
static float m_fCurrentBlurRed;
static float m_fCurrentBlurGreen;
static float m_fCurrentBlurBlue;
- static float m_fCurrentBlurAlpha;
+ static float m_fCurrentWaterRed;
+ static float m_fCurrentWaterGreen;
+ static float m_fCurrentWaterBlue;
+ static float m_fCurrentWaterAlpha;
static int32 m_nCurrentFogColourRed;
static int32 m_nCurrentFogColourGreen;
static int32 m_nCurrentFogColourBlue;
@@ -90,6 +114,9 @@ class CTimeCycle
static int32 m_FogReduction;
public:
+ static int32 m_bExtraColourOn;
+ static int32 m_ExtraColour;
+ static float m_ExtraColourInter;
static int32 m_CurrentStoredValue;
static CVector m_VectorToSun[16];
static float m_fShadowFrontX[16];
@@ -102,6 +129,15 @@ public:
static float GetAmbientRed(void) { return m_fCurrentAmbientRed; }
static float GetAmbientGreen(void) { return m_fCurrentAmbientGreen; }
static float GetAmbientBlue(void) { return m_fCurrentAmbientBlue; }
+ static float GetAmbientRed_Obj(void) { return m_fCurrentAmbientRed_Obj; }
+ static float GetAmbientGreen_Obj(void) { return m_fCurrentAmbientGreen_Obj; }
+ static float GetAmbientBlue_Obj(void) { return m_fCurrentAmbientBlue_Obj; }
+ static float GetAmbientRed_Bl(void) { return m_fCurrentAmbientRed_Bl; }
+ static float GetAmbientGreen_Bl(void) { return m_fCurrentAmbientGreen_Bl; }
+ static float GetAmbientBlue_Bl(void) { return m_fCurrentAmbientBlue_Bl; }
+ static float GetAmbientRed_Obj_Bl(void) { return m_fCurrentAmbientRed_Obj_Bl; }
+ static float GetAmbientGreen_Obj_Bl(void) { return m_fCurrentAmbientGreen_Obj_Bl; }
+ static float GetAmbientBlue_Obj_Bl(void) { return m_fCurrentAmbientBlue_Obj_Bl; }
static float GetDirectionalRed(void) { return m_fCurrentDirectionalRed; }
static float GetDirectionalGreen(void) { return m_fCurrentDirectionalGreen; }
static float GetDirectionalBlue(void) { return m_fCurrentDirectionalBlue; }
@@ -140,8 +176,21 @@ public:
static int32 GetFogBlue(void) { return m_nCurrentFogColourBlue; }
static int32 GetFogReduction(void) { return m_FogReduction; }
+ static int32 GetBlurRed(void) { return m_fCurrentBlurRed; }
+ static int32 GetBlurGreen(void) { return m_fCurrentBlurGreen; }
+ static int32 GetBlurBlue(void) { return m_fCurrentBlurBlue; }
+ static int32 GetWaterRed(void) { return m_fCurrentWaterRed; }
+ static int32 GetWaterGreen(void) { return m_fCurrentWaterGreen; }
+ static int32 GetWaterBlue(void) { return m_fCurrentWaterBlue; }
+ static int32 GetWaterAlpha(void) { return m_fCurrentWaterAlpha; }
+
static void Initialise(void);
static void Update(void);
+ static float Interpolate(int8 *a, int8 *b);
+ static float Interpolate(uint8 *a, uint8 *b);
+ static float Interpolate(int16 *a, int16 *b);
+ static void StartExtraColour(int32 c, bool fade);
+ static void StopExtraColour(bool fade);
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]; }
diff --git a/src/renderer/VarConsole.cpp b/src/renderer/VarConsole.cpp
new file mode 100644
index 00000000..372a091a
--- /dev/null
+++ b/src/renderer/VarConsole.cpp
@@ -0,0 +1,786 @@
+#include "common.h"
+#include "VarConsole.h"
+#include "Font.h"
+#include "Pad.h"
+
+#define VAR_CONSOLE_PAD 1
+
+CVarConsole VarConsole;
+
+void
+CVarConsole::Initialise()
+{
+ m_nCountEntries = 0;
+ m_nCurPage = 1;
+ m_bIsOpen = false;
+ m_nCurEntry = 0;
+ m_nFirstEntryOnPage = 0;
+}
+
+void
+CVarConsole::Add(char *text, int8 *pVal, uint8 step, int8 min, int8 max, bool8 isVar)
+{
+ int i;
+ for (i = 0; i < m_nCountEntries; i++) {
+ if (m_aEntries[i].text == text)
+ return;
+ }
+
+ m_aEntries[i].text = text;
+ m_aEntries[i].pInt8Value = pVal;
+ m_aEntries[i].bAllowExceedBounds = isVar;
+ m_aEntries[i].VarType = VCE_TYPE_INT8;
+ m_aEntries[i].I8_step = step;
+ m_aEntries[i].I8_min = min;
+ m_aEntries[i].I8_max = max;
+ m_nCountEntries++;
+}
+
+void
+CVarConsole::Add(char *text, int16 *pVal, uint16 step, int16 min, int16 max, bool8 isVar)
+{
+ int i;
+ for (i = 0; i < m_nCountEntries; i++) {
+ if (m_aEntries[i].text == text)
+ return;
+ }
+
+ m_aEntries[i].text = text;
+ m_aEntries[i].pInt16Value = pVal;
+ m_aEntries[i].bAllowExceedBounds = isVar;
+ m_aEntries[i].VarType = VCE_TYPE_INT16;
+ m_aEntries[i].I16_step = step;
+ m_aEntries[i].I16_min = min;
+ m_aEntries[i].I16_max = max;
+ m_nCountEntries++;
+}
+
+void
+CVarConsole::Add(char *text, int32 *pVal, uint32 step, int32 min, int32 max, bool8 isVar)
+{
+ int i;
+ for (i = 0; i < m_nCountEntries; i++) {
+ if (m_aEntries[i].text == text)
+ return;
+ }
+
+ m_aEntries[i].text = text;
+ m_aEntries[i].pInt32Value = pVal;
+ m_aEntries[i].bAllowExceedBounds = isVar;
+ m_aEntries[i].VarType = VCE_TYPE_INT32;
+ m_aEntries[i].I32_step = step;
+ m_aEntries[i].I32_min = min;
+ m_aEntries[i].I32_max = max;
+ m_nCountEntries++;
+}
+
+void
+CVarConsole::Add(char *text, int64 *pVal, uint64 step, int64 min, int64 max, bool8 isVar)
+{
+ int i;
+ for (i = 0; i < m_nCountEntries; i++) {
+ if (m_aEntries[i].text == text)
+ return;
+ }
+
+ m_aEntries[i].text = text;
+ m_aEntries[i].pInt64Value = pVal;
+ m_aEntries[i].bAllowExceedBounds = isVar;
+ m_aEntries[i].VarType = VCE_TYPE_INT64;
+ m_aEntries[i].I64_step = step;
+ m_aEntries[i].I64_min = min;
+ m_aEntries[i].I64_max = max;
+ m_nCountEntries++;
+}
+
+void
+CVarConsole::Add(char *text, uint8 *pVal, uint8 step, int8 min, int8 max, bool8 isVar)
+{
+ int i;
+ for (i = 0; i < m_nCountEntries; i++) {
+ if (m_aEntries[i].text == text)
+ return;
+ }
+
+ m_aEntries[i].text = text;
+ m_aEntries[i].pUint8Value = pVal;
+ m_aEntries[i].bAllowExceedBounds = isVar;
+ m_aEntries[i].VarType = VCE_TYPE_UINT8;
+ m_aEntries[i].I8_step = step;
+ m_aEntries[i].I8_min = min;
+ m_aEntries[i].I8_max = max;
+ m_nCountEntries++;
+}
+
+void
+CVarConsole::Add(char *text, uint16 *pVal, uint16 step, int16 min, int16 max, bool8 isVar)
+{
+ int i;
+ for (i = 0; i < m_nCountEntries; i++) {
+ if (m_aEntries[i].text == text)
+ return;
+ }
+
+ m_aEntries[i].text = text;
+ m_aEntries[i].pUint16Value = pVal;
+ m_aEntries[i].bAllowExceedBounds = isVar;
+ m_aEntries[i].VarType = VCE_TYPE_UINT16;
+ m_aEntries[i].I16_step = step;
+ m_aEntries[i].I16_min = min;
+ m_aEntries[i].I16_max = max;
+ m_nCountEntries++;
+}
+
+void
+CVarConsole::Add(char *text, uint32 *pVal, uint32 step, int32 min, int32 max, bool8 isVar)
+{
+ int i;
+ for (i = 0; i < m_nCountEntries; i++) {
+ if (m_aEntries[i].text == text)
+ return;
+ }
+
+ m_aEntries[i].text = text;
+ m_aEntries[i].pUint32Value = pVal;
+ m_aEntries[i].bAllowExceedBounds = isVar;
+ m_aEntries[i].VarType = VCE_TYPE_UINT32;
+ m_aEntries[i].I32_step = step;
+ m_aEntries[i].I32_min = min;
+ m_aEntries[i].I32_max = max;
+ m_nCountEntries++;
+}
+
+void
+CVarConsole::Add(char *text, uint64 *pVal, uint64 step, int64 min, int64 max, bool8 isVar)
+{
+ int i;
+ for (i = 0; i < m_nCountEntries; i++) {
+ if (m_aEntries[i].text == text)
+ return;
+ }
+
+ m_aEntries[i].text = text;
+ m_aEntries[i].pUint64Value = pVal;
+ m_aEntries[i].bAllowExceedBounds = isVar;
+ m_aEntries[i].VarType = VCE_TYPE_UINT64;
+ m_aEntries[i].I64_step = step;
+ m_aEntries[i].I64_min = min;
+ m_aEntries[i].I64_max = max;
+ m_nCountEntries++;
+}
+
+void
+CVarConsole::Add(char *text, float *pVal, float step, float min, float max, bool8 isVar)
+{
+ int i;
+ for (i = 0; i < m_nCountEntries; i++) {
+ if (m_aEntries[i].text == text)
+ return;
+ }
+
+ m_aEntries[i].text = text;
+ m_aEntries[i].pFloatValue = pVal;
+ m_aEntries[i].bAllowExceedBounds = isVar;
+ m_aEntries[i].VarType = VCE_TYPE_FLOAT;
+ m_aEntries[i].F_step = step;
+ m_aEntries[i].F_min = min;
+ m_aEntries[i].F_max = max;
+ m_nCountEntries++;
+}
+
+void
+CVarConsole::Add(char *text, bool *pVal, bool8 isVar)
+{
+ int i;
+ for (i = 0; i < m_nCountEntries; i++) {
+ if (m_aEntries[i].text == text)
+ return;
+ }
+
+ m_aEntries[i].text = text;
+ m_aEntries[i].pBoolValue = pVal;
+ m_aEntries[i].bAllowExceedBounds = isVar;
+ m_aEntries[i].VarType = VCE_TYPE_BOOL;
+ m_nCountEntries++;
+}
+
+void
+CVarConsole::Add(char *text, bool8 *pVal, bool8 isVar)
+{
+ int i;
+ for (i = 0; i < m_nCountEntries; i++) {
+ if (m_aEntries[i].text == text)
+ return;
+ }
+
+ m_aEntries[i].text = text;
+ m_aEntries[i].pUint8Value = pVal;
+ m_aEntries[i].bAllowExceedBounds = isVar;
+ m_aEntries[i].VarType = VCE_TYPE_BOOL8;
+ m_nCountEntries++;
+}
+
+void
+CVarConsole::Add(char *text, bool16 *pVal, bool8 isVar)
+{
+ int i;
+ for (i = 0; i < m_nCountEntries; i++) {
+ if (m_aEntries[i].text == text)
+ return;
+ }
+
+ m_aEntries[i].text = text;
+ m_aEntries[i].pUint16Value = pVal;
+ m_aEntries[i].bAllowExceedBounds = isVar;
+ m_aEntries[i].VarType = VCE_TYPE_BOOL16;
+ m_nCountEntries++;
+}
+
+void
+CVarConsole::Add(char *text, bool32 *pVal, bool8 isVar)
+{
+ int i;
+ for (i = 0; i < m_nCountEntries; i++) {
+ if (m_aEntries[i].text == text)
+ return;
+ }
+
+ m_aEntries[i].text = text;
+ m_aEntries[i].pUint32Value = pVal;
+ m_aEntries[i].bAllowExceedBounds = isVar;
+ m_aEntries[i].VarType = VCE_TYPE_BOOL32;
+ m_nCountEntries++;
+}
+
+void
+CVarConsole::Add(char *text, void (*pCallback)(void))
+{
+ int i;
+ for (i = 0; i < m_nCountEntries; i++) {
+ if (m_aEntries[i].text == text)
+ return;
+ }
+
+ m_aEntries[i].text = text;
+ m_aEntries[i].pCallback = pCallback;
+ m_aEntries[i].VarType = VCE_TYPE_FUNCTION;
+ m_nCountEntries++;
+}
+
+void
+CVarConsole::Remove(char *text)
+{
+ int i;
+ for (i = 0; i < m_nCountEntries; i++) {
+ if (m_aEntries[i].text == text)
+ {
+ for (int j = i; j < m_nCountEntries-1; j++)
+ m_aEntries[j] = m_aEntries[j+1];
+ m_nCountEntries--;
+ return;
+ }
+ }
+}
+
+void
+CVarConsole::SortPages()
+{
+ m_nNumPages = m_nCountEntries / 30 + 1;
+}
+
+void
+CVarConsole::Display()
+{
+ char s[256];
+ wchar ws[256];
+
+ CFont::SetColor(CRGBA(200, 200, 200, 255));
+ CFont::SetFontStyle(FONT_STANDARD);
+ CFont::SetScale(SCREEN_SCALE_X(0.5f), SCREEN_SCALE_Y(0.6f));
+ CFont::SetDropShadowPosition(2);
+ CFont::SetDropColor(CRGBA(0, 0, 0, 255));
+ CFont::SetPropOn();
+ CFont::SetWrapx(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH));
+ CFont::SetRightJustifyWrap(0.0f);
+ sprintf(s, "PAGE %d", m_nCurPage);
+ AsciiToUnicode(s, ws);
+ CFont::SetRightJustifyOn();
+ CFont::PrintString(SCREEN_SCALE_X(310.0f), SCREEN_SCALE_Y(30.0f), ws);
+ CFont::SetRightJustifyOff();
+ int y = 45;
+ for (int i = m_nFirstEntryOnPage; i < m_nCountEntries && i < m_nFirstEntryOnPage + 30; i++)
+ {
+ switch (m_aEntries[i].VarType)
+ {
+ case VCE_TYPE_INT8:
+ sprintf(s, "(%d) %s:I8:%d", i + 1, m_aEntries[i].text, *m_aEntries[i].pInt8Value);
+ break;
+ case VCE_TYPE_INT16:
+ sprintf(s, "(%d) %s:I16:%d", i + 1, m_aEntries[i].text, *m_aEntries[i].pInt16Value);
+ break;
+ case VCE_TYPE_INT32:
+ sprintf(s, "(%d) %s:I32:%d", i + 1, m_aEntries[i].text, *m_aEntries[i].pInt32Value);
+ break;
+ case VCE_TYPE_INT64:
+#ifdef FIX_BUGS
+ sprintf(s, "(%d) %s:I64:%lld", i + 1, m_aEntries[i].text, *m_aEntries[i].pInt64Value);
+#else
+ sprintf(s, "(%d) %s:I64:%d", i + 1, m_aEntries[i].text, (int32)*m_aEntries[i].pInt64Value);
+#endif
+ break;
+ case VCE_TYPE_UINT8:
+ sprintf(s, "(%d) %s:U8:%d", i + 1, m_aEntries[i].text, *m_aEntries[i].pUint8Value);
+ break;
+ case VCE_TYPE_UINT16:
+ sprintf(s, "(%d) %s:U6:%d", i + 1, m_aEntries[i].text, *m_aEntries[i].pUint16Value);
+ break;
+ case VCE_TYPE_UINT32:
+ sprintf(s, "(%d) %s:U32:%d", i + 1, m_aEntries[i].text, *m_aEntries[i].pUint32Value);
+ break;
+ case VCE_TYPE_UINT64:
+#ifdef FIX_BUGS
+ sprintf(s, "(%d) %s:U64:%llu", i + 1, m_aEntries[i].text, *m_aEntries[i].pUint64Value);
+#else
+ sprintf(s, "(%d) %s:U64:%d", i + 1, m_aEntries[i].text, (uint32)*m_aEntries[i].pUint64Value);
+#endif
+ break;
+ case VCE_TYPE_FLOAT:
+ sprintf(s, "(%d) %s:F:%f", i + 1, m_aEntries[i].text, *m_aEntries[i].pFloatValue);
+ break;
+ case VCE_TYPE_BOOL:
+ if (*m_aEntries[i].pBoolValue)
+ sprintf(s, "(%d) %s:B:TRUE", i + 1, m_aEntries[i].text);
+ else
+ sprintf(s, "(%d) %s:B : FALSE", i + 1, m_aEntries[i].text);
+ break;
+ case VCE_TYPE_BOOL8:
+ if (*m_aEntries[i].pUint8Value == FALSE)
+ sprintf(s, "(%d) %s:B8:FALSE", i + 1, m_aEntries[i].text);
+ else
+ sprintf(s, "(%d) %s:B8:TRUE", i + 1, m_aEntries[i].text);
+ break;
+ case VCE_TYPE_BOOL16:
+ if (*m_aEntries[i].pUint16Value == FALSE)
+ sprintf(s, "(%d) %s:B16:FALSE", i + 1, m_aEntries[i].text);
+ else
+ sprintf(s, "(%d) %s:B16:TRUE", i + 1, m_aEntries[i].text);
+ break;
+ case VCE_TYPE_BOOL32:
+ if (*m_aEntries[i].pUint32Value == FALSE)
+ sprintf(s, "(%d) %s:B32:FALSE", i + 1, m_aEntries[i].text);
+ else
+ sprintf(s, "(%d) %s:B32:TRUE", i + 1, m_aEntries[i].text);
+ break;
+ case VCE_TYPE_FUNCTION:
+ sprintf(s, "(%d) %s:FUNCTION:call this function?", i + 1, m_aEntries[i].text);
+ break;
+ }
+ AsciiToUnicode(s, ws);
+ if (m_nCurEntry == i) {
+ CFont::SetBackgroundOn();
+#ifdef FIX_BUGS
+ CFont::SetBackgroundColor(CRGBA(128, 128, 128, 128));
+#endif
+ }
+#ifdef FIX_BUGS
+ else
+ CFont::SetBackgroundColor(CRGBA(128, 128, 128, 0));
+#endif
+
+ CFont::SetColor(CRGBA(200, 200, 200, 255));
+ CFont::PrintString(SCREEN_SCALE_X(30.0f), SCREEN_SCALE_Y(y), ws);
+ if (m_nCurEntry == i)
+ CFont::SetBackgroundOff();
+ y += 12;
+ }
+}
+
+void
+CVarConsole::ModifyLeft()
+{
+ CVarConsoleEntry &entry = m_aEntries[m_nCurEntry];
+ switch (entry.VarType)
+ {
+ case VCE_TYPE_INT8:
+ *entry.pInt8Value -= entry.I8_step;
+ if (entry.bAllowExceedBounds) {
+ if (*entry.pInt8Value < entry.I8_min)
+ *entry.pInt8Value = entry.I8_max;
+ } else {
+ if (*entry.pInt8Value < entry.I8_min)
+ *entry.pInt8Value = entry.I8_min;
+ }
+ break;
+ case VCE_TYPE_INT16:
+ *entry.pInt16Value -= entry.I16_step;
+ if (entry.bAllowExceedBounds) {
+ if (*entry.pInt16Value < entry.I16_min)
+ *entry.pInt16Value = entry.I16_max;
+ }
+ else {
+ if (*entry.pInt16Value < entry.I16_min)
+ *entry.pInt16Value = entry.I16_min;
+ }
+ break;
+ case VCE_TYPE_INT32:
+ *entry.pInt32Value -= entry.I32_step;
+ if (entry.bAllowExceedBounds) {
+ if (*entry.pInt32Value < entry.I32_min)
+ *entry.pInt32Value = entry.I32_max;
+ }
+ else {
+ if (*entry.pInt32Value < entry.I32_min)
+ *entry.pInt32Value = entry.I32_min;
+ }
+ break;
+ case VCE_TYPE_INT64:
+ *entry.pInt64Value -= entry.I64_step;
+ if (entry.bAllowExceedBounds) {
+ if (*entry.pInt64Value < entry.I64_min)
+ *entry.pInt64Value = entry.I64_max;
+ }
+ else {
+ if (*entry.pInt64Value < entry.I64_min)
+ *entry.pInt64Value = entry.I64_min;
+ }
+ break;
+ case VCE_TYPE_UINT8:
+ *entry.pUint8Value -= entry.I8_step;
+ if (entry.bAllowExceedBounds) {
+ if (*(int8*)entry.pUint8Value < entry.I8_min)
+ *entry.pUint8Value = entry.I8_max;
+ }
+ else {
+ if (*(int8*)entry.pUint8Value < entry.I8_min)
+ *entry.pUint8Value = entry.I8_min;
+ }
+ break;
+ case VCE_TYPE_UINT16:
+ *entry.pUint16Value -= entry.I16_step;
+ if (entry.bAllowExceedBounds) {
+ if (*(int16*)entry.pUint16Value < entry.I16_min)
+ *entry.pUint16Value = entry.I16_max;
+ }
+ else {
+ if (*(int16*)entry.pUint16Value < entry.I16_min)
+ *entry.pUint16Value = entry.I16_min;
+ }
+ break;
+ case VCE_TYPE_UINT32:
+ *entry.pUint32Value -= entry.I32_step;
+ if (entry.bAllowExceedBounds) {
+ if (*(int32*)entry.pUint32Value < entry.I32_min)
+ *entry.pUint32Value = entry.I32_max;
+ }
+ else {
+ if (*(int32*)entry.pUint32Value < entry.I32_min)
+ *entry.pUint32Value = entry.I32_min;
+ }
+ break;
+ case VCE_TYPE_UINT64:
+ *entry.pUint64Value -= entry.I64_step;
+ if (entry.bAllowExceedBounds) {
+ if (*(int64*)entry.pUint64Value < entry.I64_min)
+ *entry.pUint64Value = entry.I64_max;
+ }
+ else {
+ if (*(int64*)entry.pUint64Value < entry.I64_min)
+ *entry.pUint64Value = entry.I64_min;
+ }
+ break;
+ case VCE_TYPE_FLOAT:
+ *entry.pFloatValue -= entry.F_step;
+ if (entry.bAllowExceedBounds) {
+ if (*entry.pFloatValue < entry.F_min)
+ *entry.pFloatValue = entry.F_max;
+ }
+ else {
+ if (*entry.pFloatValue < entry.F_min)
+ *entry.pFloatValue = entry.F_min;
+ }
+ break;
+ case VCE_TYPE_BOOL:
+ if (entry.bAllowExceedBounds)
+ *entry.pBoolValue ^= true;
+ else
+ *entry.pBoolValue = false;
+ break;
+ case VCE_TYPE_BOOL8:
+ if (entry.bAllowExceedBounds)
+ *entry.pUint8Value = *entry.pUint8Value == false;
+ else
+ *entry.pUint8Value = false;
+ break;
+ case VCE_TYPE_BOOL16:
+ if (entry.bAllowExceedBounds)
+ *entry.pUint16Value = *entry.pUint16Value == false;
+ else
+ *entry.pUint16Value = false;
+ break;
+ case VCE_TYPE_BOOL32:
+ if (entry.bAllowExceedBounds)
+ *entry.pUint32Value = *entry.pUint32Value == false;
+ else
+ *entry.pUint32Value = false;
+ break;
+ case VCE_TYPE_FUNCTION:
+ entry.pCallback();
+ break;
+ default:
+ return;
+ }
+}
+
+void
+CVarConsole::ModifyRight()
+{
+ CVarConsoleEntry &entry = m_aEntries[m_nCurEntry];
+ switch (entry.VarType)
+ {
+ case VCE_TYPE_INT8:
+ *entry.pInt8Value += entry.I8_step;
+ if (entry.bAllowExceedBounds) {
+ if (*entry.pInt8Value > entry.I8_max)
+ *entry.pInt8Value = entry.I8_min;
+ }
+ else {
+ if (*entry.pInt8Value > entry.I8_max)
+ *entry.pInt8Value = entry.I8_max;
+ }
+ break;
+ case VCE_TYPE_INT16:
+ *entry.pInt16Value += entry.I16_step;
+ if (entry.bAllowExceedBounds) {
+ if (*entry.pInt16Value > entry.I16_max)
+ *entry.pInt16Value = entry.I16_min;
+ }
+ else {
+ if (*entry.pInt16Value > entry.I16_max)
+ *entry.pInt16Value = entry.I16_max;
+ }
+ break;
+ case VCE_TYPE_INT32:
+ *entry.pInt32Value += entry.I32_step;
+ if (entry.bAllowExceedBounds) {
+ if (*entry.pInt32Value > entry.I32_max)
+ *entry.pInt32Value = entry.I32_min;
+ }
+ else {
+ if (*entry.pInt32Value > entry.I32_max)
+ *entry.pInt32Value = entry.I32_max;
+ }
+ break;
+ case VCE_TYPE_INT64:
+ *entry.pInt64Value += entry.I64_step;
+ if (entry.bAllowExceedBounds) {
+ if (*entry.pInt64Value > entry.I64_max)
+ *entry.pInt64Value = entry.I64_min;
+ }
+ else {
+ if (*entry.pInt64Value > entry.I64_max)
+ *entry.pInt64Value = entry.I64_max;
+ }
+ break;
+ case VCE_TYPE_UINT8:
+ *entry.pUint8Value += entry.I8_step;
+ if (entry.bAllowExceedBounds) {
+ if (*entry.pUint8Value > (uint8)entry.I8_max)
+ *entry.pUint8Value = entry.I8_min;
+ }
+ else {
+ if (*entry.pUint8Value > (uint8)entry.I8_max)
+ *entry.pUint8Value = entry.I8_max;
+ }
+ break;
+ case VCE_TYPE_UINT16:
+ *entry.pUint16Value += entry.I16_step;
+ if (entry.bAllowExceedBounds) {
+ if (*entry.pUint16Value > (uint16)entry.I16_max)
+ *entry.pUint16Value = entry.I16_min;
+ }
+ else {
+ if (*entry.pUint16Value > (uint16)entry.I16_max)
+ *entry.pUint16Value = entry.I16_max;
+ }
+ break;
+ case VCE_TYPE_UINT32:
+ *entry.pUint32Value += entry.I32_step;
+ if (entry.bAllowExceedBounds) {
+ if (*entry.pUint32Value > (uint32)entry.I32_max)
+ *entry.pUint32Value = entry.I32_min;
+ }
+ else {
+ if (*entry.pUint32Value > (uint32)entry.I32_max)
+ *entry.pUint32Value = entry.I32_max;
+ }
+ break;
+ case VCE_TYPE_UINT64:
+ *entry.pUint64Value += entry.I64_step;
+ if (entry.bAllowExceedBounds) {
+ if (*entry.pUint64Value > (uint64)entry.I64_max)
+ *entry.pUint64Value = entry.I64_min;
+ }
+ else {
+ if (*entry.pUint64Value > (uint64)entry.I64_max)
+ *entry.pUint64Value = entry.I64_max;
+ }
+ break;
+ case VCE_TYPE_FLOAT:
+ *entry.pFloatValue += entry.F_step;
+ if (entry.bAllowExceedBounds) {
+ if (*entry.pFloatValue > entry.F_max)
+ *entry.pFloatValue = entry.F_min;
+ }
+ else {
+ if (*entry.pFloatValue > entry.F_max)
+ *entry.pFloatValue = entry.F_max;
+ }
+ break;
+ case VCE_TYPE_BOOL:
+ if (entry.bAllowExceedBounds)
+ *entry.pBoolValue ^= true;
+ else
+ *entry.pBoolValue = true;
+ break;
+ case VCE_TYPE_BOOL8:
+ if (entry.bAllowExceedBounds)
+ *entry.pUint8Value = *entry.pUint8Value == false;
+ else
+ *entry.pUint8Value = true;
+ break;
+ case VCE_TYPE_BOOL16:
+ if (entry.bAllowExceedBounds)
+ *entry.pUint16Value = *entry.pUint16Value == false;
+ else
+ *entry.pUint16Value = true;
+ break;
+ case VCE_TYPE_BOOL32:
+ if (entry.bAllowExceedBounds)
+ *entry.pUint32Value = *entry.pUint32Value == false;
+ else
+ *entry.pUint32Value = true;
+ break;
+ case VCE_TYPE_FUNCTION:
+ entry.pCallback();
+ break;
+ default:
+ return;
+ }
+}
+
+void
+CVarConsole::Enter()
+{
+ m_bIsOpen = true;
+}
+
+void
+CVarConsole::Exit()
+{
+ m_bIsOpen = false;
+}
+
+void
+CVarConsole::Input()
+{
+ if (CPad::GetPad(VAR_CONSOLE_PAD)->GetDPadDownJustDown() || CPad::GetPad(VAR_CONSOLE_PAD)->GetAnaloguePadDown())
+ {
+ m_nCurEntry++;
+ if (m_nCurEntry < m_nCountEntries)
+ {
+ if (m_nCurEntry > m_nFirstEntryOnPage + 29)
+ {
+ m_nFirstEntryOnPage = m_nCurEntry;
+ ++m_nCurPage;
+ }
+ }
+ else
+ {
+ m_nCurEntry = m_nCountEntries - 1;
+ }
+ }
+
+ if (CPad::GetPad(VAR_CONSOLE_PAD)->GetDPadUpJustDown() || CPad::GetPad(VAR_CONSOLE_PAD)->GetAnaloguePadUp())
+ {
+ m_nCurEntry--;
+ if (m_nCurEntry < m_nFirstEntryOnPage)
+ {
+ m_nFirstEntryOnPage = m_nCurEntry - 29;
+ --m_nCurPage;
+ }
+ if (m_nFirstEntryOnPage < 0)
+ {
+ m_nCurEntry = 0;
+ m_nFirstEntryOnPage = 0;
+ m_nCurPage = 1;
+ }
+ }
+ if (CPad::GetPad(VAR_CONSOLE_PAD)->GetSquare())
+ ModifyLeft();
+ if (CPad::GetPad(VAR_CONSOLE_PAD)->GetTriangle())
+ ModifyRight();
+
+ if (CPad::GetPad(VAR_CONSOLE_PAD)->GetDPadLeftJustDown() || CPad::GetPad(VAR_CONSOLE_PAD)->GetAnaloguePadLeft())
+ ModifyLeft();
+
+ if (CPad::GetPad(VAR_CONSOLE_PAD)->GetDPadRightJustDown() || CPad::GetPad(VAR_CONSOLE_PAD)->GetAnaloguePadRight())
+ ModifyRight();
+
+ if (CPad::GetPad(VAR_CONSOLE_PAD)->GetLeftShoulder2JustDown())
+ {
+ if (m_nCurPage > 1)
+ {
+ m_nCurPage--;
+ m_nFirstEntryOnPage -= 30;
+ m_nCurEntry = m_nFirstEntryOnPage;
+ if (m_nFirstEntryOnPage < 0)
+ {
+ m_nFirstEntryOnPage = 0;
+ m_nCurEntry = m_nFirstEntryOnPage;
+ m_nCurPage = 1;
+ }
+ }
+ }
+
+ if (CPad::GetPad(VAR_CONSOLE_PAD)->GetRightShoulder2JustDown())
+ {
+ if (m_nCurPage < m_nNumPages)
+ {
+ m_nCurPage++;
+ m_nFirstEntryOnPage += 30;
+ m_nCurEntry = m_nFirstEntryOnPage;
+ if (m_nFirstEntryOnPage >= m_nCountEntries)
+ {
+ m_nFirstEntryOnPage -= 30;
+ m_nCurEntry = m_nFirstEntryOnPage;
+ m_nCurPage--;
+ }
+ }
+ }
+
+ if (CPad::GetPad(VAR_CONSOLE_PAD)->GetRightShoulder1JustDown() && CPad::GetPad(VAR_CONSOLE_PAD)->GetLeftShoulder1JustDown())
+ Exit();
+}
+
+void
+CVarConsole::Process()
+{
+ Input();
+ SortPages();
+ Display();
+}
+
+bool8
+CVarConsole::Open()
+{
+ return m_bIsOpen;
+}
+
+void
+CVarConsole::Check()
+{
+ if (Open())
+ Process();
+ else if (CPad::GetPad(VAR_CONSOLE_PAD)->GetRightShoulder1JustDown() && CPad::GetPad(VAR_CONSOLE_PAD)->GetLeftShoulder1JustDown())
+ Enter();
+} \ No newline at end of file
diff --git a/src/renderer/VarConsole.h b/src/renderer/VarConsole.h
new file mode 100644
index 00000000..5179a10d
--- /dev/null
+++ b/src/renderer/VarConsole.h
@@ -0,0 +1,92 @@
+#pragma once
+
+enum eVarConsoleEntryType
+{
+ VCE_TYPE_INT8,
+ VCE_TYPE_INT16,
+ VCE_TYPE_INT32,
+ VCE_TYPE_INT64,
+ VCE_TYPE_UINT8,
+ VCE_TYPE_UINT16,
+ VCE_TYPE_UINT32,
+ VCE_TYPE_UINT64,
+ VCE_TYPE_FLOAT,
+ VCE_TYPE_BOOL,
+ VCE_TYPE_BOOL8,
+ VCE_TYPE_BOOL16,
+ VCE_TYPE_BOOL32,
+ VCE_TYPE_FUNCTION,
+};
+
+struct CVarConsoleEntry
+{
+ char *text;
+ int8 *pInt8Value;
+ int16 *pInt16Value;
+ int32 *pInt32Value;
+ int64 *pInt64Value;
+ uint8 *pUint8Value;
+ uint16 *pUint16Value;
+ uint32 *pUint32Value;
+ uint64 *pUint64Value;
+ float *pFloatValue;
+ bool *pBoolValue;
+ void (*pCallback)(void);
+ int8 I8_step, I8_max, I8_min;
+ int16 I16_step, I16_max, I16_min;
+ int32 I32_step, I32_max, I32_min;
+ int64 I64_step, I64_max, I64_min;
+ float F_step, F_max, F_min;
+ bool8 bAllowExceedBounds;
+ uint8 VarType;
+};
+
+
+class CVarConsole
+{
+ int32 m_nCountEntries;
+ bool8 m_bIsOpen;
+ int32 m_nCurEntry;
+ int32 m_nFirstEntryOnPage;
+ int32 m_nCurPage;
+ int32 m_nNumPages;
+ CVarConsoleEntry m_aEntries[91];
+public:
+#ifdef FIX_BUGS
+ CVarConsole() { Initialise(); }
+#endif
+ void Initialise();
+ void Add(char *text, int8 *pVal, uint8 step, int8 min, int8 max, bool8 isVar);
+ void Add(char *text, int16 *pVal, uint16 step, int16 min, int16 max, bool8 isVar);
+ void Add(char *text, int32 *pVal, uint32 step, int32 min, int32 max, bool8 isVar);
+ void Add(char *text, int64 *pVal, uint64 step, int64 min, int64 max, bool8 isVar);
+ void Add(char *text, uint8 *pVal, uint8 step, int8 min, int8 max, bool8 isVar);
+ void Add(char *text, uint16 *pVal, uint16 step, int16 min, int16 max, bool8 isVar);
+ void Add(char *text, uint32 *pVal, uint32 step, int32 min, int32 max, bool8 isVar);
+ void Add(char *text, uint64 *pVal, uint64 step, int64 min, int64 max, bool8 isVar);
+ void Add(char *text, float *pVal, float step, float min, float max, bool8 isVar);
+ void Add(char *text, bool *pVal, bool8 isVar);
+ void Add(char *text, bool8 *pVal, bool8 isVar);
+ void Add(char *text, bool16 *pVal, bool8 isVar);
+ void Add(char *text, bool32 *pVal, bool8 isVar);
+ void Add(char *text, void (*pVar)(void));
+
+ void Remove(char *text);
+
+ void SortPages();
+ void Display();
+
+ void ModifyLeft();
+ void ModifyRight();
+
+ void Enter();
+ void Exit();
+
+ void Input();
+ void Process();
+
+ bool8 Open();
+ void Check();
+};
+
+extern CVarConsole VarConsole; \ No newline at end of file
diff --git a/src/renderer/WaterCannon.cpp b/src/renderer/WaterCannon.cpp
index 08898be8..4976f8a3 100644
--- a/src/renderer/WaterCannon.cpp
+++ b/src/renderer/WaterCannon.cpp
@@ -11,6 +11,7 @@
#include "Fire.h"
#include "WaterLevel.h"
#include "Camera.h"
+#include "Particle.h"
#define WATERCANNONVERTS 4
#define WATERCANNONINDEXES 12
@@ -77,9 +78,13 @@ void CWaterCannon::Update_OncePerFrame(int16 index)
}
}
- int32 extinguishingPoint = CGeneral::GetRandomNumber() & (NUM_SEGMENTPOINTS - 1);
- if ( m_abUsed[extinguishingPoint] )
- gFireManager.ExtinguishPoint(m_avecPos[extinguishingPoint], 3.0f);
+ for ( int32 i = 0; i < NUM_SEGMENTPOINTS; i++ )
+ {
+ if ( m_abUsed[i] && gFireManager.ExtinguishPointWithWater(m_avecPos[i], 4.0f) )
+ {
+ break;
+ }
+ }
if ( ((index + CTimer::GetFrameCounter()) & 3) == 0 )
PushPeds();
@@ -231,11 +236,16 @@ void CWaterCannon::PushPeds(void)
ped->m_vecMoveSpeed.x = (0.6f * m_avecVelocity[j].x + ped->m_vecMoveSpeed.x) * 0.5f;
ped->m_vecMoveSpeed.y = (0.6f * m_avecVelocity[j].y + ped->m_vecMoveSpeed.y) * 0.5f;
- ped->SetFall(2000, AnimationId(ANIM_STD_HIGHIMPACT_FRONT + localDir), 0);
-
- CFire *fire = ped->m_pFire;
- if ( fire )
- fire->Extinguish();
+ float pedSpeed2D = ped->m_vecMoveSpeed.Magnitude2D();
+
+ if ( pedSpeed2D > 0.2f ) {
+ ped->m_vecMoveSpeed.x *= (0.2f / pedSpeed2D);
+ ped->m_vecMoveSpeed.y *= (0.2f / pedSpeed2D);
+ }
+ ped->SetFall(2000, (AnimationId)(localDir + ANIM_STD_HIGHIMPACT_FRONT), 0);
+ CParticle::AddParticle(PARTICLE_STEAM_NY_SLOWMOTION, ped->GetPosition(), ped->m_vecMoveSpeed * 0.3f, 0, 0.5f);
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, ped->GetPosition(), ped->m_vecMoveSpeed * -0.3f + CVector(0.f, 0.f, 0.5f), 0, 0.5f,
+ CGeneral::GetRandomNumberInRange(0.f, 10.f), CGeneral::GetRandomNumberInRange(0.f, 90.f), 1);
j = NUM_SEGMENTPOINTS;
}
diff --git a/src/renderer/WaterCreatures.cpp b/src/renderer/WaterCreatures.cpp
new file mode 100644
index 00000000..92fb74ee
--- /dev/null
+++ b/src/renderer/WaterCreatures.cpp
@@ -0,0 +1,275 @@
+#include "common.h"
+#include "WaterCreatures.h"
+#include "ModelIndices.h"
+#include "World.h"
+#include "WaterLevel.h"
+#include "Camera.h"
+#include "PlayerPed.h"
+#include "General.h"
+#include "Object.h"
+
+int CWaterCreatures::nNumActiveSeaLifeForms;
+CWaterCreature CWaterCreatures::aWaterCreatures[NUM_WATER_CREATURES];
+
+struct WaterCreatureProperties aProperties[65] = {
+ { &MI_FISH1SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f },
+ { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f },
+ { &MI_FISH2SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f },
+ { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f },
+ { &MI_FISH3SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f },
+ { &MI_FISH3S, 0.04f, 1.5f, 0.0008f, 3.0f },
+ { &MI_FISH1SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f },
+ { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f },
+ { &MI_FISH2SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f },
+ { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f },
+ { &MI_FISH3SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f },
+ { &MI_FISH3S, 0.04f, 1.5f, 0.0008f, 3.0f },
+ { &MI_JELLYFISH, 0.01f, 2.2f, 0.0005f, 3.5f },
+ { &MI_JELLYFISH01, 0.01f, 2.2f, 0.0005f, 3.5f },
+ { &MI_FISH1SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f },
+ { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f },
+ { &MI_FISH2SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f },
+ { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f },
+ { &MI_FISH3SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f },
+ { &MI_FISH3S, 0.04f, 1.5f, 0.0008f, 3.0f },
+ { &MI_FISH1SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f },
+ { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f },
+ { &MI_FISH2SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f },
+ { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f },
+ { &MI_FISH3SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f },
+ { &MI_FISH3S, 0.04f, 1.5f, 0.0008f, 3.0f },
+ { &MI_TURTLE, 0.01f, 2.0f, 0.0005f, 4.0f },
+ { &MI_FISH1SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f },
+ { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f },
+ { &MI_FISH2SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f },
+ { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f },
+ { &MI_FISH3SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f },
+ { &MI_FISH3S, 0.04f, 1.5f, 0.0008f, 3.0f },
+ { &MI_FISH1SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f },
+ { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f },
+ { &MI_FISH2SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f },
+ { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f },
+ { &MI_FISH3SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f },
+ { &MI_FISH3S, 0.04f, 1.5f, 0.0008f, 3.0f },
+ { &MI_DOLPHIN, 0.03f, 1.5f, 0.0005f, 4.0f },
+ { &MI_FISH1SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f },
+ { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f },
+ { &MI_FISH2SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f },
+ { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f },
+ { &MI_FISH3SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f },
+ { &MI_FISH3S, 0.04f, 1.5f, 0.0008f, 3.0f },
+ { &MI_FISH1SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f },
+ { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f },
+ { &MI_FISH2SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f },
+ { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f },
+ { &MI_FISH3SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f },
+ { &MI_FISH3S, 0.04f, 1.5f, 0.0008f, 3.0f },
+ { &MI_SHARK, 0.03f, 0.4f, 0.0005f, 4.0f },
+ { &MI_FISH1SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f },
+ { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f },
+ { &MI_FISH2SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f },
+ { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f },
+ { &MI_FISH3SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f },
+ { &MI_FISH3S, 0.04f, 1.5f, 0.0008f, 3.0f },
+ { &MI_FISH1SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f },
+ { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f },
+ { &MI_FISH2SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f },
+ { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f },
+ { &MI_FISH3SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f },
+ { &MI_FISH3S, 0.04f, 1.5f, 0.0008f, 3.0f },
+};
+
+CWaterCreature::CWaterCreature() {
+ Free();
+}
+
+void CWaterCreature::Initialise(CObject *pObj, float fFwdSpeed, float fZTurnSpeed, float fWaterDepth, uint32 alpha, eFishSlotState state) {
+ this->m_pObj = pObj;
+ this->m_fFwdSpeed = fFwdSpeed;
+ this->m_fZTurnSpeed = fZTurnSpeed;
+ this->m_fWaterDepth = fWaterDepth;
+ this->m_alpha = alpha;
+ this->m_state = state;
+}
+
+void CWaterCreature::Allocate(CObject *pObj, float fFwdSpeed, float fZTurnSpeed, float fWaterDepth, uint32 alpha, eFishSlotState state) {
+ CWaterCreature::Initialise(pObj, fFwdSpeed, fZTurnSpeed, fWaterDepth, alpha, state);
+}
+
+void CWaterCreature::Free() {
+ CWaterCreature::Initialise(nil, 0.0f, 0.0f, 0.0f, 0, WATER_CREATURE_DISABLED);
+}
+
+CWaterCreature *CWaterCreatures::GetFishStructSlot() {
+ for (int i = 0; i < NUM_WATER_CREATURES; i++)
+ if (aWaterCreatures[i].m_state == WATER_CREATURE_DISABLED)
+ return &aWaterCreatures[i];
+
+ return nil;
+}
+
+CObject *CWaterCreatures::CreateSeaLifeForm(CVector const& pos, int16 modelID, int32 zRotAngle) {
+ if (CObject::nNoTempObjects >= NUMTEMPOBJECTS)
+ return nil;
+
+ CObject *pObj = new CObject(modelID, true);
+
+ if (!pObj) return nil;
+
+ pObj->SetPosition(pos);
+ pObj->GetMatrix().UpdateRW();
+ pObj->m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
+ pObj->m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f);
+ pObj->GetMatrix().SetRotateZOnly(DEGTORAD(zRotAngle));
+ pObj->GetMatrix().UpdateRW();
+ pObj->ObjectCreatedBy = CONTROLLED_SUB_OBJECT;
+ pObj->bIsStatic = false;
+
+ if (pObj->ObjectCreatedBy == TEMP_OBJECT) {
+ CObject::nNoTempObjects++;
+ pObj->m_nEndOfLifeTime = CTimer::GetTimeInMilliseconds() + 60000;
+ }
+
+ pObj->bTouchingWater = true;
+ pObj->bUnderwater = true;
+ CWorld::Add(pObj);
+
+ return pObj;
+}
+
+bool CWaterCreatures::IsSpaceForMoreWaterCreatures() {
+ return nNumActiveSeaLifeForms < NUM_WATER_CREATURES;
+}
+
+float CWaterCreatures::CalculateFishHeading(CVector const& pos1, CVector const& pos2) {
+ CVector delta = pos1 - pos2;
+ delta.Normalise();
+
+ return CGeneral::GetRandomNumberInRange(-90, 90) +
+ RADTODEG(delta.Heading() + HALFPI + PI);
+}
+
+void CWaterCreatures::CreateOne(CVector const& pos, int32 modelID) {
+ if (!IsSpaceForMoreWaterCreatures())
+ return;
+
+ CVector playerPos = FindPlayerPed()->GetPosition();
+ CVector fishPos = pos;
+ float fDepth, fLevelNoWaves;
+ if (!TheCamera.IsSphereVisible(fishPos, 3.0f)
+ && CWaterLevel::GetWaterDepth(fishPos, &fDepth, &fLevelNoWaves, nil) && fDepth > 4.5f) {
+
+ if (modelID == -1 || modelID < 0 || modelID > 64)
+ modelID = CGeneral::GetRandomNumberInRange(0, 64);
+
+ WaterCreatureProperties *creature = &aProperties[modelID];
+ fishPos.z = fLevelNoWaves - creature->fLevel;
+ float fFwdSpeed = CGeneral::GetRandomNumberInRange(0.0f, creature->fFwdSpeed) + 0.01f;
+ float angle = CWaterCreatures::CalculateFishHeading(playerPos, fishPos);
+
+ CObject *fish = CreateSeaLifeForm(fishPos, *creature->modelID, angle);
+ if (!fish) return;
+
+ fish->SetRwObjectAlpha(255);
+ CWaterCreature *wc = GetFishStructSlot();
+ wc->Allocate(fish, fFwdSpeed, 0.0f, creature->fWaterDepth, 255, WATER_CREATURE_INIT);
+ nNumActiveSeaLifeForms++;
+ }
+}
+
+void CWaterCreatures::FreeFishStructSlot(CWaterCreature *wc) {
+ wc->Free();
+}
+
+void CWaterCreatures::UpdateAll() {
+ if (nNumActiveSeaLifeForms == 0)
+ return;
+
+ CVector playerPos = FindPlayerPed()->GetPosition();
+ for (int i = 0; i < NUM_WATER_CREATURES; i++) {
+ switch (aWaterCreatures[i].m_state) {
+ case WATER_CREATURE_ACTIVE:
+ // is this even reachable?
+ aWaterCreatures[i].m_pObj->m_nEndOfLifeTime = CTimer::GetTimeInMilliseconds() + 40000;
+ if (!aWaterCreatures[i].m_pObj->GetIsOnScreen()) {
+ aWaterCreatures[i].m_pObj->SetRwObjectAlpha(0);
+ aWaterCreatures[i].m_state = WATER_CREATURE_REMOVE;
+ break;
+ }
+ // fall through
+ case WATER_CREATURE_INIT: {
+ if ((playerPos - aWaterCreatures[i].m_pObj->GetPosition()).MagnitudeSqr() < SQR(75.0f)) {
+ if (aWaterCreatures[i].m_alpha < 255)
+ aWaterCreatures[i].m_alpha = Min(aWaterCreatures[i].m_alpha + 4, 255);
+ aWaterCreatures[i].m_pObj->SetRwObjectAlpha(aWaterCreatures[i].m_alpha);
+ CVector fwd = aWaterCreatures[i].m_pObj->GetRight(); // for some reason they used x for forward
+ fwd.Normalise();
+ aWaterCreatures[i].m_pObj->m_vecMoveSpeed = fwd * aWaterCreatures[i].m_fFwdSpeed;
+ aWaterCreatures[i].m_pObj->m_vecTurnSpeed = CVector(0.0f, 0.0f, aWaterCreatures[i].m_fZTurnSpeed);
+ aWaterCreatures[i].m_pObj->bIsStatic = false;
+ float fDepth = 0.0;
+ CWaterLevel::GetWaterDepth(aWaterCreatures[i].m_pObj->GetPosition(), &fDepth, nil, nil);
+ if (aWaterCreatures[i].m_fWaterDepth < fDepth) {
+ // it looks like this can never be true initially, looks like a BUG
+ if (aWaterCreatures[i].m_pObj->m_nEndOfLifeTime - 40000 <= CTimer::GetTimeInMilliseconds())
+ aWaterCreatures[i].m_state = WATER_CREATURE_ACTIVE;
+ }
+ else {
+ // creature is deeper than water
+ aWaterCreatures[i].m_state = WATER_CREATURE_FADE_OUT;
+ }
+
+ }
+ else {
+ aWaterCreatures[i].m_state = WATER_CREATURE_REMOVE;
+ }
+ break;
+ }
+ case WATER_CREATURE_FADE_OUT: {
+ aWaterCreatures[i].m_pObj->m_nEndOfLifeTime = CTimer::GetTimeInMilliseconds() + 40000;
+ if (aWaterCreatures[i].m_alpha <= 0) {
+ aWaterCreatures[i].m_state = WATER_CREATURE_REMOVE;
+ }
+ else {
+ aWaterCreatures[i].m_alpha = Max(aWaterCreatures[i].m_alpha - 6, 0);
+ aWaterCreatures[i].m_pObj->SetRwObjectAlpha(aWaterCreatures[i].m_alpha);
+ CVector speed = aWaterCreatures[i].m_pObj->GetRight();
+ speed.Normalise();
+ speed.x *= aWaterCreatures[i].m_fFwdSpeed;
+ speed.y *= aWaterCreatures[i].m_fFwdSpeed;
+ speed.z = -0.015f;
+ aWaterCreatures[i].m_pObj->m_vecMoveSpeed = speed;
+
+ if (!aWaterCreatures[i].m_pObj->GetIsOnScreen())
+ aWaterCreatures[i].m_state = WATER_CREATURE_REMOVE;
+ }
+ break;
+ }
+ case WATER_CREATURE_REMOVE:
+ if (aWaterCreatures[i].m_pObj){
+ CWorld::Remove(aWaterCreatures[i].m_pObj);
+ delete aWaterCreatures[i].m_pObj;
+ }
+ FreeFishStructSlot(&aWaterCreatures[i]);
+ nNumActiveSeaLifeForms--;
+ aWaterCreatures[i].m_state = WATER_CREATURE_DISABLED;
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void CWaterCreatures::RemoveAll() {
+ for (int i = 0; i < NUM_WATER_CREATURES; i++) {
+ if (aWaterCreatures[i].m_state != WATER_CREATURE_DISABLED) {
+ if (aWaterCreatures[i].m_pObj){
+ CWorld::Remove(aWaterCreatures[i].m_pObj);
+ delete aWaterCreatures[i].m_pObj;
+ }
+ FreeFishStructSlot(&aWaterCreatures[i]);
+ aWaterCreatures[i].m_state = WATER_CREATURE_DISABLED;
+ nNumActiveSeaLifeForms--;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/renderer/WaterCreatures.h b/src/renderer/WaterCreatures.h
new file mode 100644
index 00000000..32754a10
--- /dev/null
+++ b/src/renderer/WaterCreatures.h
@@ -0,0 +1,49 @@
+#pragma once
+
+class CObject;
+
+enum eFishSlotState {
+ WATER_CREATURE_INIT = 0,
+ WATER_CREATURE_ACTIVE,
+ WATER_CREATURE_FADE_OUT,
+ WATER_CREATURE_REMOVE,
+ WATER_CREATURE_DISABLED
+};
+
+class CWaterCreature {
+public:
+ CObject *m_pObj;
+ float m_fFwdSpeed;
+ float m_fZTurnSpeed;
+ int32 m_alpha;
+ float m_fWaterDepth;
+ int32 m_state;
+
+ CWaterCreature();
+ void Allocate(CObject *pObj, float fFwdSpeed, float fZTurnSpeed, float fWaterDepth, uint32 alpha, eFishSlotState state);
+ void Free();
+ void Initialise(CObject *pObj, float fFwdSpeed, float fZTurnSpeed, float fWaterDepth, uint32 alpha, eFishSlotState state);
+};
+
+class CWaterCreatures {
+
+public:
+ static CWaterCreature aWaterCreatures[NUM_WATER_CREATURES];
+ static int32 nNumActiveSeaLifeForms;
+ static CObject *CreateSeaLifeForm(CVector const& pos, int16 modelID, int32 zRotAngle);
+ static void CreateOne(CVector const& pos, int32 modelID);
+ static void UpdateAll();
+ static void FreeFishStructSlot(CWaterCreature *wc);
+ static bool IsSpaceForMoreWaterCreatures();
+ static float CalculateFishHeading(CVector const& pos1, CVector const& pos2);
+ static void RemoveAll();
+ static CWaterCreature* GetFishStructSlot();
+};
+
+struct WaterCreatureProperties {
+ int16 *modelID;
+ float fFwdSpeed;
+ float fLevel;
+ float fUnknown; //unused
+ float fWaterDepth;
+}; \ No newline at end of file
diff --git a/src/renderer/WaterLevel.cpp b/src/renderer/WaterLevel.cpp
index 7001c0cf..dee60d66 100644
--- a/src/renderer/WaterLevel.cpp
+++ b/src/renderer/WaterLevel.cpp
@@ -7,6 +7,7 @@
#include "Weather.h"
#include "Camera.h"
#include "Vehicle.h"
+#include "PlayerPed.h"
#include "Boat.h"
#include "World.h"
#include "General.h"
@@ -17,48 +18,105 @@
#include "ParticleMgr.h"
#include "RwHelper.h"
#include "Streaming.h"
+#include "ColStore.h"
#include "CdStream.h"
#include "Pad.h"
#include "RenderBuffer.h"
+#include <rwcore.h>
#include <rpworld.h>
+#include <rpmatfx.h>
+#include "Occlusion.h"
+#include "Replay.h"
#include "WaterLevel.h"
-#include "MemoryHeap.h"
+#include "SurfaceTable.h"
+#include "WaterCreatures.h"
+#define RwIm3DVertexSet_RGBA(vert, rgba) RwIm3DVertexSetRGBA(vert, rgba.red, rgba.green, rgba.blue, rgba.alpha) // (RwRGBAAssign(&(_dst)->color, &_src))
float TEXTURE_ADDU;
float TEXTURE_ADDV;
+float _TEXTURE_MASK_ADDU;
+float _TEXTURE_MASK_ADDV;
+
+float _TEXTURE_WAKE_ADDU;
+float _TEXTURE_WAKE_ADDV;
+
int32 CWaterLevel::ms_nNoOfWaterLevels;
float CWaterLevel::ms_aWaterZs[48];
CRect CWaterLevel::ms_aWaterRects[48];
int8 CWaterLevel::aWaterBlockList[MAX_LARGE_SECTORS][MAX_LARGE_SECTORS];
int8 CWaterLevel::aWaterFineBlockList[MAX_SMALL_SECTORS][MAX_SMALL_SECTORS];
bool CWaterLevel::WavesCalculatedThisFrame;
+
+
+bool CWaterLevel::RequireWavySector;
+bool CWaterLevel::MaskCalculatedThisFrame;
+CVector CWaterLevel::PreCalculatedMaskPosn;
+bool CWaterLevel::m_bRenderSeaBed;
+int32 CWaterLevel::m_nRenderWaterLayers;
+
RpAtomic *CWaterLevel::ms_pWavyAtomic;
-RpGeometry *CWaterLevel::apGeomArray[8];
-int16 CWaterLevel::nGeomUsed;
+RpAtomic *CWaterLevel::ms_pMaskAtomic;
//"Custom" Don't Render Water Toggle
bool gbDontRenderWater;
-//RwTexture *gpWaterTex;
-//RwRaster *gpWaterRaster;
RwTexture *gpWaterTex;
+RwTexture *gpWaterEnvTex;
+RwTexture *gpWaterEnvBaseTex;
+RwTexture *gpWaterWakeTex;
+
RwRaster *gpWaterRaster;
+RwRaster *gpWaterEnvRaster;
+RwRaster *gpWaterEnvBaseRaster;
+RwRaster *gpWaterWakeRaster;
+bool _bSeaLife;
+float _fWaterZOffset = WATER_Z_OFFSET;
-const float fAdd1 = 180.0f;
-const float fAdd2 = 80.0f;
-const float fRedMult = 0.6f;
-const float fGreenMult = 1.0f;
-const float fBlueMult = 1.4f;
+#ifdef PC_WATER
+float fEnvScale = 0.25f;
+#else
+float fEnvScale = 0.5f;
+#endif
+float fWave2InvLength = 0.03f;
+float fWave2NormScale = 0.5f;
+float fWave2Ampl = 0.1f;
+uint8 nWaterAlpha = 192;
+uint8 nWakeAlpha = 192;
+float fUnder1 = 4.0;
+float fUnder2 = 2.5;
+float fUnder3 = 1.5;
+int nMaskAlpha = 230;
+float fAdd1 = 180.0f;
+float fAdd2 = 80.0;
+float fRedMult = 0.6f;
+float fGreenMult = 1.0f;
+float fBlueMult = 1.4f;
+float fAlphaMult = 500.0f;
+float fAlphaBase = 30.0f;
+float fRandomMoveDiv = 8.0f;
+float fRandomDamp = 0.99f;
+float fNormMult = 2.0f;
+float fNormMultB = 1.0f;
+float fBumpScale = 1.5;
+float fBumpTexRepeat = 2.0;
+float fNormalDirectionScalar1 = 2.0f;
+float fNormalDirectionScalar2 = 1.0f;
+bool bTestDoNormals = true;
+float fSeaBedZ = 25.0f;
+float aAlphaFade[5] = { 0.4f, 1.0f, 0.2f, 1.0f, 0.4f}; //CWaterLevel::RenderWakeSegment
+float fFlatWaterBlendRange = 0.05f;
+float fStartBlendDistanceAdd = 64.0f;
+float fMinWaterAlphaMult = -30.0f;
void
CWaterLevel::Initialise(Const char *pWaterDat)
{
ms_nNoOfWaterLevels = 0;
-
+
#ifdef MASTER
int32 hFile = -1;
@@ -70,15 +128,14 @@ CWaterLevel::Initialise(Const char *pWaterDat)
#else
int32 hFile = CFileMgr::OpenFile("DATA\\waterpro.dat", "rb");
#endif
-
+
if (hFile > 0)
{
CFileMgr::Read(hFile, (char *)&ms_nNoOfWaterLevels, sizeof(ms_nNoOfWaterLevels));
- CFileMgr::Read(hFile, (char *)ms_aWaterZs, sizeof(ms_aWaterZs));
+ CFileMgr::Read(hFile, (char *)ms_aWaterZs, sizeof(ms_aWaterZs));
CFileMgr::Read(hFile, (char *)ms_aWaterRects, sizeof(ms_aWaterRects));
CFileMgr::Read(hFile, (char *)aWaterBlockList, sizeof(aWaterBlockList));
CFileMgr::Read(hFile, (char *)aWaterFineBlockList, sizeof(aWaterFineBlockList));
-
CFileMgr::CloseFile(hFile);
}
#ifndef MASTER
@@ -86,6 +143,9 @@ CWaterLevel::Initialise(Const char *pWaterDat)
{
printf("Init waterlevels\n");
+ // collision is streamed in VC
+ CColStore::LoadAllCollision();
+
CFileMgr::SetDir("");
hFile = CFileMgr::OpenFile(pWaterDat, "r");
@@ -93,11 +153,7 @@ CWaterLevel::Initialise(Const char *pWaterDat)
while ((line = CFileLoader::LoadLine(hFile)))
{
-#ifdef FIX_BUGS
if (*line && *line != ';' && !strstr(line, "* ;end of file"))
-#else
- if (*line && *line != ';')
-#endif
{
float z, l, b, r, t;
sscanf(line, "%f %f %f %f %f", &z, &l, &b, &r, &t);
@@ -118,19 +174,15 @@ CWaterLevel::Initialise(Const char *pWaterDat)
// rasterize water rects read from file
for (int32 i = 0; i < ms_nNoOfWaterLevels; i++)
{
- int32 l = WATER_HUGE_X(ms_aWaterRects[i].left);
- int32 r = WATER_HUGE_X(ms_aWaterRects[i].right) + 1.0f;
+ int32 l = WATER_HUGE_X(ms_aWaterRects[i].left + WATER_X_OFFSET);
+ int32 r = WATER_HUGE_X(ms_aWaterRects[i].right + WATER_X_OFFSET) + 1.0f;
int32 t = WATER_HUGE_Y(ms_aWaterRects[i].top);
int32 b = WATER_HUGE_Y(ms_aWaterRects[i].bottom) + 1.0f;
-#ifdef FIX_BUGS
- // water.dat has rects that go out of bounds
- // which causes memory corruption
l = Clamp(l, 0, MAX_SMALL_SECTORS - 1);
r = Clamp(r, 0, MAX_SMALL_SECTORS - 1);
t = Clamp(t, 0, MAX_SMALL_SECTORS - 1);
b = Clamp(b, 0, MAX_SMALL_SECTORS - 1);
-#endif
for (int32 x = l; x <= r; x++)
{
@@ -144,11 +196,11 @@ CWaterLevel::Initialise(Const char *pWaterDat)
// remove tiles that are obscured by land
for (int32 x = 0; x < MAX_SMALL_SECTORS; x++)
{
- float worldX = WATER_START_X + x * SMALL_SECTOR_SIZE;
+ float worldX = WATER_START_X + x * SMALL_SECTOR_SIZE - WATER_X_OFFSET;
for (int32 y = 0; y < MAX_SMALL_SECTORS; y++)
{
- if (aWaterFineBlockList[x][y] >= 0)
+ if (CWaterLevel::aWaterFineBlockList[x][y] >= 0)
{
float worldY = WATER_START_Y + y * SMALL_SECTOR_SIZE;
@@ -160,7 +212,7 @@ CWaterLevel::Initialise(Const char *pWaterDat)
CVector worldPos = CVector(worldX + i * (SMALL_SECTOR_SIZE / 8), worldY + j * (SMALL_SECTOR_SIZE / 8), ms_aWaterZs[aWaterFineBlockList[x][y]]);
if ((worldPos.x > WORLD_MIN_X && worldPos.x < WORLD_MAX_X) && (worldPos.y > WORLD_MIN_Y && worldPos.y < WORLD_MAX_Y) &&
- (!WaterLevelAccordingToRectangles(worldPos.x, worldPos.y) || TestVisibilityForFineWaterBlocks(worldPos)))
+ (!WaterLevelAccordingToRectangles(worldPos.x, worldPos.y) || TestVisibilityForFineWaterBlocks(worldPos)))
continue;
// at least one point in the tile wasn't blocked, so don't remove water
@@ -210,13 +262,16 @@ CWaterLevel::Initialise(Const char *pWaterDat)
if (hFile > 0)
{
CFileMgr::Write(hFile, (char *)&ms_nNoOfWaterLevels, sizeof(ms_nNoOfWaterLevels));
- CFileMgr::Write(hFile, (char *)ms_aWaterZs, sizeof(ms_aWaterZs));
+ CFileMgr::Write(hFile, (char *)ms_aWaterZs, sizeof(ms_aWaterZs));
CFileMgr::Write(hFile, (char *)ms_aWaterRects, sizeof(ms_aWaterRects));
CFileMgr::Write(hFile, (char *)aWaterBlockList, sizeof(aWaterBlockList));
CFileMgr::Write(hFile, (char *)aWaterFineBlockList, sizeof(aWaterFineBlockList));
CFileMgr::CloseFile(hFile);
}
+
+ // collision is streamed in VC
+ CColStore::RemoveAllCollision();
}
#endif
@@ -226,13 +281,26 @@ CWaterLevel::Initialise(Const char *pWaterDat)
CTxdStore::SetCurrentTxd(slot);
if ( gpWaterTex == nil )
- gpWaterTex = RwTextureRead("water_old", nil);
+ gpWaterTex = RwTextureRead("waterclear256", nil);
gpWaterRaster = RwTextureGetRaster(gpWaterTex);
+ if ( gpWaterEnvTex == nil )
+ gpWaterEnvTex = RwTextureRead("waterreflection2", nil);
+ gpWaterEnvRaster = RwTextureGetRaster(gpWaterEnvTex);
+
+#ifdef PC_WATER
+ if ( gpWaterEnvBaseTex == nil )
+ gpWaterEnvBaseTex = RwTextureRead("sandywater", nil);
+ gpWaterEnvBaseRaster = RwTextureGetRaster(gpWaterEnvBaseTex);
+#endif
+
+ if ( gpWaterWakeTex == nil )
+ gpWaterWakeTex = RwTextureRead("waterwake", nil);
+ gpWaterWakeRaster = RwTextureGetRaster(gpWaterWakeTex);
+
CTxdStore::PopCurrentTxd();
CreateWavyAtomic();
- FreeBoatWakeArray();
printf("Done Initing waterlevels\n");
}
@@ -240,92 +308,154 @@ CWaterLevel::Initialise(Const char *pWaterDat)
void
CWaterLevel::Shutdown()
{
- FreeBoatWakeArray();
DestroyWavyAtomic();
- if ( gpWaterTex != nil )
- {
- RwTextureDestroy(gpWaterTex);
- gpWaterTex = nil;
- }
+#define _DELETE_TEXTURE(t) if ( t ) \
+ { \
+ RwTextureDestroy(t); \
+ t = nil; \
+ }
+
+ _DELETE_TEXTURE(gpWaterTex);
+ _DELETE_TEXTURE(gpWaterEnvTex);
+ _DELETE_TEXTURE(gpWaterWakeTex);
+ _DELETE_TEXTURE(gpWaterEnvBaseTex);
+
+#undef _DELETE_TEXTURE
}
void
CWaterLevel::CreateWavyAtomic()
{
RpGeometry *wavyGeometry;
+ RpGeometry *maskGeometry;
RpMaterial *wavyMaterial;
- RpTriangle *wavyTriangles;
+ RpMaterial *maskMaterial;
+
+ RpTriangle *wavytlist;
+ RpTriangle *masktlist;
+
RpMorphTarget *wavyMorphTarget;
- RwSphere boundingSphere;
+ RpMorphTarget *maskMorphTarget;
+
+ RwSphere boundingSphere;
+
RwV3d *wavyVert;
-
+ RwV3d *wavyNormal;
+
+ RwV3d *maskVert;
+ RwV3d *maskNormal;
+
RwFrame *wavyFrame;
+ RwFrame *maskFrame;
{
- wavyGeometry = RpGeometryCreate(9*9, 8*8*2, rpGEOMETRYTRISTRIP
+ wavyGeometry = RpGeometryCreate(17*17, 512, rpGEOMETRYTRISTRIP
|rpGEOMETRYTEXTURED
|rpGEOMETRYPRELIT
+ |rpGEOMETRYNORMALS
|rpGEOMETRYMODULATEMATERIALCOLOR);
-
- ASSERT(wavyGeometry != nil);
-
+#ifdef PC_WATER
+ RpGeometryAddMorphTarget(wavyGeometry);
+#endif
+ }
+
+ {
+ maskGeometry = RpGeometryCreate(33*33, 2048, rpGEOMETRYTRISTRIP
+ |rpGEOMETRYTEXTURED
+ |rpGEOMETRYPRELIT
+ |rpGEOMETRYNORMALS
+ |rpGEOMETRYMODULATEMATERIALCOLOR);
+#ifdef PC_WATER
+ RpGeometryAddMorphTarget(maskGeometry);
+#endif
}
{
wavyMaterial = RpMaterialCreate();
-
- ASSERT(wavyMaterial != nil);
- ASSERT(gpWaterTex != nil);
-
RpMaterialSetTexture(wavyMaterial, gpWaterTex);
+ RwRGBA watercolor = { 255, 255, 255, 192 };
+ RpMaterialSetColor(wavyMaterial, &watercolor);
}
{
- wavyTriangles = RpGeometryGetTriangles(wavyGeometry);
-
- ASSERT(wavyTriangles != nil);
- /*
- [B] [C]
- ***********
- * * *
- * * *
- * * *
- * * *
- ***********
- [A] [D]
- */
+ maskMaterial = RpMaterialCreate();
+#ifdef PC_WATER
+ RpMaterialSetTexture(maskMaterial, gpWaterEnvBaseTex);
+#else
+ RpMaterialSetTexture(maskMaterial, gpWaterTex);
+#endif
+ RwRGBA watercolor = { 255, 255, 255, 192 };
+ RpMaterialSetColor(maskMaterial, &watercolor);
+ }
+
+ {
+ wavytlist = RpGeometryGetTriangles(wavyGeometry);
- for ( int32 i = 0; i < 8; i++ )
+ for ( int32 i = 0; i < 16; i++ )
{
- for ( int32 j = 0; j < 8; j++ )
- {
+ for ( int32 j = 0; j < 16; j++ )
+ {
+ const RwUInt16 base = (RwUInt16)((16 + 1)*i+j);
+
RpGeometryTriangleSetVertexIndices(wavyGeometry,
- &wavyTriangles[2 * 8*i + 2*j + 0], /*A*/9*i+j+0, /*B*/9*i+j+1, /*C*/9*i+j+9+1);
-
- RpGeometryTriangleSetVertexIndices(wavyGeometry,
- &wavyTriangles[2 * 8*i + 2*j + 1], /*A*/9*i+j+0, /*C*/9*i+j+9+1, /*D*/9*i+j+9 );
+ wavytlist, (RwInt16)base, (RwInt16)(base+1), (RwInt16)(base+16+2));
+
+ RpGeometryTriangleSetVertexIndices(wavyGeometry,
+ (wavytlist+1), (RwInt16)base, (RwInt16)(base+16+2), (RwInt16)(base+16+1));
- RpGeometryTriangleSetMaterial(wavyGeometry, &wavyTriangles[2 * 8*i + 2*j + 0], wavyMaterial);
- RpGeometryTriangleSetMaterial(wavyGeometry, &wavyTriangles[2 * 8*i + 2*j + 1], wavyMaterial);
+ RpGeometryTriangleSetMaterial(wavyGeometry, wavytlist, wavyMaterial);
+
+ RpGeometryTriangleSetMaterial(wavyGeometry, (wavytlist+1), wavyMaterial);
+
+ wavytlist+=2;
}
}
}
+ {
+ masktlist = RpGeometryGetTriangles(maskGeometry);
+
+ for ( int32 i = 0; i < 32; i++ )
+ {
+ for ( int32 j = 0; j < 32; j++ )
+ {
+ const RwUInt16 base = (RwUInt16)((32 + 1)*i+j);
+
+ RpGeometryTriangleSetVertexIndices(maskGeometry,
+ masktlist, (RwInt16)base, (RwInt16)(base+1), (RwInt16)(base+32+2));
+
+ RpGeometryTriangleSetVertexIndices(maskGeometry,
+ (masktlist+1), (RwInt16)base, (RwInt16)(base+32+2), (RwInt16)(base+32+1));
+
+ RpGeometryTriangleSetMaterial(maskGeometry, masktlist, maskMaterial);
+
+ RpGeometryTriangleSetMaterial(maskGeometry, (masktlist+1), maskMaterial);
+
+ masktlist+=2;
+ }
+ }
+ }
{
wavyMorphTarget = RpGeometryGetMorphTarget(wavyGeometry, 0);
- ASSERT(wavyMorphTarget != nil);
- wavyVert = RpMorphTargetGetVertices(wavyMorphTarget);
- ASSERT(wavyVert != nil);
+ wavyVert = RpMorphTargetGetVertices(wavyMorphTarget);
+ wavyNormal = RpMorphTargetGetVertexNormals(wavyMorphTarget);
- for ( int32 i = 0; i < 9; i++ )
+ for ( int32 i = 0; i < 17; i++ )
{
- for ( int32 j = 0; j < 9; j++ )
+ for ( int32 j = 0; j < 17; j++ )
{
- wavyVert[9*i+j].x = (float)i * 4.0f;
- wavyVert[9*i+j].y = (float)j * 4.0f;
- wavyVert[9*i+j].z = 0.0f;
+ (*wavyVert).x = (float)i * 2.0f;
+ (*wavyVert).y = (float)j * 2.0f;
+ (*wavyVert).z = 0.0f;
+
+ (*wavyNormal).x = 0.0f;
+ (*wavyNormal).y = 0.0f;
+ (*wavyNormal).z = 1.0f;
+
+ wavyVert++;
+ wavyNormal++;
}
}
@@ -334,31 +464,80 @@ CWaterLevel::CreateWavyAtomic()
RpGeometryUnlock(wavyGeometry);
}
-
{
- wavyFrame = RwFrameCreate();
- ASSERT( wavyFrame != nil );
+ maskMorphTarget = RpGeometryGetMorphTarget(maskGeometry, 0);
+ maskVert = RpMorphTargetGetVertices(maskMorphTarget);
+ maskNormal = RpMorphTargetGetVertexNormals(maskMorphTarget);
- ms_pWavyAtomic = RpAtomicCreate();
- ASSERT( ms_pWavyAtomic != nil );
+ for ( int32 i = 0; i < 33; i++ )
+ {
+ for ( int32 j = 0; j < 33; j++ )
+ {
+ (*maskVert).x = (float)i * 2.0f;
+ (*maskVert).y = (float)j * 2.0f;
+ (*maskVert).z = 0.0f;
+
+ (*maskNormal).x = 0.0f;
+ (*maskNormal).y = 0.0f;
+ (*maskNormal).z = 1.0f;
+
+ maskVert++;
+ maskNormal++;
+ }
+ }
+ RpMorphTargetCalcBoundingSphere(maskMorphTarget, &boundingSphere);
+ RpMorphTargetSetBoundingSphere(maskMorphTarget, &boundingSphere);
+ RpGeometryUnlock(maskGeometry);
+ }
+
+ {
+ wavyFrame = RwFrameCreate();
+ ms_pWavyAtomic = RpAtomicCreate();
RpAtomicSetGeometry(ms_pWavyAtomic, wavyGeometry, 0);
RpAtomicSetFrame(ms_pWavyAtomic, wavyFrame);
RpMaterialDestroy(wavyMaterial);
RpGeometryDestroy(wavyGeometry);
}
+
+ {
+ maskFrame = RwFrameCreate();
+ ms_pMaskAtomic = RpAtomicCreate();
+ RpAtomicSetGeometry(ms_pMaskAtomic, maskGeometry, 0);
+ RpAtomicSetFrame(ms_pMaskAtomic, maskFrame);
+ RpMaterialDestroy(maskMaterial);
+ RpGeometryDestroy(maskGeometry);
+ }
+
+ static RwFrame *wakeEnvFrame;
+
+ if ( wakeEnvFrame == nil )
+ {
+ wakeEnvFrame = RwFrameCreate();
+ RwMatrixSetIdentity(RwFrameGetMatrix(wakeEnvFrame));
+ RwFrameUpdateObjects(wakeEnvFrame);
+ }
+
+ RpMatFXMaterialSetEffects(maskMaterial, rpMATFXEFFECTENVMAP);
+ RpMatFXMaterialSetupEnvMap(maskMaterial, gpWaterEnvTex, wakeEnvFrame, TRUE, fEnvScale);
+ RpMatFXAtomicEnableEffects(ms_pMaskAtomic);
}
void
CWaterLevel::DestroyWavyAtomic()
{
- RwFrame *frame;
-
- frame = RpAtomicGetFrame(ms_pWavyAtomic);
-
- RpAtomicDestroy(ms_pWavyAtomic);
+#define _DELETE_ATOMIC(a) \
+ { \
+ RwFrame *frame; \
+ frame = RpAtomicGetFrame(a); \
+ RpAtomicDestroy(a); \
+ RwFrameDestroy(frame); \
+ }
+
+ _DELETE_ATOMIC(ms_pWavyAtomic);
+ _DELETE_ATOMIC(ms_pMaskAtomic);
- RwFrameDestroy(frame);
+#undef _DELETE_ATOMIC
}
#ifndef MASTER
@@ -511,7 +690,7 @@ CWaterLevel::RemoveIsolatedWater()
{
for (int32 y = 0; y < MAX_SMALL_SECTORS; y++)
{
- if (aWaterFineBlockList[x][y] >= 0 && !isConnected[x][y] && ms_aWaterZs[aWaterFineBlockList[x][y]] == 0.0f)
+ if (aWaterFineBlockList[x][y] >= 0 && !isConnected[x][y] && ms_aWaterZs[aWaterFineBlockList[x][y]] == 6.0f)
{
numRemoved++;
aWaterFineBlockList[x][y] = NO_WATER;
@@ -528,11 +707,13 @@ CWaterLevel::RemoveIsolatedWater()
bool
CWaterLevel::GetWaterLevel(float fX, float fY, float fZ, float *pfOutLevel, bool bDontCheckZ)
{
- int32 x = WATER_HUGE_X(fX);
- int32 y = WATER_HUGE_Y(fY);
-
- ASSERT( x >= 0 && x < HUGE_SECTOR_SIZE );
- ASSERT( y >= 0 && y < HUGE_SECTOR_SIZE );
+ int32 x = WATER_TO_SMALL_SECTOR_X(fX + WATER_X_OFFSET);
+ int32 y = WATER_TO_SMALL_SECTOR_Y(fY);
+
+#ifdef FIX_BUGS
+ if ( x < 0 || x >= MAX_SMALL_SECTORS ) return false;
+ if ( y < 0 || y >= MAX_SMALL_SECTORS ) return false;
+#endif
int8 nBlock = aWaterFineBlockList[x][y];
@@ -546,12 +727,13 @@ CWaterLevel::GetWaterLevel(float fX, float fY, float fZ, float *pfOutLevel, bool
float fWave = Sin
(
- /*( WATER_UNSIGN_Y(fY) - float(y) * MAX_HUGE_SECTORS + WATER_UNSIGN_X(fX) - float(x) * MAX_HUGE_SECTORS )*/ // VC
- (float)( ((int32)fX & (MAX_HUGE_SECTORS-1)) + ((int32)fY & (MAX_HUGE_SECTORS-1)) )
- * (TWOPI / MAX_HUGE_SECTORS ) + fAngle
+ ( WATER_UNSIGN_Y(fY) - y*SMALL_SECTOR_SIZE
+ + WATER_UNSIGN_X(fX + WATER_X_OFFSET) - x*SMALL_SECTOR_SIZE )
+
+ * (TWOPI / SMALL_SECTOR_SIZE ) + fAngle
);
- float fWindFactor = CWeather::Wind * 0.7f + 0.3f;
+ float fWindFactor = CWeather::WindClipped * 0.4f + 0.2f;
*pfOutLevel += fWave * fWindFactor;
@@ -567,11 +749,13 @@ CWaterLevel::GetWaterLevel(float fX, float fY, float fZ, float *pfOutLevel, bool
bool
CWaterLevel::GetWaterLevelNoWaves(float fX, float fY, float fZ, float *pfOutLevel)
{
- int32 x = WATER_HUGE_X(fX);
- int32 y = WATER_HUGE_Y(fY);
-
- ASSERT( x >= 0 && x < HUGE_SECTOR_SIZE );
- ASSERT( y >= 0 && y < HUGE_SECTOR_SIZE );
+ int32 x = WATER_TO_SMALL_SECTOR_X(fX + WATER_X_OFFSET);
+ int32 y = WATER_TO_SMALL_SECTOR_Y(fY);
+
+#ifdef FIX_BUGS
+ if ( x < 0 || x >= MAX_SMALL_SECTORS ) return false;
+ if ( y < 0 || y >= MAX_SMALL_SECTORS ) return false;
+#endif
int8 nBlock = aWaterFineBlockList[x][y];
@@ -584,18 +768,49 @@ CWaterLevel::GetWaterLevelNoWaves(float fX, float fY, float fZ, float *pfOutLeve
return true;
}
-inline float
-_GetWaterDrawDist()
+float
+CWaterLevel::GetWaterWavesOnly(short x, short y)
{
- // if z less then 15.0f return 1200.0f
- if ( TheCamera.GetPosition().z < 15.0f )
- return 1200.0f;
+ float fAngle = (CTimer::GetTimeInMilliseconds() & 4095) * (TWOPI / 4096.0f);
+
+ float fWindFactor = CWeather::WindClipped * 0.7f + 0.3f;
+
+ float fWave = Sin( float(float(4 * y + 4 * x) * (TWOPI / SMALL_SECTOR_SIZE )) + fAngle );
+
+ return fWave * fWindFactor;
+}
+
+CVector
+CWaterLevel::GetWaterNormal(float fX, float fY)
+{
+ //TODO: BUG ? no x offset
+
+ int32 x = WATER_TO_SMALL_SECTOR_X(fX);
+ int32 y = WATER_TO_SMALL_SECTOR_Y(fY);
+
+ float fAngle = (CTimer::GetTimeInMilliseconds() & 4095) * (TWOPI / 4096.0f);
+ float fWindFactor = CWeather::WindClipped * 0.4f + 0.2f;
+
+ float _fWave = (WATER_UNSIGN_Y(fY) - y*SMALL_SECTOR_SIZE + WATER_UNSIGN_X(fX) - x*SMALL_SECTOR_SIZE)
+ * (TWOPI / SMALL_SECTOR_SIZE ) + fAngle;
- // if z greater then 60.0f return 2000.0f;
- if ( TheCamera.GetPosition().z > 60.0f )
- return 2000.0f;
+ CVector vA(1.0f, 0.0f, fWindFactor * (TWOPI / SMALL_SECTOR_SIZE ) * Cos(_fWave));
+ CVector vB(0.0f, 1.0f, fWindFactor * (TWOPI / SMALL_SECTOR_SIZE ) * Cos(_fWave));
+
+ CVector norm = CrossProduct(vA, vB);
+
+ norm.Normalise();
+
+ return norm;
+}
- return (TheCamera.GetPosition().z + -15.0f) * 800.0f / 45.0f + 1200.0f;
+
+inline float
+_GetWaterDrawDist()
+{
+ if ( TheCamera.GetPosition().z < 15.0f ) return 1200.0f;
+ if ( TheCamera.GetPosition().z > 60.0f ) return 2000.0f;
+ return ( TheCamera.GetPosition().z + -15.0f ) * 800.0f / 45.0f + 1200.0f;
}
inline float
@@ -629,6 +844,49 @@ _GetCamBounds(bool *bUseCamStartY, bool *bUseCamEndY, bool *bUseCamStartX, bool
}
}
+
+inline bool
+_IsColideWithBlock(int32 x, int32 y, int32 &block)
+{
+ block = CWaterLevel::aWaterFineBlockList[x + 0][y + 0];
+ if (block >= 0)
+ return true;
+
+ block = CWaterLevel::aWaterFineBlockList[x + 0][y + 1];
+ if (block >= 0)
+ {
+ block = CWaterLevel::aWaterFineBlockList[x + 0][y + 2];
+ if (block >= 0)
+ return true;
+ }
+
+ block = CWaterLevel::aWaterFineBlockList[x + 1][y + 0];
+ if (block >= 0)
+ return true;
+
+ block = CWaterLevel::aWaterFineBlockList[x + 1][y + 1];
+ if (block >= 0)
+ {
+ block = CWaterLevel::aWaterFineBlockList[x + 1][y + 2];
+ if (block >= 0)
+ return true;
+ }
+
+ block = CWaterLevel::aWaterFineBlockList[x + 2][y + 0];
+ if (block >= 0)
+ return true;
+
+ block = CWaterLevel::aWaterFineBlockList[x + 2][y + 1];
+ if (block >= 0)
+ {
+ block = CWaterLevel::aWaterFineBlockList[x + 2][y + 2];
+ if (block >= 0)
+ return true;
+ }
+
+ return false;
+}
+
inline float
SectorRadius(float fSize)
{
@@ -643,71 +901,91 @@ CWaterLevel::RenderWater()
if (gbDontRenderWater)
return;
#endif
- PUSH_RENDERGROUP("CWaterLevel::RenderWater");
bool bUseCamEndX = false;
bool bUseCamStartY = false;
bool bUseCamStartX = false;
bool bUseCamEndY = false;
- float fWavySectorMaxRenderDist = _GetWavyDrawDist();
- float fWavySectorMaxRenderDistSqr = SQR(fWavySectorMaxRenderDist);
+ if ( !CGame::CanSeeWaterFromCurrArea() )
+ return;
_GetCamBounds(&bUseCamStartY, &bUseCamEndY, &bUseCamStartX, &bUseCamEndX);
float fHugeSectorMaxRenderDist = _GetWaterDrawDist();
float fHugeSectorMaxRenderDistSqr = SQR(fHugeSectorMaxRenderDist);
- float windAddUV = CWeather::Wind * 0.0015f + 0.0005f;
+ float windAddUV = CWeather::WindClipped * 0.0005f + 0.0006f;
+ float fAngle = (CTimer::GetTimeInMilliseconds() & 4095) * (TWOPI / 4096.0f);
if ( !CTimer::GetIsPaused() )
{
-#ifdef FIX_BUGS
- TEXTURE_ADDU += (CGeneral::GetRandomNumberInRange(-0.0005f, 0.0005f) + windAddUV) * CTimer::GetTimeStepFix();
- TEXTURE_ADDV += (CGeneral::GetRandomNumberInRange(-0.0005f, 0.0005f) + windAddUV) * CTimer::GetTimeStepFix();
-#else
- TEXTURE_ADDU += CGeneral::GetRandomNumberInRange(-0.0005f, 0.0005f) + windAddUV;
- TEXTURE_ADDV += CGeneral::GetRandomNumberInRange(-0.0005f, 0.0005f) + windAddUV;
-#endif
+ TEXTURE_ADDU += windAddUV;
+ TEXTURE_ADDV += windAddUV;
+
+ _TEXTURE_MASK_ADDU += Sin(fAngle) * 0.0005f + 1.1f * windAddUV;
+ _TEXTURE_MASK_ADDV -= Cos(fAngle * 1.3f) * 0.0005f + 1.2f * windAddUV;
+
+ _TEXTURE_WAKE_ADDU -= Sin(fAngle) * 0.0003f + windAddUV;
+ _TEXTURE_WAKE_ADDV += Cos(fAngle * 0.7f) * 0.0003f + windAddUV;
}
+ if ( _TEXTURE_MASK_ADDU >= 1.0f )
+ _TEXTURE_MASK_ADDU = 0.0f;
+ if ( _TEXTURE_MASK_ADDV >= 1.0f )
+ _TEXTURE_MASK_ADDV = 0.0f;
+
+ if ( _TEXTURE_WAKE_ADDU >= 1.0f )
+ _TEXTURE_WAKE_ADDU = 0.0f;
+ if ( _TEXTURE_WAKE_ADDV >= 1.0f )
+ _TEXTURE_WAKE_ADDV = 0.0f;
+
if ( TEXTURE_ADDU >= 1.0f )
TEXTURE_ADDU = 0.0f;
if ( TEXTURE_ADDV >= 1.0f )
TEXTURE_ADDV = 0.0f;
- WavesCalculatedThisFrame = false;
+#ifdef PC_WATER
+ _fWaterZOffset = CWeather::WindClipped * 0.5f + 0.25f;
+#endif
RwRGBA color = { 0, 0, 0, 255 };
-
- color.red = uint32((CTimeCycle::GetDirectionalRed() * 0.5f + CTimeCycle::GetAmbientRed() ) * 255.0f);
- color.green = uint32((CTimeCycle::GetDirectionalGreen() * 0.5f + CTimeCycle::GetAmbientGreen()) * 255.0f);
- color.blue = uint32((CTimeCycle::GetDirectionalBlue() * 0.5f + CTimeCycle::GetAmbientBlue() ) * 255.0f);
+
+ color.red = CTimeCycle::GetWaterRed();
+ color.green = CTimeCycle::GetWaterGreen();
+ color.blue = CTimeCycle::GetWaterBlue();
+
+#ifndef PC_WATER
+ RwRGBA colorUnderwater = { 0, 0, 0, 255 };
+ colorUnderwater.red = (uint32)(0.8f * (float)colorUnderwater.red);
+ colorUnderwater.green = (uint32)(0.8f * (float)colorUnderwater.green);
+ colorUnderwater.blue = (uint32)(0.8f * (float)colorUnderwater.blue);
+#endif
TempBufferVerticesStored = 0;
TempBufferIndicesStored = 0;
+
+#ifndef PC_WATER
+ WavesCalculatedThisFrame = false;
+#endif
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)gpWaterRaster);
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void *)TRUE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDONE);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDZERO);
- CVector2D camPos
- (
- TheCamera.GetPosition().x,
- TheCamera.GetPosition().y
- );
+ CVector2D camPos(TheCamera.GetPosition().x, TheCamera.GetPosition().y);
- int32 nStartX = WATER_TO_HUGE_SECTOR_X(camPos.x - fHugeSectorMaxRenderDist);
- int32 nEndX = WATER_TO_HUGE_SECTOR_X(camPos.x + fHugeSectorMaxRenderDist) + 1;
+ int32 nStartX = WATER_TO_HUGE_SECTOR_X(camPos.x - fHugeSectorMaxRenderDist + WATER_X_OFFSET);
+ int32 nEndX = WATER_TO_HUGE_SECTOR_X(camPos.x + fHugeSectorMaxRenderDist + WATER_X_OFFSET) + 1;
int32 nStartY = WATER_TO_HUGE_SECTOR_Y(camPos.y - fHugeSectorMaxRenderDist);
int32 nEndY = WATER_TO_HUGE_SECTOR_Y(camPos.y + fHugeSectorMaxRenderDist) + 1;
-
+
if ( bUseCamStartX )
- nStartX = WATER_TO_HUGE_SECTOR_X(camPos.x);
+ nStartX = WATER_TO_HUGE_SECTOR_X(camPos.x + WATER_X_OFFSET);
if ( bUseCamEndX )
- nEndX = WATER_TO_HUGE_SECTOR_X(camPos.x);
+ nEndX = WATER_TO_HUGE_SECTOR_X(camPos.x + WATER_X_OFFSET);
if ( bUseCamStartY )
nStartY = WATER_TO_HUGE_SECTOR_Y(camPos.y);
if ( bUseCamEndY )
@@ -727,7 +1005,276 @@ CWaterLevel::RenderWater()
|| aWaterBlockList[2*x+0][2*y+1] >= 0
|| aWaterBlockList[2*x+1][2*y+1] >= 0 )
{
- float fX = WATER_FROM_HUGE_SECTOR_X(x);
+ float fX = WATER_FROM_HUGE_SECTOR_X(x) - WATER_X_OFFSET;
+ float fY = WATER_FROM_HUGE_SECTOR_Y(y);
+
+ CVector2D vecHugeSectorCentre(fX + HUGE_SECTOR_SIZE/2,fY + HUGE_SECTOR_SIZE/2);
+
+ float fHugeSectorDistToCamSqr = (camPos - vecHugeSectorCentre).MagnitudeSqr();
+
+ if ( fHugeSectorMaxRenderDistSqr > fHugeSectorDistToCamSqr )
+ {
+ if ( TheCamera.IsSphereVisible(CVector(vecHugeSectorCentre.x, vecHugeSectorCentre.y, 0.0f), SectorRadius(HUGE_SECTOR_SIZE)) )
+ {
+#ifndef PC_WATER
+ WavesCalculatedThisFrame = true;
+#endif
+
+
+ float fZ;
+
+ if ( aWaterBlockList[2*x+0][2*y+0] >= 0 )
+ fZ = ms_aWaterZs[ aWaterBlockList[2*x+0][2*y+0] ];
+
+ if ( aWaterBlockList[2*x+1][2*y+0] >= 0 )
+ fZ = ms_aWaterZs[ aWaterBlockList[2*x+1][2*y+0] ];
+
+ if ( aWaterBlockList[2*x+0][2*y+1] >= 0 )
+ fZ = ms_aWaterZs[ aWaterBlockList[2*x+0][2*y+1] ];
+
+ if ( aWaterBlockList[2*x+1][2*y+1] >= 0 )
+ fZ = ms_aWaterZs[ aWaterBlockList[2*x+1][2*y+1] ];
+
+ if ( fHugeSectorDistToCamSqr >= SQR(500.0f) )
+ {
+ RenderOneFlatHugeWaterPoly(fX, fY, fZ, color);
+ }
+ else
+ {
+#ifndef PC_WATER
+ if (m_bRenderSeaBed)
+ RenderOneSlopedUnderWaterPoly(fX, fY, fZ, colorUnderwater);
+#endif
+ // see RenderTransparentWater()
+ ;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /*
+ ----------- ---------------------- ----------------------
+ | [N] | | [ EndY ] | | [ top ] |
+ | | | | | |
+ |[W] [0] [E]| |[StartX] [] [ EndX ]| |[ left ] [] [ right]|
+ | | | | | |
+ | [S] | | [StartY] | | [bottom] |
+ ----------- ---------------------- ----------------------
+
+
+ [S] [StartY] [bottom]
+ [N] [EndY] [top]
+ [W] [StartX] [left]
+ [E] [EndX] [right]
+
+ [S] -> [N] && [W] -> [E]
+ bottom -> top && left -> right
+ */
+
+ for ( int32 x = 0; x < 26; x++ )
+ {
+ for ( int32 y = 0; y < 5; y++ )
+ {
+ float fX = WATER_SIGN_X(float(x) * EXTRAHUGE_SECTOR_SIZE) - 1280.0f - WATER_X_OFFSET;
+ float fY = WATER_SIGN_Y(float(y) * EXTRAHUGE_SECTOR_SIZE) - 1280.0f;
+
+ if ( !bUseCamStartY )
+ {
+ CVector2D vecExtraHugeSectorCentre(fX + EXTRAHUGE_SECTOR_SIZE/2, fY + EXTRAHUGE_SECTOR_SIZE/2);
+
+ float fCamDistToSector = (vecExtraHugeSectorCentre - camPos).Magnitude();
+
+ if ( fCamDistToSector < fHugeSectorMaxRenderDistSqr )
+ {
+ if ( TheCamera.IsSphereVisible(CVector(vecExtraHugeSectorCentre.x, vecExtraHugeSectorCentre.y, 0.0f), SectorRadius(EXTRAHUGE_SECTOR_SIZE)) )
+ {
+ RenderOneFlatExtraHugeWaterPoly(
+ vecExtraHugeSectorCentre.x - EXTRAHUGE_SECTOR_SIZE/2,
+ vecExtraHugeSectorCentre.y - EXTRAHUGE_SECTOR_SIZE/2,
+ 0.0f,
+ color);
+ }
+ }
+ }
+
+ if ( !bUseCamEndY )
+ {
+ CVector2D vecExtraHugeSectorCentre(fX + EXTRAHUGE_SECTOR_SIZE/2, -(fY + EXTRAHUGE_SECTOR_SIZE/2));
+
+ float fCamDistToSector = (vecExtraHugeSectorCentre - camPos).Magnitude();
+
+ if ( fCamDistToSector < fHugeSectorMaxRenderDistSqr )
+ {
+ if ( TheCamera.IsSphereVisible(CVector(vecExtraHugeSectorCentre.x, vecExtraHugeSectorCentre.y, 0.0f), SectorRadius(EXTRAHUGE_SECTOR_SIZE)) )
+ {
+ RenderOneFlatExtraHugeWaterPoly(
+ vecExtraHugeSectorCentre.x - EXTRAHUGE_SECTOR_SIZE/2,
+ vecExtraHugeSectorCentre.y - EXTRAHUGE_SECTOR_SIZE/2,
+ 0.0f,
+ color);
+ }
+ }
+ }
+ }
+ }
+
+ for ( int32 y = 5; y < 21; y++ )
+ {
+ for ( int32 x = 0; x < 5; x++ )
+ {
+ float fX = WATER_SIGN_X(float(x) * EXTRAHUGE_SECTOR_SIZE) - 1280.0f - WATER_X_OFFSET;
+ float fX2 = WATER_SIGN_X(float(x) * EXTRAHUGE_SECTOR_SIZE) - 1280.0f + WATER_X_OFFSET;
+ float fY = WATER_SIGN_Y(float(y) * EXTRAHUGE_SECTOR_SIZE) - 1280.0f;
+
+ if ( !bUseCamStartX )
+ {
+ CVector2D vecExtraHugeSectorCentre(fX + EXTRAHUGE_SECTOR_SIZE/2, fY + EXTRAHUGE_SECTOR_SIZE/2);
+
+ float fCamDistToSector = (vecExtraHugeSectorCentre - camPos).Magnitude();
+
+ if ( fCamDistToSector < fHugeSectorMaxRenderDistSqr )
+ {
+ if ( TheCamera.IsSphereVisible(CVector(vecExtraHugeSectorCentre.x, vecExtraHugeSectorCentre.y, 0.0f), SectorRadius(EXTRAHUGE_SECTOR_SIZE)) )
+ {
+ RenderOneFlatExtraHugeWaterPoly(
+ vecExtraHugeSectorCentre.x - EXTRAHUGE_SECTOR_SIZE/2,
+ vecExtraHugeSectorCentre.y - EXTRAHUGE_SECTOR_SIZE/2,
+ 0.0f,
+ color);
+ }
+ }
+ }
+
+ if ( !bUseCamEndX )
+ {
+ CVector2D vecExtraHugeSectorCentre(-(fX2 + EXTRAHUGE_SECTOR_SIZE/2), fY + EXTRAHUGE_SECTOR_SIZE/2);
+
+ float fCamDistToSector = (vecExtraHugeSectorCentre - camPos).Magnitude();
+
+ if ( fCamDistToSector < fHugeSectorMaxRenderDistSqr )
+ {
+ if ( TheCamera.IsSphereVisible(CVector(vecExtraHugeSectorCentre.x, vecExtraHugeSectorCentre.x, 0.0f), SectorRadius(EXTRAHUGE_SECTOR_SIZE)) )
+ {
+ RenderOneFlatExtraHugeWaterPoly(
+ vecExtraHugeSectorCentre.x - EXTRAHUGE_SECTOR_SIZE/2,
+ vecExtraHugeSectorCentre.y - EXTRAHUGE_SECTOR_SIZE/2,
+ 0.0f,
+ color);
+ }
+ }
+ }
+ }
+ }
+
+ RenderAndEmptyRenderBuffer();
+
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA);
+
+ if ( WavesCalculatedThisFrame )
+ {
+ RenderSeaBirds();
+ RenderShipsOnHorizon();
+ CParticle::HandleShipsAtHorizonStuff();
+ HandleBeachToysStuff();
+ }
+
+ if ( _bSeaLife )
+ HandleSeaLifeForms();
+
+ DefinedState();
+}
+
+
+void
+CWaterLevel::RenderTransparentWater(void)
+{
+ bool bUseCamEndX = false;
+ bool bUseCamStartY = false;
+
+ bool bUseCamStartX = false;
+ bool bUseCamEndY = false;
+
+ _bSeaLife = false;
+
+ if ( !CGame::CanSeeWaterFromCurrArea() )
+ return;
+
+ PUSH_RENDERGROUP("CWaterLevel::RenderTransparentWater");
+
+ float fWaterDrawDist = _GetWavyDrawDist();
+ float fWaterDrawDistLarge = fWaterDrawDist + 90.0f;
+ float fWavySectorMaxRenderDistSqr = SQR(fWaterDrawDist);
+
+ _GetCamBounds(&bUseCamStartY, &bUseCamEndY, &bUseCamStartX, &bUseCamEndX);
+
+ float fHugeSectorMaxRenderDist = _GetWaterDrawDist();
+ float fHugeSectorMaxRenderDistSqr = SQR(fHugeSectorMaxRenderDist);
+
+ RenderBoatWakes();
+
+ RwRGBA color;
+
+ color.red = CTimeCycle::GetWaterRed();
+ color.green = CTimeCycle::GetWaterGreen();
+ color.blue = CTimeCycle::GetWaterBlue();
+ color.alpha = 255;
+
+ RwRGBA colorTrans;
+
+ colorTrans.red = CTimeCycle::GetWaterRed();
+ colorTrans.green = CTimeCycle::GetWaterGreen();
+ colorTrans.blue = CTimeCycle::GetWaterBlue();
+ colorTrans.alpha = CTimeCycle::GetWaterAlpha();
+
+ TempBufferVerticesStored = 0;
+ TempBufferIndicesStored = 0;
+
+#ifndef PC_WATER
+ WavesCalculatedThisFrame = false;
+#endif
+
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)gpWaterRaster);
+#ifndef PC_WATER
+ RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void *)TRUE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA);
+#endif
+
+ CVector2D camPos(TheCamera.GetPosition().x, TheCamera.GetPosition().y);
+
+ int32 nStartX = WATER_TO_HUGE_SECTOR_X(camPos.x - fHugeSectorMaxRenderDist + WATER_X_OFFSET);
+ int32 nEndX = WATER_TO_HUGE_SECTOR_X(camPos.x + fHugeSectorMaxRenderDist + WATER_X_OFFSET) + 1;
+ int32 nStartY = WATER_TO_HUGE_SECTOR_Y(camPos.y - fHugeSectorMaxRenderDist );
+ int32 nEndY = WATER_TO_HUGE_SECTOR_Y(camPos.y + fHugeSectorMaxRenderDist ) + 1;
+
+ if ( bUseCamStartX )
+ nStartX = WATER_TO_HUGE_SECTOR_X(camPos.x + WATER_X_OFFSET);
+ if ( bUseCamEndX )
+ nEndX = WATER_TO_HUGE_SECTOR_X(camPos.x + WATER_X_OFFSET);
+ if ( bUseCamStartY )
+ nStartY = WATER_TO_HUGE_SECTOR_Y(camPos.y );
+ if ( bUseCamEndY )
+ nEndY = WATER_TO_HUGE_SECTOR_Y(camPos.y );
+
+ nStartX = Clamp(nStartX, 0, MAX_HUGE_SECTORS - 1);
+ nEndX = Clamp(nEndX, 0, MAX_HUGE_SECTORS - 1);
+ nStartY = Clamp(nStartY, 0, MAX_HUGE_SECTORS - 1);
+ nEndY = Clamp(nEndY, 0, MAX_HUGE_SECTORS - 1);
+
+
+ for ( int32 x = nStartX; x <= nEndX; x++ )
+ {
+ for ( int32 y = nStartY; y <= nEndY; y++ )
+ {
+ if ( aWaterBlockList[2*x+0][2*y+0] >= 0
+ || aWaterBlockList[2*x+1][2*y+0] >= 0
+ || aWaterBlockList[2*x+0][2*y+1] >= 0
+ || aWaterBlockList[2*x+1][2*y+1] >= 0 )
+ {
+ float fX = WATER_FROM_HUGE_SECTOR_X(x) - WATER_X_OFFSET;
float fY = WATER_FROM_HUGE_SECTOR_Y(y);
CVector2D vecHugeSectorCentre
@@ -737,28 +1284,15 @@ CWaterLevel::RenderWater()
);
float fHugeSectorDistToCamSqr = (camPos - vecHugeSectorCentre).MagnitudeSqr();
-
+
if ( fHugeSectorMaxRenderDistSqr > fHugeSectorDistToCamSqr )
{
if ( TheCamera.IsSphereVisible(CVector(vecHugeSectorCentre.x, vecHugeSectorCentre.y, 0.0f), SectorRadius(HUGE_SECTOR_SIZE)) )
{
- if ( fHugeSectorDistToCamSqr >= SQR(500.0f) /*fHugeSectorNearDist*/ )
+ if ( fHugeSectorDistToCamSqr >= SQR(500.0f) )
{
- float fZ;
-
- if ( aWaterBlockList[2*x+0][2*y+0] >= 0 )
- fZ = ms_aWaterZs[ aWaterBlockList[2*x+0][2*y+0] ];
-
- if ( aWaterBlockList[2*x+1][2*y+0] >= 0 )
- fZ = ms_aWaterZs[ aWaterBlockList[2*x+1][2*y+0] ];
-
- if ( aWaterBlockList[2*x+0][2*y+1] >= 0 )
- fZ = ms_aWaterZs[ aWaterBlockList[2*x+0][2*y+1] ];
-
- if ( aWaterBlockList[2*x+1][2*y+1] >= 0 )
- fZ = ms_aWaterZs[ aWaterBlockList[2*x+1][2*y+1] ];
-
- RenderOneFlatHugeWaterPoly(fX, fY, fZ, color);
+ // see RenderWater()
+ ;
}
else
{
@@ -768,20 +1302,16 @@ CWaterLevel::RenderWater()
{
if ( aWaterBlockList[x2][y2] >= 0 )
{
- float fLargeX = WATER_FROM_LARGE_SECTOR_X(x2);
+ float fLargeX = WATER_FROM_LARGE_SECTOR_X(x2) - WATER_X_OFFSET;
float fLargeY = WATER_FROM_LARGE_SECTOR_Y(y2);
- CVector2D vecLargeSectorCentre
- (
- fLargeX + LARGE_SECTOR_SIZE/2,
- fLargeY + LARGE_SECTOR_SIZE/2
- );
+ CVector2D vecLargeSectorCentre(fLargeX + LARGE_SECTOR_SIZE/2, fLargeY + LARGE_SECTOR_SIZE/2);
float fLargeSectorDistToCamSqr = (camPos - vecLargeSectorCentre).MagnitudeSqr();
if ( fLargeSectorDistToCamSqr < fHugeSectorMaxRenderDistSqr )
{
- if ( TheCamera.IsSphereVisible(CVector(vecLargeSectorCentre.x, vecLargeSectorCentre.y, 0.0f), SectorRadius(LARGE_SECTOR_SIZE)) ) //90.879997f,
+ if ( TheCamera.IsSphereVisible(CVector(vecLargeSectorCentre.x, vecLargeSectorCentre.y, 0.0f), SectorRadius(LARGE_SECTOR_SIZE)) )
{
// Render four small(32x32) sectors, or one large(64x64).
@@ -794,9 +1324,13 @@ CWaterLevel::RenderWater()
// ---------
// [S]
//
-
- if ( fLargeSectorDistToCamSqr < SQR(176.0f) )
- {
+
+ float fLargeSectorDrawDistSqr = SQR((fWaterDrawDistLarge + 16.0f));
+
+ if ( fLargeSectorDistToCamSqr < fLargeSectorDrawDistSqr )
+ {
+ _bSeaLife = true;
+
float fZ;
// WS
@@ -805,19 +1339,15 @@ CWaterLevel::RenderWater()
float fSmallX = fLargeX;
float fSmallY = fLargeY;
- CVector2D vecSmallSectorCentre
- (
- fSmallX + SMALL_SECTOR_SIZE/2,
- fSmallY + SMALL_SECTOR_SIZE/2
- );
+ CVector2D vecSmallSectorCentre(fSmallX + SMALL_SECTOR_SIZE/2, fSmallY + SMALL_SECTOR_SIZE/2);
float fSmallSectorDistToCamSqr = (camPos - vecSmallSectorCentre).MagnitudeSqr();
fZ = ms_aWaterZs[ aWaterFineBlockList[2*x2+0][2*y2+0] ];
if ( fSmallSectorDistToCamSqr < fWavySectorMaxRenderDistSqr )
- RenderOneWavySector(fSmallX, fSmallY, fZ, color);
+ RenderOneWavySector(fSmallX, fSmallY, fZ, colorTrans);
else
- RenderOneFlatSmallWaterPoly(fSmallX, fSmallY, fZ, color);
+ RenderOneFlatSmallWaterPolyBlended(fSmallX, fSmallY, fZ, camPos.x, camPos.y, color, colorTrans, fWaterDrawDist);
}
// SE
@@ -826,19 +1356,15 @@ CWaterLevel::RenderWater()
float fSmallX = fLargeX + (LARGE_SECTOR_SIZE/2);
float fSmallY = fLargeY;
- CVector2D vecSmallSectorCentre
- (
- fSmallX + SMALL_SECTOR_SIZE/2,
- fSmallY + SMALL_SECTOR_SIZE/2
- );
+ CVector2D vecSmallSectorCentre(fSmallX + SMALL_SECTOR_SIZE/2, fSmallY + SMALL_SECTOR_SIZE/2);
float fSmallSectorDistToCamSqr = (camPos - vecSmallSectorCentre).MagnitudeSqr();
fZ = ms_aWaterZs[ aWaterFineBlockList[2*x2+1][2*y2+0] ];
if ( fSmallSectorDistToCamSqr < fWavySectorMaxRenderDistSqr )
- RenderOneWavySector(fSmallX, fSmallY, fZ, color);
+ RenderOneWavySector(fSmallX, fSmallY, fZ, colorTrans);
else
- RenderOneFlatSmallWaterPoly(fSmallX, fSmallY, fZ, color);
+ RenderOneFlatSmallWaterPolyBlended(fSmallX, fSmallY, fZ, camPos.x, camPos.y, color, colorTrans, fWaterDrawDist);
}
// WN
@@ -847,19 +1373,15 @@ CWaterLevel::RenderWater()
float fSmallX = fLargeX;
float fSmallY = fLargeY + (LARGE_SECTOR_SIZE/2);
- CVector2D vecSmallSectorCentre
- (
- fSmallX + SMALL_SECTOR_SIZE/2,
- fSmallY + SMALL_SECTOR_SIZE/2
- );
+ CVector2D vecSmallSectorCentre(fSmallX + SMALL_SECTOR_SIZE/2,fSmallY + SMALL_SECTOR_SIZE/2);
float fSmallSectorDistToCamSqr = (camPos - vecSmallSectorCentre).MagnitudeSqr();
fZ = ms_aWaterZs[ aWaterFineBlockList[2*x2+0][2*y2+1] ];
if ( fSmallSectorDistToCamSqr < fWavySectorMaxRenderDistSqr )
- RenderOneWavySector(fSmallX, fSmallY, fZ, color);
+ RenderOneWavySector(fSmallX, fSmallY, fZ, colorTrans);
else
- RenderOneFlatSmallWaterPoly(fSmallX, fSmallY, fZ, color);
+ RenderOneFlatSmallWaterPolyBlended(fSmallX, fSmallY, fZ, camPos.x, camPos.y, color, colorTrans, fWaterDrawDist);
}
//NE
@@ -868,19 +1390,15 @@ CWaterLevel::RenderWater()
float fSmallX = fLargeX + (LARGE_SECTOR_SIZE/2);
float fSmallY = fLargeY + (LARGE_SECTOR_SIZE/2);
- CVector2D vecSmallSectorCentre
- (
- fSmallX + SMALL_SECTOR_SIZE/2,
- fSmallY + SMALL_SECTOR_SIZE/2
- );
+ CVector2D vecSmallSectorCentre(fSmallX + SMALL_SECTOR_SIZE/2, fSmallY + SMALL_SECTOR_SIZE/2);
float fSmallSectorDistToCamSqr = (camPos - vecSmallSectorCentre).MagnitudeSqr();
fZ = ms_aWaterZs[ aWaterFineBlockList[2*x2+1][2*y2+1] ];
if ( fSmallSectorDistToCamSqr < fWavySectorMaxRenderDistSqr )
- RenderOneWavySector(fSmallX, fSmallY, fZ, color);
+ RenderOneWavySector(fSmallX, fSmallY, fZ, colorTrans);
else
- RenderOneFlatSmallWaterPoly(fSmallX, fSmallY, fZ, color);
+ RenderOneFlatSmallWaterPolyBlended(fSmallX, fSmallY, fZ, camPos.x, camPos.y, color, colorTrans, fWaterDrawDist);
}
}
else
@@ -891,13 +1409,11 @@ CWaterLevel::RenderWater()
RenderOneFlatLargeWaterPoly(fLargeX, fLargeY, fZ, color);
}
- } // if ( TheCamera.IsSphereVisible
- } // if ( fLargeSectorDistToCamSqr < fHugeSectorMaxRenderDistSqr )
- } // if ( aWaterBlockList[x2][y2] >= 0 )
- } // for ( int32 y2 = 2*y; y2 <= 2*y+1; y2++ )
- } // for ( int32 x2 = 2*x; x2 <= 2*x+1; x2++ )
- //
-
+ }
+ }
+ }
+ }
+ }
}
}
}
@@ -905,194 +1421,102 @@ CWaterLevel::RenderWater()
}
}
- /*
- ----------- ---------------------- ----------------------
- | [N] | | [ EndY ] | | [ top ] |
- | | | | | |
- |[W] [0] [E]| |[StartX] [] [ EndX ]| |[ left ] [] [ right]|
- | | | | | |
- | [S] | | [StartY] | | [bottom] |
- ----------- ---------------------- ----------------------
-
-
- [S] [StartY] [bottom]
- [N] [EndY] [top]
- [W] [StartX] [left]
- [E] [EndX] [right]
+ RenderAndEmptyRenderBuffer();
- [S] -> [N] && [W] -> [E]
- bottom -> top && left -> right
- */
-
- if ( !bUseCamStartY )
+#ifdef PC_WATER
+ if ( MaskCalculatedThisFrame
+ && (m_nRenderWaterLayers == 0 || m_nRenderWaterLayers == 2 || m_nRenderWaterLayers == 3) )
{
- for ( int32 x = 0; x < 26; x++ )
- {
- for ( int32 y = 0; y < 5; y++ )
- {
- float fX = WATER_SIGN_X(float(x) * EXTRAHUGE_SECTOR_SIZE) - 1280.0f;
- float fY = WATER_SIGN_Y(float(y) * EXTRAHUGE_SECTOR_SIZE) - 1280.0f;
-
- CVector2D vecExtraHugeSectorCentre
- (
- fX + EXTRAHUGE_SECTOR_SIZE/2,
- fY + EXTRAHUGE_SECTOR_SIZE/2
- );
-
- float fCamDistToSector = (vecExtraHugeSectorCentre - camPos).Magnitude();
+ RwV3d pos = { 0.0f, 0.0f, 0.0f };
+
+ pos.x = PreCalculatedMaskPosn.x;
+ pos.y = PreCalculatedMaskPosn.y;
+ pos.z = PreCalculatedMaskPosn.z;
+
+ RpMatFXMaterialSetEnvMapFrame(RpGeometryGetMaterial(RpAtomicGetGeometry(ms_pMaskAtomic), 0),
+ RwCameraGetFrame(RwCameraGetCurrentCamera()));
+
+ RwFrameTranslate(RpAtomicGetFrame(ms_pMaskAtomic), &pos, rwCOMBINEREPLACE);
- if ( fCamDistToSector < fHugeSectorMaxRenderDistSqr )
- {
- if ( TheCamera.IsSphereVisible(CVector(vecExtraHugeSectorCentre.x, vecExtraHugeSectorCentre.y, 0.0f), SectorRadius(EXTRAHUGE_SECTOR_SIZE)) )
- {
- RenderOneFlatExtraHugeWaterPoly(
- vecExtraHugeSectorCentre.x - EXTRAHUGE_SECTOR_SIZE/2,
- vecExtraHugeSectorCentre.y - EXTRAHUGE_SECTOR_SIZE/2,
- 0.0f,
- color);
- }
- }
- }
- }
+ RpAtomicRender(ms_pMaskAtomic);
}
-
- for ( int32 y = 5; y < 21; y++ )
+#else
+ if (!CCullZones::WaterFudge())
{
- for ( int32 x = 0; x < 5; x++ )
- {
- float fX = WATER_SIGN_X(float(x) * EXTRAHUGE_SECTOR_SIZE) - 1280.0f;
- float fX2 = WATER_SIGN_X(float(x) * EXTRAHUGE_SECTOR_SIZE) - 1280.0f;
- float fY = WATER_SIGN_Y(float(y) * EXTRAHUGE_SECTOR_SIZE) - 1280.0f;
-
- if ( !bUseCamStartX )
- {
- CVector2D vecExtraHugeSectorCentre
- (
- fX + EXTRAHUGE_SECTOR_SIZE/2,
- fY + EXTRAHUGE_SECTOR_SIZE/2
- );
-
- float fCamDistToSector = (vecExtraHugeSectorCentre - camPos).Magnitude();
-
- if ( fCamDistToSector < fHugeSectorMaxRenderDistSqr )
- {
- if ( TheCamera.IsSphereVisible(CVector(vecExtraHugeSectorCentre.x, vecExtraHugeSectorCentre.y, 0.0f), SectorRadius(EXTRAHUGE_SECTOR_SIZE)) )
- {
- RenderOneFlatExtraHugeWaterPoly(
- vecExtraHugeSectorCentre.x - EXTRAHUGE_SECTOR_SIZE/2,
- vecExtraHugeSectorCentre.y - EXTRAHUGE_SECTOR_SIZE/2,
- 0.0f,
- color);
- }
- }
- }
-
- if ( !bUseCamEndX )
- {
- CVector2D vecExtraHugeSectorCentre
- (
- -(fX2 + EXTRAHUGE_SECTOR_SIZE/2),
- fY + EXTRAHUGE_SECTOR_SIZE/2
- );
-
- float fCamDistToSector = (vecExtraHugeSectorCentre - camPos).Magnitude();
-
- if ( fCamDistToSector < fHugeSectorMaxRenderDistSqr )
- {
- if ( TheCamera.IsSphereVisible(CVector(vecExtraHugeSectorCentre.x, vecExtraHugeSectorCentre.y, 0.0f), SectorRadius(EXTRAHUGE_SECTOR_SIZE)) )
- {
- RenderOneFlatExtraHugeWaterPoly(
- vecExtraHugeSectorCentre.x - EXTRAHUGE_SECTOR_SIZE/2,
- vecExtraHugeSectorCentre.y - EXTRAHUGE_SECTOR_SIZE/2,
- 0.0f,
- color);
- }
- }
- }
- }
- }
+ int32 signX = 0;
+ int32 signY = 0;
- RenderAndEmptyRenderBuffer();
-
- CVector cur_pos = TheCamera.GetPosition();
-
- if ( !CCullZones::CamNoRain()
- && !CCullZones::PlayerNoRain()
- && CWeather::NewWeatherType == WEATHER_SUNNY
- && CClock::GetHours() > 6 && CClock::GetHours() < 20
- && WavesCalculatedThisFrame)
- {
- static CVector prev_pos(0.0f, 0.0f, 0.0f);
- static CVector prev_front(0.0f, 0.0f, 0.0f);
- static int32 timecounter;
+ float fCamX = camPos.x - SMALL_SECTOR_SIZE;
+ float fCamY = camPos.y - SMALL_SECTOR_SIZE;
- if ( Abs(prev_pos.x - cur_pos.x) + Abs(prev_pos.y - cur_pos.y) + Abs(prev_pos.z - cur_pos.z) > 1.5f )
- {
- prev_pos = cur_pos;
- timecounter = CTimer::GetTimeInMilliseconds();
- }
- else if ( CTimer::GetTimeInMilliseconds() - timecounter > 5000 )
+ if (TheCamera.GetForward().x > 0.3f)
+ signX = 1;
+ else if (TheCamera.GetForward().x < -0.3f)
+ signX = -1;
+
+ fCamX += 0.3f * (float)signX * float(SMALL_SECTOR_SIZE * 2.0f); // 19.2f
+
+ if (TheCamera.GetForward().y > 0.3f)
+ signY = 1;
+ else if (TheCamera.GetForward().y < -0.3f)
+ signY = -1;
+
+ fCamY += 0.3f * (float)signY * float(SMALL_SECTOR_SIZE * 2.0f); // 19.2f
+
+ int32 nBlock;
+
+ int32 BlockX = WATER_TO_SMALL_SECTOR_X(fCamX + WATER_X_OFFSET) + 1;
+ int32 BlockY = WATER_TO_SMALL_SECTOR_Y(fCamY) + 1;
+
+ if (_IsColideWithBlock(BlockX, BlockY, nBlock))
{
- static int32 birdgenTime = 0;
-
- if ( CTimer::GetTimeInMilliseconds() - birdgenTime > 1000 )
+ if (m_nRenderWaterLayers != 1 && m_nRenderWaterLayers != 6)
{
- birdgenTime = CTimer::GetTimeInMilliseconds();
-
- CVector vecPos = cur_pos;
-
- float fAngle = CGeneral::GetRandomNumberInRange(90.0f, 150.0f);
-
- int32 nRot = CGeneral::GetRandomNumber() % CParticle::SIN_COS_TABLE_SIZE-1;
-
- float fCos = CParticle::Cos(nRot);
- float fSin = CParticle::Sin(nRot);
-
- vecPos.x += (fCos - fSin) * fAngle;
- vecPos.y += (fSin + fCos) * fAngle;
- vecPos.z += CGeneral::GetRandomNumberInRange(10.0f, 30.0f);
-
- CVector vecDir(CGeneral::GetRandomNumberInRange(-1.0f, 1.0f),
- CGeneral::GetRandomNumberInRange(-1.0f, 1.0f),
- 0.0f);
-
- CParticle::AddParticle(PARTICLE_BIRD_FRONT, vecPos, vecDir);
+ float fMaskX = Floor(fCamX / 2.0f) * 2.0f;
+ float fMaskY = Floor(fCamY / 2.0f) * 2.0f;
+ float fWaterZ = CWaterLevel::ms_aWaterZs[nBlock];
+ float fSectorX = WATER_FROM_SMALL_SECTOR_X(BlockX) - WATER_X_OFFSET;
+ float fSectorY = WATER_FROM_SMALL_SECTOR_Y(BlockY);
+
+ RenderWavyMask(fMaskX, fMaskY, fWaterZ,
+ fSectorX, fSectorY,
+ signX, signY, colorTrans);
}
}
}
-
+
DefinedState();
+#endif
POP_RENDERGROUP();
}
-void
-CWaterLevel::RenderOneFlatSmallWaterPoly(float fX, float fY, float fZ, RwRGBA const &color)
+void CWaterLevel::RenderOneFlatSmallWaterPoly(float fX, float fY, float fZ, RwRGBA const &color)
{
if ( TempBufferIndicesStored >= TEMPBUFFERINDEXSIZE-6 || TempBufferVerticesStored >= TEMPBUFFERVERTSIZE-4 )
RenderAndEmptyRenderBuffer();
int32 vidx = TempBufferVerticesStored;
- RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 0], fX, fY, fZ - WATER_Z_OFFSET);
+ RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 0], fX, fY, fZ - _fWaterZOffset);
RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 0], TEXTURE_ADDU);
RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 0], TEXTURE_ADDV);
- RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 0], color.red, color.green, color.blue, color.alpha);
+ RwIm3DVertexSet_RGBA(&TempBufferRenderVertices[vidx + 0], color);
- RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 1], fX, fY + SMALL_SECTOR_SIZE, fZ - WATER_Z_OFFSET);
+ RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 1], fX, fY + SMALL_SECTOR_SIZE, fZ - _fWaterZOffset);
RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 1], TEXTURE_ADDU);
RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 1], TEXTURE_ADDV + 1.0f);
- RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 1], color.red, color.green, color.blue, color.alpha);
+ RwIm3DVertexSet_RGBA(&TempBufferRenderVertices[vidx + 1], color);
- RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 2], fX + SMALL_SECTOR_SIZE, fY + SMALL_SECTOR_SIZE, fZ - WATER_Z_OFFSET);
+ RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 2], fX + SMALL_SECTOR_SIZE, fY + SMALL_SECTOR_SIZE, fZ - _fWaterZOffset);
RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 2], TEXTURE_ADDU + 1.0f);
RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 2], TEXTURE_ADDV + 1.0f);
- RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 2], color.red, color.green, color.blue, color.alpha);
+ RwIm3DVertexSet_RGBA(&TempBufferRenderVertices[vidx + 2], color);
- RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 3], fX + SMALL_SECTOR_SIZE, fY, fZ - WATER_Z_OFFSET);
+ RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 3], fX + SMALL_SECTOR_SIZE, fY, fZ - _fWaterZOffset);
RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 3], TEXTURE_ADDU + 1.0f);
RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 3], TEXTURE_ADDV);
- RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 3], color.red, color.green, color.blue, color.alpha);
+ RwIm3DVertexSet_RGBA(&TempBufferRenderVertices[vidx + 3], color);
int32 iidx = TempBufferIndicesStored;
@@ -1116,25 +1540,25 @@ CWaterLevel::RenderOneFlatLargeWaterPoly(float fX, float fY, float fZ, RwRGBA co
int32 vidx = TempBufferVerticesStored;
- RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 0], fX, fY, fZ - WATER_Z_OFFSET);
+ RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 0], fX, fY, fZ - _fWaterZOffset);
RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 0], TEXTURE_ADDU);
RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 0], TEXTURE_ADDV);
- RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 0], color.red, color.green, color.blue, color.alpha);
+ RwIm3DVertexSet_RGBA(&TempBufferRenderVertices[vidx + 0], color);
- RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 1], fX, fY + LARGE_SECTOR_SIZE, fZ - WATER_Z_OFFSET);
+ RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 1], fX, fY + LARGE_SECTOR_SIZE, fZ - _fWaterZOffset);
RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 1], TEXTURE_ADDU);
RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 1], TEXTURE_ADDV + 2.0f);
- RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 1], color.red, color.green, color.blue, color.alpha);
+ RwIm3DVertexSet_RGBA(&TempBufferRenderVertices[vidx + 1], color);
- RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 2], fX + LARGE_SECTOR_SIZE, fY + LARGE_SECTOR_SIZE, fZ - WATER_Z_OFFSET);
+ RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 2], fX + LARGE_SECTOR_SIZE, fY + LARGE_SECTOR_SIZE, fZ - _fWaterZOffset);
RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 2], TEXTURE_ADDU + 2.0f);
RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 2], TEXTURE_ADDV + 2.0f);
- RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 2], color.red, color.green, color.blue, color.alpha);
+ RwIm3DVertexSet_RGBA(&TempBufferRenderVertices[vidx + 2], color);
- RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 3], fX + LARGE_SECTOR_SIZE, fY, fZ - WATER_Z_OFFSET);
+ RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 3], fX + LARGE_SECTOR_SIZE, fY, fZ - _fWaterZOffset);
RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 3], TEXTURE_ADDU + 2.0f);
RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 3], TEXTURE_ADDV);
- RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 3], color.red, color.green, color.blue, color.alpha);
+ RwIm3DVertexSet_RGBA(&TempBufferRenderVertices[vidx + 3], color);
int32 iidx = TempBufferIndicesStored;
@@ -1157,27 +1581,33 @@ CWaterLevel::RenderOneFlatHugeWaterPoly(float fX, float fY, float fZ, RwRGBA con
RenderAndEmptyRenderBuffer();
int32 vidx = TempBufferVerticesStored;
-
- RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 0], fX, fY, fZ - WATER_Z_OFFSET);
+ RwRGBA c;
+
+ c.red = color.red;
+ c.green = color.green;
+ c.blue = color.blue;
+ c.alpha = 255;
+
+ RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 0], fX, fY, fZ - _fWaterZOffset);
RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 0], TEXTURE_ADDU);
RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 0], TEXTURE_ADDV);
- RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 0], color.red, color.green, color.blue, 255);
+ RwIm3DVertexSet_RGBA(&TempBufferRenderVertices[vidx + 0], c);
- RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 1], fX, fY + HUGE_SECTOR_SIZE, fZ - WATER_Z_OFFSET);
+ RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 1], fX, fY + HUGE_SECTOR_SIZE, fZ - _fWaterZOffset);
RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 1], TEXTURE_ADDU);
RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 1], TEXTURE_ADDV + 4.0f);
- RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 1], color.red, color.green, color.blue, 255);
+ RwIm3DVertexSet_RGBA(&TempBufferRenderVertices[vidx + 1], c);
- RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 2], fX + HUGE_SECTOR_SIZE, fY + HUGE_SECTOR_SIZE, fZ - WATER_Z_OFFSET);
+ RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 2], fX + HUGE_SECTOR_SIZE, fY + HUGE_SECTOR_SIZE, fZ - _fWaterZOffset);
RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 2], TEXTURE_ADDU + 4.0f);
RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 2], TEXTURE_ADDV + 4.0f);
- RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 2], color.red, color.green, color.blue, 255);
+ RwIm3DVertexSet_RGBA(&TempBufferRenderVertices[vidx + 2], c);
- RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 3], fX + HUGE_SECTOR_SIZE, fY, fZ - WATER_Z_OFFSET);
+ RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 3], fX + HUGE_SECTOR_SIZE, fY, fZ - _fWaterZOffset);
RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 3], TEXTURE_ADDU + 4.0f);
RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 3], TEXTURE_ADDV);
- RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 3], color.red, color.green, color.blue, 255);
+ RwIm3DVertexSet_RGBA(&TempBufferRenderVertices[vidx + 3], c);
int32 iidx = TempBufferIndicesStored;
@@ -1200,27 +1630,33 @@ CWaterLevel::RenderOneFlatExtraHugeWaterPoly(float fX, float fY, float fZ, RwRGB
RenderAndEmptyRenderBuffer();
int32 vidx = TempBufferVerticesStored;
-
- RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 0], fX, fY, fZ - WATER_Z_OFFSET);
+ RwRGBA c;
+
+ c.red = color.red;
+ c.green = color.green;
+ c.blue = color.blue;
+ c.alpha = 255;
+
+ RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 0], fX, fY, fZ - _fWaterZOffset);
RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 0], TEXTURE_ADDU);
RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 0], TEXTURE_ADDV);
- RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 0], color.red, color.green, color.blue, 255);
+ RwIm3DVertexSet_RGBA(&TempBufferRenderVertices[vidx + 0], c);
- RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 1], fX, fY + EXTRAHUGE_SECTOR_SIZE, fZ - WATER_Z_OFFSET);
+ RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 1], fX, fY + EXTRAHUGE_SECTOR_SIZE, fZ - _fWaterZOffset);
RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 1], TEXTURE_ADDU);
RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 1], TEXTURE_ADDV + 8.0f);
- RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 1], color.red, color.green, color.blue, 255);
+ RwIm3DVertexSet_RGBA(&TempBufferRenderVertices[vidx + 1], c);
- RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 2], fX + EXTRAHUGE_SECTOR_SIZE, fY + EXTRAHUGE_SECTOR_SIZE, fZ - WATER_Z_OFFSET);
+ RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 2], fX + EXTRAHUGE_SECTOR_SIZE, fY + EXTRAHUGE_SECTOR_SIZE, fZ - _fWaterZOffset);
RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 2], TEXTURE_ADDU + 8.0f);
RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 2], TEXTURE_ADDV + 8.0f);
- RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 2], color.red, color.green, color.blue, 255);
+ RwIm3DVertexSet_RGBA(&TempBufferRenderVertices[vidx + 2], c);
- RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 3], fX + EXTRAHUGE_SECTOR_SIZE, fY, fZ - WATER_Z_OFFSET);
+ RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 3], fX + EXTRAHUGE_SECTOR_SIZE, fY, fZ - _fWaterZOffset);
RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 3], TEXTURE_ADDU + 8.0f);
RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 3], TEXTURE_ADDV);
- RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 3], color.red, color.green, color.blue, 255);
+ RwIm3DVertexSet_RGBA(&TempBufferRenderVertices[vidx + 3], c);
int32 iidx = TempBufferIndicesStored;
@@ -1237,172 +1673,1218 @@ CWaterLevel::RenderOneFlatExtraHugeWaterPoly(float fX, float fY, float fZ, RwRGB
}
void
-CWaterLevel::RenderOneWavySector(float fX, float fY, float fZ, RwRGBA const &color, bool bUnk)
+CWaterLevel::RenderOneWavySector(float fX, float fY, float fZ, RwRGBA const &color, bool bDontRender)
{
- float fAngle = (CTimer::GetTimeInMilliseconds() & 4095) * (TWOPI / 4096.0f);
-
- if ( !WavesCalculatedThisFrame )
+ CVector vecSectorPos(fX + (SMALL_SECTOR_SIZE/2), fY + (SMALL_SECTOR_SIZE/2), fZ + 2.0f);
+
+ if ( COcclusion::IsAABoxOccluded(vecSectorPos, SMALL_SECTOR_SIZE, SMALL_SECTOR_SIZE, 4.0f) )
+ return;
+
+#ifdef PC_WATER
+ RequireWavySector = true;
+#else
+ if (!WavesCalculatedThisFrame)
{
- nGeomUsed = 0;
-
WavesCalculatedThisFrame = true;
+
+ float fAngle = (CTimer::GetTimeInMilliseconds() & 4095) * (TWOPI / 4096.0f);
+
+ RpGeometry *wavyGeometry = RpAtomicGetGeometry(ms_pWavyAtomic);
+ RwTexCoords *wavyTexCoords = RpGeometryGetVertexTexCoords(wavyGeometry, rwTEXTURECOORDINATEINDEX0);
+ RpMorphTarget *wavyMorph = RpGeometryGetMorphTarget(wavyGeometry, 0);
+ RwRGBA *wavyPreLight = RpGeometryGetPreLightColors(wavyGeometry);
+ RwV3d *wavyMorphVerts = RpMorphTargetGetVertices(wavyMorph);
+ RwV3d *wavyMorphNormals = RpMorphTargetGetVertexNormals(wavyMorph);
+
+ RpGeometryLock(wavyGeometry, rpGEOMETRYLOCKVERTICES | rpGEOMETRYLOCKNORMALS | rpGEOMETRYLOCKPRELIGHT | rpGEOMETRYLOCKTEXCOORDS);
+
+ RwMatrix *camMat = RwFrameGetLTM(RwCameraGetFrame(RwCameraGetCurrentCamera())); //or curWorld
+
+ float randomDampInv2 = (1.0f - fRandomDamp) * 2.0f;
+
+ float move = 1.0f / 16.0f;
+ float randomMove = 1.0f / (16.0f * fRandomMoveDiv);
+
+ float vertMul = 0.5f;
+
+ float wind = CWeather::WindClipped * 0.4f + 0.2f;
+ float waveWind = CWeather::WindClipped * fWave2Ampl + 0.05f;
+
+ float waveA = (TWOPI / 16.0f)
+ * ((fNormalDirectionScalar1 * Abs(camMat->at.x + camMat->at.y) + fNormMult) * (CWeather::WindClipped * 0.4f + 0.2f));
+
+ float waveB = TWOPI / (16.0f * fWave2NormScale)
+ * ((fNormalDirectionScalar2 * Abs(camMat->at.y - camMat->at.x) + fNormMultB) * (CWeather::WindClipped * 0.2f + 0.1f));
+
+ CVector vA(1.0f, 0.0f, 0.0f);
+ CVector vB(0.0f, 1.0f, 0.0f);
+
+ for ( int32 i = 0; i < 17; i++ )
+ {
+ for ( int32 j = 0; j < 17; j++ )
+ {
+ wavyTexCoords->u = float(i) * move + TEXTURE_ADDV;
+ wavyTexCoords->v = float(j) * move + TEXTURE_ADDU;
+
+ RwRGBAAssign(wavyPreLight, &color);
+
+ if (i > 0 && i < 16 && j > 0 && j < 16)
+ {
+ wavyMorphVerts->x += CGeneral::GetRandomNumberInRange(-1.0f, 1.0f) * randomMove;
+ wavyMorphVerts->x *= fRandomDamp;
+ wavyMorphVerts->x += float(i) * randomDampInv2;
+
+ wavyMorphVerts->y += CGeneral::GetRandomNumberInRange(-1.0f, 1.0f) * randomMove;
+ wavyMorphVerts->y *= fRandomDamp;
+ wavyMorphVerts->y += float(j) * randomDampInv2;
+ }
+
+ float morphVertXHalf = (i == 16) ? 0.0f : vertMul * wavyMorphVerts->x;
+ float morphVertYHalf = (j == 16) ? 0.0f : vertMul * wavyMorphVerts->y;
+
+ float waveMulA = (morphVertYHalf + morphVertXHalf) * (TWOPI / 16.0f) + fAngle;
+ float waveMulB = (morphVertYHalf - morphVertXHalf) * (TWOPI / (16.0f * fWave2InvLength)) + fAngle;
+
+ wavyMorphVerts->z = wind * Sin(waveMulA) + waveWind * Sin(waveMulB);
+
+ vA.z = (waveA * Cos(waveMulA)) - (waveB * Cos(waveMulB));
+ vB.z = (waveA * Cos(waveMulA)) + (waveB * Cos(waveMulB));
+
+ CVector norm = CrossProduct(vA, vB);
+ norm.Normalise();
+
+ wavyMorphNormals->x = norm.x;
+ wavyMorphNormals->y = norm.y;
+ wavyMorphNormals->z = norm.z;
+
+ ++wavyPreLight;
+ ++wavyTexCoords;
+
+ ++wavyMorphVerts;
+ ++wavyMorphNormals;
+ }
+ }
+
+ RpGeometryUnlock(wavyGeometry);
+ }
+
+ float fCentreX = fX + (SMALL_SECTOR_SIZE / 2);
+ float fCentreY = fY + (SMALL_SECTOR_SIZE / 2);
+#endif
+
+#ifdef PC_WATER
+ if ( WavesCalculatedThisFrame )
+#endif
+ {
+ if (bDontRender == false
+ && m_nRenderWaterLayers != 2
+ && m_nRenderWaterLayers != 4
+ && m_nRenderWaterLayers != 6 )
+ {
+ RwV3d pos = { 0.0f, 0.0f, 0.0f };
+
+ pos.x = fX;
+ pos.y = fY;
+ pos.z = fZ;
+
+ RwFrameTranslate(RpAtomicGetFrame(ms_pWavyAtomic), &pos, rwCOMBINEREPLACE);
- CBoat::FillBoatList();
+ RpAtomicRender(ms_pWavyAtomic);
+ }
+ }
+}
- ASSERT( ms_pWavyAtomic != nil );
+int16
+_RoundValue(int32 v)
+{
+ int16 result = v;
+
+ while ( result < 0 ) result += 16;
+ while ( result > 16 ) result -= 16;
+
+ return result;
+}
- RpGeometry *geometry = RpAtomicGetGeometry(ms_pWavyAtomic);
-
- ASSERT( geometry != nil );
+void
+CWaterLevel::RenderWavyMask(float fX, float fY, float fZ,
+ float fSectorX, float fSectorY,
+#ifdef PC_WATER
+ float fCamPosX, float fCamPosY,
+ float fCamDirX, float fCamDirY, RwRGBA const&color)
+#else
+ int32 nCamDirX, int32 nCamDirY, RwRGBA const&color)
+#endif
+{
+#ifndef PC_WATER
+ bool bRender = true;
+ if (m_nRenderWaterLayers != 0 && m_nRenderWaterLayers != 2 && m_nRenderWaterLayers != 3)
+ bRender = false;
+#endif
+ CVector vecSectorPos(fX + (LARGE_SECTOR_SIZE/2), fY + (LARGE_SECTOR_SIZE/2), fZ + 2.0f);
- RwRGBA *wavyPreLights = RpGeometryGetPreLightColors(geometry);
- RwTexCoords *wavyTexCoords = RpGeometryGetVertexTexCoords(geometry, rwTEXTURECOORDINATEINDEX0);
- RwV3d *wavyVertices = RpMorphTargetGetVertices(RpGeometryGetMorphTarget(geometry, 0));
-
- ASSERT( wavyPreLights != nil );
- ASSERT( wavyTexCoords != nil );
- ASSERT( wavyVertices != nil );
+ if ( COcclusion::IsAABoxOccluded(vecSectorPos, LARGE_SECTOR_SIZE, LARGE_SECTOR_SIZE, 4.0f) )
+ return;
- RpGeometryLock(geometry, rpGEOMETRYLOCKVERTICES
- | rpGEOMETRYLOCKPRELIGHT
- | rpGEOMETRYLOCKTEXCOORDS);
-
- for ( int32 i = 0; i < 9; i++ )
+#ifndef PC_WATER
+ float fUOffset = fX - (MAX_LARGE_SECTORS * (int32)Floor(fX / MAX_LARGE_SECTORS));
+ float fVOffset = fY - (MAX_LARGE_SECTORS * (int32)Floor(fY / MAX_LARGE_SECTORS));
+
+ int32 nSecsX = (int32)((fX - fSectorX) / 2.0f);
+ int32 nSecsY = (int32)((fY - fSectorY) / 2.0f);
+#endif
+
+ RpGeometry *wavyGeometry = RpAtomicGetGeometry(ms_pWavyAtomic);
+ RpMorphTarget *wavyMorph = RpGeometryGetMorphTarget(wavyGeometry, 0);
+ RwV3d *wavyMorphVerts = RpMorphTargetGetVertices(wavyMorph);
+ RwV3d *wavyMorphNormals = RpMorphTargetGetVertexNormals(wavyMorph);
+
+ RpGeometry *maskGeometry = RpAtomicGetGeometry(ms_pMaskAtomic);
+ RwTexCoords *maskTexCoords = RpGeometryGetVertexTexCoords(maskGeometry, rwTEXTURECOORDINATEINDEX0);
+ RwRGBA *maskPreLight = RpGeometryGetPreLightColors(maskGeometry);
+ RpMorphTarget *maskMorph = RpGeometryGetMorphTarget(maskGeometry, 0);
+ RwV3d *maskMorphVerts = RpMorphTargetGetVertices(maskMorph);
+ RwV3d *maskMorphNormals = RpMorphTargetGetVertexNormals(maskMorph);
+
+ RpGeometryLock(maskGeometry, rpGEOMETRYLOCKVERTICES|rpGEOMETRYLOCKNORMALS|rpGEOMETRYLOCKPRELIGHT|rpGEOMETRYLOCKTEXCOORDS);
+
+#ifndef PC_WATER
+ RpMaterial *maskMat = RpGeometryGetMaterial(maskGeometry, 0);
+ RpMatFXMaterialSetEnvMapFrame(maskMat, RwCameraGetFrame(RwCameraGetCurrentCamera()));
+ RpMatFXMaterialSetEnvMapCoefficient(maskMat, fEnvScale);
+ RpMatFXMaterialSetEnvMapFrameBufferAlpha(maskMat, TRUE);
+#endif
+
+#ifndef PC_WATER
+ float fMinSparkZ = (CWeather::WindClipped * fWave2Ampl + 0.05f +
+ CWeather::WindClipped * 0.4f + 0.2) * (1.0f - 0.04f * CWeather::SunGlare);
+
+ int32 randval = CGeneral::GetRandomNumber();
+
+ float fUVStep = 0.125f;
+ float f27 = 2.0f;
+
+ float fMinU = (fUOffset / 16.0f) + _TEXTURE_MASK_ADDU;
+ float fMinV = (fVOffset / 16.0f) + _TEXTURE_MASK_ADDV;
+
+ float fAlphaMul = ((float)color.alpha * 0.4f) / 16.0f;
+
+ float fXOffset = 16.0f;
+ if (nCamDirX > 0)
+ fXOffset = 6.4f;
+ else if (nCamDirX < 0)
+ fXOffset = 25.6f;
+
+ float fYOffset = 16.0f;
+ if (nCamDirY > 0)
+ fYOffset = 6.4f;
+ else if (nCamDirY < 0)
+ fYOffset = 25.6f;
+
+ int16 nX = _RoundValue(nSecsX - 1);
+ int16 nY = _RoundValue(nSecsY - 1);
+#else
+ float fMinSparkZ = (fWave2Ampl * CWeather::WindClipped + 0.05f +
+ 0.4f * CWeather::WindClipped + 0.2) * (1.0f - 0.02f * CWeather::SunGlare);
+
+ int32 randval = CGeneral::GetRandomNumber() & 255;
+
+ int16 nX = _RoundValue((int32)((fX - fSectorX) * 0.5f) - 1);
+ int16 nY = _RoundValue((int32)((fY - fSectorY) * 0.5f) - 1);
+#endif
+ int16 idxX = nX;
+
+ for ( int32 i = 0; i < 17; i++ )
+ {
+ int16 idxY = nY;
+
+ if ( ++idxX > 16 )
+ idxX -= 16;
+
+ for ( int32 j = 0; j < 17; j++ )
{
- for ( int32 j = 0; j < 9; j++ )
+ if ( ++idxY > 16 )
+ idxY -= 16;
+
+ const int32 a = (0*16);
+ const int32 b = (1*16);
+ const int32 c = (33*16);
+ const int32 d = (34*16);
+
+ int32 base = (i*33+j);
+
+#ifndef PC_WATER
+ maskTexCoords[base + a].u = fMinU + ((float)i * fUVStep);
+ maskTexCoords[base + a].v = fMinV + ((float)j * fUVStep);
+
+ maskTexCoords[base + b].u = maskTexCoords[base + a].u;
+ maskTexCoords[base + b].v = maskTexCoords[base + a].v + (16.0f * fUVStep);
+
+ maskTexCoords[base + c].u = maskTexCoords[base + a].u + (16.0f * fUVStep);
+ maskTexCoords[base + c].v = maskTexCoords[base + a].v;
+
+ maskTexCoords[base + d].u = maskTexCoords[base + a].u + (16.0f * fUVStep);
+ maskTexCoords[base + d].v = maskTexCoords[base + a].v + (16.0f * fUVStep);
+#else
+ maskTexCoords[base+a].v = float(j) / SMALL_SECTOR_SIZE + ((fCamPosY - fY) / 64);
+ maskTexCoords[base+c].v = maskTexCoords[base+a].v;
+ maskTexCoords[base+d].v = maskTexCoords[base+a].v + 0.5f;
+ maskTexCoords[base+b].v = maskTexCoords[base+d].v;
+
+ maskTexCoords[base+a].u = float(i) / SMALL_SECTOR_SIZE + ((fCamPosX - fX) / 64);
+ maskTexCoords[base+b].u = maskTexCoords[base+a].u;
+ maskTexCoords[base+d].u = maskTexCoords[base+a].u + 0.5f;
+ maskTexCoords[base+c].u = maskTexCoords[base+d].u;
+#endif
+
+ maskMorphVerts[base+a].x = (wavyMorphVerts[idxY + (17 * idxX)].x - (float)idxX * 2.0f) + (float(i) * 2.0f);
+ maskMorphVerts[base+b].x = maskMorphVerts[base+a].x;
+ maskMorphVerts[base+c].x = maskMorphVerts[base+a].x + SMALL_SECTOR_SIZE;
+ maskMorphVerts[base+d].x = maskMorphVerts[base+c].x;
+
+ maskMorphVerts[base+a].y = (wavyMorphVerts[idxY + (17 * idxX)].y - (float)idxY * 2.0f) + (float(j) * 2.0f);
+ maskMorphVerts[base+c].y = maskMorphVerts[base+a].y;
+ maskMorphVerts[base+b].y = maskMorphVerts[base+a].y + SMALL_SECTOR_SIZE;
+ maskMorphVerts[base+d].y = maskMorphVerts[base+b].y;
+
+ maskMorphVerts[base+a].z = wavyMorphVerts[idxY + (17 * idxX)].z;
+ maskMorphVerts[base+d].z = maskMorphVerts[base+a].z;
+ maskMorphVerts[base+c].z = maskMorphVerts[base+d].z;
+ maskMorphVerts[base+b].z = maskMorphVerts[base+c].z;
+
+#ifndef PC_WATER
+ if (maskMorphVerts[base].z >= fMinSparkZ)
+#else
+ if ( maskMorphVerts[base].z > fMinSparkZ )
+#endif
{
- wavyTexCoords[9*i+j].u = float(i) / 8 + TEXTURE_ADDV;
- wavyTexCoords[9*i+j].v = float(j) / 8 + TEXTURE_ADDU;
- RwRGBAAssign(&wavyPreLights[9*i+j], &color);
+ switch ( (i + j + randval) & 3 )
+ {
+ case 0:
+ {
+ CVector vecPos
+ (
+ fX + maskMorphVerts[base+a].x,
+ fY + maskMorphVerts[base+a].y,
+ fZ + maskMorphVerts[base+a].z + 0.12f
+ );
+
+ vecPos -= 0.05f * TheCamera.GetForward();
+
+ CParticle::AddParticle(PARTICLE_WATER_SPARK,
+ vecPos,
+ CVector(0.0f, 0.0f, 0.0f),
+ nil,
+ 0.0f,
+ 15,
+ CGeneral::GetRandomNumberInRange(-90, 90),
+ 0,
+ 0);
+ }
+ break;
- wavyVertices[9*i+j].z = ( CWeather::Wind * 0.7f + 0.3f )
- * ( Sin(float(i + j) * DEGTORAD(45.0f) + fAngle) )
- + ( CWeather::Wind * 0.2f * Sin(float(j - i) * PI + (2.0f * fAngle)) );
+ case 1:
+ {
+ CVector vecPos
+ (
+ fX + maskMorphVerts[base+c].x,
+ fY + maskMorphVerts[base+c].y,
+ fZ + maskMorphVerts[base+c].z + 0.12f
+ );
+
+ vecPos -= 0.05f * TheCamera.GetForward();
+
+ CParticle::AddParticle(PARTICLE_WATER_SPARK,
+ vecPos,
+ CVector(0.0f, 0.0f, 0.0f),
+ nil,
+ 0.0f,
+ 15,
+ CGeneral::GetRandomNumberInRange(-90, 90),
+ 0,
+ 0);
+ }
+ break;
+
+ case 2:
+ {
+ CVector vecPos
+ (
+ fX + maskMorphVerts[base+b].x,
+ fY + maskMorphVerts[base+b].y,
+ fZ + maskMorphVerts[base+b].z + 0.12f
+ );
+
+ vecPos -= 0.05f * TheCamera.GetForward();
+
+ CParticle::AddParticle(PARTICLE_WATER_SPARK,
+ vecPos,
+ CVector(0.0f, 0.0f, 0.0f),
+ nil,
+ 0.0f,
+ 15,
+ CGeneral::GetRandomNumberInRange(-90, 90),
+ 0,
+ 0);
+ }
+ break;
+
+ case 3:
+ {
+ CVector vecPos
+ (
+ fX + maskMorphVerts[base+d].x,
+ fY + maskMorphVerts[base+d].y,
+ fZ + maskMorphVerts[base+d].z + 0.12f
+ );
+
+ vecPos -= 0.05f * TheCamera.GetForward();
+
+ CParticle::AddParticle(PARTICLE_WATER_SPARK,
+ vecPos,
+ CVector(0.0f, 0.0f, 0.0f),
+ nil,
+ 0.0f,
+ 15,
+ CGeneral::GetRandomNumberInRange(-90, 90),
+ 0,
+ 0);
+ }
+ break;
+ }
}
+
+ maskMorphNormals[base+a].x = wavyMorphNormals[idxY + (17 * idxX)].x;
+ maskMorphNormals[base+a].y = wavyMorphNormals[idxY + (17 * idxX)].y;
+ maskMorphNormals[base+a].z = wavyMorphNormals[idxY + (17 * idxX)].z;
+
+ maskMorphNormals[base+d].x = maskMorphNormals[base+a].x;
+ maskMorphNormals[base+d].y = maskMorphNormals[base+a].y;
+ maskMorphNormals[base+d].z = maskMorphNormals[base+a].z;
+
+ maskMorphNormals[base+c].x = maskMorphNormals[base+d].x;
+ maskMorphNormals[base+c].y = maskMorphNormals[base+d].y;
+ maskMorphNormals[base+c].z = maskMorphNormals[base+d].z;
+
+ maskMorphNormals[base+b].x = maskMorphNormals[base+c].x;
+ maskMorphNormals[base+b].y = maskMorphNormals[base+c].y;
+ maskMorphNormals[base+b].z = maskMorphNormals[base+c].z;
+
+ maskPreLight[base+a].red = color.red;
+ maskPreLight[base+a].green = color.green;
+ maskPreLight[base+a].blue = color.blue;
+ maskPreLight[base+a].alpha = color.alpha;
+
+ maskPreLight[base+d].red = maskPreLight[base+a].red;
+ maskPreLight[base+d].green = maskPreLight[base+a].green;
+ maskPreLight[base+d].blue = maskPreLight[base+a].blue;
+ maskPreLight[base+d].alpha = maskPreLight[base+a].alpha;
+
+ maskPreLight[base+c].red = maskPreLight[base+d].red;
+ maskPreLight[base+c].green = maskPreLight[base+d].green;
+ maskPreLight[base+c].blue = maskPreLight[base+d].blue;
+ maskPreLight[base+c].alpha = maskPreLight[base+d].alpha;
+
+ maskPreLight[base+b].red = maskPreLight[base+c].red;
+ maskPreLight[base+b].green = maskPreLight[base+c].green;
+ maskPreLight[base+b].blue = maskPreLight[base+c].blue;
+ maskPreLight[base+b].alpha = maskPreLight[base+c].alpha;
+
+#ifndef PC_WATER
+ maskPreLight[base + a].alpha = Max(0, (int32)((float)color.alpha - (fAlphaMul * (Abs((float)i - fXOffset) + Abs((float)j - fYOffset)))));
+ maskPreLight[base + b].alpha = Max(0, (int32)((float)color.alpha - (fAlphaMul * (Abs((float)i - fXOffset) + Abs(16.0f + (float)j - fYOffset)))));
+ maskPreLight[base + c].alpha = Max(0, (int32)((float)color.alpha - (fAlphaMul * (Abs(16.0f + (float)i - fXOffset) + Abs((float)j - fYOffset)))));
+ maskPreLight[base + d].alpha = Max(0, (int32)((float)color.alpha - (fAlphaMul * (Abs(16.0f + (float)i - fXOffset) + Abs(16.0f + (float)j - fYOffset)))));
+#endif
+ }
+ }
+
+ RpGeometryUnlock(maskGeometry);
+
+#ifndef PC_WATER
+ {
+ RwV3d pos = { 0.0f, 0.0f, 0.0f };
+
+ pos.x = fX;
+ pos.y = fY;
+ pos.z = fZ + 0.05f;
+
+ RwFrameTranslate(RpAtomicGetFrame(ms_pMaskAtomic), &pos, rwCOMBINEREPLACE);
+
+ if (bRender)
+ {
+#ifdef PS2
+ RpSkyTexCacheFlush();
+#endif
+ RpAtomicRender(ms_pMaskAtomic);
}
-
- RpGeometryUnlock(geometry);
}
+#endif
+}
+
+#ifdef PC_WATER
+void
+CWaterLevel::PreCalcWaterGeometry(void)
+{
+ if ( !RequireWavySector )
+ {
+ WavesCalculatedThisFrame = false;
+ MaskCalculatedThisFrame = false;
+ return;
+ }
+
+ RequireWavySector = false;
+ WavesCalculatedThisFrame = true;
- static CBoat *apBoatList[4] = { nil };
+ RwRGBA color;
- if ( apGeomArray[0]
- && nGeomUsed < MAX_BOAT_WAKES
- && CBoat::IsSectorAffectedByWake(
- CVector2D(fX + (SMALL_SECTOR_SIZE / 2), fY + (SMALL_SECTOR_SIZE / 2)),
- SMALL_SECTOR_SIZE / 2,
- apBoatList) )
+ color.red = CTimeCycle::GetWaterRed();
+ color.green = CTimeCycle::GetWaterGreen();
+ color.blue = CTimeCycle::GetWaterBlue();
+ color.alpha = CTimeCycle::GetWaterAlpha();
+
+ PreCalcWavySector(color);
+
+ if ( CCullZones::WaterFudge() )
{
- float fWakeColor = fAdd1 - Max(255.0f - float(color.blue + color.red + color.green) / 3, fAdd2);
-
- RpGeometry *wavyGeometry = RpAtomicGetGeometry(ms_pWavyAtomic);
- RpGeometry *geom = apGeomArray[nGeomUsed++];
-
- ASSERT( wavyGeometry != nil );
- ASSERT( geom != nil );
-
- RpAtomic *atomic = RpAtomicCreate();
- ASSERT( atomic != nil );
-
- RpAtomicSetGeometry(atomic, geom, 0);
-
- RwFrame *frame = RwFrameCreate();
- ASSERT( frame != nil );
-
- RwMatrixCopy(RwFrameGetMatrix(frame), RwFrameGetMatrix(RpAtomicGetFrame(ms_pWavyAtomic)));
- RpAtomicSetFrame(atomic, frame);
+ MaskCalculatedThisFrame = false;
+ return;
+ }
+
+ CVector CamFwdDir = TheCamera.GetForward();
+ CamFwdDir.z = 0.0f;
+ CamFwdDir.Normalise();
+
+ float fCamX = TheCamera.GetPosition().x - SMALL_SECTOR_SIZE;
+ float fCamY = TheCamera.GetPosition().y - SMALL_SECTOR_SIZE;
+
+ //1.4144272f; 1.4144f;
+ float signX = CamFwdDir.x * 1.4144272f;
+ float signY = CamFwdDir.y * 1.4144272f;
+
+ signX = Clamp(signX, -1.0f, 1.0f);
+ fCamX += 0.4f * signX * float(SMALL_SECTOR_SIZE * 2.0f);
+
+ signY = Clamp(signY, -1.0f, 1.0f);
+ fCamY += 0.4f * signY * float(SMALL_SECTOR_SIZE * 2.0f);
+
+ int32 nBlock;
+
+ int32 BlockX = WATER_TO_SMALL_SECTOR_X(fCamX + WATER_X_OFFSET) + 1;
+ int32 BlockY = WATER_TO_SMALL_SECTOR_Y(fCamY ) + 1;
+
+ ASSERT( BlockX >= 0 && BlockX < MAX_SMALL_SECTORS );
+ ASSERT( BlockY >= 0 && BlockY < MAX_SMALL_SECTORS );
+
+ if ( _IsColideWithBlock(BlockX, BlockY, nBlock) )
+ {
+ float fMaskX = Floor(fCamX / 2.0f) * 2.0f;
+ float fMaskY = Floor(fCamY / 2.0f) * 2.0f;
+
+ float fSectorX = WATER_FROM_SMALL_SECTOR_X(BlockX) - WATER_X_OFFSET;
+ float fSectorY = WATER_FROM_SMALL_SECTOR_Y(BlockY);
- RwTexCoords *geomTexCoords = RpGeometryGetVertexTexCoords(geom, rwTEXTURECOORDINATEINDEX0);
- RwTexCoords *wavyTexCoord = RpGeometryGetVertexTexCoords(wavyGeometry, rwTEXTURECOORDINATEINDEX0);
- RwRGBA *geomPreLights = RpGeometryGetPreLightColors(geom);
- RwV3d *geomVertices = RpMorphTargetGetVertices(RpGeometryGetMorphTarget(geom, 0));
- RwV3d *wavyVertices = RpMorphTargetGetVertices(RpGeometryGetMorphTarget(wavyGeometry, 0));
+ if ( PreCalcWavyMask( fMaskX, fMaskY, ms_aWaterZs[nBlock],
+ fSectorX, fSectorY, fCamX, fCamY, CamFwdDir.x, CamFwdDir.y, color ) )
+ {
+ PreCalculatedMaskPosn.x = fMaskX;
+ PreCalculatedMaskPosn.y = fMaskY;
+ PreCalculatedMaskPosn.z = ms_aWaterZs[nBlock] + 0.05f;
+
+ MaskCalculatedThisFrame = true;
+ }
+ else
+ MaskCalculatedThisFrame = false;
+ }
+ else
+ MaskCalculatedThisFrame = false;
+}
+
+bool
+CWaterLevel::PreCalcWavySector(RwRGBA const &color)
+{
+ float fAngle = (CTimer::GetTimeInMilliseconds() & 4095) * (TWOPI / 4096.0f);
+
+ RpGeometry *wavyGeometry = RpAtomicGetGeometry(ms_pWavyAtomic);
+
+ RwTexCoords *wavyTexCoords = RpGeometryGetVertexTexCoords(wavyGeometry, rwTEXTURECOORDINATEINDEX0);
+ RpMorphTarget *wavyMorph = RpGeometryGetMorphTarget(wavyGeometry, 0);
+
+ RwRGBA *wavyPreLight = RpGeometryGetPreLightColors(wavyGeometry);
+ RwV3d *wavyMorphVerts = RpMorphTargetGetVertices(wavyMorph);
+ RwV3d *wavyMorphNormals = RpMorphTargetGetVertexNormals(wavyMorph);
+
+ if ( !m_bRenderSeaBed )
+ RpGeometryLock(wavyGeometry, rpGEOMETRYLOCKVERTICES
+ |rpGEOMETRYLOCKNORMALS
+ |rpGEOMETRYLOCKPRELIGHT
+ |rpGEOMETRYLOCKTEXCOORDS);
+
+ CVector camPosUp = TheCamera.GetForward();
- ASSERT( geomTexCoords != nil );
- ASSERT( wavyTexCoord != nil );
- ASSERT( geomPreLights != nil );
- ASSERT( geomVertices != nil );
- ASSERT( wavyVertices != nil );
+ float randomDampInv2 = (1.0f - fRandomDamp) * 2.0f;
+
+ float randomMove = 1.0f / (16.0f * fRandomMoveDiv);
+
+ float wind = CWeather::WindClipped * 0.4f + 0.2f;
+ float waveWind = CWeather::WindClipped * fWave2Ampl + 0.05f;
- RpGeometryLock(geom, rpGEOMETRYLOCKVERTICES | rpGEOMETRYLOCKPRELIGHT | rpGEOMETRYLOCKTEXCOORDS);
+ float waveA = (TWOPI / 16.0f)
+ * ((CWeather::WindClipped * 0.4f + 0.2f) * (fNormalDirectionScalar1 * Abs(camPosUp.x + camPosUp.y) + fNormMult));
- for ( int32 i = 0; i < 9; i++ )
+ float waveB = TWOPI / (16.0f * fWave2NormScale)
+ * ((CWeather::WindClipped * 0.2f + 0.1f) * (fNormalDirectionScalar2 * Abs(camPosUp.y - camPosUp.x) + fNormMultB));
+
+
+ CVector vA(1.0f, 0.0f, 0.0f);
+ CVector vB(0.0f, 1.0f, 0.0f);
+
+ for ( int32 i = 0; i < 17; i++ )
+ {
+ for ( int32 j = 0; j < 17; j++ )
{
- for ( int32 j = 0; j < 9; j++ )
+ wavyTexCoords->u = (float(i) / 16.0f) + TEXTURE_ADDV;
+ wavyTexCoords->v = (float(j) / 16.0f) + TEXTURE_ADDU;
+
+ RwRGBAAssign(wavyPreLight, &color);
+
+ if ( i > 0 && i < 16 && j > 0 && j < 16 )
{
- geomTexCoords[9*i+j] = wavyTexCoord[9*i+j];
+ wavyMorphVerts->x += CGeneral::GetRandomNumberInRange(-1.0f, 1.0f) * randomMove;
+ wavyMorphVerts->x *= fRandomDamp;
+ wavyMorphVerts->x += float(i) * randomDampInv2;
+
+ wavyMorphVerts->y += CGeneral::GetRandomNumberInRange(-1.0f, 1.0f) * randomMove;
+ wavyMorphVerts->y *= fRandomDamp;
+ wavyMorphVerts->y += float(j) * randomDampInv2;
+ }
+
+ float morphVertXHalf = ( i == 16 ) ? 0.0f : 0.5f * wavyMorphVerts->x;
+ float morphVertYHalf = ( j == 16 ) ? 0.0f : 0.5f * wavyMorphVerts->y;
+
+ float waveMulA = (morphVertYHalf + morphVertXHalf) * (TWOPI / 16.0f) + fAngle;
+ float waveMulB = (morphVertYHalf - morphVertXHalf) * (TWOPI / (16.0f * fWave2InvLength)) + fAngle;
+
+ wavyMorphVerts->z = wind * Sin(waveMulA) + waveWind * Sin(waveMulB);
+
+ vA.z = (waveA * Cos(waveMulA)) - (waveB * Cos(waveMulB));
+ vB.z = (waveA * Cos(waveMulA)) + (waveB * Cos(waveMulB));
- float fVertexX = (float)i * 4.0f + fX;
- float fVertexY = (float)j * 4.0f + fY;
+ CVector norm = CrossProduct(vA, vB);
+ norm.Normalise();
- float fDistMult = 0.0f;
-
- for ( int32 k = 0; k < 4; k++ )
- {
- if ( apBoatList[k] != nil )
- fDistMult += CBoat::IsVertexAffectedByWake(CVector(fVertexX, fVertexY, 0.0f), apBoatList[k]);
- }
-
- if ( fDistMult > 0.0f )
+ wavyMorphNormals->x = norm.x;
+ wavyMorphNormals->y = norm.y;
+ wavyMorphNormals->z = norm.z;
+
+ ++wavyPreLight;
+ ++wavyTexCoords;
+
+ ++wavyMorphVerts;
+ ++wavyMorphNormals;
+ }
+ }
+
+ RpGeometryUnlock(wavyGeometry);
+
+ return true;
+}
+
+bool
+CWaterLevel::PreCalcWavyMask(float fX, float fY, float fZ,
+ float fSectorX, float fSectorY,
+ float fCamPosX, float fCamPosY,
+ float fCamDirX, float fCamDirY,
+ RwRGBA const&color)
+{
+ CVector vecSectorPos(fX + (MAX_LARGE_SECTORS/2), fY + (MAX_LARGE_SECTORS/2), fZ + 2.0f);
+
+ if ( COcclusion::IsAABoxOccluded(vecSectorPos, MAX_LARGE_SECTORS, MAX_LARGE_SECTORS, 4.0f) )
+ return false;
+
+ Floor(fX / MAX_LARGE_SECTORS);
+ Floor(fY / MAX_LARGE_SECTORS);
+
+ RpGeometry *wavyGeometry = RpAtomicGetGeometry(ms_pWavyAtomic);
+ RpMorphTarget *wavyMorph = RpGeometryGetMorphTarget(wavyGeometry, 0);
+ RwV3d *wavyMorphVerts = RpMorphTargetGetVertices(wavyMorph);
+ RwV3d *wavyMorphNormals = RpMorphTargetGetVertexNormals(wavyMorph);
+
+ RpGeometry *maskGeometry = RpAtomicGetGeometry(ms_pMaskAtomic);
+ RwTexCoords *maskTexCoords = RpGeometryGetVertexTexCoords(maskGeometry, rwTEXTURECOORDINATEINDEX0);
+ RwRGBA *maskPreLight = RpGeometryGetPreLightColors(maskGeometry);
+ RpMorphTarget *maskMorph = RpGeometryGetMorphTarget(maskGeometry, 0);
+ RwV3d *maskMorphVerts = RpMorphTargetGetVertices(maskMorph);
+ RwV3d *maskMorphNormals = RpMorphTargetGetVertexNormals(maskMorph);
+
+ if ( !m_bRenderSeaBed )
+ RpGeometryLock(maskGeometry, rpGEOMETRYLOCKVERTICES | rpGEOMETRYLOCKNORMALS | rpGEOMETRYLOCKPRELIGHT | rpGEOMETRYLOCKTEXCOORDS);
+
+
+ float fMinSparkZ = (fWave2Ampl * CWeather::WindClipped + 0.05f +
+ 0.4f * CWeather::WindClipped + 0.2) * (1.0f - 0.02f * CWeather::SunGlare);
+
+ int32 randval = CGeneral::GetRandomNumber() & 255;
+
+ int16 nX = _RoundValue((int32)((fX - fSectorX) * 0.5f) - 1);
+ int16 nY = _RoundValue((int32)((fY - fSectorY) * 0.5f) - 1);
+
+ int16 idxX = nX;
+
+ for ( int32 i = 0; i < 17; i++ )
+ {
+ int16 idxY = nY;
+
+ if ( ++idxX > 16 )
+ idxX -= 16;
+
+ for ( int32 j = 0; j < 17; j++ )
+ {
+ if ( ++idxY > 16 )
+ idxY -= 16;
+
+ const int32 a = (0*16);
+ const int32 b = (1*16);
+ const int32 c = (33*16);
+ const int32 d = (34*16);
+
+ int32 base = (i*33+j);
+
+ maskTexCoords[base+a].v = float(j) / 32 + ((fCamPosY - fY) / 64);
+ maskTexCoords[base+c].v = maskTexCoords[base+a].v;
+ maskTexCoords[base+d].v = maskTexCoords[base+a].v + 0.5f;
+ maskTexCoords[base+b].v = maskTexCoords[base+d].v;
+
+ maskTexCoords[base+a].u = float(i) / 32 + ((fCamPosX - fX) / 64);
+ maskTexCoords[base+b].u = maskTexCoords[base+a].u;
+ maskTexCoords[base+d].u = maskTexCoords[base+a].u + 0.5f;
+ maskTexCoords[base+c].u = maskTexCoords[base+d].u;
+
+ maskMorphVerts[base+a].x = (wavyMorphVerts[idxY + (17 * idxX)].x - (float)idxX * 2.0f) + (float(i) * 2.0f);
+ maskMorphVerts[base+b].x = maskMorphVerts[base+a].x;
+ maskMorphVerts[base+c].x = maskMorphVerts[base+a].x + SMALL_SECTOR_SIZE;
+ maskMorphVerts[base+d].x = maskMorphVerts[base+c].x;
+
+ maskMorphVerts[base+a].y = (wavyMorphVerts[idxY + (17 * idxX)].y - (float)idxY * 2.0f) + (float(j) * 2.0f);
+ maskMorphVerts[base+c].y = maskMorphVerts[base+a].y;
+ maskMorphVerts[base+b].y = maskMorphVerts[base+a].y + SMALL_SECTOR_SIZE;
+ maskMorphVerts[base+d].y = maskMorphVerts[base+b].y;
+
+ maskMorphVerts[base+a].z = wavyMorphVerts[idxY + (17 * idxX)].z;
+ maskMorphVerts[base+d].z = maskMorphVerts[base+a].z;
+ maskMorphVerts[base+c].z = maskMorphVerts[base+d].z;
+ maskMorphVerts[base+b].z = maskMorphVerts[base+c].z;
+
+ if ( maskMorphVerts[base].z > fMinSparkZ )
+ {
+ switch ( (i + j + randval) & 3 )
{
- RwRGBA wakeColor;
-
- RwRGBAAssign(&wakeColor, &color);
+ case 0:
+ {
+ CVector vecPos
+ (
+ fX + maskMorphVerts[base+a].x,
+ fY + maskMorphVerts[base+a].y,
+ fZ + maskMorphVerts[base+a].z + 0.12f
+ );
+
+ vecPos -= 0.05f * TheCamera.GetForward();
+
+ CParticle::AddParticle(PARTICLE_WATER_SPARK,
+ vecPos,
+ CVector(0.0f, 0.0f, 0.0f),
+ nil,
+ 0.0f,
+ 15,
+ CGeneral::GetRandomNumberInRange(-90, 90),
+ 0,
+ 0);
+ }
+ break;
- wakeColor.red = Min(color.red + int32(fWakeColor * fRedMult * fDistMult), 255);
- wakeColor.green = Min(color.green + int32(fWakeColor * fGreenMult * fDistMult), 255);
- wakeColor.blue = Min(color.blue + int32(fWakeColor * fBlueMult * fDistMult), 255);
-
- RwRGBAAssign(&geomPreLights[9*i+j], &wakeColor);
+ case 1:
+ {
+ CVector vecPos
+ (
+ fX + maskMorphVerts[base+c].x,
+ fY + maskMorphVerts[base+c].y,
+ fZ + maskMorphVerts[base+c].z + 0.12f
+ );
+
+ vecPos -= 0.05f * TheCamera.GetForward();
+
+ CParticle::AddParticle(PARTICLE_WATER_SPARK,
+ vecPos,
+ CVector(0.0f, 0.0f, 0.0f),
+ nil,
+ 0.0f,
+ 15,
+ CGeneral::GetRandomNumberInRange(-90, 90),
+ 0,
+ 0);
+ }
+ break;
+
+ case 2:
+ {
+ CVector vecPos
+ (
+ fX + maskMorphVerts[base+b].x,
+ fY + maskMorphVerts[base+b].y,
+ fZ + maskMorphVerts[base+b].z + 0.12f
+ );
+
+ vecPos -= 0.05f * TheCamera.GetForward();
+
+ CParticle::AddParticle(PARTICLE_WATER_SPARK,
+ vecPos,
+ CVector(0.0f, 0.0f, 0.0f),
+ nil,
+ 0.0f,
+ 15,
+ CGeneral::GetRandomNumberInRange(-90, 90),
+ 0,
+ 0);
+ }
+ break;
+ case 3:
+ {
+ CVector vecPos
+ (
+ fX + maskMorphVerts[base+d].x,
+ fY + maskMorphVerts[base+d].y,
+ fZ + maskMorphVerts[base+d].z + 0.12f
+ );
+
+ vecPos -= 0.05f * TheCamera.GetForward();
+
+ CParticle::AddParticle(PARTICLE_WATER_SPARK,
+ vecPos,
+ CVector(0.0f, 0.0f, 0.0f),
+ nil,
+ 0.0f,
+ 15,
+ CGeneral::GetRandomNumberInRange(-90, 90),
+ 0,
+ 0);
+ }
+ break;
}
- else
- RwRGBAAssign(&geomPreLights[9*i+j], &color);
-
-
- geomVertices[9*i+j].z = wavyVertices[9*i+j].z;
}
+
+ maskMorphNormals[base+a].x = wavyMorphNormals[idxY + (17 * idxX)].x;
+ maskMorphNormals[base+a].y = wavyMorphNormals[idxY + (17 * idxX)].y;
+ maskMorphNormals[base+a].z = wavyMorphNormals[idxY + (17 * idxX)].z;
+
+ maskMorphNormals[base+d].x = maskMorphNormals[base+a].x;
+ maskMorphNormals[base+d].y = maskMorphNormals[base+a].y;
+ maskMorphNormals[base+d].z = maskMorphNormals[base+a].z;
+
+ maskMorphNormals[base+c].x = maskMorphNormals[base+d].x;
+ maskMorphNormals[base+c].y = maskMorphNormals[base+d].y;
+ maskMorphNormals[base+c].z = maskMorphNormals[base+d].z;
+
+ maskMorphNormals[base+b].x = maskMorphNormals[base+c].x;
+ maskMorphNormals[base+b].y = maskMorphNormals[base+c].y;
+ maskMorphNormals[base+b].z = maskMorphNormals[base+c].z;
+
+ maskPreLight[base+a].red = color.red;
+ maskPreLight[base+a].green = color.green;
+ maskPreLight[base+a].blue = color.blue;
+ maskPreLight[base+a].alpha = color.alpha;
+
+ maskPreLight[base+d].red = maskPreLight[base+a].red;
+ maskPreLight[base+d].green = maskPreLight[base+a].green;
+ maskPreLight[base+d].blue = maskPreLight[base+a].blue;
+ maskPreLight[base+d].alpha = maskPreLight[base+a].alpha;
+
+ maskPreLight[base+c].red = maskPreLight[base+d].red;
+ maskPreLight[base+c].green = maskPreLight[base+d].green;
+ maskPreLight[base+c].blue = maskPreLight[base+d].blue;
+ maskPreLight[base+c].alpha = maskPreLight[base+d].alpha;
+
+ maskPreLight[base+b].red = maskPreLight[base+c].red;
+ maskPreLight[base+b].green = maskPreLight[base+c].green;
+ maskPreLight[base+b].blue = maskPreLight[base+c].blue;
+ maskPreLight[base+b].alpha = maskPreLight[base+c].alpha;
}
+ }
+
+ RpGeometryUnlock(maskGeometry);
+ return true;
+}
+#endif
+
+void
+CWaterLevel::RenderBoatWakes(void)
+{
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)gpWaterWakeRaster);
+#ifndef PC_WATER
+ RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void *)TRUE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA);
+#endif
+
+#ifdef _XBOX
+ // TODO save and restore rwRENDERSTATESRCBLEND rwRENDERSTATEDESTBLEND
+#endif
+
+ CBoat::FillBoatList();
+
+ float fWakeZ = 5.97f;
+ float fWakeLifeTimeMult = 0.01f / CBoat::WAKE_LIFETIME;
+
+ for ( int32 idx = 0; idx < ARRAY_SIZE(CBoat::apFrameWakeGeneratingBoats); idx++ )
+ {
+ CBoat *pBoat = CBoat::apFrameWakeGeneratingBoats[idx];
+
+ if ( pBoat == nil )
+ break;
+
+ CVector2D vecDistA(pBoat->GetForward().x, pBoat->GetForward().y);
+
+
+ float fSize = pBoat->GetColModel()->boundingBox.max.z
+ * 0.65f;
- RpGeometryUnlock(geom);
+ if ( pBoat->GetModelIndex() == MI_SKIMMER)
+ fSize *= 0.4f;
+ float fAplhaA = 255.0f;
+ float fSizeA = fSize;
+ float fAplhaB;
+ float fSizeB;
- RwV3d pos = {0.0f, 0.0f, 0.0f};
+ for ( int32 wake = 1; wake < pBoat->m_nNumWakePoints; wake++ )
+ {
+ bool bRender = true;
+
+ float fTimeleft = CBoat::WAKE_LIFETIME - pBoat->m_afWakePointLifeTime[wake];
- pos.x = fX;
- pos.z = fZ;
- pos.y = fY;
+ float fWakeSizeB = ((float)wake * 0.19f) + fSize - fWakeLifeTimeMult * Max(fTimeleft, 0.0f);
+
+ fSizeB = fWakeSizeB / CBoat::MIN_WAKE_INTERVAL;
+ if ( fSizeB < 0.0f )
+ fSizeB = 1.0f;
+
+ if ( wake == pBoat->m_nNumWakePoints - 1 )
+ {
+ // set alpha to 0 if it's last point
+ fAplhaB = 0.0f;
+ }
+ else
+ {
+ // clip (-100, 500), less lifetime - less val
+ float val = 500.0f - (CBoat::WAKE_LIFETIME - pBoat->m_afWakePointLifeTime[wake])
+ * 600.0f / CBoat::WAKE_LIFETIME;
+
+ fAplhaB = Clamp(val, 0.0f, 255.0f);
+ }
- RwFrameTranslate(RpAtomicGetFrame(atomic), &pos, rwCOMBINEREPLACE);
+ CVector2D vecDistB = pBoat->m_avec2dWakePoints[wake - 1] - pBoat->m_avec2dWakePoints[wake];
- RpAtomicRender(atomic);
-
- RpAtomicDestroy(atomic);
- RwFrameDestroy(frame);
+ float fScal = vecDistB.MagnitudeSqr();
+
+ // normalize if distance between points is greater than 3
+
+ if ( fScal > SQR(3.0f) )
+ {
+ float fNorm = 1.0f / sqrt(fScal);
+
+ vecDistB.x *= fNorm;
+ vecDistB.y *= fNorm;
+
+ // disable render if distance between points too big
+
+ if ( sqrt(fScal) > 13.0f )
+ bRender = false;
+ }
+
+ CVector2D vecAA
+ (
+ pBoat->m_avec2dWakePoints[wake - 1].x - (fSizeA * vecDistA.y),
+ pBoat->m_avec2dWakePoints[wake - 1].y + (fSizeA * vecDistA.x)
+ );
+ CVector2D vecAB
+ (
+ pBoat->m_avec2dWakePoints[wake - 1].x + (fSizeA * vecDistA.y),
+ pBoat->m_avec2dWakePoints[wake - 1].y - (fSizeA * vecDistA.x)
+ );
+ CVector2D vecBA
+ (
+ pBoat->m_avec2dWakePoints[wake].x + (fSizeB * vecDistB.y),
+ pBoat->m_avec2dWakePoints[wake].y - (fSizeB * vecDistB.x)
+ );
+ CVector2D vecBB
+ (
+ pBoat->m_avec2dWakePoints[wake].x - (fSizeB * vecDistB.y),
+ pBoat->m_avec2dWakePoints[wake].y + (fSizeB * vecDistB.x)
+ );
+
+ if ( bRender )
+ RenderWakeSegment(vecAA, vecAB, vecBA, vecBB, fSizeA, fSizeB, fAplhaA, fAplhaB, fWakeZ);
+
+ vecDistA = vecDistB;
+ fSizeA = fSizeB;
+
+ fAplhaB = fAplhaA;
+ }
}
- else
+
+ RenderAndEmptyRenderBuffer();
+}
+
+inline float
+_GetWindedWave(float fX, float fY)
+{
+ float fAngle = (CTimer::GetTimeInMilliseconds() & 4095) * (TWOPI / 4096.0f);
+ float x = WATER_HUGE_X(fX + WATER_X_OFFSET);
+ float y = WATER_HUGE_Y(fY);
+
+ float fWindFactor (CWeather::WindClipped * 0.4f + 0.2f);
+ float fWave = Sin(( (x - Floor(x)) + (y - Floor(y)) ) * TWOPI + fAngle);
+
+ return fWindFactor * fWave;
+}
+
+void
+CWaterLevel::RenderWakeSegment(CVector2D &vecA, CVector2D &vecB, CVector2D &vecC, CVector2D &vecD,
+ float &fSizeA, float &fSizeB,
+ float &fAlphaA, float &fAlphaB,
+ float &fWakeZ)
+{
+ for ( int32 i = 0; i < 4; i++ )
{
- RwV3d pos = { 0.0f, 0.0f, 0.0f };
+ if ( TempBufferIndicesStored >= TEMPBUFFERINDEXSIZE-6 || TempBufferVerticesStored >= TEMPBUFFERVERTSIZE-4 )
+ RenderAndEmptyRenderBuffer();
+
+ float fCurStep = (float)i / 4;
+ float fNxtStep = (float)(i + 1) / 4;
+
+ float fLeftCurStep = 1.0f - fCurStep;
+ float fLeftNxtStep = 1.0f - fNxtStep;
- pos.x = fX;
- pos.y = fY;
- pos.z = fZ;
+ uint8 AlphaA = (uint32)(fAlphaA * aAlphaFade[i] );
+ uint8 AlphaB = (uint32)(fAlphaA * aAlphaFade[i + 1]);
+ uint8 AlphaC = (uint32)(fAlphaB * aAlphaFade[i + 1]);
+ uint8 AlphaD = (uint32)(fAlphaB * aAlphaFade[i] );
+
+ CVector2D PosA = vecB*fCurStep + vecA*fLeftCurStep;
+ CVector2D PosB = vecB*fNxtStep + vecA*fLeftNxtStep;
+ CVector2D PosC = vecC*fNxtStep + vecD*fLeftNxtStep;
+ CVector2D PosD = vecC*fCurStep + vecD*fLeftCurStep;
+
+ float fUA = (PosA.x / 4) + _TEXTURE_WAKE_ADDU;
+ float fVA = (PosA.y / 4) + _TEXTURE_WAKE_ADDV;
+
+ float fUB = (PosB.x / 4) + _TEXTURE_WAKE_ADDU;
+ float fVB = (PosB.y / 4) + _TEXTURE_WAKE_ADDV;
+
+ float fUC = (PosC.x / 4) + _TEXTURE_WAKE_ADDU;
+ float fVC = (PosC.y / 4) + _TEXTURE_WAKE_ADDV;
+
+ float fUD = (PosD.x / 4) + _TEXTURE_WAKE_ADDU;
+ float fVD = (PosD.y / 4) + _TEXTURE_WAKE_ADDV;
- ASSERT( ms_pWavyAtomic != nil );
+#define MIN4(a, b, c, d) (Min((a), Min((b), Min((c), (d)))))
+ float fMinU = Floor(MIN4(fUA, fUB, fUC, fUD));
+ float fMinV = Floor(MIN4(fVA, fVB, fVC, fVD));
+#undef MIN4
+
+ float fZA = _GetWindedWave(PosA.x, PosA.y) + fWakeZ;
+ float fZB = _GetWindedWave(PosB.x, PosB.y) + fWakeZ;
+ float fZC = _GetWindedWave(PosC.x, PosC.y) + fWakeZ;
+ float fZD = _GetWindedWave(PosD.x, PosD.y) + fWakeZ;
+
+ int32 vidx = TempBufferVerticesStored;
+
+ RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 0], PosA.x, PosA.y, fZA);
+ RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 0], fUA - fMinU);
+ RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 0], fVA - fMinV);
+ RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 0], 255, 255, 255, AlphaA);
+
+ RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 1], PosB.x, PosB.y, fZB);
+ RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 1], fUB - fMinU);
+ RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 1], fVB - fMinV);
+ RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 1], 255, 255, 255, AlphaB);
+
+ RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 2], PosC.x, PosC.y, fZC);
+ RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 2], fUC - fMinU);
+ RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 2], fVC - fMinV);
+ RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 2], 255, 255, 255, AlphaC);
+
+ RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 3], PosD.x, PosD.y, fZD);
+ RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 3], fUD - fMinU);
+ RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 3], fVD - fMinV);
+ RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 3], 255, 255, 255, AlphaD);
- RwFrameTranslate(RpAtomicGetFrame(ms_pWavyAtomic), &pos, rwCOMBINEREPLACE);
+ int32 iidx = TempBufferIndicesStored;
+
+ TempBufferRenderIndexList[iidx + 0] = TempBufferVerticesStored + 0;
+ TempBufferRenderIndexList[iidx + 1] = TempBufferVerticesStored + 2;
+ TempBufferRenderIndexList[iidx + 2] = TempBufferVerticesStored + 1;
+ TempBufferRenderIndexList[iidx + 3] = TempBufferVerticesStored + 0;
+ TempBufferRenderIndexList[iidx + 4] = TempBufferVerticesStored + 3;
+ TempBufferRenderIndexList[iidx + 5] = TempBufferVerticesStored + 2;
- RpAtomicRender(ms_pWavyAtomic);
+ TempBufferVerticesStored += 4;
+
+ TempBufferIndicesStored += 6;
}
}
+void
+CWaterLevel::RenderOneSlopedUnderWaterPoly(float fX, float fY, float fZ, RwRGBA const&color)
+{
+ CVector2D camPos(TheCamera.GetPosition().x, TheCamera.GetPosition().y);
+
+ float fDistA = (CVector2D(fX, fY) - camPos).Magnitude() + -140.0f;
+ float fDistB = (CVector2D(fX, fY + HUGE_SECTOR_SIZE) - camPos).Magnitude() + -140.0f;
+ float fDistC = (CVector2D(fX + HUGE_SECTOR_SIZE, fY + HUGE_SECTOR_SIZE) - camPos).Magnitude() + -140.0f;
+ float fDistD = (CVector2D(fX + HUGE_SECTOR_SIZE, fY) - camPos).Magnitude() + -140.0f;
+
+#ifndef PC_WATER
+#define CALCSEABED(v, d) \
+ { \
+ if ( d < 0.0f ) \
+ v = 0.1f + fSeaBedZ; \
+ else if ( d > 240.0f ) \
+ v = 0.1f; \
+ else \
+ v = 0.1f + ((fSeaBedZ * (240.0f - d)) / 240.0f); \
+ }
+#else
+ #define CALCSEABED(v, d) \
+ { \
+ v = 0.1f; \
+ if ( d < 0.0f ) \
+ v += fSeaBedZ; \
+ else if ( d <= 240.0f ) \
+ v += (fSeaBedZ / 240.0f) * (240.0f - d); \
+ }
+#endif
+ float fSeaBedA, fSeaBedB, fSeaBedC, fSeaBedD;
+
+ CALCSEABED(fSeaBedA, fDistA);
+ CALCSEABED(fSeaBedB, fDistB);
+ CALCSEABED(fSeaBedC, fDistC);
+ CALCSEABED(fSeaBedD, fDistD);
+
+ #undef CALCSEABED
+
+ if ( TempBufferIndicesStored >= TEMPBUFFERINDEXSIZE-6 || TempBufferVerticesStored >= TEMPBUFFERVERTSIZE-4 )
+ RenderAndEmptyRenderBuffer();
+
+ int32 vidx = TempBufferVerticesStored;
+
+ RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 0], fX, fY, fZ - _fWaterZOffset - fSeaBedA);
+ RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 0], 0.0f);
+ RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 0], 0.0f);
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[vidx + 0], color.red, color.green, color.blue, 255);
+
+ RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 1], fX, fY + HUGE_SECTOR_SIZE, fZ - _fWaterZOffset - fSeaBedB);
+ RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 1], 0.0f);
+ RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 1], 4.0f);
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[vidx + 1], color.red, color.green, color.blue, 255);
+
+ RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 2], fX + HUGE_SECTOR_SIZE, fY + HUGE_SECTOR_SIZE, fZ - _fWaterZOffset - fSeaBedC);
+ RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 2], 4.0f);
+ RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 2], 4.0f);
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[vidx + 2], color.red, color.green, color.blue, 255);
+
+ RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 3], fX + HUGE_SECTOR_SIZE, fY, fZ - _fWaterZOffset - fSeaBedD);
+ RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 3], 4.0f);
+ RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 3], 0.0f);
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[vidx + 3], color.red, color.green, color.blue, 255);
+
+ int32 iidx = TempBufferIndicesStored;
+
+ TempBufferRenderIndexList[iidx + 0] = TempBufferVerticesStored + 0;
+ TempBufferRenderIndexList[iidx + 1] = TempBufferVerticesStored + 2;
+ TempBufferRenderIndexList[iidx + 2] = TempBufferVerticesStored + 1;
+ TempBufferRenderIndexList[iidx + 3] = TempBufferVerticesStored + 0;
+ TempBufferRenderIndexList[iidx + 4] = TempBufferVerticesStored + 3;
+ TempBufferRenderIndexList[iidx + 5] = TempBufferVerticesStored + 2;
+
+ TempBufferVerticesStored += 4;
+
+ TempBufferIndicesStored += 6;
+}
+
+void
+CWaterLevel::RenderOneFlatSmallWaterPolyBlended(float fX, float fY, float fZ, float fCamX, float fCamY,
+ RwRGBA const &color, RwRGBA const &colorTrans,
+ float fDrawDist)
+{
+ if ( TempBufferIndicesStored >= TEMPBUFFERINDEXSIZE-6 || TempBufferVerticesStored >= TEMPBUFFERVERTSIZE-4 )
+ RenderAndEmptyRenderBuffer();
+
+ int32 vidx = TempBufferVerticesStored;
+
+ float fBlendDrawDist = fDrawDist + fStartBlendDistanceAdd;
+
+ float fDistStartX = SQR(fX - fCamX);
+ float fDistStartY = SQR(fY - fCamY);
+ float fDistEndX = SQR((fX + SMALL_SECTOR_SIZE) - fCamX);
+ float fDistEndY = SQR((fY + SMALL_SECTOR_SIZE) - fCamY);
+
+
+ float fAlphaBlendMulA
+ = Min(fFlatWaterBlendRange * Max(sqrt(fDistStartX + fDistStartY) - fBlendDrawDist, fMinWaterAlphaMult), 1.0f);
+ float fAlphaBlendMulB
+ = Min(fFlatWaterBlendRange * Max(sqrt(fDistStartX + fDistEndY ) - fBlendDrawDist, fMinWaterAlphaMult), 1.0f);
+ float fAlphaBlendMulC
+ = Min(fFlatWaterBlendRange * Max(sqrt(fDistEndX + fDistEndY ) - fBlendDrawDist, fMinWaterAlphaMult), 1.0f);
+ float fAlphaBlendMulD
+ = Min(fFlatWaterBlendRange * Max(sqrt(fDistEndX + fDistStartY) - fBlendDrawDist, fMinWaterAlphaMult), 1.0f);
+
+
+ RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 0], fX, fY, fZ - _fWaterZOffset);
+ RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 0], TEXTURE_ADDU);
+ RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 0], TEXTURE_ADDV);
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[vidx + 0], color.red, color.green, color.blue,
+ (colorTrans.alpha + (color.alpha - colorTrans.alpha) * (uint8)(int32)fAlphaBlendMulA));
+
+ RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 1], fX, fY + SMALL_SECTOR_SIZE, fZ - _fWaterZOffset);
+ RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 1], TEXTURE_ADDU);
+ RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 1], TEXTURE_ADDV + 1.0f);
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[vidx + 1], color.red, color.green, color.blue,
+ (colorTrans.alpha + (color.alpha - colorTrans.alpha) * (uint8)(int32)fAlphaBlendMulB));
+
+ RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 2], fX + SMALL_SECTOR_SIZE, fY + SMALL_SECTOR_SIZE, fZ - _fWaterZOffset);
+ RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 2], TEXTURE_ADDU + 1.0f);
+ RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 2], TEXTURE_ADDV + 1.0f);
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[vidx + 2], color.red, color.green, color.blue,
+ (colorTrans.alpha + (color.alpha - colorTrans.alpha) * (uint8)(int32)fAlphaBlendMulC));
+
+ RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 3], fX + SMALL_SECTOR_SIZE, fY, fZ - _fWaterZOffset);
+ RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 3], TEXTURE_ADDU + 1.0f);
+ RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 3], TEXTURE_ADDV);
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[vidx + 3], color.red, color.green, color.blue,
+ (colorTrans.alpha + (color.alpha - colorTrans.alpha) * (uint8)(int32)fAlphaBlendMulD));
+
+
+ int32 iidx = TempBufferIndicesStored;
+
+ TempBufferRenderIndexList[iidx + 0] = TempBufferVerticesStored + 0;
+ TempBufferRenderIndexList[iidx + 1] = TempBufferVerticesStored + 2;
+ TempBufferRenderIndexList[iidx + 2] = TempBufferVerticesStored + 1;
+ TempBufferRenderIndexList[iidx + 3] = TempBufferVerticesStored + 0;
+ TempBufferRenderIndexList[iidx + 4] = TempBufferVerticesStored + 3;
+ TempBufferRenderIndexList[iidx + 5] = TempBufferVerticesStored + 2;
+
+ TempBufferVerticesStored += 4;
+
+ TempBufferIndicesStored += 6;
+}
+
float
CWaterLevel::CalcDistanceToWater(float fX, float fY)
{
- const float fSectorMaxRenderDist = 75.0f;
+ const float fSectorMaxRenderDist = 250.0f;
- int32 nStartX = WATER_TO_SMALL_SECTOR_X(fX - fSectorMaxRenderDist) - 1;
- int32 nEndX = WATER_TO_SMALL_SECTOR_X(fX + fSectorMaxRenderDist) + 1;
+ int32 nStartX = WATER_TO_SMALL_SECTOR_X(fX - fSectorMaxRenderDist + WATER_X_OFFSET) - 1;
+ int32 nEndX = WATER_TO_SMALL_SECTOR_X(fX + fSectorMaxRenderDist + WATER_X_OFFSET) + 1;
int32 nStartY = WATER_TO_SMALL_SECTOR_Y(fY - fSectorMaxRenderDist) - 1;
int32 nEndY = WATER_TO_SMALL_SECTOR_Y(fY + fSectorMaxRenderDist) + 1;
@@ -1419,7 +2901,7 @@ CWaterLevel::CalcDistanceToWater(float fX, float fY)
{
if ( aWaterFineBlockList[x][y] >= 0 )
{
- float fSectorX = WATER_FROM_SMALL_SECTOR_X(x);
+ float fSectorX = WATER_FROM_SMALL_SECTOR_X(x) - WATER_X_OFFSET;
float fSectorY = WATER_FROM_SMALL_SECTOR_Y(y);
CVector2D vecDist
@@ -1454,101 +2936,442 @@ CWaterLevel::RenderAndEmptyRenderBuffer()
TempBufferVerticesStored = 0;
}
-void
-CWaterLevel::AllocateBoatWakeArray()
+bool
+CWaterLevel::GetGroundLevel(CVector const &vecPosn, float *pfOutLevel, ColData *pData, float fDistance)
{
- CStreaming::MakeSpaceFor(14 * CDSTREAM_SECTOR_SIZE);
+ CColPoint point;
+ CEntity *entity;
+
+ if ( !CWorld::ProcessVerticalLine(vecPosn + CVector(0.0f, 0.0f, fDistance),
+ -fDistance, point, entity, true, false, false, false, true, false, nil) )
+ return false;
+
+ *pfOutLevel = point.point.z;
+
+ if ( pData != nil )
+ {
+ pData->SurfaceType = point.surfaceB;
+ pData->PieceType = point.pieceB;
+ }
+
+ return true;
+}
+
+bool
+CWaterLevel::IsLocationOutOfWorldBounds_WS(CVector const &vecPosn, int nOffset)
+{
+ int32 x = int32((vecPosn.x / 50.0f) + 48.0f);
+ int32 y = int32((vecPosn.y / 50.0f) + 40.0f);
+
+ return x < nOffset || x >= 80 - nOffset || y < nOffset || y >= 80 - nOffset;
+}
- PUSH_MEMID(MEMID_STREAM);
+bool
+CWaterLevel::GetGroundLevel_WS(CVector const &vecPosn, float *pfOutLevel, ColData *pData, float fDistance)
+{
+ if ( IsLocationOutOfWorldBounds_WS(vecPosn, 0) )
+ return false;
+ else
+ return GetGroundLevel(vecPosn, pfOutLevel, pData, fDistance);
+}
- ASSERT(ms_pWavyAtomic != nil );
+bool
+CWaterLevel::GetWaterDepth(CVector const &vecPosn, float *pfDepth, float *pfLevelNoWaves, float *pfGroundLevel)
+{
+ float fLevelNoWaves;
+ float fGroundLevel;
+
+ if ( !GetWaterLevelNoWaves(vecPosn.x, vecPosn.y, vecPosn.z, &fLevelNoWaves) )
+ return false;
+
+ if ( !GetGroundLevel(vecPosn, &fGroundLevel, nil, 30.0f) )
+ fGroundLevel = -100.0;
- RpGeometry *wavyGeometry = RpAtomicGetGeometry(ms_pWavyAtomic);
- ASSERT(wavyGeometry != nil );
- RpMorphTarget *wavyMorphTarget = RpGeometryGetMorphTarget(wavyGeometry, 0);
- RpMaterial *wavyMaterial = RpGeometryGetMaterial(wavyGeometry, 0);
+ if ( pfDepth != nil )
+ *pfDepth = fLevelNoWaves - fGroundLevel;
- ASSERT(wavyMorphTarget != nil );
- ASSERT(wavyMaterial != nil );
+ if ( pfLevelNoWaves != nil )
+ *pfLevelNoWaves = fLevelNoWaves;
- for ( int32 geom = 0; geom < MAX_BOAT_WAKES; geom++ )
+ if ( pfGroundLevel != nil )
+ *pfGroundLevel = fGroundLevel;
+
+ return true;
+}
+
+void
+CWaterLevel::RenderSeaBirds()
+{
+ CVector cur_pos = TheCamera.GetPosition();
+
+ if ( !CCullZones::CamNoRain()
+ && !CCullZones::PlayerNoRain()
+ && (CWeather::NewWeatherType == WEATHER_SUNNY || CWeather::NewWeatherType == WEATHER_EXTRA_SUNNY)
+ && CClock::ms_nGameClockHours > 6 && CClock::ms_nGameClockHours < 20 )
{
- if ( apGeomArray[geom] == nil )
+ static CVector prev_pos(0.0f, 0.0f, 0.0f);
+ static CVector prev_front(0.0f, 0.0f, 0.0f);
+ static int32 timecounter;
+
+ if ( Abs(prev_pos.x - cur_pos.x) + Abs(prev_pos.y - cur_pos.y) + Abs(prev_pos.z - cur_pos.z) > 1.5f )
{
- apGeomArray[geom] = RpGeometryCreate(9*9, 8*8*2, rpGEOMETRYTRISTRIP
- | rpGEOMETRYPRELIT
- | rpGEOMETRYMODULATEMATERIALCOLOR
- | rpGEOMETRYTEXTURED);
- ASSERT(apGeomArray[geom] != nil);
+ prev_pos = cur_pos;
+ timecounter = CTimer::GetTimeInMilliseconds();
+ }
+ else if ( (CTimer::GetTimeInMilliseconds() - timecounter) > 5000 )
+ {
+ static int32 birdgenTime = 0;
+
+ if ( (CTimer::GetTimeInMilliseconds() - birdgenTime) > 1000 )
+ {
+ birdgenTime = CTimer::GetTimeInMilliseconds();
+
+ CVector vecPos = cur_pos;
+
+ float fAngle = CGeneral::GetRandomNumberInRange(90.0f, 150.0f);
+
+ uint16 nSinCosIdx = CGeneral::GetRandomNumber() % (CParticle::SIN_COS_TABLE_SIZE-1);
+
+ float fCos = CParticle::Cos(nSinCosIdx);
+ float fSin = CParticle::Sin(nSinCosIdx);
+
+ vecPos.x += (fCos - fSin) * fAngle;
+ vecPos.y += (fSin + fCos) * fAngle;
+ vecPos.z += CGeneral::GetRandomNumberInRange(10.0f, 30.0f);
+
+ CVector vecDir(CGeneral::GetRandomNumberInRange(-1.0f, 1.0f),
+ CGeneral::GetRandomNumberInRange(-1.0f, 1.0f),
+ 0.0f);
+
+ CParticle::AddParticle(PARTICLE_BIRD_FRONT, vecPos, vecDir, nil, 0.0f, 0, 0, 0, 0);
+ }
+ }
+ }
+}
- RpTriangle *geomTriangles = RpGeometryGetTriangles(apGeomArray[geom]);
+void
+CWaterLevel::RenderShipsOnHorizon()
+{
+#ifdef FIX_BUGS
+ CVector cur_pos = FindPlayerCoors();
+#else
+ CVector cur_pos = FindPlayerPed()->GetPosition();
+#endif
+
+ static CVector prev_pos(0.0f, 0.0f, 0.0f);
+ static CVector prev_front(0.0f, 0.0f, 0.0f);
+ static int32 timecounter;
+
+ if ( Abs(prev_pos.x - cur_pos.x) + Abs(prev_pos.y - cur_pos.y) + Abs(prev_pos.z - cur_pos.z) > 1.5f )
+ {
+ prev_pos = cur_pos;
+ timecounter = CTimer::GetTimeInMilliseconds();
+ }
+ else if ( (CTimer::GetTimeInMilliseconds() - timecounter) > 5000 )
+ {
+ static int32 shipgenTime = 0;
+
+ if ( (CTimer::GetTimeInMilliseconds() - shipgenTime) > 4000 )
+ {
+ shipgenTime = CTimer::GetTimeInMilliseconds();
+
+ CVector vecPos = cur_pos;
- ASSERT( geomTriangles != nil );
+ float fAngle = CGeneral::GetRandomNumberInRange(450.0f, 750.0f);
+
+ uint16 nSinCosIdx = CGeneral::GetRandomNumber() % (CParticle::SIN_COS_TABLE_SIZE-1);
+
+ float fCos = CParticle::Cos(nSinCosIdx);
+ float fSin = CParticle::Sin(nSinCosIdx);
- for ( int32 i = 0; i < 8; i++ )
+ vecPos.x += (fCos - fSin) * fAngle;
+ vecPos.y += (fSin + fCos) * fAngle;
+
+ float fLevelNoWaves;
+
+ if ( GetWaterLevelNoWaves(vecPos.x, vecPos.y, vecPos.z, &fLevelNoWaves) )
{
- for ( int32 j = 0; j < 8; j++ )
+ if ( IsLocationOutOfWorldBounds_WS(vecPos, 1) )
{
+ vecPos.z = fLevelNoWaves + 9.5f;
- /*
- [B] [C]
- ***********
- * * *
- * * *
- * * *
- * * *
- ***********
- [A] [D]
- */
+ CVector vecDir
+ (
+ CGeneral::GetRandomNumberInRange(-0.1f, 0.1f),
+ 0.0f,
+ 0.0f
+ );
-
- RpGeometryTriangleSetVertexIndices(apGeomArray[geom],
- &geomTriangles[2 * 8*i + 2*j + 0], /*A*/i*9+j+0, /*B*/i*9+j+1, /*C*/i*9+j+9+1);
-
- RpGeometryTriangleSetVertexIndices(apGeomArray[geom],
- &geomTriangles[2 * 8*i + 2*j + 1], /*A*/i*9+j+0, /*C*/i*9+j+9+1, /*D*/i*9+j+9 );
-
- RpGeometryTriangleSetMaterial(apGeomArray[geom], &geomTriangles[2 * 8*i + 2*j + 0], wavyMaterial);
-
- RpGeometryTriangleSetMaterial(apGeomArray[geom], &geomTriangles[2 * 8*i + 2*j + 1], wavyMaterial);
+ CParticle::AddParticle(PARTICLE_SHIP_SIDE, vecPos, vecDir,
+ nil, 0.0f, 0, 0, CGeneral::GetRandomNumber() & 7, 0);
}
}
+ }
+ }
+}
- RpMorphTarget *geomMorphTarget = RpGeometryGetMorphTarget(apGeomArray[geom], 0);
- RwV3d *geomVertices = RpMorphTargetGetVertices(geomMorphTarget);
-
- ASSERT( geomMorphTarget != nil );
- ASSERT( geomVertices != nil );
+void
+CWaterLevel::HandleSeaLifeForms()
+{
+ if ( CReplay::IsPlayingBack() )
+ return;
+
+ CVector cur_pos = FindPlayerPed()->GetPosition();
- for ( int32 i = 0; i < 9; i++ )
+ static CVector prev_pos(0.0f, 0.0f, 0.0f);
+ static int32 timecounter;
+
+ if ( Abs(prev_pos.x - cur_pos.x) + Abs(prev_pos.y - cur_pos.y) + Abs(prev_pos.z - cur_pos.z) > 1.5f )
+ {
+ prev_pos = cur_pos;
+ timecounter = CTimer::GetTimeInMilliseconds();
+ }
+ else if ( (CTimer::GetTimeInMilliseconds() - timecounter) > 5000 )
+ {
+ if ( CWaterCreatures::IsSpaceForMoreWaterCreatures() )
+ {
+ for ( int32 i = 0; i < 3; i++ )
{
- for ( int32 j = 0; j < 9; j++ )
- {
- geomVertices[9*i+j].x = (float)i * 4.0f;
- geomVertices[9*i+j].y = (float)j * 4.0f;
- geomVertices[9*i+j].z = 0.0f;
- }
+ CVector vecPos = cur_pos;
+
+ float fAngle = CGeneral::GetRandomNumberInRange(15.0f, 30.0f);
+
+ uint16 nSinCosIdx = CGeneral::GetRandomNumber() % (CParticle::SIN_COS_TABLE_SIZE-1);
+
+ float fCos = CParticle::Cos(nSinCosIdx);
+ float fSin = CParticle::Sin(nSinCosIdx);
+
+ vecPos.x += (fCos - fSin) * fAngle;
+ vecPos.y += (fSin + fCos) * fAngle;
+
+ CWaterCreatures::CreateOne(vecPos, -1);
}
-
- RpMorphTargetSetBoundingSphere(geomMorphTarget, RpMorphTargetGetBoundingSphere(wavyMorphTarget));
- RpGeometryUnlock(apGeomArray[geom]);
}
}
-
- POP_MEMID();
+
+ CWaterCreatures::UpdateAll();
}
void
-CWaterLevel::FreeBoatWakeArray()
+CWaterLevel::HandleBeachToysStuff(void)
{
- for ( int32 i = 0; i < MAX_BOAT_WAKES; i++ )
+#ifdef FIX_BUGS
+ CVector cur_pos = FindPlayerCoors();
+#else
+ CVector cur_pos = FindPlayerPed()->GetPosition();
+#endif
+
+ static bool bBeachBallInit = true;
+ static CVector FirstBeachBallPos = cur_pos;
+ static bool bLoungeInit = true;
+ static CVector FirstLoungePos = cur_pos;
+ static CVector prev_pos(0.0f, 0.0f, 0.0f);
+ static int32 timecounter;
+
+ if ( Abs(prev_pos.x - cur_pos.x) + Abs(prev_pos.y - cur_pos.y) + Abs(prev_pos.z - cur_pos.z) > 1.5f )
+ {
+ prev_pos = cur_pos;
+ timecounter = CTimer::GetTimeInMilliseconds();
+ }
+ else if ( (CTimer::GetTimeInMilliseconds() - timecounter) > 5000 )
{
- if ( apGeomArray[i] != nil )
+ static int32 toygenTime = CTimer::GetTimeInMilliseconds();
+
+ if ( (CTimer::GetTimeInMilliseconds() - toygenTime) > 20000 )
{
- RpGeometryDestroy(apGeomArray[i]);
- apGeomArray[i] = nil;
+ toygenTime = CTimer::GetTimeInMilliseconds();
+
+ if ( bBeachBallInit || (cur_pos - FirstBeachBallPos).MagnitudeSqr() > 6400.0f )
+ {
+ for ( int32 i = 0; i < 3; i++ )
+ {
+ CVector vecPos = cur_pos;
+
+ float fAngle = CGeneral::GetRandomNumberInRange(20.0f, 35.0f);
+
+ uint16 nSinCosIdx = CGeneral::GetRandomNumber() % (CParticle::SIN_COS_TABLE_SIZE-1);
+
+ float fCos = CParticle::Cos(nSinCosIdx);
+ float fSin = CParticle::Sin(nSinCosIdx);
+
+ vecPos.x += (fCos - fSin) * fAngle;
+ vecPos.y += (fSin + fCos) * fAngle;
+
+ if ( TheCamera.IsSphereVisible(vecPos, 1.0f) )
+ {
+ float fWaterLevel;
+
+ if ( !GetWaterLevel(vecPos.x, vecPos.y, vecPos.z, &fWaterLevel, false) )
+ {
+ float fGroundLevel;
+ ColData coldata;
+
+ if ( GetGroundLevel(vecPos, &fGroundLevel, &coldata, 30.0f) )
+ {
+ if ( coldata.SurfaceType == SURFACE_SAND )
+ {
+ CEntity *toy = CreateBeachToy(vecPos, BEACHTOY_BALL);
+
+ if ( toy )
+ {
+ FirstBeachBallPos = cur_pos;
+ bBeachBallInit = false;
+ i = 10;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if ( bLoungeInit || (cur_pos - FirstLoungePos).MagnitudeSqr() > 6400.0f )
+ {
+ for ( int32 i = 0; i < 5; i++ )
+ {
+ CVector vecPos = cur_pos;
+
+ float fAngle = CGeneral::GetRandomNumberInRange(20.0f, 35.0f);
+
+ uint16 nSinCosIdx = CGeneral::GetRandomNumber() % (CParticle::SIN_COS_TABLE_SIZE-1);
+
+ float fCos = CParticle::Cos(nSinCosIdx);
+ float fSin = CParticle::Sin(nSinCosIdx);
+
+ vecPos.x += (fCos - fSin) * fAngle;
+ vecPos.y += (fSin + fCos) * fAngle;
+
+ if ( TheCamera.IsSphereVisible(vecPos, 2.0f) )
+ {
+ float fWaterLevel;
+
+ if ( !GetWaterLevel(vecPos.x, vecPos.y, vecPos.z, &fWaterLevel, false) )
+ {
+ float fGroundLevel;
+ ColData coldata;
+
+ if ( GetGroundLevel(vecPos, &fGroundLevel, &coldata, 30.0f) )
+ {
+ if ( coldata.SurfaceType == SURFACE_SAND )
+ {
+ CEntity *toy = CreateBeachToy(vecPos, BEACHTOY_ANY_LOUNGE);
+ if ( toy )
+ {
+ toy->SetHeading(DEGTORAD(CGeneral::GetRandomNumberInRange(0.0f, 359.0f)));
+ FirstLoungePos = cur_pos;
+ bLoungeInit = false;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
}
}
-
- nGeomUsed = 0;
}
+
+CEntity *
+CWaterLevel::CreateBeachToy(CVector const &vec, eBeachToy beachtoy)
+{
+ if (CObject::nNoTempObjects >= NUMTEMPOBJECTS)
+ return nil;
+
+ int finalToy = beachtoy;
+ bool isStatic = false;
+ int model = MI_BEACHBALL;
+ switch (beachtoy) {
+ case BEACHTOY_ANY_LOUNGE:
+ switch ( CGeneral::GetRandomNumber() & 7 ) {
+ case 1:
+ case 7:
+ finalToy = BEACHTOY_LOUNGE_WOOD_UP;
+ break;
+ case 3:
+ case 5:
+ finalToy = BEACHTOY_LOUNGE_TOWEL_UP;
+ break;
+ default:
+ finalToy = BEACHTOY_LOUNGE_WOOD_ON;
+ break;
+ }
+ break;
+ case BEACHTOY_ANY_TOWEL:
+ switch ( CGeneral::GetRandomNumber() & 7 ) {
+ case 1:
+ case 7:
+ finalToy = BEACHTOY_TOWEL2;
+ break;
+ case 2:
+ case 6:
+ finalToy = BEACHTOY_TOWEL3;
+ break;
+ case 3:
+ case 5:
+ finalToy = BEACHTOY_TOWEL4;
+ break;
+ default:
+ finalToy = BEACHTOY_TOWEL1;
+ break;
+ }
+ if (CObject::nNoTempObjects >= 35) {
+ return nil;
+ }
+ default:
+ break;
+ }
+ switch (finalToy) {
+ case BEACHTOY_BALL:
+ isStatic = false;
+ model = MI_BEACHBALL;
+ break;
+ case BEACHTOY_LOUNGE_WOOD_UP:
+ isStatic = false;
+ model = MI_LOUNGE_WOOD_UP;
+ break;
+ case BEACHTOY_LOUNGE_TOWEL_UP:
+ isStatic = false;
+ model = MI_LOUNGE_TOWEL_UP;
+ break;
+ case BEACHTOY_LOUNGE_WOOD_ON:
+ isStatic = false;
+ model = MI_LOUNGE_WOOD_DN;
+ break;
+ case BEACHTOY_LOTION:
+ model = MI_LOTION;
+ isStatic = true;
+ break;
+ case BEACHTOY_TOWEL1:
+ model = MI_BEACHTOWEL01;
+ isStatic = true;
+ break;
+ case BEACHTOY_TOWEL2:
+ model = MI_BEACHTOWEL02;
+ isStatic = true;
+ break;
+ case BEACHTOY_TOWEL3:
+ model = MI_BEACHTOWEL03;
+ isStatic = true;
+ break;
+ case BEACHTOY_TOWEL4:
+ model = MI_BEACHTOWEL04;
+ isStatic = true;
+ break;
+ default:
+ break;
+ }
+ CObject *toy = new CObject(model, true);
+ if (toy) {
+ toy->SetPosition(vec);
+ toy->GetMatrix().UpdateRW();
+ toy->m_vecMoveSpeed = CVector(0.f, 0.f, 0.f);
+ toy->m_vecTurnSpeed = CVector(0.f, 0.f, 0.f);
+ toy->ObjectCreatedBy = TEMP_OBJECT;
+ toy->bIsStatic = isStatic;
+ CObject::nNoTempObjects++;
+ toy->m_nEndOfLifeTime = CTimer::GetTimeInMilliseconds() + 43200000;
+ CWorld::Add(toy);
+ return toy;
+ } else
+ return nil;
+} \ No newline at end of file
diff --git a/src/renderer/WaterLevel.h b/src/renderer/WaterLevel.h
index b797f251..6d6614d8 100644
--- a/src/renderer/WaterLevel.h
+++ b/src/renderer/WaterLevel.h
@@ -1,6 +1,8 @@
#pragma once
-#define WATER_Z_OFFSET (1.5f)
+#define WATER_X_OFFSET (400.0f)
+
+#define WATER_Z_OFFSET (0.5f)
#define NO_WATER -128
@@ -28,6 +30,14 @@
#define WATER_SIGN_X(x) ( (x) - (WATER_WIDTH /2) )
#define WATER_SIGN_Y(y) ( (y) - (WATER_HEIGHT/2) )
+// 64x64 Large blocks 64x64 each
+#define WATER_TO_BLOCK_X(x) ( WATER_UNSIGN_X(x) / WATER_BLOCK_SECTORS )
+#define WATER_TO_BLOCK_Y(x) ( WATER_UNSIGN_Y(x) / WATER_BLOCK_SECTORS )
+
+// 128x128 Small blocks 32x32 each
+#define WATER_TO_FINEBLOCK_X(x) ( WATER_UNSIGN_X(x) / WATER_FINEBLOCK_SECTORS )
+#define WATER_TO_FINEBLOCK_Y(x) ( WATER_UNSIGN_Y(x) / WATER_FINEBLOCK_SECTORS )
+
// 32
#define WATER_SMALL_X(x) ( WATER_UNSIGN_X(x) / MAX_SMALL_SECTORS )
#define WATER_SMALL_Y(y) ( WATER_UNSIGN_Y(y) / MAX_SMALL_SECTORS )
@@ -60,44 +70,115 @@
#define WATER_TO_EXTRAHUGE_SECTOR_X(x) ( WATER_UNSIGN_X(x) / EXTRAHUGE_SECTOR_SIZE )
#define WATER_TO_EXTRAHUGE_SECTOR_Y(y) ( WATER_UNSIGN_Y(y) / EXTRAHUGE_SECTOR_SIZE )
+struct ColData
+{
+ uint8 SurfaceType;
+ uint8 PieceType;
+};
-#define MAX_BOAT_WAKES 8
+enum eBeachToy
+{
+ BEACHTOY_0 = 0,
+ BEACHTOY_BALL,
+ BEACHTOY_LOUNGE_WOOD_UP,
+ BEACHTOY_LOUNGE_TOWEL_UP,
+ BEACHTOY_LOUNGE_WOOD_ON,
+ BEACHTOY_ANY_LOUNGE,
+ BEACHTOY_LOTION,
+ BEACHTOY_TOWEL1,
+ BEACHTOY_TOWEL2,
+ BEACHTOY_TOWEL3,
+ BEACHTOY_TOWEL4,
+ BEACHTOY_ANY_TOWEL,
+};
extern RwRaster* gpWaterRaster;
extern bool gbDontRenderWater;
+class CEntity;
+
class CWaterLevel
{
+public:
static int32 ms_nNoOfWaterLevels;
static float ms_aWaterZs[48];
static CRect ms_aWaterRects[48];
- static int8 aWaterBlockList[MAX_LARGE_SECTORS][MAX_LARGE_SECTORS];
- static int8 aWaterFineBlockList[MAX_SMALL_SECTORS][MAX_SMALL_SECTORS];
+ static int8 aWaterBlockList[MAX_LARGE_SECTORS][MAX_LARGE_SECTORS]; // 64x64 Large blocks 64x64 each
+ static int8 aWaterFineBlockList[MAX_SMALL_SECTORS][MAX_SMALL_SECTORS]; // 128x128 Small blocks 32x32 each
static bool WavesCalculatedThisFrame;
- static RpAtomic *ms_pWavyAtomic;
- static RpGeometry *apGeomArray[MAX_BOAT_WAKES];
- static int16 nGeomUsed;
-public:
+ static bool RequireWavySector;
+ static bool MaskCalculatedThisFrame;
+ static CVector PreCalculatedMaskPosn;
+ static bool m_bRenderSeaBed;
+ static int32 m_nRenderWaterLayers;
+
+ static RpAtomic *ms_pWavyAtomic;
+ static RpAtomic *ms_pMaskAtomic;
+
static void Initialise(Const char *pWaterDat); // out of class in III PC and later because of SecuROM
static void Shutdown();
+
static void CreateWavyAtomic();
static void DestroyWavyAtomic();
+
static void AddWaterLevel(float fXLeft, float fYBottom, float fXRight, float fYTop, float fLevel);
static bool WaterLevelAccordingToRectangles(float fX, float fY, float *pfOutLevel = nil);
static bool TestVisibilityForFineWaterBlocks(const CVector &worldPos);
static void RemoveIsolatedWater();
+
static bool GetWaterLevel(float fX, float fY, float fZ, float *pfOutLevel, bool bDontCheckZ);
static bool GetWaterLevel(CVector coors, float *pfOutLevel, bool bDontCheckZ) { return GetWaterLevel(coors.x, coors.y, coors.z, pfOutLevel, bDontCheckZ); }
static bool GetWaterLevelNoWaves(float fX, float fY, float fZ, float *pfOutLevel);
+ static float GetWaterWavesOnly(short x, short y); // unused
+ static CVector GetWaterNormal(float fX, float fY);
+
static void RenderWater();
- static void RenderOneFlatSmallWaterPoly (float fX, float fY, float fZ, RwRGBA const &color);
- static void RenderOneFlatLargeWaterPoly (float fX, float fY, float fZ, RwRGBA const &color);
- static void RenderOneFlatHugeWaterPoly (float fX, float fY, float fZ, RwRGBA const &color);
- static void RenderOneFlatExtraHugeWaterPoly(float fX, float fY, float fZ, RwRGBA const &color);
- static void RenderOneWavySector (float fX, float fY, float fZ, RwRGBA const &color, bool bUnk = false);
- static float CalcDistanceToWater(float fX, float fY);
- static void RenderAndEmptyRenderBuffer();
- static void AllocateBoatWakeArray();
- static void FreeBoatWakeArray();
+ static void RenderTransparentWater(void);
+ // unused
+ static void RenderOneFlatSmallWaterPoly (float fX, float fY, float fZ, RwRGBA const &color);
+ // inlined
+ static void RenderOneFlatLargeWaterPoly (float fX, float fY, float fZ, RwRGBA const &color);
+ static void RenderOneFlatHugeWaterPoly (float fX, float fY, float fZ, RwRGBA const &color);
+ static void RenderOneFlatExtraHugeWaterPoly(float fX, float fY, float fZ, RwRGBA const &color);
+ // inlined
+ static void RenderOneWavySector (float fX, float fY, float fZ, RwRGBA const &color, bool bDontRender = false);
+ // unused
+#ifdef PC_WATER
+ static void RenderWavyMask(float fX, float fY, float fZ, float fSectorX, float fSectorY, float fCamPosX, float fCamPosY, float fCamDirX, float fCamDirY, RwRGBA const&color);
+#else
+ static void RenderWavyMask(float fX, float fY, float fZ, float fSectorX, float fSectorY, int32 nCamDirX, int32 nCamDirY, RwRGBA const&color);
+#endif
+
+#ifdef PC_WATER
+ static void PreCalcWaterGeometry(void);
+ static bool PreCalcWavySector(RwRGBA const &color); //fucked up
+ static bool PreCalcWavyMask(float fX, float fY, float fZ, float fSectorX, float fSectorY, float fCamPosX, float fCamPosY, float fCamDirX, float fCamDirY, RwRGBA const&color);
+#endif
+
+
+ static void RenderBoatWakes(void);
+ static void RenderWakeSegment(CVector2D &vecA, CVector2D &vecB, CVector2D &vecC, CVector2D &vecD, float &fSizeA, float &fSizeB, float &fAlphaA, float &fAlphaB, float &fWakeZ);
+
+ // unused
+ static void RenderOneSlopedUnderWaterPoly(float fX, float fY, float fZ, RwRGBA const&color); // UNUSED
+ static void RenderOneFlatSmallWaterPolyBlended(float fX, float fY, float fZ, float fCamX, float fCamY, RwRGBA const &color, RwRGBA const &colorTrans, float fDrawDist);
+ static float CalcDistanceToWater(float fX, float fY);
+ static void RenderAndEmptyRenderBuffer();
+
+ static bool GetGroundLevel(CVector const &vecPosn, float *pfOutLevel, ColData *pData, float fDistance);
+
+ // unused
+ static bool IsLocationOutOfWorldBounds_WS(CVector const &vecPosn, int nOffset);
+ // unused
+ static bool GetGroundLevel_WS(CVector const & vecPosn, float *pfOutLevel, ColData *pData, float fDistance);
+ static bool GetWaterDepth(CVector const &vecPosn, float *pfDepth, float *pfLevelNoWaves, float *pfGroundLevel);
+
+ static void RenderSeaBirds();
+ static void RenderShipsOnHorizon();
+
+ static void HandleSeaLifeForms();
+
+ static void HandleBeachToysStuff(void);
+ static CEntity *CreateBeachToy(CVector const &vec, eBeachToy beachtoy);
};
diff --git a/src/renderer/Weather.cpp b/src/renderer/Weather.cpp
index e57d57d6..9f925a8c 100644
--- a/src/renderer/Weather.cpp
+++ b/src/renderer/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,8 @@
#include "Vehicle.h"
#include "World.h"
#include "ZoneCull.h"
+#include "SpecialFX.h"
+#include "Replay.h"
int32 CWeather::SoundHandle = -1;
@@ -31,7 +34,9 @@ uint32 CWeather::LightningStart;
uint32 CWeather::LightningFlashLastChange;
uint32 CWeather::WhenToPlayLightningSound;
uint32 CWeather::LightningDuration;
+int32 CWeather::StreamAfterRainTimer;
+float CWeather::ExtraSunnyness;
float CWeather::Foggyness;
float CWeather::CloudCoverage;
float CWeather::Wind;
@@ -39,41 +44,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_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY,
- WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY,
- WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY,
+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_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_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_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
+};
+
+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_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 Windyness[] = {
- 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)
@@ -104,10 +128,9 @@ const float Windyness[] = {
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;
@@ -119,30 +142,27 @@ void CWeather::Init(void)
void CWeather::Update(void)
{
- float fNewInterpolation = CClock::GetMinutes() * 1.0f / 60;
- if (fNewInterpolation < InterpolationValue) {
- // new hour
- OldWeatherType = NewWeatherType;
- if (ForcedWeatherType >= 0)
- NewWeatherType = ForcedWeatherType;
- else {
- WeatherTypeInList = (WeatherTypeInList + 1) % ARRAY_SIZE(WeatherTypesList);
- NewWeatherType = WeatherTypesList[WeatherTypeInList];
-#ifdef FIX_BUGS
- }
- if (NewWeatherType == WEATHER_RAINY)
- CStats::mmRain += CGeneral::GetRandomNumber() & 7;
-#else
- if (NewWeatherType == WEATHER_RAINY)
- CStats::mmRain += CGeneral::GetRandomNumber() & 7;
+ if(!CReplay::IsPlayingBack()){
+ float fNewInterpolation = (CClock::GetMinutes() + CClock::GetSeconds()/60.0f)/60.0f;
+ if (fNewInterpolation < InterpolationValue) {
+ // new hour
+ OldWeatherType = NewWeatherType;
+ if (ForcedWeatherType >= 0)
+ NewWeatherType = ForcedWeatherType;
+ else {
+ WeatherTypeInList = (WeatherTypeInList + 1) % ARRAY_SIZE(WeatherTypesList);
+ NewWeatherType = CStats::NoMoreHurricanes ? WeatherTypesList[WeatherTypeInList] : WeatherTypesList_WithHurricanes[WeatherTypeInList];
+ }
}
-#endif
+ InterpolationValue = fNewInterpolation;
}
- InterpolationValue = fNewInterpolation;
+
+#ifndef FINAL
if (CPad::GetPad(1)->GetRightShockJustDown()) {
NewWeatherType = (NewWeatherType + 1) % WEATHER_TOTAL;
OldWeatherType = NewWeatherType;
}
+#endif
// Lightning
if (NewWeatherType != WEATHER_RAINY || OldWeatherType != WEATHER_RAINY) {
@@ -188,48 +208,25 @@ 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;
}
// Rain
-#ifndef VC_RAIN_NERF
float fNewRain;
- if (NewWeatherType == WEATHER_RAINY) {
- // 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 (InterpolationValue < 0.4f)
- // if rain has just started (<24 minutes), always 0.5
- fNewRain = 0.5f;
- else
- // if rain is ongoing for >24 minutes, values: 0.25, 0.5, 0.75, 1.0, switching every ~16.5s
- fNewRain = 0.25f + ((uint16)CTimer::GetTimeInMilliseconds() >> 14) * 0.25f;
- }
- }
- 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());
- }
-#else
- float fNewRain;
- if (NewWeatherType == WEATHER_RAINY) {
+ if (NewWeatherType == WEATHER_RAINY || NewWeatherType == WEATHER_HURRICANE) {
// if raining for >1 hour, values: 0, 0.33, switching every ~16.5s
fNewRain = (((uint16)CTimer::GetTimeInMilliseconds() >> 14) & 1) * 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;
@@ -242,14 +239,13 @@ void CWeather::Update(void)
else
fNewRain = 0.0f;
Rain = fNewRain;
-#endif
// 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
@@ -259,12 +255,100 @@ 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_CLOUDY && (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 * Windyness[NewWeatherType] + (1.0f - InterpolationValue) * Windyness[OldWeatherType];
+ WindClipped = Min(1.0f, Wind);
+
+ if (CClock::GetHours() > 20)
+ TrafficLightBrightness = 1.0f;
+ else if (CClock::GetHours() > 19)
+ TrafficLightBrightness = CClock::GetMinutes() / 60.0f;
+ else if (CClock::GetHours() > 6)
+ TrafficLightBrightness = 0.0f;
+ else if (CClock::GetHours() > 5)
+ TrafficLightBrightness = 1.0f - CClock::GetMinutes() / 60.0f;
+ else
+ TrafficLightBrightness = 1.0f;
+ TrafficLightBrightness = Max(WetRoads, TrafficLightBrightness);
+ TrafficLightBrightness = Max(Foggyness, 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()
+{
+ if(TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN ||
+ TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOP_DOWN_PED)
+ return;
+ CVector pos;
+ pos.x = SCREEN_WIDTH*0.5f;
+ if(TheCamera.GetLookingForwardFirstPerson())
+ pos.y = CGeneral::GetRandomNumberInRange(SCREEN_HEIGHT*0.25f, SCREEN_HEIGHT*0.9f);
+ else
+ pos.y = CGeneral::GetRandomNumberInRange(SCREEN_HEIGHT*0.4f, SCREEN_HEIGHT*0.9f);
+ pos.z = 100.0f;
+ CParticle::AddParticle(PARTICLE_HEATHAZE_IN_DIST, pos, CVector(0.0f, 0.0f, 0.0f));
+}
+
+void CWeather::AddBeastie()
+{
+ if(FindPlayerVehicle() || CTimer::GetFrameCounter()%10 || (CGeneral::GetRandomNumber()&5) == 0)
+ return;
+ CVector pos = TheCamera.GetPosition();
+ float dist = CGeneral::GetRandomNumberInRange(90.0f, 60.0f);
+ int angle = CGeneral::GetRandomNumber() % CParticle::SIN_COS_TABLE_SIZE;
+ float c = CParticle::m_CosTable[angle];
+ float s = CParticle::m_SinTable[angle];
+ pos.x += dist*(c - s);
+ pos.y += dist*(c + s);
+ pos.z += CGeneral::GetRandomNumberInRange(7.5f, 30.0f);
+ CParticle::AddParticle(PARTICLE_BEASTIE, pos, CVector(0.0f, 0.0f, 0.0f));
}
void CWeather::ForceWeather(int16 weather)
@@ -284,6 +368,62 @@ void CWeather::ReleaseWeather()
ForcedWeatherType = -1;
}
+void CWeather::AddSplashesDuringHurricane()
+{
+ RwRGBA colour = { 255, 255, 255, 32 };
+ CVector pos = TheCamera.pTargetEntity ? TheCamera.pTargetEntity->GetPosition() : TheCamera.GetPosition();
+ bool foundGround;
+ float groundZ = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z, &foundGround) + 0.1f;
+ if(!foundGround)
+ groundZ = pos.z + 0.5f;
+ for(int i = 0; i < 20; i++){
+ float dist = (CGeneral::GetRandomNumber()&0xFF)/255.0f +
+ CGeneral::GetRandomNumberInRange(-10.0f, 30.0f);
+ float angle;
+ uint8 rnd = CGeneral::GetRandomNumber();
+ if(rnd&1)
+ angle = (CGeneral::GetRandomNumber()&0x7F)/128.0f * TWOPI;
+ else
+ angle = TheCamera.Orientation + (rnd-128)/160.0f;
+ pos.x = TheCamera.GetPosition().x + dist*Sin(angle);
+ pos.y = TheCamera.GetPosition().y + dist*Cos(angle);
+ pos.z = groundZ;
+ if(foundGround)
+ CParticle::AddParticle(PARTICLE_GROUND_STEAM, pos, CVector(-0.002f, -0.002f, 0.015f), nil, 0.0f, colour);
+ }
+}
+
+static int startStreamAfterRain;
+
+void CWeather::AddStreamAfterRain()
+{
+ if(CClock::GetHours() > 6 && CClock::GetHours() < 18){
+ RwRGBA colour = { 255, 255, 255, 24 };
+ CVector pos = TheCamera.pTargetEntity ? TheCamera.pTargetEntity->GetPosition() : TheCamera.GetPosition();
+ bool foundGround;
+ float groundZ = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z, &foundGround) + 0.2f;
+ if(!foundGround)
+ groundZ = pos.z + 0.75f;
+ for(int i = 0; i < 20; i++){
+ float dist = (CGeneral::GetRandomNumber()&0xFF)/255.0f +
+ CGeneral::GetRandomNumberInRange(-10.0f, 30.0f);
+ float angle;
+ uint8 rnd = CGeneral::GetRandomNumber();
+ if(rnd&1)
+ angle = (CGeneral::GetRandomNumber()&0x7F)/128.0f * TWOPI;
+ else
+ angle = TheCamera.Orientation + (rnd-128)/160.0f;
+ pos.x = TheCamera.GetPosition().x + dist*Sin(angle);
+ pos.y = TheCamera.GetPosition().y + dist*Cos(angle);
+ pos.z = groundZ;
+ CParticle::AddParticle(PARTICLE_GROUND_STEAM, pos, CVector(0.0f, 0.0f, 0.015f), nil, 0.0f, colour);
+ }
+ }else{
+ startStreamAfterRain = 0;
+ StreamAfterRainTimer = 800;
+ }
+}
+
void CWeather::AddRain()
{
if (CCullZones::CamNoRain() || CCullZones::PlayerNoRain())
@@ -295,104 +435,77 @@ void CWeather::AddRain()
return;
}
}
+
+ if(Rain > 0.0){
+ startStreamAfterRain = 1;
+ StreamAfterRainTimer = 800;
+ }else if(startStreamAfterRain){
+ if(StreamAfterRainTimer > 0){
+ AddStreamAfterRain();
+ StreamAfterRainTimer--;
+ }else{
+ startStreamAfterRain = 0;
+ StreamAfterRainTimer = 800;
+ }
+ }
+
+ if (Wind > 1.1f)
+ AddSplashesDuringHurricane();
+
if (Rain <= 0.1f)
return;
static RwRGBA colour;
- float screen_width = SCREEN_WIDTH;
- float screen_height = SCREEN_HEIGHT;
- int cur_frame = (int)(3 * Rain) & 3;
- int num_drops = (int)(2 * Rain) + 2;
- static int STATIC_RAIN_ANGLE = -45;
- static int count = 1500;
- static int add_angle = 1;
- if (--count == 0) {
- count = 1;
- if (add_angle) {
- STATIC_RAIN_ANGLE += 12;
- if (STATIC_RAIN_ANGLE > 45) {
- count = 1500;
- add_angle = !add_angle;
- }
- }
- else {
- STATIC_RAIN_ANGLE -= 12;
- if (STATIC_RAIN_ANGLE < -45) {
- count = 1500;
- add_angle = !add_angle;
- }
- }
- }
- float rain_angle = DEGTORAD(STATIC_RAIN_ANGLE + ((STATIC_RAIN_ANGLE < 0) ? 360 : 0));
- float sin_angle = Sin(rain_angle);
- float cos_angle = Cos(rain_angle);
- float base_x = 0.0f * cos_angle - 1.0f * sin_angle;
- float base_y = 1.0f * cos_angle + 0.0f * sin_angle;
- CVector xpos(0.0f, 0.0f, 0.0f);
- for (int i = 0; i < 2 * num_drops; i++) {
- CVector dir;
- dir.x = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_x) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f);
- dir.y = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_y) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f);
- dir.z = 0;
- CParticle::AddParticle(PARTICLE_RAINDROP_2D, xpos, dir, nil, CGeneral::GetRandomNumberInRange(0.5f, 0.9f),
- colour, 0, rain_angle + CGeneral::GetRandomNumberInRange(-10, 10), cur_frame);
- xpos.x += screen_width / (2 * num_drops);
- xpos.x += CGeneral::GetRandomNumberInRange(-25.0f, 25.0f);
- }
- CVector ypos(0.0f, 0.0f, 0.0f);
- for (int i = 0; i < num_drops; i++) {
- CVector dir;
- dir.x = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_x) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f);
- dir.y = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_y) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f);
- dir.z = 0;
- CParticle::AddParticle(PARTICLE_RAINDROP_2D, ypos, dir, nil, CGeneral::GetRandomNumberInRange(0.5f, 0.9f),
- colour, 0, rain_angle + CGeneral::GetRandomNumberInRange(-10, 10), cur_frame);
- ypos.y += screen_width / num_drops;
- ypos.y += CGeneral::GetRandomNumberInRange(-25.0f, 25.0f);
- }
- CVector ypos2(0.0f, 0.0f, 0.0f);
- for (int i = 0; i < num_drops; i++) {
- CVector dir;
- dir.x = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_x) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f);
- dir.y = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_y) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f);
- dir.z = 0;
- CParticle::AddParticle(PARTICLE_RAINDROP_2D, ypos2, dir, nil, CGeneral::GetRandomNumberInRange(0.5f, 0.9f),
- colour, 0, rain_angle + CGeneral::GetRandomNumberInRange(-10, 10), cur_frame);
- ypos2.y += screen_width / num_drops;
- ypos2.y += CGeneral::GetRandomNumberInRange(-25.0f, 25.0f);
- }
- for (int i = 0; i < num_drops; i++) {
- CVector pos;
- pos.x = CGeneral::GetRandomNumberInRange(DROPLETS_LEFT_OFFSET, screen_width - DROPLETS_RIGHT_OFFSET);
- pos.y = CGeneral::GetRandomNumberInRange(DROPLETS_TOP_OFFSET, screen_height - DROPLETS_TOP_OFFSET);
+ int numDrops = 5.0f * Rain;
+ int numSplashes = 2.0f * Rain;
+ CVector pos, dir;
+ for(int i = 0; i < numDrops; i++){
+ pos.x = CGeneral::GetRandomNumberInRange(0, (int)SCREEN_WIDTH);
+ pos.y = CGeneral::GetRandomNumberInRange(0, (int)SCREEN_HEIGHT/5);
+ pos.z = 0.0f;
+ dir.x = 0.0f;
+ dir.y = CGeneral::GetRandomNumberInRange(30.0f, 40.0f);
+ dir.z = 0.0f;
+ CParticle::AddParticle(PARTICLE_RAINDROP_2D, pos, dir, nil, CGeneral::GetRandomNumberInRange(0.1f, 0.75f), 0, 0, (int)Rain&3, 0);
+
+ pos.x = CGeneral::GetRandomNumberInRange(0, (int)SCREEN_WIDTH);
+ pos.y = CGeneral::GetRandomNumberInRange((int)SCREEN_HEIGHT/5, (int)SCREEN_HEIGHT/2);
+ pos.z = 0.0f;
+ dir.x = 0.0f;
+ dir.y = CGeneral::GetRandomNumberInRange(30.0f, 40.0f);
+ dir.z = 0.0f;
+ CParticle::AddParticle(PARTICLE_RAINDROP_2D, pos, dir, nil, CGeneral::GetRandomNumberInRange(0.1f, 0.75f), 0, 0, (int)Rain&3, 0);
+
+ pos.x = CGeneral::GetRandomNumberInRange(0, (int)SCREEN_WIDTH);
+ pos.y = 0.0f;
+ pos.z = 0.0f;
+ dir.x = 0.0f;
+ dir.y = CGeneral::GetRandomNumberInRange(30.0f, 40.0f);
+ dir.z = 0.0f;
+ CParticle::AddParticle(PARTICLE_RAINDROP_2D, pos, dir, nil, CGeneral::GetRandomNumberInRange(0.1f, 0.75f), 0, 0, (int)Rain&3, 0);
+
+ float dist = CGeneral::GetRandomNumberInRange(0.0f, Max(10.0f*Rain, 40.0f)/2.0f);
+ float angle;
+ uint8 rnd = CGeneral::GetRandomNumber();
+ if(rnd&1)
+ angle = (CGeneral::GetRandomNumber()&0x7F)/128.0f * TWOPI;
+ else
+ angle = TheCamera.Orientation + (rnd-128)/160.0f;
+ pos.x = TheCamera.GetPosition().x + dist*Sin(angle);
+ pos.y = TheCamera.GetPosition().y + dist*Cos(angle);
pos.z = 0.0f;
- CParticle::AddParticle(PARTICLE_RAINDROP_2D, pos, CVector(0.0f, 0.0f, 0.0f), nil, CGeneral::GetRandomNumberInRange(0.5f, 0.9f),
- colour, CGeneral::GetRandomNumberInRange(-10, 10), 360 - rain_angle + CGeneral::GetRandomNumberInRange(-30, 30), cur_frame, 50);
- }
- int num_splash_attempts = (int)(3 * Rain) + 1;
- int num_splashes = (int)(3 * Rain) + 4;
- CVector splash_points[4];
- splash_points[0] = CVector(-RwCameraGetViewWindow(TheCamera.m_pRwCamera)->x, RwCameraGetViewWindow(TheCamera.m_pRwCamera)->y, 1.0f) *
- RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) / (RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) * *(CVector2D*)RwCameraGetViewWindow(TheCamera.m_pRwCamera)).Magnitude();
- splash_points[1] = CVector(RwCameraGetViewWindow(TheCamera.m_pRwCamera)->x, RwCameraGetViewWindow(TheCamera.m_pRwCamera)->y, 1.0f) *
- RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) / (RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) * *(CVector2D*)RwCameraGetViewWindow(TheCamera.m_pRwCamera)).Magnitude();
- splash_points[2] = 4.0f * CVector(-RwCameraGetViewWindow(TheCamera.m_pRwCamera)->x, RwCameraGetViewWindow(TheCamera.m_pRwCamera)->y, 1.0f) *
- RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) / (RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) * *(CVector2D*)RwCameraGetViewWindow(TheCamera.m_pRwCamera)).Magnitude();
- splash_points[3] = 4.0f * CVector(RwCameraGetViewWindow(TheCamera.m_pRwCamera)->x, RwCameraGetViewWindow(TheCamera.m_pRwCamera)->y, 1.0f) *
- RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) / (RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) * *(CVector2D*)RwCameraGetViewWindow(TheCamera.m_pRwCamera)).Magnitude();
- RwV3dTransformPoints(splash_points, splash_points, 4, RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)));
- CVector fp = (splash_points[0] + splash_points[1] + splash_points[2] + splash_points[3]) / 4;
- for (int i = 0; i < num_splash_attempts; i++) {
CColPoint point;
- CEntity* entity;
- CVector np = fp + CVector(CGeneral::GetRandomNumberInRange(-SPLASH_CHECK_RADIUS, SPLASH_CHECK_RADIUS), CGeneral::GetRandomNumberInRange(-SPLASH_CHECK_RADIUS, SPLASH_CHECK_RADIUS), 0.0f);
- if (CWorld::ProcessVerticalLine(np + CVector(0.0f, 0.0f, 40.0f), -40.0f, point, entity, true, false, false, false, true, false, nil)) {
- for (int j = 0; j < num_splashes; j++)
- CParticle::AddParticle((CGeneral::GetRandomTrueFalse() ? PARTICLE_RAIN_SPLASH : PARTICLE_RAIN_SPLASHUP),
- CVector(
- np.x + CGeneral::GetRandomNumberInRange(-SPLASH_OFFSET_RADIUS, SPLASH_OFFSET_RADIUS),
- np.y + CGeneral::GetRandomNumberInRange(-SPLASH_OFFSET_RADIUS, SPLASH_OFFSET_RADIUS),
- point.point.z + 0.1f),
- CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, colour);
+ CEntity *ent;
+ if(CWorld::ProcessVerticalLine(pos+CVector(0.0f, 0.0f, 40.0f), -40.0f, point, ent, true, false, false, false, true, false, nil)){
+ pos.z = point.point.z;
+ for(int j = 0; j < numSplashes+15; j++){
+ CVector pos2 = pos;
+ pos2.x += CGeneral::GetRandomNumberInRange(-15.0f, 15.0f);
+ pos2.y += CGeneral::GetRandomNumberInRange(-15.0f, 15.0f);
+ if(CGeneral::GetRandomNumber() & 1)
+ CParticle::AddParticle(PARTICLE_RAIN_SPLASH, pos2, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, colour);
+ else
+ CParticle::AddParticle(PARTICLE_RAIN_SPLASHUP, pos2, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, colour);
+ }
}
}
}
@@ -440,9 +553,9 @@ void RenderOneRainStreak(CVector pos, CVector unused, int intensity, bool scale,
u *= distance_coefficient;
v *= distance_coefficient;
if (!CTimer::GetIsPaused()) {
- RandomTex = ((CGeneral::GetRandomNumber() & 255) - 128) * 0.01f;
- RandomTexX = (CGeneral::GetRandomNumber() & 127) * 0.01f;
- RandomTexY = (CGeneral::GetRandomNumber() & 127) * 0.01f;
+ RandomTex = 0.0f;
+ RandomTexX = 0.0f;
+ RandomTexY = 0.0f;
}
RwIm3DVertexSetU(&TempBufferRenderVertices[TempBufferVerticesStored + 0], 0.5f * u - RandomTex + RandomTexX);
RwIm3DVertexSetV(&TempBufferRenderVertices[TempBufferVerticesStored + 0], -v * 0.5f + RandomTexY);
@@ -465,6 +578,8 @@ void CWeather::RenderRainStreaks(void)
int base_intensity = (64.0f - CTimeCycle::GetFogReduction()) / 64.0f * int(255 * Rain);
if (base_intensity == 0)
return;
+ if (TheCamera.m_CameraAverageSpeed > 1.75f)
+ return;
TempBufferIndicesStored = 0;
TempBufferVerticesStored = 0;
for (int i = 0; i < NUM_RAIN_STREAKS; i++) {
@@ -475,11 +590,11 @@ void CWeather::RenderRainStreaks(void)
else{
int intensity;
if (secondsElapsed < STREAK_INTEROLATION_TIME)
- intensity = base_intensity * 0.5f * secondsElapsed / STREAK_INTEROLATION_TIME;
+ intensity = base_intensity * 0.25f * secondsElapsed / STREAK_INTEROLATION_TIME;
else if (secondsElapsed > (STREAK_LIFETIME - STREAK_INTEROLATION_TIME))
- intensity = (STREAK_LIFETIME - secondsElapsed) * 0.5f * base_intensity / STREAK_INTEROLATION_TIME;
+ intensity = (STREAK_LIFETIME - secondsElapsed) * 0.25f * base_intensity / STREAK_INTEROLATION_TIME;
else
- intensity = base_intensity * 0.5f;
+ intensity = base_intensity * 0.25f;
CVector dir = Streaks[i].direction;
dir.Normalise();
CVector pos = Streaks[i].position + secondsElapsed * Streaks[i].direction;
@@ -493,7 +608,7 @@ void CWeather::RenderRainStreaks(void)
}
else if ((CGeneral::GetRandomNumber() & 0xF00) == 0){
// 1/16 probability
- Streaks[i].direction = CVector(4.0f, 4.0f, -4.0f);
+ Streaks[i].direction = CVector(0.0f, 0.0f, -12.0f);
Streaks[i].position = 6.0f * TheCamera.GetForward() + TheCamera.GetPosition() + CVector(-1.8f * Streaks[i].direction.x, -1.8f * Streaks[i].direction.y, 8.0f);
if (!CCutsceneMgr::IsRunning()) {
Streaks[i].position.x += 2.0f * FindPlayerSpeed().x * 60.0f;
@@ -501,8 +616,8 @@ void CWeather::RenderRainStreaks(void)
}
else
Streaks[i].position += (TheCamera.GetPosition() - TheCamera.m_RealPreviousCameraPosition) * 20.0f;
- Streaks[i].position.x += ((CGeneral::GetRandomNumber() & 255) - 128) * 0.08f;
- Streaks[i].position.y += ((CGeneral::GetRandomNumber() & 255) - 128) * 0.08f;
+ Streaks[i].position.x += ((CGeneral::GetRandomNumber() & 255) - 128) * 0.04f;
+ Streaks[i].position.y += ((CGeneral::GetRandomNumber() & 255) - 128) * 0.04f;
Streaks[i].timer = CTimer::GetTimeInMilliseconds();
}
}
@@ -514,7 +629,7 @@ void CWeather::RenderRainStreaks(void)
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
- RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpRainDropTex[3]));
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpRainDropTex));
if (RwIm3DTransform(TempBufferRenderVertices, TempBufferVerticesStored, nil, 1))
{
RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TempBufferRenderIndexList, TempBufferIndicesStored);
@@ -531,22 +646,17 @@ void CWeather::RenderRainStreaks(void)
TempBufferIndicesStored = 0;
}
-void CWeather::StoreWeatherState()
+#ifdef SECUROM
+void CWeather::ForceHurricaneWeather()
{
- Stored_StateStored = true;
- Stored_InterpolationValue = InterpolationValue;
- Stored_Rain = Rain;
- Stored_NewWeatherType = NewWeatherType;
- Stored_OldWeatherType = OldWeatherType;
-}
+ for (int i = 0; i < ARRAY_SIZE(WeatherTypesList_WithHurricanes); i++)
+ {
+ WeatherTypesList[i] = WEATHER_HURRICANE;
+ WeatherTypesList_WithHurricanes[i] = WEATHER_HURRICANE;
+ }
-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;
+ CWeather::OldWeatherType = WEATHER_HURRICANE;
+ CWeather::NewWeatherType = WEATHER_HURRICANE;
+ CWeather::ForcedWeatherType = WEATHER_HURRICANE;
}
+#endif
diff --git a/src/renderer/Weather.h b/src/renderer/Weather.h
index 9c670317..bda57d55 100644
--- a/src/renderer/Weather.h
+++ b/src/renderer/Weather.h
@@ -1,21 +1,19 @@
enum {
- WEATHER_SUNNY,
+ WEATHER_RANDOM = -1,
+ WEATHER_SUNNY = 0,
WEATHER_CLOUDY,
WEATHER_RAINY,
- WEATHER_FOGGY
+ WEATHER_FOGGY,
+ WEATHER_EXTRA_SUNNY,
+ WEATHER_HURRICANE,
+ WEATHER_TOTAL,
+
+ WEATHER_EXTRACOLOURS = 6
};
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;
@@ -29,7 +27,9 @@ public:
static uint32 LightningFlashLastChange;
static uint32 WhenToPlayLightningSound;
static uint32 LightningDuration;
+ static int32 StreamAfterRainTimer;
+ static float ExtraSunnyness;
static float Foggyness;
static float CloudCoverage;
static float Wind;
@@ -37,13 +37,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);
@@ -52,9 +50,13 @@ public:
static void ReleaseWeather();
static void ForceWeather(int16);
static void ForceWeatherNow(int16);
- static void StoreWeatherState();
- static void RestoreWeatherState();
+ static void AddSplashesDuringHurricane();
+ static void AddStreamAfterRain();
static void AddRain();
+ static void AddHeatHaze();
+ static void AddBeastie();
+
+ static void ForceHurricaneWeather();
};
enum {
@@ -68,4 +70,4 @@ struct tRainStreak
uint32 timer;
};
-extern RwTexture* gpRainDropTex[4]; \ No newline at end of file
+extern RwTexture* gpRainDropTex; \ No newline at end of file
diff --git a/src/renderer/WindModifiers.cpp b/src/renderer/WindModifiers.cpp
new file mode 100644
index 00000000..3bd6ac9c
--- /dev/null
+++ b/src/renderer/WindModifiers.cpp
@@ -0,0 +1,52 @@
+#include "common.h"
+#include "WindModifiers.h"
+#include "Camera.h"
+#include "General.h"
+
+#define MAX_HEIGHT_DIST 40.0f
+#define MIN_FADE_DIST 20.0f
+#define MAX_FADE_DIST 50.0f
+
+CWindModifiers Array[16];
+int32 CWindModifiers::Number;
+
+void
+CWindModifiers::RegisterOne(CVector pos, int32 type = 1)
+{
+ if (CWindModifiers::Number < 16 && (pos - TheCamera.GetPosition()).Magnitude() < 100.0f) {
+ Array[Number].m_pos = pos;
+ Array[Number].m_type = type;
+ Number++;
+ }
+}
+
+bool
+CWindModifiers::FindWindModifier(CVector pos, float *x, float *y)
+{
+ bool bWasWindModifierFound = false;
+ CVector2D dir;
+ for (int i = 0; i < Number; i++) {
+ if (Array[i].m_type == 1) {
+ float zDist = Abs(15.0f + pos.z - Array[i].m_pos.z);
+
+ if (zDist < MAX_HEIGHT_DIST) {
+ float dist = (pos - Array[i].m_pos).Magnitude();
+ if (dist < MAX_FADE_DIST) {
+ float distFade = dist < MIN_FADE_DIST ? 1.0f : 1.0f - (dist - MIN_FADE_DIST) / (MAX_FADE_DIST - MIN_FADE_DIST);
+ float heightFade = 1.0f - zDist / MAX_HEIGHT_DIST;
+ float fade = distFade * heightFade * 0.5f;
+ dir = (pos - Array[i].m_pos) * fade / dist;
+ bWasWindModifierFound = true;
+ }
+ }
+ }
+ }
+
+ if (bWasWindModifierFound) {
+ float directionMult = ((CGeneral::GetRandomNumber() & 0x1F) - 16) * 0.0035f + 1.0f;
+ *x += dir.x * directionMult;
+ *y += dir.y * directionMult;
+ }
+
+ return bWasWindModifierFound;
+}
diff --git a/src/renderer/WindModifiers.h b/src/renderer/WindModifiers.h
new file mode 100644
index 00000000..7c2e57bd
--- /dev/null
+++ b/src/renderer/WindModifiers.h
@@ -0,0 +1,11 @@
+#pragma once
+
+class CWindModifiers
+{
+ CVector m_pos;
+ int32 m_type;
+public:
+ static int32 Number;
+ static void RegisterOne(CVector pos, int32 windSourceType);
+ static bool FindWindModifier(CVector pos, float *x, float *y);
+};
diff --git a/src/rw/ClumpRead.cpp b/src/rw/ClumpRead.cpp
index 5f50f52d..9c027dc5 100644
--- a/src/rw/ClumpRead.cpp
+++ b/src/rw/ClumpRead.cpp
@@ -1,6 +1,5 @@
#include "common.h"
-
struct rpGeometryList
{
RpGeometry **geometries;
diff --git a/src/rw/Lights.cpp b/src/rw/Lights.cpp
index b3cef6d4..772e1961 100644
--- a/src/rw/Lights.cpp
+++ b/src/rw/Lights.cpp
@@ -9,6 +9,7 @@
#include "Weather.h"
#include "ZoneCull.h"
#include "Frontend.h"
+#include "MBlur.h"
RpLight *pAmbient;
RpLight *pDirect;
@@ -23,6 +24,13 @@ RwRGBAReal DirectionalLightColourForFrame;
RwRGBAReal AmbientLightColour;
RwRGBAReal DirectionalLightColour;
+#ifdef EXTENDED_COLOURFILTER
+#include "postfx.h"
+#define USEBLURCOLORS CPostFX::UseBlurColours()
+#else
+#define USEBLURCOLORS CMBlur::BlurOn
+#endif
+
void
SetLightsWithTimeOfDayColour(RpWorld *)
{
@@ -30,17 +38,35 @@ SetLightsWithTimeOfDayColour(RpWorld *)
RwMatrix mat;
if(pAmbient){
- AmbientLightColourForFrame.red = CTimeCycle::GetAmbientRed() * CCoronas::LightsMult;
- AmbientLightColourForFrame.green = CTimeCycle::GetAmbientGreen() * CCoronas::LightsMult;
- AmbientLightColourForFrame.blue = CTimeCycle::GetAmbientBlue() * CCoronas::LightsMult;
+ if(USEBLURCOLORS){
+ AmbientLightColourForFrame.red = CTimeCycle::GetAmbientRed_Bl() * CCoronas::LightsMult;
+ AmbientLightColourForFrame.green = CTimeCycle::GetAmbientGreen_Bl() * CCoronas::LightsMult;
+ AmbientLightColourForFrame.blue = CTimeCycle::GetAmbientBlue_Bl() * CCoronas::LightsMult;
+ }else{
+ AmbientLightColourForFrame.red = CTimeCycle::GetAmbientRed() * CCoronas::LightsMult;
+ AmbientLightColourForFrame.green = CTimeCycle::GetAmbientGreen() * CCoronas::LightsMult;
+ AmbientLightColourForFrame.blue = CTimeCycle::GetAmbientBlue() * CCoronas::LightsMult;
+ }
+
+ if(USEBLURCOLORS){
+ AmbientLightColourForFrame_PedsCarsAndObjects.red = CTimeCycle::GetAmbientRed_Obj_Bl() * CCoronas::LightsMult;
+ AmbientLightColourForFrame_PedsCarsAndObjects.green = CTimeCycle::GetAmbientGreen_Obj_Bl() * CCoronas::LightsMult;
+ AmbientLightColourForFrame_PedsCarsAndObjects.blue = CTimeCycle::GetAmbientBlue_Obj_Bl() * CCoronas::LightsMult;
+ }else{
+ AmbientLightColourForFrame_PedsCarsAndObjects.red = CTimeCycle::GetAmbientRed_Obj() * CCoronas::LightsMult;
+ AmbientLightColourForFrame_PedsCarsAndObjects.green = CTimeCycle::GetAmbientGreen_Obj() * CCoronas::LightsMult;
+ AmbientLightColourForFrame_PedsCarsAndObjects.blue = CTimeCycle::GetAmbientBlue_Obj() * CCoronas::LightsMult;
+ }
+
if(CWeather::LightningFlash && !CCullZones::CamNoRain()){
AmbientLightColourForFrame.red = 1.0f;
AmbientLightColourForFrame.green = 1.0f;
AmbientLightColourForFrame.blue = 1.0f;
+
+ AmbientLightColourForFrame_PedsCarsAndObjects.red = 1.0f;
+ AmbientLightColourForFrame_PedsCarsAndObjects.green = 1.0f;
+ AmbientLightColourForFrame_PedsCarsAndObjects.blue = 1.0f;
}
- AmbientLightColourForFrame_PedsCarsAndObjects.red = Min(1.0f, AmbientLightColourForFrame.red*1.3f);
- AmbientLightColourForFrame_PedsCarsAndObjects.green = Min(1.0f, AmbientLightColourForFrame.green*1.3f);
- AmbientLightColourForFrame_PedsCarsAndObjects.blue = Min(1.0f, AmbientLightColourForFrame.blue*1.3f);
RpLightSetColor(pAmbient, &AmbientLightColourForFrame);
}
@@ -67,9 +93,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);
@@ -323,6 +349,14 @@ ActivateDirectional(void)
RpLightSetFlags(pDirect, rpLIGHTLIGHTATOMICS);
}
+RwRGBAReal FullLight = { 1.0f, 1.0f, 1.0f, 1.0f };
+
+void
+SetFullAmbient(void)
+{
+ RpLightSetColor(pAmbient, &FullLight);
+}
+
void
SetAmbientColours(void)
{
diff --git a/src/rw/Lights.h b/src/rw/Lights.h
index 5057f1d0..ad355adb 100644
--- a/src/rw/Lights.h
+++ b/src/rw/Lights.h
@@ -24,3 +24,4 @@ void SetAmbientColours(void);
void SetAmbientColoursForPedsCarsAndObjects(void);
void SetAmbientColoursToIndicateRoadGroup(int i);
void SetAmbientColours(RwRGBAReal *color);
+void SetFullAmbient(void);
diff --git a/src/rw/MemoryHeap.cpp b/src/rw/MemoryHeap.cpp
index 469262d3..285a7c70 100644
--- a/src/rw/MemoryHeap.cpp
+++ b/src/rw/MemoryHeap.cpp
@@ -7,6 +7,8 @@
#include "FileLoader.h"
#include "MemoryHeap.h"
+// TODO(MIAMI)
+
#ifdef USE_CUSTOM_ALLOCATOR
//#define MEMORYHEAP_ASSERT(cond) { if (!(cond)) { printf("ASSERT File:%s Line:%d\n", __FILE__, __LINE__); exit(1); } }
@@ -339,7 +341,7 @@ CMemoryHeap::TidyHeap(void)
}
}
-//
+// MIAMI: this is empty
void
CMemoryHeap::RegisterMemPointer(void *ptr)
{
diff --git a/src/rw/MemoryHeap.h b/src/rw/MemoryHeap.h
index cd8cf22c..1a9a51f8 100644
--- a/src/rw/MemoryHeap.h
+++ b/src/rw/MemoryHeap.h
@@ -23,17 +23,19 @@ enum {
MEMID_POOLS = 4, // "Pools"
MEMID_DEF_MODELS = 5, // "Default Models"
MEMID_STREAM = 6, // "Streaming"
- MEMID_STREAM_MODELS = 7, // "Streamed Models" (instance)
- MEMID_STREAM_TEXUTRES = 8, // "Streamed Textures"
- MEMID_TEXTURES = 9, // "Textures"
- MEMID_COLLISION = 10, // "Collision"
- MEMID_RENDERLIST = 11, // ?
- MEMID_GAME_PROCESS = 12, // "Game Process"
- MEMID_SCRIPT = 13, // "Script"
- MEMID_CARS = 14, // "Cars"
- MEMID_RENDER = 15, // "Render"
- MEMID_FRONTEND = 17, // ?
-
+ MEMID_STREAM_MODELS = 7, // "Streamed Models"
+ MEMID_STREAM_LODS = 8, // "Streamed LODs"
+ MEMID_STREAM_TEXUTRES = 9, // "Streamed Textures"
+ MEMID_STREAM_COLLISION = 10, // "Streamed Collision"
+ MEMID_STREAM_ANIMATION = 11, // "Streamed Animation"
+ MEMID_TEXTURES = 12, // "Textures"
+ MEMID_COLLISION = 13, // "Collision"
+ MEMID_PRE_ALLOC = 14, // "PreAlloc"
+ MEMID_GAME_PROCESS = 15, // "Game Process"
+ MEMID_SCRIPT = 16, // "Script"
+ MEMID_CARS = 17, // "Cars"
+ MEMID_RENDER = 18, // "Render"
+ MEMID_PED_ATTR = 19, // "Ped Attr"
NUM_MEMIDS,
NUM_FIXED_MEMBLOCKS = 6
diff --git a/src/rw/RwHelper.cpp b/src/rw/RwHelper.cpp
index 35593722..25cd2eef 100644
--- a/src/rw/RwHelper.cpp
+++ b/src/rw/RwHelper.cpp
@@ -2,7 +2,6 @@
#include "common.h"
#include <rpskin.h>
-#include "RwHelper.h"
#include "Timecycle.h"
#include "skeleton.h"
#include "Debug.h"
@@ -77,7 +76,7 @@ DefinedState(void)
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
- RwRenderStateSet(rwRENDERSTATEALPHAPRIMITIVEBUFFER, (void*)FALSE);
+ //RwRenderStateSet(rwRENDERSTATEALPHAPRIMITIVEBUFFER, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEBORDERCOLOR, (void*)RWRGBALONG(0, 0, 0, 255));
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEFOGCOLOR,
@@ -87,22 +86,13 @@ DefinedState(void)
#ifdef LIBRW
rw::SetRenderState(rw::ALPHATESTFUNC, rw::ALPHAGREATEREQUAL);
+ rw::SetRenderState(rw::ALPHATESTREF, 3);
rw::SetRenderState(rw::GSALPHATEST, gPS2alphaTest);
#else
// D3D stuff
RwD3D8SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER);
-#endif
- SetAlphaRef(2);
-}
-
-void
-SetAlphaRef(int ref)
-{
-#ifdef LIBRW
- rw::SetRenderState(rw::ALPHATESTREF, ref+1);
-#else
- RwD3D8SetRenderState(D3DRS_ALPHAREF, ref);
+ RwD3D8SetRenderState(D3DRS_ALPHAREF, 2);
#endif
}
@@ -213,24 +203,11 @@ GetFirstTexture(RwTexDictionary *txd)
return tex;
}
-#ifdef PED_SKIN
-static RpAtomic*
-isSkinnedCb(RpAtomic *atomic, void *data)
-{
- RpAtomic **pAtomic = (RpAtomic**)data;
- if(*pAtomic)
- return nil; // already found one
- if(RpSkinGeometryGetSkin(RpAtomicGetGeometry(atomic)))
- *pAtomic = atomic; // we could just return nil here directly...
- return atomic;
-}
-
-RpAtomic*
+bool
IsClumpSkinned(RpClump *clump)
{
- RpAtomic *atomic = nil;
- RpClumpForAllAtomics(clump, isSkinnedCb, &atomic);
- return atomic;
+ RpAtomic *atomic = GetFirstAtomic(clump);
+ return atomic ? RpSkinGeometryGetSkin(RpAtomicGetGeometry(atomic)) : nil;
}
static RpAtomic*
@@ -268,17 +245,6 @@ GetAnimHierarchyFromClump(RpClump *clump)
return hier;
}
-RwFrame*
-GetHierarchyFromChildNodesCB(RwFrame *frame, void *data)
-{
- RpHAnimHierarchy **pHier = (RpHAnimHierarchy**)data;
- RpHAnimHierarchy *hier = RpHAnimFrameGetHierarchy(frame);
- if(hier == nil)
- RwFrameForAllChildren(frame, GetHierarchyFromChildNodesCB, &hier);
- *pHier = hier;
- return nil;
-}
-
void
SkinGetBonePositionsToTable(RpClump *clump, RwV3d *boneTable)
{
@@ -294,8 +260,7 @@ SkinGetBonePositionsToTable(RpClump *clump, RwV3d *boneTable)
if(boneTable == nil)
return;
-// atomic = GetFirstAtomic(clump); // mobile, also VC
- atomic = IsClumpSkinned(clump); // xbox, seems safer
+ atomic = GetFirstAtomic(clump); // mobile, also VC
assert(atomic);
skin = RpSkinGeometryGetSkin(RpAtomicGetGeometry(atomic));
assert(skin);
@@ -382,7 +347,125 @@ RenderSkeleton(RpHAnimHierarchy *hier)
par = stack[--sp];
}
}
-#endif
+
+
+RwBool Im2DRenderQuad(RwReal x1, RwReal y1, RwReal x2, RwReal y2, RwReal z, RwReal recipCamZ, RwReal uvOffset)
+{
+ RwIm2DVertex vx[4];
+
+ /*
+ * Render an opaque white 2D quad at the given coordinates and
+ * spanning a whole texture.
+ */
+
+ RwIm2DVertexSetScreenX(&vx[0], x1);
+ RwIm2DVertexSetScreenY(&vx[0], y1);
+ RwIm2DVertexSetScreenZ(&vx[0], z);
+ RwIm2DVertexSetIntRGBA(&vx[0], 255, 255, 255, 255);
+ RwIm2DVertexSetRecipCameraZ(&vx[0], recipCamZ);
+ RwIm2DVertexSetU(&vx[0], uvOffset, recipCamZ);
+ RwIm2DVertexSetV(&vx[0], uvOffset, recipCamZ);
+
+ RwIm2DVertexSetScreenX(&vx[1], x1);
+ RwIm2DVertexSetScreenY(&vx[1], y2);
+ RwIm2DVertexSetScreenZ(&vx[1], z);
+ RwIm2DVertexSetIntRGBA(&vx[1], 255, 255, 255, 255);
+ RwIm2DVertexSetRecipCameraZ(&vx[1], recipCamZ);
+ RwIm2DVertexSetU(&vx[1], uvOffset, recipCamZ);
+ RwIm2DVertexSetV(&vx[1], 1.0f + uvOffset, recipCamZ);
+
+ RwIm2DVertexSetScreenX(&vx[2], x2);
+ RwIm2DVertexSetScreenY(&vx[2], y1);
+ RwIm2DVertexSetScreenZ(&vx[2], z);
+ RwIm2DVertexSetIntRGBA(&vx[2], 255, 255, 255, 255);
+ RwIm2DVertexSetRecipCameraZ(&vx[2], recipCamZ);
+ RwIm2DVertexSetU(&vx[2], 1.0f + uvOffset, recipCamZ);
+ RwIm2DVertexSetV(&vx[2], uvOffset, recipCamZ);
+
+ RwIm2DVertexSetScreenX(&vx[3], x2);
+ RwIm2DVertexSetScreenY(&vx[3], y2);
+ RwIm2DVertexSetScreenZ(&vx[3], z);
+ RwIm2DVertexSetIntRGBA(&vx[3], 255, 255, 255, 255);
+ RwIm2DVertexSetRecipCameraZ(&vx[3], recipCamZ);
+ RwIm2DVertexSetU(&vx[3], 1.0f + uvOffset, recipCamZ);
+ RwIm2DVertexSetV(&vx[3], 1.0f + uvOffset, recipCamZ);
+
+ RwIm2DRenderPrimitive(rwPRIMTYPETRISTRIP, vx, 4);
+
+ return TRUE;
+}
+
+bool b_cbsUseLTM = true;
+
+RpAtomic *cbsCalcMeanBSphereRadiusCB(RpAtomic *atomic, void *data)
+{
+ RwV3d atomicPos;
+
+ if ( b_cbsUseLTM )
+ RwV3dTransformPoints(&atomicPos, &RpAtomicGetBoundingSphere(atomic)->center, 1, RwFrameGetLTM(RpClumpGetFrame(atomic->clump)));
+ else
+ RwV3dTransformPoints(&atomicPos, &RpAtomicGetBoundingSphere(atomic)->center, 1, RwFrameGetMatrix(RpClumpGetFrame(atomic->clump)));
+
+ RwV3d temp;
+ RwV3dSub(&temp, &atomicPos, &((RwSphere *)data)->center);
+ RwReal radius = RwV3dLength(&temp) + RpAtomicGetBoundingSphere(atomic)->radius;
+
+ if ( ((RwSphere *)data)->radius < radius )
+ ((RwSphere *)data)->radius = radius;
+
+ return atomic;
+}
+
+RpAtomic *cbsCalcMeanBSphereCenterCB(RpAtomic *atomic, void *data)
+{
+ RwV3d atomicPos;
+
+ if ( b_cbsUseLTM )
+ RwV3dTransformPoints(&atomicPos, &RpAtomicGetBoundingSphere(atomic)->center, 1, RwFrameGetLTM(RpClumpGetFrame(atomic->clump)));
+ else
+ RwV3dTransformPoints(&atomicPos, &RpAtomicGetBoundingSphere(atomic)->center, 1, RwFrameGetMatrix(RpClumpGetFrame(atomic->clump)));
+
+ RwV3dAdd(&((RwSphere *)data)->center, &((RwSphere *)data)->center, &atomicPos);
+
+ return atomic;
+}
+
+RpClump *RpClumpGetBoundingSphere(RpClump *clump, RwSphere *sphere, bool useLTM)
+{
+ RwMatrix matrix;
+ RwSphere result = { 0.0f, 0.0f, 0.0f, 0.0f };
+
+ b_cbsUseLTM = useLTM;
+
+ if ( clump == nil || sphere == nil )
+ return nil;
+
+ sphere->radius = 0.0f;
+ sphere->center.x = 0.0f;
+ sphere->center.y = 0.0f;
+ sphere->center.z = 0.0f;
+
+ RwInt32 numAtomics = RpClumpGetNumAtomics(clump);
+ if ( numAtomics < 1.0f )
+ return nil;
+
+ RpClumpForAllAtomics(clump, cbsCalcMeanBSphereCenterCB, &result);
+
+ RwV3dScale(&result.center, &result.center, 1.0f/numAtomics);
+
+ RpClumpForAllAtomics(clump, cbsCalcMeanBSphereRadiusCB, &result);
+
+ if ( b_cbsUseLTM )
+ RwMatrixInvert(&matrix, RwFrameGetLTM(RpClumpGetFrame(clump)));
+ else
+ RwMatrixInvert(&matrix, RwFrameGetMatrix(RpClumpGetFrame(clump)));
+
+ RwV3dTransformPoints(&result.center, &result.center, 1, &matrix);
+
+ *sphere = result;
+
+ return clump;
+}
void
CameraSize(RwCamera * camera, RwRect * rect,
@@ -495,7 +578,7 @@ CameraSize(RwCamera * camera, RwRect * rect,
#else
raster = RwCameraGetRaster(camera);
zRaster = RwCameraGetZRaster(camera);
-
+
raster->width = zRaster->width = rect->w;
raster->height = zRaster->height = rect->h;
#endif
@@ -636,16 +719,6 @@ findPlatform(rw::Atomic *a)
return 0;
}
-// in CVehicleModelInfo in VC
-static RpMaterial*
-GetMatFXEffectMaterialCB(RpMaterial *material, void *data)
-{
- if(RpMatFXMaterialGetEffects(material) == rpMATFXEFFECTNULL)
- return material;
- *(int*)data = RpMatFXMaterialGetEffects(material);
- return nil;
-}
-
// Game doesn't read atomic extensions so we never get any other than the default pipe,
// but we need it for uninstancing
void
@@ -655,7 +728,7 @@ attachPipe(rw::Atomic *atomic)
atomic->pipeline = rw::skinGlobals.pipelines[rw::platform];
else{
int fx = rpMATFXEFFECTNULL;
- RpGeometryForAllMaterials(RpAtomicGetGeometry(atomic), GetMatFXEffectMaterialCB, &fx);
+ RpGeometryForAllMaterials(RpAtomicGetGeometry(atomic), CVehicleModelInfo::GetMatFXEffectMaterialCB, &fx);
if(fx != rpMATFXEFFECTNULL)
RpMatFXAtomicEnableEffects(atomic);
}
diff --git a/src/rw/RwHelper.h b/src/rw/RwHelper.h
index 0e04aece..a3a1928c 100644
--- a/src/rw/RwHelper.h
+++ b/src/rw/RwHelper.h
@@ -2,6 +2,7 @@
extern bool bDebugRenderGroups;
extern bool gPS2alphaTest;
+extern bool gBackfaceCulling;
void OpenCharsetSafe();
void CreateDebugFont();
@@ -9,23 +10,22 @@ void DestroyDebugFont();
void ObrsPrintfString(const char *str, short x, short y);
void FlushObrsPrintfs();
void DefinedState(void);
-void SetAlphaRef(int ref);
void SetCullMode(uint32 mode);
RwFrame *GetFirstChild(RwFrame *frame);
RwObject *GetFirstObject(RwFrame *frame);
RpAtomic *GetFirstAtomic(RpClump *clump);
RwTexture *GetFirstTexture(RwTexDictionary *txd);
-#ifdef PED_SKIN
-RpAtomic *IsClumpSkinned(RpClump *clump);
+bool IsClumpSkinned(RpClump *clump);
RpHAnimHierarchy *GetAnimHierarchyFromSkinClump(RpClump *clump); // get from atomic
RpHAnimHierarchy *GetAnimHierarchyFromClump(RpClump *clump); // get from frame
-RwFrame *GetHierarchyFromChildNodesCB(RwFrame *frame, void *data);
void SkinGetBonePositionsToTable(RpClump *clump, RwV3d *boneTable);
RpHAnimAnimation *HAnimAnimationCreateForHierarchy(RpHAnimHierarchy *hier);
RpAtomic *AtomicRemoveAnimFromSkinCB(RpAtomic *atomic, void *data);
void RenderSkeleton(RpHAnimHierarchy *hier);
-#endif
+
+RwBool Im2DRenderQuad(RwReal x1, RwReal y1, RwReal x2, RwReal y2, RwReal z, RwReal recipCamZ, RwReal uvOffset);
+RpClump *RpClumpGetBoundingSphere(RpClump *clump, RwSphere *sphere, bool useLTM);
RwTexDictionary *RwTexDictionaryGtaStreamRead(RwStream *stream);
RwTexDictionary *RwTexDictionaryGtaStreamRead1(RwStream *stream);
@@ -33,6 +33,7 @@ RwTexDictionary *RwTexDictionaryGtaStreamRead2(RwStream *stream, RwTexDictionary
void ReadVideoCardCapsFile(uint32&, uint32&, uint32&, uint32&);
bool CheckVideoCardCaps(void);
void WriteVideoCardCapsFile(void);
+bool CanVideoCardDoDXT(void);
void ConvertingTexturesScreen(uint32, uint32, const char*);
void DealWithTxdWriteError(uint32, uint32, const char*);
bool CreateTxdImageForVideoCard();
diff --git a/src/rw/TexRead.cpp b/src/rw/TexRead.cpp
index 98e7d180..1f96180b 100644
--- a/src/rw/TexRead.cpp
+++ b/src/rw/TexRead.cpp
@@ -2,6 +2,9 @@
#pragma warning( disable : 4005)
#pragma warning( pop )
#define FORCE_PC_SCALING
+#ifndef LIBRW
+#define WITHD3D
+#endif
#include "common.h"
#ifdef ANISOTROPIC_FILTERING
#include "rpanisot.h"
@@ -233,8 +236,10 @@ WriteVideoCardCapsFile(void)
}
}
+
#else
extern "C" RwInt32 _rwD3D8FindCorrectRasterFormat(RwRasterType type, RwInt32 flags);
+extern "C" RwBool _rwD3D8CheckValidTextureFormat(RwInt32 format);
void
ReadVideoCardCapsFile(uint32 &cap32, uint32 &cap24, uint32 &cap16, uint32 &cap8)
{
@@ -283,6 +288,21 @@ WriteVideoCardCapsFile(void)
}
#endif
+bool
+CanVideoCardDoDXT(void)
+{
+#ifdef LIBRW
+ // TODO
+#ifdef RW_OPENGL
+ return false;
+#else
+ return true;
+#endif
+#else
+ return _rwD3D8CheckValidTextureFormat(D3DFMT_DXT1) && _rwD3D8CheckValidTextureFormat(D3DFMT_DXT3);
+#endif
+}
+
void
ConvertingTexturesScreen(uint32 num, uint32 count, const char *text)
{
@@ -301,7 +321,11 @@ ConvertingTexturesScreen(uint32 num, uint32 count, const char *text)
splash->Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255));
CSprite2d::DrawRect(CRect(SCREEN_SCALE_X(200.0f), SCREEN_SCALE_Y(240.0f), SCREEN_SCALE_FROM_RIGHT(200.0f), SCREEN_SCALE_Y(248.0f)), CRGBA(64, 64, 64, 255));
+#ifdef FIX_BUGS
+ CSprite2d::DrawRect(CRect(SCREEN_SCALE_X(200.0f), SCREEN_SCALE_Y(240.0f), (SCREEN_SCALE_FROM_RIGHT(200.0f) - SCREEN_SCALE_X(200.0f)) * ((float)num / (float)count) + SCREEN_SCALE_X(200.0f), SCREEN_SCALE_Y(248.0f)), CRGBA(255, 150, 225, 255));
+#else
CSprite2d::DrawRect(CRect(SCREEN_SCALE_X(200.0f), SCREEN_SCALE_Y(240.0f), (SCREEN_SCALE_FROM_RIGHT(200.0f) - SCREEN_SCALE_X(200.0f)) * ((float)num / (float)count) + SCREEN_SCALE_X(200.0f), SCREEN_SCALE_Y(248.0f)), CRGBA(255, 217, 106, 255));
+#endif
CSprite2d::DrawRect(CRect(SCREEN_SCALE_X(120.0f), SCREEN_SCALE_Y(150.0f), SCREEN_SCALE_FROM_RIGHT(120.0f), SCREEN_HEIGHT - SCREEN_SCALE_Y(220.0f)), CRGBA(50, 50, 50, 210));
CFont::SetBackgroundOff();
@@ -310,9 +334,13 @@ ConvertingTexturesScreen(uint32 num, uint32 count, const char *text)
CFont::SetCentreOff();
CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(170.0f));
CFont::SetJustifyOff();
+#ifdef FIX_BUGS
+ CFont::SetColor(CRGBA(255, 150, 225, 255));
+#else
CFont::SetColor(CRGBA(255, 217, 106, 255));
+#endif
CFont::SetBackGroundOnlyTextOff();
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
CFont::PrintString(SCREEN_SCALE_X(170.0f), SCREEN_SCALE_Y(160.0f), TheText.Get(text));
CFont::DrawFonts();
DoRWStuffEndOfFrame();
@@ -373,10 +401,10 @@ CreateTxdImageForVideoCard()
#ifdef DISABLE_VSYNC_ON_TEXTURE_CONVERSION
// let's disable vsync and frame limiter to speed up texture conversion
// (actually we probably don't need to disable frame limiter in here, but let's do it just in case =P)
- int8 vsyncState = CMenuManager::m_PrefsVsync;
- int8 frameLimiterState = CMenuManager::m_PrefsFrameLimiter;
- CMenuManager::m_PrefsVsync = 0;
- CMenuManager::m_PrefsFrameLimiter = 0;
+ int8 vsyncState = FrontEndMenuManager.m_PrefsVsync;
+ int8 frameLimiterState = FrontEndMenuManager.m_PrefsFrameLimiter;
+ FrontEndMenuManager.m_PrefsVsync = 0;
+ FrontEndMenuManager.m_PrefsFrameLimiter = 0;
#endif
int32 i;
@@ -434,8 +462,8 @@ CreateTxdImageForVideoCard()
#ifdef DISABLE_VSYNC_ON_TEXTURE_CONVERSION
// restore vsync and frame limiter states
- CMenuManager::m_PrefsVsync = vsyncState;
- CMenuManager::m_PrefsFrameLimiter = frameLimiterState;
+ FrontEndMenuManager.m_PrefsVsync = vsyncState;
+ FrontEndMenuManager.m_PrefsFrameLimiter = frameLimiterState;
#endif
RwStreamClose(img, nil);
diff --git a/src/rw/TxdStore.cpp b/src/rw/TxdStore.cpp
index a9e29729..0bd29718 100644
--- a/src/rw/TxdStore.cpp
+++ b/src/rw/TxdStore.cpp
@@ -13,7 +13,7 @@ void
CTxdStore::Initialise(void)
{
if(ms_pTxdPool == nil)
- ms_pTxdPool = new CPool<TxdDef,TxdDef>(TXDSTORESIZE);
+ ms_pTxdPool = new CPool<TxdDef,TxdDef>(TXDSTORESIZE, "TexDictionary");
}
void
diff --git a/src/rw/VisibilityPlugins.cpp b/src/rw/VisibilityPlugins.cpp
index e6d4641d..01f2c8e7 100644
--- a/src/rw/VisibilityPlugins.cpp
+++ b/src/rw/VisibilityPlugins.cpp
@@ -6,6 +6,7 @@
#include "Entity.h"
#include "ModelInfo.h"
#include "Lights.h"
+#include "RwHelper.h"
#include "Renderer.h"
#include "Camera.h"
#include "VisibilityPlugins.h"
@@ -14,7 +15,9 @@
#include "MemoryHeap.h"
CLinkList<CVisibilityPlugins::AlphaObjectInfo> CVisibilityPlugins::m_alphaList;
+CLinkList<CVisibilityPlugins::AlphaObjectInfo> CVisibilityPlugins::m_alphaBoatAtomicList;
CLinkList<CVisibilityPlugins::AlphaObjectInfo> CVisibilityPlugins::m_alphaEntityList;
+CLinkList<CVisibilityPlugins::AlphaObjectInfo> CVisibilityPlugins::m_alphaUnderwaterEntityList;
#ifdef NEW_RENDERER
CLinkList<CVisibilityPlugins::AlphaObjectInfo> CVisibilityPlugins::m_alphaBuildingList;
#endif
@@ -31,122 +34,10 @@ float CVisibilityPlugins::ms_vehicleLod1Dist;
float CVisibilityPlugins::ms_vehicleFadeDist;
float CVisibilityPlugins::ms_bigVehicleLod0Dist;
float CVisibilityPlugins::ms_bigVehicleLod1Dist;
-float CVisibilityPlugins::ms_pedLod0Dist;
float CVisibilityPlugins::ms_pedLod1Dist;
float CVisibilityPlugins::ms_pedFadeDist;
-#ifdef GTA_PS2 // maybe something else?
-// if wanted, delete the original geometry data after rendering
-// and only keep the instanced data
-bool
-rpDefaultGeometryInstance(RpGeometry *geo, void *atomic, int del)
-{
-#if THIS_IS_COMPATIBLE_WITH_GTA3_RW31
- if(RpGeometryGetNumMorphTargets(geo) != 1)
- return false;
-
- // this needs R*'s modification that geometry data is
- // allocated separately from the geometry itself
- geo->instanceFlags = rpGEOMETRYINSTANCE;
- AtomicDefaultRenderCallBack((RpAtomic*)atomic);
-
- if(!del)
- return true;
-
- // New mesh without indices
- RpMeshHeader *newheader = _rpMeshHeaderCreate(sizeof(RpMesh)*geo->mesh->numMeshes + sizeof(RpMeshHeader));
- newheader->numMeshes = geo->mesh->numMeshes;
- newheader->serialNum = 1;
- newheader->totalIndicesInMesh = 0;
- newheader->firstMeshOffset = 0;
- RpMesh *oldmesh = (RpMesh*)(geo->mesh+1);
- RpMesh *newmesh = (RpMesh*)(newheader+1);
- for(int i = 0; i < geo->mesh->numMeshes; i++){
- newmesh[i].indices = nil;
- newmesh[i].numIndices = 0;
- newmesh[i].material = oldmesh[i].material;
- }
-
- geo->refCount++;
- RpGeometryLock(geo, rpGEOMETRYLOCKPOLYGONS | rpGEOMETRYLOCKVERTICES |
- rpGEOMETRYLOCKNORMALS | rpGEOMETRYLOCKPRELIGHT |
- rpGEOMETRYLOCKTEXCOORDS1 | rpGEOMETRYLOCKTEXCOORDS2);
-
- // vertices and normals
- RpMorphTarget *mt = RpGeometryGetMorphTarget(geo, 0);
- if(mt->verts){
- RwFree(mt->verts);
- mt->verts = nil;
- mt->normals = nil;
- }
- geo->numVertices = 0;
-
- // triangles
- for(int i = 0; i < RpGeometryGetNumTriangles(geo); i++){
- if(RpGeometryGetTriangles(geo)->matIndex == -1)
- continue;
- RpMaterialDestroy(_rpMaterialListGetMaterial(&geo->matList, RpGeometryGetTriangles(geo)->matIndex));
- }
- if(RpGeometryGetTriangles(geo)){
- RwFree(RpGeometryGetTriangles(geo));
- geo->triangles = nil;
- geo->numTriangles = 0;
- }
-
- // tex coords
- if(RpGeometryGetVertexTexCoords(geo, 1)){
- RwFree(RpGeometryGetVertexTexCoords(geo, 1));
- geo->texCoords[1] = nil;
- }
- if(RpGeometryGetVertexTexCoords(geo, 0)){
- RwFree(RpGeometryGetVertexTexCoords(geo, 0));
- geo->texCoords[0] = nil;
- }
-
- // vertex colors
- if(RpGeometryGetPreLightColors(geo)){
- RwFree(RpGeometryGetPreLightColors(geo));
- geo->preLitLum = nil;
- }
-
- RpGeometryUnlock(geo);
-
- geo->instanceFlags = rpGEOMETRYPERSISTENT;
- // BUG? don't we have to free the old mesh?
- geo->mesh = newheader;
- geo->refCount--;
-#else
- // We can do something for librw here actually, maybe later
- AtomicDefaultRenderCallBack((RpAtomic*)atomic);
-#endif
-
- return true;
-}
-
-RpAtomic*
-PreInstanceRenderCB(RpAtomic *atomic)
-{
- RpGeometry *geo = RpAtomicGetGeometry(atomic);
- if(RpGeometryGetTriangles(geo)){
- PUSH_MEMID(MEMID_STREAM_MODELS);
- rpDefaultGeometryInstance(geo, atomic, 1);
- POP_MEMID();
- }else
- AtomicDefaultRenderCallBack(atomic);
- return atomic;
-}
-#define RENDERCALLBACK PreInstanceRenderCB
-#else
-RpAtomic*
-DefaultRenderCB_pushid(RpAtomic *atomic)
-{
- PUSH_MEMID(MEMID_STREAM_MODELS);
- AtomicDefaultRenderCallBack(atomic);
- POP_MEMID();
- return atomic;
-}
-#define RENDERCALLBACK DefaultRenderCB_pushid
-#endif
+#define RENDERCALLBACK AtomicDefaultRenderCallBack
void
CVisibilityPlugins::Initialise(void)
@@ -154,6 +45,11 @@ CVisibilityPlugins::Initialise(void)
m_alphaList.Init(NUMALPHALIST);
m_alphaList.head.item.sort = 0.0f;
m_alphaList.tail.item.sort = 100000000.0f;
+
+ m_alphaBoatAtomicList.Init(NUMBOATALPHALIST);
+ m_alphaBoatAtomicList.head.item.sort = 0.0f;
+ m_alphaBoatAtomicList.tail.item.sort = 100000000.0f;
+
#ifdef ASPECT_RATIO_SCALE
// default 150 is not enough for bigger FOVs
m_alphaEntityList.Init(NUMALPHAENTITYLIST * 3);
@@ -163,6 +59,10 @@ CVisibilityPlugins::Initialise(void)
m_alphaEntityList.head.item.sort = 0.0f;
m_alphaEntityList.tail.item.sort = 100000000.0f;
+ m_alphaUnderwaterEntityList.Init(NUMALPHAUNTERWATERENTITYLIST);
+ m_alphaUnderwaterEntityList.head.item.sort = 0.0f;
+ m_alphaUnderwaterEntityList.tail.item.sort = 100000000.0f;
+
#ifdef NEW_RENDERER
m_alphaBuildingList.Init(NUMALPHAENTITYLIST);
m_alphaBuildingList.head.item.sort = 0.0f;
@@ -174,7 +74,9 @@ void
CVisibilityPlugins::Shutdown(void)
{
m_alphaList.Shutdown();
+ m_alphaBoatAtomicList.Shutdown();
m_alphaEntityList.Shutdown();
+ m_alphaUnderwaterEntityList.Shutdown();
#ifdef NEW_RENDERER
m_alphaBuildingList.Shutdown();
#endif
@@ -184,6 +86,8 @@ void
CVisibilityPlugins::InitAlphaEntityList(void)
{
m_alphaEntityList.Clear();
+ m_alphaBoatAtomicList.Clear();
+ m_alphaUnderwaterEntityList.Clear();
#ifdef NEW_RENDERER
m_alphaBuildingList.Clear();
#endif
@@ -203,10 +107,9 @@ CVisibilityPlugins::InsertEntityIntoSortedList(CEntity *e, float dist)
if(gbNewRenderer && e->IsBuilding())
return !!m_alphaBuildingList.InsertSorted(item);
#endif
- bool ret = !!m_alphaEntityList.InsertSorted(item);
-// if(!ret)
-// printf("list full %d\n", m_alphaEntityList.Count());
- return ret;
+ if(e->bUnderwater && m_alphaUnderwaterEntityList.InsertSorted(item))
+ return true;
+ return !!m_alphaEntityList.InsertSorted(item);
}
void
@@ -221,10 +124,16 @@ CVisibilityPlugins::InsertAtomicIntoSortedList(RpAtomic *a, float dist)
AlphaObjectInfo item;
item.atomic = a;
item.sort = dist;
- bool ret = !!m_alphaList.InsertSorted(item);
-// if(!ret)
-// printf("list full %d\n", m_alphaList.Count());
- return ret;
+ return !!m_alphaList.InsertSorted(item);
+}
+
+bool
+CVisibilityPlugins::InsertAtomicIntoBoatSortedList(RpAtomic *a, float dist)
+{
+ AlphaObjectInfo item;
+ item.atomic = a;
+ item.sort = dist;
+ return !!m_alphaBoatAtomicList.InsertSorted(item);
}
// can't increase this yet unfortunately...
@@ -243,14 +152,28 @@ CVisibilityPlugins::SetRenderWareCamera(RwCamera *camera)
else
ms_cullCompsDist = sq(TheCamera.LODDistMultiplier * 20.0f);
- ms_vehicleLod0Dist = sq(70.0f * VEHICLE_LODDIST_MULTIPLIER);
- ms_vehicleLod1Dist = sq(90.0f * VEHICLE_LODDIST_MULTIPLIER);
- ms_vehicleFadeDist = sq(100.0f * VEHICLE_LODDIST_MULTIPLIER);
- ms_bigVehicleLod0Dist = sq(60.0f * VEHICLE_LODDIST_MULTIPLIER);
- ms_bigVehicleLod1Dist = sq(150.0f * VEHICLE_LODDIST_MULTIPLIER);
- ms_pedLod0Dist = sq(25.0f * TheCamera.LODDistMultiplier);
- ms_pedLod1Dist = sq(60.0f * TheCamera.LODDistMultiplier);
- ms_pedFadeDist = sq(70.0f * TheCamera.LODDistMultiplier);
+ ms_vehicleLod0Dist = sq(70.0f * VEHICLE_LODDIST_MULTIPLIER);
+ ms_vehicleLod1Dist = sq(90.0f * VEHICLE_LODDIST_MULTIPLIER);
+ ms_vehicleFadeDist = sq(100.0f * VEHICLE_LODDIST_MULTIPLIER);
+ ms_bigVehicleLod0Dist = sq(60.0f * VEHICLE_LODDIST_MULTIPLIER);
+ ms_bigVehicleLod1Dist = sq(150.0f * VEHICLE_LODDIST_MULTIPLIER);
+ ms_pedLod1Dist = sq(60.0f * TheCamera.LODDistMultiplier);
+ ms_pedFadeDist = sq(70.0f * TheCamera.LODDistMultiplier);
+}
+
+static float DistToCameraSq;
+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);
+ float dist2d = Sqrt(SQR(distToCam.x) + SQR(distToCam.y));
+ PitchToCamera = Atan2(distToCam.z, dist2d);
}
RpMaterial*
@@ -268,23 +191,33 @@ SetTextureCB(RpMaterial *material, void *data)
}
void
-CVisibilityPlugins::RenderAlphaAtomics(void)
+CVisibilityPlugins::RenderAtomicList(CLinkList<AlphaObjectInfo> &list)
{
CLink<AlphaObjectInfo> *node;
- for(node = m_alphaList.tail.prev;
- node != &m_alphaList.head;
- node = node->prev)
+ for(node = list.tail.prev; node != &list.head; node = node->prev)
RENDERCALLBACK(node->item.atomic);
}
void
-CVisibilityPlugins::RenderFadingEntities(void)
+CVisibilityPlugins::RenderAlphaAtomics(void)
+{
+ RenderAtomicList(m_alphaList);
+}
+
+void
+CVisibilityPlugins::RenderBoatAlphaAtomics(void)
+{
+ SetCullMode(rwCULLMODECULLNONE);
+ RenderAtomicList(m_alphaBoatAtomicList);
+ SetCullMode(rwCULLMODECULLBACK);
+}
+
+void
+CVisibilityPlugins::RenderFadingEntities(CLinkList<AlphaObjectInfo> &list)
{
CLink<AlphaObjectInfo> *node;
CSimpleModelInfo *mi;
- for(node = m_alphaEntityList.tail.prev;
- node != &m_alphaEntityList.head;
- node = node->prev){
+ for(node = list.tail.prev; node != &list.head; node = node->prev){
CEntity *e = node->item.entity;
if(e->m_rwObject == nil)
continue;
@@ -293,19 +226,8 @@ CVisibilityPlugins::RenderFadingEntities(void)
continue;
#endif
mi = (CSimpleModelInfo *)CModelInfo::GetModelInfo(e->GetModelIndex());
-
-#ifdef FIX_BUGS
if(mi->GetModelType() == MITYPE_SIMPLE && mi->m_noZwrite)
-#else
- if(mi->m_noZwrite)
-#endif
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, FALSE);
-#ifdef EXTRA_MODEL_FLAGS
- else if(mi->m_bIsTree)
- SetAlphaRef(128);
- if(!e->IsBuilding() || mi->RenderDoubleSided())
- BACKFACE_CULLING_OFF;
-#endif
if(e->bDistanceFade){
DeActivateDirectional();
@@ -318,39 +240,34 @@ CVisibilityPlugins::RenderFadingEntities(void)
}else
CRenderer::RenderOneNonRoad(e);
-#ifdef EXTRA_MODEL_FLAGS
- if(mi->m_bIsTree)
- SetAlphaRef(2);
- BACKFACE_CULLING_ON;
-#endif
-#ifdef FIX_BUGS
if(mi->GetModelType() == MITYPE_SIMPLE && mi->m_noZwrite)
-#else
- if(mi->m_noZwrite)
-#endif
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
}
}
+void
+CVisibilityPlugins::RenderFadingEntities(void)
+{
+ RenderFadingEntities(m_alphaEntityList);
+ RenderBoatAlphaAtomics();
+}
+
+void
+CVisibilityPlugins::RenderFadingUnderwaterEntities(void)
+{
+ RenderFadingEntities(m_alphaUnderwaterEntityList);
+}
+
RpAtomic*
CVisibilityPlugins::RenderWheelAtomicCB(RpAtomic *atomic)
{
RpAtomic *lodatm;
- RwMatrix *m;
- RwV3d view;
float len;
CSimpleModelInfo *mi;
mi = GetAtomicModelInfo(atomic);
- m = RwFrameGetLTM(RpAtomicGetFrame(atomic));
- RwV3dSub(&view, RwMatrixGetPos(m), ms_pCameraPosn);
- len = RwV3dLength(&view);
-#ifdef FIX_BUGS
- // from VC
+ len = Sqrt(DistToCameraSq);
lodatm = mi->GetAtomicFromDistance(len * TheCamera.LODDistMultiplier / VEHICLE_LODDIST_MULTIPLIER);
-#else
- lodatm = mi->GetAtomicFromDistance(len);
-#endif
if(lodatm){
if(RpAtomicGetGeometry(lodatm) != RpAtomicGetGeometry(atomic))
RpAtomicSetGeometry(atomic, RpAtomicGetGeometry(lodatm), rpATOMICSAMEBOUNDINGSPHERE);
@@ -392,6 +309,24 @@ CVisibilityPlugins::RenderAlphaAtomic(RpAtomic *atomic, int alpha)
}
RpAtomic*
+CVisibilityPlugins::RenderWeaponCB(RpAtomic *atomic)
+{
+ RwMatrix *m;
+ RwV3d view;
+ float maxdist, distsq;
+ CSimpleModelInfo *mi;
+
+ mi = GetAtomicModelInfo(atomic);
+ m = RwFrameGetLTM(RpAtomicGetFrame(atomic));
+ RwV3dSub(&view, RwMatrixGetPos(m), ms_pCameraPosn);
+ maxdist = mi->GetLodDistance(0);
+ distsq = RwV3dDotProduct(&view, &view);
+ if(distsq < maxdist*maxdist)
+ RENDERCALLBACK(atomic);
+ return atomic;
+}
+
+RpAtomic*
CVisibilityPlugins::RenderFadingAtomic(RpAtomic *atomic, float camdist)
{
RpAtomic *lodatm;
@@ -401,29 +336,30 @@ CVisibilityPlugins::RenderFadingAtomic(RpAtomic *atomic, float camdist)
mi = GetAtomicModelInfo(atomic);
lodatm = mi->GetAtomicFromDistance(camdist - FADE_DISTANCE);
- if(mi->m_additive){
+ if(mi->m_additive)
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
+
+ fadefactor = (mi->GetLargestLodDistance() - (camdist - FADE_DISTANCE))/FADE_DISTANCE;
+ if(fadefactor > 1.0f)
+ fadefactor = 1.0f;
+ alpha = mi->m_alpha * fadefactor;
+ if(alpha == 255)
RENDERCALLBACK(atomic);
- RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
- }else{
- fadefactor = (mi->GetLargestLodDistance() - (camdist - FADE_DISTANCE))/FADE_DISTANCE;
- if(fadefactor > 1.0f)
- fadefactor = 1.0f;
- alpha = mi->m_alpha * fadefactor;
- if(alpha == 255)
- RENDERCALLBACK(atomic);
- else{
- RpGeometry *geo = RpAtomicGetGeometry(lodatm);
- uint32 flags = RpGeometryGetFlags(geo);
- RpGeometrySetFlags(geo, flags | rpGEOMETRYMODULATEMATERIALCOLOR);
- RpGeometryForAllMaterials(geo, SetAlphaCB, (void*)alpha);
- if(geo != RpAtomicGetGeometry(atomic))
- RpAtomicSetGeometry(atomic, geo, rpATOMICSAMEBOUNDINGSPHERE); // originally 5 (mistake?)
- RENDERCALLBACK(atomic);
- RpGeometryForAllMaterials(geo, SetAlphaCB, (void*)255);
- RpGeometrySetFlags(geo, flags);
- }
+ else{
+ RpGeometry *geo = RpAtomicGetGeometry(lodatm);
+ uint32 flags = RpGeometryGetFlags(geo);
+ RpGeometrySetFlags(geo, flags | rpGEOMETRYMODULATEMATERIALCOLOR);
+ RpGeometryForAllMaterials(geo, SetAlphaCB, (void*)alpha);
+ if(geo != RpAtomicGetGeometry(atomic))
+ RpAtomicSetGeometry(atomic, geo, rpATOMICSAMEBOUNDINGSPHERE); // originally 5 (mistake?)
+ RENDERCALLBACK(atomic);
+ RpGeometryForAllMaterials(geo, SetAlphaCB, (void*)255);
+ RpGeometrySetFlags(geo, flags);
}
+
+ if(mi->m_additive)
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+
return atomic;
}
@@ -433,17 +369,16 @@ RpAtomic*
CVisibilityPlugins::RenderVehicleHiDetailCB(RpAtomic *atomic)
{
RwFrame *clumpframe;
- float distsq, dot;
+ float dot;
uint32 flags;
clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic));
- distsq = GetDistanceSquaredFromCamera(clumpframe);
- if(distsq < ms_vehicleLod0Dist){
+ if(DistToCameraSq < ms_vehicleLod0Dist){
flags = GetAtomicId(atomic);
- if(distsq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0){
+ if(DistToCameraSq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0 && PitchToCamera < 0.2f){
dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)),
RwFrameGetLTM(clumpframe), flags);
- if(dot > 0.0f && ((flags & ATOMIC_FLAG_ANGLECULL) || 0.1f*distsq < dot*dot))
+ if(dot > 0.0f && ((flags & ATOMIC_FLAG_ANGLECULL) || 0.1f*DistToCameraSq < dot*dot))
return atomic;
}
RENDERCALLBACK(atomic);
@@ -455,25 +390,24 @@ RpAtomic*
CVisibilityPlugins::RenderVehicleHiDetailAlphaCB(RpAtomic *atomic)
{
RwFrame *clumpframe;
- float distsq, dot;
+ float dot;
uint32 flags;
clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic));
- distsq = GetDistanceSquaredFromCamera(clumpframe);
- if(distsq < ms_vehicleLod0Dist){
+ if(DistToCameraSq < ms_vehicleLod0Dist){
flags = GetAtomicId(atomic);
dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)),
RwFrameGetLTM(clumpframe), flags);
- if(distsq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0)
- if(dot > 0.0f && ((flags & ATOMIC_FLAG_ANGLECULL) || 0.1f*distsq < dot*dot))
+ if(DistToCameraSq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0 && PitchToCamera < 0.2f)
+ if(dot > 0.0f && ((flags & ATOMIC_FLAG_ANGLECULL) || 0.1f*DistToCameraSq < dot*dot))
return atomic;
if(flags & ATOMIC_FLAG_DRAWLAST){
// sort before clump
- if(!InsertAtomicIntoSortedList(atomic, distsq - 0.0001f))
+ if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq - 0.0001f))
RENDERCALLBACK(atomic);
}else{
- if(!InsertAtomicIntoSortedList(atomic, distsq + dot))
+ if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq + dot))
RENDERCALLBACK(atomic);
}
}
@@ -484,14 +418,13 @@ RpAtomic*
CVisibilityPlugins::RenderVehicleHiDetailCB_BigVehicle(RpAtomic *atomic)
{
RwFrame *clumpframe;
- float distsq, dot;
+ float dot;
uint32 flags;
clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic));
- distsq = GetDistanceSquaredFromCamera(clumpframe);
- if(distsq < ms_bigVehicleLod0Dist){
+ if(DistToCameraSq < ms_bigVehicleLod0Dist){
flags = GetAtomicId(atomic);
- if(distsq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0){
+ if(DistToCameraSq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0 && PitchToCamera < 0.2f){
dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)),
RwFrameGetLTM(clumpframe), flags);
if(dot > 0.0f)
@@ -506,20 +439,19 @@ RpAtomic*
CVisibilityPlugins::RenderVehicleHiDetailAlphaCB_BigVehicle(RpAtomic *atomic)
{
RwFrame *clumpframe;
- float distsq, dot;
+ float dot;
uint32 flags;
clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic));
- distsq = GetDistanceSquaredFromCamera(clumpframe);
- if(distsq < ms_bigVehicleLod0Dist){
+ if(DistToCameraSq < ms_bigVehicleLod0Dist){
flags = GetAtomicId(atomic);
dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)),
RwFrameGetLTM(clumpframe), flags);
- if(dot > 0.0f)
- if(distsq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0)
+ if(DistToCameraSq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0 && PitchToCamera < 0.2f)
+ if(dot > 0.0f && ((flags & ATOMIC_FLAG_ANGLECULL) || 0.1f*DistToCameraSq < dot*dot))
return atomic;
- if(!InsertAtomicIntoSortedList(atomic, distsq + dot))
+ if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq + dot))
RENDERCALLBACK(atomic);
}
return atomic;
@@ -528,29 +460,53 @@ CVisibilityPlugins::RenderVehicleHiDetailAlphaCB_BigVehicle(RpAtomic *atomic)
RpAtomic*
CVisibilityPlugins::RenderVehicleHiDetailCB_Boat(RpAtomic *atomic)
{
- RwFrame *clumpframe;
- float distsq;
-
- clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic));
- distsq = GetDistanceSquaredFromCamera(clumpframe);
- if(distsq < ms_bigVehicleLod1Dist)
+ if(DistToCameraSq < ms_vehicleLod0Dist)
RENDERCALLBACK(atomic);
return atomic;
}
RpAtomic*
+CVisibilityPlugins::RenderVehicleHiDetailAlphaCB_Boat(RpAtomic *atomic)
+{
+ if(DistToCameraSq < ms_vehicleLod0Dist){
+ if(GetAtomicId(atomic) & ATOMIC_FLAG_DRAWLAST){
+ if(!InsertAtomicIntoBoatSortedList(atomic, DistToCameraSq))
+ RENDERCALLBACK(atomic);
+ }else
+ RENDERCALLBACK(atomic);
+ }
+ return atomic;
+}
+
+RpAtomic*
+CVisibilityPlugins::RenderVehicleLoDetailCB_Boat(RpAtomic *atomic)
+{
+ RpClump *clump;
+ int32 alpha;
+
+ clump = RpAtomicGetClump(atomic);
+ if(DistToCameraSq >= ms_vehicleLod0Dist){
+ alpha = GetClumpAlpha(clump);
+ if(alpha == 255)
+ RENDERCALLBACK(atomic);
+ else
+ RenderAlphaAtomic(atomic, alpha);
+ }
+ return atomic;
+}
+
+RpAtomic*
CVisibilityPlugins::RenderVehicleLowDetailCB_BigVehicle(RpAtomic *atomic)
{
RwFrame *clumpframe;
- float distsq, dot;
+ float dot;
uint32 flags;
clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic));
- distsq = GetDistanceSquaredFromCamera(clumpframe);
- if(distsq >= ms_bigVehicleLod0Dist &&
- distsq < ms_bigVehicleLod1Dist){
+ if(DistToCameraSq >= ms_bigVehicleLod0Dist &&
+ DistToCameraSq < ms_bigVehicleLod1Dist){
flags = GetAtomicId(atomic);
- if(distsq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0){
+ if(DistToCameraSq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0 && PitchToCamera < 0.2f){
dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)),
RwFrameGetLTM(clumpframe), flags);
if(dot > 0.0f)
@@ -565,21 +521,20 @@ RpAtomic*
CVisibilityPlugins::RenderVehicleLowDetailAlphaCB_BigVehicle(RpAtomic *atomic)
{
RwFrame *clumpframe;
- float distsq, dot;
+ float dot;
uint32 flags;
clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic));
- distsq = GetDistanceSquaredFromCamera(clumpframe);
- if(distsq >= ms_bigVehicleLod0Dist &&
- distsq < ms_bigVehicleLod1Dist){
+ if(DistToCameraSq >= ms_bigVehicleLod0Dist &&
+ DistToCameraSq < ms_bigVehicleLod1Dist){
flags = GetAtomicId(atomic);
dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)),
RwFrameGetLTM(clumpframe), flags);
if(dot > 0.0f)
- if(distsq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0)
+ if(DistToCameraSq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0 && PitchToCamera < 0.2f)
return atomic;
- if(!InsertAtomicIntoSortedList(atomic, distsq + dot))
+ if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq + dot))
RENDERCALLBACK(atomic);
}
return atomic;
@@ -589,12 +544,10 @@ RpAtomic*
CVisibilityPlugins::RenderVehicleReallyLowDetailCB(RpAtomic *atomic)
{
RpClump *clump;
- float dist;
int32 alpha;
clump = RpAtomicGetClump(atomic);
- dist = GetDistanceSquaredFromCamera(RpClumpGetFrame(clump));
- if(dist >= ms_vehicleLod0Dist){
+ if(DistToCameraSq >= ms_vehicleLod0Dist){
alpha = GetClumpAlpha(clump);
if(alpha == 255)
RENDERCALLBACK(atomic);
@@ -608,12 +561,7 @@ CVisibilityPlugins::RenderVehicleReallyLowDetailCB(RpAtomic *atomic)
RpAtomic*
CVisibilityPlugins::RenderVehicleReallyLowDetailCB_BigVehicle(RpAtomic *atomic)
{
- RwFrame *clumpframe;
- float distsq;
-
- clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic));
- distsq = GetDistanceSquaredFromCamera(clumpframe);
- if(distsq >= ms_bigVehicleLod1Dist)
+ if(DistToCameraSq >= ms_bigVehicleLod1Dist)
RENDERCALLBACK(atomic);
return atomic;
}
@@ -622,17 +570,16 @@ RpAtomic*
CVisibilityPlugins::RenderTrainHiDetailCB(RpAtomic *atomic)
{
RwFrame *clumpframe;
- float distsq, dot;
+ float dot;
uint32 flags;
clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic));
- distsq = GetDistanceSquaredFromCamera(clumpframe);
- if(distsq < ms_bigVehicleLod1Dist){
+ if(DistToCameraSq < ms_bigVehicleLod1Dist){
flags = GetAtomicId(atomic);
- if(distsq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0){
+ if(DistToCameraSq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0 && PitchToCamera < 0.2f){
dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)),
RwFrameGetLTM(clumpframe), flags);
- if(dot > 0.0f && ((flags & ATOMIC_FLAG_ANGLECULL) || 0.1f*distsq < dot*dot))
+ if(dot > 0.0f && ((flags & ATOMIC_FLAG_ANGLECULL) || 0.1f*DistToCameraSq < dot*dot))
return atomic;
}
RENDERCALLBACK(atomic);
@@ -644,24 +591,23 @@ RpAtomic*
CVisibilityPlugins::RenderTrainHiDetailAlphaCB(RpAtomic *atomic)
{
RwFrame *clumpframe;
- float distsq, dot;
+ float dot;
uint32 flags;
clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic));
- distsq = GetDistanceSquaredFromCamera(clumpframe);
- if(distsq < ms_bigVehicleLod1Dist){
+ if(DistToCameraSq < ms_bigVehicleLod1Dist){
flags = GetAtomicId(atomic);
dot = GetDotProductWithCameraVector(RwFrameGetLTM(RpAtomicGetFrame(atomic)),
RwFrameGetLTM(clumpframe), flags);
- if(distsq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0)
- if(dot > 0.0f && ((flags & ATOMIC_FLAG_ANGLECULL) || 0.1f*distsq < dot*dot))
+ if(DistToCameraSq > ms_cullCompsDist && (flags & ATOMIC_FLAG_NOCULL) == 0 && PitchToCamera < 0.2f)
+ if(dot > 0.0f && ((flags & ATOMIC_FLAG_ANGLECULL) || 0.1f*DistToCameraSq < dot*dot))
return atomic;
if(flags & ATOMIC_FLAG_DRAWLAST){
- if(!InsertAtomicIntoSortedList(atomic, distsq))
+ if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq))
RENDERCALLBACK(atomic);
}else{
- if(!InsertAtomicIntoSortedList(atomic, distsq + dot))
+ if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq + dot))
RENDERCALLBACK(atomic);
}
}
@@ -669,35 +615,51 @@ CVisibilityPlugins::RenderTrainHiDetailAlphaCB(RpAtomic *atomic)
}
RpAtomic*
-CVisibilityPlugins::RenderPlayerCB(RpAtomic *atomic)
+CVisibilityPlugins::RenderVehicleRotorAlphaCB(RpAtomic *atomic)
{
- if(CWorld::Players[0].m_pSkinTexture)
- RpGeometryForAllMaterials(RpAtomicGetGeometry(atomic), SetTextureCB, CWorld::Players[0].m_pSkinTexture);
- RENDERCALLBACK(atomic);
+ RwFrame *clumpframe;
+ float dot;
+ RwV3d cam2atm;
+
+ clumpframe = RpClumpGetFrame(RpAtomicGetClump(atomic));
+ if(DistToCameraSq < ms_bigVehicleLod1Dist){
+ RwV3dSub(&cam2atm, &RwFrameGetLTM(RpAtomicGetFrame(atomic))->pos, ms_pCameraPosn);
+ dot = RwV3dDotProduct(&cam2atm, &RwFrameGetLTM(clumpframe)->at);
+ if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq + dot*20.0f))
+ RENDERCALLBACK(atomic);
+ }
return atomic;
}
RpAtomic*
-CVisibilityPlugins::RenderPedLowDetailCB(RpAtomic *atomic)
+CVisibilityPlugins::RenderVehicleTailRotorAlphaCB(RpAtomic *atomic)
{
- RpClump *clump;
- float dist;
- int32 alpha;
+ RwMatrix *clumpMat, *atmMat;
+ float dot;
+ RwV3d cam2atm;
- clump = RpAtomicGetClump(atomic);
- dist = GetDistanceSquaredFromCamera(RpClumpGetFrame(clump));
- if(dist >= ms_pedLod0Dist){
- alpha = GetClumpAlpha(clump);
- if(alpha == 255)
+ if(DistToCameraSq < ms_bigVehicleLod0Dist){
+ atmMat = RwFrameGetLTM(RpAtomicGetFrame(atomic));
+ clumpMat = RwFrameGetLTM(RpClumpGetFrame(RpAtomicGetClump(atomic)));
+ RwV3dSub(&cam2atm, &atmMat->pos, ms_pCameraPosn);
+ dot = RwV3dDotProduct(&cam2atm, &clumpMat->up) + RwV3dDotProduct(&cam2atm, &clumpMat->right);
+ if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq - dot))
RENDERCALLBACK(atomic);
- else
- RenderAlphaAtomic(atomic, alpha);
}
return atomic;
}
RpAtomic*
-CVisibilityPlugins::RenderPedHiDetailCB(RpAtomic *atomic)
+CVisibilityPlugins::RenderPlayerCB(RpAtomic *atomic)
+{
+ if(CWorld::Players[0].m_pSkinTexture)
+ RpGeometryForAllMaterials(RpAtomicGetGeometry(atomic), SetTextureCB, CWorld::Players[0].m_pSkinTexture);
+ RENDERCALLBACK(atomic);
+ return atomic;
+}
+
+RpAtomic*
+CVisibilityPlugins::RenderPedCB(RpAtomic *atomic)
{
RpClump *clump;
float dist;
@@ -705,7 +667,7 @@ CVisibilityPlugins::RenderPedHiDetailCB(RpAtomic *atomic)
clump = RpAtomicGetClump(atomic);
dist = GetDistanceSquaredFromCamera(RpClumpGetFrame(clump));
- if(dist < ms_pedLod0Dist){
+ if(dist < ms_pedLod1Dist){
alpha = GetClumpAlpha(clump);
if(alpha == 255)
RENDERCALLBACK(atomic);
@@ -715,23 +677,12 @@ CVisibilityPlugins::RenderPedHiDetailCB(RpAtomic *atomic)
return atomic;
}
-// This is needed for peds with only one clump, i.e. skinned models
-// strangely even the xbox version has no such thing
-RpAtomic*
-CVisibilityPlugins::RenderPedCB(RpAtomic *atomic)
+float
+CVisibilityPlugins::GetDistanceSquaredFromCamera(RwV3d *pos)
{
- int32 alpha;
- RwV3d cam2atm;
-
- RwV3dSub(&cam2atm, &RwFrameGetLTM(RpAtomicGetFrame(atomic))->pos, ms_pCameraPosn);
- if(RwV3dDotProduct(&cam2atm, &cam2atm) < ms_pedLod1Dist){
- alpha = GetClumpAlpha(RpAtomicGetClump(atomic));
- if(alpha == 255)
- RENDERCALLBACK(atomic);
- else
- RenderAlphaAtomic(atomic, alpha);
- }
- return atomic;
+ RwV3d dist;
+ RwV3dSub(&dist, pos, ms_pCameraPosn);
+ return RwV3dDotProduct(&dist, &dist);
}
float
@@ -858,11 +809,6 @@ CVisibilityPlugins::PluginAttach(void)
ms_clumpPluginOffset = RpClumpRegisterPlugin(sizeof(ClumpExt),
ID_VISIBILITYCLUMP,
ClumpConstructor, ClumpDestructor, ClumpCopyConstructor);
-
-#if GTA_VERSION <= GTA3_PS2_160
- Initialise();
-#endif
-
return ms_atomicPluginOffset != -1 && ms_clumpPluginOffset != -1;
}
@@ -900,13 +846,6 @@ CVisibilityPlugins::SetAtomicModelInfo(RpAtomic *atomic,
{
AtomicExt *ext = ATOMICEXT(atomic);
ext->modelInfo = modelInfo;
- switch (modelInfo->GetModelType()) {
- case MITYPE_SIMPLE:
- case MITYPE_TIME:
- if(modelInfo->m_normalCull)
- SetAtomicRenderCallback(atomic, RenderObjNormalAtomic);
- default: break;
- }
}
CSimpleModelInfo*
@@ -943,7 +882,7 @@ void
CVisibilityPlugins::SetAtomicRenderCallback(RpAtomic *atomic, RpAtomicCallBackRender cb)
{
if(cb == nil)
- cb = RENDERCALLBACK;
+ cb = RENDERCALLBACK; // not necessary
RpAtomicSetRenderCallBack(atomic, cb);
}
diff --git a/src/rw/VisibilityPlugins.h b/src/rw/VisibilityPlugins.h
index f97fd589..90afc0f5 100644
--- a/src/rw/VisibilityPlugins.h
+++ b/src/rw/VisibilityPlugins.h
@@ -21,7 +21,9 @@ public:
};
static CLinkList<AlphaObjectInfo> m_alphaList;
+ static CLinkList<AlphaObjectInfo> m_alphaBoatAtomicList;
static CLinkList<AlphaObjectInfo> m_alphaEntityList;
+ static CLinkList<AlphaObjectInfo> m_alphaUnderwaterEntityList;
#ifdef NEW_RENDERER
static CLinkList<AlphaObjectInfo> m_alphaBuildingList;
#endif
@@ -33,7 +35,6 @@ public:
static float ms_vehicleFadeDist;
static float ms_bigVehicleLod0Dist;
static float ms_bigVehicleLod1Dist;
- static float ms_pedLod0Dist;
static float ms_pedLod1Dist;
static float ms_pedFadeDist;
@@ -43,12 +44,15 @@ public:
static bool InsertEntityIntoSortedList(CEntity *e, float dist);
static void InitAlphaAtomicList(void);
static bool InsertAtomicIntoSortedList(RpAtomic *a, float dist);
+ static bool InsertAtomicIntoBoatSortedList(RpAtomic *a, float dist);
static void SetRenderWareCamera(RwCamera *camera);
+ static void SetupVehicleVariables(RpClump *vehicle);
static RpAtomic *RenderWheelAtomicCB(RpAtomic *atomic);
static RpAtomic *RenderObjNormalAtomic(RpAtomic *atomic);
static RpAtomic *RenderAlphaAtomic(RpAtomic *atomic, int alpha);
+ static RpAtomic *RenderWeaponCB(RpAtomic *atomic);
static RpAtomic *RenderFadingAtomic(RpAtomic *atm, float dist);
static RpAtomic *RenderVehicleHiDetailCB(RpAtomic *atomic);
@@ -56,20 +60,26 @@ public:
static RpAtomic *RenderVehicleHiDetailCB_BigVehicle(RpAtomic *atomic);
static RpAtomic *RenderVehicleHiDetailAlphaCB_BigVehicle(RpAtomic *atomic);
static RpAtomic *RenderVehicleHiDetailCB_Boat(RpAtomic *atomic);
+ static RpAtomic *RenderVehicleHiDetailAlphaCB_Boat(RpAtomic *atomic);
+ static RpAtomic *RenderVehicleLoDetailCB_Boat(RpAtomic *atomic);
static RpAtomic *RenderVehicleLowDetailCB_BigVehicle(RpAtomic *atomic);
static RpAtomic *RenderVehicleLowDetailAlphaCB_BigVehicle(RpAtomic *atomic);
static RpAtomic *RenderVehicleReallyLowDetailCB(RpAtomic *atomic);
static RpAtomic *RenderVehicleReallyLowDetailCB_BigVehicle(RpAtomic *atomic);
static RpAtomic *RenderTrainHiDetailCB(RpAtomic *atomic);
static RpAtomic *RenderTrainHiDetailAlphaCB(RpAtomic *atomic);
+ static RpAtomic *RenderVehicleRotorAlphaCB(RpAtomic *atomic);
+ static RpAtomic *RenderVehicleTailRotorAlphaCB(RpAtomic *atomic);
static RpAtomic *RenderPlayerCB(RpAtomic *atomic);
- static RpAtomic *RenderPedLowDetailCB(RpAtomic *atomic);
- static RpAtomic *RenderPedHiDetailCB(RpAtomic *atomic);
static RpAtomic *RenderPedCB(RpAtomic *atomic); // for skinned models with only one clump
+ static void RenderAtomicList(CLinkList<AlphaObjectInfo> &list);
static void RenderAlphaAtomics(void);
+ static void RenderBoatAlphaAtomics(void);
+ static void RenderFadingEntities(CLinkList<AlphaObjectInfo> &list);
static void RenderFadingEntities(void);
+ static void RenderFadingUnderwaterEntities(void);
// All actually unused
static bool DefaultVisibilityCB(RpClump *clump);
@@ -78,6 +88,7 @@ public:
static bool VehicleVisibilityCB(RpClump *clump);
static bool VehicleVisibilityCB_BigVehicle(RpClump *clump);
+ static float GetDistanceSquaredFromCamera(RwV3d *pos);
static float GetDistanceSquaredFromCamera(RwFrame *frame);
static float GetDotProductWithCameraVector(RwMatrix *atomicMat, RwMatrix *clumpMat, uint32 flags);
diff --git a/src/save/GenericGameStorage.cpp b/src/save/GenericGameStorage.cpp
index e4ee4542..b68b805a 100644
--- a/src/save/GenericGameStorage.cpp
+++ b/src/save/GenericGameStorage.cpp
@@ -30,6 +30,7 @@
#include "Radar.h"
#include "Restart.h"
#include "Script.h"
+#include "SetPieces.h"
#include "Stats.h"
#include "Streaming.h"
#include "Timer.h"
@@ -37,9 +38,11 @@
#include "Weather.h"
#include "World.h"
#include "Zones.h"
+#include "Timecycle.h"
+#include "Fluff.h"
-#define BLOCK_COUNT 20
-#define SIZE_OF_SIMPLEVARS 0xBC
+#define BLOCK_COUNT 22
+#define SIZE_OF_SIMPLEVARS 0xE4
const uint32 SIZE_OF_ONE_GAME_IN_BYTES = 201729;
@@ -56,8 +59,7 @@ wchar SlotSaveDate[SLOT_COUNT][70];
int CheckSum;
eLevelName m_LevelToLoad;
char SaveFileNameJustSaved[260];
-int Slots[SLOT_COUNT+1];
-CDate CompileDateAndTime;
+int Slots[SLOT_COUNT];
bool b_FoundRecentSavedGameWantToLoad;
bool JustLoadedDontFadeInYet;
@@ -65,6 +67,28 @@ bool StillToFadeOut;
uint32 TimeStartedCountingForFade;
uint32 TimeToStayFadedBeforeFadeOut = 1750;
+int32 RadioStationPosition[NUM_RADIOS];
+
+void
+InitRadioStationPositionList()
+{
+ for (int i = 0; i < NUM_RADIOS; i++)
+ RadioStationPosition[i] = -1;
+}
+
+int32
+GetSavedRadioStationPosition(int32 station)
+{
+ return RadioStationPosition[station];
+}
+
+void
+PopulateRadioStationPositionList()
+{
+ for (int i = 0; i < NUM_RADIOS; i++)
+ RadioStationPosition[i] = DMAudio.GetRadioPosition(i);
+}
+
#define ReadDataFromBufferPointer(buf, to) memcpy(&to, buf, sizeof(to)); buf += align4bytes(sizeof(to));
#define WriteDataToBufferPointer(buf, from) memcpy(buf, &from, sizeof(from)); buf += align4bytes(sizeof(from));
@@ -87,12 +111,14 @@ do {\
buf += size;\
} while (0)
-#define WriteSaveDataBlock(save_func)\
+#define WriteSaveDataBlock(save_func, msg)\
do {\
+ size = 0;\
buf = work_buff;\
reserved = 0;\
MakeSpaceForSizeInBufferPointer(presize, buf, postsize);\
save_func(buf, &size);\
+ debug(msg"== %i \n", size);\
CopySizeAndPreparePointer(presize, buf, postsize, reserved, size);\
if (!PcSaveHelper.PcClassSaveRoutine(file, work_buff, buf - work_buff))\
return false;\
@@ -119,24 +145,23 @@ GenericSave(int file)
reserved = 0;
// Save simple vars
- lastMissionPassed = TheText.Get(CStats::LastMissionPassedName);
- if (lastMissionPassed[0] != '\0') {
- AsciiToUnicode("...'", suffix);
+ lastMissionPassed = TheText.Get(CStats::LastMissionPassedName[0] ? CStats::LastMissionPassedName : "ITBEG");
+ AsciiToUnicode("...'", suffix);
+ suffix[3] = L'\0';
#ifdef FIX_BUGS
- // fix buffer overflow
- int len = UnicodeStrlen(lastMissionPassed);
- if (len > ARRAY_SIZE(saveName)-1)
- len = ARRAY_SIZE(saveName)-1;
- memcpy(saveName, lastMissionPassed, sizeof(wchar) * len);
+ // fix buffer overflow
+ int len = UnicodeStrlen(lastMissionPassed);
+ if (len > ARRAY_SIZE(saveName)-1)
+ len = ARRAY_SIZE(saveName)-1;
+ memcpy(saveName, lastMissionPassed, sizeof(wchar) * len);
#else
- TextCopy(saveName, lastMissionPassed);
- int len = UnicodeStrlen(saveName);
+ TextCopy(saveName, lastMissionPassed);
+ int len = UnicodeStrlen(saveName);
#endif
- saveName[len] = '\0';
- if (len > ARRAY_SIZE(saveName)-2)
- TextCopy(&saveName[ARRAY_SIZE(saveName)-ARRAY_SIZE(suffix)], suffix);
- saveName[ARRAY_SIZE(saveName)-1] = '\0';
- }
+ saveName[len] = '\0';
+ if (len > ARRAY_SIZE(saveName)-2)
+ TextCopy(&saveName[ARRAY_SIZE(saveName)-ARRAY_SIZE(suffix)], suffix);
+ saveName[ARRAY_SIZE(saveName)-1] = '\0';
WriteDataToBufferPointer(buf, saveName);
GetLocalTime(&saveTime);
WriteDataToBufferPointer(buf, saveTime);
@@ -168,12 +193,6 @@ GenericSave(int file)
WriteDataToBufferPointer(buf, CWeather::NewWeatherType);
WriteDataToBufferPointer(buf, CWeather::ForcedWeatherType);
WriteDataToBufferPointer(buf, CWeather::InterpolationValue);
- WriteDataToBufferPointer(buf, CompileDateAndTime.m_nSecond);
- WriteDataToBufferPointer(buf, CompileDateAndTime.m_nMinute);
- WriteDataToBufferPointer(buf, CompileDateAndTime.m_nHour);
- WriteDataToBufferPointer(buf, CompileDateAndTime.m_nDay);
- WriteDataToBufferPointer(buf, CompileDateAndTime.m_nMonth);
- WriteDataToBufferPointer(buf, CompileDateAndTime.m_nYear);
WriteDataToBufferPointer(buf, CWeather::WeatherTypeInList);
#ifdef COMPATIBLE_SAVES
// converted to float for compatibility with original format
@@ -186,6 +205,14 @@ GenericSave(int file)
WriteDataToBufferPointer(buf, TheCamera.CarZoomIndicator);
WriteDataToBufferPointer(buf, TheCamera.PedZoomIndicator);
#endif
+ WriteDataToBufferPointer(buf, CGame::currArea);
+ WriteDataToBufferPointer(buf, CVehicle::bAllTaxisHaveNitro);
+ WriteDataToBufferPointer(buf, CPad::bInvertLook4Pad);
+ WriteDataToBufferPointer(buf, CTimeCycle::m_ExtraColour);
+ WriteDataToBufferPointer(buf, CTimeCycle::m_bExtraColourOn);
+ WriteDataToBufferPointer(buf, CTimeCycle::m_ExtraColourInter);
+ PopulateRadioStationPositionList();
+ WriteDataToBufferPointer(buf, RadioStationPosition);
assert(buf - work_buff == SIZE_OF_SIMPLEVARS);
// Save scripts, block is nested within the same block as simple vars for some reason
@@ -193,6 +220,7 @@ GenericSave(int file)
buf += 4;
postsize = buf;
CTheScripts::SaveAllScripts(buf, &size);
+ debug("ScriptSize== %i \n", size);
CopySizeAndPreparePointer(presize, buf, postsize, reserved, size);
if (!PcSaveHelper.PcClassSaveRoutine(file, work_buff, buf - work_buff))
return false;
@@ -200,25 +228,28 @@ GenericSave(int file)
totalSize = buf - work_buff;
// Save the rest
- WriteSaveDataBlock(CPools::SavePedPool);
- WriteSaveDataBlock(CGarages::Save);
- WriteSaveDataBlock(CPools::SaveVehiclePool);
- WriteSaveDataBlock(CPools::SaveObjectPool);
- WriteSaveDataBlock(ThePaths.Save);
- WriteSaveDataBlock(CCranes::Save);
- WriteSaveDataBlock(CPickups::Save);
- WriteSaveDataBlock(gPhoneInfo.Save);
- WriteSaveDataBlock(CRestart::SaveAllRestartPoints);
- WriteSaveDataBlock(CRadar::SaveAllRadarBlips);
- WriteSaveDataBlock(CTheZones::SaveAllZones);
- WriteSaveDataBlock(CGangs::SaveAllGangData);
- WriteSaveDataBlock(CTheCarGenerators::SaveAllCarGenerators);
- WriteSaveDataBlock(CParticleObject::SaveParticle);
- WriteSaveDataBlock(cAudioScriptObject::SaveAllAudioScriptObjects);
- WriteSaveDataBlock(CWorld::Players[CWorld::PlayerInFocus].SavePlayerInfo);
- WriteSaveDataBlock(CStats::SaveStats);
- WriteSaveDataBlock(CStreaming::MemoryCardSave);
- WriteSaveDataBlock(CPedType::Save);
+ WriteSaveDataBlock(CPools::SavePedPool, "PedPoolSize");
+ WriteSaveDataBlock(CGarages::Save, "GaragesSize");
+ WriteSaveDataBlock(CGameLogic::Save, "GameLogicSize");
+ WriteSaveDataBlock(CPools::SaveVehiclePool, "VehPoolSize");
+ WriteSaveDataBlock(CPools::SaveObjectPool, "ObjectPoolSize");
+ WriteSaveDataBlock(ThePaths.Save, "ThePathsSize");
+ WriteSaveDataBlock(CCranes::Save, "CranesSize");
+ WriteSaveDataBlock(CPickups::Save, "PickUpsSize");
+ WriteSaveDataBlock(gPhoneInfo.Save, "PhoneInfoSize");
+ WriteSaveDataBlock(CRestart::SaveAllRestartPoints, "RestartPointsBufferSize");
+ WriteSaveDataBlock(CRadar::SaveAllRadarBlips, "RadarBlipsBufferSize");
+ WriteSaveDataBlock(CTheZones::SaveAllZones, "AllZonesBufferSize");
+ WriteSaveDataBlock(CGangs::SaveAllGangData, "AllGangDataSize");
+ WriteSaveDataBlock(CTheCarGenerators::SaveAllCarGenerators, "AllCarGeneratorsSize");
+ WriteSaveDataBlock(CParticleObject::SaveParticle, "ParticlesSize");
+ WriteSaveDataBlock(cAudioScriptObject::SaveAllAudioScriptObjects, "AllAudioScriptObjectsSize");
+ WriteSaveDataBlock(CScriptPaths::Save, "ScriptPathsSize");
+ WriteSaveDataBlock(CWorld::Players[CWorld::PlayerInFocus].SavePlayerInfo, "PlayerInfoSize");
+ WriteSaveDataBlock(CStats::SaveStats, "StatsSize");
+ WriteSaveDataBlock(CSetPieces::Save, "SetPiecesSize");
+ WriteSaveDataBlock(CStreaming::MemoryCardSave, "StreamingSize");
+ WriteSaveDataBlock(CPedType::Save, "PedTypeSize");
// sure just write garbage data repeatedly ...
#ifndef THIS_IS_STUPID
@@ -246,7 +277,8 @@ GenericSave(int file)
return false;
}
-
+
+ CPad::FixPadsAfterSave();
return true;
}
@@ -297,13 +329,12 @@ GenericLoad()
ReadDataFromBufferPointer(buf, CWeather::OldWeatherType);
ReadDataFromBufferPointer(buf, CWeather::NewWeatherType);
ReadDataFromBufferPointer(buf, CWeather::ForcedWeatherType);
+#ifdef SECUROM
+ if (CTimer::m_FrameCounter > 72000){
+ buf += align4bytes(4);
+ }
+#endif
ReadDataFromBufferPointer(buf, CWeather::InterpolationValue);
- ReadDataFromBufferPointer(buf, CompileDateAndTime.m_nSecond);
- ReadDataFromBufferPointer(buf, CompileDateAndTime.m_nMinute);
- ReadDataFromBufferPointer(buf, CompileDateAndTime.m_nHour);
- ReadDataFromBufferPointer(buf, CompileDateAndTime.m_nDay);
- ReadDataFromBufferPointer(buf, CompileDateAndTime.m_nMonth);
- ReadDataFromBufferPointer(buf, CompileDateAndTime.m_nYear);
ReadDataFromBufferPointer(buf, CWeather::WeatherTypeInList);
#ifdef COMPATIBLE_SAVES
// converted to float for compatibility with original format
@@ -317,6 +348,17 @@ GenericLoad()
ReadDataFromBufferPointer(buf, TheCamera.CarZoomIndicator);
ReadDataFromBufferPointer(buf, TheCamera.PedZoomIndicator);
#endif
+ ReadDataFromBufferPointer(buf, CGame::currArea);
+ ReadDataFromBufferPointer(buf, CVehicle::bAllTaxisHaveNitro);
+#ifdef LOAD_INI_SETTINGS
+ buf += align4bytes(sizeof(CPad::bInvertLook4Pad));
+#else
+ ReadDataFromBufferPointer(buf, CPad::bInvertLook4Pad);
+#endif
+ ReadDataFromBufferPointer(buf, CTimeCycle::m_ExtraColour);
+ ReadDataFromBufferPointer(buf, CTimeCycle::m_bExtraColourOn);
+ ReadDataFromBufferPointer(buf, CTimeCycle::m_ExtraColourInter);
+ ReadDataFromBufferPointer(buf, RadioStationPosition);
assert(buf - work_buff == SIZE_OF_SIMPLEVARS);
#ifdef MISSION_REPLAY
WaitForSave = 0;
@@ -331,6 +373,8 @@ GenericLoad()
LoadSaveDataBlock();
ReadDataFromBlock("Loading Garages \n", CGarages::Load);
LoadSaveDataBlock();
+ ReadDataFromBlock("Loading GameLogic \n", CGameLogic::Load);
+ LoadSaveDataBlock();
ReadDataFromBlock("Loading Vehicles \n", CPools::LoadVehiclePool);
LoadSaveDataBlock();
CProjectileInfo::RemoveAllProjectiles();
@@ -360,16 +404,20 @@ GenericLoad()
LoadSaveDataBlock();
ReadDataFromBlock("Loading AudioScript Objects \n", cAudioScriptObject::LoadAllAudioScriptObjects);
LoadSaveDataBlock();
+ ReadDataFromBlock("Loading ScriptPaths \n", CScriptPaths::Load);
+ LoadSaveDataBlock();
ReadDataFromBlock("Loading Player Info \n", CWorld::Players[CWorld::PlayerInFocus].LoadPlayerInfo);
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;
@@ -424,8 +472,13 @@ CloseFile(int32 file)
void
DoGameSpecificStuffAfterSucessLoad()
{
+ CCollision::SortOutCollisionAfterLoad();
+ CStreaming::LoadSceneCollision(TheCamera.GetPosition());
+ CStreaming::LoadScene(TheCamera.GetPosition());
+ CGame::TidyUpMemory(true, false);
StillToFadeOut = true;
JustLoadedDontFadeInYet = true;
+ TheCamera.Fade(0.0f, FADE_OUT);
CTheScripts::Process();
}
@@ -572,19 +625,9 @@ RestoreForStartLoad()
ReadDataFromBufferPointer(_buf, TheCamera.GetMatrix().GetPosition().x);
ReadDataFromBufferPointer(_buf, TheCamera.GetMatrix().GetPosition().y);
ReadDataFromBufferPointer(_buf, TheCamera.GetMatrix().GetPosition().z);
- ISLAND_LOADING_IS(LOW)
- {
- CStreaming::RemoveUnusedBigBuildings(CGame::currLevel);
- CStreaming::RemoveUnusedBuildings(CGame::currLevel);
- }
- CCollision::SortOutCollisionAfterLoad();
- ISLAND_LOADING_IS(LOW)
- {
- CStreaming::RequestBigBuildings(CGame::currLevel);
- CStreaming::LoadAllRequestedModels(false);
- CStreaming::HaveAllBigBuildingsLoaded(CGame::currLevel);
- CGame::TidyUpMemory(true, false);
- }
+ CStreaming::RemoveUnusedBigBuildings(CGame::currLevel);
+ CStreaming::RemoveUnusedBuildings(CGame::currLevel);
+
if (CloseFile(file)) {
return true;
} else {
@@ -650,6 +693,7 @@ enum
SAVE_TYPE_64_BIT = 2,
SAVE_TYPE_MSVC = 4,
SAVE_TYPE_GCC = 8,
+ SAVE_TYPE_STEAM = 16,
};
uint8
@@ -664,6 +708,14 @@ GetSaveType(char *savename)
uint8 *buf = work_buff;
CFileMgr::Read(file, (const char *)work_buff, size); // simple vars + scripts
+ buf += 0x40 + sizeof(int32) + sizeof(int32) + sizeof(float) * 3;
+
+ int8 steam_byte;
+ ReadDataFromBufferPointer(buf, steam_byte);
+
+ if (steam_byte == -3)
+ save_type |= SAVE_TYPE_STEAM;
+
LoadSaveDataBlockNoCheck(buf, file, size); // ped pool
LoadSaveDataBlockNoCheck(buf, file, size); // garages
@@ -672,6 +724,7 @@ GetSaveType(char *savename)
// store for later after we know how much data we need to skip
ReadDataFromBufferPointerWithSize(buf, work_buff2, size);
+ LoadSaveDataBlockNoCheck(buf, file, size); // game logic
LoadSaveDataBlockNoCheck(buf, file, size); // vehicle pool
LoadSaveDataBlockNoCheck(buf, file, size); // object pool
LoadSaveDataBlockNoCheck(buf, file, size); // paths
@@ -682,7 +735,7 @@ GetSaveType(char *savename)
ReadDataFromBufferPointer(buf, size);
- if (size == 1032)
+ if (size == 1000)
save_type |= SAVE_TYPE_32_BIT;
else if (size == 1160)
save_type |= SAVE_TYPE_64_BIT;
@@ -691,22 +744,21 @@ GetSaveType(char *savename)
buf = work_buff2;
- buf += 760; // skip everything before the first garage
- buf += save_type & SAVE_TYPE_32_BIT ? 28 : 40; // skip first garage up to m_fX1
+ buf += 1964; // skip everything before the first garage
+ buf += save_type & SAVE_TYPE_32_BIT ? 28 : 40; // skip first garage up to m_vecCorner1
- // now the values we want to verify
- float fX1, fX2, fY1, fY2, fZ1, fZ2;
+ CVector2D vecCorner1;
+ float fInfZ, fSupZ;
- ReadBuf(buf, fX1);
- ReadBuf(buf, fX2);
- ReadBuf(buf, fY1);
- ReadBuf(buf, fY2);
- ReadBuf(buf, fZ1);
- ReadBuf(buf, fZ2);
+ ReadBuf(buf, vecCorner1);
+ ReadBuf(buf, fInfZ);
+ SkipBuf(buf, sizeof(CVector2D));
+ SkipBuf(buf, sizeof(CVector2D));
+ ReadBuf(buf, fSupZ);
- if (fX1 == CRUSHER_GARAGE_X1 && fX2 == CRUSHER_GARAGE_X2 &&
- fY1 == CRUSHER_GARAGE_Y1 && fY2 == CRUSHER_GARAGE_Y2 &&
- fZ1 == CRUSHER_GARAGE_Z1 && fZ2 == CRUSHER_GARAGE_Z2)
+ // SET_GARAGE -914.129028 -1263.540039 10.706000 -907.137024 -1246.625977 -906.299988 -1266.900024 14.421000
+ if (vecCorner1.x == -914.129028f && vecCorner1.y == -1263.540039f &&
+ fInfZ == 10.706000f && fSupZ == 14.421000f)
save_type |= SAVE_TYPE_MSVC;
else
save_type |= SAVE_TYPE_GCC;
@@ -715,25 +767,48 @@ GetSaveType(char *savename)
}
static void
+FixSimpleVarsAndScripts(uint8 save_type, uint8 *buf, uint8 *buf2, uint32 *size)
+{
+ uint8 *buf_start = buf;
+ uint8 *buf2_start = buf2;
+ uint32 read = *size;
+ uint32 written = *size - (sizeof(int8) + 3);
+
+ uint32 pre_steam = 0x40 + sizeof(int32) + sizeof(int32) + sizeof(float) * 3;
+ uint32 post_steam = *size - (sizeof(int8) + 3) - pre_steam;
+
+ CopyBuf(buf, buf2, pre_steam);
+ SkipBuf(buf, sizeof(int8) + 3);
+ CopyBuf(buf, buf2, post_steam);
+
+ *size = 0;
+
+ assert(buf - buf_start == read);
+ assert(buf2 - buf2_start == written);
+
+ *size = written;
+}
+
+static void
FixGarages(uint8 save_type, uint8 *buf, uint8 *buf2, uint32 *size)
{
- // hardcoded: 5484
- // x86 msvc: 5240
- // x86 gcc: 5040
- // amd64 msvc: 5880
- // amd64 gcc: 5808
+ // hardcoded: 7876
+ // x86 msvc: 7340
+ // x86 gcc: 7020
+ // amd64 msvc: 7852
+ // amd64 gcc: 7660
uint8 *buf_start = buf;
uint8 *buf2_start = buf2;
uint32 read;
- uint32 written = 5240;
+ uint32 written = 7340;
if (save_type & SAVE_TYPE_32_BIT && save_type & SAVE_TYPE_GCC)
- read = 5040;
+ read = 7020;
else if (save_type & SAVE_TYPE_64_BIT && save_type & SAVE_TYPE_GCC)
- read = 5808;
+ read = 7660;
else
- read = 5880;
+ read = 7852;
uint32 ptrsize = save_type & SAVE_TYPE_32_BIT ? 4 : 8;
@@ -745,62 +820,45 @@ FixGarages(uint8 save_type, uint8 *buf, uint8 *buf2, uint32 *size)
{
for (int32 i = 0; i < NUM_GARAGE_STORED_CARS; i++)
{
-#define FixStoredCar(buf, buf2) \
-do { \
- CopyBuf(buf, buf2, 4 + sizeof(CVector) + sizeof(CVector)); \
- uint8 nFlags8; \
- ReadBuf(buf, nFlags8); \
- int32 nFlags32 = nFlags8; \
- WriteBuf(buf2, nFlags32); \
- CopyBuf(buf, buf2, 1 * 6); \
- SkipBuf(buf, 1); \
- SkipBuf(buf2, 2); \
-} while(0)
-
- FixStoredCar(buf, buf2);
- FixStoredCar(buf, buf2);
- FixStoredCar(buf, buf2);
-
-#undef FixStoredCar
+ for (int32 j = 0; j < TOTAL_HIDEOUT_GARAGES; j++)
+ {
+ CopyBuf(buf, buf2, 4 + sizeof(CVector) + sizeof(CVector));
+ uint8 nFlags8;
+ ReadBuf(buf, nFlags8);
+ int32 nFlags32 = nFlags8;
+ WriteBuf(buf2, nFlags32);
+ CopyBuf(buf, buf2, 1 * 6);
+ SkipBuf(buf, 1);
+ SkipBuf(buf2, 2);
+ }
}
}
else
{
- CopyBuf(buf, buf2, sizeof(CStoredCar) * NUM_GARAGE_STORED_CARS);
- CopyBuf(buf, buf2, sizeof(CStoredCar) * NUM_GARAGE_STORED_CARS);
- CopyBuf(buf, buf2, sizeof(CStoredCar) * NUM_GARAGE_STORED_CARS);
+ CopyBuf(buf, buf2, sizeof(CStoredCar) * NUM_GARAGE_STORED_CARS * TOTAL_HIDEOUT_GARAGES);
}
for (int32 i = 0; i < NUM_GARAGES; i++)
{
- // skip the last 5 garages in 64bit builds without FIX_GARAGE_SIZE since they weren't actually saved and are unused
- if (save_type & SAVE_TYPE_64_BIT && *size == 5484 && i >= NUM_GARAGES - 5)
- {
- SkipBuf(buf, 160); // sizeof(CGarage) on x64
- SkipBuf(buf2, 140); // sizeof(CGarage) on x86
- }
+ CopyBuf(buf, buf2, 1 * 7);
+ SkipBoth(buf, buf2, 1);
+ CopyBuf(buf, buf2, 4);
+ SkipBuf(buf, ptrsize - 4); // write 4 bytes padding if 8 byte pointer, if not, write 0
+ SkipBuf(buf, ptrsize * 2);
+ SkipBuf(buf2, 4 * 2);
+ CopyBuf(buf, buf2, 1 * 7);
+ SkipBoth(buf, buf2, 1);
+ CopyBuf(buf, buf2, sizeof(CVector2D) * 3 + 4 * 17 + 1);
+ SkipBoth(buf, buf2, 3);
+ SkipBuf(buf, ptrsize);
+ SkipBuf(buf2, 4);
+
+ if (save_type & SAVE_TYPE_GCC)
+ SkipBuf(buf, save_type & SAVE_TYPE_64_BIT ? 36 + 4 : 36); // sizeof(CStoredCar) on gcc 64/32 before fix
else
- {
- CopyBuf(buf, buf2, 1 * 6);
- SkipBoth(buf, buf2, 2);
- CopyBuf(buf, buf2, 4);
- SkipBuf(buf, ptrsize - 4); // write 4 bytes padding if 8 byte pointer, if not, write 0
- SkipBuf(buf, ptrsize * 2);
- SkipBuf(buf2, 4 * 2);
- CopyBuf(buf, buf2, 1 * 7);
- SkipBoth(buf, buf2, 1);
- CopyBuf(buf, buf2, 4 * 15 + 1);
- SkipBoth(buf, buf2, 3);
- SkipBuf(buf, ptrsize * 2);
- SkipBuf(buf2, 4 * 2);
-
- if (save_type & SAVE_TYPE_GCC)
- SkipBuf(buf, save_type & SAVE_TYPE_64_BIT ? 36 + 4 : 36); // sizeof(CStoredCar) on gcc 64/32 before fix
- else
- SkipBuf(buf, sizeof(CStoredCar));
-
- SkipBuf(buf2, sizeof(CStoredCar));
- }
+ SkipBuf(buf, sizeof(CStoredCar));
+
+ SkipBuf(buf2, sizeof(CStoredCar));
}
*size = 0;
@@ -808,11 +866,7 @@ do { \
assert(buf - buf_start == read);
assert(buf2 - buf2_start == written);
-#ifdef FIX_GARAGE_SIZE
- *size = (6 * sizeof(uint32) + TOTAL_COLLECTCARS_GARAGES * sizeof(*CGarages::CarTypesCollected) + sizeof(uint32) + 3 * NUM_GARAGE_STORED_CARS * sizeof(CStoredCar) + NUM_GARAGES * sizeof(CGarage));
-#else
- *size = 5484;
-#endif
+ *size = 7876;
}
static void
@@ -821,7 +875,7 @@ FixCranes(uint8 save_type, uint8 *buf, uint8 *buf2, uint32 *size)
uint8 *buf_start = buf;
uint8 *buf2_start = buf2;
uint32 read = 2 * sizeof(uint32) + 0x480; // sizeof(aCranes)
- uint32 written = 2 * sizeof(uint32) + 0x400; // see CRANES_SAVE_SIZE
+ uint32 written = 2 * sizeof(uint32) + 0x3E0; // see CRANES_SAVE_SIZE
CopyBuf(buf, buf2, 4 + 4);
@@ -829,7 +883,8 @@ FixCranes(uint8 save_type, uint8 *buf, uint8 *buf2, uint32 *size)
{
CopyPtr(buf, buf2);
CopyPtr(buf, buf2);
- CopyBuf(buf, buf2, 15 * 4 + sizeof(CVector) * 3 + sizeof(CVector2D));
+ CopyBuf(buf, buf2, 14 * 4 + sizeof(CVector) * 3 + sizeof(CVector2D));
+ SkipBuf(buf, 4);
CopyPtr(buf, buf2);
CopyBuf(buf, buf2, 4 + 7 * 1);
SkipBuf(buf, 5);
@@ -849,16 +904,17 @@ FixPickups(uint8 save_type, uint8 *buf, uint8 *buf2, uint32 *size)
{
uint8 *buf_start = buf;
uint8 *buf2_start = buf2;
- uint32 read = 0x3480 + sizeof(uint16) + sizeof(uint16) + sizeof(int32) * NUMCOLLECTEDPICKUPS; // sizeof(aPickUps)
- uint32 written = 0x24C0 + sizeof(uint16) + sizeof(uint16) + sizeof(int32) * NUMCOLLECTEDPICKUPS; // see PICKUPS_SAVE_SIZE
+ uint32 read = 0x5400 + sizeof(uint16) + sizeof(uint16) + sizeof(int32) * NUMCOLLECTEDPICKUPS; // sizeof(aPickUps)
+ uint32 written = 0x4440 + sizeof(uint16) + sizeof(uint16) + sizeof(int32) * NUMCOLLECTEDPICKUPS; // see PICKUPS_SAVE_SIZE
for (int32 i = 0; i < NUMPICKUPS; i++)
{
- CopyBuf(buf, buf2, 1 + 1 + 2);
- SkipBuf(buf, 4);
+ CopyBuf(buf, buf2, sizeof(CVector) + 4);
CopyPtr(buf, buf2);
- CopyBuf(buf, buf2, 4 + 2 + 2 + sizeof(CVector));
- SkipBuf(buf, 4);
+ CopyPtr(buf, buf2);
+ CopyBuf(buf, buf2, 4 * 2 + 2 * 3 + 8 + 1 * 3);
+ SkipBuf(buf, 7);
+ SkipBuf(buf2, 3);
}
CopyBuf(buf, buf2, 2);
@@ -910,54 +966,6 @@ FixPhoneInfo(uint8 save_type, uint8 *buf, uint8 *buf2, uint32 *size)
}
static void
-FixZones(uint8 save_type, uint8 *buf, uint8 *buf2, uint32 *size)
-{
- uint8 *buf_start = buf;
- uint8 *buf2_start = buf2;
- uint32 read = 11300; // see SaveAllZones
- uint32 written = 10100; // see SaveAllZones
-
- CopyBuf(buf, buf2, 1 * 4);
-
- SkipBuf(buf, 4);
- uint32 hdr_size = 10100 - (1 * 4 + 4); // see SaveAllZones
- WriteBuf(buf2, hdr_size);
-
- CopyBuf(buf, buf2, 4 * 2 + 2);
- SkipBoth(buf, buf2, 2);
-
-#define FixOneZone(buf, buf2) \
-do { \
- CopyBuf(buf, buf2, 8 + 8 * 4 + 2 * 2); \
- SkipBuf(buf, 4); \
- CopyPtr(buf, buf2); \
- CopyPtr(buf, buf2); \
- CopyPtr(buf, buf2); \
-} while(0)
-
- for (int32 i = 0; i < NUMZONES; i++)
- FixOneZone(buf, buf2);
-
- CopyBuf(buf, buf2, sizeof(CZoneInfo) * NUMZONES * 2);
- CopyBuf(buf, buf2, 2 + 2);
-
- for (int32 i = 0; i < NUMMAPZONES; i++)
- FixOneZone(buf, buf2);
-
- CopyBuf(buf, buf2, 2 * NUMAUDIOZONES);
- CopyBuf(buf, buf2, 2 + 2);
-
-#undef FixOneZone
-
- *size = 0;
-
- assert(buf - buf_start == read);
- assert(buf2 - buf2_start == written);
-
- *size = written;
-}
-
-static void
FixParticles(uint8 save_type, uint8 *buf, uint8 *buf2, uint32 *size)
{
uint8 *buf_start = buf;
@@ -967,13 +975,12 @@ FixParticles(uint8 save_type, uint8 *buf, uint8 *buf2, uint32 *size)
ReadBuf(buf, numObjects);
WriteBuf(buf2, numObjects);
- uint32 read = 0xA0 * (numObjects + 1) + 4; // sizeof(CParticleObject)
- uint32 written = 0x88 * (numObjects + 1) + 4; // see PARTICLE_OBJECT_SIZEOF
+ uint32 read = 0x98 * (numObjects + 1) + 4; // sizeof(CParticleObject)
+ uint32 written = 0x84 * (numObjects + 1) + 4; // see PARTICLE_OBJECT_SIZEOF
for (int32 i = 0; i < numObjects; i++)
{
// CPlaceable
- SkipPtr(buf, buf2);
CopyBuf(buf, buf2, 4 * 4 * 4);
SkipPtr(buf, buf2);
CopyBuf(buf, buf2, 1);
@@ -990,8 +997,47 @@ FixParticles(uint8 save_type, uint8 *buf, uint8 *buf2, uint32 *size)
SkipBoth(buf, buf2, 2);
}
- SkipBuf(buf, 0xA0); // sizeof(CParticleObject)
- SkipBuf(buf2, 0x88); // see PARTICLE_OBJECT_SIZEOF
+ SkipBuf(buf, 0x98); // sizeof(CParticleObject)
+ SkipBuf(buf2, 0x84); // see PARTICLE_OBJECT_SIZEOF
+
+ *size = 0;
+
+ assert(buf - buf_start == read);
+ assert(buf2 - buf2_start == written);
+
+ *size = written;
+}
+
+static void
+FixScriptPaths(uint8 save_type, uint8 *buf, uint8 *buf2, uint32 *size)
+{
+ uint8 *buf_start = buf;
+ uint8 *buf2_start = buf2;
+ uint32 read = 0x108; // sizeof(CScriptPath) * 3
+ uint32 written = 0x9C; // see SCRIPTPATHS_SAVE_SIZE
+
+ for (int32 i = 0; i < 3; i++)
+ {
+ int32 numNodes;
+ ReadBuf(buf, numNodes);
+ WriteBuf(buf2, numNodes);
+ SkipBuf(buf, 4);
+ SkipPtr(buf, buf2);
+ CopyBuf(buf, buf2, 4 * 5);
+ SkipBuf(buf, 4);
+
+ for (int32 i = 0; i < 6; i++)
+ {
+ CopyPtr(buf, buf2);
+ }
+
+ for (int32 i = 0; i < numNodes; i++)
+ {
+ CopyBuf(buf, buf2, sizeof(CPlaneNode));
+ read += sizeof(CPlaneNode);
+ written += sizeof(CPlaneNode);
+ }
+ }
*size = 0;
@@ -1004,7 +1050,7 @@ FixParticles(uint8 save_type, uint8 *buf, uint8 *buf2, uint32 *size)
bool
FixSave(int32 slot, uint8 save_type)
{
- if (save_type & SAVE_TYPE_32_BIT && save_type & SAVE_TYPE_MSVC)
+ if (save_type & SAVE_TYPE_32_BIT && save_type & SAVE_TYPE_MSVC && !(save_type & SAVE_TYPE_STEAM))
return true;
bool success = false;
@@ -1035,13 +1081,27 @@ FixSave(int32 slot, uint8 save_type)
buf = work_buff;
CFileMgr::Read(file_in, (const char *)work_buff, size); // simple vars + scripts
- WriteSavaDataBlockNoFunc(buf, file_out, size);
+ if (save_type & SAVE_TYPE_STEAM && save_type & SAVE_TYPE_MSVC && save_type & SAVE_TYPE_32_BIT) {
+ memset(work_buff2, 0, sizeof(work_buff2));
+ buf2 = work_buff2;
+ FixSimpleVarsAndScripts(save_type, buf, buf2, &size);
+ if (!PcSaveHelper.PcClassSaveRoutine(file_out, work_buff2, size))
+ goto fail;
+ totalSize += size;
+ } else
+ WriteSavaDataBlockNoFunc(buf, file_out, size);
LoadSaveDataBlockNoCheck(buf, file_in, size); // ped pool
WriteSavaDataBlockNoFunc(buf, file_out, size);
LoadSaveDataBlockNoCheck(buf, file_in, size); // garages
- FixSaveDataBlock(FixGarages, file_out, size); // garages need to be fixed in either case
+ if (!(save_type & SAVE_TYPE_STEAM && save_type & SAVE_TYPE_MSVC && save_type & SAVE_TYPE_32_BIT))
+ FixSaveDataBlock(FixGarages, file_out, size);
+ else
+ WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+ LoadSaveDataBlockNoCheck(buf, file_in, size); // game logic
+ WriteSavaDataBlockNoFunc(buf, file_out, size);
LoadSaveDataBlockNoCheck(buf, file_in, size); // vehicle pool
WriteSavaDataBlockNoFunc(buf, file_out, size);
@@ -1077,10 +1137,7 @@ FixSave(int32 slot, uint8 save_type)
WriteSavaDataBlockNoFunc(buf, file_out, size);
LoadSaveDataBlockNoCheck(buf, file_in, size); // zones
- if (save_type & SAVE_TYPE_64_BIT)
- FixSaveDataBlock(FixZones, file_out, size);
- else
- WriteSavaDataBlockNoFunc(buf, file_out, size);
+ WriteSavaDataBlockNoFunc(buf, file_out, size);
LoadSaveDataBlockNoCheck(buf, file_in, size); // gang data
WriteSavaDataBlockNoFunc(buf, file_out, size);
@@ -1097,12 +1154,21 @@ FixSave(int32 slot, uint8 save_type)
LoadSaveDataBlockNoCheck(buf, file_in, size); // audio script objects
WriteSavaDataBlockNoFunc(buf, file_out, size);
+ LoadSaveDataBlockNoCheck(buf, file_in, size); // script paths
+ if (save_type & SAVE_TYPE_64_BIT)
+ FixSaveDataBlock(FixScriptPaths, file_out, size);
+ else
+ WriteSavaDataBlockNoFunc(buf, file_out, size);
+
LoadSaveDataBlockNoCheck(buf, file_in, size); // player info
WriteSavaDataBlockNoFunc(buf, file_out, size);
LoadSaveDataBlockNoCheck(buf, file_in, size); // stats
WriteSavaDataBlockNoFunc(buf, file_out, size);
+ LoadSaveDataBlockNoCheck(buf, file_in, size); // set pieces
+ WriteSavaDataBlockNoFunc(buf, file_out, size);
+
LoadSaveDataBlockNoCheck(buf, file_in, size); // streaming
WriteSavaDataBlockNoFunc(buf, file_out, size);
@@ -1154,15 +1220,20 @@ void DisplaySaveResult(int unk, char* name)
bool SaveGameForPause(int type)
{
- if (AllowMissionReplay != MISSION_RETRY_STAGE_NORMAL)
+ if (AllowMissionReplay != MISSION_RETRY_STAGE_NORMAL && AllowMissionReplay != MISSION_RETRY_STAGE_WAIT_FOR_TIMER_AFTER_RESTART) {
+ debug("SaveGameForPause failed during AllowMissionReplay %d", AllowMissionReplay);
return false;
- if (type != SAVE_TYPE_QUICKSAVE_FOR_MISSION_REPLAY && WaitForSave > CTimer::GetTimeInMilliseconds())
+ }
+ if (type != SAVE_TYPE_QUICKSAVE_FOR_MISSION_REPLAY && WaitForSave > CTimer::GetTimeInMilliseconds()) {
+ debug("SaveGameForPause failed WaitForSave");
return false;
+ }
WaitForSave = 0;
- if (gGameState != GS_PLAYING_GAME || CTheScripts::IsPlayerOnAMission() || CStats::LastMissionPassedName[0] == '\0') {
+ if (gGameState != GS_PLAYING_GAME || (CTheScripts::bAlreadyRunningAMissionScript && type != SAVE_TYPE_QUICKSAVE_FOR_SCRIPT_ON_A_MISSION)) {
DisplaySaveResult(3, CStats::LastMissionPassedName);
return false;
}
+ debug("SaveGameForPause ******************************** %s doSave %d", CStats::LastMissionPassedName, !CTheScripts::bAlreadyRunningAMissionScript);
IsQuickSave = type;
MissionStartTime = 0;
int res = PcSaveHelper.SaveSlot(PAUSE_SAVE_SLOT);
diff --git a/src/save/GenericGameStorage.h b/src/save/GenericGameStorage.h
index 6a5b04fa..bebf426a 100644
--- a/src/save/GenericGameStorage.h
+++ b/src/save/GenericGameStorage.h
@@ -5,6 +5,9 @@
#define SLOT_COUNT (8)
+void InitRadioStationPositionList();
+int32 GetSavedRadioStationPosition(int32 station);
+void PopulateRadioStationPositionList();
bool GenericSave(int file);
bool GenericLoad();
bool ReadInSizeofSaveFileBuffer(int32 &file, uint32 &size);
@@ -27,8 +30,6 @@ uint8 GetSaveType(char *savename);
bool FixSave(int32 slot, uint8 save_type);
#endif
-extern class CDate CompileDateAndTime;
-
extern char DefaultPCSaveFileName[260];
extern char ValidSaveName[260];
extern char LoadFileName[256];
@@ -36,7 +37,7 @@ extern wchar SlotFileName[SLOT_COUNT][260];
extern wchar SlotSaveDate[SLOT_COUNT][70];
extern int CheckSum;
extern enum eLevelName m_LevelToLoad;
-extern int Slots[SLOT_COUNT+1];
+extern int Slots[SLOT_COUNT];
extern bool b_FoundRecentSavedGameWantToLoad;
extern bool JustLoadedDontFadeInYet;
@@ -57,7 +58,9 @@ enum {
SAVE_TYPE_NORMAL,
SAVE_TYPE_QUICKSAVE,
SAVE_TYPE_2,
- SAVE_TYPE_QUICKSAVE_FOR_MISSION_REPLAY
+ SAVE_TYPE_QUICKSAVE_FOR_MISSION_REPLAY,
+ SAVE_TYPE_QUICKSAVE_FOR_SCRIPT,
+ SAVE_TYPE_QUICKSAVE_FOR_SCRIPT_ON_A_MISSION
};
#endif
diff --git a/src/save/PCSave.cpp b/src/save/PCSave.cpp
index 0c228a6d..a33e9d90 100644
--- a/src/save/PCSave.cpp
+++ b/src/save/PCSave.cpp
@@ -19,7 +19,7 @@ C_PcSave PcSaveHelper;
void
C_PcSave::SetSaveDirectory(const char *path)
{
- sprintf(DefaultPCSaveFileName, "%s\\%s", path, "GTA3sf");
+ sprintf(DefaultPCSaveFileName, "%s\\%s", path, "GTAVCsf");
}
bool
@@ -38,7 +38,7 @@ C_PcSave::DeleteSlot(int32 slot)
return true;
}
-bool
+int8
C_PcSave::SaveSlot(int32 slot)
{
MakeValidSaveName(slot);
@@ -53,10 +53,10 @@ C_PcSave::SaveSlot(int32 slot)
if (GenericSave(file)) {
if (!!CFileMgr::CloseFile(file))
nErrorCode = SAVESTATUS_ERR_SAVE_CLOSE;
- return true;
+ return 0;
}
- return false;
+ return 2;
}
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_SAVE_CREATE;
return false;
@@ -93,7 +93,7 @@ void
C_PcSave::PopulateSlotInfo()
{
for (int i = 0; i < SLOT_COUNT; i++) {
- Slots[i + 1] = SLOT_EMPTY;
+ Slots[i] = SLOT_EMPTY;
SlotFileName[i][0] = '\0';
SlotSaveDate[i][0] = '\0';
}
@@ -113,19 +113,19 @@ C_PcSave::PopulateSlotInfo()
if (file != 0) {
CFileMgr::Read(file, (char*)&header, sizeof(header));
if (strncmp((char*)&header, TopLineEmptyFile, sizeof(TopLineEmptyFile)-1) != 0) {
- Slots[i + 1] = SLOT_OK;
+ Slots[i] = SLOT_OK;
memcpy(SlotFileName[i], &header.FileName, sizeof(header.FileName));
SlotFileName[i][24] = '\0';
}
CFileMgr::CloseFile(file);
}
- if (Slots[i + 1] == SLOT_OK) {
+ if (Slots[i] == SLOT_OK) {
if (CheckDataNotCorrupt(i, savename)) {
#ifdef FIX_INCOMPATIBLE_SAVES
if (!FixSave(i, GetSaveType(savename))) {
CMessages::InsertNumberInString(TheText.Get("FEC_SLC"), i + 1, -1, -1, -1, -1, -1, SlotFileName[i]);
- Slots[i + 1] = SLOT_CORRUPTED;
+ Slots[i] = SLOT_CORRUPTED;
continue;
}
#endif
@@ -159,7 +159,7 @@ C_PcSave::PopulateSlotInfo()
} else {
CMessages::InsertNumberInString(TheText.Get("FEC_SLC"), i + 1, -1, -1, -1, -1, -1, SlotFileName[i]);
- Slots[i + 1] = SLOT_CORRUPTED;
+ Slots[i] = SLOT_CORRUPTED;
}
}
}
diff --git a/src/save/PCSave.h b/src/save/PCSave.h
index 83471b5d..2a29fa95 100644
--- a/src/save/PCSave.h
+++ b/src/save/PCSave.h
@@ -32,7 +32,7 @@ public:
C_PcSave() : nErrorCode(SAVESTATUS_SUCCESSFUL) {}
void PopulateSlotInfo();
bool DeleteSlot(int32 slot);
- bool SaveSlot(int32 slot);
+ int8 SaveSlot(int32 slot);
bool PcClassSaveRoutine(int32 file, uint8 *data, uint32 size);
static void SetSaveDirectory(const char *path);
};
diff --git a/src/save/SaveBuf.h b/src/save/SaveBuf.h
index aad2e1a8..d0817e9a 100644
--- a/src/save/SaveBuf.h
+++ b/src/save/SaveBuf.h
@@ -18,24 +18,52 @@ SkipSaveBuf(uint8 *&buf, int32 skip)
#endif
}
-template <typename T>
inline void
-ReadSaveBuf(T* out, uint8 *&buf)
+SkipSaveBuf(uint8*& buf, uint32 &length, int32 skip)
+{
+ buf += skip;
+ length += skip;
+#ifdef VALIDATE_SAVE_SIZE
+ _saveBufCount += skip;
+#endif
+}
+
+template<typename T>
+inline void
+ReadSaveBuf(T *out, uint8 *&buf)
{
*out = *(T *)buf;
SkipSaveBuf(buf, sizeof(T));
}
-template <typename T>
+template<typename T>
+inline void
+ReadSaveBuf(T *out, uint8 *&buf, uint32 &length)
+{
+ *out = *(T *)buf;
+ SkipSaveBuf(buf, length, sizeof(T));
+}
+
+template<typename T>
inline T *
WriteSaveBuf(uint8 *&buf, const T &value)
{
- T *p = (T *)buf;
+ T *p = (T*)buf;
*p = value;
SkipSaveBuf(buf, sizeof(T));
return p;
}
+template<typename T>
+inline T *
+WriteSaveBuf(uint8 *&buf, uint32 &length, const T &value)
+{
+ T *p = (T*)buf;
+ *p = value;
+ SkipSaveBuf(buf, length, sizeof(T));
+ return p;
+}
+
#ifdef COMPATIBLE_SAVES
inline void
ZeroSaveBuf(uint8 *&buf, uint32 length)
@@ -45,14 +73,21 @@ ZeroSaveBuf(uint8 *&buf, uint32 length)
}
#endif
-#define SAVE_HEADER_SIZE (4 * sizeof(char) + sizeof(uint32))
+#define SAVE_HEADER_SIZE (4*sizeof(char)+sizeof(uint32))
-#define WriteSaveHeader(buf, a, b, c, d, size) \
- WriteSaveBuf(buf, a); \
- WriteSaveBuf(buf, b); \
- WriteSaveBuf(buf, c); \
- WriteSaveBuf(buf, d); \
- WriteSaveBuf(buf, (uint32)(size));
+#define WriteSaveHeader(buf,a,b,c,d,size) \
+ WriteSaveBuf(buf, a);\
+ WriteSaveBuf(buf, b);\
+ WriteSaveBuf(buf, c);\
+ WriteSaveBuf(buf, d);\
+ WriteSaveBuf<uint32>(buf, size);
+
+#define WriteSaveHeaderWithLength(buf,len,a,b,c,d,size) \
+ WriteSaveBuf(buf, len, a);\
+ WriteSaveBuf(buf, len, b);\
+ WriteSaveBuf(buf, len, c);\
+ WriteSaveBuf(buf, len, d);\
+ WriteSaveBuf(buf, len, (uint32)(size));
#ifdef VALIDATE_SAVE_SIZE
#define CheckSaveHeader(buf, a, b, c, d, size) do { \
@@ -68,6 +103,21 @@ ZeroSaveBuf(uint8 *&buf, uint32 length)
ReadSaveBuf(&_size, buf);\
assert(_size == size);\
} while(0)
+
+#define CheckSaveHeaderWithLength(buf,len,a,b,c,d,size) do { \
+ char _c; uint32 _size;\
+ ReadSaveBuf(&_c, buf, len);\
+ assert(_c == a);\
+ ReadSaveBuf(&_c, buf, len);\
+ assert(_c == b);\
+ ReadSaveBuf(&_c, buf, len);\
+ assert(_c == c);\
+ ReadSaveBuf(&_c, buf, len);\
+ assert(_c == d);\
+ ReadSaveBuf(&_size, buf, len);\
+ assert(_size == size);\
+ } while(0)
#else
#define CheckSaveHeader(buf, a, b, c, d, size) SkipSaveBuf(buf, 8);
-#endif \ No newline at end of file
+#define CheckSaveHeaderWithLength(buf, len, a, b, c, d, size) SkipSaveBuf(buf, 8);
+#endif
diff --git a/src/skel/crossplatform.cpp b/src/skel/crossplatform.cpp
index 577983b6..58ab7920 100644
--- a/src/skel/crossplatform.cpp
+++ b/src/skel/crossplatform.cpp
@@ -32,15 +32,15 @@ HANDLE FindFirstFile(const char* pathname, WIN32_FIND_DATA* firstfile) {
char *folder = strtok(pathCopy, "*");
char *extension = strtok(NULL, "*");
- // because I remember like strtok might not return NULL for last delimiter
- if (extension && extension - folder == strlen(pathname))
- extension = nil;
+ // because I remember like strtok might not return NULL for last delimiter
+ if (extension && extension - folder == strlen(pathname))
+ extension = nil;
// Case-sensitivity and backslashes...
- // Will be freed at the bottom
- char *realFolder = casepath(folder);
+ // Will be freed at the bottom
+ char *realFolder = casepath(folder);
if (realFolder) {
- folder = realFolder;
+ folder = realFolder;
}
strncpy(firstfile->folder, folder, sizeof(firstfile->folder));
@@ -50,8 +50,8 @@ HANDLE FindFirstFile(const char* pathname, WIN32_FIND_DATA* firstfile) {
else
firstfile->extension[0] = '\0';
- if (realFolder)
- free(realFolder);
+ if (realFolder)
+ free(realFolder);
HANDLE d;
if ((d = (HANDLE)opendir(firstfile->folder)) == NULL || !FindNextFile(d, firstfile))
@@ -198,6 +198,20 @@ char* casepath(char const* path, bool checkPathFirst)
size_t rl = 0;
DIR* d;
+ char* c;
+
+ #if defined(__SWITCH__) || defined(PSP2)
+ if( (c = strstr(p, ":/")) != NULL) // scheme used by some environments, eg. switch, vita
+ {
+ size_t deviceNameOffset = c - p + 3;
+ char* deviceNamePath = (char*)alloca(deviceNameOffset + 1);
+ strlcpy(deviceNamePath, p, deviceNameOffset);
+ deviceNamePath[deviceNameOffset] = 0;
+ d = opendir(deviceNamePath);
+ p = c + 1;
+ }
+ else
+ #endif
if (p[0] == '/' || p[0] == '\\')
{
d = opendir("/");
@@ -212,7 +226,7 @@ char* casepath(char const* path, bool checkPathFirst)
bool cantProceed = false; // just convert slashes in what's left in string, don't correct case of letters(because we can't)
bool mayBeTrailingSlash = false;
- char* c;
+
while (c = strsep(&p, "/\\"))
{
// May be trailing slash(allow), slash at the start(avoid), or multiple slashes(avoid)
@@ -279,3 +293,147 @@ char* casepath(char const* path, bool checkPathFirst)
return out;
}
#endif
+
+#if !defined(_MSC_VER) && !defined(__CWCC__)
+char *strdate(char *buf) {
+ time_t timestamp;
+ time(&timestamp);
+ tm *localTm = localtime(&timestamp);
+ strftime(buf, 10, "%m/%d/%y", localTm);
+ return buf;
+}
+
+char *_strdate(char *buf) {
+ return strdate(buf);
+}
+#endif
+
+#ifdef __SWITCH__
+/* Taken from glibc */
+char *realpath(const char *name, char *resolved)
+{
+ char *rpath, *dest = NULL;
+ const char *start, *end, *rpath_limit;
+ long int path_max;
+
+ /* As per Single Unix Specification V2 we must return an error if
+ either parameter is a null pointer. We extend this to allow
+ the RESOLVED parameter to be NULL in case the we are expected to
+ allocate the room for the return value. */
+ if (!name)
+ return NULL;
+
+ /* As per Single Unix Specification V2 we must return an error if
+ the name argument points to an empty string. */
+ if (name[0] == '\0')
+ return NULL;
+
+#ifdef PATH_MAX
+ path_max = PATH_MAX;
+#else
+ path_max = pathconf(name, _PC_PATH_MAX);
+ if (path_max <= 0)
+ path_max = 1024;
+#endif
+
+ if (!resolved)
+ {
+ rpath = (char*)malloc(path_max);
+ if (!rpath)
+ return NULL;
+ }
+ else
+ rpath = resolved;
+ rpath_limit = rpath + path_max;
+
+ if (name[0] != '/')
+ {
+ if (!getcwd(rpath, path_max))
+ {
+ rpath[0] = '\0';
+ goto error;
+ }
+ dest = (char*)memchr(rpath, '\0', path_max);
+ }
+ else
+ {
+ rpath[0] = '/';
+ dest = rpath + 1;
+ }
+
+ for (start = end = name; *start; start = end)
+ {
+ /* Skip sequence of multiple path-separators. */
+ while (*start == '/')
+ ++start;
+
+ /* Find end of path component. */
+ for (end = start; *end && *end != '/'; ++end)
+ /* Nothing. */;
+
+ if (end - start == 0)
+ break;
+ else if (end - start == 1 && start[0] == '.')
+ /* nothing */;
+ else if (end - start == 2 && start[0] == '.' && start[1] == '.')
+ {
+ /* Back up to previous component, ignore if at root already. */
+ if (dest > rpath + 1)
+ while ((--dest)[-1] != '/')
+ ;
+ }
+ else
+ {
+ size_t new_size;
+
+ if (dest[-1] != '/')
+ *dest++ = '/';
+
+ if (dest + (end - start) >= rpath_limit)
+ {
+ ptrdiff_t dest_offset = dest - rpath;
+ char *new_rpath;
+
+ if (resolved)
+ {
+ if (dest > rpath + 1)
+ dest--;
+ *dest = '\0';
+ goto error;
+ }
+ new_size = rpath_limit - rpath;
+ if (end - start + 1 > path_max)
+ new_size += end - start + 1;
+ else
+ new_size += path_max;
+ new_rpath = (char *)realloc(rpath, new_size);
+ if (!new_rpath)
+ goto error;
+ rpath = new_rpath;
+ rpath_limit = rpath + new_size;
+
+ dest = rpath + dest_offset;
+ }
+
+ dest = (char*)memcpy(dest, start, end - start);
+ *dest = '\0';
+ }
+ }
+ if (dest > rpath + 1 && dest[-1] == '/')
+ --dest;
+ *dest = '\0';
+
+ return rpath;
+
+error:
+ if (!resolved)
+ free(rpath);
+ return NULL;
+}
+
+ssize_t readlink (const char * __path, char * __buf, size_t __buflen)
+{
+ errno = ENOSYS;
+ return -1;
+}
+#endif
diff --git a/src/skel/crossplatform.h b/src/skel/crossplatform.h
index aa90ce5a..4ab7d156 100644
--- a/src/skel/crossplatform.h
+++ b/src/skel/crossplatform.h
@@ -13,6 +13,10 @@ enum eWinVersion
OS_WINXP,
};
+#if !defined(_MSC_VER) && !defined(__CWCC__)
+char *_strdate(char *buf);
+#endif
+
#ifdef _WIN32
// As long as WITHWINDOWS isn't defined / <Windows.h> isn't included, we only need type definitions so let's include <IntSafe.h>.
@@ -157,3 +161,28 @@ bool FindNextFile(HANDLE, WIN32_FIND_DATA*);
void FileTimeToSystemTime(time_t*, SYSTEMTIME*);
void GetDateFormat(int, int, SYSTEMTIME*, int, char*, int);
#endif
+
+#ifdef __SWITCH__
+
+// tweak glfw values for switch to match expected pc bindings
+#ifdef GLFW_GAMEPAD_BUTTON_A
+ #undef GLFW_GAMEPAD_BUTTON_A
+#endif
+#define GLFW_GAMEPAD_BUTTON_A 1
+
+#ifdef GLFW_GAMEPAD_BUTTON_B
+ #undef GLFW_GAMEPAD_BUTTON_B
+#endif
+#define GLFW_GAMEPAD_BUTTON_B 0
+
+#ifdef GLFW_GAMEPAD_BUTTON_X
+ #undef GLFW_GAMEPAD_BUTTON_X
+#endif
+#define GLFW_GAMEPAD_BUTTON_X 3
+
+#ifdef GLFW_GAMEPAD_BUTTON_Y
+ #undef GLFW_GAMEPAD_BUTTON_Y
+#endif
+#define GLFW_GAMEPAD_BUTTON_Y 2
+
+#endif
diff --git a/src/skel/events.cpp b/src/skel/events.cpp
index 3e1e95b3..87447819 100644
--- a/src/skel/events.cpp
+++ b/src/skel/events.cpp
@@ -821,7 +821,9 @@ PadHandler(RsEvent event, void *param)
RwBool
AttachInputDevices(void)
{
+#ifndef IGNORE_MOUSE_KEYBOARD
RsInputDeviceAttach(rsKEYBOARD, KeyboardHandler);
+#endif
RsInputDeviceAttach(rsPAD, PadHandler);
diff --git a/src/skel/glfw/glfw.cpp b/src/skel/glfw/glfw.cpp
index 44f0c83a..f8beee64 100644
--- a/src/skel/glfw/glfw.cpp
+++ b/src/skel/glfw/glfw.cpp
@@ -12,12 +12,14 @@ DWORD _dwOperatingSystemVersion;
#include "resource.h"
#else
long _dwOperatingSystemVersion;
+#ifndef __SWITCH__
#ifndef __APPLE__
#include <sys/sysinfo.h>
#else
#include <mach/mach_host.h>
#include <sys/sysctl.h>
#endif
+#endif
#include <errno.h>
#include <locale.h>
#include <signal.h>
@@ -51,7 +53,7 @@ long _dwOperatingSystemVersion;
#include "MemoryMgr.h"
// We found out that GLFW's keyboard input handling is still pretty delayed/not stable, so now we fetch input from X11 directly on Linux.
-#if !defined _WIN32 && !defined __APPLE__ && !defined __SWITCH__ // && !defined WAYLAND
+#if !defined _WIN32 && !defined __APPLE__ && !defined GTA_HANDHELD // && !defined WAYLAND
#define GET_KEYBOARD_INPUT_FROM_X11
#endif
@@ -159,7 +161,7 @@ const char *_psGetUserFilesFolder()
&KeycbData) == ERROR_SUCCESS )
{
RegCloseKey(hKey);
- strcat(szUserFiles, "\\GTA3 User Files");
+ strcat(szUserFiles, "\\GTA Vice City User Files");
_psCreateFolder(szUserFiles);
return szUserFiles;
}
@@ -199,7 +201,11 @@ psCameraBeginUpdate(RwCamera *camera)
void
psCameraShowRaster(RwCamera *camera)
{
- if (CMenuManager::m_PrefsVsync)
+#ifdef LEGACY_MENU_OPTIONS
+ if (FrontEndMenuManager.m_PrefsVsync || FrontEndMenuManager.m_bMenuActive)
+#else
+ if (FrontEndMenuManager.m_PrefsFrameLimiter || FrontEndMenuManager.m_bMenuActive)
+#endif
RwCameraShowRaster(camera, PSGLOBAL(window), rwRASTERFLIPWAITVSYNC);
else
RwCameraShowRaster(camera, PSGLOBAL(window), rwRASTERFLIPDONTWAIT);
@@ -327,6 +333,78 @@ psNativeTextureSupport(void)
/*
*****************************************************************************
*/
+
+#ifdef __SWITCH__
+
+static HidVibrationValue SwitchVibrationValues[2];
+static HidVibrationDeviceHandle SwitchVibrationDeviceHandles[2][2];
+static HidVibrationDeviceHandle SwitchVibrationDeviceGC;
+
+static PadState SwitchPad;
+
+static Result HidInitializationResult[2];
+static Result HidInitializationGCResult;
+
+static void _psInitializeVibration()
+{
+ HidInitializationResult[0] = hidInitializeVibrationDevices(SwitchVibrationDeviceHandles[0], 2, HidNpadIdType_Handheld, HidNpadStyleTag_NpadHandheld);
+ if(R_FAILED(HidInitializationResult[0])) {
+ printf("Failed to initialize VibrationDevice for Handheld Mode\n");
+ }
+ HidInitializationResult[1] = hidInitializeVibrationDevices(SwitchVibrationDeviceHandles[1], 2, HidNpadIdType_No1, HidNpadStyleSet_NpadFullCtrl);
+ if(R_FAILED(HidInitializationResult[1])) {
+ printf("Failed to initialize VibrationDevice for Detached Mode\n");
+ }
+ HidInitializationGCResult = hidInitializeVibrationDevices(&SwitchVibrationDeviceGC, 1, HidNpadIdType_No1, HidNpadStyleTag_NpadGc);
+ if(R_FAILED(HidInitializationResult[1])) {
+ printf("Failed to initialize VibrationDevice for GC Mode\n");
+ }
+
+ SwitchVibrationValues[0].freq_low = 160.0f;
+ SwitchVibrationValues[0].freq_high = 320.0f;
+
+ padConfigureInput(1, HidNpadStyleSet_NpadFullCtrl);
+ padInitializeDefault(&SwitchPad);
+}
+
+static void _psHandleVibration()
+{
+ padUpdate(&SwitchPad);
+
+ uint8 target_device = padIsHandheld(&SwitchPad) ? 0 : 1;
+
+ if(R_SUCCEEDED(HidInitializationResult[target_device])) {
+ CPad* pad = CPad::GetPad(0);
+
+ // value conversion based on SDL2 switch port
+ SwitchVibrationValues[0].amp_high = SwitchVibrationValues[0].amp_low = pad->ShakeFreq == 0 ? 0.0f : 320.0f;
+ SwitchVibrationValues[0].freq_low = pad->ShakeFreq == 0.0 ? 160.0f : (float)pad->ShakeFreq * 1.26f;
+ SwitchVibrationValues[0].freq_high = pad->ShakeFreq == 0.0 ? 320.0f : (float)pad->ShakeFreq * 1.26f;
+
+ if (pad->ShakeDur < CTimer::GetTimeStepInMilliseconds())
+ pad->ShakeDur = 0;
+ else
+ pad->ShakeDur -= CTimer::GetTimeStepInMilliseconds();
+ if (pad->ShakeDur == 0) pad->ShakeFreq = 0;
+
+
+ if(target_device == 1 && R_SUCCEEDED(HidInitializationGCResult)) {
+ // gamecube rumble
+ hidSendVibrationGcErmCommand(SwitchVibrationDeviceGC, pad->ShakeFreq > 0 ? HidVibrationGcErmCommand_Start : HidVibrationGcErmCommand_Stop);
+ }
+
+ memcpy(&SwitchVibrationValues[1], &SwitchVibrationValues[0], sizeof(HidVibrationValue));
+ hidSendVibrationValues(SwitchVibrationDeviceHandles[target_device], SwitchVibrationValues, 2);
+ }
+}
+#else
+static void _psInitializeVibration() {}
+static void _psHandleVibration() {}
+#endif
+
+/*
+ *****************************************************************************
+ */
RwBool
psInitialize(void)
{
@@ -402,11 +480,9 @@ psInitialize(void)
InitialiseLanguage();
-#if GTA_VERSION < GTA3_PC_11
- FrontEndMenuManager.LoadSettings();
#endif
-#endif
+ _psInitializeVibration();
gGameState = GS_START_UP;
TRACE("gGameState = GS_START_UP");
@@ -455,13 +531,9 @@ psInitialize(void)
#ifndef PS2_MENU
-
-#if GTA_VERSION >= GTA3_PC_11
FrontEndMenuManager.LoadSettings();
#endif
-#endif
-
#ifdef _WIN32
MEMORYSTATUS memstats;
@@ -484,12 +556,31 @@ psInitialize(void)
_dwMemAvailPhys = (uint64_t)(vm_stat.free_count * page_size);
debug("Physical memory size %llu\n", _dwMemAvailPhys);
debug("Available physical memory %llu\n", size);
+#elif defined (__SWITCH__)
+ svcGetInfo(&_dwMemAvailPhys, InfoType_UsedMemorySize, CUR_PROCESS_HANDLE, 0);
+ debug("Physical memory size %llu\n", _dwMemAvailPhys);
#else
+#ifndef __APPLE__
struct sysinfo systemInfo;
sysinfo(&systemInfo);
_dwMemAvailPhys = systemInfo.freeram;
debug("Physical memory size %u\n", systemInfo.totalram);
debug("Available physical memory %u\n", systemInfo.freeram);
+#else
+ uint64_t size = 0;
+ uint64_t page_size = 0;
+ size_t uint64_len = sizeof(uint64_t);
+ size_t ull_len = sizeof(unsigned long long);
+ sysctl((int[]){CTL_HW, HW_PAGESIZE}, 2, &page_size, &ull_len, NULL, 0);
+ sysctl((int[]){CTL_HW, HW_MEMSIZE}, 2, &size, &uint64_len, NULL, 0);
+ vm_statistics_data_t vm_stat;
+ mach_msg_type_number_t count = HOST_VM_INFO_COUNT;
+ host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vm_stat, &count);
+ _dwMemAvailPhys = (uint64_t)(vm_stat.free_count * page_size);
+ debug("Physical memory size %llu\n", _dwMemAvailPhys);
+ debug("Available physical memory %llu\n", size);
+#endif
+ _dwOperatingSystemVersion = OS_WINXP; // To fool other classes
#endif
TheText.Unload();
@@ -907,7 +998,7 @@ void _InputInitialiseJoys()
free(db);
fclose(f);
} else
- printf("You don't seem to have copied " SDL_GAMEPAD_DB_PATH " file from re3/gamefiles to GTA3 directory. Some gamepads may not be recognized.\n");
+ printf("You don't seem to have copied " SDL_GAMEPAD_DB_PATH " file from reVC/gamefiles to GTA: Vice City directory. Some gamepads may not be recognized.\n");
#undef SDL_GAMEPAD_DB_PATH
@@ -938,30 +1029,53 @@ void _InputInitialiseJoys()
}
}
-long _InputInitialiseMouse()
+int lastCursorMode = GLFW_CURSOR_HIDDEN;
+long _InputInitialiseMouse(bool exclusive)
{
- glfwSetInputMode(PSGLOBAL(window), GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
+ // Disabled = keep cursor centered and hide
+ lastCursorMode = exclusive ? GLFW_CURSOR_DISABLED : GLFW_CURSOR_HIDDEN;
+ glfwSetInputMode(PSGLOBAL(window), GLFW_CURSOR, lastCursorMode);
return 0;
}
+void _InputShutdownMouse()
+{
+ // Not needed
+}
+
+// Not "needs exclusive" on GLFW, but more like "needs to change mode"
+bool _InputMouseNeedsExclusive()
+{
+ // That was the cause of infamous mouse bug on Win.
+
+ RwVideoMode vm;
+ RwEngineGetVideoModeInfo(&vm, GcurSelVM);
+
+ // If windowed, free the cursor on menu(where this func. is called and DISABLED-HIDDEN transition is done accordingly)
+ // If it's fullscreen, be sure that it didn't stuck on HIDDEN.
+ return !(vm.flags & rwVIDEOMODEEXCLUSIVE) || lastCursorMode == GLFW_CURSOR_HIDDEN;
+}
+
void psPostRWinit(void)
{
RwVideoMode vm;
RwEngineGetVideoModeInfo(&vm, GcurSelVM);
+ glfwSetFramebufferSizeCallback(PSGLOBAL(window), resizeCB);
+#ifndef IGNORE_MOUSE_KEYBOARD
#ifndef GET_KEYBOARD_INPUT_FROM_X11
glfwSetKeyCallback(PSGLOBAL(window), keypressCB);
#endif
- glfwSetFramebufferSizeCallback(PSGLOBAL(window), resizeCB);
glfwSetScrollCallback(PSGLOBAL(window), scrollCB);
glfwSetCursorPosCallback(PSGLOBAL(window), cursorCB);
glfwSetCursorEnterCallback(PSGLOBAL(window), cursorEnterCB);
+#endif
glfwSetWindowIconifyCallback(PSGLOBAL(window), windowIconifyCB);
glfwSetWindowFocusCallback(PSGLOBAL(window), windowFocusCB);
glfwSetJoystickCallback(joysChangeCB);
_InputInitialiseJoys();
- _InputInitialiseMouse();
+ _InputInitialiseMouse(false);
if(!(vm.flags & rwVIDEOMODEEXCLUSIVE))
glfwSetWindowSize(PSGLOBAL(window), RsGlobal.maximumWidth, RsGlobal.maximumHeight);
@@ -1140,7 +1254,7 @@ void InitialiseLanguage()
|| primLayout == LANG_GERMAN )
{
CGame::nastyGame = false;
- CMenuManager::m_PrefsAllowNastyGame = false;
+ FrontEndMenuManager.m_PrefsAllowNastyGame = false;
CGame::germanGame = true;
}
@@ -1149,7 +1263,7 @@ void InitialiseLanguage()
|| primLayout == LANG_FRENCH )
{
CGame::nastyGame = false;
- CMenuManager::m_PrefsAllowNastyGame = false;
+ FrontEndMenuManager.m_PrefsAllowNastyGame = false;
CGame::frenchGame = true;
}
@@ -1160,7 +1274,7 @@ void InitialiseLanguage()
#ifdef NASTY_GAME
CGame::nastyGame = true;
- CMenuManager::m_PrefsAllowNastyGame = true;
+ FrontEndMenuManager.m_PrefsAllowNastyGame = true;
CGame::noProstitutes = false;
#endif
@@ -1195,33 +1309,33 @@ void InitialiseLanguage()
}
}
- CMenuManager::OS_Language = primUserLCID;
+ FrontEndMenuManager.OS_Language = primUserLCID;
switch ( lang )
{
case LANG_GERMAN:
{
- CMenuManager::m_PrefsLanguage = CMenuManager::LANGUAGE_GERMAN;
+ FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_GERMAN;
break;
}
case LANG_SPANISH:
{
- CMenuManager::m_PrefsLanguage = CMenuManager::LANGUAGE_SPANISH;
+ FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_SPANISH;
break;
}
case LANG_FRENCH:
{
- CMenuManager::m_PrefsLanguage = CMenuManager::LANGUAGE_FRENCH;
+ FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_FRENCH;
break;
}
case LANG_ITALIAN:
{
- CMenuManager::m_PrefsLanguage = CMenuManager::LANGUAGE_ITALIAN;
+ FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_ITALIAN;
break;
}
default:
{
- CMenuManager::m_PrefsLanguage = CMenuManager::LANGUAGE_AMERICAN;
+ FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_AMERICAN;
break;
}
}
@@ -1791,7 +1905,7 @@ main(int argc, char *argv[])
InitMemoryMgr();
#endif
-#ifndef _WIN32
+#if !defined(_WIN32) && !defined(__SWITCH__)
struct sigaction act;
act.sa_sigaction = terminateHandler;
act.sa_flags = SA_SIGINFO;
@@ -1923,7 +2037,7 @@ main(int argc, char *argv[])
int connectedPadButtons = ControlsManager.ms_padButtonsInited;
#endif
- int32 gta3set = CFileMgr::OpenFile("gta3.set", "r");
+ int32 gta3set = CFileMgr::OpenFile("gta_vc.set", "r");
if ( gta3set )
{
@@ -1984,7 +2098,7 @@ main(int argc, char *argv[])
#ifndef MASTER
if (gbModelViewer) {
- // This is TheModelViewer in LCS, but not compiled on III Mobile.
+ // This is TheModelViewer in LCS
LoadingScreen("Loading the ModelViewer", NULL, GetRandomSplashScreen());
CAnimViewer::Initialise();
CTimer::Update();
@@ -2013,7 +2127,7 @@ main(int argc, char *argv[])
#endif
#ifndef MASTER
if (gbModelViewer) {
- // This is TheModelViewerCore in LCS, but TheModelViewer on other state-machine III-VCs.
+ // This is TheModelViewerCore in LCS
TheModelViewer();
} else
#endif
@@ -2112,6 +2226,7 @@ main(int argc, char *argv[])
printf("Into TheGame!!!\n");
#else
LoadingScreen(nil, nil, "loadsc0");
+ // LoadingScreen(nil, nil, "loadsc0"); // duplicate
#endif
if ( !CGame::InitialiseOnceAfterRW() )
RsGlobal.quit = TRUE;
@@ -2124,15 +2239,15 @@ main(int argc, char *argv[])
#endif
break;
}
-
#ifndef PS2_MENU
case GS_INIT_FRONTEND:
{
LoadingScreen(nil, nil, "loadsc0");
+ // LoadingScreen(nil, nil, "loadsc0"); // duplicate
FrontEndMenuManager.m_bGameNotLoaded = true;
- CMenuManager::m_bStartUpFrontEndRequested = true;
+ FrontEndMenuManager.m_bStartUpFrontEndRequested = true;
if ( defaultFullscreenRes )
{
@@ -2215,7 +2330,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;
@@ -2318,7 +2433,6 @@ main(int argc, char *argv[])
#endif
}
-
#ifndef MASTER
if ( gbModelViewer )
CAnimViewer::Shutdown();
@@ -2455,7 +2569,9 @@ void CapturePad(RwInt32 padID)
if ( Abs(rightStickPos.y) > 0.3f )
pad->PCTempJoyState.RightStickY = (int32)(rightStickPos.y * 128.0f);
}
-
+
+ _psHandleVibration();
+
return;
}
@@ -2489,5 +2605,9 @@ int strcasecmp(const char* str1, const char* str2)
{
return _strcmpi(str1, str2);
}
+int strncasecmp(const char *str1, const char *str2, size_t len)
+{
+ return _strnicmp(str1, str2, len);
+}
#endif
#endif
diff --git a/src/skel/platform.h b/src/skel/platform.h
index c9a8a11f..0475d20a 100644
--- a/src/skel/platform.h
+++ b/src/skel/platform.h
@@ -38,7 +38,9 @@ extern RwBool psInstallFileSystem(void);
extern RwBool psNativeTextureSupport(void);
extern void _InputTranslateShiftKeyUpDown(RsKeyCodes* rs);
-extern long _InputInitialiseMouse(); // returns HRESULT on Windows actually
+extern long _InputInitialiseMouse(bool exclusive); // returns HRESULT on Windows actually
+extern void _InputShutdownMouse();
+extern bool _InputMouseNeedsExclusive();
extern void _InputInitialiseJoys();
extern void HandleExit();
diff --git a/src/skel/skeleton.cpp b/src/skel/skeleton.cpp
index 7889056b..2bb23460 100644
--- a/src/skel/skeleton.cpp
+++ b/src/skel/skeleton.cpp
@@ -305,8 +305,6 @@ RsRwInitialize(void *displayID)
{
RwEngineOpenParams openParams;
- PUSH_MEMID(MEMID_RENDER); // NB: not popped on failed return
-
/*
* Start RenderWare...
*/
@@ -371,10 +369,8 @@ RsRwInitialize(void *displayID)
psNativeTextureSupport();
+ RwTextureSetAutoMipmapping(TRUE);
RwTextureSetMipmapping(FALSE);
- RwTextureSetAutoMipmapping(FALSE);
-
- POP_MEMID();
return TRUE;
}
@@ -401,7 +397,7 @@ RsInitialize(void)
*/
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;
diff --git a/src/skel/win/gta3.ico b/src/skel/win/gta3.ico
deleted file mode 100644
index d0a47713..00000000
--- a/src/skel/win/gta3.ico
+++ /dev/null
Binary files differ
diff --git a/src/skel/win/gtavc.ico b/src/skel/win/gtavc.ico
new file mode 100644
index 00000000..7bfcc5a5
--- /dev/null
+++ b/src/skel/win/gtavc.ico
Binary files differ
diff --git a/src/skel/win/resource.h b/src/skel/win/resource.h
index 84dffb95..93f14216 100644
--- a/src/skel/win/resource.h
+++ b/src/skel/win/resource.h
@@ -8,7 +8,7 @@
#define IDEXIT 1002
#define IDC_SELECTDEVICE 1005
-#define IDI_MAIN_ICON 1042
+#define IDI_MAIN_ICON 100
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
diff --git a/src/skel/win/win.cpp b/src/skel/win/win.cpp
index 95ac28aa..c49f0ab9 100644
--- a/src/skel/win/win.cpp
+++ b/src/skel/win/win.cpp
@@ -53,7 +53,6 @@
#define MAX_SUBSYSTEMS (16)
-
static RwBool ForegroundApp = TRUE;
static RwBool RwInitialised = FALSE;
@@ -195,7 +194,7 @@ const char *_psGetUserFilesFolder()
&KeycbData) == ERROR_SUCCESS )
{
RegCloseKey(hKey);
- strcat(szUserFiles, "\\GTA3 User Files");
+ strcat(szUserFiles, "\\GTA Vice City User Files");
_psCreateFolder(szUserFiles);
return szUserFiles;
}
@@ -235,7 +234,11 @@ psCameraBeginUpdate(RwCamera *camera)
void
psCameraShowRaster(RwCamera *camera)
{
- if (CMenuManager::m_PrefsVsync)
+#ifdef LEGACY_MENU_OPTIONS
+ if (FrontEndMenuManager.m_PrefsVsync || FrontEndMenuManager.m_bMenuActive)
+#else
+ if (FrontEndMenuManager.m_PrefsFrameLimiter || FrontEndMenuManager.m_bMenuActive)
+#endif
RwCameraShowRaster(camera, PSGLOBAL(window), rwRASTERFLIPWAITVSYNC);
else
RwCameraShowRaster(camera, PSGLOBAL(window), rwRASTERFLIPDONTWAIT);
@@ -579,6 +582,9 @@ _RETEX:
}
}
+#ifdef __MWERKS__
+#pragma dont_inline on
+#endif
void _psPrintCpuInfo()
{
RwUInt32 features = _psGetCpuFeatures();
@@ -593,6 +599,9 @@ void _psPrintCpuInfo()
if ( FeaturesEx & 0x80000000 )
debug("with 3DNow");
}
+#ifdef __MWERKS__
+#pragma dont_inline off
+#endif
#endif
/*
@@ -661,10 +670,6 @@ psInitialize(void)
C_PcSave::SetSaveDirectory(_psGetUserFilesFolder());
InitialiseLanguage();
-#if GTA_VERSION < GTA3_PC_11
- FrontEndMenuManager.LoadSettings();
-#endif
-
#endif
gGameState = GS_START_UP;
@@ -712,13 +717,9 @@ psInitialize(void)
}
#ifndef PS2_MENU
-
-#if GTA_VERSION >= GTA3_PC_11
FrontEndMenuManager.LoadSettings();
#endif
-#endif
-
dwDXVersion = GetDXVersion();
debug("DirectX version 0x%x\n", dwDXVersion);
@@ -956,8 +957,7 @@ void HandleGraphEvent(void)
/*
*****************************************************************************
- */
-
+ */
LRESULT CALLBACK
MainWndProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam)
{
@@ -1303,6 +1303,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;
+ }
+
}
/*
@@ -1311,7 +1321,6 @@ MainWndProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam)
return DefWindowProc(window, message, wParam, lParam);
}
-
/*
*****************************************************************************
*/
@@ -1330,11 +1339,7 @@ InitApplication(HANDLE instance)
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
windowClass.hInstance = (HINSTANCE)instance;
-#ifdef FIX_BUGS
- windowClass.hIcon = LoadIcon((HINSTANCE)instance, MAKEINTRESOURCE(IDI_MAIN_ICON));
-#else
- windowClass.hIcon = nil;
-#endif
+ windowClass.hIcon = LoadIcon((HINSTANCE)instance, (LPCSTR)IDI_MAIN_ICON);
windowClass.hCursor = LoadCursor(nil, IDC_ARROW);
windowClass.hbrBackground = nil;
windowClass.lpszMenuName = NULL;
@@ -1390,10 +1395,7 @@ UINT GetBestRefreshRate(UINT width, UINT height, UINT depth)
if ( mode.Width == width && mode.Height == height && mode.Format == format )
{
if ( mode.RefreshRate == 0 ) {
- // From VC
-#ifdef FIX_BUGS
d3d->Release();
-#endif
return 0;
}
@@ -1402,10 +1404,7 @@ UINT GetBestRefreshRate(UINT width, UINT height, UINT depth)
}
}
- // From VC
-#ifdef FIX_BUGS
d3d->Release();
-#endif
if ( refreshRate == -1 )
return -1;
@@ -1499,7 +1498,7 @@ psSelectDevice()
#ifdef DEFAULT_NATIVE_RESOLUTION
GcurSelVM = 1;
#else
- MessageBox(nil, "Cannot find 640x480 video mode", "GTA3", MB_OK);
+ MessageBox(nil, "Cannot find 640x480 video mode", "GTA: Vice City", MB_OK);
return FALSE;
#endif
}
@@ -1542,7 +1541,7 @@ psSelectDevice()
}
if(bestFsMode < 0){
- MessageBox(nil, "Cannot find desired video mode", "GTA3", MB_OK);
+ MessageBox(nil, "Cannot find desired video mode", "GTA: Vice City", MB_OK);
return FALSE;
}
GcurSelVM = bestFsMode;
@@ -1676,7 +1675,6 @@ RwBool _psSetVideoMode(RwInt32 subSystem, RwInt32 videoMode)
return TRUE;
}
-
/*
*****************************************************************************
*/
@@ -1787,7 +1785,7 @@ void InitialiseLanguage()
|| primLayout == LANG_GERMAN )
{
CGame::nastyGame = false;
- CMenuManager::m_PrefsAllowNastyGame = false;
+ FrontEndMenuManager.m_PrefsAllowNastyGame = false;
CGame::germanGame = true;
}
@@ -1796,7 +1794,7 @@ void InitialiseLanguage()
|| primLayout == LANG_FRENCH )
{
CGame::nastyGame = false;
- CMenuManager::m_PrefsAllowNastyGame = false;
+ FrontEndMenuManager.m_PrefsAllowNastyGame = false;
CGame::frenchGame = true;
}
@@ -1807,7 +1805,7 @@ void InitialiseLanguage()
#ifdef NASTY_GAME
CGame::nastyGame = true;
- CMenuManager::m_PrefsAllowNastyGame = true;
+ FrontEndMenuManager.m_PrefsAllowNastyGame = true;
CGame::noProstitutes = false;
#endif
@@ -1842,33 +1840,33 @@ void InitialiseLanguage()
}
}
- CMenuManager::OS_Language = primUserLCID;
+ FrontEndMenuManager.OS_Language = primUserLCID;
switch ( lang )
{
case LANG_GERMAN:
{
- CMenuManager::m_PrefsLanguage = CMenuManager::LANGUAGE_GERMAN;
+ FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_GERMAN;
break;
}
case LANG_SPANISH:
{
- CMenuManager::m_PrefsLanguage = CMenuManager::LANGUAGE_SPANISH;
+ FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_SPANISH;
break;
}
case LANG_FRENCH:
{
- CMenuManager::m_PrefsLanguage = CMenuManager::LANGUAGE_FRENCH;
+ FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_FRENCH;
break;
}
case LANG_ITALIAN:
{
- CMenuManager::m_PrefsLanguage = CMenuManager::LANGUAGE_ITALIAN;
+ FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_ITALIAN;
break;
}
default:
{
- CMenuManager::m_PrefsLanguage = CMenuManager::LANGUAGE_AMERICAN;
+ FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_AMERICAN;
break;
}
}
@@ -2088,7 +2086,7 @@ WinMain(HINSTANCE instance,
if ( _InputInitialise() == S_OK )
{
- _InputInitialiseMouse();
+ _InputInitialiseMouse(false);
_InputInitialiseJoys();
}
@@ -2169,7 +2167,7 @@ WinMain(HINSTANCE instance,
int connectedPadButtons = ControlsManager.ms_padButtonsInited;
#endif
- int32 gta3set = CFileMgr::OpenFile("gta3.set", "r");
+ int32 gta3set = CFileMgr::OpenFile("gta_vc.set", "r");
if ( gta3set )
{
@@ -2211,7 +2209,7 @@ WinMain(HINSTANCE instance,
#ifndef MASTER
if (gbModelViewer) {
- // This is TheModelViewer in LCS, but not compiled on III Mobile.
+ // This is TheModelViewer in LCS
LoadingScreen("Loading the ModelViewer", NULL, GetRandomSplashScreen());
CAnimViewer::Initialise();
CTimer::Update();
@@ -2300,6 +2298,8 @@ WinMain(HINSTANCE instance,
if ( startupDeactivate || ControlsManager.GetJoyButtonJustDown() != 0 )
++gGameState;
+ else if ( CPad::GetPad(0)->NewState.CheckForInput() )
+ ++gGameState;
else if ( CPad::GetPad(0)->GetLeftMouseJustDown() )
++gGameState;
else if ( CPad::GetPad(0)->GetEnterJustDown() )
@@ -2324,7 +2324,7 @@ WinMain(HINSTANCE instance,
CoUninitialize();
#endif
- 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");
@@ -2340,6 +2340,8 @@ WinMain(HINSTANCE instance,
if ( startupDeactivate || ControlsManager.GetJoyButtonJustDown() != 0 )
++gGameState;
+ else if ( CPad::GetPad(0)->NewState.CheckForInput() )
+ ++gGameState;
else if ( CPad::GetPad(0)->GetLeftMouseJustDown() )
++gGameState;
else if ( CPad::GetPad(0)->GetEnterJustDown() )
@@ -2379,6 +2381,7 @@ WinMain(HINSTANCE instance,
printf("Into TheGame!!!\n");
#else
LoadingScreen(nil, nil, "loadsc0");
+ // LoadingScreen(nil, nil, "loadsc0"); // duplicate
#endif
if ( !CGame::InitialiseOnceAfterRW() )
RsGlobal.quit = TRUE;
@@ -2396,10 +2399,11 @@ WinMain(HINSTANCE instance,
case GS_INIT_FRONTEND:
{
LoadingScreen(nil, nil, "loadsc0");
+ // LoadingScreen(nil, nil, "loadsc0"); // duplicate
FrontEndMenuManager.m_bGameNotLoaded = true;
- CMenuManager::m_bStartUpFrontEndRequested = true;
+ FrontEndMenuManager.m_bStartUpFrontEndRequested = true;
if ( defaultFullscreenRes )
{
@@ -2484,7 +2488,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;
@@ -2653,7 +2657,7 @@ HRESULT _InputInitialise()
return S_OK;
}
-HRESULT _InputInitialiseMouse()
+HRESULT _InputInitialiseMouse(bool exclusive)
{
HRESULT hr;
@@ -2671,7 +2675,7 @@ HRESULT _InputInitialiseMouse()
if( FAILED( hr = PSGLOBAL(mouse)->SetDataFormat( &c_dfDIMouse2 ) ) )
return hr;
- if( FAILED( hr = PSGLOBAL(mouse)->SetCooperativeLevel( PSGLOBAL(window), DISCL_NONEXCLUSIVE | DISCL_FOREGROUND ) ) )
+ if( FAILED( hr = PSGLOBAL(mouse)->SetCooperativeLevel( PSGLOBAL(window), (exclusive ? DISCL_EXCLUSIVE : DISCL_NONEXCLUSIVE) | DISCL_FOREGROUND ) ) )
return hr;
// Acquire the newly created device
@@ -2959,6 +2963,28 @@ void _InputShutdown()
SAFE_RELEASE(PSGLOBAL(dinterface));
}
+void _InputShutdownMouse()
+{
+ if (PSGLOBAL(mouse) == nil)
+ return;
+
+ PSGLOBAL(mouse)->Unacquire();
+ SAFE_RELEASE(PSGLOBAL(mouse));
+}
+
+bool _InputMouseNeedsExclusive(void)
+{
+ // FIX: I don't know why R* needed that, but it causes infamous mouse bug on modern systems.
+ // Probably DirectInput bug, since Acquire() and GetDeviceState() reports everything A-OK.
+#ifdef FIX_BUGS
+ return false;
+#endif
+ RwVideoMode vm;
+ RwEngineGetVideoModeInfo(&vm, GcurSelVM);
+
+ return vm.flags & rwVIDEOMODEEXCLUSIVE;
+}
+
BOOL CALLBACK _InputEnumDevicesCallback( const DIDEVICEINSTANCE* pdidInstance, VOID* pContext )
{
HRESULT hr;
@@ -3428,5 +3454,9 @@ int strcasecmp(const char *str1, const char *str2)
{
return _strcmpi(str1, str2);
}
+int strncasecmp(const char *str1, const char *str2, size_t len)
+{
+ return _strnicmp(str1, str2, len);
+}
#endif
#endif
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/Messages.cpp b/src/text/Messages.cpp
index b68f918d..81339ae0 100644
--- a/src/text/Messages.cpp
+++ b/src/text/Messages.cpp
@@ -290,6 +290,7 @@ CMessages::AddBigMessage(wchar *msg, uint32 time, uint16 style)
BIGMessages[style].m_Stack[0].m_nNumber[5] = -1;
BIGMessages[style].m_Stack[0].m_pString = nil;
}
+
void
CMessages::AddBigMessageQ(wchar *msg, uint32 time, uint16 style)
{
@@ -320,7 +321,7 @@ CMessages::AddBigMessageQ(wchar *msg, uint32 time, uint16 style)
void
CMessages::AddToPreviousBriefArray(wchar *text, int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6, wchar *string)
{
- int32 i = 0;
+ int32 i;
for (i = 0; i < NUMPREVIOUSBRIEFS && PreviousBriefs[i].m_pText != nil; i++) {
if (PreviousBriefs[i].m_nNumber[0] == n1
&& PreviousBriefs[i].m_nNumber[1] == n2
@@ -419,10 +420,9 @@ CMessages::InsertStringInString(wchar *str1, wchar *str2)
for (i = 0; i < total_size; ) {
#ifdef MORE_LANGUAGES
if ((CFont::IsJapanese() && *_str1 == (0x8000 | '~') && *(_str1 + 1) == (0x8000 | 'a') && *(_str1 + 2) == (0x8000 | '~'))
- || (*_str1 == '~' && *(_str1 + 1) == 'a' && *(_str1 + 2) == '~'))
- {
+ || (*_str1 == '~' && *(_str1 + 1) == 'a' && *(_str1 + 2) == '~')) {
#else
- if (*_str1 == '~' && *(_str1 + 1) == 'a' && *(_str1 + 2) == '~') {
+ if (*_str1 == '~' && *(_str1 + 1) == 'a' && *(_str1 + 2) == '~') {
#endif
_str1 += 3;
for (int j = 0; j < str2_size; j++) {
diff --git a/src/text/Text.cpp b/src/text/Text.cpp
index 08ab0e1e..1369d1db 100644
--- a/src/text/Text.cpp
+++ b/src/text/Text.cpp
@@ -7,6 +7,7 @@
#include "Frontend.h"
#include "Messages.h"
#include "Text.h"
+#include "Timer.h"
wchar WideErrorString[25];
@@ -15,22 +16,28 @@ CText TheText;
CText::CText(void)
{
encoding = 'e';
+ bHasMissionTextOffsets = false;
+ bIsMissionTextLoaded = false;
+ memset(szMissionTableName, 0, sizeof(szMissionTableName));
memset(WideErrorString, 0, sizeof(WideErrorString));
}
void
CText::Load(void)
{
- uint8 *filedata;
- char filename[32], type[4];
- ssize_t offset, length;
- size_t sectlen;
+ char filename[32];
+ size_t 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 CMenuManager::LANGUAGE_AMERICAN:
sprintf(filename, "AMERICAN.GXT");
break;
@@ -59,49 +66,62 @@ 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("");
}
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));
}
wchar*
CText::Get(const char *key)
{
+ uint8 result = false;
#if defined (FIX_BUGS) || defined(FIX_BUGS_64)
- return keyArray.Search(key, data.chars);
+ wchar *outstr = keyArray.Search(key, data.chars, &result);
#else
- return keyArray.Search(key);
+ wchar *outstr = keyArray.Search(key, &result);
#endif
+
+ if (!result && bHasMissionTextOffsets && bIsMissionTextLoaded)
+#if defined (FIX_BUGS) || defined(FIX_BUGS_64)
+ outstr = mission_keyArray.Search(key, mission_data.chars, &result);
+#else
+ outstr = mission_keyArray.Search(key, &result);
+#endif
+ return outstr;
}
wchar UpperCaseTable[128] = {
@@ -174,20 +194,137 @@ CText::UpperCase(wchar *s)
}
}
+void
+CText::GetNameOfLoadedMissionText(char *outName)
+{
+ strcpy(outName, szMissionTableName);
+}
void
-CKeyArray::Load(size_t length, uint8 *data, ssize_t *offset)
+CText::ReadChunkHeader(ChunkHeader *buf, int32 file, size_t *offset)
{
- size_t i;
- uint8 *rawbytes;
+#ifdef THIS_IS_STUPID
+ char *_buf = (char*)buf;
+ for (int i = 0; i < sizeof(ChunkHeader); i++) {
+ CFileMgr::Read(file, &_buf[i], 1);
+ (*offset)++;
+ }
+#else
+ // 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);
+#endif
+}
+
+void
+CText::LoadMissionText(char *MissionTableName)
+{
+ char filename[32];
+ CMessages::ClearAllMessagesDisplayedByGame();
+
+ 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 CMenuManager::LANGUAGE_AMERICAN:
+ sprintf(filename, "AMERICAN.GXT");
+ break;
+ case CMenuManager::LANGUAGE_FRENCH:
+ sprintf(filename, "FRENCH.GXT");
+ break;
+ case CMenuManager::LANGUAGE_GERMAN:
+ sprintf(filename, "GERMAN.GXT");
+ break;
+ case CMenuManager::LANGUAGE_ITALIAN:
+ sprintf(filename, "ITALIAN.GXT");
+ break;
+ case CMenuManager::LANGUAGE_SPANISH:
+ sprintf(filename, "SPANISH.GXT");
+ break;
+#ifdef MORE_LANGUAGES
+ case CMenuManager::LANGUAGE_POLISH:
+ sprintf(filename, "POLISH.GXT");
+ break;
+ case CMenuManager::LANGUAGE_RUSSIAN:
+ sprintf(filename, "RUSSIAN.GXT");
+ break;
+ case CMenuManager::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) {
+ size_t bytes_read = 0;
+ ReadChunkHeader(&m_ChunkHeader, file, &bytes_read);
+ if (m_ChunkHeader.size != 0) {
+ if (strncmp(m_ChunkHeader.magic, "TKEY", 4) == 0) {
+ size_t bytes_read = 0;
+ mission_keyArray.Load(m_ChunkHeader.size, file, &bytes_read);
+ tkey_loaded = true;
+ } else if (strncmp(m_ChunkHeader.magic, "TDAT", 4) == 0) {
+ size_t 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;
+}
+
+
+void
+CKeyArray::Load(size_t length, int file, size_t* offset)
+{
+ char *rawbytes;
// You can make numEntries size_t if you want to exceed 32-bit boundaries, everything else should be ready.
numEntries = (int)(length / sizeof(CKeyEntry));
entries = new CKeyEntry[numEntries];
- rawbytes = (uint8*)entries;
+ rawbytes = (char*)entries;
- for(i = 0; i < length; i++)
- rawbytes[i] = data[(*offset)++];
+#ifdef THIS_IS_STUPID
+ for (uint32 i = 0; i < length; i++) {
+ CFileMgr::Read(file, &rawbytes[i], 1);
+ (*offset)++;
+ }
+#else
+ CFileMgr::Read(file, rawbytes, length);
+ *offset += length;
+#endif
}
void
@@ -230,9 +367,9 @@ CKeyArray::BinarySearch(const char *key, CKeyEntry *entries, int16 low, int16 hi
wchar*
#if defined (FIX_BUGS) || defined(FIX_BUGS_64)
-CKeyArray::Search(const char *key, wchar *data)
+CKeyArray::Search(const char *key, wchar *data, uint8 *result)
#else
-CKeyArray::Search(const char *key)
+CKeyArray::Search(const char *key, uint8 *result)
#endif
{
CKeyEntry *found;
@@ -241,33 +378,47 @@ CKeyArray::Search(const char *key)
#if defined (FIX_BUGS) || defined(FIX_BUGS_64)
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)
+ 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;
}
-
void
-CData::Load(size_t length, uint8 *data, ssize_t *offset)
+CData::Load(size_t length, int file, size_t * offset)
{
- size_t i;
- uint8 *rawbytes;
+ char *rawbytes;
// You can make numChars size_t if you want to exceed 32-bit boundaries, everything else should be ready.
numChars = (int)(length / sizeof(wchar));
chars = new wchar[numChars];
- rawbytes = (uint8*)chars;
+ rawbytes = (char*)chars;
- for(i = 0; i < length; i++)
- rawbytes[i] = data[(*offset)++];
+#ifdef THIS_IS_STUPID
+ for(uint32 i = 0; i < length; i++){
+ CFileMgr::Read(file, &rawbytes[i], 1);
+ (*offset)++;
+ }
+#else
+ CFileMgr::Read(file, rawbytes, length);
+ *offset += length;
+#endif
}
void
@@ -278,6 +429,33 @@ CData::Unload(void)
numChars = 0;
}
+void
+CMissionTextOffsets::Load(size_t table_size, int file, size_t *offset, int)
+{
+#ifdef THIS_IS_STUPID
+ size_t num_of_entries = table_size / sizeof(CMissionTextOffsets::Entry);
+ for (size_t mi = 0; mi < num_of_entries; mi++) {
+ for (uint32 i = 0; i < sizeof(data[mi].szMissionName); i++) {
+ CFileMgr::Read(file, &data[i].szMissionName[i], 1);
+ (*offset)++;
+ }
+ char* _buf = (char*)&data[mi].offset;
+ for (uint32 i = 0; i < sizeof(data[mi].offset); i++) {
+ CFileMgr::Read(file, &_buf[i], 1);
+ (*offset)++;
+ }
+ }
+ size = (uint16)num_of_entries;
+#else
+ // not exact VC code but smaller and better :P
+
+ // You can make this size_t if you want to exceed 32-bit boundaries, everything else should be ready.
+ size = (uint16) (table_size / sizeof(CMissionTextOffsets::Entry));
+ CFileMgr::Read(file, (char*)data, sizeof(CMissionTextOffsets::Entry) * size);
+ *offset += sizeof(CMissionTextOffsets::Entry) * size;
+#endif
+}
+
char*
UnicodeToAscii(wchar *src)
{
@@ -290,8 +468,29 @@ UnicodeToAscii(wchar *src)
if(*src < 128)
#endif
aStr[len] = *src;
- else
- aStr[len] = '#';
+ // convert to CP1252
+ else if(*src <= 131)
+ aStr[len] = *src + 64;
+ else if (*src <= 141)
+ aStr[len] = *src + 66;
+ else if (*src <= 145)
+ aStr[len] = *src + 68;
+ else if (*src <= 149)
+ aStr[len] = *src + 71;
+ else if (*src <= 154)
+ aStr[len] = *src + 73;
+ else if (*src <= 164)
+ aStr[len] = *src + 75;
+ else if (*src <= 168)
+ aStr[len] = *src + 77;
+ else if (*src <= 204)
+ aStr[len] = *src + 80;
+ else switch (*src) {
+ case 205: aStr[len] = 209; break;
+ case 206: aStr[len] = 241; break;
+ case 207: aStr[len] = 191; break;
+ default: aStr[len] = '#'; break;
+ }
aStr[len] = '\0';
return aStr;
}
diff --git a/src/text/Text.h b/src/text/Text.h
index ab6d1809..1174216c 100644
--- a/src/text/Text.h
+++ b/src/text/Text.h
@@ -26,14 +26,14 @@ public:
CKeyArray(void) : entries(nil), numEntries(0) {}
~CKeyArray(void) { Unload(); }
- void Load(size_t length, uint8 *data, ssize_t *offset);
+ void Load(size_t length, int file, size_t *offset);
void Unload(void);
void Update(wchar *chars);
CKeyEntry *BinarySearch(const char *key, CKeyEntry *entries, int16 low, int16 high);
#if defined (FIX_BUGS) || defined(FIX_BUGS_64)
- wchar *Search(const char *key, wchar *data);
+ wchar *Search(const char *key, wchar *data, uint8 *result);
#else
- wchar *Search(const char *key);
+ wchar *Search(const char *key, uint8* result);
#endif
};
@@ -45,15 +45,45 @@ public:
CData(void) : chars(nil), numChars(0) {}
~CData(void) { Unload(); }
- void Load(size_t length, uint8 *data, ssize_t *offset);
+ void Load(size_t length, int file, size_t* 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; // You can make this size_t if you want to exceed 32-bit boundaries, everything else should be ready.
+
+ CMissionTextOffsets(void) : size(0) {}
+ void Load(size_t table_size, int file, size_t* 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);
@@ -61,6 +91,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, size_t *bytes_read);
+ void LoadMissionText(char *MissionTableName);
};
extern CText TheText;
diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp
index 7b3a8921..96b78fa6 100644
--- a/src/vehicles/Automobile.cpp
+++ b/src/vehicles/Automobile.cpp
@@ -17,8 +17,10 @@
#include "Explosion.h"
#include "Particle.h"
#include "ParticleObject.h"
+#include "Glass.h"
#include "Antennas.h"
#include "Skidmarks.h"
+#include "WindModifiers.h"
#include "Shadows.h"
#include "PointLights.h"
#include "Coronas.h"
@@ -35,8 +37,10 @@
#include "Population.h"
#include "CarCtrl.h"
#include "CarAI.h"
+#include "Stats.h"
#include "Garages.h"
#include "PathFind.h"
+#include "Replay.h"
#include "AnimManager.h"
#include "RpAnimBlend.h"
#include "AnimBlendAssociation.h"
@@ -44,10 +48,11 @@
#include "PlayerPed.h"
#include "Object.h"
#include "Automobile.h"
+#include "Bike.h"
#include "Wanted.h"
#include "SaveBuf.h"
-bool bAllCarCheat; // unused
+bool bAllCarCheat;
RwObject *GetCurrentAtomicObjectCB(RwObject *object, void *data);
@@ -55,7 +60,7 @@ bool CAutomobile::m_sAllTaxiLights;
const uint32 CAutomobile::nSaveStructSize =
#ifdef COMPATIBLE_SAVES
- 1448;
+ 1500;
#else
sizeof(CAutomobile);
#endif
@@ -69,7 +74,7 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy)
CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(id);
m_fFireBlowUpTimer = 0.0f;
- m_auto_unk1 = 0;
+ m_doingBurnout = 0;
bTaxiLight = m_sAllTaxiLights;
bFixedColour = false;
bBigWheels = false;
@@ -77,7 +82,26 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy)
SetModelIndex(id);
+ // Already done in CVehicle...
+ switch(GetModelIndex()){
+ case MI_HUNTER:
+ case MI_ANGEL:
+ case MI_FREEWAY:
+ m_nRadioStation = V_ROCK;
+ break;
+ case MI_RCBARON:
+ case MI_RCBANDIT:
+ case MI_RCRAIDER:
+ case MI_RCGOBLIN:
+ case MI_TOPFUN:
+ case MI_CADDY:
+ case MI_BAGGAGE:
+ m_nRadioStation = RADIO_OFF;
+ break;
+ }
+
pHandling = mod_HandlingManager.GetHandlingData((tVehicleType)mi->m_handlingId);
+ pFlyingHandling = mod_HandlingManager.GetFlyingPointer((tVehicleType)mi->m_handlingId);
m_auto_unused1 = 20.0f;
m_auto_unused2 = 0;
@@ -131,6 +155,8 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy)
m_fElasticity = 0.05f;
m_fBuoyancy = pHandling->fBuoyancy;
+ m_fOrientation = m_fPlaneSteer = 0.0f;
+
m_nBusDoorTimerEnd = 0;
m_nBusDoorTimerStart = 0;
@@ -141,6 +167,9 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy)
m_fGasPedalAudio = 0.0f;
bNotDamagedUpsideDown = false;
bMoreResistantToDamage = false;
+ bTankDetonateCars = true;
+ bStuckInSand = false;
+ bHeliDestroyed = false;
m_fVelocityChangeForAudio = 0.0f;
m_hydraulicState = 0;
@@ -152,7 +181,7 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy)
m_aWheelRotation[i] = 0.0f;
m_aWheelSpeed[i] = 0.0f;
m_aWheelState[i] = WHEEL_STATE_NORMAL;
- m_aWheelSkidmarkMuddy[i] = false;
+ m_aWheelSkidmarkType[i] = SKIDMARK_NORMAL;
m_aWheelSkidmarkBloody[i] = false;
}
@@ -161,6 +190,7 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy)
m_nDriveWheelsOnGroundPrev = 0;
m_fHeightAboveRoad = 0.0f;
m_fTraction = 1.0f;
+ m_fTireTemperature = 1.0f;
CColModel *colModel = mi->GetColModel();
if(colModel->lines == nil){
@@ -175,10 +205,6 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy)
m_nNumPassengers = 0;
- m_bombType = CARBOMB_NONE;
- bDriverLastFrame = false;
- m_pBombRigger = nil;
-
if(m_nDoorLock == CARLOCK_UNLOCKED &&
(id == MI_POLICE || id == MI_ENFORCER || id == MI_RHINO))
m_nDoorLock = CARLOCK_LOCKED_INITIALLY;
@@ -186,6 +212,7 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy)
m_fCarGunLR = 0.0f;
m_fCarGunUD = 0.05f;
m_fPropellerRotation = 0.0f;
+ m_fHeliOrientation = -1.0f;
m_weaponDoorTimerLeft = 0.0f;
m_weaponDoorTimerRight = m_weaponDoorTimerLeft;
@@ -196,7 +223,10 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy)
CMatrix mat2(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_LF]));
mat1.GetPosition() += CVector(mat2.GetPosition().x + 0.1f, 0.0f, mat2.GetPosition().z);
mat1.UpdateRW();
- }else if(GetModelIndex() == MI_MIAMI_SPARROW || GetModelIndex() == MI_MIAMI_RCRAIDER){
+ }else if(GetModelIndex() == MI_HUNTER){
+ RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_LB]), 0);
+ RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_RB]), 0);
+ }else if(IsRealHeli()){
RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_LF]), 0);
RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_RF]), 0);
RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_LB]), 0);
@@ -207,7 +237,6 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy)
}
}
-
void
CAutomobile::SetModelIndex(uint32 id)
{
@@ -215,10 +244,16 @@ CAutomobile::SetModelIndex(uint32 id)
SetupModelNodes();
}
+#define SAND_SLOWDOWN (0.01f)
+float CAR_BALANCE_MULT = 0.3f;
+float HELI_ROTOR_DOTPROD_LIMIT = 0.95f;
+CVector vecSeaSparrowGunPos(-0.5f, 2.4f, -0.785f);
+CVector vecHunterGunPos(0.0f, 4.8f, -1.3f);
+CVector vecHunterRocketPos(2.5f, 1.0f, -0.5f);
CVector vecDAMAGE_ENGINE_POS_SMALL(-0.1f, -0.1f, 0.0f);
CVector vecDAMAGE_ENGINE_POS_BIG(-0.5f, -0.3f, 0.0f);
-#pragma optimize("", off) // that's what R* did
+#pragma optimize("", off) // a workaround for another compiler bug
void
CAutomobile::ProcessControl(void)
@@ -232,12 +267,25 @@ CAutomobile::ProcessControl(void)
colModel = &CWorld::Players[CWorld::PlayerInFocus].m_ColModel;
else
colModel = GetColModel();
+ bool drivingInSand = false;
bWarnedPeds = false;
+ m_doingBurnout = 0;
+ bStuckInSand = false;
+ bRestingOnPhysical = false;
- // skip if the collision isn't for the current level
- if(colModel->level > LEVEL_GENERIC && colModel->level != CCollision::ms_collisionInMemory)
+ bool carHasNitro = bAllTaxisHaveNitro && GetStatus() == STATUS_PLAYER && IsTaxi();
+
+ if(CReplay::IsPlayingBack())
return;
+ // Heli wind
+ if(IsRealHeli())
+ if((GetStatus() == STATUS_PLAYER || GetStatus() == STATUS_PHYSICS) && m_aWheelSpeed[1] > 0.075f ||
+ GetStatus() == STATUS_SIMPLE)
+ CWindModifiers::RegisterOne(GetPosition(), 1);
+
+ UpdatePassengerList();
+
// Improve grip of vehicles in certain cases
bool strongGrip1 = false;
bool strongGrip2 = false;
@@ -252,7 +300,8 @@ CAutomobile::ProcessControl(void)
strongGrip2 = true;
else if((GetPosition() - FindPlayerCoors()).Magnitude() > 50.0f)
strongGrip2 = true;
- }
+ }else if(GetModelIndex() == MI_RCBANDIT && GetStatus() != STATUS_PLAYER_REMOTE)
+ strongGrip1 = true;
if(bIsBus)
ProcessAutoBusDoors();
@@ -263,7 +312,7 @@ CAutomobile::ProcessControl(void)
if(GetStatus() != STATUS_ABANDONED && GetStatus() != STATUS_WRECKED &&
GetStatus() != STATUS_PLAYER && GetStatus() != STATUS_PLAYER_REMOTE && GetStatus() != STATUS_PLAYER_DISABLED){
switch(GetModelIndex())
- case MI_FBICAR:
+ case MI_FBIRANCH:
case MI_POLICE:
case MI_ENFORCER:
case MI_SECURICA:
@@ -273,25 +322,15 @@ CAutomobile::ProcessControl(void)
}
// Process driver
- 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;
-
+ if(pDriver)
if(IsUpsideDown() && CanPedEnterCar()){
if(!pDriver->IsPlayer() &&
!(pDriver->m_leader && pDriver->m_leader->bInVehicle) &&
pDriver->CharCreatedBy != MISSION_CHAR)
pDriver->SetObjective(OBJECTIVE_LEAVE_CAR, this);
}
- }else
- bDriverLastFrame = false;
+
+ ActivateBombWhenEntered();
// Process passengers
if(m_nNumPassengers != 0 && IsUpsideDown() && CanPedEnterCar()){
@@ -305,18 +344,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;
@@ -327,7 +355,18 @@ CAutomobile::ProcessControl(void)
else if(pHandling->Flags & HANDLING_NONPLAYER_STABILISER && GetStatus() == STATUS_PHYSICS)
m_vecCentreOfMass.z = pHandling->CentreOfMass.z - 0.2f*pHandling->Dimension.z;
else
- m_vecCentreOfMass.z = pHandling->CentreOfMass.z;
+ m_vecCentreOfMass = pHandling->CentreOfMass;
+
+ // Park car
+ if(bCanPark && !bParking && VehicleCreatedBy != MISSION_VEHICLE && AutoPilot.m_nCarMission == MISSION_CRUISE &&
+ ((CTimer::GetFrameCounter() + m_randomSeed)&0xF) == 0 && !IsTaxi()){
+ CVector parkPosition = GetPosition() + 3.0f*GetRight() + 10.0f*GetForward();
+ CEntity *ent = nil;
+ CColPoint colpoint;
+ if(!CWorld::ProcessLineOfSight(GetPosition(), parkPosition, colpoint, ent, true, true, true, false, false, false) ||
+ ent == this)
+ CCarAI::GetCarToParkAtCoors(this, &parkPosition);
+ }
// Process depending on status
@@ -335,20 +374,18 @@ CAutomobile::ProcessControl(void)
switch(GetStatus()){
case STATUS_PLAYER_REMOTE:
#ifdef FIX_BUGS
- if (CPad::GetPad(0)->CarGunJustDown()) {
+ if(CPad::GetPad(0)->CarGunJustDown() && !bDisableRemoteDetonation){
#else
- if (CPad::GetPad(0)->WeaponJustDown()) {
+ if(CPad::GetPad(0)->WeaponJustDown() && !bDisableRemoteDetonation){
#endif
BlowUpCar(FindPlayerPed());
CRemote::TakeRemoteControlledCarFromPlayer();
}
- if(GetModelIndex() == MI_RCBANDIT){
- CVector pos = GetPosition();
+ if(GetModelIndex() == MI_RCBANDIT && !bDisableRemoteDetonationOnContact){
+ //CVector pos = GetPosition();
// FindPlayerCoors unused
- if(RcbanditCheckHitWheels() || bIsInWater || CPopulation::IsPointInSafeZone(&pos)){
- if(CPopulation::IsPointInSafeZone(&pos))
- CGarages::TriggerMessage("HM2_5", -1, 5000, -1);
+ if(RcbanditCheckHitWheels() || bIsInWater){
CRemote::TakeRemoteControlledCarFromPlayer();
BlowUpCar(FindPlayerPed());
}
@@ -359,7 +396,7 @@ CAutomobile::ProcessControl(void)
// fall through
case STATUS_PLAYER:
if(playerRemote ||
- pDriver && pDriver->GetPedState() != PED_EXIT_CAR && pDriver->GetPedState() != PED_DRAG_FROM_CAR){
+ pDriver && pDriver->GetPedState() != PED_EXIT_CAR && pDriver->GetPedState() != PED_DRAG_FROM_CAR && pDriver->GetPedState() != PED_ARRESTED){
// process control input if controlled by player
if(playerRemote || pDriver->m_nPedType == PEDTYPE_PLAYER1)
ProcessControlInputs(0);
@@ -368,7 +405,59 @@ CAutomobile::ProcessControl(void)
if(GetStatus() == STATUS_PLAYER && !CRecordDataForChase::IsRecording())
DoDriveByShootings();
+
+ // Tweak center on mass when driving on two wheels
+ int twoWheelTime = CWorld::Players[CWorld::PlayerInFocus].m_nTimeNotFullyOnGround;
+ if(twoWheelTime > 500 && !IsRealHeli() && !IsRealPlane()){
+ float tweak = Min(twoWheelTime-500, 1000)/500.0f;
+ if(GetUp().z > 0.0f){
+ // positive when on left wheels, negative on right wheels
+ if(GetRight().z <= 0.0f)
+ tweak *= -1.0f;
+ m_vecCentreOfMass.z = pHandling->CentreOfMass.z +
+ CPad::GetPad(0)->GetSteeringLeftRight()/128.0f *
+ CAR_BALANCE_MULT * tweak * colModel->boundingBox.max.z;
+ }
+ }else
+ m_vecCentreOfMass.z = pHandling->CentreOfMass.z;
+
+ if(bHoverCheat)
+ DoHoverSuspensionRatios();
+
+ if(m_aSuspensionSpringRatio[0] < 1.0f && CSurfaceTable::GetAdhesionGroup(m_aWheelColPoints[0].surfaceB) == ADHESIVE_SAND ||
+ m_aSuspensionSpringRatio[1] < 1.0f && CSurfaceTable::GetAdhesionGroup(m_aWheelColPoints[1].surfaceB) == ADHESIVE_SAND ||
+ m_aSuspensionSpringRatio[2] < 1.0f && CSurfaceTable::GetAdhesionGroup(m_aWheelColPoints[2].surfaceB) == ADHESIVE_SAND ||
+ m_aSuspensionSpringRatio[3] < 1.0f && CSurfaceTable::GetAdhesionGroup(m_aWheelColPoints[3].surfaceB) == ADHESIVE_SAND){
+ if(GetModelIndex() != MI_RCBANDIT && GetModelIndex() != MI_RHINO){
+ float slowdown;
+ CVector parallelSpeed = m_vecMoveSpeed - DotProduct(m_vecMoveSpeed, GetUp())*GetUp();
+ float fSpeed = parallelSpeed.MagnitudeSqr();
+ if(fSpeed > SQR(0.3f)){
+ fSpeed = Sqrt(fSpeed);
+ parallelSpeed *= 0.3f / fSpeed;
+ slowdown = SAND_SLOWDOWN * Max(1.0f - 2.0f*fSpeed, 0.2f);
+ }else{
+ bStuckInSand = true;
+ slowdown = SAND_SLOWDOWN;
+ }
+ if(pHandling->Flags & HANDLING_GOOD_INSAND)
+ slowdown *= 0.5f;
+ if(CWeather::WetRoads > 0.2f)
+ slowdown *= (1.2f - CWeather::WetRoads);
+ ApplyMoveForce(parallelSpeed * -CTimer::GetTimeStep()*slowdown*m_fMass);
+ drivingInSand = true;
+ }
+ }
+ }else if(pDriver && pDriver->IsPlayer() &&
+ (pDriver->GetPedState() == PED_ARRESTED ||
+ pDriver->GetPedState() == PED_DRAG_FROM_CAR ||
+ (pDriver->GetPedState() == PED_EXIT_CAR || pDriver->m_objective == OBJECTIVE_LEAVE_CAR) && !CanPedJumpOutCar())){
+ bIsHandbrakeOn = true;
+ m_fBrakePedal = 1.0f;
+ m_fGasPedal = 0.0f;
}
+ if(CPad::GetPad(0)->CarGunJustDown())
+ ActivateBomb();
break;
case STATUS_SIMPLE:
@@ -389,6 +478,7 @@ CAutomobile::ProcessControl(void)
PlayHornIfNecessary();
ReduceHornCounter();
bVehicleColProcessed = false;
+ bAudioChangingGear = false;
// that's all we do for simple vehicles
return;
@@ -396,15 +486,44 @@ CAutomobile::ProcessControl(void)
CCarAI::UpdateCarAI(this);
CCarCtrl::SteerAICarWithPhysics(this);
PlayHornIfNecessary();
+
+ if(bIsBeingCarJacked){
+ m_fGasPedal = 0.0f;
+ m_fBrakePedal = 1.0f;
+ bIsHandbrakeOn = true;
+ }
+
+ if(m_aSuspensionSpringRatio[0] < 1.0f && CSurfaceTable::GetAdhesionGroup(m_aWheelColPoints[0].surfaceB) == ADHESIVE_SAND ||
+ m_aSuspensionSpringRatio[1] < 1.0f && CSurfaceTable::GetAdhesionGroup(m_aWheelColPoints[1].surfaceB) == ADHESIVE_SAND ||
+ m_aSuspensionSpringRatio[2] < 1.0f && CSurfaceTable::GetAdhesionGroup(m_aWheelColPoints[2].surfaceB) == ADHESIVE_SAND ||
+ m_aSuspensionSpringRatio[3] < 1.0f && CSurfaceTable::GetAdhesionGroup(m_aWheelColPoints[3].surfaceB) == ADHESIVE_SAND){
+ if(GetModelIndex() != MI_RCBANDIT && GetModelIndex() != MI_SANDKING && GetModelIndex() != MI_BFINJECT){
+ bStuckInSand = true;
+ if(CWeather::WetRoads > 0.0f)
+ ApplyMoveForce(m_vecMoveSpeed * -CTimer::GetTimeStep()*SAND_SLOWDOWN*m_fMass * (1.0f-CWeather::WetRoads));
+ else
+ ApplyMoveForce(m_vecMoveSpeed * -CTimer::GetTimeStep()*SAND_SLOWDOWN*m_fMass);
+ }
+ }
break;
case STATUS_ABANDONED:
- m_fBrakePedal = 0.2f;
+ if(m_vecMoveSpeed.MagnitudeSqr() < SQR(0.1f))
+ m_fBrakePedal = 0.2f;
+ else
+ m_fBrakePedal = 0.0f;
bIsHandbrakeOn = false;
m_fSteerAngle = 0.0f;
m_fGasPedal = 0.0f;
- m_nCarHornTimer = 0;
+ if(!IsAlarmOn())
+ m_nCarHornTimer = 0;
+
+ if(bIsBeingCarJacked){
+ m_fGasPedal = 0.0f;
+ m_fBrakePedal = 1.0f;
+ bIsHandbrakeOn = true;
+ }
break;
case STATUS_WRECKED:
@@ -413,26 +532,32 @@ CAutomobile::ProcessControl(void)
m_fSteerAngle = 0.0f;
m_fGasPedal = 0.0f;
- m_nCarHornTimer = 0;
+ if(!IsAlarmOn())
+ m_nCarHornTimer = 0;
break;
case STATUS_PLAYER_DISABLED:
- m_fBrakePedal = 1.0f;
- bIsHandbrakeOn = true;
+ if(m_vecMoveSpeed.MagnitudeSqr() < SQR(0.1f) ||
+ (pDriver && pDriver->IsPlayer() &&
+ (pDriver->GetPedState() == PED_ARRESTED ||
+ pDriver->GetPedState() == PED_DRAG_FROM_CAR ||
+ (pDriver->GetPedState() == PED_EXIT_CAR || pDriver->m_objective == OBJECTIVE_LEAVE_CAR) && !CanPedJumpOutCar()))){
+ bIsHandbrakeOn = true;
+ m_fBrakePedal = 1.0f;
+ m_fGasPedal = 0.0f;
+ }else{
+ m_fBrakePedal = 0.0f;
+ bIsHandbrakeOn = false;
+ }
m_fSteerAngle = 0.0f;
m_fGasPedal = 0.0f;
- m_nCarHornTimer = 0;
+ if(!IsAlarmOn())
+ m_nCarHornTimer = 0;
break;
default: break;
}
- // what's going on here?
- if(GetPosition().z < -0.6f &&
- Abs(m_vecMoveSpeed.x) < 0.05f &&
- Abs(m_vecMoveSpeed.y) < 0.05f)
- m_vecTurnSpeed *= Pow(0.95f, CTimer::GetTimeStep());
-
// Skip physics if object is found to have been static recently
bool skipPhysics = false;
if(!bIsStuck && (GetStatus() == STATUS_ABANDONED || GetStatus() == STATUS_WRECKED)){
@@ -460,7 +585,8 @@ CAutomobile::ProcessControl(void)
if(m_vecMoveSpeedAvg.MagnitudeSqr() <= sq(moveSpeedLimit*CTimer::GetTimeStep()) &&
m_vecTurnSpeedAvg.MagnitudeSqr() <= sq(turnSpeedLimit*CTimer::GetTimeStep()) &&
- m_fDistanceTravelled < distanceLimit ||
+ m_fDistanceTravelled < distanceLimit &&
+ !(m_fDamageImpulse > 0.0f && m_pDamageEntity && m_pDamageEntity->IsPed()) ||
makeStatic){
m_nStaticFrames++;
@@ -476,15 +602,27 @@ CAutomobile::ProcessControl(void)
}
}else
m_nStaticFrames = 0;
+ if(IsRealHeli() && m_aWheelSpeed[1] > 0.0f){
+ skipPhysics = false;
+ m_nStaticFrames = 0;
+ }
}
// Postpone
for(i = 0; i < 4; i++)
- if(m_aGroundPhysical[i] && !CWorld::bForceProcessControl && m_aGroundPhysical[i]->bIsInSafePosition){
- bWasPostponed = true;
- return;
+ if(m_aGroundPhysical[i]){
+ bRestingOnPhysical = true;
+ if(!CWorld::bForceProcessControl && m_aGroundPhysical[i]->bIsInSafePosition){
+ bWasPostponed = true;
+ return;
+ }
}
+ if(bRestingOnPhysical){
+ skipPhysics = false;
+ m_nStaticFrames = 0;
+ }
+
VehicleDamage(0.0f, 0);
// special control
@@ -496,12 +634,11 @@ CAutomobile::ProcessControl(void)
TankControl();
BlowUpCarsInPath();
break;
- case MI_YARDIE:
- // beta also had esperanto here it seems
+ case MI_VOODOO:
HydraulicControl();
break;
default:
- if(CVehicle::bCheat3){
+ if(CVehicle::bCheat3 || carHasNitro){
// Make vehicle jump when horn is sounded
if(GetStatus() == STATUS_PLAYER && m_vecMoveSpeed.MagnitudeSqr() > sq(0.2f) &&
// BUG: game checks [0] four times, instead of all wheels
@@ -540,12 +677,17 @@ CAutomobile::ProcessControl(void)
1.2f*m_vecMoveSpeed, nil, 2.0f);
ApplyMoveForce(CVector(0.0f, 0.0f, 1.0f)*m_fMass*0.4f);
- ApplyTurnForce(GetUp()*m_fMass*0.035f, GetForward()*1.0f);
+ ApplyTurnForce(GetUp()*m_fTurnMass*0.01f, GetForward()*1.0f);
}
}
break;
}
+ if(GetStatus() == STATUS_PHYSICS || GetStatus() == STATUS_SIMPLE)
+ if(AutoPilot.m_nCarMission == MISSION_HELI_FLYTOCOORS ||
+ AutoPilot.m_nCarMission == MISSION_PLANE_FLYTOCOORS)
+ skipPhysics = true;
+
if(skipPhysics){
bHasContacted = false;
bIsInSafePosition = false;
@@ -554,11 +696,13 @@ CAutomobile::ProcessControl(void)
m_nCollisionRecords = 0;
bHasCollided = false;
bVehicleColProcessed = false;
+ bAudioChangingGear = false;
m_nDamagePieceType = 0;
m_fDamageImpulse = 0.0f;
m_pDamageEntity = nil;
m_vecTurnFriction = CVector(0.0f, 0.0f, 0.0f);
m_vecMoveFriction = CVector(0.0f, 0.0f, 0.0f);
+ m_fTireTemperature = 1.0f;
}else{
// This has to be done if ProcessEntityCollision wasn't called
@@ -611,6 +755,14 @@ CAutomobile::ProcessControl(void)
if(m_aSuspensionSpringRatio[i] > 1.0f)
m_aSuspensionSpringRatio[i] = 1.0f;
}
+ }else if(CSurfaceTable::GetAdhesionGroup(m_aWheelColPoints[i].surfaceB) == ADHESIVE_SAND &&
+ GetModelIndex() != MI_RHINO){
+ fwdSpeed *= 0.7f;
+ float f = 1.0f - fwdSpeed/0.3f - 0.7f*CWeather::WetRoads;
+ f = Max(f, 0.4f);
+ m_aSuspensionSpringRatio[i] += 0.35f*f*(m_aSuspensionLineLength[i]-m_aSuspensionSpringLength[i])/m_aSuspensionSpringLength[i];
+ if(m_aSuspensionSpringRatio[i] > 1.0f)
+ m_aSuspensionSpringRatio[i] = 1.0f;
}
// get points and directions if spring is compressed
@@ -628,13 +780,20 @@ CAutomobile::ProcessControl(void)
if(i == CARWHEEL_REAR_LEFT || i == CARWHEEL_REAR_RIGHT)
bias = 1.0f - bias;
- ApplySpringCollision(pHandling->fSuspensionForceLevel,
+ ApplySpringCollisionAlt(pHandling->fSuspensionForceLevel,
springDirections[i], contactPoints[i],
- m_aSuspensionSpringRatio[i], bias);
- m_aWheelSkidmarkMuddy[i] =
- m_aWheelColPoints[i].surfaceB == SURFACE_GRASS ||
- m_aWheelColPoints[i].surfaceB == SURFACE_MUD_DRY ||
- m_aWheelColPoints[i].surfaceB == SURFACE_SAND;
+ m_aSuspensionSpringRatio[i], bias, m_aWheelColPoints[i].normal);
+
+ m_aWheelSkidmarkUnk[i] = false;
+ if(m_aWheelColPoints[i].surfaceB == SURFACE_GRASS ||
+ m_aWheelColPoints[i].surfaceB == SURFACE_MUD_DRY)
+ m_aWheelSkidmarkType[i] = SKIDMARK_MUDDY;
+ else if(m_aWheelColPoints[i].surfaceB == SURFACE_SAND ||
+ m_aWheelColPoints[i].surfaceB == SURFACE_SAND_BEACH){
+ m_aWheelSkidmarkType[i] = SKIDMARK_SANDY;
+ m_aWheelSkidmarkUnk[i] = true;
+ }else
+ m_aWheelSkidmarkType[i] = SKIDMARK_NORMAL;
}else{
contactPoints[i] = Multiply3x3(GetMatrix(), colModel->lines[i].p1);
}
@@ -651,11 +810,13 @@ CAutomobile::ProcessControl(void)
m_aGroundPhysical[i] = nil;
#endif
}
+ if(m_aSuspensionSpringRatio[i] < 1.0f && m_aWheelColPoints[i].normal.z > 0.35f)
+ springDirections[i] = -m_aWheelColPoints[i].normal;
}
// dampen springs
for(i = 0; i < 4; i++)
- if(m_aSuspensionSpringRatio[i] < 1.0f)
+ if(m_aSuspensionSpringRatio[i] < 0.99999f)
ApplySpringDampening(pHandling->fSuspensionDampingLevel,
springDirections[i], contactPoints[i], contactSpeeds[i]);
@@ -669,7 +830,6 @@ CAutomobile::ProcessControl(void)
}
}
-
bool gripCheat = true;
fwdSpeed = DotProduct(m_vecMoveSpeed, GetForward());
if(!strongGrip1 && !CVehicle::bCheat3)
@@ -677,16 +837,32 @@ CAutomobile::ProcessControl(void)
float acceleration = pHandling->Transmission.CalculateDriveAcceleration(m_fGasPedal, m_nCurrentGear, m_fChangeGearTime, fwdSpeed, gripCheat);
acceleration /= m_fForceMultiplier;
- // unused
- if(GetModelIndex() == MI_MIAMI_RCBARON ||
- GetModelIndex() == MI_MIAMI_RCRAIDER ||
- GetModelIndex() == MI_MIAMI_SPARROW)
+ if(IsRealHeli() || IsRealPlane())
acceleration = 0.0f;
+ if(bAudioChangingGear && m_fGasPedal > 0.4f && m_fBrakePedal < 0.1f && fwdSpeed > 0.15f &&
+ this == FindPlayerVehicle() && TheCamera.Cams[TheCamera.ActiveCam].Mode != CCam::MODE_1STPERSON){
+ if(GetStatus() == STATUS_PLAYER && !(pHandling->Flags & HANDLING_IS_BUS)){
+ if(m_nBusDoorTimerEnd == 0)
+ m_nBusDoorTimerEnd = 1000;
+ else {
+ uint32 timeStepInMs = CTimer::GetTimeStepInMilliseconds();
+ if(m_nBusDoorTimerEnd > timeStepInMs)
+ m_nBusDoorTimerEnd -= timeStepInMs;
+ else
+ m_nBusDoorTimerEnd = 0;
+ }
+ }
+
+ if((m_aSuspensionSpringRatio[0] < 1.0f || m_aSuspensionSpringRatio[2] < 1.0f) &&
+ (m_aSuspensionSpringRatio[1] < 1.0f || m_aSuspensionSpringRatio[3] < 1.0f))
+ ApplyTurnForce(-GRAVITY*Min(m_fTurnMass, 2500.0f)*GetUp(), -1.0f*GetForward());
+ }
+
brake = m_fBrakePedal * pHandling->fBrakeDeceleration * CTimer::GetTimeStep();
- bool neutralHandling = !!(pHandling->Flags & HANDLING_NEUTRALHANDLING);
+ bool neutralHandling = GetStatus() != STATUS_PLAYER && GetStatus() != STATUS_PLAYER_REMOTE && (pHandling->Flags & HANDLING_NEUTRALHANDLING);
float brakeBiasFront = neutralHandling ? 1.0f : 2.0f*pHandling->fBrakeBias;
- float brakeBiasRear = neutralHandling ? 1.0f : 2.0f*(1.0f-pHandling->fBrakeBias);
+ float brakeBiasRear = neutralHandling ? 1.0f : 2.0f-pHandling->fBrakeBias; // looks like a bug, but it was correct in III...
float tractionBiasFront = neutralHandling ? 1.0f : 2.0f*pHandling->fTractionBias;
float tractionBiasRear = neutralHandling ? 1.0f : 2.0f-tractionBiasFront;
@@ -730,21 +906,7 @@ CAutomobile::ProcessControl(void)
if(CVehicle::bCheat3)
traction *= 4.0f;
- if(FindPlayerVehicle() && FindPlayerVehicle() == this){
- if(CPad::GetPad(0)->CarGunJustDown()){
- 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);
- }
- }
- }else if(strongGrip1 || CVehicle::bCheat3){
+ if(FindPlayerVehicle() != this && (strongGrip1 || CVehicle::bCheat3)){
traction *= 1.2f;
acceleration *= 1.4f;
if(strongGrip2 || CVehicle::bCheat3){
@@ -756,13 +918,16 @@ CAutomobile::ProcessControl(void)
static float fThrust;
static tWheelState WheelState[4];
- // Process front wheels on ground
+ bool rearWheelsFirst = !!(pHandling->Flags & HANDLING_REARWHEEL_1ST);
+ // Process front wheels on ground - first try
+
+ if(!rearWheelsFirst){
if(m_aWheelTimer[CARWHEEL_FRONT_LEFT] > 0.0f || m_aWheelTimer[CARWHEEL_FRONT_RIGHT] > 0.0f){
float s = Sin(m_fSteerAngle);
float c = Cos(m_fSteerAngle);
- CVector wheelFwd = Multiply3x3(GetMatrix(), CVector(-s, c, 0.0f));
- CVector wheelRight = Multiply3x3(GetMatrix(), CVector(c, s, 0.0f));
+
+ CVector wheelFwd, wheelRight, tmp;
if(m_aWheelTimer[CARWHEEL_FRONT_LEFT] > 0.0f){
if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier))
@@ -770,6 +935,15 @@ CAutomobile::ProcessControl(void)
else
fThrust = 0.0f;
+ wheelFwd = GetForward();
+ wheelFwd -= DotProduct(wheelFwd, m_aWheelColPoints[CARWHEEL_FRONT_LEFT].normal)*m_aWheelColPoints[CARWHEEL_FRONT_LEFT].normal;
+ wheelFwd.Normalise();
+ wheelRight = CrossProduct(wheelFwd, m_aWheelColPoints[CARWHEEL_FRONT_LEFT].normal);
+ wheelRight.Normalise();
+ tmp = c*wheelFwd - s*wheelRight;
+ wheelRight = s*wheelFwd + c*wheelRight;
+ wheelFwd = tmp;
+
m_aWheelColPoints[CARWHEEL_FRONT_LEFT].surfaceA = SURFACE_WHEELBASE;
float adhesion = CSurfaceTable::GetAdhesiveLimit(m_aWheelColPoints[CARWHEEL_FRONT_LEFT])*traction;
if(GetStatus() == STATUS_PLAYER)
@@ -804,6 +978,15 @@ CAutomobile::ProcessControl(void)
else
fThrust = 0.0f;
+ wheelFwd = GetForward();
+ wheelFwd -= DotProduct(wheelFwd, m_aWheelColPoints[CARWHEEL_FRONT_RIGHT].normal)*m_aWheelColPoints[CARWHEEL_FRONT_RIGHT].normal;
+ wheelFwd.Normalise();
+ wheelRight = CrossProduct(wheelFwd, m_aWheelColPoints[CARWHEEL_FRONT_RIGHT].normal);
+ wheelRight.Normalise();
+ tmp = c*wheelFwd - s*wheelRight;
+ wheelRight = s*wheelFwd + c*wheelRight;
+ wheelFwd = tmp;
+
m_aWheelColPoints[CARWHEEL_FRONT_RIGHT].surfaceA = SURFACE_WHEELBASE;
float adhesion = CSurfaceTable::GetAdhesiveLimit(m_aWheelColPoints[CARWHEEL_FRONT_RIGHT])*traction;
if(GetStatus() == STATUS_PLAYER)
@@ -835,49 +1018,66 @@ CAutomobile::ProcessControl(void)
// Process front wheels off ground
- if(m_aWheelTimer[CARWHEEL_FRONT_LEFT] <= 0.0f){
- if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier) && acceleration != 0.0f){
- if(acceleration > 0.0f){
- if(m_aWheelSpeed[CARWHEEL_FRONT_LEFT] < 2.0f)
- m_aWheelSpeed[CARWHEEL_FRONT_LEFT] -= 0.2f;
+ if(!IsRealHeli()){
+ if(m_aWheelTimer[CARWHEEL_FRONT_LEFT] <= 0.0f){
+ if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier) && acceleration != 0.0f){
+ if(acceleration > 0.0f){
+ if(m_aWheelSpeed[CARWHEEL_FRONT_LEFT] < 2.0f)
+ m_aWheelSpeed[CARWHEEL_FRONT_LEFT] -= 0.2f;
+ }else{
+ if(m_aWheelSpeed[CARWHEEL_FRONT_LEFT] > -2.0f)
+ m_aWheelSpeed[CARWHEEL_FRONT_LEFT] += 0.1f;
+ }
}else{
- if(m_aWheelSpeed[CARWHEEL_FRONT_LEFT] > -2.0f)
- m_aWheelSpeed[CARWHEEL_FRONT_LEFT] += 0.1f;
+ m_aWheelSpeed[CARWHEEL_FRONT_LEFT] *= 0.95f;
}
- }else{
- m_aWheelSpeed[CARWHEEL_FRONT_LEFT] *= 0.95f;
+ m_aWheelRotation[CARWHEEL_FRONT_LEFT] += m_aWheelSpeed[CARWHEEL_FRONT_LEFT];
}
- m_aWheelRotation[CARWHEEL_FRONT_LEFT] += m_aWheelSpeed[CARWHEEL_FRONT_LEFT];
- }
- if(m_aWheelTimer[CARWHEEL_FRONT_RIGHT] <= 0.0f){
- if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier) && acceleration != 0.0f){
- if(acceleration > 0.0f){
- if(m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] < 2.0f)
- m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] -= 0.2f;
+ if(m_aWheelTimer[CARWHEEL_FRONT_RIGHT] <= 0.0f){
+ if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier) && acceleration != 0.0f){
+ if(acceleration > 0.0f){
+ if(m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] < 2.0f)
+ m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] -= 0.2f;
+ }else{
+ if(m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] > -2.0f)
+ m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] += 0.1f;
+ }
}else{
- if(m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] > -2.0f)
- m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] += 0.1f;
+ m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] *= 0.95f;
}
- }else{
- m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] *= 0.95f;
+ m_aWheelRotation[CARWHEEL_FRONT_RIGHT] += m_aWheelSpeed[CARWHEEL_FRONT_RIGHT];
}
- m_aWheelRotation[CARWHEEL_FRONT_RIGHT] += m_aWheelSpeed[CARWHEEL_FRONT_RIGHT];
+ }
}
// Process rear wheels
if(m_aWheelTimer[CARWHEEL_REAR_LEFT] > 0.0f || m_aWheelTimer[CARWHEEL_REAR_RIGHT] > 0.0f){
CVector wheelFwd = GetForward();
- CVector wheelRight = GetRight();
+ CVector wheelRight = GetRight(); // overwritten for resp. wheel
+ float rearBrake = brake;
+ float rearTraction = traction;
+ if(bIsHandbrakeOn){
#ifdef FIX_BUGS
- // Not sure if this is needed, but brake usually has timestep as a factor
- if(bIsHandbrakeOn)
- brake = 20000.0f * CTimer::GetTimeStepFix();
+ // Not sure if this is needed, but brake usually has timestep as a factor
+ rearBrake = 20000.0f * CTimer::GetTimeStepFix();
#else
- if(bIsHandbrakeOn)
- brake = 20000.0f;
+ rearBrake = 20000.0f;
#endif
+ if(fwdSpeed > 0.1f && pHandling->Flags & HANDLING_HANDBRAKE_TYRE){
+ m_fTireTemperature += 0.005*CTimer::GetTimeStep();
+ if(m_fTireTemperature > 2.0f)
+ m_fTireTemperature = 2.0f;
+ }
+ }else if(m_doingBurnout && mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier)){
+ rearBrake = 0.0f;
+ rearTraction = 0.0f;
+ // BUG: missing timestep
+ ApplyTurnForce(contactPoints[CARWHEEL_REAR_LEFT], -0.001f*m_fTurnMass*m_fSteerAngle*GetRight());
+ }else if(m_fTireTemperature > 1.0f){
+ rearTraction *= m_fTireTemperature;
+ }
if(m_aWheelTimer[CARWHEEL_REAR_LEFT] > 0.0f){
if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier))
@@ -885,8 +1085,13 @@ CAutomobile::ProcessControl(void)
else
fThrust = 0.0f;
+ wheelFwd -= DotProduct(wheelFwd, m_aWheelColPoints[CARWHEEL_REAR_LEFT].normal)*m_aWheelColPoints[CARWHEEL_REAR_LEFT].normal;
+ wheelFwd.Normalise();
+ wheelRight = CrossProduct(wheelFwd, m_aWheelColPoints[CARWHEEL_REAR_LEFT].normal);
+ wheelRight.Normalise();
+
m_aWheelColPoints[CARWHEEL_REAR_LEFT].surfaceA = SURFACE_WHEELBASE;
- float adhesion = CSurfaceTable::GetAdhesiveLimit(m_aWheelColPoints[CARWHEEL_REAR_LEFT])*traction;
+ float adhesion = CSurfaceTable::GetAdhesiveLimit(m_aWheelColPoints[CARWHEEL_REAR_LEFT])*rearTraction;
if(GetStatus() == STATUS_PLAYER)
adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[CARWHEEL_REAR_LEFT].surfaceB);
WheelState[CARWHEEL_REAR_LEFT] = m_aWheelState[CARWHEEL_REAR_LEFT];
@@ -895,7 +1100,7 @@ CAutomobile::ProcessControl(void)
ProcessWheel(wheelFwd, wheelRight,
contactSpeeds[CARWHEEL_REAR_LEFT], contactPoints[CARWHEEL_REAR_LEFT],
m_nWheelsOnGround, fThrust,
- brake*brakeBiasRear,
+ rearBrake*brakeBiasRear,
adhesion*tractionBiasRear*Damage.m_fWheelDamageEffect,
CARWHEEL_REAR_LEFT,
&m_aWheelSpeed[CARWHEEL_REAR_LEFT],
@@ -905,7 +1110,7 @@ CAutomobile::ProcessControl(void)
ProcessWheel(wheelFwd, wheelRight,
contactSpeeds[CARWHEEL_REAR_LEFT], contactPoints[CARWHEEL_REAR_LEFT],
m_nWheelsOnGround, fThrust,
- brake*brakeBiasRear,
+ rearBrake*brakeBiasRear,
adhesion*tractionBiasRear,
CARWHEEL_REAR_LEFT,
&m_aWheelSpeed[CARWHEEL_REAR_LEFT],
@@ -913,14 +1118,25 @@ CAutomobile::ProcessControl(void)
WHEEL_STATUS_OK);
}
+#ifdef FIX_BUGS
+ // Shouldn't we reset these after the left wheel?
+ wheelFwd = GetForward();
+ wheelRight = GetRight(); // actually useless
+#endif
+
if(m_aWheelTimer[CARWHEEL_REAR_RIGHT] > 0.0f){
if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier))
fThrust = acceleration;
else
fThrust = 0.0f;
+ wheelFwd -= DotProduct(wheelFwd, m_aWheelColPoints[CARWHEEL_REAR_RIGHT].normal)*m_aWheelColPoints[CARWHEEL_REAR_RIGHT].normal;
+ wheelFwd.Normalise();
+ wheelRight = CrossProduct(wheelFwd, m_aWheelColPoints[CARWHEEL_REAR_RIGHT].normal);
+ wheelRight.Normalise();
+
m_aWheelColPoints[CARWHEEL_REAR_RIGHT].surfaceA = SURFACE_WHEELBASE;
- float adhesion = CSurfaceTable::GetAdhesiveLimit(m_aWheelColPoints[CARWHEEL_REAR_RIGHT])*traction;
+ float adhesion = CSurfaceTable::GetAdhesiveLimit(m_aWheelColPoints[CARWHEEL_REAR_RIGHT])*rearTraction;
if(GetStatus() == STATUS_PLAYER)
adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[CARWHEEL_REAR_RIGHT].surfaceB);
WheelState[CARWHEEL_REAR_RIGHT] = m_aWheelState[CARWHEEL_REAR_RIGHT];
@@ -929,7 +1145,7 @@ CAutomobile::ProcessControl(void)
ProcessWheel(wheelFwd, wheelRight,
contactSpeeds[CARWHEEL_REAR_RIGHT], contactPoints[CARWHEEL_REAR_RIGHT],
m_nWheelsOnGround, fThrust,
- brake*brakeBiasRear,
+ rearBrake*brakeBiasRear,
adhesion*tractionBiasRear*Damage.m_fWheelDamageEffect,
CARWHEEL_REAR_RIGHT,
&m_aWheelSpeed[CARWHEEL_REAR_RIGHT],
@@ -939,7 +1155,7 @@ CAutomobile::ProcessControl(void)
ProcessWheel(wheelFwd, wheelRight,
contactSpeeds[CARWHEEL_REAR_RIGHT], contactPoints[CARWHEEL_REAR_RIGHT],
m_nWheelsOnGround, fThrust,
- brake*brakeBiasRear,
+ rearBrake*brakeBiasRear,
adhesion*tractionBiasRear,
CARWHEEL_REAR_RIGHT,
&m_aWheelSpeed[CARWHEEL_REAR_RIGHT],
@@ -948,58 +1164,207 @@ CAutomobile::ProcessControl(void)
}
}
+ if(m_doingBurnout && mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier) &&
+ (m_aWheelState[CARWHEEL_REAR_LEFT] == WHEEL_STATE_SPINNING || m_aWheelState[CARWHEEL_REAR_RIGHT] == WHEEL_STATE_SPINNING)){
+ m_fTireTemperature += 0.001f*CTimer::GetTimeStep();
+ if(m_fTireTemperature > 3.0f)
+ m_fTireTemperature = 3.0f;
+ }else if(m_fTireTemperature > 1.0f){
+ m_fTireTemperature = (m_fTireTemperature - 1.0f)*Pow(0.995f, CTimer::GetTimeStep()) + 1.0f;
+ }
+
// Process rear wheels off ground
- if(m_aWheelTimer[CARWHEEL_REAR_LEFT] <= 0.0f){
- if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier) && acceleration != 0.0f){
- if(acceleration > 0.0f){
- if(m_aWheelSpeed[CARWHEEL_REAR_LEFT] < 2.0f)
- m_aWheelSpeed[CARWHEEL_REAR_LEFT] -= 0.2f;
+ if(!IsRealHeli()){
+ if(m_aWheelTimer[CARWHEEL_REAR_LEFT] <= 0.0f){
+ if(bIsHandbrakeOn)
+ m_aWheelSpeed[CARWHEEL_REAR_LEFT] = 0.0f;
+ else if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier) && acceleration != 0.0f){
+ if(acceleration > 0.0f){
+ if(m_aWheelSpeed[CARWHEEL_REAR_LEFT] < 2.0f)
+ m_aWheelSpeed[CARWHEEL_REAR_LEFT] -= 0.2f;
+ }else{
+ if(m_aWheelSpeed[CARWHEEL_REAR_LEFT] > -2.0f)
+ m_aWheelSpeed[CARWHEEL_REAR_LEFT] += 0.1f;
+ }
}else{
- if(m_aWheelSpeed[CARWHEEL_REAR_LEFT] > -2.0f)
- m_aWheelSpeed[CARWHEEL_REAR_LEFT] += 0.1f;
+ m_aWheelSpeed[CARWHEEL_REAR_LEFT] *= 0.95f;
}
- }else{
- m_aWheelSpeed[CARWHEEL_REAR_LEFT] *= 0.95f;
+ m_aWheelRotation[CARWHEEL_REAR_LEFT] += m_aWheelSpeed[CARWHEEL_REAR_LEFT];
+ }
+ if(m_aWheelTimer[CARWHEEL_REAR_RIGHT] <= 0.0f){
+ if(bIsHandbrakeOn)
+ m_aWheelSpeed[CARWHEEL_REAR_RIGHT] = 0.0f;
+ else if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier) && acceleration != 0.0f){
+ if(acceleration > 0.0f){
+ if(m_aWheelSpeed[CARWHEEL_REAR_RIGHT] < 2.0f)
+ m_aWheelSpeed[CARWHEEL_REAR_RIGHT] -= 0.2f;
+ }else{
+ if(m_aWheelSpeed[CARWHEEL_REAR_RIGHT] > -2.0f)
+ m_aWheelSpeed[CARWHEEL_REAR_RIGHT] += 0.1f;
+ }
+ }else{
+ m_aWheelSpeed[CARWHEEL_REAR_RIGHT] *= 0.95f;
+ }
+ m_aWheelRotation[CARWHEEL_REAR_RIGHT] += m_aWheelSpeed[CARWHEEL_REAR_RIGHT];
+ }
+ }
+
+ // Process front wheels on ground - second try
+
+ if(rearWheelsFirst){
+ if(m_aWheelTimer[CARWHEEL_FRONT_LEFT] > 0.0f || m_aWheelTimer[CARWHEEL_FRONT_RIGHT] > 0.0f){
+ float s = Sin(m_fSteerAngle);
+ float c = Cos(m_fSteerAngle);
+
+ CVector wheelFwd, wheelRight, tmp;
+
+ if(m_aWheelTimer[CARWHEEL_FRONT_LEFT] > 0.0f){
+ if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier))
+ fThrust = acceleration;
+ else
+ fThrust = 0.0f;
+
+ wheelFwd = GetForward();
+ wheelFwd -= DotProduct(wheelFwd, m_aWheelColPoints[CARWHEEL_FRONT_LEFT].normal)*m_aWheelColPoints[CARWHEEL_FRONT_LEFT].normal;
+ wheelFwd.Normalise();
+ wheelRight = CrossProduct(wheelFwd, m_aWheelColPoints[CARWHEEL_FRONT_LEFT].normal);
+ wheelRight.Normalise();
+ tmp = c*wheelFwd - s*wheelRight;
+ wheelRight = s*wheelFwd + c*wheelRight;
+ wheelFwd = tmp;
+
+ 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);
+ WheelState[CARWHEEL_FRONT_LEFT] = m_aWheelState[CARWHEEL_FRONT_LEFT];
+
+ if(Damage.GetWheelStatus(CARWHEEL_FRONT_LEFT) == WHEEL_STATUS_BURST)
+ ProcessWheel(wheelFwd, wheelRight,
+ contactSpeeds[CARWHEEL_FRONT_LEFT], contactPoints[CARWHEEL_FRONT_LEFT],
+ m_nWheelsOnGround, fThrust,
+ brake*brakeBiasFront,
+ adhesion*tractionBiasFront*Damage.m_fWheelDamageEffect,
+ CARWHEEL_FRONT_LEFT,
+ &m_aWheelSpeed[CARWHEEL_FRONT_LEFT],
+ &WheelState[CARWHEEL_FRONT_LEFT],
+ WHEEL_STATUS_BURST);
+ else
+ ProcessWheel(wheelFwd, wheelRight,
+ contactSpeeds[CARWHEEL_FRONT_LEFT], contactPoints[CARWHEEL_FRONT_LEFT],
+ m_nWheelsOnGround, fThrust,
+ brake*brakeBiasFront,
+ adhesion*tractionBiasFront,
+ CARWHEEL_FRONT_LEFT,
+ &m_aWheelSpeed[CARWHEEL_FRONT_LEFT],
+ &WheelState[CARWHEEL_FRONT_LEFT],
+ WHEEL_STATUS_OK);
+ }
+
+ if(m_aWheelTimer[CARWHEEL_FRONT_RIGHT] > 0.0f){
+ if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier))
+ fThrust = acceleration;
+ else
+ fThrust = 0.0f;
+
+ wheelFwd = GetForward();
+ wheelFwd -= DotProduct(wheelFwd, m_aWheelColPoints[CARWHEEL_FRONT_RIGHT].normal)*m_aWheelColPoints[CARWHEEL_FRONT_RIGHT].normal;
+ wheelFwd.Normalise();
+ wheelRight = CrossProduct(wheelFwd, m_aWheelColPoints[CARWHEEL_FRONT_RIGHT].normal);
+ wheelRight.Normalise();
+ tmp = c*wheelFwd - s*wheelRight;
+ wheelRight = s*wheelFwd + c*wheelRight;
+ wheelFwd = tmp;
+
+ 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);
+ WheelState[CARWHEEL_FRONT_RIGHT] = m_aWheelState[CARWHEEL_FRONT_RIGHT];
+
+ if(Damage.GetWheelStatus(CARWHEEL_FRONT_RIGHT) == WHEEL_STATUS_BURST)
+ ProcessWheel(wheelFwd, wheelRight,
+ contactSpeeds[CARWHEEL_FRONT_RIGHT], contactPoints[CARWHEEL_FRONT_RIGHT],
+ m_nWheelsOnGround, fThrust,
+ brake*brakeBiasFront,
+ adhesion*tractionBiasFront*Damage.m_fWheelDamageEffect,
+ CARWHEEL_FRONT_RIGHT,
+ &m_aWheelSpeed[CARWHEEL_FRONT_RIGHT],
+ &WheelState[CARWHEEL_FRONT_RIGHT],
+ WHEEL_STATUS_BURST);
+ else
+ ProcessWheel(wheelFwd, wheelRight,
+ contactSpeeds[CARWHEEL_FRONT_RIGHT], contactPoints[CARWHEEL_FRONT_RIGHT],
+ m_nWheelsOnGround, fThrust,
+ brake*brakeBiasFront,
+ adhesion*tractionBiasFront,
+ CARWHEEL_FRONT_RIGHT,
+ &m_aWheelSpeed[CARWHEEL_FRONT_RIGHT],
+ &WheelState[CARWHEEL_FRONT_RIGHT],
+ WHEEL_STATUS_OK);
}
- m_aWheelRotation[CARWHEEL_REAR_LEFT] += m_aWheelSpeed[CARWHEEL_REAR_LEFT];
}
- if(m_aWheelTimer[CARWHEEL_REAR_RIGHT] <= 0.0f){
- if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier) && acceleration != 0.0f){
- if(acceleration > 0.0f){
- if(m_aWheelSpeed[CARWHEEL_REAR_RIGHT] < 2.0f)
- m_aWheelSpeed[CARWHEEL_REAR_RIGHT] -= 0.2f;
+
+ // Process front wheels off ground
+
+ if (!IsRealHeli()) {
+ if(m_aWheelTimer[CARWHEEL_FRONT_LEFT] <= 0.0f){
+ if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier) && acceleration != 0.0f){
+ if(acceleration > 0.0f){
+ if(m_aWheelSpeed[CARWHEEL_FRONT_LEFT] < 2.0f)
+ m_aWheelSpeed[CARWHEEL_FRONT_LEFT] -= 0.2f;
+ }else{
+ if(m_aWheelSpeed[CARWHEEL_FRONT_LEFT] > -2.0f)
+ m_aWheelSpeed[CARWHEEL_FRONT_LEFT] += 0.1f;
+ }
}else{
- if(m_aWheelSpeed[CARWHEEL_REAR_RIGHT] > -2.0f)
- m_aWheelSpeed[CARWHEEL_REAR_RIGHT] += 0.1f;
+ m_aWheelSpeed[CARWHEEL_FRONT_LEFT] *= 0.95f;
}
- }else{
- m_aWheelSpeed[CARWHEEL_REAR_RIGHT] *= 0.95f;
+ m_aWheelRotation[CARWHEEL_FRONT_LEFT] += m_aWheelSpeed[CARWHEEL_FRONT_LEFT];
}
- m_aWheelRotation[CARWHEEL_REAR_RIGHT] += m_aWheelSpeed[CARWHEEL_REAR_RIGHT];
+ if(m_aWheelTimer[CARWHEEL_FRONT_RIGHT] <= 0.0f){
+ if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier) && acceleration != 0.0f){
+ if(acceleration > 0.0f){
+ if(m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] < 2.0f)
+ m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] -= 0.2f;
+ }else{
+ if(m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] > -2.0f)
+ m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] += 0.1f;
+ }
+ }else{
+ m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] *= 0.95f;
+ }
+ m_aWheelRotation[CARWHEEL_FRONT_RIGHT] += m_aWheelSpeed[CARWHEEL_FRONT_RIGHT];
+ }
+ }
}
for(i = 0; i < 4; i++){
float wheelPos = colModel->lines[i].p0.z;
if(m_aSuspensionSpringRatio[i] > 0.0f)
wheelPos -= m_aSuspensionSpringRatio[i]*m_aSuspensionSpringLength[i];
- m_aWheelPosition[i] += (wheelPos - m_aWheelPosition[i])*0.75f;
+ if(GetModelIndex() == MI_VOODOO && bUsingSpecialColModel)
+ m_aWheelPosition[i] = wheelPos;
+ else
+ m_aWheelPosition[i] += (wheelPos - m_aWheelPosition[i])*0.75f;
}
for(i = 0; i < 4; i++)
m_aWheelState[i] = WheelState[i];
+ if(m_fGasPedal < 0.0f){
+ if(m_aWheelState[CARWHEEL_REAR_LEFT] == WHEEL_STATE_SPINNING)
+ m_aWheelState[CARWHEEL_REAR_LEFT] = WHEEL_STATE_NORMAL;
+ if(m_aWheelState[CARWHEEL_REAR_RIGHT] == WHEEL_STATE_SPINNING)
+ m_aWheelState[CARWHEEL_REAR_RIGHT] = WHEEL_STATE_NORMAL;
+ }
// Process horn
if(GetStatus() != STATUS_PLAYER){
- ReduceHornCounter();
+ if(!IsAlarmOn())
+ ReduceHornCounter();
}else{
- if(GetModelIndex() == MI_MRWHOOP){
- if(Pads[0].bHornHistory[Pads[0].iCurrHornHistory] &&
- !Pads[0].bHornHistory[(Pads[0].iCurrHornHistory+CPad::HORNHISTORY_SIZE-1) % CPad::HORNHISTORY_SIZE]){
- m_bSirenOrAlarm = !m_bSirenOrAlarm;
- printf("m_bSirenOrAlarm toggled to %d\n", m_bSirenOrAlarm);
- }
- }else if(UsesSiren(GetModelIndex())){
+ if(UsesSiren()){
if(Pads[0].bHornHistory[Pads[0].iCurrHornHistory]){
if(Pads[0].bHornHistory[(Pads[0].iCurrHornHistory+CPad::HORNHISTORY_SIZE-1) % CPad::HORNHISTORY_SIZE] &&
Pads[0].bHornHistory[(Pads[0].iCurrHornHistory+CPad::HORNHISTORY_SIZE-2) % CPad::HORNHISTORY_SIZE])
@@ -1012,42 +1377,146 @@ CAutomobile::ProcessControl(void)
m_bSirenOrAlarm = !m_bSirenOrAlarm;
}else
m_nCarHornTimer = 0;
- }else if(GetModelIndex() != MI_YARDIE && !CVehicle::bCheat3){
- if(Pads[0].GetHorn())
- m_nCarHornTimer = 1;
- else
- m_nCarHornTimer = 0;
+ }else if(GetModelIndex() != MI_VOODOO && !CVehicle::bCheat3 && !carHasNitro){
+ if(!IsAlarmOn()){
+ if(Pads[0].GetHorn())
+ m_nCarHornTimer = 1;
+ else
+ m_nCarHornTimer = 0;
+ }
}
}
// Flying
- if(GetStatus() != STATUS_PLAYER && GetStatus() != STATUS_PLAYER_REMOTE && GetStatus() != STATUS_PHYSICS){
- if(GetModelIndex() == MI_MIAMI_RCRAIDER || GetModelIndex() == MI_MIAMI_SPARROW)
- m_aWheelSpeed[0] = Max(m_aWheelSpeed[0]-0.0005f, 0.0f);
- }else if((GetModelIndex() == MI_DODO || CVehicle::bAllDodosCheat) &&
- m_vecMoveSpeed.Magnitude() > 0.0f && CTimer::GetTimeStep() > 0.0f){
-#ifdef ALT_DODO_CHEAT
- if (bAltDodoCheat)
- FlyingControl(FLIGHT_MODEL_SEAPLANE);
- else
+ bool playRotorSound = false;
+ bool isPlane = GetModelIndex() == MI_DODO || bAllDodosCheat;
+#ifdef FIX_BUGS
+ isPlane = isPlane && !IsRealHeli();
#endif
+ if(GetStatus() != STATUS_PLAYER && GetStatus() != STATUS_PLAYER_REMOTE && GetStatus() != STATUS_PHYSICS){
+ if(IsRealHeli()){
+ bEngineOn = false;
+ m_aWheelSpeed[1] = Max(m_aWheelSpeed[1]-0.0005f, 0.0f);
+ if(GetModelIndex() != MI_RCRAIDER && GetModelIndex() != MI_RCGOBLIN)
+ if(m_aWheelSpeed[1] < 0.154f && m_aWheelSpeed[1] > 0.0044f)
+ playRotorSound = true;
+ }
+ }else if(isPlane && m_vecMoveSpeed.Magnitude() > 0.0f && CTimer::GetTimeStep() > 0.0f){
+ if(GetModelIndex() == MI_DODO)
FlyingControl(FLIGHT_MODEL_DODO);
- }else if(GetModelIndex() == MI_MIAMI_RCBARON){
+ else
+ FlyingControl(FLIGHT_MODEL_PLANE);
+ }else if(GetModelIndex() == MI_RCBARON){
FlyingControl(FLIGHT_MODEL_RCPLANE);
- }else if(GetModelIndex() == MI_MIAMI_RCRAIDER || GetModelIndex() == MI_MIAMI_SPARROW || bAllCarCheat){
-#ifdef ALLCARSHELI_CHEAT
+ }else if(IsRealHeli() || bAllCarCheat){
+#ifdef RESTORE_ALLCARSHELI_CHEAT
if (bAllCarCheat)
FlyingControl(FLIGHT_MODEL_HELI);
else
#endif
{
- if (CPad::GetPad(0)->GetCircleJustDown())
- m_aWheelSpeed[0] = Max(m_aWheelSpeed[0] - 0.03f, 0.0f);
- if (m_aWheelSpeed[0] < 0.22f)
- m_aWheelSpeed[0] += 0.0001f;
- if (m_aWheelSpeed[0] > 0.15f)
- FlyingControl(FLIGHT_MODEL_HELI);
+ // Speed up rotor
+ if (m_aWheelSpeed[1] < 0.22f && !bIsInWater) {
+ if (GetModelIndex() == MI_RCRAIDER || GetModelIndex() == MI_RCGOBLIN)
+ m_aWheelSpeed[1] += 0.003f;
+ else
+ m_aWheelSpeed[1] += 0.001f;
+ }
+
+ // Fly
+ if (m_aWheelSpeed[1] > 0.15f) {
+ if (GetModelIndex() == MI_RCRAIDER || GetModelIndex() == MI_RCGOBLIN)
+ FlyingControl(FLIGHT_MODEL_RCHELI);
+ else if (m_nWheelsOnGround < 4 && !(GetModelIndex() == MI_SEASPAR && bTouchingWater) ||
+ CPad::GetPad(0)->GetAccelerate() != 0 ||
+#ifndef FREE_CAM
+ CPad::GetPad(0)->GetCarGunUpDown() > 1.0f ||
+#else
+ ((!CCamera::bFreeCam || (CCamera::bFreeCam && !CPad::IsAffectedByController)) && CPad::GetPad(0)->GetCarGunUpDown() > 1.0f) ||
+#endif
+ Abs(m_vecMoveSpeed.x) > 0.02f ||
+ Abs(m_vecMoveSpeed.y) > 0.02f ||
+ Abs(m_vecMoveSpeed.z) > 0.02f)
+ FlyingControl(FLIGHT_MODEL_HELI);
+ }
+ }
+
+ // Blade collision
+ if(m_aWheelSpeed[1] > 0.015f && m_aCarNodes[CAR_BONNET]){
+ CMatrix mat;
+ mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_BONNET]));
+ if(GetModelIndex() == MI_RCRAIDER || GetModelIndex() == MI_RCGOBLIN)
+ DoBladeCollision(mat.GetPosition(), GetMatrix(), ROTOR_TOP, 0.72f, 0.9f);
+ else if(GetModelIndex() == MI_SPARROW || GetModelIndex() == MI_SEASPAR)
+ DoBladeCollision(mat.GetPosition(), GetMatrix(), ROTOR_TOP, 5.15f, 0.8f);
+ else if(GetModelIndex() == MI_HUNTER)
+ DoBladeCollision(mat.GetPosition(), GetMatrix(), ROTOR_TOP, 6.15f, 0.5f);
+ else
+ DoBladeCollision(mat.GetPosition(), GetMatrix(), ROTOR_TOP, 6.15f, 1.0f);
+ }
+
+ // Heli weapons
+ if(GetModelIndex() == MI_HUNTER && GetStatus() == STATUS_PLAYER){
+ // Hunter rockets
+ if(CPad::GetPad(0)->CarGunJustDown() && CTimer::GetTimeInMilliseconds() > m_nGunFiringTime+350){
+ CWeapon gun(WEAPONTYPE_ROCKETLAUNCHER, 100);
+ CVector source = vecHunterRocketPos;
+ source = GetMatrix()*source + Max(DotProduct(m_vecMoveSpeed, GetForward()), 0.0f)*GetForward()*CTimer::GetTimeStep();
+ gun.FireProjectile(this, &source, 0.0f);
+
+ source = vecHunterRocketPos;
+ source.x = -source.x;
+ source = GetMatrix()*source + Max(DotProduct(m_vecMoveSpeed, GetForward()), 0.0f)*GetForward()*CTimer::GetTimeStep();
+ gun.FireProjectile(this, &source, 0.0f);
+
+ CStats::RoundsFiredByPlayer++;
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_SHOT_FIRED, 0.0f);
+ m_nGunFiringTime = CTimer::GetTimeInMilliseconds();
+ // Hunter gun
+ }else if(CPad::GetPad(0)->GetHandBrake() && CTimer::GetTimeInMilliseconds() > m_nGunFiringTime+60){
+ CWeapon gun(WEAPONTYPE_HELICANNON, 5000);
+ CVector source = vecHunterGunPos;
+ source = GetMatrix()*source + m_vecMoveSpeed*CTimer::GetTimeStep();
+ gun.FireInstantHit(this, &source);
+ gun.AddGunshell(this, source, CVector2D(0.0f, 0.1f), 0.025f);
+ CStats::RoundsFiredByPlayer++;
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_SHOT_FIRED, 0.0f);
+ m_nGunFiringTime = CTimer::GetTimeInMilliseconds();
+ }
+ }else if(GetModelIndex() == MI_SEASPAR && GetStatus() == STATUS_PLAYER){
+ // Sea sparrow gun
+ if(CPad::GetPad(0)->GetHandBrake() && CTimer::GetTimeInMilliseconds() > m_nGunFiringTime+40){
+ CWeapon gun(WEAPONTYPE_M4, 5000);
+ CVector source = vecSeaSparrowGunPos;
+ source = GetMatrix()*source + m_vecMoveSpeed*CTimer::GetTimeStep();
+ gun.FireInstantHit(this, &source);
+ gun.AddGunshell(this, source, CVector2D(0.0f, 0.1f), 0.025f);
+ CStats::RoundsFiredByPlayer++;
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_SHOT_FIRED, 0.0f);
+ m_nGunFiringTime = CTimer::GetTimeInMilliseconds();
+ }
+ }
+
+ if(GetModelIndex() != MI_RCRAIDER && GetModelIndex() != MI_RCGOBLIN)
+ if(m_aWheelSpeed[1] < 0.154f && m_aWheelSpeed[1] > 0.0044f)
+ playRotorSound = true;
+ }
+
+ // Play rotor sound
+ if(playRotorSound && m_aCarNodes[CAR_BONNET]){
+ CVector camDist = TheCamera.GetPosition() - GetPosition();
+ float distSq = camDist.MagnitudeSqr();
+ if(distSq < SQR(20.0f) && Abs(m_fPropellerRotation - m_aWheelRotation[1]) > DEGTORAD(30.0f)){
+ CMatrix mat;
+ mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_BONNET]));
+ CVector blade = mat.GetRight();
+ blade = Multiply3x3(GetMatrix(), blade);
+ camDist /= Max(Sqrt(distSq), 0.01f);
+ if(Abs(DotProduct(camDist, blade)) > HELI_ROTOR_DOTPROD_LIMIT){
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_HELI_BLADE, 0.0f);
+ m_fPropellerRotation = m_aWheelRotation[1];
+ }
}
}
}
@@ -1090,7 +1559,7 @@ CAutomobile::ProcessControl(void)
CParticle::AddParticle(PARTICLE_CARFLAME, damagePos,
CVector(0.0f, 0.0f, CGeneral::GetRandomNumberInRange(0.01125f, 0.09f)),
- nil, 0.9f);
+ nil, 0.63f);
CVector coors = damagePos;
coors.x += CGeneral::GetRandomNumberInRange(-0.5625f, 0.5625f),
@@ -1102,10 +1571,8 @@ CAutomobile::ProcessControl(void)
// Blow up car after 5 seconds
m_fFireBlowUpTimer += CTimer::GetTimeStepInMilliseconds();
- if(m_fFireBlowUpTimer > 5000.0f){
- CWorld::Players[CWorld::PlayerInFocus].AwardMoneyForExplosion(this);
+ if(m_fFireBlowUpTimer > 5000.0f)
BlowUpCar(m_pSetOnFireEntity);
- }
}else
m_fFireBlowUpTimer = 0.0f;
@@ -1117,7 +1584,7 @@ CAutomobile::ProcessControl(void)
if(m_bSirenOrAlarm && (CTimer::GetFrameCounter()&7) == 5 &&
- UsesSiren(GetModelIndex()) && GetModelIndex() != MI_MRWHOOP)
+ UsesSiren() && GetModelIndex() != MI_MRWHOOP)
CCarAI::MakeWayForCarWithSiren(this);
@@ -1125,10 +1592,14 @@ CAutomobile::ProcessControl(void)
float suspShake = 0.0f;
float surfShake = 0.0f;
+ float speedsq = m_vecMoveSpeed.MagnitudeSqr();
for(i = 0; i < 4; i++){
float suspChange = m_aSuspensionSpringRatioPrev[i] - m_aSuspensionSpringRatio[i];
- if(suspChange > 0.3f){
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_JUMP, suspChange);
+ if(suspChange > 0.3f && !drivingInSand && speedsq > SQR(0.2f)){
+ if(Damage.GetWheelStatus(i) == WHEEL_STATUS_BURST)
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_JUMP_2, suspChange);
+ else
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_JUMP, suspChange);
if(suspChange > suspShake)
suspShake = suspChange;
}
@@ -1137,7 +1608,7 @@ CAutomobile::ProcessControl(void)
if(surf == SURFACE_GRAVEL || surf == SURFACE_WATER || surf == SURFACE_HEDGE){
if(surfShake < 0.2f)
surfShake = 0.3f;
- }else if(surf == SURFACE_MUD_DRY || surf == SURFACE_SAND){
+ }else if(surf == SURFACE_MUD_DRY){
if(surfShake < 0.1f)
surfShake = 0.2f;
}else if(surf == SURFACE_GRASS){
@@ -1145,13 +1616,17 @@ CAutomobile::ProcessControl(void)
surfShake = 0.1f;
}
+ if(this == FindPlayerVehicle())
+// BUG: this only observes one of the wheels
+ TheCamera.m_bVehicleSuspenHigh = Abs(suspChange) > 0.05f;
+
m_aSuspensionSpringRatioPrev[i] = m_aSuspensionSpringRatio[i];
m_aSuspensionSpringRatio[i] = 1.0f;
}
// Shake pad
- if((suspShake > 0.0f || surfShake > 0.0f) && GetStatus() == STATUS_PLAYER){
+ if(!drivingInSand && (suspShake > 0.0f || surfShake > 0.0f) && GetStatus() == STATUS_PLAYER){
float speed = m_vecMoveSpeed.MagnitudeSqr();
if(speed > sq(0.1f)){
speed = Sqrt(speed);
@@ -1166,8 +1641,9 @@ CAutomobile::ProcessControl(void)
}
bVehicleColProcessed = false;
+ bAudioChangingGear = false;
- if(!bWarnedPeds)
+ if(!bWarnedPeds && GetVehicleAppearance() != VEHICLE_APPEARANCE_HELI && GetVehicleAppearance() != VEHICLE_APPEARANCE_PLANE)
CCarCtrl::ScanForPedDanger(this);
@@ -1175,20 +1651,20 @@ CAutomobile::ProcessControl(void)
// TODO: make the numbers defines
float heading;
- if(GetPosition().x > 1900.0f){
+ if(GetPosition().x > 1950.0f-400.0f){
if(m_vecMoveSpeed.x > 0.0f)
m_vecMoveSpeed.x *= -1.0f;
heading = GetForward().Heading();
if(heading > 0.0f) // going west
SetHeading(-heading);
- }else if(GetPosition().x < -1900.0f){
+ }else if(GetPosition().x < -1950.0f-400.0f){
if(m_vecMoveSpeed.x < 0.0f)
m_vecMoveSpeed.x *= -1.0f;
heading = GetForward().Heading();
if(heading < 0.0f) // going east
SetHeading(-heading);
}
- if(GetPosition().y > 1900.0f){
+ if(GetPosition().y > 1950.0f){
if(m_vecMoveSpeed.y > 0.0f)
m_vecMoveSpeed.y *= -1.0f;
heading = GetForward().Heading();
@@ -1196,7 +1672,7 @@ CAutomobile::ProcessControl(void)
SetHeading(PI-heading);
else if(heading > -HALFPI && heading < 0.0f)
SetHeading(-PI-heading);
- }else if(GetPosition().y < -1900.0f){
+ }else if(GetPosition().y < -1950.0f){
if(m_vecMoveSpeed.y < 0.0f)
m_vecMoveSpeed.y *= -1.0f;
heading = GetForward().Heading();
@@ -1215,11 +1691,31 @@ CAutomobile::ProcessControl(void)
(m_fGasPedal == 0.0f && brake == 0.0f || GetStatus() == STATUS_WRECKED)){
if(Abs(m_vecMoveSpeed.x) < 0.005f &&
Abs(m_vecMoveSpeed.y) < 0.005f &&
- Abs(m_vecMoveSpeed.z) < 0.005f){
+ Abs(m_vecMoveSpeed.z) < 0.005f &&
+ !(m_fDamageImpulse > 0.0f && m_pDamageEntity == FindPlayerPed()) &&
+ (m_aSuspensionSpringRatioPrev[0] < 1.0f || m_aSuspensionSpringRatioPrev[1] < 1.0f ||
+ m_aSuspensionSpringRatioPrev[2] < 1.0f || m_aSuspensionSpringRatioPrev[3] < 1.0f)){
m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
m_vecTurnSpeed.z = 0.0f;
}
}
+
+ if(IsRealHeli() && bHeliDestroyed && !bRenderScorched){
+ ApplyMoveForce(0.0f, 0.0f, -2.0f*CTimer::GetTimeStep());
+ m_vecTurnSpeed.z += -0.002f*CTimer::GetTimeStep();
+ m_vecTurnSpeed.x += -0.0002f*CTimer::GetTimeStep();
+
+ RwRGBA col = { 84, 84, 84, 255 };
+ CParticle::AddParticle(PARTICLE_ENGINE_SMOKE, GetMatrix()*CVector(0.0f, 0.0f, -10.0f),
+ CVector(0.0f, 0.0f, 0.0f), nil, 0.7f, col, 0, 0, 0, 3000);
+
+ if(CWorld::TestSphereAgainstWorld(GetPosition(), 10.0f, this, true, false, false, false, false, false) ||
+ GetPosition().z < 6.0f)
+ if(!bRenderScorched){ // we already know this is true...
+ CExplosion::AddExplosion(this, nil, EXPLOSION_CAR, GetPosition(), 0);
+ bRenderScorched = true;
+ }
+ }
}
#pragma optimize("", on)
@@ -1245,6 +1741,17 @@ CAutomobile::PreRender(void)
int i, j, n;
CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex());
+ if(GetModelIndex() == MI_RHINO && m_aCarNodes[CAR_WINDSCREEN]){
+ // Rotate Rhino turret
+ CMatrix m;
+ CVector p;
+ m.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WINDSCREEN]));
+ p = m.GetPosition();
+ m.SetRotateZ(m_fCarGunLR);
+ m.Translate(p);
+ m.UpdateRW();
+ }
+
if(GetModelIndex() == MI_RCBANDIT){
CVector pos = GetMatrix() * CVector(0.218f, -0.444f, 0.391f);
CAntennas::RegisterOne((uintptr)this, GetUp(), pos, 1.0f);
@@ -1255,7 +1762,7 @@ CAutomobile::PreRender(void)
// Wheel particles
- if(GetModelIndex() == MI_DODO){
+ if(GetModelIndex() == MI_DODO || GetVehicleAppearance() != VEHICLE_APPEARANCE_CAR){
; // nothing
}else if(GetModelIndex() == MI_RCBANDIT){
for(i = 0; i < 4; i++){
@@ -1310,6 +1817,7 @@ CAutomobile::PreRender(void)
rearSkidding = true;
for(i = 0; i < 4; i++){
+ if(m_aSuspensionSpringRatioPrev[i] < 1.0f && m_aWheelColPoints[i].surfaceB != SURFACE_WATER)
switch(m_aWheelState[i]){
case WHEEL_STATE_SPINNING:
if(AddWheelDirtAndWater(&m_aWheelColPoints[i], drawParticles)){
@@ -1329,46 +1837,79 @@ CAutomobile::PreRender(void)
if(m_aWheelTimer[i] > 0.0f)
CSkidmarks::RegisterOne((uintptr)this + i, m_aWheelColPoints[i].point,
GetForward().x, GetForward().y,
- &m_aWheelSkidmarkMuddy[i], &m_aWheelSkidmarkBloody[i]);
+ m_aWheelSkidmarkType[i], &m_aWheelSkidmarkBloody[i]);
break;
case WHEEL_STATE_SKIDDING:
if(i == CARWHEEL_REAR_LEFT || i == CARWHEEL_REAR_RIGHT || rearSkidding){
// same as below
- AddWheelDirtAndWater(&m_aWheelColPoints[i], drawParticles);
+ if(Abs(fwdSpeed) > 5.0f){
+ AddWheelDirtAndWater(&m_aWheelColPoints[i], drawParticles);
- CParticle::AddParticle(PARTICLE_RUBBER_SMOKE,
- m_aWheelColPoints[i].point + CVector(0.0f, 0.0f, 0.25f),
- CVector(0.0f, 0.0f, 0.0f));
+ CParticle::AddParticle(PARTICLE_RUBBER_SMOKE,
+ m_aWheelColPoints[i].point + CVector(0.0f, 0.0f, 0.25f),
+ CVector(0.0f, 0.0f, 0.0f));
+ }
if(m_aWheelTimer[i] > 0.0f)
CSkidmarks::RegisterOne((uintptr)this + i, m_aWheelColPoints[i].point,
GetForward().x, GetForward().y,
- &m_aWheelSkidmarkMuddy[i], &m_aWheelSkidmarkBloody[i]);
+ m_aWheelSkidmarkType[i], &m_aWheelSkidmarkBloody[i]);
}
break;
case WHEEL_STATE_FIXED:
- AddWheelDirtAndWater(&m_aWheelColPoints[i], drawParticles);
+ if(Abs(fwdSpeed) > 5.0f){
+ AddWheelDirtAndWater(&m_aWheelColPoints[i], drawParticles);
- CParticle::AddParticle(PARTICLE_RUBBER_SMOKE,
- m_aWheelColPoints[i].point + CVector(0.0f, 0.0f, 0.25f),
- CVector(0.0f, 0.0f, 0.0f));
+ CParticle::AddParticle(PARTICLE_RUBBER_SMOKE,
+ m_aWheelColPoints[i].point + CVector(0.0f, 0.0f, 0.25f),
+ CVector(0.0f, 0.0f, 0.0f));
+ }
if(m_aWheelTimer[i] > 0.0f)
CSkidmarks::RegisterOne((uintptr)this + i, m_aWheelColPoints[i].point,
GetForward().x, GetForward().y,
- &m_aWheelSkidmarkMuddy[i], &m_aWheelSkidmarkBloody[i]);
+ m_aWheelSkidmarkType[i], &m_aWheelSkidmarkBloody[i]);
break;
default:
if(Abs(fwdSpeed) > 0.5f)
AddWheelDirtAndWater(&m_aWheelColPoints[i], drawParticles);
- if(m_aWheelSkidmarkBloody[i] && m_aWheelTimer[i] > 0.0f)
+ if((m_aWheelSkidmarkBloody[i] || m_aWheelSkidmarkUnk[i]) && m_aWheelTimer[i] > 0.0f)
CSkidmarks::RegisterOne((uintptr)this + i, m_aWheelColPoints[i].point,
GetForward().x, GetForward().y,
- &m_aWheelSkidmarkMuddy[i], &m_aWheelSkidmarkBloody[i]);
+ m_aWheelSkidmarkType[i], &m_aWheelSkidmarkBloody[i]);
+ }
+
+ // Sparks for friction of burst wheels
+ if(Damage.GetWheelStatus(i) == WHEEL_STATUS_BURST && m_aSuspensionSpringRatioPrev[i] < 1.0f){
+ static float speedSq;
+ speedSq = m_vecMoveSpeed.MagnitudeSqr();
+ if(speedSq > SQR(0.1f) &&
+ m_aWheelColPoints[i].surfaceB != SURFACE_GRASS &&
+ m_aWheelColPoints[i].surfaceB != SURFACE_MUD_DRY &&
+ m_aWheelColPoints[i].surfaceB != SURFACE_SAND &&
+ m_aWheelColPoints[i].surfaceB != SURFACE_SAND_BEACH &&
+ m_aWheelColPoints[i].surfaceB != SURFACE_WATER){
+ CVector normalSpeed = m_aWheelColPoints[i].normal * DotProduct(m_aWheelColPoints[i].normal, m_vecMoveSpeed);
+ CVector frictionSpeed = m_vecMoveSpeed - normalSpeed;
+ if(i == CARWHEEL_FRONT_LEFT || i == CARWHEEL_REAR_LEFT)
+ frictionSpeed -= 0.05f*GetRight();
+ else
+ frictionSpeed += 0.05f*GetRight();
+ CVector unusedRight = 0.15f*GetRight();
+ CVector sparkDir = 0.25f*frictionSpeed;
+ CParticle::AddParticle(PARTICLE_SPARK_SMALL, m_aWheelColPoints[i].point, sparkDir);
+
+ if(speedSq > 0.04f)
+ CParticle::AddParticle(PARTICLE_SPARK_SMALL, m_aWheelColPoints[i].point, sparkDir);
+ if(speedSq > 0.16f){
+ CParticle::AddParticle(PARTICLE_SPARK_SMALL, m_aWheelColPoints[i].point, sparkDir);
+ CParticle::AddParticle(PARTICLE_SPARK_SMALL, m_aWheelColPoints[i].point, sparkDir);
+ }
+ }
}
}
}
@@ -1391,7 +1932,7 @@ CAutomobile::PreRender(void)
CSkidmarks::RegisterOne((uintptr)this + CARWHEEL_REAR_LEFT,
m_aWheelColPoints[CARWHEEL_REAR_LEFT].point + offset,
GetForward().x, GetForward().y,
- &m_aWheelSkidmarkMuddy[CARWHEEL_REAR_LEFT], &m_aWheelSkidmarkBloody[CARWHEEL_REAR_LEFT]);
+ m_aWheelSkidmarkType[CARWHEEL_REAR_LEFT], &m_aWheelSkidmarkBloody[CARWHEEL_REAR_LEFT]);
break;
default: break;
}
@@ -1409,7 +1950,7 @@ CAutomobile::PreRender(void)
CSkidmarks::RegisterOne((uintptr)this + CARWHEEL_REAR_RIGHT,
m_aWheelColPoints[CARWHEEL_REAR_RIGHT].point + offset,
GetForward().x, GetForward().y,
- &m_aWheelSkidmarkMuddy[CARWHEEL_REAR_RIGHT], &m_aWheelSkidmarkBloody[CARWHEEL_REAR_RIGHT]);
+ m_aWheelSkidmarkType[CARWHEEL_REAR_RIGHT], &m_aWheelSkidmarkBloody[CARWHEEL_REAR_RIGHT]);
break;
default: break;
}
@@ -1444,21 +1985,22 @@ CAutomobile::PreRender(void)
AddDamagedVehicleParticles();
// Exhaust smoke
- if(bEngineOn && fwdSpeed < 90.0f){
+ if(bEngineOn && !(pHandling->Flags & HANDLING_NO_EXHAUST) && fwdSpeed < 130.0f){
CVector exhaustPos = mi->m_positions[CAR_POS_EXHAUST];
- CVector pos1, pos2, dir;
+ CVector pos1, pos2, dir1, dir2;
if(exhaustPos != CVector(0.0f, 0.0f, 0.0f)){
- dir.z = 0.0f;
+ dir1.z = 0.0f;
+ dir2.z = 0.0f;
if(fwdSpeed < 10.0f){
CVector steerFwd(-Sin(m_fSteerAngle), Cos(m_fSteerAngle), 0.0f);
steerFwd = Multiply3x3(GetMatrix(), steerFwd);
float r = CGeneral::GetRandomNumberInRange(-0.06f, -0.03f);
- dir.x = steerFwd.x * r;
- dir.y = steerFwd.y * r;
+ dir1.x = steerFwd.x * r;
+ dir1.y = steerFwd.y * r;
}else{
- dir.x = m_vecMoveSpeed.x;
- dir.y = m_vecMoveSpeed.y;
+ dir1.x = m_vecMoveSpeed.x;
+ dir1.y = m_vecMoveSpeed.y;
}
bool dblExhaust = false;
@@ -1468,17 +2010,62 @@ CAutomobile::PreRender(void)
pos2 = exhaustPos;
pos2.x = -pos2.x;
pos2 = GetMatrix() * pos2;
+ dir2 = dir1;
}
- n = 4.0f*m_fGasPedal;
- if(dblExhaust)
- for(i = 0; i <= n; i++){
- CParticle::AddParticle(PARTICLE_EXHAUST_FUMES, pos1, dir);
- CParticle::AddParticle(PARTICLE_EXHAUST_FUMES, pos2, dir);
+ static float fumesLimit = 2.0f;
+ if(CGeneral::GetRandomNumberInRange(1.0f, 3.0f)*(m_fGasPedal+1.1f) > fumesLimit)
+ for(i = 0; i < 4;){
+ CParticle::AddParticle(PARTICLE_EXHAUST_FUMES, pos1, dir1);
+ if(pHandling->Flags & HANDLING_DBL_EXHAUST)
+ CParticle::AddParticle(PARTICLE_EXHAUST_FUMES, pos2, dir2);
+
+ static float extraFumesLimit = 0.5f;
+ if(m_fGasPedal > extraFumesLimit && m_nCurrentGear < 3){
+ if(CGeneral::GetRandomNumber() & 1)
+ CParticle::AddParticle(PARTICLE_EXHAUST_FUMES, pos1, dir1);
+ else if(pHandling->Flags & HANDLING_DBL_EXHAUST)
+ CParticle::AddParticle(PARTICLE_EXHAUST_FUMES, pos2, dir2);
+ }
+
+ // Fire on Cuban hermes
+ if(GetModelIndex() == MI_CUBAN && i == 1 && m_fGasPedal > 0.9f){
+ if(m_nCurrentGear == 1 || m_nCurrentGear == 3 && (CTimer::GetTimeInMilliseconds()%1500) > 750){
+ if(CGeneral::GetRandomNumber() & 1){
+ CParticle::AddParticle(PARTICLE_FIREBALL, pos1, dir1, nil, 0.05f, 0, 0, 2, 200);
+ CParticle::AddParticle(PARTICLE_FIREBALL, pos1, dir1, nil, 0.05f, 0, 0, 2, 200);
+ }else{
+ CParticle::AddParticle(PARTICLE_FIREBALL, pos2, dir2, nil, 0.05f, 0, 0, 2, 200);
+ CParticle::AddParticle(PARTICLE_FIREBALL, pos2, dir2, nil, 0.05f, 0, 0, 2, 200);
+ }
+ }
+ }
+
+ if(GetStatus() == STATUS_PLAYER && (CTimer::GetFrameCounter()&3) == 0 &&
+ CWeather::Rain == 0.0f && i == 0){
+ CVector camDist = GetPosition() - TheCamera.GetPosition();
+ if(DotProduct(GetForward(), camDist) > 0.0f ||
+ TheCamera.GetLookDirection() == LOOKING_LEFT ||
+ TheCamera.GetLookDirection() == LOOKING_RIGHT){
+ CParticle::AddParticle(PARTICLE_HEATHAZE, pos1, CVector(0.0f, 0.0f, 0.0f));
+ if(pHandling->Flags & HANDLING_DBL_EXHAUST)
+ CParticle::AddParticle(PARTICLE_HEATHAZE, pos2, CVector(0.0f, 0.0f, 0.0f));
+
+ CParticle::AddParticle(PARTICLE_HEATHAZE, pos1, CVector(0.0f, 0.0f, 0.0f));
+ if(pHandling->Flags & HANDLING_DBL_EXHAUST)
+ CParticle::AddParticle(PARTICLE_HEATHAZE, pos2, CVector(0.0f, 0.0f, 0.0f));
+ }
+ }
+
+ if(GetModelIndex() == MI_CUBAN && i < 1){
+ i = 1;
+ pos1 = GetMatrix() * CVector(1.134f, -1.276f, -0.56f);
+ pos2 = GetMatrix() * CVector(-1.134f, -1.276f, -0.56f);
+ dir1 += 0.05f*GetRight();
+ dir2 -= 0.05f*GetRight();
+ }else
+ i = 99;
}
- else
- for(i = 0; i <= n; i++)
- CParticle::AddParticle(PARTICLE_EXHAUST_FUMES, pos1, dir);
}
}
@@ -1550,8 +2137,8 @@ CAutomobile::PreRender(void)
float angle = (CTimer::GetTimeInMilliseconds() & 0x3FF)*TWOPI/0x3FF;
float s = 8.0f*Sin(angle);
float c = 8.0f*Cos(angle);
- CShadows::StoreCarLightShadow(this, (uintptr)this + 21, gpShadowHeadLightsTex,
- &pos, c, s, s, -c, r, g, b, 8.0f);
+ //CShadows::StoreCarLightShadow(this, (uintptr)this + 21, gpShadowHeadLightsTex,
+ // &pos, c, s, s, -c, r, g, b, 8.0f);
CPointLights::AddLight(CPointLights::LIGHT_POINT,
pos + GetUp()*2.0f, CVector(0.0f, 0.0f, 0.0f), 12.0f,
@@ -1589,17 +2176,26 @@ CAutomobile::PreRender(void)
}
break;
- case MI_FBICAR:
+ case MI_FBIRANCH:
+ case MI_VICECHEE:
if(m_bSirenOrAlarm){
CVector pos = GetMatrix() * CVector(0.4f, 0.6f, 0.3f);
if(CTimer::GetTimeInMilliseconds() & 0x100 &&
DotProduct(GetForward(), GetPosition() - TheCamera.GetPosition()) < 0.0f)
- CCoronas::RegisterCorona((uintptr)this + 21,
- 0, 0, 255, 255,
- pos, 0.4f, 50.0f,
- CCoronas::TYPE_STAR,
- CCoronas::FLARE_NONE,
- CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
+ if(GetModelIndex() == MI_VICECHEE)
+ CCoronas::RegisterCorona((uintptr)this + 21,
+ 255, 70, 70, 255,
+ pos, 0.4f, 50.0f,
+ CCoronas::TYPE_STAR,
+ CCoronas::FLARE_NONE,
+ CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
+ else
+ CCoronas::RegisterCorona((uintptr)this + 21,
+ 0, 0, 255, 255,
+ pos, 0.4f, 50.0f,
+ CCoronas::TYPE_STAR,
+ CCoronas::FLARE_NONE,
+ CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
else
CCoronas::UpdateCoronaCoors((uintptr)this + 21, pos, 50.0f, 0.0f);
}
@@ -1607,7 +2203,8 @@ CAutomobile::PreRender(void)
case MI_TAXI:
case MI_CABBIE:
- case MI_BORGNINE:
+ case MI_ZEBRA:
+ case MI_KAUFMAN:
if(bTaxiLight){
CVector pos = GetPosition() + GetUp()*0.95f;
CCoronas::RegisterCorona((uintptr)this + 21,
@@ -1624,7 +2221,8 @@ CAutomobile::PreRender(void)
}
if(GetModelIndex() != MI_RCBANDIT && GetModelIndex() != MI_DODO &&
- GetModelIndex() != MI_RHINO) {
+ GetModelIndex() != MI_RHINO && GetModelIndex() != MI_RCBARON &&
+ GetVehicleAppearance() != VEHICLE_APPEARANCE_HELI) {
// Process lights
// Turn lights on/off
@@ -1663,7 +2261,6 @@ CAutomobile::PreRender(void)
lookVector = CVector(1.0f, 0.0f, 0.0f);
// 1.0 if directly behind car, -1.0 if in front
- // BUG on PC: Abs of DotProduct is taken
float behindness = DotProduct(lookVector, GetForward());
behindness = Clamp(behindness, -1.0f, 1.0f); // shouldn't be necessary
// 0.0 if behind car, PI if in front
@@ -1678,7 +2275,8 @@ CAutomobile::PreRender(void)
lightL -= GetRight()*2.0f*headLightPos.x;
// Headlight coronas
- if(behindness < 0.0f){
+ if(DotProduct(lightR-TheCamera.GetPosition(), GetForward()) < 0.0f &&
+ (TheCamera.Cams[TheCamera.ActiveCam].Mode != CCam::MODE_1STPERSON || this != FindPlayerVehicle())){
// In front of car
float intensity = -0.5f*behindness + 0.3f;
float size = 1.0f - behindness;
@@ -1768,7 +2366,7 @@ CAutomobile::PreRender(void)
lightL -= GetRight()*2.0f*tailLightPos.x;
// Taillight coronas
- if(behindness > 0.0f){
+ if(DotProduct(lightR-TheCamera.GetPosition(), GetForward()) > 0.0f){
// Behind car
float intensity = 0.4f*behindness + 0.4f;
float size = (behindness + 1.0f)/2.0f;
@@ -1842,7 +2440,7 @@ CAutomobile::PreRender(void)
if(Damage.GetLightStatus(VEHLIGHT_FRONT_LEFT) == LIGHT_STATUS_OK ||
Damage.GetLightStatus(VEHLIGHT_FRONT_RIGHT) == LIGHT_STATUS_OK)
CShadows::StoreCarLightShadow(this, (uintptr)this + 22, gpShadowHeadLightsTex, &pos,
- 7.0f*fwd.x, 7.0f*fwd.y, 7.0f*fwd.y, -7.0f*fwd.x, 45, 45, 45, 7.0f);
+ 7.0f*fwd.x, 7.0f*fwd.y, 5.5f*fwd.y, -5.5f*fwd.x, 45, 45, 45, 7.0f);
f = (tailLightPos.y - 2.5f) - (headLightPos.y + 6.0f);
pos += CVector(f*fwd.x, f*fwd.y, 0.0f);
@@ -1934,26 +2532,43 @@ CAutomobile::PreRender(void)
// end of lights
}
- CShadows::StoreShadowForCar(this);
-}
+ if (IsRealHeli())
+ CShadows::StoreShadowForVehicle(this, VEH_SHD_TYPE_HELI);
+ else if ( GetModelIndex() == MI_RCBARON)
+ CShadows::StoreShadowForVehicle(this, VEH_SHD_TYPE_RCPLANE);
+ else
+ CShadows::StoreShadowForVehicle(this, VEH_SHD_TYPE_CAR);
+
+ DoSunGlare();
+
+ // Heli dust
+ if(IsRealHeli() && m_aWheelSpeed[1] > 0.1125f && GetPosition().z < 30.0f){
+ bool foundGround = false;
+ float waterZ = -1000.0f;
+ float groundZ = CWorld::FindGroundZFor3DCoord(GetPosition().x, GetPosition().y, GetPosition().z, &foundGround);
+ if(!CWaterLevel::GetWaterLevel(GetPosition(), &waterZ, false))
+ waterZ = 0.0f;
+ groundZ = Max(groundZ, waterZ);
+ float rnd = (m_aWheelSpeed[1]-0.1125f)*((int)Max(16.0f-4.0f*CTimer::GetTimeStep(),2.0f))*400.0f/43.0f;
+ float radius = 10.0f;
+ if(GetModelIndex() == MI_RCGOBLIN || GetModelIndex() == MI_RCRAIDER)
+ radius = 3.0f;
+ if(GetPosition().z - groundZ < radius)
+ HeliDustGenerate(this, radius-(GetPosition().z - groundZ), groundZ, Ceil(rnd));
+ }
-void
-CAutomobile::Render(void)
-{
- int i;
CMatrix mat;
CVector pos;
- CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex());
- if(GetModelIndex() == MI_RHINO && m_aCarNodes[CAR_BONNET]){
- // Rotate Rhino turret
- CMatrix m;
- CVector p;
- m.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_BONNET]));
- p = m.GetPosition();
- m.SetRotateZ(m_fCarGunLR);
- m.Translate(p);
- m.UpdateRW();
+ bool onlyFrontWheels = false;
+ if(IsRealHeli()){
+ // top rotor
+ m_aWheelRotation[1] += m_aWheelSpeed[1]*CTimer::GetTimeStep();
+ while(m_aWheelRotation[1] > TWOPI) m_aWheelRotation[1] -= TWOPI;
+ // rear rotor
+ m_aWheelRotation[3] += m_aWheelSpeed[1]*CTimer::GetTimeStep();
+ while(m_aWheelRotation[3] > TWOPI) m_aWheelRotation[3] -= TWOPI;
+ onlyFrontWheels = true;
}
CVector contactPoints[4]; // relative to model
@@ -1961,7 +2576,7 @@ CAutomobile::Render(void)
CVector frontWheelFwd = Multiply3x3(GetMatrix(), CVector(-Sin(m_fSteerAngle), Cos(m_fSteerAngle), 0.0f));
CVector rearWheelFwd = GetForward();
for(i = 0; i < 4; i++){
- if (m_aWheelTimer[i] > 0.0f) {
+ if (m_aWheelTimer[i] > 0.0f && (!onlyFrontWheels || i == CARWHEEL_FRONT_LEFT || i == CARWHEEL_FRONT_RIGHT)) {
contactPoints[i] = m_aWheelColPoints[i].point - GetPosition();
contactSpeeds[i] = GetSpeed(contactPoints[i]);
if (i == CARWHEEL_FRONT_LEFT || i == CARWHEEL_FRONT_RIGHT)
@@ -1972,75 +2587,162 @@ CAutomobile::Render(void)
}
}
+ RwRGBA hoverParticleCol = { 255, 255, 255, 32 };
+
// Rear right wheel
mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_RB]));
- pos.x = mat.GetPosition().x;
- pos.y = mat.GetPosition().y;
+ pos = mat.GetPosition();
pos.z = m_aWheelPosition[CARWHEEL_REAR_RIGHT];
if(Damage.GetWheelStatus(CARWHEEL_REAR_RIGHT) == WHEEL_STATUS_BURST)
mat.SetRotate(m_aWheelRotation[CARWHEEL_REAR_RIGHT], 0.0f, 0.3f*Sin(m_aWheelRotation[CARWHEEL_REAR_RIGHT]));
else
mat.SetRotateX(m_aWheelRotation[CARWHEEL_REAR_RIGHT]);
- mat.Scale(mi->m_wheelScale);
+ if(GetStatus() == STATUS_PLAYER){
+ if(bHoverCheat && m_aSuspensionSpringRatioPrev[CARWHEEL_REAR_RIGHT] < 1.0f &&
+ m_aWheelColPoints[CARWHEEL_REAR_RIGHT].surfaceB == SURFACE_WATER){
+ // hovering on water
+ mat.RotateY(-HALFPI);
+ if((CTimer::GetFrameCounter()+CARWHEEL_REAR_RIGHT) & 1){
+ CParticle::AddParticle(PARTICLE_STEAM_NY_SLOWMOTION, m_aWheelColPoints[CARWHEEL_REAR_RIGHT].point,
+ 0.5f*m_vecMoveSpeed+0.1f*GetRight(), nil, 0.4f, hoverParticleCol);
+ }else{
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, m_aWheelColPoints[CARWHEEL_REAR_RIGHT].point,
+ 0.3f*m_vecMoveSpeed+0.15f*GetRight()+CVector(0.0f, 0.0f, 0.1f), nil, 0.15f, hoverParticleCol,
+ CGeneral::GetRandomNumberInRange(0.0f, 90.0f),
+ CGeneral::GetRandomNumberInRange(0.0f, 10.0f), 1);
+ }
+#ifdef BETTER_ALLCARSAREDODO_CHEAT
+ } else if (bAllDodosCheat && m_nDriveWheelsOnGround == 0 && m_nDriveWheelsOnGroundPrev == 0) {
+ mat.RotateY(-HALFPI);
+#endif
+ }else{
+ // tilt wheel depending oh how much it presses on ground
+ float groundOffset = pos.z + m_fHeightAboveRoad - 0.5f*mi->m_wheelScale;
+ if(GetModelIndex() == MI_VOODOO)
+ groundOffset *= 0.6f;
+ mat.RotateY(Asin(Clamp(-groundOffset, -1.0f, 1.0f)));
+ }
+ }
+ if(pHandling->Flags & HANDLING_FAT_REARW)
+ mat.Scale(1.15f*mi->m_wheelScale, mi->m_wheelScale, mi->m_wheelScale);
+ else
+ mat.Scale(mi->m_wheelScale);
mat.Translate(pos);
mat.UpdateRW();
- if(CVehicle::bWheelsOnlyCheat)
- RpAtomicRender((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_RB]));
// Rear left wheel
mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_LB]));
- pos.x = mat.GetPosition().x;
- pos.y = mat.GetPosition().y;
+ pos = mat.GetPosition();
pos.z = m_aWheelPosition[CARWHEEL_REAR_LEFT];
if(Damage.GetWheelStatus(CARWHEEL_REAR_LEFT) == WHEEL_STATUS_BURST)
- mat.SetRotate(-m_aWheelRotation[CARWHEEL_REAR_LEFT], 0.0f, PI+0.3f*Sin(-m_aWheelRotation[CARWHEEL_REAR_LEFT]));
+ mat.SetRotate(-m_aWheelRotation[CARWHEEL_REAR_LEFT], 0.0f, PI+0.3f*Sin(m_aWheelRotation[CARWHEEL_REAR_LEFT]));
else
mat.SetRotate(-m_aWheelRotation[CARWHEEL_REAR_LEFT], 0.0f, PI);
- mat.Scale(mi->m_wheelScale);
+ if(GetStatus() == STATUS_PLAYER){
+ if(bHoverCheat && m_aSuspensionSpringRatioPrev[CARWHEEL_REAR_LEFT] < 1.0f &&
+ m_aWheelColPoints[CARWHEEL_REAR_LEFT].surfaceB == SURFACE_WATER){
+ // hovering on water
+ mat.RotateY(HALFPI);
+ if((CTimer::GetFrameCounter()+CARWHEEL_REAR_LEFT) & 1){
+ CParticle::AddParticle(PARTICLE_STEAM_NY_SLOWMOTION, m_aWheelColPoints[CARWHEEL_REAR_LEFT].point,
+ 0.5f*m_vecMoveSpeed-0.1f*GetRight(), nil, 0.4f, hoverParticleCol);
+ }else{
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, m_aWheelColPoints[CARWHEEL_REAR_LEFT].point,
+ 0.3f*m_vecMoveSpeed-0.15f*GetRight()+CVector(0.0f, 0.0f, 0.1f), nil, 0.15f, hoverParticleCol,
+ CGeneral::GetRandomNumberInRange(0.0f, 90.0f),
+ CGeneral::GetRandomNumberInRange(0.0f, 10.0f), 1);
+ }
+#ifdef BETTER_ALLCARSAREDODO_CHEAT
+ } else if (bAllDodosCheat && m_nDriveWheelsOnGround == 0 && m_nDriveWheelsOnGroundPrev == 0) {
+ mat.RotateY(HALFPI);
+#endif
+ }else{
+ // tilt wheel depending oh how much it presses on ground
+ float groundOffset = pos.z + m_fHeightAboveRoad - 0.5f*mi->m_wheelScale;
+ if(GetModelIndex() == MI_VOODOO)
+ groundOffset *= 0.6f;
+ mat.RotateY(Asin(Clamp(groundOffset, -1.0f, 1.0f)));
+ }
+ }
+ if(pHandling->Flags & HANDLING_FAT_REARW)
+ mat.Scale(1.15f*mi->m_wheelScale, mi->m_wheelScale, mi->m_wheelScale);
+ else
+ mat.Scale(mi->m_wheelScale);
mat.Translate(pos);
mat.UpdateRW();
- if(CVehicle::bWheelsOnlyCheat)
- RpAtomicRender((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_LB]));
// Mid right wheel
if(m_aCarNodes[CAR_WHEEL_RM]){
mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_RM]));
- pos.x = mat.GetPosition().x;
- pos.y = mat.GetPosition().y;
+ pos = mat.GetPosition();
pos.z = m_aWheelPosition[CARWHEEL_REAR_RIGHT];
if(Damage.GetWheelStatus(CARWHEEL_REAR_RIGHT) == WHEEL_STATUS_BURST)
mat.SetRotate(m_aWheelRotation[CARWHEEL_REAR_RIGHT], 0.0f, 0.3f*Sin(m_aWheelRotation[CARWHEEL_REAR_RIGHT]));
else
mat.SetRotateX(m_aWheelRotation[CARWHEEL_REAR_RIGHT]);
- mat.Scale(mi->m_wheelScale);
+ if(GetStatus() == STATUS_PLAYER){
+ if(bHoverCheat && m_aSuspensionSpringRatioPrev[CARWHEEL_REAR_RIGHT] < 1.0f &&
+ m_aWheelColPoints[CARWHEEL_REAR_RIGHT].surfaceB == SURFACE_WATER){
+ // hovering on water
+ mat.RotateY(-HALFPI);
+#ifdef BETTER_ALLCARSAREDODO_CHEAT
+ } else if (bAllDodosCheat && m_nDriveWheelsOnGround == 0 && m_nDriveWheelsOnGroundPrev == 0) {
+ mat.RotateY(-HALFPI);
+#endif
+ }else{
+ // tilt wheel depending oh how much it presses on ground
+ float groundOffset = pos.z + m_fHeightAboveRoad - 0.5f*mi->m_wheelScale;
+ if(GetModelIndex() == MI_VOODOO)
+ groundOffset *= 0.6f;
+ mat.RotateY(Asin(Clamp(-groundOffset, -1.0f, 1.0f)));
+ }
+ }
+ if(pHandling->Flags & HANDLING_FAT_REARW)
+ mat.Scale(1.15f*mi->m_wheelScale, mi->m_wheelScale, mi->m_wheelScale);
+ else
+ mat.Scale(mi->m_wheelScale);
mat.Translate(pos);
mat.UpdateRW();
- if(CVehicle::bWheelsOnlyCheat)
- RpAtomicRender((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_RM]));
}
// Mid left wheel
if(m_aCarNodes[CAR_WHEEL_LM]){
mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_LM]));
- pos.x = mat.GetPosition().x;
- pos.y = mat.GetPosition().y;
+ pos = mat.GetPosition();
pos.z = m_aWheelPosition[CARWHEEL_REAR_LEFT];
if(Damage.GetWheelStatus(CARWHEEL_REAR_LEFT) == WHEEL_STATUS_BURST)
- mat.SetRotate(-m_aWheelRotation[CARWHEEL_REAR_LEFT], 0.0f, PI+0.3f*Sin(-m_aWheelRotation[CARWHEEL_REAR_LEFT]));
+ mat.SetRotate(-m_aWheelRotation[CARWHEEL_REAR_LEFT], 0.0f, PI+0.3f*Sin(m_aWheelRotation[CARWHEEL_REAR_LEFT]));
else
mat.SetRotate(-m_aWheelRotation[CARWHEEL_REAR_LEFT], 0.0f, PI);
- mat.Scale(mi->m_wheelScale);
+ if(GetStatus() == STATUS_PLAYER){
+ if(bHoverCheat && m_aSuspensionSpringRatioPrev[CARWHEEL_REAR_LEFT] < 1.0f &&
+ m_aWheelColPoints[CARWHEEL_REAR_LEFT].surfaceB == SURFACE_WATER){
+ // hovering on water
+ mat.RotateY(HALFPI);
+#ifdef BETTER_ALLCARSAREDODO_CHEAT
+ } else if (bAllDodosCheat && m_nDriveWheelsOnGround == 0 && m_nDriveWheelsOnGroundPrev == 0) {
+ mat.RotateY(HALFPI);
+#endif
+ }else{
+ // tilt wheel depending oh how much it presses on ground
+ float groundOffset = pos.z + m_fHeightAboveRoad - 0.5f*mi->m_wheelScale;
+ if(GetModelIndex() == MI_VOODOO)
+ groundOffset *= 0.6f;
+ mat.RotateY(Asin(Clamp(groundOffset, -1.0f, 1.0f)));
+ }
+ }
+ if(pHandling->Flags & HANDLING_FAT_REARW)
+ mat.Scale(1.15f*mi->m_wheelScale, mi->m_wheelScale, mi->m_wheelScale);
+ else
+ mat.Scale(mi->m_wheelScale);
mat.Translate(pos);
mat.UpdateRW();
- if(CVehicle::bWheelsOnlyCheat)
- RpAtomicRender((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_LM]));
}
if(GetModelIndex() == MI_DODO){
// Front wheel
mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_RF]));
- pos.x = mat.GetPosition().x;
- pos.y = mat.GetPosition().y;
+ pos = mat.GetPosition();
pos.z = m_aWheelPosition[CARWHEEL_FRONT_RIGHT];
if(Damage.GetWheelStatus(CARWHEEL_FRONT_RIGHT) == WHEEL_STATUS_BURST)
mat.SetRotate(m_aWheelRotation[CARWHEEL_FRONT_RIGHT], 0.0f, m_fSteerAngle+0.3f*Sin(m_aWheelRotation[CARWHEEL_FRONT_RIGHT]));
@@ -2049,8 +2751,6 @@ CAutomobile::Render(void)
mat.Scale(mi->m_wheelScale);
mat.Translate(pos);
mat.UpdateRW();
- if(CVehicle::bWheelsOnlyCheat)
- RpAtomicRender((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_RF]));
// Rotate propeller
if(m_aCarNodes[CAR_WINDSCREEN]){
@@ -2080,59 +2780,138 @@ CAutomobile::Render(void)
}else if(GetModelIndex() == MI_RHINO){
// Front right wheel
mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_RF]));
- pos.x = mat.GetPosition().x;
- pos.y = mat.GetPosition().y;
+ pos = mat.GetPosition();
pos.z = m_aWheelPosition[CARWHEEL_FRONT_RIGHT];
// no damaged wheels or steering
mat.SetRotate(m_aWheelRotation[CARWHEEL_FRONT_RIGHT], 0.0f, 0.0f);
mat.Scale(mi->m_wheelScale);
mat.Translate(pos);
mat.UpdateRW();
- if(CVehicle::bWheelsOnlyCheat)
- RpAtomicRender((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_RF]));
// Front left wheel
mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_LF]));
- pos.x = mat.GetPosition().x;
- pos.y = mat.GetPosition().y;
+ pos = mat.GetPosition();
pos.z = m_aWheelPosition[CARWHEEL_FRONT_LEFT];
// no damaged wheels or steering
mat.SetRotate(-m_aWheelRotation[CARWHEEL_FRONT_LEFT], 0.0f, PI);
mat.Scale(mi->m_wheelScale);
mat.Translate(pos);
mat.UpdateRW();
- if(CVehicle::bWheelsOnlyCheat)
- RpAtomicRender((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_LF]));
+ }else if(IsRealHeli()){
+ // Top rotor
+ if(m_aCarNodes[CAR_BONNET]){
+ mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_BONNET]));
+ pos = mat.GetPosition();
+ mat.SetRotateZ(m_aWheelRotation[1]);
+ mat.Translate(pos);
+ mat.UpdateRW();
+ }
+ // Blurred top rotor
+ if(m_aCarNodes[CAR_WINDSCREEN]){
+ mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WINDSCREEN]));
+ pos = mat.GetPosition();
+ mat.SetRotateZ(-m_aWheelRotation[1]);
+ mat.Translate(pos);
+ mat.UpdateRW();
+ }
+ // Rear rotor
+ if(m_aCarNodes[CAR_BOOT]){
+ mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_BOOT]));
+ pos = mat.GetPosition();
+ mat.SetRotateX(m_aWheelRotation[3]);
+ mat.Translate(pos);
+ mat.UpdateRW();
+ }
+ // Blurred rear rotor
+ if(m_aCarNodes[CAR_BUMP_REAR]){
+ mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_BUMP_REAR]));
+ pos = mat.GetPosition();
+ mat.SetRotateX(-m_aWheelRotation[3]);
+ mat.Translate(pos);
+ mat.UpdateRW();
+ }
}else{
// Front right wheel
mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_RF]));
- pos.x = mat.GetPosition().x;
- pos.y = mat.GetPosition().y;
+ pos = mat.GetPosition();
pos.z = m_aWheelPosition[CARWHEEL_FRONT_RIGHT];
if(Damage.GetWheelStatus(CARWHEEL_FRONT_RIGHT) == WHEEL_STATUS_BURST)
mat.SetRotate(m_aWheelRotation[CARWHEEL_FRONT_RIGHT], 0.0f, m_fSteerAngle+0.3f*Sin(m_aWheelRotation[CARWHEEL_FRONT_RIGHT]));
else
mat.SetRotate(m_aWheelRotation[CARWHEEL_FRONT_RIGHT], 0.0f, m_fSteerAngle);
- mat.Scale(mi->m_wheelScale);
+ if(GetStatus() == STATUS_PLAYER){
+ if(bHoverCheat && m_aSuspensionSpringRatioPrev[CARWHEEL_FRONT_RIGHT] < 1.0f &&
+ m_aWheelColPoints[CARWHEEL_FRONT_RIGHT].surfaceB == SURFACE_WATER){
+ // hovering on water
+ mat.RotateY(-HALFPI);
+ if((CTimer::GetFrameCounter()+CARWHEEL_FRONT_RIGHT) & 1){
+ CParticle::AddParticle(PARTICLE_STEAM_NY_SLOWMOTION, m_aWheelColPoints[CARWHEEL_FRONT_RIGHT].point,
+ 0.5f*m_vecMoveSpeed+0.1f*GetRight(), nil, 0.4f, hoverParticleCol);
+ }else{
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, m_aWheelColPoints[CARWHEEL_FRONT_RIGHT].point,
+ 0.3f*m_vecMoveSpeed+0.15f*GetRight()+CVector(0.0f, 0.0f, 0.1f), nil, 0.15f, hoverParticleCol,
+ CGeneral::GetRandomNumberInRange(0.0f, 90.0f),
+ CGeneral::GetRandomNumberInRange(0.0f, 10.0f), 1);
+ }
+#ifdef BETTER_ALLCARSAREDODO_CHEAT
+ } else if (bAllDodosCheat && m_nDriveWheelsOnGround == 0 && m_nDriveWheelsOnGroundPrev == 0) {
+ mat.RotateY(-HALFPI);
+#endif
+ }else{
+ // tilt wheel depending oh how much it presses on ground
+ float groundOffset = pos.z + m_fHeightAboveRoad - 0.5f*mi->m_wheelScale;
+ if(GetModelIndex() == MI_VOODOO)
+ groundOffset *= 0.6f;
+ mat.RotateY(Asin(Clamp(-groundOffset, -1.0f, 1.0f)));
+ }
+ }
+ if(pHandling->Flags & HANDLING_NARROW_FRONTW)
+ mat.Scale(0.7f*mi->m_wheelScale, mi->m_wheelScale, mi->m_wheelScale);
+ else
+ mat.Scale(mi->m_wheelScale);
mat.Translate(pos);
mat.UpdateRW();
- if(CVehicle::bWheelsOnlyCheat)
- RpAtomicRender((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_RF]));
// Front left wheel
mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_LF]));
- pos.x = mat.GetPosition().x;
- pos.y = mat.GetPosition().y;
+ pos = mat.GetPosition();
pos.z = m_aWheelPosition[CARWHEEL_FRONT_LEFT];
if(Damage.GetWheelStatus(CARWHEEL_FRONT_LEFT) == WHEEL_STATUS_BURST)
- mat.SetRotate(-m_aWheelRotation[CARWHEEL_FRONT_LEFT], 0.0f, PI+m_fSteerAngle+0.3f*Sin(-m_aWheelRotation[CARWHEEL_FRONT_LEFT]));
+ mat.SetRotate(-m_aWheelRotation[CARWHEEL_FRONT_LEFT], 0.0f, PI+m_fSteerAngle+0.3f*Sin(m_aWheelRotation[CARWHEEL_FRONT_LEFT]));
else
mat.SetRotate(-m_aWheelRotation[CARWHEEL_FRONT_LEFT], 0.0f, PI+m_fSteerAngle);
- mat.Scale(mi->m_wheelScale);
+ if(GetStatus() == STATUS_PLAYER){
+ if(bHoverCheat && m_aSuspensionSpringRatioPrev[CARWHEEL_FRONT_LEFT] < 1.0f &&
+ m_aWheelColPoints[CARWHEEL_FRONT_LEFT].surfaceB == SURFACE_WATER){
+ // hovering on water
+ mat.RotateY(HALFPI);
+ if((CTimer::GetFrameCounter()+CARWHEEL_FRONT_LEFT) & 1){
+ CParticle::AddParticle(PARTICLE_STEAM_NY_SLOWMOTION, m_aWheelColPoints[CARWHEEL_FRONT_LEFT].point,
+ 0.5f*m_vecMoveSpeed-0.1f*GetRight(), nil, 0.4f, hoverParticleCol);
+ }else{
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, m_aWheelColPoints[CARWHEEL_FRONT_LEFT].point,
+ 0.3f*m_vecMoveSpeed-0.15f*GetRight()+CVector(0.0f, 0.0f, 0.1f), nil, 0.15f, hoverParticleCol,
+ CGeneral::GetRandomNumberInRange(0.0f, 90.0f),
+ CGeneral::GetRandomNumberInRange(0.0f, 10.0f), 1);
+ }
+#ifdef BETTER_ALLCARSAREDODO_CHEAT
+ } else if (bAllDodosCheat && m_nDriveWheelsOnGround == 0 && m_nDriveWheelsOnGroundPrev == 0) {
+ mat.RotateY(HALFPI);
+#endif
+ }else{
+ // tilt wheel depending oh how much it presses on ground
+ float groundOffset = pos.z + m_fHeightAboveRoad - 0.5f*mi->m_wheelScale;
+ if(GetModelIndex() == MI_VOODOO)
+ groundOffset *= 0.6f;
+ mat.RotateY(Asin(Clamp(groundOffset, -1.0f, 1.0f)));
+ }
+ }
+ if(pHandling->Flags & HANDLING_NARROW_FRONTW)
+ mat.Scale(0.7f*mi->m_wheelScale, mi->m_wheelScale, mi->m_wheelScale);
+ else
+ mat.Scale(mi->m_wheelScale);
mat.Translate(pos);
mat.UpdateRW();
- if(CVehicle::bWheelsOnlyCheat)
- RpAtomicRender((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_LF]));
ProcessSwingingDoor(CAR_DOOR_LF, DOOR_FRONT_LEFT);
ProcessSwingingDoor(CAR_DOOR_RF, DOOR_FRONT_RIGHT);
@@ -2140,11 +2919,104 @@ CAutomobile::Render(void)
ProcessSwingingDoor(CAR_DOOR_RR, DOOR_REAR_RIGHT);
ProcessSwingingDoor(CAR_BONNET, DOOR_BONNET);
ProcessSwingingDoor(CAR_BOOT, DOOR_BOOT);
+ }
+
+ if((GetModelIndex() == MI_PHEONIX || GetModelIndex() == MI_BFINJECT) &&
+ GetStatus() == STATUS_PLAYER && m_aCarNodes[CAR_WING_LR]){
+ float rotation = 0.0f;
+
+ if(GetModelIndex() == MI_BFINJECT)
+ if(m_fPropellerRotation > TWOPI) m_fPropellerRotation -= TWOPI;
- mi->SetVehicleColour(m_currentColour1, m_currentColour2);
+ if(Abs(m_fGasPedal) > 0.0f){
+ if(GetModelIndex() == MI_BFINJECT){
+ m_fPropellerRotation += 0.2f*CTimer::GetTimeStep();
+ rotation = m_fPropellerRotation;
+ }else{
+ if(m_fPropellerRotation < 1.3f){
+ m_fPropellerRotation = Min(m_fPropellerRotation+0.1f*CTimer::GetTimeStep(), 1.3f);
+ rotation = m_fPropellerRotation;
+ }else{
+ float wave = Sin((CTimer::GetTimeInMilliseconds()%10000)/70.0f);
+ rotation = m_fPropellerRotation + 0.13*wave;
+ }
+ }
+ }else{
+ if(GetModelIndex() == MI_BFINJECT){
+ m_fPropellerRotation += 0.1f*CTimer::GetTimeStep();
+ rotation = m_fPropellerRotation;
+ }else{
+ if(m_fPropellerRotation > 0.0f){
+ m_fPropellerRotation = Max(m_fPropellerRotation-0.05f*CTimer::GetTimeStep(), 0.0f);
+ rotation = m_fPropellerRotation;
+ }
+ }
+ }
+
+ mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WING_LR]));
+ pos = mat.GetPosition();
+ if(GetModelIndex() == MI_BFINJECT)
+ mat.SetRotateY(rotation);
+ else
+ mat.SetRotateX(rotation);
+ mat.Translate(pos);
+ mat.UpdateRW();
}
+}
- if(!CVehicle::bWheelsOnlyCheat)
+void
+CAutomobile::Render(void)
+{
+ CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex());
+
+ mi->SetVehicleColour(m_currentColour1, m_currentColour2);
+
+ if(IsRealHeli()){
+ RpAtomic *atomic = nil;
+ int rotorAlpha = (1.5f - Min(1.7f*Max(m_aWheelSpeed[1],0.0f)/0.22f, 1.5f))*255.0f;
+ rotorAlpha = Min(rotorAlpha, 255);
+ int blurAlpha = Max(1.5f*m_aWheelSpeed[1]/0.22f - 0.4f, 0.0f)*150.0f;
+ blurAlpha = Min(blurAlpha, 150);
+
+ // Top rotor
+ if(m_aCarNodes[CAR_BONNET]){
+ RwFrameForAllObjects(m_aCarNodes[CAR_BONNET], GetCurrentAtomicObjectCB, &atomic);
+ if(atomic)
+ SetComponentAtomicAlpha(atomic, rotorAlpha);
+ }
+ atomic = nil;
+ // Rear rotor
+ if(m_aCarNodes[CAR_BOOT]){
+ RwFrameForAllObjects(m_aCarNodes[CAR_BOOT], GetCurrentAtomicObjectCB, &atomic);
+ if(atomic)
+ SetComponentAtomicAlpha(atomic, rotorAlpha);
+ }
+ atomic = nil;
+ // Blurred top rotor
+ if(m_aCarNodes[CAR_WINDSCREEN]){
+ RwFrameForAllObjects(m_aCarNodes[CAR_WINDSCREEN], GetCurrentAtomicObjectCB, &atomic);
+ if(atomic)
+ SetComponentAtomicAlpha(atomic, blurAlpha);
+ }
+ atomic = nil;
+ // Blurred rear rotor
+ if(m_aCarNodes[CAR_BUMP_REAR]){
+ RwFrameForAllObjects(m_aCarNodes[CAR_BUMP_REAR], GetCurrentAtomicObjectCB, &atomic);
+ if(atomic)
+ SetComponentAtomicAlpha(atomic, blurAlpha);
+ }
+ }
+
+ if(CVehicle::bWheelsOnlyCheat){
+ RpAtomicRender((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_RB]));
+ RpAtomicRender((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_LB]));
+ RpAtomicRender((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_RF]));
+ RpAtomicRender((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_LF]));
+ if(m_aCarNodes[CAR_WHEEL_RM])
+ RpAtomicRender((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_RM]));
+ if(m_aCarNodes[CAR_WHEEL_LM])
+ RpAtomicRender((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_LM]));
+ }else
CEntity::Render();
}
@@ -2167,6 +3039,10 @@ CAutomobile::ProcessEntityCollision(CEntity *ent, CColPoint *colpoints)
for(i = 0; i < 4; i++)
prevRatios[i] = m_aSuspensionSpringRatio[i];
+ if(m_bIsVehicleBeingShifted || bSkipLineCol || ent->IsPed() ||
+ GetModelIndex() == MI_DODO && ent->IsVehicle())
+ colModel->numLines = 0;
+
int numCollisions = CCollision::ProcessColModels(GetMatrix(), *colModel,
ent->GetMatrix(), *ent->GetColModel(),
colpoints,
@@ -2175,12 +3051,7 @@ CAutomobile::ProcessEntityCollision(CEntity *ent, CColPoint *colpoints)
// m_aSuspensionSpringRatio are now set to the point where the tyre touches ground.
// In ProcessControl these will be re-normalized to ignore the tyre radius.
- if(m_bIsVehicleBeingShifted || bSkipLineCol ||
- GetModelIndex() == MI_DODO && (ent->IsPed() || ent->IsVehicle())){
- // don't do line collision
- for(i = 0; i < 4; i++)
- m_aSuspensionSpringRatio[i] = prevRatios[i];
- }else{
+ if(colModel->numLines){
for(i = 0; i < 4; i++)
if(m_aSuspensionSpringRatio[i] < 1.0f && m_aSuspensionSpringRatio[i] < prevRatios[i]){
numWheelCollisions++;
@@ -2192,30 +3063,14 @@ CAutomobile::ProcessEntityCollision(CEntity *ent, CColPoint *colpoints)
m_aGroundPhysical[i] = phys;
phys->RegisterReference((CEntity**)&m_aGroundPhysical[i]);
m_aGroundOffset[i] = m_aWheelColPoints[i].point - phys->GetPosition();
-
- if(phys->GetModelIndex() == MI_BODYCAST && GetStatus() == STATUS_PLAYER){
- // damage body cast
- float speed = m_vecMoveSpeed.MagnitudeSqr();
- if(speed > 0.1f){
- CObject::nBodyCastHealth -= 0.1f*m_fMass*speed;
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_PED_BODYCAST_HIT, 0.0f);
- }
-
- // move body cast
- if(phys->GetIsStatic()){
- phys->SetIsStatic(false);
- phys->m_nStaticFrames = 0;
- phys->ApplyMoveForce(m_vecMoveSpeed / Sqrt(speed));
- phys->AddToMovingList();
- }
- }
}
m_nSurfaceTouched = m_aWheelColPoints[i].surfaceB;
if(ent->IsBuilding())
m_pCurGroundEntity = ent;
}
- }
+ }else
+ colModel->numLines = 4;
if(numCollisions > 0 || numWheelCollisions > 0){
AddCollisionRecord(ent);
@@ -2241,10 +3096,12 @@ CAutomobile::ProcessControlInputs(uint8 pad)
{
float speed = DotProduct(m_vecMoveSpeed, GetForward());
- if(CPad::GetPad(pad)->GetExitVehicle())
- bIsHandbrakeOn = true;
- else
+ if(!CPad::GetPad(pad)->GetExitVehicle() ||
+ pDriver && pDriver->m_pVehicleAnim && (pDriver->m_pVehicleAnim->animId == ANIM_STD_ROLLOUT_LHS ||
+ pDriver->m_pVehicleAnim->animId == ANIM_STD_ROLLOUT_RHS))
bIsHandbrakeOn = !!CPad::GetPad(pad)->GetHandBrake();
+ else
+ bIsHandbrakeOn = true;
// Steer left/right
if(CCamera::m_bUseMouse3rdPerson && !CVehicle::m_bDisableMouseSteering){
@@ -2272,8 +3129,14 @@ CAutomobile::ProcessControlInputs(uint8 pad)
acceleration *= 0.3f;
if(Abs(speed) < 0.01f){
// standing still, go into direction we want
- m_fGasPedal = acceleration;
- m_fBrakePedal = 0.0f;
+ if(CPad::GetPad(pad)->GetAccelerate() > 150.0f && CPad::GetPad(pad)->GetBrake() > 150.0f){
+ m_fGasPedal = CPad::GetPad(pad)->GetAccelerate()/255.0f;
+ m_fBrakePedal = CPad::GetPad(pad)->GetBrake()/255.0f;
+ m_doingBurnout = 1;
+ }else{
+ m_fGasPedal = acceleration;
+ m_fBrakePedal = 0.0f;
+ }
}else{
#if 1
// simpler than the code below
@@ -2322,17 +3185,6 @@ CAutomobile::ProcessControlInputs(uint8 pad)
m_fSteerAngle = DEGTORAD(pHandling->fSteeringLock) * fValue;
if(bComedyControls){
-#if 0 // old comedy controls from PS2 - same as bike's
- if(((CTimer::GetTimeInMilliseconds() >> 10) & 0xF) < 12)
- m_fGasPedal = 1.0f;
- if((((CTimer::GetTimeInMilliseconds() >> 10)+6) & 0xF) < 12)
- m_fBrakePedal = 0.0f;
- bIsHandbrakeOn = false;
- if(CTimer::GetTimeInMilliseconds() & 0x800)
- m_fSteerAngle += 0.08f;
- else
- m_fSteerAngle -= 0.03f;
-#else
int rnd = CGeneral::GetRandomNumber() % 10;
switch(m_comedyControlState){
case 0:
@@ -2352,14 +3204,16 @@ CAutomobile::ProcessControlInputs(uint8 pad)
m_comedyControlState = 0;
break;
}
- }else{
+ }else
m_comedyControlState = 0;
-#endif
- }
// Brake if player isn't in control
// BUG: game always uses pad 0 here
+#ifdef FIX_BUGS
if(CPad::GetPad(pad)->ArePlayerControlsDisabled()){
+#else
+ if(CPad::GetPad(0)->ArePlayerControlsDisabled()){
+#endif
m_fBrakePedal = 1.0f;
bIsHandbrakeOn = true;
m_fGasPedal = 0.0f;
@@ -2377,11 +3231,7 @@ void
CAutomobile::FireTruckControl(void)
{
if(this == FindPlayerVehicle()){
-#ifdef FIX_BUGS
- if (!CPad::GetPad(0)->GetCarGunFired())
-#else
- if (!CPad::GetPad(0)->GetWeapon())
-#endif // FIX_BUGS
+ if(!CPad::GetPad(0)->GetCarGunFired())
return;
#ifdef FREE_CAM
if (!CCamera::bFreeCam)
@@ -2538,22 +3388,10 @@ CAutomobile::TankControl(void)
flashPos += 0.1f*shotDir;
CParticle::AddParticle(PARTICLE_GUNFLASH, flashPos, nullDir, nil, 0.15f, black, 0, 0, 0, lifeSpan);
}
-
- // Actually update turret node
- if(m_aCarNodes[CAR_WINDSCREEN]){
- CMatrix mat;
- CVector pos;
-
- mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WINDSCREEN]));
- pos = mat.GetPosition();
- mat.SetRotateZ(m_fCarGunLR);
- mat.Translate(pos);
- mat.UpdateRW();
- }
}
-#define HYDRAULIC_UPPER_EXT (-0.12f)
-#define HYDRAULIC_LOWER_EXT (0.14f)
+#define HYDRAULIC_UPPER_EXT (-0.16f)
+#define HYDRAULIC_LOWER_EXT (0.16f)
void
CAutomobile::HydraulicControl(void)
@@ -2661,8 +3499,6 @@ CAutomobile::HydraulicControl(void)
if(m_hydraulicState < 20 && m_fVelocityChangeForAudio > 0.2f){
if(m_hydraulicState == 0){
m_hydraulicState = 20;
- for(i = 0; i < 4; i++)
- m_aWheelPosition[i] -= 0.06f;
DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_HYDRAULIC_1, 0.0f);
setPrevRatio = true;
}else{
@@ -2736,7 +3572,6 @@ CAutomobile::HydraulicControl(void)
}
setPrevRatio = true;
- m_aWheelPosition[i] -= 0.05f;
}
DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_HYDRAULIC_2, 0.0f);
}
@@ -2767,7 +3602,6 @@ CAutomobile::HydraulicControl(void)
if(suspChange[i] > 1.0f)
suspChange[i] = 1.0f;
- float oldZ = specialColModel->lines[i].p1.z;
float upperLimit = suspChange[i]*(extendedUpperLimit-normalUpperLimit) + normalUpperLimit;
float springLength = suspChange[i]*(extendedSpringLength-normalSpringLength) + normalSpringLength;
float lineLength = springLength + wheelRadius;
@@ -2787,15 +3621,11 @@ CAutomobile::HydraulicControl(void)
m_aSuspensionSpringRatio[i] = (specialColModel->lines[i].p0.z - wheelPositions[i])/m_aSuspensionLineLength[i];
if(m_aSuspensionSpringRatio[i] > 1.0f)
m_aSuspensionSpringRatio[i] = 1.0f;
- m_aWheelPosition[i] -= (oldZ - specialColModel->lines[i].p1.z)*0.3f;
}
}
}else{
- if(m_hydraulicState < 104){
+ if(m_hydraulicState < 104)
m_hydraulicState++;
- for(i = 0; i < 4; i++)
- m_aWheelPosition[i] -= 0.1f;
- }
if(m_fVelocityChangeForAudio < 0.1f){
normalUpperLimit += HYDRAULIC_UPPER_EXT;
@@ -2862,18 +3692,47 @@ CAutomobile::ProcessBuoyancy(void)
if(mod_Buoyancy.ProcessBuoyancy(this, m_fBuoyancy, &point, &impulse)){
bTouchingWater = true;
- ApplyMoveForce(impulse);
- ApplyTurnForce(impulse, point);
-
- CVector initialSpeed = m_vecMoveSpeed;
float timeStep = Max(CTimer::GetTimeStep(), 0.01f);
float impulseRatio = impulse.z / (GRAVITY * m_fMass * timeStep);
float waterResistance = Pow(1.0f - 0.05f*impulseRatio, CTimer::GetTimeStep());
m_vecMoveSpeed *= waterResistance;
m_vecTurnSpeed *= waterResistance;
- if(impulseRatio > 0.5f){
+ bool heliHitWaterHard = false;
+ if(IsRealHeli() && m_aWheelSpeed[1] > 0.15f){
+ if(GetModelIndex() == MI_SEASPAR){
+ if(impulseRatio > 3.0f){
+ m_aWheelSpeed[1] = 0.0f;
+ heliHitWaterHard = true;
+ }
+ }else{
+ float strength = Max(8.0f*impulseRatio, 1.0f);
+ ApplyMoveForce(-2.0f*impulse/strength);
+ ApplyTurnForce(-impulse/strength, point);
+ if(impulseRatio > 0.9f){
+ m_aWheelSpeed[1] = 0.0f;
+ heliHitWaterHard = true;
+ }else
+ return;
+ }
+ }
+
+ bTouchingWater = true;
+ ApplyMoveForce(impulse);
+ ApplyTurnForce(impulse, point);
+ CVector initialSpeed = m_vecMoveSpeed;
+
+ if(m_modelIndex == MI_SEASPAR && impulseRatio < 3.0f && (GetUp().z > -0.5f || impulseRatio < 0.6f) ||
+ CVehicle::bHoverCheat && GetStatus() == STATUS_PLAYER && GetUp().z > 0.1f){
+ bIsInWater = false;
+ bIsDrowning = false;
+ }else if(heliHitWaterHard || impulseRatio > 1.0f ||
+ impulseRatio > 0.6f && (m_aSuspensionSpringRatio[0] == 1.0f ||
+ m_aSuspensionSpringRatio[1] == 1.0f ||
+ m_aSuspensionSpringRatio[2] == 1.0f ||
+ m_aSuspensionSpringRatio[3] == 1.0f)){
bIsInWater = true;
+ bIsDrowning = true;
if(m_vecMoveSpeed.z < -0.1f)
m_vecMoveSpeed.z = -0.1f;
@@ -2888,49 +3747,35 @@ 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;
- if(initialSpeed.z < -0.3f && impulse.z > 0.3f){
-#if defined(PC_PARTICLE) || defined (PS2_ALTERNATIVE_CARSPLASH)
+ if(initialSpeed.z < -0.1f && impulse.z > 0.3f || heliHitWaterHard){
RwRGBA color;
- color.red = (0.5f * CTimeCycle::GetDirectionalRed() + CTimeCycle::GetAmbientRed())*0.45f*255;
- color.green = (0.5f * CTimeCycle::GetDirectionalGreen() + CTimeCycle::GetAmbientGreen())*0.45f*255;
- color.blue = (0.5f * CTimeCycle::GetDirectionalBlue() + CTimeCycle::GetAmbientBlue())*0.45f*255;
+ color.red = (0.5f * CTimeCycle::GetDirectionalRed() + CTimeCycle::GetAmbientRed_Obj())*0.45f*255;
+ color.green = (0.5f * CTimeCycle::GetDirectionalGreen() + CTimeCycle::GetAmbientGreen_Obj())*0.45f*255;
+ color.blue = (0.5f * CTimeCycle::GetDirectionalBlue() + CTimeCycle::GetAmbientBlue_Obj())*0.45f*255;
color.alpha = CGeneral::GetRandomNumberInRange(0, 32) + 128;
+ CVector target = CVector(0.0f, 0.0f, CGeneral::GetRandomNumberInRange(0.15f, 0.45f));
CParticleObject::AddObject(POBJECT_CAR_WATER_SPLASH, GetPosition(),
- CVector(0.0f, 0.0f, CGeneral::GetRandomNumberInRange(0.15f, 0.3f)),
- 0.0f, 75, color, true);
-#else
- CVector pos = (initialSpeed * 2.0f) + (GetPosition() + point);
-
- for ( int32 i = 0; i < 360; i += 4 )
- {
- float fSin = Sin(float(i));
- float fCos = Cos(float(i));
-
- CVector dir(fSin*0.01f, fCos*0.01f, CGeneral::GetRandomNumberInRange(0.25f, 0.45f));
-
- CParticle::AddParticle(PARTICLE_CAR_SPLASH,
- pos + CVector(fSin*4.5f, fCos*4.5f, 0.0f),
- dir, NULL, 0.0f, CRGBA(225, 225, 255, 180));
-
- for ( int32 j = 0; j < 3; j++ )
- {
- float fMul = 1.5f * float(j + 1);
-
- CParticle::AddParticle(PARTICLE_CAR_SPLASH,
- pos + CVector(fSin * fMul, fCos * fMul, 0.0f),
- dir, NULL, 0.0f, CRGBA(225, 225, 255, 180));
- }
- }
-#endif
+ target, 0.0f, 75, color, true);
nGenerateRaindrops = CTimer::GetTimeInMilliseconds() + 300;
nGenerateWaterCircles = CTimer::GetTimeInMilliseconds() + 60;
+
+ if(heliHitWaterHard){
+ CVector right = CrossProduct(GetForward(), CVector(0.0f, 0.0f, 1.0f));
+ CParticleObject::AddObject(POBJECT_CAR_WATER_SPLASH, GetPosition() + right,
+ target, 0.0f, 75, color, true);
+ CParticleObject::AddObject(POBJECT_CAR_WATER_SPLASH, GetPosition() - right,
+ target, 0.0f, 75, color, true);
+ }
+
if(m_vecMoveSpeed.z < -0.2f)
m_vecMoveSpeed.z = -0.2f;
DMAudio.PlayOneShot(m_audioEntityId, SOUND_WATER_FALL, 0.0f);
@@ -2971,6 +3816,7 @@ CAutomobile::ProcessBuoyancy(void)
}
}else{
bIsInWater = false;
+ bIsDrowning = false;
bTouchingWater = false;
static RwRGBA splashCol = {155, 155, 185, 196};
@@ -2981,13 +3827,7 @@ CAutomobile::ProcessBuoyancy(void)
CVector pos = m_aWheelColPoints[i].point + 0.3f*GetUp() - GetPosition();
CVector vSpeed = GetSpeed(pos);
vSpeed.z = 0.0f;
-#ifdef GTA_PS2_STUFF
- // ps2 puddle physics
- CVector moveForce = CTimer::GetTimeStep() * (m_fMass * (vSpeed * -0.003f));
- ApplyMoveForce(moveForce.x, moveForce.y, moveForce.z);
-#endif
float fSpeed = vSpeed.MagnitudeSqr();
-#ifdef PC_PARTICLE
if(fSpeed > sq(0.05f)){
fSpeed = Sqrt(fSpeed);
@@ -3007,35 +3847,6 @@ CAutomobile::ProcessBuoyancy(void)
if((CTimer::GetFrameCounter() & 0xF) == 0)
DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_SPLASH, 2000.0f*fSpeed);
}
-#else
- if ( ( (CTimer::GetFrameCounter() + i) & 3 ) == 0 )
- {
- if(fSpeed > sq(0.05f))
- {
- fSpeed = Sqrt(fSpeed);
- CRGBA color(155, 185, 155, 255);
- float boxY = GetColModel()->boundingBox.max.y;
- CVector right = 0.5f * GetRight();
-
- if ( i == 2 )
- {
- CParticle::AddParticle(PARTICLE_PED_SPLASH,
- GetPosition() + (boxY * GetForward()) + right,
- 0.75f*m_vecMoveSpeed, NULL, 0.0f, color);
-
- }
- else if ( i == 0 )
- {
- CParticle::AddParticle(PARTICLE_PED_SPLASH,
- GetPosition() + (boxY * GetForward()) - right,
- 0.75f*m_vecMoveSpeed, NULL, 0.0f, color);
- }
-
- if((CTimer::GetFrameCounter() & 0xF) == 0)
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_SPLASH, 2000.0f*fSpeed);
- }
- }
-#endif
}
}
}
@@ -3044,16 +3855,21 @@ CAutomobile::ProcessBuoyancy(void)
void
CAutomobile::DoDriveByShootings(void)
{
- CAnimBlendAssociation *anim;
+ CAnimBlendAssociation *anim = nil;
+ CPlayerInfo* playerInfo = ((CPlayerPed*)pDriver)->GetPlayerInfoForThisPlayerPed();
+ if (playerInfo && !playerInfo->m_bDriveByAllowed)
+ return;
+
CWeapon *weapon = pDriver->GetWeapon();
- if(weapon->m_eWeaponType != WEAPONTYPE_UZI)
+ if(CWeaponInfo::GetWeaponInfo(weapon->m_eWeaponType)->m_nWeaponSlot != WEAPONSLOT_SUBMACHINEGUN)
return;
- weapon->Update(pDriver->m_audioEntityId);
+ weapon->Update(pDriver->m_audioEntityId, nil);
bool lookingLeft = false;
bool lookingRight = false;
- if(TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN){
+ if(TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN ||
+ TheCamera.m_bObbeCinematicCarCamOn){
if(CPad::GetPad(0)->GetLookLeft())
lookingLeft = true;
if(CPad::GetPad(0)->GetLookRight())
@@ -3065,37 +3881,42 @@ CAutomobile::DoDriveByShootings(void)
lookingRight = true;
}
+ AnimationId rightAnim = ANIM_STD_CAR_DRIVEBY_RIGHT;
+ AnimationId leftAnim = ANIM_STD_CAR_DRIVEBY_LEFT;
+ if (pDriver->m_pMyVehicle->bLowVehicle) {
+ rightAnim = ANIM_STD_CAR_DRIVEBY_RIGHT_LO;
+ leftAnim = ANIM_STD_CAR_DRIVEBY_LEFT_LO;
+ }
+
if(lookingLeft || lookingRight){
if(lookingLeft){
- anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_STD_CAR_DRIVEBY_RIGHT);
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), rightAnim);
if(anim)
anim->blendDelta = -1000.0f;
- anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_STD_CAR_DRIVEBY_LEFT);
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), leftAnim);
if(anim == nil || anim->blendDelta < 0.0f)
- CAnimManager::AddAnimation(pDriver->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_DRIVEBY_LEFT);
- 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_STD_CAR_DRIVEBY_LEFT);
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), leftAnim);
if(anim)
anim->blendDelta = -1000.0f;
- anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_STD_CAR_DRIVEBY_RIGHT);
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), rightAnim);
if(anim == nil || anim->blendDelta < 0.0f)
- CAnimManager::AddAnimation(pDriver->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_DRIVEBY_RIGHT);
- 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, true);
+ weapon->m_nTimer = CTimer::GetTimeInMilliseconds() + 70;
+ }
}
}else{
weapon->Reload();
- anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_STD_CAR_DRIVEBY_LEFT);
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), leftAnim);
if(anim)
anim->blendDelta = -1000.0f;
- anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_STD_CAR_DRIVEBY_RIGHT);
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), rightAnim);
if(anim)
anim->blendDelta = -1000.0f;
}
@@ -3111,6 +3932,44 @@ CAutomobile::DoDriveByShootings(void)
}
}
+void
+CAutomobile::DoHoverSuspensionRatios(void)
+{
+ int i;
+
+ if(GetUp().z < 0.1f)
+ return;
+
+ CColModel *colmodel = GetColModel();
+ for(i = 0; i < 4; i++){
+ float z, waterZ;
+ CVector upper = GetMatrix() * colmodel->lines[i].p0;
+ CVector lower = GetMatrix() * colmodel->lines[i].p1;
+ if(m_aSuspensionSpringRatio[i] < 1.0f)
+ z = m_aWheelColPoints[i].point.z;
+ else
+ z = -100.0f;
+ // see if touching water
+ if(CWaterLevel::GetWaterLevel(lower, &waterZ, false) &&
+ waterZ > z && lower.z-1.0f < waterZ){
+ // compress spring
+ if(lower.z < waterZ){
+ if(upper.z < waterZ)
+ m_aSuspensionSpringRatio[i] = 0.0f;
+ else
+ m_aSuspensionSpringRatio[i] = (upper.z - waterZ)/(upper.z - lower.z);
+ }else
+ m_aSuspensionSpringRatio[i] = 0.99999f;
+
+ m_aWheelColPoints[i].point = CVector((lower.x - upper.x)*m_aSuspensionSpringRatio[i] + upper.x,
+ (lower.y - upper.y)*m_aSuspensionSpringRatio[i] + upper.y,
+ waterZ);
+ m_aWheelColPoints[i].normal = CVector(0.0f, 0.0f, 1.0f);
+ m_aWheelColPoints[i].surfaceB = SURFACE_WATER;
+ }
+ }
+}
+
int32
CAutomobile::RcbanditCheckHitWheels(void)
{
@@ -3150,7 +4009,8 @@ CAutomobile::RcbanditCheck1CarWheels(CPtrList &list)
for(node = list.first; node; node = node->next){
car = (CAutomobile*)node->item;
- if(this != car && car->IsCar() && car->m_scanCode != CWorld::GetCurrentScanCode()){
+ if(this != car && car->IsCar() && car->GetModelIndex() != MI_RCBANDIT &&
+ car->m_scanCode != CWorld::GetCurrentScanCode()){
car->m_scanCode = CWorld::GetCurrentScanCode();
if(Abs(this->GetPosition().x - car->GetPosition().x) < 10.0f &&
@@ -3224,8 +4084,7 @@ void
CAutomobile::VehicleDamage(float impulse, uint16 damagedPiece)
{
int i;
- float damageMultiplier = 0.2f;
- bool doubleMoney = false;
+ float damageMultiplier = 0.333f;
if(impulse == 0.0f){
impulse = m_fDamageImpulse;
@@ -3233,19 +4092,30 @@ CAutomobile::VehicleDamage(float impulse, uint16 damagedPiece)
damageMultiplier = 1.0f;
}
+ if(GetStatus() == STATUS_PLAYER && CStats::GetPercentageProgress() >= 100.0f)
+ impulse *= 0.5f;
+
CVector pos(0.0f, 0.0f, 0.0f);
if(!bCanBeDamaged)
return;
+ if(m_pDamageEntity && m_pDamageEntity->IsPed() && ((CPed*)m_pDamageEntity)->bIsStanding){
+ float speed = ((CPed*)m_pDamageEntity)->m_vecAnimMoveDelta.y * DotProduct(GetForward(), m_vecDamageNormal);
+ if(speed < 0.0f)
+ impulse = Max(impulse + ((CPed*)m_pDamageEntity)->m_fMass * speed, 0.0f);
+ }
+
// damage flipped over car
if(GetUp().z < 0.0f && this != FindPlayerVehicle()){
if(bNotDamagedUpsideDown || GetStatus() == STATUS_PLAYER_REMOTE || bIsInWater)
return;
- m_fHealth -= 4.0f*CTimer::GetTimeStep();
+ if(GetStatus() != STATUS_WRECKED)
+ m_fHealth = Max(m_fHealth - 4.0f*CTimer::GetTimeStep(), 0.0f);
}
- if(impulse > 25.0f && GetStatus() != STATUS_WRECKED){
+ float minImpulse = GetModelIndex() == MI_RCRAIDER || GetModelIndex() == MI_RCGOBLIN ? 1.0f : 25.0f;
+ if(impulse > minImpulse && GetStatus() != STATUS_WRECKED){
if(bIsLawEnforcer &&
FindPlayerVehicle() && FindPlayerVehicle() == m_pDamageEntity &&
GetStatus() != STATUS_ABANDONED &&
@@ -3258,12 +4128,17 @@ CAutomobile::VehicleDamage(float impulse, uint16 damagedPiece)
CPad::GetPad(0)->StartShake(40000/freq, freq);
}
- if(bOnlyDamagedByPlayer){
+ if(GetStatus() != STATUS_PLAYER && bOnlyDamagedByPlayer){
if(m_pDamageEntity != FindPlayerPed() &&
m_pDamageEntity != FindPlayerVehicle())
return;
}
+ if(m_pDamageEntity && m_pDamageEntity->IsVehicle()){
+ m_nLastWeaponDamage = WEAPONTYPE_RAMMEDBYCAR;
+ m_pLastDamageEntity = m_pDamageEntity;
+ }
+
if(bCollisionProof)
return;
@@ -3283,109 +4158,81 @@ CAutomobile::VehicleDamage(float impulse, uint16 damagedPiece)
switch(damagedPiece){
case CAR_PIECE_BUMP_FRONT:
GetComponentWorldPosition(CAR_BUMP_FRONT, pos);
- dmgDrawCarCollidingParticles(pos, impulse);
- if(Damage.ApplyDamage(COMPONENT_BUMPER_FRONT, impulse*impulseMult, pHandling->fCollisionDamageMultiplier)){
+ dmgDrawCarCollidingParticles(pos, impulse*damageMultiplier);
+ if(Damage.ApplyDamage(COMPONENT_BUMPER_FRONT, impulse*impulseMult, pHandling->fCollisionDamageMultiplier))
SetBumperDamage(CAR_BUMP_FRONT, VEHBUMPER_FRONT);
- doubleMoney = true;
- }
if(m_aCarNodes[CAR_BONNET] && Damage.GetPanelStatus(VEHBUMPER_FRONT) == PANEL_STATUS_MISSING){
case CAR_PIECE_BONNET:
GetComponentWorldPosition(CAR_BONNET, pos);
- dmgDrawCarCollidingParticles(pos, impulse);
+ dmgDrawCarCollidingParticles(pos, impulse*damageMultiplier);
if(GetModelIndex() != MI_DODO)
- if(Damage.ApplyDamage(COMPONENT_DOOR_BONNET, impulse*impulseMult, pHandling->fCollisionDamageMultiplier)){
+ if(Damage.ApplyDamage(COMPONENT_DOOR_BONNET, impulse*impulseMult, pHandling->fCollisionDamageMultiplier))
SetDoorDamage(CAR_BONNET, DOOR_BONNET);
- doubleMoney = true;
- }
}
break;
case CAR_PIECE_BUMP_REAR:
GetComponentWorldPosition(CAR_BUMP_REAR, pos);
- dmgDrawCarCollidingParticles(pos, impulse);
- if(Damage.ApplyDamage(COMPONENT_BUMPER_REAR, impulse*impulseMult, pHandling->fCollisionDamageMultiplier)){
+ dmgDrawCarCollidingParticles(pos, impulse*damageMultiplier);
+ if(Damage.ApplyDamage(COMPONENT_BUMPER_REAR, impulse*impulseMult, pHandling->fCollisionDamageMultiplier))
SetBumperDamage(CAR_BUMP_REAR, VEHBUMPER_REAR);
- doubleMoney = true;
- }
if(m_aCarNodes[CAR_BOOT] && Damage.GetPanelStatus(VEHBUMPER_REAR) == PANEL_STATUS_MISSING){
case CAR_PIECE_BOOT:
GetComponentWorldPosition(CAR_BOOT, pos);
- dmgDrawCarCollidingParticles(pos, impulse);
- if(Damage.ApplyDamage(COMPONENT_DOOR_BOOT, impulse*impulseMult, pHandling->fCollisionDamageMultiplier)){
+ dmgDrawCarCollidingParticles(pos, impulse*damageMultiplier);
+ if(Damage.ApplyDamage(COMPONENT_DOOR_BOOT, impulse*impulseMult, pHandling->fCollisionDamageMultiplier))
SetDoorDamage(CAR_BOOT, DOOR_BOOT);
- doubleMoney = true;
- }
}
break;
case CAR_PIECE_DOOR_LF:
GetComponentWorldPosition(CAR_DOOR_LF, pos);
- dmgDrawCarCollidingParticles(pos, impulse);
- if((m_nDoorLock == CARLOCK_NOT_USED || m_nDoorLock == CARLOCK_UNLOCKED) &&
- Damage.ApplyDamage(COMPONENT_DOOR_FRONT_LEFT, impulse*impulseMult, pHandling->fCollisionDamageMultiplier)){
+ dmgDrawCarCollidingParticles(pos, impulse*damageMultiplier);
+ if(Damage.ApplyDamage(COMPONENT_DOOR_FRONT_LEFT, impulse*impulseMult, pHandling->fCollisionDamageMultiplier))
SetDoorDamage(CAR_DOOR_LF, DOOR_FRONT_LEFT);
- doubleMoney = true;
- }
break;
case CAR_PIECE_DOOR_RF:
GetComponentWorldPosition(CAR_DOOR_RF, pos);
- dmgDrawCarCollidingParticles(pos, impulse);
- if((m_nDoorLock == CARLOCK_NOT_USED || m_nDoorLock == CARLOCK_UNLOCKED) &&
- Damage.ApplyDamage(COMPONENT_DOOR_FRONT_RIGHT, impulse*impulseMult, pHandling->fCollisionDamageMultiplier)){
+ dmgDrawCarCollidingParticles(pos, impulse*damageMultiplier);
+ if(Damage.ApplyDamage(COMPONENT_DOOR_FRONT_RIGHT, impulse*impulseMult, pHandling->fCollisionDamageMultiplier))
SetDoorDamage(CAR_DOOR_RF, DOOR_FRONT_RIGHT);
- doubleMoney = true;
- }
break;
case CAR_PIECE_DOOR_LR:
GetComponentWorldPosition(CAR_DOOR_LR, pos);
- dmgDrawCarCollidingParticles(pos, impulse);
- if((m_nDoorLock == CARLOCK_NOT_USED || m_nDoorLock == CARLOCK_UNLOCKED) &&
- Damage.ApplyDamage(COMPONENT_DOOR_REAR_LEFT, impulse*impulseMult, pHandling->fCollisionDamageMultiplier)){
+ dmgDrawCarCollidingParticles(pos, impulse*damageMultiplier);
+ if(Damage.ApplyDamage(COMPONENT_DOOR_REAR_LEFT, impulse*impulseMult, pHandling->fCollisionDamageMultiplier))
SetDoorDamage(CAR_DOOR_LR, DOOR_REAR_LEFT);
- doubleMoney = true;
- }
break;
case CAR_PIECE_DOOR_RR:
GetComponentWorldPosition(CAR_DOOR_RR, pos);
- dmgDrawCarCollidingParticles(pos, impulse);
- if((m_nDoorLock == CARLOCK_NOT_USED || m_nDoorLock == CARLOCK_UNLOCKED) &&
- Damage.ApplyDamage(COMPONENT_DOOR_REAR_RIGHT, impulse*impulseMult, pHandling->fCollisionDamageMultiplier)){
+ dmgDrawCarCollidingParticles(pos, impulse*damageMultiplier);
+ if(Damage.ApplyDamage(COMPONENT_DOOR_REAR_RIGHT, impulse*impulseMult, pHandling->fCollisionDamageMultiplier))
SetDoorDamage(CAR_DOOR_RR, DOOR_REAR_RIGHT);
- doubleMoney = true;
- }
break;
case CAR_PIECE_WING_LF:
GetComponentWorldPosition(CAR_WING_LF, pos);
- dmgDrawCarCollidingParticles(pos, impulse);
- if(Damage.ApplyDamage(COMPONENT_PANEL_FRONT_LEFT, impulse*impulseMult, pHandling->fCollisionDamageMultiplier)){
+ dmgDrawCarCollidingParticles(pos, impulse*damageMultiplier);
+ if(Damage.ApplyDamage(COMPONENT_PANEL_FRONT_LEFT, impulse*impulseMult, pHandling->fCollisionDamageMultiplier))
SetPanelDamage(CAR_WING_LF, VEHPANEL_FRONT_LEFT);
- doubleMoney = true;
- }
break;
case CAR_PIECE_WING_RF:
GetComponentWorldPosition(CAR_WING_RF, pos);
- dmgDrawCarCollidingParticles(pos, impulse);
- if(Damage.ApplyDamage(COMPONENT_PANEL_FRONT_RIGHT, impulse*impulseMult, pHandling->fCollisionDamageMultiplier)){
+ dmgDrawCarCollidingParticles(pos, impulse*damageMultiplier);
+ if(Damage.ApplyDamage(COMPONENT_PANEL_FRONT_RIGHT, impulse*impulseMult, pHandling->fCollisionDamageMultiplier))
SetPanelDamage(CAR_WING_RF, VEHPANEL_FRONT_RIGHT);
- doubleMoney = true;
- }
break;
case CAR_PIECE_WING_LR:
GetComponentWorldPosition(CAR_WING_LR, pos);
- dmgDrawCarCollidingParticles(pos, impulse);
- if(Damage.ApplyDamage(COMPONENT_PANEL_REAR_LEFT, impulse*impulseMult, pHandling->fCollisionDamageMultiplier)){
+ dmgDrawCarCollidingParticles(pos, impulse*damageMultiplier);
+ if(Damage.ApplyDamage(COMPONENT_PANEL_REAR_LEFT, impulse*impulseMult, pHandling->fCollisionDamageMultiplier))
SetPanelDamage(CAR_WING_LR, VEHPANEL_REAR_LEFT);
- doubleMoney = true;
- }
break;
case CAR_PIECE_WING_RR:
GetComponentWorldPosition(CAR_WING_RR, pos);
- dmgDrawCarCollidingParticles(pos, impulse);
- if(Damage.ApplyDamage(COMPONENT_PANEL_REAR_RIGHT, impulse*impulseMult, pHandling->fCollisionDamageMultiplier)){
+ dmgDrawCarCollidingParticles(pos, impulse*damageMultiplier);
+ if(Damage.ApplyDamage(COMPONENT_PANEL_REAR_RIGHT, impulse*impulseMult, pHandling->fCollisionDamageMultiplier))
SetPanelDamage(CAR_WING_RR, VEHPANEL_REAR_RIGHT);
- doubleMoney = true;
- }
break;
case CAR_PIECE_WHEEL_LF:
@@ -3399,37 +4246,42 @@ CAutomobile::VehicleDamage(float impulse, uint16 damagedPiece)
uint8 oldStatus = Damage.GetPanelStatus(VEHPANEL_WINDSCREEN);
SetPanelDamage(CAR_WINDSCREEN, VEHPANEL_WINDSCREEN);
if(oldStatus != Damage.GetPanelStatus(VEHPANEL_WINDSCREEN)){
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_WINDSHIELD_CRACK, 0.0f);
- doubleMoney = true;
+ // DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_WINDSHIELD_CRACK, 0.0f);
}
}
break;
}
-
- if(m_pDamageEntity && m_pDamageEntity == FindPlayerVehicle() && impulse > 10.0f){
- int money = (doubleMoney ? 2 : 1) * impulse*pHandling->nMonetaryValue/1000000.0f;
- money = Min(money, 40);
- if(money > 2){
- sprintf(gString, "$%d", money);
- CWorld::Players[CWorld::PlayerInFocus].m_nMoney += money;
- }
- }
}
- float damage = (impulse-25.0f)*pHandling->fCollisionDamageMultiplier*0.6f*damageMultiplier;
+ float damage = (impulse-minImpulse)*pHandling->fCollisionDamageMultiplier*0.6f*damageMultiplier;
if(GetModelIndex() == MI_SECURICA && m_pDamageEntity && m_pDamageEntity->GetStatus() == STATUS_PLAYER)
damage *= 7.0f;
+ if(GetModelIndex() == MI_RCGOBLIN || GetModelIndex() == MI_RCRAIDER)
+ damage *= 30.0f;
+
if(damage > 0.0f){
+ if(damage > 5.0f &&
+ pDriver &&
+ m_pDamageEntity && m_pDamageEntity->IsVehicle() &&
+ (this != FindPlayerVehicle() || ((CVehicle*)m_pDamageEntity)->VehicleCreatedBy == MISSION_VEHICLE) &&
+ ((CVehicle*)m_pDamageEntity)->pDriver){
+ if(GetVehicleAppearance() == VEHICLE_APPEARANCE_CAR)
+ pDriver->Say(SOUND_PED_CRASH_CAR);
+ else
+ pDriver->Say(SOUND_PED_CRASH_VEHICLE);
+ }
+
int oldHealth = m_fHealth;
- if(this == FindPlayerVehicle()){
+ if(this == FindPlayerVehicle())
m_fHealth -= bTakeLessDamage ? damage/6.0f : damage/2.0f;
- }else{
- if(damage > 35.0f && pDriver)
- pDriver->Say(SOUND_PED_ANNOYED_DRIVER);
- m_fHealth -= bTakeLessDamage ? damage/12.0f : damage/4.0f;
- }
+ else if(bTakeLessDamage)
+ m_fHealth -= damage/12.0f;
+ else if(m_pDamageEntity && m_pDamageEntity == FindPlayerVehicle())
+ m_fHealth -= damage/1.5f;
+ else
+ m_fHealth -= damage/4.0f;
if(m_fHealth <= 0.0f && oldHealth > 0)
m_fHealth = 1.0f;
}
@@ -3504,15 +4356,16 @@ CAutomobile::dmgDrawCarCollidingParticles(const CVector &pos, float amount)
void
CAutomobile::AddDamagedVehicleParticles(void)
{
+ int i, n;
+
if(this == FindPlayerVehicle() && TheCamera.GetLookingForwardFirstPerson())
return;
-
- uint8 engineStatus = Damage.GetEngineStatus();
- if(engineStatus < ENGINE_STATUS_STEAM1)
+ if(this != FindPlayerVehicle() && (CTimer::GetFrameCounter() + m_randomSeed) & 1)
+ return;
+ if(m_fHealth >= 650.0f)
return;
- float fwdSpeed = DotProduct(m_vecMoveSpeed, GetForward()) * 180.0f;
- CVector direction = 0.5f*m_vecMoveSpeed;
+ CVector direction = 0.85f*m_vecMoveSpeed;
CVector damagePos = ((CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex()))->m_positions[CAR_POS_HEADLIGHTS];
switch(Damage.GetDoorStatus(DOOR_BONNET)){
@@ -3530,26 +4383,72 @@ CAutomobile::AddDamagedVehicleParticles(void)
if(GetModelIndex() == MI_BFINJECT)
damagePos = CVector(0.3f, -1.5f, -0.1f);
-
+ else if(GetModelIndex() == MI_CADDY)
+ damagePos = CVector(0.6f, -1.0f, -0.25f);
+ else if(IsRealHeli()){
+ damagePos.x = 0.4f*GetColModel()->boundingBox.max.x;
+ damagePos.y = 0.2f*GetColModel()->boundingBox.min.y;
+ damagePos.z = 0.3f*GetColModel()->boundingBox.max.z;
+ }else
+ damagePos.z += 0.4f*(GetColModel()->boundingBox.max.z-damagePos.z) * DotProduct(GetForward(), m_vecMoveSpeed);
damagePos = GetMatrix()*damagePos;
damagePos.z += 0.15f;
- if(engineStatus < ENGINE_STATUS_STEAM2){
- if(fwdSpeed < 90.0f){
- direction.z += 0.05f;
- CParticle::AddParticle(PARTICLE_ENGINE_STEAM, damagePos, direction, nil, 0.1f);
- }
- }else if(engineStatus < ENGINE_STATUS_SMOKE){
- if(fwdSpeed < 90.0f)
- CParticle::AddParticle(PARTICLE_ENGINE_STEAM, damagePos, direction, nil, 0.0f);
- }else if(engineStatus < ENGINE_STATUS_ON_FIRE){
- if(fwdSpeed < 90.0f){
- CParticle::AddParticle(PARTICLE_ENGINE_STEAM, damagePos, direction, nil, 0.0f);
- CParticle::AddParticle(PARTICLE_ENGINE_SMOKE, damagePos, 0.3f*direction, nil, 0.0f);
- }
- }else if(m_fHealth > 250.0f){
- if(fwdSpeed < 90.0f)
- CParticle::AddParticle(PARTICLE_ENGINE_SMOKE2, damagePos, 0.2f*direction, nil, 0.0f);
+ bool electric = pHandling->Transmission.nEngineType == 'E';
+
+ if(electric && m_fHealth < 320.0f && m_fHealth > 1.0f){
+ direction = 0.85f*m_vecMoveSpeed;
+ direction += GetRight() * CGeneral::GetRandomNumberInRange(0.0f, 0.04f) * (1.0f - 2.0f*m_vecMoveSpeed.Magnitude());
+ direction.z += 0.001f;
+ n = (CGeneral::GetRandomNumber() & 7) + 2;
+ for(i = 0; i < n; i++)
+ CParticle::AddParticle(PARTICLE_SPARK_SMALL, damagePos, direction);
+ if(((CTimer::GetFrameCounter() + m_randomSeed) & 7) == 0)
+ CParticle::AddParticle(PARTICLE_ENGINE_SMOKE2, damagePos, 0.8f*m_vecMoveSpeed, nil, 0.1f, 0, 0, 0, 1000);
+ }else if(electric && m_fHealth < 460.0f){
+ direction = 0.85f*m_vecMoveSpeed;
+ direction += GetRight() * CGeneral::GetRandomNumberInRange(0.0f, 0.04f) * (1.0f - 2.0f*m_vecMoveSpeed.Magnitude());
+ direction.z += 0.001f;
+ n = (CGeneral::GetRandomNumber() & 3) + 2;
+ for(i = 0; i < n; i++)
+ CParticle::AddParticle(PARTICLE_SPARK_SMALL, damagePos, direction);
+ if(((CTimer::GetFrameCounter() + m_randomSeed) & 0xF) == 0)
+ CParticle::AddParticle(PARTICLE_ENGINE_SMOKE, damagePos, 0.8f*m_vecMoveSpeed, nil, 0.1f, 0, 0, 0, 1000);
+ }else if(m_fHealth < 250.0f){
+ // nothing
+ }else if(m_fHealth < 320.0f){
+ CParticle::AddParticle(PARTICLE_ENGINE_SMOKE2, damagePos, 0.8f*direction);
+ }else if(m_fHealth < 390.0f){
+ CParticle::AddParticle(PARTICLE_ENGINE_STEAM, damagePos, 0.75f*direction);
+ CParticle::AddParticle(PARTICLE_ENGINE_SMOKE, damagePos, 0.85f*direction);
+ }else if(m_fHealth < 460.0f){
+ int rnd = CTimer::GetFrameCounter() + m_randomSeed;
+ if(rnd < 10 ||
+ rnd < 70 && rnd > 25 ||
+ rnd < 160 && rnd > 100 ||
+ rnd < 200 && rnd > 175 ||
+ rnd > 235)
+ return;
+ direction.z += 0.05f*Max(1.0f - 1.6f*m_vecMoveSpeed.Magnitude(), 0.0f);
+ if(electric){
+ // BUG. we had that case already
+ direction = 0.85f*m_vecMoveSpeed;
+ direction += GetRight() * CGeneral::GetRandomNumberInRange(0.0f, 0.04f) * (1.0f - 2.0f*m_vecMoveSpeed.Magnitude());
+ direction.z += 0.001f;
+ n = (CGeneral::GetRandomNumber() & 2) + 2;
+ for(i = 0; i < n; i++)
+ CParticle::AddParticle(PARTICLE_SPARK_SMALL, damagePos, direction);
+ if(((CTimer::GetFrameCounter() + m_randomSeed) & 0xF) == 0)
+ CParticle::AddParticle(PARTICLE_ENGINE_SMOKE, damagePos, 0.8f*m_vecMoveSpeed, nil, 0.1f, 0, 0, 0, 1000);
+ }else{
+ if(TheCamera.GetLookDirection() != LOOKING_FORWARD)
+ CParticle::AddParticle(PARTICLE_ENGINE_STEAM, damagePos, 0.75f*direction);
+ else if(((CTimer::GetFrameCounter() + m_randomSeed) & 1) == 0)
+ CParticle::AddParticle(PARTICLE_ENGINE_STEAM, damagePos, 0.85f*m_vecMoveSpeed);
+ }
+ }else if(((CTimer::GetFrameCounter() + m_randomSeed) & 3) == 0 ||
+ ((CTimer::GetFrameCounter() + m_randomSeed) & 3) == 2){
+ CParticle::AddParticle(PARTICLE_ENGINE_STEAM, damagePos, 0.9f*direction);
}
}
@@ -3561,9 +4460,11 @@ CAutomobile::AddWheelDirtAndWater(CColPoint *colpoint, uint32 belowEffectSpeed)
static RwRGBA grassCol = { 8, 24, 8, 255 };
static RwRGBA gravelCol = { 64, 64, 64, 255 };
static RwRGBA mudCol = { 64, 32, 16, 255 };
+ static RwRGBA sandCol = { 170, 165, 140, 255 };
static RwRGBA waterCol = { 48, 48, 64, 0 };
- if(!belowEffectSpeed)
+ if(!belowEffectSpeed &&
+ colpoint->surfaceB != SURFACE_SAND && colpoint->surfaceB != SURFACE_SAND_BEACH)
return 0;
switch(colpoint->surfaceB){
@@ -3582,7 +4483,7 @@ CAutomobile::AddWheelDirtAndWater(CColPoint *colpoint, uint32 belowEffectSpeed)
for(i = 0; i < 4; i++){
dir.z = CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
CParticle::AddParticle(PARTICLE_WHEEL_DIRT, colpoint->point, dir, nil,
- CGeneral::GetRandomNumberInRange(0.02f, 0.06f), gravelCol);
+ CGeneral::GetRandomNumberInRange(0.05f, 0.09f), gravelCol);
}
return 1;
case SURFACE_MUD_DRY:
@@ -3594,30 +4495,30 @@ CAutomobile::AddWheelDirtAndWater(CColPoint *colpoint, uint32 belowEffectSpeed)
CGeneral::GetRandomNumberInRange(0.02f, 0.06f), mudCol);
}
return 0;
+ case SURFACE_SAND:
+ case SURFACE_SAND_BEACH:
+ if(CTimer::GetFrameCounter() & 2 ||
+ CGeneral::GetRandomNumberInRange(CWeather::WetRoads, 1.01f) > 0.5f)
+ return 0;
+ dir.x = 0.5f*m_vecMoveSpeed.x;
+ dir.y = 0.5f*m_vecMoveSpeed.y;
+ for(i = 0; i < 1; i++){
+ dir.z = CGeneral::GetRandomNumberInRange(0.02f, 0.055f);
+ CParticle::AddParticle(PARTICLE_SAND, colpoint->point, dir, nil,
+ 2.0f*m_vecMoveSpeed.Magnitude(), sandCol);
+ }
+ return 0;
default:
- if ( CWeather::WetRoads > 0.01f
-#ifdef PC_PARTICLE
- && CTimer::GetFrameCounter() & 1
-#endif
- )
- {
- CParticle::AddParticle(
-#if defined(FIX_BUGS) && !defined(PC_PARTICLE) // looks wrong on PC particles
- PARTICLE_WHEEL_WATER,
-#else
- PARTICLE_WATERSPRAY,
-#endif
- colpoint->point + CVector(0.0f, 0.0f, 0.25f+0.25f),
-#ifdef PC_PARTICLE
- CVector(0.0f, 0.0f, 1.0f),
-#else
- CVector(0.0f, 0.0f, CGeneral::GetRandomNumberInRange(0.005f, 0.04f)),
-#endif
- nil,
- CGeneral::GetRandomNumberInRange(0.1f, 0.5f), waterCol);
+ if(CWeather::WetRoads > 0.01f){
+ if(CTimer::GetFrameCounter() & 1)
+ CParticle::AddParticle(
+ PARTICLE_WATERSPRAY,
+ colpoint->point + CVector(0.0f, 0.0f, 0.25f+0.25f),
+ CVector(0.0f, 0.0f, CGeneral::GetRandomNumberInRange(0.005f, 0.04f)),
+ nil,
+ CGeneral::GetRandomNumberInRange(0.1f, 0.5f), waterCol);
return 0;
}
-
return 1;
}
}
@@ -3728,6 +4629,7 @@ inline void ProcessDoorOpenCloseAnimation(CAutomobile *car, uint32 component, eD
car->OpenDoor(component, door, 0.0f);
}
}
+
void
CAutomobile::ProcessOpenDoor(uint32 component, uint32 anim, float time)
{
@@ -3748,13 +4650,13 @@ CAutomobile::ProcessOpenDoor(uint32 component, uint32 anim, float time)
case ANIM_STD_QUICKJACK:
case ANIM_STD_CAR_OPEN_DOOR_LHS:
case ANIM_STD_CAR_OPEN_DOOR_RHS:
- ProcessDoorOpenAnimation(this, component, door, time, 0.66f, 0.8f);
+ ProcessDoorOpenAnimation(this, component, door, time, 0.41f, 0.89f);
break;
case ANIM_STD_CAR_CLOSE_DOOR_LHS:
case ANIM_STD_CAR_CLOSE_DOOR_LO_LHS:
case ANIM_STD_CAR_CLOSE_DOOR_RHS:
case ANIM_STD_CAR_CLOSE_DOOR_LO_RHS:
- ProcessDoorCloseAnimation(this, component, door, time, 0.2f, 0.63f);
+ ProcessDoorCloseAnimation(this, component, door, time, 0.2f, 0.45f);
break;
case ANIM_STD_CAR_CLOSE_DOOR_ROLLING_LHS:
case ANIM_STD_CAR_CLOSE_DOOR_ROLLING_LO_LHS:
@@ -3833,6 +4735,41 @@ CAutomobile::IsDoorMissing(eDoors door)
return Damage.GetDoorStatus(door) == DOOR_STATUS_MISSING;
}
+bool
+CAutomobile::IsDoorReady(uint32 door)
+{
+ switch(door){
+ case CAR_DOOR_RF: return IsDoorReady(DOOR_FRONT_RIGHT);
+ case CAR_DOOR_RR: return IsDoorReady(DOOR_REAR_RIGHT);
+ case CAR_DOOR_LF: return IsDoorReady(DOOR_FRONT_LEFT);
+ case CAR_DOOR_LR: return IsDoorReady(DOOR_REAR_LEFT);
+ default:
+ return false;
+ }
+}
+
+bool
+CAutomobile::IsDoorMissing(uint32 door)
+{
+ switch(door){
+ case CAR_DOOR_RF: return IsDoorMissing(DOOR_FRONT_RIGHT);
+ case CAR_DOOR_RR: return IsDoorMissing(DOOR_REAR_RIGHT);
+ case CAR_DOOR_LF: return IsDoorMissing(DOOR_FRONT_LEFT);
+ case CAR_DOOR_LR: return IsDoorMissing(DOOR_REAR_LEFT);
+ default:
+ return false;
+ }
+}
+
+bool
+CAutomobile::IsOpenTopCar(void)
+{
+ return GetModelIndex() == MI_STINGER ||
+ // component 0 is assumed to be a roof
+ GetModelIndex() == MI_COMET && m_aExtras[0] != 0 && m_aExtras[1] != 0 ||
+ GetModelIndex() == MI_STALLION && m_aExtras[0] != 0 && m_aExtras[1] != 0;
+}
+
void
CAutomobile::RemoveRefsToVehicle(CEntity *ent)
{
@@ -3845,12 +4782,17 @@ CAutomobile::RemoveRefsToVehicle(CEntity *ent)
void
CAutomobile::BlowUpCar(CEntity *culprit)
{
- int i;
RpAtomic *atomic;
if(!bCanBeDamaged)
return;
+ if(culprit == FindPlayerPed() || culprit == FindPlayerVehicle()){
+ CWorld::Players[CWorld::PlayerInFocus].m_nHavocLevel += 20;
+ CWorld::Players[CWorld::PlayerInFocus].m_fMediaAttention += 10.0f;
+ CStats::PropertyDestroyed += CGeneral::GetRandomNumber()%6000 + 4000;
+ }
+
// explosion pushes vehicle up
m_vecMoveSpeed.z += 0.13f;
SetStatus(STATUS_WRECKED);
@@ -3880,27 +4822,7 @@ CAutomobile::BlowUpCar(CEntity *culprit)
TheCamera.CamShake(0.7f, GetPosition().x, GetPosition().y, GetPosition().z);
- // kill driver and passengers
- if(pDriver){
- CDarkel::RegisterKillByPlayer(pDriver, WEAPONTYPE_EXPLOSION);
- if(pDriver->GetPedState() == PED_DRIVING){
- pDriver->SetDead();
- if(!pDriver->IsPlayer())
- pDriver->FlagToDestroyWhenNextProcessed();
- }else
- pDriver->SetDie(ANIM_STD_KO_FRONT, 4.0f, 0.0f);
- }
- for(i = 0; i < m_nNumMaxPassengers; i++){
- if(pPassengers[i]){
- CDarkel::RegisterKillByPlayer(pPassengers[i], WEAPONTYPE_EXPLOSION);
- if(pPassengers[i]->GetPedState() == PED_DRIVING){
- pPassengers[i]->SetDead();
- if(!pPassengers[i]->IsPlayer())
- pPassengers[i]->FlagToDestroyWhenNextProcessed();
- }else
- pPassengers[i]->SetDie(ANIM_STD_KO_FRONT, 4.0f, 0.0f);
- }
- }
+ KillPedsInVehicle();
bEngineOn = false;
bLightsOn = false;
@@ -3930,24 +4852,28 @@ CAutomobile::SetUpWheelColModel(CColModel *colModel)
CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex());
CColModel *vehColModel = mi->GetColModel();
+ if(GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI ||
+ GetVehicleAppearance() == VEHICLE_APPEARANCE_PLANE)
+ return false;
+
colModel->boundingSphere = vehColModel->boundingSphere;
colModel->boundingBox = vehColModel->boundingBox;
CMatrix mat;
mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_LF]));
- colModel->spheres[0].Set(mi->m_wheelScale, mat.GetPosition(), SURFACE_RUBBER, CAR_PIECE_WHEEL_LF);
+ colModel->spheres[0].Set(mi->m_wheelScale / 2, 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_RUBBER, CAR_PIECE_WHEEL_LR);
+ colModel->spheres[1].Set(mi->m_wheelScale / 2, 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_RUBBER, CAR_PIECE_WHEEL_RF);
+ colModel->spheres[2].Set(mi->m_wheelScale / 2, 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_RUBBER, CAR_PIECE_WHEEL_RR);
+ colModel->spheres[3].Set(mi->m_wheelScale / 2, 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_RUBBER, CAR_PIECE_WHEEL_LR);
+ colModel->spheres[4].Set(mi->m_wheelScale / 2, 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_RUBBER, CAR_PIECE_WHEEL_RR);
+ colModel->spheres[5].Set(mi->m_wheelScale / 2, mat.GetPosition(), SURFACE_RUBBER, CAR_PIECE_WHEEL_RR);
colModel->numSpheres = 6;
}else
colModel->numSpheres = 4;
@@ -3957,10 +4883,12 @@ CAutomobile::SetUpWheelColModel(CColModel *colModel)
float fBurstForceMult = 0.03f;
-// this isn't used in III yet
void
-CAutomobile::BurstTyre(uint8 wheel)
+CAutomobile::BurstTyre(uint8 wheel, bool applyForces)
{
+ if(GetModelIndex() == MI_RHINO || bTyresDontBurst)
+ return;
+
switch(wheel){
case CAR_PIECE_WHEEL_LF: wheel = CARWHEEL_FRONT_LEFT; break;
case CAR_PIECE_WHEEL_RF: wheel = CARWHEEL_FRONT_RIGHT; break;
@@ -3971,14 +4899,18 @@ CAutomobile::BurstTyre(uint8 wheel)
int status = Damage.GetWheelStatus(wheel);
if(status == WHEEL_STATUS_OK){
Damage.SetWheelStatus(wheel, WHEEL_STATUS_BURST);
+ CStats::TyresPopped++;
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_TYRE_POP, 0.0f);
if(GetStatus() == STATUS_SIMPLE){
SetStatus(STATUS_PHYSICS);
CCarCtrl::SwitchVehicleToRealPhysics(this);
}
- ApplyMoveForce(GetRight() * m_fMass * CGeneral::GetRandomNumberInRange(-fBurstForceMult, fBurstForceMult));
- ApplyTurnForce(GetRight() * m_fTurnMass * CGeneral::GetRandomNumberInRange(-fBurstForceMult, fBurstForceMult), GetForward());
+ if(applyForces){
+ ApplyMoveForce(GetRight() * m_fMass * CGeneral::GetRandomNumberInRange(-fBurstForceMult, fBurstForceMult));
+ ApplyTurnForce(GetRight() * m_fTurnMass * CGeneral::GetRandomNumberInRange(-fBurstForceMult, fBurstForceMult), GetForward());
+ }
}
}
@@ -4055,10 +4987,16 @@ CAutomobile::PlayCarHorn(void)
{
uint32 r;
- if(m_nCarHornTimer != 0)
+ if (IsAlarmOn() || 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){
@@ -4080,7 +5018,6 @@ CAutomobile::PlayHornIfNecessary(void)
PlayCarHorn();
}
-
void
CAutomobile::ResetSuspension(void)
{
@@ -4123,8 +5060,8 @@ CAutomobile::SetupSuspensionLines(void)
}
// Compress spring somewhat to get normal height on road
- m_fHeightAboveRoad = -(colModel->lines[0].p0.z + (colModel->lines[0].p1.z - colModel->lines[0].p0.z)*
- (1.0f - 1.0f/(8.0f*pHandling->fSuspensionForceLevel)));
+ m_fHeightAboveRoad = m_aSuspensionSpringLength[0]*(1.0f - 1.0f/(4.0f*pHandling->fSuspensionForceLevel))
+ - colModel->lines[0].p0.z + mi->m_wheelScale*0.5f;
for(i = 0; i < 4; i++)
m_aWheelPosition[i] = mi->m_wheelScale*0.5f - m_fHeightAboveRoad;
@@ -4158,13 +5095,16 @@ 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() &&
m_aCollisionRecords[i]->GetModelIndex() != MI_RHINO &&
- !m_aCollisionRecords[i]->bRenderScorched)
+ !m_aCollisionRecords[i]->bRenderScorched){
+ if(this == FindPlayerVehicle())
+ CEventList::RegisterEvent(EVENT_EXPLOSION, EVENT_ENTITY_VEHICLE, m_aCollisionRecords[i], FindPlayerPed(), 2000);
((CVehicle*)m_aCollisionRecords[i])->BlowUpCar(this);
+ }
}
bool
@@ -4224,24 +5164,29 @@ CPed::DeadPedMakesTyresBloody(void)
void
CPed::MakeTyresMuddySectorList(CPtrList &list)
{
+ CAutomobile *car = nil;
+ CBike *bike = nil;
for (CPtrNode *node = list.first; node; node = node->next) {
CVehicle *veh = (CVehicle*)node->item;
- if (veh->IsCar() && veh->m_scanCode != CWorld::GetCurrentScanCode()) {
+ if (veh->m_scanCode != CWorld::GetCurrentScanCode()) {
veh->m_scanCode = CWorld::GetCurrentScanCode();
- if (Abs(GetPosition().x - veh->GetPosition().x) < 10.0f) {
-
- if (Abs(GetPosition().y - veh->GetPosition().y) < 10.0f
- && veh->m_vecMoveSpeed.MagnitudeSqr2D() > 0.05f) {
-
- for(int wheel = 0; wheel < 4; wheel++) {
-
- if (!((CAutomobile*)veh)->m_aWheelSkidmarkBloody[wheel]
- && ((CAutomobile*)veh)->m_aSuspensionSpringRatio[wheel] < 1.0f) {
-
- CColModel *vehCol = veh->GetModelInfo()->GetColModel();
- CVector approxWheelOffset;
- switch (wheel) {
+ if (Abs(GetPosition().x - veh->GetPosition().x) < 10.0f && Abs(GetPosition().y - veh->GetPosition().y) < 10.0f) {
+ if (veh->IsCar()) {
+ bike = nil;
+ car = (CAutomobile*)veh;
+ } else if (veh->IsBike()) {
+ bike = (CBike*)veh;
+ car = nil;
+ }
+ if (veh->m_vecMoveSpeed.MagnitudeSqr2D() > 0.05f) {
+ if (car) {
+ for (int wheel = 0; wheel < 4; wheel++) {
+ if (!car->m_aWheelSkidmarkBloody[wheel] && car->m_aSuspensionSpringRatio[wheel] < 1.0f) {
+
+ CColModel* vehCol = car->GetModelInfo()->GetColModel();
+ CVector approxWheelOffset;
+ switch (wheel) {
case 0:
approxWheelOffset = CVector(-vehCol->boundingBox.max.x, vehCol->boundingBox.max.y, 0.0f);
break;
@@ -4256,24 +5201,65 @@ CPed::MakeTyresMuddySectorList(CPtrList &list)
break;
default:
break;
- }
-
- // I hope so
- CVector wheelPos = veh->GetMatrix() * approxWheelOffset;
- if (Abs(wheelPos.z - GetPosition().z) < 2.0f) {
+ }
- if ((wheelPos - GetPosition()).MagnitudeSqr2D() < 1.0f) {
- if (CGame::nastyGame) {
- ((CAutomobile*)veh)->m_aWheelSkidmarkBloody[wheel] = true;
- DMAudio.PlayOneShot(veh->m_audioEntityId, SOUND_SPLATTER, 0.0f);
+ // I hope so
+ CVector wheelPos = car->GetMatrix() * approxWheelOffset;
+ if (Abs(wheelPos.z - GetPosition().z) < 2.0f) {
+
+ if ((wheelPos - GetPosition()).MagnitudeSqr2D() < 1.0f) {
+ if (CGame::nastyGame) {
+ car->m_aWheelSkidmarkBloody[wheel] = true;
+ DMAudio.PlayOneShot(car->m_audioEntityId, SOUND_SPLATTER, 0.0f);
+ }
+ if (car->m_fMass > 500.f) {
+ car->ApplyMoveForce(CVector(0.0f, 0.0f, 50.0f * Min(1.0f, m_fMass * 0.001f)));
+
+ CVector vehAndWheelDist = wheelPos - car->GetPosition();
+ car->ApplyTurnForce(CVector(0.0f, 0.0f, 50.0f * Min(1.0f, m_fTurnMass * 0.0005f)), vehAndWheelDist);
+ if (car == FindPlayerVehicle()) {
+ CPad::GetPad(0)->StartShake(300, 70);
+ }
+ }
}
- veh->ApplyMoveForce(CVector(0.0f, 0.0f, 50.0f));
-
- CVector vehAndWheelDist = wheelPos - veh->GetPosition();
- veh->ApplyTurnForce(CVector(0.0f, 0.0f, 50.0f), vehAndWheelDist);
+ }
+ }
+ }
+ } else if (bike) {
+ for (int wheel = 0; wheel < 2; wheel++) {
+ if (!bike->m_aWheelSkidmarkBloody[wheel] && bike->m_aSuspensionSpringRatio[wheel] < 1.0f) {
- if (veh == FindPlayerVehicle()) {
- CPad::GetPad(0)->StartShake(300, 70);
+ CColModel* vehCol = bike->GetModelInfo()->GetColModel();
+ CVector approxWheelOffset;
+ switch (wheel) {
+ case 0:
+ approxWheelOffset = CVector(0.0f, 0.8f * vehCol->boundingBox.max.y, 0.0f);
+ break;
+ case 1:
+ approxWheelOffset = CVector(0.0f, 0.8f * vehCol->boundingBox.min.y, 0.0f);
+ default:
+ break;
+ }
+
+ // I hope so
+ CVector wheelPos = bike->GetMatrix() * approxWheelOffset;
+ if (Abs(wheelPos.z - GetPosition().z) < 2.0f) {
+
+ if ((wheelPos - GetPosition()).MagnitudeSqr2D() < 1.0f) {
+ if (CGame::nastyGame) {
+ bike->m_aWheelSkidmarkBloody[wheel] = true;
+ DMAudio.PlayOneShot(bike->m_audioEntityId, SOUND_SPLATTER, 0.0f);
+ }
+ if (bike->m_fMass > 100.0f) {
+ bike->ApplyMoveForce(CVector(0.0f, 0.0f, 10.0f));
+
+ CVector vehAndWheelDist = wheelPos - bike->GetPosition();
+ bike->ApplyTurnForce(CVector(0.0f, 0.0f, 10.0f), vehAndWheelDist);
+
+ if (bike == FindPlayerVehicle()) {
+ CPad::GetPad(0)->StartShake(300, 70);
+ }
+ }
}
}
}
@@ -4344,6 +5330,9 @@ CAutomobile::ProcessSwingingDoor(int32 component, eDoors door)
if(Damage.GetDoorStatus(door) != DOOR_STATUS_SWINGING)
return;
+ if (m_aCarNodes[component] == nil)
+ return;
+
CMatrix mat(RwFrameGetMatrix(m_aCarNodes[component]));
CVector pos = mat.GetPosition();
float axes[3] = { 0.0f, 0.0f, 0.0f };
@@ -4353,6 +5342,27 @@ CAutomobile::ProcessSwingingDoor(int32 component, eDoors door)
mat.SetRotate(axes[0], axes[1], axes[2]);
mat.Translate(pos);
mat.UpdateRW();
+
+ // make wind rip off bonnet
+ if(door == DOOR_BONNET && Doors[door].m_nDoorState == DOORST_OPEN &&
+ DotProduct(m_vecMoveSpeed, GetForward()) > 0.4f){
+#ifdef FIX_BUGS
+ CObject *comp = SpawnFlyingComponent(CAR_BONNET, COMPGROUP_BONNET);
+#else
+ CObject *comp = SpawnFlyingComponent(CAR_BONNET, COMPGROUP_DOOR);
+#endif
+ // make both doors invisible on car
+ SetComponentVisibility(m_aCarNodes[CAR_BONNET], ATOMIC_FLAG_NONE);
+ Damage.SetDoorStatus(DOOR_BONNET, DOOR_STATUS_MISSING);
+
+ if(comp){
+ if(CGeneral::GetRandomNumber() & 1)
+ comp->m_vecMoveSpeed = 0.4f*m_vecMoveSpeed + 0.1f*GetRight() + 0.5f*GetUp();
+ else
+ comp->m_vecMoveSpeed = 0.4f*m_vecMoveSpeed - 0.1f*GetRight() + 0.5f*GetUp();
+ comp->ApplyTurnForce(10.0f*GetUp(), GetForward());
+ }
+ }
}
void
@@ -4379,6 +5389,19 @@ CAutomobile::Fix(void)
mat.UpdateRW();
}
}
+
+ for(component = 0; component < 4; component++)
+ Damage.SetWheelStatus(component, WHEEL_STATUS_OK);
+
+ if(GetModelIndex() == MI_HUNTER){
+ RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_LB]), 0);
+ RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_RB]), 0);
+ }else if(IsRealHeli()){
+ RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_LF]), 0);
+ RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_RF]), 0);
+ RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_LB]), 0);
+ RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_RB]), 0);
+ }
}
void
@@ -4420,8 +5443,6 @@ GetCurrentAtomicObjectCB(RwObject *object, void *data)
return object;
}
-static CColPoint aTempPedColPts[MAX_COLLISION_POINTS];
-
CObject*
CAutomobile::SpawnFlyingComponent(int32 component, uint32 type)
{
@@ -4454,6 +5475,7 @@ CAutomobile::SpawnFlyingComponent(int32 component, uint32 type)
case COMPGROUP_DOOR:
obj->SetModelIndexNoCreate(MI_CAR_DOOR);
obj->SetCenterOfMass(0.0f, -0.5f, 0.0f);
+ obj->bDrawLast = true;
break;
case COMPGROUP_BONNET:
obj->SetModelIndexNoCreate(MI_CAR_BONNET);
@@ -4480,6 +5502,7 @@ CAutomobile::SpawnFlyingComponent(int32 component, uint32 type)
RpAtomicSetFrame(atomic, frame);
CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil);
obj->AttachToRwObject((RwObject*)atomic);
+ obj->bDontStream = true;
// init object
obj->m_fMass = 10.0f;
@@ -4538,9 +5561,16 @@ CAutomobile::SpawnFlyingComponent(int32 component, uint32 type)
obj->m_fAirResistance = 0.99f;
}
+ if(GetStatus() == STATUS_WRECKED && IsVisible() && DotProduct(dist, TheCamera.GetPosition() - GetPosition()) > -0.5f){
+ dist = TheCamera.GetPosition() - GetPosition();
+ dist.Normalise();
+ dist.z += 0.3f;
+ ApplyMoveForce(5.0f*dist);
+ }
+
if(CCollision::ProcessColModels(obj->GetMatrix(), *obj->GetColModel(),
this->GetMatrix(), *this->GetColModel(),
- aTempPedColPts, nil, nil) > 0)
+ CWorld::m_aTempColPts, nil, nil) > 0)
obj->m_pCollidingEntity = this;
if(bRenderScorched)
@@ -4578,11 +5608,15 @@ CAutomobile::SetPanelDamage(int32 component, ePanels panel, bool noFlyingCompone
if(m_aCarNodes[component] == nil)
return;
if(status == PANEL_STATUS_SMASHED1){
+ if(panel == VEHPANEL_WINDSCREEN)
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_WINDSHIELD_CRACK, 0.0f);
// show damaged part
SetComponentVisibility(m_aCarNodes[component], ATOMIC_FLAG_DAM);
}else if(status == PANEL_STATUS_MISSING){
if(!noFlyingComponents)
SpawnFlyingComponent(component, COMPGROUP_PANEL);
+ else if(panel == VEHPANEL_WINDSCREEN)
+ CGlass::CarWindscreenShatters(this, false);
// hide both
SetComponentVisibility(m_aCarNodes[component], ATOMIC_FLAG_NONE);
}
@@ -4618,6 +5652,11 @@ CAutomobile::SetDoorDamage(int32 component, eDoors door, bool noFlyingComponents
return;
}
+ if(!CanDoorsBeDamaged() && status > DOOR_STATUS_SMASHED && door != DOOR_BONNET && door != DOOR_BOOT){
+ Damage.SetDoorStatus(door, DOOR_STATUS_SMASHED);
+ status = DOOR_STATUS_SMASHED;
+ }
+
if(door == DOOR_BOOT && status == DOOR_STATUS_SWINGING && pHandling->Flags & HANDLING_NOSWING_BOOT){
Damage.SetDoorStatus(DOOR_BOOT, DOOR_STATUS_MISSING);
status = DOOR_STATUS_MISSING;
@@ -4714,13 +5753,130 @@ 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);
+
+ if(m_fOrientation == 0.0f){
+ m_fOrientation = CGeneral::GetATanOfXY(GetForward().x, GetForward().y) + PI;
+ while(m_fOrientation > TWOPI) m_fOrientation -= TWOPI;
+ }
+}
+
+void
+CAutomobile::TellPlaneToGoToCoors(float x, float y, float z, uint8 speed)
+{
+ AutoPilot.m_nCarMission = MISSION_PLANE_FLYTOCOORS;
+ AutoPilot.m_vecDestinationCoors.x = x;
+ AutoPilot.m_vecDestinationCoors.y = y;
+ AutoPilot.m_vecDestinationCoors.z = z;
+ AutoPilot.m_nCruiseSpeed = speed;
+ SetStatus(STATUS_PHYSICS);
+
+ if(m_fOrientation == 0.0f)
+ m_fOrientation = CGeneral::GetATanOfXY(GetForward().x, GetForward().y);
+}
+
+void
+CAutomobile::PopBoot(void)
+{
+ switch(Damage.GetDoorStatus(DOOR_BOOT)){
+ case DOOR_STATUS_OK:
+ case DOOR_STATUS_SMASHED:
+ Doors[DOOR_BOOT].m_fAngle = Doors[DOOR_BOOT].m_fMinAngle;
+ CMatrix mat(RwFrameGetMatrix(m_aCarNodes[CAR_BOOT]));
+ CVector pos = mat.GetPosition();
+ float axes[3] = { 0.0f, 0.0f, 0.0f };
+ axes[Doors[DOOR_BOOT].m_nAxis] = Doors[DOOR_BOOT].m_fAngle;
+ mat.SetRotate(axes[0], axes[1], axes[2]);
+ mat.Translate(pos);
+ mat.UpdateRW();
+ }
+}
+
+void
+CAutomobile::PopBootUsingPhysics(void)
+{
+ switch(Damage.GetDoorStatus(DOOR_BOOT))
+ case DOOR_STATUS_OK:
+ case DOOR_STATUS_SMASHED:
+ Damage.SetDoorStatus(DOOR_BOOT, DOOR_STATUS_SWINGING);
+ Doors[DOOR_BOOT].m_fAngVel = -2.0f;
+}
+
+void
+CAutomobile::CloseAllDoors(void)
+{
+ CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex());
+ if(!IsDoorMissing(DOOR_FRONT_LEFT))
+ OpenDoor(CAR_DOOR_LF, DOOR_FRONT_LEFT, 0.0f);
+ if(mi->m_numDoors > 1){
+ if(!IsDoorMissing(DOOR_FRONT_RIGHT))
+ OpenDoor(CAR_DOOR_RF, DOOR_FRONT_RIGHT, 0.0f);
+ if(mi->m_numDoors > 2){
+ if(!IsDoorMissing(DOOR_REAR_LEFT))
+ OpenDoor(CAR_DOOR_LR, DOOR_REAR_LEFT, 0.0f);
+ if(!IsDoorMissing(DOOR_REAR_RIGHT))
+ OpenDoor(CAR_DOOR_RR, DOOR_REAR_RIGHT, 0.0f);
+ }
+ }
+}
+
+void
+CAutomobile::KnockPedOutCar(eWeaponType weapon, uint16 door, CPed *ped)
+{
+ AnimationId anim = ANIM_STD_KO_FRONT;
+ if(ped == nil)
+ return;
+
+ ped->m_vehDoor = door;
+ ped->SetPedState(PED_IDLE);
+ CAnimManager::BlendAnimation(ped->GetClump(), ped->m_animGroup, ANIM_STD_IDLE, 100.0f);
+ CPed::PedSetOutCarCB(nil, ped);
+ ped->SetMoveState(PEDMOVE_STILL);
+ if(GetUp().z < 0.0f)
+ ped->SetHeading(CGeneral::LimitRadianAngle(GetForward().Heading() + PI));
+ else
+ ped->SetHeading(GetForward().Heading());
+
+ switch(weapon){
+ case WEAPONTYPE_UNARMED:
+ case WEAPONTYPE_UNIDENTIFIED:
+ ped->m_vecMoveSpeed = m_vecMoveSpeed;
+ ped->m_pCollidingEntity = this;
+ anim = ANIM_STD_NUM;
+ break;
+
+ case WEAPONTYPE_BASEBALLBAT:
+ case WEAPONTYPE_RAMMEDBYCAR:
+ case WEAPONTYPE_FALL:
+ ped->m_vecMoveSpeed = m_vecMoveSpeed;
+ anim = ANIM_STD_SPINFORWARD_LEFT;
+ ApplyMoveForce(4.0f*GetUp() + 8.0f*GetRight());
+ break;
+ }
+
+ if(weapon != WEAPONTYPE_UNARMED){
+ ped->SetFall(1000, anim, 0);
+ ped->bIsStanding = false;
+ ped->m_headingRate = 0.0f;
+ }
+ ped->m_pMyVehicle = nil;
+}
+
#ifdef COMPATIBLE_SAVES
void
CAutomobile::Save(uint8*& buf)
{
CVehicle::Save(buf);
WriteSaveBuf(buf, Damage);
- ZeroSaveBuf(buf, 800 - sizeof(CDamageManager));
+ ZeroSaveBuf(buf, 1500 - 672 - sizeof(CDamageManager));
}
void
@@ -4728,7 +5884,7 @@ CAutomobile::Load(uint8*& buf)
{
CVehicle::Load(buf);
ReadSaveBuf(&Damage, buf);
- SkipSaveBuf(buf, 800 - sizeof(CDamageManager));
+ SkipSaveBuf(buf, 1500 - 672 - sizeof(CDamageManager));
SetupDamageAfterLoad();
}
#endif
diff --git a/src/vehicles/Automobile.h b/src/vehicles/Automobile.h
index a5bee226..16d86917 100644
--- a/src/vehicles/Automobile.h
+++ b/src/vehicles/Automobile.h
@@ -3,33 +3,10 @@
#include "Vehicle.h"
#include "DamageManager.h"
#include "Door.h"
+#include "Skidmarks.h"
class CObject;
-enum eCarNodes
-{
- CAR_WHEEL_RF = 1,
- CAR_WHEEL_RM,
- CAR_WHEEL_RB,
- CAR_WHEEL_LF,
- CAR_WHEEL_LM,
- CAR_WHEEL_LB,
- CAR_BUMP_FRONT,
- CAR_BUMP_REAR,
- CAR_WING_RF,
- CAR_WING_RR,
- CAR_DOOR_RF,
- CAR_DOOR_RR,
- CAR_WING_LF,
- CAR_WING_LR,
- CAR_DOOR_LF,
- CAR_DOOR_LR,
- CAR_BONNET,
- CAR_BOOT,
- CAR_WINDSCREEN,
- NUM_CAR_NODES,
-};
-
enum {
CARWHEEL_FRONT_LEFT,
CARWHEEL_REAR_LEFT,
@@ -37,28 +14,10 @@ enum {
CARWHEEL_REAR_RIGHT
};
-enum eBombType
-{
- CARBOMB_NONE,
- CARBOMB_TIMED,
- CARBOMB_ONIGNITION,
- CARBOMB_REMOTE,
- CARBOMB_TIMEDACTIVE,
- CARBOMB_ONIGNITIONACTIVE,
-};
-
-enum {
- CAR_DOOR_FLAG_UNKNOWN = 0x0,
- CAR_DOOR_FLAG_LF = 0x1,
- CAR_DOOR_FLAG_LR = 0x2,
- CAR_DOOR_FLAG_RF = 0x4,
- CAR_DOOR_FLAG_RR = 0x8
-};
class CAutomobile : public CVehicle
{
public:
- // 0x288
CDamageManager Damage;
CDoor Doors[6];
RwFrame *m_aCarNodes[NUM_CAR_NODES];
@@ -67,22 +26,29 @@ public:
float m_aSuspensionSpringRatioPrev[4];
float m_aWheelTimer[4]; // set to 4.0 when wheel is touching ground, then decremented
float m_auto_unused1;
- bool m_aWheelSkidmarkMuddy[4];
+ eSkidmarkType m_aWheelSkidmarkType[4];
bool m_aWheelSkidmarkBloody[4];
+ bool m_aWheelSkidmarkUnk[4];
float m_aWheelRotation[4];
float m_aWheelPosition[4];
float m_aWheelSpeed[4];
uint8 m_auto_unused2;
+#if (defined GTA_PS2 && !defined FIX_BUGS)
uint8 m_bombType : 3;
+#endif
uint8 bTaxiLight : 1;
- uint8 bDriverLastFrame : 1; // for bombs
uint8 bFixedColour : 1;
uint8 bBigWheels : 1;
uint8 bWaterTight : 1; // no damage for non-player peds
uint8 bNotDamagedUpsideDown : 1;
uint8 bMoreResistantToDamage : 1;
- CEntity *m_pBombRigger;
- int16 m_auto_unk1;
+ uint8 bTankDetonateCars : 1;
+ uint8 bStuckInSand : 1;
+ uint8 bHeliDestroyed : 1;
+#if (defined GTA_PS2 && !defined FIX_BUGS)
+ CEntity* m_pBombRigger;
+#endif
+ int16 m_doingBurnout;
uint16 m_hydraulicState;
uint32 m_nBusDoorTimerEnd;
uint32 m_nBusDoorTimerStart;
@@ -90,6 +56,9 @@ public:
float m_aSuspensionLineLength[4];
float m_fHeightAboveRoad;
float m_fTraction;
+ float m_fTireTemperature;
+ float m_fOrientation; // for heli and plane go-to
+ float m_fPlaneSteer; // related to the above
float m_fVelocityChangeForAudio;
float m_randomValues[6]; // used for what?
float m_fFireBlowUpTimer;
@@ -100,6 +69,7 @@ public:
float m_weaponDoorTimerRight;
float m_fCarGunLR;
float m_fCarGunUD;
+ float m_fHeliOrientation;
float m_fPropellerRotation;
uint8 stuff4[4];
uint8 m_nWheelsOnGround;
@@ -133,10 +103,13 @@ public:
bool IsDoorFullyOpen(eDoors door);
bool IsDoorClosed(eDoors door);
bool IsDoorMissing(eDoors door);
+ bool IsDoorReady(uint32 door);
+ bool IsDoorMissing(uint32 door);
+ bool IsOpenTopCar(void);
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);
@@ -147,6 +120,7 @@ public:
void VehicleDamage(float impulse, uint16 damagedPiece);
void ProcessBuoyancy(void);
void DoDriveByShootings(void);
+ void DoHoverSuspensionRatios(void);
int32 RcbanditCheckHitWheels(void);
int32 RcbanditCheck1CarWheels(CPtrList &list);
void PlaceOnRoadProperly(void);
@@ -169,6 +143,11 @@ 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 TellPlaneToGoToCoors(float x, float y, float z, uint8 speed);
+ void SetHeliOrientation(float orient) { m_fHeliOrientation = orient; }
+ void ClearHeliOrientation(void) { m_fHeliOrientation = -1.0f; }
+
void Fix(void);
void SetComponentVisibility(RwFrame *frame, uint32 flags);
void SetupModelNodes(void);
@@ -177,6 +156,12 @@ public:
void HideAllComps(void);
void ShowAllComps(void);
void ReduceHornCounter(void);
+
+ void PopBoot(void);
+ void PopBootUsingPhysics(void);
+ void CloseAllDoors(void);
+ void KnockPedOutCar(eWeaponType weapon, uint16 door, CPed *ped);
+
#ifdef COMPATIBLE_SAVES
virtual void Save(uint8*& buf);
virtual void Load(uint8*& buf);
@@ -186,19 +171,5 @@ public:
static void SetAllTaxiLights(bool set);
};
-VALIDATE_SIZE(CAutomobile, 0x5A8);
-
-inline uint8 GetCarDoorFlag(int32 carnode) {
- switch (carnode) {
- case CAR_DOOR_LF:
- return CAR_DOOR_FLAG_LF;
- case CAR_DOOR_LR:
- return CAR_DOOR_FLAG_LR;
- case CAR_DOOR_RF:
- return CAR_DOOR_FLAG_RF;
- case CAR_DOOR_RR:
- return CAR_DOOR_FLAG_RR;
- default:
- return CAR_DOOR_FLAG_UNKNOWN;
- }
-}
+extern CVector vecHunterGunPos;
+extern bool bAllCarCheat; \ No newline at end of file
diff --git a/src/vehicles/Bike.cpp b/src/vehicles/Bike.cpp
new file mode 100644
index 00000000..a65b64d2
--- /dev/null
+++ b/src/vehicles/Bike.cpp
@@ -0,0 +1,2962 @@
+#include "common.h"
+#include "General.h"
+#include "Pad.h"
+#include "DMAudio.h"
+#include "Clock.h"
+#include "Timecycle.h"
+#include "ZoneCull.h"
+#include "Camera.h"
+#include "Darkel.h"
+#include "Rubbish.h"
+#include "Explosion.h"
+#include "Particle.h"
+#include "ParticleObject.h"
+#include "Shadows.h"
+#include "PointLights.h"
+#include "Coronas.h"
+#include "SpecialFX.h"
+#include "WaterLevel.h"
+#include "Floater.h"
+#include "World.h"
+#include "SurfaceTable.h"
+#include "Weather.h"
+#include "Record.h"
+#include "CarCtrl.h"
+#include "CarAI.h"
+#include "Script.h"
+#include "Stats.h"
+#include "Replay.h"
+#include "AnimManager.h"
+#include "RpAnimBlend.h"
+#include "AnimBlendAssociation.h"
+#include "Ped.h"
+#include "PlayerPed.h"
+#include "DamageManager.h"
+#include "Vehicle.h"
+#include "Automobile.h"
+#include "Bike.h"
+#include "Debug.h"
+#include "SaveBuf.h"
+
+const uint32 CBike::nSaveStructSize =
+#ifdef COMPATIBLE_SAVES
+ 1260;
+#else
+ sizeof(CBoat);
+#endif
+
+
+// TODO: maybe put this somewhere else
+inline void
+GetRelativeMatrix(RwMatrix *mat, RwFrame *frm, RwFrame *end)
+{
+ *mat = *RwFrameGetMatrix(frm);
+ frm = RwFrameGetParent(frm);
+ while(frm){
+ RwMatrixTransform(mat, RwFrameGetMatrix(frm), rwCOMBINEPOSTCONCAT);
+ frm = RwFrameGetParent(frm);
+ if(frm == end)
+ frm = nil;
+ }
+}
+
+#define FAKESUSPENSION (99999.992f)
+
+CBike::CBike(int32 id, uint8 CreatedBy)
+ : CVehicle(CreatedBy)
+{
+ int i;
+ CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(id);
+ switch(id){
+ case MI_ANGEL:
+ case MI_FREEWAY:
+ m_bikeAnimType = ASSOCGRP_BIKE_HARLEY;
+ break;
+ case MI_PIZZABOY:
+ case MI_FAGGIO:
+ m_bikeAnimType = ASSOCGRP_BIKE_VESPA;
+ break;
+ case MI_PCJ600:
+ m_bikeAnimType = ASSOCGRP_BIKE_STANDARD;
+ break;
+ case MI_SANCHEZ:
+ m_bikeAnimType = ASSOCGRP_BIKE_DIRT;
+ break;
+ default: assert(0 && "invalid bike model ID");
+ }
+ m_vehType = VEHICLE_TYPE_BIKE;
+
+ m_fFireBlowUpTimer = 0.0f;
+ m_doingBurnout = 0;
+ m_bike_flag01 = false;
+
+ SetModelIndex(id);
+
+ pHandling = mod_HandlingManager.GetHandlingData((tVehicleType)mi->m_handlingId);
+ pBikeHandling = mod_HandlingManager.GetBikePointer((tVehicleType)mi->m_handlingId);
+ pFlyingHandling = mod_HandlingManager.GetFlyingPointer((tVehicleType)mi->m_handlingId);
+
+ m_bike_unused1 = 20.0f;
+ m_bike_unused2 = 0;
+
+ mi->ChooseVehicleColour(m_currentColour1, m_currentColour2);
+
+ m_fRearForkLength = 0.0f;
+ m_fFrontForkY = 0.0;
+ m_fFrontForkZ = 0.0;
+ m_fFrontForkSlope = Tan(DEGTORAD(mi->m_bikeSteerAngle));
+
+ m_fMass = pHandling->fMass;
+ m_fTurnMass = pHandling->fTurnMass;
+ m_vecCentreOfMass = pHandling->CentreOfMass;
+ m_vecCentreOfMass.z = 0.1f;
+ m_fAirResistance = pHandling->Dimension.x*pHandling->Dimension.z/m_fMass;
+ m_fElasticity = 0.05f;
+ m_fBuoyancy = pHandling->fBuoyancy;
+
+ m_fSteerAngle = 0.0f;
+ m_fWheelAngle = 0.0f;
+ m_fLeanLRAngle = 0.0f;
+ m_fLeanLRAngle2 = 0.0f;
+ m_fGasPedal = 0.0f;
+ m_fBrakePedal = 0.0f;
+ m_fLeanInput = 0.0f;
+ m_fPedLeanAmountLR = 0.0f;
+ m_fPedLeanAmountUD = 0.0f;
+ m_pSetOnFireEntity = nil;
+ m_pBombRigger = nil;
+ m_fGasPedalAudio = 0.0f;
+ m_bike_flag02 = false;
+ bWaterTight = false;
+ bIsBeingPickedUp = false;
+ bIsStanding = false;
+ bExtraSpeed = false;
+ bIsOnFire = false;
+ bWheelieCam = false;
+
+ m_fTireTemperature = 1.0f;
+ m_fBrakeDestabilization = 0.0f;
+ m_fVelocityChangeForAudio = 0;
+
+ for(i = 0; i < 2; i++){
+ m_aWheelRotation[i] = 0.0f;
+ m_aWheelSpeed[i] = 0.0f;
+ m_aWheelState[i] = WHEEL_STATE_NORMAL;
+ m_aWheelSkidmarkType[i] = SKIDMARK_NORMAL;
+ m_aWheelSkidmarkBloody[i] = false;
+ m_aWheelSkidmarkUnk[0] = false;
+ m_wheelStatus[i] = WHEEL_STATUS_OK;
+ }
+
+ for(i = 0; i < 4; i++){
+ m_aGroundPhysical[i] = nil;
+ m_aGroundOffset[i] = CVector(0.0f, 0.0f, 0.0f);
+ m_aSuspensionSpringRatioPrev[i] = m_aSuspensionSpringRatio[i] = 1.0f;
+ m_aWheelTimer[i] = 0.0f;
+ }
+
+ m_nWheelsOnGround = 0;
+ m_nDriveWheelsOnGround = 0;
+ m_nDriveWheelsOnGroundPrev = 0;
+ m_fHeightAboveRoad = 0.0f;
+ m_fTraction = 1.0f;
+
+ CColModel *colModel = mi->GetColModel();
+ if(colModel->lines == nil){
+ colModel->lines = (CColLine*)RwMalloc(4*sizeof(CColLine));
+ colModel->numLines = 4;
+ }
+ // BUG? this would make more sense in the if above
+ colModel->lines[0].p0.z = FAKESUSPENSION;
+
+ SetupSuspensionLines();
+
+ AutoPilot.m_nCarMission = MISSION_NONE;
+ AutoPilot.m_nTempAction = TEMPACT_NONE;
+ AutoPilot.m_nTimeToStartMission = CTimer::GetTimeInMilliseconds();
+ AutoPilot.m_bStayInCurrentLevel = false;
+
+ SetStatus(STATUS_SIMPLE);
+ bUseCollisionRecords = true;
+ m_nNumPassengers = 0;
+ bIsVan = false;
+ bIsBus = false;
+ bIsBig = false;
+ bLowVehicle = false;
+ bPedPhysics = false;
+
+ bLeanMatrixClean = false;
+ m_leanMatrix = GetMatrix();
+}
+
+void
+CBike::SetModelIndex(uint32 id)
+{
+ CVehicle::SetModelIndex(id);
+ SetupModelNodes();
+}
+
+#define SAND_SLOWDOWN (0.02f)
+CVector vecTestResistance(0.9995f, 0.9f, 0.95f);
+float fDAxisX = 1.0f;
+float fDAxisXExtra = 100.0f;
+float fDAxisY = 1000.0f;
+float fInAirXRes = 0.98f;
+float fFlySpeedMult = -0.6f;
+
+#pragma optimize("", off) // a workaround for another compiler bug =P, original had optimize off for this function too though
+
+void
+CBike::ProcessControl(void)
+{
+ int i;
+ float wheelRot;
+ float acceleration = 0.0f;
+ bool bBalancedByRider = false;
+ bool bStuckInSand = false;
+ float brake = 0.0f;
+ CColModel *colModel = GetColModel();
+ float wheelScale = ((CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex()))->m_wheelScale;
+ bWarnedPeds = false;
+ bLeanMatrixClean = false;
+ m_doingBurnout = 0;
+ bExtraSpeed = false;
+ bRestingOnPhysical = false;
+
+ if(CReplay::IsPlayingBack())
+ return;
+
+ ProcessCarAlarm();
+
+ ActivateBombWhenEntered();
+
+ CRubbish::StirUp(this);
+
+ UpdateClumpAlpha();
+
+ AutoPilot.m_bSlowedDownBecauseOfCars = false;
+ AutoPilot.m_bSlowedDownBecauseOfPeds = false;
+
+ switch(GetStatus()){
+ case STATUS_PLAYER:
+ bBalancedByRider = true;
+ bIsBeingPickedUp = false;
+ if(FindPlayerPed()->GetPedState() != PED_EXIT_CAR && FindPlayerPed()->GetPedState() != PED_DRAG_FROM_CAR){
+ ProcessControlInputs(0);
+
+ if(m_fLeanInput < 0.0f){
+ m_vecCentreOfMass.y = pHandling->CentreOfMass.y + pBikeHandling->fLeanBakCOM*m_fLeanInput;
+ CVector com = m_vecCentreOfMass;
+#ifdef FIX_BUGS
+ // center of mass has to have world space orientation. unfortunately we can't do wheelies
+ // at high speed then, flipping y here is like riding south without this fix where wheelies work
+ com.y = -com.y;
+ com = Multiply3x3(GetMatrix(), com);
+#endif
+ if(m_fBrakePedal == 0.0f && !bIsHandbrakeOn || m_nWheelsOnGround == 0){
+ if(GetModelIndex() == MI_SANCHEZ){
+ float force = m_fLeanInput*m_fTurnMass*pBikeHandling->fLeanBackForce*Min(m_vecMoveSpeed.Magnitude(), 0.1f);
+ force *= 0.7f*m_fGasPedal + 0.3f;
+ ApplyTurnForce(-force*CTimer::GetTimeStep()*GetUp(), com+GetForward());
+ }else{
+ float force = m_fLeanInput*m_fTurnMass*pBikeHandling->fLeanBackForce*Min(m_vecMoveSpeed.Magnitude(), 0.1f);
+ force *= 0.5f*m_fGasPedal + 0.5f;
+ ApplyTurnForce(-force*CTimer::GetTimeStep()*GetUp(), com+GetForward());
+ }
+ }
+ }else{
+ m_vecCentreOfMass.y = pHandling->CentreOfMass.y + pBikeHandling->fLeanFwdCOM*m_fLeanInput;
+ CVector com = m_vecCentreOfMass;
+#ifdef FIX_BUGS
+ // see above
+ com.y = -com.y;
+ com = Multiply3x3(GetMatrix(), com);
+#endif
+ if(m_fBrakePedal < 0.0f || m_nWheelsOnGround == 0){
+ float force = m_fLeanInput*m_fTurnMass*pBikeHandling->fLeanFwdForce*Min(m_vecMoveSpeed.Magnitude(), 0.1f);
+ ApplyTurnForce(-force*CTimer::GetTimeStep()*GetUp(), com+GetForward());
+ }
+ }
+
+ PruneReferences();
+
+ if(GetStatus() == STATUS_PLAYER && !CRecordDataForChase::IsRecording())
+ DoDriveByShootings();
+
+ if(m_aSuspensionSpringRatio[0] < 1.0f && CSurfaceTable::GetAdhesionGroup(m_aWheelColPoints[0].surfaceB) == ADHESIVE_SAND ||
+ m_aSuspensionSpringRatio[1] < 1.0f && CSurfaceTable::GetAdhesionGroup(m_aWheelColPoints[1].surfaceB) == ADHESIVE_SAND ||
+ m_aSuspensionSpringRatio[2] < 1.0f && CSurfaceTable::GetAdhesionGroup(m_aWheelColPoints[2].surfaceB) == ADHESIVE_SAND ||
+ m_aSuspensionSpringRatio[3] < 1.0f && CSurfaceTable::GetAdhesionGroup(m_aWheelColPoints[3].surfaceB) == ADHESIVE_SAND){
+ CVector parallelSpeed = m_vecMoveSpeed - DotProduct(m_vecMoveSpeed, GetUp())*GetUp();
+ if(m_fGasPedal > 0.3f){
+ if(parallelSpeed.MagnitudeSqr() < SQR(0.3f))
+ bStuckInSand = true;
+ parallelSpeed -= DotProduct(parallelSpeed, GetForward())*GetForward();
+ }
+ ApplyMoveForce(parallelSpeed * -CTimer::GetTimeStep()*SAND_SLOWDOWN*m_fMass);
+ }
+ }
+ if(CPad::GetPad(0)->WeaponJustDown())
+ ActivateBomb();
+ break;
+
+ case STATUS_PLAYER_PLAYBACKFROMBUFFER:
+ bBalancedByRider = true;
+ break;
+
+ case STATUS_SIMPLE:
+ CCarAI::UpdateCarAI(this);
+ CPhysical::ProcessControl();
+ CCarCtrl::UpdateCarOnRails(this);
+
+ m_nWheelsOnGround = 2;
+ m_nDriveWheelsOnGroundPrev = m_nDriveWheelsOnGround;
+ m_nDriveWheelsOnGround = 2;
+
+ pHandling->Transmission.CalculateGearForSimpleCar(AutoPilot.m_fMaxTrafficSpeed/50.0f, m_nCurrentGear);
+
+ wheelRot = ProcessWheelRotation(WHEEL_STATE_NORMAL, GetForward(), m_vecMoveSpeed, 0.5f*wheelScale);
+ for(i = 0; i < 2; i++)
+ m_aWheelRotation[i] += wheelRot;
+
+ PlayHornIfNecessary();
+ ReduceHornCounter();
+ bVehicleColProcessed = false;
+ bAudioChangingGear = false;
+ bWheelieCam = false;
+ // that's all we do for simple vehicles
+ return;
+
+ case STATUS_PHYSICS:
+ CCarAI::UpdateCarAI(this);
+ CCarCtrl::SteerAICarWithPhysics(this);
+ PlayHornIfNecessary();
+
+ bBalancedByRider = true;
+ bWheelieCam = false;
+
+ if(bIsBeingCarJacked){
+ m_fGasPedal = 0.0f;
+ m_fBrakePedal = 1.0f;
+ bIsHandbrakeOn = true;
+ }else
+ bIsBeingPickedUp = false;
+ break;
+
+ case STATUS_ABANDONED:
+ m_fBrakePedal = 0.0f;
+ if(m_vecMoveSpeed.MagnitudeSqr() < SQR(0.1f) || bIsStanding)
+ bIsHandbrakeOn = true;
+ else
+ bIsHandbrakeOn = false;
+
+ m_fGasPedal = 0.0f;
+#ifdef FIX_BUGS
+ if(!IsAlarmOn())
+#endif
+ m_nCarHornTimer = 0;
+
+ bBalancedByRider = (pDriver || pPassengers[0] || bIsBeingCarJacked) && !bIsStanding;
+ m_fPedLeanAmountLR = 0.0f;
+ m_fPedLeanAmountUD = 0.0f;
+ bWheelieCam = false;
+
+ if(bIsBeingCarJacked){
+ m_fGasPedal = 0.0f;
+ m_fBrakePedal = 1.0f;
+ bIsHandbrakeOn = true;
+ }
+ break;
+
+ case STATUS_WRECKED:
+ m_fBrakePedal = 0.05f;
+ bIsHandbrakeOn = true;
+
+ m_fSteerAngle = 0.0f;
+ m_fGasPedal = 0.0f;
+#ifdef FIX_BUGS
+ if(!IsAlarmOn())
+#endif
+ m_nCarHornTimer = 0;
+
+ bBalancedByRider = false;
+ bWheelieCam = false;
+ m_fPedLeanAmountLR = 0.0f;
+ m_fPedLeanAmountUD = 0.0f;
+ break;
+
+ case STATUS_PLAYER_DISABLED:
+ if(m_vecMoveSpeed.MagnitudeSqr() < SQR(0.1f)){
+ m_fBrakePedal = 1.0f;
+ bIsHandbrakeOn = true;
+ }else{
+ m_fBrakePedal = 0.0f;
+ bIsHandbrakeOn = false;
+ }
+
+ m_fSteerAngle = 0.0f;
+ m_fGasPedal = 0.0f;
+#ifdef FIX_BUGS
+ if(!IsAlarmOn())
+#endif
+ m_nCarHornTimer = 0;
+
+ bBalancedByRider = true;
+ bWheelieCam = false;
+ break;
+ }
+
+ if(bIsStanding)
+ if(Abs(GetRight().z) > 0.35f || Abs(GetForward().z) > 0.5f)
+ bIsStanding = false;
+
+ if(bBalancedByRider || bIsBeingPickedUp || bIsStanding){
+ float fDx = fDAxisX;
+ CVector res = vecTestResistance;
+ CVector localTurnSpeed = Multiply3x3(m_vecTurnSpeed, GetMatrix());
+
+ if(GetStatus() == STATUS_PLAYER){
+ if(m_aWheelTimer[BIKESUSP_F1] == 0.0f && m_aWheelTimer[BIKESUSP_F2] == 0.0f){
+ fDx = fDAxisXExtra;
+ if(!(m_aWheelTimer[BIKESUSP_R1] == 0.0f && m_aWheelTimer[BIKESUSP_R2] == 0.0f) &&
+ GetForward().z > 0.0f)
+ res.x -= Min(0.25f*Abs(pBikeHandling->fWheelieAng-GetForward().z), 0.07f);
+ else
+ res.x = fInAirXRes;
+ }else if(m_aWheelTimer[BIKESUSP_R1] == 0.0f && m_aWheelTimer[BIKESUSP_R2] == 0.0f){
+ fDx = fDAxisXExtra;
+ if(GetForward().z < 0.0f)
+ res.x *= Min(0.3f*Abs(pBikeHandling->fStoppieAng-GetForward().z), 0.1f) + 0.9f;
+ }
+ }
+
+ res.x *= 1.0f/(fDx*SQR(localTurnSpeed.x) + 1.0f);
+ res.y *= 1.0f/(fDAxisY*SQR(localTurnSpeed.y) + 1.0f);
+ res.x = Pow(res.x, CTimer::GetTimeStep());
+ res.y = Pow(res.y, CTimer::GetTimeStep());
+ float turnX = localTurnSpeed.x*(res.x - 1.0f);
+ float turnY = localTurnSpeed.y*(res.y - 1.0f);
+
+ res = -GetUp() * turnY * m_fTurnMass;
+ ApplyTurnForce(res, GetRight() + Multiply3x3(GetMatrix(), m_vecCentreOfMass));
+
+ res = GetUp() * turnX * m_fTurnMass;
+ ApplyTurnForce(res, GetForward() + Multiply3x3(GetMatrix(), m_vecCentreOfMass));
+
+ if(GetStatus() != STATUS_PLAYER)
+ m_vecCentreOfMass = pHandling->CentreOfMass;
+ }else{
+ m_vecCentreOfMass = pHandling->CentreOfMass;
+ m_vecCentreOfMass.z = pBikeHandling->fNoPlayerCOMz;
+ }
+
+ // Skip physics if object is found to have been static recently
+ bool skipPhysics = false;
+ if(!bIsStuck && (GetStatus() == STATUS_ABANDONED || GetStatus() == STATUS_WRECKED) && !bIsBeingPickedUp){
+ bool makeStatic = false;
+ float moveSpeedLimit, turnSpeedLimit, distanceLimit;
+
+ if(!bVehicleColProcessed &&
+ m_vecMoveSpeed.IsZero() &&
+ // BUG? m_aSuspensionSpringRatioPrev[3] is checked twice in the game. also, why 3?
+ m_aSuspensionSpringRatioPrev[3] != 1.0f)
+ makeStatic = true;
+
+ if(GetStatus() == STATUS_WRECKED){
+ moveSpeedLimit = 0.006f;
+ turnSpeedLimit = 0.0015f;
+ distanceLimit = 0.015f;
+ }else{
+ moveSpeedLimit = 0.003f;
+ turnSpeedLimit = 0.0009f;
+ distanceLimit = 0.005f;
+ }
+
+ m_vecMoveSpeedAvg = (m_vecMoveSpeedAvg + m_vecMoveSpeed)/2.0f;
+ m_vecTurnSpeedAvg = (m_vecTurnSpeedAvg + m_vecTurnSpeed)/2.0f;
+
+ if(m_vecMoveSpeedAvg.MagnitudeSqr() <= sq(moveSpeedLimit*CTimer::GetTimeStep()) &&
+ m_vecTurnSpeedAvg.MagnitudeSqr() <= sq(turnSpeedLimit*CTimer::GetTimeStep()) &&
+ m_fDistanceTravelled < distanceLimit ||
+ makeStatic){
+ m_nStaticFrames++;
+
+ if(m_nStaticFrames > 10 || makeStatic)
+ if(!CCarCtrl::MapCouldMoveInThisArea(GetPosition().x, GetPosition().y)){
+ if(!makeStatic || m_nStaticFrames > 10)
+ m_nStaticFrames = 10;
+
+ skipPhysics = true;
+
+ m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
+ m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f);
+ }
+ }else
+ m_nStaticFrames = 0;
+ }
+
+ // Postpone
+ for(i = 0; i < 4; i++)
+ if(m_aGroundPhysical[i]){
+ bRestingOnPhysical = true;
+ if(!CWorld::bForceProcessControl && m_aGroundPhysical[i]->bIsInSafePosition){
+ bWasPostponed = true;
+ return;
+ }
+ }
+
+ if(bRestingOnPhysical){
+ skipPhysics = false;
+ m_nStaticFrames = 0;
+ }
+
+ VehicleDamage();
+
+ if(skipPhysics){
+ bHasContacted = false;
+ bIsInSafePosition = false;
+ bWasPostponed = false;
+ bHasHitWall = false;
+ m_nCollisionRecords = 0;
+ bHasCollided = false;
+ bVehicleColProcessed = false;
+ bAudioChangingGear = false;
+ m_nDamagePieceType = 0;
+ m_fDamageImpulse = 0.0f;
+ m_pDamageEntity = nil;
+ m_vecTurnFriction = CVector(0.0f, 0.0f, 0.0f);
+ m_vecMoveFriction = CVector(0.0f, 0.0f, 0.0f);
+// missing. BUG?
+// m_fTireTemperature = 1.0f;
+
+ if(bIsStanding && m_fWheelAngle < DEGTORAD(20.0f))
+ m_fWheelAngle += DEGTORAD(1.0f)*CTimer::GetTimeStep();
+ if(bIsStanding){
+ float f = Pow(0.97f, CTimer::GetTimeStep());
+ m_fLeanLRAngle2 = m_fLeanLRAngle2*f - (Asin(Clamp(GetRight().z,-1.0f,1.0f))+DEGTORAD(15.0f))*(1.0f-f);
+ m_fLeanLRAngle = m_fLeanLRAngle2;
+ }
+ }else{
+
+ // This has to be done if ProcessEntityCollision wasn't called
+ if(!bVehicleColProcessed){
+ CMatrix mat(GetMatrix());
+ bIsStuck = false;
+ bHasContacted = false;
+ bIsInSafePosition = false;
+ bWasPostponed = false;
+ bHasHitWall = false;
+ m_fDistanceTravelled = 0.0f;
+ m_bIsVehicleBeingShifted = false;
+ bSkipLineCol = false;
+ ApplyMoveSpeed();
+ ApplyTurnSpeed();
+ for(i = 0; CheckCollision() && i < 5; i++){
+ GetMatrix() = mat;
+ ApplyMoveSpeed();
+ ApplyTurnSpeed();
+ }
+ bIsInSafePosition = true;
+ bIsStuck = false;
+ }
+
+ if(!(bBalancedByRider || bIsBeingPickedUp || bIsStanding)){
+ if(GetRight().z < 0.0f){
+ if(m_fSteerAngle > -DEGTORAD(25.0f))
+ m_fSteerAngle -= DEGTORAD(0.5f)*CTimer::GetTimeStep();
+ }else{
+ if(m_fSteerAngle < DEGTORAD(25.0f))
+ m_fSteerAngle += DEGTORAD(0.5f)*CTimer::GetTimeStep();
+ }
+ }
+
+ // Lean forward speed up
+ float savedAirResistance = m_fAirResistance;
+ if(GetStatus() == STATUS_PLAYER && pDriver){
+ CAnimBlendAssociation *assoc = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_BIKE_LEANF);
+ if(assoc && assoc->blendAmount > 0.5f &&
+ assoc->currentTime > 0.06f && assoc->currentTime < 0.14f){
+ m_fAirResistance *= 0.6f;
+ if(m_fGasPedal > 0.5f && DotProduct(m_vecMoveSpeed, GetForward()) > 0.25f){
+ ApplyMoveForce(0.2f*m_fMass*GRAVITY*CTimer::GetTimeStep()*GetForward());
+ bExtraSpeed = true;
+ }
+ }
+ }
+
+ CPhysical::ProcessControl();
+ m_fAirResistance = savedAirResistance;
+
+ ProcessBuoyancy();
+
+ // Rescale spring ratios, i.e. subtract wheel radius
+ for(i = 0; i < 4; i++){
+ // wheel radius in relation to suspension line
+ float wheelRadius = 1.0f - m_aSuspensionSpringLength[i]/m_aSuspensionLineLength[i];
+ // rescale such that 0.0 is fully compressed and 1.0 is fully extended
+ m_aSuspensionSpringRatio[i] = (m_aSuspensionSpringRatio[i]-wheelRadius)/(1.0f-wheelRadius);
+ }
+
+ int rnd = 0;
+ float fwdSpeed = Abs(DotProduct(m_vecMoveSpeed, GetForward()));
+ CVector contactPoints[4]; // relative to model
+ CVector contactSpeeds[4]; // speed at contact points
+ CVector springDirections[4]; // normalized, in model space
+
+ for(i = 0; i < 4; i++){
+ // Set spring under certain circumstances
+ if(m_wheelStatus[i/2] == WHEEL_STATUS_MISSING)
+ m_aSuspensionSpringRatio[i] = 1.0f;
+ else if(m_wheelStatus[i/2] == WHEEL_STATUS_BURST){
+ // wheel more bumpy the faster we are
+ if(i == BIKESUSP_F1 || i == BIKESUSP_R1)
+ rnd = CGeneral::GetRandomNumberInRange(0, (uint16)(40*fwdSpeed) + 98) < 100;
+ if(rnd){
+ m_aSuspensionSpringRatio[i] += 0.3f*(m_aSuspensionLineLength[i]-m_aSuspensionSpringLength[i])/m_aSuspensionSpringLength[i];
+ if(m_aSuspensionSpringRatio[i] > 1.0f)
+ m_aSuspensionSpringRatio[i] = 1.0f;
+ }
+ }
+
+ // get points and directions if spring is compressed
+ if(m_aSuspensionSpringRatio[i] < 1.0f){
+ contactPoints[i] = m_aWheelColPoints[i].point - GetPosition();
+ springDirections[i] = Multiply3x3(GetMatrix(), colModel->lines[i].p1 - colModel->lines[i].p0);
+ springDirections[i].Normalise();
+ }
+ }
+
+ m_aWheelSkidmarkType[0] = m_aWheelSkidmarkType[1] = SKIDMARK_NORMAL;
+ m_aWheelSkidmarkUnk[0] = m_aWheelSkidmarkUnk[1] = false;
+
+ // Make springs push up vehicle
+ for(i = 0; i < 4; i++){
+ if(m_aSuspensionSpringRatio[i] < 1.0f){
+ float bias = pHandling->fSuspensionBias;
+ if(i == BIKESUSP_R1 || i == BIKESUSP_R2)
+ bias = 1.0f - bias;
+
+ if(m_aWheelColPoints[i].normal.z > 0.35f)
+ ApplySpringCollisionAlt(pHandling->fSuspensionForceLevel,
+ springDirections[i], contactPoints[i],
+ m_aSuspensionSpringRatio[i], bias, m_aWheelColPoints[i].normal);
+ else
+ ApplySpringCollision(pHandling->fSuspensionForceLevel,
+ springDirections[i], contactPoints[i],
+ m_aSuspensionSpringRatio[i], bias);
+
+ if(m_aWheelColPoints[i].surfaceB == SURFACE_GRASS ||
+ m_aWheelColPoints[i].surfaceB == SURFACE_MUD_DRY){
+ if(i < 2)
+ m_aWheelSkidmarkType[0] = SKIDMARK_MUDDY;
+ else
+ m_aWheelSkidmarkType[1] = SKIDMARK_MUDDY;
+ }else if(m_aWheelColPoints[i].surfaceB == SURFACE_SAND ||
+ m_aWheelColPoints[i].surfaceB == SURFACE_SAND_BEACH){
+ if(i < 2){
+ m_aWheelSkidmarkType[0] = SKIDMARK_SANDY;
+ m_aWheelSkidmarkUnk[0] = true;
+ }else{
+ m_aWheelSkidmarkType[1] = SKIDMARK_SANDY;
+ m_aWheelSkidmarkUnk[1] = true;
+ }
+ }
+ }else{
+ contactPoints[i] = Multiply3x3(GetMatrix(), colModel->lines[i].p1);
+ }
+ }
+
+ // Get speed at contact points
+ for(i = 0; i < 4; i++){
+ contactSpeeds[i] = GetSpeed(contactPoints[i]);
+ if(m_aGroundPhysical[i]){
+ // subtract movement of physical we're standing on
+ contactSpeeds[i] -= m_aGroundPhysical[i]->GetSpeed(m_aGroundOffset[i]);
+#ifndef FIX_BUGS
+ // this shouldn't be reset because we still need it below
+ m_aGroundPhysical[i] = nil;
+#endif
+ }
+ }
+
+ CVector normal;
+ if(m_aSuspensionSpringRatio[0] < 1.0f || m_aSuspensionSpringRatio[1] < 1.0f){
+ normal = m_aSuspensionSpringRatio[0] < 1.0f ? m_aWheelColPoints[0].normal : m_aWheelColPoints[1].normal;
+ if(normal.z > 0.35f)
+ springDirections[0] = -normal;
+ normal = m_aSuspensionSpringRatio[1] < 1.0f ? m_aWheelColPoints[1].normal : m_aWheelColPoints[0].normal;
+ if(normal.z > 0.35f)
+ springDirections[1] = -normal;
+ }
+ if(m_aSuspensionSpringRatio[2] < 1.0f || m_aSuspensionSpringRatio[3] < 1.0f){
+ normal = m_aSuspensionSpringRatio[2] < 1.0f ? m_aWheelColPoints[2].normal : m_aWheelColPoints[3].normal;
+ if(normal.z > 0.35f)
+ springDirections[2] = -normal;
+ normal = m_aSuspensionSpringRatio[3] < 1.0f ? m_aWheelColPoints[3].normal : m_aWheelColPoints[2].normal;
+ if(normal.z > 0.35f)
+ springDirections[3] = -normal;
+ }
+
+ // game has dead code here if m_vecMoveSpeed.Magnitude() < 0.01f
+
+ // dampen springs
+ for(i = 0; i < 4; i++)
+ if(m_aSuspensionSpringRatio[i] < 1.0f)
+ ApplySpringDampening(pHandling->fSuspensionDampingLevel,
+ springDirections[i], contactPoints[i], contactSpeeds[i]);
+
+ // Get speed at contact points again
+ for(i = 0; i < 4; i++){
+ contactSpeeds[i] = GetSpeed(contactPoints[i]);
+ if(m_aGroundPhysical[i]){
+ // subtract movement of physical we're standing on
+ contactSpeeds[i] -= m_aGroundPhysical[i]->GetSpeed(m_aGroundOffset[i]);
+ m_aGroundPhysical[i] = nil;
+ }
+ }
+
+ bool gripCheat = true;
+ fwdSpeed = DotProduct(m_vecMoveSpeed, GetForward());
+ if(!CVehicle::bCheat3)
+ gripCheat = false;
+ acceleration = pHandling->Transmission.CalculateDriveAcceleration(m_fGasPedal, m_nCurrentGear, m_fChangeGearTime, fwdSpeed, gripCheat);
+ acceleration /= m_fForceMultiplier;
+
+ brake = m_fBrakePedal * pHandling->fBrakeDeceleration * CTimer::GetTimeStep();
+ bool neutralHandling = GetStatus() != STATUS_PLAYER && GetStatus() != STATUS_PLAYER_REMOTE && (pHandling->Flags & HANDLING_NEUTRALHANDLING);
+ float brakeBiasFront = neutralHandling ? 1.0f : 2.0f*pHandling->fBrakeBias;
+ float brakeBiasRear = neutralHandling ? 1.0f : 2.0f*(1.0f-pHandling->fBrakeBias);
+ float tractionBiasFront = neutralHandling ? 1.0f : 2.0f*pHandling->fTractionBias;
+ float tractionBiasRear = neutralHandling ? 1.0f : 2.0f-tractionBiasFront;
+
+ // Count how many wheels are touching the ground
+
+ m_nWheelsOnGround = 0;
+ m_nDriveWheelsOnGroundPrev = m_nDriveWheelsOnGround;
+ m_nDriveWheelsOnGround = 0;
+
+ for(i = 0; i < 4; i++){
+ if(m_aSuspensionSpringRatio[i] < 1.0f)
+ m_aWheelTimer[i] = 4.0f;
+ else
+ m_aWheelTimer[i] = Max(m_aWheelTimer[i]-CTimer::GetTimeStep(), 0.0f);
+
+ if(m_aWheelTimer[i] > 0.0f){
+ m_nWheelsOnGround++;
+ if(i == BIKESUSP_R1 || i == BIKESUSP_R2)
+ m_nDriveWheelsOnGround = 1;
+ if(m_nWheelsOnGround == 1)
+ m_vecAvgSurfaceNormal = m_aWheelColPoints[i].normal;
+ else
+ m_vecAvgSurfaceNormal += m_aWheelColPoints[i].normal;
+ }
+ }
+
+ if(m_nWheelsOnGround == 0)
+ m_vecAvgSurfaceNormal = CVector(0.0f, 0.0f, 1.0f);
+ else{
+ m_vecAvgSurfaceNormal /= m_nWheelsOnGround;
+ if(DotProduct(m_vecAvgSurfaceNormal, GetUp()) < -0.5f)
+ m_vecAvgSurfaceNormal *= -1.0f;
+ }
+
+ // Find contact points for wheel processing
+ int frontLine = m_aSuspensionSpringRatio[BIKESUSP_F1] < m_aSuspensionSpringRatio[BIKESUSP_F2] ?
+ BIKESUSP_F1 : BIKESUSP_F2;
+ CVector frontContact(0.0f,
+ colModel->lines[BIKESUSP_F1].p0.y,
+ colModel->lines[BIKESUSP_F1].p0.z - m_aSuspensionSpringRatio[frontLine]*m_aSuspensionSpringLength[BIKESUSP_F1] - 0.5f*wheelScale);
+ frontContact = Multiply3x3(GetMatrix(), frontContact);
+
+ int rearLine = m_aSuspensionSpringRatio[BIKESUSP_R1] < m_aSuspensionSpringRatio[BIKESUSP_R2] ?
+ BIKESUSP_R1 : BIKESUSP_R2;
+ CVector rearContact(0.0f,
+ colModel->lines[BIKESUSP_R1].p0.y,
+ colModel->lines[BIKESUSP_R1].p0.z - m_aSuspensionSpringRatio[rearLine]*m_aSuspensionSpringLength[BIKESUSP_R1] - 0.5f*wheelScale);
+ rearContact = Multiply3x3(GetMatrix(), rearContact);
+
+ float traction = 0.004f * m_fTraction;
+ traction *= pHandling->fTractionMultiplier / 4.0f;
+
+ // Turn wheel
+ if(GetStatus() == STATUS_PLAYER || !bIsStanding || bIsBeingPickedUp){
+ if(Abs(m_vecMoveSpeed.x) < 0.01f && Abs(m_vecMoveSpeed.y) < 0.01f && m_fSteerAngle == 0.0f){
+ m_fWheelAngle *= Pow(0.96f, CTimer::GetTimeStep());
+ }else{
+ float f;
+ if(fwdSpeed > 0.01f && m_aWheelTimer[BIKESUSP_F1] > 0.0f && m_aWheelTimer[BIKESUSP_F2] > 0.0f && GetStatus() == STATUS_PLAYER){
+ CColPoint point;
+ point.surfaceA = SURFACE_WHEELBASE;
+ point.surfaceB = SURFACE_TARMAC;
+ float steer = CSurfaceTable::GetAdhesiveLimit(point)*4.0f*pBikeHandling->fSpeedSteer*traction;
+ if(CSurfaceTable::GetAdhesionGroup(m_aWheelColPoints[rearLine].surfaceB) == ADHESIVE_LOOSE ||
+ CSurfaceTable::GetAdhesionGroup(m_aWheelColPoints[rearLine].surfaceB) == ADHESIVE_SAND)
+ steer *= pBikeHandling->fSlipSteer;
+ f = Asin(Min(steer/SQR(fwdSpeed), 1.0))/DEGTORAD(pHandling->fSteeringLock);
+ if(m_fSteerAngle < 0.0f && m_fLeanLRAngle < 0.0f ||
+ m_fSteerAngle > 0.0f && m_fLeanLRAngle > 0.0f)
+ f *= 2.0f;
+ f = Min(f, 1.0f);
+ }else{
+ f = 1.0f;
+ }
+ if(GetStatus() != STATUS_PLAYER)
+ f = 1.0f;
+ m_fWheelAngle = m_fSteerAngle*f;
+ }
+ }else if(m_fWheelAngle < DEGTORAD(20.0f))
+ m_fWheelAngle += DEGTORAD(1.5f)*CTimer::GetTimeStep();
+
+ static float fThrust;
+ static tWheelState WheelState[2];
+ CVector initialMoveSpeed = m_vecMoveSpeed;
+ bool rearWheelsFirst = !!(pHandling->Flags & HANDLING_REARWHEEL_1ST);
+
+ // Process front wheel - first try
+
+ if(!rearWheelsFirst){
+ if(m_aWheelTimer[BIKESUSP_F1] > 0.0f || m_aWheelTimer[BIKESUSP_F2] > 0.0f){
+ // Wheel on ground
+ eBikeWheelSpecial spec;
+ if(m_aWheelTimer[BIKESUSP_R1] > 0.0f || m_aWheelTimer[BIKESUSP_R2] > 0.0f)
+ spec = BIKE_WHEELSPEC_0;
+ else
+ spec = BIKE_WHEELSPEC_2;
+ CVector wheelFwd = Multiply3x3(GetMatrix(), CVector(-Sin(m_fWheelAngle), Cos(m_fWheelAngle), 0.0f));
+ wheelFwd -= DotProduct(wheelFwd, m_aWheelColPoints[frontLine].normal)*m_aWheelColPoints[frontLine].normal;
+ wheelFwd.Normalise();
+ CVector wheelRight = CrossProduct(wheelFwd, m_aWheelColPoints[frontLine].normal);
+ wheelRight.Normalise();
+
+ fThrust = 0.0f;
+ m_aWheelColPoints[frontLine].surfaceA = SURFACE_WHEELBASE;
+ float adhesion = CSurfaceTable::GetAdhesiveLimit(m_aWheelColPoints[frontLine])*traction;
+ float adhesionDestab = 1.0f;
+ if(m_fBrakeDestabilization > 0.0f)
+ switch(CSurfaceTable::GetAdhesionGroup(m_aWheelColPoints[frontLine].surfaceB)){
+ case ADHESIVE_HARD:
+ case ADHESIVE_LOOSE:
+ adhesionDestab = 0.9f;
+ break;
+ case ADHESIVE_ROAD:
+ adhesionDestab = 0.7f;
+ break;
+ }
+ if(GetStatus() == STATUS_PLAYER)
+ adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[frontLine].surfaceB);
+ if(m_wheelStatus[BIKEWHEEL_FRONT] == WHEEL_STATUS_BURST)
+ adhesion *= 0.4f;
+ WheelState[BIKEWHEEL_FRONT] = m_aWheelState[BIKEWHEEL_FRONT];
+ CVector contactSpeed = GetSpeed(frontContact);
+ ProcessBikeWheel(wheelFwd, wheelRight,
+ contactSpeed, frontContact,
+ 2, fThrust,
+ brake*brakeBiasFront,
+ adhesion*tractionBiasFront, adhesionDestab,
+ BIKEWHEEL_FRONT,
+ &m_aWheelSpeed[BIKEWHEEL_FRONT],
+ &WheelState[BIKEWHEEL_FRONT],
+ spec,
+ m_wheelStatus[BIKEWHEEL_FRONT]);
+ if(bStuckInSand && (WheelState[BIKEWHEEL_FRONT] == WHEEL_STATE_SPINNING || WheelState[BIKEWHEEL_FRONT] == WHEEL_STATE_SKIDDING))
+ WheelState[BIKEWHEEL_FRONT] = WHEEL_STATE_NORMAL;
+ }else{
+ // Wheel in the air
+ m_aWheelSpeed[BIKEWHEEL_FRONT] *= 0.95f;
+ m_aWheelRotation[BIKEWHEEL_FRONT] += m_aWheelSpeed[BIKEWHEEL_FRONT];
+ }
+ }
+
+ // Process rear wheel
+
+ if(m_aWheelTimer[BIKESUSP_R1] > 0.0f || m_aWheelTimer[BIKESUSP_R2] > 0.0f){
+ // Wheel on ground
+ float rearBrake = brake;
+ float rearTraction = traction;
+
+ CVector wheelFwd = GetForward();
+ CVector wheelRight = GetRight();
+ wheelFwd -= DotProduct(wheelFwd, m_aWheelColPoints[rearLine].normal)*m_aWheelColPoints[rearLine].normal;
+ wheelFwd.Normalise();
+ wheelRight = CrossProduct(wheelFwd, m_aWheelColPoints[rearLine].normal);
+ wheelRight.Normalise();
+
+ if(bIsHandbrakeOn){
+#ifdef FIX_BUGS
+ // Not sure if this is needed, but brake usually has timestep as a factor
+ rearBrake = 20000.0f * CTimer::GetTimeStepFix();
+#else
+ rearBrake = 20000.0f;
+#endif
+ m_fTireTemperature = 1.0f;
+ }else if(m_doingBurnout){
+ rearBrake = 0.0f;
+ rearTraction = 0.0f;
+ ApplyTurnForce(contactPoints[BIKESUSP_R1], -0.0007f*m_fTurnMass*m_fSteerAngle*GetRight()*CTimer::GetTimeStep());
+ }else if(m_fTireTemperature < 1.0f && m_fGasPedal > 0.75f){
+ rearTraction *= m_fTireTemperature;
+ ApplyTurnForce(contactPoints[BIKESUSP_R1], (1.0f-m_fTireTemperature)*-0.0007f*m_fTurnMass*m_fSteerAngle*GetRight()*CTimer::GetTimeStep());
+ }
+
+ if(fThrust > 0.0f && brake > 0.0f)
+ brake = 0.0f; // only affects next front wheel. is this intended?
+ fThrust = acceleration;
+ m_aWheelColPoints[rearLine].surfaceA = SURFACE_WHEELBASE;
+ float adhesion = CSurfaceTable::GetAdhesiveLimit(m_aWheelColPoints[rearLine])*rearTraction;
+ float adhesionDestab = 1.0f;
+ if(m_fBrakeDestabilization > 0.0f)
+ switch(CSurfaceTable::GetAdhesionGroup(m_aWheelColPoints[rearLine].surfaceB)){
+ case ADHESIVE_HARD:
+ case ADHESIVE_LOOSE:
+ adhesionDestab = 0.9f;
+ break;
+ case ADHESIVE_ROAD:
+ adhesionDestab = 0.7f;
+ break;
+ }
+ if(GetStatus() == STATUS_PLAYER)
+ adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[rearLine].surfaceB);
+ if(m_wheelStatus[BIKEWHEEL_REAR] == WHEEL_STATUS_BURST)
+ adhesion *= 0.4f;
+ WheelState[BIKEWHEEL_REAR] = m_aWheelState[BIKEWHEEL_REAR];
+ CVector contactSpeed = GetSpeed(rearContact);
+ ProcessBikeWheel(wheelFwd, wheelRight,
+ contactSpeed, rearContact,
+ 2, fThrust,
+ rearBrake*brakeBiasRear,
+ adhesion*tractionBiasRear, adhesionDestab,
+ BIKEWHEEL_REAR,
+ &m_aWheelSpeed[BIKEWHEEL_REAR],
+ &WheelState[BIKEWHEEL_REAR],
+ BIKE_WHEELSPEC_1,
+ m_wheelStatus[BIKEWHEEL_REAR]);
+ if(bStuckInSand && (WheelState[BIKEWHEEL_REAR] == WHEEL_STATE_SPINNING || WheelState[BIKEWHEEL_REAR] == WHEEL_STATE_SKIDDING))
+ WheelState[BIKEWHEEL_REAR] = WHEEL_STATE_NORMAL;
+ }else{
+ // Wheel in the air
+ if(bIsHandbrakeOn)
+ m_aWheelSpeed[BIKEWHEEL_REAR] = 0.0f;
+ else{
+ if(acceleration > 0.0f){
+ if(m_aWheelSpeed[BIKEWHEEL_REAR] < 2.0f)
+ m_aWheelSpeed[BIKEWHEEL_REAR] -= 0.2f;
+ }else{
+ if(m_aWheelSpeed[BIKEWHEEL_REAR] > -2.0f)
+ m_aWheelSpeed[BIKEWHEEL_REAR] += 0.1f;
+ }
+ }
+ m_aWheelRotation[BIKEWHEEL_REAR] += m_aWheelSpeed[BIKEWHEEL_REAR];
+ }
+
+ if(m_doingBurnout && m_aWheelState[BIKEWHEEL_REAR] == WHEEL_STATE_SPINNING){
+ m_fTireTemperature += 0.001f*CTimer::GetTimeStep();
+ if(m_fTireTemperature > 3.0f)
+ m_fTireTemperature = 3.0f;
+ }else if(m_fTireTemperature > 1.0f){
+ m_fTireTemperature = (m_fTireTemperature - 1.0f)*Pow(0.995f, CTimer::GetTimeStep()) + 1.0f;
+ }
+
+ // Process front wheel - second try
+
+ if(rearWheelsFirst){
+ if(m_aWheelTimer[BIKESUSP_F1] > 0.0f || m_aWheelTimer[BIKESUSP_F2] > 0.0f){
+ // Wheel on ground
+ eBikeWheelSpecial spec;
+ if(m_aWheelTimer[BIKESUSP_R1] > 0.0f || m_aWheelTimer[BIKESUSP_R2] > 0.0f)
+ spec = BIKE_WHEELSPEC_0;
+ else
+ spec = BIKE_WHEELSPEC_2;
+ CVector wheelFwd = GetMatrix() * CVector(-Sin(m_fWheelAngle), Cos(m_fWheelAngle), 0.0f);
+ wheelFwd -= DotProduct(wheelFwd, m_aWheelColPoints[frontLine].normal)*m_aWheelColPoints[frontLine].normal;
+ wheelFwd.Normalise();
+ CVector wheelRight = CrossProduct(wheelFwd, m_aWheelColPoints[frontLine].normal);
+ wheelRight.Normalise();
+
+ fThrust = 0.0f;
+ m_aWheelColPoints[frontLine].surfaceA = SURFACE_WHEELBASE;
+ float adhesion = CSurfaceTable::GetAdhesiveLimit(m_aWheelColPoints[frontLine])*traction;
+ float adhesionDestab = 1.0f;
+ if(m_fBrakeDestabilization > 0.0f)
+ switch(CSurfaceTable::GetAdhesionGroup(m_aWheelColPoints[frontLine].surfaceB)){
+ case ADHESIVE_HARD:
+ case ADHESIVE_LOOSE:
+ adhesionDestab = 0.9f;
+ break;
+ case ADHESIVE_ROAD:
+ adhesionDestab = 0.7f;
+ break;
+ }
+ if(GetStatus() == STATUS_PLAYER)
+ adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[frontLine].surfaceB);
+ if(m_wheelStatus[BIKEWHEEL_FRONT] == WHEEL_STATUS_BURST)
+ adhesion *= 0.4f;
+ WheelState[BIKEWHEEL_FRONT] = m_aWheelState[BIKEWHEEL_FRONT];
+ CVector contactSpeed = GetSpeed(frontContact);
+ ProcessBikeWheel(wheelFwd, wheelRight,
+ contactSpeed, frontContact,
+ 2, fThrust,
+ brake*brakeBiasFront,
+ adhesion*tractionBiasFront, adhesionDestab,
+ BIKEWHEEL_FRONT,
+ &m_aWheelSpeed[BIKEWHEEL_FRONT],
+ &WheelState[BIKEWHEEL_FRONT],
+ spec,
+ m_wheelStatus[BIKEWHEEL_FRONT]);
+ if(bStuckInSand && (WheelState[BIKEWHEEL_FRONT] == WHEEL_STATE_SPINNING || WheelState[BIKEWHEEL_FRONT] == WHEEL_STATE_SKIDDING))
+ WheelState[BIKEWHEEL_FRONT] = WHEEL_STATE_NORMAL;
+ }else{
+ // Wheel in the air
+ m_aWheelSpeed[BIKEWHEEL_FRONT] *= 0.95f;
+ m_aWheelRotation[BIKEWHEEL_FRONT] += m_aWheelSpeed[BIKEWHEEL_FRONT];
+ }
+ }
+
+ // Process leaning
+ float idleAngle = 0.0f;
+ if(pDriver){
+ CAnimBlendAssociation *assoc = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_BIKE_READY);
+ if(assoc)
+ idleAngle = DEGTORAD(10.0f) * assoc->blendAmount;
+ }
+ if(bBalancedByRider || bIsBeingPickedUp){
+ m_vecAvgSurfaceRight = CrossProduct(GetForward(), m_vecAvgSurfaceNormal);
+ m_vecAvgSurfaceRight.Normalise();
+ float lean;
+ if(m_nWheelsOnGround == 0)
+ lean = -(m_fSteerAngle/DEGTORAD(pHandling->fSteeringLock))*0.5f*GRAVITY*CTimer::GetTimeStep();
+ else
+ lean = DotProduct(m_vecMoveSpeed-initialMoveSpeed, m_vecAvgSurfaceRight);
+ lean /= GRAVITY*Max(CTimer::GetTimeStep(), 0.01f);
+ if(m_wheelStatus[BIKEWHEEL_FRONT] == WHEEL_STATUS_BURST)
+ lean = Clamp(lean, -0.4f*pBikeHandling->fMaxLean, 0.4f*pBikeHandling->fMaxLean);
+ else
+ lean = Clamp(lean, -pBikeHandling->fMaxLean, pBikeHandling->fMaxLean);
+ float f = Pow(pBikeHandling->fDesLean, CTimer::GetTimeStep());
+ m_fLeanLRAngle2 = (Asin(lean) - idleAngle)*(1.0f-f) + m_fLeanLRAngle2*f;
+ }else{
+ if(bIsStanding){
+ float f = Pow(0.97f, CTimer::GetTimeStep());
+ m_fLeanLRAngle2 = m_fLeanLRAngle2*f - (Asin(GetRight().z) + DEGTORAD(15.0f) + idleAngle)*(1.0f-f);
+ }else{
+ float f = Pow(0.95f, CTimer::GetTimeStep());
+ m_fLeanLRAngle2 = m_fLeanLRAngle2*f;
+ }
+ }
+ m_fLeanLRAngle = m_fLeanLRAngle2;
+
+ // Destabilize steering when braking
+ if((m_aSuspensionSpringRatio[BIKESUSP_F1] < 1.0f || m_aSuspensionSpringRatio[BIKESUSP_F2] < 1.0f) &&
+ m_fBrakePedal - m_fGasPedal > 0.9f &&
+ fwdSpeed > 0.02f &&
+ !bIsHandbrakeOn){
+ m_fBrakeDestabilization += CGeneral::GetRandomNumberInRange(0.5f, 1.0f)*0.2f*CTimer::GetTimeStep();
+ if(m_aSuspensionSpringRatio[BIKESUSP_R1] < 1.0f || m_aSuspensionSpringRatio[BIKESUSP_R2] < 1.0f){
+ // BUG: this clamp makes no sense and the arguments seem swapped too
+ ApplyTurnForce(contactPoints[BIKESUSP_R1],
+ m_fTurnMass*Sin(m_fBrakeDestabilization)*Clamp(fwdSpeed, 0.5f, 0.2f)*0.013f*GetRight()*CTimer::GetTimeStep());
+ }else{
+ // BUG: this clamp makes no sense and the arguments seem swapped too
+ ApplyTurnForce(contactPoints[BIKESUSP_R1],
+ m_fTurnMass*Sin(m_fBrakeDestabilization)*Clamp(fwdSpeed, 0.5f, 0.2f)*0.003f*GetRight()*CTimer::GetTimeStep());
+ }
+ }else
+ m_fBrakeDestabilization = 0.0f;
+
+ // Update wheel positions from suspension
+ float frontWheelPos = colModel->lines[frontLine].p0.z;
+ if(m_aSuspensionSpringRatio[frontLine] > 0.0f)
+ frontWheelPos -= m_aSuspensionSpringRatio[frontLine]*m_aSuspensionSpringLength[frontLine];
+ m_aWheelPosition[BIKEWHEEL_FRONT] += (frontWheelPos - m_aWheelPosition[BIKEWHEEL_FRONT])*0.75f;
+
+ float rearWheelPos = colModel->lines[rearLine].p0.z;
+ if(m_aSuspensionSpringRatio[rearLine] > 0.0f)
+ rearWheelPos -= m_aSuspensionSpringRatio[rearLine]*m_aSuspensionSpringLength[rearLine];
+ m_aWheelPosition[BIKEWHEEL_REAR] += (rearWheelPos - m_aWheelPosition[BIKEWHEEL_REAR])*0.75f;
+
+ for(i = 0; i < 2; i++)
+ m_aWheelState[i] = WheelState[i];
+ // never spin when moving backwards
+ if(m_fGasPedal < 0.0f && m_aWheelState[BIKEWHEEL_REAR] == WHEEL_STATE_SPINNING)
+ m_aWheelState[BIKEWHEEL_REAR] = WHEEL_STATE_NORMAL;
+
+ // Process horn
+
+ if(GetStatus() != STATUS_PLAYER){
+#ifdef FIX_BUGS
+ if(!IsAlarmOn())
+#endif
+ ReduceHornCounter();
+ }else{
+#ifdef FIX_BUGS
+ if(!IsAlarmOn())
+#endif
+ {
+ if(Pads[0].GetHorn())
+ m_nCarHornTimer = 1;
+ else
+ m_nCarHornTimer = 0;
+ }
+ }
+ }
+
+ if(m_fHealth < 250.0f && GetStatus() != STATUS_WRECKED){
+ // Car is on fire
+
+ CVector damagePos, fireDir;
+
+ // move fire forward if in first person
+ if(this == FindPlayerVehicle() && TheCamera.GetLookingForwardFirstPerson()){
+ damagePos = CVector(0.0f, 1.2f, -0.4f);
+ fireDir = CVector(0.0f, 0.0f, CGeneral::GetRandomNumberInRange(0.01125f, 0.09f));
+ }else{
+ damagePos = ((CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex()))->m_positions[CAR_POS_BACKSEAT];
+ damagePos.z -= 0.3f;
+ fireDir = CGeneral::GetRandomNumberInRange(0.02025f, 0.09f) * GetRight();
+ fireDir -= CGeneral::GetRandomNumberInRange(0.02025f, 0.18f) * GetForward();
+ fireDir.z = CGeneral::GetRandomNumberInRange(0.00225f, 0.018f);
+ }
+
+ damagePos = GetMatrix()*damagePos;
+ CParticle::AddParticle(PARTICLE_CARFLAME, damagePos, fireDir,
+ nil, 0.9f);
+
+ CParticle::AddParticle(PARTICLE_ENGINE_SMOKE2, damagePos, CVector(0.0f, 0.0f, 0.0f), nil, 0.5f);
+
+ damagePos.x += CGeneral::GetRandomNumberInRange(-0.5625f, 0.5625f),
+ damagePos.y += CGeneral::GetRandomNumberInRange(-0.5625f, 0.5625f),
+ damagePos.z += CGeneral::GetRandomNumberInRange(0.5625f, 2.25f);
+ CParticle::AddParticle(PARTICLE_CARFLAME_SMOKE, damagePos, CVector(0.0f, 0.0f, 0.0f));
+
+ // Blow up car after 5 seconds
+ m_fFireBlowUpTimer += CTimer::GetTimeStepInMilliseconds();
+ if(m_fFireBlowUpTimer > 5000.0f)
+ BlowUpCar(m_pSetOnFireEntity);
+ }else
+ m_fFireBlowUpTimer = 0.0f;
+
+ ProcessDelayedExplosion();
+
+ // Find out how much to shake the pad depending on suspension and ground surface
+
+ float suspShake = 0.0f;
+ float surfShake = 0.0f;
+ float speedsq = m_vecMoveSpeed.MagnitudeSqr();
+ for(i = 0; i < 4; i++){
+ float suspChange = m_aSuspensionSpringRatioPrev[i] - m_aSuspensionSpringRatio[i];
+ if(suspChange > 0.3f && (i == BIKESUSP_F1 || i == BIKESUSP_R1) && speedsq > 0.04f){
+ if(GetStatus() == STATUS_PLAYER || GetStatus() == STATUS_PHYSICS){
+#ifdef FIX_BUGS
+ // only two wheels but 4 suspensions
+ if(m_wheelStatus[i/2] == WHEEL_STATUS_BURST)
+#else
+ if(m_wheelStatus[i] == WHEEL_STATUS_BURST)
+#endif
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_JUMP_2, suspChange);
+ else
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_JUMP, suspChange);
+ if(suspChange > suspShake)
+ suspShake = suspChange;
+ }
+ }
+
+ if(this == FindPlayerVehicle()){
+ uint8 surf = m_aWheelColPoints[i].surfaceB;
+ if(surf == SURFACE_GRAVEL || surf == SURFACE_WATER || surf == SURFACE_HEDGE){
+ if(surfShake < 0.2f)
+ surfShake = 0.3f;
+ }else if(surf == SURFACE_MUD_DRY || surf == SURFACE_SAND || surf == SURFACE_SAND_BEACH){
+ if(surfShake < 0.1f)
+ surfShake = 0.2f;
+ }else if(surf == SURFACE_GRASS){
+ if(surfShake < 0.05f)
+ surfShake = 0.1f;
+ }
+
+// BUG: this only observes one of the wheels
+ TheCamera.m_bVehicleSuspenHigh = Abs(suspChange) > 0.05f;
+ }
+
+ m_aSuspensionSpringRatioPrev[i] = m_aSuspensionSpringRatio[i];
+ m_aSuspensionSpringRatio[i] = 1.0f;
+ }
+
+ // Shake pad
+
+ if((suspShake > 0.0f || surfShake > 0.0f) && GetStatus() == STATUS_PLAYER){
+ float speed = m_vecMoveSpeed.MagnitudeSqr();
+ if(speed > sq(0.1f)){
+ speed = Sqrt(speed);
+ if(suspShake > 0.0f){
+ uint8 freq = Min(200.0f*suspShake*speed*2000.0f/m_fMass + 100.0f, 250.0f);
+ CPad::GetPad(0)->StartShake(20000.0f*CTimer::GetTimeStep()/freq, freq);
+ }else{
+ uint8 freq = Min(200.0f*surfShake*speed*2000.0f/m_fMass + 40.0f, 150.0f);
+ CPad::GetPad(0)->StartShake(5000.0f*CTimer::GetTimeStep()/freq, freq);
+ }
+ }
+ }
+
+ bVehicleColProcessed = false;
+ bAudioChangingGear = false;
+
+ if(!bWarnedPeds)
+ CCarCtrl::ScanForPedDanger(this);
+
+ if(bInfiniteMass){
+ m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
+ m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f);
+ m_vecMoveFriction = CVector(0.0f, 0.0f, 0.0f);
+ m_vecTurnFriction = CVector(0.0f, 0.0f, 0.0f);
+ }else if(!skipPhysics &&
+ (acceleration == 0.0f && brake == 0.0f || GetStatus() == STATUS_WRECKED)){
+ if(Abs(m_vecMoveSpeed.x) < 0.005f &&
+ Abs(m_vecMoveSpeed.y) < 0.005f &&
+ Abs(m_vecMoveSpeed.z) < 0.005f){
+ m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
+ m_vecTurnSpeed.z = 0.0f;
+ }
+ }
+
+ // Balance bike
+ if(bBalancedByRider || bIsBeingPickedUp || bIsStanding){
+ float onSideness = DotProduct(GetRight(), m_vecAvgSurfaceNormal);
+ onSideness = Clamp(onSideness, -1.0f, 1.0f);
+ CVector worldCOM = Multiply3x3(GetMatrix(), m_vecCentreOfMass);
+ // Keep bike upright
+ if(bBalancedByRider){
+ ApplyTurnForce(-0.07f*onSideness*m_fTurnMass*GetUp()*CTimer::GetTimeStep(), worldCOM+GetRight());
+ bIsStanding = false;
+ }else
+ ApplyTurnForce(-0.1f*onSideness*m_fTurnMass*GetUp()*CTimer::GetTimeStep(), worldCOM+GetRight());
+
+ // Wheelie/Stoppie stabilization
+ if(GetStatus() == STATUS_PLAYER){
+ if(m_aWheelTimer[BIKESUSP_F1] == 0.0f && m_aWheelTimer[BIKESUSP_F2] == 0.0f && GetForward().z > 0.0 &&
+ !(m_aWheelTimer[BIKESUSP_R1] == 0.0f && m_aWheelTimer[BIKESUSP_R2] == 0.0f)){
+ // Wheelie
+ float wheelie = pBikeHandling->fWheelieAng - GetForward().z;
+ if(wheelie > 0.15f)
+ // below wheelie angle
+ wheelie = Max(0.3f - wheelie, 0.0f);
+ else if(wheelie < -0.08f)
+ // above wheelie angle
+ wheelie = Min(-0.15f - wheelie, 0.0f);
+ float wheelieStab = pBikeHandling->fWheelieStabMult * Min(m_vecMoveSpeed.Magnitude(), 0.1f) * wheelie;
+ ApplyTurnForce(0.5f*CTimer::GetTimeStep()*wheelieStab*m_fTurnMass*GetUp(), worldCOM+GetForward());
+ ApplyTurnForce(0.5f*CTimer::GetTimeStep()*m_fWheelAngle*pBikeHandling->fWheelieSteer*m_fTurnMass*GetRight(), worldCOM+GetForward());
+ }else if(m_aWheelTimer[BIKESUSP_R1] == 0.0f && m_aWheelTimer[BIKESUSP_R2] == 0.0f && GetForward().z < 0.0 &&
+ !(m_aWheelTimer[BIKESUSP_F1] == 0.0f && m_aWheelTimer[BIKESUSP_F2] == 0.0f)){
+ // Stoppie
+ float stoppie = pBikeHandling->fStoppieAng - GetForward().z;
+ if(stoppie > 0.15f)
+ // below stoppie angle
+ stoppie = Max(0.3f - stoppie, 0.0f);
+ else if(stoppie < -0.15f)
+ // above stoppie angle
+ stoppie = Min(-0.3f - stoppie, 0.0f);
+ float speed = m_vecMoveSpeed.Magnitude();
+ float stoppieStab = pBikeHandling->fStoppieStabMult * Min(speed, 0.1f) * stoppie;
+ ApplyTurnForce(0.5f*CTimer::GetTimeStep()*stoppieStab*m_fTurnMass*GetUp(), worldCOM+GetForward());
+ ApplyTurnForce(0.5f*Min(5.0f*speed,1.0f)*CTimer::GetTimeStep()*m_fWheelAngle*pBikeHandling->fWheelieSteer*m_fTurnMass*GetRight(), worldCOM+GetForward());
+ }
+ }
+ }
+}
+
+#pragma optimize("", on)
+
+void
+CBike::Teleport(CVector pos)
+{
+ CWorld::Remove(this);
+
+ SetPosition(pos);
+ SetOrientation(0.0f, 0.0f, 0.0f);
+ SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ SetTurnSpeed(0.0f, 0.0f, 0.0f);
+
+ ResetSuspension();
+
+ CWorld::Add(this);
+}
+
+void
+CBike::PreRender(void)
+{
+ int i;
+ CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex());
+
+ // Wheel particles
+
+ if(m_aWheelState[BIKEWHEEL_REAR] != WHEEL_STATE_NORMAL &&
+ m_aWheelColPoints[BIKESUSP_R2].surfaceB != SURFACE_WATER && m_aWheelTimer[BIKESUSP_R2] > 0.0f){
+ static float smokeSize = 0.2f;
+ CVector groundPos = m_aWheelColPoints[BIKESUSP_R2].point;
+ if(m_aSuspensionSpringRatioPrev[BIKESUSP_R1] < 1.0f)
+ groundPos = (groundPos + m_aWheelColPoints[BIKESUSP_R1].point)/2.0f;
+ groundPos += Sin(m_fLeanLRAngle) * 0.8f*GetColModel()->boundingBox.min.z * GetRight();
+ CParticle::AddParticle(PARTICLE_RUBBER_SMOKE,
+ groundPos + CVector(0.0f, 0.0f, 0.25f), CVector(0.0f, 0.0f, 0.0f),
+ nil, smokeSize);
+
+ CSkidmarks::RegisterOne((uintptr)this, groundPos, GetForward().x, GetForward().y,
+ m_aWheelSkidmarkType[BIKEWHEEL_REAR], &m_aWheelSkidmarkBloody[BIKEWHEEL_REAR]);
+
+ if(m_aWheelState[BIKEWHEEL_REAR] == WHEEL_STATE_SPINNING &&
+ (CSurfaceTable::GetAdhesionGroup(m_aWheelColPoints[BIKESUSP_R2].surfaceB) == ADHESIVE_HARD ||
+ CSurfaceTable::GetAdhesionGroup(m_aWheelColPoints[BIKESUSP_R2].surfaceB) == ADHESIVE_ROAD)){
+ CParticle::AddParticle(PARTICLE_BURNINGRUBBER_SMOKE,
+ groundPos + CVector(0.0f, 0.0f, 0.25f),
+ CVector(0.0f, 0.0f, 0.0f));
+ CParticle::AddParticle(PARTICLE_BURNINGRUBBER_SMOKE,
+ groundPos + CVector(0.0f, 0.0f, 0.25f),
+ CVector(0.0f, 0.0f, 0.05f));
+ }
+ }else if(m_aWheelSkidmarkBloody[BIKEWHEEL_REAR] || m_aWheelSkidmarkUnk[BIKEWHEEL_REAR]){
+ CVector groundPos = m_aWheelColPoints[BIKESUSP_R2].point;
+ groundPos += Sin(m_fLeanLRAngle) * 0.8f*GetColModel()->boundingBox.min.z * GetRight();
+
+ CSkidmarks::RegisterOne((uintptr)this, groundPos, GetForward().x, GetForward().y,
+ m_aWheelSkidmarkType[BIKEWHEEL_REAR], &m_aWheelSkidmarkBloody[BIKEWHEEL_REAR]);
+ }
+
+ // Process lights
+
+ // Turn lights on/off
+ bool shouldLightsBeOn =
+ CClock::GetHours() > 20 ||
+ CClock::GetHours() > 19 && CClock::GetMinutes() > (m_randomSeed & 0x3F) ||
+ CClock::GetHours() < 7 ||
+ CClock::GetHours() < 8 && CClock::GetMinutes() < (m_randomSeed & 0x3F) ||
+ m_randomSeed/50000.0f < CWeather::Foggyness ||
+ m_randomSeed/50000.0f < CWeather::WetRoads;
+ if(shouldLightsBeOn != bLightsOn && GetStatus() != STATUS_WRECKED){
+ if(GetStatus() == STATUS_ABANDONED){
+ // Turn off lights on abandoned vehicles only when we they're far away
+ if(bLightsOn &&
+ Abs(TheCamera.GetPosition().x - GetPosition().x) + Abs(TheCamera.GetPosition().y - GetPosition().y) > 100.0f)
+ bLightsOn = false;
+ }else
+ bLightsOn = shouldLightsBeOn;
+ }
+
+ // Actually render the lights
+ bool alarmOn = false;
+ bool alarmOff = false;
+ if(IsAlarmOn()){
+ if(CTimer::GetTimeInMilliseconds() & 0x100)
+ alarmOn = true;
+ else
+ alarmOff = true;
+ }
+ if(bEngineOn && bLightsOn || alarmOn || alarmOff){
+ CalculateLeanMatrix();
+ CVector lookVector = GetPosition() - TheCamera.GetPosition();
+ float camDist = lookVector.Magnitude();
+ if(camDist != 0.0f)
+ lookVector *= 1.0f/camDist;
+ else
+ lookVector = CVector(1.0f, 0.0f, 0.0f);
+
+ // 1.0 if directly behind car, -1.0 if in front
+ float behindness = DotProduct(lookVector, GetForward());
+ // 0.0 if behind car, PI if in front
+ float angle = Abs(Acos(Abs(behindness)));
+
+ // Headlight
+
+ CMatrix mat;
+ CVector headLightPos = mi->m_positions[CAR_POS_HEADLIGHTS];
+ if(GetModelIndex() == 152){ // this is the bobcat in VC, but we don't want that effect anyway
+ mat.SetUnity();
+ mat.RotateZ(m_fWheelAngle);
+ mat = m_leanMatrix * mat;
+ }else
+ mat = m_leanMatrix;
+ CVector light = mat * headLightPos;
+ if(behindness < 0.0f){
+ // In front of bike
+ float intensity = -0.5f*behindness + 0.3f;
+ float size = 1.0f - behindness;
+
+ if(behindness < -0.97f && camDist < 30.0f){
+ // Directly in front and not too far away
+ if(pHandling->Flags & HANDLING_HALOGEN_LIGHTS){
+ CCoronas::RegisterCorona((uintptr)this + 6, 150, 150, 195, 255,
+ light, 1.2f, 45.0f*TheCamera.LODDistMultiplier,
+ CCoronas::TYPE_HEADLIGHT, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON,
+ CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, angle);
+ }else{
+ CCoronas::RegisterCorona((uintptr)this + 6, 160, 160, 140, 255,
+ light, 1.2f, 45.0f*TheCamera.LODDistMultiplier,
+ CCoronas::TYPE_HEADLIGHT, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON,
+ CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, angle);
+ }
+ }
+
+ if(alarmOff){
+ CCoronas::RegisterCorona((uintptr)this, 0, 0, 0, 0,
+ light, size, 0.0f,
+ CCoronas::TYPE_STREAK, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON,
+ CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, angle);
+ }else{
+ if(pHandling->Flags & HANDLING_HALOGEN_LIGHTS){
+ CCoronas::RegisterCorona((uintptr)this + 1, 190*intensity, 190*intensity, 255*intensity, 255,
+ light, size, 50.0f*TheCamera.LODDistMultiplier,
+ CCoronas::TYPE_STREAK, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON,
+ CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, angle);
+ }else{
+ CCoronas::RegisterCorona((uintptr)this + 1, 210*intensity, 210*intensity, 195*intensity, 255,
+ light, size, 50.0f*TheCamera.LODDistMultiplier,
+ CCoronas::TYPE_STREAK, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON,
+ CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, angle);
+ }
+ }
+ }else{
+ CCoronas::UpdateCoronaCoors((uintptr)this, light, 50.0f*TheCamera.LODDistMultiplier, angle);
+ }
+
+ // bright light
+ CBrightLights::RegisterOne(light, GetUp(), GetRight(), GetForward(), pHandling->FrontLights + BRIGHTLIGHT_FRONT);
+
+ // Taillight
+
+ CVector tailLightPos = mi->m_positions[CAR_POS_TAILLIGHTS];
+ light = m_leanMatrix * tailLightPos;
+
+ // Taillight corona
+ if(behindness > 0.0f){
+ // Behind car
+ float intensity = 0.4f*behindness + 0.4f;
+ float size = (behindness + 1.0f)/2.0f;
+
+ if(m_fGasPedal < 0.0f){
+ // reversing
+ // no lights in this case
+ }else{
+ if(m_fBrakePedal > 0.0f){
+ intensity += 0.4f;
+ size += 0.3f;
+ }
+
+ if(alarmOff){
+ CCoronas::RegisterCorona((uintptr)this + 14, 0, 0, 0, 0,
+ light, size, 0.0f,
+ CCoronas::TYPE_STREAK, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON,
+ CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, angle);
+ }else{
+ CCoronas::RegisterCorona((uintptr)this + 14, 128*intensity, 0, 0, 255,
+ light, size, 50.0f*TheCamera.LODDistMultiplier,
+ CCoronas::TYPE_STREAK, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON,
+ CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, angle);
+ }
+ }
+ }else{
+ CCoronas::UpdateCoronaCoors((uintptr)this + 14, light, 50.0f*TheCamera.LODDistMultiplier, angle);
+ }
+
+ // bright light
+ CBrightLights::RegisterOne(light, GetUp(), GetRight(), GetForward(), pHandling->RearLights + BRIGHTLIGHT_REAR);
+
+ // Light shadows
+ if(!alarmOff){
+ CVector pos = GetPosition();
+ CVector2D fwd(GetForward());
+ fwd.Normalise();
+ float f = headLightPos.y + 6.0f;
+ pos += CVector(f*fwd.x, f*fwd.y, 2.0f);
+ CShadows::StoreCarLightShadow(this, (uintptr)this + 22, gpShadowExplosionTex, &pos,
+ 7.0f*fwd.x, 7.0f*fwd.y, 3.5f*fwd.y, -3.5f*fwd.x, 45, 45, 45, 7.0f);
+
+ f = (tailLightPos.y - 2.5f) - (headLightPos.y + 6.0f);
+ pos += CVector(f*fwd.x, f*fwd.y, 0.0f);
+ CShadows::StoreCarLightShadow(this, (uintptr)this + 25, gpShadowExplosionTex, &pos,
+ 3.0f, 0.0f, 0.0f, -3.0f, 35, 0, 0, 4.0f);
+ }
+
+ if(this == FindPlayerVehicle() && !alarmOff){
+ CPointLights::AddLight(CPointLights::LIGHT_DIRECTIONAL, GetPosition(), GetForward(),
+ 20.0f, 1.0f, 1.0f, 1.0f,
+ FindPlayerVehicle()->m_vecMoveSpeed.MagnitudeSqr2D() < sq(0.45f) ? CPointLights::FOG_NORMAL : CPointLights::FOG_NONE,
+ false);
+ CVector pos = GetPosition() - 4.0f*GetForward();
+ if(m_fBrakePedal > 0.0f)
+ CPointLights::AddLight(CPointLights::LIGHT_POINT, pos, CVector(0.0f, 0.0f, 0.0f),
+ 10.0f, 1.0f, 0.0f, 0.0f,
+ CPointLights::FOG_NONE, false);
+ else
+ CPointLights::AddLight(CPointLights::LIGHT_POINT, pos, CVector(0.0f, 0.0f, 0.0f),
+ 7.0f, 0.6f, 0.0f, 0.0f,
+ CPointLights::FOG_NONE, false);
+ }
+ }else if(GetStatus() != STATUS_ABANDONED && GetStatus() != STATUS_WRECKED){
+ // Lights off
+ CalculateLeanMatrix();
+
+ CVector tailLightPos = mi->m_positions[CAR_POS_TAILLIGHTS];
+ CVector light = m_leanMatrix * tailLightPos;
+
+ if(m_fBrakePedal > 0.0f || m_fGasPedal < 0.0f){
+ CVector lookVector = GetPosition() - TheCamera.GetPosition();
+ lookVector.Normalise();
+ float behindness = DotProduct(lookVector, GetForward());
+ if(behindness > 0.0f){
+ if(m_fGasPedal < 0.0f){
+ // reversing
+ // no lights in this case
+ }else{
+ // braking
+ CCoronas::RegisterCorona((uintptr)this + 14, 120, 0, 0, 255,
+ light, 1.2f, 50.0f*TheCamera.LODDistMultiplier,
+ CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON,
+ CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, 0.0f);
+ CBrightLights::RegisterOne(light, GetUp(), GetRight(), GetForward(), pHandling->RearLights + BRIGHTLIGHT_REAR);
+ }
+ }else{
+ CCoronas::UpdateCoronaCoors((uintptr)this + 14, light, 50.0f*TheCamera.LODDistMultiplier, 0.0f);
+ }
+ }else{
+ CCoronas::UpdateCoronaCoors((uintptr)this + 14, light, 50.0f*TheCamera.LODDistMultiplier, 0.0f);
+ }
+ }
+
+
+ // Wheel particles
+
+ float fwdSpeed = DotProduct(m_vecMoveSpeed, GetForward())*180.0f;
+ int drawParticles = Abs(fwdSpeed) < 90.0f;
+ int susp = BIKESUSP_F1;
+ for(i = 0; i < 2; i++){
+ if(i == BIKEWHEEL_REAR)
+ susp = BIKESUSP_R1;
+
+ static float speedSq;
+ // Sparks for friction of burst wheels
+ if(m_wheelStatus[i] == WHEEL_STATUS_BURST && m_aSuspensionSpringRatioPrev[susp] < 1.0f &&
+ (speedSq = m_vecMoveSpeed.MagnitudeSqr(), speedSq > SQR(0.1f)) &&
+ m_aWheelColPoints[susp].surfaceB != SURFACE_GRASS &&
+ m_aWheelColPoints[susp].surfaceB != SURFACE_MUD_DRY &&
+ m_aWheelColPoints[susp].surfaceB != SURFACE_SAND &&
+ m_aWheelColPoints[susp].surfaceB != SURFACE_SAND_BEACH){
+ CVector normalSpeed = m_aWheelColPoints[susp].normal * DotProduct(m_aWheelColPoints[susp].normal, m_vecMoveSpeed);
+ CVector frictionSpeed = m_vecMoveSpeed - normalSpeed;
+ CVector sparkDir = 0.25f*frictionSpeed;
+ CParticle::AddParticle(PARTICLE_SPARK_SMALL, m_aWheelColPoints[susp].point, sparkDir);
+
+ if(speedSq > 0.04f)
+ CParticle::AddParticle(PARTICLE_SPARK_SMALL, m_aWheelColPoints[susp].point, sparkDir);
+ if(speedSq > 0.16f){
+ CParticle::AddParticle(PARTICLE_SPARK_SMALL, m_aWheelColPoints[susp].point, sparkDir);
+ CParticle::AddParticle(PARTICLE_SPARK_SMALL, m_aWheelColPoints[susp].point, sparkDir);
+ }
+ }else if(m_aSuspensionSpringRatioPrev[i] < 1.0f &&
+ (fwdSpeed > 0.2f || m_aWheelState[i] == WHEEL_STATE_SPINNING)){
+ if(m_aWheelColPoints[susp].surfaceB == SURFACE_GRASS ||
+ m_aWheelColPoints[susp].surfaceB == SURFACE_MUD_DRY ||
+ m_aWheelColPoints[susp].surfaceB == SURFACE_SAND ||
+ m_aWheelColPoints[susp].surfaceB == SURFACE_SAND_BEACH)
+ AddWheelDirtAndWater(&m_aWheelColPoints[susp], drawParticles);
+ }
+ }
+
+ AddDamagedVehicleParticles();
+ CShadows::StoreShadowForVehicle(this, VEH_SHD_TYPE_BIKE);
+
+ CMatrix mat;
+ CVector pos;
+ CColModel *colModel = mi->GetColModel();
+
+ // Wheel rotation
+ CVector frontWheelFwd = Multiply3x3(GetMatrix(), CVector(-Sin(m_fSteerAngle), Cos(m_fSteerAngle), 0.0f));
+ CVector rearWheelFwd = GetForward();
+ if(m_aWheelTimer[BIKESUSP_F1] > 0.0f || m_aWheelTimer[BIKESUSP_F2] > 0.0f){
+ float springRatio = Min(m_aSuspensionSpringRatioPrev[BIKESUSP_F1], m_aSuspensionSpringRatioPrev[BIKESUSP_F2]);
+ CVector contactPoint(0.0f,
+ (colModel->lines[BIKESUSP_F1].p0.y - colModel->lines[BIKESUSP_F2].p0.y)/2.0f,
+ colModel->lines[BIKESUSP_F1].p0.z - m_aSuspensionSpringLength[BIKESUSP_F1]*springRatio - 0.5f*mi->m_wheelScale);
+ CVector contactSpeed = GetSpeed(contactPoint);
+ // Why is wheel state always normal?
+ m_aWheelSpeed[BIKEWHEEL_FRONT] = ProcessWheelRotation(WHEEL_STATE_NORMAL, frontWheelFwd, contactSpeed, 0.5f*mi->m_wheelScale);
+ m_aWheelRotation[BIKEWHEEL_FRONT] += m_aWheelSpeed[BIKEWHEEL_FRONT];
+ }
+ if(m_aWheelTimer[BIKESUSP_R1] > 0.0f || m_aWheelTimer[BIKESUSP_R2] > 0.0f){
+ float springRatio = Min(m_aSuspensionSpringRatioPrev[BIKESUSP_R1], m_aSuspensionSpringRatioPrev[BIKESUSP_R2]);
+ CVector contactPoint(0.0f,
+ (colModel->lines[BIKESUSP_R1].p0.y - colModel->lines[BIKESUSP_R2].p0.y)/2.0f,
+ colModel->lines[BIKESUSP_R1].p0.z - m_aSuspensionSpringLength[BIKESUSP_R1]*springRatio - 0.5f*mi->m_wheelScale);
+ CVector contactSpeed = GetSpeed(contactPoint);
+ m_aWheelSpeed[BIKEWHEEL_REAR] = ProcessWheelRotation(m_aWheelState[BIKEWHEEL_REAR], rearWheelFwd, contactSpeed, 0.5f*mi->m_wheelScale);
+ m_aWheelRotation[BIKEWHEEL_REAR] += m_aWheelSpeed[BIKEWHEEL_REAR];
+ }
+
+ // Front fork
+ if(m_aBikeNodes[BIKE_FORKS_FRONT]){
+ mat.Attach(RwFrameGetMatrix(m_aBikeNodes[BIKE_FORKS_FRONT]));
+ pos = mat.GetPosition();
+
+ RwMatrix rwrot;
+ // TODO: this looks like some weird ctor we don't have
+ CMatrix rot;
+ rot.m_attachment = &rwrot;
+ rot.SetUnity();
+ rot.UpdateRW();
+
+ // Make rotation matrix with front fork as axis
+ CVector forkAxis(0.0f, Sin(DEGTORAD(mi->m_bikeSteerAngle)), -Cos(DEGTORAD(mi->m_bikeSteerAngle)));
+ forkAxis.Normalise(); // as if that's not already the case
+ CQuaternion quat;
+ quat.Set(&forkAxis, -m_fWheelAngle);
+ quat.Get(rot.m_attachment);
+ rot.Update();
+
+ // Transform fork
+ mat.SetUnity();
+ mat = mat * rot;
+ mat.Translate(pos);
+ mat.UpdateRW();
+
+ if(m_aBikeNodes[BIKE_HANDLEBARS]){
+ // Transform handle
+ mat.Attach(RwFrameGetMatrix(m_aBikeNodes[BIKE_HANDLEBARS]));
+ pos = mat.GetPosition();
+ if(GetStatus() == STATUS_ABANDONED || GetStatus() == STATUS_WRECKED){
+ mat.SetUnity();
+ mat = mat * rot;
+ mat.Translate(pos);
+ }else
+ mat.SetTranslate(mat.GetPosition());
+ mat.UpdateRW();
+ }
+ }
+
+ // Rear fork
+ if(m_aBikeNodes[BIKE_FORKS_REAR]){
+ float sine = (m_aWheelPosition[BIKEWHEEL_REAR] - m_aWheelBasePosition[BIKEWHEEL_REAR])/m_fRearForkLength;
+ mat.Attach(RwFrameGetMatrix(m_aBikeNodes[BIKE_FORKS_REAR]));
+ pos = mat.GetPosition();
+ mat.SetRotate(-Asin(sine), 0.0f, 0.0f);
+ mat.Translate(pos);
+ mat.UpdateRW();
+ }
+
+ // Front wheel
+ mat.Attach(RwFrameGetMatrix(m_aBikeNodes[BIKE_WHEEL_FRONT]));
+ pos.x = mat.GetPosition().x;
+ pos.z = m_aWheelPosition[BIKEWHEEL_FRONT] - m_fFrontForkZ;
+ float y = (colModel->lines[BIKESUSP_F1].p0.y+colModel->lines[BIKESUSP_F2].p0.y)/2.0f - m_fFrontForkY;
+ pos.y = y - (m_aWheelPosition[BIKEWHEEL_FRONT] - m_aWheelBasePosition[BIKEWHEEL_FRONT])*m_fFrontForkSlope;
+ if(m_wheelStatus[BIKEWHEEL_FRONT] == WHEEL_STATUS_BURST)
+ mat.SetRotate(m_aWheelRotation[BIKEWHEEL_FRONT], 0.0f, 0.05f*Sin(m_aWheelRotation[BIKEWHEEL_FRONT]));
+ else
+ mat.SetRotateX(m_aWheelRotation[BIKEWHEEL_FRONT]);
+ mat.Translate(pos);
+ mat.UpdateRW();
+ // and mudguard
+ mat.Attach(RwFrameGetMatrix(m_aBikeNodes[BIKE_MUDGUARD]));
+ mat.SetTranslateOnly(pos);
+ mat.UpdateRW();
+
+ // Rear wheel
+ mat.Attach(RwFrameGetMatrix(m_aBikeNodes[BIKE_WHEEL_REAR]));
+ pos = mat.GetPosition();
+ if(m_wheelStatus[BIKEWHEEL_REAR] == WHEEL_STATUS_BURST)
+ mat.SetRotate(m_aWheelRotation[BIKEWHEEL_REAR], 0.0f, 0.07f*Sin(m_aWheelRotation[BIKEWHEEL_REAR]));
+ else
+ mat.SetRotateX(m_aWheelRotation[BIKEWHEEL_REAR]);
+ mat.Translate(pos);
+ mat.UpdateRW();
+
+ // Chassis
+ if(m_aBikeNodes[BIKE_CHASSIS]){
+ mat.Attach(RwFrameGetMatrix(m_aBikeNodes[BIKE_CHASSIS]));
+ pos = mat.GetPosition();
+ pos.z = (1.0f - Cos(m_fLeanLRAngle)) * (0.9*colModel->boundingBox.min.z);
+ mat.SetRotateX(-0.05f*Abs(m_fLeanLRAngle));
+ mat.RotateY(m_fLeanLRAngle);
+ mat.Translate(pos);
+ mat.UpdateRW();
+ }
+
+ // Exhaust smoke
+ if(bEngineOn && !(pHandling->Flags & HANDLING_NO_EXHAUST) && fwdSpeed < 130.0f){
+ CVector exhaustPos = mi->m_positions[CAR_POS_EXHAUST];
+ CVector pos1, pos2, dir;
+
+ if(exhaustPos != CVector(0.0f, 0.0f, 0.0f)){
+ dir.z = 0.0f;
+ if(fwdSpeed < 10.0f){
+ CVector steerFwd(-Sin(m_fSteerAngle), Cos(m_fSteerAngle), 0.0f);
+ steerFwd = Multiply3x3(GetMatrix(), steerFwd);
+ float r = CGeneral::GetRandomNumberInRange(-0.06f, -0.03f);
+ dir.x = steerFwd.x * r;
+ dir.y = steerFwd.y * r;
+ }else{
+ dir.x = m_vecMoveSpeed.x;
+ dir.y = m_vecMoveSpeed.y;
+ }
+
+ bool dblExhaust = false;
+ pos1 = GetMatrix() * exhaustPos;
+ if(pHandling->Flags & HANDLING_DBL_EXHAUST){
+ dblExhaust = true;
+ pos2 = exhaustPos;
+ pos2.x = -pos2.x;
+ pos2 = GetMatrix() * pos2;
+ }
+
+ static float fumesLimit = 2.0f;
+ if(CGeneral::GetRandomNumberInRange(1.0f, 3.0f)*(m_fGasPedal+1.1f) > fumesLimit){
+ CParticle::AddParticle(PARTICLE_EXHAUST_FUMES, pos1, dir);
+ if(dblExhaust)
+ CParticle::AddParticle(PARTICLE_EXHAUST_FUMES, pos2, dir);
+
+ if(GetStatus() == STATUS_PLAYER && (CTimer::GetFrameCounter()&3) == 0 &&
+ CWeather::Rain == 0.0f){
+ CVector camDist = GetPosition() - TheCamera.GetPosition();
+ if(DotProduct(GetForward(), camDist) > 0.0f ||
+ TheCamera.GetLookDirection() == LOOKING_LEFT ||
+ TheCamera.GetLookDirection() == LOOKING_RIGHT){
+ if(dblExhaust)
+ pos1 = 0.5f*pos1 + 0.5f*pos2;
+
+ if(TheCamera.GetLookDirection() == LOOKING_LEFT ||
+ TheCamera.GetLookDirection() == LOOKING_RIGHT)
+ pos1 -= 0.2f*GetForward();
+
+ CParticle::AddParticle(PARTICLE_HEATHAZE, pos1, CVector(0.0f, 0.0f, 0.0f));
+ }
+ }
+ }
+ }
+ }
+}
+
+void
+CBike::Render(void)
+{
+ CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex());
+
+ m_nSetPieceExtendedRangeTime = CTimer::GetTimeInMilliseconds() + 3000;
+ mi->SetVehicleColour(m_currentColour1, m_currentColour2);
+ CEntity::Render();
+}
+
+int32
+CBike::ProcessEntityCollision(CEntity *ent, CColPoint *colpoints)
+{
+ int i;
+ CColModel *colModel;
+
+ if(GetStatus() != STATUS_SIMPLE)
+ bVehicleColProcessed = true;
+
+ colModel = GetColModel();
+
+ int numWheelCollisions = 0;
+ float prevRatios[4] = { 0.0f, 0.0f, 0.0f, 0.0f};
+ for(i = 0; i < 4; i++)
+ prevRatios[i] = m_aSuspensionSpringRatio[i];
+
+ if(m_bIsVehicleBeingShifted || bSkipLineCol || ent->IsPed() ||
+ GetModelIndex() == MI_DODO && ent->IsVehicle())
+ colModel->numLines = 0;
+
+ int numCollisions = CCollision::ProcessColModels(GetMatrix(), *colModel,
+ ent->GetMatrix(), *ent->GetColModel(),
+ colpoints,
+ m_aWheelColPoints, m_aSuspensionSpringRatio);
+
+ // m_aSuspensionSpringRatio are now set to the point where the tyre touches ground.
+ // In ProcessControl these will be re-normalized to ignore the tyre radius.
+ if(colModel->numLines){
+ for(i = 0; i < 4; i++){
+ if(m_aSuspensionSpringRatio[i] < 1.0f && m_aSuspensionSpringRatio[i] < prevRatios[i]){
+ numWheelCollisions++;
+
+ // wheel is touching a physical
+ if(ent->IsVehicle() || ent->IsObject()){
+ CPhysical *phys = (CPhysical*)ent;
+
+ m_aGroundPhysical[i] = phys;
+ phys->RegisterReference((CEntity**)&m_aGroundPhysical[i]);
+ m_aGroundOffset[i] = m_aWheelColPoints[i].point - phys->GetPosition();
+ }
+
+ m_nSurfaceTouched = m_aWheelColPoints[i].surfaceB;
+ if(ent->IsBuilding())
+ m_pCurGroundEntity = ent;
+ }
+ }
+ }else
+ colModel->numLines = 4;
+
+ if(numCollisions > 0 || numWheelCollisions > 0){
+ AddCollisionRecord(ent);
+ if(!ent->IsBuilding())
+ ((CPhysical*)ent)->AddCollisionRecord(this);
+
+ if(numCollisions > 0)
+ if(ent->IsBuilding() ||
+ ent->IsObject() && ((CPhysical*)ent)->bInfiniteMass)
+ bHasHitWall = true;
+ }
+
+ return numCollisions;
+}
+
+static int16 nLastControlInput;
+static float fMouseCentreRange = 0.35f;
+static float fMouseSteerSens = -0.0035f;
+static float fMouseCentreMult = 0.975f;
+
+void
+CBike::ProcessControlInputs(uint8 pad)
+{
+ float speed = DotProduct(m_vecMoveSpeed, GetForward());
+
+ if(CPad::GetPad(pad)->GetExitVehicle())
+ bIsHandbrakeOn = true;
+ else
+ bIsHandbrakeOn = !!CPad::GetPad(pad)->GetHandBrake();
+
+ // Steer left/right
+#ifdef FIX_BUGS
+ if(CCamera::m_bUseMouse3rdPerson && !CVehicle::m_bDisableMouseSteering){
+ if(CPad::GetPad(pad)->GetMouseX() != 0.0f){
+ m_fSteerInput += fMouseSteerSens*CPad::GetPad(pad)->GetMouseX();
+ nLastControlInput = 2;
+ if(Abs(m_fSteerInput) < fMouseCentreRange)
+ m_fSteerInput *= Pow(fMouseCentreMult, CTimer::GetTimeStep());
+ }else if(CPad::GetPad(pad)->GetSteeringLeftRight() || nLastControlInput != 2){
+ // mouse hasn't move, steer with pad like below
+ m_fSteerInput += (-CPad::GetPad(pad)->GetSteeringLeftRight()/128.0f - m_fSteerInput)*
+ 0.2f*CTimer::GetTimeStep();
+ nLastControlInput = 0;
+ }
+ }else
+#endif
+ {
+ m_fSteerInput += (-CPad::GetPad(pad)->GetSteeringLeftRight()/128.0f - m_fSteerInput)*
+ 0.2f*CTimer::GetTimeStep();
+ nLastControlInput = 0;
+ }
+ m_fSteerInput = Clamp(m_fSteerInput, -1.0f, 1.0f);
+
+ // Lean forward/backward
+ float updown;
+#ifdef FREE_CAM
+ if (CCamera::bFreeCam) updown = CPad::IsAffectedByController ? -CPad::GetPad(pad)->GetSteeringUpDown()/128.0f : CPad::GetPad(pad)->GetCarGunUpDown()/128.0f;
+ else
+#endif
+ updown = -CPad::GetPad(pad)->GetSteeringUpDown()/128.0f + CPad::GetPad(pad)->GetCarGunUpDown()/128.0f;
+ m_fLeanInput += (updown - m_fLeanInput)*0.2f*CTimer::GetTimeStep();
+ m_fLeanInput = Clamp(m_fLeanInput, -1.0f, 1.0f);
+
+ // Accelerate/Brake
+ float acceleration = (CPad::GetPad(pad)->GetAccelerate() - CPad::GetPad(pad)->GetBrake())/255.0f;
+ if(GetModelIndex() == MI_DODO && acceleration < 0.0f)
+ acceleration *= 0.3f;
+ if(Abs(speed) < 0.01f){
+ // standing still, go into direction we want
+ if(CPad::GetPad(pad)->GetAccelerate() > 150.0f && CPad::GetPad(pad)->GetBrake() > 150.0f){
+ m_fGasPedal = CPad::GetPad(pad)->GetAccelerate()/255.0f;
+ m_fBrakePedal = CPad::GetPad(pad)->GetBrake()/255.0f;
+ m_doingBurnout = 1;
+ }else{
+ m_fGasPedal = acceleration;
+ m_fBrakePedal = 0.0f;
+ }
+ }else{
+#if 1
+ // simpler than the code below
+ if(speed * acceleration < 0.0f){
+ // if opposite directions, have to brake first
+ m_fGasPedal = 0.0f;
+ m_fBrakePedal = Abs(acceleration);
+ }else{
+ // accelerating in same direction we were already going
+ m_fGasPedal = acceleration;
+ m_fBrakePedal = 0.0f;
+ }
+#else
+ if(speed < 0.0f){
+ // moving backwards currently
+ if(acceleration < 0.0f){
+ // still go backwards
+ m_fGasPedal = acceleration;
+ m_fBrakePedal = 0.0f;
+ }else{
+ // want to go forwards, so brake
+ m_fGasPedal = 0.0f;
+ m_fBrakePedal = acceleration;
+ }
+ }else{
+ // moving forwards currently
+ if(acceleration < 0.0f){
+ // want to go backwards, so brake
+ m_fGasPedal = 0.0f;
+ m_fBrakePedal = -acceleration;
+ }else{
+ // still go forwards
+ m_fGasPedal = acceleration;
+ m_fBrakePedal = 0.0f;
+ }
+ }
+#endif
+ }
+
+ // Actually turn wheels
+ static float fValue; // why static?
+ if(m_fSteerInput < 0.0f)
+ fValue = -sq(m_fSteerInput);
+ else
+ fValue = sq(m_fSteerInput);
+ m_fSteerAngle = DEGTORAD(pHandling->fSteeringLock) * fValue;
+
+ if(bComedyControls){
+ if(((CTimer::GetTimeInMilliseconds() >> 10) & 0xF) < 12)
+ m_fGasPedal = 1.0f;
+ if((((CTimer::GetTimeInMilliseconds() >> 10)+6) & 0xF) < 12)
+ m_fBrakePedal = 0.0f;
+ bIsHandbrakeOn = false;
+ if(CTimer::GetTimeInMilliseconds() & 0x800)
+ m_fSteerAngle += 0.08f;
+ else
+ m_fSteerAngle -= 0.03f;
+ }
+
+ // Brake if player isn't in control
+ // BUG: game always uses pad 0 here
+ if(CPad::GetPad(pad)->ArePlayerControlsDisabled()){
+ m_fBrakePedal = 1.0f;
+ bIsHandbrakeOn = true;
+ m_fGasPedal = 0.0f;
+
+ FindPlayerPed()->KeepAreaAroundPlayerClear();
+
+ // slow down car immediately
+ speed = m_vecMoveSpeed.Magnitude();
+ if(speed > 0.28f)
+ m_vecMoveSpeed *= 0.28f/speed;
+ }
+}
+
+void
+CBike::ProcessBuoyancy(void)
+{
+ int i;
+ CVector impulse, point;
+
+ if(mod_Buoyancy.ProcessBuoyancy(this, m_fBuoyancy, &point, &impulse)){
+ bTouchingWater = true;
+ ApplyMoveForce(impulse);
+ ApplyTurnForce(impulse, point);
+
+ float timeStep = Max(CTimer::GetTimeStep(), 0.01f);
+ float impulseRatio = impulse.z / (GRAVITY * m_fMass * timeStep);
+ float waterResistance = Pow(1.0f - 0.05f*impulseRatio, CTimer::GetTimeStep());
+ m_vecMoveSpeed *= waterResistance;
+ m_vecTurnSpeed *= waterResistance;
+
+ if(impulseRatio > 0.8f ||
+ impulseRatio > 0.4f && (m_aSuspensionSpringRatio[0] == 1.0f ||
+ m_aSuspensionSpringRatio[1] == 1.0f ||
+ m_aSuspensionSpringRatio[2] == 1.0f ||
+ m_aSuspensionSpringRatio[3] == 1.0f)){
+ bIsInWater = true;
+ bIsDrowning = true;
+ if(m_vecMoveSpeed.z < -0.1f)
+ m_vecMoveSpeed.z = -0.1f;
+
+ if(pDriver){
+ pDriver->bIsInWater = true;
+ if(pDriver->IsPlayer() || !bWaterTight){
+ if(m_aSuspensionSpringRatio[0] < 1.0f ||
+ m_aSuspensionSpringRatio[1] < 1.0f ||
+ m_aSuspensionSpringRatio[2] < 1.0f ||
+ m_aSuspensionSpringRatio[3] < 1.0f)
+ pDriver->InflictDamage(nil, WEAPONTYPE_DROWNING, CTimer::GetTimeStep(), PEDPIECE_TORSO, 0);
+ else
+ KnockOffRider(WEAPONTYPE_DROWNING, 0, pDriver, false);
+ }
+ }
+ for(i = 0; i < m_nNumMaxPassengers; i++)
+ if(pPassengers[i]){
+ pPassengers[i]->bIsInWater = true;
+ if(pPassengers[i]->IsPlayer() || !bWaterTight){
+ if(m_aSuspensionSpringRatio[0] < 1.0f ||
+ m_aSuspensionSpringRatio[1] < 1.0f ||
+ m_aSuspensionSpringRatio[2] < 1.0f ||
+ m_aSuspensionSpringRatio[3] < 1.0f)
+ pPassengers[i]->InflictDamage(nil, WEAPONTYPE_DROWNING, CTimer::GetTimeStep(), PEDPIECE_TORSO, 0);
+ else
+ KnockOffRider(WEAPONTYPE_DROWNING, 0, pPassengers[i], false);
+ }
+ }
+ }else{
+ bIsInWater = false;
+ bIsDrowning = false;
+ }
+ }else{
+ bIsInWater = false;
+ bIsDrowning = false;
+ bTouchingWater = false;
+ }
+}
+
+void
+CBike::DoDriveByShootings(void)
+{
+ CAnimBlendAssociation *anim;
+ CPlayerInfo* playerInfo = ((CPlayerPed*)pDriver)->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 ||
+ TheCamera.m_bObbeCinematicCarCamOn){
+ 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 || CPad::GetPad(0)->GetCarGunFired()){
+ if(lookingLeft){
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_BIKE_DRIVEBY_RHS);
+ if(anim)
+ anim->blendDelta = -1000.0f;
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_BIKE_DRIVEBY_FORWARD);
+ if(anim)
+ anim->blendDelta = -1000.0f;
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_BIKE_DRIVEBY_LHS);
+ if(anim == nil || anim->blendDelta < 0.0f)
+ anim = CAnimManager::AddAnimation(pDriver->GetClump(), m_bikeAnimType, ANIM_BIKE_DRIVEBY_LHS);
+ }else if(lookingRight){
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_BIKE_DRIVEBY_LHS);
+ if(anim)
+ anim->blendDelta = -1000.0f;
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_BIKE_DRIVEBY_FORWARD);
+ if(anim)
+ anim->blendDelta = -1000.0f;
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_BIKE_DRIVEBY_RHS);
+ if(anim == nil || anim->blendDelta < 0.0f)
+ anim = CAnimManager::AddAnimation(pDriver->GetClump(), m_bikeAnimType, ANIM_BIKE_DRIVEBY_RHS);
+ }else{
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_BIKE_DRIVEBY_RHS);
+ if(anim)
+ anim->blendDelta = -1000.0f;
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_BIKE_DRIVEBY_LHS);
+ if(anim)
+ anim->blendDelta = -1000.0f;
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_BIKE_DRIVEBY_FORWARD);
+ if(anim == nil || anim->blendDelta < 0.0f)
+ anim = CAnimManager::AddAnimation(pDriver->GetClump(), m_bikeAnimType, ANIM_BIKE_DRIVEBY_FORWARD);
+ }
+
+ if (!anim || !anim->IsRunning()) {
+ if (CPad::GetPad(0)->GetCarGunFired() && CTimer::GetTimeInMilliseconds() > weapon->m_nTimer) {
+ weapon->FireFromCar(this, lookingLeft, lookingRight);
+ weapon->m_nTimer = CTimer::GetTimeInMilliseconds() + 70;
+ }
+ }
+ }else{
+ weapon->Reload();
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_BIKE_DRIVEBY_LHS);
+ if(anim)
+ anim->blendDelta = -1000.0f;
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_BIKE_DRIVEBY_RHS);
+ if(anim)
+ anim->blendDelta = -1000.0f;
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_BIKE_DRIVEBY_FORWARD);
+ if(anim)
+ anim->blendDelta = -1000.0f;
+ }
+}
+
+void
+CBike::VehicleDamage(void)
+{
+ float impulse = m_fDamageImpulse;
+ float colSpeed = 800.0f*impulse/m_fMass;
+ if(GetStatus() == STATUS_PLAYER)
+ colSpeed *= 0.65f;
+ else if(VehicleCreatedBy == MISSION_VEHICLE)
+ colSpeed *= 0.4f;
+
+ if(!bCanBeDamaged)
+ return;
+
+ if(GetStatus() == STATUS_PLAYER && CStats::GetPercentageProgress() >= 100.0f)
+ impulse *= 0.5f;
+
+ if(bIsStanding && impulse > 20.0f)
+ bIsStanding = false;
+
+ // Inflict damage on the driver and passenger
+ if(pDriver && pDriver->GetPedState() == PED_DRIVING && colSpeed > 10.0f){
+ float fwd = 0.6f;
+ if(Abs(DotProduct(m_vecDamageNormal, GetForward())) > 0.85f){
+ float u = Max(DotProduct(m_vecDamageNormal, CVector(0.0f, 0.0f, 1.0f)), 0.0f);
+ if(u < 0.85f)
+ u = 0.0f;
+ fwd += 7.0f * SQR(u);
+ }
+ float up = 0.05f;
+
+ if(GetModelIndex() == MI_SANCHEZ){
+ fwd *= 0.65f;
+ up *= 0.75f;
+ }
+
+ float total = fwd*Abs(DotProduct(m_vecDamageNormal, GetForward())) +
+ 0.45f*Abs(DotProduct(m_vecDamageNormal, GetRight())) +
+ up*Max(DotProduct(m_vecDamageNormal, GetUp()), 0.0f);
+ float damage = (total - 1.5f*Min(DotProduct(m_vecDamageNormal, GetUp()), 0.0f))*colSpeed;
+
+ if(pDriver->IsPlayer() && CCullZones::CamStairsForPlayer() && CCullZones::FindZoneWithStairsAttributeForPlayer())
+ damage = 0.0f;
+
+ if(damage > 75.0f){
+ int dir = -10;
+ if(pDriver){
+ dir = pDriver->GetLocalDirection(-m_vecDamageNormal);
+ if(pDriver->m_fHealth > 0.0f)
+ pDriver->InflictDamage(m_pDamageEntity, WEAPONTYPE_RAMMEDBYCAR, 0.05f*damage, PEDPIECE_TORSO, dir);
+ if(pDriver && pDriver->GetPedState() == PED_DRIVING)
+ KnockOffRider(WEAPONTYPE_RAMMEDBYCAR, dir, pDriver, false);
+ }
+ if(pPassengers[0]){
+ dir = pPassengers[0]->GetLocalDirection(-m_vecDamageNormal);
+ if(pPassengers[0]->m_fHealth > 0.0f)
+ pPassengers[0]->InflictDamage(m_pDamageEntity, WEAPONTYPE_RAMMEDBYCAR, 0.05f*damage, PEDPIECE_TORSO, dir);
+ if(pPassengers[0] && pPassengers[0]->GetPedState() == PED_DRIVING)
+ KnockOffRider(WEAPONTYPE_RAMMEDBYCAR, dir, pPassengers[0], false);
+ }
+ }
+ }
+
+ if(impulse > 25.0f && GetStatus() != STATUS_WRECKED){
+ float damage = (impulse-25.0f)*pHandling->fCollisionDamageMultiplier;
+ if(damage > 0.0f){
+ if(damage > 5.0f &&
+ pDriver &&
+ m_pDamageEntity && m_pDamageEntity->IsVehicle() &&
+ (this != FindPlayerVehicle() || ((CVehicle*)m_pDamageEntity)->VehicleCreatedBy == MISSION_VEHICLE) &&
+ ((CVehicle*)m_pDamageEntity)->pDriver)
+ pDriver->Say(SOUND_PED_CRASH_VEHICLE);
+
+ int oldHealth = m_fHealth;
+ if(this == FindPlayerVehicle())
+ m_fHealth -= bTakeLessDamage ? damage/6.0f : damage/2.0f;
+ else if(bTakeLessDamage)
+ m_fHealth -= damage/12.0f;
+ else if(m_pDamageEntity && m_pDamageEntity == FindPlayerVehicle())
+ m_fHealth -= damage/1.5f;
+ else
+ m_fHealth -= damage/4.0f;
+ if(m_fHealth <= 0.0f && oldHealth > 0)
+ m_fHealth = 1.0f;
+ }
+ }
+
+ if(m_fHealth < 250.0f){
+ // Car is on fire
+ if(!bIsOnFire){
+ // Set engine on fire and remember who did this
+ bIsOnFire = true;
+ m_fFireBlowUpTimer = 0.0f;
+ m_pSetOnFireEntity = m_pDamageEntity;
+ if(m_pSetOnFireEntity)
+ m_pSetOnFireEntity->RegisterReference(&m_pSetOnFireEntity);
+ }
+ }
+}
+
+void
+CBike::AddDamagedVehicleParticles(void)
+{
+ if(this == FindPlayerVehicle() && TheCamera.GetLookingForwardFirstPerson())
+ return;
+ if(this != FindPlayerVehicle() && (CTimer::GetFrameCounter() + m_randomSeed) & 1)
+ return;
+ if(m_fHealth >= 650.0f)
+ return;
+
+ CVector direction = 0.5f*m_vecMoveSpeed;
+ CVector damagePos = ((CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex()))->GetFrontSeatPosn();
+
+ damagePos.z -= 0.4f;
+ damagePos = GetMatrix()*damagePos;
+
+ CalculateLeanMatrix();
+
+ if(m_fHealth < 250.0f){
+ // fire, done in processControl
+ }else if(m_fHealth < 320.0f){
+ direction *= 0.2f;
+ CParticle::AddParticle(PARTICLE_ENGINE_SMOKE2, damagePos, direction + 0.02f*m_leanMatrix.GetRight());
+ }else if(m_fHealth < 390.0f){
+ if(((CTimer::GetFrameCounter() + m_randomSeed) & 3) == 0 ||
+ ((CTimer::GetFrameCounter() + m_randomSeed) & 3) == 2)
+ CParticle::AddParticle(PARTICLE_ENGINE_STEAM, damagePos, direction + 0.05f*m_leanMatrix.GetRight());
+ direction *= 0.3f;
+ CParticle::AddParticle(PARTICLE_ENGINE_SMOKE, damagePos, direction + 0.04f*m_leanMatrix.GetRight());
+ }else if(m_fHealth < 460.0f){
+ int rnd = CTimer::GetFrameCounter() + m_randomSeed;
+ if(rnd < 10 ||
+ rnd < 70 && rnd > 25 ||
+ rnd < 160 && rnd > 100 ||
+ rnd < 200 && rnd > 175 ||
+ rnd > 235)
+ return;
+ direction.z += 0.05f;
+ if(TheCamera.GetLookDirection() != LOOKING_FORWARD){
+ CParticle::AddParticle(PARTICLE_ENGINE_STEAM, damagePos, direction + 0.08f*m_leanMatrix.GetRight(), nil, 0.1f, 0, 0, 0, 1000);
+ }else if(((CTimer::GetFrameCounter() + m_randomSeed) & 1) == 0){
+ direction = 0.8f*m_vecMoveSpeed;
+ CParticle::AddParticle(PARTICLE_ENGINE_STEAM, damagePos, direction + 0.07f*m_leanMatrix.GetRight(), nil, 0.1f, 0, 0, 0, 1000);
+ }
+ }else if(((CTimer::GetFrameCounter() + m_randomSeed) & 3) == 0 ||
+ ((CTimer::GetFrameCounter() + m_randomSeed) & 3) == 2){
+ CParticle::AddParticle(PARTICLE_ENGINE_STEAM, damagePos + 0.06f*m_leanMatrix.GetRight(), direction);
+ }
+}
+
+int32
+CBike::AddWheelDirtAndWater(CColPoint *colpoint, uint32 belowEffectSpeed)
+{
+ int i;
+ CVector dir;
+ static float minSize = 0.02f;
+ static float maxSize = 0.04f;
+ static RwRGBA grassCol = { 8, 24, 8, 255 };
+ static RwRGBA gravelCol = { 64, 64, 64, 255 };
+ static RwRGBA mudCol = { 64, 32, 16, 255 };
+ static RwRGBA sandCol = { 170, 165, 140, 255 };
+ static RwRGBA waterCol = { 48, 48, 64, 0 };
+
+ if(!belowEffectSpeed &&
+ colpoint->surfaceB != SURFACE_SAND && colpoint->surfaceB != SURFACE_SAND_BEACH)
+ return 0;
+
+ switch(colpoint->surfaceB){
+ case SURFACE_GRASS:
+ dir.x = -0.05f*m_vecMoveSpeed.x;
+ dir.y = -0.05f*m_vecMoveSpeed.y;
+ for(i = 0; i < 4; i++){
+ dir.z = CGeneral::GetRandomNumberInRange(0.03f, 0.04f);
+ CParticle::AddParticle(PARTICLE_WHEEL_DIRT, colpoint->point, dir, nil,
+ CGeneral::GetRandomNumberInRange(minSize, maxSize), grassCol);
+ }
+ return 0;
+ case SURFACE_GRAVEL:
+ dir.x = -0.05f*m_vecMoveSpeed.x;
+ dir.y = -0.05f*m_vecMoveSpeed.y;
+ for(i = 0; i < 4; i++){
+ dir.z = CGeneral::GetRandomNumberInRange(0.03f, 0.04f);
+ CParticle::AddParticle(PARTICLE_WHEEL_DIRT, colpoint->point, dir, nil,
+ CGeneral::GetRandomNumberInRange(minSize, maxSize), gravelCol);
+ }
+ return 1;
+ case SURFACE_MUD_DRY:
+ dir.x = -0.05f*m_vecMoveSpeed.x;
+ dir.y = -0.05f*m_vecMoveSpeed.y;
+ for(i = 0; i < 4; i++){
+ dir.z = CGeneral::GetRandomNumberInRange(0.03f, 0.04f);
+ CParticle::AddParticle(PARTICLE_WHEEL_DIRT, colpoint->point, dir, nil,
+ CGeneral::GetRandomNumberInRange(minSize, maxSize), mudCol);
+ }
+ return 0;
+ case SURFACE_SAND:
+ case SURFACE_SAND_BEACH:
+ if(CTimer::GetFrameCounter() & 2)
+ return 0;
+ dir.x = 0.75f*m_vecMoveSpeed.x;
+ dir.y = 0.75f*m_vecMoveSpeed.y;
+ for(i = 0; i < 1; i++){
+ dir.z = CGeneral::GetRandomNumberInRange(0.02f, 0.055f);
+ CParticle::AddParticle(PARTICLE_SAND, colpoint->point, dir, nil,
+ 0.8f*m_vecMoveSpeed.Magnitude(), sandCol);
+ }
+ return 0;
+ default:
+ if(CWeather::WetRoads > 0.01f){
+ CParticle::AddParticle(
+ PARTICLE_WATERSPRAY,
+ colpoint->point + CVector(0.0f, 0.0f, 0.25f+0.25f),
+ CVector(0.0f, 0.0f, CGeneral::GetRandomNumberInRange(0.005f, 0.04f)),
+ nil,
+ CGeneral::GetRandomNumberInRange(0.1f, 0.5f), waterCol);
+ return 0;
+ }
+ return 1;
+ }
+
+ return 0;
+}
+
+void
+CBike::GetComponentWorldPosition(int32 component, CVector &pos)
+{
+ if(m_aBikeNodes[component] == nil){
+ printf("BikeNode missing: %d %d\n", GetModelIndex(), component);
+ return;
+ }
+ RwMatrix *ltm = RwFrameGetLTM(m_aBikeNodes[component]);
+ pos = *RwMatrixGetPos(ltm);
+}
+
+bool
+CBike::IsComponentPresent(int32 component)
+{
+ return m_aBikeNodes[component] != nil;
+}
+
+void
+CBike::SetComponentRotation(int32 component, CVector rotation)
+{
+ CMatrix mat(RwFrameGetMatrix(m_aBikeNodes[component]));
+ CVector pos = mat.GetPosition();
+ // BUG: all these set the whole matrix
+ mat.SetRotateX(DEGTORAD(rotation.x));
+ mat.SetRotateY(DEGTORAD(rotation.y));
+ mat.SetRotateZ(DEGTORAD(rotation.z));
+ mat.Translate(pos);
+ mat.UpdateRW();
+}
+
+bool
+CBike::IsDoorReady(eDoors door)
+{
+ return true;
+}
+
+bool
+CBike::IsDoorFullyOpen(eDoors door)
+{
+ return false;
+}
+
+bool
+CBike::IsDoorClosed(eDoors door)
+{
+ return false;
+}
+
+bool
+CBike::IsDoorMissing(eDoors door)
+{
+ return true;
+}
+
+void
+CBike::RemoveRefsToVehicle(CEntity *ent)
+{
+ int i;
+ for(i = 0; i < 4; i++)
+ if(m_aGroundPhysical[i] == ent)
+ m_aGroundPhysical[i] = nil;
+}
+
+void
+CBike::BlowUpCar(CEntity *culprit)
+{
+ if(!bCanBeDamaged)
+ return;
+
+#ifdef FIX_BUGS
+ // taken from CAutomobile. maybe tweak values?
+ if(culprit == FindPlayerPed() || culprit == FindPlayerVehicle()){
+ CWorld::Players[CWorld::PlayerInFocus].m_nHavocLevel += 20;
+ CWorld::Players[CWorld::PlayerInFocus].m_fMediaAttention += 10.0f;
+ CStats::PropertyDestroyed += CGeneral::GetRandomNumber()%6000 + 4000;
+ }
+#endif
+
+ // explosion pushes vehicle up
+ m_vecMoveSpeed.z += 0.13f;
+ SetStatus(STATUS_WRECKED);
+ bRenderScorched = true;
+
+ m_fHealth = 0.0f;
+ m_nBombTimer = 0;
+
+ TheCamera.CamShake(0.7f, GetPosition().x, GetPosition().y, GetPosition().z);
+
+ KillPedsInVehicle();
+
+ bEngineOn = false;
+ bLightsOn = false;
+ ChangeLawEnforcerState(false);
+
+ CExplosion::AddExplosion(this, culprit, EXPLOSION_CAR, GetPosition(), 0);
+ CDarkel::RegisterCarBlownUpByPlayer(this);
+}
+
+bool
+CBike::SetUpWheelColModel(CColModel *colModel)
+{
+ RwMatrix *mat = RwMatrixCreate();
+ CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex());
+ CColModel *vehColModel = mi->GetColModel();
+
+ colModel->boundingSphere = vehColModel->boundingSphere;
+ colModel->boundingBox = vehColModel->boundingBox;
+
+ GetRelativeMatrix(mat, m_aBikeNodes[BIKE_WHEEL_FRONT], m_aBikeNodes[BIKE_CHASSIS]);
+ colModel->spheres[0].Set(0.5f*mi->m_wheelScale, *RwMatrixGetPos(mat), SURFACE_RUBBER, CAR_PIECE_WHEEL_LF);
+ GetRelativeMatrix(mat, m_aBikeNodes[BIKE_WHEEL_REAR], m_aBikeNodes[BIKE_CHASSIS]);
+ colModel->spheres[1].Set(0.5f*mi->m_wheelScale, *RwMatrixGetPos(mat), SURFACE_RUBBER, CAR_PIECE_WHEEL_LR);
+ colModel->numSpheres = 2;
+#ifdef FIX_BUGS
+ RwMatrixDestroy(mat);
+#endif
+ return true;
+}
+
+float fBikeBurstForceMult = 0.02f;
+float fBikeBurstFallSpeed = 0.3f;
+float fBikeBurstFallSpeedPlayer = 0.55f;
+
+void
+CBike::BurstTyre(uint8 wheel, bool applyForces)
+{
+ if(bTyresDontBurst)
+ return;
+
+ switch(wheel){
+ case CAR_PIECE_WHEEL_LF: wheel = BIKEWHEEL_FRONT; break;
+ case CAR_PIECE_WHEEL_LR: wheel = BIKEWHEEL_REAR; break;
+ }
+
+ if(m_wheelStatus[wheel] == WHEEL_STATUS_OK){
+ m_wheelStatus[wheel] = WHEEL_STATUS_BURST;
+#ifdef FIX_BUGS
+ CStats::TyresPopped++;
+#endif
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_TYRE_POP, 0.0f);
+
+ if(GetStatus() == STATUS_SIMPLE){
+ SetStatus(STATUS_PHYSICS);
+ CCarCtrl::SwitchVehicleToRealPhysics(this);
+ }
+
+ if(applyForces){
+ ApplyMoveForce(GetRight() * m_fMass * CGeneral::GetRandomNumberInRange(-0.02f, 0.02f));
+ ApplyTurnForce(GetRight() * m_fTurnMass * CGeneral::GetRandomNumberInRange(-0.02f, 0.02f), GetForward());
+ }
+
+ // This code checks piece types originally so it is never triggered
+ // as we have converted them to wheel indices above already.
+ if(pDriver){
+#ifdef FIX_SIGNIFICANT_BUGS
+ if(wheel == BIKEWHEEL_FRONT && (m_aSuspensionSpringRatioPrev[BIKESUSP_F1] < 1.0f || m_aSuspensionSpringRatioPrev[BIKESUSP_F2] < 1.0f) ||
+ wheel == BIKEWHEEL_REAR && (m_aSuspensionSpringRatioPrev[BIKESUSP_R1] < 1.0f || m_aSuspensionSpringRatioPrev[BIKESUSP_R2] < 1.0f)){
+#else
+ if(wheel == CAR_PIECE_WHEEL_LF && (m_aSuspensionSpringRatioPrev[BIKESUSP_F1] < 1.0f || m_aSuspensionSpringRatioPrev[BIKESUSP_F2] < 1.0f) ||
+ wheel == CAR_PIECE_WHEEL_LR && (m_aSuspensionSpringRatioPrev[BIKESUSP_R1] < 1.0f || m_aSuspensionSpringRatioPrev[BIKESUSP_R2] < 1.0f)){
+#endif
+ float speedSq = m_vecMoveSpeed.MagnitudeSqr();
+ if(speedSq > fBikeBurstFallSpeed &&
+ (GetStatus() != STATUS_PLAYER || speedSq > fBikeBurstFallSpeedPlayer)){
+#ifdef FIX_SIGNIFICANT_BUGS
+ if(wheel == BIKEWHEEL_FRONT){
+#else
+ if(wheel == CAR_PIECE_WHEEL_LF){
+#endif
+ KnockOffRider(WEAPONTYPE_RAMMEDBYCAR, 0, pDriver, false);
+ if(pPassengers[0])
+ KnockOffRider(WEAPONTYPE_RAMMEDBYCAR, 0, pPassengers[0], false);
+ }else
+ ApplyTurnForce(2.0f*fBikeBurstForceMult*m_fTurnMass*GetRight(), GetForward());
+ }
+ }
+ }
+ }
+}
+
+bool
+CBike::IsRoomForPedToLeaveCar(uint32 component, CVector *doorOffset)
+{
+ CColPoint colpoint;
+ CEntity *ent;
+ colpoint.point = CVector(0.0f, 0.0f, 0.0f);
+ CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex());
+
+ CVector seatPos = mi->GetFrontSeatPosn();
+ if(component == CAR_DOOR_RR || component == CAR_DOOR_LR)
+ seatPos = mi->m_positions[CAR_POS_BACKSEAT];
+ if(component == CAR_DOOR_LF || component == CAR_DOOR_LR)
+ seatPos.x = -seatPos.x;
+ seatPos = GetMatrix() * seatPos;
+
+ CVector doorPos = CPed::GetPositionToOpenCarDoor(this, component);
+ if(doorOffset){
+ CVector off = *doorOffset;
+ if(component == CAR_DOOR_RF || component == CAR_DOOR_RR)
+ off.x = -off.x;
+ doorPos += Multiply3x3(GetMatrix(), off);
+ }
+
+ if(GetUp().z < 0.0f){
+ seatPos.z += 0.5f;
+ doorPos.z += 0.5f;
+ }
+
+ CVector dist = doorPos - seatPos;
+
+ // Removing that makes thiProcessEntityCollisions func. return false for van doors.
+ doorPos.z += 0.5f;
+ float length = dist.Magnitude();
+ CVector pedPos = seatPos + dist*((length+0.6f)/length);
+
+ if(!CWorld::GetIsLineOfSightClear(seatPos, pedPos, true, false, false, true, false, false))
+ return false;
+ if(CWorld::TestSphereAgainstWorld(doorPos, 0.6f, this, true, true, false, true, false, false))
+ return false;
+ if(CWorld::ProcessVerticalLine(doorPos, 1000.0f, colpoint, ent, true, false, false, true, false, false, nil))
+ if(colpoint.point.z > doorPos.z && colpoint.point.z < doorPos.z + 0.6f)
+ return false;
+ float upperZ = colpoint.point.z;
+ if(!CWorld::ProcessVerticalLine(doorPos, -1000.0f, colpoint, ent, true, false, false, true, false, false, nil))
+ return false;
+ if(upperZ != 0.0f && upperZ < colpoint.point.z)
+ return false;
+ return true;
+}
+
+float
+CBike::GetHeightAboveRoad(void)
+{
+ return m_fHeightAboveRoad;
+}
+
+void
+CBike::PlayCarHorn(void)
+{
+ uint32 r;
+
+ if (IsAlarmOn() || m_nCarHornTimer != 0)
+ return;
+
+ 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){
+ if(pDriver)
+ pDriver->Say(SOUND_PED_ANNOYED_DRIVER);
+ m_nCarHornTimer = 45;
+ }else{
+ if(pDriver)
+ pDriver->Say(SOUND_PED_ANNOYED_DRIVER);
+ }
+}
+
+void
+CBike::KnockOffRider(eWeaponType weapon, uint8 direction, CPed *ped, bool bGetBackOn)
+{
+ AnimationId anim = ANIM_STD_KO_FRONT;
+ if(ped == nil)
+ return;
+
+ if(!ped->IsPlayer()){
+ if(bGetBackOn){
+ if(ped->m_pedStats->m_temper > ped->m_pedStats->m_fear &&
+ ped->CharCreatedBy != MISSION_CHAR && ped->m_pMyVehicle->VehicleCreatedBy != MISSION_VEHICLE &&
+ FindPlayerPed()->m_carInObjective == ped->m_pMyVehicle &&
+ !CTheScripts::IsPlayerOnAMission())
+ ped->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, ped->m_pMyVehicle);
+ else if(ped->m_pedStats->m_temper > ped->m_pedStats->m_fear &&
+ ped->CharCreatedBy != MISSION_CHAR && ped->m_pMyVehicle->VehicleCreatedBy != MISSION_VEHICLE &&
+ !CTheScripts::IsPlayerOnAMission())
+ ped->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, ped->m_pMyVehicle);
+ else if(ped->m_pedStats->m_temper <= ped->m_pedStats->m_fear &&
+ ped->CharCreatedBy != MISSION_CHAR && ped->m_pMyVehicle->VehicleCreatedBy != MISSION_VEHICLE &&
+ !CTheScripts::IsPlayerOnAMission()){
+ ped->SetObjective(OBJECTIVE_WANDER, ped->m_pMyVehicle);
+ ped->m_nPathDir = CGeneral::GetRandomNumberInRange(0, 8);
+ }
+ }else if(ped->m_leader == nil){
+ if(pDriver == ped)
+ ped->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, this);
+ else
+ ped->SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, this);
+ }
+ }
+
+ if(ped->IsPed()){
+ CAnimBlendAssociation *assoc;
+ for(assoc = RpAnimBlendClumpGetFirstAssociation(ped->GetClump(), ASSOC_DRIVING);
+ assoc;
+ assoc = RpAnimBlendGetNextAssociation(assoc))
+ assoc->flags |= ASSOC_DELETEFADEDOUT;
+ }
+
+ ped->SetPedState(PED_IDLE);
+ CAnimManager::BlendAnimation(ped->GetClump(), ped->m_animGroup, ANIM_STD_IDLE, 100.0f);
+ ped->m_vehDoor = CAR_DOOR_LF;
+ CPed::PedSetOutCarCB(nil, ped);
+ ped->SetMoveState(PEDMOVE_STILL);
+ if(GetUp().z < 0.0f)
+ ped->SetHeading(CGeneral::LimitRadianAngle(GetForward().Heading() + PI));
+ else
+ ped->SetHeading(GetForward().Heading());
+
+ switch(weapon){
+ case WEAPONTYPE_UNARMED:
+ case WEAPONTYPE_UNIDENTIFIED:
+ ped->m_vecMoveSpeed = m_vecMoveSpeed;
+ ped->m_pCollidingEntity = this;
+ anim = ANIM_STD_NUM;
+ break;
+
+ case WEAPONTYPE_BASEBALLBAT:
+ default:
+ switch(direction){
+ case 0:
+ anim = ANIM_STD_BIKE_FALLBACK;
+ ped->m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.1f);
+ if(m_vecMoveSpeed.MagnitudeSqr() < SQR(0.3f))
+ ped->ApplyMoveForce(5.0f*GetUp() - 6.0f*GetForward());
+ ped->m_pCollidingEntity = this;
+ break;
+ case 1:
+ case 2:
+ if(m_vecMoveSpeed.MagnitudeSqr() > SQR(0.3f)){
+ anim = ANIM_STD_HIGHIMPACT_LEFT;
+ ped->m_vecMoveSpeed = 0.3f*m_vecMoveSpeed;
+ ped->ApplyMoveForce(5.0f*GetUp() + 6.0f*GetRight());
+ }else{
+ anim = ANIM_STD_SPINFORWARD_LEFT;
+ ped->m_vecMoveSpeed = m_vecMoveSpeed;
+ ped->ApplyMoveForce(4.0f*GetUp() + 8.0f*GetRight());
+ }
+ // BUG or is it intentionally missing?
+ //ped->m_pCollidingEntity = this;
+ break;
+ case 3:
+ if(m_vecMoveSpeed.MagnitudeSqr() > SQR(0.3f)){
+ anim = ANIM_STD_HIGHIMPACT_RIGHT;
+ ped->m_vecMoveSpeed = 0.3f*m_vecMoveSpeed;
+ ped->ApplyMoveForce(5.0f*GetUp() - 6.0f*GetRight());
+ }else{
+ anim = ANIM_STD_SPINFORWARD_RIGHT;
+ ped->m_vecMoveSpeed = m_vecMoveSpeed;
+ ped->ApplyMoveForce(4.0f*GetUp() - 8.0f*GetRight());
+ }
+ // BUG or is it intentionally missing?
+ //ped->m_pCollidingEntity = this;
+ break;
+ }
+ break;
+
+ case WEAPONTYPE_DROWNING:{
+ RwRGBA color;
+ anim = ANIM_STD_FALL;
+ ped->m_vecMoveSpeed = m_vecMoveSpeed*0.2f;
+ ped->m_vecMoveSpeed.z = 0.0f;
+ ped->m_pCollidingEntity = this;
+ color.red = (0.5f * CTimeCycle::GetDirectionalRed() + CTimeCycle::GetAmbientRed_Obj())*0.45f*255;
+ color.green = (0.5f * CTimeCycle::GetDirectionalGreen() + CTimeCycle::GetAmbientGreen_Obj())*0.45f*255;
+ color.blue = (0.5f * CTimeCycle::GetDirectionalBlue() + CTimeCycle::GetAmbientBlue_Obj())*0.45f*255;
+ color.alpha = CGeneral::GetRandomNumberInRange(48, 96);
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_SPLASH, 0.0f);
+ CVector splashPos = ped->GetPosition() + 2.2f*ped->m_vecMoveSpeed;
+ float waterZ = 0.0f;
+ if(CWaterLevel::GetWaterLevel(splashPos, &waterZ, false))
+ splashPos.z = waterZ;
+ CParticleObject::AddObject(POBJECT_PED_WATER_SPLASH, splashPos, CVector(0.0f, 0.0f, 0.1f),
+ 0.0f, 200, color, true);
+ break;
+ }
+
+ case WEAPONTYPE_FALL: {
+ ped->m_vecMoveSpeed = ped->m_pMyVehicle->m_vecMoveSpeed;
+ float forceXY = -0.6*m_fDamageImpulse * ped->m_fMass / m_fMass;
+ ped->ApplyMoveForce(m_vecDamageNormal.x*forceXY, m_vecDamageNormal.y*forceXY,
+ CGeneral::GetRandomNumberInRange(3.0f, 7.0f));
+ ped->m_pCollidingEntity = this;
+ switch(direction){
+ case 0: anim = ANIM_STD_HIGHIMPACT_BACK; break;
+ case 1: anim = ANIM_STD_SPINFORWARD_RIGHT; break;
+ case 2: anim = ANIM_STD_BIKE_FALLBACK; break;
+ case 3: anim = ANIM_STD_SPINFORWARD_LEFT; break;
+ }
+ if(m_nWheelsOnGround == 0)
+ ped->bKnockedOffBike = true;
+ break;
+ }
+
+ case WEAPONTYPE_RAMMEDBYCAR: {
+ ped->m_vecMoveSpeed = ped->m_pMyVehicle->m_vecMoveSpeed;
+ static float minForceZ = 8.0f;
+ static float maxForceZ = 15.0f;
+ float forceXY = -0.6*m_fDamageImpulse * ped->m_fMass / m_fMass;
+ ped->ApplyMoveForce(m_vecDamageNormal.x*forceXY, m_vecDamageNormal.y*forceXY,
+ CGeneral::GetRandomNumberInRange(minForceZ, maxForceZ));
+ ped->m_pCollidingEntity = this;
+ switch(direction){
+ case 0: anim = ANIM_STD_HIGHIMPACT_BACK; break;
+ case 1: anim = ANIM_STD_SPINFORWARD_RIGHT; break;
+ case 2: anim = ANIM_STD_HIGHIMPACT_FRONT; break;
+ case 3: anim = ANIM_STD_SPINFORWARD_LEFT; break;
+ }
+ ped->bKnockedOffBike = true;
+ if(ped->IsPlayer())
+ ped->Say(SOUND_PED_DAMAGE);
+ break;
+ }
+ }
+
+ if(weapon == WEAPONTYPE_DROWNING){
+ ped->bIsStanding = false;
+ ped->bWasStanding = false;
+ ped->bIsInTheAir = true;
+ ped->bIsInWater = true;
+ ped->bTouchingWater = true;
+ CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_STD_FALL, 4.0f);
+ }else if(weapon != WEAPONTYPE_UNARMED){
+ if(ped->m_fHealth > 0.0f)
+ ped->SetFall(1000, anim, 0);
+ else
+ ped->SetDie(anim);
+ ped->bIsStanding = false;
+ }
+
+ CEntity *ent = CWorld::TestSphereAgainstWorld(ped->GetPosition()+CVector(0.0f, 0.0, 0.5f), 0.4f, nil, true, false, false, false, false, false);
+ if(ent == nil)
+ ent = CWorld::TestSphereAgainstWorld(ped->GetPosition()+CVector(0.0f, 0.0, 0.8f), 0.4f, nil, true, false, false, false, false, false);
+ if(ent == nil)
+ ent = CWorld::TestSphereAgainstWorld(ped->GetPosition()+CTimer::GetTimeStep()*ped->m_vecMoveSpeed+CVector(0.0f, 0.0, 0.5f), 0.4f, nil, true, false, false, false, false, false);
+ if(ent == nil)
+ ent = CWorld::TestSphereAgainstWorld(ped->GetPosition()+CTimer::GetTimeStep()*ped->m_vecMoveSpeed+CVector(0.0f, 0.0, 0.8f), 0.4f, nil, true, false, false, false, false, false);
+ if(ent){
+ CColPoint point;
+ ent = nil;
+ if(CWorld::ProcessVerticalLine(ped->GetPosition(), ped->GetPosition().z-2.0f, point, ent, true, false, false, false, false, false, nil)){
+ if(ped->m_pMyVehicle == nil){
+ ped->m_pMyVehicle = this;
+ ped->PositionPedOutOfCollision();
+ ped->m_pMyVehicle = nil;
+ }else
+ ped->PositionPedOutOfCollision();
+ }else
+ ped->GetMatrix().Translate(CVector(0.0f, 0.0f, -2.0f));
+ ped->m_pCollidingEntity = ped->m_pMyVehicle;
+ ped->bKnockedOffBike = true;
+ ped->bHeadStuckInCollision = true;
+ }else if(weapon == WEAPONTYPE_RAMMEDBYCAR){
+ if(CWorld::TestSphereAgainstWorld(ped->GetPosition()+CVector(0.0f, 0.0, 1.3f), 0.6f, nil, true, false, false, false, false, false) == nil)
+ ped->GetMatrix().Translate(CVector(0.0f, 0.0f, 0.5f));
+ }
+ ped->m_pMyVehicle = nil;
+}
+
+void
+CBike::PlayHornIfNecessary(void)
+{
+ if(AutoPilot.m_bSlowedDownBecauseOfPeds ||
+ AutoPilot.m_bSlowedDownBecauseOfCars)
+ PlayCarHorn();
+}
+
+void
+CBike::ResetSuspension(void)
+{
+ int i;
+ for(i = 0; i < 2; i++){
+ m_aWheelRotation[i] = 0.0f;
+ m_aWheelState[i] = WHEEL_STATE_NORMAL;
+ }
+ for(i = 0; i < 4; i++){
+ m_aSuspensionSpringRatio[i] = 1.0f;
+ m_aWheelTimer[i] = 0.0f;
+ }
+}
+
+void
+CBike::SetupSuspensionLines(void)
+{
+ int i;
+ CVector posn;
+ float suspOffset = 0.0f;
+ RwFrame *node = nil;
+ CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex());
+ CColModel *colModel = mi->GetColModel();
+ RwMatrix *mat = RwMatrixCreate();
+
+ bool initialized = colModel->lines[0].p0.z != FAKESUSPENSION;
+
+ for(i = 0; i < 4; i++){
+ if(initialized){
+ posn = colModel->lines[i].p0;
+ if(i < 2)
+ posn.z = m_aWheelBasePosition[0];
+ else
+ posn.z = m_aWheelBasePosition[1];
+ }else{
+ switch(i){
+ case BIKESUSP_F1:
+ node = m_aBikeNodes[BIKE_WHEEL_FRONT];
+ suspOffset = 0.25f*mi->m_wheelScale;
+ break;
+ case BIKESUSP_F2:
+ node = m_aBikeNodes[BIKE_WHEEL_FRONT];
+ suspOffset = -0.25f*mi->m_wheelScale;
+ break;
+ case BIKESUSP_R1:
+ node = m_aBikeNodes[BIKE_WHEEL_REAR];
+ suspOffset = 0.25f*mi->m_wheelScale;
+ break;
+ case BIKESUSP_R2:
+ node = m_aBikeNodes[BIKE_WHEEL_REAR];
+ suspOffset = -0.25f*mi->m_wheelScale;
+ break;
+ }
+
+ GetRelativeMatrix(mat, node, node);
+ posn = *RwMatrixGetPos(mat);
+ if(i == BIKESUSP_F1)
+ m_aWheelBasePosition[BIKEWHEEL_FRONT] = posn.z;
+ else if(i == BIKESUSP_R1){
+ m_aWheelBasePosition[BIKEWHEEL_REAR] = posn.z;
+
+ GetRelativeMatrix(mat, m_aBikeNodes[BIKE_FORKS_REAR], m_aBikeNodes[BIKE_FORKS_REAR]);
+ float dz = posn.z - RwMatrixGetPos(mat)->z;
+ float dy = posn.y - RwMatrixGetPos(mat)->y;
+ m_fRearForkLength = Sqrt(SQR(dy) + SQR(dz));
+ assert(m_fRearForkLength != 0.0f); // we want to divide by this
+ }
+ posn.y += suspOffset;
+ }
+
+ // uppermost wheel position
+ posn.z += pHandling->fSuspensionUpperLimit;
+ colModel->lines[i].p0 = posn;
+
+ // lowermost wheel position
+ posn.z += pHandling->fSuspensionLowerLimit - pHandling->fSuspensionUpperLimit;
+ // lowest point on tyre
+ posn.z -= mi->m_wheelScale*0.5f;
+ colModel->lines[i].p1 = posn;
+
+ // this is length of the spring at rest
+ m_aSuspensionSpringLength[i] = pHandling->fSuspensionUpperLimit - pHandling->fSuspensionLowerLimit;
+ m_aSuspensionLineLength[i] = colModel->lines[i].p0.z - colModel->lines[i].p1.z;
+ }
+
+ if(!initialized){
+ GetRelativeMatrix(mat, m_aBikeNodes[BIKE_FORKS_FRONT], m_aBikeNodes[BIKE_FORKS_FRONT]);
+ m_fFrontForkY = RwMatrixGetPos(mat)->y;
+ m_fFrontForkZ = RwMatrixGetPos(mat)->z;
+ }
+
+ // Compress spring somewhat to get normal height on road
+ m_fHeightAboveRoad = m_aSuspensionSpringLength[0]*(1.0f - 1.0f/(4.0f*pHandling->fSuspensionForceLevel))
+ - colModel->lines[0].p0.z + mi->m_wheelScale*0.5f;
+ for(i = 0; i < 2; i++)
+ m_aWheelPosition[i] = mi->m_wheelScale*0.5f - m_fHeightAboveRoad;
+
+ // adjust col model to include suspension lines
+ if(colModel->boundingBox.min.z > colModel->lines[0].p1.z)
+ colModel->boundingBox.min.z = colModel->lines[0].p1.z;
+ float radius = Max(colModel->boundingBox.min.Magnitude(), colModel->boundingBox.max.Magnitude());
+ if(colModel->boundingSphere.radius < radius)
+ colModel->boundingSphere.radius = radius;
+
+#ifdef FIX_BUGS
+ RwMatrixDestroy(mat);
+#endif
+}
+
+void
+CBike::CalculateLeanMatrix(void)
+{
+ if(bLeanMatrixClean)
+ return;
+
+ CMatrix mat;
+ mat.SetRotateX(-0.05f*Abs(m_fLeanLRAngle));
+ mat.RotateY(m_fLeanLRAngle);
+ m_leanMatrix = GetMatrix();
+ m_leanMatrix = m_leanMatrix * mat;
+ // place wheel back on ground
+ m_leanMatrix.GetPosition() += GetUp()*(1.0f-Cos(m_fLeanLRAngle))*GetColModel()->boundingBox.min.z;
+ bLeanMatrixClean = true;
+}
+
+void
+CBike::GetCorrectedWorldDoorPosition(CVector &pos, CVector p1, CVector p2)
+{
+ CVector &fwd = GetForward();
+ CVector rightWorld = CrossProduct(fwd, CVector(0.0f, 0.0f, 1.0f));
+ CVector upWorld = CrossProduct(rightWorld, fwd);
+ CColModel *colModel = GetColModel();
+ float onSide = DotProduct(GetUp(), rightWorld);
+ float diff = Max(colModel->boundingBox.max.z-colModel->boundingBox.max.x, 0.0f);
+ pos = CVector(0.0f, 0.0f, 0.0f);
+ float y = p2.y - p1.y;
+ float x = onSide*diff + p2.x + p1.x;
+ float z = p2.z - p1.z;
+ pos = x*rightWorld + y*fwd + z*upWorld + GetPosition();
+}
+
+void
+CBike::Fix(void)
+{
+ bIsDamaged = false;
+ bIsOnFire = false;
+ m_wheelStatus[0] = WHEEL_STATUS_OK;
+ m_wheelStatus[1] = WHEEL_STATUS_OK;
+}
+
+void
+CBike::SetupModelNodes(void)
+{
+ int i;
+ for(i = 0; i < BIKE_NUM_NODES; i++)
+ m_aBikeNodes[i] = nil;
+ CClumpModelInfo::FillFrameArray(GetClump(), m_aBikeNodes);
+}
+
+void
+CBike::ReduceHornCounter(void)
+{
+ if(m_nCarHornTimer != 0)
+ m_nCarHornTimer--;
+}
+
+#ifdef COMPATIBLE_SAVES
+void
+CBike::Save(uint8*& buf)
+{
+ CVehicle::Save(buf);
+ ZeroSaveBuf(buf, 1260 - 672);
+}
+
+void
+CBike::Load(uint8*& buf)
+{
+ CVehicle::Load(buf);
+ SkipSaveBuf(buf, 1260 - 672);
+}
+#endif
diff --git a/src/vehicles/Bike.h b/src/vehicles/Bike.h
index 85ff211b..219d8872 100644
--- a/src/vehicles/Bike.h
+++ b/src/vehicles/Bike.h
@@ -1,8 +1,8 @@
#pragma once
#include "Vehicle.h"
-
-// some miami bike leftovers
+#include "Skidmarks.h"
+#include "AnimManager.h"
enum eBikeNodes {
BIKE_NODE_NONE,
@@ -16,20 +16,35 @@ enum eBikeNodes {
BIKE_NUM_NODES
};
+enum {
+ BIKEWHEEL_FRONT,
+ BIKEWHEEL_REAR,
+};
+
+enum {
+ BIKESUSP_F1,
+ BIKESUSP_F2,
+ BIKESUSP_R1,
+ BIKESUSP_R2,
+};
+
class CBike : public CVehicle
{
public:
- RwFrame *m_aBikeNodes[BIKE_NUM_NODES]; // assuming
- uint8 unk1[96];
- AnimationId m_bikeSitAnimation;
- uint8 unk2[180];
+ RwFrame *m_aBikeNodes[BIKE_NUM_NODES];
+ bool bLeanMatrixClean;
+ CMatrix m_leanMatrix;
+ CVector m_vecAvgSurfaceNormal;
+ CVector m_vecAvgSurfaceRight;
+ tBikeHandlingData *pBikeHandling;
+ AssocGroupId m_bikeAnimType;
+ uint8 m_wheelStatus[2];
+ CColPoint m_aWheelColPoints[4];
float m_aSuspensionSpringRatio[4];
-
- /* copied from VC, one of the floats here is gone, assuming m_bike_unused1 */
float m_aSuspensionSpringRatioPrev[4];
float m_aWheelTimer[4];
- //float m_bike_unused1;
- int m_aWheelSkidmarkType[2];
+ float m_bike_unused1;
+ eSkidmarkType m_aWheelSkidmarkType[2];
bool m_aWheelSkidmarkBloody[2];
bool m_aWheelSkidmarkUnk[2];
float m_aWheelRotation[2];
@@ -39,7 +54,119 @@ public:
float m_aSuspensionSpringLength[4];
float m_aSuspensionLineLength[4];
float m_fHeightAboveRoad;
- /**/
-
float m_fTraction;
-}; \ No newline at end of file
+ float m_fRearForkLength;
+ float m_fFrontForkY;
+ float m_fFrontForkZ;
+ float m_fFrontForkSlope;
+ float m_fWheelAngle;
+ float m_fLeanLRAngle;
+ float m_fLeanLRAngle2;
+ float m_fLeanInput;
+ float m_fPedLeanAmountLR;
+ float m_fPedLeanAmountUD;
+ uint8 m_bike_unused2;
+ uint8 unused[3]; // looks like padding..but for what?
+ uint8 m_bike_flag01 : 1;
+ uint8 m_bike_flag02 : 1;
+ uint8 bWaterTight : 1;
+ uint8 bIsBeingPickedUp : 1;
+ uint8 bIsStanding : 1;
+ uint8 bExtraSpeed : 1; // leaning forward
+ uint8 bIsOnFire : 1;
+ uint8 bWheelieCam : 1;
+ int16 m_doingBurnout;
+ float m_fTireTemperature;
+ float m_fBrakeDestabilization;
+ float m_fVelocityChangeForAudio;
+ float m_fFireBlowUpTimer;
+ CPhysical *m_aGroundPhysical[4];
+ CVector m_aGroundOffset[4];
+ CEntity *m_pSetOnFireEntity;
+ uint8 m_nWheelsOnGround;
+ uint8 m_nDriveWheelsOnGround;
+ uint8 m_nDriveWheelsOnGroundPrev;
+ float m_fGasPedalAudio;
+ tWheelState m_aWheelState[2];
+
+ CBike(int32 id, uint8 CreatedBy);
+
+ // from CEntity
+ void SetModelIndex(uint32 id);
+ void ProcessControl(void);
+ void Teleport(CVector v);
+ void PreRender(void);
+ void Render(void);
+
+ // from CPhysical
+ int32 ProcessEntityCollision(CEntity *ent, CColPoint *colpoints);
+
+ // from CVehicle
+ void ProcessControlInputs(uint8);
+ void GetComponentWorldPosition(int32 component, CVector &pos);
+ bool IsComponentPresent(int32 component);
+ void SetComponentRotation(int32 component, CVector rotation);
+ bool IsDoorReady(eDoors door);
+ bool IsDoorFullyOpen(eDoors door);
+ bool IsDoorClosed(eDoors door);
+ bool IsDoorMissing(eDoors door);
+ void RemoveRefsToVehicle(CEntity *ent);
+ void BlowUpCar(CEntity *ent);
+ bool SetUpWheelColModel(CColModel *colModel);
+ void BurstTyre(uint8 tyre, bool applyForces);
+ bool IsRoomForPedToLeaveCar(uint32 component, CVector *doorOffset);
+ float GetHeightAboveRoad(void);
+ void PlayCarHorn(void);
+
+ void KnockOffRider(eWeaponType weapon, uint8 direction, CPed *ped, bool bGetBackOn);
+ void VehicleDamage(void);
+ void ProcessBuoyancy(void);
+ void DoDriveByShootings(void);
+ void AddDamagedVehicleParticles(void);
+ int32 AddWheelDirtAndWater(CColPoint *colpoint, uint32 belowEffectSpeed);
+ void PlayHornIfNecessary(void);
+ void ResetSuspension(void);
+ void SetupSuspensionLines(void);
+ void CalculateLeanMatrix(void);
+ void GetCorrectedWorldDoorPosition(CVector &pos, CVector p1, CVector p2);
+
+ void Fix(void);
+ void SetupModelNodes(void);
+ void ReduceHornCounter(void);
+
+#ifdef COMPATIBLE_SAVES
+ virtual void Save(uint8*& buf);
+ virtual void Load(uint8*& buf);
+#endif
+ static const uint32 nSaveStructSize;
+};
+
+// These functions and function names are made up
+
+inline int8 GetBikeDoorFlag(int32 carnode) {
+ switch (carnode) {
+ case CAR_DOOR_RR:
+ case CAR_DOOR_LR:
+ return CAR_DOOR_FLAG_RR | CAR_DOOR_FLAG_LR;
+ case CAR_DOOR_RF:
+ case CAR_DOOR_LF:
+ return CAR_DOOR_FLAG_RF | CAR_DOOR_FLAG_LF;
+ default:
+ return CAR_DOOR_FLAG_UNKNOWN;
+ }
+}
+
+// for m_nGettingOutFlags
+inline int8 GetBikeDoorFlagInclJumpInFromFront(int32 carnode) {
+ switch (carnode) {
+ case CAR_DOOR_RR:
+ case CAR_DOOR_LR:
+ return CAR_DOOR_FLAG_RR | CAR_DOOR_FLAG_LR;
+ case CAR_DOOR_RF:
+ case CAR_DOOR_LF:
+ case CAR_WINDSCREEN:
+ return CAR_DOOR_FLAG_RF | CAR_DOOR_FLAG_LF;
+ default:
+ return CAR_DOOR_FLAG_UNKNOWN;
+ }
+} \ No newline at end of file
diff --git a/src/vehicles/Boat.cpp b/src/vehicles/Boat.cpp
index 65cdd8c6..73957107 100644
--- a/src/vehicles/Boat.cpp
+++ b/src/vehicles/Boat.cpp
@@ -3,7 +3,9 @@
#include "main.h"
#include "General.h"
#include "Timecycle.h"
+#include "Weather.h"
#include "HandlingMgr.h"
+#include "CarAI.h"
#include "CarCtrl.h"
#include "RwHelper.h"
#include "ModelIndices.h"
@@ -13,30 +15,37 @@
#include "Darkel.h"
#include "Explosion.h"
#include "Particle.h"
+#include "ParticleObject.h"
#include "WaterLevel.h"
#include "Floater.h"
#include "World.h"
+#include "Stats.h"
#include "Pools.h"
#include "Pad.h"
#include "Boat.h"
+#include "AnimBlendAssociation.h"
+#include "RpAnimBlend.h"
+#include "Record.h"
+#include "Shadows.h"
+#include "Wanted.h"
#include "SaveBuf.h"
#define INVALID_ORIENTATION (-9999.99f)
-float MAX_WAKE_LENGTH = 50.0f;
-float MIN_WAKE_INTERVAL = 1.0f;
-float WAKE_LIFETIME = 400.0f;
+float CBoat::MAX_WAKE_LENGTH = 50.0f;
+float CBoat::MIN_WAKE_INTERVAL = 2.0f;
+float CBoat::WAKE_LIFETIME = 150.0f;
float fShapeLength = 0.4f;
float fShapeTime = 0.05f;
-float fRangeMult = 0.75f;
-float fTimeMult = 1.0f/WAKE_LIFETIME;
+float fRangeMult = 0.6f;
+float fTimeMult = 1.2f/CBoat::WAKE_LIFETIME;
CBoat *CBoat::apFrameWakeGeneratingBoats[4];
const uint32 CBoat::nSaveStructSize =
#ifdef COMPATIBLE_SAVES
- 1156;
+ 1216;
#else
sizeof(CBoat);
#endif
@@ -50,9 +59,14 @@ CBoat::CBoat(int mi, uint8 owner) : CVehicle(owner)
m_fSteeringLeftRight = 0.0f;
m_nPadID = 0;
m_fMovingRotation = 0.0f;
+ m_fMovingSpeed = 0.0f;
+ m_skimmerThingTimer = 0.0f;
+ m_nPoliceShoutTimer = CTimer::GetTimeInMilliseconds();
SetModelIndex(mi);
pHandling = mod_HandlingManager.GetHandlingData((tVehicleType)minfo->m_handlingId);
+ pFlyingHandling = mod_HandlingManager.GetFlyingPointer((tVehicleType)minfo->m_handlingId);
+ pBoatHandling = mod_HandlingManager.GetBoatPointer((tVehicleType)minfo->m_handlingId);
minfo->ChooseVehicleColour(m_currentColour1, m_currentColour2);
m_fMass = pHandling->fMass;
@@ -65,10 +79,6 @@ CBoat::CBoat(int mi, uint8 owner) : CVehicle(owner)
m_fGasPedal = 0.0f;
m_fBrakePedal = 0.0f;
- m_fThrustZ = 0.25f;
- m_fThrustY = 0.35f;
- m_vecMoveRes = CVector(0.7f, 0.998f, 0.999f);
- m_vecTurnRes = CVector(0.85f, 0.96f, 0.96f);
m_boat_unused3 = false;
m_fVolumeUnderWater = 7.0f;
@@ -81,6 +91,7 @@ CBoat::CBoat(int mi, uint8 owner) : CVehicle(owner)
bIsInWater = true;
+ m_phys_unused1 = 0.0f;
m_boat_unused2 = 0;
m_bIsAnchored = true;
m_fOrientation = INVALID_ORIENTATION;
@@ -93,12 +104,17 @@ CBoat::CBoat(int mi, uint8 owner) : CVehicle(owner)
m_afWakePointLifeTime[i] = 0.0f;
m_nAmmoInClip = 20;
+
+ if(GetModelIndex() == MI_MARQUIS)
+ m_boom.Init(-PI/10.0f, PI/10.0f, 0, 2);
+ else
+ m_boom.Init(-PI/5.0f, PI/5.0f, 0, 2);
}
void
CBoat::SetModelIndex(uint32 id)
{
- CEntity::SetModelIndex(id);
+ CVehicle::SetModelIndex(id);
SetupModelNodes();
}
@@ -111,39 +127,59 @@ CBoat::GetComponentWorldPosition(int32 component, CVector &pos)
void
CBoat::ProcessControl(void)
{
- if(m_nZoneLevel > LEVEL_GENERIC && m_nZoneLevel != CCollision::ms_collisionInMemory)
- return;
-
bool onLand = m_fDamageImpulse > 0.0f && m_vecDamageNormal.z > 0.1f;
PruneWakeTrail();
+ if(bRenderScorched)
+ m_fBuoyancy *= 0.99f;
+
+#ifdef FIX_BUGS
+ if(FindPlayerPed() && FindPlayerPed()->m_pWanted->GetWantedLevel() > 0 && GetModelIndex() == MI_PREDATOR){
+#else
+ if(FindPlayerPed()->m_pWanted->GetWantedLevel() > 0 && GetModelIndex() == MI_PREDATOR){
+#endif
+ CVehicle *playerVeh = FindPlayerVehicle();
+ if(playerVeh && playerVeh->GetVehicleAppearance() == VEHICLE_APPEARANCE_BOAT &&
+ (AutoPilot.m_nCarMission == MISSION_RAMPLAYER_FARAWAY ||
+ AutoPilot.m_nCarMission == MISSION_RAMPLAYER_CLOSE ||
+ AutoPilot.m_nCarMission == MISSION_BLOCKPLAYER_FARAWAY ||
+ AutoPilot.m_nCarMission == MISSION_BLOCKPLAYER_CLOSE ||
+ AutoPilot.m_nCarMission == MISSION_ATTACKPLAYER) &&
+ CTimer::GetTimeInMilliseconds() > m_nPoliceShoutTimer){
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_PED_VCPA_PLAYER_FOUND, 0.0f);
+ m_nPoliceShoutTimer = CTimer::GetTimeInMilliseconds() + 4500 + (CGeneral::GetRandomNumber()&0xFFF);
+ }
+ }
+
int r, g, b;
+ RwRGBA dropColor = { 0, 0, 0, 0 };
RwRGBA splashColor, jetColor;
- r = 114.75f*(CTimeCycle::GetAmbientRed() + 0.5f*CTimeCycle::GetDirectionalRed());
- g = 114.75f*(CTimeCycle::GetAmbientGreen() + 0.5f*CTimeCycle::GetDirectionalGreen());
- b = 114.75f*(CTimeCycle::GetAmbientBlue() + 0.5f*CTimeCycle::GetDirectionalBlue());
+ r = 127.5f*(CTimeCycle::GetAmbientRed_Obj() + 0.5f*CTimeCycle::GetDirectionalRed());
+ g = 127.5f*(CTimeCycle::GetAmbientGreen_Obj() + 0.5f*CTimeCycle::GetDirectionalGreen());
+ b = 127.5f*(CTimeCycle::GetAmbientBlue_Obj() + 0.5f*CTimeCycle::GetDirectionalBlue());
r = Clamp(r, 0, 255);
g = Clamp(g, 0, 255);
b = Clamp(b, 0, 255);
splashColor.red = r;
splashColor.green = g;
splashColor.blue = b;
- splashColor.alpha = CGeneral::GetRandomNumberInRange(128, 150);
+ splashColor.alpha = CGeneral::GetRandomNumberInRange(160, 196);
- r = 242.25f*(CTimeCycle::GetAmbientRed() + 0.5f*CTimeCycle::GetDirectionalRed());
- g = 242.25f*(CTimeCycle::GetAmbientGreen() + 0.5f*CTimeCycle::GetDirectionalGreen());
- b = 242.25f*(CTimeCycle::GetAmbientBlue() + 0.5f*CTimeCycle::GetDirectionalBlue());
+ r = 229.5f*(CTimeCycle::GetAmbientRed() + 0.85f*CTimeCycle::GetDirectionalRed());
+ g = 229.5f*(CTimeCycle::GetAmbientGreen() + 0.85f*CTimeCycle::GetDirectionalGreen());
+ b = 229.5f*(CTimeCycle::GetAmbientBlue() + 0.85f*CTimeCycle::GetDirectionalBlue());
r = Clamp(r, 0, 255);
g = Clamp(g, 0, 255);
b = Clamp(b, 0, 255);
jetColor.red = r;
jetColor.green = g;
jetColor.blue = b;
- jetColor.alpha = CGeneral::GetRandomNumberInRange(96, 128);
+ jetColor.alpha = CGeneral::GetRandomNumberInRange(196, 228);
CGeneral::GetRandomNumber(); // unused
+ UpdateClumpAlpha();
ProcessCarAlarm();
switch(GetStatus()){
@@ -153,10 +189,14 @@ CBoat::ProcessControl(void)
ProcessControlInputs(0);
if(GetModelIndex() == MI_PREDATOR)
DoFixedMachineGuns();
+
+ if (!CRecordDataForChase::IsRecording())
+ DoDriveByShootings();
break;
case STATUS_SIMPLE:
m_bIsAnchored = false;
m_fOrientation = INVALID_ORIENTATION;
+ CCarAI::UpdateCarAI(this);
CPhysical::ProcessControl();
bBoatInWater = true;
bPropellerInWater = true;
@@ -165,7 +205,8 @@ CBoat::ProcessControl(void)
case STATUS_PHYSICS:
m_bIsAnchored = false;
m_fOrientation = INVALID_ORIENTATION;
- CCarCtrl::SteerAIBoatWithPhysics(this);
+ CCarAI::UpdateCarAI(this);
+ CCarCtrl::SteerAICarWithPhysics(this);
break;
case STATUS_ABANDONED:
case STATUS_WRECKED:
@@ -176,7 +217,7 @@ CBoat::ProcessControl(void)
bIsHandbrakeOn = false;
m_fBrakePedal = 0.5f;
m_fGasPedal = 0.0f;
- if((GetPosition() - CWorld::Players[CWorld::PlayerInFocus].GetPos()).Magnitude() > 150.0f){
+ if((GetPosition() - FindPlayerCentreOfWorld_NoSniperShift()).Magnitude() > 150.0f){
m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f);
return;
@@ -187,33 +228,42 @@ CBoat::ProcessControl(void)
float collisionDamage = pHandling->fCollisionDamageMultiplier * m_fDamageImpulse;
#ifdef FIX_BUGS
- if (collisionDamage > 25.0f && GetStatus() != STATUS_WRECKED && m_fHealth >= 150.0f && !bCollisionProof) {
+ if(GetStatus() == STATUS_PLAYER && CStats::GetPercentageProgress() >= 100.0f)
+ collisionDamage *= 0.5f;
+ if (collisionDamage > 25.0f && GetStatus() != STATUS_WRECKED && !bCollisionProof) {
#else
- if(collisionDamage > 25.0f && GetStatus() != STATUS_WRECKED && m_fHealth >= 150.0f){
+ if(collisionDamage > 25.0f && GetStatus() != STATUS_WRECKED){
#endif
float prevHealth = m_fHealth;
- if(this == FindPlayerVehicle()){
- if(bTakeLessDamage)
- m_fHealth -= (collisionDamage-25.0f)/6.0f;
- else
- m_fHealth -= (collisionDamage-25.0f)/2.0f;
- }else{
- if(collisionDamage > 60.0f && pDriver)
- pDriver->Say(SOUND_PED_ANNOYED_DRIVER);
- if(bTakeLessDamage)
- m_fHealth -= (collisionDamage-25.0f)/12.0f;
- else
- m_fHealth -= (collisionDamage-25.0f)/4.0f;
- }
+ if(prevHealth >= 250.0f){
+#ifndef FIX_BUGS
+ // if collisionDamage < 50 we actually increase health here...
+ if(GetStatus() == STATUS_PLAYER && CStats::GetPercentageProgress() >= 100.0f)
+ collisionDamage *= 0.5f;
+#endif
+ if(this == FindPlayerVehicle()){
+ if(bTakeLessDamage)
+ m_fHealth -= (collisionDamage-25.0f)/6.0f;
+ else
+ m_fHealth -= (collisionDamage-25.0f)/2.0f;
+ }else{
+ if(collisionDamage > 60.0f && pDriver)
+ pDriver->Say(SOUND_PED_ANNOYED_DRIVER);
+ if(bTakeLessDamage)
+ m_fHealth -= (collisionDamage-25.0f)/12.0f;
+ else
+ m_fHealth -= (collisionDamage-25.0f)/4.0f;
+ }
- if(m_fHealth <= 0.0f && prevHealth > 0.0f){
- m_fHealth = 1.0f;
- m_pSetOnFireEntity = m_pDamageEntity;
+ if(m_fHealth <= 0.0f && prevHealth > 0.0f){
+ m_fHealth = 1.0f;
+ m_pSetOnFireEntity = m_pDamageEntity;
+ }
}
}
// Damage particles
- if(m_fHealth <= 600.0f && GetStatus() != STATUS_WRECKED &&
+ if(m_fHealth <= 460.0f && GetStatus() != STATUS_WRECKED &&
Abs(GetPosition().x - TheCamera.GetPosition().x) < 200.0f &&
Abs(GetPosition().y - TheCamera.GetPosition().y) < 200.0f){
float speedSq = m_vecMoveSpeed.MagnitudeSqr();
@@ -239,7 +289,7 @@ CBoat::ProcessControl(void)
smokePos = GetMatrix() * smokePos;
// On fire
- if(m_fHealth < 150.0f){
+ if(m_fHealth < 250.0f){
CParticle::AddParticle(PARTICLE_CARFLAME, smokePos,
CVector(0.0f, 0.0f, CGeneral::GetRandomNumberInRange(2.25f/200.0f, 0.09f)),
nil, 0.9f);
@@ -256,52 +306,92 @@ CBoat::ProcessControl(void)
if(speedSq < 0.25f && (CTimer::GetFrameCounter() + m_randomSeed) & 1)
CParticle::AddParticle(PARTICLE_ENGINE_STEAM, smokePos, smokeDir);
- if(speedSq < 0.25f && m_fHealth <= 350.0f)
+ if(speedSq < 0.25f && m_fHealth <= 390.0f)
CParticle::AddParticle(PARTICLE_ENGINE_SMOKE, smokePos, 1.25f*smokeDir);
}
+ bool bSeparateTurnForce = bHasHitWall;
CPhysical::ProcessControl();
CVector buoyanceImpulse(0.0f, 0.0f, 0.0f);
CVector buoyancePoint(0.0f, 0.0f, 0.0f);
- if(mod_Buoyancy.ProcessBuoyancy(this, pHandling->fBuoyancy, &buoyancePoint, &buoyanceImpulse)){
+ if(mod_Buoyancy.ProcessBuoyancyBoat(this, pHandling->fBuoyancy, &buoyancePoint, &buoyanceImpulse, bSeparateTurnForce)){
// Process boat in water
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->bTouchingWater = true;
+ 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;
m_vecBuoyancePoint = buoyancePoint;
- ApplyMoveForce(buoyanceImpulse);
- if(!onLand)
- ApplyTurnForce(buoyanceImpulse, buoyancePoint);
+ if(GetModelIndex() == MI_SKIMMER && GetUp().z < -0.5f && Abs(m_vecMoveSpeed.x) < 0.2f && Abs(m_vecMoveSpeed.y) < 0.2f)
+ ApplyMoveForce(0.03f*buoyanceImpulse);
+ else
+ ApplyMoveForce(buoyanceImpulse);
+ if(bSeparateTurnForce)
+ ApplyTurnForce(0.4f*buoyanceImpulse, buoyancePoint);
+
+ // TODO: what is this?
+ if(GetModelIndex() == MI_SKIMMER)
+ if(m_skimmerThingTimer != 0.0f ||
+ GetForward().z < -0.5f && GetUp().z > -0.5f && m_vecMoveSpeed.z < -0.15f &&
+ buoyanceImpulse.z > 0.01f*m_fMass * GRAVITY*CTimer::GetTimeStep() &&
+ buoyanceImpulse.z < 0.4f*m_fMass * GRAVITY*CTimer::GetTimeStep()){
+ float turnImpulse = -0.00017f*GetForward().z*buoyanceImpulse.z * m_fMass*CTimer::GetTimeStep();
+ ApplyTurnForce(turnImpulse*GetForward(), GetUp());
+ bBoatInWater = false;
+ //BUG? aren't we forgetting the timestep here?
+ float moveImpulse = -0.5f*DotProduct(m_vecMoveSpeed, GetForward()) * m_fMass;
+ ApplyMoveForce(moveImpulse*GetForward());
+ if(m_skimmerThingTimer == 0.0f)
+ m_skimmerThingTimer = CTimer::GetTimeInMilliseconds() + 300.0f;
+ else if(m_skimmerThingTimer < CTimer::GetTimeInMilliseconds())
+ m_skimmerThingTimer = 0.0f;
+ }
if(!onLand && bBoatInWater && GetUp().z > 0.0f){
- float impulse;
- if(m_fGasPedal > 0.05f)
- impulse = m_vecMoveSpeed.MagnitudeSqr()*pHandling->fSuspensionForceLevel*buoyanceImpulse.z*CTimer::GetTimeStep()*0.5f*m_fGasPedal;
+ float impulse = m_vecMoveSpeed.MagnitudeSqr()*pBoatHandling->fAqPlaneForce*buoyanceImpulse.z*CTimer::GetTimeStep()*0.5f;
+ if(GetModelIndex() == MI_SKIMMER)
+ impulse *= 1.0f + m_fGasPedal;
+ else if(m_fGasPedal > 0.05f)
+ impulse *= m_fGasPedal;
else
impulse = 0.0f;
- impulse = Min(impulse, GRAVITY*pHandling->fSuspensionDampingLevel*m_fMass*CTimer::GetTimeStep());
+ impulse = Min(impulse, GRAVITY*pBoatHandling->fAqPlaneLimit*m_fMass*CTimer::GetTimeStep());
ApplyMoveForce(impulse*GetUp());
- ApplyTurnForce(impulse*GetUp(), buoyancePoint - pHandling->fSuspensionBias*GetForward());
+ ApplyTurnForce(impulse*GetUp(), buoyancePoint - pBoatHandling->fAqPlaneOffset*GetForward());
}
// Handle boat moving forward
- if(Abs(m_fGasPedal) > 0.05f || m_vecMoveSpeed.Magnitude2D() > 0.01f){
- if(bBoatInWater)
+ float fwdSpeed = 1.0f;
+ if(Abs(m_fGasPedal) > 0.05f || (fwdSpeed = m_vecMoveSpeed.Magnitude2D()) > 0.01f){
+ if(bBoatInWater && fwdSpeed > 0.05f)
AddWakePoint(GetPosition());
- float steerFactor = 1.0f - DotProduct(m_vecMoveSpeed, GetForward());
- if (GetModelIndex() == MI_GHOST)
- steerFactor = 1.0f - DotProduct(m_vecMoveSpeed, GetForward())*0.3f;
- if(steerFactor < 0.0f) steerFactor = 0.0f;
+ float steerFactor = 1.0f;
+ if(GetStatus() == STATUS_PLAYER){
+ float steerLoss = DotProduct(m_vecMoveSpeed, GetForward())*pHandling->fTractionBias;
+ if(CPad::GetPad(0)->GetHandBrake())
+ steerLoss *= 0.5f;
+ steerFactor -= steerLoss;
+ steerFactor = Clamp(steerFactor, 0.0f, 1.0f);
+ }
- CVector propeller(0.0f, -pHandling->Dimension.y*m_fThrustY, -pHandling->Dimension.z*m_fThrustZ);
+ CVector boundMin = GetColModel()->boundingBox.min;
+ CVector propeller(0.0f, boundMin.y*pBoatHandling->fThrustY, boundMin.z*pBoatHandling->fThrustZ);
propeller = Multiply3x3(GetMatrix(), propeller);
CVector propellerWorld = GetPosition() + propeller;
@@ -317,7 +407,11 @@ CBoat::ProcessControl(void)
propellerDepth = SQR(propellerDepth);
bPropellerInWater = true;
- if(Abs(m_fGasPedal) > 0.05f){
+ bool bSlowAhead = false;
+ if(Abs(m_fGasPedal) > 0.01f && GetModelIndex() != MI_SKIMMER){
+ if(Abs(m_fGasPedal) < 0.05f)
+ bSlowAhead = true;
+
CVector forceDir = Multiply3x3(GetMatrix(), CVector(-steerSin, steerCos, -Abs(m_fSteerAngle)));
CVector force = propellerDepth * m_fGasPedal * 40.0f * pHandling->Transmission.fEngineAcceleration * pHandling->fMass * forceDir;
if(force.z > 0.2f)
@@ -332,191 +426,326 @@ CBoat::ProcessControl(void)
ApplyMoveForce(force * CTimer::GetTimeStep());
}else{
ApplyMoveForce(force * CTimer::GetTimeStep());
- ApplyTurnForce(force * CTimer::GetTimeStep(), propeller - pHandling->fTractionBias*GetUp());
- float rightForce = DotProduct(GetRight(), force);
- ApplyTurnForce(-rightForce*GetRight() * CTimer::GetTimeStep(), GetUp());
+ ApplyTurnForce(force * CTimer::GetTimeStep(), propeller - pBoatHandling->fThrustAppZ*GetUp());
+ float rightForce = -DotProduct(GetRight(), force)*pHandling->fTractionMultiplier;
+ ApplyTurnForce(rightForce*GetRight() * CTimer::GetTimeStep(), GetUp());
}
// Spray some particles
CVector jetDir = -0.04f * force;
if(m_fGasPedal > 0.0f){
if(GetStatus() == STATUS_PLAYER){
- bool cameraHack = TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN ||
- TheCamera.WhoIsInControlOfTheCamera == CAMCONTROL_OBBE;
CVector sternPos = GetColModel()->boundingBox.min;
sternPos.x = 0.0f;
sternPos.z = 0.0f;
sternPos = Multiply3x3(GetMatrix(), sternPos);
- CVector jetPos = GetPosition() + sternPos;
- if(cameraHack)
- jetPos.z = 1.0f;
- else
- jetPos.z = 0.0f;
-
-#ifdef PC_PARTICLE
- CVector wakePos = GetPosition() + sternPos;
- wakePos.z -= 0.65f;
-#else
CVector wakePos = GetPosition() + sternPos;
- wakePos.z = -0.3f;
-#endif
-
- CVector wakeDir = 0.75f * jetDir;
-
- CParticle::AddParticle(PARTICLE_BOAT_THRUSTJET, jetPos, jetDir, nil, 0.0f, jetColor);
-#ifdef PC_PARTICLE
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, jetPos, 0.25f * jetDir, nil, 1.0f, splashColor,
- CGeneral::GetRandomNumberInRange(0, 30),
- CGeneral::GetRandomNumberInRange(0, 90), 3);
-#endif
- if(!cameraHack)
- CParticle::AddParticle(PARTICLE_BOAT_WAKE, wakePos, wakeDir, nil, 0.0f, jetColor);
- }else if((CTimer::GetFrameCounter() + m_randomSeed) & 1){
-#ifdef PC_PARTICLE
- jetDir.z = 0.018f;
- jetDir.x *= 0.01f;
- jetDir.y *= 0.01f;
- propellerWorld.z += 1.5f;
+ // no actual particles for player...
+ }else if(IsVisible() && ((CTimer::GetFrameCounter() + m_randomSeed) & 1) &&
+ CVisibilityPlugins::GetDistanceSquaredFromCamera(&propellerWorld) < SQR(70.0f * TheCamera.GenerationDistMultiplier)){
+ jetDir.z = 0.015f;
+ jetDir.x *= 3.5f;
+ jetDir.y *= 3.5f;
+ propellerWorld.z += 0.5f;
- CParticle::AddParticle(PARTICLE_BOAT_SPLASH, propellerWorld, jetDir, nil, 1.5f, jetColor);
-#else
- jetDir.z = 0.018f;
- jetDir.x *= 0.03f;
- jetDir.y *= 0.03f;
- propellerWorld.z += 1.0f;
-
- CParticle::AddParticle(PARTICLE_BOAT_SPLASH, propellerWorld, jetDir, nil, 0.0f, jetColor);
-#endif
+ CParticle::AddParticle(PARTICLE_BOAT_SPLASH, propellerWorld, jetDir, nil, 1.25f, jetColor,
+ CGeneral::GetRandomNumberInRange(0, 5),
+ CGeneral::GetRandomNumberInRange(0, 90), 1, 500);
-#ifdef PC_PARTICLE
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, propellerWorld, 0.1f * jetDir, nil, 0.5f, splashColor,
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, propellerWorld, 0.75f * jetDir, nil, 0.5f, splashColor,
CGeneral::GetRandomNumberInRange(0, 30),
- CGeneral::GetRandomNumberInRange(0, 90), 3);
-#endif
+ CGeneral::GetRandomNumberInRange(0, 45), 3, 500);
}
}
- }else if(!onLand){
- float force = 50.0f*DotProduct(m_vecMoveSpeed, GetForward());
- force = Min(force, 10.0f);
+ }else
+ bSlowAhead = true;
+
+ if(!onLand && bSlowAhead){
+ float force = pHandling->fTractionLoss*DotProduct(m_vecMoveSpeed, GetForward());
+ force = Min(force, 0.01f*m_fTurnMass);
+ if(m_fGasPedal > 0.01f){
+ if(GetStatus() == STATUS_PLAYER)
+ force *= (0.55f - Abs(m_fGasPedal)) * 1.3f;
+ else
+ force *= (0.55f - Abs(m_fGasPedal)) * 2.5f;
+ }
+ if(m_fGasPedal < 0.0f && force > 0.0f || m_fGasPedal > 0.0f && force < 0.0f)
+ force *= -1.0f;
CVector propellerForce = propellerDepth * Multiply3x3(GetMatrix(), force*CVector(-steerSin, 0.0f, 0.0f));
- ApplyMoveForce(propellerForce * CTimer::GetTimeStep()*0.5f);
- ApplyTurnForce(propellerForce * CTimer::GetTimeStep()*0.5f, propeller);
+ ApplyMoveForce(propellerForce * CTimer::GetTimeStep());
+ ApplyTurnForce(propellerForce * CTimer::GetTimeStep(), propeller);
+ float rightForce = -steerSin * force * 0.75f/steerFactor * Max(CTimer::GetTimeStep(), 0.01f);
+ ApplyTurnForce(GetRight() * rightForce, GetUp());
}
}else
bPropellerInWater = false;
+
+ if(pHandling->fSuspensionBias != 0.0f){
+ CVector right = CrossProduct(GetForward(), CVector(0.0f, 0.0f, 1.0f));
+ float rightSpeed = DotProduct(m_vecMoveSpeed, right);
+ float impulse = 0.1f*pHandling->fSuspensionBias * m_fMass * m_fVolumeUnderWater * rightSpeed * CTimer::GetTimeStep();
+ ApplyMoveForce(right - impulse * 0.3f * CVector(-right.y, right.x, 0.0f));
+ }
+
+ if(GetStatus() == STATUS_PLAYER && CPad::GetPad(0)->GetHandBrake()){
+ float fwdSpeed = DotProduct(m_vecMoveSpeed, GetForward());
+ if(fwdSpeed > 0.0f){
+ float impulse = -0.1f*pHandling->fSuspensionLowerLimit * m_fMass * m_fVolumeUnderWater * fwdSpeed * CTimer::GetTimeStep();
+ ApplyMoveForce(impulse * GetForward());
+ }
+ }
}
// Slow down or push down boat as it approaches the world limits
- m_vecMoveSpeed.x = Min(m_vecMoveSpeed.x, -(GetPosition().x - 1900.0f)*0.01f); // east
- m_vecMoveSpeed.x = Max(m_vecMoveSpeed.x, -(GetPosition().x - -1515.0f)*0.01f); // west
- m_vecMoveSpeed.y = Min(m_vecMoveSpeed.y, -(GetPosition().y - 600.0f)*0.01f); // north
- m_vecMoveSpeed.y = Max(m_vecMoveSpeed.y, -(GetPosition().y - -1900.0f)*0.01f); // south
+ m_vecMoveSpeed.x = Min(m_vecMoveSpeed.x, -(GetPosition().x - (WORLD_MAX_X-100.0f))*0.01f); // east
+ m_vecMoveSpeed.x = Max(m_vecMoveSpeed.x, -(GetPosition().x - (WORLD_MIN_X+100.0f))*0.01f); // west
+ m_vecMoveSpeed.y = Min(m_vecMoveSpeed.y, -(GetPosition().y - (WORLD_MAX_Y-100.0f))*0.01f); // north
+ m_vecMoveSpeed.y = Max(m_vecMoveSpeed.y, -(GetPosition().y - (WORLD_MIN_Y+100.0f))*0.01f); // south
- if(!onLand && bBoatInWater)
+ if(!onLand && bBoatInWater && !bSeparateTurnForce)
ApplyWaterResistance();
- // No idea what exactly is going on here besides drag in YZ
- float fx = Pow(m_vecTurnRes.x, CTimer::GetTimeStep());
- float fy = Pow(m_vecTurnRes.y, CTimer::GetTimeStep());
- float fz = Pow(m_vecTurnRes.z, CTimer::GetTimeStep());
- m_vecTurnSpeed = Multiply3x3(m_vecTurnSpeed, GetMatrix()); // invert - to local space
- // TODO: figure this out
- float magic = 1.0f/(1000.0f * SQR(m_vecTurnSpeed.x) + 1.0f) * fx;
- m_vecTurnSpeed.y *= fy;
- m_vecTurnSpeed.z *= fz;
- float forceUp = (magic - 1.0f) * m_vecTurnSpeed.x * m_fTurnMass;
- m_vecTurnSpeed = Multiply3x3(GetMatrix(), m_vecTurnSpeed); // back to world
- CVector com = Multiply3x3(GetMatrix(), m_vecCentreOfMass);
- ApplyTurnForce(CVector(0.0f, 0.0f, forceUp), com + GetForward());
+ if((GetModelIndex() != MI_SKIMMER || m_skimmerThingTimer == 0.0f) && !bSeparateTurnForce){
+ // No idea what exactly is going on here besides drag in YZ
+ float fx = Pow(pBoatHandling->vecTurnRes.x, CTimer::GetTimeStep());
+ float fy = Pow(pBoatHandling->vecTurnRes.y, CTimer::GetTimeStep());
+ float fz = Pow(pBoatHandling->vecTurnRes.z, CTimer::GetTimeStep());
+ m_vecTurnSpeed = Multiply3x3(m_vecTurnSpeed, GetMatrix()); // invert - to local space
+ // TODO: figure this out
+ float magic = 1.0f/(1000.0f * SQR(m_vecTurnSpeed.x) + 1.0f) * fx;
+ m_vecTurnSpeed.y *= fy;
+ m_vecTurnSpeed.z *= fz;
+ float forceUp = (magic - 1.0f) * m_vecTurnSpeed.x * m_fTurnMass;
+ m_vecTurnSpeed = Multiply3x3(GetMatrix(), m_vecTurnSpeed); // back to world
+ CVector com = Multiply3x3(GetMatrix(), m_vecCentreOfMass);
+ ApplyTurnForce(forceUp*GetUp(), com + GetForward());
+ }
m_nDeltaVolumeUnderWater = (m_fVolumeUnderWater-m_fPrevVolumeUnderWater)*10000;
// Falling into water
- if(!onLand && bBoatInWater && GetUp().z > 0.0f && m_nDeltaVolumeUnderWater > 200){
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_SPLASH, m_nDeltaVolumeUnderWater);
-
- float speedUp = m_vecMoveSpeed.MagnitudeSqr() * m_nDeltaVolumeUnderWater * 0.0004f;
- if(speedUp + m_vecMoveSpeed.z > pHandling->fBrakeDeceleration)
- speedUp = pHandling->fBrakeDeceleration - m_vecMoveSpeed.z;
- if(speedUp < 0.0f) speedUp = 0.0f;
- float speedFwd = DotProduct(m_vecMoveSpeed, GetForward());
- speedFwd *= -m_nDeltaVolumeUnderWater * 0.01f * pHandling->fTractionLoss;
- CVector speed = speedFwd*GetForward() + CVector(0.0f, 0.0f, speedUp);
- CVector splashImpulse = speed * m_fMass;
- ApplyMoveForce(splashImpulse);
- ApplyTurnForce(splashImpulse, buoyancePoint);
+ if(!onLand && bBoatInWater && GetUp().z > 0.0f){
+ float splashVol = m_nDeltaVolumeUnderWater*pBoatHandling->fWaveAudioMult;
+ if(splashVol > 200.0f)
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_SPLASH, splashVol);
+
+ if(m_nDeltaVolumeUnderWater > 200){
+ float speedUp = m_vecMoveSpeed.MagnitudeSqr() * m_nDeltaVolumeUnderWater * 0.001f;
+ if(speedUp + m_vecMoveSpeed.z > pHandling->fBrakeDeceleration)
+ speedUp = pHandling->fBrakeDeceleration - m_vecMoveSpeed.z;
+ if(speedUp < 0.0f) speedUp = 0.0f;
+ float speedFwd = DotProduct(m_vecMoveSpeed, GetForward());
+ speedFwd *= -m_nDeltaVolumeUnderWater * 0.01f * pHandling->fBrakeBias;
+ CVector speed = speedFwd*GetForward() + CVector(0.0f, 0.0f, speedUp);
+ CVector splashImpulse = speed * m_fMass;
+ ApplyMoveForce(splashImpulse);
+ ApplyTurnForce(splashImpulse, buoyancePoint);
+ }
}
- // Spray particles on sides of boat
-#ifdef PC_PARTICLE
- if(m_nDeltaVolumeUnderWater > 75)
-#else
- if(m_nDeltaVolumeUnderWater > 120)
-#endif
- {
- float speed = m_vecMoveSpeed.Magnitude();
- float splash1Size = speed;
- float splash2Size = float(m_nDeltaVolumeUnderWater) * 0.005f * 0.2f;
- float front = 0.9f * GetColModel()->boundingBox.max.y;
- if(splash1Size > 0.75f) splash1Size = 0.75f;
-
- CVector dir, pos;
-
- // right
-#ifdef PC_PARTICLE
- dir = -0.5f*m_vecMoveSpeed;
- dir.z += 0.1f*speed;
- dir += 0.5f*GetRight()*speed;
- pos = front*GetForward() + 0.5f*GetRight() + GetPosition() + m_vecBuoyancePoint;
- CWaterLevel::GetWaterLevel(pos, &pos.z, true);
-#else
- dir = 0.3f*m_vecMoveSpeed;
- dir.z += 0.05f*speed;
- dir += 0.5f*GetRight()*speed;
- pos = (GetPosition() + m_vecBuoyancePoint) + (1.5f*GetRight());
-#endif
-
-#ifdef PC_PARTICLE
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, 0.75f * dir, nil, splash1Size, splashColor,
- CGeneral::GetRandomNumberInRange(0, 30),
- CGeneral::GetRandomNumberInRange(0, 90), 1);
- CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, splash2Size, jetColor);
-#else
- CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, splash2Size);
-#endif
-
-
- // left
-#ifdef PC_PARTICLE
- dir = -0.5f*m_vecMoveSpeed;
- dir.z += 0.1f*speed;
- dir -= 0.5f*GetRight()*speed;
- pos = front*GetForward() - 0.5f*GetRight() + GetPosition() + m_vecBuoyancePoint;
- CWaterLevel::GetWaterLevel(pos, &pos.z, true);
-#else
- dir = 0.3f*m_vecMoveSpeed;
- dir.z += 0.05f*speed;
- dir -= 0.5f*GetRight()*speed;
- pos = (GetPosition() + m_vecBuoyancePoint) - (1.5f*GetRight());
-#endif
-
-#ifdef PC_PARTICLE
- CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, 0.75f * dir, nil, splash1Size, splashColor,
- CGeneral::GetRandomNumberInRange(0, 30),
- CGeneral::GetRandomNumberInRange(0, 90), 1);
- CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, splash2Size, jetColor);
-#else
- CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, splash2Size);
-#endif
+ // Splashes
+ float speed = m_vecMoveSpeed.Magnitude();
+ if(speed > 0.05f && GetUp().x > 0.0f && !TheCamera.GetLookingForwardFirstPerson() && IsVisible() &&
+ (AutoPilot.m_nCarMission != MISSION_CRUISE || (CTimer::GetFrameCounter()&2) == 0)){
+ CVector splashPos, splashDir;
+ float splashSize, front, waterLevel;
+
+ switch(GetModelIndex()){
+ case MI_RIO:
+ splashSize = speed;
+ front = 0.9f * GetColModel()->boundingBox.max.y;
+ splashDir = -0.5f * m_vecMoveSpeed;
+ splashDir.z += 0.25f*speed;
+ splashDir += 0.35f*speed*GetRight();
+ splashPos = GetPosition() + 1.85f*GetRight() + front*GetForward();
+ splashPos.z += 0.5f;
+ break;
+ case MI_SQUALO:
+ splashSize = speed;
+ front = 0.75f * GetColModel()->boundingBox.max.y;
+ splashDir = -0.125f * m_vecMoveSpeed;
+ splashDir.z += 0.15f*speed;
+ splashDir += 0.25f*speed*GetRight();
+ splashPos = GetPosition() + m_vecBuoyancePoint + 0.5f*GetRight() + front*GetForward();
+ splashPos.z += 0.5f;
+ break;
+ case MI_REEFER:
+ splashSize = speed;
+ front = 0.75f * GetColModel()->boundingBox.max.y;
+ splashDir = -0.5f * m_vecMoveSpeed;
+ splashDir.z += 0.15f*speed;
+ splashDir += 0.5f*speed*GetRight();
+ splashPos = GetPosition() + m_vecBuoyancePoint + 1.3f*GetRight() + front*GetForward();
+ break;
+ case MI_COASTG:
+ splashSize = 0.25f*speed;
+ front = 0.8f * GetColModel()->boundingBox.max.y;
+ splashDir = 0.165f * m_vecMoveSpeed;
+ splashDir.z += 0.25f*speed;
+ splashDir += 0.15f*speed*GetRight();
+ splashPos = GetPosition() + 0.65f*GetRight() + front*GetForward();
+ splashPos.z += 0.5f;
+ break;
+ case MI_DINGHY:
+ splashSize = 0.25f*speed;
+ front = 0.9f * GetColModel()->boundingBox.max.y;
+ splashDir = 0.35f * m_vecMoveSpeed;
+ splashDir.z += 0.25f*speed;
+ splashDir += 0.25f*speed*GetRight();
+ splashPos = GetPosition() + 0.6f*GetRight() + front*GetForward();
+ splashPos.z += 0.5f;
+ break;
+ default:
+ splashSize = speed;
+ front = 0.9f * GetColModel()->boundingBox.max.y;
+ splashDir = -0.5f * m_vecMoveSpeed;
+ splashDir.z += 0.25f*speed;
+ splashDir += 0.35f*speed*GetRight();
+ splashPos = GetPosition() + m_vecBuoyancePoint + 0.5f*GetRight() + front*GetForward();
+ break;
+ }
+ if(splashSize > 0.75f) splashSize = 0.75f;
+ if(AutoPilot.m_nCarMission == MISSION_CRUISE)
+ splashDir *= 1.5f;
+ static float lifeMult = 1000.0f;
+ static float lifeBase = 300.0f;
+ splashDir.z += 0.0003f*m_nDeltaVolumeUnderWater;
+ CWaterLevel::GetWaterLevel(splashPos, &waterLevel, true);
+ if(splashPos.z-waterLevel < 3.0f &&
+ CVisibilityPlugins::GetDistanceSquaredFromCamera(&splashPos) < SQR(70.0f * TheCamera.GenerationDistMultiplier)){
+ splashPos.z = waterLevel + 0.1f;
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashPos, 0.75f*splashDir, nil, splashSize+0.1f, splashColor,
+ CGeneral::GetRandomNumberInRange(0.0f, 10.0f), CGeneral::GetRandomNumberInRange(0.0f, 90.0f),
+ 1, lifeBase + splashDir.z*lifeMult);
+ CParticle::AddParticle(PARTICLE_BOAT_SPLASH, splashPos, splashDir, nil, splashSize, jetColor,
+ CGeneral::GetRandomNumberInRange(0.0f, 0.4f), CGeneral::GetRandomNumberInRange(0.0f, 45.0f),
+ 0, lifeBase + splashDir.z*lifeMult);
+ }
+
+ switch(GetModelIndex()){
+ case MI_RIO:
+ splashDir = -0.5f * m_vecMoveSpeed;
+ splashDir.z += 0.25f*speed;
+ splashDir -= 0.35f*speed*GetRight();
+ splashPos = GetPosition() - 1.85f*GetRight() + front*GetForward();
+ splashPos.z += 0.5f;
+ break;
+ case MI_SQUALO:
+ splashDir = -0.125f * m_vecMoveSpeed;
+ splashDir.z += 0.15f*speed;
+ splashDir -= 0.25f*speed*GetRight();
+ splashPos = GetPosition() + m_vecBuoyancePoint - 0.5f*GetRight() + front*GetForward();
+ splashPos.z += 0.5f;
+ break;
+ case MI_REEFER:
+ splashDir = -0.5f * m_vecMoveSpeed;
+ splashDir.z += 0.15f*speed;
+ splashDir -= 0.5f*speed*GetRight();
+ splashPos = GetPosition() + m_vecBuoyancePoint - 1.3f*GetRight() + front*GetForward();
+ break;
+ case MI_COASTG:
+ splashDir = 0.165f * m_vecMoveSpeed;
+ splashDir.z += 0.25f*speed;
+ splashDir -= 0.15f*speed*GetRight();
+ splashPos = GetPosition() - 0.65f*GetRight() + front*GetForward();
+ splashPos.z += 0.5f;
+ break;
+ case MI_DINGHY:
+ splashDir = 0.35f * m_vecMoveSpeed;
+ splashDir.z += 0.25f*speed;
+ splashDir -= 0.25f*speed*GetRight();
+ splashPos = GetPosition() - 0.6f*GetRight() + front*GetForward();
+ splashPos.z += 0.5f;
+ break;
+ default:
+ splashDir = -0.5f * m_vecMoveSpeed;
+ splashDir.z += 0.25f*speed;
+ splashDir -= 0.35f*speed*GetRight();
+ splashPos = GetPosition() + m_vecBuoyancePoint - 0.5f*GetRight() + front*GetForward();
+ break;
+ }
+ if(AutoPilot.m_nCarMission == MISSION_CRUISE)
+ splashDir *= 1.5f;
+ splashDir.z += 0.0003f*m_nDeltaVolumeUnderWater;
+ CWaterLevel::GetWaterLevel(splashPos, &waterLevel, true);
+ if(splashPos.z-waterLevel < 3.0f &&
+ CVisibilityPlugins::GetDistanceSquaredFromCamera(&splashPos) < SQR(70.0f * TheCamera.GenerationDistMultiplier)){
+ splashPos.z = waterLevel + 0.1f;
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashPos, 0.75f*splashDir, nil, splashSize+0.1f, splashColor,
+ CGeneral::GetRandomNumberInRange(0.0f, 10.0f), CGeneral::GetRandomNumberInRange(0.0f, 90.0f),
+ 1, lifeBase + splashDir.z*lifeMult);
+ CParticle::AddParticle(PARTICLE_BOAT_SPLASH, splashPos, splashDir, nil, splashSize, jetColor,
+ CGeneral::GetRandomNumberInRange(0.0f, 0.4f), CGeneral::GetRandomNumberInRange(0.0f, 45.0f),
+ 0, lifeBase + splashDir.z*lifeMult);
+ }
+ }
+
+ // Spray waterdrops on screen
+ if(TheCamera.GetLookingForwardFirstPerson() && FindPlayerVehicle() && FindPlayerVehicle()->IsBoat() &&
+ m_nDeltaVolumeUnderWater > 0 && numWaterDropOnScreen < 20){
+ CVector dropPos;
+ CVector dropDir(CGeneral::GetRandomNumberInRange(-0.25f, 0.25f), CGeneral::GetRandomNumberInRange(1.0f, 0.75f), 0.0f);
+
+ int frm = CGeneral::GetRandomNumber() & 1;
+ if(TheCamera.m_CameraAverageSpeed < 0.35f){
+ dropPos.x = CGeneral::GetRandomNumberInRange(50, (int)SCREEN_WIDTH-50);
+ dropPos.y = CGeneral::GetRandomNumberInRange(50, (int)SCREEN_HEIGHT-50);
+ }else{
+ dropPos.x = CGeneral::GetRandomNumberInRange(200, (int)SCREEN_WIDTH-200);
+ dropPos.y = CGeneral::GetRandomNumberInRange(150, (int)SCREEN_HEIGHT-150);
+ }
+ dropPos.z = 1.0f;
+
+ if(TheCamera.m_CameraAverageSpeed > 0.35f){
+ if((int)SCREEN_WIDTH / 2 < dropPos.x)
+ dropPos.x += CGeneral::GetRandomNumberInRange(0.35f, TheCamera.m_CameraAverageSpeed)*7.5f;
+ else
+ dropPos.x -= CGeneral::GetRandomNumberInRange(0.35f, TheCamera.m_CameraAverageSpeed)*7.5f;
+
+ if((int)SCREEN_HEIGHT / 2 < dropPos.y)
+ dropPos.y += CGeneral::GetRandomNumberInRange(0.35f, TheCamera.m_CameraAverageSpeed)*7.5f;
+ else
+ dropPos.y -= CGeneral::GetRandomNumberInRange(0.35f, TheCamera.m_CameraAverageSpeed)*7.5f;
+ }
+
+ if(CParticle::AddParticle(PARTICLE_WATERDROP, dropPos, dropDir, nil,
+ CGeneral::GetRandomNumberInRange(0.1f, 0.15f), dropColor, 0, 0, frm))
+ numWaterDropOnScreen++;
+ }
+
+ if(m_fPrevVolumeUnderWater == 0.0f && m_fVolumeUnderWater > 0.0f && GetModelIndex() == MI_SKIMMER){
+ CVector splashDir(0.0f, 0.0f, 0.25f*speed);
+ CVector splashPos = GetPosition();
+ float level;
+ CWaterLevel::GetWaterLevel(splashPos, &level, true);
+ splashPos.z = level;
+ CParticleObject::AddObject(POBJECT_CAR_WATER_SPLASH, splashPos, splashDir, 0.0f, 65, splashColor, true);
}
m_fPrevVolumeUnderWater = m_fVolumeUnderWater;
}else{
bBoatInWater = false;
bIsInWater = false;
+#ifdef FIX_BUGS
+ bIsDrowning = false;
+#endif
}
+ if(m_modelIndex == MI_SKIMMER && CTimer::GetTimeStep() > 0.0f){
+ if(GetStatus() == STATUS_PLAYER){
+ if(m_fMovingSpeed < 0.22f)
+ m_fMovingSpeed += 0.001f*CTimer::GetTimeStep();
+ FlyingControl(FLIGHT_MODEL_SEAPLANE);
+ }else{
+ if(m_fMovingSpeed > 0.0005f*CTimer::GetTimeStep())
+ m_fMovingSpeed -= 0.0005f*CTimer::GetTimeStep();
+ else
+ m_fMovingSpeed = 0.0f;
+ }
+ }else if(bCheat8)
+ FlyingControl(FLIGHT_MODEL_PLANE);
+
if(m_bIsAnchored){
m_vecMoveSpeed.x = 0.0f;
m_vecMoveSpeed.y = 0.0f;
@@ -549,7 +778,7 @@ CBoat::ProcessControlInputs(uint8 pad)
m_fAccelerate += (CPad::GetPad(pad)->GetAccelerate()/255.0f - m_fAccelerate)*0.1f;
m_fAccelerate = Clamp(m_fAccelerate, 0.0f, 1.0f);
}else
- m_fAccelerate = -m_fBrake*0.2f;
+ m_fAccelerate = -m_fBrake*0.3f;
m_fSteeringLeftRight += (-CPad::GetPad(pad)->GetSteeringLeftRight()/128.0f - m_fSteeringLeftRight)*0.2f;
m_fSteeringLeftRight = Clamp(m_fSteeringLeftRight, -1.0f, 1.0f);
@@ -559,17 +788,21 @@ CBoat::ProcessControlInputs(uint8 pad)
m_fGasPedal = m_fAccelerate;
}
+float fSeaPlaneWaterResistance = 30.0f;
+
void
CBoat::ApplyWaterResistance(void)
{
- float fwdSpeed = DotProduct(GetMoveSpeed(), GetForward());
// TODO: figure out how this works
- float resistance = 0.001f * SQR(m_fVolumeUnderWater) * m_fMass;
+ float resistance = 0.001f * pHandling->fSuspensionForceLevel * SQR(m_fVolumeUnderWater) * m_fMass;
+ if(GetModelIndex() == MI_SKIMMER)
+ resistance *= fSeaPlaneWaterResistance;
+ float fwdSpeed = DotProduct(GetMoveSpeed(), GetForward());
float magic = (SQR(fwdSpeed) + 0.05f) * resistance + 1.0f;
magic = Abs(magic);
- float fx = Pow(m_vecMoveRes.x/magic, 0.5f*CTimer::GetTimeStep());
- float fy = Pow(m_vecMoveRes.y/magic, 0.5f*CTimer::GetTimeStep());
- float fz = Pow(m_vecMoveRes.z/magic, 0.5f*CTimer::GetTimeStep());
+ float fx = Pow(pBoatHandling->vecMoveRes.x/magic, 0.5f*CTimer::GetTimeStep());
+ float fy = Pow(pBoatHandling->vecMoveRes.y/magic, 0.5f*CTimer::GetTimeStep());
+ float fz = Pow(pBoatHandling->vecMoveRes.z/magic, 0.5f*CTimer::GetTimeStep());
m_vecMoveSpeed = Multiply3x3(m_vecMoveSpeed, GetMatrix()); // invert - to local space
m_vecMoveSpeed.x *= fx;
@@ -618,19 +851,14 @@ CBoat::BlowUpCar(CEntity *culprit)
m_nBombTimer = 0;
TheCamera.CamShake(0.7f, GetPosition().x, GetPosition().y, GetPosition().z);
- if(this == FindPlayerVehicle())
- FindPlayerPed()->m_fHealth = 0.0f; // kill player
- if(pDriver){
- CDarkel::RegisterKillByPlayer(pDriver, WEAPONTYPE_EXPLOSION);
- pDriver->SetDead();
- pDriver->FlagToDestroyWhenNextProcessed();
- }
+ KillPedsInVehicle();
bEngineOn = false;
bLightsOn = false;
ChangeLawEnforcerState(false);
- CExplosion::AddExplosion(this, culprit, EXPLOSION_CAR, GetPosition(), 0);
+ CExplosion::AddExplosion(this, culprit, EXPLOSION_BOAT, GetPosition(), 0);
+ CDarkel::RegisterCarBlownUpByPlayer(this);
if(m_aBoatNodes[BOAT_MOVING] == nil)
return;
@@ -658,6 +886,7 @@ CBoat::BlowUpCar(CEntity *culprit)
RpAtomicSetFrame(atomic, frame);
CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil);
obj->AttachToRwObject((RwObject*)atomic);
+ obj->bDontStream = true;
// init object
obj->m_fMass = 10.0f;
@@ -697,39 +926,200 @@ CBoat::BlowUpCar(CEntity *culprit)
RpAtomicSetFlags(atomic, 0);
}
-RwIm3DVertex KeepWaterOutVertices[4];
-RwImVertexIndex KeepWaterOutIndices[6];
-
void
-CBoat::Render()
+CBoat::PreRender(void)
{
CMatrix matrix;
+ CVector pos;
+ RpAtomic *atomic;
- if (m_aBoatNodes[BOAT_MOVING] != nil) {
- matrix.Attach(RwFrameGetMatrix(m_aBoatNodes[BOAT_MOVING]));
+ if(GetModelIndex() == MI_SKIMMER){
+ m_fMovingRotation += m_fMovingSpeed*CTimer::GetTimeStep();
+ if(m_fMovingRotation > TWOPI) m_fMovingRotation -= TWOPI;
+ int alpha = (1.0f - Min(2.0f*m_fMovingSpeed*8.0f/PI, 1.0f))*255.0f;
+ if(GetStatus() == STATUS_PLAYER || GetStatus() == STATUS_PLAYER_REMOTE || GetStatus() == STATUS_PLAYER_PLAYBACKFROMBUFFER){
+ if(m_aBoatNodes[BOAT_RUDDER]){
+ float sine = Sin(m_fSteerAngle);
+ matrix.Attach(RwFrameGetMatrix(m_aBoatNodes[BOAT_RUDDER]));
+ pos = matrix.GetPosition();
+ matrix.SetRotate(0.0f, 0.0f, -m_fSteerAngle);
+ matrix.Rotate(0.0f, DEGTORAD(22.0f)*sine, 0.0f);
+ matrix.Translate(pos);
+ matrix.UpdateRW();
+ }
+ if(m_aBoatNodes[BOAT_FLAP_LEFT]){
+ matrix.Attach(RwFrameGetMatrix(m_aBoatNodes[BOAT_FLAP_LEFT]));
+ pos = matrix.GetPosition();
+ matrix.SetRotateX(-m_fSteerAngle);
+ matrix.Translate(pos);
+ matrix.UpdateRW();
+ }
+ if(m_aBoatNodes[BOAT_FLAP_RIGHT]){
+ matrix.Attach(RwFrameGetMatrix(m_aBoatNodes[BOAT_FLAP_RIGHT]));
+ pos = matrix.GetPosition();
+ matrix.SetRotateX(m_fSteerAngle);
+ matrix.Translate(pos);
+ matrix.UpdateRW();
+ }
+ // FIX: Planes can also be controlled with GetCarGunUpDown
+#ifdef FIX_BUGS
+ static float steeringUpDown = 0.0f;
+#ifdef FREE_CAM
+ if(!CCamera::bFreeCam || (CCamera::bFreeCam && !CPad::IsAffectedByController))
+#endif
+ steeringUpDown += ((Abs(CPad::GetPad(0)->GetCarGunUpDown()) > 1.0f ? (-CPad::GetPad(0)->GetCarGunUpDown()/128.0f) : (-CPad::GetPad(0)->GetSteeringUpDown()/128.0f)) - steeringUpDown) * Min(1.f, CTimer::GetTimeStep()/5.f);
+#ifdef FREE_CAM
+ else
+ steeringUpDown = -CPad::GetPad(0)->GetSteeringUpDown()/128.0f;
+#endif
+#else
+ float steeringUpDown = -CPad::GetPad(0)->GetSteeringUpDown()/128.0f;
+#endif
+ if(m_aBoatNodes[BOAT_REARFLAP_LEFT]){
+ matrix.Attach(RwFrameGetMatrix(m_aBoatNodes[BOAT_REARFLAP_LEFT]));
+ pos = matrix.GetPosition();
+ matrix.SetRotateX(steeringUpDown);
+ matrix.Translate(pos);
+ matrix.UpdateRW();
+ }
+ if(m_aBoatNodes[BOAT_REARFLAP_RIGHT]){
+ matrix.Attach(RwFrameGetMatrix(m_aBoatNodes[BOAT_REARFLAP_RIGHT]));
+ pos = matrix.GetPosition();
+ matrix.SetRotateX(steeringUpDown);
+ matrix.Translate(pos);
+ matrix.UpdateRW();
+ }
+ }
+ if(m_aBoatNodes[BOAT_MOVING]){
+ matrix.Attach(RwFrameGetMatrix(m_aBoatNodes[BOAT_MOVING]));
+ pos = matrix.GetPosition();
+ matrix.SetRotateY(m_fMovingRotation);
+ matrix.Translate(pos);
+ matrix.UpdateRW();
+
+ atomic = nil;
+ RwFrameForAllObjects(m_aBoatNodes[BOAT_MOVING], GetBoatAtomicObjectCB, &atomic);
+ if(atomic)
+ SetComponentAtomicAlpha(atomic, alpha);
+ }
+ if(m_aBoatNodes[BOAT_WINDSCREEN]){
+ matrix.Attach(RwFrameGetMatrix(m_aBoatNodes[BOAT_WINDSCREEN]));
+ pos = matrix.GetPosition();
+ matrix.SetRotateY(-m_fMovingRotation);
+ matrix.Translate(pos);
+ matrix.UpdateRW();
+
+ atomic = nil;
+ RwFrameForAllObjects(m_aBoatNodes[BOAT_WINDSCREEN], GetBoatAtomicObjectCB, &atomic);
+ if(atomic)
+ SetComponentAtomicAlpha(atomic, Max(150-alpha, 0));
+ }
+ CShadows::StoreShadowForVehicle(this, VEH_SHD_TYPE_SEAPLANE);
+ }else if(GetModelIndex() == MI_COASTG || GetModelIndex() == MI_DINGHY || GetModelIndex() == MI_RIO ||
+ GetModelIndex() == MI_SQUALO || GetModelIndex() == MI_MARQUIS){
+ if(m_aBoatNodes[BOAT_RUDDER]){
+ matrix.Attach(RwFrameGetMatrix(m_aBoatNodes[BOAT_RUDDER]));
+ pos = matrix.GetPosition();
+ matrix.SetRotateZ(-m_fSteerAngle);
+ matrix.Translate(pos);
+ matrix.UpdateRW();
+ }
+ if(m_aBoatNodes[BOAT_REARFLAP_LEFT]){
+ matrix.Attach(RwFrameGetMatrix(m_aBoatNodes[BOAT_REARFLAP_LEFT]));
+ pos = matrix.GetPosition();
+ matrix.SetRotateZ(-m_fSteerAngle);
+ matrix.Translate(pos);
+ matrix.UpdateRW();
+ }
+ if(m_aBoatNodes[BOAT_REARFLAP_RIGHT]){
+ matrix.Attach(RwFrameGetMatrix(m_aBoatNodes[BOAT_REARFLAP_RIGHT]));
+ pos = matrix.GetPosition();
+ matrix.SetRotateZ(-m_fSteerAngle);
+ matrix.Translate(pos);
+ matrix.UpdateRW();
+ }
+ }
- CVector pos = matrix.GetPosition();
- matrix.SetRotateZ(m_fMovingRotation);
+ if(GetModelIndex() == MI_RIO || GetModelIndex() == MI_MARQUIS){
+ float axes[3] = { 0.0f, 0.0f, 0.0f };
+ m_boom.Process(this);
+ axes[m_boom.m_nAxis] = m_boom.m_fAngle;
+ matrix.Attach(RwFrameGetMatrix(m_aBoatNodes[BOAT_FLAP_LEFT]));
+ pos = matrix.GetPosition();
+ matrix.SetRotate(axes[0], axes[1], axes[2]);
matrix.Translate(pos);
-
matrix.UpdateRW();
- if (CVehicle::bWheelsOnlyCheat) {
- RpAtomicRender((RpAtomic*)GetFirstObject(m_aBoatNodes[BOAT_MOVING]));
+ }
+
+ if(GetModelIndex() == MI_RIO){
+ // That little wind propeller
+ if(m_aBoatNodes[BOAT_FLAP_RIGHT]){
+ matrix.Attach(RwFrameGetMatrix(m_aBoatNodes[BOAT_FLAP_RIGHT]));
+ pos = matrix.GetPosition();
+
+ float flapHeading = matrix.GetForward().Heading();
+ float boatHeading = GetForward().Heading();
+ float rot = -DEGTORAD(45.0f) - (flapHeading + boatHeading);
+ // eh what?
+ rot = CGeneral::LimitRadianAngle(rot);
+ if(rot > HALFPI) rot = PI;
+ else if(rot < -HALFPI) rot = -PI;
+ rot = Clamp(rot, -DEGTORAD(63.0f), DEGTORAD(63.0f));
+ m_fMovingSpeed += (0.008f * CWeather::Wind + 0.002f) * rot;
+ m_fMovingSpeed *= Pow(0.9985f, CTimer::GetTimeStep())/(500.0f*SQR(m_fMovingSpeed) + 1.0f);
+
+ matrix.SetRotateZ(flapHeading + m_fMovingSpeed*CTimer::GetTimeStep());
+ matrix.Translate(pos);
+ matrix.UpdateRW();
+ }
+ if(m_aBoatNodes[BOAT_MOVING]){
+ matrix.Attach(RwFrameGetMatrix(m_aBoatNodes[BOAT_MOVING]));
+ pos = matrix.GetPosition();
+ matrix.SetRotateY(m_fMovingRotation);
+ matrix.Translate(pos);
+ matrix.UpdateRW();
+
+ CVector wind = CVector(0.707f, 0.707f, 0.0f) * (CWeather::Wind + 0.15f)*0.4f;
+ m_fMovingRotation += (m_vecMoveSpeed + wind).Magnitude()*CTimer::GetTimeStep();
}
+ }else if(GetModelIndex() == MI_PREDATOR || GetModelIndex() == MI_REEFER){
+ if (m_aBoatNodes[BOAT_MOVING] != nil) {
+ matrix.Attach(RwFrameGetMatrix(m_aBoatNodes[BOAT_MOVING]));
+
+ CVector pos = matrix.GetPosition();
+ matrix.SetRotateZ(m_fMovingRotation);
+ matrix.Translate(pos);
+
+ matrix.UpdateRW();
+ if (CVehicle::bWheelsOnlyCheat) {
+ RpAtomicRender((RpAtomic*)GetFirstObject(m_aBoatNodes[BOAT_MOVING]));
+ }
+ }
+ m_fMovingRotation += 0.02f * CTimer::GetTimeStep();
}
- m_fMovingRotation += 0.05f;
+}
+
+RwIm3DVertex KeepWaterOutVertices[4];
+RwImVertexIndex KeepWaterOutIndices[6];
+
+void
+CBoat::Render()
+{
((CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex()))->SetVehicleColour(m_currentColour1, m_currentColour2);
+ m_nSetPieceExtendedRangeTime = CTimer::GetTimeInMilliseconds() + 3000;
if (!CVehicle::bWheelsOnlyCheat)
CEntity::Render();
#ifdef NEW_RENDERER
if(!gbNewRenderer)
#endif
- RenderWaterOutPolys(); // not separate function in III
+ RenderWaterOutPolys(); // not separate function in VC
}
void
CBoat::RenderWaterOutPolys(void)
{
+ if(GetModelIndex() == MI_SKIMMER)
+ return;
KeepWaterOutIndices[0] = 0;
KeepWaterOutIndices[1] = 2;
KeepWaterOutIndices[2] = 1;
@@ -741,6 +1131,18 @@ CBoat::RenderWaterOutPolys(void)
RwIm3DVertexSetRGBA(&KeepWaterOutVertices[2], 255, 255, 255, 255);
RwIm3DVertexSetRGBA(&KeepWaterOutVertices[3], 255, 255, 255, 255);
switch (GetModelIndex()) {
+ case MI_RIO:
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[0], -1.3f, -1.016f, 0.51f);
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[1], 1.3f, -1.016f, 0.51f);
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[2], -1.3f, -2.832f, 0.51f);
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[3], 1.3f, -2.832f, 0.51f);
+ break;
+ case MI_SQUALO:
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[0], -1.222f, 2.004f, 0.846f);
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[1], 1.222f, 2.004f, 0.846f);
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[2], -1.24f, -1.367f, 0.846f);
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[3], 1.24f, -1.367f, 0.846f);
+ break;
case MI_SPEEDER:
RwIm3DVertexSetPos(&KeepWaterOutVertices[0], -1.15f, 3.61f, 1.03f);
RwIm3DVertexSetPos(&KeepWaterOutVertices[1], 1.15f, 3.61f, 1.03f);
@@ -754,12 +1156,37 @@ CBoat::RenderWaterOutPolys(void)
RwIm3DVertexSetPos(&KeepWaterOutVertices[3], 1.66f, -4.48f, 0.83f);
break;
case MI_PREDATOR:
- default:
RwIm3DVertexSetPos(&KeepWaterOutVertices[0], -1.45f, 1.9f, 0.96f);
RwIm3DVertexSetPos(&KeepWaterOutVertices[1], 1.45f, 1.9f, 0.96f);
RwIm3DVertexSetPos(&KeepWaterOutVertices[2], -1.45f, -3.75f, 0.96f);
RwIm3DVertexSetPos(&KeepWaterOutVertices[3], 1.45f, -3.75f, 0.96f);
break;
+ case MI_TROPIC:
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[0], -1.886f, -2.347f, 0.787f);
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[1], 1.886f, -2.347f, 0.787f);
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[2], -1.886f, -4.67f, 0.842f);
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[3], 1.886f, -4.67f, 0.842f);
+ break;
+ case MI_COASTG:
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[0], -0.663f, 3.565f, 0.382f);
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[1], 0.663f, 3.565f, 0.382f);
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[2], -1.087f, 0.83f, 0.381f);
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[3], 1.087f, 0.83f, 0.381f);
+ break;
+ case MI_DINGHY:
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[0], -0.797f, 1.641f, 0.573f);
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[1], 0.797f, 1.641f, 0.573f);
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[2], -0.865f, -1.444f, 0.509f);
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[3], 0.865f, -1.444f, 0.509f);
+ break;
+ case MI_MARQUIS:
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[0], -1.246f, -1.373f, 0.787f);
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[1], 1.246f, -1.373f, 0.787f);
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[2], -1.023f, -5.322f, 0.787f);
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[3], 1.023f, -5.322f, 0.787f);
+ break;
+ default:
+ return;
}
KeepWaterOutVertices[0].u = 0.0f;
KeepWaterOutVertices[0].v = 0.0f;
@@ -783,6 +1210,28 @@ CBoat::RenderWaterOutPolys(void)
RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, KeepWaterOutIndices, 6);
RwIm3DEnd();
}
+ bool drawAnotherRect = false;
+ if(GetModelIndex() == MI_COASTG){
+ drawAnotherRect = true;
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[0], -1.087f, 0.831f, 0.381f);
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[1], 1.087f, 0.831f, 0.381f);
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[2], -1.097f, -2.977f, 0.381f);
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[3], 1.097f, -2.977f, 0.381f);
+ }
+ if(drawAnotherRect){
+ KeepWaterOutVertices[0].u = 0.0f;
+ KeepWaterOutVertices[0].v = 0.0f;
+ KeepWaterOutVertices[1].u = 1.0f;
+ KeepWaterOutVertices[1].v = 0.0f;
+ KeepWaterOutVertices[2].u = 0.0f;
+ KeepWaterOutVertices[2].v = 1.0f;
+ KeepWaterOutVertices[3].u = 1.0f;
+ KeepWaterOutVertices[3].v = 1.0f;
+ if (!CVehicle::bWheelsOnlyCheat && RwIm3DTransform(KeepWaterOutVertices, 4, GetMatrix().m_attachment, rwIM3D_VERTEXUV)) {
+ RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, KeepWaterOutIndices, 6);
+ RwIm3DEnd();
+ }
+ }
#ifdef NEW_RENDERER
if(!gbNewRenderer)
#endif
@@ -804,6 +1253,7 @@ CBoat::Teleport(CVector v)
CWorld::Add(this);
}
+// unused
bool
CBoat::IsSectorAffectedByWake(CVector2D sector, float fSize, CBoat **apBoats)
{
@@ -835,6 +1285,7 @@ CBoat::IsSectorAffectedByWake(CVector2D sector, float fSize, CBoat **apBoats)
return numVerts != 0;
}
+// unused
float
CBoat::IsVertexAffectedByWake(CVector vecVertex, CBoat *pBoat)
{
@@ -871,22 +1322,35 @@ CBoat::FillBoatList()
apFrameWakeGeneratingBoats[1] = nil;
apFrameWakeGeneratingBoats[2] = nil;
apFrameWakeGeneratingBoats[3] = nil;
-
+ CVector2D camPos = TheCamera.GetPosition();
+ CVector2D camFwd = TheCamera.GetForward();
+ float camDist = camFwd.Magnitude();
+ if(camDist > 0.0f)
+ camFwd /= camDist;
for (int i = CPools::GetVehiclePool()->GetSize() - 1; i >= 0; i--) {
CBoat *boat = (CBoat *)(CPools::GetVehiclePool()->GetSlot(i));
if (boat && boat->m_vehType == VEHICLE_TYPE_BOAT) {
- int16 nNumWakePoints = boat->m_nNumWakePoints;
- if (nNumWakePoints != 0) {
+ if (boat->m_nNumWakePoints != 0) {
+ CVector2D camToBoat = CVector2D(boat->GetPosition()) - camPos;
+ float distToCam = DotProduct2D(camFwd, camToBoat);
+ if(distToCam > 100.0f || distToCam < -15.0f)
+ continue;
+ float distSq = camToBoat.MagnitudeSqr();
+ if(distSq > SQR(70.0f))
+ continue;
if (frameId >= ARRAY_SIZE(apFrameWakeGeneratingBoats)) {
+ float nearest = 999999.88f;
int16 frameId2 = -1;
for (int16 j = 0; j < ARRAY_SIZE(apFrameWakeGeneratingBoats); j++) {
- if (apFrameWakeGeneratingBoats[j]->m_nNumWakePoints < nNumWakePoints) {
+ float tmpDistSq = (CVector2D(apFrameWakeGeneratingBoats[j]->GetPosition()) - camPos).MagnitudeSqr();
+ if (tmpDistSq < nearest) {
+ nearest = tmpDistSq;
frameId2 = j;
- nNumWakePoints = apFrameWakeGeneratingBoats[j]->m_nNumWakePoints;
}
}
- if (frameId2 != -1)
+ if (frameId2 != -1 &&
+ (distSq < nearest || boat->GetStatus() == STATUS_PLAYER))
apFrameWakeGeneratingBoats[frameId2] = boat;
} else {
apFrameWakeGeneratingBoats[frameId++] = boat;
@@ -918,35 +1382,108 @@ CBoat::AddWakePoint(CVector point)
{
int i;
if(m_afWakePointLifeTime[0] > 0.0f){
- if((CVector2D(GetPosition()) - m_avec2dWakePoints[0]).MagnitudeSqr() < SQR(1.0f)){
- for(i = Min(m_nNumWakePoints, ARRAY_SIZE(m_afWakePointLifeTime)-1); i != 0; i--){
+ if((CVector2D(GetPosition()) - m_avec2dWakePoints[0]).MagnitudeSqr() < SQR(2.0f)) {
+ if(GetStatus() == STATUS_PLAYER){
+ if(m_nNumWakePoints >= 31)
+ m_nNumWakePoints = 31;
+ }else if(VehicleCreatedBy == MISSION_VEHICLE){
+ if(m_nNumWakePoints >= 20)
+ m_nNumWakePoints = 20;
+ }else{
+ if(m_nNumWakePoints >= 15)
+ m_nNumWakePoints = 15;
+ }
+ for(i = m_nNumWakePoints; i != 0; i--){
m_avec2dWakePoints[i] = m_avec2dWakePoints[i-1];
m_afWakePointLifeTime[i] = m_afWakePointLifeTime[i-1];
}
m_avec2dWakePoints[0] = point;
- m_afWakePointLifeTime[0] = 400.0f;
+ m_afWakePointLifeTime[0] = 150.0f;
if(m_nNumWakePoints < ARRAY_SIZE(m_afWakePointLifeTime))
m_nNumWakePoints++;
}
}else{
m_avec2dWakePoints[0] = point;
- m_afWakePointLifeTime[0] = 400.0f;
+ m_afWakePointLifeTime[0] = 150.0f;
m_nNumWakePoints = 1;
}
}
+void
+CBoat::DoDriveByShootings(void)
+{
+ CAnimBlendAssociation *anim = nil;
+ CPlayerInfo* playerInfo = ((CPlayerPed*)pDriver)->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 ||
+ TheCamera.m_bObbeCinematicCarCamOn){
+ 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_STD_CAR_DRIVEBY_RIGHT);
+ if(anim)
+ anim->blendDelta = -1000.0f;
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_STD_CAR_DRIVEBY_LEFT);
+ if(anim == nil || anim->blendDelta < 0.0f)
+ anim = CAnimManager::AddAnimation(pDriver->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_DRIVEBY_LEFT);
+ }else if(pDriver->m_pMyVehicle->pPassengers[0] == nil || TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON){
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_STD_CAR_DRIVEBY_LEFT);
+ if(anim)
+ anim->blendDelta = -1000.0f;
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_STD_CAR_DRIVEBY_RIGHT);
+ if(anim == nil || anim->blendDelta < 0.0f)
+ anim = CAnimManager::AddAnimation(pDriver->GetClump(), ASSOCGRP_STD, ANIM_STD_CAR_DRIVEBY_RIGHT);
+ }
+
+ if (!anim || !anim->IsRunning()) {
+ if (CPad::GetPad(0)->GetCarGunFired() && CTimer::GetTimeInMilliseconds() > weapon->m_nTimer) {
+ weapon->FireFromCar(this, lookingLeft, true);
+ weapon->m_nTimer = CTimer::GetTimeInMilliseconds() + 70;
+ }
+ }
+ }else{
+ weapon->Reload();
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_STD_CAR_DRIVEBY_LEFT);
+ if(anim)
+ anim->blendDelta = -1000.0f;
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_STD_CAR_DRIVEBY_RIGHT);
+ if(anim)
+ anim->blendDelta = -1000.0f;
+ }
+}
+
#ifdef COMPATIBLE_SAVES
void
CBoat::Save(uint8*& buf)
{
CVehicle::Save(buf);
- ZeroSaveBuf(buf, 1156 - 648);
+ ZeroSaveBuf(buf, 1216 - 672);
}
void
CBoat::Load(uint8*& buf)
{
CVehicle::Load(buf);
- SkipSaveBuf(buf, 1156 - 648);
+ SkipSaveBuf(buf, 1216 - 672);
}
#endif
diff --git a/src/vehicles/Boat.h b/src/vehicles/Boat.h
index 157b4852..5d866c48 100644
--- a/src/vehicles/Boat.h
+++ b/src/vehicles/Boat.h
@@ -1,33 +1,38 @@
#pragma once
#include "Vehicle.h"
+#include "Door.h"
enum eBoatNodes
{
BOAT_MOVING = 1,
- BOAT_RUDDER,
BOAT_WINDSCREEN,
+ BOAT_RUDDER,
+ BOAT_FLAP_LEFT,
+ BOAT_FLAP_RIGHT,
+ BOAT_REARFLAP_LEFT,
+ BOAT_REARFLAP_RIGHT,
NUM_BOAT_NODES
};
class CBoat : public CVehicle
{
public:
- // 0x288
- float m_fThrustZ;
- float m_fThrustY;
- CVector m_vecMoveRes;
- CVector m_vecTurnRes;
float m_fMovingRotation;
+ float m_fMovingSpeed;
int32 m_boat_unused1;
RwFrame *m_aBoatNodes[NUM_BOAT_NODES];
+ CDoor m_boom;
+ tBoatHandlingData *pBoatHandling;
uint8 bBoatInWater : 1;
uint8 bPropellerInWater : 1;
bool m_bIsAnchored;
float m_fOrientation;
+ uint32 m_nPoliceShoutTimer;
int32 m_boat_unused2;
float m_fDamage;
CEntity *m_pSetOnFireEntity;
+ float m_skimmerThingTimer;
bool m_boat_unused3;
float m_fAccelerate;
float m_fBrake;
@@ -42,23 +47,28 @@ public:
CVector2D m_avec2dWakePoints[32];
float m_afWakePointLifeTime[32];
+ static float MAX_WAKE_LENGTH;
+ static float MIN_WAKE_INTERVAL;
+ static float WAKE_LIFETIME;
+
CBoat(int, uint8);
virtual void SetModelIndex(uint32 id);
virtual void ProcessControl();
virtual void Teleport(CVector v);
- virtual void PreRender(void) {};
+ virtual void PreRender(void);
virtual void Render(void);
virtual void ProcessControlInputs(uint8);
virtual void GetComponentWorldPosition(int32 component, CVector &pos);
virtual bool IsComponentPresent(int32 component) { return true; }
virtual void BlowUpCar(CEntity *ent);
-
+
void RenderWaterOutPolys(void);
void ApplyWaterResistance(void);
void SetupModelNodes();
void PruneWakeTrail(void);
void AddWakePoint(CVector point);
+ void DoDriveByShootings(void);
static CBoat *apFrameWakeGeneratingBoats[4];
@@ -72,10 +82,4 @@ public:
#endif
static const uint32 nSaveStructSize;
-};
-
-VALIDATE_SIZE(CBoat, 0x484);
-
-extern float MAX_WAKE_LENGTH;
-extern float MIN_WAKE_INTERVAL;
-extern float WAKE_LIFETIME; \ No newline at end of file
+}; \ No newline at end of file
diff --git a/src/vehicles/CarGen.cpp b/src/vehicles/CarGen.cpp
index ebb767dd..bce8cdab 100644
--- a/src/vehicles/CarGen.cpp
+++ b/src/vehicles/CarGen.cpp
@@ -3,6 +3,7 @@
#include "CarGen.h"
#include "Automobile.h"
+#include "Bike.h"
#include "Boat.h"
#include "Camera.h"
#include "CarCtrl.h"
@@ -12,7 +13,10 @@
#include "Streaming.h"
#include "Timer.h"
#include "Vehicle.h"
+#include "VisibilityPlugins.h"
#include "World.h"
+#include "Zones.h"
+#include "Occlusion.h"
#include "SaveBuf.h"
uint8 CTheCarGenerators::ProcessCounter;
@@ -46,42 +50,50 @@ uint32 CCarGenerator::CalcNextGen()
void CCarGenerator::DoInternalProcessing()
{
- if (CheckForBlockage()) {
- m_nTimer += 4;
- if (m_nUsesRemaining == 0)
- --CTheCarGenerators::CurrentActiveCount;
- return;
- }
+ int mi;
if (CCarCtrl::NumParkedCars >= 10)
return;
- CStreaming::RequestModel(m_nModelIndex, STREAMFLAGS_DEPENDENCY);
- if (!CStreaming::HasModelLoaded(m_nModelIndex))
+ if (m_nModelIndex >= 0) {
+ if (CheckForBlockage(m_nModelIndex)) {
+ m_nTimer += 4;
+ return;
+ }
+ CStreaming::RequestModel(m_nModelIndex, STREAMFLAGS_DEPENDENCY);
+ mi = m_nModelIndex;
+ }
+ else {
+ mi = -m_nModelIndex;
+ if (m_nModelIndex == -1 || !CStreaming::HasModelLoaded(mi)) {
+ CZoneInfo pZone;
+ CVector pos = FindPlayerCoors();
+ CTheZones::GetZoneInfoForTimeOfDay(&pos, &pZone);
+ mi = CCarCtrl::ChooseCarModel(CCarCtrl::ChooseCarRating(&pZone));
+ if (mi < 0)
+ return;
+ m_nModelIndex = -mi;
+ m_nColor1 = -1;
+ m_nColor2 = -1;
+ }
+ if (CheckForBlockage(mi)) {
+ m_nTimer += 4;
+ return;
+ }
+ }
+ if (!CStreaming::HasModelLoaded(mi))
return;
- if (CModelInfo::IsBoatModel(m_nModelIndex)){
- CBoat* pBoat = new CBoat(m_nModelIndex, PARKED_VEHICLE);
- pBoat->SetIsStatic(false);
- pBoat->bEngineOn = false;
- CVector pos = m_vecPos;
+ CVehicle* pVehicle;
+
+ CVector pos;
+ if (CModelInfo::IsBoatModel(mi)){
+ CBoat* pBoat = new CBoat(mi, PARKED_VEHICLE);
+ pos = m_vecPos;
+ pVehicle = pBoat;
if (pos.z <= -100.0f)
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
- pos.z += pBoat->GetDistanceFromCentreOfMassToBaseOfModel();
- pBoat->SetPosition(pos);
- pBoat->SetOrientation(0.0f, 0.0f, DEGTORAD(m_fAngle));
- pBoat->SetStatus(STATUS_ABANDONED);
- pBoat->m_nDoorLock = CARLOCK_UNLOCKED;
- CWorld::Add(pBoat);
- if (CGeneral::GetRandomNumberInRange(0, 100) < m_nAlarm)
- pBoat->m_nAlarmState = -1;
- if (CGeneral::GetRandomNumberInRange(0, 100) < m_nDoorlock)
- pBoat->m_nDoorLock = CARLOCK_LOCKED;
- if (m_nColor1 != -1 && m_nColor2){
- pBoat->m_currentColour1 = m_nColor1;
- pBoat->m_currentColour2 = m_nColor2;
- }
- m_nVehicleHandle = CPools::GetVehiclePool()->GetIndex(pBoat);
+ pBoat->bExtendedRange = true;
}else{
bool groundFound;
- CVector pos = m_vecPos;
+ pos = m_vecPos;
if (pos.z > -100.0f){
pos.z = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z, &groundFound);
}else{
@@ -95,33 +107,43 @@ void CCarGenerator::DoInternalProcessing()
}
if (!groundFound) {
debug("CCarGenerator::DoInternalProcessing - can't find ground z for new car x = %f y = %f \n", m_vecPos.x, m_vecPos.y);
- }else{
- CAutomobile* pCar;
-
- // So game crashes if it's bike :D
- if (((CVehicleModelInfo*)CModelInfo::GetModelInfo(m_nModelIndex))->m_vehicleType != VEHICLE_TYPE_BIKE)
- pCar = new CAutomobile(m_nModelIndex, PARKED_VEHICLE);
-
- pCar->SetIsStatic(false);
- pCar->bEngineOn = false;
- pos.z += pCar->GetDistanceFromCentreOfMassToBaseOfModel();
- pCar->SetPosition(pos);
- pCar->SetOrientation(0.0f, 0.0f, DEGTORAD(m_fAngle));
- pCar->SetStatus(STATUS_ABANDONED);
- pCar->bLightsOn = false;
- pCar->m_nDoorLock = CARLOCK_UNLOCKED;
- CWorld::Add(pCar);
- if (CGeneral::GetRandomNumberInRange(0, 100) < m_nAlarm)
- pCar->m_nAlarmState = -1;
- if (CGeneral::GetRandomNumberInRange(0, 100) < m_nDoorlock)
- pCar->m_nDoorLock = CARLOCK_LOCKED;
- if (m_nColor1 != -1 && m_nColor2) {
- pCar->m_currentColour1 = m_nColor1;
- pCar->m_currentColour2 = m_nColor2;
- }
- m_nVehicleHandle = CPools::GetVehiclePool()->GetIndex(pCar);
+ return;
}
+ if (((CVehicleModelInfo*)CModelInfo::GetModelInfo(mi))->m_vehicleType == VEHICLE_TYPE_BIKE) {
+ CBike* pBike = new CBike(mi, PARKED_VEHICLE);
+ pBike->bIsStanding = true;
+ pVehicle = pBike;
+ }
+ else {
+ CAutomobile* pCar = new CAutomobile(mi, PARKED_VEHICLE);
+ pVehicle = pCar;
+ }
+ // pVehicle->GetDistanceFromCentreOfMassToBaseOfModel();
+ pVehicle->bLightsOn = false;
+ }
+ pVehicle->bIsStatic = false;
+ pVehicle->bEngineOn = false;
+ pos.z += pVehicle->GetDistanceFromCentreOfMassToBaseOfModel();
+ pVehicle->SetPosition(pos);
+ pVehicle->SetOrientation(0.0f, 0.0f, DEGTORAD(m_fAngle));
+ pVehicle->SetStatus(STATUS_ABANDONED);
+ pVehicle->m_nDoorLock = CARLOCK_UNLOCKED;
+ CWorld::Add(pVehicle);
+ if (CGeneral::GetRandomNumberInRange(0, 100) < m_nAlarm)
+ pVehicle->m_nAlarmState = -1;
+ if (CGeneral::GetRandomNumberInRange(0, 100) < m_nDoorlock)
+ pVehicle->m_nDoorLock = CARLOCK_LOCKED;
+ if (m_nColor1 != -1 && m_nColor2 != -1) {
+ pVehicle->m_currentColour1 = m_nColor1;
+ pVehicle->m_currentColour2 = m_nColor2;
}
+ else if (m_nModelIndex < -1) {
+ m_nColor1 = pVehicle->m_currentColour1;
+ m_nColor2 = pVehicle->m_currentColour2;
+ }
+ CVisibilityPlugins::SetClumpAlpha(pVehicle->GetClump(), 0);
+ m_nVehicleHandle = CPools::GetVehiclePool()->GetIndex(pVehicle);
+ /* I don't think this is a correct comparasion */
#ifdef FIX_BUGS
if (m_nUsesRemaining < UINT16_MAX)
--m_nUsesRemaining;
@@ -138,7 +160,7 @@ void CCarGenerator::Process()
{
if (m_nVehicleHandle == -1 &&
(CTheCarGenerators::GenerateEvenIfPlayerIsCloseCounter || CTimer::GetTimeInMilliseconds() >= m_nTimer) &&
- m_nUsesRemaining != 0 && CheckIfWithinRangeOfAnyPlayer())
+ m_nUsesRemaining != 0 && CheckIfWithinRangeOfAnyPlayers())
DoInternalProcessing();
if (m_nVehicleHandle == -1)
return;
@@ -153,6 +175,8 @@ void CCarGenerator::Process()
m_nVehicleHandle = -1;
m_bIsBlocking = true;
pVehicle->bExtendedRange = false;
+ if (m_nModelIndex < 0)
+ m_nModelIndex = -1;
}
void CCarGenerator::Setup(float x, float y, float z, float angle, int32 mi, int16 color1, int16 color2, uint8 force, uint8 alarm, uint8 lock, uint16 min_delay, uint16 max_delay)
@@ -172,25 +196,33 @@ void CCarGenerator::Setup(float x, float y, float z, float angle, int32 mi, int1
m_nTimer = CTimer::GetTimeInMilliseconds() + 1;
m_nUsesRemaining = 0;
m_bIsBlocking = false;
- m_vecInf = CModelInfo::GetColModel(m_nModelIndex)->boundingBox.min;
- m_vecSup = CModelInfo::GetColModel(m_nModelIndex)->boundingBox.max;
- m_fSize = Max(m_vecInf.Magnitude(), m_vecSup.Magnitude());
}
-bool CCarGenerator::CheckForBlockage()
+bool CCarGenerator::CheckForBlockage(int32 mi)
{
int16 entities;
- CWorld::FindObjectsKindaColliding(CVector(m_vecPos), m_fSize, 1, &entities, 2, nil, false, true, true, false, false);
- return entities > 0;
+ CEntity* pEntities[8];
+ CColModel* pColModel = CModelInfo::GetColModel(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_bIsBlocking = true;
+ return true;
+ }
+ }
+ return false;
}
-bool CCarGenerator::CheckIfWithinRangeOfAnyPlayer()
+bool CCarGenerator::CheckIfWithinRangeOfAnyPlayers()
{
CVector2D direction = FindPlayerCentreOfWorld(CWorld::PlayerInFocus) - m_vecPos;
float distance = direction.Magnitude();
- float farclip = 120.0f * TheCamera.GenerationDistMultiplier;
+ float farclip = 110.0f * TheCamera.GenerationDistMultiplier;
float nearclip = farclip - 20.0f;
- if (distance >= farclip){
+ bool canBeRemoved = (m_nModelIndex > 0 && CModelInfo::IsBoatModel(m_nModelIndex) && 165.0f * TheCamera.GenerationDistMultiplier > distance &&
+ TheCamera.IsSphereVisible(m_vecPos, 0.0f) && !COcclusion::IsPositionOccluded(m_vecPos, 0.0f));
+ if (distance >= farclip && !canBeRemoved){
if (m_bIsBlocking)
m_bIsBlocking = false;
return false;
@@ -199,7 +231,7 @@ bool CCarGenerator::CheckIfWithinRangeOfAnyPlayer()
return true;
if (m_bIsBlocking)
return false;
- if (distance < nearclip)
+ if (distance < nearclip && !m_bForceSpawn)
return false;
return DotProduct2D(direction, FindPlayerSpeed()) <= 0;
}
@@ -218,8 +250,9 @@ void CTheCarGenerators::Process()
int32 CTheCarGenerators::CreateCarGenerator(float x, float y, float z, float angle, int32 mi, int16 color1, int16 color2, uint8 force, uint8 alarm, uint8 lock, uint16 min_delay, uint16 max_delay)
{
- CarGeneratorArray[NumOfCarGenerators].Setup(x, y, z, angle, mi, color1, color2, force, alarm, lock, min_delay, max_delay);
- return NumOfCarGenerators++;
+ if (NumOfCarGenerators < NUM_CARGENS)
+ CarGeneratorArray[NumOfCarGenerators++].Setup(x, y, z, angle, mi, color1, color2, force, alarm, lock, min_delay, max_delay);
+ return NumOfCarGenerators - 1;
}
void CTheCarGenerators::Init()
@@ -251,6 +284,11 @@ VALIDATESAVEBUF(*size)
void CTheCarGenerators::LoadAllCarGenerators(uint8* buffer, uint32 size)
{
+ NumOfCarGenerators = 0;
+ GenerateEvenIfPlayerIsCloseCounter = 0;
+ CurrentActiveCount = 0;
+ ProcessCounter = 0;
+
const int32 nGeneralDataSize = sizeof(NumOfCarGenerators) + sizeof(CurrentActiveCount) + sizeof(ProcessCounter) + sizeof(GenerateEvenIfPlayerIsCloseCounter) + sizeof(int16);
Init();
INITSAVEBUF
diff --git a/src/vehicles/CarGen.h b/src/vehicles/CarGen.h
index 9d645318..fccbee96 100644
--- a/src/vehicles/CarGen.h
+++ b/src/vehicles/CarGen.h
@@ -22,9 +22,6 @@ class CCarGenerator
int32 m_nVehicleHandle;
uint16 m_nUsesRemaining;
bool m_bIsBlocking;
- CVector m_vecInf;
- CVector m_vecSup;
- float m_fSize;
public:
void SwitchOff();
void SwitchOn();
@@ -32,8 +29,8 @@ public:
void DoInternalProcessing();
void Process();
void Setup(float x, float y, float z, float angle, int32 mi, int16 color1, int16 color2, uint8 force, uint8 alarm, uint8 lock, uint16 min_delay, uint16 max_delay);
- bool CheckForBlockage();
- bool CheckIfWithinRangeOfAnyPlayer();
+ bool CheckForBlockage(int32 mi);
+ bool CheckIfWithinRangeOfAnyPlayers();
void SetUsesRemaining(uint16 uses) { m_nUsesRemaining = uses; }
};
diff --git a/src/vehicles/Cranes.cpp b/src/vehicles/Cranes.cpp
index db9d2e00..934ccb08 100644
--- a/src/vehicles/Cranes.cpp
+++ b/src/vehicles/Cranes.cpp
@@ -38,7 +38,7 @@
#define DEFAULT_OFFSET (20.0f)
#ifdef COMPATIBLE_SAVES
-#define CRANES_SAVE_SIZE 0x400
+#define CRANES_SAVE_SIZE 0x3E0
#else
#define CRANES_SAVE_SIZE sizeof(aCranes)
#endif
@@ -59,16 +59,22 @@ void CCranes::InitCranes(void)
CEntity* pEntity = (CEntity*)pNode->item;
if (MODELID_CRANE_1 == pEntity->GetModelIndex() ||
MODELID_CRANE_2 == pEntity->GetModelIndex() ||
- MODELID_CRANE_3 == pEntity->GetModelIndex())
+ MODELID_CRANE_3 == pEntity->GetModelIndex() ||
+ MODELID_CRANE_4 == pEntity->GetModelIndex() ||
+ MODELID_CRANE_5 == pEntity->GetModelIndex() ||
+ MODELID_CRANE_6 == pEntity->GetModelIndex())
AddThisOneCrane(pEntity);
}
}
}
- for (CPtrNode* pNode = CWorld::GetBigBuildingList(LEVEL_INDUSTRIAL).first; pNode; pNode = pNode->next) {
+ for (CPtrNode* pNode = CWorld::GetBigBuildingList(LEVEL_MAINLAND).first; pNode; pNode = pNode->next) {
CEntity* pEntity = (CEntity*)pNode->item;
if (MODELID_CRANE_1 == pEntity->GetModelIndex() ||
MODELID_CRANE_2 == pEntity->GetModelIndex() ||
- MODELID_CRANE_3 == pEntity->GetModelIndex())
+ MODELID_CRANE_3 == pEntity->GetModelIndex() ||
+ MODELID_CRANE_4 == pEntity->GetModelIndex() ||
+ MODELID_CRANE_5 == pEntity->GetModelIndex() ||
+ MODELID_CRANE_6 == pEntity->GetModelIndex())
AddThisOneCrane(pEntity);
}
}
@@ -90,23 +96,8 @@ void CCranes::AddThisOneCrane(CEntity* pEntity)
pCrane->m_nTimeForNextCheck = 0;
pCrane->m_nCraneState = CCrane::IDLE;
pCrane->m_bWasMilitaryCrane = false;
- pCrane->m_nAudioEntity = DMAudio.CreateEntity(AUDIOTYPE_CRANE, &aCranes[NumCranes]);
- if (pCrane->m_nAudioEntity >= 0)
- DMAudio.SetEntityStatus(pCrane->m_nAudioEntity, TRUE);
pCrane->m_bIsTop = (MODELID_CRANE_1 != pEntity->GetModelIndex());
- // Is this used to avoid military crane?
- if (pCrane->m_bIsTop || pEntity->GetPosition().y > 0.0f) {
- CObject* pHook = new CObject(MI_MAGNET, false);
- pHook->ObjectCreatedBy = MISSION_OBJECT;
- pHook->bUsesCollision = false;
- pHook->bExplosionProof = true;
- pHook->bAffectedByGravity = false;
- pCrane->m_pHook = pHook;
- pCrane->CalcHookCoordinates(&pCrane->m_vecHookCurPos.x, &pCrane->m_vecHookCurPos.y, &pCrane->m_vecHookCurPos.z);
- pCrane->SetHookMatrix();
- }
- else
- pCrane->m_pHook = nil;
+ pCrane->m_pHook = nil;
NumCranes++;
}
@@ -275,7 +266,6 @@ void CCrane::Update(void)
m_pVehiclePickedUp->bUsesCollision = false;
if (m_bIsCrusher)
m_pVehiclePickedUp->bCollisionProof = true;
- DMAudio.PlayOneShot(m_nAudioEntity, SOUND_CRANE_PICKUP, 0.0f);
}
}
}
@@ -455,8 +445,6 @@ bool CCrane::DoesCranePickUpThisCarType(uint32 mi)
mi != MI_TRASH &&
#ifdef FIX_BUGS
mi != MI_COACH &&
-#else
- mi != MI_BLISTA &&
#endif
mi != MI_SECURICA &&
mi != MI_BUS &&
@@ -467,7 +455,7 @@ bool CCrane::DoesCranePickUpThisCarType(uint32 mi)
return mi == MI_FIRETRUCK ||
mi == MI_AMBULAN ||
mi == MI_ENFORCER ||
- mi == MI_FBICAR ||
+ mi == MI_FBIRANCH ||
mi == MI_RHINO ||
mi == MI_BARRACKS ||
mi == MI_POLICE;
@@ -481,7 +469,7 @@ bool CCranes::DoesMilitaryCraneHaveThisOneAlready(uint32 mi)
case MI_FIRETRUCK: return (CarsCollectedMilitaryCrane & 1);
case MI_AMBULAN: return (CarsCollectedMilitaryCrane & 2);
case MI_ENFORCER: return (CarsCollectedMilitaryCrane & 4);
- case MI_FBICAR: return (CarsCollectedMilitaryCrane & 8);
+ case MI_FBIRANCH: return (CarsCollectedMilitaryCrane & 8);
case MI_RHINO: return (CarsCollectedMilitaryCrane & 0x10);
case MI_BARRACKS: return (CarsCollectedMilitaryCrane & 0x20);
case MI_POLICE: return (CarsCollectedMilitaryCrane & 0x40);
@@ -496,7 +484,7 @@ void CCranes::RegisterCarForMilitaryCrane(uint32 mi)
case MI_FIRETRUCK: CarsCollectedMilitaryCrane |= 1; break;
case MI_AMBULAN: CarsCollectedMilitaryCrane |= 2; break;
case MI_ENFORCER: CarsCollectedMilitaryCrane |= 4; break;
- case MI_FBICAR: CarsCollectedMilitaryCrane |= 8; break;
+ case MI_FBIRANCH: CarsCollectedMilitaryCrane |= 8; break;
case MI_RHINO: CarsCollectedMilitaryCrane |= 0x10; break;
case MI_BARRACKS: CarsCollectedMilitaryCrane |= 0x20; break;
case MI_POLICE: CarsCollectedMilitaryCrane |= 0x40; break;
@@ -649,7 +637,6 @@ void CCranes::Save(uint8* buf, uint32* size)
WriteSaveBuf(buf, tmp);
tmp = aCranes[i].m_pHook != nil ? CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(aCranes[i].m_pHook) + 1 : 0;
WriteSaveBuf(buf, tmp);
- WriteSaveBuf(buf, aCranes[i].m_nAudioEntity);
WriteSaveBuf(buf, aCranes[i].m_fPickupX1);
WriteSaveBuf(buf, aCranes[i].m_fPickupX2);
WriteSaveBuf(buf, aCranes[i].m_fPickupY1);
@@ -706,34 +693,33 @@ void CCranes::Load(uint8* buf, uint32 size)
aCranes[i].m_pCraneEntity = tmp != 0 ? CPools::GetBuildingPool()->GetSlot(tmp - 1) : nil;
ReadSaveBuf(&tmp, buf);
aCranes[i].m_pHook = tmp != 0 ? CPools::GetObjectPool()->GetSlot(tmp - 1) : nil;
- ReadSaveBuf(&aCranes[i].m_nAudioEntity, buf);
- ReadSaveBuf(&aCranes[i].m_fPickupX1, buf);
- ReadSaveBuf(&aCranes[i].m_fPickupX2, buf);
- ReadSaveBuf(&aCranes[i].m_fPickupY1, buf);
- ReadSaveBuf(&aCranes[i].m_fPickupY2, buf);
- ReadSaveBuf(&aCranes[i].m_vecDropoffTarget, buf);
- ReadSaveBuf(&aCranes[i].m_fDropoffHeading, buf);
- ReadSaveBuf(&aCranes[i].m_fPickupAngle, buf);
- ReadSaveBuf(&aCranes[i].m_fDropoffAngle, buf);
- ReadSaveBuf(&aCranes[i].m_fPickupDistance, buf);
- ReadSaveBuf(&aCranes[i].m_fDropoffDistance, buf);
- ReadSaveBuf(&aCranes[i].m_fPickupHeight, buf);
- ReadSaveBuf(&aCranes[i].m_fDropoffHeight, buf);
- ReadSaveBuf(&aCranes[i].m_fHookAngle, buf);
- ReadSaveBuf(&aCranes[i].m_fHookOffset, buf);
- ReadSaveBuf(&aCranes[i].m_fHookHeight, buf);
- ReadSaveBuf(&aCranes[i].m_vecHookInitPos, buf);
- ReadSaveBuf(&aCranes[i].m_vecHookCurPos, buf);
+ ReadSaveBuf(&aCranes[i].m_fPickupX1, buf);
+ ReadSaveBuf(&aCranes[i].m_fPickupX2, buf);
+ ReadSaveBuf(&aCranes[i].m_fPickupY1, buf);
+ ReadSaveBuf(&aCranes[i].m_fPickupY2, buf);
+ ReadSaveBuf(&aCranes[i].m_vecDropoffTarget, buf);
+ ReadSaveBuf(&aCranes[i].m_fDropoffHeading, buf);
+ ReadSaveBuf(&aCranes[i].m_fPickupAngle, buf);
+ ReadSaveBuf(&aCranes[i].m_fDropoffAngle, buf);
+ ReadSaveBuf(&aCranes[i].m_fPickupDistance, buf);
+ ReadSaveBuf(&aCranes[i].m_fDropoffDistance, buf);
+ ReadSaveBuf(&aCranes[i].m_fPickupHeight, buf);
+ ReadSaveBuf(&aCranes[i].m_fDropoffHeight, buf);
+ ReadSaveBuf(&aCranes[i].m_fHookAngle, buf);
+ ReadSaveBuf(&aCranes[i].m_fHookOffset, buf);
+ ReadSaveBuf(&aCranes[i].m_fHookHeight, buf);
+ ReadSaveBuf(&aCranes[i].m_vecHookInitPos, buf);
+ ReadSaveBuf(&aCranes[i].m_vecHookCurPos, buf);
ReadSaveBuf(&aCranes[i].m_vecHookVelocity, buf);
ReadSaveBuf(&tmp, buf);
aCranes[i].m_pVehiclePickedUp = tmp != 0 ? CPools::GetVehiclePool()->GetSlot(tmp - 1) : nil;
- ReadSaveBuf(&aCranes[i].m_nTimeForNextCheck, buf);
- ReadSaveBuf(&aCranes[i].m_nCraneStatus, buf);
- ReadSaveBuf(&aCranes[i].m_nCraneState, buf);
- ReadSaveBuf(&aCranes[i].m_nVehiclesCollected, buf);
- ReadSaveBuf(&aCranes[i].m_bIsCrusher, buf);
- ReadSaveBuf(&aCranes[i].m_bIsMilitaryCrane, buf);
- ReadSaveBuf(&aCranes[i].m_bWasMilitaryCrane, buf);
+ ReadSaveBuf(&aCranes[i].m_nTimeForNextCheck, buf);
+ ReadSaveBuf(&aCranes[i].m_nCraneStatus, buf);
+ ReadSaveBuf(&aCranes[i].m_nCraneState, buf);
+ ReadSaveBuf(&aCranes[i].m_nVehiclesCollected, buf);
+ ReadSaveBuf(&aCranes[i].m_bIsCrusher, buf);
+ ReadSaveBuf(&aCranes[i].m_bIsMilitaryCrane, buf);
+ ReadSaveBuf(&aCranes[i].m_bWasMilitaryCrane, buf);
ReadSaveBuf(&aCranes[i].m_bIsTop, buf);
SkipSaveBuf(buf, 1);
#else
@@ -749,11 +735,6 @@ void CCranes::Load(uint8* buf, uint32 size)
pCrane->m_pVehiclePickedUp = CPools::GetVehiclePool()->GetSlot((uintptr)pCrane->m_pVehiclePickedUp - 1);
#endif
}
- for (int i = 0; i < NUM_CRANES; i++) {
- aCranes[i].m_nAudioEntity = DMAudio.CreateEntity(AUDIOTYPE_CRANE, &aCranes[i]);
- if (aCranes[i].m_nAudioEntity != 0)
- DMAudio.SetEntityStatus(aCranes[i].m_nAudioEntity, TRUE);
- }
VALIDATESAVEBUF(size);
}
diff --git a/src/vehicles/Cranes.h b/src/vehicles/Cranes.h
index e9178105..e842ed3f 100644
--- a/src/vehicles/Cranes.h
+++ b/src/vehicles/Cranes.h
@@ -26,7 +26,6 @@ public:
};
CBuilding *m_pCraneEntity;
CObject *m_pHook;
- int32 m_nAudioEntity;
float m_fPickupX1;
float m_fPickupX2;
float m_fPickupY1;
diff --git a/src/vehicles/DamageManager.cpp b/src/vehicles/DamageManager.cpp
index 56034dee..8ba235b7 100644
--- a/src/vehicles/DamageManager.cpp
+++ b/src/vehicles/DamageManager.cpp
@@ -10,14 +10,20 @@ float G_aComponentDamage[] = { 2.5f, 1.25f, 3.2f, 1.4f, 2.5f, 2.8f, 0.5f };
CDamageManager::CDamageManager(void)
{
ResetDamageStatus();
- m_fWheelDamageEffect = 0.75f;
+ m_fWheelDamageEffect = 0.5f;
field_18 = 1;
}
void
CDamageManager::ResetDamageStatus(void)
{
- memset(this, 0, sizeof(*this));
+ int i;
+ m_fWheelDamageEffect = 0.0f;
+ m_engineStatus = 0;
+ for(i = 0; i < ARRAY_SIZE(m_wheelStatus); i++) m_wheelStatus[i] = 0;
+ for(i = 0; i < ARRAY_SIZE(m_doorStatus); i++) m_doorStatus[i] = 0;
+ m_lightStatus = 0;
+ m_panelStatus = 0;
}
void
@@ -57,6 +63,8 @@ CDamageManager::ApplyDamage(tComponent component, float damage, float unused)
GetComponentGroup(component, &group, &subComp);
damage *= G_aComponentDamage[group];
+ if(component == COMPONENT_PANEL_WINDSCREEN)
+ damage *= 0.6f;
if(damage > 150.0f){
switch(group){
case COMPGROUP_WHEEL:
@@ -220,10 +228,6 @@ CDamageManager::GetEngineStatus(void)
bool
CDamageManager::ProgressEngineDamage(void)
{
- int status = GetEngineStatus();
- int newstatus = status + 32 + (CGeneral::GetRandomNumber() & 0x1F);
- if(status < ENGINE_STATUS_ON_FIRE && newstatus > ENGINE_STATUS_ON_FIRE-1)
- newstatus = ENGINE_STATUS_ON_FIRE-1;
- SetEngineStatus(newstatus);
- return true;
+ // gone in VC
+ return false;
}
diff --git a/src/vehicles/Floater.cpp b/src/vehicles/Floater.cpp
index 4331090d..08688a3c 100644
--- a/src/vehicles/Floater.cpp
+++ b/src/vehicles/Floater.cpp
@@ -16,9 +16,29 @@ float fBoatVolumeDistribution[9] = {
// rear
0.75f, 0.9f, 0.75f,
0.95f, 1.0f, 0.95f,
- 0.3f, 0.7f, 0.3f
+ 0.4f, 0.7f, 0.4f
// bow
};
+float fBoatVolumeDistributionCat[9] = {
+ 0.9f, 0.3f, 0.9f,
+ 1.0f, 0.5f, 1.0f,
+ 0.95f, 0.4f, 0.95f
+};
+float fBoatVolumeDistributionSail[9] = {
+ 0.55f, 0.95f, 0.55f,
+ 0.75f, 1.1f, 0.75f,
+ 0.3f, 0.8f, 0.3f
+};
+float fBoatVolumeDistributionDinghy[9] = {
+ 0.65f, 0.85f, 0.65f,
+ 0.85f, 1.1f, 0.85f,
+ 0.65f, 0.95f, 0.65f
+};
+float fBoatVolumeDistributionSpeed[9] = {
+ 0.7f, 0.9f, 0.7f,
+ 0.95f, 1.0f, 0.95f,
+ 0.6f, 0.7f, 0.6f
+};
bool
cBuoyancy::ProcessBuoyancy(CPhysical *phys, float buoyancy, CVector *point, CVector *impulse)
@@ -37,6 +57,76 @@ cBuoyancy::ProcessBuoyancy(CPhysical *phys, float buoyancy, CVector *point, CVec
return f != 0.0f;
}
+bool
+cBuoyancy::ProcessBuoyancyBoat(CVehicle *veh, float buoyancy, CVector *point, CVector *impulse, bool bNoTurnForce)
+{
+ m_numSteps = 2.0f;
+
+ if(!CWaterLevel::GetWaterLevel(veh->GetPosition(), &m_waterlevel, veh->bTouchingWater))
+ return false;
+ m_matrix = veh->GetMatrix();
+ PreCalcSetup(veh, buoyancy);
+
+
+ float x, y;
+ int ix, i;
+ tWaterLevel waterPosition;
+ CVector waterNormal;
+
+ // Floater is divided into 3x3 parts. Process and sum each of them
+ float volDiv = 1.0f/((m_dimMax.z - m_dimMin.z)*sq(m_numSteps+1.0f));
+ ix = 0;
+ for(x = m_dimMin.x; x <= m_dimMax.x; x += m_step.x){
+ i = ix;
+ for(y = m_dimMin.y; y <= m_dimMax.y; y += m_step.y){
+ CVector waterLevel(x, y, 0.0f);
+ FindWaterLevelNorm(m_positionZ, &waterLevel, &waterPosition, &waterNormal);
+ switch(veh->GetModelIndex()){
+ case MI_RIO:
+ fVolMultiplier = fBoatVolumeDistributionCat[i];
+ break;
+ case MI_SQUALO:
+ case MI_SPEEDER:
+ case MI_JETMAX:
+ fVolMultiplier = fBoatVolumeDistributionSpeed[i];
+ break;
+ case MI_COASTG:
+ case MI_DINGHY:
+ fVolMultiplier = fBoatVolumeDistributionDinghy[i];
+ break;
+ case MI_MARQUIS:
+ fVolMultiplier = fBoatVolumeDistributionSail[i];
+ break;
+ case MI_PREDATOR:
+ case MI_SKIMMER:
+ case MI_REEFER:
+ case MI_TROPIC:
+ default:
+ fVolMultiplier = fBoatVolumeDistribution[i];
+ break;
+ }
+ if(waterPosition != FLOATER_ABOVE_WATER){
+ float volume = SimpleSumBuoyancyData(waterLevel, waterPosition);
+ float upImpulse = volume * volDiv * buoyancy * CTimer::GetTimeStep();
+ CVector speed = veh->GetSpeed(Multiply3x3(veh->GetMatrix(), CVector(x, y, 0.0f)));
+ float damp = 1.0f - DotProduct(speed, waterNormal)*veh->pHandling->fSuspensionDampingLevel;
+ float finalImpulse = upImpulse*Max(damp, 0.0f);
+ impulse->z += finalImpulse;
+ if(!bNoTurnForce)
+ veh->ApplyTurnForce(finalImpulse*waterNormal, Multiply3x3(m_matrix, waterLevel));
+ }
+ i += 3;
+ }
+ ix++;
+ }
+
+ m_volumeUnderWater *= volDiv;
+
+ *point = Multiply3x3(m_matrix, m_impulsePoint);
+ return m_isBoat || m_haveVolume;
+
+}
+
void
cBuoyancy::PreCalcSetup(CPhysical *phys, float buoyancy)
{
@@ -48,17 +138,55 @@ cBuoyancy::PreCalcSetup(CPhysical *phys, float buoyancy)
m_dimMax = colModel->boundingBox.max;
if(m_isBoat){
- if(phys->GetModelIndex() == MI_PREDATOR){
+ switch(phys->GetModelIndex()){
+ case MI_PREDATOR:
+ default:
+ m_dimMax.y *= 1.05f;
+ m_dimMin.y *= 0.9f;
+ break;
+ case MI_SPEEDER:
+ m_dimMax.y *= 1.25f;
+ m_dimMin.y *= 0.83f;
+ break;
+ case MI_REEFER:
+ m_dimMin.y *= 0.9f;
+ break;
+ case MI_RIO:
m_dimMax.y *= 0.9f;
m_dimMin.y *= 0.9f;
- }else if(phys->GetModelIndex() == MI_SPEEDER){
+ m_dimMax.z += 0.25f;
+ m_dimMin.z -= 0.2f;
+ break;
+ case MI_SQUALO:
+ m_dimMax.y *= 0.9f;
+ m_dimMin.y *= 0.9f;
+ break;
+ case MI_TROPIC:
+ m_dimMax.y *= 1.3f;
+ m_dimMin.y *= 0.82f;
+ m_dimMin.z -= 0.2f;
+ break;
+ case MI_SKIMMER:
+ m_dimMin.y = -m_dimMax.y;
+ m_dimMax.y *= 1.2f;
+ break;
+ case MI_COASTG:
m_dimMax.y *= 1.1f;
m_dimMin.y *= 0.9f;
- }else if(phys->GetModelIndex() == MI_REEFER){
+ m_dimMin.z -= 0.3f;
+ break;
+ case MI_DINGHY:
+ m_dimMax.y *= 1.3f;
m_dimMin.y *= 0.9f;
- }else{
- m_dimMax.y *= 0.9f;
+ m_dimMin.z -= 0.2f;
+ break;
+ case MI_MARQUIS:
+ m_dimMax.y *= 1.3f;
+ m_dimMin.y *= 0.9f;
+ break;
+ case MI_JETMAX:
m_dimMin.y *= 0.9f;
+ break;
}
}
@@ -92,22 +220,17 @@ void
cBuoyancy::SimpleCalcBuoyancy(void)
{
float x, y;
- int ix, i;
tWaterLevel waterPosition;
// Floater is divided into 3x3 parts. Process and sum each of them
- ix = 0;
for(x = m_dimMin.x; x <= m_dimMax.x; x += m_step.x){
- i = ix;
for(y = m_dimMin.y; y <= m_dimMax.y; y += m_step.y){
CVector waterLevel(x, y, 0.0f);
FindWaterLevel(m_positionZ, &waterLevel, &waterPosition);
- fVolMultiplier = m_isBoat ? fBoatVolumeDistribution[i] : 1.0f;
+ fVolMultiplier = 1.0f;
if(waterPosition != FLOATER_ABOVE_WATER)
SimpleSumBuoyancyData(waterLevel, waterPosition);
- i += 3;
}
- ix++;
}
m_volumeUnderWater /= (m_dimMax.z - m_dimMin.z)*sq(m_numSteps+1.0f);
@@ -129,10 +252,6 @@ cBuoyancy::SimpleSumBuoyancyData(CVector &waterLevel, tWaterLevel waterPosition)
if(m_isBoat){
fThisVolume *= fVolMultiplier;
- if(fThisVolume < 0.5f)
- fThisVolume = 2.0f*sq(fThisVolume);
- if(fThisVolume < 1.0f)
- fThisVolume = sq(fThisVolume);
fThisVolume = sq(fThisVolume);
}
@@ -173,6 +292,26 @@ cBuoyancy::FindWaterLevel(const CVector &zpos, CVector *waterLevel, tWaterLevel
}
}
+// Same as above but also get normal
+void
+cBuoyancy::FindWaterLevelNorm(const CVector &zpos, CVector *waterLevel, tWaterLevel *waterPosition, CVector *normal)
+{
+ *waterPosition = FLOATER_IN_WATER;
+ CVector xWaterLevel = Multiply3x3(m_matrix, *waterLevel);
+ CWaterLevel::GetWaterLevel(xWaterLevel.x + m_position.x, xWaterLevel.y + m_position.y, m_position.z,
+ &waterLevel->z, true);
+ waterLevel->z -= xWaterLevel.z + zpos.z; // make local
+ if(waterLevel->z >= m_dimMin.z)
+ *normal = CWaterLevel::GetWaterNormal(xWaterLevel.x + m_position.x, xWaterLevel.y + m_position.y);
+ if(waterLevel->z > m_dimMax.z){
+ waterLevel->z = m_dimMax.z;
+ *waterPosition = FLOATER_UNDER_WATER;
+ }else if(waterLevel->z < m_dimMin.z){
+ waterLevel->z = m_dimMin.z;
+ *waterPosition = FLOATER_ABOVE_WATER;
+ }
+}
+
bool
cBuoyancy::CalcBuoyancyForce(CPhysical *phys, CVector *point, CVector *impulse)
{
diff --git a/src/vehicles/Floater.h b/src/vehicles/Floater.h
index 1cfb46fb..91ab70ae 100644
--- a/src/vehicles/Floater.h
+++ b/src/vehicles/Floater.h
@@ -36,10 +36,12 @@ public:
CVector m_impulsePoint;
bool ProcessBuoyancy(CPhysical *phys, float buoyancy, CVector *point, CVector *impulse);
+ bool ProcessBuoyancyBoat(CVehicle *phys, float buoyancy, CVector *point, CVector *impulse, bool bNoTurnForce);
void PreCalcSetup(CPhysical *phys, float buoyancy);
void SimpleCalcBuoyancy(void);
float SimpleSumBuoyancyData(CVector &waterLevel, tWaterLevel waterPosition);
void FindWaterLevel(const CVector &zpos, CVector *waterLevel, tWaterLevel *waterPosition);
+ void FindWaterLevelNorm(const CVector &zpos, CVector *waterLevel, tWaterLevel *waterPosition, CVector *normal);
bool CalcBuoyancyForce(CPhysical *phys, CVector *impulse, CVector *point);
};
extern cBuoyancy mod_Buoyancy;
diff --git a/src/vehicles/HandlingMgr.cpp b/src/vehicles/HandlingMgr.cpp
index 00aaa682..8438c5c9 100644
--- a/src/vehicles/HandlingMgr.cpp
+++ b/src/vehicles/HandlingMgr.cpp
@@ -22,7 +22,6 @@ const char VehicleNames[NUMHANDLINGS][14] = {
"STRETCH",
"MANANA",
"INFERNUS",
- "BLISTA",
"PONY",
"MULE",
"CHEETAH",
@@ -39,7 +38,6 @@ const char VehicleNames[NUMHANDLINGS][14] = {
"ENFORCER",
"SECURICA",
"BANSHEE",
- "PREDATOR",
"BUS",
"RHINO",
"BARRACKS",
@@ -51,22 +49,73 @@ const char VehicleNames[NUMHANDLINGS][14] = {
"STALLION",
"RUMPO",
"RCBANDIT",
- "BELLYUP",
- "MRWONGS",
"MAFIA",
- "YARDIE",
- "YAKUZA",
- "DIABLOS",
- "COLUMB",
- "HOODS",
"AIRTRAIN",
"DEADDODO",
- "SPEEDER",
- "REEFER",
- "PANLANT",
"FLATBED",
"YANKEE",
- "BORGNINE"
+ "GOLFCART",
+ "VOODOO",
+ "WASHING",
+ "CUBAN",
+ "ROMERO",
+ "PACKER",
+ "ADMIRAL",
+ "GANGBUR",
+ "ZEBRA",
+ "TOPFUN",
+ "GLENDALE",
+ "OCEANIC",
+ "HERMES",
+ "SABRE1",
+ "SABRETUR",
+ "PHEONIX",
+ "WALTON",
+ "REGINA",
+ "COMET",
+ "DELUXO",
+ "BURRITO",
+ "SPAND",
+ "BAGGAGE",
+ "KAUFMAN",
+ "RANCHER",
+ "FBIRANCH",
+ "VIRGO",
+ "GREENWOO",
+ "HOTRING",
+ "SANDKING",
+ "BLISTAC",
+ "BOXVILLE",
+ "BENSON",
+ "DESPERAD",
+ "LOVEFIST",
+ "BLOODRA",
+ "BLOODRB",
+ "BIKE",
+ "MOPED",
+ "DIRTBIKE",
+ "ANGEL",
+ "FREEWAY",
+ "PREDATOR",
+ "SPEEDER",
+ "REEFER",
+ "RIO",
+ "SQUALO",
+ "TROPIC",
+ "COASTGRD",
+ "DINGHY",
+ "MARQUIS",
+ "CUPBOAT",
+ "SEAPLANE",
+ "SPARROW",
+ "SEASPAR",
+ "MAVERICK",
+ "COASTMAV",
+ "POLMAV",
+ "HUNTER",
+ "RCBARON",
+ "RCGOBLIN",
+ "RCCOPTER"
};
cHandlingDataMgr::cHandlingDataMgr(void)
@@ -95,6 +144,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");
@@ -103,6 +155,9 @@ cHandlingDataMgr::LoadHandlingData(void)
start = (char*)work_buff;
end = start+1;
handling = nil;
+ flyingHandling = nil;
+ boatHandling = nil;
+ bikeHandling = nil;
keepGoing = 1;
while(keepGoing){
@@ -119,55 +174,157 @@ cHandlingDataMgr::LoadHandlingData(void)
if(strcmp(line, ";the end") == 0)
keepGoing = 0;
else if(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 = (tVehicleType)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.4; 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:
- sscanf(word, "%x", &handling->Flags);
- handling->Transmission.Flags = handling->Flags;
- break;
- case 30: handling->FrontLights = atoi(word); break;
- case 31: handling->RearLights = atoi(word); break;
+ 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 = (tVehicleType)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 = (tVehicleType)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 = (tVehicleType)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 = (tVehicleType)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.4; 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);
}
}
}
@@ -190,7 +347,7 @@ cHandlingDataMgr::FindExactWord(const char *word, const char *words, int wordLen
void
cHandlingDataMgr::ConvertDataToGameUnits(tHandlingData *handling)
{
- // acceleration is in ms^-2, but we need mf^-2 where f is one frame time (50fps)
+ // convert distance to m, time to 1/50s
float velocity, a, b;
handling->Transmission.fEngineAcceleration *= 1.0f/(50.0f*50.0f);
@@ -200,6 +357,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 * GRAVITY*handling->fMass;
// Don't quite understand this. What seems to be going on is that
@@ -221,11 +379,16 @@ cHandlingDataMgr::ConvertDataToGameUnits(tHandlingData *handling)
if(handling->nIdentifier == HANDLING_RCBANDIT){
handling->Transmission.fMaxCruiseVelocity = handling->Transmission.fMaxVelocity;
+ handling->Transmission.fMaxReverseVelocity = -handling->Transmission.fMaxVelocity;
+ }else if(handling->nIdentifier >= HANDLING_BIKE && handling->nIdentifier <= HANDLING_FREEWAY){
+ handling->Transmission.fMaxCruiseVelocity = velocity;
+ handling->Transmission.fMaxVelocity = velocity * 1.2f;
+ handling->Transmission.fMaxReverseVelocity = -0.05f;
}else{
handling->Transmission.fMaxCruiseVelocity = 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;
@@ -235,6 +398,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)
{
@@ -245,26 +417,18 @@ cHandlingDataMgr::GetHandlingId(const char *name)
return i;
}
-void
-cHandlingDataMgr::ConvertDataToWorldUnits(tHandlingData *handling)
-{
- // TODO: mobile code
-}
-
-void
-cHandlingDataMgr::RangeCheck(tHandlingData *handling)
+tFlyingHandlingData*
+cHandlingDataMgr::GetFlyingPointer(uint8 id)
{
- // TODO: mobile code
+ if(id >= HANDLING_SEAPLANE && id <= HANDLING_RCCOPTER)
+ return &FlyingHandlingData[id-HANDLING_SEAPLANE];
+ return &FlyingHandlingData[0];
}
-void
-cHandlingDataMgr::ModifyHandlingValue(CVehicle *, const tVehicleType &, const tField &, const bool &)
+tBoatHandlingData*
+cHandlingDataMgr::GetBoatPointer(uint8 id)
{
- // TODO: mobile code
+ if(id >= HANDLING_PREDATOR && id <= HANDLING_SEAPLANE)
+ return &BoatHandlingData[id-HANDLING_PREDATOR];
+ return &BoatHandlingData[0];
}
-
-void
-cHandlingDataMgr::DisplayHandlingData(CVehicle *, tHandlingData *, uint8, bool)
-{
- // TODO: mobile code
-} \ No newline at end of file
diff --git a/src/vehicles/HandlingMgr.h b/src/vehicles/HandlingMgr.h
index 9848bb74..8d290f7d 100644
--- a/src/vehicles/HandlingMgr.h
+++ b/src/vehicles/HandlingMgr.h
@@ -16,7 +16,6 @@ enum tVehicleType
HANDLING_STRETCH,
HANDLING_MANANA,
HANDLING_INFERNUS,
- HANDLING_BLISTA,
HANDLING_PONY,
HANDLING_MULE,
HANDLING_CHEETAH,
@@ -33,7 +32,6 @@ enum tVehicleType
HANDLING_ENFORCER,
HANDLING_SECURICA,
HANDLING_BANSHEE,
- HANDLING_PREDATOR,
HANDLING_BUS,
HANDLING_RHINO,
HANDLING_BARRACKS,
@@ -45,24 +43,81 @@ enum tVehicleType
HANDLING_STALLION,
HANDLING_RUMPO,
HANDLING_RCBANDIT,
- HANDLING_BELLYUP,
- HANDLING_MRWONGS,
HANDLING_MAFIA,
- HANDLING_YARDIE,
- HANDLING_YAKUZA,
- HANDLING_DIABLOS,
- HANDLING_COLUMB,
- HANDLING_HOODS,
HANDLING_AIRTRAIN,
HANDLING_DEADDODO,
- HANDLING_SPEEDER,
- HANDLING_REEFER,
- HANDLING_PANLANT,
HANDLING_FLATBED,
HANDLING_YANKEE,
- HANDLING_BORGNINE,
+ HANDLING_GOLFCART,
+ HANDLING_VOODOO,
+ HANDLING_WASHING,
+ HANDLING_CUBAN,
+ HANDLING_ROMERO,
+ HANDLING_PACKER,
+ HANDLING_ADMIRAL,
+ HANDLING_GANGBUR,
+ HANDLING_ZEBRA,
+ HANDLING_TOPFUN,
+ HANDLING_GLENDALE,
+ HANDLING_OCEANIC,
+ HANDLING_HERMES,
+ HANDLING_SABRE1,
+ HANDLING_SABRETUR,
+ HANDLING_PHEONIX,
+ HANDLING_WALTON,
+ HANDLING_REGINA,
+ HANDLING_COMET,
+ HANDLING_DELUXO,
+ HANDLING_BURRITO,
+ HANDLING_SPAND,
+ HANDLING_BAGGAGE,
+ HANDLING_KAUFMAN,
+ HANDLING_RANCHER,
+ HANDLING_FBIRANCH,
+ HANDLING_VIRGO,
+ HANDLING_GREENWOO,
+ HANDLING_HOTRING,
+ HANDLING_SANDKING,
+ HANDLING_BLISTAC,
+ HANDLING_BOXVILLE,
+ HANDLING_BENSON,
+ HANDLING_DESPERAD,
+ HANDLING_LOVEFIST,
+ HANDLING_BLOODRA,
+ HANDLING_BLOODRB,
- NUMHANDLINGS
+ HANDLING_BIKE,
+ HANDLING_MOPED,
+ HANDLING_DIRTBIKE,
+ HANDLING_ANGEL,
+ HANDLING_FREEWAY,
+
+ HANDLING_PREDATOR,
+ HANDLING_SPEEDER,
+ HANDLING_REEFER,
+ HANDLING_RIO,
+ HANDLING_SQUALO,
+ HANDLING_TROPIC,
+ HANDLING_COASTGRD,
+ HANDLING_DINGHY,
+ HANDLING_MARQUIS,
+ HANDLING_CUPBOAT,
+ HANDLING_SEAPLANE, // both boat and plane!
+ HANDLING_SPARROW,
+ HANDLING_SEASPAR,
+ HANDLING_MAVERICK,
+ HANDLING_COASTMAV,
+ HANDLING_POLMAV,
+ HANDLING_HUNTER,
+ HANDLING_RCBARON,
+ HANDLING_RCGOBLIN,
+ HANDLING_RCCOPTER,
+
+ NUMHANDLINGS,
+
+ NUMBIKEHANDLINGS = HANDLING_FREEWAY+1 - HANDLING_BIKE,
+ NUMFLYINGHANDLINGS = HANDLING_RCCOPTER+1 - HANDLING_SEAPLANE,
+ NUMBOATHANDLINGS = HANDLING_SEAPLANE+1 - HANDLING_PREDATOR,
};
enum tField // most likely a handling field enum, never used so :shrug:
@@ -88,6 +143,18 @@ enum
HANDLING_HAS_NO_ROOF = 0x2000,
HANDLING_IS_BIG = 0x4000,
HANDLING_HALOGEN_LIGHTS = 0x8000,
+ HANDLING_IS_BIKE = 0x10000,
+ HANDLING_IS_HELI = 0x20000,
+ HANDLING_IS_PLANE = 0x40000,
+ HANDLING_IS_BOAT = 0x80000,
+ HANDLING_NO_EXHAUST = 0x100000,
+ HANDLING_REARWHEEL_1ST = 0x200000,
+ HANDLING_HANDBRAKE_TYRE = 0x400000,
+ HANDLING_SIT_IN_BOAT = 0x800000,
+ HANDLING_FAT_REARW = 0x1000000,
+ HANDLING_NARROW_FRONTW = 0x2000000,
+ HANDLING_GOOD_INSAND = 0x4000000,
+ HANDLING_UNKNOWN = 0x8000000, // something for helis and planes
};
struct tHandlingData
@@ -114,6 +181,7 @@ struct tHandlingData
float fSuspensionUpperLimit;
float fSuspensionLowerLimit;
float fSuspensionBias;
+ float fSuspensionAntidiveMultiplier;
float fCollisionDamageMultiplier;
uint32 Flags;
float fSeatOffsetDistance;
@@ -121,7 +189,60 @@ struct tHandlingData
int8 FrontLights;
int8 RearLights;
};
-VALIDATE_SIZE(tHandlingData, 0xD8);
+
+struct tBikeHandlingData
+{
+ tVehicleType 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
+{
+ tVehicleType 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
+{
+ tVehicleType 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 CVehicle;
@@ -135,7 +256,9 @@ private:
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);
@@ -144,13 +267,13 @@ public:
int FindExactWord(const char *word, const char *words, int wordLen, int numWords);
void ConvertDataToWorldUnits(tHandlingData *handling);
void ConvertDataToGameUnits(tHandlingData *handling);
- void RangeCheck(tHandlingData *handling);
- void ModifyHandlingValue(CVehicle *, const tVehicleType &, const tField &, const bool &);
- void DisplayHandlingData(CVehicle *, tHandlingData *, uint8, bool);
+ void ConvertBikeDataToGameUnits(tBikeHandlingData *handling);
int32 GetHandlingId(const char *name);
tHandlingData *GetHandlingData(tVehicleType id) { return &HandlingData[id]; }
+ tBikeHandlingData *GetBikePointer(uint8 id) { return &BikeHandlingData[id-HANDLING_BIKE]; }
+ tFlyingHandlingData *GetFlyingPointer(uint8 id);
+ tBoatHandlingData *GetBoatPointer(uint8 id);
bool HasRearWheelDrive(tVehicleType id) { return HandlingData[id].Transmission.nDriveType != 'F'; }
bool HasFrontWheelDrive(tVehicleType id) { return HandlingData[id].Transmission.nDriveType != 'R'; }
};
-VALIDATE_SIZE(cHandlingDataMgr, 0x3030);
extern cHandlingDataMgr mod_HandlingManager;
diff --git a/src/vehicles/Heli.cpp b/src/vehicles/Heli.cpp
index 6e302e01..f51c8481 100644
--- a/src/vehicles/Heli.cpp
+++ b/src/vehicles/Heli.cpp
@@ -14,15 +14,19 @@
#include "Shadows.h"
#include "Coronas.h"
#include "Explosion.h"
+#include "WindModifiers.h"
#include "Timecycle.h"
#include "TempColModels.h"
#include "World.h"
#include "WaterLevel.h"
+#include "Population.h"
#include "PlayerPed.h"
+#include "CopPed.h"
#include "Wanted.h"
#include "DMAudio.h"
#include "Object.h"
#include "HandlingMgr.h"
+#include "Ropes.h"
#include "Heli.h"
#ifdef FIX_BUGS
#include "Replay.h"
@@ -40,7 +44,6 @@ enum
CHeli *CHeli::pHelis[NUM_HELIS];
int16 CHeli::NumRandomHelis;
uint32 CHeli::TestForNewRandomHelisTimer;
-int16 CHeli::NumScriptHelis; // unused
bool CHeli::CatalinaHeliOn;
bool CHeli::CatalinaHasBeenShotDown;
bool CHeli::ScriptHeliOn;
@@ -67,6 +70,9 @@ CHeli::CHeli(int32 id, uint8 CreatedBy)
m_nBulletDamage = 0;
m_fAngularSpeed = 0.0f;
m_fRotation = 0.0f;
+
+ m_numSwat = 4;
+
m_nSearchLightTimer = CTimer::GetTimeInMilliseconds();
for(i = 0; i < 6; i++){
m_aSearchLightHistoryX[i] = 0.0f;
@@ -82,6 +88,8 @@ CHeli::CHeli(int32 id, uint8 CreatedBy)
m_fTargetOffset = 0.0f;
m_fSearchLightX = m_fSearchLightY = 0.0f;
+ m_aSwatState[0] = m_aSwatState[1] = m_aSwatState[2] = m_aSwatState[3] = 0;
+
// BUG: not in game but gets initialized to CDCDCDCD in debug
m_nLastShotTime = 0;
}
@@ -120,6 +128,8 @@ CHeli::ProcessControl(void)
if(gbModelViewer)
return;
+ CWindModifiers::RegisterOne(GetPosition(), 1);
+
// Find target
CVector target(0.0f, 0.0f, 0.0f);
CVector2D vTargetDist;
@@ -266,9 +276,9 @@ CHeli::ProcessControl(void)
if(fTargetDist > targetHeight)
m_heliStatus = HELI_STATUS_CHASE_PLAYER;
}
-#ifdef FIX_BUGS
+ if(m_numSwat)
+ SendDownSwat();
break;
-#endif
case HELI_STATUS_CHASE_PLAYER:{
float targetHeight;
if(m_heliType == HELI_TYPE_CATALINA)
@@ -279,6 +289,7 @@ CHeli::ProcessControl(void)
fTargetDist < targetHeight && CWorld::GetIsLineOfSightClear(GetPosition(), FindPlayerCoors(), true, false, false, false, false, false))
m_heliStatus = HELI_STATUS_HOVER;
}
+ break;
}
// Find xy speed
@@ -348,13 +359,6 @@ CHeli::ProcessControl(void)
if(m_fTargetOffset >= 2.0f)
m_fTargetOffset -= 2.0f;
- if(m_heliType == HELI_TYPE_CATALINA)
- if(m_pathState == 9 || m_pathState == 11 || m_pathState == 10){
- float f = Pow(0.997f, CTimer::GetTimeStep());
- m_vecMoveSpeed.x *= f;
- m_vecMoveSpeed.y *= f;
- }
-
CVector2D speedDir = targetSpeed - m_vecMoveSpeed;
float speedDiff = speedDir.Magnitude();
if(speedDiff != 0.0f)
@@ -526,28 +530,17 @@ CHeli::ProcessControl(void)
}
}
- // Drop Catalina's bombs
- if(m_heliType == HELI_TYPE_CATALINA && m_pathState > 8 && (CTimer::GetTimeInMilliseconds()>>9) != (CTimer::GetPreviousTimeInMilliseconds()>>9)){
- CVector bombPos = GetPosition() - 60.0f*m_vecMoveSpeed;
- if(sq(FindPlayerCoors().x-bombPos.x) + sq(FindPlayerCoors().y-bombPos.y) < sq(35.0f)){
- bool found;
- float groundZ = CWorld::FindGroundZFor3DCoord(bombPos.x, bombPos.y, bombPos.z, &found);
- float waterZ;
- if(!CWaterLevel::GetWaterLevelNoWaves(bombPos.x, bombPos.y, bombPos.z, &waterZ))
- waterZ = 0.0f;
- if(groundZ > waterZ){
- bombPos.z = groundZ + 2.0f;
- CExplosion::AddExplosion(nil, this, EXPLOSION_HELI_BOMB, bombPos, 0);
- }else{
- bombPos.z = waterZ;
- CVector dir;
- for(i = 0; i < 16; i++){
- dir.x = ((CGeneral::GetRandomNumber()&0xFF)-127)*0.001f;
- dir.y = ((CGeneral::GetRandomNumber()&0xFF)-127)*0.001f;
- dir.z = 0.5f;
- CParticle::AddParticle(PARTICLE_BOAT_SPLASH, bombPos, dir, nil, 0.2f);
- }
- }
+ // Process ropes
+ for(i = 0; i < 4; i++){
+ if(m_aSwatState[i] == 0)
+ continue;
+
+ m_aSwatState[i]--;
+ CRopes::RegisterRope((uintptr)this + i, GetMatrix()*FindSwatPositionRelativeToHeli(i), false);
+ if(m_aSwatState[i] == 0){
+ CVector speed = Multiply3x3(GetMatrix(), 0.05f*FindSwatPositionRelativeToHeli(i));
+ speed.z = 0.0f;
+ CRopes::SetSpeedOfTopNode((uintptr)this + i, speed);
}
}
@@ -560,60 +553,9 @@ 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 = CVector(pos.x, pos.y, 1.0f)*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_GRAVEL:
- r = 10;
- g = 8;
- b = 7;
- break;
- case SURFACE_MUD_DRY:
- 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));
+ CShadows::StoreShadowForVehicle(this, VEH_SHD_TYPE_HELI);
}
void
@@ -649,7 +591,7 @@ CHeli::PreRenderAlways(void)
CShadows::StoreShadowToBeRendered(SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &shadowPos,
6.0f, 0.0f, 0.0f, -6.0f,
80*m_fSearchLightIntensity, 80*m_fSearchLightIntensity, 80*m_fSearchLightIntensity, 80*m_fSearchLightIntensity,
- 50.0f, true, 1.0f);
+ 50.0f, true, 1.0f, nil, false);
CVector front = GetMatrix() * CVector(0.0f, 7.0f, 0.0f);
CVector toPlayer = FindPlayerCoors() - front;
@@ -718,6 +660,7 @@ CHeli::SpawnFlyingComponent(int32 component)
RpAtomicSetFrame(atomic, frame);
CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil);
obj->AttachToRwObject((RwObject*)atomic);
+ obj->bDontStream = true;
// init object
obj->m_fMass = 10.0f;
@@ -763,6 +706,42 @@ CHeli::SpawnFlyingComponent(int32 component)
return obj;
}
+CVector
+CHeli::FindSwatPositionRelativeToHeli(int n)
+{
+ switch(n){
+ case 0: return CVector(-1.2f, -1.0f, -0.5f);
+ case 1: return CVector( 1.2f, -1.0f, -0.5f);
+ case 2: return CVector(-1.2f, 1.0f, -0.5f);
+ case 3: return CVector( 1.2f, 1.0f, -0.5f);
+ default: return CVector(0.0f, 0.0f, 0.0f);
+ }
+}
+
+bool
+CHeli::SendDownSwat(void)
+{
+ if(m_numSwat == 0 || !CStreaming::HasModelLoaded(MI_SWAT) ||
+ CGeneral::GetRandomNumber() & 0x7F || (GetPosition() - FindPlayerCoors()).Magnitude() > 50.0f)
+ return false;
+
+ CMatrix mat(GetMatrix());
+ CVector pos = Multiply3x3(mat, FindSwatPositionRelativeToHeli(m_numSwat-1)) + GetPosition();
+
+ float groundZ = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z, nil);
+ if(Abs(FindPlayerCoors().z - groundZ) < 2.5f && CRopes::RegisterRope((uintptr)this + m_numSwat-1, pos, false)){
+ CCopPed *swat = (CCopPed*)CPopulation::AddPed(PEDTYPE_COP, COP_HELI_SWAT, pos);
+ swat->bUsesCollision = false;
+ swat->m_pRopeEntity = this;
+ RegisterReference(&swat->m_pRopeEntity);
+ m_numSwat--;
+ swat->m_nRopeID = (uintptr)this + m_numSwat;
+ m_aSwatState[m_numSwat] = 255;
+ CAnimManager::BlendAnimation(swat->GetClump(), ASSOCGRP_STD, ANIM_STD_ABSEIL, 4.0f);
+ return true;
+ }
+ return false;
+}
void
@@ -772,16 +751,12 @@ CHeli::InitHelis(void)
NumRandomHelis = 0;
TestForNewRandomHelisTimer = 0;
- NumScriptHelis = 0;
CatalinaHeliOn = false;
ScriptHeliOn = false;
for(i = 0; i < NUM_HELIS; i++)
pHelis[i] = nil;
-#if GTA_VERSION >= GTA3_PS2_160
- ((CVehicleModelInfo*)CModelInfo::GetModelInfo(MI_ESCAPE))->SetColModel(&CTempColModels::ms_colModelPed1);
((CVehicleModelInfo*)CModelInfo::GetModelInfo(MI_CHOPPER))->SetColModel(&CTempColModels::ms_colModelPed1);
-#endif
}
CHeli*
@@ -791,15 +766,8 @@ CHeli::GenerateHeli(bool catalina)
CVector heliPos;
int i;
-#if GTA_VERSION < GTA3_PS2_160
- if(catalina)
- ((CVehicleModelInfo*)CModelInfo::GetModelInfo(MI_ESCAPE))->SetColModel(&CTempColModels::ms_colModelPed1);
- else
- ((CVehicleModelInfo*)CModelInfo::GetModelInfo(MI_CHOPPER))->SetColModel(&CTempColModels::ms_colModelPed1);
-#endif
-
if(catalina)
- heli = new CHeli(MI_ESCAPE, PERMANENT_VEHICLE);
+ assert(0 && "can't create catalina's heli");
else
heli = new CHeli(MI_CHOPPER, PERMANENT_VEHICLE);
@@ -810,7 +778,7 @@ CHeli::GenerateHeli(bool catalina)
float angle = (float)(CGeneral::GetRandomNumber() & 0xFF)/0x100 * 6.28f;
heliPos.x += 250.0f*Sin(angle);
heliPos.y += 250.0f*Cos(angle);
- if(heliPos.x < -2000.0f || heliPos.x > 2000.0f || heliPos.y < -2000.0f || heliPos.y > 2000.0f){
+ if(heliPos.x < -2000.0f-400.0f || heliPos.x > 2000.0f-400.0f || heliPos.y < -2000.0f || heliPos.y > 2000.0f){
heliPos = FindPlayerCoors();
heliPos.x -= 250.0f*Sin(angle);
heliPos.y -= 250.0f*Cos(angle);
@@ -851,6 +819,8 @@ CHeli::UpdateHelis(void)
CReplay::IsPlayingBack() ? 0 :
#endif
FindPlayerPed()->m_pWanted->NumOfHelisRequired();
+ if(CCullZones::PlayerNoRain() || CGame::IsInInterior())
+ numHelisRequired = 0;
if(CStreaming::HasModelLoaded(MI_CHOPPER) && CTimer::GetTimeInMilliseconds() > TestForNewRandomHelisTimer){
// Spawn a police heli
TestForNewRandomHelisTimer = CTimer::GetTimeInMilliseconds() + 15000;
@@ -879,18 +849,6 @@ CHeli::UpdateHelis(void)
pHelis[HELI_SCRIPT]->m_heliStatus = HELI_STATUS_FLY_AWAY;
}
- // Handle Catalina's heli
- if(CatalinaHeliOn){
- if(CStreaming::HasModelLoaded(MI_ESCAPE) && pHelis[HELI_CATALINA] == nil){
- pHelis[HELI_CATALINA] = GenerateHeli(true);
- pHelis[HELI_CATALINA]->m_heliType = HELI_TYPE_CATALINA;
- }else
- CStreaming::RequestModel(MI_ESCAPE, STREAMFLAGS_DONT_REMOVE);
- }else{
- if(pHelis[HELI_CATALINA])
- pHelis[HELI_CATALINA]->m_heliStatus = HELI_STATUS_FLY_AWAY;
- }
-
// Delete helis that we no longer need
for(i = 0; i < NUM_HELIS; i++)
if(pHelis[i] && pHelis[i]->m_heliStatus == HELI_STATUS_FLY_AWAY && pHelis[i]->GetPosition().z > 150.0f){
@@ -911,7 +869,7 @@ CHeli::UpdateHelis(void)
TheCamera.CamShake(0.7f, pHelis[i]->GetPosition().x, pHelis[i]->GetPosition().y, pHelis[i]->GetPosition().z);
colors[0] = CRGBA(0, 0, 0, 255);
- colors[1] = CRGBA(224, 230, 238, 255);
+ colors[1] = CRGBA(224, 224, 224, 255);
colors[2] = CRGBA(0, 0, 0, 255);
colors[3] = CRGBA(0, 0, 0, 255);
colors[4] = CRGBA(66, 162, 252, 255);
@@ -931,7 +889,7 @@ CHeli::UpdateHelis(void)
int f = ++nFrameGen & 3;
CParticle::AddParticle(PARTICLE_HELI_DEBRIS, pos, dir,
nil, CGeneral::GetRandomNumberInRange(0.1f, 1.0f),
- colors[nFrameGen], rotSpeed, 0, f, 0);
+ colors[nFrameGen&7], rotSpeed, 0, f, 0);
}
CExplosion::AddExplosion(nil, nil, EXPLOSION_HELI, pos, 0);
@@ -949,7 +907,6 @@ CHeli::UpdateHelis(void)
if(i == HELI_CATALINA)
CatalinaHasBeenShotDown = true;
- CStats::HelisDestroyed++;
CStats::PeopleKilledByPlayer += 2;
CStats::PedsKilledOfThisType[PEDTYPE_COP] += 2;
CWorld::Players[CWorld::PlayerInFocus].m_nMoney += 250;
@@ -969,7 +926,7 @@ CHeli::UpdateHelis(void)
TheCamera.CamShake(0.4f, pHelis[i]->GetPosition().x, pHelis[i]->GetPosition().y, pHelis[i]->GetPosition().z);
CVector pos = pHelis[i]->GetPosition() - 2.5f*pHelis[i]->GetForward();
- CExplosion::AddExplosion(nil, nil, EXPLOSION_HELI, pos, 0);
+ CExplosion::AddExplosion(nil, nil, EXPLOSION_HELI2, pos, 0);
}else
pHelis[i]->m_fAngularSpeed *= 1.03f;
}
@@ -1045,6 +1002,28 @@ CHeli::TestBulletCollision(CVector *line0, CVector *line1, CVector *bulletPos, i
return hit;
}
+bool
+CHeli::TestSniperCollision(CVector *line0, CVector *line1)
+{
+ int i;
+ bool hit = false;
+
+ for(i = 0; i < NUM_HELIS; i++){
+ if(pHelis[i] && !pHelis[i]->bBulletProof) {
+ CVector pilotPos = pHelis[i]->GetMatrix() * CVector(-0.43f, 1.49f, 1.5f);
+ if(CCollision::DistToLine(line0, line1, &pilotPos) < 0.8f){
+ pHelis[i]->m_fAngularSpeed = CGeneral::GetRandomTrueFalse() ? 0.05f : -0.05f;
+ pHelis[i]->m_heliStatus = HELI_STATUS_SHOT_DOWN;
+ pHelis[i]->m_nExplosionTimer = CTimer::GetTimeInMilliseconds() + 9999999;
+ pHelis[i]->m_numSwat = 0;
+
+ hit = true;
+ }
+ }
+ }
+ return hit;
+}
+
void CHeli::StartCatalinaFlyBy(void)
{
CatalinaHeliOn = true;
diff --git a/src/vehicles/Heli.h b/src/vehicles/Heli.h
index 5fef799b..c5ae08e2 100644
--- a/src/vehicles/Heli.h
+++ b/src/vehicles/Heli.h
@@ -21,7 +21,7 @@ enum
HELI_RANDOM0,
HELI_RANDOM1,
HELI_SCRIPT,
- HELI_CATALINA,
+ HELI_CATALINA, // TODO 2 in VC
NUM_HELIS
};
@@ -36,7 +36,6 @@ enum
class CHeli : public CVehicle
{
public:
- // 0x288
RwFrame *m_aHeliNodes[NUM_HELI_NODES];
int8 m_heliStatus;
float m_fSearchLightX;
@@ -49,6 +48,8 @@ public:
int8 m_nHeliId;
int8 m_heliType;
int8 m_pathState;
+ int8 m_numSwat;
+ uint8 m_aSwatState[4];
float m_aSearchLightHistoryX[6];
float m_aSearchLightHistoryY[6];
uint32 m_nSearchLightTimer;
@@ -64,7 +65,6 @@ public:
static CHeli *pHelis[NUM_HELIS];
static int16 NumRandomHelis;
static uint32 TestForNewRandomHelisTimer;
- static int16 NumScriptHelis; // unused
static bool CatalinaHeliOn;
static bool CatalinaHasBeenShotDown;
static bool ScriptHeliOn;
@@ -79,6 +79,8 @@ public:
void PreRenderAlways(void);
CObject *SpawnFlyingComponent(int32 component);
+ CVector FindSwatPositionRelativeToHeli(int n);
+ bool SendDownSwat(void);
static void InitHelis(void);
static CHeli *GenerateHeli(bool catalina); // out of class in III PC and later because of SecuROM
@@ -86,6 +88,7 @@ public:
static void SpecialHeliPreRender(void);
static bool TestRocketCollision(CVector *coors);
static bool TestBulletCollision(CVector *line0, CVector *line1, CVector *bulletPos, int32 damage);
+ static bool TestSniperCollision(CVector *line0, CVector *line1);
static void StartCatalinaFlyBy(void); // out of class in III PC and later because of SecuROM
static void RemoveCatalinaHeli(void);
@@ -96,6 +99,3 @@ public:
static void ActivateHeli(bool activate);
};
-
-VALIDATE_SIZE(CHeli, 0x33C);
-
diff --git a/src/vehicles/Plane.cpp b/src/vehicles/Plane.cpp
index 8ea03bf7..0b40ca7e 100644
--- a/src/vehicles/Plane.cpp
+++ b/src/vehicles/Plane.cpp
@@ -2,6 +2,7 @@
#include "main.h"
#include "General.h"
+#include "CutsceneMgr.h"
#include "ModelIndices.h"
#include "FileMgr.h"
#include "Streaming.h"
@@ -12,8 +13,10 @@
#include "Coronas.h"
#include "Particle.h"
#include "Explosion.h"
+#include "Fluff.h"
#include "World.h"
#include "HandlingMgr.h"
+#include "Heli.h"
#include "Plane.h"
#include "MemoryHeap.h"
@@ -40,12 +43,10 @@ CPlaneInterpolationLine aPlaneLineBits[6];
float PlanePathPosition[3];
float OldPlanePathPosition[3];
float PlanePathSpeed[3];
-float PlanePath2Position[3];
-float PlanePath3Position;
-float PlanePath4Position;
-float PlanePath2Speed[3];
-float PlanePath3Speed;
-float PlanePath4Speed;
+float PlanePath2Position[5];
+float PlanePath3Position[4];
+float PlanePath2Speed[5];
+float PlanePath3Speed[4];
enum
@@ -63,7 +64,6 @@ int32 DropOffCesnaMissionStatus;
int32 DropOffCesnaMissionStartTime;
CPlane *pDropOffCesna;
-
CPlane::CPlane(int32 id, uint8 CreatedBy)
: CVehicle(CreatedBy)
{
@@ -81,13 +81,15 @@ CPlane::CPlane(int32 id, uint8 CreatedBy)
m_bHasBeenHit = false;
m_bIsDrugRunCesna = false;
m_bIsDropOffCesna = false;
+ m_bTempPlane = false;
SetStatus(STATUS_PLANE);
bIsBIGBuilding = true;
m_level = LEVEL_GENERIC;
-#ifdef FIX_BUGS
m_isFarAway = false;
+#ifdef CPLANE_ROTORS
+ m_fRotorRotation = 0.0f;
#endif
}
@@ -100,6 +102,21 @@ void
CPlane::SetModelIndex(uint32 id)
{
CVehicle::SetModelIndex(id);
+#ifdef CPLANE_ROTORS
+ int i;
+ for(i = 0; i < NUM_PLANE_NODES; i++)
+ m_aPlaneNodes[i] = nil;
+ if(GetModelIndex() == MI_CHOPPER){
+ // This is surprisingly annoying...
+ RwFrame *heliNodes[NUM_HELI_NODES];
+ for(i = 0; i < NUM_HELI_NODES; i++)
+ heliNodes[i] = nil;
+ CClumpModelInfo::FillFrameArray(GetClump(), heliNodes);
+ m_aPlaneNodes[PLANE_TOPROTOR] = heliNodes[HELI_TOPROTOR];
+ m_aPlaneNodes[PLANE_BACKROTOR] = heliNodes[HELI_BACKROTOR];
+ }else
+ CClumpModelInfo::FillFrameArray(GetClump(), m_aPlaneNodes);
+#endif
}
void
@@ -124,6 +141,15 @@ CPlane::ProcessControl(void)
int i;
CVector pos;
+ if(CReplay::IsPlayingBack())
+ return;
+
+ if(GetModelIndex() == MI_AIRTRAIN){
+ if(GetPosition().z > 100.0f)
+ CPlaneTrails::RegisterPoint(GetPosition(), m_nPlaneId);
+ }else if(GetModelIndex() == MI_DEADDODO)
+ CPlaneBanners::RegisterPoint(GetPosition(), m_nPlaneId);
+
// Explosion
if(m_bHasBeenHit){
// BUG: since this is all based on frames, you can skip the explosion processing when you go into the menu
@@ -384,7 +410,6 @@ CPlane::ProcessControl(void)
GetMatrix().GetRight() = right;
GetMatrix().GetUp() = up;
GetMatrix().GetForward() = fwd;
-
// Set speed
m_vecMoveSpeed = fwd*PlanePathSpeed[m_nPlaneId]/60.0f;
m_fSpeed = PlanePathSpeed[m_nPlaneId]/60.0f;
@@ -398,26 +423,12 @@ CPlane::ProcessControl(void)
float planePathSpeed;
int numPathNodes;
- if(m_bIsDrugRunCesna){
- planePathPosition = PlanePath3Position;
+ if(GetModelIndex() == MI_CHOPPER){
+ planePathPosition = PlanePath3Position[m_nPlaneId];
totalLengthOfFlightPath = TotalLengthOfFlightPath3;
pathNodes = pPath3Nodes;
- planePathSpeed = PlanePath3Speed;
+ planePathSpeed = PlanePath3Speed[m_nPlaneId];
numPathNodes = NumPath3Nodes;
- if(CesnaMissionStatus == CESNA_STATUS_LANDED){
- pDrugRunCesna = nil;
- FlagToDestroyWhenNextProcessed();
- }
- }else if(m_bIsDropOffCesna){
- planePathPosition = PlanePath4Position;
- totalLengthOfFlightPath = TotalLengthOfFlightPath4;
- pathNodes = pPath4Nodes;
- planePathSpeed = PlanePath4Speed;
- numPathNodes = NumPath4Nodes;
- if(DropOffCesnaMissionStatus == CESNA_STATUS_LANDED){
- pDropOffCesna = nil;
- FlagToDestroyWhenNextProcessed();
- }
}else{
planePathPosition = PlanePath2Position[m_nPlaneId];
totalLengthOfFlightPath = TotalLengthOfFlightPath2;
@@ -638,12 +649,36 @@ CPlane::PreRender(void)
CCoronas::TYPE_NORMAL, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON,
CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, 0.0f);
}
+
+#ifdef CPLANE_ROTORS
+ CMatrix mat;
+ CVector pos;
+ m_fRotorRotation += 3.14f/6.5f;
+ if(m_fRotorRotation > 6.28f)
+ m_fRotorRotation -= 6.28f;
+
+ if(m_aPlaneNodes[PLANE_TOPROTOR]){
+ mat.Attach(RwFrameGetMatrix(m_aPlaneNodes[PLANE_TOPROTOR]));
+ pos = mat.GetPosition();
+ mat.SetRotateZ(m_fRotorRotation);
+ mat.Translate(pos);
+ mat.UpdateRW();
+ }
+ if(m_aPlaneNodes[PLANE_BACKROTOR]){
+ mat.Attach(RwFrameGetMatrix(m_aPlaneNodes[PLANE_BACKROTOR]));
+ pos = mat.GetPosition();
+ mat.SetRotateX(m_fRotorRotation);
+ mat.Translate(pos);
+ mat.UpdateRW();
+ }
+#endif
}
void
CPlane::Render(void)
{
- CEntity::Render();
+ if(!CCutsceneMgr::IsRunning())
+ CEntity::Render();
}
#define CRUISE_SPEED (50.0f)
@@ -661,11 +696,9 @@ CPlane::InitPlanes(void)
pPathNodes = LoadPath("data\\paths\\flight.dat", NumPathNodes, TotalLengthOfFlightPath, true);
// Figure out which nodes are on ground
- CColPoint colpoint;
- CEntity *entity;
for(i = 0; i < NumPathNodes; i++){
- if(CWorld::ProcessVerticalLine(pPathNodes[i].p, 1000.0f, colpoint, entity, true, false, false, false, true, false, nil)){
- pPathNodes[i].p.z = colpoint.point.z;
+ if(pPathNodes[i].p.z < 14.0f){
+ pPathNodes[i].p.z = 14.0f;
pPathNodes[i].bOnGround = true;
}else
pPathNodes[i].bOnGround = false;
@@ -692,7 +725,7 @@ CPlane::InitPlanes(void)
aPlaneLineBits[0].position = position;
aPlaneLineBits[0].speed = TAXI_SPEED;
aPlaneLineBits[0].acceleration = 0.0f;
- float dist = (TakeOffPoint-600.0f) - position;
+ float dist = (TakeOffPoint-500.0f) - position;
time += dist/TAXI_SPEED;
position += dist;
@@ -701,9 +734,9 @@ CPlane::InitPlanes(void)
aPlaneLineBits[1].time = time;
aPlaneLineBits[1].position = position;
aPlaneLineBits[1].speed = TAXI_SPEED;
- aPlaneLineBits[1].acceleration = 618.75f/600.0f;
- time += 600.0f/((CRUISE_SPEED+TAXI_SPEED)/2.0f);
- position += 600.0f;
+ aPlaneLineBits[1].acceleration = 618.75f/500.0f;
+ time += 500.0f/((CRUISE_SPEED+TAXI_SPEED)/2.0f);
+ position += 500.0f;
// Fly at cruise speed
aPlaneLineBits[2].type = 1;
@@ -720,9 +753,9 @@ CPlane::InitPlanes(void)
aPlaneLineBits[3].time = time;
aPlaneLineBits[3].position = position;
aPlaneLineBits[3].speed = CRUISE_SPEED;
- aPlaneLineBits[3].acceleration = -618.75f/600.0f;
- time += 600.0f/((CRUISE_SPEED+TAXI_SPEED)/2.0f);
- position += 600.0f;
+ aPlaneLineBits[3].acceleration = -618.75f/500.0f;
+ time += 500.0f/((CRUISE_SPEED+TAXI_SPEED)/2.0f);
+ position += 500.0f;
// Taxi
aPlaneLineBits[4].type = 1;
@@ -743,22 +776,17 @@ CPlane::InitPlanes(void)
TotalDurationOfFlightPath2 = TotalLengthOfFlightPath2/CRUISE_SPEED;
}
- // Mission Cesna
+ // Heli
if(pPath3Nodes == nil){
pPath3Nodes = LoadPath("data\\paths\\flight3.dat", NumPath3Nodes, TotalLengthOfFlightPath3, false);
TotalDurationOfFlightPath3 = TotalLengthOfFlightPath3/CRUISE_SPEED;
}
- // Mission Cesna
- if(pPath4Nodes == nil){
- pPath4Nodes = LoadPath("data\\paths\\flight4.dat", NumPath4Nodes, TotalLengthOfFlightPath4, false);
- TotalDurationOfFlightPath4 = TotalLengthOfFlightPath4/CRUISE_SPEED;
- }
-
CStreaming::LoadAllRequestedModels(false);
CStreaming::RequestModel(MI_AIRTRAIN, 0);
CStreaming::LoadAllRequestedModels(false);
+ // NB: 3 hardcoded also in CPlaneTrails
for(i = 0; i < 3; i++){
CPlane *plane = new CPlane(MI_AIRTRAIN, PERMANENT_VEHICLE);
plane->GetMatrix().SetTranslate(0.0f, 0.0f, 0.0f);
@@ -768,20 +796,6 @@ CPlane::InitPlanes(void)
plane->m_nCurPathNode = 0;
CWorld::Add(plane);
}
-
-
- CStreaming::RequestModel(MI_DEADDODO, 0);
- CStreaming::LoadAllRequestedModels(false);
-
- for(i = 0; i < 3; i++){
- CPlane *plane = new CPlane(MI_DEADDODO, PERMANENT_VEHICLE);
- plane->GetMatrix().SetTranslate(0.0f, 0.0f, 0.0f);
- plane->SetStatus(STATUS_ABANDONED);
- plane->bIsLocked = true;
- plane->m_nPlaneId = i;
- plane->m_nCurPathNode = 0;
- CWorld::Add(plane);
- }
}
void
@@ -813,8 +827,7 @@ CPlane::LoadPath(char const *filename, int32 &numNodes, float &totalLength, bool
CPlaneNode *nodes = new CPlaneNode[numNodes];
for(i = 0; i < numNodes; i++){
- *gString = '\0';
- for(lp = 0; work_buff[bp] != '\n'; bp++, lp++)
+ for(lp = 0; work_buff[bp] != '\n' && work_buff[bp] != '\0'; bp++, lp++)
gString[lp] = work_buff[bp];
bp++;
// BUG: game doesn't terminate string
@@ -835,6 +848,10 @@ CPlane::LoadPath(char const *filename, int32 &numNodes, float &totalLength, bool
return nodes;
}
+int32 LastTimeInPlane, LastTimeNotInPlane;
+bool bCesnasActivated;
+bool bHelisActivated;
+
void
CPlane::UpdatePlanes(void)
{
@@ -877,25 +894,87 @@ CPlane::UpdatePlanes(void)
t = TotalDurationOfFlightPath2/0x80000;
PlanePath2Position[0] = CRUISE_SPEED * (time & 0x7FFFF)*t;
- PlanePath2Position[1] = CRUISE_SPEED * ((time + 0x80000/3) & 0x7FFFF)*t;
- PlanePath2Position[2] = CRUISE_SPEED * ((time + 0x80000/3*2) & 0x7FFFF)*t;
+ PlanePath2Position[1] = CRUISE_SPEED * ((time + 0x80000/5) & 0x7FFFF)*t;
+ PlanePath2Position[2] = CRUISE_SPEED * ((time + 0x80000/5*2) & 0x7FFFF)*t;
+ PlanePath2Position[3] = CRUISE_SPEED * ((time + 0x80000/5*3) & 0x7FFFF)*t;
+ PlanePath2Position[4] = CRUISE_SPEED * ((time + 0x80000/5*4) & 0x7FFFF)*t;
PlanePath2Speed[0] = CRUISE_SPEED*t;
PlanePath2Speed[1] = CRUISE_SPEED*t;
PlanePath2Speed[2] = CRUISE_SPEED*t;
+ PlanePath2Speed[3] = CRUISE_SPEED*t;
+ PlanePath2Speed[4] = CRUISE_SPEED*t;
+
+ t = TotalDurationOfFlightPath3/0x80000;
+ PlanePath3Position[0] = CRUISE_SPEED * (time & 0x7FFFF)*t;
+ PlanePath3Position[1] = CRUISE_SPEED * ((time + 0x80000/4) & 0x7FFFF)*t;
+ PlanePath3Position[2] = CRUISE_SPEED * ((time + 0x80000/4*2) & 0x7FFFF)*t;
+ PlanePath3Position[3] = CRUISE_SPEED * ((time + 0x80000/4*3) & 0x7FFFF)*t;
+ PlanePath3Speed[0] = CRUISE_SPEED*t;
+ PlanePath3Speed[1] = CRUISE_SPEED*t;
+ PlanePath3Speed[2] = CRUISE_SPEED*t;
+ PlanePath3Speed[3] = CRUISE_SPEED*t;
+
+ if(FindPlayerVehicle() && (FindPlayerVehicle()->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI ||
+ FindPlayerVehicle()->GetVehicleAppearance() == VEHICLE_APPEARANCE_PLANE))
+ LastTimeInPlane = CTimer::GetTimeInMilliseconds();
+ else
+ LastTimeNotInPlane = CTimer::GetTimeInMilliseconds();
+
+ if(CTimer::GetTimeInMilliseconds() - LastTimeNotInPlane > 10000){
+ if(!bCesnasActivated){
+ if(CStreaming::HasModelLoaded(MI_DEADDODO)){
+ for(i = 0; i < 5; i++){
+ CPlane *plane = new CPlane(MI_DEADDODO, PERMANENT_VEHICLE);
+ plane->GetMatrix().SetTranslate(0.0f, 0.0f, 0.0f);
+ plane->SetStatus(STATUS_ABANDONED);
+ plane->bIsLocked = true;
+ plane->m_nPlaneId = i;
+ plane->m_nCurPathNode = 0;
+ plane->m_bTempPlane = true;
+ CWorld::Add(plane);
+ }
+ bCesnasActivated = true;
+ }else
+ CStreaming::RequestModel(MI_DEADDODO, 0);
+ }
- if(CesnaMissionStatus == CESNA_STATUS_FLYING){
- PlanePath3Speed = CRUISE_SPEED*TotalDurationOfFlightPath3/0x20000;
- PlanePath3Position = PlanePath3Speed * ((time - CesnaMissionStartTime) & 0x1FFFF);
- if(time - CesnaMissionStartTime >= 128072)
- CesnaMissionStatus = CESNA_STATUS_LANDED;
- }
+ if(!bHelisActivated){
+ if(CStreaming::HasModelLoaded(MI_CHOPPER)){
+ for(i = 0; i < 4; i++){
+ CPlane *plane = new CPlane(MI_CHOPPER, PERMANENT_VEHICLE);
+ plane->GetMatrix().SetTranslate(0.0f, 0.0f, 0.0f);
+ plane->SetStatus(STATUS_ABANDONED);
+ plane->bIsLocked = true;
+ plane->m_nPlaneId = i;
+ plane->m_nCurPathNode = 0;
+ plane->m_bTempPlane = true;
+ CWorld::Add(plane);
+ }
+ bHelisActivated = true;
+ }else
+ CStreaming::RequestModel(MI_CHOPPER, 0);
+ }
+ }else if(CTimer::GetTimeInMilliseconds() - LastTimeInPlane > 10000)
+ RemoveTemporaryPlanes();
+}
- if(DropOffCesnaMissionStatus == CESNA_STATUS_FLYING){
- PlanePath4Speed = CRUISE_SPEED*TotalDurationOfFlightPath4/0x80000;
- PlanePath4Position = PlanePath4Speed * ((time - DropOffCesnaMissionStartTime) & 0x7FFFF);
- if(time - DropOffCesnaMissionStartTime >= 521288)
- DropOffCesnaMissionStatus = CESNA_STATUS_LANDED;
+void
+CPlane::RemoveTemporaryPlanes(void)
+{
+ int i;
+ if(!bHelisActivated && !bCesnasActivated)
+ return;
+
+ i = CPools::GetVehiclePool()->GetSize();
+ while(--i >= 0){
+ CPlane *plane = (CPlane*)CPools::GetVehiclePool()->GetSlot(i);
+ if(plane && plane->IsPlane() && plane->m_bTempPlane){
+ CWorld::Remove(plane);
+ delete plane;
+ }
}
+ bCesnasActivated = false;
+ bHelisActivated = false;
}
bool
@@ -923,6 +1002,7 @@ CPlane::TestRocketCollision(CVector *rocketPos)
return false;
}
+// unused
// BUG: not in CPlane in the game
void
CPlane::CreateIncomingCesna(void)
@@ -946,6 +1026,7 @@ CPlane::CreateIncomingCesna(void)
printf("CPlane::CreateIncomingCesna(void)\n");
}
+// unused
void
CPlane::CreateDropOffCesna(void)
{
@@ -968,8 +1049,21 @@ CPlane::CreateDropOffCesna(void)
printf("CPlane::CreateDropOffCesna(void)\n");
}
+// all unused
const CVector CPlane::FindDrugPlaneCoordinates(void) { return pDrugRunCesna->GetPosition(); }
const CVector CPlane::FindDropOffCesnaCoordinates(void) { return pDropOffCesna->GetPosition(); }
bool CPlane::HasCesnaLanded(void) { return CesnaMissionStatus == CESNA_STATUS_LANDED; }
bool CPlane::HasCesnaBeenDestroyed(void) { return CesnaMissionStatus == CESNA_STATUS_DESTROYED; }
bool CPlane::HasDropOffCesnaBeenShotDown(void) { return DropOffCesnaMissionStatus == CESNA_STATUS_DESTROYED; }
+
+void
+CPlane::Load(void)
+{
+ RemoveTemporaryPlanes();
+}
+
+void
+CPlane::Save(void)
+{
+ RemoveTemporaryPlanes();
+}
diff --git a/src/vehicles/Plane.h b/src/vehicles/Plane.h
index 783c53b3..c8f02048 100644
--- a/src/vehicles/Plane.h
+++ b/src/vehicles/Plane.h
@@ -4,6 +4,11 @@
enum ePlaneNodes
{
+#ifdef CPLANE_ROTORS
+ // for heli
+ PLANE_TOPROTOR,
+ PLANE_BACKROTOR,
+#endif
PLANE_WHEEL_FRONT = 2,
PLANE_WHEEL_READ,
NUM_PLANE_NODES
@@ -29,7 +34,10 @@ struct CPlaneInterpolationLine
class CPlane : public CVehicle
{
public:
- // 0x288
+#ifdef CPLANE_ROTORS
+ RwFrame *m_aPlaneNodes[NUM_PLANE_NODES];
+ float m_fRotorRotation;
+#endif
int16 m_nPlaneId;
int16 m_isFarAway;
int16 m_nCurPathNode;
@@ -38,6 +46,7 @@ public:
bool m_bHasBeenHit;
bool m_bIsDrugRunCesna;
bool m_bIsDropOffCesna;
+ bool m_bTempPlane;
CPlane(int32 id, uint8 CreatedBy);
~CPlane(void);
@@ -53,6 +62,7 @@ public:
static void InitPlanes(void);
static void Shutdown(void);
static CPlaneNode *LoadPath(char const *filename, int32 &numNodes, float &totalLength, bool loop);
+ static void RemoveTemporaryPlanes(void);
static void UpdatePlanes(void);
static bool TestRocketCollision(CVector *rocketPos);
static void CreateIncomingCesna(void);
@@ -62,10 +72,10 @@ public:
static bool HasCesnaLanded(void);
static bool HasCesnaBeenDestroyed(void);
static bool HasDropOffCesnaBeenShotDown(void);
+ static void Load(void);
+ static void Save(void);
};
-VALIDATE_SIZE(CPlane, 0x29C);
-
extern float LandingPoint;
extern float TakeOffPoint;
extern float PlanePathPosition[3];
diff --git a/src/vehicles/Train.cpp b/src/vehicles/Train.cpp
index be546c70..3a04b614 100644
--- a/src/vehicles/Train.cpp
+++ b/src/vehicles/Train.cpp
@@ -41,6 +41,7 @@ static bool bTrainArrivalAnnounced[3] = {false, false, false};
CTrain::CTrain(int32 id, uint8 CreatedBy)
: CVehicle(CreatedBy)
{
+#ifdef GTA_TRAIN
CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(id);
m_vehType = VEHICLE_TYPE_TRAIN;
pHandling = mod_HandlingManager.GetHandlingData((tVehicleType)mi->m_handlingId);
@@ -67,22 +68,28 @@ CTrain::CTrain(int32 id, uint8 CreatedBy)
#ifdef FIX_BUGS
m_isFarAway = true;
#endif
+#else
+ assert(0 && "No trains in this game");
+#endif
}
void
CTrain::SetModelIndex(uint32 id)
{
+#ifdef GTA_TRAIN
int i;
CVehicle::SetModelIndex(id);
for(i = 0; i < NUM_TRAIN_NODES; i++)
m_aTrainNodes[i] = nil;
CClumpModelInfo::FillFrameArray(GetClump(), m_aTrainNodes);
+#endif
}
void
CTrain::ProcessControl(void)
{
+#ifdef GTA_TRAIN
if(gbModelViewer || m_isFarAway && (CTimer::GetFrameCounter() + m_nWagonId) & 0xF)
return;
@@ -285,11 +292,13 @@ CTrain::ProcessControl(void)
TrainHitStuff(s->m_lists[ENTITYLIST_PEDS_OVERLAP]);
}
}
+#endif // GTA_TRAIN
}
void
CTrain::PreRender(void)
{
+#ifdef GTA_TRAIN
CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex());
if(m_bIsFirstWagon){
@@ -349,17 +358,21 @@ CTrain::PreRender(void)
CCoronas::TYPE_NORMAL, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON,
CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, 0.0f);
}
+#endif
}
void
CTrain::Render(void)
{
+#ifdef GTA_TRAIN
CEntity::Render();
+#endif
}
void
CTrain::TrainHitStuff(CPtrList &list)
{
+#ifdef GTA_TRAIN
CPtrNode *node;
CPhysical *phys;
@@ -368,11 +381,13 @@ CTrain::TrainHitStuff(CPtrList &list)
if(phys != this && Abs(this->GetPosition().z - phys->GetPosition().z) < 1.5f)
phys->bHitByTrain = true;
}
+#endif
}
void
CTrain::AddPassenger(CPed *ped)
{
+#ifdef GTA_TRAIN
int i = ped->m_vehDoor;
if((i == TRAIN_POS_LEFT_ENTRY || i == TRAIN_POS_MID_ENTRY || i == TRAIN_POS_RIGHT_ENTRY) && pPassengers[i] == nil){
pPassengers[i] = ped;
@@ -385,11 +400,13 @@ CTrain::AddPassenger(CPed *ped)
return;
}
}
+#endif
}
void
CTrain::OpenTrainDoor(float ratio)
{
+#ifdef GTA_TRAIN
if(m_rwObject == nil)
return;
@@ -414,6 +431,7 @@ CTrain::OpenTrainDoor(float ratio)
doorL.UpdateRW();
doorR.UpdateRW();
+#endif
}
@@ -421,6 +439,7 @@ CTrain::OpenTrainDoor(float ratio)
void
CTrain::InitTrains(void)
{
+#ifdef GTA_TRAIN
int i, j;
CTrain *train;
@@ -487,21 +506,25 @@ CTrain::InitTrains(void)
for(j = 0; pTrackNodes_S[j].t < StationDist_S[i]; j++);
aStationCoors_S[i] = pTrackNodes_S[j].p;
}
+#endif
}
void
CTrain::Shutdown(void)
{
+#ifdef GTA_TRAIN
delete[] pTrackNodes;
delete[] pTrackNodes_S;
pTrackNodes = nil;
pTrackNodes_S = nil;
+#endif
}
void
CTrain::ReadAndInterpretTrackFile(Const char *filename, CTrainNode **nodes, int16 *numNodes, int32 numStations, float *stationDists,
float *totalLength, float *totalDuration, CTrainInterpolationLine *interpLines, bool rightRail)
{
+#ifdef GTA_TRAIN
bool readingFile = false;
int bp, lp;
int i, tmp;
@@ -623,6 +646,7 @@ CTrain::ReadAndInterpretTrackFile(Const char *filename, CTrainNode **nodes, int1
// end
interpLines[j].time = *totalDuration;
+#endif
}
void
@@ -639,6 +663,7 @@ PlayAnnouncement(uint8 sound, uint8 station)
void
ProcessTrainAnnouncements(void)
{
+#ifdef GTA_TRAIN
for (int i = 0; i < ARRAY_SIZE(StationDist); i++) {
for (int j = 0; j < ARRAY_SIZE(EngineTrackPosition); j++) {
if (!bTrainArrivalAnnounced[i]) {
@@ -667,11 +692,13 @@ ProcessTrainAnnouncements(void)
}
}
}
+#endif
}
void
CTrain::UpdateTrains(void)
{
+#ifdef GTA_TRAIN
int i, j;
uint32 time;
float t, deltaT;
@@ -735,4 +762,5 @@ CTrain::UpdateTrains(void)
// time offset for each train
time += 0x40000/4;
}
+#endif
}
diff --git a/src/vehicles/Train.h b/src/vehicles/Train.h
index 3446eeb5..57cd28de 100644
--- a/src/vehicles/Train.h
+++ b/src/vehicles/Train.h
@@ -82,5 +82,3 @@ public:
float *totalLength, float *totalDuration, CTrainInterpolationLine *interpLines, bool rightRail);
static void UpdateTrains(void);
};
-
-VALIDATE_SIZE(CTrain, 0x2E4);
diff --git a/src/vehicles/Transmission.cpp b/src/vehicles/Transmission.cpp
index 109847a5..1aeabfe0 100644
--- a/src/vehicles/Transmission.cpp
+++ b/src/vehicles/Transmission.cpp
@@ -80,59 +80,51 @@ cTransmission::CalculateDriveAcceleration(const float &gasPedal, uint8 &gear, fl
if(fVelocity > pGearRatio->fShiftUpVelocity){
if(gear != 0 || gasPedal > 0.0f){
gear++;
- time = 0.0f;
return CalculateDriveAcceleration(gasPedal, gear, time, fVelocity, false);
}
}else if(fVelocity < pGearRatio->fShiftDownVelocity && gear != 0){
if(gear != 1 || gasPedal < 0.0f){
gear--;
- time = 0.0f;
return CalculateDriveAcceleration(gasPedal, gear, time, fVelocity, false);
}
}
- if(time > 0.0f){
- // changing gears currently, can't accelerate
- fAcceleration = 0.0f;
- time -= CTimer::GetTimeStepInSeconds();
- }else{
- float speedMul, accelMul;
+ float speedMul, accelMul;
- if(gear < 1){
- // going reverse
- accelMul = (Flags & HANDLING_2G_BOOST) ? 2.0f : 1.0f;
- speedMul = -1.0f;
- }else if(nNumberOfGears == 1){
- accelMul = 1.0f;
- speedMul = 1.0f;
- }else{
- // BUG or not? this is 1.0 normally but 0.0 in the highest gear
- float f = 1.0f - (gear-1)/(nNumberOfGears-1);
- speedMul = 3.0f*sq(f) + 1.0f;
- // This is pretty ugly, could be written more clearly
- if(Flags & HANDLING_2G_BOOST){
- if(gear == 1)
- accelMul = (Flags & HANDLING_1G_BOOST) ? 3.0f : 2.0f;
- else if(gear == 2)
- accelMul = 1.3f;
- else
- accelMul = 1.0f;
- }else if(Flags & HANDLING_1G_BOOST && gear == 1){
- accelMul = 3.0f;
- }else
+ if(gear < 1){
+ // going reverse
+ accelMul = (Flags & HANDLING_2G_BOOST) ? 2.0f : 1.0f;
+ speedMul = -1.0f;
+ }else if(nNumberOfGears == 1){
+ accelMul = 1.0f;
+ speedMul = 1.0f;
+ }else{
+ // BUG or not? this is 1.0 normally but 0.0 in the highest gear
+ float f = 1.0f - (gear-1)/(nNumberOfGears-1);
+ speedMul = 3.0f*sq(f) + 1.0f;
+ // This is pretty ugly, could be written more clearly
+ if(Flags & HANDLING_2G_BOOST){
+ if(gear == 1)
+ accelMul = (Flags & HANDLING_1G_BOOST) ? 2.0f : 1.6f;
+ else if(gear == 2)
+ accelMul = 1.3f;
+ else
accelMul = 1.0f;
- }
-
- if(cheat)
- fCheat = 1.2f;
- else
- fCheat = 1.0f;
- float targetVelocity = Gears[gear].fMaxVelocity*speedMul*fCheat;
- float accel = (targetVelocity - fVelocity) * (fEngineAcceleration*accelMul) / Abs(targetVelocity);
- if(Abs(fVelocity) < Abs(Gears[gear].fMaxVelocity*fCheat))
- fAcceleration = gasPedal * accel * CTimer::GetTimeStep();
- else
- fAcceleration = 0.0f;
+ }else if(Flags & HANDLING_1G_BOOST && gear == 1){
+ accelMul = 2.0f;
+ }else
+ accelMul = 1.0f;
}
+
+ if(cheat)
+ fCheat = 1.2f;
+ else
+ fCheat = 1.0f;
+ float targetVelocity = Gears[gear].fMaxVelocity*speedMul*fCheat;
+ float accel = (targetVelocity - fVelocity) * (fEngineAcceleration*accelMul) / Abs(targetVelocity);
+ if(Abs(fVelocity) < Abs(Gears[gear].fMaxVelocity*fCheat))
+ fAcceleration = gasPedal * accel * CTimer::GetTimeStep();
+ else
+ fAcceleration = 0.0f;
return fAcceleration;
}
diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp
index 451f3a39..d1054191 100644
--- a/src/vehicles/Vehicle.cpp
+++ b/src/vehicles/Vehicle.cpp
@@ -5,6 +5,8 @@
#include "Timer.h"
#include "Pad.h"
#include "Vehicle.h"
+#include "Bike.h"
+#include "Automobile.h"
#include "Pools.h"
#include "HandlingMgr.h"
#include "CarCtrl.h"
@@ -14,10 +16,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"
#include "SaveBuf.h"
bool CVehicle::bWheelsOnlyCheat;
@@ -25,10 +39,17 @@ bool CVehicle::bAllDodosCheat;
bool CVehicle::bCheat3;
bool CVehicle::bCheat4;
bool CVehicle::bCheat5;
-#ifdef ALT_DODO_CHEAT
-bool CVehicle::bAltDodoCheat;
-#endif
+bool CVehicle::bCheat8;
+bool CVehicle::bCheat9;
+bool CVehicle::bCheat10;
+bool CVehicle::bHoverCheat;
+bool CVehicle::bAllTaxisHaveNitro;
bool CVehicle::m_bDisableMouseSteering = true;
+bool CVehicle::bDisableRemoteDetonation;
+bool CVehicle::bDisableRemoteDetonationOnContact;
+#ifndef MASTER
+bool CVehicle::m_bDisplayHandlingInfo;
+#endif
void *CVehicle::operator new(size_t sz) throw() { return CPools::GetVehiclePool()->New(); }
void *CVehicle::operator new(size_t sz, int handle) throw() { return CPools::GetVehiclePool()->New(handle); }
@@ -56,6 +77,7 @@ CVehicle::CVehicle(uint8 CreatedBy)
m_fSteerInput = 0.0f;
m_type = ENTITY_TYPE_VEHICLE;
VehicleCreatedBy = CreatedBy;
+ m_nRouteSeed = 0;
bIsLocked = false;
bIsLawEnforcer = false;
bIsAmbulanceOnDuty = false;
@@ -103,14 +125,54 @@ CVehicle::CVehicle(uint8 CreatedBy)
m_bSirenOrAlarm = false;
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; // never true. probably doesn't work very well
+ 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;
+ m_pLastDamageEntity = nil;
m_fMapObjectHeightAhead = m_fMapObjectHeightBehind = 0.0f;
m_audioEntityId = DMAudio.CreateEntity(AUDIOTYPE_PHYSICAL, this);
if(m_audioEntityId >= 0)
DMAudio.SetEntityStatus(m_audioEntityId, TRUE);
- m_nRadioStation = CGeneral::GetRandomNumber() % USERTRACK;
+ //m_nRadioStation = CGeneral::GetRandomNumber() % NUM_RADIOS;
+ switch(GetModelIndex()){
+ case MI_HUNTER:
+ case MI_ANGEL:
+ case MI_FREEWAY:
+ m_nRadioStation = V_ROCK;
+ break;
+ case MI_RCBARON:
+ case MI_RCBANDIT:
+ case MI_RCRAIDER:
+ case MI_RCGOBLIN:
+ case MI_TOPFUN:
+ case MI_CADDY:
+ case MI_BAGGAGE:
+ m_nRadioStation = RADIO_OFF;
+ break;
+ default:
+ m_nRadioStation = CGeneral::GetRandomNumber() % NUM_RADIOS;
+ break;
+ }
m_pCurGroundEntity = nil;
m_bRainAudioCounter = 0;
m_bRainSamplesCounter = 0;
@@ -122,6 +184,7 @@ CVehicle::CVehicle(uint8 CreatedBy)
AutoPilot.m_nTimeToStartMission = CTimer::GetTimeInMilliseconds();
AutoPilot.m_bStayInCurrentLevel = false;
AutoPilot.m_bIgnorePathfinding = false;
+ AutoPilot.m_nSwitchDistance = 20;
}
CVehicle::~CVehicle()
@@ -171,7 +234,7 @@ CVehicle::SetupLighting(void)
}else{
CVector coors = GetPosition();
float lighting = CPointLights::GenerateLightsAffectingObject(&coors);
- if(!bHasBlip && lighting != 1.0f){
+ if(lighting != 1.0f){
SetAmbientAndDirectionalColours(lighting);
return true;
}
@@ -186,57 +249,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:
{
@@ -277,6 +313,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);
@@ -289,38 +327,68 @@ CVehicle::FlyingControl(eFlightModel flightModel)
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());
+#ifdef FREE_CAM
+ if(!CCamera::bFreeCam || (CCamera::bFreeCam && !CPad::IsAffectedByController))
+#endif
+ 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 fThrust = flightModel == FLIGHT_MODEL_RCPLANE ? fRCAeroThrust : fSeaThrust;
- float fThrustFallOff = flightModel == FLIGHT_MODEL_RCPLANE ? fRCPropFallOff : fSeaPropFallOff;
-
+ float fThrust = pFlyingHandling->fThrust;
+ float fThrustFallOff = pFlyingHandling->fThrustFallOff;
+ float fThrustFallOffBack = pFlyingHandling->fThrustFallOff * 8.0f;
+#ifdef BETTER_ALLCARSAREDODO_CHEAT
+ if (bAllDodosCheat && !IsRealPlane()) {
+ fThrust = pHandling->Transmission.fEngineAcceleration
+ * (pHandling->Transmission.nDriveType == '4' ? 4.0f : 2.0f);
+ fThrust = 5.0f * Max(fThrust, pFlyingHandling->fThrust); //tweak: (cars engines too weak to thrust car on air)
+ fThrustFallOff = Min(0.7f / pHandling->Transmission.fMaxVelocity, fThrustFallOff); //tweak: (use 0.7 instead of 1.0 to make cars 30% faster)
+ fThrustFallOffBack = -1.0f / pHandling->Transmission.fMaxReverseVelocity;
+ }
+#endif
float fForwSpeed = DotProduct(GetMoveSpeed(), GetForward());
CVector vecTail = GetColModel()->boundingBox.min.y * GetForward();
float fPedalState = (CPad::GetPad(0)->GetAccelerate() - CPad::GetPad(0)->GetBrake()) / 255.0f;
- if (fForwSpeed > 0.1f || (flightModel == FLIGHT_MODEL_RCPLANE && fForwSpeed > 0.02f))
- fPedalState += 1.0f;
- else if (fForwSpeed > 0.0f && fPedalState < 0.0f)
- fPedalState = 0.0f;
- float fThrustAccel = (fPedalState - fThrustFallOff * fForwSpeed) * fThrust;
-
+ float fThrustAccel;
+ if(fForwSpeed > 0.0f || fPedalState > 0.0f)
+ fThrustAccel = (fPedalState - fThrustFallOff * fForwSpeed) * fThrust;
+ else
+ fThrustAccel = Min(fPedalState - fThrustFallOffBack * fForwSpeed, 0.0f) * 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 fSideSlipAccel;
- if (flightModel == FLIGHT_MODEL_RCPLANE)
- fSideSlipAccel = Abs(fSideSpeed) * fSideSpeed * fRCSideSlipMult;
- else
- fSideSlipAccel = Abs(fSideSpeed) * fSideSpeed * fSeaSideSlipMult;
+ float fSideSlipAccel = pFlyingHandling->fSideSlip * fSideSpeed * Abs(fSideSpeed);
ApplyMoveForce(m_fMass * GetRight() * fSideSlipAccel * CTimer::GetTimeStep());
float fYaw = -DotProduct(GetSpeed(vecTail), GetRight());
- float fYawAccel;
- if (flightModel == FLIGHT_MODEL_RCPLANE)
- fYawAccel = fRCRudderMult * fYaw * Abs(fYaw) + fRCYawMult * fSteerLR * fForwSpeed;
- else
- fYawAccel = fSeaRudderMult * fYaw * Abs(fYaw) + fSeaYawMult * fSteerLR * fForwSpeed;
+ float fYawAccel = pFlyingHandling->fYawStab * fYaw * Abs(fYaw) + pFlyingHandling->fYaw * fSteerLR * fForwSpeed;
ApplyTurnForce(fYawAccel * GetRight() * m_fTurnMass * CTimer::GetTimeStep(), vecTail);
float fRollAccel;
@@ -328,125 +396,151 @@ CVehicle::FlyingControl(eFlightModel flightModel)
float fDirectionMultiplier = CPad::GetPad(0)->GetLookRight();
if (CPad::GetPad(0)->GetLookLeft())
fDirectionMultiplier = -1;
- fRollAccel = (0.5f * fDirectionMultiplier + fSteerLR) * fRCRollMult;
+ fRollAccel = (0.5f * fDirectionMultiplier + fSteerLR) * pFlyingHandling->fRoll;
}
else
- fRollAccel = fSteerLR * fSeaRollMult;
+ 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 fStabiliseSpeed;
- if (flightModel == FLIGHT_MODEL_RCPLANE)
- fStabiliseSpeed = fRCRollStabilise * fStabiliseDirection * (1.0f - DotProduct(GetRight(), vecStabilise)) * (1.0f - Abs(GetForward().z));
- else
- fStabiliseSpeed = fSeaRollStabilise * fStabiliseDirection * (1.0f - DotProduct(GetRight(), vecStabilise)) * (1.0f - Abs(GetForward().z));
- ApplyTurnForce(fStabiliseSpeed * 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(GetSpeed(vecTail), GetUp());
- float fSteerUD = -CPad::GetPad(0)->GetSteeringUpDown() / 128.0f;
- float fPitchAccel;
- if (flightModel == FLIGHT_MODEL_RCPLANE)
- fPitchAccel = fRCTailMult * fTail * Abs(fTail) + fRCPitchMult * fSteerUD * fForwSpeed;
- else
- fPitchAccel = fSeaTailMult * fTail * Abs(fTail) + fSeaPitchMult * fSteerUD * fForwSpeed;
+ float fPitchAccel = pFlyingHandling->fPitchStab * fTail * Abs(fTail) + pFlyingHandling->fPitch * fSteerUD * fForwSpeed;
ApplyTurnForce(fPitchAccel * m_fTurnMass * GetUp() * CTimer::GetTimeStep(), vecTail);
float fLift = DotProduct(GetMoveSpeed(), GetUp()) / Max(0.01f, GetMoveSpeed().Magnitude()); //accel*angle
- float fLiftAccel;
- if (flightModel == FLIGHT_MODEL_RCPLANE)
- fLiftAccel = (fRCFormLiftMult - fRCAttackLiftMult * fLift) * SQR(fForwSpeed);
- else
- fLiftAccel = (fSeaFormLiftMult - fSeaAttackLiftMult * fLift) * SQR(fForwSpeed);
+ float fLiftAccel = (pFlyingHandling->fFormLift - pFlyingHandling->fAttackLift * fLift) * SQR(fForwSpeed);
float fLiftImpulse = fLiftAccel * m_fMass * CTimer::GetTimeStep();
if (GRAVITY * CTimer::GetTimeStep() * m_fMass < fLiftImpulse) {
if (flightModel == FLIGHT_MODEL_RCPLANE && GetPosition().z > 50.0f)
fLiftImpulse = CTimer::GetTimeStep() * 0.9f*GRAVITY * m_fMass;
else if (flightModel == FLIGHT_MODEL_SEAPLANE && GetPosition().z > 80.0f)
fLiftImpulse = CTimer::GetTimeStep() * 0.9f*GRAVITY * m_fMass;
+#ifdef BETTER_ALLCARSAREDODO_CHEAT
+ else if(bAllDodosCheat && GetPosition().z > 170.0f)
+ fLiftImpulse = CTimer::GetTimeStep() * 0.9f * GRAVITY * m_fMass;
+#endif
}
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_MIAMI_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;
+#ifdef RESTORE_ALLCARSHELI_CHEAT
+ tFlyingHandlingData* flyingHandling = bAllCarCheat && !IsRealHeli() ? mod_HandlingManager.GetFlyingPointer(HANDLING_MAVERICK) : pFlyingHandling;
+#else
+ tFlyingHandlingData* flyingHandling = pFlyingHandling;
+#endif
+ float rm = Pow(flyingHandling->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());
-#if GTA_VERSION >= GTA3_PC_11
- 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 = flyingHandling->fThrust * fThrust + 0.45f;
+ ApplyMoveForce(GRAVITY * CVector(0.0f, 0.0f, 0.5f) * m_fMass * CTimer::GetTimeStep());
+ }else
+ fThrust = flyingHandling->fThrust * fThrust + 0.95f;
+ fThrust -= flyingHandling->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, -flyingHandling->fFormLift, flyingHandling->fFormLift);
+ float upImpulseRight = -upRight * flyingHandling->fAttackLift * m_fTurnMass * CTimer::GetTimeStep();
+ ApplyTurnForce(upImpulseRight * GetUp(), GetRight());
+
+ float upFwd = Clamp(GetForward().z, -flyingHandling->fFormLift, flyingHandling->fFormLift);
+ float upImpulseFwd = -upFwd * flyingHandling->fAttackLift * m_fTurnMass * CTimer::GetTimeStep();
+ ApplyTurnForce(upImpulseFwd * GetUp(), GetForward());
+ }else{
+ float upRight = GetRight().z < 0.0f ? -flyingHandling->fFormLift : flyingHandling->fFormLift;
+ float upImpulseRight = -upRight * flyingHandling->fAttackLift * m_fTurnMass * CTimer::GetTimeStep();
+ ApplyTurnForce(upImpulseRight * GetUp(), GetRight());
+
+ float upFwd = GetForward().z < 0.0f ? -flyingHandling->fFormLift : flyingHandling->fFormLift;
+ float upImpulseFwd = -upFwd * flyingHandling->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;
+#ifdef FREE_CAM
+ if (!CCamera::bFreeCam || (CCamera::bFreeCam && !CPad::IsAffectedByController))
+#endif
+ if(Abs(CPad::GetPad(0)->GetCarGunLeftRight()) > 1.0f)
+ fYaw = CPad::GetPad(0)->GetCarGunLeftRight() / 128.0f;
}
+#ifdef FREE_CAM
+ if(!CCamera::bFreeCam || (CCamera::bFreeCam && !CPad::IsAffectedByController))
+#endif
+ 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, GetForward()), -200.0f, 1.3f);
- fRoll = Clamp(10.0f * DotProduct(m_vecMoveSpeed, GetRight()), -200.0f, 1.3f);
+ fPitch = Clamp(flyingHandling->fPitchStab * DotProduct(m_vecMoveSpeed, GetForward()), -200.0f, 1.3f);
+ fRoll = Clamp(flyingHandling->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() * flyingHandling->fPitch * m_fTurnMass * CTimer::GetTimeStep(), GetForward());
+ ApplyTurnForce(fRoll * GetUp() * flyingHandling->fRoll * m_fTurnMass * CTimer::GetTimeStep(), GetRight());
- CVector vecResistance;
- if (GetModelIndex() == MI_MIAMI_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 = flyingHandling->fSideSlip * fSideSpeed * Abs(fSideSpeed);
+ ApplyMoveForce(m_fMass * GetRight() * fSideSlipAccel * CTimer::GetTimeStep());
+ float fYawAccel = flyingHandling->fYawStab * fSideSpeed * Abs(fSideSpeed) + flyingHandling->fYaw * fYaw;
+ ApplyTurnForce(fYawAccel * GetRight() * m_fTurnMass * CTimer::GetTimeStep(), -GetForward());
+
+ ApplyTurnForce(fYaw * GetForward() * flyingHandling->fYaw * m_fTurnMass * CTimer::GetTimeStep(), GetRight());
+
+ float rX = Pow(flyingHandling->vecTurnRes.x, CTimer::GetTimeStep());
+ float rY = Pow(flyingHandling->vecTurnRes.y, CTimer::GetTimeStep());
+ float rZ = Pow(flyingHandling->vecTurnRes.z, CTimer::GetTimeStep());
CVector vecTurnSpeed = Multiply3x3(m_vecTurnSpeed, GetMatrix());
- float fResistanceMultiplier = Pow(1.0f / (fSpinSpeedRes * SQR(vecTurnSpeed.z) + 1.0f) * rZ, CTimer::GetTimeStep());
+ float fResistanceMultiplier = Pow(1.0f / (flyingHandling->vecSpeedRes.z * SQR(vecTurnSpeed.z) + 1.0f) * rZ, CTimer::GetTimeStep());
float fResistance = vecTurnSpeed.z * fResistanceMultiplier - vecTurnSpeed.z;
vecTurnSpeed.x *= rX;
vecTurnSpeed.y *= rY;
@@ -458,8 +552,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 = false;
+ 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 = entity->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;
+
+ hadCollision = true;
+ 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_aWheelSpeed[1] > 0.15f){
+ ApplyCollision(CWorld::m_aTempColPts[i], impulse);
+ ApplyTurnForce(m_fTurnMass*ROTOR_COL_TURNMULT*tangentSpeed, colpos - center);
+ heli->m_aWheelSpeed[1] = 0.15f;
+ }else if(heli->m_aWheelSpeed[1] < 0.075f && heli->m_aWheelSpeed[1] > 0.0f)
+ heli->m_aWheelSpeed[1] *= -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);
+
+ }
+
+ 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.1f;
+float fBurstTyreMod = 0.13f;
void
CVehicle::ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelContactSpeed, CVector &wheelContactPoint,
@@ -533,7 +847,11 @@ CVehicle::ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelCon
if(!bBraking){
if(m_fGasPedal < 0.01f){
- if(GetModelIndex() == MI_RCBANDIT)
+ if(IsBike())
+ brake = 0.6f * mod_HandlingManager.fWheelFriction / (pHandling->fMass + 200.0f);
+ else if(pHandling->fMass < 500.0f)
+ brake = 0.2f * mod_HandlingManager.fWheelFriction / pHandling->fMass;
+ else if(GetModelIndex() == MI_RCBANDIT)
brake = 0.2f * mod_HandlingManager.fWheelFriction / pHandling->fMass;
else
brake = mod_HandlingManager.fWheelFriction / pHandling->fMass;
@@ -573,23 +891,199 @@ CVehicle::ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelCon
}
if(fwd != 0.0f || right != 0.0f){
- CVector direction = fwd*wheelFwd + right*wheelRight;
- float speed = direction.Magnitude();
+ 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 = speed*GetMass(wheelContactPoint, direction);
+ float turnImpulse = turnSpeed*GetMass(wheelContactPoint, turnDirection);
ApplyMoveForce(impulse * direction);
- ApplyTurnForce(turnImpulse * direction, wheelContactPoint);
+ ApplyTurnForce(turnImpulse * turnDirection, 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, int8 wheelId, float *wheelSpeed, tWheelState *wheelState, eBikeWheelSpecial special, uint16 wheelStatus)
+CVehicle::ProcessBikeWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelContactSpeed, CVector &wheelContactPoint,
+ int32 wheelsOnGround, float thrust, float brake, float adhesion, float destabTraction, int8 wheelId, float *wheelSpeed, tWheelState *wheelState, eBikeWheelSpecial special, uint16 wheelStatus)
{
- // TODO: mobile code
+ // 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_SIGNIFICANT_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_WHEELSPEC_2 || special == BIKE_WHEELSPEC_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
+ // see above
+ //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
+ // see above
+ //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(destabTraction < 1.0f)
+ right *= destabTraction;
+ }else if(destabTraction < 1.0f){
+ if(!bAlreadySkidding)
+ destabTraction *= pHandling->fTractionLoss;
+ if(sq(adhesion*destabTraction) < speedSq){
+ float l = Sqrt(speedSq);
+ right *= adhesion * destabTraction / 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;
+ ApplyMoveForce(impulse * direction);
+
+ float turnRight = DotProduct(vTurnImpulse, GetRight());
+ float contactRight = DotProduct(wheelContactPoint, GetRight());
+ float contactFwd = DotProduct(wheelContactPoint, GetForward());
+
+ if(wheelId != BIKEWHEEL_REAR || !bBraking && !bReversing)
+ ApplyTurnForce((vTurnImpulse - turnRight*GetRight()) * fTweakBikeWheelTurnForce,
+ wheelContactPoint - contactRight*GetRight());
+
+ ApplyTurnForce(turnRight*GetRight(), contactFwd*GetForward());
+ }
}
float
@@ -610,35 +1104,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_AK47:
- case WEAPONTYPE_M16:
+ 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_TOTAL_INVENTORY_WEAPONS:
+ 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;
@@ -655,6 +1195,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) &&
@@ -667,24 +1253,41 @@ 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_CAR, this);
- }
- for (int i = 0; i < m_nNumMaxPassengers; i++) {
- if (pPassengers[i]) {
- pPassengers[i]->bFleeAfterExitingCar = true;
- pPassengers[i]->SetObjective(OBJECTIVE_LEAVE_CAR, 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_CAR){
+ 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_CAR, this);
+ pDriver->Say(SOUND_PED_FLEE_SPRINT);
+ }
+ int time = 200;
+ for (int i = 0; i < m_nNumMaxPassengers; i++) {
+ if (pPassengers[i] &&
+ pPassengers[i]->m_objective != OBJECTIVE_LEAVE_CAR &&
+ pPassengers[i]->CharCreatedBy != MISSION_CHAR) {
+ pPassengers[i]->bFleeAfterExitingCar = true;
+ pPassengers[i]->SetObjective(OBJECTIVE_LEAVE_CAR, this);
+ pPassengers[i]->m_objectiveTimer = CTimer::GetTimeInMilliseconds() + time;
+ pPassengers[i]->Say(SOUND_PED_FLEE_SPRINT);
+ time += 200;
+ }
}
}
break;
@@ -726,56 +1329,98 @@ CVehicle::InflictDamage(CEntity* damagedBy, eWeaponType weaponType, float damage
void
CVehicle::DoFixedMachineGuns(void)
{
- if(CPad::GetPad(0)->GetCarGunFired() && !bGunSwitchedOff){
- if(CTimer::GetTimeInMilliseconds() > m_nGunFiringTime + 150){
- CVector source, target;
- float dx, dy, len;
-
- dx = GetForward().x;
- dy = GetForward().y;
- len = Sqrt(SQR(dx) + SQR(dy));
- if(len < 0.1f) len = 0.1f;
- dx /= len;
- dy /= len;
-
- m_nGunFiringTime = CTimer::GetTimeInMilliseconds();
-
- source = GetMatrix() * CVector(2.0f, 2.5f, 1.0f);
- target = source + CVector(dx, dy, 0.0f)*60.0f;
- target += CVector(
- ((CGeneral::GetRandomNumber()&0xFF)-128) * 0.015f,
- ((CGeneral::GetRandomNumber()&0xFF)-128) * 0.015f,
- ((CGeneral::GetRandomNumber()&0xFF)-128) * 0.02f);
- CWeapon::DoTankDoomAiming(this, pDriver, &source, &target);
- FireOneInstantHitRound(&source, &target, 15);
-
- source = GetMatrix() * CVector(-2.0f, 2.5f, 1.0f);
- target = source + CVector(dx, dy, 0.0f)*60.0f;
- target += CVector(
- ((CGeneral::GetRandomNumber()&0xFF)-128) * 0.015f,
- ((CGeneral::GetRandomNumber()&0xFF)-128) * 0.015f,
- ((CGeneral::GetRandomNumber()&0xFF)-128) * 0.02f);
- CWeapon::DoTankDoomAiming(this, pDriver, &source, &target);
- FireOneInstantHitRound(&source, &target, 15);
-
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_SHOT_FIRED, 0.0f);
-
- m_nAmmoInClip--;
- if(m_nAmmoInClip == 0){
+ 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;
- m_nGunFiringTime = CTimer::GetTimeInMilliseconds() + 1400;
- }
}
- }else{
- if(CTimer::GetTimeInMilliseconds() > m_nGunFiringTime + 1400)
- m_nAmmoInClip = 20;
}
}
void
+CVehicle::FireFixedMachineGuns(void)
+{
+ if (CTimer::GetTimeInMilliseconds() <= m_nGunFiringTime + 150)
+ return;
+ CVector source, target;
+ float dx, dy, len;
+
+ dx = GetForward().x;
+ dy = GetForward().y;
+ len = Sqrt(SQR(dx) + SQR(dy));
+ if (len < 0.1f) len = 0.1f;
+ dx /= len;
+ dy /= len;
+
+ m_nGunFiringTime = CTimer::GetTimeInMilliseconds();
+
+ source = GetMatrix() * CVector(2.0f, 2.5f, 1.0f);
+ target = source + CVector(dx, dy, 0.0f) * 60.0f;
+ target += CVector(
+ ((CGeneral::GetRandomNumber() & 0xFF) - 128) * 0.015f,
+ ((CGeneral::GetRandomNumber() & 0xFF) - 128) * 0.015f,
+ ((CGeneral::GetRandomNumber() & 0xFF) - 128) * 0.02f);
+ CWeapon::DoTankDoomAiming(this, pDriver, &source, &target);
+ FireOneInstantHitRound(&source, &target, 15);
+
+ source = GetMatrix() * CVector(-2.0f, 2.5f, 1.0f);
+ target = source + CVector(dx, dy, 0.0f) * 60.0f;
+ target += CVector(
+ ((CGeneral::GetRandomNumber() & 0xFF) - 128) * 0.015f,
+ ((CGeneral::GetRandomNumber() & 0xFF) - 128) * 0.015f,
+ ((CGeneral::GetRandomNumber() & 0xFF) - 128) * 0.02f);
+ CWeapon::DoTankDoomAiming(this, pDriver, &source, &target);
+ FireOneInstantHitRound(&source, &target, 15);
+
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_SHOT_FIRED, 0.0f);
+
+ m_nAmmoInClip--;
+ if (m_nAmmoInClip == 0) {
+ m_nAmmoInClip = 20;
+ m_nGunFiringTime = CTimer::GetTimeInMilliseconds() + 1400;
+ }
+}
+
+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()){
@@ -846,6 +1491,68 @@ CVehicle::ShufflePassengersToMakeSpace(void)
}
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->GetWantedLevel() > 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 > 0 || ped1IsDriver)
+ 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->GetWantedLevel() > 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_CAR, 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]->bHeldHostageInCar = true;
+ peds2[i]->bFleeAfterExitingCar = true;
+ }
+}
+
+void
CVehicle::ProcessDelayedExplosion(void)
{
if(m_nBombTimer == 0)
@@ -861,23 +1568,21 @@ CVehicle::ProcessDelayedExplosion(void)
if(IsCar() && ((CAutomobile*)this)->m_bombType == CARBOMB_TIMEDACTIVE && (m_nBombTimer & 0xFE00) != (prev & 0xFE00))
DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_BOMB_TICK, 0.0f);
- if (m_nBombTimer == 0){
- if(FindPlayerVehicle() != this && m_pBlowUpEntity == FindPlayerPed())
- CWorld::Players[CWorld::PlayerInFocus].AwardMoneyForExplosion(this);
+ if (m_nBombTimer == 0)
BlowUpCar(m_pBlowUpEntity);
- }
}
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;
@@ -885,9 +1590,9 @@ CVehicle::IsLawEnforcementVehicle(void)
}
bool
-CVehicle::UsesSiren(uint32 id)
+CVehicle::UsesSiren(void)
{
- switch(id){
+ switch(GetModelIndex()){
case MI_FIRETRUCK:
case MI_AMBULAN:
case MI_FBICAR:
@@ -895,6 +1600,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;
@@ -906,24 +1613,7 @@ CVehicle::IsVehicleNormal(void)
{
if (!pDriver || m_nNumPassengers != 0 || GetStatus() == STATUS_WRECKED)
return false;
- switch (GetModelIndex()){
- case MI_FIRETRUCK:
- case MI_AMBULAN:
- case MI_TAXI:
- case MI_POLICE:
- case MI_ENFORCER:
- case MI_BUS:
- case MI_RHINO:
- case MI_BARRACKS:
- case MI_DODO:
- case MI_COACH:
- case MI_CABBIE:
- case MI_RCBANDIT:
- case MI_BORGNINE:
- return false;
- default:
- return true;
- }
+ return GetModelInfo()->m_vehicleClass != -1;
}
bool
@@ -931,9 +1621,8 @@ CVehicle::CarHasRoof(void)
{
if((pHandling->Flags & HANDLING_HAS_NO_ROOF) == 0)
return true;
- if(m_aExtras[0] && m_aExtras[1])
- return false;
- return true;
+ // component 0 is assumed to be a roof
+ return m_aExtras[0] == 0 || m_aExtras[1] == 0;
}
bool
@@ -1000,7 +1689,8 @@ 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_LOCKED_BUT_CAN_BE_DAMAGED)
return false;
if(ped->IsPlayer() && m_nDoorLock == CARLOCK_LOCKOUT_PLAYER_ONLY)
return false;
@@ -1008,10 +1698,18 @@ CVehicle::CanPedOpenLocks(CPed *ped)
}
bool
+CVehicle::CanDoorsBeDamaged(void)
+{
+ return m_nDoorLock == CARLOCK_NOT_USED ||
+ m_nDoorLock == CARLOCK_UNLOCKED ||
+ m_nDoorLock == CARLOCK_LOCKED_BUT_CAN_BE_DAMAGED;
+}
+
+bool
CVehicle::CanPedEnterCar(void)
{
// can't enter when car is on side
- if(GetUp().z > 0.1f || GetUp().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;
@@ -1023,16 +1721,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 ||
@@ -1055,6 +1751,23 @@ CVehicle::CanPedExitCar(void)
}
}
+bool
+CVehicle::CanPedJumpOutCar(void)
+{
+ if(GetUp().z < 0.3f)
+ return false;
+ float speed = m_vecMoveSpeed.MagnitudeSqr();
+ return speed < 0.1f || speed > 0.5f ? false : true;
+}
+
+bool
+CVehicle::CanPedJumpOffBike(void)
+{
+ if(pPassengers[0])
+ return false;
+ return m_vecMoveSpeed.MagnitudeSqr() < 0.07f ? false : true;
+}
+
void
CVehicle::ChangeLawEnforcerState(uint8 enable)
{
@@ -1079,7 +1792,7 @@ CVehicle::SetUpDriver(void)
if(VehicleCreatedBy != RANDOM_VEHICLE)
return nil;
- pDriver = CPopulation::AddPedInCar(this);
+ pDriver = CPopulation::AddPedInCar(this, true);
pDriver->m_pMyVehicle = this;
pDriver->m_pMyVehicle->RegisterReference((CEntity**)&pDriver->m_pMyVehicle);
pDriver->bInVehicle = true;
@@ -1092,15 +1805,31 @@ CVehicle::SetUpDriver(void)
CPed*
CVehicle::SetupPassenger(int n)
{
+ int i;
+
if(pPassengers[n])
return pPassengers[n];
- pPassengers[n] = CPopulation::AddPedInCar(this);
- 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];
@@ -1113,23 +1842,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)
- 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_BORGNINE)
- 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.02f*driver->m_fMass * GetUp());
+ else
+ ApplyTurnForce(0.0f, 0.0f, -0.02f*driver->m_fMass,
+ driver->GetPosition().x - GetPosition().x,
+ driver->GetPosition().y - GetPosition().y,
+ 0.0f);
}
bool
@@ -1137,10 +1885,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.02f*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){
@@ -1157,10 +1908,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.02f*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;
@@ -1177,6 +1931,22 @@ CVehicle::RemoveDriver(void)
if (GetStatus() != STATUS_WRECKED)
#endif
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;
}
@@ -1202,6 +1972,55 @@ CVehicle::RemovePassenger(CPed *p)
}
}
+bool
+CVehicle::IsDriver(CPed *ped)
+{
+ return ped && 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)
{
@@ -1211,9 +2030,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;
}
@@ -1241,6 +2061,287 @@ 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, (RwUInt8)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].Get();
+ 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].Get();
+ }
+ if(b2 != a1 && b2 != b1 && b2 != c1){
+ // b2 is not in tri1
+ numTri2Verts++;
+ vert4 = colmodel->vertices[b2].Get();
+ }
+ if(c2 != a1 && c2 != b1 && c2 != c1){
+ // c2 is not in tri1
+ numTri2Verts++;
+ vert4 = colmodel->vertices[c2].Get();
+ }
+ // Need exactly one vertex from tri2 for a quad with tri1
+ if(numTri2Verts != 1)
+ continue;
+
+ CVector mid = (vert1 + colmodel->vertices[b1].Get() + colmodel->vertices[c1].Get() + 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
+CVehicle::KillPedsInVehicle(void)
+{
+ int i;
+ if(pDriver){
+ CDarkel::RegisterKillByPlayer(pDriver, WEAPONTYPE_EXPLOSION);
+ if(pDriver->GetPedState() == PED_DRIVING){
+ pDriver->SetDead();
+ if(!pDriver->IsPlayer())
+ pDriver->FlagToDestroyWhenNextProcessed();
+ }else
+ pDriver->SetDie();
+ }
+ for(i = 0; i < m_nNumMaxPassengers; i++){
+ if(pPassengers[i]){
+ CDarkel::RegisterKillByPlayer(pPassengers[i], WEAPONTYPE_EXPLOSION);
+ if(pPassengers[i]->GetPedState() == PED_DRIVING){
+ pPassengers[i]->SetDead();
+ if(!pPassengers[i]->IsPlayer())
+ pPassengers[i]->FlagToDestroyWhenNextProcessed();
+ }else
+ pPassengers[i]->SetDie();
+ }
+ }
+}
+
void
DestroyVehicleAndDriverAndPassengers(CVehicle* pVehicle)
{
@@ -1280,15 +2381,15 @@ CVehicle::Save(uint8*& buf)
WriteSaveBuf(buf, GetPosition().z);
ZeroSaveBuf(buf, 16);
SaveEntityFlags(buf);
- ZeroSaveBuf(buf, 212);
+ ZeroSaveBuf(buf, 208);
AutoPilot.Save(buf);
WriteSaveBuf(buf, m_currentColour1);
WriteSaveBuf(buf, m_currentColour2);
ZeroSaveBuf(buf, 2);
WriteSaveBuf(buf, m_nAlarmState);
- ZeroSaveBuf(buf, 43);
+ ZeroSaveBuf(buf, 42);
WriteSaveBuf(buf, m_nNumMaxPassengers);
- ZeroSaveBuf(buf, 2);
+ ZeroSaveBuf(buf, 3);
WriteSaveBuf(buf, field_1D0[0]);
WriteSaveBuf(buf, field_1D0[1]);
WriteSaveBuf(buf, field_1D0[2]);
@@ -1311,13 +2412,13 @@ CVehicle::Save(uint8*& buf)
WriteSaveBuf(buf, m_nCurrentGear);
ZeroSaveBuf(buf, 3);
WriteSaveBuf(buf, m_fChangeGearTime);
- ZeroSaveBuf(buf, 4);
+ ZeroSaveBuf(buf, 12);
WriteSaveBuf(buf, m_nTimeOfDeath);
ZeroSaveBuf(buf, 2);
WriteSaveBuf(buf, m_nBombTimer);
ZeroSaveBuf(buf, 12);
WriteSaveBuf(buf, m_nDoorLock);
- ZeroSaveBuf(buf, 96);
+ ZeroSaveBuf(buf, 108);
}
void
@@ -1343,15 +2444,15 @@ CVehicle::Load(uint8*& buf)
m_matrix = tmp;
SkipSaveBuf(buf, 16);
LoadEntityFlags(buf);
- SkipSaveBuf(buf, 212);
+ SkipSaveBuf(buf, 208);
AutoPilot.Load(buf);
ReadSaveBuf(&m_currentColour1, buf);
ReadSaveBuf(&m_currentColour2, buf);
SkipSaveBuf(buf, 2);
ReadSaveBuf(&m_nAlarmState, buf);
- SkipSaveBuf(buf, 43);
+ SkipSaveBuf(buf, 42);
ReadSaveBuf(&m_nNumMaxPassengers, buf);
- SkipSaveBuf(buf, 2);
+ SkipSaveBuf(buf, 3);
ReadSaveBuf(&field_1D0[0], buf);
ReadSaveBuf(&field_1D0[1], buf);
ReadSaveBuf(&field_1D0[2], buf);
@@ -1374,12 +2475,44 @@ CVehicle::Load(uint8*& buf)
ReadSaveBuf(&m_nCurrentGear, buf);
SkipSaveBuf(buf, 3);
ReadSaveBuf(&m_fChangeGearTime, buf);
- SkipSaveBuf(buf, 4);
+ SkipSaveBuf(buf, 12);
ReadSaveBuf(&m_nTimeOfDeath, buf);
SkipSaveBuf(buf, 2);
ReadSaveBuf(&m_nBombTimer, buf);
SkipSaveBuf(buf, 12);
ReadSaveBuf(&m_nDoorLock, buf);
- SkipSaveBuf(buf, 96);
+ SkipSaveBuf(buf, 108);
}
#endif
+
+eVehicleAppearance
+CVehicle::GetVehicleAppearance(void)
+{
+ 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_NoFreeAssert(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 738cfc0f..b59b6b19 100644
--- a/src/vehicles/Vehicle.h
+++ b/src/vehicles/Vehicle.h
@@ -6,10 +6,12 @@
#include "AnimationId.h"
#include "WeaponType.h"
#include "Collision.h"
+#include "HandlingMgr.h"
class CPed;
+class CPlayerPed;
+class CCopPed;
class CFire;
-struct tHandlingData;
enum {
RANDOM_VEHICLE = 1,
@@ -18,6 +20,38 @@ enum {
PERMANENT_VEHICLE = 4,
};
+enum eCarNodes
+{
+ CAR_WHEEL_RF = 1,
+ CAR_WHEEL_RM,
+ CAR_WHEEL_RB,
+ CAR_WHEEL_LF,
+ CAR_WHEEL_LM,
+ CAR_WHEEL_LB,
+ CAR_BUMP_FRONT,
+ CAR_BUMP_REAR,
+ CAR_WING_RF,
+ CAR_WING_RR,
+ CAR_DOOR_RF,
+ CAR_DOOR_RR,
+ CAR_WING_LF,
+ CAR_WING_LR,
+ CAR_DOOR_LF,
+ CAR_DOOR_LR,
+ CAR_BONNET,
+ CAR_BOOT,
+ CAR_WINDSCREEN,
+ NUM_CAR_NODES,
+};
+
+enum {
+ CAR_DOOR_FLAG_UNKNOWN = 0x0,
+ CAR_DOOR_FLAG_LF = 0x1,
+ CAR_DOOR_FLAG_LR = 0x2,
+ CAR_DOOR_FLAG_RF = 0x4,
+ CAR_DOOR_FLAG_RR = 0x8
+};
+
enum eCarLock {
CARLOCK_NOT_USED,
CARLOCK_UNLOCKED,
@@ -25,7 +59,18 @@ enum eCarLock {
CARLOCK_LOCKOUT_PLAYER_ONLY,
CARLOCK_LOCKED_PLAYER_INSIDE,
CARLOCK_LOCKED_INITIALLY,
- CARLOCK_FORCE_SHUT_DOORS
+ CARLOCK_FORCE_SHUT_DOORS,
+ CARLOCK_LOCKED_BUT_CAN_BE_DAMAGED
+};
+
+enum eBombType
+{
+ CARBOMB_NONE,
+ CARBOMB_TIMED,
+ CARBOMB_ONIGNITION,
+ CARBOMB_REMOTE,
+ CARBOMB_TIMEDACTIVE,
+ CARBOMB_ONIGNITIONACTIVE,
};
enum eDoors
@@ -89,32 +134,54 @@ 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_APPEARANCE_NONE,
+ VEHICLE_APPEARANCE_CAR,
+ VEHICLE_APPEARANCE_BIKE,
+ VEHICLE_APPEARANCE_HELI,
+ VEHICLE_APPEARANCE_BOAT,
+ VEHICLE_APPEARANCE_PLANE,
};
// TODO: what is this even?
-enum eBikeWheelSpecial {
- BIKE_WHEELSPEC_0, // both wheels on ground
- BIKE_WHEELSPEC_1, // rear wheel on ground
- BIKE_WHEELSPEC_2, // only front wheel on ground
- BIKE_WHEELSPEC_3, // can't happen
+enum eBikeWheelSpecial
+{
+ BIKE_WHEELSPEC_0, // both wheels on ground
+ BIKE_WHEELSPEC_1, // rear wheel on ground
+ BIKE_WHEELSPEC_2, // only front wheel on ground
+ BIKE_WHEELSPEC_3, // can't happen
};
+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;
int8 m_aExtras[2];
int16 m_nAlarmState;
- int16 m_nMissionValue;
+ int16 m_nRouteSeed;
CPed *pDriver;
CPed *pPassengers[8];
uint8 m_nNumPassengers;
@@ -163,15 +230,32 @@ 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;
+#if (!defined GTA_PS2 || defined FIX_BUGS)
+ uint8 m_bombType : 3;
+#endif
+ 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;
+#if (!defined GTA_PS2 || defined FIX_BUGS)
+ CEntity* m_pBombRigger;
+#endif
+ uint32 m_nSetPieceExtendedRangeTime;
uint32 m_nGunFiringTime; // last time when gun on vehicle was fired (used on boats)
uint32 m_nTimeOfDeath;
uint16 m_nTimeBlocked;
@@ -181,12 +265,14 @@ public:
float m_fMapObjectHeightBehind; // rear Z?
eCarLock m_nDoorLock;
int8 m_nLastWeaponDamage; // see eWeaponType, -1 if no damage
+ CEntity *m_pLastDamageEntity;
uint8 m_nRadioStation;
uint8 m_bRainAudioCounter;
uint8 m_bRainSamplesCounter;
- uint8 m_nCarHornTimer;
- uint8 m_nCarHornPattern; // last horn?
+ uint32 m_nCarHornTimer;
+ uint8 m_nCarHornPattern;
uint8 m_bSirenOrAlarm;
+ uint8 m_nCarHornDelay;
int8 m_comedyControlState;
CStoredCollPoly m_aCollPolys[2]; // poly which is under front/rear part of car
float m_fSteerInput;
@@ -216,11 +302,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 bool IsRoomForPedToLeaveCar(uint32 component, CVector *forcedDoorPos) { return false;}
+ 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
@@ -228,6 +318,7 @@ public:
virtual void Load(uint8*& buf);
#endif
+ eVehicleAppearance GetVehicleAppearance(void);
bool IsCar(void) { return m_vehType == VEHICLE_TYPE_CAR; }
bool IsBoat(void) { return m_vehType == VEHICLE_TYPE_BOAT; }
bool IsTrain(void) { return m_vehType == VEHICLE_TYPE_TRAIN; }
@@ -236,24 +327,31 @@ 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, int8 wheelId, float *wheelSpeed, tWheelState *wheelState, eBikeWheelSpecial special, uint16 wheelStatus);
+ void ProcessBikeWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelContactSpeed, CVector &wheelContactPoint,
+ int32 wheelsOnGround, float thrust, float brake, float adhesion, float destabTraction, 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);
+ bool UsesSiren(void);
bool IsVehicleNormal(void);
bool CarHasRoof(void);
bool IsUpsideDown(void);
bool IsOnItsSide(void);
bool CanBeDeleted(void);
bool CanPedOpenLocks(CPed *ped);
+ bool CanDoorsBeDamaged(void);
bool CanPedEnterCar(void);
- bool CanPedExitCar(void);
+ bool CanPedExitCar(bool jumpExit);
+ bool CanPedJumpOutCar(void);
+ bool CanPedJumpOffBike(void);
// do these two actually return something?
CPed *SetUpDriver(void);
CPed *SetupPassenger(int n);
@@ -262,32 +360,92 @@ 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 KillPedsInVehicle(void);
+
+ void SetComponentAtomicAlpha(RpAtomic *atomic, int32 alpha);
+ void UpdateClumpAlpha(void);
+
+ static void HeliDustGenerate(CEntity *heli, float radius, float ground, int rnd);
+ void DoSunGlare(void);
-#ifdef FIX_BUGS
bool IsAlarmOn(void) { return m_nAlarmState != 0 && m_nAlarmState != -1 && GetStatus() != STATUS_WRECKED; }
-#else
- bool IsAlarmOn(void) { return m_nAlarmState != 0 && m_nAlarmState != -1; }
-#endif
CVehicleModelInfo* GetModelInfo() { return (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex()); }
- bool IsTaxi(void) { return GetModelIndex() == MI_TAXI || GetModelIndex() == MI_CABBIE || GetModelIndex() == MI_BORGNINE; }
- AnimationId GetDriverAnim(void) { return IsCar() && bLowVehicle ? ANIM_STD_CAR_SIT_LO : (IsBoat() && GetModelIndex() != MI_SPEEDER ? ANIM_STD_BOAT_DRIVE : ANIM_STD_CAR_SIT); }
+ 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); }
+ bool IsRealPlane(void) { return !!(pHandling->Flags & HANDLING_IS_PLANE); }
static bool bWheelsOnlyCheat;
static bool bAllDodosCheat;
static bool bCheat3;
static bool bCheat4;
static bool bCheat5;
-#ifdef ALT_DODO_CHEAT
- static bool bAltDodoCheat;
-#endif
+ static bool bCheat8;
+ static bool bCheat9;
+ static bool bCheat10;
+ static bool bHoverCheat;
+ static bool bAllTaxisHaveNitro;
static bool m_bDisableMouseSteering;
+ static bool bDisableRemoteDetonation;
+ static bool bDisableRemoteDetonationOnContact;
+#ifndef MASTER
+ static bool m_bDisplayHandlingInfo;
+#endif
};
-VALIDATE_SIZE(CVehicle, 0x288);
-
void DestroyVehicleAndDriverAndPassengers(CVehicle* pVehicle);
+bool IsVehiclePointerValid(CVehicle* pVehicle);
+
+// Names of functions below are made up by us.
+
+// Used in III and VC.
+inline int8 GetCarDoorFlag(int32 carnode) {
+ switch (carnode) {
+ case CAR_DOOR_LF:
+ return CAR_DOOR_FLAG_LF;
+ case CAR_DOOR_LR:
+ return CAR_DOOR_FLAG_LR;
+ case CAR_DOOR_RF:
+ return CAR_DOOR_FLAG_RF;
+ case CAR_DOOR_RR:
+ return CAR_DOOR_FLAG_RR;
+ default:
+ return CAR_DOOR_FLAG_UNKNOWN;
+ }
+}
+
+// VC. Accounts the case numMaxPassengers == 0, only for m_nGettingInFlags.
+inline int8 GetEnterCarDoorFlag(int32 carnode, uint8 numMaxPassengers) {
+ switch (carnode) {
+ case CAR_DOOR_RF:
+ return CAR_DOOR_FLAG_RF;
+ case CAR_DOOR_RR:
+ return CAR_DOOR_FLAG_RR;
+ case CAR_DOOR_LF:
+ if (numMaxPassengers != 0)
+ return CAR_DOOR_FLAG_LF;
+ else
+ return CAR_DOOR_FLAG_LF | CAR_DOOR_FLAG_LR;
+ case CAR_DOOR_LR:
+ if (numMaxPassengers != 0)
+ return CAR_DOOR_FLAG_LR;
+ else
+ return CAR_DOOR_FLAG_LF | CAR_DOOR_FLAG_LR;
+ default:
+ return CAR_DOOR_FLAG_UNKNOWN;
+ }
+}
diff --git a/src/weapons/BulletInfo.cpp b/src/weapons/BulletInfo.cpp
index bfe27e18..b49db74a 100644
--- a/src/weapons/BulletInfo.cpp
+++ b/src/weapons/BulletInfo.cpp
@@ -23,6 +23,7 @@
#include "WeaponInfo.h"
#include "World.h"
#include "SurfaceTable.h"
+#include "Heli.h"
#ifdef SQUEEZE_PERFORMANCE
uint32 bulletInfoInUse;
@@ -32,9 +33,14 @@ uint32 bulletInfoInUse;
#define NUM_PED_BLOOD_PARTICLES (8)
#define BLOOD_PARTICLE_OFFSET (CVector(0.0f, 0.0f, 0.0f))
#define NUM_VEHICLE_SPARKS (16)
+#define NUM_TYRE_POP_SMOKES (4)
#define NUM_OTHER_SPARKS (8)
#define BULLET_HIT_FORCE (7.5f)
-#define MAP_BORDER (1960.0f)
+
+#define BULLET_BOUNDARY_MIN_X -2400.0f
+#define BULLET_BOUNDARY_MAX_X 1600.0f
+#define BULLET_BOUNDARY_MIN_Y -2000.0f
+#define BULLET_BOUNDARY_MAX_Y 2000.0f
CBulletInfo gaBulletInfo[CBulletInfo::NUM_BULLETS];
bool bPlayerSniperBullet;
@@ -91,7 +97,6 @@ void CBulletInfo::Update(void)
if (bulletInfoInUse == 0)
return;
#endif
- bool bAddSound = true;
bPlayerSniperBullet = false;
for (int i = 0; i < NUM_BULLETS; i++) {
CBulletInfo* pBullet = &gaBulletInfo[i];
@@ -107,34 +112,35 @@ void CBulletInfo::Update(void)
}
CVector vecOldPos = pBullet->m_vecPosition;
CVector vecNewPos = pBullet->m_vecPosition + pBullet->m_vecSpeed * CTimer::GetTimeStep() * 0.5f;
- CWorld::bIncludeCarTyres = true;
+
+ if ( vecNewPos.x <= BULLET_BOUNDARY_MIN_X || vecNewPos.x >= BULLET_BOUNDARY_MAX_X || vecNewPos.y <= BULLET_BOUNDARY_MIN_Y || vecNewPos.y >= BULLET_BOUNDARY_MAX_Y ) {
+ pBullet->m_bInUse = false;
+ continue;
+ }
CWorld::bIncludeDeadPeds = true;
+ CWorld::bIncludeBikers = true;
+ CWorld::bIncludeCarTyres = true;
CWorld::pIgnoreEntity = pBullet->m_pSource;
CColPoint point;
CEntity* pHitEntity;
- if (CWorld::ProcessLineOfSight(vecOldPos, vecNewPos, point, pHitEntity, true, true, true, true, true, true)) {
- if (pBullet->m_pSource && (pHitEntity->IsPed() || pHitEntity->IsVehicle()))
- CStats::InstantHitsHitByPlayer++;
+ if (CWorld::ProcessLineOfSight(vecOldPos, vecNewPos, point, pHitEntity, true, true, true, true, true, false, false, true)) {
+
+ CWeapon::CheckForShootingVehicleOccupant(&pHitEntity, &point, pBullet->m_eWeaponType, vecOldPos, vecNewPos);
if (pHitEntity->IsPed()) {
CPed* pPed = (CPed*)pHitEntity;
if (!pPed->DyingOrDead() && pPed != pBullet->m_pSource) {
- if (pPed->DoesLOSBulletHitPed(point)) {
- if (pPed->IsPedInControl() && !pPed->bIsDucking) {
- pPed->ClearAttackByRemovingAnim();
- CAnimBlendAssociation* pAnim = CAnimManager::AddAnimation(pPed->GetClump(), ASSOCGRP_STD, ANIM_STD_HITBYGUN_FRONT);
- pAnim->SetBlend(0.0f, 8.0f);
- }
- pPed->InflictDamage(pBullet->m_pSource, pBullet->m_eWeaponType, pBullet->m_nDamage, (ePedPieceTypes)point.pieceB, pPed->GetLocalDirection(pPed->GetPosition() - point.point));
- CEventList::RegisterEvent(pPed->m_nPedType == PEDTYPE_COP ? EVENT_SHOOT_COP : EVENT_SHOOT_PED, EVENT_ENTITY_PED, pPed, (CPed*)pBullet->m_pSource, 1000);
- pBullet->m_bInUse = false;
+ if (pPed->IsPedInControl() && !pPed->bIsDucking) {
+ pPed->ClearAttackByRemovingAnim();
+ CAnimBlendAssociation* pAnim = CAnimManager::AddAnimation(pPed->GetClump(), ASSOCGRP_STD, ANIM_STD_HITBYGUN_FRONT);
+ pAnim->SetBlend(0.0f, 8.0f);
+ }
+ pPed->InflictDamage(pBullet->m_pSource, pBullet->m_eWeaponType, pBullet->m_nDamage, (ePedPieceTypes)point.pieceB, pPed->GetLocalDirection(pPed->GetPosition() - point.point));
+ CEventList::RegisterEvent(pPed->m_nPedType == PEDTYPE_COP ? EVENT_SHOOT_COP : EVENT_SHOOT_PED, EVENT_ENTITY_PED, pPed, (CPed*)pBullet->m_pSource, 1000);
+ pBullet->m_bInUse = false;
#ifdef SQUEEZE_PERFORMANCE
- bulletInfoInUse--;
+ bulletInfoInUse--;
#endif
- vecNewPos = point.point;
- }
- else {
- bAddSound = false;
- }
+ vecNewPos = point.point;
}
if (CGame::nastyGame) {
CVector vecParticleDirection = (point.point - pPed->GetPosition()) * 0.01f;
@@ -163,13 +169,24 @@ void CBulletInfo::Update(void)
}
}
else if (pHitEntity->IsVehicle()) {
- CVehicle* pVehicle = (CVehicle*)pHitEntity;
- pVehicle->InflictDamage(pBullet->m_pSource, pBullet->m_eWeaponType, pBullet->m_nDamage);
- if (pBullet->m_eWeaponType == WEAPONTYPE_FLAMETHROWER) // huh?
- gFireManager.StartFire(pVehicle, pBullet->m_pSource, 0.8f, true);
- else {
- for (int j = 0; j < NUM_VEHICLE_SPARKS; j++)
- CParticle::AddParticle(PARTICLE_SPARK, point.point, point.normal / 20);
+ CEntity *source = pBullet->m_pSource;
+ if ( !source || !source->IsPed() || ((CPed*)source)->m_attachedTo != pHitEntity) {
+ if ( point.pieceB >= CAR_PIECE_WHEEL_LF && point.pieceB <= CAR_PIECE_WHEEL_RR ) {
+ ((CVehicle*)pHitEntity)->BurstTyre(point.pieceB, true);
+ for (int j=0; j<NUM_TYRE_POP_SMOKES; j++) {
+ CParticle::AddParticle(PARTICLE_BULLETHIT_SMOKE, point.point, point.normal / 20);
+ }
+ } else {
+ // CVector sth(0.0f, 0.0f, 0.0f); // unused
+ ((CVehicle*)pHitEntity)->InflictDamage(source, pBullet->m_eWeaponType, pBullet->m_nDamage);
+ if ( pBullet->m_eWeaponType == WEAPONTYPE_FLAMETHROWER ) {
+ gFireManager.StartFire(pHitEntity, pBullet->m_pSource, 0.8f, 1);
+ } else {
+ for (int j=0; j<NUM_VEHICLE_SPARKS; j++) {
+ CParticle::AddParticle(PARTICLE_SPARK, point.point, point.normal / 20);
+ }
+ }
+ }
}
#ifdef FIX_BUGS
pBullet->m_bInUse = false;
@@ -178,19 +195,28 @@ void CBulletInfo::Update(void)
#endif
vecNewPos = point.point;
#endif
- }
- else {
+ } else {
for (int j = 0; j < NUM_OTHER_SPARKS; j++)
CParticle::AddParticle(PARTICLE_SPARK, point.point, point.normal / 20);
- if (pHitEntity->IsObject()) {
- CObject* pObject = (CObject*)pHitEntity;
- if (!pObject->bInfiniteMass) {
- if (pObject->GetIsStatic() && pObject->m_fUprootLimit <= 0.0f) {
- pObject->SetIsStatic(false);
- pObject->AddToMovingList();
+ CEntity *source = pBullet->m_pSource;
+ if ( !source || !source->IsPed() || ((CPed*)source)->m_attachedTo != pHitEntity) {
+ if (pHitEntity->IsObject()) {
+ CObject *pHitObject = (CObject*)pHitEntity;
+ if ( !pHitObject->bInfiniteMass && pHitObject->m_fCollisionDamageMultiplier < 99.9f) {
+ bool notStatic = !pHitObject->GetIsStatic();
+ if (notStatic && pHitObject->m_fUprootLimit <= 0.0f) {
+ pHitObject->bIsStatic = false;
+ pHitObject->AddToMovingList();
+ }
+
+ notStatic = !pHitObject->GetIsStatic();
+ if (!notStatic) {
+ CVector moveForce = point.normal * -BULLET_HIT_FORCE;
+ pHitObject->ApplyMoveForce(moveForce.x, moveForce.y, moveForce.z);
+ }
+ } else if (pHitObject->m_nCollisionDamageEffect >= DAMAGE_EFFECT_SMASH_COMPLETELY) {
+ pHitObject->ObjectDamage(50.f);
}
- if (!pObject->GetIsStatic())
- pObject->ApplyMoveForce(-BULLET_HIT_FORCE * point.normal);
}
}
#ifdef FIX_BUGS
@@ -201,38 +227,55 @@ void CBulletInfo::Update(void)
vecNewPos = point.point;
#endif
}
- if (pBullet->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE && bAddSound) {
+ if (pBullet->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE || pBullet->m_eWeaponType == WEAPONTYPE_LASERSCOPE) {
cAudioScriptObject* pAudio;
switch (pHitEntity->GetType()) {
- case ENTITY_TYPE_BUILDING:
- pAudio = new cAudioScriptObject();
- pAudio->Posn = pHitEntity->GetPosition();
- pAudio->AudioId = SCRIPT_SOUND_BULLET_HIT_GROUND_1;
- pAudio->AudioEntity = AEHANDLE_NONE;
- DMAudio.CreateOneShotScriptObject(pAudio);
- break;
- case ENTITY_TYPE_OBJECT:
- pAudio = new cAudioScriptObject();
- pAudio->Posn = pHitEntity->GetPosition();
- pAudio->AudioId = SCRIPT_SOUND_BULLET_HIT_GROUND_2;
- pAudio->AudioEntity = AEHANDLE_NONE;
- DMAudio.CreateOneShotScriptObject(pAudio);
- break;
- case ENTITY_TYPE_DUMMY:
- pAudio = new cAudioScriptObject();
- pAudio->Posn = pHitEntity->GetPosition();
- pAudio->AudioId = SCRIPT_SOUND_BULLET_HIT_GROUND_3;
- pAudio->AudioEntity = AEHANDLE_NONE;
- DMAudio.CreateOneShotScriptObject(pAudio);
- break;
- case ENTITY_TYPE_PED:
- DMAudio.PlayOneShot(((CPed*)pHitEntity)->m_audioEntityId, SOUND_WEAPON_HIT_PED, 1.0f);
- ((CPed*)pHitEntity)->Say(SOUND_PED_BULLET_HIT);
- break;
- case ENTITY_TYPE_VEHICLE:
- DMAudio.PlayOneShot(((CVehicle*)pHitEntity)->m_audioEntityId, SOUND_WEAPON_HIT_VEHICLE, 1.0f);
- break;
- default: break;
+ case ENTITY_TYPE_BUILDING:
+ if (!DMAudio.IsAudioInitialised())
+ break;
+
+ pAudio = new cAudioScriptObject();
+ if (pAudio)
+ pAudio->Reset();
+ pAudio->Posn = pHitEntity->GetPosition();
+ pAudio->AudioId = SCRIPT_SOUND_BULLET_HIT_GROUND_1;
+ pAudio->AudioEntity = AEHANDLE_NONE;
+ DMAudio.CreateOneShotScriptObject(pAudio);
+ break;
+ case ENTITY_TYPE_OBJECT:
+ if (!DMAudio.IsAudioInitialised())
+ break;
+
+ pAudio = new cAudioScriptObject();
+ if (pAudio)
+ pAudio->Reset();
+ pAudio->Posn = pHitEntity->GetPosition();
+ pAudio->AudioId = SCRIPT_SOUND_BULLET_HIT_GROUND_2;
+ pAudio->AudioEntity = AEHANDLE_NONE;
+ DMAudio.CreateOneShotScriptObject(pAudio);
+ break;
+ case ENTITY_TYPE_DUMMY:
+ if (!DMAudio.IsAudioInitialised())
+ break;
+
+ pAudio = new cAudioScriptObject();
+ if (pAudio)
+ pAudio->Reset();
+ pAudio->Posn = pHitEntity->GetPosition();
+ pAudio->AudioId = SCRIPT_SOUND_BULLET_HIT_GROUND_3;
+ pAudio->AudioEntity = AEHANDLE_NONE;
+ DMAudio.CreateOneShotScriptObject(pAudio);
+ break;
+ case ENTITY_TYPE_PED:
+ ++CStats::BulletsThatHit;
+ DMAudio.PlayOneShot(((CPed*)pHitEntity)->m_audioEntityId, SOUND_WEAPON_HIT_PED, 1.0f);
+ ((CPed*)pHitEntity)->Say(SOUND_PED_BULLET_HIT);
+ break;
+ case ENTITY_TYPE_VEHICLE:
+ ++CStats::BulletsThatHit;
+ DMAudio.PlayOneShot(((CVehicle*)pHitEntity)->m_audioEntityId, SOUND_WEAPON_HIT_VEHICLE, 1.0f);
+ break;
+ default: break;
}
}
CGlass::WasGlassHitByBullet(pHitEntity, point.point);
@@ -241,19 +284,14 @@ void CBulletInfo::Update(void)
CWorld::pIgnoreEntity = nil;
CWorld::bIncludeDeadPeds = false;
CWorld::bIncludeCarTyres = false;
- if (pBullet->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE) {
+ CWorld::bIncludeBikers = false;
+ if (pBullet->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE || pBullet->m_eWeaponType == WEAPONTYPE_LASERSCOPE) {
bPlayerSniperBullet = true;
PlayerSniperBulletStart = pBullet->m_vecPosition;
PlayerSniperBulletEnd = vecNewPos;
}
pBullet->m_vecPosition = vecNewPos;
- if (pBullet->m_vecPosition.x < -MAP_BORDER || pBullet->m_vecPosition.x > MAP_BORDER ||
- pBullet->m_vecPosition.y < -MAP_BORDER || pBullet->m_vecPosition.y > MAP_BORDER) {
- pBullet->m_bInUse = false;
-#ifdef SQUEEZE_PERFORMANCE
- bulletInfoInUse--;
-#endif
- }
+ CHeli::TestSniperCollision(&PlayerSniperBulletStart, &PlayerSniperBulletEnd);
}
}
diff --git a/src/weapons/Explosion.cpp b/src/weapons/Explosion.cpp
index f79c0278..7683ed97 100644
--- a/src/weapons/Explosion.cpp
+++ b/src/weapons/Explosion.cpp
@@ -25,12 +25,25 @@ CExplosion gaExplosion[NUM_EXPLOSIONS];
RwRGBA colMedExpl = { 0, 0, 0, 0 };
RwRGBA colUpdate = { 0, 0, 0, 0 };
+const RwRGBA colAddExplosion = { 160, 160, 160, 255 };
+const RwRGBA colGrenade = { 96, 96, 96, 255 };
+
int AudioHandle = AEHANDLE_NONE;
void
CExplosion::Initialise()
{
debug("Initialising CExplosion...\n");
+ ClearAllExplosions();
+ AudioHandle = DMAudio.CreateEntity(AUDIOTYPE_EXPLOSION, (void*)1);
+ if (AudioHandle >= 0)
+ DMAudio.SetEntityStatus(AudioHandle, TRUE);
+ debug("CExplosion ready\n");
+}
+
+void
+CExplosion::ClearAllExplosions()
+{
for (int i = 0; i < ARRAY_SIZE(gaExplosion); i++) {
gaExplosion[i].m_ExplosionType = EXPLOSION_GRENADE;
gaExplosion[i].m_vecPosition = CVector(0.0f, 0.0f, 0.0f);
@@ -43,11 +56,8 @@ CExplosion::Initialise()
gaExplosion[i].m_nIteration = 0;
gaExplosion[i].m_fStartTime = 0.0f;
gaExplosion[i].m_bIsBoat = false;
+ gaExplosion[i].m_bMakeSound = true;
}
- AudioHandle = DMAudio.CreateEntity(AUDIOTYPE_EXPLOSION, (void*)1);
- if (AudioHandle >= 0)
- DMAudio.SetEntityStatus(AudioHandle, TRUE);
- debug("CExplosion ready\n");
}
void
@@ -79,6 +89,12 @@ CExplosion::GetExplosionType(uint8 id)
return gaExplosion[id].m_ExplosionType;
}
+bool
+CExplosion::DoesExplosionMakeSound(uint8 id)
+{
+ return gaExplosion[id].m_bMakeSound;
+};
+
CVector *
CExplosion::GetExplosionPosition(uint8 id)
{
@@ -86,14 +102,19 @@ CExplosion::GetExplosionPosition(uint8 id)
}
bool
-CExplosion::AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionType type, const CVector &pos, uint32 lifetime)
+#ifdef SIMPLER_MISSIONS
+CExplosion::AddExplosion(CEntity* explodingEntity, CEntity* culprit, eExplosionType type, const CVector& pos, uint32 lifetime, bool makeSound, float radius)
+#else
+CExplosion::AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionType type, const CVector &pos, uint32 lifetime, bool makeSound)
+#endif
{
CVector pPosn;
CVector posGround;
RwRGBA colorMedium = colMedExpl;
+ RwRGBA color = colAddExplosion;
+ RwRGBA colorGrenade = colGrenade;
bool bDontExplode = false;
- const RwRGBA color = { 160, 160, 160, 255 };
pPosn = pos;
pPosn.z += 5.0f;
#ifdef FIX_BUGS
@@ -128,19 +149,28 @@ CExplosion::AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionT
explosion.m_nIteration = 1;
explosion.m_nActiveCounter = 1;
explosion.m_bIsBoat = false;
+ explosion.m_bMakeSound = makeSound;
explosion.m_nParticlesExpireTime = lifetime != 0 ? CTimer::GetTimeInMilliseconds() + lifetime : 0;
switch (type)
{
case EXPLOSION_GRENADE:
+#ifdef SIMPLER_MISSIONS
+ explosion.m_fRadius = (radius == -1.0f ? 9.0f : radius);
+#else
explosion.m_fRadius = 9.0f;
+#endif
explosion.m_fPower = 300.0f;
explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 750;
explosion.m_fPropagationRate = 0.5f;
posGround = pos;
posGround.z = CWorld::FindGroundZFor3DCoord(posGround.x, posGround.y, posGround.z + 3.0f, nil);
CEventList::RegisterEvent(EVENT_EXPLOSION, posGround, 250);
- if (Distance(explosion.m_vecPosition, TheCamera.GetPosition()) < 40.0f)
- CParticle::AddParticle(PARTICLE_EXPLOSION_LFAST, explosion.m_vecPosition, CVector(0.0f, 0.0f, 0.0f), nil, 5.5f, color);
+ if (Distance(explosion.m_vecPosition, TheCamera.GetPosition()) < 40.0f) {
+ uint8 tmp = CGeneral::GetRandomNumberInRange(0, 64) - 64;
+ colorGrenade.green += tmp;
+ colorGrenade.blue += tmp;
+ CParticle::AddParticle(PARTICLE_EXPLOSION_LFAST, explosion.m_vecPosition, CVector(0.0f, 0.0f, 0.0f), nil, 4.5f, colorGrenade);
+ }
break;
case EXPLOSION_MOLOTOV:
{
@@ -150,18 +180,17 @@ CExplosion::AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionT
explosion.m_fPropagationRate = 0.5f;
posGround = pos;
bool found;
- posGround.z = CWorld::FindGroundZFor3DCoord(posGround.x, posGround.y, posGround.z + 3.0f, &found);
- if (found) {
- float waterLevel;
- if (CWaterLevel::GetWaterLevelNoWaves(posGround.x, posGround.y, posGround.z, &waterLevel)
- && posGround.z < waterLevel
- && waterLevel - 6.0f < posGround.z) // some subway/tunnels check?
- bDontExplode = true;
- else
- gFireManager.StartFire(posGround, 1.8f, false);
- }
- else
+ float tmp = CWorld::FindGroundZFor3DCoord(posGround.x, posGround.y, posGround.z + 3.0f, &found);
+ if (found)
+ posGround.z = tmp;
+
+ float waterLevel;
+ if (CWaterLevel::GetWaterLevelNoWaves(posGround.x, posGround.y, posGround.z, &waterLevel)
+ && posGround.z < waterLevel && waterLevel - 6.0f < posGround.z) { // some subway/tunnels check?
bDontExplode = true;
+ } else if (found) {
+ gFireManager.StartFire(posGround, 1.8f, false);
+ }
break;
}
case EXPLOSION_ROCKET:
@@ -175,6 +204,7 @@ CExplosion::AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionT
break;
case EXPLOSION_CAR:
case EXPLOSION_CAR_QUICK:
+ case EXPLOSION_BOAT:
explosion.m_fRadius = 9.0f;
explosion.m_fPower = 300.0f;
explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 4250;
@@ -184,59 +214,71 @@ CExplosion::AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionT
if (explosion.m_pVictimEntity->IsVehicle() && ((CVehicle*)explosion.m_pVictimEntity)->IsBoat())
explosion.m_bIsBoat = true;
CEventList::RegisterEvent(EVENT_EXPLOSION, EVENT_ENTITY_VEHICLE, explosion.m_pVictimEntity, nil, 1000);
- } else
+ } else {
CEventList::RegisterEvent(EVENT_EXPLOSION, pos, 1000);
+ }
if (explosion.m_pVictimEntity != nil && !explosion.m_bIsBoat) {
- int rn = (CGeneral::GetRandomNumber() & 1) + 2;
- for (int i = 0; i < rn; i++) {
- CParticle::AddParticle(PARTICLE_EXPLOSION_MEDIUM, explosion.m_pVictimEntity->GetPosition(), CVector(0.0f, 0.0f, 0.0f), nil, 3.5f, colMedExpl);
- CParticle::AddParticle(PARTICLE_EXPLOSION_LFAST, explosion.m_pVictimEntity->GetPosition(), CVector(0.0f, 0.0f, 0.0f), nil, 5.5f, color);
- }
CVehicle *veh = (CVehicle*)explosion.m_pVictimEntity;
- int32 component = CAR_WING_LR;
-
- // miami leftover
- if (veh->IsBike())
- component = BIKE_FORKS_REAR;
-
- if (veh->IsComponentPresent(component)) {
- CVector componentPos;
- veh->GetComponentWorldPosition(component, componentPos);
- rn = (CGeneral::GetRandomNumber() & 1) + 1;
+ CVector componentPos;
+
+ if (veh->IsBike()) {
+ veh->GetComponentWorldPosition(BIKE_FORKS_REAR, componentPos);
+ } else if (veh->IsComponentPresent(CAR_BUMP_REAR) && veh->IsComponentPresent(CAR_WHEEL_LB)) { //mb it's another enum
+ CVector tmpVec;
+ veh->GetComponentWorldPosition(CAR_BUMP_REAR, componentPos);
+ veh->GetComponentWorldPosition(CAR_WHEEL_LB, tmpVec);
+ componentPos += tmpVec;
+ componentPos /= 2.0f;
+ } else if (veh->IsComponentPresent(CAR_BOOT)) {
+ veh->GetComponentWorldPosition(CAR_BOOT, componentPos);
+ }
+ if (componentPos.x != 0.0f) {
+ int rn = (CGeneral::GetRandomNumber() & 1) + 1;
for (int i = 0; i < rn; i++)
- CParticle::AddJetExplosion(componentPos, 1.4f, 0.0f);
+ CParticle::AddJetExplosion(componentPos, (CGeneral::GetRandomNumber() & 7) / 7.0f + 1.5f, 0.5f);
}
}
break;
case EXPLOSION_HELI:
- explosion.m_fRadius = 6.0f;
- explosion.m_fPower = 300.0f;
+ case EXPLOSION_HELI2:
+ if (type == EXPLOSION_HELI2) {
+ explosion.m_fRadius = 12.0f;
+ explosion.m_fPower = 500.0f;
+ } else {
+ explosion.m_fRadius = 6.0f;
+ explosion.m_fPower = 300.0f;
+ }
explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 750;
explosion.m_fPropagationRate = 0.5f;
explosion.m_fStartTime = CTimer::GetTimeInMilliseconds();
for (int i = 0; i < 10; i++) {
CVector randpos;
- uint8 x, y, z;
- x = CGeneral::GetRandomNumber();
- y = CGeneral::GetRandomNumber();
- z = CGeneral::GetRandomNumber();
- randpos = pos + CVector(x - 128, y - 128, z - 128) / 20.0f;
+ randpos.x = CGeneral::GetRandomNumber();
+ randpos.y = CGeneral::GetRandomNumber();
+ randpos.z = CGeneral::GetRandomNumber();
+ randpos -= CVector(128, 128, 128);
+ randpos /= 20.0f;
+ randpos += pos;
CParticle::AddParticle(PARTICLE_EXPLOSION_MFAST, randpos, CVector(0.0f, 0.0f, 0.0f), nil, 2.5f, color);
- x = CGeneral::GetRandomNumber();
- y = CGeneral::GetRandomNumber();
- z = CGeneral::GetRandomNumber();
- randpos = pos + CVector(x - 128, y - 128, z - 128) / 20.0f;
+ randpos.x = CGeneral::GetRandomNumber();
+ randpos.y = CGeneral::GetRandomNumber();
+ randpos.z = CGeneral::GetRandomNumber();
+ randpos -= CVector(128, 128, 128);
+ randpos /= 20.0f;
+ randpos += pos;
CParticle::AddParticle(PARTICLE_EXPLOSION_LFAST, randpos, CVector(0.0f, 0.0f, 0.0f), nil, 5.0f, color);
- x = CGeneral::GetRandomNumber();
- y = CGeneral::GetRandomNumber();
- z = CGeneral::GetRandomNumber();
- randpos = pos + CVector(x - 128, y - 128, z - 128) / 20.0f;
+ randpos.x = CGeneral::GetRandomNumber();
+ randpos.y = CGeneral::GetRandomNumber();
+ randpos.z = CGeneral::GetRandomNumber();
+ randpos -= CVector(128, 128, 128);
+ randpos /= 20.0f;
+ randpos += pos;
CParticle::AddJetExplosion(randpos, 1.4f, 3.0f);
}
@@ -259,13 +301,10 @@ CExplosion::AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionT
explosion.m_fPropagationRate = 0.5f;
for (int i = 0; i < 6; i++) {
CVector randpos;
- uint8 x, y, z;
-
- x = CGeneral::GetRandomNumber();
- y = CGeneral::GetRandomNumber();
- z = CGeneral::GetRandomNumber();
- randpos = CVector(x - 128, y - 128, z - 128);
-
+ randpos.x = CGeneral::GetRandomNumber();
+ randpos.y = CGeneral::GetRandomNumber();
+ randpos.z = CGeneral::GetRandomNumber();
+ randpos -= CVector(128, 128, 128);
randpos.x /= 50.0f;
randpos.y /= 50.0f;
randpos.z /= 25.0f;
@@ -297,7 +336,11 @@ CExplosion::AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionT
CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z + 4.0f, nil); // BUG? result is unused
CEventList::RegisterEvent(EVENT_EXPLOSION, posGround, 250);
break;
+ default:
+ debug("Undefined explosion type, AddExplosion, Explosion.cpp");
+ break;
}
+
if (bDontExplode) {
explosion.m_nIteration = 0;
return false;
@@ -306,8 +349,12 @@ CExplosion::AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionT
if (explosion.m_fPower != 0.0f && explosion.m_nParticlesExpireTime == 0)
CWorld::TriggerExplosion(pos, explosion.m_fRadius, explosion.m_fPower, culprit, (type == EXPLOSION_ROCKET || type == EXPLOSION_CAR_QUICK || type == EXPLOSION_MINE || type == EXPLOSION_BARREL || type == EXPLOSION_TANK_GRENADE || type == EXPLOSION_HELI_BOMB));
- TheCamera.CamShake(0.6f, pos.x, pos.y, pos.z);
- CPad::GetPad(0)->StartShake_Distance(300, 128, pos.x, pos.y, pos.z);
+ if (type == EXPLOSION_MOLOTOV) {
+ TheCamera.CamShake(0.2f, pos.x, pos.y, pos.z);
+ } else {
+ TheCamera.CamShake(0.6f, pos.x, pos.y, pos.z);
+ CPad::GetPad(0)->StartShake_Distance(300, 128, pos.x, pos.y, pos.z);
+ }
return true;
}
@@ -333,6 +380,7 @@ CExplosion::Update()
case EXPLOSION_GRENADE:
case EXPLOSION_ROCKET:
case EXPLOSION_HELI:
+ case EXPLOSION_HELI2:
case EXPLOSION_MINE:
case EXPLOSION_BARREL:
if (CTimer::GetFrameCounter() & 1) {
@@ -351,8 +399,10 @@ CExplosion::Update()
point1.z += 5.0f;
CColPoint colPoint;
CEntity *pEntity;
- CWorld::ProcessVerticalLine(point1, -1000.0f, colPoint, pEntity, true, false, false, false, true, false, nil);
- explosion.m_fZshift = colPoint.point.z;
+ if (CWorld::ProcessVerticalLine(point1, -1000.0f, colPoint, pEntity, true, false, false, false, true, false, nil))
+ explosion.m_fZshift = colPoint.point.z;
+ else
+ explosion.m_fZshift = explosion.m_vecPosition.z;
}
float ff = ((float)explosion.m_nIteration * 0.55f);
for (int i = 0; i < 5 * ff; i++) {
@@ -361,8 +411,6 @@ CExplosion::Update()
CVector pos = explosion.m_vecPosition;
pos.x += ff * Sin(angle);
pos.y += ff * Cos(angle);
- pos.z += 5.0f; // what is the point of this?
-
pos.z = explosion.m_fZshift + 0.5f;
CParticle::AddParticle(PARTICLE_EXPLOSION_MEDIUM, pos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, color, CGeneral::GetRandomNumberInRange(-3.0f, 3.0f), CGeneral::GetRandomNumberInRange(-180.0f, 180.0f));
}
@@ -370,9 +418,10 @@ CExplosion::Update()
break;
case EXPLOSION_CAR:
case EXPLOSION_CAR_QUICK:
+ case EXPLOSION_BOAT:
if (someTime >= 3500) {
- if (explosion.m_pVictimEntity != nil && !explosion.m_bIsBoat) {
- if ((CGeneral::GetRandomNumber() & 0xF) == 0) {
+ if (explosion.m_pVictimEntity != nil) {
+ if ((CGeneral::GetRandomNumber() & 0xF) == 0 && !explosion.m_bIsBoat) {
CVehicle *veh = (CVehicle*)explosion.m_pVictimEntity;
uint8 component = CAR_WING_LR;
@@ -383,16 +432,14 @@ CExplosion::Update()
if (veh->IsComponentPresent(component)) {
CVector componentPos;
veh->GetComponentWorldPosition(component, componentPos);
- CParticle::AddJetExplosion(componentPos, 1.5f, 0.0f);
+ CParticle::AddJetExplosion(componentPos, 0.5f, 0.0f);
}
}
if (CTimer::GetTimeInMilliseconds() > explosion.m_fStartTime) {
explosion.m_fStartTime = CTimer::GetTimeInMilliseconds() + 125 + (CGeneral::GetRandomNumber() & 0x7F);
CVector pos = explosion.m_pVictimEntity->GetPosition();
- for (int i = 0; i < (CGeneral::GetRandomNumber() & 1) + 1; i++) {
+ for (int i = 0; i < (CGeneral::GetRandomNumber() & 1) + 1; i++)
CParticle::AddParticle(PARTICLE_EXPLOSION_MEDIUM, pos, CVector(0.0f, 0.0f, 0.0f), nil, 3.5f, color);
- CParticle::AddParticle(PARTICLE_EXPLOSION_LARGE, pos, CVector(0.0f, 0.0f, 0.0f), nil, 5.5f, color);
- }
}
}
if (CTimer::GetFrameCounter() & 1) {
@@ -419,13 +466,15 @@ CExplosion::Update()
CVector pos(x - 128, y - 128, (z % 128) + 1);
pos.Normalise();
- pos *= ff / 5.0f;
+ pos *= (explosion.m_nIteration + 1) * ff / 5.0f;
pos += explosion.m_vecPosition;
pos.z += 0.5f;
CParticle::AddParticle(PARTICLE_EXPLOSION_LARGE, pos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, color, CGeneral::GetRandomNumberInRange(-3.0f, 3.0f), CGeneral::GetRandomNumberInRange(-180.0f, 180.0f));
}
}
break;
+ default:
+ break;
}
if (someTime > 0)
explosion.m_nIteration++;
diff --git a/src/weapons/Explosion.h b/src/weapons/Explosion.h
index bf54328c..e76c99ea 100644
--- a/src/weapons/Explosion.h
+++ b/src/weapons/Explosion.h
@@ -10,7 +10,9 @@ enum eExplosionType
EXPLOSION_ROCKET,
EXPLOSION_CAR,
EXPLOSION_CAR_QUICK,
+ EXPLOSION_BOAT,
EXPLOSION_HELI,
+ EXPLOSION_HELI2,
EXPLOSION_MINE,
EXPLOSION_BARREL,
EXPLOSION_TANK_GRENADE,
@@ -28,22 +30,29 @@ class CExplosion
float m_fStopTime;
uint8 m_nIteration;
uint8 m_nActiveCounter;
+ bool m_bIsBoat;
+ bool m_bMakeSound;
float m_fStartTime;
uint32 m_nParticlesExpireTime;
float m_fPower;
- bool m_bIsBoat;
float m_fZshift;
public:
- static void Initialise();
- static void Shutdown();
- static int8 GetExplosionActiveCounter(uint8 id);
- static void ResetExplosionActiveCounter(uint8 id);
- static uint8 GetExplosionType(uint8 id);
- static CVector *GetExplosionPosition(uint8 id);
- static bool AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionType type, const CVector &pos, uint32 lifetime);
- static void Update();
- static bool TestForExplosionInArea(eExplosionType type, float x1, float x2, float y1, float y2, float z1, float z2);
- static void RemoveAllExplosionsInArea(CVector pos, float radius);
+#ifdef SIMPLER_MISSIONS
+ static bool AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionType type, const CVector &pos, uint32 lifetime, bool makeSound = true, float radius = -1.0f);
+#else
+ static bool AddExplosion(CEntity* explodingEntity, CEntity* culprit, eExplosionType type, const CVector& pos, uint32 lifetime, bool makeSound = true);
+#endif
+ static void ClearAllExplosions(); //done
+ static bool DoesExplosionMakeSound(uint8 id); //done
+ static int8 GetExplosionActiveCounter(uint8 id); //done
+ static CVector *GetExplosionPosition(uint8 id); //done
+ static uint8 GetExplosionType(uint8 id); //done, mb need change type to tExplosionType
+ static void Initialise(); //done
+ static void RemoveAllExplosionsInArea(CVector pos, float radius); //done
+ static void ResetExplosionActiveCounter(uint8 id); //done
+ static void Shutdown(); //done
+ static void Update(); //done
+ static bool TestForExplosionInArea(eExplosionType type, float x1, float x2, float y1, float y2, float z1, float z2); //done, not used
};
extern CExplosion gaExplosion[NUM_EXPLOSIONS]; \ No newline at end of file
diff --git a/src/weapons/ProjectileInfo.cpp b/src/weapons/ProjectileInfo.cpp
index da00b87a..10aa3ef5 100644
--- a/src/weapons/ProjectileInfo.cpp
+++ b/src/weapons/ProjectileInfo.cpp
@@ -20,6 +20,11 @@ uint32 projectileInUse;
CProjectileInfo gaProjectileInfo[NUM_PROJECTILES];
CProjectile *CProjectileInfo::ms_apProjectile[NUM_PROJECTILES];
+#define PROJECTILE_BOUNDARY_MIN_X -2390.0f
+#define PROJECTILE_BOUNDARY_MAX_X 1590.0f
+#define PROJECTILE_BOUNDARY_MIN_Y -1990.0f
+#define PROJECTILE_BOUNDARY_MAX_Y 1990.0f
+
void
CProjectileInfo::Initialise()
{
@@ -66,65 +71,89 @@ CProjectileInfo::AddProjectile(CEntity *entity, eWeaponType weapon, CVector pos,
switch (weapon)
{
- case WEAPONTYPE_ROCKETLAUNCHER:
- {
- float vy = 1.25f;
- time = CTimer::GetTimeInMilliseconds() + 1400;
- if (ped->IsPlayer()) {
- matrix.GetForward() = TheCamera.Cams[TheCamera.ActiveCam].Front;
- matrix.GetUp() = TheCamera.Cams[TheCamera.ActiveCam].Up;
- matrix.GetRight() = CrossProduct(TheCamera.Cams[TheCamera.ActiveCam].Up, TheCamera.Cams[TheCamera.ActiveCam].Front);
- matrix.GetPosition() = pos;
- } else if (ped->m_pSeekTarget != nil) {
- float ry = CGeneral::GetRadianAngleBetweenPoints(1.0f, ped->m_pSeekTarget->GetPosition().z, 1.0f, pos.z);
- float rz = Atan2(-ped->GetForward().x, ped->GetForward().y);
- vy = 0.35f * speed + 0.15f;
- matrix.SetTranslate(0.0f, 1.0f, 1.0f);
- matrix.Rotate(0.0f, ry, rz);
- matrix.GetPosition() += pos;
- } else {
- matrix = ped->GetMatrix();
+ case WEAPONTYPE_ROCKET:
+ {
+ float vy = 0.35f;
+ time = CTimer::GetTimeInMilliseconds() + 2000;
+ if (entity->GetModelIndex() == MI_SPARROW || entity->GetModelIndex() == MI_HUNTER || entity->GetModelIndex() == MI_SENTINEL) {
+ matrix = ped->GetMatrix();
+ matrix.GetPosition() = pos;
+ CVector vecSpeed = ((CPhysical*)entity)->m_vecMoveSpeed;
+ vy += Max(0.0f, DotProduct(vecSpeed, entity->GetForward())) + Max(0.0f, DotProduct(vecSpeed, entity->GetUp()));
+ } else {
+ if (ped->IsPlayer()) {
+ matrix.GetForward() = TheCamera.Cams[TheCamera.ActiveCam].Front;
+ matrix.GetUp() = TheCamera.Cams[TheCamera.ActiveCam].Up;
+ matrix.GetRight() = CrossProduct(TheCamera.Cams[TheCamera.ActiveCam].Up, TheCamera.Cams[TheCamera.ActiveCam].Front);
+ matrix.GetPosition() = pos;
+ } else if (ped->m_pSeekTarget != nil) {
+ float ry = CGeneral::GetRadianAngleBetweenPoints(1.0f, ped->m_pSeekTarget->GetPosition().z, 1.0f, pos.z);
+ float rz = Atan2(-ped->GetForward().x, ped->GetForward().y);
+ vy = 0.35f * speed + 0.15f;
+ matrix.SetTranslate(0.0f, 1.0f, 1.0f);
+ matrix.Rotate(0.0f, ry, rz);
+ matrix.GetPosition() += pos;
+ } else {
+ matrix = ped->GetMatrix();
+ }
+ }
+ velocity = Multiply3x3(matrix, CVector(0.0f, vy, 0.0f));
+ gravity = false;
+ break;
}
- velocity = Multiply3x3(matrix, CVector(0.0f, vy, 0.0f));
- gravity = false;
- break;
- }
- case WEAPONTYPE_FLAMETHROWER:
+ case WEAPONTYPE_MOLOTOV:
+ {
+ time = CTimer::GetTimeInMilliseconds() + 2000;
+ float scale = 0.22f * speed + 0.15f;
+ if (scale < 0.2f)
+ scale = 0.2f;
+ float angle = Atan2(-ped->GetForward().x, ped->GetForward().y);
+ matrix.SetTranslate(0.0f, 0.0f, 0.0f);
+ matrix.RotateZ(angle);
+ matrix.GetPosition() += pos;
+ velocity.x = -1.0f * scale * Sin(angle);
+ velocity.y = scale * Cos(angle);
+ velocity.z = (0.2f * speed + 0.4f) * scale;
+ break;
+ }
+ case WEAPONTYPE_TEARGAS:
+ {
+ time = CTimer::GetTimeInMilliseconds() + 20000;
+ float scale = 0.0f;
+ if (speed != 0.0f)
+ scale = 0.22f * speed + 0.15f;
+ float angle = Atan2(-ped->GetForward().x, ped->GetForward().y);
+ matrix.SetTranslate(0.0f, 0.0f, 0.0f);
+ matrix.RotateZ(angle);
+ matrix.GetPosition() += pos;
+ SpecialCollisionResponseCase = COLLRESPONSE_UNKNOWN5;
+ velocity.x = -1.0f * scale * Sin(angle);
+ velocity.y = scale * Cos(angle);
+ velocity.z = (0.4f * speed + 0.4f) * scale;
+ elasticity = 0.5f;
+ break;
+ }
+ case WEAPONTYPE_GRENADE:
+ case WEAPONTYPE_DETONATOR_GRENADE:
+ {
+ time = CTimer::GetTimeInMilliseconds() + 2000;
+ float scale = 0.0f;
+ if (speed != 0.0f)
+ scale = 0.22f * speed + 0.15f;
+ float angle = Atan2(-ped->GetForward().x, ped->GetForward().y);
+ matrix.SetTranslate(0.0f, 0.0f, 0.0f);
+ matrix.RotateZ(angle);
+ matrix.GetPosition() += pos;
+ SpecialCollisionResponseCase = COLLRESPONSE_UNKNOWN5;
+ velocity.x = -1.0f * scale * Sin(angle);
+ velocity.y = scale * Cos(angle);
+ velocity.z = (0.4f * speed + 0.4f) * scale;
+ elasticity = 0.5f;
+ break;
+ }
+ default:
Error("Undefined projectile type, AddProjectile, ProjectileInfo.cpp");
break;
- case WEAPONTYPE_MOLOTOV:
- {
- time = CTimer::GetTimeInMilliseconds() + 2000;
- float scale = 0.22f * speed + 0.15f;
- if (scale < 0.2f)
- scale = 0.2f;
- float angle = Atan2(-ped->GetForward().x, ped->GetForward().y);
- matrix.SetTranslate(0.0f, 0.0f, 0.0f);
- matrix.RotateZ(angle);
- matrix.GetPosition() += pos;
- velocity.x = -1.0f * scale * Sin(angle);
- velocity.y = scale * Cos(angle);
- velocity.z = (0.2f * speed + 0.4f) * scale;
- break;
- }
- case WEAPONTYPE_GRENADE:
- {
- time = CTimer::GetTimeInMilliseconds() + 2000;
- float scale = 0.0f;
- if (speed != 0.0f)
- scale = 0.22f * speed + 0.15f;
- float angle = Atan2(-ped->GetForward().x, ped->GetForward().y);
- matrix.SetTranslate(0.0f, 0.0f, 0.0f);
- matrix.RotateZ(angle);
- matrix.GetPosition() += pos;
- SpecialCollisionResponseCase = COLLRESPONSE_UNKNOWN5;
- velocity.x = -1.0f * scale * Sin(angle);
- velocity.y = scale * Cos(angle);
- velocity.z = (0.4f * speed + 0.4f) * scale;
- elasticity = 0.5f;
- break;
- }
- default: break;
}
int i = 0;
@@ -139,18 +168,20 @@ CProjectileInfo::AddProjectile(CEntity *entity, eWeaponType weapon, CVector pos,
switch (weapon)
{
- case WEAPONTYPE_ROCKETLAUNCHER:
+ case WEAPONTYPE_ROCKET:
ms_apProjectile[i] = new CProjectile(MI_MISSILE);
break;
- case WEAPONTYPE_FLAMETHROWER:
+ case WEAPONTYPE_TEARGAS:
+ ms_apProjectile[i] = new CProjectile(MI_TEARGAS);
break;
- case WEAPONTYPE_MOLOTOV:
+ case WEAPONTYPE_MOLOTOV:
ms_apProjectile[i] = new CProjectile(MI_MOLOTOV);
break;
- case WEAPONTYPE_GRENADE:
+ case WEAPONTYPE_GRENADE:
+ case WEAPONTYPE_DETONATOR_GRENADE:
ms_apProjectile[i] = new CProjectile(MI_GRENADE);
break;
- default: break;
+ default: break;
}
if (ms_apProjectile[i] == nil)
@@ -174,13 +205,28 @@ CProjectileInfo::AddProjectile(CEntity *entity, eWeaponType weapon, CVector pos,
CWorld::Add(ms_apProjectile[i]);
gaProjectileInfo[i].m_vecPos = ms_apProjectile[i]->GetPosition();
+
+ if (entity && entity->IsPed() && !ped->m_pCollidingEntity) {
+ ped->m_pCollidingEntity = ms_apProjectile[i];
+ }
return true;
}
void
CProjectileInfo::RemoveProjectile(CProjectileInfo *info, CProjectile *projectile)
{
- RemoveNotAdd(info->m_pSource, info->m_eWeaponType, projectile->GetPosition());
+ // TODO(Miami): New parameter: 1
+ switch (info->m_eWeaponType) {
+ case WEAPONTYPE_GRENADE:
+ CExplosion::AddExplosion(nil, info->m_pSource, EXPLOSION_GRENADE, projectile->GetPosition(), 0);
+ break;
+ case WEAPONTYPE_MOLOTOV:
+ CExplosion::AddExplosion(nil, info->m_pSource, EXPLOSION_MOLOTOV, projectile->GetPosition(), 0);
+ break;
+ case WEAPONTYPE_ROCKET:
+ CExplosion::AddExplosion(nil, info->m_pSource->IsVehicle() ? ((CVehicle*)info->m_pSource)->pDriver : info->m_pSource, EXPLOSION_ROCKET, projectile->GetPosition(), 0);
+ break;
+ }
#ifdef SQUEEZE_PERFORMANCE
projectileInUse--;
#endif
@@ -193,18 +239,17 @@ CProjectileInfo::RemoveProjectile(CProjectileInfo *info, CProjectile *projectile
void
CProjectileInfo::RemoveNotAdd(CEntity *entity, eWeaponType weaponType, CVector pos)
{
- switch (weaponType)
- {
- case WEAPONTYPE_GRENADE:
- CExplosion::AddExplosion(nil, entity, EXPLOSION_GRENADE, pos, 0);
- break;
- case WEAPONTYPE_MOLOTOV:
- CExplosion::AddExplosion(nil, entity, EXPLOSION_MOLOTOV, pos, 0);
- break;
- case WEAPONTYPE_ROCKETLAUNCHER:
- CExplosion::AddExplosion(nil, entity, EXPLOSION_ROCKET, pos, 0);
- break;
- default: break;
+ // TODO(Miami): New parameter: 1
+ switch (weaponType) {
+ case WEAPONTYPE_GRENADE:
+ CExplosion::AddExplosion(nil, entity, EXPLOSION_GRENADE, pos, 0);
+ break;
+ case WEAPONTYPE_MOLOTOV:
+ CExplosion::AddExplosion(nil, entity, EXPLOSION_MOLOTOV, pos, 0);
+ break;
+ case WEAPONTYPE_ROCKET:
+ CExplosion::AddExplosion(nil, entity, EXPLOSION_ROCKET, pos, 0);
+ break;
}
}
@@ -216,6 +261,8 @@ CProjectileInfo::Update()
return;
#endif
+ int tearGasOffset = -0.0f; // unused
+
for (int i = 0; i < ARRAY_SIZE(gaProjectileInfo); i++) {
if (!gaProjectileInfo[i].m_bInUse) continue;
@@ -231,21 +278,46 @@ CProjectileInfo::Update()
gaProjectileInfo[i].m_bInUse = false;
continue;
}
+ if ( (gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_DETONATOR_GRENADE || gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_TEARGAS) && ms_apProjectile[i]->m_fElasticity > 0.1f ) {
+ if ( Abs(ms_apProjectile[i]->m_vecMoveSpeed.x) < 0.05f && Abs(ms_apProjectile[i]->m_vecMoveSpeed.y) < 0.05f && Abs(ms_apProjectile[i]->m_vecMoveSpeed.z) < 0.05f ) {
+ ms_apProjectile[i]->m_fElasticity = 0.03f;
+ }
+ }
+ const CVector &projectilePos = ms_apProjectile[i]->GetPosition();
+ CVector nextPos = CTimer::GetTimeStep() * ms_apProjectile[i]->m_vecMoveSpeed + projectilePos;
+
+ if ( nextPos.x <= PROJECTILE_BOUNDARY_MIN_X || nextPos.x >= PROJECTILE_BOUNDARY_MAX_X || nextPos.y <= PROJECTILE_BOUNDARY_MIN_Y || nextPos.y >= PROJECTILE_BOUNDARY_MAX_Y ) {
+ // Not RemoveProjectile, because we don't want no explosion
+ gaProjectileInfo[i].m_bInUse = false;
+ CWorld::Remove(ms_apProjectile[i]);
+ delete ms_apProjectile[i];
+ continue;
+ }
+ if ( gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_TEARGAS && CTimer::GetTimeInMilliseconds() > gaProjectileInfo[i].m_nExplosionTime - 19500 ) {
+ CParticle::AddParticle(PARTICLE_TEARGAS, projectilePos, CVector(0.2f, tearGasOffset, 0.0f), 0, 0.0f, 0, 0, 0, 0);
+ CParticle::AddParticle(PARTICLE_TEARGAS, projectilePos, CVector(-0.2f, tearGasOffset, 0.0f), 0, 0.0f, 0, 0, 0, 0);
+ CParticle::AddParticle(PARTICLE_TEARGAS, projectilePos, CVector(tearGasOffset, tearGasOffset, 0.0f), 0, 0.0f, 0, 0, 0, 0);
+
+ if ( CTimer::GetTimeInMilliseconds() & 0x200 )
+ CWorld::SetPedsChoking(projectilePos.x, projectilePos.y, projectilePos.z, 6.0f, gaProjectileInfo[i].m_pSource);
+ }
- if (gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER) {
- CParticle::AddParticle(PARTICLE_SMOKE, ms_apProjectile[i]->GetPosition(), CVector(0.0f, 0.0f, 0.0f));
+ if (gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_ROCKET) {
+ CParticle::AddParticlesAlongLine(PARTICLE_ROCKET_SMOKE, gaProjectileInfo[i].m_vecPos, projectilePos, CVector(0.0f, 0.0f, 0.0f), 0.7f, 0, 0, 0, 3000);
}
- if (CTimer::GetTimeInMilliseconds() <= gaProjectileInfo[i].m_nExplosionTime) {
- if (gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER) {
+ if (CTimer::GetTimeInMilliseconds() <= gaProjectileInfo[i].m_nExplosionTime || gaProjectileInfo[i].m_nExplosionTime == 0) {
+ if (gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_ROCKET) {
CVector pos = ms_apProjectile[i]->GetPosition();
CWorld::pIgnoreEntity = ms_apProjectile[i];
if (ms_apProjectile[i]->bHasCollided
|| !CWorld::GetIsLineOfSightClear(gaProjectileInfo[i].m_vecPos, pos, true, true, true, true, false, false)
- || gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER && (CHeli::TestRocketCollision(&pos) || CPlane::TestRocketCollision(&pos))) {
+ || CHeli::TestRocketCollision(&pos) || CPlane::TestRocketCollision(&pos)) {
RemoveProjectile(&gaProjectileInfo[i], ms_apProjectile[i]);
}
CWorld::pIgnoreEntity = nil;
+ ms_apProjectile[i]->m_vecMoveSpeed *= 1.07f;
+
} else if (gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_MOLOTOV) {
CVector pos = ms_apProjectile[i]->GetPosition();
CWorld::pIgnoreEntity = ms_apProjectile[i];
@@ -254,15 +326,25 @@ CProjectileInfo::Update()
|| ((gaProjectileInfo[i].m_vecPos - gaProjectileInfo[i].m_pSource->GetPosition()).MagnitudeSqr() >= 2.0f))
{
if (ms_apProjectile[i]->bHasCollided
- || !CWorld::GetIsLineOfSightClear(gaProjectileInfo[i].m_vecPos, pos, true, true, true, true, false, false)
- || gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER && (CHeli::TestRocketCollision(&pos) || CPlane::TestRocketCollision(&pos))) {
+ || !CWorld::GetIsLineOfSightClear(gaProjectileInfo[i].m_vecPos, pos, true, true, true, true, false, false)) {
RemoveProjectile(&gaProjectileInfo[i], ms_apProjectile[i]);
}
}
CWorld::pIgnoreEntity = nil;
}
} else {
- RemoveProjectile(&gaProjectileInfo[i], ms_apProjectile[i]);
+ if (gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_DETONATOR_GRENADE) {
+ CEntity *ent = gaProjectileInfo[i].m_pSource;
+ if (ent->IsPed() && ((CPed*)ped)->IsPlayer()) {
+ CPed *ped = (CPed*)ent;
+ if (ped->GetWeapon(ped->GetWeaponSlot(WEAPONTYPE_DETONATOR)).m_eWeaponType != WEAPONTYPE_DETONATOR
+ || ped->GetWeapon(ped->GetWeaponSlot(WEAPONTYPE_DETONATOR)).m_nAmmoTotal == 0) {
+ gaProjectileInfo[i].m_nExplosionTime = 0;
+ }
+ }
+ } else {
+ RemoveProjectile(&gaProjectileInfo[i], ms_apProjectile[i]);
+ }
}
gaProjectileInfo[i].m_vecPos = ms_apProjectile[i]->GetPosition();
@@ -275,7 +357,7 @@ CProjectileInfo::IsProjectileInRange(float x1, float x2, float y1, float y2, flo
bool result = false;
for (int i = 0; i < ARRAY_SIZE(ms_apProjectile); i++) {
if (gaProjectileInfo[i].m_bInUse) {
- if (gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER || gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_MOLOTOV || gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_GRENADE) {
+ if (gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_ROCKET || gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_MOLOTOV || gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_GRENADE) {
const CVector &pos = ms_apProjectile[i]->GetPosition();
if (pos.x >= x1 && pos.x <= x2 && pos.y >= y1 && pos.y <= y2 && pos.z >= z1 && pos.z <= z2) {
result = true;
@@ -296,6 +378,19 @@ CProjectileInfo::IsProjectileInRange(float x1, float x2, float y1, float y2, flo
}
void
+CProjectileInfo::RemoveDetonatorProjectiles()
+{
+ for (int i = 0; i < ARRAY_SIZE(ms_apProjectile); i++) {
+ if (gaProjectileInfo[i].m_bInUse && gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_DETONATOR_GRENADE) {
+ CExplosion::AddExplosion(nil, gaProjectileInfo[i].m_pSource, EXPLOSION_GRENADE, gaProjectileInfo[i].m_vecPos, 0); // TODO(Miami): New parameter: 1
+ gaProjectileInfo[i].m_bInUse = false;
+ CWorld::Remove(ms_apProjectile[i]);
+ delete ms_apProjectile[i];
+ }
+ }
+}
+
+void
CProjectileInfo::RemoveAllProjectiles()
{
#ifdef SQUEEZE_PERFORMANCE
diff --git a/src/weapons/ProjectileInfo.h b/src/weapons/ProjectileInfo.h
index 3d8074c9..d1688948 100644
--- a/src/weapons/ProjectileInfo.h
+++ b/src/weapons/ProjectileInfo.h
@@ -26,6 +26,7 @@ public:
static void RemoveNotAdd(CEntity *entity, eWeaponType weaponType, CVector pos);
static bool RemoveIfThisIsAProjectile(CObject *pObject);
static void RemoveAllProjectiles();
+ static void RemoveDetonatorProjectiles();
static void Update();
static bool IsProjectileInRange(float x1, float x2, float y1, float y2, float z1, float z2, bool remove);
};
diff --git a/src/weapons/ShotInfo.cpp b/src/weapons/ShotInfo.cpp
index e604093c..788bcbe1 100644
--- a/src/weapons/ShotInfo.cpp
+++ b/src/weapons/ShotInfo.cpp
@@ -146,4 +146,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 6eab1a65..2d219e2d 100644
--- a/src/weapons/Weapon.cpp
+++ b/src/weapons/Weapon.cpp
@@ -30,25 +30,47 @@
#include "WaterLevel.h"
#include "WeaponInfo.h"
#include "World.h"
+#include "SurfaceTable.h"
+#include "Bike.h"
+#include "Glass.h"
+#include "Sprite.h"
+#include "Pickups.h"
#include "SaveBuf.h"
-uint16 gReloadSampleTime[WEAPONTYPE_LAST_WEAPONTYPE] =
+float fReloadAnimSampleFraction[5] = { 0.5f, 0.7f, 0.75f, 0.75f, 0.7f };
+float fSeaSparrowAimingAngle = 10.0f;
+float fHunterAimingAngle = 30.0f;
+float fPlayerAimScaleDist = 5.0f;
+float fPlayerAimScale = 2.5f;
+
+bool CWeapon::bPhotographHasBeenTaken;
+
+#ifdef SECUROM
+int32 sniperPirateCheck = 0x00797743; // 'Cwy\0' ???
+#endif
+
+#ifdef FREE_CAM
+static bool
+Find3rdPersonCamTargetVectorFromCachedVectors(float dist, CVector pos, CVector& source, CVector& target, CVector camSource, CVector camFront, CVector camUp)
{
- 0, // UNARMED
- 0, // BASEBALLBAT
- 250, // COLT45
- 400, // UZI
- 650, // SHOTGUN
- 300, // AK47
- 300, // M16
- 423, // SNIPERRIFLE
- 400, // ROCKETLAUNCHER
- 0, // FLAMETHROWER
- 0, // MOLOTOV
- 0, // GRENADE
- 0, // DETONATOR
- 0 // HELICANNON
-};
+ if (CPad::GetPad(0)->GetLookBehindForPed()) {
+ source = pos;
+ target = dist * FindPlayerPed()->GetForward() + source;
+ return false;
+ } else {
+ float angleX = DEGTORAD((CCamera::m_f3rdPersonCHairMultX - 0.5f) * 1.8f * 0.5f * TheCamera.Cams[TheCamera.ActiveCam].FOV * CDraw::GetAspectRatio());
+ float angleY = DEGTORAD((0.5f - CCamera::m_f3rdPersonCHairMultY) * 1.8f * 0.5f * TheCamera.Cams[TheCamera.ActiveCam].FOV);
+ source = camSource;
+ target = camFront;
+ target += camUp * Tan(angleY);
+ target += CrossProduct(camFront, camUp) * Tan(angleX);
+ target.Normalise();
+ source += DotProduct(pos - source, target) * target;
+ target = dist * target + source;
+ return true;
+ }
+}
+#endif
CWeaponInfo *
CWeapon::GetInfo()
@@ -58,6 +80,17 @@ CWeapon::GetInfo()
return info;
}
+CWeapon::CWeapon(eWeaponType type, int32 ammo)
+{
+ m_eWeaponType = type;
+ m_eWeaponState = WEAPONSTATE_READY;
+ m_nAmmoTotal = Min(ammo, 99999);
+ m_nAmmoInClip = 0;
+ Reload();
+ m_nTimer = 0;
+ m_bAddRotOffset = false;
+}
+
void
CWeapon::InitialiseWeapons(void)
{
@@ -66,6 +99,7 @@ CWeapon::InitialiseWeapons(void)
CExplosion::Initialise();
CProjectileInfo::Initialise();
CBulletInfo::Initialise();
+ bPhotographHasBeenTaken = false;
}
void
@@ -87,18 +121,41 @@ CWeapon::UpdateWeapons(void)
CBulletInfo::Update();
}
+
void
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;
+ int32 modelId = CWeaponInfo::GetWeaponInfo(m_eWeaponType)->m_nModelId;
+ int32 model2Id = CWeaponInfo::GetWeaponInfo(m_eWeaponType)->m_nModel2Id;
+
+ if ( modelId != -1 )
+ CModelInfo::GetModelInfo(modelId)->AddRef();
+ if ( model2Id != -1 )
+ CModelInfo::GetModelInfo(model2Id)->AddRef();
+}
+
+void
+CWeapon::Shutdown()
+{
+ int32 modelId = CWeaponInfo::GetWeaponInfo(m_eWeaponType)->m_nModelId;
+ if (modelId != -1)
+ CModelInfo::GetModelInfo(modelId)->RemoveRef();
+
+ int32 model2Id = CWeaponInfo::GetWeaponInfo(m_eWeaponType)->m_nModel2Id;
+ if (model2Id != -1)
+ CModelInfo::GetModelInfo(model2Id)->RemoveRef();
+
+ m_eWeaponType = WEAPONTYPE_UNARMED;
+ m_eWeaponState = WEAPONSTATE_READY;
+ m_nAmmoInClip = 0;
+ m_nAmmoTotal = 0;
+ m_nTimer = 0;
}
bool
@@ -108,19 +165,18 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
CVector fireOffset(0.0f, 0.0f, 0.6f);
CVector *source = fireSource;
-
- if (!fireSource)
- {
- fireOffset = shooter->GetMatrix() * fireOffset;
#ifdef FIX_BUGS
- static CVector tmp;
- tmp = fireOffset;
- source = &tmp;
+ static CVector shooterSource;
#else
- source = &fireOffset;
+ CVector shooterSource;
#endif
-
+
+ if ( !fireSource )
+ {
+ shooterSource = shooter->GetMatrix() * fireOffset;
+ source = &shooterSource;
}
+
if ( m_bAddRotOffset )
{
float heading = RADTODEG(shooter->GetForward().Heading());
@@ -133,44 +189,60 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
return false;
bool fired;
+ bool addFireRateAsDelay = true;
if ( GetInfo()->m_eWeaponFire != WEAPON_FIRE_MELEE )
{
- if ( m_nAmmoInClip <= 0 )
- return false;
+ if (m_nAmmoInClip <= 0) {
+ if (m_nAmmoTotal <= 0 || m_eWeaponState == WEAPONSTATE_RELOADING)
+ return false;
+
+ Reload();
+ }
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_UZI:
- case WEAPONTYPE_AK47:
- {
- fired = FireInstantHit(shooter, source);
-
- break;
- }
-
case WEAPONTYPE_SNIPERRIFLE:
+ case WEAPONTYPE_LASERSCOPE:
{
- fired = FireSniper(shooter);
-
+ if (shooter == FindPlayerPed())
+ fired = FireSniper(shooter);
+ else
+ fired = FireInstantHit(shooter, source);
+
break;
}
-
- case WEAPONTYPE_M16:
+
+ case WEAPONTYPE_COLT45:
+ case WEAPONTYPE_PYTHON:
+ case WEAPONTYPE_UZI:
+ case WEAPONTYPE_TEC9:
+ case WEAPONTYPE_SILENCED_INGRAM:
+ case WEAPONTYPE_MP5:
+ case WEAPONTYPE_M4:
+ case WEAPONTYPE_RUGER:
+ case WEAPONTYPE_M60:
+ case WEAPONTYPE_MINIGUN:
+ case WEAPONTYPE_HELICANNON:
{
- if ( TheCamera.PlayerWeaponMode.Mode == CCam::MODE_M16_1STPERSON && shooter == FindPlayerPed() )
+ if ((TheCamera.PlayerWeaponMode.Mode == CCam::MODE_HELICANNON_1STPERSON || TheCamera.PlayerWeaponMode.Mode == CCam::MODE_M16_1STPERSON)
+ && shooter == FindPlayerPed()) {
+ addFireRateAsDelay = true;
fired = FireM16_1stPerson(shooter);
- else
+ } else {
+ addFireRateAsDelay = false;
fired = FireInstantHit(shooter, source);
-
+ }
break;
}
@@ -193,12 +265,12 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
case WEAPONTYPE_MOLOTOV:
case WEAPONTYPE_GRENADE:
+ case WEAPONTYPE_DETONATOR_GRENADE:
+ case WEAPONTYPE_TEARGAS:
{
if ( shooter == FindPlayerPed() )
{
fired = FireProjectile(shooter, source, ((CPlayerPed*)shooter)->m_fAttackButtonCounter*0.0375f);
- if ( m_eWeaponType == WEAPONTYPE_GRENADE )
- CStats::KgsOfExplosivesUsed++;
}
else if ( shooter->IsPed() && ((CPed*)shooter)->m_pSeekTarget != nil )
{
@@ -210,6 +282,11 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
else
fired = FireProjectile(shooter, source, 0.3f);
+ if (m_eWeaponType == WEAPONTYPE_DETONATOR_GRENADE) {
+ ((CPed*)shooter)->GiveWeapon(WEAPONTYPE_DETONATOR, 1, true);
+ ((CPed*)shooter)->GetWeapon(((CPed*)shooter)->GetWeaponSlot(WEAPONTYPE_DETONATOR)).m_eWeaponState = WEAPONSTATE_READY;
+ ((CPed*)shooter)->SetCurrentWeapon(WEAPONTYPE_DETONATOR);
+ }
break;
}
@@ -229,16 +306,10 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
break;
}
-
- case WEAPONTYPE_HELICANNON:
+
+ case WEAPONTYPE_CAMERA:
{
- if ( (TheCamera.PlayerWeaponMode.Mode == CCam::MODE_HELICANNON_1STPERSON || TheCamera.PlayerWeaponMode.Mode == CCam::MODE_M16_1STPERSON )
- && shooter == FindPlayerPed() )
- {
- fired = FireM16_1stPerson(shooter);
- }
- else
- fired = FireInstantHit(shooter, source);
+ fired = TakePhotograph(shooter);
break;
}
@@ -257,17 +328,65 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
if (shooter->IsPed())
{
CPed* shooterPed = (CPed*)shooter;
-
- shooterPed->bIsShooting = true;
-
- if (shooterPed->IsPlayer())
- isPlayer = true;
-
+
+ if ( m_eWeaponType != WEAPONTYPE_CAMERA )
+ {
+ shooterPed->bIsShooting = true;
+
+ if (shooterPed->IsPlayer())
+ isPlayer = true;
+ }
+
DMAudio.PlayOneShot(shooterPed->m_audioEntityId, SOUND_WEAPON_SHOT_FIRED, 0.0f);
+
+ if ( isPlayer )
+ {
+ CPed *aimPed = (CPed *)shooterPed->m_pSeekTarget;
+ if ( aimPed )
+ {
+ if ( aimPed->IsPed() )
+ shooterPed->Say(SOUND_PED_ON_FIRE);
+ }
+ }
}
+
+ switch ( m_eWeaponType )
+ {
+ 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_M60:
+ case WEAPONTYPE_MINIGUN:
+ CStats::RoundsFiredByPlayer++;
+ break;
+
+ case WEAPONTYPE_GRENADE:
+ case WEAPONTYPE_DETONATOR_GRENADE:
+ case WEAPONTYPE_MOLOTOV:
+ case WEAPONTYPE_ROCKET:
+ case WEAPONTYPE_ROCKETLAUNCHER:
+ case WEAPONTYPE_DETONATOR:
+ case WEAPONTYPE_HELICANNON:
+ CStats::KgsOfExplosivesUsed++;
+ break;
+ }
+
+
+ if (m_nAmmoInClip > 0)
+ m_nAmmoInClip--;
- if (m_nAmmoInClip > 0) m_nAmmoInClip--;
- if (m_nAmmoTotal > 0 && (m_nAmmoTotal < 25000 || isPlayer)) m_nAmmoTotal--;
+ 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);
@@ -276,8 +395,12 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
if (m_nAmmoInClip == 0)
{
- if (m_nAmmoTotal == 0)
+ if (m_nAmmoTotal == 0) {
+ if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_CAMERA)
+ CPad::GetPad(0)->Clear(false);
+
return true;
+ }
m_eWeaponState = WEAPONSTATE_RELOADING;
m_nTimer = CTimer::GetTimeInMilliseconds() + GetInfo()->m_nReload;
@@ -291,9 +414,10 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
return true;
}
- m_nTimer = CTimer::GetTimeInMilliseconds() + 1000;
- if (shooter == FindPlayerPed())
- CStats::RoundsFiredByPlayer++;
+ if ( addFireRateAsDelay )
+ m_nTimer = CTimer::GetTimeInMilliseconds() + GetInfo()->m_nFiringRate;
+ else
+ m_nTimer = CTimer::GetTimeInMilliseconds();
}
}
else
@@ -302,9 +426,14 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
{
m_nTimer = CTimer::GetTimeInMilliseconds() + GetInfo()->m_nReload;
m_eWeaponState = WEAPONSTATE_FIRING;
+
+ if (shooter->IsPed() && m_eWeaponType != WEAPONTYPE_CHAINSAW)
+ {
+ DMAudio.PlayOneShot(((CPed*)shooter)->m_audioEntityId, SOUND_MELEE_ATTACK_START, m_eWeaponType << 8);
+ }
}
- FireMelee(shooter, *source);
+ fired = FireMelee(shooter, *source);
}
if ( m_eWeaponType == WEAPONTYPE_UNARMED || m_eWeaponType == WEAPONTYPE_BASEBALLBAT )
@@ -314,7 +443,7 @@ CWeapon::Fire(CEntity *shooter, CVector *fireSource)
}
bool
-CWeapon::FireFromCar(CAutomobile *shooter, bool left)
+CWeapon::FireFromCar(CVehicle *shooter, bool left, bool right)
{
ASSERT(shooter!=nil);
@@ -324,12 +453,15 @@ CWeapon::FireFromCar(CAutomobile *shooter, bool left)
if ( m_nAmmoInClip <= 0 )
return false;
- if ( FireInstantHitFromCar(shooter, left) )
+ if ( FireInstantHitFromCar(shooter, left, right) )
{
DMAudio.PlayOneShot(shooter->m_audioEntityId, SOUND_WEAPON_SHOT_FIRED, 0.0f);
- if ( m_nAmmoInClip > 0 ) m_nAmmoInClip--;
- if ( m_nAmmoTotal < 25000 && m_nAmmoTotal > 0 ) m_nAmmoTotal--;
+ if ( m_nAmmoInClip > 0 )
+ m_nAmmoInClip--;
+
+ if ( m_nAmmoTotal < 25000 && m_nAmmoTotal > 0 && (!shooter || shooter->GetStatus() != STATUS_PLAYER || CStats::GetPercentageProgress() < 100.f))
+ m_nAmmoTotal--;
m_eWeaponState = WEAPONSTATE_FIRING;
@@ -345,8 +477,6 @@ CWeapon::FireFromCar(CAutomobile *shooter, bool left)
}
m_nTimer = CTimer::GetTimeInMilliseconds() + 1000;
- if ( shooter == FindPlayerVehicle() )
- CStats::RoundsFiredByPlayer++;
}
return true;
@@ -360,27 +490,45 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource)
CWeaponInfo *info = GetInfo();
bool anim2Playing = false;
- if ( RpAnimBlendClumpGetAssociation(shooter->GetClump(), info->m_Anim2ToPlay) )
- anim2Playing = true;
-
+
+ if ( CPed::GetFireAnimGround(info, false) != (AnimationId)0 )
+ {
+ if ( RpAnimBlendClumpGetAssociation(shooter->GetClump(), CPed::GetFireAnimGround(info, false)) )
+ anim2Playing = true;
+ }
+
ASSERT(shooter->IsPed());
CPed *shooterPed = (CPed*)shooter;
+ if (shooterPed == FindPlayerPed())
+ {
+ if (m_eWeaponType == WEAPONTYPE_GOLFCLUB || m_eWeaponType == WEAPONTYPE_NIGHTSTICK ||
+ (m_eWeaponType >= WEAPONTYPE_BASEBALLBAT && m_eWeaponType <= WEAPONTYPE_CHAINSAW))
+ {
+ CGlass::BreakGlassPhysically(fireSource, info->m_fRadius);
+
+ 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->IsFlagSet(WEAPONFLAG_FIGHTMODE)))
+ continue;
float victimPedRadius = victimPed->GetBoundRadius() + info->m_fRadius;
if ( victimPed->bUsesCollision || victimPed->Dead() || victimPed->Driving() )
@@ -389,12 +537,28 @@ 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() )
{
@@ -415,65 +579,127 @@ 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;
+ if (victimPed->bInVehicle)
+ {
+ CVehicle *victimVeh = victimPed->m_pMyVehicle;
+ if (victimVeh)
+ {
+ if (victimVeh->IsBike())
+ {
+ CBike *victimBike = (CBike*)victimVeh;
+ victimBike->KnockOffRider(m_eWeaponType, localDir, victimPed, false);
+ if (victimBike->pDriver)
+ victimBike->pDriver->ReactToAttack(shooterPed);
+ else
+ {
+ if (victimVeh->pPassengers[0])
+ victimVeh->pPassengers[0]->ReactToAttack(shooterPed);
+ }
+ continue;
+ }
+ }
+ }
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());
+ 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 )
+ {
+ 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_BLOOD, bloodPos, dir);
+ }
- if ( isBat )
+ 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);
+
+ CVector dropDir(CGeneral::GetRandomNumberInRange(-0.15f, 0.15f), CGeneral::GetRandomNumberInRange(0.1f, 0.35f), 0.f);
+ CVector dropPos(CGeneral::GetRandomNumberInRange(SCREEN_STRETCH_X(50.0f), SCREEN_STRETCH_FROM_RIGHT(50.0f)),
+ CGeneral::GetRandomNumberInRange(SCREEN_STRETCH_Y(50.0f), SCREEN_STRETCH_FROM_BOTTOM(50.0f)), 1.f);
+ CParticle::AddParticle(PARTICLE_BLOODDROP, dropPos, dropDir, 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 += 0.1f * shooterPed->GetUp() + 0.05f * shooterPed->GetRight();
+ 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 > 30.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_STD_HIGHIMPACT_FRONT + localDir), false);
else
victimPed->SetFall(1500, AnimationId(ANIM_STD_HIGHIMPACT_FRONT + localDir), false);
@@ -486,21 +712,151 @@ 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( int32 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);
+
+ CParticle::AddParticle(PARTICLE_HEATHAZE, gaTempSphereColPoints[0].point, CVector(0.0f, 0.0f, 0.0f), 0, 0.0f, 0, 0, 0, 0);
+ }
+ else
+ {
+ nearCar->VehicleDamage(info->m_nDamage* (0.01f * 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_ON_FOOT_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_ON_FOOT_TILL_SAFE);
+ passenger->m_leaveCarTimer = CTimer::GetTimeInMilliseconds() + leaveCarDelay;
+ leaveCarDelay += 200;
+ }
+ }
+ }
+ else
+ {
+ CPed *driver = nearCar->pDriver;
+ if (driver)
+ {
+ if (driver->m_objective != OBJECTIVE_LEAVE_CAR && driver->m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT &&
+ driver->m_objective != OBJECTIVE_FLEE_ON_FOOT_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);
+ }
+
+ CParticle::AddParticle(PARTICLE_HEATHAZE, 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;
}
@@ -542,9 +898,6 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
int32 accuracy = shooterPed->m_wepAccuracy;
int32 inaccuracy = 100-accuracy;
- if ( accuracy != 100 )
- FindPlayerPed(); //what ?
-
CPed *threatAttack = (CPed*)shooterPed->m_pPointGunAt;
if ( threatAttack->IsPed() )
{
@@ -555,19 +908,40 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
target = threatAttack->GetPosition();
target -= *fireSource;
- target *= info->m_fRange / target.Magnitude();
+ float distToTarget = Max(target.Magnitude(), 0.01f);
+ target *= info->m_fRange / distToTarget;
target += *fireSource;
- if ( inaccuracy != 0 )
+ if (shooter == FindPlayerPed() && inaccuracy != 0.f)
+ {
+ float newInaccuracy = fPlayerAimScale * FindPlayerPed()->m_fAttackButtonCounter * (inaccuracy * Min(1.f, fPlayerAimScaleDist / distToTarget));
+ if (FindPlayerPed()->bIsDucking)
+ newInaccuracy *= 0.4f;
+
+ target.x += CGeneral::GetRandomNumberInRange(-0.15f, 0.15f) * newInaccuracy;
+ target.y += CGeneral::GetRandomNumberInRange(-0.15f, 0.15f) * newInaccuracy;
+ target.z += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f) * newInaccuracy;
+ FindPlayerPed()->m_fAttackButtonCounter += info->m_nDamage * 0.04f;
+ }
+ else if (inaccuracy > 0.f)
{
+ if (threatAttack == FindPlayerPed())
+ {
+ float speed = Min(0.33f, FindPlayerPed()->m_vecMoveSpeed.Magnitude());
+ inaccuracy *= (0.3f * speed * 100.f / 33.f + 0.8f);
+ }
target.x += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f) * inaccuracy;
target.y += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f) * inaccuracy;
target.z += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f) * inaccuracy;
}
- CWorld::bIncludeDeadPeds = true;
- ProcessLineOfSight(*fireSource, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, true, false);
+ if (shooter == FindPlayerPed())
+ CWorld::bIncludeDeadPeds = true;
+
+ CWorld::bIncludeBikers = true;
+ ProcessLineOfSight(*fireSource, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, false, false);
CWorld::bIncludeDeadPeds = false;
+ CWorld::bIncludeBikers = false;
}
else
{
@@ -577,11 +951,13 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
shooterPed->TransformToNode(target, PED_HANDR);
- ProcessLineOfSight(*fireSource, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, true, false);
+ CWorld::bIncludeBikers = true;
+ ProcessLineOfSight(*fireSource, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, false, false);
+ CWorld::bIncludeBikers = false;
}
#ifdef FIX_BUGS
// fix muzzleflash rotation
- heading = CGeneral::GetAngleBetweenPoints(fireSource->x, fireSource->y, target.x, target.y);
+ heading = CGeneral::GetAngleBetweenPoints(source.x, source.y, target.x, target.y);
angle = DEGTORAD(heading);
ahead = CVector2D(-Sin(angle), Cos(angle));
@@ -590,38 +966,49 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
}
else if ( shooter == FindPlayerPed() && TheCamera.Cams[0].Using3rdPersonMouseCam() )
{
- CVector src, trgt;
- TheCamera.Find3rdPersonCamTargetVector(info->m_fRange, *fireSource, src, trgt);
#ifdef FREE_CAM
- CPed *shooterPed = (CPed *)shooter;
- if((shooterPed->m_pedIK.m_flags & CPedIK::GUN_POINTED_SUCCESSFULLY) == 0) {
- trgt.x = info->m_fRange;
- trgt.y = 0.0f;
- trgt.z = 0.0f;
+ if (CCamera::bFreeCam) {
+ CPlayerPed* shooterPed = (CPlayerPed*)shooter;
+ Find3rdPersonCamTargetVectorFromCachedVectors(info->m_fRange, *fireSource, source, target, shooterPed->m_cachedCamSource, shooterPed->m_cachedCamFront, shooterPed->m_cachedCamUp);
- shooterPed->TransformToNode(trgt, PED_HANDR);
- }
+ if ((shooterPed->m_pedIK.m_flags & CPedIK::GUN_POINTED_SUCCESSFULLY) == 0) {
+ target.x = info->m_fRange;
+ target.y = 0.0f;
+ target.z = 0.0f;
+
+ shooterPed->TransformToNode(target, PED_HANDR);
+ }
+ } else
#endif
+ {
+ TheCamera.Find3rdPersonCamTargetVector(info->m_fRange, *fireSource, source, target);
+ }
#ifdef FIX_BUGS
// fix muzzleflash rotation
- heading = CGeneral::GetAngleBetweenPoints(src.x, src.y, trgt.x, trgt.y);
+ heading = CGeneral::GetAngleBetweenPoints(source.x, source.y, target.x, target.y);
angle = DEGTORAD(heading);
ahead = CVector2D(-Sin(angle), Cos(angle));
ahead.Normalise();
#endif
-
+ CWorld::bIncludeBikers = true;
CWorld::bIncludeDeadPeds = true;
- ProcessLineOfSight(src, trgt,point, victim, m_eWeaponType, shooter, true, true, true, true, true, true, false);
+ CWorld::bIncludeCarTyres = true;
+ ProcessLineOfSight(source, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, false, false);
+ CWorld::bIncludeBikers = false;
CWorld::bIncludeDeadPeds = false;
+ CWorld::bIncludeCarTyres = false;
+
+ if (victim)
+ CheckForShootingVehicleOccupant(&victim, &point, m_eWeaponType, source, target);
int32 rotSpeed = 1;
- if ( m_eWeaponType == WEAPONTYPE_M16 )
+ if ( m_eWeaponType == WEAPONTYPE_M4 )
rotSpeed = 4;
CVector bulletPos;
- if ( CHeli::TestBulletCollision(&src, &trgt, &bulletPos, 4) )
+ if ( CHeli::TestBulletCollision(&source, &target, &bulletPos, 4) )
{
for ( int32 i = 0; i < 16; i++ )
CParticle::AddParticle(PARTICLE_SPARK, bulletPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, rotSpeed);
@@ -629,140 +1016,117 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
}
else
{
- float shooterHeading = RADTODEG(shooter->GetForward().Heading());
- float shooterAngle = DEGTORAD(shooterHeading);
+ uint32 model = shooter->GetModelIndex();
+ if (model == MI_HUNTER || model == MI_SEASPAR || model == MI_SPARROW)
+ {
+ float inaccuracyMult = 0.6f;
+ target = shooter->GetForward();
+ if (shooter->GetStatus() == STATUS_PLAYER)
+ {
+ target *= info->m_fRange;
+ target += *fireSource;
+ CWeapon::DoDriveByAutoAiming(FindPlayerPed(), (CVehicle*)shooter, fireSource, &target);
+ target -= *fireSource;
+ target.Normalise();
+ if (model == MI_SEASPAR || model == MI_SPARROW)
+ inaccuracyMult = 0.1f;
+ else
+ inaccuracyMult = 0.3f;
+ }
+ target.x += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f) * inaccuracyMult;
+ target.y += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f) * inaccuracyMult;
+ target.z += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f) * inaccuracyMult;
- CVector2D rotOffset(-Sin(shooterAngle), Cos(shooterAngle));
- rotOffset.Normalise();
+ target.Normalise();
+ target *= info->m_fRange;
+ target += *fireSource;
+ CWorld::pIgnoreEntity = shooter;
+ ProcessLineOfSight(*fireSource, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, true, false);
+ CWorld::pIgnoreEntity = nil;
- target = *fireSource;
- target.x += rotOffset.x * info->m_fRange;
- target.y += rotOffset.y * info->m_fRange;
+ int32 rotSpeed = 1;
+ if (m_eWeaponType == WEAPONTYPE_M4)
+ rotSpeed = 4;
- if ( shooter->IsPed() )
- DoDoomAiming(shooter, fireSource, &target);
+ CVector bulletPos;
+ if (CHeli::TestBulletCollision(fireSource, &target, &bulletPos, 4))
+ {
+ for (int32 i = 0; i < 16; i++)
+ CParticle::AddParticle(PARTICLE_SPARK, bulletPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, rotSpeed);
+ }
+ }
+ else
+ {
+ float shooterHeading = RADTODEG(shooter->GetForward().Heading());
+ float shooterAngle = DEGTORAD(shooterHeading);
- ProcessLineOfSight(*fireSource, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, true, false);
+ CVector2D rotOffset(-Sin(shooterAngle), Cos(shooterAngle));
+ rotOffset.Normalise();
- int32 rotSpeed = 1;
- if ( m_eWeaponType == WEAPONTYPE_M16 )
- rotSpeed = 4;
+ target = *fireSource;
+ target.x += rotOffset.x * info->m_fRange;
+ target.y += rotOffset.y * info->m_fRange;
- CVector bulletPos;
- if ( CHeli::TestBulletCollision(fireSource, &target, &bulletPos, 4) )
- {
- for ( int32 i = 0; i < 16; i++ )
- CParticle::AddParticle(PARTICLE_SPARK, bulletPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, rotSpeed);
+ CParticle::HandleShootableBirdsStuff(shooter, *fireSource);
+ if (shooter->IsPed() && ((CPed*)shooter)->bDoomAim && (shooter != FindPlayerPed() || !info->IsFlagSet(WEAPONFLAG_CANAIM)))
+ {
+ CWeapon::DoDoomAiming(shooter, fireSource, &target);
+ }
+
+ CWorld::bIncludeBikers = true;
+ ProcessLineOfSight(*fireSource, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, false, false);
+ CWorld::bIncludeBikers = false;
+
+ int32 rotSpeed = 1;
+ if (m_eWeaponType == WEAPONTYPE_M4)
+ rotSpeed = 4;
+
+ CVector bulletPos;
+ if (CHeli::TestBulletCollision(fireSource, &target, &bulletPos, 4))
+ {
+ for (int32 i = 0; i < 16; i++)
+ CParticle::AddParticle(PARTICLE_SPARK, bulletPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, rotSpeed);
+ }
}
}
- if ( victim && shooter->IsPed() && victim == ((CPed*)shooter)->m_leader )
- return false;
+ if ( shooter->IsPed() && victim)
+ {
+ if (victim == ((CPed*)shooter)->m_leader)
+ return false;
+
+ if (victim->IsPed() && ((CPed*)shooter)->IsGangMember() && !((CPed*)victim)->CanBeDamagedByThisGangMember((CPed*)shooter))
+ return false;
+ }
- CEventList::RegisterEvent(EVENT_GUNSHOT, EVENT_ENTITY_PED, shooter, (CPed *)shooter, 1000);
+ if (shooter->IsPed())
+ CEventList::RegisterEvent(EVENT_GUNSHOT, EVENT_ENTITY_PED, shooter, (CPed*)shooter, 1000);
+ else if (shooter->IsVehicle() && ((CVehicle*)shooter)->pDriver)
+ CEventList::RegisterEvent(EVENT_GUNSHOT, EVENT_ENTITY_VEHICLE, shooter, ((CVehicle*)shooter)->pDriver, 1000);
if ( shooter == FindPlayerPed() )
{
- CStats::InstantHitsFiredByPlayer++;
if ( !(CTimer::GetFrameCounter() & 3) )
MakePedsJumpAtShot((CPhysical*)shooter, fireSource, &target);
}
switch ( m_eWeaponType )
{
- case WEAPONTYPE_AK47:
- {
- 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:
+ case WEAPONTYPE_M4:
+ case WEAPONTYPE_RUGER:
+ case WEAPONTYPE_M60:
+ case WEAPONTYPE_MINIGUN:
+ case WEAPONTYPE_HELICANNON:
{
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,
- 1.0f, 0.8f, 0.0f, CPointLights::FOG_NONE, false);
-
- CVector gunflashPos = *fireSource;
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.08f);
- 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.06f);
- 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.06f);
-
- gunflashPos = *fireSource;
- gunflashPos += CVector(-0.1f*ahead.x, -0.1f*ahead.y, 0.0f);
- gunflashPos.z += 0.04f;
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.04f);
- gunflashPos.z += 0.04f;
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
- gunflashPos.z += 0.03f;
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
-
- gunflashPos = *fireSource;
- gunflashPos += CVector(-0.1f*ahead.x, -0.1f*ahead.y, 0.0f);
- gunflashPos.z -= 0.04f;
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.04f);
- gunflashPos.z -= 0.04f;
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
- gunflashPos.z -= 0.03f;
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
-
- CVector offset = CrossProduct(CVector(ahead.x, ahead.y, 0.0f), CVector(0.0f, 0.0f, 5.0f));
- offset.Normalise2D();
-
- gunflashPos = *fireSource;
- gunflashPos += CVector(-0.1f*ahead.x, -0.1f*ahead.y, 0.0f);
- gunflashPos += CVector(0.06f*offset.x, 0.06f*offset.y, 0.0f);
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.04f);
- gunflashPos += CVector(0.04f*offset.x, 0.04f*offset.y, 0.0f);
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.03f);
- gunflashPos += CVector(0.03f*offset.x, 0.03f*offset.y, 0.0f);
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
-
- gunflashPos = *fireSource;
- gunflashPos += CVector(-0.1f*ahead.x, -0.1f*ahead.y, 0.0f);
- gunflashPos -= CVector(0.06f*offset.x, 0.06f*offset.y, 0.0f);
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.04f);
- gunflashPos -= CVector(0.04f*offset.x, 0.04f*offset.y, 0.0f);
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.03f);
- gunflashPos -= CVector(0.03f*offset.x, 0.03f*offset.y, 0.0f);
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
-
- 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));
+#ifdef FIX_BUGS
+ AddGunFlashBigGuns(*fireSource, target);
+#else
+ AddGunFlashBigGuns(*fireSource, *fireSource + target);
+#endif
CVector gunshellPos = *fireSource;
gunshellPos -= CVector(0.65f*ahead.x, 0.65f*ahead.y, 0.0f);
@@ -775,6 +1139,9 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
}
case WEAPONTYPE_UZI:
+ case WEAPONTYPE_TEC9:
+ case WEAPONTYPE_SILENCED_INGRAM:
+ case WEAPONTYPE_MP5:
{
CPointLights::AddLight(CPointLights::LIGHT_POINT,
*fireSource, CVector(0.0f, 0.0f, 0.0f), 5.0f,
@@ -813,6 +1180,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,
@@ -851,6 +1221,71 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
}
void
+CWeapon::AddGunFlashBigGuns(CVector start, CVector end)
+{
+ CPointLights::AddLight(CPointLights::LIGHT_POINT,
+ start, CVector(0.0f, 0.0f, 0.0f), 5.0f,
+ 1.0f, 0.8f, 0.0f, CPointLights::FOG_NONE, false);
+ CVector gunflashPos = start;
+
+ CVector shootVec = end - start;
+
+ // Wtf did you do there R*?
+ shootVec.Normalise();
+ CVector2D ahead = shootVec;
+ ahead.Normalise();
+
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.08f);
+ 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.06f);
+ 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.06f);
+
+ gunflashPos = start;
+ gunflashPos += CVector(-0.1f * ahead.x, -0.1f * ahead.y, 0.0f);
+ gunflashPos.z += 0.04f;
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.04f);
+ gunflashPos.z += 0.04f;
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
+ gunflashPos.z += 0.03f;
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
+
+ gunflashPos = start;
+ gunflashPos += CVector(-0.1f * ahead.x, -0.1f * ahead.y, 0.0f);
+ gunflashPos.z -= 0.04f;
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.04f);
+ gunflashPos.z -= 0.04f;
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
+ gunflashPos.z -= 0.03f;
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
+
+ CVector offset = CrossProduct(CVector(ahead.x, ahead.y, 0.0f), CVector(0.0f, 0.0f, 5.0f));
+ offset.Normalise2D();
+
+ gunflashPos = start;
+ gunflashPos += CVector(-0.1f * ahead.x, -0.1f * ahead.y, 0.0f);
+ gunflashPos += CVector(0.06f * offset.x, 0.06f * offset.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.04f);
+ gunflashPos += CVector(0.04f * offset.x, 0.04f * offset.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.03f);
+ gunflashPos += CVector(0.03f * offset.x, 0.03f * offset.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
+
+ gunflashPos = start;
+ gunflashPos += CVector(-0.1f * ahead.x, -0.1f * ahead.y, 0.0f);
+ gunflashPos -= CVector(0.06f * offset.x, 0.06f * offset.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.04f);
+ gunflashPos -= CVector(0.04f * offset.x, 0.04f * offset.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.03f);
+ gunflashPos -= CVector(0.03f * offset.x, 0.03f * offset.y, 0.0f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.02f);
+
+ CVector gunsmokePos = start;
+ float rnd = CGeneral::GetRandomNumberInRange(0.05f, 0.25f);
+ CParticle::AddParticle(PARTICLE_GUNSMOKE2, gunsmokePos, CVector(ahead.x * rnd, ahead.y * rnd, 0.0f));
+}
+
+void
CWeapon::AddGunshell(CEntity *shooter, CVector const &source, CVector2D const &direction, float size)
{
ASSERT(shooter!=nil);
@@ -879,6 +1314,7 @@ CWeapon::AddGunshell(CEntity *shooter, CVector const &source, CVector2D const &d
}
}
+
void
CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim,
CVector *source, CVector *target, CColPoint *point, CVector2D ahead)
@@ -892,72 +1328,99 @@ CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim,
if ( victim )
{
- CGlass::WasGlassHitByBullet(victim, point->point);
-
- CVector traceTarget = point->point;
- CBulletTraces::AddTrace(source, &traceTarget);
-
- if ( shooter != nil )
+ if (shooter)
{
- if ( shooter == FindPlayerPed() )
+ if (shooter && shooter->IsPed() && ((CPed*)shooter)->m_attachedTo == victim)
+ return;
+
+ if (shooter->IsPed() && !((CPed*)shooter)->IsPlayer())
{
- if ( victim->IsPed() || victim->IsVehicle() )
- CStats::InstantHitsHitByPlayer++;
+ 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(1500);
+ else
+ shooterPed->SetAttackTimer(3000);
+ }
+ }
+ }
+ }
}
}
+ CGlass::WasGlassHitByBullet(victim, point->point);
+
+ CVector traceTarget = point->point;
+ CBulletTraces::AddTrace(source, &traceTarget, m_eWeaponType, shooter);
- if ( victim->IsPed() && ((CPed*)shooter)->m_nPedType != ((CPed*)victim)->m_nPedType || ((CPed*)shooter)->m_nPedType == PEDTYPE_PLAYER2 )
+ if (victim->IsPed() && shooter->IsVehicle() && ((CVehicle*)shooter)->pDriver)
+ shooter = ((CVehicle*)shooter)->pDriver;
+
+ if ( victim->IsPed() && shooter->IsPed() &&
+ (((CPed*)shooter)->m_nPedType != ((CPed*)victim)->m_nPedType || ((CPed*)shooter)->m_nPedType == PEDTYPE_PLAYER2 ||
+ !((CPed*)shooter)->IsGangMember() && ((CPed*)shooter)->m_nPedType != PEDTYPE_COP))
{
CPed *victimPed = (CPed *)victim;
if ( !victimPed->DyingOrDead() && victim != shooter )
{
- if ( victimPed->DoesLOSBulletHitPed(*point) )
- {
- CVector pos = victimPed->GetPosition();
+ CVector pos = victimPed->GetPosition();
- CVector2D posOffset(source->x-pos.x, source->y-pos.y);
- int32 localDir = victimPed->GetLocalDirection(posOffset);
+ CVector2D posOffset(source->x-pos.x, source->y-pos.y);
+ int32 localDir = victimPed->GetLocalDirection(posOffset);
- victimPed->ReactToAttack(shooter);
+ victimPed->ReactToAttack(shooter);
- if ( !victimPed->IsPedInControl() || victimPed->bIsDucking )
+ if ( !victimPed->IsPedInControl() || victimPed->bIsDucking )
+ {
+ victimPed->InflictDamage(shooter, m_eWeaponType, info->m_nDamage, (ePedPieceTypes)point->pieceB, localDir);
+ }
+ else
+ {
+ if ( victimPed->bCanBeShotInVehicle && (IsShotgun(m_eWeaponType) ||
+ (!victimPed->IsPlayer() && (m_eWeaponType == WEAPONTYPE_HELICANNON || m_eWeaponType == WEAPONTYPE_M60 || m_eWeaponType == WEAPONTYPE_PYTHON))))
{
+ posOffset.Normalise();
+ victimPed->bIsStanding = false;
+
+ victimPed->ApplyMoveForce(posOffset.x*-5.0f, posOffset.y*-5.0f, 5.0f);
+ victimPed->SetFall(1500, AnimationId(ANIM_STD_HIGHIMPACT_FRONT + localDir), false);
+
victimPed->InflictDamage(shooter, m_eWeaponType, info->m_nDamage, (ePedPieceTypes)point->pieceB, localDir);
}
else
{
- if ( m_eWeaponType == WEAPONTYPE_SHOTGUN || m_eWeaponType == WEAPONTYPE_HELICANNON )
+ if ( victimPed->IsPlayer() )
{
- posOffset.Normalise();
- victimPed->bIsStanding = false;
-
- victimPed->ApplyMoveForce(posOffset.x*-5.0f, posOffset.y*-5.0f, 5.0f);
- victimPed->SetFall(1500, AnimationId(ANIM_STD_HIGHIMPACT_FRONT + localDir), false);
-
- victimPed->InflictDamage(shooter, m_eWeaponType, info->m_nDamage, (ePedPieceTypes)point->pieceB, localDir);
- }
- else
- {
- if ( victimPed->IsPlayer() )
- {
- CPlayerPed *victimPlayer = (CPlayerPed *)victimPed;
- if ( victimPlayer->m_nHitAnimDelayTimer < CTimer::GetTimeInMilliseconds() )
- {
- victimPed->ClearAttackByRemovingAnim();
-
- CAnimBlendAssociation *asoc = CAnimManager::AddAnimation(victimPed->GetClump(), ASSOCGRP_STD, AnimationId(ANIM_STD_HITBYGUN_FRONT + localDir));
- ASSERT(asoc!=nil);
-
- asoc->blendAmount = 0.0f;
- asoc->blendDelta = 8.0f;
-
- if ( m_eWeaponType == WEAPONTYPE_AK47 || m_eWeaponType == WEAPONTYPE_M16 )
- victimPlayer->m_nHitAnimDelayTimer = CTimer::GetTimeInMilliseconds() + 2500;
- else
- victimPlayer->m_nHitAnimDelayTimer = CTimer::GetTimeInMilliseconds() + 1000;
- }
- }
- else
+ CPlayerPed *victimPlayer = (CPlayerPed *)victimPed;
+ if ( victimPlayer->m_nHitAnimDelayTimer < CTimer::GetTimeInMilliseconds() && victimPed->m_nPedState != PED_DRIVING )
{
victimPed->ClearAttackByRemovingAnim();
@@ -966,31 +1429,53 @@ CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim,
asoc->blendAmount = 0.0f;
asoc->blendDelta = 8.0f;
+
+ if ( m_eWeaponType == WEAPONTYPE_M4 )
+ victimPlayer->m_nHitAnimDelayTimer = CTimer::GetTimeInMilliseconds() + 2500;
+ else
+ victimPlayer->m_nHitAnimDelayTimer = CTimer::GetTimeInMilliseconds() + 1000;
}
+ }
+ else
+ {
+ victimPed->ClearAttackByRemovingAnim();
+
+ CAnimBlendAssociation *asoc = CAnimManager::AddAnimation(victimPed->GetClump(), ASSOCGRP_STD, AnimationId(ANIM_STD_HITBYGUN_FRONT + localDir));
+ ASSERT(asoc!=nil);
- victimPed->InflictDamage(shooter, m_eWeaponType, info->m_nDamage, (ePedPieceTypes)point->pieceB, localDir);
+ asoc->blendAmount = 0.0f;
+ asoc->blendDelta = 8.0f;
}
+
+ victimPed->InflictDamage(shooter, m_eWeaponType, info->m_nDamage, (ePedPieceTypes)point->pieceB, localDir);
}
+ }
- if ( victimPed->m_nPedType == PEDTYPE_COP )
- CEventList::RegisterEvent(EVENT_SHOOT_COP, EVENT_ENTITY_PED, victim, (CPed*)shooter, 10000);
- else
- CEventList::RegisterEvent(EVENT_SHOOT_PED, EVENT_ENTITY_PED, victim, (CPed*)shooter, 10000);
+ if ( victimPed->m_nPedType == PEDTYPE_COP )
+ CEventList::RegisterEvent(EVENT_SHOOT_COP, EVENT_ENTITY_PED, victim, (CPed*)shooter, 10000);
+ else
+ CEventList::RegisterEvent(EVENT_SHOOT_PED, EVENT_ENTITY_PED, victim, (CPed*)shooter, 10000);
- if ( CGame::nastyGame )
- {
- uint8 bloodAmount = 8;
- if ( m_eWeaponType == WEAPONTYPE_SHOTGUN || m_eWeaponType == WEAPONTYPE_HELICANNON )
- bloodAmount = 32;
+ if ( CGame::nastyGame )
+ {
+ uint8 bloodAmount = 8;
+ if ( IsShotgun(m_eWeaponType) || m_eWeaponType == WEAPONTYPE_HELICANNON )
+ bloodAmount = 32;
- CVector dir = (point->point - victim->GetPosition()) * 0.01f;
- dir.z = 0.01f;
+ CVector dir = (point->point - victim->GetPosition()) * 0.01f;
+ dir.z = 0.01f;
- if ( victimPed->GetIsOnScreen() )
- {
- for ( uint8 i = 0; i < bloodAmount; i++ )
- CParticle::AddParticle(PARTICLE_BLOOD_SMALL, point->point, dir);
- }
+ if ( victimPed->GetIsOnScreen() )
+ {
+ for ( uint8 i = 0; i < bloodAmount; i++ )
+ CParticle::AddParticle(PARTICLE_BLOOD_SMALL, point->point, dir);
+ }
+
+ if (m_eWeaponType == WEAPONTYPE_MINIGUN)
+ {
+ CParticle::AddParticle(PARTICLE_TEST, point->point, CVector(0.f, 0.f, 0.f), nil, 0.f, 0, 0, 0, 0);
+ CParticle::AddParticle(PARTICLE_TEST, point->point + CVector(0.2f, -0.2f, 0.f), CVector(0.f, 0.f, 0.f), nil, 0.f, 0, 0, 0, 0);
+ CParticle::AddParticle(PARTICLE_TEST, point->point + CVector(-0.2f, 0.2f, 0.f), CVector(0.f, 0.f, 0.f), nil, 0.f, 0, 0, 0, 0);
}
}
}
@@ -1035,9 +1520,9 @@ CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim,
CParticle::AddParticle(PARTICLE_SPARK, point->point, point->normal*0.05f);
#ifndef FIX_BUGS
- CVector dist = point->point - (*source);
- CVector offset = dist - Max(0.2f * dist.Magnitude(), 2.0f) * CVector(ahead.x, ahead.y, 0.0f);
- CVector smokePos = *source + offset;
+ CVector dist = point->point - (*source);
+ float distMagnitude = dist.Magnitude();
+ CVector smokePos = point->point - Max(distMagnitude / 10.0f, 0.2f) * dist / distMagnitude;
#else
CVector smokePos = point->point;
#endif // !FIX_BUGS
@@ -1052,20 +1537,30 @@ CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim,
}
case ENTITY_TYPE_VEHICLE:
{
- ((CVehicle *)victim)->InflictDamage(shooter, m_eWeaponType, info->m_nDamage);
+ if (point->pieceB >= CAR_PIECE_WHEEL_LF && point->pieceB <= CAR_PIECE_WHEEL_RR) {
+ ((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 - (*source);
- CVector offset = dist - Max(0.2f*dist.Magnitude(), 0.5f) * CVector(ahead.x, ahead.y, 0.0f);
- CVector smokePos = *source + offset;
+ CVector dist = point->point - (*source);
+ CVector offset = dist - Max(0.2f * dist.Magnitude(), 0.5f) * CVector(ahead.x, ahead.y, 0.0f);
+ CVector smokePos = *source + offset;
#else
- CVector smokePos = point->point;
-#endif // !FIX_BUGS
+ 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));
if ( shooter->IsPed() )
{
@@ -1090,19 +1585,23 @@ CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim,
CObject *victimObject = (CObject *)victim;
- if ( !victimObject->bInfiniteMass )
+ if ( !victimObject->bInfiniteMass && victimObject->m_fCollisionDamageMultiplier < 99.9f)
{
- if ( victimObject->GetIsStatic() && victimObject->m_fUprootLimit <= 0.0f )
+ bool notStatic = !victimObject->GetIsStatic();
+ if (notStatic && victimObject->m_fUprootLimit <= 0.0f)
{
victimObject->SetIsStatic(false);
victimObject->AddToMovingList();
}
- if ( !victimObject->GetIsStatic())
+ notStatic = !victimObject->GetIsStatic();
+ if (!notStatic)
{
- CVector moveForce = point->normal*-4.0f;
+ CVector moveForce = point->normal * -4.0f;
victimObject->ApplyMoveForce(moveForce.x, moveForce.y, moveForce.z);
}
+ } else if (victimObject->m_nCollisionDamageEffect >= DAMAGE_EFFECT_SMASH_COMPLETELY) {
+ victimObject->ObjectDamage(50.f);
}
break;
@@ -1120,17 +1619,20 @@ CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim,
}
case ENTITY_TYPE_VEHICLE:
{
+ CStats::BulletsThatHit++;
DMAudio.PlayOneShot(((CPhysical*)victim)->m_audioEntityId, SOUND_WEAPON_HIT_VEHICLE, 1.0f);
break;
}
case ENTITY_TYPE_PED:
{
+ CStats::BulletsThatHit++;
DMAudio.PlayOneShot(((CPhysical*)victim)->m_audioEntityId, SOUND_WEAPON_HIT_PED, 1.0f);
((CPed*)victim)->Say(SOUND_PED_BULLET_HIT);
break;
}
case ENTITY_TYPE_OBJECT:
{
+ CStats::BulletsThatHit++;
PlayOneShotScriptObject(SCRIPT_SOUND_BULLET_HIT_GROUND_2, point->point);
break;
}
@@ -1143,7 +1645,7 @@ CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim,
}
}
else
- CBulletTraces::AddTrace(source, target);
+ CBulletTraces::AddTrace(source, target, m_eWeaponType, shooter);
if ( shooter == FindPlayerPed() )
CPad::GetPad(0)->StartShake_Distance(240, 128, FindPlayerPed()->GetPosition().x, FindPlayerPed()->GetPosition().y, FindPlayerPed()->GetPosition().z);
@@ -1151,6 +1653,7 @@ CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim,
BlowUpExplosiveThings(victim);
}
+
bool
CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
{
@@ -1196,10 +1699,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));
shootRot.Normalise();
@@ -1209,15 +1737,30 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
if ( shooter == FindPlayerPed() && TheCamera.Cams[0].Using3rdPersonMouseCam() )
{
- TheCamera.Find3rdPersonCamTargetVector(1.0f, *fireSource, source, target);
- CVector Left = CrossProduct(TheCamera.Cams[TheCamera.ActiveCam].Front, TheCamera.Cams[TheCamera.ActiveCam].Up);
+ CVector Left;
+#ifdef FREE_CAM
+ if (CCamera::bFreeCam) {
+ CPlayerPed* shooterPed = (CPlayerPed*)shooter;
+ Find3rdPersonCamTargetVectorFromCachedVectors(1.0f, *fireSource, source, target, shooterPed->m_cachedCamSource, shooterPed->m_cachedCamFront, shooterPed->m_cachedCamUp);
+ Left = CrossProduct(shooterPed->m_cachedCamFront, shooterPed->m_cachedCamUp);
+ }
+ else
+#endif
+ {
+ TheCamera.Find3rdPersonCamTargetVector(1.0f, *fireSource, source, target);
+ 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;
-
- ProcessLineOfSight(source, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, true, false);
+ CWorld::bIncludeCarTyres = true;
+ CWorld::bIncludeBikers = true;
+ CWorld::bIncludeDeadPeds = true;
+ ProcessLineOfSight(source, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, false, false);
+ CWorld::bIncludeDeadPeds = false;
+ CWorld::bIncludeCarTyres = false;
}
else
{
@@ -1233,24 +1776,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(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);
+ CWorld::bIncludeBikers = true;
+ ProcessLineOfSight(*fireSource, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, false, false);
+ CWorld::bIncludeDeadPeds = false;
}
+ CWorld::bIncludeBikers = false;
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);
- CBulletTraces::AddTrace(fireSource, &point.point);
+ 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(1500);
+ else
+ shooterPed->SetAttackTimer(3000);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ CBulletTraces::AddTrace(fireSource, &point.point, m_eWeaponType, shooter);
if ( victim->IsPed() )
{
CPed *victimPed = (CPed *)victim;
- if ( !victimPed->OnGround() && victim != shooter && victimPed->DoesLOSBulletHitPed(point) )
+ if ( !victimPed->DyingOrDead() && victim != shooter )
{
bool cantStandup = true;
@@ -1263,7 +1866,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 )
@@ -1288,7 +1892,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;
@@ -1300,6 +1904,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_STD_HIT_FLOOR_FRONT, 8.0f);
+ }
+ else
+ {
+ hitAssoc = CAnimManager::BlendAnimation(victimPed->GetClump(), ASSOCGRP_STD, ANIM_STD_HIT_FLOOR, 8.0f);
+ }
+ if (hitAssoc)
+ {
+ hitAssoc->SetCurrentTime(0.0f);
+ hitAssoc->SetRun();
+ hitAssoc->flags &= ~ASSOC_DELETEFADEDOUT;
+ }
+ }
+ }
}
}
else
@@ -1308,21 +1942,29 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
{
case ENTITY_TYPE_VEHICLE:
{
- ((CVehicle *)victim)->InflictDamage(shooter, m_eWeaponType, info->m_nDamage);
+ if (point.pieceB >= CAR_PIECE_WHEEL_LF && point.pieceB <= CAR_PIECE_WHEEL_RR) {
+ ((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;
}
@@ -1352,13 +1994,15 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
if ( !victimObject->bInfiniteMass )
{
- if ( victimObject->GetIsStatic() && victimObject->m_fUprootLimit <= 0.0f )
+ bool notStatic = !victimObject->GetIsStatic();
+ if ( notStatic && victimObject->m_fUprootLimit <= 0.0f )
{
victimObject->SetIsStatic(false);
victimObject->AddToMovingList();
}
- if ( !victimObject->GetIsStatic())
+ notStatic = !victimObject->GetIsStatic();
+ if ( !notStatic )
{
CVector moveForce = point.normal*-5.0f;
victimObject->ApplyMoveForce(moveForce.x, moveForce.y, moveForce.z);
@@ -1381,17 +2025,29 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
}
case ENTITY_TYPE_VEHICLE:
{
+ if (!statUpdated) {
+ CStats::BulletsThatHit++;
+ statUpdated = true;
+ }
DMAudio.PlayOneShot(((CPhysical*)victim)->m_audioEntityId, SOUND_WEAPON_HIT_VEHICLE, 1.0f);
break;
}
case ENTITY_TYPE_PED:
{
+ if (!statUpdated) {
+ CStats::BulletsThatHit++;
+ 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::BulletsThatHit++;
+ statUpdated = true;
+ }
PlayOneShotScriptObject(SCRIPT_SOUND_BULLET_HIT_GROUND_2, point.point);
break;
}
@@ -1407,7 +2063,7 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
{
CVector traceTarget = *fireSource;
traceTarget += (target - (*fireSource)) * Min(info->m_fRange, 30.0f) / info->m_fRange;
- CBulletTraces::AddTrace(fireSource, &traceTarget);
+ CBulletTraces::AddTrace(fireSource, &traceTarget, m_eWeaponType, shooter);
}
}
@@ -1424,10 +2080,12 @@ CWeapon::FireProjectile(CEntity *shooter, CVector *fireSource, float power)
ASSERT(fireSource!=nil);
CVector source, target;
+ eWeaponType projectileType = m_eWeaponType;
if ( m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER )
{
source = *fireSource;
+ projectileType = WEAPONTYPE_ROCKET;
if ( shooter->IsPed() && ((CPed*)shooter)->IsPlayer() )
{
@@ -1469,7 +2127,7 @@ CWeapon::FireProjectile(CEntity *shooter, CVector *fireSource, float power)
if ( !CWorld::GetIsLineOfSightClear(source, target, true, true, false, true, false, false, false) )
{
if ( m_eWeaponType != WEAPONTYPE_GRENADE )
- CProjectileInfo::RemoveNotAdd(shooter, m_eWeaponType, *fireSource);
+ CProjectileInfo::RemoveNotAdd(shooter, projectileType, *fireSource);
else
{
if ( shooter->IsPed() )
@@ -1478,14 +2136,22 @@ CWeapon::FireProjectile(CEntity *shooter, CVector *fireSource, float power)
source.z -= 0.4f;
if ( !CWorld::TestSphereAgainstWorld(source, 0.5f, nil, false, false, true, false, false, false) )
- CProjectileInfo::AddProjectile(shooter, m_eWeaponType, source, 0.0f);
+ CProjectileInfo::AddProjectile(shooter, WEAPONTYPE_GRENADE, source, 0.0f);
else
- CProjectileInfo::RemoveNotAdd(shooter, m_eWeaponType, *fireSource);
+ CProjectileInfo::RemoveNotAdd(shooter, WEAPONTYPE_GRENADE, *fireSource);
}
}
}
else
- CProjectileInfo::AddProjectile(shooter, m_eWeaponType, *fireSource, power);
+ CProjectileInfo::AddProjectile(shooter, projectileType, *fireSource, power);
+
+
+ CWorld::pIgnoreEntity = nil;
+
+ if ( shooter->IsPed() )
+ CEventList::RegisterEvent(EVENT_GUNSHOT, EVENT_ENTITY_PED, shooter, (CPed *)shooter, 1000);
+ else if ( shooter->IsVehicle() && ((CVehicle*)shooter)->pDriver )
+ CEventList::RegisterEvent(EVENT_GUNSHOT, EVENT_ENTITY_VEHICLE, shooter, ((CVehicle*)shooter)->pDriver, 1000);
return true;
}
@@ -1525,7 +2191,16 @@ CWeapon::FireAreaEffect(CEntity *shooter, CVector *fireSource)
if ( shooter == FindPlayerPed() && TheCamera.Cams[0].Using3rdPersonMouseCam() )
{
- TheCamera.Find3rdPersonCamTargetVector(info->m_fRange, *fireSource, source, target);
+#ifdef FREE_CAM
+ if (CCamera::bFreeCam) {
+ CPlayerPed* shooterPed = (CPlayerPed*)shooter;
+ Find3rdPersonCamTargetVectorFromCachedVectors(info->m_fRange, *fireSource, source, target, shooterPed->m_cachedCamSource, shooterPed->m_cachedCamFront, shooterPed->m_cachedCamUp);
+ }
+ else
+#endif
+ {
+ TheCamera.Find3rdPersonCamTargetVector(info->m_fRange, *fireSource, source, target);
+ }
float norm = (1.0f / info->m_fRange);
dir = (target - source) * norm;
}
@@ -1538,25 +2213,84 @@ CWeapon::FireAreaEffect(CEntity *shooter, CVector *fireSource)
CShotInfo::AddShot(shooter, m_eWeaponType, *fireSource, target);
CWeapon::GenerateFlameThrowerParticles(*fireSource, dir);
+
+ if ( shooter == (CEntity *)FindPlayerPed() )
+ {
+ for ( int32 i = 0; i < FindPlayerPed()->m_numNearPeds; i++ )
+ {
+ if ( FindPlayerPed()->m_nearPeds[i]->CharCreatedBy == RANDOM_CHAR )
+ {
+ if ( FindPlayerPed()->m_nearPeds[i]->IsPedInControl() && FindPlayerPed()->m_nearPeds[i]->m_nPedState != PED_FLEE_ENTITY )
+ FindPlayerPed()->m_nearPeds[i]->SetFlee(shooter, 10000);
+ }
+ }
+ }
return true;
}
bool
+CWeapon::LaserScopeDot(CVector *pOutPos, float *pOutSize)
+{
+ CWeaponInfo *info = GetInfo();
+
+ float range = info->m_fRange;
+
+ CVector source, target;
+ CEntity *foundEnt = nil;
+ CColPoint foundCol;
+
+ source = 0.5f * TheCamera.Cams[TheCamera.ActiveCam].Front + TheCamera.Cams[TheCamera.ActiveCam].Source;
+ target = TheCamera.Cams[TheCamera.ActiveCam].Front;
+ target.Normalise();
+ target *= range;
+ target += source;
+
+ if ( CWorld::ProcessLineOfSight(source, target, foundCol, foundEnt, true, true, true, true, false, false, false) )
+ {
+ CVector pos = foundCol.point;
+ float w, h;
+
+ if ( CSprite::CalcScreenCoors(foundCol.point, &pos, &w, &h, true) )
+ {
+ *pOutPos = pos;
+ *pOutSize = w * 0.05f;
+
+ CCoronas::RegisterCorona((uintptr)this + 7, 128, 0, 0, 255, pos, 1.2f, 50.0f, CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, 0.0f);
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool
CWeapon::FireSniper(CEntity *shooter)
{
ASSERT(shooter!=nil);
-
- int16 mode = TheCamera.Cams[TheCamera.ActiveCam].Mode;
- if (!( mode == CCam::MODE_M16_1STPERSON
- || mode == CCam::MODE_SNIPER
- || mode == CCam::MODE_ROCKETLAUNCHER
- || mode == CCam::MODE_M16_1STPERSON_RUNABOUT
- || mode == CCam::MODE_SNIPER_RUNABOUT
- || mode == CCam::MODE_ROCKETLAUNCHER_RUNABOUT) )
+
+ if ( (CEntity *)FindPlayerPed() == shooter )
{
- return false;
+ int16 mode = TheCamera.Cams[TheCamera.ActiveCam].Mode;
+ if (!( mode == CCam::MODE_M16_1STPERSON
+ || mode == CCam::MODE_SNIPER
+ || mode == CCam::MODE_CAMERA
+ || mode == CCam::MODE_ROCKETLAUNCHER
+ || mode == CCam::MODE_M16_1STPERSON_RUNABOUT
+ || mode == CCam::MODE_SNIPER_RUNABOUT
+ || mode == CCam::MODE_ROCKETLAUNCHER_RUNABOUT) )
+ {
+ return false;
+ }
+ }
+
+#ifdef SECUROM
+ if (sniperPirateCheck){
+ // if not pirated game
+ // sniperPirateCheck = 0;
}
+#endif
#ifndef FIX_BUGS
CWeaponInfo *info = GetInfo(); //unused
@@ -1569,15 +2303,16 @@ CWeapon::FireSniper(CEntity *shooter)
CVector dir = cam->Front;
if ( DotProduct(dir, CVector(0.0f, -0.9894f, 0.145f)) > 0.997f )
- CCoronas::bSmallMoon = !CCoronas::bSmallMoon;
+ CCoronas::MoonSize = (CCoronas::MoonSize+1) & 7;
dir.Normalise();
dir *= 16.0f;
- CBulletInfo::AddBullet(shooter, m_eWeaponType, source, dir);
+#ifdef SECUROM
+ if (sniperPirateCheck) return true;
+#endif
- if ( shooter == FindPlayerPed() )
- CStats::InstantHitsFiredByPlayer++;
+ CBulletInfo::AddBullet(shooter, m_eWeaponType, source, dir);
if ( shooter == FindPlayerPed() )
{
@@ -1585,14 +2320,75 @@ CWeapon::FireSniper(CEntity *shooter)
FindPlayerPed()->GetPosition().x,
FindPlayerPed()->GetPosition().y,
FindPlayerPed()->GetPosition().z);
+
+ CParticle::HandleShootableBirdsStuff(shooter, source);
CamShakeNoPos(&TheCamera, 0.2f);
}
+ if ( shooter->IsPed() )
+ CEventList::RegisterEvent(EVENT_GUNSHOT, EVENT_ENTITY_PED, shooter, (CPed*)shooter, 1000);
+ else if ( shooter->IsVehicle() && ((CVehicle*)shooter)->pDriver )
+ CEventList::RegisterEvent(EVENT_GUNSHOT, EVENT_ENTITY_VEHICLE, shooter, ((CVehicle*)shooter)->pDriver, 1000);
+
return true;
}
bool
+CWeapon::TakePhotograph(CEntity *shooter)
+{
+ if ( TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_CAMERA )
+ {
+ CSpecialFX::bSnapShotActive = true;
+ CSpecialFX::SnapShotFrames = 0;
+ CStats::PhotosTaken++;
+ bPhotographHasBeenTaken = true;
+
+ for ( int32 i = CPools::GetPedPool()->GetSize() - 1; i >= 0; i--)
+ {
+ CPed *ped = CPools::GetPedPool()->GetSlot(i);
+ if ( ped )
+ {
+ if ( (ped->GetPosition() - TheCamera.GetPosition()).Magnitude() < 125.0f )
+ {
+ CVector pedPos = ped->GetPosition();
+ pedPos.z += 0.8f;
+
+ CVector pos;
+ float w, h;
+
+ if ( CSprite::CalcScreenCoors(pedPos, &pos, &w, &h, false) )
+ {
+ if ( SCREEN_WIDTH * 0.1f < pos.x && SCREEN_WIDTH * 0.9f > pos.x
+ && SCREEN_HEIGHT * 0.1f < pos.y && SCREEN_HEIGHT * 0.9f > pos.y )
+ {
+ CVector source, target;
+ CEntity *foundEnt = nil;
+ CColPoint foundCol;
+
+ target = pedPos;
+ source = TheCamera.GetForward() * 2.0f + TheCamera.GetPosition();
+
+ if ( CWorld::ProcessLineOfSight(source, target, foundCol, foundEnt, true, true, true, true, true, true, false) )
+ {
+ if ( foundEnt != (CEntity*)ped )
+ continue;
+ }
+
+ ped->bHasBeenPhotographed = true;
+ }
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+bool
CWeapon::FireM16_1stPerson(CEntity *shooter)
{
ASSERT(shooter!=nil);
@@ -1601,6 +2397,7 @@ CWeapon::FireM16_1stPerson(CEntity *shooter)
if (!( mode == CCam::MODE_M16_1STPERSON
|| mode == CCam::MODE_SNIPER
+ || mode == CCam::MODE_CAMERA
|| mode == CCam::MODE_ROCKETLAUNCHER
|| mode == CCam::MODE_M16_1STPERSON_RUNABOUT
|| mode == CCam::MODE_SNIPER_RUNABOUT
@@ -1612,10 +2409,12 @@ CWeapon::FireM16_1stPerson(CEntity *shooter)
CWeaponInfo *info = GetInfo();
+ CWorld::bIncludeCarTyres = true;
+ CWorld::bIncludeBikers = true;
+
CColPoint point;
CEntity *victim;
- CWorld::bIncludeCarTyres = true;
CWorld::pIgnoreEntity = shooter;
CWorld::bIncludeDeadPeds = true;
@@ -1625,9 +2424,12 @@ CWeapon::FireM16_1stPerson(CEntity *shooter)
CVector source = cam->Source;
CVector target = cam->Front*info->m_fRange + source;
- ProcessLineOfSight(source, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, true, false);
- CWorld::bIncludeDeadPeds = false;
+ if (ProcessLineOfSight(source, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, true, false)) {
+ CheckForShootingVehicleOccupant(&victim, &point, m_eWeaponType, source, target);
+ }
CWorld::pIgnoreEntity = nil;
+ CWorld::bIncludeDeadPeds = false;
+ CWorld::bIncludeBikers = false;
CWorld::bIncludeCarTyres = false;
CVector2D front(cam->Front.x, cam->Front.y);
@@ -1636,7 +2438,8 @@ CWeapon::FireM16_1stPerson(CEntity *shooter)
DoBulletImpact(shooter, victim, &source, &target, &point, front);
CVector bulletPos;
- if ( CHeli::TestBulletCollision(&source, &target, &bulletPos, 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));
@@ -1644,77 +2447,137 @@ CWeapon::FireM16_1stPerson(CEntity *shooter)
if ( shooter == FindPlayerPed() )
{
-#ifdef FIX_BUGS
- CStats::InstantHitsFiredByPlayer++;
-#endif
- CPad::GetPad(0)->StartShake_Distance(240, 128, FindPlayerPed()->GetPosition().x, FindPlayerPed()->GetPosition().y, FindPlayerPed()->GetPosition().z);
-
- if ( m_eWeaponType == WEAPONTYPE_M16 )
- {
- TheCamera.Cams[TheCamera.ActiveCam].Beta += float((CGeneral::GetRandomNumber() & 127) - 64) * 0.0003f;
- TheCamera.Cams[TheCamera.ActiveCam].Alpha += float((CGeneral::GetRandomNumber() & 127) - 64) * 0.0003f;
- }
- else if ( m_eWeaponType == WEAPONTYPE_HELICANNON )
- {
- TheCamera.Cams[TheCamera.ActiveCam].Beta += float((CGeneral::GetRandomNumber() & 127) - 64) * 0.0001f;
- TheCamera.Cams[TheCamera.ActiveCam].Alpha += float((CGeneral::GetRandomNumber() & 127) - 64) * 0.0001f;
+ float mult;
+ switch (m_eWeaponType) {
+ case WEAPONTYPE_M4:
+ mult = 0.0003f;
+ break;
+ case WEAPONTYPE_RUGER:
+ mult = 0.00015f;
+ break;
+ case WEAPONTYPE_HELICANNON:
+ case WEAPONTYPE_M60:
+ mult = 0.0003f;
+ break;
+ default:
+ mult = 0.0002f;
+ break;
}
+
+ if (FindPlayerPed()->bIsDucking || FindPlayerPed()->m_attachedTo)
+ mult *= 0.3f;
+
+ TheCamera.Cams[TheCamera.ActiveCam].Beta += float((CGeneral::GetRandomNumber() & 127) - 64) * mult;
+ TheCamera.Cams[TheCamera.ActiveCam].Alpha += float((CGeneral::GetRandomNumber() & 127) - 64) * mult;
+
+ // yes, double
+ double notFiringRate = (20.0 - info->m_nFiringRate) / 80.0;
+ double raisedNotFiringRate = Max(1.0, Max(0.0, notFiringRate));
+
+ uint8 shakeFreq = 80.0 * raisedNotFiringRate + 130.0;
+ CPad::GetPad(0)->StartShake(20000.0f * CTimer::GetTimeStep() / shakeFreq, shakeFreq);
}
return true;
}
bool
-CWeapon::FireInstantHitFromCar(CAutomobile *shooter, bool left)
+CWeapon::FireInstantHitFromCar(CVehicle *shooter, bool left, bool right)
{
CWeaponInfo *info = GetInfo();
CVehicleModelInfo *modelInfo = shooter->GetModelInfo();
-
+
CVector source, target;
- if ( left )
+
+ if ( shooter->IsBike() )
{
- source = shooter->GetMatrix() * CVector(-shooter->GetColModel()->boundingBox.max.x + -0.2f,
- float(CGeneral::GetRandomNumber() & 255) * 0.001f + modelInfo->GetFrontSeatPosn().y,
- modelInfo->GetFrontSeatPosn().z + 0.5f);
- source += CTimer::GetTimeStep() * shooter->m_vecMoveSpeed;
-
-
- target = shooter->GetMatrix() * CVector(-info->m_fRange,
- modelInfo->GetFrontSeatPosn().y,
+ if ( shooter->pDriver )
+ {
+ source = info->m_vecFireOffset;
+
+ shooter->pDriver->TransformToNode(source, PED_HANDR);
+ source += CTimer::GetTimeStep() * shooter->m_vecMoveSpeed;
+
+ if ( left )
+ target = source - info->m_fRange * shooter->GetRight();
+ else if ( right )
+ target = source + info->m_fRange * shooter->GetRight();
+ else
+ target = source + info->m_fRange * shooter->GetForward();
+
+ }
+ else if ( left )
+ {
+ source = shooter->GetMatrix() * CVector(-shooter->GetColModel()->boundingBox.max.x + -0.25f,
+ float(CGeneral::GetRandomNumber() & 255) * 0.001f + modelInfo->GetFrontSeatPosn().y - 0.05f,
+ modelInfo->GetFrontSeatPosn().z + 0.63f);
+ source += CTimer::GetTimeStep() * shooter->m_vecMoveSpeed;
+
+
+ target = shooter->GetMatrix() * CVector(-info->m_fRange,
+ modelInfo->GetFrontSeatPosn().y,
+ modelInfo->GetFrontSeatPosn().z + 0.6f);
+ }
+ else if ( right )
+ {
+ source = shooter->GetMatrix() * CVector(shooter->GetColModel()->boundingBox.max.x + 0.25f,
+ float(CGeneral::GetRandomNumber() & 255) * 0.001f + modelInfo->GetFrontSeatPosn().y - 0.18f,
+ modelInfo->GetFrontSeatPosn().z + 0.52f);
+ source += CTimer::GetTimeStep() * shooter->m_vecMoveSpeed;
+
+ target = shooter->GetMatrix() * CVector(info->m_fRange,
+ modelInfo->GetFrontSeatPosn().y,
+ modelInfo->GetFrontSeatPosn().z + 0.5f);
+ }
+ else
+ {
+ source = shooter->GetMatrix() * CVector(float(CGeneral::GetRandomNumber() & 255) * 0.001f + -0.4f,
+ modelInfo->GetFrontSeatPosn().y + shooter->GetColModel()->boundingBox.max.y + 0.2f,
+ modelInfo->GetFrontSeatPosn().z + 0.55f);
+ source += CTimer::GetTimeStep() * shooter->m_vecMoveSpeed;
+
+ target = shooter->GetMatrix() * CVector(0.0f,
+ info->m_fRange,
modelInfo->GetFrontSeatPosn().z + 0.5f);
+ }
}
else
{
- source = shooter->GetMatrix() * CVector(shooter->GetColModel()->boundingBox.max.x + 0.2f,
- float(CGeneral::GetRandomNumber() & 255) * 0.001f + modelInfo->GetFrontSeatPosn().y,
- modelInfo->GetFrontSeatPosn().z + 0.5f);
+ if ( left )
+ source = info->m_vecFireOffset;
+ else
+ {
+ source = 1.8f * info->m_vecFireOffset;
+ source.z -= 0.1f;
+ }
+
+ shooter->pDriver->TransformToNode(source, PED_HANDR);
source += CTimer::GetTimeStep() * shooter->m_vecMoveSpeed;
-
- target = shooter->GetMatrix() * CVector(info->m_fRange,
- modelInfo->GetFrontSeatPosn().y,
- modelInfo->GetFrontSeatPosn().z + 0.5f);
- }
- #undef FRONTSEATPOS
-
- if ( TheCamera.GetLookingLRBFirstPerson() && !left )
- {
- source -= 0.3f * shooter->GetForward();
- target -= 0.3f * shooter->GetForward();
+
+ if ( left )
+ target = source - info->m_fRange * shooter->GetRight();
+ else
+ target = source + info->m_fRange * shooter->GetRight();
}
target += CVector(float(CGeneral::GetRandomNumber()&255)*0.01f-1.28f,
float(CGeneral::GetRandomNumber()&255)*0.01f-1.28f,
float(CGeneral::GetRandomNumber()&255)*0.01f-1.28f);
- DoDriveByAutoAiming(FindPlayerPed(), &source, &target);
+ DoDriveByAutoAiming(FindPlayerPed(), shooter, &source, &target);
CEventList::RegisterEvent(EVENT_GUNSHOT, EVENT_ENTITY_PED, FindPlayerPed(), FindPlayerPed(), 1000);
if ( !TheCamera.GetLookingLRBFirstPerson() )
- CParticle::AddParticle(PARTICLE_GUNFLASH, source, CVector(0.0f, 0.0f, 0.0f));
+ {
+ if ( !shooter->IsBike() )
+ CParticle::AddParticle(PARTICLE_GUNFLASH, source, CVector(0.0f, 0.0f, 0.0f));
+ else
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, source, 1.4f*shooter->m_vecMoveSpeed);
+ }
else
- CamShakeNoPos(&TheCamera, 0.01f);
+ CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, source, 1.6f*shooter->m_vecMoveSpeed, nil, 0.18f);
CEventList::RegisterEvent(EVENT_GUNSHOT, EVENT_ENTITY_VEHICLE, shooter, FindPlayerPed(), 1000);
@@ -1723,7 +2586,12 @@ CWeapon::FireInstantHitFromCar(CAutomobile *shooter, bool left)
CColPoint point;
CEntity *victim;
+
+ CWorld::bIncludeBikers = true;
+ CWorld::pIgnoreEntity = shooter;
ProcessLineOfSight(source, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, true, false);
+ CWorld::pIgnoreEntity = NULL;
+ CWorld::bIncludeBikers = false;
if ( !(CTimer::GetFrameCounter() & 3) )
MakePedsJumpAtShot(shooter, &source, &target);
@@ -1731,7 +2599,7 @@ CWeapon::FireInstantHitFromCar(CAutomobile *shooter, bool left)
if ( victim )
{
CVector traceTarget = point.point;
- CBulletTraces::AddTrace(&source, &traceTarget);
+ CBulletTraces::AddTrace(&source, &traceTarget, m_eWeaponType, shooter);
if ( victim->IsPed() )
{
@@ -1818,7 +2686,7 @@ CWeapon::FireInstantHitFromCar(CAutomobile *shooter, bool left)
{
float norm = 30.0f/info->m_fRange;
CVector traceTarget = (target-source)*norm + source;
- CBulletTraces::AddTrace(&source, &traceTarget);
+ CBulletTraces::AddTrace(&source, &traceTarget, m_eWeaponType, shooter);
}
if ( shooter == FindPlayerVehicle() )
@@ -1839,8 +2707,6 @@ CWeapon::DoDoomAiming(CEntity *shooter, CVector *source, CVector *target)
#endif
CPed *shooterPed = (CPed*)shooter;
- if ( shooterPed->IsPed() && shooterPed->bCrouchWhenShooting )
- return;
int16 lastEntity;
CEntity *entities[16];
@@ -1859,7 +2725,8 @@ CWeapon::DoDoomAiming(CEntity *shooter, CVector *source, CVector *target)
if ( !(victim->GetStatus() == STATUS_TRAIN_MOVING
|| victim->GetStatus() == STATUS_TRAIN_NOT_MOVING
|| victim->GetStatus() == STATUS_HELI
- || victim->GetStatus() == STATUS_PLANE) )
+ || victim->GetStatus() == STATUS_PLANE
+ || victim->GetStatus() == STATUS_WRECKED) )
{
float distToVictim = (shooterPed->GetPosition()-victim->GetPosition()).Magnitude2D();
float distToVictimZ = Abs(shooterPed->GetPosition().z-victim->GetPosition().z);
@@ -1878,7 +2745,10 @@ CWeapon::DoDoomAiming(CEntity *shooter, CVector *source, CVector *target)
}
}
- if ( closestEntityDist < DOOMAUTOAIMING_MAXDIST )
+ CColPoint foundCol;
+ CEntity *foundEnt;
+ if (closestEntityDist < DOOMAUTOAIMING_MAXDIST
+ && !CWorld::ProcessLineOfSight(*source, entities[closestEntity]->GetPosition(), foundCol, foundEnt, true, false, false, false, false, false, false, true))
{
CEntity *victim = entities[closestEntity];
ASSERT(victim !=nil);
@@ -1967,10 +2837,11 @@ CWeapon::DoTankDoomAiming(CEntity *shooter, CEntity *driver, CVector *source, CV
}
}
+
void
-CWeapon::DoDriveByAutoAiming(CEntity *shooter, CVector *source, CVector *target)
+CWeapon::DoDriveByAutoAiming(CEntity *driver, CVehicle *vehicle, CVector *source, CVector *target)
{
- ASSERT(shooter!=nil);
+ ASSERT(driver!=nil);
ASSERT(source!=nil);
ASSERT(target!=nil);
@@ -1978,27 +2849,36 @@ CWeapon::DoDriveByAutoAiming(CEntity *shooter, CVector *source, CVector *target)
CEntity entity; // unused
#endif
- CPed *shooterPed = (CPed*)shooter;
- if ( shooterPed->IsPed() && shooterPed->bCrouchWhenShooting )
- return;
+ CPed *shooterPed = (CPed*)driver;
int16 lastEntity;
- CEntity *entities[16];
- CWorld::FindObjectsInRange(*source, (*target-*source).Magnitude(), true, &lastEntity, 15, entities, false, false, true, false, false);
+ CEntity *peds[16];
+ CWorld::FindObjectsInRange(*source, (*target-*source).Magnitude(), true, &lastEntity, 15, peds, false, false, true, false, false);
float closestEntityDist = 10000.0f;
int16 closestEntity;
for ( int32 i = 0; i < lastEntity; i++ )
{
- CEntity *victim = entities[i];
+ CPed *victim = (CPed*)peds[i];
ASSERT(victim!=nil);
- if ( shooter != victim )
+ if (driver != victim && !victim->DyingOrDead() && victim->m_attachedTo != vehicle)
{
float lineDist = CCollision::DistToLine(source, target, &victim->GetPosition());
- float distToVictim = (victim->GetPosition() - shooter->GetPosition()).Magnitude();
- float pedDist = 0.15f*distToVictim + lineDist;
+
+ uint32 model = vehicle->GetModelIndex();
+ float pedDist;
+ if (model == MI_HUNTER || model == MI_SEASPAR || model == MI_SPARROW)
+ {
+ float distToVictim = (victim->GetPosition() - vehicle->GetPosition()).Magnitude();
+ pedDist = lineDist / Max(5.f, distToVictim);
+ }
+ else
+ {
+ float distToVictim = (victim->GetPosition() - driver->GetPosition()).Magnitude();
+ pedDist = 0.15f * distToVictim + lineDist;
+ }
if ( DotProduct((*target-*source), victim->GetPosition()-*source) > 0.0f && pedDist < closestEntityDist)
{
@@ -2007,14 +2887,24 @@ CWeapon::DoDriveByAutoAiming(CEntity *shooter, CVector *source, CVector *target)
}
}
}
+ uint32 model = vehicle->GetModelIndex();
+ float maxAimDistance = CAR_DRIVEBYAUTOAIMING_MAXDIST;
+ if (model == MI_HUNTER)
+ {
+ maxAimDistance = Tan(DEGTORAD(fHunterAimingAngle));
+ }
+ else if (model == MI_SEASPAR || model == MI_SPARROW)
+ {
+ maxAimDistance = Tan(DEGTORAD(fSeaSparrowAimingAngle));
+ }
- if ( closestEntityDist < DRIVEBYAUTOAIMING_MAXDIST )
+ if ( closestEntityDist < maxAimDistance )
{
- CEntity *victim = entities[closestEntity];
+ CEntity *victim = peds[closestEntity];
ASSERT(victim!=nil);
float distToTarget = (*source - *target).Magnitude();
- float distToSource = (*source - victim->GetPosition()).Magnitude();
+ float distToSource = (*source - victim->GetPosition()).Magnitude();
*target = (distToTarget / distToSource) * (victim->GetPosition() - *source) + *source;
}
}
@@ -2034,8 +2924,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:
@@ -2046,18 +2938,19 @@ 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 - CWeaponInfo::ms_aReloadSampleTime[m_eWeaponType];
if ( CTimer::GetPreviousTimeInMilliseconds() < timePassed && CTimer::GetTimeInMilliseconds() >= timePassed )
DMAudio.PlayOneShot(audioEntity, SOUND_WEAPON_RELOAD, 0.0f);
}
if ( CTimer::GetTimeInMilliseconds() > m_nTimer )
{
- if ( GetInfo()->m_eWeaponFire != WEAPON_FIRE_MELEE && m_nAmmoTotal == 0 )
+ if ( GetInfo()->m_eWeaponFire != WEAPON_FIRE_MELEE && m_nAmmoTotal == 0 ) {
m_eWeaponState = WEAPONSTATE_OUT_OF_AMMO;
- else
+ CPickups::RemoveAllPickupsOfACertainWeaponGroupWithNoAmmo(m_eWeaponType);
+ } else
m_eWeaponState = WEAPONSTATE_READY;
}
@@ -2066,11 +2959,49 @@ 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 = fReloadAnimSampleFraction[0];
+ break;
+ case ASSOCGRP_COLT:
+ case ASSOCGRP_TEC:
+ soundStart = fReloadAnimSampleFraction[1];
+ break;
+ case ASSOCGRP_UZI:
+ soundStart = fReloadAnimSampleFraction[2];
+ break;
+ case ASSOCGRP_RIFLE:
+ soundStart = fReloadAnimSampleFraction[3];
+ break;
+ case ASSOCGRP_M60:
+ soundStart = fReloadAnimSampleFraction[4];
+ break;
+ default:
+ break;
+ }
+ if (reloadAssoc->GetProgress() >= soundStart && (reloadAssoc->currentTime - reloadAssoc->timeStep) / reloadAssoc->hierarchy->totalLength < soundStart)
+ DMAudio.PlayOneShot(audioEntity, SOUND_WEAPON_RELOAD, m_eWeaponType);
+ if (CTimer::GetTimeInMilliseconds() > m_nTimer && reloadAssoc->GetProgress() < 0.9f) {
+ m_nTimer = CTimer::GetTimeInMilliseconds();
+ }
+ } else {
+ uint32 timePassed = m_nTimer - CWeaponInfo::ms_aReloadSampleTime[m_eWeaponType];
+ if (CTimer::GetPreviousTimeInMilliseconds() < timePassed && CTimer::GetTimeInMilliseconds() >= timePassed)
+ DMAudio.PlayOneShot(audioEntity, SOUND_WEAPON_RELOAD, m_eWeaponType);
+ }
}
if ( CTimer::GetTimeInMilliseconds() > m_nTimer )
@@ -2157,17 +3088,20 @@ FireOneInstantHitRound(CVector *source, CVector *target, int32 damage)
}
case ENTITY_TYPE_VEHICLE:
{
+ CStats::BulletsThatHit++;
DMAudio.PlayOneShot(((CPhysical*)victim)->m_audioEntityId, SOUND_WEAPON_HIT_VEHICLE, 1.0f);
break;
}
case ENTITY_TYPE_PED:
{
+ CStats::BulletsThatHit++;
DMAudio.PlayOneShot(((CPhysical*)victim)->m_audioEntityId, SOUND_WEAPON_HIT_PED, 1.0f);
((CPed*)victim)->Say(SOUND_PED_BULLET_HIT);
break;
}
case ENTITY_TYPE_OBJECT:
{
+ CStats::BulletsThatHit++;
PlayOneShotScriptObject(SCRIPT_SOUND_BULLET_HIT_GROUND_2, point.point);
break;
}
@@ -2193,13 +3127,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
@@ -2284,14 +3220,14 @@ CWeapon::BlowUpExplosiveThings(CEntity *thing)
{
CObject *object = (CObject*)thing;
int32 mi = object->GetModelIndex();
- if ( IsExplosiveThingModel(mi) && !object->bHasBeenDamaged )
+ if ( IsExplosiveThingModel(mi) && !object->bHasBeenDamaged && object->IsObject() )
{
object->bHasBeenDamaged = true;
CExplosion::AddExplosion(object, FindPlayerPed(), EXPLOSION_BARREL, object->GetPosition()+CVector(0.0f,0.0f,0.5f), 100);
if ( MI_EXPLODINGBARREL == mi )
- object->m_vecMoveSpeed.z += 0.75f;
+ object->m_vecMoveSpeed.z += 0.55f;
else
object->m_vecMoveSpeed.z += 0.45f;
@@ -2310,19 +3246,25 @@ 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
CPed::IsPedDoingDriveByShooting(void)
{
+#ifdef FIX_BUGS
+ if (FindPlayerPed() == this && CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_nWeaponSlot == WEAPONSLOT_SUBMACHINEGUN) {
+#else
if (FindPlayerPed() == this && GetWeapon()->m_eWeaponType == WEAPONTYPE_UZI) {
+#endif
if (TheCamera.Cams[TheCamera.ActiveCam].LookingLeft || TheCamera.Cams[TheCamera.ActiveCam].LookingRight)
return true;
}
@@ -2332,7 +3274,82 @@ CPed::IsPedDoingDriveByShooting(void)
bool
CWeapon::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)
{
- return CWorld::ProcessLineOfSight(point1, point2, point, entity, checkBuildings, checkVehicles, checkPeds, checkObjects, checkDummies, ignoreSeeThrough, ignoreSomeObjects);
+ return CWorld::ProcessLineOfSight(point1, point2, point, entity, checkBuildings, checkVehicles, checkPeds, checkObjects, checkDummies, false, ignoreSomeObjects, true);
+}
+
+
+void
+CWeapon::CheckForShootingVehicleOccupant(CEntity **victim, CColPoint *point, eWeaponType weapon, CVector const& source, CVector const& target)
+{
+ if (!(*victim)->IsVehicle())
+ return;
+
+ CColSphere headSphere;
+
+ CVehicle *veh = (CVehicle*)*victim;
+ CColPoint origPoint(*point);
+ float radius = 1.0f;
+ bool found = false;
+ CColLine shootLine(source, target);
+
+ if (veh->pDriver && veh->pDriver->bCanBeShotInVehicle) {
+ CVector pos(0.f, 0.f, 0.f);
+ veh->pDriver->TransformToNode(pos, PED_HEAD);
+ headSphere.Set(0.2f, pos + CVector(0.f, 0.f, 0.1f), 0, PEDPIECE_HEAD);
+ if (CCollision::ProcessLineSphere(shootLine, headSphere, *point, radius)) {
+ *victim = veh->pDriver;
+ found = true;
+ }
+ }
+
+ for(int i = 0; i < ARRAY_SIZE(veh->pPassengers); i++) {
+ CPed *passenger = veh->pPassengers[i];
+ if (passenger && passenger->bCanBeShotInVehicle) {
+ CVector pos(0.f, 0.f, 0.f);
+ passenger->TransformToNode(pos, PED_HEAD);
+ headSphere.Set(0.2f, pos + CVector(0.f, 0.f, 0.1f), 0, PEDPIECE_HEAD);
+ if (CCollision::ProcessLineSphere(shootLine, headSphere, *point, radius)) {
+ *victim = passenger;
+ found = true;
+ }
+ }
+ }
+ if (veh->IsCar()) {
+ CVector distVec = target - source;
+ if (DotProduct(distVec, veh->GetForward()) < 0.0f && DotProduct(distVec, veh->GetUp()) <= 0.0f) {
+ CColModel *colModel = veh->GetColModel();
+ if (colModel->numTriangles > 0) {
+ bool passesGlass = false;
+ CMatrix invVehMat;
+ Invert(veh->GetMatrix(), invVehMat);
+ shootLine.p0 = invVehMat * shootLine.p0;
+ shootLine.p1 = invVehMat * shootLine.p1;
+ CCollision::CalculateTrianglePlanes(colModel);
+ for (int i = 0; i < colModel->numTriangles; i++) {
+ if (colModel->triangles[i].surface == SURFACE_GLASS &&
+ CCollision::TestLineTriangle(shootLine, colModel->vertices, colModel->triangles[i], colModel->trianglePlanes[i])) {
+ passesGlass = true;
+ break;
+ }
+ }
+ CAutomobile *car = (CAutomobile*)veh;
+
+ // No need to damage windscreen if there isn't one.
+ if (passesGlass && car->Damage.ProgressPanelDamage(VEHPANEL_WINDSCREEN)) {
+ if (car->Damage.GetPanelStatus(VEHPANEL_WINDSCREEN) == PANEL_STATUS_SMASHED2)
+ car->Damage.ProgressPanelDamage(VEHPANEL_WINDSCREEN);
+
+ car->SetPanelDamage(CAR_WINDSCREEN, VEHPANEL_WINDSCREEN, true);
+ DMAudio.PlayOneShot(veh->m_audioEntityId, SOUND_CAR_WINDSHIELD_CRACK, 0.f);
+ }
+ }
+ }
+ }
+
+ if (!found) {
+ *victim = veh;
+ *point = origPoint;
+ }
}
#ifdef COMPATIBLE_SAVES
diff --git a/src/weapons/Weapon.h b/src/weapons/Weapon.h
index c7685e0d..f720b312 100644
--- a/src/weapons/Weapon.h
+++ b/src/weapons/Weapon.h
@@ -2,12 +2,13 @@
#include "WeaponType.h"
-#define DRIVEBYAUTOAIMING_MAXDIST (2.5f)
+#define CAR_DRIVEBYAUTOAIMING_MAXDIST (2.5f)
#define DOOMAUTOAIMING_MAXDIST (9000.0f)
class CEntity;
class CPhysical;
-class CAutomobile;
+class CVehicle;
+class CPed;
struct CColPoint;
class CWeaponInfo;
@@ -20,10 +21,13 @@ public:
int32 m_nAmmoTotal;
uint32 m_nTimer;
bool m_bAddRotOffset;
-
+
+ static bool bPhotographHasBeenTaken;
+
CWeapon() {
m_bAddRotOffset = false;
}
+ CWeapon(eWeaponType type, int32 ammo);
CWeaponInfo *GetInfo();
@@ -32,12 +36,14 @@ public:
static void UpdateWeapons (void);
void Initialise(eWeaponType type, int32 ammo);
+ void Shutdown();
bool Fire (CEntity *shooter, CVector *fireSource);
- bool FireFromCar (CAutomobile *shooter, bool left);
+ bool FireFromCar (CVehicle *shooter, bool left, bool right);
bool FireMelee (CEntity *shooter, CVector &fireSource);
bool FireInstantHit(CEntity *shooter, CVector *fireSource);
+ static void AddGunFlashBigGuns(CVector start, CVector end);
void AddGunshell (CEntity *shooter, CVector const &source, CVector2D const &direction, float size);
void DoBulletImpact(CEntity *shooter, CEntity *victim, CVector *source, CVector *target, CColPoint *point, CVector2D ahead);
@@ -47,16 +53,18 @@ public:
static void GenerateFlameThrowerParticles(CVector pos, CVector dir);
bool FireAreaEffect (CEntity *shooter, CVector *fireSource);
+ bool LaserScopeDot (CVector *pOutPos, float *pOutSize);
bool FireSniper (CEntity *shooter);
+ bool TakePhotograph (CEntity *shooter);
bool FireM16_1stPerson (CEntity *shooter);
- bool FireInstantHitFromCar(CAutomobile *shooter, bool left);
+ bool FireInstantHitFromCar(CVehicle *shooter, bool left, bool right);
- 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);
+ static void DoDoomAiming (CEntity *shooter, CVector *source, CVector *target);
+ static void DoTankDoomAiming (CEntity *shooter, CEntity *driver, CVector *source, CVector *target);
+ static void DoDriveByAutoAiming(CEntity *driver, CVehicle *vehicle, CVector *source, CVector *target);
void Reload(void);
- void Update(int32 audioEntity);
+ void Update(int32 audioEntity, CPed *pedToAdjustSound);
bool IsTypeMelee (void);
bool IsType2Handed(void);
@@ -66,8 +74,12 @@ 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);
+ static void CheckForShootingVehicleOccupant(CEntity **victim, CColPoint *point, eWeaponType weapon, CVector const& source, CVector const& target);
+
#ifdef COMPATIBLE_SAVES
void Save(uint8*& buf);
void Load(uint8*& buf);
diff --git a/src/weapons/WeaponEffects.cpp b/src/weapons/WeaponEffects.cpp
index 32e55fb1..bb95ea85 100644
--- a/src/weapons/WeaponEffects.cpp
+++ b/src/weapons/WeaponEffects.cpp
@@ -4,9 +4,11 @@
#include "WeaponEffects.h"
#include "TxdStore.h"
#include "Sprite.h"
+#include "PlayerPed.h"
+#include "World.h"
+#include "WeaponType.h"
RwTexture *gpCrossHairTex;
-RwRaster *gpCrossHairRaster;
CWeaponEffects gCrossHair;
@@ -25,10 +27,10 @@ CWeaponEffects::Init(void)
{
gCrossHair.m_bActive = false;
gCrossHair.m_vecPos = CVector(0.0f, 0.0f, 0.0f);
- gCrossHair.m_nRed = 0;
+ gCrossHair.m_nRed = 255;
gCrossHair.m_nGreen = 0;
gCrossHair.m_nBlue = 0;
- gCrossHair.m_nAlpha = 255;
+ gCrossHair.m_nAlpha = 127;
gCrossHair.m_fSize = 1.0f;
gCrossHair.m_fRotation = 0.0f;
@@ -37,8 +39,7 @@ CWeaponEffects::Init(void)
int32 slot = CTxdStore::FindTxdSlot("particle");
CTxdStore::SetCurrentTxd(slot);
- gpCrossHairTex = RwTextureRead("crosshair", nil);
- gpCrossHairRaster = RwTextureGetRaster(gpCrossHairTex);
+ gpCrossHairTex = RwTextureRead("target256", "target256m");
CTxdStore::PopCurrentTxd();
}
@@ -47,9 +48,7 @@ void
CWeaponEffects::Shutdown(void)
{
RwTextureDestroy(gpCrossHairTex);
-#if GTA_VERSION >= GTA3_PC_11
gpCrossHairTex = nil;
-#endif
}
void
@@ -57,10 +56,6 @@ CWeaponEffects::MarkTarget(CVector pos, uint8 red, uint8 green, uint8 blue, uint
{
gCrossHair.m_bActive = true;
gCrossHair.m_vecPos = pos;
- gCrossHair.m_nRed = red;
- gCrossHair.m_nGreen = green;
- gCrossHair.m_nBlue = blue;
- gCrossHair.m_nAlpha = alpha;
gCrossHair.m_fSize = size;
}
@@ -73,13 +68,37 @@ CWeaponEffects::ClearCrossHair(void)
void
CWeaponEffects::Render(void)
{
+ static float aCrossHairSize[WEAPONTYPE_TOTALWEAPONS] =
+ {
+ 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,
+ 0.4f, 0.4f,
+ 0.5f,
+ 0.3f,
+ 0.9f, 0.9f, 0.9f,
+ 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
+ 0.1f, 0.1f,
+ 1.0f,
+ 0.6f,
+ 0.7f,
+ 0.0f, 0.0f
+ };
+
+
+
if ( gCrossHair.m_bActive )
{
+ float size = aCrossHairSize[FindPlayerPed()->GetWeapon()->m_eWeaponType];
+
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void *)FALSE);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)FALSE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)TRUE);
- RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDONE);
- RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDONE);
- RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)gpCrossHairRaster);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA);
+#ifdef FIX_BUGS
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA);
+#else
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVDESTALPHA);
+#endif
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)RwTextureGetRaster(gpCrossHairTex));
RwV3d pos;
float w, h;
@@ -88,17 +107,27 @@ CWeaponEffects::Render(void)
PUSH_RENDERGROUP("CWeaponEffects::Render");
float recipz = 1.0f / pos.z;
- CSprite::RenderOneXLUSprite(pos.x, pos.y, pos.z,
- gCrossHair.m_fSize * w, gCrossHair.m_fSize * h,
- gCrossHair.m_nRed, gCrossHair.m_nGreen, gCrossHair.m_nBlue, 255,
- recipz, 255);
+ CSprite::RenderOneXLUSprite_Rotate_Aspect(pos.x, pos.y, pos.z,
+ w, h,
+ 255, 88, 100, 158,
+ recipz, gCrossHair.m_fRotation, gCrossHair.m_nAlpha);
+
+ float recipz2 = 1.0f / pos.z;
+
+ CSprite::RenderOneXLUSprite_Rotate_Aspect(pos.x, pos.y, pos.z,
+ size*w, size*h,
+ 107, 134, 247, 158,
+ recipz2, TWOPI - gCrossHair.m_fRotation, gCrossHair.m_nAlpha);
+
+ gCrossHair.m_fRotation += 0.02f;
+ if ( gCrossHair.m_fRotation > TWOPI )
+ gCrossHair.m_fRotation = 0.0;
POP_RENDERGROUP();
}
-
+
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)FALSE);
- RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void *)FALSE);
- RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA);
- RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void *)TRUE);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)TRUE);
}
} \ No newline at end of file
diff --git a/src/weapons/WeaponInfo.cpp b/src/weapons/WeaponInfo.cpp
index ba872454..1f78b7d4 100644
--- a/src/weapons/WeaponInfo.cpp
+++ b/src/weapons/WeaponInfo.cpp
@@ -6,28 +6,102 @@
#include "AnimManager.h"
#include "AnimBlendAssociation.h"
#include "Weapon.h"
+#include "ModelInfo.h"
+#include "ModelIndices.h"
-static CWeaponInfo aWeaponInfo[WEAPONTYPE_TOTALWEAPONS];
+uint16 CWeaponInfo::ms_aReloadSampleTime[WEAPONTYPE_TOTALWEAPONS] =
+{
+ 0, // UNARMED
+ 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
+ 300, // M16
+ 300, // AK47
+ 423, // SNIPERRIFLE
+ 423, // LASERSCOPE
+ 400, // ROCKETLAUNCHER
+ 0, // FLAMETHROWER
+ 0, // M60
+ 0, // MINIGUN
+ 0, // DETONATOR
+ 0, // HELICANNON
+ 0 // CAMERA
+};
+
+// 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
+};
-static char ms_aWeaponNames[][32] = {
+CWeaponInfo aWeaponInfo[WEAPONTYPE_TOTALWEAPONS];
+char CWeaponInfo::ms_aWeaponNames[WEAPONTYPE_TOTALWEAPONS][32] =
+{
"Unarmed",
+ "BrassKnuckle",
+ "ScrewDriver",
+ "GolfClub",
+ "NightStick",
+ "Knife",
"BaseballBat",
+ "Hammer",
+ "Cleaver",
+ "Machete",
+ "Katana",
+ "Chainsaw",
+ "Grenade",
+ "DetonateGrenade",
+ "TearGas",
+ "Molotov",
+ "Rocket",
"Colt45",
- "Uzi",
+ "Python",
"Shotgun",
- "AK47",
- "M16",
+ "Spas12Shotgun",
+ "StubbyShotgun",
+ "Tec9",
+ "Uzi",
+ "SilencedIngram",
+ "Mp5",
+ "m4",
+ "Ruger",
"SniperRifle",
+ "LaserScope",
"RocketLauncher",
"FlameThrower",
- "Molotov",
- "Grenade",
+ "M60",
+ "Minigun",
"Detonator",
- "HeliCannon"
+ "HeliCannon",
+ "Camera",
};
CWeaponInfo*
-CWeaponInfo::GetWeaponInfo(eWeaponType weaponType) {
+CWeaponInfo::GetWeaponInfo(eWeaponType weaponType)
+{
return &aWeaponInfo[weaponType];
}
@@ -37,9 +111,26 @@ CWeaponInfo::Initialise(void)
debug("Initialising CWeaponInfo...\n");
for (int i = 0; i < WEAPONTYPE_TOTALWEAPONS; i++) {
aWeaponInfo[i].m_eWeaponFire = WEAPON_FIRE_INSTANT_HIT;
- aWeaponInfo[i].m_AnimToPlay = ANIM_STD_PUNCH;
- aWeaponInfo[i].m_Anim2ToPlay = ANIM_STD_NUM;
+ aWeaponInfo[i].m_fRange = 0.0f;
+ aWeaponInfo[i].m_nFiringRate = 0;
+ aWeaponInfo[i].m_nReload = 0;
+ aWeaponInfo[i].m_nAmountofAmmunition = 0;
+ aWeaponInfo[i].m_nDamage = 0;
+ aWeaponInfo[i].m_fSpeed = 0.0f;
+ aWeaponInfo[i].m_fRadius = 0.0f;
+ aWeaponInfo[i].m_fLifespan = 0.0f;
+ aWeaponInfo[i].m_fSpread = 0.0f;
+ aWeaponInfo[i].m_vecFireOffset = CVector(0.0f, 0.0f, 0.0f);
+ aWeaponInfo[i].m_AnimToPlay = ASSOCGRP_UNARMED;
+ aWeaponInfo[i].m_fAnimLoopStart = 0.0f;
+ aWeaponInfo[i].m_fAnimLoopEnd = 0.0f;
+ aWeaponInfo[i].m_fAnimFrameFire = 0.0f;
+ aWeaponInfo[i].m_fAnim2LoopStart = 0.0f;
+ aWeaponInfo[i].m_fAnim2LoopEnd = 0.0f;
+ aWeaponInfo[i].m_fAnim2FrameFire = 0.0f;
+ aWeaponInfo[i].m_fAnimBreakout = 0.0f;
aWeaponInfo[i].m_Flags = WEAPONFLAG_USE_GRAVITY | WEAPONFLAG_SLOWS_DOWN | WEAPONFLAG_RAND_SPEED | WEAPONFLAG_EXPANDS | WEAPONFLAG_EXPLODES;
+ aWeaponInfo[i].m_nWeaponSlot = WEAPONSLOT_UNARMED;
}
debug("Loading weapon data...\n");
LoadWeaponData();
@@ -51,21 +142,18 @@ CWeaponInfo::LoadWeaponData(void)
{
float spread, speed, lifeSpan, radius;
float range, fireOffsetX, fireOffsetY, fireOffsetZ;
- float delayBetweenAnimAndFire, delayBetweenAnim2AndFire, animLoopStart, animLoopEnd;
+ float anim2LoopStart, anim2LoopEnd, delayBetweenAnim2AndFire, animBreakout;
+ float delayBetweenAnimAndFire, animLoopStart, animLoopEnd;
int flags, ammoAmount, damage, reload, weaponType;
- int firingRate, modelId;
+ int firingRate, modelId, modelId2, weaponSlot;
char line[256], weaponName[32], fireType[32];
- char animToPlay[32], anim2ToPlay[32];
-
- CAnimBlendAssociation *animAssoc;
- AnimationId animId;
+ char animToPlay[32];
size_t bp, buflen;
int lp, linelen;
CFileMgr::SetDir("DATA");
buflen = CFileMgr::LoadFile("WEAPON.DAT", work_buff, sizeof(work_buff), "r");
- CFileMgr::SetDir("");
for (bp = 0; bp < buflen; ) {
// read file line by line
@@ -96,10 +184,9 @@ CWeaponInfo::LoadWeaponData(void)
fireType[0] = '\0';
fireOffsetY = 0.0f;
fireOffsetZ = 0.0f;
- animId = ANIM_STD_WALK;
sscanf(
&line[lp],
- "%s %s %f %d %d %d %d %f %f %f %f %f %f %f %s %s %f %f %f %f %d %d",
+ "%s %s %f %d %d %d %d %f %f %f %f %f %f %f %s %f %f %f %f %f %f %f %d %d %x %d",
weaponName,
fireType,
&range,
@@ -115,27 +202,23 @@ CWeaponInfo::LoadWeaponData(void)
&fireOffsetY,
&fireOffsetZ,
animToPlay,
- anim2ToPlay,
&animLoopStart,
&animLoopEnd,
&delayBetweenAnimAndFire,
+ &anim2LoopStart,
+ &anim2LoopEnd,
&delayBetweenAnim2AndFire,
+ &animBreakout,
&modelId,
- &flags);
+ &modelId2,
+ &flags,
+ &weaponSlot);
if (strncmp(weaponName, "ENDWEAPONDATA", 13) == 0)
return;
weaponType = FindWeaponType(weaponName);
- animAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, animToPlay);
- animId = static_cast<AnimationId>(animAssoc->animId);
-
- if (strcmp(anim2ToPlay, "null") != 0) {
- animAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, anim2ToPlay);
- aWeaponInfo[weaponType].m_Anim2ToPlay = (AnimationId) animAssoc->animId;
- }
-
CVector vecFireOffset(fireOffsetX, fireOffsetY, fireOffsetZ);
aWeaponInfo[weaponType].m_eWeaponFire = FindWeaponFireType(fireType);
@@ -149,13 +232,35 @@ CWeaponInfo::LoadWeaponData(void)
aWeaponInfo[weaponType].m_fLifespan = lifeSpan;
aWeaponInfo[weaponType].m_fSpread = spread;
aWeaponInfo[weaponType].m_vecFireOffset = vecFireOffset;
- aWeaponInfo[weaponType].m_AnimToPlay = animId;
aWeaponInfo[weaponType].m_fAnimLoopStart = animLoopStart / 30.0f;
aWeaponInfo[weaponType].m_fAnimLoopEnd = animLoopEnd / 30.0f;
+ aWeaponInfo[weaponType].m_fAnim2LoopStart = anim2LoopStart / 30.0f;
+ aWeaponInfo[weaponType].m_fAnim2LoopEnd = anim2LoopEnd / 30.0f;
aWeaponInfo[weaponType].m_fAnimFrameFire = delayBetweenAnimAndFire / 30.0f;
aWeaponInfo[weaponType].m_fAnim2FrameFire = delayBetweenAnim2AndFire / 30.0f;
+ aWeaponInfo[weaponType].m_fAnimBreakout = animBreakout / 30.0f;
aWeaponInfo[weaponType].m_nModelId = modelId;
+ aWeaponInfo[weaponType].m_nModel2Id = modelId2;
aWeaponInfo[weaponType].m_Flags = flags;
+ aWeaponInfo[weaponType].m_nWeaponSlot = weaponSlot;
+
+ if (animLoopEnd < 98.0f && weaponType != WEAPONTYPE_FLAMETHROWER && !CWeapon::IsShotgun(weaponType))
+ aWeaponInfo[weaponType].m_nFiringRate = ((aWeaponInfo[weaponType].m_fAnimLoopEnd - aWeaponInfo[weaponType].m_fAnimLoopStart) * 900.0f);
+
+ if (weaponType == WEAPONTYPE_DETONATOR || weaponType == WEAPONTYPE_HELICANNON)
+ modelId = -1;
+ else if (weaponType == WEAPONTYPE_DETONATOR_GRENADE)
+ modelId = MI_BOMB;
+
+ if (modelId != -1)
+ ((CWeaponModelInfo*)CModelInfo::GetModelInfo(modelId))->SetWeaponInfo(weaponType);
+
+ for (int i = 0; i < NUM_ANIM_ASSOC_GROUPS; i++) {
+ if (!strcmp(animToPlay, CAnimManager::GetAnimGroupName((AssocGroupId)i))) {
+ aWeaponInfo[weaponType].m_AnimToPlay = (AssocGroupId)i;
+ break;
+ }
+ }
}
}
@@ -177,6 +282,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 96e2ecf4..d7f1563d 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"
@@ -16,10 +17,25 @@ enum
WEAPONFLAG_1ST_PERSON = 1 << 8,
WEAPONFLAG_HEAVY = 1 << 9,
WEAPONFLAG_THROW = 1 << 10,
+ WEAPONFLAG_RELOAD_LOOP2START = 1 << 11,
+ WEAPONFLAG_USE_2ND = 1 << 12,
+ WEAPONFLAG_GROUND_2ND = 1 << 13,
+ WEAPONFLAG_FINISH_3RD = 1 << 14,
+ WEAPONFLAG_RELOAD = 1 << 15,
+ WEAPONFLAG_FIGHTMODE = 1 << 16,
+ WEAPONFLAG_CROUCHFIRE = 1 << 17,
+ WEAPONFLAG_COP3_RD = 1 << 18,
+ WEAPONFLAG_GROUND_3RD = 1 << 19,
+ WEAPONFLAG_PARTIALATTACK = 1 << 20,
+ WEAPONFLAG_ANIMDETONATE = 1 << 21,
};
class CWeaponInfo {
+ static char ms_aWeaponNames[WEAPONTYPE_TOTALWEAPONS][32];
public:
+ static uint16 ms_aReloadSampleTime[WEAPONTYPE_TOTALWEAPONS];
+ static int32 ms_aMaxAmmoForWeapon[WEAPONTYPE_TOTALWEAPONS];
+
eWeaponFire m_eWeaponFire;
float m_fRange;
uint32 m_nFiringRate;
@@ -31,22 +47,28 @@ public:
float m_fLifespan;
float m_fSpread;
CVector m_vecFireOffset;
- AnimationId m_AnimToPlay;
- AnimationId m_Anim2ToPlay;
+ AssocGroupId m_AnimToPlay;
float m_fAnimLoopStart;
float m_fAnimLoopEnd;
float m_fAnimFrameFire;
+ float m_fAnim2LoopStart;
+ float m_fAnim2LoopEnd;
float m_fAnim2FrameFire;
+ float m_fAnimBreakout;
int32 m_nModelId;
+ int32 m_nModel2Id;
uint32 m_Flags;
+ uint32 m_nWeaponSlot;
+
static void Initialise(void);
static void LoadWeaponData(void);
static CWeaponInfo *GetWeaponInfo(eWeaponType weaponType);
static eWeaponFire FindWeaponFireType(char *name);
static eWeaponType FindWeaponType(char *name);
static void Shutdown(void);
+ static bool IsWeaponSlotAmmoMergeable(uint32 slot) { return slot == WEAPONSLOT_SHOTGUN || slot == WEAPONSLOT_SUBMACHINEGUN || slot == WEAPONSLOT_RIFLE; }
bool IsFlagSet(uint32 flag) const { return (m_Flags & flag) != 0; }
};
-VALIDATE_SIZE(CWeaponInfo, 0x54); \ No newline at end of file
+VALIDATE_SIZE(CWeaponInfo, 0x64);
diff --git a/src/weapons/WeaponType.h b/src/weapons/WeaponType.h
index b45740b7..1220196f 100644
--- a/src/weapons/WeaponType.h
+++ b/src/weapons/WeaponType.h
@@ -3,20 +3,44 @@
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_UZI,
+ WEAPONTYPE_PYTHON,
WEAPONTYPE_SHOTGUN,
- WEAPONTYPE_AK47,
- WEAPONTYPE_M16,
+ WEAPONTYPE_SPAS12_SHOTGUN,
+ WEAPONTYPE_STUBBY_SHOTGUN,
+ WEAPONTYPE_TEC9,
+ WEAPONTYPE_UZI,
+ WEAPONTYPE_SILENCED_INGRAM,
+ WEAPONTYPE_MP5,
+ WEAPONTYPE_M4,
+ WEAPONTYPE_RUGER,
WEAPONTYPE_SNIPERRIFLE,
+ WEAPONTYPE_LASERSCOPE,
WEAPONTYPE_ROCKETLAUNCHER,
WEAPONTYPE_FLAMETHROWER,
- WEAPONTYPE_MOLOTOV,
- WEAPONTYPE_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,
@@ -25,9 +49,22 @@ enum eWeaponType
WEAPONTYPE_DROWNING,
WEAPONTYPE_FALL,
WEAPONTYPE_UNIDENTIFIED,
-
- WEAPONTYPE_TOTALWEAPONS = WEAPONTYPE_LAST_WEAPONTYPE,
- WEAPONTYPE_TOTAL_INVENTORY_WEAPONS = 13,
+ WEAPONTYPE_ANYMELEE,
+ WEAPONTYPE_ANYWEAPON
+};
+
+enum {
+ WEAPONSLOT_UNARMED = 0,
+ WEAPONSLOT_MELEE,
+ WEAPONSLOT_PROJECTILE,
+ WEAPONSLOT_HANDGUN,
+ WEAPONSLOT_SHOTGUN,
+ WEAPONSLOT_SUBMACHINEGUN,
+ WEAPONSLOT_RIFLE,
+ WEAPONSLOT_HEAVY,
+ WEAPONSLOT_SNIPER,
+ WEAPONSLOT_OTHER,
+ TOTAL_WEAPON_SLOTS
};
enum eWeaponFire {
@@ -35,7 +72,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