aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/ISSUE_TEMPLATE/bug_report.md24
-rw-r--r--.github/workflows/build-cmake-conan.yml10
-rw-r--r--.github/workflows/reVC_msvc_amd64.yml (renamed from .github/workflows/re3_msvc_amd64.yml)14
-rw-r--r--.github/workflows/reVC_msvc_x86.yml (renamed from .github/workflows/re3_msvc_x86.yml)14
-rw-r--r--.gitignore4
-rw-r--r--CMakeLists.txt6
-rw-r--r--README.md54
-rw-r--r--codewarrior/Debug/gta-vc.txt (renamed from codewarrior/Debug/gta3.txt)0
-rw-r--r--codewarrior/Release/gta-vc.txt (renamed from codewarrior/Release/gta3.txt)0
-rw-r--r--codewarrior/reVC.mcp.xml (renamed from codewarrior/re3.mcp.xml)1454
-rw-r--r--conanfile.py18
-rw-r--r--gamefiles/TEXT/JAPANESE.gxtbin122022 -> 0 bytes
-rw-r--r--gamefiles/TEXT/american.gxtbin220642 -> 424066 bytes
-rw-r--r--gamefiles/TEXT/english.gxtbin204492 -> 0 bytes
-rw-r--r--gamefiles/TEXT/french.gxtbin246616 -> 470068 bytes
-rw-r--r--gamefiles/TEXT/german.gxtbin242680 -> 461962 bytes
-rw-r--r--gamefiles/TEXT/italian.gxtbin242050 -> 459018 bytes
-rwxr-xr-xgamefiles/TEXT/polish.gxtbin241682 -> 0 bytes
-rw-r--r--gamefiles/TEXT/russian.gxtbin222468 -> 420604 bytes
-rw-r--r--gamefiles/TEXT/spanish.gxtbin235614 -> 455350 bytes
-rw-r--r--gamefiles/data/PARTICLE.CFG363
-rw-r--r--gamefiles/data/freeroam_miami.scmbin0 -> 38197 bytes
-rw-r--r--gamefiles/data/main_d.scmbin620154 -> 0 bytes
-rw-r--r--gamefiles/data/main_freeroam.scmbin1618 -> 0 bytes
-rw-r--r--gamefiles/models/fonts_j.txdbin1052072 -> 0 bytes
-rw-r--r--gamefiles/models/fonts_p.txdbin1379752 -> 0 bytes
-rw-r--r--gamefiles/models/fonts_r.txdbin1379752 -> 524584 bytes
-rw-r--r--gamefiles/models/frontend_ds2.txdbin0 -> 329976 bytes
-rw-r--r--gamefiles/models/frontend_ds3.txdbin590632 -> 524968 bytes
-rw-r--r--gamefiles/models/frontend_ds4.txdbin590632 -> 524968 bytes
-rw-r--r--gamefiles/models/frontend_x360.txdbin590632 -> 524968 bytes
-rw-r--r--gamefiles/models/frontend_xone.txdbin590632 -> 524968 bytes
-rw-r--r--gamefiles/models/generic.txdbin1604112 -> 1168376 bytes
-rw-r--r--gamefiles/models/menu.txdbin10244648 -> 0 bytes
-rw-r--r--gamefiles/models/particle.txdbin414968 -> 2668072 bytes
-rw-r--r--gamefiles/models/ps3btns.txdbin528424 -> 528424 bytes
-rw-r--r--gamefiles/models/x360btns.txdbin528424 -> 528424 bytes
-rw-r--r--gamefiles/neo/carTweakingTable.dat208
-rw-r--r--gamefiles/neo/neo.txdbin118696 -> 28968 bytes
-rw-r--r--gamefiles/neo/rimTweakingTable.dat260
-rw-r--r--gamefiles/neo/worldTweakingTable.dat56
-rw-r--r--logo.pngbin24295 -> 58630 bytes
-rw-r--r--logo.svg94
-rw-r--r--premake5.lua22
-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.cpp10650
-rw-r--r--src/audio/AudioManager.cpp384
-rw-r--r--src/audio/AudioManager.h379
-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.h3029
-rw-r--r--src/audio/sampman_miles.cpp745
-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.cpp258
-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.cpp18
-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.cpp676
-rw-r--r--src/control/Script.h131
-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.cpp654
-rw-r--r--src/control/Script7.cpp1404
-rw-r--r--src/control/Script8.cpp618
-rw-r--r--src/control/ScriptCommands.h330
-rw-r--r--src/control/ScriptDebug.cpp442
-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.cpp1875
-rw-r--r--src/core/Camera.h110
-rw-r--r--src/core/Clock.cpp21
-rw-r--r--src/core/ControllerConfig.cpp234
-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.cpp8457
-rw-r--r--src/core/Frontend.h830
-rw-r--r--src/core/Frontend_PS2.cpp31
-rw-r--r--src/core/Frontend_PS2.h6
-rw-r--r--src/core/Game.cpp718
-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.cpp632
-rw-r--r--src/core/MenuScreensCustom.cpp777
-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.cpp1074
-rw-r--r--src/core/Radar.h187
-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.h8
-rw-r--r--src/core/config.h232
-rw-r--r--src/core/main.cpp866
-rw-r--r--src/core/re3.cpp270
-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.cpp4863
-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.cpp2841
-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.cpp1108
-rw-r--r--src/peds/PlayerPed.h53
-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.cpp448
-rw-r--r--src/save/GenericGameStorage.h7
-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.cpp30
-rw-r--r--src/skel/crossplatform.h4
-rw-r--r--src/skel/glfw/glfw.cpp97
-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.cpp2495
-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.cpp1874
-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
-rw-r--r--utils/gxt/american.txt16020
-rw-r--r--utils/gxt/build.bat13
-rw-r--r--utils/gxt/english.txt7026
-rw-r--r--utils/gxt/french.txt17208
-rw-r--r--utils/gxt/german.txt17043
-rw-r--r--utils/gxt/italian.txt17040
-rwxr-xr-xutils/gxt/polish.txt8114
-rw-r--r--utils/gxt/russian.txt8115
-rw-r--r--utils/gxt/spanish.txt16813
434 files changed, 152780 insertions, 96838 deletions
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
deleted file mode 100644
index 85d1e584..00000000
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ /dev/null
@@ -1,24 +0,0 @@
----
-name: Bug report
-about: Create a report to help us improve
-title: ''
-labels: ''
-assignees: ''
-
----
-
-**Describe the bug**
-A clear and concise description of what the bug is.
-
-**To Reproduce**
-Steps to reproduce the behavior.
-
-**Expected behavior**
-A clear and concise description of what you expected to happen.
-
-**Screenshots**
-If applicable, add screenshots to help explain your problem.
-
-**Version**
-Tell us what version you're running. Find out using the debug menu (Ctrl-M, Debug -> Version Text)
-If you send a screenshot just enable it beforehand.
diff --git a/.github/workflows/build-cmake-conan.yml b/.github/workflows/build-cmake-conan.yml
index 5e8dad94..e5e80791 100644
--- a/.github/workflows/build-cmake-conan.yml
+++ b/.github/workflows/build-cmake-conan.yml
@@ -1,4 +1,4 @@
-name: re3 conan+cmake
+name: reVC conan+cmake
on:
pull_request:
push:
@@ -96,13 +96,13 @@ jobs:
conan export re3mss miles-sdk/master@
- name: "Download/build dependencies (conan install)"
run: |
- conan install ${{ github.workspace }} re3/master@ -if build -o re3:audio=${{ matrix.audio }} -o librw:platform=${{ matrix.platform }} -o librw:gl3_gfxlib=${{ matrix.gl3_gfxlib || 'glfw' }} --build missing -pr:h ./host_profile -pr:b default -s re3:build_type=RelWithDebInfo -s librw:build_type=RelWithDebInfo
+ conan install ${{ github.workspace }} reVC/master@ -if build -o reVC:audio=${{ matrix.audio }} -o librw:platform=${{ matrix.platform }} -o librw:gl3_gfxlib=${{ matrix.gl3_gfxlib || 'glfw' }} --build missing -pr:h ./host_profile -pr:b default -s reVC:build_type=RelWithDebInfo -s librw:build_type=RelWithDebInfo
env:
CONAN_SYSREQUIRES_MODE: enabled
- - name: "Build re3 (conan build)"
+ - name: "Build reVC (conan build)"
run: |
conan build ${{ github.workspace }} -if build -bf build -pf package
- - name: "Package re3 (conan package)"
+ - name: "Package reVC (conan package)"
run: |
conan package ${{ github.workspace }} -if build -bf build -pf package
- name: "Create binary package (cpack)"
@@ -113,5 +113,5 @@ jobs:
uses: actions/upload-artifact@v2
with:
name: "${{ matrix.os }}-${{ matrix.platform }}"
- path: build/*.zip
+ path: build/*.tar.xz
if-no-files-found: error
diff --git a/.github/workflows/re3_msvc_amd64.yml b/.github/workflows/reVC_msvc_amd64.yml
index 014ac4f7..a00c5d2c 100644
--- a/.github/workflows/re3_msvc_amd64.yml
+++ b/.github/workflows/reVC_msvc_amd64.yml
@@ -1,4 +1,4 @@
-name: re3 premake amd64
+name: reVC premake amd64
on:
pull_request:
@@ -37,14 +37,14 @@ jobs:
./premake5 vs2019 --with-librw --no-full-paths --glfwdir64=${{env.GLFW_BASE}}
- name: Build
run: |
- msbuild -m build/re3.sln /property:Configuration=${{matrix.buildtype}} /property:Platform=${{matrix.platform}}
+ msbuild -m build/reVC.sln /property:Configuration=${{matrix.buildtype}} /property:Platform=${{matrix.platform}}
# - name: Pack artifacts
# run: |
- # 7z a re3_${{matrix.buildtype}}_${{matrix.platform}}.zip ./bin/${{matrix.platform}}/${{matrix.buildtype}}/*
+ # 7z a reVC_${{matrix.buildtype}}_${{matrix.platform}}.zip ./bin/${{matrix.platform}}/${{matrix.buildtype}}/*
- name: Move binaries to gamefiles
run: |
- mv ./bin/${{matrix.platform}}/${{matrix.buildtype}}/re3.exe ./gamefiles/
- mv ./bin/${{matrix.platform}}/${{matrix.buildtype}}/re3.pdb ./gamefiles/
+ mv ./bin/${{matrix.platform}}/${{matrix.buildtype}}/reVC.exe ./gamefiles/
+ mv ./bin/${{matrix.platform}}/${{matrix.buildtype}}/reVC.pdb ./gamefiles/
- name: Move dynamic dependencies to gamefiles
run: |
mv ./vendor/mpg123/dist/Win64/libmpg123-0.dll ./gamefiles/
@@ -52,12 +52,12 @@ jobs:
- name: Upload artifact to actions
uses: actions/upload-artifact@v2
with:
- name: re3_${{matrix.buildtype}}_${{matrix.platform}}
+ name: reVC_${{matrix.buildtype}}_${{matrix.platform}}
path: ./gamefiles/*
# - name: Upload artifact to Bintray
# uses: hpcsc/upload-bintray-docker-action@v1
# with:
-# repository: re3
+# repository: reVC
# package: ${{matrix.buildtype}}_${{matrix.platform}}
# version: 1.0-$(echo ${GITHUB_SHA}
# sourcePath: ./bin/${{matrix.platform}}/${{matrix.buildtype}}
diff --git a/.github/workflows/re3_msvc_x86.yml b/.github/workflows/reVC_msvc_x86.yml
index 87f0e430..1407aeae 100644
--- a/.github/workflows/re3_msvc_x86.yml
+++ b/.github/workflows/reVC_msvc_x86.yml
@@ -1,4 +1,4 @@
-name: re3 premake x86
+name: reVC premake x86
on:
pull_request:
@@ -37,14 +37,14 @@ jobs:
./premake5 vs2019 --with-librw --no-full-paths --glfwdir32=${{env.GLFW_BASE}}
- name: Build
run: |
- msbuild -m build/re3.sln /property:Configuration=${{matrix.buildtype}} /property:Platform=${{matrix.platform}}
+ msbuild -m build/reVC.sln /property:Configuration=${{matrix.buildtype}} /property:Platform=${{matrix.platform}}
# - name: Pack artifacts
# run: |
- # 7z a re3_${{matrix.buildtype}}_${{matrix.platform}}.zip ./bin/${{matrix.platform}}/${{matrix.buildtype}}/*
+ # 7z a reVC_${{matrix.buildtype}}_${{matrix.platform}}.zip ./bin/${{matrix.platform}}/${{matrix.buildtype}}/*
- name: Move binaries to gamefiles
run: |
- mv ./bin/${{matrix.platform}}/${{matrix.buildtype}}/re3.exe ./gamefiles/
- mv ./bin/${{matrix.platform}}/${{matrix.buildtype}}/re3.pdb ./gamefiles/
+ mv ./bin/${{matrix.platform}}/${{matrix.buildtype}}/reVC.exe ./gamefiles/
+ mv ./bin/${{matrix.platform}}/${{matrix.buildtype}}/reVC.pdb ./gamefiles/
- if: contains(matrix.platform, 'oal')
name: Move dynamic dependencies to gamefiles
run: |
@@ -53,12 +53,12 @@ jobs:
- name: Upload artifact to actions
uses: actions/upload-artifact@v2
with:
- name: re3_${{matrix.buildtype}}_${{matrix.platform}}
+ name: reVC_${{matrix.buildtype}}_${{matrix.platform}}
path: ./gamefiles/*
# - name: Upload artifact to Bintray
# uses: hpcsc/upload-bintray-docker-action@v1
# with:
-# repository: re3
+# repository: reVC
# package: ${{matrix.buildtype}}_${{matrix.platform}}
# version: 1.0-$(echo ${GITHUB_SHA}
# sourcePath: ./bin/${{matrix.platform}}/${{matrix.buildtype}}
diff --git a/.gitignore b/.gitignore
index 38ad5d73..c55a27ce 100644
--- a/.gitignore
+++ b/.gitignore
@@ -355,8 +355,8 @@ vendor/glfw-3.3.2.bin.WIN64/
sdk/
-codewarrior/re3.mcp
-codewarrior/re3_Data/
+codewarrior/reVC.mcp
+codewarrior/reVC_Data/
codewarrior/Release/
codewarrior/Debug/
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5396d3b4..e8689b38 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.8)
-set(EXECUTABLE re3)
-set(PROJECT RE3)
+set(EXECUTABLE reVC)
+set(PROJECT REVC)
project(${EXECUTABLE} C CXX)
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
@@ -81,6 +81,6 @@ if(${PROJECT}_INSTALL)
set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_NAME}")
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}")
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}")
- set(CPACK_GENERATOR "ZIP")
+ set(CPACK_GENERATOR "TXZ")
include(CPack)
endif()
diff --git a/README.md b/README.md
index 9ccabf1e..0bfd955b 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
-<img src="https://github.com/GTAmodding/re3/blob/master/logo.png?raw=true" alt="re3 logo" width="200">
+<img src="https://github.com/GTAmodding/re3/blob/miami/logo.png?raw=true" alt="reVC logo" width="200">
-[![Build Status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2FGTAmodding%2Fre3%2Fbadge%3Fref%3Dmaster&style=flat)](https://actions-badge.atrox.dev/GTAmodding/re3/goto?ref=master)
+[![Build Status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2FGTAmodding%2Fre3%2Fbadge%3Fref%3Dmiami&style=flat)](https://actions-badge.atrox.dev/GTAmodding/re3/goto?ref=miami)
<a href="https://discord.gg/RFNbjsUMGg"><img src="https://img.shields.io/badge/discord-join-7289DA.svg?logo=discord&longCache=true&style=flat" /></a>
## Intro
@@ -12,29 +12,25 @@ Rendering is handled either by original RenderWare (D3D8)
or the reimplementation [librw](https://github.com/aap/librw) (D3D9, OpenGL 2.1 or above, OpenGL ES 2.0 or above).\
Audio is done with MSS (using dlls from original GTA) or OpenAL.
-The project has also been ported to the [Nintendo Switch](https://github.com/AGraber/re3-nx/),
-[Playstation Vita](https://github.com/Rinnegatamante/re3) and
-[Nintendo Wii U](https://github.com/GaryOderNichts/re3-wiiu/).
-
We cannot build for PS2 or Xbox yet. If you're interested in doing so, get in touch with us.
## Installation
-- re3 requires PC game assets to work, so you **must** own [a copy of GTA III](https://store.steampowered.com/app/12100/Grand_Theft_Auto_III/).
-- Build re3 or download the latest build:
- - [Windows D3D9 MSS 32bit](https://nightly.link/GTAmodding/re3/workflows/re3_msvc_x86/master/re3_Release_win-x86-librw_d3d9-mss.zip)
- - [Windows D3D9 64bit](https://nightly.link/GTAmodding/re3/workflows/re3_msvc_amd64/master/re3_Release_win-amd64-librw_d3d9-oal.zip)
- - [Windows OpenGL 64bit](https://nightly.link/GTAmodding/re3/workflows/re3_msvc_amd64/master/re3_Release_win-amd64-librw_gl3_glfw-oal.zip)
- - [Linux 64bit](https://nightly.link/GTAmodding/re3/workflows/build-cmake-conan/master/ubuntu-18.04-gl3.zip)
- - [MacOS 64bit x86-64](https://nightly.link/GTAmodding/re3/workflows/build-cmake-conan/master/macos-latest-gl3.zip)
-- Extract the downloaded zip over your GTA 3 directory and run re3. The zip includes the binary, updated and additional gamefiles and in case of OpenAL the required dlls.
+- reVC requires game assets to work, so you **must** own [a copy of GTA Vice City](https://store.steampowered.com/app/12110/Grand_Theft_Auto_Vice_City/).
+- Build reVC or download the latest build:
+ - [Windows D3D9 MSS 32bit](https://nightly.link/GTAmodding/re3/workflows/reVC_msvc_x86/miami/reVC_Release_win-x86-librw_d3d9-mss.zip)
+ - [Windows D3D9 64bit](https://nightly.link/GTAmodding/re3/workflows/reVC_msvc_amd64/miami/reVC_Release_win-amd64-librw_d3d9-oal.zip)
+ - [Windows OpenGL 64bit](https://nightly.link/GTAmodding/re3/workflows/reVC_msvc_amd64/miami/reVC_Release_win-amd64-librw_gl3_glfw-oal.zip)
+ - [Linux 64bit](https://nightly.link/GTAmodding/re3/workflows/build-cmake-conan/miami/ubuntu-18.04-gl3.zip)
+ - [MacOS 64bit x86-64](https://nightly.link/GTAmodding/re3/workflows/build-cmake-conan/miami/macos-latest-gl3.zip)
+- Extract the downloaded zip over your GTA VC directory and run reVC. The zip includes the binary, updated and additional gamefiles and in case of OpenAL the required dlls.
## Screenshots
-![re3 2021-02-11 22-57-03-23](https://user-images.githubusercontent.com/1521437/107704085-fbdabd00-6cbc-11eb-8406-8951a80ccb16.png)
-![re3 2021-02-11 22-43-44-98](https://user-images.githubusercontent.com/1521437/107703339-cbdeea00-6cbb-11eb-8f0b-07daa105d470.png)
-![re3 2021-02-11 22-46-33-76](https://user-images.githubusercontent.com/1521437/107703343-cd101700-6cbb-11eb-9ccd-012cb90524b7.png)
-![re3 2021-02-11 22-50-29-54](https://user-images.githubusercontent.com/1521437/107703348-d00b0780-6cbb-11eb-8afd-054249c2b95e.png)
+![screen_ 1613087332](https://user-images.githubusercontent.com/1521437/107714111-f84f3200-6ccc-11eb-902e-d757481d579a.png)
+![screen_ 1613086852](https://user-images.githubusercontent.com/1521437/107714115-fa18f580-6ccc-11eb-9de5-eb4cd04865d3.png)
+![screen_ 1613086989](https://user-images.githubusercontent.com/1521437/107714103-f38a7e00-6ccc-11eb-88a3-c8c2033c51d6.png)
+![screen_ 1613087193](https://user-images.githubusercontent.com/1521437/107714106-f4bbab00-6ccc-11eb-96a9-13821d9b9684.png)
## Improvements
@@ -44,25 +40,22 @@ Some of them can be toggled at runtime, some cannot.
* Fixed a lot of smaller and bigger bugs
* User files (saves and settings) stored in GTA root directory
-* Settings stored in re3.ini file instead of gta3.set
+* Settings stored in reVC.ini file instead of gta_vc.set
* Debug menu to do and change various things (Ctrl-M to open)
* Debug camera (Ctrl-B to toggle)
* Rotatable camera
* XInput controller support (Windows)
* No loading screens between islands ("map memory usage" in menu)
-* Skinned ped support (models from Xbox or Mobile)
* Rendering
* Widescreen support (properly scaled HUD, Menu and FOV)
* PS2 MatFX (vehicle reflections)
* PS2 alpha test (better rendering of transparency)
- * PS2 particles
* Xbox vehicle rendering
* Xbox world lightmap rendering (needs Xbox map)
* Xbox ped rim light
* Xbox screen rain droplets
* More customizable colourfilter
* Menu
- * Map
* More options
* Controller configuration menu
* ...
@@ -75,7 +68,6 @@ The following things would be nice to have/do:
* Fix physics for high FPS
* Improve performance on lower end devices, especially the OpenGL layer on the Raspberry Pi (if you have experience with this, please get in touch)
-* Compare code with PS2 code (tedious, no good decompiler)
* [PS2 port](https://github.com/GTAmodding/re3/wiki/PS2-port)
* Xbox port (not quite as important)
* reverse remaining unused/debug functions
@@ -93,9 +85,9 @@ Sorry for the inconvenience.
## Building from Source
-When using premake, you may want to point GTA_III_RE_DIR environment variable to GTA3 root folder if you want the executable to be moved there via post-build script.
+When using premake, you may want to point GTA_VC_RE_DIR environment variable to GTA Vice City root folder if you want the executable to be moved there via post-build script.
-Clone the repository with `git clone --recursive https://github.com/GTAmodding/re3.git`. Then `cd re3` into the cloned repository.
+Clone the repository with `git clone --recursive -b miami https://github.com/GTAmodding/re3.git reVC`. Then `cd reVC` into the cloned repository.
<details><summary>Linux Premake</summary>
@@ -110,7 +102,7 @@ Install python and conan, and then run build.
conan export vendor/librw librw/master@
mkdir build
cd build
-conan install .. re3/master@ -if build -o re3:audio=openal -o librw:platform=gl3 -o librw:gl3_gfxlib=glfw --build missing -s re3:build_type=RelWithDebInfo -s librw:build_type=RelWithDebInfo
+conan install .. reVC/master@ -if build -o reVC:audio=openal -o librw:platform=gl3 -o librw:gl3_gfxlib=glfw --build missing -s reVC:build_type=RelWithDebInfo -s librw:build_type=RelWithDebInfo
conan build .. -if build -bf build -pf package
```
</details>
@@ -131,8 +123,8 @@ For FreeBSD using premake, proceed: [Building on FreeBSD](https://github.com/GTA
Assuming you have Visual Studio 2015/2017/2019:
- Run one of the `premake-vsXXXX.cmd` variants on root folder.
-- Open build/re3.sln with Visual Studio and compile the solution.
-
+- Open build/reVC.sln with Visual Studio and compile the solution.
+
Microsoft recently discontinued its downloads of the DX9 SDK. You can download an archived version here: https://archive.org/details/dxsdk_jun10
**If you choose OpenAL on Windows** You must read [Running OpenAL build on Windows](https://github.com/GTAmodding/re3/wiki/Running-OpenAL-build-on-Windows).
@@ -140,11 +132,11 @@ Microsoft recently discontinued its downloads of the DX9 SDK. You can download a
> :information_source: premake has an `--with-lto` option if you want the project to be compiled with Link Time Optimization.
-> :information_source: There are various settings in [config.h](https://github.com/GTAmodding/re3/tree/master/src/core/config.h), you may want to take a look there.
+> :information_source: There are various settings in [config.h](https://github.com/GTAmodding/re3/tree/miami/src/core/config.h), you may want to take a look there.
-> :information_source: re3 uses completely homebrew RenderWare-replacement rendering engine; [librw](https://github.com/aap/librw/). librw comes as submodule of re3, but you also can use LIBRW enviorenment variable to specify path to your own librw.
+> :information_source: reVC uses completely homebrew RenderWare-replacement rendering engine; [librw](https://github.com/aap/librw/). librw comes as submodule of re3, but you also can use LIBRW enviorenment variable to specify path to your own librw.
-If you feel the need, you can also use CodeWarrior 7 to compile re3 using the supplied codewarrior/re3.mcp project - this requires the original RW33 libraries, and the DX8 SDK. The build is unstable compared to the MSVC builds though, and is mostly meant to serve as a reference.
+If you feel the need, you can also use CodeWarrior 7 to compile reVC using the supplied codewarrior/reVC.mcp project - this requires the original RW34 libraries, and the DX8 SDK. The build is unstable compared to the MSVC builds though, and is mostly meant to serve as a reference.
## Contributing
As long as it's not linux/cross-platform skeleton/compatibility layer, all of the code on the repo that's not behind a preprocessor condition(like FIX_BUGS) are **completely** reversed code from original binaries.
diff --git a/codewarrior/Debug/gta3.txt b/codewarrior/Debug/gta-vc.txt
index e69de29b..e69de29b 100644
--- a/codewarrior/Debug/gta3.txt
+++ b/codewarrior/Debug/gta-vc.txt
diff --git a/codewarrior/Release/gta3.txt b/codewarrior/Release/gta-vc.txt
index e69de29b..e69de29b 100644
--- a/codewarrior/Release/gta3.txt
+++ b/codewarrior/Release/gta-vc.txt
diff --git a/codewarrior/re3.mcp.xml b/codewarrior/reVC.mcp.xml
index ca20ec2a..750fb675 100644
--- a/codewarrior/re3.mcp.xml
+++ b/codewarrior/reVC.mcp.xml
@@ -748,7 +748,7 @@
<!-- Settings for "x86 Project" panel -->
<SETTING><NAME>MWProject_X86_type</NAME><VALUE>Application</VALUE></SETTING>
- <SETTING><NAME>MWProject_X86_outfile</NAME><VALUE>Debug\gta3.exe</VALUE></SETTING>
+ <SETTING><NAME>MWProject_X86_outfile</NAME><VALUE>Debug\gta-vc.exe</VALUE></SETTING>
<SETTING><NAME>MWProject_X86_baseaddress</NAME><VALUE>4194304</VALUE></SETTING>
<SETTING><NAME>MWProject_X86_maxstacksize</NAME><VALUE>1024</VALUE></SETTING>
<SETTING><NAME>MWProject_X86_minstacksize</NAME><VALUE>4</VALUE></SETTING>
@@ -815,6 +815,146 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>mss32.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>d3d8.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>ddraw.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>dxguid.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>strmiids.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>dinput8.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>winmm.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>rwcore.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>rpworld.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>rpmatfx.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>rpskin.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>rphanim.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>rtbmp.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>rtquat.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>rtcharse.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>ole32.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>shell32.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>uuid.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>rtanim.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>rpanisot.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>AnimationId.h</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
@@ -1242,6 +1382,20 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>ColStore.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>ColStore.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS></FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>ColTriangle.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
@@ -1620,6 +1774,20 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>Script7.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>Script8.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>ScriptCommands.h</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
@@ -1627,6 +1795,20 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>SetPieces.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>SetPieces.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS></FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>TrafficLights.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
@@ -2117,6 +2299,20 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>Ropes.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>Ropes.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS></FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>Stats.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
@@ -2432,20 +2628,6 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
- <PATH>MloModelInfo.cpp</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Text</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>MloModelInfo.h</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Text</FILEKIND>
- <FILEFLAGS></FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
<PATH>ModelIndices.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
@@ -2530,21 +2712,14 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
- <PATH>XtraCompsModelInfo.h</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Text</FILEKIND>
- <FILEFLAGS></FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>CutsceneHead.cpp</PATH>
+ <PATH>WeaponModelInfo.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
- <PATH>CutsceneHead.h</PATH>
+ <PATH>WeaponModelInfo.h</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
@@ -2635,6 +2810,20 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>Stinger.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>Stinger.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS></FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>CivilianPed.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
@@ -2719,6 +2908,20 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>PedAttractor.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>PedAttractor.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS></FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>PedChat.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
@@ -2901,6 +3104,20 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>CutsceneShadow.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>CutsceneShadow.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS></FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>Draw.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
@@ -3013,6 +3230,20 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>Occlusion.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>Occlusion.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS></FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>Particle.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
@@ -3118,6 +3349,20 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>ShadowCamera.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>ShadowCamera.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS></FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>Shadows.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
@@ -3216,6 +3461,20 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>VarConsole.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>VarConsole.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS></FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>WaterCannon.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
@@ -3230,6 +3489,20 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>WaterCreatures.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>WaterCreatures.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS></FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>WaterLevel.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
@@ -3258,6 +3531,20 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>WindModifiers.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>WindModifiers.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS></FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>ClumpRead.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
@@ -3587,6 +3874,13 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>Bike.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>Bike.h</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
@@ -3865,132 +4159,6 @@
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>mss32.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Library</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>d3d8.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Library</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>ddraw.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Library</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>dxguid.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Library</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>strmiids.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Library</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>dinput8.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Library</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>winmm.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Library</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>rwcore.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Library</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>rpworld.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Library</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>rpmatfx.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Library</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>rpskin.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Library</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>rphanim.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Library</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>rtbmp.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Library</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>rtquat.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Library</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>rtcharse.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Library</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>ole32.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Library</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>shell32.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Library</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>uuid.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Library</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
</FILELIST>
<LINKORDER>
<FILEREF>
@@ -4300,6 +4468,16 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>ColStore.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>ColStore.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>ColTriangle.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -4570,11 +4748,31 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>Script7.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>Script8.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>ScriptCommands.h</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>SetPieces.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>SetPieces.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>TrafficLights.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -4925,6 +5123,16 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>Ropes.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>Ropes.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>Stats.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -5150,16 +5358,6 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
- <PATH>MloModelInfo.cpp</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- </FILEREF>
- <FILEREF>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>MloModelInfo.h</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- </FILEREF>
- <FILEREF>
- <PATHTYPE>Name</PATHTYPE>
<PATH>ModelIndices.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -5220,17 +5418,12 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
- <PATH>XtraCompsModelInfo.h</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- </FILEREF>
- <FILEREF>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>CutsceneHead.cpp</PATH>
+ <PATH>WeaponModelInfo.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
- <PATH>CutsceneHead.h</PATH>
+ <PATH>WeaponModelInfo.h</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
<FILEREF>
@@ -5295,6 +5488,16 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>Stinger.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>Stinger.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>CivilianPed.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -5355,6 +5558,16 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>PedAttractor.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>PedAttractor.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>PedChat.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -5485,6 +5698,16 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>CutsceneShadow.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>CutsceneShadow.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>Draw.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -5565,6 +5788,16 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>Occlusion.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>Occlusion.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>Particle.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -5640,6 +5873,16 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>ShadowCamera.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>ShadowCamera.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>Shadows.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -5710,6 +5953,16 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>VarConsole.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>VarConsole.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>WaterCannon.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -5720,6 +5973,16 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>WaterCreatures.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>WaterCreatures.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>WaterLevel.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -5740,6 +6003,16 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>WindModifiers.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>WindModifiers.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>ClumpRead.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -5975,6 +6248,11 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>Bike.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>Bike.h</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -6250,17 +6528,12 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
- <PATH>ole32.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- </FILEREF>
- <FILEREF>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>shell32.lib</PATH>
+ <PATH>rtanim.lib</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
- <PATH>uuid.lib</PATH>
+ <PATH>rpanisot.lib</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
<FILEREF>
@@ -6288,6 +6561,21 @@
<PATH>User32.lib</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>ole32.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>shell32.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>uuid.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
</LINKORDER>
</TARGET>
<TARGET>
@@ -6960,7 +7248,7 @@
<SETTING><NAME>MWFrontEnd_C_useRTTI</NAME><VALUE>1</VALUE></SETTING>
<SETTING><NAME>MWFrontEnd_C_multibyteaware</NAME><VALUE>1</VALUE></SETTING>
<SETTING><NAME>MWFrontEnd_C_unsignedchars</NAME><VALUE>0</VALUE></SETTING>
- <SETTING><NAME>MWFrontEnd_C_autoinline</NAME><VALUE>0</VALUE></SETTING>
+ <SETTING><NAME>MWFrontEnd_C_autoinline</NAME><VALUE>1</VALUE></SETTING>
<SETTING><NAME>MWFrontEnd_C_booltruefalse</NAME><VALUE>1</VALUE></SETTING>
<SETTING><NAME>MWFrontEnd_C_direct_to_som</NAME><VALUE>0</VALUE></SETTING>
<SETTING><NAME>MWFrontEnd_C_som_env_check</NAME><VALUE>0</VALUE></SETTING>
@@ -6985,7 +7273,7 @@
<!-- Settings for "x86 Project" panel -->
<SETTING><NAME>MWProject_X86_type</NAME><VALUE>Application</VALUE></SETTING>
- <SETTING><NAME>MWProject_X86_outfile</NAME><VALUE>Release\gta3.exe</VALUE></SETTING>
+ <SETTING><NAME>MWProject_X86_outfile</NAME><VALUE>Release\gta-vc.exe</VALUE></SETTING>
<SETTING><NAME>MWProject_X86_baseaddress</NAME><VALUE>4194304</VALUE></SETTING>
<SETTING><NAME>MWProject_X86_maxstacksize</NAME><VALUE>1024</VALUE></SETTING>
<SETTING><NAME>MWProject_X86_minstacksize</NAME><VALUE>4</VALUE></SETTING>
@@ -7052,6 +7340,146 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>mss32.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>d3d8.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>ddraw.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>dxguid.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>strmiids.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>dinput8.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>winmm.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>rwcore.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>rpworld.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>rpmatfx.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>rpskin.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>rphanim.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>rtbmp.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>rtquat.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>rtcharse.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>ole32.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>shell32.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>uuid.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>rtanim.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>rpanisot.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Library</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>AnimationId.h</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
@@ -7479,6 +7907,20 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>ColStore.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>ColStore.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS></FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>ColTriangle.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
@@ -7857,6 +8299,20 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>Script7.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>Script8.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>ScriptCommands.h</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
@@ -7864,6 +8320,20 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>SetPieces.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>SetPieces.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS></FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>TrafficLights.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
@@ -8354,6 +8824,20 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>Ropes.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>Ropes.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS></FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>Stats.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
@@ -8669,20 +9153,6 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
- <PATH>MloModelInfo.cpp</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Text</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>MloModelInfo.h</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Text</FILEKIND>
- <FILEFLAGS></FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
<PATH>ModelIndices.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
@@ -8767,21 +9237,14 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
- <PATH>XtraCompsModelInfo.h</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Text</FILEKIND>
- <FILEFLAGS></FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>CutsceneHead.cpp</PATH>
+ <PATH>WeaponModelInfo.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
- <PATH>CutsceneHead.h</PATH>
+ <PATH>WeaponModelInfo.h</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
@@ -8872,6 +9335,20 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>Stinger.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>Stinger.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS></FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>CivilianPed.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
@@ -8956,6 +9433,20 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>PedAttractor.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>PedAttractor.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS></FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>PedChat.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
@@ -9138,6 +9629,20 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>CutsceneShadow.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>CutsceneShadow.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS></FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>Draw.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
@@ -9250,6 +9755,20 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>Occlusion.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>Occlusion.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS></FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>Particle.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
@@ -9355,6 +9874,20 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>ShadowCamera.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>ShadowCamera.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS></FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>Shadows.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
@@ -9453,6 +9986,20 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>VarConsole.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>VarConsole.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS></FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>WaterCannon.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
@@ -9467,6 +10014,20 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>WaterCreatures.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>WaterCreatures.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS></FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>WaterLevel.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
@@ -9495,6 +10056,20 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>WindModifiers.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>WindModifiers.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS></FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>ClumpRead.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
@@ -9824,6 +10399,13 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>Bike.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS>Debug</FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>Bike.h</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
@@ -10102,132 +10684,6 @@
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>mss32.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Library</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>d3d8.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Library</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>ddraw.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Library</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>dxguid.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Library</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>strmiids.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Library</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>dinput8.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Library</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>winmm.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Library</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>rwcore.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Library</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>rpworld.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Library</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>rpmatfx.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Library</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>rpskin.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Library</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>rphanim.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Library</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>rtbmp.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Library</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>rtquat.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Library</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>rtcharse.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Library</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>ole32.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Library</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>shell32.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Library</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>uuid.lib</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- <FILEKIND>Library</FILEKIND>
- <FILEFLAGS>Debug</FILEFLAGS>
- </FILE>
</FILELIST>
<LINKORDER>
<FILEREF>
@@ -10537,6 +10993,16 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>ColStore.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>ColStore.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>ColTriangle.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -10807,11 +11273,31 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>Script7.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>Script8.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>ScriptCommands.h</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>SetPieces.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>SetPieces.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>TrafficLights.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -11162,6 +11648,16 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>Ropes.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>Ropes.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>Stats.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -11387,16 +11883,6 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
- <PATH>MloModelInfo.cpp</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- </FILEREF>
- <FILEREF>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>MloModelInfo.h</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- </FILEREF>
- <FILEREF>
- <PATHTYPE>Name</PATHTYPE>
<PATH>ModelIndices.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -11457,17 +11943,12 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
- <PATH>XtraCompsModelInfo.h</PATH>
+ <PATH>WeaponModelInfo.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
- <PATH>CutsceneHead.cpp</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- </FILEREF>
- <FILEREF>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>CutsceneHead.h</PATH>
+ <PATH>WeaponModelInfo.h</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
<FILEREF>
@@ -11532,6 +12013,16 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>Stinger.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>Stinger.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>CivilianPed.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -11592,6 +12083,16 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>PedAttractor.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>PedAttractor.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>PedChat.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -11722,6 +12223,16 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>CutsceneShadow.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>CutsceneShadow.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>Draw.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -11802,6 +12313,16 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>Occlusion.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>Occlusion.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>Particle.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -11877,6 +12398,16 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>ShadowCamera.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>ShadowCamera.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>Shadows.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -11947,6 +12478,16 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>VarConsole.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>VarConsole.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>WaterCannon.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -11957,6 +12498,16 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>WaterCreatures.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>WaterCreatures.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>WaterLevel.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -11977,6 +12528,16 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>WindModifiers.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>WindModifiers.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>ClumpRead.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -12212,6 +12773,11 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>Bike.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>Bike.h</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -12487,6 +13053,16 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>rtanim.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>rpanisot.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>MSL_All_x86.lib</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
@@ -12755,13 +13331,13 @@
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
<FILEREF>
- <TARGETNAME>Release</TARGETNAME>
+ <TARGETNAME>Debug</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
<PATH>PolRadio.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
<FILEREF>
- <TARGETNAME>Release</TARGETNAME>
+ <TARGETNAME>Debug</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
<PATH>PolRadio.h</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
@@ -12911,6 +13487,18 @@
<FILEREF>
<TARGETNAME>Debug</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>ColStore.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <TARGETNAME>Debug</TARGETNAME>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>ColStore.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <TARGETNAME>Debug</TARGETNAME>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>ColTriangle.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -13237,12 +13825,36 @@
<FILEREF>
<TARGETNAME>Debug</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>Script7.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <TARGETNAME>Debug</TARGETNAME>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>Script8.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <TARGETNAME>Debug</TARGETNAME>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>ScriptCommands.h</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>Debug</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>SetPieces.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <TARGETNAME>Debug</TARGETNAME>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>SetPieces.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <TARGETNAME>Debug</TARGETNAME>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>TrafficLights.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -13665,6 +14277,18 @@
<FILEREF>
<TARGETNAME>Debug</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>Ropes.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <TARGETNAME>Debug</TARGETNAME>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>Ropes.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <TARGETNAME>Debug</TARGETNAME>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>Stats.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -13839,8 +14463,6 @@
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
</GROUP>
- <GROUP><NAME>extras</NAME>
- </GROUP>
<GROUP><NAME>math</NAME>
<FILEREF>
<TARGETNAME>Debug</TARGETNAME>
@@ -13943,18 +14565,6 @@
<FILEREF>
<TARGETNAME>Debug</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
- <PATH>MloModelInfo.cpp</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- </FILEREF>
- <FILEREF>
- <TARGETNAME>Debug</TARGETNAME>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>MloModelInfo.h</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- </FILEREF>
- <FILEREF>
- <TARGETNAME>Debug</TARGETNAME>
- <PATHTYPE>Name</PATHTYPE>
<PATH>ModelIndices.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -14027,23 +14637,17 @@
<FILEREF>
<TARGETNAME>Debug</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
- <PATH>XtraCompsModelInfo.h</PATH>
- <PATHFORMAT>Windows</PATHFORMAT>
- </FILEREF>
- </GROUP>
- <GROUP><NAME>objects</NAME>
- <FILEREF>
- <TARGETNAME>Debug</TARGETNAME>
- <PATHTYPE>Name</PATHTYPE>
- <PATH>CutsceneHead.cpp</PATH>
+ <PATH>WeaponModelInfo.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>Debug</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
- <PATH>CutsceneHead.h</PATH>
+ <PATH>WeaponModelInfo.h</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
+ </GROUP>
+ <GROUP><NAME>objects</NAME>
<FILEREF>
<TARGETNAME>Debug</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
@@ -14116,6 +14720,18 @@
<PATH>Projectile.h</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
+ <FILEREF>
+ <TARGETNAME>Debug</TARGETNAME>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>Stinger.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <TARGETNAME>Debug</TARGETNAME>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>Stinger.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
</GROUP>
<GROUP><NAME>peds</NAME>
<FILEREF>
@@ -14193,6 +14809,18 @@
<FILEREF>
<TARGETNAME>Debug</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>PedAttractor.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <TARGETNAME>Debug</TARGETNAME>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>PedAttractor.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <TARGETNAME>Debug</TARGETNAME>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>PedChat.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -14351,6 +14979,18 @@
<FILEREF>
<TARGETNAME>Debug</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>CutsceneShadow.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <TARGETNAME>Debug</TARGETNAME>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>CutsceneShadow.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <TARGETNAME>Debug</TARGETNAME>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>Draw.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -14447,6 +15087,18 @@
<FILEREF>
<TARGETNAME>Debug</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>Occlusion.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <TARGETNAME>Debug</TARGETNAME>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>Occlusion.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <TARGETNAME>Debug</TARGETNAME>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>Particle.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -14537,6 +15189,18 @@
<FILEREF>
<TARGETNAME>Debug</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>ShadowCamera.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <TARGETNAME>Debug</TARGETNAME>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>ShadowCamera.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <TARGETNAME>Debug</TARGETNAME>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>Shadows.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -14621,6 +15285,18 @@
<FILEREF>
<TARGETNAME>Debug</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>VarConsole.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <TARGETNAME>Debug</TARGETNAME>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>VarConsole.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <TARGETNAME>Debug</TARGETNAME>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>WaterCannon.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -14633,6 +15309,18 @@
<FILEREF>
<TARGETNAME>Debug</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>WaterCreatures.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <TARGETNAME>Debug</TARGETNAME>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>WaterCreatures.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <TARGETNAME>Debug</TARGETNAME>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>WaterLevel.cpp</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -14654,6 +15342,18 @@
<PATH>Weather.h</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
+ <FILEREF>
+ <TARGETNAME>Debug</TARGETNAME>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>WindModifiers.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <TARGETNAME>Debug</TARGETNAME>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>WindModifiers.h</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
</GROUP>
<GROUP><NAME>rw</NAME>
<FILEREF>
@@ -14949,6 +15649,12 @@
<FILEREF>
<TARGETNAME>Debug</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>Bike.cpp</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <TARGETNAME>Debug</TARGETNAME>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>Bike.h</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
@@ -15238,6 +15944,18 @@
<PATH>rtcharse.lib</PATH>
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
+ <FILEREF>
+ <TARGETNAME>Debug</TARGETNAME>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>rtanim.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <TARGETNAME>Debug</TARGETNAME>
+ <PATHTYPE>Name</PATHTYPE>
+ <PATH>rpanisot.lib</PATH>
+ <PATHFORMAT>Windows</PATHFORMAT>
+ </FILEREF>
</GROUP>
<GROUP><NAME>DirectX</NAME>
<FILEREF>
diff --git a/conanfile.py b/conanfile.py
index cabcc4c2..c5b74802 100644
--- a/conanfile.py
+++ b/conanfile.py
@@ -5,8 +5,8 @@ import shutil
import textwrap
-class Re3Conan(ConanFile):
- name = "re3"
+class ReVCConan(ConanFile):
+ name = "reVC"
version = "master"
license = "???" # FIXME: https://github.com/GTAmodding/re3/issues/794
settings = "os", "arch", "compiler", "build_type"
@@ -69,10 +69,10 @@ class Re3Conan(ConanFile):
raise ConanInvalidConfiguration("Only `glfw` is supported as gl3_gfxlib.")
#if not self.options.with_opus:
# if not self.options["libsndfile"].with_external_libs:
- # raise ConanInvalidConfiguration("re3 with opus support requires a libsndfile built with external libs (=ogg/flac/opus/vorbis)")
+ # raise ConanInvalidConfiguration("reVC with opus support requires a libsndfile built with external libs (=ogg/flac/opus/vorbis)")
@property
- def _re3_audio(self):
+ def _reVC_audio(self):
return {
"miles": "MSS",
"openal": "OAL",
@@ -111,16 +111,16 @@ class Re3Conan(ConanFile):
include("{}/conanbuildinfo.cmake")
conan_basic_setup(TARGETS NO_OUTPUT_DIRS)
- add_subdirectory("{}" re3)
+ add_subdirectory("{}" reVC)
""").format(self.install_folder.replace("\\", "/"),
self.source_folder.replace("\\", "/")))
except FileNotFoundError:
pass
cmake = CMake(self)
- cmake.definitions["RE3_AUDIO"] = self._re3_audio
- cmake.definitions["RE3_WITH_OPUS"] = self.options.with_opus
- cmake.definitions["RE3_INSTALL"] = True
- cmake.definitions["RE3_VENDORED_LIBRW"] = False
+ cmake.definitions["REVC_AUDIO"] = self._reVC_audio
+ cmake.definitions["REVC_WITH_OPUS"] = self.options.with_opus
+ cmake.definitions["REVC_INSTALL"] = True
+ cmake.definitions["REVC_VENDORED_LIBRW"] = False
env = {}
if self._os_is_playstation2:
cmake.definitions["CMAKE_TOOLCHAIN_FILE"] = self.deps_user_info["ps2dev-cmaketoolchain"].cmake_toolchain_file
diff --git a/gamefiles/TEXT/JAPANESE.gxt b/gamefiles/TEXT/JAPANESE.gxt
deleted file mode 100644
index d4b54383..00000000
--- a/gamefiles/TEXT/JAPANESE.gxt
+++ /dev/null
Binary files differ
diff --git a/gamefiles/TEXT/american.gxt b/gamefiles/TEXT/american.gxt
index d4034411..39895b0c 100644
--- a/gamefiles/TEXT/american.gxt
+++ b/gamefiles/TEXT/american.gxt
Binary files differ
diff --git a/gamefiles/TEXT/english.gxt b/gamefiles/TEXT/english.gxt
deleted file mode 100644
index 71a42d12..00000000
--- a/gamefiles/TEXT/english.gxt
+++ /dev/null
Binary files differ
diff --git a/gamefiles/TEXT/french.gxt b/gamefiles/TEXT/french.gxt
index 16c7a716..d2020651 100644
--- a/gamefiles/TEXT/french.gxt
+++ b/gamefiles/TEXT/french.gxt
Binary files differ
diff --git a/gamefiles/TEXT/german.gxt b/gamefiles/TEXT/german.gxt
index c3309d61..f96f87d5 100644
--- a/gamefiles/TEXT/german.gxt
+++ b/gamefiles/TEXT/german.gxt
Binary files differ
diff --git a/gamefiles/TEXT/italian.gxt b/gamefiles/TEXT/italian.gxt
index b30b74f4..407da68d 100644
--- a/gamefiles/TEXT/italian.gxt
+++ b/gamefiles/TEXT/italian.gxt
Binary files differ
diff --git a/gamefiles/TEXT/polish.gxt b/gamefiles/TEXT/polish.gxt
deleted file mode 100755
index d771427b..00000000
--- a/gamefiles/TEXT/polish.gxt
+++ /dev/null
Binary files differ
diff --git a/gamefiles/TEXT/russian.gxt b/gamefiles/TEXT/russian.gxt
index 0075c691..375323ba 100644
--- a/gamefiles/TEXT/russian.gxt
+++ b/gamefiles/TEXT/russian.gxt
Binary files differ
diff --git a/gamefiles/TEXT/spanish.gxt b/gamefiles/TEXT/spanish.gxt
index 8980eb4d..54773d07 100644
--- a/gamefiles/TEXT/spanish.gxt
+++ b/gamefiles/TEXT/spanish.gxt
Binary files differ
diff --git a/gamefiles/data/PARTICLE.CFG b/gamefiles/data/PARTICLE.CFG
deleted file mode 100644
index 8bb6d30b..00000000
--- a/gamefiles/data/PARTICLE.CFG
+++ /dev/null
@@ -1,363 +0,0 @@
-; Author: Alexander Roger
-; Date: 21/12/2000
-;
-; Author: Andrzej Madajczyk
-; Date: 26/02/2001
-; 14/03/2001 - Alpha (opacity) support added;
-; 10/05/2001 - Drag/Friction Decceleration changed to constants;
-; 28/08/2001 - Initial Color Variation added;
-;
-;
-;
-;
-; Note! Last line of the file MUST BE ";the end\n", otherwise you'll get parsing error(s) of the file;
-;
-;
-;
-;Particle Systems Configuration Data:: Format
-;
-;
-;A: Particle Type Name (max 20 chars)
-;
-;B/C/D: Render Colouring (r,g,b) (0-255)
-;
-;CV: Initial Color Variation (for r,g,b only, in %) (0-100);
-; (i.e. Color=(100,100,100) and CV=20, then v=random(-20,20), real_color=(100+v, 100+v, 100+v));
-;
-;
-;
-;B2/C2/D2: Fade Destination Color (r,g,b) (0-255)
-;
-;FT: Color Fade Time for (B,C,D)->(B2,C2,D2), (0 for none);
-;
-;
-;
-;
-;E: Default Initial Radius (float)
-;F: Expansion Rate (float)
-;
-;
-; Color "Fade-to-Black" options:
-;G: Initial Intensity (0-255)
-;H: Fade Time (time between fade steps in frames)
-;I: Fade Amount (-255 to 255) can get brighter or dimmer
-;
-; "Fade Alpha" options:
-;GA: Initial Intensity (0-255)
-;HA: Fade Time (time between fade steps in frames)
-;IA: Fade Amount
-;
-; "Z Rotation" options:
-;GZA: Initial Angle (0-1023)
-;HZA: Change Time (time between steps in frames)
-;IZA: Angle Change Amount
-;
-;GZR: Initial Z Radius
-;HZR: Change Time (time between steps in frames)
-;IZR: Z Radius Change Amount
-;
-;
-;J: Animation Speed (0=no animation)(time between steps msec)
-;K: Start Animation Frame ( 0 -> )
-;L: Final Animation Frame ( H -> )
-;
-;
-;M: Rotation Speed (0=None,i-deg/frame)
-;N: Gravitational Acceleration (0=none, float)
-;O: Drag/Friction Decceleration (int: 0=none, 50=0.50, 80=0.80, 90=0.90, 95=0.95, 96=0.96, 99=0.99)
-;
-;P: Default Life-Span of Particle (msec)
-;
-;Q: Position Random Error [position += (+/-)rand(a)]
-;R: Velocity Random Error [velocity += (+/-)rand(b)]
-;S: Expansion Rate Error [exp_rate += (+)rand(c)]
-;T: Rotation Rate Error [rot_speed = (+/-)rand(d)]
-;U: Life-Span Error Shape [shape distribution, e=0->all at default, e->Inf then shape->0] (max=255!!)
-;V: Trail Length Multiplier [length *= (float) multiplier] (only used if trail flag active)
-;
-;CR:Particle Create Range (in meters: 0=no check); if particles are created enough far away from camera, they are deleted (not added to particle system);
-;
-;
-;Z: Flags! Guide: 1=ZCHECK_FIRST, 2=ZCHECK_STEP, 4=DRAW_OPAQUE, 8=SCREEN_TRAIL,
-; 16=SPEED_TRAIL, 32=RAND_VERT_V, 64=CYCLE_ANIM, 128=DRAW_DARK, 256=VERT_TRAIL
-; 1024=DRAWTOP2D, 2048=CLIPOUT2D
-; 4096=ZCHECK_BUMP, 8192=ZCHECK_BUMP_FIRST
-;
-;
-;
-;default:
-;GUNFLASH 255 255 255 0 0.1 0.0 255 0 128 0 0 0 0 0.0 1.0 250 0.0 0.0 0.0 0 0 1.0 0
-;
-;good idea for fire-smudge?
-;GUNFLASH 255 255 255 0 1.0 0.0 255 0 32 100 0 3 0 0.0 1.0 400 0.0 0.0 0.0 0 0 1.0 0
-;
-;current:
-;GUNFLASH 255 255 255 0 1.0 0.0 255 0 32 100 0 3 0 0.0 1.0 400 0.0 0.0 0.0 0 0 1.0 0
-;
-;
-;SPARK_SMALL 255 255 128 0 0.005 0.0 255 0 0 0 0 0 0 0.0 1.0 500 0.0 0.05 0.0 0 0 0.5 40
-;
-;
-;
-;
-;
-;
-;
-; A B C D CV B2 C2 D2 FT E F G H I GA HA IA GZA HZA IZA GZR HZR IZR J K L M N O P Q R S T U V CR Z
-;
-SPARK 255 128 64 0 0 0 0 0 0.005 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.001 1 300 0.0 0.07 0.0 0 0 1.0 20.0 48
-SPARK_SMALL 255 255 128 0 0 0 0 0 0.005 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.001 1 500 0.0 0.05 0.0 0 0 0.6 20.0 40
-;
-WHEEL_DIRT 8 24 8 0 0 0 0 0 0.05 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.002 1 1000 0.15 0.015 0.0 0 0 1.0 30.0 4
-;
-;
-;WHEEL_WATER 24 24 24 0 0 0 0 0 0.05 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.002 1 1000 0.15 0.015 0.0 0 0 1.0 20.0 0
-WHEEL_WATER 24 24 32 0 0 0 0 0 0.05 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.004 1 1000 0.15 0.015 0.0 0 0 1.0 20.0 1
-;
-;
-BLOOD 128 128 128 0 0 0 0 0 0.02 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.03 1 2000 0.3 0.05 0.0 0 0 1.0 50.0 5
-BLOOD_SMALL 255 32 32 0 0 0 0 0 0.007 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.005 1 2000 0.05 0.05 0.0 0 0 1.0 50.0 53
-;BLOOD_SPLAT 128 128 128 0 0 0 0 0 0.1 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 200 0.3 0.0 0.0 0 0 1.0 400.0 36
-BLOOD_SPURT 255 32 32 0 0 0 0 0 0.008 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.005 1 2000 0.0 0.01 0.0 0 0 2.0 50.0 52
-DEBRIS 64 64 64 0 0 0 0 0 0.5 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.01 95 1000 0.2 0.0 0.0 0 0 1.0 50.0 4
-DEBRIS2 64 64 64 0 0 0 0 0 0.04 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 5 0.01 99 1000 0.03 0.04 0.0 0 0 1.0 50.0 38
-WATER 64 64 128 0 0 0 0 0 0.01 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 2000 0.0 0.0 0.0 0 0 1.0 100.0 0
-;
-;
-;FLAME 255 74 30 0 0 0 0 0 0.2 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 32 0 4 0 0.0 1 100 0.05 0.0 0.0 0 0 1.0 400.0 0
-;FLAME 255 74 30 0 0 255 0 400 0.8 -0.02 255 0 10 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 -0.005 1 2000 0.02 0.01 0.01 0 0 1.0 200.0 0
-FLAME 255 74 30 0 0 0 0 0 0.8 -0.02 255 0 10 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 -0.005 1 2000 0.02 0.01 0.01 0 0 1.0 200.0 0
-;
-;
-;
-;FIREBALL 255 74 30 0 0 0 0 0 0.1 0.04 255 1 8 255 0 0 0 0 0 0.0 0 0.0 32 0 7 0 0.0 96 1000 0.1 0.0 0.0 0 0 1.0 400.0 0
-;
-;FIREBALL 255 74 30 0 0 0 0 0 0.1 0.05 255 0 6 255 0 0 0 0 0 0.0 0 0.0 1 0 7 0 -0.002 96 2000 0.1 0.02 0.02 3 0 1.0 200.0 0
-FIREBALL 255 74 30 0 0 0 0 0 0.1 0.02 255 0 6 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 -0.003 96 2000 0.1 0.03 0.014 2.5 0 1.0 200.0 0
-;
-;
-;
-GUNFLASH 170 170 170 0 0 0 0 0 0.1 0.0 255 1 50 255 0 0 0 0 0 0.0 0 0.0 51 0 3 0 0.0 1 250 0.0 0.0 0.0 0 0 1.0 35.0 0
-GUNFLASH_NOANIM 128 128 128 0 0 0 0 0 0.1 0.0 255 1 128 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 25 0.0 0.0 0.0 0 0 1.0 35.0 0
-;
-GUNSMOKE 64 64 64 0 0 0 0 0 0.15 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 2 0 7 0 -0.002 95 1000 0.0 0.0 0.0 0 0 1.0 60.0 0
-GUNSMOKE2 255 255 255 0 0 0 0 0 0.05 0.02 255 0 0 255 0 8 0 0 0 0.0 0 0.0 0 0 3 4 -0.001 80 1400 0.05 0.05 0.01 3 0 1.0 60.0 4
-;
-;
-SMOKE 32 32 32 0 0 0 0 0 0.15 0.015 255 5 25 255 0 0 0 0 0 0.0 0 0.0 32 0 4 0 -0.01 95 1000 0.05 0.05 0.01 3 0 1.0 150.0 0
-;SMOKE_SLOWMOTION 32 32 32 0 0 0 0 0 0.15 0.015 255 5 15 255 0 0 0 0 0 0.0 0 0.0 32 0 4 0 -0.003 95 1000 0.05 0.05 0.01 3 0 1.0 400.0 0
-SMOKE_SLOWMOTION 32 32 32 0 0 0 0 0 0.15 0.015 128 5 11 255 0 0 0 0 0 0.0 0 0.0 32 0 4 0 -0.003 95 3000 0.05 0.05 0.01 3 0 1.0 150.0 0
-;
-;
-;
-;GARAGEPAINT_SPRAY 32 32 32 0 0 0 0 0 0.15 0.015 255 0 5 255 0 0 0 0 0 0.0 0 0.0 0 0 4 0 -0.001 95 2000 0.05 0.05 0.01 3 0 1.0 400.0 0
-GARAGEPAINT_SPRAY 32 32 32 0 0 0 0 0 0.15 0.015 255 0 5 255 0 0 0 0 0 0.0 0 0.0 0 0 4 0 -0.0005 95 4000 0.05 0.05 0.01 3 0 1.0 100.0 0
-SHARD 255 255 255 0 0 0 0 0 0.03 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 96 300 0.0 0.0 0.0 0 0 1.0 100.0 0
-SPLASH 64 64 128 0 0 0 0 0 0.1 0.007 255 1 10 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 1000 0.0 0.0 0.0 0 0 1.0 100.0 0
-;BLOOD_SPLASH 24 64 0 0 0 0 0 0 0.1 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 96 300 0.0 0.0 0.0 0 0 1.0 100.0 0
-;
-;
-;CARFLAME 255 74 30 0 0 0 0 0 0.5 0.04 255 2 20 255 0 0 0 0 0 0.0 0 0.0 32 0 4 0 0.0 1 1000 0.4 0.0 0.0 0 0 1.0 400.0 64
-;CARFLAME 255 74 30 0 0 0 0 0 0.8 -0.02 255 0 10 255 0 0 0 0 0 0.0 0 0.0 32 0 4 0 -0.001 1 2000 0.4 0.01 0.01 0 0 1.0 400.0 64
-;CARFLAME 255 74 30 0 0 0 0 0 0.8 -0.02 255 0 10 255 0 0 0 0 0 0.0 0 0.0 32 0 4 0 -0.001 1 2000 0.4 0.01 0.01 0 0 1.0 400.0 64
-;
-CARFLAME 255 74 30 0 0 0 0 0 0.8 -0.02 255 0 10 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 -0.005 1 2000 0.02 0.01 0.01 0 0 1.0 100.0 0
-;
-;
-STEAM 64 64 64 0 0 0 0 0 0.5 0.05 255 1 16 255 0 0 0 0 0 0.0 0 0.0 32 0 4 0 -0.005 95 2000 0.01 0.03 0.0 0 0 1.0 85.0 0
-;
-;default:
-;STEAM2 255 255 255 0 0 0 0 0 0.5 0.05 255 0 0 128 2 8 0 0 0 0.0 0 0.0 32 0 4 0 -0.005 95 2000 0.01 0.03 0.0 0 0 1.0 400.0 4
-STEAM2 255 255 255 0 0 0 0 0 0.5 0.015 255 0 0 192 0 1 0 0 10 0.5 1 0.02 32 0 4 0 -0.002 95 8000 0.01 0.03 0.0 0 0 1.0 85.0 4
-;
-;
-;STEAM_NY 255 255 255 0 0 0 0 0 0.5 0.05 255 0 0 128 2 8 0 0 0 0.0 0 0.0 32 0 4 0 -0.005 95 2000 0.01 0.03 0.0 0 0 1.0 400.0 4
-STEAM_NY 255 255 255 0 0 0 0 0 0.5 0.05 255 0 0 96 2 8 0 0 0 0.0 0 0.0 32 0 4 0 -0.005 95 1400 0.01 0.03 0.0 0 0 1.0 85.0 4
-STEAM_NY_SLOWMOTION 255 255 255 0 0 0 0 0 0.5 0.05 255 0 0 96 2 8 0 0 0 0.0 0 0.0 32 0 4 0 -0.0015 95 1400 0.01 0.03 0.0 0 0 1.0 85.0 4
-;
-;
-;ENGINE_STEAM 210 210 210 0 0 0 0 0 0.5 0.05 255 0 0 192 2 16 0 0 0 0.0 0 0.0 32 0 4 0 -0.005 95 2000 0.01 0.03 0.0 0 0 1.0 250.0 4
-ENGINE_STEAM 210 210 210 0 0 0 0 0 0.5 0.05 255 0 0 192 0 10 0 0 0 0.0 0 0.0 32 0 4 1 -0.005 95 4000 0.03 0.03 0.02 0 0 1.0 85.0 4
-;
-;
-;RAINDROP 32 32 32 0 0 0 0 0 0.6 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.025 1 1000 0.0 0.0 0.0 0 0 1.0 15.0 1
-RAINDROP 64 64 64 0 0 0 0 0 0.4 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 3 0 0.05 1 1000 0.0 0.0 0.0 0 0 1.0 15.0 1
-RAINDROP_SMALL 16 16 16 0 0 0 0 0 0.3 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.05 1 1000 0.0 0.0 0.0 0 0 1.0 15.0 1
-RAIN_SPLASH 32 32 32 0 0 0 0 0 0.08 0.0 255 0 5 255 0 0 0 0 0 0.0 0 0.0 1 0 4 0 0.0 1 500 0.0 0.0 0.0 0 0 1.0 15.0 0
-RAIN_SPLASH_BIGGROW 128 128 128 0 0 0 0 0 0.5 0.06 255 0 2 255 0 0 0 0 0 0.0 0 0.0 2 1 4 0 0.0 1 5500 0.0 0.0 0.0 0 0 1.0 15.0 0
-RAIN_SPLASHUP 48 48 48 0 0 0 0 0 0.1 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 1 0 0.0 1 50 0.0 0.0 0.0 0 0 1.0 15.0 0
-;
-WATERSPRAY 64 64 64 0 0 0 0 0 0.2 0.0 255 0 25 255 0 0 0 0 0 0.0 0 0.0 3 0 2 0 0.002 1 800 0.05 0.0 0.01 0 0 1.0 20.0 0
-;
-;
-;
-;EXPLOSION_MEDIUM 80 80 80 0 0 0 0 0 0.6 0.04 255 5 8 255 0 0 0 0 0 0.0 0 0.0 8 0 11 0 0.0 96 15000 0.2 0.0 0.0 3 0 1.0 400.0 0
-;EXPLOSION_LARGE 80 80 80 0 0 0 0 0 1.1 0.04 255 5 8 255 0 0 0 0 0 0.0 0 0.0 8 0 11 0 0.0 96 15000 0.8 0.0 0.0 3 0 1.0 400.0 0
-;EXPLOSION_MEDIUM 80 80 80 0 0 0 0 0 0.6 0.04 255 1 4 255 0 0 0 0 0 0.0 0 0.0 1 0 11 0 0.0 96 7000 0.2 0.0 0.0 0 0 1.0 400.0 0
-;EXPLOSION_LARGE 80 80 80 0 0 0 0 0 1.1 0.04 255 1 4 255 0 0 0 0 0 0.0 0 0.0 1 0 11 0 0.0 96 7000 0.8 0.0 0.0 0 0 1.0 400.0 0
-;
-;EXPLOSION_MEDIUM 80 80 80 0 0 0 0 0 0.6 0.04 255 0 3 255 0 0 0 0 0 0.0 0 0.0 1 0 11 0 -0.001 96 6000 0.2 0.0 0.0 0 0 1.0 400.0 0
-;EXPLOSION_LARGE 80 80 80 0 0 0 0 0 1.1 0.04 255 0 3 255 0 0 0 0 0 0.0 0 0.0 1 0 11 0 -0.001 96 6000 0.8 0.0 0.0 0 0 1.0 400.0 0
-EXPLOSION_MEDIUM 80 80 80 0 0 0 0 0 0.6 0.04 255 0 3 255 0 0 0 0 0 0.0 0 0.0 2 0 5 0 -0.001 96 6000 0.2 0.0 0.0 0 0 1.0 200.0 0
-EXPLOSION_LARGE 80 80 80 0 0 0 0 0 1.1 0.04 255 0 3 255 0 0 0 0 0 0.0 0 0.0 2 0 5 0 -0.001 96 6000 0.8 0.0 0.0 0 0 1.0 200.0 0
-EXPLOSION_MFAST 80 80 80 0 0 0 0 0 0.6 0.04 255 0 6 255 0 0 0 0 0 0.0 0 0.0 2 0 5 0 -0.001 96 3500 0.2 0.0 0.0 0 0 1.0 200.0 0
-EXPLOSION_LFAST 80 80 80 0 0 0 0 0 1.1 0.04 255 0 6 255 0 0 0 0 0 0.0 0 0.0 2 0 5 0 -0.001 96 3500 0.8 0.0 0.0 0 0 1.0 200.0 0
-;
-;
-;
-;
-;BOAT_SPLASH 32 64 32 0 0 0 0 0 0.2 0.2 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.01 1 2000 0.0 0.0 0.0 0 0 1.0 200.0 0
-;BOAT_THRUSTJET 24 32 24 0 0 0 0 0 0.5 0.1 255 0 0 255 0 0 0 0 0 0.0 0 0.0 250 0 4 0 0.01 50 1000 0.0 0.0 0.0 0 4 1.0 200.0 8
-;BOAT_SPLASH 16 32 32 0 0 0 0 0 0.2 0.2 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.01 1 2000 0.0 0.0 0.0 0 0 1.0 200.0 0
-;BOAT_THRUSTJET 8 24 24 0 0 0 0 0 0.5 0.1 255 0 0 255 0 0 0 0 0 0.0 0 0.0 250 0 4 0 0.01 50 1000 0.0 0.0 0.0 0 4 1.0 200.0 8
-;CAR_SPLASH 64 64 64 0 0 0 0 0 2.0 0.25 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.02 1 2000 0.0 0.0 0.0 0 0 1.0 250.0 0
-;CAR_SPLASH 64 64 64 0 0 0 0 0 2.0 0.25 255 0 0 200 0 8 0 0 0 0.0 0 0.0 0 0 0 0 0.04 1 2000 0.0 0.0 0.0 0 0 1.0 150.0 4
-;CAR_SPLASH 64 64 64 0 0 0 0 0 2.0 0.35 255 0 0 200 0 8 0 0 0 0.0 0 0.0 0 0 0 0 0.05 1 2000 0.0 0.0 0.0 0 0 1.0 150.0 4
-;CAR_SPLASH 64 64 64 0 0 0 0 0 1.0 0.25 255 0 0 180 0 5 0 0 0 0.0 0 0.0 2 1 3 0 0.05 1 1000 0.0 0.0 0.0 0 0 1.0 150.0 12
-;
-;
-;CAR_SPLASH 64 64 64 0 0 0 0 0 1.0 0.15 255 0 0 180 0 2 0 0 0 0.0 0 0.0 2 0 3 0 0.02 1 2000 0.0 0.0 0.0 0 0 1.0 150.0 12
-;CAR_SPLASH 48 48 64 0 0 0 0 0 1.0 0.15 96 0 0 255 0 0 0 0 0 0.0 0 0.0 6 0 2 0 0.01 1 2000 0.5 0.04 0.0 0 0 2.0 150.0 288
-;CAR_SPLASH 48 48 64 0 0 0 0 0 1.0 0.05 96 0 0 255 0 0 0 0 0 0.0 0 0.0 0 1 2 0 0.01 1 2000 0.5 0.04 0.0 0 0 2.0 150.0 288
-; A B C D CV B2 C2 D2 FT E F G H I GA HA IA GZA HZA IZA GZR HZR IZR J K L M N O P Q R S T U V CR Z
-CAR_SPLASH 48 48 60 0 0 0 0 0 1.0 0.00 128 1 4 128 0 0 0 0 0 0.0 0 0.0 0 0 2 0 0.01 1 2000 0.5 0.04 0.0 0 0 1.4 150.0 272
-;
-;
-;
-;BOAT_SPLASH 70 70 70 0 0 0 0 0 0.2 0.2 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.01 1 1000 0.0 0.0 0.0 0 0 1.0 150.0 0
-BOAT_SPLASH 64 64 64 0 0 0 0 0 0.2 0.2 255 0 2 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.01 1 1000 0.0 0.0 0.0 0 0 1.0 150.0 0
-;
-;
-;BOAT_THRUSTJET 90 90 90 0 0 0 0 0 1.8 0.1 255 0 0 120 0 1 0 0 0 0.0 0 0.0 0 1 4 0 0.01 50 1600 0.8 0.4 0.02 0 4 1.0 150.0 4
-BOAT_THRUSTJET 90 90 90 0 0 0 0 0 1.4 0.06 255 0 0 96 0 1 0 0 0 0.0 0 0.0 0 1 4 0 0.01 50 1600 0.8 0.4 0.02 0 4 1.0 150.0 4
-;
-;
-;BOAT_WAKE 255 255 255 0 0 0 0 0 2.0 0.2 255 0 0 128 0 1 0 0 0 0.0 0 0.0 0 0 0 0 0.03 50 1600 0.8 0.4 0.02 0 4 1.0 150.0 4
-BOAT_WAKE 255 255 255 0 0 0 0 0 1.5 0.45 255 0 0 192 0 2 0 0 0 0.0 0 0.0 0 0 0 0 0.0 50 1600 0.8 0.4 0.02 0 4 1.0 150.0 4
-;
-;
-;
-;
-;
-; A B C D CV B2 C2 D2 FT E F G H I GA HA IA GZA HZA IZA GZR HZR IZR J K L M N O P Q R S T U V CR Z
-WATER_HYDRANT 64 64 64 0 0 0 0 0 0.8 0.01 255 1 16 255 1 16 0 0 0 0.0 0 0.0 0 0 2 0 0.007 99 500 0.02 0.08 0.0 0 4 1.0 85.0 16
-WATER_CANNON 64 64 128 0 0 0 0 0 0.03 0.03 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 1000 0.0 0.0 0.0 0 0 1.0 85.0 0
-EXTINGUISH_STEAM 32 32 32 0 0 0 0 0 0.1 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 1000 0.0 0.0 0.0 0 0 1.0 85.0 0
-;
-;
-;
-;PED_SPLASH 32 32 64 0 0 0 0 0 0.1 0.05 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 1000 0.0 0.0 0.0 0 0 1.0 85.0 0
-PED_SPLASH 48 48 60 0 0 0 0 0 0.1 0.06 96 0 0 255 0 0 0 0 0 0.0 0 0.0 0 1 2 0 0.01 1 2000 0.5 0.04 0.0 0 0 1.4 50.0 256
-;
-;
-PEDFOOT_DUST 170 166 150 0 0 0 0 0 0.01 0.015 255 0 0 63 0 4 0 0 0 0.0 0 0.0 0 0 0 0 -0.0005 1 1000 0.0 0.0 0.0 0 0 1.0 6.0 4
-;
-HELI_DUST 17 15 9 0 0 0 0 0 0.2 0.1 255 1 8 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 -0.001 1 1000 0.2 0.05 0.0 0 0 1.0 85.0 0
-HELI_ATTACK 255 255 128 0 0 0 0 0 0.01 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 500 0.0 0.0 0.0 0 0 0.5 85.0 10
-;
-;
-;ENGINE_SMOKE 16 16 16 0 0 0 0 0 0.5 0.04 255 0 0 63 0 0 0 0 0 0.0 0 0.0 0 0 0 0 -0.005 95 2000 0.01 0.03 0.0 0 0 1.0 150.0 4
-;ENGINE_SMOKE2 8 8 8 0 0 0 0 0 1.0 0.2 128 2 4 63 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.001 1 1000 0.0 0.0 0.0 0 3 1.0 150.0 4
-ENGINE_SMOKE 16 16 16 0 0 0 0 0 0.5 0.04 255 0 0 52 0 2 10 0 80 0.0 0 0.0 0 0 5 2 -0.009 95 2000 0.11 0.03 0.01 1 0 1.0 85.0 4
-ENGINE_SMOKE2 9 9 9 80 0 0 0 0 1.0 0.06 128 0 1 140 0 5 10 0 80 0.0 0 0.0 0 0 0 2 0.002 1 1300 0.0 0.01 0.0 3 3 1.0 85.0 4
-;
-;
-CARFLAME_SMOKE 32 32 32 0 0 0 0 0 0.05 0.01 255 0 0 64 0 2 0 0 0 0.0 0 0.0 0 0 0 0 -0.008 95 2000 0.01 0.03 0.01 0 0 1.0 85.0 4
-FIREBALL_SMOKE 32 32 32 0 0 0 0 0 0.05 0.03 255 0 0 128 0 2 0 0 0 0.0 0 0.0 0 0 0 0 -0.004 95 2000 0.01 0.03 0.01 0 0 1.0 85.0 4
-;
-PAINT_SMOKE 255 0 0 0 0 0 0 0 0.1 0.01 255 1 8 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 95 3000 0.0 0.005 0.0 0 0 1.0 85.0 0
-TREE_LEAVES 64 64 64 0 0 0 0 0 0.2 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 1000 0.0 0.0 0.0 0 0 1.0 85.0 0
-;
-;
-;CARCOLLISION_DUST 224 224 224 0 0 0 0 0 0.15 0.04 255 0 0 127 1 8 0 0 0 0.0 0 0.0 0 0 0 0 -0.002 90 2000 0.02 0.02 0.0 0 0 1.0 80.0 4
-CARCOLLISION_DUST 76 76 76 0 0 0 0 0 0.10 0.02 255 0 0 160 0 4 0 0 0 0.0 0 0.0 0 0 0 0 -0.0015 90 2000 0.02 0.02 0.0 0 0 1.0 30.0 4
-;
-;
-CAR_DEBRIS 32 32 32 0 0 0 0 0 0.5 0.0 224 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 4 0 0.010 90 1000 0.02 0.02 0.0 0 0 1.0 50.0 4
-HELI_DEBRIS 32 32 32 0 0 0 0 0 1.5 0.0 224 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 4 0 0.065 90 1500 0.02 0.02 0.0 0 0 1.0 150.0 4
-;
-;
-;
-;EXHAUST_FUMES 80 80 80 0 0 0 0 0 0.03 0.03 255 0 0 122 0 4 0 0 0 0.0 0 0.0 2 0 4 0 -0.001 95 1500 0.01 0.03 0.0 0 0 1.0 50.0 4
-EXHAUST_FUMES 98 98 108 0 0 0 0 0 0.03 0.06 255 0 0 152 0 12 0 0 0 0.0 0 0.0 2 0 4 0 -0.002 96 1000 0.01 0.03 0.0 0 0 1.0 25.0 4
-;
-;
-;RUBBER 40 40 40 0 0 0 0 0 0.4 0.005 255 21 20 255 0 0 0 0 0 0.0 0 0.0 3 0 4 0 -0.0005 1 1000 0.02 0.0 0.0 0 0 1.0 400.0 4
-RUBBER_SMOKE 255 255 255 0 0 0 0 0 0.4 0.005 255 0 0 127 1 8 0 0 0 0.0 0 0.0 3 0 4 0 -0.0005 1 1000 0.02 0.0 0.0 0 0 1.0 50.0 4
-;BURNINGRUBBER_SMOKE128 128 128 0 0 0 0 0 0.35 0.06 255 0 0 192 1 6 0 0 0 0.0 0 0.0 0 0 0 0 -0.002 90 4000 0.02 0.02 0.0 0 0 1.0 400.0 4
-BURNINGRUBBER_SMOKE 128 128 128 0 0 0 0 0 0.35 0.06 255 0 0 128 0 4 0 0 0 0.0 0 0.0 0 0 0 0 -0.002 90 2000 0.02 0.02 0.0 0 0 1.0 50.0 4
-;
-;
-BULLETHIT_SMOKE 192 192 192 0 0 0 0 0 0.15 0.03 70 0 2 255 1 10 0 0 0 0.0 0 0.0 0 0 0 0 -0.001 90 2000 0.04 0.02 0.0 0 0 1.0 150.0 0
-;
-;
-GUNSHELL_FIRST 108 108 108 0 0 0 0 0 0.015 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 4 0 0.010 90 1000 0.02 0.02 0.0 0 0 1.0 0.0 12292
-GUNSHELL 108 108 108 0 0 0 0 0 0.015 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 4 0 0.010 90 1000 0.02 0.02 0.0 0 0 1.0 12.0 4100
-GUNSHELL_BUMP1 108 108 108 0 0 0 0 0 0.015 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 4 0 0.010 90 1000 0.02 0.02 0.0 0 0 1.0 8.0 4100
-GUNSHELL_BUMP2 108 108 108 0 0 0 0 0 0.015 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 4 0 0.010 90 400 0.02 0.02 0.0 0 0 1.0 8.0 4100
-;
-;
-TEST 255 64 64 0 0 0 0 0 0.2 0.025 255 1 20 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 3000 0.0 0.0 0.0 0 0 1.0 400.0 128
-;
-;
-;Particles with flag DRAWTOP2D should be placed last and VR (Visibility Range) set to 0!
-;
-;BIRD_FRONT 8 8 8 0 0 0 0 0 0.05 0.0 255 0 0 255 2 1 0 0 0 0.0 0 0.0 1 0 3 0 0.0 1 10000 0.0 0.0 0.0 0 0 1.0 0.0 3140
-BIRD_FRONT 8 8 8 0 0 0 0 0 1.05 0.0 255 0 0 255 2 2 0 0 0 0.0 0 0.0 1 0 3 0 0.0 1 8000 0.0 0.0 0.0 0 0 1.0 0.0 68
-;
-RAINDROP_2D 32 32 32 0 0 0 0 0 0.5 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 1 0 0 0.0 1 1000 0.0 0.0 0.0 0 0 1.0 0.0 3072
-;
-;
-;
-;
-;
-;
-;
-;
-;
-;
-;
-;
-; below is just backup of above values:
-;
-;SPARK 255 128 64 0.005 0.0 255 0 0 0 0 0 0 0.0 1.0 300 0.0 0.07 0.0 0 0 1.0 48
-;SPARK_SMALL 255 255 128 0.005 0.0 255 0 0 0 0 0 0 0.0 1.0 500 0.0 0.05 0.0 0 0 0.6 40
-;BLOOD 128 128 128 0.02 0.0 255 0 0 0 0 0 0 0.03 1.0 2000 0.3 0.05 0.0 0 0 1.0 6
-;BLOOD_SMALL 255 32 32 0.007 0.0 255 0 0 0 0 0 0 0.005 1.0 2000 0.05 0.05 0.0 0 0 1.0 54
-;BLOOD_SPLAT 128 128 128 0.1 0.0 255 0 0 0 0 0 0 0.0 1.0 200 0.3 0.0 0.0 0 0 1.0 36
-;BLOOD_SPURT 255 32 32 0.008 0.0 255 0 0 0 0 0 0 0.005 1.0 2000 0.0 0.01 0.0 0 0 2.0 52
-;DEBRIS 64 64 64 0.5 0.0 255 0 0 0 0 0 0 0.01 0.95 1000 0.2 0.0 0.0 0 0 1.0 4
-;DEBRIS2 64 64 64 0.04 0.0 255 0 0 0 0 0 5 0.01 0.99 1000 0.03 0.04 0.0 0 0 1.0 38
-;WATER 64 64 128 0.01 0.0 255 0 0 0 0 0 0 0.0 1.0 2000 0.0 0.0 0.0 0 0 1.0 0
-;FLAME 255 74 30 0.2 0.0 255 0 0 31 0 5 0 0.0 1.0 100 0.05 0.0 0.0 0 0 1.0 0
-;FIREBALL 255 74 30 0.1 0.04 255 0 8 31 0 8 0 0.0 0.96 1000 0.1 0.0 0.0 0 0 1.0 0
-;GUNFLASH 255 255 255 0.1 0.0 255 0 50 50 0 3 0 0.0 1.0 250 0.0 0.0 0.0 0 0 1.0 0
-;GUNFLASHSTATIC 255 255 255 0.1 0.0 255 0 128 0 0 0 0 0.0 1.0 25 0.0 0.0 0.0 0 0 1.0 0
-;SMOKE 32 32 32 0.15 0.015 255 4 25 31 0 5 0 -0.01 0.95 1000 0.05 0.05 0.01 3 0 1.0 0
-;SHARD 255 255 255 0.03 0.0 255 0 0 0 0 0 0 0.0 0.96 300 0.0 0.0 0.0 0 0 1.0 0
-;SPLASH 64 64 128 0.1 0.007 255 0 10 0 0 0 0 0.0 1.0 1000 0.0 0.0 0.0 0 0 1.0 0
-;BLOOD_SPLASH 24 64 0 0.1 0.0 255 0 0 0 0 0 0 0.0 0.96 300 0.0 0.0 0.0 0 0 1.0 0
-;RUBBER 40 40 40 0.4 0.005 255 1 25 31 0 5 0 0.0 1.0 1000 0.02 0.0 0.0 0 0 1.0 0
-;CARFLAME 255 74 30 0.5 0.04 255 1 20 31 0 5 0 0.0 1.0 1000 0.4 0.0 0.0 0 0 1.0 64
-;STEAM 64 64 64 0.5 0.05 255 0 16 31 0 5 0 -0.005 0.95 2000 0.01 0.03 0.0 0 0 1.0 0
-;RAINDROP 32 32 32 0.6 0.0 255 0 0 0 0 0 0 0.1 1.0 1000 0.0 0.0 0.0 0 0 1.0 1
-;RAIN_SPLASH 32 32 32 0.08 0.0 255 0 0 1 0 4 0 0.0 1.0 1000 0.0 0.0 0.0 0 0 1.0 0
-;RAINDROP_SMALL 32 32 32 0.3 0.0 255 0 0 0 0 0 0 0.1 1.0 1000 0.0 0.0 0.0 0 0 1.0 1
-;EXPLOSION_MEDIUM 80 80 80 0.6 0.04 255 4 8 7 0 11 0 0.0 0.96 30000 0.2 0.0 0.0 3 0 1.0 0
-;EXPLOSION_LARGE 80 80 80 1.1 0.04 255 4 8 7 0 11 0 0.0 0.96 30000 0.8 0.0 0.0 3 0 1.0 0
-;BOAT_SPLASH 32 64 32 0.2 0.2 255 0 0 0 0 0 0 0.01 1.0 2000 0.0 0.0 0.0 0 0 1.0 0
-;BOAT_THRUSTJET 24 32 24 0.5 0.1 255 0 0 250 0 5 0 0.01 0.5 1000 0.0 0.0 0.0 0 4 1.0 8
-;WATER_HYDRANT 64 64 128 0.4 0.01 255 1 2 20 0 5 0 0.007 0.99 500 0.02 0.05 0.0 0 4 1.0 256
-;WATER_CANNON 64 64 128 0.03 0.03 255 0 0 0 0 0 0 0.0 1.0 1000 0.0 0.0 0.0 0 0 1.0 0
-;EXTINGUISH_STEAM 32 32 32 0.1 0.0 255 0 0 0 0 0 0 0.0 1.0 1000 0.0 0.0 0.0 0 0 1.0 0
-;PED_SPLASH 32 32 64 0.1 0.05 255 0 0 0 0 0 0 0.0 1.0 1000 0.0 0.0 0.0 0 0 1.0 0
-;HELI_DUST 17 15 9 0.2 0.1 255 0 8 0 0 0 0 -0.001 1.0 1000 0.2 0.05 0.0 0 0 1.0 0
-;HELI_ATTACK 255 255 128 0.01 0.0 255 0 0 0 0 0 0 0.0 1.0 500 0.0 0.0 0.0 0 0 0.5 10
-;ENGINE_SMOKE 16 16 16 0.5 0.04 255 0 0 0 0 0 0 -0.005 0.95 2000 0.01 0.03 0.0 0 0 1.0 4
-;ENGINE_SMOKE2 4 4 4 1.0 0.2 255 1 4 0 0 0 0 0.001 1.0 1000 0.0 0.0 0.0 0 3 1.0 4
-;PAINT_SMOKE 255 0 0 0.1 0.01 255 0 8 0 0 0 0 0.0 0.95 3000 0.0 0.005 0.0 0 0 1.0 0
-;TREE_LEAVES 64 64 64 0.2 0.0 255 0 0 0 0 0 0 0.0 1.0 1000 0.0 0.0 0.0 0 0 1.0 0
-;TEST 255 64 64 0.2 0.05 255 0 16 0 0 0 0 0.0 1.0 3000 0.0 0.0 0.0 0 0 1.0 128
-;
-;
-;the end
diff --git a/gamefiles/data/freeroam_miami.scm b/gamefiles/data/freeroam_miami.scm
new file mode 100644
index 00000000..36f5dfd0
--- /dev/null
+++ b/gamefiles/data/freeroam_miami.scm
Binary files differ
diff --git a/gamefiles/data/main_d.scm b/gamefiles/data/main_d.scm
deleted file mode 100644
index 7b46ca39..00000000
--- a/gamefiles/data/main_d.scm
+++ /dev/null
Binary files differ
diff --git a/gamefiles/data/main_freeroam.scm b/gamefiles/data/main_freeroam.scm
deleted file mode 100644
index 021b5c25..00000000
--- a/gamefiles/data/main_freeroam.scm
+++ /dev/null
Binary files differ
diff --git a/gamefiles/models/fonts_j.txd b/gamefiles/models/fonts_j.txd
deleted file mode 100644
index 437e13f9..00000000
--- a/gamefiles/models/fonts_j.txd
+++ /dev/null
Binary files differ
diff --git a/gamefiles/models/fonts_p.txd b/gamefiles/models/fonts_p.txd
deleted file mode 100644
index c05e402e..00000000
--- a/gamefiles/models/fonts_p.txd
+++ /dev/null
Binary files differ
diff --git a/gamefiles/models/fonts_r.txd b/gamefiles/models/fonts_r.txd
index 4b89e449..b6d50ac2 100644
--- a/gamefiles/models/fonts_r.txd
+++ b/gamefiles/models/fonts_r.txd
Binary files differ
diff --git a/gamefiles/models/frontend_ds2.txd b/gamefiles/models/frontend_ds2.txd
new file mode 100644
index 00000000..7cf6c41f
--- /dev/null
+++ b/gamefiles/models/frontend_ds2.txd
Binary files differ
diff --git a/gamefiles/models/frontend_ds3.txd b/gamefiles/models/frontend_ds3.txd
index 7481e9b9..06518848 100644
--- a/gamefiles/models/frontend_ds3.txd
+++ b/gamefiles/models/frontend_ds3.txd
Binary files differ
diff --git a/gamefiles/models/frontend_ds4.txd b/gamefiles/models/frontend_ds4.txd
index 594de328..96193714 100644
--- a/gamefiles/models/frontend_ds4.txd
+++ b/gamefiles/models/frontend_ds4.txd
Binary files differ
diff --git a/gamefiles/models/frontend_x360.txd b/gamefiles/models/frontend_x360.txd
index a57b8d13..acb33099 100644
--- a/gamefiles/models/frontend_x360.txd
+++ b/gamefiles/models/frontend_x360.txd
Binary files differ
diff --git a/gamefiles/models/frontend_xone.txd b/gamefiles/models/frontend_xone.txd
index 03dfefda..b092e8e2 100644
--- a/gamefiles/models/frontend_xone.txd
+++ b/gamefiles/models/frontend_xone.txd
Binary files differ
diff --git a/gamefiles/models/generic.txd b/gamefiles/models/generic.txd
index 8e0d60f3..885cba15 100644
--- a/gamefiles/models/generic.txd
+++ b/gamefiles/models/generic.txd
Binary files differ
diff --git a/gamefiles/models/menu.txd b/gamefiles/models/menu.txd
deleted file mode 100644
index f617bcf8..00000000
--- a/gamefiles/models/menu.txd
+++ /dev/null
Binary files differ
diff --git a/gamefiles/models/particle.txd b/gamefiles/models/particle.txd
index e908ba4e..b0c585f4 100644
--- a/gamefiles/models/particle.txd
+++ b/gamefiles/models/particle.txd
Binary files differ
diff --git a/gamefiles/models/ps3btns.txd b/gamefiles/models/ps3btns.txd
index ed216263..6f485f14 100644
--- a/gamefiles/models/ps3btns.txd
+++ b/gamefiles/models/ps3btns.txd
Binary files differ
diff --git a/gamefiles/models/x360btns.txd b/gamefiles/models/x360btns.txd
index 95a68c8b..3c6ac314 100644
--- a/gamefiles/models/x360btns.txd
+++ b/gamefiles/models/x360btns.txd
Binary files differ
diff --git a/gamefiles/neo/carTweakingTable.dat b/gamefiles/neo/carTweakingTable.dat
index 5e707ae2..5bdc3596 100644
--- a/gamefiles/neo/carTweakingTable.dat
+++ b/gamefiles/neo/carTweakingTable.dat
@@ -1,104 +1,104 @@
-# Fresnal RO Table
-# SUNNY CLOUDY RAINY, FOGGY
-0.400000 0.400000 0.400000 0.150000 # Midnight
-0.400000 0.400000 0.400000 0.150000 # 1am
-0.400000 0.400000 0.400000 0.150000 # 2am
-0.400000 0.400000 0.400000 0.150000 # 3am
-0.400000 0.400000 0.400000 0.150000 # 4am
-0.400000 0.400000 0.400000 0.150000 # 5am
-0.400000 0.400000 0.400000 0.150000 # 6am
-0.400000 0.400000 0.400000 0.150000 # 7am
-0.400000 0.400000 0.400000 0.150000 # 8am
-0.400000 0.400000 0.400000 0.150000 # 9am
-0.400000 0.400000 0.400000 0.150000 # 10am
-0.400000 0.400000 0.400000 0.150000 # 11am
-0.400000 0.400000 0.400000 0.150000 # Midday
-0.400000 0.400000 0.400000 0.150000 # 1pm
-0.400000 0.400000 0.400000 0.150000 # 2pm
-0.400000 0.400000 0.400000 0.150000 # 3pm
-0.400000 0.400000 0.400000 0.150000 # 4pm
-0.400000 0.400000 0.400000 0.150000 # 5pm
-0.400000 0.400000 0.400000 0.150000 # 6pm
-0.400000 0.400000 0.400000 0.150000 # 7pm
-0.400000 0.400000 0.400000 0.150000 # 8pm
-0.400000 0.400000 0.400000 0.150000 # 9pm
-0.400000 0.400000 0.400000 0.150000 # 10pm
-0.400000 0.400000 0.400000 0.150000 # 11pm
-# Specular Power Table
-# SUNNY CLOUDY RAINY, FOGGY
-128.000000 80.000000 30.000000 128.000000 # Midnight
-128.000000 80.000000 30.000000 128.000000 # 1am
-128.000000 80.000000 30.000000 128.000000 # 2am
-128.000000 80.000000 30.000000 128.000000 # 3am
-128.000000 80.000000 30.000000 128.000000 # 4am
-80.000000 60.000000 30.000000 128.000000 # 5am
-80.000000 60.000000 30.000000 128.000000 # 6am
-80.000000 60.000000 30.000000 128.000000 # 7am
-80.000000 60.000000 30.000000 128.000000 # 8am
-80.000000 60.000000 30.000000 128.000000 # 9am
-80.000000 60.000000 30.000000 128.000000 # 10am
-80.000000 60.000000 30.000000 128.000000 # 11am
-80.000000 60.000000 30.000000 128.000000 # Midday
-80.000000 60.000000 30.000000 128.000000 # 1pm
-80.000000 60.000000 30.000000 128.000000 # 2pm
-80.000000 60.000000 30.000000 128.000000 # 3pm
-80.000000 60.000000 30.000000 128.000000 # 4pm
-128.000000 80.000000 30.000000 128.000000 # 5pm
-128.000000 80.000000 30.000000 128.000000 # 6pm
-128.000000 80.000000 30.000000 128.000000 # 7pm
-128.000000 80.000000 30.000000 128.000000 # 8pm
-128.000000 80.000000 30.000000 128.000000 # 9pm
-128.000000 80.000000 30.000000 128.000000 # 10pm
-128.000000 80.000000 30.000000 128.000000 # 11pm
-# Diffuse Colour Modifier Table (Red,Green,Blue,Amount)
-# SUNNY CLOUDY RAINY, FOGGY
-0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 # Midnight
-0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 # 1am
-0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 # 2am
-0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 # 3am
-0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 # 4am
-0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 # 5am
-0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 # 6am
-0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 # 7am
-0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 # 8am
-0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 # 9am
-0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 # 10am
-0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 # 11am
-0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 # Midday
-0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 # 1pm
-0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 # 2pm
-0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 # 3pm
-0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 # 4pm
-0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 # 5pm
-0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 # 6pm
-0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 # 7pm
-0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 # 8pm
-0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 # 9pm
-0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 # 10pm
-0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 0, 0, 0, 0 # 11pm
-# Specular Colour Table (Red,Green,Blue,Amount)
-# SUNNY CLOUDY RAINY, FOGGY
- 81, 150, 178, 100 178, 178, 178, 50 178, 178, 178, 75 178, 178, 178, 20 # Midnight
- 81, 150, 178, 100 178, 178, 178, 50 178, 178, 178, 75 178, 178, 178, 20 # 1am
- 81, 150, 178, 100 178, 178, 178, 50 178, 178, 178, 75 178, 178, 178, 20 # 2am
- 81, 150, 178, 100 178, 178, 178, 50 178, 178, 178, 75 178, 178, 178, 20 # 3am
- 81, 150, 178, 100 178, 178, 178, 50 178, 178, 178, 75 178, 178, 178, 20 # 4am
-178, 178, 178, 100 178, 178, 178, 50 178, 178, 178, 75 178, 178, 178, 20 # 5am
-178, 178, 178, 100 178, 178, 178, 50 178, 178, 178, 75 178, 178, 178, 20 # 6am
-178, 178, 178, 100 178, 178, 178, 50 178, 178, 178, 75 178, 178, 178, 20 # 7am
-178, 178, 178, 100 178, 178, 178, 50 178, 178, 178, 75 178, 178, 178, 20 # 8am
-178, 178, 178, 100 178, 178, 178, 50 178, 178, 178, 75 178, 178, 178, 20 # 9am
-178, 178, 178, 100 178, 178, 178, 50 178, 178, 178, 75 178, 178, 178, 20 # 10am
-178, 178, 178, 100 178, 178, 178, 50 178, 178, 178, 75 178, 178, 178, 20 # 11am
-178, 178, 178, 100 178, 178, 178, 50 178, 178, 178, 75 178, 178, 178, 20 # Midday
-178, 178, 178, 100 178, 178, 178, 50 178, 178, 178, 75 178, 178, 178, 20 # 1pm
-178, 178, 178, 100 178, 178, 178, 50 178, 178, 178, 75 178, 178, 178, 20 # 2pm
-178, 178, 178, 100 178, 178, 178, 50 178, 178, 178, 75 178, 178, 178, 20 # 3pm
-178, 178, 178, 100 178, 178, 178, 50 178, 178, 178, 75 178, 178, 178, 20 # 4pm
-178, 178, 178, 100 178, 178, 178, 50 178, 178, 178, 75 178, 178, 178, 20 # 5pm
-178, 178, 178, 100 178, 178, 178, 50 178, 178, 178, 75 178, 178, 178, 20 # 6pm
-178, 178, 178, 100 178, 178, 178, 50 178, 178, 178, 75 178, 178, 178, 20 # 7pm
-178, 178, 178, 100 178, 178, 178, 50 178, 178, 178, 75 178, 178, 178, 20 # 8pm
-178, 178, 178, 100 178, 178, 178, 50 178, 178, 178, 75 178, 178, 178, 20 # 9pm
- 81, 150, 178, 100 178, 178, 178, 50 178, 178, 178, 75 178, 178, 178, 20 # 10pm
- 81, 150, 178, 100 178, 178, 178, 50 178, 178, 178, 75 178, 178, 178, 20 # 11pm
+# Fresnel RO Table
+# SUNNY CLOUDY RAINY, FOGGY EXTRASUNNY HURRICANE EXTRACOLOURS
+0.4 0.4 0.4 0.4 0.4 0.4 0.4 # Midnight
+0.4 0.4 0.4 0.4 0.4 0.4 0.4 # 1am
+0.4 0.4 0.4 0.4 0.4 0.4 0.4 # 2am
+0.4 0.4 0.4 0.4 0.4 0.4 0.4 # 3am
+0.4 0.4 0.4 0.4 0.4 0.4 0.4 # 4am
+0.4 0.4 0.4 0.4 0.4 0.4 0.4 # 5am
+0.4 0.4 0.4 0.4 0.4 0.4 0.4 # 6am
+0.4 0.4 0.4 0.4 0.4 0.4 0.4 # 7am
+0.4 0.4 0.4 0.4 0.4 0.4 0.4 # 8am
+0.4 0.4 0.4 0.4 0.4 0.4 0.4 # 9am
+0.4 0.4 0.4 0.4 0.4 0.4 0.4 # 10am
+0.4 0.4 0.4 0.4 0.4 0.4 0.4 # 11am
+0.4 0.4 0.4 0.4 0.4 0.4 0.4 # Midday
+0.4 0.4 0.4 0.4 0.4 0.4 0.4 # 1pm
+0.4 0.4 0.4 0.4 0.4 0.4 0.4 # 2pm
+0.4 0.4 0.4 0.4 0.4 0.4 0.4 # 3pm
+0.4 0.4 0.4 0.4 0.4 0.4 0.4 # 4pm
+0.4 0.4 0.4 0.4 0.4 0.4 0.4 # 5pm
+0.4 0.4 0.4 0.4 0.4 0.4 0.4 # 6pm
+0.4 0.4 0.4 0.4 0.4 0.4 0.4 # 7pm
+0.4 0.4 0.4 0.4 0.4 0.4 0.4 # 8pm
+0.4 0.4 0.4 0.4 0.4 0.4 0.4 # 9pm
+0.4 0.4 0.4 0.4 0.4 0.4 0.4 # 10pm
+0.4 0.4 0.4 0.4 0.4 0.4 0.4 # 11pm
+# Specular Power Table (ther higher, the tighter the highlite)
+# SUNNY CLOUDY RAINY, FOGGY EXTRASUNNY HURRICANE EXTRACOLOURS
+25 15 70 10 15 15 18 # Midnight
+25 15 70 10 15 15 18 # 1am
+25 15 70 10 15 15 18 # 2am
+25 15 70 10 15 15 18 # 3am
+25 15 70 10 15 15 18 # 4am
+25 15 70 10 15 15 18 # 5am
+25 15 70 10 15 15 18 # 6am
+25 15 70 10 15 15 18 # 7am
+25 15 70 10 15 15 18 # 8am
+25 15 70 10 15 15 18 # 9am
+25 15 70 10 15 15 18 # 10am
+25 15 70 10 15 15 18 # 11am
+25 15 70 10 15 15 18 # Midday
+25 15 70 10 15 15 18 # 1pm
+25 15 70 10 15 15 18 # 2pm
+25 15 70 10 15 15 18 # 3pm
+25 15 70 10 15 15 18 # 4pm
+25 15 70 10 15 15 18 # 5pm
+25 15 70 10 15 15 18 # 6pm
+25 15 70 10 15 15 18 # 7pm
+25 15 70 10 15 15 18 # 8pm
+25 15 70 10 15 15 18 # 9pm
+25 15 70 10 15 15 18 # 10pm
+25 15 70 10 15 15 18 # 11pm
+# Diffuse Colour Modifier Table (Red,Green,Blue,Amount)
+# SUNNY CLOUDY RAINY, FOGGY EXTRASUNNY HURRICANE EXTRACOLOURS
+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 # Midnight
+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 # 1am
+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 # 2am
+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 # 3am
+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 # 4am
+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 # 5am
+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 # 6am
+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 # 7am
+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 # 8am
+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 # 9am
+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 # 10am
+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 # 11am
+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 # Midday
+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 # 1pm
+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 # 2pm
+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 # 3pm
+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 # 4pm
+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 # 5pm
+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 # 6pm
+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 # 7pm
+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 # 8pm
+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 # 9pm
+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 # 10pm
+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 # 11pm
+# Specular Colour Table (Red,Green,Blue,Ignored)
+# SUNNY CLOUDY RAINY, FOGGY EXTRASUNNY HURRICANE EXTRACOLOURS
+178, 178, 178, 100 140, 140, 150, 50 220, 220, 220, 75 255, 255, 255, 20 178, 178, 178, 100 178, 178, 178, 75 178, 178, 178, 100 # Midnight
+178, 178, 178, 100 140, 140, 150, 50 220, 220, 220, 75 255, 255, 255, 20 178, 178, 178, 100 178, 178, 178, 75 178, 178, 178, 100 # 1am
+178, 178, 178, 100 140, 140, 150, 50 220, 220, 220, 75 255, 255, 255, 20 178, 178, 178, 100 178, 178, 178, 75 178, 178, 178, 100 # 2am
+178, 178, 178, 100 140, 140, 150, 50 220, 220, 220, 75 255, 255, 255, 20 178, 178, 178, 100 178, 178, 178, 75 178, 178, 178, 100 # 3am
+178, 178, 178, 100 140, 140, 150, 50 220, 220, 220, 75 255, 255, 255, 20 178, 178, 178, 100 178, 178, 178, 75 178, 178, 178, 100 # 4am
+178, 178, 178, 100 140, 140, 150, 50 220, 220, 220, 75 255, 255, 255, 20 178, 178, 178, 100 178, 178, 178, 75 178, 178, 178, 100 # 5am
+178, 178, 178, 100 140, 140, 150, 50 220, 220, 220, 75 255, 255, 255, 20 178, 178, 178, 100 178, 178, 178, 75 178, 178, 178, 100 # 6am
+178, 178, 178, 100 140, 140, 150, 50 220, 220, 220, 75 255, 255, 255, 20 178, 178, 178, 100 178, 178, 178, 75 178, 178, 178, 100 # 7am
+178, 178, 178, 100 140, 140, 150, 50 220, 220, 220, 75 255, 255, 255, 20 178, 178, 178, 100 178, 178, 178, 75 178, 178, 178, 100 # 8am
+178, 178, 178, 100 140, 140, 150, 50 220, 220, 220, 75 255, 255, 255, 20 178, 178, 178, 100 178, 178, 178, 75 178, 178, 178, 100 # 9am
+178, 178, 178, 100 140, 140, 150, 50 220, 220, 220, 75 255, 255, 255, 20 178, 178, 178, 100 178, 178, 178, 75 178, 178, 178, 100 # 10am
+178, 178, 178, 100 140, 140, 150, 50 220, 220, 220, 75 255, 255, 255, 20 178, 178, 178, 100 178, 178, 178, 75 178, 178, 178, 100 # 11am
+178, 178, 178, 100 140, 140, 150, 50 220, 220, 220, 75 255, 255, 255, 20 178, 178, 178, 100 178, 178, 178, 75 178, 178, 178, 100 # Midday
+178, 178, 178, 100 140, 140, 150, 50 220, 220, 220, 75 255, 255, 255, 20 178, 178, 178, 100 178, 178, 178, 75 178, 178, 178, 100 # 1pm
+178, 178, 178, 100 140, 140, 150, 50 220, 220, 220, 75 255, 255, 255, 20 178, 178, 178, 100 178, 178, 178, 75 178, 178, 178, 100 # 2pm
+178, 178, 178, 100 140, 140, 150, 50 220, 220, 220, 75 255, 255, 255, 20 178, 178, 178, 100 178, 178, 178, 75 178, 178, 178, 100 # 3pm
+178, 178, 178, 100 140, 140, 150, 50 220, 220, 220, 75 255, 255, 255, 20 178, 178, 178, 100 178, 178, 178, 75 178, 178, 178, 100 # 4pm
+178, 178, 178, 100 140, 140, 150, 50 220, 220, 220, 75 255, 255, 255, 20 178, 178, 178, 100 178, 178, 178, 75 178, 178, 178, 100 # 5pm
+178, 178, 178, 100 140, 140, 150, 50 220, 220, 220, 75 255, 255, 255, 20 178, 178, 178, 100 178, 178, 178, 75 178, 178, 178, 100 # 6pm
+178, 178, 178, 100 140, 140, 150, 50 220, 220, 220, 75 255, 255, 255, 20 178, 178, 178, 100 178, 178, 178, 75 178, 178, 178, 100 # 7pm
+178, 178, 178, 100 140, 140, 150, 50 220, 220, 220, 75 255, 255, 255, 20 178, 178, 178, 100 178, 178, 178, 75 178, 178, 178, 100 # 8pm
+178, 178, 178, 100 140, 140, 150, 50 220, 220, 220, 75 255, 255, 255, 20 178, 178, 178, 100 178, 178, 178, 75 178, 178, 178, 100 # 9pm
+178, 178, 178, 100 140, 140, 150, 50 220, 220, 220, 75 255, 255, 255, 20 178, 178, 178, 100 178, 178, 178, 75 178, 178, 178, 100 # 10pm
+178, 178, 178, 100 140, 140, 150, 50 220, 220, 220, 75 255, 255, 255, 20 178, 178, 178, 100 178, 178, 178, 75 178, 178, 178, 100 # 11pm
diff --git a/gamefiles/neo/neo.txd b/gamefiles/neo/neo.txd
index d20215e0..b2fa6e66 100644
--- a/gamefiles/neo/neo.txd
+++ b/gamefiles/neo/neo.txd
Binary files differ
diff --git a/gamefiles/neo/rimTweakingTable.dat b/gamefiles/neo/rimTweakingTable.dat
index 058d55eb..6a1e0106 100644
--- a/gamefiles/neo/rimTweakingTable.dat
+++ b/gamefiles/neo/rimTweakingTable.dat
@@ -1,130 +1,130 @@
-# Ramp Start Table
-# SUNNY CLOUDY RAINY, FOGGY
-60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 # Midnight
-60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 # 1am
-60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 # 2am
-60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 # 3am
-60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 # 4am
-60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 # 5am
-60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 # 6am
-60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 # 7am
-60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 # 8am
-60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 # 9am
-60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 # 10am
-60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 # 11am
-60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 # Midday
-60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 # 1pm
-60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 # 2pm
-60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 # 3pm
-60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 # 4pm
-60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 # 5pm
-60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 # 6pm
-60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 # 7pm
-60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 # 8pm
-60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 # 9pm
-60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 # 10pm
-60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 60, 55, 53, 100 # 11pm
-# Ramp End Table
-# SUNNY CLOUDY RAINY, FOGGY
-190, 171, 167, 100 190, 171, 167, 100 190, 171, 167, 100 190, 171, 167, 100 # Midnight
-190, 171, 167, 100 190, 171, 167, 100 190, 171, 167, 100 190, 171, 167, 100 # 1am
-190, 171, 167, 100 190, 171, 167, 100 190, 171, 167, 100 190, 171, 167, 100 # 2am
-190, 171, 167, 100 190, 171, 167, 100 190, 171, 167, 100 190, 171, 167, 100 # 3am
-190, 171, 167, 100 190, 171, 167, 100 190, 171, 167, 100 190, 171, 167, 100 # 4am
-255, 230, 224, 100 255, 230, 224, 100 255, 230, 224, 100 255, 230, 224, 100 # 5am
-255, 230, 224, 100 255, 230, 224, 100 255, 230, 224, 100 255, 230, 224, 100 # 6am
-255, 230, 224, 100 255, 230, 224, 100 255, 230, 224, 100 255, 230, 224, 100 # 7am
-255, 230, 224, 100 255, 230, 224, 100 255, 230, 224, 100 255, 230, 224, 100 # 8am
-255, 230, 224, 100 255, 230, 224, 100 255, 230, 224, 100 255, 230, 224, 100 # 9am
-255, 230, 224, 100 255, 230, 224, 100 255, 230, 224, 100 255, 230, 224, 100 # 10am
-255, 230, 224, 100 255, 230, 224, 100 255, 230, 224, 100 255, 230, 224, 100 # 11am
-255, 230, 224, 100 255, 230, 224, 100 255, 230, 224, 100 255, 230, 224, 100 # Midday
-255, 230, 224, 100 255, 230, 224, 100 255, 230, 224, 100 255, 230, 224, 100 # 1pm
-255, 230, 224, 100 255, 230, 224, 100 255, 230, 224, 100 255, 230, 224, 100 # 2pm
-255, 230, 224, 100 255, 230, 224, 100 255, 230, 224, 100 255, 230, 224, 100 # 3pm
-255, 230, 224, 100 255, 230, 224, 100 255, 230, 224, 100 255, 230, 224, 100 # 4pm
-255, 230, 224, 100 255, 230, 224, 100 255, 230, 224, 100 255, 230, 224, 100 # 5pm
-255, 230, 224, 100 255, 230, 224, 100 255, 230, 224, 100 255, 230, 224, 100 # 6pm
-190, 171, 167, 100 190, 171, 167, 100 190, 171, 167, 100 190, 171, 167, 100 # 7pm
-190, 171, 167, 100 190, 171, 167, 100 190, 171, 167, 100 190, 171, 167, 100 # 8pm
-190, 171, 167, 100 190, 171, 167, 100 190, 171, 167, 100 190, 171, 167, 100 # 9pm
-190, 171, 167, 100 190, 171, 167, 100 190, 171, 167, 100 190, 171, 167, 100 # 10pm
-190, 171, 167, 100 190, 171, 167, 100 190, 171, 167, 100 190, 171, 167, 100 # 11pm
-# Offset Table
-# SUNNY CLOUDY RAINY, FOGGY
-0 0 0 0 # Midnight
-0 0 0 0 # 1am
-0 0 0 0 # 2am
-0 0 0 0 # 3am
-0 0 0 0 # 4am
-0 0 0 0 # 5am
-0 0 0 0 # 6am
-0 0 0 0 # 7am
-0 0 0 0 # 8am
-0 0 0 0 # 9am
-0 0 0 0 # 10am
-0 0 0 0 # 11am
-0 0 0 0 # Midday
-0 0 0 0 # 1pm
-0 0 0 0 # 2pm
-0 0 0 0 # 3pm
-0 0 0 0 # 4pm
-0 0 0 0 # 5pm
-0 0 0 0 # 6pm
-0 0 0 0 # 7pm
-0 0 0 0 # 8pm
-0 0 0 0 # 9pm
-0 0 0 0 # 10pm
-0 0 0 0 # 11pm
-# Scale Table
-# SUNNY CLOUDY RAINY, FOGGY
-1.5 1.5 1.0 1.0 # Midnight
-1.5 1.5 1.0 1.0 # 1am
-1.5 1.5 1.0 1.0 # 2am
-1.5 1.5 1.5 1.5 # 3am
-2.0 2.0 2.0 2.0 # 4am
-2.0 2.0 2.0 2.0 # 5am
-2.0 2.0 2.0 2.0 # 6am
-2.5 2.5 2.0 2.0 # 7am
-2.5 2.5 2.0 2.0 # 8am
-2.5 2.5 2.0 2.0 # 9am
-2.5 2.5 2.0 2.0 # 10am
-2.5 2.5 2.0 2.0 # 11am
-2.5 2.5 2.0 2.0 # Midday
-2.5 2.5 2.0 2.0 # 1pm
-2.5 2.5 2.0 2.0 # 2pm
-2.5 2.5 2.0 2.0 # 3pm
-2.5 2.5 2.0 2.0 # 4pm
-2.0 2.0 2.0 2.0 # 5pm
-2.0 2.0 2.0 2.0 # 6pm
-2.0 2.0 2.0 2.0 # 7pm
-1.5 1.5 1.5 1.5 # 8pm
-1.5 1.5 1.0 1.0 # 9pm
-1.5 1.5 1.0 1.0 # 10pm
-1.5 1.5 1.0 1.0 # 11pm
-# Scaling Table
-# SUNNY CLOUDY RAINY, FOGGY
-0.2 0.2 0.1 0.1 # Midnight
-0.2 0.2 0.1 0.1 # 1am
-0.7 0.7 0.2 0.2 # 6am
-0.7 0.7 0.2 0.2 # 3am
-0.7 0.7 0.2 0.2 # 4am
-2.0 2.0 0.3 0.3 # 5am
-3.0 3.0 0.3 0.3 # 6am
-4.0 4.0 0.3 0.3 # 7am
-5.0 5.0 0.3 0.3 # 8am
-6.0 6.0 1.3 1.3 # 9am
-6.0 6.0 2.0 2.0 # 10am
-6.0 6.0 2.0 2.0 # 11am
-6.0 6.0 2.0 2.0 # Midday
-6.0 6.0 2.0 2.0 # 1pm
-6.0 6.0 1.3 1.3 # 6pm
-5.0 5.0 0.3 0.3 # 3pm
-4.0 4.0 0.3 0.3 # 4pm
-3.0 3.0 0.3 0.3 # 5pm
-2.0 2.0 0.3 0.3 # 6pm
-0.7 0.7 0.2 0.2 # 7pm
-0.7 0.7 0.2 0.2 # 8pm
-0.7 0.7 0.2 0.2 # 9pm
-0.2 0.2 0.1 0.1 # 10pm
-0.2 0.2 0.1 0.1 # 11pm
+# Ramp Start Table
+# SUNNY CLOUDY RAINY, FOGGY EXTRASUNNY HURRICANE EXTRACOLOURS
+0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 # Midnight
+0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 # 1am
+0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 # 2am
+0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 # 3am
+0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 # 4am
+0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 # 5am
+0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 # 6am
+0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 # 7am
+0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 # 8am
+0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 # 9am
+0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 # 10am
+0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 # 11am
+0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 # Midday
+0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 # 1pm
+0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 # 2pm
+0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 # 3pm
+0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 # 4pm
+0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 # 5pm
+0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 # 6pm
+0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 # 7pm
+0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 # 8pm
+0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 # 9pm
+0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 # 10pm
+0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 0, 0, 0, 255 # 11pm
+# Ramp End Table
+# SUNNY CLOUDY RAINY, FOGGY EXTRASUNNY HURRICANE EXTRACOLOURS
+255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 # Midnight
+255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 # 1am
+255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 # 2am
+255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 # 3am
+255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 # 4am
+255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 # 5am
+255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 # 6am
+255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 # 7am
+255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 # 8am
+255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 # 9am
+255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 # 10am
+255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 # 11am
+255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 # Midday
+255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 # 1pm
+255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 # 2pm
+255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 # 3pm
+255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 # 4pm
+255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 # 5pm
+255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 # 6pm
+255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 # 7pm
+255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 # 8pm
+255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 # 9pm
+255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 # 10pm
+255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 255, 255, 255, 255 # 11pm
+# Offset Table
+# SUNNY CLOUDY RAINY, FOGGY EXTRASUNNY HURRICANE EXTRACOLOURS
+0.5 0.5 0.5 0.5 0.5 0.5 0.5 # Midnight
+0.5 0.5 0.5 0.5 0.5 0.5 0.5 # 1am
+0.5 0.5 0.5 0.5 0.5 0.5 0.5 # 2am
+0.5 0.5 0.5 0.5 0.5 0.5 0.5 # 3am
+0.5 0.5 0.5 0.5 0.5 0.5 0.5 # 4am
+0.5 0.5 0.5 0.5 0.5 0.5 0.5 # 5am
+0.5 0.5 0.5 0.5 0.5 0.5 0.5 # 6am
+0.5 0.5 0.5 0.5 0.5 0.5 0.5 # 7am
+0.5 0.5 0.5 0.5 0.5 0.5 0.5 # 8am
+0.5 0.5 0.5 0.5 0.5 0.5 0.5 # 9am
+0.5 0.5 0.5 0.5 0.5 0.5 0.5 # 10am
+0.5 0.5 0.5 0.5 0.5 0.5 0.5 # 11am
+0.5 0.5 0.5 0.5 0.5 0.5 0.5 # Midday
+0.5 0.5 0.5 0.5 0.5 0.5 0.5 # 1pm
+0.5 0.5 0.5 0.5 0.5 0.5 0.5 # 2pm
+0.5 0.5 0.5 0.5 0.5 0.5 0.5 # 3pm
+0.5 0.5 0.5 0.5 0.5 0.5 0.5 # 4pm
+0.5 0.5 0.5 0.5 0.5 0.5 0.5 # 5pm
+0.5 0.5 0.5 0.5 0.5 0.5 0.5 # 6pm
+0.5 0.5 0.5 0.5 0.5 0.5 0.5 # 7pm
+0.5 0.5 0.5 0.5 0.5 0.5 0.5 # 8pm
+0.5 0.5 0.5 0.5 0.5 0.5 0.5 # 9pm
+0.5 0.5 0.5 0.5 0.5 0.5 0.5 # 10pm
+0.5 0.5 0.5 0.5 0.5 0.5 0.5 # 11pm
+# Scale Table (the lentgh of the light band?)
+# SUNNY CLOUDY RAINY, FOGGY EXTRASUNNY HURRICANE EXTRACOLOURS
+1 0.5 1.5 0.5 1.5 1.5 1.5 # Midnight
+1 0.5 1.5 0.5 1.5 1.5 1.5 # 1am
+1 0.5 1.5 0.5 1.5 1.5 1.5 # 2am
+1 0.5 1.5 0.5 1.5 1.5 1.5 # 3am
+1 0.5 1.5 0.5 1.5 1.5 1.5 # 4am
+1 0.5 1.5 0.5 1.5 1.5 1.5 # 5am
+1 0.5 1.5 0.5 1.5 1.5 1.5 # 6am
+1 0.5 1.5 0.5 1.5 1.5 1.5 # 7am
+1 0.5 1.5 0.5 1.5 1.5 1.5 # 8am
+1 0.5 1.5 0.5 1.5 1.5 1.5 # 9am
+1 0.5 1.5 0.5 1.5 1.5 1.5 # 10am
+1 0.5 1.5 0.5 1.5 1.5 1.5 # 11am
+1 0.5 1.5 0.5 1.5 1.5 1.5 # Midday
+1 0.5 1.5 0.5 1.5 1.5 1.5 # 1pm
+1 0.5 1.5 0.5 1.5 1.5 1.5 # 2pm
+1 0.5 1.5 0.5 1.5 1.5 1.5 # 3pm
+1 0.5 1.5 0.5 1.5 1.5 1.5 # 4pm
+1 0.5 1.5 0.5 1.5 1.5 1.5 # 5pm
+1 0.5 1.5 0.5 1.5 1.5 1.5 # 6pm
+1 0.5 1.5 0.5 1.5 1.5 1.5 # 7pm
+1 0.5 1.5 0.5 1.5 1.5 1.5 # 8pm
+1 0.5 1.5 0.5 1.5 1.5 1.5 # 9pm
+1 0.5 1.5 0.5 1.5 1.5 1.5 # 10pm
+1 0.5 1.5 0.5 1.5 1.5 1.5 # 11pm
+# Scaling Table (how strong the overall effect is)
+# SUNNY CLOUDY RAINY, FOGGY EXTRASUNNY HURRICANE EXTRACOLOURS time multiplier
+1 0.3 0.5 0.1 1 1 1 # Midnight 0.5
+1 0.3 0.5 0.1 1 1 1 # 1am 0.5
+1 0.3 0.5 0.1 1 1 1 # 2am 0.5
+1 0.3 0.5 0.1 1 1 1 # 3am 0.5
+1 0.3 0.5 0.1 1 1 1 # 4am 0.5
+1 0.3 0.5 0.1 1 1 1 # 5am 0.5
+1 0.3 0.5 0.1 1 1 1 # 6am 0.5
+1.2 0.36 0.6 0.12 1.2 1.2 1.2 # 7am 0.6
+1.4 0.42 0.7 0.14 1.4 1.4 1.4 # 8am 0.7
+1.6 0.48 0.8 0.16 1.6 1.6 1.6 # 9am 0.8
+1.8 0.54 0.9 0.18 1.8 1.8 1.8 # 10am 0.9
+2 0.6 1 0.2 2 2 2 # 11am 1
+2 0.6 1 0.2 2 2 2 # Midday tweaking value
+2 0.6 1 0.2 2 2 2 # 1pm 1
+2 0.6 1 0.2 2 2 2 # 2pm 1
+2.2 0.66 1.1 0.22 2.2 2.2 2.2 # 3pm 1.1
+2.2 0.66 1.1 0.22 2.2 2.2 2.2 # 4pm 1.1
+2.4 0.72 1.2 0.24 2.4 2.4 2.4 # 5pm 1.2
+2.4 0.72 1.2 0.24 2.4 2.4 2.4 # 6pm 1.2
+2.2 0.66 1.1 0.22 2.2 2.2 2.2 # 7pm 1.1
+2 0.6 1 0.2 2 2 2 # 8pm 1
+1.6 0.48 0.8 0.16 1.6 1.6 1.6 # 9pm 0.8
+1.2 0.36 0.6 0.12 1.2 1.2 1.2 # 10pm 0.6
+1 0.3 0.5 0.1 1 1 1 # 11pm 0.5
diff --git a/gamefiles/neo/worldTweakingTable.dat b/gamefiles/neo/worldTweakingTable.dat
index b054fa38..8b6ac79c 100644
--- a/gamefiles/neo/worldTweakingTable.dat
+++ b/gamefiles/neo/worldTweakingTable.dat
@@ -1,26 +1,30 @@
-# LM blend Table
-# SUNNY CLOUDY RAINY FOGGY
-0.700000 0.700000 0.700000 0.550000 # Midnight
-0.700000 0.700000 0.700000 0.550000 # 1am
-0.700000 0.700000 0.700000 0.550000 # 2am
-0.700000 0.700000 0.700000 0.550000 # 3am
-0.700000 0.700000 0.700000 0.550000 # 4am
-0.750000 0.750000 0.700000 0.600000 # 5am
-0.800000 0.800000 0.750000 0.600000 # 6am
-0.850000 0.850000 0.800000 0.650000 # 7am
-0.900000 0.900000 0.800000 0.700000 # 8am
-0.950000 0.900000 0.800000 0.700000 # 9am
-1.000000 0.900000 0.800000 0.700000 # 10am
-1.000000 0.900000 0.800000 0.700000 # 11am
-1.000000 0.900000 0.800000 0.700000 # Midday
-1.000000 0.900000 0.800000 0.700000 # 1pm
-1.000000 0.900000 0.800000 0.700000 # 2pm
-0.950000 0.900000 0.800000 0.700000 # 3pm
-0.900000 0.900000 0.800000 0.700000 # 4pm
-0.850000 0.850000 0.800000 0.650000 # 5pm
-0.800000 0.800000 0.750000 0.600000 # 6pm
-0.750000 0.750000 0.700000 0.600000 # 7pm
-0.700000 0.700000 0.700000 0.550000 # 8pm
-0.700000 0.700000 0.700000 0.550000 # 9pm
-0.700000 0.700000 0.700000 0.550000 # 10pm
-0.700000 0.700000 0.700000 0.550000 # 11pm
+# LM blend Table
+# SUNNY CLOUDY RAINY, FOGGY EXTRASUNNY HURRICANE EXTRACOLOURS basic daytime ramp
+0.45 0.6 0.75 0.525 0.45 0.75 0.375 # Midnight 0.75 0.1
+0.48 0.64 0.8 0.56 0.48 0.8 0.4 # 1am 0.8 0.2
+0.51 0.68 0.85 0.595 0.51 0.85 0.425 # 2am 0.85 0.3
+0.54 0.72 0.9 0.63 0.54 0.9 0.45 # 3am 0.9 0.4
+0.57 0.76 0.95 0.665 0.57 0.95 0.475 # 4am 0.95 0.6
+0.6 0.8 1 0.7 0.6 1 0.5 # 5am 1 0.8
+0.6 0.8 1 0.7 0.6 1 0.5 # 6am 1 1
+0.6 0.8 1 0.7 0.6 1 0.5 # 7am 1 1
+0.6 0.8 1 0.7 0.6 1 0.5 # 8am 1 1
+0.6 0.8 1 0.7 0.6 1 0.5 # 9am 1 1
+0.6 0.8 1 0.7 0.6 1 0.5 # 10am 1 1
+0.6 0.8 1 0.7 0.6 1 0.5 # 11am 1 1
+0.6 0.8 1 0.7 0.6 1 0.5 # Midday 1 tweak here
+0.6 0.8 1 0.7 0.6 1 0.5 # 1pm 1 1
+0.6 0.8 1 0.7 0.6 1 0.5 # 2pm 1 1
+0.6 0.8 1 0.7 0.6 1 0.5 # 3pm 1 1
+0.6 0.8 1 0.7 0.6 1 0.5 # 4pm 1 1
+0.6 0.8 1 0.7 0.6 1 0.5 # 5pm 1 1
+0.6 0.8 1 0.7 0.6 1 0.5 # 6pm 1 0.8
+0.57 0.76 0.95 0.665 0.57 0.95 0.475 # 7pm 0.95 0.6
+0.54 0.72 0.9 0.63 0.54 0.9 0.45 # 8pm 0.9 0.5
+0.51 0.68 0.85 0.595 0.51 0.85 0.425 # 9pm 0.85 0.4
+0.48 0.64 0.8 0.56 0.48 0.8 0.4 # 10pm 0.8 0.3
+0.45 0.6 0.75 0.525 0.45 0.75 0.375 # 11pm 0.75 0.2
+
+
+
+
diff --git a/logo.png b/logo.png
index 50ae8690..4d5a192d 100644
--- a/logo.png
+++ b/logo.png
Binary files differ
diff --git a/logo.svg b/logo.svg
index 9db8447c..3af9cb19 100644
--- a/logo.svg
+++ b/logo.svg
@@ -7,18 +7,51 @@
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- sodipodi:docname="re3_final.svg"
- inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)"
+ sodipodi:docname="reVC.svg"
+ inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07, custom)"
id="svg8"
version="1.1"
viewBox="0 0 270.93331 270.93334"
height="1024"
width="1024"
- inkscape:export-filename="/home/hazelnot/Design/re3_red.png"
+ inkscape:export-filename="/home/hazelnot/Design/re3_final.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96">
<defs
- id="defs2" />
+ id="defs2">
+ <filter
+ style="color-interpolation-filters:sRGB"
+ inkscape:label="Drop Shadow"
+ id="filter1055">
+ <feFlood
+ flood-opacity="1"
+ flood-color="rgb(0,0,0)"
+ result="flood"
+ id="feFlood1045" />
+ <feComposite
+ in="flood"
+ in2="SourceGraphic"
+ operator="in"
+ result="composite1"
+ id="feComposite1047" />
+ <feGaussianBlur
+ in="composite1"
+ stdDeviation="0"
+ result="blur"
+ id="feGaussianBlur1049" />
+ <feOffset
+ dx="1"
+ dy="1"
+ result="offset"
+ id="feOffset1051" />
+ <feComposite
+ in="SourceGraphic"
+ in2="offset"
+ operator="over"
+ result="composite2"
+ id="feComposite1053" />
+ </filter>
+ </defs>
<sodipodi:namedview
inkscape:window-maximized="1"
inkscape:window-y="0"
@@ -30,10 +63,10 @@
inkscape:pagecheckerboard="false"
showgrid="false"
inkscape:document-rotation="0"
- inkscape:current-layer="g837"
+ inkscape:current-layer="svg8"
inkscape:document-units="mm"
- inkscape:cy="544.84615"
- inkscape:cx="415.73725"
+ inkscape:cy="624.20389"
+ inkscape:cx="108.63858"
inkscape:zoom="0.7"
inkscape:pageshadow="2"
inkscape:pageopacity="0"
@@ -61,10 +94,11 @@
</metadata>
<g
id="g837"
- transform="matrix(2.1130708,0,0,2.1130708,14.956432,63.50059)">
+ transform="matrix(2.1130708,0,0,2.1130708,14.956432,63.50059)"
+ style="display:none">
<path
id="path1450"
- style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:1.25;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;shape-margin:0;inline-size:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.836;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1"
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:1.25;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;shape-margin:0;inline-size:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.83595;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1"
d="M 0.91799998,0.91799998 V 54.101316 H 17.960888 v 2.33009 c 0,2.95453 1.347497,6.384348 3.911905,8.332308 2.564408,1.947971 5.514112,2.433445 8.500257,2.433445 h 46.367194 v -14.5464 c 2.171993,1.134845 4.548071,1.450557 6.948413,1.450557 h 17.042893 c 2.98614,0 5.93584,-0.485482 8.50025,-2.433442 2.5644,-1.94796 3.91191,-5.377273 3.91191,-8.331793 V 30.964744 c 0,-1.094128 -0.25094,-2.296243 -0.70487,-3.457153 0.45593,-1.16196 0.70487,-2.363609 0.70487,-3.453019 V 11.81656 c 0,-2.9682265 -1.29681,-6.3966108 -3.85713,-8.3907028 -2.56031,-1.9940909 -5.55104,-2.50785722 -8.55503,-2.50785722 H 83.819398 c -3.003989,0 -5.99213,0.51376632 -8.55245,2.50785722 C 74.832145,3.7645045 74.436551,4.1470248 74.074773,4.5591214 73.713016,4.1470532 73.317379,3.7644843 72.8826,3.4258572 70.322288,1.4317663 67.332073,0.91799998 64.328081,0.91799998 H 47.285195 c -2.976748,0 -5.937909,0.51342982 -8.482687,2.46289872 C 36.275393,1.4370808 33.325985,0.91799998 30.37305,0.91799998 Z"
inkscape:label="Border" />
<g
@@ -79,10 +113,50 @@
transform="translate(-2.6458322)"
inkscape:label="re" />
<path
- style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:1.25;font-family:Pricedown;-inkscape-font-specification:Pricedown;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;shape-margin:0;inline-size:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#c60000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:11.136;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1"
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:1.25;font-family:Pricedown;-inkscape-font-specification:Pricedown;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;shape-margin:0;inline-size:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#c60000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:11.1359;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1"
d="m 135.23613,125.97382 c -4.56245,0 -6.84367,-1.73285 -6.84367,-5.19855 v -7.89654 h 13.68733 v 2.50057 c 0,0.0877 0.0439,0.13161 0.13161,0.13161 h 3.09281 c 0.0877,0 0.13161,-0.0439 0.13161,-0.13161 v -6.11982 c 0,-0.0877 -0.0439,-0.13161 -0.13161,-0.13161 h -16.71434 v -8.35717 h 16.71434 c 0.0877,0 0.13161,-0.0439 0.13161,-0.13161 v -6.054011 c 0,-0.08774 -0.0439,-0.131609 -0.13161,-0.131609 h -3.09281 c -0.0877,0 -0.13161,0.04387 -0.13161,0.131609 v 2.434766 h -13.55572 v -7.764931 c 0,-3.553443 2.28122,-5.330164 6.84366,-5.330164 h 16.91176 c 4.56245,0 6.84367,1.776721 6.84367,5.330164 v 12.239636 c 0,2.01801 -1.14061,3.15862 -3.42184,3.42183 2.28123,0.30709 3.42184,1.46964 3.42184,3.48764 v 12.37125 c 0,3.4657 -2.28122,5.19855 -6.84367,5.19855 z"
id="path1458"
inkscape:label="3" />
</g>
</g>
+ <g
+ id="g3625-7"
+ inkscape:label="reVC_10"
+ transform="matrix(2.4113736,0,0,2.4113736,-122.44911,-160.08821)">
+ <path
+ style="display:inline;fill:#00bbe2;fill-opacity:1;stroke:none;stroke-width:0.264583;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 102.78895,112.11187 54.54276,9.96769 -30.34918,43.22598 z"
+ id="path1613-9"
+ sodipodi:nodetypes="cccc"
+ inkscape:label="triangle" />
+ <g
+ id="g3669-0"
+ style="display:inline;opacity:1"
+ inkscape:label="re">
+ <path
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:1.25;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;shape-margin:0;inline-size:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#f17db2;stroke-width:1.60863;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1"
+ d="m 57.388672,80.632812 v 48.632808 h 17.042969 v 4.60547 c 0,2.45514 1.029322,5.01368 3.011718,6.51953 1.982397,1.50586 4.425056,1.97071 7.123047,1.97071 H 128.6582 v -17.04688 h -1.47851 c 0.87224,-1.37715 1.47851,-2.92106 1.47851,-4.53906 v -7.23633 -3.95312 -20.330081 c 0,-2.481169 -1.00049,-5.053605 -2.98047,-6.595703 -1.97997,-1.542097 -4.44771,-2.027344 -7.15625,-2.027344 h -17.04296 c -2.708546,10e-7 -5.176278,0.485247 -7.156254,2.027344 -0.588908,0.458669 -0.913121,1.140613 -1.328125,1.751953 -0.409812,-0.606749 -0.72664,-1.284534 -1.308594,-1.742187 -1.967878,-1.547555 -4.428385,-2.03711 -7.119141,-2.03711 z m 6.582031,6.583985 h 20.595703 c 1.827819,0 2.757419,0.399739 3.048828,0.628906 0.29141,0.229167 0.4375,0.331111 0.4375,1.410156 v 12.238281 c 0,0.0702 0.0022,0.0438 0.002,0.0801 0.03874,-0.0312 0.06635,0.0114 -0.451172,0.0723 l -0.05469,6.53321 c 0.66816,0.0899 0.752817,0.24295 0.65625,0.14453 -0.09657,-0.0984 -0.08594,-0.3087 -0.08594,0.0801 v 20.07031 c 0,0.59276 0.198598,1.6281 0.996093,2.42578 0.797496,0.79768 1.834701,0.99805 2.427735,0.99805 h 30.53125 v 3.8789 H 84.566406 c -1.864454,0 -2.841799,-0.40191 -3.140625,-0.6289 -0.298826,-0.227 -0.410156,-0.26677 -0.410156,-1.27735 v -24.61132 c 0,-0.59276 -0.200551,-1.6281 -0.998047,-2.42579 -0.797496,-0.79768 -1.832748,-0.99804 -2.425781,-0.99804 h -6.517578 v 16.8457 h -7.103516 z m 37.507817,0 h 17.04296 c 1.8539,0 2.80813,0.402095 3.10938,0.636719 0.30124,0.234623 0.44336,0.33007 0.44336,1.402343 V 106.95508 H 105.0293 v 8.42383 c 0,0.59313 0.20067,1.63031 0.99804,2.42773 0.79738,0.79742 1.83258,0.99609 2.42578,0.99609 h 3.09376 c 0.59313,0 1.62836,-0.19872 2.42578,-0.99609 0.51996,-0.51993 0.73732,-1.1028 0.85937,-1.63672 h 7.24219 v 4.60547 c 0,1.01057 -0.11133,1.05035 -0.41016,1.27734 -0.29882,0.227 -1.27812,0.62891 -3.14258,0.62891 h -17.04296 c -1.864458,0 -2.841803,-0.40191 -3.140629,-0.62891 -0.298826,-0.22699 -0.410157,-0.26677 -0.410157,-1.27734 V 89.255859 c 0,-1.072272 0.140161,-1.167719 0.441407,-1.402343 0.301246,-0.234625 1.255472,-0.636719 3.109379,-0.636719 z M 71.074219,91.162109 V 104.0625 h 6.517578 c 0.592903,0 1.628193,-0.20031 2.425781,-0.99805 0.797588,-0.79773 0.998047,-1.83309 0.998047,-2.42578 v -6.052732 c 0,-0.592528 -0.200189,-1.629881 -0.998047,-2.427735 -0.797858,-0.797853 -1.83326,-0.996094 -2.425781,-0.996094 z m 37.378901,0 c -0.59275,0 -1.62809,0.198598 -2.42578,0.996094 -0.79768,0.797496 -0.99804,1.834701 -0.99804,2.427735 v 9.148442 h 9.9414 v -9.148442 c 0,-0.592903 -0.20031,-1.630147 -0.99804,-2.427735 -0.79774,-0.797588 -1.8331,-0.996094 -2.42578,-0.996094 z"
+ id="path3671-2"
+ inkscape:label="outline" />
+ <path
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:1.25;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;shape-margin:0;inline-size:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:9.53813;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1"
+ d="m 84.566726,139.06892 c -4.562445,0 -6.843668,-1.73285 -6.843668,-5.19856 v -24.61088 c 0,-0.0877 -0.04387,-0.13161 -0.131609,-0.13161 h -3.22442 v 16.84595 H 60.679694 V 83.92475 h 23.887032 c 4.518575,0 6.777863,1.776721 6.777863,5.330164 v 12.239636 c 0,2.01801 -1.118676,3.15862 -3.356029,3.42183 2.281223,0.30709 3.421834,1.46964 3.421834,3.48764 v 20.07037 c 0,0.0877 0.04387,0.13161 0.131609,0.13161 h 33.823507 v 10.46292 z M 77.723058,94.585079 c 0,-0.08774 -0.04387,-0.131609 -0.131609,-0.131609 h -3.22442 v 6.31723 h 3.22442 c 0.08774,0 0.131609,-0.0439 0.131609,-0.13161 z m 33.955122,0 c 0,-0.08774 -0.0439,-0.131609 -0.13161,-0.131609 h -3.09281 c -0.0877,0 -0.13161,0.04387 -0.13161,0.131609 v 5.856601 h 3.35603 z m -10.1997,31.388741 c -4.562444,0 -6.843666,-1.73285 -6.843666,-5.19855 V 89.254914 c 0,-3.553443 2.281222,-5.330164 6.843666,-5.330164 h 17.04337 c 4.56244,0 6.84366,1.776721 6.84366,5.330164 v 20.991636 h -17.04336 v 5.13275 c 0,0.0877 0.0439,0.13161 0.13161,0.13161 h 3.09281 c 0.0877,0 0.13161,-0.0439 0.13161,-0.13161 v -2.50057 h 13.68733 v 7.89654 c 0,3.4657 -2.28122,5.19855 -6.84366,5.19855 z"
+ id="path3673-3"
+ inkscape:label="text" />
+ </g>
+ <g
+ id="g861-9-7"
+ style="display:inline;fill:#ffffff;fill-opacity:1;stroke:#f17db2;stroke-opacity:1;filter:url(#filter1055)"
+ transform="matrix(1.3835644,0,0,1.3835644,-22.936608,36.936115)"
+ inkscape:label="Vc">
+ <path
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;shape-margin:0;inline-size:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#f17db2;stroke-width:3.175;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1"
+ d="m 115.29478,55.979585 a 1.0583349,1.0583349 0 0 0 -0.94727,0.53711 l -13.61915,24.06445 -1.763667,-7.15234 a 1.0583349,1.0583349 0 0 0 -1.28125,-0.77344 1.0583349,1.0583349 0 0 0 -0.77344,1.28125 l 2.40235,9.73438 a 1.0584408,1.0584408 0 0 0 1.947257,0.26757 l 14.9297,-26.38086 a 1.0583349,1.0583349 0 0 0 -0.39844,-1.4414 1.0583349,1.0583349 0 0 0 -0.49609,-0.13672 z"
+ id="path892-1-5" />
+ <path
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;shape-margin:0;inline-size:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#f17db2;stroke-width:3.175;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1"
+ d="m 118.1854,69.604585 a 1.0583349,1.0583349 0 0 0 -0.27343,0.0391 c 0,0 -2.1903,0.59881 -4.46875,2.08789 -2.27846,1.48909 -4.77359,3.96951 -5.16602,7.69531 -0.20107,1.90898 0.49022,3.43086 1.68359,4.15821 1.19338,0.72735 2.6066,0.75222 3.94727,0.60547 2.68134,-0.29351 5.29297,-1.44336 5.29297,-1.44336 a 1.0583349,1.0583349 0 0 0 0.55078,-1.39063 1.0583349,1.0583349 0 0 0 -1.39063,-0.55273 c 0,0 -2.46507,1.04035 -4.68359,1.2832 -1.10926,0.12142 -2.10191,0.002 -2.61523,-0.31055 -0.51333,-0.31286 -0.82729,-0.72566 -0.67969,-2.12695 0.3049,-2.89473 2.23993,-4.85323 4.21875,-6.14648 1.97882,-1.29326 3.87305,-1.82032 3.87305,-1.82032 a 1.0583349,1.0583349 0 0 0 0.73828,-1.30078 1.0583349,1.0583349 0 0 0 -1.02735,-0.77734 z"
+ id="path896-2-9" />
+ </g>
+ </g>
</svg>
diff --git a/premake5.lua b/premake5.lua
index 25090dc6..4223b395 100644
--- a/premake5.lua
+++ b/premake5.lua
@@ -66,10 +66,10 @@ function getarch(a)
return a
end
-workspace "re3"
+workspace "reVC"
language "C++"
configurations { "Debug", "Release" }
- startproject "re3"
+ startproject "reVC"
location "build"
symbols "Full"
staticruntime "off"
@@ -82,10 +82,10 @@ workspace "re3"
filter { "system:windows" }
configurations { "Vanilla" }
platforms {
- "win-x86-RW33_d3d8-mss",
+ "win-x86-RW34_d3d8-mss",
"win-x86-librw_d3d9-mss",
"win-x86-librw_gl3_glfw-mss",
- "win-x86-RW33_d3d8-oal",
+ "win-x86-RW34_d3d8-oal",
"win-x86-librw_d3d9-oal",
"win-x86-librw_gl3_glfw-oal",
"win-amd64-librw_d3d9-oal",
@@ -232,7 +232,7 @@ project "librw"
filter "platforms:*gl3_glfw*"
staticruntime "off"
- filter "platforms:*RW33*"
+ filter "platforms:*RW34*"
flags { "ExcludeFromBuild" }
filter {}
end
@@ -241,9 +241,9 @@ local function addSrcFiles( prefix )
return prefix .. "/*cpp", prefix .. "/*.h", prefix .. "/*.c", prefix .. "/*.ico", prefix .. "/*.rc"
end
-project "re3"
+project "reVC"
kind "WindowedApp"
- targetname "re3"
+ targetname "reVC"
targetdir "bin/%{cfg.platform}/%{cfg.buildcfg}"
if(_OPTIONS["with-librw"]) then
@@ -334,8 +334,8 @@ project "re3"
defines { "AUDIO_OAL" }
filter {}
- if(os.getenv("GTA_III_RE_DIR")) then
- setpaths(os.getenv("GTA_III_RE_DIR") .. "/", "%(cfg.buildtarget.name)")
+ if(os.getenv("GTA_VC_RE_DIR")) then
+ setpaths(os.getenv("GTA_VC_RE_DIR") .. "/", "%(cfg.buildtarget.name)")
end
filter "platforms:win*"
@@ -404,10 +404,10 @@ project "re3"
links { "opusfile" }
end
- filter "platforms:*RW33*"
+ filter "platforms:*RW34*"
includedirs { "sdk/rwsdk/include/d3d8" }
libdirs { "sdk/rwsdk/lib/d3d8/release" }
- links { "rwcore", "rpworld", "rpmatfx", "rpskin", "rphanim", "rtbmp", "rtquat", "rtcharse", "rpanisot" }
+ links { "rwcore", "rpworld", "rpmatfx", "rpskin", "rphanim", "rtbmp", "rtquat", "rtanim", "rtcharse", "rpanisot" }
defines { "RWLIBS" }
linkoptions "/SECTION:_rwcseg,ER!W /MERGE:_rwcseg=.text"
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 bc470c49..d94d99ea 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;
m_sQueueSample.m_nEmittingVolume = emittingVol;
- SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex);
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
m_sQueueSample.m_fSpeedMultiplier = 4.0f;
m_sQueueSample.m_fSoundIntensity = 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 44664f8a..c547007c 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,23 +241,23 @@ cAudioManager::ResetAudioLogicTimers(uint32 timer)
}
}
}
- ClearMissionAudio();
+ ClearMissionAudio(0);
+ ClearMissionAudio(1);
SampleManager.StopChannel(CHANNEL_POLICE_RADIO);
}
void
cAudioManager::ProcessReverb()
{
- 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);
}
@@ -261,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);
+ }
+ }
}
}
}
@@ -310,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();
@@ -357,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;
}
@@ -389,13 +440,13 @@ enum eVehicleModel {
LINERUN,
PEREN,
SENTINEL,
- PATRIOT,
+ RIO,
FIRETRUK,
TRASH,
STRETCH,
MANANA,
INFERNUS,
- BLISTA,
+ VOODOO,
PONY,
MULE,
CHEETAH,
@@ -404,11 +455,11 @@ enum eVehicleModel {
MOONBEAM,
ESPERANT,
TAXI,
- KURUMA,
+ WASHING,
BOBCAT,
MRWHOOP,
BFINJECT,
- CORPSE,
+ HUNTER,
POLICE,
ENFORCER,
SECURICA,
@@ -417,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
@@ -476,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;
@@ -569,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 (propellerSpeed == 0.0f)
+ return;
+
+ propellerSpeed = Min(1.0f, propellerSpeed);
+ CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance);
- if (handling != nil)
- params.m_pTransmission = &handling->Transmission;
+
+ //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;
+ m_sQueueSample.m_nEmittingVolume = emittingVol;
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
+ m_sQueueSample.m_fSpeedMultiplier = 6.0f;
+ m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
+ m_sQueueSample.m_bReleasingSoundFlag = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 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;
+
+ if (params.m_fDistance >= SQR(140.0f))
+ return;
- 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 (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;
+ m_sQueueSample.m_nEmittingVolume = emittingVol;
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
+ m_sQueueSample.m_fSpeedMultiplier = 6.0f;
+ m_sQueueSample.m_fSoundIntensity = 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;
+ m_sQueueSample.m_nEmittingVolume = emittingVol;
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
+ m_sQueueSample.m_fSpeedMultiplier = 6.0f;
+ m_sQueueSample.m_fSoundIntensity = 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;
+ m_sQueueSample.m_nEmittingVolume = emittingVol;
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
+ m_sQueueSample.m_fSpeedMultiplier = 6.0f;
+ m_sQueueSample.m_fSoundIntensity = 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;
+ m_sQueueSample.m_nEmittingVolume = emittingVol;
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
+ m_sQueueSample.m_fSpeedMultiplier = 6.0f;
+ m_sQueueSample.m_fSoundIntensity = 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;
+ m_sQueueSample.m_nEmittingVolume = emittingVol;
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
+ m_sQueueSample.m_fSpeedMultiplier = 6.0f;
+ m_sQueueSample.m_fSoundIntensity = 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;
+ m_sQueueSample.m_nEmittingVolume = propellerSpeed * 100.0f;
+ SET_LOOP_OFFSETS(SFX_SEAPLANE_PRO4)
+ m_sQueueSample.m_fSpeedMultiplier = 5.0f;
+ m_sQueueSample.m_fSoundIntensity = 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;
- m_sQueueSample.m_nEmittingVolume = (uint8)emittingVol;
- RESET_LOOP_OFFSETS
- m_sQueueSample.m_fSpeedMultiplier = 0.0f;
- m_sQueueSample.m_fSoundIntensity = 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;
+ m_sQueueSample.m_nEmittingVolume = volumeModifier * 25.0f;
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
+ m_sQueueSample.m_fSpeedMultiplier = 6.0f;
+ m_sQueueSample.m_fSoundIntensity = 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;
+ m_sQueueSample.m_nEmittingVolume = emittingVol;
+ RESET_LOOP_OFFSETS
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
+ m_sQueueSample.m_bReleasingSoundFlag = TRUE;
+ m_sQueueSample.m_bReverbFlag = FALSE;
+ m_sQueueSample.m_bRequireReflection = FALSE;
+ AddSampleToRequestedQueue();
+ }
}
}
@@ -699,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;
@@ -731,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;
- m_sQueueSample.m_nEmittingVolume = emittingVol;
+ m_sQueueSample.m_nEmittingVolume = emittingVolume;
SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
m_sQueueSample.m_fSpeedMultiplier = 3.0f;
m_sQueueSample.m_fSoundIntensity = reverseGearIntensity;
@@ -748,57 +1259,257 @@ 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, 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;
+ m_sQueueSample.m_nEmittingVolume = 70;
+ SET_LOOP_OFFSETS(SFX_CAR_RC_HELI)
+ m_sQueueSample.m_fSpeedMultiplier = 3.0f;
+ m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
+ m_sQueueSample.m_bReleasingSoundFlag = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 4;
+ m_sQueueSample.m_bReverbFlag = TRUE;
+ m_sQueueSample.m_bRequireReflection = FALSE;
+ AddSampleToRequestedQueue();
+ }
+ 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;
+ m_sQueueSample.m_nEmittingVolume = volume;
+ SET_LOOP_OFFSETS(SFX_RC_REV)
+ m_sQueueSample.m_fSpeedMultiplier = 3.0f;
+ m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
+ m_sQueueSample.m_bReleasingSoundFlag = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 4;
+ m_sQueueSample.m_bReverbFlag = TRUE;
+ m_sQueueSample.m_bRequireReflection = FALSE;
+ AddSampleToRequestedQueue();
}
- 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;
- m_sQueueSample.m_nEmittingVolume = emittingVol;
- SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
- m_sQueueSample.m_fSpeedMultiplier = 3.0f;
- m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
- m_sQueueSample.m_bReleasingSoundFlag = FALSE;
- m_sQueueSample.m_nReleasingVolumeDivider = 3;
- m_sQueueSample.m_bReverbFlag = TRUE;
- m_sQueueSample.m_bRequireReflection = FALSE;
- AddSampleToRequestedQueue();
- }
+ }
+ 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;
+ m_sQueueSample.m_nEmittingVolume = volume;
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
+ m_sQueueSample.m_fSpeedMultiplier = 3.0f;
+ m_sQueueSample.m_fSoundIntensity = 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;
+ m_sQueueSample.m_nEmittingVolume = emittingVol;
+ SET_LOOP_OFFSETS(SFX_TYRE_BURST_L)
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
+ m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
+ m_sQueueSample.m_bReleasingSoundFlag = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_bReverbFlag = TRUE;
+ m_sQueueSample.m_bRequireReflection = FALSE;
+ AddSampleToRequestedQueue();
+ }
+ }
+}
+
bool8
cAudioManager::ProcessVehicleRoadNoise(cVehicleParams& params)
{
@@ -809,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;
- m_sQueueSample.m_nEmittingVolume = emittingVol;
- SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
- m_sQueueSample.m_fSpeedMultiplier = 6.0f;
- m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
- m_sQueueSample.m_bReleasingSoundFlag = FALSE;
- m_sQueueSample.m_nReleasingVolumeDivider = 4;
- m_sQueueSample.m_bReverbFlag = TRUE;
- m_sQueueSample.m_bRequireReflection = FALSE;
- AddSampleToRequestedQueue();
- }
+
+ 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;
+ m_sQueueSample.m_nEmittingVolume = emittingVol;
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
+ m_sQueueSample.m_fSpeedMultiplier = 6.0f;
+ m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
+ m_sQueueSample.m_bReleasingSoundFlag = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 4;
+ m_sQueueSample.m_bReverbFlag = TRUE;
+ m_sQueueSample.m_bRequireReflection = FALSE;
+ AddSampleToRequestedQueue();
}
}
+
return TRUE;
}
@@ -860,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;
- m_sQueueSample.m_nEmittingVolume = emittingVol;
- SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
- m_sQueueSample.m_fSpeedMultiplier = 6.0f;
- m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
- m_sQueueSample.m_bReleasingSoundFlag = FALSE;
- m_sQueueSample.m_nReleasingVolumeDivider = 4;
- m_sQueueSample.m_bReverbFlag = TRUE;
- m_sQueueSample.m_bRequireReflection = FALSE;
- AddSampleToRequestedQueue();
- }
- }
+ 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;
+ m_sQueueSample.m_nEmittingVolume = emittingVol;
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
+ m_sQueueSample.m_fSpeedMultiplier = 6.0f;
+ m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
+ m_sQueueSample.m_bReleasingSoundFlag = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 4;
+ m_sQueueSample.m_bReverbFlag = TRUE;
+ m_sQueueSample.m_bRequireReflection = FALSE;
+ AddSampleToRequestedQueue();
}
}
+
return TRUE;
}
@@ -907,155 +1641,237 @@ 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;
- if (params.m_fDistance < SQR(SOUND_INTENSITY)) {
- playerVeh = FindPlayerVehicle();
- veh = params.m_pVehicle;
- if (playerVeh == veh && veh->GetStatus() == STATUS_WRECKED) {
- SampleManager.StopChannel(CHANNEL_PLAYER_VEHICLE_ENGINE);
+ isMoped = FALSE;
+ caddyBool = FALSE;
+ traction = 0.0f;
+ if (params.m_fDistance >= SQR(SOUND_INTENSITY))
+ return;
+ playerVeh = FindPlayerVehicle();
+ veh = params.m_pVehicle;
+ if (playerVeh == veh && veh->GetStatus() == STATUS_WRECKED) {
+ SampleManager.StopChannel(CHANNEL_PLAYER_VEHICLE_ENGINE);
+ return;
+ }
+ if (!veh->bEngineOn)
+ return;
+ CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance);
+ if (playerVeh == veh && veh->m_modelIndex != MI_CADDY) {
+ ProcessPlayersVehicleEngine(params, params.m_pVehicle);
+ return;
+ }
+ transmission = params.m_pTransmission;
+ if (transmission != nil) {
+ 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;
}
- if (veh->bEngineOn) {
- CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance);
- automobile = (CAutomobile *)params.m_pVehicle;
- if (params.m_nIndex == DODO) {
- ProcessCesna(params);
- return;
- }
- if (FindPlayerVehicle() == veh) {
- ProcessPlayersVehicleEngine(params, automobile);
- return;
- }
- transmission = params.m_pTransmission;
- if (transmission != nil) {
- currentGear = params.m_pVehicle->m_nCurrentGear;
- if (automobile->m_nWheelsOnGround != 0) {
- if (automobile->bIsHandbrakeOn) {
- if (params.m_fVelocityChange == 0.0f)
- traction = 0.9f;
- } else if (params.m_pVehicle->GetStatus() == STATUS_SIMPLE) {
- traction = 0.0f;
- } else {
- switch (transmission->nDriveType) {
- case '4':
- for (int32 i = 0; i < ARRAY_SIZE(automobile->m_aWheelState); i++) {
- if (automobile->m_aWheelState[i] == WHEEL_STATE_SPINNING)
+
+ 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 (automobile->m_aWheelState[CARWHEEL_FRONT_LEFT] == WHEEL_STATE_SPINNING)
+ }
+ 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 (automobile->m_aWheelState[CARWHEEL_FRONT_RIGHT] == WHEEL_STATE_SPINNING)
+ if (wheelState[CARWHEEL_FRONT_RIGHT] == WHEEL_STATE_SPINNING)
traction += 0.1f;
- break;
- case 'R':
- if (automobile->m_aWheelState[CARWHEEL_REAR_LEFT] == WHEEL_STATE_SPINNING)
+ }
+ 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 (automobile->m_aWheelState[CARWHEEL_REAR_RIGHT] == WHEEL_STATE_SPINNING)
+ if (wheelState[CARWHEEL_REAR_RIGHT] == WHEEL_STATE_SPINNING)
traction += 0.1f;
- break;
}
+ break;
+ default:
+ break;
}
- if (transmission->fMaxVelocity <= 0.f) {
- relativeChange = 0.f;
- } else if (currentGear != 0) {
- relativeGearChange =
- Min(1.0f, (params.m_fVelocityChange - transmission->Gears[currentGear].fShiftDownVelocity) / transmission->fMaxVelocity * 2.5f);
- if (traction == 0.0f && automobile->GetStatus() != STATUS_SIMPLE &&
- params.m_fVelocityChange < transmission->Gears[1].fShiftUpVelocity) {
+ }
+ } else if (params.m_fVelocityChange == 0.0f) {
+ traction = 0.9f;
+ }
+ 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 * 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));
+ 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 {
- if (automobile->m_nDriveWheelsOnGround != 0)
- automobile->m_fGasPedalAudio *= 0.4f;
- relativeChange = automobile->m_fGasPedalAudio;
+ modificator = Min(1.0f, Abs(params.m_fVelocityChange / transmission->fMaxVelocity > 1.0f));
}
- modificator = relativeChange;
- if (currentGear != 0 || automobile->m_nWheelsOnGround == 0)
- freq = 1200 * currentGear + 18000.f * modificator + 14000;
- else
- freq = 13000.f * modificator + 14000;
- if (modificator >= 0.75f) {
- emittingVol = 120;
- volume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance);
+ }
+ } else {
+ if (wheelsOnGroundPrev != 0)
+ *gasPedalAudioPtr *= 0.4f;
+ relativeChange = *gasPedalAudioPtr;
+ modificator = relativeChange;
+ }
+ 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.0f * modificator + 14000;
+ if (modificator >= 0.75f)
+ emittingVol = 90;
+ else
+ emittingVol = modificator * (4.0f / 3.0f) * 15.0f + 75;
+ } else {
+ modificator = 0.0f;
+ emittingVol = 75;
+ }
+ 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 (!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 {
- emittingVol = modificator * 4.0f / 3.0f * 40.f + 80.f;
- volume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_nSampleIndex = aVehicleSettings[params.m_nIndex].m_nAccelerationSampleIndex;
+ m_sQueueSample.m_nCounter = 2;
}
} else {
- modificator = 0.f;
- emittingVol = 80;
- volume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance);
- }
- m_sQueueSample.m_nVolume = volume;
- if (m_sQueueSample.m_nVolume != 0) {
- if (automobile->GetStatus() == STATUS_SIMPLE) {
- if (modificator < 0.02f) {
- m_sQueueSample.m_nSampleIndex = aVehicleSettings[params.m_nIndex].m_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 (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 {
- 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;
- }
+ m_sQueueSample.m_nSampleIndex = aVehicleSettings[params.m_nIndex].m_nAccelerationSampleIndex;
+ m_sQueueSample.m_nCounter = 2;
}
- 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)
- m_sQueueSample.m_nFrequency /= 2;
- m_sQueueSample.m_nLoopCount = 0;
- m_sQueueSample.m_nEmittingVolume = emittingVol;
- SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
- m_sQueueSample.m_fSpeedMultiplier = 6.0f;
- m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
- m_sQueueSample.m_bReleasingSoundFlag = FALSE;
- m_sQueueSample.m_nReleasingVolumeDivider = 8;
- m_sQueueSample.m_bReverbFlag = TRUE;
- m_sQueueSample.m_bRequireReflection = FALSE;
- AddSampleToRequestedQueue();
}
+ m_sQueueSample.m_nFrequency = freq + 100 * m_sQueueSample.m_nBankIndex % 1000;
+ } else {
+ 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;
+ 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;
+ m_sQueueSample.m_nEmittingVolume = emittingVol;
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
+ m_sQueueSample.m_fSpeedMultiplier = 6.0f;
+ m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
+ m_sQueueSample.m_bReleasingSoundFlag = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 8;
+ m_sQueueSample.m_bReverbFlag = TRUE;
+ m_sQueueSample.m_bRequireReflection = FALSE;
+ AddSampleToRequestedQueue();
}
}
void
-cAudioManager::UpdateGasPedalAudio(CAutomobile *automobile)
+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
@@ -1104,29 +1920,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;
@@ -1137,27 +1936,27 @@ cAudioManager::ProcessCesna(cVehicleParams& params)
m_sQueueSample.m_nReleasingVolumeDivider = 8;
m_sQueueSample.m_nEmittingVolume = 80;
SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
- m_sQueueSample.m_fSpeedMultiplier = 8.0f;
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
m_sQueueSample.m_fSoundIntensity = 200.0f;
m_sQueueSample.m_bReleasingSoundFlag = FALSE;
m_sQueueSample.m_bReverbFlag = TRUE;
m_sQueueSample.m_bRequireReflection = FALSE;
AddSampleToRequestedQueue();
}
- if (params.m_fDistance < SQR(90)) {
+ 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;
m_sQueueSample.m_nEmittingVolume = 80;
SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
- m_sQueueSample.m_fSpeedMultiplier = 8.0f;
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
m_sQueueSample.m_fSoundIntensity = 90.0f;
m_sQueueSample.m_bReleasingSoundFlag = FALSE;
m_sQueueSample.m_bReverbFlag = TRUE;
@@ -1169,41 +1968,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;
@@ -1211,48 +2021,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
@@ -1261,63 +2114,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)
@@ -1326,57 +2271,80 @@ 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);
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) {
+ 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, 12.5f);
+ 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);
+ 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, 12.5f);
+ 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);
- }
- 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.f, 12.5f);
- 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);
+ 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, 12.5f);
+ 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) {
@@ -1385,14 +2353,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
@@ -1401,6 +2371,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;
@@ -1408,29 +2385,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;
@@ -1457,6 +2453,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;
@@ -1464,6 +2461,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;
}
@@ -1486,18 +2485,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);
@@ -1518,92 +2516,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;
- m_sQueueSample.m_nEmittingVolume = 80;
- SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
- m_sQueueSample.m_fSpeedMultiplier = 5.0f;
- m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
- m_sQueueSample.m_bReleasingSoundFlag = FALSE;
- m_sQueueSample.m_nReleasingVolumeDivider = 3;
- m_sQueueSample.m_bReverbFlag = TRUE;
- m_sQueueSample.m_bRequireReflection = FALSE;
- AddSampleToRequestedQueue();
- }
- }
+ 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
+ m_sQueueSample.m_nEmittingVolume = volume;
+#else
+ m_sQueueSample.m_nEmittingVolume = 80;
+#endif
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
+ m_sQueueSample.m_fSpeedMultiplier = 5.0f;
+ m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
+ m_sQueueSample.m_bReleasingSoundFlag = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 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
@@ -1611,57 +2609,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;
- m_sQueueSample.m_nEmittingVolume = 80;
- SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
- m_sQueueSample.m_fSpeedMultiplier = 7.0f;
- m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
- m_sQueueSample.m_bReleasingSoundFlag = FALSE;
- m_sQueueSample.m_nReleasingVolumeDivider = 5;
- m_sQueueSample.m_bReverbFlag = TRUE;
- m_sQueueSample.m_bRequireReflection = FALSE;
- AddSampleToRequestedQueue();
- return 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;
+ m_sQueueSample.m_nEmittingVolume = volume;
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
+ m_sQueueSample.m_fSpeedMultiplier = 7.0f;
+ m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
+ m_sQueueSample.m_bReleasingSoundFlag = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 5;
+ m_sQueueSample.m_bReverbFlag = TRUE;
+ m_sQueueSample.m_bRequireReflection = FALSE;
+ AddSampleToRequestedQueue();
+ }
+ return 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
@@ -1670,13 +2682,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;
@@ -1685,7 +2699,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
+ m_sQueueSample.m_nEmittingVolume = volume;
+#else
m_sQueueSample.m_nEmittingVolume = 60;
+#endif
SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
m_sQueueSample.m_fSpeedMultiplier = 3.0f;
m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
@@ -1720,7 +2738,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;
@@ -1749,10 +2767,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)
@@ -1763,8 +2782,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;
@@ -1774,10 +2793,10 @@ cAudioManager::ProcessAirBrakes(cVehicleParams& params)
m_sQueueSample.m_bIs2D = FALSE;
m_sQueueSample.m_nReleasingVolumeModificator = 10;
m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.m_nEmittingVolume = rand;
+ m_sQueueSample.m_nEmittingVolume = volume;
RESET_LOOP_OFFSETS
m_sQueueSample.m_fSpeedMultiplier = 0.0f;
- m_sQueueSample.m_fSoundIntensity = 30.0f;
+ m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
m_sQueueSample.m_bReleasingSoundFlag = TRUE;
m_sQueueSample.m_bReverbFlag = TRUE;
m_sQueueSample.m_bRequireReflection = FALSE;
@@ -1790,38 +2809,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;
@@ -1830,7 +2852,7 @@ cAudioManager::ProcessEngineDamage(cVehicleParams& params)
m_sQueueSample.m_nEmittingVolume = emittingVolume;
SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
m_sQueueSample.m_fSpeedMultiplier = 2.0f;
- m_sQueueSample.m_fSoundIntensity = engineDamageIntensity;
+ m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
m_sQueueSample.m_bReleasingSoundFlag = FALSE;
m_sQueueSample.m_nReleasingVolumeDivider = 3;
m_sQueueSample.m_bReverbFlag = TRUE;
@@ -1844,31 +2866,47 @@ cAudioManager::ProcessEngineDamage(cVehicleParams& params)
bool8
cAudioManager::ProcessCarBombTick(cVehicleParams& params)
{
- CAutomobile *automobile;
+ const float SOUND_INTENSITY = 40.0f;
+ const uint8 EMITTING_VOLUME = 60;
+
+ uint8 bombType;
- if (params.m_fDistance >= SQR(40.f))
+ 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;
- m_sQueueSample.m_nEmittingVolume = 60;
- SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
- m_sQueueSample.m_fSpeedMultiplier = 2.0f;
- m_sQueueSample.m_fSoundIntensity = 40.0f;
- m_sQueueSample.m_bReleasingSoundFlag = FALSE;
- m_sQueueSample.m_nReleasingVolumeDivider = 3;
- m_sQueueSample.m_bReverbFlag = TRUE;
- m_sQueueSample.m_bRequireReflection = FALSE;
- AddSampleToRequestedQueue();
+ 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;
+ m_sQueueSample.m_nEmittingVolume = EMITTING_VOLUME;
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
+ m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
+ m_sQueueSample.m_bReleasingSoundFlag = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_bReverbFlag = TRUE;
+ m_sQueueSample.m_bRequireReflection = FALSE;
+ AddSampleToRequestedQueue();
+ }
}
}
return TRUE;
@@ -1882,15 +2920,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 (int i = 0; i < m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_AudioEvents; i++) {
- noReflections = 0;
+ noReflections = FALSE;
+ isHeli = FALSE;
m_sQueueSample.m_bRequireReflection = FALSE;
event = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i];
switch (event) {
@@ -1926,7 +2962,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;
@@ -1947,16 +2986,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
@@ -1964,7 +3002,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;
@@ -1973,39 +3014,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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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;
@@ -2080,27 +3150,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_fSoundIntensity = 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;
@@ -2112,7 +3183,8 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams& params)
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;
@@ -2127,20 +3199,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_fSoundIntensity = 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;
@@ -2172,23 +3245,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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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;
@@ -2204,7 +3385,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;
@@ -2220,24 +3401,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;
@@ -2252,13 +3443,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_fSoundIntensity = 40.0f;
+ m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
++CrunchOffset;
maxDist = SQR(SOUND_INTENSITY);
emittingVol = m_anRandomTable[4] % 20 + 55;
@@ -2269,14 +3461,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_fSoundIntensity = SOUND_INTENSITY;
@@ -2300,13 +3493,50 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams& params)
SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
m_sQueueSample.m_nEmittingVolume = emittingVol;
m_sQueueSample.m_bReverbFlag = TRUE;
+ if (isHeli) {
+ if (0.2f * m_sQueueSample.m_fSoundIntensity > 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)
{
@@ -2370,31 +3600,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;
+ m_sQueueSample.m_nEmittingVolume = Vol;
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
+ m_sQueueSample.m_fSoundIntensity = intensity;
+ m_sQueueSample.m_bReleasingSoundFlag = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 7;
+ m_sQueueSample.m_bReverbFlag = TRUE;
+ m_sQueueSample.m_bRequireReflection = FALSE;
+ AddSampleToRequestedQueue();
+ }
+ }
+
+ if(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;
@@ -2410,100 +3742,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;
- m_sQueueSample.m_nEmittingVolume = emittingVol;
- SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
- m_sQueueSample.m_fSpeedMultiplier = 2.0f;
- m_sQueueSample.m_fSoundIntensity = intensity;
- m_sQueueSample.m_bReleasingSoundFlag = FALSE;
- m_sQueueSample.m_nReleasingVolumeDivider = 7;
- m_sQueueSample.m_bReverbFlag = TRUE;
- m_sQueueSample.m_bRequireReflection = FALSE;
- } else {
- if (FindPlayerVehicle() == params.m_pVehicle) {
- 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;
- m_sQueueSample.m_nEmittingVolume = emittingVol;
- SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
- m_sQueueSample.m_fSpeedMultiplier = 2.0f;
- m_sQueueSample.m_fSoundIntensity = intensity;
- m_sQueueSample.m_bReleasingSoundFlag = FALSE;
- m_sQueueSample.m_nReleasingVolumeDivider = 7;
- m_sQueueSample.m_bReverbFlag = TRUE;
- m_sQueueSample.m_bRequireReflection = FALSE;
}
- AddSampleToRequestedQueue();
+ if(bIsPlayerVeh) {
+ LastFreq = Freq;
+ LastVol = Vol;
+ }
return TRUE;
}
return FALSE;
@@ -2541,7 +3784,7 @@ cAudioManager::ProcessBoatMovingOverWater(cVehicleParams& params)
m_sQueueSample.m_fSpeedMultiplier = 2.0f;
m_sQueueSample.m_fSoundIntensity = 50.0f;
m_sQueueSample.m_bReleasingSoundFlag = FALSE;
- m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 6;
m_sQueueSample.m_bReverbFlag = TRUE;
m_sQueueSample.m_bRequireReflection = FALSE;
AddSampleToRequestedQueue();
@@ -2550,61 +3793,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;
- m_sQueueSample.m_nEmittingVolume = emittingVol;
- SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
- m_sQueueSample.m_fSpeedMultiplier = 6.0f;
- m_sQueueSample.m_fSoundIntensity = gHeliSfxRanges[i].m_fMaxDistance;
- m_sQueueSample.m_bReleasingSoundFlag = FALSE;
- m_sQueueSample.m_nReleasingVolumeDivider = 3;
- m_sQueueSample.m_bReverbFlag = TRUE;
- m_sQueueSample.m_bRequireReflection = FALSE;
- AddSampleToRequestedQueue();
- }
- }
- return TRUE;
-}
-
void
cAudioManager::ProcessPlane(cVehicleParams& params)
{
@@ -2616,7 +3804,6 @@ cAudioManager::ProcessPlane(cVehicleParams& params)
ProcessCesna(params);
break;
default:
- debug("Plane Model Id is %d\n, ", params.m_pVehicle->GetModelIndex());
break;
}
}
@@ -2637,33 +3824,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();
}
}
@@ -2681,25 +3864,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);
}
}
}
@@ -2843,12 +4024,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;
@@ -2863,7 +4043,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;
@@ -2908,7 +4088,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
@@ -2926,62 +4106,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;
- m_sQueueSample.m_nEmittingVolume = emittingVol;
- SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
- m_sQueueSample.m_fSpeedMultiplier = 4.0f;
- m_sQueueSample.m_fSoundIntensity = 7.0f;
- m_sQueueSample.m_bReleasingSoundFlag = FALSE;
- m_sQueueSample.m_nReleasingVolumeDivider = 5;
- m_sQueueSample.m_bReverbFlag = TRUE;
- m_sQueueSample.m_bRequireReflection = FALSE;
- AddSampleToRequestedQueue();
- }
- return;
- }
- }
-}
-
-void
cAudioManager::ProcessPedOneShots(cPedParams &params)
{
uint8 emittingVol;
@@ -2996,6 +4124,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++) {
@@ -3108,54 +4237,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;
@@ -3173,11 +4333,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_fSoundIntensity = 30.0f;
@@ -3188,14 +4385,106 @@ cAudioManager::ProcessPedOneShots(cPedParams &params)
m_sQueueSample.m_nEmittingVolume = 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_fSoundIntensity = 50.0f;
+ maxDist = SQR(50);
+ m_sQueueSample.m_nLoopCount = 0;
+ emittingVol = 100;
+ SET_LOOP_OFFSETS(SFX_CAR_CHAINSAW_IDLE)
+ m_sQueueSample.m_nEmittingVolume = 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_fSoundIntensity = 60.0f;
+ maxDist = SQR(60);
+ m_sQueueSample.m_nLoopCount = 0;
+ emittingVol = 100;
+ SET_LOOP_OFFSETS(SFX_CAR_CHAINSAW_ATTACK)
+ m_sQueueSample.m_nEmittingVolume = 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_fSoundIntensity = 60.0f;
+ maxDist = SQR(60);
+ m_sQueueSample.m_nLoopCount = 0;
+ emittingVol = 100;
+ SET_LOOP_OFFSETS(SFX_CAR_CHAINSAW_ATTACK)
+ m_sQueueSample.m_nEmittingVolume = 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_fSoundIntensity = 120.0f;
+ maxDist = SQR(120);
+ m_sQueueSample.m_nLoopCount = 1;
+ RESET_LOOP_OFFSETS
+ emittingVol = m_anRandomTable[0] % 20 + 80;
+ m_sQueueSample.m_nEmittingVolume = 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;
@@ -3205,38 +4494,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_fSoundIntensity = 50.0f;
- maxDist = SQR(50);
+ m_sQueueSample.m_fSoundIntensity = 120.0f;
+ maxDist = SQR(120);
m_sQueueSample.m_nLoopCount = 1;
RESET_LOOP_OFFSETS
emittingVol = m_anRandomTable[1] % 10 + 90;
m_sQueueSample.m_nEmittingVolume = emittingVol;
m_sQueueSample.m_bIs2D = FALSE;
m_sQueueSample.m_bReleasingSoundFlag = TRUE;
- if (m_bDynamicAcousticModelingStatus)
- m_sQueueSample.m_bRequireReflection = TRUE;
- else
- 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_fSoundIntensity = 80.0f;
- maxDist = SQR(80);
+ m_sQueueSample.m_fSoundIntensity = 120.0f;
+ maxDist = SQR(120);
m_sQueueSample.m_nLoopCount = 1;
RESET_LOOP_OFFSETS
- emittingVol = m_anRandomTable[3] % 15 + 70;
+ emittingVol = 127;
m_sQueueSample.m_nEmittingVolume = 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++;
@@ -3245,98 +4535,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_fSoundIntensity = 60.0f;
- maxDist = SQR(60);
+ m_sQueueSample.m_fSoundIntensity = 120.0f;
+ maxDist = SQR(120);
m_sQueueSample.m_nLoopCount = 1;
RESET_LOOP_OFFSETS
emittingVol = m_anRandomTable[2] % 10 + 100;
m_sQueueSample.m_nEmittingVolume = emittingVol;
m_sQueueSample.m_bIs2D = FALSE;
m_sQueueSample.m_bReleasingSoundFlag = TRUE;
- if (m_bDynamicAcousticModelingStatus)
- m_sQueueSample.m_bRequireReflection = TRUE;
- else
- 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_fSoundIntensity = 80.0f;
- maxDist = SQR(80);
+ m_sQueueSample.m_fSoundIntensity = 120.0f;
+ maxDist = SQR(120);
m_sQueueSample.m_nLoopCount = 1;
RESET_LOOP_OFFSETS
- emittingVol = m_anRandomTable[1] % 15 + 70;
+ emittingVol = m_anRandomTable[2] % 10 + 100;
m_sQueueSample.m_nEmittingVolume = emittingVol;
m_sQueueSample.m_bIs2D = FALSE;
m_sQueueSample.m_bReleasingSoundFlag = TRUE;
+ m_sQueueSample.m_bRequireReflection = TRUE;
+ stereo = TRUE;
break;
- case WEAPONTYPE_M16:
- m_sQueueSample.m_nSampleIndex = SFX_M16_LEFT;
+ 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 = SampleManager.GetSampleBaseFrequency(SFX_M16_LEFT);
+ m_sQueueSample.m_nFrequency = RandomDisplacement(500) + 17000;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_fSoundIntensity = 120.0f;
+ maxDist = SQR(120);
+ m_sQueueSample.m_nLoopCount = 1;
+ RESET_LOOP_OFFSETS
+ emittingVol = m_anRandomTable[3] % 15 + 70;
+ m_sQueueSample.m_nEmittingVolume = emittingVol;
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_bReleasingSoundFlag = TRUE;
+ stereo = TRUE;
+ break;
+ 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_UZI_LEFT);
m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32);
m_sQueueSample.m_nReleasingVolumeModificator = 3;
m_sQueueSample.m_fSpeedMultiplier = 0.0f;
- m_sQueueSample.m_fSoundIntensity = 80.0f;
- maxDist = SQR(80);
+ m_sQueueSample.m_fSoundIntensity = 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;
m_sQueueSample.m_nEmittingVolume = 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_fSoundIntensity = 120.0f;
+ maxDist = SQR(120);
+ m_sQueueSample.m_nLoopCount = 1;
+ RESET_LOOP_OFFSETS
+ emittingVol = m_anRandomTable[3] % 15 + 70;
+ m_sQueueSample.m_nEmittingVolume = 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_fSoundIntensity = 60.0f;
- maxDist = SQR(60);
+ m_sQueueSample.m_fSoundIntensity = 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;
m_sQueueSample.m_nEmittingVolume = 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_fSoundIntensity = 120.0f;
+ maxDist = SQR(120);
+ m_sQueueSample.m_nLoopCount = 1;
+ RESET_LOOP_OFFSETS
+ emittingVol = m_anRandomTable[3] % 15 + 90;
+ m_sQueueSample.m_nEmittingVolume = 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_fSoundIntensity = 90.0f;
- maxDist = SQR(90);
+ m_sQueueSample.m_fSoundIntensity = 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;
m_sQueueSample.m_nEmittingVolume = 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_fSoundIntensity = 120.0f;
+ maxDist = SQR(120);
+ m_sQueueSample.m_nLoopCount = 1;
+ RESET_LOOP_OFFSETS
+ emittingVol = m_anRandomTable[4] % 10 + 110;
+ m_sQueueSample.m_nEmittingVolume = 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;
@@ -3354,47 +4718,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_fSoundIntensity = 120.0f;
+ maxDist = SQR(120);
+ m_sQueueSample.m_nLoopCount = 1;
+ RESET_LOOP_OFFSETS
+ emittingVol = 127;
+ m_sQueueSample.m_nEmittingVolume = 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;
}
@@ -3415,29 +4798,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_fSoundIntensity = 80.0f;
- maxDist = SQR(80);
+ m_sQueueSample.m_fSoundIntensity = 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;
m_sQueueSample.m_nEmittingVolume = 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;
@@ -3474,6 +4898,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++;
@@ -3491,6 +4918,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_fSoundIntensity = 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
+ m_sQueueSample.m_nEmittingVolume = 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_fSoundIntensity = 20.0f;
+ maxDist = SQR(20);
+ m_sQueueSample.m_nLoopCount = 1;
+ RESET_LOOP_OFFSETS
+ emittingVol = (m_anRandomTable[2] % 20 + 70) * param1 / 127;
+ m_sQueueSample.m_nEmittingVolume = 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_fSoundIntensity = 150.0f;
+ emittingVol = 127;
+ maxDist = SQR(150);
+ m_sQueueSample.m_nLoopCount = 0;
+ SET_LOOP_OFFSETS(SFX_MINIGUN_FIRE_LEFT)
+ m_sQueueSample.m_nEmittingVolume = 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_fSoundIntensity = 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)
+ m_sQueueSample.m_nEmittingVolume = 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_fSoundIntensity = 150.0f;
+ maxDist = SQR(150);
+ m_sQueueSample.m_nLoopCount = 1;
+ RESET_LOOP_OFFSETS
+ emittingVol = 127;
+ m_sQueueSample.m_nEmittingVolume = 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_fSoundIntensity = 15.0f;
+ maxDist = SQR(15);
+ m_sQueueSample.m_nLoopCount = 0;
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
+ m_sQueueSample.m_nEmittingVolume = emittingVol;
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_bReleasingSoundFlag = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ }
+ }
+ continue;
default:
SetupPedComments(params, sound);
continue;
@@ -3531,6 +5116,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;
@@ -3538,236 +5177,199 @@ 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_bVolume = m_sQueueSample.m_nVolume;
- m_sPedComments.Add(&pedComment);
- }
+ 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_bVolume = m_sQueueSample.m_nVolume;
+ 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
@@ -3784,2209 +5386,2433 @@ 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;
+}
- 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);
+uint32
+cAudioManager::GetWMYBETalkSfx(CPed *ped, uint16 sound)
+{
+ uint32 sfx;
+
+ 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;
+}
+
+uint32
+cAudioManager::GetWFYPRTalkSfx(CPed *ped, uint16 sound)
+{
+ uint32 sfx;
- return GetGenericMaleTalkSfx(sound);
+ 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_bVolume = 99;
+
+ pedComment.m_vecPos = CWorld::Players[0].m_pPed->GetPosition();
+
+ m_sPedComments.Add(&pedComment);
+}
+
void
cPedComments::Add(tPedComment *com)
{
@@ -6020,59 +7846,71 @@ 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_bVolume;
- 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_nEmittingVolume = MAX_VOLUME;
- AudioManager.m_sQueueSample.m_fSpeedMultiplier = 3.0f;
- switch (sampleIndex) {
- case SFX_POLICE_HELI_1:
- case SFX_POLICE_HELI_2:
- case SFX_POLICE_HELI_3:
- AudioManager.m_sQueueSample.m_fSoundIntensity = 400.0f;
- break;
- default:
- AudioManager.m_sQueueSample.m_fSoundIntensity = 50.0f;
- break;
+ 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;
+ }
}
- 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;
+ 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_bVolume;
+ 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
+ AudioManager.m_sQueueSample.m_nEmittingVolume = MAX_VOLUME;
+ AudioManager.m_sQueueSample.m_fSpeedMultiplier = 3.0f;
+ AudioManager.m_sQueueSample.m_fSoundIntensity = 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
@@ -6095,8 +7933,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
@@ -6105,11 +7949,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) {
@@ -6117,39 +7960,41 @@ cAudioManager::ProcessExplosions(int32 explosion)
case EXPLOSION_ROCKET:
case EXPLOSION_BARREL:
case EXPLOSION_TANK_GRENADE:
- m_sQueueSample.m_fSoundIntensity = 400.0f;
+ m_sQueueSample.m_fSoundIntensity = 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_fSoundIntensity = 200.0f;
+ m_sQueueSample.m_fSoundIntensity = 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_fSoundIntensity = 300.0f;
+ m_sQueueSample.m_fSoundIntensity = 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_fSoundIntensity = 400.0f;
+ m_sQueueSample.m_fSoundIntensity = 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_fSoundIntensity)) {
m_sQueueSample.m_fDistance = Sqrt(distSquared);
@@ -6160,11 +8005,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;
m_sQueueSample.m_nEmittingVolume = MAX_VOLUME;
RESET_LOOP_OFFSETS
m_sQueueSample.m_bReverbFlag = TRUE;
- m_sQueueSample.m_bRequireReflection = TRUE;
AddSampleToRequestedQueue();
}
}
@@ -6185,7 +8028,7 @@ cAudioManager::ProcessFires(int32)
if (entity) {
switch (entity->GetType()) {
case ENTITY_TYPE_BUILDING:
- m_sQueueSample.m_fSoundIntensity = 50.0f;
+ m_sQueueSample.m_fSoundIntensity = 80.0f;
m_sQueueSample.m_nSampleIndex = SFX_CAR_ON_FIRE;
emittingVol = 100;
m_sQueueSample.m_nFrequency = 8 * SampleManager.GetSampleBaseFrequency(SFX_CAR_ON_FIRE) / 10;
@@ -6201,7 +8044,7 @@ cAudioManager::ProcessFires(int32)
m_sQueueSample.m_nReleasingVolumeModificator = 10;
break;
default:
- m_sQueueSample.m_fSoundIntensity = 50.0f;
+ m_sQueueSample.m_fSoundIntensity = 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);
@@ -6209,10 +8052,9 @@ cAudioManager::ProcessFires(int32)
m_sQueueSample.m_nReleasingVolumeModificator = 8;
}
} else {
- m_sQueueSample.m_fSoundIntensity = 50.0f;
+ m_sQueueSample.m_fSoundIntensity = 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;
}
@@ -6236,6 +8078,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_fSoundIntensity, 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;
+ m_sQueueSample.m_nEmittingVolume = emittingVol;
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
+ m_sQueueSample.m_bReverbFlag = TRUE;
+ m_sQueueSample.m_bRequireReflection = FALSE;
+ AddSampleToRequestedQueue();
+ }
+ }
}
}
}
@@ -6251,17 +8116,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_fSoundIntensity, m_sQueueSample.m_fDistance);
-#endif
if (m_sQueueSample.m_nVolume != 0) {
-#ifdef FIX_BUGS
m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
-#else
- m_sQueueSample.m_fSoundIntensity = SQR(SOUND_INTENSITY);
-#endif
m_sQueueSample.m_nSampleIndex = SFX_JUMBO_TAXI;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_nFrequency = 15591;
@@ -6290,13 +8147,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);
+ }
}
}
@@ -6310,37 +8169,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_fSoundIntensity = 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;
+ break;
+ case SCRIPT_SOUND_GARAGE_DOOR_CLUNK:
+ m_sQueueSample.m_fSoundIntensity = 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;
- emittingVolume = RandomDisplacement(10) + 50;
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:
@@ -6354,18 +8207,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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 80.0f;
@@ -6465,6 +8341,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_fSoundIntensity = 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) {
@@ -6477,21 +8365,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_fSoundIntensity = 20.0f;
@@ -6536,594 +8425,204 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
uint8 emittingVolume;
float distSquared;
- switch (sound) {
- case SCRIPT_SOUND_PARTY_1_LOOP_S:
- m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- m_sQueueSample.m_nSampleIndex = SFX_CLUB_1;
- m_sQueueSample.m_nBankIndex = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity = 50.0f;
- m_sQueueSample.m_nSampleIndex = SFX_CAR_ON_FIRE;
+ case SCRIPT_SOUND_NEW_WATERFALL:
+ emittingVolume = 30;
+ m_sQueueSample.m_fSoundIntensity = 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_fSoundIntensity)) {
+ if(distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) {
m_sQueueSample.m_fDistance = Sqrt(distSquared);
m_sQueueSample.m_nVolume = ComputeVolume(emittingVolume, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
+ if(m_sQueueSample.m_nVolume != 0) {
m_sQueueSample.m_nCounter = 0;
m_sQueueSample.m_bIs2D = FALSE;
m_sQueueSample.m_nLoopCount = 0;
@@ -7136,559 +8635,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_fSoundIntensity = 20.0f;
- break;
- case SCRIPT_SOUND_PORN_CINEMA_1_L:
- case SCRIPT_SOUND_MISTY_SEX_L:
- m_sQueueSample.m_nSampleIndex = SFX_PORN_1_LOOP;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_PORN_1;
- sample = SFX_PORN_1_GROAN_1;
- m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- break;
- case SCRIPT_SOUND_PORN_CINEMA_2_S:
- m_sQueueSample.m_nSampleIndex = SFX_PORN_2_LOOP;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_PORN_2;
- sample = SFX_PORN_2_GROAN_1;
- m_sQueueSample.m_fSoundIntensity = 20.0f;
- break;
- case SCRIPT_SOUND_PORN_CINEMA_2_L:
- m_sQueueSample.m_nSampleIndex = SFX_PORN_2_LOOP;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_PORN_2;
- sample = SFX_PORN_2_GROAN_1;
- m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- break;
- case SCRIPT_SOUND_PORN_CINEMA_3_S:
- m_sQueueSample.m_nSampleIndex = SFX_PORN_3_LOOP;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_PORN_3;
- m_sQueueSample.m_fSoundIntensity = 20.0f;
- sample = SFX_PORN_3_GROAN_1;
- break;
- case SCRIPT_SOUND_PORN_CINEMA_3_L:
- m_sQueueSample.m_nSampleIndex = SFX_PORN_3_LOOP;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_PORN_3;
- m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- sample = SFX_PORN_3_GROAN_1;
- break;
- default:
- return;
- }
- distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos);
- if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) {
- m_sQueueSample.m_fDistance = Sqrt(distSquared);
- if (sound != SCRIPT_SOUND_MISTY_SEX_S && sound != SCRIPT_SOUND_MISTY_SEX_L) {
- m_sQueueSample.m_nVolume = ComputeVolume(MAX_VOLUME, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nCounter = 0;
- m_sQueueSample.m_bIs2D = FALSE;
- m_sQueueSample.m_nLoopCount = 0;
- m_sQueueSample.m_bReleasingSoundFlag = FALSE;
- m_sQueueSample.m_nReleasingVolumeModificator = 3;
- m_sQueueSample.m_fSpeedMultiplier = 2.0f;
- m_sQueueSample.m_nEmittingVolume = MAX_VOLUME;
- 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_fSoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
- rand = m_anRandomTable[1] & 1;
- m_sQueueSample.m_nSampleIndex = rand + sample;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16);
- m_sQueueSample.m_nCounter = rand + 1;
- m_sQueueSample.m_bIs2D = FALSE;
- m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.m_bReleasingSoundFlag = TRUE;
- m_sQueueSample.m_nReleasingVolumeModificator = 6;
- m_sQueueSample.m_fSpeedMultiplier = 0.0f;
- 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_fSoundIntensity = 20.0f;
- break;
- default:
- return;
- }
- distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos);
- if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) {
- m_sQueueSample.m_fDistance = Sqrt(distSquared);
- m_sQueueSample.m_nVolume = ComputeVolume(30, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
- m_sQueueSample.m_nSampleIndex = SFX_WORKSHOP_1;
- m_sQueueSample.m_nBankIndex = 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;
- m_sQueueSample.m_nEmittingVolume = 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_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- break;
- default:
- return;
- }
- distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos);
- if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) {
- m_sQueueSample.m_fDistance = Sqrt(distSquared);
- m_sQueueSample.m_nVolume = ComputeVolume(30, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
- m_sQueueSample.m_nSampleIndex = SFX_SAWMILL_LOOP;
- m_sQueueSample.m_nBankIndex = 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;
- m_sQueueSample.m_nEmittingVolume = 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_fSoundIntensity, 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;
- 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_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- break;
- default:
- return;
- }
- float distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos);
- if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) {
- m_sQueueSample.m_fDistance = Sqrt(distSquared);
- m_sQueueSample.m_nVolume = ComputeVolume(45, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
- m_sQueueSample.m_nSampleIndex = SFX_LAUNDERETTE_LOOP;
- m_sQueueSample.m_nBankIndex = 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;
- m_sQueueSample.m_nEmittingVolume = 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_fSoundIntensity, 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;
- m_sQueueSample.m_nEmittingVolume = 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_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- break;
- default:
- return;
- }
- distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos);
- if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) {
- m_sQueueSample.m_fDistance = Sqrt(distSquared);
- m_sQueueSample.m_nVolume = ComputeVolume(30, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
- m_sQueueSample.m_nSampleIndex = SFX_SHOP_LOOP;
- m_sQueueSample.m_nBankIndex = 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;
- m_sQueueSample.m_nEmittingVolume = 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_fSoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
- rand = m_anRandomTable[1] & 1;
- m_sQueueSample.m_nSampleIndex = rand + SFX_SHOP_TILL_1;
- m_sQueueSample.m_nBankIndex = 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;
- m_sQueueSample.m_nEmittingVolume = 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_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- break;
- case SCRIPT_SOUND_AIRPORT_LOOP_L:
- m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- break;
- default:
- return;
- }
- float distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos);
- if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) {
- m_sQueueSample.m_fDistance = Sqrt(distSquared);
- m_sQueueSample.m_nVolume = ComputeVolume(110, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
- m_sQueueSample.m_nSampleIndex = (m_anRandomTable[1] & 3) + SFX_AIRPORT_ANNOUNCEMENT_1;
- m_sQueueSample.m_nBankIndex = 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;
- m_sQueueSample.m_nEmittingVolume = 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_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- break;
- case SCRIPT_SOUND_CINEMA_LOOP_L:
- m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- break;
- default:
- return;
- }
- float distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos);
- if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) {
- m_sQueueSample.m_fDistance = Sqrt(distSquared);
- rand = m_anRandomTable[0] % 90 + 30;
- m_sQueueSample.m_nVolume = ComputeVolume(rand, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
- m_sQueueSample.m_nSampleIndex = iSound % 3 + SFX_CINEMA_BASS_1;
- m_sQueueSample.m_nBankIndex = 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;
- m_sQueueSample.m_nEmittingVolume = 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_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- break;
- case SCRIPT_SOUND_DOCKS_LOOP_L:
- m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- break;
- default:
- return;
- }
- distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos);
- if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) {
- m_sQueueSample.m_fDistance = Sqrt(distSquared);
- rand = m_anRandomTable[0] % 60 + 40;
- m_sQueueSample.m_nVolume = ComputeVolume(rand, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
- m_sQueueSample.m_nSampleIndex = SFX_DOCKS_FOGHORN;
- m_sQueueSample.m_nBankIndex = 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;
- m_sQueueSample.m_nEmittingVolume = 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_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- break;
- case SCRIPT_SOUND_HOME_LOOP_L:
- m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- break;
- default:
- return;
- }
- dist = GetDistanceSquared(m_sQueueSample.m_vecPos);
- if (dist < SQR(m_sQueueSample.m_fSoundIntensity)) {
- m_sQueueSample.m_fDistance = Sqrt(dist);
- rand = m_anRandomTable[0] % 30 + 40;
- m_sQueueSample.m_nVolume = ComputeVolume(rand, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
- m_sQueueSample.m_nSampleIndex = m_anRandomTable[0] % 5 + SFX_HOME_1;
- m_sQueueSample.m_nBankIndex = 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;
- m_sQueueSample.m_nEmittingVolume = 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_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- break;
- case SCRIPT_SOUND_POLICE_CELL_BEATING_LOOP_L:
- m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- break;
- default:
- return;
- }
- distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos);
- if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) {
- m_sQueueSample.m_fDistance = Sqrt(distSquared);
- if (m_FrameCounter & 1)
- sampleIndex = (m_anRandomTable[1] & 3) + SFX_FIGHT_1;
- else
- sampleIndex = (m_anRandomTable[3] & 1) + SFX_BAT_HIT_LEFT;
- m_sQueueSample.m_nSampleIndex = sampleIndex;
- emittingVol = m_anRandomTable[0] % 50 + 55;
- m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
- m_sQueueSample.m_nBankIndex = 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;
- m_sQueueSample.m_nEmittingVolume = 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 && m_asAudioEntities[id].m_awAudioEvent[0] == SOUND_LIGHTNING) {
+ if (m_asAudioEntities[id].m_AudioEvents != 0 && m_asAudioEntities[id].m_awAudioEvent[0] == SOUND_LIGHTNING) {
if (m_asAudioEntities[id].m_afVolume[0] >= 10.f) {
m_sQueueSample.m_nSampleIndex = SFX_EXPLOSION_1;
m_sQueueSample.m_nBankIndex = SFX_BANK_GENERIC_EXTRA;
m_sQueueSample.m_nFrequency = RandomDisplacement(500) + 4000;
- vol = (m_asAudioEntities[id].m_afVolume[0] - 10.f) + 40;
+ vol = (m_asAudioEntities[id].m_afVolume[0] - 10.0f) + 40;
} else {
m_sQueueSample.m_nSampleIndex = SFX_EXPLOSION_2;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
@@ -7696,7 +8661,7 @@ cAudioManager::ProcessWeather(int32 id)
vol = (m_asAudioEntities[id].m_afVolume[0]) + 35;
}
m_sQueueSample.m_nVolume = vol;
- if (TheCamera.SoundDistUp < 20.f)
+ if (TheCamera.SoundDistUp < 20.0f)
m_sQueueSample.m_nVolume /= 2;
if (iSound == 4)
iSound = 0;
@@ -7715,7 +8680,7 @@ cAudioManager::ProcessWeather(int32 id)
if (CWeather::Rain > 0.0f && (!CCullZones::CamNoRain() || !CCullZones::PlayerNoRain())) {
m_sQueueSample.m_nSampleIndex = SFX_RAIN;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RAIN);
- m_sQueueSample.m_nVolume = (int32)(25.f * CWeather::Rain);
+ m_sQueueSample.m_nVolume = (uint8)(25.0f * CWeather::Rain);
m_sQueueSample.m_nCounter = 4;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_nReleasingVolumeModificator = 0;
@@ -7730,6 +8695,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;
+ m_sQueueSample.m_nEmittingVolume = m_sQueueSample.m_nVolume;
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
+ m_sQueueSample.m_bRequireReflection = FALSE;
+ AddSampleToRequestedQueue();
+ CObject::fDistToNearestTree = 999999.9f;
+ }
}
void
@@ -7738,18 +8728,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;
@@ -7760,112 +8753,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_FRONTEND_STEREO:
- m_sQueueSample.m_nSampleIndex = SFX_STEREO_LEFT;
+ 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_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;
@@ -7882,29 +8885,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;
m_sQueueSample.m_nEmittingVolume = 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();
@@ -7914,10 +8938,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;
@@ -7965,42 +8996,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_fSoundIntensity = rocketLauncherIntensity;
- m_sQueueSample.m_nSampleIndex = SFX_ROCKET_FLY;
+ case WEAPONTYPE_TEARGAS:
+ emittingVol = 80;
+ m_sQueueSample.m_fSoundIntensity = 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_fSoundIntensity = molotovIntensity;
+ emittingVol = 50;
+ m_sQueueSample.m_fSoundIntensity = 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_fSoundIntensity = 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_fSoundIntensity)) {
m_sQueueSample.m_fDistance = Sqrt(distSquared);
m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
@@ -8021,6 +9058,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_fSoundIntensity = SOUND_INTENSITY;
+ m_sQueueSample.m_nCounter = i;
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_nLoopCount = 0;
+ m_sQueueSample.m_nEmittingVolume = 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;
+ m_sQueueSample.m_nEmittingVolume = EMITTING_VOLUME;
+ SET_LOOP_OFFSETS(SFX_ARCADE)
+ m_sQueueSample.m_bReverbFlag = TRUE;
+ m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
+ m_sQueueSample.m_bRequireReflection = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ AddSampleToRequestedQueue();
+ }
+ }
+ }
+}
+
+void
cAudioManager::ProcessGarages()
{
const float SOUND_INTENSITY = 80.0f;
@@ -8145,36 +9259,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;
m_sQueueSample.m_nEmittingVolume = 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_fSoundIntensity = intensity;
+ m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
m_sQueueSample.m_bReleasingSoundFlag = FALSE;
- m_sQueueSample.m_nReleasingVolumeDivider = 3;
- m_sQueueSample.m_bReverbFlag = TRUE;
m_sQueueSample.m_bRequireReflection = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
AddSampleToRequestedQueue();
}
}
}
-
+#ifdef GTA_BRIDGE
#pragma region BRIDGE
const int bridgeIntensity = 400;
@@ -8216,7 +9330,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);
@@ -8293,50 +9407,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)
@@ -8349,100 +9805,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;
+}
+
+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[slot]++ % 64) != 0;
+ }
+}
+
+bool8
+cAudioManager::IsMissionAudioSampleFinished(uint8 slot)
+{
+ if (m_bIsInitialised) {
+ if (slot < MISSION_AUDIO_SLOTS)
+ return m_sMissionAudio.m_nPlayStatus[slot] == PLAY_STATUS_FINISHED;
+ else
+ return TRUE;
+ }
- static int32 cPretendFrame = 1;
+ static int32 cPretendFrame[MISSION_AUDIO_SLOTS] = { 1, 1 };
- return (cPretendFrame++ & 63) == 0;
+ return (cPretendFrame[slot]++ % 64) == 0;
}
void
-cAudioManager::ClearMissionAudio()
+cAudioManager::ClearMissionAudio(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 (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::ProcessMissionAudio()
+cAudioManager::ProcessMissionAudioSlot(uint8 slot)
{
float dist;
uint8 emittingVol;
@@ -8450,104 +9936,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:
@@ -8555,15 +10074,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 22415e76..ad76b73a 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;
@@ -109,9 +111,7 @@ cAudioManager::Service()
if (m_bIsInitialised) {
m_nPreviousUserPause = m_nUserPause;
m_nUserPause = CTimer::GetIsUserPaused();
-#ifdef GTA_PC
UpdateReflections();
-#endif
ServiceSoundEffects();
MusicManager.Service();
}
@@ -186,11 +186,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) {
@@ -246,6 +246,12 @@ cAudioManager::SetMusicMasterVolume(uint8 volume)
}
void
+cAudioManager::SetMP3BoostVolume(uint8 volume)
+{
+ SampleManager.SetMP3BoostVolume(volume);
+}
+
+void
cAudioManager::SetEffectsFadeVol(uint8 volume)
{
SampleManager.SetEffectsFadeVolume(volume);
@@ -258,9 +264,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
@@ -280,11 +286,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
@@ -303,7 +311,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);
@@ -360,6 +368,15 @@ cAudioManager::GetCurrent3DProviderIndex()
}
int8
+cAudioManager::AutoDetect3DProviders()
+{
+ if (m_bIsInitialised)
+ return SampleManager.AutoDetect3DProviders();
+
+ return -1;
+}
+
+int8
cAudioManager::SetCurrent3DProvider(uint8 which)
{
if (!m_bIsInitialised)
@@ -428,9 +445,7 @@ cAudioManager::CheckForAnAudioFileOnCD()
char
cAudioManager::GetCDAudioDriveLetter()
{
- if (m_bIsInitialised)
- return SampleManager.GetCDAudioDriveLetter();
-
+ if(m_bIsInitialised) return SampleManager.GetCDAudioDriveLetter();
return '\0';
}
@@ -466,7 +481,7 @@ cAudioManager::ServiceSoundEffects()
ClearActiveSamples();
}
m_nActiveSampleQueue = m_nActiveSampleQueue == 1 ? 0 : 1;
- ProcessReverb();
+ if(m_bReverb) ProcessReverb();
ProcessSpecial();
ClearRequestedQueue();
InterrogateAudioEntities();
@@ -491,22 +506,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(127u, newEmittingVolume);
}
void
@@ -515,13 +530,23 @@ cAudioManager::TranslateEntity(Const CVector *in, CVector *out)
*out = MultiplyInverse(TheCamera.GetMatrix(), *in);
}
+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 uint8 PanTable[64] = {0, 3, 8, 12, 16, 19, 22, 24, 26, 28, 30, 31, 33, 34, 36, 37, 39, 40, 41, 42, 44, 45, 46, 47, 48, 49, 49, 50, 51, 52, 53, 53,
- 54, 55, 55, 56, 56, 57, 57, 58, 58, 58, 59, 59, 59, 60, 60, 61, 61, 61, 61, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 63, 63};
+ int32 index = Min(63, Abs(int32(vec->y / (dist / 64.f))));
- int32 index = Min(63, Abs(vec->x / (dist / 64.f)));
+ if (vec->y > 0.f)
+ return Max(0, 63 - PanTable[index]);
+ return Min(127, PanTable[index] + 63);
+}
+
+int32
+cAudioManager::ComputePan(float dist, CVector *vec)
+{
+ int32 index = Min(63, Abs(int32(vec->x / (dist / 64.f))));
if (vec->x > 0.f)
return Max(20, 63 - PanTable[index]);
@@ -537,11 +562,7 @@ cAudioManager::ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1,
if (dist != 0.0f) {
float speedOfSource = (dist / m_nTimeSpent) * speedMultiplier;
if (m_fSpeedOfSound > Abs(speedOfSource)) {
- if (speedOfSource < 0.0f) {
- speedOfSource = Max(speedOfSource, -1.5f);
- } else {
- speedOfSource = Min(speedOfSource, 1.5f);
- }
+ speedOfSource = Clamp2(speedOfSource, 0.0f, 1.5f);
newFreq = (oldFreq * m_fSpeedOfSound) / (speedOfSource + m_fSpeedOfSound);
}
}
@@ -599,7 +620,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;
}
@@ -611,6 +632,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;
@@ -643,26 +667,52 @@ cAudioManager::AddDetailsToRequestedOrderList(uint8 sample)
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_fSoundIntensity /= 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_fSoundIntensity) {
- 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];
m_sQueueSample.m_nEmittingVolume = emittingVolume;
m_sQueueSample.m_nVolume = ComputeVolume(emittingVolume, m_sQueueSample.m_fSoundIntensity, 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];
@@ -671,50 +721,84 @@ cAudioManager::AddReflectionsToRequestedQueue()
}
}
}
+ m_sQueueSample.m_vecPos = oldPos;
+ m_sQueueSample.m_fDistance = oldDist;
}
void
cAudioManager::UpdateReflections()
{
- const CVector &camPos = TheCamera.GetPosition();
+ CVector camPos = TheCamera.GetPosition();
CColPoint colpoint;
CEntity *ent;
if (m_FrameCounter % 8 == 0) {
m_avecReflectionsPos[0] = camPos;
- m_avecReflectionsPos[0].y += 50.f;
+ 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] = 50.0f;
+ m_afReflectionsDistances[0] = 100.0f;
+
} else if ((m_FrameCounter + 1) % 8 == 0) {
m_avecReflectionsPos[1] = camPos;
- m_avecReflectionsPos[1].y -= 50.0f;
+ 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] = 50.0f;
+ m_afReflectionsDistances[1] = 100.0f;
+
} else if ((m_FrameCounter + 2) % 8 == 0) {
m_avecReflectionsPos[2] = camPos;
- m_avecReflectionsPos[2].x -= 50.0f;
+ 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] = 50.0f;
+ m_afReflectionsDistances[2] = 100.0f;
+
} else if ((m_FrameCounter + 3) % 8 == 0) {
m_avecReflectionsPos[3] = camPos;
- m_avecReflectionsPos[3].x += 50.0f;
+ 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] = 50.0f;
+ m_afReflectionsDistances[3] = 100.0f;
+
} else if ((m_FrameCounter + 4) % 8 == 0) {
+ camPos.y += 1.0f;
m_avecReflectionsPos[4] = camPos;
- m_avecReflectionsPos[4].z += 50.0f;
+ 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] = 50.0f;
+ m_afReflectionsDistances[4] = 100.0f;
+
+ } else if ((m_FrameCounter + 5) % 8 == 0) {
+ 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.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.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 // GTA_PC
@@ -768,7 +852,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();
@@ -779,39 +863,41 @@ cAudioManager::AddReleasingSounds()
void
cAudioManager::ProcessActiveQueues()
{
- bool8 flag;
- float position2;
- float position1;
-
- uint32 v28;
- uint32 v29;
-
- float x;
- float usedX;
- float usedY;
- float usedZ;
-
- uint8 vol;
- uint8 emittingVol;
CVector position;
+ uint32 freqDivided;
+ uint32 loopCount;
+ uint8 emittingVol;
+ uint8 vol;
+ uint8 offset;
+ float x;
+ bool8 flag;
+ bool8 missionState;
for (int32 i = 0; i < m_nActiveSamples; i++) {
m_asSamples[m_nActiveSampleQueue][i].m_bIsProcessed = FALSE;
m_asActiveSamples[i].m_bIsProcessed = FALSE;
}
-
- for (int32 i = 0; i < m_SampleRequestQueuesStatus[m_nActiveSampleQueue]; ++i) {
- tSound &sample = m_asSamples[m_nActiveSampleQueue][m_abSampleQueueIndexTable[m_nActiveSampleQueue][i]];
+ for (int32 i = 0; i < m_SampleRequestQueuesStatus[m_nActiveSampleQueue]; i++) {
+ tSound& sample = m_asSamples[m_nActiveSampleQueue][m_abSampleQueueIndexTable[m_nActiveSampleQueue][i]];
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) {
+ 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) {
if (sample.m_nLoopCount) {
+
if (m_FrameCounter & 1) {
- flag = !!(j & 1);
+ if (!(j & 1)) {
+ flag = FALSE;
+ } else {
+ flag = TRUE;
+ }
+ } else if (j & 1) {
+ flag = FALSE;
} else {
- flag = !(j & 1);
+ flag = TRUE;
}
+
if (flag && !SampleManager.GetChannelUsedFlag(j)) {
sample.m_bLoopEnded = TRUE;
m_asActiveSamples[j].m_bLoopEnded = TRUE;
@@ -819,6 +905,8 @@ cAudioManager::ProcessActiveQueues()
m_asActiveSamples[j].m_nEntityIndex = AEHANDLE_NONE;
continue;
}
+ if (!sample.m_nReleasingVolumeDivider)
+ sample.m_nReleasingVolumeDivider = 1;
}
sample.m_bIsProcessed = TRUE;
m_asActiveSamples[j].m_bIsProcessed = TRUE;
@@ -834,37 +922,39 @@ cAudioManager::ProcessActiveQueues()
SampleManager.SetChannelEmittingVolume(j, emittingVol);
} else {
m_asActiveSamples[j].m_fDistance = sample.m_fDistance;
- position2 = sample.m_fDistance;
- position1 = m_asActiveSamples[j].m_fDistance;
- sample.m_nFrequency = ComputeDopplerEffectedFrequency(sample.m_nFrequency, position1, position2, sample.m_fSpeedMultiplier);
+ sample.m_nFrequency = ComputeDopplerEffectedFrequency(
+ sample.m_nFrequency,
+ m_asActiveSamples[j].m_fDistance,
+ sample.m_fDistance,
+ sample.m_fSpeedMultiplier);
+
if (sample.m_nFrequency != m_asActiveSamples[j].m_nFrequency) {
- int32 freq;
- if (sample.m_nFrequency <= m_asActiveSamples[j].m_nFrequency) {
-#ifdef FIX_BUGS
- freq = Max((int32)sample.m_nFrequency, (int32)m_asActiveSamples[j].m_nFrequency - 6000);
-#else
- freq = Max((int32)sample.m_nFrequency, int32(m_asActiveSamples[j].m_nFrequency - 6000));
-#endif
- } else {
- freq = Min(sample.m_nFrequency, m_asActiveSamples[j].m_nFrequency + 6000);
- }
- m_asActiveSamples[j].m_nFrequency = freq;
- SampleManager.SetChannelFrequency(j, freq);
+ m_asActiveSamples[j].m_nFrequency = Clamp2((int32)sample.m_nFrequency, (int32)m_asActiveSamples[j].m_nFrequency, 6000);
+ SampleManager.SetChannelFrequency(j, m_asActiveSamples[j].m_nFrequency);
}
-
if (sample.m_nEmittingVolume != m_asActiveSamples[j].m_nEmittingVolume) {
- if (sample.m_nEmittingVolume <= m_asActiveSamples[j].m_nEmittingVolume) {
- vol = Max(m_asActiveSamples[j].m_nEmittingVolume - 10, sample.m_nEmittingVolume);
- } else {
- vol = Min(m_asActiveSamples[j].m_nEmittingVolume + 10, sample.m_nEmittingVolume);
- }
+ vol = Clamp2((int8)sample.m_nEmittingVolume, (int8)m_asActiveSamples[j].m_nEmittingVolume, 10);
- uint8 emittingVol;
if (field_4) {
emittingVol = 2 * Min(63, vol);
} else {
emittingVol = vol;
}
+
+ missionState = FALSE;
+ for (int32 k = 0; k < ARRAY_SIZE(m_sMissionAudio.m_bIsMobile); 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;
+ }
+
SampleManager.SetChannelEmittingVolume(j, emittingVol);
m_asActiveSamples[j].m_nEmittingVolume = vol;
}
@@ -873,10 +963,11 @@ cAudioManager::ProcessActiveQueues()
SampleManager.SetChannel3DDistances(j, sample.m_fSoundIntensity, 0.25f * sample.m_fSoundIntensity);
}
SampleManager.SetChannelReverbFlag(j, sample.m_bReverbFlag);
- break;
+ break; //continue for i
}
sample.m_bIsProcessed = FALSE;
m_asActiveSamples[j].m_bIsProcessed = FALSE;
+ //continue for j
}
}
}
@@ -888,59 +979,69 @@ cAudioManager::ProcessActiveQueues()
m_asActiveSamples[i].m_nEntityIndex = AEHANDLE_NONE;
}
}
- for (uint8 i = 0; i < m_SampleRequestQueuesStatus[m_nActiveSampleQueue]; ++i) {
- tSound &sample = m_asSamples[m_nActiveSampleQueue][m_abSampleQueueIndexTable[m_nActiveSampleQueue][i]];
- if (!sample.m_bIsProcessed && !sample.m_bLoopEnded && m_asAudioEntities[sample.m_nEntityIndex].m_bIsUsed && sample.m_nSampleIndex < NO_SAMPLE) {
+ for (uint8 i = 0; i < m_SampleRequestQueuesStatus[m_nActiveSampleQueue]; i++) {
+ tSound& sample = m_asSamples[m_nActiveSampleQueue][m_abSampleQueueIndexTable[m_nActiveSampleQueue][i]];
+ if (!sample.m_bIsProcessed && !sample.m_bLoopEnded &&
+ m_asAudioEntities[sample.m_nEntityIndex].m_bIsUsed && sample.m_nSampleIndex < NO_SAMPLE) {
if (sample.m_nCounter > 255 && sample.m_nLoopCount && sample.m_nLoopsRemaining) {
- --sample.m_nLoopsRemaining;
+ sample.m_nLoopsRemaining--;
sample.m_nReleasingVolumeDivider = 1;
} else {
- for (uint8 j = 0; j < m_nActiveSamples; ++j) {
- if (!m_asActiveSamples[j].m_bIsProcessed) {
- if (sample.m_nLoopCount) {
- v28 = sample.m_nFrequency / m_nTimeSpent;
- v29 = sample.m_nLoopCount * SampleManager.GetSampleLength(sample.m_nSampleIndex);
- if (v28 == 0)
+ for (uint8 j = 0; j < m_nActiveSamples; j++) {
+ uint8 k = (j + field_6) % m_nActiveSamples;
+ if (!m_asActiveSamples[k].m_bIsProcessed) {
+ if (sample.m_nLoopCount != 0) {
+ freqDivided = sample.m_nFrequency / m_nTimeSpent;
+ loopCount = sample.m_nLoopCount * SampleManager.GetSampleLength(sample.m_nSampleIndex);
+ if (freqDivided == 0)
continue;
- sample.m_nReleasingVolumeDivider = v29 / v28 + 1;
+ sample.m_nReleasingVolumeDivider = loopCount / freqDivided + 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);
if (field_4) {
- emittingVol = 2 * Min(63, m_asActiveSamples[j].m_nEmittingVolume);
+ emittingVol = 2 * Min(63, m_asActiveSamples[k].m_nEmittingVolume);
} else {
- emittingVol = m_asActiveSamples[j].m_nEmittingVolume;
+ emittingVol = m_asActiveSamples[k].m_nEmittingVolume;
}
- if (SampleManager.InitialiseChannel(j, m_asActiveSamples[j].m_nSampleIndex, m_asActiveSamples[j].m_nBankIndex)) {
- SampleManager.SetChannelFrequency(j, m_asActiveSamples[j].m_nFrequency);
- SampleManager.SetChannelEmittingVolume(j, emittingVol);
- 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);
- if (m_asActiveSamples[j].m_bIs2D) {
- uint8 offset = m_asActiveSamples[j].m_nOffset;
+ 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 < ARRAY_SIZE(m_sMissionAudio.m_bIsMobile); 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);
+ }
+ SampleManager.SetChannelEmittingVolume(k, vol);
+ 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);
+ if (m_asActiveSamples[k].m_bIs2D) {
+ offset = m_asActiveSamples[k].m_nOffset;
if (offset == 63) {
- x = 0.f;
+ x = 0.0f;
} else if (offset >= 63) {
- x = (offset - 63) * 1000.f / 63;
+ x = (offset - 63) * 1000.0f / 63;
} else {
- x = -(63 - offset) * 1000.f / 63;
+ x = -(63 - offset) * 1000.0f / 63; //same like line below
}
- usedX = x;
- usedY = 0.f;
- usedZ = 0.f;
- m_asActiveSamples[j].m_fSoundIntensity = 100000.0f;
- } else {
- usedX = position.x;
- usedY = position.y;
- usedZ = position.z;
+ position = CVector(x, 0.0f, 0.0f);
+ m_asActiveSamples[k].m_fSoundIntensity = 100000.0f;
}
- SampleManager.SetChannel3DPosition(j, usedX, usedY, usedZ);
- SampleManager.SetChannel3DDistances(j, m_asActiveSamples[j].m_fSoundIntensity, 0.25f * m_asActiveSamples[j].m_fSoundIntensity);
- SampleManager.StartChannel(j);
+ SampleManager.SetChannel3DPosition(k, position.x, position.y, position.z);
+ SampleManager.SetChannel3DDistances(k, m_asActiveSamples[k].m_fSoundIntensity, 0.25f * m_asActiveSamples[k].m_fSoundIntensity);
+ SampleManager.StartChannel(k);
}
- m_asActiveSamples[j].m_bIsProcessed = TRUE;
+ m_asActiveSamples[k].m_bIsProcessed = TRUE;
sample.m_bIsProcessed = TRUE;
sample.m_nVolumeChange = -1;
break;
@@ -949,6 +1050,7 @@ cAudioManager::ProcessActiveQueues()
}
}
}
+ field_6 %= m_nActiveSamples;
}
void
@@ -963,7 +1065,7 @@ cAudioManager::ClearRequestedQueue()
void
cAudioManager::ClearActiveSamples()
{
- for (int32 i = 0; i < m_nActiveSamples; i++) {
+ for (uint8 i = 0; i < m_nActiveSamples; i++) {
m_asActiveSamples[i].m_nEntityIndex = AEHANDLE_NONE;
m_asActiveSamples[i].m_nCounter = 0;
m_asActiveSamples[i].m_nSampleIndex = NO_SAMPLE;
diff --git a/src/audio/AudioManager.h b/src/audio/AudioManager.h
index 187a71a8..df978d5b 100644
--- a/src/audio/AudioManager.h
+++ b/src/audio/AudioManager.h
@@ -3,6 +3,8 @@
#include "audio_enums.h"
#include "AudioCollision.h"
#include "PolRadio.h"
+#include "VehicleModelInfo.h"
+#include "Vehicle.h"
class tSound
{
@@ -30,6 +32,7 @@ public:
uint8 m_nLoopsRemaining;
bool8 m_bRequireReflection; // Used for oneshots
uint8 m_nOffset;
+ uint8 field_4C;
int32 m_nReleasingVolumeDivider;
bool8 m_bIsProcessed;
bool8 m_bLoopEnded;
@@ -37,7 +40,7 @@ public:
int8 m_nVolumeChange;
};
-VALIDATE_SIZE(tSound, 92);
+VALIDATE_SIZE(tSound, 96);
class CPhysical;
class CAutomobile;
@@ -59,7 +62,7 @@ VALIDATE_SIZE(tAudioEntity, 40);
class tPedComment
{
public:
- int32 m_nSampleIndex;
+ uint32 m_nSampleIndex;
int32 m_nEntityIndex;
CVector m_vecPos;
float m_fDistance;
@@ -76,6 +79,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()
{
@@ -93,23 +100,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
@@ -146,6 +158,7 @@ public:
class cVehicleParams
{
public:
+ int32 m_VehicleType;
bool8 m_bDistanceCalculated;
float m_fDistance;
CVehicle *m_pVehicle;
@@ -155,6 +168,7 @@ public:
cVehicleParams()
{
+ m_VehicleType = -1;
m_bDistanceCalculated = false;
m_fDistance = 0.0f;
m_pVehicle = nil;
@@ -164,22 +178,17 @@ public:
}
};
-VALIDATE_SIZE(cVehicleParams, 0x18);
+VALIDATE_SIZE(cVehicleParams, 0x1C);
enum {
- /*
- REFLECTION_YMAX = 0, top
- REFLECTION_YMIN = 1, bottom
- REFLECTION_XMIN = 2, left
- REFLECTION_XMAX = 3, right
- REFLECTION_ZMAX = 4,
- */
-
- REFLECTION_TOP = 0,
- REFLECTION_BOTTOM,
- REFLECTION_LEFT,
- REFLECTION_RIGHT,
- REFLECTION_UP,
+ REFLECTION_NORTH = 0,
+ REFLECTION_SOUTH,
+ REFLECTION_WEST,
+ REFLECTION_EAST,
+ REFLECTION_CEIL_NORTH,
+ REFLECTION_CEIL_SOUTH,
+ REFLECTION_CEIL_WEST,
+ REFLECTION_CEIL_EAST,
MAX_REFLECTIONS,
};
@@ -190,11 +199,12 @@ class cAudioManager
{
public:
bool8 m_bIsInitialised;
- bool8 m_bReverb; // unused
+ uint8 m_bReverb; // unused
bool8 m_bFifthFrameFlag;
uint8 m_nActiveSamples;
uint8 field_4; // unused
bool8 m_bDynamicAcousticModelingStatus;
+ int8 field_6;
float m_fSpeedOfSound;
bool8 m_bTimerJustReset;
int32 m_nTimer;
@@ -212,6 +222,14 @@ public:
float m_afReflectionsDistances[NUM_AUDIO_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;
@@ -221,8 +239,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;
@@ -236,23 +259,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();
@@ -265,29 +290,29 @@ 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
+ void AddDetailsToRequestedOrderList(uint8 sample); // inlined in vc
#ifdef GTA_PC
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 GTA_PC
- 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
@@ -297,145 +322,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);
void 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);
@@ -443,51 +497,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();
@@ -496,7 +545,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);
@@ -506,7 +555,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); }
};
/*
@@ -527,7 +578,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 d6079191..28c18256 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 dc95622b..9b21ddb3 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
@@ -104,7 +120,7 @@ enum
#define MAXCHANNELS_SURROUND (MAXCHANNELS-4)
#define MAX2DCHANNELS 1
-#define MAX_STREAMS 2
+#define MAX_STREAMS 3
#define DIGITALRATE 32000
#define DIGITALBITS 16
@@ -114,7 +130,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" );
@@ -122,15 +138,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:
@@ -150,6 +170,8 @@ public:
int8 GetCurrent3DProviderIndex(void);
int8 SetCurrent3DProvider(uint8 which);
+
+ int8 AutoDetect3DProviders();
bool8 IsMP3RadioChannelAvailable(void);
@@ -166,6 +188,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);
@@ -185,7 +208,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);
@@ -201,463 +224,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 7c40d15d..95a094ba 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
///////////////////////////////////////////////////////////////
@@ -264,10 +260,63 @@ set_new_provider(S32 index)
return FALSE;
}
+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)
@@ -354,6 +403,63 @@ cSampleManager::SetCurrent3DProvider(uint8 nProvider)
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;
+}
+
static bool8
_ResolveLink(char const *path, char *out)
{
@@ -449,15 +555,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 )
{
@@ -467,12 +564,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;
@@ -496,10 +587,6 @@ _FindMP3s(void)
if ( _pMP3List == NULL )
{
FindClose(hFind);
-
- if ( f )
- fclose(f);
-
return;
}
@@ -522,9 +609,6 @@ _FindMP3s(void)
{
_pMP3List->pLinkPath = NULL;
}
-
- if ( f ) fprintf(f, " - OK\n");
-
bInitFirstEntry = FALSE;
}
else
@@ -533,8 +617,6 @@ _FindMP3s(void)
OutputDebugString(filepath);
- if ( f ) fprintf(f, " - not an MP3 or supported MP3 type\n");
-
bInitFirstEntry = TRUE;
}
@@ -550,8 +632,6 @@ _FindMP3s(void)
int32 filepathlen = strlen(filepath);
- if ( f ) fprintf(f, "\"%s\"", fd.cFileName);
-
if ( filepathlen > 0 )
{
if ( filepathlen > 4 )
@@ -562,12 +642,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;
@@ -578,8 +652,6 @@ _FindMP3s(void)
if ( filepathlen > MAX_PATH )
{
- if ( f ) fprintf(f, " - Filename and path too long - %s - IGNORED)\n", filepath);
-
continue;
}
}
@@ -618,17 +690,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");
}
}
}
@@ -641,8 +709,6 @@ _FindMP3s(void)
if ( filepathlen > 0 )
{
- if ( f ) fprintf(f, "\"%s\"", fd.cFileName);
-
if ( filepathlen > 4 )
{
if ( !strcmp(&filepath[filepathlen - 4], ".lnk") )
@@ -651,12 +717,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;
@@ -701,26 +761,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);
}
@@ -932,54 +982,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;
- }
-
- add_providers();
-
- 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];
@@ -1009,122 +1042,49 @@ 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
+
+ if ( DIG == NULL )
+ {
+ OutputDebugString(AIL_last_error());
+ Terminate();
+ return FALSE;
}
- break;
- }
- }
+ add_providers();
-#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;
+ m_szCDRomRootPath[0] = '\0';
-#ifdef PS2_AUDIO_PATHS
- f = fopen(PS2StreamedNameTable[0], "rb");
- if (!f)
-#endif
+ strcpy(m_WavFilesPath, m_szCDRomRootPath);
- f = fopen(StreamedNameTable[0], "rb");
-
- if ( f )
- {
- fclose(f);
-
- for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
+#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);
@@ -1132,39 +1092,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++ )
@@ -1193,7 +1283,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;
@@ -1208,10 +1298,6 @@ cSampleManager::Initialise(void)
}
}
- TRACE("bank");
-
- LoadSampleBank(SFX_BANK_0);
-
// mp3
TRACE("mp3");
{
@@ -1331,77 +1417,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
-
- strcat(filepath, PS2StreamedNameTable[AudioManager.m_anRandomTable[1] % TOTAL_STREAMED_SOUNDS]);
+ strcpy(filepath, m_MiscomPath);
+ strcat(filepath, StreamedNameTable[STREAMED_SOUND_MISSION_COMPLETED4]);
- 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
+ FILE *f = fopen(filepath, "rb");
- 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
@@ -1454,6 +1506,12 @@ cSampleManager::SetMusicMasterVolume(uint8 nVolume)
}
void
+cSampleManager::SetMP3BoostVolume(uint8 nVolume)
+{
+ m_nMP3BoostVolume = nVolume;
+}
+
+void
cSampleManager::SetEffectsFadeVolume(uint8 nVolume)
{
m_nEffectsFadeVolume = nVolume;
@@ -1563,14 +1621,6 @@ cSampleManager::LoadPedComment(uint32 nComment)
break;
}
-
- case MUSICMODE_FRONTEND:
- {
- if ( MusicManager.GetNextTrack() == STREAMED_SOUND_GAME_COMPLETED )
- return FALSE;
-
- break;
- }
}
}
@@ -1633,69 +1683,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;
@@ -1804,11 +1830,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] )
@@ -1844,8 +1870,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;
}
@@ -2045,7 +2070,7 @@ cSampleManager::StopChannel(uint32 nChannel)
}
void
-cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream)
+cSampleManager::PreloadStreamedFile(uint32 nFile, uint8 nStream)
{
if ( m_bInitialised )
{
@@ -2059,16 +2084,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);
}
@@ -2104,7 +2130,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;
@@ -2133,21 +2159,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;
@@ -2189,23 +2216,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;
@@ -2239,21 +2270,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;
@@ -2315,11 +2348,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;
@@ -2327,9 +2363,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);
}
@@ -2407,4 +2448,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 df912a9a..af4c54ad 100644
--- a/src/audio/sampman_null.cpp
+++ b/src/audio/sampman_null.cpp
@@ -114,6 +114,11 @@ cSampleManager::SetMusicMasterVolume(uint8 nVolume)
}
void
+cSampleManager::SetMP3BoostVolume(uint8 nVolume)
+{
+}
+
+void
cSampleManager::SetEffectsFadeVolume(uint8 nVolume)
{
}
@@ -124,7 +129,7 @@ cSampleManager::SetMusicFadeVolume(uint8 nVolume)
}
void
-cSampleManager::SetMonoMode(uint8 nMode)
+cSampleManager::SetMonoMode(bool8 nMode)
{
}
@@ -297,7 +302,7 @@ cSampleManager::StopChannel(uint32 nChannel)
}
void
-cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream)
+cSampleManager::PreloadStreamedFile(uint32 nFile, uint8 nStream)
{
ASSERT( nStream < MAX_STREAMS );
}
@@ -315,7 +320,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 );
@@ -337,7 +342,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 );
}
@@ -365,4 +370,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 9d656581..0ffcd09a 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 d2a82121..8e79fee1 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 &&
-#endif
- (FindPlayerPed()->m_pWanted->m_bIgnoredByEveryone || pVehicle->bIsLawEnforcer &&
- (FindPlayerPed()->m_pWanted->GetWantedLevel() == 0 || FindPlayerPed()->m_pWanted->m_bIgnoredByCops || CCullZones::NoPolice()))
-#ifdef FIX_BUGS
- )
+#ifdef FIX_BUGS // btw fixed in SA
+ if (FindPlayerVehicle() == pVehicle->AutoPilot.m_pTargetCar)
#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;
}
@@ -516,7 +590,26 @@ 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);
+ if (pVehicle->GetModelIndex() != MI_FIRETRUCK && pVehicle->GetModelIndex() == MI_AMBULAN)
+ pVehicle->pDriver->Say(SOUND_PED_LEAVE_VEHICLE);
+ }
+ 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);
}
}
}
@@ -553,6 +646,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()) {
@@ -605,6 +712,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)
@@ -629,6 +753,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 37312b89..6e1b5f21 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::GetModelInfo(pVehicle->GetModelIndex())->GetColModel()->boundingBox;
+ CBox* boundingBox = &CModelInfo::GetModelInfo(pVehicle->GetModelIndex())->GetColModel()->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::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, CVector* pPos, int* pClass) {
+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;
@@ -1315,22 +1566,24 @@ void CCarCtrl::WeaveThroughCarsSectorList(CPtrList& lst, CVehicle* pVehicle, CPh
void CCarCtrl::WeaveForOtherCar(CEntity* pOtherEntity, CVehicle* pVehicle, float* pAngleToWeaveLeft, float* pAngleToWeaveRight)
{
+ CVehicle* pOtherCar = (CVehicle*)pOtherEntity;
+ if (pVehicle->bPartOfConvoy && pOtherCar->bPartOfConvoy)
+ return;
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 +1623,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 +1728,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 +1755,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 +1800,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 +1810,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 +1820,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 +1968,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 +2038,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 +2097,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 +2106,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 +2192,7 @@ void CCarCtrl::Init(void)
LastTimeAmbulanceCreated = 0;
#ifdef FIX_BUGS
LastTimeLawEnforcerCreated = 0;
+ LastTimeMiamiViceGenerated = 0;
#endif
bCarsGeneratedAroundCamera = false;
CountDownToCarsAtStart = 2;
@@ -1950,9 +2200,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 +2222,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 +2339,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 +2347,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 +2423,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 +2464,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 +2480,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 +2507,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 +2640,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 +2809,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 +2852,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 +2921,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 +2939,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 +2964,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 +3006,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 +3113,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 +3128,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 +3143,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 +3169,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 +3186,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 +3206,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 +3231,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 +3252,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 +3297,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 +3332,7 @@ void CCarCtrl::UpdateCarCount(CVehicle* pVehicle, bool remove)
++NumParkedCars;
return;
case PERMANENT_VEHICLE:
- ++NumPermanentCars;;
+ ++NumPermanentCars;
return;
}
}
@@ -2812,12 +3340,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..31a2767a 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,21 @@ 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(*pPos1 - *pPos2, *pDir1));
+ float t2 = Abs(DotProduct2D(*pPos2 - *pPos1, *pDir2));
+ float curveCoef;
+ if (t1 > t2) {
+ if (between < (t1 - t2) / (t1 + t2))
+ curveCoef = 0.0f;
+ else
+ curveCoef = 0.5f - 0.5f * Cos(3.1415f * (t1 + t2) / (2 * t2) * (between - (t1 - t2) / (t1 + t2)));
+ }
+ else {
+ if (2 * t1 / (t1 + t2) < between)
+ 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 245e961d..34ed11eb 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 c22bebaa..46eee71f 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::GetModelInfo(vehicleId)->GetColModel();
- 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::GetModelInfo(vehicleId)->GetColModel()->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::GetModelInfo(vehicleId)->GetColModel();
+ 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::GetModelInfo(vehicleId)->GetColModel()->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 285b4cb7..ca250f29 100644
--- a/src/control/Script.cpp
+++ b/src/control/Script.cpp
@@ -17,6 +17,9 @@
#include "FileMgr.h"
#include "Frontend.h"
#include "General.h"
+#ifdef MISSION_REPLAY
+#include "GenericGameStorage.h"
+#endif
#include "HandlingMgr.h"
#include "Heli.h"
#include "Hud.h"
@@ -34,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];
@@ -64,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;
@@ -76,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
@@ -94,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;
@@ -106,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
@@ -154,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--;
@@ -161,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);
@@ -179,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();
@@ -214,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
@@ -382,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:
@@ -405,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;
@@ -419,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:
@@ -433,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);
}
@@ -482,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;
@@ -496,15 +726,24 @@ void CRunningScript::Init()
#ifdef USE_DEBUG_SCRIPT_LOADER
int scriptToLoad = 0;
+const char *scriptfile = "main.scm";
int open_script()
{
+ // glfwGetKey doesn't work because of CGame::Initialise is blocking
+ CPad::UpdatePads();
+ if (CPad::GetPad(0)->GetChar('G'))
+ scriptToLoad = 0;
+ if (CPad::GetPad(0)->GetChar('R'))
+ scriptToLoad = 1;
+ if (CPad::GetPad(0)->GetChar('D'))
+ scriptToLoad = 2;
switch (scriptToLoad) {
- case 0: return CFileMgr::OpenFile("data\\main.scm", "rb");
- case 1: return CFileMgr::OpenFile("data\\main_freeroam.scm", "rb");
- case 2: return CFileMgr::OpenFile("data\\main_d.scm", "rb");
+ case 0: scriptfile = "main.scm"; break;
+ case 1: scriptfile = "freeroam_miami.scm"; break;
+ case 2: scriptfile = "main_d.scm"; break;
}
- return CFileMgr::OpenFile("data\\main.scm", "rb");
+ return CFileMgr::OpenFile(scriptfile, "rb");
}
#endif
@@ -520,16 +759,10 @@ void CTheScripts::Init()
MissionCleanUp.Init();
UpsideDownCars.Init();
StuckCars.Init();
+ CFileMgr::SetDir("data");
#ifdef USE_DEBUG_SCRIPT_LOADER
- // glfwGetKey doesn't work because of CGame::Initialise is blocking
- CPad::UpdatePads();
- if(CPad::GetPad(0)->GetChar('G')) scriptToLoad = 0;
- if(CPad::GetPad(0)->GetChar('R')) scriptToLoad = 1;
- if(CPad::GetPad(0)->GetChar('D')) scriptToLoad = 2;
-
int mainf = open_script();
#else
- CFileMgr::SetDir("data");
int mainf = CFileMgr::OpenFile("main.scm", "rb");
#endif
CFileMgr::Read(mainf, (char*)ScriptSpace, SIZE_MAIN_SCRIPT);
@@ -538,15 +771,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));
@@ -559,15 +784,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;
@@ -588,6 +815,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;
@@ -599,6 +827,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)
@@ -628,6 +869,7 @@ CRunningScript* CTheScripts::StartNewScript(uint32 ip)
pNew->Init();
pNew->SetIP(ip);
pNew->AddScriptToList(&pActiveScripts);
+ pNew->m_bIsActive = true;
return pNew;
}
@@ -640,13 +882,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();
@@ -662,6 +901,7 @@ void CTheScripts::Process()
#ifdef MISSION_REPLAY
static uint32 TimeToWaitTill;
+ static bool AlreadyResetHealth;
switch (AllowMissionReplay) {
case 2:
AllowMissionReplay = 3;
@@ -677,9 +917,19 @@ void CTheScripts::Process()
break;
case 6:
AllowMissionReplay = 7;
+ AlreadyResetHealth = false;
TimeToWaitTill = CTimer::GetTimeInMilliseconds() + 500;
break;
case 7:
+ 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 = 0;
return;
@@ -707,6 +957,8 @@ void CTheScripts::Process()
script->UpdateTimers(timeStep);
script->Process();
script = next;
+ if (script && !script->m_bIsActive)
+ script = nil;
}
DbgFlag = false;
@@ -782,24 +1034,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;
}
@@ -1227,13 +1485,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);
@@ -1269,19 +1525,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)
@@ -1293,6 +1548,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];
@@ -1312,6 +1568,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++) {
@@ -1359,7 +1616,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);
@@ -1399,20 +1656,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:
@@ -1848,6 +2134,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);
@@ -1855,6 +2142,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++;
@@ -1868,24 +2157,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;
@@ -1904,22 +2176,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:
@@ -1964,44 +2245,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);
@@ -2009,6 +2273,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);
@@ -2074,15 +2339,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);
@@ -2093,13 +2365,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);
}
@@ -2137,7 +2411,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;
}
@@ -2149,7 +2423,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;
}
@@ -2221,6 +2495,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
}
return 0;
}
+ /*
case COMMAND_IS_CAR_STILL_ALIVE:
{
CollectParameters(&m_nIp, 1);
@@ -2228,19 +2503,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:
@@ -2307,40 +2576,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 = 1;
+ if (strcmp((char*)&CTheScripts::ScriptSpace[m_nIp - KEY_LENGTH_IN_SCRIPT], "M_FAIL") == 0) {
+ if (AllowMissionReplay == 7)
+ AllowMissionReplay = 0;
+ if (CanAllowMissionReplay())
+ AllowMissionReplay = 1;
+ }
#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;
@@ -2373,15 +2644,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;
@@ -2434,8 +2705,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;
}
@@ -2578,29 +2847,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);
@@ -2608,6 +2871,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:
@@ -2674,6 +2938,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);
@@ -2698,6 +2965,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);
@@ -2740,12 +3009,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);
@@ -2754,10 +3025,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);
@@ -2766,14 +3035,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:
@@ -2784,9 +3053,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);
@@ -2796,23 +3063,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;
}
@@ -2820,8 +3085,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:
{
@@ -2831,10 +3094,8 @@ int8 CRunningScript::ProcessCommands200To299(int32 command)
UpdateCompareFlag(pPed->OurPedCanSeeThisOne(CWorld::Players[ScriptParams[1]].m_pPed));
return 0;
}
- /* Not implemented.
- case COMMAND_ORDER_CHAR_TO_BACKDOOR:
- case COMMAND_ADD_CHAR_TO_GANG:
- */
+ //case COMMAND_ORDER_CHAR_TO_BACKDOOR:
+ //case COMMAND_ADD_CHAR_TO_GANG:
case COMMAND_IS_CHAR_OBJECTIVE_PASSED:
{
CollectParameters(&m_nIp, 1);
@@ -2890,6 +3151,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);
@@ -2905,13 +3169,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);
@@ -2940,18 +3198,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();
@@ -2959,9 +3217,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;
@@ -2975,21 +3231,15 @@ bool CRunningScript::CanAllowMissionReplay()
{
if (AllowMissionReplay)
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;
}
diff --git a/src/control/Script.h b/src/control/Script.h
index 470de444..4e443727 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,10 +47,12 @@ void FlushLog();
#define KEY_LENGTH_IN_SCRIPT (8)
-#if GTA_VERSION <= GTA3_PS2_160
-#define GTA_SCRIPT_COLLECTIVE
+#ifdef USE_DEBUG_SCRIPT_LOADER
+extern const char* scriptfile;
#endif
+//#define GTA_SCRIPT_COLLECTIVE
+
struct intro_script_rectangle
{
bool m_bIsUsed;
@@ -64,7 +68,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 +109,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 +153,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 +169,7 @@ public:
void AddEntityToList(int32, uint8);
void RemoveEntityFromList(int32, uint8);
void Process();
+ void CheckIfCollisionHasLoadedForMissionObjects();
};
struct upsidedown_car_data
@@ -248,11 +253,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 +288,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 +340,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 +358,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 +387,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 +401,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 +428,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 +455,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 +497,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 +558,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 +586,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_ADVANCED_SCRIPT_DEBUG_OUTPUT
@@ -591,6 +600,9 @@ public:
#endif
};
+#ifdef USE_DEBUG_SCRIPT_LOADER
+extern int scriptToLoad;
+#endif
#ifdef MISSION_REPLAY
extern int AllowMissionReplay;
extern uint32 WaitForMissionActivate;
@@ -598,12 +610,19 @@ 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);
#endif
#ifdef USE_DEBUG_SCRIPT_LOADER
-int open_script();
extern int scriptToLoad;
-#endif \ No newline at end of file
+#endif
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 953a1f50..87260603 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 != 0)
+ if (AllowMissionReplay != 7 && AllowMissionReplay != 0)
return;
+ if (AllowMissionReplay == 7)
+ AllowMissionReplay = 0;
if (CanAllowMissionReplay())
AllowMissionReplay = 1;
#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 c9b2b070..a9b750bf 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 = 0;
- SaveGameForPause(3);
-#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,22 +363,42 @@ 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(4);
+ AlreadySavedGame = true;
+ return 0;
+ }
+ else {
+ AlreadySavedGame = false;
+ }
+ }
+#endif
#endif
CTimer::Suspend();
int offset = CTheScripts::MultiScriptArray[ScriptParams[0]];
- CFileMgr::ChangeDir("\\");
#ifdef USE_DEBUG_SCRIPT_LOADER
- int handle = open_script();
+ CFileMgr::ChangeDir("\\data\\");
+ int handle = CFileMgr::OpenFile(scriptfile, "rb");
+ CFileMgr::ChangeDir("\\");
#else
+ CFileMgr::ChangeDir("\\");
int handle = CFileMgr::OpenFile("data\\main.scm", "rb");
#endif
CFileMgr::Seek(handle, offset, 0);
@@ -318,6 +409,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 +425,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 +478,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
}
return 0;
}
+ */
case COMMAND_SET_NEAR_CLIP:
CollectParameters(&m_nIp, 1);
TheCamera.SetNearClipScript(*(float*)&ScriptParams[0]);
@@ -393,6 +487,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 +508,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 +518,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 +537,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
StoreParameters(&m_nIp, 1);
return 0;
}
+ /*
case COMMAND_MARK_ROADS_BETWEEN_LEVELS:
{
CollectParameters(&m_nIp, 6);
@@ -490,6 +586,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 +595,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 +608,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 +635,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 +659,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 +671,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 +694,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 +727,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 +747,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
CStreaming::LoadAllRequestedModels(false);
}
return 0;
+ */
case COMMAND_SET_PLAYER_HOOKER:
{
CollectParameters(&m_nIp, 2);
@@ -655,6 +760,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 +788,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 +796,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 +825,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 +833,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 +841,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 +862,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 +872,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 +908,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 +916,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 +938,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 +950,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 +977,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 +991,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
UpdateCompareFlag(pTarget && pTarget->IsPed());
return 0;
}
+ */
case COMMAND_IS_PLAYER_TARGETTING_CHAR:
{
CollectParameters(&m_nIp, 2);
@@ -887,9 +1000,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 +1043,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 +1085,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 +1136,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 +1150,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 +1194,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 +1227,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 +1261,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 +1275,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 +1291,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 +1323,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 +1339,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 +1396,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 +1405,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 +1417,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 +1445,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 +1470,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 +1482,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
UpdateCompareFlag(pPed->bFallenDown);
return 0;
}
+ */
case COMMAND_CAN_CHAR_SEE_DEAD_CHAR:
{
CollectParameters(&m_nIp, 2);
@@ -1332,23 +1500,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..9863e852 100644
--- a/src/control/ScriptCommands.h
+++ b/src/control/ScriptCommands.h
@@ -995,7 +995,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 +1022,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 +1108,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 +1144,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 +1155,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 e9014088..856b30bd 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, ""),
@@ -354,12 +358,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 +373,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 +562,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 +742,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 +757,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 +770,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 +822,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 +834,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 +852,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 +882,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 +988,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 +1000,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 +1019,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 +1036,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 +1046,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 +1132,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 +1168,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 +1523,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 +1564,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 +1708,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,17 +1729,25 @@ 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(4);
+ }
+#endif
#endif
CTimer::Suspend();
int offset = CTheScripts::MultiScriptArray[mission];
- CFileMgr::ChangeDir("\\");
#ifdef USE_DEBUG_SCRIPT_LOADER
- int handle = open_script();
+ CFileMgr::ChangeDir("\\data\\");
+ int handle = CFileMgr::OpenFile(scriptfile, "rb");
+ CFileMgr::ChangeDir("\\");
#else
+ CFileMgr::ChangeDir("\\");
int handle = CFileMgr::OpenFile("data\\main.scm", "rb");
#endif
CFileMgr::Seek(handle, offset, 0);
@@ -1437,5 +1758,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..3ebd52f2 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
@@ -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..7612b937 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);
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..72d31137 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,11 @@ const char *PlayStationButtons[][MAX_CONTROLLERACTIONS] =
#undef PS2_CROSS
#undef PS2_SQUARE
+#undef UP
+#undef DOWN
+#undef LEFT
+#undef RIGHT
+
#undef CONTROLLER_BUTTONS
#undef VFB
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 ecb893b4..64e27a32 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_3DH")) {
-#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,234 @@ 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
+ m_PrefsControllerType = CONTROLLER_XBOXONE;
+#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();
+ m_bShowMouse = true;
+ 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 && m_nCurrScreen != MENUPAGE_MISSION_RETRY)
+#else
+ if (!m_OnlySaveMenu)
#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);
- else
- sprintf(gString2, " %d", *(int*)stat);
+ m_nCurrScreen = MENUPAGE_NONE;
+ DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND);
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_STARTING, 0);
+ DMAudio.Service();
+ DMAudio.SetMusicMasterVolume(m_PrefsMusicVolume);
+ DMAudio.SetEffectsMasterVolume(m_PrefsSfxVolume);
+#ifdef FIX_BUGS
+ static bool firstTime = true;
+ if (firstTime) {
+ DMAudio.SetRadioInCar(m_PrefsRadioStation);
+ firstTime = false;
} else
- gString2[0] = '\0';
+#endif
+ m_PrefsRadioStation = DMAudio.GetRadioInCar();
+
+ 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);
- UnicodeStrcpy(gUString, TheText.Get(text));
- AsciiToUnicode(gString2, gUString2);
+ CFileMgr::SetDir("");
+ //CFileMgr::SetDir("");
+ PcSaveHelper.PopulateSlotInfo();
+ CTimer::StartUserPause();
}
void
@@ -842,26 +659,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 +687,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 +701,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 +769,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 +899,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 +991,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 +1013,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
+ 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));
}
- // 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;
- }
-
-#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);
- if (option.m_CFODynamic->drawFunc) {
- rightText = option.m_CFODynamic->drawFunc(&isOptionDisabled, m_nCurrOption == i);
+ } 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);
+
+ } 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)));
-
- 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)));
- }
- }
+ && m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) {
- 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 +1612,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 +1654,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 +1696,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 +1738,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 +1756,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 +1811,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 +1850,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 +1883,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 +1918,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 +1932,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 +1976,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 +2043,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 +2073,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 +2110,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 +2151,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 +2170,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 +2214,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));
- } 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;
+ 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 {
- m_nHoverOption = HOVEROPTION_NOT_HOVERING;
+ } 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;
+ }
}
// 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 != 0) {
- 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)
+ if (m_nMenuFadeAlpha < 255) {
- field_518 = 2;
- else
- field_518 = 1;
- }
- }
+ 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();
- 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));
+ // 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));
- 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;
- }
+ // 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));
- // 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) {
+ // 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));
- // 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) {
-
- // 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)));
-
- for (int i = 0; i < bbTabCount; i++) {
- float xStart = leftPadding + optionWidth * i;
- if (CheckHover(xStart, xStart + optionWidth, optionTop, optionBottom))
- hoveredBottomBarOption = i;
-
- 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));
- }
-
- 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);
-
- 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));
+ // 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;
- 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;
+ 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_MULTIPLAYER_MAIN:
- previousSprite = MENUSPRITE_MULTIPLAYER;
+ 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_MAP:
- case MENUPAGE_MULTIPLAYER_FIND_GAME:
case MENUPAGE_SKIN_SELECT:
case MENUPAGE_KEYBOARD_CONTROLS:
- case MENUPAGE_MOUSE_CONTROLS:
- previousSprite = MENUSPRITE_FINDGAME;
- break;
- case MENUPAGE_MULTIPLAYER_CONNECTION:
- case MENUPAGE_MULTIPLAYER_MODE:
- previousSprite = MENUSPRITE_CONNECTION;
- break;
- case MENUPAGE_MULTIPLAYER_CREATE:
- previousSprite = MENUSPRITE_HOSTGAME;
+ 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_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)));
+ }
- 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_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;
+ }
+ }
+
+ 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 +2608,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 +2623,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 +2639,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 +2664,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 +2711,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 +2748,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 +2770,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 +2811,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 +2888,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 +2991,7 @@ CMenuManager::InitialiseChangedLanguageSettings()
default:
break;
}
+
}
}
@@ -3578,182 +3001,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 +3111,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);
}
}
@@ -3812,26 +3151,33 @@ CMenuManager::LoadSettings()
if (LoadINISettings()) {
LoadINIControllerSettings();
}
- // if no re3.ini, create it, or update it with new values
+ // if no reVC.ini, create it, or update it with new values
SaveINISettings();
SaveINIControllerSettings();
#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();
@@ -3862,11 +3208,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));
@@ -3881,45 +3233,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))
@@ -3929,54 +3286,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,
@@ -3985,347 +3346,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;
- }
-
-#ifdef PS2_LIKE_MENU
- CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255)));
- CFont::SetDropShadowPosition(1);
-#endif
+ CFont::FilterOutTokensFromString(gUString);
-#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(2, 0);
- 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
- 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')) {
- 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')) {
- 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;
@@ -4338,33 +4339,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;
@@ -4376,245 +4369,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;
+ if (CPad::GetPad(0)->GetLeftMouseJustUp() && m_nCurrScreen != MENUPAGE_MAP) {
+ if (m_nHoverOption == HOVEROPTION_RANDOM_ITEM)
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;
- 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:
-#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:
+ 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;
@@ -4628,40 +4419,36 @@ 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)
+ {
m_bShowMouse = false;
goBack = true;
}
@@ -4670,92 +4457,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')) {
+ 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) {
@@ -4764,634 +4652,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 = 0;
+ RequestFrontEndShutDown();
+ break;
+ case MENUACTION_UNK114:
+ doingMissionRetry = false;
+ RequestFrontEndShutDown();
+ RetryMission(2, 0);
+ 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(2, 0);
- 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;
@@ -5409,25 +5081,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
@@ -5438,7 +5134,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;
@@ -5460,21 +5156,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);
}
}
}
@@ -5483,106 +5177,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;
}
}
@@ -5591,7 +5260,6 @@ void
CMenuManager::RequestFrontEndShutDown()
{
m_bShutDownFrontEndRequested = true;
- DMAudio.ChangeMusicMode(MUSICMODE_GAME);
}
void
@@ -5608,49 +5276,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)
{
@@ -5670,128 +5301,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(2, 0);
+ m_nCurrSaveSlot = SLOT_COUNT;
+ doingMissionRetry = false;
+ }
+#endif
+ if (CheckSlotDataValid(m_nCurrSaveSlot)) {
+#ifdef USE_DEBUG_SCRIPT_LOADER
+ 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();
- 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();
+ CTxdStore::RemoveTxd(frontend2);
+
+#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
@@ -5800,13 +5719,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)
@@ -5814,7 +5726,7 @@ CMenuManager::WaitForUserCD()
HandleExit();
CPad::UpdatePads();
- MessageScreen("NO_PCCD");
+ MessageScreen("NO_PCCD", true);
if (CPad::GetPad(0)->GetEscapeJustDown()) {
m_bQuitGameNoCD = true;
@@ -5822,15 +5734,244 @@ 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",
+};
+
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;
@@ -5838,46 +5979,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)
{
@@ -5890,7 +6031,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;
@@ -5906,7 +6047,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;
@@ -5923,7 +6064,7 @@ 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;
@@ -5932,854 +6073,632 @@ CMenuManager::PrintController(void)
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;
+ }
+ 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;
- 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
+ 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:
+ 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:
+ 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:
+ 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:
+ 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;
+ 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..858d3fd9 100644
--- a/src/core/Frontend.h
+++ b/src/core/Frontend.h
@@ -4,44 +4,60 @@
#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 HELPER_TEXT_LEFT_MARGIN 320.0f
-#define HELPER_TEXT_BOTTOM_MARGIN 120.0f
-
-#define PLAYERSETUP_LIST_TOP 28.0f
-#define PLAYERSETUP_LIST_BOTTOM 125.0f
+#define MENULABEL_X_MARGIN 80.0f
+#define MENULABEL_POS_X 100.0f
+#define MENULABEL_POS_Y 97.0f
+
+#define MENU_DEFAULT_CONTENT_X 320
+#define MENU_DEFAULT_CONTENT_Y 100
+#define MENU_DEFAULT_LINE_HEIGHT 29
+
+#define RIGHT_ALIGNED_TEXT_RIGHT_MARGIN(xMargin) (xMargin + 30.0f)
+
+#define MENURADIO_ICON_FIRST_X 238.f
+#define MENURADIO_ICON_Y 288.0f
+#define MENURADIO_ICON_SIZE 60.0f
+#define MENURADIO_SELECTOR_START_Y 285.f // other options should leave room on the screen
+#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 +69,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 +162,72 @@ enum eSaveSlot
SAVESLOT_6,
SAVESLOT_7,
SAVESLOT_8,
- SAVESLOT_LABEL = 36,
-};
-
-#ifdef MENU_MAP
-enum MapSprites
-{
- MAPMID1,
- MAPMID2,
- MAPMID3,
- MAPBOT1,
- MAPBOT2,
- MAPBOT3,
- MAPTOP1,
- MAPTOP2,
- MAPTOP3,
- NUM_MAP_SPRITES
+ SAVESLOT_LABEL = 36
};
-#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 +239,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 +250,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 +260,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 +287,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 +325,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 +337,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 +348,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 +365,7 @@ enum eControlMethod
enum ControllerSetupColumn
{
CONTSETUP_PED_COLUMN = 0,
- CONTSETUP_VEHICLE_COLUMN = 14,
+ CONTSETUP_VEHICLE_COLUMN = 16,
};
struct tSkinInfo
@@ -472,9 +387,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 +396,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 +482,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 +500,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 +707,22 @@ public:
int32 m_nSelectedScreenMode;
#endif
#ifdef MULTISAMPLING
- static int8 m_nPrefsMSAALevel;
- static int8 m_nDisplayMSAALevel;
+ int8 m_nPrefsMSAALevel;
+ int8 m_nDisplayMSAALevel;
#endif
+#ifdef GAMEPAD_MENU
+ enum
+ {
+ CONTROLLER_DUALSHOCK2 = 0,
+ CONTROLLER_DUALSHOCK3,
+ CONTROLLER_DUALSHOCK4,
+ CONTROLLER_XBOX360,
+ CONTROLLER_XBOXONE,
+ };
+
+ int8 m_PrefsControllerType;
+#endif
enum LANGUAGE
{
LANGUAGE_AMERICAN,
@@ -681,42 +736,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 +747,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 +758,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..3a8cdb06 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,41 @@ 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
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);
+ 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 +361,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 +415,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 +432,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 +446,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 +455,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 +511,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 +530,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 +565,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 +636,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 +665,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 +686,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 +705,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 +731,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 +751,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 +771,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 +814,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 +845,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 +888,7 @@ void CGame::Process(void)
POP_MEMID();
CCollision::Update();
+ CScriptPaths::Update();
CTrain::UpdateTrains();
CPlane::UpdatePlanes();
CHeli::UpdateHelis();
@@ -1056,10 +899,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 +937,7 @@ void CGame::Process(void)
CGarages::Update();
CRubbish::Update();
CSpecialFX::Update();
+ CRopes::Update();
CTimeCycle::Update();
if (CReplay::ShouldStandardCameraBeProcessed())
TheCamera.Process();
@@ -1096,9 +953,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 +968,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 +1008,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 +1039,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 +1068,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 +1113,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 +1151,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 +1187,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 +1224,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 +1275,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 3bd9adf4..3ffc4e83 100644
--- a/src/core/MenuScreens.cpp
+++ b/src/core/MenuScreens.cpp
@@ -6,443 +6,341 @@
// 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,
- },
-
- // MENUPAGE_BRIEFS = 3
- { "FET_BRE", 1, MENUPAGE_NONE, MENUPAGE_NONE, 6, 3,
- MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
- },
-
- // 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_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,
- MENUACTION_AUDIOHW, "FEA_3DH", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS,
- MENUACTION_SPEAKERCONF, "FEA_SPK", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS,
- 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,
+CMenuScreen aScreens[] = {
+ // MENUPAGE_STATS = 0
+ { "FEH_STA", MENUPAGE_NONE, 3,
+ MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 190, 320, MENUALIGN_RIGHT,
},
- // 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_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_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,
+ // MENUPAGE_BRIEFS = 2
+ { "FEH_BRI", MENUPAGE_NONE, 4,
+ MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 190, 320, MENUALIGN_RIGHT,
},
- // 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,
+ // 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,
+ 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,
+ 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,
+ MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, 320, 367, MENUALIGN_CENTER,
+ MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, MENUALIGN_CENTER,
},
- // 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_DISPLAY_SETTINGS = 4
+#ifdef LEGACY_MENU_OPTIONS
+ #define Y_OFFSET 50
+#else
+ #define Y_OFFSET 0
+#endif
- // 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,
+ { "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_NO_MEMORY_CARD = 13
- { "FES_NOC", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
- // hud adjustment page in mobile
+#undef Y_OFFSET
+
+ // 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_LOADING_IN_PROGRESS = 14
- { "FET_LG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
- MENUACTION_LABEL, "FED_LDW", SAVESLOT_NONE, MENUPAGE_LOAD_SLOT_CONFIRM,
+ // MENUPAGE_MAP = 6
+ { "FEH_MAP", MENUPAGE_NONE, 2,
+ MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 70, 380, 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_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_PS2_LOAD_FAILED = 16
- { "FET_LG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
- MENUACTION_LABEL, "FES_LOE", SAVESLOT_NONE, MENUPAGE_NONE,
+ // 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_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_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_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_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_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_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_MEMORY_CARD_TEST = 20
- { "FEM_MC2", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
+ // MENUPAGE_LOADING_IN_PROGRESS = 12
+ { "FET_LG", MENUPAGE_CHOOSE_LOAD_SLOT, 0,
+ },
+ // MENUPAGE_DELETING_IN_PROGRESS = 13
+ { "FES_DEL", MENUPAGE_CHOOSE_DELETE_SLOT, 0,
},
- // MENUPAGE_MULTIPLAYER_MAIN = 21
- { "FET_MP", 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_PS2_SAVE_FAILED = 22
- { "MCDNSP", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
- MENUACTION_MEMCARDSAVECONFIRM, "JAILB_U", SAVESLOT_NONE, MENUPAGE_NONE,
+ // 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_PS2_SAVE_FAILED_2 = 23
- { "MCGNSP", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
- MENUACTION_MEMCARDSAVECONFIRM, "JAILB_U", SAVESLOT_NONE, MENUPAGE_NONE,
+ // MENUPAGE_SAVING_IN_PROGRESS = 17
+ { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, 0,
},
- // 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_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,
},
-#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_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,
},
-#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_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,
},
- // 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_SKIN_SELECT = 21
+ { "FET_PS", MENUPAGE_OPTIONS, 4,
+ MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_OPTIONS, 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_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_MULTIPLAYER_MAP = 28
- { "FET_MAP", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
+ // 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_FAILED_2 = 24
+ { "FET_LG", MENUPAGE_CHOOSE_SAVE_SLOT, 0,
+ MENUACTION_LABEL, "FEC_SVU", SAVESLOT_NONE, 0, 0, 0, 0,
},
- // MENUPAGE_MULTIPLAYER_CONNECTION = 29
- { "FET_CON", 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_FIND_GAME = 30
- { "FET_FG", 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_MODE = 31
- { "FET_GT", 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_CREATE = 32
- { "FET_HG", 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_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 033ed9b9..431fd794 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"
@@ -37,31 +38,31 @@
#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) },
+ #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);
}
@@ -395,531 +387,416 @@ void ControllerTypeAfterChange(int8 before, int8 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,
-#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_AUDIOHW, "FEA_3DH", { nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS },
- MENUACTION_SPEAKERCONF, "FEA_SPK", { nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS },
- 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 },
+ // 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,
+ 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,
+ 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,
+ MENUACTION_RESTOREDEF, "FET_DEF", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 320, 367, MENUALIGN_CENTER,
+ 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 },
- 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 },
+ { "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,
+#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
DUALPASS_SELECTOR
CUTSCENE_BORDERS_TOGGLE
FREE_CAM_TOGGLE
+ DENSITY_SLIDERS
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 },
- DENSITY_SLIDERS
+ { "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,
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 },
+ DENSITY_SLIDERS
+ 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_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_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_MAP = 6
+ { "FEH_MAP", MENUPAGE_NONE, nil, nil,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 70, 380, MENUALIGN_CENTER,
},
- // MENUPAGE_NO_MEMORY_CARD = 13
- { "FES_NOC", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
- // hud adjustment page in mobile
+ // 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_LOADING_IN_PROGRESS = 14
- { "FET_LG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
- MENUACTION_LABEL, "FED_LDW", { nil, SAVESLOT_NONE, MENUPAGE_LOAD_SLOT_CONFIRM },
+ // 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_DELETING_IN_PROGRESS = 15
- { "FET_DG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
- MENUACTION_LABEL, "FEDL_WR", { 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_PS2_LOAD_FAILED = 16
- { "FET_LG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
- MENUACTION_LABEL, "FES_LOE", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
+ // 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_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_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_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_LOADING_IN_PROGRESS = 12
+ { "FET_LG", MENUPAGE_CHOOSE_LOAD_SLOT, nil, nil,
},
- // 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_DELETING_IN_PROGRESS = 13
+ { "FES_DEL", MENUPAGE_CHOOSE_DELETE_SLOT, nil, nil,
},
- // MENUPAGE_MEMORY_CARD_TEST = 20
- { "FEM_MC2", 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_MULTIPLAYER_MAIN = 21
- { "FET_MP", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
-
+ // 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 = 22
- { "MCDNSP", 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,
},
- // MENUPAGE_PS2_SAVE_FAILED_2 = 23
- { "MCGNSP", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
- MENUACTION_MEMCARDSAVECONFIRM, "JAILB_U", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
+ // MENUPAGE_SAVING_IN_PROGRESS = 17
+ { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
},
- // 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 },
+ // 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,
},
-#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_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_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_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_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_SKIN_SELECT = 21
+ { "FET_PS", MENUPAGE_OPTIONS, nil, nil,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_OPTIONS}, 0, 0, 0,
},
- // MENUPAGE_MULTIPLAYER_MAP = 28
- { "FET_MAP", 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_CONNECTION = 29
- { "FET_CON", 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_FIND_GAME = 30
- { "FET_FG", 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_MULTIPLAYER_MODE = 31
- { "FET_GT", 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_MULTIPLAYER_CREATE = 32
- { "FET_HG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
-
- },
-
- // MENUPAGE_MULTIPLAYER_START = 33
- { "FEN_STA", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
-
- },
-
- // MENUPAGE_SKIN_SELECT_OLD = 34
- { "FET_PS", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
-
- },
-
- // 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 },
+ 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_PC_OLD4 = 39
- { "FET_CTL", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, nil, nil,
-
- },
-
- // 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,
+ MENUACTION_CHANGEMENU, "FEO_CON", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC}, 320, 132, MENUALIGN_CENTER,
+ 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 },
+ 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_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 },
+ // 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_SAVING_IN_PROGRESS = 43
- { "", MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
- MENUACTION_LABEL, "FES_WAR", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
+ // 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_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_KEYBOARD_CONTROLS = 30
+ { "FET_STI", MENUPAGE_CONTROLLER_PC, nil, nil,
},
- // 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_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, },
- // 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 },
+#ifdef GAMEPAD_MENU
+ { "FET_AGS", MENUPAGE_CONTROLLER_PC, new CCustomScreenLayout({40, 78, 25, true, true}), nil,
+ 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_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 },
+ MENUACTION_SCREENRES, "FED_RES", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS }, 0, 0, MENUALIGN_LEFT,
+ 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 cccf1d2e..0792008a 100644
--- a/src/core/Radar.cpp
+++ b/src/core/Radar.cpp
@@ -19,55 +19,95 @@
#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;
+CSprite2d CRadar::TShirtSprite;
+CSprite2d CRadar::TommySprite;
+CSprite2d CRadar::PhoneSprite;
+CSprite2d CRadar::RadioWildstyleSprite;
+CSprite2d CRadar::RadioFlashSprite;
+CSprite2d CRadar::RadioKChatSprite;
+CSprite2d CRadar::RadioFeverSprite;
+CSprite2d CRadar::RadioVRockSprite;
+CSprite2d CRadar::RadioVCPRSprite;
+CSprite2d CRadar::RadioEspantosoSprite;
+CSprite2d CRadar::RadioEmotionSprite;
+CSprite2d CRadar::RadioWaveSprite;
CSprite2d *CRadar::RadarSprites[RADAR_SPRITE_COUNT] = {
nil,
- &AsukaSprite,
- &BombSprite,
- &CatSprite,
&CentreSprite,
- &CopcarSprite,
- &DonSprite,
- &EightSprite,
- &ElSprite,
- &IceSprite,
- &JoeySprite,
- &KenjiSprite,
- &LizSprite,
- &LuigiSprite,
+ &MapHereSprite,
&NorthSprite,
- &RaySprite,
- &SalSprite,
- &SaveSprite,
+ &AverySprite,
+ &BikerSprite,
+ &CortezSprite,
+ &DiazSprite,
+ &KentSprite,
+ &LawyerSprite,
+ &PhilSprite,
+ &BikersSprite,
+ &BoatyardSprite,
+ &MalibuClubSprite,
+ &CubansSprite,
+ &FilmSprite,
+ &GunSprite,
+ &HaitiansSprite,
+ &HardwareSprite,
+ &SaveHouseSprite,
+ &StripSprite,
+ &IceSprite,
+ &KCabsSprite,
+ &LovefistSprite,
+ &PrintworksSprite,
+ &PropertySprite,
+ &SunYardSprite,
&SpraySprite,
- &TonySprite,
- &WeaponSprite
+ &TShirtSprite,
+ &TommySprite,
+ &PhoneSprite,
+ &RadioWildstyleSprite,
+ &RadioFlashSprite,
+ &RadioKChatSprite,
+ &RadioFeverSprite,
+ &RadioVRockSprite,
+ &RadioVCPRSprite,
+ &RadioEspantosoSprite,
+ &RadioEmotionSprite,
+ &RadioWaveSprite
};
// Why this doesn't coincide with world coordinates i don't know
@@ -87,12 +127,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;
@@ -145,15 +188,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;
}
@@ -192,12 +234,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
}
}
@@ -422,9 +461,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;
@@ -442,7 +480,7 @@ void CRadar::Draw3dMarkers()
if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
CVector pos = entity->GetPosition();
pos.z += 1.2f * CModelInfo::GetModelInfo(entity->GetModelIndex())->GetColModel()->boundingBox.max.z + 2.5f;
- C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), 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;
}
@@ -456,7 +494,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;
}
@@ -466,7 +504,7 @@ void CRadar::Draw3dMarkers()
if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
CVector pos = entity->GetPosition();
pos.z += CModelInfo::GetModelInfo(entity->GetModelIndex())->GetColModel()->boundingBox.max.z + 1.0f + 1.0f;
- C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), 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;
}
@@ -475,7 +513,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;
}
@@ -485,11 +523,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);
@@ -501,9 +539,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();
@@ -523,17 +559,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;
@@ -541,165 +569,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;
@@ -712,65 +640,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)
@@ -784,14 +682,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)
@@ -869,6 +766,7 @@ void CRadar::DrawRadarMask()
#if !defined(GTA_PS2_STUFF) && defined(RWLIBS)
RwD3D8SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER);
#endif
+
}
void CRadar::DrawRadarSection(int32 x, int32 y)
@@ -886,11 +784,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++)
@@ -908,8 +803,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);
@@ -918,6 +820,18 @@ void CRadar::DrawRadarSection(int32 x, int32 y)
void CRadar::DrawRadarSprite(uint16 sprite, float x, float y, uint8 alpha)
{
RadarSprites[sprite]->Draw(CRect(x - SCREEN_SCALE_X(8.0f), y - SCREEN_SCALE_Y(8.0f), x + SCREEN_SCALE_X(8.0f), y + SCREEN_SCALE_Y(8.0f)), CRGBA(255, 255, 255, alpha));
+
+ 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)
@@ -1022,14 +936,11 @@ const char* gRadarTexNames[] = {
void
CRadar::Initialise()
{
-#ifdef MENU_MAP
- 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;
@@ -1045,10 +956,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;
@@ -1063,37 +974,109 @@ 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
+ if (TargetMarkerId != -1) {
+ ClearBlip(TargetMarkerId);
+ TargetMarkerId = -1;
+ }
+#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));
+ }
+
+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");
+ AverySprite.SetTexture("radar_avery");
+ BikerSprite.SetTexture("radar_biker");
+ CortezSprite.SetTexture("radar_cortez");
+ DiazSprite.SetTexture("radar_diaz");
+ KentSprite.SetTexture("radar_kent");
+ LawyerSprite.SetTexture("radar_lawyer");
+ PhilSprite.SetTexture("radar_phil");
+ BikersSprite.SetTexture("bikers");
+ BoatyardSprite.SetTexture("boatyard");
+ MalibuClubSprite.SetTexture("club");
+ CubansSprite.SetTexture("cubans");
+ FilmSprite.SetTexture("filmstudio");
+ GunSprite.SetTexture("gun");
+ HaitiansSprite.SetTexture("haitians");
+ HardwareSprite.SetTexture("hardware");
+ SaveHouseSprite.SetTexture("radar_save");
+ StripSprite.SetTexture("radar_strip");
+ IceSprite.SetTexture("icecream");
+ KCabsSprite.SetTexture("kcabs");
+ LovefistSprite.SetTexture("lovefist");
+ PrintworksSprite.SetTexture("printworks");
+ PropertySprite.SetTexture("property");
+ SunYardSprite.SetTexture("SunYard");
+ SpraySprite.SetTexture("spray");
+ TShirtSprite.SetTexture("tshirt");
+ TommySprite.SetTexture("tommy");
+ PhoneSprite.SetTexture("phone");
+ RadioWildstyleSprite.SetTexture("RWildstyle");
+ RadioFlashSprite.SetTexture("RFlash");
+ RadioKChatSprite.SetTexture("RKchat");
+ RadioFeverSprite.SetTexture("RFever");
+ RadioVRockSprite.SetTexture("RVRock");
+ RadioVCPRSprite.SetTexture("RVCPR");
+ RadioEspantosoSprite.SetTexture("REspantoso");
+ RadioEmotionSprite.SetTexture("REmotion");
+ RadioWaveSprite.SetTexture("RWave");
CTxdStore::PopCurrentTxd();
}
@@ -1104,33 +1087,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);
@@ -1139,7 +1095,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++) {
@@ -1151,9 +1107,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;
@@ -1164,7 +1121,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++) {
@@ -1176,9 +1142,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;
@@ -1232,11 +1199,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));
@@ -1245,22 +1208,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;
@@ -1273,32 +1232,52 @@ void CRadar::ShowRadarTraceWithHeight(float x, float y, uint32 size, uint8 red,
void CRadar::Shutdown()
{
- AsukaSprite.Delete();
- BombSprite.Delete();
- CatSprite.Delete();
CentreSprite.Delete();
- CopcarSprite.Delete();
- DonSprite.Delete();
- EightSprite.Delete();
- ElSprite.Delete();
- IceSprite.Delete();
- JoeySprite.Delete();
- KenjiSprite.Delete();
- LizSprite.Delete();
- LuigiSprite.Delete();
+ MapHereSprite.Delete();
NorthSprite.Delete();
- RaySprite.Delete();
- SalSprite.Delete();
- SaveSprite.Delete();
+ AverySprite.Delete();
+ BikerSprite.Delete();
+ CortezSprite.Delete();
+ DiazSprite.Delete();
+ KentSprite.Delete();
+ LawyerSprite.Delete();
+ PhilSprite.Delete();
+ BikersSprite.Delete();
+ BoatyardSprite.Delete();
+ MalibuClubSprite.Delete();
+ CubansSprite.Delete();
+ FilmSprite.Delete();
+ GunSprite.Delete();
+ HaitiansSprite.Delete();
+ HardwareSprite.Delete();
+ SaveHouseSprite.Delete();
+ StripSprite.Delete();
+ IceSprite.Delete();
+ KCabsSprite.Delete();
+ LovefistSprite.Delete();
+ PrintworksSprite.Delete();
+ PropertySprite.Delete();
+ SunYardSprite.Delete();
SpraySprite.Delete();
- TonySprite.Delete();
- WeaponSprite.Delete();
+ TShirtSprite.Delete();
+ TommySprite.Delete();
+ PhoneSprite.Delete();
+ RadioWildstyleSprite.Delete();
+ RadioFlashSprite.Delete();
+ RadioKChatSprite.Delete();
+ RadioFeverSprite.Delete();
+ RadioVRockSprite.Delete();
+ RadioVCPRSprite.Delete();
+ RadioEspantosoSprite.Delete();
+ RadioEmotionSprite.Delete();
+ RadioWaveSprite.Delete();
RemoveRadarSections();
}
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)
@@ -1324,33 +1303,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;
@@ -1361,14 +1315,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
@@ -1381,35 +1331,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);
@@ -1421,11 +1344,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) {
@@ -1446,14 +1366,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
@@ -1475,14 +1400,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)
{
@@ -1492,10 +1436,10 @@ CRadar::ToggleTargetMarker(float x, float y)
if (!ms_RadarTrace[nextBlip].m_bInUse)
break;
}
-#ifdef FIX_BUGS
+
if (nextBlip == NUMRADARBLIPS)
return;
-#endif
+
ms_RadarTrace[nextBlip].m_eBlipType = BLIP_COORD;
ms_RadarTrace[nextBlip].m_nColor = RADAR_TRACE_GRAY;
ms_RadarTrace[nextBlip].m_bDim = 0;
@@ -1517,3 +1461,287 @@ 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;
+ 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 5b38d350..b01a5d04 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,31 +51,49 @@ 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,
+ RADAR_SPRITE_TSHIRT,
+ RADAR_SPRITE_TOMMY,
+ RADAR_SPRITE_PHONE,
+ RADAR_SPRITE_RADIO_WILDSTYLE,
+ RADAR_SPRITE_RADIO_FLASH,
+ RADAR_SPRITE_RADIO_KCHAT,
+ RADAR_SPRITE_RADIO_FEVER,
+ RADAR_SPRITE_RADIO_VROCK,
+ RADAR_SPRITE_RADIO_VCPR,
+ RADAR_SPRITE_RADIO_ESPANTOSO,
+ RADAR_SPRITE_RADIO_EMOTION,
+ RADAR_SPRITE_RADIO_WAVE,
+
RADAR_SPRITE_COUNT
};
@@ -73,25 +120,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
/*
@@ -120,35 +185,61 @@ 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 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);
@@ -178,8 +269,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);
@@ -191,7 +283,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 6e8314f4..841aab40 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::GetModelInfo(e->GetModelIndex())->GetColModel();
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::GetModelInfo(e->GetModelIndex())->GetColModel();
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::GetModelInfo(e->GetModelIndex())->GetColModel();
- 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 da162762..9d3bca67 100644
--- a/src/core/common.h
+++ b/src/core/common.h
@@ -116,10 +116,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 +146,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,12 +284,15 @@ 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);
#define Clamp(v, low, high) ((v)<(low) ? (low) : (v)>(high) ? (high) : (v))
+#define Clamp2(v, center, radius) ((v) < (center) ? Max(v, center - radius) : Min(v, center + radius))
+
inline float sq(float x) { return x*x; }
#define SQR(x) ((x) * (x))
@@ -393,3 +394,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 21a8b738..73b77560 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,16 +133,21 @@ enum Config {
NUM_PED_COMMENTS_SLOTS = 20,
NUM_SOUNDS_SAMPLES_BANKS = 2,
- NUM_AUDIOENTITIES = 200,
+ NUM_AUDIOENTITIES = 250,
- NUM_AUDIO_REFLECTIONS = 5,
+ NUM_AUDIO_REFLECTIONS = 8,
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
@@ -149,28 +157,34 @@ 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
+
+// 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 PC_PLAYER_CONTROLS // mouse player/cam mode
# 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 +217,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 +234,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 +271,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 +286,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 +304,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,9 +320,12 @@ 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)
@@ -327,45 +336,39 @@ enum Config {
#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
-
+# define MAP_ENHANCEMENTS // Adding waypoint and better mouse support
# ifdef XINPUT
# 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 +377,17 @@ 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
+#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,45 +404,43 @@ 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 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
@@ -454,15 +462,11 @@ 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
-#endif // VANILLA_DEFINES
+#endif // VANILLA_DEFINES \ No newline at end of file
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 b7d89363..b0183408 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"
@@ -54,6 +57,8 @@
#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 +93,8 @@ mysrand(unsigned int seed)
#ifdef CUSTOM_FRONTEND_OPTIONS
#include "frontendoption.h"
+
+
#ifdef MORE_LANGUAGES
void LangPolSelect(int8 action)
{
@@ -125,8 +132,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 +141,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 +195,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 +316,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 +423,7 @@ void LoadINIControllerSettings()
}
}
}
-
+
ControlsManager.SetControllerKeyAssociatedWithAction((e_ControllerAction)i, contKey, (eControllerType)contType);
}
}
@@ -424,7 +434,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 +495,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);
ReadIniIfExists("Audio", "SpeakerType", &FrontEndMenuManager.m_PrefsSpeakers);
ReadIniIfExists("Audio", "Provider", &FrontEndMenuManager.m_nPrefsAudio3DProviderIndex);
@@ -500,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);
@@ -517,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
@@ -567,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
@@ -585,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);
StoreIni("Audio", "SpeakerType", FrontEndMenuManager.m_PrefsSpeakers);
StoreIni("Audio", "Provider", FrontEndMenuManager.m_nPrefsAudio3DProviderIndex);
@@ -600,12 +617,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);
@@ -617,6 +639,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
@@ -658,11 +681,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();
@@ -682,7 +706,8 @@ void FastWeatherCheat();
void OnlyRenderWheelsCheat();
void ChittyChittyBangBangCheat();
void StrongGripCheat();
-void NastyLimbsCheat();
+void SpecialCarCheats();
+void PickUpChicksCheat();
DebugMenuEntry *carCol1;
DebugMenuEntry *carCol2;
@@ -705,6 +730,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);
@@ -734,13 +761,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)
{
@@ -795,20 +824,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;
@@ -866,11 +895,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);
@@ -878,19 +933,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);
@@ -907,17 +965,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);
});
@@ -927,22 +984,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
@@ -952,6 +1020,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);
@@ -960,7 +1029,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;
@@ -970,7 +1039,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);
@@ -985,8 +1054,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);
@@ -1009,8 +1083,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);
@@ -1019,7 +1091,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);
@@ -1035,8 +1107,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
@@ -1045,7 +1115,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);
@@ -1053,32 +1128,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);
@@ -1088,9 +1165,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");
@@ -1133,7 +1207,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)
@@ -1154,7 +1228,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
}
@@ -1208,14 +1282,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 1d4c881f..e51a0821 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 3ccae5d0..535445c5 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,9 +1230,7 @@ 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())
@@ -1129,17 +1242,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 +1283,12 @@ CPed::RestoreGunPosition(void)
}
}
+bool
+CPed::CanWeRunAndFireWithWeapon(void)
+{
+ return CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM);
+}
+
void
CPed::ScanForInterestingStuff(void)
{
@@ -1236,28 +1360,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 +1372,6 @@ CPed::ScanForInterestingStuff(void)
int time = CGeneral::GetRandomNumber() % 4000 + 10000;
SetChat(m_nearPeds[i], time);
m_nearPeds[i]->SetChat(this, time);
- return;
}
}
}
@@ -1278,50 +1379,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 +1398,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 +1421,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 +1444,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 +1469,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 +1486,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 +1513,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 +1524,7 @@ CPed::WorkOutHeadingForMovingFirstPerson(float offset)
void
CPed::UpdatePosition(void)
{
- if (CReplay::IsPlayingBack() || !bIsStanding)
+ if (CReplay::IsPlayingBack() || !bIsStanding || m_attachedTo)
return;
CVector2D velocityChange;
@@ -1527,7 +1571,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 +1607,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 +1634,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 +1666,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 +1744,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 +1762,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 +1794,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 +1830,11 @@ CPed::ProcessControl(void)
if (ServiceTalkingWhenDead())
ServiceTalking();
-#ifdef VC_PED_PORTS
if (bIsInWater) {
bIsStanding = false;
bWasStanding = false;
CPhysical::ProcessControl();
}
-#endif
return;
}
@@ -1852,16 +1855,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 +1871,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 +1882,7 @@ CPed::ProcessControl(void)
}
*/
-#ifndef VC_PED_PORTS
- } else {
-#else
} else if (collidingEnt) {
-#endif
switch (collidingEnt->GetType())
{
case ENTITY_TYPE_BUILDING:
@@ -1919,6 +1917,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 +1932,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 +1944,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 +1976,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 +1993,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 +2013,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 +2110,7 @@ CPed::ProcessControl(void)
if (collidingVeh == m_pMyVehicle)
bCollidedWithMyVehicle = true;
-#ifdef VC_PED_PORTS
+
float oldHealth = m_fHealth;
bool playerSufferSound = false;
@@ -2099,23 +2119,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 +2166,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 {
@@ -2248,142 +2276,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::GetModelInfo(collidingVeh->GetModelIndex())->GetColModel();
- 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 +2297,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 +2317,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 +2328,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 +2349,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 +2374,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 +2388,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 +2419,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 +2435,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 +2490,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 +2516,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 +2546,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 +2597,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 +2648,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 +2710,9 @@ CPed::ProcessControl(void)
case PED_SEEK_IN_BOAT:
SeekBoatPosition();
break;
+ case PED_BUY_ICECREAM:
+ BuyIceCream();
+ break;
case PED_INVESTIGATE:
InvestigateEvent();
break;
@@ -2850,30 +2721,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 +2763,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 +2829,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 +2858,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 +2883,8 @@ CPed::ProcessControl(void)
}
m_pCurrentPhysSurface = nil;
}
- }
+ } else
+ ServiceTalking();
}
int32
@@ -3064,22 +2899,16 @@ CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints)
CColModel *ourCol = CModelInfo::GetModelInfo(GetModelIndex())->GetColModel();
CColModel *hisCol = CModelInfo::GetModelInfo(collidingEnt->GetModelIndex())->GetColModel();
- 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 +2930,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 +2969,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 +3000,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 +3021,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 +3034,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 +3044,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 +3064,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 +3095,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 +3103,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 +3114,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 +3134,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 +3154,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 +3163,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 +3371,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 +3404,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 +3430,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 +3470,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 +3516,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 +3539,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 +3557,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 +3575,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 +3593,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 +3713,6 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
m_walkAroundType = 0;
}
}
-#endif
}
m_collidingEntityWhileFleeing = obj;
m_collidingEntityWhileFleeing->RegisterReference((CEntity**) &m_collidingEntityWhileFleeing);
@@ -3907,56 +3722,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 +3836,6 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
}
}
}
-#endif
if (objUpsideDown)
localPosToHead.x = localPosToHead.x * -1.0f;
@@ -4142,7 +3906,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 +3930,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 +3974,6 @@ CPed::PedStaggerCB(CAnimBlendAssociation* animAssoc, void* arg)
// nothing
*/
}
-
void
CPed::PedSetOutCarCB(CAnimBlendAssociation *animAssoc, void *arg)
{
@@ -4207,22 +3991,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 +4064,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 +4088,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 +4103,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 +4151,7 @@ CPed::PedSetOutCarCB(CAnimBlendAssociation *animAssoc, void *arg)
if (createdBy == MISSION_CHAR && !startedToRun)
ped->SetMoveState(PEDMOVE_WALK);
}
+ ped->bHeldHostageInCar = false;
}
void
@@ -4362,7 +4161,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 +4185,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 +4209,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 +4241,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 +4266,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 +4291,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 +4302,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 +4316,7 @@ CPed::PedSetInCarCB(CAnimBlendAssociation *animAssoc, void *arg)
ped->SetPedState(PED_DRIVING);
ped->StopNonPartialAnims();
+ ped->RemoveWeaponWhenEnteringVehicle();
return;
}
@@ -4509,7 +4328,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 +4347,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 +4388,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 +4424,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 +4456,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 +4499,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 +4524,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 +4552,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;
+ }
+ }
+}
+
+int32
+CPed::GiveWeapon(eWeaponType weaponType, uint32 ammo, bool unused)
+{
+ int slot = GetWeaponSlot(weaponType);
- weapon.Reload();
+ 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 +4775,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();
- 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);
+ 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 (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 +4999,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 +5025,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 +5086,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 +5119,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 +5142,9 @@ CPed::Pause(void)
void
CPed::SetFall(int extraTime, AnimationId animId, uint8 evenIfNotInControl)
{
+ if (m_attachedTo)
+ return;
+
if (!IsPedInControl() && (!evenIfNotInControl || DyingOrDead()))
return;
@@ -5085,24 +5152,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 +5213,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 +5320,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 +5339,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 +5387,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 +5414,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 +5456,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 +5510,7 @@ CPed::ClearLook(void)
void
CPed::Look(void)
{
- // UNUSED: This is a perfectly empty function.
+ TurnBody();
}
bool
@@ -5390,14 +5550,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 +5564,6 @@ CPed::SetSeek(CVector pos, float distanceToCountDone)
m_distanceToCountSeekDone = distanceToCountDone;
m_vecSeekPos = pos;
}
-
void
CPed::SetSeek(CEntity *seeking, float distanceToCountDone)
{
@@ -5418,7 +5573,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 +5605,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 +5627,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 +5646,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 +5669,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 +5704,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 +5726,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 +5736,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 +5747,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 +5762,6 @@ CPed::Seek(void)
bUsePedNodeSeek = true;
}
- if (SeekFollowingPath(nil))
- m_nCurPathNode++;
-
return true;
}
@@ -5603,8 +5775,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 +5844,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 +5861,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 +5889,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 +5943,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 +5952,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 +6025,9 @@ CPed::SetWanderPath(int8 pathStateDest)
{
uint8 nextPathState;
+ if (IsPlayer())
+ return false;
+
if (IsPedInControl()) {
if (bKindaStayInSamePlace) {
SetIdle();
@@ -5915,14 +6080,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 +6100,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 +6117,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 +6151,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 +6175,6 @@ CPed::WanderPath(void)
Say(SOUND_PED_WAIT_DOUBLEBACK);
}
}
-
void
CPed::Avoid(void)
{
@@ -6044,68 +6223,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();
+
+ 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;
- while (v4 < maxNodeIndex)
- v4++;
+ 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 +6819,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 +6904,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 +6939,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 +6980,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 +6991,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 +7022,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 +7034,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 +7042,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 +7055,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 +7069,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 +7094,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 +7111,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 +7132,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 +7161,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 +7211,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 +7265,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 +7390,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 +7418,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 +7489,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 +7509,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 +7531,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 +7549,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 +7666,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 +7682,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 +7722,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 +7763,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 +7780,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 +7795,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 +7817,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 +7828,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 +8021,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 +8168,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 +8196,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 +8226,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 +8243,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 +8306,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 +8386,7 @@ CPed::Wait(void)
CPed *pedWeLook;
if (DyingOrDead()) {
- m_nWaitState = WAITSTATE_FALSE;
+ ClearWaitState();
RestoreHeadingRate();
return;
}
@@ -7405,7 +8396,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 +8405,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 +8419,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 +8436,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 +8447,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 +8471,7 @@ CPed::Wait(void)
animAssoc->SetFinishCallback(FinishedWaitCB, this);
m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 5000;
} else {
- m_nWaitState = WAITSTATE_FALSE;
+ ClearWaitState();
}
}
break;
@@ -7510,7 +8500,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 +8537,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 +8562,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 +8639,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 +8665,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 +8822,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 +8858,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 +8914,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 +8926,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 +8950,7 @@ CPed::Solicit(void)
} else {
m_pVehicleAnim = nil;
SetLeader(m_carInObjective->pDriver);
+ Say(SOUND_PED_SOLICIT);
}
}
@@ -7807,26 +8963,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 +9122,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 +9140,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 +9159,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 +9182,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::GetModelInfo(ped->GetModelIndex())->GetColModel()->spheres->center.z + 0.25f;
+ CVector forward(0.09f * ped->GetForward() + ped->GetPosition());
+ forward.z += CModelInfo::GetModelInfo(ped->GetModelIndex())->GetColModel()->spheres[2].center.z + 0.35f;
CEntity *obstacle = CWorld::TestSphereAgainstWorld(forward, 0.25f, nil, true, true, false, true, false, false);
if (!obstacle) {
@@ -8054,11 +9193,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 +9217,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 +9236,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 +9325,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 +9362,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 +9401,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 +9610,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 +9628,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..20df6553 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,69 @@ 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);
- } else {
+ } else 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);
-
- if (FindPlayerPed() == this && TheCamera.Cams[0].Using3rdPersonMouseCam())
- ((CPlayerPed*)this)->m_fFPSMoveHeading = TheCamera.Find3rdPersonQuickAimPitch();
}
}
#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 +365,7 @@ CPed::SetAttack(CEntity *victim)
return;
}
- if (IsPlayer() || !victimPed || victimPed->IsPedInControl()) {
+ if (IsPlayer() || (!victimPed || victimPed->IsPedInControl())) {
if (IsPlayer())
CPad::GetPad(0)->ResetAverageWeapon();
@@ -347,7 +379,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 +390,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 +438,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 +465,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);
-
- if (!weaponAssoc && weapon->IsFlagSet(WEAPONFLAG_THROW))
- weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_THROW_UNDER);
+ CAnimBlendAssociation *weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetPrimaryFireAnim(weapon));
- 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 +622,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 +635,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 +657,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 +802,122 @@ 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
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 +935,94 @@ 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)) {
- 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);
+ 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())) {
+
+ 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);
-#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 +1032,7 @@ CPed::Attack(void)
}
}
}
+
if (weaponAnimAssoc->currentTime > delayBetweenAnimAndFire)
attackShouldContinue = false;
@@ -774,7 +1042,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 +1054,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 +1171,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 +1201,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 +1243,6 @@ CPed::StartFightDefend(uint8 direction, uint8 hitLevel, uint8 unk)
hitAssoc->SetRun();
hitAssoc->flags |= ASSOC_FADEOUTWHENDONE;
}
-#endif
}
Say(SOUND_PED_DEFEND);
} else {
@@ -987,20 +1252,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 +1310,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 +1348,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 +1378,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 +1411,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 +1441,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 (!nearPed->OnGroundOrGettingUp()) {
+ if (!IsPlayer())
+ Say(SOUND_PED_ATTACK);
- if (nearPedDist < 0.8f && neededTurn < DEGTORAD(75.0f) && canKneeHead) {
- canAffectMultiplePeople = false;
- } else if (nearPedDist >= 1.3f || neededTurn >= DEGTORAD(55.0f) || hasShoppingBags) {
+ if (m_curFightMove != FIGHTMOVE_IDLE)
+ m_lastFightMove = m_curFightMove;
- if (nearPedDist < 1.7f
- && neededTurn < DEGTORAD(35.0f)
- && (canKick || hasShoppingBags)) {
+ m_curFightMove = IsPlayer() ? ChooseAttackPlayer(m_fightButtonPressure, fightWithWeapon) : ChooseAttackAI(m_fightButtonPressure, fightWithWeapon);
- 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;
+ if (m_curFightMove != FIGHTMOVE_IDLE) {
- float fightingPedDist = (m_pedInObjective->GetPosition() - GetPosition()).Magnitude();
- if (hasShoppingBags) {
- if (fightingPedDist >= 1.7f)
- nextFightMove = FIGHTMOVE_SHUFFLE_F;
- else
- nextFightMove = FIGHTMOVE_ROUNDHOUSE;
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), m_curFightMove < FIGHTMOVE_MELEE1 ? ASSOCGRP_STD : weaponInfo->m_AnimToPlay,
+ tFightMoves[m_curFightMove].animId, 8.0f);
- } else if (punchOnly) {
- if (fightingPedDist >= 1.3f)
- 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_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 +1567,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 +1592,7 @@ CPed::Fight(void)
}
} else {
+ m_lastFightMove = m_curFightMove;
m_curFightMove = FIGHTMOVE_IDLE;
if (IsPlayer())
m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 500;
@@ -1445,6 +1601,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 +1936,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 +1961,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 +2033,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;
+
+ victim->StartFightDefend(direction, tFightMoves[m_curFightMove].hitLevel, unk2);
+ PlayHitSound(victim);
+ m_fightState = FIGHTSTATE_JUST_ATTACKED;
+ RpAnimBlendClumpGetAssociation(GetClump(), tFightMoves[m_curFightMove].animId)->speed = 0.6f;
- // 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;
+ 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 (!nearPed->OnGround()) {
- float curVictimHealth = nearPed->m_fHealth;
+ 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);
+ }
+ }
+
+ 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 +2295,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 +2324,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 +2343,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 +2367,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 +2414,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 +2474,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 +2524,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 +2592,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 +2642,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 +2677,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 +2691,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 +2748,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 +2903,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 +3001,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 +3060,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 +3079,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 +3131,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 +3148,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 +3211,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 +3235,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 +3254,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 +3281,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 +3350,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 +3366,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 +3396,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 +3459,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 +3475,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 +3496,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 +3506,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 +3538,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 +3561,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 +3614,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 +3623,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 +3685,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 +3730,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 +3745,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 +3794,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 +3813,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 +3824,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 +3839,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..1d96ba6d 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,33 @@ 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");
}
-void CPlayerPed::ClearWeaponTarget()
+void
+CPlayerPed::ClearWeaponTarget()
{
if (m_nPedType == PEDTYPE_PLAYER1) {
SetWeaponLockOnTarget(nil);
@@ -97,11 +127,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 +178,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 +214,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 +238,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 +266,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 +287,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 +302,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 +333,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 +351,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 +365,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 +376,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 +405,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 +453,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 +470,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 +516,8 @@ CPlayerPed::SetRealMoveAnim(void)
curRunAssoc->blendAmount = 1.0f;
m_nMoveState = PEDMOVE_RUN;
}
+ curWalkAssoc->blendDelta = 0.0f;
+ curRunAssoc->blendDelta = 0.0f;
}
}
}
@@ -488,6 +544,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 +559,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 +627,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 +649,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 +667,7 @@ CPlayerPed::IsThisPedAttackingPlayer(CPed *suspect)
default:
break;
}
- return false;
+ return suspect->m_nPedState == PED_ABSEIL;
}
void
@@ -583,78 +676,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 +802,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 +884,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 +909,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 +923,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 +967,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 +1004,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 +1016,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 +1060,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 +1110,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 +1143,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 +1152,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 +1184,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 +1223,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 +1303,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 +1328,35 @@ 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);
// On this one we can rotate arm.
- if (weaponInfo->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM)) {
+ if (CAN_AIM_WITH_ARM) {
if (!padUsed->GetWeapon()) { // making this State != ATTACK still stops it after attack. Re-start it immediately!
SetPointGunAt(nil);
bIsPointingGunAt = false; // to not stop after attack
}
-
+ pointedGun = 2;
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 +1372,21 @@ 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 && m_nPedState != PED_ATTACK) {
+ 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 +1394,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 +1426,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 +1436,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 +1451,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 +1480,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 +1489,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 +1516,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 +1541,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 +1720,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 +1752,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 +1771,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 +1793,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 +1822,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 +1878,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 +1890,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 +1927,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 +2216,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 +2230,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..1b7158b5 100644
--- a/src/peds/PlayerPed.h
+++ b/src/peds/PlayerPed.h
@@ -15,25 +15,40 @@ 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;
+
+ static bool bDontAllowWeaponChange;
+#ifndef MASTER
+ static bool bDebugPlayerInfo;
+#endif
CPlayerPed();
~CPlayerPed();
@@ -45,7 +60,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 +69,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 +111,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 fcabff91..65bc80da 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::GetModelInfo(obj->GetModelIndex())->GetColModel()->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::GetModelInfo(gangModel)->GetColModel()->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::GetModelInfo(manModel)->GetColModel()->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::GetModelInfo(womanModel)->GetColModel()->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::GetModelInfo(pedModel)->GetColModel()->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..1e4d289b 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::GetModelInfo(MI_ESCALATORSTEP)->GetColModel()->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 25effc81..49e8e611 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::GetModelInfo(e->GetModelIndex())->GetColModel(), 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::GetModelInfo(e->GetModelIndex())->GetColModel(), 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 f51f8233..c42ae738 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 {
@@ -672,6 +715,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 +726,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 +735,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;
@@ -717,23 +760,23 @@ GetSaveType(char *savename)
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 +788,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 +834,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 +843,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 +851,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 +872,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 +934,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 +943,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 +965,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;
@@ -1042,6 +1056,9 @@ FixSave(int32 slot, uint8 save_type)
LoadSaveDataBlockNoCheck(buf, file_in, size); // garages
FixSaveDataBlock(FixGarages, file_out, size); // garages need to be fixed in either case
+ LoadSaveDataBlockNoCheck(buf, file_in, size); // game logic
+ WriteSavaDataBlockNoFunc(buf, file_out, size);
+
LoadSaveDataBlockNoCheck(buf, file_in, size); // vehicle pool
WriteSavaDataBlockNoFunc(buf, file_out, size);
@@ -1076,10 +1093,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);
@@ -1096,12 +1110,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);
@@ -1153,13 +1176,20 @@ void DisplaySaveResult(int unk, char* name)
bool SaveGameForPause(int type)
{
- if (AllowMissionReplay != 0 || type != 3 && WaitForSave > CTimer::GetTimeInMilliseconds())
+ if (AllowMissionReplay != 0 && AllowMissionReplay != 7) {
+ debug("SaveGameForPause failed during AllowMissionReplay %d", AllowMissionReplay);
return false;
+ }
+ if (type != 3 && 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 != 5)) {
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 b291ddf9..b2bf7a24 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;
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..f7016b21 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))
@@ -279,3 +279,17 @@ 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
diff --git a/src/skel/crossplatform.h b/src/skel/crossplatform.h
index aa90ce5a..f37e64a1 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>.
diff --git a/src/skel/glfw/glfw.cpp b/src/skel/glfw/glfw.cpp
index 8d3fc7d7..0928229f 100644
--- a/src/skel/glfw/glfw.cpp
+++ b/src/skel/glfw/glfw.cpp
@@ -159,7 +159,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 +199,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);
@@ -402,10 +406,6 @@ psInitialize(void)
InitialiseLanguage();
-#if GTA_VERSION < GTA3_PC_11
- FrontEndMenuManager.LoadSettings();
-#endif
-
#endif
gGameState = GS_START_UP;
@@ -455,13 +455,9 @@ psInitialize(void)
#ifndef PS2_MENU
-
-#if GTA_VERSION >= GTA3_PC_11
FrontEndMenuManager.LoadSettings();
#endif
-#endif
-
#ifdef _WIN32
MEMORYSTATUS memstats;
@@ -485,11 +481,27 @@ psInitialize(void)
debug("Physical memory size %llu\n", _dwMemAvailPhys);
debug("Available physical memory %llu\n", size);
#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 +919,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,12 +950,33 @@ 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;
@@ -961,7 +994,7 @@ void psPostRWinit(void)
glfwSetJoystickCallback(joysChangeCB);
_InputInitialiseJoys();
- _InputInitialiseMouse();
+ _InputInitialiseMouse(false);
if(!(vm.flags & rwVIDEOMODEEXCLUSIVE))
glfwSetWindowSize(PSGLOBAL(window), RsGlobal.maximumWidth, RsGlobal.maximumHeight);
@@ -1140,7 +1173,7 @@ void InitialiseLanguage()
|| primLayout == LANG_GERMAN )
{
CGame::nastyGame = false;
- CMenuManager::m_PrefsAllowNastyGame = false;
+ FrontEndMenuManager.m_PrefsAllowNastyGame = false;
CGame::germanGame = true;
}
@@ -1149,7 +1182,7 @@ void InitialiseLanguage()
|| primLayout == LANG_FRENCH )
{
CGame::nastyGame = false;
- CMenuManager::m_PrefsAllowNastyGame = false;
+ FrontEndMenuManager.m_PrefsAllowNastyGame = false;
CGame::frenchGame = true;
}
@@ -1160,7 +1193,7 @@ void InitialiseLanguage()
#ifdef NASTY_GAME
CGame::nastyGame = true;
- CMenuManager::m_PrefsAllowNastyGame = true;
+ FrontEndMenuManager.m_PrefsAllowNastyGame = true;
CGame::noProstitutes = false;
#endif
@@ -1195,33 +1228,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;
}
}
@@ -1923,7 +1956,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 )
{
@@ -1982,7 +2015,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();
@@ -2011,7 +2044,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
@@ -2110,6 +2143,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;
@@ -2122,15 +2156,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 )
{
@@ -2213,7 +2247,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;
@@ -2316,7 +2350,6 @@ main(int argc, char *argv[])
#endif
}
-
#ifndef MASTER
if ( gbModelViewer )
CAnimViewer::Shutdown();
@@ -2487,5 +2520,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 01e56701..f251f58d 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 )
{
@@ -2209,7 +2207,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();
@@ -2298,6 +2296,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() )
@@ -2322,7 +2322,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");
@@ -2338,6 +2338,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() )
@@ -2377,6 +2379,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;
@@ -2394,10 +2397,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 )
{
@@ -2482,7 +2486,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;
@@ -2651,7 +2655,7 @@ HRESULT _InputInitialise()
return S_OK;
}
-HRESULT _InputInitialiseMouse()
+HRESULT _InputInitialiseMouse(bool exclusive)
{
HRESULT hr;
@@ -2669,7 +2673,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
@@ -2957,6 +2961,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;
@@ -3426,5 +3452,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 7d942dcd..9395ded8 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,15 @@ CAutomobile::SetModelIndex(uint32 id)
SetupModelNodes();
}
+#define SAND_SLOWDOWN (0.01f)
+float CAR_BALANCE_MULT = 0.3f;
+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 +266,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 +299,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 +311,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 +321,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 +343,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 +354,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 +373,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 +395,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 +404,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 +477,7 @@ CAutomobile::ProcessControl(void)
PlayHornIfNecessary();
ReduceHornCounter();
bVehicleColProcessed = false;
+ bAudioChangingGear = false;
// that's all we do for simple vehicles
return;
@@ -396,15 +485,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 +531,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 +584,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 +601,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 +633,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 +676,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 +695,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 +754,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 +779,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 +809,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 +829,6 @@ CAutomobile::ProcessControl(void)
}
}
-
bool gripCheat = true;
fwdSpeed = DotProduct(m_vecMoveSpeed, GetForward());
if(!strongGrip1 && !CVehicle::bCheat3)
@@ -677,16 +836,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 +905,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 +917,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 +934,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 +977,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 +1017,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 +1084,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 +1099,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 +1109,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 +1117,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 +1144,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 +1154,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 +1163,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];
}
- 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 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);
+ }
+ }
+
+ // 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];
+ }
+ 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];
}
- m_aWheelRotation[CARWHEEL_REAR_RIGHT] += m_aWheelSpeed[CARWHEEL_REAR_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+4) % 5]){
- 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+4) % 5] &&
Pads[0].bHornHistory[(Pads[0].iCurrHornHistory+3) % 5])
@@ -1012,42 +1376,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(blade, GetMatrix());
+ camDist /= Max(Sqrt(distSq), 0.01f);
+ if(Abs(DotProduct(camDist, blade)) > 0.95f){
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_HELI_BLADE, 0.0f);
+ m_fPropellerRotation = m_aWheelRotation[1];
+ }
}
}
}
@@ -1090,7 +1558,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 +1570,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 +1583,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 +1591,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 > 0.04f){
+ 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 +1607,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 +1615,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 +1640,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 +1650,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 +1671,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 +1690,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 +1740,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 +1761,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 +1816,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 +1836,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 +1931,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 +1949,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 +1984,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 +2009,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 +2136,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 +2175,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 +2202,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 +2220,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 +2260,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 +2274,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 +2365,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 +2439,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 +2531,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();
+ if(m_aWheelRotation[1] > TWOPI) m_aWheelRotation[1] -= TWOPI;
+ // rear rotor
+ m_aWheelRotation[3] += m_aWheelSpeed[1]*CTimer::GetTimeStep();
+ if(m_aWheelRotation[3] > TWOPI) m_aWheelRotation[3] -= TWOPI;
+ onlyFrontWheels = true;
}
CVector contactPoints[4]; // relative to model
@@ -1961,7 +2575,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 +2586,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 +2750,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 +2779,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 +2918,104 @@ CAutomobile::Render(void)
ProcessSwingingDoor(CAR_DOOR_RR, DOOR_REAR_RIGHT);
ProcessSwingingDoor(CAR_BONNET, DOOR_BONNET);
ProcessSwingingDoor(CAR_BOOT, DOOR_BOOT);
+ }
- mi->SetVehicleColour(m_currentColour1, m_currentColour2);
+ 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;
+
+ 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 +3038,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 +3050,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 +3062,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 +3095,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 +3128,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 +3184,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 +3203,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 +3230,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 +3387,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 +3498,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 +3571,6 @@ CAutomobile::HydraulicControl(void)
}
setPrevRatio = true;
- m_aWheelPosition[i] -= 0.05f;
}
DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_HYDRAULIC_2, 0.0f);
}
@@ -2767,7 +3601,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 +3620,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;
@@ -2861,19 +3690,47 @@ CAutomobile::ProcessBuoyancy(void)
CVector impulse, point;
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 = 1.0f/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 +3745,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 +3814,7 @@ CAutomobile::ProcessBuoyancy(void)
}
}else{
bIsInWater = false;
+ bIsDrowning = false;
bTouchingWater = false;
static RwRGBA splashCol = {155, 155, 185, 196};
@@ -2981,13 +3825,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 +3845,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 +3853,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 +3879,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 +3930,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.x = (lower.x - upper.x)*m_aSuspensionSpringRatio[i] + upper.x;
+ m_aWheelColPoints[i].point.y = (lower.y - upper.y)*m_aSuspensionSpringRatio[i] + upper.y;
+ m_aWheelColPoints[i].point.z = waterZ;
+ m_aWheelColPoints[i].normal = CVector(0.01f, 0.0f, 1.0f);
+ m_aWheelColPoints[i].surfaceB = SURFACE_WATER;
+ }
+ }
+}
+
int32
CAutomobile::RcbanditCheckHitWheels(void)
{
@@ -3150,7 +4007,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 +4082,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 +4090,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 +4126,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 +4156,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 +4244,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 +4354,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 +4381,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 +4458,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 +4481,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 +4493,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 +4627,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 +4648,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 +4733,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 +4780,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 +4820,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 +4850,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;
@@ -3955,10 +4879,12 @@ CAutomobile::SetUpWheelColModel(CColModel *colModel)
return true;
}
-// this probably isn't used in III yet
void
-CAutomobile::BurstTyre(uint8 wheel)
+CAutomobile::BurstTyre(uint8 wheel, bool applyForces)
{
+ 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;
@@ -3969,14 +4895,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(-0.03f, 0.03f));
- ApplyTurnForce(GetRight() * m_fTurnMass * CGeneral::GetRandomNumberInRange(-0.03f, 0.03f), GetForward());
+ if(applyForces){
+ ApplyMoveForce(GetRight() * m_fMass * CGeneral::GetRandomNumberInRange(-0.03f, 0.03f));
+ ApplyTurnForce(GetRight() * m_fTurnMass * CGeneral::GetRandomNumberInRange(-0.03f, 0.03f), GetForward());
+ }
}
}
@@ -4022,7 +4952,7 @@ CAutomobile::IsRoomForPedToLeaveCar(uint32 component, CVector *doorOffset)
CVector dist = doorPos - seatPos;
- // Removing that makes this func. return false for van doors.
+ // 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);
@@ -4053,10 +4983,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){
@@ -4078,7 +5014,6 @@ CAutomobile::PlayHornIfNecessary(void)
PlayCarHorn();
}
-
void
CAutomobile::ResetSuspension(void)
{
@@ -4121,8 +5056,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;
@@ -4156,13 +5091,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
@@ -4222,24 +5160,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;
@@ -4254,24 +5197,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);
+ }
+ }
}
}
}
@@ -4342,6 +5326,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 };
@@ -4351,6 +5338,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
@@ -4377,6 +5385,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
@@ -4418,8 +5439,6 @@ GetCurrentAtomicObjectCB(RwObject *object, void *data)
return object;
}
-static CColPoint aTempPedColPts[MAX_COLLISION_POINTS];
-
CObject*
CAutomobile::SpawnFlyingComponent(int32 component, uint32 type)
{
@@ -4452,6 +5471,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);
@@ -4478,6 +5498,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;
@@ -4536,9 +5557,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)
@@ -4576,11 +5604,14 @@ CAutomobile::SetPanelDamage(int32 component, ePanels panel, bool noFlyingCompone
if(m_aCarNodes[component] == nil)
return;
if(status == PANEL_STATUS_SMASHED1){
+ 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
+ CGlass::CarWindscreenShatters(this, false);
// hide both
SetComponentVisibility(m_aCarNodes[component], ATOMIC_FLAG_NONE);
}
@@ -4616,6 +5647,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;
@@ -4712,13 +5748,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
@@ -4726,7 +5879,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 22b2fc60..29d0c5c7 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::GetModelInfo(m_nModelIndex)->GetColModel()->boundingBox.min;
- m_vecSup = CModelInfo::GetModelInfo(m_nModelIndex)->GetColModel()->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::GetModelInfo(mi)->GetColModel();
+ 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..5f0cf36a 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..c0319a11 100644
--- a/src/weapons/Weapon.cpp
+++ b/src/weapons/Weapon.cpp
@@ -30,25 +30,24 @@
#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] =
-{
- 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
-};
+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
CWeaponInfo *
CWeapon::GetInfo()
@@ -58,6 +57,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 +76,7 @@ CWeapon::InitialiseWeapons(void)
CExplosion::Initialise();
CProjectileInfo::Initialise();
CBulletInfo::Initialise();
+ bPhotographHasBeenTaken = false;
}
void
@@ -87,18 +98,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 +142,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 +166,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 +242,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 +259,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 +283,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 +305,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_nAmmoTotal > 0 && (m_nAmmoTotal < 25000 || isPlayer)) m_nAmmoTotal--;
+ if (m_nAmmoInClip > 0)
+ m_nAmmoInClip--;
+
+ 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 +372,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 +391,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 +403,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 +420,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 +430,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 +454,6 @@ CWeapon::FireFromCar(CAutomobile *shooter, bool left)
}
m_nTimer = CTimer::GetTimeInMilliseconds() + 1000;
- if ( shooter == FindPlayerVehicle() )
- CStats::RoundsFiredByPlayer++;
}
return true;
@@ -360,27 +467,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 +514,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 +556,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 +689,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 +875,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 +885,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 +928,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 +943,43 @@ 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);
+ TheCamera.Find3rdPersonCamTargetVector(info->m_fRange, *fireSource, source, target);
#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;
+ target.x = info->m_fRange;
+ target.y = 0.0f;
+ target.z = 0.0f;
- shooterPed->TransformToNode(trgt, PED_HANDR);
+ shooterPed->TransformToNode(target, PED_HANDR);
}
#endif
#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 +987,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:
+ 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;
- gunflashPos += CVector(0.06f*ahead.x, 0.06f*ahead.y, 0.0f);
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.10f);
- gunflashPos += CVector(0.06f*ahead.x, 0.06f*ahead.y, 0.0f);
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.08f);
- gunflashPos += CVector(0.05f*ahead.x, 0.05f*ahead.y, 0.0f);
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.06f);
- gunflashPos += CVector(0.04f*ahead.x, 0.04f*ahead.y, 0.0f);
- CParticle::AddParticle(PARTICLE_GUNFLASH_NOANIM, gunflashPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.04f);
-
- CVector gunsmokePos = *fireSource;
- float rnd = CGeneral::GetRandomNumberInRange(0.05f, 0.25f);
- CParticle::AddParticle(PARTICLE_GUNSMOKE2, gunsmokePos, CVector(ahead.x*rnd, ahead.y*rnd, 0.0f));
-
- CVector gunshellPos = *fireSource;
- gunshellPos -= CVector(0.5f*ahead.x, 0.5f*ahead.y, 0.0f);
- CVector dir = CrossProduct(CVector(ahead.x, ahead.y, 0.0f), CVector(0.0f, 0.0f, 5.0f));
- dir.Normalise2D();
- AddGunshell(shooter, gunshellPos, CVector2D(dir.x, dir.y), 0.018f);
- }
-
- break;
- }
-
- case WEAPONTYPE_M16:
- {
- static uint8 counter = 0;
-
- if ( !(++counter & 1) )
- {
- 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 +1110,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 +1151,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 +1192,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 +1285,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 +1299,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 +1400,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();
- victimPed->InflictDamage(shooter, m_eWeaponType, info->m_nDamage, (ePedPieceTypes)point->pieceB, localDir);
+ 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;
}
+
+ 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 +1491,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 +1508,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 +1556,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 +1590,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 +1616,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 +1624,7 @@ CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim,
BlowUpExplosiveThings(victim);
}
+
bool
CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
{
@@ -1196,10 +1670,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();
@@ -1212,12 +1711,16 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
TheCamera.Find3rdPersonCamTargetVector(1.0f, *fireSource, source, target);
CVector Left = CrossProduct(TheCamera.Cams[TheCamera.ActiveCam].Front, TheCamera.Cams[TheCamera.ActiveCam].Up);
- float f = float(i - 2) * (DEGTORAD(7.5f) / 2);
+ float f = (i - (shootsAtOnce / 2)) * angleBetweenTwoShot;
target = f * Left + target - source;
target *= info->m_fRange;
target += source;
-
- 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 +1736,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 +1826,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 +1852,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 +1864,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 +1902,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 +1954,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 +1985,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 +2023,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 +2040,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 +2087,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 +2096,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;
}
@@ -1538,26 +2164,85 @@ 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
#endif
@@ -1569,15 +2254,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 +2271,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 +2348,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 +2360,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 +2375,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 +2389,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 +2398,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 +2537,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 +2550,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 +2637,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 +2658,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 +2676,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 +2696,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 +2788,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 +2800,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 +2838,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 +2875,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 +2889,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 +2910,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 +3039,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 +3078,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 +3171,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 +3197,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 +3225,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
diff --git a/utils/gxt/american.txt b/utils/gxt/american.txt
index d8f79f05..66d74238 100644
--- a/utils/gxt/american.txt
+++ b/utils/gxt/american.txt
@@ -1,71 +1,17 @@
-[LETTER1]
-abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789"$,.'-?!!SDBF
-
-[DEFNAM]
-Claude----------------------
-
-[IN_VEH]
+[IN_VEH]
~g~Hey! Get back in the vehicle!
-[IN_VEH2]
-~g~You need some wheels for this job!
-
-[IN_BOAT]
-~g~You need a boat for this job!
-
[HEY]
~g~Don't go solo, keep your posse together!
-[HEY2]
-~g~Don't split up, keep the group together!
-
-[HEY3]
-~g~You've dropped your main man, go back and get 8-Ball!
-
-[HEY4]
-~g~Lose Misty and Luigi will lose your face! Go and get her!
-
-[HEY5]
-~g~One of the girls is AWOL, Go back and round her up!
-
-[HEY6]
-~g~You left your honor with the Yakuza Kanbu. You must protect him!
-
-[HEY7]
-~g~An extra gun could be useful. Go back and pick up your contact!
-
-[HEY8]
-~g~Protection means just that -Protect the Old Oriental Gentleman!
-
-[HEY9]
-~g~You want the word on the street? Go see the contact!
-
-[HELP2_A]
-Press the ~h~/ button~w~ when running to ~h~sprint.
-
[HELP3]
You can only sprint for short periods before becoming tired.
-[HELP4_A]
-Press the~h~ ~k~~VEHICLE_ACCELERATE~ button~w~ to ~h~accelerate.
-
[HELP4_D]
-Push the~h~ right analog stick~w~ up to ~h~accelerate.
-
-[HELP5_A]
-Press the~h~ ~k~~VEHICLE_BRAKE~ button~w~ to ~h~brake~w~, or to ~h~reverse~w~ if the vehicle has stopped.
+Push the right analog stick up to ~h~accelerate.
[HELP5_D]
-Pull the ~h~right analog stick~w~ back to ~h~brake~w~, or to ~h~reverse~w~ if the vehicle has stopped.
-
-[HELP6_A]
-Press the~h~ ~k~~VEHICLE_HANDBRAKE~ button ~w~to apply the vehicle's ~h~handbrake.
-
-[HELP6_C]
-Press the~h~ ~k~~VEHICLE_HANDBRAKE~ button ~w~to apply the vehicle's ~h~handbrake.
-
-[HELP6_D]
-Press the~h~ ~k~~VEHICLE_HANDBRAKE~ button ~w~to apply the vehicle's ~h~handbrake.
+Pull the right analog stick back to brake, or to reverse if the vehicle has stopped.
[HELP7_A]
Press and hold the~h~ ~k~~PED_LOCK_TARGET~ button ~w~to ~h~target~w~ with the sniper rifle.
@@ -73,12 +19,6 @@ Press and hold the~h~ ~k~~PED_LOCK_TARGET~ button ~w~to ~h~target~w~ with the sn
[HELP7_D]
Press and hold the~h~ ~k~~PED_LOCK_TARGET~ button ~w~to ~h~target ~w~with the sniper rifle.
-[HELP8_A]
-Press the~h~ ~k~~PED_SNIPER_ZOOM_IN~ button ~w~to ~h~zoom in ~w~with the rifle and the~h~ ~k~~PED_SNIPER_ZOOM_OUT~ button ~w~to ~h~zoom out ~w~again.
-
-[HELP9_A]
-Press the~h~ ~k~~PED_FIREWEAPON~ button ~w~to ~h~fire~w~ the sniper rifle.
-
[HELP10]
This badge indicates you have a police wanted level.
@@ -91,75 +31,48 @@ Sometimes you may need to use pathways not shown on the radar.
[TIMER]
This is a timed mission, you must complete it before the timer counts down to zero.
-[MISTY1]
-~r~Misty is morgue-meat!
-
-[OUT_VEH]
-~g~Get out of the vehicle!
-
-[GARAGE]
-Drive the vehicle into the garage, then walk outside.
-
-[WANTED1]
-~g~Shake the cops and lose your wanted level!
-
-[NODOORS]
-~g~They ain't sardines! Get some wheels with enough seats.
-
-[TRASH]
-~g~You've junked your wheels real bad! Get your vehicle repaired!
-
-[WRECKED]
-~r~The vehicle is wrecked!
-
[HORN]
~g~Sound the horn.
[NOMONEY]
~g~You need more cash!
-[OUTTIME]
-~r~Too slow, man, too slow!
-
-[SPOTTED]
-~r~They're on to you!
-
[REWARD]
REWARD $~1~
-[GAMEOVR]
-GAME OVER
-
-[Z]
-Z-axis value: ~1~
-
[M_FAIL]
MISSION FAILED!
[M_PASS]
MISSION PASSED! $~1~
-[O_PASS]
-ODD JOB PASSED!
-
-[O_FAIL]
-ODD JOB FAILED!
-
[DEAD]
WASTED!
[BUSTED]
BUSTED!
-[S_PROMP]
-When not on a mission you can ~h~save your game here~w~, this will advance time six hours.
+[WEATHE1]
+FORCE WEATHER SUNNY
+
+[WEATHE2]
+FORCE WEATHER EXTRA SUNNY
+
+[WEATHE3]
+FORCE WEATHER CLOUDY
+
+[WEATHE4]
+FORCE WEATHER RAINY
+
+[WEATHE5]
+FORCE WEATHER FOGGY
+
+[WEATHE6]
+WEATHER NORMAL
[NUMBER]
~1~
-[SCORE]
-$~1~
-
[LOADCAR]
LOADING VEHICLE... (PRESS L1 TO CANCEL)
@@ -178,44 +91,11 @@ Cheat mode ON
[CHEATOF]
Cheat mode OFF
-[UZI_IN]
-The Uzi is now in stock at Ammunation!
-
[IMPORT1]
Go outside and wait for your vehicle.
-[PAGEB1]
-Pistol delivered to hideout
-
-[PAGEB2]
-Uzi delivered to hideout
-
-[PAGEB3]
-Body armor delivered to hideout
-
-[PAGEB4]
-Shotgun delivered to hideout
-
-[PAGEB5]
-grenades delivered to hideout
-
-[PAGEB6]
-molotovs delivered to hideout
-
-[PAGEB7]
-AK47 delivered to hideout
-
-[PAGEB8]
-Sniper rifle delivered to hideout
-
-[PAGEB9]
-M16 delivered to hideout
-
-[PAGEB10]
-Rocket Launcher delivered to hideout
-
[PAGEB11]
-Flamethrower delivered to hideout
+Flamethrower delivered to hideout.
[WANT_A]
You will only be arrested if you have a ~h~wanted level.
@@ -259,32 +139,8 @@ You will lose your weapons and the doctors will take some cash for patching you
[HEAL_E]
You will find ways of healing or protecting yourself the more you play the game.
-[DAM]
-DAMAGE:
-
-[KILLS]
-KILLS:
-
-[FARES]
-FARES:
-
-[BULL]
-BULLION:
-
-[EVID]
-EVIDENCE:
-
-[HEALTH]
-CAR HEALTH:
-
-[COLLECT]
-COLLECTED:
-
-[BOMB]
-Drive your vehicle into the bomb shop to attach a ~h~bomb~w~. Cost - ~h~$1000.
-
[SAVE1]
-Walk through the doorway to ~h~Save the game~w~. You cannot save during a mission.
+Walk into the corona to ~h~Save the game~w~. You cannot save during a mission.
[SAVE2]
Any vehicle left in this garage will be stored when the game is saved.
@@ -292,4869 +148,4737 @@ Any vehicle left in this garage will be stored when the game is saved.
[AMMU]
Go inside Ammu-Nation to buy a weapon.
-[BRIDGE1]
-When the Callahan Bridge is repaired you will be able to drive to Staunton Island.
-
-[TUNNEL]
-When the Porter Tunnel is opened you will be able to drive to Staunton Island.
-
-[LUIGI]
-LUIGI MISSIONS
-
-[TONI]
-TONI MISSIONS
-
-[JOEY]
-JOEY MISSIONS
+[R_TIME]
+RACE TIME:
-[FRANK]
-SALVATORE MISSIONS
+[PROP_1]
+You don't have enough cash for this property
-[DIABLO]
-DIABLO MISSIONS
+[PROP_2]
+You cannot buy property whilst on a mission
-[ASUKA]
-ASUKA MISSIONS
+[IND_ZON]
+Vice City Beach
-[B_SITE]
-ASUKA SUBURBAN MISSIONS
+[COM_ZON]
+Vice City Mainland
-[KENJI]
-KENJI MISSIONS
+[BEACH1]
+Ocean Beach
-[RAY]
-RAY MISSIONS
+[BEACH2]
+Washington Beach
-[LOVE]
-LOVE MISSIONS
+[BEACH3]
+Vice Point
-[YARDIE]
-YARDIE MISSIONS
+[GOLFC]
+Leaf Links
-[HOOD]
-HOOD MISSIONS
+[STARI]
+Starfish Island
-[CITYZON]
-Liberty City
+[DOCKS]
+Viceport
-[IND_ZON]
-Portland
+[HAVANA]
+Little Havana
-[PORT_W]
-Callahan Point
+[HAITI]
+Little Haiti
-[PORT_S]
-Atlantic Quays
+[PORNI]
+Prawn Island
-[PORT_E]
-Portland Harbor
+[DTOWN]
+Downtown
-[PORT_I]
-Trenton
+[VICE_C]
+Vice City
-[S_VIEW]
-Portland View
+[A_PORT]
+Escobar International
-[CHINA]
-Chinatown
+[JUNKY]
+Junk Yard
-[EASTBAY]
-Portland Beach
+[PISTOL]
+Pistol
-[LITTLEI]
-Saint Mark's
+[PYTHON]
+.357
-[REDLIGH]
-Red Light District
+[UZI]
+Uz-1
-[TOWERS]
-Hepburn Heights
+[TEC9]
+Tec 9
-[HARWOOD]
-Harwood
+[M4]
+M4
-[ROADBR1]
-Callahan Bridge
+[INGRAM]
+Mac
-[ROADBR2]
-Callahan Bridge
+[MP5]
+MP
-[TUNNELP]
-Porter Tunnel
+[RUGER]
+Kruger
-[BOMB1]
-8-Ball's Garage
+[SNIPE]
+Sniper rifle
-[COM_ZON]
-Staunton Island
+[GRENADE]
+Grenades
-[STADIUM]
-Aspatria
+[SHOTGN1]
+Shotgun
-[HOSPI_2]
-Rockford
+[SHOTGN2]
+S.P.A.S. 12
-[UNIVERS]
-Liberty Campus
+[SHOTGN3]
+Stubby shotgun
-[CONSTRU]
-Fort Staunton
+[ARMOUR]
+Body Armor
-[PARK]
-Belleville Park
+[LASER]
+.308 Sniper
-[COM_EAS]
-Newport
+[BASEBAT]
+Baseball bat
-[SHOPING]
-Bedford Point
+[HAMMER]
+Hammer
-[YAKUSA]
-Torrington
+[SCREWD]
+Screwdriver
-[SUB_ZON]
-Shoreside Vale
+[CLEVER]
+Meat Cleaver
-[AIRPORT]
-Francis Intl. Airport
+[MACHETE]
+Machete
-[PROJECT]
-Wichita Gardens
+[KNIFE]
+Knife
-[SUB_IND]
-Pike Creek
+[KATANA]
+Katana
-[SWANKS]
-Cedar Grove
+[CHAINSA]
+Chainsaw
-[BIG_DAM]
-Cochrane Dam
-
-[SUB_ZO2]
-Shoreside Vale
-
-[SUB_ZO3]
-Shoreside Vale
+[G_COST]
+Cost: $~1~
[CAR_1]
Ambulance
-[CAR_2]
-Firetruck
+[MALIBU]
+The Malibu Club
-[CAR_3]
-Police
+[MANSION]
+Diaz's Mansion
-[CAR_4]
-Enforcer
+[TMANS]
+Vercetti Estate
-[CAR_5]
-Barracks
+[STRIP]
+The 'Pole Position Club'
-[CAR_6]
-Rhino
+[MALL1]
+North Point Mall
-[CAR_7]
-FBIcar
+[BANKINT]
+El Banco Corrupto Grande
-[CAR_8]
-Securicar
+[RANGE]
+Rifle Range
-[CAR_9]
-Moonbeam
+[POL_HQ]
+VCPD HQ
-[CAR_10]
-Coach
+[INT_B]
+An Old Friend
-[CAR_11]
-Flatbed
+[INTB_1]
+~g~Go to the Lawyer's office.
-[CAR_12]
-Linerunner
+[LAW_1]
+The Party
-[CAR_13]
-Trashmaster
+[LAW_2]
+Back Alley Brawl
-[CAR_14]
-Patriot
+[LAW_3]
+Jury Fury
-[CAR_15]
-Mr Whoopee
+[LAW_4]
+Riot
-[CAR_16]
-Mule
+[COL_1]
+Treacherous Swine
-[CAR_17]
-Yankee
+[COL_2]
+Mall Shootout
-[CAR_18]
-Pony
+[COL_3]
+Guardian Angels
-[CAR_19]
-Bobcat
+[COL_4]
+Sir, Yes Sir!
-[CAR_20]
-Rumpo
+[COL_5]
+All Hands On Deck!
-[CAR_21]
-Blista
+[COK_1]
+The Chase
-[CAR_22]
-Dodo
+[COK_2]
+Phnom Penh '86
-[CAR_23]
-Bus
+[COK_3]
+The Fastest Boat
-[CAR_24]
-Sentinel
+[COK_4]
+Supply & Demand
-[CAR_25]
-Cheetah
+[KENT_1]
+Death Row
-[CAR_26]
-Banshee
+[ASS_1]
+Rub Out
-[CAR_27]
-Stinger
+[BUD_1]
+Shakedown
-[CAR_28]
-Infernus
+[BUD_2]
+Bar Brawl
-[CAR_29]
-Esperanto
+[BUD_3]
+Cop Land
-[CAR_30]
-Kuruma
+[CAP_1]
+Cap the Collector
-[CAR_31]
-Stretch
+[FIN_1]
+Keep your Friends Close...
-[CAR_32]
-Perennial
+[BANK_1]
+No Escape?
-[CAR_33]
-Landstalker
+[BANK_2]
+The Shootist
-[CAR_34]
-Manana
+[BANK_3]
+The Driver
-[CAR_35]
-Idaho
+[BANK_4]
+The Job
-[CAR_36]
-Stallion
+[CNT_1]
+Spilling the Beans
-[CAR_37]
-Taxi
+[CNT_2]
+Hit the Courier
-[CAR_38]
-Cabbie
+[PORN_1]
+Recruitment Drive
-[CAR_39]
-Buggy
+[PORN_2]
+Dildo Dodo
-[LUIGIS]
-Luigi's Place
+[PORN_3]
+Martha's Mug Shot
-[GOAWAY]
-~g~You are already on a mission!
+[PORN_4]
+G-spotlight
-[LUIGGO]
-~g~Luigi's interviewing some new girls -Come back later!
+[TAX_1]
+Kaufman Cabs
-[JOEYGO]
-~g~Joey's out on the town with Misty -Drop by later!
+[TAXI_1]
+V.I.P.
-[TONIGO]
-~g~Toni's taken his Momma to the opera -Call in some other time!
+[TAXI_2]
+Friendly Rivalry
-[KEMUGO]
-~g~Maria and Kemuri are all tied up at the moment -Drop by later!
+[TAXI_3]
+Cabmaggedon
-[KENJGO]
-~g~Kenji is attending a Yakuza meeting -Call by some other time!
+[ICE_1]
+Distribution
-[RAYGO]
-~g~Ray has other toilets to hang around -Try again later!
+[TEX_1]
+Four Iron
-[LOVEGO]
-~g~Donald Love has other business to attend to -Make an appointment later!
+[TEX_2]
+Two Bit Hit
-[KENSGO]
-~g~Kenji is busy! -Call by later!
+[TEX_3]
+Demolition Man
-[HOODGO]
-~g~The Hoods are not available at this time!
+[PHIL_1]
+Gun Runner
-[WRONGT1]
-~g~Come back between 05:00 and 21:00 for a job
+[PHIL_2]
+Boomshine Saigon
-[WRONGT2]
-~g~Come back between 06:00 and 14:00 for a job
+[BIKE_1]
+Alloy Wheels of Steel
-[WRONGT3]
-~g~Come back between 15:00 and 00:00 for a job
+[BIKE_2]
+Messing with the Man
-[GUN_1A]
-Use the ~h~~k~~PED_CYCLE_WEAPON_RIGHT~ button ~w~and the ~h~~k~~PED_CYCLE_WEAPON_LEFT~ button ~w~to cycle through your weapons.
+[BIKE_3]
+Hog Tied
-[GUN_2A]
-Hold the ~h~~k~~PED_LOCK_TARGET~ button ~w~to ~h~auto-target~w~, press the~h~ ~k~~PED_FIREWEAPON~ button ~w~to ~h~fire! Try shooting the targets...
+[ROCK_1]
+Love Juice
-[GUN_2C]
-Hold the ~h~~k~~PED_LOCK_TARGET~ button ~w~to ~h~auto-target~w~, press the~h~ ~k~~PED_FIREWEAPON~ button ~w~to ~h~fire! Try shooting the targets...
+[ROCK_2]
+Psycho Killer
-[GUN_2D]
-Hold the ~h~~k~~PED_LOCK_TARGET~ button ~w~to ~h~auto-target~w~, press the~h~ ~k~~PED_FIREWEAPON~ button ~w~to ~h~fire! Try shooting the targets...
+[ROCK_3]
+Publicity Tour
-[GUN_3A]
-While holding the ~h~~k~~PED_LOCK_TARGET~ button,~w~ press the ~h~~k~~PED_CYCLE_TARGET_LEFT~ button~w~ or the ~h~~k~~PED_CYCLE_TARGET_RIGHT~ button to switch target.
+[ROCK_4]
+Love Fist!!
-[GUN_3B]
-While holding the ~h~~k~~PED_LOCK_TARGET~ button,~w~ press the ~h~~k~~PED_CYCLE_TARGET_LEFT~ button~w~ or the ~h~~k~~PED_CYCLE_TARGET_RIGHT~ button to switch target.
+[HAT_1]
+Juju Scramble
-[GUN_4A]
-While holding the ~h~~k~~PED_LOCK_TARGET~ button~w~ you can walk or run while remaining locked onto a target.
+[HAT_2]
+Bombs Away!
-[GUN_4B]
-While holding the ~h~~k~~PED_LOCK_TARGET~ button~w~ you can walk or run while remaining locked onto a target.
+[HAT_3]
+Dirty Lickin's
-[GUN_5]
-You can practice targeting and shooting on these paper targets. When you are finished resume the mission.
+[CUB_1]
+Stunt Boat Challenge
-[TAXI1]
-~g~Look for a fare.
+[CUB_2]
+Cannon Fodder
-[FARE1]
-~g~Destination ~w~'Meeouch Sex Kitten Club' ~g~in Redlight.
+[CUB_3]
+Naval Engagement
-[FARE2]
-~g~Destination ~w~'Supa Save' ~g~in Portland View.
+[CUB_4]
+Trojan Voodoo
-[FARE3]
-~g~Destination ~w~'old school hall' ~g~in Chinatown.
+[JOB_1]
+Road Kill
-[FARE4]
-~g~Destination ~w~'Greasy Joe's Cafe' ~g~in Callahan Point.
+[JOB_2]
+Waste the Wife
-[FARE5]
-~g~Destination ~w~'AmmuNation' ~g~in Redlight.
+[JOB_3]
+Autocide
-[FARE6]
-~g~Destination ~w~'Easy Credit Autos' ~g~in Saint Mark's.
+[JOB_4]
+Check Out at the Check In
-[FARE7]
-~g~Destination ~w~'Woody's topless bar' ~g~in Redlight.
+[JOB_5]
+Loose Ends
-[FARE8]
-~g~Destination ~w~'Marcos Bistro' ~g~in Saint Mark's.
+[ANSWER]
+Press the ~h~~k~~PED_ANSWER_PHONE~~w~ to answer your cell phone.
-[FARE9]
-~g~Destination ~w~'import export garage' ~g~in Portland Harbor.
+[MOB_01A]
+Awright me ol'china! It's Paul. I might have a little result for you, but I need to speak to you in person.
-[FARE10]
-~g~Destination ~w~'Punk Noodles' ~g~in Chinatown.
+[MOB_01B]
+I'm enjoying a little R&R at the Club Malibu.
-[FARE12]
-~g~Destination ~w~'Football Stadium' ~g~in Aspatria.
+[MOB_01C]
+Reckon you're gonna owe me a favor or two after this, sunshine. I'll see you later.
-[FARE13]
-~g~Destination ~w~'The Church' ~g~in Bedford Point
+[MOB_02A]
+Ssssnniiiiffffff Hey! Hello, Tommy? Tommy!
-[FARE14]
-~g~Destination ~w~'The Casino' ~g~in Torrington
+[MOB_02B]
+We got a situation over at the Print Works. You better go and check it out.
-[FARE15]
-~g~Destination ~w~'Liberty University' ~g~in Liberty Campus
+[MOB_02C]
+Some kind of mess or other. Things are messed up. I gotta go.
-[FARE16]
-~g~Destination ~w~'Shopping Mall' ~g~in Belleville Park Area
+[MOB_03A]
+Mr. Vercetti? I have here a signed piece of crap stating
-[FARE17]
-~g~Destination ~w~'Museum' ~g~in Newport
+[MOB_03B]
+that you have taken on all of BJ's Auto's debts.
-[FARE18]
-~g~Destination ~w~'AmCo Building' ~g~in Torrington
+[MOB_03C]
+With BJ's sudden disappearance I have no choice
-[FARE19]
-~g~Destination ~w~'Bolt Burgers' ~g~in Bedford Point
+[MOB_03D]
+but to hold you responsible for his financial insecurities.
-[FARE20]
-~g~Destination ~w~'The Park' ~g~in Belleville
+[MOB_03E]
+Until this account is settled in full
-[FARE21]
-~g~Destination ~w~'Francis intl. Airport'
+[MOB_03F]
+you should consider Vice City's streets to be very unfriendly.
-[FARE22]
-~g~Destination ~w~'Cochrane Dam'
+[MOB_04A]
+How you doin' mate? It's Paulo again.
-[FARE24]
-~g~Destination ~w~'The hospital' ~g~in Pike Creek
+[MOB_04B]
+Look Tommy, I forgot to mention we're going to need some extra muscle for the concert. A bit of security.
-[FARE25]
-~g~Destination ~w~'The Park' ~g~in Shoreside Vale
+[MOB_04C]
+There's a biker gang led by Mitch Baker, it would be great publicity. Very rock and roll, baby.
-[FARE26]
-~g~Destination ~w~'North West Towers' ~g~in Wichita Gardens
+[MOB_04D]
+Sort this out for me and I'll get you some back stage passes for the gig, awright?
-[NEW_TAX]
-BIGGER! FASTER! HARDER! new Borgnine taxis open for business in Harwood. Call 555-BORGNINE today!
+[MOB_05A]
+Hey, it's Mitch. You did good Tommy, it's good to have the old girl back.
-[TSCORE2]
-$~1~
+[MOB_05B]
+You tell Kent Paul he'll get his security for the gig.
-[IN_ROW]
-~1~ IN A ROW bonus! $~1~
+[MOB_05C]
+You have my word on that.
-[TTUTOR]
-Press the ~h~~k~~TOGGLE_SUBMISSIONS~ button~w~ to toggle taxi missions on or off.
+[MOB_05D]
+Now keep yourself out of trouble.
-[TTUTOR2]
-Press the ~h~~k~~TOGGLE_SUBMISSIONS~ button~w~ to toggle taxi missions on or off.
+[MOB_06A]
+Tommy, 'nuf dead man been chattin' about you, my dear.
-[A_TIME]
-+~1~ seconds
+[MOB_06B]
+Thought you might need something to make you feel better. So Auntie Poulet make you some stew, aye?
-[A_FULL]
-~r~Ambulance full!!
+[MOB_06C]
+Come by me kitchen some time, ok Tommy?
-[A_RANGE]
-~g~The ambulance radio is out of range, get closer to a hospital!
+[MOB_08A]
+Hey Tommy, I thought you might need some business advice.
-[FTUTOR]
-Press the ~h~~k~~TOGGLE_SUBMISSIONS~ button~w~ to toggle fire truck missions on or off.
+[MOB_08B]
+Once you got an operation up and running, you'll need to drop by and take the week's cash.
-[FTUTOR2]
-Press the ~h~~k~~TOGGLE_SUBMISSIONS~ button~w~ to toggle fire truck missions on or off.
-
-[F_PASS1]
-Fire extinguished!
-
-[F_RANGE]
-~g~The fire truck radio is out of range, get closer to a fire station!
-
-[C_BREIF]
-~g~Suspect last seen in the ~a~ area.
-
-[C_RANGE]
-~g~The police radio is out of range, get closer to a police station!
-
-[DODO_FT]
-You flew for ~1~ seconds!
-
-[EBAL_A]
-I know a place on the edge of the Red Light District where we can lay low,
-
-[EBAL_A1]
-but my hands are all messed up so you better drive, brother.
-
-[EBAL_1]
-Press the~h~ ~k~~VEHICLE_ENTER_EXIT~ button~w~ to ~h~enter ~w~or ~h~exit~w~ a vehicle.
-
-[EBAL_1B]
-Press the~h~ ~k~~VEHICLE_ENTER_EXIT~ button~w~ to ~h~enter ~w~or ~h~exit~w~ a vehicle.
-
-[EBAL_2]
-~g~Get back into the car!
-
-[EBAL_3]
-This is the ~h~radar~w~. Use it to navigate the city, follow the ~h~blip~w~ on the ~h~radar~w~ to find the hideout!
+[MOB_08C]
+Let the guys think they got the run of the place and they'll try shaving the profits - ok?
-[EBAL_D]
-I know a guy, he's connected, his name's Luigi.
+[MOB_08D]
+Hey, I know how to handle business, Ken, ok?
-[EBAL_D1]
-Me an' him go back so I could probably get you some work. C'mon lets head over there.
+[MOB_08E]
+Ok, ok. I know, you know. I know. I was,
-[EBAL_E]
-C'mon, lets drop by and I'll introduce you.
+[MOB_08F]
+I was just, you know, telling you I know, that you know, that I know.
-[EBAL_I]
-The boss will be out to see you shortly...
+[MOB_08G]
+Just keeping it sharp baby!
-[EBAL_J]
-8-Ball's got some business up stairs.
+[MOB_08H]
+Whatever, Ken, whatever...
-[EBAL_K]
-Maybe you can do me a favor.
+[MOB_09A]
+Hey Leo! I got some work for you!
-[EBAL_L]
-One of my girls needs a ride so grab a car and pick up Misty from the clinic. Then bring her back here.
+[MOB_09B]
+This ain't Leo.
-[EBAL_N]
-So keep your hands on the wheel!
+[MOB_09C]
+Hey, if Leo knows you got his phone, he gonna kill you!
-[EBAL_4]
-~r~8-Ball's dead!
+[MOB_09E]
+You killed Leo? You must have big cojones - wanna work for me?!
-[EBAL_5]
-~g~Get a vehicle!
+[MOB_09F]
+Drop by my father's cafe in Little Havana and we'll talk mano a mano.
-[EBAL_6]
-~g~Pick up Misty!
+[MOB_10A]
+Tommy! Look, I gotta ask you a favor.
-[LM1]
-'LUIGI'S GIRLS'
+[MOB_10B]
+Steve! How's filming going!
-[LM2]
-'DON'T SPANK MA BITCH UP'
+[MOB_10C]
+Fine, fine. I, heh, WE need a car chase scene, but our budget can't stretch to it.
-[LM3]
-'DRIVE MISTY FOR ME'
+[MOB_10D]
+I've left some wheels around town. You'll know what to do.
-[LM5]
-'THE FUZZ BALL'
+[MOB_10E]
+Ok Steve, I'll keep an eye out. Catch you later.
-[LM1_2]
-~g~Take Misty to Luigi's Club.
+[MOB_11A]
+Howdy son, just thought I'd ring you up and give you some advice.
-[LM1_3]
-~g~Press the horn to get the girl into the car.
+[MOB_11B]
+Hey, Avery. What's eating you?
-[LM1_6]
-~g~Get back into the car!
+[MOB_11C]
+There's a lot of opportunity in this town if you own the right real estate, you catch my drift?
-[LM1_7]
-Stop the vehicle next to Misty and allow her to enter it.
+[MOB_11D]
+I reckon so...
-[LM1_8]
-You can go and see Luigi for more work or check out Liberty City.
+[MOB_11E]
+All I'm saying is keep your eyes open and you might find the perfect business opportunity. I'll catch y'later.
-[LM2_A]
-There's a new high on the street goes by the name of SPANK.
+[MOB_11F]
+Later, Avery.
-[LM2_E]
-Some wiseguy's been introducing this trash to my girls down Portland Harbor.
+[MOB12_A]
+Hey Tommy, it's Avery! Now listen, I got me all tied up at the moment
-[LM2_B]
-Go and introduce a bat to his face!
+[MOB12_B]
+and I have a representative of mine needs chaperoning out to the Gator Keys.
-[LM2_G]
-I want compensation for this insult!
+[MOB12_C]
+I'm after some land out that way, so I'm sending someone out to sweeten the deal.
-[LM2_1]
-~g~Take his car and get it resprayed.
+[MOB12_D]
+Could you do me a favor and make sure he gets there ok?
-[LM2_2A]
-Use the~h~ ~k~~PED_FIREWEAPON~ button~w~ to ~h~punch ~w~and ~h~kick~w~ or ~h~swing ~w~the bat!
+[MOB12_E]
+Yeah, sure thing Avery. Where'd you want me to pick him up?
-[LM2_2C]
-Use the~h~ ~k~~PED_FIREWEAPON~ button~w~ to ~h~punch ~w~and ~h~kick~w~ or ~h~swing ~w~the bat~w~!
+[MOB12_F]
+He's just finishing some business at the building site. I said you'd pick him up from there.
-[LM2_2D]
-Use the~h~ ~k~~PED_FIREWEAPON~ button~w~ to ~h~punch ~w~and ~h~kick~w~ or ~h~swing ~w~the bat~w~!
+[MOB12_G]
+No problem. See you later, Avery.
-[LM2_3]
-~g~Stash the car in Luigi's lockup!
+[MOB13_A]
+Vercetti? VERCETTI!! Damn you man, you've got to help me!
-[LM2_4]
-~g~Respray the car!
+[MOB13_B]
+Mr. Moffat? How's family life?
-[LM3_A]
-Hey I've gotta talk to you... All right Mick I'll talk to yah later.
+[MOB13_C]
+Damn you to hell, HELL, do hear me?!
-[LM3_B]
-How yah doing kid?
+[MOB13_D]
+Well it was nice chatting...
-[LM3_C]
-The Don's son, Joey Leone, he wants some action from his regular girl Misty.
+[MOB13_E]
+WAIT! Wait, Vercetti - Tommy, can I call you Tommy?
-[LM3_D]
-Go pick her up at Hepburn Heights...
+[MOB13_F]
+We're both businessmen, yeah? You know a good deal when you hear one, ok?
-[LM3_E]
-but watch yourself that's Diablo turf.
+[MOB13_G]
+I don't have time to chat, get to the point.
-[LM3_F]
-Then run her over to his garage in Trenton and make it quick,
+[MOB13_H]
+MONEY. Money is the goddamned point.
-[LM3_H]
-so keep your eyes on the road and off Misty!
+[MOB13_I]
+I've escaped the coop again, but it's never long before they track me down - they think it's a damned game!
-[LM3_2]
-~g~Take Misty to Joey's.
+[MOB13_J]
+I'm at a pay phone somewhere in this god forsaken shit hole.
-[LM3_4]
-~g~Go pick up Misty!
+[MOB13_K]
+Get me out of here before they take me back and...and..oh go-o-od...
-[LM3_5]
-You working regular for Luigi now huh? It's about time he got a driver we can trust!
+[MOB13_L]
+Well, I'm busy for the next -
-[LM3_7]
-I'll be with you in a minute spark plug.
+[MOB13_M]
+No! Don't shit with me here, have a heart! No man should have to do such, such things.
-[LM3_10]
-~g~Get a vehicle!
+[MOB13_N]
+I'm on my knees here Tommy, in the dirt begging you please...
-[LM4_B]
-Go and take care of things for me.
+[MOB13_O]
+I guess I could swing by that way, see if I can spot you...
-[LM4_C]
-If you need a piece go around the back of AmmuNation opposite the subway.
+[MOB13_P]
+Oh god, they're coming. For the love of Christ hurry, hurry!
-[LM5_A]
-The Policeman's Ball is being held at the old school hall near the Callahan Bridge
+[MOB_14A]
+Hey there Tommy, you're gonna love me mate.
-[LM5_B]
-and they'll be looking for some 'old school' action.
+[MOB_14B]
+A little birdy told me that Vice City SWAT Division has a deposit box at a certain rather large banking establishment,
-[LM5_C]
-Now I got girls all over town walking the streets.
+[MOB_14C]
+where they keep all the bribes they've taken over the years,
-[LM5_D]
-Get'em to the ball they'll make a bundle.
+[MOB_14D]
+like some kind of old boys' retirement fund.
-[LM5_1]
-~g~You pack these ladies too tight, they gonna bruise! ~g~Drop these girls off first, then come back for more.
+[MOB_14E]
+Of course, if this information should ever help you acquire any of that cash,
-[LM5_2]
-~r~One of Luigi's girls is bodybag meat!
+[MOB_14F]
+I guess you'd feel obliged to push some of it my way?
-[LM5_3]
-~g~You need a car!
+[MOB_14G]
+I'll bear that in mind, thanks Kent.
-[LM5_4]
-~g~Pick up the girls working St. Marks.
+[MOB_14H]
+It's Paul. I'm from Kent, near London, you prat.
-[LM5_5]
-~g~Take the girls to the Fuzz Ball!
+[MOB_14I]
+My provincial English geography ain't what it was.
-[LM5_8]
-~g~Girls working the Ball: ~1~
+[MOB15_A]
+Tommy, mate, it's Paul, from Kent,
-[JM2]
-'FAREWELL 'CHUNKY' LEE CHONG'
+[MOB15_B]
+a couple of proper sorts have your name written all over them, down at the Malibu.
-[JM4]
-'CIPRIANI'S CHAUFFEUR'
+[MOB15_C]
+What are you talking about?
-[JM5]
-'DEAD SKUNK IN THE TRUNK'
+[MOB15_D]
+Sorts. Birds. You know. Girls. Tastey ones, don't think they're brasses or nothing.
-[JM1_1]
-~g~Take Forelli's car to 8-Ball's garage North of here, behind 'Easy Credit Autos'.
+[MOB15_E]
+You gotta come check them out.
-[JM1_2]
-~g~Park the car back at Marco's Bistro.
+[MOB16_A]
+Tommy, Paulo here, que pasa amigo?
-[JM1_3]
-~g~Activate the car bomb then get out of there!
+[MOB16_B]
+What do you want Paul. I don't want any fake label clothes.
-[JM1_4]
-~g~You're trashing the vehicle! Get it repaired!
+[MOB16_C]
+Very funny, mate, but you know I don't touch bent gear.
-[JM1_5]
-~g~The car bomb's not set!
+[MOB16_D]
+Nah, I was just calling to see if I get a part in one your movies,
-[JM1_6]
-~g~Put the car back in the correct position.
+[MOB16_E]
+back in England I did a lot of blue stuff, mate.
-[JM1_8A]
-~y~Hey, it's my main man!
+[MOB16_F]
+I'm packing more heat than you, my son.
-[JM1_8B]
-~y~The bomb shop's automated. Just drive in, stop your car and the shop will do the rest.
+[MOB16_G]
+Paul, thanks for the offer, I'll bear it in mind.
-[JM1_8C]
-~y~Here, your first can be free, but after that it'll cost.
+[MOB16_H]
+Seriously, don't forget about me, after all I done for you.
-[JM2_A]
-Chunky Lee Chong is pushing spank for some new gang from Colombia... or Colorado... or something....
+[MOB16_I]
+That's what I'm trying to forget about.
-[JM2_B]
-I'm not really sure. Who needs details anyway.
+[MOB19_A]
+Tommy V, It's KP here. Kent Paul. Word on the street is people want to rip you off.
-[JM2_D]
-That rat has sold his last stir fry.
+[MOB19_B]
+Keep your eye's peeled, my son. And remember, I didn't say nothing to you about this.
-[JM2_E]
-I want you to take him out!
+[MOB_20A]
+Alright, Tommy, it's Paul. I just heard from a mush that you've been a real naughty boy.
-[JM2_G]
-Sort yourself with a nine, you know where it is, right?
+[MOB_20B]
+Somebody has taken offense to you acting like the big guy all of a sudden, giving it the big shot thing.
-[JM2_H]
-Well remember, just watch your back in China Town, it's Triad territory.
+[MOB_20C]
+Well, don't say I never warned you or nothing. Boasting is a mug's game, son.
-[JM3_A]
-Alright, we're gonna hit the pay role van.
+[MOB_20D]
+Anyway, I heard there's some price been put on your head and someone's going to have a crack at you,
-[JM3_B]
-It leaves the edge of China Town everyday.
+[MOB_20E]
+so watch yourself, and remember me, mate.
-[JM3_C]
-Bullets won't even dent the van's armor, so get a car and ram it off the road.
+[MOB21_A]
+Tommy, Thomas, it's Cortez. Que pasa?
-[JM3_D]
-Now hit it hard and the punk ass security guards should bail.
+[MOB21_B]
+Things are interesting. How are you, my friend?
-[JM3_E]
-Then take it to the warehouse at the docks and my guys are gonna take over from there.
+[MOB21_G]
+I wanted to ask you about Mercedes.
-[JM3_F]
-Now it won't be doin' it's rounds all day, so don't hang around.
+[MOB21_H]
+Ok, what about her?
-[JM3_1]
-~g~Take the van to the lock up.
+[MOB21_I]
+Oh Tommy, Tommy. I, I hear these stories, all these stories - I don't know what to think.
-[JM3_2]
-~g~Ram the van until its damage is below 70 percent.
+[MOB21_K]
+Maybe she thinks she can do what she likes, but Tommy, tell me, is it true?
-[JM4_B]
-Oh! Here's the guy I was telling you about!
+[MOB21_M]
+Is what true?
-[JM4_C]
-Alright Listen. This guy ain't Italian and he's no mechanic but he can get things fixed.
+[MOB21_N]
+These stories I hear. Is she really going to be a lawyer?
-[JM4_D]
-This is Pops Capo, Toni Cipriani.
+[MOB21_O]
+Oh Tommy, the shame, the shame! You know, we Cortez's are a proud family.
-[JM4_E]
-Yeah, I'm Toni Cipriani
+[MOB21_P]
+We would never allow a daughter of ours to become a lawyer. Please tell me it isn't so. I don't think I could take it.
-[JM4_F]
-Take him to Momma's restaurant at St Marks, alright.
+[MOB21_Q]
+Oh Colonel, I can assure you Mercedes is never going to become a lawyer. Don't worry about it.
-[JM4_G]
-Now listen to me, I'm planning a job that needs a good driver so drop by sometime later Ok?
+[MOB21_R]
+Oh thank you, Tommy. Tommy, thank you. The shame would be unbearable. She is a lady, not a parasite, you know.
-[JM4_2]
-Wait here! Keep the engine running. This ain't a social call.
+[MOB21_S]
+I know, colonel.
-[JM4_3]
-It's a Triad ambush! Get us out of here kid!
+[MOB21_T]
+Anyway, Tommy, you must excuse me, the new minister of the interior has arrived.
-[JM4_4]
-The Triads think they can mess with me, the triads, with ME!
+[MOB21_U]
+Many years ago, I killed his father in a failed coup so I must be polite. Good day, amigo.
-[JM4_6]
-Hey watch the car! I said no fancy crap.
+[MOB21_C]
+Tommy, it is always a struggle here. Excuse the poor line, we have just had another failed coup.
-[JM4_7]
-~g~Take Toni to his momma's restaurant.
+[MOB21_D]
+The people are the most demanding mistress of all.
-[JM4_8]
-~r~Toni's been wasted!
+[MOB21_E]
+So far, we have had three revolutions and four coups since I return from Vice City.
-[JM5_A]
-Beautiful! Just beautiful.
+[MOB21_F]
+Luckily, I have been promoted each time.
-[JM5_B]
-Alright, Just the guy I need to talk to!
+[MOB21_J]
+Maybe everyone is humiliating me.
-[JM5_D]
-One of the Forellis thought he was a wise guy, so he got what he had coming to him.
+[MOB21_L]
+but tell me Tommy, is it true?
-[JM5_E]
-Take the corpse to the crusher in Harwood, alright?
+[MOB22_A]
+Tommy, you are proving very useful, my friend.
-[JM5_1]
-~g~Take it to the crusher!
+[MOB22_B]
+Thanks, Cortez. What about my deal?
-[JM5_2]
-~g~It's the Forelli brothers!
+[MOB22_C]
+Tommy, I am working tirelessly on your behalf to ensue we get to the bottom of this trench of stinking lies and deceit,
-[JM6_A]
-What a ride she's gonna be, huh?
+[MOB22_D]
+you have my word on that, but in the meantime,
-[JM6_B]
-Alright, listen. Get some wheels to the safehouse at St. Marks and pick up a few friends of mine.
+[MOB22_E]
+please accept the esteemed thanks of my people for your work on our behalf.
-[JM6_C]
-They're hittin' a bank and they need a driver.
+[MOB_25A]
+Tommy, Thomas it's Cortez. Look, the French are giving me all kinds of trouble, amigo.
-[JM6_D]
-I gave my word that you were the man, so don't screw this up.
+[MOB_25B]
+Damn hypocrites. They spend a hundred years stealing from poor countries and they call me a thief!
-[JM6_E]
-Get them to the bank before five o'clock, not a minute after.
+[MOB_25C]
+I am going to need your help as soon as possible, amigo.
-[JM6_2]
-Keep the engine running we'll be in and out in no time.
+[MOB_25D]
+So please hurry, Tommy, I need you, all right? I hate the damn French.
-[JM6_3]
-Get us out of here!!
+[MOB_26A]
+Hello, Tommy?
-[JM6_4]
-Shake the cops and get us to the safehouse!!
+[MOB_26B]
+Yeah?
-[JM6_6]
-~g~Go and get a vehicle less conspicuous!
+[MOB_26C]
+It's Baker. I just wanted to say I really enjoyed the show.
-[JM6_7]
-~g~You need all 3 to rob the bank!
+[MOB_26D]
+Me and the boys want to thank you, and remind you,
-[TM1]
-'TAKING OUT THE LAUNDRY'
+[MOB_26E]
+you got our respect. Good day. Keep riding hard, son.
-[TM2]
-'THE PICK-UP'
+[MOB_29A]
+Hello, is this Mr. Tommy Vercetti?
-[TM3]
-'SALVATORE'S CALLED A MEETING'
+[MOB_29B]
+Yes.
-[TM4]
-'TRIADS AND TRIBULATIONS'
+[MOB_29C]
+Well, I hear through the vine of grapes you the man when someone got a vermin infestation.
-[TM5]
-'BLOW FISH'
+[MOB_29D]
+Maybe...
-[TONI_P]
-I've got some urgent work for you! -Toni
+[MOB_29E]
+Well, I got a real vermin infestation. Haitians everywhere.
-[TM1_A]
-~w~Take a seat kid, take a god damned seat.
+[MOB_29F]
+My name is Umberto Robina and I want you to meet me at the Cafe Robina as soon as you can,
-[TM1_B]
-~w~So the laundry won't pay any protection eh?
+[MOB_29G]
+'cause I tell you, these damn Haitians gone too far this time.
-[TM1_C]
-~w~The Triads think they can mess with me?
+[MOB_29H]
+Test
-[TM1_D]
-~w~Let's teach these would be tough guys what it means to be a tough guy.
+[MOB_30A]
+Tommy, is Umberto Robina
-[TM1_E]
-~w~Yeah, teach 'em some respect. No son of mine gets it from some Triads.
+[MOB_30B]
+Hey, how's the cafe?
-[TM1_F]
-~w~Your father, god rest his soul, took no crap from no Triads back in Sicily.
+[MOB_30C]
+Oh, wonderful. Incredible. Tommy, incredible. No wimps, Tommy, just real men, and the beautiful women!
-[TM1_G]
-~w~Sorry Ma. Yes Ma.
+[MOB_30D]
+Anyway, I wanted to tell you, me and Papi, to us, you Cuban.
-[TM1_H]
-~w~I want you to destroy their laundry vans
+[MOB_30E]
+You have proved yourself, man. You got big cojones.
-[TM1_I]
-~w~and mangle any triad gimp that gets in your way.
+[MOB_30F]
+Well thank you, Umberto. Nobody's said that to me since I left jail. I'll see you around.
-[TM1_J]
-~w~8-Ball can supply you with what you're gonna need.
+[MOB_33A]
+Tommy, it's Phil, now cut out all the reminiscing crap and listen to me, you hear?
-[TM2_A]
-~w~TONI's off making people bleed or trying to.
+[MOB_33B]
+Good. I got me some extra strength boomshine nearing fermentation time and I was wondering if you'd fancy having a shot.
-[TM2_AA]
-~w~He'll never be as tough as his Pop, but he left you a note on the table.
+[MOB_33C]
+Seriously, Tommy, if you like a drink, or if you need to strip paint, this stuff'll make a man out of you.
-[TM2_B]
-~w~The laundry has agreed to pay - you did real good kid!
+[MOB_33D]
+Sure did out of me, even though I can't see out of one eye. I'll be waiting for you, y'hear.
-[TM2_C]
-~w~Go collect the cash and bring it back here. Watch out for the Triads.
+[MOB_34A]
+Tommy, I really enjoyed working with you. Ain't had so much fun since the ridge in Nam, pal.
-[TM2_D]
-~w~They may be shoving a firecracker up your ass, but don't take no crap.
+[MOB_34B]
+Anyhows, you need anything, you call on me, you hear?
-[TM2_E]
-~w~Nobody I mean nobody, messes with TONI CIPRIANI!
+[MOB_34C]
+I always remember those I served with,
-[TM2_1]
-~g~Get the cash back to Toni's!!
+[MOB_34D]
+and I am sure I can help you out, you hear?
-[TM2_2]
-~g~You iced them all!
+[MOB_35A]
+Tommy, the wound is healing well. Funny thing is,
-[TM3_MA]
-~w~I don't know where he is!
+[MOB_35B]
+I have fought in 6 battle zones and always walked away without a scratch, and now this!
-[TM3_MB]
-~w~I swear that boy of mine don't know himself sometimes.
+[MOB_35C]
+One armed Phil. Still, I got me a healthy selection of one handed fire power so I'll never be unarmed Phil, you hear.
-[TM3_MC]
-~w~Now his father, he was different. Always on top, in charge, manful...
+[MOB_35D]
+Any way son, cut out the sentimental crap and go buy yourself a drink, you hear!
-[TM3_A]
-~w~Don Salvatore has called a meeting.
+[MOB_36A]
+Tommy, it's Phil, I want to thank you for helping me out back there son,
-[TM3_B]
-~w~I need you to collect the limo and his boy, Joey, from the garage.
+[MOB_36B]
+Damn Charlie, he'll always ambush you somewhere or other,
-[TM3_C]
-~w~Then get Luigi from his club, come back here and pick me up,
+[MOB_36C]
+Anyway the wound is healing well, and it means I'll no longer be defrauding the government on my disability check.
-[TM3_D]
-~w~then we'll all drive over to the boss's place together.
+[MOB_40A]
+Hey Tommy, it's Sonny. How's the sun tan?
-[TM3_E]
-~w~Those Triads, they don't know when to stop.
+[MOB_40B]
+I ain't got no sun tan.
-[TM3_F]
-~w~They want a war. They got a war.
+[MOB_40C]
+Well, you ain't got my money, either, so I'm wondering to myself,
-[TM3_G]
-~w~Now get going.
+[MOB_40D]
+what are you doing? So, tell me, Tommy, what are you doing?
-[TM3_1]
-~g~Pick up the Stretch from Joey's.
+[MOB_40E]
+I'm looking for the money, Sonny. Don't worry.
-[TM3_2]
-~g~Now go pick up Luigi.
+[MOB_40F]
+I am worrying, Tommy, that's my style,
-[TM3_3]
-~g~Now go pick up Toni.
+[MOB_40G]
+because I seem to have this problem in my life with unreliable people.
-[TM3_4]
-~g~Drive the goodfellas to Salvatore's place.
+[MOB_40H]
+Don't be an unreliable person, Tommy, please.
-[TM3_5]
-~y~It's a triad ambush!!
+[MOB_40I]
+Do us both a favor. I'm looking forward to hearing from you.
-[TM4_B]
-~w~We're at WAR! The Triads have a fish factory as a front.
+[MOB_41A]
+Tommy, remember me?
-[TM4_C]
-~w~Most of their business goes down at the fish market in Chinatown.
+[MOB_41B]
+Hello Sonny.
-[TM4_D]
-~w~That laundry still owes us protection.
+[MOB_41C]
+That's right, Sonny. We're old friends,
-[TM4_E]
-~w~They reckon the Triads are protecting them now, so I say we exact a fitting punishment.
+[MOB_41D]
+You never write me, you never call. Don't you want to be friends no more?
-[TM4_F]
-~w~Take these boys over and whack the Triad Warlords!
+[MOB_41E]
+I've been busy trying to sort things out. You didn't give me a lot of support down here, Sonny.
-[TM4_G]
-~w~Hell, if you get a chance, pop some of their soldiers too.
+[MOB_41F]
+Oh, my fault is it? We'll I've heard you been busy all right.
-[TM4_GAT]
-~g~You need a 'Triad fish van' to enter.
+[MOB_41G]
+Busy killing drugs barons. Busy taking over.
-[TM5_B]
-~w~OK, I've had enough of this shit.
+[MOB_41H]
+Don't forget about us, Tommy, 'cause I can assure you, I ain't forgotten about you.
-[TM5_C]
-~w~We're gonna finish the Triads in Liberty once and for all!
+[MOB_42A]
+Tommy.
-[TM5_D]
-8-Ball's rigged a dustcart with a bomb.
+[MOB_42B]
+Sonny.
-[TM5_E]
-~w~It's on a timer so if you mess up there'll be no evidence. Go and pick up the dustcart.
+[MOB_42C]
+Obviously you are suffering from hearing problems, so I'll try again.
-[TM5_F]
-~w~Careful, 8-Ball says it's real sensitive and the slightest bump could set that thing off!
+[MOB_42D]
+Where's the goddamned money, where's the goddamned stuff, and where's my cut of your new action?
-[TM5_G]
-~w~Their fish factory will open its gates for a dustcart, so you can drive right in.
+[MOB_42E]
+You are making an idiot out of me, Tommy, and I'm not laughing yet.
-[TM5_H]
-~w~Park up between the gas canisters and get the hell out of there!
+[MOB_43A]
+Tommy, Tommy, Tommy, I had Sonny on the phone, ok, are you with me?.
-[TM5_I]
-~w~I want it to rain mackerel.
+[MOB_43B]
+I don't know about you, but there's something about a man threatening to murder my family
-[TM5_J]
-~w~We're talking real biblical here, nothing low budget.
+[MOB_43C]
+which really scares the crap out of me. What are you going to do?
-[FM2]
-'CUTTING THE GRASS'
+[MOB_43D]
+Ken, take it easy.
-[FM4]
-'LAST REQUESTS'
+[MOB_43E]
+I AM calm, calm as a man can be when he's fearing for his life!
-[FM1_A]
-~w~Me an' the fellas need to talk business
+[MOB_43F]
+Stay off the idiot fuel and look after yourself.
-[FM1_B]
-~w~so you're gonna look after my girl for the evening.
+[MOB_43G]
+No one's gonna take us out. I'll see you later.
-[FM1_C]
-~w~HEY MARIA! MOVE YOUR BUTT!
+[MOB_43H]
+I am calm. Don't I sound calm? Must be impending death that is doing this to my voice.
-[FM1_D]
-~w~Dumb broad does this every time.
+[MOB45_A]
+Tommy We gotta talk about stuff.
-[FM1_E]
-~w~And here she is, the one and only Queen of Sheba!
+[MOB45_B]
+What's the problem Lance?
-[FM1_F]
-~w~What were you doing up there?
+[MOB45_C]
+It's you, my friend, I feel you're not giving me a fair slice.
-[FM1_G]
-~w~Whatever it was, I bet it cost me money.
+[MOB45_D]
+And more than that, you been embarrassing me in front of the boys. I can't have that.
-[FM1_H]
-~w~Well, you don't think I hang around for the conversation, do you?
+[MOB45_E]
+Lance, it ain't like that. You've been making mistakes.
-[FM1_I]
-~w~Get in that car and keep your big mouth shut.
+[MOB45_F]
+Tommy, I'm not your message boy. I'm not your running boy.
-[FM1_J]
-~w~Take the limo but bring it back in one piece, y'hear me?
+[MOB45_G]
+Lance, don't screw up, and we won't have any problems. I screw up, you can lay into me any time.
-[FM1_K]
-~w~And watch her, she can be trouble.
+[MOB45_H]
+Tommy, I've done everything for you, you treat me like a fool. Don't do that.
-[FM1_L]
-~w~Yeah, yeah, yeah! I'm sure your new lap dog has everything covered,
+[MOB45_I]
+Lance, I won't rip you off or stab you in the back, okay?
-[FM1_M]
-~w~and isn't he big and strong?
+[MOB45_J]
+Just take it easy. This is tough enough without you getting all emotional on me.
-[FM1_N]
-~w~Hey Fido, Let's go visit Chico and get some party treats!
+[MOB45_K]
+Trust me. Do you hear me, do you hear me?
-[FM1_P]
-~g~That's Chico over there, pull up next to him.
+[MOB45_L]
+I hear you, Tommy, but I can't take this much more.
-[FM1_S]
-~w~Here you go lady.
+[MOB45_M]
+Lance, don't be like this. Now I'm warning you.
-[FM1_TT]
-~w~IT'S A POLICE RAID!
+[MOB45_N]
+Do you hear me? Just relax, take a few days off. Okay? I'll talk to you.
-[FM1_1]
-~g~Get back into the Stretch!
+[MOB46_A]
+Yo, Tommy! It's Lance.
-[FM1_2]
-~g~Get into the Stretch!
+[MOB46_B]
+Yeah?
-[FM1_3]
-~r~Leave Maria and Salvatore will have you whacked, go back and pick her up.
+[MOB46_C]
+Oh, nice to hear from you, Lance. Come on, man, be cool, be cool.
-[FM1_4]
-~g~You've dumped the Don's woman! Get back to the warehouse and wait for Maria!
+[MOB46_D]
+I'm in the middle of something. What do you want?
-[FM1_5]
-~g~Get Maria safely back to Salvatore's!
+[MOB46_E]
+Nothing. Just to say, you know. Look Tommy, we can do this thing.
-[FM1_6]
-~g~Chico won't be there forever, get Maria to the waterfront!
+[MOB46_F]
+You and me, no problem. You know what I mean?
-[FM1_7]
-~r~Maria's dead! Salvatore won't be too pleased...
+[MOB46_G]
+We're going to have to do it, 'cause otherwise, we're going to be dead, Lance.
-[FM1_8]
-~r~You wasted Maria's supplier!
+[MOB46_H]
+We're in too far now. But thanks for the call. I'll speak to you later.
-[FM2_J]
-Leave us alone for a minute.
+[MOB_47A]
+Tommy, Lance, we got big problems. Come down here. Right away.
-[FM2_A]
-The Colombian Cartel is making SPANK somewhere in Liberty.
+[MOB52_A]
+Hey Leo, I think we got a buyer for Diaz's merchandise.
-[FM2_K]
-but we don't know where, and they seem to know everything we're doin' before we do.
+[MOB52_B]
+You gotta give him a ring, man, set up the deal, you know?
-[FM2_L]
-There is a guy named Curly Bob works the bar at Luigi's.
+[MOB52_C]
+Where are you now?
-[FM2_M]
-He's been throwing more money around than he's earning.
+[MOB52_D]
+You ok Leo? You sound kinda different.
-[FM2_N]
-He usually gets a taxi home after work. So follow him.
+[MOB52_E]
+Just tell me where you are.
-[FM2_O]
-And if he's rattin' us out... kill him.
+[MOB52_F]
+Who the hell is this? Put Leo on, man!
-[FM2_F]
-Here comes our little friend. Mr big mouth himself.
+[MOB52_G]
+Leo's gone away for a while, he left me in charge.
-[FM2_G]
-Were you followed? You know what goes on here is our little secret.
+[MOB52_H]
+Screw you, man!
-[FM2_H]
-No..no, I wasn't followed. You got my stuff?
+[MOB54_A]
+Hiya Tommy!
-[FM2_I]
-Here's your SPANK, squealer, now talk.
+[MOB54_B]
+Hi Mercedes, howyadoin'?
-[FM2_P]
-OK, so the Leone's are fighting wars on two fronts.
+[MOB54_C]
+I got a new apartment up in Vice Point
-[FM2_Q]
-They're in a turf war with the Triads with no sign of either side giving up.
+[MOB54_D]
+- thought you might want to drop by sometime.
-[FM2_R]
-Meanwhile Joey Leone has stirred up some bad blood with the Forellis.
+[MOB54_E]
+I'd love to. I'll catch you later.
-[FM2_S]
-Every day they're losing men and influence in the city.
+[MOB55_A]
+Tommy, it's me.
-[FM2_T]
-Salvatore is becoming dangerous and paranoid. He suspects everybody and everything.
+[MOB55_B]
+Hi Mercedes.
-[FM2_U]
-With loyalty like yours, what has he possibly got to worry about.
+[MOB55_C]
+Tommy, I so bored, when we going to have some fun?
-[FM2_1]
-~g~There's Curly Bob!
+[MOB55_D]
+What do you mean?
-[FM2_2]
-~g~Curly's left the club, tail him!
+[MOB55_E]
+Well, I know you're busy fighting and killing and corrupting people,
-[FM2_5]
-~g~Take him to Portland Harbor.
+[MOB55_F]
+but I just want to have some fun. So don't forget about me, you hear?
-[FM2_6]
-~r~Curly won't get into a smashed-up taxi!
+[MOB56_A]
+Tommy, I hear you kill Ricardo Diaz.
-[FM2_7]
-~r~Curly's spooked! The meeting's off!
+[MOB56_B]
+there was an unfortunate fire at his mansion.
-[FM2_8]
-~g~Whack Curly Bob!
+[MOB56_C]
+I think he burnt to death in an acrylic shirt.
-[FM2_9]
-~r~Curly Bob's dead!
+[MOB56_D]
+Tommy, I so proud of you. I knew you were a real man.
-[FM2_10]
-~r~Curly got away!
+[MOB56_E]
+He awful trouser stain of a man, you make me so proud to be your friend.
-[FM2_11]
-~g~Park out the front of Luigi's Club, Curly Bob will be leaving shortly.
+[MOB56_F]
+No, I know you going to be busy trying to take over this town,
-[FM2_12]
-~r~He gave you the slip!
+[MOB56_G]
+but don't forget about me, you hear?
-[FM3_A]
-~w~We should take these Colombian bastards out,
+[MOB57_A]
+It's merceedes. I no longer love you Tommy.
-[FM3_B]
-~w~but while we're at war with the Triads we ain't strong enough.
+[MOB57_B]
+I no longer do. Honest. 'cause you no longer nice to Mercedes.
-[FM3_C]
-~w~The Cartel has got bottomless funds from pushing that SPANK crap.
+[MOB57_C]
+You no longer treat her like a lady. You ignore me and I hate you.
-[FM3_D]
-~w~If we make an open attack on them, they'll wipe the floor with us.
+[MOB57_D]
+I insist you come to see me right away!
-[FM3_E]
-~w~They must be making SPANK on that big boat that Curly lead you to.
+[MOB58_A]
+Tommy.
-[FM3_F]
-~w~So we gotta use our heads, or rather one head. Your head.
+[MOB58_B]
+Hey Mercedes.
-[FM3_G]
-~w~I'm asking you to destroy that SPANK factory as a personal favor to me, Salvatore Leone.
+[MOB58_C]
+Hey indeed Mr. Tough Guy. I real angry with you Tommy.
-[FM3_H]
-~w~If you do this for me, you will be a made man, anything you want.
+[MOB58_D]
+Never make me hang out with Jezz Torrent again.
-[FM3_I]
-~w~Go and see 8-Ball, you'll need his expertise to blow-up that boat.
+[MOB58_E]
+He is pathetic. Half way through he starts crying about his doggie
-[FM3_8A]
-~w~Yo my man! Salvatore phoned ahead,
+[MOB58_F]
+that died when he was 7 years old and that his mommy never loved him.
-[FM3_8B]
-~w~but a job like this is gonna need a lot of fireworks.
+[MOB58_G]
+And Tommy. He wear a wig and a bra in private.
-[FM3_8D]
-~w~but you know with me you get a lot of bang for your buck.
+[MOB58_H]
+I not very happy with you!
-[FM3_8E]
-~w~Okay, let's do this thing!
+[MOB59_A]
+Ooh Tommy, its Mercedes.
-[FM3_8F]
-~w~I can set this baby to detonate, but I still can't use a piece with these hands.
+[MOB59_B]
+I just want to say, I have so much fun on that film set.
-[FM3_8G]
-~w~Here, this rifle should help you pop some heads!
+[MOB59_C]
+Anything else you have like that, you let me know.
-[FM3_4]
-~g~Stop the vehicle and let 8-Ball out!
+[MOB59_D]
+I really mean that. I always wanted to be an actress.
-[FM3_7]
-~r~8-Ball's been iced!
+[MOB59_E]
+I think I learn a lot about the dramatic process.
-[FM3_8]
-~r~The guards have been alerted!
+[MOB59_F]
+It so enlightening! Thank you. Thank you. I see you real soon. Adios.
-[FM4_A]
-~w~It's my favorite cleaner.
+[MOB_99]
+Get to the payphone at location.
-[FM4_B]
-~w~I'm proud of you my boy, you kicked the shit out of those grease balls.
+[MOB_98]
+Get to the payphone at location.
-[FM4_C]
-~w~I've got just one little job for you before we can all celebrate.
+[MOB_97]
+Get to the payphone at location.
-[FM4_D]
-~w~There's a car around the block from Luigi's club.
+[MOB_96]
+Get to the payphone at location.
-[FM4_E]
-~w~The inside is covered in brains.
+[MOB_95]
+Get to the payphone at location.
-[FM4_F]
-~w~We had to help some guy make up his mind and it proved a little messy.
-
-[FM4_H]
-~w~Take it to the crusher before the cops find it.
-
-[AM3]
-'PAPARAZZI PURGE'
-
-[AM4]
-'PAYDAY FOR RAY'
-
-[AM5]
-'TWO-FACED TANNER'
-
-[AM1_A]
-We have certain issues to clear up before we can continue any form of relationship,
-
-[AM1_B]
-business or otherwise. Lets lay our cards on the table.
-
-[AM1_C]
-I am Yakuza and I know you worked for Salvatore Leone's family.
-
-[AM1_D]
-I can give you work with our organization,
-
-[AM1_E]
-But first you must prove to me that your ties with the Mafia are truly broken.
-
-[AM1_G]
-Make sure he doesn't reach his club alive.
-
-[AM1_H]
-Meanwhile Maria and I will catch up on old times.
-
-[AM1_I]
-Oh..Asuka, you've got a massager.
+[A_TIME]
++~1~ seconds
-[AM1_J]
-That's not a massager.
+[DODO_FT]
+You flew for ~1~ seconds!
-[AM1_1]
-~g~Salvatore is now leaving Luigi's!
+[GA_8]
+Use the detonator to activate the bomb.
-[AM1_2]
-~r~You have been spotted!
+[GA_10]
+Nice one. Here's your $~1~
-[AM1_3]
-~r~You've missed Salvatore!
+[GA_11]
+We got these wheels already. It's worthless to us!
-[AM1_4]
-~r~Nice going, you scared off the target! Call yourself a hitman?
+[GA_12]
+Bomb armed
-[AM1_5]
-~g~Get to the Red Light District and wait for Salvatore to leave the club.
+[GA_13]
+Delivered like a pro. Complete the list and there'll be a bonus for you.
-[AM1_7]
-~r~Salvatore's home, safe and sipping a cocktail. Ain't no one gonna call you the 'Jackal'!
+[GA_14]
+All the cars. NICE! Here's a little something.
-[AM1_8]
-~g~Salvatore will be leaving Luigi's at about ~1~:~1~
+[GA_15]
+Hope you like the new color.
-[AM2_4]
-~g~They seen you coming like a dayglow elephant!
+[GA_16]
+Respray is complementary.
-[AM3_A]
-A reporter has been nosing around.
+[GA_19]
+We're not interested in that model.
-[AM3_B]
-Maria and I have taken a little holiday together until you can get rid of this perverted voyeur.
+[GA_20]
+We got more of these than we can shift. Sorry man, no deal.
-[AM4_A]
-It's my handsome handyman!
+[CHASE]
+Highest media attention
-[AM4_B]
-Maria's all tied up at the moment but I'll tell her you called.
+[CHASE1]
+Ignored
-[AM4_C]
-Who's that? Asuka? I know I've been a naughty girl but I really need to pee! OK?
+[CHASE2]
+Boring
-[AM4_D]
-It's time you met our man inside the LPD.
+[CHASE3]
+Vaguely interesting
-[AM4_E]
-Here's his payment for the last little job he did for us.
+[CHASE4]
+Local paper Page 7
-[AM4_F]
-He is understandably cautious.
+[CHASE5]
+Front page of local paper
-[AM4_G]
-Get to the pay phone in Torrington as quick as you can and await his instructions.
+[CHASE6]
+Vice Courier Page 2
-[AM5_A]
-Maria and I have gone shopping.
+[CHASE7]
+Vice Courier Front page
-[AM5_B]
-Our source in the police has informed us that one of our drivers is a strangely animated undercover cop!
+[CHASE8]
+Local TV 3am
-[AM5_C]
-He's more or less useless out of his car, so we've tagged it with a tracer.
+[CHASE9]
+Local TV news
-[AM5_D]
-Make him bleed!
+[CHASE10]
+Local TV Live coverage
-[AM5_1]
-Tanner's on to you!
+[CHASE11]
+UFA Today page 12
-[AS1]
-'BAIT'
+[CHASE12]
+UFA Today page 4
-[AS2]
-'ESPRESSO-2-GO!'
+[CHASE13]
+Picture in UFA Today
-[AS4]
-'RANSOM'
+[CHASE14]
+National TV 4am
-[AS1_A]
-~w~Miguel seems to think I'm mistreating him.
+[CHASE15]
+National TV news
-[AS1_B]
-~w~Still, he's revealed the extent to which Catalina fears your quest for revenge.
+[CHASE16]
+National TV live coverage
-[AS2_A]
-~w~We underestimated Catalina's plans for SPANK.
+[CHASE17]
+International news
-[AS2_B]
-~w~It reaches far beyond the Yardies selling it on the street corners.
+[CHASE18]
+National crisis
-[AS2_D]
-~w~They've been selling SPANK through the street stalls.
+[CHASE19]
+International crisis
-[AS2_1]
-~g~All espresso stalls in Portland wrecked!!
+[CHASE20]
+World event
-[AS2_2]
-~g~All espresso stalls in Staunton Island wrecked!!
+[CHASE21]
+Stuff of legends
-[AS2_3]
-~g~All espresso stalls in Shoreside Vale wrecked!!
+[CR_1]
+Crane cannot lift this vehicle.
-[AS2_4]
-~r~The Cartel have warned their pushers!!
+[PU_MONY]
+You don't have enough cash.
-[AS2_5]
-~g~There are still espresso stalls in Shoreside Vale and on Staunton Island!
+[CO_ALL]
+You got all of them. Here's a little something...
-[AS2_6]
-~g~There are still espresso stalls in Shoreside Vale!
+[FEM_ON]
+ON
-[AS2_7]
-~g~There are still espresso stalls on Staunton Island!
+[FEM_OFF]
+OFF
-[AS2_8]
-~g~There are still espresso stalls in Portland!
+[FEM_YES]
+Yes
-[AS2_9]
-~g~There are still espresso stalls in Portland and Shoreside Vale!
+[FEM_NO]
+No
-[AS2_10]
-~g~There are still espresso stalls in Portland and on Staunton Island
+[FEC_NA]
+NA
-[AS2_12]
-~g~Cruise Liberty's districts to find ~b~Espresso-2-Go stalls!
+[FEC_CWL]
+Cycle Weapon left
-[AS3_A]
-~W~Do we tighten it some more now, or just wait for it to turn black and fall off?
+[FEC_CWR]
+Cycle Weapon right
-[AS3_B]
-~w~Give it a quick prod...
+[FEC_LOF]
+Look forward
-[AS3_D]
-~w~My Handyman!
+[FEC_TAR]
+Target
-[AS3_E]
-~w~I was bored so I came over to keep Asuka company.
+[FEC_MOV]
+Movement
-[AS3_1]
-~g~Find the ~r~boat~g~ and get to the ~b~marker buoy!
+[FEC_CAM]
+Camera modes
-[AS3_3]
-~g~Wait for the ~y~plane~g~ to start its approach!
+[FEC_PAU]
+Pause
-[AS3_5]
-~g~Collect the cargo!
+[FEC_ENV]
+Enter vehicle
-[AS3_4]
-~g~Use a rocket launcher to shoot the ~y~plane~g~ down!!
+[FEC_JUM]
+Jump
-[AS3_2]
-~b~Get to the runway marker buoys! ~y~The plane is on its final approach!!
+[FEC_ATT]
+Attack or Fire weapon
-[AS3_6]
-~g~~1~ OF 8
+[FEC_RUN]
+Run
-[KM1]
-'KANBU BUST-OUT'
+[FEC_FPC]
+First person camera
-[KM3]
-'DEAL STEAL'
+[FEC_LL]
+Look left
-[KM4]
-'SHIMA'
+[FEC_LB]
+Look behind
-[KM5]
-'SMACK DOWN'
+[FEC_LR]
+Look right
-[KM1_A]
-My sister speaks highly of you,
+[FEC_HOR]
+Horn
-[KM1_E]
-though I am yet to be convinced that a gaijin can offer anything but disappointment.
+[FEC_VES]
+Vehicle control
-[KM1_B]
-Perhaps you could help deal with a situation that has me at a disadvantage.
+[FEC_BRA]
+Brake or Reverse
-[KM1_F]
-Of course failure has its own disgrace.
+[FEC_HAB]
+Hand brake
-[KM1_C]
-A Yakuza Kanbu is in custody awaiting transfer for trial.
+[FEC_CAW]
+Car weapon
-[KM1_G]
-He is a valued member of the family.
+[FEC_ACC]
+Accelerate
-[KM1_H]
-Break him out of custody and get him to the dojo at Bedford Point.
+[FEC_CCF]
+Configuration
-[KM1_D]
-We thankyou for your selfless actions. If you ever need help the dojo will be honoured to provide two men who will stand at your side.
+[FEC_CF1]
+Setup 1
-[KM1_1]
-~g~Steal a cop car!
+[FEC_CF2]
+Setup 2
-[KM1_2]
-~g~Rig the car with a bomb!
+[FEC_CF3]
+Setup 3
-[KM1_3]
-~g~Now get him to the Yakuza dojo.
+[FEC_CF4]
+Setup 4
-[KM1_5]
-~g~Okay now go to the police station.
+[FEC_CDP]
+Controller Display
-[KM1_6]
-~g~Fit the car with a bomb!
+[FEC_ONF]
+On foot
-[KM1_7]
-~g~Authorised police vehicles only!
+[FEC_INC]
+In car
-[KM1_9]
-~r~You did not use a car bomb to destroy the wall
+[FEC_VIB]
+Vibration
-[KM1_10]
-~r~The Yakuza Kanbu is dead -along with your honor!
+[FEL_ENG]
+English
-[KM1_11]
-~r~You brought the heat down on yourself!
+[FEL_FRE]
+French
-[KM2_A]
-It is impossible to over-estimate the importance of etiquette in this line of work.
+[FEL_GER]
+German
-[KM2_B]
-To my eternal shame, a man once did me a favor and I have never had the opportunity to repay his kindness.
+[FEL_ITA]
+Italian
-[KM2_C]
-The man's weakness is motor cars and he has requested that we acquire him certain models for his collection.
+[FEL_SPA]
+Spanish
-[KM2_F]
-My honor demands it.
+[FED_DBG]
+Menu Debug
-[KM2_2]
-~g~Car delivered.
+[FED_RID]
+Reload IDE
-[KM3_A]
-When trouble looms, the fool turns his back, while the wise man faces it down.
+[FED_RIP]
+Reload IPL
-[KM3_B]
-The Colombian Cartel have ignored repeated requests to leave our interests in Liberty well alone.
+[FED_PAH]
+Parse Heap
-[KM3_C]
-Now they are negotiating terms with the Jamaicans in order to humiliate us further.
+[FED_DFL]
+CTheScripts::DbgFlag
-[KM3_D]
-They are finalizing a deal across town.
+[FED_DLS]
+Big White Debug Light Switched
-[KM3_F]
-Take one of my men, steal a Yardie car, and go and pay your respects to the Colombians.
+[FED_SPR]
+Show Ped Road Groups
-[KM3_E]
-Our Honor demands that you leave no one alive.
+[FED_SCR]
+Show Car Road Grups
-[KM3_2]
-~g~Go and pick up your contact.
+[FED_SCZ]
+Show Cull Zones
-[KM3_3]
-~g~The meeting is being held in the hospital parking lot in Rockford!
+[FED_DSR]
+Debug Streaming Requests
-[KM3_4]
-~r~They got away!
+[FED_SCP]
+gbShowCollisionPolys
-[KM3_6]
-~g~Kill them, kill them all!
+[PL_STAT]
+Player stats
-[KM3_8]
-~g~You need a Yardie car to get on with the job!
+[PE_WAST]
+People you've wasted
-[KM3_9]
-~r~One of the Colombians is dead, the deal's off.
+[PE_WSOT]
+People wasted by others
-[KM3_10]
-~r~The contact is dead!
+[TM_BUST]
+Times busted
-[KM4_A]
-To be truly strong, it is important that you never show weakness.
+[GNG_WST]
+Gang members wasted
-[KM4_C]
-Go and collect the money immediately, so we can enter it into the casino accounts.
+[DED_CRI]
+Criminals wasted
-[KM4_1]
-I can't pay you and I wouldn't pay you if I could!
+[PER_COM]
+Percentage completed
-[KM4_9]
-Some young gang just jacked out the place! They took everything!
+[KGS_EXP]
+Kgs of explosives used
-[KM4_2]
-You guys are useless.
+[ACCURA]
+Accuracy
-[KM4_10]
-What kind of Yakuza are YOU anyway...?
+[ST_WEAP]
+Weapon Budget
-[KM4_3]
-This ain't what I pay you goons for. If I wanted this kind of protection I'd have used the god damn police service
+[ST_PROP]
+Property Budget
-[KM4_4]
-~g~Punish the gang responsible and retrieve the ~b~protection money~g~!
+[ST_AUTO]
+Auto Repair and Painting Budget
-[KM4_7]
-~r~The shopkeeper's breathed his last!
+[ST_PHOT]
+Photographs Taken
-[KM4_5]
-Donald Love wishes you to drop by his tea garden so you and he can talk.
+[ST_LOAN]
+Visits From Loan Sharks
-[KM4_6]
-There's the money its all there!
+[ST_STOR]
+Stores Knocked Off
-[KM4_8]
-~g~Briefcase collected!
+[ST_MOVI]
+Movie Stunts
-[KM5_A]
-YOU! How fitting you should choose this moment to show your worthless face!
+[ST_PIZZ]
+Pizza's Delivered
-[KM5_B]
-It would appear your attempts to dissuade the Jamaicans
+[ST_GARB]
+Garbage Pickups Made
-[KM5_B1]
-from becoming bed fellows with the Cartel were wholly inadequate!
+[TOP_SHO]
+Top Shooting Range Score
-[KM5_C]
-Yardie pushers line Liberty's streets selling packets of SPANK like they were selling hotdogs!
+[SHO_RAN]
+Shooting Range Rank
-[KM5_D]
-Those Cartel pigs are laughing at us, at me!
+[SEAGULL]
+Seagulls Sniped
-[KM5_E]
-I will give you one last chance to prove my sister's faith in you to be well founded!
+[PROPOWN]
+Property Owned
-[KM5_F]
-Run these scumbags into the ground and wash your shame in rivers of our enemies' blood!!!
+[ST_TIME]
+Playing Time
-[KM5_3]
-~r~You failed to kill at least ~1~ yardies.
+[ST_FTIM]
+Flight hours
-[KM5_4]
-~g~Congratulations you killed ~1~ Yardies.
+[ST_PRAN]
+Pilot Ranking
-[KM5_5]
-~g~Congratulations you killed ~1~ Yardies. BONUS $~1~
+[ST_RAN0]
+Learner
-[RM1]
-'SILENCE THE SNEAK'
+[ST_RAN1]
+Navigator
-[RM3]
-'EVIDENCE DASH'
+[ST_RAN2]
+Co Pilot
-[RM4]
-'GONE FISHING'
+[ST_RAN3]
+Junior
-[RM5]
-'PLASTER BLASTER'
+[ST_RAN4]
+Competent
-[RM1_D]
-He's under armed protection in WitSec property down in Newport, some apartment behind the car park.
+[ST_RAN5]
+Senior
-[RM1_E]
-Torch that place, that should flush 'em out, and you'll hunt 'em down, make sure he never talks to nobody.
+[ST_RAN6]
+Ace
-[RM1_1]
-~g~Check out the witness protection house.
+[ST_RAN7]
+Red baron
-[RM1_2]
-~g~Take out McAffrey!
+[ST_DRWN]
+Fishes Fed
-[RM2_A1]
-Hey kid over here!
+[ST_FASH]
+Fashion Budget
-[RM2_A]
-An old army buddy of mine runs a business in Rockford.
+[ST_DAMA]
+Property Destroyed
-[RM2_D]
-He's gonna need some back-up and in return he'll give you knock-down rates on any hardware you buy.
+[TM_DED]
+Hospital visits
-[RM2_E]
-Ray phoned ahead....but I thought there'd be more of you.
+[DAYSPS]
+Days passed in game
-[RM2_F]
-Well, three arms are better than one, so grab whatever you need.
+[NUMSHV]
+Safehouse visits
-[RM2_G]
-~g~Go and check on Phil!
+[MXCARD]
+Max. INSANE Jump dist. (ft)
-[RM2_H]
-~r~Phil has been killed!!
+[MXCARJ]
+Max. INSANE Jump height (ft)
-[RM2_L]
-Heh-hey! If I'd teamed up with you in Nicaragua maybe I'd still have my arm!
+[MXCARDM]
+Max. INSANE Jump dist. (m)
-[RM2_N]
-Leave the cash behind. Now get out of here, I'll handle the cops.
+[MXCARJM]
+Max. INSANE Jump height (m)
-[RM3_D]
-The evidence is being driven across town.
+[MXFLIP]
+Max. INSANE Jump flips
-[RM3_E]
-You are going to have to ram that car and collect each little bit of evidence as it falls out.
+[MXJUMP]
+Max. INSANE Jump rotation
-[RM3_F]
-When you've got it all, leave it in the car and torch it.
+[BUL_FIR]
+Bullets fired
-[RM3_G]
-We're both gonna do pretty well outta this kid.
+[BUL_HIT]
+Bullets that hit
-[RM3_1]
-~g~Leave the evidence in a car then torch the car.
+[SPRAYIN]
+Sprayings
-[RM3_4]
-~g~The Prosecution has dropped the evidence!
+[BSTSTU]
+Best INSANE stunt so far
-[RM3_6]
-~r~The photos will be washed up all over Liberty!
+[INSTUN]
+Insane stunt
-[RM3_7]
-~g~Now torch the car!
+[PRINST]
+Perfect insane stunt
-[RM4_A]
-I think my partner's a rat.
+[DBINST]
+Double insane stunt
-[RM4_C]
-He goes fishing out of his boat near the lighthouse on Portland Rock most nights.
+[DBPINS]
+Perfect double insane stunt
-[RM4_D]
-Steal a police boat and make sure his back stabbing plans are sunk!
+[TRINST]
+Triple insane stunt
-[RM4_1]
-~g~Go and steal a police boat.
+[PRTRST]
+Perfect triple insane stunt
-[RM4_2]
-~g~Get to the lighthouse and 'rub out' Ray's partner!
+[QUINST]
+Quadruple insane stunt
-[RM5_A]
-You useless bastard!
+[PQUINS]
+Perfect quadruple insane stunt
-[RM5_A1]
-You totally messed up! My ass is on the line and you can't even kill a god damned fly.
+[NOSTUC]
+No INSANE stunts completed
-[RM5_B]
-I paid you good money to kill that witness and he ain't dead!
+[NOUNIF]
+Unique Jumps completed
-[RM5_B1]
-And today he's gonna make a Federal Deposition!
+[NMISON]
+Mission attempts
-[RM5_C]
-He's being moved any second now from the Carson General Hospital up in Rockford.
+[PASDRO]
+Passengers dropped off
-[RM5_D]
-If he squeals, I squeal....
+[MONTAX]
+Cash made in taxi
-[RM5_E]
-so go do the job you were paid for!
+[DAYPLC]
+Daily police spending
-[RM5_1]
-~g~Intercept the ambulance.
+[CRIMRA]
+Criminal rating:
-[RM5_2]
-~g~You've been spotted!!
+[STPR_1]
+The Malibu
-[RM5_3]
-~g~It was a decoy!
+[STPR_2]
+Print Works
-[RM5_4]
-~g~Bullets won't get through that armored bodycast!!
+[STPR_3]
+Film Studio
-[RM5_5]
-~g~That armored bodycast is flame retardant!!
+[STPR_4]
+Ice Cream Factory
-[RM5_7]
-~r~Witness has been delivered!!
+[STPR_5]
+Car Showroom
-[RM5_8]
-~g~Witness has drowned!!
+[STPR_6]
+Taxi Company
-[LOVE2]
-'WAKA-GASHIRA WIPEOUT!'
+[STPR_7]
+Boatyard
-[LOVE3]
-'A DROP IN THE OCEAN'
+[SET1EN]
+SetUp 1. Enabled
-[LOVE1_A]
-First of all, let me thank you for dealing with that personal matter.
+[GMSAVE]
+Save Game
-[LOVE1_F]
-People will read something into anything these days.
+[FEDS_TB]
+Back
-[LOVE1_D]
-They're trying to extort additional funds from me but I don't believe in re-negotiation.
+[FEST_OO]
+out of
-[LOVE1_E]
-A deal is a deal, so they'll not see a penny from me.
+[FEC_TUC]
+Turret control
-[LOVE1_G]
-Go and rescue my friend, do whatever it takes.
+[FEC_RS3]
+Radio station cycle (L3 button)
-[LOVE1_2]
-~g~Rescue the Old Oriental Gentleman.
+[FEC_HO3]
+Horn (L3 button)
-[LOVE1_3]
-~g~Take the Old Oriental Gentleman back to Donald Love's building.
+[C_FAIL]
+Vigilante mission ended!
-[LOVE1_4]
-~g~The Old Oriental Gentleman must be in one of the garages....
+[C_ESCP]
+~r~The suspect has escaped!
-[LOVE1_6]
-~r~The Old Oriental Gentleman's guts are all over the street!
+[C_VIGIL]
+VIGILANTE BONUS!!
-[LOVE1_7]
-~g~The gate will only open for a Colombian Gang-car.
+[HEAL_A]
+Your ~h~health~w~ is displayed in orange in the top right of the screen.
-[LOVE2_A]
-Nothing drives down real estate prices like a good old fashioned gang war,
+[WRONGCD]
+Incorrect disc. Please insert correct disc.
-[LOVE2_B]
-apart from an outbreak of plague......but that might be going too far in this case.
+[NOCD]
+The disc tray is empty. Please insert disc.
-[LOVE2_C]
-I've noticed the Yakuza and the Colombians are far from friends.
+[OPENCD]
+The disc tray is open. Please close the disc tray.
-[LOVE2_D]
-Let's capitalise on this business opportunity.
+[CDERROR]
+Error reading the Grand Theft Auto: Vice City DVD
-[LOVE2_E]
-I want you to kill the Yakuza Waka-gashira, Kenji Kasen.
+[RESTART]
+Starting new game
-[LOVE2_F]
-Kenji is attending a meeting at the top of the multi-story carpark in Newport.
+[GA_3]
+No more freebies. $100 to respray!
-[LOVE2_G]
-Get a Cartel gangcar and eliminate him!
+[GA_1]
+Whoa! I don't touch nothing THAT hot!
-[LOVE2_H]
-The Yakuza must blame the Cartel for this declaration of war.
+[GA_1A]
+Come back when you're not so busy...
-[LOVE2_1]
-~g~Go to Fort Staunton and steal a Colombian gangcar!
+[HELP9_C]
+Press the~h~ ~k~~PED_FIREWEAPON~ ~w~button to ~h~fire~w~ the sniper rifle.
-[LOVE2_2]
-~g~Now get to the ~p~multi-storey in Newport~g~ and whack Kenji!
+[TAXI2]
+~r~You're out of time!
-[LOVE2_3]
-~r~If you proceed without a Cartel car you will be identified!!
+[PAGEB13]
+Health delivered to hideout
-[LOVE2_4]
-~r~The Yakuza have identified you!!
+[PAGEB14]
+Adrenaline delivered to hideout
-[LOVE2_6]
-~r~You've killed all the witnesses!!
+[FESZ_CA]
+Cancel
-[LOVE3_A]
-In these days of moral hypocrisy certain valuable commodities can be hard to import.
+[FES_NGA]
+New Game
-[LOVE3_C]
-It will drop several packages into the water.
+[FES_CAN]
+Cancel
-[LOVE3_D]
-Make sure you pick them up before anyone else does.
+[FESZ_QL]
+All unsaved progress in your current game will be lost. Proceed with loading?
-[LOVE3_1]
-~g~Get a ~r~boat~g~ and follow the ~y~plane~g~!
+[FESZ_QD]
+Proceed with deleting this save game?
-[LOVE4]
-'GRAND THEFT AERO'
+[FESZ_QO]
+Proceed with overwriting this save game?
-[LOVE5]
-'ESCORT SERVICE'
+[T4X4_1]
+'PCJ Playground'
-[LOVE4_A]
-Thank you for retrieving those packages, but they were only a decoy.
+[BMX_1]
+'Trial by Dirt'
-[LOVE4_B]
-Sorry about that, but that's sometimes the way in business.
+[BMX_2]
+'Test Track'
-[LOVE4_C]
-My real objective was hidden on the plane all along.
+[BMXFAIL]
+~r~You failed to set a new record!
-[LOVE4_F]
-I've paid off the officials.
+[BMX_REC]
+~g~New Record Set:~1~ !!
-[LOVE4_1]
-~r~The Colombian Cartel is here!!
+[T4X4_3]
+'GRIPPED!'
-[LOVE4_2]
-~g~The package is gone! Track down the Colombians and retrieve it.
+[MM_1]
+'CONE CRAZY'
-[LOVE4_3]
-~g~Panlantic Construction...?
+[T4X4_F]
+~r~You bailed! Too tough for you?!
-[LOVE4_5]
-~g~The package should be in the plane....
+[LANDSTK]
+Landstalker
-[LOVE4_6]
-~g~Take the lift up the tower!
+[IDAHO]
+Idaho
-[LOVE5_B]
-My Oriental friend will need an escort while he takes my latest acquisition to be authenticated.
+[STINGER]
+Stinger
-[LOVE5_1]
-~g~Lets go!
+[LINERUN]
+Linerunner
-[LOVE5_2]
-~g~You'll need a car!
+[PEREN]
+Perennial
-[LOVE5_3]
-~g~Go ahead and scout the exit of the tunnel!
+[SENTINL]
+Sentinel
-[LOVE5_4]
-~r~Protect the truck!
+[RIO]
+Rio
-[RM6]
-'MARKED MAN'
+[PATRIOT]
+Patriot
-[RM6_A]
-You weren't followed? Good.
+[FIRETRK]
+Firetruck
-[RM6_B]
-This is it, I'm way over my head and I'm starting to drown here!
+[TRASHM]
+Trashmaster
-[RM6_D]
-I'm a marked man, so I'm getting out of here.
+[STRETCH]
+Stretch
-[RM6_E]
-Get me to my flight at the airport and I'll make it worth your while!
+[MANANA]
+Manana
-[RM6_666]
-Take care of my bullet proof Patriot. See you in Miami, Ray
+[INFERNS]
+Infernus
-[CAT1]
-'RANSOM'
+[VOODOO]
+Voodoo
-[CAT2]
-'THE EXCHANGE'
+[PONY]
+Pony
-[CAT1_A]
-I've got your precious Maria. If you don't want her face to look like she fell out with the butcher.
+[MULE]
+Mule
-[CAT2_F]
-I broke a nail, and my hair's ruined. Can you believe it? This one cost me fifty dollars!
+[CHEETAH]
+Cheetah
-[CAT2_G]
-I was so scared, but then I thought to myself, you're a big girl now.
+[AMBULAN]
+Ambulance
-[CAT2_H]
-Oh we're going to have such fun, cause, you know, my sister said she wanted to come to stay with her two kids,
+[FBICAR]
+FBI Washington
-[CAT2_I]
-because her husband's playing around again and..
+[MOONBM]
+Moonbeam
-[CAT1_E]
-XXXX
+[ESPERAN]
+Esperanto
-[CAT1_F]
-Get to Catalina before the time runs out!
+[TAXI]
+Taxi
-[CAT_MON]
-~g~You don't have enough money yet. You need $500,000.
+[WASHING]
+Washington
-[BITCH_D]
-~g~Maria's dead!
+[BOBCAT]
+Bobcat
-[WEATHER]
-FORCE WEATHER
+[WHOOPEE]
+Mr. Whoopee
-[WEATHE2]
-WEATHER NORMAL
+[BFINJC]
+BF Injection
-[8001]
-You failed miserably!!
+[HUNTER]
+Hunter
-[1000]
-YOU ARE DEAD
+[POLICAR]
+Police
-[1001]
-YOU ARE DEAD
+[ENFORCR]
+Enforcer
-[1002]
-YOU ARE DEAD
+[SECURI]
+Securicar
-[1003]
-YOU ARE DEAD
+[BANSHEE]
+Banshee
-[1004]
-YOU ARE DEAD
+[PREDATR]
+Predator
-[1005]
-BUSTED
+[BUS]
+Bus
-[1006]
-BUSTED
+[RHINO]
+Rhino
-[1007]
-BUSTED
+[BARRCKS]
+Barracks OL
-[1008]
-BUSTED
+[CUBAN]
+Cuban Hermes
-[1009]
-BUSTED
+[HELI]
+Helicopter
-[GA_4]
-Car bombs are $1000 each
+[DODO]
+Dodo
-[GA_5]
-Your car is already fitted with a bomb.
+[COACH]
+Coach
-[GA_6] { re3 change }
-Park it, prime it by pressing the ~h~~k~~VEHICLE_FIREWEAPON~ button~w~ and LEG IT!
+[CABBIE]
+Cabbie
-[GA_7] { re3 change }
-Arm with ~h~~k~~VEHICLE_FIREWEAPON~ button~w~. Bomb will go off when engine is started.
+[STALION]
+Stallion
-[GA_8]
-Use the detonator to activate the bomb.
+[RUMPO]
+Rumpo
-[GA_9]
-You collected ~1~ out of 10 special cars
+[RCBANDT]
+RC Bandit
-[GA_10]
-Nice one. Here's your $~1~
+[ROMERO]
+Romero's Hearse
-[GA_11]
-We got these wheels already. It's worthless to us!
+[PACKER]
+Packer
-[GA_12]
-Bomb armed
+[ADMIRAL]
+Admiral
-[GA_13]
-Delivered like a pro. Complete the list and there'll be a bonus for you.
+[SQUALO]
+Squalo
-[GA_14]
-All the cars. NICE! Here's a little something.
+[SEASPAR]
+Sea Sparrow
-[GA_15]
-Hope you like the new color.
+[PIZZABO]
+Pizza Boy
-[GA_16]
-Respray is complementary.
+[GANGBUR]
+Gang Burrito
-[GA_19]
-We're not interested in that model.
+[TROPIC]
+Tropic
-[GA_20]
-We got more of these than we can shift. Sorry man, no deal.
+[SPEEDER]
+Speeder
-[CR_1]
-Crane cannot lift this vehicle.
+[REEFER]
+Reefer
-[PU_MONY]
-You don't have enough cash.
+[FLATBED]
+Flatbed
-[CO_ALL]
-You got all of them. Here's a little something...
+[YANKEE]
+Yankee
-[PAUSED]
-GAME PAUSED
+[CADDY]
+Caddy
-[HEALTH1]
-Get outta here! You're perfectly healthy.
+[ZEBRA]
+Zebra Cab
-[HEALTH2]
-Healthcare costs.
+[TOPFUN]
+Top Fun
-[HEALTH3]
-I'll just fix you up.
+[SKIMMER]
+Skimmer
-[HEALTH4]
-That will be $250.
+[PCJ600]
+PCJ 600
-[FEB_STA]
-Stats
+[PHOENIX]
+Phoenix
-[FEB_BRI]
-Briefs
+[FAGGIO]
+Faggio
-[FEB_CON]
-Controls
+[FREEWAY]
+Freeway
-[FEB_AUD]
-Audio
+[RCBARON]
+RC Baron
-[FEB_DIS]
-Display
+[RCRAIDE]
+RC Raider
-[FEB_LAN]
-Language
+[GLENDAL]
+Glendale
-[FEP_STA]
-STATS
+[OCEANIC]
+Oceanic
-[FEP_BRI]
-BRIEFS
+[SANCHEZ]
+Sanchez
-[FEP_CON]
-CONTROLS
+[SPARROW]
+Sparrow
-[FEP_AUD]
-AUDIO
+[LOVEFIS]
+Love Fist
-[FEP_DIS]
-DISPLAY
+[COASTG]
+Coast Guard
-[FEP_LAN]
-LANGUAGE
+[DINGHY]
+Dinghy
-[FEF_ST1]
-Who's the bad man?
+[HERMES]
+Hermes
-[FEF_ST2]
-How much havoc have you caused
+[SABRE]
+Sabre
-[FEF_BR1]
-Lost the plot?
+[SABRETU]
+Sabre Turbo
-[FEF_CO1]
-Need more control, freak?
+[WALTON]
+Walton
-[FEF_CO2]
-Choose the best contoller set-up for your playing style
+[REGINA]
+Regina
-[FEF_SA1]
-Keep your place in the pile!
+[COMET]
+Comet
-[FEF_SA2]
-Save and load your games
+[DELUXO]
+Deluxo
-[FEF_AU1]
-Pump up the volume!
+[BURRITO]
+Burrito
-[FEF_AU2]
-Select a radio station and sound effect
+[SPAND]
+Spand Express
-[FEF_DI1]
-Change the game!
+[MARQUIS]
+Marquis
-[FEF_DI2]
-Customize the game for your TV
+[BAGGAGE]
+Baggage Handler
-[FEF_LA1]
-What you talking about willis?
+[KAUFMAN]
+Kaufman Cab
-[FEF_LA2]
-Choose your preferred parlance
+[COASTMA]
+Coastguard Maverick
-[FEB_PMB]
-Previous Mission Briefs:
+[MAVERIC]
+Maverick
-[FEC_NA]
-NA
+[RANCHER]
+Rancher
-[FEC_CWL]
-Cycle Weapon left
+[FBIRANC]
+FBI Rancher
-[FEC_CWR]
-Cycle Weapon right
+[VIRGO]
+Virgo
-[FEC_LOF]
-Look forward
+[GREENWO]
+Greenwood
-[FEC_TAR]
-Target
+[HOTRING]
+Hotring Racer
-[FEC_MOV]
-Movement
+[BLISTAC]
+Blista Compact
-[FEC_CAM]
-Camera modes
+[FEST_DF]
+Dist. traveled on foot (miles)
-[FEC_PAU]
-Pause
+[FEST_DC]
+Dist. traveled by car (miles)
-[FEC_ENV]
-Enter vehicle
+[FESTDFM]
+Distance traveled on foot (m)
-[FEC_JUM]
-Jump
+[FESTDCM]
+Distance traveled by car (m)
-[FEC_ATT]
-Attack or Fire weapon
+[TOT_DIS]
+Total distance traveled (miles)
-[FEC_RUN]
-Run
+[TOTDISM]
+Total distance traveled (m)
-[FEC_FPC]
-First person camera
+[DISTHEL]
+Dist. traveled by helicopter (miles)
-[FEC_LL]
-Look left
+[DISTHEM]
+Distance traveled by helicopter (m)
-[FEC_LB1]
-Look
+[DISTBOA]
+Dist. traveled by boat (miles)
-[FEC_LB2]
-behind
+[DISTBOM]
+Distance traveled by boat (m)
-[FEC_LB]
-Look behind
-
-[FEC_LR]
-Look right
-
-[FEC_HOR]
-Horn
+[FEST_LS]
+People saved in an Ambulance
-[FEC_VES]
-Vehicle control
+[FEST_CC]
+Criminals killed on Vigilante Mission
-[FEC_RSC]
-Radio station cycle
+[FEST_FE]
+Total fires extinguished
-[FEC_BRA]
-Brake or Reverse
+[FEST_RP]
+Rampages passed
-[FEC_HAB]
-Hand brake
+[FEST_MP]
+Missions passed
-[FEC_CAW]
-Car weapon
+[FEST_BB]
+Bling-bling Scramble:
-[FEC_ACC]
-Accelerate
+[FEST_H0]
+Most checkpoints
-[FEC_SMT]
-Special mission trigger
+[FEST_GC]
+Gang Cars Totaled:
-[FEA_OUT]
-Output:
+[FEST_H1]
+Diablo destruction
-[FEA_ST]
-Stereo
+[FEST_H2]
+Mafia Massacre
-[FEA_MNO]
-Mono
+[FEST_H3]
+Casino Calamity
-[FEA_NON]
-None
+[FEST_H4]
+Rumpo Wrecker
-[FEA_FM0]
-HEAD RADIO
+[USJ]
+UNIQUE STUNT BONUS!
-[FEA_FM1]
-DOUBLE CLEFF FM
+[RATNG1]
+Upstanding Citizen
-[FEA_FM2]
-JAH RADIO
+[RATNG2]
+Nobody Special
-[FEA_FM3]
-RISE FM
+[RATNG3]
+Litterer
-[FEA_FM4]
-LIPS 106
+[RATNG4]
+Shoplifter
-[FEA_FM5]
-GAME FM
+[RATNG5]
+Vandal
-[FEA_FM6]
-MSX FM
+[RATNG6]
+Do boy
-[FEA_FM7]
-FLASHBACK 95.6
+[RATNG7]
+Pickpocket
-[FEA_FM8]
-CHATTERBOX 109
+[RATNG8]
+Clepto
-[FED_DBG]
-Menu Debug
+[RATNG9]
+Snitch
-[FED_RID]
-Reload IDE
+[RATNG10]
+Rat
-[FED_RIP]
-Reload IPL
+[RATNG11]
+Leece
-[FED_PAH]
-Parse Heap
+[RATNG12]
+Scam Artist
-[FED_RCD]
-CCullZones::RecalculateCullZoneData
+[RATNG13]
+Trickster
-[FED_DFL]
-CTheScripts::DbgFlag
+[RATNG14]
+Numbers Runner
-[FED_DLS]
-Big White Debug Light Switched
+[RATNG15]
+Hustler
-[FED_SPR]
-Show Ped Road Groups
+[RATNG16]
+Bully
-[FED_SCR]
-Show Car Road Grups
+[RATNG17]
+Riff-Raff
-[FED_SCZ]
-Show Cull Zones
+[RATNG18]
+Scalawag
-[FED_DSR]
-Debug Streaming Requests
+[RATNG19]
+Ruffian
-[FED_SCP]
-gbShowCollisionPolys
+[RATNG20]
+Outlaw
-[FEM_MCM]
-Memory Card Menu
+[RATNG21]
+Thug
-[FEM_RMC]
-Register MemCard One
+[RATNG22]
+Drop Man
-[FEM_TFM]
-Test Format MemCard One
+[RATNG23]
+SA Goon
-[FEM_TUM]
-Test UnFormat MemCard One
+[RATNG24]
+Goon
-[FEM_CRD]
-Create Root Dir
+[RATNG25]
+Jailbird
-[FEM_CLI]
-Create And Load Icons
+[RATNG26]
+Ex-Con
-[FEM_FFF]
-Fill First File with Guff
+[RATNG27]
+Felon
-[FEM_SOG]
-Save Only The Game
+[RATNG28]
+Bag Man
-[FEM_CES]
-Check Every 0kB4 Save
+[RATNG29]
+Wiseguy
-[FEM_STG]
-Save The Game
+[RATNG30]
+Wheelman
-[FEM_STS]
-Save The Game under GTA3 name
+[RATNG31]
+Hired Muscle
-[FEM_CPD]
-Create copy protected mag directory
+[RATNG32]
+Hatchetman
-[FEM_MC2]
-Memory Card Menu 2
+[RATNG33]
+Headhunter
-[FEM_TS]
-Test Save:
+[RATNG34]
+Enforcer
-[FEM_TL]
-Test Load:
+[RATNG35]
+Ronin
-[FEM_TD]
-Test Delete:
+[RATNG36]
+Fixer
-[PL_STAT]
-Player stats
+[RATNG37]
+Hitman
-[PE_WAST]
-People you've wasted
+[RATNG38]
+Associate
-[PE_WSOT]
-People wasted by others
+[RATNG39]
+Butcher
-[CAR_EXP]
-Cars exploded
+[RATNG40]
+Cleaner
-[TM_BUST]
-Times busted
+[RATNG41]
+Assassin
-[M_WASTE]
-Civilian males wasted
+[RATNG42]
+Consigliere
-[F_WASTE]
-Civilian females wasted
+[RATNG43]
+Made Man
-[PIG_WST]
-Cops wasted
+[RATNG44]
+Right-Hand Man
-[GNG_WST]
-Gang members wasted
+[RATNG45]
+Executioner
-[MED_WST]
-Medics wasted
+[RATNG46]
+Lieutenant
-[FIRE_WS]
-Firemen wasted
+[RATNG47]
+Underboss
-[DED_CRI]
-Criminals wasted
+[RATNG48]
+Capo
-[DED_DED]
-Deadbeats wasted
+[RATNG49]
+Boss
-[DED_HOK]
-Hookers wasted
+[RATNG50]
+Kingpin
-[HEL_DST]
-Helicopters destroyed
+[RATNG51]
+Don
-[PER_COM]
-Percentage completed
+[RATNG52]
+Godfather
-[KGS_EXP]
-Kgs of explosives used
+[PAGE_00]
+.
-[ACCURA]
-Accuracy
+[WELCOME]
+WELCOME TO
-[ELBURRO]
-Best Turismo time in secs
+[TSCORE]
+EARNINGS: $~1~
-[CAR_CRU]
-Cars crushed
+[PBOAT_2] { reVC update }
+Press the ~h~~k~~VEHICLE_FIREWEAPON~ ~w~button to fire the boat cannons.
-[HED_EX]
-Heads exploded
+[HJSTAT]
+Distance: ~1~.~1~m Height: ~1~.~1~m Flips: ~1~ Rotation: ~1~_
-[TM_DED]
-Hospital visits
+[HJSTATW]
+Distance: ~1~.~1~m Height: ~1~.~1~m Flips: ~1~ Rotation: ~1~_ And what a great landing!
-[DAYSPS]
-Days passed in game
+[ATUTOR]
+Press the ~h~~k~~TOGGLE_SUBMISSIONS~ ~w~button to toggle Paramedic missions on or off.
-[MMRAIN]
-Mm rain fallen
+[FEST_HA]
+Highest Paramedic Mission level
-[MXCARD]
-Max. INSANE Jump dist. (ft)
+[C_KILLS]
+CRIMINALS KILLED: ~1~
-[MXCARJ]
-Max. INSANE Jump height (ft)
+[HJSTATF]
+Distance: ~1~ft Height: ~1~ft Flips: ~1~ Rotation: ~1~_
-[MXCARDM]
-Max. INSANE Jump dist. (m)
+[HJSTAWF]
+Distance: ~1~ft Height: ~1~ft Flips: ~1~ Rotation: ~1~_ And what a great landing!
-[MXCARJM]
-Max. INSANE Jump height (m)
+[CINCAM]
+Cinematic Camera
-[MXFLIP]
-Max. INSANE Jump flips
+[RC4]
+'RUMPO RAMPAGE'
-[MXJUMP]
-Max. INSANE Jump rotation
+[LEGAL]
+~g~Eliminate the criminal threat!
-[BSTSTU]
-Best INSANE stunt so far:
+[GA_2]
+New engine and paint job. The cops won't recognize you!
-[INSTUN]
-Insane stunt
+[HELP15]
+When on foot press the ~h~~k~~PED_LOOKBEHIND~ ~w~button to ~h~look behind~w~.
-[PRINST]
-Perfect insane stunt
+[FEC_LB4]
+Look behind (R3 button)
-[DBINST]
-Double insane stunt
+[PERPIC]
+Hidden Packages found
-[DBPINS]
-Perfect double insane stunt
+[CO_ONE]
+Hidden Package ~1~ of ~1~
-[TRINST]
-Triple insane stunt
+[GA_21]
+You cannot store any more cars in this garage.
-[PRTRST]
-Perfect triple insane stunt
+[CHEAT1]
+Cheat activated
-[QUINST]
-Quadruple insane stunt
+[CHEAT2]
+Weapon cheat
-[PQUINS]
-Perfect quadruple insane stunt
+[CHEAT3]
+Health cheat
-[NOSTUC]
-No INSANE stunts completed
+[CHEAT4]
+Armor cheat
-[NOUNIF]
-Unique Jumps completed
+[CHEAT5]
+Wanted level cheat
-[NOUNGM]
-Total Unique Jumps
+[CHEAT6]
+Money cheat
-[NMISON]
-Mission attempts
+[CHEAT7]
+Weather cheat
-[NMMISP]
-Missions passed
+[USJ_ALL]
+ALL UNIQUE STUNTS COMPLETED!
-[PASDRO]
-Passengers dropped off
+[JAN]
+Jan
-[MONTAX]
-Cash made in taxi
+[FEB]
+Feb
-[DAYPLC]
-Daily police spending
+[MAR]
+Mar
-[CRIMRA]
-Criminal rating:
+[APR]
+Apr
-[GMSTOR]
-Game Store
+[MAY]
+May
-[PREBRF]
-Previous Briefs
+[JUN]
+Jun
-[CNTLS]
-Controls
+[JUL]
+Jul
-[MUSMEN]
-Music/SFX
+[AUG]
+Aug
-[GAMSET]
-Game Settings
+[SEP]
+Sept
-[LANGUA]
-Language
+[OCT]
+Oct
-[DSPLAY]
-Display
+[NOV]
+Nov
-[DEBUGM]
-Debug Menu
+[DEC]
+Dec
-[QUITOP]
-Quit Options
+[DEFDT]
+--:---:---- --:--:--
-[CONTRL]
-Control Configuration
+[BONUS]
+~g~BONUS $~1~
-[SET1EN]
-SetUp 1. Enabled
+[HORN1]
+Press the ~h~~k~~VEHICLE_HORN~ ~w~button to activate the ~h~horn.
-[SET1]
-SetUp 1.
+[HORN2]
+Press the ~h~~k~~VEHICLE_HORN~ ~w~button to activate the ~h~horn
-[SET2EN]
-SetUp 2. Enabled
+[HORN3]
+Press the ~h~~k~~VEHICLE_HORN~ ~w~button to activate the ~h~horn
-[SET2]
-SetUp 2
+[FEC_EXV]
+Enter and exit vehicle
-[SET3EN]
-SetUp 3. Enabled
+[TAXI_M]
+'TAXI DRIVER'
-[SET3]
-SetUp 3
+[COP_M]
+'VIGILANTE'
-[SET4EN]
-SetUp 4. Enabled
+[FIRE_M]
+'FIREFIGHTER'
-[SET4]
-SetUp 4
+[AMBUL_M]
+'PARAMEDIC'
-[GOBACK]
-GoBack
+[HJ_IS]
+INSANE STUNT BONUS: $~1~
-[SOUND]
-SOUND
+[HJ_PIS]
+PERFECT INSANE STUNT BONUS: $~1~
-[MUSVOL]
-Music Volume
+[HJ_DIS]
+DOUBLE INSANE STUNT BONUS: $~1~
-[SFXVOL]
-SFX Volume
+[HJ_PDIS]
+PERFECT DOUBLE INSANE STUNT BONUS: $~1~
-[SCROPT]
-SCREEN OPTIONS
+[HJ_TIS]
+TRIPLE INSANE STUNT BONUS: $~1~
-[CTRSCR]
-Center Screen
+[HJ_PTIS]
+PERFECT TRIPLE INSANE STUNT BONUS: $~1~
-[SCRFOR]
-Screen format
+[HJ_QIS]
+QUADRUPLE INSANE STUNT BONUS: $~1~
-[GMSVLQ]
-GAME SAVE-LOAD-QUIT
+[HJ_PQIS]
+PERFECT QUADRUPLE INSANE STUNT BONUS: $~1~
-[GMREST]
-Restart Game
+[FESZ_LS]
+Load Successful.
-[NOGMSV]
-Can save only at your hideout.
+[HELI_1A]
+Test your skills with the Sparrow, see how quickly you can complete the course.
-[DLFILE]
-Delete Grand Theft Auto III Files
+[HELI_1B]
+Course Complete! $ ~1~
-[CHFILE]
-CHOOSE FILE TO LOAD
+[HELIODD]
+Helicopter odd jobs
-[CHFIDL]
-CHOOSE FILE TO DELETE
+[LAW]
+THE LAWYER MISSIONS
-[SVCONF]
-SAVE CONFIRMATION
+[LAW1_1]
+~g~Go get some new threads from Rafael's clothes shop.
-[LANGSL]
-LANGUAGE SELECTION
+[LAW4_6]
+Burn the management!
-[ENGLIS]
-English
+[LAW4_7]
+Kill the bosses!
-[GERMAN]
-German
+[LAW4_8]
+Fight, Fight, Fight, Fight.
-[ITALIA]
-Italian
+[LAW4_9]
+More Holiday, Less Work!
-[FRENCH]
-French
+[LAW4_11]
+Fight! Fight! Fight! Fight!
-[SPAIN]
-Spanish
+[LAW4_12]
+Viva la revolution!
-[RELIDE]
-ReLoadIde
+[GENERAL]
+THE COLONEL MISSIONS
-[RELIPE]
-ReLoadIpl
+[GEN3_4]
+Tommy Vercetti. Let's go...
-[PARSHP]
-Parse Heap
+[GEN3_13]
+What's the matter with you man?! Get on the roof across the yard before they turn up!
-[DBGFON]
-CTheScripts::DbgFlag On
+[GEN3_17]
+Sheeit! You trying to kill me?!
-[DBFOFF]
-CTheScripts::DbgFlag Off
+[GEN3_21]
+~g~He got Diaz's money! Chase him down and get it back!
-[BGWHON]
-Big White Debug Light Switched On
+[GEN3_24]
+~r~Diaz died! You failed to protect him!
-[BGWOFF]
-Big White Debug Light Switched Off
+[GEN3_26]
+~r~You shot Diaz!
-[DSTRON]
-Debug Streaming Requests On
+[GEN3_27]
+~r~You shot Diaz's bodyguards!
-[DSTROFF]
-Debug Streaming Requests Off
+[GEN3_31]
+~g~Now go to the drop off and watch over Diaz.
-[PDRGON]
-ShowPedRoadGroups On
+[GEN3_32]
+~g~Get to your vantage point on the roof of the building opposite Lance.
-[PRGOFF]
-ShowPedRoadGroups Off
+[COKE]
+THE COKE BARON MISSIONS
-[CRRGON]
-ShowCarRoadGroups On
+[COK1_3]
+Hope you fall and break your neck!
-[CRGOFF]
-ShowCarRoadGroups Off
+[COK1_6]
+I'm sick of these pricks.
-[CLZOON]
-Show Cull Zones On
+[COK2_7]
+See those marker boys? Try taking out the lights!
-[CLZOOF]
-Show Cull Zones Off
+[COK2_10]
+You sure is better at shooting than talking.
-[SHPLON]
-gbShowCollisionPolys On
+[COK2_11]
+Thanks. You're a real charmer yourself.
-[SHPLOF]
-gbShowCollisionPolys Off
+[COK2_12]
+I Know, Tommy.
-[CULREC]
-CCullZones::RecalculateCullZoneData()
+[COK2_18]
+You cool with Kenny Loggins
-[FORMM1]
-FormatMemCard 1 (teststuff)
+[COK2_19]
+Hell, I love this record
-[UNFRM1]
-UnFormatMemCard 1 (teststuff)
+[COK2_26]
+~r~You killed Lance!
-[GORLEV]
-Gore Level
+[COK3_1]
+Don't shoot, dude!
-[SICASS]
-Sick Fuck
+[COK3_2]
+What's in this stuff?
-[SICSIC]
-Sick Fucker
+[COK3_3]
+He's taking the boat. Bummer.
-[SCASSL]
-Sick Fuck Selected
+[COK3_4]
+Help! Some square's stealing the boat, man!
-[SCSCSL]
-Sick Fucker Selected
+[COK4_W]
+Uugghh! That's the last of them.
-[PRVMEN]
-Previous Mission Briefs
+[COK4_X]
+I'm going to start her up.
-[FORMEN]
-Format Menu
+[COK4_Y]
+I think we've got some new friends.
-[MEMTST]
-MemoryCardTest screen
+[COK4_2]
+Yeah.
-[REGCAR]
-Register MemoryCard One
+[COK4_6]
+Do you know where we're going?
-[TEFONE]
-Test Format MemCard One
+[COK4_7]
+Are we lost?
-[TEUFON]
-Test UnFormat MemCard One
+[COK4_8]
+We got some competition!
-[CRROOT]
-CreateRootDir
+[COK4_9]
+Take 'em out!
-[CRLDIC]
-Create and Load Icons
+[COK4_9A]
+It's time for the Lance Vance Dance!
-[FLFSGF]
-Fill First File With Guff
+[COK4_10]
+They're matchwood! And fish food.
-[PUSAVE]
-Save Only the game
+[COK4_11]
+We made it! Those other boats ain't VIP class.
-[CHEVOK]
-CheckEveryOkB4Save
+[COK4_17]
+They're getting desperate!
-[SVGMON]
-SaveTheGame
+[COK4_18]
+My damn feet are wet! WE'RE TAKING ON WATER!
-[CNTSAV]
-Can't save the game. On a mission.
+[COK4_21]
+Bridge coming up!
-[CNCSAV]
-Can't save the game. You're in a car
+[COK4_22]
+Bail out, she's about to blow!
-[CRMGSV]
-Create copy protected magazine directory
+[COK4_23]
+Good shooting.
-[MGSVCN]
-MagazineDirectory Created
+[COK4_29]
+~r~You killed Lance!
-[MGSVNC]
-MagazineDirectory Not Created
+[ASS1_6]
+Go on Tommy, I'll be ok!
-[YES]
-Yes
+[ASS1_7]
+Eat this, you murdering bastards!!
-[NO]
-No
+[ASS1_8]
+I'm pinned down!
-[X]
-x
+[ASS1_9]
+I got you covered Tommy!
-[LAST]
-Last message.
+[ASS1_10]
+Hey, this is a real nice herbaceous border
-[FEDS_XB]
-Select
+[ASS1_11]
+Hey Tommy, can my room have a view of the bay?
-[FEDS_ST]
-START button - RESUME
+[ASS1_12]
+Beautiful high ceilings in here...
-[FEST_OO]
-out of
+[ASS1_3]
+Lance! I need cover!
-[FEC_TUC]
-Turret control
+[ASS1_4]
+Diaz must be inside!
-[FEC_SM3]
-Special mission trigger (R3 button)
+[ASS1_5]
+Lance!
-[FEC_RS3]
-Radio station cycle (L3 button)
+[TAXWAR]
+TAXI WAR MISSIONS
-[FEC_HO3]
-Horn (L3 button)
+[NOTAXI]
+~g~You need a Kaufman Cab to activate this mission.
-[DIAB1]
-'TURISMO'
+[TAXW1_5]
+~g~You need to be in a Kaufman cab!
-[DIAB2]
-'I SCREAM, YOU SCREAM'
+[TAX2_4]
+Go on, Tommy.
-[DIAB3]
-'TRIAL BY FIRE'
+[TAX2_5]
+Beat the hell out of him.
-[DIAB4]
-'BIG'N'VEINY'
+[TAX2_6]
+He hasn't even got a license.
-[DIAB1_A]
-El Burro wants to offer you an opportunity. Get to the payphone in Hepburn Heights if you want more info.
+[TAX2_7]
+Damn limo services.
-[DIAB1_C]
-You drive a mean race. Drop by the payphone again and 'El Burro' may have some work for you.
+[TAXW3_1]
+~g~Go and pick up Mercedes.
-[DIAB1_1]
+[RACE1]
~g~3..2..1.. GO GO GO!
-[DIAB1_4]
-~g~Get a fast car and get to the starting grid.
+[RACE2]
+~g~3
+
+[RACE3]
+~g~2
-[DIAB1_3]
-~r~You couldn't win a raffle, LOSER!
+[RACE4]
+~g~1
-[DIAB1_2]
-~g~Congratulations you won, with an incredible time of ~1~ seconds.
+[RACE5]
+~g~GO!
[FIRST]
-~g~1st
+~b~1st
[SECOND]
-~g~2nd
+~b~2nd
[THIRD]
-~g~3rd
+~b~3rd
[FOURTH]
-~g~4th
-
-[DIAB2_1]
-~g~Pick up the briefcase in Harwood.
-
-[DIAB2_2]
-~g~Find an icecream van.
-
-[DIAB2_3]
-~g~Park the icecream van down at Atlantic Quays.
-
-[DIAB2_4]
-~g~Press the ~w~~k~~VEHICLE_HORN~ button ~g~to activate the Icecream jingle.
-
-[DIAB2_6]
-~g~Press the ~w~~k~~VEHICLE_HORN~ button ~g~to activate the Icecream jingle.
-
-[DIAB2_7]
-~g~Press the ~w~~k~~VEHICLE_HORN~ button ~g~to activate the Icecream jingle.
-
-[DIAB2_5]
-~g~Exit the van then use the remote to detonate the Icecream van.
-
-[YD1]
-'BLING-BLING SCRAMBLE'
-
-[YD2]
-'UZI RIDER'
-
-[YD3]
-'GANGCAR ROUND-UP'
+~b~4th
-[YD4]
-'KINGDOM COME'
+[RACETM]
+~b~RACE TIME: ~1~:~1~
-[YD_P]
-King Courtney would like a word. Get to the payphone in Aspatria!!
+[RACETM2]
+~b~RACE TIME: ~1~:0~1~
-[YD1_A]
-~w~This is King Courtney.
+[RACEFA]
+~r~You failed to win the race!
-[YD1_A1]
-~w~My Yardie posse could do with a driver and you've got a reputation for hot moves.
+[TEX1_5]
+~r~He got away!
-[YD1_B]
-~w~Get to the waste ground opposite the stadium in a car and wait for the other hopefuls.
+[SEG3_2]
+~g~Get to the van that contains the RC Raider and remote timed bombs.
-[YD1_C]
-~w~I've got men watching checkpoints all over Staunton.
+[SEG3_3]
+~g~You must use the RC RAIDER to transport 4 bombs to 4 target zones on the building site.
-[YD1_D]
-~w~First driver to a checkpoint gets a Grand, then it's on to the next stop.
+[SERG3_5]
+~g~You can only carry one bomb at a time and cannot pick up successfully planted bombs.
-[YD1_D1]
-~w~If you get more checkpoints than any other driver, I could have some work for you.
+[SEG3_7]
+~g~Once you have dropped the FIRST bomb successfully in a target zone the detonation timer will start; you must then drop all the bombs within this time period.
-[YD1_E]
-~g~Prepare to race!
+[SEG3_8]
+~g~All 4 bombs must be located at the 4 target zones to pass the mission and demolish the building.
-[YD1_F]
-~g~You jumped the start -I like your style!!
+[SEG3_9]
+~g~You hit the target! 3 more to go.
-[YD1_G]
-~r~This is a CAR RACE. You need a CAR fool!
+[SEG3_10]
+~g~You hit the target! 2 more to go.
-[YD1GO]
-~g~GO!!
+[SEG3_11]
+~g~You hit the target! Just 1 more to go!
-[YD1_1]
-~r~1
+[SEG3_12]
+~r~You missed the target! Go get a bomb!
-[YD1_2]
-~r~2
+[SEG3_13]
+~g~Drop the bomb at a target zone.
-[YD1_3]
-~r~3
+[SEG3_14]
+~r~You ran out of time and failed to demolish the building.
-[YD1_BON]
-$1000!!
+[SEG3_15]
+~r~Your RC Raider has been destroyed! How you gonna transport the bombs now?
-[Y1_1ST]
-~g~You came first with ~1~ successful checkpoints!
+[AVERY]
+AVERY MISSIONS
-[Y1_2ND]
-~y~2nd with ~1~ successful checkpoints. ~y~Close, but you just ain't the best!
+[ASM]
+ASSASSIN MISSIONS
-[Y1_3RD]
-~r~3rd with ~1~ successful checkpoints. ~r~I thought you said you were good!
+[ASM_1]
+ASSASSIN MISSION 1
-[Y1_LAST]
-~r~You were last! ~r~You wasted my time FOOL!
+[ASM1_1]
+~g~Mr. Teal, your help in eradicating those out-of-towners was invaluable to business. I have more work for you with a more 'hands-on' approach. Your next job is taped under the phone.
-[Y1_J1ST]
-~y~Joint 1st with ~1~ successful checkpoints. ~y~Good, but you gotta be the best to drive for Queen Lizzy!
+[ASM1_2]
+~g~Get to the payphone outside the Mall in Washington.
-[Y1_J2ND]
-~r~Joint 2nd with ~1~ successful checkpoints. You drive like a crazed monkey!
+[ASM1_3]
+~g~Carl Pearson, Pizza Delivery Man. He must not complete his deliveries.
-[Y1JLAST]
-~r~Joint last! You talk like a driver, but you drive like a talker!
+[ASM1_4]
+~g~Kill the Pizza Delivery Man before he completes his deliveries.
-[Y1_TEST]
-CAR IN WATER!!
+[ASM_2]
+ASSASSIN MISSION 2
-[YD2_A]
-~w~I need to see if you're capable of doing my dirty work.
+[ASM_3]
+ASSASSIN MISSION 3
-[YD2_A1]
-~w~See if you can be trusted.
-
-[YD2_B]
-~w~Two of my boys will be there any second to take you for a ride,
+[ASM3_A]
+TEXT NO LONGER NEEDED
-[YD2_B1]
-~w~see if you are who you say you are.
+[ASM3_B]
+TEXT NO LONGER NEEDED
-[YD2_C]
-~w~We're going for a little ride into Hepburn Heights, whack us some filthy Diablos been dissing Queen Lizzy.
+[ASM3_1]
+~g~Go and get the weapon Mr. Black has left for you.
-[YD2_CC]
-~w~Here, you'll need a 'piece'.
+[ASM3_2]
+~g~Don't get too close to the target or he may spot you!
-[YD2_D]
-~w~You do the driving and shooting. We'll make sure you don't get cold feet.
+[ASM3_3]
+~g~For a quick safe kill find a secluded spot nearby with a clear view of your target.
-[YD2_E]
-~w~Let's drive!!
+[ASM3_4]
+~g~He's seen you! Better waste him any way you can!
-[YD2_F]
-~r~He's bailed out on us, cap his yellow ass!!!
+[ASM3_5]
+~g~Marcus Hammond is working on an advertising board in Washington.
-[YD2_G1]
-~w~Hepburn Heights..Let's kill me some filthy Diablos...
+[ASM3_6]
+~g~Franco Carter is working for DBP Security off Ocean Drive.
-[YD2_G2]
-~w~But remember, ~r~You don't leave this car!!
+[ASM3_7]
+~g~Dick Tanner is situated near the Jewelry shop in Vice Point.
-[YD2_H]
-~w~OK, Get us back to Yardie turf! GO GO GO!!
+[ASM3_8]
+~g~Nick Kong is situated near Washington Beach.
-[YD2_L]
-~w~You did good, Reaperman!
+[ASM3_9]
+~g~Stuntman Driver is situated in Washington.
-[YD2_M]
-~r~He's wrecked my car! Waste him!
+[ASM3_10]
+~r~You failed to kill them all.
-[YD2_N]
-~w~Get your ass back in this car!
+[ASM_4]
+ASSASSIN MISSION 4
-[YD3_A]
-I want you to boost some gang cars
+[ASM4_1]
+~g~Go get the rifle left for you in the foliage outside the airport terminal.
-[YD3_A1]
-so we can do hits on our enemies' turf.
+[ASM4_2]
+~g~Don't miss your target or you may alert his bodyguards, and remember keep your distance so he does not spot you.
-[YD3_B]
-I need a Mafia Sentinel,
+[ASM4_3]
+~g~Watch the woman on the balcony above the check-in desks inside the airport terminal. DO NOT KILL HER.
-[YD3_B1]
-a Yakuza Stinger and a
+[ASM4_4]
+~g~Kill the man she hands the briefcase to but only AFTER HE PICKS IT UP. Then retrieve the briefcase and take it to Ammu-Nation in Downtown.
-[YD3_B2]
-Diablo Stallion so we can hit any gang in Liberty.
+[ASM4_5]
+~g~Get the briefcase!
-[YD3_C]
-Drop them off at the garage in Newport and remember,
+[ASM4_6]
+~g~Take the briefcase to Ammu-Nation in Downtown.
-[YD3_C1]
-they're no use to us wrecked!!
+[ASM4_7]
+~r~You killed the woman, you fool!
-[YD3_D]
-Spare text label
+[ASM4_8]
+~r~The target heard you firing your weapon! The deal is off!
-[YD3_E]
-~r~You've already boosted a diablo gangcar!
+[ASM4_9]
+~r~The target has boarded his flight!
-[YD3_F]
-~r~You've already boosted a Mafia gangcar!
+[ASM4_11]
+~r~The target has seen you! The deal is off!
-[YD3_G]
-~r~You've already boosted a Yakuza gangcar!
+[ASM4_13]
+~g~He's spotted you and is making a run for it, nail him and get the briefcase!
-[YD3_H]
-~g~Diablo gangcar boosted!
+[ASM4_14]
+~g~The distance bar in the upper right of the screen gives you an indication to how close you are to your target do not let it fill or he will see you.
-[YD3_I]
-~g~Mafia gangcar boosted!
+[ASM_5]
+ASSASSIN MISSION 5
-[YD3_J]
-~g~Yakuza gangcar boosted!
+[KICK]
+KICKSTART
-[YD3_K]
-~r~The car's nearly wrecked! Get it repaired!
+[KICK1_3]
+~g~Number of times foot put down: ~1~
-[YD3_L]
-~g~Take it to the ~p~garage!
+[KICK1_4]
+~g~Time penalty: ~1~ seconds
-[YD3_M]
-~r~You've flipped it! Get another one!
+[BANK]
+BANKJOB MISSIONS
-[YD4_A]
-Listen up!
+[BANK1]
+BANKJOB MISSION 1
-[YD4_A1]
-Get over to Bedford Point.
+[BANK2]
+BANKJOB MISSION 2
-[YD4_A2]
-There's a stash in an old car I need pronto!
+[BJM2_21]
+~g~Hit as many targets as you can while your ammo lasts.
-[YD4_B]
-LETTER: I hear you've been a busy boy. Well I've been a busy girl.
+[BANK3]
+BANKJOB MISSION 3
-[YD4_C]
-I think it's time you witnessed the real power of 'SPANK'! Besos y fuderes, Catalina, xxx.
+[BJM3_1]
+~g~Get a fast car and get to the starting grid.
-[YD4_D]
-PS: DIE PEEG DOG, DIE!!
+[BNK4_2A]
+Boys at the car lot did a great job on this baby.
-[YD4_1]
-~g~SPANKED-up madmen!
+[BNK4_3G]
+Oh crap, now the cops are onto us!
-[YD4_2]
-~g~Destroy the madmens' vans!!
+[BNK4_3H]
+- and we're not even there yet.
-[HM_1]
-'UZI MONEY'
+[BNK4_3K]
+We'll have to lose the cops first...
-[HM_2]
-'TOYMINATOR'
+[BNK4_3L]
+Christ Tommy, you trying to kill us all!?
-[HM_3]
-'RIGGED TO BLOW'
+[BNK4_3N]
+Everything I care about gets trashed!
-[HM_5]
-'RUMBLE'
+[BNK4_26]
+Hot damn! Here they come!
-[HOOD1_A]
-Get to the payphone in Wichita Gardens and we'll talk business.
+[BNK4_32]
+Use explosives to open the deposit boxes!
-[HM1_A]
-Yo! This is D-Ice of the Red Jacks!
+[BNK4_36]
+Where's Cam?
-[HM1_C]
-These young punks, they come onto the streets and they got nothing but guns and SPANK on their minds.
+[BNK4_37]
+History...
-[HM1_3]
-~g~The 'Nines' walk their turf in Wichita Gardens.
+[BNK4_38]
+That's the last of them. GO! GO! GO!
-[HM2_3]
-If you hit a vehicle's wheels the RC buggy will detonate!
+[BNK_39]
+Shit! Where's Hilary?
-[HM2_4]
-If it goes out of range the RC buggy will detonate!
+[BK4_40A]
+I'll give him abandonment issues!
-[HM2_5]
-~r~Out of range!
+[BNK4_42]
+Hey guys! Get in! I got you covered!
-[HM3_1]
-~g~Get to the garage but watch out if the car takes too much damage it will blow!
+[BNK4_43]
+I've got our asses covered, DRIVE!
-[HM3_2]
-~g~Take the car back it has to be in perfect condition - no damage!
+[BNK4_44]
+We made it! We're rich! RICH!
-[HM3_3]
-~g~Get the car repaired!
+[BNK4_45]
+Shame Cam didn't make it, he was a good guy!
-[HM4_D]
-~g~Get a vehicle!
+[BNK4_46]
+Yeah. Still... more for us!
-[HM4_E]
-TEXT NO LONGER REQUIRED
+[BNK4_47]
+Damned straight! YEEEEHAAAH!
-[HM4_1]
-~g~Head to the location where the cargo is scattered, you need to collect 30 pieces of bullion.
+[BNK4_48]
+Tommy, would you like a massage?
-[HM4_2]
-~g~Remember when the vehicle becomes too heavy and slow goto the garage and drop off the cargo.
+[BNK4_49]
+Well, Hi there, Mercedes! Yeah, I'm a little tense...
-[HM5_3]
-~r~You were told to use a baseball bat only!
+[BNK450A]
+What'd I tell you Tommy? What'd I tell you? Bent SWAT better watch out when Kent Paul is in town.
-[HM5_4]
-~r~Your contact's dead!
+[BNK450B]
+Come on, gimme a bigger slice, mate, c'mon. I gotta get some new threads.
-[MEA1]
-'THE CROOK'
+[BNK4_51]
+You look fine to me.
-[MEA2]
-'THE THIEVES'
+[KENT]
+KENT PAULS MISSIONS
-[MEA3]
-'THE WIFE'
+[KENT1]
+KENT PAUL MISSION1
-[MEA4]
-'HER LOVER'
+[COUNT]
+COUNTERFEITING MISSIONS
-[MEAT1_A]
-A friend said you could fix some problems I got. Get to the payphone in Trenton if you think you can help.
+[COUNT1]
+COUNTERFEITING MISSION 1
-[MEA1_B3]
-~g~Go and meet the Bank Manager.
+[COUNT2]
+COUNTERFEITING MISSION 2
-[MEA1_B6]
-~g~Take the car to the crusher to get rid of evidence, get out of the car and the crane will pick it up.
+[BIKE]
+THE BIKER GANG MISSIONS
-[MEA1_1]
-~r~The Bank Manager's dead!
+[BIKE1]
+BIKER MISSION 1
-[MEA1_2]
-~r~You were told to crush the vehicle!
+[BIKE2]
+BIKER MISSION 2
-[MEA1_3]
-~g~Get out of the car!
+[BIKE3]
+BIKER MISSION 3
-[MEA1_4]
-~r~You have left the Bank Manager behind!
+[GOAWAY1]
+~g~Come back when you have finished the Haitian gang missions.
-[MEA2_B3]
-~g~Go and meet the thieves.
+[HAIT]
+THE HAITIAN GANG MISSIONS
-[MEA2_B4]
-~g~Take them to the Bitch'n' Dog Food Factory
+[HAIT1]
+HAITIAN MISSION 1
-[MEA2_B6]
-~g~Get the car resprayed to get rid of any evidence.
+[HAIT2]
+HAITIAN MISSION 2
-[MEA2_1]
-~r~You were told to crush the vehicle!
+[HAIT3]
+HAITIAN MISSION 3
-[MEA2_2]
-~r~A thief's dead!
+[HAM3_6]
+~g~Use the sniper rifle I have left to accomplish your task.
-[MEA2_4]
-~r~You have left a thief behind!
+[ROCK]
+THE ROCKBAND GANG MISSIONS
-[MEA3_B3]
-~g~Go and collect Mrs. Chonks
+[ROK1_4]
+~g~Ok, I think this is what you were after...
-[MEA3_B6]
-~g~Take the car and dump it into the sea, this will get rid of any evidence.
+[ROK1_1E]
+~g~It'll cost more than you've got!
-[MEA3_1]
-~r~The wife's dead!
+[ROK1_1F]
+~g~Come back when you got the money.
-[MEA3_2]
-~r~You were supposed to dump the vehicle in the water!
+[RBM2_6]
+~g~Wow! She's a bloke, stop him!
-[MEA3_3]
-~r~You have left his wife behind!
+[ROCK3]
+ROCKBAND MISSION 3
-[MEA4_B3]
-~g~Pick up his wife's lover
+[RBM3_5]
+~g~Take Love Fist to the venue.
-[MEA4_B6]
-It's far too late for that Marty. You had your chance, but now I'm taking over the business...
+[CUBANM]
+THE CUBAN GANG MISSIONS
-[MEA4_1]
-~r~Carlos is dead!
+[CUBAN1]
+CUBAN MISSION 1
-[MEA4_3]
-~r~You have left Carlos the loan shark behind!
+[CUBAN2]
+CUBAN MISSION 2
-[LOOK_A]
-Press and hold the ~h~~k~~VEHICLE_LOOKLEFT~ button ~w~or the ~h~~k~~VEHICLE_LOOKRIGHT~ button~w~ to look ~h~left~w~ or ~h~right~w~ while in a vehicle. Press both to look ~h~behind~w~.
+[CUB2_10]
+~r~You are supposed to be killing Haitians, not Cubans.
-[LOVE6_1]
-~g~Now lead the cops away from the warehouse!
+[CUBAN3]
+CUBAN MISSION 3
-[LOVE6_2]
-~r~You failed to lead the police far enough away!
+[CUBAN4]
+CUBAN MISSION 4
-[RM4_3]
-~r~Ray's partner has escaped!
+[PROT]
+PROTECTION MISSIONS
-[RM6_C]
-The CIA seem to have a vested interest in SPANK
+[PORN]
+PORN MISSIONS
-[RM6_C1]
-and they don't like us screwing with the Cartel.
+[PORN1]
+PORN MISSION 1
-[C_PASS]
-THREAT ELIMINATED!
+[POR1_03]
+~r~Candy is dead!
-[CTUTOR]
-Press the ~h~~k~~TOGGLE_SUBMISSIONS~ button~w~ to toggle Vigilante missions on or off.
-
-[CTUTOR2]
-Press the ~h~~k~~TOGGLE_SUBMISSIONS~ button~w~ to toggle Vigilante missions on or off.
+[PORN2]
+PORN MISSION 2
-[COPCART]
-~g~You have ~1~ seconds to return to a police vehicle before the mission ends.
-
-[C_FAIL]
-Vigilante mission ended!
-
-[C_CANC]
-~r~Vigilante mission cancelled!
-
-[C_ESCP]
-~r~The suspect has escaped!
+[PORN3]
+PORN MISSION 3
-[C_TIME]
-~r~Your time as a law enforcer is over!
+[PORN4]
+PORN MISSION 4
-[C_VIGIL]
-VIGILANTE BONUS!!
+[PHIL]
+PHIL MISSIONS
-[A_FAIL2]
-~r~Your lack of urgency has been fatal to the patient!
+[PHIL1]
+PHIL MISSION 1
-[A_FAIL3]
-~r~The patient is dead!!
+[PHIL2]
+PHIL MISSION 2
-[A_PASS]
-Rescued!
+[PIZ1_A]
+PIZZA BOY MISSION
-[F_FAIL2]
-~r~You're too late!
+[CNTBUY1]
+Printworks purchased: $~1~
-[A_COMP2]
-You will never get tired!
+[CARBUY]
+Car Showroom purchased: $~1~
-[RM2_M]
-If you need any firepower just drop by and take what you need from the lockers.
+[PORNBUY]
+Film Studio purchased: $~1~
-[HEAL_A]
-Your ~h~health~w~ is displayed in orange in the top right of the screen.
+[ICEBUY]
+Ice Cream Factory purchased: $~1~
-[YD1_CNT]
-~1~ of 15!
+[TAXIBUY]
+Taxi Firm purchased: $~1~
-[FM1_9]
-~g~Thats the party up ahead, drop Maria off out front.
+[BANKBUY]
+The Malibu purchased: $~1~
-[FM1_Y]
-~w~You know I enjoyed myself for the first time in a long while, and you treated me really good. With respect and everything.
+[BOATBUY]
+Boatyard purchased: $~1~
-[FM1_AA]
-~w~Oh, I'd better go. I'll see you around I hope.
+[PRNT_NO]
+You cannot buy the Print Works at this time, come back later.
-[NOCONTE]
-Please re-insert the analog controller (DUALSHOCK@) or analog controller (DUALSHOCK@2) in controller port 1 to continue
+[CAR_NO]
+You cannot buy the Car Showroom at this time, come back later.
-[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).
+[PORN_NO]
+You cannot buy the Film Studio at this time, come back later.
-[WRCONTE]
-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).
+[ICE_NO]
+You cannot buy the Ice Cream Factory at this time, come back later.
-[WRONGCD]
-Incorrect disc. Please insert correct disc.
+[TAXI_NO]
+You cannot buy the Taxi Company at this time, come back later.
-[NOCD]
-The disc tray is empty. Please insert disc.
+[BANK_NO]
+You cannot buy The Malibu at this time, come back later.
-[OPENCD]
-The disc tray is open. Please close the disc tray.
+[BOAT_NO]
+You cannot buy the Boatyard at this time, come back later.
-[CDERROR]
-Error reading the Grand Theft Auto III DVD
+[COL2_6]
+Freeze, imperialist American pig!
-[RESTART]
-Starting new game
+[COL2_6B]
+Zat iz propertay of ze government Francais.
-[GA_3]
-No more freebies. $1000 to respray!
+[COL2_6C]
+'And eet over!
-[GA_1]
-Whoa! I don't touch nothing THAT hot!
+[COL3_A]
+Thomas I appreciate you coming
-[GA_1A]
-Come back when you're not so busy...
+[COL3_B]
+Forgive me for getting straight to business,
-[S_PROM2]
-The garage next door can store one vehicle when you save your game.
+[COL3_C]
+Diaz has asked me to oversee a minor business transaction.
-[STOCK]
-out of stock
+[COL3_D]
+Let's hope it goes better than last time.
-[FM1_O]
-~w~He's at the rail station at the Chinatown waterfront I think.
+[COL3_E]
+Which is why I thought of you, my friend.
-[EBAL_B]
-This is the place right here, let's get off the street and find a change of clothes!
+[COL3_F]
+I've dropped some protection at the multistory carpark.
-[EBAL_G]
-This is Luigi's club. Let's go round the back and use the service door.
+[COL3_G]
+Pick it up then go and watch over Diaz's men at the drop off.
-[AM4_3]
-You must be Asuka's new errand boy!
+[COL4_2]
+Don't know Sir!
-[AM4_4]
-You got the money? Is it all here?
+[COL4_5]
+Sir, Yes Sir!
-[AM4_5]
-I know what you're thinking, another bent cop.
+[COL4_10]
+Lets go eat some doughnuts.
-[AM4_6]
-Well, it's a bent world.
+[COL4_16]
+Sir! Moving vehicle Sir!
-[AM4_7]
-Just 'cause I lost a few partners, those suckers from internal affairs have started sniffing around.
+[COL4_25]
+Vehicle self destruct initiated!
-[AM4_8]
-Reckon they can smell me.
+[COL5_6]
+Mercedes, that girl will be the death of me.
-[AM4_9]
-Well, this city is just one big open sewer.
+[COL5_8]
+Damn cockroach!
-[AM4_10]
-But I'm gonna need some non-union help.
+[COL5_5]
+Die French peegs!
-[AM4_11]
-And if you're interested you'll know where to find me.
+[CNT2_1]
+Kill him.
-[CAM_A]
-Press the ~h~~k~~CAMERA_CHANGE_VIEW_ALL_SITUATIONS~ button~w~ to change ~h~camera ~w~modes when on foot or in a vehicle.
+[CNT2_2]
+Get the Plates!
-[CAM_B]
-Press the ~h~directional button up~w~ and ~h~down~w~ to change ~h~camera ~w~modes when on foot or in a vehicle.
+[CNT2_3]
+Protect the courier!
-[KM2_1]
-~g~Repair the car, it's gotta be mint.
+[FINKILL]
+Ok boys, kill him!
-[LM3_6]
-Joey...
+[FIN_1A]
+Come here you double-crossing piece of shit!
-[LM3_6A]
-Am I goin' to play with your big end again?
+[FIN_1B]
+You're going down, you back stabbing prick!
-[LM3_9A]
-there might be some work for you.
+[FIN_1C]
+This is the last dance for lance vance!
-[LM3_9B]
-Alright?
+[FIN_2B]
+Oh you think so!
-[AWAY2]
-~r~They got away.
+[FIN_2C]
+I said I had enough of that at school!
-[AWAY]
-~r~He's clean out of here!
+[FIN_3]
+No one to cover your ass now, eh Tommy?
-[JM6_1]
-Get to the bank on the main drag.
+[FIN_4]
+You're history, Tommy, history
-[GA_6B] { re3 change }
-Park it, prime it by pressing the ~h~~k~~VEHICLE_FIREWEAPON~ button~w~ and LEG IT!
+[FIN_5]
+You picked the wrong side, Lance...
-[GA_7B] { re3 change }
-Arm with ~h~~k~~VEHICLE_FIREWEAPON~ button~w~. Bomb will go off when engine is started.
+[FIN_6]
+Sonny's up with the safe and MY money...
-[BAT1]
-~g~Pick up the bat!
+[FIN_10]
+Sonny? SONNY! I'm coming for ya!
-[EBAL_O]
-If you don't mess this up, maybe there be more work for you. Now get outta here!
+[FIN_11A]
+You took fifteen years from me Sonny...
-[HELP9_B]
-Press the~h~ ~k~~PED_FIREWEAPON~ button ~w~to ~h~fire~w~ the sniper rifle.
+[FIN_11B]
+And now I'm gonna make you pay!
-[HELP9_C]
-Press the~h~ ~k~~PED_FIREWEAPON~ button ~w~to ~h~fire~w~ the sniper rifle.
+[FIN_12A]
+You still don't get it do you!
-[JM6_8]
-~r~You've lost all the robbers!
+[FIN_12B]
+I OWN you, Tommy.
-[COLT_IN]
-The Pistol is now in stock at Ammunation!
+[FIN_12C]
+Those fifteen years were mine to spend!
-[TAXI2]
-~r~You're out of time!
+[FIN_13]
+Get him boys, he never understood a thing.
-[TAXI3]
-~r~Your passenger fled in terror!
+[RACES_4]
+3
-[TAXI7]
-~r~Your car is trashed, get it repaired.
+[RACES_5]
+2
-[TAXI4]
-Fare complete!
+[RACES_6]
+1
-[TAXI5]
-SPEED BONUS!!
+[RACES_7]
+GO!
-[TAXI6]
-Taxi mission over
+[RACES_9]
+Time: ~1~:~1~
-[FRANGO]
-~g~Salvatore wants you to help Toni deal with the Triads first!
+[RACES]
+TIME:
-[PAGEB12]
-Police Bribe delivered to hideout
+[RACES17]
+New best time: ~1~:~1~
-[PAGEB13]
-Health delivered to hideout
+[RACES18]
+YOU HAVE WON: $~1~
-[PAGEB14]
-Adrenaline delivered to hideout
+[RACES20]
+New best time: ~1~:0~1~
-[KM1_4]
-~g~You need a cop car to do the job!
+[RACES21]
+Time: ~1~:0~1~
-[CAT1_B]
-bring $500,000 to the Villa at Cedar Grove.
+[RCH1_1]
+NO LONGER NEEDED NO LONGER NEEDED NO LONGER NEEDED NO LONGER NEEDED NO LONGER NEEDED
-[JM2_C]
-He's got a noodle stand down in China Town.
+[RCH1_2]
+~g~The CHECKPOINTS are scattered throughout the airport.
-[RM6_1]
-Here's a key to a lock-up.
+[RCH1_3]
+NO LONGER NEEDED NO LONGER NEEDED NO LONGER NEEDED NO LONGER NEEDED NO LONGER NEEDED
-[RM6_2]
-You'll find some cash and some 'supplies' I'd stashed in case things got tight.
+[RCH1_5]
+Time:
-[RM6_3]
-See y'around.
+[RCRC1_2]
+~g~Get to the starting grid now!
-[FE_INIP]
-Initialising and loading Pause Menu... Please wait.
+[RCRC1_4]
+~g~3
-[FESZ_CA]
-Cancel
+[RCRC1_5]
+~g~2
-[FESZ_QU]
-Quit
+[RCRC1_6]
+~g~1
-[FESZ_L1]
-Game saved successfully!
+[RCRC1_7]
+~g~GO!
-[FESZ_L2]
-Your saved filename is:
+[RCRC1_8]
+~g~Race time: ~1~ seconds
-[FESZ_OK]
-OK
+[RCPL1_1]
+~g~Compete in a CHECKPOINT RACE with 3 other RC Baron's
-[FES_LGA]
-Load Game
+[RCPL1_2]
+~g~You must go through the ~o~CENTRE CORONA ~g~to successfully pass a checkpoint.
-[FES_NGA]
-New Game
+[RCPL1_3]
+~g~Get to the starting grid now!
-[FES_CAN]
-Cancel
+[ICC1_O]
+What is wrong with you??
-[FESZ_QL]
-All unsaved progress in your current game will be lost. Proceed with loading?
+[FEA_2SP]
+2 Speakers
-[FESZ_QD]
-Proceed with deleting this saved game?
+[FEA_4SP]
+More than 2 speakers
-[FESZ_QO]
-Proceed with overwriting this saved game?
+[FEA_EAR]
+Headphones
-[FESZ_QR]
-Are you sure you want to start a new game? All progress since the last save game will be lost. Proceed?
+[FEA_NAH]
+NO AUDIO HARDWARE
-[FESZ_QS]
-PROCEED WITH SAVE ?
+[FET_APP]
+APPLY
-[T4X4_1]
-'PATRIOT PLAYGROUND'
+[FES_SKN]
+SKIN NAME
-[T4X4_2]
-'A RIDE IN THE PARK'
+[FES_DAT]
+DATE
-[T4X4_3]
-'GRIPPED!'
+[FES_SET]
+Use Skin
-[MM_1]
-'MULTISTOREY MAYHEM'
+[FET_DEF]
+Restore Defaults
-[T4X4_1A]
-~g~You have ~y~5 minutes~g~ to collect ~y~15~g~ checkpoints. ~g~You may collect them in ~y~ANY ORDER.
+[FESZ_QZ]
+Are you sure you want to save this game?
-[T4X4_1B]
-~1~ of 15!
+[FES_SCG]
+Save the current game?
-[T4X4_1C]
-~y~PASS THROUGH~g~ the first checkpoint to start the timer. ~g~Each checkpoint will credit you with ~y~20 SECONDS~g~.
+[FES_LCG]
+Load the game and continue playing?
-[T4X4_2A]
-~g~You have ~y~2 minutes~g~ to collect ~y~12~g~ checkpoints!! ~g~You may collect them in ~y~ANY ORDER.
+[FEC_FIR]
+Fire
-[T4X4_2B]
-~1~ of 12!
+[FEC_NWE]
+Next weapon
-[T4X4_2C]
-~y~PASS THROUGH~g~ the first checkpoint to start the timer. ~g~Each checkpoint will credit you with ~y~10 SECONDS~g~.
+[FEC_PWE]
+Previous weapon
-[T4X4_3A]
-~g~You have ~y~5 minutes~g~ to collect ~y~20~g~ checkpoints. ~g~You may collect them in ~y~ANY ORDER.
+[FEC_FOR]
+Forward
-[T4X4_3B]
-~y~PASS THROUGH~g~ the first checkpoint to start the timer. ~g~Each checkpoint will credit you with ~y~15 SECONDS~g~.
+[FEC_BAC]
+Backwards
-[T4X4_3C]
-~1~ of 20!
+[FEC_LEF]
+Left
-[T4X4_F]
-~r~You bailed! Too tough for you?!
+[FEC_RIG]
+Right
-[MM_1_A]
-~g~You have ~y~2 minutes~g~ to collect ~y~20 checkpoints~g~ in the multistorey! ~g~You may collect them in ~y~ANY ORDER.
+[FEC_ZIN]
+Zoom in
-[MM_1_B]
-~1~ of 20!
+[FEC_ZOT]
+Zoom out
-[MM_1_C]
-~g~That's 20 seconds, plus ~y~5 SECONDS~g~ for each checkpoint. ~g~The timer will start ~y~IMMEDIATELY.
+[FEC_EEX]
+Enter+exit
-[FM2_14]
-~r~You got too close and spooked Curly!
+[FEC_RAD]
+Radio
-[FM2_15]
-~g~Don't get too close or Curly will suspect something!
+[FEC_SUB]
+Sub-mission
-[UPSIDE]
-~r~You flipped your wheels!
+[FEC_CMR]
+Change camera
-[FM2_16]
-SPOOKOMETER:
+[FEC_JMP]
+Jump
-[LM3_11]
-~g~Misty won't ride in a bus get another vehicle!
+[FEC_SPN]
+Sprint
-[LANDSTK]
-Landstalker
+[FEC_HND]
+Handbrake
-[IDAHO]
-Idaho
+[FEC_LOL]
+Look left
-[STINGER]
-Stinger
+[FEC_LOR]
+Look right
-[LINERUN]
-Linerunner
+[FEC_NTR]
+Next target
-[PEREN]
-Perennial
+[FEC_PTT]
+Previous target
-[SENTINL]
-Sentinel
+[FEC_LBA]
+Look behind
-[PATRIOT]
-Patriot
+[FEC_CEN]
+Center camera
-[FIRETRK]
-Firetruck
+[FET_CFT]
+ON FOOT
-[TRASHM]
-Trashmaster
+[FET_CCR]
+IN CAR
-[STRETCH]
-Stretch
+[FET_CAC]
+ACTION
-[MANANA]
-Manana
+[FEC_IBT]
+-
-[INFERNS]
-Infernus
+[FEC_MXO]
+MXB1
-[BLISTA]
-Blista
+[FEC_MXT]
+MXB2
-[PONY]
-Pony
+[FEC_UNB]
+UNBOUND
-[MULE]
-Mule
+[FEC_TFL]
+Look left+Turret L
-[CHEETAH]
-Cheetah
+[FEC_TFR]
+Look right+Turret R
-[AMBULAN]
-Ambulance
+[FEC_MWF]
+MS WHEEL UP
-[FBICAR]
-Fbi Car
+[FEC_MWB]
+MS WHEEL DN
-[MOONBM]
-Moonbeam
+[FEC_ORR]
+or
-[ESPERAN]
-Esperanto
+[FEC_NUS]
+NOT USED
-[TAXI]
-Taxi
+[FEC_LUD]
+Look Up
-[KURUMA]
-Kuruma
+[FEC_LDU]
+Look Down
-[BOBCAT]
-Bobcat
+[FEC_CMP]
+COMBO: LOOK L+R
-[WHOOPEE]
-Mr Whoopee
+[LAW_1A]
+law_1a
-[BFINJC]
-BF Injection
+[LAW_1B]
+law_1b
-[POLICAR]
-Police
+[LAW_2A]
+law_2a
-[ENFORCR]
-Enforcer
+[LAW_2B]
+law_2b
-[SECURI]
-Securicar
+[FEH_STA]
+STATS
-[BANSHEE]
-Banshee
+[FEH_LOA]
+LOAD
-[PREDATR]
-Predator
+[FEH_CON]
+CONTROLS
-[BUS]
-Bus
+[FEH_AUD]
+AUDIO
-[RHINO]
-Rhino
+[FEH_LAN]
+LANGUAGE
-[BARRCKS]
-Barracks OL
+[FEH_SGA]
+START NEW GAME
-[TRAIN]
-Train
+[FEO_CON]
+Controller Setup
-[HELI]
-Helicopter
+[FEO_AUD]
+Audio Setup
-[DODO]
-Dodo
+[FEO_DIS]
+Display Setup
-[COACH]
-Coach
+[FEO_LAN]
+Language Setup
-[CABBIE]
-Cabbie
+[FEO_PLA]
+Player Setup
-[STALION]
-Stallion
+[FEA_OUT]
+Output
-[RUMPO]
-Rumpo
+[FEA_ST]
+Stereo
-[RCBANDT]
-RC Bandit
+[FEA_DTS]
+DTS
-[BELLYUP]
-Triad Fish Van
+[FEA_RSS]
+Radio station
-[MRWONGS]
-Mr Wongs
+[FEA_NON]
+RADIO OFF
-[MAFIACR]
-Mafia Sentinel
+[FEA_FM0]
+WILDSTYLE
-[YARDICR]
-Yardie Lobo
+[FEA_FM1]
+FLASH FM
-[YAKUZCR]
-Yakuza Stinger
+[FEA_FM2]
+KCHAT
-[DIABLCR]
-Diablo Stallion
+[FEA_FM3]
+FEVER 105
-[COLOMCR]
-Cartel Cruiser
+[FEA_FM4]
+VROCK
-[HOODSCR]
-Hoods Rumpo XL
+[FEA_FM5]
+VCPR
-[AEROPL]
-Aeroplane
+[FEA_FM7]
+EMOTION 98.3
-[SPEEDER]
-Speeder
+[FEA_FM8]
+WAVE 103
-[REEFER]
-Reefer
+[FED_BRI]
+Brightness
-[PANLANT]
-Panlantic
+[FED_TRA]
+Trails
-[FLATBED]
-Flatbed
+[FED_SUB]
+Subtitles
-[YANKEE]
-Yankee
+[FED_WIS]
+Wide Screen
-[BORGNIN]
-Borgnine
+[FED_POS]
+Screen Position
-[TOYZ]
-TOYZ
+[FEP_RES]
+Resume
-[FEST_DF]
-Dist. travelled on foot (miles)
+[FEP_STG]
+Start Game
-[FEST_DC]
-Dist. travelled by car (miles)
+[FEP_STA]
+Stats
-[FESTDFM]
-Distance travelled on foot (m)
+[FEP_BRI]
+Briefs
-[FESTDCM]
-Distance travelled by car (m)
+[FEP_OPT]
+Options
-[FEST_R1]
-Patriot Playground in secs
+[FEP_QUI]
+Quit Game
-[FEST_R2]
-A Ride In The Park in secs
+[FES_LOA]
+Load game
-[FEST_R3]
-Gripped! in secs
+[FES_DEL]
+Delete game
-[FEST_RM]
-Multistorey Mayhem in secs
+[FEC_CSU]
+Controller Setup
-[FEST_LS]
-People saved in an Ambulance
+[FEC_RED]
+Redefine Controls
-[FEST_CC]
-Criminals killed on Vigilante Mission
+[FEC_MOU]
+Mouse Settings
-[FEST_FE]
-Total fires extinguished
+[DISTGOL]
+Dist. traveled by golf cart (miles)
-[FEST_LF]
-Longest flight in Dodo
+[DISTGOM]
+Distance traveled by golf cart (m)
-[FEST_BD]
-Best time for bomb defusal
+[ST_FAVR]
+Favorite radio station
-[FEST_RP]
-Rampages passed
+[ST_WSTR]
+least favorite radio station
-[FEST_MP]
-Missions passed
+[ST_FAVV]
+Favorite vehicle
-[FEST_BB]
-Bling-bling Scramble:
+[ST_STAR]
+Total number of wanted stars attained
-[FEST_H0]
-Most checkpoints
+[ST_HEAD]
+Number of headshots
-[FEST_GC]
-Gang Cars Totalled:
+[ST_GANG]
+Least favorite gang
-[FEST_H1]
-Diablo destruction
+[ST_STGN]
+Total number of wanted stars evaded
-[FEST_H2]
-Mafia Massacre
+[TYREPOP]
+Tires popped with gunfire
-[FEST_H3]
-Casino Calamity
+[TYRESLA]
+Tires slashed with a blade
-[FEST_H4]
-Rumpo Wrecker
+[ST_BRK]
+Number of bloodring kills
-[USJI1]
-TEXT NO LONGER REQUIRED
+[ST_LTBR]
+Longest time in bloodring (secs)
-[USJI2]
-TEXT NO LONGER REQUIRED
+[ST_GNG1]
+Cubans
-[USJI3]
-TEXT NO LONGER REQUIRED
+[ST_GNG2]
+Haitians
-[USJ]
-UNIQUE STUNT BONUS!
+[ST_GNG3]
+Streetwannabe's
-[SPRAY]
-Drive your vehicle into the spray shop to lose your ~h~wanted level~w~, ~h~repair ~w~and ~h~respray ~w~your vehicle. Cost - ~h~$1000.
+[ST_GNG4]
+Diaz's gang
-[HM1_1]
-~g~Ice 20 Purple Nines in 2 minutes 30 seconds.
+[ST_GNG5]
+Security guards
-[KM1_8A] { re3 change }
-Press the~h~ ~k~~VEHICLE_FIREWEAPON~ button~w~ to ~h~activate the bomb,~w~ remember to get out of the way.
+[ST_GNG6]
+Biker gang
-[KM1_8D] { re3 change }
-Press the~h~ ~k~~VEHICLE_FIREWEAPON~ button~w~ to ~h~activate the bomb,~w~ remember to get out of the way.
+[ST_GNG7]
+Vercetti gang
-[KM1_12]
-~g~Get him to the dojo but get rid of the cops first!
+[ST_GNG8]
+Golfers
-[RATNG1]
-Pickpocket
+[FEA_FM6]
+ESPANTOSO
-[RATNG2]
-Bully
+[ST_ASSI]
+Assassination Contracts Completed
-[RATNG3]
-Thug
+[DISTBIK]
+Dist. traveled by bike (miles)
-[RATNG4]
-Hustler
+[DISTBIM]
+Distance traveled by bike (m)
-[RATNG5]
-Goon
+[HOTEL]
+Ocean View
-[RATNG6]
-Wheelman
+[KICK1_9]
+CHECKPOINTS:
-[RATNG7]
-Hired muscle
+[FIN_B6]
+You do not have enough money to start this mission.
-[RATNG8]
-Fixer
+[TEX3_9]
+~g~Pickup a bomb by maneuvering the RC helicopter next to it.
-[RATNG9]
-Associate
+[HELP22]
+Go to the green house blip on the radar.
-[RATNG10]
-Cleaner
+[FES_FMS]
+Format Successful. Select OK to continue.
-[RATNG11]
-Assassin
+[FES_SSC]
+Save Successful. Select OK to continue.
-[RATNG12]
-Right-hand man
+[FES_DSC]
+Delete Successful. Select OK to continue.
-[RATNG13]
-Executioner
+[FESZ_QC]
+Proceed with overwriting this corrupted save game?
-[RATNG14]
-Capo
+[FES_CHE]
+Warning! One or more cheats have been activated. This may affect your save game. It is recommended that you do not save this game.
-[RATNG15]
-Boss
+[FET_SG]
+SAVE GAME
-[1010]
-~r~Your vehicle is upside down
+[FEH_BRI]
+BRIEF
-[1011]
-~r~Your vehicle is upside down
+[FEH_DIS]
+DISPLAY
-[1012]
-~r~Your vehicle is upside down
+[FEH_MAP]
+MAP
-[1013]
-~r~Your vehicle is upside down
+[FEM_OK]
+OK
-[1014]
-~r~Your vehicle is upside down
+[FEC_CRO]
+Crouch
-[JM4_10]
-OK, Kid. Drive me to the laundry in Chinatown first, I got a bit of business to take care of.
+[FEC_CR3]
+Crouch (L3 button)
-[JM4_11]
-Those washer women aint been payin' their protection money.
+[FEC_SMT]
+Sub-mission
-[JM4_12]
-And watch the car, Joey just fixed this junk heap.
+[FEC_SM3]
+Sub-mission (R3 button)
-[JM4_13]
-So no fancy crap, OK?
+[FEC_RSC]
+Radio stations
-[KM4_11]
-~g~Take the money back to the casino!
+[ST_PR01]
+Flyboy
-[FEF_BR2]
-Find it again by reading any mission briefs collected to date.
+[ST_PR02]
+Aircraftman
-[TRAIN_1]
-Kurowski Station
+[ST_PR03]
+Pilot Officer
-[TRAIN_2]
-Rothwell Station
+[ST_PR04]
+Corporal
-[TRAIN_3]
-Baillie Station
+[ST_PR05]
+Lieutenant
-[SUBWAY1]
-Portland Station
+[ST_PR06]
+Sergeant
-[SUBWAY2]
-Rockford Station
+[ST_PR07]
+Captain
-[SUBWAY3]
-Staunton South Station
+[ST_PR08]
+Biggs
-[SUBWAY4]
-Shoreside Terminal
+[ST_PR09]
+Wedge
-[MEA4_2]
-~r~Marty Chonks is dead!
+[ST_PR10]
+Red Baron
-[SPRAY1]
-Drive your vehicle into the spray shop to lose your ~h~wanted level~w~, ~h~repair ~w~and ~h~respray ~w~your vehicle. Cost - ~h~$1000~w~. This time it's free.
+[ST_PR11]
+Goose
-[JM4_A]
-Yeah, I know Toni, I've tuned her real sweet. She purrs, you know what I mean?
+[ST_PR12]
+Viper
-[JM4_5]
-Drop by later and we'll give them something to launder, their own blood stained clothes!
+[ST_PR13]
+Jester
-[AMMU_A]
-Luigi said you'd need a piece...
+[ST_PR14]
+Chappy
-[AMMU_B]
-Joey told me to tool you up...
+[ST_PR15]
+Iceman
-[AMMU_C]
-So go around back of the shop. I left you a nine in the yard.
+[ST_PR16]
+Maverick
-[AMMU_D]
-I got all your home defence needs.
+[ST_PR17]
+Noops
-[AMMU_E]
-You want a license too?
+[ST_PR18]
+Air Chief Marshal
-[AMMU_F]
-I don't need to see any I.D. you look trustworthy.
+[ST_PR19]
+Ace
-[DETON]
-DETONATION:
+[FET_LG]
+LOAD GAME
-[DRIVE_A] { re3 change }
-Have an Uzi selected when entering a vehicle then look left or right and press the ~h~~k~~VEHICLE_FIREWEAPON~ button~w~ to fire.
+[CAR_EXP]
+Road Vehicles destroyed
-[DRIVE_B] { re3 change }
-Have an Uzi selected when entering a vehicle then look left or right and press the ~h~~k~~VEHICLE_FIREWEAPON~ button~w~ to fire.
+[BOA_EXP]
+Boats destroyed
-[RECORD]
-~g~NEW RECORD!!
+[HEL_DST]
+Planes & Helicopters destroyed
-[NRECORD]
-~r~NO NEW RECORD!
+[STFT_01]
+Fastest time on 'Alloy Wheels Of Steel'
-[RCHELP] { re3 change }
-Press ~k~~VEHICLE_FIREWEAPON~, or drive the RC car into a vehicle's wheels to detonate.
+[STFT_02]
+Fastest time on 'The Driver'
-[RCHELPA] { re3 change }
-Press the ~k~~VEHICLE_FIREWEAPON~ button, or drive the RC car into a vehicle's wheels to detonate.
+[STFT_03]
+Fastest time in Dirt Ring
-[RC_1]
-You have 2 minutes to blow up as many Diablo Gang Cars as possible!
+[STFT_04]
+Fastest time on RC Plane Race
-[RC_2]
-You have 2 minutes to blow up as many Mafia Gang Cars as possible!
+[STFT_05]
+Fastest time on RC Car Race
-[RC_3]
-You have 2 minutes to blow up as many Yakuza Gang Cars as possible!
+[STFT_06]
+Fastest time on RC helicopter Pickup
-[RC_4]
-You have 2 minutes to blow up as many Yardie Gang Cars as possible!
+[STFT_07]
+Fastest time on 'Terminal Velocity'
-[RC_5]
-You have 2 minutes to blow up as many Hood Gang Cars as possible!
+[STFT_08]
+Fastest time on 'Ocean Drive'
-[RC_6]
-You have 2 minutes to blow up as many Cartel Gang Cars as possible!
+[STFT_09]
+Fastest time on 'Border Run'
-[RAMPAGE]
-RAMPAGE!!
+[STFT_10]
+Fastest time on 'Capital Cruise'
-[RAMP_P]
-RAMPAGE COMPLETE!
+[STFT_11]
+Fastest time on 'Tour!'
-[RAMP_F]
-RAMPAGE FAILED
+[STFT_12]
+Fastest time on 'V.C. Endurance'
-[PAGE_00]
-.
+[STHC_01]
+Highest score for Shooter
-[PAGE_01]
-Murder ~1~ Diablos in 120 seconds!
+[STHC_02]
+Best Percentage of hits for Shooter
-[PAGE_02]
-Destroy ~1~ vehicles in 120 seconds!
+[STHC_03]
+Number of drug deals made
-[PAGE_03]
-Kill ~1~ Mafia in 120 seconds!
+[HELP24]
+You can now take jobs from the Colonel.
-[PAGE_04]
-Kill ~1~ Triads in 120 seconds!
+[HELP25]
+You can now take jobs from Avery Carrington.
-[PAGE_05]
-Kill ~1~ Triads in 120 seconds!
+[HELP29]
+You can visit the clothes store when you're not on a mission.
-[PAGE_06]
-Destroy ~1~ vehicles in 120 seconds!
+[HELP30]
+When you buy new clothes your wanted level will be set to zero.
-[PAGE_07]
-Pop ~1~ Yardie heads in 120 seconds!
+[ASM4_24]
+distance:
-[PAGE_08]
-Burn ~1~ Yakuza in 120 seconds!
+[RBM1_6]
+~g~Take Mercedes and the 'Love Juice' to the band at the recording studio.
-[PAGE_09]
-Destroy ~1~ vehicles in 120 seconds!
+[RBM1_3]
+NO LONGER NEEDED
-[PAGE_10]
-Destroy ~1~ vehicles in 120 seconds!
+[HAM1_5]
+NO LONGER NEEDED
-[PAGE_11]
-Annihialate ~1~ Yardies in 120 seconds!
+[RBM1_11]
+NO LONGER NEEDED
-[PAGE_12]
-Torch ~1~ Yakuza in 120 seconds!
+[HELP31]
+To do a drive-by, first look left or right using the ~h~~k~~VEHICLE_LOOKLEFT~~w~ or the ~h~~k~~VEHICLE_LOOKRIGHT~.
-[PAGE_13]
-Explode ~1~ Yardies in 120 seconds!
+[HELP34]
+You must have a sub machine gun to perform a drive-by.
-[PAGE_14]
-Fry ~1~ Colombians in 120 seconds!
+[STRIP_1]
+~r~Not enough cash, you cheap sleazebag.
-[PAGE_15]
-Splatter ~1~ Hoods in 120 seconds!
+[EXIT_1]
+Press the ~h~~k~~PED_SPRINT~ ~w~button to exit.
-[PAGE_16]
-Destroy ~1~ vehicles in 120 seconds!
+[ASM1_B]
+Your next job is taped under the phone.
-[PAGE_17]
-Splatter ~1~ Colombians with a car in 120 seconds!
+[ASM1_C]
+I have more work for you with a more 'hands-on' approach.
-[PAGE_18]
-Driveby and Destroy ~1~ vehicles in 120 seconds!
+[SCARF]
+Apartment 3c
-[PAGE_19]
-Remove ~1~ Colombian heads in 120 seconds!
+[LAW4_10]
+Rich management suck!
-[PAGE_20]
-Behead ~1~ Hoods in 120 seconds!
+[RCH1_6]
+~g~Use the RC Helicopter to collect checkpoints scattered throughout the airport.
-[JM1_A]
-Hey, I'm bored when you gonna drill me?
+[RCH1_9]
+~b~TOTAL TIME: ~1~:~1~
-[JM1_B]
-In a moment sweet heart, I got a little business to take care of.
+[RCH1_10]
+~b~TOTAL TIME: ~1~:0~1~
-[JM1_C]
-I got a little job for you pal.
+[WHEEL01]
+TWO WHEELS DOUBLE BONUS: $ ~1~ Distance: ~1~.~1~m Time: ~1~ seconds
-[JM1_D]
-The Forelli brothers have owed me money for too long
+[WHEEL02]
+TWO WHEELS DOUBLE BONUS: $ ~1~ Distance: ~1~ feet Time: ~1~ seconds
-[JM1_E]
-and they need to be taught some respect.
+[WHEEL03]
+TWO WHEELS BONUS: $ ~1~ Time: ~1~ seconds
-[JM1_F]
-Lips Forelli is stuffing his fat face in St Marks Bistro,
+[WHEEL04]
+TWO WHEELS BONUS: $ ~1~ Distance: ~1~.~1~m
-[JM1_G]
-so steal his car and take it to 8-Ball's bomb shop up in Harwood.
+[WHEEL05]
+TWO WHEELS BONUS: $ ~1~ Distance: ~1~ feet
-[JM1_H]
-You know 8-Ball right?
+[WHEEL06]
+WHEELIE BONUS: $ ~1~ Distance: ~1~.~1~m Time: ~1~ seconds
-[JM1_I]
-Once he's fitted it with a bomb, go park the car where you found it.
+[WHEEL07]
+WHEELIE BONUS: $ ~1~ Distance: ~1~ feet Time: ~1~ seconds
-[JM1_J]
-Then sit back and watch the whole show.
+[WHEEL08]
+WHEELIE BONUS: $ ~1~ Time: ~1~ seconds
-[JM1_K]
-But hurry up, he won't be eating forever.
+[WHEEL09]
+WHEELIE BONUS: $ ~1~ Distance: ~1~.~1~m
-[CAT2_A1]
-Come on you dumb bitch!
+[WHEEL10]
+WHEELIE BONUS: $ ~1~ Distance: ~1~ feet
-[CAT2_A]
-The real question is, did you turn up to rescue Maria or to get me back?
+[WHEEL11]
+STOPPIE BONUS: $ ~1~ Distance: ~1~.~1~m Time: ~1~ seconds
-[CAT2_B]
-Well I got news for you,
+[WHEEL12]
+STOPPIE BONUS: $ ~1~ Distance: ~1~ feet Time: ~1~ seconds
-[CAT2_B2]
-shooting you will be a pleasure but dating you was only business.
+[WHEEL13]
+STOPPIE BONUS: $ ~1~ Time: ~1~ seconds
-[CAT2_C]
-You are muy peccinno amigo!
+[WHEEL14]
+STOPPIE BONUS: $ ~1~ Distance: ~1~.~1~m
-[CAT2_D]
-Throw over the cash.
+[WHEEL15]
+STOPPIE BONUS: $ ~1~ Distance: ~1~ feet
-[CAT2_E]
-You have been a busy boy!
+[ROK3_72]
+Love Fist!
-[CAT2_E2]
-But you haven't learned, I'm not to be trusted.
+[POR1_19]
+Hey!
-[CAT2_E3]
-Kill the idiot.
+[DESPERA]
+Desperado
-[CAT2_J]
-Get this thing airborne!!
+[MOB_99A]
+Get to the payphone next to the mall in Washington.
-[HM5_1]
-Yo, Ice said was comin'. There rules. Bats only. No guns, no cars.
+[MOB_98A]
+Get to the pay phone in Vice Point.
-[HM5_5]
-This is a battle for respect, you cool?
+[MOB_96A]
+Get to the payphone at the airport terminal.
-[HELP14]
-To collect weapons walk through them. These cannot be collected while in a vehicle.
+[MOB_95A]
+Get to the payphone in Little Havana.
-[CRUSH]
-Park in the marked area and exit your vehicle. The vehicle will then be crushed.
+[BNK1_1]
+Can I help you, sir?
-[DIAB2_B]
-A gang of no-goods has threatened to remove my starring member if I don't pay them a cut.
+[BNK1_2]
+There's an imposter!
-[DIAB2_C]
-They threaten the wrong man, amigo.
+[BNK1_3]
+He's gone insane!
-[DIAB2_D]
-They have a weakness for the icecream.
+[BNK1_4]
+Who the hell are you?
-[DIAB2_E]
-Pick up the bomb I've hidden in Harwood,
+[BNK1_5]
+Where's your badge?
-[DIAB2_F]
-hijack the regular icecream van on its rounds.
+[BNK1_6]
+There they are! Shoot to kill!
-[DIAB2_G]
-and lure these fools to their doom with the jeengle-jeengle.
+[MOB_24A]
+Hola, is this Mr. Vercetti?
-[DIAB2_H]
-They hide in a warehouse on Atlantic Quay.
+[MOB_24B]
+Yeah.
-[DIAB3_A]
-Some insolent Triads stole my beautiful car last night,
+[MOB_24C]
+This is Cortez. You were at my party.
-[DIAB3_B]
-wrecked it and left it burning.
+[MOB_24D]
+Yeah. I remember.
-[DIAB3_C]
-Some of my most precious donkey memorabilia was in the trunk -
+[MOB_24E]
+Mr. Vercetti, it was a most unfortunate incident that happened with your business deal.
-[DIAB3_D]
-real collectibles that are irreplaceable my friend.
+[MOB_24F]
+I know.
-[DIAB3_E]
-I've hidden a throbbing weapon on the edge of Chinatown.
+[MOB_24G]
+I want you to know me and my people are doing their utmost to get to the bottom of it.
-[DIAB3_F]
-Take it and teach these Triad vandals to fear El Burro's well-endowed wrath.
+[MOB_24H]
+If you'd like to talk to me more privately, you can find me at the boat, eh? Okay? Good day, senor.
-[DIAB3_1]
-KILL 25 TRIADS
+[BNK2_6]
+This guy's a lunatic!
-[DIAB4_A]
-A thieving opportunist has stolen a van of my latest publication hot off the press!
+[ANGEL]
+Angel
-[DIAB4_B]
-But that SPANKED-up idiot has left the rear doors open
+[CUBJET]
+Cuban Jetmax
-[DIAB4_C]
-and now my beautifully produced,
+[SANDKIN]
+Sandking
-[DIAB4_D]
-tastefully photographed adult literature is being dropped all over Liberty!
+[POLMAV]
+Police Maverick
-[DIAB4_E]
-Take the van and follow that trail of Donkey Does Dallas volumes 1, 2 and 3
+[BOXVILL]
+Boxville
-[DIAB4_F]
-collecting it as you go.
+[BENSON]
+Benson
-[DIAB4_G]
-When you've followed the trail to that thieving SPANK-head, waste him!
+[HOTRINA]
+Hotring Racer
-[DIAB4_H]
-Then deliver my donkey derby to XXX Mags in the Red Light District.
+[HOTRINB]
+Hotring Racer
-[DIAB4_1]
-~g~Take the van to the back of XXX Magazines.
+[BLOODRA]
+Bloodring Banger
-[HM1_E]
-I want you to show these punk ass bitches how a real drive-by works.
+[BLOODRB]
+Bloodring Banger
-[HM1_H]
-Take these nines off of here!!
+[MAFIACR]
+Mafia Cruiser
-[HM2_A]
-Those Nines are pressing me.
+[COP_M2]
+'VICE SQUAD'
-[HM2_B]
-These Bitches got armored cars and now they're running SPANK...
+[COP_M3]
+'BROWN THUNDER'
-[HM2_C]
-and slinging it to brothers with no fear.
+[BNK3_2]
+I'm not driving for you, no way, I'm sharing this at group.
-[HM2_D]
-There's a car parked up the way.
+[FEM_SL1]
+Save File 1 Not Present
-[HM2_E]
-There's some stuff in there to put these sissys on blass...
+[FEM_SL2]
+Save File 2 Not Present
-[HM3_A]
-Some effa has wired my wheels to blow.
+[FEM_SL3]
+Save File 3 Not Present
-[HM3_B]
-If I lose those wheels, my rep on the street will be dead.
+[FEM_SL4]
+Save File 4 Not Present
-[HM3_C]
-Pick up my car and take it over to the garage on St. Marks, a'right yo.
+[FEM_SL5]
+Save File 5 Not Present
-[HM3_D]
-Let them diffuse that, let them take care of that bomb.
+[FEM_SL6]
+Save File 6 Not Present
-[HM3_E]
-The clocks ticking and the wiring is messed up.
+[FEM_SL7]
+Save File 7 Not Present
-[HM3_F]
-One pot hole too many and that thing could blow.
+[FEM_SL8]
+Save File 8 Not Present
-[HM3_G]
-Now move it!
+[FEA_CHA]
+Changing audio output to STEREO. Please wait...
-[HM4_A]
-Yo, a Federal Reserve flight just smashed down at Francis International.
+[FEA_CHD]
+Warning! You are changing from STEREO output to DTS. Please wait...
-[HM4_B]
-There's platinum all over the strip.
+[FEI_SEL]
+Select
-[HM4_C]
-Get a car and snatch up as much as you can.
+[FEI_BAC]
+Back
-[HM4_F]
-You can drop the bling off at one of my garages.
+[FEI_RES]
+Resume
-[HM4_G]
-This platinum is mad heavy and it will slow your wheels down some.
+[FEI_NAV]
+Navigate
-[HM4_H]
-So make regular drop off's at the garage.
+[FEI_BTX]
+/ button -
-[HM5_A]
-Them Nines are down to a few scabby herds...
+[FEI_BTT]
+" button -
-[HM5_B]
-but they still wanna bring it.
+[FEI_STA]
+START button -
-[HM5_C]
-They agreed to go toe to toe.
+[FEI_BTD]
+; = > < -
-[HM5_D]
-A gang of them against two of us, or rather...
+[FEI_STO]
+Stop
-[HM5_E]
-two of yaw
+[ST_ICEC]
+'Ice Cream' Sold
-[HM5_F]
-I'd join you but...
+[MOB_68A]
+Tommy son, have I got a surprise for you
-[HM5_G]
-I ain't due my parole hearing for another three months now,
+[MOB_68B]
+I'm down at the recording studios with some major artists
-[HM5_H]
-y'know what I mean?
+[MOB_68C]
+Why don't you pay us a visit?
-[HM5_I]
-Go and meet my baby brother,
+[MOB_68D]
+You know it makes sense, dontcha? See ya later.
-[HM5_J]
-He'll show you where they are fighting a'right son.
+[OUTFT1]
+Street
-[MEA1_B]
-The name's Chonks, Marty Chonks.
+[OUTFT2]
+Soiree
-[MEA1_C]
-I run the Bitchin' Dog Food factory around the corner.
+[OUTFT3]
+Coveralls
-[MEA1_D]
-I got money troubles, but hey, who doesn't right?
+[OUTFT4]
+Country Club
-[MEA1_E]
-I'm meeting my bank manager later.
+[OUTFT5]
+Havana
-[MEA1_F]
-He's a crooked bastard that keeps bumping up the loan repayments so he can cut a slice.
+[OUTFT6]
+Cop
-[MEA1_G]
-Take my car, pick him up and bring him back here.
+[OUTFT7]
+Bank Job
-[MEA1_H]
-I've got a little surprise for that blood sucking leech!!
+[OUTFT8]
+Casual
-[MEA2_A]
-I hired some thieves to break into my apartment...
+[OUTFT9]
+Mr Vercetti
-[MEA2_C]
-The thieving bastards are threatening to tell the insurance company,
+[OUTFT10]
+Tracksuit
-[MEA2_D]
-if I don't give them a cut.
+[OUTFT13]
+MC Tommy
-[MEA2_E]
-Can you believe it?
+[CAR_AS1]
+CAR SHOWROOM ASSET COMPLETED
-[MEA2_F]
-I've left a car inside the factory gates.
+[CAR_AS2]
+~g~Sunshine Auto's will now generate revenue up to a maximum of $~1~. Make sure you collect it regularly.
-[MEA2_G]
-Use it to go and pick them up from their turf in the Red Light district.
+[BUYSAVE]
+~g~You can now save your game here when not on a mission.
-[MEA2_H]
-Then bring 'em back to the factory so I can make 'em see Marty's point of view.
+[BUYGARG]
+~g~You can also store vehicles in this garage.
-[MEA3_A]
-The business is going to go under unless I get hold of some serious cash soon.
+[STRPBUY]
+Pole Position Club purchased: $~1~
-[MEA3_B]
-My wife has an insurance policy and all she's ever been to me is a hole in my pocket.
+[GA_4]
+Car bombs are $500 each
-[MEA3_C]
-I've left a car in the usual place.
+[GA_5]
+Your car is already fitted with a bomb.
-[MEA3_D]
-Go and pick up my wife from Classic Nails and bring her back to the factory.
+[GA_6] { reVC update }
+Park it, prime it by pressing the ~h~~k~~VEHICLE_FIREWEAPON~ ~w~button and LEG IT!
-[MEA4_A]
-Damn, I'm in trouble!
+[GA_7] { reVC update }
+Arm with the ~h~~k~~VEHICLE_FIREWEAPON~ ~w~button. Bomb will go off when engine is started.
-[MEA4_B]
-Turns out my wife was seeing some guy I owe money to.
+[GA_6B] { reVC update }
+Park it, prime it by pressing the ~h~~k~~VEHICLE_FIREWEAPON~ ~w~button and LEG IT!
-[MEA4_C]
-He's got real angry and he's looking for payback!
+[GA_7B] { reVC update }
+Arm with the ~h~~k~~VEHICLE_FIREWEAPON~ ~w~button. Bomb will go off when engine is started.
-[MEA4_E]
-he thinks I'm gonna pay him off...
+[MOB_70A]
+Tommy, it's me, Colonel Cortez. Look senor, I believe you are a man who can get things done. So please help me.
-[MEA4_F]
-but my guess is...
+[MOB_70B]
+You can find me at the boat.
-[MEA4_G]
-Liberty's dogs are gonna get yet another flavor this month!
+[PICK2]
+.357 delivered to Ocean View Hotel!
-[WELCOME]
-WELCOME TO
+[PICK3]
+Chainsaw delivered to Ocean View Hotel!
-[HM1_2]
-~g~Get a vehicle, remember only Uzi drive by kills count!
+[PICK4]
+Flame Thrower delivered to Ocean View Hotel!
-[HELP8_B]
-Press the~h~ ~k~~PED_SNIPER_ZOOM_IN~ button ~w~to ~h~zoom in ~w~with the rifle and the~h~ ~k~~PED_SNIPER_ZOOM_OUT~ button ~w~to ~h~zoom out ~w~again.
+[PICK5]
+.308 Sniper delivered to Ocean View Hotel!
-[LRQC_1]
-Asuka and I are gonna have to talk, uh,
+[PICK6]
+Minigun delivered to Ocean View Hotel!
-[LRQC_2]
-Why don't you go cruise around?
+[PICK7]
+Rocket Launcher delivered to Ocean View Hotel!
-[LRQC_3]
-You'll need a place to lie low.
+[PICK8]
+Sea Sparrow now available from the Mansion on Starfish Island!
-[LRQC_4]
-There's a warehouse at the edge of Belleville that should suit your needs.
+[PICK9]
+Tank now available from the Army Barracks!
-[LRQC_5]
-Come back here to my Condo when you are ready,
+[PICK10]
+Hunter now available from the Army Barracks!
-[LRQC_6]
-and we can have a little chat.
+[CLOTH1]
+Soiree outfit delivered to Rafael's on Ocean Beach.
-[JM6_5]
-~g~You need a getaway vehicle, Idiot!
+[CLOTH2]
+Street outfit delivered to Safehouses.
-[JM2_F]
-If you need a piece go around back of AmmuNation opposite the subway.
+[CLOTH3]
+Coveralls outfit delivered to Tooled Up in The North Point Mall.
-[LOVE4_7]
-~g~There's a construction yard in Staunton Island, maybe they took the package there.
+[CLOTH4]
+Country Club outfit delivered to The Golf Club in Leaf Links.
-[LOVE4_8]
-~g~You'll need a car to open the garage.
+[CLOTH5]
+Havana outfit delivered to Little Havana Streetwear in Little Havana.
-[TSCORE]
-EARNINGS: $~1~
+[CLOTH6]
+Cop outfit delivered to Police Station on Washington Beach.
-[AM1_9]
-~r~Salvatore has escaped back into Luigi's Club!
+[CLOTH7]
+Casual outfit delivered to Gash in The North Point Mall.
-[AM1_6]
-~g~If you hang around Luigi's club, the Mafia will spot you!
+[CLOTH8]
+Mr Vercetti outfit delivered to Collar & Cuffs on Ocean Beach.
-[TM2_3]
-~g~It's a trap! Waste them all!!
+[CLOTH9]
+Tracksuit outfit delivered to Jocksport in Downtown.
-[FM4_1]
-This is Maria. The car's a trap! Meet me at the slip south of Callahan Bridge.
+[CLOTH10]
+Bank Job outfit delivered to Malibu Club in Vice Point.
-[JM1_7]
-~g~Close the car door! He'll notice!
+[MOB_62A]
+Tommy, is Ricardo Diaz, I want to thank you for looking out for me my man.
-[KM5_1]
-~g~DEALER MINCED!!.
+[MOB_62B]
+I ask that prick Cortez, he say you the real deal, my friend, why you not come see me.
-[KM5_6]
-~g~You must murder at least 8 Yardie dealers.
+[MOB_62C]
+I need a guy like you. All I have now is dickheads,
-[KM5_7]
-~g~Kill them quickly! Once they've pushed their SPANK they're off the streets.
+[MOB_62D]
+dickheads everywhere, yo. I make you real rich.
-[RM3_8]
-~r~That car is a decoy!!
+[GOAWAY2]
+~g~Come back when you have finished the Biker gang missions.
-[LM3_8]
-Hey, I'm Joey.
+[COL2_9]
+You American idiot! They followed you here!
-[LM3_9]
-Luigi said you were reliable so come back later,
+[LOADCOL]
+Loading...
-[KM3_5]
-~g~Press the horn to get the deal going.
+[STFT_17]
+Fastest time on 'PCJ Playground'
-[LOVE7]
-LOVE'S DISAPPEARANCE
+[STFT_18]
+Fastest time on 'Trial By Dirt'
-[LOVE2_5]
-~g~Kenji is fender meat! Get out of Newport and dump the car!
+[STFT_19]
+Fastest time on 'Test Track'
-[AS2_11]
-~g~~1~ OF 9!
+[NEW_REC]
+~g~New Record Set!! ~w~~1~ minutes ~g~and ~w~~1~ seconds.
-[GARAGE1]
-~g~Get out of the vehicle and walk outside.
+[BMX_HOW]
+~g~Do two laps of the dirt track, ~y~passing through ~g~the ~y~CHECKPOINTS ~g~as you go!
-[KM3_11]
-~g~The Cartel have been attacked and the briefcase has not been recovered.
+[BMXREW1]
+~g~Each time you beat your previous record for the two laps
-[KM3_12]
-~g~Kill all of the Colombians, destory the vehicles and recover the briefcase.
+[BMXREW2]
+~g~a larger ~y~REWARD ~g~will be awarded!
-[KM3_13]
-~g~Take the briefcase back to the casino.
+[BMXRAIN]
+~g~Looks like rain...
-[RM5_6]
-~g~He's bailed out!! Smash his bodycast with a vehicle or an explosion!!
+[ITBEG]
+In the beginning...
-[PBOAT_1] { re3 change }
-Press the ~h~~k~~VEHICLE_FIREWEAPON~ button~w~ to fire the boat cannons.
+[NBMNBUY]
+El Swanko Casa purchased: $~1~
-[PBOAT_2] { re3 change }
-Press the ~h~~k~~VEHICLE_FIREWEAPON~ button~w~ to fire the boat cannons.
+[LNKVBUY]
+Links View Apartment purchased: $~1~
-[DIAB1_B]
-This is El Burro of the Diablos.
+[HYCOBUY]
+Hyman Condo purchased: $~1~
-[DIAB1_D]
-You're new in Liberty, but already you are gaining a reputation on the streets.
+[BUYGARS]
+~g~You can also store vehicles in these garages.
-[DIAB1_E]
-There's a street race starting by the old school hall near the Callahan Bridge.
+[OCHEBUY]
+Ocean Heights Apartment purchased: $~1~
-[DIAB1_F]
-Get yourself some wheels and first through all the checkpoints wins the prize.
+[WASHBUY]
+1102 Washington Street purchased: $~1~
-[HM2_1] { re3 change }
-Use the RC buggies to destroy the armored cars. Press the ~h~~k~~VEHICLE_FIREWEAPON~ button ~w~to detonate.
+[VCPTBUY]
+3321 Vice Point purchased: $~1~
-[HM2_1A] { re3 change }
-Use the RC buggies to destroy the armored cars. Press the ~h~~k~~VEHICLE_FIREWEAPON~ button ~w~to detonate.
+[HELP6_C]
+Press the ~h~~k~~VEHICLE_HANDBRAKE~ ~w~button to apply the vehicle's handbrake.
-[HM2_2]
-~r~You failed to destroy all the armored cars!
+[HELP2_A]
+Press the ~h~~k~~PED_SPRINT~ ~w~button when running to ~h~sprint
-[HM2_6]
-~g~Armored Car destroyed!
+[HELP4_A]
+Press the ~h~~k~~VEHICLE_ACCELERATE~ ~w~button to accelerate.
-[RM3_A]
-I know a real important man in town, a soft touch,
+[HELP5_A]
+Press the ~h~~k~~VEHICLE_BRAKE~ ~w~button to brake, or to reverse if the vehicle has stopped.
-[RM3_H]
-with shall we say, exotic tastes and the money to indulge them.
+[HELP8_A]
+Press the~h~ ~k~~PED_SNIPER_ZOOM_IN~ button ~w~to ~h~zoom in ~w~with the rifle and the~h~ ~k~~PED_SNIPER_ZOOM_OUT~ button ~w~to ~h~zoom out ~w~again.
-[RM3_B]
-He's involved in a legal matter and the prosecution has some rather embarrassing photos of him
+[PBOAT_1] { reVC update }
+Press the ~h~~k~~VEHICLE_FIREWEAPON~ ~w~button to fire the boat cannons.
-[RM3_C]
-at a morgue party or something.
+[SEG3_4] { reVC update }
+~g~You can pick up bombs by simply piloting your RC Raider adjacent to each one, to drop a bomb press the ~h~~k~~VEHICLE_FIREWEAPON~ ~g~button.
-[LOVE6_A]
-A lesson in business, my friend.
+[RCR1_3] { reVC update }
+~g~If you wish to quit this mission press the ~h~~k~~VEHICLE_FIREWEAPON~ ~g~button to detonate your RC car.
-[LOVE6_E]
-If you have a unique commodity, the world and his wife will try to wrestle it from your grasp...
+[HELP32] { reVC update }
+Then fire using the ~h~~k~~VEHICLE_FIREWEAPON~ ~w~button.
-[LOVE6_C]
-SWAT teams have cordoned off the area around my associate and the package.
+[HELP33] { reVC update }
+Then fire using the ~h~~k~~VEHICLE_FIREWEAPON~ ~w~button.
-[LOVE6_D]
-Get over there, pick up the van and act as a decoy.
+[TTUTOR]
+Press the ~h~~k~~TOGGLE_SUBMISSIONS~ button~w~ to toggle taxi missions on or off.
-[LOVE6_F]
-Keep them busy and he should make good his escape.
+[TTUTOR2]
+Press the ~h~~k~~TOGGLE_SUBMISSIONS~ button~w~ to toggle taxi missions on or off.
-[AM3_C]
-He's probably out in the bay as you read this! Steal a police boat, and sink his career!
+[FTUTOR]
+Press the ~h~~k~~TOGGLE_SUBMISSIONS~ button~w~ to toggle fire truck missions on or off.
-[FESZ_UC]
-CANCEL
+[FTUTOR2]
+Press the ~h~~k~~TOGGLE_SUBMISSIONS~ button~w~ to toggle fire truck missions on or off.
-[FEDS_SM]
-L1,R1-CHANGE MENU
+[CTUTOR]
+Press the ~h~~k~~TOGGLE_SUBMISSIONS~ button~w~ to toggle Vigilante missions on or off.
-[FEDS_AS]
-;=-CHANGE SELECTION
+[CTUTOR2]
+Press the ~h~~k~~TOGGLE_SUBMISSIONS~ button~w~ to toggle Vigilante missions on or off.
-[FEDSAS2]
-<>-CHANGE SELECTION
+[HELP8_B]
+Press the ~h~~k~~PED_SNIPER_ZOOM_IN~ button ~w~to ~h~zoom in ~w~with the rifle and the~h~ ~k~~PED_SNIPER_ZOOM_OUT~ button ~w~to ~h~zoom out ~w~again.
-[FEDS_SS]
-L1,R1-CHANGE SELECTION
+[ATUTOR3]
+Press the ~h~~k~~TOGGLE_SUBMISSIONS~ button~w~ to toggle Paramedic missions on or off.
-[FEDSSC1]
-;-FASTER SCROLLING
+[GUN_H1]
+~w~Press the~h~ ~k~~PED_SPRINT~ ~w~button to buy. Press the~h~ ~k~~VEHICLE_ENTER_EXIT~ ~w~button to exit.
-[FEDSSC2]
-=-STOP SCROLLING
+[PU_CF3] { reVC update }
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to replace current weapon in this slot.
-[MEA2_3]
-~g~Bring the car back to the factory.
+[PU_CF4] { reVC update }
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to replace current weapon in this slot.
-[RM1_3]
-~r~McAffrey escaped!
+[HELP9_B]
+Press the~h~ ~k~~PED_FIREWEAPON~ button ~w~to ~h~fire~w~ the sniper rifle.
-[RM1_4]
-~g~You have used all the grenades! Get some more from ammunation!
+[HELP37]
+If you do not want to enter the vehicle while car jacking someone, press the ~h~~k~~PED_SPRINT~ ~w~button.
-[RM1_5]
-~g~Go back and torch the safehouse!
+[HELP6_A]
+Press the~h~ ~k~~VEHICLE_HANDBRAKE~ button ~w~to apply the vehicle's ~h~handbrake.
-[RM6_4]
-~g~Go over to the lockup and collect Ray's stash.
+[HELP6_D]
+Press the~h~ ~k~~VEHICLE_HANDBRAKE~ button ~w~to apply the vehicle's ~h~handbrake.
-[RM6_5]
-~g~The CIA have the bridge under surveillance, find another route across.
+[HELP26]
+Press the ~h~~k~~VEHICLE_ENTER_EXIT~ ~w~button to enter or exit a vehicle.
-[HM2_F]
-and wreck all their armored stuff.
+[HELP27]
+Press the ~h~~k~~VEHICLE_TURRETUP~~w~ button and the ~h~~k~~VEHICLE_TURRETDOWN~~w~ button, to shift your weight on a bike.
-[HM_4]
-'BULLION RUN'
+[HELP28]
+Press the ~h~~k~~VEHICLE_TURRETUP~~w~ button and the ~h~~k~~VEHICLE_TURRETDOWN~~w~ button, to shift your weight on a bike.
-[MEA2_B5]
-TEXT NO LONGER NEEDED
+[HELP35]
+Press the ~h~~k~~GO_LEFT~~w~, and the ~h~~k~~GO_RIGHT~~w~, to steer the vehicle.
-[MEA1_B5]
-TEXT NO LONGER NEEDED
+[HELP36]
+Press the ~h~~k~~GO_LEFT~~w~, and the ~h~~k~~GO_RIGHT~~w~, to steer the vehicle.
-[MEA3_B5]
-TEXT NO LONGER NEEDED
+[HELP42]
+Follow the ~q~pink blip~w~ to find the hotel.
-[MEA4_B7]
-but if you just step into my office...
+[HELP19]
+Walk into the ~q~pink marker ~w~to continue.
-[MEA3_B4]
-Marty wants to see me? Well it better be quick because I have to get my hair done.
+[HELP1]
+Stop in the center of the ~q~pink marker.
-[KM3_7]
-It's a Yakuza trap man!
+[HELP12]
+Walk into the center of the ~q~pink marker~w~ to trigger a mission.
-[FES_LOF]
-Load Failed.
+[SEG3_6]
+~g~To successfully hit a target zone, you must drop the bomb in the area represented by the ~q~pink marker~w~. You can drop the bombs in any order.
-[FES_SLO]
-SAVE FILE
+[S_PROMP]
+When not on a mission you can save your progress by collecting the ~h~cassette tape pickup.
-[FES_ISC]
-IS CORRUPTED
+[HELP16]
+Walk through the front door of the ~h~Ocean View~w~ Hotel to enter the building.
-[FESZ_TI]
-SAVE Z1
+[HELP43]
+~g~Goto the ~h~Ocean View~g~ hotel on Ocean Drive.
-[FESZ_SA]
-Save game
+[HELI_F1]
+~r~Heli Checkpoint mission cancelled!
-[MC_LDFL]
-Load Failed!
+[AMMUHLP]
+If you need any weapons visit ~h~Ammu-Nation~w~. Follow the ~h~Gun blip~w~ on the radar.
-[MC_NWRE]
-Now Restarting Game.
+[HELI_1]
+Downtown Chopper Checkpoint
-[LOVE6_3]
-~g~You have ~1~ seconds to return to the Securicar before you fail the mission.
+[HELI_2]
+Ocean Beach Chopper Checkpoint
-[LOVE6_4]
-~r~You ditched the Decoy Securicar!
+[HELI_3]
+Vice Point Chopper Checkpoint
-[HELP1]
-Stop in the center of the blue marker.
+[HELI_4]
+Little Haiti Chopper Checkpoint
-[HELP12]
-Walk into the center of the blue marker to trigger a mission.
+[FST_MFR]
+Most Favorite Radio Station
-[HJSTAT]
-Distance: ~1~.~1~m Height: ~1~.~1~m Flips: ~1~ Rotation: ~1~_
+[FST_LFR]
+Least Favorite Radio Station
-[HJSTATW]
-Distance: ~1~.~1~m Height: ~1~.~1~m Flips: ~1~ Rotation: ~1~_ And what a great landing!
+[FEI_HOL]
+Hold
-[DIAB1_5]
-RACE TIME:
+[FEI_ZOO]
+Zoom
-[LOVE3_4]
-~r~You destroyed the plane!!
+[FEI_BTR]
+> < -
-[F_FAIL1]
-Fire Truck mission ended.
+[FEI_NA]
+N\A
-[F_CANC]
-~r~Fire Fighter mission cancelled!
+[MESA]
+Mesa Grande
-[F_EXTIN]
-FIRES:
+[STRP_NO]
+You cannot buy the Stripclub at this time, come back later.
-[A_COMP1]
-Paramedic missions complete!
+[CHSE]
+CHASE
-[A_CANC]
-~r~Paramedic mission cancelled!
+[NBMN_L]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase El Swanko Casa for $~1~
-[A_COMP3]
-Paramedic missions complete! You will never get tired when running!
+[NBMN_T]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase El Swanko Casa for $~1~
-[ATUTOR]
-Press the ~h~~k~~TOGGLE_SUBMISSIONS~ button~w~ to toggle Paramedic missions on or off.
+[NBMN_C]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase El Swanko Casa for $~1~
-[ATUTOR3]
-Press the ~h~~k~~TOGGLE_SUBMISSIONS~ button~w~ to toggle Paramedic missions on or off.
+[LNKV_L]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase Links View Apartment for $~1~
-[ALEVEL]
-Paramedic Mission Level ~1~
+[LNKV_T]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase Links View Apartment for $~1~
-[A_FAIL1]
-Paramedic mission ended.
+[LNKV_C]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase Links View Apartment for $~1~
-[FEST_HA]
-Highest Paramedic Mission level
+[HYCO_L]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase Hyman Condo for $~1~
-[A_SAVES]
-PEOPLE SAVED: ~1~
+[HYCO_T]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase Hyman Condo for $~1~
-[C_KILLS]
-CRIMINALS KILLED: ~1~
+[HYCO_C]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase Hyman Condo for $~1~
-[HM1_B]
-I got a problem they tryin' to play me.
+[OCHE_L]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase Ocean Heights Apartment for $~1~
-[AM2_A]
-Salvatore's death comes as pleasurable news,
+[OCHE_T]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase Ocean Heights Apartment for $~1~
-[AM2_A2]
-you are an efficient killer. I like that in a man.
+[OCHE_C]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase Ocean Heights Apartment for $~1~
-[AM2_B]
-This is my brother Kenji.
+[WASH_L]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase 1102 Washington Street for $~1~
-[AM2_C]
-Asuka has a little job for you, but when you're done, drop by my casino and we can talk.
+[WASH_T]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase 1102 Washington Street for $~1~
-[AM2_D]
-Just like Kenji, always trying to play with my toys.
+[WASH_C]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase 1102 Washington Street for $~1~
-[AM2_E]
-My police source indicates that the Mafia are watching our interests around the city
+[VCPT_L]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase 3321 Vice Point for $~1~
-[AM2_E2]
-in a bid to track you down.
+[VCPT_T]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase 3321 Vice Point for $~1~
-[AM2_F]
-We cannot continue our operations until they are dealt with.
+[VCPT_C]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase 3321 Vice Point for $~1~
-[AM2_G]
-Take out these spying fools and end this vendetta once and for all.
+[PRNT_L]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase the Print Works for $~1~
-[F_START]
-~g~Burning vehicle reported in the ~a~ area. Go and extinguish the fire.
+[PRNT_T]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase the Print Works for $~1~
-[AM4_1A]
-Get to the Phone in West Belleville Park.
+[PRNT_C]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase the Print Works for $~1~
-[AM4_1B]
-Get to the Phone on Liberty Campus.
+[CAR_L]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase the Car Showroom for $~1~
-[AM4_1C]
-Get to the Phone in South Belleville Park.
+[CAR_T]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase the Car Showroom for $~1~
-[AM4_1D]
-Meet me in the toilet block in the park.
+[CAR_C]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase the Car Showroom for $~1~
-[HJSTATF]
-Distance: ~1~ft Height: ~1~ft Flips: ~1~ Rotation: ~1~_
+[PORN_L]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase the Film Studios for $~1~
-[HJSTAWF]
-Distance: ~1~ft Height: ~1~ft Flips: ~1~ Rotation: ~1~_ And what a great landing!
+[PORN_T]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase the Film Studios for $~1~
-[HM1_F]
-Watch your back though, there'll be Jacks on the street who'll think you're trying to blast them too!
+[PORN_C]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase the Film Studios for $~1~
-[HM1_D]
-'Nines' is their tag and purple is their flag and each day they rock their colors...
+[ICE_L]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase the Ice Cream Factory for $~1~
-[HM1_G]
-is another day the 'Jacks' look soft.
+[ICE_T]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase the Ice Cream Factory for $~1~
-[MEA2_B]
-and steal some stuff so I could claim on the insurance as you do.
+[ICE_C]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase the Ice Cream Factory for $~1~
-[TM3_H]
-~w~You did good back there kid, real good.
+[TAXI_L]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase the Taxi Company for $~1~
-[TM3_I]
-~w~Come on, let's introduce you to the Don.
+[TAXI_T]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase the Taxi Company for $~1~
-[TM3_J]
-~w~Heeyyy! Luigi!
+[TAXI_C]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase the Taxi Company for $~1~
-[TM3_K]
-~w~Oh my girls have been missing you so long Salvatore, you been away too long.
+[BANK_L]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase The Malibu for $~1~
-[TM3_L]
-~w~You tell them that once this unfortunate business is taken care of,
+[BANK_T]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase The Malibu for $~1~
-[TM3_M]
-~w~we'll all go down to the club and celebrate, ok?
+[BANK_C]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase The Malibu for $~1~
-[TM3_N]
-~w~Here's my boy.
+[BOAT_L]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase the Boatyard for $~1~
-[TM3_N2]
-~w~How you doin' pop?
+[BOAT_T]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase the Boatyard for $~1~
-[TM3_O]
-~w~You got yourself a good woman yet?
+[BOAT_C]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase the Boatyard for $~1~
-[TM3_P]
-~w~Hey, your mother, god bless her soul, would be turning over in her grave
+[STRP_L]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase the Pole Position Club for $~1~
-[TM3_Q]
-~w~to see you without a wife.
+[STRP_T]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase the Pole Position Club for $~1~
-[TM3_R]
-~w~I know Pop, I'm working on it.
+[STRP_C]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase the Pole Position Club for $~1~
-[TM3_S]
-~w~TONI! How's your Momma?
+[STOCK]
+~r~out of stock
-[TM3_T]
-~w~She's a great woman you know. Strong. Firenze.
+[HELP14]
+To find the Lawyer's office, follow the ~h~L blip~w~ on the radar
-[TM3_U]
-~w~She's good...fine.
+[RAMPAGE]
+RAMPAGE!!
-[TM3_V]
-~w~Terrific, Terrific. Now listen you guys, you go inside while I talk to our new friend here.
+[RAMP_F]
+RAMPAGE FAILED!!
-[TM3_W]
-~w~I see nothing but good things for you my boy...
+[RAMP_P]
+RAMPAGE PASSED!!
-[RM1_A]
-That scumbag McAffrey, he took more bribes than anyone.
+[RAMP_A]
+ALL RAMPAGES COMPLETED!!
-[RM1_B]
-He thinks he's gonna get an honorable discharge if he turns states evidence.
+[PAGE_01]
+Kill ~1~ Gang Members in 2 Minutes!
-[RM1_C]
-He just squealed!
+[PAGE_02]
+Destroy ~1~ Vehicles in 2 Minutes!
-[RM4_B]
-We gotta shut him up, permanently.
+[PAGE_03]
+Drive-by and Waste ~1~ Gang Members in 2 Minutes!
-[RM4_E]
-I want him sleeping with the fishes, not eating them.
+[PAGE_04]
+Runover and Kill ~1~ Gang Members in 2 Minutes!
-[LOVE3_B]
-On its approach to the airport tonight, a light aircraft will pass over the bay.
+[PAGE_05]
+Gun Down ~1~ Gang Members in 2 Minutes!
-[LOVE4_D]
-Unfortunately the port authorities seized the plane and were stripping it down
+[SENTXS]
+Sentinel XS
-[LOVE4_H]
-until I intervened at great personal expense.
+[MAP_LEG]
+Map Legend
-[LOVE4_E]
-Cross the bridge to Shoreside Vale and go to Francis International Airport.
+[VCNMAV]
+VCN Maverick
-[GTAB_A]
-Hey, let's get this out of here. God knows what it is
+[LG_01]
+Player position
-[GTAB_B]
-but he seems to want it badly enough so it must be worth something.
+[LG_02]
+Avery Carrington
-[GTAB_C]
-Who the Heck!
+[LG_03]
+Biker Contact
-[GTAB_D]
-YOU!
+[LG_04]
+Colonel Cortez
-[GTAB_E]
-Hey take it easy amigo! De nada! De nada!
+[LG_05]
+Ricardo Diaz
-[GTAB_F]
-I left you pouring your heart out into the gutter!
+[LG_06]
+Kent Paul
-[GTAB_G]
-Don't shoot amigo. No problem. We all friends. Here, take this.
+[LG_07]
+Lawyer
-[GTAB_H]
-Don't be such a pussy!
+[LG_08]
+Phil Cassidy
-[GTAB_I]
-We got no choice baby!
+[LG_09]
+Boatyard
-[GTAB_J]
-We always got a choice you dumb bastard!
+[LG_10]
+Malibu Club
-[GTAB_K]
-I'm sorry about that crazy bitch man, they all the same...por favor??
+[LG_11]
+Cubans
-[GTAB_L]
-So the whore got away.
+[LG_12]
+Film Studio
-[GTAB_M]
-But you've done me a favor,
+[LG_13]
+Ammu-Nation
-[GTAB_N]
-you're not the only one that has a score to settle with the Cartel,
+[LG_14]
+Haitians
-[GTAB_O]
-this worm killed my brother!
+[LG_15]
+Hardware Store
-[GTAB_P]
-I never killed no Yakuza!
+[LG_16]
+Safe House
-[GTAB_Q]
-LIAR! We all saw the Cartel assassin.
+[LG_17]
+Ice Cream
-[GTAB_R]
-We are going to hunt down and kill all you Colombian dogs!
+[LG_18]
+Kaufman Cabs
-[GTAB_S]
-I'll be operating on our friend here to extract information and a little pleasure.
+[LG_19]
+Love Fist
-[GTAB_T]
-You, drop by later, I'm sure I'll require your services.
+[LG_20]
+Print Works
-[GTAB_U]
-Please amigo, don't leave me with her, she psycho chica! Amigo? Hey AMEEEGO!!!...Aiiieeeeaaargghh!
+[LG_21]
+Property
-[LOVE5_A]
-You are proving to be a safe investment, a rare thing in these days of false hood.
+[LG_22]
+Pay 'n' Spray
-[KM3_1]
-~g~The Cartel are expecting a Yardie Posse go and steal a Yardie car! Head north you'll find one in Newport.
+[LG_23]
+Clothes Shop
-[LOVE1_1]
-~g~Go 'jack a Colombian gang car, so you can infiltrate the hideout, head north you'll find one in Fort Staunton.
+[LG_24]
+Tommy's Mansion
-[FM1_Q1]
-~w~You looking for some fun? A little...hmm? Some SPANK?
+[LG_25]
+Telephone
-[FM1_R]
-~w~Hi Chico. Nah, just the usual.
+[LG_26]
+Wildstyle Radio Station
-[FM1_T]
-~w~Thanks Chico. See you around.
+[LG_27]
+Flash FM Radio Station
-[FM1_W]
-~w~Alright Fido, you wait here and look after the car while I go and shake my butt alright.
+[LG_28]
+KChat Radio Station
-[FM1_X]
-~w~OK Fido, let's get out of here. Wooooh!
+[LG_29]
+Fever 105 Radio Station
-[FM1_Q]
-~w~Hey Maria! It's my favorite lady!
+[LG_30]
+VROck Radio Station
-[FM1_S1]
-~w~Hey, maybe you should check out the warehouse party at the east end of Atlantic Quays.
+[LG_31]
+VCPR Radio Station
-[FM1_U]
-~w~Gracias and enjoy. That's good stuff.
+[LG_32]
+Espantoso Radio Station
-[FM1_V]
-~w~C'mon Fido, let's go and check out this party!
+[LG_33]
+Emotion 98.3 Radio Station
-[FM1_SS]
-~r~SCANNER: ~g~Four-five to all units: Assist narcotics raid Atlantic Quays...
+[LG_34]
+Wave 103 Radio Station
-[LOVE6_B]
-even if they have little understanding as to its true value.
+[LG_36]
+Sun Yard
-[TM3_A1]
-~r~Joey's Fried!
+[LG_37]
+Strip Club
-[TM3_A2]
-~r~Joey and Luigi have been cremated!
+[MAP_YAH]
+YOU ARE HERE
-[TM3_A3]
-~r~Joey, Luigi and Toni are Toast!
+[TAXSHRT]
+~g~You can use this Kaufman Cab to take you to destinations instead of driving. It will cost you $9.
-[FM4_2]
-Listen, Salvatore thinks that we're going behind his back,
+[MOB_09D]
+Maybe Leo's already dead. Maybe I killed Leo and took his phone - you think of that prick?
-[FM4_3]
-so he was offering you to the Cartel in order to make a deal.
+[FE_MLG]
+MAP LEGEND
-[FM4_4]
-I couldn't let him do that, I mean the worst thing is,
+[FED_RDR]
+RADAR MODE
-[FM4_4B]
-it's all my fault... because I told him, we were an item.
+[FED_HUD]
+HUD MODE
-[FM4_5]
-Don't ask me why. I don't know.
+[FED_RDB]
+BLIPS ONLY
-[FM4_6]
-Look you're a marked man on Mafia turf and I've got to get out of here too.
+[FEST_HV]
+Highest Vigilante Mission level
-[FM4_6B]
-I've seen too much killing. Too much blood!
+[BRIBE1]
+You have just picked up a police bribe, this will reduce your wanted level by one star.
-[FM4_7]
-This is a friend of mine ok, she's an old friend.. it's Asuka, she's someone we can trust.
+[CLOHELP]
+Clean Clothes!!
-[FM4_8]
-C'mon, Enough of the speeches.
+[CRED001]
+ROCKSTAR NORTH
-[FM4_9]
-We better get out of here before we get more hysterical Italians wanting less friendly reunions.
+[CRD001A]
+STUDIO DIRECTOR
-[CRED001]
-ROCKSTAR STUDIOS
+[CRD001B]
+ANDREW SEMPLE
[CRED002]
PRODUCER
+[CRD002A]
+DEVELOPMENT DIRECTOR
+
[CRED003]
LESLIE BENZIES
@@ -5165,7 +4889,7 @@ ART DIRECTOR
AARON GARBUT
[CRED006]
-TECHNICAL DIRECTION
+TECHNICAL DIRECTORS
[CRED007]
OBBE VERMEIJ
@@ -5173,21 +4897,27 @@ OBBE VERMEIJ
[CRED008]
ADAM FOWLER
-[CRED009]
-DESIGN
-
[CRED010]
-CRAIG FILSHIE
+ANDREW DUTHIE
[CRED011]
-WILLIAM MILLS
+CRAIG FILSHIE
[CRED012]
-CHRIS ROTHWELL
+WILLIAM MILLS
[CRED013]
+CHRIS ROTHWELL
+
+[CRD013A]
+IMRAN SARWAR
+
+[CRD013B]
JAMES WORRALL
+[CRD013C]
+JOHN HAIME
+
[CRED014]
WRITTEN BY
@@ -5201,67 +4931,121 @@ PAUL KUROWSKI
DAN HOUSER
[CRED018]
-CHARACTERS
+LEAD CHARACTER DESIGNER
+
+[CRD018A]
+CHARACTER DESIGNER
[CRED019]
IAN MCQUE
+[CRD019A]
+TOKS SOLARIN
+
+[CRD019B]
+ALAN DAVIDSON
+
[CRED020]
-ANIMATION & DIRECTION
+LEAD ANIMATOR
[CRED021]
ALEX HORTON
+[CRD022A]
+ANIMATORS
+
[CRED022]
LEE MONTGOMERY
+[CRD022B]
+DUNCAN SHIELDS
+
+[CRD022C]
+GUS BRAID
+
[CRED023]
-AUTO DESIGN
+VEHICLE DESIGNERS
+
+[CRD023A]
+JOLYON ORME
+
+[CRD023B]
+ALAN DUNCAN
+
+[CRD024A]
+LEAD VEHICLE DESIGNER
[CRED024]
PAUL KUROWSKI
[CRED025]
-ARTISTS
+MAP DESIGNERS
[CRED026]
-KEIRAN BAILLIE
+ADAM COCHRANE
[CRED027]
-ADAM COCHRANE
+NIK TAYLOR
[CRED028]
GARY MCADAM
[CRED029]
-MICHAEL PIRSO
+KEIRAN BAILLIE
[CRED030]
-ANDREW SOOSAY
+ALISDAIR WOOD
[CRED031]
-ALISDAIR WOOD
+ANDREW SOOSAY
+
+[CRD031A]
+STEVEN MULHOLLAND
+
+[CRD031B]
+WAYLAND STANDING
+
+[CRD031C]
+CAMPBELL J. DICK
+
+[CRD031D]
+GRAPHIC DESIGNER
+
+[CRD031E]
+STUART PETRI
[CRED032]
-CODERS
+LEAD PROGRAMMER
+
+[CRD032A]
+PROGRAMMERS
[CRED033]
-ALAN CAMPBELL
+ALEXANDER ROGER
[CRED034]
-MARK HANLON
+GRAEME WILLIAMSON
[CRED035]
-ANDRZEJ MADAJCZYK
+BARANE CHAN
[CRED036]
-ALEXANDER ROGER
+DEREK PAYNE
[CRED037]
-GRAEME WILLIAMSON
+GORDON YEOMAN
+
+[CRD037A]
+ALAN CAMPBELL
+
+[CRD037B]
+MARK HANLON
+
+[CRD037C]
+ANDRZEJ MADAJCZYK
[CRED038]
-SCORE
+LEAD MUSIC PRODUCER
[CRED039]
CRAIG CONNER
@@ -5270,13 +5054,22 @@ CRAIG CONNER
STUART ROSS
[CRED041]
-SOUND DESIGN & MASTERING
+LEAD AUDIO ENGINEER
[CRED042]
ALLAN WALKER
+[CRD041A]
+AUDIO ENGINEER
+
+[CRD041B]
+AUDIO
+
+[CRD042A]
+WILL MORTON
+
[CRED043]
-AUDIO PROGRAMMING
+AUDIO PROGRAMMER
[CRED044]
RAYMOND USHER
@@ -5288,49 +5081,70 @@ TEST MANAGER
CRAIG ARBUTHNOTT
[CRED047]
-LEAD TESTERS
+LEAD QA
[CRED048]
-ANDY DUTHIE
+NEIL CORBETT
[CRED049]
-JOHN HAIME
+KEVIN WONG
[CRED050]
-NEIL CORBETT
-
-[CRD050A]
-TESTERS
+QA
[CRED051]
-GRAEME JENNINGS
+DAVID BEDDOES
[CRED052]
-DAVID MURDOCH
+DAVID WATSON
[CRED053]
-DAVID BEDDOES
+BARRY CLARK
[CRED054]
-EDWIN SMITH
+ROSS SPARROW
[CRED055]
-MARK FLETT
+JAMES ALLAN
[CRED056]
-MICHAEL SUTHERLAND
+NEIL MEIKLE
+
+[CRD056A]
+GEORGE WILLIAMSON
+
+[CRD056B]
+MATT JONES
+
+[CRD056C]
+ROB HARBOUR
+
+[CRD056D]
+TOM WHITTAKER
[CRED057]
-TECHNICAL SUPPORT
+LEAD TECHNICAL SUPPORT
[CRED058]
LORRAINE ROY
+[CRD057A]
+TECHNICAL SUPPORT
+
[CRED059]
CHRISTINE CHALMERS
+[CRD060A]
+OFFICE SUPPORT
+
+[CRD060B]
+KIM GURNEY
+
+[CRD060C]
+CASSIE OLIVER
+
[CRED060]
-ROCKSTAR
+ROCKSTAR NEW YORK
[CRED061]
EXECUTIVE PRODUCER
@@ -5345,13 +5159,13 @@ PRODUCER
DAN HOUSER
[CRED065]
-DIRECTOR OF DEVELOPMENT
+VP OF DEVELOPMENT
[CRED066]
JAMIE KING
[CRED067]
-TECHNICAL PRODUCER
+CHIEF TECHNOLOGY OFFICER
[CRED068]
GARY J. FOREMAN
@@ -5362,6 +5176,12 @@ ASSOCIATE PRODUCER
[CRED070]
JEREMY POPE
+[CRD071A]
+DIRECTOR OF QUALITY ASSURANCE
+
+[CRD072A]
+JEFF ROSA
+
[CRED071]
MUSIC SUPERVISOR
@@ -5369,7 +5189,7 @@ MUSIC SUPERVISOR
TERRY DONOVAN
[CRED073]
-ROCKSTAR PRODUCTION TEAM
+PRODUCTION TEAM
[CRED074]
TERRY DONOVAN
@@ -5387,10 +5207,10 @@ LAURA PATERSON
JEFF CASTANEDA
[CRED079]
-CHRIS CARRO
+JERONIMO BARRERA
[CRED080]
-ADAM TEDMAN
+CARLY SLATER
[CRED081]
JUNG KWAK
@@ -5399,28 +5219,67 @@ JUNG KWAK
BRIAN WOOD
[CRED083]
-PAUL YEATES
+RENAUD SEBANNE
[CRED084]
-STANTON SARJEANT
+RICHARD KRUGER
+
+[CRD084A]
+DANIEL EINZIG
+
+[CRD084B]
+JACEN BURROWS
+
+[CRD084C]
+LINN PR
+
+[CRD084D]
+COVER ART
+
+[CRD084E]
+STEPHEN BLISS
[CRED085]
-VP OF MARKETING
+KENT PAUL'S 80 NOSTALGIA ZONE
[CRED086]
-TERRY DONOVAN
+WRITTEN BY DAN HOUSER
+
+[CRD086A]
+PRODUCED BY ADAM TEDMAN
[CRED087]
-TECHNICAL COORDINATOR
+WWW.KENTPAUL.COM AND WWW.VICECITY.COM
[CRED088]
-BRANDON ROSE
+CREATED BY
+
+[CRD088A]
+ADAM TEDMAN
+
+[CRD088B]
+DAVID YU
+
+[CRD088C]
+JERRY LUNA
+
+[CRD088D]
+STUART PETRI
+
+[CRD088E]
+MICHAEL CARNEVALE
+
+[CRD088F]
+GREG LAU
+
+[CRD088G]
+FUTABA HAYASHI
[CRED089]
QA MANAGER
[CRED090]
-JEFF ROSA
+CRAIG ARBUTHNOTT
[CRED091]
LEAD ANALYST
@@ -5428,6 +5287,12 @@ LEAD ANALYST
[CRED092]
ADAM DAVIDSON
+[CRD092A]
+JOE HOWELL
+
+[CRD092B]
+MARC FERNANDEZ
+
[CRED093]
GAME ANALYST
@@ -5435,7 +5300,7 @@ GAME ANALYST
RICHARD HUIE
[CRED095]
-TEST TEAM
+ROCKSTAR TEST TEAM
[CRED096]
LANCE WILLIAMS
@@ -5446,11 +5311,20 @@ JOE GREENE
[CRED098]
BRIAN PLANER
+[CRD098A]
+ELIZABETH SATTERWHITE
+
+[CRD098B]
+JAMEEL VEGA
+
+[CRD098C]
+MIKE HONG
+
[CRED099]
-OSWALD GREENE
+LEE CUMMINGS
[CRED100]
-LIBERTY TREE EDITORIAL
+STORY
[CRED101]
JAMES WORRALL
@@ -5471,88 +5345,121 @@ JENEFER GROSS
LAURA PATERSON
[CRED107]
-CUT-SCENES
+CUT SCENES
[CRED108]
-SCRIPT BY DAN HOUSER AND JAMES WORRALL
+WRITTEN BY DAN HOUSER AND JAMES WORRALL
[CRED109]
-AUDIO DIRECTED BY DAN HOUSER
+AUDIO DIRECTED BY DAN HOUSER AND NAVID KHONSARI
[CRED110]
-AUDIO PRODUCED BY RENAUD SEBBANE
+PRODUCED BY JAMIE KING
+
+[CRD110A]
+TALENT PROCUREMENT: JAMIE KING, SEAN MACALUSO
[CRED111]
CAST
+[CRD111A]
+SUPPORTING CHARACTERS
+
[CRED112]
-FRANK VINCENT AS SALVATORE LEONE
+TOMMY VERCETTI - RAY LIOTTA
[CRED113]
-JOE PANTOLIANO AS LUIGI GOTERELLI
+KEN ROSENBERG - WILLIAN FICHTNER
[CRED114]
-MICHAEL MADSEN AS TONI CIPRIANI
+SONNY FORELLI - TOM SIZEMORE
[CRED115]
-MICHAEL RAPAPORT AS JOEY LEONE
+STEVE SCOTT - DENNIS HOPPER
[CRED116]
-DEBBI MAZAR AS MARIA
+AVERY CARRINGTON - BURT REYNOLDS
[CRED117]
-KYLE MACLACHLAN AS DONALD LOVE
+RICARDO DIAZ - LUIS GUZMAN
[CRED118]
-ROBERT LOGGIA AS RAY MACHOWSKI
+LANCE VANCE - PHILIP MICHAEL THOMAS
[CRED119]
-GURU AS 8-BALL
+COLONEL JUAN CORTEZ - ROBERT DAVI
[CRED120]
-SONDRA JAMES AS MOMMA
+UMBERTO ROBINA - DANNY TREJO
[CRED121]
-LIANA PAI AS ASUKA
+PHIL CASSIDY - GARY BUSEY
[CRED122]
-LES MAU AS KENJI
+MITCH BAKER - LEE MAJORS
[CRED123]
-CYNTHIA FARRELL AS CATALINA
+MERCEDES CORTEZ - FAIRUZA BALK
[CRED124]
-AL ESPINOSA AS MIGUEL
+KENT PAUL - DANNY DYER
[CRED125]
-CHRIS PHILLIPS AS EL BURRO
+JEZZ TORRENT - KEVIN MCKIDD
[CRED126]
-HUNTER PLATIN AS CHICO
+TAXI CONTROLLER - DEBORAH HARRY
[CRED127]
-WALTER MUDU AS D-ICE
+CANDY SUXXX - JENNA JAMESON
[CRED128]
-CURTIS MCCLARIN AS CURTLY
+BJ SMITH - LAWRENCE TAYLOR
[CRED129]
-BILL FIORE AS DARKEL
+AUNTIE POULET - YOUREE CLEOMILI HARRIS
[CRED130]
-CHRIS PHILLIPS AS MARTY CHONKS
+SUPPLIER - ARMANDO RIESCO
[CRED131]
-HUNTER PLATIN AS CURLY BOB
+COUGAR - BLAYNE PERRY
[CRED132]
-WALTER MUDU AS KING COURTNEY
+HILARY - CHARLES TUCKER
[CRED133]
-HUNTER PLATIN AS ONE-ARMED PHIL
+CONGRESSMAN ALEX SHRUB - CHRIS LUCAS
[CRED134]
-KIM GURNEY AS MISTY
+OLD MAN KELLY - GEORGE DICENZO
+
+[CRD134A]
+CAM JONES - GREG SIMS
+
+[CRD134B]
+PSYCHO - HUNTER PLATIN
+
+[CRD134C]
+MAUDE THE ICE CREAM LADY - JANE GENNARO
+
+[CRD134D]
+JETHRO - JOHN ZURHELLEN
+
+[CRD134E]
+GONZALES - JORGE PUPO
+
+[CRD134F]
+DWAYNE - NAVID KHONSARI
+
+[CRD134G]
+DICK - PETER MCKAY
+
+[CRD134H]
+MIKE THE GOON & PORN GUY - ROBERT CIHRA
+
+[CRD134I]
+PERCY - RUSSELL FOREMAN
[CRED135]
MOTION CAPTURE
@@ -5561,145 +5468,169 @@ MOTION CAPTURE
ANIMATED BY
[CRD136A]
-ALEX HORTON
+TECHNICAL DIRECTION BY ALEX HORTON
[CRED137]
DIRECTED BY
[CRD137A]
-NAVID KHONSARI
+DIRECTED BY NAVID KHONSARI
[CRED138]
PRODUCED BY
[CRD138A]
-JAMIE KING
+PRODUCED BY JAMIE KING
[CRD138B]
RENAUD SEBBANE
[CRED139]
-RECORDED AT MODERN UPRISING STUDIOS, BROOKLYN
+RECORDED AT PERSPECTIVE STUDIOS, BROOKLYN
[CRED140]
-ACTORS
+MOTION CAPTURE ACTORS
[CRD140A]
-RENAUD SEBBANE
+BLAYNE PERRY
[CRD140B]
-GISELLE JONES
+JONATHON SALE
[CRD140C]
-STEPHEN DANIELS
+CHARLES TUCKER
[CRD140D]
-ROBERT STIO
+EDDIE MARRERO
[CRD140E]
-JENNY GROSS.
+WILLIAM MCCALL
+
+[CRD140F]
+JORGE PUPO
+
+[CRD140G]
+ROBERT JACKSON
+
+[CRD140H]
+TARA RADCLIFFE
+
+[CRD140I]
+JENIFER GAMBETESE
+
+[CRD140J]
+KRIS ACHEVARRIA
+
+[CRD140K]
+ALI ORDOUBADI
+
+[CRD140L]
+KAHLEEM POOLE
[CRED141]
PEDESTRIAN DIALOGUE
+[CRD141A]
+WRITTEN BY DAN HOUSER, MARC FERNANDEZ, GILLIAN TELLING AND NAVID KHONSARI
+
+[CRD141B]
+WITH HELP FROM JEREMY POPE, LANCE WILLIAMS, AND JENNY JEMISON
+
[CRED142]
-WRITTEN BY DAN HOUSER, NAVID KHONSARI & JAMES WORRALL
+WRITTEN BY
+
+[CRD142A]
+DAN HOUSER AND JAMES WORRALL
[CRED143]
-DIRECTED BY CRAIG CONNER, DAN HOUSER AND LAZLOW
+DIRECTED BY DAN HOUSER, CRAIG CONNER, MARC FERNANDEZ, AND ALLAN WALKER
[CRED144]
-PRODUCED BY RENAUD SEBBANE
+PRODUCED BY RENAUD SEBANNE
[CRED145]
-CAST
+PEDESTRIANS
[CRED146]
-HUNTER PLATIN
+ADAM DAVIDSON, ADAM WATKINS, ALEJANDRO K. BROWN, ALEX ANTHONY SIOUKAS, ALEX GARCIA,
[CRED147]
-DAN HOUSER
+ALICE SALTZMAN, ALISON CIHRA, AMY SALIMA, AMY SALZMAN, ANDREA VIDELA, ANTHONY ATTI,
[CRED148]
-RENAUD SEBBANE
+ANTHONY RIVERA, BIJAN SHAMS, BLAYNE PERRY, BRETT BISOGNO, BREYE MATA, BRIAN PANEN,
[CRED149]
-MARIA CHAMBERS
+BROCK VODER, CAREY BERTINI, CHARISSE LAMBERT, CHRIS DIFAT, CHRIS REISENBERGER,
[CRED150]
-JEFF STANTON
+CHRISTOPHER BRODAY, CHRISTOPHER CARRO, CYNTHIA GREENE, DAMARIES LOPEZ, DAN LEE,
[CRED151]
-RYAN CROY
+DAN SCHNEIDER, DAN TOYAMA, DAVID DEAN CHALTFIELD, JR., DAVID HARRISON, DAVID WILEY,
[CRED152]
-DEENA BERMAN
+DEBORAH COLLINS, DEBRANDA CHANEY-GILES, DEMETRA KOUKOULAS, DENISE ROSADO,
[CRED153]
-MARIA CHAMBERS
+DEVIN BENNETT, DEVIN WINTERBOTTOM, DORIS WOO, DOUGLAS HARRISON, DUNCAN COUTTS,
[CRED154]
-ALICE B. SALTZMAN
+DUPE AJAYI, EDWIN AVELLANEDA, ELIZABETH HOWELL, ELIZABETH SATTERWHITE, ERIC NAGLE,
[CRED155]
-ALEX ANTHONY SIOUKAS
+ESTEBAN KARPLUS, F. FONT, FUTABA HAYASHI, GENE HILGREEN, GERALD COSGROVE,
[CRED156]
-SEAN R. LYNCH
+GERARD LUNA, GILLIAN TELLING, GREGG CARLUCCI, GREGORY CLERVOIX, GREGORY SCHWEIZER,
[CRED157]
-AMY SALZMAN
+HADLEY TOMICKI, J. ROSSETT, JAMEEL VEGA, JASON JONES, JEFF ROSA, JENNIFER JEMISON,
[CRED158]
-COLIN MCSHANE
+JEREMY TAGGERT, JESSICA RIDER, JOSEPH GREENE,JOSEPH HOWELL, KATE DUKICH,
[CRED159]
-COREY WADE
+KEL O'NEILL, KEVIN HOPKINS, LADAWN JAMES, LANCE WILLIAMS, LAURA BUBBLES,
[CRED160]
-GERALD COSGROVE
+LAURA PATTERSON, LEE CUMMINGS, LETICIA L. YOUNG, LINDSAY KENNEDY, LISA ORITZ,
[CRED161]
-STEPHANIE ROY
+LORNA JORDAN, LUCIO AMADIO, MARCO FERNANDEZ, MARIKO TANAKA, MARLON MATTHEWS,
[CRED162]
-DORIS WOO
+MARY TELLING, MASAYOSHI MITSUYAMA, MATTHEW CHUNG, MAX ALLSTADT, MAX BOGDANOV,
[CRED163]
-JOSEPH GREENE
+MELISSA ALVAREZ, MICHAEL MAY, MICHAEL ROTHSTEIN, MIGUEL VIDAL, MIKE FEDERLINE,
[CRED164]
-LAZLOW JONES
+NATALIE DESCALZO, N'GAI MEMBERS, NICOLAS MALLO, NOELLE SADLER, NORBERT MORIVAN,
[CRED165]
-HSIANG LIN
+OSWALD GREENE, JR., PETER MCKAY, PETER APPEL, PRESTON SAVARESE, RAFAEL GONZALES,
[CRED166]
-STEVE MICHAEL ROBERT
+RANDY JOHNSON, REY CONCEPCION, RICHARD KROGER, ROB TIBBS, ROBERT JACKSON,
[CRED167]
-MATHEW MURRAY
+ROBERT SCHULER, ROSS A. MCINTYRE, RUSSELL FOREMAN, RUTH NUNEZ, SALVADORE SUAZO,
[CRED168]
-RICHARD HUIE
+SAM WHITE, SANTOS GONZALES, SCOTT SMITH, SEYMOUR FRAILMAN, SPELMAN BRAUMAN,
[CRED169]
-GARVIN ATWELL
+STEPHANIE TELLING, STEVE KNEZEVICH, STEVE ROBERT, SUMIKO YASUDA, SUSAN LEWIS,
[CRED170]
-STEVE KNEZEVICH
+SYLVIA COLACIOS, TOMOKO MIYAZAKI, TRON, VERDEL HALE, YVES MONDESIR, ZENO LEINFELDER,
[CRED171]
-YUKIMURA SATO
+DAVID BEDDOES, CHRISTINE CHALMERS, BARRY CLARK, NEIL CORBETT, KIM GURNEY, NEIL MEIKLE,
[CRED172]
-FRANK CHAVEZ
-
-[CRED173]
-LIEZL JACINTO
-
-[CRED174]
-CANAAN MCKOY
+CASSIE OLIVER, LORRAINE ROY, DAVID WATSON, KEVIN WONG, WILL MORTON
[CRED175]
ADAM DAVIDSON
@@ -5831,10 +5762,10 @@ SARA SEWELL
RADIO STATIONS AND MUSIC
[CRED218]
-PRODUCERS FOR ROCKSTAR UK
+MUSIC CONSULTANCY
[CRD218A]
-CRAIG CONNER
+HEINZ HENN
[CRD218B]
STUART ROSS
@@ -5849,10 +5780,10 @@ TERRY DONOVAN
PRODUCER FOR ROCKSTAR GAMES
[CRED222]
-DAN HOUSER
+DAN HOUSER AND LAZLOW
[CRED223]
-EDITED BY
+PRODUCER FOR ROCKSTAR NORTH
[CRED224]
CRAIG CONNER
@@ -5864,1033 +5795,1070 @@ ALLAN WALKER
LAZLOW
[CRED227]
-DJ BANTER AND IMAGING WRITTEN BY
+DJ BANTER AND IMAGING
[CRED228]
-DAN HOUSER
+WRITTEN BY DAN HOUSER AND LAZLOW
[CRED229]
-LAZLOW
+FLASH FM
+
+[CRD229A]
+TONI-MARIA CHAMBERS
+
+[CRD229B]
+IMAGING VOICE AND PRODUCTION-JEFF BERLIN
[CRED230]
SPECIAL THANKS TO
[CRED231]
-ADAM TEDMAN
+TOMMY MOTTOLA,
[CRED232]
-ALEX MASON
+MICHELLE ANTHONY,
[CRED233]
-JUDY HENDERSON CASTING
+STEVE BARNETT,
[CRED234]
-HAMISH BROWN
+CHUCK FLECKENSTEIN,
[CRED235]
-CHRISSY HOBAN
+RITA LIBERATOR
[CRED236]
-INNES RICARD
+MARTIN & CLAIRE LOGAN
[CRED237]
-LILION BROZSKA
+SANDRA HUTTON
[CRED238]
-BOB HILLARY
+CHRISTINE DAVIDSON
[CRED239]
-EMILY ANDERSON
+ALAN, RED & BIGFOOT
[CRED240]
-RICHIE HENDERSON
+LE T
[CRED241]
-CHRSTIAN CANTAMESSA
+COLIN DONALD
[CRED242]
-JERONIMO BARRERA
+KERRY STALLWOOD
[CRED243]
-ALEXANDER ILLES
+ALAN MCGREGOR
[CRED244]
-BARANE CHAN
+CHRIS MORTON
[CRED245]
-DUNCAN SHIELDS
+EMIL BUSSE
[CRED246]
-BARANE CHAN
+EMILY BAILLIE
[CRED247]
-DEREK PAYNE
+KEVIN ARCHIBALD
[CRED248]
-KEVIN WONG
+MORAG KERR
[CRED249]
-ROSS ELLIOTT
+CATH WALKER
[CRED250]
-ROSS BEAZLEY
+ISO BAR
[CRED251]
-ALEX BAZLINTON
+WATERLINE
[CRED252]
-DAVE WATSON
+NEWS CAFE
+
+[CRD251A]
+THE POND
+
+[CRD252A]
+PIVO
[CRED253]
-MALCOLM SMITH
+BUDGET VIDEO RENTALS
+
+[CRED254]
+LORNA'S SCOOTER
[CRED255]
-ANDREW SEMPLE
+GARETH MURFIN
[CRED256]
-ARTIST
+ADDITIONAL ART
[CRED257]
-STUART PETRI
+TONY PORTER
[CRED258]
-JERONIMO BARRERA
+CRAIG MOORE
[CRED259]
-CARLY SLATER
+CUT SCENE LIP-SYNC ANIMATION
[CRED260]
-GREG LAU
+COSGROVE HALL FILMS
[CRED261]
-STEVE KNEZEVICH
+PRODUCER - OWEN BALLHATCHET
[CRED262]
-DEVIN WINTERBOTTOM
+SENIOR ANIMATOR - JON TURNER
[CRED263]
-JAMEEL VEGA
+ANIMATORS - RICHARD DRUMM
[CRED264]
-LEE CUMMINGS
+DAVE BROWN
[CRED265]
-DEVIN BENNET
+MAIR THOMAS
[CRED266]
-ELIZABETH SATTERWHITE
+PRASHANT PATEL
[CRED267]
-AARON RIGBY
+AUDIO TECHNOLOGY CONSULTANT
[CRED268]
-STEVE K.
+RIK EDE FOR GAMESOUND LTD.
[CRED269]
-GREG LAU
+DTS INTEGRATION SUPPORT
[CRED270]
-MIKE HONG
+TED LAVERTY FOR DTS
-[CINCAM]
-Cinematic Camera
+[CRED271]
+CHRIS GREER FOR DTS
-[KM1_13]
-Drive the vehicle into the garage!
+[CRED272]
+JASON PAGE FOR SCEE
-[KM3_14]
-~r~You have been spotted the deal is off!
+[CRED273]
+RESEARCH AND ANALYSIS
-[EBAL_H]
-Wait here man while I go in and talk to Luigi.
+[CRED274]
+VROCK
-[EBAL_M]
-Remember no one messes with my girls!
+[CRED275]
+DJ: LAZLOW AS HIMSELF
-[LM2_F]
-Then take his car, respray it.
+[CRED276]
+IMAGING VOICE-JOE KELLY
-[LM2_D]
-here, here take it.
+[CRED277]
+IMAGING PRODUCTION-JONATHAN HANST
-[LM1_9]
-Hi I'm Misty.
+[CRED278]
+WAVE 103
-[LM4_A]
-Some Diablo scumbag has been pimping his skuzzy bitches in my backyard.
+[CRED279]
+DJ: ADAM FIRST-JAMIE CANFIELD
-[FM2_B]
-We got us a rat!
+[CRED280]
+IMAGING VOICE-JEN SWEENEY
-[FM2_C]
-He ain't pimpin' or pushin' so he must be talking.
+[CRED281]
+IMAGING PRODUCTION-JONATHAN HANST
-[FM3_CC]
-~w~Come back brother when you have the money.
+[CRED282]
+FEVER 105
-[FEDS_AM]
-<>-CHANGE MENU
+[CRED283]
+DJ: OLIVER 'LADYKILLER' BISCUIT-JULIUS DYSON
-[LOVE5_5]
-~r~You failed to protect the truck!
+[CRED284]
+IMAGING VOICE MALE-ED MCMANN
-[RM6_6]
-~r~Ray is dead!
+[CRED285]
+IMAGING VOICE FEMALE-SHAWNEE SMITH
-[RM6_7]
-~r~Ray has missed his flight.
+[CRED286]
+IMAGING PRODUCTION- LISTEN KITCHEN
-[RM6_8]
-~g~You have left Ray behind, go back and get him.
+[CRED287]
+EMOTION 98.3
-[FM1_10]
-~g~You have left Maria behind, go back and pick her up.
+[CRED288]
+DJ: FERNANDO- FRANK CHAVEZ
-[LOVE4_9]
-~r~The plane has been destroyed!
+[CRED289]
+IMAGING VOICE-JEN SWEENEY
-[LOV4_10]
-~r~The only lead to where the package has gone has been destroyed!
+[CRED290]
+IMAGING PRODUCTION-JONATHAN HANST
-[KM2_D]
-Needless to say, we must give him the cars as a gift, to repay the debt that I owe him.
+[CRED291]
+RADIO ESPANTOSO
-[KM4_B]
-The business's fortunate enough to have our protection settle their accounts today.
+[CRED292]
+DJ: PEPE-TONY CHILRODES
-[KM2_E]
-You must obtain the cars on this list and deliver them to a garage behind the car park in Newport.
+[CRED293]
+WILDSTYLE
-[FM3_8I]
-~w~Get a good vantage point then I'll head in when you fire the first shot.
+[CRED294]
+DJ: MISTER MAGIC AS HIMSELF
-[LOVE1_B]
-Experience has taught me that a man like you can be very loyal for the right price,
+[CRED295]
+IMAGING VOICE-FRANK SILVESTRO
-[LOVE1_H]
-but groups of men get greedy.
+[CRED296]
+IMAGING PRODUCTION-LAZLOW
-[LOVE1_C]
-A valued resource, an old oriental gentleman I know,
+[CRED297]
+KCHAT
-[LOVE1_I]
-has been kept hostage by some South Americans in Aspatria.
+[CRED298]
+WRITTEN BY DAN HOUSER AND LAZLOW
-[MEA4_D]
-I've agreed to see him...
+[CRED299]
+PRODUCED AND EDITED BY LAZLOW
-[MEA4_B4]
-Marty sent you huh? OK, I'm gonna show that creep the meaning of the word business.
+[CRED300]
+DJ AMY SHECKENHAUSEN -LEYNA WEBER
-[MEA4_B5]
-Carl, hi! i eerr, I need more time to get your money.
+[CRED301]
+JEZ TORRENT-KEVIN MCKIDD
-[MEA1_B4]
-Ah, Mr Chonks sent you did he. Let's go and pay the fellow a visit.
+[CRED302]
+MANDY -COLLEEN CORBETT
-[HM5_6]
-Let's go crack some skulls...
+[CRED303]
+MICHELLE CARAPADIS-MARY BIRDSONG
-[LOVE1_5]
-~g~Stop hanging around, get a Colombian Gang car and rescue Love's associate.
+[CRED304]
+MR.ZOO-CARL DOWLING
-[AS1_D]
-~w~Act as the bait, and get the death squads to follow you to Pike Creek
+[CRED305]
+GETHSEMANEE-LYNN LIPTON
-[AS1_E]
-~w~where some of my men will be waiting for them.
+[CRED306]
+CLAUDE MAGINOT-JOHN MAUCERI
-[AS2_C]
-~w~The Cartel have a front company, The Kappa Coffee House.
+[CRED307]
+BJ SMITH-LAWRENCE TAYLOR
-[AS2_E]
-~w~We have no choice but to put these drug stands out of operation.
+[CRED308]
+THOR-FRANK FAVA
-[AS2_F]
-~w~Smash them to splinters!!
+[CRED309]
+RADIO CALLERS
-[AS2_A1]
-~w~Miguel certainly has some of that famous Latin stamina.
+[CRED310]
+COUZIN ED, JOSH CLARK, JASON BUHRMESTER, JUAN ALLER, WAYNE OLIVER, SUSAN LEWIS, GILLIAN TELLING, TOM MURRAY, MIKE FERRANTE SR., EMMANUEL GOLDSTEIN, DAN HOUSER, NICK MANDELOS, GERRY COSGROVE, MIKE PALERMO, PORKCHOP, KEITH BROADAS
-[AS2_A2]
-~w~I'm quite exhausted.
+[CRED311]
+LEWIS, GILLIAN TELLING, TOM MURRAY, MIKE FERRANTE SR., EMMANUEL GOLDSTEIN,
-[SIREN_3]
-To turn on this vehicle's sirens tap the ~h~~k~~VEHICLE_HORN~ button~w~.
+[CRED312]
+DAN HOUSER, NICK MANDELOS, GERRY COSGROVE, MIKE PALERMO, PORKCHOP,
-[SIREN_4]
-To turn on this vehicle's sirens tap the ~h~~k~~VEHICLE_HORN~ button~w~.
+[CRED313]
+KEITH BROADAS
-[AS3_C]
-~w~Eeeeeeyoooo! What IS that gooey yellow stuff?
+[CRED314]
+VCPR
-[AS3_C1]
-~w~Oh hi Babe.
+[CRED315]
+WRITTEN BY DAN HOUSER AND LAZLOW
-[AS3_F]
-~w~She's got the makings of a natural this girl.
+[CRED316]
+PRODUCED BY LAZLOW
-[AS3_F1]
-~w~She's managed to extract this little gem from our guest.
+[CRED317]
+MAURICE CHAVEZ-PHILLIP ANTHONY RODRIGUEZ
-[AS3_G]
-~w~There is a plane coming into Francis International in 2 hours time.
+[CRED318]
+JONATHAN FREELOADER- PATRICK OLSEN
-[AS3_G1]
-~w~It is full of Catalina's poison.
+[CRED319]
+MICHELLE MONTANIUS-KELLY GUEST
-[AS3_H]
-~w~You can avoid airport security by getting a boat out to the runway-light buoys
+[CRED320]
+REP. ALEX SHRUB- CHRIS LUCAS
-[AS3_H1]
-and shooting the plane down on its approach.
+[CRED321]
+CALLUM CRAYSHAW- SEAN MODICA
-[AS3_I]
-~w~Collect the cargo from the debris and stash it!
+[CRED322]
+JOHN F. HICKORY- LJ GANSEN
-[AS3_J]
-~w~Oh you be careful now, OK baby?
+[CRED323]
+PASTOR RICHARDS- DAVID GREEN
-[AS3_K]
-~w~Now try the chilli oil.....
+[CRED324]
+JAN BROWN- MAUREEN SILLIMAN
-[RM2_F1]
-Those Colombians'll be here any minute!
+[CRED325]
+BARRY STARK- RENAUD SEBBANE
-[RM2_K]
-Goddam they're here!! LOCK'N'LOAD!!
+[CRED326]
+JENNY LOUISE CRAB- MARY BIRDSONG
-[LOVE2_7]
-~g~Now dump the car!
+[CRED327]
+KONSTANTINOS SMITH- KONSTANTINOS.COM
-[LOVE2_8]
-~g~Now get out of Newport!
+[CRED328]
+JEREMY ROBARD-PETER SILVESTRO
-[AM1_F]
-Salvatore Leone will be leaving Luigi's in about three hours time. (~1~:~1~)
+[CRED329]
+RADIO COMMERCIALS
-[LOVE5_C]
-I want you to follow him, and make sure both he and my package get to Pike Creek unharmed.
+[CRED330]
+WRITTEN BY DAN HOUSER AND LAZLOW
-[FESZ_SR]
-Save Failed! Check Memory Card (PS2) in MEMORY CARD slot 1 and please try again.
+[CRED331]
+PRODUCED BY LAZLOW
-[FESZ_FO]
-Would you like to format the Memory Card (PS2) in MEMORY CARD slot 1?
+[CRED332]
+ADDITIONAL JINGLES PRODUCED BY CRAIG CONNER
-[FELZ_FO]
-Memory Card (PS2) in MEMORY CARD slot 1 is unformatted.
+[CRED333]
+COMMERCIAL VOICES:
-[FES_NOC]
-No Memory Card (PS2) in MEMORY CARD slot 1.
+[CRED334]
+ADAM DAVIDSON, ALEX ANTHONY, ALICE SALTZMAN, AMY SALZMAN, KATE DUKICH,
-[FES_LOE]
-Load Failed! Check Memory Card (PS2) in MEMORY CARD slot 1 and please try again.
+[CRED335]
+ARAN RONICLE, BARB JONES, BEN KRECH, BRIAN THOMAS, BROCK YODER, CHRIS
-[FES_DEE]
-Deleting Failed! Check Memory Card (PS2) in MEMORY CARD slot 1 and please try again.
+[CRED336]
+FERRANTE, CRAIG CONNER, DAVE RYAN, DAVID GREEN, DORIS WOO, DOUGLAS
-[SLONFM]
-Error formatting Memory Card (PS2) in MEMORY CARD slot 1.
+[CRED337]
+HARRISON, ED MCMANN, FRANK CHAVEZ, FRANK FAVA, GENE HILGREEN, GREG
-[SLONDR]
-Insufficient space to save. Please insert a Memory Card (PS2) with at least 500KB of free space available into MEMORY CARD slot 1.
+[CRED338]
+SCHWEIZER, HUNTER PLATIN, JAMES FERRANTE, JEFF BERLIN, JEFF ROSA, JOE KELLY,
-[SLNSP]
-Insufficient space to save. Please insert a Memory Card (PS2) with at least 200KB of free space available into MEMORY CARD slot 1.
+[CRED339]
+JOHN MAUCERI, JOSH CLARK, JULIE WEMYSS, KEVIN STRALEY, KIM GURNEY, LANCE
-[FEFD_WR]
-Formatting Memory Card (PS2) in MEMORY CARD slot 1. Please do not remove the Memory Card (PS2), reset or switch off the console.
+[CRED340]
+WILLIAMS, LAURA PATERSON, LAZLOW, LISA ORTIZ, LORNA JORDAN, LUCIEN JONES,
-[FES_ISF]
-NOT PRESENT
+[CRED341]
+MAUREEN SILLIMAN, MIKE FERRANTE JR., PETE GUSTIN, PETER SILVESTRO, RAFF
-[FES_SAG]
-PRESENT
+[CRED342]
+CROLLA, RANDY JOHNSON, RICHARD KRUGER, RON REEVE, SHELLEY MILLER, SKY, TJ ALLARD
-[SLONNO]
-No Memory Card (PS2) in MEMORY CARD slot 1.
+[CRD344A]
+AUDIO RECORDED AT DIGITAL ARTS STUDIOS,
-[SLONNF]
-Memory Card (PS2) in MEMORY CARD slot 1 is unformatted.
+[CRED344]
+NYC, TRACK 9 STUDIOS, NYC,
-[FESZ_FM]
-Memory Card (PS2) in MEMORY CARD slot 1 is unformatted. Would you like to format Memory Card (PS2) in MEMORY CARD slot 1?
+[CRED345]
+WEDDINGTON MULTIMEDIA, LOS ANGELES,
-[FESZ_FF]
-Format Failed! Check Memory Card (PS2) in MEMORY CARD slot 1 and please try again.
+[CRD345A]
+SYNC SOUND, NYC AND RADIO LAZLOW, LONG ISLAND.
-[MCDNSP]
-There is insufficient space on the Memory Card (PS2) in MEMORY CARD slot 1. At least 500KB is needed to save this application data. Do you wish to start? (YES or NO)
+[CRED346]
+THANKS TO AXEL ERICSON AND WON LEE AT DIGITAL ARTS, PAUL VASQUEZ AT TRACK 9 STUDIOS, JOHN BOWEN AND JOHN HASSLER AT SYNC SOUND
-[MCGNSP]
-There is insufficient space on the Memory Card (PS2) in MEMORY CARD slot 1. At least 200KB is needed to save this application data. Do you wish to start? (YES or NO)
+[CRED347]
+MARK LLOYD
-[FESZ_WR]
-Saving data. Please do not remove the Memory Card (PS2) in MEMORY CARD slot 1, reset or switch off the console.
+[CRED348]
+TIM BATES
-[FESZ_OW]
-Overwriting data. Please do not remove the Memory Card (PS2) in MEMORY CARD slot 1, reset or switch off the console.
+[CRED349]
+KIT BROWN
-[FELD_WR]
-Loading data. Please do not remove the Memory Card (PS2) in MEMORY CARD slot 1, reset or switch off the console.
+[CRED350]
+ANDY MASON
-[FEDL_WR]
-Deleting data. Please do not remove the Memory Card (PS2) in MEMORY CARD slot 1, reset or switch off the console.
+[CRED351]
+PHIL DEANE
-[LM2_C]
-Luigi said to, to give you this so...
+[CRED352]
+PHIL ALEXANDER
-[LM3_G]
-Joey ain't the kind you keep waiting, remember, this is your foot in the door...
+[CRED353]
+MATT HEWITT
-[LM5_E]
-Get as many of them as you can before the cops drink away their green.
+[CRED354]
+DENBY GRACE
-[JM5_C]
-Alright, there's a car stuffed with a stiff at the cafe near Callahan Point.
+[CRED355]
+ANTOINE CABROL
-[RM2_B]
-We saw action in Nicaragua, back when the country knew what it was doing.
+[CRED356]
+JONOTHAN STONES
-[RM2_C]
-Some Cartel scum roughed him up yesterday, said they'd be back for some of his stock today.
+[CRED357]
+MIKE BLACKBURN
-[RM2_D1]
-I'd go myself but the old sciatica's playing up again -cough cough- so, eerr-hhrrmmm, good luck.
+[CRED358]
+TIM MCGAFF
-[CATINF1]
-~g~Get Catalina!
+[SUNSHIN]
+Sunshine Autos
-[CATINF2]
-~g~Follow the chopper to find Catalina.
+[CHERRYP]
+Cherry Popper Icecreams
-[BOATIN1]
-Jump into a boat and press the ~h~~k~~VEHICLE_ENTER_EXIT~ button ~w~to get in.
+[KAUFCAB]
+Kaufman Cabs
-[BOATIN2]
-You can press the ~h~~k~~VEHICLE_ENTER_EXIT~ button ~w~if you are near a boat to get in it.
+[BOATYAR]
+The Boatyard
-[BOATIN3]
-Jump into a boat and press the ~h~~k~~VEHICLE_ENTER_EXIT~ button ~w~to get in.
+[WANT_L]
+Your wanted level has been suspended, if you commit a crime whilst the stars are flashing your full wanted level will be reinstated.
-[BOATIN4]
-You can press the ~h~~k~~VEHICLE_ENTER_EXIT~ button ~w~if you are near a boat to get in it.
+[PICK1]
+Body Armor delivered to Ocean View Hotel!
-[JM6]
-'THE GETAWAY'
+[HOTRNG]
+HOTRING
-[FM1]
-'CHAPERONE'
+[BLODRNG]
+BLOODRING
-[JM1]
-'MIKE LIPS LAST LUNCH'
+[DIRTRNG]
+DIRTRING
-[FM21]
-'BOMB DA BASE: ACT I'
+[FEC_ABR]
+Accelerate, Brake or Reverse
-[FM3]
-'BOMB DA BASE: ACT II'
+[FEI_BTU]
+; = -
-[AM1]
-'SAYONARA SALVATORE'
+[FEI_SCR]
+Scroll
-[AM2]
-'UNDER SURVEILLANCE'
+[SKUMBUY]
+Skumole Shack purchased: $~1~
-[KM2]
-'GRAND THEFT AUTO'
+[SKUM_L]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase Skumole Shack for $~1~
-[AS3]
-'S.A.M.'
+[SKUM_T]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase Skumole Shack for $~1~
-[RM2]
-'ARMS SHORTAGE'
+[SKUM_C]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to purchase Skumole Shack for $~1~
-[LOVE6]
-'DECOY'
+[LG_35]
+Destination
-[LOVE1]
-'LIBERATOR'
+[BOAT_AS]
+~g~The Boatyard will now generate revenue up to a maximum of $~1~. Make sure you collect it regularly.
-[RC1]
-'DIABLO DESTRUCTION'
+[BOAT_A2]
+BOATYARD ASSET COMPLETED
-[RC2]
-'MAFIA MASSACRE'
+[BOAT_N]
+Checkpoint Charlie
-[RC3]
-'CASINO CALAMITY'
+[BOAT_P]
+~g~collect the packages before the time runs out.
-[RC4]
-'RUMPO RAMPAGE'
+[FEI_R1B]
+R1 \ R2 button -
-[RM2_E1]
-I can't believe those yellow-bellied bastards left me without proper cover again!
+[HELP9_A]
+Press the~h~ ~k~~PED_FIREWEAPON~ button ~w~to ~h~fire~w~ the sniper rifle.
-[GREN_1]
-The longer you hold the ~h~~k~~PED_FIREWEAPON~ button~w~, the further you will throw the grenade.
+[HELP21]
+Press the ~h~~k~~VEHICLE_ENTER_EXIT~ ~w~button to enter or exit a vehicle.
-[GREN_2]
-The longer you hold the ~h~~k~~PED_FIREWEAPON~ button~w~, the further you will throw the grenade.
+[CREAM]
+Distribution
-[GREN_3]
-The longer you hold the ~h~~k~~PED_FIREWEAPON~ button~w~, the further you will throw the grenade.
+[UMBERTO]
+Cafe Robina
-[LOVE4_G]
-My property will be waiting for you at the customs hanger in the aircraft's fuselage.
+[PU_CF1]
+Press the ~h~~k~~PED_ANSWER_PHONE~ ~w~button to pick up this weapon. It will replace any weapon you have of the same type.
-[KABOOM]
-KABOOOM!
+[FED_RDM]
+MAP & BLIPS
-[SPLAT]
-SPLAT!
+[FEC_ILU]
+Invert Look in 1st Person
-[PANCAK]
-PANCAKED!
+[NITRO]
+All taxi's now have a boost jump! Just press the horn button.
-[SOAKED]
-SOAKED!
+[RATNG53]
+Untrustworthy
-[HEAD]
-Head Radio
+[RATNG54]
+Embarrassment
-[DBL_CLF]
-Double Clef FM
+[RATNG55]
+Hacker
-[FLASHB]
-Flashback FM
+[RATNG56]
+Cheater
-[RISE]
-Rise FM
+[RATNG57]
+Total Liar
-[LIPS]
-Lips 106
+[STHC_04]
+Highest score with Keepie-Uppy beach ball
-[CHAT]
-Chatterbox FM
+[STHC_05]
+Hotring Best Result
-[K_JAH]
-K-Jah Radio
+[STFT_13]
+Fastest time on Downtown Chopper Checkpoint
-[GAM_FM]
-Game Radio FM
+[STFT_14]
+Fastest time on Ocean Beach Chopper Checkpoint
-[MSX_FM]
-MSX FM
+[STFT_15]
+Fastest time on Vice Point Chopper Checkpoint
-[TUBE1]
-When the subway opens you will be able to catch a train to Staunton Island.
+[STFT_16]
+Fastest time on Little Haiti Chopper Checkpoint
-[TUBE2]
-When Shoreside Vale opens you will be able to Exit Shoreside Terminal to Francis International Airport.
+[STFT_21]
+Fastest time in Hotring
-[TUBE_2]
-To board a subway train, press the ~h~'enter vehicle' button~w~.
+[STFT_22]
+Fastest lap time in Hotring
-[LEGAL]
-~g~Eliminate the criminal threat!
+[STFT_20]
+Fastest time for 'Cone Crazy'
-[GA_2]
-New engine and paint job. The cops won't recognize you!
+[HELP44]
+Stop in the ~q~pink marker.
-[LM1_8A]
-To earn some extra cash, why not 'borrow' a taxi...
+[HELP45]
+Press the ~h~~k~~PED_DUCK~~w~ button to duck. This will increase the accuracy of guns you are holding.
-[TAXIH1]
-Stop near a highlighted pedestrian to pick them up then drive them to their destination before the time runs out.
+[RCR1_5]
+RC Bandit Race
-[LM5_7]
-~g~Less than four girls working the ~p~Fuzz Ball~g~ and Luigi won't be happy!
+[RCPL1_7]
+RC Baron Race
-[KM2_3]
-~g~Remember the ~r~cars~g~ have to be in mint condition to be accepted by the ~p~garage~g~.
+[RCH1_11]
+RC Raider Pickup
-[KM5_2]
-~g~A Yardie is off the streets.
+[FEA_CTD]
+Warning! This feature requires DTS compatible hardware to be connected. Proceed?
-[BETRA_A]
-Sorry, babe.
+[FEM_STE]
+USE STEREO
-[BETRA_B]
-I'm an ambitious girl and you,
+[GREET]
+Greetings from...
-[BETRA_C]
-you're just small time.
+[LANCE_1]
+Come on man, drive more careful!
-[JAILB_C]
-*
+[LANCE_2]
+Hey watch what you're doin!
-[JAILB_D]
-*
+[LANCE_3]
+Hey where are we goin' now?
-[JAILB_E]
-*
+[LANCE_4]
+What are we doin' now?
-[JAILB_F]
-*
+[LAW4_15]
+More money!
-[JAILB_G]
-*
+[MERC_5]
+Nice car, Mr. Vercetti.
-[JAILB_H]
-*
+[MERC_26]
+FASTER, FASTER, FASTER!
-[JAILB_I]
-*
+[MERC_27]
+Careful, Tommy, I only have a nose job last month.
-[JAILB_J]
-*
+[MERC_28]
+Tommy, drive careful.
-[JAILB_P]
-*
+[MERC_29]
+Tommy, go slower.
-[JAILB_Q]
-Come on!
+[MERC_30]
+Tommy, please kill someone other than me.
-[JAILB_R]
-Senor dickhead!
+[MERC_31]
+Tommy, baby, don't kill me!
-[JAILB_S]
-It's no problem to kill you.
+[MERC_32]
+Tommy, I'm glad you stole this car!
-[JAILB_T]
-You gonna be sorry.
+[MERC_40]
+I had so much fun.
-[JAILB_U]
-A'right, a'right. Get lost.
+[MERC_43]
+Adios, angel.
-[HELP15]
-When on foot press the ~h~~k~~PED_LOOKBEHIND~ button~w~ to ~h~look behind~w~.
+[MERC_44]
+You keep working out, now, you hear.
-[FEC_LB3]
-Look behind
+[MERC_45]
+Ciao, beautiful.
-[FEC_R3]
-(R3 button)
+[COL5_17]
+Oh my god they've got a helicopter!
-[FES_AFO]
-This Memory Card (PS2) is already formatted.
+[COL5_18]
+Shoot the helicopter!
-[FEA_UP]
-;
+[COL5_19]
+Tommy, take that chopper out!
-[FEA_DO]
-=
+[COL5_20]
+He's coming again! Blow that chopper!
-[FEA_LE]
-<
+[COL5_21]
+Look at the size of that chopper!
-[FEA_RI]
->
+[COL5_22]
+Here he comes again!
-[FEDSAS3]
-- CHANGE SELECTION
+[FEA_DSM]
+Warning! This savegame is set to use DTS. This requires DTS compatible hardware to be connected. Please select whether you want to proceed using DTS or STEREO output.
-[FEDSAS4]
-;=<> - CHANGE SELECTION
+[STFT_23]
+Fastest time for Checkpoint Charlie
-[SPRAY_4] { re3 change }
-Use the ~h~~k~~VEHICLE_FIREWEAPON~ button ~w~to fire the water cannon.
+[HELP50]
+Press the ~h~~k~~PED_ANSWER_PHONE~~w~ button to set the camera behind you.
-[SPRAY_1] { re3 change }
-Use the ~h~~k~~VEHICLE_FIREWEAPON~ button ~w~to fire the water cannon.
+[HELP51]
+Press the ~h~~k~~PED_ANSWER_PHONE~~w~ button to set the camera behind you.
-[LITTLE]
-LITTLE T
+[HELP52]
+Press the ~h~~k~~PED_ANSWER_PHONE~~w~ button to set the camera behind you.
-[NICK]
-NICK LOVE
+[HELP53]
+Press ~h~~k~~PED_CYCLE_WEAPON_LEFT~~w~ button or ~h~~k~~PED_CYCLE_WEAPON_RIGHT~~w~ button to cycle through your available weapons.
-[AM1_10]
-~g~Salvatore will be leaving Luigi's at about 0~1~:~1~
+[HELP46]
+There are eight different types of weapon.
-[JAILB_V]
-*
+[HELP47]
+You can carry one of each type of weapon at a time - one type of pistol, one type of shotgun.
-[JAILB_A]
-*
+[HELP54]
+~w~Cost: $~1~ ~r~Buying this will replace your current weapon.
-[JAILB_B]
-*
+[HELP2A2]
+Press the ~h~~k~~PED_SPRINT~~w~ button when running to ~h~sprint
-[JAILB_W]
-*
+[HLPSN_A]
+The sniper rifle allows you to zoom in and fire accurately at targets from a distance.
-[JAILB_K]
-*
+[HLPSN_B]
+Press and hold the~h~ ~k~~PED_LOCK_TARGET~ ~w~button to ~h~target~w~ with the sniper rifle.
-[JAILB_L]
-*
+[HLPSN_C]
+Press and hold the~h~ ~k~~PED_LOCK_TARGET~ ~w~button to ~h~target~w~ with the sniper rifle.
-[JAILB_M]
-*
+[HLPSN_D]
+Press the ~h~~k~~PED_SNIPER_ZOOM_IN~~w~ button ~w~to ~h~zoom in ~w~with the rifle and the~h~ ~k~~PED_SNIPER_ZOOM_OUT~ button ~w~to ~h~zoom out ~w~again.
-[JAILB_N]
-*
+[HLPSN_E]
+Press the ~h~~k~~PED_FIREWEAPON~~w~ button ~w~to ~h~fire~w~ the sniper rifle.
-[JAILB_O]
-*
+[HLPSN_F]
+Press the ~h~~k~~PED_FIREWEAPON~~w~ button ~w~to ~h~fire~w~ the sniper rifle.
-[JAILB_X]
-*
+[HLPSN_G]
+Press the ~h~~k~~PED_FIREWEAPON~~w~ button to ~h~fire~w~ the sniper rifle.
-[FEDS_SE]
-/ button - SELECT
+[PLANE_H]
+Use the ~h~~k~~VEHICLE_ACCELERATE~~w~ button to accelerate, Left and right to turn.
-[FEDS_SB]
-/ button - SELECT " button - BACK
+[PLANE_4] { reVC update }
+{ Use the ~h~~k~~VEHICLE_ACCELERATE~~w~ button to accelerate, Left and right to turn. }
+Use the right analog stick to accelerate, pull back on the left analog stick to climb, push forwards to descend. Left and right to turn.
-[TM4_A]
-~w~Oh it's you. TONI ain't here.
+[HELP55]
+Press the ~h~~k~~PED_FIREWEAPON~~w~ button to attack the chef.
-[TM4_A2]
-~w~But he left one of his sugary love letters for you.
+[STPR_8]
+Pole Position Club
-[DIAB2_A]
-I started my exotic entertainment business with nothing but the sizeable contents of my leather pants!
+[STPR_9]
+3321 Vice Point
-[LM5_9]
-GIRLS:
+[STPR_10]
+Links View Apartment
-[PERPIC]
-Hidden Packages found
+[STPR_11]
+El Swanko Casa
-[CO_ONE]
-Hidden Package ~1~ of ~1~
+[STPR_12]
+1102 Washington Street
-[LOVE3_3]
-~g~The plane has dropped ~1~ of 6 packages.
+[STPR_13]
+Ocean Heights Apartment
-[FARE11]
-~g~Destination ~w~'Construction site' ~g~in Fort staunton.
+[STPR_14]
+Skumole Shack
-[GA_21]
-You cannot store any more cars in this garage.
+[STPR_15]
+Hyman Condo
-[CHEAT1]
-Cheat activated
+[RCCANX]
+~r~RC plane cancelled.
-[CHEAT2]
-Weapon cheat
+[CLT_HL2]
+When a Clothes Pickup is collected, a one star or two star wanted level will be cleared.
-[CHEAT3]
-Health cheat
+[CRED009]
+MISSION DESIGN
-[CHEAT4]
-Armor cheat
+[CRED359]
+LEE JOHNSON
-[CHEAT5]
-Wanted level cheat
+[CRED360]
+HENDRIK LESSER
-[CHEAT6]
-Money cheat
+[CRED361]
+PASQUALE STACCHIOTTI
-[CHEAT7]
-Weather cheat
+[CRED362]
+ENRIQUE FERNANDEZ
-[AS1_H]
-~r~You failed to lead the Deathsquad into the Yakuza trap!!
+[CRED363]
+PAUL BYERS
-[FEDS_BA]
-" button - BACK
+[CRED364]
+MIKE EMENY
-[RAMP_A]
-ALL RAMPAGES COMPLETED!
+[CRED365]
+ROB DUNKIN
-[USJ_ALL]
-ALL UNIQUE STUNTS COMPLETED!
+[CRED366]
+CHARLIE KINLOCH
-[FARE23]
-~g~Destination ~w~'import export garage' ~g~in Cochrane Dam district
+[CRED367]
+KEVIN HOBSON
-[L_TRN_1]
-You can ride the L-train around Portland. Press the~h~ ~k~~VEHICLE_ENTER_EXIT~ button~w~ to ~h~enter ~w~or ~h~exit~w~ a train.
+[CRED368]
+JIM CREE
-[L_TRN_2]
-You can ride the L-train around Portland. Press the~h~ ~k~~VEHICLE_ENTER_EXIT~ button~w~ to ~h~enter ~w~or ~h~exit~w~ a train.
+[MOB_66A]
+Tommy, Tommy why you coming back here for?
-[S_TRN_1]
-You can take the subway trains across Liberty. Press the~h~ ~k~~VEHICLE_ENTER_EXIT~ button~w~ to ~h~enter ~w~or ~h~exit~w~ a train.
+[MOB_66B]
+I tell you we don't want to see you around here no more.
-[S_TRN_2]
-You can take the subway trains across Liberty. Press the~h~ ~k~~VEHICLE_ENTER_EXIT~ button~w~ to ~h~enter ~w~or ~h~exit~w~ a train.
+[MOB_67A]
+Tommy, me thinks you should be staying away, you hear?
-[AS1_C]
-~w~She has three death squads dotted around Liberty, whose sole job is to hunt you down.
+[MOB_67B]
+The Haitian boys not too 'appy with you.
-[AS1_G]
-~r~All the Yakuza are dead!!
+[MOB_18A]
+Tommy, it's Paulo, how are you? Right mate, anyway, thought I had to drop you a line.
-[JAN]
-Jan
+[MOB_18B]
+Oh my good lord, my son, you will not believe the quality of the brass I just encountered.
-[FEB]
-Feb
+[MOB_18C]
+Street walker or something, just down in Little Havana, mate.
-[MAR]
-Mar
+[MOB_18D]
+Said her name was Mercedes or something.
-[APR]
-Apr
+[MOB_18E]
+Oh my god, mate. You gotta check this bird out.
-[MAY]
-May
+[MOB_18F]
+Could strip the lead out of a pencil. Said I was the best she ever had and all.
-[JUN]
-Jun
+[MOB_18G]
+Keep you potatoes skinned for her. Be seeing you.
-[JUL]
-Jul
+[MOB_72A]
+Tommy, it's me, Lance. Keep your mouth shut there Tommy, 'cause I ain't got time to talk.
-[AUG]
-Aug
+[MOB_72B]
+I ain't interested in what you got to say. Why should I be? You don't care about me, do you?
-[SEP]
-Sept
+[MOB_72C]
+You gotta look after me a bit better. Give me a fair slice. You know...
-[OCT]
-Oct
+[MOB_72D]
+Tommy... oh, look, man, I'm sorry. It's just that...
-[NOV]
-Nov
+[MOB_72E]
+People patronize me all my life, treat me like a little kid.
-[DEC]
-Dec
+[MOB_72F]
+My brother would do that. Please, man, don't do that.
-[DEFDT]
---:---:---- --:--:--
+[MOB_72G]
+I gotta go.
-[BUGGY]
-BUGGIES LEFT:
+[MOB_63A]
+Tommy, it's Earnest. Earnest Kelly.
-[BONUS]
-~g~BONUS $~1~
+[MOB_63B]
+How are you?
-[HORN1]
-Press the ~h~L3 button ~w~to activate the ~h~horn.
+[MOB_63C]
+I'm doing okay. I'll need a stick to walk, but I should be back at work soon enough.
-[HORN2]
-Press the ~h~L1 button ~w~to activate the ~h~horn
+[MOB_63D]
+Good.
-[HORN3]
-Press the ~h~R1 button ~w~to activate the ~h~horn
+[MOB_63E]
+I heard about Lance. What a little prick, eh?
-[LM3_1A]
-Press the~h~ ~k~~VEHICLE_HORN~ button~w~ to activate the ~h~horn~w~ and let Misty know you are here.
+[MOB_63F]
+Yes.
-[LM3_1B]
-Press the~h~ ~k~~VEHICLE_HORN~ button~w~ to activate the ~h~horn~w~ and let Misty know you are here.
+[MOB_63G]
+Never trust a man who walks the streets in his pajamas. That's what I say. Glad you killed him. I hope it was painful for the prick.
-[LM3_1C]
-Press the~h~ ~k~~VEHICLE_HORN~ button~w~ to activate the ~h~horn~w~ and let Misty know you are here.
+[MOB_63H]
+I think it was. I just didn't think he was like that...
-[RADIO_A]
-Press the ~h~~k~~VEHICLE_CHANGE_RADIO_STATION~ button~w~ to cycle through the ~h~radio stations.
+[MOB_63I]
+Tommy, for a raging lunatic, you're pretty naive. I'll be back at work soon, teach you a thing or two about life, you hear.
-[RADIO_B]
-Press the ~h~~k~~VEHICLE_CHANGE_RADIO_STATION~ button~w~ to cycle through the ~h~radio stations.
+[MOB_63J]
+Take your time, Earnest. Look after yourself.
-[RADIO_C]
-Press the ~h~~k~~VEHICLE_CHANGE_RADIO_STATION~ button~w~ to cycle through the ~h~radio stations.
+[MOB_16A]
+Tommy, Paulo here, que pasa amigo?
-[RADIO_D]
-Press the ~h~~k~~VEHICLE_CHANGE_RADIO_STATION~ button~w~ to cycle through the ~h~radio stations.
+[MOB_16B]
+What do you want Paul? I don't want any fake label clothes.
-[FEC_EXV]
-Enter and exit vehicle
+[MOB_16C]
+Very funny, mate, but you know I don't touch bent gear. Nah, I was just calling to see if I get a part in one your movies.
-[TAXI_M]
-'TAXI DRIVER'
+[MOB_16D]
+Back in England I did a lot of blue stuff, mate. I'm packing more heat than you, my son.
-[COP_M]
-'VIGILANTE'
+[MOB_16E]
+Paul, thanks for the offer, I'll bear it in mind.
-[FIRE_M]
-'FIREFIGHTER'
+[MOB_16F]
+Seriously, don't forget about me, after all I done for you.
-[AMBUL_M]
-'PARAMEDIC'
+[MOB_16G]
+That's what I'm trying to forget about.
-[HJ_IS]
-INSANE STUNT BONUS: $~1~
+[MOB_17A]
+Tommy Vercetti, how's it going, Mr. big shot? I hear all these things about you, some kind of player in town, now eh...
-[HJ_PIS]
-PERFECT INSANE STUNT BONUS: $~1~
+[MOB_17B]
+Paul, you're drunk.
-[HJ_DIS]
-DOUBLE INSANE STUNT BONUS: $~1~
+[MOB_17C]
+Nah, you stupid prat, I ain't drunk. I only had a couple and some treats, ain't been to bed for a couple of days, you know.
-[HJ_PDIS]
-PERFECT DOUBLE INSANE STUNT BONUS: $~1~
+[MOB_17D]
+Anyway, don't give me that. I ain't a mug. Who set you up in this town? Who? Me. That's who.
-[HJ_TIS]
-TRIPLE INSANE STUNT BONUS: $~1~
+[MOB_17F]
+Really?
-[HJ_PTIS]
-PERFECT TRIPLE INSANE STUNT BONUS: $~1~
+[MOB_17G]
+Don't give me that. Don't! I introduced you to people. I showed you the ropes, did a lot of stuff for you, and this is how you repay me.
-[HJ_QIS]
-QUADRUPLE INSANE STUNT BONUS: $~1~
+[MOB_17H]
+You ignore me. You won't give me a way in, after all I did for you! What do you think I am? A div or something?
-[HJ_PQIS]
-PERFECT QUADRUPLE INSANE STUNT BONUS: $~1~
+[MOB_17I]
+Paul, take it easy. I've been busy, don't be an idiot.
-[AM1_K]
-Salvatore Leone will be leaving Luigi's in about three hours time. (0~1~:~1~)
+[MOB_17J]
+I ain't no idiot, mush. That's what they said in borstal. Are you asking for trouble son, because you're going to get it!
-[IMPEXPP]
-Import/Export garage, Portland Harbor. We have orders for various vehicles. Check our notice board for our requirements.
+[MOB_17K]
+Tommy, mate. Please. You was my big hope! Please, don't laugh at me!
-[VANHSTP]
-Any more Securicars you want cracked? Bring them to our garage in the Portland Harbor.
+[MOB_17L]
+Paul, get some sleep, seriously.
-[EMVHPUP]
-Great rates paid for new and used Emergency Vehicles. Bring them to the crane in the north east of Portland Harbor.
+[MOB_73A]
+Tommy, it's Steve.
-[STANDS]
-STALLS WRECKED:
+[MOB_73B]
+Hey, Steve.
-[STASH]
-~g~Stash the SPANK back at the ~p~construction site!
+[MOB_73C]
+Hey indeed, genius. You're a marvel! I'm a marvel! They love us. We are re-writing the record books, pal.
-[MCSTNS]
-There is no Memory Card (PS2) in MEMORY CARD slot 1. Do you wish to start? (YES or NO)
+[MOB_73D]
+We are talking major awards here. Finally, I can put my dad in a home an tell him to shut up.
-[LOVE3_5]
-~g~The plane is now in range.
+[MOB_73E]
+Eeer, that's cool, Steve.
-[LOVE3_6]
-~r~The Police got to the packages first!
+[MOB_73F]
+Cool? It's hot, man. Hot. H. O. T. He never believed in me. Never thought I was an artist, and now I've made it.
-[SIREN_1]
-To turn on this vehicle's sirens tap the ~h~~k~~VEHICLE_HORN~ button~w~.
+[MOB_73G]
+I'm the best damn skin flick director of all time, my friend. I just wanted to say, it's a pleasure to have met you.
-[SIREN_2]
-To turn on this vehicle's sirens tap the ~h~~k~~VEHICLE_HORN~ button~w~.
+[MOB_73H]
+Thanks steve.
-[FM3_8C]
-~w~I'll need $100,000 to cover expenses,
+[MOB_73I]
+I love you, baby. Don't go changing on me, you hear.
-[MCLOAD]
-Loading Data. Please do not remove the Memory Card (PS2) in MEMORY CARD slot 1, reset or switch off the console.
+[MOB_73J]
+I hear you. Good bye, Steve.
-[FES_GME]
-Error Reading Memory Card (PS2) in MEMORY CARD slot 1 please check and try again.
+[BOLLOX]
+Press the ~h~~k~~VEHICLE_HANDBRAKE~ ~w~button to drop a bomb. Press the ~h~~k~~VEHICLE_ENTER_EXIT~ ~w~button to cancel.
-[FESZ_QF]
-Are you sure you wish to format the Memory Card (PS2) in MEMORY CARD slot 1?
+[BRID_OP]
+Storm warning over, all bridges to the mainland are now open.
-[FESZ_LS]
-Load Successful.
+[BRID_CL]
+Storm warning: All bridges to the mainland are closed.
+
+[LG_38]
+Target
-[RM3_5]
-~g~You have ~1~ of 6 evidence packages.
+[ASSET_C]
+POLE POSITION ASSET COMPLETED!
-[LOVE3_2]
-~g~You have all the packages! Take them back to Donald Love.
+[ASSET_D]
+~g~The Pole Position Club will now generate revenue up to a maximum of $~1~ per day. Pick up your cash regularly!
-[LOVE4_4]
-~g~Take the package back to Donald Love!
+[ST_WHEE]
+Longest Wheelie time (secs)
-[FEB_SAV]
-Load
+[ST_STOP]
+Longest Stoppie time (secs)
-[FEP_SAV]
-LOAD GAME
+[ST_2WHE]
+Longest 2 wheels time (secs)
+
+[ST_WHED]
+Longest Wheelie distance (m)
+
+[ST_STOD]
+Longest Stoppie distance (m)
-[AS2_12A]
-~g~After you trash the first stall, you will have 8 minutes before the Cartel warn their pushers!
+[ST_2WHD]
+Longest 2 wheels distance (m)
-[AS3_1A]
-~g~Now get to the ~b~marker buoy!
+[OUTFT11]
+Tracksuit
-[NOCONT]
-Please reconnect an analog controller (DUALSHOCK@) or analog controller (DUALSHOCK@2). to controller port 1 to continue
+[OUTFT12]
+Frankie
-[BET_JB]
-BETRAYED BY HIS LOVER CATALINA AND LEFT FOR DEAD. CONVICTED AND SENTENCED, HE BEGINS HIS JOURNEY TO LIBERTY CITY PENITENTIARY. BUT ONLY ONE THOUGHT BURNS IN HIS CRIMINAL MIND......REVENGE!
+[RELOAD]
+~g~You have won the fast reload ability!
-[END_A]
-Residents in Cedar Grove have been coming to terms
+[APACHE]
+Hunter delivered to helipad in Ocean Beach.
-[END_B]
-with the emotional aftermath of a full blown war
+[CRED369]
+JOHN MCCARDLE
-[END_C]
-that hit the area yesterday.
+[CRED370]
+DAVID MURDOCH
+
+[CRED371]
+CHRIS BROWN
-[END_D]
-Local resident, Clive Denver described to police
+[CRED372]
+PAUL GREEN
-[END_E]
-a single gunman that he saw fleeing the scene, with a dark haired woman.
+[CRED373]
+KYLE MILNE
-[END_F]
-Oh, you know, we're gonna have such fun, 'cos you know, you know,
+[CRED374]
+KEVIN YUN
-[END_G]
-I love you, I, I, I, I really do, 'cos you're such a big strong man
+[CRED375]
+ERICK COBBS
-[END_H]
-and that's just what I need.
+[CRED376]
+RANDY BLAKE
-[END_I]
-Anyway, what was I saying?
+[CRED377]
+BRANDON LIM
-[END_J]
-Oh, you know, I forget. But you know what it's like, don't you?
+[CRED378]
+BRANDON FENOL
-[END_K]
-The sound of explosions shook nearby homes as people ran for cover.
+[CRED379]
+MICHAEL MANOLE
-[END_L]
-Several citizens were injured in the panic as ground fire was exchanged
+[CRED380]
+ALETHEIA SIMONSON
-[END_M]
-between ground forces and a helicopter circling the dam.
+[CRED381]
+JOHN JANSEN
-[END_N]
-Yeah, we got a good view from down here in the gardens.
+[CUNTY]
+New clothes delivered to the Vercetti Estate!
-[END_O]
-When the 'copter finally got taken out,
+[GOODBOY]
+$50 Good Citizen Bonus!
-[END_P]
-better than the fireworks on the 4th of July.
+[NEWCONT]
+New ~h~Contact Point ~w~opened at the marina in Ocean Beach!!
-[END_Q]
-With the death toll already over twenty,
+[FIRELVL]
+Fire Truck Mission level ~1~
-[END_R]
-police are still finding bodies.
+[FEM_RET]
+RETRY
-[END_S]
-There have been no official denials concerning rumours
+[FESZ_QR]
+Are you sure you want to start a new game? All progress will be lost. Proceed?
-[END_T]
-that the dead were members of the Colombian Cartel,
+[SEG3_1]
+TIME:
-[END_U]
-and still no leads as to the cause of the massacre.
+[HELP56]
+Press the ~h~~k~~CAMERA_CHANGE_VIEW_ALL_SITUATIONS~~w~ button to change camera modes.
-[END_V]
-I broke a nail and my hair is ruined, I mean can you believe it?
+[HELP57]
+Press the ~h~~k~~CAMERA_CHANGE_VIEW_ALL_SITUATIONS~~w~ button to change camera modes.
-[END_W]
-This one cost me fifty dollars...
+[HELP58]
+While targeting you can press the ~h~~k~~PED_CYCLE_TARGET_LEFT~ button or ~k~~PED_CYCLE_TARGET_RIGHT~ ~w~button to cycle through targets.
-[PAPER1]
-*
+[HELP59]
+While targeting you can press the ~h~~k~~PED_CYCLE_TARGET_LEFT~ button or ~k~~PED_CYCLE_TARGET_RIGHT~ ~w~button to cycle through targets.
-[PAPER2]
-*
+[HELP60]
+If you press the ~w~~k~~PED_SPRINT~ ~w~button while car jacking, you will not enter that vehicle.
-[PAPER3]
-*
+[HELP61]
+You now have limitless ammo and double health on all vehicles.
-[FEB_CPC]
-Control Configuration
+[FEC_LB1]
+Look
+
+[FEC_LB2]
+behind
+
+[FEC_LB3]
+Look behind
+
+[FEC_R3]
+(R3 button)
[FEC_PED]
Controls On Foot
@@ -6905,7 +6873,7 @@ Controls For First Person
Common Controls
[FEC_PWL]
-GO Left
+Go Left
[FEC_PWR]
Go Right
@@ -7015,84 +6983,6 @@ Change camera mode all situations.
[FEC_TSS]
Take Screen Shot
-[FEN_NET]
-Network
-
-[FEN_CON]
-Connection
-
-[FEN_GAM]
-Find game
-
-[FEN_TYP]
-Game type
-
-[FEN_TY0]
-Deathmatch
-
-[FEN_TY1]
-Deathmatch stealth
-
-[FEN_TY2]
-Team Deathmatch
-
-[FEN_TY3]
-Team Deathmatch stealth
-
-[FEN_TY4]
-Stash the Cash
-
-[FEN_TY5]
-Capture the Flag
-
-[FEN_TY6]
-Rat Race
-
-[FEN_TY7]
-Domination
-
-[FEN_NAM]
-Name:
-
-[FEN_GNA]
-Game name:
-
-[FEM_MAP]
-Select map
-
-[FEN_PLS]
-Player settings
-
-[FEN_PLC]
-Player color
-
-[FEM_MA0]
-Liberty City
-
-[FEM_MA1]
-RedLight
-
-[FEM_MA2]
-Chinatown
-
-[FEM_MA3]
-The Tower
-
-[FEM_MA4]
-The Sewer
-
-[FEM_MA5]
-Industrial Park
-
-[FEM_MA6]
-The Docks
-
-[FEM_MA7]
-Staunton
-
-[FEC_EMS]
-Unique Keyboard Keys only please.
-
[FEC_DBG]
DEBUG MENU
@@ -7144,778 +7034,7250 @@ Use Look Left With Look Right.
[FEC_JBO]
JOY ~1~
-[NO_PAUZ]
-Cannot pause in multiplayer. Press twice to quit!
+[FEC_WAR]
+Warning
-[FEM_SL1]
-Slot 1 is free
+[FEC_OKK]
+O.K.
-[FEM_SL2]
-Slot 2 is free
+[FEC_DLF]
+Delete Failed.
-[FEM_SL3]
-Slot 3 is free
+[FEC_SVU]
+Save Unsuccessful.
-[FEM_SL4]
-Slot 4 is free
+[FEC_LUN]
+Load Unsuccessful. File Corrupted, Please delete.
-[FEM_SL5]
-Slot 5 is free
+[FEC_PAD]
+Gamepad
-[FEM_SL6]
-Slot 6 is free
+[FEC_JOY]
+Joystick
-[FEM_SL7]
-Slot 7 is free
+[FES_CSA]
+Select a skin from the list below:
-[FEM_SL8]
-Slot 8 is free
+[FET_HRD]
+DEFAULT SETTINGS RESTORED
+
+[FET_MST]
+MOUSE CONTROLLED STEERING
+
+[FEC_STR]
+NUM STAR
+
+[FET_MIG]
+LEFT, RIGHT, MOUSEWHEEL TO ADJUST
+
+[FET_CIG]
+BACKSPACE TO CLEAR - LMB, RETURN TO CHANGE
+
+[FET_DSN]
+Default Player Skin.bmp
+
+[FET_RSO]
+ORIGINAL SETTING RESTORED
+
+[FET_RSC]
+HARDWARE NOT AVAILABLE - ORIGINAL SETTING RESTORED
+
+[FEA_3DH]
+AUDIO HARDWARE
+
+[FEA_SPK]
+SPEAKERS CONFIGURATION
+
+[FEM_LOD]
+DRAW DISTANCE
+
+[FEM_VSC]
+FRAME SYNC
+
+[FEM_FRM]
+FRAME LIMITER
[FEM_MM]
MAIN MENU
+[FED_RES]
+SCREEN RESOLUTION
+
+[FET_CTL]
+CONTROLLER SETUP
+
+[FET_OPT]
+OPTIONS
+
+[FEC_MSH]
+MOUSE SENSITIVITY
+
+[FEC_IVV]
+INVERT MOUSE VERTICALLY
+
+[FEC_FNC]
+F~1~
+
+[FEC_IRT]
+INS
+
+[FEC_DLL]
+DEL
+
+[FEC_HME]
+HOME
+
+[FEC_END]
+END
+
+[FEC_PGU]
+PGUP
+
+[FEC_PGD]
+PGDN
+
+[FEC_UPA]
+UP
+
+[FEC_DWA]
+DOWN
+
+[FEC_LFA]
+LEFT
+
+[FEC_RFA]
+RIGHT
+
+[FEC_NUM]
+NUM
+
+[FEC_NMN]
+NUM~1~
+
+[FEC_FWS]
+NUM /
+
+[FEC_PLS]
+NUM +
+
+[FEC_MIN]
+NUM -
+
+[FEC_DOT]
+NUM .
+
+[FEC_NLK]
+NUMLOCK
+
+[FEC_ETR]
+ENT
+
+[FEC_SLK]
+SCROLL LOCK
+
+[FEC_PSB]
+BREAK
+
+[FEC_BSP]
+BSPACE
+
+[FEC_TAB]
+TAB
+
+[FEC_CLK]
+CAPSLOCK
+
+[FEC_RTN]
+RET
+
+[FEC_LSF]
+LSHIFT
+
+[FEC_RSF]
+RSHIFT
+
+[FEC_LCT]
+LCTRL
+
+[FEC_RCT]
+RCTRL
+
+[FEC_LAL]
+LALT
+
+[FEC_RAL]
+RALT
+
+[FEC_LWD]
+LWIN
+
+[FEC_RWD]
+RWIN
+
+[FEC_WRC]
+WINCLICK
+
+[FEC_SPC]
+SPC
+
+[WIN_TTL]
+Grand Theft Auto VC
+
+[WIN_95]
+Grand Theft Auto VC cannot run on Windows 95
+
+[WIN_DX]
+Grand Theft Auto VC requires at least DirectX version 8.1
+
+[FET_EIG]
+CANNOT SET A CONTROL FOR THIS ACTION
+
+[FET_DAM]
+DYNAMIC ACOUSTIC MODELING
+
[FEQ_SRE]
Are you sure you want to quit? All progress since the last save game will be lost. Proceed?
[FEQ_SRW]
Are you sure you want to quit the game?
-[FEG_SRV]
-SERVER
+[FET_QG]
+QUIT GAME
-[FEG_MAP]
-MAP
+[FEN_STA]
+START GAME
+
+[FET_PAU]
+PAUSE MENU
-[FEG_PLY]
-PLAYERS
+[REPLAY]
+REPLAY
-[FEG_TYP]
-TYPE
+[FEC_ANS]
+Action
+
+[CVT_MSG]
+Converting textures to optimal format for your video card
+
+[FEC_SFT]
+SHIFT
-[FEG_PNG]
-PING
+[FEH_VMP]
+VIEW MAP
-[FET_FG]
-FIND GAME
+[FES_DEE]
+Delete Failed! Please try again.
+
+[FES_CMP]
+Save failed! Please try again.
+
+[FESZ_WR]
+Saving current game. Please wait...
+
+[FELD_WR]
+Loading game. Please wait...
+
+[FEDL_WR]
+Deleting saved game. Please wait...
-[FET_SP]
-SINGLE PLAYER
+[PCRESRT]
+Starting new game. Please wait...
-[FET_MP]
-MULTIPLAYER
+[FET_STI]
+Standard Controls
-[FET_HG]
-HOST GAME
+[FET_CTI]
+Classic Controls
[FET_PS]
-PLAYER SETUP
+PLAYER SKIN SETUP
-[FET_CON]
-CONNECTION
+[FEH_NA]
+OPTION NOT AVAILABLE
-[FET_AUD]
-AUDIO SETUP
+[FEH_MPH]
+MOUSE, CURSORS TO MOVE - PGUP, PGDN, MSWHEEL TO ZOOM, L - LEGEND
-[FET_DIS]
-DISPLAY SETUP
+[FEA_MP3]
+MP3 PLAYER
-[FET_LAN]
-LANGUAGE SETUP
+[NO_PCCD]
+Please insert your GTA Vice City CD, or press ESC to cancel
-[FET_LG]
-LOAD GAME
+[FEH_SSA]
+CURSORS TO MOVE - S TO SAVE TO FILE
-[FET_DG]
-DELETE GAME
+[FES_CMI]
+LAST MISSION PASSED
-[FET_NG]
-NEW GAME
+[FET_STS]
+STATS SAVED TO 'STATS.HTML' + 'STATS.TXT'
-[FET_SG]
-SAVE GAME
+[WIN_VDM]
+Grand Theft Auto VC cannot find enough available video memory
-[FET_MAP]
-SELECT MAP
+[FEC_ERI]
+Error! One or more control actions are not bound to a key or button. Please check all control actions are set
-[FET_GT]
-GAME TYPE
+[FEC_TFU]
+Turret + Lean Up
-[FET_CTL]
-CONTROLLER SETUP
+[FEC_TFD]
+Turret + Lean Down
-[FET_OPT]
-OPTIONS
+[FET_RIG]
+SELECT A NEW CONTROL FOR THIS ACTION
-[FET_QG]
-QUIT GAME
+[FEA_NM3]
+NO MP3 FILES FOUND
-[FET_STA]
-STATISTICS
+[FEA_MPB]
+MP3 VOLUME BOOST
-[FET_BRE]
-BRIEFS
+[FEA_MUS]
+MUSIC VOLUME
-[FEC_WAR]
-Warning
+[FEA_SFX]
+SFX VOLUME
-[FEC_OKK]
-O.K.
+[CVT_ERR]
+You have run out of disk space. Please make some space on your harddisk before continuing. Press ESC to cancel.
-[FED_CON]
-Delete File Confirmation
+[FEA_ADP]
+AUTO-DETECT HARDWARE
-[FES_SSC]
-Game successfully saved.
+{=================================== MISSION TABLE AMBULAE ===================================}
-[DEL_FNM]
-File Successfully Deleted.
+[ATUTOR2:AMBULAE]
+~g~Drive the patients to Hospital CAREFULLY. Each bump reduces their chances of survival.
-[PCLOAD]
-Loading File Data
+[A_FULL:AMBULAE]
+~r~Ambulance full!!
-[PCRESRT]
-Restarting Grand Theft Auto III
+[A_FAIL2:AMBULAE]
+~r~Your lack of urgency has been fatal to the patient!
-[FEC_DLF]
-Delete Failed.
+[A_FAIL3:AMBULAE]
+~r~The patient is dead!!
-[FEC_SVU]
-Save Unsuccessful.
+[A_PASS:AMBULAE]
+Rescued!
-[FEC_LUN]
-Load Unsuccessful. File Corrupted, Please delete.
+[A_COMP2:AMBULAE]
+You will never get tired!
-[FEN_PLA]
-Number of players:
+[A_CANC:AMBULAE]
+~r~Paramedic mission cancelled!
-[FET_NON]
-NO GAMES AVAILABLE
+[A_COMP3:AMBULAE]
+Paramedic missions complete! You will never get tired when running!
-[FET_SFG]
-SEARCHING FOR GAMES...
+[ALEVEL:AMBULAE]
+Paramedic Mission Level ~1~
-[FET_SRT]
-SORTING GAMES...
+[A_FAIL1:AMBULAE]
+Paramedic mission ended.
-[FEF_LAN]
-LAN
+[A_SAVES:AMBULAE]
+PEOPLE SAVED: ~1~
-[FEF_INT]
-INTERNET
+[A_COMP1:AMBULAE]
+Paramedic missions complete: $~1~
-[FET_REF]
-Refresh
+{=================================== MISSION TABLE ASSIN1 ===================================}
-[FET_FIL]
-Filter
+[ASM1_5:ASSIN1]
+~r~Your target completed his deliveries!
-[FET_JG]
-Join
+[ASM1_6:ASSIN1]
+Deliveries left:
-[FEC_NTW]
-Talk To Network
+[ASM1_7:ASSIN1]
+~g~Carl Pearson, Pizza Delivery Man. Kill him before he completes his deliveries.
-[FEC_ESR]
-Escape key is Restricted
+[ASM1_A:ASSIN1]
+Mr. Teal, your help in eradicating those out-of-towners was invaluable to business. I have more work for you with a more 'hands-on' approach.
-[FEC_GSL]
-Show head bob:
+[ASM1_D:ASSIN1]
+Mr. Teal, your help in eradicating those out-of-towners was invaluable to business.
-[FIL_FLT]
-FILTER GAMES LIST
+{=================================== MISSION TABLE ASSIN2 ===================================}
-[FET_SAN]
-START NEW GAME
+[ASM2_1:ASSIN2]
+~g~Mrs. Dawson will be leaving the Jewelry shop in Vice Point soon. Kill her. It must look like a car accident.
-[FIL_MAP]
-Map:
+[ASM2_3:ASSIN2]
+~g~She's gonna blow! Get out of there!
-[FIL_SRV]
-Server:
+[ASM2_4:ASSIN2]
+~r~You smashed up her car when she wasn't in it! She won't touch it now!
-[FIL_TYP]
-Game type:
+[ASM2_5:ASSIN2]
+~r~She got away!
-[FIL_SPC]
-Games with Space available?
+[ASM2_6:ASSIN2]
+~r~You were too near the scene of the 'accident'!
-[FIL_PNG]
-Ping:
+[ASM2_7:ASSIN2]
+~r~It's supposed to look like an accident! Try ramming her off the road instead!
-[FEN_UKH]
-Unknown host
+[ASM2_8:ASSIN2]
+~g~You must make Mrs. Dawson's death look like an accident. Do not use any weapons.
-[FEN_UKM]
-Map not found
+[ASM2_9:ASSIN2]
+~g~You need some wheels for this job!
-[FEN_UKT]
-Game type not found
+[ASM2_10:ASSIN2]
+~g~When her car bursts into flames make your self scarce!
-[FEN_NCI]
-NOT CONNECTED TO THE INTERNET
+[ASM2_11:ASSIN2]
+Help me!
-[FET_PAU]
-PAUSE MENU
+[ASM2_12:ASSIN2]
+Somebody help me!
-[FET_SGA]
-START GAME
+[ASM2_13:ASSIN2]
+Oh my god!
-[FEC_SGJ]
-Set Game Joystick
+[ASM2_A:ASSIN2]
+My compliments on a job well done Mr. Teal. My client was very pleased.
-[FEC_PAD]
-Gamepad
+[ASM2_2:ASSIN2]
+health:
-[FEC_JOY]
-Joystick
+{=================================== MISSION TABLE ASSIN3 ===================================}
-[FEC_WHL]
-Steering wheel
+[ASM3_11:ASSIN3]
+TIME:
-[FEC_CNT]
-Controller type:
+[ASM3_C:ASSIN3]
+A European gang plans to hit a bank in Vice City. My employers would rather this didn't happen.
-[FES_CSA]
-Select a skin from the list below:
+[ASM3_D:ASSIN3]
+Each member of the gang has a cover while they are here in Vice City. Some have menial jobs, others are on vacation.
-[FES_SKN]
-SKIN NAME
+[ASM3_E:ASSIN3]
+Each target and their likely whereabouts are taped under the phone.
-[FES_DAT]
-DATE
+[ASM3_14:ASSIN3]
+~g~Dick Tanner is working for DBP Security in Ocean Drive.
-[FES_NON]
-NO SKINS AVAILABLE
+[ASM3_15:ASSIN3]
+~g~Marcus Hammond and Franco Carter are located near the Jewelry shop in Vice Point.
-[FEA_FM9]
-MP3 PLAYER
+[ASM3_16:ASSIN3]
+~g~Nick Kong is cruising off Washington Beach.
-[FESZ_QZ]
-Are you sure you want to save this game?
+[ASM3_18:ASSIN3]
+~g~Don't get too close to the target or he may spot you!
-[FES_CGA]
-Current game slots available:
+[ASM3_19:ASSIN3]
+~g~He's seen you! Waste him!
-[FES_SCG]
-Save the current game?
+[ASM3_20:ASSIN3]
+~g~They have seen you! Make sure you waste them both!
-[FES_LCG]
-Load the game and continue playing?
+[ASM3_21:ASSIN3]
+~r~You did not kill all the gang members in time!
-[FEC_FIR]
-Fire
+[ASM3_22:ASSIN3]
+~g~Don't get too close to the targets or they may spot you!
-[FEC_NWE]
-Next weapon
+[ASM3_12:ASSIN3]
+~g~A selection of weapons have been left for you nearby if you require them. You have ~h~9 MINUTES ~g~to kill all members of the gang.
-[FEC_PWE]
-Previous weapon
+[ASM3_13:ASSIN3]
+~g~Mike Griffin is working on an advertising board in Washington.
-[FEC_FOR]
-Forward
+[ASM3_17:ASSIN3]
+~g~Charlie Dilson is riding in Washington.
-[FEC_BAC]
-Backwards
+{=================================== MISSION TABLE ASSIN4 ===================================}
-[FEC_LEF]
-Left
+[ASM4_10:ASSIN4]
+~g~Looks like you're not the only one after the briefcase! Get it to Ammu-Nation, quick time!
-[FEC_RIG]
-Right
+[ASM4_12:ASSIN4]
+Distance:
-[FEC_ZIN]
-Zoom in
+[ASM4_15:ASSIN4]
+~g~Get the sniper rifle to your right.
-[FEC_ZOT]
-Zoom out
+[ASM4_16:ASSIN4]
+~g~Watch the woman on the balcony, she will walk down the escalators and ask someone the time.
-[FEC_EEX]
-Enter /exit
+[ASM4_17:ASSIN4]
+~g~Once the conversation has finished kill the person she spoke to, but do not kill her.
-[FEC_RAD]
-Radio
+[ASM4_18:ASSIN4]
+~g~Once the target is dead retrieve his briefcase and take it to Ammu-Nation in Downtown.
-[FEC_SUB]
-Sub-mission
+[ASM4_19:ASSIN4]
+~g~Keep your distance from the target! Use the distance bar in the upper right corner of the screen.
-[FEC_CMR]
-Change camera
+[ASM4_20:ASSIN4]
+~g~If it gets full he will see you.
-[FEC_JMP]
-Jump
+[ASM4_21:ASSIN4]
+~g~Get the briefcase!
-[FEC_SPN]
-Sprint
+[ASM4_22:ASSIN4]
+~g~Take the briefcase to Ammu-Nation in Downtown.
-[FEC_HND]
-Handbrake
+[ASM4_23:ASSIN4]
+~g~He has spotted you! Nail him and get the briefcase!
-[FEC_TUL]
-Turret left
+[ASM4_25:ASSIN4]
+~r~You killed the woman you fool!
-[FEC_TUR]
-Turret right
+[ASM4_26:ASSIN4]
+~r~The target has boarded his flight!
-[FEC_LOL]
-Look left
+[ASM4_27:ASSIN4]
+~r~The target has seen you! You should have kept your distance!
-[FEC_LOR]
-Look right
+[ASM4_28:ASSIN4]
+~r~The target heard you firing your weapon!
-[FEC_NTR]
-Next target
+[ASM4_29:ASSIN4]
+~r~Itchy trigger finger? You killed him too soon!
-[FEC_PTT]
-Previous target
+[ASM4_A:ASSIN4]
+Time to fry bigger fish, Mr. Teal. There's a rifle in the foliage to your right.
-[FEC_LBA]
-Look behind
+[ASM4_B:ASSIN4]
+Watch the woman standing on the balcony above the check-in desks. She will walk through the crowd and ask someone the time.
-[FEC_CEN]
-Center camera
+[ASM4_C:ASSIN4]
+You must kill that person, retrieve his case and take it to the location taped under the phone.
-[FEC_UND]
-(NO)
+{=================================== MISSION TABLE ASSIN5 ===================================}
-[FET_CFT]
-ON FOOT
+[ASM5_A:ASSIN5]
+There is a valuable exchange taking place on the roof of the Cherry Popper Ice Cream Company.
-[FET_CCR]
-IN CAR
+[ASM5_B:ASSIN5]
+Kill everyone involved, steal the merchandise and take it to the helipad at the airport.
-[CVT_MSG]
-Converting textures to optimal format for your video card
+[ASM5_C:ASSIN5]
+There is a gate to your left that leads to the back of the factory.
-[FET_CAC]
-ACTION
+[ASM5_1:ASSIN5]
+~g~Enter the compound behind the Cherry Popper Ice Cream Company The deal is taking place on the roof.
-[FEC_IBT]
--
+[ASM5_2:ASSIN5]
+~g~Get the merchandise and take it to the helipad at the airport!
-[FEC_SPC]
-SPC
+[ASM5_3:ASSIN5]
+~g~Take the merchandise to the helipad at the airport!
-[FEC_MXO]
-MXB1
+{=================================== MISSION TABLE BANKJ1 ===================================}
-[FEC_MXT]
-MXB2
+[WANTED1:BANKJ1]
+~g~Shake the cops and lose your wanted level!
-[FEC_UNB]
-UNBOUND
+[BJM1_A:BANKJ1]
+Tommy! Hey, Tommy, look at this, this is great! I've got us this minibar installed!
-[FET_CME]
-CONTROL METHOD
+[BJM1_B:BANKJ1]
+We got a whole bar downstairs, Ken.
-[FET_RDK]
-REDEFINE CONTROLS
+[BJM1_C:BANKJ1]
+Yeah, yeah, whatever. Well, I got the chalkboard you asked for.
-[FET_AMS]
-MOUSE SETTINGS
+[BJM1_D:BANKJ1]
+Ah, that's the benefit of a law school education: the ability to follow instructions.
-[FET_STI]
-STANDARD CONTROL CONFIGURATION
+[BJM1_E:BANKJ1]
+Now, I need a safe man.
-[FET_CTI]
-CLASSIC CONTROL CONFIGURATION
+[BJM1_F:BANKJ1]
+Oh, all right, well, let me think...safe, safe, safe, safe - I got it! This guy will blow you away!
-[FET_MTI]
-MOUSE CONTROL CONFIGURATION
+[BJM1_G:BANKJ1]
+Ahh, nah, that schmuck. He's on the inside.
-[FET_DAM]
-DYNAMIC ACOUSTIC MODELING
+[BJM1_H:BANKJ1]
+Where inside?
-[FEC_TFL]
-Turret Left
+[BJM1_I:BANKJ1]
+In a police headquarter cell awaiting transfer.
-[FEC_TFR]
-Turret Right
+[BJM1_J:BANKJ1]
+I think he's about to get paroled....
-[FEC_MWF]
-WHEEL UP
+[BJM1_1:BANKJ1]
+~g~Break Cam Jones out of police custody!
-[FEC_MWB]
-WHEEL DN
+[BJM1_3:BANKJ1]
+~g~You will find something useful in the station's locker room.
-[FEC_ORR]
-or
+[BJM1_21:BANKJ1]
+~g~The key card to the cells can be found upstairs in the station.
-[FEC_NUS]
-NOT USED
+[BNK1_7:BANKJ1]
+Cam Jones?
-[FEC_LUD]
-Look Up
+[BNK1_8:BANKJ1]
+I'm busting you out!
-[FEC_LDU]
-Look Down
+[BNK1_10:BANKJ1]
+Yeah, that's me..
-[FEC_CMP]
-COMBO: LOOK L+R
+[BNK1_11:BANKJ1]
+Whatever you say!
-[FEC_NTT]
-No Text Yet For This Key
+[BNK1_13:BANKJ1]
+I'm gonna be doing a job and you're my safe cracker.
-[FEC_FNC]
-F~1~
+[BNK1_14:BANKJ1]
+Beats losing my ass in a cell!
-[FEC_IRT]
-INS
+[BJM1_22:BANKJ1]
+~g~Get Cam back to his house!
-[FEC_DLL]
-DEL
+[BJM1_23:BANKJ1]
+~g~You need to get the key card first!
-[FEC_HME]
-HOME
+[BNK1_12:BANKJ1]
+Lose the heat and get me back to my place!
-[FEC_END]
-END
+[BJM1_20:BANKJ1]
+Put the weapon away or face the consequences!
-[FEC_PGU]
-PGUP
+[BJM1_5:BANKJ1]
+Only authorized personnel beyond this point!
-[FEC_PGD]
-PGDN
+[BJM1_2:BANKJ1]
+~r~You were supposed to bust Cam out, not get him killed!
-[FEC_UPA]
-UP
+[BJM1_4:BANKJ1]
+He's armed! Kill him!
-[FEC_DWA]
-DOWN
+{=================================== MISSION TABLE BANKJ2 ===================================}
-[FEC_LFA]
-LEFT
+[BJM2_A:BANKJ2]
+We need a stick up man. You know one?
-[FEC_RFA]
-RIGHT
+[BJM2_B:BANKJ2]
+Hey, Tommy, Tommy, Tommy, this stuff keeps you sharp, man.
-[FEC_NUM]
-NUM
+[BJM2_C:BANKJ2]
+WoooOOOooo!
-[FEC_NMN]
-NUM~1~
+[BJM2_D:BANKJ2]
+I could be your stick up man! Stick 'em up! Stick 'em up!
-[FEC_FWS]
-NUM /
+[BJM2_E:BANKJ2]
+You ain't a stick up man, you're an idiot.
-[FEC_PLS]
-NUM +
+[BJM2_F:BANKJ2]
+Now get yourself a drink and shut up.
-[FEC_MIN]
-NUM -
+[BJM2_G:BANKJ2]
+Hey, get outta my way! Yeh yeh yeh - ow ow ow!
-[FEC_DOT]
-NUM .
+[BJM2_H:BANKJ2]
+Cam, what do you think?
-[FEC_NLK]
-NUMLOCK
+[BJM2_I:BANKJ2]
+Well, the best shooter in this town is a guy named Cassidy.
-[FEC_ETR]
-ENT
+[BJM2_J:BANKJ2]
+Is that so?
-[FEC_SLK]
-SCROLL LOCK
+[BJM2_K:BANKJ2]
+Yeah. A military guy, or he thinks he is.
-[FEC_PSB]
-BREAK
+[BJM2_L:BANKJ2]
+I doubt he was ever in the army, but he certainly knows how to get a hold of guns.
-[FEC_BSP]
-BSPACE
+[BJM2_M:BANKJ2]
+He'll be down at the shooting range.
-[FEC_TAB]
-TAB
+[BJM2_2A:BANKJ2]
+You Phil Cassidy?
-[FEC_CLK]
-CAPSLOCK
+[BJM2_2B:BANKJ2]
+Why?
-[FEC_RTN]
-RET
+[BJM2_2C:BANKJ2]
+I'm looking for a man who can handle a gun. From this setup, I'm not too convinced.
-[FEC_LSF]
-LSHIFT
+[BJM2_2D:BANKJ2]
+Son, I could shoot a fly off your head at 80 feet.
-[FEC_RSF]
-RSHIFT
+[BJM2_2E:BANKJ2]
+Oh really?
-[FEC_LCT]
-LCTRL
+[BJM2_2F:BANKJ2]
+Yeah. I learnt in the army.
-[FEC_RCT]
-RCTRL
+[BJM2_2G:BANKJ2]
+Fly shooting real popular in the army? Glad I don't pay tax.
-[FEC_LAL]
-LALT
+[BJM2_2H:BANKJ2]
+You tryin' to be funny kid?
-[FEC_RAL]
-RALT
+[BJM2_2I:BANKJ2]
+Ha ha ha ha ha!
-[FEC_LWD]
-LWIN
+[BJM2_2J:BANKJ2]
+Let's shoot.
-[FEC_RWD]
-RWIN
+[BJM2_1:BANKJ2]
+~g~Go to Ammu-Nation in Downtown and talk to Phil Cassidy.
-[FEC_WRC]
-WINCLICK
+[BJM2_3:BANKJ2]
+HIT RATE: ~1~%
-[WIN_TTL]
-Grand Theft Auto III
+[BJM2_4:BANKJ2]
+SCORE ROUND ONE: ~1~
-[WIN_95]
-Grand Theft Auto III cannot run on Windows 95
+[BJM2_6:BANKJ2]
+SCORE ROUND TWO: ~1~
-[WIN_DX]
-Grand Theft Auto III requires at least DirectX version 8.1
+[BJM2_7:BANKJ2]
+TOTAL SCORE FOR SHOOT: ~1~
-[WIN_VDM]
-Grand Theft Auto III requires at least 12MB of available video memory
+[BJM2_9:BANKJ2]
+~g~Get to round two's starting point.
-[DIAB3_G]
-Arriba!
+[BJM2_11:BANKJ2]
+~r~Phil's dead!
-[FEM_RES]
-RESUME GAME
+[BJM2_12:BANKJ2]
+~r~One of the shooters is dead!
-[FES_SNG]
-START NEW GAME
+[BJM2_14:BANKJ2]
+~g~Move on to the next area!
-[FEM_SP]
-SINGLE PLAYER
+[BJM2_15:BANKJ2]
+SCORE:
-[FEM_MP]
-MULTIPLAYER
+[BJM2_17:BANKJ2]
+~g~Go and talk to Phil.
-[FEM_QT]
-QUIT GAME
+[BJM2_18:BANKJ2]
+SCORE TO BEAT:
-[FES_SG]
-START NEW GAME
+[BJM2_19:BANKJ2]
+~g~Hit as many targets as you can in the time limit!
-[FES_LG]
-LOAD GAME
+[BJM2_22:BANKJ2]
+~r~You have left the shooting range!
-[FEM_HST]
-HOST GAME
+[BJM2_23:BANKJ2]
+~g~If you leave the shooting range during the competition, you will fail the mission.
-[FEM_OPT]
-OPTIONS
+[BJM2_24:BANKJ2]
+~g~The closest target is worth one point.
-[FEM_DBG]
-DEBUG
+[BJM2_25:BANKJ2]
+~g~The middle target is worth two points.
-[FET_PSU]
-PLAYER SETUP
+[BJM2_27:BANKJ2]
+~g~All targets this round are worth one point.
-[FET_DEF]
-RESTORE DEFAULTS
+[BNK2_2:BANKJ2]
+AIM 3-2-1 FIRE!
-[FED_BRI]
-BRIGHTNESS
+[BNK2_3:BANKJ2]
+AREA CLEAR!
-[FED_TRA]
-TRAILS
+[BNK2_4:BANKJ2]
+Hoooeee!
-[FEM_LOD]
-DRAW DISTANCE
+[BNK2_5:BANKJ2]
+Couldn't hit a barn door!
-[FEM_VSC]
-FRAME SYNC
+[BNK2_7:BANKJ2]
+So you wanna do me a favor, and help me put together a job?
-[FEM_FRM]
-FRAME LIMITER
+[BNK2_8:BANKJ2]
+Son, after shooting like that, if you asked me to be your wife, I'd say yes.
-[FED_RES]
-SCREEN RESOLUTION
+[BNK2_9A:BANKJ2]
+Son, you better get your fancy talking and big ideas and shove 'em where there ain't no sun. You can't shoot nothin'!
-[FED_WIS]
-WIDE SCREEN
+[BNK2_9B:BANKJ2]
+You can't shoot nothin'.
-[FEDS_TB]
-BACK
+[BJM2_28:BANKJ2]
+SCORE ROUND THREE: ~1~
-[FEA_MUS]
-MUSIC VOLUME
+[BJM2_20:BANKJ2]
+~g~When you run out of ~w~time ~g~or ~w~ammunition ~g~the round is over!
-[FEA_SFX]
-SFX VOLUME
+[BJM2_26:BANKJ2]
+~g~The far target is worth three points.
-[FEA_RSS]
-RADIO STATION
+[BNK2_1:BANKJ2]
+LIVE AMMUNITION
-[FEL_ENG]
-ENGLISH
+[RANGE_1:BANKJ2]
+SCORE FOR SHOOT: ~1~
-[FEL_FRE]
-FRENCH
+[BJM2_2:BANKJ2]
+~g~To exit the round press the ~h~~k~~PED_JUMPING~ ~g~button.
-[FEL_GER]
-GERMAN
+[BJM2_N:BANKJ2]
+Relax
-[FEL_ITA]
-ITALIAN
+{=================================== MISSION TABLE BANKJ3 ===================================}
-[FEL_SPA]
-SPANISH
+[BJM3_A:BANKJ3]
+Things are starting to come together nicely here.
-[FEA_3DH]
-AUDIO HARDWARE
+[BJM3_B:BANKJ3]
+What's the plan, Tommy? Que pasa, amigo?
-[FEA_SPK]
-SPEAKERS CONFIGURATION
+[BJM3_C:BANKJ3]
+The plan is you keep doing that like a moron. Anyhow, we need a driver.
-[FEA_2SP]
-2 SPEAKERS
+[BJM3_D:BANKJ3]
+Tommy, I'll do it. I can drive.
-[FEA_4SP]
-MORE THAN 2 SPEAKERS
+[BJM3_E:BANKJ3]
+You want Hilary, mister. Not some smart-talking law school chump.
-[FEA_EAR]
-HEADPHONES
+[BJM3_F:BANKJ3]
+Hilary's the real deal. You ain't never seen anyone drive so fast. I'll give him a call here.
-[FEA_NAH]
-NO AUDIO HARDWARE
+[BJM3_G:BANKJ3]
+Hey Hil, it's Phil. How's it going? No. don't talk. We'll reminisce later. You want to do me a favor?
-[FET_SNG]
-START NEW GAME
+[BJM3_H:BANKJ3]
+I got me a guy from up north. No, no, I don't think he was in the service, but he wants a driver.
-[FEN_STA]
-START GAME
+[BJM3_I:BANKJ3]
+For a bit of action. Okay, I understand.
-[GMLOAD]
-LOAD GAME
+[BJM3_J:BANKJ3]
+What'd he say?
-[GMSAVE]
-SAVE GAME
+[BJM3_K:BANKJ3]
+Well, he'll do it, no problem. Well, there might be a little problem - see, he has abandonment issues.
-[FES_DGA]
-DELETE GAME
+[BJM3_L:BANKJ3]
+Seems he won't work for anyone who can't beat him. Something to do with his momma.
-[FEM_NON]
-NONE
+[BJM3_M:BANKJ3]
+Anyway, he wants to race you first, said he'd meet you outside..
-[FEC_IVV]
-INVERT MOUSE VERTICALLY
+[BJM3_2A:BANKJ3]
+You Tommy? Of course you're Tommy, I mean,
-[FEC_MSH]
-MOUSE SENSITIVITY
+[BJM3_2B:BANKJ3]
+Why else would anyone want to speak to me?
-[FET_CCN]
-CONTROLS: CLASSIC
+[BJM3_2C:BANKJ3]
+OK. Consider it this way -
-[FET_SCN]
-CONTROLS: STANDARD
+[BJM3_2D:BANKJ3]
+I'll drive for you IF, and only IF, you can drive properly.
-[FES_SET]
-USE SKIN
+[BJM3_2E:BANKJ3]
+Leave me alone - and I'll never forgive you.
-[GHOST]
-Ghost
+[BJM3_2:BANKJ3]
+~r~Hilary is dead!
-[WIN_RSZ]
-Failed to select new screen resolution
+[BJM3_4:BANKJ3]
+~g~You need a car to take part!
-[FEC_TFU]
-Turret /Dodo up
+[BNK3_1:BANKJ3]
+Ok. I'll drive for you, but please, treat me bad.
-[FEC_TFD]
-Turret /Dodo down
+[BNK3_3A:BANKJ3]
+Illegal street race in progress at Vice Point.
-[FET_APL]
-APPLY
+[BNK3_3B:BANKJ3]
+Calling all officers.
-[FET_APP]
-LMB,RETURN TO APPLY THE NEW SETTING
+[BNK3_3C:BANKJ3]
+Street racers, this is illegal and forbidden!
-[FET_HRD]
-DEFAULT SETTINGS RESTORED
+{=================================== MISSION TABLE BANKJ4 ===================================}
-[FET_MST]
-MOUSE CONTROLLED STEERING
+[BNK4_A:BANKJ4]
+~w~As you can see, gentlemen, this is going to be the easiest buck we ever made.
-[FEC_STR]
-NUM STAR
+[BNK4_B:BANKJ4]
+~w~Tommy, seriously, you gotta consider going into law.
-[FET_MIG]
-LEFT,RIGHT,MOUSEWHEEL TO ADJUST
+[BNK4_C:BANKJ4]
+~w~What the hell are you smoking, man? This ain't no simple plan!
-[FET_CIG]
-BACKSPACE TO CLEAR - LMB,RETURN TO CHANGE
+[BNK4_D:BANKJ4]
+~w~Well, who needs a simple plan anyway?
-[FET_RIG]
-SELECT A NEW CONTROL FOR THIS ACTION OR ESC TO CANCEL
+[BNK4_E:BANKJ4]
+~w~Take communism, now that was a simple plan. Didn't do Russia any favors, huh?
-[FET_EIG]
-CANNOT SET A CONTROL FOR THIS ACTION
+[BNK4_F:BANKJ4]
+~w~Calm down, all right? With a team like this it's going to be no problem.
-[NO_PCCD]
-Please insert Grand Theft Auto III - disc 2 into the drive or press ESC to cancel
+[BNK4_G:BANKJ4]
+~w~We got Cam on safe. Phil? You and me will handle security, and Hilary'll drive the getaway car.
-[CVT_ERR]
-You have run out of disk space. Please make some space on your harddisk before continuing. Press ESC to cancel.
+[BNK4_H:BANKJ4]
+~w~Uh, heh heh, aren't you forgetting somebody? Somebody who helped you to no end in this town? Somebody who...
-[FED_SUB]
-SUBTITLES
+[BNK4_I:BANKJ4]
+~w~Ken... Ken, that's right. Ken here, he washes the money for us and he keeps the drinks on ice.
-[FET_DSN]
-Default Player Skin.bmp
+[BNK4_J:BANKJ4]
+~w~I don't understand what I am supposed to be doing here.
-[JM3]
-'VAN HEIST'
+[BNK4_K:BANKJ4]
+~w~Look, it's easy. Haven't you ever seen a movie?
-[ATUTOR2]
-~g~Drive the patients to Hospital CAREFULLY. Each bump reduces their chances of survival.
+[BNK4_L:BANKJ4]
+~w~We walk into the bank, we wave the gun around, and leave very rich men.
-[EBAL]
-'GIVE ME LIBERTY'
+[P_DEAD:BANKJ4]
+~r~Phil's dead!!
-[LM4]
-'PUMP-ACTION PIMP'
+[C_DEAD:BANKJ4]
+~r~Cam's dead!!
-[REPLAY]
-REPLAY
+[H_DEAD:BANKJ4]
+~r~Hilary's dead!!
-[FEC_SFT]
-SHIFT
+[P_HIND:BANKJ4]
+~r~You've lost Phil!
-[CRED254]
-STUDIO MANAGER
+[C_HIND:BANKJ4]
+~r~Cam's been left behind!
-[CVT_CRT]
-Cannot convert textures for your video card. You must login to an Administrator account to do this. Press ESC to quit.
+[H_HIND:BANKJ4]
+~r~Hilary's been abandoned!
-[FEM_ON]
-ON
+[GETCAR:BANKJ4]
+~g~Get in the getaway car to do the bank job!
-[FEM_OFF]
-OFF
+[TRASHED:BANKJ4]
+~r~YOU TRASHED THE GETAWAY CAR!!
-[FEM_YES]
-YES
+[BNK4_1:BANKJ4]
+I'll drive.
-[FEM_NO]
-NO
+[BNK4_2:BANKJ4]
+Great. A passenger. Wait 'til I tell the group about this.
-[FES_WAR]
-Saving, please wait...
+[BNK4_3A:BANKJ4]
+Hey, watch the wheels, Tommy!
-[FED_DLW]
-Deleting, please wait...
+[BNK4_3B:BANKJ4]
+Tommy, Hilary's taking up too much room!
-[FED_LDW]
-Loading, please wait...
+[BNK4_3C:BANKJ4]
+I am not!
-[FEC_SLC]
-Slot is corrupted
+[BNK4_3D:BANKJ4]
+Are too!
-[FED_LFL]
-Loading save game has failed. The game will restart now.
+[BNK4_3E:BANKJ4]
+Hey, shut up you two, or you can get out and walk.
-[FET_RSO]
-ORIGINAL SETTING RESTORED
+[BNK4_3F:BANKJ4]
+Yeah - HILARY.
-[FET_RSC]
-HARDWARE NOT AVAILABLE - ORIGINAL SETTING RESTORED
+[BNK4_3I:BANKJ4]
+For god's sake, Phil, stop waving that thing around!
+
+[BNK4_3J:BANKJ4]
+Yeah, you'll have somebody's eye out!
+
+[BNK4_3M:BANKJ4]
+The car's ruined. RUINED!
+
+[BNK4_3O:BANKJ4]
+You cling to an illusion of permanence.
+
+[BNK4_3P:BANKJ4]
+What?
+
+[BNK4_3Q:BANKJ4]
+You think all things will last.
+
+[BNK4_3R:BANKJ4]
+Youth, loved ones, pizza,
+
+[BNK4_3S:BANKJ4]
+All will pass or end and you must accept that.
+
+[BNK4_3T:BANKJ4]
+You're right. Thanks, Cam.
+
+[BNK4_3U:BANKJ4]
+Don't mention it.
+
+[BNK4_3V:BANKJ4]
+Hey Tommy, why have we stopped?
+
+[BNK4_4A:BANKJ4]
+~w~Keep driving around the block, OK?
+
+[BNK4_5:BANKJ4]
+~w~Okay, Tommy, Okay.
+
+[BNK4_6:BANKJ4]
+~w~THIS IS A RAID!
+
+[BNK4_7:BANKJ4]
+~w~NOBODY MOVE!
+
+[BNK4_8:BANKJ4]
+~w~EVERYBODY UP AGAINST THAT WALL!
+
+[BNK4_9:BANKJ4]
+Phil, hold down the fort!
+
+[BNK4_10:BANKJ4]
+Wilco roger that!
+
+[BNK4_11:BANKJ4]
+Come on Cam, the vault's upstairs...
+
+[BK4_12A:BANKJ4]
+Damn! It's a Flange 9000!
+
+[BK4_12B:BANKJ4]
+This could take hours to crack,
+
+[BK4_12C:BANKJ4]
+Or five minutes if you could find the manager.
+
+[BNK4_13:BANKJ4]
+I'll go find where he's holed up.
+
+[BK4_14A:BANKJ4]
+Phil, things still sweet?
+
+[BNK4_15:BANKJ4]
+Sure. Everything's reeaal quiet.
+
+[BNK4_16:BANKJ4]
+You - you're coming with me!
+
+[BNK4_17:BANKJ4]
+Ok! Ok! Just don't shoot!
+
+[BNK4_18:BANKJ4]
+I SAID NOBODY MOVE!
+
+[BK4_19A:BANKJ4]
+It's on a time lock,
+
+[BK4_19B:BANKJ4]
+You might as well give up now!
+
+[BK4_20A:BANKJ4]
+Hell, I can bypass the time lock,
+
+[BK4_20B:BANKJ4]
+Then we just need your key code and we're good!
+
+[BNK4_21:BANKJ4]
+Stay here. You try anything and you're dead.
+
+[BNK422A:BANKJ4]
+Cam, how long?
+
+[BK4_23A:BANKJ4]
+Give me 5 minutes!
+
+[BK4_24A:BANKJ4]
+I'm gonna check on Phil, I'll be right back.
+
+[BK4_24B:BANKJ4]
+I told you not to touch that alarm!
+
+[BNK4_25:BANKJ4]
+The SWAT team will be here any minute!
+
+[BNK4_27:BANKJ4]
+I could do with some help here, Tommy!
+
+[BNK4_28:BANKJ4]
+Vice City S.W.A.T! You are completely surrounded!
+
+[BNK4_29:BANKJ4]
+Surrounded? HA HA HA HAAAAAaaa!
+
+[BNK4_30:BANKJ4]
+They're crapping themselves, corrupt bastards!
+
+[BK4_31A:BANKJ4]
+Tommy! The vault's open!
+
+[BK4_34A:BANKJ4]
+Ok, we got the SWAT retirement fund. Let's get out of here!
+
+[BK4_34B:BANKJ4]
+Ok, you asked for it! You've had your last chance!
+
+[BK4_35A:BANKJ4]
+They're storming the place!
+
+[BK4_35B:BANKJ4]
+Take cover!
+
+[BNK4_94:BANKJ4]
+~w~Ok, guys. Nice an easy just as we planned.
+
+[BM_DEAD:BANKJ4]
+~r~You needed the bank manager alive!!
+
+[ASSET_A:BANKJ4]
+BANK HEIST ASSET COMPLETED!
+
+[ASSET_B:BANKJ4]
+~g~The Malibu Club will now generate revenue up to a maximum of $~1~ per day. Pick up your cash regularly!
+
+[IDIOT:BANKJ4]
+~r~ That's right, just wander about dressed like a lunatic and draw attention to yourself, IDIOT!
+
+{=================================== MISSION TABLE BARON1 ===================================}
+
+[COK1_A:BARON1]
+Come on, baby, go! Yeah! Yeah! Arrrrr!
+
+[COK1_B:BARON1]
+Stupid horse! I'll chop your head off! Grrrrr...
+
+[COK1_C:BARON1]
+Who is this dickhead?
+
+[COK1_D:BARON1]
+Tommy Vercetti. You remember me.
+
+[COK1_E:BARON1]
+Excuse me. I'm a little anxious. Never trust a goddamn horse!
+
+[COK1_F:BARON1]
+You do a good job - you work for me now.
+
+[COK1_H:BARON1]
+As I said, amigo, you work for me now. Shut up. Some Judas has betrayed me.
+
+[COK1_I:BARON1]
+He thinks I don't know how much money I should be making, but stealing 3% is as good as stealing 100%.
+
+[COK1_J:BARON1]
+No one does this to me. NO ONE!!
+
+[COK1_K:BARON1]
+You follow him from his apartment and you see where he goes! Later, we will kill him.
+
+[COK1_1:BARON1]
+Ooh shit!
+
+[COK1_2:BARON1]
+Too slow grandad!
+
+[COK1_4:BARON1]
+Loser.
+
+[COK1_5:BARON1]
+You better keep on running, asshole!
+
+[COK1_8:BARON1]
+~g~Quick! Grab some wheels and follow him!
+
+[COK1_9:BARON1]
+~r~You're supposed to follow him, not kill him!
+
+[COK1_10:BARON1]
+~g~Go to the thief's house and find out where he's stashing the money.
+
+[COK1_11:BARON1]
+~g~Have a look through his window.
+
+[COK1_7:BARON1]
+~g~He's escaped to the roof, keep on his tail but don't kill him!
+
+[COK1_G:BARON1]
+I work for money.
+
+{=================================== MISSION TABLE BARON2 ===================================}
+
+[COK2_A:BARON2]
+What kind of incompetent fool are you?
+
+[COK2_B:BARON2]
+FOOL! FOOL! FOOL! FOOL!
+
+[COK2_C:BARON2]
+Tommy!
+
+[COK2_D:BARON2]
+What, Ricardo?
+
+[COK2_E:BARON2]
+These idiots - they always trying to screw you.
+
+[COK2_F:BARON2]
+That's the problem with this business.
+
+[COK2_G:BARON2]
+What do you think you're doing?
+
+[COK2_H:BARON2]
+These pricks have failed me miserably,
+
+[COK2_I:BARON2]
+Soon any mom and pop will think they can sell gallo in Vice City.
+
+[COK2_J:BARON2]
+What next, huh? The stinking Mafia?!
+
+[COK2_K:BARON2]
+That gang place is a fortress at ground level,
+
+[COK2_L:BARON2]
+so Quentin here - Quentin! QUENTIN!
+
+[COK2_M:BARON2]
+He'll fly you over the area!
+
+[COK2_N:BARON2]
+Eradicate them!
+
+[COK2_O:BARON2]
+What do you think you're doing?
+
+[COK2_P:BARON2]
+What are you doing here?
+
+[COK2_Q:BARON2]
+Hey, I've been asking around and it's obvious
+
+[COK2_R:BARON2]
+that Diaz jumped the deal and iced my brother.
+
+[COK2_S:BARON2]
+And he'll kill you, too!
+
+[COK2_T:BARON2]
+I can take Diaz!
+
+[COK2_U:BARON2]
+No - listen to me! I'll handle Diaz -
+
+[COK2_1:BARON2]
+One thing puzzling me, What's with 'Quentin!?
+
+[COK2_2:BARON2]
+I dunno, I always kinda liked it...Quentin Vance...
+
+[COK2_3:BARON2]
+Vance? Your name's Lance Vance?
+
+[COK2_4:BARON2]
+Hey! I got enough of that at school!
+
+[COK2_5:BARON2]
+You ever fired one of those from a whirly?
+
+[COK2_8:BARON2]
+Where the hell are we headed anyway?
+
+[COK2_9:BARON2]
+Prawn Island.
+
+[COK2_13:BARON2]
+Lance Vance. Poor bastard.
+
+[COK2_14:BARON2]
+Ok, we're almost there.
+
+[COK2_15:BARON2]
+We'll make a couple of passes.
+
+[COK2_16:BARON2]
+So take out as many guns as you can.
+
+[COK2_17:BARON2]
+Then I'll set you down and you're on your way.
+
+[COK2_20:BARON2]
+Damn! This is a war zone! Take out some of those gunmen!
+
+[COK2_21:BARON2]
+We're taking hits here, man!
+
+[COK2_22:BARON2]
+This thing ain't cheap to fix! Take them out!
+
+[COK2_23:BARON2]
+Ok, you're on your own from here! Good luck, brother!
+
+[COK2_24:BARON2]
+Heli Health:
+
+[COK2_25:BARON2]
+~g~Go and collect the money on the roof.
+
+[COK2_27:BARON2]
+You're on MY turf asshole!
+
+[COK2_28:BARON2]
+You're going down!
+
+[COK2_6:BARON2]
+No. I'll get a bit of practice on the way though.
+
+[OPEN_B:BARON2]
+The road blocks to the mainland have now been removed
+
+[COK2_V:BARON2]
+- he's beginning to trust me.
+
+{=================================== MISSION TABLE BARON3 ===================================}
+
+[COK3_A:BARON3]
+Not so pleased with your selves NOW, huh!
+
+[COK3_B:BARON3]
+Ahahahahaa, Ahahahahaa.
+
+[COK3_C:BARON3]
+Whoa! Watch where you're waving that thing!
+
+[COK3_D:BARON3]
+No more pigeon shit on MY car, eh Tommy!
+
+[COK3_E:BARON3]
+Guess not.
+
+[COK3_F:BARON3]
+You're damn right. Now listen,
+
+[COK3_G:BARON3]
+you know who owns the fastest boat on the east coast?
+
+[COK3_H:BARON3]
+Not off hand, no.
+
+[COK3_I:BARON3]
+ME. And I want it to stay that way.
+
+[COK3_J:BARON3]
+Every smuggler from here to Caracas has one dream, a faster boat.
+
+[COK3_K:BARON3]
+Rumor has it the boatyard has just completed such a vessel.
+
+[COK3_L:BARON3]
+for some Costa Rican dickhead.
+
+[COK3_M:BARON3]
+And Tommy...I WANT THAT BOAT!!!
+
+[COK3_N:BARON3]
+I think your pigeons are back.
+
+[COK3_O:BARON3]
+Ah! I thought I got you. Where'd you come from?
+
+[COK3_P:BARON3]
+Pigeons! Boom! Aaaaah!
+
+[COK3_5:BARON3]
+~g~Find the switch to lower the boat.
+
+[COK3_6:BARON3]
+~g~Get the boat to the mansion.
+
+[COK3_7:BARON3]
+~r~You destroyed the boat!
+
+[COK3_8:BARON3]
+~g~Go to the boatyard at the docks and steal the fastest boat.
+
+[COK3_9:BARON3]
+~g~Now get into the boat.
+
+{=================================== MISSION TABLE BARON4 ===================================}
+
+[COK4_A:BARON4]
+Eject! PLASTIC CRAP!
+
+[COK4_B:BARON4]
+You doing this to me?
+
+[COK4_C:BARON4]
+Who do you think you are, you piece of plastic SHIT? Aaarrgh!
+
+[COK4_D:BARON4]
+SCREW YOU!
+
+[COK4_E:BARON4]
+It eats my favorite El burro movie, it die!
+
+[COK4_F:BARON4]
+What else could I do?
+
+[COK4_G:BARON4]
+It's probably not plugged in.
+
+[COK4_H:BARON4]
+What?
+
+[COK4_I:BARON4]
+Damn - no matter, I can buy a hundred more.
+
+[COK4_J:BARON4]
+Now Tommy,
+
+[COK4_K:BARON4]
+each month a freelancer sails into Vice City and moors his yacht.
+
+[COK4_L:BARON4]
+He sells his cargo to the first boat.
+
+[COK4_M:BARON4]
+I want you to take the speedboat
+
+[COK4_N:BARON4]
+and beat all the other shitheads to it,
+
+[COK4_O:BARON4]
+then you bring the cargo here, ok!?
+
+[COK4_P:BARON4]
+Let me guess, you thought I could use a guardian angel.
+
+[COK4_Q:BARON4]
+I'm just saying you need to let me in there, my man.
+
+[COK4_T:BARON4]
+and you're probably gonna wanna kiss me!
+
+[COK4_U:BARON4]
+Wacko.
+
+[COK4_V:BARON4]
+Hahahahahaha!
+
+[COK4_1:BARON4]
+So Tommy, we know it was Diaz busted our deal..
+
+[COK4_3:BARON4]
+So why the hell are we running errands for him?
+
+[COK4_4:BARON4]
+The more we learn now, the less we have to learn when we take this town over!
+
+[COK4_5:BARON4]
+I like your style, man. Real fresh.
+
+[COK4_12:BARON4]
+Watch yourself, they're coming from all over!
+
+[COK4_13:BARON4]
+Got 'em. Head for Diaz's as fast as you can!
+
+[COK4_14:BARON4]
+You want some of this?!
+
+[COK4_15:BARON4]
+Sleep with the fish!
+
+[COK4_16:BARON4]
+Eat it! EAT IT!
+
+[COK4_19:BARON4]
+More trouble up ahead!
+
+[COK4_20:BARON4]
+There are gunmen on that jetty!
+
+[COK4_24:BARON4]
+Good shooting, my friend. You're a real, proper, grade A lunatic.
+
+[COK4_25:BARON4]
+Well, thank you.
+
+[COK4_26:BARON4]
+See you around, Tommy.
+
+[COK4_27:BARON4]
+Okay, Mr. Lance Vance Dance.
+
+[COK4_28:BARON4]
+~g~Get to the yacht before the other boats do!
+
+[COK4_31:BARON4]
+~g~Go to the fastest boat at the jetty!
+
+[COK4_32:BARON4]
+~r~Too slow!
+
+[COK4_33:BARON4]
+~r~You destroyed the boat!
+
+[COK4_34:BARON4]
+~g~Take those boats out!
+
+[COK4_35:BARON4]
+Boat health:
+
+[COK4_R:BARON4]
+Now you can feed me all this 'lonely tough guy' crap,
+
+[COK4_S:BARON4]
+but I know one day I'm gonna save your ass,
+
+{=================================== MISSION TABLE BARON5 ===================================}
+
+[PROP_A:BARON5]
+PROPERTY ACQUIRED!
+
+[COK4_30:BARON5]
+~r~Lance is dead!
+
+[ASS1_A:BARON5]
+I got us some cannons in the trunk.
+
+[ASS1_B:BARON5]
+Holy shit! Where'd you get all this stuff?
+
+[ASS1_C:BARON5]
+Been saving it for a rainy day.
+
+[ASS1_D:BARON5]
+You like?
+
+[ASS1_E:BARON5]
+Yeah, I like.
+
+[ASS1_F:BARON5]
+You stupid pricks...
+
+[ASS1_G:BARON5]
+my beautiful house
+
+[ASS1_H:BARON5]
+look what you've done to it!
+
+[ASS1_I:BARON5]
+This is for my brother!
+
+[ASS1_J:BARON5]
+I trusted you, Tommy.
+
+[ASS1_K:BARON5]
+I woulda had you made...
+
+[ASS1_L:BARON5]
+Say goodnight, Mr. Diaz.
+
+[ASS1_1:BARON5]
+This place is going to be crawling with assholes...be careful...
+
+[ASS1_2:BARON5]
+Don't worry Tommy, I'll cover you.
+
+[ASS1_13:BARON5]
+DIAZ?! I've come to take over your business!
+
+[ASS1_15:BARON5]
+~g~Storm the mansion and kill Diaz!
+
+[ASS1_16:BARON5]
+~g~Kill Diaz!
+
+[ASS1_17:BARON5]
+~g~There are multiple routes into the mansion.
+
+[BUD1:BARON5]
+Lances Health:
+
+[ASS1_18:BARON5]
+~g~The door is locked, try another route.
+
+[ASS1_19:BARON5]
+This way!
+
+[ASS1_14:BARON5]
+TOMMY! You betrayed me, you idiot! I'm gonna kill you real soon..
+
+[ASS1_20:BARON5]
+Tommy, my problem with Quentin, not wit you, man!
+
+{=================================== MISSION TABLE BIKE1 ===================================}
+
+[BM1_A:BIKE1]
+Where's Baker?
+
+[BM1_B:BIKE1]
+I'm looking for Big Mitch Baker...
+
+[BM1_C:BIKE1]
+Who's lookin'?
+
+[BM1_D:BIKE1]
+Tommy Vercetti.
+
+[BM1_E:BIKE1]
+Vercetti
+
+[BM1_F:BIKE1]
+You don't look like the law, so that's bought you a minute.
+
+[BM1_G:BIKE1]
+You better talk fast.
+
+[BM1_H:BIKE1]
+Kent Paul said you might be interested in pulling security for a gig he's got set up.
+
+[BM1_I:BIKE1]
+Kent Paul? Sheesh! No wonder he sent ya.
+
+[BM1_J:BIKE1]
+The last time he was here he left through the window in nothing but his limey birthday suit.
+
+[BM1_K:BIKE1]
+Are you interested or not?
+
+[BM1_L:BIKE1]
+We only do favors for our own.
+
+[BM1_M:BIKE1]
+How do I join?
+
+[BM1_N:BIKE1]
+This ain't no country club, boy. Can you handle a bike?
+
+[BM1_O:BIKE1]
+Can you sit on a stool and drink?
+
+[BM1_P:BIKE1]
+Cougar, Zeppelin, go see how this girl handles a bike...
+
+[BM1_3:BIKE1]
+~r~The racers have been attacked!
+
+[BIKE1_1:BIKE1]
+All right, fancy clothes. Let's see what you can do.
+
+[BM1_1:BIKE1]
+~g~Get a Freeway or an Angel and get to the starting grid.
+
+[BM1_2:BIKE1]
+~g~You need a Freeway or an Angel to compete!
+
+{=================================== MISSION TABLE BIKE2 ===================================}
+
+[BM2_1:BIKE2]
+CHAOSMETER:
+
+[BM2_A:BIKE2]
+Ah, got ya again.
+
+[BM2_B:BIKE2]
+Hey Vercetti.
+
+[BM2_C:BIKE2]
+Cougar says you can handle a bike pretty good.
+
+[BM2_D:BIKE2]
+Yeah, how many more errands am I gonna to have to run?
+
+[BM2_E:BIKE2]
+I'm a very busy man.
+
+[BM2_F:BIKE2]
+If it's a fight that's gonna settle this then bring it on.
+
+[BM2_G:BIKE2]
+Being one of us ain't just about brawlin'. It's about being part of a family.
+
+[BM2_H:BIKE2]
+Yeah, I've been part of a family before alright. It didn't work out.
+
+[BM2_I:BIKE2]
+Yeah, right, but this family takes care of its own.
+
+[BM2_J:BIKE2]
+We don't ask a man to do the dirty work and then let him do fifteen years hard time.
+
+[BM2_K:BIKE2]
+Yeah, that's right. I've done my homework.
+
+[BM2_L:BIKE2]
+This here's the biggest family of misfits, outcasts and badasses.
+
+[BM2_M:BIKE2]
+Hell, some of us has even been betrayed by our own country.
+
+[BM2_N:BIKE2]
+I was locked up during 'Nam. Ugly business.
+
+[BM2_O:BIKE2]
+Which is why I'm gonna ask you to go mess with the man.
+
+[BM2_Q:BIKE2]
+So get out there, grab a bike and show this city how pissed you are!
+
+[BM2_R:BIKE2]
+Alright, alright.
+
+[BM2_3:BIKE2]
+~g~This sound indicates that you have filled a part of the meter, continue to do so.
+
+[BM2_2:BIKE2]
+~g~You must fill the Chaos Meter in the time given to show us how much of a badass you are!
+
+[BM2_4:BIKE2]
+~r~You failed to fill the Chaos Meter in time!
+
+[BM2_P:BIKE2]
+This whole damn country needs a kick in the ass, and we're the ones to deliver it.
+
+{=================================== MISSION TABLE BIKE3 ===================================}
+
+[BM3_A:BIKE3]
+Hey there, Mitch.
+
+[BM3_B:BIKE3]
+Well, if it ain't 'bad ass' Vercetti.
+
+[BM3_C:BIKE3]
+Now I wanna see how good you can fight for your patch.
+
+[BM3_D:BIKE3]
+A local street gang made the mistake of stealing my hog...
+
+[BM3_E:BIKE3]
+probably because of some machismo thing or somethin'.
+
+[BM3_F:BIKE3]
+Me and the boys would go over there and teach them a lesson in respect an'all.
+
+[BM3_G:BIKE3]
+Anyways.
+
+[BM3_H:BIKE3]
+Then I got to thinking - this would make a good initiation for you.
+
+[BM3_I:BIKE3]
+You get my bike back, you can tell Paul he's got his security.
+
+[BM3_2:BIKE3]
+~r~You were supposed to bring the bike back, not destroy it!
+
+[BM3_3:BIKE3]
+~g~Get the bike back to the bar!
+
+[BM3_4:BIKE3]
+~g~Get on the bike!
+
+[INTRUDE:BIKE3]
+~g~You've been spotted!
+
+[BM3_6:BIKE3]
+~g~They are holed up behind Ammu-Nation in the Downtown area.
+
+[BM3_7:BIKE3]
+~g~You will need a fast bike to gain access to the roof.
+
+[BM3_8:BIKE3]
+~g~Use the bike to jump from these stairs to the roof on the far side of the road.
+
+[BM3_1:BIKE3]
+~g~A local gang has stolen Mitch Baker's Angel. Get it back!
+
+[BM3_9:BIKE3]
+~g~Get Mitch's Angel and get out of there!
+
+{=================================== MISSION TABLE BMX_1 ===================================}
+
+[GETBIK2:BMX_1]
+~r~You have ~w~~1~ seconds ~g~to get on a Dirt Bike!
+
+{=================================== MISSION TABLE BOATBUY ===================================}
+
+[DRUG_2:BOATBUY]
+Put it out. There's a dude here.
+
+[DRUG_3:BOATBUY]
+Hey suit dude! I guess you're the new owner?
+
+[DRUG_4:BOATBUY]
+Yeah. Which one of the boats is the fastest?
+
+[DRUG_5:BOATBUY]
+It's already in the water, dude,
+
+[DRUG_6:BOATBUY]
+I though you might want to try her out.
+
+[DRUG_7:BOATBUY]
+Dude, she's already running with a 300 horse power engine...
+
+[DRUG_8:BOATBUY]
+...and the fiberglass hull, she just shoots through the waves.!
+
+[DRUG_9:BOATBUY]
+She can do like zero to sixty in four seconds flat dude...
+
+[DRUG_10:BOATBUY]
+and she can hold like twenty bales of the best Jamaican smoke right in the hull!
+
+[DRUG_11:BOATBUY]
+So go ahead dude, she's ready to fly!
+
+[DRUG_12:BOATBUY]
+Yo yo, uh, suit dude, you gotta light?
+
+[DRUG_1:BOATBUY]
+Hello? Hel-lo?! Hello?
+
+[DRUG_13:BOATBUY]
+Dude?
+
+{=================================== MISSION TABLE CAP_1 ===================================}
+
+[CAP1_B1:CAP_1]
+~g~The Mafia is taxing your businesses. Find them and kill them.
+
+[CAP1_B2:CAP_1]
+~g~The Mafia has taxed the Boatyard!
+
+[CAP1_B3:CAP_1]
+~g~The Mafia has taxed the Ice Cream Factory!
+
+[CAP1_B4:CAP_1]
+~g~The Mafia has taxed the Car Showroom!
+
+[CAP1_B5:CAP_1]
+~g~The Mafia has taxed the Taxi Firm!
+
+[CAP_01:CAP_1]
+Ok, what's the emergency?
+
+[CAP_02:CAP_1]
+WHO?
+
+[CAP_03:CAP_1]
+Tommy...some mob thugs ...said they'd come to take their cut...
+
+[CAP_04:CAP_1]
+...said it was a Mr. Forello's money...I feel like crap.
+
+[CAP_05:CAP_1]
+Forelli? SONNY Forelli?
+
+[CAP_06:CAP_1]
+Yeah, that's the guy...I think...they were very insistent...
+
+[CAP_07:CAP_1]
+Don't you worry, pop, I'm not angry with you.
+
+[CAP_08:CAP_1]
+Get him to the hospital.
+
+[CAP_09:CAP_1]
+Tommy...rip that guy a new asshole for me...
+
+[CAP_10:CAP_1]
+I'm gonna rip him two!
+
+[CAP1_2:CAP_1]
+You know the rules, Vercetti!
+
+[CAP1_3:CAP_1]
+Mr. Forelli sends his regards!
+
+[CAP1_4:CAP_1]
+It's the Harwood Butcher!
+
+[CAP1_5:CAP_1]
+You tell Sonny - stay away!
+
+[CAP1_6:CAP_1]
+Vice City is MINE now, NOT his.
+
+[CAP1_7:CAP_1]
+You think you can take me down, Vercetti?
+
+[CAP1_8:CAP_1]
+We'll keep coming after you until you die, Vercetti.
+
+[CAP1_9:CAP_1]
+You don't stand a chance, you psychotic prick.
+
+[CAP1_10:CAP_1]
+I'll murder you Vercetti.
+
+[CAP1_11:CAP_1]
+You always were a jerk.
+
+[CAP1_12:CAP_1]
+You're going to die, Vercetti.
+
+[CAP1_B6:CAP_1]
+~g~You have found the collector, kill him.
+
+[CAP1_B7:CAP_1]
+~g~You've lost the collector.
+
+[CAP1_B8:CAP_1]
+~r~The collector has taxed all of your businesses.
+
+[CAP1_B9:CAP_1]
+~g~The mafia has taxed The Malibu!
+
+[CAP1_B0:CAP_1]
+~g~The mafia has taxed the film studio!
+
+[CAP1_C2:CAP_1]
+~g~The Mafia has arrived at the Boatyard!
+
+[CAP1_C3:CAP_1]
+~g~The Mafia has arrived at the Ice Cream Factory!
+
+[CAP1_C4:CAP_1]
+~g~The Mafia has arrived at the Car Showroom!
+
+[CAP1_C5:CAP_1]
+~g~The Mafia has arrived at the Taxi Firm!
+
+[CAP1_C9:CAP_1]
+~g~The Mafia has arrived at The Malibu!
+
+[CAP1_C0:CAP_1]
+~g~The Mafia has arrived at the film studio!
+
+[CAP1_D2:CAP_1]
+~g~The Mafia is leaving the Boatyard!
+
+[CAP1_D3:CAP_1]
+~g~The Mafia is leaving the Ice Cream Factory!
+
+[CAP1_D4:CAP_1]
+~g~The Mafia is leaving the Car Showroom!
+
+[CAP1_D5:CAP_1]
+~g~The Mafia is leaving the Taxi Firm!
+
+[CAP1_D9:CAP_1]
+~g~The Mafia is leaving The Malibu!
+
+[CAP1_D0:CAP_1]
+~g~The Mafia is leaving the film studio!
+
+[CAP1B10:CAP_1]
+You've capped the Collectors. More are on their way.
+
+{=================================== MISSION TABLE CARBUY ===================================}
+
+[CAR1_1:CARBUY]
+B.J. Smith. And you must be Mr. Vercetti.
+
+[CAR1_2:CARBUY]
+Would you like the tour?
+
+[CAR1_3:CARBUY]
+Might as well.
+
+[CAR1_4:CARBUY]
+Well, I'm very sad to be selling the dealership to y'all.
+
+[CAR1_5:CARBUY]
+This was my first investment after I turned pro.
+
+[CAR1_6:CARBUY]
+But now it's time for me to move on.
+
+[CAR1_7:CARBUY]
+You're leaving town?
+
+[CAR1_8:CARBUY]
+Not in too much of a hurry, I hope?
+
+[CAR1_9:CARBUY]
+No. I'm just coming out of retirement, and preparing for my future comeback.
+
+[CAR1_10:CARBUY]
+The business wasn't too strong,
+
+[CAR1_11:CARBUY]
+and my staff took it upon themselves to get a bit more
+
+[CAR1_12:CARBUY]
+creative with the generation of wealth.
+
+[CAR1_13:CARBUY]
+Obviously, I could wind down the business before I hand it over.
+
+[CAR1_14:CARBUY]
+Hell, I could burn the place down if I wanted to.
+
+[CAR1_15:CARBUY]
+This is prime development land.
+
+[CAR1_16:CARBUY]
+Oh, I wouldn't worry about any of that.
+
+[CAR1_17:CARBUY]
+This place seems perfect.
+
+[CAR1_18:CARBUY]
+Yeh it does, So I take it we have a deal?
+
+{=================================== MISSION TABLE CARPAR1 ===================================}
+
+[MM_1_A:CARPAR1]
+~g~Collect ~y~5 checkpoints~r~ WITHOUT ~g~smashing any ~r~CONES! ~g~You may collect checkpoints in ~y~ANY ORDER.
+
+[CONE_1:CARPAR1]
+~r~You smashed a cone!!
+
+[MM_1_C:CARPAR1]
+~y~PASS THROUGH~g~ a checkpoint to start the timer. ~g~Each checkpoint will credit you with ~y~~1~ SECONDS~g~.
+
+{=================================== MISSION TABLE COPCAR ===================================}
+
+[KILLS:COPCAR]
+KILLS:
+
+[C_BREIF:COPCAR]
+~g~Suspect last seen in the ~a~ area.
+
+[COPCART:COPCAR]
+~g~You have ~1~ seconds to return to a police vehicle before the mission ends.
+
+[C_CANC:COPCAR]
+~r~Vigilante mission cancelled!
+
+[C_TIME:COPCAR]
+~r~Your time as a law enforcer is over!
+
+[C_COMP1:COPCAR]
+Vigilante mission level 12 complete: Your max Body Armor increased to 150
+
+[CLEVEL:COPCAR]
+Vigilante Mission Level ~1~
+
+[C_PASS:COPCAR]
+THREAT ELIMINATED: $ ~1~
+
+{=================================== MISSION TABLE COUNT1 ===================================}
+
+[CM1_A:COUNT1]
+Mr. Vercetti? Hey. You bought the old print works?
+
+[CM1_B:COUNT1]
+Yeah, my old man used to work on these.
+
+[CM1_C:COUNT1]
+I was going to follow him in his trade, but...I lived a different life.
+
+[CM1_D:COUNT1]
+You planning on selling the old machinery, breaking it down?
+
+[CM1_E:COUNT1]
+I'm thinking we might print something - a newspaper, a magazine...
+
+[CM1_F:COUNT1]
+Oh, crap, sonny, low grade crap. I've always fancied printing money. It ain't too hard.
+
+[CM1_G:COUNT1]
+You know, I've been doing it on a small scale for years.
+
+[CM1_H:COUNT1]
+Really?
+
+[CM1_I:COUNT1]
+Sure. But we'd need some good quality plates.
+
+[CM1_J:COUNT1]
+Of course! There's a counterfeiting syndicate already operating in Florida.
+
+[CM1_K:COUNT1]
+A syndicate?
+
+[CM1_L:COUNT1]
+Yeah. Just rumors is all I've heard.
+
+[CM1_M:COUNT1]
+I know a man who's good with rumors...
+
+[CM1_N:COUNT1]
+I used to spend the evenings with him, cleaning the rollers...
+
+[CM1_2A:COUNT1]
+Look at the arse on that!
+
+[CM1_2B:COUNT1]
+Awright girl, it's your loss mate init!
+
+[CM1_2C:COUNT1]
+Awright me ol'china, how's it hangin'?
+
+[CM1_2D:COUNT1]
+What do you know about counterfeiting?
+
+[CM1_2E:COUNT1]
+Oh I'm fine Paul, how 'bout you?
+
+[CM1_2F:COUNT1]
+Come 'ere!
+
+[CM1_2G:COUNT1]
+Awright! Awright! Awright!! You're obviously a busy man.
+
+[CM1_2H:COUNT1]
+All I know about dodgy readys is the Triads supply the plates.
+
+[CM1_2I:COUNT1]
+They've got a shipping company down the docks,
+
+[CM1_2J:COUNT1]
+the boss man would know when the plates are coming in next!
+
+[CM1_2K:COUNT1]
+Thanks Paul.
+
+[CM1_2L:COUNT1]
+What's the matter with you, you maniac!
+
+[CM1_2M:COUNT1]
+Give me another drink, lively!
+
+[CM1_3:COUNT1]
+~g~You've been spotted!
+
+[CM1_5:COUNT1]
+~g~Go and meet Kent Paul at the Malibu Club!
+
+[CNT1_1:COUNT1]
+Who are you? Oooof! Aaiieee! Not the face! Not the face!
+
+[CM1_1:COUNT1]
+~g~Go to the Chartered Libertine Lines boat at the docks.
+
+[CM1_2:COUNT1]
+~g~The Shipping Officer will have the information that is required.
+
+[CNT1_2:COUNT1]
+Ok, I talk! I talk!
+
+[CM1_6:COUNT1]
+~g~Get the information back to the Print Works!
+
+{=================================== MISSION TABLE COUNT2 ===================================}
+
+[CNT2_B1:COUNT2]
+Alright, the courier's moving the plates from the docks today.
+
+[CNT2_B2:COUNT2]
+I'm gonna go intercept them, grab the plates, lose any heat, and make my way back here.
+
+[CNT2_B3:COUNT2]
+Now. Depending how well this goes,
+
+[CNT2_B4:COUNT2]
+we may have five minutes to print the money before the counterfeit syndicate finds us, or we may have all year.
+
+[CNT2_B5:COUNT2]
+Either way, I want green rolling off the presses five minutes after I get back. Got it?
+
+[CNT2_B6:COUNT2]
+Don't you worry Tommy. We'll be ready.
+
+[CNT2_B7:COUNT2]
+Me an'the boys will be around in the neighborhood case you need any heat taken care of.
+
+[CNT2_B8:COUNT2]
+All right, everybody cool? All right. I'll catch you later...
+
+[CNT2_01:COUNT2]
+~g~The counterfeit plates ~y~courier~g~ is arriving at the ~r~docks~g~ in a helicopter any second now.
+
+[CNT2_02:COUNT2]
+~r~The plates courier has fled in the helicopter.
+
+[CNT2_03:COUNT2]
+~r~The courier has arrived at his destination safely, you're too late!
+
+[CNT2_04:COUNT2]
+~r~You destroyed the plates in the explosion!
+
+[CNT2_05:COUNT2]
+~g~You have the counterfeit plates. Take them to the print works.
+
+[CNT2_06:COUNT2]
+~g~The courier has died and dropped the plates, get to them before anyone else.
+
+[CNT2_07:COUNT2]
+~g~One of the guards has picked up the plates, don't let 'em get away.
+
+[CNT2_08:COUNT2]
+~g~The ~r~courier~g~ with the plates has arrived at the docks.
+
+[CNT2_4:COUNT2]
+Private business. You're not welcome!
+
+[CNT2_09:COUNT2]
+PRINT WORKS ASSET COMPLETED
+
+[CNT2_10:COUNT2]
+~g~The print works will now generate revenue up to a maximum of $~1~. Make sure you collect it regularly.
+
+[CNT2_11:COUNT2]
+~r~The plates are at the bottom of the sea!
+
+{=================================== MISSION TABLE CUBAN1 ===================================}
+
+[CUB1_A:CUBAN1]
+Si, men?
+
+[CUB1_B:CUBAN1]
+Hey, easy Papi, this man's for me. You, you the boy?
+
+[CUB1_C:CUBAN1]
+Oh yeh. You the boy. I think so, you know?
+
+[CUB1_D:CUBAN1]
+No. I don't think I do.
+
+[CUB1_E:CUBAN1]
+Oh yeah? You come here, tough guy.
+
+[CUB1_F:CUBAN1]
+You think you can take me on?
+
+[CUB1_G:CUBAN1]
+You think you can play stupid with me?
+
+[CUB1_H:CUBAN1]
+No, I think you're playing plenty stupid enough for both of us.
+
+[CUB1_I:CUBAN1]
+Hey, he call you dumb, son.
+
+[CUB1_J:CUBAN1]
+And I call him a little girl, Papi.
+
+[CUB1_K:CUBAN1]
+Look at him, all dressed up like that.
+
+[CUB1_L:CUBAN1]
+What is this, ladies night?
+
+[CUB1_M:CUBAN1]
+You some kind of tough guy, you dress like a woman?
+
+[CUB1_N:CUBAN1]
+You got on panties like a woman too, huh?
+
+[CUB1_O:CUBAN1]
+What you got against women? You prefer men, big boy?
+
+[CUB1_P:CUBAN1]
+I like women! I like all women! I love my mother, chico!
+
+[CUB1_Q:CUBAN1]
+Alright, alright, I'll take your word for it. Relax.
+
+[CUB1_R:CUBAN1]
+Can you drive, amigo?
+
+[CUB1_S:CUBAN1]
+Yeah... like a woman.
+
+[CUB1_T:CUBAN1]
+Very funny. I like you, big boy. Maybe you can help.
+
+[CUB1_U:CUBAN1]
+Maybe you can prove you a man. Huh?
+
+[CUB1_V:CUBAN1]
+Take out the boat.
+
+[CUB1_W:CUBAN1]
+Show me you got some big cojones,
+
+[CUB1_X:CUBAN1]
+and not some little bitty chiquita ones.
+
+[CUB1_02:CUBAN1]
+Ok man, treat her like a woman.
+
+[CUB1_03:CUBAN1]
+Not bad, you're a real man.
+
+[CUB1_04:CUBAN1]
+You got real big cojones, amigo.
+
+[CUB1_05:CUBAN1]
+Amigo, you a man, man.
+
+[CUB1_06:CUBAN1]
+Call yourself a man, man?
+
+[CUB1_07:CUBAN1]
+You a little scaredy kitten, baby boy, go cry to your mommy!
+
+[CUB1_09:CUBAN1]
+Man, you the man, man. I like you, man. I like you a lot.
+
+[CUB1_10:CUBAN1]
+Any time, man. 'cause you got cojones. And all my friends have big cojones.
+
+[CUB1_11:CUBAN1]
+~r~You Killed Rico!
+
+[CUB1_12:CUBAN1]
+Go through the first checkpoint to begin the test.
+
+[CUB1_14:CUBAN1]
+Get back in the boat!
+
+[CUB1_15:CUBAN1]
+~r~You are too slow, man.
+
+[CUB1_01:CUBAN1]
+Hey, I'm Rico. You the man with the big cojones?
+
+[CUB1_13:CUBAN1]
+~g~You have three minutes to get round the course.
+
+[CUB1_08:CUBAN1]
+You a big waste of space. Walk like a man, talk like a man, but you drive like an idiot.
+
+{=================================== MISSION TABLE CUBAN2 ===================================}
+
+[CUB2_A:CUBAN2]
+Un cafecito, por favor, Alberto..
+
+[CUB2_N:CUBAN2]
+No problema, Tommy.
+
+[CUB2_B:CUBAN2]
+Papi! Una grande problema!
+
+[CUB2_O:CUBAN2]
+Umberto my son, what happened?
+
+[CUB2_C:CUBAN2]
+The Haitians! I hate these Haitians!
+
+[CUB2_D:CUBAN2]
+They mess with me for the last time!
+
+[CUB2_E:CUBAN2]
+These Hai - these Haitians! We take 'em out!
+
+[CUB2_F:CUBAN2]
+Only we need some backup.
+
+[CUB2_H:CUBAN2]
+Amigo, you drive good!
+
+[CUB2_I:CUBAN2]
+For a woman. Right?
+
+[CUB2_J:CUBAN2]
+This is no time for joking!
+
+[CUB2_K:CUBAN2]
+Come on, drive for me again!
+
+[CUB2_L:CUBAN2]
+Take my boys over there, and then we'll take these Haitians down!
+
+[CUB2_01:CUBAN2]
+Not enough room, man, you need a bigger car.
+
+[CUB2_02:CUBAN2]
+We need reinforcements from the cafe!
+
+[CUB2_03:CUBAN2]
+~g~Get a car and pick up the Cubans from outside Robina's Cafe.
+
+[CUB2_04:CUBAN2]
+~g~Go and drop the Cubans off at the fight.
+
+[CUB2_05:CUBAN2]
+Take out that cowardly sniper!
+
+[CUB2_07:CUBAN2]
+They fight like girls! Take cover!
+
+[CUB2_09:CUBAN2]
+Sniper on the roof!
+
+[CUB2_11:CUBAN2]
+~r~You fool, we needed that car.
+
+[CUB2_12:CUBAN2]
+Hey amigo! Good to see you could make it!
+
+[CUB2_13:CUBAN2]
+Stinking nest of Haitians, we gonna kill 'em all!
+
+[CUB2_14:CUBAN2]
+CHAAAAAARGE!
+
+[CUB2_15:CUBAN2]
+Now, my brothers, CHAAARRRGGEE!!
+
+[CUB2_16:CUBAN2]
+Tommy, we have proved our manful bravery!
+
+[CUB2_17:CUBAN2]
+Let us steal the van full of drugs and make good our escape!
+
+[CUB2_18:CUBAN2]
+~g~Get a car and pick up the Cubans
+
+[CUB2_19:CUBAN2]
+We gonna fight like men!
+
+[CUB2_21:CUBAN2]
+Fight like men with huge cojones!
+
+[CUB2_22:CUBAN2]
+~g~ Finish off the rest of the Haitians so the Cubans can move forward.
+
+[CUB2_23:CUBAN2]
+~g~ Little Haiti will be swarming with Haitians trying to even the score with the Cubans. Watch your back.
+
+[CUB2_24:CUBAN2]
+~g~Return to Robina's Cafe with the Van and park it round the back.
+
+[CUB2_25:CUBAN2]
+KILL ALL THE HAITIANS!!
+
+[CUB2_G:CUBAN2]
+I lost a few hermanos already out there.
+
+[CUB2_M:CUBAN2]
+They mess with me, they mess with the biggest boy in town!
+
+{=================================== MISSION TABLE CUBAN3 ===================================}
+
+[CUB3_B:CUBAN3]
+Poppa, don't serve this snake in the straw.
+
+[CUB3_C:CUBAN3]
+You're two-faced, Tommy!
+
+[CUB3_E:CUBAN3]
+The Haitians, man. They're laughing at me!
+
+[CUB3_G:CUBAN3]
+They're laughing at me, Tommy. At me!
+
+[CUB3_I:CUBAN3]
+Nobody does whatever they like, Umberto, they do what you let them do.
+
+[CUB3_J:CUBAN3]
+What?
+
+[CUB3_K:CUBAN3]
+You want somebody taken care of?
+
+[CUB3_L:CUBAN3]
+I can handle it, but it's gonna cost you.
+
+[CUB3_M:CUBAN3]
+I know we're brothers and all, but this is business.
+
+[CUB3_N:CUBAN3]
+Tommy. You a real man. Businessman, a gentleman.
+
+[CUB3_O:CUBAN3]
+These Haitians. They have a load of product coming in off shore, really good stuff.
+
+[CUB3_P:CUBAN3]
+We take it, and we finish them.
+
+[CUB3_Q:CUBAN3]
+You take it, and I look after you. Like my brother. Like my son.
+
+[CUB3_R:CUBAN3]
+I think I prefer the cash to being bounced on your knee, amigo.
+
+[CUB3_01:CUBAN3]
+Hey Rico. Nice boat, you ready?
+
+[CUB3_03:CUBAN3]
+~g~Collect all the briefcases filled with the drugs and cash.
+
+[CUB3_04:CUBAN3]
+~g~Get the drugs and cash back to Umberto.
+
+[CUB3_05:CUBAN3]
+Si Tommy. Now you be a good shot today,
+
+[CUB3_06:CUBAN3]
+My boat, she no good full of holes, ok?
+
+[CUB3_07:CUBAN3]
+~g~ Go meet Rico. He'll drive you to the meet location.
+
+[CUB3_02:CUBAN3]
+~g~KILL ALL THE HAITIANS ON THE BOATS!!
+
+[CUB3_08:CUBAN3]
+Uh oh.. Pack of Cubans. We under attack!
+
+[CUB3_A:CUBAN3]
+Alberto. Una cafe, senor.
+
+[CUB3_D:CUBAN3]
+You're either two-faced, or you're a wimp, baby boy!
+
+[CUB3_F:CUBAN3]
+Easy, easy. What's your problem?
+
+[CUB3_H:CUBAN3]
+Umberto Robina! They're doing whatever they like!
+
+{=================================== MISSION TABLE CUBAN4 ===================================}
+
+[CUB4_A:CUBAN4]
+Hey, ladies. You know what I'm gonna do?
+
+[CUB4_B:CUBAN4]
+I'm gonna kill me a Haitian. And then?
+
+[CUB4_C:CUBAN4]
+And then I'm going to make love like a man.
+
+[CUB4_D:CUBAN4]
+You know that, chica? Something like this.
+
+[CUB4_E:CUBAN4]
+Loser!
+
+[CUB4_F:CUBAN4]
+Prick.
+
+[CUB4_G:CUBAN4]
+Hey, baby, I wouldn't touch you with a ten foot pole!
+
+[CUB4_H:CUBAN4]
+Umberto Robina, he likes the ladies! Not some goat in a skirt!
+
+[CUB4_I:CUBAN4]
+Tommy!! Tommy, I love you, I love you! Let's go!
+
+[CUB4_J:CUBAN4]
+Go where? Can't I get a cup of coffee first?
+
+[CUB4_K:CUBAN4]
+No time for coffee! Besides, I just had one.
+
+[CUB4_L:CUBAN4]
+We gonna take out the Haitians.
+
+[CUB4_M:CUBAN4]
+Tommy, how do you take out a snake?
+
+[CUB4_N:CUBAN4]
+You bite him in the ass! Hahaha!
+
+[CUB4_O:CUBAN4]
+Whatever you say, Umberto.
+
+[CUB4_P:CUBAN4]
+Tommy, you go and get us a little Haitian car.
+
+[CUB4_Q:CUBAN4]
+When you get it, come back and pick up my boy.
+
+[CUB4_R:CUBAN4]
+Pepe, and take him out to the Haitians.
+
+[CUB4_S:CUBAN4]
+Then, you go around to the Haitians processing plant, and you use their solvent as an explosive.
+
+[CUB4_T:CUBAN4]
+Boom! Bye bye!
+
+[CUB4_U:CUBAN4]
+Umberto, what about you?
+
+[CUB4_V:CUBAN4]
+Uhh... I'm going to stay behind, and watch over the cafe with Poppa.
+
+[CUB4_W:CUBAN4]
+He not feeling so good. You know?
+
+[CUB4_02:CUBAN4]
+~g~The bombs will be set with a 45 second timer.
+
+[CUB4_04:CUBAN4]
+~r~You've alerted the base, there is no way we will get in now!
+
+[CUB4_07:CUBAN4]
+Oy - the solvent is round the back, amigo.
+
+[CUB4_08:CUBAN4]
+Hola, amigos.
+
+[CUB4_09:CUBAN4]
+Bueno. Haitian Putas. Muerte.
+
+[CUB4_10:CUBAN4]
+Vamos.
+
+[CUB4_11:CUBAN4]
+Vamos indeed.
+
+[CUB4_12:CUBAN4]
+Hey, we need a Haitian gang car!
+
+[CUB4_13:CUBAN4]
+Oye, let's go find our muchachos!
+
+[CUB4_14:CUBAN4]
+Follow my compadres.
+
+[CUB4_15:CUBAN4]
+Ok, in you go...
+
+[CUB4_16:CUBAN4]
+I'm going to plant the bomb, cover me!
+
+[CUB4_17:CUBAN4]
+RUN!!
+
+[CUB4_18:CUBAN4]
+Man, this a nice part of town...
+
+[CUB4_19:CUBAN4]
+This place is a dump, man.
+
+[CUB4_20:CUBAN4]
+I had a beautiful woman... lived around this neighborhood.
+
+[CUB4_21:CUBAN4]
+You know, they do nice pizzas here.
+
+[CUB4_22:CUBAN4]
+Whoah, man. You drive like a crazy bitch!
+
+[CUB4_23:CUBAN4]
+You lost, man?
+
+[CUB4_24:CUBAN4]
+You've left Pepe behind, go and get him.
+
+[CUB4_03:CUBAN4]
+~g~Stay in the car until safely parked inside the compound.
+
+[CUB4_26:CUBAN4]
+~g~Take Pepe, head North into Little Haiti and steal a Voodoo car.
+
+[CUB4_27:CUBAN4]
+~g~Go and meet up with Rico and the other Cubans.
+
+[CUB4_28:CUBAN4]
+~g~Join the other Cubans at the Haitian Drugs Factory.
+
+[CUB4_29:CUBAN4]
+~g~Walk into each of the markers to plant a bomb at that location.
+
+[CUB4_30:CUBAN4]
+~g~After all three bombs are planted, get clear of the factory before it blows.
+
+[CUB4_31:CUBAN4]
+~g~Get clear of the factory!!
+
+[CUB4_32:CUBAN4]
+~g~Park the car at the blip and get out.
+
+[CUB4_06:CUBAN4]
+~r~You did not get far enough away from the base and we had to abort the explosion!
+
+{=================================== MISSION TABLE FINALE ===================================}
+
+[FIN1_01:FINALE]
+What's going on?
+
+[FIN1_02:FINALE]
+Tommy! Oh good, good. Listen, listen. Uh, listen,
+
+[FIN1_03:FINALE]
+I like fish. I love fish.
+
+[FIN1_04:FINALE]
+I love them as pets in bowls, or as food on a plate,
+
+[FIN1_05:FINALE]
+but as much as I love em, I don't want to sleep with them.
+
+[FIN1_06:FINALE]
+Okay, but right now your Italian brothers are coming from up there to fit me with some cement shoes, and I...
+
+[FIN1_07:FINALE]
+Shut up Ken. Sit down.
+
+[FIN1_08:FINALE]
+Lance, what the hell's going on?
+
+[FIN1_09:FINALE]
+It's your friends up north Tommy. They ain't too happy you capped their man.
+
+[FIN1_10:FINALE]
+They're coming down to see the business today.
+
+[FIN1_11:FINALE]
+They took longer than I thought...
+
+[FIN1_12:FINALE]
+Guys, we gotta make this final we gotta leave no doubt that this is my operation. Mine!
+
+[FIN1_13:FINALE]
+Ken, you get the first run of counterfeit cash and put three mil in briefcases.
+
+[FIN1_14:FINALE]
+Lance, you get the guys together...
+
+[FIN2_01:FINALE]
+Tommy!
+
+[FIN2_02:FINALE]
+What? No big hugs for your old buddy?
+
+[FIN2_03:FINALE]
+I've had fifteen years out of the loop,
+
+[FIN2_04:FINALE]
+I'm a bit rusty on family etiquette.
+
+[FIN2_05:FINALE]
+Always angry, eh Tommy.
+
+[FIN2_06:FINALE]
+Didn't I say your temper would get you into trouble, huh?
+
+[FIN2_07:FINALE]
+There's three mil in the cases...
+
+[FIN2_08:FINALE]
+How many was it? Ten? No, eleven men.
+
+[FIN2_09:FINALE]
+That's how you get to be called the Harwood Butcher! Heh-heh-heh!
+
+[FIN2_10:FINALE]
+You sent me to kill one man, ONE MAN. They knew I was coming Sonny...
+
+[FIN2_11:FINALE]
+Tommy, Tommy, watch your tone.
+
+[FIN2_12:FINALE]
+Anyone would think you blame me for that unfortunate set of circumstances.
+
+[FIN2_13:FINALE]
+Just take the money...
+
+[FIN2_14:FINALE]
+Get the damn cash.
+
+[FIN2_15:FINALE]
+You know, Tommy? I did what I could for you, I pulled strings, called in favors.
+
+[FIN2_16:FINALE]
+I was your friend, Tommy. I hoped you'd see sense, see what's good for business.
+
+[FIN2_17:FINALE]
+I trusted you, Tommy, and you disappointed me.
+
+[FIN2_18:FINALE]
+But at least someone in your chicken shit organization knows how to do business,
+
+[FIN2_19:FINALE]
+Isn't that right, Lance?
+
+[FIN2_20:FINALE]
+I'm sorry Tommy. This is Vice City. This is business.
+
+[FIN2_21:FINALE]
+You sold us out...
+
+[FIN2_22:FINALE]
+No. I sold YOU out, Tommy, I sold YOU out.
+
+[FIN2_23:FINALE]
+The real cash is upstairs in the safe.
+
+[FIN2_24:FINALE]
+Tommy, what was the big plan?
+
+[FIN2_25:FINALE]
+You think I'd just take the fake cash?
+
+[FIN2_26:FINALE]
+Save face and run away with my tail between my legs?!
+
+[FIN2_27:FINALE]
+No.
+
+[FIN2_28:FINALE]
+I just wanted to piss you off before I kill you.
+
+[FIN3_01:FINALE]
+Tommy?
+
+[FIN3_02:FINALE]
+Oh my god, Tommy! What happened?
+
+[FIN3_03:FINALE]
+What does it look like?
+
+[FIN3_04:FINALE]
+It looks like you ruined your suit!
+
+[FIN3_05:FINALE]
+and Tommy, that was a beautiful suit! Tommy, what on earth happened?
+
+[FIN3_06:FINALE]
+I had a disagreement with a business associate, you know how it is.
+
+[FIN3_07:FINALE]
+Tommy, I have a disagreement, I send them an angry letter.
+
+[FIN3_08:FINALE]
+Maybe I pee in their mailbox. I don't start World War III.
+
+[FIN3_09:FINALE]
+You know, maybe you should speak to my shrink...
+
+[FIN3_10:FINALE]
+That stupid prick, Lance...
+
+[FIN3_11:FINALE]
+Tommy. I never liked that guy, okay?
+
+[FIN3_12:FINALE]
+He's neurotic, he's insecure, he's self-centered - the guy's an asshole!
+
+[FIN3_13:FINALE]
+I'm glad you took him out!
+
+[FIN3_14:FINALE]
+I don't think we're gonna be getting any more heat from up north either...
+
+[FIN3_15:FINALE]
+...'cause there ain't no 'up north', anymore.
+
+[FIN3_16:FINALE]
+It's all down south now.
+
+[FIN3_17:FINALE]
+Wait, does that mean what I think it means..? Tommy, baby!
+
+[FIN3_18:FINALE]
+What do you think it means?
+
+[FIN3_19:FINALE]
+That we're in charge... I mean, that you're in charge. Oh, Tommy!
+
+[FIN3_20:FINALE]
+You know, Ken. I think this could be the beginning of a beautiful business relationship....
+
+[FIN3_21:FINALE]
+After all, you're a conniving, backstabbing, two-bit thief
+
+[FIN3_22:FINALE]
+and I'm a convicted psychotic killer and drug dealer.
+
+[FIN3_23:FINALE]
+I know. Ain't it just beautiful?
+
+[FIN_B1:FINALE]
+~g~Go and kill ~y~Lance Vance~g~ the backstabber.
+
+[FIN_B2:FINALE]
+~g~Kill ~p~Sonny~g~ and finish this once and for all.
+
+[FIN_B3:FINALE]
+~g~The Mafia are trying to steal your money. Defend the safe.
+
+[FIN_B4:FINALE]
+~g~You are close to death, get some ~w~health~g~ from downstairs.
+
+[FIN_B5:FINALE]
+~g~The Mafia is stealing your money, defend the ~c~safe
+
+[FIN_B7:FINALE]
+~r~The mafia has stolen all your money.
+
+[DEFSAFE:FINALE]
+~g~Get back to the safe and defend it.
+
+{=================================== MISSION TABLE FIRETRK ===================================}
+
+[F_PASS1:FIRETRK]
+Fire extinguished!
+
+[F_FAIL2:FIRETRK]
+~r~You're too late!
+
+[F_CANC:FIRETRK]
+~r~Fire Fighter mission cancelled!
+
+[F_EXTIN:FIRETRK]
+FIRES:
+
+[F_START:FIRETRK]
+~g~Burning vehicle reported in the ~a~ area. Go and extinguish the fire.
+
+[SIREN_1:FIRETRK]
+To turn on this vehicle's sirens tap the ~h~~k~~VEHICLE_HORN~ ~w~button.
+
+[SIREN_2:FIRETRK]
+To turn on this vehicle's sirens tap the ~h~~k~~VEHICLE_HORN~ ~w~button.
+
+[FIREPRO:FIRETRK]
+Fire Truck Mission level 12 complete. You are now completely fireproof!!
+
+[F_FAIL1:FIRETRK]
+Fire Fighter mission ended.
+
+[F_STAR1:FIRETRK]
+~g~Burning vehicles reported in the ~a~ area. Go and extinguish the fire.
+
+[SPRAY_4:FIRETRK] { reVC update }
+Use the ~h~~k~~VEHICLE_FIREWEAPON~ ~w~button to fire the water cannon. Aim using ~h~~k~~VEHICLE_TURRETLEFT~~w~ and ~h~~k~~VEHICLE_TURRETRIGHT~~w~.
+
+[SPRAY_1:FIRETRK] { reVC update }
+Use the ~h~~k~~VEHICLE_FIREWEAPON~ ~w~button to fire the water cannon. Aim using ~h~~k~~VEHICLE_TURRETLEFT~~w~ and ~h~~k~~VEHICLE_TURRETRIGHT~~w~.
+
+{=================================== MISSION TABLE GENERA1 ===================================}
+
+[GEN1_A:GENERA1]
+Mr. Vercetti!
+
+[GEN1_B:GENERA1]
+Colonel.
+
+[GEN1_D:GENERA1]
+No - thanks.
+
+[GEN1_E:GENERA1]
+I'm ashamed to admit that one of the causes of our mutual problem appears to have been the loose tongue of a man I used to trust.
+
+[GEN1_F:GENERA1]
+I've been carrying Gonzalez for years, but now his incompetence reaches new heights!
+
+[GEN1_G:GENERA1]
+It is only right that you kill Gonzalez...
+
+[GEN1_H:GENERA1]
+Did he do it? It's the money that's important to me.
+
+[GEN1_J:GENERA1]
+He will be at his Penthouse, half drunk probably. Use this...
+
+[GEN1_06:GENERA1]
+Eh! He's got a blade!
+
+[GEN1_07:GENERA1]
+Go away from me, you cheap bastard!
+
+[GEN1_08:GENERA1]
+Oh sweet Jesus, I've wasted my life and my looks!
+
+[GEN1_10:GENERA1]
+I'm going to shut that big mouth of yours!
+
+[GEN1_11:GENERA1]
+Stop running you fat slimeball!
+
+[GEN1_12:GENERA1]
+Stand still and I'll make it quick!
+
+[GEN1_13:GENERA1]
+Quit your squealing, no one cares, fatso!
+
+[GEN1_C:GENERA1]
+Thank you for coming. Please sit. Lobster?
+
+[GEN1_05:GENERA1]
+~g~Go and kill Gonzalez!
+
+[GEN1_09:GENERA1]
+I pay you double, Tommy, DOUBLE!
+
+[GEN1_18:GENERA1]
+~r~Gonzalez has made it safely to the Police Station!
+
+[GEN1_19:GENERA1]
+~g~The Vice City Police are on to you!
+
+[GEN1_20:GENERA1]
+~g~Get into a vehicle.
+
+[GEN1_21:GENERA1]
+~g~Get to the~h~ Pay 'N' Spray~g~ in~h~ Vice Point~g~.
+
+[GEN1_22:GENERA1]
+Drive your vehicle into the spray shop to lose your ~h~wanted level, ~h~repair and ~h~respray your vehicle. Cost - ~h~$100. This time it's free.
+
+[GEN1_01:GENERA1]
+When jogging, press and hold the~h~ ~k~~PED_FIREWEAPON~ ~w~button to prepare a melee attack.
+
+[GEN1_02:GENERA1]
+When jogging, press and hold the~h~ ~k~~PED_FIREWEAPON~ ~w~button to prepare a melee attack.
+
+[GEN1_03:GENERA1]
+When jogging, press and hold the~h~ ~k~~PED_FIREWEAPON~ ~w~button to prepare a melee attack.
+
+[GEN1_14:GENERA1]
+Release the~h~ ~k~~PED_FIREWEAPON~ ~w~button to make the attack.
+
+[GEN1_15:GENERA1]
+Release the~h~ ~k~~PED_FIREWEAPON~ ~w~button to make the attack.
+
+[GEN1_16:GENERA1]
+Release the~h~ ~k~~PED_FIREWEAPON~ ~w~button to make the attack.
+
+[GEN1_I:GENERA1]
+For this kindness I'll reward you, and then we will find your money together.
+
+[GEN1_23:GENERA1]
+~g~Go back through the doors to return to the ground floor.
+
+{=================================== MISSION TABLE GENERA2 ===================================}
+
+[COL2_B:GENERA2]
+This looks delicious, huh? Tapir snout?
+
+[COL2_C:GENERA2]
+Uhhh... no, no. No, thanks.
+
+[COL2_D:GENERA2]
+Tommy, you are like a pampas breeze that has freed me from the stench of corruption,
+
+[COL2_E:GENERA2]
+although, I must appear to mourn his passing and carry on with business as usual.
+
+[COL2_F:GENERA2]
+This isn't getting me any closer to my money...
+
+[COL2_G:GENERA2]
+Tommy, my friend, you are not in Liberty now. Here we do things differently.
+
+[COL2_H:GENERA2]
+I will continue with my enquiries but in the meantime I have a valuable deal to close.
+
+[COL2_I:GENERA2]
+A favor for a friend, Cortez?
+
+[COL2_J:GENERA2]
+You're a good friend, Tommy. I knew you would not let me down.
+
+[COL2_K:GENERA2]
+I need you to meet a courier who has obtained some valuable technology for me...
+
+[COL2_1:GENERA2]
+Ze rain, she is tres wet zis time of the year...
+
+[COL2_2:GENERA2]
+What?
+
+[COL2_3:GENERA2]
+Ah, comment?
+
+[COL2_4:GENERA2]
+Look, Cortez sent me. Just give me the damn chips.
+
+[COL2_5:GENERA2]
+Oh...d'accord.
+
+[COL2_B1:GENERA2]
+~g~Meet the courier at the mall.
+
+[COL2_B2:GENERA2]
+~g~The courier is fleeing with the guidance chips! Don't let him get away!
+
+[COL2_B3:GENERA2]
+~g~Take the guidance chips back to the Colonel.
+
+[COL2_F1:GENERA2]
+~r~You killed the contact!
+
+[COL2_F2:GENERA2]
+~g~The courier is dead. Grab the guidance chips.
+
+[COL2_6A:GENERA2]
+Freeze, imperialist American pig! Zat iz propertay of ze government Francais. 'And eet over!
+
+[BLIPHLP:GENERA2]
+The blip on the radar is a triangle pointing up, this shows that the target is higher than the player.
+
+[COL2_F3:GENERA2]
+~r~The guidance chips are at the bottom of the sea.
+
+[COL2_F4:GENERA2]
+~r~The courier has escaped! You failed to get the guidance chips.
+
+[COL2_A:GENERA2]
+Tommy! Come, join me.
+
+{=================================== MISSION TABLE GENERA3 ===================================}
+
+[GEN3_A:GENERA3]
+Thomas, I appreciate your coming.
+
+[GEN3_B:GENERA3]
+Forgive me for getting straight to business.
+
+[GEN3_C:GENERA3]
+Diaz has asked me to oversee a minor business transaction.
+
+[GEN3_D:GENERA3]
+Let's hope it goes better than last time, huh?
+
+[GEN3_E:GENERA3]
+Which is why I thought of you, my friend.
+
+[GEN3_F:GENERA3]
+I've dropped some protection at the multistory carpark.
+
+[GEN3_G:GENERA3]
+Pick it up - then go and watch over Diaz's men at the drop off.
+
+[GEN3_H:GENERA3]
+Gracias, amigo.
+
+[GEN3_1:GENERA3]
+Hogging all the action, I see...
+
+[GEN3_2:GENERA3]
+Look, you wanna do something other than just shadowing me everywhere? Why don't you come along and show me if you're any use.
+
+[GEN3_3:GENERA3]
+I might just do that. The name's Lance, by the way.
+
+[GEN3_5:GENERA3]
+You must be Cortez's new gun.
+
+[GEN3_6:GENERA3]
+Until more gainful opportunities arise.
+
+[GEN3_7:GENERA3]
+They'll be here any minute - we both better get a good vantage point...
+
+[GEN3_8:GENERA3]
+OK! I'll take the balcony, you get the roof across the yard.
+
+[GEN3_9:GENERA3]
+I live! Dickheads! And it's all down to you! What is your name?
+
+[GEN3_10:GENERA3]
+Tommy.
+
+[GEN3_11:GENERA3]
+I see you soon, amigo, I think!
+
+[GEN3_12:GENERA3]
+Shit. Where's that guy Lance?
+
+[GEN3_14:GENERA3]
+Tommy! I need some help here!
+
+[GEN3_15:GENERA3]
+Don't worry, I got you covered!
+
+[GEN3_16:GENERA3]
+Diaz's men are getting cut down!
+
+[GEN3_19:GENERA3]
+~g~Haitians! They're busting the deal! Protect Diaz!
+
+[GEN3_20:GENERA3]
+~g~The Colonel has arranged some firepower for you at the multistory carpark.
+
+[GEN3_22:GENERA3]
+Diaz's Health:
+
+[GEN3_23:GENERA3]
+~g~You've left Lance behind! Go and get him!
+
+[GEN3_25:GENERA3]
+~r~Lance died!
+
+[GEN3_28:GENERA3]
+~g~Take the briefcase back to Diaz.
+
+[GEN3_29:GENERA3]
+~g~Collect the briefcase and take it back to Diaz.
+
+[GEN3_30:GENERA3]
+~r~He got away with the money! Diaz will have your balls for this!
+
+[GEN3_33:GENERA3]
+~r~Check your fire!! You're supposed to be watching over Diaz and his men, not shooting them!
+
+[GEN3_34:GENERA3]
+~r~There ain't gonna be a deal if you shoot the Cubans!
+
+[GEN3_35:GENERA3]
+~g~He's stolen Diaz's money!
+
+[GEN3_36:GENERA3]
+~g~Grab the bike, chase him down and get Diaz's money back!
+
+[GEN3_37:GENERA3]
+~g~Here come the Cubans. Watch over the deal making sure Diaz and Lance are safe.
+
+[GEN3_38:GENERA3]
+~r~Diaz died! You failed to protect him!
+
+[GEN3_39:GENERA3]
+~g~Get to your vantage point up the stairs.
+
+[GEN3_44:GENERA3]
+~g~Go with Lance to the drop off and watch over Diaz.
+
+[GEN3_45:GENERA3]
+They'll be here any minute, we both better get a good vantage point.
+
+[GEN3_40:GENERA3] { reVC update }
+To ~h~shoot straight ahead ~w~on a ~h~motorbike ~w~press the ~h~~k~~VEHICLE_FIREWEAPON~ ~w~button.
+
+[GEN3_41:GENERA3] { reVC update }
+To ~h~shoot straight ahead ~w~on a ~h~motorbike ~w~press the ~h~~k~~VEHICLE_FIREWEAPON~ ~w~button.
+
+[GEN3_46:GENERA3]
+Sheeit!
+
+[GEN3_47:GENERA3]
+Tommy!
+
+[GEN3_48:GENERA3]
+Damn!
+
+[GEN3_49:GENERA3]
+lance's health:
+
+[GEN3_50:GENERA3]
+~r~You lost Diaz's money! Next time try not to reduce the money to ashes!
+
+[GEN3_51:GENERA3]
+More damned Haitians in a shitty van!
+
+[GEN3_54:GENERA3]
+Don't just stand there, you pricks, chase that Haitian dickhead down!
+
+[GEN3_55:GENERA3]
+Tommy! I'll stay here and watch over Diaz!
+
+[GEN3_18:GENERA3]
+~g~Here come the Cubans, keep close to Diaz. Watch over the deal making Diaz and Lance are safe.
+
+[GEN3_56:GENERA3]
+~r~Diaz was ambushed and died! Next time keep him in your sights!
+
+[GEN3_57:GENERA3]
+The Kruger is an assault rifle, which allows you to manually aim in 1st person.
+
+[GEN3_58:GENERA3]
+Press and hold the~h~ ~k~~PED_LOCK_TARGET~~w~ button to ~h~aim~w~ with an assault rifle.
+
+[GEN3_59:GENERA3]
+Press and hold the~h~ ~k~~PED_LOCK_TARGET~~w~ button to ~h~aim~w~ with an assault rifle.
+
+[GEN3_60:GENERA3]
+Press the ~h~~k~~PED_FIREWEAPON~~w~ button to ~h~fire~w~ an assault rifle.
+
+[GEN3_61:GENERA3]
+Press the ~h~~k~~PED_FIREWEAPON~~w~ button to ~h~fire~w~ an assault rifle.
+
+[GEN3_62:GENERA3]
+Press the ~h~~k~~PED_FIREWEAPON~~w~ button to ~h~fire~w~ an assault rifle.
+
+[GEN3_63:GENERA3]
+As well as performing drive-by's,~h~ motorbikes ~w~allow you to ~h~shoot forwards~w~.
+
+[GEN3_64:GENERA3] { reVC update }
+To shoot forwards while on a bike press the ~h~~k~~VEHICLE_FIREWEAPON~~w~ button.
+
+[GEN3_65:GENERA3] { reVC update }
+To shoot forwards while on a bike press the ~h~~k~~VEHICLE_FIREWEAPON~~w~ button.
+
+[GEN3_66:GENERA3] { reVC update }
+To shoot forwards while on a bike press the ~h~~k~~VEHICLE_FIREWEAPON~~w~ button.
+
+[GEN3_67:GENERA3]
+You must have a sub machine gun to shoot forwards on a motorbike.
+
+[GEN3_53:GENERA3]
+MY MONEY!
+
+[GEN3_52:GENERA3]
+These Haitians think they can take RICARDO DIAZ!?!
+
+{=================================== MISSION TABLE GENERA4 ===================================}
+
+[DETON:GENERA4]
+DETONATION:
+
+[COL4_3:GENERA4]
+CONVOY HALT!
+
+[COL4_6:GENERA4]
+WE'RE TAKING ENEMY FIRE!
+
+[COL4_7:GENERA4]
+Civilian, move away from the tank!
+
+[COL4_8:GENERA4]
+I SAID, move away, IMMEDIATELY!
+
+[COL4_9:GENERA4]
+DEFENSIVE POSITIONS!
+
+[COL4_11:GENERA4]
+Get that civilian out of our way soldier! - Sir, Yes Sir!
+
+[COL4_12:GENERA4]
+Civilian in the TANK! STOP HIM!
+
+[COL4_13:GENERA4]
+This is a military convoy, do not obstruct our route.
+
+[COL4_14:GENERA4]
+Drop him soldier.
+
+[COL4_15:GENERA4]
+Get that civilian vehicle out of our way! - Sir! Moving vehicle Sir!
+
+[COL4_17:GENERA4]
+Ok, PLATOON MOVE IT OUT!
+
+[COL4_18:GENERA4]
+Someone's on the tank Sir!
+
+[COL4_19:GENERA4]
+Go get some doughnuts, soldier! - Sir, Yes Sir!
+
+[COL4_20:GENERA4]
+Target acquired, Sir
+
+[COL4_21:GENERA4]
+SNIPER!
+
+[COL4_22:GENERA4]
+I'm getting out of here.
+
+[COL4_23:GENERA4]
+Objective completed! Platoon dismissed! - Lets go eat some doughnuts.
+
+[COL4_24:GENERA4]
+Security protocol Delta India Echo triggered! Vehicle self destruct initiated!
+
+[COL4_26:GENERA4]
+Prepare to die Communist scum!
+
+[COL4_B2:GENERA4]
+~r~The tank arrived at its destination safely!
+
+[COL4_B5:GENERA4]
+~r~The tank has been destroyed!
+
+[COL4_01:GENERA4]
+Diaz was pleased, and would like to meet you again.
+
+[COL4_02:GENERA4]
+Is that a good thing?
+
+[COL4_03:GENERA4]
+Of course! Although I'm starting to think that Diaz was responsible for our unfortunate loss...
+
+[COL4_04:GENERA4]
+What makes you say that?
+
+[COL4_05:GENERA4]
+One does not wave accusations at a man like Diaz - I'm merely thinking out loud...
+
+[COL4_06:GENERA4]
+No matter. I have a proposal that you could profit from...
+
+[COL4_07:GENERA4]
+I don't have time to run more errands, Cortez.
+
+[COL4_08:GENERA4]
+I would have thought a man with such dangerous debts would be hungry for opportunities. Please, Tommy, at least hear me out.
+
+[COL4_09:GENERA4]
+Go on...
+
+[COL410:GENERA4]
+I have a buyer for a piece of military hardware that is being taken through town. Pick it up for me...
+
+[COL411:GENERA4]
+and once you get it, I want you to call me immediately, then...
+
+[COL4_B4:GENERA4]
+~g~The tank is locked. Find a way to lure out the occupants.
+
+[COL4_1:GENERA4]
+What's up with the Gunner? - Don't know Sir!
+
+[COL4_4:GENERA4]
+Get topside soldier. - Sir, Yes Sir!
+
+[COL4_B1:GENERA4]
+~g~Go and acquire the piece of military hardware that is being taken through town.
+
+[COL4_B3:GENERA4]
+~g~Drop the tank off in the Colonels lockup before it self destructs.
+
+[COL4_B6:GENERA4]
+~g~Find a way to steal the tank!
+
+[COL4_B7:GENERA4]
+~g~Drive the tank into the garage.
+
+[COL4_B8:GENERA4]
+~g~Get out of the tank and walk out of the garage.
+
+{=================================== MISSION TABLE GENERA5 ===================================}
+
+[COL5A_1:GENERA5]
+Circumstances force a hasty departure, amigo.
+
+[COL5A_2:GENERA5]
+What's the problem?
+
+[COL5A_3:GENERA5]
+Ehh, the French want their missile technology back and after that last incident,
+
+[COL5A_4:GENERA5]
+I feel it is time to find safer harbors.
+
+[COL5A_5:GENERA5]
+Wouldn't it be safer to fly?
+
+[COL5A_6:GENERA5]
+I'd be dead before I reached check-in. Besides, I need to get my merchandise out of the country.
+
+[COL5A_7:GENERA5]
+Need another gun?
+
+[COL5A_8:GENERA5]
+You, my friend, are worth ten guns...
+
+[COL5B_1:GENERA5]
+Thomas, you have protected and served me well.
+
+[COL5B_2:GENERA5]
+But now you must leave us before we reach the open seas.
+
+[COL5B_4:GENERA5]
+Thank you, Colonel.
+
+[COL5B_5:GENERA5]
+One more request. While I'm away, could you keep an eye on Mercedes for me?
+
+[COL5B_6:GENERA5]
+I think she could look after herself, but sure, I'll keep an eye out.
+
+[COL5B_7:GENERA5]
+Gracias, amigo. Hasta luego.
+
+[COL5B_8:GENERA5]
+Adios, amigo.
+
+[COL5_7:GENERA5]
+Stop shooting at me!
+
+[COL5_9:GENERA5]
+Tommy, stop them shooting at me!
+
+[COL5_10:GENERA5]
+I have diplomatic immunity!
+
+[COL5_11:GENERA5]
+Don't shoot, I am a Colonel!
+
+[COL5_12:GENERA5]
+Thomas, kill them, my country will love you.
+
+[COL5_13:GENERA5]
+Tommy, we are being overrun by the French!
+
+[COL5_14:GENERA5]
+Tommy, everywhere I look, there are French men, I hate it!
+
+[COL5_15:GENERA5]
+Tommy, how are you?
+
+[COL5_16:GENERA5]
+This is for Piaf and Gainesbourg and your stupid french bread!
+
+[COL5_1:GENERA5]
+Port side! Port side!
+
+[COL5_2:GENERA5]
+They're attacking from starboard!
+
+[COL5_3:GENERA5]
+The bridge up ahead!
+
+[COL5_4:GENERA5]
+They've got a helicopter!
+
+[COL5_B1:GENERA5]
+~g~Defend the Colonel and his yacht at all costs.
+
+[COL5_B2:GENERA5]
+~g~Get up front and clear the route for the Colonel's yacht.
+
+[COL5_B3:GENERA5]
+~r~The Colonel is dead!
+
+[COL5_B4:GENERA5]
+~g~Shoot the attacking helicopter out of the sky.
+
+[COL5B_3:GENERA5]
+I will lower my personal launch. Keep it, my friend, a token of my gratitude.
+
+[COL5_B5:GENERA5]
+~g~Shoot down the helicopters, do not endanger the yacht.
+
+[COL5_B6:GENERA5]
+~g~You have run out of ammo, get more from the stairs on the top deck.
+
+[COL5_B7:GENERA5]
+~g~You are running low on health, get more from the stairs on the top deck.
+
+{=================================== MISSION TABLE HAIT1 ===================================}
+
+[HAM1_A:HAIT1]
+Hello? Hello?
+
+[HAM1_C:HAIT1]
+You must be the big bad man me grandaddy been chattin' 'bout.
+
+[HAM1_D:HAIT1]
+Tells me tings about you, you know, when he visits,
+
+[HAM1_E:HAIT1]
+and about the others who wait for you.
+
+[HAM1_F:HAIT1]
+Now, we all dead for long time, but you,
+
+[HAM1_G:HAIT1]
+I wouldn't want to be in your shoes, ha ha ha ha ha!
+
+[HAM1_H:HAIT1]
+I got a message to come here.
+
+[HAM1_I:HAIT1]
+Can you hear dem?
+
+[HAM1_J:HAIT1]
+Dem callin' your name, boy, must want you pretty bad, don't ya tink?
+
+[HAM1_K:HAIT1]
+Now you do old Auntie Poulet a turn, huh, maybe she help you.
+
+[HAM1_L:HAIT1]
+Maybe she can give you a little juju after all of dis.
+
+[HAM1_M:HAIT1]
+Give you some magic to give the law man the stink eye, hmmmmm?
+
+[HAM1_N:HAIT1]
+Look, this is all very, um... give me what?
+
+[HAM1_O:HAIT1]
+I,I, I think I've got the wrong address...
+
+[HAM1_P:HAIT1]
+Do me these tings, Tommy......
+
+[HAM1_Q:HAIT1]
+The Cubans, nasty proud foofoos, mmm,
+
+[HAM1_R:HAIT1]
+been making my lovely Haitian boys shake de heads.
+
+[HAM1_S:HAIT1]
+Now they told the policeman where me been stashing my powders.
+
+[HAM1_T:HAIT1]
+Dey tink it drugs, them stupid.
+
+[HAM1_U:HAIT1]
+Now be a good boy Tommy and go and get the powders for Auntie Poulet.
+
+[HAM1_V:HAIT1]
+Yeah, yeah, sure, sure.
+
+[HAM1_1:HAIT1]
+~g~The cops are closing in on our stashes. BE quick, and beat dem to it!
+
+[HAM1_2:HAIT1]
+~r~The cops got to the stash first!
+
+[HAM1_3:HAIT1]
+~g~Get this stuff back to the hideout!
+
+[HAM1_4:HAIT1]
+~g~Good! Now get the next one!
+
+[HAM1_6:HAIT1]
+~r~The Stash was destroyed, you idiot!
+
+[HAM1_7:HAIT1]
+~g~The cops have got our stash! Retrieve it before they get away!
+
+[HAM1_8:HAIT1]
+~g~The cops are on the way to pick up the stash, get a move on!
+
+[HAT_1A:HAIT1]
+~g~Don't move a muscle, chump!
+
+[HAM1_B:HAIT1]
+Come in, my dear, and rest your soul.
+
+{=================================== MISSION TABLE HAIT2 ===================================}
+
+[HAT2_B1:HAIT2]
+~g~Get to the van that contains the flying bombs.
+
+[HAT2_B2:HAIT2]
+Kill the Cubans...
+
+[HAT2_B4:HAIT2]
+...and destroy their boats!
+
+[HAT2_B5:HAIT2]
+~g~The Cubans are making a run for it. Don't let them get away!
+
+[HAT2_B6:HAIT2]
+~r~The RC plane is getting too far out of range!
+
+[HAT2_B7:HAIT2]
+~g~One of the Cubans in escaping in a car. Don't leave any witnesses!
+
+[HAT2_B8:HAIT2]
+~r~You have no RC planes left!
+
+[HAT2_B9:HAIT2]
+RC Planes:
+
+[HAT2_1:HAIT2]
+Oh, sorry, I - I must have the wrong address...
+
+[HAT2_2:HAIT2]
+Well, you might as well come in and rest your soles and have some tea.
+
+[HAT2_3:HAIT2]
+Do you have something there for me, Tommy?
+
+[HAT2_4:HAIT2]
+Yeah...
+
+[HAT2_5:HAIT2]
+This place feels familiar to me, uh - it's - a smell from childhood - a deja vu...
+
+[HAT2_6:HAIT2]
+Now Tommy, I'm going to whisper a lickle errand for you. Hear me well, aye?
+
+[HAT2_7:HAIT2]
+You look like someone I, I...
+
+[HAT2_8:HAIT2]
+The Cubans have fast boats they use to cross the seas with drugs.
+
+[HAT2_9:HAIT2]
+It is their livelihood.
+
+[HAT2_10:HAIT2]
+Me nephew bin making lickle flying bombs to take dem out.
+
+[HAT2_11:HAIT2]
+Blow de boats to coffin wood.
+
+[HAT2_12:HAIT2]
+Thanks for the tea.
+
+[HAT2_B3:HAIT2] { reVC update }
+Press the ~h~~k~~VEHICLE_FIREWEAPON~ ~w~button to drop a bomb. Press the ~h~~k~~VEHICLE_ENTER_EXIT~ ~w~button to cancel.
+
+{=================================== MISSION TABLE HAIT3 ===================================}
+
+[HAM3_A:HAIT3]
+Hello? Hello - uh..I'm looking for somebody around here...
+
+[HAM3_B:HAIT3]
+You looking hungry, Tommy.
+
+[HAM3_C:HAIT3]
+Do I know you?
+
+[HAM3_D:HAIT3]
+Hush now.
+
+[HAM3_E:HAIT3]
+One more ting an I can let you go, Tommy.
+
+[HAM3_F:HAIT3]
+My boys gone war wit dem Cuban boys.
+
+[HAM3_G:HAIT3]
+But no guns.
+
+[HAM3_H:HAIT3]
+Hmm, but de Cubans have a surprise comin'.
+
+[HAM3_I:HAIT3]
+While they fight in de streets, you take this rifle and kill dem in de hubbub.
+
+[HAM3_J:HAIT3]
+No one sees you, no one hear you.
+
+[HAM3_K:HAIT3]
+Now, Tommy, you do this for me, and you no longer tied to my apron strings.
+
+[HAM3_1:HAIT3]
+~g~We must win this battle. If all the Haitians die we lose.
+
+[HAM3_3:HAIT3]
+~g~I expect the Cubans to cheat so be on your guard.
+
+[HAM3_4:HAIT3]
+~r~You have been spotted! The mission is a failure!
+
+[HAM3_5:HAIT3]
+~g~You must kill the Cubans from a distance. You must not be seen.
+
+[HAM3_8:HAIT3]
+~g~Haitians are dying! Improve your aim.
+
+[HAM3_7:HAIT3]
+~g~Look Out! The Cubans have brought reinforcements. Kill them all!!
+
+[HAM3_2:HAIT3]
+~r~The Haitians have died!
+
+[HAM3_L:HAIT3]
+Kay auntie..
+
+{=================================== MISSION TABLE HOTEL ===================================}
+
+[INTB_A:HOTEL]
+Tommy! Tommy, it's been too long.
+
+[INTB_B:HOTEL]
+Hello Sonny.
+
+[INTB_C:HOTEL]
+I know, I know. You're just overwhelmed with emotion.
+
+[INTB_D:HOTEL]
+Fifteen years - seems like only yesterday.
+
+[INTB_E:HOTEL]
+I guess that's a perspective thing.
+
+[INTB_F:HOTEL]
+Hey, doing time for the family is no piece of cake,
+
+[INTB_G:HOTEL]
+but the family looks after its own, ok?
+
+[INTB_H:HOTEL]
+So, how'd the deal go down - you sitting on some white gold?
+
+[INTB_I:HOTEL]
+Look Sonny, we were set up. The deal was an ambush. Harry and Lee are dead.
+
+[INTB_J:HOTEL]
+You better be kidding me Tommy. Tell me you still got the money.
+
+[INTB_K:HOTEL]
+...no Sonny...I don't have the money.
+
+[INTB_L:HOTEL]
+That was my money, Tommy, MY MONEY!
+
+[INTB_M:HOTEL]
+You better not be screwing me Tommy because you know I'm not a man to be screwed with!
+
+[INTB_N:HOTEL]
+Wait Sonny.
+
+[INTB_O:HOTEL]
+You have my personal assurance that I'm going to get your money back and the drugs.
+
+[INTB_P:HOTEL]
+And I'm gonna mail you the dicks of those responsible.
+
+[INTB_Q:HOTEL]
+Hey, I already know that. You're not a fool Tommy, but I warn you, neither am I.
+
+[INTB_R:HOTEL]
+If it was anybody else you'd be DEAD already.
+
+[INTB_S:HOTEL]
+But because it's you, because we got history, I'm gonna let you handle this.
+
+[INTB_T:HOTEL]
+Look, Sonny, you got my word.
+
+[INTB_U:HOTEL]
+I'll be in touch.
+
+{=================================== MISSION TABLE ICECRE1 ===================================}
+
+[ICC1_1:ICECRE1]
+~g~Use your Ice Cream van distribute drugs around Vice City.
+
+[ICC1_3:ICECRE1]
+~g~You receive money for each transaction you make, but the more transactions you make the more police attention you get.
+
+[ICC1_4:ICECRE1]
+~g~There aren't any customers in this area try another one.
+
+[ICC1_5:ICECRE1]
+Deals done:
+
+[ICC1_6:ICECRE1]
+~g~Use the Mr. Whoopee van to distribute Cherry Poppers product around Vice City.
+
+[ICC1_7:ICECRE1]
+~g~You receive money for each transaction you make, but the more transactions you make the more police attention you get.
+
+[ICC1_9:ICECRE1]
+~g~Local gangs will not appreciate you doing business on their turf so expect hostility if you do so.
+
+[ICC1_10:ICECRE1]
+~g~You made ~1~ deals!
+
+[ICC1_11:ICECRE1]
+~g~You made ~1~ deal!
+
+[ICC1_12:ICECRE1]
+PROPERTY ACQUIRED!
+
+[ICC1_13:ICECRE1]
+~r~You didn't make any deals!
+
+[ICC1_14:ICECRE1]
+ICECREAM ASSET COMPLETED
+
+[ICC1_15:ICECRE1]
+~g~The icecream factory will now generate revenue up to a maximum of $~1~. Make sure you collect it regularly.
+
+[ICC1_2:ICECRE1]
+~g~Park your van and press the ~h~~k~~VEHICLE_HORN~~w~ to play your ice cream jingle to notify customers that your ready for business.
+
+[ICC1_16:ICECRE1]
+~g~Use your Mr. Whoopee van to distribute Cherry Poppers product around Vice City.
+
+[ICC1_8:ICECRE1]
+~g~To make a transaction, ~h~park your van ~g~and press the ~h~~k~~VEHICLE_HORN~ ~g~button to play the ice cream jingle to attract customers.
+
+[ICE_AT1:ICECRE1]
+ICECREAM FACTORY ASSET COMPLETED
+
+[ICE_AT2:ICECRE1]
+~g~The Cherry Popper factory will now generate revenue up to a maximum of $~1~. Make sure you collect it regularly.
+
+[ICC1_17:ICECRE1]
+Distribution mission over
+
+[ICC1_18:ICECRE1]
+Total ice cream sales: $~1~
+
+[ICC1_19:ICECRE1]
+Total deals done: ~1~
+
+{=================================== MISSION TABLE ICECUT ===================================}
+
+[ICC1_A:ICECUT]
+Who are you?
+
+[ICC1_B:ICECUT]
+Your new owner.
+
+[ICC1_C:ICECUT]
+Were you now, or at any time, a child?
+
+[ICC1_D:ICECUT]
+What are you talking about?
+
+[ICC1_E:ICECUT]
+Were you a child?
+
+[ICC1_F:ICECUT]
+Yes! Calm down! What's wrong with you?
+
+[ICC1_G:ICECUT]
+I knew it. A child.
+
+[ICC1_H:ICECUT]
+A dirty, stinking, sniveling, snotting, vile, puking, crying little baby!
+
+[ICC1_K:ICECUT]
+Ow! Calm down.
+
+[ICC1_L:ICECUT]
+I HATE babies, and I hate children.
+
+[ICC1_N:ICECUT]
+Enough already!
+
+[ICC1_P:ICECUT]
+You make soft ice cream, okay? It's purely for kids.
+
+[ICC1_Q:ICECUT]
+What kind of psycho are you?
+
+[ICC1_R:ICECUT]
+Just so I understand this, why make children happy if you hate them?
+
+[ICC1_S:ICECUT]
+Oh, you stupid, sniveling, snotty-
+
+[ICC1_T:ICECUT]
+Shut up!
+
+[ICC1_U:ICECUT]
+- Brat!
+
+[ICC1_V:ICECUT]
+The ice cream is a front.
+
+[ICC1_W:ICECUT]
+We distribute other, non-dairy products.
+
+[ICC1_X:ICECUT]
+And if I see a kid, I put him to good use.
+
+[ICC1_Y:ICECUT]
+Don't I, kiddies? Yes - yes, I do. Mummy doesn't love you.
+
+[ICC1_Z:ICECUT]
+She HATES you!
+
+[ICC1_ZA:ICECUT]
+PROPERTY ACQUIRED!
+
+[ICC1_M:ICECUT]
+They're dirty, sniveling, snotting, vile, puking little..
+
+[ICC1_I:ICECUT]
+A baby.. an awful, horrible, disgusting little boo hoo.
+
+[ICC1_J:ICECUT]
+Mommy doesn't love you. You little shit!
+
+{=================================== MISSION TABLE INTRO ===================================}
+
+[INT1_A:INTRO]
+Tommy Vercetti...Huh! shit.
+
+[INT1_B:INTRO]
+Didn't think they'd ever let him out.
+
+[INT1_C:INTRO]
+He kept his head down, helps people forget.
+
+[INT1_D:INTRO]
+People will remember soon enough.
+
+[INT1_E:INTRO]
+When they see him walking down the streets of their neighborhoods.
+
+[INT1_F:INTRO]
+It will be bad for business.
+
+[INT1_G:INTRO]
+Well, what are we gonna do, Sonny?
+
+[INT1_H:INTRO]
+We treat him like an old friend and keep him busy out of town. OK?
+
+[INT1_I:INTRO]
+We been talking about expanding down South, right?
+
+[INT1_J:INTRO]
+Vice City is twenty-four carat gold these days.
+
+[INT1_K:INTRO]
+The Colombians, the Mexicans, hell,
+
+[INT1_L:INTRO]
+even those Cuban refugees are cutting themselves a piece of some nice action.
+
+[INT1_M:INTRO]
+But it's all drugs, Sonny,
+
+[INT1_N:INTRO]
+None of the families will touch that shit!
+
+[INT1_O:INTRO]
+Times are changing.
+
+[INT1_P:INTRO]
+The families can't keep their backs turned while our enemies reap the rewards.
+
+[INT1_Q:INTRO]
+So, we send someone down to do the dirty work for us...
+
+[INT1_R:INTRO]
+and cut ourselves a nice quiet slice. OK?
+
+[INT1_S:INTRO]
+Who's our contact down there?
+
+[INT1_T:INTRO]
+Ken Rosenberg, schmuck of a lawyer.
+
+[INT1_U:INTRO]
+How's he gonna hold Vercetti's leash?
+
+[INT1_V:INTRO]
+We don't need him to.
+
+[INT1_W:INTRO]
+We just set him loose in Vice City,
+
+[INT1_X:INTRO]
+we give him a little cash to get started. OK?
+
+[INT1_Y:INTRO]
+Give it a few months.
+
+[INT1_Z:INTRO]
+Then we go down,
+
+[INT1_A1:INTRO]
+pay him a little visit, right?
+
+[INT1_A2:INTRO]
+see how he's doing.
+
+[INT2_A:INTRO]
+Hey, hey, guys! It's, uh, Ken Rosenberg here! Hey! Heh, heh, hey, great, hey!
+
+[INT2_B:INTRO]
+Well, uh, I'm gonna drive you guys to the meet, okay?
+
+[INT2_C:INTRO]
+Now, I've talked to the suppliers and they are very, huh-ha,
+
+[INT2_D:INTRO]
+keen to start a business relationship, so, uh,
+
+[INT2_E:INTRO]
+if all goes well, we should, uh,
+
+[INT2_F:INTRO]
+be doing very nicely for ourselves, which is, y'know...
+
+[INT2_G:INTRO]
+good..
+
+[INT2_H:INTRO]
+Okay, so. They're brothers, okay.
+
+[INT2_I:INTRO]
+One operates the uh, the business,
+
+[INT2_J:INTRO]
+and the other one does the flying.
+
+[INT2_K:INTRO]
+Now they operate out of Mexico,
+
+[INT2_M:INTRO]
+They own a farm in Panama.
+
+[INT2_N:INTRO]
+Okay, all right, listen -
+
+[INT2_O:INTRO]
+you guys, when we get there should I stay in the car,
+
+[INT2_P:INTRO]
+or do you guys want me to come in with you guys?
+
+[INT2_Q:INTRO]
+No. Stay in the car.
+
+[INT2_R:INTRO]
+You know what, I thought about it,
+
+[INT2_S:INTRO]
+I'm gonna watch the car.
+
+[INT3_A:INTRO]
+Ok, that's them in the chopper.
+
+[INT3_B:INTRO]
+All right, here's the deal.
+
+[INT3_C:INTRO]
+They want a straight exchange on open ground.
+
+[INT3_D:INTRO]
+All right? Ok. Stay tight, let's go.
+
+[INT3_E:INTRO]
+All right. Take it easy, now.
+
+[INT3_F:INTRO]
+I'm right here. The cars running, baby!
+
+[INT3_G:INTRO]
+Got it?
+
+[INT3_H:INTRO]
+100% pure grade-A Colombian, my friend.
+
+[INT3_I:INTRO]
+The greens?
+
+[INT3_J:INTRO]
+Tens and twenties...used.
+
+[INT3_L:INTRO]
+Go on, get out of here! Drive!
+
+[INT4_A:INTRO]
+Screwed! We're screwed!
+
+[INT4_B:INTRO]
+This is soo typical,
+
+[INT4_C:INTRO]
+I poke my head out of the gutter for one freakin' second,
+
+[INT4_D:INTRO]
+and fate shovels shit in my face!
+
+[INT4_E:INTRO]
+Well, screw you!
+
+[INT4_F:INTRO]
+Shut your face and quit complaining! You're alive, aren't ya'?
+
+[INT4_G:INTRO]
+Drop me right up here.
+
+[INT4_H:INTRO]
+Go dump the car, then go get some sleep.
+
+[INT4_I:INTRO]
+I'll drop by your office tomorrow and we can start sorting this mess out.
-{ re3 updates }
+[INT4_J:INTRO]
+OK, that's a good idea, I'll get some sleep.
+
+[INT4_K:INTRO]
+What are you gonna do?
+
+[INT4_L:INTRO]
+Make my way back to my hotel,
+
+[INT4_M:INTRO]
+clear my head, and figure this crap out.
+
+[INT4_N:INTRO]
+OK.
+
+[INTRO1:INTRO]
+I poke my head out of the gutter for one freakin' second and fate shovels shit in my face!
+
+[INTRO2:INTRO]
+Go get some sleep.
+
+[INTRO3:INTRO]
+What are you gonna do?
+
+[INTRO4:INTRO]
+I'll drop by your office tomorrow and we can start sorting this mess out.
+
+[INT3_K:INTRO]
+I think we have a deal, my friend. HA HA!
+
+[INT3_M:INTRO]
+Let me see it.
+
+[INT2_L:INTRO]
+no, no, no, wait...
+
+[INT3_N:INTRO]
+Oh Shit!
+
+{=================================== MISSION TABLE KENT1 ===================================}
+
+[KPM1_A:KENT1]
+Awright mush, I'm gonna save your Vera, mate.
+
+[KPM1_B:KENT1]
+What the hell are you talking about?
+
+[KPM1_C:KENT1]
+You know that wanker Diaz, the Bugle Master.
+
+[KPM1_D:KENT1]
+He's got your boy, Lance. Word is your mate tried to jump him...
+
+[KPM1_E:KENT1]
+didn't jump high enough if you know what I mean.
+
+[KPM1_F:KENT1]
+Where did he take him? In plain English?
+
+[KPM1_G:KENT1]
+Keep your barnet on! They got him across town at the junkyard.
+
+[KPM1_H:KENT1]
+Bloody hell....you nutter!
+
+[KPM1_2:KENT1]
+~r~You were supposed to get Lance out alive!
+
+[KPM1_3:KENT1]
+LANCE'S HEALTH:
+
+[RESC_1:KENT1]
+You ok to use a gun?
+
+[RESC_2:KENT1]
+Sure...I guess...nice to see you, too.
+
+[RESC_3:KENT1]
+Let's get out of here.
+
+[RESC_4:KENT1]
+There goes my careful planning blown to shit, thanks to you. You screwed up real good, Lance!
+
+[RESC_5:KENT1]
+He killed my brother. What do you expect me to do, mow his lawns?
+
+[RESC_6:KENT1]
+We're gonna have to take out that prick Diaz before he takes us out.
+
+[RESC_7:KENT1]
+Get patched up and meet me on the bridge to Star Island, ok?
+
+[RESC_8:KENT1]
+Ok, I got you.
+
+[KPM1_1:KENT1]
+~g~Lance is being held at the junk yard, Go and rescue him!
+
+[KPM1_4:KENT1]
+~g~Get Lance to the hospital!
+
+[M_PASSN:KENT1]
+MISSION PASSED!
+
+[KPM1_5:KENT1]
+~g~Diaz's guys are after you! Get Lance to the hospital.
+
+{=================================== MISSION TABLE KICKSTT ===================================}
+
+[KICK1_2:KICKSTT]
+~r~You did not get back to the bike quickly enough!
+
+[KICK1_7:KICKSTT]
+~r~You have wrecked the bike!
+
+[KICK1_8:KICKSTT]
+~g~Get on the bike!
+
+[KICK1_T:KICKSTT]
+TIME TAKEN:
+
+[KICKTM:KICKSTT]
+~b~EVENT TIME: ~1~:~1~
+
+[KICKTM2:KICKSTT]
+~b~EVENT TIME: ~1~:0~1~
+
+[GETBIKE:KICKSTT]
+~g~You have ~1~ seconds to return to a dirtbike before the mission ends.
+
+[KICK1_1:KICKSTT]
+~g~Complete the course as quickly as possible.
+
+[KICK1_6:KICKSTT]
+~g~Well done!
+
+[KICK_10:KICKSTT]
+~g~Use the Sanchez to complete the course by passing through all of the checkpoints.
+
+[KICK_12:KICKSTT]
+~r~You bottled it!
+
+[KICK_13:KICKSTT]
+~r~You have taken too long!
+
+[KICK_11:KICKSTT]
+~g~To leave the mission stand in the ~q~pink marker~g~ on foot.
+
+{=================================== MISSION TABLE LAWYER1 ===================================}
+
+[LAW1_A:LAWYER1]
+Go get some sleep, he says -
+
+[LAW1_B:LAWYER1]
+- I have been sitting in this chair all night with the lights off drinking coffee!
+
+[LAW1_C:LAWYER1]
+This is a disaster. We are so screwed, man!
+
+[LAW1_D:LAWYER1]
+These gorillas, listen to me, are gonna come down here and rip my head off. It's ridiculous!
+
+[LAW1_E:LAWYER1]
+I did NOT go to law school for this! Ok, now what the hell are we gonna do?
+
+[LAW1_F:LAWYER1]
+Shut up, sit down, relax. I'll tell you what we're gonna do.
+
+[LAW1_G:LAWYER1]
+You're gonna find out who took our cocaine - and then, I'm gonna kill them.
+
+[LAW1_H:LAWYER1]
+That's a good idea. That's a GREAT idea. Let me think, let me think, let me think.
+
+[LAW1_I:LAWYER1]
+- OH! There's this retired Colonel, Colonel Juan Garcia Cortez.
+
+[LAW1_J:LAWYER1]
+He's the one that helped me set up this deal
+
+[LAW1_K:LAWYER1]
+well away from Vice City's established thugs. Ok?
+
+[LAW1_L:LAWYER1]
+Now, listen. He's holding his party out in the bay on his expensive yacht
+
+[LAW1_M:LAWYER1]
+and all of Vice City's big players are gonna be there. OK?
+
+[LAW1_N:LAWYER1]
+I have an invite, of course I have an invite,
+
+[LAW1_O:LAWYER1]
+but there's no way that I'm going out there, sticking my head out the door - no way! Not gonna happen.
+
+[LAW1_P:LAWYER1]
+I told you, shut up! I'll go myself...
+
+[LAW1_Q:LAWYER1]
+Ho - whoa, whoa! Hey, I like 1978 too, but, y'know, this isn't gonna be a beer and strippers do.
+
+[LAW1_R:LAWYER1]
+I mean, no offense, but I think that you might turn heads on the runway for the wrong reasons.
+
+[LAW1_S:LAWYER1]
+What's wrong with the way I'm dressed?
+
+[LAW1_T:LAWYER1]
+Ok, look, here. Stop by Rafael's, tell him I sent 'ya. He'll make you look respectable.
+
+[LAW1_U:LAWYER1]
+OK, go, c'mon...
+
+[LAWP_1:LAWYER1]
+Buenas noches.
+
+[LAWP_2:LAWYER1]
+I understand you are here on the behalf of Mr. Rosenberg,
+
+[LAWP_3:LAWYER1]
+I hope any recent problems have not affected his health, or uh,
+
+[LAWP_4:LAWYER1]
+mental well being, Mr...uh?
+
+[LAWP_5:LAWYER1]
+Vercetti. He's just got a touch of...agoraphobia.
+
+[LAWP_6:LAWYER1]
+Excellent, excellent. And you?
+
+[LAWP_7:LAWYER1]
+I just want my merchandise.
+
+[LAWP_8:LAWYER1]
+Ah. It's an unfortunate set of circumstances for all involved.
+
+[LAWP_9:LAWYER1]
+Of course I have initiated my own lines of inquiry,
+
+[LAWP_10:LAWYER1]
+but such a delicate matter will take time.
+
+[LAWP_11:LAWYER1]
+Perhaps we will talk later.
+
+[LAWP_12:LAWYER1]
+Meanwhile, let me introduce you to my daughter,
+
+[LAWP_13:LAWYER1]
+Mercedes!
+
+[LAWP_14:LAWYER1]
+Caramia, could you look after our guest while I attend to my necessary obligations?
+
+[LAWP_15:LAWYER1]
+Of course, daddy.
+
+[LAWP_16:LAWYER1]
+Please excuse me.
+
+[LAWP_17:LAWYER1]
+Mercedes!?
+
+[LAWP_18:LAWYER1]
+You try living with it.
+
+[LAWP_19:LAWYER1]
+Anyway, let me point out some of our more distinguished guests...
+
+[LAWP_20:LAWYER1]
+That's our congressman Alex Shrub with rising silicone star Candy Suxxx...
+
+[LAWP_21:LAWYER1]
+And have you met my lovely wife Laura? No?
+
+[LAWP_22:LAWYER1]
+Well, unfortunately she's in Alabama. This is Candy.
+
+[LAWP_23:LAWYER1]
+And over there we have the Vice City Mambas' star tight end, BJ -
+
+[LAWP_24:LAWYER1]
+always the charmer.
+
+[LAWP_25:LAWYER1]
+I blocked down on him and then I put him in a wheelchair!
+
+[LAWP_26:LAWYER1]
+Haha, that is good!
+
+[LAWP_27:LAWYER1]
+Well now, I'm looking at some prime real estate property.
+
+[LAWP_28:LAWYER1]
+And that poolside amphibian is Jezz Torrent,
+
+[LAWP_29:LAWYER1]
+lead singer with Love Fist.
+
+[LAWP_30:LAWYER1]
+Can I tell yous - do you know how they play ping-pong in Thailand?
+
+[LAWP_31:LAWYER1]
+Let me tell you's,
+
+[LAWP_32:LAWYER1]
+it does not involve a paddle, if you know what I mean!
+
+[LAWP_33:LAWYER1]
+Impotent.
+
+[LAWP_34:LAWYER1]
+And the chatty trio.
+
+[LAWP_35:LAWYER1]
+That sleeping sweat gland is Papa's right hand gimp, Gonzalez
+
+[LAWP_36:LAWYER1]
+and the other two are Pastor Richards
+
+[LAWP_37:LAWYER1]
+and pseudo intellectual film director, Steve Scott.
+
+[LAWP_38:LAWYER1]
+...passion with the nympho invaders,
+
+[LAWP_39:LAWYER1]
+when the giant shark comes in and
+
+[LAWP_40:LAWYER1]
+just bites their dicks off!
+
+[LAWP_41:LAWYER1]
+Ha now, you never saw anything like that before, have you?
+
+[LAWP_42:LAWYER1]
+Colonel!
+
+[LAWP_43:LAWYER1]
+your parties as ever are a triumph, hahahaha!
+
+[LAWP_44:LAWYER1]
+I can only apologize for my late arrival.
+
+[LAWP_45:LAWYER1]
+Ah, de nada amigo. How do we find you?
+
+[LAWP_46:LAWYER1]
+Our business is very trying - barbarians at the gates.
+
+[LAWP_47:LAWYER1]
+A time for rewarding one's friends and liquidating one's enemies, amigo.
+
+[LAWP_48:LAWYER1]
+Who's the loudmouth?
+
+[LAWP_49:LAWYER1]
+Ricardo Diaz. He's Mr. Coke.
+
+[LAWP_50:LAWYER1]
+Mercedes!
+
+[LAWP_51:LAWYER1]
+Oh, I was just taking my friend back into town.
+
+[LAWP_52:LAWYER1]
+Another time, Ricardo!
+
+[LAWP_53:LAWYER1]
+Let's get out of here.
+
+[LAWP_54:LAWYER1]
+Actually, take me to the Pole Position club.
+
+[LAW1_2:LAWYER1]
+~g~Get to the Colonel's boat.
+
+[LAW1_4:LAWYER1]
+~r~You killed the Colonel's daughter!
+
+[LAW1_5:LAWYER1]
+Will you be working for my father?
+
+[LAW1_6:LAWYER1]
+Maybe.
+
+[LAW1_7:LAWYER1]
+Do you mind me resting my hand in your lap?
+
+[LAW1_8:LAWYER1]
+Maybe...
+
+[LAW1_9:LAWYER1]
+It's so difficult having a rich and powerful father. Vamos.
+
+[LAW1_10:LAWYER1]
+See you around, handsome!
+
+[LAW1_11:LAWYER1]
+I'm sure you will.
+
+[LAW1_12:LAWYER1]
+Hmmmm...nice bike.
+
+[LAW1_13:LAWYER1]
+No! My Bike!
+
+[LAW1_3:LAWYER1]
+~g~Take the Colonel's daughter to the Pole Position club.
+
+[HELP20:LAWYER1]
+Follow the ~h~T-shirt~w~ blip on the radar to find Rafael's.
+
+[LAW1_14:LAWYER1]
+Wow, I like, really dig your motorcycle.
+
+[LAW1_15:LAWYER1]
+Yeah babe, just picked it up from Howlin' Pete's
+
+{=================================== MISSION TABLE LAWYER2 ===================================}
+
+[LAW2_A:LAWYER2]
+Ah! Well, I hope you're having a good time. Because I'm going out of my mind with worry here. What did you find out?
+
+[LAW2_B:LAWYER2]
+That there are more criminals in this town than in prison. We need a lead from the streets...
+
+[LAW2_C:LAWYER2]
+Ok, let me think, let me think, let me think -
+
+[LAW2_D:LAWYER2]
+- AH! I've got it!
+
+[LAW2_E:LAWYER2]
+Ok, There's this limey, some music industry slimeball,
+
+[LAW2_F:LAWYER2]
+goes by the name of Kent Paul.
+
+[LAW2_G:LAWYER2]
+Anyway, he's got his nose so far up most of Vice City's ass
+
+[LAW2_I:LAWYER2]
+it's this guy, all right? He's always at The Malibu.
+
+[LAW2_J:LAWYER2]
+I'll go pay him a visit.
+
+[LAW2B_A:LAWYER2]
+Where'd you pop up from?
+
+[LAW2B_B:LAWYER2]
+I've been looking for a bird like you for ages, mate...
+
+[LAW2B_C:LAWYER2]
+Kent Paul, mate. Yeah, I'm the guvnor 'round here.
+
+[LAW2B_D:LAWYER2]
+I'm looking for some English guy...
+
+[LAW2B_E:LAWYER2]
+I sort things out, you know what I mean?
+
+[LAW2B_F:LAWYER2]
+I'll treat you. Whatever you want, I'll get you, girl.
+
+[LAW2B_G:LAWYER2]
+Don't you worry about a thing, mate.
+
+[LAW2B_H:LAWYER2]
+Get lost, honey.
+
+[LAW2B_I:LAWYER2]
+Oi oi oi oi oi!
+
+[LAW2B_J:LAWYER2]
+You Kent Paul? I'm a friend of Rosenberg's...
+
+[LAW2B_K:LAWYER2]
+Rosenberg...Rosenberg...Oh, that bonkers ambulance chaser!
+
+[LAW2B_L:LAWYER2]
+That guy could defend an innocent man all the way to death row!
+
+[LAW2B_M:LAWYER2]
+Give us another drink, bruv.
+
+[LAW2B_N:LAWYER2]
+Everybody's a comedian.
+
+[LAW2B_O:LAWYER2]
+Listen to me, I'm missing twenty keys and a lot of cash...
+
+[LAW2B_P:LAWYER2]
+Drugs, mate? It's a mug's game.
+
+[LAW2B_Q:LAWYER2]
+What do you know about it?
+
+[LAW2B_R:LAWYER2]
+Oi oi! What I was coming to was,
+
+[LAW2B_S:LAWYER2]
+there's some chef-cum-trumpetshifter who deals out kitchen of a hotel on Ocean Drive.
+
+[LAW2B_T:LAWYER2]
+He's been looking real pleased with himself lately. You could go and check him out...?!
+
+[LAW2B_U:LAWYER2]
+I will - and I'll be seeing you around.
+
+[LAW2B_V:LAWYER2]
+Yeah, that's right. Go on - walk away, you mug. I'll knock you spark out!
+
+[LAW2B_W:LAWYER2]
+Give me a drink - and where's that slut!
+
+[LAW2C_A:LAWYER2]
+Oh, way to go, tough guy. Beat him to a pulp. That should make him real chatty.
+
+[LAW2C_B:LAWYER2]
+You want some, too?
+
+[LAW2C_C:LAWYER2]
+Hey, chill. I want what you want, brother.
+
+[LAW2C_D:LAWYER2]
+Oh, yeah? And what's that?
+
+[LAW2C_E:LAWYER2]
+Your green - and my dead brother's white lady. Unfortunately, you just silenced our lead.
+
+[LAW2C_F:LAWYER2]
+Accidents happen. Get lost.
+
+[LAW2C_G:LAWYER2]
+Hey, hey, whoa. No need to go all 'Lone Ranger' on my ass.
+
+[LAW2C_H:LAWYER2]
+The way I see it - we two hombres in a strange town. We need to watch each other's back.
+
+[LAW2C_I:LAWYER2]
+My back's just fine, brother...
+
+[LAW2C_J:LAWYER2]
+You sure about that? Here, take this.
+
+[LAW2C_K:LAWYER2]
+Follow me!
+
+[LAW2_1:LAWYER2]
+Hey, whatchoo lookin' at?
+
+[LAW2_2:LAWYER2]
+You better start talking..
+
+[LAW2_3:LAWYER2]
+Hey, make me, you prick!
+
+[LAW2_4:LAWYER2]
+This way!
+
+[LAW2_5:LAWYER2]
+I'm going to go see what I can dig up. I'll be watching you, Tommy.
+
+[LAW2_6:LAWYER2]
+~g~Go to the Malibu Club and find Kent Paul.
+
+[LAW2_7:LAWYER2]
+~g~Go and find the chef on Ocean Drive.
+
+[LAW2_10:LAWYER2]
+~g~Drive back to the hotel.
+
+[LAW2_11:LAWYER2]
+~g~Pick up his cell phone.
+
+[LAW2_12:LAWYER2]
+Cell phone acquired! You can now receive phone calls.
+
+[LAW2_13:LAWYER2]
+~g~You've left Lance behind! Go and get him!
+
+[LAW2_14:LAWYER2]
+We gotta get the hell outta here!
+
+[GUN_2A:LAWYER2]
+Hold the ~h~~k~~PED_LOCK_TARGET~ ~w~button to ~h~auto-target~w~, press the ~h~~k~~PED_FIREWEAPON~ ~w~button to ~h~fire!
+
+[GUN_2C:LAWYER2]
+Hold the ~h~~k~~PED_LOCK_TARGET~ ~w~button to ~h~auto-target~w~, press the ~h~~k~~PED_FIREWEAPON~ ~w~button to ~h~fire!
+
+[GUN_2D:LAWYER2]
+Hold the ~h~~k~~PED_LOCK_TARGET~ ~w~button to ~h~auto-target~w~, press the ~h~~k~~PED_FIREWEAPON~ ~w~button to ~h~fire!
+
+[HELP17:LAWYER2]
+Press the ~h~~k~~PED_FIREWEAPON~ ~w~button to attack the chef.
+
+[HELP18:LAWYER2]
+Press the~h~ ~k~~PED_FIREWEAPON~ ~w~button to attack the chef.
+
+[LAW3_11:LAWYER2]
+Stand in the ~q~pink marker~w~ to view the weapons on offer.
+
+[LAW3_12:LAWYER2]
+You can select weapons by pressing ~h~left~w~ or ~h~right~w~ on the ~h~directional button.
+
+[LAW3_13:LAWYER2]
+If you have enough cash you can buy weapons by pressing the ~h~~k~~PED_SPRINT~ ~w~button.
+
+[LAW3_14:LAWYER2]
+You can exit the shop by pressing the ~h~~k~~VEHICLE_ENTER_EXIT~ ~w~button.
+
+[LAW3_15:LAWYER2]
+Follow the ~h~Gun blip~w~ on the radar to find ~h~Ammu-Nation.
+
+[LAW2_15:LAWYER2]
+~g~Go to Ammu-Nation.
+
+[LAW2_H:LAWYER2]
+that if anybody knows the whereabouts of 20 k's of coke,
+
+[LAW2_K:LAWYER2]
+Take it easy now.
+
+[LAW2_16:LAWYER2]
+One thing you gotta realize about this town. You gotta pack some heat.
+
+[LAW2_17:LAWYER2]
+C'mon, the local gun shop's a couple of blocks away.
+
+[LAW2_18:LAWYER2]
+Tommy, every man needs a little R&R once in a while.
+
+[LAW2_19:LAWYER2]
+This here's the Pole Position Strip Club. You might want to drop in some time.
+
+{=================================== MISSION TABLE LAWYER3 ===================================}
+
+[LAW3_A:LAWYER3]
+Aaah! Oh, for god's sake, it's you! Oh, Jeez - I'm gonna need new pants!
+
+[LAW3_B:LAWYER3]
+Hey, those psychos from up north - they've been on the horn, and they're coming down here soon.
+
+[LAW3_C:LAWYER3]
+Now where is the goddamn money?!
+
+[LAW3_D:LAWYER3]
+Relax, relax. We're not at that part yet.
+
+[LAW3_E:LAWYER3]
+Ohhh... I thought that you were taking care of this, I really did!
+
+[LAW3_F:LAWYER3]
+And now those guidos say we gotta do them a favor.
+
+[LAW3_G:LAWYER3]
+You mean I gotta do 'em a favor.
+
+[LAW3_H:LAWYER3]
+Oh, of course that's what I mean. Do I look like I can intimidate a jury?
+
+[LAW3_I:LAWYER3]
+I couldn't intimidate a child - and believe me, I've tried.
+
+[LAW3_J:LAWYER3]
+Now, look. It's either that, or Forelli's cousin, Giorgio, gets five years for fraud.
+
+[LAW3_K:LAWYER3]
+You gotta take these guys OUT!
+
+[LAW3_L:LAWYER3]
+I understand. Help the jury change their minds. Don't worry about it.
+
+[LAW3_M:LAWYER3]
+No no no no no - NO! I tried that. The jury case didn't go so well,
+
+[LAW3_N:LAWYER3]
+so MAKE them change their minds.
+
+[LAW3_1:LAWYER3]
+Giorgio sends his regards.
+
+[LAW3_2:LAWYER3]
+Remember, guilty is a dirty word.
+
+[LAW3_3:LAWYER3]
+Innocent until I say otherwise.
+
+[LAW3_4:LAWYER3]
+You know he's not guilty.
+
+[LAW3_5:LAWYER3]
+You remember Giorgio? You remember he's innocent.
+
+[LAW3_6:LAWYER3]
+Not guilty, understand? Good.
+
+[LAW3_8:LAWYER3]
+~r~You killed a Juror!
+
+[LAW3_9:LAWYER3]
+~g~Smash up the Juror's car to get him out!
+
+[HELP40:LAWYER3]
+You can smash cars up by using the hammer or a similar weapon.
+
+[HELP41:LAWYER3]
+or you can ram them with a vehicle
+
+[LAW3_20:LAWYER3]
+~g~Smash up the Juror's car!
+
+[LAW3_21:LAWYER3]
+I can't believe this is happening!
+
+[LAW3_22:LAWYER3]
+Unbelievable!
+
+[LAW3_23:LAWYER3]
+Ok! Ok, man! I get the message!
+
+[LAW3_24:LAWYER3]
+~g~That hammer would be useful.
+
+[LAW3_7:LAWYER3]
+~g~Go and intimidate the two jurors, but DON'T kill them!
+
+[HELP23:LAWYER3]
+You can follow the ~h~hammer blip~w~ on the radar if you want to buy melee weapons from the hardware store.
+
+[LAW3_16:LAWYER3]
+Dumb Florida Moron.
+
+[LAW3_17:LAWYER3]
+Get out of the way!
+
+{=================================== MISSION TABLE LAWYER4 ===================================}
+
+[LAW4_A:LAWYER4]
+Avery, it goes without saying... Tommy! Tommy! Any progress? No, no, no - tell me later, tell me later.
+
+[LAW4_B:LAWYER4]
+Tommy, this is Avery Carrington - I believe you met at the party?
+
+[LAW4_C:LAWYER4]
+Not in person.
+
+[LAW4_D:LAWYER4]
+Howdy.
+
+[LAW4_E:LAWYER4]
+Avery here has a proposition.
+
+[LAW4_F:LAWYER4]
+Haven't we got other things on our mind?
+
+[LAW4_G:LAWYER4]
+I'm trying to keep the wolves from the door, so could you please cut me some slack?
+
+[LAW4_H:LAWYER4]
+I'm stretched like a wire and even if I'm dead by the end of the week, I'd like to think that I didn't die poor.
+
+[LAW4_I:LAWYER4]
+Now just calm down, both of you.
+
+[LAW4_J:LAWYER4]
+Son, you help me and any greaseballs giving you a hard time, I'll see to it they take a long dirt nap.
+
+[LAW4_K:LAWYER4]
+Ok. What could I do for ya'?
+
+[LAW4_L:LAWYER4]
+This delivery company's got its depot on some prime land. They won't sell.
+
+[LAW4_M:LAWYER4]
+They're hanging on like a big old prairie rat, so we gotta go in there and smoke that vermin out.
+
+[LAW4_N:LAWYER4]
+Head on down there and stir up a hornet's nest
+
+[LAW4_O:LAWYER4]
+- the security will have their hands full and then you can sneak in and put 'em out of business.
+
+[LAW4_P:LAWYER4]
+And you could drop by Rafael's for a change of clothes. You might be there a while, but yeah, go for it.
+
+[LAW4_Q:LAWYER4]
+Should be a riot.
+
+[LAW4_R:LAWYER4]
+If the balls drop like they should, stop by my office sometime...
+
+[LAW4_1:LAWYER4]
+Please disperse. The management will discuss any grievances in the appropriate manner!
+
+[LAW4_2:LAWYER4]
+Please disperse. Go back to your homes!
+
+[LAW4_3:LAWYER4]
+Please disperse! This is inappropriate!
+
+[LAW4_4:LAWYER4]
+Please disperse. You will all end up on the streets.
+
+[LAW4_5:LAWYER4]
+Sticks out, boys! Let's crack some commie skulls!
+
+[LAW4_13:LAWYER4]
+~g~Start fighting with at least 4 workers to get a riot started.
+
+[LAW4_14:LAWYER4]
+~g~Destroy the vans in the compound!
+
+[HELP38:LAWYER4]
+If you take out someone who's holding a weapon, they will drop it.
+
+[HELP39:LAWYER4]
+You can target and shoot explosive barrels but keep your distance.
+
+{=================================== MISSION TABLE MIAMI_1 ===================================}
+
+[T4X4_1A:MIAMI_1]
+~g~You have ~1~ seconds to collect ~y~24~g~ checkpoints. ~g~You may collect them in ~y~ANY ORDER.
+
+[T4X4_1B:MIAMI_1]
+~y~PASS THROUGH~g~ the first checkpoint to start the ~r~TIMER.
+
+[T4X4_1C:MIAMI_1]
+~1~ of 24!
+
+[GETBIK1:MIAMI_1]
+You have ~1~ seconds to get on a PCJ 600!
+
+[GETBIK3:MIAMI_1]
+~r~You need a PCJ 600 to attempt this mission!
+
+{=================================== MISSION TABLE MM ===================================}
+
+[BLOD_04:MM]
+CAR HEALTH:
+
+[BLOD_05:MM]
+~g~TARGET TIME: ~1~ Minute
+
+[BLOD_06:MM]
+~g~TARGET TIME: ~1~ Minutes
+
+[BLOD_07:MM]
+NEW Best Time: ~1~ Seconds
+
+[BLOD_08:MM]
+Cars Destroyed: ~1~
+
+[BLOD_09:MM]
+$~1~
+
+[BLOD_10:MM]
+WINNER!!
+
+[BLOD_01:MM]
+Drive through the checkpoints to increase your overall time.
+
+[BLOD_02:MM]
+You will fail if your overall time reaches zero.
+
+[BLOD_03:MM]
+Get your overall time above the Target Time to win!
+
+{=================================== MISSION TABLE OVALRIG ===================================}
+
+[HOTR_01:OVALRIG]
+~g~The Race lasts for 12 laps. Only 1st, 2nd and 3rd places qualify for winnings.
+
+[HOTR_02:OVALRIG]
+~g~If your car is destroyed you will be disqualified.
+
+[HOTR_03:OVALRIG]
+~g~When your car is damaged you can get it repaired at the pitstop.
+
+[HOTR_04:OVALRIG]
+~g~This is the way to leave the stadium.
+
+[HOTR_05:OVALRIG]
+Car Health:
+
+[HOTR_06:OVALRIG]
+Laps:
+
+[HOTR_07:OVALRIG]
+New best time: ~1~:0~1~
+
+[HOTR_08:OVALRIG]
+Time: ~1~:~1~
+
+[HOTR_10:OVALRIG]
+Race Time:
+
+[HOTR_09:OVALRIG]
+Position:
+
+[HOTR_12:OVALRIG]
+~r~Your car has been destroyed!
+
+[HOTR_13:OVALRIG]
+~r~You didn't win the race!
+
+[HOTR_14:OVALRIG]
+~r~You have been disqualified!
+
+[HOTR_15:OVALRIG]
+Time: ~1~:~1~
+
+[HOTR_16:OVALRIG]
+Time: ~1~:0~1~
+
+[HOTR_17:OVALRIG]
+Best Time: ~1~:~1~
+
+[HOTR_18:OVALRIG]
+Best Time: ~1~:0~1~
+
+[HOTR_19:OVALRIG]
+Best Time: NA
+
+[HOTR_20:OVALRIG]
+New Best Time: ~1~:~1~
+
+[HOTR_21:OVALRIG]
+New Best Time: ~1~:0~1~
+
+[HOTR_22:OVALRIG]
+Best Result: NA
+
+[HOTR_23:OVALRIG]
+Best Result: 1st
+
+[HOTR_24:OVALRIG]
+Best Result: 2nd
+
+[HOTR_25:OVALRIG]
+Best Result: 3rd
+
+[HOTR_26:OVALRIG]
+Best Result: ~1~th
+
+[HOTR_27:OVALRIG]
+Best Lap Time: ~1~.~1~ seconds
+
+[HOTR_28:OVALRIG]
+Best Lap Time: ~1~.0~1~ seconds
+
+[HOTR_29:OVALRIG]
+$~1~
+
+[HOTR_30:OVALRIG]
+1ST PLACE
+
+[HOTR_31:OVALRIG]
+2ND PLACE
+
+[HOTR_32:OVALRIG]
+3RD PLACE
+
+[HOTR_33:OVALRIG]
+Best Lap Time: NA
+
+[HOTR_11:OVALRIG]
+New best lap time: ~1~.~1~ seconds
+
+[HOTR_34:OVALRIG]
+New best lap time: ~1~.0~1~ seconds
+
+{=================================== MISSION TABLE PHIL1 ===================================}
+
+[PHIL1_A:PHIL1]
+Phil?
+
+[PHIL1_B:PHIL1]
+RUN!
+
+[PHIL1_C:PHIL1]
+Run
+
+[PHIL1_E:PHIL1]
+Shit Phil, you drink that stuff?
+
+[PHIL1_F:PHIL1]
+Hell, you don't have to drink it
+
+[PHIL1_G:PHIL1]
+- just a good whiff will set you off. Hoowwee!
+
+[PHIL1_H:PHIL1]
+Listen Phil, you said you could fix me up with some firepower...
+
+[PHIL1_I:PHIL1]
+Sure thing.
+
+[PHIL1_J:PHIL1]
+There's some Mexican gun-runner been doing me for business of late.
+
+[PHIL1_K:PHIL1]
+He does his weekly run about now.
+
+[PHIL1_L:PHIL1]
+Ram his hardware off the back of his trucks before he goes to ground.
+
+[PHIL1_M:PHIL1]
+And you'd be doing me a favor while you're at it.
+
+[PHIL1_N:PHIL1]
+Then finish him off.
+
+[PHI1_01:PHIL1]
+~g~Go and knock the arms off the back of the dealers' trucks.
+
+[PHI1_02:PHIL1]
+~g~The arms dealer dropped his load. Smash the crate and pick up the weapon.
+
+[PHI1_03:PHIL1]
+~g~Looks like they have called for back up.
+
+[PHI1_04:PHIL1]
+~g~Now go and finish off the remaining arms dealers.
+
+[PHI1_HP:PHIL1]
+When using Detonator Grenades, throw a grenade then trigger the explosion at any time.
+
+[PHIL1_O:PHIL1]
+Hoooooweeeeee!
+
+[PHIL1_D:PHIL1]
+Never get a naked flame too close to one of Phil Cassidy's Boomshine stills!
+
+{=================================== MISSION TABLE PHIL2 ===================================}
+
+[PHIL2_A:PHIL2]
+Hey Phil, how's it goin?
+
+[PHIL2_B:PHIL2]
+Heeyyyy, Tommy. Howyadoin'? Ish been too long...
+
+[PHIL2_C:PHIL2]
+I swear you should lay off that boomshine, man -
+
+[PHIL2_D:PHIL2]
+smells like paint stripper. Making my eyes burn...
+
+[PHIL2_E:PHIL2]
+Shshs shhh youshelf Tommy,
+
+[PHIL2_F:PHIL2]
+and come over here because there's someshin' I wanna show you.. someshin.
+
+[PHIL2_G:PHIL2]
+Woof! God! Should I be able to smell that from way over here? I'm feeling woozy.
+
+[PHIL2_H:PHIL2]
+Don'tchaworry about the shmell Tommy, you jush wash thish.
+
+[PHIL2_I:PHIL2]
+Shittycheapbatteriesh or shumin'. There'sh shum more on the bench.
+
+[PHIL2_J:PHIL2]
+TA-DAAA!
+
+[PHIL2_K:PHIL2]
+Aww Damn!
+
+[PHI2_01:PHIL2]
+~g~Quick, get Phil to the hospital.
+
+[PHI2_03:PHIL2]
+~r~Phil Cassidy is dead!!! Now who's gonna supply arms in Vice City?
+
+[PHI2_05:PHIL2]
+Not the hospital, man! Too many cops and Viet Cong!
+
+[PHI2_06:PHIL2]
+There's an ex-army surgeon owes me a few favors and a lawnmower.
+
+[PHI2_07:PHIL2]
+He's got a place down Little Havana - ooo look, a giant fish.
+
+[PHI2_08:PHIL2]
+Watch out! Charlie in the tree line!
+
+[PHI2_09:PHIL2]
+Is it me or are the roads made of jelly?
+
+[PHI2_10:PHIL2]
+Broken Spoon to Mother Hen, you copy?
+
+[PHI2_11:PHIL2]
+Spooney Wooney Woo Woo Woooo!
+
+[PHI2_12:PHIL2]
+He's come for me boy!
+
+[PHI2_13:PHIL2]
+Black feathered wings beating all around...
+
+[PHI2_14:PHIL2]
+It's beautiful, man ... it's beautiful ... but so cold ...
+
+[PHI2_15:PHIL2]
+10-4 we've got a drunk driver.
+
+[PHI2_04:PHIL2]
+PHIL'S HEALTH:
+
+[PHI_AS1:PHIL2]
+PHILS PLACE ASSET COMPLETED
+
+[PHI_AS2:PHIL2]
+~g~New Weapons available to purchase from Phils Place.
+
+{=================================== MISSION TABLE PIZZA ===================================}
+
+[PIZ1_01:PIZZA]
+~g~Go deliver these pizzas, you must throw the pizza to the customers. Do a drive-by to throw the pizzas.
+
+[PIZ1_02:PIZZA]
+~g~You have thrown all your pizzas, go back and get some more.
+
+[PIZ1_05:PIZZA]
+~g~You have five minutes to deliver the orders before the customers phone another pizza shop.
+
+[PIZ1_07:PIZZA]
+~r~You killed the customer! You're fired.
+
+[PIZ1_08:PIZZA]
+~r~You are out of time. You're fired.
+
+[PIZ1_09:PIZZA]
+~r~You destroyed our bike! You're fired.
+
+[PIZ1_11:PIZZA]
+Hey! Get back on the bike!
+
+[PIZ1_12:PIZZA]
+Pizzas left:
+
+[PIZ1_06:PIZZA]
+Press the~h~ ~k~~TOGGLE_SUBMISSIONS~~w~ when on the bike to cancel the mission.
+
+[PIZ1_13:PIZZA]
+Get these delivered nice and hot.
+
+[PIZ1_14:PIZZA]
+Pal, pizza's for you.
+
+[PIZ1_15:PIZZA]
+Hey, come on Mister, deliver these quick.
+
+[PIZ1_16:PIZZA]
+What are you waiting around for Mister? You got pizza to deliver.
+
+[PIZ1_17:PIZZA]
+I know you didn't want to be a pizza boy, well I don't give a damn.
+
+[PIZ1_18:PIZZA]
+Deliver these.
+
+[PIZ1_19:PIZZA]
+These need delivering.
+
+[PIZ1_20:PIZZA]
+Come on Mister, deliver these things or you're sacked.
+
+[PIZ1_21:PIZZA]
+We got people waiting pal.
+
+[PIZ1_22:PIZZA]
+What are you waiting around for? These need delivering!
+
+[PIZ1_23:PIZZA]
+Deliver the damn food Mister.
+
+[PIZ1_24:PIZZA]
+These need delivering pal.
+
+[PIZ1_25:PIZZA]
+Man, can you take these?
+
+[PIZ1_26:PIZZA]
+Mister, deliver these pronto, avamos amigo.
+
+[PIZ1_27:PIZZA]
+Come on, we're in a rush, deliver these.
+
+[PIZ1_28:PIZZA]
+You again? well deliver these quick pal.
+
+[PIZ1_29:PIZZA]
+No wasting time this time pal.
+
+[PIZ1_30:PIZZA]
+Come on you lazy bastard, deliver this crap on time.
+
+[PIZ1_31:PIZZA]
+You'll never get a promotion unless you move faster this time.
+
+[PIZ1_32:PIZZA]
+~r~Pizza's too hot to handle?
+
+[PIZ1_33:PIZZA]
+~g~Return to the restaurant for more orders.
+
+[PIZ1_34:PIZZA]
+~g~Pizza delivered, here's your cash.
+
+[PIZ_WON:PIZZA]
+Pizza Mission Complete. Your max Health increased to 150.
+
+{=================================== MISSION TABLE PORN1 ===================================}
+
+[POR1_A:PORN1]
+Action.
+
+[POR1_B:PORN1]
+Whoa! Now that's big.
+
+[POR1_C:PORN1]
+12 inches. That is regulation baby.
+
+[POR1_D:PORN1]
+CUT!! Who IS this idiot? You! YOU! Why are you in my space? WHY?
+
+[POR1_E:PORN1]
+What is all this crap?
+
+[POR1_F:PORN1]
+Aliens? Fishing poles?
+
+[POR1_G:PORN1]
+Who's ever seen a shark that big?
+
+[POR1_H:PORN1]
+All this stuff's gotta go.
+
+[POR1_I:PORN1]
+Why'd you get in this business, ya prick?
+
+[POR1_J:PORN1]
+Huh?
+
+[POR1_K:PORN1]
+For the pussy, that's why! What is this??
+
+[POR1_L:PORN1]
+This is my art - SECURITY!
+
+[POR1_M:PORN1]
+Look, you pompous asshole, I own you now. I own all of this.
+
+[POR1_N:PORN1]
+We're gonna turn this place around...
+
+[POR1_O:PORN1]
+I'm gonna make you rich.
+
+[POR1_P:PORN1]
+Uh. You're - You - you're Tommy Vercetti? But I thought that you were...
+
+[POR1_Q:PORN1]
+That's right.
+
+[POR1_R:PORN1]
+We're gonna be making some changes around here and start making some real money.
+
+[POR1_S:PORN1]
+Actually, have you ever thought about, umm...
+
+[POR1_T:PORN1]
+But first we're going to need some good-looking broads.
+
+[POR1_U:PORN1]
+Yeh, girls are fine but you... whew!
+
+[POR1_02:PORN1]
+~g~ Go and take out Candy's pimp, then return and pick up Candy.
+
+[POR1_04:PORN1]
+Yo, Candy. I'm looking for movie talent - you interested?
+
+[POR1_05:PORN1]
+Sure! But, you'd have to talk to my agent...
+
+[POR1_06:PORN1]
+The HELL are you doin'?
+
+[POR1_07:PORN1]
+You should have stayed at home today!
+
+[POR1_7B:PORN1]
+Can you believe this asshole?
+
+[POR1_08:PORN1]
+Hey Mercedes!
+
+[POR1_09:PORN1]
+Hey Tommy! You wanna party?
+
+[POR1_10:PORN1]
+Not now sweets. You interested in doing some movies?
+
+[POR1_11:PORN1]
+Of course. As long as it's cheap and sleazy.
+
+[POR1_13:PORN1]
+~g~Take the girls back to the Studio to meet Steve.
+
+[POR1_17:PORN1]
+Whoa, cool shark!
+
+[POR1_18:PORN1]
+~r~Mercedes is dead!
+
+[POR1_20:PORN1]
+Tommy where are you going? Get back here!
+
+[POR1_21:PORN1]
+Where are you going?
+
+[POR1_22:PORN1]
+Tommy, when are we going to spend some time alone together?
+
+[POR1_01:PORN1]
+~g~Candy Suxxx would be perfect for a starring role!
+
+[POR1_12:PORN1]
+~g~Take Candy with you to meet up with Mercedes.
+
+[POR1_16:PORN1]
+Maybe later, babe...
+
+[POR1_24:PORN1]
+~g~Go back and collect Candy.
+
+[POR1_25:PORN1]
+~g~You have left Candy behind, go and get her.
+
+[POR1_23:PORN1]
+~g~Candy will be taking care of business ~h~Downtown~g~.
+
+[POR1_26:PORN1]
+~g~Here's Candy, looks like she has been with Congressman Shrub again.
+
+[POR1_15:PORN1]
+Tommy, you coming in for a warm-up?
+
+[POR1_14:PORN1]
+Heh heh - you're hired!
+
+[POR1_27:PORN1]
+Come on, let's go.
+
+[POR1_28:PORN1]
+Tommy be careful! My implants aren't insured yet!
+
+[POR1_29:PORN1]
+You call that driving?
+
+[POR1_30:PORN1]
+I can't do porno after this!
+
+[POR1_31:PORN1]
+What? Are you trying to kill me? I thought I was the star!
+
+{=================================== MISSION TABLE PORN2 ===================================}
+
+[POR2_A:PORN2]
+How's filming going, Steve?
+
+[POR2_B:PORN2]
+Well, Candy is a natural and that new girl - she's insatiable!
+
+[POR2_C:PORN2]
+She went through half the cast and crew before I even took a light reading.
+
+[POR2_D:PORN2]
+Anyway, hey, tomorrow we're going on location to shoot the boat scenes -
+
+[POR2_E:PORN2]
+Boat scenes?! What boat scenes?
+
+[POR2_F:PORN2]
+The fishermen are in the throes of passion when this giant shark comes in -
+
+[POR2_G:PORN2]
+What'd I say about the giant shark?
+
+[POR2_H:PORN2]
+I said, 'NO GIANT SHARK', alright?
+
+[POR2_I:PORN2]
+Just keep the cameras pointed at the poontang!
+
+[POR2_J:PORN2]
+Ok ok, hey Tommy, a guy's gotta try, right?
+
+[POR2_K:PORN2]
+Get those flyers printed up?
+
+[POR2_L:PORN2]
+Yeah, but nobody's gonna let us distribute those things, I mean
+
+[POR2_M:PORN2]
+They're just too, uh, they're unimaginative.
+
+[POR2_N:PORN2]
+You don't worry about that.
+
+[POR2_O:PORN2]
+I've got my own ideas for distribution.
+
+[POR2_P:PORN2]
+O.K. Hey, Candy, uh - in my trailer.
+
+[POR2_01:PORN2]
+~g~There is a seaplane that was used as a prop in some old indie film round the back of the studios.
+
+[POR2_02:PORN2]
+~g~Pick one of the checkpoints to start dropping the flyers from.
+
+[POR2_03:PORN2]
+~g~Drop the flyers all the way to the end checkpoint.
+
+[POR2_04:PORN2]
+~r~LOW FUEL!!!
+
+[POR2_05:PORN2]
+~g~Use it to distribute the flyers around town.
+
+[DILDO:PORN2]
+Skimmer Fuel:
+
+[POR2_Q:PORN2]
+Oh, boy.
+
+[PORN2_9:PORN2]
+~g~You have ~1~ seconds to return to a Skimmer before the mission ends.
+
+{=================================== MISSION TABLE PORN3 ===================================}
+
+[POR3_A:PORN3]
+Ok, what's the problem now?
+
+[POR3_B:PORN3]
+SSShhhh!
+
+[POR3_C:PORN3]
+Well, after his close encounter with the nympho-invaders,
+
+[POR3_D:PORN3]
+our hero finds himself unable to think of anything but this huge phallic mountain -
+
+[POR3_E:PORN3]
+and that's when I want to do the scene with the vat of mashed potatoes, but then we, uh -
+
+[POR3_F:PORN3]
+I don't give a crap about that!
+
+[POR3_G:PORN3]
+J - Just keep going, keep going!
+
+[POR3_H:PORN3]
+Hey Tommy...
+
+[POR3_I:PORN3]
+You mentioned something about some legal problem on the phone?
+
+[POR3_J:PORN3]
+Congressman Alex Shrub has jumped on the pre-election bandwagon, he's going after the puritan vote.
+
+[POR3_K:PORN3]
+Rumors are he's gonna support measures to restrict, shall we say,
+
+[POR3_L:PORN3]
+the more fleshy aspects of this nation's great entertainment industry.
+
+[POR3_M:PORN3]
+Great.
+
+[POR3_N:PORN3]
+Candy! You know Shrub,
+
+[POR3_O:PORN3]
+you guys get up to anything kinky?
+
+[POR3_P:PORN3]
+Oh yeah, oh yeah, oh yeah! Yes yes yes YES OOOoooh!
+
+[POR3_Q:PORN3]
+Please - tell me you got that.
+
+[POR3_R:PORN3]
+Was that part of the, uh... or was she talking to..?
+
+[POR3_S:PORN3]
+Hey, I can never tell. Anyway...
+
+[POR3_T:PORN3]
+You're probably best following her after the shoot,
+
+[POR3_U:PORN3]
+see if she'll lead you to their new love nest.
+
+[POR3_V:PORN3]
+You got a camera?
+
+[POR3_X:PORN3]
+Yeah. Get him a camera.
+
+[POR3_02:PORN3]
+~r~You've killed the Congressman! There's no way you can blackmail him now.
+
+[POR3_03:PORN3]
+~r~You've alerted the Congressman's protection, they will get him out of there immediately.
+
+[POR3_04:PORN3]
+Uh, Candy, could you call me Martha?
+
+[POR3_05:PORN3]
+Oh Alex - I mean Martha. Whatever you say...
+
+[POR3_06:PORN3]
+Martha, someone's watching.. how kinky.
+
+[POR3_07:PORN3]
+You! Give me that camera!
+
+[POR3_01:PORN3]
+~g~Follow Candy's ~h~Stretch~g~.
+
+[POR3_15:PORN3]
+~r~You trashed Candy's Stretch!
+
+[POR3_17:PORN3]
+~g~Get back to the Porn Studios with the film.
+
+[POR3_19:PORN3]
+~r~You ran out of film!
+
+[POR3_21:PORN3]
+~g~You lost Candy's Stretch!
+
+[POR3_22:PORN3]
+~g~The WK Chariot Hotel across from his balcony should provide an ideal photo-grabbing location.
+
+[POR3_23:PORN3]
+~g~There is a side door that will allow you access to the hotel.
+
+[POR3_08:PORN3]
+Press and hold the~h~ ~k~~PED_LOCK_TARGET~ ~w~button to ~h~target~w~ with the camera.
+
+[POR3_09:PORN3]
+Press and hold the~h~ ~k~~PED_LOCK_TARGET~ ~w~button to ~h~target ~w~with the camera.
+
+[POR3_10:PORN3]
+Press the~h~ ~k~~PED_SNIPER_ZOOM_IN~ ~w~button to ~h~zoom in ~w~with the camera and the~h~ ~k~~PED_SNIPER_ZOOM_OUT~ ~w~button to ~h~zoom out ~w~again.
+
+[POR3_11:PORN3]
+Press the~h~ ~k~~PED_SNIPER_ZOOM_IN~ ~w~button to ~h~zoom in ~w~with the camera and the~h~ ~k~~PED_SNIPER_ZOOM_OUT~ ~w~button to ~h~zoom out ~w~again.
+
+[POR3_12:PORN3]
+Press the~h~ ~k~~PED_FIREWEAPON~ ~w~button to take a picture.
+
+[POR3_13:PORN3]
+Press the~h~ ~k~~PED_FIREWEAPON~ ~w~button to take a picture.
+
+[POR3_14:PORN3]
+Press the~h~ ~k~~PED_FIREWEAPON~ ~w~button to take a picture.
+
+[POR3_20:PORN3]
+~g~If you need transport, use the ~h~Sparrow~g~ round the back.
+
+[POR3_16:PORN3]
+~g~You need three good blackmail photographs of Alex Shrub with Candy.
+
+[POR3_24:PORN3]
+PHOTOS TAKEN:
+
+{=================================== MISSION TABLE PORN4 ===================================}
+
+[POR4_A:PORN4]
+I'm sorry, but I just can't swallow this right now.
+
+[POR4_B:PORN4]
+Oh COME ON darling!
+
+[POR4_C:PORN4]
+He's hung like a sperm whale for pity's sake,
+
+[POR4_D:PORN4]
+how can you not feel the part?!
+
+[POR4_E:PORN4]
+But Stevie...
+
+[POR4_F:PORN4]
+How's my star director?
+
+[POR4_G:PORN4]
+Oh, man. The struggle between the artistic integrity and
+
+[POR4_H:PORN4]
+the humping, pumping action continues unabated.
+
+[POR4_I:PORN4]
+And before you ask, yes, all four videos will be released by their...
+
+[POR4_J:PORN4]
+Honey, can you PLEASE keep the anaconda in the shot,
+
+[POR4_K:PORN4]
+he costs more per hour than you do!
+
+[POR4_L:PORN4]
+Oh, sorry Steve.
+
+[POR4_M:PORN4]
+I was thinking, we need some kind of big stunt to really promote the launch.
+
+[POR4_N:PORN4]
+Something that will make a real impact on the City - you got any ideas?
+
+[POR4_O:PORN4]
+Well, in the old days they used to have gala events,
+
+[POR4_P:PORN4]
+stars, limos, the night sky crisscrossed with searchlights...
+
+[POR4_Q:PORN4]
+Searchlights! I've got an idea...
+
+[POR4_R:PORN4]
+...yeah, yeah, yeah. The little sequined numbers, and the limos, oh, premieres
+
+[POR4_S:PORN4]
+Oh, yes ma'am, of course ma'am,
+
+[POR4_T:PORN4]
+and the press, and the barrage of lights...
+
+[POR4_01:PORN4]
+~g~Go ~y~Downtown~g~ and adjust the spotlight on top of the building.
+
+[POR4_02:PORN4]
+~g~A fast bike will be needed to jump from roof to roof. The Security Guard usually drives a ~y~PCJ 600~g~ to work...
+
+[POR4_03:PORN4]
+~g~You will need to get onto the roofs of the buildings. There should be a lift into one of the upper offices...
+
+[POR4_06:PORN4]
+~g~Return to the lower office if you need access to the rooftops again.
+
+[POR4_07:PORN4]
+~g~You will need a bike so you can jump from building to building.
+
+[POR4_08:PORN4]
+~g~Smash through the window to start the course. You have until 07:00 before it gets too light to get up there unseen.
+
+[POR4_09:PORN4]
+~g~The pickups will show you which building to jump to next.
+
+[POR4_10:PORN4]
+~r~It's too light to get up there unseen.
+
+[POR4_11:PORN4]
+~g~Return to the ladder if you need access to the rooftops again.
+
+[POR4_05:PORN4]
+~g~These stairs will lead round to a lower office.
+
+[POR_AS1:PORN4]
+FILM STUDIO ASSET COMPLETED
+
+[POR_AS2:PORN4]
+~g~Inter Global Films will now generate revenue up to a maximum of $~1~. Make sure you collect it regularly.
+
+{=================================== MISSION TABLE PROT1 ===================================}
+
+[PRO1_B:PROT1]
+I can't stand this look. Tommy, whadaya say? Whadaya say we put a bar in...
+
+[PRO1_D:PROT1]
+Listen to me,
+
+[PRO1_E:PROT1]
+The time to take over this town is now. It's all out there waiting for us.
+
+[PRO1_F:PROT1]
+We need to start seizing territory,
+
+[PRO1_G:PROT1]
+let Vice City know we're the new players in town, know what I'm saying?
+
+[PRO1_I:PROT1]
+What you need is a legitimate front Tommy, real estate. It's never done me no harm.
+
+[PRO1_J:PROT1]
+We need to start using some muscle or we can kiss all that hard work goodbye.
+
+[PRO1_K:PROT1]
+Local businesses know Diaz is dead, and they're refusing to pay protection!
+
+[PRO1_L:PROT1]
+Ooh! We could try bribery...
+
+[PRO1_M:PROT1]
+Bribery? Screw bribery! I'll show you how to make 'em scared!
+
+[PRO1_01:PROT1]
+~g~Do a hit and run on the shop fronts and the owners will be begging for protection.
+
+[PRO1_03:PROT1]
+~r~This was supposed to be a hit and run, not a 'hit and have coffee'.
+
+[PRO1_04:PROT1]
+My livelihood, destroyed!
+
+[PRO1_05:PROT1]
+Ruined...RUINED!!
+
+[PRO1_06:PROT1]
+I pay through the ass for protection!
+
+[PRO1_07:PROT1]
+My beautiful window display!
+
+[PRO1_08:PROT1]
+My store. My wonderful store.
+
+[PRO1_09:PROT1]
+Vercetti. Remember the name.
+
+[PRO1_10:PROT1]
+I run this town now. ME!
+
+[BUYP1:PROT1]
+You can now buy property in certain areas of the map.
+
+[BUYP2:PROT1]
+If you see a green house pickup, you can buy that property.
+
+[PRO1_N:PROT1]
+I'll be back here in five minutes...
+
+[PRO1_11:PROT1]
+~g~Get to ~y~The North Point Mall~g~ in ~y~Vice Point~g~.
+
+[PRO1_12:PROT1]
+~g~Smash the panes of glass in each shop front and the owners will be begging for new protection.
+
+[PRO1_A:PROT1]
+Oh, we gotta redecorate this place. We gotta make it look older.
+
+[PRO1_C:PROT1]
+You're my lawyer, Rosenberg, not my interior decorator. Got it?
+
+[BUYP3:PROT1]
+Stand inside the pickup, then press the ~h~~k~~PED_ANSWER_PHONE~~w~ button to purchase that property.
+
+[PRO1_13:PROT1]
+~g~You have five minutes to smash them all.
+
+{=================================== MISSION TABLE PROT2 ===================================}
+
+[PRO2_A:PROT2]
+What's the problem?
+
+[PRO2_B:PROT2]
+Some bar is refusing to pay.
+
+[PRO2_C:PROT2]
+They reckon they're protected by a local gang of thugs.
+
+[PRO2_D:PROT2]
+But don't worry Tommy, I can handle it.
+
+[PRO2_E:PROT2]
+You call this handling it?
+
+[PRO2_F:PROT2]
+You two, off your asses...
+
+[PRO2_G:PROT2]
+Let's go.
+
+[PRO2_10:PROT2]
+~g~Two more have made a run for it. Track them down and finish this.
+
+[PRO2_11:PROT2]
+Get in the car, useless.
+
+[PRO2_02:PROT2]
+Your protection needs a little more protection.
+
+[PRO2_03:PROT2]
+Aw hell, not again! I don't need this crap!
+
+[PRO2_04:PROT2]
+These idiots operate out of DBP Security around the block.
+
+[PRO2_05:PROT2]
+You guys just sort it out amongst yourselves.
+
+[PRO2_06:PROT2]
+I'll be seeing you later.
+
+[PRO2_07:PROT2]
+Yeah, yeah, whatever.
+
+[PRO2_09:PROT2]
+~g~Go and speak to the Front Page Bar Owner.
+
+[PRO2_01:PROT2]
+~g~Take out the guards protecting the Front Page Bar and find out who supplied them.
+
+[PRO2_08:PROT2]
+~g~DBP Security will know you are on your way, go and get them before they clear out.
+
+{=================================== MISSION TABLE PROT3 ===================================}
+
+[PRO3_A:PROT3]
+You moron! What were you thinking?!
+
+[PRO3_B:PROT3]
+Do you realize what this means?!
+
+[PRO3_C:PROT3]
+We could all be sunk!
+
+[PRO3_D:PROT3]
+The timer must have got screwed.
+
+[PRO3_E:PROT3]
+That place was wired to go up like a firework factory.
+
+[PRO3_F:PROT3]
+Then somebody tipped off the cops...
+
+[PRO3_G:PROT3]
+What's the problem, fellas?
+
+[PRO3_H:PROT3]
+Mike was supposed to torch some place in the mall,
+
+[PRO3_I:PROT3]
+but he screwed the fuses and now the cops are crawling all over it.
+
+[PRO3_J:PROT3]
+We gotta get our stuff and get out of here!
+
+[PRO3_K:PROT3]
+Relax, both of you, let me think for a second!
+
+[PRO3_L:PROT3]
+Tommy Vercetti just doesn't cut and run.
+
+[PRO3_M:PROT3]
+The cops are gonna be going over that building with a fine toothed comb, right?
+
+[PRO3_N:PROT3]
+But that takes time.
+
+[PRO3_O:PROT3]
+We gotta go in and torch that place ourselves.
+
+[PRO3_P:PROT3]
+Yeah, but...
+
+[PRO3_Q:PROT3]
+No one but a cop could get within a mile of that place!
+
+[PRO3_R:PROT3]
+So we go as cops.
+
+[PRO3_S:PROT3]
+We gotta get uniforms - and we're gonna need a squad car.
+
+[PRO3_T:PROT3]
+All thanks to you Mike.
+
+[PRO3_U:PROT3]
+I'm sorry.
+
+[PRO3_V:PROT3]
+I got it.
+
+[PRO3_W:PROT3]
+What we got to do is lure the cops in with the finger,
+
+[PRO3_X:PROT3]
+put them in a lock-up
+
+[PRO3_Y:PROT3]
+and jump 'em.
+
+[PRO3_Z:PROT3]
+Good plan. Let's go!
+
+[PRO3_A1:PROT3]
+Alright.
+
+[PRO3_01:PROT3]
+Ok Lance, let's get the cops' attention!
+
+[PRO3_02:PROT3]
+~g~ Take a cop car and go and plant the bomb at the Tarbrush Coffee Shop in the Mall.
+
+[PRO3_03:PROT3]
+~g~ You've left Lance behind, go and get him.
+
+[PRO3_04:PROT3]
+~g~ Let's go.
+
+[PRO3_05:PROT3]
+~r~You killed Lance!
+
+[PRO3_07:PROT3]
+~g~ You have blown your cover. Hurry up and plant the bomb!
+
+[PRO3_09:PROT3]
+Tie 'em up and gag 'em!
+
+[PRO3_10:PROT3]
+Ooo. Fits perfectly!
+
+[PRO3_11:PROT3]
+Bit tight around the crotch though...
+
+[PRO3_12:PROT3]
+Oh yeah yeah, mine too. Mine too.
+
+[PRO3_13:PROT3]
+Easy brother! No cop drives this bad!
+
+[PRO3_14:PROT3]
+Remember - smile at the other cops
+
+[PRO3_15:PROT3]
+Hey there officer. Nice badge, nice badge.
+
+[PRO3_16:PROT3]
+Real smooth, Lance.
+
+[PRO3_17:PROT3]
+Ok, timers are set, 5 seconds and ticking.
+
+[PRO3_18:PROT3]
+5 seconds?!! We got to get the hell out of here!
+
+[PRO3_19:PROT3]
+Now that got them really irritated.
+
+[PRO3_20:PROT3]
+~g~ Get two cops to follow you into the garage.
+
+[PRO3_21:PROT3]
+~g~Get a wanted level so the cops will follow you into the lock-up.
+
+[PRO3_22:PROT3]
+~g~The lock-up door is blocked! You need to clear the door so it can close.
+
+[PRO3_23:PROT3]
+~g~Walk into the marker to plant the bomb.
+
+[PRO3_24:PROT3]
+~g~Get clear of the Cafe!
+
+[PRO_AS1:PROT3]
+PROTECTION RING ASSET COMPLETED
+
+[PRO_AS2:PROT3]
+~g~Vercetti Estate will now generate revenue up to a maximum of $~1~. Make sure you collect it regularly.
+
+[PRO3_08:PROT3]
+~g~ Get back to ~h~Vercetti Estate~g~ on ~h~Starfish Island~g~.
+
+{=================================== MISSION TABLE RACES ===================================}
+
+[RACES_2:RACES]
+~g~You need a vehicle to race, this is not a foot race!
+
+[RACES_3:RACES]
+3..2..1.. GO GO GO!
+
+[RACES_8:RACES]
+~r~You didn't win the race!
+
+[RACES00:RACES]
+Race ~1~:
+
+[RACES01:RACES]
+Terminal Velocity
+
+[RACES02:RACES]
+Ocean Drive
+
+[RACES03:RACES]
+Border Run
+
+[RACES04:RACES]
+Capital Cruise
+
+[RACES05:RACES]
+Tour!
+
+[RACES06:RACES]
+V.C. Endurance
+
+[RACES07:RACES]
+Entrance Fee: $~1~
+
+[RACES08:RACES]
+Best Time: ~1~:~1~
+
+[RACES09:RACES]
+Best Result: 1st
+
+[RACES10:RACES]
+Best Result: 2nd
+
+[RACES11:RACES]
+Best Result: 3rd
+
+[RACES12:RACES]
+Best Result: 4th
+
+[RACES13:RACES]
+Track Length: ~1~.~1~ km
+
+[RACES15:RACES]
+Best Time: NA
+
+[RACES16:RACES]
+Best Result: NA
+
+[RACES19:RACES]
+You cannot afford to enter this race.
+
+[RACES22:RACES]
+Best Time: ~1~:0~1~
+
+[RACES23:RACES]
+Track Length: ~1~.~1~ miles
+
+[RACES_1:RACES]
+~g~Get a fast vehicle and get to the starting grid.
+
+[RACEHLP:RACES]
+~w~Press the~h~ ~k~~PED_SPRINT~ ~w~button to start the selected race. Press the~h~ ~k~~VEHICLE_ENTER_EXIT~ ~w~button to exit.
+
+{=================================== MISSION TABLE RCHELI1 ===================================}
+
+[WRECKED:RCHELI1]
+~r~The vehicle is wrecked!
+
+[RCH1_4:RCHELI1]
+Checkpoints:
+
+[RCH1_7:RCHELI1]
+~g~There are 20 checkpoints in total.
+
+[RCH1_12:RCHELI1]
+~g~The RC helicopter is getting too far out of range!
+
+[RCH1_13:RCHELI1]
+~r~The RC helicopter went out of range!
+
+[RCH1_8:RCHELI1] { reVC update }
+~g~If you wish to quit this mission press the ~h~~k~~VEHICLE_FIREWEAPON~ ~g~button to detonate your RC Helicopter.
+
+{=================================== MISSION TABLE RCPLNE1 ===================================}
+
+[RCPL1_4:RCPLNE1]
+~g~Compete in a CHECKPOINT RACE with 3 other RC Plane's
+
+[RCPL1_5:RCPLNE1]
+~g~Fly through the checkpoints scattered throughout Vice City.
+
+[RCPL1_6:RCPLNE1] { reVC update }
+~g~If you wish to quit this mission press the ~h~~k~~VEHICLE_FIREWEAPON~ ~g~button to detonate your RC Plane.
+
+[RCPL1_8:RCPLNE1]
+~g~Your RC Plane is going out of range!
+
+[RCPL1_9:RCPLNE1]
+~r~Your RC Plane went out of range!
+
+{=================================== MISSION TABLE RCRACE1 ===================================}
+
+[RCRC1_1:RCRACE1]
+~g~Compete in a CHECKPOINT RACE with 3 other RC Bandits over 2 LAPS
+
+[RCRC1_3:RCRACE1]
+~g~Final lap!
+
+[RCR1_4:RCRACE1]
+laps left:
+
+[RCR1_1:RCRACE1]
+~g~Compete in a checkpoint race with 3 other RC Cars.
+
+[RCR1_2:RCRACE1]
+~g~Be the first to complete two laps of the track to win!
+
+[RCR1_6:RCRACE1]
+~g~Your RC Car is going out of range!
+
+[RCR1_7:RCRACE1]
+~r~Your RC Car went out of range!
+
+{=================================== MISSION TABLE ROCK1 ===================================}
+
+[RBM1_A:ROCK1]
+AllllllllRrrighttt!
+
+[RBM1_B:ROCK1]
+Yessss! Brilliant, bloody brilliant!
+
+[RBM1_D:ROCK1]
+Hey, you ever met Love Fist before?
+
+[RBM1_E:ROCK1]
+No, I haven't but I've always loved your music.
+
+[RBM1_F:ROCK1]
+Let me introduce you to the band.
+
+[RBM1_G:ROCK1]
+This is Percy, Dick, and Willy's in the kaze, and that was Jezz in the booth earlier,
+
+[RBM1_H:ROCK1]
+and guys, I want you to meet a good friend of mine.
+
+[RBM1_I:ROCK1]
+This is Tommy. We go way back.
+
+[RBM1_J:ROCK1]
+All right, pal.
+
+[RBM1_K:ROCK1]
+And eh, what was your name again?
+
+[RBM1_L:ROCK1]
+Leave it out, Jezz you, remember -
+
+[RBM1_M:ROCK1]
+don't be playing them games with me, mate,
+
+[RBM1_N:ROCK1]
+I'm too crafty for that, sunshine!
+
+[RBM1_O:ROCK1]
+You see, the thing is, Tom, the boys need some help.
+
+[RBM1_P:ROCK1]
+They ain't too connected here, they don't have the old 'how's your father?'
+
+[RBM1_Q:ROCK1]
+We need some drugs, pal!
+
+[RBM1_R:ROCK1]
+Gonna get on the old Love Fist fury, you know?!
+
+[RBM1_S:ROCK1]
+Well, this is Vice City, man. What's the problem?
+
+[RBM1_U:ROCK1]
+Love Juice, man!
+
+[RBM1_V:ROCK1]
+Love Juice?
+
+[RBM1_W:ROCK1]
+Aye, two parts boomshine, 1 part trumpet, 5 fizz bombs and a liter of petrol.
+
+[RBM1_X:ROCK1]
+Can you help us out, pal?
+
+[RBM1_Y:ROCK1]
+Aw, it would really mean a lot to the boys.
+
+[RBM1_Z:ROCK1]
+You can do that for the boys, right?
+
+[RBM1_7:ROCK1]
+~r~You did not get the Love Juice in time!
+
+[RBM1_8:ROCK1]
+~r~Mercedes is dead!
+
+[RBM1_10:ROCK1]
+~r~You idiot! You have destroyed the merchandise!
+
+[RBM1_13:ROCK1]
+~g~Get the 'Love Juice' and Mercedes to the band before they are needed on stage.
+
+[RBM1_15:ROCK1]
+~r~You have lost the dealer, our cash and the drugs!
+
+[RBM1_17:ROCK1]
+~g~Kill the dealer and get the drugs!
+
+[MOB_07A:ROCK1]
+Hey mate, the guys could do with some company, if you know what I mean...
+
+[MOB_07B:ROCK1]
+I know just the girl.
+
+[ROK1_5:ROCK1]
+Hey, Mercedes!
+
+[ROK1_6:ROCK1]
+Hiya, Tommy. And how are you?
+
+[ROK1_7:ROCK1]
+Just fine. Listen, you fancy having Love Fist?
+
+[ROK1_8:ROCK1]
+Ok, but just as a favor I expect returned..
+
+[RBM1_14:ROCK1]
+~g~You need a car or a motorcycle!
+
+[RBM1_1:ROCK1]
+~g~Go and collect Mercedes from her apartment.
+
+[RBM1_12:ROCK1]
+~g~Go and collect the 'Love Juice' ingredients from the dealer.
+
+[ROK1_2:ROCK1]
+NO LONGER NEEDED
+
+[ROK1_3:ROCK1]
+NO LONGER NEEDED
+
+[MERC_39:ROCK1]
+I'll see you later, big boy.
+
+[RBM1_C:ROCK1]
+Hey, Tommy! Glad you could make it.
+
+[RBM1_9:ROCK1]
+~g~Go and collect some love juice from the dealer for Love Fist!
+
+[ROK1_1A:ROCK1]
+Looking for something special? I got what you need!
+
+[ROK1_9:ROCK1]
+Thanks for the money, sucker!
+
+[RBM1_T:ROCK1]
+We need Love Juice, man, you know?
+
+{=================================== MISSION TABLE ROCK2 ===================================}
+
+[RBM2_A:ROCK2]
+Tommy, man. Am I glad to see you!
+
+[RBM2_B:ROCK2]
+What's going on?
+
+[RBM2_C:ROCK2]
+Bad vibes, Tommy....
+
+[RBM2_E:ROCK2]
+There's this cat, we hardly know him, but he knows us.
+
+[RBM2_F:ROCK2]
+Like this cat. Knows all about us.
+
+[RBM2_G:ROCK2]
+Knows that Willy likes his ladies' underwear, eh!
+
+[RBM2_H:ROCK2]
+Or that Percy likes Duran Duran!
+
+[RBM2_K:ROCK2]
+Yeah, the love rocket thing, right. But listen, this cat...
+
+[RBM2_L:ROCK2]
+yeh, yeh, the guy, he wants Love Fist dead.
+
+[RBM2_M:ROCK2]
+Dead Tommy.
+
+[RBM2_N:ROCK2]
+Love Fist gone. You know what they say, the good die young.
+
+[RBM2_O:ROCK2]
+but Tommy, you gotta save Love Fist!
+
+[RBM2_P:ROCK2]
+We got a signing in two hours and I think...
+
+[RBM2_Q:ROCK2]
+And the boys think the stalker's gonna try some monkey business there.
+
+[RBM2_1:ROCK2]
+~g~Drive the limo to the signing event and try to draw the psycho out.
+
+[RBM2_2:ROCK2]
+~r~You've wrecked the band's car!
+
+[RBM2_3:ROCK2]
+~g~Get to the signing!
+
+[RBM2_4:ROCK2]
+~g~Get the Psycho! Don't let him escape!
+
+[RBM2_5:ROCK2]
+~r~You lost him, you idiot!
+
+[RBM2_7:ROCK2]
+~r~The fans have been attacked, the psycho won't show!
+
+[RBM2_8:ROCK2]
+~r~The security guards have been attacked, the psycho won't show!
+
+[PSYCH_1:ROCK2]
+I'll see Love Fist burn!
+
+[PSYCH_2:ROCK2]
+Love Fist ruined my life!
+
+[RBM2_I:ROCK2]
+Shut up ye fool. Just 'cause Jezz bangs sheep.
+
+[RBM2_R:ROCK2]
+Oi shut it!
+
+[RBM2_D:ROCK2]
+Aye, I'm not joking, it's heavy stuff man, heavy you know?
+
+[RBM2_J:ROCK2]
+It's a love rocket thing, you know?
+
+{=================================== MISSION TABLE ROCK3 ===================================}
+
+[RBM3_A:ROCK3]
+Tommy! Tommy! Tommy, man, that psycho's back!
+
+[RBM3_B:ROCK3]
+What's going on?
+
+[RBM3_C:ROCK3]
+That psycho won't leave Love Fist alone!
+
+[RBM3_D:ROCK3]
+You didnae kill him man. And now he's back.
+
+[RBM3_E:ROCK3]
+Yeah, yeah, yeah, and the thing is...
+
+[RBM3_F:ROCK3]
+The thing is, we need someone to drive the limo we can trust,
+
+[RBM3_G:ROCK3]
+cause that nutter keeps making threats!
+
+[RBM3_I:ROCK3]
+We're all bricking ourselves, man.
+
+[RBM3_J:ROCK3]
+Okay guys, calm down, I'll handle this.
+
+[RBM3_K:ROCK3]
+Normally I wouldn't busy myself with driving around a bunch of drunken Scottish bisexuals,
+
+[RBM3_L:ROCK3]
+but, in your case I'll make an exception.
+
+[RBM3_4:ROCK3]
+~r~You've killed Love Fist!
+
+[RBM3_6:ROCK3]
+DETONATION:
+
+[RBM3_1:ROCK3]
+~g~Drive Love Fist to the venue.
+
+[RBM3_2:ROCK3]
+While the bomb is armed if you try to leave the car it will explode...
+
+[RBM3_3:ROCK3]
+If the detonation bar completely fills the bomb will explode.
+
+[RBM3_8:ROCK3]
+The faster you drive the lower the detonation bar will go.
+
+[RBM3_7:ROCK3]
+~g~BOMB DEFUSED!
+
+[ROK3_62:ROCK3]
+so we thought we'd show you our Temple of Rock -
+
+[ROK3_63:ROCK3]
+Get a feel for that Love Fist fury!
+
+[ROK3_64:ROCK3]
+Listen to yourself, man. It's papier-mache and gaffa tape.
+
+[ROK3_65:ROCK3]
+Hey, to the kids, it's a temple and we are the priests!
+
+[ROK3_66:ROCK3]
+Aye, well, if the kids like their priests half cut and tone deaf,
+
+[ROK3_67:ROCK3]
+who am I to argue?
+
+[ROK3_68:ROCK3]
+Oh geez, the tape's getting chewed again.
+
+[ROK3_69:ROCK3]
+At this rate, we'll never get to play live.
+
+[ROK3_70:ROCK3]
+Oohh shite! My bowels...
+
+[ROK3_73:ROCK3]
+Jezz is running the tape,
+
+[RBM3_9:ROCK3]
+If you are stopped or drive slowly the detonation bar will increase.
+
+[RBM3_H:ROCK3]
+I'm shitin' masel' man. I need ma ma!
+
+[ROK3_71:ROCK3]
+We gotta get on with it - thanks again Tommy, Know what I am saying, nice one, bye!
+
+[ROK3_1:ROCK3]
+At last man, time for a well earned drink. The venue's just a hundred yards down the road.
+
+[ROK3_2:ROCK3]
+Better make it a large one then. Hey Tommy, change the tunes, man.
+
+[ROK3_3:ROCK3]
+I get confused if my head ain't banging. Ah look, what's this? Hey Tommy, stick this tape on.
+
+[ROK3_4:ROCK3]
+Love Fist. Your time polluting the airwaves is over. I gave you the chance to be friends.
+
+[ROK3_5:ROCK3]
+Now, I'm giving you the chance to die. Try to slow down and your limousine will explode, along with your BIG, HAIRY ARSES!
+
+[ROK3_6:ROCK3]
+Tommy pal, you gotta save the band! I'm getting bored of this. Just keep the pedal to the metal!!
+
+[ROK3_7:ROCK3]
+We gotta find the bomb! Can't we just drive around all day? Aye, we've got plenty to drink..
+
+[ROK3_8:ROCK3]
+Won't the bomb not be in the engine? We'll have to stop to get it. We're all going to die! I'm gonna get drunk!
+
+[ROK3_9:ROCK3]
+Hey, there's a queue here pal! The answer ain't in the drinks cabinet! Get out of my way!
+
+[ROK3_10:ROCK3]
+Hey, the vodka bottle's got wires coming out of it! That's not vodka, that's BOOMSHINE!
+
+[ROK3_11:ROCK3]
+WAAAAAAGGGHHHH!!!! And it's wired to blow!! WAAAAAAAAAAAAGGGHHHHHHHH!!!!
+
+[ROK3_12:ROCK3]
+They always said the drink would kill me. I've seen this on the telly. you gotta pull out one of the wires. Which wire? I don't know, man.
+
+[ROK3_13:ROCK3]
+I don't have a clue. Willy, say something. I'm gonna play bass in hell.
+
+[ROK3_14:ROCK3]
+Tommy man, keep driving fast, pal. Somebody do something. Aye, clever!
+
+[ROK3_15:ROCK3]
+'Somebody do something', what kind of crap is that, I've seen braver girls. Okay tough guy, you do something.
+
+[ROK3_16:ROCK3]
+Look, man, I play a musical instrument I don't have a clue about bomb disposal. Willy could just suck the boomshine out with a straw.
+
+[ROK3_17:ROCK3]
+Aye, I've heard that your good at that kind of thing. Hey, I was off my tits that night, as well you know!
+
+[ROK3_18:ROCK3]
+Just pass Willy a straw! A straw?!?! This is the Love Fist Tour Bus!
+
+[ROK3_19:ROCK3]
+Where am I gonna get a straw from, know wot I mean? Which wire, Tommy? The green one. There isn't a green one.
+
+[ROK3_20:ROCK3]
+Or is this one green? Any of these wires look green to you?
+
+[ROK3_21:ROCK3]
+Oh no! Death's on the cards! Everything looks green! I should have dumped you lot when I had the chance man.
+
+[ROK3_22:ROCK3]
+Glory seeker. Capitalist. I've been carrying you for years. Shut up. You're a muppit.
+
+[ROK3_23:ROCK3]
+A big screaming girl. Yeah. Shut up and pull a wire. Which wire? This one..
+
+[ROK3_24:ROCK3]
+NO! Man, we're okay. We ain't been blown up, pal.
+
+[ROK3_25:ROCK3]
+Tommy, man, nice one. Rock and roll, man. Ain't we got a gig to go to?
+
+[ROK3_26:ROCK3]
+A racket to make? Groupies to abuse? LOVE FIST!
+
+[ROK3_27:ROCK3]
+Have you finished with that bottle?
+
+{=================================== MISSION TABLE SERG1 ===================================}
+
+[TEX1_A:SERG1]
+Come in and park yourself on the hide, son.
+
+[TEX1_B:SERG1]
+Hell, my daddy used to say, never look a gift horse in the mouth, and by golly, he never did.
+
+[TEX1_C:SERG1]
+Would you like a drop of the old Kentucky?
+
+[TEX1_D:SERG1]
+No thanks.
+
+[TEX1_E:SERG1]
+A clean thinker! I like that.
+
+[TEX1_F:SERG1]
+Now, the property business isn't all about high-falootin' paper pushing.
+
+[TEX1_G:SERG1]
+It's about dirt! And the will to claim that dirt! You with me, son?
+
+[TEX1_H:SERG1]
+Oh yeah.
+
+[TEX1_K:SERG1]
+Persuasion's my forte.
+
+[TEX1_L:SERG1]
+Yeh, he'll be down at the country club, down on the golf course.
+
+[TEX1_M:SERG1]
+They don't allow guns, so his bodyguards won't be packing lawgivers.
+
+[TEX1_N:SERG1]
+Go beat eight tons of crap out of him.
+
+[TEX1_O:SERG1]
+Here now - I got you a membership, and boy you're going to need more appropriate clothing.
+
+[TEX1_2:SERG1]
+~g~Now head to the Leaf Links Golf Club.
+
+[TEX1_3:SERG1]
+Who's this guy? Boys, deal with him.
+
+[TEX1_6:SERG1]
+Nice ass baby!
+
+[TEX1_7:SERG1]
+Is this me?
+
+[TEX1_I:SERG1]
+Well, I need some tenacious bastard to let go of some dirt,
+
+[TEX1_J:SERG1]
+and you look to me like the kind of guy to persuade him.
+
+[TEX1_0:SERG1]
+~g~The target is at the driving range enjoying a game of golf. Make sure it's his last.
+
+[TEX1_8:SERG1]
+Each time you enter a caddy you automatically receive a golf club, providing your melee weapon slot is empty.
+
+[TEX1_9:SERG1]
+Get him!
+
+[TEX1_10:SERG1]
+Kill that Psycho!
+
+[TEX1_1:SERG1]
+~g~Go and pick up some golfing clothes from Jocksports.
+
+{=================================== MISSION TABLE SERG2 ===================================}
+
+[TEX_2A:SERG2]
+~g~Excellent! They've spotted you!
+
+[TEX_2B:SERG2]
+~r~Fool! People have to WITNESS a Cuban doing the hit!
+
+[TEX_2C:SERG2]
+~g~Go get yourself some Cuban gang colors in Little Havana!
+
+[TEX_2D:SERG2]
+~g~Take out the Haitian Gang Lord at Romero's Funeral Parlor!
+
+[TEX2_A:SERG2]
+Tommy, this is Donald Love. Donald, this here is Tommy Vercetti,
+
+[TEX2_B:SERG2]
+the latest gunslinger to come to these parts.
+
+[TEX2_C:SERG2]
+Yeh...uh...
+
+[TEX2_D:SERG2]
+Donald, you just shut up and listen, and you might learn something.
+
+[TEX2_E:SERG2]
+Now, nothing brings down real estate prices quicker than a good old-fashioned gang war -
+
+[TEX2_F:SERG2]
+'cept maybe a disaster, like a biblical plague or something,
+
+[TEX2_G:SERG2]
+but, that may be going too far in this case.
+
+[TEX2_H:SERG2]
+You getting this down, you four-eyed prick?
+
+[TEX2_I:SERG2]
+Now recently a Haitian gang lord died. Apparently the Cubans did it, nobody's certain.
+
+[TEX2_J:SERG2]
+But let's make them certain! You disguise yourself as a Cuban hombre,
+
+[TEX2_K:SERG2]
+and head on down to crash that funeral. Mix it up, and then high tail it.
+
+[TEX2_L:SERG2]
+You getting this down, Donald?
+
+[TEX2_M:SERG2]
+Well, that ought to put the coyote in the chicken coop, huh?
+
+[TEX2_N:SERG2]
+And then we'll just sit back, and watch the prices tumble.
+
+[TEXEXIT:SERG2]
+~g~Now get out of Little Haiti!
+
+{=================================== MISSION TABLE SERG3 ===================================}
+
+[TEX3_A:SERG3]
+Now look here, son. I got a problem and I reckon you could help me with it.
+
+[TEX3_B:SERG3]
+I'm no builder.
+
+[TEX3_C:SERG3]
+No, I was thinking more of your demolition skills.
+
+[TEX3_D:SERG3]
+Now this here, this is the development as planned and this,
+
+[TEX3_E:SERG3]
+this is the property that we're looking at.
+
+[TEX3_F:SERG3]
+You're trying to say this new office block is kind of in the way.
+
+[TEX3_G:SERG3]
+You catch on quick.
+
+[TEX3_H:SERG3]
+Now I'm going to head out of town for a while
+
+[TEX3_I:SERG3]
+and if that office development were to face sudden and insurmountable structural problems, then I..
+
+[TEX3_J:SERG3]
+As a civil minded individual you'd feel obliged to step in and
+
+[TEX3_K:SERG3]
+save the rejuvenation of an important area of the city?
+
+[TEX3_L:SERG3]
+Where can I get more guys like you?
+
+[TEX3_1:SERG3]
+~g~Use the RC helicopter to transport bombs to four demolition points on the building site.
+
+[TEX3_2:SERG3]
+~g~You must place one bomb at each target. You can place bombs in any order.
+
+[TEX3_3:SERG3]
+~g~Maneuver the RC helicopter next to a bomb to pick it up. it can carry one bomb at a time..
+
+[TEX3_5:SERG3]
+~g~If you place a bomb unsuccessfully you can pick it up and try again.
+
+[TEX3_7:SERG3]
+~g~You must then place the remaining bombs in 7 minutes!
+
+[TEX3_8:SERG3]
+~g~You missed the target! Pick up a bomb and try again!
+
+[TEX3_10:SERG3]
+~g~Drop the bomb at a target.
+
+[TEX3_11:SERG3]
+targets left:
+
+[TEX3_17:SERG3]
+~r~You ran out of time!
+
+[TEX3_18:SERG3]
+~r~Your RC Helicopter has been destroyed!
+
+[TEX3_19:SERG3]
+~r~You dropped your bomb in the water! That ain't no way to fish!
+
+[TEX3_20:SERG3]
+~r~The RC Helicopter is nearly out of range!
+
+[TEX3_21:SERG3]
+~r~The RC Helicopter went out of range!
+
+[TEX3_24:SERG3]
+Press the ~h~~k~~VEHICLE_LOOKLEFT~ ~w~button to rotate the helicopter counter-clockwise.
+
+[TEX3_25:SERG3]
+Press the ~h~~k~~VEHICLE_LOOKRIGHT~ ~w~button to rotate the helicopter clockwise.
+
+[TEX3_27:SERG3]
+~g~A central stairway allows access to all the floors in the building.
+
+[TEX3_31:SERG3]
+~r~You destroyed the TOPFUN van that contained the bombs and RC helicopter!
+
+[TEX3_32:SERG3]
+You can ~h~look behind~w~ by simultaneously pressing the ~h~~k~~VEHICLE_LOOKLEFT~~w~ and the ~h~~k~~VEHICLE_LOOKRIGHT~~w~ buttons.
+
+[TEX3_4:SERG3] { reVC update }
+~g~To drop a bomb press the~h~ ~k~~VEHICLE_FIREWEAPON~ ~g~button.
+
+[TEX3_29:SERG3] { reVC update }
+To drop a bomb press the~h~ ~k~~VEHICLE_FIREWEAPON~ ~w~button.
+
+[TEX3_26:SERG3]
+Pressing the ~h~~k~~VEHICLE_BRAKE~ ~w~button ~w~decreases the rotor speed, causing the helicopter to~h~ descend.
+
+[TEX3_22:SERG3]
+Pressing the ~h~~k~~VEHICLE_ACCELERATE~ ~w~button increases the rotor speed, causing the helicopter to ~h~ascend.
+
+[TEX3_16:SERG3]
+~g~Get to the ~w~TOPFUN ~g~van near the building site to be demolished.
+
+[TEX3_33:SERG3]
+Once you pick up a bomb the radar will show you the position of the target relative to the RC helicopter.
+
+[TEX3_34:SERG3]
+An ~h~upwards pointing triangular blip ~w~indicates the target is ~h~above ~w~the RC helicopter.
+
+[TEX3_35:SERG3]
+A ~h~downward pointing triangular blip ~w~indicates the target is ~h~below ~w~the RC helicopter.
+
+[TEX3_36:SERG3]
+A ~h~square blip ~w~indicates the target is on the ~h~same level ~w~as the RC helicopter
+
+[TEX3_6:SERG3]
+~g~Once you have picked up a bomb for the first time, the detonation timer will start.
+
+[TEX3_28:SERG3]
+To ~h~pick up a bomb~w~, simply maneuver the RC helicopter next to it. The RC Helicopter can carry one bomb at a time.
+
+[TEX3_30:SERG3]
+~g~To pick up a bomb, simply maneuver the RC helicopter next to it. The RC Helicopter can carry one bomb at a time.
+
+[TEX3_12:SERG3]
+~g~Bomb planted! Only 3 more targets to go! Go back and get another bomb.
+
+[TEX3_13:SERG3]
+~g~Bomb planted! Only 2 more targets to go! Go back and get another bomb.
+
+[TEX3_14:SERG3]
+~g~Bomb planted! Only 1 more target to go! Go back and get another bomb.
+
+[TEX3_15:SERG3]
+~r~Detonation timer initiated! ~g~You must plant the ~w~4 bombs ~g~in the remaining time!
+
+[TEX3_37:SERG3]
+Pushing ~h~back on the analog stick ~w~decreases the rotor speed, causing the helicopter to~h~ descend.
+
+[TEX3_38:SERG3] { reVC update }
+{ Pressing the ~h~~k~~VEHICLE_ACCELERATE~ ~w~button increases the rotor speed, causing the helicopter to ~h~ascend. }
+Pushing ~h~forward on the analog stick ~w~increases the rotor speed, causing the helicopter to ~h~ascend.
+
+[TEX3_39:SERG3]
+~g~To drop a bomb press the ~h~~k~~VEHICLE_HANDBRAKE~ ~g~button.
+
+[TEX3_40:SERG3]
+To drop a bomb press the ~h~~k~~VEHICLE_HANDBRAKE~ ~w~button.
+
+[TEX3_23:SERG3]
+Press the ~h~~k~~VEHICLE_TURRETUP~~w~ and ~h~~k~~VEHICLE_TURRETDOWN~~w~ buttons to tilt the helicopter in the direction you wish to maneuver it.
+
+{=================================== MISSION TABLE TAXI1 ===================================}
+
+[FARES:TAXI1]
+FARES:
+
+[TAXI1:TAXI1]
+~g~Look for a fare.
+
+[TSCORE2:TAXI1]
+$~1~
+
+[IN_ROW:TAXI1]
+~1~ IN A ROW bonus! $~1~
+
+[TAXI3:TAXI1]
+~r~Your passenger fled in terror!
+
+[TAXI7:TAXI1]
+~r~Your car is trashed, get it repaired.
+
+[TAXI4:TAXI1]
+Fare complete!
+
+[TAXI5:TAXI1]
+SPEED BONUS!!
+
+[TAXI6:TAXI1]
+Taxi mission over
+
+[TAXIH1:TAXI1]
+Stop near a highlighted pedestrian to pick them up then drive them to their destination before the time runs out.
+
+[FARE1:TAXI1]
+~g~Destination ~w~'The Pole Position Club' ~g~in Ocean Beach.
+
+[FARE3:TAXI1]
+~g~Destination ~w~'The Marina' ~g~in Ocean Beach.
+
+[FARE4:TAXI1]
+~g~Destination ~w~'Ammu-Nation' ~g~in Ocean Beach.
+
+[FARE5:TAXI1]
+~g~Destination ~w~'The Hardware store' ~g~in Washington Beach.
+
+[FARE6:TAXI1]
+~g~Destination ~w~'The North Point Mall' ~g~in Vice Point.
+
+[MFARE1:TAXI1]
+~g~Destination ~w~'Ammu-Nation' ~g~in Downtown.
+
+[MFARE2:TAXI1]
+~g~Destination ~w~'the Terminal' ~g~at Escobar International Airport.
+
+[WFARE3:TAXI1]
+~g~Destination ~w~'Sunshine Autos' ~g~in Little Havana.
+
+[WFARE4:TAXI1]
+~g~Destination ~w~'Kaufman Cabs' ~g~in Little Haiti.
+
+[WFARE5:TAXI1]
+~g~Destination ~w~'The Hardware store' ~g~in Little Havana.
+
+[WFARE6:TAXI1]
+~g~Destination ~w~'Howlin Petes Bike Emporium' ~g~in Downtown.
+
+[FARE7:TAXI1]
+~g~Destination ~w~'The Jewelers' ~g~in Vice Point.
+
+[FARE8:TAXI1]
+~g~Destination ~w~'The Beach' ~g~in Ocean Beach.
+
+[FARE9:TAXI1]
+~g~Destination ~w~'The Beach' ~g~in Washington Beach.
+
+[FARE10:TAXI1]
+~g~Destination ~w~'The Beach' ~g~in Vice Point.
+
+[FARE11:TAXI1]
+~g~Destination ~w~'Hospital' ~g~in Ocean Beach.
+
+[FARE12:TAXI1]
+~g~Destination ~w~'Hospital' ~g~in Vice Point.
+
+[FARE13:TAXI1]
+~g~Destination ~w~'Police Station' ~g~in Washington Beach.
+
+[FARE14:TAXI1]
+~g~Destination ~w~'Police Station' ~g~in Vice Point.
+
+[FARE15:TAXI1]
+~g~Destination ~w~'Pizza Restaurant' ~g~in Vice Point.
+
+[WFARE7:TAXI1]
+~g~Destination ~w~'Police Station' ~g~in Little Havana.
+
+[WFARE8:TAXI1]
+~g~Destination ~w~'Police Station' ~g~in Downtown.
+
+[WFARE9:TAXI1]
+~g~Destination ~w~'Hospital' ~g~in Downtown.
+
+[WFARE10:TAXI1]
+~g~Destination ~w~'Hospital' ~g~in Little Havana.
+
+[WFARE11:TAXI1]
+~g~Destination ~w~'The Stadium' ~g~in Downtown.
+
+[WFARE12:TAXI1]
+~g~Destination ~w~'Pizza Restaurant' ~g~in Little Haiti.
+
+[WFARE13:TAXI1]
+~g~Destination ~w~'Pizza Restaurant' ~g~in Downtown.
+
+[WFARE14:TAXI1]
+~g~Destination ~w~'Docks' ~g~in Viceport.
+
+[WFARE15:TAXI1]
+~g~Destination ~w~'Chemist' ~g~in Little Haiti.
+
+[FARE2:TAXI1]
+~g~Destination ~w~'The Malibu club' ~g~in Vice Point.
+
+{=================================== MISSION TABLE TAXICUT ===================================}
+
+[TAXC_A:TAXICUT]
+Guess you're the new owner.
+
+[TAXC_B:TAXICUT]
+What are you, mob? Cartel? You don't look Mexican...
+
+[TAXC_C:TAXICUT]
+Anyhoo, I guess you better get on with the 'things are gonna change around here' crap,
+
+[TAXC_D:TAXICUT]
+maybe threaten one of the drivers -
+
+[TAXC_E:TAXICUT]
+go steady on Ted over there, he's just had his hernia fixed.
+
+[TAXC_F:TAXICUT]
+Well, yeah. Things are going to change around here, lady.
+
+[TAXC_G:TAXICUT]
+Oh crap, sonny. Might as well leave this to me -
+
+[TAXC_H:TAXICUT]
+I've been doing this for years.
+
+[TAXC_I:TAXICUT]
+Now hear this.
+
+[TAXC_J:TAXICUT]
+We are now under new management and things are going to change around here again.
+
+[TAXC_K:TAXICUT]
+Our new management, the
+
+[TAXC_L:TAXICUT]
+- Which gang are you?
+
+[TAXC_M:TAXICUT]
+Well, I'm not part of any gang actually.
+
+[TAXC_N:TAXICUT]
+What's your goddamned name, kid?
+
+[TAXC_O:TAXICUT]
+Vercetti, Tommy Vercetti.
+
+[TAXC_P:TAXICUT]
+Our new management, the Vercetti Gang,
+
+[TAXC_Q:TAXICUT]
+is gonna make sure we get no trouble.
+
+[TAXC_R:TAXICUT]
+Capiche? Out!
+
+[TAXC_S:TAXICUT]
+Did you like the 'capiche'? I liked the 'capiche'.
+
+[TAXC_T:TAXICUT]
+So this is how it's worked in the past,
+
+[TAXC_U:TAXICUT]
+We run the firm as usual.
+
+[TAXC_V:TAXICUT]
+If we get any trouble from rival firms, you beat the crap out of them.
+
+[TAXC_W:TAXICUT]
+Then they beat the crap out of us,
+
+[TAXC_X:TAXICUT]
+then you beat the crap out of them,
+
+[TAXC_Y:TAXICUT]
+etcetera, etcetera. You got it?
+
+[TAXC_Z:TAXICUT]
+Uh, yeah, I guess...
+
+[TAXC_A1:TAXICUT]
+Just grab a taxi from the garage if you feel like jumping in.
+
+{=================================== MISSION TABLE TAXIWA1 ===================================}
+
+[OUTTIME:TAXIWA1]
+~r~Too slow, man, too slow!
+
+[TAX1_1:TAXIWA1]
+Ok, we got a high class fare needs picking up from Starfish island - any takers?
+
+[TAX1_2:TAXIWA1]
+Tommy here, I'll take it!
+
+[TAX1_3:TAXIWA1]
+This is my fare, back off asshole!
+
+[TAX1_4:TAXIWA1]
+Come on come on, Get in, quick!
+
+[TAX1_5:TAXIWA1]
+Ok, ok! Just don't hurt me!
+
+[TAXW1_1:TAXIWA1]
+~g~Pick up the V.I.P. on Starfish Island.
+
+[TAXW1_2:TAXIWA1]
+~g~Get the V.I.P back! Take the other car out!
+
+[TAXW1_3:TAXIWA1]
+~r~The V.I.P. is dead!
+
+[TAXW1_4:TAXIWA1]
+~r~The V.I.P. has been dropped off!
+
+[TAXW1_6:TAXIWA1]
+~g~Take the V.I.P. to the airport!
+
+{=================================== MISSION TABLE TAXIWA2 ===================================}
+
+[TAX2_1:TAXIWA2]
+Calling all cars, we're losing fares all over town. What's with you guys?
+
+[TAX2_2:TAXIWA2]
+VC Cabs keep beating us to it. They've just got too many cars - we can't compete!
+
+[TAX2_3:TAXIWA2]
+Mr. Vercetti, if you're out there listening in, you gotta put some VC Cabs out of action before we go bust!
+
+[TAXW2_1:TAXIWA2]
+~g~Destroy 3 of the rival taxis!
+
+{=================================== MISSION TABLE TAXIWA3 ===================================}
+
+[TAX3_1:TAXIWA3]
+Car 13, We got a Miss Cortez, asked for you especially.
+
+[TAX3_2:TAXIWA3]
+Ok, I got it. Car 13 out!
+
+[TAX3_3:TAXIWA3]
+Hmmmm, no sign of Mercedes...
+
+[TAXW3_3:TAXIWA3]
+~g~Take out the leader cab!
+
+[TAXW3_2:TAXIWA3]
+~g~Stay alive until the timer runs out.
+
+[TAX_AS1:TAXIWA3]
+TAXI FIRM ASSET COMPLETED
+
+[TAX_AS2:TAXIWA3]
+~g~Kaufman Cabs will now generate revenue up to a maximum of $~1~. Make sure you collect it regularly.
+
+[TAX3_4:TAXIWA3]
+It's time for Kaufman Cab's guardian angel to eat some fender!
+
+[TAX3_5:TAXIWA3]
+Hey boy I'm gonna tan your hide!
+
+{ reVC updates }
{ new languages }
[FEL_JAP]
JAPANESE
@@ -7992,7 +14354,6 @@ REPLAY MISSION
[FESZ_RM]
RETRY?
-{ more graphics }
[FED_VPL]
VEHICLE PIPELINE
@@ -8032,19 +14393,11 @@ PS2
[FEM_XBX]
XBOX
-[FEM_AUT] { aspect ratio related }
-AUTO
-
-{ controls }
[FEC_IVP]
INVERT PAD VERTICALLY
-{ map }
-[FEM_TWP]
-Toggle Waypoint
-
-[FEA_FMN]
-RADIO OFF
+[FEM_NON]
+NONE
[FEC_DS2]
DUALSHOCK 2
@@ -8064,36 +14417,12 @@ XBOX ONE CONTROLLER
[FEC_TYP]
GAMEPAD TYPE
-[FEC_CCF]
-CONFIGURATION
-
-[FEC_CF1]
-SETUP 1
-
-[FEC_CF2]
-SETUP 2
-
-[FEC_CF3]
-SETUP 3
-
-[FEC_CF4]
-SETUP 4
-
-[FEC_CDP]
-CONTROLLER DISPLAY
-
-[FEC_ONF]
-ON FOOT
-
-[FEC_INC]
-IN CAR
-
-[FEC_VIB]
-VIBRATION
-
[FET_AGS]
GAMEPAD SETTINGS
+[FEM_AUT] { aspect ratio related }
+AUTO
+
[FEM_PED]
PED DENSITY
@@ -8101,7 +14430,6 @@ PED DENSITY
CAR DENSITY
{ end of file }
-
[DUMMY]
THIS LABEL NEEDS TO BE HERE !!!
AS THE LAST LABEL DOES NOT GET COMPILED \ No newline at end of file
diff --git a/utils/gxt/build.bat b/utils/gxt/build.bat
index a674850e..7327497f 100644
--- a/utils/gxt/build.bat
+++ b/utils/gxt/build.bat
@@ -1,8 +1,5 @@
-gxt -g III -i "american.txt" -o "../../gamefiles/TEXT/american.gxt"
-gxt -g III -i "english.txt" -o "../../gamefiles/TEXT/english.gxt"
-gxt -g III -i "french.txt" -o "../../gamefiles/TEXT/french.gxt"
-gxt -g III -i "german.txt" -o "../../gamefiles/TEXT/german.gxt"
-gxt -g III -i "italian.txt" -o "../../gamefiles/TEXT/italian.gxt"
-gxt -g III -i "spanish.txt" -o "../../gamefiles/TEXT/spanish.gxt"
-gxt -g III -r -i "russian.txt" -o "../../gamefiles/TEXT/russian.gxt"
-gxt -g III -p -i "polish.txt" -o "../../gamefiles/TEXT/polish.gxt"
+gxt -g VC -i "american.txt" -o "../../gamefiles/TEXT/american.gxt"
+gxt -g VC -i "french.txt" -o "../../gamefiles/TEXT/french.gxt"
+gxt -g VC -i "german.txt" -o "../../gamefiles/TEXT/german.gxt"
+gxt -g VC -i "italian.txt" -o "../../gamefiles/TEXT/italian.gxt"
+gxt -g VC -i "spanish.txt" -o "../../gamefiles/TEXT/spanish.gxt" \ No newline at end of file
diff --git a/utils/gxt/english.txt b/utils/gxt/english.txt
deleted file mode 100644
index adc63780..00000000
--- a/utils/gxt/english.txt
+++ /dev/null
@@ -1,7026 +0,0 @@
-[LETTER1]
-abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789"$,.'-?!!SDBF
-
-[DEFNAM]
-Claude----------------------
-
-[IN_VEH]
-~g~Hey! Get back in the vehicle!
-
-[IN_VEH2]
-~g~You need some wheels for this job!
-
-[IN_BOAT]
-~g~You need a boat for this job!
-
-[HEY]
-~g~Don't go solo, keep your posse together!
-
-[HEY2]
-~g~Don't split up, keep the group together!
-
-[HEY3]
-~g~You've dropped your main man, go back and get 8-Ball!
-
-[HEY4]
-~g~Lose Misty and Luigi will lose your face! Go and get her!
-
-[HEY5]
-~g~One of the girls is AWOL, Go back and round her up!
-
-[HEY6]
-~g~You left your honor with the Yakuza Kanbu. You must protect him!
-
-[HEY7]
-~g~An extra gun could be useful. Go back and pick up your contact!
-
-[HEY8]
-~g~Protection means just that -Protect the Old Oriental Gentleman!
-
-[HEY9]
-~g~You want the word on the street? Go see the contact!
-
-[HELP2_A]
-Press the ~h~/ button~w~ when running to ~h~sprint.
-
-[HELP3]
-You can only sprint for short periods before becoming tired.
-
-[HELP4_A]
-Press the~h~ ~k~~VEHICLE_ACCELERATE~ button~w~ to ~h~accelerate.
-
-[HELP4_D]
-Push the~h~ right analog stick~w~ up to ~h~accelerate.
-
-[HELP5_A]
-Press the~h~ ~k~~VEHICLE_BRAKE~ button~w~ to ~h~brake~w~, or to ~h~reverse~w~ if the vehicle has stopped.
-
-[HELP5_D]
-Pull the ~h~right analog stick~w~ back to ~h~brake~w~, or to ~h~reverse~w~ if the vehicle has stopped.
-
-[HELP6_A]
-Press the~h~ ~k~~VEHICLE_HANDBRAKE~ button ~w~to apply the vehicle's ~h~handbrake.
-
-[HELP6_C]
-Press the~h~ ~k~~VEHICLE_HANDBRAKE~ button ~w~to apply the vehicle's ~h~handbrake.
-
-[HELP6_D]
-Press the~h~ ~k~~VEHICLE_HANDBRAKE~ button ~w~to apply the vehicle's ~h~handbrake.
-
-[HELP7_A]
-Press and hold the~h~ ~k~~PED_LOCK_TARGET~ button ~w~to ~h~target~w~ with the sniper rifle.
-
-[HELP7_D]
-Press and hold the~h~ ~k~~PED_LOCK_TARGET~ button ~w~to ~h~target ~w~with the sniper rifle.
-
-[HELP8_A]
-Press the~h~ ~k~~PED_SNIPER_ZOOM_IN~ button ~w~to ~h~zoom in ~w~with the rifle and the~h~ ~k~~PED_SNIPER_ZOOM_OUT~ button ~w~to ~h~zoom out ~w~again.
-
-[HELP9_A]
-Press the~h~ ~k~~PED_FIREWEAPON~ button ~w~to ~h~fire~w~ the sniper rifle.
-
-[HELP10]
-This badge indicates you have a police wanted level.
-
-[HELP11]
-The more badges the higher your wanted level.
-
-[HELP13]
-Sometimes you may need to use pathways not shown on the radar.
-
-[TIMER]
-This is a timed mission, you must complete it before the timer counts down to zero.
-
-[MISTY1]
-~r~Misty is morgue-meat!
-
-[OUT_VEH]
-~g~Get out of the vehicle!
-
-[GARAGE]
-Drive the vehicle into the garage, then walk outside.
-
-[WANTED1]
-~g~Shake the cops and lose your wanted level!
-
-[NODOORS]
-~g~They ain't sardines! Get some wheels with enough seats.
-
-[TRASH]
-~g~You've junked your wheels real bad! Get your vehicle repaired!
-
-[WRECKED]
-~r~The vehicle is wrecked!
-
-[HORN]
-~g~Sound the horn.
-
-[NOMONEY]
-~g~You need more cash!
-
-[OUTTIME]
-~r~Too slow, man, too slow!
-
-[SPOTTED]
-~r~They're on to you!
-
-[REWARD]
-REWARD $~1~
-
-[GAMEOVR]
-GAME OVER
-
-[Z]
-Z-axis value: ~1~
-
-[M_FAIL]
-MISSION FAILED!
-
-[M_PASS]
-MISSION PASSED! $~1~
-
-[O_PASS]
-ODD JOB PASSED!
-
-[O_FAIL]
-ODD JOB FAILED!
-
-[DEAD]
-WASTED!
-
-[BUSTED]
-BUSTED!
-
-[S_PROMP]
-When not on a mission you can ~h~save your game here~w~, this will advance time six hours.
-
-[NUMBER]
-~1~
-
-[SCORE]
-$~1~
-
-[LOADCAR]
-LOADING VEHICLE... (PRESS L1 TO CANCEL)
-
-[CARSOFF]
-Cars turned off.
-
-[CARS_ON]
-Cars turned on.
-
-[TEXTXYZ]
-Writing coordinates to file...
-
-[CHEATON]
-Cheat mode ON
-
-[CHEATOF]
-Cheat mode OFF
-
-[UZI_IN]
-The Uzi is now in stock at Ammunation!
-
-[IMPORT1]
-Go outside and wait for your vehicle.
-
-[PAGEB1]
-Pistol delivered to hideout
-
-[PAGEB2]
-Uzi delivered to hideout
-
-[PAGEB3]
-Body armor delivered to hideout
-
-[PAGEB4]
-Shotgun delivered to hideout
-
-[PAGEB5]
-grenades delivered to hideout
-
-[PAGEB6]
-molotovs delivered to hideout
-
-[PAGEB7]
-AK47 delivered to hideout
-
-[PAGEB8]
-Sniper rifle delivered to hideout
-
-[PAGEB9]
-M16 delivered to hideout
-
-[PAGEB10]
-Rocket Launcher delivered to hideout
-
-[PAGEB11]
-Flamethrower delivered to hideout
-
-[WANT_A]
-You will only be arrested if you have a ~h~wanted level.
-
-[WANT_B]
-Your ~h~wanted level~w~ is represented by the row of stars in the top right of the screen.
-
-[WANT_C]
-You now have a ~h~wanted level~w~ of one...
-
-[WANT_D]
-two...
-
-[WANT_E]
-three...
-
-[WANT_F]
-As your ~h~wanted level~w~ increases you will attract more powerful forms of law enforcement.
-
-[WANT_G]
-When you are ~h~'busted'~w~ you are returned to the nearest police station.
-
-[WANT_H]
-The cops will take all your weapons and some of your cash as a bribe.
-
-[WANT_I]
-Any mission you were on will be failed.
-
-[WANT_J]
-You will find ways of reducing your wanted level the more you play.
-
-[WANT_K]
-If you are in a car, ~h~SPRAY SHOPS~w~ will ~h~clear your wanted level.
-
-[HEAL_B]
-When you are ~h~'wasted'~w~ you are returned to the nearest hospital.
-
-[HEAL_C]
-You will lose your weapons and the doctors will take some cash for patching you up.
-
-[HEAL_E]
-You will find ways of healing or protecting yourself the more you play the game.
-
-[DAM]
-DAMAGE:
-
-[KILLS]
-KILLS:
-
-[FARES]
-FARES:
-
-[BULL]
-BULLION:
-
-[EVID]
-EVIDENCE:
-
-[HEALTH]
-CAR HEALTH:
-
-[COLLECT]
-COLLECTED:
-
-[BOMB]
-Drive your vehicle into the bomb shop to attach a ~h~bomb~w~. Cost - ~h~$1000.
-
-[SAVE1]
-Walk through the doorway to ~h~Save the game~w~. You cannot save during a mission.
-
-[SAVE2]
-Any vehicle left in this garage will be stored when the game is saved.
-
-[AMMU]
-Go inside Ammu-Nation to buy a weapon.
-
-[BRIDGE1]
-When the Callahan Bridge is repaired you will be able to drive to Staunton Island.
-
-[TUNNEL]
-When the Porter Tunnel is opened you will be able to drive to Staunton Island.
-
-[LUIGI]
-LUIGI MISSIONS
-
-[TONI]
-TONI MISSIONS
-
-[JOEY]
-JOEY MISSIONS
-
-[FRANK]
-SALVATORE MISSIONS
-
-[DIABLO]
-DIABLO MISSIONS
-
-[ASUKA]
-ASUKA MISSIONS
-
-[B_SITE]
-ASUKA SUBURBAN MISSIONS
-
-[KENJI]
-KENJI MISSIONS
-
-[RAY]
-RAY MISSIONS
-
-[LOVE]
-LOVE MISSIONS
-
-[YARDIE]
-YARDIE MISSIONS
-
-[HOOD]
-HOOD MISSIONS
-
-[CITYZON]
-Liberty City
-
-[IND_ZON]
-Portland
-
-[PORT_W]
-Callahan Point
-
-[PORT_S]
-Atlantic Quays
-
-[PORT_E]
-Portland Harbor
-
-[PORT_I]
-Trenton
-
-[S_VIEW]
-Portland View
-
-[CHINA]
-Chinatown
-
-[EASTBAY]
-Portland Beach
-
-[LITTLEI]
-Saint Mark's
-
-[REDLIGH]
-Red Light District
-
-[TOWERS]
-Hepburn Heights
-
-[HARWOOD]
-Harwood
-
-[ROADBR1]
-Callahan Bridge
-
-[ROADBR2]
-Callahan Bridge
-
-[TUNNELP]
-Porter Tunnel
-
-[BOMB1]
-8-Ball's Garage
-
-[COM_ZON]
-Staunton Island
-
-[STADIUM]
-Aspatria
-
-[HOSPI_2]
-Rockford
-
-[UNIVERS]
-Liberty Campus
-
-[CONSTRU]
-Fort Staunton
-
-[PARK]
-Belleville Park
-
-[COM_EAS]
-Newport
-
-[SHOPING]
-Bedford Point
-
-[YAKUSA]
-Torrington
-
-[SUB_ZON]
-Shoreside Vale
-
-[AIRPORT]
-Francis Intl. Airport
-
-[PROJECT]
-Wichita Gardens
-
-[SUB_IND]
-Pike Creek
-
-[SWANKS]
-Cedar Grove
-
-[BIG_DAM]
-Cochrane Dam
-
-[SUB_ZO2]
-Shoreside Vale
-
-[SUB_ZO3]
-Shoreside Vale
-
-[CAR_1]
-Ambulance
-
-[CAR_2]
-Firetruck
-
-[CAR_3]
-Police
-
-[CAR_4]
-Enforcer
-
-[CAR_5]
-Barracks
-
-[CAR_6]
-Rhino
-
-[CAR_7]
-FBIcar
-
-[CAR_8]
-Securicar
-
-[CAR_9]
-Moonbeam
-
-[CAR_10]
-Coach
-
-[CAR_11]
-Flatbed
-
-[CAR_12]
-Linerunner
-
-[CAR_13]
-Trashmaster
-
-[CAR_14]
-Patriot
-
-[CAR_15]
-Mr Whoopee
-
-[CAR_16]
-Mule
-
-[CAR_17]
-Yankee
-
-[CAR_18]
-Pony
-
-[CAR_19]
-Bobcat
-
-[CAR_20]
-Rumpo
-
-[CAR_21]
-Blista
-
-[CAR_22]
-Dodo
-
-[CAR_23]
-Bus
-
-[CAR_24]
-Sentinel
-
-[CAR_25]
-Cheetah
-
-[CAR_26]
-Banshee
-
-[CAR_27]
-Stinger
-
-[CAR_28]
-Infernus
-
-[CAR_29]
-Esperanto
-
-[CAR_30]
-Kuruma
-
-[CAR_31]
-Stretch
-
-[CAR_32]
-Perennial
-
-[CAR_33]
-Landstalker
-
-[CAR_34]
-Manana
-
-[CAR_35]
-Idaho
-
-[CAR_36]
-Stallion
-
-[CAR_37]
-Taxi
-
-[CAR_38]
-Cabbie
-
-[CAR_39]
-Buggy
-
-[LUIGIS]
-Luigi's Place
-
-[GOAWAY]
-~g~You are already on a mission!
-
-[LUIGGO]
-~g~Luigi's interviewing some new girls -Come back later!
-
-[JOEYGO]
-~g~Joey's out on the town with Misty -Drop by later!
-
-[TONIGO]
-~g~Toni's taken his Momma to the opera -Call in some other time!
-
-[KEMUGO]
-~g~Maria and Kemuri are all tied up at the moment -Drop by later!
-
-[KENJGO]
-~g~Kenji is attending a Yakuza meeting -Call by some other time!
-
-[RAYGO]
-~g~Ray has other toilets to hang around -Try again later!
-
-[LOVEGO]
-~g~Donald Love has other business to attend to -Make an appointment later!
-
-[KENSGO]
-~g~Kenji is busy! -Call by later!
-
-[HOODGO]
-~g~The Hoods are not available at this time!
-
-[WRONGT1]
-~g~Come back between 05:00 and 21:00 for a job
-
-[WRONGT2]
-~g~Come back between 06:00 and 14:00 for a job
-
-[WRONGT3]
-~g~Come back between 15:00 and 00:00 for a job
-
-[GUN_1A]
-Use the ~h~~k~~PED_CYCLE_WEAPON_RIGHT~ button ~w~and the ~h~~k~~PED_CYCLE_WEAPON_LEFT~ button ~w~to cycle through your weapons.
-
-[GUN_2A]
-Hold the ~h~~k~~PED_LOCK_TARGET~ button ~w~to ~h~auto-target~w~, press the~h~ ~k~~PED_FIREWEAPON~ button ~w~to ~h~fire! Try shooting the targets...
-
-[GUN_2C]
-Hold the ~h~~k~~PED_LOCK_TARGET~ button ~w~to ~h~auto-target~w~, press the~h~ ~k~~PED_FIREWEAPON~ button ~w~to ~h~fire! Try shooting the targets...
-
-[GUN_2D]
-Hold the ~h~~k~~PED_LOCK_TARGET~ button ~w~to ~h~auto-target~w~, press the~h~ ~k~~PED_FIREWEAPON~ button ~w~to ~h~fire! Try shooting the targets...
-
-[GUN_3A]
-While holding the ~h~~k~~PED_LOCK_TARGET~ button,~w~ press the ~h~~k~~PED_CYCLE_TARGET_LEFT~ button~w~ or the ~h~~k~~PED_CYCLE_TARGET_RIGHT~ button to switch target.
-
-[GUN_3B]
-While holding the ~h~~k~~PED_LOCK_TARGET~ button,~w~ press the ~h~~k~~PED_CYCLE_TARGET_LEFT~ button~w~ or the ~h~~k~~PED_CYCLE_TARGET_RIGHT~ button to switch target.
-
-[GUN_4A]
-While holding the ~h~~k~~PED_LOCK_TARGET~ button~w~ you can walk or run while remaining locked onto a target.
-
-[GUN_4B]
-While holding the ~h~~k~~PED_LOCK_TARGET~ button~w~ you can walk or run while remaining locked onto a target.
-
-[GUN_5]
-You can practice targeting and shooting on these paper targets. When you are finished resume the mission.
-
-[TAXI1]
-~g~Look for a fare.
-
-[FARE1]
-~g~Destination ~w~'Meeouch Sex Kitten Club' ~g~in Redlight.
-
-[FARE2]
-~g~Destination ~w~'Supa Save' ~g~in Portland View.
-
-[FARE3]
-~g~Destination ~w~'old school hall' ~g~in Chinatown.
-
-[FARE4]
-~g~Destination ~w~'Greasy Joe's Cafe' ~g~in Callahan Point.
-
-[FARE5]
-~g~Destination ~w~'AmmuNation' ~g~in Redlight.
-
-[FARE6]
-~g~Destination ~w~'Easy Credit Autos' ~g~in Saint Mark's.
-
-[FARE7]
-~g~Destination ~w~'Woody's topless bar' ~g~in Redlight.
-
-[FARE8]
-~g~Destination ~w~'Marcos Bistro' ~g~in Saint Mark's.
-
-[FARE9]
-~g~Destination ~w~'import export garage' ~g~in Portland Harbor.
-
-[FARE10]
-~g~Destination ~w~'Punk Noodles' ~g~in Chinatown.
-
-[FARE12]
-~g~Destination ~w~'Football Stadium' ~g~in Aspatria.
-
-[FARE13]
-~g~Destination ~w~'The Church' ~g~in Bedford Point
-
-[FARE14]
-~g~Destination ~w~'The Casino' ~g~in Torrington
-
-[FARE15]
-~g~Destination ~w~'Liberty University' ~g~in Liberty Campus
-
-[FARE16]
-~g~Destination ~w~'Shopping Mall' ~g~in Belleville Park Area
-
-[FARE17]
-~g~Destination ~w~'Museum' ~g~in Newport
-
-[FARE18]
-~g~Destination ~w~'AmCo Building' ~g~in Torrington
-
-[FARE19]
-~g~Destination ~w~'Bolt Burgers' ~g~in Bedford Point
-
-[FARE20]
-~g~Destination ~w~'The Park' ~g~in Belleville
-
-[FARE21]
-~g~Destination ~w~'Francis intl. Airport'
-
-[FARE22]
-~g~Destination ~w~'Cochrane Dam'
-
-[FARE24]
-~g~Destination ~w~'The hospital' ~g~in Pike Creek
-
-[FARE25]
-~g~Destination ~w~'The Park' ~g~in Shoreside Vale
-
-[FARE26]
-~g~Destination ~w~'North West Towers' ~g~in Wichita Gardens
-
-[NEW_TAX]
-BIGGER! FASTER! HARDER! new Borgnine taxis open for business in Harwood. Call 555-BORGNINE today!
-
-[TSCORE2]
-$~1~
-
-[IN_ROW]
-~1~ IN A ROW bonus! $~1~
-
-[TTUTOR]
-Press the ~h~~k~~TOGGLE_SUBMISSIONS~ button~w~ to toggle taxi missions on or off.
-
-[TTUTOR2]
-Press the ~h~~k~~TOGGLE_SUBMISSIONS~ button~w~ to toggle taxi missions on or off.
-
-[ATUTOR2]
-~g~Drive the patients to Hospital CAREFULLY. Each bump reduces their chances of survival.
-
-[A_TIME]
-+~1~ seconds
-
-[A_FULL]
-~r~Ambulance full!!
-
-[A_RANGE]
-~g~The ambulance radio is out of range, get closer to a hospital!
-
-[FTUTOR]
-Press the ~h~~k~~TOGGLE_SUBMISSIONS~ button~w~ to toggle fire truck missions on or off.
-
-[FTUTOR2]
-Press the ~h~~k~~TOGGLE_SUBMISSIONS~ button~w~ to toggle fire truck missions on or off.
-
-[F_PASS1]
-Fire extinguished!
-
-[F_RANGE]
-~g~The fire truck radio is out of range, get closer to a fire station!
-
-[C_BREIF]
-~g~Suspect last seen in the ~a~ area.
-
-[C_RANGE]
-~g~The police radio is out of range, get closer to a police station!
-
-[DODO_FT]
-You flew for ~1~ seconds!
-
-[EBAL]
-'GIVE ME LIBERTY'
-
-[EBAL_A]
-I know a place on the edge of the Red Light District where we can lay low,
-
-[EBAL_A1]
-but my hands are all messed up so you better drive, brother.
-
-[EBAL_1]
-Press the~h~ ~k~~VEHICLE_ENTER_EXIT~ button~w~ to ~h~enter ~w~or ~h~exit~w~ a vehicle.
-
-[EBAL_1B]
-Press the~h~ ~k~~VEHICLE_ENTER_EXIT~ button~w~ to ~h~enter ~w~or ~h~exit~w~ a vehicle.
-
-[EBAL_2]
-~g~Get back into the car!
-
-[EBAL_3]
-This is the ~h~radar~w~. Use it to navigate the city, follow the ~h~blip~w~ on the ~h~radar~w~ to find the hideout!
-
-[EBAL_D]
-I know a guy, he's connected, his name's Luigi.
-
-[EBAL_D1]
-Me an' him go back so I could probably get you some work. C'mon lets head over there.
-
-[EBAL_E]
-C'mon, lets drop by and I'll introduce you.
-
-[EBAL_I]
-The boss will be out to see you shortly...
-
-[EBAL_J]
-8-Ball's got some business up stairs.
-
-[EBAL_K]
-Maybe you can do me a favor.
-
-[EBAL_L]
-One of my girls needs a ride so grab a car and pick up Misty from the clinic. Then bring her back here.
-
-[EBAL_N]
-So keep your hands on the wheel!
-
-[EBAL_4]
-~r~8-Ball's dead!
-
-[EBAL_5]
-~g~Get a vehicle!
-
-[EBAL_6]
-~g~Pick up Misty!
-
-[LM1]
-'LUIGI'S GIRLS'
-
-[LM2]
-'DON'T SPANK MA BITCH UP'
-
-[LM3]
-'DRIVE MISTY FOR ME'
-
-[LM4]
-'PUMP-ACTION PIMP'
-
-[LM5]
-'THE FUZZ BALL'
-
-[LM1_2]
-~g~Take Misty to Luigi's Club.
-
-[LM1_3]
-~g~Press the horn to get the girl into the car.
-
-[LM1_6]
-~g~Get back into the car!
-
-[LM1_7]
-Stop the vehicle next to Misty and allow her to enter it.
-
-[LM1_8]
-You can go and see Luigi for more work or check out Liberty City.
-
-[LM2_A]
-There's a new high on the street goes by the name of SPANK.
-
-[LM2_E]
-Some wiseguy's been introducing this trash to my girls down Portland Harbor.
-
-[LM2_B]
-Go and introduce a bat to his face!
-
-[LM2_G]
-I want compensation for this insult!
-
-[LM2_1]
-~g~Take his car and get it resprayed.
-
-[LM2_2A]
-Use the~h~ ~k~~PED_FIREWEAPON~ button~w~ to ~h~punch ~w~and ~h~kick~w~ or ~h~swing ~w~the bat!
-
-[LM2_2C]
-Use the~h~ ~k~~PED_FIREWEAPON~ button~w~ to ~h~punch ~w~and ~h~kick~w~ or ~h~swing ~w~the bat~w~!
-
-[LM2_2D]
-Use the~h~ ~k~~PED_FIREWEAPON~ button~w~ to ~h~punch ~w~and ~h~kick~w~ or ~h~swing ~w~the bat~w~!
-
-[LM2_3]
-~g~Stash the car in Luigi's lockup!
-
-[LM2_4]
-~g~Respray the car!
-
-[LM3_A]
-Hey I've gotta talk to you... All right Mick I'll talk to yah later.
-
-[LM3_B]
-How yah doing kid?
-
-[LM3_C]
-The Don's son, Joey Leone, he wants some action from his regular girl Misty.
-
-[LM3_D]
-Go pick her up at Hepburn Heights...
-
-[LM3_E]
-but watch yourself that's Diablo turf.
-
-[LM3_F]
-Then run her over to his garage in Trenton and make it quick,
-
-[LM3_H]
-so keep your eyes on the road and off Misty!
-
-[LM3_2]
-~g~Take Misty to Joey's.
-
-[LM3_4]
-~g~Go pick up Misty!
-
-[LM3_5]
-You working regular for Luigi now huh? It's about time he got a driver we can trust!
-
-[LM3_7]
-I'll be with you in a minute spark plug.
-
-[LM3_10]
-~g~Get a vehicle!
-
-[LM4_B]
-Go and take care of things for me.
-
-[LM4_C]
-If you need a piece go around the back of AmmuNation opposite the subway.
-
-[LM5_A]
-The Policeman's Ball is being held at the old school hall near the Callahan Bridge
-
-[LM5_B]
-and they'll be looking for some 'old school' action.
-
-[LM5_C]
-Now I got girls all over town walking the streets.
-
-[LM5_D]
-Get'em to the ball they'll make a bundle.
-
-[LM5_1]
-~g~You pack these ladies too tight, they gonna bruise! ~g~Drop these girls off first, then come back for more.
-
-[LM5_2]
-~r~One of Luigi's girls is bodybag meat!
-
-[LM5_3]
-~g~You need a car!
-
-[LM5_4]
-~g~Pick up the girls working St. Marks.
-
-[LM5_5]
-~g~Take the girls to the Fuzz Ball!
-
-[LM5_8]
-~g~Girls working the Ball: ~1~
-
-[JM2]
-'FAREWELL 'CHUNKY' LEE CHONG'
-
-[JM3]
-'VAN HEIST'
-
-[JM4]
-'CIPRIANI'S CHAUFFEUR'
-
-[JM5]
-'DEAD SKUNK IN THE TRUNK'
-
-[JM1_1]
-~g~Take Forelli's car to 8-Ball's garage North of here, behind 'Easy Credit Autos'.
-
-[JM1_2]
-~g~Park the car back at Marco's Bistro.
-
-[JM1_3]
-~g~Activate the car bomb then get out of there!
-
-[JM1_4]
-~g~You're trashing the vehicle! Get it repaired!
-
-[JM1_5]
-~g~The car bomb's not set!
-
-[JM1_6]
-~g~Put the car back in the correct position.
-
-[JM1_8A]
-~y~Hey, it's my main man!
-
-[JM1_8B]
-~y~The bomb shop's automated. Just drive in, stop your car and the shop will do the rest.
-
-[JM1_8C]
-~y~Here, your first can be free, but after that it'll cost.
-
-[JM2_A]
-Chunky Lee Chong is pushing spank for some new gang from Colombia... or Colorado... or something....
-
-[JM2_B]
-I'm not really sure. Who needs details anyway.
-
-[JM2_D]
-That rat has sold his last stir fry.
-
-[JM2_E]
-I want you to take him out!
-
-[JM2_G]
-Sort yourself with a nine, you know where it is, right?
-
-[JM2_H]
-Well remember, just watch your back in China Town, it's Triad territory.
-
-[JM3_A]
-Alright, we're gonna hit the pay role van.
-
-[JM3_B]
-It leaves the edge of China Town everyday.
-
-[JM3_C]
-Bullets won't even dent the van's armor, so get a car and ram it off the road.
-
-[JM3_D]
-Now hit it hard and the punk ass security guards should bail.
-
-[JM3_E]
-Then take it to the warehouse at the docks and my guys are gonna take over from there.
-
-[JM3_F]
-Now it won't be doin' it's rounds all day, so don't hang around.
-
-[JM3_1]
-~g~Take the van to the lock up.
-
-[JM3_2]
-~g~Ram the van until its damage is below 70 percent.
-
-[JM4_B]
-Oh! Here's the guy I was telling you about!
-
-[JM4_C]
-Alright Listen. This guy ain't Italian and he's no mechanic but he can get things fixed.
-
-[JM4_D]
-This is Pops Capo, Toni Cipriani.
-
-[JM4_E]
-Yeah, I'm Toni Cipriani
-
-[JM4_F]
-Take him to Momma's restaurant at St Marks, alright.
-
-[JM4_G]
-Now listen to me, I'm planning a job that needs a good driver so drop by sometime later Ok?
-
-[JM4_2]
-Wait here! Keep the engine running. This ain't a social call.
-
-[JM4_3]
-It's a Triad ambush! Get us out of here kid!
-
-[JM4_4]
-The Triads think they can mess with me, the triads, with ME!
-
-[JM4_6]
-Hey watch the car! I said no fancy crap.
-
-[JM4_7]
-~g~Take Toni to his momma's restaurant.
-
-[JM4_8]
-~r~Toni's been wasted!
-
-[JM5_A]
-Beautiful! Just beautiful.
-
-[JM5_B]
-Alright, Just the guy I need to talk to!
-
-[JM5_D]
-One of the Forellis thought he was a wise guy, so he got what he had coming to him.
-
-[JM5_E]
-Take the corpse to the crusher in Harwood, alright?
-
-[JM5_1]
-~g~Take it to the crusher!
-
-[JM5_2]
-~g~It's the Forelli brothers!
-
-[JM6_A]
-What a ride she's gonna be, huh?
-
-[JM6_B]
-Alright, listen. Get some wheels to the safehouse at St. Marks and pick up a few friends of mine.
-
-[JM6_C]
-They're hittin' a bank and they need a driver.
-
-[JM6_D]
-I gave my word that you were the man, so don't screw this up.
-
-[JM6_E]
-Get them to the bank before five o'clock, not a minute after.
-
-[JM6_2]
-Keep the engine running we'll be in and out in no time.
-
-[JM6_3]
-Get us out of here!!
-
-[JM6_4]
-Shake the cops and get us to the safehouse!!
-
-[JM6_6]
-~g~Go and get a vehicle less conspicuous!
-
-[JM6_7]
-~g~You need all 3 to rob the bank!
-
-[TM1]
-'TAKING OUT THE LAUNDRY'
-
-[TM2]
-'THE PICK-UP'
-
-[TM3]
-'SALVATORE'S CALLED A MEETING'
-
-[TM4]
-'TRIADS AND TRIBULATIONS'
-
-[TM5]
-'BLOW FISH'
-
-[TONI_P]
-I've got some urgent work for you! -Toni
-
-[TM1_A]
-~w~Take a seat kid, take a god damned seat.
-
-[TM1_B]
-~w~So the laundry won't pay any protection eh?
-
-[TM1_C]
-~w~The Triads think they can mess with me?
-
-[TM1_D]
-~w~Let's teach these would be tough guys what it means to be a tough guy.
-
-[TM1_E]
-~w~Yeah, teach 'em some respect. No son of mine gets it from some Triads.
-
-[TM1_F]
-~w~Your father, god rest his soul, took no crap from no Triads back in Sicily.
-
-[TM1_G]
-~w~Sorry Ma. Yes Ma.
-
-[TM1_H]
-~w~I want you to destroy their laundry vans
-
-[TM1_I]
-~w~and mangle any triad gimp that gets in your way.
-
-[TM1_J]
-~w~8-Ball can supply you with what you're gonna need.
-
-[TM2_A]
-~w~TONI's off making people bleed or trying to.
-
-[TM2_AA]
-~w~He'll never be as tough as his Pop, but he left you a note on the table.
-
-[TM2_B]
-~w~The laundry has agreed to pay - you did real good kid!
-
-[TM2_C]
-~w~Go collect the cash and bring it back here. Watch out for the Triads.
-
-[TM2_D]
-~w~They may be shoving a firecracker up your ass, but don't take no crap.
-
-[TM2_E]
-~w~Nobody I mean nobody, messes with TONI CIPRIANI!
-
-[TM2_1]
-~g~Get the cash back to Toni's!!
-
-[TM2_2]
-~g~You iced them all!
-
-[TM3_MA]
-~w~I don't know where he is!
-
-[TM3_MB]
-~w~I swear that boy of mine don't know himself sometimes.
-
-[TM3_MC]
-~w~Now his father, he was different. Always on top, in charge, manful...
-
-[TM3_A]
-~w~Don Salvatore has called a meeting.
-
-[TM3_B]
-~w~I need you to collect the limo and his boy, Joey, from the garage.
-
-[TM3_C]
-~w~Then get Luigi from his club, come back here and pick me up,
-
-[TM3_D]
-~w~then we'll all drive over to the boss's place together.
-
-[TM3_E]
-~w~Those Triads, they don't know when to stop.
-
-[TM3_F]
-~w~They want a war. They got a war.
-
-[TM3_G]
-~w~Now get going.
-
-[TM3_1]
-~g~Pick up the Stretch from Joey's.
-
-[TM3_2]
-~g~Now go pick up Luigi.
-
-[TM3_3]
-~g~Now go pick up Toni.
-
-[TM3_4]
-~g~Drive the goodfellas to Salvatore's place.
-
-[TM3_5]
-~y~It's a triad ambush!!
-
-[TM4_B]
-~w~We're at WAR! The Triads have a fish factory as a front.
-
-[TM4_C]
-~w~Most of their business goes down at the fish market in Chinatown.
-
-[TM4_D]
-~w~That laundry still owes us protection.
-
-[TM4_E]
-~w~They reckon the Triads are protecting them now, so I say we exact a fitting punishment.
-
-[TM4_F]
-~w~Take these boys over and whack the Triad Warlords!
-
-[TM4_G]
-~w~Hell, if you get a chance, pop some of their soldiers too.
-
-[TM4_GAT]
-~g~You need a 'Triad fish van' to enter.
-
-[TM5_B]
-~w~OK, I've had enough of this shit.
-
-[TM5_C]
-~w~We're gonna finish the Triads in Liberty once and for all!
-
-[TM5_D]
-8-Ball's rigged a dustcart with a bomb.
-
-[TM5_E]
-~w~It's on a timer so if you mess up there'll be no evidence. Go and pick up the dustcart.
-
-[TM5_F]
-~w~Careful, 8-Ball says it's real sensitive and the slightest bump could set that thing off!
-
-[TM5_G]
-~w~Their fish factory will open its gates for a dustcart, so you can drive right in.
-
-[TM5_H]
-~w~Park up between the gas canisters and get the hell out of there!
-
-[TM5_I]
-~w~I want it to rain mackerel.
-
-[TM5_J]
-~w~We're talking real biblical here, nothing low budget.
-
-[FM2]
-'CUTTING THE GRASS'
-
-[FM4]
-'LAST REQUESTS'
-
-[FM1_A]
-~w~Me an' the fellas need to talk business
-
-[FM1_B]
-~w~so you're gonna look after my girl for the evening.
-
-[FM1_C]
-~w~HEY MARIA! MOVE YOUR BUTT!
-
-[FM1_D]
-~w~Dumb broad does this every time.
-
-[FM1_E]
-~w~And here she is, the one and only Queen of Sheba!
-
-[FM1_F]
-~w~What were you doing up there?
-
-[FM1_G]
-~w~Whatever it was, I bet it cost me money.
-
-[FM1_H]
-~w~Well, you don't think I hang around for the conversation, do you?
-
-[FM1_I]
-~w~Get in that car and keep your big mouth shut.
-
-[FM1_J]
-~w~Take the limo but bring it back in one piece, y'hear me?
-
-[FM1_K]
-~w~And watch her, she can be trouble.
-
-[FM1_L]
-~w~Yeah, yeah, yeah! I'm sure your new lap dog has everything covered,
-
-[FM1_M]
-~w~and isn't he big and strong?
-
-[FM1_N]
-~w~Hey Fido, Let's go visit Chico and get some party treats!
-
-[FM1_P]
-~g~That's Chico over there, pull up next to him.
-
-[FM1_S]
-~w~Here you go lady.
-
-[FM1_TT]
-~w~IT'S A POLICE RAID!
-
-[FM1_1]
-~g~Get back into the Stretch!
-
-[FM1_2]
-~g~Get into the Stretch!
-
-[FM1_3]
-~r~Leave Maria and Salvatore will have you whacked, go back and pick her up.
-
-[FM1_4]
-~g~You've dumped the Don's woman! Get back to the warehouse and wait for Maria!
-
-[FM1_5]
-~g~Get Maria safely back to Salvatore's!
-
-[FM1_6]
-~g~Chico won't be there forever, get Maria to the waterfront!
-
-[FM1_7]
-~r~Maria's dead! Salvatore won't be too pleased...
-
-[FM1_8]
-~r~You wasted Maria's supplier!
-
-[FM2_J]
-Leave us alone for a minute.
-
-[FM2_A]
-The Colombian Cartel is making SPANK somewhere in Liberty.
-
-[FM2_K]
-but we don't know where, and they seem to know everything we're doin' before we do.
-
-[FM2_L]
-There is a guy named Curly Bob works the bar at Luigi's.
-
-[FM2_M]
-He's been throwing more money around than he's earning.
-
-[FM2_N]
-He usually gets a taxi home after work. So follow him.
-
-[FM2_O]
-And if he's rattin' us out... kill him.
-
-[FM2_F]
-Here comes our little friend. Mr big mouth himself.
-
-[FM2_G]
-Were you followed? You know what goes on here is our little secret.
-
-[FM2_H]
-No..no, I wasn't followed. You got my stuff?
-
-[FM2_I]
-Here's your SPANK, squealer, now talk.
-
-[FM2_P]
-OK, so the Leone's are fighting wars on two fronts.
-
-[FM2_Q]
-They're in a turf war with the Triads with no sign of either side giving up.
-
-[FM2_R]
-Meanwhile Joey Leone has stirred up some bad blood with the Forellis.
-
-[FM2_S]
-Every day they're losing men and influence in the city.
-
-[FM2_T]
-Salvatore is becoming dangerous and paranoid. He suspects everybody and everything.
-
-[FM2_U]
-With loyalty like yours, what has he possibly got to worry about.
-
-[FM2_1]
-~g~There's Curly Bob!
-
-[FM2_2]
-~g~Curly's left the club, tail him!
-
-[FM2_5]
-~g~Take him to Portland Harbor.
-
-[FM2_6]
-~r~Curly won't get into a smashed-up taxi!
-
-[FM2_7]
-~r~Curly's spooked! The meeting's off!
-
-[FM2_8]
-~g~Whack Curly Bob!
-
-[FM2_9]
-~r~Curly Bob's dead!
-
-[FM2_10]
-~r~Curly got away!
-
-[FM2_11]
-~g~Park out the front of Luigi's Club, Curly Bob will be leaving shortly.
-
-[FM2_12]
-~r~He gave you the slip!
-
-[FM3_A]
-~w~We should take these Colombian bastards out,
-
-[FM3_B]
-~w~but while we're at war with the Triads we ain't strong enough.
-
-[FM3_C]
-~w~The Cartel has got bottomless funds from pushing that SPANK crap.
-
-[FM3_D]
-~w~If we make an open attack on them, they'll wipe the floor with us.
-
-[FM3_E]
-~w~They must be making SPANK on that big boat that Curly lead you to.
-
-[FM3_F]
-~w~So we gotta use our heads, or rather one head. Your head.
-
-[FM3_G]
-~w~I'm asking you to destroy that SPANK factory as a personal favor to me, Salvatore Leone.
-
-[FM3_H]
-~w~If you do this for me, you will be a made man, anything you want.
-
-[FM3_I]
-~w~Go and see 8-Ball, you'll need his expertise to blow-up that boat.
-
-[FM3_8A]
-~w~Yo my man! Salvatore phoned ahead,
-
-[FM3_8B]
-~w~but a job like this is gonna need a lot of fireworks.
-
-[FM3_8D]
-~w~but you know with me you get a lot of bang for your buck.
-
-[FM3_8E]
-~w~Okay, let's do this thing!
-
-[FM3_8F]
-~w~I can set this baby to detonate, but I still can't use a piece with these hands.
-
-[FM3_8G]
-~w~Here, this rifle should help you pop some heads!
-
-[FM3_4]
-~g~Stop the vehicle and let 8-Ball out!
-
-[FM3_7]
-~r~8-Ball's been iced!
-
-[FM3_8]
-~r~The guards have been alerted!
-
-[FM4_A]
-~w~It's my favorite cleaner.
-
-[FM4_B]
-~w~I'm proud of you my boy, you kicked the shit out of those grease balls.
-
-[FM4_C]
-~w~I've got just one little job for you before we can all celebrate.
-
-[FM4_D]
-~w~There's a car around the block from Luigi's club.
-
-[FM4_E]
-~w~The inside is covered in brains.
-
-[FM4_F]
-~w~We had to help some guy make up his mind and it proved a little messy.
-
-[FM4_H]
-~w~Take it to the crusher before the cops find it.
-
-[AM3]
-'PAPARAZZI PURGE'
-
-[AM4]
-'PAYDAY FOR RAY'
-
-[AM5]
-'TWO-FACED TANNER'
-
-[AM1_A]
-We have certain issues to clear up before we can continue any form of relationship,
-
-[AM1_B]
-business or otherwise. Lets lay our cards on the table.
-
-[AM1_C]
-I am Yakuza and I know you worked for Salvatore Leone's family.
-
-[AM1_D]
-I can give you work with our organization,
-
-[AM1_E]
-But first you must prove to me that your ties with the Mafia are truly broken.
-
-[AM1_G]
-Make sure he doesn't reach his club alive.
-
-[AM1_H]
-Meanwhile Maria and I will catch up on old times.
-
-[AM1_I]
-Oh..Asuka, you've got a massager.
-
-[AM1_J]
-That's not a massager.
-
-[AM1_1]
-~g~Salvatore is now leaving Luigi's!
-
-[AM1_2]
-~r~You have been spotted!
-
-[AM1_3]
-~r~You've missed Salvatore!
-
-[AM1_4]
-~r~Nice going, you scared off the target! Call yourself a hitman?
-
-[AM1_5]
-~g~Get to the Red Light District and wait for Salvatore to leave the club.
-
-[AM1_7]
-~r~Salvatore's home, safe and sipping a cocktail. Ain't no one gonna call you the 'Jackal'!
-
-[AM1_8]
-~g~Salvatore will be leaving Luigi's at about ~1~:~1~
-
-[AM2_4]
-~g~They seen you coming like a dayglow elephant!
-
-[AM3_A]
-A reporter has been nosing around.
-
-[AM3_B]
-Maria and I have taken a little holiday together until you can get rid of this perverted voyeur.
-
-[AM4_A]
-It's my handsome handyman!
-
-[AM4_B]
-Maria's all tied up at the moment but I'll tell her you called.
-
-[AM4_C]
-Who's that? Asuka? I know I've been a naughty girl but I really need to pee! OK?
-
-[AM4_D]
-It's time you met our man inside the LPD.
-
-[AM4_E]
-Here's his payment for the last little job he did for us.
-
-[AM4_F]
-He is understandably cautious.
-
-[AM4_G]
-Get to the pay phone in Torrington as quick as you can and await his instructions.
-
-[AM5_A]
-Maria and I have gone shopping.
-
-[AM5_B]
-Our source in the police has informed us that one of our drivers is a strangely animated undercover cop!
-
-[AM5_C]
-He's more or less useless out of his car, so we've tagged it with a tracer.
-
-[AM5_D]
-Make him bleed!
-
-[AM5_1]
-Tanner's on to you!
-
-[AS1]
-'BAIT'
-
-[AS2]
-'ESPRESSO-2-GO!'
-
-[AS4]
-'RANSOM'
-
-[AS1_A]
-~w~Miguel seems to think I'm mistreating him.
-
-[AS1_B]
-~w~Still, he's revealed the extent to which Catalina fears your quest for revenge.
-
-[AS2_A]
-~w~We underestimated Catalina's plans for SPANK.
-
-[AS2_B]
-~w~It reaches far beyond the Yardies selling it on the street corners.
-
-[AS2_D]
-~w~They've been selling SPANK through the street stalls.
-
-[AS2_1]
-~g~All espresso stalls in Portland wrecked!!
-
-[AS2_2]
-~g~All espresso stalls in Staunton Island wrecked!!
-
-[AS2_3]
-~g~All espresso stalls in Shoreside Vale wrecked!!
-
-[AS2_4]
-~r~The Cartel have warned their pushers!!
-
-[AS2_5]
-~g~There are still espresso stalls in Shoreside Vale and on Staunton Island!
-
-[AS2_6]
-~g~There are still espresso stalls in Shoreside Vale!
-
-[AS2_7]
-~g~There are still espresso stalls on Staunton Island!
-
-[AS2_8]
-~g~There are still espresso stalls in Portland!
-
-[AS2_9]
-~g~There are still espresso stalls in Portland and Shoreside Vale!
-
-[AS2_10]
-~g~There are still espresso stalls in Portland and on Staunton Island
-
-[AS2_12]
-~g~Cruise Liberty's districts to find ~b~Espresso-2-Go stalls!
-
-[AS3_A]
-~W~Do we tighten it some more now, or just wait for it to turn black and fall off?
-
-[AS3_B]
-~w~Give it a quick prod...
-
-[AS3_D]
-~w~My Handyman!
-
-[AS3_E]
-~w~I was bored so I came over to keep Asuka company.
-
-[AS3_1]
-~g~Find the ~r~boat~g~ and get to the ~b~marker buoy!
-
-[AS3_3]
-~g~Wait for the ~y~plane~g~ to start its approach!
-
-[AS3_5]
-~g~Collect the cargo!
-
-[AS3_4]
-~g~Use a rocket launcher to shoot the ~y~plane~g~ down!!
-
-[AS3_2]
-~b~Get to the runway marker buoys! ~y~The plane is on its final approach!!
-
-[AS3_6]
-~g~~1~ OF 8
-
-[KM1]
-'KANBU BUST-OUT'
-
-[KM3]
-'DEAL STEAL'
-
-[KM4]
-'SHIMA'
-
-[KM5]
-'SMACK DOWN'
-
-[KM1_A]
-My sister speaks highly of you,
-
-[KM1_E]
-though I am yet to be convinced that a gaijin can offer anything but disappointment.
-
-[KM1_B]
-Perhaps you could help deal with a situation that has me at a disadvantage.
-
-[KM1_F]
-Of course failure has its own disgrace.
-
-[KM1_C]
-A Yakuza Kanbu is in custody awaiting transfer for trial.
-
-[KM1_G]
-He is a valued member of the family.
-
-[KM1_H]
-Break him out of custody and get him to the dojo at Bedford Point.
-
-[KM1_D]
-We thankyou for your selfless actions. If you ever need help the dojo will be honoured to provide two men who will stand at your side.
-
-[KM1_1]
-~g~Steal a cop car!
-
-[KM1_2]
-~g~Rig the car with a bomb!
-
-[KM1_3]
-~g~Now get him to the Yakuza dojo.
-
-[KM1_5]
-~g~Okay now go to the police station.
-
-[KM1_6]
-~g~Fit the car with a bomb!
-
-[KM1_7]
-~g~Authorised police vehicles only!
-
-[KM1_9]
-~r~You did not use a car bomb to destroy the wall
-
-[KM1_10]
-~r~The Yakuza Kanbu is dead -along with your honor!
-
-[KM1_11]
-~r~You brought the heat down on yourself!
-
-[KM2_A]
-It is impossible to over-estimate the importance of etiquette in this line of work.
-
-[KM2_B]
-To my eternal shame, a man once did me a favor and I have never had the opportunity to repay his kindness.
-
-[KM2_C]
-The man's weakness is motor cars and he has requested that we acquire him certain models for his collection.
-
-[KM2_F]
-My honor demands it.
-
-[KM2_2]
-~g~Car delivered.
-
-[KM3_A]
-When trouble looms, the fool turns his back, while the wise man faces it down.
-
-[KM3_B]
-The Colombian Cartel have ignored repeated requests to leave our interests in Liberty well alone.
-
-[KM3_C]
-Now they are negotiating terms with the Jamaicans in order to humiliate us further.
-
-[KM3_D]
-They are finalizing a deal across town.
-
-[KM3_F]
-Take one of my men, steal a Yardie car, and go and pay your respects to the Colombians.
-
-[KM3_E]
-Our Honor demands that you leave no one alive.
-
-[KM3_2]
-~g~Go and pick up your contact.
-
-[KM3_3]
-~g~The meeting is being held in the hospital parking lot in Rockford!
-
-[KM3_4]
-~r~They got away!
-
-[KM3_6]
-~g~Kill them, kill them all!
-
-[KM3_8]
-~g~You need a Yardie car to get on with the job!
-
-[KM3_9]
-~r~One of the Colombians is dead, the deal's off.
-
-[KM3_10]
-~r~The contact is dead!
-
-[KM4_A]
-To be truly strong, it is important that you never show weakness.
-
-[KM4_C]
-Go and collect the money immediately, so we can enter it into the casino accounts.
-
-[KM4_1]
-I can't pay you and I wouldn't pay you if I could!
-
-[KM4_9]
-Some young gang just jacked out the place! They took everything!
-
-[KM4_2]
-You guys are useless.
-
-[KM4_10]
-What kind of Yakuza are YOU anyway...?
-
-[KM4_3]
-This ain't what I pay you goons for. If I wanted this kind of protection I'd have used the god damn police service
-
-[KM4_4]
-~g~Punish the gang responsible and retrieve the ~b~protection money~g~!
-
-[KM4_7]
-~r~The shopkeeper's breathed his last!
-
-[KM4_5]
-Donald Love wishes you to drop by his tea garden so you and he can talk.
-
-[KM4_6]
-There's the money its all there!
-
-[KM4_8]
-~g~Briefcase collected!
-
-[KM5_A]
-YOU! How fitting you should choose this moment to show your worthless face!
-
-[KM5_B]
-It would appear your attempts to dissuade the Jamaicans
-
-[KM5_B1]
-from becoming bed fellows with the Cartel were wholly inadequate!
-
-[KM5_C]
-Yardie pushers line Liberty's streets selling packets of SPANK like they were selling hotdogs!
-
-[KM5_D]
-Those Cartel pigs are laughing at us, at me!
-
-[KM5_E]
-I will give you one last chance to prove my sister's faith in you to be well founded!
-
-[KM5_F]
-Run these scumbags into the ground and wash your shame in rivers of our enemies' blood!!!
-
-[KM5_3]
-~r~You failed to kill at least ~1~ yardies.
-
-[KM5_4]
-~g~Congratulations you killed ~1~ Yardies.
-
-[KM5_5]
-~g~Congratulations you killed ~1~ Yardies. BONUS $~1~
-
-[RM1]
-'SILENCE THE SNEAK'
-
-[RM3]
-'EVIDENCE DASH'
-
-[RM4]
-'GONE FISHING'
-
-[RM5]
-'PLASTER BLASTER'
-
-[RM1_D]
-He's under armed protection in WitSec property down in Newport, some apartment behind the car park.
-
-[RM1_E]
-Torch that place, that should flush 'em out, and you'll hunt 'em down, make sure he never talks to nobody.
-
-[RM1_1]
-~g~Check out the witness protection house.
-
-[RM1_2]
-~g~Take out McAffrey!
-
-[RM2_A1]
-Hey kid over here!
-
-[RM2_A]
-An old army buddy of mine runs a business in Rockford.
-
-[RM2_D]
-He's gonna need some back-up and in return he'll give you knock-down rates on any hardware you buy.
-
-[RM2_E]
-Ray phoned ahead....but I thought there'd be more of you.
-
-[RM2_F]
-Well, three arms are better than one, so grab whatever you need.
-
-[RM2_G]
-~g~Go and check on Phil!
-
-[RM2_H]
-~r~Phil has been killed!!
-
-[RM2_L]
-Heh-hey! If I'd teamed up with you in Nicaragua maybe I'd still have my arm!
-
-[RM2_N]
-Leave the cash behind. Now get out of here, I'll handle the cops.
-
-[RM3_D]
-The evidence is being driven across town.
-
-[RM3_E]
-You are going to have to ram that car and collect each little bit of evidence as it falls out.
-
-[RM3_F]
-When you've got it all, leave it in the car and torch it.
-
-[RM3_G]
-We're both gonna do pretty well outta this kid.
-
-[RM3_1]
-~g~Leave the evidence in a car then torch the car.
-
-[RM3_4]
-~g~The Prosecution has dropped the evidence!
-
-[RM3_6]
-~r~The photos will be washed up all over Liberty!
-
-[RM3_7]
-~g~Now torch the car!
-
-[RM4_A]
-I think my partner's a rat.
-
-[RM4_C]
-He goes fishing out of his boat near the lighthouse on Portland Rock most nights.
-
-[RM4_D]
-Steal a police boat and make sure his back stabbing plans are sunk!
-
-[RM4_1]
-~g~Go and steal a police boat.
-
-[RM4_2]
-~g~Get to the lighthouse and 'rub out' Ray's partner!
-
-[RM5_A]
-You useless bastard!
-
-[RM5_A1]
-You totally messed up! My ass is on the line and you can't even kill a god damned fly.
-
-[RM5_B]
-I paid you good money to kill that witness and he ain't dead!
-
-[RM5_B1]
-And today he's gonna make a Federal Deposition!
-
-[RM5_C]
-He's being moved any second now from the Carson General Hospital up in Rockford.
-
-[RM5_D]
-If he squeals, I squeal....
-
-[RM5_E]
-so go do the job you were paid for!
-
-[RM5_1]
-~g~Intercept the ambulance.
-
-[RM5_2]
-~g~You've been spotted!!
-
-[RM5_3]
-~g~It was a decoy!
-
-[RM5_4]
-~g~Bullets won't get through that armored bodycast!!
-
-[RM5_5]
-~g~That armored bodycast is flame retardant!!
-
-[RM5_7]
-~r~Witness has been delivered!!
-
-[RM5_8]
-~g~Witness has drowned!!
-
-[LOVE2]
-'WAKA-GASHIRA WIPEOUT!'
-
-[LOVE3]
-'A DROP IN THE OCEAN'
-
-[LOVE1_A]
-First of all, let me thank you for dealing with that personal matter.
-
-[LOVE1_F]
-People will read something into anything these days.
-
-[LOVE1_D]
-They're trying to extort additional funds from me but I don't believe in re-negotiation.
-
-[LOVE1_E]
-A deal is a deal, so they'll not see a penny from me.
-
-[LOVE1_G]
-Go and rescue my friend, do whatever it takes.
-
-[LOVE1_2]
-~g~Rescue the Old Oriental Gentleman.
-
-[LOVE1_3]
-~g~Take the Old Oriental Gentleman back to Donald Love's building.
-
-[LOVE1_4]
-~g~The Old Oriental Gentleman must be in one of the garages....
-
-[LOVE1_6]
-~r~The Old Oriental Gentleman's guts are all over the street!
-
-[LOVE1_7]
-~g~The gate will only open for a Colombian Gang-car.
-
-[LOVE2_A]
-Nothing drives down real estate prices like a good old fashioned gang war,
-
-[LOVE2_B]
-apart from an outbreak of plague......but that might be going too far in this case.
-
-[LOVE2_C]
-I've noticed the Yakuza and the Colombians are far from friends.
-
-[LOVE2_D]
-Let's capitalise on this business opportunity.
-
-[LOVE2_E]
-I want you to kill the Yakuza Waka-gashira, Kenji Kasen.
-
-[LOVE2_F]
-Kenji is attending a meeting at the top of the multi-story carpark in Newport.
-
-[LOVE2_G]
-Get a Cartel gangcar and eliminate him!
-
-[LOVE2_H]
-The Yakuza must blame the Cartel for this declaration of war.
-
-[LOVE2_1]
-~g~Go to Fort Staunton and steal a Colombian gangcar!
-
-[LOVE2_2]
-~g~Now get to the ~p~multi-storey in Newport~g~ and whack Kenji!
-
-[LOVE2_3]
-~r~If you proceed without a Cartel car you will be identified!!
-
-[LOVE2_4]
-~r~The Yakuza have identified you!!
-
-[LOVE2_6]
-~r~You've killed all the witnesses!!
-
-[LOVE3_A]
-In these days of moral hypocrisy certain valuable commodities can be hard to import.
-
-[LOVE3_C]
-It will drop several packages into the water.
-
-[LOVE3_D]
-Make sure you pick them up before anyone else does.
-
-[LOVE3_1]
-~g~Get a ~r~boat~g~ and follow the ~y~plane~g~!
-
-[LOVE4]
-'GRAND THEFT AERO'
-
-[LOVE5]
-'ESCORT SERVICE'
-
-[LOVE4_A]
-Thank you for retrieving those packages, but they were only a decoy.
-
-[LOVE4_B]
-Sorry about that, but that's sometimes the way in business.
-
-[LOVE4_C]
-My real objective was hidden on the plane all along.
-
-[LOVE4_F]
-I've paid off the officials.
-
-[LOVE4_1]
-~r~The Colombian Cartel is here!!
-
-[LOVE4_2]
-~g~The package is gone! Track down the Colombians and retrieve it.
-
-[LOVE4_3]
-~g~Panlantic Construction...?
-
-[LOVE4_5]
-~g~The package should be in the plane....
-
-[LOVE4_6]
-~g~Take the lift up the tower!
-
-[LOVE5_B]
-My Oriental friend will need an escort while he takes my latest acquisition to be authenticated.
-
-[LOVE5_1]
-~g~Lets go!
-
-[LOVE5_2]
-~g~You'll need a car!
-
-[LOVE5_3]
-~g~Go ahead and scout the exit of the tunnel!
-
-[LOVE5_4]
-~r~Protect the truck!
-
-[RM6]
-'MARKED MAN'
-
-[RM6_A]
-You weren't followed? Good.
-
-[RM6_B]
-This is it, I'm way over my head and I'm starting to drown here!
-
-[RM6_D]
-I'm a marked man, so I'm getting out of here.
-
-[RM6_E]
-Get me to my flight at the airport and I'll make it worth your while!
-
-[RM6_666]
-Take care of my bullet proof Patriot. See you in Miami, Ray
-
-[CAT1]
-'RANSOM'
-
-[CAT2]
-'THE EXCHANGE'
-
-[CAT1_A]
-I've got your precious Maria. If you don't want her face to look like she fell out with the butcher.
-
-[CAT2_F]
-I broke a nail, and my hair's ruined. Can you believe it? This one cost me fifty dollars!
-
-[CAT2_G]
-I was so scared, but then I thought to myself, you're a big girl now.
-
-[CAT2_H]
-Oh we're going to have such fun, cause, you know, my sister said she wanted to come to stay with her two kids,
-
-[CAT2_I]
-because her husband's playing around again and..
-
-[CAT1_E]
-XXXX
-
-[CAT1_F]
-Get to Catalina before the time runs out!
-
-[CAT_MON]
-~g~You don't have enough money yet. You need $500,000.
-
-[BITCH_D]
-~g~Maria's dead!
-
-[WEATHER]
-FORCE WEATHER
-
-[WEATHE2]
-WEATHER NORMAL
-
-[8001]
-You failed miserably!!
-
-[1000]
-YOU ARE DEAD
-
-[1001]
-YOU ARE DEAD
-
-[1002]
-YOU ARE DEAD
-
-[1003]
-YOU ARE DEAD
-
-[1004]
-YOU ARE DEAD
-
-[1005]
-BUSTED
-
-[1006]
-BUSTED
-
-[1007]
-BUSTED
-
-[1008]
-BUSTED
-
-[1009]
-BUSTED
-
-[GA_4]
-Car bombs are $1000 each
-
-[GA_5]
-Your car is already fitted with a bomb.
-
-[GA_6]
-Park it, prime it by pressing the ~h~~k~~PED_FIREWEAPON~ button~w~ and LEG IT!
-
-[GA_7]
-Arm with ~h~~k~~PED_FIREWEAPON~ button~w~. Bomb will go off when engine is started.
-
-[GA_8]
-Use the detonator to activate the bomb.
-
-[GA_9]
-You collected ~1~ out of 10 special cars
-
-[GA_10]
-Nice one. Here's your $~1~
-
-[GA_11]
-We got these wheels already. It's worthless to us!
-
-[GA_12]
-Bomb armed
-
-[GA_13]
-Delivered like a pro. Complete the list and there'll be a bonus for you.
-
-[GA_14]
-All the cars. NICE! Here's a little something.
-
-[GA_15]
-Hope you like the new color.
-
-[GA_16]
-Respray is complementary.
-
-[GA_19]
-We're not interested in that model.
-
-[GA_20]
-We got more of these than we can shift. Sorry man, no deal.
-
-[CR_1]
-Crane cannot lift this vehicle.
-
-[PU_MONY]
-You don't have enough cash.
-
-[CO_ALL]
-You got all of them. Here's a little something...
-
-[PAUSED]
-GAME PAUSED
-
-[HEALTH1]
-Get outta here! You're perfectly healthy.
-
-[HEALTH2]
-Healthcare costs.
-
-[HEALTH3]
-I'll just fix you up.
-
-[HEALTH4]
-That will be $250.
-
-[FEB_STA]
-Stats
-
-[FEB_BRI]
-Briefs
-
-[FEB_CON]
-Controls
-
-[FEB_AUD]
-Audio
-
-[FEB_DIS]
-Display
-
-[FEB_LAN]
-Language
-
-[FEP_STA]
-STATS
-
-[FEP_BRI]
-BRIEFS
-
-[FEP_CON]
-CONTROLS
-
-[FEP_AUD]
-AUDIO
-
-[FEP_DIS]
-DISPLAY
-
-[FEP_LAN]
-LANGUAGE
-
-[FEF_ST1]
-Who's the bad man?
-
-[FEF_ST2]
-How much havoc have you caused
-
-[FEF_BR1]
-Lost the plot?
-
-[FEF_CO1]
-Need more control, freak?
-
-[FEF_CO2]
-Choose the best contoller set-up for your playing style
-
-[FEF_SA1]
-Keep your place in the pile!
-
-[FEF_SA2]
-Save and load your games
-
-[FEF_AU1]
-Pump up the volume!
-
-[FEF_AU2]
-Select a radio station and sound effect
-
-[FEF_DI1]
-Change the game!
-
-[FEF_DI2]
-Customize the game for your TV
-
-[FEF_LA1]
-What you talking about willis?
-
-[FEF_LA2]
-Choose your preferred parlance
-
-[FEM_ON]
-On
-
-[FEM_OFF]
-Off
-
-[FEM_YES]
-Yes
-
-[FEM_NO]
-No
-
-[FEM_NON]
-None
-
-[FEB_PMB]
-Previous Mission Briefs:
-
-[FEC_NA]
-NA
-
-[FEC_CWL]
-Cycle Weapon left
-
-[FEC_CWR]
-Cycle Weapon right
-
-[FEC_LOF]
-Look forward
-
-[FEC_TAR]
-Target
-
-[FEC_MOV]
-Movement
-
-[FEC_CAM]
-Camera modes
-
-[FEC_PAU]
-Pause
-
-[FEC_ENV]
-Enter vehicle
-
-[FEC_JUM]
-Jump
-
-[FEC_ATT]
-Attack or Fire weapon
-
-[FEC_RUN]
-Run
-
-[FEC_FPC]
-First person camera
-
-[FEC_LL]
-Look left
-
-[FEC_LB1]
-Look
-
-[FEC_LB2]
-behind
-
-[FEC_LB]
-Look behind
-
-[FEC_LR]
-Look right
-
-[FEC_HOR]
-Horn
-
-[FEC_VES]
-Vehicle control
-
-[FEC_RSC]
-Radio station cycle
-
-[FEC_BRA]
-Brake or Reverse
-
-[FEC_HAB]
-Hand brake
-
-[FEC_CAW]
-Car weapon
-
-[FEC_ACC]
-Accelerate
-
-[FEC_SMT]
-Special mission trigger
-
-[FEC_CCF]
-Configuration:
-
-[FEC_CF1]
-Setup1
-
-[FEC_CF2]
-Setup2
-
-[FEC_CF3]
-Setup3
-
-[FEC_CF4]
-Setup4
-
-[FEC_CDP]
-Controller Display:
-
-[FEC_ONF]
-On Foot
-
-[FEC_INC]
-In Car
-
-[FEC_VIB]
-Vibration:
-
-[FEA_MUS]
-Music Volume
-
-[FEA_SFX]
-SFX Volume
-
-[FEA_OUT]
-Output:
-
-[FEA_ST]
-Stereo
-
-[FEA_MNO]
-Mono
-
-[FEA_RSS]
-Radio station select:
-
-[FEA_NON]
-None
-
-[FEA_FM0]
-HEAD RADIO
-
-[FEA_FM1]
-DOUBLE CLEFF FM
-
-[FEA_FM2]
-JAH RADIO
-
-[FEA_FM3]
-RISE FM
-
-[FEA_FM4]
-LIPS 106
-
-[FEA_FM5]
-GAME FM
-
-[FEA_FM6]
-MSX FM
-
-[FEA_FM7]
-FLASHBACK 95.6
-
-[FEA_FM8]
-CHATTERBOX 109
-
-[FED_BRI]
-Brightness
-
-[FED_TRA]
-Trails:
-
-[FEL_ENG]
-English
-
-[FEL_FRE]
-French
-
-[FEL_GER]
-German
-
-[FEL_ITA]
-Italian
-
-[FEL_SPA]
-Spanish
-
-[FED_DBG]
-Menu Debug
-
-[FED_RID]
-Reload IDE
-
-[FED_RIP]
-Reload IPL
-
-[FED_PAH]
-Parse Heap
-
-[FED_RCD]
-CCullZones::RecalculateCullZoneData
-
-[FED_DFL]
-CTheScripts::DbgFlag
-
-[FED_DLS]
-Big White Debug Light Switched
-
-[FED_SPR]
-Show Ped Road Groups
-
-[FED_SCR]
-Show Car Road Grups
-
-[FED_SCZ]
-Show Cull Zones
-
-[FED_DSR]
-Debug Streaming Requests
-
-[FED_SCP]
-gbShowCollisionPolys
-
-[FEM_MCM]
-Memory Card Menu
-
-[FEM_RMC]
-Register MemCard One
-
-[FEM_TFM]
-Test Format MemCard One
-
-[FEM_TUM]
-Test UnFormat MemCard One
-
-[FEM_CRD]
-Create Root Dir
-
-[FEM_CLI]
-Create And Load Icons
-
-[FEM_FFF]
-Fill First File with Guff
-
-[FEM_SOG]
-Save Only The Game
-
-[FEM_CES]
-Check Every 0kB4 Save
-
-[FEM_STG]
-Save The Game
-
-[FEM_STS]
-Save The Game under GTA3 name
-
-[FEM_CPD]
-Create copy protected mag directory
-
-[FEM_MC2]
-Memory Card Menu 2
-
-[FEM_TS]
-Test Save:
-
-[FEM_TL]
-Test Load:
-
-[FEM_TD]
-Test Delete:
-
-[FEM_SL0]
-Slot0
-
-[FEM_SL1]
-Slot1
-
-[FEM_SL2]
-Slot2
-
-[FEM_SL3]
-Slot3
-
-[FEM_SL4]
-Slot4
-
-[FEM_SL5]
-Slot5
-
-[FEM_SL6]
-Slot6
-
-[FEM_SL7]
-Slot7
-
-[PL_STAT]
-Player stats
-
-[PE_WAST]
-People you've wasted
-
-[PE_WSOT]
-People wasted by others
-
-[CAR_EXP]
-Cars exploded
-
-[TM_BUST]
-Times busted
-
-[M_WASTE]
-Civilian males wasted
-
-[F_WASTE]
-Civilian females wasted
-
-[PIG_WST]
-Cops wasted
-
-[GNG_WST]
-Gang members wasted
-
-[MED_WST]
-Medics wasted
-
-[FIRE_WS]
-Firemen wasted
-
-[DED_CRI]
-Criminals wasted
-
-[DED_DED]
-Deadbeats wasted
-
-[DED_HOK]
-Hookers wasted
-
-[HEL_DST]
-Helicopters destroyed
-
-[PER_COM]
-Percentage completed
-
-[KGS_EXP]
-Kgs of explosives used
-
-[ACCURA]
-Accuracy
-
-[ELBURRO]
-Best Turismo time in secs
-
-[CAR_CRU]
-Cars crushed
-
-[HED_EX]
-Heads exploded
-
-[TM_DED]
-Hospital visits
-
-[DAYSPS]
-Days passed in game
-
-[MMRAIN]
-Mm rain fallen
-
-[MXCARD]
-Max. INSANE Jump dist. (ft)
-
-[MXCARJ]
-Max. INSANE Jump height (ft)
-
-[MXCARDM]
-Max. INSANE Jump dist. (m)
-
-[MXCARJM]
-Max. INSANE Jump height (m)
-
-[MXFLIP]
-Max. INSANE Jump flips
-
-[MXJUMP]
-Max. INSANE Jump rotation
-
-[BSTSTU]
-Best INSANE stunt so far:
-
-[INSTUN]
-Insane stunt
-
-[PRINST]
-Perfect insane stunt
-
-[DBINST]
-Double insane stunt
-
-[DBPINS]
-Perfect double insane stunt
-
-[TRINST]
-Triple insane stunt
-
-[PRTRST]
-Perfect triple insane stunt
-
-[QUINST]
-Quadruple insane stunt
-
-[PQUINS]
-Perfect quadruple insane stunt
-
-[NOSTUC]
-No INSANE stunts completed
-
-[NOUNIF]
-Unique Jumps completed
-
-[NOUNGM]
-Total Unique Jumps
-
-[NMISON]
-Mission attempts
-
-[NMMISP]
-Missions passed
-
-[PASDRO]
-Passengers dropped off
-
-[MONTAX]
-Cash made in taxi
-
-[DAYPLC]
-Daily police spending
-
-[CRIMRA]
-Criminal rating
-
-[GMSTOR]
-Game Store
-
-[PREBRF]
-Previous Briefs
-
-[CNTLS]
-Controls
-
-[MUSMEN]
-Music/SFX
-
-[GAMSET]
-Game Settings
-
-[LANGUA]
-Language
-
-[DSPLAY]
-Display
-
-[DEBUGM]
-Debug Menu
-
-[QUITOP]
-Quit Options
-
-[CONTRL]
-Control Configuration
-
-[SET1EN]
-SetUp 1. Enabled
-
-[SET1]
-SetUp 1.
-
-[SET2EN]
-SetUp 2. Enabled
-
-[SET2]
-SetUp 2
-
-[SET3EN]
-SetUp 3. Enabled
-
-[SET3]
-SetUp 3
-
-[SET4EN]
-SetUp 4. Enabled
-
-[SET4]
-SetUp 4
-
-[GOBACK]
-GoBack
-
-[SOUND]
-SOUND
-
-[MUSVOL]
-Music Volume
-
-[SFXVOL]
-SFX Volume
-
-[SCROPT]
-SCREEN OPTIONS
-
-[CTRSCR]
-Center Screen
-
-[SCRFOR]
-Screen format
-
-[GMSVLQ]
-GAME SAVE-LOAD-QUIT
-
-[GMREST]
-Restart Game
-
-[GMLOAD]
-Load Game
-
-[GMSAVE]
-Save Game
-
-[NOGMSV]
-Can save only at your hideout.
-
-[DLFILE]
-Delete Grand Theft Auto 3 Files
-
-[CHFILE]
-CHOOSE FILE TO LOAD
-
-[CHFIDL]
-CHOOSE FILE TO DELETE
-
-[SVCONF]
-SAVE CONFIRMATION
-
-[SVFNAM]
-Your saved file name is
-
-[LANGSL]
-LANGUAGE SELECTION
-
-[ENGLIS]
-English
-
-[GERMAN]
-German
-
-[ITALIA]
-Italian
-
-[FRENCH]
-French
-
-[SPAIN]
-Spanish
-
-[RELIDE]
-ReLoadIde
-
-[RELIPE]
-ReLoadIpl
-
-[PARSHP]
-Parse Heap
-
-[DBGFON]
-CTheScripts::DbgFlag On
-
-[DBFOFF]
-CTheScripts::DbgFlag Off
-
-[BGWHON]
-Big White Debug Light Switched On
-
-[BGWOFF]
-Big White Debug Light Switched Off
-
-[DSTRON]
-Debug Streaming Requests On
-
-[DSTROFF]
-Debug Streaming Requests Off
-
-[PDRGON]
-ShowPedRoadGroups On
-
-[PRGOFF]
-ShowPedRoadGroups Off
-
-[CRRGON]
-ShowCarRoadGroups On
-
-[CRGOFF]
-ShowCarRoadGroups Off
-
-[CLZOON]
-Show Cull Zones On
-
-[CLZOOF]
-Show Cull Zones Off
-
-[SHPLON]
-gbShowCollisionPolys On
-
-[SHPLOF]
-gbShowCollisionPolys Off
-
-[CULREC]
-CCullZones::RecalculateCullZoneData()
-
-[FORMM1]
-FormatMemCard 1 (teststuff)
-
-[UNFRM1]
-UnFormatMemCard 1 (teststuff)
-
-[GORLEV]
-Gore Level
-
-[SICASS]
-Sick Fuck
-
-[SICSIC]
-Sick Fucker
-
-[SCASSL]
-Sick Fuck Selected
-
-[SCSCSL]
-Sick Fucker Selected
-
-[PRVMEN]
-Previous Mission Briefs
-
-[FORMEN]
-Format Menu
-
-[MEMTST]
-MemoryCardTest screen
-
-[REGCAR]
-Register MemoryCard One
-
-[TEFONE]
-Test Format MemCard One
-
-[TEUFON]
-Test UnFormat MemCard One
-
-[CRROOT]
-CreateRootDir
-
-[CRLDIC]
-Create and Load Icons
-
-[FLFSGF]
-Fill First File With Guff
-
-[PUSAVE]
-Save Only the game
-
-[CHEVOK]
-CheckEveryOkB4Save
-
-[SVGMON]
-SaveTheGame
-
-[CNTSAV]
-Can't save the game. On a mission.
-
-[CNCSAV]
-Can't save the game. You're in a car
-
-[CRMGSV]
-Create copy protected magazine directory
-
-[MGSVCN]
-MagazineDirectory Created
-
-[MGSVNC]
-MagazineDirectory Not Created
-
-[YES]
-Yes
-
-[NO]
-No
-
-[X]
-x
-
-[LAST]
-Last message.
-
-[FEDS_XB]
-Select
-
-[FEDS_TB]
-Back
-
-[FEDS_ST]
-START button - RESUME
-
-[FEST_OO]
-out of
-
-[FED_SUB]
-Subtitles:
-
-[FEC_TUC]
-Turret control
-
-[FEC_SM3]
-Special mission trigger (R3 button)
-
-[FEC_RS3]
-Radio station cycle (L3 button)
-
-[FEC_HO3]
-Horn (L3 button)
-
-[DIAB1]
-'TURISMO'
-
-[DIAB2]
-'I SCREAM, YOU SCREAM'
-
-[DIAB3]
-'TRIAL BY FIRE'
-
-[DIAB4]
-'BIG'N'VEINY'
-
-[DIAB1_A]
-El Burro wants to offer you an opportunity. Get to the payphone in Hepburn Heights if you want more info.
-
-[DIAB1_C]
-You drive a mean race. Drop by the payphone again and 'El Burro' may have some work for you.
-
-[DIAB1_1]
-~g~3..2..1.. GO GO GO!
-
-[DIAB1_4]
-~g~Get a fast car and get to the starting grid.
-
-[DIAB1_3]
-~r~You couldn't win a raffle, LOSER!
-
-[DIAB1_2]
-~g~Congratulations you won, with an incredible time of ~1~ seconds.
-
-[FIRST]
-~g~1st
-
-[SECOND]
-~g~2nd
-
-[THIRD]
-~g~3rd
-
-[FOURTH]
-~g~4th
-
-[DIAB2_1]
-~g~Pick up the briefcase in Harwood.
-
-[DIAB2_2]
-~g~Find an icecream van.
-
-[DIAB2_3]
-~g~Park the icecream van down at Atlantic Quays.
-
-[DIAB2_4]
-~g~Press the ~w~~k~~VEHICLE_HORN~ button ~g~to activate the Icecream jingle.
-
-[DIAB2_6]
-~g~Press the ~w~~k~~VEHICLE_HORN~ button ~g~to activate the Icecream jingle.
-
-[DIAB2_7]
-~g~Press the ~w~~k~~VEHICLE_HORN~ button ~g~to activate the Icecream jingle.
-
-[DIAB2_5]
-~g~Exit the van then use the remote to detonate the Icecream van.
-
-[YD1]
-'BLING-BLING SCRAMBLE'
-
-[YD2]
-'UZI RIDER'
-
-[YD3]
-'GANGCAR ROUND-UP'
-
-[YD4]
-'KINGDOM COME'
-
-[YD_P]
-King Courtney would like a word. Get to the payphone in Aspatria!!
-
-[YD1_A]
-~w~This is King Courtney.
-
-[YD1_A1]
-~w~My Yardie posse could do with a driver and you've got a reputation for hot moves.
-
-[YD1_B]
-~w~Get to the waste ground opposite the stadium in a car and wait for the other hopefuls.
-
-[YD1_C]
-~w~I've got men watching checkpoints all over Staunton.
-
-[YD1_D]
-~w~First driver to a checkpoint gets a Grand, then it's on to the next stop.
-
-[YD1_D1]
-~w~If you get more checkpoints than any other driver, I could have some work for you.
-
-[YD1_E]
-~g~Prepare to race!
-
-[YD1_F]
-~g~You jumped the start -I like your style!!
-
-[YD1_G]
-~r~This is a CAR RACE. You need a CAR fool!
-
-[YD1GO]
-~g~GO!!
-
-[YD1_1]
-~r~1
-
-[YD1_2]
-~r~2
-
-[YD1_3]
-~r~3
-
-[YD1_BON]
-$1000!!
-
-[Y1_1ST]
-~g~You came first with ~1~ successful checkpoints!
-
-[Y1_2ND]
-~y~2nd with ~1~ successful checkpoints. ~y~Close, but you just ain't the best!
-
-[Y1_3RD]
-~r~3rd with ~1~ successful checkpoints. ~r~I thought you said you were good!
-
-[Y1_LAST]
-~r~You were last! ~r~You wasted my time FOOL!
-
-[Y1_J1ST]
-~y~Joint 1st with ~1~ successful checkpoints. ~y~Good, but you gotta be the best to drive for Queen Lizzy!
-
-[Y1_J2ND]
-~r~Joint 2nd with ~1~ successful checkpoints. You drive like a crazed monkey!
-
-[Y1JLAST]
-~r~Joint last! You talk like a driver, but you drive like a talker!
-
-[Y1_TEST]
-CAR IN WATER!!
-
-[YD2_A]
-~w~I need to see if you're capable of doing my dirty work.
-
-[YD2_A1]
-~w~See if you can be trusted.
-
-[YD2_B]
-~w~Two of my boys will be there any second to take you for a ride,
-
-[YD2_B1]
-~w~see if you are who you say you are.
-
-[YD2_C]
-~w~We're going for a little ride into Hepburn Heights, whack us some filthy Diablos been dissing Queen Lizzy.
-
-[YD2_CC]
-~w~Here, you'll need a 'piece'.
-
-[YD2_D]
-~w~You do the driving and shooting. We'll make sure you don't get cold feet.
-
-[YD2_E]
-~w~Let's drive!!
-
-[YD2_F]
-~r~He's bailed out on us, cap his yellow ass!!!
-
-[YD2_G1]
-~w~Hepburn Heights..Let's kill me some filthy Diablos...
-
-[YD2_G2]
-~w~But remember, ~r~You don't leave this car!!
-
-[YD2_H]
-~w~OK, Get us back to Yardie turf! GO GO GO!!
-
-[YD2_L]
-~w~You did good, Reaperman!
-
-[YD2_M]
-~r~He's wrecked my car! Waste him!
-
-[YD2_N]
-~w~Get your ass back in this car!
-
-[YD3_A]
-I want you to boost some gang cars
-
-[YD3_A1]
-so we can do hits on our enemies' turf.
-
-[YD3_B]
-I need a Mafia Sentinel,
-
-[YD3_B1]
-a Yakuza Stinger and a
-
-[YD3_B2]
-Diablo Stallion so we can hit any gang in Liberty.
-
-[YD3_C]
-Drop them off at the garage in Newport and remember,
-
-[YD3_C1]
-they're no use to us wrecked!!
-
-[YD3_D]
-Spare text label
-
-[YD3_E]
-~r~You've already boosted a diablo gangcar!
-
-[YD3_F]
-~r~You've already boosted a Mafia gangcar!
-
-[YD3_G]
-~r~You've already boosted a Yakuza gangcar!
-
-[YD3_H]
-~g~Diablo gangcar boosted!
-
-[YD3_I]
-~g~Mafia gangcar boosted!
-
-[YD3_J]
-~g~Yakuza gangcar boosted!
-
-[YD3_K]
-~r~The car's nearly wrecked! Get it repaired!
-
-[YD3_L]
-~g~Take it to the ~p~garage!
-
-[YD3_M]
-~r~You've flipped it! Get another one!
-
-[YD4_A]
-Listen up!
-
-[YD4_A1]
-Get over to Bedford Point.
-
-[YD4_A2]
-There's a stash in an old car I need pronto!
-
-[YD4_B]
-LETTER: I hear you've been a busy boy. Well I've been a busy girl.
-
-[YD4_C]
-I think it's time you witnessed the real power of 'SPANK'! Besos y fuderes, Catalina, xxx.
-
-[YD4_D]
-PS: DIE PEEG DOG, DIE!!
-
-[YD4_1]
-~g~SPANKED-up madmen!!
-
-[YD4_2]
-~g~Destroy the madmens' vans!!
-
-[HM_1]
-'UZI MONEY'
-
-[HM_2]
-'TOYMINATOR'
-
-[HM_3]
-'RIGGED TO BLOW'
-
-[HM_5]
-'RUMBLE'
-
-[HOOD1_A]
-Get to the payphone in Wichita Gardens and we'll talk business.
-
-[HM1_A]
-Yo! This is D-Ice of the Red Jacks!
-
-[HM1_C]
-These young punks, they come onto the streets and they got nothing but guns and SPANK on their minds.
-
-[HM1_3]
-~g~The 'Nines' walk their turf in Wichita Gardens.
-
-[HM2_3]
-If you hit a vehicle's wheels the RC buggy will detonate!
-
-[HM2_4]
-If it goes out of range the RC buggy will detonate!
-
-[HM2_5]
-~r~Out of range!
-
-[HM3_1]
-~g~Get to the garage but watch out if the car takes too much damage it will blow!
-
-[HM3_2]
-~g~Take the car back it has to be in perfect condition - no damage!
-
-[HM3_3]
-~g~Get the car repaired!
-
-[HM4_D]
-~g~Get a vehicle!
-
-[HM4_E]
-TEXT NO LONGER REQUIRED
-
-[HM4_1]
-~g~Head to the location where the cargo is scattered, you need to collect 30 pieces of bullion.
-
-[HM4_2]
-~g~Remember when the vehicle becomes too heavy and slow goto the garage and drop off the cargo.
-
-[HM5_3]
-~r~You were told to use a baseball bat only!
-
-[HM5_4]
-~r~Your contact's dead!
-
-[MEA1]
-'THE CROOK'
-
-[MEA2]
-'THE THIEVES'
-
-[MEA3]
-'THE WIFE'
-
-[MEA4]
-'HER LOVER'
-
-[MEAT1_A]
-A friend said you could fix some problems I got. Get to the payphone in Trenton if you think you can help.
-
-[MEA1_B3]
-~g~Go and meet the Bank Manager.
-
-[MEA1_B6]
-~g~Take the car to the crusher to get rid of evidence, get out of the car and the crane will pick it up.
-
-[MEA1_1]
-~r~The Bank Manager's dead!
-
-[MEA1_2]
-~r~You were told to crush the vehicle!
-
-[MEA1_3]
-~g~Get out of the car!
-
-[MEA1_4]
-~r~You have left the Bank Manager behind!
-
-[MEA2_B3]
-~g~Go and meet the thieves.
-
-[MEA2_B4]
-~g~Take them to the Bitch'n' Dog Food Factory
-
-[MEA2_B6]
-~g~Get the car resprayed to get rid of any evidence.
-
-[MEA2_1]
-~r~You were told to crush the vehicle!
-
-[MEA2_2]
-~r~A thief's dead!
-
-[MEA2_4]
-~r~You have left a thief behind!
-
-[MEA3_B3]
-~g~Go and collect Mrs. Chonks
-
-[MEA3_B6]
-~g~Take the car and dump it into the sea, this will get rid of any evidence.
-
-[MEA3_1]
-~r~The wife's dead!
-
-[MEA3_2]
-~r~You were supposed to dump the vehicle in the water!
-
-[MEA3_3]
-~r~You have left his wife behind!
-
-[MEA4_B3]
-~g~Pick up his wife's lover
-
-[MEA4_B6]
-It's far too late for that Marty. You had your chance, but now I'm taking over the business...
-
-[MEA4_1]
-~r~Carlos is dead!
-
-[MEA4_3]
-~r~You have left Carlos the loan shark behind!
-
-[LOOK_A]
-Press and hold the ~h~~k~~VEHICLE_LOOKLEFT~ button ~w~or the ~h~~k~~VEHICLE_LOOKRIGHT~ button~w~ to look ~h~left~w~ or ~h~right~w~ while in a vehicle. Press both to look ~h~behind~w~.
-
-[LOVE6_1]
-~g~Now lead the cops away from the warehouse!
-
-[LOVE6_2]
-~r~You failed to lead the police far enough away!
-
-[RM4_3]
-~r~Ray's partner has escaped!
-
-[RM6_C]
-The CIA seem to have a vested interest in SPANK
-
-[RM6_C1]
-and they don't like us screwing with the Cartel.
-
-[C_PASS]
-THREAT ELIMINATED!
-
-[CTUTOR]
-Press the ~h~~k~~TOGGLE_SUBMISSIONS~ button~w~ to toggle Vigilante missions on or off.
-
-[CTUTOR2]
-Press the ~h~~k~~TOGGLE_SUBMISSIONS~ button~w~ to toggle Vigilante missions on or off.
-
-[COPCART]
-~g~You have ~1~ seconds to return to a police vehicle before the mission ends.
-
-[C_FAIL]
-Vigilante mission ended!
-
-[C_CANC]
-~r~Vigilante mission cancelled!
-
-[C_ESCP]
-~r~The suspect has escaped!
-
-[C_TIME]
-~r~Your time as a law enforcer is over!
-
-[C_VIGIL]
-VIGILANTE BONUS!!
-
-[A_FAIL2]
-~r~Your lack of urgency has been fatal to the patient!
-
-[A_FAIL3]
-~r~The patient is dead!!
-
-[A_PASS]
-Rescued!
-
-[F_FAIL2]
-~r~You're too late!
-
-[A_COMP2]
-You will never get tired!
-
-[RM2_M]
-If you need any firepower just drop by and take what you need from the lockers.
-
-[HEAL_A]
-Your ~h~health~w~ is displayed in orange in the top right of the screen.
-
-[YD1_CNT]
-~1~ of 15!
-
-[FM1_9]
-~g~Thats the party up ahead, drop Maria off out front.
-
-[FM1_Y]
-~w~You know I enjoyed myself for the first time in a long while, and you treated me really good. With respect and everything.
-
-[FM1_AA]
-~w~Oh, I'd better go. I'll see you around I hope.
-
-[NOCONTE]
-Please re-insert an analog controller (DUALSHOCK#) or analog controller (DUALSHOCK#2) in controller port 1 to continue.
-
-[WRCONT]
-The controller connected to controller port 1 is an unsupported controller. Grand Theft Auto 3 requires an analog controller (DUALSHOCK#) or analog controller (DUALSHOCK#2).
-
-[WRCONTE]
-The controller connected to controller port 1 is an unsupported controller. Grand Theft Auto 3 requires an analog controller (DUALSHOCK#) or analog controller (DUALSHOCK#2).
-
-[WRONGCD]
-Incorrect disc. Please insert correct disc.
-
-[NOCD]
-The disc tray is empty. Please insert disc.
-
-[OPENCD]
-The disc tray is open. Please close the disc tray.
-
-[CDERROR]
-Error reading the Grand Theft Auto 3 DVD
-
-[RESTART]
-Starting new game
-
-[GA_3]
-No more freebies. $1000 to respray!
-
-[GA_1]
-Whoa! I don't touch nothing THAT hot!
-
-[GA_1A]
-Come back when you're not so busy...
-
-[S_PROM2]
-The garage next door can store one vehicle when you save your game.
-
-[STOCK]
-out of stock
-
-[FM1_O]
-~w~He's at the rail station at the Chinatown waterfront I think.
-
-[EBAL_B]
-This is the place right here, let's get off the street and find a change of clothes!
-
-[EBAL_G]
-This is Luigi's club. Let's go round the back and use the service door.
-
-[AM4_3]
-You must be Asuka's new errand boy!
-
-[AM4_4]
-You got the money? Is it all here?
-
-[AM4_5]
-I know what you're thinking, another bent cop.
-
-[AM4_6]
-Well, it's a bent world.
-
-[AM4_7]
-Just 'cause I lost a few partners, those suckers from internal affairs have started sniffing around.
-
-[AM4_8]
-Reckon they can smell me.
-
-[AM4_9]
-Well, this city is just one big open sewer.
-
-[AM4_10]
-But I'm gonna need some non-union help.
-
-[AM4_11]
-And if you're interested you'll know where to find me.
-
-[CAM_A]
-Press the ~h~~k~~CAMERA_CHANGE_VIEW_ALL_SITUATIONS~ button~w~ to change ~h~camera ~w~modes when on foot or in a vehicle.
-
-[CAM_B]
-Press the ~h~directional button up~w~ and ~h~down~w~ to change ~h~camera ~w~modes when on foot or in a vehicle.
-
-[KM2_1]
-~g~Repair the car, it's gotta be mint.
-
-[LM3_6]
-Joey...
-
-[LM3_6A]
-Am I goin' to play with your big end again?
-
-[LM3_9A]
-there might be some work for you.
-
-[LM3_9B]
-Alright?
-
-[AWAY2]
-~r~They got away.
-
-[AWAY]
-~r~He's clean out of here!
-
-[JM6_1]
-Get to the bank on the main drag.
-
-[GA_6B]
-Park it, prime it by pressing the ~h~~k~~PED_FIREWEAPON~ button~w~ and LEG IT!
-
-[GA_7B]
-Arm with ~h~~k~~PED_FIREWEAPON~ button~w~. Bomb will go off when engine is started.
-
-[BAT1]
-~g~Pick up the bat!
-
-[EBAL_O]
-If you don't mess this up, maybe there be more work for you. Now get outta here!
-
-[HELP9_B]
-Press the~h~ ~k~~PED_FIREWEAPON~ button ~w~to ~h~fire~w~ the sniper rifle.
-
-[HELP9_C]
-Press the~h~ ~k~~PED_FIREWEAPON~ button ~w~to ~h~fire~w~ the sniper rifle.
-
-[JM6_8]
-~r~You've lost all the robbers!
-
-[COLT_IN]
-The Pistol is now in stock at Ammunation!
-
-[TAXI2]
-~r~You're out of time!
-
-[TAXI3]
-~r~Your passenger fled in terror!
-
-[TAXI7]
-~r~Your car is trashed, get it repaired.
-
-[TAXI4]
-Fare complete!
-
-[TAXI5]
-SPEED BONUS!!
-
-[TAXI6]
-Taxi mission over
-
-[FRANGO]
-~g~Salvatore wants you to help Toni deal with the Triads first!
-
-[PAGEB12]
-Police Bribe delivered to hideout
-
-[PAGEB13]
-Health delivered to hideout
-
-[PAGEB14]
-Adrenaline delivered to hideout
-
-[KM1_4]
-~g~You need a cop car to do the job!
-
-[CAT1_B]
-bring $500,000 to the Villa at Cedar Grove.
-
-[JM2_C]
-He's got a noodle stand down in China Town.
-
-[RM6_1]
-Here's a key to a lock-up.
-
-[RM6_2]
-You'll find some cash and some 'supplies' I'd stashed in case things got tight.
-
-[RM6_3]
-See y'around.
-
-[FE_INIP]
-Initialising and loading Pause Menu... Please wait.
-
-[FESZ_CA]
-Cancel
-
-[FESZ_QU]
-Quit
-
-[FESZ_L1]
-Game saved successfully!
-
-[FESZ_L2]
-Your saved filename is:
-
-[FESZ_OK]
-OK
-
-[FES_LGA]
-Load Game
-
-[FES_DGA]
-Delete Game
-
-[FES_NGA]
-New Game
-
-[FES_CAN]
-Cancel
-
-[FESZ_QL]
-All unsaved progress in your current game will be lost. Proceed with loading?
-
-[FESZ_QD]
-Proceed with deleting this saved game?
-
-[FESZ_QO]
-Proceed with overwriting this saved game?
-
-[FESZ_QR]
-Are you sure you want to start a new game? All progress since the last save game will be lost. Proceed?
-
-[FESZ_QS]
-PROCEED WITH SAVE ?
-
-[T4X4_1]
-'PATRIOT PLAYGROUND'
-
-[T4X4_2]
-'A RIDE IN THE PARK'
-
-[T4X4_3]
-'GRIPPED!'
-
-[MM_1]
-'MULTISTOREY MAYHEM'
-
-[T4X4_1A]
-~g~You have ~y~5 minutes~g~ to collect ~y~15~g~ checkpoints. ~g~You may collect them in ~y~ANY ORDER.
-
-[T4X4_1B]
-~1~ of 15!
-
-[T4X4_1C]
-~y~PASS THROUGH~g~ the first checkpoint to start the timer. ~g~Each checkpoint will credit you with ~y~20 SECONDS~g~.
-
-[T4X4_2A]
-~g~You have ~y~2 minutes~g~ to collect ~y~12~g~ checkpoints!! ~g~You may collect them in ~y~ANY ORDER.
-
-[T4X4_2B]
-~1~ of 12!
-
-[T4X4_2C]
-~y~PASS THROUGH~g~ the first checkpoint to start the timer. ~g~Each checkpoint will credit you with ~y~10 SECONDS~g~.
-
-[T4X4_3A]
-~g~You have ~y~5 minutes~g~ to collect ~y~20~g~ checkpoints. ~g~You may collect them in ~y~ANY ORDER.
-
-[T4X4_3B]
-~y~PASS THROUGH~g~ the first checkpoint to start the timer. ~g~Each checkpoint will credit you with ~y~15 SECONDS~g~.
-
-[T4X4_3C]
-~1~ of 20!
-
-[T4X4_F]
-~r~You bailed! Too tough for you?!
-
-[MM_1_A]
-~g~You have ~y~2 minutes~g~ to collect ~y~20 checkpoints~g~ in the multistorey! ~g~You may collect them in ~y~ANY ORDER.
-
-[MM_1_B]
-~1~ of 20!
-
-[MM_1_C]
-~g~That's 20 seconds, plus ~y~5 SECONDS~g~ for each checkpoint. ~g~The timer will start ~y~IMMEDIATELY.
-
-[FM2_14]
-~r~You got too close and spooked Curly!
-
-[FM2_15]
-~g~Don't get too close or Curly will suspect something!
-
-[UPSIDE]
-~r~You flipped your wheels!
-
-[FM2_16]
-SPOOKOMETER:
-
-[LM3_11]
-~g~Misty won't ride in a bus get another vehicle!
-
-[LANDSTK]
-Landstalker
-
-[IDAHO]
-Idaho
-
-[STINGER]
-Stinger
-
-[LINERUN]
-Linerunner
-
-[PEREN]
-Perennial
-
-[SENTINL]
-Sentinel
-
-[PATRIOT]
-Patriot
-
-[FIRETRK]
-Firetruck
-
-[TRASHM]
-Trashmaster
-
-[STRETCH]
-Stretch
-
-[MANANA]
-Manana
-
-[INFERNS]
-Infernus
-
-[BLISTA]
-Blista
-
-[PONY]
-Pony
-
-[MULE]
-Mule
-
-[CHEETAH]
-Cheetah
-
-[AMBULAN]
-Ambulance
-
-[FBICAR]
-Fbi Car
-
-[MOONBM]
-Moonbeam
-
-[ESPERAN]
-Esperanto
-
-[TAXI]
-Taxi
-
-[KURUMA]
-Kuruma
-
-[BOBCAT]
-Bobcat
-
-[WHOOPEE]
-Mr Whoopee
-
-[BFINJC]
-BF Injection
-
-[POLICAR]
-Police
-
-[ENFORCR]
-Enforcer
-
-[SECURI]
-Securicar
-
-[BANSHEE]
-Banshee
-
-[PREDATR]
-Predator
-
-[BUS]
-Bus
-
-[RHINO]
-Rhino
-
-[BARRCKS]
-Barracks OL
-
-[TRAIN]
-Train
-
-[HELI]
-Helicopter
-
-[DODO]
-Dodo
-
-[COACH]
-Coach
-
-[CABBIE]
-Cabbie
-
-[STALION]
-Stallion
-
-[RUMPO]
-Rumpo
-
-[RCBANDT]
-RC Bandit
-
-[BELLYUP]
-Triad Fish Van
-
-[MRWONGS]
-Mr Wongs
-
-[MAFIACR]
-Mafia Sentinel
-
-[YARDICR]
-Yardie Lobo
-
-[YAKUZCR]
-Yakuza Stinger
-
-[DIABLCR]
-Diablo Stallion
-
-[COLOMCR]
-Cartel Cruiser
-
-[HOODSCR]
-Hoods Rumpo XL
-
-[AEROPL]
-Aeroplane
-
-[SPEEDER]
-Speeder
-
-[REEFER]
-Reefer
-
-[PANLANT]
-Panlantic
-
-[FLATBED]
-Flatbed
-
-[YANKEE]
-Yankee
-
-[BORGNIN]
-Borgnine
-
-[TOYZ]
-TOYZ
-
-[FEST_DF]
-Dist. travelled on foot (miles)
-
-[FEST_DC]
-Dist. travelled by car (miles)
-
-[FESTDFM]
-Distance travelled on foot (m)
-
-[FESTDCM]
-Distance travelled by car (m)
-
-[FEST_R1]
-Patriot Playground in secs
-
-[FEST_R2]
-A Ride In The Park in secs
-
-[FEST_R3]
-Gripped! in secs
-
-[FEST_RM]
-Multistorey Mayhem in secs
-
-[FEST_LS]
-People saved in an Ambulance
-
-[FEST_CC]
-Criminals killed on Vigilante Mission
-
-[FEST_FE]
-Total fires extinguished
-
-[FEST_LF]
-Longest flight in Dodo
-
-[FEST_BD]
-Best time for bomb defusal
-
-[FEST_RP]
-Rampages passed
-
-[FEST_MP]
-Missions passed
-
-[FEST_BB]
-Bling-bling Scramble:
-
-[FEST_H0]
-Most checkpoints
-
-[FEST_GC]
-Gang Cars Totalled:
-
-[FEST_H1]
-Diablo destruction
-
-[FEST_H2]
-Mafia Massacre
-
-[FEST_H3]
-Casino Calamity
-
-[FEST_H4]
-Rumpo Wrecker
-
-[USJI1]
-TEXT NO LONGER REQUIRED
-
-[USJI2]
-TEXT NO LONGER REQUIRED
-
-[USJI3]
-TEXT NO LONGER REQUIRED
-
-[USJ]
-UNIQUE STUNT BONUS!
-
-[SPRAY]
-Drive your vehicle into the spray shop to lose your ~h~wanted level~w~, ~h~repair ~w~and ~h~respray ~w~your vehicle. Cost - ~h~$1000.
-
-[HM1_1]
-~g~Ice 20 Purple Nines in 2 minutes 30 seconds.
-
-[KM1_8A]
-Press the~h~ ~k~~PED_FIREWEAPON~ button~w~ to ~h~activate the bomb,~w~ remember to get out of the way.
-
-[KM1_8D]
-Press the~h~ ~k~~PED_FIREWEAPON~ button~w~ to ~h~activate the bomb,~w~ remember to get out of the way.
-
-[KM1_12]
-~g~Get him to the dojo but get rid of the cops first!
-
-[RATNG1]
-Pickpocket
-
-[RATNG2]
-Bully
-
-[RATNG3]
-Thug
-
-[RATNG4]
-Hustler
-
-[RATNG5]
-Goon
-
-[RATNG6]
-Wheelman
-
-[RATNG7]
-Hired muscle
-
-[RATNG8]
-Fixer
-
-[RATNG9]
-Associate
-
-[RATNG10]
-Cleaner
-
-[RATNG11]
-Assassin
-
-[RATNG12]
-Right-hand man
-
-[RATNG13]
-Executioner
-
-[RATNG14]
-Capo
-
-[RATNG15]
-Boss
-
-[1010]
-~r~Your vehicle is upside down
-
-[1011]
-~r~Your vehicle is upside down
-
-[1012]
-~r~Your vehicle is upside down
-
-[1013]
-~r~Your vehicle is upside down
-
-[1014]
-~r~Your vehicle is upside down
-
-[JM4_10]
-OK, Kid. Drive me to the laundry in Chinatown first, I got a bit of business to take care of.
-
-[JM4_11]
-Those washer women aint been payin' their protection money.
-
-[JM4_12]
-And watch the car, Joey just fixed this junk heap.
-
-[JM4_13]
-So no fancy crap, OK?
-
-[KM4_11]
-~g~Take the money back to the casino!
-
-[FEF_BR2]
-Find it again by reading any mission briefs collected to date.
-
-[TRAIN_1]
-Kurowski Station
-
-[TRAIN_2]
-Rothwell Station
-
-[TRAIN_3]
-Baillie Station
-
-[SUBWAY1]
-Portland Station
-
-[SUBWAY2]
-Rockford Station
-
-[SUBWAY3]
-Staunton South Station
-
-[SUBWAY4]
-Shoreside Terminal
-
-[MEA4_2]
-~r~Marty Chonks is dead!
-
-[SPRAY1]
-Drive your vehicle into the spray shop to lose your ~h~wanted level~w~, ~h~repair ~w~and ~h~respray ~w~your vehicle. Cost - ~h~$1000~w~. This time it's free.
-
-[JM4_A]
-Yeah, I know Toni, I've tuned her real sweet. She purrs, you know what I mean?
-
-[JM4_5]
-Drop by later and we'll give them something to launder, their own blood stained clothes!
-
-[AMMU_A]
-Luigi said you'd need a piece...
-
-[AMMU_B]
-Joey told me to tool you up...
-
-[AMMU_C]
-So go around back of the shop. I left you a nine in the yard.
-
-[AMMU_D]
-I got all your home defence needs.
-
-[AMMU_E]
-You want a license too?
-
-[AMMU_F]
-I don't need to see any I.D. you look trustworthy.
-
-[DETON]
-DETONATION:
-
-[DRIVE_A]
-Have an Uzi selected when entering a vehicle then look left or right and press the ~h~~k~~PED_FIREWEAPON~ button~w~ to fire.
-
-[DRIVE_B]
-Have an Uzi selected when entering a vehicle then look left or right and press the ~h~~k~~PED_FIREWEAPON~ button~w~ to fire.
-
-[RECORD]
-~g~NEW RECORD!!
-
-[NRECORD]
-~r~NO NEW RECORD!
-
-[RCHELP]
-Press ~k~~PED_FIREWEAPON~, or drive the RC car into a vehicle's wheels to detonate.
-
-[RCHELPA]
-Press the ~k~~PED_FIREWEAPON~ button, or drive the RC car into a vehicle's wheels to detonate.
-
-[RC_1]
-You have 2 minutes to blow up as many Diablo Gang Cars as possible!
-
-[RC_2]
-You have 2 minutes to blow up as many Mafia Gang Cars as possible!
-
-[RC_3]
-You have 2 minutes to blow up as many Yakuza Gang Cars as possible!
-
-[RC_4]
-You have 2 minutes to blow up as many Yardie Gang Cars as possible!
-
-[RC_5]
-You have 2 minutes to blow up as many Hood Gang Cars as possible!
-
-[RC_6]
-You have 2 minutes to blow up as many Cartel Gang Cars as possible!
-
-[RAMPAGE]
-RAMPAGE!!
-
-[RAMP_P]
-RAMPAGE COMPLETE!
-
-[RAMP_F]
-RAMPAGE FAILED
-
-[PAGE_00]
-.
-
-[PAGE_01]
-Murder ~1~ Diablos in 120 seconds!
-
-[PAGE_02]
-Destroy ~1~ vehicles in 120 seconds!
-
-[PAGE_03]
-Kill ~1~ Mafia in 120 seconds!
-
-[PAGE_04]
-Kill ~1~ Triads in 120 seconds!
-
-[PAGE_05]
-Kill ~1~ Triads in 120 seconds!
-
-[PAGE_06]
-Destroy ~1~ vehicles in 120 seconds!
-
-[PAGE_07]
-Pop ~1~ Yardie heads in 120 seconds!
-
-[PAGE_08]
-Burn ~1~ Yakuza in 120 seconds!
-
-[PAGE_09]
-Destroy ~1~ vehicles in 120 seconds!
-
-[PAGE_10]
-Destroy ~1~ vehicles in 120 seconds!
-
-[PAGE_11]
-Annihialate ~1~ Yardies in 120 seconds!
-
-[PAGE_12]
-Torch ~1~ Yakuza in 120 seconds!
-
-[PAGE_13]
-Explode ~1~ Yardies in 120 seconds!
-
-[PAGE_14]
-Fry ~1~ Colombians in 120 seconds!
-
-[PAGE_15]
-Splatter ~1~ Hoods in 120 seconds!
-
-[PAGE_16]
-Destroy ~1~ vehicles in 120 seconds!
-
-[PAGE_17]
-Splatter ~1~ Colombians with a car in 120 seconds!
-
-[PAGE_18]
-Driveby and Destroy ~1~ vehicles in 120 seconds!
-
-[PAGE_19]
-Remove ~1~ Colombian heads in 120 seconds!
-
-[PAGE_20]
-Behead ~1~ Hoods in 120 seconds!
-
-[JM1_A]
-Hey, I'm bored when you gonna drill me?
-
-[JM1_B]
-In a moment sweet heart, I got a little business to take care of.
-
-[JM1_C]
-I got a little job for you pal.
-
-[JM1_D]
-The Forelli brothers have owed me money for too long
-
-[JM1_E]
-and they need to be taught some respect.
-
-[JM1_F]
-Lips Forelli is stuffing his fat face in St Marks Bistro,
-
-[JM1_G]
-so steal his car and take it to 8-Ball's bomb shop up in Harwood.
-
-[JM1_H]
-You know 8-Ball right?
-
-[JM1_I]
-Once he's fitted it with a bomb, go park the car where you found it.
-
-[JM1_J]
-Then sit back and watch the whole show.
-
-[JM1_K]
-But hurry up, he won't be eating forever.
-
-[CAT2_A1]
-Come on you dumb bitch!
-
-[CAT2_A]
-The real question is, did you turn up to rescue Maria or to get me back?
-
-[CAT2_B]
-Well I got news for you,
-
-[CAT2_B2]
-shooting you will be a pleasure but dating you was only business.
-
-[CAT2_C]
-You are muy peccinno amigo!
-
-[CAT2_D]
-Throw over the cash.
-
-[CAT2_E]
-You have been a busy boy!
-
-[CAT2_E2]
-But you haven't learned, I'm not to be trusted.
-
-[CAT2_E3]
-Kill the idiot.
-
-[CAT2_J]
-Get this thing airborne!!
-
-[HM5_1]
-Yo, Ice said was comin'. There rules. Bats only. No guns, no cars.
-
-[HM5_5]
-This is a battle for respect, you cool?
-
-[HELP14]
-To collect weapons walk through them. These cannot be collected while in a vehicle.
-
-[CRUSH]
-Park in the marked area and exit your vehicle. The vehicle will then be crushed.
-
-[DIAB2_B]
-A gang of no-goods has threatened to remove my starring member if I don't pay them a cut.
-
-[DIAB2_C]
-They threaten the wrong man, amigo.
-
-[DIAB2_D]
-They have a weakness for the icecream.
-
-[DIAB2_E]
-Pick up the bomb I've hidden in Harwood,
-
-[DIAB2_F]
-hijack the regular icecream van on its rounds.
-
-[DIAB2_G]
-and lure these fools to their doom with the jeengle-jeengle.
-
-[DIAB2_H]
-They hide in a warehouse on Atlantic Quay.
-
-[DIAB3_A]
-Some insolent Triads stole my beautiful car last night,
-
-[DIAB3_B]
-wrecked it and left it burning.
-
-[DIAB3_C]
-Some of my most precious donkey memorabilia was in the trunk -
-
-[DIAB3_D]
-real collectibles that are irreplaceable my friend.
-
-[DIAB3_E]
-I've hidden a throbbing weapon on the edge of Chinatown.
-
-[DIAB3_F]
-Take it and teach these Triad vandals to fear El Burro's well-endowed wrath.
-
-[DIAB3_G]
-Ariba!
-
-[DIAB3_1]
-KILL 25 TRIADS
-
-[DIAB4_A]
-A thieving opportunist has stolen a van of my latest publication hot off the press!
-
-[DIAB4_B]
-But that SPANKED-up idiot has left the rear doors open
-
-[DIAB4_C]
-and now my beautifully produced,
-
-[DIAB4_D]
-tastefully photographed adult literature is being dropped all over Liberty!
-
-[DIAB4_E]
-Take the van and follow that trail of Donkey Does Dallas volumes 1, 2 and 3
-
-[DIAB4_F]
-collecting it as you go.
-
-[DIAB4_G]
-When you've followed the trail to that thieving SPANK-head, waste him!
-
-[DIAB4_H]
-Then deliver my donkey derby to XXX Mags in the Red Light District.
-
-[DIAB4_1]
-~g~Take the van to the back of XXX Magazines.
-
-[HM1_E]
-I want you to show these punk ass bitches how a real drive-by works.
-
-[HM1_H]
-Take these nines off of here!!
-
-[HM2_A]
-Those Nines are pressing me.
-
-[HM2_B]
-These Bitches got armored cars and now they're running SPANK...
-
-[HM2_C]
-and slinging it to brothers with no fear.
-
-[HM2_D]
-There's a car parked up the way.
-
-[HM2_E]
-There's some stuff in there to put these sissys on blass...
-
-[HM3_A]
-Some effa has wired my wheels to blow.
-
-[HM3_B]
-If I lose those wheels, my rep on the street will be dead.
-
-[HM3_C]
-Pick up my car and take it over to the garage on St. Marks, a'right yo.
-
-[HM3_D]
-Let them diffuse that, let them take care of that bomb.
-
-[HM3_E]
-The clocks ticking and the wiring is messed up.
-
-[HM3_F]
-One pot hole too many and that thing could blow.
-
-[HM3_G]
-Now move it!
-
-[HM4_A]
-Yo, a Federal Reserve flight just smashed down at Francis International.
-
-[HM4_B]
-There's platinum all over the strip.
-
-[HM4_C]
-Get a car and snatch up as much as you can.
-
-[HM4_F]
-You can drop the bling off at one of my garages.
-
-[HM4_G]
-This platinum is mad heavy and it will slow your wheels down some.
-
-[HM4_H]
-So make regular drop off's at the garage.
-
-[HM5_A]
-Them Nines are down to a few scabby herds...
-
-[HM5_B]
-but they still wanna bring it.
-
-[HM5_C]
-They agreed to go toe to toe.
-
-[HM5_D]
-A gang of them against two of us, or rather...
-
-[HM5_E]
-two of yaw
-
-[HM5_F]
-I'd join you but...
-
-[HM5_G]
-I ain't due my parole hearing for another three months now,
-
-[HM5_H]
-y'know what I mean?
-
-[HM5_I]
-Go and meet my baby brother,
-
-[HM5_J]
-He'll show you where they are fighting a'right son.
-
-[MEA1_B]
-The name's Chonks, Marty Chonks.
-
-[MEA1_C]
-I run the Bitchin' Dog Food factory around the corner.
-
-[MEA1_D]
-I got money troubles, but hey, who doesn't right?
-
-[MEA1_E]
-I'm meeting my bank manager later.
-
-[MEA1_F]
-He's a crooked bastard that keeps bumping up the loan repayments so he can cut a slice.
-
-[MEA1_G]
-Take my car, pick him up and bring him back here.
-
-[MEA1_H]
-I've got a little surprise for that blood sucking leech!!
-
-[MEA2_A]
-I hired some thieves to break into my apartment...
-
-[MEA2_C]
-The thieving bastards are threatening to tell the insurance company,
-
-[MEA2_D]
-if I don't give them a cut.
-
-[MEA2_E]
-Can you believe it?
-
-[MEA2_F]
-I've left a car inside the factory gates.
-
-[MEA2_G]
-Use it to go and pick them up from their turf in the Red Light district.
-
-[MEA2_H]
-Then bring 'em back to the factory so I can make 'em see Marty's point of view.
-
-[MEA3_A]
-The business is going to go under unless I get hold of some serious cash soon.
-
-[MEA3_B]
-My wife has an insurance policy and all she's ever been to me is a hole in my pocket.
-
-[MEA3_C]
-I've left a car in the usual place.
-
-[MEA3_D]
-Go and pick up my wife from Classic Nails and bring her back to the factory.
-
-[MEA4_A]
-Damn, I'm in trouble!
-
-[MEA4_B]
-Turns out my wife was seeing some guy I owe money to.
-
-[MEA4_C]
-He's got real angry and he's looking for payback!
-
-[MEA4_E]
-he thinks I'm gonna pay him off...
-
-[MEA4_F]
-but my guess is...
-
-[MEA4_G]
-Liberty's dogs are gonna get yet another flavor this month!
-
-[WELCOME]
-WELCOME TO
-
-[HM1_2]
-~g~Get a vehicle, remember only Uzi drive by kills count!
-
-[HELP8_B]
-Press the~h~ ~k~~PED_SNIPER_ZOOM_IN~ button ~w~to ~h~zoom in ~w~with the rifle and the~h~ ~k~~PED_SNIPER_ZOOM_OUT~ button ~w~to ~h~zoom out ~w~again.
-
-[LRQC_1]
-Asuka and I are gonna have to talk, uh,
-
-[LRQC_2]
-Why don't you go cruise around?
-
-[LRQC_3]
-You'll need a place to lie low.
-
-[LRQC_4]
-There's a warehouse at the edge of Belleville that should suit your needs.
-
-[LRQC_5]
-Come back here to my Condo when you are ready,
-
-[LRQC_6]
-and we can have a little chat.
-
-[JM6_5]
-~g~You need a getaway vehicle, Idiot!
-
-[JM2_F]
-If you need a piece go around back of AmmuNation opposite the subway.
-
-[LOVE4_7]
-~g~There's a construction yard in Staunton Island, maybe they took the package there.
-
-[LOVE4_8]
-~g~You'll need a car to open the garage.
-
-[TSCORE]
-EARNINGS: $~1~
-
-[AM1_9]
-~r~Salvatore has escaped back into Luigi's Club!
-
-[AM1_6]
-~g~If you hang around Luigi's club, the Mafia will spot you!
-
-[TM2_3]
-~g~It's a trap! Waste them all!!
-
-[FM4_1]
-This is Maria. The car's a trap! Meet me at the slip south of Callahan Bridge.
-
-[JM1_7]
-~g~Close the car door! He'll notice!
-
-[KM5_1]
-~g~DEALER MINCED!!.
-
-[KM5_6]
-~g~You must murder at least 8 Yardie dealers.
-
-[KM5_7]
-~g~Kill them quickly! Once they've pushed their SPANK they're off the streets.
-
-[RM3_8]
-~r~That car is a decoy!!
-
-[LM3_8]
-Hey, I'm Joey.
-
-[LM3_9]
-Luigi said you were reliable so come back later,
-
-[KM3_5]
-~g~Press the horn to get the deal going.
-
-[LOVE7]
-LOVE'S DISAPPEARANCE
-
-[LOVE2_5]
-~g~Kenji is fender meat! Get out of Newport and dump the car!
-
-[AS2_11]
-~g~~1~ OF 9!
-
-[GARAGE1]
-~g~Get out of the vehicle and walk outside.
-
-[KM3_11]
-~g~The Cartel have been attacked and the briefcase has not been recovered.
-
-[KM3_12]
-~g~Kill all of the Colombians, destory the vehicles and recover the briefcase.
-
-[KM3_13]
-~g~Take the briefcase back to the casino.
-
-[RM5_6]
-~g~He's bailed out!! Smash his bodycast with a vehicle or an explosion!!
-
-[PBOAT_1]
-Press the ~h~~k~~PED_FIREWEAPON~ button~w~ to fire the boat cannons.
-
-[PBOAT_2]
-Press the ~h~~k~~PED_FIREWEAPON~ button~w~ to fire the boat cannons.
-
-[DIAB1_B]
-This is El Burro of the Diablos.
-
-[DIAB1_D]
-You're new in Liberty, but already you are gaining a reputation on the streets.
-
-[DIAB1_E]
-There's a street race starting by the old school hall near the Callahan Bridge.
-
-[DIAB1_F]
-Get yourself some wheels and first through all the checkpoints wins the prize.
-
-[HM2_1]
-Use the RC buggies to destroy the armored cars. Press the ~h~~k~~PED_FIREWEAPON~ button ~w~to detonate.
-
-[HM2_1A]
-Use the RC buggies to destroy the armored cars. Press the ~h~~k~~PED_FIREWEAPON~ button ~w~to detonate.
-
-[HM2_2]
-~r~You failed to destroy all the armored cars!
-
-[HM2_6]
-~g~Armored Car destroyed!
-
-[RM3_A]
-I know a real important man in town, a soft touch,
-
-[RM3_H]
-with shall we say, exotic tastes and the money to indulge them.
-
-[RM3_B]
-He's involved in a legal matter and the prosecution has some rather embarrassing photos of him
-
-[RM3_C]
-at a morgue party or something.
-
-[LOVE6_A]
-A lesson in business, my friend.
-
-[LOVE6_E]
-If you have a unique commodity, the world and his wife will try to wrestle it from your grasp...
-
-[LOVE6_C]
-SWAT teams have cordoned off the area around my associate and the package.
-
-[LOVE6_D]
-Get over there, pick up the van and act as a decoy.
-
-[LOVE6_F]
-Keep them busy and he should make good his escape.
-
-[AM3_C]
-He's probably out in the bay as you read this! Steal a police boat, and sink his career!
-
-[FESZ_UC]
-CANCEL
-
-[FEDS_SM]
-L1,R1-CHANGE MENU
-
-[FEDS_AS]
-;=-CHANGE SELECTION
-
-[FEDSAS2]
-<>-CHANGE SELECTION
-
-[FEDS_SS]
-L1,R1-CHANGE SELECTION
-
-[FEDSSC1]
-;-FASTER SCROLLING
-
-[FEDSSC2]
-=-STOP SCROLLING
-
-[MEA2_3]
-~g~Bring the car back to the factory.
-
-[RM1_3]
-~r~McAffrey escaped!
-
-[RM1_4]
-~g~You have used all the grenades! Get some more from ammunation!
-
-[RM1_5]
-~g~Go back and torch the safehouse!
-
-[RM6_4]
-~g~Go over to the lockup and collect Ray's stash.
-
-[RM6_5]
-~g~The CIA have the bridge under surveillance, find another route across.
-
-[HM2_F]
-and wreck all their armored stuff.
-
-[HM_4]
-'BULLION RUN'
-
-[MEA2_B5]
-TEXT NO LONGER NEEDED
-
-[MEA1_B5]
-TEXT NO LONGER NEEDED
-
-[MEA3_B5]
-TEXT NO LONGER NEEDED
-
-[MEA4_B7]
-but if you just step into my office...
-
-[MEA3_B4]
-Marty wants to see me? Well it better be quick because I have to get my hair done.
-
-[KM3_7]
-It's a Yakuza trap man!
-
-[FES_LOF]
-Load Failed.
-
-[FES_SLO]
-SAVE FILE
-
-[FES_ISC]
-IS CORRUPTED
-
-[FESZ_TI]
-SAVE Z1
-
-[FESZ_SA]
-Save game
-
-[MC_LDFL]
-Load Failed!
-
-[MC_NWRE]
-Now Restarting Game.
-
-[LOVE6_3]
-~g~You have ~1~ seconds to return to the Securicar before you fail the mission.
-
-[LOVE6_4]
-~r~You ditched the Decoy Securicar!
-
-[HELP1]
-Stop in the center of the blue marker.
-
-[HELP12]
-Walk into the center of the blue marker to trigger a mission.
-
-[HJSTAT]
-Distance: ~1~.~1~m Height: ~1~.~1~m Flips: ~1~ Rotation: ~1~_
-
-[HJSTATW]
-Distance: ~1~.~1~m Height: ~1~.~1~m Flips: ~1~ Rotation: ~1~_ And what a great landing!
-
-[DIAB1_5]
-RACE TIME:
-
-[LOVE3_4]
-~r~You destroyed the plane!!
-
-[F_FAIL1]
-Fire Truck mission ended.
-
-[F_CANC]
-~r~Fire Fighter mission cancelled!
-
-[F_EXTIN]
-FIRES:
-
-[A_COMP1]
-Paramedic missions complete!
-
-[A_CANC]
-~r~Paramedic mission cancelled!
-
-[A_COMP3]
-Paramedic missions complete! You will never get tired when running!
-
-[ATUTOR]
-Press the ~h~~k~~TOGGLE_SUBMISSIONS~ button~w~ to toggle Paramedic missions on or off.
-
-[ATUTOR3]
-Press the ~h~~k~~TOGGLE_SUBMISSIONS~ button~w~ to toggle Paramedic missions on or off.
-
-[ALEVEL]
-Paramedic Mission Level ~1~
-
-[A_FAIL1]
-Paramedic mission ended.
-
-[FEST_HA]
-Highest Paramedic Mission level
-
-[A_SAVES]
-PEOPLE SAVED: ~1~
-
-[C_KILLS]
-CRIMINALS KILLED: ~1~
-
-[HM1_B]
-I got a problem they tryin' to play me.
-
-[AM2_A]
-Salvatore's death comes as pleasurable news,
-
-[AM2_A2]
-you are an efficient killer. I like that in a man.
-
-[AM2_B]
-This is my brother Kenji.
-
-[AM2_C]
-Asuka has a little job for you, but when you're done, drop by my casino and we can talk.
-
-[AM2_D]
-Just like Kenji, always trying to play with my toys.
-
-[AM2_E]
-My police source indicates that the Mafia are watching our interests around the city
-
-[AM2_E2]
-in a bid to track you down.
-
-[AM2_F]
-We cannot continue our operations until they are dealt with.
-
-[AM2_G]
-Take out these spying fools and end this vendetta once and for all.
-
-[F_START]
-~g~Burning vehicle reported in the ~a~ area. Go and extinguish the fire.
-
-[AM4_1A]
-Get to the Phone in West Belleville Park.
-
-[AM4_1B]
-Get to the Phone on Liberty Campus.
-
-[AM4_1C]
-Get to the Phone in South Belleville Park.
-
-[AM4_1D]
-Meet me in the toilet block in the park.
-
-[HJSTATF]
-Distance: ~1~ft Height: ~1~ft Flips: ~1~ Rotation: ~1~_
-
-[HJSTAWF]
-Distance: ~1~ft Height: ~1~ft Flips: ~1~ Rotation: ~1~_ And what a great landing!
-
-[HM1_F]
-Watch your back though, there'll be Jacks on the street who'll think you're trying to blast them too!
-
-[HM1_D]
-'Nines' is their tag and purple is their flag and each day they rock their colors...
-
-[HM1_G]
-is another day the 'Jacks' look soft.
-
-[MEA2_B]
-and steal some stuff so I could claim on the insurance as you do.
-
-[TM3_H]
-~w~You did good back there kid, real good.
-
-[TM3_I]
-~w~Come on, let's introduce you to the Don.
-
-[TM3_J]
-~w~Heeyyy! Luigi!
-
-[TM3_K]
-~w~Oh my girls have been missing you so long Salvatore, you been away too long.
-
-[TM3_L]
-~w~You tell them that once this unfortunate business is taken care of,
-
-[TM3_M]
-~w~we'll all go down to the club and celebrate, ok?
-
-[TM3_N]
-~w~Here's my boy.
-
-[TM3_N2]
-~w~How you doin' pop?
-
-[TM3_O]
-~w~You got yourself a good woman yet?
-
-[TM3_P]
-~w~Hey, your mother, god bless her soul, would be turning over in her grave
-
-[TM3_Q]
-~w~to see you without a wife.
-
-[TM3_R]
-~w~I know Pop, I'm working on it.
-
-[TM3_S]
-~w~TONI! How's your Momma?
-
-[TM3_T]
-~w~She's a great woman you know. Strong. Firenze.
-
-[TM3_U]
-~w~She's good...fine.
-
-[TM3_V]
-~w~Terrific, Terrific. Now listen you guys, you go inside while I talk to our new friend here.
-
-[TM3_W]
-~w~I see nothing but good things for you my boy...
-
-[RM1_A]
-That scumbag McAffrey, he took more bribes than anyone.
-
-[RM1_B]
-He thinks he's gonna get an honorable discharge if he turns states evidence.
-
-[RM1_C]
-He just squealed!
-
-[RM4_B]
-We gotta shut him up, permanently.
-
-[RM4_E]
-I want him sleeping with the fishes, not eating them.
-
-[LOVE3_B]
-On its approach to the airport tonight, a light aircraft will pass over the bay.
-
-[LOVE4_D]
-Unfortunately the port authorities seized the plane and were stripping it down
-
-[LOVE4_H]
-until I intervened at great personal expense.
-
-[LOVE4_E]
-Cross the bridge to Shoreside Vale and go to Francis International Airport.
-
-[GTAB_A]
-Hey, let's get this out of here. God knows what it is
-
-[GTAB_B]
-but he seems to want it badly enough so it must be worth something.
-
-[GTAB_C]
-Who the Heck!
-
-[GTAB_D]
-YOU!
-
-[GTAB_E]
-Hey take it easy amigo! De nada! De nada!
-
-[GTAB_F]
-I left you pouring your heart out into the gutter!
-
-[GTAB_G]
-Don't shoot amigo. No problem. We all friends. Here, take this.
-
-[GTAB_H]
-Don't be such a pussy!
-
-[GTAB_I]
-We got no choice baby!
-
-[GTAB_J]
-We always got a choice you dumb bastard!
-
-[GTAB_K]
-I'm sorry about that crazy bitch man, they all the same...por favor??
-
-[GTAB_L]
-So the whore got away.
-
-[GTAB_M]
-But you've done me a favor,
-
-[GTAB_N]
-you're not the only one that has a score to settle with the Cartel,
-
-[GTAB_O]
-this worm killed my brother!
-
-[GTAB_P]
-I never killed no Yakuza!
-
-[GTAB_Q]
-LIAR! We all saw the Cartel assassin.
-
-[GTAB_R]
-We are going to hunt down and kill all you Colombian dogs!
-
-[GTAB_S]
-I'll be operating on our friend here to extract information and a little pleasure.
-
-[GTAB_T]
-You, drop by later, I'm sure I'll require your services.
-
-[GTAB_U]
-Please amigo, don't leave me with her, she psycho chica! Amigo? Hey AMEEEGO!!!...Aiiieeeeaaargghh!
-
-[LOVE5_A]
-You are proving to be a safe investment, a rare thing in these days of false hood.
-
-[KM3_1]
-~g~The Cartel are expecting a Yardie Posse go and steal a Yardie car! Head north you'll find one in Newport.
-
-[LOVE1_1]
-~g~Go 'jack a Colombian gang car, so you can infiltrate the hideout, head north you'll find one in Fort Staunton.
-
-[FM1_Q1]
-~w~You looking for some fun? A little...hmm? Some SPANK?
-
-[FM1_R]
-~w~Hi Chico. Nah, just the usual.
-
-[FM1_T]
-~w~Thanks Chico. See you around.
-
-[FM1_W]
-~w~Alright Fido, you wait here and look after the car while I go and shake my butt alright.
-
-[FM1_X]
-~w~OK Fido, let's get out of here. Wooooh!
-
-[FM1_Q]
-~w~Hey Maria! It's my favorite lady!
-
-[FM1_S1]
-~w~Hey, maybe you should check out the warehouse party at the east end of Atlantic Quays.
-
-[FM1_U]
-~w~Gracias and enjoy. That's good stuff.
-
-[FM1_V]
-~w~C'mon Fido, let's go and check out this party!
-
-[FM1_SS]
-~r~SCANNER: ~g~Four-five to all units: Assist narcotics raid Atlantic Quays...
-
-[LOVE6_B]
-even if they have little understanding as to its true value.
-
-[TM3_A1]
-~r~Joey's Fried!
-
-[TM3_A2]
-~r~Joey and Luigi have been cremated!
-
-[TM3_A3]
-~r~Joey, Luigi and Toni are Toast!
-
-[FM4_2]
-Listen, Salvatore thinks that we're going behind his back,
-
-[FM4_3]
-so he was offering you to the Cartel in order to make a deal.
-
-[FM4_4]
-I couldn't let him do that, I mean the worst thing is,
-
-[FM4_4B]
-it's all my fault... because I told him, we were an item.
-
-[FM4_5]
-Don't ask me why. I don't know.
-
-[FM4_6]
-Look you're a marked man on Mafia turf and I've got to get out of here too.
-
-[FM4_6B]
-I've seen too much killing. Too much blood!
-
-[FM4_7]
-This is a friend of mine ok, she's an old friend.. it's Asuka, she's someone we can trust.
-
-[FM4_8]
-C'mon, Enough of the speeches.
-
-[FM4_9]
-We better get out of here before we get more hysterical Italians wanting less friendly reunions.
-
-[CRED001]
-ROCKSTAR STUDIOS
-
-[CRED002]
-PRODUCER
-
-[CRED003]
-LESLIE BENZIES
-
-[CRED004]
-ART DIRECTOR
-
-[CRED005]
-AARON GARBUT
-
-[CRED006]
-TECHNICAL DIRECTION
-
-[CRED007]
-OBBE VERMEIJ
-
-[CRED008]
-ADAM FOWLER
-
-[CRED009]
-DESIGN
-
-[CRED010]
-CRAIG FILSHIE
-
-[CRED011]
-WILLIAM MILLS
-
-[CRED012]
-CHRIS ROTHWELL
-
-[CRED013]
-JAMES WORRALL
-
-[CRED014]
-WRITTEN BY
-
-[CRED015]
-JAMES WORRALL
-
-[CRED016]
-PAUL KUROWSKI
-
-[CRED017]
-DAN HOUSER
-
-[CRED018]
-CHARACTERS
-
-[CRED019]
-IAN MCQUE
-
-[CRED020]
-ANIMATION & DIRECTION
-
-[CRED021]
-ALEX HORTON
-
-[CRED022]
-LEE MONTGOMERY
-
-[CRED023]
-AUTO DESIGN
-
-[CRED024]
-PAUL KUROWSKI
-
-[CRED025]
-ARTISTS
-
-[CRED026]
-KEIRAN BAILLIE
-
-[CRED027]
-ADAM COCHRANE
-
-[CRED028]
-GARY MCADAM
-
-[CRED029]
-MICHAEL PIRSO
-
-[CRED030]
-ANDREW SOOSAY
-
-[CRED031]
-ALISDAIR WOOD
-
-[CRED032]
-CODERS
-
-[CRED033]
-ALAN CAMPBELL
-
-[CRED034]
-MARK HANLON
-
-[CRED035]
-ANDRZEJ MADAJCZYK
-
-[CRED036]
-ALEXANDER ROGER
-
-[CRED037]
-GRAEME WILLIAMSON
-
-[CRED038]
-SCORE
-
-[CRED039]
-CRAIG CONNER
-
-[CRED040]
-STUART ROSS
-
-[CRED041]
-SOUND DESIGN & MASTERING
-
-[CRED042]
-ALLAN WALKER
-
-[CRED043]
-AUDIO PROGRAMMING
-
-[CRED044]
-RAYMOND USHER
-
-[CRED045]
-TEST MANAGER
-
-[CRED046]
-CRAIG ARBUTHNOTT
-
-[CRED047]
-LEAD TESTERS
-
-[CRED048]
-ANDY DUTHIE
-
-[CRED049]
-JOHN HAIME
-
-[CRED050]
-NEIL CORBETT
-
-[CRD050A]
-TESTERS
-
-[CRED051]
-GRAEME JENNINGS
-
-[CRED052]
-DAVID MURDOCH
-
-[CRED053]
-DAVID BEDDOES
-
-[CRED054]
-EDWIN SMITH
-
-[CRED055]
-MARK FLETT
-
-[CRED056]
-MICHAEL SUTHERLAND
-
-[CRED057]
-TECHNICAL SUPPORT
-
-[CRED058]
-LORRAINE ROY
-
-[CRED059]
-CHRISTINE CHALMERS
-
-[CRED060]
-ROCKSTAR
-
-[CRED061]
-EXECUTIVE PRODUCER
-
-[CRED062]
-SAM HOUSER
-
-[CRED063]
-PRODUCER
-
-[CRED064]
-DAN HOUSER
-
-[CRED065]
-DIRECTOR OF DEVELOPMENT
-
-[CRED066]
-JAMIE KING
-
-[CRED067]
-TECHNICAL PRODUCER
-
-[CRED068]
-GARY J. FOREMAN
-
-[CRED069]
-ASSOCIATE PRODUCER
-
-[CRED070]
-JEREMY POPE
-
-[CRED071]
-MUSIC SUPERVISOR
-
-[CRED072]
-TERRY DONOVAN
-
-[CRED073]
-ROCKSTAR PRODUCTION TEAM
-
-[CRED074]
-TERRY DONOVAN
-
-[CRED075]
-JENNIFER KOLBE
-
-[CRED076]
-JENEFER GROSS
-
-[CRED077]
-LAURA PATERSON
-
-[CRED078]
-JEFF CASTANEDA
-
-[CRED079]
-CHRIS CARRO
-
-[CRED080]
-ADAM TEDMAN
-
-[CRED081]
-JUNG KWAK
-
-[CRED082]
-BRIAN WOOD
-
-[CRED083]
-PAUL YEATES
-
-[CRED084]
-STANTON SARJEANT
-
-[CRED085]
-VP OF MARKETING
-
-[CRED086]
-TERRY DONOVAN
-
-[CRED087]
-TECHNICAL COORDINATOR
-
-[CRED088]
-BRANDON ROSE
-
-[CRED089]
-QA MANAGER
-
-[CRED090]
-JEFF ROSA
-
-[CRED091]
-LEAD ANALYST
-
-[CRED092]
-ADAM DAVIDSON
-
-[CRED093]
-GAME ANALYST
-
-[CRED094]
-RICHARD HUIE
-
-[CRED095]
-TEST TEAM
-
-[CRED096]
-LANCE WILLIAMS
-
-[CRED097]
-JOE GREENE
-
-[CRED098]
-BRIAN PLANER
-
-[CRED099]
-OSWALD GREENE
-
-[CRED100]
-LIBERTY TREE EDITORIAL
-
-[CRED101]
-JAMES WORRALL
-
-[CRED102]
-DAN HOUSER
-
-[CRED103]
-ADAM TEDMAN
-
-[CRED104]
-PAUL YEATES
-
-[CRED105]
-JENEFER GROSS
-
-[CRED106]
-LAURA PATERSON
-
-[CRED107]
-CUT-SCENES
-
-[CRED108]
-SCRIPT BY DAN HOUSER AND JAMES WORRALL
-
-[CRED109]
-AUDIO DIRECTED BY DAN HOUSER
-
-[CRED110]
-AUDIO PRODUCED BY RENAUD SEBBANE
-
-[CRED111]
-CAST
-
-[CRED112]
-FRANK VINCENT AS SALVATORE LEONE
-
-[CRED113]
-JOE PANTOLIANO AS LUIGI GOTERELLI
-
-[CRED114]
-MICHAEL MADSEN AS TONI CIPRIANI
-
-[CRED115]
-MICHAEL RAPAPORT AS JOEY LEONE
-
-[CRED116]
-DEBBI MAZAR AS MARIA
-
-[CRED117]
-KYLE MACLACHLAN AS DONALD LOVE
-
-[CRED118]
-ROBERT LOGGIA AS RAY MACHOWSKI
-
-[CRED119]
-GURU AS 8-BALL
-
-[CRED120]
-SONDRA JAMES AS MOMMA
-
-[CRED121]
-LIANA PAI AS ASUKA
-
-[CRED122]
-LES MAU AS KENJI
-
-[CRED123]
-CYNTHIA FARRELL AS CATALINA
-
-[CRED124]
-AL ESPINOSA AS MIGUEL
-
-[CRED125]
-CHRIS PHILLIPS AS EL BURRO
-
-[CRED126]
-HUNTER PLATIN AS CHICO
-
-[CRED127]
-WALTER MUDU AS D-ICE
-
-[CRED128]
-CURTIS MCCLARIN AS CURTLY
-
-[CRED129]
-BILL FIORE AS DARKEL
-
-[CRED130]
-CHRIS PHILLIPS AS MARTY CHONKS
-
-[CRED131]
-HUNTER PLATIN AS CURLY BOB
-
-[CRED132]
-WALTER MUDU AS KING COURTNEY
-
-[CRED133]
-HUNTER PLATIN AS ONE-ARMED PHIL
-
-[CRED134]
-KIM GURNEY AS MISTY
-
-[CRED135]
-MOTION CAPTURE
-
-[CRED136]
-ANIMATED BY
-
-[CRD136A]
-ALEX HORTON
-
-[CRED137]
-DIRECTED BY
-
-[CRD137A]
-NAVID KHONSARI
-
-[CRED138]
-PRODUCED BY
-
-[CRD138A]
-JAMIE KING
-
-[CRD138B]
-RENAUD SEBBANE
-
-[CRED139]
-RECORDED AT MODERN UPRISING STUDIOS, BROOKLYN
-
-[CRED140]
-ACTORS
-
-[CRD140A]
-RENAUD SEBBANE
-
-[CRD140B]
-GISELLE JONES
-
-[CRD140C]
-STEPHEN DANIELS
-
-[CRD140D]
-ROBERT STIO
-
-[CRD140E]
-JENNY GROSS.
-
-[CRED141]
-PEDESTRIAN DIALOGUE
-
-[CRED142]
-WRITTEN BY DAN HOUSER, NAVID KHONSARI & JAMES WORRALL
-
-[CRED143]
-DIRECTED BY CRAIG CONNER, DAN HOUSER AND LAZLOW
-
-[CRED144]
-PRODUCED BY RENAUD SEBBANE
-
-[CRED145]
-CAST
-
-[CRED146]
-HUNTER PLATIN
-
-[CRED147]
-DAN HOUSER
-
-[CRED148]
-RENAUD SEBBANE
-
-[CRED149]
-MARIA CHAMBERS
-
-[CRED150]
-JEFF STANTON
-
-[CRED151]
-RYAN CROY
-
-[CRED152]
-DEENA BERMAN
-
-[CRED153]
-MARIA CHAMBERS
-
-[CRED154]
-ALICE B. SALTZMAN
-
-[CRED155]
-ALEX ANTHONY SIOUKAS
-
-[CRED156]
-SEAN R. LYNCH
-
-[CRED157]
-AMY SALZMAN
-
-[CRED158]
-COLIN MCSHANE
-
-[CRED159]
-COREY WADE
-
-[CRED160]
-GERALD COSGROVE
-
-[CRED161]
-STEPHANIE ROY
-
-[CRED162]
-DORIS WOO
-
-[CRED163]
-JOSEPH GREENE
-
-[CRED164]
-LAZLOW JONES
-
-[CRED165]
-HSIANG LIN
-
-[CRED166]
-STEVE MICHAEL ROBERT
-
-[CRED167]
-MATHEW MURRAY
-
-[CRED168]
-RICHARD HUIE
-
-[CRED169]
-GARVIN ATWELL
-
-[CRED170]
-STEVE KNEZEVICH
-
-[CRED171]
-YUKIMURA SATO
-
-[CRED172]
-FRANK CHAVEZ
-
-[CRED173]
-LIEZL JACINTO
-
-[CRED174]
-CANAAN MCKOY
-
-[CRED175]
-ADAM DAVIDSON
-
-[CRED176]
-LANCE WILLIAMS
-
-[CRED177]
-NEIL MCCAFFREY
-
-[CRED178]
-LAURA PATERSON
-
-[CRED179]
-REY CONCEPCION
-
-[CRED180]
-CHARLES HEROLD
-
-[CRED181]
-ANDREW GREENWALD
-
-[CRED182]
-JAMES MIELKE
-
-[CRED183]
-PETER SUCIU
-
-[CRED184]
-ALEX ODULIO
-
-[CRED185]
-DON NKRUMAH
-
-[CRED186]
-KENDALL PITTMAN
-
-[CRED187]
-SAL SUAZO
-
-[CRED188]
-EREK MATEO
-
-[CRED189]
-CHRIS DIFATE
-
-[CRED190]
-LEILA MILTON
-
-[CRED191]
-DARREN ZOLTOWSKI
-
-[CRED192]
-VIRGINIA SMITH
-
-[CRED193]
-KEVIN CASSIN
-
-[CRED194]
-JASON SHIGEMORI
-
-[CRED195]
-KELLY KINSELLA
-
-[CRED196]
-MOLLIE STICKNEY
-
-[CRED197]
-STANTON SARJEANT
-
-[CRED198]
-LAURA WALSH
-
-[CRED199]
-MARK GARONE
-
-[CRED200]
-JOANNA SLY
-
-[CRED201]
-ELIZABETH HOWELL
-
-[CRED202]
-ANA HERCULES
-
-[CRED203]
-SHIRLEY IRICK
-
-[CRED204]
-KASHONA FIELDS
-
-[CRED205]
-JOEL M. LILJE
-
-[CRED206]
-JOHN DIBENEDETTO
-
-[CRED207]
-NANCY GILES
-
-[CRED208]
-RYAN CROY
-
-[CRED209]
-JENNIFER KOLBE
-
-[CRED210]
-LIAM BURKE
-
-[CRED211]
-SIGRID PREISSL
-
-[CRED212]
-ANITA FITZSIMONS
-
-[CRED213]
-PHILIPPA RASELLI
-
-[CRED214]
-WIL QUESNEL
-
-[CRED215]
-FALKO BURKERT
-
-[CRED216]
-SARA SEWELL
-
-[CRED217]
-RADIO STATIONS AND MUSIC
-
-[CRED218]
-PRODUCERS FOR DMA DESIGN
-
-[CRD218A]
-CRAIG CONNER
-
-[CRD218B]
-STUART ROSS
-
-[CRED219]
-SOUNDTRACK CO-ORDINATOR
-
-[CRED220]
-TERRY DONOVAN
-
-[CRED221]
-PRODUCER FOR ROCKSTAR GAMES
-
-[CRED222]
-DAN HOUSER
-
-[CRED223]
-EDITED BY
-
-[CRED224]
-CRAIG CONNER
-
-[CRED225]
-ALLAN WALKER
-
-[CRED226]
-LAZLOW
-
-[CRED227]
-DJ BANTER AND IMAGING WRITTEN BY
-
-[CRED228]
-DAN HOUSER
-
-[CRED229]
-LAZLOW
-
-[CRED230]
-SPECIAL THANKS TO
-
-[CRED231]
-ADAM TEDMAN
-
-[CRED232]
-ALEX MASON
-
-[CRED233]
-JUDY HENDERSON CASTING
-
-[CRED234]
-HAMISH BROWN
-
-[CRED235]
-CHRISSY HOBAN
-
-[CRED236]
-INNES RICARD
-
-[CRED237]
-LILION BROZSKA
-
-[CRED238]
-BOB HILLARY
-
-[CRED239]
-EMILY ANDERSON
-
-[CRED240]
-RICHIE HENDERSON
-
-[CRED241]
-CHRSTIAN CANTAMESSA
-
-[CRED242]
-JERONIMO BARRERA
-
-[CRED243]
-ALEXANDER ILLES
-
-[CRED244]
-BARANE CHAN
-
-[CRED245]
-DUNCAN SHIELDS
-
-[CRED246]
-BARANE CHAN
-
-[CRED247]
-DEREK PAYNE
-
-[CRED248]
-KEVIN WONG
-
-[CRED249]
-ROSS ELLIOTT
-
-[CRED250]
-ROSS BEAZLEY
-
-[CRED251]
-ALEX BAZLINTON
-
-[CRED252]
-DAVE WATSON
-
-[CRED253]
-MALCOLM SMITH
-
-[CRED254]
-STUDIO MANAGER
-
-[CRED255]
-ANDREW SEMPLE
-
-[CRED256]
-ARTIST
-
-[CRED257]
-STUART PETRI
-
-[CRED258]
-JERONIMO BARRERA
-
-[CRED259]
-CARLY SLATER
-
-[CRED260]
-GREG LAU
-
-[CRED261]
-STEVE KNEZEVICH
-
-[CRED262]
-DEVIN WINTERBOTTOM
-
-[CRED263]
-JAMEEL VEGA
-
-[CRED264]
-LEE CUMMINGS
-
-[CRED265]
-DEVIN BENNET
-
-[CRED266]
-ELIZABETH SATTERWHITE
-
-[CRED267]
-AARON RIGBY
-
-[CRED268]
-STEVE K.
-
-[CRED269]
-GREG LAU
-
-[CINCAM]
-Cinematic Camera
-
-[KM1_13]
-Drive the vehicle into the garage!
-
-[KM3_14]
-~r~You have been spotted the deal is off!
-
-[EBAL_H]
-Wait here man while I go in and talk to Luigi.
-
-[EBAL_M]
-Remember no one messes with my girls!
-
-[LM2_F]
-Then take his car, respray it.
-
-[LM2_D]
-here, here take it.
-
-[LM1_9]
-Hi I'm Misty.
-
-[LM4_A]
-Some Diablo scumbag has been pimping his skuzzy bitches in my backyard.
-
-[FM2_B]
-We got us a rat!
-
-[FM2_C]
-He ain't pimpin' or pushin' so he must be talking.
-
-[FM3_CC]
-~w~Come back brother when you have the money.
-
-[FEDS_AM]
-<>-CHANGE MENU
-
-[LOVE5_5]
-~r~You failed to protect the truck!
-
-[RM6_6]
-~r~Ray is dead!
-
-[RM6_7]
-~r~Ray has missed his flight.
-
-[RM6_8]
-~g~You have left Ray behind, go back and get him.
-
-[FM1_10]
-~g~You have left Maria behind, go back and pick her up.
-
-[LOVE4_9]
-~r~The plane has been destroyed!
-
-[LOV4_10]
-~r~The only lead to where the package has gone has been destroyed!
-
-[KM2_D]
-Needless to say, we must give him the cars as a gift, to repay the debt that I owe him.
-
-[KM4_B]
-The business's fortunate enough to have our protection settle their accounts today.
-
-[KM2_E]
-You must obtain the cars on this list and deliver them to a garage behind the car park in Newport.
-
-[FM3_8I]
-~w~Get a good vantage point then I'll head in when you fire the first shot.
-
-[LOVE1_B]
-Experience has taught me that a man like you can be very loyal for the right price,
-
-[LOVE1_H]
-but groups of men get greedy.
-
-[LOVE1_C]
-A valued resource, an old oriental gentleman I know,
-
-[LOVE1_I]
-has been kept hostage by some South Americans in Aspatria.
-
-[MEA4_D]
-I've agreed to see him...
-
-[MEA4_B4]
-Marty sent you huh? OK, I'm gonna show that creep the meaning of the word business.
-
-[MEA4_B5]
-Carl, hi! i eerr, I need more time to get your money.
-
-[MEA1_B4]
-Ah, Mr Chonks sent you did he. Let's go and pay the fellow a visit.
-
-[HM5_6]
-Let's go crack some skulls...
-
-[LOVE1_5]
-~g~Stop hanging around, get a Colombian Gang car and rescue Love's associate.
-
-[AS1_D]
-~w~Act as the bait, and get the death squads to follow you to Pike Creek
-
-[AS1_E]
-~w~where some of my men will be waiting for them.
-
-[AS2_C]
-~w~The Cartel have a front company, The Kappa Coffee House.
-
-[AS2_E]
-~w~We have no choice but to put these drug stands out of operation.
-
-[AS2_F]
-~w~Smash them to splinters!!
-
-[AS2_A1]
-~w~Miguel certainly has some of that famous Latin stamina.
-
-[AS2_A2]
-~w~I'm quite exhausted.
-
-[SIREN_3]
-To turn on this vehicle's sirens tap the ~h~~k~~VEHICLE_HORN~ button~w~.
-
-[SIREN_4]
-To turn on this vehicle's sirens tap the ~h~~k~~VEHICLE_HORN~ button~w~.
-
-[AS3_C]
-~w~Eeeeeeyoooo! What IS that gooey yellow stuff?
-
-[AS3_C1]
-~w~Oh hi Babe.
-
-[AS3_F]
-~w~She's got the makings of a natural this girl.
-
-[AS3_F1]
-~w~She's managed to extract this little gem from our guest.
-
-[AS3_G]
-~w~There is a plane coming into Francis International in 2 hours time.
-
-[AS3_G1]
-~w~It is full of Catalina's poison.
-
-[AS3_H]
-~w~You can avoid airport security by getting a boat out to the runway-light buoys
-
-[AS3_H1]
-and shooting the plane down on its approach.
-
-[AS3_I]
-~w~Collect the cargo from the debris and stash it!
-
-[AS3_J]
-~w~Oh you be careful now, OK baby?
-
-[AS3_K]
-~w~Now try the chilli oil.....
-
-[RM2_F1]
-Those Colombians'll be here any minute!
-
-[RM2_K]
-Goddam they're here!! LOCK'N'LOAD!!
-
-[LOVE2_7]
-~g~Now dump the car!
-
-[LOVE2_8]
-~g~Now get out of Newport!
-
-[AM1_F]
-Salvatore Leone will be leaving Luigi's in about three hours time. (~1~:~1~)
-
-[LOVE5_C]
-I want you to follow him, and make sure both he and my package get to Pike Creek unharmed.
-
-[FESZ_SR]
-Save Failed! Check memory card (PS2) in MEMORY CARD slot 1 and please try again.
-
-[FESZ_FO]
-Would you like to format the memory card (PS2) in MEMORY CARD slot 1?
-
-[FELZ_FO]
-Memory card (PS2) in MEMORY CARD slot 1 is unformatted.
-
-[FES_NOC]
-No memory card (PS2) in MEMORY CARD slot 1.
-
-[FES_LOE]
-Load Failed! Check memory card (PS2) in MEMORY CARD slot 1 and please try again.
-
-[FES_DEE]
-Deleting Failed! Check memory card (PS2) in MEMORY CARD slot 1 and please try again.
-
-[SLONFM]
-Error formatting memory card (PS2) in MEMORY CARD slot 1.
-
-[SLONDR]
-Insufficient space to save. Please insert a memory card (PS2) with at least 500KB of free space available into MEMORY CARD slot 1.
-
-[SLNSP]
-Insufficient space to save. Please insert a memory card (PS2) with at least 200KB of free space available into MEMORY CARD slot 1.
-
-[FEFD_WR]
-Formatting memory card (PS2) in MEMORY CARD slot 1. Please do not remove the memory card (PS2), reset or switch off the console.
-
-[FES_ISF]
-NOT PRESENT
-
-[FES_SAG]
-PRESENT
-
-[SLONNO]
-No memory card (PS2) in MEMORY CARD slot 1.
-
-[SLONNF]
-Memory card (PS2) in MEMORY CARD slot 1 is unformatted.
-
-[FESZ_FM]
-Memory card (PS2) in MEMORY CARD slot 1 is unformatted. Would you like to format memory card (PS2) in MEMORY CARD slot 1?
-
-[FESZ_FF]
-Format Failed! Check memory card (PS2) in MEMORY CARD slot 1 and please try again.
-
-[MCDNSP]
-There is insufficient space on the memory card (PS2) in MEMORY CARD slot 1. At least 500KB is needed to save this application data. Do you wish to start? (YES or NO)
-
-[MCGNSP]
-There is insufficient space on the memory card (PS2) in MEMORY CARD slot 1. At least 200KB is needed to save this application data. Do you wish to start? (YES or NO)
-
-[FESZ_WR]
-Saving data. Please do not remove the memory card (PS2) in MEMORY CARD slot 1, reset or switch off the console.
-
-[FESZ_OW]
-Overwriting data. Please do not remove the memory card (PS2) in MEMORY CARD slot 1, reset or switch off the console.
-
-[FELD_WR]
-Loading data. Please do not remove the memory card (PS2) in MEMORY CARD slot 1, reset or switch off the console.
-
-[FEDL_WR]
-Deleting data. Please do not remove the memory card (PS2) in MEMORY CARD slot 1, reset or switch off the console.
-
-[LM2_C]
-Luigi said to, to give you this so...
-
-[LM3_G]
-Joey ain't the kind you keep waiting, remember, this is your foot in the door...
-
-[LM5_E]
-Get as many of them as you can before the cops drink away their green.
-
-[JM5_C]
-Alright, there's a car stuffed with a stiff at the cafe near Callahan Point.
-
-[RM2_B]
-We saw action in Nicaragua, back when the country knew what it was doing.
-
-[RM2_C]
-Some Cartel scum roughed him up yesterday, said they'd be back for some of his stock today.
-
-[RM2_D1]
-I'd go myself but the old sciatica's playing up again -cough cough- so, eerr-hhrrmmm, good luck.
-
-[CATINF1]
-~g~Get Catalina!
-
-[CATINF2]
-~g~Follow the chopper to find Catalina.
-
-[BOATIN1]
-Jump into a boat and press the ~h~~k~~VEHICLE_ENTER_EXIT~ button ~w~to get in.
-
-[BOATIN2]
-You can press the ~h~~k~~VEHICLE_ENTER_EXIT~ button ~w~if you are near a boat to get in it.
-
-[BOATIN3]
-Jump into a boat and press the ~h~~k~~VEHICLE_ENTER_EXIT~ button ~w~to get in.
-
-[BOATIN4]
-You can press the ~h~~k~~VEHICLE_ENTER_EXIT~ button ~w~if you are near a boat to get in it.
-
-[JM6]
-'THE GETAWAY'
-
-[FM1]
-'CHAPERONE'
-
-[JM1]
-'MIKE LIPS LAST LUNCH'
-
-[FM21]
-'BOMB DA BASE: ACT I'
-
-[FM3]
-'BOMB DA BASE: ACT II'
-
-[AM1]
-'SAYONARA SALVATORE'
-
-[AM2]
-'UNDER SURVEILLANCE'
-
-[KM2]
-'GRAND THEFT AUTO'
-
-[AS3]
-'S.A.M.'
-
-[RM2]
-'ARMS SHORTAGE'
-
-[LOVE6]
-'DECOY'
-
-[LOVE1]
-'LIBERATOR'
-
-[RC1]
-'DIABLO DESTRUCTION'
-
-[RC2]
-'MAFIA MASSACRE'
-
-[RC3]
-'CASINO CALAMITY'
-
-[RC4]
-'RUMPO RAMPAGE'
-
-[RM2_E1]
-I can't believe those yellow-bellied bastards left me without proper cover again!
-
-[GREN_1]
-The longer you hold the ~h~~k~~PED_FIREWEAPON~ button~w~, the further you will throw the grenade.
-
-[GREN_2]
-The longer you hold the ~h~~k~~PED_FIREWEAPON~ button~w~, the further you will throw the grenade.
-
-[GREN_3]
-The longer you hold the ~h~~k~~PED_FIREWEAPON~ button~w~, the further you will throw the grenade.
-
-[LOVE4_G]
-My property will be waiting for you at the customs hanger in the aircraft's fuselage.
-
-[KABOOM]
-KABOOOM!
-
-[SPLAT]
-SPLAT!
-
-[PANCAK]
-PANCAKED!
-
-[SOAKED]
-SOAKED!
-
-[HEAD]
-Head Radio
-
-[DBL_CLF]
-Double Clef FM
-
-[FLASHB]
-Flashback FM
-
-[RISE]
-Rise FM
-
-[LIPS]
-Lips 106
-
-[CHAT]
-Chatterbox FM
-
-[K_JAH]
-K-Jah Radio
-
-[GAM_FM]
-Game Radio FM
-
-[MSX_FM]
-MSX FM
-
-[TUBE1]
-When the subway opens you will be able to catch a train to Staunton Island.
-
-[TUBE2]
-When Shoreside Vale opens you will be able to Exit Shoreside Terminal to Francis International Airport.
-
-[TUBE_2]
-To board a subway train, press the ~h~'enter vehicle' button~w~.
-
-[LEGAL]
-~g~Eliminate the criminal threat!
-
-[GA_2]
-New engine and paint job. The cops won't recognize you!
-
-[LM1_8A]
-To earn some extra cash, why not 'borrow' a taxi...
-
-[TAXIH1]
-Stop near a highlighted pedestrian to pick them up then drive them to their destination before the time runs out.
-
-[LM5_7]
-~g~Less than four girls working the ~p~Fuzz Ball~g~ and Luigi won't be happy!
-
-[KM2_3]
-~g~Remember the ~r~cars~g~ have to be in mint condition to be accepted by the ~p~garage~g~.
-
-[KM5_2]
-~g~A Yardie is off the streets.
-
-[BETRA_A]
-Sorry, babe.
-
-[BETRA_B]
-I'm an ambitious girl and you,
-
-[BETRA_C]
-you're just small time.
-
-[JAILB_Q]
-Come on!
-
-[JAILB_R]
-Senor dickhead!
-
-[JAILB_S]
-It's no problem to kill you.
-
-[JAILB_T]
-You gonna be sorry.
-
-[JAILB_U]
-A'right, a'right. Get lost.
-
-[HELP15]
-When on foot press the ~h~~k~~PED_LOOKBEHIND~ button~w~ to ~h~look behind~w~.
-
-[FEC_LB3]
-Look behind
-
-[FEC_R3]
-(R3 button)
-
-[FES_AFO]
-This memory card (PS2) is already formatted.
-
-[FEA_UP]
-;
-
-[FEA_DO]
-=
-
-[FEA_LE]
-<
-
-[FEA_RI]
->
-
-[FEDSAS3]
-- CHANGE SELECTION
-
-[FEDSAS4]
-;=<> - CHANGE SELECTION
-
-[SPRAY_4]
-Use the ~h~~k~~PED_FIREWEAPON~ button ~w~to fire the water cannon.
-
-[SPRAY_1]
-Use the ~h~~k~~PED_FIREWEAPON~ button ~w~to fire the water cannon.
-
-[LITTLE]
-LITTLE T
-
-[NICK]
-NICK LOVE
-
-[AM1_10]
-~g~Salvatore will be leaving Luigi's at about 0~1~:~1~
-
-[FEDS_SE]
-/ button - SELECT
-
-[FEDS_SB]
-/ button - SELECT " button - BACK
-
-[TM4_A]
-~w~Oh it's you. TONI ain't here.
-
-[TM4_A2]
-~w~But he left one of his sugary love letters for you.
-
-[DIAB2_A]
-I started my exotic entertainment business with nothing but the sizeable contents of my leather pants!
-
-[LM5_9]
-GIRLS:
-
-[PERPIC]
-Hidden Packages found
-
-[CO_ONE]
-Hidden Package ~1~ of ~1~
-
-[LOVE3_3]
-~g~The plane has dropped ~1~ of 6 packages.
-
-[FARE11]
-~g~Destination ~w~'Construction site' ~g~in Fort staunton.
-
-[GA_21]
-You cannot store any more cars in this garage.
-
-[CHEAT1]
-Cheat activated
-
-[CHEAT2]
-Weapon cheat
-
-[CHEAT3]
-Health cheat
-
-[CHEAT4]
-Armor cheat
-
-[CHEAT5]
-Wanted level cheat
-
-[CHEAT6]
-Money cheat
-
-[CHEAT7]
-Weather cheat
-
-[AS1_H]
-~r~You failed to lead the Deathsquad into the Yakuza trap!!
-
-[FEDS_BA]
-" button - BACK
-
-[FED_WIS]
-Wide Screen:
-
-[RAMP_A]
-ALL RAMPAGES COMPLETED!
-
-[USJ_ALL]
-ALL UNIQUE STUNTS COMPLETED!
-
-[FARE23]
-~g~Destination ~w~'import export garage' ~g~in Cochrane Dam district
-
-[L_TRN_1]
-You can ride the L-train around Portland. Press the~h~ ~k~~VEHICLE_ENTER_EXIT~ button~w~ to ~h~enter ~w~or ~h~exit~w~ a train.
-
-[L_TRN_2]
-You can ride the L-train around Portland. Press the~h~ ~k~~VEHICLE_ENTER_EXIT~ button~w~ to ~h~enter ~w~or ~h~exit~w~ a train.
-
-[S_TRN_1]
-You can take the subway trains across Liberty. Press the~h~ ~k~~VEHICLE_ENTER_EXIT~ button~w~ to ~h~enter ~w~or ~h~exit~w~ a train.
-
-[S_TRN_2]
-You can take the subway trains across Liberty. Press the~h~ ~k~~VEHICLE_ENTER_EXIT~ button~w~ to ~h~enter ~w~or ~h~exit~w~ a train.
-
-[AS1_C]
-~w~She has three death squads dotted around Liberty, whose sole job is to hunt you down.
-
-[AS1_G]
-~r~All the Yakuza are dead!!
-
-[JAN]
-Jan
-
-[FEB]
-Feb
-
-[MAR]
-Mar
-
-[APR]
-Apr
-
-[MAY]
-May
-
-[JUN]
-Jun
-
-[JUL]
-Jul
-
-[AUG]
-Aug
-
-[SEP]
-Sept
-
-[OCT]
-Oct
-
-[NOV]
-Nov
-
-[DEC]
-Dec
-
-[DEFDT]
---:---:---- --:--:--
-
-[BUGGY]
-BUGGIES LEFT:
-
-[BONUS]
-~g~BONUS $~1~
-
-[HORN1]
-Press the ~h~L3 button ~w~to activate the ~h~horn.
-
-[HORN2]
-Press the ~h~L1 button ~w~to activate the ~h~horn
-
-[HORN3]
-Press the ~h~R1 button ~w~to activate the ~h~horn
-
-[LM3_1A]
-Press the~h~ ~k~~VEHICLE_HORN~ button~w~ to activate the ~h~horn~w~ and let Misty know you are here.
-
-[LM3_1B]
-Press the~h~ ~k~~VEHICLE_HORN~ button~w~ to activate the ~h~horn~w~ and let Misty know you are here.
-
-[LM3_1C]
-Press the~h~ ~k~~VEHICLE_HORN~ button~w~ to activate the ~h~horn~w~ and let Misty know you are here.
-
-[RADIO_A]
-Press the ~h~~k~~VEHICLE_CHANGE_RADIO_STATION~ button~w~ to cycle through the ~h~radio stations.
-
-[RADIO_B]
-Press the ~h~~k~~VEHICLE_CHANGE_RADIO_STATION~ button~w~ to cycle through the ~h~radio stations.
-
-[RADIO_C]
-Press the ~h~~k~~VEHICLE_CHANGE_RADIO_STATION~ button~w~ to cycle through the ~h~radio stations.
-
-[RADIO_D]
-Press the ~h~~k~~VEHICLE_CHANGE_RADIO_STATION~ button~w~ to cycle through the ~h~radio stations.
-
-[FEC_EXV]
-Enter and exit vehicle
-
-[TAXI_M]
-'TAXI DRIVER'
-
-[COP_M]
-'VIGILANTE'
-
-[FIRE_M]
-'FIREFIGHTER'
-
-[AMBUL_M]
-'PARAMEDIC'
-
-[HJ_IS]
-INSANE STUNT BONUS: $~1~
-
-[HJ_PIS]
-PERFECT INSANE STUNT BONUS: $~1~
-
-[HJ_DIS]
-DOUBLE INSANE STUNT BONUS: $~1~
-
-[HJ_PDIS]
-PERFECT DOUBLE INSANE STUNT BONUS: $~1~
-
-[HJ_TIS]
-TRIPLE INSANE STUNT BONUS: $~1~
-
-[HJ_PTIS]
-PERFECT TRIPLE INSANE STUNT BONUS: $~1~
-
-[HJ_QIS]
-QUADRUPLE INSANE STUNT BONUS: $~1~
-
-[HJ_PQIS]
-PERFECT QUADRUPLE INSANE STUNT BONUS: $~1~
-
-[AM1_K]
-Salvatore Leone will be leaving Luigi's in about three hours time. (0~1~:~1~)
-
-[IMPEXPP]
-Import/Export garage, Portland Harbor. We have orders for various vehicles. Check our notice board for our requirements.
-
-[VANHSTP]
-Any more Securicars you want cracked? Bring them to our garage in the Portland Harbor.
-
-[EMVHPUP]
-Great rates paid for new and used Emergency Vehicles. Bring them to the crane in the north east of Portland Harbor.
-
-[STANDS]
-STALLS WRECKED:
-
-[STASH]
-~g~Stash the SPANK back at the ~p~construction site!
-
-[MCSTNS]
-There is no memory card (PS2) in MEMORY CARD slot 1. Do you wish to start? (YES or NO)
-
-[LOVE3_5]
-~g~The plane is now in range.
-
-[LOVE3_6]
-~r~The Police got to the packages first!
-
-[SIREN_1]
-To turn on this vehicle's sirens tap the ~h~~k~~VEHICLE_HORN~ button~w~.
-
-[SIREN_2]
-To turn on this vehicle's sirens tap the ~h~~k~~VEHICLE_HORN~ button~w~.
-
-[FM3_8C]
-~w~I'll need $100,000 to cover expenses,
-
-[MCLOAD]
-Loading Data. Please do not remove the memory card (PS2) in MEMORY CARD slot 1, reset or switch off the console.
-
-[FES_GME]
-Error Reading memory card (PS2) in MEMORY CARD slot 1 please check and try again.
-
-[FESZ_QF]
-Are you sure you wish to format the memory card (PS2) in MEMORY CARD slot 1?
-
-[FESZ_LS]
-Load Successful.
-
-[RM3_5]
-~g~You have ~1~ of 6 evidence packages.
-
-[LOVE3_2]
-~g~You have all the packages! Take them back to Donald Love.
-
-[LOVE4_4]
-~g~Take the package back to Donald Love!
-
-[FEB_SAV]
-Load
-
-[FEP_SAV]
-LOAD GAME
-
-[AS2_12A]
-~g~After you trash the first stall, you will have 8 minutes before the Cartel warn their pushers!
-
-[AS3_1A]
-~g~Now get to the ~b~marker buoy!
-
-[NOCONT]
-Please reconnect analog controller (DUALSHOCK#) or analog controller (DUALSHOCK#2) to controller port 1 to continue
-
-[BET_JB]
-BETRAYED BY HIS LOVER CATALINA AND LEFT FOR DEAD. CONVICTED AND SENTENCED, HE BEGINS HIS JOURNEY TO LIBERTY CITY PENITENTIARY. BUT ONLY ONE THOUGHT BURNS IN HIS CRIMINAL MIND......REVENGE!
-
-[END_A]
-Residents in Cedar Grove have been coming to terms
-
-[END_B]
-with the emotional aftermath of a full blown war
-
-[END_C]
-that hit the area yesterday.
-
-[END_D]
-Local resident, Clive Denver described to police
-
-[END_E]
-a single gunman that he saw fleeing the scene, with a dark haired woman.
-
-[END_F]
-Oh, you know, we're gonna have such fun, 'cos you know, you know,
-
-[END_G]
-I love you, I, I, I, I really do, 'cos you're such a big strong man
-
-[END_H]
-and that's just what I need.
-
-[END_I]
-Anyway, what was I saying?
-
-[END_J]
-Oh, you know, I forget. But you know what it's like, don't you?
-
-[END_K]
-The sound of explosions shook nearby homes as people ran for cover.
-
-[END_L]
-Several citizens were injured in the panic as ground fire was exchanged
-
-[END_M]
-between ground forces and a helicopter circling the dam.
-
-[END_N]
-Yeah, we got a good view from down here in the gardens.
-
-[END_O]
-When the 'copter finally got taken out,
-
-[END_P]
-better than the fireworks on the 4th of July.
-
-[END_Q]
-With the death toll already over twenty,
-
-[END_R]
-police are still finding bodies.
-
-[END_S]
-There have been no official denials concerning rumours
-
-[END_T]
-that the dead were members of the Colombian Cartel,
-
-[END_U]
-and still no leads as to the cause of the massacre.
-
-[END_V]
-I broke a nail and my hair is ruined, I mean can you believe it?
-
-[END_W]
-This one cost me fifty dollars...
-
-[PAPER1]
-*
-
-[PAPER2]
-*
-
-[PAPER3]
-*
-
-[JAILB_V]
-*
-
-[JAILB_A]
-*
-
-[JAILB_B]
-*
-
-[JAILB_C]
-*
-
-[JAILB_E]
-*
-
-[JAILB_F]
-*
-
-[JAILB_G]
-*
-
-[JAILB_I]
-*
-
-[JAILB_W]
-*
-
-[JAILB_K]
-*
-
-[JAILB_L]
-*
-
-[JAILB_X]
-*
-
-[JAILB_M]
-*
-
-[JAILB_N]
-*
-
-[JAILB_O]
-*
-
-[JAILB_P]
-*
-
-[JAILB_D]
-*
-
-[JAILB_H]
-*
-
-[JAILB_J]
-*
-
-[DUMMY]
-THIS LABEL NEEDS TO BE HERE !!!
-AS THE LAST LABEL DOES NOT GET COMPILED \ No newline at end of file
diff --git a/utils/gxt/french.txt b/utils/gxt/french.txt
index bd4acf96..246600a1 100644
--- a/utils/gxt/french.txt
+++ b/utils/gxt/french.txt
@@ -5,7154 +5,7062 @@
unnecessary edits like rephasing because you think it suits better for your taste.
}
-[LETTER1]
-abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789"$,.'-?!!SDBF
-
-[DEFNAM]
-Claude----------------------
-
-[IN_VEH]
-~g~Hé! Retourne dans ta caisse!
-
-[IN_VEH2]
-~g~T'as besoin d'une caisse pour cette mission!
-
-[IN_BOAT]
-~g~T'as besoin d'un bateau pour cette mission!
-
-[HEY]
-~g~Te la joue pas perso, pense à tes potes!
-
-[HEY2]
-~g~Restez groupés!
+[RAMPAGE]
+RODEO!
-[HEY3]
-~g~T'as perdu ton meilleur homme, retournes-y et ramène-le!
+[RAMP_F]
+ECHEC DU RODEO!
-[HEY4]
-~g~Perds Misty, et Luigi te fera sauter la tête ! Alors, retourne la chercher!
+[RAMP_P]
+RODEO REUSSI!
-[HEY5]
-~g~L'une des filles manque à l'appel! Retourne la chercher!
+[RAMP_A]
+TOUS LES RODEOS REUSSIS!
-[HEY6]
-~g~Ton honneur est lié à celui du Yakuza Kanbu. Tu dois le protéger!
+[PAGE_01]
+Tue ~1~ membres de gang en 2 minutes!
-[HEY7]
-~g~Un flingue de plus ferait pas de mal! Retourne en arrière et embarque ton contact!
+[PAGE_02]
+Détruis ~1~ véhicules en 2 minutes!
-[HEY8]
-~g~Dans protection, y'a protection, compris ? Alors protège le vieux bridé!
+[PAGE_03]
+Roule à côte des membres de gang et tue-en ~1~ en 2 minutes!
-[HEY9]
-~g~Tu veux savoir ce qui se passe dans la rue ? Ben va voir ton contact!
+[PAGE_04]
+Ecrase ~1~ membres de gang en 2 minutes!
-[HELP2_A]
-Appuie sur la ~h~touche /~w~ quand tu cours pour piquer un ~h~sprint.
+[PAGE_05]
+Eclate la tête de ~1~ membres de gang en 2 minutes!
-[HELP3]
-Tu ne peux sprinter que pendant une courte durée, avant d'être claqué!
+[FEC_ABR]
+Accélérer, freiner ou marche arrière
-[HELP4_A]
-Appuie sur la ~h~touche ~k~~VEHICLE_ACCELERATE~~w~ pour ~h~accélérer.
+[CLOHELP]
+Vêtements changés!
-[HELP4_D]
-Pousse le ~h~stick analogique de droit~w~ vers le haut pour accélérer.
+[FE_MLG]
+LEGENDE DE LA CARTE
-[HELP5_A]
-Appuie sur la~h~ touche ~k~~VEHICLE_BRAKE~~w~ pour ~h~freiner~w~ ou pour ~h~passer la marche arrière~w~ si ta caisse est à l'arrêt.
+[FED_RDR]
+RADAR
-[HELP5_D]
-Pousse le ~h~stick analogique de droit~w~ vers le bas pour ~h~freiner~w~ ou pour ~h~passer la marche arrière~w~ si ta caisse est à l'arrêt.
+[FED_HUD]
+L'INTERFACE
-[HELP6_A]
-Appuie sur la ~h~touche ~k~~VEHICLE_HANDBRAKE~~w~ pour utiliser le ~h~frein à main du véhicule.
+[FED_RDL]
+GRAND
-[HELP6_C]
-Appuie sur la ~h~touche ~k~~VEHICLE_HANDBRAKE~~w~ pour utiliser le ~h~frein à main du véhicule.
+[FED_RDB]
+BIPS UNIQUEMENT
-[HELP6_D]
-Appuie sur la ~h~touche ~k~~VEHICLE_HANDBRAKE~~w~ pour utiliser le ~h~frein à main du caisse.
+[FED_HUF]
+FONDU
-[HELP7_A]
-Maintiens la ~h~touche ~k~~PED_LOCK_TARGET~~w~ enfoncée pour ~h~viser~w~ avec le fusil à lunette.
+[FEI_BTU]
+; = -
-[HELP7_D]
-Maintiens la ~h~touche ~k~~PED_LOCK_TARGET~~w~ enfoncée pour ~h~viser~w~ avec le fusil à lunette.
+[FEI_SCR]
+Fait défiler
-[HELP8_A]
-Appuie sur la ~h~touche ~k~~PED_SNIPER_ZOOM_IN~~w~ pour faire un ~h~zoom avant~w~ avec le fusil et sur la ~h~touche ~k~~PED_SNIPER_ZOOM_OUT~~w~ pour faire un ~h~zoom arrière~w~.
+[FEST_HV]
+Missions d'Autodéfense, niveau maximum
-[HELP9_A]
-Appuie sur la ~h~touche ~k~~PED_FIREWEAPON~~w~ pour ~h~tirer~w~ au fusil à lunette.
+[LG_01]
+Position du joueur
-[HELP10]
-Ce badge t'indique que la police te recherche.
+[LG_02]
+Avery Carrington
-[HELP11]
-Plus il y a de badges, plus il y a de flics à tes trousses.
+[LG_03]
+Motards
-[HELP13]
-Tu as parfois intérêt à utiliser des chemins qui n'apparaissent pas sur le radar.
+[LG_04]
+Colonel Cortez
-[TIMER]
-C'est une mission en temps limité, alors il faut la finir avant que le compte à rebours arrive à zéro!
+[LG_05]
+Ricardo Diaz
-[MISTY1]
-~r~Misty bouffe les pissenlits par la racine!
+[LG_06]
+Kent Paul
-[OUT_VEH]
-~g~Sors du véhicule!
+[LG_07]
+Avocat
-[GARAGE]
-Conduis ta caisse dans le garage et repars à pied.
+[LG_08]
+Phil Cassidy
-[WANTED1]
-~g~Largue les flics pour en avoir moins à tes basques!
+[LG_09]
+Chantier naval
-[NODOORS]
-~g~Hé, c'est pas des sardines! Trouve une caisse avec assez de sièges!
+[LG_10]
+Club Malibu
-[TRASH]
-~g~T'as vachement bousillé ta bagnole ! Fais-la réparer !
+[LG_11]
+Cubains
-[WRECKED]
-~r~Le caisse est fortue!
+[LG_12]
+Studio de Cinéma
-[HORN]
-~g~Klaxonne!
+[LG_13]
+Ammu-Nation
-[HORN4]
-Appuie sur la ~h~touche L3~w~ pour ~h~klaxonner.
+[LG_14]
+Haïtiens
-[NOMONEY]
-~g~T'as besoin de thune!
+[LG_15]
+Quincaillerie
-[OUTTIME]
-~r~T'es lent, mec, t'es trop lent!
+[LG_16]
+Planque
-[SPOTTED]
-~r~Ils en ont après ta peau!
+[LG_17]
+Crèmes glacées
-[REWARD]
-~1~$ de récompense
+[LG_18]
+Taxi Kaufman
-[GAMEOVR]
-FIN DE PARTIE
+[LG_19]
+Love Fist
-[Z]
-Valeur axe Z : ~1~
+[LG_20]
+Imprimerie
-[M_FAIL]
-ECHEC DE LA MISSION!
+[LG_21]
+Propriété
-[M_PASS]
-MISSION REUSSIE! ~1~$
+[LG_22]
+Pay 'n' Spray
-[O_PASS]
-PETIT BOULOT REUSSI!
+[LG_23]
+Boutique de fringues
-[O_FAIL]
-PETIT BOULOT RATE!
+[LG_24]
+Manoir de Tommy
-[DEAD]
-T'ES MORT!
+[LG_25]
+Téléphone
-[BUSTED]
-TU T'ES FAIT COFFRER!
+[LG_26]
+Station de radio Wildstyle
-[S_PROMP]
-Si tu n'es pas en mission, tu peux ~h~sauvegarder le jeu ici~w~, ça fera avancer la montre de six heures.
+[LG_27]
+Station de radio Flash FM
-[NUMBER]
-~1~
+[LG_28]
+Station de radio KChat
-[SCORE]
-~1~$
+[LG_29]
+Station de radio Fever 105
-[LOADCAR]
-CHARGEMENT DU VEHICULE...
+[LG_30]
+Station de radio VRock
-[CARSOFF]
-Trafic désactivé
+[LG_31]
+Station de radio VCPR
-[CARS_ON]
-Trafic activé
+[LG_32]
+Station de radio Espantoso
-[TEXTXYZ]
-Ecriture des coordonnées sur le fichier...
+[LG_33]
+Station de radio Emotion 98.3
-[CHEATON]
-Mode Triche activé
+[LG_34]
+Station de radio Onde 103
-[CHEATOF]
-Fonction tricher OFF
+[LG_35]
+Destination
-[UZI_IN]
-L'Uzi est disponible maintenant à Ammu-Nation!
+[LG_36]
+Sun Yard
-[IMPORT1]
-Va dehors et attends ton véhicule.
+[LG_37]
+Boîte de striptease
-[PAGEB1]
-Pistolet livré à la planque.
+[MAP_YAH]
+VOUS ETES ICI
-[PAGEB2]
-Uzi livré à la planque.
+[MAP_LEG]
+Légende
-[PAGEB3]
-Armure livrée à la planque.
+[SENTXS]
+Sentinelle XS
-[PAGEB4]
-Fusil à pompe livré à la planque.
+[VCNMAV]
+VCN Maverick
-[PAGEB5]
-Grenades livrées à la planque.
+[TAXSHRT]
+~g~Au lieu de conduire, tu peux te servir de ce taxi Kaufman pour te déplacer. Cela te coûtera $9.
-[PAGEB6]
-Cokctails molotov livrés à la planque.
+[BRIBE1]
+Tu viens de récupérer un pot-de-vin de la police. Cela réduira ton indice de recherche d'une étoile.
-[PAGEB7]
-AK47 livré à la planque.
+[SUNSHIN]
+Sunshine Autos
-[PAGEB8]
-Fusil à lunette livré à la planque.
+[KAUFCAB]
+Taxis Kaufman
-[PAGEB9]
-M16 livré à la planque.
+[BOATYAR]
+Le chantier naval
-[PAGEB10]
-Lance-roquettes livré à la planque.
+[WANT_L]
+Tu as perdu ton indice de recherche. Ne commets pas de délit tant que les étoiles brillent ou tu seras de nouveau très recherché.
-[PAGEB11]
-Lance-flammes livré à la planque.
+[HOTRNG]
+HOTRING
-[WANT_A]
-Tu ne seras arrêté que si tu possèdes un ~h~indice de recherche.
+[BLODRNG]
+BLOODRING
-[WANT_B]
-Ton ~h~indice de recherche~w~ est symbolisé par les étoiles dans le coin supérieur droit de l'écran.
+[DIRTRNG]
+DIRTRING
-[WANT_C]
-Ton ~h~indice de recherche~w~ est de 1...
+[IN_VEH]
+~g~Eh! Remonte dans ta caisse!
-[WANT_D]
-2...
+[HEY]
+~g~Te la joue pas perso, reste avec tes potes!
-[WANT_E]
-3...
+[HELP3]
+T'es vite crevé, ton sprint ne dure donc pas longtemps.
-[WANT_F]
-Plus ton ~h~indice de recherche~w~ augmente, plus les forces de l'ordre t'en veulent.
+[HELP4_D]
+Pousse le ~h~joystick analogique droit ~w~ vers le haut pour ~h~accélérer.
-[WANT_G]
-Quand tu te fais ~h~choper~w~, tu es amené au poste de police le plus proche.
+[HELP5_D]
+Tire le ~h~joystick analogique droit~w~ vers toi pour ~h~freiner~w~ ou pour ~h~reculer~w~ si le véhicule est à l'arrêt.
-[WANT_H]
-Les flics se laisseront corrompre contre tes armes et une partie de ton oseille.
+[HELP7_A]
+Maintiens la ~h~ ~k~~PED_LOCK_TARGET~ ~w~ enfoncée pour ~h~viser~w~ avec le fusil à lunette.
-[WANT_I]
-Toute mission en cours sera automatiquement un échec.
+[HELP7_D]
+Maintiens la ~h~ ~k~~PED_LOCK_TARGET~ ~w~ enfoncée pour ~h~viser~w~ avec le fusil à lunette.
-[WANT_J]
-Plus tu joueras, plus tu trouveras de moyens de diminuer ton indice de recherche.
+[HELP10]
+Ce badge t'indique que t'es recherché par la police.
-[WANT_K]
-En voiture, les ~h~ateliers de peinture~w~ te permettront d'~h~enrayer ton indice de recherche.
+[HELP11]
+Plus t'as de badges, plus ton indice de recherche est important.
-[HEAL_B]
-Quand tu es ~h~H.S.~w~, t'es amené à l'hosto le plus proche.
+[HELP13]
+Tu as parfois intérêt à emprunter des chemins non indiqués sur le radar.
-[HEAL_C]
-On te confisque alors toute ton artillerie et les toubibs te pompent ton flouze pour recoller les bouts.
+[TIMER]
+Cette mission est en temps limité. Tu dois donc la réussir avant que le compteur n'atteigne zéro.
-[HEAL_E]
-En jouant, tu trouveras d'autres moyens de te soigner ou de te protéger.
+[HORN]
+~g~Klaxonne!
-[DAM]
-DEGATS :
+[NOMONEY]
+~g~T'as pas assez de cash!
-[KILLS]
-VICTIMES :
+[REWARD]
+RECOMPENSE $~1~
-[FARES]
-FRAIS :
+[M_FAIL]
+ECHEC DE LA MISSION!
-[BULL]
-FRIC :
+[M_PASS]
+MISSION ACCOMPLIE! $~1~
-[EVID]
-PREUVES :
+[DEAD]
+T'ES MORT!
-[HEALTH]
-ETAT DU VEHICULE :
+[BUSTED]
+CHOPE!
-[COLLECT]
-RECUPERE :
+[WEATHE1]
+TEMPS ENSOLEILLE
-[BOMB]
-Conduis ton véhicule chez l'artificier et piège-le avec une ~h~bombe~w~. Coût - ~h~1.000 dollars.
+[WEATHE2]
+TEMPS TRES ENSOLEILLE
-[SAVE1]
-Franchis la porte pour ~h~sauvegarder la partie~w~. Tu ne peux pas sauvegarder en cours de mission.
+[WEATHE3]
+TEMPS NUAGEUX
-[SAVE2]
-Tout véhicule laissé dans ce garage sera enregistré lors de la sauvegarde.
+[WEATHE4]
+TEMPS PLUVIEUX
-[AMMU]
-Va chez Ma-Gnum pour acheter une arme.
+[WEATHE5]
+TEMPS BRUMEUX
-[BRIDGE1]
-Quand le pont Callahan sera réparé, tu pourras te rendre à l'île Staunton .
+[WEATHE6]
+TEMPS NORMAL
-[TUNNEL]
-Quand le tunnel Porter aura réouvert, tu pourras te rendre à l'île Staunton .
+[NUMBER]
+~1~
-[LUIGI]
-MISSIONS DE LUIGI
+[LOADCAR]
+CHARGEMENT DU VEHICULE... (APPUIE SUR F1 POUR ANNULER)
-[TONI]
-MISSIONS DE TONI
+[CARSOFF]
+Trafic désactivé.
-[JOEY]
-MISSIONS DE JOEY
+[CARS_ON]
+Trafic activé.
-[FRANK]
-MISSIONS DE SALVATORE
+[TEXTXYZ]
+Ecriture des coordonnées sur le fichier...
-[DIABLO]
-MISSIONS DE DIABLO
+[CHEATON]
+Mode triche activé
-[ASUKA]
-MISSIONS D'ASUKA
+[CHEATOF]
+Mode triche désactivé
-[B_SITE]
-MISSIONS DE BANLIEUE D'ASUKA
+[IMPORT1]
+Va dehors et attends ton véhicule.
-[KENJI]
-MISSIONS DE KENJI
+[PAGEB11]
+Lance-flammes livré à la planque
-[RAY]
-MISSIONS DE RAY
+[WANT_A]
+Tu ne seras arrêté que si tu as un ~h~indice de recherche.
-[LOVE]
-MISSIONS DE LOVE
+[WANT_B]
+La rangée d'étoiles dans le coin supérieur droit de l'écran symbolise ton ~h~indice de recherche~w~.
-[YARDIE]
-MISSIONS DE YARDIE
+[WANT_C]
+Ton ~h~indice de recherche~w~ est désormais de un...
-[HOOD]
-MISSIONS DE HOOD
+[WANT_D]
+deux...
-[CITYZON]
-Liberty City
+[WANT_E]
+trois...
-[IND_ZON]
-Portland
+[WANT_F]
+Plus ton ~h~indice de recherche~w~ augmente, plus les forces de l'ordre t'en veulent.
-[PORT_W]
-Point Callahan
+[WANT_G]
+Quand tu es ~h~'chopé'~w~, tu es amené au poste de police le plus proche.
-[PORT_S]
-Atlantic Quays
+[WANT_H]
+Les flics se laisseront corrompre contre toutes tes armes et une partie de ton cash.
-[PORT_E]
-Port de Portland
+[WANT_I]
+Toutes les missions en cours échoueront.
-[PORT_I]
-Trenton
+[WANT_J]
+Plus tu joueras, plus tu trouveras de moyens de diminuer ton indice de recherche.
-[S_VIEW]
-Vue de Portland
+[WANT_K]
+En voiture, les ~h~ATELIERS DE PEINTURE~w~ te permettront d'effacer ton indice de recherche.
-[CHINA]
-Chinatown
+[HEAL_B]
+Quand tu es ~h~'H.S'~w~, t'es amené à l'hôpital le plus proche.
-[EASTBAY]
-Plage de Portland
+[HEAL_C]
+On te confisque alors toute ton artillerie et les docteurs prennent ton argent pour te remettre en forme.
-[LITTLEI]
-Saint Mark's
+[HEAL_E]
+En jouant, tu trouveras d'autres moyens de te soigner ou de te protéger.
-[REDLIGH]
-Le Quartier Rouge
+[SAVE1]
+Entre dans la corona pour ~h~sauvegarder la partie~w~. Tu ne peux pas sauvegarder en cours de mission.
-[TOWERS]
-Hauteurs de Hepburn
+[SAVE2]
+Tout véhicule laissé dans ce garage sera enregistré lors de la sauvegarde.
-[HARWOOD]
-Harwood
+[AMMU]
+Va chez Ammu-Nation pour acheter une arme.
-[ROADBR1]
-Pont Callahan
+[R_TIME]
+TEMPS DE COURSE :
-[ROADBR2]
-Pont Callahan
+[PROP_1]
+Tu n'as pas assez de cash pour acheter cette propriété
-[TUNNELP]
-Tunnel Porter
+[PROP_2]
+Tu ne peux pas acheter une propriété en cours de mission
-[BOMB1]
-Garage de 8-Ball
+[IND_ZON]
+Vice City Beach
[COM_ZON]
-Ile de Staunton
-
-[STADIUM]
-Aspatria
-
-[HOSPI_2]
-Rockford
-
-[UNIVERS]
-Campus Liberty
-
-[CONSTRU]
-Fort Staunton
-
-[PARK]
-Parc Belleville
-
-[COM_EAS]
-Newport
-
-[SHOPING]
-Point Bedford
-
-[YAKUSA]
-Torrington
-
-[SUB_ZON]
-Vallée Shoreside
-
-[AIRPORT]
-Aéroport intl. Francis
-
-[PROJECT]
-Jardins Wichita
-
-[SUB_IND]
-Crique de Pike
+Partie centrale de Vice City
-[SWANKS]
-Bosquet Cedar
+[BEACH1]
+Ocean Beach
-[BIG_DAM]
-Ecluse Cochrane
+[BEACH2]
+Washington Beach
-[SUB_ZO2]
-Vallée Shoreside
+[BEACH3]
+Vice Point
-[SUB_ZO3]
-Vallée Shoreside
+[GOLFC]
+Leaf Links
-[CAR_1]
-Ambulance
-
-[CAR_2]
-Camion de pompier
-
-[CAR_3]
-Voiture de police
-
-[CAR_4]
-Enforcer
-
-[CAR_5]
-Barraquements
-
-[CAR_6]
-Rhino
-
-[CAR_7]
-Voiture du FBI
-
-[CAR_8]
-Sécuricar
-
-[CAR_9]
-Moonbeam
-
-[CAR_10]
-Autobus
-
-[CAR_11]
-Camion
-
-[CAR_12]
-Linerunner
-
-[CAR_13]
-Camion-poubelle
+[STARI]
+Starfish Island
-[CAR_14]
-Patriot
+[DOCKS]
+Port de Vice
-[CAR_15]
-M. Whoopee
+[HAVANA]
+Little Havana
-[CAR_16]
-Mule
+[HAITI]
+Little Haiti
-[CAR_17]
-Yankee
+[PORNI]
+Prawn Island
-[CAR_18]
-Pony
+[DTOWN]
+Centre
-[CAR_19]
-Bobcat
+[VICE_C]
+Vice City
-[CAR_20]
-Rumpo
+[A_PORT]
+Aéroport Escobar
-[CAR_21]
-Blista
+[JUNKY]
+Décharge
-[CAR_22]
-Dodo
+[PISTOL]
+Pistolet
-[CAR_23]
-Bus
+[PYTHON]
+.357
-[CAR_24]
-Sentinelle
+[UZI]
+Uz-1
-[CAR_25]
-Guépard
+[TEC9]
+Tec 9
-[CAR_26]
-Banshee
+[M4]
+M4
-[CAR_27]
-Stinger
+[INGRAM]
+Mac
-[CAR_28]
-Infernus
+[MP5]
+MP
-[CAR_29]
-Esperanto
+[RUGER]
+Kruger
-[CAR_30]
-Kuruma
+[SNIPE]
+Fusil à lunette
-[CAR_31]
-Stretch
+[GRENADE]
+Grenades
-[CAR_32]
-Perennial
+[SHOTGN1]
+Fusil à pompe
-[CAR_33]
-Tout-terrain
+[SHOTGN2]
+S.P.A.S. 12
-[CAR_34]
-Manana
+[SHOTGN3]
+Fusil à pompe Stubby
-[CAR_35]
-Idaho
-
-[CAR_36]
-Etalon
+[ARMOUR]
+Gilet pare-balles
-[CAR_37]
-Taxi
+[LASER]
+.308 Lunette
-[CAR_38]
-Tacot
+[BASEBAT]
+Batte de baseball
-[CAR_39]
-Buggy
+[HAMMER]
+Marteau
-[LUIGIS]
-Chez Luigi
+[SCREWD]
+Tournevis
-[GOAWAY]
-~g~T'es déjà en mission, imbécile!
+[CLEVER]
+Couperet
-[LUIGGO]
-~g~Luigi fait passer un entretien à de nouvelles filles. Reviens plus tard!
+[MACHETE]
+Machette
-[JOEYGO]
-~g~Joey est en ville avec Misty. Repasse plus tard!
+[KNIFE]
+Couteau
-[TONIGO]
-~g~Toni a emmené sa mère à l'opéra. Rappelle plus tard!
+[KATANA]
+Katana
-[KEMUGO]
-~g~Maria et Kenuri sont occupés. Reviens un peu plus tard!
+[CHAINSA]
+Tronçonneuse
-[KENJGO]
-~g~Kenji est à un congrès de Yakuzas. Repasse plus tard.
+[G_COST]
+$~1~
-[RAYGO]
-Ray a autre chose à faire que de voir ta tronche. Va faire un tour!
+[CAR_1]
+Ambulance
-[LOVEGO]
-~g~Donald Love a d'autres chats à fouetter. Prends rendez-vous la prochaine fois!
+[MALIBU]
+Malibu Club
-[KENSGO]
-~g~Kenji est occupé. Repasse à un autre moment.
+[MANSION]
+La résidence de Diaz
-[ASUSGO]
-~g~Asuka n'est pas dispo pour l'instant.
+[TMANS]
+Chez Tommy
-[HOODGO]
-~g~Les Hoods ne sont pas là pour le moment.
+[STRIP]
+'Pole Position Club'
-[WRONGT1]
-~g~Repasse entre 05:00 et 21:00 pour du boulot.
+[MALL1]
+Centre commercial de North Point
-[WRONGT2]
-~g~Repasse entre 06:00 et 14:00 pour du taf.
+[BANKINT]
+El Banco Corrupto Grande
-[WRONGT3]
-~g~Ramène ta fraise entre 15:00 et 00:00 pour bosser.
+[RANGE]
+Champ de tir
-[GUN_1A]
-Sers-toi de la ~h~touche ~k~~PED_CYCLE_WEAPON_RIGHT~~w~ et de la ~h~touche ~k~~PED_CYCLE_WEAPON_LEFT~~w~ pour faire défiler tes armes.
+[POL_HQ]
+QG de Vice City Police
-[GUN_2A]
-Maintiens la ~h~touche ~k~~PED_LOCK_TARGET~~w~ enfoncée pour ~h~viser automatiquement~w~ tes ennemis et appuie sur la ~h~touche ~k~~PED_FIREWEAPON~~w~ pour tirer. Entraîne-toi sur les cibles...
+[INT_B]
+Un vieil ami
-[GUN_2C]
-Maintiens la ~h~touche ~k~~PED_LOCK_TARGET~~w~ enfoncée pour ~h~viser automatiquement~w~ tes ennemis et appuie sur la ~h~touche ~k~~PED_FIREWEAPON~~w~ pour tirer. Entraîne-toi sur les cibles...
+[INTB_1]
+~g~Va au bureau de l'avocat.
-[GUN_2D]
-Maintiens la ~h~touche ~k~~PED_LOCK_TARGET~~w~ enfoncée pour ~h~viser automatiquement~w~ tes ennemis et appuie sur la ~h~touche ~k~~PED_FIREWEAPON~~w~ pour tirer. Entraîne-toi sur les cibles...
+[LAW_1]
+La Fête
-[GUN_3A]
-Tout en appuyant sur la ~h~touche ~k~~PED_LOCK_TARGET~~w~, appuie sur la ~h~touche ~k~~PED_CYCLE_TARGET_LEFT~~w~ ou la ~h~touche ~k~~PED_CYCLE_TARGET_RIGHT~~w~ pour changer de cible.
+[LAW_2]
+Baston de Rue
-[GUN_3B]
-Tout en appuyant sur la ~h~touche ~k~~PED_LOCK_TARGET~~w~, appuie sur la ~h~touche ~k~~PED_CYCLE_TARGET_LEFT~~w~ ou la ~h~touche ~k~~PED_CYCLE_TARGET_RIGHT~~w~ pour changer de cible.
+[LAW_3]
+Jury sous pression
-[GUN_4A]
-Tu peux marcher ou courir tout en gardant la ~h~touche ~k~~PED_LOCK_TARGET~~w~ enfoncée afin de verrouiller une cible.
+[LAW_4]
+Emeute
-[GUN_4B]
-Tu peux marcher ou courir tout en gardant la ~h~touche ~k~~PED_LOCK_TARGET~~w~ enfoncée afin de verrouiller une cible.
+[COL_1]
+Salaud de traître
-[GUN_5]
-Tu peux t'entraîner à cibler et tirer sur ces cibles en papier. Quand tu as finis, reprends ta mission.
+[COL_2]
+Fusillade
-[TAXI1]
-~g~Cherche une course.
+[COL_3]
+Anges gardiens
-[FARE1]
-~g~Destination : ~w~Le 'Club Sex Meeouch'~g~ dans Le Quartier Rouge.
+[COL_4]
+Chef, oui, chef !
-[FARE2]
-~g~Destination : ~w~'Pribas'~g~ au Belvédère de Portland.
+[COL_5]
+Sur le Pont
-[FARE3]
-~g~Destination : ~w~la 'Vieille Ecole'~g~ à Chinatown.
+[COK_1]
+Course poursuite
-[FARE4]
-~g~Destination : ~w~le 'Cafe greasy Joes' ~g~au Point Callahan.
+[COK_2]
+Phnom Penh '86
-[FARE5]
-~g~Destination : ~w~'AmmuNation'~g~ dans Le Quartier Rouge.
+[COK_3]
+Speedboat
-[FARE6]
-~g~Destination : ~w~'Caisses à crédit'~g~ à Saint Mark's.
+[COK_4]
+Offre & demande
-[FARE7]
-~g~Destination : ~w~le 'Woody's topless bar' ~g~ dans le Quartier Rouge.
+[KENT_1]
+Couloir de la mort
-[FARE8]
-~g~Destination : ~w~le 'Bistro de Marco'~g~ à Saint Mark's.
+[ASS_1]
+Liquidation
-[FARE9]
-~g~Destination : ~w~le 'Garage import export' ~g~au Port de Portland.
+[BUD_1]
+EXTORSION
-[FARE10]
-~g~Destination : ~w~'Têtes de Punk' ~g~ à Chinatown.
+[BUD_2]
+Rixe de Bar
-[FARE12]
-~g~Destination : ~w~le 'Stade de Football'~g~ à Aspatria.
+[BUD_3]
+CopLand
-[FARE13]
-~g~Destination : ~w~'L'église'~g~ au Point Bedford.
+[CAP_1]
+L'encaisseur
-[FARE14]
-~g~Destination : ~w~'Le Casino'~g~ à Torrington.
+[FIN_1]
+Amis proches
-[FARE15]
-~g~Destination : ~w~'Université de Liberty'~g~ au Campus Liberty.
+[BANK_1]
+Sans Issue
-[FARE16]
-~g~Destination : ~w~le 'Centre commercial~g~ dans le coin du Parc Belleville.
+[BANK_2]
+Le Flingueur
-[FARE17]
-~g~Destination : ~w~le 'Musée'~g~ de Newport
+[BANK_3]
+Le Chauffeur
-[FARE18]
-~g~Destination : ~w~le 'Bâtiment Am'~g~ de Torrington.
+[BANK_4]
+Hold-up
-[FARE19]
-~g~Destination : ~w~'Burgers bourgeois'~g~ à Point Bedford.
+[CNT_1]
+La Mèche est vendue
-[FARE20]
-~g~Destination : ~w~'Le parc'~g~ à Belleville.
+[CNT_2]
+Halte au Messager
-[FARE21]
-~g~Destination : ~w~'Aéroport internationnal Francis'~g~.
+[PORN_1]
+Bout d'essai
-[FARE22]
-~g~Destination : ~w~'l'écluse de Cochrane'~g~.
+[PORN_2]
+Dodo Vibro
-[FARE24]
-~g~Destination : ~w~'L'hôpital'~g~ de la Crique Pike.
+[PORN_3]
+Martha
-[FARE25]
-~g~Destination : ~w~le 'Parc'~g~ à la vallée Shoreside.
+[PORN_4]
+Projecteur-G
-[FARE26]
-~g~Destination : ~w~les 'Tours North West'~g~ des jardins Wichita.
+[TAX_1]
+Taxis Kaufman
-[NEW_TAX]
-PLUS GROS! PLUS RAPIDES! PLUS SOLIDES! Les taxis Borgnine s'installent à Harwood. Contactez-les dès aujourd'hui au 555-Borgnine!
+[TAXI_1]
+V.I.P.
-[TSCORE2]
-~1~$
+[TAXI_2]
+Concurrence Amicale
-[IN_ROW]
-~1~ DE SUITE! Bonus : ~1~$
+[TAXI_3]
+Cabmaggedon
-[TTUTOR]
-Appuie sur la ~h~touche ~k~~TOGGLE_SUBMISSIONS~~w~ pour activer ou désactiver l'affichage des missions taxi.
+[ICE_1]
+Distribution
-[TTUTOR2]
-Appuie sur la ~h~touche ~k~~TOGGLE_SUBMISSIONS~~w~ pour activer ou désactiver l'affichage des missions taxi.
+[TEX_1]
+Quatre fers
-[ATUTOR2]
-~g~Conduis les patients à l'hôpital. DOUCEMENT. Chaque secousse réduit leurs chances de survie.
+[TEX_2]
+Funérailles
-[A_TIME]
-+~1~ secondes.
+[TEX_3]
+Demolition Man
-[A_FULL]
-~r~Ambulance pleine!
+[PHIL_1]
+Trafiquant d'armes
-[A_RANGE]
-~g~La radio de l'ambulance ne capte plus rien. Rapproche-toi d'un hôpital!
+[PHIL_2]
+Boomshine Saigon
-[FTUTOR]
-Appuie sur la ~h~touche ~k~~TOGGLE_SUBMISSIONS~~w~ pour activer ou désactiver les missions camion de pompier.
+[BIKE_1]
+Alliage d'Acier
-[FTUTOR2]
-Appuie sur la ~h~touche ~k~~TOGGLE_SUBMISSIONS~~w~ pour activer ou désactiver les missions camion de pompier.
+[BIKE_2]
+Colère
-[F_PASS1]
-Feu éteint!
+[BIKE_3]
+Bécane
-[F_RANGE]
-~g~La radio du camion de pompier ne capte plus rien. Rapproche-toi d'une caserne de pompiers!
+[ROCK_1]
+Love Juice
-[C_BREIF]
-~g~Suspect aperçu pour la dernière fois dans le secteur : ~a~.
+[ROCK_2]
+Psychopathe
-[C_RANGE]
-~g~La radio de la voiture de police ne capte plus rien. Rapproche-toi d'un poste de police!
+[ROCK_3]
+Promo
-[DODO_FT]
-Tu as 'volé' pendant ~1~ secondes!
+[ROCK_4]
+Les Love Fist!
-[EBAL_A]
-Je connais un coin dans Le Quartier Rouge où on pourra se planquer,
+[HAT_1]
+Juju
-[EBAL_A1]
-faut que tu prennes le volant, mes mains tremblent trop.
+[HAT_2]
+Bombes!
-[EBAL_1]
-Appuie sur la ~h~touche ~k~~VEHICLE_ENTER_EXIT~~w~ pour ~h~monter~w~ ou ~h~sortir~w~ d'un véhicule.
+[HAT_3]
+Raclée
-[EBAL_1B]
-Appuie sur la ~h~touche ~k~~VEHICLE_ENTER_EXIT~~w~ pour ~h~monter~w~ ou ~h~sortir~w~ d'un véhicule.
+[CUB_1]
+Cascades aquatiques
-[EBAL_2]
-~g~Remonte dans la bagnole!
+[CUB_2]
+Chair à Canon
-[EBAL_3]
-C'est le ~h~radar~w~. Utilise-le pour te repérer dans la ville, et suis le ~h~symbole~w~ sur le ~h~radar~w~ pour trouver la planque!
+[CUB_3]
+Bataille Navale
-[EBAL_D]
-Je connais un mec qu'a des relations. Il s'appelle Luigi.
+[CUB_4]
+Vaudou
-[EBAL_D1]
-On est pote, alors il pourra certainement te trouver du boulot. Viens, on y va.
+[JOB_1]
+Accident de la route
-[EBAL_E]
-Allez, viens, on va y faire un tour, histoire de te présenter.
+[JOB_2]
+Bute la femme!
-[EBAL_I]
-Le patron viendra bientôt vous voir...
+[JOB_3]
+Autocide
-[EBAL_J]
-8-Ball a des trucs à faire en haut.
+[JOB_4]
+Enregistrement
-[EBAL_K]
-Tu peux peut-être me rendre un service.
+[JOB_5]
+Détails
-[EBAL_L]
-Une de mes filles a besoin d'un taxi. Tire une bagnole et va chercher Misty à la clinique. Ensuite, ramène-la ici.
+[ANSWER]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~~w~ pour répondre au téléphone.
-[EBAL_N]
-Et garde bien tes mains sur le volant, compris ?
+[MOB_01A]
+Comment ça va, mon pote? C'est Paul! J'ai peut-être quelque chose d'intéressant pour toi, mais faut que je te parle en personne.
-[EBAL_4]
-~r~8-Ball est mort!
+[MOB_01B]
+Je suis en train de me la couler douce au Malibu.
-[EBAL_5]
-~g~Prenez une caisse!
+[MOB_01C]
+Tu me devras un ou deux petits services en échange, mon mignon. A tout à l'heure...
-[EBAL_6]
-~g~Va chercher Misty!
+[MOB_02A]
+Sniiiiiiiiiiiif! Hé, salut, Tommy! Tommy?
-[LM1]
-'LES FILLES DE LUIGI'
+[MOB_02B]
+On a un problème à l'imprimerie. Tu ferais mieux d'aller y jeter un coup d'oeil.
-[LM2]
-'PAS DE SPANK POUR LA PEPEE'
+[MOB_02C]
+Quelque chose a merdé. C'est le bordel. Faut que j'te laisse.
-[LM3]
-'LA MYSTERIEUSE MISTY'
+[MOB_03A]
+Mr Vercetti? J'ai ici un document signé qui établit formellement
-[LM5]
-'LE BAL A BALLES'
+[MOB_03B]
+que vous avez racheté toutes les dettes de BJ's Auto.
-[LM1_2]
-~g~Emmène Misty au club de Luigi.
+[MOB_03C]
+La disparition soudaine de BJ ne me laisse pas d'autre choix
-[LM1_3]
-~g~Klaxonne pour faire monter la fille.
+[MOB_03D]
+que de vous tenir pour responsable du passif de cette société.
-[LM1_6]
-~g~Rentre dans la caisse!
+[MOB_03E]
+Jusqu'à ce que ce compte soit complètement soldé
-[LM1_7]
-Arrête la bagnole près de Misty et laisse-la monter à bord.
+[MOB_03F]
+vous devriez considérer les rues de Vice City comme très dangereuses.
-[LM1_8]
-Tu peux retourner voir Luigi pour le boulot, ou visiter Liberty City.
+[MOB_04A]
+Comment va, vieille branche?
-[LM2_A]
-Y'a une nouvelle saloperie sur le marché. Ca s'appelle la SPANK.
+[MOB_04B]
+Ecoute, Tommy, j'avais oublié de te dire qu'on va avoir besoin de balaises en plus pour le concert.
-[LM2_E]
-Un petit malin fourgue cette merde à mes filles du Port de Portland.
+[MOB_04C]
+Y'a un gang de motards dirigé par Mitch Baker, ça nous ferai une super publicité. Vraiment Rock'n'roll, Baby.
-[LM2_B]
-Va lui foutre une raclée!
+[MOB_04D]
+Règle ça pour moi et je te laisserai accéder aux coulisses du concert, d'accord?
-[LM2_G]
-Je me vengerai!
+[MOB_05A]
+Bien joué, Tommy, j'suis content d'avoir récupéré ma bécane.
-[LM2_1]
-~g~Pique sa caisse et fais-la repeindre.
+[MOB_05B]
+Dis à Mr Kent Paul que la sécurité sera assurée pour le concert.
-[LM2_2A]
-Sers-toi de la ~h~touche ~k~~PED_FIREWEAPON~~w~ pour ~h~donner un coup de poing~w~, ~h~un coup de pied~w~ ou un ~h~coup de batte~w~.
+[MOB_05C]
+Tu as ma parole.
-[LM2_2C]
-Sers-toi de la ~h~touche ~k~~PED_FIREWEAPON~~w~ pour ~h~donner un coup de poing~w~, ~h~un coup de pied~w~ ou un ~h~coup de batte~w~.
+[MOB_05D]
+Bon, maintenant, évite de t'attirer des emmerdes.
-[LM2_2D]
-Sers-toi de la ~h~touche ~k~~PED_FIREWEAPON~~w~ pour ~h~donner un coup de poing~w~, ~h~un coup de pied~w~ ou un ~h~coup de batte~w~.
+[MOB_06A]
+Tommy! Ceux d'en bas, ils parlent de toi, mon petit...
-[LM2_3]
-~g~Planque la bagnole dans le garage de Luigi!
+[MOB_06B]
+Je me disais que tu te laisserais peut-être tenter par un doux foyer et par une soupe au gombo de tata Poulet? Mmm?
-[LM2_4]
-~g~Repeins la bagnole!
+[MOB_06C]
+Fais un saut par ma cuisine un de ces jours, hein, Tommy?
-[LM3_A]
-Hé, faut que je te cause... OK, Mick, je te parle plus tard.
+[MOB_08A]
+Salut, Tommy, je me disais que t'aurais peut-être besoin d'un conseil en affaires...
-[LM3_B]
-Comment ça va, gamin ?
+[MOB_08B]
+Dès que tu as une opération en route, il faut que tu passes prendre le fric de la semaine.
-[LM3_C]
-Le fils du Don, Joey Leone, il veut voir sa régulière, Misty.
+[MOB_08C]
+Si tu laisses les mecs penser que ce sont eux qui dirigent l'affaire, ils essayent de ronger tes bénefs! Ok?
-[LM3_D]
-Va la chercher à Hauteurs de Hepburn...
+[MOB_08D]
+Ca va, Ken, je connais le business...
-[LM3_E]
-Mais fais gaffe, c'est le territoire de Diablo.
+[MOB_08E]
+Ok, ok, je sais que tu sais. Je sais. C'était...
-[LM3_F]
-Amène-la ensuite au garage de joey, à Trenton et vite!
+[MOB_08F]
+C'était juste pour te dire que je sais que tu sais que je sais...
-[LM3_H]
-Donc tes yeux, ils regardent la route et pas Misty, ok ?
+[MOB_08G]
+Ouvre simplement l'oeil!
-[LM3_1D]
-Appuie sur la ~h~touche L3~w~ pour ~h~klaxonner~w~ et indiquer à Misty que tu es là.
+[MOB_08H]
+T'inquiète, Ken, t'inquiète...
-[LM3_2]
-~g~Emmène Misty chez Joey!
+[MOB_09A]
+Salut, Léo! J'ai du boulot pour toi!
-[LM3_4]
-~g~Va chercher Misty!
+[MOB_09B]
+C'est pas Léo.
-[LM3_5]
-Tu bosses pour Luigi, hein ? Il était temps qu'il se trouve un chauffeur digne de confiance.
+[MOB_09C]
+Si Léo apprend que t'as son téléphone, il va te buter aussi sec!
-[LM3_7]
-Je suis à toi dans une minute, poupée.
+[MOB_09D]
+Peut-être que Léo est mort. Peut-être même que c'est moi qui l'ai buté et que j'ai hérité de son téléphone. T'avais pas pensé à ça hein, connard?
-[LM3_10]
-~g~Trouve une caisse!
+[MOB_09E]
+T'as buté Léo? Alors, c'est que t'en as dans le froc! Tu veux bosser pour moi?
-[LM4_B]
-Va t'occuper de cette affaire pour moi.
+[MOB_09F]
+Passe au café de mon père dans Little Havana et on pourra causer entre hommes.
-[LM4_C]
-Si t'as besoin d'un calibre, va derrière Ammu-Nation en face du métro.
+[MOB_10A]
+Tommy! Ecoute, j'ai un service à te demander!
-[LM5_A]
-Le Bal de la police a lieu dans la vieille école près du Pont de Callahan.
+[MOB_10B]
+Steve! Comment ça marche, le cinoche?
-[LM5_B]
-Alors les flics auront besoin d'action à l'ancienne!
+[MOB_10C]
+Ca va, ça va. Mais on a besoin d'une scène de poursuite en bagnole et on a pas le budget pour ça.
-[LM5_C]
-J'ai des filles partout dans les rues.
+[MOB_10D]
+J'ai laissé des bagnoles dans les environs. Tu sauras quoi faire.
-[LM5_D]
-Emmène-les au bal, histoire de faire d'une pierre deux coups : profit et détente!
+[MOB_10E]
+OK, Steve, je vais voir ce que je peux faire. A plus tard.
-[LM5_1]
-~g~Si tu les serres trop, elles vont avoir des bleus! ~g~Livre d'abord celles-la et reviens en chercher d'autres.
+[MOB_11A]
+Salut petit, je me suis dit que j'allais te passer un coup de fil pour te donner un bon conseil.
-[LM5_2]
-~r~L'une des filles de Luigi est bonne pour la morgue!
+[MOB_11B]
+Salut Avery, qu'est-ce que tu voulais me dire?
-[LM5_3]
-~g~T'as besoin d'un véhicule!
+[MOB_11C]
+Les perspectives ne manquent pas dans cette ville, si tu possèdes le bon business... Tu vois ce que je veux dire?
-[LM5_4]
-~g~Va ramasser les filles qui tapinent à St. Mark's.
+[MOB_11D]
+Je pense que oui...
-[LM5_5]
-~g~Emmène les filles au bal!
+[MOB_11E]
+Je te conseille d'ouvrir l'oeil, et le bon, si tu veux dégotter un bon business. A plus tard.
-[LM5_8]
-~g~Filles au bal : ~1~
+[MOB_11F]
+Ciao, Avery.
-[JM2]
-'AU REVOIR LEE'
+[MOB12_A]
+Tommy! C'est Avery! Ecoute, je suis débordé de boulot pour le moment,
-[JM4]
-'LE CHAUFFEUR DE MONSIEUR'
+[MOB12_B]
+et j'ai un de mes réprésentants qui a besoin d'être chaperonné jusqu'aux Gator Keys.
-[JM5]
-'TRANSPORT DE MARCHANDISES AVARIEES'
+[MOB12_C]
+Je suis sur l'achat d'un terrain là-bas, alors j'envoie un mec graisser quelques pattes.
-[JM1_1]
-~g~Amène la voiture de Forelli au garage de 8-Ball, au nord, derrière 'Caisses à crédit'.
+[MOB12_D]
+J'ai besoin que tu t'assures qu'il arrive bien là-bas. OK?
-[JM1_2]
-~g~Ramène la bagnole au Bistro de Marco.
+[MOB12_E]
+OK, pas de problème, Avery! Mais où c'est que je le trouve, ce mec?
-[JM1_3]
-~g~Arme la bombe et CASSE-TOI EN VITESSE!
+[MOB12_F]
+Il boucle une affaire au chantier. Je lui ai dit que tu le prendrais là-bas.
-[JM1_4]
-~g~T'as bousillé la caisse! Fais-la réparer!
+[MOB12_G]
+Ok, Avery. J'y vais. A plus tard.
-[JM1_5]
-~g~T'as pas armé la bombe!
+[MOB13_A]
+Vercetti? VERCETTI! Putain, mec, faut que tu me files un coup de main!
-[JM1_6]
-~g~Gare la bagnole correctement!
+[MOB13_B]
+Mr Moffat? Comment va la famille?
-[JM1_8A]
-~y~Hé, c'est mon gars préféré!
+[MOB13_C]
+Merde, mais quel con! Tu m'entends?
-[JM1_8B]
-~y~Chez l'artifier, tout est automatique. T'amènes la voiture, tu la gares, et le reste se fait tout seul!
+[MOB13_D]
+Ca m'a fait plaisir d'avoir des nouvelles...
-[JM1_8C]
-~y~Viens, le premier est gratuit, mais juste le premier, compris ?
+[MOB13_E]
+Attends! Attends! Vercetti, euh... Tommy. Je peux t'appeler Tommy?
-[JM2_A]
-Chunky Lee Chong fout la merde avec la Spank pour un nouveau gang de Colombie... ou du Colorado... un coin comme ça...
+[MOB13_F]
+On est tous les deux dans les affaires, pas vrai? Et tu sais renifler les bonnes, hein?
-[JM2_B]
-J'en sais rien. On s'en fout, après tout.
+[MOB13_G]
+J'ai pas le temps de causer, viens-en au fait!
-[JM2_D]
-Il a dépassé les bornes!
+[MOB13_H]
+Du FRIC! Voilà le putain de fait!
-[JM2_E]
-Il faut lui régler son compte!
+[MOB13_I]
+Je me suis encore tiré de taule, mais ça prend jamais longtemps avant qu'ils me retombent dessus. Pour eux, c'est qu'un putain de jeu!
-[JM2_G]
-Débrouille-toi avec un 9 mm, tu sais où il se trouve, non ?
+[MOB13_J]
+Je t'appelle d'une cabine quelque part dans le trou du cul du monde!
-[JM2_H]
-Et souviens-toi : fais gaffe à Chinatown, c'est le territoire de la Triade.
+[MOB13_K]
+Sors-moi de là avant qu'ils me chopent encore et... et... ah... meeeerde...
-[JM3_A]
-Bon, on va s'attaquer à un fourgon blindé.
+[MOB13_L]
+Eh bien, c'est que je suis très occupé pour les prochaines-
-[JM3_B]
-Il part de Chinatown tous les jours.
+[MOB13_M]
+Non! Me laisse pas dans cette merde! T'as pas de coeur ou quoi? Putain, j'devrais pas avoir à m'abaisser comme ça!
-[JM3_C]
-Les balles traverseront pas son blindage, alors vole une caisse et rentre-lui dedans.
+[MOB13_N]
+Je suis à genoux, Tommy! Et c'est les rotules dans la poussière que je te supplie...
-[JM3_D]
-Cogne bien fort et les larbins de sécurité devraient pas demander leur reste!
+[MOB13_O]
+J'imagine que je pourrais passer dans le coin et voir si je te trouve...
-[JM3_E]
-Ensuite, t'emmènes le fourgon à l'entrepôt des docks et mes gars prennent le relais.
+[MOB13_P]
+Oh, merde, les voilà! Putain, magne-toi, Tommy! Vite!
-[JM3_F]
-Mais bon, ils vont pas faire leur ronde toute la journée, alors traîne pas en route!
+[MOB_14A]
+Salut, Tommy, on va bien s'entendre, toi et moi.
-[JM3_1]
-~g~Emmène le fourgon à la planque.
+[MOB_14B]
+Une tendre amie est venu me sussurrer dans l'oreille que la division SWAT de Vice City a un coffre dans une grosse banque,
-[JM3_2]
-~g~Fonce dans le fourgon jusqu'à ce que ses dégâts soient inférieurs à 70%.
+[MOB_14C]
+et ils y gardent les pots-de-vin de toutes ces dernières années.
-[JM4_B]
-Hé! C'est le gars dont je te parlais!
+[MOB_14D]
+C'est une sorte de caisse de retraite pour vieux garçons.
-[JM4_C]
-Ok. Ce gars, c'est pas un Italien, c'est pas un mécano, mais il peut réparer les choses.
+[MOB_14E]
+Evidemment, si cette info pouvait t'aider à ramasser un peu de ce pognon,
-[JM4_D]
-C'est Pops Capo, Toni Cipriani.
+[MOB_14F]
+j'imagine que tu te sentirais obligé de m'en refiler un peu, pas vrai, Tommy?
-[JM4_E]
-Ouais, je suis Toni Cipriani.
+[MOB_14G]
+Je vais garder ça à l'esprit, merci, Kent.
-[JM4_F]
-Emmène-le au resto de la Mamma, à St Mark's, ok ?
+[MOB_14H]
+Je m'appelle Paul, abruti! Et je suis du Kent, près de Londres.
-[JM4_G]
-Maintenant, écoute. Je prépare un truc et j'ai besoin d'un bon conducteur. Alors, passe me voir, ok ?
+[MOB_14I]
+Pour ce que j'en ai à foutre de la campagne anglaise, depuis l'école...
-[JM4_2]
-Attends-moi ici. Et laisse tourner le moulin. C'est pas une visite de courtoisie.
+[MOB15_A]
+Tommy, mon vieux, c'est Paul, du Kent.
-[JM4_3]
-Une embuscade de la Triade! Sors-nous d'ici, gamin!
+[MOB15_B]
+Il y a une ou deux authentiques dames qui ont ton nom plein la bouche, au Malibu.
-[JM4_4]
-La Triade pense qu'elle peut s'attaquer à moi! Hum! Tu te rends compte, A MOI!
+[MOB15_C]
+De quoi tu parles?!
-[JM4_6]
-Hé, fais gaffe à la bagnole! J'ai dit pas de lézards!
+[MOB15_D]
+De gonzesses, de poulettes, de filles, quoi! Et bien élevées, pas le genre à causer pognon.
-[JM4_7]
-~g~Emmène Toni au restaurant de la Mamma.
+[MOB15_E]
+Faut que tu viennes voir ça.
-[JM4_8]
-~r~Toni sert d'engrais aux chrisantèmes!
+[MOB16_A]
+Tommy, c'est Paulo, que pasa amigo?
-[JM5_A]
-Magnifique! Réellement magnifique!
+[MOB16_B]
+Qu'est-ce que tu m'veux, Paul? J'ai pas besoin de fausses fringues de marque.
-[JM5_B]
-Très bien, c'est l'homme qu'il me fallait!
+[MOB16_C]
+Très drôle, mon vieux, mais je fais pas dans la fringue de tapette, moi.
-[JM5_D]
-Un des Forelli s'est cru un peu trop malin et il en a pris pour son grade!
+[MOB16_D]
+Bon, je t'appelle parce que j'me demande si je ne pourrais pas avoir un rôle dans un de tes films.
-[JM5_E]
-Emmène le corps au broyeur de Harwood, ok ?
+[MOB16_E]
+J'ai fait pas mal de pornos en Angleterre, mon vieux.
-[JM5_1]
-~g~Emmène-le au broyeur!
+[MOB16_F]
+Au plumard, je suis une mitrailleuse lourde.
-[JM5_2]
-~g~C'est les frères Forelli!
+[MOB16_G]
+Merci de me proposer tes services, Paul, j'y réfléchirai.
-[JM6_A]
-Joli morceau, hein?
+[MOB16_H]
+Sérieusement, pense à moi, après tout ce que j'ai fait pour toi...
-[JM6_B]
-Ok, écoute : choisis une caisse dans l'entrepôt de Saint Mark's et va chercher quelques potes à moi.
+[MOB16_I]
+Justement, j'essaie de l'oublier.
-[JM6_C]
-Il font un retrait à la banque et ils ont besoin d'un taxi.
+[MOB17_A]
+Tommy Vercetti, comment ça va, big boss?
-[JM6_D]
-J'ai dit que tu ferais parfaitement l'affaire, alors me déçois pas!
+[MOB17_B]
+J'ai entendu tous ces trucs sur toi. Un flambeur en ville maintenant...
-[JM6_E]
-Amène-les à la banque avant 5 heures, et sois pas en retard!
+[MOB17_C]
+Paul, t'es bourré.
-[JM6_2]
-Laisse le moulin tourner, y'en a pas pour longtemps!
+[MOB17_D]
+Naan! Pauvre abruti! J'suis pas saoul!
-[JM6_3]
-Sors-nous de là!
+[MOB17_E]
+J'ai juste pris un ou deux verres et quelques tournées, et ça fait deux jours que j'ai pas fermé l'oeil!
-[JM6_4]
-Débarrasse-toi des poulets et amène-nous à l'entrepôt!
+[MOB17_F]
+De toute façon, ne me traite pas comme ça.
-[JM6_6]
-~g~Va voler une caisse moins voyante!
+[MOB17_G]
+Je suis pas une poire. Qui c'est qui t'a lancé dans cette ville? Hein, qui? Moi!
-[JM6_7]
-~g~Faut que tu prennes les 3 pour voler la banque!
+[MOB17_H]
+Ah ouais?
-[TM1]
-'LINGE SALE'
+[MOB17_I]
+Ouais!
-[TM2]
-'LA LIVRAISON'
+[MOB17_J]
+Paul, t'énerve pas. J'étais occupé, sois pas stupide.
-[TM3]
-'LA RENCONTRE'
+[MOB17_K]
+Je suis pas stupide, connard! Ils me l'ont dit en maison de redressement!
-[TM4]
-'LE TRIANGLE DES TRIADES'
+[MOB17_L]
+Si tu cherches les emmerdes, mon pote, tu vas les trouver!
-[TM5]
-'LA HUITIEME PLAIE'
+[MOB17_M]
+Tommy, s'il te plaît! T'étais mon grand espoir! Te fous pas de moi!
-[TONI_P]
-J'ai un boulot urgent pour toi!
+[MOB17_N]
+Paul, va roupiller un bon coup, sérieusement.
-[TM1_A]
-~w~Assieds-toi, gamin. Prends une de ces putains de chaises.
+[MOB18_A]
+Tommy, c'est Paulo, comment ça va, mon pote, je me suis dit que j'allais te passer un petit coup de fil.
-[TM1_B]
-~w~Alors, la laverie veut pas payer pour sa protection, hein ?
+[MOB18_B]
+Ah, mon pote, tu croiras jamais l'incroyable petit lot que je viens de lever...
-[TM1_C]
-~w~La Triade pense qu'elle peut se mêler de mes affaires ?
+[MOB18_C]
+Elle se promenait juste en bas dans Little Havana, mon pote.
-[TM1_D]
-~w~On va apprendre à ces faux durs ce que c'est que des vrais hommes!
+[MOB18_D]
+Elle m'a dit qu'elle s'appelait Mercedes ou un truc comme ça. Ah, mon pote, faut que t'ailles voir cette fille!
-[TM1_E]
-~w~Ouais, on va leur apprendre à nous respecter! Aucun de mes gars ne se laisse intimider par une Triade minable!
+[MOB18_E]
+Elle ferait bander un eunuque! Elle m'a dit que j'étais le meilleur coup de sa vie et tout et tout!
-[TM1_F]
-~w~Ton père, qu'il repose en paix, se laissait pas faire par les Triades, à l'époque, en Sicile!
+[MOB18_F]
+Vas-y, trouve-la. A plus tard.
-[TM1_G]
-~w~Pardon Ma. Oui Ma.
+[MOB19_A]
+Tommy V, c'est KP! Kent Paul. Le bruit court que des mecs veulent te faire la peau.
-[TM1_H]
-~w~Je veux que tu détruises les camionnettes de la laverie.
+[MOB19_B]
+Ouvre l'oeil, mon pote. Et oublie pas... Je t'ai rien dit.
-[TM1_I]
-~w~Et roule sur tous les gars de la Triade que tu croiseras.
+[MOB_20A]
+Salut, Tommy, c'est Paul. Je viens juste d'entendre dire que t'avais été un vilain garçon.
-[TM1_J]
-~w~8-Ball te donnera ce dont tu as besoin.
+[MOB_20B]
+Il y a quelqu'un qui s'est vexé de te voir jouer les caïds et ça lui a donné de mauvaises idées...
-[TM2_A]
-~w~Toni est parti en faire saigner plus d'un, ou du moins, il essaie.
+[MOB_20C]
+Bon, dis à personne que je t'ai rencardé. Les grandes gueules finissent toujours par l'avoir dans l'os.
-[TM2_AA]
-Il ne sera jamais aussi fort que son papa. Il t'a laissé un mot sur la table.
+[MOB_20D]
+Enfin, j'ai entendu dire que ta tête a été mise à prix et que quelqu'un va essayer de t'avoir,
-[TM2_B]
-~w~La laverie a accepté de payer. C'est du bon boulot!
+[MOB_20E]
+alors fais gaffe, et m'oublie pas, mon pote.
-[TM2_C]
-~w~Va chercher la thune et ramène-la ici. Et fais gaffe à la Triade.
+[MOB71_A]
+Tommy, Thomas, c'est Cortez. Que pasa?
-[TM2_D]
-~w~C'est comme les roquets : ça aboie, mais ça mord pas!
+[MOB71_B]
+Les affaires tournent... Et toi, comment ça va?
-[TM2_E]
-~w~Personne, je dis bien PERSONNE, ne se mêle des affaires de TONY CIPRIANI!
+[MOB71_C]
+Tommy, ici, c'est toujours la guerre. Excusez la mauvaise ligne, mais on vient juste d'avoir un nouveau coup d'état manqué.
-[TM2_1]
-~g~Apporte le flouze à Toni!
+[MOB71_D]
+Le peuple est la plus exigeante des maîtresses.
-[TM2_2]
-~g~Tu les as tous refroidis!
+[MOB71_E]
+Si je compte bien, y'a eu trois révolutions et quatre coups d'état depuis que je suis rentré de Vice City.
-[TM3_MA]
-~w~Je ne sais pas où il est!
+[MOB71_F]
+Heureusement, à chaque fois, j'ai pris du galon.
-[TM3_MB]
-~w~Ce gamin, des fois, il sait même pas où il se trouve!
+[MOB71_G]
+Je voulais vous demander quelque chose à propos de Mercedes...
-[TM3_MC]
-~w~Son père, c'est sûr, c'était différent. Toujours au top, sûr de lui, viril...
+[MOB71_H]
+Ouais? Quoi?
-[TM3_A]
-~w~Don Salvatore a convoqué une assemblée.
+[MOB71_I]
+Voilà, Tommy, Tommy, j'ai entendu toutes ces histoires et je sais pas quoi penser...
-[TM3_B]
-~w~J'ai besoin de toi pour aller chercher la Stretch et Joey, son fils, au garage.
+[MOB71_J]
+Peut-être que tout le monde essaye de m'humilier...
-[TM3_C]
-~w~Alors va chercher Luigi à son club et reviens ensuite me chercher.
+[MOB71_K]
+Peut-être qu'elle se croit tout permis, mais dites-moi juste la vérité, Tommy, c'est vrai?
-[TM3_D]
-~w~On ira tous ensemble chez le don.
+[MOB71_L]
+Mais dites-moi juste la vérité, Tommy, c'est vrai?
-[TM3_E]
-~w~Ces Triades, elles savent jamais quand s'arrêter.
+[MOB71_M]
+Qu'est-ce qui est vrai?
-[TM3_F]
-~w~Elles veulent la guerre, elles auront la guerre.
+[MOB71_N]
+Ces bruits qui courent... Elle va vraiment devenir avocate?
-[TM3_G]
-~w~Maintenant, faut y aller.
+[MOB71_O]
+Ah, Tommy, c'est une véritable honte! Nous, les Cortez, sommes une honorable famille et nous ne tolèrerons jamais qu'une de nos filles devienne avocate.
-[TM3_1]
-~g~Prends la Stretch chez Joey.
+[MOB71_P]
+Je vous en prie, dites-moi que ce n'est pas vrai, je ne crois pas que je pourrais le supporter.
-[TM3_2]
-~g~Va chercher Luigi.
+[MOB71_Q]
+Colonel, je peux vous assurer que Mercedes ne deviendra jamais avocate. Ne vous inquiètez pas.
-[TM3_3]
-~g~Va chercher Toni.
+[MOB71_R]
+Merci, Tommy, cette honte me serait insupportable. C'est une femme, pas un parasite, vous comprenez.
-[TM3_4]
-~g~Conduis tout le monde chez Salvatore.
+[MOB71_S]
+Je le sais, colonel.
-[TM3_5]
-~y~Une embuscade de la Triade!
+[MOB71_T]
+Bon, vous allez devoir m'excuser, Tommy, mais le nouveau ministre de l'intérieur vient d'arriver...
-[TM4_B]
-~w~Nous sommes en GUERRE! La Triade se sert d'une conserverie de poisson comme façade!
+[MOB71_U]
+Il y a de nombreuses années, j'ai tué son père au cours d'une tentative de coup d'état ratée et je dois me montrer poli. Adios, amigo.
-[TM4_C]
-~w~Ils règlent la majeure partie de leurs affaires au marché aux poissons de Chinatown.
+[MOB22_A]
+Tommy, vous vous révèlez très utile, amigo.
-[TM4_D]
-~w~Cette laverie doit toujours payer son assurance...
+[MOB22_B]
+Merci, Cortez. Et mon affaire?
-[TM4_E]
-~w~Ils pensent que la Triade les protège, donc il faut leur montrer que ce n'est pas le cas.
+[MOB22_C]
+Tommy, je travaille inlassablement en ce sens pour aller au fond des choses et de la vérité dans cette terrible histoire.
-[TM4_F]
-~w~Prends les garçons avec toi pour éliminer les chefs de la Triade!
+[MOB22_D]
+Vous avez ma parole, mais en attendant,
-[TM4_G]
-~w~Et puis, si t'en as l'occasion, descends quelques-uns de leurs porte-flingues.
+[MOB22_E]
+acceptez, je vous en prie, les sincères remerciements de mon peuple pour vos actions bénéfiques.
-[TM4_GAT]
-~g~Tu as besoin d'un 'Camion de poisson de la Triade' pour entrer.
+[MOB_25A]
+Tommy, c'est Cortez. Les Français me font beaucoup d'ennuis...
-[TM5_A]
-TEXT NO LONGER REQUIRED
+[MOB_25B]
+Les sales hypocrites! Ils passent des siècles à piller les pays pauvres et ils osent me traiter de voleur!
-[TM5_B]
-~w~Ok, j'en ai marre de toutes ces conneries.
+[MOB_25C]
+Je vais avoir besoin de votre aide aussi vite que possible.
-[TM5_C]
-~w~On va en finir une bonne fois pour toute avec la Triade de Liberty!.
+[MOB_25D]
+Vite, Tommy, j'ai vraiment besoin de vous. Je hais ces maudits Français!
-[TM5_D]
-8-Ball a installé une bombe sur une benne à ordures.
+[MOB_26A]
+Allo, Tommy?
-[TM5_E]
-~w~Il y a un minuteur donc, si tu te chies dessus, y'aura pas de preuves. Va chercher la benne.
+[MOB_26B]
+Ouais?
-[TM5_F]
-~w~Fais gaffe, 8-Ball dit que c'est super-sensible et que la moindre secousse peut tout faire sauter.
+[MOB_26C]
+C'est moi, Baker. Je voulais juste te dire que j'ai beaucoup apprécié le spectacle.
-[TM5_G]
-~w~La conserverie de poisson laissera entrer la benne, après ce sera à toi de jouer.
+[MOB_26D]
+Moi et mes gars, on veut te remercier, et te rappeler
-[TM5_H]
-~w~Gare-toi entre les bonbonnes de gaz et casse-toi en vitesse!
+[MOB_26E]
+que tu as tout notre respect. Bon, salut. Et continue comme ça, mon pote.
-[TM5_I]
-~w~Je veux qu'il pleuve des maquereaux!
+[MOB_29A]
+Allo? Vous êtes bien M. Tommy Vercetti?
-[TM5_J]
-~w~C'est du Cecil B. DeMille que je veux, pas de la série Z!
+[MOB_29B]
+Ouais.
-[FM2]
-'LA FILLE DU MOGHOL'
+[MOB_29C]
+Bien. J'ai entendu dire que vous êtes l'homme à appeler quand on est victime d'une invasion de vermine.
-[FM4]
-'DERNIERES VOLONTES'
+[MOB_29D]
+Ca se peut...
-[FM1_A]
-~w~Moi et les gars, on a besoin de causer affaires.
+[MOB_29E]
+Eh bien, là je suis vraiment envahi par la vermine. Les haïtiens sont partout...
-[FM1_B]
-~w~Alors tu vas veiller sur ma fille pendant la soirée.
+[MOB_29F]
+Je m'appelle Umberto Robina et je vous propose une rencontre au Café Robina aussitôt que vous pourrez.
-[FM1_C]
-~w~MARIA! RAMENE TES FESSES PAR ICI!
+[MOB_29G]
+Moi j'vous le dis, ces maudits haïtiens sont allés trop loin, cette fois...
-[FM1_D]
-~w~Cette petite conne fait toujours ça.
+[MOB_29H]
+Test
-[FM1_E]
-~w~Et la voilà, la seule et unique reine de Saba!
+[MOB_30A]
+Tommy, c'est Umberto Robina.
-[FM1_F]
-~w~Qu'est-ce que tu faisais là-bas ?
+[MOB_30B]
+Quoi de neuf au café?
-[FM1_G]
-~w~Enfin, peu importe, je parie que ça m'a coûté de l'argent!
+[MOB_30C]
+Oh, merveilleux, Tommy, vraiment incroyable! Ici, plus de mauviettes, Tommy. Juste de vrais hommes et des belles filles!
-[FM1_H]
-~w~Bon, tu crois quand même pas que je suis dans le coin pour te faire la conversation ?
+[MOB_30D]
+Je voulais te dire que moi et papa, maintenant, on te considère comme cubain.
-[FM1_I]
-~w~Monte dans cette bagnole et ferme ta grande gueule!
+[MOB_30E]
+T'as fait tes preuves, mon frère et t'en as une sacrée paire dans l'pantalon!
-[FM1_J]
-~w~Prends la Stretch, mais tu la ramènes en un seul morceau, compris?
+[MOB_30F]
+Euh, merci, Umberto. Personne ne m'a dit ça depuis que je suis sorti de taule. Bon, salut.
-[FM1_K]
-~w~Et surveille-la, elle peut foutre la merde!
+[MOB_33A]
+Tommy, c'est Phil! Bon, arrête tes conneries et écoute-moi, tu veux?
-[FM1_L]
-~w~Ouais, ouais, ouais, je suis sûr que le neurone de ton nouveau larbin a tout enregistré!
+[MOB_33B]
+Bon. J'ai du whisky extra fort, presque fermenté, et je me demandais si tu voulais pas venir boire un coup...
-[FM1_M]
-~w~Et pis il est taillé comme une armoire normande, alors y'a pas de risque!
+[MOB_33C]
+Sans déconner, Tommy, si t'as besoin d'un verre ou de décoller de la peinture, t'es le bienvenu, ce truc fera de toi un homme!
-[FM1_N]
-~w~Allez, Fido. On va chez Chico s'éclater un peu!
+[MOB_33D]
+Ca me fait cet effet, même si je vois plus rien d'un oeil. Je t'attends, t'entends?
-[FM1_P]
-~g~C'est Chico, là! Arrête-moi à côté!
+[MOB_34A]
+Tommy, ça m'a fait vraiment plaisir de bosser avec toi. Je m'étais pas autant marré depuis la guerre du Vietnam, mon pote.
-[FM1_S]
-~w~Bonsoir, jolie dame.
+[MOB_34B]
+Bon, si t'as besoin de quelque chose, tu m'appelles, t'entends?
-[FM1_TT]
-~w~22, V'LA LES FLICS!
+[MOB_34C]
+Je n'oublie jamais ceux avec qui j'ai servi
-[FM1_1]
-~g~Retourne dans la Stretch!
+[MOB_34D]
+et je suis sûr que je peux t'aider, t'entends?
-[FM1_2]
-~g~Monte dans la Stretch!
+[MOB_35A]
+Tommy, la blessure cicatrise bien. Le truc drôle, c'est que
-[FM1_3]
-~r~Si tu laisses Maria, Salvatore va l'avoir mauvaise, alors retourne la chercher!
+[MOB_35B]
+j'ai combattu dans six batailles et que je m'en suis toujours sorti sans une égratignure, et voilà!
-[FM1_4]
-~g~Tu viens de larguer la femme du Don! Retourne à l'entrepôt et attends Maria!
+[MOB_35C]
+'Phil, le manchot d'un bras.' Enfin, j'ai encore une large selection d'armes de poing alors je serai jamais 'Phil, le désarmé', t'entends?
-[FM1_5]
-~g~Ramène Maria chez Salvatore!
+[MOB_35D]
+Aller, mon pote, laisse tomber les conneries sentimentales et va te boire un verre, t'entends?
-[FM1_6]
-~g~Chico ne restera pas là tout le temps, alors emmène Maria voir la mer.
+[MOB_36A]
+Tommy, c'est Phil. Je voulais te remercier pour le coup de main, mon pote.
-[FM1_7]
-~r~Maria est morte! Salvatore va être furax...
+[MOB_36B]
+Salopard de Charlie, toujours à tendre des embuscades ici ou là,
-[FM1_8]
-~r~T'as trucidé le fournisseur de Maria!
+[MOB_36C]
+mais la blessure cicatrise bien, et ça veut aussi dire que j'aurai plus à truander le gouvernement pour le contrôle d'invalidité. Merci, mon pote.
-[FM2_J]
-Laisse-nous seuls un moment.
+[MOB_40A]
+Salut, Tommy, c'est Sonny. Alors ce bronzage?
-[FM2_A]
-Le Cartel colombien fabrique de la SPANK quelque part à Liberty.
+[MOB_40B]
+J'suis pas bronzé.
-[FM2_K]
-Mais on sait pas où, et on dirait qu'ils sont au courant de nos moindres faits et gestes.
+[MOB_40C]
+Ouais et t'as pas non plus mon pognon, alors je m'interrogeais...
-[FM2_L]
-Y'a un gars, Bob le frisé, qui bosse au bar chaz Luigi.
+[MOB_40D]
+Je me disais : 'Qu'est-ce qu'il fout?' Alors, je te le demande, Tommy, qu'est-ce que tu fous?
-[FM2_M]
-Il dépense plus qu'il ne gagne...
+[MOB_40E]
+Je cherche le pognon, Sonny, t'inquéte pas!
-[FM2_N]
-Il prend souvent un taxi pour rentrer chez lui après le boulot. Alors, suis-le.
+[MOB_40F]
+Je m'inquiéte, Tommy, c'est mon genre,
-[FM2_O]
-Et si c'est lui la balance, descends-le...
+[MOB_40G]
+parce que j'ai ce problème récurrent dans la vie de tomber sur des gens indignes de confiance...
-[FM2_F]
-Voilà notre copain. Monsieur grande gueule en personne.
+[MOB_40H]
+Ne sois pas indigne de ma confiance, Tommy, s'il te plaît...
-[FM2_G]
-T'as été suivi ? Tu sais que ce qui se passe ici, c'est notre petit secret...
+[MOB_40I]
+Rends-nous à tous deux ce service. J'attends de tes nouvelles...
-[FM2_H]
-Non, non, j'ai pas été suivi. T'as la came ?
+[MOB_41A]
+Tommy, tu te souviens de moi?
-[FM2_I]
-Voilà ta SPANK, alors crache le morceau.
+[MOB_41B]
+Salut, Sonny.
-[FM2_P]
-Ok, alors ce qui se passe, c'est que les Leone mènent la guerre sur deux fronts à la fois.
+[MOB_41C]
+Ouais, exactement, Sonny, on est de vieux amis,
-[FM2_Q]
-Y'a une guerre de territoire avec la Triade qu'est pas prête de finir
+[MOB_41D]
+mais tu ne m'écris jamais, tu ne m'appelles jamais. Tu ne veux plus qu'on soit amis?
-[FM2_R]
-et Joey Leone a foutu la merde avec les Forelli.
+[MOB_41E]
+J'ai été très occupé à régler des trucs ici et là. Tu ne m'aides pas beaucoup, ici.
-[FM2_S]
-Ils perdent du terrain et des hommes tous les jours.
+[MOB_41F]
+Oh, c'est ma faute? Bon, j'ai entendu que tu étais très occupé, d'accord,
-[FM2_T]
-Salvatore devient de plus en plus irascible et parano chaque jour. Il soupçonne tout le monde.
+[MOB_41G]
+occupé à liquider des barons de la drogue, occupé à prendre le pouvoir.
-[FM2_U]
-Ben, quand je te vois, je me dis qu'il a pas forcément tort...
+[MOB_41H]
+Alors je te préviens simplement de ne pas m'oublier, Tommy, parce que moi, je ne t'oublie pas...
-[FM2_1]
-~g~Voilà Bob le frisé!
+[MOB_42A]
+Tommy.
-[FM2_2]
-~g~Bob a quitté le club, suis-le!
+[MOB_42B]
+Sonny.
-[FM2_5]
-~g~Amène-le au port de Portland.
+[MOB_42C]
+Faut croire que t'es à moitié sourd, alors je vais me répéter :
-[FM2_6]
-~r~Bob montera jamais dans un taxi bousillé!
+[MOB_42D]
+Tommy, où est ce putain de pognon? Où est cette putain de marchandise? Et où est ma putain de part sur ta nouvelle affaire?
-[FM2_7]
-~r~Bob le frisé s'est dégonflé. Le rendez-vous est annulé.
+[MOB_42E]
+Tu te fous vraiment d'ma gueule, Tommy, et ça me fait pas rire!
-[FM2_8]
-~g~Cogne Bob le frisé!
+[MOB_43A]
+Tommy! Tommy! J'ai eu Sonny au téléphone. Tu m'écoutes?
-[FM2_9]
-~r~Bob le frisé est mort!
+[MOB_43B]
+Je ne sais pas pour toi, mais il y a un mec qui menace de buter toute ma famille,
-[FM2_10]
-~r~Bob le frisé s'est fait la malle!
+[MOB_43C]
+et ça me fout vraiment les jetons. Qu'est-ce que tu comptes faire?
-[FM2_11]
-~g~Gare-toi devant le club de Luigi, Bob le frisé devrait pas tarder à sortir.
+[MOB_43D]
+Reste calme, Ken, tout va bien se passer.
-[FM2_12]
-~r~Il t'a faussé compagnie!
+[MOB_43E]
+Je suis calme! Calme comme un homme qui craint pour sa propre vie!
-[FM3_A]
-~w~On devrait régler leur compte à ces bâtards de Colombiens.
+[MOB_43F]
+Ken, j'ai d'autres choses en tête pour l'instant,
-[FM3_B]
-~w~Mais tant qu'on est en guerre avec les Triades, on n'est pas assez fort.
+[MOB_43G]
+on s'occupera de Forelli quand l'heure sera venue.
-[FM3_C]
-~w~Les fonds du Cartel sont illimités, avec tout l'argent qu'ils se font sur la SPANK.
+[MOB_43H]
+Je suis calme. J'ai pas l'air calme? J'sais pas, c'est ma voix qui a changé à cause de la mort qui me pend au nez!
-[FM3_D]
-~w~Si on les attaquait de front, ils nous lamineraient!
+[MOB45_A]
+Tommy, faut qu'on cause sérieusement.
-[FM3_E]
-~w~Ils doivent fabriquer la SPANK sur le bateau vers lequel Le frisé t'a conduit.
+[MOB45_B]
+C'est quoi le problème, Lance?
-[FM3_F]
-~w~Va falloir utiliser nos cerveaux, ou plutôt un. Le tien!
+[MOB45_C]
+C'est toi le problème, mon pote, j'ai l'impression que tu m'files pas une part équitable...
-[FM3_G]
-~w~Je te demande de détruire cette usine de SPANK comme une faveur, pour moi, Salvatore Leone.
+[MOB45_D]
+Mais le pire, c'est que tu m'as foutu la honte devant les mecs. Je supporte pas ça.
-[FM3_H]
-~w~Si tu y arrives, ton avenir est assuré, tu auras tout ce que tu veux!
+[MOB45_E]
+Lance, c'est pas ça du tout. T'as fait des bourdes, c'est tout.
-[FM3_I]
-~w~Va voir 8-Ball, il te dira comment faire, c'est un expert en explosifs.
+[MOB45_F]
+Tommy, je suis pas ton petit messager et encore moins ton garçon de courses.
-[FM3_8A]
-~w~Salut mon gars! Salvatore m'a téléphoné.
+[MOB45_G]
+Lance, déconne pas et on aura pas d'emmerdes! Et si c'est moi qui déconne, tu peux me rentrer dedans quand tu veux.
-[FM3_8B]
-~w~Pour un boulot comme ça, il va te falloir un sacré paquet de feux d'artifices!
+[MOB45_H]
+Tommy, j'ai tout fait pour toi et tu me traites comme un con. Fais pas ça.
-[FM3_8D]
-~w~Mais tu sais que tu en as toujours pour ton pognon avec moi!
+[MOB45_I]
+Lance, je ne vais pas t'arnaquer ou te planter un couteau dans le dos, ok?
-[FM3_8E]
-~w~Ok, au boulot!
+[MOB45_J]
+T'énerve pas. C'est déjà assez dur comme ça, sans que tu perdes les pédales.
-[FM3_8F]
-~w~Je peux régler le détonateur de ce bébé, mais je peux toujours pas utiliser un flingue avec ces mains.
+[MOB45_K]
+Fais-moi confiance. Tu m'entends? Tu m'entends?
-[FM3_8G]
-~w~Tiens, cette pétoire devrait te servir à faire sauter quelques têtes.
+[MOB45_L]
+Je t'entends, Tommy, mais je peux pas supporter ça plus longtemps.
-[FM3_4]
-~g~Arrête la bagnole et laisse 8-Ball sortir.
+[MOB45_M]
+Lance, arrête de déconner. Maintenant, je te préviens.
-[FM3_7]
-~r~8-Ball s'est fait refroidir!
+[MOB45_N]
+Tu m'entends? Relax! Prends quelques jours de repos et on en reparle, ok?
-[FM3_8]
-~r~Les gardes ont été prévenus!
+[MOB46_A]
+Tommy, c'est Lance.
-[FM4_A]
-~w~Ah, voilà mon nettoyeur favori!
+[MOB46_B]
+Ouais?
-[FM4_B]
-~w~Je suis fier de toi, mon garçon, tu leur en as mis plein la gueule!
+[MOB46_C]
+Même pas un 'ça fait plaisir d'avoir des tes nouvelles'? Allez, mec, sois sympa!
-[FM4_C]
-~w~J'ai juste un autre petit travail à te confier avant de pouvoir sabrer le champagne.
+[MOB46_D]
+Je suis occupé. Qu'est-ce que tu veux?
-[FM4_D]
-~w~Il y a une voiture devant le club de Luigi.
+[MOB46_E]
+Rien. C'était juste pour te dire... Tu sais, Tommy, on peut faire ce truc.
-[FM4_E]
-~w~L'intérieur est tapissé de cervelle!
+[MOB46_F]
+Toi et moi, sans problème. Tu vois ce que je veux dire?
-[FM4_F]
-~w~On a aidé un gars à se faire une idée, et y'a eu quelques salissures.
+[MOB46_G]
+Va bien falloir qu'on le fasse, parce que sinon, on est morts, Lance.
-[FM4_H]
-~w~Emmène-le au broyeur avant que les flics ne le trouvent.
+[MOB46_H]
+On peut plus reculer, maintenant, mais merci de ton appel. On se reparle plus tard.
-[AM3]
-'PURGE DE PAPARAZZI'
+[MOB_47A]
+Tommy, c'est Lance, on a de gros problèmes. Amène-toi ici en vitesse.
-[AM4]
-'JOUR DE PAYE'
+[MOB52_A]
+Salut, Léo, je crois qu'on a un acheteur pour la marchandise de Diaz.
-[AM5]
-'TANNER L'AGENT DOUBLE'
+[MOB52_B]
+Il faut que tu l'appelles, mec, pour organiser le deal, tu comprends?
-[AM1_A]
-Nous devons éclaircir certains points avant de poursuivre nos relations,
+[MOB52_C]
+T'es où, là?
-[AM1_B]
-affaires ou autres. Mettons cartes sur table.
+[MOB52_D]
+T'es sûr que ça va, Léo? T'as une voix bizarre...
-[AM1_C]
-Moi, je suis Yakuza et je sais que tu travailles pour la famille de Salvatore Leone.
+[MOB52_E]
+Dis-moi juste où t'es.
-[AM1_D]
-Nous pouvons te donner du travail,
+[MOB52_F]
+Qui c'est qui cause? Je veux parler à Léo!
-[AM1_E]
-mais il faut d'abord nous prouver que t'as plus aucun lien avec la mafia.
+[MOB52_G]
+Léo est parti pour un moment, je le remplace.
-[AM1_G]
-Débrouille-toi pour qu'il n'arrive pas vivant à son club.
+[MOB52_H]
+Va te faire foutre, connard!
-[AM1_H]
-Pendant ce temps-là, Maria et moi, nous nous remémorerons le bon vieux temps.
+[MOB54_A]
+Salut, Tommy!
-[AM1_I]
-Oh... Asuka, tu t'es trouvé un messager.
+[MOB54_B]
+Salut, Mercedes, quoi de neuf?
-[AM1_J]
-Ce n'est pas un simple messager.
+[MOB54_C]
+J'ai un nouvel appartement dans Vice Point.
-[AM1_1]
-~g~Salvatore part de chez Luigi!
+[MOB54_D]
+J'ai pensé que tu voudrais peut-être passer un de ces quatre...
-[AM1_2]
-~r~Tu t'es fait repérer!
+[MOB54_E]
+J'adorerai. A plus tard.
-[AM1_3]
-~r~Tu as raté Salvatore!
+[MOB55_A]
+Tommy, c'est moi.
-[AM1_4]
-~r~Bravo, t'as effrayé la cible! Et t'es censé être un tireur d'élite, c'est ça ?
+[MOB55_B]
+Salut, Mercedes.
-[AM1_5]
-~g~Va au Le Quartier Rouge et attends que Salvatore sorte du club.
+[MOB55_C]
+Tommy, je m'ennuie tellement! Quand est-ce qu'on va s'amuser?
-[AM1_7]
-~r~Salvatore est chez lui, à siroter un whisky. T'es vraiment pas une flèche, toi!
+[MOB55_D]
+Comment ça?
-[AM1_8]
-~g~Salvatore va sortir de chez Luigi à environ ~1~:~1~.
+[MOB55_E]
+Bon, je sais que t'es très occupé à te battre, à tuer des gens ou à les corrompre,
-[AM2_4]
-~g~Ils t'ont vu venir aussi nettement que si t'étais un éléphant rose!
+[MOB55_F]
+mais moi, j'ai envie de m'amuser un peu! Alors, ne m'oublie pas, Tommy!
-[AM3_A]
-Y'a un journaliste qui nous tourne autour.
+[MOB56_A]
+Tommy, j'ai entendu dire que tu avais tué Ricardo Diaz!
-[AM3_B]
-Maria et moi, on part en vacances, histoire de te laisser le temps de te débarrasser de ce voyeur pervers.
+[MOB56_B]
+Un feu accidentel s'est déclenché dans sa résidence...
-[AM4_A]
-Ah, mon meilleur homme!
+[MOB56_C]
+Je pense qu'il a cramé dans sa chemise en acrylique.
-[AM4_B]
-Maria est très occupée, mais je lui dirai que t'es passé.
+[MOB56_D]
+Tommy, je suis si fière de toi! Je savais que tu étais un vrai macho!
-[AM4_C]
-Qui est là ? Asuka ? Je sais que je n'ai pas été très sage, mais j'ai le droit d'aller toute seule au petit coin, ok ?
+[MOB56_E]
+Ah, mon dur de dur, je suis si fière d'être ton amie!
-[AM4_D]
-Il est temps que tu rencontres notre homme au LPD.
+[MOB56_F]
+Je sais que tu vas être très occupé à essayer de t'emparer de cette ville,
-[AM4_E]
-Voilà sa paye pour le dernier service qu'il nous a rendu.
+[MOB56_G]
+mais ne m'oublie pas, d'accord?
-[AM4_F]
-Il est terriblement prudent.
+[MOB57_A]
+C'est Mercedes. Je ne t'aime plus, Tommy!
-[AM4_G]
-Va à la cabine de téléphone de Torrington aussi vite que tu peux et attends ses instructions.
+[MOB57_B]
+C'est fini! C'est vrai! Parce que tu n'es plus gentil avec moi!
-[AM5_A]
-Maria et moi, on est allé faire des courses.
+[MOB57_C]
+Tu ne me traites plus comme une dame! Tu m'ignores et je te déteste!
-[AM5_B]
-Notre informateur dans la police nous a dit qu'un de nos conducteurs est un flic sous couverture!
+[MOB57_D]
+Je veux que tu viennes me voir tout de suite! "
-[AM5_C]
-Il ne vaut pas grand chose hors de sa voiture, alors on y a installé un capteur.
+[MOB58_A]
+Tommy.
-[AM5_D]
-Je veux qu'il souffre!
+[MOB58_B]
+Salut, Mercedes.
-[AM5_1]
-Tanner est à tes trousses!
+[MOB58_C]
+Bonjour monsieur le vrai dur! Je suis très en colère contre toi, Tommy!
-[AS1]
-'L'APPAT'
+[MOB58_D]
+Ne m'oblige plus jamais à supporter Jezz Torrent!
-[AS2]
-'CAFE RAPIDO'
+[MOB58_E]
+Il est pathétique! En plein milieu il a commencé à pleurer à cause de son toutou
-[AS4]
-'LA RANCON'
+[MOB58_F]
+qui est mort quand il avait 7 ans et parce que sa mère ne l'a jamais aimé...
-[AS1_A]
-~w~Miguel semble croire que je l'ai maltraité.
+[MOB58_G]
+En plus, Tommy, il porte une perruque et un soutien-gorge dans l'intimité!
-[AS1_B]
-Il nous a néanmoins révélé à quel point Catalina s'inquiète de ta soif de vengeance.
+[MOB58_H]
+Je t'en veux vraiment!
-[AS2_A]
-~w~On a sous-estimé les ambitions de Catalina avec la SPANK.
+[MOB59_A]
+Ooh Tommy, c'est Mercedes.
-[AS2_B]
-~w~Cela va plus loin qu'une vente à la sauvette dans les rues.
+[MOB59_B]
+Je voulais juste te dire que je m'étais éclatée sur le tournage!
-[AS2_D]
-~w~Il fourgue sa came sur des étals.
+[MOB59_C]
+Si tu as quelque chose d'autre de ce genre, pense à moi!
-[AS2_1]
-~g~Tous les étals des vendeurs de café de Portland ont été renversés!
+[MOB59_D]
+Je suis sincère! J'ai toujours voulu être actrice!
-[AS2_2]
-~g~Tous les étals des vendeurs de café de l'île de Staunton ont été renversés!
+[MOB59_E]
+Je crois que j'ai beaucoup appris sur l'art dramatique!
-[AS2_3]
-~g~Tous les étals des vendeurs de café la vallée Shoreside ont été renversés!
+[MOB59_F]
+C'est tellement révélateur! Merci beaucoup! On se voit très bientôt, adios!
-[AS2_4]
-~r~Le Cartel a mis en garde ses revendeurs!
+[MOB_99]
+Rends-toi à la cabine indiquée.
-[AS2_5]
-~g~Il y a toujours des stands de café à la vallée Shoreside et sur l'île Staunton!
+[MOB_98]
+Rends-toi à la cabine indiquée.
-[AS2_6]
-~g~Il y a toujours des stands de café à la vallée Shoreside!
+[MOB_97]
+Rends-toi à la cabine indiquée.
-[AS2_7]
-~g~Il y a toujours des stands de café sur l'île Staunton!
+[MOB_96]
+Rends-toi à la cabine indiquée.
-[AS2_8]
-~g~Il y a encore des étals de vendeurs de café à Portland!
+[MOB_95]
+Rends-toi à la cabine indiquée.
-[AS2_9]
-~g~Il y a toujours des stands de café dans Portland et la vallée Shoreside!
+[A_TIME]
++~1~ secondes
-[AS2_10]
-~g~Il y a toujours des stands de café dans Portland et sur l'île Staunton!
+[F_RANGE]
+La radio du camion de pompiers ne capte plus rien. Rapproche-toi d'une caserne!
-[AS2_12]
-~g~Parcours les districts de Liberty pour trouver ~b~les étals de Café Rapido!
+[DODO_FT]
+Tu as 'volé' pendant ~1~ secondes!
-[AS3_A]
-~W~Est-ce qu'on le serre un peu plus maintenant ou on attend juste qu'il vire au noir et qu'il tombe tout seul?
+[GA_8]
+Utilise le détonateur pour armer la bombe.
-[AS3_B]
-~w~Allez, encore un peu...
+[GA_10]
+Bravo. Voilà tes ~1~$.
-[AS3_D]
-~w~Mon homme à tout faire!
+[GA_11]
+On en a déjà des comme ça. Ca nous sert à rien!
-[AS3_E]
-~w~Je m'ennuyais alors je suis venue tenir compagnie à Asuka.
+[GA_12]
+Bombe armée
-[AS3_1]
-~g~Trouve un ~r~bateau~g~ et rejoins la ~b~bouée repère!
+[GA_13]
+Comme un pro! Finis la liste et t'auras un bonus!
-[AS3_3]
-~g~Attends que l'~y~avion~g~ s'approche!
+[GA_14]
+Toutes les voitures! PARFAIT! Tiens, voilà un petit quelque chose!
-[AS3_5]
-~g~Récupère la marchandise!
+[GA_15]
+J'espère que t'aimes la nouvelle couleur.
-[AS3_4]
-~g~Sers-toi d'un lance-roquettes pour descendre l'~y~avion~g~!
+[GA_16]
+La peinture est en option!
-[AS3_2]
-~b~Va vers les bouées repères! ~y~L'avion est en phase d'approche!
+[GA_19]
+Ce modèle ne nous intéresse pas!
-[AS3_6]
-~g~~1~ SUR 8
+[GA_20]
+On en a trop des comme ça! Désolé, mec.
-[KM1]
-'LA GRANDE EVASION'
+[CHASE]
+Attention maximale des médias
-[KM3]
-'NEGOCIATION'
+[CHASE1]
+Ignoré
-[KM4]
-'SHIMA'
+[CHASE2]
+Ennuyeux
-[KM5]
-'LES RIVIERES POURPRES'
+[CHASE3]
+Plus ou moins intéressant
-[KM1_A]
-Ma soeur m'a parlé de toi en des termes élogieux,
+[CHASE4]
+Journal local page 7
-[KM1_E]
-même si je suis toujours pas convaincu qu'un gaijin à autre chose à offrir que des déceptions.
+[CHASE5]
+Journal local La une
-[KM1_B]
-Quoique, tu pourrais peut-être m'aider à régler un petit problème.
+[CHASE6]
+Vice Courier Rubrique 1
-[KM1_F]
-Bien sûr, un échec te serait fatal.
+[CHASE7]
+Vice Courier La une
-[KM1_C]
-Un kanbu Yakuza est en garde à vue, en attente d'un transfert au palais de justice.
+[CHASE8]
+Télé locale 3h du mat'
-[KM1_G]
-C'est un membre apprécié de notre famille.
+[CHASE9]
+Télé locale Infos
-[KM1_H]
-Libère-le et amène-le au dojo de Bedford Point.
+[CHASE10]
+Télé locale Direct
-[KM1_D]
-Nous te remercions pour ton aide désintéressée. Si toi aussi, tu as besoin d'aide un jour, le dojo te fournira avec plaisir deux hommes pour t'assister.
+[CHASE11]
+UFA Today page 12
-[KM1_1]
-~g~Vole une bagnole de flics!
+[CHASE12]
+UFA Today page 4
-[KM1_2]
-~g~Equipe-la d'une bombe!
+[CHASE13]
+Photo dans UFA Today
-[KM1_3]
-~g~Maintenant, emmène-la au dojo des Yakuzas!
+[CHASE14]
+Télé nationale 4h du mat'
-[KM1_5]
-~g~Bien, maintenant, va au poste de police.
+[CHASE15]
+Télé nationale Infos
-[KM1_6]
-~g~Equipe la voiture d'une bombe!
+[CHASE16]
+Télé nationale Direct
-[KM1_7]
-~g~Réservé aux véhicules de police!
+[CHASE17]
+Infos internationales
-[KM1_9]
-~r~Tu n'as pas utilisé de voiture piégée pour détruire le mur.
+[CHASE18]
+Crise nationale
-[KM1_10]
-~r~Le Yakuza Kanbu est mort, tout comme ton honneur!
+[CHASE19]
+Crise internationale
-[KM1_11]
-~r~Tu t'es fouré tout seul dans le pétrin!
+[CHASE20]
+Evénement mondial
-[KM2_A]
-Dans ce milieu, l'étiquette ne doit jamais être sous-estimée. Au contraire!
+[CHASE21]
+Truc de légendes
-[KM2_B]
-J'ai honte mais un homme m'a autrefois rendu service et je n'ai jamais eu l'occasion de lui montrer ma reconnaissance.
+[CR_1]
+La grue ne peut pas soulever ce véhicule.
-[KM2_C]
-Cet homme est un passionné de voitures et il a demandé que nous lui fournissions certains modèles pour sa collection.
+[PU_MONY]
+T'as pas assez de liquide.
-[KM2_F]
-Mon honneur m'interdit de refuser.
+[CO_ALL]
+Tu les as toutes eues. Tiens, voilà pour toi...
-[KM2_2]
-~g~Voiture livrée.
+[FEM_ON]
+Activé
-[KM3_A]
-Face au danger, l'inconscient tourne le dos alors que le sage fait front.
+[FEM_OFF]
+Désactivé
-[KM3_B]
-Nous avons prévenu à plusieurs reprises le Cartel colombien qu'il fallait laisser nos intérêts à Liberty tranquilles.
+[FEM_YES]
+Oui
-[KM3_C]
-En ce moment même, ils négocient avec les Jamaïcains pour se moquer encore plus de nous.
+[FEM_NO]
+Non
-[KM3_D]
-Ils sont en train de passer un accord pour l'ensemble de la ville.
+[FEM_RET]
+Réessayer
-[KM3_F]
-Prends un de mes hommes, vole une bagnole de Yardie et va présenter nos respects aux Colombiens.
+[FEC_NA]
+NA
-[KM3_E]
-Pour notre honneur, ils doivent tous mourir!
+[FEC_CWL]
+Faire défiler les armes vers la gauche
-[KM3_2]
-~g~Va prendre ton contact.
+[FEC_CWR]
+Faire défiler les armes vers la droite
-[KM3_3]
-~g~La réunion a lieu sur le parking de l'hôpital de Rockford!
+[FEC_LOF]
+Regarder devant
-[KM3_4]
-~r~Ils ont filé!
+[FEC_TAR]
+Viser
-[KM3_6]
-~g~Supprime-les, tue-les tous!
+[FEC_MOV]
+Déplacement
-[KM3_8]
-~g~Il te faut une bagnole de Yardie pour ce boulot!
+[FEC_CAM]
+Modes caméra
-[KM3_9]
-~r~L'un des Colombiens est mort, l'accord est caduc.
+[FEC_PAU]
+Pause
-[KM3_10]
-~r~Le contact est mort!
+[FEC_ENV]
+Monter dans un véhicule
-[KM4_A]
-La seule vraie force consiste à ne jamais montrer ses faiblesses.
+[FEC_JUM]
+Sauter
-[KM4_C]
-Va récupérer l'argent immédiatement pour qu'on puisse le placer sur les comptes du casino.
+[FEC_ATT]
+Attaquer ou tirer
-[KM4_1]
-Je peux pas vous payer et même si je pouvais, je le ferais pas!
+[FEC_RUN]
+Courir
-[KM4_9]
-Un gang de jeunes vient de dévaliser cet endroit! Ils ont tout pris!
+[FEC_FPC]
+Vue subjective
-[KM4_2]
-Vous ne servez à rien!
+[FEC_LL]
+Rergarder à gauche
-[KM4_10]
-Quel genre de Yakuza êtes-vous? hein?
+[FEC_LB]
+Regarder derrière
-[KM4_3]
-C'est pas pour ça que je vous paye! Si j'avais voulu ce genre de protection, je me serais adressé directement aux flics!
+[FEC_LR]
+Regarder à droite
-[KM4_4]
-~g~Réglez son compte au gang et récupérez ~b~l'argent de la protection~g~!
+[FEC_HOR]
+Klaxon
-[KM4_7]
-~r~Le commerçant est mort!
+[FEC_VES]
+Commandes du véhicule
-[KM4_5]
-Donald Love aimerait que vous passiez prendre le thé chez lui afin d'avoir une conversation avec vous.
+[FEC_BRA]
+Freiner ou marche arrière
-[KM4_6]
-Tout l'argent est là!
+[FEC_HAB]
+Frein à main
-[KM4_8]
-~g~Malette récupérée!
+[FEC_CAW]
+Arme du véhicule
-[KM5_A]
-TOI! Et c'est maintenant que tu te décides à te montrer!
+[FEC_ACC]
+Accélérateur
-[KM5_B]
-Il semblerait que ta tentative pour empêcher les Jamaïcains
+[FEC_CCF]
+Configuration :
-[KM5_B1]
-de s'allier aux Colombiens ait complètement raté!
+[FEC_CF1]
+Config. 1
-[KM5_C]
-Y a des dealers du gang des Caraïbes dans tout Liberty qui vendent des sachets de SPANK comme si c'était des friandises!
+[FEC_CF2]
+Config. 2
-[KM5_D]
-Les membres du Cartel se foutent de nous et de moi surtout!
+[FEC_CF3]
+Config. 3
-[KM5_E]
-Je te donne une dernière chance de me prouver que ma soeur avait raison de te faire confiance!
+[FEC_CF4]
+Config. 4
-[KM5_F]
-Débarrasse-moi de tous ces rats et rachète-toi avec leur sang!
+[FEC_CDP]
+Affichage manette :
-[KM5_3]
-~r~Tu n'as pas réussi à tuer au moins ~1~ Yardies.
+[FEC_ONF]
+à pied
-[KM5_4]
-~g~Bravo, tu as tué ~1~ Yardies.
+[FEC_INC]
+En voiture
-[KM5_5]
-~g~Bravo! Tu as tué ~1~ Yardies. Bonus : ~1~$
+[FEC_VIB]
+Vibrations :
-[RM1]
-'EQUILIBRER LA BALANCE'
+[FEL_ENG]
+Anglais
-[RM3]
-'PREUVES A PROUVER'
+[FEL_FRE]
+Français
-[RM4]
-'PECHE AU GROS'
+[FEL_GER]
+Allemand
-[RM5]
-'LE MARTEAU ET L'ENCLUME'
+[FEL_ITA]
+Italien
-[RM1_D]
-Il est sous protection dans une propriété de WitSec à Newport, des appartements à l'arrière du parking.
+[FEL_SPA]
+Espagnol
-[RM1_E]
-Enfume-moi cet endroit, ça devrait les faire sortir, et tu me les butes tous, fais en sorte que Mc Machin ne parle plus à personne.
+[FED_DBG]
+Menu Debug
-[RM1_1]
-~g~Vérifie la maison du programme de protection des témoins.
+[FED_RID]
+Recharger IDE
-[RM1_2]
-~g~Chope McAffrey!
+[FED_RIP]
+Recharger IPL
-[RM2_A1]
-Hé, gamin, par là!
+[FED_PAH]
+Analyser Saut
-[RM2_A]
-Un vieux pote à moi de l'armée a une affaire à Rockford.
+[FED_DFL]
+CTheScripts::DbgFlag
-[RM2_D]
-Il a besoin d'un coup de main et, en échange, il te fera des prix d'enfer sur son matos.
+[FED_DLS]
+Lumière blanche de debug allumée
-[RM2_E]
-Ray a téléphoné... mais je pensais que vous seriez plusieurs...
+[FED_SPR]
+Affiche les groupes de pietons
-[RM2_F]
-Bon, trois bras valent mieux qu'un, alors prends ce qu'il te faut.
+[FED_SCR]
+Affiche les groupes en voiture
-[RM2_G]
-~g~Va voir Phil!
+[FED_SCZ]
+Affiche les zones de massacre
-[RM2_H]
-~r~Phil a été tué!
+[FED_DSR]
+Debug les demandes de répartition par niveaux
-[RM2_L]
-Héhé! Si je t'avais eu comme partenaire au Nicaragua, j'aurais peut-être encore mes deux bras!
+[FED_SCP]
+gb Indique les polys de collision
-[RM2_N]
-Laisse le fric. Maintenant, dégage, je m'occupe des poulets.
+[PL_STAT]
+Stats du joueur
-[RM3_D]
-La pièce à conviction est en train de rouler dans la ville.
+[PE_WAST]
+Personnes tuées par toi
-[RM3_E]
-Va falloir que tu tamponnes cette caisse et que tu récupères les preuves au fur et à mesure qu'elles tombent!
+[PE_WSOT]
+Personnes tuées par d'autres
-[RM3_F]
-Quand t'auras tout, laisse-les dans la voiture et brûle-la.
+[TM_BUST]
+Nb de fois capturé
-[RM3_G]
-C'est une bonne affaire pour tous les deux, tu sais, gamin.
+[GNG_WST]
+Gangsters tués
-[RM3_1]
-~g~Laisse les preuves dans la voiture et brûle-la.
+[DED_CRI]
+Criminels tués
-[RM3_4]
-~g~L'accusation n'a pas tenu compte des pièces à conviction!
+[PER_COM]
+Pourcentage accompli
-[RM3_6]
-~r~Ces photos seront dans tout Liberty!
+[KGS_EXP]
+Kilos d'explosifs utilisés
-[RM3_7]
-~g~Brûle la voiture!
+[ACCURA]
+Précision
-[RM4_A]
-Mon partenaire est un rat.
+[ST_WEAP]
+Budget arsenal
-[RM4_C]
-Il va souvent pêcher en bateau près du phare de Portland Rock, la nuit.
+[ST_PROP]
+Budget propriété
-[RM4_D]
-Vole une vedette de la police et assure-toi que ses sales plans de traître tombent à l'eau!
+[ST_AUTO]
+Budget réparation et peinture voiture
-[RM4_1]
-~g~Vole une vedette de la police.
+[ST_PHOT]
+Photos prises
-[RM4_2]
-~g~Va jusqu'au phare et 'occupe-toi' du partenaire de Ray!
+[ST_LOAN]
+Visites des usuriers
-[RM5_A]
-Espèce de bon à rien!
+[ST_STOR]
+Magasins liquidés
-[RM5_A1]
-Tu t'es chié dessus! Mon cul est en première ligne et t'es même pas foutu de buter une mouche!
+[ST_MOVI]
+Cascades de films
-[RM5_B]
-Je t'ai filé de la thune pour buter ce témoin et il est encore en vie!
+[ST_PIZZ]
+Pizza livrées
-[RM5_B1]
-Et il va faire une déposition devant les fédéraux aujourd'hui!
+[ST_GARB]
+Collectes de détritus effectuées
-[RM5_C]
-Ils vont le transférer d'un moment à l'autre de l'Hôpital Général Carson à Rockford!
+[ST_ICEC]
+Crèmes glacées vendues
-[RM5_D]
-S'il crache le morceau, je vais cracher mes dents, et plus encore...
+[TOP_SHO]
+Meilleur score au champ de tir
-[RM5_E]
-Alors fais ce putain de boulot pour lequel je t'ai payé!
+[SHO_RAN]
+Position au champ de tir
-[RM5_1]
-~g~Intercepte l'ambulance.
+[SEAGULL]
+Mouettes descendues
-[RM5_2]
-~g~Tu t'es fait repérer!
+[PROPOWN]
+Propriété possédée
-[RM5_3]
-~g~C'était un piège à cons!
+[ST_TIME]
+Temps de jeu
-[RM5_4]
-~g~Les balles ne peuvent pas traverser cette armure!
+[ST_FTIM]
+Heures de vol
-[RM5_5]
-~g~Cette armure est recouverte d'amiante!
+[ST_PRAN]
+Classement pilote
-[RM5_7]
-~r~Le témoin est arrivé à bon port!
+[ST_RAN0]
+Apprenti
-[RM5_8]
-~g~Le témoin s'est noyé!
+[ST_RAN1]
+Navigateur
-[LOVE2]
-'HARA-KIRI WAKA-SHIRA'
+[ST_RAN2]
+Copilote
-[LOVE3]
-'RIEN QU'UNE GOUTTE DANS L'OCEAN'
+[ST_RAN3]
+Junior
-[LOVE1_A]
-Tout d'abord, je tiens à te remercier pour m'avoir aidé à régler cette affaire privée.
+[ST_RAN4]
+Compétent
-[LOVE1_F]
-Les gens croient tout ce qu'on leur raconte de nos jours!
+[ST_RAN5]
+Senior
-[LOVE1_D]
-Ils essaient de m'extorquer plus d'argent, mais j'aime pas renégocier mes accords!
+[ST_RAN6]
+As
-[LOVE1_E]
-Un accord est un accord et il n'auront rien de plus de moi!
+[ST_RAN7]
+Baron rouge
-[LOVE1_G]
-Va aider mon ami, tu as carte blanche.
+[ST_DRWN]
+Poissons nourris
-[LOVE1_2]
-~g~Sauve le vieux bridé.
+[ST_FASH]
+Budget fringues
-[LOVE1_3]
-~g~Amène le vieux bridé à l'appartement de Donald Love.
+[ST_DAMA]
+Propriété détruite
-[LOVE1_4]
-~g~Le vieux bridé doit se trouver dans un de ces garages...
+[TM_DED]
+Visites à l'hôpital
-[LOVE1_6]
-~r~Les tripes du vieux bridé sont étalées sur le trottoir. Attention, ça glisse!
+[DAYSPS]
+Jours passés dans le jeu
-[LOVE1_7]
-~g~Les portes ne s'ouvriront que pour laisser passer une voiture du gang des Colombiens.
+[NUMSHV]
+Visites dans l'entrepôt
-[LOVE2_A]
-Rien de mieux qu'une bonne vieille guerre des gangs pour faire marcher l'immobilier,
+[MXCARD]
+Dist. max. de saut de Cascade dangereuse (ft)
-[LOVE2_B]
-en dehors d'une bonne épidémie... mais ça serait peut-être un peu trop.
+[MXCARJ]
+Hauteur max. de saut de Cascade dangereuse(ft)
-[LOVE2_C]
-J'ai remarqué que les Yakuzas et les Colombiens n'étaient pas très copains.
+[MXCARDM]
+Dist. max. de saut de Cascade dangereuse (m)
-[LOVE2_D]
-C'est une opportunité que nous devons saisir!
+[MXCARJM]
+Hauteur max. de saut de Cascade dangereuse (m)
-[LOVE2_E]
-Je veux que tu tues le waka-gashira des Yakuzas, Kenji Kasen.
+[MXFLIP]
+Saltos max. de saut de Cascade dangereuse
-[LOVE2_F]
-Kenji est à une réunion au sommet du parking à plusieurs étages de Newport.
+[MXJUMP]
+Rotation max. de saut de Cascade dangereuse
-[LOVE2_G]
-Procure-toi une voiture du Cartel et tue-le!
+[BUL_FIR]
+Balles tirées
-[LOVE2_H]
-Les Yakuzas doivent accuser le Cartel de leur déclarer la guerre.
+[BUL_HIT]
+Balles ayant atteint la cible
-[LOVE2_1]
-~g~Va à Fort Staunton et vole une voiture du gang des Colombiens.
+[SPRAYIN]
+Peintures
-[LOVE2_2]
-~g~Maintenant, rends-toi au ~p~parking de Newport~g~ et élimine Kenji.
+[BSTSTU]
+Meilleure cacade jusqu'à maintenant
-[LOVE2_3]
-~r~Si tu n'as pas de voiture du Cartel, tu seras démasqué!
+[INSTUN]
+Cascade dangereuse
-[LOVE2_4]
-~r~Les Yakuzas t'ont reconnu!
+[PRINST]
+Cascade dangereuse parfaite
-[LOVE2_6]
-~r~Tu as tué tous les témoins!
+[DBINST]
+Double cascade dangereuse
-[LOVE3_A]
-De nos jours, certaines marchandises de valeur sont difficiles à importer.
+[DBPINS]
+Double cascade dangereuse parfaite
-[LOVE3_C]
-Plusieurs paquets vont être jetés à l'eau.
+[TRINST]
+Triple cascade dangereuse
-[LOVE3_D]
-Récupère-les avant tout le monde.
+[PRTRST]
+Triple cascade dangereuse parfaite
-[LOVE3_1]
-~g~Procure-toi un ~r~bateau~g~ et suis l'~y~avion~g~!
+[QUINST]
+Quadruple cascade dangereuse
-[LOVE4]
-'VOL AU VENT'
+[PQUINS]
+Quadruple cascade dangereuse parfaite
-[LOVE5]
-'ACCORTE ESCORTE!'
+[NOSTUC]
+Aucune cascade dangereuse réalisée
-[LOVE4_A]
-Merci beaucoup pour ces paquets, mais ils n'étaient qu'un leurre!
+[NOUNIF]
+Sauts uniques accomplis
-[LOVE4_B]
-Je suis désolé pour ça, mais c'est quelque fois comme ça dans les affaires.
+[NMISON]
+Tentatives de mission
-[LOVE4_C]
-Mon réel objectif se trouvait depuis le début caché à bord de l'avion.
+[PASDRO]
+Passagers perdus
-[LOVE4_F]
-J'avais graissé la patte aux autorités.
+[MONTAX]
+Total des courses en taxi
-[LOVE4_1]
-~r~Les Colombiens sont là!
+[DAYPLC]
+Dépenses quotidiennes de police
-[LOVE4_2]
-~g~Le paquet est parti! Suis les Colombiens et récupère-le!
+[CRIMRA]
+Taux de criminalité :
-[LOVE4_3]
-~g~Panlantic construction ?
+[STPR_1]
+Le Malibu
-[LOVE4_5]
-~g~Le paquet devrait être à bord de l'avion...
+[STPR_2]
+Imprimerie
-[LOVE4_6]
-~g~Prends l'ascenseur pour accéder au sommet de la tour!
+[STPR_3]
+Studio de cinéma
-[LOVE5_B]
-Mon ami oriental a besoin d'une escorte pour l'accompagner pendant l'authentification de ma dernière acquisition.
+[STPR_4]
+Usine de crème glacée
-[LOVE5_1]
-~g~Vas-y!
+[STPR_5]
+Concession automobile
-[LOVE5_2]
-~g~Tu vas avoir besoin d'une caisse!
+[STPR_6]
+Compagnie de taxis
-[LOVE5_3]
-~g~Passe devant et contrôle la sortie du tunnel!
+[STPR_7]
+Chantier naval
-[LOVE5_4]
-~r~Protège le camion!
+[SET1EN]
+Config. 1. Activée
-[RM6]
-'L'HOMME A ABATTRE!'
+[GMSAVE]
+Sauvegarder partie
-[RM6_A]
-T'as pas été suivi ? Parfait!
+[FEDS_TB]
+Retour
-[RM6_B]
-Ca y est! Je suis cuit, déjà mort, en quelque sorte!
+[FEST_OO]
+sur
-[RM6_D]
-J'ai un contrat sur ma tête, alors je me casse!
+[FEC_TUC]
+Commandes tourelle
-[RM6_E]
-Amène-moi à l'aéroport et t'auras un bon pourboire!
+[FEC_RS3]
+Faire défiler les stations de radio (touche L3)
-[RM6_666]
-Prends soin de ma Patriot blindée. On se verra à Miami, Ray!
+[FEC_HO3]
+Klaxonner (touche L3)
-[CAT1]
-'LA RANCON'
+[C_FAIL]
+Mission d'autodéfense terminée!
-[CAT2]
-'L'ECHANGE'
+[C_ESCP]
+~r~Le suspect s'est échappé!
-[CAT1_A]
-C'est moi qui ai Maria. Je pense pas que t'aies l'envie que son visage ressemble à un foie de veau trop faisandé, hein ?
+[C_VIGIL]
+BONUS AUTODEFENSE!
-[CAT2_F]
-Je me suis cassé un ongle et ma mise en plis est foutue! Tu le crois, ça ? Ca m'avait coûté 50 dollars!
+[HEAL_A]
+Ton niveau de ~h~santé~w~ s'affiche en orange en haut à droite de l'écran.
-[CAT2_G]
-J'étais complètement flippée, mais, je me suis dit, Maria, t'es une grande fille maintenant.
+[WRONGCD]
+Disque invalide. Insère le bon disque.
-[CAT2_H]
-Oh on va bien s'amuser, tu sais, parce que ma soeur, elle a dit qu'elle voulait venir s'installer avec nous, elle et ses deux gosses.
+[NOCD]
+Le compartiment à disque est vide. Insère un disque.
-[CAT2_I]
-Son mec a recommencé à aller voir ailleurs et...
+[OPENCD]
+Le compartiment à disque est ouvert. Referme-le.
-[CAT1_F]
-Rattrape Catalina avant la fin du temps imparti!
+[CDERROR]
+Erreur au cours de la lecture du DVD de Grand Theft Auto: Vice City
-[CAT_MON]
-~g~T'as pas encore assez d'argent. T'as besoin de 500 000$.
+[RESTART]
+Démarrage d'une nouvelle partie
-[BITCH_D]
-~g~Maria est morte!
+[GA_3]
+Plus de cadeaux. 100$ pour repeindre!
-[WEATHER]
-METEO AGITEE
+[GA_1]
+Oula! Je ne touche à rien d'aussi chaud, moi!
-[WEATHE2]
-METEO NORMALE
+[GA_1A]
+Reviens quand tu seras moins occupé...
-[8001]
-Tu as échoué lamentablement!
+[HELP9_C]
+Appuie sur la~h~ ~k~~PED_FIREWEAPON~ ~w~pour ~h~tirer~w~ avec le fusil à lunette.
-[1000]
-TU ES MORT
+[TAXI2]
+~r~Tu n'as plus le temps!
-[1001]
-TU ES MORT
+[PAGEB13]
+Santé livrée à la planque
-[1002]
-TU ES MORT
+[PAGEB14]
+Adrénaline livrée à la planque
-[1003]
-TU ES MORT
+[FESZ_CA]
+Annuler
-[1004]
-TU ES MORT
+[FES_NGA]
+Nouvelle partie
-[1005]
-CAPTURE!
+[FES_CAN]
+Annuler
-[1006]
-CAPTURE!
+[FESZ_QL]
+Toutes les étapes non sauvegardées de cette partie seront perdues. Charger la partie?
-[1007]
-CAPTURE!
+[FESZ_QD]
+Effacer cette sauvegarde?
-[1008]
-CAPTURE!
+[FESZ_QO]
+Ecraser cette sauvegarde?
-[1009]
-CAPTURE!
+[FESZ_QR]
+Veux-tu vraiment commencer une autre partie? Toutes les données depuis la dernière partie sauvegardée seront perdues. Continuer?
-[GA_4]
-Une voiture piégée coûte 1000$ pièce!
+[T4X4_1]
+'Terrain de jeu PCJ'
-[GA_5]
-Ta voiture est déjà équipée d'une bombe.
+[BMX_1]
+'Sélection par la boue'
-[GA_6] { re3 change }
-Gare-la, arme la bombe avec la ~h~touche ~k~~VEHICLE_FIREWEAPON~~w~ et CASSE-TOI!
+[BMX_2]
+'Piste d'essai'
-[GA_7] { re3 change }
-Arme la bombe avec la ~h~touche ~k~~VEHICLE_FIREWEAPON~~w~. Elle explose au démarrage.
+[BMXFAIL]
+~r~Tu n'as pas réussi à établir un nouveau record!
-[GA_8]
-Utilise le détonateur pour armer la bombe.
+[T4X4_3]
+'DANS LA POCHE!'
-[GA_9]
-Tu as récupéré ~1~ des 10 voitures spéciales.
+[MM_1]
+'Cônes en folie'
-[GA_10]
-Beau morceau. Voilà tes ~1~$.
+[T4X4_F]
+~r~Tu t'es barré! Trop dur pour toi?
-[GA_11]
-On en a déjà des comme ça. Ca nous sert à rien!
+[LANDSTK]
+Landstalker
-[GA_12]
-Bombe armée.
+[IDAHO]
+Idaho
-[GA_13]
-Comme un pro! Finis la liste et t'auras un bonus!
+[STINGER]
+Stinger
-[GA_14]
-Toutes les voitures! Parfait! Tiens, voilà un petit quelque chose!
+[LINERUN]
+Linerunner
-[GA_15]
-J'espère que t'aimes la nouvelle couleur!
+[PEREN]
+Perennial
-[GA_16]
-La peinture est en option!
+[SENTINL]
+Sentinelle
-[GA_19]
-Ce modèle, ça nous intéresse pas!
+[RIO]
+Rio
-[GA_20]
-On en a trop des comme ça! Désolé, mec.
+[PATRIOT]
+Patriote
-[CR_1]
-La grue ne peut pas soulever ce véhicule.
+[FIRETRK]
+Camion de pompier
-[PU_MONY]
-T'as pas assez d'argent.
+[TRASHM]
+Trashmaster
-[CO_ALL]
-Tu les as toutes eues. Tiens, voilà pour toi...
+[STRETCH]
+Stretch
-[PAUSED]
-PAUSE
+[MANANA]
+Manana
-[HEALTH1]
-Sors de là! T'es en pleine forme!
+[INFERNS]
+Infernus
-[HEALTH2]
-Coût des soins
+[VOODOO]
+Voodoo
-[HEALTH3]
-Je vais vous remettre sur pied!
+[PONY]
+Pony
-[HEALTH4]
-Ca fera 250$.
+[MULE]
+Mule
-[FEB_STA]
-Statistiques
+[CHEETAH]
+Cheetah
-[FEB_BRI]
-Briefings
+[AMBULAN]
+Ambulance
-[FEB_CON]
-Commandes
+[FBICAR]
+FBI Washington
-[FEB_AUD]
-Son
+[MOONBM]
+Moonbeam
-[FEB_DIS]
-Affichage
+[ESPERAN]
+Esperanto
-[FEB_LAN]
-Langue
+[TAXI]
+Taxi
-[FEP_STA]
-STATISTIQUES
+[WASHING]
+Washington
-[FEP_BRI]
-BRIEFINGS
+[BOBCAT]
+Bobcat
-[FEP_CON]
-COMMANDES
+[WHOOPEE]
+Mr Whoopee
-[FEP_AUD]
-SON
+[BFINJC]
+BF Injection
-[FEP_DIS]
-AFFICHAGE
+[HUNTER]
+Hunter
-[FEP_LAN]
-LANGUE
+[POLICAR]
+Police
-[FEF_ST1]
-C'est qui, le méchant ?
+[ENFORCR]
+Enforcer
-[FEF_ST2]
-T'as foutu un sacré merdier!
+[SECURI]
+Securicar
-[FEF_BR1]
-T'as perdu le fil de l'histoire ?
+[BANSHEE]
+Banshee
-[FEF_CO1]
-Tu veux prendre les commandes, c'est ça ?
+[PREDATR]
+Predator
-[FEF_CO2]
-Choisis la configuration qui correspond le mieux à ta façon de jouer.
+[BUS]
+Bus
-[FEF_SA1]
-Fais la queue!
+[RHINO]
+Rhino
-[FEF_SA2]
-Sauvegarde et charge tes parties
+[BARRCKS]
+Barracks OL
-[FEF_AU1]
-Fais péter la sono!
+[CUBAN]
+Cuban Hermes
-[FEF_AU2]
-Sélectionne une station de radio et des effets sonores
+[HELI]
+Hélicoptère
-[FEF_DI1]
-Change de partie!
+[DODO]
+Dodo
-[FEF_DI2]
-Configure le jeu pour ta télé pourrie!
+[COACH]
+Coach
-[FEF_LA1]
-Mais qu'est-ce que tu racontes ?
+[CABBIE]
+Cabbie
-[FEF_LA2]
-Do tu hablar Deutsh ?
+[STALION]
+Stallion
-[FEB_PMB]
-Briefings de mission précédents:
+[RUMPO]
+Rumpo
-[FEC_NA]
-Oups!
+[RCBANDT]
+RC Bandit
-[FEC_CWL]
-Montrer les armes à gauche
+[ROMERO]
+Corbillard de Romero
-[FEC_CWR]
-Montrer les armes à droite
+[PACKER]
+Packer
-[FEC_LOF]
-Regarder devant
+[ADMIRAL]
+Amiral
-[FEC_TAR]
-Cible
+[SQUALO]
+Squalo
-[FEC_MOV]
-Déplacement
+[SEASPAR]
+Sea Sparrow
-[FEC_CAM]
-Modes caméra
+[PIZZABO]
+Pizza Boy
-[FEC_PAU]
-Pause
+[GANGBUR]
+Gang Burrito
-[FEC_ENV]
-Monter dans un véhicule
+[TROPIC]
+Tropic
-[FEC_JUM]
-Sauter
+[SPEEDER]
+Speeder
-[FEC_ATT]
-Attaquer ou tirer
+[REEFER]
+Reefer
-[FEC_RUN]
-Courir
+[FLATBED]
+Flatbed
-[FEC_FPC]
-Vue subjective
+[YANKEE]
+Yankee
-[FEC_LL]
-Regarder à gauche
+[CADDY]
+Caddy
-[FEC_LB1]
-Regarder
+[ZEBRA]
+Taxi Zebra
-[FEC_LB2]
-derrière
+[TOPFUN]
+Top Fun
-[FEC_LB]
-Regarder derrière
+[SKIMMER]
+Skimmer
-[FEC_LR]
-Regarder à droite
+[PCJ600]
+PCJ 600
-[FEC_HOR]
-Klaxon
+[PHOENIX]
+Phoenix
-[FEC_VES]
-Commandes du véhicule
+[FAGGIO]
+Faggio
-[FEC_RSC]
-Chang. les stations de radio
+[FREEWAY]
+Freeway
-[FEC_BRA]
-Frein ou marche arrière
+[RCBARON]
+RC Baron
-[FEC_HAB]
-Frein à main
+[RCRAIDE]
+RC Raider
-[FEC_CAW]
-Arme du véhicule
+[GLENDAL]
+Glendale
-[FEC_ACC]
-Accélérateur
+[OCEANIC]
+Oceanic
-[FEC_SMT]
-Déclencheur de mission spéciale
+[SANCHEZ]
+Sanchez
-[FEA_OUT]
-Sortie audio:
+[SPARROW]
+Sparrow
-[FEA_ST]
-Stéréo
+[LOVEFIS]
+Love Fist
-[FEA_MNO]
-Mono
+[COASTG]
+Garde-côte
-[FEA_NON]
-Aucune
+[DINGHY]
+Dinghy
-[FEA_FM0]
-HEAD RADIO
+[HERMES]
+Hermes
-[FEA_FM1]
-DOUBLE CLEFF FM
+[SABRE]
+Sabre
-[FEA_FM2]
-JAH RADIO
+[SABRETU]
+Sabre Turbo
-[FEA_FM3]
-RISE FM
+[WALTON]
+Walton
-[FEA_FM4]
-LIPS 106
+[REGINA]
+Regina
-[FEA_FM5]
-GAME FM
+[COMET]
+Comet
-[FEA_FM6]
-MSX FM
+[DELUXO]
+Deluxo
-[FEA_FM7]
-FLASHBACK 95.6
+[BURRITO]
+Burrito
-[FEA_FM8]
-CHATTERBOX 109
+[SPAND]
+Spandex Express
-[FED_DBG]
-Menu Debug
+[MARQUIS]
+Marquis
-[FEM_MCM]
-Menu memory card
+[BAGGAGE]
+Bagagiste
-[FEM_RMC]
-Enregistrer memory card 1
+[KAUFMAN]
+Taxi Kaufman
-[FEM_TFM]
-Test memory card 1 formatée
+[COASTMA]
+Garde-côte Maverick
-[FEM_TUM]
-Test memory card 1 non formatée
+[MAVERIC]
+Maverick
-[FEM_CRD]
-Créer rép. racine
+[RANCHER]
+Rancher
-[FEM_CLI]
-Créer et charger des icones
+[FBIRANC]
+FBI Rancher
-[FEM_FFF]
-Remplir le premier fichier de conneries
+[VIRGO]
+Virgo
-[FEM_SOG]
-Sauvegarder uniquement la partie
+[GREENWO]
+Greenwood
-[FEM_CES]
-Vérifier chaque sauvegarde de 0kb4
+[HOTRING]
+Hotring Racer
-[FEM_STG]
-Sauvegarder la partie
+[BLISTAC]
+Blista Compact
-[FEM_STS]
-Sauvegarder la partie sous le nom GTA3
+[FEST_DF]
+Dist. parcourue à pied (miles)
-[FEM_CPD]
-Créer un répertoire protégé contre les copies
+[FEST_DC]
+Dist. parcourue en voiture (miles)
-[FEM_MC2]
-Menu memory card 2
+[FESTDFM]
+Distance parcourue à pied (m)
-[FEM_TS]
-Test de sauvegarde :
+[FESTDCM]
+Distance parcourue en voiture (m)
-[FEM_TL]
-Test de chargement :
+[TOT_DIS]
+Distance totale parcourue (miles)
-[FEM_TD]
-Test de suppression :
+[TOTDISM]
+Distance totale parcourue (m)
-[PL_STAT]
-Statistiques du joueur
+[DISTHEL]
+Dist. parcourue en hélicoptère (miles)
-[PE_WAST]
-Victimes
+[DISTHEM]
+Dist. parcourue en hélicoptère (m)
-[PE_WSOT]
-Personnes tuées par d'autres
+[DISTBOA]
+Dist. parcourue en bateau (miles)
-[CAR_EXP]
-Véhicules détruits
+[DISTBOM]
+Dist. parcourue en bateau (m)
-[TM_BUST]
-Nb de fois capturé
+[FEST_LS]
+Personnes secourues en ambulance
-[M_WASTE]
-Hommes tués
+[FEST_CC]
+Criminels tués lors de la mission d'autodéfense
-[F_WASTE]
-Femmes tuées
+[FEST_FE]
+Nombre total de feux éteints
-[PIG_WST]
-Flics tués
+[FEST_RP]
+Rodéos réussis
-[GNG_WST]
-Gangsters tués
+[FEST_MP]
+Missions réussies
-[MED_WST]
-Toubibs tués
+[FEST_BB]
+Les fous du volant :
-[FIRE_WS]
-Pompiers tués
+[FEST_H0]
+Nombre maximum de points de passage
-[DED_CRI]
-Criminels tués
+[FEST_GC]
+Nombre total de voitures de gang :
-[DED_DED]
-Parasites tués
+[FEST_H1]
+Destruction de diablo
-[DED_HOK]
-Putes tuées
+[FEST_H2]
+Massacre de la Mafia
-[HEL_DST]
-Hélicoptères détruits
+[FEST_H3]
+Le désastre du casino
-[PER_COM]
-Pourcentage accompli
+[FEST_H4]
+Le destructeur de Rumpo
-[KGS_EXP]
-Kilos d'explosif utilisés
+[USJ]
+BONUS POUR CASCADE UNIQUE!
-[ACCURA]
-Précision
+[RATNG1]
+Citoyen honnête
-[ELBURRO]
-Meilleur temps en sec.
+[RATNG2]
+Quidam
-[CAR_CRU]
-Véhicules défoncés
+[RATNG3]
+Eboueur
-[HED_EX]
-Têtes explosées
+[RATNG4]
+Voleur à l'étalage
-[TM_DED]
-Visites à l'hôpital
+[RATNG5]
+Vandale
-[DAYSPS]
-Jours de jeu
+[RATNG6]
+Escroc
-[MMRAIN]
-Mm de pluie tombés
+[RATNG7]
+Pickpocket
-[MXCARD]
-Distance max. de sauts dangereux (pieds)
+[RATNG8]
+Cleptomane
-[MXCARJ]
-Hauteur max de sauts dangereux (pieds)
+[RATNG9]
+Mouchard
-[MXCARDM]
-Distance max. de sauts dangereux (m)
+[RATNG10]
+Rat
-[MXCARJM]
-Hauteur max de sauts dangereux (m)
+[RATNG11]
+Sangsue
-[MXFLIP]
-Saltos max. de sauts dangereux
+[RATNG12]
+Le roi de l'arnaque
-[MXJUMP]
-Rotation max. de sauts dangereux
+[RATNG13]
+Aigrefin
-[BSTSTU]
-Meilleures cascades jusqu'à maintenant:
+[RATNG14]
+Grippe-sou
-[INSTUN]
-Cascade dangereuse
+[RATNG15]
+Crapule
-[PRINST]
-Cascade dangereuse parfaite
+[RATNG16]
+Rascal
-[DBINST]
-Double cascade dangereuse
+[RATNG17]
+Racaille
-[DBPINS]
-Double cascade dangereuse parfaite
+[RATNG18]
+Garnement
-[TRINST]
-Triple cascade dangereuse
+[RATNG19]
+Vaurien
-[PRTRST]
-Triple cascade dangereuse parfaite
+[RATNG20]
+Hors-la-loi
-[QUINST]
-Quadruple cascade dangereuse
+[RATNG21]
+Voyou
-[PQUINS]
-Quadruple cascade dangereuse parfaite
+[RATNG22]
+Lâche
-[NOSTUC]
-Aucune cascade dangereuse accomplie
+[RATNG23]
+Idiot SA
-[NOUNIF]
-Sauts uniques accomplis
+[RATNG24]
+Idiot
-[NOUNGM]
-Total sauts uniques
+[RATNG25]
+Récidiviste
-[NMISON]
-Missions commencées
+[RATNG26]
+Ancien taulard
-[NMMISP]
-Missions réussies
+[RATNG27]
+Criminel
-[PASDRO]
-Passagers perdus
+[RATNG28]
+Clochard
-[MONTAX]
-Total courses en taxi
+[RATNG29]
+Sage
-[DAYPLC]
-Dépenses quotidiennes de police
+[RATNG30]
+Pilote
-[CRIMRA]
-Taux de criminalité
+[RATNG31]
+Gros bras
-[GMSTOR]
-Magasin du jeu
+[RATNG32]
+Tueur à gages
-[PREBRF]
-Briefings précédents
+[RATNG33]
+Chasseur de tête
-[CNTLS]
-Commandes
+[RATNG34]
+Force de l'ordre
-[MUSMEN]
-Musique/Effets
+[RATNG35]
+Ronin
-[GAMSET]
-Paramètres du jeu
+[RATNG36]
+Magouilleur
-[LANGUA]
-Langue
+[RATNG37]
+Tueur
-[DSPLAY]
-Affichage
+[RATNG38]
+Associé
-[DEBUGM]
-Menu Debug
+[RATNG39]
+Boucher
-[QUITOP]
-Options de fin
+[RATNG40]
+Nettoyeur
-[CONTRL]
-Configuration des manettes
+[RATNG41]
+Assassin
-[SET1EN]
-Config 1. activée
+[RATNG42]
+Conseiller
-[SET1]
-Config 1.
+[RATNG43]
+Autodidacte
-[SET2EN]
-Config 2. activée
+[RATNG44]
+Bras droit
-[SET2]
-Config 2.
+[RATNG45]
+Exécutant
-[SET3EN]
-Config 3. activée
+[RATNG46]
+Lieutenant
-[SET3]
-Config 3.
+[RATNG47]
+Sous-chef
-[SET4EN]
-Config 4. activée
+[RATNG48]
+Capo
-[SET4]
-Config 4.
+[RATNG49]
+Patron
-[GOBACK]
-Retour
+[RATNG50]
+Noops
-[SOUND]
-AUDIO
+[RATNG51]
+Don
-[MUSVOL]
-Volume de la musique
+[RATNG52]
+Roi de la putain de ville
-[SFXVOL]
-Volume des effets
+[PAGE_00]
+.
-[SCROPT]
-OPTIONS D'AFFICHAGE
+[WELCOME]
+BIENVENUE A
-[CTRSCR]
-Centrer l'écran
+[TSCORE]
+REVENUS : ~1~$
-[SCRFOR]
-Format d'écran
+[PBOAT_2] { reVC update }
+Appuie sur la ~h~~k~~VEHICLE_FIREWEAPON~~w~ pour tirer avec les canons du bateau.
-[GMSVLQ]
-SAUVEGARDER-CHARGER-QUITTER
+[HJSTAT]
+Distance : ~1~.~1~ m Hauteur : ~1~.~1~ m Saltos : ~1~ Rotation : ~1~_
-[GMREST]
-Recommencer
+[HJSTATW]
+Distance : ~1~.~1~ m Hauteur : ~1~.~1~ m Saltos : ~1~ Rotation : ~1~_ Et quelle belle réception!
-[NOGMSV]
-Tu ne peux sauvegarder que depuis ta planque.
+[ATUTOR]
+Appuie sur la ~h~~k~~TOGGLE_SUBMISSIONS~~w~ pour activer ou désactiver les missions ambulance.
-[DLFILE]
-Supprimer les fichiers de GTA3
+[FEST_HA]
+Mission ambulance, niveau maximum
-[CHFILE]
-CHOISIR LE FICHIER A CHARGER
+[C_KILLS]
+CRIMINELS TUES : ~1~
-[CHFIDL]
-CHOISIR LE FICHIER A SUPPRIMER
+[HJSTATF]
+Distance : ~1~ ft Hauteur : ~1~ ft Saltos : ~1~ Rotation : ~1~_
-[SVCONF]
-CONFIRMER SAUVEGARDE
+[HJSTAWF]
+Distance : ~1~ ft Hauteur : ~1~ ft Saltos : ~1~ Rotation : ~1~_ Et quelle belle réception!
-[SVFNAM]
-Le nom du fichier de sauvegarde est
+[CRED001]
+ROCKSTAR NORTH
-[SAVEDN]
-Erreur. Echec de la sauvegarde.
+[CRD001A]
+DIRECTEUR DU STUDIO
-[LANGSL]
-CHOIX DE LA LANGUE
+[CRD001B]
+ANDREW SEMPLE
-[ENGLIS]
-Anglais
+[CRED002]
+PRODUCTEUR
-[GERMAN]
-Allemand
+[CRD002A]
+DIRECTEUR DU DEVELOPPEMENT
-[ITALIA]
-Italien
+[CRED003]
+LESLIE BENZIES
-[FRENCH]
-Français
+[CRED004]
+CONCEPTEUR GRAPHIQUE
-[SPAIN]
-Espagnol
+[CRED005]
+AARON GARBUT
-[BGWHON]
-Big White Debug Light Switched On
+[CRED006]
+DIRECTEURS TECHNIQUES
-[BGWOFF]
-Big White Debug Light Switched Off
+[CRED007]
+OBBE VERMEIJ
-[PRVMEN]
-Briefings de mission précédents
+[CRED008]
+ADAM FOWLER
-[DOSVGM]
-Tu veux sauvegarder la partie ?
+[CRED010]
+ANDREW DUTHIE
-[FORMEN]
-Menu formatage
+[CRED011]
+CRAIG FILSHIE
-[MEMTST]
-Ecran de test memory card
+[CRED012]
+WILLIAM MILLS
-[REGCAR]
-Enregistrer memory card 1
+[CRED013]
+CHRIS ROTHWELL
-[TEFONE]
-Test memory card 1 formatée
+[CRD013A]
+IMRAN SARWAR
-[TEUFON]
-Test memory card 1 non formatée
+[CRD013B]
+JAMES WORRALL
-[CRROOT]
-Créer rép. racine
+[CRD013C]
+JOHN HAIME
-[CRLDIC]
-Créer et charger des icones
+[CRED014]
+ECRIT PAR
-[FLFSGF]
-Remplir le premier fichier de conneries
+[CRED015]
+JAMES WORRALL
-[PUSAVE]
-Sauvegarder uniquement la partie
+[CRED016]
+PAUL KUROWSKI
-[CHEVOK]
-Vérifier chaque sauvegarde de 0kb4
+[CRED017]
+DAN HOUSER
-[SVGMON]
-Sauvegarder
+[CRED018]
+CONCEPTEUR PRINCIPAL DES PERSONNAGES
-[CNTSAV]
-Sauvegarde impossible. Tu es en mission.
+[CRD018A]
+CONCEPTEUR DES PERSONNAGES
-[CNCSAV]
-Sauvegarde impossible. Tu es en voiture.
+[CRED019]
+IAN MCQUE
-[CRMGSV]
-Créer un répertoire protégé contre les copies
+[CRD019A]
+TOKS SOLARIN
-[MGSVCN]
-Répertoire créé
+[CRD019B]
+ALAN DAVIDSON
-[MGSVNC]
-Répertoire non créé
+[CRED020]
+ANIMATEUR PRINCIPAL
-[YES]
-Oui
+[CRED021]
+ALEX HORTON
-[NO]
-Non
+[CRD022A]
+ANIMATEURS
-[X]
-x
+[CRED022]
+LEE MONTGOMERY
-[LAST]
-Dernier message.
+[CRD022B]
+DUNCAN SHIELDS
-[FEDS_XB]
-Choisir
+[CRD022C]
+GUS BRAID
-[FEDS_ST]
-touche START - REPRENDRE
+[CRED023]
+CONCEPTEURS DES VEHICULES
-[FEST_OO]
-sur
+[CRD023A]
+JOLYON ORME
-[FEC_TUC]
-Commandes tourelle
+[CRD023B]
+ALAN DUNCAN
-[FEC_SM3]
-Déclencheur mission spéciale (touche R3)
+[CRD024A]
+CONCEPTEUR PRINCIPAL DES VEHICULES
-[FEC_RS3]
-Chang. les stations de radio (touche L3)
+[CRED024]
+PAUL KUROWSKI
-[FEC_HO3]
-Klaxonner (touche L3)
+[CRED025]
+CONCEPTEURS DE CARTE
-[DIAB1]
-'TOURISME'
+[CRED026]
+ADAM COCHRANE
-[DIAB2]
-'DE LA GLACE, T'ES REFROIDI'
+[CRED027]
+NIK TAYLOR
-[DIAB3]
-'JUGÉ PAR LE FEU'
+[CRED028]
+GARY MCADAM
-[DIAB4]
-'STAR DU X'
+[CRED029]
+KEIRAN BAILLIE
-[DIAB1_A]
-El Burro veut te donner une chance. Va à la cabine téléphonique de Hauteurs de Hepburn si tu veux plus d'infos.
+[CRED030]
+ALISDAIR WOOD
-[DIAB1_C]
-Tu t'es bien défendu. Retourne à la cabine et El Burro aura peut-être du boulot pour toi.
+[CRED031]
+ANDREW SOOSAY
-[DIAB1_1]
-~g~3..2..1..GO GO GO!
+[CRD031A]
+STEVEN MULHOLLAND
-[DIAB1_4]
-~g~Trouve une voiture rapide et va sur la grille de départ.
+[CRD031B]
+WAYLAND STANDING
-[DIAB1_3]
-~r~Tu ne pourrais même pas gagner à une tombol, blaireau!
+[CRD031C]
+CAMPBELL J. DICK
-[DIAB1_2]
-~g~Félicitations tu as gagné, avec un temps incroyable de ~1~ secondes
+[CRD031D]
+CONCEPTEUR GRAPHIQUE
-[FIRST]
-~g~1er
+[CRD031E]
+STUART PETRI
-[SECOND]
-~g~2e
+[CRED032]
+PROGRAMMEUR PRINCIPAL
-[THIRD]
-~g~3e
+[CRD032A]
+PROGRAMMEURS
-[FOURTH]
-~g~4e
+[CRED033]
+ALEXANDER ROGER
-[DIAB2_1]
-~g~Va prendre la malette à Harwood.
+[CRED034]
+GRAEME WILLIAMSON
-[DIAB2_2]
-~g~Trouve une camionnette de vendeur de glaces.
+[CRED035]
+BARANE CHAN
-[DIAB2_3]
-~g~Gare la camionette à Atlantic Quays.
+[CRED036]
+DEREK PAYNE
-[DIAB2_4]
-~g~Appuie sur la ~w~touche ~k~~VEHICLE_HORN~ ~g~pour actionner la clochette.
+[CRED037]
+GORDON YEOMAN
-[DIAB2_6]
-~g~Appuie sur la ~w~touche ~k~~VEHICLE_HORN~ ~g~pour actionner la clochette.
+[CRD037A]
+ALAN CAMPBELL
-[DIAB2_7]
-~g~Appuie sur la ~w~touche ~k~~VEHICLE_HORN~ ~g~pour actionner la clochette.
+[CRD037B]
+MARK HANLON
-[DIAB2_5]
-~g~Sors de la camionette et sers-toi de la télécommande pour faire exploser la camionnette.
+[CRD037C]
+ANDRZEJ MADAJCZYK
-[YD1]
-'LES FOUS DU VOLANT'
+[CRED038]
+PRODUCTEUR MUSIQUE PRINCIPAL
-[YD2]
-'TOUS A L'UZI'
+[CRED039]
+CRAIG CONNER
-[YD3]
-'LA VALSE DES VOITURES'
+[CRED040]
+STUART ROSS
-[YD4]
-'A NOUS LE ROYAUME'
+[CRED041]
+INGENIEUR AUDIO PRINCIPAL
-[YD_P]
-King Courtney voudrait te dire un mot. Va à la cabine d'Aspatria!
+[CRED042]
+ALLAN WALKER
-[YD1_A]
-~w~Voila King Courtney.
+[CRD041A]
+INGENIEUR DU SON
-[YD1_A1]
-~w~Mon gang de Yardies aurait besoin d'un bon chauffeur et t'as une réputation de rapide.
+[CRD041B]
+AUDIO
-[YD1_B]
-~w~Va à la décharge en face du stade et attends les autres joueurs.
+[CRD042A]
+WILL MORTON
-[YD1_C]
-~w~J'ai des gars qui surveillent tous les points de passage de Staunton.
+[CRED043]
+PROGRAMMEUR AUDIO
-[YD1_D]
-~w~Le premier pilote qui franchit un point de passage gagne 1000$ et ainsi de suite.
+[CRED044]
+RAYMOND USHER
-[YD1_D1]
-~w~Si tu passes plus de checkpoints que tous les autres pilotes, j'aurais peut-être du boulot pour toi.
+[CRED045]
+RESPONSABLE DES TESTS
-[YD1_E]
-~g~Prépare-toi à partir!
+[CRED046]
+CRAIG ARBUTHNOTT
-[YD1_F]
-~g~T'as foncé dès le départ. J'adore ton style!
+[CRED047]
+RESPONSABLE CQ
-[YD1_G]
-~r~C'est une course de bagnoles. T'as besoin d'une bagnole, patate!
+[CRED048]
+NEIL CORBETT
-[YD1GO]
-~g~GO!
+[CRED049]
+KEVIN WONG
-[YD1_1]
-~r~1
+[CRED050]
+CQ
-[YD1_2]
-~r~2
+[CRED051]
+DAVID BEDDOES
-[YD1_3]
-~r~3
+[CRED052]
+DAVID WATSON
-[YD1_BON]
-1000$!
+[CRED053]
+BARRY CLARK
-[Y1_1ST]
-~g~T'es arrivé premier en franchissant ~1~ points de passage!
+[CRED054]
+ROSS SPARROW
-[Y1_2ND]
-~y~2e avec ~1~ points de passage gagnants. ~y~Pas mal, mais t'es pas le meilleur.
+[CRED055]
+JAMES ALLAN
-[Y1_3RD]
-~r~3e avec ~1~ points de passage gagnants. ~r~Je croyais que t'étais bon!
+[CRED056]
+NEIL MEIKLE
-[Y1_LAST]
-~r~Tu es le dernier! ~r~Tu m'as fait perdre mon temps, imbécile!
+[CRD056A]
+GEORGE WILLIAMSON
-[Y1_J1ST]
-~y~1er ex aequo avec ~1~ points de passage gagnants. ~y~C'est bien, mais tu dois être le meilleur pour courir sur Queen lizzy!
+[CRD056B]
+MATT JONES
-[Y1_J2ND]
-~r~2e ex aequo avec ~1~ points de passage gagnants. Tu conduis comme un vieux singe dingo!
+[CRD056C]
+ROB HARBOUR
-[Y1JLAST]
-~r~Dernier ex æquo! Tu parles comme un pilote, mais tu pilotes comme un beau-parleur!
+[CRD056D]
+TOM WHITTAKER
-[Y1_TEST]
-VOITURE A L'EAU!
+[CRED057]
+ASSISTANCE TECHNIQUE PRINCIPALE
-[YD2_A]
-~w~J'ai besoin de voir si tu peux faire mon sale boulot.
+[CRED058]
+LORRAINE ROY
-[YD2_A1]
-~w~Faut voir si on peut te faire confiance.
+[CRD057A]
+ASSISTANCE TECHNIQUE
-[YD2_B]
-~w~Deux de mes gars seront là-bas dans peu de temps pour te faire faire un tour,
+[CRED059]
+CHRISTINE CHALMERS
-[YD2_B1]
-~w~histoire de voir si tu vaux quelque chose...
+[CRD060A]
+SERVICES GENERAUX
-[YD2_C]
-~w~On va aller faire un tour à Hauteurs de Hepburn, flingue-nous quelques Diablos qui font des misères à Queen Lizzy.
+[CRD060B]
+KIM GURNEY
-[YD2_CC]
-~w~Tiens, t'auras besoin d'un calibre.
+[CRD060C]
+CASSIE OLIVER
-[YD2_D]
-~w~Tu conduis et tu tires. On s'arrangera pour que tu te fasses pas descendre.
+[CRED060]
+ROCKSTAR NEW YORK
-[YD2_E]
-~w~Allons-y!!
+[CRED061]
+PRODUCTEUR EXECUTIF
-[YD2_F]
-~r~Il nous a échappé, colle-lui au cul!!!
+[CRED062]
+SAM HOUSER
-[YD2_G1]
-~w~Hauteurs de Hepburn... On va se farcir quelques Diablos de malheur...
+[CRED063]
+PRODUCTEUR
-[YD2_G2]
-~w~Mais n'oublie pas, ~r~tu restes dans la bagnole!!
+[CRED064]
+DAN HOUSER
-[YD2_H]
-~w~OK, ramène-nous sur le territoire des Yardies! Allez, FONCE!
+[CRED065]
+VICE-PRESIDENT DU DEVELOPPEMENT
-[YD2_L]
-~w~Tu t'es bien débrouillé, le bourreau.
+[CRED066]
+JAMIE KING
-[YD2_M]
-~r~Il a bousillé ma bagnole! Descends-le!
+[CRED067]
+RESPONSABLE TECHNOLOGIE
-[YD2_N]
-~w~Ramène ta fraise dans cette bagnole!
+[CRED068]
+GARY J. FOREMAN
-[YD3_A]
-Je veux que tu piques quelques bagnoles de gangs
+[CRED069]
+PRODUCTEUR ASSOCIE
-[YD3_A1]
-comme ça, on pourra faire un carton chez nos ennemis.
+[CRED070]
+JEREMY POPE
-[YD3_B]
-Je veux une Sentinelle de la Mafia,
+[CRD071A]
+RESPONSABLE CONTROLE QUALITE
-[YD3_B1]
-une Stinger des Yakuzas et une
+[CRD072A]
+JEFF ROSA
-[YD3_B2]
-Stallion des Diablos comme ça, on pourra frapper dans tous les gangs de Liberty.
+[CRED071]
+RESPONSABLE MUSIQUE
-[YD3_C]
-Tu les amènes au garage de Newport et souviens-toi,
+[CRED072]
+TERRY DONOVAN
-[YD3_C1]
-elles ne nous sont utiles qu'en bon état!
+[CRED073]
+EQUIPE DE PRODUCTION
-[YD3_D]
-Spare text label
+[CRED074]
+TERRY DONOVAN
-[YD3_E]
-~r~Tu as déjà piqué une voiture des Diablos!
+[CRED075]
+JENNIFER KOLBE
-[YD3_F]
-~r~Tu as déjà piqué une voiture de la Mafia!
+[CRED076]
+JENEFER GROSS
-[YD3_G]
-~r~Tu as déjà piqué une voiture des Yazukas!
+[CRED077]
+LAURA PATERSON
-[YD3_H]
-~g~Bagnole des Diablos chourrée!
+[CRED078]
+JEFF CASTANEDA
-[YD3_I]
-~g~Bagnole de la Mafia chourrée!
+[CRED079]
+JERONIMO BARRERA
-[YD3_J]
-~g~Bagnole des Yasukas chourrée!
+[CRED080]
+CARLY SLATER
-[YD3_K]
-~r~La bagnole est presque une épave! Fais-la réparer!
+[CRED081]
+JUNG KWAK
-[YD3_L]
-Emmène-la au garage!
+[CRED082]
+BRIAN WOOD
-[YD3_M]
-~r~T'as fait un tonneau avec! Va en chercher une autre!
+[CRED083]
+RENAUD SEBANNE
-[YD4_A]
-Ecoute-moi bien!
+[CRED084]
+RICHARD KRUGER
-[YD4_A1]
-Tu vas aller à Bedford Point.
+[CRD084A]
+DANIEL EINZIG
-[YD4_A2]
-Il y a de la came dont j'ai besoin rapidos dans une vieille bagnole!
+[CRD084B]
+JACEN BURROWS
-[YD4_B]
-LETTRE : je sais que tu es très occupé. Eh bien moi aussi, je suis très occupée.
+[CRD084C]
+LINN PR
-[YD4_C]
-Je pense qu'il est temps que tu te rendes compte de ce que c'est, de la SPANK! Catalina, Bisous.
+[CRD084D]
+COUVERTURE
-[YD4_D]
-PS : CREVE SALE CHIEN, CREVE!
+[CRD084E]
+STEPHEN BLISS
-[YD4_1]
-Des drogués défoncés !
+[CRED085]
+KENT PAUL'S 80 NOSTALGIA ZONE
-[YD4_2]
-Détruis les camionnettes de SPANK !!
+[CRED086]
+ECRIT PAR DAN HOUSER
-[HM_1]
-'DESCENTE A L'UZI'
+[CRD086A]
+PRODUIT PAR ADAM TEDMAN
-[HM_2]
-'BUGGY FAIT DES RAVAGES'
+[CRED087]
+WWW.KENTPAUL.COM ET WWW.VICECITY.COM
-[HM_3]
-'VOITURE PIEGEE'
+[CRED088]
+CREES PAR
-[HM_5]
-'LA RIXE'
+[CRD088A]
+ADAM TEDMAN
-[HOOD1_A]
-Va à la cabine dans Wichita Gardens et on parlera affaires.
+[CRD088B]
+DAVID YU
-[HM1_A]
-Salut! C'est D-Ice des Red Jacks!
+[CRD088C]
+JERRY LUNA
-[HM1_C]
-Ces jeunes cons, ils viennent dans la rue et ils ont qu'une idée en tête, la SPANK et les flingues.
+[CRD088D]
+STUART PETRI
-[HM1_3]
-~g~Les 'Nines' font leur business dans Wichita Gardens.
+[CRD088E]
+MICHAEL CARNEVALE
-[HM2_3]
-Si tu touches les roues d'une bagnole, le buggy télécommandé explosera!
+[CRD088F]
+GREG LAU
-[HM2_4]
-Si le buggy télécommandé est hors de portée, il explosera!
+[CRD088G]
+FUTABA HAYASHI
-[HM2_5]
-~r~Hors de portée!
+[CRED089]
+RESPONSABLE CQ
-[HM3_1]
-~g~Va au garage mais fais gaffe, si tu brusques trop la bagnole, elle va exploser!
+[CRED090]
+CRAIG ARBUTHNOTT
-[HM3_2]
-~g~Ramène la voiture en parfait état, pas de grabuge!
+[CRED091]
+ANALYSTE PRINCIPAL
-[HM3_3]
-~g~Fais réparer la voiture!
+[CRED092]
+ADAM DAVIDSON
-[HM4_D]
-~g~Trouve une caisse!
+[CRD092A]
+JOE HOWELL
-[HM4_E]
-TEXT NO LONGER REQUIRED
+[CRD092B]
+MARC FERNANDEZ
-[HM4_1]
-~g~Va à l'endroit où la cargaison est tombée, tu dois ramasser 30 lingots.
+[CRED093]
+ANALYSTE DE JEU
-[HM4_2]
-~g~Souviens-toi que quand la bagnole est trop chargée, elle se traîne alors quand c'est le cas, fonce au garage pour livrer la marchandise.
+[CRED094]
+RICHARD HUIE
-[HM5_3]
-~r~On t'a dit de te servir d'une batte de baseball et c'est tout!
+[CRED095]
+EQUIPE DE TEST CHEZ ROCKSTAR
-[HM5_4]
-~r~Ton contact est mort!
+[CRED096]
+LANCE WILLIAMS
-[MEA1]
-'L'ESCROC'
+[CRED097]
+JOE GREENE
-[MEA2]
-'LES BRAQUEURS'
+[CRED098]
+BRIAN PLANER
-[MEA3]
-'LA FEMME'
+[CRD098A]
+ELIZABETH SATTERWHITE
-[MEA4]
-'SON AMANT'
+[CRD098B]
+JAMEEL VEGA
-[MEAT1_A]
-Un ami m'a dit que tu pouvais régler certains de mes problèmes. Si tu penses que tu peux m'aider, va à la cabine de Trenton.
+[CRD098C]
+MIKE HONG
-[MEA1_B3]
-~g~Va voir le banquier.
+[CRED099]
+LEE CUMMINGS
-[MEA1_B6]
-~g~Amène la voiture à la casse pour se débarrasser des preuves. Une fois sur place, sors de la voiture et laisse faire la grue!
+[CRED100]
+HISTOIRE
-[MEA1_1]
-~r~Le banquier est mort!
+[CRED101]
+JAMES WORRALL
-[MEA1_2]
-~r~On t'a dit d'écrabouiller la voiture!
+[CRED102]
+DAN HOUSER
-[MEA1_3]
-~g~Sors de la bagnole!
+[CRED103]
+ADAM TEDMAN
-[MEA1_4]
-~r~T'as laissé le banquier derrière toi!
+[CRED104]
+PAUL YEATES
-[MEA2_B3]
-~g~Va voir les braqueurs.
+[CRED105]
+JENEFER GROSS
-[MEA2_B4]
-~g~Amène-les à l'usine de pâtée pour chiens.
+[CRED106]
+LAURA PATERSON
-[MEA2_B6]
-~g~Fais repeindre la voiture, comme ça y'aura pas de preuve.
+[CRED107]
+CINEMATIQUES
-[MEA2_1]
-~r~On t'a dit d'écrabouiller la voiture!
+[CRED108]
+ECRITES PAR DAN HOUSER ET JAMES WORRALL
-[MEA2_2]
-~r~Un braqueur est mort!
+[CRED109]
+DIRECTION DE L'AUDIO PAR DAN HOUSER ET NAVID KHONSARI
-[MEA2_4]
-~r~T'as laissé un des braqueurs derrière toi!
+[CRED110]
+PRODUCTION DE JAMIE KING
-[MEA3_B3]
-~g~Va chercher Mme Chonks.
+[CRD110A]
+CASTING : JAMIE KING, SEAN MACALUSO
-[MEA3_B6]
-~g~Prends la voiture et fous-la à l'eau, comme ça y'aura pas de preuve.
+[CRED111]
+DISTRIBUTION
-[MEA3_1]
-~r~La femme est morte!
+[CRD111A]
+PERSONNAGES SECONDAIRES
-[MEA3_2]
-~r~Tu étais censé balancer la bagnole à la mer!
+[CRED112]
+TOMMY VERCETTI : RAY LIOTTA
-[MEA3_3]
-~r~T'as laissé sa femme derrière!
+[CRED113]
+KEN ROSENBERG : WILLIAN FICHTNER
-[MEA4_B3]
-~g~Va chercher l'amant de sa femme.
+[CRED114]
+SONNY FORELLI : TOM SIZEMORE
-[MEA4_B6]
-C'est beaucoup trop tard, Marty. Je t'ai donné une chance, mais maintenant je reprends tout en charge!
+[CRED115]
+STEVE SCOTT : DENNIS HOPPER
-[MEA4_1]
-~r~Carlos est mort!
+[CRED116]
+AVERY CARRINGTON : BURT REYNOLDS
-[MEA4_3]
-~r~T'as laissé Carlos l'usurier derrière!
+[CRED117]
+RICARDO DIAZ : LUIS GUZMAN
-[LOOK_A]
-Appuie et maintiens enfoncée la ~h~touche ~k~~VEHICLE_LOOKLEFT~ ~w~ou ~h~touche ~k~~VEHICLE_LOOKRIGHT~ ~w~ pour regarder ~h~à gauche~w~ ou ~h~à droite~w~ quand tu es en voiture. Appuie sur ces deux touches pour regarder ~h~derrière~w~.
+[CRED118]
+LANCE VANCE : PHILIP MICHAEL THOMAS
-[LOVE6_1]
-~g~Maintenant, attire les flics loin de l'entrepôt!
+[CRED119]
+COLONEL JUAN CORTEZ : ROBERT DAVI
-[LOVE6_2]
-~r~T'as pas réussi à attirer les flics assez loin!
+[CRED120]
+UMBERTO ROBINA : DANNY TREJO
-[RM4_3]
-~r~L'associé de Ray s'est échappé!
+[CRED121]
+PHIL CASSIDY : GARY BUSEY
-[RM6_C]
-La CIA semble s'intéresser de près à la SPANK.
+[CRED122]
+MITCH BAKER : LEE MAJORS
-[RM6_C1]
-Et elle n'aime pas qu'on cherche des noises au Cartel.
+[CRED123]
+MERCEDES CORTEZ : FAIRUZA BALK
-[C_PASS]
-MENACE ENRAYEE!
+[CRED124]
+KENT PAUL : DANNY DYER
-[CTUTOR]
-Appuie sur la ~h~touche ~k~~TOGGLE_SUBMISSIONS~~w~ pour activer ou désactiver les missions de caisse.
+[CRED125]
+JEZZ TORRENT : KEVIN MCKIDD
-[CTUTOR2]
-Appuie sur la ~h~touche ~k~~TOGGLE_SUBMISSIONS~~w~ pour activer ou désactiver les missions de caisse.
+[CRED126]
+REGULATRICE TAXI : DEBORAH HARRY
-[COPCART]
-~g~Tu as ~1~ secondes pour retourner à une voiture de police avant que la mission ne s'achève.
+[CRED127]
+CANDY SUXX : JENNA JAMESON
-[C_FAIL]
-Mission de caisse terminée!
+[CRED128]
+BJ SMITH : LAWRENCE TAYLOR
-[C_CANC]
-~r~Mission de caisse annulée!
+[CRED129]
+TATA POULET : YOUREE CLEOMILI HARRIS
-[C_ESCP]
-~r~Le suspect s'est échappé!
+[CRED130]
+FOURNISSEUR : ARMANDO RIESCO
-[C_TIME]
-~r~Ta carrière de flic est terminée!
+[CRED131]
+COUGAR : BLAYNE PERRY
-[C_VIGIL]
-BONUS POLICE!
+[CRED132]
+HILARY : CHARLES TUCKER
-[A_FAIL2]
-~r~Ton manque de précipitation a été fatal pour le patient!
+[CRED133]
+ALEX SHRUB, REPRESENTANT DU CONGRES : CHRIS LUCAS
-[A_FAIL3]
-~r~Le patient est mort!
+[CRED134]
+LE VIEUX KELLY : GEORGE DICENZO
-[A_PASS]
-Sauvé!
+[CRD134A]
+CAM JONES : GREG SIMS
-[F_FAIL2]
-~r~T'arrives trop tard!
+[CRD134B]
+PSYCHOPATHE : HUNTER PLATIN
-[A_COMP2]
-T'en as jamais assez ?
+[CRD134C]
+MAUDE, LA VENDEUSE DE GLACES : JANE GENNARO
-[RM2_M]
-Si tu as besoin d'artillerie, passe prendre ce dont t'as besoin dans les armoires.
+[CRD134D]
+JETHRO : JOHN ZURHELLEN
-[HEAL_A]
-Ton niveau de ~h~santé~w~ s'affiche en orange en haut à droite de l'écran.
+[CRD134E]
+GONZALES : JORGE PUPO
-[YD1_CNT]
-~1~ sur 15!
+[CRD134F]
+DWAYNE : NAVID KHONSARI
-[FM1_9]
-~g~C'est la fête un peu plus haut. Dépose Maria devant.
+[CRD134G]
+DICK : PETER MCKAY
-[FM1_Y]
-~w~Ça faisait longtemps que je m'étais pas amusée comme ça et tu m'as traitée vraiment bien ... avec respect et tout.
+[CRD134H]
+MIKE, L'ACTEUR DE PORNO : ROBERT CIHRA
-[FM1_AA]
-~w~Oh, faut que j'y aille, à bientôt j'espère.
+[CRD134I]
+PERCY : RUSSELL FOREMAN
-[NOCONTE]
-Reconnecte la manette analogique (DUALSHOCK#) ou manette analogique (DUALSHOCK#2) au port de manette 1 pour continuer.
+[CRED135]
+CAPTURE DE MOUVEMENTS
-[WRCONT]
-La manette connectée au port de manette 1 n'est pas une manette compatible. GTA3 nécessite une manette analogique (DUALSHOCK#) ou manette analogique (DUALSHOCK#2).
+[CRED136]
+ANIME PAR
-[WRCONTE]
-La manette connectée au port de manette 1 n'est pas une manette compatible. GTA3 nécessite une manette analogique (DUALSHOCK#) ou manette analogique (DUALSHOCK#2).
+[CRD136A]
+DIRECTION TECHNIQUE PAR ALEX HORTON
-[WRONGCD]
-Disque invalide. Veuillez insérer le bon disque.
+[CRED137]
+DIRIGE PAR
-[NOCD]
-Le compartiment à disque est vide. Veuillez insérer le disque.
+[CRD137A]
+DIRIGE PAR NAVID KHONSARI
-[OPENCD]
-Le compartiment à disque est ouvert. Veuillez refermer le compartiment à disque.
+[CRED138]
+PRODUIT PAR
-[CDERROR]
-Erreur de lecture du DVD de GTA3
+[CRD138A]
+PRODUIT PAR JAMIE KING
-[RESTART]
-Démarrage d'une nouvelle partie
+[CRD138B]
+RENAUD SEBBANE
-[GA_3]
-Plus de cadeaux. 1000$ pour repeindre!
+[CRED139]
+ENREGISTRE AUX PERSPECTIVE STUDIOS, BROOKLYN
-[GA_1]
-Oula! Je ne touche à rien d'aussi chaud, moi!
+[CRED140]
+ACTEURS POUR LA CAPTURE DE MOUVEMENTS
-[GA_1A]
-Reviens quand tu seras moins occupé...
+[CRD140A]
+BLAYNE PERRY
-[S_PROM2]
-Le garage d'à côté peut garder une voiture quand tu sauvegardes la partie.
+[CRD140B]
+JONATHON SALE
-[STOCK]
-Stock épuisé
+[CRD140C]
+CHARLES TUCKER
-[FM1_O]
-~w~Je pense qu'il est à la gare sur le bord de mer de Chinatown.
+[CRD140D]
+EDDIE MARRERO
-[EBAL_B]
-Tiens c'est là! Allez, on va se garer et on va trouver de nouvelles fringues!
+[CRD140E]
+WILLIAM MCCALL
-[EBAL_G]
-Ça, c'est la boîte de Luigi. Viens, on va rentrer par la porte de derrière.
+[CRD140F]
+JORGE PUPO
-[AM4_3]
-T'es le nouveau coursier d'Azuka!
+[CRD140G]
+ROBERT JACKSON
-[AM4_4]
-T'as le fric ? Le compte y est ?
+[CRD140H]
+TARA RADCLIFFE
-[AM4_5]
-Je sais ce que tu penses, encore un ripoux.
+[CRD140I]
+JENIFER GAMBETESE
-[AM4_6]
-Ben, le monde est pourri.
+[CRD140J]
+KRIS ACHEVARRIA
-[AM4_7]
-Parce que j'ai perdu quelques équipiers, ces enfoirés de poulets commencent à renifler partout.
+[CRD140K]
+ALI ORDOUBADI
-[AM4_8]
-J'imagine qu'ils peuvent me sentir.
+[CRD140L]
+KAHLEEM POOLE
-[AM4_9]
-Et oui, cette ville est un vrai dépotoir.
+[CRED141]
+DIALOGUES DES PIETONS
-[AM4_10]
-Mais je vais avoir besoin d'aide.
+[CRD141A]
+ECRIT PAR DAN HOUSER, MARC FERNANDEZ, GILLIAN TELLING ET NAVID KHONSARI
-[AM4_11]
-Si ça t'intéresse, tu sais où me trouver.
+[CRD141B]
+AVEC L'AIDE DE JEREMY POPE, LANCE WILLIAMS ET JENNY JEMISON
-[CAM_A]
-Appuie sur la ~h~touche ~k~~CAMERA_CHANGE_VIEW_ALL_SITUATIONS~~w~ pour changer les modes ~h~caméra ~w~quand tu es à pied ou en voiture.
+[CRED142]
+ECRITS PAR
-[CAM_B]
-~w~Appuie sur la ~h~touche directionnelle haut~w~ ou ~h~bas~w~ pour changer les modes ~h~caméra~w~ quand tu es à pied ou en voiture.
+[CRD142A]
+DAN HOUSER ET JAMES WORRALL
-[KM2_1]
-~g~Répare la voiture, elle doit être comme neuve.
+[CRED143]
+DIRIGE PAR DAN HOUSER, CRAIG CONNER, MARC FERNANDEZ ET ALLAN WALKER
-[LM3_6]
-Joey...
+[CRED144]
+PRODUITS PAR RENAUD SEBANNE
-[LM3_6A]
-Est-ce que je vais jouer avec ton gros canon ?
+[CRED145]
+PIETONS
-[LM3_9A]
-Y'a peut-être du travail pour toi.
+[CRED146]
+ADAM DAVIDSON, ADAM WATKINS, ALEJANDRO K. BROWN, ALEX ANTHONY SIOUKAS, ALEX GARCIA,
-[LM3_9B]
-D'accord ?
+[CRED147]
+ALICE SALTZMAN, ALISON CIHRA, AMY SALIMA, AMY SALZMAN, ANDREA VIDELA, ANTHONY ATTI,
-[AWAY2]
-~r~Ils se sont enfuis.
+[CRED148]
+ANTHONY RIVERA, BIJAN SHAMS, BLAYNE PERRY, BRETT BISOGNO, BREYE MATA, BRIAN PANEN,
-[AWAY]
-~r~Il s'est barré d'ici!
+[CRED149]
+BROCK VODER, CAREY BERTINI, CHARISSE LAMBERT, CHRIS DIFAT, CHRIS REISENBERGER,
-[JM6_1]
-Va à la banque par la rue principale.
+[CRED150]
+CHRISTOPHER BRODAY, CHRISTOPHER CARRO, CYNTHIA GREENE, DAMARIES LOPEZ, DAN LEE,
-[GA_6B] { re3 change }
-Tu la gares, tu l'amorces en appuyant sur la ~h~touche ~k~~VEHICLE_FIREWEAPON~~w~ et tu te barres!
+[CRED151]
+DAN SCHNEIDER, DAN TOYAMA, DAVID DEAN CHALTFIELD, JR., DAVID HARRISON, DAVID WILEY,
-[GA_7B] { re3 change }
-Pour armer la bombe, appuie sur la ~h~touche ~k~~VEHICLE_FIREWEAPON~~w~. Elle explosera au démarrage.
+[CRED152]
+DEBORAH COLLINS, DEBRANDA CHANEY-GILES, DEMETRA KOUKOULAS, DENISE ROSADO,
-[BAT1]
-~g~Ramasse la batte!
+[CRED153]
+DEVIN BENNETT, DEVIN WINTERBOTTOM, DORIS WOO, DOUGLAS HARRISON, DUNCAN COUTTS,
-[EBAL_O]
-Si t'es réglo, j'ai du travail pour toi. Et maintenant, casse-toi!
+[CRED154]
+DUPE AJAYI, EDWIN AVELLANEDA, ELIZABETH HOWELL, ELIZABETH SATTERWHITE, ERIC NAGLE,
-[HELP9_B]
-Appuie sur la ~h~touche ~k~~PED_FIREWEAPON~~w~ pour ~h~tirer~w~ avec le fusil à lunettes.
+[CRED155]
+ESTEBAN KARPLUS, F. FONT, FUTABA HAYASHI, GENE HILGREEN, GERALD COSGROVE,
-[HELP9_C]
-Appuie sur la ~h~touche ~k~~PED_FIREWEAPON~~w~ pour ~h~tirer~w~ avec le fusil à lunettes.
+[CRED156]
+GERARD LUNA, GILLIAN TELLING, GREGG CARLUCCI, GREGORY CLERVOIX, GREGORY SCHWEIZER,
-[JM6_8]
-~r~T'as semé tous les braqueurs!
+[CRED157]
+HADLEY TOMICKI, J. ROSSETT, JAMEEL VEGA, JASON JONES, JEFF ROSA, JENNIFER JEMISON,
-[COLT_IN]
-Le pistolet est disponible au Ma-Gnum.
+[CRED158]
+JEREMY TAGGERT, JESSICA RIDER, JOSEPH GREENE,JOSEPH HOWELL, KATE DUKICH,
-[TAXI2]
-~r~Tu n'as plus le temps!
+[CRED159]
+KEL O'NEILL, KEVIN HOPKINS, LADAWN JAMES, LANCE WILLIAMS, LAURA BUBBLES,
-[TAXI3]
-~r~Ton client est parti terrorisé!
+[CRED160]
+LAURA PATTERSON, LEE CUMMINGS, LETICIA L. YOUNG, LINDSAY KENNEDY, LISA ORITZ,
-[TAXI7]
-~r~Ta voiture est endommagée, fais-la réparer.
+[CRED161]
+LORNA JORDAN, LUCIO AMADIO, MARCO FERNANDEZ, MARIKO TANAKA, MARLON MATTHEWS,
-[TAXI4]
-La course est finie!
+[CRED162]
+MARY TELLING, MASAYOSHI MITSUYAMA, MATTHEW CHUNG, MAX ALLSTADT, MAX BOGDANOV,
-[TAXI5]
-BONUS DE VITESSE!
+[CRED163]
+MELISSA ALVAREZ, MICHAEL MAY, MICHAEL ROTHSTEIN, MIGUEL VIDAL, MIKE FEDERLINE,
-[TAXI6]
-La mission Taxi est finie.
+[CRED164]
+NATALIE DESCALZO, N'GAI MEMBERS, NICOLAS MALLO, NOELLE SADLER, NORBERT MORIVAN,
-[FRANGO]
-~g~Salvatore veux que tu aides d'abord Toni à régler son affaire avec la Triade!
+[CRED165]
+OSWALD GREENE, JR., PETER MCKAY, PETER APPEL, PRESTON SAVARESE, RAFAEL GONZALES,
-[PAGEB12]
-Pot-de-vin des flics livré à la planque
+[CRED166]
+RANDY JOHNSON, REY CONCEPCION, RICHARD KROGER, ROB TIBBS, ROBERT JACKSON,
-[PAGEB13]
-Santé livrée à la planque
+[CRED167]
+ROBERT SCHULER, ROSS A. MCINTYRE, RUSSELL FOREMAN, RUTH NUNEZ, SALVADORE SUAZO,
-[PAGEB14]
-Adrénaline livrée à la planque
+[CRED168]
+SAM WHITE, SANTOS GONZALES, SCOTT SMITH, SEYMOUR FRAILMAN, SPELMAN BRAUMAN,
-[KM1_4]
-~g~T'as besoin d'une bagnole de flic pour ce job!
+[CRED169]
+STEPHANIE TELLING, STEVE KNEZEVICH, STEVE ROBERT, SUMIKO YASUDA, SUSAN LEWIS,
-[CAT1_B]
-Apporte 500 000$ à la Villa de Cedar Grove.
+[CRED170]
+SYLVIA COLACIOS, TOMOKO MIYAZAKI, TRON, VERDEL HALE, YVES MONDESIR, ZENO LEINFELDER,
-[JM2_C]
-Il a un stand de nouilles dans Chinatown.
+[CRED171]
+DAVID BEDDOES, CHRISTINE CHALMERS, BARRY CLARK, NEIL CORBETT, KIM GURNEY, NEIL MEIKLE,
-[RM6_1]
-Voilà la clé d'un coffre.
+[CRED172]
+CASSIE OLIVER, LORRAINE ROY, DAVID WATSON, KEVIN WONG, WILL MORTON
-[RM6_2]
-T'y trouveras du cash et des provisions. J'avais mis ça de coté au cas où les choses tourneraient mal.
+[CRED175]
+ADAM DAVIDSON
-[RM6_3]
-A plus.
+[CRED176]
+LANCE WILLIAMS
-[FE_INIP]
-Initialisation et chargement du menu pause... Veuillez patienter.
+[CRED177]
+NEIL MCCAFFREY
-[FESZ_CA]
-Annuler
+[CRED178]
+LAURA PATERSON
-[FESZ_QU]
-Quitter
+[CRED179]
+REY CONCEPCION
-[FESZ_L1]
-Partie sauvegardée avec succès!
+[CRED180]
+CHARLES HEROLD
-[FESZ_L2]
-Le nom du fichier sauvegardé est :
+[CRED181]
+ANDREW GREENWALD
-[FESZ_OK]
-OK
+[CRED182]
+JAMES MIELKE
-[FES_NGA]
-Nouvelle partie
+[CRED183]
+PETER SUCIU
-[FES_CAN]
-Annuler
+[CRED184]
+ALEX ODULIO
-[FESZ_QL]
-Toutes les étapes non sauvegardées de cette partie seront perdues. Charger la partie?
+[CRED185]
+DON NKRUMAH
-[FESZ_QD]
-Effacer cette sauvegarde?
+[CRED186]
+KENDALL PITTMAN
-[FESZ_QO]
-Ecraser cette sauvegarde?
+[CRED187]
+SAL SUAZO
-[FESZ_QR]
-Veux-tu vraiment commencer une autre partie? Toutes vos données depuis la dernière partie sauvegardée seront perdues. Continuer?
+[CRED188]
+EREK MATEO
-[FESZ_QS]
-PASSEZ EN SAUVEGARDE?
+[CRED189]
+CHRIS DIFATE
-[SLONFP]
-Port 1 Fichier Protégé.
+[CRED190]
+LEILA MILTON
-[T4X4_1]
-'TERRAIN DE JEU DU PATRIOT'
+[CRED191]
+DARREN ZOLTOWSKI
-[T4X4_2]
-'UN TOUR DANS LE PARC'
+[CRED192]
+VIRGINIA SMITH
-[T4X4_3]
-'ADHÉRENCE!'
+[CRED193]
+KEVIN CASSIN
-[MM_1]
-'GAZ À TOUS LES ÉTAGES'
+[CRED194]
+JASON SHIGEMORI
-[T4X4_1A]
-~g~T'as ~y~5 minutes~g~ pour franchir ~y~15~g~ points de passage.
+[CRED195]
+KELLY KINSELLA
-[T4X4_1B]
-~1~ sur 15!
+[CRED196]
+MOLLIE STICKNEY
-[T4X4_1C]
-~g~Chaque point de passage te rapportera ~y~20 secondes~g~.
+[CRED197]
+STANTON SARJEANT
-[T4X4_2A]
-~g~Tu as ~y~2 minutes~g~ pour franchir ~y~12~g~ points de passage! ~g~Tu peux les franchir dans ~y~n'importe quel ordre.
+[CRED198]
+LAURA WALSH
-[T4X4_2B]
-~1~ sur 12!
+[CRED199]
+MARK GARONE
-[T4X4_2C]
-~y~Passe le premier point de passage pour déclencher le chrono. ~y~ Chaque point de passage te rapportera ~y~10 secondes~g~.
+[CRED200]
+JOANNA SLY
-[T4X4_3A]
-~g~Tu as ~y~5 minutes~g~ pour franchir ~y~20~g~ points de passage. ~g~Tu peux les franchir dans ~y~n'importe quel ordre.
+[CRED201]
+ELIZABETH HOWELL
-[T4X4_3B]
-~y~Franchis~g~ le premier point de passage pour déclencher le chrono. ~g~Chaque point de passage te rapportera ~y~15 secondes~g~.
+[CRED202]
+ANA HERCULES
-[T4X4_3C]
-~1~ sur 20!
+[CRED203]
+SHIRLEY IRICK
-[T4X4_F]
-~r~Tu t'es barré! Trop dur pour toi ?!
+[CRED204]
+KASHONA FIELDS
-[MM_1_A]
-~g~Tu as ~y~2 minutes~g~ pour franchir les ~y~20 points de passage~g~ dans le parking à plusieurs étages! ~g~Tu peux les franchir dans n'importe quel ordre.
+[CRED205]
+JOEL M. LILJE
-[MM_1_B]
-~1~ sur 20!
+[CRED206]
+JOHN DIBENEDETTO
-[MM_1_C]
-~g~Ca fait 20 secondes, plus ~y~5 secondes~g~ pour chaque point de passage. ~g~Le chrono commence ~y~immédiatement.
+[CRED207]
+NANCY GILES
-[FM2_14]
-~r~Tu t'es trop approché et Bill t'a vu!
+[CRED208]
+RYAN CROY
-[FM2_15]
-~g~Ne t'approche pas trop ou Bill va se douter de quelque chose!
+[CRED209]
+JENNIFER KOLBE
-[UPSIDE]
-~r~Tu t'es retourné!
+[CRED210]
+LIAM BURKE
-[FM2_16]
-BALANÇOMETRE :
+[CRED211]
+SIGRID PREISSL
-[LM3_11]
-~g~Misty ne montera pas dans un bus, trouve un autre véhicule!
+[CRED212]
+ANITA FITZSIMONS
-[LANDSTK]
-Landstalker
+[CRED213]
+PHILIPPA RASELLI
-[IDAHO]
-Idaho
+[CRED214]
+WIL QUESNEL
-[STINGER]
-Stinger
+[CRED215]
+FALKO BURKERT
-[LINERUN]
-Linerunner
+[CRED216]
+SARA SEWELL
-[PEREN]
-Perennial
+[CRED217]
+STATIONS DE RADIO ET MUSIQUE
-[SENTINL]
-Sentinelle
+[CRED218]
+CONSULTANT EN MUSIQUE
-[PATRIOT]
-Patriot
+[CRD218A]
+HEINZ HENN
-[FIRETRK]
-Camion de pompier
+[CRD218B]
+STUART ROSS
-[TRASHM]
-Trashmaster
+[CRED219]
+COORDINATEUR DE LA BANDE-SON
-[STRETCH]
-Stretch
+[CRED220]
+TERRY DONOVAN
-[MANANA]
-Manana
+[CRED221]
+PRODUCTEUR CHEZ ROCKSTAR GAMES
-[INFERNS]
-Infernus
+[CRED222]
+DAN HOUSER ET LAZLOW
-[BLISTA]
-Blista
+[CRED223]
+PRODUCTEUR CHEZ ROCKSTAR NORTH
-[PONY]
-Pony
+[CRED224]
+CRAIG CONNER
-[MULE]
-Mule
+[CRED225]
+ALLAN WALKER
-[CHEETAH]
-Cheetah
+[CRED226]
+LAZLOW
-[AMBULAN]
-Ambulance
+[CRED227]
+DJ BANTER ET IMAGING
-[FBICAR]
-F.B.I.
+[CRED228]
+ECRIT PAR DAN HOUSER ET LAZLOW
-[MOONBM]
-Moonbeam
+[CRED229]
+FLASH FM
-[ESPERAN]
-Esperanto
+[CRD229A]
+TONI-MARIA CHAMBERS
-[TAXI]
-Taxi
+[CRD229B]
+VOIX ET PRODUCTION : JEFF BERLIN
-[KURUMA]
-Kuruma
+[CRED230]
+REMERCIEMENTS SPECIAUX A
-[BOBCAT]
-Bobcat
+[CRED231]
+TOMMY MOTTOLA,
-[WHOOPEE]
-M. Whoopee
+[CRED232]
+MICHELLE ANTHONY,
-[BFINJC]
-BF Injection
+[CRED233]
+STEVE BARNETT,
-[POLICAR]
-Police
+[CRED234]
+CHUCK FLECKENSTEIN,
-[ENFORCR]
-Enforcer
+[CRED235]
+RITA LIBERATOR
-[SECURI]
-Sécuricar
+[CRED236]
+MARTIN ET CLAIRE LOGAN
-[BANSHEE]
-Banshee
+[CRED237]
+SANDRA HUTTON
-[PREDATR]
-Predator
+[CRED238]
+CHRISTINE DAVIDSON
-[BUS]
-Bus
+[CRED239]
+ALAN, RED ET BIGFOOT
-[RHINO]
-Rhino
+[CRED240]
+LE T
-[BARRCKS]
-Barracks OL
+[CRED241]
+COLIN DONALD
-[TRAIN]
-Train
+[CRED242]
+KERRY STALLWOOD
-[HELI]
-Hélicoptère
+[CRED243]
+ALAN MCGREGOR
-[DODO]
-Dodo
+[CRED244]
+CHRIS MORTON
-[COACH]
-Coach
+[CRED245]
+EMIL BUSSE
-[CABBIE]
-Cabbie
+[CRED246]
+EMILY BAILLIE
-[STALION]
-Stallion
+[CRED247]
+KEVIN ARCHIBALD
-[RUMPO]
-Rumpo
+[CRED248]
+MORAG KERR
-[RCBANDT]
-RC Bandit
+[CRED249]
+CATH WALKER
-[BELLYUP]
-Triad
+[CRED250]
+ISO BAR
-[MRWONGS]
-M. Wongs
+[CRED251]
+WATERLINE
-[MAFIACR]
-Mafia
+[CRED252]
+NEWS CAFE
-[YARDICR]
-Yardie
+[CRD251A]
+THE POND
-[YAKUZCR]
-Yakuza
+[CRD252A]
+PIVO
-[DIABLCR]
-Diablo
+[CRED253]
+BUDGET VIDEO RENTALS
-[COLOMCR]
-Cartel
+[CRED254]
+LORNA'S SCOOTER
-[HOODSCR]
-Hoods
+[CRED255]
+GARETH MURFIN
-[AEROPL]
-Avion
+[CRED256]
+GRAPHISMES ADDITIONNELS
-[SPEEDER]
-Speeder
+[CRED257]
+TONY PORTER
-[REEFER]
-Reefer
+[CRED258]
+CRAIG MOORE
-[PANLANT]
-Panlantic
+[CRED259]
+ANIMATION SYNCHRO LABIALE DES CINEMATIQUES
-[FLATBED]
-Flatbed
+[CRED260]
+COSGROVE HALL FILMS
-[YANKEE]
-Yankee
+[CRED261]
+PRODUCTEUR : OWEN BALLHATCHET
-[BORGNIN]
-Borgnine
+[CRED262]
+ANIMATEUR SENIOR : JON TURNER
-[TOYZ]
-TOYZ
+[CRED263]
+ANIMATEURS : RICHARD DRUMM
-[FEST_DF]
-Distance parcourue à pied (miles)
+[CRED264]
+DAVE BROWN
-[FEST_DC]
-Distance parcourue en voiture (miles)
+[CRED265]
+MAIR THOMAS
-[FESTDFM]
-Distance parcourue à pied (m)
+[CRED266]
+PRASHANT PATEL
-[FESTDCM]
-Distance parcourue en voiture (m)
+[CRED267]
+CONSULTANT TECHNOLOGIE AUDIO
-[FEST_R1]
-Terrain de jeu du Patriot en secondes
+[CRED268]
+RIK EDE POUR GAMESOUND LTD.
-[FEST_R2]
-Un tour dans le parc en secondes
+[CRED269]
+ASSISTANCE INTEGRATION DTS
-[FEST_R3]
-Adhérence en secondes
+[CRED270]
+TED LAVERTY POUR DTS
-[FEST_RM]
-Gaz à tous les étages en secondes
+[CRED271]
+CHRIS GREER POUR DTS
-[FEST_LS]
-Nbre de personnes sauvées dans l'ambulance
+[CRED272]
+JASON PAGE POUR SCEE
-[FEST_CC]
-Criminels tués dans la mission de police
+[CRED273]
+RECHERCHE ET ANALYSE
-[FEST_FE]
-Nombre total de feux éteints
+[CRED274]
+VROCK
-[FEST_LF]
-Vol le plus long en Dodo
+[CRED275]
+DJ : LAZLOW
-[FEST_BD]
-Meilleur temps pour désamorcer la bombe
+[CRED276]
+VOIX : JOE KELLY
-[FEST_RP]
-Rodéos réussis
+[CRED277]
+PRODUCTION : JONATHAN HANST
-[FEST_MP]
-Missions réussies
+[CRED278]
+ONDE 103
-[FEST_BB]
-Les fous du volants:
+[CRED279]
+DJ : ADAM FIRST-JAMIE CANFIELD
-[FEST_H0]
-La plupart des points de passage
+[CRED280]
+VOIX : JEN SWEENLEY
-[FEST_GC]
-Nombre total de voitures de gang:
+[CRED281]
+PRODUCTION : JONATHAN HANST
-[FEST_H1]
-Destruction de Diablo
+[CRED282]
+FEVER 105
-[FEST_H2]
-Massacre de la Mafia
+[CRED283]
+DJ : OLIVER 'LADYKILLER' BISCUIT-JULIUS DYSON
-[FEST_H3]
-Le désastre du casino
+[CRED284]
+VOIX D'HOMME : ED McMANN
-[FEST_H4]
-Le destructeur de Rumpo
+[CRED285]
+VOIX DE FEMME : SHWNEE SMITH
-[USJI1]
-TEXT NO LONGER REQUIRED
+[CRED286]
+PRODUCTION : LISTEN KISTEN
-[USJI2]
-TEXT NO LONGER REQUIRED
+[CRED287]
+EMOTION 98.3
-[USJI3]
-TEXT NO LONGER REQUIRED
+[CRED288]
+DJ : FERNANDO- FRANK CHAVEZ
-[USJ]
-BONUS POUR CASCADE UNIQUE!
+[CRED289]
+VOIX : JEN SWEENLEY
-[SPRAY]
-Amène ton véhicule à l'atelier de peinture pour annuler ton ~h~indice de recherche~w~, ~h~répare ~w~et ~h~repeins ~w~ton véhicule. Coût -~h~ 1000$.
+[CRED290]
+PRODUCTION : JONATHAN HANST
-[HM1_1]
-~G~Refroidis 20 Nines violets en 2 minutes et 30 secondes.
+[CRED291]
+RADIO ESPANTOSO
-[KM1_8A] { re3 change }
-Appuie sur la ~h~touche ~k~~VEHICLE_FIREWEAPON~~w~ pour ~h~activer la bombe~w~, n'oublie pas de t'éloigner.
+[CRED292]
+DJ : PEPE-TONY CHILRODES
-[KM1_8D] { re3 change }
-Appuie sur la ~h~touche ~k~~VEHICLE_FIREWEAPON~~w~ pour ~h~activer la bombe~w~, n'oublie pas de t'éloigner.
+[CRED293]
+WILDSTYLE
-[KM1_12]
-~g~Amène-le au dojo mais débarrasse-toi des flics d'abord!
+[CRED294]
+DJ : MISTER MAGIC
-[RATNG1]
-Pickpocket
+[CRED295]
+VOIX : FRANK SILVESTRO
-[RATNG2]
-Rascal
+[CRED296]
+PRODUCTION : LAZLOW
-[RATNG3]
-Voyou
+[CRED297]
+KCHAT
-[RATNG4]
-Prostituée
+[CRED298]
+ECRIT PAR DAN HOUSER ET LAZLOW
-[RATNG5]
-Idiot
+[CRED299]
+PRODUIT ET EDITE PAR LAZLOW
-[RATNG6]
-Pilote
+[CRED300]
+DJ AMY SHECKENHAUSEN : LEYNA WEBER
-[RATNG7]
-Gros Bras
+[CRED301]
+JEZ TORRENT : KEVIN MCKIDD
-[RATNG8]
-Réparateur
+[CRED302]
+MANDY : COLLEEN CORBETT
-[RATNG9]
-Associé
+[CRED303]
+MICHELLE CARAPADIS : MARY BIRDSONG
-[RATNG10]
-Nettoyeur
+[CRED304]
+MR.ZOO : CARL DOWLING
-[RATNG11]
-Assassin
+[CRED305]
+GETHSEMANEE : LYNN LIPTON
-[RATNG12]
-Bras droit
+[CRED306]
+CLAUDE MAGINOT : JOHN MAUCERI
-[RATNG13]
-Exécutant
+[CRED307]
+BJ SMITH : LAWRENCE TAYLOR
-[RATNG14]
-Capo
+[CRED308]
+THOR : FRANK FAVA
-[RATNG15]
-Patron
+[CRED309]
+INTERLOCUTEURS
-[1010]
-~r~Ta bagnole est sur le toit
+[CRED310]
+COUZIN ED, JOSH CLARK, JASON BUHRMESTER, JUAN ALLER, WAYNE OLIVER, SUSAN LEWIS, GILLIAN TELLING, TOM MURRAY, MIKE FERRANTE SR., EMMANUEL GOLDSTEIN, DAN HOUSER, NICK MANDELOS, GERRY COSGROVE, MIKE PALERMO, PORKCHOP, KEITH BROADAS
-[1011]
-~r~Ta bagnole est sur le toit
+[CRED311]
+LEWIS, GILLIAN TELLING, TOM MURRAY, MIKE FERRANTE SR., EMMANUEL GOLDSTEIN,
-[1012]
-~r~Ta bagnole est sur le toit
+[CRED312]
+DAN HOUSER, NICK MANDELOS, GERRY COSGROVE, MIKE PALERMO, PORKCHOP,
-[1013]
-~r~Ta bagnole est sur le toit
+[CRED313]
+KEITH BROADAS
-[1014]
-~r~Ta bagnole est sur le toit
+[CRED314]
+VCPR
-[JM4_10]
-OK, Petit. Emmène-moi d'abord à la laverie de Chinatown, j'ai une affaire à régler.
+[CRED315]
+ECRIT PAR DAN HOUSER ET LAZLOW
-[JM4_11]
-Cette petite laveuse ne paie pas pour sa protection.
+[CRED316]
+PRODUIT PAR LAZLOW
-[JM4_12]
-Et fais gaffe à la bagnole, Joey vient juste de la faire réparer.
+[CRED317]
+MAURICE CHAVEZ : PHILLIP ANTHONY RODRIGUEZ
-[JM4_13]
-Alors pas de conneries, ok ?
+[CRED318]
+JONATHAN FREELOADER : PATRICK OLSEN
-[KM4_11]
-~g~Ramène la monnaie au casino!
+[CRED319]
+MICHELLE MONTANIUS : KELLY GUEST
-[FEF_BR2]
-Retrouve-les en lisant les précédents briefings de missions.
+[CRED320]
+ALEX SHRUB : CHRIS LUCAS
-[TRAIN_1]
-Station Kurowski
+[CRED321]
+CALLUM CRAYSHAW : SEAN MODICA
-[TRAIN_2]
-Station Rothwell
+[CRED322]
+JOHN F. HICKORY : LJ GANSEN
-[TRAIN_3]
-Station Baillie
+[CRED323]
+LE PASTEUR RICHARDS : DAVID GREEN
-[SUBWAY1]
-Station Portland
+[CRED324]
+JAN BROWN : MAUREEN SILLIMAN
-[SUBWAY2]
-Station Rockford
+[CRED325]
+BARRY STARK : RENAUD SEBBANE
-[SUBWAY3]
-Station Staunton South
+[CRED326]
+JENNY LOUISE CRAB : MARY BIRDSONG
-[SUBWAY4]
-Terminal Shoreside
+[CRED327]
+KONSTANTINOS SMITH : KONSTANTINOS.COM
-[MEA4_2]
-~r~Marty Chonks est mort!
+[CRED328]
+JEREMY ROBARD : PETER SILVESTRO
-[SPRAY1]
-Amène ton véhicule à l'atelier de peinture pour annuler ton ~h~indice de recherche~w~, ~h~répare ~w~et ~h~repeins ~w~ton véhicule. Coût -~h~ 1000$. Pour cette fois, c'est gratos.
+[CRED329]
+PUBLICITES RADIO
-[JM4_A]
-Ouais, je sais Tony, je l'ai défoncée en douceur. Elle miaule, tu vois ce que je veux dire ?
+[CRED330]
+ECRITES PAR DAN HOUSER ET LAZLOW
-[JM4_5]
-Reviens plus tard et on leur donnera de la lessive à faire, leurs propres fringues avec leur sang dessus!
+[CRED331]
+PRODUITES PAR LAZLOW
-[AMMU_A]
-Luigi m'a dit que t'as besoin d'un calibre...
+[CRED332]
+JINGLES SUPPLEMENTAIRES PRODUITS PAR CRAIG CONNER
-[AMMU_B]
-Joey m'a dit de t'équiper...
+[CRED333]
+VOIX DES PUBLICITES :
-[AMMU_C]
-Alors tu vas aller derrière le magasin. Je t'ai laissé un 9mm dans le jardin.
+[CRED334]
+ADAM DAVIDSON, ALEX ANTHONY, ALICE SALTZMAN, AMY SALZMAN, KATE DUKICH,
-[AMMU_D]
-J'ai tout ce qu'il faut en matière de sécurité.
+[CRED335]
+ARAN RONICLE, BARB JONES, BEN KRECH, BRIAN THOMAS, BROCK YODER, CHRIS
-[AMMU_E]
-Tu veux un permis aussi ?
+[CRED336]
+FERRANTE, CRAIG CONNER, DAVE RYAN, DAVID GREEN, DORIS WOO, DOUGLAS
-[AMMU_F]
-J'ai pas besoin de tes papiers d'identité. Je pense qu'on peut te faire confiance.
+[CRED337]
+HARRISON, ED MCMANN, FRANK CHAVEZ, FRANK FAVA, GENE HILGREEN, GREG
-[DETON]
-DETONATION :
+[CRED338]
+SCHWEIZER, HUNTER PLATIN, JAMES FERRANTE, JEFF BERLIN, JEFF ROSA, JOE KELLY,
-[DRIVE_A] { re3 change }
-Selectionne un Uzi quand tu montes dans la voiture, regarde à gauche ou à droite et appuie sur la ~h~touche ~k~~VEHICLE_FIREWEAPON~~w~ pour tirer.
+[CRED339]
+JOHN MAUCERI, JOSH CLARK, JULIE WEMYSS, KEVIN STRALEY, KIM GURNEY, LANCE
-[DRIVE_B] { re3 change }
-Selectionne un Uzi quand tu montes dans la voiture, regarde à gauche ou à droite et appuie sur la ~h~touche ~k~~VEHICLE_FIREWEAPON~~w~ pour tirer.
+[CRED340]
+WILLIAMS, LAURA PATERSON, LAZLOW, LISA ORTIZ, LORNA JORDAN, LUCIEN JONES,
-[RECORD]
-~g~NOUVEAU RECORD!
+[CRED341]
+MAUREEN SILLIMAN, MIKE FERRANTE JR., PETE GUSTIN, PETER SILVESTRO, RAFF
-[NRECORD]
-~r~PAS DE RECORD!
+[CRED342]
+CROLLA, RANDY JOHNSON, RICHARD KRUGER, RON REEVE, SHELLEY MILLER, SKY, TJ ALLARD
-[RCHELP] { re3 change }
-Appuie sur la ~h~touche ~k~~VEHICLE_FIREWEAPON~~w~ ou heurte une roue de voiture avec le véhicule télécommandé pour le faire exploser.
+[CRD344A]
+ENREGISTREMENTS AUX DIGITAL ARTS STUDIOS,
-[RCHELPA] { re3 change }
-Appuie sur la ~h~touche ~k~~VEHICLE_FIREWEAPON~~w~ ou heurte une roue de voiture avec le véhicule télécommandé pour le faire exploser.
+[CRED344]
+NYC, TRACK 9 STUDIOS, NYC,
-[RC_1]
-Tu as 2 minutes pour faire péter autant de voitures de Diablo que tu peux!
+[CRED345]
+WEDDINGTON MULTIMEDIA, LOS ANGELES,
-[RC_2]
-Tu as 2 minutes pour faire péter autant de voitures de Mafia que tu peux!
+[CRD345A]
+SYNC SOUND, NYC ET RADIO LAZLOW, LONG ISLAND.
-[RC_3]
-Tu as 2 minutes pour faire péter autant de voitures de Yasuka que tu peux!
+[CRED346]
+MERCI A AXEL ERICSON ET WON LEE DE DIGITAL ARTS, PAUL VASQUEZ DETRACK 9 STUDIOS, JOHN BOWEN ET JOHN HASSLER DE SYNC SOUND.
-[RC_4]
-Tu as 2 minutes pour faire péter autant de voitures de Yardie que tu peux!
+[CRED347]
+MARK LLOYD
-[RC_5]
-Tu as 2 minutes pour faire péter autant de voitures des Hoods que tu peux!
+[CRED348]
+TIM BATES
-[RC_6]
-Tu as 2 minutes pour faire péter autant de voitures du Cartel que tu peux!
+[CRED349]
+KIT BROWN
-[RAMPAGE]
-RODEO!
+[CRED350]
+ANDY MASON
-[RAMP_P]
-RODEO REUSSI!
+[CRED351]
+PHIL DEANE
-[RAMP_F]
-RODEO RATE
+[CRED352]
+PHIL ALEXANDER
-[PAGE_00]
-..
+[CRED353]
+MATT HEWITT
-[PAGE_01]
-Elimine ~1~ Diablos en 120 secondes!
+[CRED354]
+DENBY GRACE
-[PAGE_02]
-Détruis ~1~ véhicules en 120 secondes!
+[CRED355]
+ANTOINE CABROL
-[PAGE_03]
-Tue ~1~ Mafia en 120 secondes!
+[CRED356]
+JONATHAN STONES
-[PAGE_04]
-Tue ~1~ Triades en 120 secondes!
+[CRED357]
+MIKE BLACKBURN
-[PAGE_05]
-Tue ~1~ Triades en 120 secondes!
+[CRED358]
+TIM MCGAFF
-[PAGE_06]
-Détruis ~1~ véhicules en 120 secondes!
+[CINCAM]
+Caméra cinématique
-[PAGE_07]
-Dégomme ~1~ têtes de Yardies en 120 secondes!
+[RC4]
+'RODEO DE RUMPO'
-[PAGE_08]
-Brûle ~1~ Yakuzas en 120 secondes!
+[LEGAL]
+~g~Elimine toute menace criminelle!
-[PAGE_09]
-Détruis ~1~ véhicules en 120 secondes!
+[GA_2]
+Nouveau moteur et nouvelle peinture. Les flics ne te reconnaîtront plus!
-[PAGE_10]
-Détruis ~1~ véhicules en 120 secondes!
+[HELP15]
+Si tu es à pied, appuie sur la ~h~~k~~PED_LOOKBEHIND~~w~ pour ~h~regarder derrière~w~. Utilise le ~h~joystick analogique droit~w~ pour ~h~regarder autour~w~ de toi.
-[PAGE_11]
-Bute-moi ~1~ Yardies en 120 secondes!
+[FEC_LB4]
+Regarder derrière (touche R3)
-[PAGE_12]
-Flambe ~1~ Yakuzas en 120 secondes!
+[PERPIC]
+Paquets cachés trouvés
-[PAGE_13]
-Explose ~1~ Yardies en 120 secondes!
+[CO_ONE]
+Paquet caché ~1~ sur ~1~
-[PAGE_14]
-Grille-moi ~1~ Colombiens en 120 secondes!
+[GA_21]
+Impossible de garer plus de véhicules dans ce garage.
-[PAGE_15]
-Eclate ~1~ Hoods en 120 secondes!
+[CHEAT1]
+Codes activés
-[PAGE_16]
-Détruis ~1~ véhicules en 120 secondes!
+[CHEAT2]
+Code d'arme
-[PAGE_17]
-Eclate ~1~ Colombiens avec une voiture en 120 secondes!
+[CHEAT3]
+Code de santé
-[PAGE_18]
-Détruis ~1~ véhicules en 120 secondes!
+[CHEAT4]
+Code d'armure
-[PAGE_19]
-Fais sauter ~1~ têtes de Colombiens en 120 secondes!
+[CHEAT5]
+Code d'indice de recherche
-[PAGE_20]
-Décapite ~1~ Hoods en 120 secondes!
+[CHEAT6]
+Code d'argent
-[JM1_A]
-Hé, je m'fais chier, quand est-ce que tu me sautes ?
+[CHEAT7]
+Code de météo
-[JM1_B]
-Ça va pas tarder mon coeur, je dois juste m'occuper d'un truc.
+[USJ_ALL]
+TOUTES LES CASCADES ONT ETE ACCOMPLIES!
-[JM1_C]
-J'ai un petit boulot pour toi, mon gars.
+[JAN]
+Jan
-[JM1_D]
-Les frères Forelli me doivent du fric depuis trop longtemps
+[FEB]
+Fév
-[JM1_E]
-et ils ont besoin qu'on leur apprenne un peu ce que c'est que le respect.
+[MAR]
+Mar
-[JM1_F]
-Forelli Grosses Babines est en train de s'empiffrer au Bistro de St. Marks,
+[APR]
+Avr
-[JM1_G]
-alors tu lui prends sa tire et tu l'amènes à l'atelier de 8-Ball, à Harwood.
+[MAY]
+Mai
-[JM1_H]
-Tu connais 8-Ball, pas vrai ?
+[JUN]
+Jun
-[JM1_I]
-Une fois qu'il l'a truffée avec une bombe, tu remets la voiture où tu l'as trouvée.
+[JUL]
+Jui
-[JM1_J]
-Et puis tu t'assois et tu regardes le spectacle.
+[AUG]
+Aoû
-[JM1_K]
-Mais grouille, il va mettre trois plombes à bouffer.
+[SEP]
+Sept
-[CAT2_A1]
-Viens là, petite pute!
+[OCT]
+Oct
-[CAT2_A]
-La question est : tu es venu pour sauver Maria ou pour me récupérer ?
+[NOV]
+Nov
-[CAT2_B]
-Eh bien, j'ai des infos pour toi,
+[DEC]
+Déc
-[CAT2_B2]
-te tuer sera un vrai plaisir mais sortir avec toi faisait partie du business.
+[DEFDT]
+--:---:---- --:--:--
-[CAT2_C]
-Tu estas muy peccino amigo!
+[BONUS]
+~g~BONUS $~1~
-[CAT2_D]
-Lance-moi l'argent
+[HORN1]
+Appuie sur la ~h~~k~~VEHICLE_HORN~ ~w~pour ~h~klaxonner.
-[CAT2_E]
-T'as été très occupé!
+[HORN2]
+Appuie sur la ~h~~k~~VEHICLE_HORN~ ~w~pour ~h~klaxonner.
-[CAT2_E2]
-Mais tu n'as rien appris, on ne peut pas me faire confiance.
+[HORN3]
+Appuie sur la ~h~~k~~VEHICLE_HORN~ ~w~pour ~h~klaxonner.
-[CAT2_E3]
-Descends cet idiot.
+[FEC_EXV]
+Monter et descendre d'un véhicule
-[CAT2_J]
-Fais-moi voler ça!
+[TAXI_M]
+'CHAUFFEUR DE TAXI'
-[HM5_1]
-Salut. D-Ice a dit que tu venais. Y'a des règles : juste des battes, pas de flingue, pas de bagnole.
+[COP_M]
+'AUTODEFENSE'
-[HM5_5]
-On se bat pour le respect, tu piges ?
+[FIRE_M]
+'POMPIER'
-[HELP14]
-Pour ramasser les armes, marche dessus. Tu ne peux pas en récupérer depuis un véhicule.
+[AMBUL_M]
+'AMBULANCE'
-[CRUSH]
-Gare-toi sur l'emplacement indiqué et sors de la voiture. La voiture sera alors compressée.
+[HJ_IS]
+BONUS DE CASCADE DANGEREUSE : $~1~
-[DIAB2_B]
-Un gang de bons à rien m'a menacé de me couper mon outil de travail si je ne leur paye pas un impôt.
+[HJ_PIS]
+BONUS DE CASCADE DANGEREUSE PARFAITE : $~1~
-[DIAB2_C]
-Ils ont menacé le mauvais gars, amigo.
+[HJ_DIS]
+BONUS DE DOUBLE CASCADE DANGEREUSE : $~1~
-[DIAB2_D]
-Je sais qu'ils ont un faible pour les glaces.
+[HJ_PDIS]
+BONUS DE DOUBLE CASCADE DANGEREUSE PARFAITE : $~1~
-[DIAB2_E]
-Va chercher la bombe que j'ai planquée à Harwood
+[HJ_TIS]
+BONUS DE TRIPLE CASCADE DANGEREUSE : $~1~
-[DIAB2_F]
-et pique la camionnette du vendeur de glaces pendant sa tournée.
+[HJ_PTIS]
+BONUS DE TRIPLE CASCADE DANGEREUSE PARFAITE : $~1~
-[DIAB2_G]
-Attire ces abrutis vers leur destinée fatale avec la clochette.
+[HJ_QIS]
+BONUS DE QUADRUPLE CASCADE DANGEREUSE : $~1~
-[DIAB2_H]
-Ils se planquent dans un entrepôt à Atlantic Quays.
+[HJ_PQIS]
+BONUS DE QUADRUPLE CASCADE DANGEREUSE PARFAITE : $~1~
-[DIAB3_A]
-Des prétentieux de la Triade ont volé ma magnifique bagnole la nuit dernière,
+[FESZ_LS]
+Chargement effectué.
-[DIAB3_B]
-ils l'ont bousillée et l'ont brûlée.
+[HELI_1A]
+Teste tes capacités avec le Sparrow et vois en combien de temps tu peux réussir le parcours.
-[DIAB3_C]
-Quelques-uns de mes plus précieux objets étaient dans le coffre :
+[HELI_1B]
+Parcours réussi!
-[DIAB3_D]
-des collectors irremplaçables!
+[HELIODD]
+Petits boulots en hélico
-[DIAB3_E]
-J'ai planqué une arme à la lisière de Chinatown.
+[INT2_M]
+Ils sont proprios d'une ferme au Panama!
-[DIAB3_F]
-Prends-la et montre à ces vandales de la Triade qu'El Burro est en colère!
+[INT2_N]
+Ok, écoutez un peu...
-[DIAB3_1]
-TUE 25 TRIADES
+[INT2_O]
+Les gars, quand on sera là-bas, est-ce que je dois rester dans la bagnole,
-[DIAB4_A]
-Un petit malin a piqué un camion plein de mes dernières publications fraîchement imprimées.
+[INT2_P]
+où bien est-ce que vous voulez absolument que je vienne avec vous?
-[DIAB4_B]
-Mais cet idiot camé à la Spank a laissé les portes de la camionette ouvertes
+[INT2_Q]
+Non, Reste dans la bagnole.
-[DIAB4_C]
-et toutes les belles photos
+[INT2_R]
+Vous savez quoi, j'ai réfléchi à la question,
-[DIAB4_D]
-de ma dernière production pour adultes, sont semées à travers Liberty!
+[INT2_S]
+Je vais surveiller la bagnole.
-[DIAB4_E]
-Prends le camion et suis la piste des magazines Le Taureau se fait Suelen, volumes 1, 2 et 3.
+[INT4_A]
+On est baisés! Baisés!
-[DIAB4_F]
-Dès que t'en trouves un, ramasse-le.
+[INT4_B]
+Putain, c'est vraiment le coup classique!
-[DIAB4_G]
-Quand tu auras retrouvé ce voleur bourré à la Spank, descends-le!
+[INT4_C]
+Je sors la tête d'un caniveau pour une seconde de défonce,
-[DIAB4_H]
-Après, tu iras livrer les magazines porno à XXX Mags dans Le Quartier Rouge.
+[INT4_D]
+et le destin me chie de la merde plein la gueule!
-[DIAB4_1]
-~g~Amène la camionnette à l'arrière de XXX Magazines.
+[INT4_E]
+Allez vous faire mettre!
-[HM1_E]
-Je veux que tu montres à ces assoiffés de sang comment ça marche une vraie descente.
+[INT4_F]
+Ferme-la et arrêter de gueuler! T'es encore vivant, pas vrai?
-[HM1_H]
-Fais-moi déguerpir tous ces 'Nines'!
+[INT4_G]
+Laisse-moi là.
-[HM2_A]
-Ces Nines me poussent à bout.
+[INT4_H]
+Débarrasse-toi de la caisse et va roupiller un bon coup.
-[HM2_B]
-Ces salauds ont des voitures blindées et maintenant ils dealent de la SPANK...
+[INT4_I]
+Je passerai à ton bureau demain et on essayera de trouver une solution à ce merdier.
-[HM2_C]
-et ils poussent à la conso chez nous sans être inquiétés.
+[INT4_J]
+Ouais, bonne idée, je vais aller roupiller.
-[HM2_D]
-Y'a une bagnole garée plus haut.
+[INT4_K]
+Qu'est-ce que tu vas faire?
-[HM2_E]
-Y'a des trucs dedans pour mettre ces abrutis hors d'état de nuire...
+[INT4_L]
+Rentrer à mon hôtel.
-[HM3_A]
-Y'en a qui ont piégé ma bagnole pour qu'elle saute.
+[INT4_M]
+Et penser à autre chose que ces conneries.
-[HM3_B]
-Si je perds ma bagnole, ma réputation est foutue.
+[INT4_N]
+Ok.
-[HM3_C]
-Va chercher ma caisse et amène-la au garage en haut de St. Marks, t'as pigé ?
+[LAW]
+MISSIONS AVOCAT
-[HM3_D]
-Laisse-les faire, laisse-les s'occuper de la bombe.
+[LAW1_1]
+~g~Va te procurer de nouvelles fringues à la boutique de Rafael.
-[HM3_E]
-L'horloge tourne et le cablage est un vrai bordel.
+[LAW4_6]
+Brûlez la direction!
-[HM3_F]
-Un nid de poule de trop et ça peut péter.
+[LAW4_7]
+Tuez les patrons!
-[HM3_G]
-Maintenant grouille!
+[LAW4_8]
+Allez! Battez-vous! Allez!
-[HM4_A]
-Un vol de la réserve fédérale s'est crashé à l'atterrissage, à l'aéroport Francis.
+[LAW4_9]
+Plus de vacances! Moins de travail!
-[HM4_B]
-Y'a du platine partout sur la piste.
+[LAW4_11]
+Allez! Battez-vous! Allez!
-[HM4_C]
-Prends une bagnole et va ramasser tout ce que tu peux.
+[LAW4_12]
+Viva la revolucion!
-[HM4_F]
-Tu peux balancer les lingots dans un de mes garages.
+[GENERAL]
+MISSIONS DU COLONEL
-[HM4_G]
-Ce platine, ça pèse le poids d'un âne mort et ça va ralentir ta bagnole.
+[GEN3_4]
+Tommy Vercetti. Allons-y...
-[HM4_H]
-Alors fais plusieurs voyages au garage.
+[GEN3_13]
+C'est quoi ton problème, mec? Monte sur le toit de l'autre côté de la cour avant qu'ils rappliquent!
-[HM5_A]
-Les Nines se sont faits massacrer...
+[GEN3_17]
+Meeeerde! T'essayes de m'buter ou quoi?
-[HM5_B]
-mais ils veulent toujours la guerre.
+[GEN3_21]
+~g~Il a le pognon de Diaz! Attrape-le et récupère le fric!
-[HM5_C]
-Ils sont d'accord pour un duel.
+[GEN3_24]
+~r~Diaz est mort! Tu devais le protéger!
-[HM5_D]
-Un de leurs gangs contre 2 des nôtres, ou plutôt
+[GEN3_26]
+~r~T'as flingué Diaz!
-[HM5_E]
-deux des vôtres.
+[GEN3_27]
+~r~T'as descendu les gardes du corps de Diaz!
-[HM5_F]
-J'irais bien mais...
+[GEN3_31]
+~g~Va au rencart et veille sur Diaz.
-[HM5_G]
-je suis en conditionnelle pour encore trois mois.
+[GEN3_32]
+~g~Va te mettre en position sur le toit du bâtiment en face de Lance.
-[HM5_H]
-Tu vois ce que je veux dire ?
+[COKE]
+MISSIONS BARON DE LA COKE
-[HM5_I]
-Va voir mon petit frère,
+[COK1_3]
+J'espère que tu vas te casser la gueule!
-[HM5_J]
-il te montrera où il faut que t'ailles.
+[COK1_6]
+J'en ai marre de ces merdeux.
-[MEA1_B]
-Mon nom est Chonks, Marty Chonks.
+[COK2_7]
+Tu vois ces marqueurs? Essaye de flinguer les lumières!
-[MEA1_C]
-Je dirige l'usine de pâtée pour chiens juste à coté.
+[COK2_10]
+En tout cas, tu tires mieux que tu causes.
-[MEA1_D]
-J'ai des problèmes de fric, mais qui n'en a pas, hein ?
+[COK2_11]
+Merci. T'as un certain charme aussi.
-[MEA1_E]
-Je dois rencontrer mon banquier plus tard.
+[COK2_12]
+Je sais, Tommy.
-[MEA1_F]
-C'est un sale voleur qui arrête pas d'augmenter les mensualités de mon emprunt pour s'en foutre une part dans la fouille.
+[COK2_18]
+T'aimes bien Kenny Loggins?
-[MEA1_G]
-Prends ma bagnole, va le chercher et ramène-le ici.
+[COK2_19]
+Tu parles, j'adore ce disque ouais!
-[MEA1_H]
-J'ai une petite surprise pour cette sangsue!
+[COK2_26]
+~r~T'as buté Lance!
-[MEA2_A]
-J'ai engagé des cambrioleurs pour braquer mon appart...
+[COK3_1]
+Tire pas, mec!
-[MEA2_C]
-Ces bâtards menacent de tout dire à la compagnie d'assurance,
+[COK3_2]
+Qu'est-ce que c'est que ça?
-[MEA2_D]
-si je les arrose pas plus.
+[COK3_3]
+Il embarque le bateau! Merde!
-[MEA2_E]
-T'y crois toi ?
+[COK3_4]
+A l'aide! Il y a un mec qui nous fauche le bateau!
-[MEA2_F]
-J'ai laissé une voiture dans l'usine.
+[COK4_W]
+Bon! C'est le dernier.
-[MEA2_G]
-Prends-la et va les chercher chez eux dans le Le Quartier Rouge.
+[COK4_X]
+Je vais mettre le moteur en route.
-[MEA2_H]
-Et puis tu les ramènes à l'usine, comme ça je vais pouvoir leur expliquer le point de vue de Marty.
+[COK4_Y]
+Je crois qu'on a de la visite...
-[MEA3_A]
-si je trouve pas du cash tout de suite, mon affaire va couler.
+[COK4_2]
+Ouais.
-[MEA3_B]
-Ma femme a une assurance-vie et tout ce qu'elle a jamais fait pour moi, c'est un trou dans mon budget.
+[COK4_6]
+Tu sais où on va?
-[MEA3_C]
-J'ai laissé la voiture à sa place.
+[COK4_7]
+On est paumés?
-[MEA3_D]
-Va checher ma femme chez la manucure Classic Nails et ramène-la à l'usine.
+[COK4_8]
+On a de la concurrence!
-[MEA4_A]
-Putain, je suis dans la merde!
+[COK4_9]
+Bousille-les!
-[MEA4_B]
-Ben, ma femme voyait un mec à qui je dois de l'argent.
+[COK4_9A]
+L'heure de la danse de Lance Vance a sonné!
-[MEA4_C]
-Il est est très fâché et lui, tout ce qu'il veut, c'est récupérer son pognon!
+[COK4_10]
+Réduits en miettes! Bons à nourrir la poiscaille!
-[MEA4_E]
-Il pense que je vais le rembourser...
+[COK4_11]
+On a réussi! Les autres bateaux ne sont pas de taille.
-[MEA4_F]
-mais moi je pense plutôt que...
+[COK4_17]
+Ils sont prêts à tout!
-[MEA4_G]
-les chiens de Liberty vont devoir s'habituer à une nouvelle pâtée ce mois-ci!
+[COK4_18]
+J'ai les pieds mouillés! On prend la flotte!
-[WELCOME]
-BIENVENUE A
+[COK4_21]
+Pont droit devant!
-[HM1_2]
-~g~Trouve une bagnole et souviens-toi que seuls les meurtres à l'Uzi sont pris en considération!
+[COK4_22]
+Ecope, on va chavirer!
-[HELP8_B]
-Appuie sur la~h~ touche ~k~~PED_SNIPER_ZOOM_IN~ ~w~pour faire un ~h~zoom avant ~w~avec la lunette et sur la ~h~touche ~k~~PED_SNIPER_ZOOM_OUT~~w~ pour faire un ~h~zoom arrière~w~.
+[COK4_23]
+Joli coup.
-[LRQC_1]
-Asuka et moi, on doit parler, hein,
+[COK4_29]
+~r~T'as buté Lance!
-[LRQC_2]
-alors va faire un tour, ok ?
+[ASS1_6]
+Continue, Tommy, ça va aller!
-[LRQC_3]
-T'auras besoin d'un endroit pour te planquer.
+[ASS1_7]
+Prenez ça, enculés d'assassins!
-[LRQC_4]
-Il y a un entrepôt au bord de Belleville qui te conviendra.
+[ASS1_8]
+Je suis coincé!
-[LRQC_5]
-Reviens ici dans mon Condo quand tu es prêt
+[ASS1_9]
+Je te couvre, Tommy!
-[LRQC_6]
-et on aura une petite conversation.
+[ASS1_10]
+Hé, c'est chouette toutes ces plantes...
-[JM6_5]
-~g~Il te faut une caisse pour t'enfuir, imbécile!
+[ASS1_11]
+Hé, Tommy, je peux avoir une chambre avec vue sur la baie?
-[JM2_F]
-Si t'as besoin d'un calibre, va derrière le AmmuNation, en face du métro.
+[ASS1_12]
+Il y a vraiment de superbes plafonds, ici...
-[LOVE4_7]
-~g~Il y a un chantier à l'île Staunton . Ils ont peut-être amené la marchandise là-bas.
+[ASS1_3]
+Lance! Couvre-moi!
-[LOVE4_8]
-~G~Tu auras besoin d'une voiture pour ouvrir le garage.
+[ASS1_5]
+Lance!
-[TSCORE]
-GAINS : ~1~$
+[ASS1_15]
+~g~Attaque la résidence et tue Diaz!
-[AM1_9]
-~r~Salvatore est retourné au club de Luigi!
+[ASS1_17]
+~g~Il existe de nombreux accès à la résidence.
-[AM1_6]
-~g~Si tu restes autour du club de Luigi, la Mafia va te repérer!
+[TAXWAR]
+MISSIONS GUERRE DES TAXIS
-[TM2_3]
-~g~C'est un piège! Descends-les tous!
+[NOTAXI]
+~g~T'as besoin d'un taxi Kaufman pour activer cette mission.
-[FM4_1]
-C'est Maria. La voiture est piégée! Rejoins-moi sur le quai au sud du pont de Callahan.
+[TAXW1_5]
+~g~Faut que tu sois dans un taxi Kaufman!
-[JM1_7]
-~g~Ferme la portière! Il va nous repérer!
+[TAX2_4]
+Vas-y, Tommy.
-[KM5_1]
-~g~DEALER DESCENDU!
+[TAX2_5]
+Massacre-lui la tête.
-[KM5_6]
-~g~Tu dois tuer au moins 8 dealers de Yardie.
+[TAX2_6]
+Il a même pas son permis.
-[KM5_7]
-~g~Ne perds pas de temps! Dès qu'ils auront dealer la SPANK, ils ne resteront pas dans les parages bien longtemps!
+[TAX2_7]
+Putain de limousines!
-[RM3_8]
-~r~Cette bagnole est un leurre!
+[TAXW3_1]
+~g~Va prendre Mercedes.
-[LM3_8]
-Salut. Moi, c'est Joey.
+[RACE1]
+~g~3..2..1.. PARTEZ!
-[LM3_9]
-Luigi m'a dit que t'étais réglo alors reviens plus tard.
+[RACE2]
+~g~3
-[KM3_5]
-~g~Klaxonne pour donner le signal.
+[RACE3]
+~g~2
-[LOVE7]
-LA DISPARITION DE LOVE
+[RACE4]
+~g~1
-[LOVE2_5]
-~g~Kenji est écrabouillé! Tire-toi de Newport et débarrasse-toi de la bagnole.
+[RACE5]
+~g~PARTEZ!
-[AS2_11]
-~g~~1~ SUR 9!
+[FIRST]
+~b~1er
-[GARAGE1]
-~g~Sors de la bagnole et continue à pied.
+[SECOND]
+~b~2e
-[KM3_11]
-~g~Le Cartel a été attaqué et la malette n'a pas été retrouvée.
+[THIRD]
+~b~3e
-[KM3_12]
-~g~Tue tous les Colombiens, détruis les bagnoles et retrouve la malette.
+[FOURTH]
+~b~4e
-[KM3_13]
-~g~Ramène la malette au casino.
+[RACETM]
+~b~TEMPS DE COURSE : ~1~:~1~
-[RM5_6]
-~g~Il s'est enfui! Bousille-lui son plâtre avec une bagnole ou une explosion!
+[RACETM2]
+~b~TEMPS DE COURSE : ~1~:0~1~
-[PBOAT_1] { re3 change }
-Appuie sur la ~h~touche ~k~~VEHICLE_FIREWEAPON~~w~ pour tirer avec les canons du bateau.
+[RACEFA]
+~r~Tu n'as pas gagné la course!
-[PBOAT_2] { re3 change }
-Appuie sur la ~h~touche ~k~~VEHICLE_FIREWEAPON~~w~ pour tirer avec les canons du bateau.
+[TEX1_5]
+~r~Il s'est tiré!
-[DIAB1_B]
-C'est El Burro des Diablos.
+[SEG3_1]
+TEMPS:
-[DIAB1_D]
-T'es nouveau à Liberty mais tu t'es déjà fait une sacrée réputation dans la rue.
+[SEG3_2]
+~g~Va à la camionnette qui contient le bombardier télécommandé et les bombes à retardement.
-[DIAB1_E]
-Il y a une course de bagnoles qui va partir de la vieille école près du pont de Callahan.
+[SEG3_3]
+~g~Utilise le bombardier télécommandé pour transporter 4 bombes vers 4 zones cibles sur le chantier.
-[DIAB1_F]
-Trouve-toi une caisse et le premier qui franchit tous les points de passage, gagne le gros lot.
+[SERG3_5]
+~g~Tu ne peux transporter qu'une bombe à la fois et tu ne peux récupérer une bombe déjà larguée avec succès.
-[HM2_1] { re3 change }
-Utilise les buggies télécommandés pour détruire les voitures blindées. Appuie sur la ~h~touche ~k~~VEHICLE_FIREWEAPON~~w~ pour les faire exploser.
+[SEG3_7]
+~g~Une fois que tu as largué la première bombe sur une zone cible, le compte à rebours s'enclenche. Tu dois larguer toutes les bombes avant la fin de celui-ci.
-[HM2_1A] { re3 change }
-Utilise les buggies télécommandés pour détruire les voitures blindées. Appuie sur la ~h~touche ~k~~VEHICLE_FIREWEAPON~~w~ pour les faire exploser.
+[SEG3_8]
+~g~Les 4 bombes doivent être larguées sur les 4 zones cibles pour réussir la mission et détruire le bâtiment.
-[HM2_2]
-~r~T'as pas réussi à détruire toutes leurs voitures blindées!
+[SEG3_9]
+~g~Tu as touché la cible! Plus que 3!
-[HM2_6]
-~g~Voiture blindée détruite!
+[SEG3_10]
+~g~Tu as touché la cible! Plus que 2!
-[RM3_A]
-Je connais un mec important en ville, un coeur tendre,
+[SEG3_11]
+~g~Tu as touché la cible! Plus qu'une!
-[RM3_H]
-avec ce qu'on pourrait appeler des envies exotiques et l'argent pour les assouvir.
+[SEG3_12]
+~r~Tu as raté la cible! Va récupérer une bombe!
-[RM3_B]
-Il est compromis dans une affaire et l'avocat général a des photos assez embarrassantes de lui,
+[SEG3_13]
+~g~Largue la bombe sur une zone cible.
-[RM3_C]
-pendant une séance de tir ou quelque chose comme ça.
+[SEG3_14]
+~r~Le temps est écoulé et tu n'as pu détruire le bâtiment.
-[LOVE6_A]
-Une leçon en affaires, mon ami.
+[SEG3_15]
+~r~Ton bombardier télécommandé a été détruit! Comment tu vas transporter les bombes, maintenant?
-[LOVE6_E]
-Si tu as quelque chose d'unique, le monde entier essaiera de te le subtiliser..
+[AVERY]
+MISSIONS AVERY
-[LOVE6_C]
-Les équipes spéciales de la police ont fermé le périmètre autour de mon associé et du paquet.
+[ASM]
+MISSIONS ASSASSIN
-[LOVE6_D]
-Va là-bas, prends la camionnette et fais diversion.
+[ASM_1]
+MISSION ASSASSIN 1
-[LOVE6_F]
-Occupe-les pour que nos hommes puissent s'échapper.
+[ASM1_1]
+~g~Ton aide dans l'éradication de ces indésirables fut une excellente affaire. J'ai un autre travail pour toi. Regarde sous le téléphone.
-[AM3_C]
-Il est sûrement dans la baie à l'heure qu'il est! Vole un bateau de la police et fais-le couler!
+[ASM1_2]
+~g~Rends-toi à la cabine en dehors du centre commercial à Washington.
-[FESZ_UC]
-ANNULER
+[ASM1_3]
+~g~Carl Pearson, livreur de pizzas. Il ne doit pas terminer sa tournée.
-[FEDS_SM]
-L1,R1-CHANGER MENU
+[ASM1_4]
+~g~Tue le livreur de pizzas avant qu'il le livre toutes ses pizzas.
-[FEDS_AS]
-;=-CHANGER SELECTION
+[ASM_2]
+MISSION ASSASSIN 2
-[FEDSAS2]
-<>-CHANGER SELECTION
+[ASM_3]
+MISSION ASSASSIN 3
-[FEDS_SS]
-L1,R1-CHANGER SELECTION
+[ASM3_A]
+Marcus Hammond, Franco Carter, Dick Tanner, Nick Kong et Stuntman Driver appartiennent tous au syndicat européen qui s'apprête à faire un hold-up.
-[FEDSSC1]
-;-DEFILEMENT RAPIDE
+[ASM3_B]
+Ils sont tous en position. Il faut qu'ils soient tous morts avant le commencement. Tu as 9 minutes. J'ai laissé quelques flingues à proximité qui devraient t'être utiles.
-[FEDSSC2]
-=-ARRETER DEFILEMENT
+[ASM3_1]
+~g~Va récupérer l'arme que M. Black a laissé pour toi.
-[MEA2_3]
-~g~Ramène la voiture à l'usine.
+[ASM3_2]
+~g~Ne t'approche pas trop près de la cible ou tu risques d'être repéré.
-[RM1_3]
-~r~McCaffrey s'est enfui!
+[ASM3_3]
+~g~Pour un travail propre et rapide, installe-toi près de leurs positions dans des emplacements d'où tu pourras facilement les liquider, sans être repéré.
-[RM1_4]
-~g~T'as utilisé toutes les grenades! Va en chercher chez Ma-Gnum!
+[ASM3_4]
+~g~Il t'a vu! Vaudrait mieux le buter en vitesse, maintenant!
-[RM1_5]
-~g~Retourne là-bas et brûle la barraque!
+[ASM3_5]
+~g~Marcus Hammond est en position près des panneaux publicitaires dans Washington.
-[RM6_4]
-~g~Va aux coffres et ramasse la came de Ray.
+[ASM3_6]
+~g~Franco Carter est en position à côté de DBP Security non loin d'Ocean Drive.
-[RM6_5]
-~g~La CIA surveille le pont, trouve une autre route.
+[ASM3_7]
+~g~Dick Tanner est en position à côté de la bijouterie dans Vice Point.
-[HM2_F]
-Et bousille tous leurs fourgons blindés.
+[ASM3_8]
+~g~Nick Kong est en position près de Washington Beach.
-[HM_4]
-'LA COURSE AUX LINGOTS'
+[ASM3_9]
+~g~Stuntman Driver est en position à Washington.
-[MEA2_B5]
-TEXT NO LONGER NEEDED
+[ASM3_10]
+~r~Tu n'as pas réussi à tous les descendre.
-[MEA1_B5]
-TEXT NO LONGER NEEDED
+[ASM_4]
+MISSION ASSASSIN 4
-[MEA3_B5]
-TEXT NO LONGER NEEDED
+[ASM4_1]
+~g~Va récupérer le fusil laissé à ton intention dans le feuillage à l'extérieur du terminal de l'aéroport.
-[MEA4_B7]
-Mais si tu viens dans mon bureau...
+[ASM4_2]
+~g~Ne rate pas la cible où tu alerteras ses gardes du corps et garde tes distances pour qu'il ne te repère pas.
-[MEA3_B4]
-Marty veut me voir ? Ben, il a intérêt à se dépêcher parce que j'ai rendez-vous chez le coiffeur après.
+[ASM4_3]
+~g~Observe la femme sur le balcon au-dessus des comptoirs d'enregistrements du terminal. NE LA TUE PAS.
-[KM3_7]
-C'est un piège des Yakuzas, mec!
+[ASM4_4]
+~g~Tue l'homme à qui elle donnera la serviette, mais seulement quand il l'aura récupérée. Prends ensuite la serviette et amène-la à Ammu-Nation dans le centre.
-[FES_LOF]
-Echec du chargement.
+[ASM4_5]
+~g~Récupère la serviette!
-[P1INSA]
-Port 1 carte mémoire insérée. ~1~Ko d'espace libre. ~1~Ko requis.
+[ASM4_6]
+~g~Amène la serviette à Ammu-Nation dans le centre!
-[P1INSN]
-Port 1 carte mémoire. Espace libre insuffisant. Veuillez effacer certains fichiers.
+[ASM4_7]
+~r~Imbécile! Tu as tué la femme!
-[FES_SLO]
-FICHIER
+[ASM4_8]
+~r~La cible t'a entendu tirer! Le deal est annulé!
-[FES_ISC]
-EST CORROMPUE
+[ASM4_9]
+~r~La cible a embarqué à bord de son avion!
-[FESZ_TI]
-SAUVEGARDER Z1
+[ASM4_10]
+~r~On dirait que tu n'es pas le seul à t'intéresser à cette serviette! Amène-la en vitesse à Ammu-Nation!
-[FESZ_SA]
-Sauvegarder la partie
+[ASM4_11]
+~r~La cible t'a repéré! Le deal est annulé!
-[P1NOIN]
-Port 1. Carte mémoire non insérée.
+[ASM4_13]
+~g~Il t'a repéré et essaye de s'enfuir! Rattrape-le et récupère la serviette!
-[P1INSE]
-Port 1. Carte mémoire insérée.
+[ASM4_14]
+~g~La barre de distance dans le coin supérieur droit de l'écran te signale ta proximité avec la cible. Ne la laisse pas devenir pleine ou il te repèrera.
-[MC_LDFL]
-Echec du chargement.
+[ASM_5]
+MISSION ASSASSIN 5
-[MC_NWRE]
-Redémarrage du jeu...
+[KICK]
+DEMARRAGE AU PIED
-[LOVE6_3]
-~g~Tu as ~1~ secondes pour retourner au fourgon blindé avant de rater la mission.
+[KICK1_3]
+~g~Nombre de fautes de pied : ~1~
-[LOVE6_4]
-~r~Tu t'es débarrassé de la fausse Sécuricar!
+[KICK1_4]
+~g~Pénalité de temps : ~1~ secondes
-[HELP1]
-Arrête-toi au centre du repère bleu.
+[BANK]
+MISSIONS BRAQUAGE
-[HELP12]
-Va au milieu du repère bleu pour lancer une mission.
+[BANK1]
+MISSION BRAQUAGE 1
-[HJSTAT]
-Distance : ~1~.~1~m Hauteur : ~1~.~1~m Saltos :~1~ Rotation : ~1~'
+[BANK2]
+MISSION BRAQUAGE 2
-[HJSTATW]
-Distance : ~1~.~1~m Hauteur : ~1~.~1~m Saltos : ~1~ Rotation : ~1~ Et quelle belle réception!
+[BJM2_3]
+TAUX DE REUSSITE : ~1~%
-[DIAB1_5]
-TEMPS DE COURSE :
+[BJM2_15]
+SCORE :
-[LOVE3_4]
-~r~Tu as détruit l'avion!
+[BJM2_18]
+SCORE A BATTRE :
-[F_FAIL1]
-Mission Camion de Pompier terminée.
+[BJM2_19]
+~g~Touche autant de cibles que possible dans le temps imparti!
-[F_CANC]
-~r~Mission Pompier annulée!
+[BJM2_21]
+~g~Touche autant de cibles que possible jusqu'à épuisement de tes munitions.
-[F_EXTIN]
-FEUX :
+[BANK3]
+MISSION BRAQUAGE 3
-[A_COMP1]
-Missions Ambulance réussies!
+[BJM3_1]
+~g~Trouve une bagnole qui a des chevaux et rends-toi sur la grille de départ.
-[A_CANC]
-~r~Mission Ambulance annulée!
+[BNK4_2A]
+Les gars au garage ont fait du super boulot sur ce bébé.
-[A_COMP3]
-Missions Ambulance réussies! Tu ne seras jamais fatigué en courant!
+[BNK4_3G]
+Oh, merde, maintenant, on a les flics au cul!
-[ATUTOR]
-Appuie sur la ~h~touche ~k~~TOGGLE_SUBMISSIONS~~w~ pour activer ou désactiver les missions Ambulance.
+[BNK4_3H]
+Et on n'est même pas encore sur place...
-[ATUTOR3]
-Appuie sur la ~h~touche ~k~~TOGGLE_SUBMISSIONS~~w~ pour activer ou désactiver les missions Ambulance.
+[BNK4_3K]
+Va d'abord falloir semer les flics...
-[ALEVEL]
-Mission Ambulance Niveau ~1~
+[BNK4_3L]
+Merde, Tommy, t'essayes de tous nous tuer?
-[A_FAIL1]
-Mission Ambulance terminée.
+[BNK4_3N]
+Tout ce que j'aime part en fumée!
-[FEST_HA]
-Mission Ambulance Niveau Maximum
+[BNK422A]
+Cam, combien de temps?
-[A_SAVES]
-PERSONNES SAUVEES : ~1~
+[BK4_23A]
+Donne-moi 3 minutes!
-[C_KILLS]
-CRIMINELS TUES : ~1~
+[BNK4_26]
+Bordel de merde! Les voilà!
-[HM1_B]
-J'ai un problème, ils essaient de me rouler.
+[BNK4_32]
+Sers-toi des explosifs pour ouvrir les coffres!
-[AM2_A]
-La mort de Salvatore est une bonne nouvelle,
+[BNK4_43]
+Je nous couvre, FONCE!
-[AM2_A2]
-tu es un tueur efficace, j'aime ça chez un homme.
+[BNK4_51]
+Je te trouve très bien comme ça.
-[AM2_B]
-Voilà mon frère, Kenji.
+[KENT]
+MISSIONS KENT PAUL
-[AM2_C]
-Asuka a un petit boulot pour toi, mais quand t'as fini, passe à mon casino et on va causer.
+[KENT1]
+MISSION KENT PAUL 1
-[AM2_D]
-C'est bien Kenji, faut toujours qu'il joue avec mes jouets.
+[COUNT]
+MISSIONS CONTREFACON
-[AM2_E]
-Mon indic à la police m'a dit que la Mafia surveille nos activités en ville
+[COUNT1]
+MISSION CONTREFACON 1
-[AM2_E2]
-et qu'elle est à tes trousses.
+[COUNT2]
+MISSION CONTREFACON 2
-[AM2_F]
-On ne peut pas reprendre nos activités, tant qu'ils sont dans les parages.
+[BIKE]
+MISSIONS BIKERS
-[AM2_G]
-Elimine ces fouille-merde et mets un terme à cette vendetta une bonne fois pour toutes.
+[BIKE1]
+MISSION BIKERS 1
-[F_START]
-~g~Véhicule en feu signalé dans le secteur ~a~. Vas-y et éteins le feu.
+[BIKE2]
+MISSION BIKERS 2
-[AM4_1A]
-Va à la cabine de parc de Belleville ouest.
+[BIKE3]
+MISSION BIKERS 3
-[AM4_1B]
-Va à la cabine du campus de Liberty.
+[GOAWAY1]
+Reviens quand tu auras fini les missions du gang haïtien.
-[AM4_1C]
-Va à la cabine du parc de Belleville sud.
+[HAIT]
+MISSIONS GANG HAITIEN
-[AM4_1D]
-Retrouve-moi dans les toilettes du parc.
+[HAIT1]
+MISSION GANG HAITIEN 1
-[HJSTATF]
-Distance : ~1~ft Hauteur : ~1~ft Saltos :~1~ Rotation : ~1~-
+[HAIT2]
+MISSION GANG HAITIEN 2
-[HJSTAWF]
-Distance : ~1~ft Hauteur : ~1~ft Saltos :~1~ Rotation : ~1~- Et quelle belle réception!
+[HAIT3]
+MISSION GANG HAITIEN 3
-[HM1_F]
-Mais fais gaffe à toi, y'aura aussi des Jacks dans la rue qui vont croire que tu veux aussi les buter.
+[HAM3_6]
+~g~Utilise le fusil à lunette que je t'ai donné pour les tuer!
-[HM1_D]
-Leur nom, c'est 'Nines' et leur drapeau est violet. Et chaque fois qu'ils font parader leurs couleurs...
+[ROCK]
+MISSIONS GROUPE DE ROCK
-[HM1_G]
-les 'Jacks' perdent la face.
+[ROK1_4]
+~g~Ok, je crois que c'est ce que vous vouliez...
-[MEA2_B]
-et voler plein de trucs, comme ça l'assurance me remboursera.
+[ROK1_1E]
+~g~Ca te coûtera plus que ce que tu as!
-[TM3_H]
-~w~T'as fait du bon boulot là-bas petit, c'est très bien.
+[ROK1_1F]
+~g~Reviens quand tu auras le pognon!
-[TM3_I]
-~w~Allez, on va te présenter au Don.
+[RBM2_6]
+~g~Waou! C'est un mec! Arrête-le!
-[TM3_J]
-~w~Hé! Luigi!
+[ROCK3]
+MISSION GROUPE DE ROCK 3
-[TM3_K]
-~w~Oh tu as beaucoup manqué à mes filles, Salvatore, tu as été absent trop longtemps.
+[ROK3_6D]
+~r~en même temps que vos sales grosses têtes chevelues!
-[TM3_L]
-Tu leur diras que, quand tous ces emmerdes seront terminés,
+[ROK3_40]
+Près de la glacière?
-[TM3_M]
-on ira tous à la boîte pour fêter ça, ok ?
+[RBM3_5]
+~g~Emmène les Love Fist au concert.
-[TM3_N]
-~w~Voila mon petit.
+[CUBANM]
+MISSIONS GANG CUBAIN
-[TM3_N2]
-~w~Comment ça va, Papa ?
+[CUBAN1]
+MISSION GANG CUBAIN 1
-[TM3_O]
-~w~Alors tu t'es enfin trouvé une femme ?
+[CUBAN2]
+MISSION GANG CUBAIN 2
-[TM3_P]
-~w~Ta mère, paix à son âme, se retournerait dans sa tombe
+[CUB2_10]
+~r~T'es supposé tuer des Haïtiens, pas des Cubains!
-[TM3_Q]
-~w~de te voir sans femme.
+[CUBAN3]
+MISSION GANG CUBAIN 3
-[TM3_R]
-~w~Je sais 'Pa, j'y travaille.
+[CUBAN4]
+MISSION GANG CUBAIN 40
-[TM3_S]
-~w~Toni! Comment va ta mère ?
+[CUB4_25]
+Ok, allons-y!
-[TM3_T]
-~w~C'est une femme bien. Forte. De Florence.
+[PROT]
+MISSIONS DE PROTECTION
-[TM3_U]
-~w~Ça va... elle va bien.
+[PRO1_H]
+Arrêtez de vous exciter, tous les deux. Je commence à peine à voir comment les choses marchent ici.
-[TM3_V]
-~w~Très bien. Bon les gars, entrez pendant que je parle à notre nouveau venu.
+[PRO1_02]
+~g~Sors du centre commercial.
-[TM3_W]
-~w~Je ne vois que des bonnes choses pour toi, mon petit...
+[PRO3_06]
+~g~Sème les flics.
-[RM1_A]
-Cet enfoiré de McAffrey a accepté plus de pots-de-vin que n'importe qui.
+[PORN]
+MISSIONS PORNO
-[RM1_B]
-Il pense qu'il ne va pas être poursuivi s'il donne des preuves aux condés.
+[PORN1]
+MISSION PORNO 1
-[RM1_C]
-Il a balancé!
+[POR1_03]
+~r~Candy est morte!
-[RM4_B]
-Faut qu'on le réduise au silence définitivement.
+[PORN2]
+MISSION PORNO 2
-[RM4_E]
-Je le veux dormant avec les poissons, pas en train de les bouffer.
+[PORN3]
+MISSION PORNO 3
-[LOVE3_B]
-Ce soir en approchant de l'aéroport de Liberty, un petit avion passera au dessus de la baie.
+[POR3_18]
+T'as été repéré!
-[LOVE4_D]
-Malheureusement, les autorités du port ont saisi l'avion et l'ont mis en pièces
+[PORN4]
+MISSION PORNO 4
-[LOVE4_H]
-avant que je puisse intervenir et ça m'a coûté cher.
+[POR4_04]
+~g~Les bureaux se trouvent de l'autre côté de cette porte.
-[LOVE4_E]
-Traverse le pont et va à l'aéroport International Francis.
+[PHIL]
+MISSIONS PHIL
-[GTAB_A]
-Hé, débarrasse-toi de ça. On ne sait pas ce que c'est
+[PHIL1]
+MISSION PHIL 1
-[GTAB_B]
-mais il a l'air d'y tenir beaucoup, donc ça doit valoir quelque chose.
+[PHI1_06]
+Qu'est-ce que tu fous à conduire comme ça?
-[GTAB_C]
-Qui est-ce qui...
+[PHI1_07]
+Hé!
-[GTAB_D]
-TOI!
+[PHIL2]
+MISSION PHIL 2
-[GTAB_E]
-Hé calme-toi amigo! De nada! De nada!
+[PIZ1_A]
+MISSION LIVREUR DE PIZZA
-[GTAB_F]
-Je t'ai laissé à moitié mort dans le caniveau!
+[PIZ1_03]
+~g~Retourne à la pizzeria pour d'autres commandes.
-[GTAB_G]
-Ne tire pas amigo. Pas de problèmes. On est tous amis. Tiens, prends ça.
+[PIZ1_04]
+~g~Voilà tes nouvelles commandes.
-[GTAB_H]
-Arrête de faire la tapette!
+[PIZ1_10]
+Appuie sur la ~h~ touche R3 ~w~ pour annuler les missions pizzas.
-[GTAB_I]
-On n'a pas le choix, bébé!
+[CNTBUY1]
+Imprimerie achetée : $~1~
-[GTAB_J]
-On a toujours le choix, espèce d'abruti!
+[CARBUY]
+Concession achetée : $~1~
-[GTAB_K]
-Je m'excuse pour cette pute hystérique mec, elles sont toutes les mêmes... por favor ??
+[PORNBUY]
+Studio de cinéma acheté: $~1~
-[GTAB_L]
-Alors la pute s'est barrée.
+[ICEBUY]
+Usine de crème glacée achetée: $~1~
-[GTAB_M]
-Mais tu m'as fait une fleur,
+[TAXIBUY]
+Compagnie de taxis achetée: $~1~
-[GTAB_N]
-tu n'es pas le seul à avoir à régler des comptes avec le Cartel,
+[BANKBUY]
+Club Malibu acheté : $~1~
-[GTAB_O]
-ce cafard a tué mon frère!
+[BOATBUY]
+Chantier naval acheté: $~1~
-[GTAB_P]
-Je n'ai jamais tué de Yakuza!
+[PRNT_NO]
+Tu ne peux pas acheter l'imprimerie pour l'instant, reviens plus tard.
-[GTAB_Q]
-MENTEUR! On a tous vu l'assassin du Cartel.
+[CAR_NO]
+Tu ne peux pas acheter la concession automobile pour l'instant, reviens plus tard.
-[GTAB_R]
-On va tous vous retrouver et vous descendre, vous, les chiens de Colombiens!
+[PORN_NO]
+Tu ne peux pas acheter le studio de cinéma pour l'instant, reviens plus tard.
-[GTAB_S]
-Je vais travailler avec votre ami ici, pour obtenir des informations et un peu de plaisir.
+[ICE_NO]
+Tu ne peux pas acheter l'usine de crème glacée pour l'instant, reviens plus tard.
-[GTAB_T]
-Toi, tu reviens plus tard, je suis sûr que je vais avoir besoin de tes services.
+[TAXI_NO]
+Tu ne peux pas acheter la compagnie de taxis pour l'instant, reviens plus tard.
-[GTAB_U]
-S'il te plait amigo, ne me laisse pas avec elle, c'est une minette psychotique! Amigo ? Hé AMIIIGO!!!... Aïïïïïïïeeeeee!
+[BANK_NO]
+Tu ne peux pas acheter le club Malibu pour l'instant, reviens plus tard.
-[LOVE5_A]
-Tu as prouvé que tu étais un bon investissement, ce qui est rare en ces jours de récession.
+[BOAT_NO]
+Tu ne peux pas acheter le chantier naval pour l'instant, reviens plus tard.
-[KM3_1]
-~g~Le Cartel s'attend à ce qu'un des Yardies vole une voiture de Yardie! Va vers le Nord, tu en trouveras une à Newport.
+[PRNT_R3]
+Appuie sur la touche R3 pour acheter l'imprimerie au prix de $~1~
-[LOVE1_1]
-~g~Va piquer une voiture du gang des Colombiens, comme ça tu pourras rentrer dans leur planque. Dirige-toi vers le Nord, tu en trouveras une à Fort Stanton.
+[CAR_R3]
+Appuie sur la touche R3 pour acheter la concession automobile au prix de $~1~
-[FM1_Q1]
-~w~Vous voulez vous amuser ? Un petit... hmm ? Du Spank ?
+[PORN_R3]
+Appuie sur la touche R3 pour acheter le studio de cinéma au prix de $~1~
-[FM1_R]
-~w~Salut Chico. Non, comme d'habitude.
+[ICE_R3]
+Appuie sur la touche R3 pour acheter l'usine de crème glacée au prix de $~1~
-[FM1_T]
-~w~Merci Chico. A plus tard.
+[TAXI_R3]
+Appuie sur la touche R3 pour acheter la compagnie de taxis au prix de $~1~
-[FM1_W]
-~w~Ok Fido, tu attends ici et tu surveilles la caisse pendant que je vais m'éclater.
+[BANK_R3]
+Appuie sur la touche R3 pour acheter le club Malibu au prix de $~1~
-[FM1_X]
-~w~Ok Fido, tirons-nous d'ici. Ouuulaa!
+[BOAT_R3]
+Appuie sur la touche R3 pour acheter le chantier naval au prix de $~1~
-[FM1_Q]
-~w~Hé Maria! C'est ma plus belle jument!
+[COL2_6]
+Arrête espèce de porc impérialiste d'Américain!
-[FM1_S1]
-~w~Tu devrais passer à la fête de l'entrepôt à l'est d'Atlantic Quays.
+[COL2_6B]
+Ceci est la propriété du gouvernement français!
-[FM1_U]
-~w~Gracias et éclate-toi. C'est de la bombe.
+[COL2_6C]
+Et c'est terminé.
-[FM1_V]
-~w~Allez Fido, on va aller faire un tour à cette fête!
+[COL3_A]
+Thomas, merci d'être venu.
-[FM1_SS]
-~r~SCANNER : ~w~Quatre-Cinq à toutes les unités : rejoignez les stups à Atlantic Quays...
+[COL3_B]
+Désolé d'aller droit au but...
-[LOVE6_B]
-Même s'ils n'ont pas la moindre idée de sa vraie valeur.
+[COL3_C]
+Diaz m'a demandé de superviser une petite transaction financière.
-[TM3_A1]
-~r~Joey s'est fait avoir!
+[COL3_D]
+Espérons que ça se passera mieux que la dernière fois.
-[TM3_A2]
-~r~Joey et Luigi se sont fait descendre!
+[COL3_E]
+C'est la raison pour laquelle j'ai pensé à vous, mon ami.
-[TM3_A3]
-~r~Joey, Luigi et Toni se sont fait buter!
+[COL3_F]
+J'ai laissé un revolver au parking à niveaux.
-[FM4_2]
-Salvatore pense qu'on le court-circuite,
+[COL3_G]
+Récupèrez-le et allez surveiller les mecs de Diaz au dépôt.
-[FM4_3]
-alors il voulait te donner au Cartel pour pouvoir faire un deal.
+[COL4_2]
+Je sais pas, chef!
-[FM4_4]
-Je pouvais pas le laisser faire, je veux dire,
+[COL4_5]
+Chef, oui, chef!
-[FM4_4B]
-tout ça, c'est de ma faute... parce que je lui ai dit qu'on était ensemble.
+[COL4_10]
+Allons manger quelques beignets.
-[FM4_5]
-Me demande pas pourquoi. J'en sais rien.
+[COL4_16]
+Chef, on déplace le véhicule, chef!
-[FM4_6]
-T'es sur la liste rouge dans la Mafia et je veux me tirer d'ici, moi aussi.
+[COL4_25]
+Autodestruction du véhicule initialisée!
-[FM4_6B]
-J'ai vu trop de crimes. Trop de sang!
+[COL5_6]
+Mercedes, cette fille aura ma peau.
-[FM4_7]
-C'est une amie à moi Ok, une vieille copine... Elle s'appelle Asuka, on peut lui faire confiance.
+[COL5_8]
+Maudit cafard!
-[FM4_8]
-Allez, on a assez causé.
+[COL5_5]
+Crevez, porcs de Français!
-[FM4_9]
-On ferait mieux de se barrer avant d'avoir tous ces Italiens hystériques aux fesses.
+[CNT2_1]
+Tuez-le!
-[CRED001]
-ROCKSTAR STUDIOS
+[CNT2_2]
+Récupérez les plaques!
-[CRED002]
-PRODUCER
+[CNT2_3]
+Protégez le coursier!
-[CRED003]
-LESLIE BENZIES
+[FINKILL]
+Ok, les mecs, butez-le!
-[CRED004]
-ART DIRECTOR
+[FIN_6]
+Sonny est en haut avec le coffre et MON argent...
-[CRED005]
-AARON GARBUT
+[FIN_10]
+Sonny? SONNY! Je viens te chercher!
-[CRED006]
-TECHNICAL DIRECTION
+[RACES_4]
+3
-[CRED007]
-OBBE VERMEIJ
+[RACES_5]
+2
-[CRED008]
-ADAM FOWLER
+[RACES_6]
+1
-[CRED009]
-DESIGN
+[RACES_7]
+PARTEZ!
-[CRED010]
-CRAIG FILSHIE
+[RACES_9]
+Temps : ~1~:~1~
-[CRED011]
-WILLIAM MILLS
+[RACES]
+TEMPS :
-[CRED012]
-CHRIS ROTHWELL
+[RACES17]
+Nv temps record : ~1~:~1~
-[CRED013]
-JAMES WORRALL
+[RACES20]
+Nv temps record : ~1~:0~1~
-[CRED014]
-WRITTEN BY
+[RACES21]
+Temps : ~1~:0~1~
-[CRED015]
-JAMES WORRALL
+[RCH1_1]
+~g~Utilise l'hélicoptère radiocommandé, le RC Raider, pour PASSER les points de passage.
-[CRED016]
-PAUL KUROWSKI
+[RCH1_2]
+~g~Les POINTS DE PASSAGE sont disséminés dans l'aéroport.
-[CRED017]
-DAN HOUSER
+[RCH1_3]
+~g~Tu as ~c~8 minutes~g~ pour passer les ~c~20!
-[CRED018]
-CHARACTERS
+[RCH1_5]
+Temps
-[CRED019]
-IAN MCQUE
+[RCRC1_1]
+~g~Fais une COURSE DE POINTS DE PASSAGE contre deux autres RC Bandits sur 2 TOURS
-[CRED020]
-ANIMATION & DIRECTION
+[RCRC1_2]
+~g~Va sur la grille de départ!
-[CRED021]
-ALEX HORTON
+[RCRC1_3]
+~g~Dernier tour!
-[CRED022]
-LEE MONTGOMERY
+[RCRC1_4]
+~g~3
-[CRED023]
-AUTO DESIGN
+[RCRC1_5]
+~g~2
-[CRED024]
-PAUL KUROWSKI
+[RCRC1_6]
+~g~1
-[CRED025]
-ARTISTS
+[RCRC1_7]
+~g~PARTEZ!
-[CRED026]
-KEIRAN BAILLIE
+[RCRC1_8]
+~g~Temps de course : ~1~ secondes
-[CRED027]
-ADAM COCHRANE
+[RCPL1_1]
+~g~Fais une COURSE DE POINTS DE PASSAGE contre 3 autres RC Baron
-[CRED028]
-GARY MCADAM
+[RCPL1_2]
+~g~Tu dois passer par le ~o~CENTRE CORONA ~g~pour valider un point de passage.
-[CRED029]
-MICHAEL PIRSO
+[RCPL1_3]
+~g~Va sur la grille de départ maintenant!
-[CRED030]
-ANDREW SOOSAY
+[FEA_2SP]
+2 haut-parleurs
-[CRED031]
-ALISDAIR WOOD
+[FEA_4SP]
+Plus de 2 haut-parleurs
-[CRED032]
-CODERS
+[FEA_EAR]
+Casque
-[CRED033]
-ALAN CAMPBELL
+[FEA_NAH]
+PAS DE MATERIEL AUDIO
-[CRED034]
-MARK HANLON
+[FET_APP]
+APPLIQUER
-[CRED035]
-ANDRZEJ MADAJCZYK
+[FES_SKN]
+NOM DU SKIN
-[CRED036]
-ALEXANDER ROGER
+[FES_DAT]
+DATE
-[CRED037]
-GRAEME WILLIAMSON
+[FES_SET]
+Utiliser Skin
-[CRED038]
-SCORE
+[FET_DEF]
+Par défaut
-[CRED039]
-CRAIG CONNER
+[FESZ_QZ]
+Veux-tu vraiment sauvegarder cette partie?
-[CRED040]
-STUART ROSS
+[FES_SCG]
+Sauvegarder la partie en cours?
-[CRED041]
-SOUND DESIGN & MASTERING
+[FES_LCG]
+Charger la partie et continuer à jouer?
-[CRED042]
-ALLAN WALKER
+[FEC_FIR]
+Tirer
-[CRED043]
-AUDIO PROGRAMMING
+[FEC_NWE]
+Arme suivante
-[CRED044]
-RAYMOND USHER
+[FEC_PWE]
+Arme précédente
-[CRED045]
-TEST MANAGER
+[FEC_FOR]
+Avant
-[CRED046]
-CRAIG ARBUTHNOTT
+[FEC_BAC]
+Arrière
-[CRED047]
-LEAD TESTERS
+[FEC_LEF]
+Gauche
-[CRED048]
-ANDY DUTHIE
+[FEC_RIG]
+Droite
-[CRED049]
-JOHN HAIME
+[FEC_ZIN]
+Zoom avant
-[CRED050]
-NEIL CORBETT
+[FEC_ZOT]
+Zoom arrière
-[CRD050A]
-TESTERS
+[FEC_EEX]
+Entrer+sortir
-[CRED051]
-GRAEME JENNINGS
+[FEC_RAD]
+Radio
-[CRED052]
-DAVID MURDOCH
+[FEC_SUB]
+Sous-mission
-[CRED053]
-DAVID BEDDOES
+[FEC_CMR]
+Changer caméra
-[CRED054]
-EDWIN SMITH
+[FEC_JMP]
+Sauter
-[CRED055]
-MARK FLETT
+[FEC_SPN]
+Courir
-[CRED056]
-MICHAEL SUTHERLAND
+[FEC_HND]
+Frein à main
-[CRED057]
-TECHNICAL SUPPORT
+[FEC_LOL]
+Regarder à gauche
-[CRED058]
-LORRAINE ROY
+[FEC_LOR]
+Regarder à droite
-[CRED059]
-CHRISTINE CHALMERS
+[FEC_NTR]
+Cible suivante
-[CRED060]
-ROCKSTAR
+[FEC_PTT]
+Cible précédente
-[CRED061]
-EXECUTIVE PRODUCER
+[FEC_LBA]
+Regarder derrière
-[CRED062]
-SAM HOUSER
+[FEC_CEN]
+Centrer caméra
-[CRED063]
-PRODUCER
+[FET_CCN]
+Classique
-[CRED064]
-DAN HOUSER
+[FET_SCN]
+Standard
-[CRED065]
-DIRECTOR OF DEVELOPMENT
+[FET_CFT]
+A PIED
-[CRED066]
-JAMIE KING
+[FET_CCR]
+EN VOITURE
-[CRED067]
-TECHNICAL PRODUCER
+[FET_CAC]
+ACTION
-[CRED068]
-GARY J. FOREMAN
+[FEC_IBT]
+-
-[CRED069]
-ASSOCIATE PRODUCER
+[FEC_MXO]
+MXB1
-[CRED070]
-JEREMY POPE
+[FEC_MXT]
+MXB2
-[CRED071]
-MUSIC SUPERVISOR
+[FEC_UNB]
+NON LIE
-[CRED072]
-TERRY DONOVAN
+[FEC_TFL]
+Regard gauche+tourelle G
-[CRED073]
-ROCKSTAR PRODUCTION TEAM
+[FEC_TFR]
+Regarde droite+tourelle D
-[CRED074]
-TERRY DONOVAN
+[FEC_MWF]
+VOLANT MS HAUT
-[CRED075]
-JENNIFER KOLBE
+[FEC_MWB]
+VOLANT MX BAS
-[CRED076]
-JENEFER GROSS
+[FEC_ORR]
+ou
-[CRED077]
-LAURA PATERSON
+[FEC_NUS]
+NON UTILISE
-[CRED078]
-JEFF CASTANEDA
+[FEC_LUD]
+Regarder en haut
-[CRED079]
-CHRIS CARRO
+[FEC_LDU]
+Regarder en bas
-[CRED080]
-ADAM TEDMAN
+[FEC_CMP]
+COMBO : REGARDER G+D
-[CRED081]
-JUNG KWAK
+[LAW_1A]
+law_1a
-[CRED082]
-BRIAN WOOD
+[LAW_1B]
+law_1b
-[CRED083]
-PAUL YEATES
+[LAW_2A]
+law_2a
-[CRED084]
-STANTON SARJEANT
+[LAW_2B]
+law_2b
-[CRED085]
-VP OF MARKETING
+[FEH_STA]
+STATS
-[CRED086]
-TERRY DONOVAN
+[FEH_LOA]
+CHARGER
-[CRED087]
-TECHNICAL COORDINATOR
+[FEH_CON]
+COMMANDES
-[CRED088]
-BRANDON ROSE
+[FEH_AUD]
+AUDIO
-[CRED089]
-QA MANAGER
+[FEH_DIS]
+AFFICHAGE
-[CRED090]
-JEFF ROSA
+[FEH_LAN]
+LANGUE
-[CRED091]
-LEAD ANALYST
+[FEH_SGA]
+LANCER NOUVELLE PARTIE
-[CRED092]
-ADAM DAVIDSON
+[FEO_CON]
+Configuration manette
-[CRED093]
-GAME ANALYST
+[FEO_AUD]
+Configuration audio
-[CRED094]
-RICHARD HUIE
+[FEO_DIS]
+Configuration affichage
-[CRED095]
-TEST TEAM
+[FEO_LAN]
+Choix langue
-[CRED096]
-LANCE WILLIAMS
+[FEO_PLA]
+Configuration joueur
-[CRED097]
-JOE GREENE
+[FEA_OUT]
+Sortie
-[CRED098]
-BRIAN PLANER
+[FEA_ST]
+Stéréo
-[CRED099]
-OSWALD GREENE
+[FEA_DTS]
+DTS
-[CRED100]
-LIBERTY TREE EDITORIAL
+[FEA_RSS]
+Station de radio
-[CRED101]
-JAMES WORRALL
+[FEA_NON]
+RADIO ETEINTE
-[CRED102]
-DAN HOUSER
+[FEA_FM0]
+WILDSTYLE
-[CRED103]
-ADAM TEDMAN
+[FEA_FM1]
+FLASH FM
-[CRED104]
-PAUL YEATES
+[FEA_FM2]
+KCHAT
-[CRED105]
-JENEFER GROSS
+[FEA_FM3]
+FEVER 105
-[CRED106]
-LAURA PATERSON
+[FEA_FM4]
+VROCK
-[CRED107]
-CUT-SCENES
+[FEA_FM5]
+VCPR
-[CRED108]
-SCRIPT BY DAN HOUSER AND JAMES WORRALL
+[FEA_FM7]
+EMOTION 98.3
-[CRED109]
-AUDIO DIRECTED BY DAN HOUSER
+[FEA_FM8]
+ONDE 103
-[CRED110]
-AUDIO PRODUCED BY RENAUD SEBBANE
+[FED_BRI]
+Luminosité
-[CRED111]
-CAST
+[FED_TRA]
+Rémanences :
-[CRED112]
-FRANK VINCENT AS SALVATORE LEONE
+[FED_SUB]
+Sous-titres
-[CRED113]
-JOE PANTOLIANO AS LUIGI GOTERELLI
+[FED_WIS]
+Ecran large
-[CRED114]
-MICHAEL MADSEN AS TONI CIPRIANI
+[FED_POS]
+Position écran
-[CRED115]
-MICHAEL RAPAPORT AS JOEY LEONE
+[FEP_RES]
+Reprendre
-[CRED116]
-DEBBI MAZAR AS MARIA
+[FEP_STG]
+Commencer partie
-[CRED117]
-KYLE MACLACHLAN AS DONALD LOVE
+[FEP_STA]
+Stats
-[CRED118]
-ROBERT LOGGIA AS RAY MACHOWSKI
+[FEP_BRI]
+Briefings
-[CRED119]
-GURU AS 8-BALL
+[FEP_OPT]
+Options
-[CRED120]
-SONDRA JAMES AS MOMMA
+[FEP_QUI]
+Quitter partie
-[CRED121]
-LIANA PAI AS ASUKA
+[FES_LOA]
+Charger partie
-[CRED122]
-LES MAU AS KENJI
+[FES_DEL]
+Effacer partie
-[CRED123]
-CYNTHIA FARRELL AS CATALINA
+[FEC_CSU]
+Configuration manette
-[CRED124]
-AL ESPINOSA AS MIGUEL
+[FEC_RED]
+Réassigner commandes
-[CRED125]
-CHRIS PHILLIPS AS EL BURRO
+[FEC_MOU]
+Paramètres souris
-[CRED126]
-HUNTER PLATIN AS CHICO
+[DISTGOL]
+Dist. parcourue en voiturette (miles)
-[CRED127]
-WALTER MUDU AS D-ICE
+[DISTGOM]
+Distance parcourue en voiturette (m)
-[CRED128]
-CURTIS MCCLARIN AS CURTLY
+[ST_FAVR]
+Station de radio préférée
-[CRED129]
-BILL FIORE AS DARKEL
+[ST_WSTR]
+Station de radio la moins écoutée
-[CRED130]
-CHRIS PHILLIPS AS MARTY CHONKS
+[ST_FAVV]
+Véhicule préféré
-[CRED131]
-HUNTER PLATIN AS CURLY BOB
+[ST_STAR]
+Total d'étoiles de recherche obtenues
-[CRED132]
-WALTER MUDU AS KING COURTNEY
+[ST_HEAD]
+Nombre de tirs à la tête
-[CRED133]
-HUNTER PLATIN AS ONE-ARMED PHIL
+[ST_GANG]
+Gang le moins apprécié
-[CRED134]
-KIM GURNEY AS MISTY
+[ST_STGN]
+Total d'étoiles de recherche évitées
-[CRED135]
-MOTION CAPTURE
+[TYREPOP]
+Pneus crevés avec des balles
-[CRED136]
-ANIMATED BY
+[TYRESLA]
+Pneus lacérés avec une lame
-[CRD136A]
-ALEX HORTON
+[ST_BRK]
+Nombre de victimes dans le Bloodring
-[CRED137]
-DIRECTED BY
+[ST_LTBR]
+Plus longue durée dans le Bloodring (sec)
-[CRD137A]
-NAVID KHONSARI
+[ST_GNG1]
+Cubains
-[CRED138]
-PRODUCED BY
+[ST_GNG2]
+Haïtiens
-[CRD138A]
-JAMIE KING
+[ST_GNG3]
+Faux voyous
-[CRD138B]
-RENAUD SEBBANE
+[ST_GNG4]
+Gang de Diaz
-[CRED139]
-RECORDED AT MODERN UPRISING STUDIOS, BROOKLYN
+[ST_GNG5]
+Agents de sécurité
-[CRED140]
-ACTORS
+[ST_GNG6]
+Gang de motards
-[CRD140A]
-RENAUD SEBBANE
+[ST_GNG7]
+Gang de Vercetti
-[CRD140B]
-GISELLE JONES
+[ST_GNG8]
+Golfeurs
-[CRD140C]
-STEPHEN DANIELS
+[FEA_FM6]
+ESPANTOSO
-[CRD140D]
-ROBERT STIO
+[ST_ASSI]
+Contrats exécutés
-[CRD140E]
-JENNY GROSS.
+[DISTBIK]
+Dist. parcourue à moto (miles)
-[CRED141]
-PEDESTRIAN DIALOGUE
+[DISTBIM]
+Dist. parcourue à moto (m)
-[CRED142]
-WRITTEN BY DAN HOUSER, NAVID KHONSARI & JAMES WORRALL
+[HOTEL]
+Hôtel Ocean View
-[CRED143]
-DIRECTED BY CRAIG CONNER, DAN HOUSER AND LAZLOW
+[ICC1_1]
+~g~Utilise ta camionnette de crème glacée pour distribuer de la drogue à Vice City.
-[CRED144]
-PRODUCED BY RENAUD SEBBANE
+[ICC1_2]
+~g~Gare ta camionnette et appuie sur ~h~~k~~VEHICLE_HORN~~w~ pour jouer le jingle et signaler à tes clients que tu es prêt.
-[CRED145]
-CAST
+[ICC1_3]
+~g~Tu reçois de l'argent pour chaque transaction faite, mais plus tu fais d'affaires, plus tu attires l'attention de la police.
-[CRED146]
-HUNTER PLATIN
+[KICK1_9]
+POINTS DE PASSAGE RESTANTS :
-[CRED147]
-DAN HOUSER
+[FIN_B6]
+Tu n'as pas assez d'argent pour commencer cette mission.
-[CRED148]
-RENAUD SEBBANE
+[TEX3_3]
+~g~Pour ramasser une bombe, manoeuvre l'hélico au-dessus d'elle. La bombe est alors automatiquement fixée sous la carlingue.
-[CRED149]
-MARIA CHAMBERS
+[TEX3_9]
+~g~Ramasse une bombe en manoeuvrant l'hélico à côté d'elle.
-[CRED150]
-JEFF STANTON
+[HELP22]
+Va vers la position du bip de la maison verte sur le radar.
-[CRED151]
-RYAN CROY
+[FES_FMS]
+Formatage terminé. Sélectionne OK pour continuer.
-[CRED152]
-DEENA BERMAN
+[FES_SSC]
+Sauvegarde terminée. Sélectionne OK pour continuer.
-[CRED153]
-MARIA CHAMBERS
+[FES_DSC]
+Suppression terminée. Sélectionne OK pour continuer.
-[CRED154]
-ALICE B. SALTZMAN
+[FESZ_QC]
+Ecraser ce fichier de sauvegarde corrompu?
-[CRED155]
-ALEX ANTHONY SIOUKAS
+[FES_CHE]
+Attention! Un ou plusieurs codes ont été activés, ce qui peut affecter votre fichier de sauvegarde. Sauvegarde déconseillée.
-[CRED156]
-SEAN R. LYNCH
+[FET_SG]
+SAUVEGARDER
-[CRED157]
-AMY SALZMAN
+[FEH_BRI]
+BRIEFING
-[CRED158]
-COLIN MCSHANE
+[FEH_MAP]
+CARTE
-[CRED159]
-COREY WADE
+[FEM_OK]
+OK
-[CRED160]
-GERALD COSGROVE
+[FEC_CRO]
+S'accroupir
-[CRED161]
-STEPHANIE ROY
+[FEC_CR3]
+S'accroupir (touche L3)
-[CRED162]
-DORIS WOO
+[FEC_SMT]
+Sous-mission
-[CRED163]
-JOSEPH GREENE
+[FEC_SM3]
+Sous-mission (touche R3)
-[CRED164]
-LAZLOW JONES
+[FEC_RSC]
+Stations de radio
-[CRED165]
-HSIANG LIN
+[ST_PR01]
+Pilote
-[CRED166]
-STEVE MICHAEL ROBERT
+[ST_PR02]
+Soldat armée de l'air
-[CRED167]
-MATHEW MURRAY
+[ST_PR03]
+Officier pilote
-[CRED168]
-RICHARD HUIE
+[ST_PR04]
+Caporal
-[CRED169]
-GARVIN ATWELL
+[ST_PR05]
+Lieutenant
-[CRED170]
-STEVE KNEZEVICH
+[ST_PR06]
+Sergent
-[CRED171]
-YUKIMURA SATO
+[ST_PR07]
+Capitaine
-[CRED172]
-FRANK CHAVEZ
+[ST_PR08]
+Biggs
-[CRED173]
-LIEZL JACINTO
+[ST_PR09]
+Wedge
-[CRED174]
-CANAAN MCKOY
+[ST_PR10]
+Baron rouge
-[CRED175]
-ADAM DAVIDSON
+[ST_PR11]
+Goose
-[CRED176]
-LANCE WILLIAMS
+[ST_PR12]
+Viper
-[CRED177]
-NEIL MCCAFFREY
+[ST_PR13]
+Jester
-[CRED178]
-LAURA PATERSON
+[ST_PR14]
+Chappy
-[CRED179]
-REY CONCEPCION
+[ST_PR15]
+Iceman
-[CRED180]
-CHARLES HEROLD
+[ST_PR16]
+Maverick
-[CRED181]
-ANDREW GREENWALD
+[ST_PR17]
+Noops
-[CRED182]
-JAMES MIELKE
+[ST_PR18]
+Maréchal de l'air
-[CRED183]
-PETER SUCIU
+[ST_PR19]
+As
-[CRED184]
-ALEX ODULIO
+[FET_LG]
+Charger partie
-[CRED185]
-DON NKRUMAH
+[CAR_EXP]
+Véhicules routiers détruits
-[CRED186]
-KENDALL PITTMAN
+[BOA_EXP]
+Bateaux détruits
-[CRED187]
-SAL SUAZO
+[HEL_DST]
+Avions et hélicoptères détruits
-[CRED188]
-EREK MATEO
+[STFT_01]
+Meilleur temps sur 'Alliage d'Acier'
-[CRED189]
-CHRIS DIFATE
+[STFT_02]
+Meilleur temps sur 'Le chauffeur'
-[CRED190]
-LEILA MILTON
+[STFT_03]
+Meilleur temps sur Dirt Ring
-[CRED191]
-DARREN ZOLTOWSKI
+[STFT_04]
+Meilleur temps course avion télécommandé
-[CRED192]
-VIRGINIA SMITH
+[STFT_05]
+Meilleur temps course voiture télécommandée
-[CRED193]
-KEVIN CASSIN
+[STFT_06]
+Meilleur temps hélico télécommandé
-[CRED194]
-JASON SHIGEMORI
+[STFT_07]
+Meilleur temps sur 'Terminal Velocity'
-[CRED195]
-KELLY KINSELLA
+[STFT_08]
+Meilleur temps sur 'Ocean Drive'
-[CRED196]
-MOLLIE STICKNEY
+[STFT_09]
+Meilleur temps sur 'Border Run'
-[CRED197]
-STANTON SARJEANT
+[STFT_10]
+Meilleur temps sur 'Capital Cruise'
-[CRED198]
-LAURA WALSH
+[STFT_11]
+Meilleur temps sur 'Virée!'
-[CRED199]
-MARK GARONE
+[STFT_12]
+Meilleur temps sur 'Endurance V.C.'
-[CRED200]
-JOANNA SLY
+[STHC_01]
+Meilleur score sur Le Flingueur.
-[CRED201]
-ELIZABETH HOWELL
+[STHC_02]
+Meilleur pourcentage de tir au but sur le Flingueur.
-[CRED202]
-ANA HERCULES
+[STHC_03]
+Nombre de deals de drogue
-[CRED203]
-SHIRLEY IRICK
+[HELP24]
+Tu peux maintenant bosser pour le colonel.
-[CRED204]
-KASHONA FIELDS
+[HELP25]
+Tu peux maintenant bosser pour Avery Carrington
-[CRED205]
-JOEL M. LILJE
+[HELP29]
+Tu peux te rendre au magasin de fringues quand tu n'es pas en mission.
-[CRED206]
-JOHN DIBENEDETTO
+[HELP30]
+Quand tu achètes de nouvelles fringues, ton indice de recherche retombe à zéro.
-[CRED207]
-NANCY GILES
+[BJM2_22]
+~r~Tu as quitté le stand de tir!
-[CRED208]
-RYAN CROY
+[BJM2_23]
+~g~Si tu quittes le stand de tir pendant la compétition, la mission est un échec.
-[CRED209]
-JENNIFER KOLBE
+[ASM4_24]
+Distance :
-[CRED210]
-LIAM BURKE
+[RBM1_6]
+~g~Ramène Mercedes et le Love Juice au groupe, au studio d'enregistrement.
-[CRED211]
-SIGRID PREISSL
+[RBM1_3]
+PLUS NECESSAIRE
-[CRED212]
-ANITA FITZSIMONS
+[HAM1_5]
+PLUS NECESSAIRE
-[CRED213]
-PHILIPPA RASELLI
+[RBM1_11]
+PLUS NECESSAIRE
-[CRED214]
-WIL QUESNEL
+[HELP31]
+Pour réaliser un arrosage latéral, regarde d'abord à droite ou à gauche en utilisant ~k~~VEHICLE_LOOKLEFT~ ou ~k~~VEHICLE_LOOKRIGHT~.
-[CRED215]
-FALKO BURKERT
+[HELP34]
+Tu dois être armé d'une mitraillette pour réaliser un arrosage latéral.
-[CRED216]
-SARA SEWELL
+[STRIP_1]
+~r~T'as pas assez de pognon, pauvre fauché!
-[CRED217]
-RADIO STATIONS AND MUSIC
+[EXIT_1]
+Appuie sur ~k~~PED_SPRINT~ pour sortir.
-[CRED218]
-PRODUCERS FOR ROCKSTAR UK
+[ASM1_A]
+M. Teal, votre aide dans l'éradication de ces indésirables fut une excellente affaire. J'ai un autre travail plus en finesse pour vous.
-[CRD218A]
-CRAIG CONNER
+[ASM1_B]
+Regardez sous le téléphone.
-[CRD218B]
-STUART ROSS
+[ASM1_C]
+J'ai un autre travail plus en finesse pour vous.
-[CRED219]
-SOUNDTRACK CO-ORDINATOR
+[SCARF]
+Appartement 3c
-[CRED220]
-TERRY DONOVAN
+[LAW4_10]
+Les patrons sont tous des salauds!
-[CRED221]
-PRODUCER FOR ROCKSTAR GAMES
+[GEN1_04]
+~g~Passe la porte pour accéder au toit de Gonzalez.
-[CRED222]
-DAN HOUSER
+[GEN1_17]
+~g~Gonzalez se fait la malle! Suis-le et finis-en avec lui!
-[CRED223]
-EDITED BY
+[RCH1_9]
+~b~TEMPS TOTAL : ~1~:~1~
-[CRED224]
-CRAIG CONNER
+[RCH1_10]
+~b~TEMPS TOTAL : ~1~:0~1~
-[CRED225]
-ALLAN WALKER
+[WHEEL01]
+DOUBLE BONUS DEUX ROUES : $ ~1~ Distance : ~1~.~1~m Temps : ~1~ secondes
-[CRED226]
-LAZLOW
+[WHEEL02]
+DOUBLE BONUS DEUX ROUES : $ ~1~ Distance : ~1~ feet Temps : ~1~ secondes
-[CRED227]
-DJ BANTER AND IMAGING WRITTEN BY
+[WHEEL03]
+BONUS DEUX ROUES : $ ~1~ Temps : ~1~ secondes
-[CRED228]
-DAN HOUSER
+[WHEEL04]
+BONUS DEUX ROUES : $ ~1~ Distance : ~1~.~1~m
-[CRED229]
-LAZLOW
+[WHEEL05]
+BONUS DEUX ROUES : $ ~1~ Distance : ~1~ pieds
-[CRED230]
-SPECIAL THANKS TO
+[WHEEL06]
+BONUS ROUE ARRIERE : $ ~1~ Distance : ~1~.~1~m Temps : ~1~ secondes
-[CRED231]
-ADAM TEDMAN
+[WHEEL07]
+BONUS ROUE ARRIERE : $ ~1~ Distance : ~1~ feet Temps : ~1~ secondes
-[CRED232]
-ALEX MASON
+[WHEEL08]
+BONUS ROUE ARRIERE : $ ~1~ Temps : ~1~ secondes
-[CRED233]
-JUDY HENDERSON CASTING
+[WHEEL09]
+BONUS ROUE ARRIERE : $ ~1~ Distance : ~1~.~1~m
-[CRED234]
-HAMISH BROWN
+[WHEEL10]
+BONUS ROUE ARRIERE : $ ~1~ Distance : ~1~ pieds
-[CRED235]
-CHRISSY HOBAN
+[WHEEL11]
+BONUS ROUE AVANT : $ ~1~ Distance : ~1~.~1~m Temps : ~1~ secondes
-[CRED236]
-INNES RICARD
+[WHEEL12]
+BONUS ROUE AVANT : $ ~1~ Distance : ~1~ pieds Temps : ~1~ secondes
-[CRED237]
-LILION BROZSKA
+[WHEEL13]
+BONUS ROUE AVANT: $ ~1~ Temps : ~1~ secondes
-[CRED238]
-BOB HILLARY
+[WHEEL14]
+BONUS ROUE AVANT : $ ~1~ Distance : ~1~.~1~m
-[CRED239]
-EMILY ANDERSON
+[WHEEL15]
+BONUS ROUE AVANT : $ ~1~ Distance : ~1~ pieds
-[CRED240]
-RICHIE HENDERSON
+[ROK3_72]
+Love Fist!
-[CRED241]
-CHRSTIAN CANTAMESSA
+[POR1_19]
+Hé!
-[CRED242]
-JERONIMO BARRERA
+[DESPERA]
+Desperado
-[CRED243]
-ALEXANDER ILLES
+[MOB_99A]
+Rends-toi à la cabine près du centre commercial à Washington.
-[CRED244]
-BARANE CHAN
+[MOB_98A]
+Rends-toi à la cabine dans Vice Point.
-[CRED245]
-DUNCAN SHIELDS
+[MOB_96A]
+Rends-toi à la cabine du terminal de l'aéroport.
-[CRED246]
-BARANE CHAN
+[MOB_95A]
+Rends-toi à la cabine dans Little Havana.
-[CRED247]
-DEREK PAYNE
+[BNK1_1]
+Je peux vous aider, monsieur?
-[CRED248]
-KEVIN WONG
+[BNK1_2]
+Il y a un imposteur!
-[CRED249]
-ROSS ELLIOTT
+[BNK1_3]
+Il a pêté les plombs!
-[CRED250]
-ROSS BEAZLEY
+[BNK1_4]
+Bon sang, t'es qui, toi?
-[CRED251]
-ALEX BAZLINTON
+[BNK1_5]
+Où es ton badge?
-[CRED252]
-DAVE WATSON
+[BNK1_6]
+Les voilà! Descendez-les!
-[CRED253]
-MALCOLM SMITH
+[MOB_24A]
+Bonjour, c'est M. Vercetti?
-[CRED255]
-ANDREW SEMPLE
+[MOB_24B]
+Oui.
-[CRED256]
-ARTIST
+[MOB_24C]
+ici Cortez. Vous étiez à ma fête.
-[CRED257]
-STUART PETRI
+[MOB_24D]
+Oui, je me souviens.
-[CRED258]
-JERONIMO BARRERA
+[MOB_24E]
+M. Vercetti, c'est un regrettable incident, ce qui s'est produit avec votre affaire.
-[CRED259]
-CARLY SLATER
+[MOB_24F]
+Je sais.
-[CRED260]
-GREG LAU
+[MOB_24G]
+Je veux que vous sachiez que mes hommes et moi, faisons le maximum pour tirer ça au clair.
-[CRED261]
-STEVE KNEZEVICH
+[MOB_24H]
+Si vous souhaitez me parler en privé, vous me trouverez sur le bateau. Au revoir, senor.
-[CRED262]
-DEVIN WINTERBOTTOM
+[BNK2_2]
+VISEZ 3-2-1 FEU!
-[CRED263]
-JAMEEL VEGA
+[BNK2_3]
+ZONE DEGAGEE!
-[CRED264]
-LEE CUMMINGS
+[BNK2_6]
+Ce mec est cinglé!
-[CRED265]
-DEVIN BENNET
+[ANGEL]
+Angel
-[CRED266]
-ELIZABETH SATTERWHITE
+[CUBJET]
+Jetmax cubain
-[CRED267]
-AARON RIGBY
+[SANDKIN]
+Sandking
-[CRED268]
-STEVE K.
+[POLMAV]
+Maverick Police
-[CRED269]
-GREG LAU
+[BOXVILL]
+Boxville
-[J_EP]
-PRODUCTEUR EXECUTIF
+[BENSON]
+Benson
-[N_EP]
-SAM HOUSER
+[HOTRINA]
+Hotring Racer
-[J_PROD]
-PRODUCTEUR
+[HOTRINB]
+Hotring Racer
-[N_PROD]
-LESLIE BENZIES
+[BLOODRA]
+Bloodring Banger
-[J_AD]
-DIRECTEUR ARTISTIQUE
+[BLOODRB]
+Bloodring Banger
-[N_AD]
-AARON GARBUT
+[MAFIACR]
+Mafia Cruiser
-[J_TD]
-DIRECTEURS TECHNIQUES
+[COP_M2]
+'VICE SQUAD'
-[N_TD1]
-OBBE VERMEIJ
+[COP_M3]
+'BROWN THUNDER'
-[N_TD2]
-ADAM FOWLER
+[BJM2_20]
+~g~Quand tu n'as plus de ~w~temps ~g~ou de ~w~munitions ~g~, la manche est terminée!
-[J_COD]
-ENCODEURS
+[BNK3_2]
+Pas question que je conduise pour toi! J'en parlerai pendant la réunion de groupe!
-[N_COD1]
-ALEXANDER ROGER
+[FEM_SL1]
+Pas de sauvegarde 1
-[N_COD2]
-GRAEME WILLIAMSON
+[FEM_SL2]
+Pas de sauvegarde 2
-[N_COD3]
-MARK HANLON
+[FEM_SL3]
+Pas de sauvegarde 3
-[N_COD4]
-ALAN CAMPBELL
+[FEM_SL4]
+Pas de sauvegarde 4
-[N_COD5]
-RAYMOND USHER
+[FEM_SL5]
+Pas de sauvegarde 5
-[N_COD6]
-ANDRZEJ MADAJCZYK
+[FEM_SL6]
+Pas de sauvegarde 6
-[J_ART]
-INFOGRAPHISTES
+[FEM_SL7]
+Pas de sauvegarde 7
-[N_ART1]
-ADAM COCHRANE
+[FEM_SL8]
+Pas de sauvegarde 8
-[N_ART2]
-ALISDAIR WOOD
+[FEA_CHA]
+Passage en mode STEREO. Patiente un instant...
-[N_ART3]
-GARY MCADAM
+[FEA_CHD]
+Attention! Tu es en train de passer du mode STEREO au mode DTS. Patiente un instant...
-[N_ART4]
-ANDREW SOOSAY
+[FEI_SEL]
+Sélectionner
-[N_ART5]
-KEIRAN BAILLIE
+[FEI_BAC]
+Retour
-[J_AUTO]
-CONCEPTION AUTOMOBILE
+[FEI_RES]
+Reprendre
-[N_AUTO]
-PAUL KUROWSKI
+[FEI_NAV]
+Explorer
-[J_CHAR]
-PERSONNAGES
+[FEI_BTX]
+Touche / -
-[N_CHAR]
-IAN MCQUE
+[FEI_BTT]
+Touche " -
-[J_ANIM]
-ANIMATION ET REALISATION
+[FEI_STA]
+Touche START -
-[N_ANIM1]
-ALEX HORTON
+[FEI_BTD]
+; = > < -
-[N_ANIM2]
-NAVID KHONSARI
+[FEI_STO]
+Arrêter
-[N_ANIM3]
-LEE MONTGOMERY
+[MOB_68A]
+Tommy, mon fiston, j'ai une surprise pour toi!
-[J_SND]
-CONCEPTION SON
+[MOB_68B]
+Je suis au studio d'enregistrement avec quelques artistes réputés.
-[N_SND1]
-ALLAN WALKER
+[MOB_68C]
+Pourquoi tu ne viendrais pas faire un tour?
-[J_SCR]
-MUSIQUE
+[MOB_68D]
+C'est une bonne idée, non? Allez, à plus tard. C'est plutôt normal, non? Allez, à plus tard.
-[N_SCR1]
-CRAIG CONNER
+[OUTFT1]
+Streetwear
-[N_SCR2]
-STUART ROSS
+[OUTFT2]
+Soirée
-[J_DSGN]
-CONCEPTION
+[OUTFT3]
+Bleu de travail
-[N_DSGN1]
-CRAIG FILSHIE
+[OUTFT4]
+Country club
-[N_DSGN2]
-WILLIAM MILLS
+[OUTFT5]
+Cubano
-[N_DSGN3]
-CHRIS ROTHWELL
+[OUTFT6]
+Flic
-[N_DSGN4]
-JAMES WORRALL
+[OUTFT7]
+Braqueur
-[J_WRT]
-SCENARIO
+[OUTFT8]
+Décontracté
-[N_WRT1]
-JAMES WORRALL
+[OUTFT9]
+M. Vercetti
-[N_WRT2]
-DAN HOUSER
+[OUTFT10]
+Survêtement
-[N_WRT3]
-PAUL KUROWSKI
+[OUTFT13]
+MC Tommy
-[J_IT]
-ASSISTANCE TECHNIQUE
+[HOTR_07]
+Nouveau record : ~1~:0~1~
-[N_IT1]
-LORRAINE ROY
+[HOTR_08]
+Temps : ~1~:~1~
-[N_IT2]
-CHRISTINE CHALMERS
+[GEN3_45]
+Ils seront là d'une minute à l'autre. On ferait mieux de se trouver une bonne planque...
-[J_IQA]
-RESPONSABLE DES TESTS
+[CAR_AS1]
+CONCESSION AUTOMOBILE ACQUISE
-[N_IQA1]
-CRAIG ARBUTHNOTT
+[CAR_AS2]
+~g~Sunshine Autos génère dorénavant un revenu de $~1~ maximum. Pense à récupérer le fric régulièrement.
-[LEAD_T]
-TESTEURS PRINCIPAUX
+[BUYSAVE]
+~g~Puisque tu n'es pas en mission, tu peux sauvegarder ta partie gratuitement.
-[N_IQA2]
-JOHN HAIME
+[BUYGARG]
+~g~Tu peux aussi garer des véhicules dans ce garage.
-[N_IQA3]
-NEIL CORBETT
+[STRPBUY]
+Club Pole Position acquis : $~1~
-[N_IQA4]
-ANDY DUTHIE
+[STRP_R3]
+Pour acheter le club Pole Position pour $~1~, appuie sur la touche R3.
-[TEST]
-TESTEURS
+[NBMN_R3]
+Pour acheter Elswanko Casa pour $~1~, appuie sur la touche R3.
-[N_IQA5]
-GRAEME JENNINGS
+[GA_4]
+Les bombes pour voiture coûtent $1000 pièce.
-[N_IQA6]
-DAVID MURDOCH
+[GA_5]
+Ta caisse est déjà équipée d'une bombe.
-[N_IQA7]
-DAVID BEDDOES
+[GA_6] { reVC update }
+Gare-toi, amorce-la en appuyant sur la ~h~~k~~VEHICLE_FIREWEAPON~~w~ et BARRE-TOI vite!
-[N_IQA8]
-EDWIN SMITH
+[GA_7] { reVC update }
+Amorce la bombe en appuyant sur la ~h~~k~~VEHICLE_FIREWEAPON~~w~. Elle explosera au démarrage.
-[N_IQA9]
-MARK FLETT
+[GA_6B] { reVC update }
+Gare-toi, amorce-la en appuyant sur la ~h~~k~~VEHICLE_FIREWEAPON~~w~ et BARRE-TOI vite!
-[N_IQ10]
-MICHAEL SUTHERLAND
+[GA_7B] { reVC update }
+Amorce la bombe en appuyant sur la ~h~~k~~VEHICLE_FIREWEAPON~~w~. Elle explosera au démarrage.
-[J_EQA]
-ROCKSTAR NEW YORK
+[MOB_70A]
+Tommy, c'est moi, le colonel Cortez. Ecoutez senor, je parie qu'avec vous, tout est possible.
-[N_EQA1]
-JEFF ROSA
+[MOB_70B]
+Je serai sur le bateau.
-[LEAD_T2]
-TESTEUR PRINCIPAL
+[PICK1]
+Gilet pare-balles livré dans l'hôtel Ocean View!
-[N_EQA2]
-ADAM DAVIDSON
+[PICK2]
+.357 livré à la planque!
-[N_EQA3]
-JOE HOWELL
+[PICK3]
+Tronçonneuse livrée à la planque!
-[N_EQA4]
-JOE GREEN
+[PICK4]
+Lance-flammes livré à la planque!
-[N_EQA5]
-RICH HUIE
+[PICK5]
+.308 Lunette livré à la planque!
-[N_EQA6]
-JEREMY POPE
+[PICK6]
+Mitrailleuse livrée à la planque!
-[N_EQA7]
-KAHLEEM POOLE
+[PICK7]
+Lance-roquettes livré à la planque!
-[N_EQA8]
-HAKLIN NG
+[PICK8]
+Sea Sparrow désormais disponible dans la résidence!
-[N_EQA9]
-MIKE HONG
+[PICK9]
+Char désormais disponible dans la caserne de l'armée!
-[N_EQA10]
-BRIAN PLANAR
+[PICK10]
+Hunter désormais disponible dans la caserne de l'armée!
-[N_EQA11]
-JAMEEL VEGA
+[HELP41]
+tu peux aussi les défoncer avec un véhicule
-[CINCAM]
-Caméra Cinématique
+[ICC1_6]
+~g~Utilise le Mr. Whopee pour distribuer des produits Cherry Poppers dans Vice City.
-[KM1_13]
-Amène cette bagnole au garage!
+[ICC1_12]
+PROPRIETE ACQUISE!
-[KM3_14]
-~r~Tu t'es fait repérer, le marché est annulé!
+[CLOTH1]
+Tenue de soirée livrée chez Rafael sur Ocean Beach.
-[EBAL_H]
-Attends-moi ici pendant que je vais aller parler à luigi.
+[CLOTH2]
+Tenue streetwear livrée aux planques.
-[EBAL_M]
-Rappelle-toi que personne n'embrouille mes filles!
+[CLOTH3]
+Bleu de travail livré chez Tooled Up dans le centre commercial de North Point.
-[LM2_F]
-Tu lui prends sa caisse et tu la repeins.
+[CLOTH4]
+Tenue pour le Country Club livrée au Leaf Links Golf Club.
-[LM2_D]
-Ben voilà, prends-le.
+[CLOTH5]
+Tenue Cubano livrée chez Little Havana Streetwear dans Little Havana.
-[LM1_9]
-Salut, je m'appelle Misty.
+[CLOTH6]
+Uniforme de flic livré au poste de police de Washington Beach.
-[LM4_A]
-Y'a des connards de Diablos qui font tapiner leurs sales putes sur mon territoire.
+[CLOTH7]
+Tenue décontractée livrée chez Gash dans le centre commercial de North Point.
-[FM2_B]
-On a une balance!
+[CLOTH8]
+Tenue de M. Vercetti livrée chez Collar & Cuffs sur Ocean Beach.
-[FM2_C]
-Il fait pas le maquereau,ni le dealer, donc il doit parler.
+[CLOTH9]
+Survêtement livré chez Jocksport dans le centre.
-[FM3_CC]
-~w~Reviens quand t'auras le pognon, frangin.
+[CLOTH10]
+Tenue de braqueur livrée au Malibu de Vice Point.
-[FEDS_AM]
-<>-CHANGER MENU
+[RBM1_9]
+~g~Va chez le dealer et rapporte du Love Juice pour les Love Fist!
-[LOVE5_5]
-~r~T'as pas su protéger le camion!
+[MOB_62A]
+Tommy, c'est Ricardo Diaz, je voulais te remercier de m'avoir sauvé.
-[RM6_6]
-~r~Ray est mort!
+[MOB_62B]
+J'ai demandé à ce con de Cortez. Il a dit que tu feras l'affaire, mon ami. Viens me voir à l'occasion.
-[RM6_7]
-. ~r~Ray a raté son vol.
+[MOB_62C]
+C'est d'un mec comme toi dont j'ai besoin. J'ai plus que des têtes de bites,
-[RM6_8]
-~g~Tu as laissé tomber Ray, retourne le chercher.
+[MOB_62D]
+des têtes de bite partout! Tu vas gagner plein de pognon.
-[FM1_10]
-~g~Tu as laissé tomber Maria, retourne la chercher.
+[GOAWAY2]
+~g~Reviens quand tu auras terminé les missions Bikers.
-[LOVE4_9]
-~r~L'avion a été détruit!
+[COL2_9]
+Imbécile de Ricain! Ils vous ont suivi jusqu'ici!
-[LOV4_10]
-~r~La seule piste pour retrouver le paquet est partie en fumée!
+[LOADCOL]
+Chargement...
-[KM2_D]
-Cela va sans dire, on va lui en faire cadeau, pour éponger la dette que j'ai envers lui.
+[STFT_17]
+Meilleur temps sur Terrain de jeu PCJ
-[KM4_B]
-Les mecs qui ont la chance de bénéficier de notre protection, font leurs comptes aujourd'hui.
+[STFT_18]
+Meilleur temps sur 'Sélection par la boue'
-[KM2_E]
-Tu dois trouver les voitures qui sont sur cette liste et les livrer au garage derrière le parking de Newport.
+[STFT_19]
+Meilleur temps sur Piste d'essai
-[FM3_8I]
-~w~Trouve une bonne place et je rentrerai quand tu tireras le premier coup.
+[NEW_REC]
+Nouveau record! ~1~ minutes et ~1~ secondes.
-[LOVE1_B]
-L'expérience m'a appris que quelqu'un comme toi peut être très loyal si on le paye bien,
+[BMX_HOW]
+~g~Fais deux tours de circuit, ~y~en passant par ~g~les ~y~POINTS DE PASSAGE~g~!
-[LOVE1_H]
-mais ca fait des jaloux.
+[BMXREW1]
+~g~Chaque fois que tu inscris un nouveau record pour les deux tours,
-[LOVE1_C]
-Un vieux bridé que je connais, un homme de confiance,
+[BMXREW2]
+~g~une meilleure ~y~RECOMPENSE ~g~t'est offerte!
-[LOVE1_I]
-est retenu en otage par des Sud-Américains à Aspatria.
+[BMXRAIN]
+~g~On dirait qu'il pleut...
-[MEA4_D]
-J'ai accepté de le voir...
+[ITBEG]
+AU DEBUT...
-[MEA4_B4]
-C'est Marty qui t'envoie, hein ? D'accord, je vais lui apprendre, moi, le sens des affaires.
+[NBMNBUY]
+El Swanko Casa acheté : $ ~1~
-[MEA4_B5]
-Carl, salut! Euh... j'ai besoin de plus de temps pour ton pognon.
+[LNKVBUY]
+Appartement de Links View acheté : $ ~1~
-[MEA1_B4]
-C'est M. Chonks qui t'envoie, n'est-ce pas ? Allons lui rendre visite.
+[HYCOBUY]
+Hyman Condo acheté : $ ~1~
-[HM5_6]
-Allons fracasser des crânes...
+[BUYGARS]
+~g~Tu peux également stocker des véhicules dans ces garages.
-[LOVE1_5]
-~g~Arrête de tourner en rond, trouve une bagnole des Colombiens et sauve l'associé de Love.
+[OCHEBUY]
+Appartement d'Ocean Heights acheté : $ ~1~
-[AS1_D]
-~w~T'as qu'à faire l'appât et attirer les escadrons de la mort dans la Crique de Pike.
+[WASHBUY]
+1102 Washington Street acheté : $ ~1~
-[AS1_E]
-~w~Mes hommes les attendront là-bas.
+[VCPTBUY]
+3321 Vice Point acheté : $ ~1~
-[AS2_C]
-~w~Le Cartel a une couverture : l'usine de café Kappa.
+[SKUMBUY]
+Skumole Terrace achetée : $~1~
-[AS2_E]
-~w~On a pas d'autre choix que de neutraliser ces charettes à drogue.
+[HELP6_C]
+Appuie sur la ~h~~k~~VEHICLE_HANDBRAKE~~w~ pour actionner le frein à main.
-[AS2_F]
-~w~Fais-en des allumettes!!
+[HELP2_A]
+Appuie sur la ~h~~k~~PED_SPRINT~~w~ lorsque tu cours pour ~h~sprinter.
-[AS2_A1]
-~w~Miguel a sûrement un peu de cette fameuse énergie latine.
+[HELP4_A]
+Appuie sur la ~h~~k~~VEHICLE_ACCELERATE~~w~ pour accélérer.
-[AS2_A2]
-~w~Je suis crevé.
+[HELP5_A]
+Appuie sur la ~h~~k~~VEHICLE_BRAKE~~w~ pour freiner ou faire marche arrière si le véhicule est à l'arrêt.
-[SIREN_3]
-Pour activer la sirène, appuie sur la ~h~touche ~k~~VEHICLE_HORN~~w~.
+[HELP8_A]
+Appuie sur la ~h~~k~~PED_SNIPER_ZOOM_IN~~w~ pour faire un zoom avant avec le fusil et sur la ~x~touche /~w~ pour faire un zoom arrière.
-[SIREN_4]
-Pour activer la sirène, appuie sur la ~h~touche ~k~~VEHICLE_HORN~~w~.
+[PBOAT_1] { reVC update }
+Appuie sur la~h~ ~k~~VEHICLE_FIREWEAPON~~w~ pour tirer avec les canons du bateau.
-[AS3_C]
-~w~Oulala! C'est quoi ce truc jaune ?
+[SEG3_4] { reVC update }
+~g~Tu peux ramasser des bombes en pilotant ton avion radiocommandé à côté. Appuie sur la ~h~~k~~VEHICLE_FIREWEAPON~ ~g~touche.
-[AS3_C1]
-~w~Salut ma poule.
+[RCR1_3] { reVC update }
+~g~Si tu veux quitter cette mission, appuie sur la ~h~~k~~VEHICLE_FIREWEAPON~~g~ pour faire exploser ta voiture radiocommandée.
-[AS3_F]
-~w~Elle se classe tout de suite dans les meilleures, cette nana.
+[HELP32] { reVC update }
+Appuie ensuite sur la ~h~~k~~VEHICLE_FIREWEAPON~~w~ pour tirer.
-[AS3_F1]
-~w~Elle s'est arrangée pour dérober ce joli petit bijou à notre invité.
+[HELP33] { reVC update }
+Appuie ensuite sur la ~h~~k~~VEHICLE_FIREWEAPON~~w~ pour tirer.
-[AS3_G]
-~w~Y'a un avion qui arrive à l'aéroport international Francis dans 2 heures.
+[TTUTOR]
+Appuie sur la ~h~~k~~TOGGLE_SUBMISSIONS~~w~ pour activer ou désactiver les missions Taxi.
-[AS3_G1]
-~w~Il est rempli de poison de Catalina.
+[TTUTOR2]
+Appuie sur la ~h~~k~~TOGGLE_SUBMISSIONS~~w~ pour activer ou désactiver les missions Taxi.
-[AS3_H]
-~w~Tu peux éviter la sécurité de l'aéroport en prenant un bateau jusqu'aux bouées lumineuses d'approche.
+[FTUTOR]
+Appuie sur la ~h~~k~~TOGGLE_SUBMISSIONS~~w~ pour activer ou désactiver les missions Camion de pompiers.
-[AS3_H1]
-~w~Et dès que l'avion descends, tu l'explose!
+[FTUTOR2]
+Appuie sur la ~h~~k~~TOGGLE_SUBMISSIONS~~w~ pour activer ou désactiver les missions Camion de pompiers.
-[AS3_I]
-~w~Récupère la marchandise au milieu des débris.
+[CTUTOR]
+Appuie sur la ~h~~k~~TOGGLE_SUBMISSIONS~~w~ pour activer ou désactiver les missions Auto-défense.
-[AS3_J]
-~w~Maintenant, fais attention ma poule!
+[CTUTOR2]
+Appuie sur la ~h~~k~~TOGGLE_SUBMISSIONS~~w~ pour activer ou désactiver les missions Auto-défense.
-[AS3_K]
-~w~Essaie avec l'huile pimentée...
+[HELP8_B]
+Appuie sur la~h~ ~k~~PED_SNIPER_ZOOM_IN~ ~w~pour faire un ~h~zoom avant~w~ avec le fusil et sur la ~h~~k~~PED_SNIPER_ZOOM_OUT~~w~ pour faire un ~h~zoom arrière~w~.
-[RM2_F1]
-Ces Colombiens seront là d'une minute à l'autre!
+[ATUTOR3]
+Appuie sur la ~h~~k~~TOGGLE_SUBMISSIONS~~w~ pour activer ou désactiver les missions Ambulance.
-[RM2_K]
-Merde ils sont là!! Feu à volonté!!
+[GUN_H1]
+~w~Appuie sur la~h~ ~k~~PED_SPRINT~~w~ pour acheter. ~w~Appuie sur la~h~ ~k~~VEHICLE_ENTER_EXIT~~w~ pour quitter.
-[LOVE2_7]
-~g~Maintenant, largue la bagnole!
+[PU_CF3] { reVC update }
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~~w~ pour remplacer l'arme actuelle dans cet emplacement.
-[LOVE2_8]
-~g~Dégage de Newport!
+[PU_CF4] { reVC update }
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~~w~ pour remplacer l'arme actuelle dans cet emplacement.
-[AM1_F]
-Salvatore Leone va partir de chez Luigi vers ~1~:~1~.
+[HELP9_B]
+Appuie sur la~h~ ~k~~PED_FIREWEAPON~ ~w~pour ~h~tirer~w~ avec le fusil à lunette.
-[LOVE5_C]
-Je veux que tu le suives et que tu fasses en sorte que lui et mon paquet arrivent à la Crique de Pike sains et saufs.
+[HELP37]
+Si tu ne veux pas monter dans un véhicule quand tu braques le conducteur, appuie sur la ~h~~k~~PED_SPRINT~.
-[FESZ_SR]
-Echec de la sauvegarde! Vérifie la memory card (PS2) dans la fente pour MEMORY CARD 1 et réessaie.
+[HELP6_A]
+Appuie sur la ~h~~k~~VEHICLE_HANDBRAKE~ ~w~ pour actionner le frein à main.
-[FESZ_FO]
-Veux-tu formater la memory card (PS2) dans la fente pour MEMORY CARD 1?
+[HELP6_D]
+Appuie sur la ~h~~k~~VEHICLE_HANDBRAKE~ ~w~ pour actionner le frein à main.
-[FELZ_FO]
-La memory card (PS2) dans la fente pour MEMORY CARD 1 n'est pas formatée.
+[HELP26]
+Appuie sur la ~h~~k~~VEHICLE_ENTER_EXIT~ ~w~ pour monter ou sortir d'un véhicule.
-[FES_NOC]
-Aucune memory card (PS2) dans la fente pour MEMORY CARD 1.
+[HELP27]
+Appuie sur ~h~~k~~VEHICLE_TURRETUP~~w~ ou ~h~~k~~VEHICLE_TURRETDOWN~~w~ pour déplacer ton poids sur une moto.
-[FES_LOE]
-Echec du chargement! Vérifie la memory card (PS2) dans la fente pour MEMORY CARD 1 et réessaie.
+[HELP28]
+Appuie sur ~h~~k~~VEHICLE_TURRETUP~~w~ ou ~h~~k~~VEHICLE_TURRETDOWN~~w~ pour déplacer ton poids sur une moto.
-[FES_DEE]
-Echec de la suppression! Vérifie la memory card (PS2) dans la fente pour MEMORY CARD 1 et réessaie.
+[HELP35]
+Appuie sur ~h~~k~~GO_LEFT~~w~ ou ~h~~k~~GO_RIGHT~~w~ pour diriger le véhicule.
-[FORSUC]
-Formatage réussi de la memory card (PS2) dans la fente pour MEMORY CARD 1.
+[HELP36]
+Appuie sur ~h~~k~~GO_LEFT~~w~ ou ~h~~k~~GO_RIGHT~~w~ pour diriger le véhicule.
-[ERFOUN]
-Echec du formatage de la memory card (PS2) dans la fente pour MEMORY CARD 1.
+[HELP42]
+Suis le ~q~point rose~w~ pour trouver l'hôtel.
-[ERMCNP]
-Aucune memory card (PS2) dans la fente pour MEMORY CARD 1.
+[HELP19]
+Marche sur le ~q~marqueur rose~w~ pour continuer.
-[SVMEM1]
-Sauvegarder sur la memory card (PS2) dans la fente pour MEMORY CARD 1.
+[HELP1]
+Arrête-toi au centre du ~q~marqueur rose.
-[FORSLO]
-Formater la memory card (PS2) dans la fente pour MEMORY CARD 1.
+[HELP12]
+Marche au centre du ~q~marqueur rose~w~ pour lancer une mission.
-[SLONFM]
-Erreur de formatage de la Memort Card (PS2) dans la fente pour MEMORY CARD 1.
+[SEG3_6]
+~g~Pour toucher ta cible, tu dois larguer la bombe sur la zone indiquée par le ~q~marqueur rose~w~. Tu peux larguer les bombes dans n'importe quel ordre.
-[SLONDR]
-Espace insuffisant pour sauvegarder. Insère une memory card (PS2) dotée d'au moins 500 Ko d'espace disponible, dans la fente pour MEMORY CARD 1.
+[S_PROMP]
+Lorsque tu n'es pas en mission, tu peux sauvegarder la partie en ramassant la ~h~cassette.
-[SLNSP]
-Espace insuffisant pour sauvegarder. Insère une memory card (PS2) dotée d'au moins 200 Ko d'espace disponible, dans la fente pour MEMORY CARD 1.
+[HELP16]
+Franchis la porte d'entrée de l'hôtel ~h~Ocean View~w~ pour y pénétrer.
-[FEFD_WR]
-Formatage de la memory card (PS2) dans la fente pour MEMORY CARD 1. Ne pas retirer la memory card (PS2), ni réinitialiser ou éteindre la console.
+[HELP43]
+~g~Rends-toi à l'hôtel ~h~Ocean View~g~ sur Ocean Drive.
-[FES_ISF]
-ABSENT
+[HELI_F1]
+~r~Mission Point de passage hélico annulée!
-[FES_SAG]
-EXISTANT
+[AMMUHLP]
+Si tu as besoin d'armes, va chez ~h~Ammu-Nation~w~. Suis le ~h~point pistolet~w~ sur le radar.
-[SLONNO]
-Aucune memory card (PS2) dans la fente pour MEMORY CARD 1.
+[HELI_1]
+Point de passage hélico du Centre
-[SLONNF]
-La memory card (PS2) dans la fente pour MEMORY CARD 1 pas formatée.
+[HELI_2]
+Point de passage hélico d'Ocean Beach
-[FESZ_FM]
-La memory card (PS2) dans la fente pour MEMORY CARD 1 n'est pas formatée. Veux-tu la formater?
+[HELI_3]
+Point de passage hélico de Vice Point
-[FESZ_FF]
-Echec du formatage! Vérifie la memory card (PS2) dans la fente pour MEMORY CARD 1 et réessaie.
+[HELI_4]
+Point de passage hélico de Little Haiti
-[MCDNSP]
-Espace insuffisant sur la memory card (PS2) dans la fente pour MEMORY CARD 1. 500 Ko minimum sont requis pour sauvegarder. Veux-tu commencer? (OUI ou NON)
+[FST_MFR]
+Station de radio préférée
-[MCGNSP]
-Espace insuffisant sur la memory card (PS2) dans la fente pour MEMORY CARD 1. 200 Ko minimum sont requis pour sauvegarder. Veux-tu commencer ? (OUI ou NON)
+[FST_LFR]
+Station de radio la moins écoutée
-[FESZ_WR]
-Sauvegarde en cours. Ne pas retirer la memory card (PS2) de la fente pour MEMORY CARD 1, ni réinitialiser ou éteindre la console.
+[FEI_HOL]
+Maintenir
-[FESZ_OW]
-Ecrasement en cours. Ne pas retirer la memory card (PS2) de la fente pour MEMORY CARD 1, ni réinitialiser ou éteindre la console.
+[FEI_ZOO]
+Zoom
-[FELD_WR]
-Chargement en cours. Ne pas retirer la memory card (PS2) de la fente pour MEMORY CARD 1, ni réinitialiser ou éteindre la console.
+[FEI_BTR]
+> < -
-[FEDL_WR]
-Effacement en cours. Ne pas retirer la memory card (PS2) de la fente pour MEMORY CARD 1, ni réinitialiser ou éteindre la console.
+[FEI_NA]
+Aucun
-[LM2_C]
-Luigi m'a dit de te donner ça, alors...
+[MESA]
+Grande table
-[LM3_G]
-Joey n'est pas du genre à être patient, rappelle-toi, c'est ton ticket d'entrée...
+[STRP_NO]
+Tu ne peux pas acheter la boîte de striptease maintenant. Reviens plus tard.
-[LM5_E]
-Ramènes-en autant que tu peux avant que ces poulets aient cramé tout leur blé.
+[CHSE]
+POURSUITE
-[JM5_C]
-Y'a une bagnole avec un macchabée devant le café à coté de Point Callahan.
+[NBMN_L]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter El Swanko Casa pour $~1~.
-[RM2_B]
-On a fait le Nicaragua ensemble, à l'époque où ce pays savait ce qu'il faisait.
+[NBMN_T]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter El Swanko Casa pour $~1~.
-[RM2_C]
-Un enfoiré du Cartel l'a bousculé hier et lui a dit qu'ils reviendraient aujourd'hui pour de la marchandise.
+[NBMN_C]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter El Swanko Casa pour $~1~.
-[RM2_D1]
-J'y serais bien allé moi-même mais ma vieille sciatique s'est réveillée - hhurrh hhurrh - alors, bonne chance.
+[LNKV_L]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter l'appartement de Links View pour $~1~.
-[CATINF1]
-~g~Chope Catalina!
+[LNKV_T]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter l'appartement de Links View pour $~1~.
-[CATINF2]
-~g~Suis l'hélico pour trouver Catalina.
+[LNKV_C]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter l'appartement de Links View pour $~1~.
-[BOATIN1]
-Saute dans un bateau et appuie sur la ~h~touche ~k~~VEHICLE_ENTER_EXIT~~w~ pour entrer dedans.
+[HYCO_L]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter Hyman Condo pour $~1~.
-[BOATIN2]
-Tu peux appuyer sur la ~h~touche ~k~~VEHICLE_ENTER_EXIT~ ~w~si tu es près d'un bateau pour te glisser à l'intérieur.
+[HYCO_T]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter Hyman Condo pour $~1~.
-[BOATIN3]
-Saute dans un bateau et appuie sur la ~h~touche ~k~~VEHICLE_ENTER_EXIT~ ~w~pour entrer dedans.
+[HYCO_C]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter Hyman Condo pour $~1~.
-[BOATIN4]
-Tu peux appuyer sur la ~h~touche ~k~~VEHICLE_ENTER_EXIT~ ~w~si tu es près d'un bateau pour te glisser à l'intérieur.
+[OCHE_L]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter l'appartement d'Ocean Heights pour $~1~.
-[JM6]
-'L'EVASION'
+[OCHE_T]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter l'appartement d'Ocean Heights pour $~1~.
-[FM1]
-'LE CHAPERON'
+[OCHE_C]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter l'appartement d'Ocean Heights pour $~1~.
-[JM1]
-'LE DERNIER REPAS DE MIKE 'BABINES'
+[WASH_L]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter le 1102 Washington Street pour $~1~.
-[FM21]
-'LA BOMBE : ACTE 1'
+[WASH_T]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter le 1102 Washington Street pour $~1~.
-[FM3]
-'LA BOMBE : ACTE 2'
+[WASH_C]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter le 1102 Washington Street pour $~1~.
-[AM1]
-'SAYONARA SALVATORE'
+[VCPT_L]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter le 3321 Vice Point pour $~1~.
-[AM2]
-'SOUS SURVEILLANCE'
+[VCPT_T]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter le 3321 Vice Point pour $~1~.
-[KM2]
-'GRAND THEFT AUTO'
+[VCPT_C]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter le 3321 Vice Point pour $~1~.
-[AS3]
-'S.A.M.'
+[SKUM_L]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~~w~ pour acheter la Skumole Terrace pour $~1~.
-[RM2]
-'PENURIE D'ARMES'
+[SKUM_T]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~~w~ pour acheter la Skumole Terrace pour $~1~.
-[LOVE6]
-'L'APPAT'
+[SKUM_C]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~~w~ pour acheter la Skumole Terrace pour $~1~.
-[LOVE1]
-'LIBERATEUR'
+[PRNT_L]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter l'imprimerie pour $~1~.
-[RC1]
-'DESTRUCTION DE DIABLO'
+[PRNT_T]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter l'imprimerie pour $~1~.
-[RC2]
-'MASSACRE DE LA MAFIA'
+[PRNT_C]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter l'imprimerie pour $~1~.
-[RC3]
-'CALAMITÉ AU CASINO'
+[CAR_L]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter la concession automobile pour $~1~.
-[RC4]
-'RODEO DE RUMPO'
+[CAR_T]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter la concession automobile pour $~1~.
-[RM2_E1]
-Je peux pas croire que ce trouillard m'ait encore laissé sans protection!
+[CAR_C]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter la concession automobile pour $~1~.
-[GREN_1]
-Plus tu maintiendras la ~h~touche ~k~~PED_FIREWEAPON~~w~ enfoncée, plus tu lanceras loin la grenade.
+[PORN_L]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter le studio de cinéma pour $~1~.
-[GREN_2]
-Plus tu maintiendras la ~h~touche ~k~~PED_FIREWEAPON~~w~ enfoncée, plus tu lanceras loin la grenade.
+[PORN_T]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter le studio de cinéma pour $~1~.
-[GREN_3]
-Plus tu maintiendras la ~h~touche ~k~~PED_FIREWEAPON~~w~ enfoncée, plus tu lanceras loin la grenade.
+[PORN_C]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter le studio de cinéma pour $~1~.
-[LOVE4_G]
-Mon bien t'attendra dans le hangar des douanes à l'intérieur du fuselage de l'avion.
+[ICE_L]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter l'usine de crème glacée pour $~1~.
-[KABOOM]
-KABOOOM!
+[ICE_T]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter l'usine de crème glacée pour $~1~.
-[SPLAT]
-DESSOUDE!
+[ICE_C]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter l'usine de crème glacée pour $~1~.
-[PANCAK]
-REFROIDI!
+[TAXI_L]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter la compagnie de taxis pour $~1~.
-[SOAKED]
-FLINGUE!
+[TAXI_T]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter la compagnie de taxis pour $~1~.
-[HEAD]
-Radio tête
+[TAXI_C]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter la compagnie de taxis pour $~1~.
-[DBL_CLF]
-Radio double FM
+[BANK_L]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter le Malibu pour $~1~.
-[FLASHB]
-Nostalgia FM
+[BANK_T]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter le Malibu pour $~1~.
-[RISE]
-Lévitation FM
+[BANK_C]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter le Malibu pour $~1~.
-[LIPS]
-Love 106
+[BOAT_L]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter le chantier naval pour $~1~.
-[CHAT]
-Causette FM
+[BOAT_T]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter le chantier naval pour $~1~.
-[K_JAH]
-K-Jah Radio
+[BOAT_C]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter le chantier naval pour $~1~.
-[GAM_FM]
-Echec FM
+[STRP_L]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter le Pole Position Club pour $~1~.
-[MSX_FM]
-MSX FM
+[STRP_T]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter le Pole Position Club pour $~1~.
-[TUBE1]
-Quand le métro ouvrira, tu pourras prendre une rame pour aller à l'île Staunton .
+[STRP_C]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~ ~w~pour acheter le Pole Position Club pour $~1~.
-[TUBE2]
-Quand Shoreside Vale sera ouvert, tu pourras sortir au Shoreside Terminal pour aller à l'aéroport international Francis.
+[STOCK]
+~r~stock écoulé
-[TUBE_2]
-Pour prendre le métro, appuie sur la ~h~touche 'monter véhicule'~w~.
+[HELP14]
+Pour trouver le cabinet d'avocats, suis le ~h~point L~w~ sur le radar.
-[LEGAL]
-~g~Enraye toute menace criminelle!
+[BOAT_AS]
+~g~Le chantier naval génère dorénavant un revenu de $~1~ maximum. Pense à récupérer le fric régulièrement.
-[GA_2]
-Nouveau moteur et nouvelle peinture. Les flics ne te reconnaîtront jamais!
+[BOAT_A2]
+CHANTIER NAVAL OK
-[LM1_8A]
-Pour te faire du fric en plus, tu pourrais peut-être 'emprunter' un taxi...
+[BOAT_N]
+Checkpoint Charlie
-[TAXIH1]
-Arrête-toi près d'un passage piéton pour prendre des passagers et emmène-les à destination avant la fin du temps imparti.
+[BOAT_P]
+~g~Récupère les paquets avant la fin du temps imparti.
-[LM5_7]
-~g~Y'a moins de quatre filles qui bossent au ~p~Bal~g~, Luigi va pas être content!
+[FEI_R1B]
+Touches R1\R2 -
-[KM2_3]
-~g~Rappelle-toi que les ~r~voitures~g~ doivent être en parfait état pour être acceptées par le ~p~garage~g~.
+[HELP9_A]
+Appuie sur la touche ~h~~k~~PED_FIREWEAPON~ ~w~pour tirer avec le fusil à lunette.
-[KM5_2]
-~g~Un homme du gang de Yardie est hors d'état de nuire.
+[HELP21]
+Appuie sur la touche ~h~~k~~VEHICLE_ENTER_EXIT~ ~w~pour monter dans un véhicule ou en sortir.
-[BETRA_A]
-Désolé, chérie.
+[CREAM]
+Distribution
-[BETRA_B]
-Je suis une fille ambitieuse et toi,
+[UMBERTO]
+Café Robina
-[BETRA_C]
-t'es juste un passe-temps.
+[PU_CF1]
+Appuie sur la touche ~h~~k~~PED_ANSWER_PHONE~ ~w~pour ramasser cette arme. Elle remplacera toute autre arme du même type que tu possèdes.
-[HELP15]
-A pied, appuie sur la ~h~touche ~k~~PED_LOOKBEHIND~~w~ pour ~h~regarder derrière~w~.
+[FED_RDM]
+CARTE ET POINTS
-[FEC_LB3]
-Regarder derrière
+[FEC_ILU]
+Vue inversée à la 1ere personne :
-[FEC_R3]
-(touche R3)
+[NITRO]
+Tous les taxis disposent d'un saut turbo! Appuie simplement sur la touche klaxonner.
-[FES_AFO]
-Cette memory card (PS2) est déjà formatée.
+[RATNG53]
+Faux cul
-[FEA_UP]
-;
+[RATNG54]
+Faiseur d'emmerdes
-[FEA_DO]
-=
+[RATNG55]
+Malhonnête
-[FEA_LE]
-<
+[RATNG56]
+Tricheur
-[FEA_RI]
->
+[RATNG57]
+Mythomane
-[FEDSAS3]
-- CHANGER SELECTION
+[STHC_04]
+Meilleur score au beach ball de Keepie-Uppy
-[FEDSAS4]
-;=<> - CHANGER SELECTION
+[STHC_05]
+Meilleur résultat au Hotring
-[SPRAY_4] { re3 change }
-Utilise la ~h~touche ~k~~VEHICLE_FIREWEAPON~~w~ pour tirer à l'aide du canon à eau.
+[STFT_13]
+Meilleur tps point de passage hélico du centre
-[SPRAY_1] { re3 change }
-Utilise la ~h~touche ~k~~VEHICLE_FIREWEAPON~~w~ pour tirer à l'aide du canon à eau.
+[STFT_14]
+Meilleur tps point de passage hélico d'Ocean Beach
-[AM1_10]
-~g~Salvatore Leone partira de chez Luigi vers 0~1~:~1~.
+[STFT_15]
+Meilleur tps point de passage hélico de Vice Point
-[JAILB_V]
-Liberty City est en état de choc!
+[STFT_16]
+Meilleur tps point de passage hélico de Little Haiti
-[JAILB_A]
-La police et les services d'urgence s'occupent des conséquences
+[STFT_21]
+Meilleur temps au Hotring
-[JAILB_B]
-d'une attaque lancée contre un convoi de la police ce matin.
+[STFT_22]
+Meilleur temps au tour au Hotring
-[JAILB_C]
-On n'a reçu aucune info sur les prisonniers qui étaient transférés ce matin.
+[STFT_20]
+Meilleur temps au 'Cone Crazy'
-[JAILB_D]
-Et aucun groupe, n'a revendiqué cette attaque.
+[HELP44]
+Arrête-toi sur le ~q~marqueur rose.
-[JAILB_E]
-Le convoi a quitté le Q.G. de la police tôt ce matin...
+[HELP45]
+Appuie sur la ~h~~k~~PED_DUCK~~w~ pour t'accroupir. Ceci augmente la précision des flingues que tu portes.
-[JAILB_F]
-pour un transfert vers le pénitencier de Liberty.
+[RCR1_5]
+Course de Bandit RC
-[JAILB_G]
-L'attaque a eu lieu sur le pont de Callahan,
+[RCPL1_7]
+Course de Baron RC
-[JAILB_H]
-laissant peu de témoins et un pont gravement endommagé.
+[RCH1_11]
+Course de Raider RC
-[JAILB_I]
-On suppose que certains prisonniers sont morts dans l'explosion...
+[FEA_CTD]
+Attention! Un équipement matériel compatible DTS est requis pour cette fonction. Continuer?
-[JAILB_J]
-qui a suivi la première attaque.
+[FEM_STE]
+STEREO
-[JAILB_W]
-Le professionnalisme de cette attaque a pris de court la police,
+[FEM_UDY]
+DTS
-[JAILB_K]
-lorsque l'identification des prisonniers évadés a été ralentie...
+[GREET]
+Bien le bonjour de...
-[JAILB_L]
-par la découverte d'un piratage informatique simultané des bases de données du Q.G. de la police.
+[LANCE_1]
+Hé, mec, conduis un peu mieux!
-[JAILB_O]
-Le chantier du tunnel Porter prenant de plus en plus de retard,
+[LANCE_2]
+Hé, fais gaffe à ce que tu fais!
-[JAILB_P]
-cette catastrophe laisse Portland isolé du reste de la ville.
+[LANCE_3]
+Hé, tu vas où, là?
-[JAILB_Q]
-Allez, viens!
+[LANCE_4]
+On fait quoi maintenant?
-[JAILB_R]
-Monsieur tête de noeud
+[LAW4_15]
+Plus de fric!
-[JAILB_S]
-Ca me pose aucun problème de te tuer.
+[MERC_5]
+Belle voiture, M. Vercetti.
-[JAILB_T]
-Tu vas le regretter.
+[MERC_26]
+PLUS VITE, PLUS VITE, PLUS VITE!
-[JAILB_U]
-D'accord, d'accord. Allez, dégage!
+[MERC_27]
+Attention, Tommy, je me suis fait refaire le nez le mois dernier.
-[JAILB_M]
-Le Maire O'Donovan a fait clairement comprendre que la police considérait
+[MERC_28]
+Tommy, conduis prudemment!
-[JAILB_N]
-*
+[MERC_29]
+Tommy, va moins vite!
-[JAILB_X]
-Dans une déclaration faite ce matin,
+[MERC_30]
+Tommy, tu veux bien tuer quelqu'un d'autre que moi?
-[FEDS_SE]
-Touche / - SELECTIONNER
+[MERC_31]
+Tommy, chéri, ne me tue pas!
-[FEDS_SB]
-Touche / - SELECTIONNER Touche " - RETOUR
+[MERC_32]
+Tommy, ça me très plaisir que t'aies volé cette caisse!
-[TM4_A]
-~w~Oh, c'est toi. Toni n'est pas là.
+[MERC_40]
+J'ai vraiment passé un bon moment.
-[TM4_A2]
-~w~Mais il a laissé une de ses lettres d'amour pour toi.
+[MERC_43]
+Adios, mon chou.
-[DIAB2_A]
-J'ai commencé dans les loisirs exotiques avec rien d'autre que le contenu, pas si négligeable que ça, de mon pantalon de cuir!
+[MERC_44]
+Continue la muscu, d'accord?
-[LM5_9]
-FILLES :
+[MERC_45]
+Ciao, mon beau.
-[PERPIC]
-Paquets cachés trouvés
+[COL5_17]
+Oh mon dieu, ils ont un hélicoptère!
-[CO_ONE]
-~1~ paquet caché sur ~1~ trouvé.
+[COL5_18]
+Abattez l'hélico!
-[LOVE3_3]
-~g~L'avion a largué ~1~ paquets sur 6.
+[COL5_19]
+Tommy, débarrasse-nous de cet hélico!
-[FARE11]
-~g~Destination : ~w~'Chantier'~g~ de Fort Staunton.
+[COL5_20]
+Il revient! Détruisez cet hélico!
-[GA_21]
-Impossible de garer plus de véhicules dans ce garage.
+[COL5_21]
+Visez la taille de cet hélico!
-[CHEAT1]
-Codes activés
+[COL5_22]
+Le revoilà!
-[CHEAT2]
-Code d'arme
+[FEA_DSM]
+Attention! Cette sauvegarde est paramétrée pour un son DTS. Du matériel compatible DTS doit être connecté. Choisir entre une sortie audio STEREO ou DTS.
-[CHEAT3]
-Code de santé
+[STFT_23]
+Meilleur temps à Checkpoint Charlie
-[CHEAT4]
-Code d'armure
+[HELP50]
+Appuie sur la touche ~h~~k~~PED_ANSWER_PHONE~~w~ pour placer la caméra derrière toi.
-[CHEAT5]
-Code d'indice de recherche
+[HELP51]
+Appuie sur la touche ~h~~k~~PED_ANSWER_PHONE~~w~ pour placer la caméra derrière toi.
-[CHEAT6]
-Code d'argent
+[HELP52]
+Appuie sur la touche ~h~~k~~PED_ANSWER_PHONE~~w~ pour placer la caméra derrière toi.
-[CHEAT7]
-Code de météo
+[HELP53]
+Appuie sur la touche ~h~~k~~PED_CYCLE_WEAPON_LEFT~~w~ ou sur la touche ~h~~k~~PED_CYCLE_WEAPON_RIGHT~~w~ pour faire défiler tes armes disponibles.
-[AS1_H]
-~r~T'as pas réussi à amener l'escadron de la mort dans le piège des Yakuzas!
+[HELP46]
+Il existe huit différents types d'armes.
-[FEDS_BA]
-Touche " - RETOUR
+[HELP47]
+Tu peux porter une arme de chaque type à la fois, un type de pistolet, un type de fusil à pompe, etc.
-[RAMP_A]
-TOUS LES RODEOS ONT ETE ACCOMPLIS!
+[HELP54]
+~w~Prix : $~1~ ~r~L'achat de cette arme remplacera celle que tu possèdes déjà.
-[USJ_ALL]
-TOUTES LES CASCADES ONT ETE ACCOMPLIES!
+[HELP2A2]
+Appuie sur la touche ~h~~k~~PED_SPRINT~~w~ quand tu cours, pour ~h~sprinter.
-[FARE23]
-~g~Destination : ~w~'Transport-Export'~g~ au Barrage Cochrane.
+[HLPSN_A]
+Grâce au fusil à lunette, tu peux zoomer de loin sur une cible et la viser avec précision.
-[L_TRN_1]
-Tu peux prendre le train-L à Portland. Appuie sur la ~h~touche ~k~~VEHICLE_ENTER_EXIT~~w~ pour ~h~monter~w~ ou ~h~descendre~w~ du train.
+[HLPSN_B]
+Appuie sur la touche~h~ ~k~~PED_LOCK_TARGET~ ~w~et maintiens-la enfoncée pour ~h~viser~w~ avec le fusil à lunette.
-[L_TRN_2]
-Tu peux prendre le train-L à Portland. Appuie sur la ~h~touche ~k~~VEHICLE_ENTER_EXIT~~w~ pour ~h~monter~w~ ou ~h~descendre~w~ du train.
+[HLPSN_C]
+Appuie sur la touche~h~ ~k~~PED_LOCK_TARGET~ ~w~et maintiens-la enfoncée pour ~h~viser~w~ avec le fusil à lunette.
-[S_TRN_1]
-Tu peux prendre le métro à Liberty. Appuie sur la ~h~touche ~k~~VEHICLE_ENTER_EXIT~~w~ pour ~h~monter~w~ ou ~h~descendre~w~ du train.
+[HLPSN_D]
+Appuie sur la touche ~h~~k~~PED_SNIPER_ZOOM_IN~~w~ pour ~h~faire un zoom avant ~w~avec le fusil à lunette et sur la touche~h~ ~k~~PED_SNIPER_ZOOM_OUT~ ~w~pour ~h~faire un zoom arrière~w~.
-[S_TRN_2]
-Tu peux prendre le métro à Liberty. Appuie sur la ~h~touche ~k~~VEHICLE_ENTER_EXIT~~w~ pour ~h~monter~w~ ou ~h~descendre~w~ du train.
+[HLPSN_E]
+Appuie sur la touche ~h~~k~~PED_FIREWEAPON~~w~ ~w~pour ~h~tirer~w~ avec le fusil à lunette.
-[AS1_C]
-~w~Il y a trois escadrons de la mort autour de Liberty et tout ce qu'ils veulent, c'est te buter!
+[HLPSN_F]
+Appuie sur la touche ~h~~k~~PED_FIREWEAPON~~w~ ~w~pour ~h~tirer~w~ avec le fusil à lunette.
-[AS1_G]
-~r~Tous les Yakuzas sont morts!
+[HLPSN_G]
+Appuie sur la touche ~h~~k~~PED_FIREWEAPON~~w~ ~w~pour ~h~tirer~w~ avec le fusil à lunette.
-[JAN]
-Jan
+[PLANE_H]
+Utilise la touche ~h~~k~~VEHICLE_ACCELERATE~~w~ pour accélérer. Gauche et droite pour tourner.
-[FEB]
-Fév
+[PLANE_4] { reVC update }
+{Utilise la touche ~h~~k~~VEHICLE_ACCELERATE~~w~ pour accélérer. Gauche et droite pour tourner.}
+Utilise le joystick analogique droit pour accélérer, appuie vers le bas sur le joystick analogique gauche pour monter et vers le haut pour descendre. Gauche et droite pour tourner.
-[MAR]
-Mar
+[HELP55]
+Appuie sur la touche ~h~~k~~PED_FIREWEAPON~~w~ pour attaquer le chef.
-[APR]
-Avr
+[STPR_8]
+Pole Position Club
-[MAY]
-Mai
+[STPR_9]
+3321 Vice Point
-[JUN]
-Juin
+[STPR_10]
+Appartement de Links View
-[JUL]
-Juil
+[STPR_11]
+El Swanko Casa
-[AUG]
-Août
+[STPR_12]
+1102 Washington Street
-[SEP]
-Sep
+[STPR_13]
+Appartement d'Ocean Heights
-[OCT]
-Oct
+[STPR_14]
+Skumole Shack
-[NOV]
-Nov
+[STPR_15]
+Hyman Condo
-[DEC]
-Déc
+[RCCANX]
+~r~Avion RC annulé.
-[DEFDT]
-Date de sauvegarde invalide
+[CLT_HL2]
+Lorsque tu ramasses des fringues, une ou deux étoiles d'indice de recherche sont enlevées.
-[BUGGY]
-BUGGIES RESTANTS :
+[CRED009]
+CONCEPTION DES MISSIONS
-[BONUS]
-~g~BONUS ~1~$
+[CRED359]
+LEE JOHNSON
-[HORN1]
-Appuie sur la ~h~touche L3 ~w~pour ~h~klaxonner.
+[CRED360]
+HENDRIK LESSER
-[HORN2]
-Appuie sur la ~h~touche L1 ~w~pour ~h~klaxonner.
+[CRED361]
+PASQUALE STACCHIOTTI
-[HORN3]
-Appuie sur la ~h~touche R1 ~w~pour ~h~klaxonner.
+[CRED362]
+ENRIQUE FERNANDEZ
-[LM3_1A]
-Appuie sur la ~h~touche ~k~~VEHICLE_HORN~ ~w~pour ~h~klaxonner~w~ et prévenir Misty de ton arrivée.
+[CRED363]
+PAUL BYERS
-[LM3_1B]
-Appuie sur la ~h~touche ~k~~VEHICLE_HORN~ ~w~pour ~h~klaxonner~w~ et prévenir Misty de ton arrivée.
+[CRED364]
+MIKE EMENY
-[LM3_1C]
-Appuie sur la ~h~touche ~k~~VEHICLE_HORN~ ~w~pour ~h~klaxonner~w~ et prévenir Misty de ton arrivée.
+[CRED365]
+ROB DUNKIN
-[RADIO_A]
-Appuie sur la ~h~touche ~k~~VEHICLE_CHANGE_RADIO_STATION~~w~ pour faire défiler les ~h~stations de radio.
+[CRED366]
+CHARLIE KINLOCH
-[RADIO_B]
-Appuie sur la ~h~touche ~k~~VEHICLE_CHANGE_RADIO_STATION~~w~ pour faire défiler les ~h~stations de radio.
+[CRED367]
+KEVIN HOBSON
-[RADIO_C]
-Appuie sur la ~h~touche ~k~~VEHICLE_CHANGE_RADIO_STATION~~w~ pour faire défiler les ~h~stations de radio.
+[CRED368]
+JIM CREE
-[RADIO_D]
-Appuie sur la ~h~touche ~k~~VEHICLE_CHANGE_RADIO_STATION~~w~ pour faire défiler les ~h~stations de radio.
+[MOB_66A]
+Tommy, Tommy, Tommy, pourquoi t'es revenu ici?
-[FEC_EXV]
-Entrer\sortir d'un véhicule
+[MOB_66B]
+On t'a déjà dit qu'on voulait plus te revoir.
-[TAXI_M]
-'TAXI DRIVER'
+[MOB_67A]
+Tommy, je crois que tu devrais rester à l'écart, tu saisis?
-[COP_M]
-'POLICE'
+[MOB_67B]
+Les petits gars Haïtiens t'aiment pas beaucoup.
-[FIRE_M]
-'POMPIER'
+[MOB_18A]
+Tommy, c'est Paulo. Tu vas bien? Bon, mec, il faut que je te parle.
-[AMBUL_M]
-'AMBULANCE'
+[MOB_18B]
+Ah, mon pote, tu croiras jamais l'incroyable petit lot que je viens de lever...
-[HJ_IS]
-BONUS DE CASCADE DANGEREUSE : ~1~$
+[MOB_18C]
+Elle se promenait juste en bas dans Little Havana, mon pote.
-[HJ_PIS]
-BONUS DE CASCADE DANGEREUSE PARFAITE : ~1~$
+[MOB_18D]
+Elle m'a dit qu'elle s'appelait Mercedes ou un truc comme ça.
-[HJ_DIS]
-BONUS DE DOUBLE CASCADE DANGEREUSE : ~1~$
+[MOB_18E]
+Ah, mon pote, faut que t'ailles voir cette fille!
-[HJ_PDIS]
-BONUS DE DOUBLE CASCADE DANGEREUSE PARFAITE : ~1~$
+[MOB_18F]
+Elle ferait bander un eunuque! Elle m'a dit que j'étais le meilleur coup de sa vie et tout et tout!
-[HJ_TIS]
-BONUS DE TRIPLE CASCADE DANGEREUSE : ~1~$
+[MOB_18G]
+Vas-y, trouve-la. A plus tard!
-[HJ_PTIS]
-BONUS DE TRIPLE CASCADE DANGEREUSE PARFAITE : ~1~$
+[MOB_72A]
+Tommy, c'est moi, Lance. Ferme-la, Tommy, parce que j'ai pas le temps de discuter!
-[HJ_QIS]
-BONUS DE QUADRUPLE CASCADE DANGEREUSE : ~1~$
+[MOB_72B]
+J'me tape de ce que t'as à me dire. Pourquoi ça m'intéresserait? T'en as rien à foutre de moi, non?
-[HJ_PQIS]
-BONUS DE QUADRUPLE CASCADE DANGEREUSE PARFAITE : ~1~$
+[MOB_72C]
+Il faut que tu sois plus sympa avec moi. Donne-moi une belle part. Tu vois...
-[AM1_K]
-Salvatore Leone partira de chez Luigi dans environ trois heures. (0~1~:~1~)
+[MOB_72D]
+Tommy... Ecoute, mec, je suis désolé. C'est que...
-[IMPEXPP]
-Transport-Export, port de Portland. On a commandé différents véhicules. Consulte notre panneau d'affichage pour avoir plus d'infos.
+[MOB_72E]
+Les gens arrêtent pas de me materner, de me traiter comme un gamin.
-[VANHSTP]
-Si t'arrives à choper d'autres Sécuricars, amène-les à notre garage dans le port de Portland.
+[MOB_72F]
+Mon frère pourrait me faire ça, mais pas toi. S'il te plaît.
-[EMVHPUP]
-Achat de véhicules de secours neufs et d'occasion à très bons prix. Apporte-les à la grue, au nord-est du port de Portland.
+[MOB_72G]
+Faut que j'y aille.
-[STANDS]
-ETALS RENVERSES :
+[MOB_63A]
+Tommy, c'est Earnest. Earnest Kelly.
-[STASH]
-~g~Planque la SPANK sur le ~p~chantier!
+[MOB_63B]
+Ca va?
-[MCSTNS]
-Aucune memory card (PS2) dans la fente pour MEMORY CARD 1. Veux-tu commencer? (OUI ou NON)
+[MOB_63C]
+Bien. Il va me falloir une canne pour marcher, mais je devrais revenir rapidement dans les affaires.
-[LOVE3_5]
-~g~L'avion est à portée.
+[MOB_63D]
+Bien.
-[LOVE3_6]
-~r~La police a réussi à récupérer les paquets!
+[MOB_63E]
+J'ai appris au sujet de Lance. Quel enculé, hein?
-[SIREN_1]
-Pour déclencher la sirène de ce véhicule, appuie brièvement sur la ~h~touche ~k~~VEHICLE_HORN~~w~.
+[MOB_63F]
+Ouais.
-[SIREN_2]
-Pour déclencher la sirène de ce véhicule, appuie brièvement sur la ~h~touche ~k~~VEHICLE_HORN~~w~.
+[MOB_63G]
+Ne jamais faire confiance à un mec qui se trimballe en pyjama. C'est ce que je dis toujours. J'espère bien qu'il en a bavé, ce con.
-[FM3_8C]
-~w~J'ai besoin de 100 000$ pour couvrir mes dépenses,
+[MOB_63H]
+Je crois que oui. Je pensais pas qu'il était comme ça...
-[MCLOAD]
-Chargement des données. Ne pas retirer la memory card (PS2) de la fente pour MEMORY CARD 1, ni réinitialiser ou éteindre la console.
+[MOB_63I]
+Tommy, t'as beau être cinglé, t'es vraiment naïf. Il va falloir que je t'apprenne deux ou trois trucs sur la vie, dès que je serai remis sur pied.
-[FES_GME]
-Erreur de lecture sur la memory card (PS2) de la fente pour MEMORY CARD 1. Vérifie-la et réessaie.
+[MOB_63J]
+Prends ton temps, Earnest et surtout, prends soin de toi.
-[FESZ_QF]
-Veux-tu vraiment formater la memory card (PS2) de la fente pour MEMORY CARD 1?
+[MOB_16A]
+Tommy, c'est Paulo. Que pasa amigo?
-[FESZ_LS]
-Chargement réussi.
+[MOB_16B]
+Qu'est-ce tu m'veux, Paul? J'veux pas de fringues de contrefaçon.
-[RM3_5]
-~g~Tu as ~1~ des 6 paquets de preuves.
+[MOB_16C]
+Très drôle, mon pote, mais tu sais que je fais pas dans la merde. Non, j'appelle juste pour savoir si t'aurais pas un rôle pour moi dans un de tes films.
-[LOVE3_2]
-~g~Tu as récupéré tous les paquets! Rapporte-les à Donald Love.
+[MOB_16D]
+J'ai fait pas mal de X en Angleterre, mec. J'en ai plus que toi dans l'pantalon.
-[LOVE4_4]
-~g~Rapporte le paquet à Donald Love!
+[MOB_16E]
+Paul, merci pour la proposition, je vais y réfléchir.
-[CLZOON]
-Show Cull Zones On
+[MOB_16F]
+Sérieux, pense à moi, après tout ce que j'ai fait pour toi.
-[CLZOOF]
-Show Cull Zones Off
+[MOB_16G]
+C'est ce que j'essaie d'oublier, justement...
-[CRRGON]
-ShowCarRoadGroups On
+[MOB_17A]
+Tommy Vercetti, comment vas-tu? J'ai entendu tous ces trucs sur toi. Un flambeur en ville maintenant...
-[CRGOFF]
-ShowCarRoadGroups Off
+[MOB_17B]
+Paul, t'es bourré?
-[CULREC]
-CCullZones::RecalculateCullZoneData()
+[MOB_17C]
+Non, pauv' con, je suis pas bourré! J'ai juste pris deux ou trois verres et quelques tournées, et ça fait deux jours que j'ai pas fermé l'oeil!
-[DBGFON]
-CTheScripts::DbgFlag On
+[MOB_17D]
+De toute façon, me traite pas comme ça. Je suis pas une poire. Qui c'est qui t'a lancé dans cette ville? Hein, qui? Moi!
-[DBFOFF]
-CTheScripts::DbgFlag Off
+[MOB_17F]
+Ah ouais?
-[DSTRON]
-Debug Streaming Requests On
+[MOB_17G]
+Me traite pas comme ça? Qui c'est qui t'a présenté à des gens? Je t'ai montré tous les trucs, je me suis fait chier pour toi et voilà comment tu m'remercies.
-[DSTROFF]
-Debug Streaming Requests Off
+[MOB_17H]
+Tu m'ignores. Tu me laisses de côté après tout ce que j'ai fait pour toi! Qui tu crois que je suis? Une merde ou je sais pas quoi?
-[FED_DFL]
-CTheScripts::DbgFlag
+[MOB_17I]
+Paul, calme-toi. J'ai été occupé, ne sois pas stupide.
-[FED_DLS]
-Big White Debug Light Switched
+[MOB_17J]
+Je suis pas stupide, connard! Ils me l'ont dit en maison de redressement! Si tu cherches les emmerdes, mon pote, tu vas les trouver!
-[FED_DSR]
-Debug Streaming Requests
+[MOB_17K]
+Tommy, s'il te plaît! T'étais mon grand espoir! Te fous pas de moi!
-[FED_PAH]
-Parse Heap
+[MOB_17L]
+Paul, va roupiller un bon coup, sérieusement.
-[FED_RCD]
-CCullZones::RecalculateCullZoneData
+[MOB_73A]
+Tommy, c'est Steve.
-[FED_RID]
-Reload IDE
+[MOB_73B]
+Salut, Steve.
-[FED_RIP]
-Reload IPL
+[MOB_73C]
+Salut le génie. T'es merveilleux! Je suis une merveille! Ils nous adorent. On réécrit le livre des records, mon pote!
-[FED_SCP]
-gbShowCollisionPolys
+[MOB_73D]
+Je parle de putain de récompenses. Enfin je peux envoyer mon père à l'hospice et lui dire de fermer sa gueule.
-[FED_SCR]
-Show Car Road Grups
+[MOB_73E]
+Euh... C'est cool, Steve.
-[FED_SCZ]
-Show Cull Zones
+[MOB_73F]
+Cool? C'est génial, mec. GENIAL quoi! Il n'a jamais voulu croire en moi, mais regarde ce qu'on a réussi à faire.
-[FED_SPR]
-Show Ped Road Groups
+[MOB_73G]
+Je suis le plus grand réalisateur de films de cul faits maison de la planète, mon pote. Je voulais juste te dire que je suis heureux de t'avoir rencontré.
-[GORLEV]
-Gore Level
+[MOB_73H]
+Merci, Steve.
-[LITTLE]
-LITTLE T
+[MOB_73I]
+Je t'aime, bébé. Et reste comme tu es, d'accord?
-[NICK]
-NICK LOVE
+[MOB_73J]
+D'accord. Salut, Steve.
-[PARSHP]
-Parse Heap
+[BOLLOX]
+Appuie sur la touche ~o~R1 ~w~pour larguer une bombe. Appuie sur la touche ~t~" ~w~pour annuler.
-[PDRGON]
-ShowPedRoadGroups On
+[BRID_OP]
+Avis de tempête terminé : tous les ponts sont maintenant accessibles.
-[PRGOFF]
-ShowPedRoadGroups Off
+[BRID_CL]
+Avis de tempête : tous les ponts sont fermés.
-[RELIDE]
-ReLoadIde
+[LG_38]
+Cible
-[RELIPE]
-ReLoadIpl
+[ASSET_C]
+Pole Position, OK
-[SCASSL]
-Sick Fuck Selected
+[ASSET_D]
+~g~Le club Pole Position va maintenant créer un revenu d'un maximum de $~1~ par jour. Venez retirer votre argent régulièrement.
-[SCSCSL]
-Sick Fucker Selected
+[ST_WHEE]
+Temps maximum sur roue arrière (secs)
-[SHPLON]
-gbShowCollisionPolys On
+[ST_STOP]
+Temps maximum sur roue avant (secs)
-[SHPLOF]
-gbShowCollisionPolys Off
+[ST_2WHE]
+Temps maximum sur deux roues (secs)
-[SICSIC]
-Sick Fucker
+[ST_WHED]
+Distance maximum sur roue arrière (m)
-[SICASS]
-Sick Fuck
+[ST_STOD]
+Distance maximum sur roue avant (m)
-[FEB_SAV]
-Charger
+[ST_2WHD]
+Distance maximum sur deux roues (m)
-[FEP_SAV]
-CHARGER PARTIE
+[OUTFT11]
+Survêtement
-[AS2_12A]
-~g~Quand t'auras renversé le premier étal, t'auras plus que 8 minutes avant que le Cartel prévienne ses revendeurs!
+[OUTFT12]
+Frankie
-[AS3_1A]
-~g~Et maintenant, rejoins la ~b~bouée repère!
+[RELOAD]
+~g~Tu as gagné la possibilité de recharger ton arme rapidement
-[NOCONT]
-Reconnecte une manette analogique (DUALSHOCK#) ou manette analogique (DUALSHOCK#2) au port de manette 1 pour continuer.
+[APACHE]
+Hunter livré à l'héliport d'Ocean Beach
-[BET_JB]
-TRAHI PAR CATALINA, SA PETITE AMIE, ET LAISSE POUR MORT. JUGE COUPABLE ET CONDAMNE A UNE PEINE DE PRISON, IL COMMENCE SA PEINE AU PENITENCIER DE LIBERTY. MAIS UNE SEULE ET UNIQUE PENSEE LE HANTE...... LA VENGEANCE !
+[CRED369]
+JOHN MCCARDLE
-[END_A]
-Les habitants de Cedar Grove subissent les conséquences
+[CRED370]
+DAVID MURDOCH
-[END_B]
-psychologiques de l'attentat qui a frappé
+[CRED371]
+CHRIS BROWN
-[END_C]
-leur quartier, hier.
+[CRED372]
+PAUL GREEN
-[END_D]
-Un riverain, Clive Denver, a donné à la police la description
+[CRED373]
+KYLE MILNE
-[END_E]
-d'un homme armé qu'il a vu fuir du secteur, accompagné d'une femme aux cheveux noirs.
+[CUNTY]
+Nouveaux vêtements livrés au Domaine Vercetti
-[END_F]
-Oh, tu sais, on va bien s'amuser, parce que, tu sais, oui, tu le sais,
+[GOODBOY]
+$50 pour bonne conduite
-[END_G]
-je t'aime, hein, je t'aime de tout mon coeur, tu es si beau, si fort,
+[NEWCONT]
+Nouveau ~h~point de contact ~w~créé à la marina d'Ocean Beach
-[END_H]
-tu es l'homme que j'ai toujours rêvé d'avoir à mes côtés !
+[FIRELVL]
+Mission Camion de pompiers niveau ~1~
-[END_I]
-Peu importe, j'en étais où, moi ?
+[HELP56]
+Appuie sur la touche ~h~~k~~CAMERA_CHANGE_VIEW_ALL_SITUATIONS~~w~ pour changer le mode de la caméra.
-[END_J]
-Oh, je sais plus. Mais tu sais ce que c'est, hein ?
+[HELP57]
+Appuie sur la touche ~h~~k~~CAMERA_CHANGE_VIEW_ALL_SITUATIONS~~w~ pour changer le mode de la caméra.
-[END_K]
-Les explosions ont retenti près des habitations, semant Le trouble dans le quartier. Les gens couraient dans tous les sens à la recherche d'un abri.
+[HELP58]
+Tout en visant, appuie sur la touche ~h~~k~~PED_CYCLE_TARGET_LEFT~~w~ ou ~h~~k~~PED_CYCLE_TARGET_RIGHT~~w~ pour faire défiler les cibles.
-[END_L]
-Plusieurs civils ont été blessés dans la panique alors que les forces de l'ordre
+[HELP59]
+Tout en visant, appuie sur la touche ~h~~k~~PED_CYCLE_TARGET_LEFT~~w~ ou ~h~~k~~PED_CYCLE_TARGET_RIGHT~~w~ pour faire défiler les cibles.
-[END_M]
-échangeaient des coups de feu avec un hélicoptère qui survolait le barrage.
+[HELP60]
+Si tu appuies sur la touche ~h~~k~~PED_SPRINT~ ~w~quand tu essaies de piquer une caisse, tu ne peux pas monter dedans.
-[END_N]
-Ouais, d'ici, on a une vue imprenable sur les jardins.
+[HELP61]
+Tu as désormais des munitions illimitées et tous tes véhicules sont deux fois plus résistants.
-[END_O]
-Lorsque l'hélico a enfin été bousillé,
+[CRED374]
+KEVIN YUN
-[END_P]
-c'était encore plus grandiose qu'un feu d'artifices !
+[CRED375]
+ERICK COBBS
-[END_Q]
-On recense déjà plus de vingt morts mais
+[CRED376]
+RANDY BLAKE
-[END_R]
-la police continue à découvrir des corps sous les décombres.
+[CRED377]
+BRANDON LIM
-[END_S]
-Les rumeurs selon lesquelles les morts appartenaient au cartel des Colombiens
+[CRED378]
+BRANDON FENOL
-[END_T]
-n'ont pas été officiellement démenties.
+[CRED379]
+MICHAEL MANOLE
-[END_U]
-Il n'y a toujours aucune piste qui expliquerait la raison de ce massacre.
+[CRED380]
+ALETHEIA SIMONSON
-[END_V]
-Je me suis cassé un ongle et ma mise en plis est foutue ! Tu le crois, ça ?
+[CRED381]
+JOHN JANSEN
-[END_W]
-Ca m'avait coûté 50 dollars...
+[FEC_LB1]
+Regarder
-[PAPER1]
-UN CRIMINEL TRAHI PAR SA PETITE AMIE ET COMPLICE. LES JURES RECONNAISSENT, LE VOLEUR ARME, COUPABLE A L'UNANIMITE!
+[FEC_LB2]
+derrière
-[PAPER2]
-LOVE, CONDAMNE A DIX ANS FERME !
+[FEC_LB3]
+Regarder derrière
-[FEB_CPC]
-Configuration des commandes
+[FEC_R3]
+(touche R3)
[FEC_PED]
Commandes à pied
@@ -7221,7 +7129,7 @@ Fusil à lunette zoom arrière
Regarder à gauche en vue subjective
[FEC_LRT]
-Regarder à droite en vue subjective First Person Look Right
+Regarder à droite en vue subjective
[FEC_LUP]
Regarder en haut en vue subjective
@@ -7277,84 +7185,6 @@ Changer de mode de caméra
[FEC_TSS]
Faire une capture d'écran
-[FEN_NET]
-Réseau
-
-[FEN_CON]
-Connexion
-
-[FEN_GAM]
-Trouver partie
-
-[FEN_TYP]
-Type de partie
-
-[FEN_TY0]
-Deathmatch
-
-[FEN_TY1]
-Furtif en Deathmatch
-
-[FEN_TY2]
-Deathmatch par équipes
-
-[FEN_TY3]
-Furtif en Deathmatch par équipes
-
-[FEN_TY4]
-Planquer l'argent
-
-[FEN_TY5]
-Capturer le drapeau
-
-[FEN_TY6]
-Rat Race
-
-[FEN_TY7]
-Domination
-
-[FEN_NAM]
-Nom :
-
-[FEN_GNA]
-Nom partie :
-
-[FEM_MAP]
-Choisir carte
-
-[FEN_PLS]
-Réglages joueur
-
-[FEN_PLC]
-Couleur joueur
-
-[FEM_MA0]
-Liberty City
-
-[FEM_MA1]
-Le Quartier Rouge
-
-[FEM_MA2]
-Chinatown
-
-[FEM_MA3]
-La Tour
-
-[FEM_MA4]
-Le Dépotoir
-
-[FEM_MA5]
-Le Parc Industriel
-
-[FEM_MA6]
-Les Docks
-
-[FEM_MA7]
-Staunton
-
-[FEC_EMS]
-Touches clavier uniquement
-
[FEC_DBG]
Menu Debug
@@ -7406,41 +7236,209 @@ Utiliser regarder gauche avec regarder droite
[FEC_JBO]
JOY ~1~
-[NO_PAUZ]
-Impossible de mettre en pause en multijoueur. Appuyez deux fois pour quitter !
+[FEC_WAR]
+Avertissement
-[FEM_SL1]
-Emplacement 1 libre
+[FEC_OKK]
+O.K.
-[FEM_SL2]
-Emplacement 2 libre
+[FEC_DLF]
+Erreur lors de suppression
-[FEM_SL3]
-Emplacement 3 libre
+[FEC_SVU]
+Erreur lors de la sauvegarde
-[FEM_SL4]
-Emplacement 4 libre
+[FEC_LUN]
+Erreur lors du chargement. Fichier corrompu, veuillez le supprimer.
-[FEM_SL5]
-Emplacement 5 libre
+[FEC_PAD]
+Manette
-[FEM_SL6]
-Emplacement 6 libre
+[FEC_JOY]
+Joystick
-[FEM_SL7]
-Emplacement 7 libre
+[FES_CSA]
+Sélectionnez une apparence dans la liste suivante :
-[FEM_SL8]
-Emplacement 8 libre
+[FET_HRD]
+PARAMETRES PAR DEFAUT RETABLIS
+
+[FET_MST]
+DIRECTION CONTROLEE PAR LA SOURIS
+
+[FEC_STR]
+ETOILE PAV.NUM.
+
+[FET_MIG]
+GAUCHE, DROITE, MOLETTE SOURIS POUR REGLER
+
+[FET_CIG]
+RETOUR ARRIERE POUR EFFACER - BGS, RETOUR POUR CHANGER
+
+[FET_DSN]
+Skin joueur par defaut.bmp
+
+[FET_RSO]
+PARAMETRE D'ORIGINE RETABLI
+
+[FET_RSC]
+MATERIEL INDISPONIBLE - PARAMETRE D'ORIGINE RETABLI
+
+[FEA_3DH]
+CONFIG. CARTE-SON
+
+[FEA_SPK]
+CONFIG. HAUT-PARLEURS
+
+[FEM_LOD]
+DISTANCE MODELES
+
+[FEM_VSC]
+SYNCHRO VIDEO
+
+[FEM_FRM]
+RESTRICTION VIDEO
[FEM_MM]
MENU PRINCIPAL
-[FEM_SNG]
-Nouvelle partie
+[FED_RES]
+RESOLUTION ECRAN
+
+[FET_CTL]
+CONFIG. PERIPHERIQUE
+
+[FET_OPT]
+OPTIONS
+
+[FEC_MSH]
+SENSIBILITE SOURIS
+
+[FEC_IVV]
+INVERSER SOURIS VERTIC.
+
+[FET_MTI]
+CONFIG. SOURIS
+
+[FEC_FNC]
+F~1~
+
+[FEC_IRT]
+INSER
+
+[FEC_DLL]
+SUPPR
+
+[FEC_HME]
+ORIG
+
+[FEC_END]
+FIN
+
+[FEC_PGU]
+PAGE HAUT
+
+[FEC_PGD]
+PAGE BAS
+
+[FEC_UPA]
+HAUT
+
+[FEC_DWA]
+BAS
+
+[FEC_LFA]
+GAUCHE
+
+[FEC_RFA]
+DROITE
+
+[FEC_NUM]
+PAV.NUM
+
+[FEC_NMN]
+PAV.NUM~1~
+
+[FEC_FWS]
+PAV.NUM /
+
+[FEC_PLS]
+PAV.NUM +
+
+[FEC_MIN]
+PAV.NUM -
+
+[FEC_DOT]
+PAV.NUM .
+
+[FEC_NLK]
+VERR NUM
+
+[FEC_ETR]
+ENTR
+
+[FEC_SLK]
+ARRET DEFIL
+
+[FEC_PSB]
+PAUSE
+
+[FEC_BSP]
+RET. ARR.
+
+[FEC_TAB]
+TAB
+
+[FEC_CLK]
+VERR MAJ
+
+[FEC_RTN]
+RETOUR
+
+[FEC_LSF]
+MAJ. G
+
+[FEC_RSF]
+MAJ. D
+
+[FEC_LCT]
+CTRL G
+
+[FEC_RCT]
+CTRL D
+
+[FEC_LAL]
+ALT G
+
+[FEC_RAL]
+ALT D
+
+[FEC_LWD]
+WIN G
+
+[FEC_RWD]
+WIN D
+
+[FEC_WRC]
+CLIC WIN
+
+[FEC_SPC]
+ESP
+
+[WIN_TTL]
+Grand Theft Auto VC
-[FEM_QTW]
-Quitter
+[WIN_95]
+Grand Theft Auto VC n'est pas compatible WINDOWS 95
+
+[WIN_DX]
+Grand Theft Auto VC requiert la version 8.1 de DirectX minimum.
+
+[FET_EIG]
+IMPOSSIBLE DE PARAMETRER UNE TOUCHE POUR CETTE ACTION
+
+[FET_DAM]
+MODELAGE ACCOUST. DYNAMIQUE
[FEQ_SRE]
Etes-vous sûr de vouloir quitter ? Votre progression depuis la dernière sauvegarde sera perdue. Continuer ?
@@ -7448,742 +7446,7127 @@ Etes-vous sûr de vouloir quitter ? Votre progression depuis la dernière sauveg
[FEQ_SRW]
Etes-vous sûr de vouloir quitter la partie ?
-[FEG_SRV]
-SERVEUR
+[FET_QG]
+QUITTER PARTIE
-[FEG_MAP]
-CARTE
+[FEN_STA]
+COMMENCER PARTIE
-[FEG_PLY]
-JOUEURS
+[FET_PAU]
+MENU PAUSE
-[FEG_TYP]
-TYPE
+[REPLAY]
+RALENTI
-[FEG_PNG]
-PING
+[FET_PS]
+CONFIG. JOUEURS
-[FET_FG]
-TROUVER PARTIE
+[FEC_ANS]
+Action
-[FET_SP]
-SOLO
+[CVT_MSG]
+Conversion des textures vers un format optimal pour votre carte graphique
-[FET_MP]
-MULTIJOUEUR
+[FEC_SFT]
+MAJ
-[FET_HG]
-CREER UNE PARTIE
+[FEH_VMP]
+VOIR CARTE
-[FET_PS]
-CONFIG. JOUEURS
+[FES_DEE]
+Echec de la suppression ! Recommencer.
-[FET_CON]
-CONNEXION
+[FES_CMP]
+Echec de la sauvegarde ! Recommencer.
-[FET_AUD]
-CONFIG. AUDIO
+[FESZ_WR]
+Sauvegarde en cours. Un instant...
-[FET_DIS]
-CONFIG. AFFICHAGE
+[FELD_WR]
+Chargement en cours. Un instant...
-[FET_LAN]
-CHOIX LANGUE
+[FEDL_WR]
+Suppression en cours. Un instant...
-[FET_LG]
-CHARGER PARTIE
+[PCRESRT]
+Lancement d'une nouvelle partie. Un instant...
-[FET_DG]
-SUPPRIMER PARTIE
+[FET_STI]
+Commandes standard
-[FET_NG]
-NOUVELLE PARTIE
+[FET_CTI]
+Commandes classiques
-[FET_SG]
-SAUVEGARDER PARTIE
+[FEH_NA]
+OPTION NON DISPONIBLE
-[FET_MAP]
-CHOISIR CARTE
+[FEH_MPH]
+SOURIS, CURSEURS POUR SE DEPLACER - PAGE HAUT, PAGE BAS, MOLETTE POUR ZOOMER, L - LEGENDE
-[FET_GT]
-TYPE DE PARTIE
+[FEA_MP3]
+LECTEUR MP3
-[FET_CTL]
-CONFIG. PERIPHERIQUE
+[NO_PCCD]
+Insérer le disque de GTA Vice City ou appuyer sur ECHAP pour annuler
-[FET_OPT]
-OPTIONS
+[FEH_SSA]
+CURSEURS POUR SE DEPLACER - S POUR SAUVEGARDER LE FICHIER
-[FET_QG]
-QUITTER PARTIE
+[FES_CMI]
+DERNIERE MISSION REUSSIE
-[FET_STA]
-STATISTIQUES
+[FET_STS]
+STATS SAUVEGARDEES DANS 'STATS.HTML' + 'STATS.TXT'
-[FET_BRE]
-BRIEFINGS
+[WIN_VDM]
+Grand Theft Auto VC ne dispose pas de suffisamment de mémoire graphique.
-[FEC_WAR]
-Avertissement
+[FEC_ERI]
+Erreur ! Une ou plusieurs actions ne sont pas assignées à une touche ou à un bouton. Vérifier que toutes les actions sont bien assignées.
-[FEC_OKK]
-O.K.
+[FEC_TFU]
+Tourelle + Orienter haut
-[FED_CON]
-Confirmation de suppression de fichier
+[FEC_TFD]
+Tourelle + Orienter bas
-[FES_SSC]
-Sauvegarde de la partie effectuée
+[FET_RIG]
+CHOISIR UNE AUTRE COMMANDE POUR CETTE ACTION
-[DEL_FNM]
-Suppression du fichier effectuée
+[FEA_NM3]
+AUCUN FICHIER MP3 TROUVE
-[PCLOAD]
-Chargement des données du fichier
+[FEA_MPB]
+VOLUME MP3 A FOND
-[PCRESRT]
-Redémarrage de Grand Theft Auto III
+[FEA_MUS]
+VOLUME MUSIQUE
-[FEC_DLF]
-Erreur lors de suppression
+[FEA_SFX]
+VOLUME EFFETS SONORES
-[FEC_SVU]
-Erreur lors de la sauvegarde
+[CVT_ERR]
+Espace disque épuisé. Libérez de la mémoire sur votre disque dur pour continuer. Appuyez sur ECHAP pour annuler.
-[FEC_LUN]
-Erreur lors du chargement. Fichier corrompu, veuillez le supprimer.
+[FEA_ADP]
+AUTODETECT MATERIEL
-[FEN_PLA]
-Nombre de joueurs :
+{=================================== MISSION TABLE AMBULAE ===================================}
-[FET_NON]
-AUCUNE PARTIE DISPONIBLE
+[ATUTOR2:AMBULAE]
+~g~Conduis les patients à l'hôpital. DOUCEMENT. Chaque secousse réduit leurs chances de survie.
-[FET_SFG]
-RECHERCHE DE PARTIES...
+[A_FULL:AMBULAE]
+~r~Ambulance pleine!
-[FET_SRT]
-TRI DES PARTIES...
+[A_FAIL2:AMBULAE]
+~r~Ton manque de rapidité a été fatal pour le patient!
-[FEF_LAN]
-RESEAU
+[A_FAIL3:AMBULAE]
+~r~Le patient est mort!!
-[FEF_INT]
-INTERNET
+[A_PASS:AMBULAE]
+Sauvé!
-[FET_REF]
-Rafraîchir
+[A_COMP2:AMBULAE]
+Tu ne seras plus jamais essoufflé!
-[FET_FIL]
-Filtre
+[A_COMP1:AMBULAE]
+Missions Ambulance réussies : $~1~
-[FET_JG]
-Rejoindre
+[A_CANC:AMBULAE]
+~r~Mission ambulance annulée!
-[FEC_NTW]
-Talk To Network
+[A_COMP3:AMBULAE]
+Missions ambulance accomplies! Maintenant, tu peux sprinter indéfiniment!
-[FEC_ESR]
-Utilisation restreinte de la touche Echap
+[ALEVEL:AMBULAE]
+Mission ambulance, niveau ~1~
-[FEC_GSL]
-Show head bob:
+[A_FAIL1:AMBULAE]
+Mission ambulance achevée.
-[FIL_FLT]
-FILTRER LISTE DES PARTIES
+[A_SAVES:AMBULAE]
+PERSONNES SAUVEES : ~1~
-[FET_SAN]
-NOUVELLE PARTIE
+{=================================== MISSION TABLE ASSIN1 ===================================}
-[FIL_MAP]
-Carte :
+[ASM1_5:ASSIN1]
+~r~Il a livré toutes ses pizzas!
-[FIL_SRV]
-Serveur :
+[ASM1_6:ASSIN1]
+Livraisons restantes :
-[FIL_TYP]
-Type de partie :
+[ASM1_7:ASSIN1]
+~g~Carl Pearson, livreur de pizzas. Tue-le avant qu'il ne termine ses livraisons.
-[FIL_SPC]
-Parties avec espace disponible ?
+[ASM1_D:ASSIN1]
+Ton aide dans l'éradication de ces indésirables fut une excellente affaire.
-[FIL_PNG]
-Ping :
+{=================================== MISSION TABLE ASSIN2 ===================================}
-[FEN_UKH]
-Hôte inconnu
+[ASM2_1:ASSIN2]
+~g~Mme Dawson va bientôt quitter la bijouterie à Vice Point. Tue-la. Il faut que ça ressemble à un accident de voiture.
-[FEN_UKM]
-Carte non trouvée
+[ASM2_3:ASSIN2]
+~g~Ca va sauter, écarte toi!
-[FEN_UKT]
-Type de partie non trouvé
+[ASM2_4:ASSIN2]
+~r~T'as bousillé sa bagnole alors qu'elle était même pas dedans. Elle est pas près de l'utiliser, maintenant!
-[FEN_NCI]
-VOUS N'ETES PAS CONNECTE A INTERNET
+[ASM2_5:ASSIN2]
+~r~Elle s'est enfuie!
-[FET_PAU]
-MENU PAUSE
+[ASM2_6:ASSIN2]
+~r~Tu étais trop près de l'accident!
-[FET_SGA]
-COMMENCER PARTIE
+[ASM2_7:ASSIN2]
+~g~N'utilise pas d'armes! Il faut que ça ressemble à un accident! Sors-la plutôt de la route!
-[FEC_SGJ]
-Régler joystick
+[ASM2_8:ASSIN2]
+~g~La mort de madame Dawson doit avoir l'air d'un accident. N'utilise pas d'armes.
-[FEC_PAD]
-Manette
+[ASM2_9:ASSIN2]
+~g~Il te faut une voiture pour ce boulot!
-[FEC_JOY]
-Joystick
+[ASM2_10:ASSIN2]
+~g~Quand sa bagnole prendra feu, éloigne-toi le plus possible du lieu de l'accident.
-[FEC_WHL]
-Volant
+[ASM2_11:ASSIN2]
+A l'aide!
-[FEC_CNT]
-Type de périphérique :
+[ASM2_12:ASSIN2]
+Que quelqu'un m'aide!
-[FET_APL]
-APPLIQUER
+[ASM2_13:ASSIN2]
+Oh non!
-[FES_CSA]
-Sélectionnez une apparence dans la liste suivante :
+[ASM2_A:ASSIN2]
+Mes félicitations pour ce travail bien fait, Mr. Teal. Mon client était ravi.
-[FES_SKN]
-NOM DE L'APPARENCE
+[ASM2_2:ASSIN2]
+Santé :
-[FES_DAT]
-DATE
+{=================================== MISSION TABLE ASSIN3 ===================================}
-[FES_NON]
-AUCUNE APPARENCE DISPONIBLE
+[ASM3_11:ASSIN3]
+TEMPS :
-[FEA_FM9]
-LECTEUR MP3
+[ASM3_C:ASSIN3]
+Un gang européen prépare un braquage de banque à Vice City. Mes employeurs préfèreraient que cela n'arrive pas.
-[FESZ_QZ]
-Etes-vous sûr de vouloir sauvegarder cette partie ?
+[ASM3_D:ASSIN3]
+Chaque membre du gang dispose d'une couverture à Vice City. Certains ont des petits boulots, d'autres jouent les touristes.
-[FES_CGA]
-Emplacements disponibles :
+[ASM3_E:ASSIN3]
+Chaque cible et leur position probable sont indiqués sous le téléphone.
-[FES_SCG]
-Sauvegarder la partie actuelle ?
+[ASM3_14:ASSIN3]
+~g~Dick Tanner est à côté de DBP Security sur Ocean Drive.
-[FES_LCG]
-Charger la partie et continuer à jouer ?
+[ASM3_15:ASSIN3]
+~g~Marcus Hammond et Franco Carter sont près de la bijouterie de Vice Point.
-[FEC_FIR]
-Tirer
+[ASM3_16:ASSIN3]
+~g~Nick Kong est à côté de Washington Beach.
-[FEC_NWE]
-Arme suivante
+[ASM3_18:ASSIN3]
+~g~Ne t'approche pas trop près de la cible où elle risque de te repérer et d'essayer de se faire la malle!
-[FEC_PWE]
-Arme précédente
+[ASM3_19:ASSIN3]
+~g~Il t'a repéré! Bute-le!
-[FEC_FOR]
-Avant
+[ASM3_20:ASSIN3]
+~g~Ils t'ont repéré! Tue-les vite tous les deux!
-[FEC_BAC]
-Arrière
+[ASM3_21:ASSIN3]
+~r~Tu n'as pas tué tous les membres du gang à temps!
-[FEC_LEF]
-Gauche
+[ASM3_22:ASSIN3]
+~g~Ne t'approche pas trop des cibles ou elles risquent de te repérer et d'essayer de filer.
-[FEC_RIG]
-Droite
+[ASM3_12:ASSIN3]
+~g~Des armes ont été laissées à ta disposition dans le coin si tu en as besoin. Tu as ~h~9 MINUTES ~g~pour tuer tous les membres du gang.
-[FEC_ZIN]
-Zoom avant
+[ASM3_13:ASSIN3]
+~g~Mike Griffin travaille sur un panneau publicitaire à Washington.
-[FEC_ZOT]
-Zoom arrière
+[ASM3_17:ASSIN3]
+~g~Charlie Dilson est à moto sur Washington.
-[FEC_EEX]
-Entrer+sortir
+{=================================== MISSION TABLE ASSIN4 ===================================}
-[FEC_RAD]
-Radio
+[ASM4_12:ASSIN4]
+Distance :
-[FEC_SUB]
-Sous-mission
+[ASM4_15:ASSIN4]
+~g~Prends le fusil à lunette sur ta droite.
-[FEC_CMR]
-Changer caméra
+[ASM4_16:ASSIN4]
+~g~Observe la femme au balcon. Elle va descendre l'escalator et demander l'heure à quelqu'un.
-[FEC_JMP]
-Sauter
+[ASM4_17:ASSIN4]
+~g~Lorsque la conversation est terminée, liquide son interlocuteur sans faire de mal à la femme.
-[FEC_SPN]
-Sprint
+[ASM4_18:ASSIN4]
+~g~Une fois la cible éliminée, récupère la serviette et amène-la à Ammu-Nation dans le centre.
-[FEC_HND]
-Frein à main
+[ASM4_19:ASSIN4]
+~g~Reste à distance de la cible. Sa proximité t'est indiquée par la barre de distance située dans le coin supérieur droit de l'écran.
-[FEC_TUL]
-Tourelle gauche
+[ASM4_20:ASSIN4]
+~g~Ne la laisse pas devenir pleine ou tu seras repéré.
-[FEC_TUR]
-Tourelle droite
+[ASM4_21:ASSIN4]
+~g~Récupère la serviette!
-[FEC_LOL]
-Regarder à gauche
+[ASM4_22:ASSIN4]
+~g~Ramène la serviette à Ammu-Nation dans le centre.
-[FEC_LOR]
-Regarder à droite
+[ASM4_23:ASSIN4]
+~g~Il t'a repéré et s'enfuit. Rattrape-le et récupère la serviette!
-[FEC_NTR]
-Cible suivante
+[ASM4_25:ASSIN4]
+~r~T'as buté la femme, imbécile!
-[FEC_PTT]
-Cible précédente
+[ASM4_26:ASSIN4]
+~r~La cible a embarqué pour son vol!
-[FEC_LBA]
-Regarder en arrière
+[ASM4_27:ASSIN4]
+~r~La cible t'a repéré! Tu devais garder tes distances!
-[FEC_CEN]
-Centrer caméra
+[ASM4_28:ASSIN4]
+~r~La cible t'a repéré! Elle t'a entendu tirer!
-[FEC_UND]
-(NON)
+[ASM4_29:ASSIN4]
+~r~Ne le tue qu'après qu'il ait parlé à la femme!
-[FET_CFT]
-A PIED
+[ASM4_A:ASSIN4]
+L'heure est venue de s'occuper d'un gros poisson, M. Teal. Il y a un fusil dans le feuillage à votre droite.
-[FET_CCR]
-EN VOITURE
+[ASM4_B:ASSIN4]
+Surveillez la femme sur le balcon situé au-dessus des guichets d'enregistrement. Elle va avancer à travers la foule et demander l'heure à quelqu'un.
-[CVT_MSG]
-Conversion des textures vers un format optimal pour votre carte graphique
+[ASM4_C:ASSIN4]
+Vous devez tuer son interlocuteur, récupérer la mallette et l'apporter à l'emplacement indiqué sous le téléphone.
-[FET_CAC]
-ACTION
+{=================================== MISSION TABLE ASSIN5 ===================================}
-[FEC_IBT]
--
+[ASM5_A:ASSIN5]
+Un deal important se déroule sur le toit de l'usine de crème glacée Cherry Popper.
-[FEC_SPC]
-ESP
+[ASM5_B:ASSIN5]
+Descendez toutes les personnes impliquées, embarquez la marchandise et amènez-la à la piste pour hélicos de l'aéroport.
-[FEC_MXO]
-MXB1
+[ASM5_C:ASSIN5]
+Il y a une porte sur votre gauche qui mène à l'arrière de l'usine.
-[FEC_MXT]
-MXB2
+[ASM5_1:ASSIN5]
+~g~Entre dans l'enceinte située derrière l'usine de crème glacée Cherry Popper et va jusqu'au toit où se fait le deal.
-[FEC_UNB]
-NON UTILISE
+[ASM5_2:ASSIN5]
+~g~Récupère la marchandise et amène-la à la piste pour hélicos de l'aéroport.
-[FET_CME]
-TYPE DE COMMANDES
+[ASM5_3:ASSIN5]
+~g~Emmène la marchandise à la piste pour hélicos de l'aéroport!
-[FET_RDK]
-REDEFINIR COMMANDES
+{=================================== MISSION TABLE BANKJ1 ===================================}
-[FET_AMS]
-PARAMETRES SOURIS
+[WANTED1:BANKJ1]
+~g~Largue les flics et perds ton indice de recherche!
-[FET_STI]
-CONFIG. COMMANDES STANDARD
+[BJM1_A:BANKJ1]
+Tommy! Hé, regarde-ça, c'est génial! J'ai fait installer un minibar!
-[FET_CTI]
-CONFIG. COMMANDES NORMALES
+[BJM1_B:BANKJ1]
+Y'a déjà un vrai bar en bas, Ken.
-[FET_MTI]
-CONFIG. SOURIS
+[BJM1_C:BANKJ1]
+Ouais, je sais, et alors? Bon, j'ai le tableau noir que tu m'as demandé.
-[FET_DAM]
-MODELAGE ACCOUST. DYNAMIQUE
+[BJM1_D:BANKJ1]
+Ah, c'est là qu'on voit l'intérêt de ton école de droit : t'as appris à suivre les instructions.
-[FEC_TFL]
-Tourelle Gauche
+[BJM1_E:BANKJ1]
+Bon, il me faut un mec sûr.
-[FEC_TFR]
-Tourelle Droite
+[BJM1_F:BANKJ1]
+Euh, d'accord, laisse-moi réfléchir... Sûr... sûr... sûr... Je sais! Je connais un mec qui te plaira!
-[FEC_TFU]
-Tourelle /Dodo Haut
+[BJM1_G:BANKJ1]
+Aaah, non, merde, ce con est au trou.
-[FEC_TFD]
-Tourelle /Dodo Bas
+[BJM1_H:BANKJ1]
+Comment ça au trou?
-[FEC_MWF]
-MOLETTE HAUT
+[BJM1_I:BANKJ1]
+Dans un poste de police. Il attend son transfert.
-[FEC_MWB]
-MOLETTE BAS
+[BJM1_J:BANKJ1]
+Je crois qu'il va être remis en liberté sur parole...
-[FEC_ORR]
-ou
+[BJM1_1:BANKJ1]
+~g~Sors Cam Jones de chez les flics!
-[FEC_NUS]
-NON UTILISE
+[BJM1_3:BANKJ1]
+~g~Tu trouveras quelque chose d'utile dans la salle des casiers.
-[FEC_LUD]
-Regarder Haut
+[BJM1_21:BANKJ1]
+~g~La carte d'accès aux cellules se trouve à l'étage.
-[FEC_LDU]
-Regarder Bas
+[BNK1_7:BANKJ1]
+Cam Jones?
-[FEC_CMP]
-COMBO : REGARDER G+D
+[BNK1_8:BANKJ1]
+Je viens t'aider à mettre les bouts!
-[FEC_NTT]
-No Text Yet For This Key
+[BNK1_10:BANKJ1]
+Ouais, c'est moi...
-[FEC_FNC]
-F~1~
+[BNK1_11:BANKJ1]
+Ca me va!
-[FEC_IRT]
-INSER
+[BNK1_13:BANKJ1]
+J'ai un boulot à faire et t'es mon perceur de coffre.
-[FEC_DLL]
-SUPPR
+[BNK1_14:BANKJ1]
+Marre de perdre mon temps dans une cellule.
-[FEC_HME]
-ORIG
+[BJM1_22:BANKJ1]
+~g~Ramène Cam chez lui!
-[FEC_END]
-FIN
+[BJM1_23:BANKJ1]
+~g~Tu dois d'abord trouver la carte d'accès!
-[FEC_PGU]
-PAGE HAUT
+[BNK1_12:BANKJ1]
+Sème les flics et ramène-moi chez moi!
-[FEC_PGD]
-PAGE BAS
+[BJM1_20:BANKJ1]
+Jette ton flingue ou tu vas en subir les conséquences!
-[FEC_UPA]
-HAUT
+[BJM1_5:BANKJ1]
+Accès réservé au personnel autorisé!
-[FEC_DWA]
-BAS
+[BJM1_2:BANKJ1]
+~r~T'étais supposé faire sortir Cam, pas le faire tuer!
-[FEC_LFA]
-GAUCHE
+[BJM1_4:BANKJ1]
+Il est armé! Descendez-le!
-[FEC_RFA]
-DROITE
+{=================================== MISSION TABLE BANKJ2 ===================================}
-[FEC_NUM]
-PAV.NUM
+[BJM2_A:BANKJ2]
+Il nous faut un braqueur. T'en connais un?
-[FEC_NMN]
-PAV.NUM~1~
+[BJM2_B:BANKJ2]
+Hé, Tommy, Tommy, ce truc ça permet d'rester dans l'coup, mec!
-[FEC_FWS]
-PAV.NUM /
+[BJM2_C:BANKJ2]
+WoooOOOooo!
-[FEC_PLS]
-PAV.NUM +
+[BJM2_D:BANKJ2]
+J'pourrais être ton braqueur! Haut les mains! Haut les mains!
-[FEC_MIN]
-PAV.NUM -
+[BJM2_E:BANKJ2]
+T'es pas un braqueur, t'es un idiot.
-[FEC_DOT]
-PAV.NUM .
+[BJM2_F:BANKJ2]
+Va boire un verre et ferme-la.
-[FEC_NLK]
-VERR NUM
+[BJM2_G:BANKJ2]
+Hé, tire-toi de mon chemin! Ye ye ye ow ow!
-[FEC_ETR]
-ENTR
+[BJM2_H:BANKJ2]
+Cam, qu'est-ce que t'en penses?
-[FEC_SLK]
-ARRET DEFIL
+[BJM2_I:BANKJ2]
+Ben, le meilleur tireur de cette ville, c'est un mec qui s'appelle Cassidy.
-[FEC_PSB]
-PAUSE
+[BJM2_J:BANKJ2]
+Ah ouais?
-[FEC_BSP]
-RET. ARR.
+[BJM2_K:BANKJ2]
+Ouais. Un militaire ou en tout cas c'est ce qu'il croit.
-[FEC_TAB]
-TAB
+[BJM2_L:BANKJ2]
+Je doute qu'il ait jamais été dans l'armée, mais il sait sûrement où dégotter des flingues.
-[FEC_CLK]
-VERR MAJ
+[BJM2_M:BANKJ2]
+Il devrait être au champ de tir.
-[FEC_RTN]
-RETOUR
+[BJM2_2A:BANKJ2]
+C'est toi, Phil Cassidy?
-[FEC_LSF]
-MAJ. G
+[BJM2_2B:BANKJ2]
+Pourquoi?
-[FEC_RSF]
-MAJ. D
+[BJM2_2C:BANKJ2]
+Je cherche un mec qui sache se servir d'un flingue. D'après ce que je vois, j'suis pas convaincu...
-[FEC_LCT]
-CTRL G
+[BJM2_2D:BANKJ2]
+Mon pote, je peux dégomme une mouche sur ta tête à 25 mètres!
-[FEC_RCT]
-CTRL D
+[BJM2_2E:BANKJ2]
+Vraiment?
-[FEC_LAL]
-ALT G
+[BJM2_2F:BANKJ2]
+Ouais. J'ai appris ça à l'armée.
-[FEC_RAL]
-ALT D
+[BJM2_2G:BANKJ2]
+Ils s'amusent souvent à descendre des mouches à l'armée? Heureusement que je paye pas d'impôts!
-[FEC_LWD]
-WIN G
+[BJM2_2H:BANKJ2]
+Tu t'crois marrant peut-être, minus?
-[FEC_RWD]
-WIN D
+[BJM2_2I:BANKJ2]
+Ha ha ha ha ha!
-[FEC_WRC]
-CLIC WIN
+[BJM2_2J:BANKJ2]
+Tirons quelques coups.
-[WIN_TTL]
-Grand Theft Auto III
+[BJM2_1:BANKJ2]
+~g~Va à Ammu-Nation dans le centre et parle à Phil Cassidy.
-[WIN_95]
-Grand Theft Auto III n'est pas compatible WINDOWS 95
+[BJM2_4:BANKJ2]
+SCORE MANCHE 1 : ~1~
-[WIN_DX]
-Grand Theft Auto III requiert la version 8.1 de DirectX minimum.
+[BJM2_6:BANKJ2]
+SCORE MANCHE 2 : ~1~
-[WIN_VDM]
-Grand Theft Auto III requiert au moins 12 Mo de mémoire vidéo libre.
+[BJM2_7:BANKJ2]
+SCORE TOTAL : ~1~
-[DIAB3_G]
-Arriba !
+[BJM2_9:BANKJ2]
+~g~Va au point de départ de la deuxième manche.
-[FEM_RES]
-REPRENDRE PARTIE
+[BJM2_11:BANKJ2]
+~r~Phil est mort!
-[FES_SNG]
-NOUVELLE PARTIE
+[BJM2_12:BANKJ2]
+~r~Un des tireurs est mort!
-[FEM_SP]
-MODE SOLO
+[BJM2_14:BANKJ2]
+~g~Continue jusqu'au prochain secteur!
-[FEM_MP]
-MODE MULTIJOUEUR
+[BJM2_17:BANKJ2]
+~g~Va parler à Phil.
-[FEM_QT]
-QUITTER
+[BJM2_24:BANKJ2]
+~g~La cible la plus proche rapporte un point.
-[FES_SG]
-NOUVELLE PARTIE
+[BJM2_25:BANKJ2]
+~g~La cible intermédiaire rapporte deux points.
-[FES_LG]
-CHARGER PARTIE
+[BJM2_27:BANKJ2]
+~g~Toutes les cibles de cette manche rapportent un point.
-[FEM_HST]
-HEBERGER PARTIE
+[BNK2_4:BANKJ2]
+Waou!
-[FEM_OPT]
-OPTIONS
+[BNK2_5:BANKJ2]
+Il raterait une vache dans un couloir!
-[FEM_DBG]
-DEBUG
+[BNK2_7:BANKJ2]
+Bon, tu veux bien me rendre un service et m'assister sur un boulot?
-[FET_PSU]
-PARAMETRES JOUEUR
+[BNK2_8:BANKJ2]
+Mon gars, vu comment tu tires, si tu me demandes en mariage, j'accepte.
-[FET_DEF]
-PAR DEFAUT
+[BNK2_9A:BANKJ2]
+Mon gars, tu ferais mieux de remballer ton baratin et tes grands projets. T'es trop mauvais tireur.
-[FED_BRI]
-LUMINOSITE
+[BNK2_9B:BANKJ2]
+T'es trop mauvais tireur.
-[FED_TRA]
-TRAINEES
+[BJM2_28:BANKJ2]
+SCORE MANCHE TROIS : ~1~
-[FEM_LOD]
-DISTANCE MODELES
+[BJM2_26:BANKJ2]
+~g~La cible éloignée rapporte trois points.
-[FEM_VSC]
-SYNCHRO VIDEO
+[BNK2_1:BANKJ2]
+BALLES REELLES
-[FEM_FRM]
-RESTRICTION VIDEO
+[RANGE_1:BANKJ2]
+SCORE POUR LE TIR : ~1~
-[FED_RES]
-RESOLUTION ECRAN
+[BJM2_2:BANKJ2]
+~g~Pour quitter la manche, appuie sur la ~h~~k~~PED_JUMPING~.
-[FED_WIS]
-PLEIN ECRAN
+[BJM2_N:BANKJ2]
+Du calme...
-[FEDS_TB]
-RETOUR
+{=================================== MISSION TABLE BANKJ3 ===================================}
-[FEA_MUS]
-MUSIQUE
+[BJM3_A:BANKJ3]
+Les choses commencent à se mettre tranquillement en place, ici.
-[FEA_SFX]
-EFFETS SPECIAUX
+[BJM3_B:BANKJ3]
+C'est quoi le plan, Tommy? Que pasa, amigo?
-[FEA_RSS]
-STATION RADIO
+[BJM3_C:BANKJ3]
+Le plan, c'est que toi, tu restes ici à glander. Bon, on a besoin d'un chauffeur.
-[FEL_ENG]
-ANGLAIS
+[BJM3_D:BANKJ3]
+Tommy, je m'en charge! Je peux conduire.
-[FEL_FRE]
-FRANCAIS
+[BJM3_E:BANKJ3]
+C'est Hilary que tu veux, mec! Pas un stupide vantard d'école de droit.
-[FEL_GER]
-ALLEMAND
+[BJM3_F:BANKJ3]
+Hilary, c'est le meilleur. T'as jamais vu quelqu'un conduire aussi vite. Je vais l'appeler.
-[FEL_ITA]
-ITALIEN
+[BJM3_G:BANKJ3]
+Salut, Hil, c'est Phil. Comment ça va? Non, attends, on causera plus tard, j'ai besoin que tu me rendes un service.
-[FEL_SPA]
-ESPAGNOL
+[BJM3_H:BANKJ3]
+J'ai avec moi un mec du nord. Non, je crois pas qu'il était dans l'armée, mais il a besoin d'un conducteur.
-[FEA_3DH]
-CONFIG. CARTE-SON
+[BJM3_I:BANKJ3]
+Pour un peu d'adrénaline. Ok, compris.
-[FEA_SPK]
-CONFIG. HAUT-PARLEURS
+[BJM3_J:BANKJ3]
+Qu'est-ce qu'il a dit?
-[FEA_2SP]
-2 HAUT-PARLEURS
+[BJM3_K:BANKJ3]
+Bon, il marche, pas de problème. En fait, y'a juste un détail, tu vois, il pose toujours une condition.
-[FEA_4SP]
-PLUS DE 2 HAUT-PARLEURS
+[BJM3_L:BANKJ3]
+Il refuse de bosser pour quelqu'un qui ne peut pas le battre. Un truc à cause de sa mère.
-[FEA_EAR]
-CASQUE
+[BJM3_M:BANKJ3]
+Quoi qu'il en soit, il veut t'affronter d'abord et il a dit qu'il te retrouvait dehors...
-[FEA_NAH]
-PAS DE CARTE-SON
+[BJM3_2A:BANKJ3]
+C'est toi Tommy? Evidemment que c'est toi Tommy, enfin, je veux dire,
-[FET_SNG]
-NOUVELLE PARTIE
+[BJM3_2B:BANKJ3]
+pourquoi est-ce que quelqu'un d'autre parlerait avec moi?
-[FEN_STA]
-COMMENCER PARTIE
+[BJM3_2C:BANKJ3]
+Bon. Ecoute-moi.
-[GMLOAD]
-CHARGER PARTIE
+[BJM3_2D:BANKJ3]
+Je conduis pour toi que SI, et seulement SI, tu peux conduire convenablement.
-[GMSAVE]
-SAUVEGARDER PARTIE
+[BJM3_2E:BANKJ3]
+Abandonne et je ne te pardonnerai jamais.
-[FES_DGA]
-EFFACER PARTIE
+[BJM3_2:BANKJ3]
+~r~Hilary est mort!
-[FEM_NON]
-AUCUN
+[BJM3_4:BANKJ3]
+~g~T'as besoin d'une voiture!
-[FEC_IVV]
-INVERSER SOURIS VERTIC.
+[BNK3_1:BANKJ3]
+Ok, je piloterai pour toi, mais s'il te plaît, traite-moi mal.
-[FEC_MSH]
-SENSIBILITE SOURIS
+[BNK3_3A:BANKJ3]
+Course de rue illégale dans Vice Point!
-[FET_CCN]
-COMMANDES : NORMALES
+[BNK3_3B:BANKJ3]
+Appel à tous les officiers.
-[FET_SCN]
-COMMANDES : STANDARD
+[BNK3_3C:BANKJ3]
+Les courses de rue sont formellement interdites!
-[FES_SET]
-UTILISER MODELE
+{=================================== MISSION TABLE BANKJ4 ===================================}
-[GHOST]
-Fantôme
+[BNK4_A:BANKJ4]
+~w~Comme vous pouvez voir, les mecs, ça va être le fric le plus facile qu'on se soit jamais fait!
-[WIN_RSZ]
-Impossible de choisir la nouvelle résolution.
+[BNK4_B:BANKJ4]
+~w~Tommy, sérieusement, va falloir que tu considères la question judiciaire.
-[FET_APP]
-BGS, RETOUR POUR APPLIQUER LE NOUV. PARAMETRE
+[BNK4_C:BANKJ4]
+~w~Merde! Qu'est-ce que tu fumes, mon pote? J'appelle pas ça un plan!
-[FET_HRD]
-PARAMETRES PAR DEFAUT RETABLIS
+[BNK4_D:BANKJ4]
+~w~Bon, de toute manière, on a pas besoin de plan!
-[FET_MST]
-DIRECTION CONTROLEE PAR LA SOURIS
+[BNK4_E:BANKJ4]
+~w~Prenez le communisme, ça c'était un plan! Et regarde où en est la Russie, maintenant!
-[FEC_STR]
-ETOILE PAV.NUM.
+[BNK4_F:BANKJ4]
+~w~Du calme, Ok? Avec une équipe comme ça, il n'y aura pas le moindre problème!
-[FET_MIG]
-GAUCHE, DROITE, MOLETTE SOURIS POUR REGLER
+[BNK4_G:BANKJ4]
+~w~On amène Cam au coffre. Phil, toi et moi, on s'occupe de la sécurité et Hilary conduit la bagnole.
-[FET_CIG]
-RETOUR ARRIERE POUR EFFACER - BGS, RETOUR POUR CHANGER
+[BNK4_H:BANKJ4]
+~w~Hum, euh, t'oublies pas quelqu'un? Quelqu'un qui t'aurait aidé depuis le début dans cette ville? Quelqu'un...
-[FET_RIG]
-SELECTIONNEZ NOUV. TOUCHE POUR CETTE ACTION OU ECHAP POUR ANNULER
+[BNK4_I:BANKJ4]
+~w~Ken... Ken, c'est vrai. Bon, Ken va s'occuper de blanchir le pognon et de garder les boissons au frais!
-[FET_EIG]
-IMPOSSIBLE DE PARAMETRER UNE TOUCHE POUR CETTE ACTION
+[BNK4_J:BANKJ4]
+~w~Je comprends pas ce que je suis supposé faire ici.
-[NO_PCCD]
-Insérez le disque 2 de Grand Theft Auto III dans le lecteur ou appuyez sur ECHAP pour annuler.
+[BNK4_K:BANKJ4]
+~w~Ecoute, c'est dans la poche. T'as jamais vu de film?
-[CVT_ERR]
-Espace disque épuisé. Libérez de la mémoire sur votre disque dur pour continuer. Appuyez sur ECHAP pour annuler.
+[BNK4_L:BANKJ4]
+~w~On entre dans la banque, on sort nos flingues et on ressort plein aux as!
-[FED_SUB]
-SOUS-TITRES
+[P_DEAD:BANKJ4]
+~r~Phil est mort!
-[FET_DSN]
-Skin joueur par défaut.bmp
+[C_DEAD:BANKJ4]
+~r~Cam est mort!
-[JM3]
-'HAUT LES MAINS'
+[H_DEAD:BANKJ4]
+~r~Hilary est mort!
-[EBAL]
-'A MOI LIBERTY'
+[P_HIND:BANKJ4]
+~r~T'as perdu Phil!
-[LM4]
-'MAQUEREAU EN BOITE'
+[C_HIND:BANKJ4]
+~r~T'as oublié Cam!
-[REPLAY]
-RALENTI
+[H_HIND:BANKJ4]
+~r~Hilary est resté derrière!
-[FEC_SFT]
-MAJ
+[GETCAR:BANKJ4]
+~g~Monte dans la bagnole pour terminer le boulot!
-[CRED254]
-RESPONSABLE STUDIO
+[TRASHED:BANKJ4]
+~r~T'as détruit la bagnole pour s'enfuir!
-[CVT_CRT]
-Pour convertir les textures pour votre carte graphique, connectez-vous à un compte Administrateur. Pour quitter, appuyez sur ECHAP.
+[BNK4_1:BANKJ4]
+Je vais conduire.
-[FEM_ON]
-AVEC
+[BNK4_2:BANKJ4]
+Super. Un passager. Attends que j'en parle à la réunion!
-[FEM_OFF]
-SANS
+[BNK4_3A:BANKJ4]
+Hé, fais gaffe à la caisse, Tommy!
-[FEM_YES]
-OUI
+[BNK4_3B:BANKJ4]
+Tommy, Hilary prend trop de place!
-[FEM_NO]
-NON
+[BNK4_3C:BANKJ4]
+C'est pas vrai!
-[FES_WAR]
-Sauvegarde en cours...
+[BNK4_3D:BANKJ4]
+Toi aussi!
-[FED_DLW]
-Suppression en cours...
+[BNK4_3E:BANKJ4]
+Hé, fermez-la tous les deux ou vous rentrez à pied!
-[FED_LDW]
-Chargement en cours...
+[BNK4_3F:BANKJ4]
+Ouais, Hilary.
-[FEC_SLC]
-Emplacement corrompu
+[BNK4_3I:BANKJ4]
+Putain, Phil! Arrête d'agiter ce truc devant moi!
-[FED_LFL]
-Echec du chargement de la sauvegarde. La partie va être relancée.
+[BNK4_3J:BANKJ4]
+Ouais, tu vas éborgner quelqu'un!
-[FET_RSO]
-PARAMETRE D'ORIGINE RETABLI
+[BNK4_3M:BANKJ4]
+Mon bébé! Elle est foutue!
-[FET_RSC]
-MATERIEL INDISPONIBLE - PARAMETRE D'ORIGINE RETABLI
+[BNK4_3O:BANKJ4]
+Tu t'accroches à l'illusion de la permanence!
-[CRED270]
-MIKE HONG
+[BNK4_3P:BANKJ4]
+Quoi?!
+
+[BNK4_3Q:BANKJ4]
+Tu crois que toutes les choses dureront!
+
+[BNK4_3R:BANKJ4]
+La jeunesse, les amours, les pizzas...
+
+[BNK4_3S:BANKJ4]
+Tout prend fin un jour, et tu dois l'accepter.
+
+[BNK4_3T:BANKJ4]
+Ouais, t'as raison, merci, Cam.
+
+[BNK4_3U:BANKJ4]
+De rien.
+
+[BNK4_3V:BANKJ4]
+Hé, Tommy, pourquoi on s'arrête?
+
+[BNK4_4A:BANKJ4]
+~w~Hilary, continue à tourner autour du quartier.
+
+[BNK4_5:BANKJ4]
+~w~Ok, Tommy, ok.
+
+[BNK4_6:BANKJ4]
+~w~C'EST UN HOLD-UP!
+
+[BNK4_7:BANKJ4]
+~w~PERSONNE NE BOUGE!
+
+[BNK4_8:BANKJ4]
+~w~TOUT LE MONDE CONTRE LE MUR!
+
+[BNK4_9:BANKJ4]
+Phil! Monte la garde!
+
+[BNK4_10:BANKJ4]
+Bien compris!
+
+[BNK4_11:BANKJ4]
+Amène-toi, Cam, la salle des coffres est en haut...
+
+[BK4_12A:BANKJ4]
+Merde! C'est un Flange 9000!
+
+[BK4_12B:BANKJ4]
+Ca peut prendre des heures à ouvrir,
+
+[BK4_12C:BANKJ4]
+ou cinq minutes si tu peux trouver le directeur...
+
+[BNK4_13:BANKJ4]
+Je vais aller voir où il se planque.
+
+[BK4_14A:BANKJ4]
+Ca roule, Phil?
+
+[BNK4_15:BANKJ4]
+Pas de problème. Tout le monde se tient relax.
+
+[BNK4_16:BANKJ4]
+Toi! Tu viens avec moi!
+
+[BNK4_17:BANKJ4]
+D'accord! D'accord! Ne tirez pas!
+
+[BNK4_18:BANKJ4]
+J'AI DIT PERSONNE NE BOUGE!
+
+[BK4_19A:BANKJ4]
+C'est réglé sur une serrure à horloge,
+
+[BK4_19B:BANKJ4]
+Vous feriez aussi bien d'abandonner tout de suite!
+
+[BK4_20A:BANKJ4]
+Putain, je peux court-circuiter l'horloge,
+
+[BK4_20B:BANKJ4]
+on a juste besoin de ton code secret et c'est bingo!
+
+[BNK4_21:BANKJ4]
+Reste ici. T'essayes quoi que ce soit et t'es mort! Pigé?
+
+[BK4_24A:BANKJ4]
+Je vais voir Phil, je reviens tout de suite.
+
+[BK4_24B:BANKJ4]
+Je t'avais dit de pas toucher à cette alarme!
+
+[BNK4_25:BANKJ4]
+Le commando du SWAT sera là d'une minute à l'autre!
+
+[BNK4_27:BANKJ4]
+J'aurais besoin d'un coup de main, Tommy!
+
+[BNK4_28:BANKJ4]
+Ici le SWAT de Vice City! Vous êtes complètement encerclés!
+
+[BNK4_29:BANKJ4]
+Encerclés? HA HA HA HAAAAAaaa!
+
+[BNK4_30:BANKJ4]
+Ils racontent que des conneries, ces ripoux!
+
+[BK4_31A:BANKJ4]
+Tommy! La salle des coffres est ouverte!
+
+[BK4_34A:BANKJ4]
+Ok, on a la caisse de retraite du SWAT! Tirons-nous de là!
+
+[BK4_34B:BANKJ4]
+Bon, vous l'aurez cherché! C'était votre dernière chance!
+
+[BK4_35A:BANKJ4]
+Ils lancent l'assaut!
+
+[BK4_35B:BANKJ4]
+Planquez-vous!
+
+[BNK4_36:BANKJ4]
+Où est Cam?
+
+[BNK4_37:BANKJ4]
+Du passé...
+
+[BNK4_38:BANKJ4]
+C'était le dernier! On dégage! Allez!
+
+[BNK_39:BANKJ4]
+Merde! Où est Hilary?
+
+[BK4_40A:BANKJ4]
+Il me payera ça!
+
+[BNK4_42:BANKJ4]
+Hé! Les mecs! Montez! Je vous couvre!
+
+[BNK4_44:BANKJ4]
+On a réussi! On est riches! RICHES!
+
+[BNK4_45:BANKJ4]
+Dommage que Cam y soit resté, c'était un mec réglo!
+
+[BNK4_46:BANKJ4]
+Ouais. Enfin... On hérite de sa part!
+
+[BNK4_47:BANKJ4]
+Tu l'as dit! Ouais!
+
+[BNK4_48:BANKJ4]
+Tommy, que dirais-tu d'un massage?
+
+[BNK4_49:BANKJ4]
+Salut, Mercedes! Ouais, pourquoi pas, je me sens un peu tendu...
+
+[BNK450A:BANKJ4]
+Qu'est-ce que je te disais, Tommy? Hein, quoi? Le SWAT a du souci à se faire quand Kent Paul est en ville.
+
+[BNK450B:BANKJ4]
+Allez, allonge une plus grosse part, mon pote, j'ai besoin de nouvelles fringues!
+
+[BNK4_94:BANKJ4]
+~w~Ok, les mecs. Tout roule comme prévu.
+
+[BM_DEAD:BANKJ4]
+~r~T'avais besoin du directeur vivant!
+
+[ASSET_A:BANKJ4]
+BRAQUAGE DE BANQUE OK!
+
+[ASSET_B:BANKJ4]
+~g~Le Malibu Club génère dorénavant un revenu de $~1~ maximum. Pense à récupérer le fric régulièrement.
+
+[IDIOT:BANKJ4]
+~r~T'as raison, trimballe-toi déguisé en malade pour attirer l'attention! Espèce d'abruti!
+
+{=================================== MISSION TABLE BARON1 ===================================}
+
+[COK1_A:BARON1]
+Allez, sale carne, allez! Allez! Putain...
+
+[COK1_B:BARON1]
+Connard de cheval! Je te ferai décapiter!
+
+[COK1_C:BARON1]
+C'est qui ce con?
+
+[COK1_D:BARON1]
+Tommy Vercetti, vous vous souvenez de moi?
+
+[COK1_E:BARON1]
+Excuse-moi, mais j'suis un peu enervé. Fais jamais confiance à une saloperie de canasson!
+
+[COK1_F:BARON1]
+Tu fais du bon boulot. Maintenant, tu travailles pour moi.
+
+[COK1_H:BARON1]
+Comme je disais, amigo, tu bosses pour moi. Maintenant, la ferme! Un salopard m'a trahi!
+
+[COK1_I:BARON1]
+Il croit que je sais pas combien de pognon je devrais gagner... Mais me faucher 3%, c'est pareil que d'me faucher 100%!
+
+[COK1_J:BARON1]
+Personne ne me fait ça! PERSONNE!
+
+[COK1_K:BARON1]
+Tu vas le suivre depuis son appart' pour voir où il va! On le descendra plus tard.
+
+[COK1_1:BARON1]
+Oh merde!
+
+[COK1_2:BARON1]
+Un peu trop lent, papi!
+
+[COK1_4:BARON1]
+Pauv' mec.
+
+[COK1_5:BARON1]
+Tu ferais mieux de continuer à courir, connard!
+
+[COK1_8:BARON1]
+~g~Vite! Grimpe dans une caisse et suis-le!
+
+[COK1_9:BARON1]
+~r~Tu es supposé le suivre, pas le buter!
+
+[COK1_10:BARON1]
+~r~Va à la maison des voleurs et trouve où il planque le fric!
+
+[COK1_11:BARON1]
+~g~Regarde par cette fenêtre.
+
+[COK1_7:BARON1]
+~g~Il s'est échappé vers le toit. Suis-le mais ne le tue pas!
+
+[COK1_G:BARON1]
+Je travaille pour du fric.
+
+{=================================== MISSION TABLE BARON2 ===================================}
+
+[COK2_V:BARON2]
+Il commence à me faire confiance...
+
+[COK2_A:BARON2]
+Qui c'est qui m'a foutu un con pareil!
+
+[COK2_B:BARON2]
+CON! CON! CON! CON!
+
+[COK2_C:BARON2]
+Tommy -
+
+[COK2_D:BARON2]
+Quoi, Ricardo?
+
+[COK2_E:BARON2]
+Ces merdeux, faut toujours qu'ils essayent de m'baiser...
+
+[COK2_F:BARON2]
+C'est le problème avec ce genre de biz...
+
+[COK2_G:BARON2]
+Qu'est-ce que tu fous toi?
+
+[COK2_H:BARON2]
+Ces connards m'ont vraiment manqué de respect.
+
+[COK2_I:BARON2]
+Bientôt, le premier connard venu va penser qu'il peut vendre de la dope à Vice City.
+
+[COK2_J:BARON2]
+Et ensuite, ça sera quoi? Ces pourris de la Mafia, hein?
+
+[COK2_K:BARON2]
+Le Q.G. de ce gang est une vrai forteresse au rez-de-chaussée,
+
+[COK2_L:BARON2]
+alors Quentin ici... Quentin! QUENTIN!
+
+[COK2_M:BARON2]
+Il va te faire survoler la zone!
+
+[COK2_N:BARON2]
+Liquide-les!
+
+[COK2_O:BARON2]
+Qu'est-ce que tu fous toi?
+
+[COK2_P:BARON2]
+Qu'est-ce que tu fous ici?
+
+[COK2_Q:BARON2]
+Hé, je me suis un peu renseigné et c'est sûr
+
+[COK2_R:BARON2]
+que c'est Diaz qui a bousillé le deal et refroidi mon frère!
+
+[COK2_S:BARON2]
+Et il va t'buter toi aussi!
+
+[COK2_T:BARON2]
+Je peux me faire Diaz!
+
+[COK2_U:BARON2]
+Non, écoute-moi! JE m'occupe de Diaz!
+
+[COK2_1:BARON2]
+Il y a un truc que j'pige pas, pourquoi 'Quentin'?
+
+[COK2_2:BARON2]
+Je sais pas, ça sonne bien... Quentin Vance...
+
+[COK2_3:BARON2]
+Vance? Tu t'appelles Lance Vance?
+
+[COK2_4:BARON2]
+Ca va, hein! J'en ai déjà eu pour mon compte à l'école!
+
+[COK2_5:BARON2]
+T'as déjà tiré depuis un hélico?
+
+[COK2_8:BARON2]
+On va où, au fait?
+
+[COK2_9:BARON2]
+Prawn Island.
+
+[COK2_13:BARON2]
+Lance Vance. Mon pauv' vieux...
+
+[COK2_14:BARON2]
+Ok, on y est presque.
+
+[COK2_15:BARON2]
+On va faire un ou deux passages,
+
+[COK2_16:BARON2]
+Alors, descends autant de tireurs que tu peux.
+
+[COK2_17:BARON2]
+Et puis je te dépose et tu te débrouilles tout seul.
+
+[COK2_20:BARON2]
+Merde, c'est la guerre en bas! Descends ces tireurs!
+
+[COK2_21:BARON2]
+On s'fait canarder, mec!
+
+[COK2_22:BARON2]
+Ca coûte un max de réparer c'coucou, alors bute-les!
+
+[COK2_23:BARON2]
+Bon, t'es tout seul à partir de là. Bonne chance, mon frère!
+
+[COK2_24:BARON2]
+Etat hélico :
+
+[COK2_25:BARON2]
+~g~Va récupérer le pognon sur le toit.
+
+[COK2_27:BARON2]
+T'es sur MES plates-bandes, connard!
+
+[COK2_28:BARON2]
+Ta fin est proche!
+
+[COK2_6:BARON2]
+Non. Je vais m'entraîner un peu en chemin.
+
+[OPEN_B:BARON2]
+Les barrières sur les routes pour le centre ville ont été retirées.
+
+{=================================== MISSION TABLE BARON3 ===================================}
+
+[COK3_A:BARON3]
+Tu fais moins le fier maintenant, hein!
+
+[COK3_B:BARON3]
+Ahahahaha, ahahahaha!
+
+[COK3_C:BARON3]
+Ho! Fais gaffe où tu braques ce truc!
+
+[COK3_D:BARON3]
+Plus de merde de pigeon sur ma bagnole, hein, Tommy!
+
+[COK3_E:BARON3]
+Faut croire que non...
+
+[COK3_F:BARON3]
+T'as sacrément raison. Bon, écoute,
+
+[COK3_G:BARON3]
+tu sais qui possède le bateau le plus rapide de la côte est?
+
+[COK3_H:BARON3]
+Je suis pas bien sûr.
+
+[COK3_I:BARON3]
+MOI! Et je voudrais pas que ça change...
+
+[COK3_J:BARON3]
+Tous les contrebandiers d'ici à Caracas ne rêvent que d'un seul truc, un bateau plus rapide que le mien.
+
+[COK3_K:BARON3]
+Et la rumeur prétend que le chantier naval Hull-o-caust vient juste d'en finir un
+
+[COK3_L:BARON3]
+pour le compte de je ne sais quel connard du Costa Rica.
+
+[COK3_M:BARON3]
+Alors, Tommy... JE VEUX CE BATEAU!
+
+[COK3_N:BARON3]
+Je crois que tes pigeons sont de retour...
+
+[COK3_O:BARON3]
+Ah! Je croyais que je t'avais eu! D'où tu sors?
+
+[COK3_P:BARON3]
+Pigeons d'mes deux! Boum! Aaaaah!
+
+[COK3_5:BARON3]
+~g~Trouve l'interrupteur pour abaisser le bateau.
+
+[COK3_6:BARON3]
+~g~Amène le bateau à la résidence.
+
+[COK3_7:BARON3]
+~r~T'as détruit le bateau!
+
+[COK3_8:BARON3]
+~g~Va au chantier naval des docks et fauche le bateau le plus rapide.
+
+[COK3_9:BARON3]
+~g~Monte dans le bateau.
+
+{=================================== MISSION TABLE BARON4 ===================================}
+
+[COK4_A:BARON4]
+Ejection! Connerie d'engin!
+
+[COK4_B:BARON4]
+Pourquoi tu m'fais ça?
+
+[COK4_C:BARON4]
+Pour qui tu t'prends, putain de magnéto! Grrr!
+
+[COK4_D:BARON4]
+ENCULE!
+
+[COK4_E:BARON4]
+Si il m'bouffe ma cassette préférée d'El burro, il est fini!
+
+[COK4_F:BARON4]
+Qu'est-ce que je peux faire d'autre?
+
+[COK4_G:BARON4]
+Il doit pas être branché, c'est tout...
+
+[COK4_H:BARON4]
+Hein?
+
+[COK4_I:BARON4]
+Merde! Tant pis, j'peux m'en acheter cent si ça me chante.
+
+[COK4_J:BARON4]
+Bon, Tommy,
+
+[COK4_K:BARON4]
+tous les mois, il y a un indépendant qui met le cap sur Vice City pour y amarrer son yatch.
+
+[COK4_L:BARON4]
+Il vend sa cargaison au premier bateau.
+
+[COK4_M:BARON4]
+Je veux que tu prennes le speedboat,
+
+[COK4_N:BARON4]
+que tu largues tous les autres connards intéressés
+
+[COK4_O:BARON4]
+et que tu ramènes la cargaison ici. Ok?
+
+[COK4_P:BARON4]
+Laisse-moi deviner. T'as pensé que je pourrais avoir besoin d'un ange-gardien.
+
+[COK4_Q:BARON4]
+Je dis juste que t'as intérêt à me laisser entrer, mon pote.
+
+[COK4_R:BARON4]
+Tu peux m'sortir tout un tas de conneries sur le dur solitaire,
+
+[COK4_S:BARON4]
+mais je sais qu'un de ces quatre, j'vais t'sauver la mise.
+
+[COK4_T:BARON4]
+et qu'après tu voudras me rouler une pelle!
+
+[COK4_U:BARON4]
+Taré, va!
+
+[COK4_V:BARON4]
+Hahahaha
+
+[COK4_1:BARON4]
+Tommy, on sait que c'est Diaz qui a fait foirer notre deal...
+
+[COK4_3:BARON4]
+Alors pourquoi on bosse pour sa gueule?
+
+[COK4_4:BARON4]
+Plus on en apprend maintenant, plus on en saura quand on s'emparera de cette ville!
+
+[COK4_5:BARON4]
+J'aime bien ton style, mon pote. Vraiment culotté.
+
+[COK4_12:BARON4]
+Fais gaffe, ils arrivent de partout!
+
+[COK4_13:BARON4]
+On les a eu! Fonce chez Diaz aussi vite que tu peux!
+
+[COK4_14:BARON4]
+Tu veux ta part de plancton?
+
+[COK4_15:BARON4]
+Salue la poiscaille de ma part!
+
+[COK4_16:BARON4]
+Mange! Mange!
+
+[COK4_19:BARON4]
+Encore des emmerdes droit devant!
+
+[COK4_20:BARON4]
+Il y a des porte-flingues sur cette jetée!
+
+[COK4_24:BARON4]
+Joli coup, mon pote. T'es vraiment un cinglé de première!
+
+[COK4_25:BARON4]
+Ah... Merci.
+
+[COK4_26:BARON4]
+A la prochaine, Tommy.
+
+[COK4_27:BARON4]
+Okay, M. Lance Vance Danse.
+
+[COK4_28:BARON4]
+~g~Atteins le yatch avant les autres bateaux!
+
+[COK4_31:BARON4]
+~g~Va jusqu'au bateau le plus rapide de la jetée!
+
+[COK4_32:BARON4]
+~r~Trop lent!
+
+[COK4_33:BARON4]
+~r~T'as détruit le bateau!
+
+[COK4_34:BARON4]
+~g~Bousille ces bateaux!
+
+[COK4_35:BARON4]
+Etat du bateau :
+
+{=================================== MISSION TABLE BARON5 ===================================}
+
+[PROP_A:BARON5]
+PROPRIETE ACHETEE!
+
+[COK4_30:BARON5]
+~r~Lance est mort!
+
+[ASS1_A:BARON5]
+J'ai récupéré des flingues. Ils sont dans l'coffre.
+
+[ASS1_B:BARON5]
+Merde alors! Où c'est que t'as dégoté tout ça?
+
+[ASS1_C:BARON5]
+Je l'gardais au frais pour une grande occasion...
+
+[ASS1_D:BARON5]
+Ca te botte?
+
+[ASS1_E:BARON5]
+Tu parles que ça m'botte.
+
+[ASS1_F:BARON5]
+Espèce de connard...
+
+[ASS1_G:BARON5]
+Ma belle maison...
+
+[ASS1_H:BARON5]
+Regarde ce que t'en as fait!
+
+[ASS1_I:BARON5]
+Ca c'est pour mon frère!
+
+[ASS1_J:BARON5]
+Je te faisais confiance, Tommy...
+
+[ASS1_K:BARON5]
+Je t'aurais aidé à devenir...
+
+[ASS1_L:BARON5]
+Bonne nuit, Diaz.
+
+[ASS1_1:BARON5]
+Cet endroit va bientôt grouiller de salopards... Fais gaffe.
+
+[ASS1_2:BARON5]
+T'en fais pas, Tommy, je te couvre.
+
+[ASS1_4:BARON5]
+Diaz doit être à l'intérieur!
+
+[ASS1_13:BARON5]
+DIAZ! Je suis venu reprendre ton affaire!
+
+[ASS1_14:BARON5]
+TOMMY! Tu me trahis... Idiot! Je vais te buter tout de suite!
+
+[ASS1_16:BARON5]
+~g~Tue Diaz!
+
+[BUD1:BARON5]
+Lance
+
+[ASS1_18:BARON5]
+~g~La porte est verrouillée. Trouve un autre chemin.
+
+[ASS1_19:BARON5]
+Par ici!
+
+[ASS1_20:BARON5]
+Tommy, mon problème c'est Quentin, pas toi, mec!
+
+{=================================== MISSION TABLE BIKE1 ===================================}
+
+[BM1_A:BIKE1]
+Où est Baker?
+
+[BM1_B:BIKE1]
+Je cherche Big Mitch Baker...
+
+[BM1_C:BIKE1]
+Qui le cherche?
+
+[BM1_D:BIKE1]
+Tommy Vercetti.
+
+[BM1_E:BIKE1]
+Vercetti...
+
+[BM1_F:BIKE1]
+T'as pas l'air d'un flic, ce qui te donne droit à une minute...
+
+[BM1_G:BIKE1]
+T'as intérêt à faire court!
+
+[BM1_H:BIKE1]
+Kent Paul dit que ça pourrait t'intéresser de te charger de la sécurité pour un boulot qu'il prépare.
+
+[BM1_I:BIKE1]
+Kent Paul? Ah! Pas étonnant qu'il t'ai envoyé.
+
+[BM1_J:BIKE1]
+La dernière fois qu'il est passé ici, il en est ressorti par la fenêtre avec rien d'autre que son costume d'anglais.
+
+[BM1_K:BIKE1]
+Bon, t'es intéressé ou pas?
+
+[BM1_L:BIKE1]
+On ne rend des services qu'à ceux qui font partie de la bande.
+
+[BM1_M:BIKE1]
+Comment je me joins à vous?
+
+[BM1_N:BIKE1]
+On est pas un club de loisirs, mon pote! Tu peux conduire une bécane?
+
+[BM1_O:BIKE1]
+Tu peux t'asseoir sur un tabouret de bar et boire?
+
+[BM1_P:BIKE1]
+Cougar, Zeppelin, allez voir comment elle se débrouille sur une bécane...
+
+[BM1_2:BIKE1]
+~g~Il te faut une Freeway ou une Angel pour participer!
+
+[BM1_3:BIKE1]
+~r~Les concurrents ont été attaqués!
+
+[BIKE1_1:BIKE1]
+Bon, chouettes fringues. Voyons ce que tu peux faire.
+
+[BM1_1:BIKE1]
+~g~Enfourche une Freeway ou une Angel et va sur la grille de départ.
+
+{=================================== MISSION TABLE BIKE2 ===================================}
+
+[BM2_4:BIKE2]
+~r~Tu n'as pas rempli le chaosmètre à temps!
+
+[BM2_1:BIKE2]
+CHAOSMETRE :
+
+[BM2_A:BIKE2]
+Ha ha ha, je t'ai encore eu!
+
+[BM2_B:BIKE2]
+Hé, Vercetti.
+
+[BM2_C:BIKE2]
+Cougar dit que tu te débrouilles plutôt bien sur une bécane.
+
+[BM2_D:BIKE2]
+Ouais, mais combien d'épreuves il va encore falloir que je me tape?
+
+[BM2_E:BIKE2]
+Je suis très occupé, mon pote.
+
+[BM2_F:BIKE2]
+Si c'est une baston qui peut régler la question, alors amène-toi!
+
+[BM2_G:BIKE2]
+Devenir l'un d'entre nous, c'est pas qu'une question de baston. C'est appartenir à une famille.
+
+[BM2_H:BIKE2]
+Ouais, j'ai déjà appartenu à une famille avant et ça n'a pas bien collé.
+
+[BM2_I:BIKE2]
+Peut-être, mais notre famille veille sur les siens.
+
+[BM2_J:BIKE2]
+On demande à personne de faire le sale boulot pour l'abandonner au trou pendant quinze ans...
+
+[BM2_K:BIKE2]
+Et ouais, je me suis renseigné.
+
+[BM2_L:BIKE2]
+Ce que tu vois, c'est la plus grande famille d'inadaptés, de parias et d'ordures qui existe.
+
+[BM2_M:BIKE2]
+Certains ont même été trahis par leur propre pays!
+
+[BM2_N:BIKE2]
+On m'a foutu en taule pendant la guerre du Vietnam! Saloperie...
+
+[BM2_O:BIKE2]
+Voilà pourquoi je vais te demander d'aller foutre le bordel.
+
+[BM2_P:BIKE2]
+Ce pays de merde a vraiment besoin d'un coup de pied au cul et c'est nous qui allons le lui donner!
+
+[BM2_Q:BIKE2]
+Alors sors de là, attrape une bécane et montre à cette ville à quel point t'es énervé!
+
+[BM2_R:BIKE2]
+D'accord.
+
+[BM2_2:BIKE2]
+~g~Tu dois remplir le chaosmètre dans le temps imparti pour nous prouver que t'es un dur de dur!
+
+[BM2_3:BIKE2]
+~g~Ce bruit veut dire qu'une partie du chaosmètre est remplie, continue comme ça.
+
+{=================================== MISSION TABLE BIKE3 ===================================}
+
+[BM3_A:BIKE3]
+Salut, Mitch.
+
+[BM3_B:BIKE3]
+Hé! Mais c'est ce gros méchant de Vercetti!
+
+[BM3_C:BIKE3]
+Maintenant, je veux voir à quel point tu peux te battre pour ton secteur.
+
+[BM3_D:BIKE3]
+Un gang local a commis l'erreur de me faucher ma bécane...
+
+[BM3_E:BIKE3]
+Probablement un truc de machos ou quelque chose de ce genre.
+
+[BM3_F:BIKE3]
+Moi et mes gars, on pourrait aller leur donner la leçon qu'ils méritent...
+
+[BM3_G:BIKE3]
+Enfin...
+
+[BM3_H:BIKE3]
+Je me suis dit que ça serait une excellente initiation pour toi.
+
+[BM3_I:BIKE3]
+Tu me ramènes ma bécane et tu pourras dire à Paul qu'on assurera la sécurité.
+
+[BM3_2:BIKE3]
+~r~Tu étais supposé ramener la bécane, pas la bousiller!
+
+[BM3_3:BIKE3]
+~g~Ramène la bécane au bar!
+
+[BM3_4:BIKE3]
+~g~Monte sur la bécane!
+
+[INTRUDE:BIKE3]
+~g~T'as été repéré!
+
+[BM3_6:BIKE3]
+~g~Ils se planquent derrière Ammu-Nation dans le centre.
+
+[BM3_7:BIKE3]
+~g~T'auras besoin d'une bécane rapide pour accéder au toit.
+
+[BM3_8:BIKE3]
+~g~Sers-toi de la bécane pour sauter de ces marches jusqu'à l'autre côté de la route.
+
+[BM3_1:BIKE3]
+~g~Un gang local a volé l'Angel de Mitch Baker. Récupère-la!
+
+[BM3_9:BIKE3]
+~g~Récupère l'Angel de Mitch Baker et dégage de là!
+
+{=================================== MISSION TABLE BMX_1 ===================================}
+
+[BMX_REC:BMX_1]
+~g~Nouveau record établi : ~1~!
+
+[GETBIK2:BMX_1]
+Tu as ~1~ secondes pour enfourcher une bécane!
+
+{=================================== MISSION TABLE BOATBUY ===================================}
+
+[DRUG_1:BOATBUY]
+Bonjour? Y'a quelqu'un? Y'A QUELQU'UN???
+
+[DRUG_2:BOATBUY]
+Ferme-la. Il y a un mec, ici.
+
+[DRUG_3:BOATBUY]
+Hé, mon pote! T'es le nouveau proprio?
+
+[DRUG_4:BOATBUY]
+Ouais. Lequel de ces bateaux est le plus rapide?
+
+[DRUG_5:BOATBUY]
+Il est déjà à l'eau, mon pote,
+
+[DRUG_6:BOATBUY]
+je me suis dit que tu voudrais peut-être l'essayer.
+
+[DRUG_7:BOATBUY]
+Mon pote, il est déjà équipé d'un moteur de 300 chevaux...
+
+[DRUG_8:BOATBUY]
+...et avec la coque en fibre de verre, il touche même pas l'eau!
+
+[DRUG_9:BOATBUY]
+Il monte à 60 noeuds en quatre secondes, mon pote...
+
+[DRUG_10:BOATBUY]
+Et il peut embarquer vingt écopes de la meilleure jamaïquaine dans la coque.
+
+[DRUG_11:BOATBUY]
+Alors vas-y, mon pote, il t'attend pour décoler!
+
+[DRUG_12:BOATBUY]
+Ouais, hé, mon pote, t'as du feu?
+
+[DRUG_13:BOATBUY]
+Mec?
+
+{=================================== MISSION TABLE CAP_1 ===================================}
+
+[CAP1_B1:CAP_1]
+~g~La mafia taxe tes commerces. Trouve-les et bute-les.
+
+[CAP1_B2:CAP_1]
+~g~La mafia taxe le chantier naval!
+
+[CAP1_B3:CAP_1]
+~g~La mafia taxe l'usine de crème glacée!
+
+[CAP1_B4:CAP_1]
+~g~La mafia taxe la concession automobile!
+
+[CAP1_B5:CAP_1]
+~g~La mafia taxe la compagnie de taxis!
+
+[CAP_01:CAP_1]
+Ok, où est l'urgence?
+
+[CAP_02:CAP_1]
+QUI?
+
+[CAP_03:CAP_1]
+Tommy... Des truands de la mafia... Ils ont dit qu'ils venaient prendre leur part...
+
+[CAP_04:CAP_1]
+... Ils ont dit que c'était le pognon de Mr Forello... J'me sens mal...
+
+[CAP_05:CAP_1]
+Forelli? SONNY Forelli?
+
+[CAP_06:CAP_1]
+Ouais, c'est ça... je crois... Ils ont beaucoup insisté...
+
+[CAP_07:CAP_1]
+T'inquiète pas, je suis pas en colère contre toi.
+
+[CAP_08:CAP_1]
+Emmène-le à l'hosto.
+
+[CAP_09:CAP_1]
+Tommy... Taille un nouveau trou du cul à ce salopard de ma part...
+
+[CAP_10:CAP_1]
+Je vais lui en rajouter deux!
+
+[CAP1_2:CAP_1]
+Tu connais la règle, Vercetti!
+
+[CAP1_3:CAP_1]
+Avec les compliments de M. Forelli!
+
+[CAP1_4:CAP_1]
+C'est le boucher d'Harwood!
+
+[CAP1_5:CAP_1]
+Tu diras à Sonny... de dégager!
+
+[CAP1_6:CAP_1]
+Vice City est à moi, désormais, pas à lui!
+
+[CAP1_7:CAP_1]
+Tu crois que tu peux m'avoir, Vercetti?
+
+[CAP1_8:CAP_1]
+On va continuer à s'amener jusqu'à ce que tu sois raide mort, Vercetti!
+
+[CAP1_9:CAP_1]
+T'as pas une chance, connard psychotique!
+
+[CAP1_10:CAP_1]
+Je vais te descendre, Vercetti!
+
+[CAP1_11:CAP_1]
+T'as toujours été un con!
+
+[CAP1_12:CAP_1]
+Tu vas crever, Vercetti!
+
+[CAP1_B6:CAP_1]
+~g~Tu as trouvé l'encaisseur. Tue-le.
+
+[CAP1_B7:CAP_1]
+~g~Tu as perdu l'encaisseur.
+
+[CAP1_B8:CAP_1]
+~r~L'encaisseur a taxé toutes tes affaires.
+
+[CAP1_B9:CAP_1]
+~g~La mafia a taxé le Malibu!
+
+[CAP1_B0:CAP_1]
+~g~La mafia a taxé le studio de cinéma!
+
+[CAP1_C2:CAP_1]
+~g~La mafia est arrivée au chantier naval!
+
+[CAP1_C3:CAP_1]
+~g~La mafia est arrivée à l'usine de crème glacée!
+
+[CAP1_C4:CAP_1]
+~g~La mafia est arrivée à la concession automobile!
+
+[CAP1_C5:CAP_1]
+~g~La mafia est arrivée à la compagnie de taxis!
+
+[CAP1_C9:CAP_1]
+~g~La mafia est arrivée au Malibu!
+
+[CAP1_C0:CAP_1]
+~g~La mafia est arrivée au studio de cinéma!
+
+[CAP1_D2:CAP_1]
+~g~La mafia quitte le chantier naval!
+
+[CAP1_D3:CAP_1]
+~g~La mafia quitte l'usine de crème glacée!
+
+[CAP1_D4:CAP_1]
+~g~La mafia quitte la concession automobile!
+
+[CAP1_D5:CAP_1]
+~g~La mafia quitte la compagnie de taxis!
+
+[CAP1_D9:CAP_1]
+~g~La mafia quitte le Malibu!
+
+[CAP1_D0:CAP_1]
+~g~La mafia quitte le studio de cinéma!
+
+[CAP1B10:CAP_1]
+Tu t'es occupé des taxeurs. Y'en a d'autres qui arrivent.
+
+{=================================== MISSION TABLE CARBUY ===================================}
+
+[CAR1_1:CARBUY]
+B.J. Smith. Et vous devez être Mr Vercetti.
+
+[CAR1_2:CARBUY]
+Vous voulez visiter?
+
+[CAR1_3:CARBUY]
+Pourquoi pas?
+
+[CAR1_4:CARBUY]
+Vous savez, je suis bien triste de vendre l'affaire...
+
+[CAR1_5:CARBUY]
+C'était mon premier investissement de professionnel.
+
+[CAR1_6:CARBUY]
+Mais l'heure est venue pour moi de continuer ma route.
+
+[CAR1_7:CARBUY]
+Vous quittez la ville?
+
+[CAR1_8:CARBUY]
+Pas trop pressé, j'espère?
+
+[CAR1_9:CARBUY]
+Non, je sors juste de ma retraite et je prépare mon retour dans les affaires.
+
+[CAR1_10:CARBUY]
+Cette affaire était pas trop solide,
+
+[CAR1_11:CARBUY]
+mais mon personnel a pris sur lui de faire un peu plus
+
+[CAR1_12:CARBUY]
+créatif en ce qui concerne les méthodes pour devenir rentable.
+
+[CAR1_13:CARBUY]
+Evidemment, je pourrais démanteler l'affaire avant de la refiler.
+
+[CAR1_14:CARBUY]
+Merde, je pourrais y foutre le feu si ça me chantait.
+
+[CAR1_15:CARBUY]
+C'est un terrain de premier ordre.
+
+[CAR1_16:CARBUY]
+Oh, je ne m'en ferais pas pour ça.
+
+[CAR1_17:CARBUY]
+Cet endroit me semble idéal.
+
+[CAR1_18:CARBUY]
+Ouais, il l'est, alors, marché conclu?
+
+{=================================== MISSION TABLE CARPAR1 ===================================}
+
+[MM_1_A:CARPAR1]
+~g~Récupère ~y~5 points de passage~r~ SANS ~g~renverser de ~r~CONES! ~g~Tu peux les récupérer dans ~y~N'IMPORTE QUEL ORDRE.
+
+[CONE_1:CARPAR1]
+~r~Tu as renversé un cône!
+
+[MM_1_C:CARPAR1]
+~y~FRANCHIS~g~ un point de passage pour enclencher le compteur. ~g~Chaque point de passage te crédite ~y~~1~ SECONDES~g~.
+
+{=================================== MISSION TABLE COPCAR ===================================}
+
+[CLEVEL:COPCAR]
+Missions d'autodéfense niveau ~1~
+
+[C_COMP1:COPCAR]
+Niveau 12 de mission Auto-défense réussi : votre max de gilet pare-balles passe à 150.
+
+[KILLS:COPCAR]
+VICTIMES :
+
+[C_BREIF:COPCAR]
+~g~Suspect aperçu pour la dernière fois dans le secteur ~a~.
+
+[C_PASS:COPCAR]
+MENACE ENRAYEE : $~1~
+
+[COPCART:COPCAR]
+~g~Tu as ~1~ secondes pour retourner à une voiture de police avant que la mission ne s'achève.
+
+[C_CANC:COPCAR]
+~r~Mission d'autodéfense annulée!
+
+[C_TIME:COPCAR]
+~r~Ta carrière de flic est terminée!
+
+{=================================== MISSION TABLE COUNT1 ===================================}
+
+[CM1_A:COUNT1]
+Vercetti? Hé, vous avez acheté la vieille imprimerie?
+
+[CM1_B:COUNT1]
+Ouais, mon vieux a travaillé sur ces machines.
+
+[CM1_C:COUNT1]
+J'aurais voulu marcher sur ses traces, mais... J'ai suivi une autre voie.
+
+[CM1_D:COUNT1]
+Vous avez l'intention de vendre les vieilles machines, et de tout casser?
+
+[CM1_E:COUNT1]
+Je m'disais qu'on pourrait peut-être imprimer quelque chose, un journal ou un magazine...
+
+[CM1_F:COUNT1]
+Arrête tes conneries, fiston! J'ai toujours rêvé d'imprimer mon propre pognon! C'est pas très compliqué!
+
+[CM1_G:COUNT1]
+Tu sais, j'ai fait ça sur une petite échelle pendant des années.
+
+[CM1_H:COUNT1]
+Ah ouais?
+
+[CM1_I:COUNT1]
+Ouais. Mais il nous faut des plaques de bonne qualité.
+
+[CM1_J:COUNT1]
+Evidemment! Il y a un syndicat de contrefaçon qui opère déjà en Floride!
+
+[CM1_K:COUNT1]
+Un syndicat?
+
+[CM1_L:COUNT1]
+Ouais. C'est le bruit qui court en tout cas.
+
+[CM1_M:COUNT1]
+Je connais un mec qui en saura sûrement plus...
+
+[CM1_N:COUNT1]
+On avait l'habitude de passer nos soirées ensemble, à nettoyer les rouleaux...
+
+[CM1_2A:COUNT1]
+Mate-moi ce cul!
+
+[CM1_2B:COUNT1]
+Ok, ma belle, c'est l'heure de l'initiation!
+
+[CM1_2C:COUNT1]
+Salut, vieille branche, comment ça va?
+
+[CM1_2D:COUNT1]
+Que sais-tu à propos de la contrefaçon?
+
+[CM1_2E:COUNT1]
+Oh, je vais bien, Paul, et toi?
+
+[CM1_2F:COUNT1]
+Viens ici!
+
+[CM1_2G:COUNT1]
+Bon! Bon! Bon! Tu es visiblement un homme très occupé!
+
+[CM1_2H:COUNT1]
+Tout ce que je sais, c'est que les Triades fournissent les plaques.
+
+[CM1_2I:COUNT1]
+Elles ont une compagnie de navigation sur les quais
+
+[CM1_2J:COUNT1]
+et le patron devrait savoir quand les plaques arrivent!
+
+[CM1_2K:COUNT1]
+Merci, Paul.
+
+[CM1_2L:COUNT1]
+C'est quoi ton problème, pauvre maniaque!
+
+[CM1_2M:COUNT1]
+Un autre verre, en vitesse!
+
+[CM1_3:COUNT1]
+~g~T'as été repéré!
+
+[CM1_5:COUNT1]
+~g~Va retrouver Kent Paul au Malibu!
+
+[CNT1_1:COUNT1]
+T'es qui toi? Aïe! Pas le visage! Pas le visage!
+
+[CM1_1:COUNT1]
+~g~Va au bateau de la Chartered Libertine Lines sur les docks.
+
+[CM1_2:COUNT1]
+~g~L'officier de navigation détient l'information dont tu as besoin.
+
+[CNT1_2:COUNT1]
+Ok, je parle! Je parle!
+
+[CM1_6:COUNT1]
+~g~Ramène l'info à l'imprimerie!
+
+{=================================== MISSION TABLE COUNT2 ===================================}
+
+[CNT2_B1:COUNT2]
+Bon, le coursier déplace les plaques des docks aujourd'hui.
+
+[CNT2_B2:COUNT2]
+Faut l'intercepter et récupérer ces plaques, semer les flics éventuels et revenir ici.
+
+[CNT2_B3:COUNT2]
+En fonction de comment ça marche,
+
+[CNT2_B4:COUNT2]
+on aura entre cinq minutes et toute l'année pour imprimer le pognon avant que le syndicat de contrefaçon rapplique.
+
+[CNT2_B5:COUNT2]
+Quoi qu'il en soit, je veux voir les premiers billets sortir de la presse cinq minutes après mon retour! C'est compris?
+
+[CNT2_B6:COUNT2]
+T'inquiète pas, Tommy, on sera prêts.
+
+[CNT2_B7:COUNT2]
+Les gars et moi, on sera dans le coin au cas où t'aurais besoin de renforts.
+
+[CNT2_B8:COUNT2]
+Bon, tout le monde a compris? Parfait. A plus tard.
+
+[CNT2_01:COUNT2]
+~g~Le ~r~coursier~g~ qui porte les plaques va bientôt arriver aux ~y~docks~g~ en hélico.
+
+[CNT2_02:COUNT2]
+~r~Le coursier s'est enfui en hélico!
+
+[CNT2_03:COUNT2]
+~r~Le coursier est parvenu à destination sain et sauf, c'est trop tard!
+
+[CNT2_04:COUNT2]
+~r~Tu as détruit les plaques dans l'explosion!
+
+[CNT2_05:COUNT2]
+~g~Tu as les plaques. Emmène-les à l'imprimerie!
+
+[CNT2_06:COUNT2]
+~g~Le coursier est mort et il a jeté les plaques. Récupère-les en premier.
+
+[CNT2_07:COUNT2]
+~g~Un des gardes a ramassé les plaques, ne le laisse pas s'enfuir!
+
+[CNT2_08:COUNT2]
+~g~Le ~r~coursier~g~ avec les plaques est arrivé aux docks.
+
+[CNT2_4:COUNT2]
+Affaire privée! Dégagez!
+
+[CNT2_09:COUNT2]
+IMPRIMERIE ACQUISE
+
+[CNT2_10:COUNT2]
+~g~L'imprimerie va maintenant générer un revenu maximum de $~1~. Veille à relever régulièrement les compteurs.
+
+[CNT2_11:COUNT2]
+~r~Les plaques sont au fond de la mer!
+
+{=================================== MISSION TABLE CUBAN1 ===================================}
+
+[CUB1_A:CUBAN1]
+Si, mec?
+
+[CUB1_B:CUBAN1]
+Hé, du calme, papa, ce mec est là pour moi. Hé, c'est toi le mec?
+
+[CUB1_C:CUBAN1]
+Oh ouais. C'est toi le mec. Je crois bien, tu sais.
+
+[CUB1_D:CUBAN1]
+Non, je crois pas.
+
+[CUB1_E:CUBAN1]
+Ah ouais? Amène-toi, gros dur!
+
+[CUB1_F:CUBAN1]
+Tu crois que tu peux jouer avec moi?
+
+[CUB1_G:CUBAN1]
+Tu penses que tu peux jouer au con avec moi?
+
+[CUB1_H:CUBAN1]
+Non, je pense que tu joues assez le con pour nous deux.
+
+[CUB1_I:CUBAN1]
+Hé, il t'a traité de con, fiston.
+
+[CUB1_J:CUBAN1]
+Et moi, je le traite de fillette, papa.
+
+[CUB1_K:CUBAN1]
+Regarde-le, tout habillé comme ça.
+
+[CUB1_L:CUBAN1]
+C'est la soirée des pouffiasses, ce soir?
+
+[CUB1_M:CUBAN1]
+Toi qu'est plutôt balaise, pourquoi tu te fringues en nana?
+
+[CUB1_N:CUBAN1]
+Et t'as une petite culotte comme les gonzesses?
+
+[CUB1_O:CUBAN1]
+Qu'est-ce que t'as contre les femmes? Tu préfères les mecs, mon gros?
+
+[CUB1_P:CUBAN1]
+J'aime les femmes! J'aime toutes les femmes! J'aime ma maman, Chico!
+
+[CUB1_Q:CUBAN1]
+Ok, ok, j'te crois sur parole.
+
+[CUB1_R:CUBAN1]
+Tu sais conduire, amigo?
+
+[CUB1_S:CUBAN1]
+Ouais... Comme une gonzesse.
+
+[CUB1_T:CUBAN1]
+Très drôle... Tu me plais, ma grosse, peut-être que tu peux aider.
+
+[CUB1_U:CUBAN1]
+Tu peux peut-être nous montrer que t'es un vrai mec?
+
+[CUB1_V:CUBAN1]
+Sors le bateau.
+
+[CUB1_W:CUBAN1]
+Prouve-moi que t'as des couilles énormes
+
+[CUB1_X:CUBAN1]
+et pas une paire de pois chiches!
+
+[CUB1_02:CUBAN1]
+Ok, mec, traite-la comme une gonzesse.
+
+[CUB1_03:CUBAN1]
+Pas mal, t'es un vrai macho.
+
+[CUB1_04:CUBAN1]
+Merde, t'en a vraiment dans le pantalon, amigo.
+
+[CUB1_05:CUBAN1]
+Amigo, t'es un vrai mec, mec.
+
+[CUB1_06:CUBAN1]
+Tu te prends pour un homme, mec?
+
+[CUB1_07:CUBAN1]
+T'es qu'une petite poule mouillée, petit, c'est ta mère qui te manque?
+
+[CUB1_08:CUBAN1]
+Tu gâches tout! Tu marches comme un mec, tu causes comme un mec, mais tu conduis comme une gonzesse!
+
+[CUB1_09:CUBAN1]
+Mec, t'es un vrai mec de chez mec, mec! Putain, je t'adore, mec!
+
+[CUB1_10:CUBAN1]
+C'est quand tu veux, mec. T'as des couilles de taureau et tous mes potes ont des couilles énormes!
+
+[CUB1_11:CUBAN1]
+~r~T'as tué Rico!
+
+[CUB1_12:CUBAN1]
+Va jusqu'au premier point de contrôle pour commencer le test.
+
+[CUB1_14:CUBAN1]
+Retourne dans le bateau!
+
+[CUB1_15:CUBAN1]
+~r~T'es trop lent, mec!
+
+[CUB1_01:CUBAN1]
+Salut, moi c'est Rico. C'est toi qu'a des couilles de taureau?
+
+[CUB1_13:CUBAN1]
+~g~Tu as trois minutes pour terminer le parcours.
+
+{=================================== MISSION TABLE CUBAN2 ===================================}
+
+[CUB2_25:CUBAN2]
+BUTE TOUS LES HAITIENS!
+
+[CUB2_A:CUBAN2]
+Un cafecito, por favor, Alberto...
+
+[CUB2_N:CUBAN2]
+Tout de suite, Tommy.
+
+[CUB2_B:CUBAN2]
+Poppa! Un gran problema!
+
+[CUB2_O:CUBAN2]
+Umberto, mon fils, que s'est-il passé?
+
+[CUB2_C:CUBAN2]
+Les Haïtiens! Je hais les Haïtiens!
+
+[CUB2_D:CUBAN2]
+C'est la dernière fois qu'ils me font chier!
+
+[CUB2_E:CUBAN2]
+Ces Haïtiens... On va les liquider!
+
+[CUB2_F:CUBAN2]
+On a juste besoin de renforts...
+
+[CUB2_G:CUBAN2]
+J'ai déjà perdu pas mal de frères là-bas.
+
+[CUB2_H:CUBAN2]
+Amigo, tu conduis pas mal!
+
+[CUB2_I:CUBAN2]
+Pour une gonzesse... Pas vrai?
+
+[CUB2_J:CUBAN2]
+C'est pas l'heure des vannes!
+
+[CUB2_K:CUBAN2]
+Allez, conduis encore pour moi!
+
+[CUB2_L:CUBAN2]
+Récupère mes gars là-bas et puis on s'occupe de ces Haïtiens!
+
+[CUB2_M:CUBAN2]
+Ils m'ont cherché et ils sont tombés sur le mec le plus balaise de la ville!
+
+[CUB2_01:CUBAN2]
+C'est trop petit, mec, il te faut une plus grosse bagnole.
+
+[CUB2_02:CUBAN2]
+On a besoin de renforts du café!
+
+[CUB2_03:CUBAN2]
+~g~Prend une bagnole et va ramasser les Cubains à l'extérieur du café de Robina.
+
+[CUB2_04:CUBAN2]
+~g~Amène les Cubains à l'endroit de la bagarre.
+
+[CUB2_05:CUBAN2]
+Liquide ce lâche de tireur embusqué!
+
+[CUB2_07:CUBAN2]
+Ils se battent comme des filles! A couvert!
+
+[CUB2_09:CUBAN2]
+Un sniper sur le toit!
+
+[CUB2_11:CUBAN2]
+~r~Imbécile, on avait besoin de cette bagnole!
+
+[CUB2_12:CUBAN2]
+Hé, amigo! Content de te voir que t'as réussi!
+
+[CUB2_13:CUBAN2]
+Putains de Haïtiens, on va tous les descendre!
+
+[CUB2_14:CUBAN2]
+CHAAAAAARGEZ!
+
+[CUB2_15:CUBAN2]
+Maintenant, mes frères! Chaaaargez!
+
+[CUB2_16:CUBAN2]
+Tommy, on a fait la preuve de notre courage!
+
+[CUB2_17:CUBAN2]
+Piquons cette camionnette bourrée de drogue et tirons-nous!
+
+[CUB2_18:CUBAN2]
+~g~Trouve une bagnole et va chercher les Cubains.
+
+[CUB2_19:CUBAN2]
+On va se battre comme des hommes!
+
+[CUB2_21:CUBAN2]
+Battez-vous avec vos couilles!
+
+[CUB2_22:CUBAN2]
+~g~Elimine les derniers Haïtiens pour que les Cubains puissent avancer.
+
+[CUB2_23:CUBAN2]
+~g~Little Haiti va grouiller de Haïtiens voulant régler leurs comptes avec les Cubains. Fais gaffe à tes couilles.
+
+[CUB2_24:CUBAN2]
+~g~Retourne au café de Robina avec la camionnette et gare-la derrière.
+
+{=================================== MISSION TABLE CUBAN3 ===================================}
+
+[CUB3_A:CUBAN3]
+Alberto. Un café, senor.
+
+[CUB3_B:CUBAN3]
+Papa, ne sers pas ce morbac...
+
+[CUB3_C:CUBAN3]
+T'es un hypocrite, Tommy!
+
+[CUB3_D:CUBAN3]
+T'es soit un hypocrite, soit une gonzesse!
+
+[CUB3_E:CUBAN3]
+Les Haïtiens, mec! Ils se foutent de ma gueule!
+
+[CUB3_F:CUBAN3]
+Du calme. C'est quoi ton problème?
+
+[CUB3_G:CUBAN3]
+Ils se foutent ma gueule, Tommy, de ma gueule!
+
+[CUB3_H:CUBAN3]
+Umberto Robina! Ils font comme ça leur chante!
+
+[CUB3_I:CUBAN3]
+Personne fait ce qu'il veut, Umberto, ils font ce que tu les laisses faire.
+
+[CUB3_J:CUBAN3]
+Quoi?
+
+[CUB3_K:CUBAN3]
+Tu veux que quelqu'un s'en occupe?
+
+[CUB3_L:CUBAN3]
+Je peux m'en charger, mais ça va te coûter cher!
+
+[CUB3_M:CUBAN3]
+Je sais qu'on est frères et tout et tout, mais ça, c'est les affaires...
+
+[CUB3_N:CUBAN3]
+Tommy, t'es un vrai mec! Un businessman! Un gentleman!
+
+[CUB3_O:CUBAN3]
+Ces Haïtiens. Ils ont de la marchandise de première qualité qui arrive par la mer.
+
+[CUB3_P:CUBAN3]
+On la prend et on en finit avec eux.
+
+[CUB3_Q:CUBAN3]
+Tu t'en charges et je veillerai sur toi. Comme mon frère. Comme mon fils.
+
+[CUB3_R:CUBAN3]
+J'préfère que tu me files du pognon, plutôt que de me faire sauter sur tes genoux, amigo...
+
+[CUB3_01:CUBAN3]
+Salut, Rico. Chouette bateau. T'es prêt?
+
+[CUB3_03:CUBAN3]
+~g~Récupère toutes les serviettes pleines de drogue et de cash.
+
+[CUB3_04:CUBAN3]
+~g~Ramène la drogue et le cash à Umberto.
+
+[CUB3_05:CUBAN3]
+Si, Tommy, faut que tu tires bien, aujourd'hui.
+
+[CUB3_06:CUBAN3]
+Mon bateau, je voudrais pas qu'il se retrouve plein de trous, ok?
+
+[CUB3_07:CUBAN3]
+~g~Va retrouver Rico. Il te conduira au rendez-vous.
+
+[CUB3_02:CUBAN3]
+~g~TUE TOUS LES HAITIENS EN BATEAU!
+
+[CUB3_08:CUBAN3]
+Oh oh... Les Cubains. On nous attaque!
+
+{=================================== MISSION TABLE CUBAN4 ===================================}
+
+[CUB4_A:CUBAN4]
+Salut, les filles, vous savez ce que je vais faire?
+
+[CUB4_B:CUBAN4]
+Je vais aller me descendre un Haïtien. Et après, vous savez quoi?
+
+[CUB4_C:CUBAN4]
+Après, je vais me vider les couilles comme un homme!
+
+[CUB4_D:CUBAN4]
+T'as déjà vu ça chica? Un peu comme ça...
+
+[CUB4_E:CUBAN4]
+Pauv' mec!
+
+[CUB4_F:CUBAN4]
+Connard!
+
+[CUB4_G:CUBAN4]
+Hé, ma poule, je te toucherai même pas avec une perche!
+
+[CUB4_H:CUBAN4]
+Umberto Robina, il aime les femmes! Pas les vieilles dindes en jupe!
+
+[CUB4_I:CUBAN4]
+Tommy! Tommy, je t'aime, je t'aime! Allons-y!
+
+[CUB4_J:CUBAN4]
+Où ça? Je peux pas avoir un café d'abord?
+
+[CUB4_K:CUBAN4]
+Pas le temps pour un café! D'ailleurs, je viens d'en prendre un!
+
+[CUB4_L:CUBAN4]
+Faut qu'on liquide les Haïtiens!
+
+[CUB4_M:CUBAN4]
+Tommy, tu sais comment on tue un serpent?
+
+[CUB4_N:CUBAN4]
+Tu le mords au cul! Ahahaha!
+
+[CUB4_O:CUBAN4]
+Si tu le dis, Umberto.
+
+[CUB4_P:CUBAN4]
+Tommy, va nous trouver une petite bagnole haïtienne!
+
+[CUB4_Q:CUBAN4]
+Dès que tu l'as, reviens récupérer mon petit
+
+[CUB4_R:CUBAN4]
+Pepe et emmène-le chez les Haïtiens.
+
+[CUB4_S:CUBAN4]
+Ensuite, tu vas au centre de retraitement des Haïtiens et tu te sers de leurs solvants comme explosif.
+
+[CUB4_T:CUBAN4]
+Boom! Et bye bye!
+
+[CUB4_U:CUBAN4]
+Et toi, Umberto?
+
+[CUB4_V:CUBAN4]
+Oh, je reste en arrière, je surveille le café avec papa.
+
+[CUB4_W:CUBAN4]
+Il ne se sent pas très bien, tu sais.
+
+[CUB4_02:CUBAN4]
+~g~Les bombes ont un retardateur de 45 secondes.
+
+[CUB4_04:CUBAN4]
+~r~Tu as mis leur base en alerte! Plus question d'entrer, maintenant!
+
+[CUB4_07:CUBAN4]
+Les solvants sont à l'arrière, amigo.
+
+[CUB4_08:CUBAN4]
+Hola, amigos.
+
+[CUB4_09:CUBAN4]
+Bueno. Putains d'Haïtiens. Muerte.
+
+[CUB4_10:CUBAN4]
+Vamos.
+
+[CUB4_11:CUBAN4]
+Si, vamos.
+
+[CUB4_12:CUBAN4]
+Hé, on a besoin d'une bagnole haïtienne!
+
+[CUB4_13:CUBAN4]
+Bueno, allons trouver ces muchachos!
+
+[CUB4_14:CUBAN4]
+Suis mes amigos.
+
+[CUB4_15:CUBAN4]
+Ok, tu entres...
+
+[CUB4_16:CUBAN4]
+Je vais poser la bombe, couvrez-moi!
+
+[CUB4_17:CUBAN4]
+COURS!
+
+[CUB4_18:CUBAN4]
+Mec, c'est un quartier cool...
+
+[CUB4_19:CUBAN4]
+Cet endroit est une décharge, mec.
+
+[CUB4_20:CUBAN4]
+J'avais une belle copine... Elle vivait dans le coin.
+
+[CUB4_21:CUBAN4]
+Tu sais, ils font de super pizzas, ici!
+
+[CUB4_22:CUBAN4]
+Hé, mec, tu conduis comme une putain de gonzesse!
+
+[CUB4_23:CUBAN4]
+T'es perdu, mec?
+
+[CUB4_24:CUBAN4]
+T'as laissé Pepe derrière, va le récupérer!
+
+[CUB4_03:CUBAN4]
+~g~Ne sors pas de la bagnole avant qu'elle soit garée en sécurité dans l'enceinte.
+
+[CUB4_26:CUBAN4]
+~g~Emmène Pepe, file au nord dans Little Haïti et fauche une bagnole Vaudou.
+
+[CUB4_27:CUBAN4]
+~g~Va retrouver Rico et les autres Cubains.
+
+[CUB4_28:CUBAN4]
+~g~Va rejoindre les Cubains dans l'usine de dope haïtienne.
+
+[CUB4_29:CUBAN4]
+~g~Marche sur chacun des marqueurs pour y poser une bombe.
+
+[CUB4_30:CUBAN4]
+~g~Une fois les trois bombes posées, sors de l'usine avant qu'elle n'explose.
+
+[CUB4_31:CUBAN4]
+~g~Sors de l'usine!
+
+[CUB4_32:CUBAN4]
+~g~Gare la bagnole à l'endroit du bip et descends.
+
+[CUB4_06:CUBAN4]
+~r~Tu ne t'es pas assez éloigné de la base et on a dû annuler l'explosion!
+
+{=================================== MISSION TABLE FINALE ===================================}
+
+[FIN_1A:FINALE]
+Amène-toi, putain de salopard de traître!
+
+[FIN_1B:FINALE]
+Tu vas crever, Judas de mes deux!
+
+[FIN_1C:FINALE]
+C'est la dernière danse de Lance Vance!
+
+[FIN_2B:FINALE]
+Ah ouais, c'est ce que tu crois?
+
+[FIN_2C:FINALE]
+J'ai dit que je l'avais assez entendu celle-là à l'école!
+
+[FIN_3:FINALE]
+Plus personne pour couvrir ton cul, hein, Tommy?
+
+[FIN_4:FINALE]
+T'es plus que du passé, Tommy, du passé!
+
+[FIN_5:FINALE]
+T'as choisi le mauvais camp, Lance...
+
+[FIN_11A:FINALE]
+Tu m'as volé quinze ans de ma vie, Sonny...
+
+[FIN_11B:FINALE]
+Et je viens te présenter l'addition!
+
+[FIN_12A:FINALE]
+T'as encore rien compris!
+
+[FIN_12B:FINALE]
+Tu m'appartiens, Tommy...
+
+[FIN_12C:FINALE]
+C'est moi qui devait les faire ces quinze années!
+
+[FIN_13:FINALE]
+Attrapez-le, les mecs, il a jamais rien pigé.
+
+[FIN1_01:FINALE]
+Qu'est-ce qui se passe?
+
+[FIN1_02:FINALE]
+Tommy! Ah, bien, bien. Ecoute, écoute... Euh, écoute.
+
+[FIN1_03:FINALE]
+J'aime bien les poissons. Ouais, j'adore le poisson!
+
+[FIN1_04:FINALE]
+Je l'aime à toutes les sauces, dans le bocal ou dans l'assiette,
+
+[FIN1_05:FINALE]
+mais c'est pas parce que je l'aime que je veux dormir avec!
+
+[FIN1_06:FINALE]
+Et maintenant, il y a tes cousins ritals qui s'amènent pour me coller les pieds dans le béton, et je...
+
+[FIN1_07:FINALE]
+La ferme, Ken. Assis.
+
+[FIN1_08:FINALE]
+Lance, bordel, qu'est-ce qui se passe?
+
+[FIN1_09:FINALE]
+C'est tes amis du nord, Tommy... Ils ont pas aimé ce que t'as fait à leur mec.
+
+[FIN1_10:FINALE]
+Ils s'amènent aujourd'hui pour régler cette affaire.
+
+[FIN1_11:FINALE]
+Ils ont mis plus de temps que je pensais...
+
+[FIN1_12:FINALE]
+Les mecs, faut en finir et faire comprendre à tout le monde que désormais, c'est mon business! LE MIEN!
+
+[FIN1_13:FINALE]
+Ken, prend la première production de faux dollars et mets-en pour vingt millions dans des porte-documents.
+
+[FIN1_14:FINALE]
+Lance, tu rassembles tout le monde...
+
+[FIN2_01:FINALE]
+Tommy!
+
+[FIN2_02:FINALE]
+Quoi? T'embrasses pas ton vieux pote?
+
+[FIN2_03:FINALE]
+Ca fait quinze piges que je suis hors-circuit
+
+[FIN2_04:FINALE]
+et je suis un peu rouillé question étiquette.
+
+[FIN2_05:FINALE]
+Toujours la haine, hein, Tommy!
+
+[FIN2_06:FINALE]
+Je te l'avais pas dit que ton sale caractère te causerait des emmerdes?
+
+[FIN2_07:FINALE]
+Il y a vingt millions là-dedans...
+
+[FIN2_08:FINALE]
+Combien ils étaient déjà? Dix, non onze...
+
+[FIN2_09:FINALE]
+C'est pour ça qu'on t'a surnommé le boucher d'Hartwood! Hé hé hé!
+
+[FIN2_10:FINALE]
+Tu m'avais envoyé buter un mec, un seul mec. Mais ils savaient que je venais, Sonny...
+
+[FIN2_11:FINALE]
+Fais gaffe à ce que tu dis...
+
+[FIN2_12:FINALE]
+Quelqu'un pourrait penser que tu veux me coller sur le dos un malheureux concours de circonstances...
+
+[FIN2_13:FINALE]
+Prends simplement ce pognon...
+
+[FIN2_14:FINALE]
+Prendre le putain de fric?
+
+[FIN2_15:FINALE]
+Tu sais, Tommy, j'ai fait ce que je pouvais pour toi, j'ai tiré des ficelles et demandé des services.
+
+[FIN2_16:FINALE]
+J'étais ton pote, Tommy. J'espérais que tu entendrais raison et comprendrais ce qui est bon pour les affaires.
+
+[FIN2_17:FINALE]
+Je t'ai fait confiance, Tommy et je suis déçu...
+
+[FIN2_18:FINALE]
+Mais il y a au moins un mec dans ton organisation de merde qui s'y connaît en business,
+
+[FIN2_19:FINALE]
+Pas vrai, Lance?
+
+[FIN2_20:FINALE]
+Désolé, Tommy, On est à Vice City. C'est les affaires...
+
+[FIN2_21:FINALE]
+Tu nous as vendus...
+
+[FIN2_22:FINALE]
+Non, juste toi, Tommy, juste TOI.
+
+[FIN2_23:FINALE]
+Le vrai pognon est en haut dans le coffre!
+
+[FIN2_24:FINALE]
+Alors, Tommy, c'était quoi le grand plan?
+
+[FIN2_25:FINALE]
+Tu croyais que j'allais simplement prendre les faux biftons?
+
+[FIN2_26:FINALE]
+Sauver la face et m'enfuir la queue entre les jambes?
+
+[FIN2_27:FINALE]
+Non.
+
+[FIN2_28:FINALE]
+Je voulais juste te faire chier avant de te buter.
+
+[FIN3_01:FINALE]
+Tommy?
+
+[FIN3_02:FINALE]
+Oh, mon Dieu, Tommy! Qu'est-ce qui s'est passé?
+
+[FIN3_03:FINALE]
+A ton avis?
+
+[FIN3_04:FINALE]
+On dirait que t'as niqué ton costard!
+
+[FIN3_05:FINALE]
+Sans compter qu'il était chouette, Tommy! Mais qu'est-ce qui s'est passé?
+
+[FIN3_06:FINALE]
+J'ai eu un désaccord avec un partenaire commercial, tu sais comment c'est.
+
+[FIN3_07:FINALE]
+Tommy, moi, quand j'ai un désaccord avec un partenaire commercial, je lui envoie une lettre enflammée...
+
+[FIN3_08:FINALE]
+A la rigueur, je pisse dans sa boite aux lettres... Mais je commence pas la troisième guerre mondiale!
+
+[FIN3_09:FINALE]
+Tu sais, tu devrais peut-être voir mon psy...
+
+[FIN3_10:FINALE]
+Ce sale con de Lance...
+
+[FIN3_11:FINALE]
+Tommy. J'ai jamais pu blairer ce mec, tu sais?
+
+[FIN3_12:FINALE]
+C'est un névrosé dangereux et égocentrique. Un vrai salopard!
+
+[FIN3_13:FINALE]
+Je suis bien content que tu l'aies liquidé!
+
+[FIN3_14:FINALE]
+Je crois pas qu'on doive s'attendre à plus d'emmerdes en provenance du nord...
+
+[FIN3_15:FINALE]
+... Parce qu'il y a plus de nord...
+
+[FIN3_16:FINALE]
+Maintenant, il n'y a plus que le sud...
+
+[FIN3_17:FINALE]
+Attends, est-ce que ça veut dire ce que je crois que ça veut dire, Tommy?
+
+[FIN3_18:FINALE]
+Qu'est-ce que tu crois que ça veut dire?
+
+[FIN3_19:FINALE]
+Qu'on est au commandement... Enfin, que tu es au commandement. Oh, Tommy...
+
+[FIN3_20:FINALE]
+Tu sais, Ken, c'est peut-être le début d'une grande amitié en affaires...
+
+[FIN3_21:FINALE]
+Après tout, t'es un voleur minable un peu magouilleur sur les bords...
+
+[FIN3_22:FINALE]
+Et moi je suis un tueur psychotique doublé d'un dealer...
+
+[FIN3_23:FINALE]
+Ouais. Si c'est pas grandiose!
+
+[FIN_B1:FINALE]
+~g~Va tuer ~y~Vance~g~ le traître.
+
+[FIN_B2:FINALE]
+~g~Trouve ~p~Sonni~g~ et règle-lui son compte pour de bon.
+
+[FIN_B3:FINALE]
+~g~La mafia essaye de voler ton pognon. Défends le coffre.
+
+[FIN_B4:FINALE]
+~g~Tu es presque mort. Va chercher ~w~de quoi te soigner~g~ en bas.
+
+[FIN_B5:FINALE]
+~g~La mafia te vole ton pognon. Défends le ~c~coffre.
+
+[FIN_B7:FINALE]
+~r~La mafia t'a volé tout ton pognon.
+
+[DEFSAFE:FINALE]
+~g~Retourne au coffre et protège-le.
+
+{=================================== MISSION TABLE FIRETRK ===================================}
+
+[F_PASS1:FIRETRK]
+Feu éteint!
+
+[F_FAIL2:FIRETRK]
+~r~T'arrives trop tard!
+
+[F_CANC:FIRETRK]
+~r~Mission pompier annulée!
+
+[F_EXTIN:FIRETRK]
+INCENDIES :
+
+[F_START:FIRETRK]
+~g~Véhicule en feu repéré dans le secteur ~a~. Va éteindre le feu.
+
+[SIREN_1:FIRETRK]
+Pour déclencher la sirène de ce véhicule, appuie brièvement sur la ~h~~k~~VEHICLE_HORN~~w~.
+
+[SIREN_2:FIRETRK]
+Pour déclencher la sirène de ce véhicule, appuie brièvement sur la ~h~~k~~VEHICLE_HORN~~w~.
+
+[FIREPRO:FIRETRK]
+Mission Camion de pompiers niveau 12 réussie. T'es complètement ignifugé maintenant!
+
+[F_FAIL1:FIRETRK]
+Mission Camion de pompiers achevée.
+
+[F_STAR1:FIRETRK]
+~g~Véhicules en flammes dans la zone ~a~. Va éteindre l'incendie.
+
+[SPRAY_4:FIRETRK] { reVC update }
+Utilise la touche ~h~~k~~VEHICLE_FIREWEAPON~ ~w~pour tirer avec le canon à eau et le ~h~~k~~VEHICLE_TURRETLEFT~~w~ et ~h~~k~~VEHICLE_TURRETRIGHT~~w~ pour viser.
+
+[SPRAY_1:FIRETRK] { reVC update }
+Utilise la touche ~h~~k~~VEHICLE_FIREWEAPON~ ~w~pour tirer avec le canon à eau et le ~h~~k~~VEHICLE_TURRETLEFT~~w~ et ~h~~k~~VEHICLE_TURRETRIGHT~~w~ pour viser.
+
+{=================================== MISSION TABLE GENERA1 ===================================}
+
+[GEN1_A:GENERA1]
+Mr. Vercetti!
+
+[GEN1_B:GENERA1]
+Colonel.
+
+[GEN1_D:GENERA1]
+Non merci.
+
+[GEN1_E:GENERA1]
+Ca me gêne beaucoup d'admettre que la cause d'un de nos problèmes communs semble être un homme en qui j'avais confiance.
+
+[GEN1_F:GENERA1]
+J'ai supporté Gonzalez pendant des années, mais son incompétence a atteint de nouveaux sommets.
+
+[GEN1_G:GENERA1]
+Vous avez le droit de tuer Gonzalez...
+
+[GEN1_H:GENERA1]
+C'est lui qui m'a entubé? La seule chose qui m'intéresse, c'est le pognon!
+
+[GEN1_I:GENERA1]
+Je vous récompenserai pour ce service et nous chercherons ensuite votre argent ensemble.
+
+[GEN1_J:GENERA1]
+Il sera dans son appartement, probablement à moitié saoul. Servez-vous de ça...
+
+[GEN1_06:GENERA1]
+Hé! Il a une tronçonneuse!
+
+[GEN1_07:GENERA1]
+T'approche pas de moi, connard!
+
+[GEN1_08:GENERA1]
+Oh, mon Dieu, j'ai gâché ma vie et j'suis devenu un laidron!
+
+[GEN1_10:GENERA1]
+Je vais t'faire fermer ta grande gueule une bonne fois pour toutes.
+
+[GEN1_11:GENERA1]
+Essaye pas de t'enfuir, bâtard!
+
+[GEN1_12:GENERA1]
+Laisse-toi faire et ça sera rapide!
+
+[GEN1_13:GENERA1]
+Arrête de gueuler, ça intéresse personne!
+
+[GEN1_C:GENERA1]
+Merci d'être venu. Asseyez-vous. Du homard?
+
+[GEN1_05:GENERA1]
+~g~Va tuer Gonzales!
+
+[GEN1_09:GENERA1]
+Je t'offre le double, Tommy, LE DOUBLE!
+
+[GEN1_18:GENERA1]
+~r~Gonzalez a réussi à atteindre le poste de police vivant!
+
+[GEN1_19:GENERA1]
+~g~Les flics de Vice City te cherchent!
+
+[GEN1_20:GENERA1]
+~g~Monte dans une bagnole.
+
+[GEN1_21:GENERA1]
+~g~Va au~h~ Pay 'N' Spray~g~ à~h~ Vice Point~g~.
+
+[GEN1_22:GENERA1]
+~g~Conduis ton véhicule à l'intérieur de l'atelier de peinture pour perdre ton ~h~indice de recherche~g~, ~h~réparer ~g~et ~h~repeindre ~g~ton véhicule. Coût : ~h~$100~g~. Cette coup-ci, c'est gratuit.
+
+[GEN1_01:GENERA1]
+Quand tu cours, maintiens la~h~ ~k~~PED_FIREWEAPON~~w~ enfoncée pour préparer une attaque au corps à corps.
+
+[GEN1_02:GENERA1]
+Quand tu cours, maintiens la~h~ ~k~~PED_FIREWEAPON~~w~ enfoncée pour préparer une attaque au corps à corps.
+
+[GEN1_03:GENERA1]
+Quand tu cours, maintiens la~h~ ~k~~PED_FIREWEAPON~~w~ enfoncée pour préparer une attaque au corps à corps.
+
+[GEN1_14:GENERA1]
+Relâche la~h~ ~k~~PED_FIREWEAPON~~w~ pour attaquer.
+
+[GEN1_15:GENERA1]
+Relâche la~h~ ~k~~PED_FIREWEAPON~~w~ pour attaquer.
+
+[GEN1_16:GENERA1]
+Relâche la~h~ ~k~~PED_FIREWEAPON~~w~ pour attaquer.
+
+[GEN1_23:GENERA1]
+~g~Franchis à nouveau les portes pour revenir au rez-de-chaussée.
+
+{=================================== MISSION TABLE GENERA2 ===================================}
+
+[COL2_A:GENERA2]
+Tommy! Venez donc vous joindre à moi!
+
+[COL2_B:GENERA2]
+Ca a l'air bon, hein! Un peu de museau de tapir?
+
+[COL2_C:GENERA2]
+Euh... Non. Non, merci.
+
+[COL2_D:GENERA2]
+Tommy, vous êtes comme le vent de la pampa qui m'a purifié de la puanteur de la corruption.
+
+[COL2_E:GENERA2]
+Je dois cependant montrer que je pleure sa mort et continuer les affaires comme d'habitude.
+
+[COL2_F:GENERA2]
+Ca me rapproche pas beaucoup de mon pognon...
+
+[COL2_G:GENERA2]
+Tommy, mon cher, vous n'êtes pas à Liberty. Ici, ça se passe autrement.
+
+[COL2_H:GENERA2]
+Je vais continuer mon enquête, mais en attendant, j'ai une bonne affaire à conclure.
+
+[COL2_I:GENERA2]
+Un service à rendre à un ami, Cortez.
+
+[COL2_J:GENERA2]
+Vous êtes un ami, Tommy. Je savais que vous ne me laisseriez pas tomber.
+
+[COL2_K:GENERA2]
+Il faut que vous rencontriez un coursier qui m'a obtenu une technologie intéressante...
+
+[COL2_1:GENERA2]
+Ah, la pluie est très dense en cette saison...
+
+[COL2_2:GENERA2]
+Quoi?
+
+[COL2_3:GENERA2]
+Ah, comment?
+
+[COL2_4:GENERA2]
+Ecoute, Cortez m'envoie. File-moi ces putain de processeurs.
+
+[COL2_5:GENERA2]
+Oh... D'accord.
+
+[COL2_B1:GENERA2]
+~g~Retrouve le coursier au centre commercial.
+
+[COL2_B2:GENERA2]
+~g~Le coursier se barre avec les processeurs de guidage. Ne le laisse pas filer!
+
+[COL2_B3:GENERA2]
+~g~Ramène les processeurs de guidage au Colonel.
+
+[COL2_F1:GENERA2]
+~r~T'as buté le contact!
+
+[COL2_F2:GENERA2]
+~r~Le coursier est mort. Récupère les processeurs.
+
+[COL2_6A:GENERA2]
+Arrête, espèce de porc impérialiste d'américain! Ceci est la propriété du gouvernement français! Rendez-le!
+
+[BLIPHLP:GENERA2]
+Le bip sur le radar est un triangle pointant vers le haut, ce qui signifie que la cible est plus élevée que toi.
+
+[COL2_F3:GENERA2]
+~r~Les processeurs de guidage sont au fond de la mer.
+
+[COL2_F4:GENERA2]
+~r~Le coursier s'est fait la malle! Tu n'as pas récupéré les processeurs de guidage!
+
+{=================================== MISSION TABLE GENERA3 ===================================}
+
+[GEN3_49:GENERA3]
+Santé de Lance:
+
+[GEN3_A:GENERA3]
+Merci d'être venu, Thomas.
+
+[GEN3_B:GENERA3]
+Pardonnez-moi d'en venir directement au fait...
+
+[GEN3_C:GENERA3]
+Diaz m'a demandé de superviser une petite transaction...
+
+[GEN3_D:GENERA3]
+Espérons que ça se passera mieux que l'autre fois, n'est-ce pas?
+
+[GEN3_E:GENERA3]
+C'est pour ça que j'ai pensé à vous, amigo.
+
+[GEN3_F:GENERA3]
+J'ai déposé une arme dans le parking à niveaux.
+
+[GEN3_G:GENERA3]
+Récupèrez-le et allez surveiller les hommes de Diaz au rendez-vous.
+
+[GEN3_H:GENERA3]
+Gracias, amigo...
+
+[GEN3_1:GENERA3]
+On s'accapare toute l'action, à ce que je vois...
+
+[GEN3_2:GENERA3]
+Ecoute, tu veux pas faire autre chose que de me suivre partout comme mon ombre? Pourquoi tu ne viens pas pour me montrer à quoi t'es bon?
+
+[GEN3_3:GENERA3]
+Pourquoi pas... Au fait, moi c'est Lance.
+
+[GEN3_5:GENERA3]
+Tu dois être le nouveau porte-flingues de Cortez.
+
+[GEN3_6:GENERA3]
+Jusqu'à ce que de meilleures opportunités se présentent...
+
+[GEN3_7:GENERA3]
+Ils seront là d'une minute à l'autre. On ferait mieux de se trouver une bonne planque...
+
+[GEN3_8:GENERA3]
+OK! Je vais sur le balcon et toi tu t'mets sur le toit de l'autre côté de la cour.
+
+[GEN3_9:GENERA3]
+J'suis vivant! Têtes de noeuds! Et ça c'est grâce à toi! C'est quoi ton nom?
+
+[GEN3_10:GENERA3]
+Tommy.
+
+[GEN3_11:GENERA3]
+On se reverra bientôt, je pense!
+
+[GEN3_12:GENERA3]
+Bon, où est passé Lance? Merde...
+
+[GEN3_14:GENERA3]
+Tommy! J'ai besoin d'un coup de main!
+
+[GEN3_15:GENERA3]
+T'en fais pas, je te couvre!
+
+[GEN3_16:GENERA3]
+Les hommes de Diaz se font massacrer!
+
+[GEN3_19:GENERA3]
+~g~Les haïtiens! Ils veulent foutre le deal en l'air! Protège Diaz!
+
+[GEN3_20:GENERA3]
+~g~Va au parking à niveaux où tu peux récupérer le flingue que le Colonel a laissé pour toi.
+
+[GEN3_22:GENERA3]
+Santé de Diaz :
+
+[GEN3_23:GENERA3]
+~g~T'as laissé Lance derrière! Va le chercher!
+
+[GEN3_25:GENERA3]
+~r~Lance est mort!
+
+[GEN3_28:GENERA3]
+~g~Ramène la serviette à Diaz.
+
+[GEN3_29:GENERA3]
+~g~Récupère la serviette et ramène-la à Diaz.
+
+[GEN3_30:GENERA3]
+~r~Il s'est barré avec le pognon! Diaz va te couper les couilles!
+
+[GEN3_33:GENERA3]
+~r~Tu es supposé surveiller Diaz et ses hommes, pas les flinguer!
+
+[GEN3_34:GENERA3]
+~r~Ils ne vont pas pouvoir faire affaire si tu descends les cubains!
+
+[GEN3_35:GENERA3]
+~g~Il a volé le pognon de Diaz!
+
+[GEN3_36:GENERA3]
+~g~Saute sur la moto, rattrape-le et récupère le pognon de Diaz!
+
+[GEN3_37:GENERA3]
+~g~Voilà les Cubains. Surveille le deal en veillant à la sécurité de Diaz et de Lance.
+
+[GEN3_38:GENERA3]
+~r~Diaz est mort! Tu devais le protéger!
+
+[GEN3_39:GENERA3]
+~g~Prends position en haut des escaliers.
+
+[GEN3_44:GENERA3]
+~g~Va avec Lance au rendez-vous et protège Diaz.
+
+[GEN3_40:GENERA3] { reVC update }
+Pour ~h~tirer droit devant ~w~lorsque tu es en ~h~moto~w~, appuie sur la ~h~~k~~VEHICLE_FIREWEAPON~.
+
+[GEN3_41:GENERA3] { reVC update }
+Pour ~h~tirer droit devant ~w~lorsque tu es en ~h~moto~w~, appuie sur la ~h~~k~~VEHICLE_FIREWEAPON~.
+
+[GEN3_46:GENERA3]
+Chiiiier!
+
+[GEN3_47:GENERA3]
+Tommy!
+
+[GEN3_48:GENERA3]
+Merde!
+
+[GEN3_50:GENERA3]
+~r~Tu as paumé le fric de Diaz! La prochaine fois, essaie de ne pas cramer le blé!
+
+[GEN3_51:GENERA3]
+Encore des Haïtiens dans un camion merdique!
+
+[GEN3_54:GENERA3]
+s Restez pas plantés là, bande d'abrutis! Butez-moi ce Haïtien de merde!
+
+[GEN3_55:GENERA3]
+Tommy! Je reste là et je m'occupe de Diaz!
+
+[GEN3_18:GENERA3]
+~g~Voilà les Cubains. Reste près de Diaz. Surveille les opérations tout en t'assurant que Diaz et Lance sont en sécurité.
+
+[GEN3_56:GENERA3]
+~r~Diaz a été pris dans une embuscade et s'est fait tuer! La prochaine fois, ne le quitte pas des yeux!
+
+[GEN3_57:GENERA3]
+Le Kruger est un fusil d'assaut permettant de viser manuellement à la 1ere personne.
+
+[GEN3_58:GENERA3]
+Appuie sur la touche~h~ R1~w~ et maintiens-la enfoncée pour ~h~viser~w~ avec un fusil d'assaut.
+
+[GEN3_59:GENERA3]
+Appuie sur la touche~h~ L1~w~ et maintiens-la enfoncée pour ~h~viser~w~ avec un fusil d'assaut.
+
+[GEN3_60:GENERA3]
+Appuie sur la touche ~h~~k~~PED_FIREWEAPON~~w~ pour ~h~tirer~w~ avec un fusil d'assaut.
+
+[GEN3_61:GENERA3]
+Appuie sur la touche ~h~~k~~PED_FIREWEAPON~~w~ pour ~h~tirer~w~ avec un fusil d'assaut.
+
+[GEN3_62:GENERA3]
+Appuie sur la touche ~h~~k~~PED_FIREWEAPON~~w~ pour ~h~tirer~w~ avec un fusil d'assaut.
+
+[GEN3_63:GENERA3]
+Tu peux fusiller des types de côté sur une ~h~ moto ~w~, mais également ~h~tirer droit devant~w~.
+
+[GEN3_64:GENERA3] { reVC update }
+Appuie sur la touche ~h~~k~~VEHICLE_FIREWEAPON~~w~ pour tirer droit devant toi sur une moto.
+
+[GEN3_65:GENERA3] { reVC update }
+Appuie sur la touche ~h~~k~~VEHICLE_FIREWEAPON~~w~ pour tirer droit devant toi sur une moto.
+
+[GEN3_66:GENERA3] { reVC update }
+Appuie sur la touche ~h~~k~~VEHICLE_FIREWEAPON~~w~ pour tirer droit devant toi sur une moto.
+
+[GEN3_67:GENERA3]
+Il te faut une mitrailleuse pour tirer droit devant toi sur une moto.
+
+[GEN3_53:GENERA3]
+Mon argent!
+
+[GEN3_52:GENERA3]
+Ces Haitiens pensent qu'ils peuvent se payer Ricardo Diaz!
+
+{=================================== MISSION TABLE GENERA4 ===================================}
+
+[DETON:GENERA4]
+DETONATION :
+
+[COL4_3:GENERA4]
+CONVOI, HALTE!
+
+[COL4_6:GENERA4]
+ON EST SOUS LE FEU ENNEMI!
+
+[COL4_7:GENERA4]
+Civil, éloigne-toi du char!
+
+[COL4_8:GENERA4]
+J'ai dit, dégage! IMMEDIATEMENT!
+
+[COL4_9:GENERA4]
+POSITIONS DEFENSIVES!
+
+[COL4_11:GENERA4]
+Dégagez ce civil de notre chemin, soldat! -Chef, oui, chef!
+
+[COL4_12:GENERA4]
+Un civil dans le char! ARRETEZ-LE!
+
+[COL4_13:GENERA4]
+Ceci est un convoi militaire, ne bloquez pas la route!
+
+[COL4_14:GENERA4]
+Descendez-le, soldat.
+
+[COL4_15:GENERA4]
+Dégagez ce véhicule civil de la route! -Chef, on déplace le véhicule, chef!
+
+[COL4_17:GENERA4]
+Ok, peloton, on dégage!
+
+[COL4_18:GENERA4]
+Y'a quelqu'un dans le char, chef!
+
+[COL4_19:GENERA4]
+Trouvez-moi quelques beignets, soldat! -Chef, oui, chef!
+
+[COL4_20:GENERA4]
+Cible verrouillée, chef!
+
+[COL4_21:GENERA4]
+TIREUR D'ELITE!
+
+[COL4_22:GENERA4]
+Je me tire d'ici.
+
+[COL4_23:GENERA4]
+Objectif atteint! Peloton, rompez! -Allons manger quelques beignets!
+
+[COL4_24:GENERA4]
+Protocole de sécurité Delta India Echo déclenché! Autodestruction du véhicule initialisée!
+
+[COL4_26:GENERA4]
+Prépare-toi à crever, ordure communiste!
+
+[COL4_B2:GENERA4]
+~r~Le char est parvenu sans problème à destination!
+
+[COL4_B5:GENERA4]
+~r~Le char est détruit!
+
+[COL4_01:GENERA4]
+Diaz était très content et il veut vous voir.
+
+[COL4_02:GENERA4]
+Et c'est une bonne chose?
+
+[COL4_03:GENERA4]
+Evidemment! Même si je commence à penser que Diaz est responsable de notre malheureuse perte...
+
+[COL4_04:GENERA4]
+Qu'est-ce qui vous fait dire ça?
+
+[COL4_05:GENERA4]
+On n'accuse pas comme ça un homme comme Diaz... Je ne faisais que penser à haute voix...
+
+[COL4_06:GENERA4]
+Quoi qu'il en soit, j'ai une proposition qui devrait vous intéresser...
+
+[COL4_07:GENERA4]
+Je n'ai plus le temps de faire des commissions, Cortez.
+
+[COL4_08:GENERA4]
+J'aurais pensé qu'un homme avec des dettes aussi délicates serait ouvert à toute opportunité. Mais écoutez quand même, Tommy.
+
+[COL4_09:GENERA4]
+Allez-y...
+
+[COL410:GENERA4]
+J'ai un acheteur pour une pièce d'artillerie qui est emmenée à travers la ville. Récupèrez-la pour moi.
+
+[COL411:GENERA4]
+Et une fois que vous l'aurez, je veux que vous m'appeliez de suite, et...
+
+[COL4_B4:GENERA4]
+~g~Le char est verrouillé. Trouve le moyen d'en faire sortir les occupants.
+
+[COL4_1:GENERA4]
+Qu'est-ce qui se passe avec l'artilleur? - Aucune idée, chef!
+
+[COL4_4:GENERA4]
+Montez voir, soldat! - Chef, oui, chef!
+
+[COL4_B1:GENERA4]
+~g~Va faucher la pièce d'artillerie escortée à travers la ville.
+
+[COL4_B3:GENERA4]
+~g~Amène le char dans le garage du colonel avant qu'il ne s'autodétruise.
+
+[COL4_B6:GENERA4]
+~g~Trouve un moyen de piquer le char!
+
+[COL4_B7:GENERA4]
+~g~Conduis le char dans le garage.
+
+[COL4_B8:GENERA4]
+~g~Sors du char et du garage.
+
+{=================================== MISSION TABLE GENERA5 ===================================}
+
+[COL5A_1:GENERA5]
+Les circonstances me forcent à un départ en hâte, amigo.
+
+[COL5A_2:GENERA5]
+Quel est le problème?
+
+[COL5A_3:GENERA5]
+Les français veulent récupérer leur technologie de missile et après le dernier incident,
+
+[COL5A_4:GENERA5]
+je crois que l'heure est venue de me mettre à l'abri.
+
+[COL5A_5:GENERA5]
+Ca serait pas plus sûr de partir en avion ?
+
+[COL5A_6:GENERA5]
+Je serais mort avant d'avoir atteint l'enregistrement. D'ailleurs, il faut que je fasse sortir la marchandise du pays.
+
+[COL5A_7:GENERA5]
+Besoin d'un autre flingue?
+
+[COL5A_8:GENERA5]
+Vous, amigo, vous en valez dix... hahahaha.
+
+[COL5B_1:GENERA5]
+Tommy, vous m'avez bien protégé et servi.
+
+[COL5B_2:GENERA5]
+Mais maintenant, vous devez nous laisser avant qu'on arrive en pleine mer.
+
+[COL5B_4:GENERA5]
+Merci, Colonel.
+
+[COL5B_5:GENERA5]
+Une dernière chose, pendant que je suis parti, pouvez-vous surveiller Mercedes pour moi?
+
+[COL5B_6:GENERA5]
+Je crois qu'elle peut se surveiller tout seule, mais soyez tranquille, je garderai l'oeil ouvert.
+
+[COL5B_7:GENERA5]
+Merci, mon ami. Jusqu'à mon retour.
+
+[COL5B_8:GENERA5]
+Adios, amigo.
+
+[COL5_7:GENERA5]
+Arrêtez de me tirer dessus!
+
+[COL5_9:GENERA5]
+Tommy, empêchez-les de me tirer dessus!
+
+[COL5_10:GENERA5]
+J'ai l'immunité diplomatique!
+
+[COL5_11:GENERA5]
+Ne tirez pas, je suis un Colonel!
+
+[COL5_12:GENERA5]
+Tommy, descendez-les, mon pays vous en sera reconnaissant.
+
+[COL5_13:GENERA5]
+Tommy, on est submergés par les Français!
+
+[COL5_14:GENERA5]
+Tommy, il y a des Français partout! Je déteste ça!
+
+[COL5_15:GENERA5]
+Tommy, comment ça va?
+
+[COL5_16:GENERA5]
+Ca, c'est pour Piaf et Gainsbourg et votre saloperie de pain français!
+
+[COL5_1:GENERA5]
+A bâbord! A bâbord!
+
+[COL5_2:GENERA5]
+Ils attaquent à tribord!
+
+[COL5_3:GENERA5]
+Le pont devant!
+
+[COL5_4:GENERA5]
+Ils ont un hélico!
+
+[COL5_B1:GENERA5]
+~g~Protège le colonel et son yacht à tout prix.
+
+[COL5_B2:GENERA5]
+~g~Passe devant et dégage la route pour le yacht du colonel.
+
+[COL5_B3:GENERA5]
+~r~Le colonel est mort!
+
+[COL5_B4:GENERA5]
+~g~Abats l'hélicoptère vous tire dessus.
+
+[COL5B_3:GENERA5]
+Je vous laisse ma vedette personnelle. Gardez-la en témoignage de ma gratitude!
+
+[COL5_B5:GENERA5]
+~g~Descends les hélicos et protège bien le yacht.
+
+[COL5_B6:GENERA5]
+~g~Tu n'as plus de munitions, va en chercher d'autres dans les escaliers du pont supérieur.
+
+[COL5_B7:GENERA5]
+~g~Ta santé diminue. Régénère-la dans les escaliers du pont supérieur.
+
+{=================================== MISSION TABLE HAIT1 ===================================}
+
+[HAM1_A:HAIT1]
+Bonjour? Y'a quelqu'un?
+
+[HAM1_B:HAIT1]
+Entre, mon petit, et repose ton esprit.
+
+[HAM1_C:HAIT1]
+Tu dois être le grand méchant homme dont m'a parlé mon grand-père.
+
+[HAM1_D:HAIT1]
+Il me dit des choses sur toi, tu sais, quand il me rend visite
+
+[HAM1_E:HAIT1]
+et aussi des choses sur les autres qui t'attendent.
+
+[HAM1_F:HAIT1]
+Bon, nous sommes tous morts depuis longtemps, mais toi,
+
+[HAM1_G:HAIT1]
+je ne voudrais pas être à ta place, hé hé hé!
+
+[HAM1_H:HAIT1]
+J'ai reçu un message. De venir ici.
+
+[HAM1_I:HAIT1]
+Tu les entends?
+
+[HAM1_J:HAIT1]
+Ils crient ton nom, mon garçon, ils doivent vraiment te vouloir, tu ne crois pas?
+
+[HAM1_K:HAIT1]
+Maintenant, si tu rends service à tata Poulet, peut-être qu'elle peut t'aider.
+
+[HAM1_L:HAIT1]
+Peut-être qu'elle peut te donner un petit grigri après tout ça.
+
+[HAM1_M:HAIT1]
+Te donner de la magie pour donner le mauvais oeil au policier, mmmm?
+
+[HAM1_N:HAIT1]
+Ecoute, tout ça est très, hum... me donner quoi?
+
+[HAM1_O:HAIT1]
+Je... Je crois que je me suis planté d'adresse...
+
+[HAM1_P:HAIT1]
+Fais-ça pour moi, Tommy...
+
+[HAM1_Q:HAIT1]
+Les Cubains, ces vilains coqs arrogants, hum,
+
+[HAM1_R:HAIT1]
+ont fait des ennuis à mes adorables garçons haïtiens.
+
+[HAM1_S:HAIT1]
+Et maintenant, ils ont dit au policier où je cachais mes poudres!
+
+[HAM1_T:HAIT1]
+Ils pensent que c'est des drogues, les idiots!
+
+[HAM1_U:HAIT1]
+Alors, sois un gentil garçon, Tommy, et va chercher les poudres de tata Poulet.
+
+[HAM1_V:HAIT1]
+Oui, d'accord, d'accord.
+
+[HAM1_1:HAIT1]
+~g~Les policiers se rapprochent des poudres! Va les récupérer avant eux!
+
+[HAM1_2:HAIT1]
+~r~Les policiers ont trouvé la cachette les premiers!
+
+[HAM1_3:HAIT1]
+~g~Ramène tout ça à la planque!
+
+[HAM1_4:HAIT1]
+~g~Bien! Maintenant, la suivante!
+
+[HAM1_6:HAIT1]
+~r~La cachette a été détruite, imbécile!
+
+[HAM1_7:HAIT1]
+~g~Les policiers ont les poudres! Récupère-les avant qu'ils filent!
+
+[HAM1_8:HAIT1]
+~g~Les flics sont en route pour récupérer les poudres, magne-toi!
+
+[HAT_1A:HAIT1]
+~g~Bouge pas d'un poil, connard!
+
+{=================================== MISSION TABLE HAIT2 ===================================}
+
+[HAT2_B1:HAIT2]
+~g~Va à la camionnette contenant les bombes volantes.
+
+[HAT2_B2:HAIT2]
+Tue les Cubains...
+
+[HAT2_B4:HAIT2]
+... Et détruis leurs bateaux!
+
+[HAT2_B5:HAIT2]
+~g~Les Cubains essayent de s'enfuir! Ne les laisse pas faire!
+
+[HAT2_B6:HAIT2]
+~r~L'avion télécommandé est hors de portée!
+
+[HAT2_B7:HAIT2]
+~g~Un des Cubains s'échappe en voiture. Ne laisse aucun témoin!
+
+[HAT2_B8:HAIT2]
+~r~Tu n'as plus d'avions télécommandés!
+
+[HAT2_B9:HAIT2]
+Avions télécommandés :
+
+[HAT2_1:HAIT2]
+Oh, désolé, j'ai dû me tromper d'adresse...
+
+[HAT2_2:HAIT2]
+Eh bien, entre donc te détendre en buvant un peu de thé.
+
+[HAT2_3:HAIT2]
+Tu as quelque chose pour moi, Tommy?
+
+[HAT2_4:HAIT2]
+Ouais...
+
+[HAT2_5:HAIT2]
+Cet endroit me semble familier. Un vague souvenir d'enfance, un air de déjà vu...
+
+[HAT2_6:HAIT2]
+Tommy, je voudrais te demander de faire une petite commission pour moi...
+
+[HAT2_7:HAIT2]
+Tu me rappelles quelqu'un que...
+
+[HAT2_8:HAIT2]
+Les Cubains ont des bateaux très rapides qui leur servent à traverser les mers avec de la drogue.
+
+[HAT2_9:HAIT2]
+C'est leur gagne-pain.
+
+[HAT2_10:HAIT2]
+Mon neveu a fabriqué quelques bombes volantes pour nous en débarrasser.
+
+[HAT2_11:HAIT2]
+Transforme leurs bateaux en allumettes!
+
+[HAT2_12:HAIT2]
+Bon, merci pour le thé.
+
+[HAT2_B3:HAIT2] { reVC update }
+Appuie sur la touche ~h~~k~~VEHICLE_FIREWEAPON~~w~ pour larguer une bombe ou sur ~h~~k~~VEHICLE_ENTER_EXIT~~w~ pour annuler.
+
+{=================================== MISSION TABLE HAIT3 ===================================}
+
+[HAM3_A:HAIT3]
+Salut, euh, je... Je cherche quelqu'un dans le coin...
+
+[HAM3_B:HAIT3]
+Tu as l'air d'avoir faim, Tommy.
+
+[HAM3_C:HAIT3]
+On se connait?
+
+[HAM3_D:HAIT3]
+Chut!
+
+[HAM3_E:HAIT3]
+Encore une chose et je te laisse partir, Tommy.
+
+[HAM3_F:HAIT3]
+Mes garçons sont en guerre contre les Cubains.
+
+[HAM3_G:HAIT3]
+Mais pas de revolvers.
+
+[HAM3_H:HAIT3]
+Hum, mais les Cubains ont une suprise qui les attend!
+
+[HAM3_I:HAIT3]
+Pendant qu'ils se battent dans les rues, prends ce fusil et tue-les dans la confusion!
+
+[HAM3_J:HAIT3]
+Personne ne te verra, personne ne t'entendra!
+
+[HAM3_K:HAIT3]
+Si tu fais ça pour tata Poulet, Tommy, tu ne seras plus lié aux cordons de mon tablier!
+
+[HAM3_1:HAIT3]
+~g~On doit gagner cette bataille! Si tous les Haïtiens meurent, c'est foutu!
+
+[HAM3_3:HAIT3]
+~g~Les Cubains risquent de tricher, alors fais attention.
+
+[HAM3_4:HAIT3]
+~r~Tu as été repéré! C'est foutu!
+
+[HAM3_5:HAIT3]
+~g~Tu dois tuer les cubains de loin. Ne te fais pas voir.
+
+[HAM3_8:HAIT3]
+~g~Les Haïtiens se font descendre! Vise mieux!
+
+[HAM3_7:HAIT3]
+~g~Fais gaffe! Les Cubains ont amené des renforts. Liquide-les tous!
+
+[HAM3_2:HAIT3]
+~r~Les Haïtiens sont morts!
+
+[HAM3_L:HAIT3]
+Tata...
+
+{=================================== MISSION TABLE HOTEL ===================================}
+
+[INTB_A:HOTEL]
+Tommy! Ca fait une paye!
+
+[INTB_B:HOTEL]
+Salut Sonny...
+
+[INTB_C:HOTEL]
+Je sais, je sais, t'es submergé par l'émotion, hein?
+
+[INTB_D:HOTEL]
+Quinze piges et c'est comme si c'était hier!
+
+[INTB_E:HOTEL]
+C'est une façon de voir les choses...
+
+[INTB_F:HOTEL]
+Hé, bosser pour la famille, tu sais, c'est pas de la tarte,
+
+[INTB_G:HOTEL]
+mais la famille veille toujours sur les siens, tu comprends?
+
+[INTB_H:HOTEL]
+Bon, raconte un peu comment l'affaire s'est passée? Ca y est, t'es blindé?
+
+[INTB_I:HOTEL]
+Ecoute, Sonny, on s'est fait piéger. C'était une embuscade. Et ils ont buté Harry et Lee.
+
+[INTB_J:HOTEL]
+J'espère pour toi que tu rigoles, Tommy... Et t'as plutôt intérêt à toujours avoir le fric...
+
+[INTB_K:HOTEL]
+... Non... Sonny... J'ai plus le fric...
+
+[INTB_L:HOTEL]
+C'était mon fric, Tommy! MON FRIC!!!
+
+[INTB_M:HOTEL]
+Vaudrait mieux pas que t'essayes de me baiser Tommy, parce que je suis pas le genre à aimer ça...
-{ re3 updates }
+[INTB_N:HOTEL]
+Attend Sonny...
+
+[INTB_O:HOTEL]
+Je te donne ma parole d'honneur que je vais récupérer ton fric et la dope.
+
+[INTB_P:HOTEL]
+Et en prime, je t'enverrai les couilles de ceux qui ont fait ça!
+
+[INTB_Q:HOTEL]
+Ca, je le sais déjà... Tommy, t'es pas con, mais je te préviens, moi non plus...
+
+[INTB_R:HOTEL]
+Et si c'était pas toi, tu serais déjà mort...
+
+[INTB_S:HOTEL]
+Mais j'ai un faible pour toi et en souvenir du passé, je vais te laisser t'en charger.
+
+[INTB_T:HOTEL]
+T'en fais pas, Sonny, t'as ma parole!
+
+[INTB_U:HOTEL]
+Je te tiens au courant, ciao.
+
+{=================================== MISSION TABLE ICECRE1 ===================================}
+
+[ICC1_4:ICECRE1]
+~g~Il n'y a aucun client dans ce secteur. Essaye ailleurs.
+
+[ICC1_5:ICECRE1]
+Deals effectués :
+
+[ICC1_7:ICECRE1]
+~g~Tu reçois de l'argent pour chaque transaction faite, mais plus tu fais d'affaires, plus tu attires l'attention de la police.
+
+[ICC1_8:ICECRE1]
+~g~Pour effectuer une transaction, ~h~gare ta camionnette ~g~et appuie sur la ~h~~k~~VEHICLE_HORN~ ~g~pour jouer le jingle et attirer les clients.
+
+[ICC1_9:ICECRE1]
+~g~Les gangs locaux n'apprécient pas qu'on fasse des affaires sur leur territoire. Attends-toi à des représailles.
+
+[ICC1_10:ICECRE1]
+~g~Tu as fait ~1~ deals!
+
+[ICC1_11:ICECRE1]
+~g~Tu as fait ~1~ deals!
+
+[ICC1_13:ICECRE1]
+~r~T'as fait aucun deal!
+
+[ICC1_14:ICECRE1]
+USINE DE CREME GLACEE OK
+
+[ICC1_15:ICECRE1]
+~g~L'usine de crème glacée génère dorénavant un revenu de $~1~ maximum. Pense à récupérer le fric régulièrement.
+
+[ICC1_16:ICECRE1]
+~g~Utilise la camionnette de Mr Whoopee pour distribuer les produits Cherry Poppers dans Vice City.
+
+[ICE_AT1:ICECRE1]
+USINE DE CREME GLACEE OK
+
+[ICE_AT2:ICECRE1]
+~g~L'usine Cherry Popper génère dorénavant un revenu de $~1~ maximum. Pense à récupérer le fric régulièrement.
+
+[ICC1_17:ICECRE1]
+Mission Distribution terminée
+
+[ICC1_18:ICECRE1]
+Total des ventes de glaces : $~1~
+
+[ICC1_19:ICECRE1]
+Total de deals réalisés : ~1~
+
+{=================================== MISSION TABLE ICECUT ===================================}
+
+[ICC1_A:ICECUT]
+T'es qui toi?
+
+[ICC1_B:ICECUT]
+Le nouveau proprio.
+
+[ICC1_C:ICECUT]
+Est-ce que t'as déjà été enfant?
+
+[ICC1_D:ICECUT]
+Mais de quoi tu parles?
+
+[ICC1_E:ICECUT]
+As-tu été un gosse?
+
+[ICC1_F:ICECUT]
+Ouais! Vas-y, c'est quoi ton problème?
+
+[ICC1_G:ICECUT]
+Je le savais. Un chiard.
+
+[ICC1_H:ICECUT]
+Un putain de gosse pourri gâté, un chialeur, un emmerdeur, un bébé à sa maman!
+
+[ICC1_I:ICECUT]
+Un bébé... Un horrible et dégoûtant petit morveux. Ouin ouin.
+
+[ICC1_J:ICECUT]
+Ta maman t'aime pas. Petite merde!
+
+[ICC1_K:ICECUT]
+Hé! Calme-toi.
+
+[ICC1_L:ICECUT]
+Je HAIS les mouflets et les mômes.
+
+[ICC1_M:ICECUT]
+Ce sont des putains de pourris gâtés, de chialeurs, d'emmerdeurs...
+
+[ICC1_N:ICECUT]
+Ca suffit maintenant!
+
+[ICC1_O:ICECUT]
+C'est quoi ton problème?
+
+[ICC1_P:ICECUT]
+Tu confectionnes des glaces, non? C'est un truc pour les gosses.
+
+[ICC1_Q:ICECUT]
+T'es quoi comme genre de cinglé, toi?
+
+[ICC1_R:ICECUT]
+Que je comprenne... A quoi ça sert de rendre les gosses heureux si tu les déteste?
+
+[ICC1_S:ICECUT]
+Espèce d'abruti, petit curieux, fouinard-
+
+[ICC1_T:ICECUT]
+La ferme!
+
+[ICC1_U:ICECUT]
+-de merde!
+
+[ICC1_V:ICECUT]
+Les glaces c'est une couverture.
+
+[ICC1_W:ICECUT]
+On fait aussi dans autre chose que les produits laitiers.
+
+[ICC1_X:ICECUT]
+Et si je vois un gosse, j'en fait mon affaire.
+
+[ICC1_Y:ICECUT]
+N'est-ce pas, gamin? Ouais, c'est bien ça. Ta maman t'aime pas.
+
+[ICC1_Z:ICECUT]
+Elle te DETESTE!
+
+[ICC1_ZA:ICECUT]
+PROPRIETE ACQUISE!
+
+{=================================== MISSION TABLE INTRO ===================================}
+
+[INT1_A:INTRO]
+Tommy Vercetti... Oh, merde!
+
+[INT1_B:INTRO]
+J'pensais pas qu'ils le laisseraient sortir un jour...
+
+[INT1_C:INTRO]
+Il a gardé un profil bas, pour se faire oublier...
+
+[INT1_D:INTRO]
+Mais les gens vont vite retrouver la mémoire
+
+[INT1_E:INTRO]
+quand ils vont le voir débouler dans les rues du voisinage.
+
+[INT1_F:INTRO]
+Et ça va pas être bon pour les affaires...
+
+[INT1_G:INTRO]
+Et alors, qu'est-ce qu'on va faire, Sonny?
+
+[INT1_H:INTRO]
+On le traite comme un vieil ami et on lui trouve de quoi s'occuper en-dehors de la ville. OK?
+
+[INT1_I:INTRO]
+On parlait justement de s'étendre vers le sud... Pas vrai?
+
+[INT1_J:INTRO]
+Vice City, c'est du 24 carats, maintenant.
+
+[INT1_K:INTRO]
+Les colombiens, les mexicains... Putain,
+
+[INT1_L:INTRO]
+même les réfugiés cubains se taillent une belle part du gâteau!
+
+[INT1_M:INTRO]
+Mais ils font tous dans la dope, Sonny!
+
+[INT1_N:INTRO]
+Aucune famille ne touche à cette merde!
+
+[INT1_O:INTRO]
+Les temps changent...
+
+[INT1_P:INTRO]
+Les familles ne peuvent pas rester les bras croisés pendant que nos adversaires ramassent le jackpot.
+
+[INT1_Q:INTRO]
+Alors, on envoie un mec là-bas faire le sale boulot
+
+[INT1_R:INTRO]
+et pour nous en tailler une bonne part. OK?
+
+[INT1_S:INTRO]
+C'est qui, notre contact là-bas?
+
+[INT1_T:INTRO]
+Ken Rosenberg, le con d'avocat...
+
+[INT1_U:INTRO]
+Et comment il va faire pour tenir Vercetti en laisse?
+
+[INT1_V:INTRO]
+Il aura pas besoin de faire ça.
+
+[INT1_W:INTRO]
+On le lâche juste dans Vice City
+
+[INT1_X:INTRO]
+et on lui refile un peu de cash pour commencer. OK?
+
+[INT1_Y:INTRO]
+Donne-lui quelques mois...
+
+[INT1_Z:INTRO]
+Et puis, on descendra
+
+[INT1_A1:INTRO]
+lui rendre une petite visite, tu saisis?
+
+[INT1_A2:INTRO]
+Histoire de voir comment il se débrouille...
+
+[INT2_A:INTRO]
+Hey, salut les gars, c'est moi, Ken Rosenberg! Hé ! Super!
+
+[INT2_B:INTRO]
+Bon, euh, je vais vous conduire au rendez-vous, ok?
+
+[INT2_C:INTRO]
+J'ai parlé avec les fournisseurs, ils sont très, hé hé,
+
+[INT2_D:INTRO]
+très impatients de commencer cette affaire, et... euh,
+
+[INT2_E:INTRO]
+si tout se passe sans accroc, on devrait... euh,
+
+[INT2_F:INTRO]
+s'en mettre plein les poches, ce qui est vraiment, vous savez...
+
+[INT2_G:INTRO]
+une bonne chose...
+
+[INT2_H:INTRO]
+Ok. Bon, ils sont frères, ok.
+
+[INT2_I:INTRO]
+Il y en a un qui fait marcher... euh, l'affaire
+
+[INT2_J:INTRO]
+et l'autre qui s'occupe du transport en hélicoptère.
+
+[INT2_K:INTRO]
+Maintenant, ils opèrent du Mexique,
+
+[INT3_A:INTRO]
+Ok, c'est eux, dans l'hélico.
+
+[INT3_B:INTRO]
+Bon, voilà le deal.
+
+[INT3_C:INTRO]
+Ils veulent un échange en terrain découvert.
+
+[INT3_D:INTRO]
+OK? Bon, allons-y et restez groupés.
+
+[INT3_E:INTRO]
+Bon, personne s'énerve, maintenant.
+
+[INT3_F:INTRO]
+Je suis ici! Le moteur tourne!
+
+[INT3_G:INTRO]
+Tu l'as?
+
+[INT3_H:INTRO]
+De la colombienne 100% pure, la meilleure qualité, amigo.
+
+[INT3_I:INTRO]
+Les billets?
+
+[INT3_J:INTRO]
+Des 10 et des 20... usagés.
+
+[INT3_L:INTRO]
+Allez! Sors-nous de là! Roule!
+
+[INTRO1:INTRO]
+Je sors la tête d'un caniveau pour une seconde de défonce, et le destin me chie de la merde plein la gueule!
+
+[INTRO2:INTRO]
+Va roupiller.
+
+[INTRO3:INTRO]
+Qu'est-ce que tu vas faire?
+
+[INTRO4:INTRO]
+Je passerai à ton bureau demain et on essayera de trouver une solution à ce merdier.
+
+[INT3_K:INTRO]
+Je crois que nous allons faire affaire, amigo, hé hé hé!
+
+[INT3_M:INTRO]
+Laisse-moi voir.
+
+[INT2_L:INTRO]
+non, non, non, attends...
+
+{=================================== MISSION TABLE KENT1 ===================================}
+
+[KPM1_A:KENT1]
+D'accord, mon vieux, je vais sauver ton petit ami.
+
+[KPM1_B:KENT1]
+De quoi tu m'causes?
+
+[KPM1_C:KENT1]
+Tu connais ce branleur, Diaz, la grande gueule...
+
+[KPM1_D:KENT1]
+Il a ton pote, Lance. Il paraît que celui-ci a essayé de lui sauter sur le poil.
+
+[KPM1_E:KENT1]
+Mais il a pas sauté assez haut, si tu vois ce que je veux dire...
+
+[KPM1_F:KENT1]
+Où il l'a emmené? Et tourne pas autour du pot!
+
+[KPM1_G:KENT1]
+T'énerve pas! Ils l'ont emmené de l'autre côté de la ville, à la décharge.
+
+[KPM1_H:KENT1]
+Putain... Pauvre cinglé...
+
+[KPM1_2:KENT1]
+~r~Tu étais supposé sortir Lance vivant de ce guêpier!
+
+[KPM1_3:KENT1]
+SANTE DE LANCE :
+
+[RESC_1:KENT1]
+Tu peux te servir d'un flingue?
+
+[RESC_2:KENT1]
+Ouais... je pense... Content de te voir moi aussi.
+
+[RESC_3:KENT1]
+Sortons de là!
+
+[RESC_4:KENT1]
+Ca fout tous mes plans en l'air, tes conneries. Cette fois-ci, t'as vraiment merdé pour de bon, Lance!
+
+[RESC_5:KENT1]
+Il a descendu mon frère! Tu croyais que j'allais faire quoi? Lui tondre sa pelouse?
+
+[RESC_6:KENT1]
+Va falloir qu'on liquide ce connard de Diaz avant qu'il en fasse autant avec nous.
+
+[RESC_7:KENT1]
+Va récupérer et retrouve-moi sur le pont de Star Island. Ok?
+
+[RESC_8:KENT1]
+OK.
+
+[KPM1_1:KENT1]
+~g~Lance est retenu prisonnier dans la décharge. Va le sauver!
+
+[KPM1_4:KENT1]
+~g~Amène Lance à l'hosto!
+
+[M_PASSN:KENT1]
+MISSION TERMINEE!
+
+[KPM1_5:KENT1]
+~g~Les mecs de Diaz sont après toi, amène Lance à l'hosto.
+
+{=================================== MISSION TABLE KICKSTT ===================================}
+
+[KICK1_2:KICKSTT]
+~r~Tu n'as pas récupéré la moto assez vite!
+
+[KICK1_7:KICKSTT]
+~r~Tu as niqué la moto!
+
+[KICK1_8:KICKSTT]
+~g~Monte sur la moto!
+
+[KICK1_T:KICKSTT]
+TEMPS PRIS :
+
+[KICKTM:KICKSTT]
+~b~TEMPS DE L'EPREUVE : ~1~:~1~
+
+[KICKTM2:KICKSTT]
+~b~TEMPS DE L'EPREUVE : ~1~:0~1~
+
+[GETBIKE:KICKSTT]
+~g~Il te reste ~1~ secondes pour retourner à une moto avant la fin de la mission.
+
+[KICK1_1:KICKSTT]
+~g~Termine le parcours aussi vite que possible.
+
+[KICK1_6:KICKSTT]
+~g~Bien joué!
+
+[KICK_10:KICKSTT]
+~g~Utilise la Sanchez pour terminer le parcours sans oublier aucun point de passage.
+
+[KICK_12:KICKSTT]
+~r~Tu t'es dégonflé!
+
+[KICK_13:KICKSTT]
+~r~T'as mis trop de temps!
+
+[KICK_11:KICKSTT]
+~g~Pour quitter la mission, marche sur le ~q~marqueur rose~g~.
+
+{=================================== MISSION TABLE LAWYER1 ===================================}
+
+[LAW1_A:LAWYER1]
+Va roupiller, qu'il m'a dit -
+
+[LAW1_B:LAWYER1]
+- et je suis resté toute la nuit le cul vissé sur cette chaise dans le noir à boire du café!
+
+[LAW1_C:LAWYER1]
+C'est la merde. On est baisés jusqu'à l'os, mon pote!
+
+[LAW1_D:LAWYER1]
+Ecoute-moi, ces balaises, ils vont débarquer ici pour m'arracher la tête! C'est pas possible!
+
+[LAW1_E:LAWYER1]
+J'me suis pas tapé l'école de droit pour ça! Putain, qu'est-ce qu'on va faire maintenant?
+
+[LAW1_F:LAWYER1]
+Ferme-la, pose ton cul et détends-toi. Je vais te dire ce qu'on va faire.
+
+[LAW1_G:LAWYER1]
+Faut que tu trouves les types qui nous ont fauché la coke et après je les descends.
+
+[LAW1_H:LAWYER1]
+Bonne idée. Excellente idée. Laisse-moi réfléchir, laisse-moi réfléchir.
+
+[LAW1_I:LAWYER1]
+Je sais! Il y a ce Colonel à la retraite, le Colonel Juan Garcia Cortez.
+
+[LAW1_J:LAWYER1]
+C'est lui qui m'a aidé à organiser l'affaire
+
+[LAW1_K:LAWYER1]
+en-dehors des truands établis de Vice City. Ok?
+
+[LAW1_L:LAWYER1]
+Maintenant, écoute. Il organise une fiesta dans la baie, sur son yatch du luxe
+
+[LAW1_M:LAWYER1]
+et tous les gros pontes de Vice City seront là!
+
+[LAW1_N:LAWYER1]
+J'ai une invitation, bien sûr que j'ai une invitation,
+
+[LAW1_O:LAWYER1]
+mais il est pas question que je sorte d'ici. Non, pas question!
+
+[LAW1_P:LAWYER1]
+Ferme-la, je t'ai dit! Je vais y aller moi-même...
+
+[LAW1_Q:LAWYER1]
+Attends deux secondes! Tu sais, moi aussi, j'aime bien 1978, mais là, c'est pas une soirée bière et striptease...
+
+[LAW1_R:LAWYER1]
+Je veux dire, sans vouloir t'offenser, hein, tu risque de te faire refouler à l'entrée, quoi...
+
+[LAW1_S:LAWYER1]
+Y'a un problème avec mes fringues?
+
+[LAW1_T:LAWYER1]
+Bon, écoute. Fais un saut chez Rafael, dis-lui que tu viens de ma part et il te relookera.
+
+[LAW1_U:LAWYER1]
+Ok, allez, vas-y...
+
+[LAWP_1:LAWYER1]
+Buenas noches.
+
+[LAWP_2:LAWYER1]
+Si je comprends bien, c'est M. Rosenberg qui vous envoie.
+
+[LAWP_3:LAWYER1]
+J'espère que de récents problèmes n'ont pas affecté sa santé, ou ... hum...
+
+[LAWP_4:LAWYER1]
+son équilibre mental, M....?
+
+[LAWP_5:LAWYER1]
+Vercetti. Il fait simplement un peu... d'agoraphobie.
+
+[LAWP_6:LAWYER1]
+Excellent, excellent. Et vous?
+
+[LAWP_7:LAWYER1]
+Je veux juste ma marchandise.
+
+[LAWP_8:LAWYER1]
+Ah. C'est un malheureux concours de circonstances pour toutes les personnes impliquées...
+
+[LAWP_9:LAWYER1]
+Bien entendu, j'ai de mon côté ordonné une enquête...
+
+[LAWP_10:LAWYER1]
+Mais c'est un problème délicat qui nécessite du temps...
+
+[LAWP_11:LAWYER1]
+Peut-être en reparlerons-nous plus tard, voulez-vous?
+
+[LAWP_12:LAWYER1]
+En attendant, laissez-moi vous présenter ma fille...
+
+[LAWP_13:LAWYER1]
+Mercedes!
+
+[LAWP_14:LAWYER1]
+Caramia, pourrais-tu t'occuper de notre invité pendant que je m'occupe des autres convives?
+
+[LAWP_15:LAWYER1]
+D'accord, papa.
+
+[LAWP_16:LAWYER1]
+Veuillez m'excuser...
+
+[LAWP_17:LAWYER1]
+Mercedes?
+
+[LAWP_18:LAWYER1]
+Et il faut vivre avec ça...
+
+[LAWP_19:LAWYER1]
+Quoi qu'il en soit, laissez-moi vous montrer quelques uns de nos distingués invités...
+
+[LAWP_20:LAWYER1]
+Celui-ci est le membre du congrès Alex Shrub accompagné par la star montante siliconée Candy Suxxx...
+
+[LAWP_21:LAWYER1]
+Et connaissez-vous ma charmante femme Laura? Non?
+
+[LAWP_22:LAWYER1]
+Eh bien, malheureusement, elle est en Alabama, voici Candy.
+
+[LAWP_23:LAWYER1]
+Et là-bas, nous avons l'ailier vedette des Mambas de Vice City, BJ.
+
+[LAWP_24:LAWYER1]
+toujours aussi charmeur
+
+[LAWP_25:LAWYER1]
+Mais je l'ai plaqué et mis dans une chaise roulante!
+
+[LAWP_26:LAWYER1]
+Ha ha! Excellent!
+
+[LAWP_27:LAWYER1]
+En ce moment, je cherche une nouvelle propriété de luxe.
+
+[LAWP_28:LAWYER1]
+Et ce molusque c'est Jezz Torrent,
+
+[LAWP_29:LAWYER1]
+Le chanteur principal des Love Fist.
+
+[LAWP_30:LAWYER1]
+Savez-vous... comment ils jouent au ping-pong, en Thaïlande?
+
+[LAWP_31:LAWYER1]
+Je vais vous le dire...
+
+[LAWP_32:LAWYER1]
+Ils n'utilisent pas de raquettes, si vous voyez ce que je veux dire!
+
+[LAWP_33:LAWYER1]
+L'impotent.
+
+[LAWP_34:LAWYER1]
+Et le trio bavard.
+
+[LAWP_35:LAWYER1]
+Cette outre à sueur ronflante est le bras droit handicapé de papa, Gonzales.
+
+[LAWP_36:LAWYER1]
+Les deux autres sont le Pasteur Richards
+
+[LAWP_37:LAWYER1]
+et un réalisateur pseudo intellectuel nommé Steve Scott.
+
+[LAWP_38:LAWYER1]
+...passion avec les envahisseuses nymphomanes,
+
+[LAWP_39:LAWYER1]
+Le requin géant s'amène et
+
+[LAWP_40:LAWYER1]
+il leur bouffe simplement les couilles!
+
+[LAWP_41:LAWYER1]
+Ah, c'est là. Vous n'avez jamais vu un truc pareil avant, hein?
+
+[LAWP_42:LAWYER1]
+Colonel!
+
+[LAWP_43:LAWYER1]
+Vos fêtes sont toujours aussi réussies, hahahahha!
+
+[LAWP_44:LAWYER1]
+Je ne puis que m'excuser de mon arrivée tardive.
+
+[LAWP_45:LAWYER1]
+Ah, de nada amigo. Comment allez-vous?
+
+[LAWP_46:LAWYER1]
+Nos affaires sont très difficile - Les barbares sont aux portes de la ville.
+
+[LAWP_47:LAWYER1]
+L'heure est venue de récompenser les amis et de liquider les ennemis, amigo.
+
+[LAWP_48:LAWYER1]
+C'est qui, la grande gueule?
+
+[LAWP_49:LAWYER1]
+Ricardo Diaz, c'est Mr.Coke.
+
+[LAWP_50:LAWYER1]
+Mercedes!
+
+[LAWP_51:LAWYER1]
+Oh, je raccompagnais justement mon ami en ville.
+
+[LAWP_52:LAWYER1]
+Une autre fois, Ricardo!
+
+[LAWP_53:LAWYER1]
+Partons d'ici!
+
+[LAWP_54:LAWYER1]
+En fait, emmenez-moi plutôt au Pole Position club.
+
+[LAW1_2:LAWYER1]
+~g~Va au yatch du Colonel.
+
+[LAW1_4:LAWYER1]
+~r~Tu as tué la fille du Colonel!
+
+[LAW1_5:LAWYER1]
+Vous allez travailler pour mon père?
+
+[LAW1_6:LAWYER1]
+Peut-être.
+
+[LAW1_7:LAWYER1]
+Ca vous ennuie si je pose ma main sur votre genou?
+
+[LAW1_8:LAWYER1]
+Peut-être...
+
+[LAW1_9:LAWYER1]
+C'est trop dur d'avoir un père riche et puissant! Vamos!
+
+[LAW1_10:LAWYER1]
+A plus tard, mon mignon!
+
+[LAW1_11:LAWYER1]
+Sans aucun doute.
+
+[LAW1_12:LAWYER1]
+Mmmm... Chouette bécane.
+
+[LAW1_13:LAWYER1]
+Non! Ma moto!
+
+[LAW1_3:LAWYER1]
+~g~Emmène la fille du Colonel au Pole Position Club.
+
+[HELP20:LAWYER1]
+Suis le ~h~point T-shirt~w~ sur le radar pour trouver Rafael.
+
+[LAW1_14:LAWYER1]
+Mmmm, j'aime beaucoup ta grosse moto.
+
+[LAW1_15:LAWYER1]
+Ouais, bébé, je viens de piquer ça à ce con
+
+{=================================== MISSION TABLE LAWYER2 ===================================}
+
+[LAW2_A:LAWYER2]
+Ah! Eh bien, j'espère que tu t'es bien amusé! Parce que moi, je suis mort d'inquiétude! Qu'est-ce que t'as trouvé?
+
+[LAW2_B:LAWYER2]
+Qu'y'a plus de criminels dans cette ville qu'en taule. Faut qu'on trouve une piste dans la rue.
+
+[LAW2_C:LAWYER2]
+Attends, laisse-moi réfléchir, voyons...
+
+[LAW2_D:LAWYER2]
+Ah! J'ai trouvé!
+
+[LAW2_E:LAWYER2]
+Bon, il y a bien cet anglais, une espèce de déchet du biz de la musique,
+
+[LAW2_F:LAWYER2]
+il est connu sous le nom de Kent Paul.
+
+[LAW2_G:LAWYER2]
+Quoi qu'il en soit, il a le nez plongé dans la merde de Vice City depuis un moment
+
+[LAW2_H:LAWYER2]
+et ça, si quelqu'un sait où sont les 20 kilos de coke,
+
+[LAW2_I:LAWYER2]
+c'est bien lui, ok? Il est toujours fourré au Malibu...
+
+[LAW2_J:LAWYER2]
+Je vais aller lui rendre une petite visite...
+
+[LAW2B_A:LAWYER2]
+D'où tu sors, toi?
+
+[LAW2B_B:LAWYER2]
+Je cherche un oiseau dans ton genre depuis une éternité...
+
+[LAW2B_C:LAWYER2]
+Kent Paul, mon pote. Ouais, dans le coin, c'est moi le patron.
+
+[LAW2B_D:LAWYER2]
+Je cherche un Anglais...
+
+[LAW2B_E:LAWYER2]
+Je résouds les problèmes, si tu vois ce que je veux dire?
+
+[LAW2B_F:LAWYER2]
+Je vais m'occuper de toi. Quoi que tu demandes, tu l'auras...
+
+[LAW2B_G:LAWYER2]
+Ne t'inquiéte absolument de rien.
+
+[LAW2B_H:LAWYER2]
+Dégage, chérie!
+
+[LAW2B_I:LAWYER2]
+Hé hé hé hé hé!
+
+[LAW2B_J:LAWYER2]
+C'est toi, Kent Paul? Je suis un pote de Rosenberg...
+
+[LAW2B_K:LAWYER2]
+Rosenberg...Rosenberg... Ah, ce cinglé qui poursuit les ambulances!
+
+[LAW2B_L:LAWYER2]
+Ce mec peut défendre un innocent jusqu'au couloir de la mort!
+
+[LAW2B_M:LAWYER2]
+Donne-nous un autre verre!
+
+[LAW2B_N:LAWYER2]
+On est tous des comédiens.
+
+[LAW2B_O:LAWYER2]
+Ecoute-moi, il me manque vingt kilos et un gros tas de pognon...
+
+[LAW2B_P:LAWYER2]
+Une affaire de drogue? C'est toujours des pièges à con...
+
+[LAW2B_Q:LAWYER2]
+Qu'est-ce que tu sais à ce propos?
+
+[LAW2B_R:LAWYER2]
+Hé! Hé! Là où je voulais en venir,
+
+[LAW2B_S:LAWYER2]
+c'est à un cuisinier-trompettiste qui deale à l'extérieur de la cuisine d'un hôtel sur Ocean Drive.
+
+[LAW2B_T:LAWYER2]
+Il avait l'air très content de lui, ces derniers temps. Tu pourrais peut-être aller voir ça de plus près...
+
+[LAW2B_U:LAWYER2]
+Bon, je vais y aller. A plus tard.
+
+[LAW2B_V:LAWYER2]
+Ouais, c'est ça. Allez, dégage, imbécile ou je te botte le cul!
+
+[LAW2B_W:LAWYER2]
+Donne-moi à boire et putain, où est cette salope?
+
+[LAW2C_A:LAWYER2]
+Ouais, c'est bien, massacre-le, ça devrait le rendre plus bavard.
+
+[LAW2C_B:LAWYER2]
+T'en veux aussi?
+
+[LAW2C_C:LAWYER2]
+Hé, relax, je veux la même chose que toi, mon frère.
+
+[LAW2C_D:LAWYER2]
+Ah ouais? Et c'est quoi?
+
+[LAW2C_E:LAWYER2]
+Ton fric et la blanche de mon regretté frère. Malheureusement, tu viens de refroidir notre piste.
+
+[LAW2C_F:LAWYER2]
+C'était un accident. Dégage.
+
+[LAW2C_G:LAWYER2]
+Hé, hé! Pas la peine de jouer les justiciers solitaires avec moi!
+
+[LAW2C_H:LAWYER2]
+Voilà comment je vois les choses... On est deux mecs dans une ville étrange. Et on a besoin de veiller l'un sur l'autre.
+
+[LAW2C_I:LAWYER2]
+J'ai pas besoin de toi, mon frère...
+
+[LAW2C_J:LAWYER2]
+T'en es sûr? Tiens, attrape!
+
+[LAW2C_K:LAWYER2]
+Suis-moi!
+
+[LAW2_1:LAWYER2]
+Qu'est-ce que tu regardes?
+
+[LAW2_2:LAWYER2]
+Tu ferais mieux de commencer à causer...
+
+[LAW2_3:LAWYER2]
+Suce-moi, connard!
+
+[LAW2_4:LAWYER2]
+Par là!
+
+[LAW2_5:LAWYER2]
+Je vais voir ce que je peux trouver. Je garde un oeil sur toi, Tommy.
+
+[LAW2_6:LAWYER2]
+~g~Va au Malibu Club et trouve Kent Paul.
+
+[LAW2_7:LAWYER2]
+~g~Trouve le cuisinier sur Ocean Drive.
+
+[LAW2_10:LAWYER2]
+~g~Retourne à l'hôtel.
+
+[LAW2_11:LAWYER2]
+~g~Ramasse son portable!
+
+[LAW2_12:LAWYER2]
+Portable acquis! Tu peux maintenant recevoir des coups de fil.
+
+[LAW2_13:LAWYER2]
+~g~Tu as laissé Lance derrière! Va le chercher!
+
+[LAW2_14:LAWYER2]
+On doit foutre le camp d'ici!
+
+[GUN_2A:LAWYER2]
+Maintiens la ~h~~k~~PED_LOCK_TARGET~ ~w~enfoncée pour ~h~viser automatiquement~w~. Appuie sur la~h~ ~k~~PED_FIREWEAPON~~w~ pour ~h~tirer!
+
+[GUN_2C:LAWYER2]
+Maintiens la ~h~~k~~PED_LOCK_TARGET~ ~w~enfoncée pour ~h~viser automatiquement~w~. Appuie sur la~h~ ~k~~PED_FIREWEAPON~~w~ pour ~h~tirer!
+
+[GUN_2D:LAWYER2]
+Maintiens la ~h~~k~~PED_LOCK_TARGET~ ~w~enfoncée pour ~h~viser automatiquement~w~. Appuie sur la~h~ ~k~~PED_FIREWEAPON~~w~ pour ~h~tirer!
+
+[HELP17:LAWYER2]
+Appuie sur la~h~ ~k~~PED_FIREWEAPON~ ~w~pour attaquer le chef.
+
+[HELP18:LAWYER2]
+Appuie sur la~h~ ~k~~PED_FIREWEAPON~~w~ pour attaquer le chef.
+
+[LAW3_11:LAWYER2]
+Place-toi sur le ~q~marqueur rose~w~ pour consulter les armes en vente.
+
+[LAW3_12:LAWYER2]
+Tu peux sélectionner des armes en appuyant sur ~h~gauche~w~ ou ~h~droite~w~ de la ~h~touche directionnelle.
+
+[LAW3_13:LAWYER2]
+Si tu as assez de blé, tu peux acheter des armes en appuyant sur la ~h~~k~~PED_SPRINT~.
+
+[LAW3_14:LAWYER2]
+Tu peux sortir du magasin en appuyant sur la ~h~~k~~VEHICLE_ENTER_EXIT~.
+
+[LAW3_15:LAWYER2]
+Suis le ~h~point pistolet~w~ sur le radar pour trouver ~h~Ammu-Nation
+
+[LAW2_15:LAWYER2]
+~g~Va chez Ammu-Nation.
+
+[LAW2_K:LAWYER2]
+calme-toi, maintenant.
+
+[LAW2_16:LAWYER2]
+Il faut que tu comprennes un truc sur cette ville. Tu dois toujours avoir un flingue sur toi.
+
+[LAW2_17:LAWYER2]
+Allez, l'armurerie du coin n'est qu'à quelques pas d'ici.
+
+[LAW2_18:LAWYER2]
+Tommy, tout le monde a besoin de se la couler douce de temps en temps.
+
+[LAW2_19:LAWYER2]
+Voici le Pole Position Strip Club. Tu pourrais y passer de temps en temps.
+
+{=================================== MISSION TABLE LAWYER3 ===================================}
+
+[LAW3_A:LAWYER3]
+Aaaaaah! Oh, nom de Dieu, c'est toi! Merde, je vais avoir besoin d'un nouveau pantalon!
+
+[LAW3_B:LAWYER3]
+Putain, ces psychopathes du nord ont téléphoné pour dire qu'ils rappliquaient bientôt...
+
+[LAW3_C:LAWYER3]
+Alors, où est ce sacré pognon?
+
+[LAW3_D:LAWYER3]
+Relax, relax, on n'en est pas encore là.
+
+[LAW3_E:LAWYER3]
+Je croyais vraiment que tu t'en occupais...
+
+[LAW3_F:LAWYER3]
+Et maintenant, ces mecs disent qu'il faut qu'on leur rende un service...
+
+[LAW3_G:LAWYER3]
+Tu veux dire que JE dois leur rendre un service...
+
+[LAW3_H:LAWYER3]
+Ouais, évidemment! Est-ce que j'ai l'air de pouvoir impressionner un jury?
+
+[LAW3_I:LAWYER3]
+Je ne pourrais même pas faire peur à un gosse et crois-moi, j'ai essayé!
+
+[LAW3_J:LAWYER3]
+Maintenant, écoute, c'est ça ou le cousin de Forelli, Georgio, se prend cinq ans pour escroquerie.
+
+[LAW3_K:LAWYER3]
+Faut que tu t'occupes de ces mecs!
+
+[LAW3_L:LAWYER3]
+Je comprends. Demander au jury de changer d'opinion. T'en fais pas.
+
+[LAW3_M:LAWYER3]
+Non non non non! Ca, j'ai déjà essayé! Et l'affaire ne s'est pas arrangée!
+
+[LAW3_N:LAWYER3]
+Tu dois les OBLIGER à changer d'opinion!
+
+[LAW3_1:LAWYER3]
+Avec les compliments de Georgio...
+
+[LAW3_2:LAWYER3]
+N'oublie pas que le mot 'coupable' est proscrit!
+
+[LAW3_3:LAWYER3]
+Il est innocent, jusqu'à ce que je dise le contraire.
+
+[LAW3_4:LAWYER3]
+Tu sais qu'il n'est pas coupable...
+
+[LAW3_5:LAWYER3]
+Tu te souviens de Georgio? Et donc qu'il est innocent?
+
+[LAW3_6:LAWYER3]
+Non coupable. C'est compris... bien.
+
+[LAW3_8:LAWYER3]
+~r~Tu as tué un juré!
+
+[LAW3_9:LAWYER3]
+~g~Bousille la voiture du juré pour le faire sortir!
+
+[HELP40:LAWYER3]
+Tu peux bousiller les voitures avec le marteau ou un outil similaire.
+
+[LAW3_10:LAWYER3]
+~g~Tu peux aller à la ~h~quincaillerie~g~ pour acheter une arme de corps à corps.
+
+[LAW3_20:LAWYER3]
+~g~Bousille la voiture du juré!
+
+[LAW3_21:LAWYER3]
+Je n'arrive pas à le croire!
+
+[LAW3_22:LAWYER3]
+Incroyable!
+
+[LAW3_23:LAWYER3]
+Ok! C'est bon, j'ai compris!
+
+[LAW3_24:LAWYER3]
+~g~Ce marteau pourrait être utile.
+
+[LAW3_7:LAWYER3]
+~g~Va intimider les deux jurés, mais NE LES TUE PAS!
+
+[HELP23:LAWYER3]
+Tu peux suivre le ~h~marteau~w~ sur le radar si tu veux acheter des armes de corps à corps dans la quincaillerie.
+
+[LAW3_16:LAWYER3]
+de Pete de Floride.
+
+[LAW3_17:LAWYER3]
+Casse-toi de là!
+
+{=================================== MISSION TABLE LAWYER4 ===================================}
+
+[LAW4_A:LAWYER4]
+Avery, cela va sans dire... Ah, Tommy! Des nouvelles? Non, non, tu m'en parleras plus tard. Plus tard.
+
+[LAW4_B:LAWYER4]
+Tommy, voici Avery Carrington. Je crois que vous vous êtes rencontrés à la fête?
+
+[LAW4_C:LAWYER4]
+Pas directement.
+
+[LAW4_D:LAWYER4]
+Salut.
+
+[LAW4_E:LAWYER4]
+Avery a une proposition à nous faire.
+
+[LAW4_F:LAWYER4]
+On a pas déjà du pain sur la planche?
+
+[LAW4_G:LAWYER4]
+J'essaye de maintenir les loups au loin, alors lâche-moi un peu la grappe!
+
+[LAW4_H:LAWYER4]
+Je suis tendu comme un cable et même si je dois crever avant la fin de la semaine, j'ai pas envie de mourir pauvre!
+
+[LAW4_I:LAWYER4]
+Bon, vous énervez pas, tous les deux.
+
+[LAW4_J:LAWYER4]
+Ecoute, petit, tu me files un coup de main et le moindre latino qui te fait chier, je m'occupe de lui.
+
+[LAW4_K:LAWYER4]
+Ok, qu'est-ce que je peux faire pour toi?
+
+[LAW4_L:LAWYER4]
+Cette société de livraison a son dépôt sur un terrain très intéressant. Et ils ne veulent pas vendre.
+
+[LAW4_M:LAWYER4]
+Ils s'accrochent à leur terrain comme des rats entêtés, alors va falloir exploser cette vermine.
+
+[LAW4_N:LAWYER4]
+Va là-bas et mets le feu aux poudres.
+
+[LAW4_O:LAWYER4]
+La sécurité sera débordée et tu pourras te glisser dedans et en finir avec eux...
+
+[LAW4_P:LAWYER4]
+Tu peux aussi passer chez Rafael pour changer de fringues. T'en as sans doute pour un moment, mais bon, fonce!
+
+[LAW4_Q:LAWYER4]
+Ca va être une vraie émeute.
+
+[LAW4_R:LAWYER4]
+Si tout se passe comme sur des roulettes, passe me voir au bureau...
+
+[LAW4_1:LAWYER4]
+Dispersez-vous! La direction n'écoutera vos revendications que dans les conditions appropriées!
+
+[LAW4_2:LAWYER4]
+Dispersez-vous! Retournez chez vous!
+
+[LAW4_3:LAWYER4]
+Dispersez-vous! C'est inapproprié!
+
+[LAW4_4:LAWYER4]
+Dispersez-vous ou vous finirez tous à la rue!
+
+[LAW4_5:LAWYER4]
+Sortez vos bâtons, les mecs, on va briser quelques crânes de cocos!
+
+[LAW4_13:LAWYER4]
+~g~Commence à te battre avec au moins 4 ouvriers pour déclencher une émeute.
+
+[LAW4_14:LAWYER4]
+~g~Détruis les camionnettes du complexe!
+
+[HELP38:LAWYER4]
+Si tu butes quelqu'un qui porte une arme, il la lâche.
+
+[HELP39:LAWYER4]
+Tu peux tirer sur les barils d'explosifs, mais garde tes distances.
+
+{=================================== MISSION TABLE MIAMI_1 ===================================}
+
+[T4X4_1A:MIAMI_1]
+~g~Tu as ~1~ secondes pour récupérer ~y~24~g~ points de passage. ~g~Fais-le dans ~y~N'IMPORTE QUEL ORDRE.
+
+[T4X4_1B:MIAMI_1]
+~y~Passe A TRAVERS~g~ le premier point de passage pour déclencher le ~r~CHRONOMETRE.
+
+[T4X4_1C:MIAMI_1]
+~1~ sur 24!
+
+[GETBIK1:MIAMI_1]
+Tu as ~1~ secondes pour enfourcher une PCJ 600!
+
+[GETBIK3:MIAMI_1]
+~r~Tu as besoin d'une PCJ 600 pour cette mission!
+
+{=================================== MISSION TABLE MM ===================================}
+
+[BLOD_04:MM]
+ETAT DE LA VOITURE :
+
+[BLOD_05:MM]
+~g~TEMPS VISE : ~1~ minute
+
+[BLOD_06:MM]
+~g~TEMPS VISE : ~1~ minutes
+
+[BLOD_07:MM]
+NV meilleur tps : ~1~ secondes
+
+[BLOD_08:MM]
+Voitures détruites : ~1~
+
+[BLOD_09:MM]
+$~1~
+
+[BLOD_10:MM]
+VAINQUEUR!
+
+[BLOD_01:MM]
+Franchis les points de passage pour augmenter ton temps général.
+
+[BLOD_02:MM]
+Tu as perdu si ton temps général est à zéro.
+
+[BLOD_03:MM]
+Il faut que ton temps général soit supérieur au temps visé pour gagner!
+
+{=================================== MISSION TABLE OVALRIG ===================================}
+
+[HOTR_01:OVALRIG]
+~g~La course dure 12 tours. Seuls les trois premiers arrivés reçoivent une récompense.
+
+[HOTR_02:OVALRIG]
+~g~Tu es disqualifié si ta bagnole est détruite.
+
+[HOTR_03:OVALRIG]
+~g~Si ta bagnole est bousillée, tu peux la faire réparer aux stands.
+
+[HOTR_04:OVALRIG]
+~g~C'est par là pour sortir du stade.
+
+[HOTR_05:OVALRIG]
+Etat de la voiture :
+
+[HOTR_06:OVALRIG]
+Tours :
+
+[HOTR_10:OVALRIG]
+Temps de course :
+
+[HOTR_09:OVALRIG]
+Position :
+
+[HOTR_12:OVALRIG]
+~r~Ta caisse est bousillée!
+
+[HOTR_13:OVALRIG]
+~r~Tu n'as pas gagné la course!
+
+[HOTR_14:OVALRIG]
+~r~Tu as été disqualifié!
+
+[HOTR_15:OVALRIG]
+Temps : ~1~:~1~
+
+[HOTR_16:OVALRIG]
+Temps : ~1~:0~1~
+
+[HOTR_17:OVALRIG]
+Meilleur temps : ~1~:~1~
+
+[HOTR_18:OVALRIG]
+Meilleur temps : ~1~:0~1~
+
+[HOTR_19:OVALRIG]
+Meilleur temps : aucun
+
+[HOTR_20:OVALRIG]
+Nv meilleur tps : ~1~:~1~
+
+[HOTR_21:OVALRIG]
+Nv meilleur tps : ~1~:0~1~
+
+[HOTR_22:OVALRIG]
+Meilleur résultat : aucun
+
+[HOTR_23:OVALRIG]
+Meilleur résultat : 1er
+
+[HOTR_24:OVALRIG]
+Meilleur résultat : 2e
+
+[HOTR_25:OVALRIG]
+Meilleur résultat : 3e
+
+[HOTR_26:OVALRIG]
+Meilleur résultat : ~1~e
+
+[HOTR_27:OVALRIG]
+Meilleur tps au tr : ~1~.~1~ secondes
+
+[HOTR_28:OVALRIG]
+Meilleur tps au tr : ~1~.0~1~ secondes
+
+[HOTR_29:OVALRIG]
+$~1~
+
+[HOTR_30:OVALRIG]
+1ERE PLACE
+
+[HOTR_31:OVALRIG]
+2E PLACE
+
+[HOTR_32:OVALRIG]
+3E PLACE
+
+[HOTR_33:OVALRIG]
+Meilleur tps au tr : aucun
+
+[HOTR_11:OVALRIG]
+Nv meilleur tps au tr : ~1~.~1~ secondes
+
+[HOTR_34:OVALRIG]
+Nv meilleur tps au tr : ~1~.0~1~ secondes
+
+{=================================== MISSION TABLE PHIL1 ===================================}
+
+[PHI1_HP:PHIL1]
+Tu peux lancer une grenade à détonateur quelque part puis l'y faire exploser au moment souhaité.
+
+[PHIL1_A:PHIL1]
+Phil?
+
+[PHIL1_B:PHIL1]
+COURS!
+
+[PHIL1_C:PHIL1]
+Cours.
+
+[PHIL1_E:PHIL1]
+Merde, Phil, tu bois cette saloperie?
+
+[PHIL1_F:PHIL1]
+Putain, t'as pas besoin de la boire!
+
+[PHIL1_G:PHIL1]
+Tu la renifles juste un bon coup et t'exploses direct!
+
+[PHIL1_H:PHIL1]
+Ecoute, Phil, t'avais dit que tu pourrais t'occuper de ma puissance de feu...
+
+[PHIL1_I:PHIL1]
+Pas de problème.
+
+[PHIL1_J:PHIL1]
+Il y a ce mexicain qui trafique des armes, il a pas été réglo avec moi.
+
+[PHIL1_K:PHIL1]
+Il fait sa tournée hebdomadaire, maintenant.
+
+[PHIL1_L:PHIL1]
+Défonce l'arrière de son camion et sers-toi avant qu'il réagisse.
+
+[PHIL1_M:PHIL1]
+Et rends-moi un service au passage tant que tu y es.
+
+[PHIL1_N:PHIL1]
+Ensuite, règle-lui son compte...
+
+[PHI1_01:PHIL1]
+~g~Va piquer les armes à l'arrière du camion du trafiquant.
+
+[PHI1_02:PHIL1]
+~g~Le trafiquant a largué son chargement. Brise la caisse et ramasse l'artillerie.
+
+[PHI1_03:PHIL1]
+~g~On dirait qu'ils ont demandé des renforts...
+
+[PHI1_04:PHIL1]
+~g~Va maintenant finir les trafiquants d'armes survivants.
+
+[PHIL1_O:PHIL1]
+Yeeeeeeehhaaaaa!
+
+[PHIL1_D:PHIL1]
+N'approche jamais une allumette enflammée du boomshine de Phil Cassidy!
+
+{=================================== MISSION TABLE PHIL2 ===================================}
+
+[PHIL2_A:PHIL2]
+Salut, Phil, ça roule?
+
+[PHIL2_B:PHIL2]
+Saluut Tommyyyy! Comment ça va? Ca fait tellement longtemps...
+
+[PHIL2_C:PHIL2]
+Je te jure que tu devrais arrêter le boomshine...
+
+[PHIL2_D:PHIL2]
+Ca sent comme du décapant à peinture, j'ai les yeux qui brûlent...
+
+[PHIL2_E:PHIL2]
+Ferme-la, Tommy
+
+[PHIL2_F:PHIL2]
+et amène-toi par là. Y'a quelque chose que je veux te montrer... Quelque chose...
+
+[PHIL2_G:PHIL2]
+Waou! Putain! C'est normal que je sente l'odeur d'ici? Je me sens tout drôle...
+
+[PHIL2_H:PHIL2]
+T'inquiète pas de l'odeur, Tommy, regarde juste ça.
+
+[PHIL2_I:PHIL2]
+Putain de saloperies de piles bon marché! Il y en a d'autres sur le banc.
+
+[PHIL2_J:PHIL2]
+TA-DAAA!
+
+[PHIL2_K:PHIL2]
+Oh merde!
+
+[PHI2_01:PHIL2]
+~g~Vite, emmène Phil à l'hosto!
+
+[PHI2_03:PHIL2]
+~r~Phil Cassidy est mort! Maintenant, qui va nous filer des flingues à Liberty?
+
+[PHI2_05:PHIL2]
+Pas à l'hosto, mec, c'est plein de flics et de vietcongs!
+
+[PHI2_06:PHIL2]
+Il y a un ancien chirurgien de l'armée qui me doit quelques services et une tondeuse...
+
+[PHI2_07:PHIL2]
+Il crêche à Little Havana, oh! Regarde! Un poisson géant!
+
+[PHI2_08:PHIL2]
+Fais gaffe! Charlie sur la ligne des arbres!
+
+[PHI2_09:PHIL2]
+C'est moi qui hallucine ou la route est vraiment toute molle?
+
+[PHI2_10:PHIL2]
+Cuillère Brisée à Mère Poule, tu me reçois?
+
+[PHI2_11:PHIL2]
+Spooney Wooney Woo Woo Woooo!
+
+[PHI2_12:PHIL2]
+La mort m'appelle, mon garçon!
+
+[PHI2_13:PHIL2]
+Des ailes noires qui battent tout autour...
+
+[PHI2_14:PHIL2]
+C'est magnifique, mec, magnifique... Mais tellement froid...
+
+[PHI2_15:PHIL2]
+10-4 On a un conducteur en état d'ivresse.
+
+[PHI2_04:PHIL2]
+SANTE DE PHIL :
+
+[PHI_AS1:PHIL2]
+CHEZ PHILS PLACE OK
+
+[PHI_AS2:PHIL2]
+~g~De nouvelles armes sont en vente chez Phils Place.
+
+{=================================== MISSION TABLE PIZZA ===================================}
+
+[PIZ1_01:PIZZA]
+~g~Va livrer ces pizzas. Tu dois les balancer aux clients. Roule à côté d'eux pour lancer les pizzas.
+
+[PIZ1_02:PIZZA]
+~g~T'as balancé toutes tes pizzas, retourne en chercher d'autres.
+
+[PIZ1_05:PIZZA]
+~g~Tu as 5 minutes pour livrer les commandes avant que que les clients n'appelent une autre pizzeria.
+
+[PIZ1_07:PIZZA]
+~r~T'as tué le client! T'es viré!
+
+[PIZ1_08:PIZZA]
+~r~T'es à la bourre! T'es viré!
+
+[PIZ1_09:PIZZA]
+~r~T'as bousillé notre bécane! T'es viré!
+
+[PIZ1_11:PIZZA]
+Hé! Retourne sur ta bécane!
+
+[PIZ1_12:PIZZA]
+Pizzas restantes :
+
+[PIZ1_06:PIZZA]
+Appuie sur la~h~ ~k~~TOGGLE_SUBMISSIONS~~w~ quand tu es sur la moto pour annuler la mission.
+
+[PIZ1_13:PIZZA]
+Effectue ces livraisons en vitesse.
+
+[PIZ1_14:PIZZA]
+Mon pote, un pizza pour toi!
+
+[PIZ1_15:PIZZA]
+Allez, mon vieux, livre ça en vitesse.
+
+[PIZ1_16:PIZZA]
+Qu'est-ce que t'attends, mon vieux? T'as des pizzas à livrer!
+
+[PIZ1_17:PIZZA]
+Je sais que tu voulais pas faire ce boulot, mais je m'en tape!
+
+[PIZ1_18:PIZZA]
+Va livrer ça.
+
+[PIZ1_19:PIZZA]
+On a besoin de livrer ça.
+
+[PIZ1_20:PIZZA]
+Allez, mon vieux, livre ça ou t'es viré!
+
+[PIZ1_21:PIZZA]
+Il y a des gens qui attendent, mon vieux.
+
+[PIZ1_22:PIZZA]
+Mais qu'est-ce que t'attends? Faut livrer ça!
+
+[PIZ1_23:PIZZA]
+Va livrer cette saloperie de bouffe!
+
+[PIZ1_24:PIZZA]
+Les clients ont les crocs, mon vieux!
+
+[PIZ1_25:PIZZA]
+Tu peux prendre ça, mon vieux?
+
+[PIZ1_26:PIZZA]
+Tiens, va livrer ça en vitesse, amigo.
+
+[PIZ1_27:PIZZA]
+Magne-toi, on est débordés. Va livrer ça!
+
+[PIZ1_28:PIZZA]
+Encore toi? Qu'est-ce que t'attends? Va livrer ça!
+
+[PIZ1_29:PIZZA]
+Perds pas de temps, cette fois-ci.
+
+[PIZ1_30:PIZZA]
+Espèce de bon à rien! Va livrer ça en vitesse!
+
+[PIZ1_31:PIZZA]
+T'auras jamais de promotion si tu traînes encore ce coup-ci.
+
+[PIZ1_32:PIZZA]
+~r~La pizza est trop chaude ou quoi?
+
+[PIZ1_33:PIZZA]
+~g~Retourne au restaurant pour d'autres commandes.
+
+[PIZ1_34:PIZZA]
+~g~Pizza livrée. Voilà ton fric.
+
+[PIZ_WON:PIZZA]
+Mission Pizza terminée. votre max de Santé passe à 150.
+
+{=================================== MISSION TABLE PORN1 ===================================}
+
+[POR1_A:PORN1]
+Action
+
+[POR1_B:PORN1]
+Ooooh! C'est un sacré morceau!
+
+[POR1_C:PORN1]
+30 centimètres, c'est la taille réglementaire, bébé.
+
+[POR1_D:PORN1]
+COUPEZ! Qui c'est cet abruti? Toi! Toi! T'es dans le champ? POURQUOI?
+
+[POR1_E:PORN1]
+Qu'est-ce que c'est que ces conneries?
+
+[POR1_F:PORN1]
+Des aliens? Des cannes à pêche?
+
+[POR1_G:PORN1]
+J'ai jamais vu un requin aussi gros...
+
+[POR1_H:PORN1]
+Faut que tout ça dégage!
+
+[POR1_I:PORN1]
+Pourquoi t'es dans le métier, connard?
+
+[POR1_J:PORN1]
+Hein?
+
+[POR1_K:PORN1]
+Ben, pour les chattes, évidemment! Alors, qu'est-ce que c'est que ça?
+
+[POR1_L:PORN1]
+Ceci est mon art - SECURITE!
+
+[POR1_M:PORN1]
+Ecoute-moi, trou du cul arrogant, tu m'appartiens maintenant. Tout m'appartient ici.
+
+[POR1_N:PORN1]
+On va révolutionner cet endroit...
+
+[POR1_O:PORN1]
+Je vais faire ta fortune...
+
+[POR1_P:PORN1]
+Oh. Tu es... Tu... es Tommy Vercetti? Mais je croyais que tu étais...
+
+[POR1_Q:PORN1]
+Exactement...
+
+[POR1_R:PORN1]
+Va y avoir quelques changements dans le coin et on va commencer à se faire des ronds.
+
+[POR1_S:PORN1]
+Au fait, as-tu jamais pensé à...
+
+[POR1_T:PORN1]
+Mais d'abord, on va avoir besoin de quelques putes bien foutues...
+
+[POR1_U:PORN1]
+Ouais, les filles c'est bien mais toi... waou!
+
+[POR1_02:PORN1]
+~g~Bute le mac de Candy, puis retourne la récupérer.
+
+[POR1_04:PORN1]
+Salut, Candy. Je cherche des actrices, ça te branche?
+
+[POR1_05:PORN1]
+Et comment! Mais faut causer à mon agent...
+
+[POR1_06:PORN1]
+Putain qu'est-ce que tu fous?
+
+[POR1_07:PORN1]
+Tu aurais mieux fait de rester à la maison, aujourd'hui!
+
+[POR1_7B:PORN1]
+J'arrive pas à croire ce trou du cul!
+
+[POR1_08:PORN1]
+Salut, Mercedes!
+
+[POR1_09:PORN1]
+Salut, Tommy! Tu viens faire la fête?
+
+[POR1_10:PORN1]
+Non, pas maintenant, chérie. Ca te dirait de faire du cinéma?
+
+[POR1_11:PORN1]
+Evidemment! Mais seulement si c'est sordide et bon marché!
+
+[POR1_13:PORN1]
+~g~Emmène les filles au studio y retrouver Steve.
+
+[POR1_14:PORN1]
+T'es engagé!
+
+[POR1_15:PORN1]
+Hé tommy, tu viens pour un bout d'essai?
+
+[POR1_17:PORN1]
+Waou! Sympa le requin!
+
+[POR1_18:PORN1]
+~r~Mercedes est morte!
+
+[POR1_20:PORN1]
+Tommy! Où tu vas? Reviens ici!
+
+[POR1_21:PORN1]
+Où tu vas?
+
+[POR1_22:PORN1]
+Tommy, quand c'est qu'on va pouvoir être un peu seuls ensemble?
+
+[POR1_01:PORN1]
+~g~Candy Suxxx serait parfaite pour un premier rôle!
+
+[POR1_12:PORN1]
+~g~Emmène Candy avec toi pour rencontrer Mercedes.
+
+[POR1_16:PORN1]
+Plus tard, peut-être, mon chou...
+
+[POR1_24:PORN1]
+~g~Retourne chercher Candy.
+
+[POR1_25:PORN1]
+~g~Tu as laissé Candy. Retourne la chercher!
+
+[POR1_23:PORN1]
+~g~Candy va s'occuper de l'affaire dans le ~h~Centre~g~.
+
+[POR1_26:PORN1]
+~g~Voilà Candy. On dirait qu'elle a encore eu rendez-vous avec le représentant du Congrès, Alex Shrub.
+
+[POR1_27:PORN1]
+Allez, partons d'ici!
+
+[POR1_28:PORN1]
+Tommy, sois prudent! Mes implants ne sont pas encore assurés!
+
+[POR1_29:PORN1]
+Tu appelles ça conduire?
+
+[POR1_30:PORN1]
+Je pourrais plus faire du porno après ça!
+
+[POR1_31:PORN1]
+Quoi? T'essaies de me tuer ou quoi? Je croyais que c'était moi, la star!
+
+{=================================== MISSION TABLE PORN2 ===================================}
+
+[POR2_A:PORN2]
+Comment ça se passe, Steve?
+
+[POR2_B:PORN2]
+Eh ben, Candy est faite pour le rôle et la nouvelle fille est infatigable!
+
+[POR2_C:PORN2]
+Elle s'est tapé la moitié du casting et des techniciens avant même que j'ai fini de régler les éclairages!
+
+[POR2_D:PORN2]
+Enfin, demain, on va en extérieurs pour tourner les scènes du bateau...
+
+[POR2_E:PORN2]
+Les scènes du bateau? Quelles scènes du bateau?
+
+[POR2_F:PORN2]
+Les pêcheurs sont dans les filets de la passion quand ce requin géant arrive...
+
+[POR2_G:PORN2]
+Qu'est-ce que j'avais dit à propos du requin géant?
+
+[POR2_H:PORN2]
+J'avais dit : PAS DE REQUIN GEANT! Ok?
+
+[POR2_I:PORN2]
+Laisse simplement les caméras braquées sur le pieu!
+
+[POR2_J:PORN2]
+Ok ok, Tommy, j'avais bien le droit d'essayer...
+
+[POR2_K:PORN2]
+Les prospectus sont imprimés?
+
+[POR2_L:PORN2]
+Ouais, mais personne va nous laisser distribuer ces trucs, je veux dire...
+
+[POR2_M:PORN2]
+Ils sont un peu trop, hum, enfin, ils manquent un peu de poésie...
+
+[POR2_N:PORN2]
+T'en fais pas pour ça!
+
+[POR2_O:PORN2]
+J'ai mes propres plans pour la distribution...
+
+[POR2_P:PORN2]
+OK. Hé, Candy, amène-toi dans ma caravane!
+
+[POR2_01:PORN2]
+~g~Il y a un hydravion à l'arrière des studios qui servait pour la propagande des vieux films.
+
+[POR2_02:PORN2]
+~g~Atteins l'un des points de contrôle pour commencer à larguer les prospectus.
+
+[POR2_03:PORN2]
+~g~Largue les prospectus tout le long du chemin jusqu'au dernier point de contrôle.
+
+[POR2_04:PORN2]
+~r~NIVEAU DE CARBURANT BAS!
+
+[POR2_05:PORN2]
+Utilise-le pour distribuer les prospectus dans la ville.
+
+[DILDO:PORN2]
+Kérosène :
+
+[POR2_Q:PORN2]
+Oh, merde!
+
+[PORN2_9:PORN2]
+~g~Il te reste ~1~ secondes pour retourner à une Skimmer avant la fin de la mission.
+
+{=================================== MISSION TABLE PORN3 ===================================}
+
+[POR3_A:PORN3]
+Bon, c'est quoi le problème, maintenant?
+
+[POR3_B:PORN3]
+Chuuuut!
+
+[POR3_C:PORN3]
+Eh bien, après l'intime rencontre avec les envahisseuses nymphomanes,
+
+[POR3_D:PORN3]
+notre jeune héros se retrouve incapable de penser à autre chose que cette énorme montagne phallique
+
+[POR3_E:PORN3]
+et c'est là qu'on veut placer la scène avec la cuve de purée de patates, mais alors on...
+
+[POR3_F:PORN3]
+Ces conneries m'intéressent pas!
+
+[POR3_G:PORN3]
+Continuez simplement le boulot, continuez...
+
+[POR3_H:PORN3]
+Hé, Tommy...
+
+[POR3_I:PORN3]
+T'as évoqué un problème légal au téléphone...
+
+[POR3_J:PORN3]
+Ah ouais! Le représentant du Congrès Alex Shrub a pris le train électoral en marche à la pêche des votes puritains...
+
+[POR3_K:PORN3]
+La rumeur laisse entendre qu'il soutient des mesures de restriction contre...
+
+[POR3_L:PORN3]
+Disons... les formes les plus charnelles de la grande industrie cinématographique de ce pays.
+
+[POR3_M:PORN3]
+Super.
+
+[POR3_N:PORN3]
+Candy! Tu connais Shrub.
+
+[POR3_O:PORN3]
+Vous faites des trucs bizarres tous les deux?
+
+[POR3_P:PORN3]
+Oh oui! Oui! Oh oui! Oui oui oui ouuuuuuuuuuuuuuuuuui!
+
+[POR3_Q:PORN3]
+Dis-moi que t'as eu ça...
+
+[POR3_R:PORN3]
+Est-ce que ça faisait partie du... euh... Ou bien elle parlait à...
+
+[POR3_S:PORN3]
+Impossible à dire... Dans tous les cas...
+
+[POR3_T:PORN3]
+Tu ferais mieux de la suivre après le tournage
+
+[POR3_U:PORN3]
+et voir si elle te mènera pas à leur nouveau nid d'amour.
+
+[POR3_V:PORN3]
+T'as un appareil photo?
+
+[POR3_X:PORN3]
+Hé, file-lui un appareil photo!
+
+[POR3_02:PORN3]
+~r~Tu as tué le représentant du Congrès! T'auras du mal à le faire chanter, maintenant!
+
+[POR3_03:PORN3]
+~r~Tu as alerté la sécurité du représentant du Congrès, ils vont le faire sortir tout de suite.
+
+[POR3_04:PORN3]
+Candy, tu peux m'appeler Martha?
+
+[POR3_05:PORN3]
+Oh Alex, enfin, je veux dire Martha. Comme tu veux...
+
+[POR3_06:PORN3]
+Martha, il y a quelqu'un qui regarde... C'est pervers...
+
+[POR3_07:PORN3]
+Vous là-bas, donnez-moi cet appareil photo!
+
+[POR3_01:PORN3]
+~g~Suis la ~h~Stretch~g~ de Candy.
+
+[POR3_15:PORN3]
+~r~T'as bousillé la Stretch de Candy!
+
+[POR3_17:PORN3]
+~g~Retourne aux Porn Studios avec la pellicule.
+
+[POR3_19:PORN3]
+~r~T'es à court de pellicule!
+
+[POR3_21:PORN3]
+~g~T'as perdu la Stretch de Candy!
+
+[POR3_22:PORN3]
+~g~Le WK Chariot Hotel de l'autre côté de ce balcon devrait être idéal, comme point de vue.
+
+[POR3_23:PORN3]
+~g~Il y a une porte latérale qui te permettra d'accéder à l'hôtel.
+
+[POR3_08:PORN3]
+Appuie sur la~h~ ~k~~PED_LOCK_TARGET~ ~w~et maintiens-la enfoncée pour ~h~cadrer~w~ la photo.
+
+[POR3_09:PORN3]
+Appuie sur la~h~ ~k~~PED_LOCK_TARGET~ ~w~et maintiens-la enfoncée pour ~h~cadrer~w~ la photo.
+
+[POR3_10:PORN3]
+Appuie sur la~h~ ~k~~PED_SNIPER_ZOOM_IN~ ~w~pour faire un ~h~zoom avant~w~ et sur la~h~ ~k~~PED_SNIPER_ZOOM_OUT~ ~w~pour faire un ~h~zoom arrière~w~.
+
+[POR3_11:PORN3]
+Appuie sur la~h~ ~k~~PED_SNIPER_ZOOM_IN~ ~w~pour faire un ~h~zoom avant~w~ et sur la~h~ ~k~~PED_SNIPER_ZOOM_OUT~ ~w~pour faire un ~h~zoom arrière~w~.
+
+[POR3_12:PORN3]
+Appuie sur la~h~ ~k~~PED_FIREWEAPON~ ~w~pour prendre une photo.
+
+[POR3_13:PORN3]
+Appuie sur la~h~ ~k~~PED_FIREWEAPON~ ~w~pour prendre une photo.
+
+[POR3_14:PORN3]
+Appuie sur la~h~ ~k~~PED_FIREWEAPON~ ~w~pour prendre une photo.
+
+[POR3_20:PORN3]
+~g~Si tu as besoin de te déplacer, utilise la ~h~Sparrow~g~ garée derrière.
+
+[POR3_16:PORN3]
+~g~Il te faut trois bons clichés d'Alex Shrub avec Candy pour le faire chanter.
+
+[POR3_24:PORN3]
+PHOTOS PRISES :
+
+{=================================== MISSION TABLE PORN4 ===================================}
+
+[POR4_A:PORN4]
+Je suis désolée, mais je ne peux pas avaler maintenant!
+
+[POR4_B:PORN4]
+Oh, ALLEZ! Chérie!
+
+[POR4_C:PORN4]
+Il décharge comme une baleine, par pitié
+
+[POR4_D:PORN4]
+comment tu fais pour ne pas saisir le rôle?
+
+[POR4_E:PORN4]
+Mais Stevie...
+
+[POR4_F:PORN4]
+Comment va mon réalisateur vedette?
+
+[POR4_G:PORN4]
+Ah, mon pote, la lutte incessante entre l'intégrité artistique et
+
+[POR4_H:PORN4]
+l'éjaculation sous toutes ses formes est loin d'être terminée.
+
+[POR4_I:PORN4]
+Et avant que tu me poses la question, je t'informe que les quatre vidéos sortiront dans les...
+
+[POR4_J:PORN4]
+Chérie, veux-tu garder l'anaconda dans le champ, S'IL TE PLAIT.
+
+[POR4_K:PORN4]
+Il prend plus de l'heure que toi!
+
+[POR4_L:PORN4]
+Oh, pardon, Steve...
+
+[POR4_M:PORN4]
+Je me disais, faudrait monter un gros coup de pub pour la promo du film.
+
+[POR4_N:PORN4]
+Un truc qui aurait vraiment de l'impact sur la ville... T'as pas une idée?
+
+[POR4_O:PORN4]
+Eh ben, autrefois, on faisait des galas,
+
+[POR4_P:PORN4]
+avec des vedettes, des limousines, la nuit éclairée par les projos...
+
+[POR4_Q:PORN4]
+Des projecteurs? J'ai une idée!
+
+[POR4_R:PORN4]
+...Ouais, ouais, ouais! Le petit numéro de paillettes, les limousines, ah, les premières!
+
+[POR4_S:PORN4]
+Oh oui, chère madaaaame, bien sûr, chère madaaaame...
+
+[POR4_T:PORN4]
+et la presse, et le barrage de lumières...
+
+[POR4_01:PORN4]
+~g~Va dans le ~y~Centre~g~ et ajuste le projecteur sur le toit du bâtiment.
+
+[POR4_02:PORN4]
+~g~Une bécane rapide est nécessaire pour sauter de toit en toit. L'agent de sécurité a l'habitude de venir en ~y~PCJ 600~g~ au boulot...
+
+[POR4_03:PORN4]
+~g~Faut que tu montes sur les toits. Il devrait y avoir un ascenceur dans l'un des immeubles de bureaux.
+
+[POR4_06:PORN4]
+~g~Retourne à l'immeuble de bureaux du bas si tu as besoin d'accéder à nouveau au toit.
+
+[POR4_07:PORN4]
+~g~Tu as besoin d'une bécane pour sauter de bâtiment en bâtiment!
+
+[POR4_08:PORN4]
+~g~Fonce à travers la fenêtre pour commencer. Tu as jusqu'à 07:00 avant que la lumière du jour ne risque de te faire découvrir.
+
+[POR4_09:PORN4]
+~g~Les marqueurs t'indiquent sur quel bâtiment sauter ensuite.
+
+[POR4_10:PORN4]
+~r~Il fait maintenant trop clair pour monter sans te faire voir.
+
+[POR4_11:PORN4]
+Retourne à l'escalier si tu as à nouveau besoin d'accéder au toit.
+
+[POR4_05:PORN4]
+~g~Ces escaliers mènent à un bureau.
+
+[POR_AS1:PORN4]
+STUDIO DE CINEMA OK
+
+[POR_AS2:PORN4]
+~g~Inter Global Films génère dorénavant un revenu de $~1~ maximum. Pense à récupérer le fric régulièrement.
+
+{=================================== MISSION TABLE PROT1 ===================================}
+
+[PRO1_B:PROT1]
+Je supporte pas ce style. Tommy, qu'est-ce que t'en penses? Qu'est-ce que tu dirais qu'on mette un bar dans...
+
+[PRO1_D:PROT1]
+Ecoutez-moi...
+
+[PRO1_E:PROT1]
+L'heure est venue de mettre la main sur cette ville! Le monde n'attend plus que nous!
+
+[PRO1_F:PROT1]
+Faut qu'on commence à s'emparer de territoires!
+
+[PRO1_G:PROT1]
+Faut qu'on fasse comprendre à tout Vice City qu'on est les nouveaux maîtres du jeu! Tu vois ce que je veux dire?
+
+[PRO1_I:PROT1]
+Ce qu'il te faut, c'est une façade légale, Tommy! Une affaire officielle! Ca m'a jamais rapporté d'emmerdes!
+
+[PRO1_J:PROT1]
+Faut qu'on commence à utiliser des balaises ou autant faire une croix sur tout le boulot qu'on s'est tapé jusque là.
+
+[PRO1_K:PROT1]
+Les commerces locaux savent que Diaz est mort et ils refusent de payer pour leur protection!
+
+[PRO1_L:PROT1]
+Ah. On pourrait essayer la corruption...
+
+[PRO1_M:PROT1]
+La corruption! Mon cul, la corruption! Je vais vous montrer comment on leur fait peur!
+
+[PRO1_01:PROT1]
+~g~Défoule-toi sur les devantures des magasins et les proprios supplieront pour être protégés.
+
+[PRO1_03:PROT1]
+~r~C'était supposé être un raid éclair, pas une pause café.
+
+[PRO1_04:PROT1]
+Mon gagne-pain est détruit!
+
+[PRO1_05:PROT1]
+Tout est en ruines!
+
+[PRO1_06:PROT1]
+Je paye le prix fort pour ma protection!
+
+[PRO1_07:PROT1]
+Ma belle vitrine!
+
+[PRO1_08:PROT1]
+Mon magasin! Mon beau magasin!
+
+[PRO1_09:PROT1]
+Vercetti. Souvenez-vous de mon nom...
+
+[PRO1_10:PROT1]
+Je règne désormais sur cette ville. MOI!
+
+[BUYP1:PROT1]
+Tu peux désormais acheter des propriétés dans certaines zones de la carte.
+
+[BUYP2:PROT1]
+Si tu vois un marqueur vert sur une propriété, c'est que tu peux l'acheter.
+
+[PRO1_N:PROT1]
+Je reviens dans cinq minutes...
+
+[PRO1_11:PROT1]
+~g~Va au ~y~Centre commercial de North Point~g~ dans ~y~Vice Point~g~.
+
+[PRO1_12:PROT1]
+~g~Brise les vitrines de chaque magasin et les proprios supplieront pour une nouvelle protection.
+
+[PRO1_A:PROT1]
+Ah, faut qu'on redécore cet endroit, faut qu'on lui donne un air plus vieux.
+
+[PRO1_C:PROT1]
+T'es mon avocat, Rosenberg. Pas mon décorateur. Compris?
+
+[BUYP3:PROT1]
+Tiens-toi sur le marqueur, puis appuie sur la touche ~h~~k~~PED_ANSWER_PHONE~~w~ pour acheter cette propriété.
+
+[PRO1_13:PROT1]
+~g~Tu as cinq minutes pour tous les avoir.
+
+{=================================== MISSION TABLE PROT2 ===================================}
+
+[PRO2_A:PROT2]
+C'est quoi l'problème?
+
+[PRO2_B:PROT2]
+Un bar refuse de payer.
+
+[PRO2_C:PROT2]
+Le boss considère qu'il est sous la protection d'un gang de voyous du coin...
+
+[PRO2_D:PROT2]
+Mais t'en fais pas, Tommy, je peux m'en occuper.
+
+[PRO2_E:PROT2]
+C'est ça que t'appelles t'en occuper?
+
+[PRO2_F:PROT2]
+Vous deux, levez vos culs de là...
+
+[PRO2_G:PROT2]
+Allons-y.
+
+[PRO2_01:PROT2]
+~g~Liquide les gardes qui protègent le Front Page Bar et trouve qui les a approvisionnés.
+
+[PRO2_10:PROT2]
+~g~Il y en a deux de plus qui se sont fait la malle. Finis-en avec eux.
+
+[PRO2_11:PROT2]
+Montez dans la caisse, bons à rien.
+
+[PRO2_02:PROT2]
+Ta protection a besoin d'être légèrement renforcée.
+
+[PRO2_03:PROT2]
+Ah, non, pas encore! J'en ai marre!
+
+[PRO2_04:PROT2]
+Ces imbéciles opèrent dans le quartier à partir de DBP Security.
+
+[PRO2_05:PROT2]
+Réglez la question entre vous, les mecs.
+
+[PRO2_06:PROT2]
+Bon, à plus tard.
+
+[PRO2_07:PROT2]
+Ouais, ouais, c'est ça.
+
+[PRO2_08:PROT2]
+~g~Les abrutis du DBP Security sauront que t'y vas, alors fonce et chope-les avant qu'ils décampent!
+
+[PRO2_09:PROT2]
+~g~Va parler au proprio du Front Page Bar.
+
+{=================================== MISSION TABLE PROT3 ===================================}
+
+[PRO3_A:PROT3]
+Pauvre crétin! A quoi tu pensais?
+
+[PRO3_B:PROT3]
+Tu réalise ce qui aurait pu arriver?
+
+[PRO3_C:PROT3]
+On a failli tous se faire avoir!
+
+[PRO3_D:PROT3]
+Le retardateur a dû déconner...
+
+[PRO3_E:PROT3]
+Cet endroit était prêt à sauter comme une usine de feux d'artifice.
+
+[PRO3_F:PROT3]
+Et pis quelqu'un a rencardé les flics...
+
+[PRO3_G:PROT3]
+C'est quoi le problème, les mecs?
+
+[PRO3_H:PROT3]
+Mike devait foutre le feu quelque part dans le centre commercial,
+
+[PRO3_I:PROT3]
+mais il a foiré son coup et maintenant, les flics grouillent, là-bas.
+
+[PRO3_J:PROT3]
+Faut qu'on récupère notre bordel et qu'on s'tire de là!
+
+[PRO3_K:PROT3]
+Du calme, vous deux, laissez-moi réfléchir une seconde!
+
+[PRO3_L:PROT3]
+Tommy Vercetti a pas l'habitude de mettre les bouts comme ça...
+
+[PRO3_M:PROT3]
+Les flics vont passer ce bâtiment au peigne fin, pas vrai?
+
+[PRO3_N:PROT3]
+Mais ça prend du temps...
+
+[PRO3_O:PROT3]
+On va entrer et foutre le feu nous-mêmes!
+
+[PRO3_P:PROT3]
+Ouais, mais...
+
+[PRO3_Q:PROT3]
+Il y a que les flics qui peuvent approcher à moins d'un kilomètre de là-bas!
+
+[PRO3_R:PROT3]
+Alors, on ira en tant que flics!
+
+[PRO3_S:PROT3]
+On va se dégotter des uniformes et il nous faut aussi une bagnole de patrouille.
+
+[PRO3_T:PROT3]
+Tout ça à cause de toi, Mike.
+
+[PRO3_U:PROT3]
+Je suis désolé.
+
+[PRO3_V:PROT3]
+J'ai trouvé!
+
+[PRO3_W:PROT3]
+Tout ce qu'on a à faire, c'est appâter les flics avec un doigt levé,
+
+[PRO3_X:PROT3]
+de les prendre au piège
+
+[PRO3_Y:PROT3]
+et de leur sauter dessus!
+
+[PRO3_Z:PROT3]
+Super plan! En route!
+
+[PRO3_A1:PROT3]
+OK.
+
+[PRO3_01:PROT3]
+Ok Lance, attirons l'attention des flics!
+
+[PRO3_02:PROT3]
+~g~Prends la bagnole des flics et va poser la bombe au Tarbrush Coffee Shop dans le centre commercial.
+
+[PRO3_03:PROT3]
+~g~T'as laissé Lance derrière, va le récupérer!
+
+[PRO3_04:PROT3]
+~g~Allons-y!
+
+[PRO3_05:PROT3]
+~r~T'as buté Lance!
+
+[PRO3_07:PROT3]
+~g~Tu as grillé ta couverture! Magne-toi de poser la bombe!
+
+[PRO3_09:PROT3]
+Ligotons et bâillonnons-les!
+
+[PRO3_10:PROT3]
+Aaah! Il me va parfaitement!
+
+[PRO3_11:PROT3]
+Mais quand même un peu serré au niveau des couilles...
+
+[PRO3_12:PROT3]
+Ah ouais? Le mien aussi, c'est pareil!
+
+[PRO3_13:PROT3]
+Du calme, mon pote! Les flics conduisent pas aussi mal!
+
+[PRO3_14:PROT3]
+Oublie pas... Faut sourire aux autres flics...
+
+[PRO3_15:PROT3]
+Salut officier. Bel insigne, bel insigne...
+
+[PRO3_16:PROT3]
+Tout doux, Lance.
+
+[PRO3_17:PROT3]
+Ok, les retardateurs sont programmés, 5 secondes et ça saute!
+
+[PRO3_18:PROT3]
+5 secondes? Putain faut dégager d'ici en vitesse!
+
+[PRO3_19:PROT3]
+Maintenant, ils vont vraiment être fâchés...
+
+[PRO3_20:PROT3]
+~g~Fais-toi suivre par deux flics dans le garage.
+
+[PRO3_21:PROT3]
+~g~Tu dois avoir un indice de recherche pour que les flics te suivent dans le piège.
+
+[PRO3_22:PROT3]
+~g~La porte est bloquée! Dégage le passage pour qu'elle puisse être refermée.
+
+[PRO3_23:PROT3]
+~g~Marche sur le marqueur pour poser la bombe.
+
+[PRO3_24:PROT3]
+~g~Tire-toi du café!
+
+[PRO_AS1:PROT3]
+PROTECTION OK
+
+[PRO_AS2:PROT3]
+~g~Vercetti Estate génère désormais un revenu de $~1~ maximum. Pense à récupérer le fric régulièrement.
+
+[PRO3_08:PROT3]
+~g~ Retourne à ~h~Vercetti Estate~g~ sur ~h~Starfish Island~g~.
+
+{=================================== MISSION TABLE RACES ===================================}
+
+[RACES_2:RACES]
+~g~Il te faut un véhicule, c'est pas une course à pied!
+
+[RACES_3:RACES]
+3... 2... 1... PARTEZ!
+
+[RACES_8:RACES]
+~r~Tu n'as pas gagné la course!
+
+[RACES00:RACES]
+Course ~1~ :
+
+[RACES01:RACES]
+Terminal Velocity
+
+[RACES02:RACES]
+Ocean Drive
+
+[RACES03:RACES]
+Border Run
+
+[RACES04:RACES]
+Capital Cruise
+
+[RACES05:RACES]
+Virée!
+
+[RACES06:RACES]
+Endurance V.C.
+
+[RACES07:RACES]
+Participation : ~1~$
+
+[RACES08:RACES]
+Meilleur temps : ~1~:~1~
+
+[RACES09:RACES]
+Meilleure perf : 1er
+
+[RACES10:RACES]
+Meilleure perf : 2e
+
+[RACES11:RACES]
+Meilleure perf : 3e
+
+[RACES12:RACES]
+Meilleure perf : 4e
+
+[RACES13:RACES]
+Longueur circuit : ~1~.~1~ km
+
+[RACES15:RACES]
+Meilleur temps : NA
+
+[RACES16:RACES]
+Meilleure perf : NA
+
+[RACES18:RACES]
+TU AS GAGNE : $~1~
+
+[RACES19:RACES]
+Tu n'as pas assez de moyens pour participer.
+
+[RACES22:RACES]
+Meilleur temps : ~1~:0~1~
+
+[RACES23:RACES]
+Longueur circuit : ~1~.~1~ miles
+
+[RACES_1:RACES]
+~g~Trouve un bolide et rends-toi sur la grille de départ.
+
+[RACEHLP:RACES]
+~w~Appuie sur la~h~ ~k~~PED_SPRINT~~w~ pour commencer la course choisie. Appuie sur la~h~ ~k~~VEHICLE_ENTER_EXIT~~w~ pour quitter.
+
+{=================================== MISSION TABLE RCHELI1 ===================================}
+
+[WRECKED:RCHELI1]
+Ton véhicule est mort!
+
+[RCH1_4:RCHELI1]
+Points de passage restants :
+
+[RCH1_6:RCHELI1]
+~g~Utilise l'hélico télécommandé pour passer les points de passage à travers l'aéroport.
+
+[RCH1_7:RCHELI1]
+~g~Il y a 20 points de passage en tout.
+
+[RCH1_12:RCHELI1]
+~g~L'hélicoptère télécommandé est presque hors de portée!
+
+[RCH1_13:RCHELI1]
+~r~L'hélicoptère radiocommandé est hors de portée!
+
+[RCH1_8:RCHELI1] { reVC update }
+~g~Si tu veux quitter cette mission, appuie sur la ~h~~k~~VEHICLE_FIREWEAPON~~g~ pour faire exploser ton hélicoptère radiocommandé.
+
+{=================================== MISSION TABLE RCPLNE1 ===================================}
+
+[RCPL1_4:RCPLNE1]
+~g~Fais une COURSE DE POINTS DE PASSAGE avec 3 autres avions télécommandés.
+
+[RCPL1_5:RCPLNE1]
+~g~Passe par les points de passage dispersés dans Vice City.
+
+[RCPL1_6:RCPLNE1] { reVC update }
+~g~Si tu veux quitter cette mission, appuie sur la ~h~~k~~VEHICLE_FIREWEAPON~~g~ pour faire exploser ton avion radiocommandé.
+
+[RCPL1_8:RCPLNE1]
+~g~Ton avion RC va sortir du périmètre!
+
+[RCPL1_9:RCPLNE1]
+~r~Ton avion RC est sorti du périmètre!
+
+{=================================== MISSION TABLE RCRACE1 ===================================}
+
+[RCR1_4:RCRACE1]
+Tours restants :
+
+[RCR1_1:RCRACE1]
+~g~Fais une course de points de passage contre 3 autres voitures RC.
+
+[RCR1_2:RCRACE1]
+~g~Sois le premier à boucler 2 tours de circuit pour gagner!
+
+[RCR1_6:RCRACE1]
+~g~Ta voiture RC va sortir du périmètre!
+
+[RCR1_7:RCRACE1]
+~r~Ta voiture RC est sortie du périmètre!
+
+{=================================== MISSION TABLE ROCK1 ===================================}
+
+[RBM1_A:ROCK1]
+Okaaaaaaaaaay!
+
+[RBM1_B:ROCK1]
+Grandiose! Vraiment génial!
+
+[RBM1_D:ROCK1]
+Hé, t'as déjà rencontré les Love Fist?
+
+[RBM1_E:ROCK1]
+Non, mais j'adore votre musique!
+
+[RBM1_F:ROCK1]
+Laisse-moi te présenter au groupe.
+
+[RBM1_G:ROCK1]
+Voici P, Percy, Dick et Willy est aux chiottes et Jezz était dans la cabine tout à l'heure...
+
+[RBM1_H:ROCK1]
+Les mecs, je veux vous présenter un bon ami à moi.
+
+[RBM1_I:ROCK1]
+Voici Tommy. Ca fait un bail qu'on se connait.
+
+[RBM1_J:ROCK1]
+Ok, mon pote.
+
+[RBM1_K:ROCK1]
+Ah, euh... C'est quoi déjà, ton nom?
+
+[RBM1_L:ROCK1]
+Arrête-ça Jezz tu t'en souviens,
+
+[RBM1_M:ROCK1]
+et essaye pas de jouer au plus malin avec moi,
+
+[RBM1_N:ROCK1]
+je suis trop intelligent, mon mignon!
+
+[RBM1_O:ROCK1]
+Tu vois, le problème, Tom, c'est que ces garçons ont besoin d'aide.
+
+[RBM1_P:ROCK1]
+Ils n'ont pas beaucoup de contacts ici et ils savent pas à qui s'adresser.
+
+[RBM1_Q:ROCK1]
+On a besoin de drogue, mon pote!
+
+[RBM1_R:ROCK1]
+Faut qu'on réveille la vieille fureur de Love Fist, tu vois?
+
+[RBM1_S:ROCK1]
+Et bien, ici, c'est Vice City, quel est le problème?
+
+[RBM1_U:ROCK1]
+Du Love Juice, mec!
+
+[RBM1_V:ROCK1]
+Du Love Juice?
+
+[RBM1_W:ROCK1]
+Ouais, deux doses de boomshine, une dose de trompette, 5 bombes fizz et un litre d'essence.
+
+[RBM1_X:ROCK1]
+Tu peux nous aider, mon pote?
+
+[RBM1_Y:ROCK1]
+Ah, ça rendrait tellement service aux garçons!
+
+[RBM1_Z:ROCK1]
+Tu peux faire ça pour les garçons, pas vrai?
+
+[RBM1_8:ROCK1]
+~r~Mercedes est morte!
+
+[RBM1_10:ROCK1]
+~r~Imbécile! Tu as détruit la marchandise!
+
+[RBM1_13:ROCK1]
+~g~Amène le Love Juice et Mercedes au groupe avant qu'ils n'entrent sur scène.
+
+[RBM1_15:ROCK1]
+~r~Tu as perdu le dealer, notre cash et la drogue!
+
+[RBM1_17:ROCK1]
+~g~Tue le dealer et prends la drogue!
+
+[MOB_07A:ROCK1]
+Salut, mon vieux, les gars auraient besoin d'un peu de compagnie, si tu vois ce que je veux dire...
+
+[MOB_07B:ROCK1]
+Je connais justement la fille qu'il faut.
+
+[ROK1_5:ROCK1]
+Salut Mercedes!
+
+[ROK1_6:ROCK1]
+Salut, Tommy. Comment vas-tu?
+
+[ROK1_7:ROCK1]
+Ca roule. Ecoute, les Love Fist, ça te branche?
+
+[ROK1_8:ROCK1]
+Ok, mais c'est un service qu'il faudra me retourner...
+
+[RBM1_14:ROCK1]
+~g~T'as besoin d'une bagnole ou d'une bécane!
+
+[RBM1_1:ROCK1]
+~g~Va prendre Mercedes à son appartement.
+
+[RBM1_12:ROCK1]
+~g~Va récupérer les ingrédients du Love Juice chez le dealer.
+
+[ROK1_2:ROCK1]
+PLUS NECESSAIRE
+
+[ROK1_3:ROCK1]
+PLUS NECESSAIRE
+
+[MERC_39:ROCK1]
+A plus tard, champion.
+
+[RBM1_C:ROCK1]
+Hé, Tommy! Content que t'aies réussi!
+
+[ROK1_1A:ROCK1]
+Tu cherches quelque chose de spécial? J'ai ce qu'il te faut!
+
+[ROK1_9:ROCK1]
+Merci pour le pognon, suce boules!
+
+[RBM1_T:ROCK1]
+On a besoin de Love Juice, mec, tu vois?
+
+{=================================== MISSION TABLE ROCK2 ===================================}
+
+[RBM2_A:ROCK2]
+Tommy, mon pote, je suis content de te voir!
+
+[RBM2_B:ROCK2]
+Qu'est-ce qui se passe?
+
+[RBM2_C:ROCK2]
+Des mauvaises vibrations, Tommy...
+
+[RBM2_E:ROCK2]
+Il y a ce chat, on le connaît pas, mais lui il nous connaît.
+
+[RBM2_F:ROCK2]
+C'est comme ce chat. Il nous connaît tous.
+
+[RBM2_G:ROCK2]
+Il sait que Willy a un faible pour les culottes de ses femmes, hé hé!
+
+[RBM2_H:ROCK2]
+Ou que Percy aime bien Duran Duran!
+
+[RBM2_K:ROCK2]
+Ouais, le truc de la fusée d'amour, c'est vrai. Mais écoute, ce chat...
+
+[RBM2_L:ROCK2]
+ouais, ouais, ce gars, il veut voir les Love Fist morts!
+
+[RBM2_M:ROCK2]
+Morts, Tommy.
+
+[RBM2_N:ROCK2]
+Les Love Fist disparus. Tu sais ce qu'on dit, les meilleurs meurent jeunes...
+
+[RBM2_O:ROCK2]
+Tommy, faut que tu sauves les Love Fist!
+
+[RBM2_P:ROCK2]
+On a une séance d'autographes dans deux heures et je pense que...
+
+[RBM2_Q:ROCK2]
+Et les garçons pensent que le mec va essayer quelque chose de très vilain là-bas.
+
+[RBM2_1:ROCK2]
+~g~Conduis la limousine à la séance d'autographes et essaye de démasquer le psychopathe .
+
+[RBM2_2:ROCK2]
+~r~T'as bousillé la bagnole du groupe!
+
+[RBM2_3:ROCK2]
+~g~Va à la séance d'autographes!
+
+[RBM2_4:ROCK2]
+~g~Attrape le psychopathe! Ne le laisse pas s'échapper!
+
+[RBM2_5:ROCK2]
+~r~Tu l'as perdu, imbécile!
+
+[RBM2_7:ROCK2]
+~r~Les fans ont été attaqués, le psychopathe ne se montrera pas!
+
+[RBM2_8:ROCK2]
+~r~Les agents de sécurité ont été attaqués, le psychopathe ne se montrera pas!
+
+[PSYCH_1:ROCK2]
+Je veux voir les Love Fist morts!
+
+[PSYCH_2:ROCK2]
+Les Love Fist ont gâché ma vie!
+
+[RBM2_I:ROCK2]
+Ferme-la un peu. C'est pas parce que Jezz encule les moutons...
+
+[RBM2_R:ROCK2]
+Oh, ferme-la!
+
+[RBM2_D:ROCK2]
+Je plaisante pas. C'est pas des conneries, mec, tu piges?
+
+[RBM2_J:ROCK2]
+C'est le truc de la fusée d'amour, tu sais?
+
+{=================================== MISSION TABLE ROCK3 ===================================}
+
+[RBM3_A:ROCK3]
+Tommy! Le psychopathe est de retour!
+
+[RBM3_B:ROCK3]
+Qu'est-ce qui se passe?
+
+[RBM3_C:ROCK3]
+Ce psychopathe ne laissera jamais les Love Fist tranquilles!
+
+[RBM3_D:ROCK3]
+Tu l'as pas tué, mon pote et il est revenu.
+
+[RBM3_E:ROCK3]
+Ouais, ouais et le truc c'est que...
+
+[RBM3_F:ROCK3]
+Le truc, c'est qu'on a besoin de quelqu'un de confiance pour conduire la limousine,
+
+[RBM3_G:ROCK3]
+parce que ce timbré continue à nous menacer!
+
+[RBM3_I:ROCK3]
+On chie tous dans nos frocs, mec.
+
+[RBM3_J:ROCK3]
+Ok, les gars, du calme, je vais m'en occuper...
+
+[RBM3_K:ROCK3]
+Normalement, j'ai mieux à foutre que de faire le taxi pour une bande d'Ecossais bisexuels bourrés,
+
+[RBM3_L:ROCK3]
+mais dans votre cas, je vais faire une exception.
+
+[ROK3_03:ROCK3]
+Autant pas faire dans la demi-mesure, alors.
+
+[ROK3_04:ROCK3]
+Hé, Tommy, change la musique!
+
+[ROK3_08:ROCK3]
+Ca commence à me faire chier, cette histoire.
+
+[ROK3_09:ROCK3]
+Garde juste le pied au plancher!
+
+[ROK3_61:ROCK3]
+Faut qu'on trouve la bombe!
+
+[ROK3_28:ROCK3]
+Je vais bientôt jouer de la basse en enfer...
+
+[ROK3_30:ROCK3]
+Que quelqu'un fasse quelque chose!
+
+[ROK3_32:ROCK3]
+Ok, toi monsieur le dur à cuire, fais quelque chose!
+
+[ROK3_34:ROCK3]
+Willy pourrait juste sucer le boomshine à la paille.
+
+[ROK3_37:ROCK3]
+Passez une paille à Willy!
+
+[ROK3_41:ROCK3]
+Quel fil, Tommy?
+
+[ROK3_42:ROCK3]
+Le vert.
+
+[ROK3_43:ROCK3]
+Y'en a pas de vert. Ou alors celui-la est vert?
+
+[ROK3_44:ROCK3]
+Est-ce qu'un de ces fils te semble vert?
+
+[ROK3_49:ROCK3]
+Ca fait des années que je te supporte!
+
+[ROK3_51:ROCK3]
+Une grosse poufiasse hurlante...
+
+[ROK3_52:ROCK3]
+Ouais!
+
+[ROK3_53:ROCK3]
+Ferme-la et arrache un fil!
+
+[ROK3_54:ROCK3]
+Lequel?
+
+[ROK3_55:ROCK3]
+Celui-là...
+
+[ROK3_56:ROCK3]
+Non!
+
+[ROK3_57:ROCK3]
+Hé, on est ok, on a pas sauté, les potes! Tommy, mon pote bravo. Et Rock and Roll!
+
+[ROK3_58:ROCK3]
+On a pas un concert où aller? Un racket à faire? Des fans à insulter?
+
+[ROK3_59:ROCK3]
+LOVE FIST!
+
+[ROK3_60:ROCK3]
+T'as fini avec cette bouteille?
+
+[RBM3_4:ROCK3]
+~r~Tu as tué les Love Fist!
+
+[RBM3_6:ROCK3]
+DETONATION :
+
+[RBM3_1:ROCK3]
+~g~Conduis les Love Fist jusqu'au concert.
+
+[RBM3_2:ROCK3]
+Si tu essayes de quitter la voiture tant que la bombe est armée, elle explosera.
+
+[RBM3_3:ROCK3]
+Si la jauge de détonation devient pleine, la bombe explose.
+
+[RBM3_8:ROCK3]
+Plus tu conduis vite, plus la jauge de détonation diminue.
+
+[RBM3_7:ROCK3]
+~g~BOMBE DESAMORCEE!
+
+[ROK3_6A:ROCK3]
+~g~Love Fist. Vous avez fini de polluer les ondes!
+
+[ROK3_6B:ROCK3]
+~g~Je vous ai donné l'occasion de devenir mes amis. Je vais maintenant vous offrir celle de mourir!
+
+[ROK3_62:ROCK3]
+alors on a pensé te montrer notre Temple du rock-
+
+[ROK3_63:ROCK3]
+Que tu te fasses une idée de la fureur des Love Fist!
+
+[ROK3_64:ROCK3]
+Ecoute-toi toi même, mon pote. C'est de la daube!
+
+[ROK3_65:ROCK3]
+Hé, à tous les gosses, c'est un temple et nous sommes les prêtres!
+
+[ROK3_66:ROCK3]
+Ouais, eh ben, si les gosses aiment leurs prêtres à moitié saouls et complètement sourds,
+
+[ROK3_67:ROCK3]
+c'est leur problème.
+
+[ROK3_68:ROCK3]
+Ah, merde, la bande de la cassette est encore bouffée.
+
+[ROK3_69:ROCK3]
+Si ça continue, faudra jouer en live.
+
+[ROK3_70:ROCK3]
+Ooooh merde! Mes intestins...
+
+[ROK3_74:ROCK3]
+Ah, tiens, qu'est-ce que c'est que ça? Tommy, mets cette cassette.
+
+[ROK3_01:ROCK3]
+Mon pote, c'est enfin l'heure d'un verre bien mérité.
+
+[ROK3_02:ROCK3]
+La salle de concert est à une centaine de mètres plus loin.
+
+[ROK3_05:ROCK3]
+Je me sens bizarre quand ma tête ne tambourine pas.
+
+[ROK3_07:ROCK3]
+Tommy, faut que tu sauves le groupe!
+
+[ROK3_29:ROCK3]
+Tommy, continue de foncer, mec!
+
+[ROK3_31:ROCK3]
+Que quelqu'un fasse quelque chose... C'est quoi ces conneries? J'ai déjà vu des minettes plus courageuses.
+
+[ROK3_33:ROCK3]
+Ecoute, mec. Moi, je joue d'un instrument, j'y connais rien aux bombes.
+
+[ROK3_35:ROCK3]
+Ouais, j'ai entendu dire que t'étais doué pour ce genre de trucs!
+
+[ROK3_38:ROCK3]
+Une paille? Hé, ici, c'est le bus de tournée des Love Fist!
+
+[ROK3_39:ROCK3]
+Où c'est que tu veux que je trouve une paille?
+
+[ROK3_46:ROCK3]
+J'aurais dû te larguer quand j'en avais l'occasion.
+
+[ROK3_47:ROCK3]
+Capitaliste!
+
+[ROK3_48:ROCK3]
+Arriviste!
+
+[ROK3_73:ROCK3]
+Jezz écoute la cassette,
+
+[RBM3_9:ROCK3]
+Si tu t'arrêtes ou conduis trop lentement, la jauge de détonation augmente.
+
+[ROK3_50:ROCK3]
+Ferme-la, pauvre abruti!
+
+[ROK3_36:ROCK3]
+Hé, j'étais raide défoncé cette nuit-là, et tu le sais bien!
+
+[RBM3_H:ROCK3]
+Je chie dans mon froc, mec. Je veux ma maman!
+
+[ROK3_45:ROCK3]
+Oh, je vois la mort dans les cartes! Tout est vert!
+
+[ROK3_6C:ROCK3]
+~g~Si tu ralentis, la limousine explosera et les GROS TOCARDS CHEVELUS avec!
+
+[ROK3_71:ROCK3]
+On doit continuer. Merci encore, Tommy! T'as assuré, mec! A plus!
+
+[ROK3_1:ROCK3]
+Enfin, mec, voici l'heure d'un verre bien mérité. La salle est juste à quelques mètres d'ici.
+
+[ROK3_2:ROCK3]
+Tu m'en sers un grand alors. Hé, Tommy, change de musique, mec.
+
+[ROK3_3:ROCK3]
+Je pète les plombs si je secoue pas la tête. Hé, regarde, c'est quoi ça? Tommy, mets cette cassette.
+
+[ROK3_4:ROCK3]
+Love Fist. Vous avez fini de polluer les ondes. Je vous ai donné une chance de devenir mes amis.
+
+[ROK3_5:ROCK3]
+Maintenant vous allez mourir. Essayez de freiner et c'est la fin! Paf, plus de limousine et plus de GROS NASES CHEVELUS non plus.
+
+[ROK3_6:ROCK3]
+Tommy, mec, tu dois sauver le groupe! J'en ai marre de ces conneries. Enlève pas ton pied de la pédale, mec!
+
+[ROK3_7:ROCK3]
+On doit trouver la bombe! On peut pas continuer à rouler toute la journée? Ouais, quoi, on a plein de trucs à boire...
+
+[ROK3_8:ROCK3]
+La bombe, elle serait pas dans le moteur? Va falloir qu'on s'arrête pour la désamorcer! Merde, mec, on va tous crever! J'vais m'bourrer la gueule!
+
+[ROK3_9:ROCK3]
+Hé, on est dans la mouise, mon pote! Tu trouveras pas ta réponse dans la boisson! Tire-toi de là!
+
+[ROK3_10:ROCK3]
+Hé, y'a des fils qui sortent de la bouteille de vodka! C'est pas de la vodka, c'est du BOOMSHINE!
+
+[ROK3_11:ROCK3]
+AAAAAHHHHHH! Elle va exploser! AAAAAAAAAAAHHHHH!!!!!!!!!!
+
+[ROK3_12:ROCK3]
+On m'avait prévenu que l'alcool me perdrait. J'ai déjà vu ça à la télé. Il suffit de tirer un de ces fils, mais lequel? J'en sais foutre rien, mec!
+
+[ROK3_13:ROCK3]
+Putain, j'en sais rien! Willy, dis quelque chose. J'vais jouer de la basse en enfer.
+
+[ROK3_14:ROCK3]
+Tommy, mec, continue de rouler à fond la caisse. Que quelqu'un fasse quelque chose! Ouais, c'est ça.
+
+[ROK3_15:ROCK3]
+'Que quelqu'un fasse quelque chose'. Putain, c'est quoi ces conneries. J'ai connu des tantes plus braves. Vas-y le gros dur, fais quelque chose!
+
+[ROK3_16:ROCK3]
+Ecoute, mec, je suis musicien moi, j'sais pas comment ça fonctionne les bombes. Willy a qu'à sucer le boomshine à la paille.
+
+[ROK3_17:ROCK3]
+Ouais, on m'a dit que ça, tu savais faire. J'étais tout émoustillé ce soir-là, comme tu le sais!
+
+[ROK3_18:ROCK3]
+T'as qu'à filer une paille à Willy! Une paille? C'est le bus de tournée des Love Fist!
+
+[ROK3_19:ROCK3]
+Où est-ce que je vais bien pouvoir trouver une paille? Quel fil, Tommy? Le vert. Y'en a pas de vert.
+
+[ROK3_20:ROCK3]
+Où peut-être qu'il est vert celui-là? T'en vois un vert, toi?
+
+[ROK3_21:ROCK3]
+Oh non! On va crever! Je vois la vie en vert! J'aurais dû me débarrasser de toi qu'en j'en avais l'occasion.
+
+[ROK3_22:ROCK3]
+Chasse la gloire! Capitaliste! Ca fait des années que je te soutiens. Ferme-là, tafiole!
+
+[ROK3_23:ROCK3]
+Une grosse chialeuse, ouais, ferme-là et tire le putain de fil! Lequel? Celui-là...
+
+[ROK3_24:ROCK3]
+NON! On est pas morts. On a pas sauté, mec!
+
+[ROK3_25:ROCK3]
+Tommy, bien joué, mec. Rock and roll, mon pote! On a pas un concert à donner, nous?
+
+[ROK3_26:ROCK3]
+Amasser du blé? Abuser des minettes? LOVE FIST!
+
+[ROK3_27:ROCK3]
+T'as fini avec cette bouteille?
+
+{=================================== MISSION TABLE SERG1 ===================================}
+
+[TEX1_A:SERG1]
+Entre et pose ton cul sur une des banquettes.
+
+[TEX1_B:SERG1]
+Putain, mon père avait l'habitude de dire qu'à cheval donné, on ne regarde pas les dents et il l'a jamais fait!
+
+[TEX1_C:SERG1]
+Tu veux une larme de bon vieux whisky?
+
+[TEX1_D:SERG1]
+Non merci.
+
+[TEX1_E:SERG1]
+Un mec qui aime avoir les idées claires, c'est bien.
+
+[TEX1_F:SERG1]
+En ce moment, mes affaires tournent pas comme elles le devraient...
+
+[TEX1_G:SERG1]
+C'est la merde! Et je veux nettoyer une partie de cette merde! T'es avec moi?
+
+[TEX1_H:SERG1]
+Euh, ouais.
+
+[TEX1_I:SERG1]
+En fait, j'ai besoin d'un mec obstiné pour me débarrasser d'une merde.
+
+[TEX1_J:SERG1]
+T'as l'air du genre persuasif.
+
+[TEX1_K:SERG1]
+La persuasion c'est ma spécialité.
+
+[TEX1_L:SERG1]
+Bon, ce mec sera au country club du golf.
+
+[TEX1_M:SERG1]
+Ils autorisent pas les flingues, alors ses gardes du corps en auront pas.
+
+[TEX1_N:SERG1]
+Va me massacrer ce salopard.
+
+[TEX1_O:SERG1]
+Tiens, voilà ta carte de membre, mais va falloir te trouver des fringues plus appropriées.
+
+[TEX1_2:SERG1]
+~g~Maintenant, direction le Leaf Links Golf Club.
+
+[TEX1_0:SERG1]
+~g~La cible est à ta portée, en train de jouer au golf. Fais en sorte que ce soit sa dernière partie!
+
+[TEX1_3:SERG1]
+C'est qui ce mec? Occupez-vous de lui!
+
+[TEX1_6:SERG1]
+Quel beau cul!
+
+[TEX1_7:SERG1]
+C'est moi, ça?
+
+[TEX1_8:SERG1]
+Chaque fois que tu ouvres ton caddie, tu reçois automatiquement un club de golf si ton emplacement d'arme de corps à corps est vide.
+
+[TEX1_9:SERG1]
+Attrapez-le!
+
+[TEX1_10:SERG1]
+Tuez-moi ce dingue!
+
+[TEX1_1:SERG1]
+~g~Va chercher des fringues de golfeur chez Jocksport's.
+
+{=================================== MISSION TABLE SERG2 ===================================}
+
+[TEXEXIT:SERG2]
+~g~Maintenant, casse-toi de Little Haiti!
+
+[TEX_2A:SERG2]
+~g~Parfait! Ils t'ont repéré!
+
+[TEX_2B:SERG2]
+~r~Imbécile! Les gens doivent VOIR un cubain faire le coup!
+
+[TEX_2C:SERG2]
+~g~Va te trouver des fringues de cubain dans Little Havana!
+
+[TEX_2D:SERG2]
+~g~Maintenant, liquide le chef de gang haïtien au salon funéraire Romero!
+
+[TEX2_A:SERG2]
+Tommy, voici Donald Love. Donald, Tommy Vercetti,
+
+[TEX2_B:SERG2]
+la dernière crapule à débarquer ici.
+
+[TEX2_C:SERG2]
+Ouais... Euh...
+
+[TEX2_D:SERG2]
+Donald, ferme-la et écoute, t'apprendras peut-être quelque chose.
+
+[TEX2_E:SERG2]
+Bon. Il y a rien de mieux qu'une bonne guerre des gangs pour faire baisser les prix de l'immobilier.
+
+[TEX2_F:SERG2]
+A part une catastrophe, peut-être, comme une peste biblique ou un truc dans le genre.
+
+[TEX2_G:SERG2]
+Mais ça serait aller un peu trop loin, dans le cas présent.
+
+[TEX2_H:SERG2]
+Tu piges, tête de gland?
+
+[TEX2_I:SERG2]
+Un chef du gang haïtien est mort y'a pas longtemps. C'est apparemment un coup des Cubains, mais personne en est sûr.
+
+[TEX2_J:SERG2]
+Alors on va arranger ça! Tu te déguises en Cubain
+
+[TEX2_K:SERG2]
+et tu fonces foutre le bordel aux funérailles. Tu leur balances la sauce et tu dégages vite fait.
+
+[TEX2_L:SERG2]
+T'as compris, Donald?
+
+[TEX2_M:SERG2]
+C'est comme faire entrer le renard dans le poulailler, hein?
+
+[TEX2_N:SERG2]
+Et puis on attend tranquillement que les prix s'écroulent.
+
+{=================================== MISSION TABLE SERG3 ===================================}
+
+[TEX3_A:SERG3]
+Regarde un peu, mon pote. J'ai un problème et je compte sur ton aide.
+
+[TEX3_B:SERG3]
+Je suis pas constructeur.
+
+[TEX3_C:SERG3]
+Ben, je pensais surtout à tes talents de démolisseur.
+
+[TEX3_D:SERG3]
+Bon, là, c'est le développement prévu, et ça,
+
+[TEX3_E:SERG3]
+c'est la propriété sur laquelle on a des vues.
+
+[TEX3_F:SERG3]
+T'essayes de me dire que ce nouveau bloc de bureaux est comme qui dirait sur le chemin.
+
+[TEX3_G:SERG3]
+T'as tout compris.
+
+[TEX3_H:SERG3]
+Bon, je vais aller faire un tour en ville pendant un moment
+
+[TEX3_I:SERG3]
+et si la construction de ces bureaux devait faire face à de subits et insurmontables problèmes structurels, alors je...
+
+[TEX3_J:SERG3]
+En tant qu'honnête citoyen, vous vous sentiriez obligé d'intervenir
+
+[TEX3_K:SERG3]
+pour la réhabilitation d'un important secteur de la ville?
+
+[TEX3_L:SERG3]
+Où on peut en trouver d'autres, des mecs dans ton genre?
+
+[TEX3_1:SERG3]
+~g~Utilise l'hélico télécommandé pour transporter des bombes sur les quatre cibles du bâtiment que tu dois détruire.
+
+[TEX3_2:SERG3]
+~g~Tu dois larguer une bombe sur chaque cible, et ce, dans n'importe quel ordre.
+
+[TEX3_5:SERG3]
+~g~Si tu largues une bombe sans succès, tu peux la récupérer pour un nouvel essai.
+
+[TEX3_7:SERG3]
+~g~Tu a alors 7 minutes pour larguer toutes les autres bombes!
+
+[TEX3_8:SERG3]
+~g~Tu as raté la cible! Récupère la bombe et réessaye!
+
+[TEX3_10:SERG3]
+~g~Largue la bombe sur la cible.
+
+[TEX3_11:SERG3]
+Cibles restantes:
+
+[TEX3_17:SERG3]
+~r~Tu as dépassé le temps imparti et le bâtiment n'est pas détruit.
+
+[TEX3_18:SERG3]
+~r~Ton hélico télécommandé a été détruit! Comment vas-tu faire pour transporter les bombes, maintenant?
+
+[TEX3_19:SERG3]
+~r~Tu as largué ta bombe dans l'eau! Tu as besoin des 4 bombes pour détruire le bâtiment!
+
+[TEX3_20:SERG3]
+~g~Ton hélico télécommandé est presque hors de portée! Retourne au bâtiment et termine le travail!
+
+[TEX3_21:SERG3]
+~r~Ton hélico télécommandé est hors de portée!
+
+[TEX3_24:SERG3]
+Appuie sur ~h~~k~~VEHICLE_LOOKLEFT~ ~w~pour faire pivoter l'hélico dans le sens inverse des aiguilles d'une montre.
+
+[TEX3_25:SERG3]
+Appuie sur ~h~~k~~VEHICLE_LOOKLEFT~ ~w~pour faire pivoter l'hélico dans le sens des aiguilles d'une montre.
+
+[TEX3_27:SERG3]
+~g~L'escalier central mène à tous les étages du bâtiment.
+
+[TEX3_31:SERG3]
+~r~Tu as détruit la camionnette qui contenait l'hélico télécommandé et les bombes!
+
+[TEX3_32:SERG3]
+Tu peux ~h~regarder derrière~w~ toi en ~h~appuyant simultanément sur ~k~~VEHICLE_LOOKLEFT~ et ~k~~VEHICLE_LOOKRIGHT~~w~.
+
+[TEX3_4:SERG3] { reVC update }
+~g~Pour larguer une bombe, appuie sur la~h~ ~k~~VEHICLE_FIREWEAPON~~w~.
+
+[TEX3_29:SERG3] { reVC update }
+Pour larguer une bombe, appuie sur la~h~ ~k~~VEHICLE_FIREWEAPON~.
+
+[TEX3_26:SERG3]
+Appuie sur la ~h~~k~~VEHICLE_BRAKE~ ~w~pour réduire la vitesse du rotor et ainsi faire~h~ descendre l'hélicoptère.
+
+[TEX3_22:SERG3]
+Appuie sur la ~h~~k~~VEHICLE_ACCELERATE~ ~w~pour augmenter la vitesse du rotor et ainsi faire~h~ monter l'hélicoptère.
+
+[TEX3_16:SERG3]
+~g~Va jusqu'au camion ~w~TOPFUN ~g~ près du bâtiment à démolir.
+
+[TEX3_33:SERG3]
+Une fois que tu as ramassé une bombe, le radar t'indique la position de la cible par rapport à l'hélico.
+
+[TEX3_34:SERG3]
+Le ~h~point triangulaire vers le haut ~w~indique que la cible se trouve ~h~au-dessus ~w~de l'hélicoptère radiocommandé.
+
+[TEX3_35:SERG3]
+Le ~h~point triangulaire vers le bas ~w~indique que la cible se trouve ~h~en dessous ~w~de l'hélicoptère radiocommandé.
+
+[TEX3_36:SERG3]
+Le ~h~point carré ~w~indique que la cible se trouve ~h~au même niveau ~w~que l'hélicoptère radiocommandé.
+
+[TEX3_6:SERG3]
+~g~Une fois que tu as ramassé une bombe pour la première fois, le compte à rebours s'enclenche.
+
+[TEX3_28:SERG3]
+Pour ~h~ramasser une bombe~w~, manoeuvre l'hélico radiocommandé à côté. Il ne peut transporter qu'une seule bombe à la fois.
+
+[TEX3_30:SERG3]
+~g~Pour ramasser une bombe, manoeuvre l'hélico radiocommandé à côté. Il ne peut transporter qu'une seule bombe à la fois.
+
+[TEX3_12:SERG3]
+~g~Bombe posée! Plus que 3 cibles! Va chercher une autre bombe!
+
+[TEX3_13:SERG3]
+~g~Bombe posée! Plus que 2 cibles! Va chercher une autre bombe!
+
+[TEX3_14:SERG3]
+~g~Bombe posée! Plus qu'une cible! Va chercher une autre bombe!
+
+[TEX3_15:SERG3]
+~r~Compte à rebours enclenché! ~g~Tu dois poser les ~w~4 bombes ~g~avant la fin du temps imparti!
+
+[TEX3_37:SERG3]
+Pousse le ~h~joystick analogique droit vers le haut ~w~pour vitesse la vitesse du rotor et ainsi faire ~h~ monter l'hélicoptère.
+
+[TEX3_38:SERG3] { reVC update }
+{Pousse le ~h~~k~~VEHICLE_ACCELERATE~ ~w~pour augmenter la réduire du rotor et ainsi faire ~h~ descendre l'hélicoptère.}
+Pousse le ~h~joystick analogique droit vers la bas ~w~pour augmenter la réduire du rotor et ainsi faire ~h~ descendre l'hélicoptère.
+
+[TEX3_39:SERG3]
+~g~Appuie sur la touche ~h~~k~~VEHICLE_HANDBRAKE~ ~g~pour larguer une bombe.
+
+[TEX3_40:SERG3]
+Appuie sur la touche ~h~~k~~VEHICLE_HANDBRAKE~ ~w~pour larguer une bombe.
+
+[TEX3_23:SERG3]
+Appuyer sur les touches ~h~~k~~VEHICLE_TURRETUP~~w~ et ~h~~k~~VEHICLE_TURRETDOWN~~w~ pour orienter l'hélicoptère dans la direction souhaitée.
+
+{=================================== MISSION TABLE TAXI1 ===================================}
+
+[FARES:TAXI1]
+CLIENTS:
+
+[TAXI1:TAXI1]
+Cherche une course.
+
+[TSCORE2:TAXI1]
+~1~$
+
+[IN_ROW:TAXI1]
+~1~ DE SUITE! Bonus : ~1~$
+
+[TAXI3:TAXI1]
+~r~Ton client est parti terrorisé!
+
+[TAXI7:TAXI1]
+~r~Ta voiture est endommagée. Fais-la réparer.
+
+[TAXI4:TAXI1]
+La course est finie!
+
+[TAXI5:TAXI1]
+BONUS DE VITESSE!
+
+[TAXI6:TAXI1]
+La mission taxi est finie
+
+[TAXIH1:TAXI1]
+Arrête-toi près d'un piéton mis en évidence pour qu'il monte, puis conduis-le à destination avant la fin du temps imparti.
+
+[FARE1:TAXI1]
+~g~Destination ~w~'le Pole Position Club' ~g~à Ocean Beach.
+
+[FARE3:TAXI1]
+~g~Destination ~w~'le Marina' ~g~à Ocean Beach.
+
+[FARE4:TAXI1]
+~g~Destination ~w~'Ammu-Nation' ~g~à Ocean Beach.
+
+[FARE5:TAXI1]
+~g~Destination ~w~'la quincaillerie' ~g~à Washington Beach.
+
+[FARE6:TAXI1]
+~g~Destination ~w~'le centre commercial de North Point' ~g~à Vice Point.
+
+[MFARE1:TAXI1]
+~g~Destination ~w~'Ammu-Nation' ~g~dans le Centre.
+
+[MFARE2:TAXI1]
+~g~Destination ~w~'le Terminal' ~g~à l'aéroport International Escobar.
+
+[WFARE3:TAXI1]
+~g~Destination ~w~'Sunshine Autos' ~g~dans Little Havana.
+
+[WFARE4:TAXI1]
+~g~Destination ~w~'les taxis Kaufman' ~g~dans Little Haiti.
+
+[WFARE5:TAXI1]
+~g~Destination ~w~'la quincaillerie' ~g~dans Little Havana.
+
+[WFARE6:TAXI1]
+~g~Destination ~w~'Howlin Petes Bike Emporium' ~g~dans le Centre.
+
+[FARE7:TAXI1]
+~g~Destination ~w~'Les bijoutiers' ~g~à Vice Point.
+
+[FARE8:TAXI1]
+~g~Destination ~w~'la plage' ~g~à Ocean Beach.
+
+[FARE9:TAXI1]
+~g~Destination ~w~'la plage' ~g~à Washington Beach.
+
+[FARE10:TAXI1]
+~g~Destination ~w~'la plage' ~g~à Vice Point.
+
+[FARE11:TAXI1]
+~g~Destination ~w~'l'hôpital' ~g~à Ocean Beach.
+
+[FARE12:TAXI1]
+~g~Destination ~w~'l'hôpital' ~g~à Vice Point.
+
+[FARE13:TAXI1]
+~g~Destination ~w~'le commissariat de police' ~g~à Washington Beach.
+
+[FARE14:TAXI1]
+~g~Destination ~w~'le commissariat de police' ~g~à Vice Point.
+
+[FARE15:TAXI1]
+~g~Destination ~w~'le restaurant de pizza' ~g~à Vice Point.
+
+[WFARE7:TAXI1]
+~g~Destination ~w~'le commissariat de police' ~g~à Little Havana.
+
+[WFARE8:TAXI1]
+~g~Destination ~w~'le commissariat de police' ~g~à Downtown.
+
+[WFARE9:TAXI1]
+~g~Destination ~w~'l'hôpital' ~g~à Downtown.
+
+[WFARE10:TAXI1]
+~g~Destination ~w~'l'hôpital' ~g~à Little Havana.
+
+[WFARE11:TAXI1]
+~g~Destination ~w~'le stade' ~g~à Downtown.
+
+[WFARE12:TAXI1]
+~g~Destination ~w~'le restaurant de pizza' ~g~à Little Haiti.
+
+[WFARE13:TAXI1]
+~g~Destination ~w~'le restaurant de pizza' ~g~à Downtown.
+
+[WFARE14:TAXI1]
+~g~Destination ~w~'les docks' ~g~à Viceport.
+
+[WFARE15:TAXI1]
+~g~Destination ~w~'la pharmacie' ~g~à Little Haiti.
+
+[FARE2:TAXI1]
+~g~Destination ~w~'le Malibu club' ~g~à Vice Point.
+
+{=================================== MISSION TABLE TAXICUT ===================================}
+
+[TAXC_A:TAXICUT]
+J'imagine que t'es le nouveau proprio.
+
+[TAXC_B:TAXICUT]
+D'où tu sors? La Mafia? Le Cartel? T'as pas l'air mexicain...
+
+[TAXC_C:TAXICUT]
+Quoi qu'il en soit, tu ferais mieux de continuer avec le barratin comme quoi les choses vont changer,
+
+[TAXC_D:TAXICUT]
+peut-être même menacer des conducteurs...
+
+[TAXC_E:TAXICUT]
+Vas-y mollo avec Ted là-bas, on vient juste de lui soigner son hernie.
+
+[TAXC_F:TAXICUT]
+Eh bien, ouais. Les choses vont changer dans le coin, madame.
+
+[TAXC_G:TAXICUT]
+Arrête tes conneries, petit. Vaut mieux que tu me laisses faire.
+
+[TAXC_H:TAXICUT]
+Ca fait des années que je suis dans ce genre de biz.
+
+[TAXC_I:TAXICUT]
+Ecoutez tous.
+
+[TAXC_J:TAXICUT]
+On a une nouvelle direction et les choses vont encore changer dans le coin.
+
+[TAXC_K:TAXICUT]
+Notre nouvelle direction, la...
+
+[TAXC_L:TAXICUT]
+Tu fais partie de quel gang?
+
+[TAXC_M:TAXICUT]
+En fait, je fais pas partie d'un gang...
+
+[TAXC_N:TAXICUT]
+C'est quoi ton foutu nom, petit?
+
+[TAXC_O:TAXICUT]
+Vercetti, Tommy Vercetti.
+
+[TAXC_P:TAXICUT]
+Notre nouvelle direction, le gang Vercetti,
+
+[TAXC_Q:TAXICUT]
+va veiller à nous éviter les emmerdes.
+
+[TAXC_R:TAXICUT]
+Capiche? Terminé!
+
+[TAXC_S:TAXICUT]
+Qu'est-ce que t'as pensé du 'capiche'? Moi, j'ai bien aimé le 'capiche'.
+
+[TAXC_T:TAXICUT]
+Bon, alors c'est comme ça que ça marchait avant
+
+[TAXC_U:TAXICUT]
+et on va continuer à faire tourner l'entreprise comme ça.
+
+[TAXC_V:TAXICUT]
+Si on a des ennuis avec une compagnie concurrente, tu leur flanques une dérouillée.
+
+[TAXC_W:TAXICUT]
+Puis ils nous flanquent une dérouillée.
+
+[TAXC_X:TAXICUT]
+puis tu leur flanques une dérouillée,
+
+[TAXC_Y:TAXICUT]
+et cetera et cetera. T'as pigé?
+
+[TAXC_Z:TAXICUT]
+Euh, ouais, je crois...
+
+[TAXC_A1:TAXICUT]
+Prends simplement un taxi au garage si tu te sens de bosser.
+
+{=================================== MISSION TABLE TAXIWA1 ===================================}
+
+[OUTTIME:TAXIWA1]
+~r~T'es trop lent, mec, trop lent!
+
+[TAX1_1:TAXIWA1]
+Ok, on a un client rupin qui a besoin d'être ramassé à Starfish island, ça intéresse quelqu'un?
+
+[TAX1_2:TAXIWA1]
+Ici, Tommy, je prends!
+
+[TAX1_3:TAXIWA1]
+C'est mon client, dégage!
+
+[TAX1_4:TAXIWA1]
+Allez, vite, monte!
+
+[TAX1_5:TAXIWA1]
+Ok, ok, mais ne me faites pas de mal!
+
+[TAXW1_1:TAXIWA1]
+~g~Va prendre le V.I.P. sur Starfish Island.
+
+[TAXW1_2:TAXIWA1]
+~g~Ramène le V.I.P.! Bousille l'autre bagnole!
+
+[TAXW1_3:TAXIWA1]
+~r~Le V.I.P. est mort!
+
+[TAXW1_4:TAXIWA1]
+~r~Le V.I.P. a été déposé!
+
+[TAXW1_6:TAXIWA1]
+~g~Emmène le V.I.P. à l'aéroport!
+
+{=================================== MISSION TABLE TAXIWA2 ===================================}
+
+[TAX2_1:TAXIWA2]
+Appel à toutes les voitures, on perd des clients dans toute la ville! Qu'est-ce que vous foutez, les gars?
+
+[TAX2_2:TAXIWA2]
+Les taxis VC nous les prennent! Ils ont trop de voitures, on peut pas rivaliser!
+
+[TAX2_3:TAXIWA2]
+Vercetti, si t'es en ville en train d'écouter, va falloir mettre quelques taxis VC hors circuit ou c'est la faillite!
+
+[TAXW2_1:TAXIWA2]
+~g~Détruis 3 taxis concurrents!
+
+{=================================== MISSION TABLE TAXIWA3 ===================================}
+
+[TAX3_1:TAXIWA3]
+Voiture 13, on a une demoiselle Cortez à prendre dans le centre, elle vous a spécialement demandé.
+
+[TAX3_2:TAXIWA3]
+Ok, je prends. Voiture 13 en course!
+
+[TAX3_3:TAXIWA3]
+Hmmmm, aucun signe de Mercedes...
+
+[TAXW3_3:TAXIWA3]
+~g~Bousille le taxi leader!
+
+[TAXW3_2:TAXIWA3]
+~g~Reste vivant jusqu'à la fin du temps imparti.
+
+[TAX_AS1:TAXIWA3]
+COMPAGNIE DE TAXIS ACQUISE
+
+[TAX_AS2:TAXIWA3]
+~G~Les taxis Kaufman génère dorénavant un revenu de $~1~ maximum. Pense à récupérer le fric régulièrement.
+
+[TAX3_4:TAXIWA3]
+L'heure est venue pour l'ange gardien des taxis Kaufman de froisser de la tôle!
+
+[TAX3_5:TAXIWA3]
+Hé mec, j'vais te bousiller ta caisse!
+
+{ reVC updates }
{ new languages }
[FEL_JAP]
JAPONAIS
@@ -8195,8 +14578,8 @@ POLONAIS
RUSSE
{ new display menus }
-[FET_GFX] { this probably needs to be retranslated }
-CONFIG. EFFETS SPECIAUX
+[FET_GFX]
+GRAPHICS SETUP
[FED_MIP]
MIP MAPPING
@@ -8260,7 +14643,6 @@ REJOUER MISSION
[FESZ_RM]
REJOUER?
-{ more graphics }
[FED_VPL]
VEHICLE PIPELINE
@@ -8300,19 +14682,11 @@ PS2
[FEM_XBX]
XBOX
-[FEM_AUT] { aspect ratio related }
-AUTO
-
-{ controls }
[FEC_IVP]
INVERT PAD VERTICALLY
-{ map }
-[FEM_TWP]
-Toggle Waypoint
-
-[FEA_FMN]
-RADIO ETEINTE
+[FEM_NON]
+NONE
[FEC_DS2]
DUALSHOCK 2
@@ -8332,44 +14706,18 @@ XBOX ONE CONTROLLER
[FEC_TYP]
GAMEPAD TYPE
-[FEC_CCF]
-CONFIGURATION
-
-[FEC_CF1]
-CONFIGURATION 1
-
-[FEC_CF2]
-CONFIGURATION 2
-
-[FEC_CF3]
-CONFIGURATION 3
-
-[FEC_CF4]
-CONFIGURATION 4
-
-[FEC_CDP]
-AFFICHAGE DE LA MANETTE
-
-[FEC_ONF]
-A PIED
-
-[FEC_INC]
-DANS UN VÉHICULE
-
-[FEC_VIB]
-VIBRATIONS
-
[FET_AGS]
GAMEPAD SETTINGS
+[FEM_AUT] { aspect ratio related }
+AUTO
+
[FEM_PED]
PED DENSITY
[FEM_CAR]
CAR DENSITY
-{ end of file }
-
[DUMMY]
THIS LABEL NEEDS TO BE HERE !!!
AS THE LAST LABEL DOES NOT GET COMPILED \ No newline at end of file
diff --git a/utils/gxt/german.txt b/utils/gxt/german.txt
index 5f5c53c4..595d792a 100644
--- a/utils/gxt/german.txt
+++ b/utils/gxt/german.txt
@@ -5,89 +5,257 @@
unnecessary edits like rephasing because you think it suits better for your taste.
}
-[LETTER1]
-abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789"$,.'-?!!SDBF
+[RAMPAGE]
+AMOKLAUF!!
-[DEFNAM]
-Claude----------------------
+[RAMP_F]
+AMOKLAUF FEHLGESCHLAGEN!!
-[ARSE]
-ü ß ä
+[RAMP_P]
+AMOKLAUF BESTANDEN!!
-[IN_VEH]
-~g~Hey! Zurück ins Auto!!
+[RAMP_A]
+ALLE AMOKLÄUFE BESTANDEN!!
-[IN_VEH2]
-~g~Du brauchst einen Schlitten für diesen Job!
+[PAGE_01]
+Dein Job: ~1~ Gang-Mitglieder in 2 Minuten!
-[IN_BOAT]
-~g~Du brauchst ein Boot für diesen Job!
+[PAGE_02]
+Zerstöre ~1~ Fahrzeuge in 2 Minuten!
-[HEY]
-~g~Keine Alleingänge. Halt die Gang beisammen!
+[PAGE_03]
+Erledige ~1~ Gang-Mitglieder in 2 Minuten im Vorbeifahren!
-[HEY2]
-~g~Nicht aufteilen. Halt die Leute zusammen!
+[PAGE_04]
+Überfahre ~1~ Gang-Mitglieder in 2 Minuten!
-[HEY3]
-~g~Du hast deinen besten Mann verloren. Los, zurück! Hol 8-Ball!
+[PAGE_05]
+Dein Job: ~1~ Gang-Mitglieder in 2 Minuten!
-[HEY4]
-~g~Wenn du Misty verlierst, kriegst du's mit Luigi zu tun. Los, hol sie.
+[SENTXS]
+Sentinel XS
-[HEY5]
-~g~Eines der Girls fehlt. Los, zurück! Treib das Mädchen auf!
+[MAP_LEG]
+Legende
-[HEY6]
-~g~Du stehst mit deiner Ehre für den Yakuza Kanbu ein. Du musst ihn beschützen!
+[VCNMAV]
+VCN Maverick
-[HEY7]
-~g~Ein Mann mehr kann nicht schaden. Los, zurück. Hol deinen Kontaktmann ab!
+[LG_01]
+Position des Spielers
-[HEY8]
-~g~Beschützen heißt so viel wie beschützen - Beschütze den alten Asiaten!
+[LG_02]
+Avery Carrington
-[HEY9]
-~g~Du willst wissen, was so geredet wird? Sprich mit deinem Kontaktmann!
+[LG_03]
+Biker-Kontaktpunkt
-[HELP2_A]
-Drücke die ~h~/-Taste~w~, um zu ~h~sprinten.
+[LG_04]
+Colonel Cortez
-[HELP3]
-Du kannst nur kurze Zeit sprinten, ohne müde zu werden.
+[LG_05]
+Ricardo Diaz
-[HELP4_A]
-Drücke die~h~ ~k~~VEHICLE_ACCELERATE~-Taste~w~, um zu ~h~beschleunigen.
+[LG_06]
+Kent Paul
-[HELP4_D]
-Drücke den~h~ Rechten Analog-Stick nach oben, um zu ~h~beschleunigen.
+[LG_07]
+Rechtsanwalt
-[HELP5_A]
-Drücke die~h~ ~k~~VEHICLE_BRAKE~-Taste~w~, um zu ~h~bremsen~w~, oder um ~h~zurückzusetzen~w~, wenn das Fahrzeug steht.
+[LG_08]
+Phil Cassidy
-[HELP5_D]
-Zieh den ~h~Rechten Analog-Stick~w~ zurück, um zu ~h~bremsen~w~, oder um ~h~zurückzusetzen~w~, wenn das Fahrzeug steht.
+[LG_09]
+Bootswerft
-[HELP6_A]
-Drücke die~h~ ~k~~VEHICLE_HANDBRAKE~-Taste~w~, um die ~h~Handbremse anzuziehen.
+[LG_10]
+Malibu Club
-[HELP6_C]
-Drücke die~h~ ~k~~VEHICLE_HANDBRAKE~-Taste~w~, um die ~h~Handbremse anzuziehen.
+[LG_11]
+Kubaner
-[HELP6_D]
-Drücke die~h~ ~k~~VEHICLE_HANDBRAKE~-Taste~w~, um die ~h~Handbremse anzuziehen.
+[LG_12]
+Filmstudio
-[HELP7_A]
-Halte die~h~ ~k~~PED_LOCK_TARGET~-Taste ~w~gedrückt, um mit dem Präzisionsgewehr zu zielen.
+[LG_13]
+AmmuNation
-[HELP7_D]
-Halte die~h~ ~k~~PED_LOCK_TARGET~-Taste ~w~gedrückt, um mit dem Präzisionsgewehr zu zielen.
+[LG_14]
+Haitianer
-[HELP8_A]
-Drücke die~h~ ~k~~PED_SNIPER_ZOOM_IN~-Taste~w~, um ~h~an das Ziel heranzuzoomen ~w~und die~h~ ~k~~PED_SNIPER_ZOOM_OUT~-Taste~w~,um ~h~herauszuzoomen ~w~.
+[LG_15]
+Eisenwarenladen
-[HELP9_A]
-Drücke die~h~ ~k~~PED_FIREWEAPON~-Taste~w~, um das Präzisionsgewehr abzufeuern.
+[LG_16]
+Versteck
+
+[LG_17]
+Eiscreme
+
+[LG_18]
+Kaufman-Taxis
+
+[LG_19]
+Love Fist
+
+[LG_20]
+Druckerei
+
+[LG_21]
+Immobilie
+
+[LG_22]
+Pay 'n' Spray
+
+[LG_23]
+Bekleidungsgeschäft
+
+[LG_24]
+Tommys Villa
+
+[LG_25]
+Telefon
+
+[LG_26]
+Radiosender Wildstyle
+
+[LG_27]
+Radiosender Flash FM
+
+[LG_28]
+Radiosender KChat
+
+[LG_29]
+Radiosender Fever 105
+
+[LG_30]
+Radiosender VRock
+
+[LG_31]
+Polizeifunk-Zentrale
+
+[LG_32]
+Radiosender Espantoso
+
+[LG_33]
+Radiosender Emotion 98.3
+
+[LG_34]
+Radiosender Wave 103
+
+[LG_36]
+Sun Yard
+
+[LG_37]
+Stripper-Bar
+
+[MAP_YAH]
+DU BIST HIER
+
+[TAXSHRT]
+~g~Du kannst dieses Kaufman-Taxi nehmen, statt selbst Auto zu fahren. Das kostet dich $9.
+
+[MOB_09D]
+Vielleicht hab ich Leo ja erledigt und mir sein Handy genommen. Hast du schon mal daran gedacht, du Penner?
+
+[FE_MLG]
+KARTENLEGENDE
+
+[FED_RDR]
+RADAR-MODUS
+
+[FED_HUD]
+HUD-MODUS
+
+[FED_RDL]
+GROSS
+
+[FED_RDB]
+NUR SYMBOLE
+
+[FED_HUF]
+INFOS EIN- & AUSBLENDEN
+
+[FEST_HV]
+Höchstes Bürgerwehr-Missions-Level
+
+[BRIBE1]
+Du hast soeben Polizei-Bestechungsgeld aufgenommen, dein Fahndungslevel verringert sich damit um einen Stern.
+
+[CLOHELP]
+Saubere Klamotten!!
+
+[SUNSHIN]
+Sunshine Autos
+
+[CHERRYP]
+Cherry Popper Eiscreme
+
+[KAUFCAB]
+Kaufman-Taxis
+
+[BOATYAR]
+Die Bootswerft
+
+[WANT_L]
+Dein Fahndungslevel ist bis auf weiteres aufgehoben. Solltest du ein Verbrechen begehen, während die Sterne blinken, wird dein volles Fahndungslevel wieder aktiv.
+
+[PICK1]
+Kugelsichere Weste im Ocean View Hotel angeliefert!
+
+[HOTRNG]
+HOTRING
+
+[BLODRNG]
+CHAOS-DERBY
+
+[DIRTRNG]
+DIRTRING
+
+[FEC_ABR]
+Beschleunigen, Bremsen oder Zurücksetzen
+
+[FEI_BTU]
+; = -
+
+[FEI_SCR]
+Scrollen
+
+[SKUMBUY]
+Skumole Shack gekauft: $ ~1~
+
+[SKUM_L]
+Drücke die ~h~L1-Taste~w~, um Skumole Shack zu kaufen. Preis: $~1~
+
+[SKUM_T]
+Drücke die ~t~"-Taste~w~, um Skumole Shack zu kaufen. Preis: $~1~
+
+[SKUM_C]
+Drücke die ~o~|-Taste~w~, um Skumole Shack zu kaufen. Preis: $~1~
+
+[LG_35]
+Ziel
+
+[IN_VEH]
+~g~Hey! Zurück ins Auto!!
+
+[HEY]
+~g~Keine Alleingänge. Halt die Gang beisammen!
+
+[HELP3]
+Du kannst nur kurze Zeit sprinten, ohne müde zu werden.
+
+[HELP4_D]
+Drücke den~h~ rechten Analog-Stick nach oben, um zu ~h~beschleunigen.
+
+[HELP5_D]
+Zieh den ~h~rechten Analog-Stick~w~ zurück, um zu ~h~bremsen~w~, oder um ~h~zurückzusetzen~w~, wenn das Fahrzeug steht.
+
+[HELP7_A]
+Halte die~h~ ~k~~PED_LOCK_TARGET~ ~w~gedrückt, um mit dem Präzisionsgewehr zu zielen.
+
+[HELP7_D]
+Halte die~h~ ~k~~PED_LOCK_TARGET~ ~w~gedrückt, um mit dem Präzisionsgewehr zu zielen.
[HELP10]
Dieser Stern zeigt an, dass du von der Polizei gesucht wirst.
@@ -101,78 +269,48 @@ Manchmal musst du vielleicht Wege finden, die das Radar nicht zeigt.
[TIMER]
Diese Mission hat ein Zeitlimit. Du musst sie beendet haben, bevor die Zeit um ist.
-[MISTY1]
-~r~Misty ist hinüber!
-
-[OUT_VEH]
-~g~Raus aus dem Fahrzeug!
-
-[GARAGE]
-Fahr den Wagen in eine Garage und geh dann nach draußen.
-
-[WANTED1]
-~g~Schüttle die Cops ab. Verringere deinen Fahndungslevel.
-
-[NODOORS]
-~g~Das sind keine Sardinen! Besorg einen Wagen mit ausreichend Sitzplätzen.
-
-[TRASH]
-~g~Du hast deine Karre ziemlich geschrottet! Repariere sie!
-
-[WRECKED]
-~r~Das Fahrzeug ist Schrott!
-
[HORN]
~g~Drück auf die Hupe.
-[HORN4]
-Drück die ~h~L3-Taste~w~, um zu hupen.
-
[NOMONEY]
~g~Du brauchst mehr Cash!
-[OUTTIME]
-~r~Zu langsam, Mann, zu langsam!
-
-[SPOTTED]
-~r~Sie sind dir auf den Fersen!
-
[REWARD]
BELOHNUNG $~1~
-[GAMEOVR]
-GAME OVER
-
-[Z]
-Z-Achse Wert: ~1~
-
[M_FAIL]
MISSION FEHLGESCHLAGEN!
[M_PASS]
MISSION ERFÜLLT! $~1~
-[O_PASS]
-JOB ERLEDIGT!
-
-[O_FAIL]
-JOB FEHLGESCHLAGEN!
-
[DEAD]
AUSSER GEFECHT!
[BUSTED]
VERHAFTET!
-[S_PROMP]
-Außerhalb einer Mission kannst du dein ~h~Spiel hier speichern~w~. Dies rückt die Uhr um sechs Stunden vor.
+[WEATHE1]
+WETTER AUF SONNIG UMSTELLEN
+
+[WEATHE2]
+WETTER AUF SEHR SONNIG UMSTELLEN
+
+[WEATHE3]
+WETTER AUF BEWÖLKT UMSTELLEN
+
+[WEATHE4]
+WETTER AUF REGNERISCH UMSTELLEN
+
+[WEATHE5]
+WETTER AUF NEBLIG UMSTELLEN
+
+[WEATHE6]
+WETTER NORMAL
[NUMBER]
~1~
-[SCORE]
-$~1~
-
[LOADCAR]
LADE FAHRZEUG... (ABBRECHEN MIT L1)
@@ -191,44 +329,11 @@ Cheat Modus AN
[CHEATOF]
Cheat Modus AUS
-[UZI_IN]
-Die Uzi ist jetzt im AmmuNation zu haben!
-
[IMPORT1]
Geh nach draußen und warte auf dein Fahrzeug.
-[PAGEB1]
-Pistole wurde im Versteck angeliefert.
-
-[PAGEB2]
-Uzi wurde im Versteck angeliefert.
-
-[PAGEB3]
-Kugelsichere Weste wurde im Versteck angeliefert.
-
-[PAGEB4]
-Schrotflinte wurde im Versteck angeliefert.
-
-[PAGEB5]
-Granaten wurden im Versteck angeliefert.
-
-[PAGEB6]
-Molotowcocktails wurden im Versteck angeliefert.
-
-[PAGEB7]
-AK47 wurde im Versteck angeliefert.
-
-[PAGEB8]
-Präzisionsgewehr wurde im Versteck angeliefert.
-
-[PAGEB9]
-M16 wurde im Versteck angeliefert.
-
-[PAGEB10]
-Raketenwerfer wurde im Versteck angeliefert.
-
[PAGEB11]
-Flammenwerfer wurde im Versteck angeliefert.
+Flammenwerfer in Versteck angeliefert.
[WANT_A]
Verhaftet wirst du nur, wenn die Polizei nach dir ~h~fahndet.
@@ -272,6719 +377,6642 @@ Du verlierst alle Waffen, und die Ärzte knöpfen dir ein wenig Cash für die Be
[HEAL_E]
Je länger du spielst, desto mehr Wege wirst du finden, dich selbst zu verarzten oder zu schützen.
-[DAM]
-SCHADEN:
-
-[KILLS]
-HITS:
-
-[FARES]
-FAHRTEN
-
-[BULL]
-GOLDBARREN
-
-[EVID]
-BEWEISMITTEL
-
-[HEALTH]
-ZUSTAND AUTO
-
-[COLLECT]
-GESAMMELT:
-
-[BOMB]
-Fahr deinen Wagen in die Bombenwerkstatt, um eine ~h~Bombe~w~ anzubringen. Kosten - ~h~$1000.
-
[SAVE1]
-Geh durch den Eingang. So kannst du dein ~h~Spiel speichern~w~. Während einer Mission kannst du nicht speichern.
+Stell dich in die Markierung. So kannst du dein ~h~Spiel speichern~w~. Während einer Mission kannst du nicht speichern.
[SAVE2]
Jedes Fahrzeug, das in dieser Garage abgestellt wird, wird für dich aufbewahrt, wenn das Spiel gespeichert wird.
[AMMU]
-Betritt den AmmuNation-Laden, um eine Waffe zu kaufen.
-
-[BRIDGE1]
-Wenn die Callahan Bridge repariert ist, kannst du nach Staunton Island rüber fahren.
-
-[TUNNEL]
-Wenn der Porter Tunnel geöffnet ist, kannst du nach Staunton Island rüber fahren.
-
-[LUIGI]
-LUIGI MISSIONEN
+Betritt den Ammu-Nation, um eine Waffe zu kaufen.
-[TONI]
-TONI MISSIONEN
-
-[JOEY]
-JOEY MISSIONEN
-
-[FRANK]
-SALVATORE MISSIONEN
-
-[DIABLO]
-DIABLO MISSIONEN
+[R_TIME]
+ZEIT:
-[ASUKA]
-ASUKA MISSIONEN
+[PROP_1]
+Du hast nicht genug Cash für dieses Objekt.
-[B_SITE]
-ASUKA VORSTADT-MISSIONEN
+[PROP_2]
+Während einer Mission kannst du keine Objekte kaufen.
-[KENJI]
-KENJI MISSIONEN
+[IND_ZON]
+Vice City Beach
-[RAY]
-RAY MISSIONEN
+[COM_ZON]
+Vice City Mainland
-[LOVE]
-LOVE MISSIONEN
+[BEACH1]
+Ocean Beach
-[YARDIE]
-YARDIE MISSIONEN
+[BEACH2]
+Washington Beach
-[HOOD]
-HOOD MISSIONEN
+[BEACH3]
+Vice Point
-[CITYZON]
-Liberty City
+[GOLFC]
+Leaf Links Golfclub
-[IND_ZON]
-Portland
+[STARI]
+Starfish Island
-[PORT_W]
-Callahan Point
+[DOCKS]
+Viceport
-[PORT_S]
-Atlantic Quays
+[HAVANA]
+Little Havana
-[PORT_E]
-Portland Harbor
+[HAITI]
+Little Haiti
-[PORT_I]
-Trenton
+[PORNI]
+Prawn Island
-[S_VIEW]
-Portland View
+[DTOWN]
+Downtown
-[CHINA]
-Chinatown
+[VICE_C]
+Vice City
-[EASTBAY]
-Portland Beach
+[A_PORT]
+Escobar Inter. Airport
-[LITTLEI]
-Saint Mark's
+[JUNKY]
+Schrottplatz
-[REDLIGH]
-Rotlichtbezirk
+[PISTOL]
+Pistole
-[TOWERS]
-Hepburn Heights
+[PYTHON]
+.357
-[HARWOOD]
-Harwood
+[UZI]
+Uz-1
-[ROADBR1]
-Callahan Bridge
+[TEC9]
+Tec 9
-[ROADBR2]
-Callahan Bridge
+[M4]
+M4
-[TUNNELP]
-Porter Tunnel
+[INGRAM]
+Mac
-[BOMB1]
-8-Balls Werkstatt
+[MP5]
+MP
-[COM_ZON]
-Staunton Island
+[RUGER]
+Kruger
-[STADIUM]
-Aspatria
+[SNIPE]
+Präzisionsgewehr
-[HOSPI_2]
-Rockford
+[GRENADE]
+Granaten
-[UNIVERS]
-Liberty Campus
+[SHOTGN1]
+Schrotflinte
-[CONSTRU]
-Fort Staunton
+[SHOTGN2]
+S.P.A.S. 12
-[PARK]
-Belleville Park
+[SHOTGN3]
+Abgesägte Schrotflinte
-[COM_EAS]
-Newport
+[ARMOUR]
+Kugelsichere Weste
-[SHOPING]
-Bedford Point
+[LASER]
+.308 Präzisionsgewehr
-[YAKUSA]
-Torrington
+[BASEBAT]
+Baseballschläger
-[SUB_ZON]
-Shoreside Vale
+[HAMMER]
+Hammer
-[AIRPORT]
-Francis Int. Airport
+[SCREWD]
+Schraubenzieher
-[PROJECT]
-Wichita Gardens
+[CLEVER]
+Fleischerbeil
-[SUB_IND]
-Pike Creek
+[MACHETE]
+Machete
-[SWANKS]
-Cedar Grove
+[KNIFE]
+Messer
-[BIG_DAM]
-Cochrane Dam
+[KATANA]
+Katana
-[SUB_ZO2]
-Shoreside Vale
+[CHAINSA]
+Kettensäge
-[SUB_ZO3]
-Shoreside Vale
+[G_COST]
+$~1~
[CAR_1]
Krankenwagen
-[CAR_2]
-Feuerwehrwagen
+[MALIBU]
+Malibu Club
-[CAR_3]
-Polizei
+[MANSION]
+Diaz' Haus
-[CAR_4]
-Enforcer
+[TMANS]
+Vercetti Estate
-[CAR_5]
-Barracks
+[STRIP]
+Pole Position Club
-[CAR_6]
-Rhino
+[MALL1]
+North Point Einkaufszentrum
-[CAR_7]
-FBI-Wagen
+[BANKINT]
+El Banco Corrupto Grande
-[CAR_8]
-Securicar
+[RANGE]
+Schießstand
-[CAR_9]
-Moonbeam
+[POL_HQ]
+Vice City Polizeihauptquartier
-[CAR_10]
-Kleinbus
+[INT_B]
+Ein alter Freund
-[CAR_11]
-Lkw
+[INTB_1]
+~g~Begib dich in die Anwaltskanzlei.
-[CAR_12]
-Linerunner
+[LAW_1]
+Die Party
-[CAR_13]
-Trashmaster
+[LAW_2]
+Dunkle Gassen
-[CAR_14]
-Patriot
+[LAW_3]
+Die Geschworenen
-[CAR_15]
-Mr Whoopee
+[LAW_4]
+Aufruhr
-[CAR_16]
-Mule
+[COL_1]
+Der Verräter
-[CAR_17]
-Yankee
+[COL_2]
+Kugelhagel im Einkaufszentrum
-[CAR_18]
-Pony
+[COL_3]
+Die Schutzengel
-[CAR_19]
-Bobcat
+[COL_4]
+Zu Befehl, Sir!
-[CAR_20]
-Rumpo
+[COL_5]
+Alle Mann an Deck!
-[CAR_21]
-Blista
+[COK_1]
+Die Jagd
-[CAR_22]
-Dodo
+[COK_2]
+Phnom Penh '86
-[CAR_23]
-Bus
+[COK_3]
+Das schnellste Boot
-[CAR_24]
-Sentinel
+[COK_4]
+Angebot & Nachfrage
-[CAR_25]
-Cheetah
+[KENT_1]
+Die Befreiungsaktion
-[CAR_26]
-Banshee
+[ASS_1]
+Pizza Mortale
-[CAR_27]
-Stinger
+[BUD_1]
+Fette Beute
-[CAR_28]
-Infernus
+[BUD_2]
+Zoff in der Bar
-[CAR_29]
-Esperanto
+[BUD_3]
+Cop-Land
-[CAR_30]
-Kuruma
+[CAP_1]
+Der Eintreiber
-[CAR_31]
-Stretch Limo
+[FIN_1]
+Freunde und andere Feinde
-[CAR_32]
-Perennial
+[BANK_1]
+Kein Entkommen?
-[CAR_33]
-Landstalker
+[BANK_2]
+Der Scharfschütze
-[CAR_34]
-Manana
+[BANK_3]
+Der Fahrer
-[CAR_35]
-Idaho
+[BANK_4]
+Der Coup
-[CAR_36]
-Stallion
+[CNT_1]
+Der Singvogel
-[CAR_37]
-Taxi
+[CNT_2]
+Der Kurier
-[CAR_38]
-Cabbie
+[PORN_1]
+Alle meine Pferdchen
-[CAR_39]
-Buggy
+[PORN_2]
+Der Dildo-Jet
-[LUIGIS]
-Luigis Club
+[PORN_3]
+Ein Mann namens Martha
-[GOAWAY]
-~g~Du bist bereits auf einer Mission!
+[PORN_4]
+Heiße Lightshow
-[LUIGGO]
-~g~Luigi checkt gerade ein paar neue Girls aus. Komm später wieder!
+[TAX_1]
+Kaufman-Taxis
-[JOEYGO]
-~g~Joey ist mit Misty in der Stadt unterwegs. Komm später wieder!
+[TAXI_1]
+V.I.P
-[TONIGO]
-~g~Toni ist mit seiner Mamma in der Oper. Probier's ein andermal!
+[TAXI_2]
+Konkurrentenjagd
-[KEMUGO]
-~g~Maria und Kemuri sind gerade beschäftigt. Versuch's später nochmal!
+[TAXI_3]
+Das Taxi-Inferno
-[KENJGO]
-~g~Kenji ist bei einem Yakuza-Treffen. Schau ein andermal wieder vorbei.
+[ICE_1]
+Eiscreme und andere Leckereien
-[RAYGO]
-~g~Ray hängt gerade auf irgend einem anderen Klo rum. Komm später wieder!
+[TEX_1]
+Schlagende Argumente
-[LOVEGO]
-~g~Donald Love hat anderes zu tun. Vielleicht hat er später Zeit!
+[TEX_2]
+Das Begräbnis
-[KENSGO]
-~g~Kenji hat zu tun! Komm später wieder!
+[TEX_3]
+Schutt und Asche
-[ASUSGO]
-~g~Asuka hat gerade überhaupt keine Zeit!
+[PHIL_1]
+Der Waffenschieber
-[HOODGO]
-~g~Die Hoods haben gerade keine Zeit!
+[PHIL_2]
+TNT-Whiskey
-[WRONGT1]
-~g~Komm zwischen 05:00 und 21:00 wieder. Dann gibt's einen Job.
+[BIKE_1]
+Wheels of Steel
-[WRONGT2]
-~g~Komm zwischen 06:00 und 14:00 wieder. Dann gibt's einen Job.
+[BIKE_2]
+Chaos-City
-[WRONGT3]
-~g~Komm zwischen 15:00 und 00:00 wieder. Dann gibt's einen Job.
+[BIKE_3]
+Big Bakers Bike
-[GUN_1A]
-Benutze die ~h~~k~~PED_CYCLE_WEAPON_RIGHT~-Taste ~w~und die ~h~~k~~PED_CYCLE_WEAPON_LEFT~-Taste~w~, um zwischen deinen Waffen zu wechseln.
+[ROCK_1]
+Love Juice
-[GUN_2A]
-Halte die ~h~~k~~PED_LOCK_TARGET~-Taste ~w~gedrückt, um automatisch zu zielen. Drücke die~h~ ~k~~PED_FIREWEAPON~-Taste~w~, um zu feuern! Versuch, die Ziele zu treffen...
+[ROCK_2]
+Der Psychokiller
-[GUN_2C]
-Halte die ~h~~k~~PED_LOCK_TARGET~-Taste ~w~gedrückt, um automatisch zu zielen. Drücke die~h~ ~k~~PED_FIREWEAPON~-Taste~w~, um zu feuern! Versuch, die Ziele zu treffen...
+[ROCK_3]
+Die PR-Tour
-[GUN_2D]
-Halte die ~h~~k~~PED_LOCK_TARGET~-Taste ~w~gedrückt, um automatisch zu zielen. Drücke die~h~ ~k~~PED_FIREWEAPON~-Taste~w~, um zu feuern! Versuch, die Ziele zu treffen...
+[ROCK_4]
+Love Fist!
-[GUN_3A]
-Halte die ~h~~k~~PED_LOCK_TARGET~-Taste~w~ gedrückt und drücke die ~h~~k~~PED_CYCLE_TARGET_LEFT~-Taste~w~ oder die ~h~~k~~PED_CYCLE_TARGET_RIGHT~-Taste, um das Ziel zu wechseln.
+[HAT_1]
+Mysteriöses Pulver
-[GUN_3B]
-Halte die ~h~~k~~PED_LOCK_TARGET~-Taste~w~ gedrückt und drücke die ~h~~k~~PED_CYCLE_TARGET_LEFT~-Taste~w~ oder die ~h~~k~~PED_CYCLE_TARGET_RIGHT~-Taste, um das Ziel zu wechseln.
+[HAT_2]
+Fliegende Bomben
-[GUN_4A]
-Mit gedrückter ~h~~k~~PED_LOCK_TARGET~-Taste~w~ kannst du gehen oder laufen und behältst dein Ziel im Visier.
+[HAT_3]
+Schmutzige Methoden
-[GUN_4B]
-Mit gedrückter ~h~~k~~PED_LOCK_TARGET~-Taste~w~ kannst du gehen oder laufen und behältst dein Ziel im Visier.
+[CUB_1]
+Stunt-Boot-Action
-[GUN_5]
-An diesen Pappkameraden kannst du zielen und schießen üben. Wenn du fertig bist, widme dich wieder deiner Mission.
+[CUB_2]
+Kanonenfutter
-[TAXI1]
-~g~Besorg dir einen Passagier.
+[CUB_3]
+Die Seeschlacht
-[FARE1]
-~g~Fahrziel: ~w~'Meeouch Sex Kitten Club' ~g~im Rotlichtbezirk.
+[CUB_4]
+Trojanisches Voodoo
-[FARE2]
-~g~Fahrtziel: ~w~'Supa Save' ~g~in Portland View.
+[JOB_1]
+Der Pizza-Lieferant
-[FARE3]
-~g~Fahrtziel: ~w~'Alte Schulhalle' ~g~in Chinatown.
+[JOB_2]
+Ein bedauerlicher Unfall
-[FARE4]
-~g~Fahrtziel: ~w~'Greasy Joe's Cafe' ~g~in Callahan Point.
+[JOB_3]
+Die rasende Schrottfabrik
-[FARE5]
-~g~Fahrtziel: ~w~'AmmuNation' ~g~im Rotlichtbezirk.
+[JOB_4]
+Trouble am Check-In
-[FARE6]
-~g~Fahrtziel: ~w~'Easy Credit Autos' ~g~in Saint Mark's.
+[JOB_5]
+Gefeuert!
-[FARE7]
-~g~Fahrtziel: ~w~'Woody's Topless Bar' ~g~im Rotlichtbezirk.
+[ANSWER]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um den Anruf auf deinem Handy entgegenzunehmen.
-[FARE8]
-~g~Fahrtziel: ~w~'Marcos Bistro' ~g~in Saint Mark's.
+[MOB_01A]
+Hey, mein Alter! Paul hier. Ich hätte da vielleicht was für dich, aber das müssen wir unter vier Augen besprechen.
-[FARE9]
-~g~Fahrtziel: ~w~'Import-Export Garage' ~g~in Portland Harbour.
+[MOB_01B]
+Ich bin im Malibu und lass es mir gutgehen.
-[FARE10]
-~g~Fahrtziel: ~w~'Punk Noodles' ~g~in Chinatown.
+[MOB_01C]
+Ich denke, ich hab einen gut bei dir, wenn du das hörst, Kumpel. Bis gleich.
-[FARE12]
-~g~Fahrtziel: ~w~'Football Stadion' ~g~in Aspatria.
+[MOB_02A]
+Hey! Hallo, Tommy? Tommy!
-[FARE13]
-~g~Fahrtziel: ~w~'Die Kirche' ~g~in Bedford Point.
+[MOB_02B]
+In der Druckerei ist irgendwas im Busch. Fahr mal rüber und kümmere dich darum.
-[FARE14]
-~g~Fahrtziel: ~w~'Das Casino' ~g~in Torrington.
+[MOB_02C]
+Es scheint ziemlichen Ärger zu geben. Ich muss Schluss machen.
-[FARE15]
-~g~Fahrtziel: ~w~'Liberty University' ~g~in Liberty Campus.
+[MOB_03A]
+Mr. Vercetti? Ich habe hier einen unterschriebenen Wisch,
-[FARE16]
-~g~Fahrtziel: ~w~'Einkaufszentrum' ~g~in der Belleville Park Area.
+[MOB_03B]
+der besagt, dass Sie alle Schulden von 'BJ's Autos' übernehmen.
-[FARE17]
-~g~Fahrtziel: ~w~'Museum' ~g~in Newport.
+[MOB_03C]
+Nach BJ's plötzlichem Verschwinden hab ich keine andere Wahl,
-[FARE18]
-~g~Fahrtziel: ~w~'AmCo Gebäude' ~g~in Torrington.
+[MOB_03D]
+als Sie für seine Verbindlichkeiten zur Rechenschaft zu ziehen.
-[FARE19]
-~g~Fahrtziel: ~w~'Bolt Burgers' ~g~in Bedford Point.
+[MOB_03E]
+Bis Sie die volle Summe beglichen haben,
-[FARE20]
-~g~Fahrtziel: ~w~'Der Park' ~g~in Belleville.
+[MOB_03F]
+sollte Ihnen klar sein, dass Vice City ein heißes Pflaster für Sie ist.
-[FARE21]
-~g~Fahrtziel: ~w~'Francis Int. Airport'.
+[MOB_04A]
+Wie geht's, mein Alter?
-[FARE22]
-~g~Fahrtziel: ~w~'Cochrane Dam'.
+[MOB_04B]
+Ich hab vergessen, dir zu sagen, dass wir für das Konzert noch ein paar Ordner brauchen.
-[FARE24]
-~g~Fahrtziel: ~w~'Die Klinik' ~g~in Pike Creek.
+[MOB_04C]
+Da gibt's so 'ne Biker-Gang, die wär super für die Publicity.
-[FARE25]
-~g~Fahrtziel: ~w~'Der Park' ~g~in Shoreside Vale.
+[MOB_04D]
+Wenn du mir das arrangierst, besorg ich dir 'n VIP-Pass für den Abend. Ok?
-[FARE26]
-~g~Fahrtziel: ~w~'North West Towers' ~g~in Wichita Gardens.
+[MOB_05A]
+Gut gemacht, Tommy. Schön, den Ofen wiederzuhaben.
-[NEW_TAX]
-GRÖSSER! SCHNELLER! HÄRTER! Neu! Borgnine Taxis jetzt in Harwood! Rufen Sie 555-BORGNINE! Heute noch!
+[MOB_05B]
+Sag Mr. Kent Paul, dass er seine Ordner für das Konzert kriegt.
-[TSCORE2]
-$~1~
+[MOB_05C]
+Du hast mein Wort darauf.
-[IN_ROW]
-~1~ SERIEN-Bonus! $~1~
+[MOB_05D]
+Halt die Ohren steif.
-[TTUTOR]
-Drücke die ~h~~k~~TOGGLE_SUBMISSIONS~-Taste~w~, um Taxi-Missionen an- oder abzuschalten.
+[MOB_06A]
+Tommy, man hört so allerlei über dich, mein Junge.
-[TTUTOR2]
-Drücke die ~h~~k~~TOGGLE_SUBMISSIONS~-Taste~w~, um Taxi-Missionen an- oder abzuschalten.
+[MOB_06B]
+Wenn du willst, kocht Tante Poulet dir ein leckeres Süppchen, dann kannst du mal abschalten, hm?
-[ATUTOR2]
-~g~Fahre die Patienten VORSICHTIG in die Klinik.
+[MOB_06C]
+Komm doch die Tage mal bei mir vorbei, ok, Tommy?
-[A_TIME]
-+~1~ Sekunden
+[MOB_08A]
+Tommy, ich dachte mir, du könntest meinen Rat als Geschäftsmann brauchen.
-[A_FULL]
-~r~Krankenwagen voll!!
+[MOB_08B]
+Wenn du ein Unternehmen am Laufen hast, musst du einmal pro Woche die Einnahmen kassieren gehen.
-[A_RANGE]
-~g~Du bist außer Reichweite des Notarztfunks. Fahr näher an die Klinik heran!
+[MOB_08C]
+Sonst werden deine Leute übermütig und versuchen, in die eigene Tasche zu wirtschaften. Ok?
-[FTUTOR]
-Drücke die ~h~~k~~TOGGLE_SUBMISSIONS~-Taste~w~, um Feuerwehr Missionen an- oder abzuschalten.
+[MOB_08D]
+Hey, ich weiß selbst, wie man so was macht, Ken, ok?
-[FTUTOR2]
-Drücke die ~h~~k~~TOGGLE_SUBMISSIONS~-Taste~w~, um Feuerwehr Missionen an- oder abzuschalten.
+[MOB_08E]
+Ok, ok. Ich weiß ja, dass du Bescheid weißt.
-[F_PASS1]
-Feuer gelöscht!
+[MOB_08F]
+Ich meinte ja nur, damit du weißt, dass ich im Zweifelsfall auch Bescheid weiß.
-[F_RANGE]
-~g~Du bist außer Reichweite des Feuerwehrfunks. Fahr näher an eine Feuerwache heran!
+[MOB_08G]
+Nur für alle Fälle, mein Alter!
-[C_BREIF]
-~g~Verdächtiger wurde zuletzt in der Gegend von ~a~ gesichtet.
+[MOB_08H]
+Wenn du meinst, Ken...
-[C_RANGE]
-~g~Du bist außer Reichweite des Polizeifunks. Fahr näher an ein Polizeirevier heran!
+[MOB_09A]
+Hey, Leo! Ich hab Arbeit für dich!
-[DODO_FT]
-Du bist ~1~ Sekunden geflogen!
-
-[EBAL_A]
-Ich kenn ein Plätzchen im Rotlichtbezirk, wo wir untertauchen können.
-
-[EBAL_A1]
-Aber meine Hände sind im Eimer. Also, fahr du.
-
-[EBAL_1]
-Drücke die~h~ ~k~~VEHICLE_ENTER_EXIT~-Taste~w~, um in ein Fahrzeug ~h~ein- oder auszusteigen~w~.
-
-[EBAL_1B]
-Drücke die~h~ ~k~~VEHICLE_ENTER_EXIT~-Taste~w~, um in ein Fahrzeug ~h~ein- oder auszusteigen~w~.
-
-[EBAL_2]
-~g~Steig wieder in den Wagen!
-
-[EBAL_3]
-Dies ist das ~h~Radar~w~. Damit navigierst du durch die Stadt. Folge dem ~h~Leuchtpunkt~w~ auf dem ~h~Radar~w~, um das Versteck zu finden!
-
-[EBAL_D]
-Ich kenn einen, der hat Beziehungen zur Mafia. Er heißt Luigi.
-
-[EBAL_D1]
-Wir sind alte Bekannte. Vielleicht kann ich dir 'nen Job bei ihm verschaffen. Komm, hier rüber.
-
-[EBAL_E]
-Komm, wir gehen zu ihm. Ich stell dich vor.
+[MOB_09B]
+Hier ist nicht Leo.
-[EBAL_I]
-Der Boss kommt gleich zu dir raus...
+[MOB_09C]
+Hey, wenn Leo erfährt, dass du mit seinem Handy telefonierst, bist du fällig.
-[EBAL_J]
-8-Ball hat oben was zu erledigen.
+[MOB_09E]
+Du hast Leo erledigt? Du musst Mumm haben - willst du für mich arbeiten?
-[EBAL_K]
-Du könntest mir einen Gefallen tun.
+[MOB_09F]
+Komm ins Café von meinem Vater in Little Havana, dann können wir reden.
-[EBAL_L]
-Eines meiner Girls braucht 'nen Fahrer. Schnapp dir ein Auto, hol Misty von der Klinik ab und bring sie her.
+[MOB_10A]
+Tommy! Du musst mir einen Gefallen tun.
-[EBAL_N]
-Also lass die Hände am Lenkrad!
+[MOB_10B]
+Steve! Was machen die Dreharbeiten?
-[EBAL_4]
-~r~8-Ball ist tot!
+[MOB_10C]
+Gut. Ich- äh, WIR brauchen noch eine Autoverfolgungsjagd, aber unser Budget ist knapp.
-[EBAL_5]
-~g~Besorg dir ein Fahrzeug!
+[MOB_10D]
+Ich hab in der Stadt verteilt ein paar Karren stehen. Du weißt, was zu tun ist.
-[EBAL_6]
-~g~Hol Misty ab!
+[MOB_10E]
+Ok, Steve, ich halt die Augen offen. Bis dann.
-[LM1]
-'LUIGIS GIRLS'
+[MOB_11A]
+Hallo, Söhnchen. Ich wollte dir kurz 'nen kleinen Tipp geben.
-[LM2]
-'KEIN SPANK FÜR DIE LADIES'
+[MOB_11B]
+Hi, Avery. Worum geht's denn?
-[LM3]
-'MISTY UND DER MAFIOSO'
+[MOB_11C]
+Man kann in dieser Stadt viel Geld machen, wenn man die richtigen Immobilien hat. Klingelt's?
-[LM5]
-'DER BULLEN-BALL'
+[MOB_11D]
+Ich denke schon.
-[LM1_2]
-~g~Bring Misty zu Luigis Club.
+[MOB_11E]
+Also, halt die Augen offen, dann könnte sich dir die ideale Gelegenheit bieten. Bis bald.
-[LM1_3]
-~g~Drück auf die Hupe, damit die Kleine einsteigt.
+[MOB_11F]
+Ciao, Avery.
-[LM1_6]
-~g~Steig wieder in den Wagen!
+[MOB12_A]
+Hey, Tommy. Avery hier. Hör mal, ich hab gerade alle Hände voll zu tun,
-[LM1_7]
-Halte neben Misty an und lass sie einsteigen.
+[MOB12_B]
+und ein Bevollmächtigter von mir müsste zu den Gator Keys eskortiert werden.
-[LM1_8]
-Du kannst dir bei Luigi den nächsten Job abholen oder Liberty City erkunden.
+[MOB12_C]
+Ich will da ein Stück Land kaufen und schick ihn hin, um den Deal abzuschließen.
-[LM2_A]
-Da ist eine neue Droge in Umlauf, sie heißt SPANK.
+[MOB12_D]
+Könntest du dafür sorgen, dass er gut dort ankommt?
-[LM2_E]
-Irgendein Kerl hat diesen Müll meinen Girls in Portland Harbour verabreicht.
+[MOB12_E]
+Mach ich doch glatt, Avery. Wo soll ich ihn abholen?
-[LM2_B]
-Fahr hin und verabreich ihm ein paar mit 'nem Baseballschläger!
+[MOB12_F]
+Er hat gerade noch an der Baustelle zu tun. Hol ihn doch am besten dort ab.
-[LM2_G]
-Der Typ soll bezahlen für diese Beleidigung!
+[MOB12_G]
+Kein Problem. Bis dann, Avery.
-[LM2_1]
-~g~Nimm sein Auto und spritz es um.
+[MOB13_A]
+Vercetti? VERCETTI!! Verdammt, Mann, Sie müssen mir helfen!
-[LM2_2A]
-Benutze die~h~ ~k~~PED_FIREWEAPON~-Taste~w~, um zu ~h~schlagen und zu treten~w~ oder um ~h~den Schläger zu schwingen~w~!
+[MOB13_B]
+Mr. Moffat? Wie geht's der Familie?
-[LM2_2C]
-Benutze die~h~ ~k~~PED_FIREWEAPON~-Taste~w~, um zu ~h~schlagen und zu treten~w~ oder um ~h~den Schläger zu schwingen~w~!
+[MOB13_C]
+Zur Hölle mit Ihnen, hören Sie!
-[LM2_2D]
-Benutze die~h~ ~k~~PED_FIREWEAPON~-Taste~w~, um zu ~h~schlagen und zu treten~w~ oder um ~h~den Schläger zu schwingen~w~!
+[MOB13_D]
+Tja, war nett, mit Ihnen zu plaudern...
-[LM2_3]
-~g~Stell das Auto in Luigis Garage ab!
+[MOB13_E]
+WARTEN SIE! Vercetti - Tommy, kann ich Tommy zu Ihnen sagen?
-[LM2_4]
-~g~Lackiere das Auto um!
+[MOB13_F]
+Wir sind beide Geschäftsleute. Sie erkennen doch ein gutes Geschäft sofort, oder?
-[LM3_A]
-He, ich muss mit dir reden... Okay, Mick, wir reden später.
+[MOB13_G]
+Ich hab keine Zeit für Palaver. Kommen Sie zum Punkt.
-[LM3_B]
-Na? Alles klar, mein Junge?
+[MOB13_H]
+GELD. Geld ist der Punkt, verdammt!
-[LM3_C]
-Der Sohn des Don, Joey Leone, will seine kleine Misty sehen.
+[MOB13_I]
+Ich bin den Kerlen nochmal entwischt, aber sie sitzen mir im Nacken. Die machen sich einen Spaß daraus!
-[LM3_D]
-Hol sie in Hepburn Heights ab.
+[MOB13_J]
+Ich bin in einer Telefonzelle, irgendwo in diesem verdammten Loch.
-[LM3_E]
-Aber Vorsicht, das ist Diablo-Gebiet.
+[MOB13_K]
+Holen Sie mich hier raus, bevor sie mich schnappen und-... oh Gott...
-[LM3_F]
-Dann bringst du sie rüber zu seiner Werkstatt in Trenton. Aber dalli.
+[MOB13_L]
+Ich bin leider ausgebucht bis-...
-[LM3_H]
-Also, Augen auf die Straße und nicht auf Misty!
+[MOB13_M]
+Nein! Verarschen Sie mich nicht, haben Sie Erbarmen! Kein Mensch hat das verdient!
-[LM3_1D]
-Drücke die~h~ L3-Taste~w~, um zu ~h~hupen~w~. So weiß Misty, dass du da bist.
+[MOB13_N]
+Ich flehe Sie an, Tommy, auf den Knien flehe ich Sie an! Bitte...
-[LM3_2]
-~g~Fahr Misty zu Joey.
+[MOB13_O]
+Naja, ich könnte 'nen kurzen Abstecher machen. Vielleicht finde ich Sie...
-[LM3_4]
-~g~Hol Misty ab!
+[MOB13_P]
+Oh Gott, sie kommen! Um Himmels Willen, beeilen Sie sich!
-[LM3_5]
-Du arbeitest jetzt fest für Luigi? War auch Zeit, dass er 'nen verlässlichen Fahrer anbringt.
+[MOB_14A]
+Hey, Tommy, hör zu, das wird dir gefallen.
-[LM3_7]
-Ich bin gleich bei dir, Süße.
+[MOB_14B]
+Ein Vögelchen hat mir gesteckt, dass das Vice City-Spezialkommando in einem renommierten Finanzinstitut ein Schließfach hat.
-[LM3_10]
-~g~Besorg dir ein Auto!
+[MOB_14C]
+Da sind die Schmiergelder drin, die sie über die Jahre kassiert haben.
-[LM4_B]
-Fahr hin und regle das für mich.
+[MOB_14D]
+So 'ne Art Altersversorgung für die ganze Mannschaft.
-[LM4_C]
-Wenn du 'ne Knarre brauchst, geh zum Hintereingang von AmmuNation, gegenüber der U-Bahn.
+[MOB_14E]
+Sollte dir diese Info je helfen, dir was von dem Kuchen anzueignen,
-[LM5_A]
-Der Polizeiball findet in der alten Schulhalle nahe der Callahan Bridge statt,
+[MOB_14F]
+würdest du dich sicher verpflichtet fühlen, mir 'n Stück davon abzugeben?
-[LM5_B]
-und bei solchen Bällen möchten auch Cops ein wenig 'Action' haben.
+[MOB_14G]
+Ich werd dich nicht vergessen. Danke, Kent.
-[LM5_C]
-Ich hab Girls in der ganzen Stadt stehen.
+[MOB_14H]
+'Paul'heiße ich, Scherzkeks. Ich KOMME aus Kent, Nähe London.
-[LM5_D]
-Bring sie zu dem Ball. Das bringt 'nen Haufen Kohle.
+[MOB_14I]
+Mein geographisches Wissen über England ist eben nicht mehr, was es war.
-[LM5_1]
-~g~Wenn du zu viele Ladies ins Auto stopfst, holen sie sich Schrammen! ~g~Liefere erst diese Mädchen ab und hol dann den Rest.
+[MOB15_A]
+Tommy, Alter. Hier ist Paul aus Kent.
-[LM5_2]
-~r~Eins von Luigis Girls ist hinüber!
+[MOB15_B]
+Unten im Malibu, da sind ein paar Keulen, die haben ein Auge auf dich geworfen.
-[LM5_3]
-~g~Du brauchst ein Auto!
+[MOB15_C]
+Ich verstehe nur Bahnhof.
-[LM5_4]
-~g~Hol die Girls, die in St. Mark's arbeiten.
+[MOB15_D]
+Hasen. Miezen. Na, Puppen, eben. Coole Babes, keine Professionellen, oder so.
-[LM5_5]
-~g~Bring die Girls zum Polizeiball!
+[MOB15_E]
+Du solltest mal kommen und sie dir ansehen.
-[LM5_8]
-~g~Girls auf dem Ball: ~1~
+[MOB16_A]
+Tommy, hier Paul. Wie geht's, mein Freund?
-[JM2]
-'ADIEU, 'CHUNKY' LEE CHONG'
+[MOB16_B]
+Was willst du, Paul? Ich brauch keine getürkten Designer-Klamotten.
-[JM3]
-' DER GELDTRANSPORTER'
+[MOB16_C]
+Sehr witzig. Du weißt, dass ich mit getürkter Ware nichts am Hut habe.
-[JM4]
-'CIPRIANIS CHAUFFEUR'
+[MOB16_D]
+Wollte nur hören, ob ich nicht 'ne Rolle in einem von deinen Filmen kriegen könnte.
-[JM5]
-'DER TOTE PASSAGIER'
+[MOB16_E]
+In England habe ich viel einschlägiges Zeug gedreht.
-[JM1_1]
-~g~Bring Forellis Wagen zu 8-Balls Werkstatt nördlich von hier, hinter 'Easy Credit Autos'.
+[MOB16_F]
+Ich hab mehr zu bieten als du, mein Alter.
-[JM1_2]
-~g~Park den Wagen wieder vor Marcos Bistro.
+[MOB16_G]
+Paul, danke für das Angebot. Ich komm auf dich zurück.
-[JM1_3]
-~g~Aktiviere die Autobombe und dann nichts wie weg!
+[MOB16_H]
+Lass mich nicht hängen. Denk dran, was ich alles für dich getan habe.
-[JM1_4]
-~g~Du schrottest das Auto! Repariere es!
+[MOB16_I]
+Das versuch ich ja grade zu vergessen.
-[JM1_5]
-~g~Die Autobombe ist nicht aktiviert!
+[MOB17_A]
+Tommy Vercetti. Wie geht's, großer Meister?
-[JM1_6]
-~g~Stell den Wagen wieder an den richtigen Platz.
+[MOB17_B]
+Man hört so einiges über dich. Bist jetzt 'ne große Nummer in der Stadt, hä?
-[JM1_8A]
-~y~Hey, mein alter Freund!
+[MOB17_C]
+Paul, du bist betrunken.
-[JM1_8B]
-~y~Die Bombenwerkstatt ist automatisiert. Einfach reinfahren und anhalten, der Rest passiert von selbst.
+[MOB17_D]
+Nein, du Trottel, ich bin nicht betrunken.
-[JM1_8C]
-~y~Hier, die erste ist umsonst, jede weitere kostet aber.
+[MOB17_E]
+Hab mir nur ein paar Ladungen Stoff gegeben, war seit ein paar Tagen nicht im Bett.
-[JM2_A]
-Chunky Lee Chong verhökert Spank für irgend so eine neue Gang aus Kolumbien oder Colorado oder so...
+[MOB17_F]
+Und du brauchst mich nicht dumm anzureden.
-[JM2_B]
-Ich weiß nicht genau. Aber wen interessieren schon die Details?
+[MOB17_G]
+Ich bin nicht irgendwer. Wer hat dir denn in dieser Stadt den Weg geebnet? Ich!
-[JM2_D]
-Diese Ratte hat seine letzte Frühlingsrolle verkauft.
+[MOB17_H]
+Tatsächlich?
-[JM2_E]
-Ich möchte, dass du ihn erledigst.
+[MOB17_I]
+Tatsächlich!
-[JM2_G]
-Besorg dir 'ne 9mm. Du weißt ja, wo du sie findest, oder?
+[MOB17_J]
+Paul, reg dich ab. Ich hatte viel zu tun. Sei kein Idiot.
-[JM2_H]
-Und sei vorsichtig in Chinatown. Das ist Triaden-Gebiet.
+[MOB17_K]
+Ich bin kein Idiot. Das haben sie schon im Jugendknast gesagt.
-[JM3_A]
-Also, wir überfallen den Transporter mit den Lohngeldern.
+[MOB17_L]
+Wenn du Ärger haben willst, Freundchen, den kannst du haben!
-[JM3_B]
-Er startet jeden Tag an der Grenze zu Chinatown.
+[MOB17_M]
+Tommy, bitte! Du warst meine große Hoffnung. Bitte, mach dich nicht lustig über mich!
-[JM3_C]
-Kugeln können der Karre nichts anhaben. Also besorg dir einen Wagen und ramm ihn von der Straße.
+[MOB17_N]
+Paul, schlaf mal 'ne Runde. Im Ernst.
-[JM3_D]
-Fahr ihm voll rein, dann dürften die Wachmänner schnell abhauen.
+[MOB18_A]
+Tommy, hier Paul. Wie geht's, Alter? Hey, ich dachte mir, das musst du hören...
-[JM3_E]
-Fahr den Transporter dann zum Lagerhaus bei den Docks, von da an übernehmen meine Leute.
+[MOB18_B]
+Echt der Hammer. Du glaubst nicht, was mir für 'ne Puppe über den Weg gelaufen ist.
-[JM3_F]
-Der Transporter ist nicht ewig unterwegs, also beeil dich.
+[MOB18_C]
+'ne Bordsteinschwalbe, oder sowas. Unten in Little Havana.
-[JM3_1]
-~g~Fahr den Transporter zu der Garage.
+[MOB18_D]
+Sagt, sie heißt Mercedes oder so ähnlich. Wahnsinn, Alter. Die Puppe musst du dir geben.
-[JM3_2]
-~g~Ramm den Wagen, bis der Schadenswert unter 70 Prozent liegt.
+[MOB18_E]
+Da würde 'nen Toter Hormonkoller kriegen. Sie sagt, ich wär der beste, den sie je hatte.
-[JM4_B]
-Oh! Da ist der Typ, von dem ich dir erzählt habe!
+[MOB18_F]
+Halt die Augen nach ihr offen. Bis dann.
-[JM4_C]
-Okay, hör zu. Der Typ ist kein Italiener und kein Mechaniker, aber er kann alles 'richten'.
+[MOB19_A]
+Tommy, hier KP - Kent Paul. Ich hab läuten hören, dass jemand dich leimen will.
-[JM4_D]
-Das ist Paps' Capo, Toni Cipriani.
+[MOB19_B]
+Also, sei wachsam, mein Freund. Und kein Sterbenswörtchen, dass du das von mir weißt.
-[JM4_E]
-Ja, ich bin Toni Cipriani.
+[MOB_20A]
+Hallo, Tommy. Hier Paul. Ich höre, dass du ein paar Leuten auf den Schlips getreten bist.
-[JM4_F]
-Bring ihn zu Mammas Restaurant in St. Mark's.
+[MOB_20B]
+Irgendjemand sieht es anscheinend nicht gern, dass du auf einmal den großen Zampano spielst.
-[JM4_G]
-Hör zu, ich plane eine Sache, da brauche ich einen guten Fahrer. Also komm später wieder, okay?
+[MOB_20C]
+Also, sag nicht, ich hätte dich nicht gewarnt. Es rächt sich, wenn man's übertreibt.
-[JM4_2]
-Warte hier. Lass den Motor laufen. Das ist kein Freundschaftsbesuch.
+[MOB_20D]
+Jedenfalls ist angeblich ein Kopfgeld auf dich ausgesetzt und es ist schon jemand hinter dir her.
-[JM4_3]
-Ein Hinterhalt der Triaden! Bring uns hier raus!
+[MOB_20E]
+Also pass auf dich auf. Und vergiss mich nicht ganz.
-[JM4_4]
-Die Triaden denken wohl, sie können mich fertigmachen. Die! MICH!
+[MOB71_A]
+Tommy, Thomas, hier Cortez. Wie geht's?
-[JM4_6]
-Hey, Vorsicht! Ich sagte, keine künstlerischen Einlagen!
+[MOB71_B]
+Es bleibt spannend. Und selbst?
-[JM4_7]
-~g~Fahr Toni zu Mammas Restaurant.
+[MOB71_C]
+Ein ewiger Kampf, Tommy. Entschuldigen Sie die schlechte Verbindung, wir hatten wieder einen Putschversuch.
-[JM4_8]
-~r~Toni ist tot!
+[MOB71_D]
+Es gibt keine anspruchsvollere Geliebte als das Volk.
-[JM5_A]
-Großartig! Einfach großartig!
+[MOB71_E]
+Seit ich aus Vice City zurück bin, gab's drei Revolutionen und vier Staatsstreiche.
-[JM5_B]
-Na also. Genau der, mit dem ich jetzt reden muss!
+[MOB71_F]
+Zum Glück bin ich jedesmal befördert worden.
-[JM5_D]
-Einer der Forellis meinte, er weiß zu viel, also hat er gekriegt, was er verdiente.
+[MOB71_G]
+Ich wollte Sie wegen Mercedes etwas fragen.
-[JM5_E]
-Schaff die Leiche zu der Schrottpresse in Harwood, okay?
+[MOB71_H]
+OK. Was ist mit ihr?
-[JM5_1]
-~g~Bring ihn zu der Schrottpresse!
+[MOB71_I]
+Ich hör Geschichten über sie und weiß nicht, was ich davon halten soll.
-[JM5_2]
-~g~Die Forelli Brüder!
+[MOB71_J]
+Vielleicht wollen mich alle demütigen.
-[JM6_A]
-Nicht schlecht, das Ding, was?
+[MOB71_K]
+Vielleicht wird sie übermütig, seit ich weg musste, sagen Sie mir nur eins, Tommy. Ist das wahr?.
-[JM6_B]
-Hör zu. Fahr mit einem Wagen zu der sicheren Wohnung in St. Mark's und hol ein paar Freunde von mir ab.
+[MOB71_L]
+sagen Sie mir nur eins, Tommy. Ist das wahr?
-[JM6_C]
-Die überfallen eine Bank und brauchen einen Fahrer.
+[MOB71_M]
+Ist was wahr?
-[JM6_D]
-Ich hab ihnen gesagt, du bist der richtige. Also, vermassle es nicht.
+[MOB71_N]
+Die Geschichten, die ich höre? Will sie wirklich Anwältin werden?
-[JM6_E]
-Bring sie vor 5 Uhr zu der Bank, keine Minute später.
+[MOB71_O]
+Welche Schande, Tommy. Wir Cortez sind eine stolze Familie und würden nie einer Tochter erlauben, Anwältin zu werden.
-[JM6_2]
-Lass den Motor laufen. Wir sind gleich wieder da.
+[MOB71_P]
+Sagen Sie mir, dass es nicht wahr ist. Das ertrage ich nicht.
-[JM6_3]
-Bring uns hier weg!!
+[MOB71_Q]
+Colonel, ich versichere Ihnen, dass Mercedes niemals Anwältin wird. Keine Angst.
-[JM6_4]
-Häng die Cops ab und bring uns in die sichere Wohnung!
+[MOB71_R]
+Danke, Tommy - das wäre zu viel der Schande. Sie ist eine Dame, keine Schmarotzerin.
-[JM6_6]
-~g~Los, besorge ein weniger verdächtiges Fahrzeug!
+[MOB71_S]
+Ich weiß, Colonel
-[JM6_7]
-~g~Du brauchst alle 3 für den Überfall!
+[MOB71_T]
+Tommy, Sie müssen jetzt entschuldigen, gerade kommt der neue Innenminister.
-[TM1]
-'SCHMUTZIGE WÄSCHE'
+[MOB71_U]
+Ich hab seinen Vater vor Jahren bei einem Putschversuch erledigt. Ich muss mich gut mit ihm stellen. Wiederhören.
-[TM2]
-'DER GELDBOTE'
+[MOB22_A]
+Tommy, Sie erweisen sich als sehr nützlich, mein Freund.
-[TM3]
-'DAS TREFFEN BEI SALVATORE'
+[MOB22_B]
+Danke, Cortez. Was ist mit meinem Deal?
-[TM4]
-'TRIADEN UND ANDERE KLEINE FISCHE'
+[MOB22_C]
+Tommy, ich mühe mich ohne Unterlass, um diesem Sumpf von elenden Lügen und Intrigen auf den Grund zu gehen.
-[TM5]
-'EXPLODIERENDE FISCHE'
+[MOB22_D]
+Sie haben mein Wort darauf. Einstweilen möchte ich
-[TONI_P]
-Ich habe einen dringenden Job für dich! -Toni
+[MOB22_E]
+Ihnen den Dank meines Volkes aussprechen, für das Sie so viel getan haben.
-[TM1_A]
-~w~Setz dich, Junge. Los, mach's dir bequem.
+[MOB_25A]
+Tommy, hier Cortez. Die Franzosen machen mir Ärger. Und wie.
-[TM1_B]
-~w~Die Wäscherei will also kein Schutzgeld zahlen, was?
+[MOB_25B]
+Verdammte Heuchler! Jahrhundertelang beuten sie arme Länder aus und mich schimpfen sie einen Dieb!
-[TM1_C]
-~w~Denken die Triaden, sie können mich verscheißern?
+[MOB_25C]
+Ich brauche dingend Ihre Hilfe.
-[TM1_D]
-~w~Diesen Möchtegern-Gangstern werden wir eine Lektion erteilen.
+[MOB_25D]
+Beeilen Sie sich. Ich brauche Sie. Ich hasse die Franzosen.
-[TM1_E]
-~w~Ja, ich werde denen Respekt beibringen. Die rühren keinen meiner Söhne ungestraft an.
+[MOB_26A]
+Hallo, Tommy?
-[TM1_F]
-~w~Dein Vater - Gott hab ihn selig - hat sich von den Triaden nie etwas gefallen lassen.
+[MOB_26B]
+Ja?
-[TM1_G]
-~w~Sorry, Ma. Ja, Ma.
+[MOB_26C]
+Baker hier. Wollte dir nur sagen, der Gig hat Spaß gemacht.
-[TM1_H]
-~w~Ich will, dass du ihre Wäscherei-Transporter zerstörst
+[MOB_26D]
+Danke, auch im Namen der Gang. Eins sollst du wissen:
-[TM1_I]
-~w~und jeden Triaden-Tölpel niedermachst, der dir in die Quere kommt.
+[MOB_26E]
+Du hast unsern Respekt. Halt die Nase im Wind, Junge.
-[TM1_J]
-~w~8-Ball liefert dir alles, was du dazu brauchst.
+[MOB_29A]
+Hallo? Spreche ich mit Mr. Tommy Vercetti?
-[TM2_A]
-~w~TONI ist unterwegs, um jemanden zu erledigen - oder er versucht es jedenfalls.
+[MOB_29B]
+Ja.
-[TM2_AA]
-Er wird nie so sein wie sein Papa. Auf dem Tisch hat er dir eine Nachricht hinterlassen.
+[MOB_29C]
+Ich hab mir sagen lassen, du wärst der richtige Mann, wenn man Kroppzeug am Hals hat.
-[TM2_B]
-~w~Die Wäscherei will jetzt bezahlen. Gute Arbeit, mein Junge!
+[MOB_29D]
+Vielleicht...
-[TM2_C]
-~w~Hol das Geld ab und bring es hierher. Pass auf die Triaden auf.
+[MOB_29E]
+Tja, ich hab 'ne regelrechte Plage am Hals. Haitianer, überall.
-[TM2_D]
-~w~Die wollen dich wahrscheinlich zu Chop Suey verarbeiten, aber lass dir nichts gefallen.
+[MOB_29F]
+Mein Name ist Umberto Robina und es wär mir recht, wenn du baldmöglichst ins Café Robina kämst.
-[TM2_E]
-~w~Niemand, wirklich niemand, macht TONI CIPRIANI fertig!
+[MOB_29G]
+Diesmal haben's die Haitianer nämlich zu weit getrieben.
-[TM2_1]
-~g~Bring das Geld zu Toni!!
+[MOB_29H]
+Test
-[TM2_2]
-~g~Du hast sie alle erledigt!
+[MOB_30A]
+Tommy, hier Umberto Robina.
-[TM3_MA]
-~w~Ich weiß nicht, wo er ist!
+[MOB_30B]
+Wie läuft das Café?
-[TM3_MB]
-~w~Ach, mein Sohn weiß manchmal selbst nicht, wer er ist.
+[MOB_30C]
+Oh, bestens. Sagenhaft, Tommy, sagenhaft. Keine Memmen, Tommy, nur echte Männer. Und wunderschöne Frauen!
-[TM3_MC]
-~w~Ja, sein Vater, der war da ganz anders. Immer auf Draht, top, ein echter Mann...
+[MOB_30D]
+Ich wollte nur sagen, für mich und Paps bist du jetzt einer von uns. Ein Kubaner.
-[TM3_A]
-~w~Don Salvatore hat ein Treffen angesetzt.
+[MOB_30E]
+Du bist ein ganzer Kerl. Du hast Mumm in den Knochen.
-[TM3_B]
-~w~Du musst erst die Limo und seinen Sohn Joey aus der Werkstatt abholen.
+[MOB_30F]
+Danke, Umberto. Seit ich aus dem Knast raus bin, hat das keiner zu mir gesagt. Bis dann.
-[TM3_C]
-~w~Dann holst du Luigi aus seinem Club ab und dann kommst du wieder her und holst mich ab.
+[MOB_33A]
+Tommy, Phil hier. Spar dir die sentimentalen Worte, hör mir einfach zu, ok?
-[TM3_D]
-~w~Dann fahren wir alle gemeinsam zum Boss.
+[MOB_33B]
+Also, ich brau hier 'nen extra starken TNT-Whiskey und ich wollte fragen, ob du mal 'nen Schluck probieren willst.
-[TM3_E]
-~w~Diese Triaden wissen einfach nicht, wann Schluss ist.
+[MOB_33C]
+Im Ernst, Tommy, wenn du 'nen Drink willst, oder 'ne Wand abbeizen musst - das Zeug macht einen Mann aus dir.
-[TM3_F]
-~w~Wenn sie Krieg wollen, sollen sie Krieg haben.
+[MOB_33D]
+Bei mir hat's jedenfalls gewirkt, auch wenn ich jetzt auf einem Auge nichts mehr sehe. Ich warte auf dich.
-[TM3_G]
-~w~Also, los jetzt.
+[MOB_34A]
+Tommy, war ein Vergnügen, mit dir zu arbeiten. So einen Spaß hatte ich seit Vietnam nicht mehr.
-[TM3_1]
-~g~Hol die Limousine bei Joey ab.
+[MOB_34B]
+Also, falls du je irgendwas brauchst, ruf mich an, ok?
-[TM3_2]
-~g~Jetzt hol Luigi ab.
+[MOB_34C]
+Ich vergesse keinen, mit dem ich in der Schlacht war.
-[TM3_3]
-~g~Jetzt hol Toni ab.
+[MOB_34D]
+Und ich kann dir bestimmt irgendwann helfen, ok?
-[TM3_4]
-~g~Jetzt fahr die Männer zu Salvatore.
+[MOB_35A]
+Tommy, die Wunde verheilt gut. Ist nur komisch:
-[TM3_5]
-~y~Ein Hinterhalt der Triaden!!
+[MOB_35B]
+da hab ich auf 6 Schlachtfeldern gekämpft und nie 'n Kratzer abgekriegt und dann das!
-[TM4_B]
-~w~Es herrscht KRIEG! Die Triaden betreiben zur Tarnung einen Fischmarkt in Chinatown.
+[MOB_35C]
+Jetzt bin ich der einarmige Phil. Hab aber 'n gutes Arsenal an Handfeuerwaffen, also bin ich auch mit Arm ab nicht arm dran.
-[TM4_C]
-~w~Die meisten ihrer Geschäfte werden auf diesem Fischmarkt durchgezogen.
+[MOB_35D]
+Also hör auf mit der sentimentalen Scheiße und hol dir 'nen Drink, ok!
-[TM4_D]
-~w~Diese Wäscherei schuldet uns immer noch Geld.
+[MOB_36A]
+Tommy, hier Phil. Wollte mich bedanken, dass du mich da rausgehauen hast.
-[TM4_E]
-~w~Die denken, die Triaden beschützen sie jetzt. Ich schlage vor, wir führen eine Strafaktion durch.
+[MOB_36B]
+Verdammte Vietnamesen. Wo du hinschaust ein Hinterhalt.
-[TM4_F]
-~w~Nimm dir diese Jungs und knöpf dir die Köpfe der Triaden vor!
+[MOB_36C]
+Die Wunde heilt gut. Und jetzt kassiere ich meine Versehrtenrente endlich völlig zurecht. Danke, Kumpel.
-[TM4_G]
-~w~Und wenn es geht, macht auch ein paar von deren Soldaten fertig.
+[MOB_40A]
+Hey, Tommy, hier Sonny. Was macht die Sonnenbräune?
-[TM4_GAT]
-~g~Du brauchst einen 'Triaden-Packwagon', um da reinzukommen.
+[MOB_40B]
+Ich hab keine Sonnenbräune.
-[TM5_A]
-TEXT NO LONGER REQUIRED
+[MOB_40C]
+Naja, mein Geld hast du jedenfalls auch nicht. Daher frag ich mich,
-[TM5_B]
-~w~Okay, jetzt hab ich aber die Schnauze voll.
+[MOB_40D]
+was treibst du eigentlich die ganze Zeit, Tommy? Sag doch mal?
-[TM5_C]
-~w~Wir machen die Triaden ein für alle Mal fertig.
+[MOB_40E]
+Ich bin auf der Suche nach deinem Geld, Sonny. Keine Sorge.
-[TM5_D]
-8-Ball hat einen Müllkarren mit einer Bombe präpariert.
+[MOB_40F]
+Ich mach mir aber Sorgen, Tommy, ich kann nicht anders.
-[TM5_E]
-~w~Sie hat einen Zeitzünder. Wenn du's vermasselst, hinterlassen wir keine Spuren. Hol den Müllkarren ab.
+[MOB_40G]
+Ich hab nämlich anscheinend mit zu viel unzuverlässigen Menschen zu tun.
-[TM5_F]
-~w~Fahr vorsichtig. 8-Ball sagt, die Bombe ist extrem empfindlich, das kleinste Schlagloch und sie geht hoch.
+[MOB_40H]
+Sei du bitte kein unzuverlässiger Mensch, Tommy.
-[TM5_G]
-~w~In ihrer Fischfabrik werden sie dich reinlassen mit dem Müllkarren.
+[MOB_40I]
+Tu dir und mir einen Gefallen. Ich freu mich, von dir zu hören.
-[TM5_H]
-~w~Stell das Ding zwischen den Benzinkanistern ab und dann nichts wie weg.
+[MOB_41A]
+Tommy, kennst du mich noch?
-[TM5_I]
-~w~Es soll rummsen, dass es Fische vom Himmel regnet.
+[MOB_41B]
+Hey, Sonny.
-[TM5_J]
-~w~Ne biblische Apokalypse will ich haben, nichts popeliges.
+[MOB_41C]
+Ja genau, Sonny. Wir sind doch alte Freunde,
-[FM2]
-'CURLYS GEHEIMKONTAKTE'
+[MOB_41D]
+aber du schreibst nie, rufst nie an. Willst du denn nicht mehr mein Freund sein?
-[FM4]
-'DER LETZTE WUNSCH'
+[MOB_41E]
+Ich hab alle Hände voll zu tun, die Sache zu regeln. Und du bist auch keine große Hilfe.
-[FM1_A]
-~w~Die Jungs und ich haben einiges zu besprechen,
+[MOB_41F]
+Ach, ich bin also schuld? Ja, ich hab gehört, dass du zu tun hast...
-[FM1_B]
-~w~du wirst dich heute abend um meine Kleine kümmern.
+[MOB_41G]
+Musst Drogenbarone erledigen, ihre Geschäfte übernehmen.
-[FM1_C]
-~w~HEY, MARIA! WO BLEIBST DU?
+[MOB_41H]
+Vergiss mich nicht, Tommy. Ich verspreche dir nämlich, dass ich dich nicht vergesse...
-[FM1_D]
-~w~Dämliche Ziege. Jedes Mal dasselbe.
+[MOB_42A]
+Tommy.
-[FM1_E]
-~w~Und hier ist sie, die Königin der Nacht höchstpersönlich!
+[MOB_42B]
+Sonny.
-[FM1_F]
-~w~Was hast du denn da oben getrieben?
+[MOB_42C]
+Anscheinend hörst du neuerdings schlecht, deshalb frag ich dich jetzt nochmal:
-[FM1_G]
-~w~Was es auch war, jede Wette, es hat mich Geld gekostet.
+[MOB_42D]
+Tommy, wo ist die verdammte Kohle? Wo ist der verdammte Stoff und wo ist mein Anteil an deinem neuen Geschäft?
-[FM1_H]
-~w~Du glaubst doch nicht, ich bin zum Palavern hier, oder?
+[MOB_42E]
+Du hältst mich zum Narren, Tommy, ich find's bloß nicht zum Lachen.
-[FM1_I]
-~w~Halt die Klappe und steig in den Wagen.
+[MOB_43A]
+Tommy, Tommy, Tommy, Sonny hat gerade angerufen, dämmert dir was?
-[FM1_J]
-~w~Nimm die Limo, aber bring sie mir heil wieder, hörst du?
+[MOB_43B]
+Ich weiß nicht, wie das mit dir ist, aber wenn mir jemand droht, dass er meine Familie umbringt,
-[FM1_K]
-~w~Und pass auf sie auf, sie kann eine Menge Ärger machen.
+[MOB_43C]
+dann macht mir das eine Scheißangst. Was gedenkst du zu unternehmen?
-[FM1_L]
-~w~Ja, ja, ja! Dein neues Schoßhündchen wird schon alles im Griff haben.
+[MOB_43D]
+Nur die Ruhe, Ken, alles wird cool.
-[FM1_M]
-~w~Er ist ja auch so groß und stark.
+[MOB_43E]
+Ich BIN ruhig. So ruhig wie man sein kann, wenn man um sein Leben fürchtet!
-[FM1_N]
-~w~Hey, Fiffi, los, wir besuchen Chico und besorgen uns was zum 'Naschen'!
+[MOB_43F]
+Ken, ich muss mich gerade auf was anderes konzentrieren.
-[FM1_P]
-~g~Da ist Chico. Halt neben ihm an.
+[MOB_43G]
+Wir kümmern uns zu gegebener Zeit um Forelli.
-[FM1_S]
-~w~Bitte sehr, die Dame.
+[MOB_43H]
+Ich bin ruhig. Hör ich mich nicht ruhig an? Muss die Todesangst sein, die auf die Stimme schlägt.
-[FM1_TT]
-~w~EINE POLIZEI-RAZZIA!
+[MOB45_A]
+Tommy, wir müssen miteinander reden.
-[FM1_1]
-~g~Zurück in die Limo!
+[MOB45_B]
+Wo liegt das Problem, Lance?
-[FM1_2]
-~g~Steig in die Limo!
+[MOB45_C]
+Bei dir, mein Freund: Ich finde, du gibst mir keinen fairen Anteil.
-[FM1_3]
-~r~Wenn du Maria im Stich lässt, bringt Salvatore dich um. Kehr um und hol sie!
+[MOB45_D]
+Noch dazu hast du mich vor den Jungs blamiert. Das kann ich nicht auf mir sitzen lassen.
-[FM1_4]
-~g~Du hast die Frau des Don im Stich gelassen! Los, zurück zur Lagerhalle! Warte dort auf Maria!
+[MOB45_E]
+Lance, das siehst du falsch. Du hast Fehler gemacht.
-[FM1_5]
-~g~Bring Maria wohlbehalten zu Salvatore zurück!
+[MOB45_F]
+Tommy, ich bin nicht dein Laufbursche. Nicht dein Lakai.
-[FM1_6]
-~g~Chico ist nicht ewig dort. Bring Maria zu diesem Ufer!
+[MOB45_G]
+Lance, alles ist ok, solange du keinen Mist baust. Und sollte ICH Mist bauen, steh ich dafür gerade.
-[FM1_7]
-~r~Maria ist tot! Das wird Salvatore nicht gefallen...
+[MOB45_H]
+Tommy, ich hab alles für dich getan und du trittst mich mit Füßen. Mach das doch nicht.
-[FM1_8]
-~r~Du hast Marias Lieferanten erledigt!
+[MOB45_I]
+Lance, ich betrüg dich nicht und falle dir nicht in den Rücken, ok?
-[FM2_J]
-Lasst uns eine Minute alleine.
+[MOB45_J]
+Reiß dich zusammen. Es ist schwer genug, ohne dass du mir die Ohren vollheulst.
-[FM2_A]
-Das kolumbianische Kartell stellt irgendwo in Liberty SPANK her.
+[MOB45_K]
+Vertrau mir, hörst du. Hörst du?
-[FM2_K]
-Aber wir wissen nicht wo. Und die scheinen jeden unserer Schritte im Voraus zu kennen.
+[MOB45_L]
+Ja, Tommy, aber ich halt das nicht mehr lange aus.
-[FM2_L]
-Es gibt da einen Typ namens Curly Bob. Er arbeitet in Luigis Bar.
+[MOB45_M]
+Lance, komm mir bloß nicht so, ich warne dich.
-[FM2_M]
-Der verpulvert schon dauernd mehr Geld als er verdient.
+[MOB45_N]
+Reg dich ab, mach ein paar Tage frei, dann unterhalten wir uns, ok?
-[FM2_N]
-Normalerweise fährt er nach der Arbeit mit dem Taxi nach Hause. Folge ihm.
+[MOB46_A]
+Tommy - Lance.
-[FM2_O]
-Und wenn er der Verräter ist, mach ihn fertig.
+[MOB46_B]
+Ja?
-[FM2_F]
-Da kommt ja unser kleiner, gesprächiger Freund.
+[MOB46_C]
+Kein 'Schön, dass du anrufst, Lance!' Kein freundliches Wort? Was soll das?
-[FM2_G]
-Ist man dir gefolgt? Du weißt, was hier läuft, muss unter uns bleiben.
+[MOB46_D]
+Ich habe gerade zu tun, Lance. Was willst du?
-[FM2_H]
-Nein, nein, niemand ist mir gefolgt. Hast du meinen Stoff?
+[MOB46_E]
+Nichts. Ich wollte dir nur sagen, wir kriegen das hin.
-[FM2_I]
-Hier ist dein SPANK, du Ratte, und jetzt rede.
+[MOB46_F]
+Du und ich, ohne Probleme. Du verstehst mich?
-[FM2_P]
-Okay. Die Leones führen einen Zwei-Fronten-Krieg.
+[MOB46_G]
+Wir müssen es hinkriegen. Sonst sind wir erledigt, Lance.
-[FM2_Q]
-Sie kämpfen mit den Triaden um ein Territorium, und keiner der beiden gibt nach.
+[MOB46_H]
+Wir stecken schon viel zu tief drin. Aber danke für den Anruf. Du hörst von mir.
-[FM2_R]
-Gleichzeitig hat Joey Leone Streit mit den Forellis angefangen.
+[MOB_47A]
+Tommy - Lance. Wir stecken in der Patsche. Du musst sofort kommen.
-[FM2_S]
-Jeden Tag verlieren sie Leute und Einfluss in der Stadt.
+[MOB52_A]
+Hey, Leo, ich glaube, wir haben einen Käufer für Diaz' Ware.
-[FM2_T]
-Salvatore wird gefährlich und paranoid. Er verdächtigt alles und jeden.
+[MOB52_B]
+Du musst ihn anrufen und den Deal in die Wege leiten, ok?
-[FM2_U]
-Bei treuen Gefolgsleuten wie dir, wie kann er sich da nur Sorgen machen?
+[MOB52_C]
+Wo bist du gerade?
-[FM2_1]
-~g~Da ist Curly Bob!
+[MOB52_D]
+Ist irgendwas, Leo? Du hörst dich so komisch an.
-[FM2_2]
-~g~Curly hat den Club verlassen. Folge ihm!
+[MOB52_E]
+Sag mir, wo du bist.
-[FM2_5]
-~g~Bring ihn nach Portland Harbour.
+[MOB52_F]
+Verdammt, wer ist da dran? Gib mir Leo!
-[FM2_6]
-~r~Curly steigt in kein geschrottetes Taxi!
+[MOB52_G]
+Leo ist 'ne Weile verreist, ich vertrete ihn.
-[FM2_7]
-~r~Curly hat Angst! Das Treffen ist abgeblasen!
+[MOB52_H]
+Zum Teufel mit dir!
-[FM2_8]
-~g~Knöpf dir Curly Bob vor!
+[MOB54_A]
+Hi, Tommy!
-[FM2_9]
-~r~Curly Bob ist tot!
+[MOB54_B]
+Hi, Mercedes. Wie geht's?
-[FM2_10]
-~r~Curly ist entwischt!
+[MOB54_C]
+Ich hab 'ne neue Wohnung in Vice Point.
-[FM2_11]
-~g~Parke vor Luigis Club, Curly Bob kommt gleich heraus.
+[MOB54_D]
+Vielleicht kommst du mich ja mal besuchen.
-[FM2_12]
-~r~Er ist dir entwischt!
+[MOB54_E]
+Klar, gern. Also, bis später.
-[FM3_A]
-~w~Wir sollten diese kolumbianischen Mistkerle fertigmachen,
+[MOB55_A]
+Tommy, ich bin's.
-[FM3_B]
-~w~aber durch den Krieg mit den Triaden sind wir dazu zu geschwächt.
+[MOB55_B]
+Hi, Mercedes.
-[FM3_C]
-~w~Das Kartell hat unendlich Geld aus dem Handel mit diesem Mistzeug SPANK.
+[MOB55_C]
+Tommy, mir ist so langweilig. Wann hast du denn mal Zeit für mich?
-[FM3_D]
-~w~Wenn wir sie offen angreifen, putzen sie uns weg.
+[MOB55_D]
+Was soll denn das heißen?
-[FM3_E]
-~w~Die müssen das SPANK auf diesem großen Schiff machen, zu dem dich Curly geführt hat.
+[MOB55_E]
+Ich weiß, du hast so viel zu tun, musst Leute beseitigen und bestechen.
-[FM3_F]
-~w~Wir müssen also mit Köpfchen vorgehen. Genauer gesagt, mit DEINEM Köpfchen.
+[MOB55_F]
+Aber ich will mal wieder Spaß haben. Also vergiss mich nicht, hörst du?
-[FM3_G]
-~w~Ich bitte dich, mir, Salvatore Leone zuliebe, dieses SPANK Labor zu zerstören.
+[MOB56_A]
+Tommy, es heißt, du hast Ricardo Diaz erledigt.
-[FM3_H]
-~w~Wenn du das für mich tust, bist du ein gemachter Mann. Du kriegst alles, was du willst.
+[MOB56_B]
+In seinem Haus ist ein Feuer ausgebrochen.
-[FM3_I]
-~w~Geh zu 8-Ball. Du brauchst einen Fachmann, um dieses Schiff hochzujagen.
+[MOB56_C]
+Ich glaube, er hatte ein Acrylhemd an und ist verbrannt.
-[FM3_8A]
-~w~Hi, Kumpel! Salvatore hat schon angerufen,
+[MOB56_D]
+Tommy, ich bin so stolz auf dich. Ich wusste, du bist ein echter Mann.
-[FM3_8B]
-~w~aber für so einen Job brauchst du eine Menge Chinaböller.
+[MOB56_E]
+Und er war ein Mistkerl. Ich bin so stolz, dass du mein Freund bist.
-[FM3_8D]
-~w~Aber du kennst mich. Dafür scheppert's dann auch gewaltig.
+[MOB56_F]
+Ich weiß, du hast zu tun, du musst schließlich die Stadt erobern.
-[FM3_8E]
-~w~Okay, dann wollen wir mal!
+[MOB56_G]
+Aber vergiss mich nicht, hörst du?
-[FM3_8F]
-~w~Ich kann das Baby scharf machen, aber eine Knarre kann ich mit diesen Händen immer noch nicht halten.
+[MOB57_A]
+Ich bin's, Mercedes. Ich liebe dich nicht mehr, Tommy.
-[FM3_8G]
-~w~Hier, das Gewehr hier wirst du sicher brauchen.
+[MOB57_B]
+Wirklich nicht mehr. Du bist nicht mehr nett zu Mercedes.
-[FM3_4]
-~g~Halt an und lass 8-Ball aussteigen!
+[MOB57_C]
+Du behandelst mich nicht mehr wie eine Dame. Du ignorierst mich und ich hasse dich.
-[FM3_7]
-~r~8-Ball hat's erwischt!
+[MOB57_D]
+Ich bestehe darauf, dass du sofort zu mir kommst!
-[FM3_8]
-~r~Die Wachmänner wurden alarmiert!
+[MOB58_A]
+Tommy.
-[FM4_A]
-~w~Ah, sieh an! Mein bester Troubleshooter.
+[MOB58_B]
+Hey, Mercedes.
-[FM4_B]
-~w~Ich bin stolz auf dich, meine Junge. Du hast es diesen Mistkerlen gezeigt.
+[MOB58_C]
+Selber hey, du toller Hecht. Ich bin sauer auf dich, Tommy.
-[FM4_C]
-~w~Ich hab nur noch einen kleinen Job für dich, bevor wir alle feiern können.
+[MOB58_D]
+Schick mich nie mehr zu diesem Jezz Torrent.
-[FM4_D]
-~w~Um die Ecke von Luigis Club steht ein Wagen.
+[MOB58_E]
+So ein Jammerlappen. Mittendrin fängt er an zu weinen wegen seinem Hündchen,
-[FM4_E]
-~w~Innen drin sieht's ziemlich aus.
+[MOB58_F]
+das gestorben ist, als er 7 war, und dass seine Mama ihn nie lieb hatte.
-[FM4_F]
-~w~Wir haben so einem Typ versehentlich ein Loch in den Kopf gemacht.
+[MOB58_G]
+Und Tommy - privat läuft er in Perücke und BH rum.
-[FM4_H]
-~w~Bring den Wagen zur Schrottpresse, bevor die Cops ihn finden.
+[MOB58_H]
+Ich bin nicht gut auf dich zu sprechen!
-[AM3]
-'DER PAPARAZZO'
+[MOB59_A]
+Oh, Tommy. Ich bin's, Mercedes.
-[AM4]
-'ZAHLTAG FÜR RAY'
+[MOB59_B]
+Ich wollte dir nur sagen, es ist ganz toll beim Film.
-[AM5]
-'V-MANN TANNER'
+[MOB59_C]
+Wenn du nochmal etwas für mich hast, sag Bescheid.
-[AM1_A]
-Wir müssen ein paar Dinge klären, bevor wir unsere Beziehungen fortsetzen,
+[MOB59_D]
+Wirklich. Ich wollte immer Schauspielerin werden.
-[AM1_B]
-geschäftlich oder sonstwie. Legen wir also die Karten auf den Tisch.
+[MOB59_E]
+Ich denke, ich lerne viel über die Dramaturgie.
-[AM1_C]
-Ich bin eine Yakuza und ich weiß, dass du für Salvatore Leones Familie gearbeitet hast.
+[MOB59_F]
+Es ist so lehrreich! Vielen, vielen Dank. Bis bald. Adios.
-[AM1_D]
-Ich kann dir einen Job in unserer Organisation verschaffen,
+[MOB_99]
+Geh zu der Telefonzelle vor Ort.
-[AM1_E]
-aber zuerst musst du mir beweisen, dass du dich wirklich von der Mafia losgesagt hast.
+[MOB_98]
+Geh zu der Telefonzelle vor Ort.
-[AM1_G]
-Sorge dafür, dass er seinen Club nicht lebend erreicht.
+[MOB_97]
+Geh zu der Telefonzelle vor Ort.
-[AM1_H]
-Maria und ich reden inzwischen ein bisschen über die alten Zeiten.
+[MOB_96]
+Geh zu der Telefonzelle vor Ort.
-[AM1_I]
-Oh, Asuka, du hast einen Massagestab.
+[MOB_95]
+Geh zu der Telefonzelle vor Ort.
-[AM1_J]
-Das ist kein Massagestab.
-
-[AM1_1]
-~g~Salvatore verlässt jetzt Luigis Club!
-
-[AM1_2]
-~r~Man hat dich entdeckt!
-
-[AM1_3]
-~r~Du hast Salvatore verpasst!
+[A_TIME]
++~1~ Sekunden
-[AM1_4]
-~r~Na, prima! Du hast dein Opfer verscheucht. Und du willst ein Profi sein?
+[F_RANGE]
+~g~Du bist außer Reichweite des Feuerwehrfunks. Fahr näher an eine Feuerwache heran!
-[AM1_5]
-~g~Begib dich in den Rotlichtbezirk und warte, bis Salvatore den Club verlässt.
+[DODO_FT]
+Du bist ~1~ Sekunden geflogen!
-[AM1_7]
-~r~Salvatore sitzt bequem zu Hause und schlürft einen Cocktail. 'Der Schakal' bist du nicht gerade!
+[GA_8]
+Benutze den Zünder, um die Bombe hochgehen zu lassen.
-[AM1_8]
-~g~Salvatore wird Luigis Club um zirka ~1~:~1~ verlassen.
+[GA_10]
+Hübsche Karre. Hier sind deine $~1~.
-[AM2_4]
-~g~Du bist für die so unsichtbar wie ein Hochhaus!
+[GA_11]
+So eine Karre haben wir schon. Die können wir nicht gebrauchen.
-[AM3_A]
-Ein Reporter hat rumgeschnüffelt.
+[GA_12]
+Bombe ist scharf.
-[AM3_B]
-Maria und ich sind ein bisschen ins Grüne gefahren, bis du diesen miesen Voyeur beseitigt hast.
+[GA_13]
+Auf dich ist Verlass. Wenn du alle, die auf der Liste stehen, abgeliefert hast, kriegst du einen Bonus.
-[AM4_A]
-Ah, mein hübsches Helferlein!
+[GA_14]
+Du hast alle georderten Karren geliefert. Sehr gut. Hier, für dich.
-[AM4_B]
-Maria ist gerade beschäftigt, aber ich richte ihr aus, dass du hier warst.
+[GA_15]
+Hoffentlich gefällt dir die neue Farbe.
-[AM4_C]
-Wer ist da? Asuka? Ich weiß, ich war ein böses Mädchen, aber ich muss dringend pinkeln!
+[GA_16]
+Das Umspritzen ist gratis.
-[AM4_D]
-Wird Zeit dass du unseren Mann bei der Polizei kennenlernst.
+[GA_19]
+An dem Modell haben wir kein Interesse.
-[AM4_E]
-Das ist seine Bezahlung für den letzten Job, den er für uns erledigt hat.
+[GA_20]
+Von der Sorte haben wir schon mehr als genug. Sorry, da kommen wir nicht ins Geschäft.
-[AM4_F]
-Verständlicherweise ist er vorsichtig.
+[CHASE]
+Größtes Medieninteresse bisher
-[AM4_G]
-Begib dich so schnell wie möglich zu dem öffentlichen Fernsprecher in Torrington und warte auf seine Anweisungen.
+[CHASE1]
+Null
-[AM5_A]
-Maria und ich sind shoppen gegangen.
+[CHASE2]
+Minimal
-[AM5_B]
-Unser Spitzel hat uns informiert, dass einer unserer Fahrer ein übereifriger Undercover Cop ist!
+[CHASE3]
+Vages Interesse
-[AM5_C]
-Ohne sein Auto ist er praktisch ein Nichts. Wir haben seinen Wagen mit einem Sender versehen.
+[CHASE4]
+Lokalblatt Seite 7
-[AM5_D]
-Knöpf ihn dir vor!
+[CHASE5]
+Lokalblatt Titelseite
-[AM5_1]
-Tanner hat dich bemerkt!
+[CHASE6]
+Vice Courier einspaltig
-[AS1]
-'DER KÖDER'
+[CHASE7]
+Vice Courier Titelseite
-[AS2]
-'ESPRESSO-2-GO!'
+[CHASE8]
+Lokalsender 3-Uhr-Nachrichten
-[AS4]
-'DAS LÖSEGELD'
+[CHASE9]
+Lokalsender 20-Uhr-Nachrichten
-[AS1_A]
-~w~Miguel findet anscheinend, dass ich ihn schlecht behandle.
+[CHASE10]
+Lokalsender Live-Berichterstattung
-[AS1_B]
-~w~Trotzdem hat er uns mitgeteilt, wie sehr Catalina deine Rache fürchtet.
+[CHASE11]
+UFA Today Seite 12
-[AS2_A]
-~w~Wir haben Catalinas Pläne mit dem SPANK unterschätzt.
+[CHASE12]
+UFA Today Seite 4
-[AS2_B]
-~w~Das beschränkt sich bei weitem nicht darauf, dass die Yardies es an der Straßenecke verkaufen.
+[CHASE13]
+Foto in UFA Today
-[AS2_D]
-~w~Die verkaufen SPANK über Kaffeestände.
+[CHASE14]
+Landesweites TV 4-Uhr-News
-[AS2_1]
-~g~Alle Espressostände in Portland zerstört!!
+[CHASE15]
+Landesweites TV 20-Uhr-News
-[AS2_2]
-~g~Alle Espressostände auf Staunton Island zerstört!!
+[CHASE16]
+Landesweite Live-Berichterstattung
-[AS2_3]
-~g~Alle Espressostände in Shoreside Vale zerstört!!
+[CHASE17]
+Internationale Berichterstattung
-[AS2_4]
-~r~Das Kartell hat seine Dealer gewarnt!!
+[CHASE18]
+Nationale Krise
-[AS2_5]
-~g~Da sind noch Espressostände in Shoreside Vale und auf Staunton Island!
+[CHASE19]
+Internationale Krise
-[AS2_6]
-~g~Da sind noch Espressostände in Shoreside Vale!
+[CHASE20]
+Weltereignis
-[AS2_7]
-~g~Da sind noch Espressostände auf Staunton Island!
+[CHASE21]
+Stoff aus dem Legenden sind
-[AS2_8]
-~g~Da sind noch Espressostände in Portland!
+[CR_1]
+Kran kann dieses Fahrzeug nicht anheben.
-[AS2_9]
-~g~Da sind noch Espressostände in Portland und Shoreside Vale!
+[PU_MONY]
+Du hast nicht genug Geld.
-[AS2_10]
-~g~Da sind noch Espressostände in Portland und auf Staunton Island!
+[CO_ALL]
+Du hast sie alle geliefert. Hier, für dich.
-[AS2_12]
-~g~Suche in den Sadtteilen von Liberty City nach ~b~Espresso-2-Go-Ständen!
+[FEM_ON]
+AN
-[AS3_A]
-~W~Drücken wir noch fester zu oder warten wir, bis es von selbst abfällt?
+[FEM_OFF]
+AUS
-[AS3_B]
-~w~Hau einfach drauf...
+[FEM_YES]
+Ja
-[AS3_D]
-~w~Mein Helferlein!
+[FEM_NO]
+Nein
-[AS3_E]
-~w~Mir war langweilig, da dachte ich mir, ich leiste Asuka Gesellschaft.
+[FEM_RET]
+Wiederholen
-[AS3_1]
-~g~Such dir ein ~r~Boot~g~ und fahre zu der ~b~Markierungsboje!
+[FEC_NA]
+Nicht verfügbar
-[AS3_3]
-~g~Warte, bis die ~y~Maschine~g~ zur Landung ansetzt!
+[FEC_CWL]
+Eine Waffe nach links
-[AS3_5]
-~g~Sammle die Ladung ein!
+[FEC_CWR]
+Eine Waffe nach rechts
-[AS3_4]
-~g~Benutze einen Raketenwerfer, um das ~y~Flugzeug~g~ abzuschießen!!
+[FEC_LOF]
+Nach vorne sehen
-[AS3_2]
-~b~Fahr zu der Markierungsboje! ~y~Das Flugzeug landet gleich!!
+[FEC_TAR]
+Zielen
-[AS3_6]
-~g~~1~ VON 8
+[FEC_MOV]
+Bewegung
-[KM1]
-'DIE BEFREIUNG DES KANBU'
+[FEC_CAM]
+Blickwinkel
-[KM3]
-'DER JAMAICA DEAL'
+[FEC_PAU]
+Pause
-[KM4]
-'DIE GANG'
+[FEC_ENV]
+In Fahrzeug einsteigen
-[KM5]
-'DIE ABRECHNUNG'
+[FEC_JUM]
+Springen
-[KM1_A]
-Meine Schwester hält große Stücke auf dich,
+[FEC_ATT]
+Angreifen oder Waffe abfeuern
-[KM1_E]
-aber ich bin noch nicht überzeugt, dass ein Gajin wie du was auf dem Kasten hat.
+[FEC_RUN]
+Rennen
-[KM1_B]
-Vielleicht kannst du mir bei einer etwas kniffligen Sache helfen.
+[FEC_FPC]
+Subjektive Kamera
-[KM1_F]
-Ein Fehlschlag wäre natürlich unverzeihlich.
+[FEC_LL]
+Nach links sehen
-[KM1_C]
-Ein Yakuza Kanbu sitzt in Haft und wartet auf seine Überführung zum Prozess.
+[FEC_LB]
+Nach hinten sehen
-[KM1_G]
-Er ist ein geschätztes Mitglied der Familie.
+[FEC_LR]
+Nach rechts sehen
-[KM1_H]
-Befreie ihn aus der Haft und bring ihn in das Dojo beim Bedford Point.
+[FEC_HOR]
+Hupe
-[KM1_D]
-Wir danken dir für deinen selbstlosen Einsatz. Solltest du jemals Hilfe brauchen, wird das Dojo dir jederzeit zwei Mann zur Seite stellen.
+[FEC_VES]
+Fahrzeugsteuerung
-[KM1_1]
-~g~Klau ein Polizeiauto!
+[FEC_BRA]
+Bremsen oder rückwärts fahren
-[KM1_2]
-~g~Bau eine Bombe in den Wagen ein!
+[FEC_HAB]
+Handbremse
-[KM1_3]
-~g~Jetzt bring ihn zu dem Yakuza Dojo.
+[FEC_CAW]
+Fahrzeugwaffe
-[KM1_5]
-~g~Okay, jetzt fahr zum Polizeirevier.
+[FEC_ACC]
+Beschleunigen
-[KM1_6]
-~g~Bau eine Bombe in das Auto ein!
+[FEC_CCF]
+Konfiguration :
-[KM1_7]
-~g~Nur autorisierte Polizeifahrzeuge!
+[FEC_CF1]
+Konfig. 1
-[KM1_9]
-~r~Du hast keine Autobombe benutzt, um die Wand zu sprengen.
+[FEC_CF2]
+Konfig. 2
-[KM1_10]
-~r~Der Yakuza Kanbu ist tot - genau wie deine Ehre!
+[FEC_CF3]
+Konfig. 3
-[KM1_11]
-~r~Du hast dich selbst in Schwierigkeiten gebracht!
+[FEC_CF4]
+Konfig. 4
-[KM2_A]
-Gewisse Umgangsformen sind in diesem Beruf von nicht zu unterschätzender Wichtigkeit.
+[FEC_CDP]
+Controller-Anzeige :
-[KM2_B]
-Es ist eine Schande. Jemand hat mir einmal einen Gefallen getan, und ich konnte mich nie dafür erkenntlich zeigen.
+[FEC_ONF]
+Zu Fuß
-[KM2_C]
-Der Mann ist ein Autonarr, und er hat gebeten, dass wir ihm bestimmte Modelle für seine Sammlung besorgen.
+[FEC_INC]
+Im Auto
-[KM2_F]
-Mein Ehrgefühl verlangt das von mir.
+[FEC_VIB]
+Vibration :
-[KM2_2]
-~g~Auto abgeliefert.
+[FEL_ENG]
+Englisch
-[KM3_A]
-Wenn Ungemach droht, wendet der Narr sich ab, während der Weise sich ihm stellt.
+[FEL_FRE]
+Französisch
-[KM3_B]
-Das kolumbianische Kartell hat unsere wiederholten Bitten ignoriert, unsere Interessen in Liberty zu berücksichtigen.
+[FEL_GER]
+Deutsch
-[KM3_C]
-Jetzt verhandeln die mit den Jamaikanern, um uns weiter zu demütigen.
+[FEL_ITA]
+Italienisch
-[KM3_D]
-Sie wollen den Deal am anderen Ende der Stadt besiegeln.
+[FEL_SPA]
+Spanisch
-[KM3_F]
-Nimm einen meiner Männer, klau einen Yardie-Wagen und statte den Kolumbianern einen Besuch ab.
+[FED_DBG]
+Menu Debug
-[KM3_E]
-Unser Ehrgefühl verlangt es, dass niemand am Leben bleibt.
+[FED_RID]
+Reload IDE
-[KM3_2]
-~g~Hole deinen Kontaktmann ab.
+[FED_RIP]
+Reload IPL
-[KM3_3]
-~g~Das Treffen findet auf dem Krankenhaus-Parkplatz in Rockford statt!
+[FED_PAH]
+Parse Heap
-[KM3_4]
-~r~Sie sind entkommen!
+[FED_DFL]
+CTheScripts::DbgFlag
-[KM3_6]
-~g~Knöpf sie dir vor! Mach sie fertig!
+[FED_DLS]
+Big White Debug Light Switched
-[KM3_8]
-~g~Du brauchst einen Yardie-Wagen für diesen Job!
+[FED_SPR]
+Show Ped Road Groups
-[KM3_9]
-~r~Einer der Kolumbianer ist tot. Der Deal ist geplatzt.
+[FED_SCR]
+Show Car Road Grups
-[KM3_10]
-~r~Der Kontaktmann ist tot!
+[FED_SCZ]
+Show Cull Zones
-[KM4_A]
-Um wahrhaft stark zu sein, darfst du niemals Schwäche zeigen.
+[FED_DSR]
+Debug Streaming Requests
-[KM4_C]
-Sammle die Gelder umgehend ein, damit wir sie in unsere Casinos stecken können.
+[FED_SCP]
+gbShowCollisionPolys
-[KM4_1]
-Ich kann euch nicht bezahlen, und selbst wenn ich könnte, würde ich es nicht tun.
+[PL_STAT]
+Spielerstatistiken
-[KM4_9]
-Eine Jugendbande hat mich gerade überfallen! Sie haben mir alles genommen!
+[PE_WAST]
+Von dir abservierte Personen
-[KM4_2]
-Ihr seid zu nichts nutze.
+[PE_WSOT]
+Von anderen abservierte Personen
-[KM4_10]
-Was sind SIE denn eigentlich für ein Yakuza..?
+[TM_BUST]
+Zahl deiner Verhaftungen
-[KM4_3]
-Dafür bezahle ich euch Gangster nicht. Diese Art von Schutz kann ich auch von der verdammten Polizei bekommen!
+[GNG_WST]
+Gang-Mitglieder
-[KM4_4]
-~g~Bestrafe die verantwortliche Gang und stelle das ~b~Schutzgeld~g~ sicher!
+[DED_CRI]
+Kriminelle
-[KM4_7]
-~r~Der Ladenbesitzer hat sein Leben verröchelt.
+[PER_COM]
+Absolviert (in Prozent)
-[KM4_5]
-Donald Love möchte dich in seinem Teegarten sehen, um mit dir zu reden.
+[KGS_EXP]
+Sprengstoffverbrauch in kg
-[KM4_6]
-Da ist das Geld. Es ist alles da!
+[ACCURA]
+Treffsicherheit
-[KM4_8]
-~g~Tasche aufgesammelt!
+[ST_WEAP]
+Waffen-Budget
-[KM5_A]
-DU! Wie passend, dass du ausgerechnet jetzt dein ehrloses Gesicht zeigst!
+[ST_PROP]
+Budget für Objekte
-[KM5_B]
-Es scheint, deine Versuche, die Jamaikaner davon abzuhalten,
+[ST_AUTO]
+Budget für Autoreparaturen und Lackierung
-[KM5_B1]
-sich mit dem Kartell einzulassen, sind komplett fehlgeschlagen!
+[ST_PHOT]
+Von dir gemachte Fotos
-[KM5_C]
-Yardie-Pusher verdealen päckchenweise SPANK in den Straßen von Liberty, als würden sie Hotdogs verkaufen!
+[ST_LOAN]
+Besuche von Kredithaien
-[KM5_D]
-Die Mistkerle vom Kartell lachen uns aus, lachen MICH aus!
+[ST_STOR]
+Geknackte Läden
-[KM5_E]
-Ich gebe dir eine letzte Chance das Vertrauen zu rechtfertigen, das meine Schwester in dich setzt!
+[ST_MOVI]
+Film-Stunts
-[KM5_F]
-Mach diese Dreckskerle fertig und wasch deine befleckte Ehre im Blut unserer Feinde rein!!!
+[ST_PIZZ]
+Gelieferte Pizzas
-[KM5_3]
-~r~Du hast mindestens ~1~ der Yardies nicht erwischt.
+[ST_GARB]
+Getätigte Müllfuhren
-[KM5_4]
-~g~Du hast ~1~ der Yardies erwischt.
+[ST_ICEC]
+Verkaufte Eiscreme
-[KM5_5]
-~g~Du hast ~1~ der Yardies erwischt. BONUS $~1~
+[TOP_SHO]
+Beste Schießstand-Punktzahl
-[RM1]
-'DAS SCHWEIGEN DES VERRÄTERS'
+[SHO_RAN]
+Schießstand-Rangliste
-[RM3]
-'BRENNENDE BEWEISE'
+[SEAGULL]
+Abgeschossene Möwen
-[RM4]
-'TÖDLICHE BOOTSFAHRT'
+[PROPOWN]
+Objekte in deinem Besitz
-[RM5]
-'DER GEPANZERTE ZEUGE'
+[ST_TIME]
+Gespielte Zeit
-[RM1_D]
-Er steht unter Zeugenschutz und sitzt mit bewaffneten Leibwächtern in einer Wohnung in Newport, irgendwo hinter dem Parkplatz.
+[ST_FTIM]
+Flugstunden
-[RM1_E]
-Zünde die Bude an, und wenn sie rausgerannt kommen, kannst du sie dir vornehmen. Sorge dafür, dass er mit niemandem redet.
+[ST_PRAN]
+Piloten-Rating
-[RM1_1]
-~g~Check das Zeugenschutz-Haus aus.
+[ST_RAN0]
+Anfänger
-[RM1_2]
-~g~Knöpf dir McAffrey vor!
+[ST_RAN1]
+Navigator
-[RM2_A1]
-Hey, Junge! Hier rüber!
+[ST_RAN2]
+Co-Pilot
-[RM2_A]
-Ein alter Kumpel aus der Army macht Geschäfte in Rockford.
+[ST_RAN3]
+Halb-Profi
-[RM2_D]
-Er braucht Hilfe. Zum Dank will er dir Superpreise machen für alles, was du bei ihm kaufst.
+[ST_RAN4]
+Könner
-[RM2_E]
-Ray hat schon angerufen... Aber ich dachte, er schickt mehr Leute.
+[ST_RAN5]
+Profi
-[RM2_F]
-Na ja, drei Arme sind besser als einer, also nimm dir, was du brauchst.
+[ST_RAN6]
+Ass
-[RM2_G]
-~g~Sieh nach Phil!
+[ST_RAN7]
+Roter Baron
-[RM2_H]
-~r~Phil hat's erwischt!!
+[ST_DRWN]
+Gefütterte Fische
-[RM2_L]
-Heh-hey! Wäre ich mit DIR in Nicaragua gewesen, hätte ich vielleicht meinen Arm noch!
+[ST_FASH]
+Kleidungsbudget
-[RM2_N]
-Lass das Geld da. Und jetzt verschwinde. Ich regle das mit den Cops.
+[ST_DAMA]
+Zerstörte Objekte
-[RM3_D]
-Das Beweismaterial wird gerade quer durch die Stadt transportiert.
+[TM_DED]
+Krankenhausbesuche
-[RM3_E]
-Du wirst diesen Wagen rammen und jedes kleine Beweisstück einsammeln, wenn es rausfällt.
+[DAYSPS]
+Im Spiel verstrichene Tage
-[RM3_F]
-Wenn du alles hast, lass das Zeug im Wagen und zünde ihn an.
+[NUMSHV]
+Besuche in Versteck
-[RM3_G]
-Das bringt uns beiden eine Stange Geld ein, mein Junge.
+[MXCARD]
+Weitester IRRSINNS-Sprung (in Fuß)
-[RM3_1]
-~g~Lass das Beweismaterial in einem Auto und zünde das Auto dann an.
+[MXCARJ]
+Höchster IRRSINNS-Sprung (in Fuß)
-[RM3_4]
-~g~Der Staatsanwalt hat die Beweisfotos verloren!
+[MXCARDM]
+Weitester IRRSINNS-Sprung (m)
-[RM3_6]
-~r~Die Fotos werden sich über ganz Liberty verteilen!
+[MXCARJM]
+Höchster IRRSINNS-Sprung (m)
-[RM3_7]
-~g~Steck jetzt das Auto in Brand!
+[MXFLIP]
+Max. Anzahl Salti
-[RM4_A]
-Ich glaube, mein Partner ist ein Verräter.
+[MXJUMP]
+Max. Drehungen im Sprung
-[RM4_C]
-Meistens fährt er abends mit seinem Boot fischen, nahe dem Leuchtturm auf dem Portland Rock.
+[BUL_FIR]
+Verschossene Kugeln
-[RM4_D]
-Klau ein Polizeiboot und mach seinen miesen Machenschaften ein Ende!
+[BUL_HIT]
+Kugeln, die trafen
-[RM4_1]
-~g~Klau ein Polizeiboot.
+[SPRAYIN]
+Anzahl Lackierungen
-[RM4_2]
-~g~Fahr zum Leuchtturm und nimm dir Rays Partner vor!
+[BSTSTU]
+Bester IRRSINNS-Stunt bisher
-[RM5_A]
-Du unfähiger Idiot!
+[INSTUN]
+Irrsinns-Stunt
-[RM5_A1]
-Du hast alles vermasselt! Es geht um mein Leben, und du kannst nicht mal eine Fliege totschlagen!
+[PRINST]
+Super Irrsinns-Stunt
-[RM5_B]
-Ich hab dir viel Geld gezahlt, dafür, dass du diesen Zeugen beseitigst, aber er lebt!
+[DBINST]
+Doppelter Irrsinns-Stunt
-[RM5_B1]
-Und heute wird er vor dem FBI aussagen!
+[DBPINS]
+Super-Doppel-Irrsinns-Stunt
-[RM5_C]
-Er muss jeden Moment aus dem Carson General Hospital in Rockford rausgebracht werden.
+[TRINST]
+Dreifacher Irrsinns-Stunt
-[RM5_D]
-Wenn er singt, singe ich auch...
+[PRTRST]
+Super-Dreifach-Irrsinns-Stunt
-[RM5_E]
-Also los, erledige den Job, für den ich dich bezahlt habe!
+[QUINST]
+Vierfacher Irrsinns-Stunt
-[RM5_1]
-~g~Fang den Krankenwagen ab.
+[PQUINS]
+Super-Vierfach-Irrsinns-Stunt
-[RM5_2]
-~g~Man hat dich bemerkt!!
+[NOSTUC]
+Bisher keine Irrsinns-Stunts geschafft
-[RM5_3]
-~g~Das war ein Ablenkungsmanöver!
+[NOUNIF]
+Monster-Stunts geschafft
-[RM5_4]
-~g~Kugel können den Panzer nicht durchschlagen!!
+[NMISON]
+Begonnene Missionen
-[RM5_5]
-~g~Der Panzer ist feuersicher!!
+[PASDRO]
+Ans Ziel beförderte Fahrgäste
-[RM5_7]
-~r~Zeuge wurde abgeliefert!!
+[MONTAX]
+Mit Taxi verdientes Geld
-[RM5_8]
-~g~Zeuge ist ertrunken!!
+[DAYPLC]
+Tagesetat für Polizei
-[LOVE2]
-'DAS KENJI-KOMPLOTT'
+[CRIMRA]
+Rang:
-[LOVE3]
-'NÄCHTLICHER FISCHZUG'
+[STPR_1]
+Malibu Club
-[LOVE1_A]
-Zunächst möchte ich dir danken, dass du diese Sache für mich geregelt hast.
+[STPR_2]
+Druckerei
-[LOVE1_F]
-Die Leute interpretieren heute in alles etwas hinein.
+[STPR_3]
+Filmstudio
-[LOVE1_D]
-Sie versuchen, mir immer noch mehr Geld abzupressen, aber ich halte nichts von Verhandlungen.
+[STPR_4]
+Eiscremefabrik
-[LOVE1_E]
-Deal ist Deal, die sehen keinen Penny von mir.
+[STPR_5]
+Autohaus
-[LOVE1_G]
-Befreie meinen Freund, egal wie.
+[STPR_6]
+Taxiunternehmen
-[LOVE1_2]
-~g~Rette den alten asiatischen Gentleman.
+[STPR_7]
+Bootswerft
-[LOVE1_3]
-~g~Bring den alten Asiaten zu Love.
+[SET1EN]
+Konfig. 1 aktiviert
-[LOVE1_4]
-~g~Der alte Asiate muss in einer der Garagen sein...
+[GMSAVE]
+Spiel speichern
-[LOVE1_6]
-~r~Der alte Asiate ist von uns gegangen!
+[FEDS_TB]
+Zurück
-[LOVE1_7]
-~g~Das Tor öffnet sich nur für Autos der kolumbianischen Gang.
+[FEST_OO]
+von
-[LOVE2_A]
-Nichts lässt die Grundstückspreise so tief purzeln wie ein guter alter Bandenkrieg,
+[FEC_TUC]
+Geschützsteuerung
-[LOVE2_B]
-außer vielleicht eine Pestepidemie... Aber das ginge hier wohl zu weit.
+[FEC_RS3]
+Radiosender auswählen (L3-Taste)
-[LOVE2_C]
-Wie ich bemerkt habe, sind die Yakuza und die Kolumbianer nicht eben Busenfreunde.
+[FEC_HO3]
+Hupe (L3-Taste)
-[LOVE2_D]
-Daraus sollte man Kapital schlagen.
+[C_FAIL]
+Bürgerwehr-Mission beendet!
-[LOVE2_E]
-Ich möchte, dass du dir den Yakuza WAKA-Gashira Kenji Kasen vornimmst.
+[C_ESCP]
+~r~Der Verdächtige ist entwischt!
-[LOVE2_F]
-Kenji ist bei einem Treffen auf dem Dach der Parkgarage in Newport.
+[C_VIGIL]
+BÜRGERWEHR BONUS!!
-[LOVE2_G]
-Besorg dir einen Wagen des Kartells und nimm ihn dir vor.
+[HEAL_A]
+Dein ~h~Gesundheitszustand~w~ wird rechts oben auf dem Bildschirm in Orange angezeigt.
-[LOVE2_H]
-Die Yakuza werden das als Kriegserklärung des Kartells auffassen.
+[WRONGCD]
+Falsche DVD. Bitte legen Sie die richtige DVD ein.
-[LOVE2_1]
-~g~Klau in Fort Staunton einen Wagen der kolumbianischen Gang!
+[NOCD]
+Die DVD-Lade ist leer. Bitte DVD einlegen.
-[LOVE2_2]
-~g~Fahre jetzt zu dem ~p~Parkhaus in Newport~g~ und zieh Kenji aus dem Verkehr!
+[OPENCD]
+Die DVD-Lade ist offen. Bitte schließen.
-[LOVE2_3]
-~r~Wenn du nicht mit einem Auto des Kartells aufkreuzt, wird man dich erkennen!
+[CDERROR]
+Fehler beim Lesen der 'Grand Theft Auto: Vice City' DVD.
-[LOVE2_4]
-~r~Die Yakuza haben dich erkannt!
+[RESTART]
+Neues Spiel wird gestartet
-[LOVE2_6]
-~r~Du hast alle Zeugen aus dem Weg geräumt!!
+[GA_3]
+Keine Gratisjobs mehr. Umspritzen kostet $100!
-[LOVE3_A]
-In scheinheiligen Zeiten wie diesen sind bestimmte wertvolle Waren schwer zu importieren.
+[GA_1]
+Hey, so was heißes rühre ich nicht an!
-[LOVE3_C]
-Es wird einige kleine Päckchen ins Wasser abwerfen.
+[GA_1A]
+Komm wieder, wenn du nicht so viel zu tun hast...
-[LOVE3_D]
-Sammle sie ein, bevor es ein anderer tut.
+[HELP9_C]
+Drücke die~h~ ~k~~PED_FIREWEAPON~~w~, um das Präzisionsgewehr ~h~abzufeuern~w~.
-[LOVE3_1]
-~g~Besorg dir ein ~r~Boot~g~ und folge dem ~y~Flugzeug~g~!
+[TAXI2]
+~r~Die Zeit ist um!
-[LOVE4]
-'DER FLUGHAFEN-COUP'
+[PAGEB13]
+Gesundheits-Powerups in Versteck angeliefert.
-[LOVE5]
-'BODYGUARD ACTION'
+[PAGEB14]
+Adrenalin in Versteck vorrätig.
-[LOVE4_A]
-Danke, dass du die Päckchen geholt hast. Aber die sollten nur als Köder dienen.
+[FESZ_CA]
+Abbrechen
-[LOVE4_B]
-Sorry, aber so läuft das manchmal in dem Geschäft.
+[FES_NGA]
+Neues Spiel
-[LOVE4_C]
-Die Ware, um die es mir wirklich geht, ist noch in dem Flugzeug versteckt.
+[FES_CAN]
+Abbrechen
-[LOVE4_F]
-Ich habe die Beamten bestochen.
+[FESZ_QL]
+Alle nicht gespeicherten Daten des aktuellen Spiels werden verloren gehen. Ladevorgang fortsetzen?
-[LOVE4_1]
-~r~Das kolumbianische Kartell ist da!!
+[FESZ_QD]
+Dieses gespeicherte Spiel wirklich löschen?
-[LOVE4_2]
-~g~Das Päckchen ist weg! Du musst die Kolumbianer finden und es ihnen abjagen.
+[FESZ_QO]
+Dieses gespeicherte Spiel wirklich überschreiben?
-[LOVE4_3]
-~g~Bauunternehmen Panlantic...?
+[FESZ_QR]
+Wirklich ein neues Spiel beginnen? Alle Daten seit dem letzten Speichern werden verloren gehen. Weiter?
-[LOVE4_5]
-~g~Das Päckchen müsste im Flugzeug sein...
+[T4X4_1]
+'PCJ Rallye'
-[LOVE4_6]
-~g~Nimm den Lift nach oben in den Tower!
+[BMX_1]
+'Krasses Gelände'
-[LOVE5_B]
-Mein asiatischer Freund braucht einen Bodyguard. Er lässt meine neue Lieferung auf Qualität überprüfen.
+[BMX_2]
+'Teststrecke'
-[LOVE5_1]
-~g~Los!
+[BMXFAIL]
+~r~Du hast es nicht geschafft, einen neuen Rekord aufzustellen!
-[LOVE5_2]
-~g~Du wirst ein Auto brauchen!
+[BMX_REC]
+~g~Neuer Rekord:~1~ !!
-[LOVE5_3]
-~g~Los, sieh nach, ob am Tunnelende die Luft rein ist.
+[T4X4_3]
+'CHECKPOINT FIEBER'
-[LOVE5_4]
-~r~Dem Truck darf nichts passieren!
+[MM_1]
+'PYLONEN-RALLYE'
-[RM6]
-'IM FADENKREUZ'
+[T4X4_F]
+~r~Du hast gekniffen! Schon überfordert?
-[RM6_A]
-Dir ist niemand gefolgt? Gut.
+[LANDSTK]
+Landstalker
-[RM6_B]
-Es wird langsam brenzlig, ich stecke bis zum Hals in der Scheiße!
+[IDAHO]
+Idaho
-[RM6_D]
-Die haben mich im Visier, ich muss mich absetzen.
+[STINGER]
+Stinger
-[RM6_E]
-Wenn du mich rechtzeitig zum Flughafen bringst, lass ich ordentlich was springen.
+[LINERUN]
+Linerunner
-[RM6_666]
-Pass gut auf meinen kugelsicheren Patriot auf, Ray. Wir sehen uns in Miami.
+[PEREN]
+Perennial
-[CAT1]
-'LÖSEGELD'
+[SENTINL]
+Sentinel
-[CAT2]
-'DIE ÜBERGABE'
+[RIO]
+Rio
-[CAT1_A]
-Ich habe deine Maria. Wenn ihr Gesicht nicht aussehen soll, als wär's in einen Fleischwolf geraten,
+[PATRIOT]
+Patriot
-[CAT2_F]
-Ich hab mir 'nen Fingernagel abgebrochen und meine Frisur ist hin! Fünfzig Dollar im Eimer!
+[FIRETRK]
+Feuerwehrwagen
-[CAT2_G]
-Mann, hatte ich Angst. Aber dann dachte ich mir, du bist doch kein kleines Mädchen mehr.
+[TRASHM]
+Trashmaster
-[CAT2_H]
-Du, das wird lustig, weißt du, meine Schwester will nämlich mit ihren zwei Kindern eine zeitlang bei uns wohnen,
+[STRETCH]
+Stretch Limo
-[CAT2_I]
-weil ihr Mann gerade mal wieder fremdgeht und...
+[MANANA]
+Manana
-[CAT1_C]
-XXXX
+[INFERNS]
+Infernus
-[CAT1_D]
-XXXX
+[VOODOO]
+Voodoo
-[CAT1_E]
-XXXX
+[PONY]
+Pony
-[CAT1_F]
-Du musst rechtzeitig bei Catalina sein!
+[MULE]
+Mule
-[CAT1_G]
-XXXX
+[CHEETAH]
+Cheetah
-[CAT1_H]
-XXXX
+[AMBULAN]
+Krankenwagen
-[CAT1_I]
-XXXX
+[FBICAR]
+FBI Washington
-[CAT1_J]
-XXXX
+[MOONBM]
+Moonbeam
-[CAT1_K]
-XXXX
+[ESPERAN]
+Esperanto
-[CAT1_L]
-XXXX
+[TAXI]
+Taxi
-[AS4_1]
-XXXX
+[WASHING]
+Washington
-[CAT_MON]
-~g~Du hast noch nicht genug Geld. Du brauchst $500.000.
+[BOBCAT]
+Bobcat
-[BITCH_D]
-~g~Maria ist tot!
+[WHOOPEE]
+Mr Whoopee
-[WEATHER]
-WETTER ÄNDERN
+[BFINJC]
+BF Injection
-[WEATHE2]
-WETTER NORMAL
+[HUNTER]
+Hunter
-[8001]
-Du hast komplett versagt!
+[POLICAR]
+Polizei
-[1000]
-DU BIST TOT
+[ENFORCR]
+Enforcer
-[1001]
-DU BIST TOT
+[SECURI]
+Securicar
-[1002]
-DU BIST TOT
+[BANSHEE]
+Banshee
-[1003]
-DU BIST TOT
+[PREDATR]
+Predator
-[1004]
-DU BIST TOT
+[BUS]
+Bus
-[1005]
-VERHAFTET
+[RHINO]
+Rhino
-[1006]
-VERHAFTET
+[BARRCKS]
+Barracks OL
-[1007]
-VERHAFTET
+[CUBAN]
+Kubanischer Hermes
-[1008]
-VERHAFTET
+[HELI]
+Helikopter
-[1009]
-VERHAFTET
+[DODO]
+Dodo
-[GA_4]
-Autobomben kosten $1000 pro Stück.
+[COACH]
+Coach
-[GA_5]
-In deinem Wagen ist schon eine Autobombe.
+[CABBIE]
+Cabbie
-[GA_6] { re3 change }
-Park die Karre, mach sie durch Drücken der ~h~~k~~VEHICLE_FIREWEAPON~-Taste~w~ scharf, und dann nichts wie weg!
+[STALION]
+Stallion
-[GA_7] { re3 change }
-Mach die Bombe mit der ~h~~k~~VEHICLE_FIREWEAPON~-Taste~w~ scharf. Dann geht sie hoch, wenn der Wagen angelassen wird.
+[RUMPO]
+Rumpo
-[GA_8]
-Benutze den Zünder, um die Bombe hochgehen zu lassen.
+[RCBANDT]
+RC Bandit
-[GA_9]
-Du hast ~1~ von zehn Spezialautos beschafft.
+[ROMERO]
+Romeros Leichenwagen
-[GA_10]
-Hübsche Karre. Hier sind deine $~1~.
+[PACKER]
+Packer
-[GA_11]
-So eine Karre haben wir schon. Die können wir nicht gebrauchen.
+[ADMIRAL]
+Admiral
-[GA_12]
-Bombe ist scharf.
+[SQUALO]
+Squalo
-[GA_13]
-Auf dich ist Verlass. Wenn du alle, die auf der Liste stehen, abgeliefert hast, kriegst du einen Bonus.
+[SEASPAR]
+Sea Sparrow
-[GA_14]
-Du hast alle georderten Karren geliefert. Sehr gut. Hier, für dich.
+[PIZZABO]
+Pizza Boy
-[GA_15]
-Hoffentlich gefällt dir die neue Farbe.
+[GANGBUR]
+Gang Burrito
-[GA_16]
-Das Umspritzen ist gratis.
+[TROPIC]
+Tropic
-[GA_19]
-An dem Modell haben wir kein Interesse.
+[SPEEDER]
+Speeder
-[GA_20]
-Von der Sorte haben wir schon mehr als genug. Sorry, da kommen wir nicht ins Geschäft.
+[REEFER]
+Reefer
-[CR_1]
-Kran kann dieses Fahrzeug nicht anheben.
+[FLATBED]
+Flatbed
-[PU_MONY]
-Du hast nicht genug Geld.
+[YANKEE]
+Yankee
-[CO_ALL]
-Du hast sie alle geliefert. Hier, für dich.
+[CADDY]
+Caddy
-[PAUSED]
-PAUSE
+[ZEBRA]
+Zebra Cab
-[HEALTH1]
-Stell dich nicht so an! Dir fehlt doch überhaupt nichts.
+[TOPFUN]
+Top Fun
-[HEALTH2]
-Medizinische Versorgung ist teuer.
+[SKIMMER]
+Skimmer
-[HEALTH3]
-Ich flick dich wieder zusammen.
+[PCJ600]
+PCJ 600
-[HEALTH4]
-Das macht $250.
+[PHOENIX]
+Phoenix
-[FEB_STA]
-Statistik
+[FAGGIO]
+Faggio
-[FEB_BRI]
-Mission
+[FREEWAY]
+Freeway
-[FEB_CON]
-Steuerung
+[RCBARON]
+RC Baron
-[FEB_AUD]
-Audio
+[RCRAIDE]
+RC Raider
-[FEB_DIS]
-Anzeige
+[GLENDAL]
+Glendale
-[FEB_LAN]
-Sprache
+[OCEANIC]
+Oceanic
-[FEP_STA]
-STATISTIKEN
+[SANCHEZ]
+Sanchez
-[FEP_BRI]
-MISSIONSINFOS
+[SPARROW]
+Sparrow
-[FEP_CON]
-STEUERUNG
+[LOVEFIS]
+Love Fist
-[FEP_AUD]
-AUDIO
+[COASTG]
+Küstenwache
-[FEP_DIS]
-ANZEIGE
+[DINGHY]
+Dinghy
-[FEP_LAN]
-SPRACHE
+[HERMES]
+Hermes
-[FEF_ST1]
-Wer ist der Schurke?
+[SABRE]
+Sabre
-[FEF_ST2]
-Wie viel Chaos hast du angerichtet?
+[SABRETU]
+Sabre Turbo
-[FEF_BR1]
-Du blickst bei der Story nicht mehr durch?
+[WALTON]
+Walton
-[FEF_CO1]
-Taste dich ran, Mann!
+[REGINA]
+Regina
-[FEF_CO2]
-Wähle das Controller-Setup, das zu deinem Spielstil am besten passt
+[COMET]
+Comet
-[FEF_SA1]
-Bring deine Daten in Sicherheit!
+[DELUXO]
+Deluxo
-[FEF_SA2]
-Spiele laden und speichern
+[BURRITO]
+Burrito
-[FEF_AU1]
-Volle Dröhnung gefällig?
+[SPAND]
+Spandex Express
-[FEF_AU2]
-Radiosender und Soundeffekt auswählen
+[MARQUIS]
+Marquis
-[FEF_DI1]
-Andere Optik?
+[BAGGAGE]
+Baggage Handler
-[FEF_DI2]
-Spiel für deinen Fernseher optimieren
+[KAUFMAN]
+Kaufman-Taxi
-[FEF_LA1]
-Was für ein Gefasel!
+[COASTMA]
+Küstenwachen-Maverick
-[FEF_LA2]
-Sprache auswählen
+[MAVERIC]
+Maverick
-[FEB_PMB]
-Vorherige Missionsinfos:
+[RANCHER]
+Rancher
-[FEC_NA]
-Nicht verfügbar
+[FBIRANC]
+FBI Rancher
-[FEC_CWL]
-Eine Waffe nach links
+[VIRGO]
+Virgo
-[FEC_CWR]
-Eine Waffe nach rechts
+[GREENWO]
+Greenwood
-[FEC_LOF]
-Nach vorne schauen
+[HOTRING]
+Hotring Racer
-[FEC_TAR]
-Zielen
+[BLISTAC]
+Blista Compact
-[FEC_MOV]
-Bewegung
+[FEST_DF]
+Zu Fuß zurückgel. Strecke (Meilen)
-[FEC_CAM]
-Blickwinkel
+[FEST_DC]
+Mit Auto gefahrene Strecke (Meilen)
-[FEC_PAU]
-Pause
+[FESTDFM]
+Zu Fuß zurückgelegte Strecke (Meter)
-[FEC_ENV]
-In Fahrzeug einsteigen
+[FESTDCM]
+Mit Auto gefahrene Strecke (Meter)
-[FEC_JUM]
-Springen
+[TOT_DIS]
+Insgesamt zurückgel. Strecke (Meilen)
-[FEC_ATT]
-Angreifen\Waffe abfeuern
+[TOTDISM]
+Insgesamt zurückgel. Strecke (Meter)
-[FEC_RUN]
-Rennen
+[DISTHEL]
+Mit Helikopter geflogene Strecke (Meilen)
-[FEC_FPC]
-Subjektive Kamera
+[DISTHEM]
+Mit Helikopter geflogene Strecke (Meter)
-[FEC_LB1]
-Schau
+[DISTBOA]
+Mit Boot zurückgel. Strecke (Meilen)
-[FEC_LL]
-Nach links schauen
+[DISTBOM]
+Mit Boot zurückgel. Strecke (Meter)
-[FEC_LB2]
-nach hinten
+[FEST_LS]
+Mit Krankenwagen gerettete Menschen
-[FEC_LB]
-Nach hinten schauen
+[FEST_CC]
+Kriminelle bei Bürgerwehr-Mission
-[FEC_LR]
-Nach rechts schauen
+[FEST_FE]
+Gelöschte Feuer gesamt
-[FEC_HOR]
-Hupe
+[FEST_RP]
+Bestandene Amokfahrten
-[FEC_VES]
-Fahrzeug steuern
+[FEST_MP]
+Erledigte Missionen
-[FEC_RSC]
-Radiosender auswählen
+[FEST_BB]
+Schnelle Autos, Schnelles Geld:
-[FEC_BRA]
-Bremsen\rückwärts fahren
+[FEST_H0]
+Meiste Checkpoints
-[FEC_HAB]
-Handbremse
+[FEST_GC]
+Geschrottete Gang-Autos:
-[FEC_CAW]
-Fahrzeugwaffe
+[FEST_H1]
+Im Dschungel der Diablos
-[FEC_ACC]
-Beschleunigen
+[FEST_H2]
+Mafia-Massaker
-[FEC_SMT]
-Spezialmission aktivieren
+[FEST_H3]
+Der Casino-Coup
-[FEA_OUT]
-Tonausgabe:
+[FEST_H4]
+Rock'n'Roll mit Rumpo
-[FEA_ST]
-Stereo
+[USJ]
+MONSTER-STUNT-BONUS!
-[FEA_MNO]
-Mono
+[RATNG1]
+Unbescholtener Bürger
-[FEA_NON]
-Keinen
+[RATNG2]
+Durchschnittstyp
-[FEA_FM0]
-HEAD RADIO
+[RATNG3]
+Falschparker
-[FEA_FM1]
-DOUBLE CLEFF FM
+[RATNG4]
+Ladendieb
-[FEA_FM2]
-JAH RADIO
+[RATNG5]
+Rowdy
-[FEA_FM3]
-RISE FM
+[RATNG6]
+Laufbursche
-[FEA_FM4]
-LIPS 106
+[RATNG7]
+Taschendieb
-[FEA_FM5]
-GAME FM
+[RATNG8]
+Kleptomane
-[FEA_FM6]
-MSX FM
+[RATNG9]
+Informant
-[FEA_FM7]
-FLASHBACK 95.6
+[RATNG10]
+Spitzel
-[FEA_FM8]
-CHATTERBOX 109
+[RATNG11]
+Verräter
-[FED_DBG]
-Menu Debug
+[RATNG12]
+Hochstapler
-[FED_RID]
-Reload IDE
+[RATNG13]
+Betrüger
-[FED_RIP]
-Reload IPL
+[RATNG14]
+Schieber
-[FED_PAH]
-Parse Heap
+[RATNG15]
+Falschspieler
-[FED_RCD]
-CCullZones::RecalculateCullZoneData
+[RATNG16]
+Schläger
-[FED_DFL]
-CTheScripts::DbgFlag
+[RATNG17]
+Straßengauner
-[FED_DLS]
-Big White Debug Light Switched
+[RATNG18]
+Gauner
-[FED_SPR]
-Show Ped Road Groups
+[RATNG19]
+Halunke
-[FED_SCR]
-Show Car Road Grups
+[RATNG20]
+Outlaw
-[FED_SCZ]
-Show Cull Zones
+[RATNG21]
+Schurke
-[FED_DSR]
-Debug Streaming Requests
+[RATNG22]
+Kurier
-[FED_SCP]
-gbShowCollisionPolys
+[RATNG23]
+Gangster
-[FEM_MCM]
-Memory Card Menü
+[RATNG24]
+Obergangster
-[FEM_RMC]
-Register MemCard One
+[RATNG25]
+Galgenvogel
-[FEM_TFM]
-Test Format MemCard One
+[RATNG26]
+Ex-Knacki
-[FEM_TUM]
-Test UnFormat MemCard One
+[RATNG27]
+Schwerer Junge
-[FEM_CRD]
-Create Root Dir
+[RATNG28]
+Profi
-[FEM_CLI]
-Create And Load Icons
+[RATNG29]
+Drahtzieher
-[FEM_FFF]
-Fill First File with Guff
+[RATNG30]
+Fahrer
-[FEM_SOG]
-Save Only The Game
+[RATNG31]
+Soldat
-[FEM_CES]
-Check Every 0kB4 Save
+[RATNG32]
+Gorilla
-[FEM_STG]
-Save The Game
+[RATNG33]
+Kopfgeldjäger
-[FEM_STS]
-Save The Game under GTA3 name
+[RATNG34]
+Mann fürs Grobe
-[FEM_CPD]
-Create copy protected mag directory
+[RATNG35]
+Ronin
-[FEM_MC2]
-Memory Card Menu 2
+[RATNG36]
+Abräumer
-[FEM_TS]
-Test Save:
+[RATNG37]
+Hit-Man
-[FEM_TL]
-Test Load:
+[RATNG38]
+Partner
-[FEM_TD]
-Test Delete:
+[RATNG39]
+Butcher
-[PL_STAT]
-Spielerstatistiken
+[RATNG40]
+Troubleshooter
-[PE_WAST]
-Von dir abservierte Personen
+[RATNG41]
+Attentäter
-[PE_WSOT]
-Von anderen abservierte Personen
+[RATNG42]
+Adjutant
-[CAR_EXP]
-Explodierte Autos
+[RATNG43]
+Gemachter Mann
-[TM_BUST]
-Zahl deiner Verhaftungen
+[RATNG44]
+Rechte Hand
-[M_WASTE]
-Männliche Passanten
+[RATNG45]
+Vollstrecker
-[F_WASTE]
-Weibliche Passanten
+[RATNG46]
+Leutnant
-[PIG_WST]
-Cops
+[RATNG47]
+Vize-Boss
-[GNG_WST]
-Gang-Mitglieder
+[RATNG48]
+Capo
-[MED_WST]
-Sanitäter
+[RATNG49]
+Boss
-[FIRE_WS]
-Feuerwehrmänner
+[RATNG50]
+Oberboss
-[DED_CRI]
-Kriminelle
+[RATNG51]
+Don
-[DED_DED]
-Schnorrer
+[RATNG52]
+King of the City
-[DED_HOK]
-Girls
+[PAGE_00]
+..
-[HEL_DST]
-Zerstörte Helikopter
+[WELCOME]
+WILLKOMMEN IN
-[PER_COM]
-Absolviert (in Prozent)
+[TSCORE]
+EINKÜNFTE: $~1~
-[KGS_EXP]
-Sprengstoffverbrauch in kg
+[PBOAT_2] { reVC update }
+Drücke die ~h~~k~~VEHICLE_FIREWEAPON~~w~, um die Bordkanonen abzufeuern.
-[ACCURA]
-Treffsicherheit
+[HJSTAT]
+Distanz: ~1~.~1~m Höhe: ~1~.~1~m Saltos: ~1~ Drehungen: ~1~_
-[ELBURRO]
-Beste Turismo-Zeit in Sekunden
+[HJSTATW]
+Distanz: ~1~.~1~m Höhe: ~1~.~1~m Saltos: ~1~ Drehungen: ~1~_ Und was für eine Landung!
-[CAR_CRU]
-Geschrottete Autos
+[ATUTOR]
+Drücke die ~h~~k~~TOGGLE_SUBMISSIONS~~w~, um Krankenwagen-Missionen an- oder abzuschalten.
-[HED_EX]
-Köpfe
+[FEST_HA]
+Höchster Krankenwagen-Missions-Level
-[TM_DED]
-Krankenhausbesuche
+[C_KILLS]
+KRIMINELLE: ~1~
-[DAYSPS]
-Im Spiel verstrichene Tage
+[HJSTATF]
+Distanz: ~1~Fuß Höhe: ~1~Fuß Saltos: ~1~ Drehungen: ~1~_
-[MMRAIN]
-Regenfälle in mm
+[HJSTAWF]
+Distanz: ~1~Fuß Höhe: ~1~Fuß Saltos: ~1~ Drehungen: ~1~_ Und was für eine Landung!
-[MXCARD]
-Weitester IRRSINNS-Sprung (in Fuß)
+[CRED001]
+ROCKSTAR NORTH
-[MXCARJ]
-Höchster IRRSINNS-Sprung (in Fuß)
+[CRD001A]
+STUDIO DIRECTOR
-[MXCARDM]
-Weitester IRRSINNS-Sprung (m)
+[CRD001B]
+ANDREW SEMPLE
-[MXCARJM]
-Höchster IRRSINNS-Sprung (m)
+[CRED002]
+PRODUCER
-[MXFLIP]
-Max. Anzahl Saltos
+[CRD002A]
+DEVELOPMENT DIRECTOR
-[MXJUMP]
-Max. Drehungen im Sprung
+[CRED003]
+LESLIE BENZIES
-[BSTSTU]
-Bester IRRSINNS-Stunt bisher:
+[CRED004]
+ART DIRECTOR
-[INSTUN]
-Irrsinns-Stunt
+[CRED005]
+AARON GARBUT
-[PRINST]
-Super Irrsinns-Stunt
+[CRED006]
+TECHNICAL DIRECTORS
-[DBINST]
-Doppelter Irrsinns-Stunt
+[CRED007]
+OBBE VERMEIJ
-[DBPINS]
-Super-Doppel-Irrsinns-Stunt
+[CRED008]
+ADAM FOWLER
-[TRINST]
-Dreifacher Irrsinns-Stunt
+[CRED010]
+ANDREW DUTHIE
-[PRTRST]
-Super-Dreifach-Irrsinns-Stunt
+[CRED011]
+CRAIG FILSHIE
-[QUINST]
-Vierfacher Irrsinns-Stunt
+[CRED012]
+WILLIAM MILLS
-[PQUINS]
-Super-Vierfach-Irrsinns-Stunt
+[CRED013]
+CHRIS ROTHWELL
-[NOSTUC]
-Bisher keine Stunts geschafft
+[CRD013A]
+IMRAN SARWAR
-[NOUNIF]
-Monster-Stunts geschafft
+[CRD013B]
+JAMES WORRALL
-[NOUNGM]
-Monster-Stunts insgesamt
+[CRD013C]
+JOHN HAIME
-[NMISON]
-Begonnene Missionen
+[CRED014]
+WRITTEN BY
-[NMMISP]
-Erfüllte Missionen
+[CRED015]
+JAMES WORRALL
-[PASDRO]
-Beförderte Fahrgäste
+[CRED016]
+PAUL KUROWSKI
-[MONTAX]
-Mit Taxi verdientes Geld
+[CRED017]
+DAN HOUSER
-[DAYPLC]
-Tagesetat für Polizei
+[CRED018]
+LEAD CHARACTER DESIGNER
-[CRIMRA]
-Punktzahl:
+[CRD018A]
+CHARACTER DESIGNER
-[GMSTOR]
-Spielarchiv
+[CRED019]
+IAN MCQUE
-[PREBRF]
-Vorherige Missionsinfos
+[CRD019A]
+TOKS SOLARIN
-[CNTLS]
-Steuerung
+[CRD019B]
+ALAN DAVIDSON
-[MUSMEN]
-Musik SFX
+[CRED020]
+LEAD ANIMATOR
-[GAMSET]
-Spieleinstellungen
+[CRED021]
+ALEX HORTON
-[LANGUA]
-Sprache
+[CRD022A]
+ANIMATORS
-[DSPLAY]
-Anzeige
+[CRED022]
+LEE MONTGOMERY
-[DEBUGM]
-Debug Menu
+[CRD022B]
+DUNCAN SHIELDS
-[QUITOP]
-Optionen verlassen
+[CRD022C]
+GUS BRAID
-[CONTRL]
-Konfiguration d. Steuerung
+[CRED023]
+VEHICLE DESIGNERS
-[SET1EN]
-Konfiguration 1 aktiviert
+[CRD023A]
+JOLYON ORME
-[SET1]
-Konfiguration 1
+[CRD023B]
+ALAN DUNCAN
-[SET2EN]
-Konfiguration 2 aktiviert
+[CRD024A]
+LEAD VEHICLE DESIGNER
-[SET2]
-Konfiguration 2
+[CRED024]
+PAUL KUROWSKI
-[SET3EN]
-Konfiguration 3 aktiviert
+[CRED025]
+MAP DESIGNERS
-[SET3]
-Konfiguration 3
+[CRED026]
+ADAM COCHRANE
-[SET4EN]
-Konfiguration 4 aktiviert
+[CRED027]
+NIK TAYLOR
-[SET4]
-Konfiguration 4
+[CRED028]
+GARY MCADAM
-[GOBACK]
-Zurück
+[CRED029]
+KEIRAN BAILLIE
-[SOUND]
-SOUND
+[CRED030]
+ALISDAIR WOOD
-[MUSVOL]
-Lautstärke Musik
+[CRED031]
+ANDREW SOOSAY
-[SFXVOL]
-Lautstärke SFX
+[CRD031A]
+STEVEN MULHOLLAND
-[SCROPT]
-BILDSCHIRMOPTIONEN
+[CRD031B]
+WAYLAND STANDING
-[CTRSCR]
-Bildschirm zentrieren
+[CRD031C]
+CAMPBELL J. DICK
-[SCRFOR]
-Bildschirmformat
+[CRD031D]
+GRAPHIC DESIGNER
-[GMSVLQ]
-SPEICHERN-LADEN-BEENDEN
+[CRD031E]
+STUART PETRI
-[GMREST]
-Spiel neu starten
+[CRED032]
+LEAD PROGRAMMER
-[NOGMSV]
-Du kannst nur in deinem Unterschlupf speichern.
+[CRD032A]
+PROGRAMMERS
-[DLFILE]
-GTA3 Dateien löschen
+[CRED033]
+ALEXANDER ROGER
-[CHFILE]
-ZU LADENDE DATEI AUSWÄHLEN
+[CRED034]
+GRAEME WILLIAMSON
-[CHCDLD]
-Wähle Memory Card (PS2) von der geladen werden soll
+[CRED035]
+BARANE CHAN
-[CDUNFR]
-Memory Card (PS2) ist nicht formatiert.
+[CRED036]
+DEREK PAYNE
-[CHFIDL]
-ZU LÖSCHENDE DATEI AUSWÄHLEN
+[CRED037]
+GORDON YEOMAN
-[SVCONF]
-SPEICHERBESTÄTIGUNG
+[CRD037A]
+ALAN CAMPBELL
-[SVFNAM]
-Dateiname des gespeicherten Spiels:
+[CRD037B]
+MARK HANLON
-[SAVEDN]
-Fehler - Speicherung nicht vollständig.
+[CRD037C]
+ANDRZEJ MADAJCZYK
-[LANGSL]
-SPRACHAUSWAHL
+[CRED038]
+LEAD MUSIC PRODUCER
-[ENGLIS]
-Englisch
+[CRED039]
+CRAIG CONNER
-[GERMAN]
-Deutsch
+[CRED040]
+STUART ROSS
-[ITALIA]
-Italienisch
+[CRED041]
+LEAD AUDIO ENGINEER
-[FRENCH]
-Französisch
+[CRED042]
+ALLAN WALKER
-[SPAIN]
-Spanisch
+[CRD041A]
+AUDIO ENGINEER
-[RELIDE]
-ReLoadIde
+[CRD041B]
+AUDIO
-[RELIPE]
-ReLoadIpl
+[CRD042A]
+WILL MORTON
-[PARSHP]
-Parse Heap
+[CRED043]
+AUDIO PROGRAMMER
-[DBGFON]
-CTheScripts::DbgFlag On
+[CRED044]
+RAYMOND USHER
-[DBFOFF]
-CTheScripts::DbgFlag Off
+[CRED045]
+TEST MANAGER
-[BGWHON]
-Big White Debug Light Switched On
+[CRED046]
+CRAIG ARBUTHNOTT
-[BGWOFF]
-Big White Debug Light Switched Off
+[CRED047]
+LEAD QA
-[DSTRON]
-Debug Streaming Requests On
+[CRED048]
+NEIL CORBETT
-[DSTROFF]
-Debug Streaming Requests Off
+[CRED049]
+KEVIN WONG
-[PDRGON]
-ShowPedRoadGroups On
+[CRED050]
+QA
-[PRGOFF]
-ShowPedRoadGroups Off
+[CRED051]
+DAVID BEDDOES
-[CRRGON]
-ShowCarRoadGroups On
+[CRED052]
+DAVID WATSON
-[CRGOFF]
-ShowCarRoadGroups Off
+[CRED053]
+BARRY CLARK
-[CLZOON]
-Show Cull Zones On
+[CRED054]
+ROSS SPARROW
-[CLZOOF]
-Show Cull Zones Off
+[CRED055]
+JAMES ALLAN
-[SHPLON]
-gbShowCollisionPolys On
+[CRED056]
+NEIL MEIKLE
-[SHPLOF]
-gbShowCollisionPolys Off
+[CRD056A]
+GEORGE WILLIAMSON
-[CULREC]
-CCullZones::RecalculateCullZoneData()
+[CRD056B]
+MATT JONES
-[FORMM1]
-FormatMemCard 1 (teststuff)
+[CRD056C]
+ROB HARBOUR
-[UNFRM1]
-UnFormatMemCard 1 (teststuff)
+[CRD056D]
+TOM WHITTAKER
-[GORLEV]
-Gewalt-Level
+[CRED057]
+LEAD TECHNICAL SUPPORT
-[SICASS]
-Mittel
+[CRED058]
+LORRAINE ROY
-[SICSIC]
-Hoch
+[CRD057A]
+TECHNICAL SUPPORT
-[SCASSL]
-Gewalt-Level 'mittel' gewählt
+[CRED059]
+CHRISTINE CHALMERS
-[SCSCSL]
-Gewalt-Level 'hoch' gewählt
+[CRD060A]
+OFFICE SUPPORT
-[PRVMEN]
-Vorherige Missionsinfos
+[CRD060B]
+KIM GURNEY
-[DOSVGM]
-Spiel speichern?
+[CRD060C]
+CASSIE OLIVER
-[FORMEN]
-Formatierungsmenü
+[CRED060]
+ROCKSTAR NEW YORK
-[MEMTST]
-Memory Card-Testmenü
+[CRED061]
+EXECUTIVE PRODUCER
-[REGCAR]
-Memory Card 1 registrieren
+[CRED062]
+SAM HOUSER
-[TEFONE]
-Memory Card 1 testweise formatieren
+[CRED063]
+PRODUCER
-[TEUFON]
-Memory Card 1 testweise de-formatieren
+[CRED064]
+DAN HOUSER
-[CRROOT]
-CreateRootDir
+[CRED065]
+VP OF DEVELOPMENT
-[CRLDIC]
-Create and Load Icons
+[CRED066]
+JAMIE KING
-[FLFSGF]
-Fill First File With Guff
+[CRED067]
+CHIEF TECHNOLOGY OFFICER
-[PUSAVE]
-Save Only the game
+[CRED068]
+GARY J. FOREMAN
-[CHEVOK]
-CheckEveryOkB4Save
+[CRED069]
+ASSOCIATE PRODUCER
-[SVGMON]
-SaveTheGame
+[CRED070]
+JEREMY POPE
-[CNTSAV]
-Spiel kann nicht gespeichert werden. Mitten in Mission.
+[CRD071A]
+DIRECTOR OF QUALITY ASSURANCE
-[CNCSAV]
-Spiel kann nicht gespeichert werden. Du bist im Auto.
+[CRD072A]
+JEFF ROSA
-[CRMGSV]
-Create copy protected magazine directory
+[CRED071]
+MUSIC SUPERVISOR
-[MGSVCN]
-MagazineDirectory Created
+[CRED072]
+TERRY DONOVAN
-[MGSVNC]
-MagazineDirectory Not Created
+[CRED073]
+PRODUCTION TEAM
-[YES]
-Ja
+[CRED074]
+TERRY DONOVAN
-[NO]
-Nein
+[CRED075]
+JENNIFER KOLBE
-[X]
-x
+[CRED076]
+JENEFER GROSS
-[LAST]
-Letzte Nachricht
+[CRED077]
+LAURA PATERSON
-[FEDS_XB]
-Auswählen
+[CRED078]
+JEFF CASTANEDA
-[FEDS_ST]
-START-Taste - WEITER
+[CRED079]
+JERONIMO BARRERA
-[FEST_OO]
-von
+[CRED080]
+CARLY SLATER
-[FEC_TUC]
-Geschützsteuerung
+[CRED081]
+JUNG KWAK
-[FEC_SM3]
-Spezialmission aktivieren (R3-Taste)
+[CRED082]
+BRIAN WOOD
-[FEC_RS3]
-Radiosender auswählen (L3-Taste)
+[CRED083]
+RENAUD SEBANNE
-[FEC_HO3]
-Hupe (L3-Taste)
+[CRED084]
+RICHARD KRUGER
-[DIAB1]
-'GRAN TURISMO'
+[CRD084A]
+DANIEL EINZIG
-[DIAB2]
-'BRANDHEISSE EISCREME'
+[CRD084B]
+JACEN BURROWS
-[DIAB3]
-'FEUERTAUFE'
+[CRD084C]
+LINN PR
-[DIAB4]
-'JÄGER DES VERLORENEN SCHUNDES'
+[CRD084D]
+COVER ART
-[DIAB1_A]
-El Burro bietet dir eine Chance. Über den öffentlichen Fernsprecher in Hepburn Heights erfährst du näheres.
+[CRD084E]
+STEPHEN BLISS
-[DIAB1_C]
-Du bist kein übler Fahrer. Komm wieder zu dem Telefon. Vielleicht hat El Burro noch mehr Jobs für dich.
+[CRED085]
+KENT PAUL'S 80 NOSTALGIA ZONE
-[DIAB1_1]
-~g~3...2...1... LOS. LOS, LOS!
+[CRED086]
+WRITTEN BY DAN HOUSER
-[DIAB1_4]
-~g~Schnapp dir einen schnellen Wagen und fahr zum Start.
+[CRD086A]
+PRODUCED BY ADAM TEDMAN
-[DIAB1_3]
-~r~Du würdest nicht mal beim Sackhüpfen gewinnen, du LOSER!
+[CRED087]
+WWW.KENTPAUL.COM AND WWW.VICECITY.COM
-[DIAB1_2]
-~g~Gratulation! Du hast gesiegt. In der unglaublichen Zeit von ~1~ Sekunden.
+[CRED088]
+CREATED BY
-[FIRST]
-~g~1.
+[CRD088A]
+ADAM TEDMAN
-[SECOND]
-~g~2.
+[CRD088B]
+DAVID YU
-[THIRD]
-~g~3.
+[CRD088C]
+JERRY LUNA
-[FOURTH]
-~g~4.
+[CRD088D]
+STUART PETRI
-[DIAB2_1]
-~g~Hol die Aktentasche in Harwood ab.
+[CRD088E]
+MICHAEL CARNEVALE
-[DIAB2_2]
-~g~Such dir einen Eis-Wagen.
+[CRD088F]
+GREG LAU
-[DIAB2_3]
-~g~Parke den Eis-Wagen unten bei den Atlantic Quays.
+[CRD088G]
+FUTABA HAYASHI
-[DIAB2_4]
-~g~Drücke die ~w~~k~~VEHICLE_HORN~-Taste~g~, um den Eiscreme-Jingle abzuspielen.
+[CRED089]
+QA MANAGER
-[DIAB2_6]
-~g~Drücke die ~w~~k~~VEHICLE_HORN~-Taste~g~, um den Eiscreme-Jingle abzuspielen.
+[CRED090]
+CRAIG ARBUTHNOTT
-[DIAB2_7]
-~g~Drücke die ~w~~k~~VEHICLE_HORN~-Taste~g~, um den Eiscreme-Jingle abzuspielen.
+[CRED091]
+LEAD ANALYST
-[DIAB2_5]
-~g~Steig aus und sprenge den Eis-Wagen mit dem Fernzünder.
+[CRED092]
+ADAM DAVIDSON
-[YD1]
-'SCHNELLE AUTOS, SCHNELLES GELD'
+[CRD092A]
+JOE HOWELL
-[YD2]
-'UZI RIDER'
+[CRD092B]
+MARC FERNANDEZ
-[YD3]
-'DER GROSSE AUTOKLAU'
+[CRED093]
+GAME ANALYST
-[YD4]
-'TAG DER RACHE'
+[CRED094]
+RICHARD HUIE
-[YD_P]
-King Courtney will dich sprechen - am Telefon in Aspatria!!
+[CRED095]
+ROCKSTAR TEST TEAM
-[YD1_A]
-~w~Hier spricht King Courtney.
+[CRED096]
+LANCE WILLIAMS
-[YD1_A1]
-~w~Meine Yardies könnten einen Fahrer brauchen, und du hast keinen schlechten Ruf.
+[CRED097]
+JOE GREENE
-[YD1_B]
-~w~Fahr mit einem Wagen zu dem Gelände gegenüber dem Stadion und warte auf die anderen Mitbewerber.
+[CRED098]
+BRIAN PLANER
-[YD1_C]
-~w~Meine Männer beobachten Checkpoints überall in Staunton.
+[CRD098A]
+ELIZABETH SATTERWHITE
-[YD1_D]
-~w~Wer einen Checkpoint als erster erreicht, kriegt $1000. Dann geht's weiter zur nächsten Station.
+[CRD098B]
+JAMEEL VEGA
-[YD1_D1]
-~w~Wenn du mehr Checkpoints als die anderen gewinnst, habe ich vielleicht Arbeit für dich.
+[CRD098C]
+MIKE HONG
-[YD1_E]
-~g~Fertigmachen zum Start!
+[CRED099]
+LEE CUMMINGS
-[YD1_F]
-~g~Du bist zu früh gestartet. Das gefällt mir!!
+[CRED100]
+STORY
-[YD1_G]
-~r~Dies ist ein AUTORENNEN. Du brauchst ein AUTO, Hirni!
+[CRED101]
+JAMES WORRALL
-[YD1GO]
-~g~LOS!!
+[CRED102]
+DAN HOUSER
-[YD1_1]
-~r~1
+[CRED103]
+ADAM TEDMAN
-[YD1_2]
-~r~2
+[CRED104]
+PAUL YEATES
-[YD1_3]
-~r~3
+[CRED105]
+JENEFER GROSS
-[YD1_BON]
-$1000!!
+[CRED106]
+LAURA PATERSON
-[Y1_1ST]
-~g~Du bist Erster mit ~1~ gewonnenen Checkpoints!
+[CRED107]
+CUT SCENES
-[Y1_2ND]
-~y~Zweiter mit ~1~ gewonnenen Checkpoints. ~y~Tja, knapp daneben ist auch versagt!
+[CRED108]
+WRITTEN BY DAN HOUSER AND JAMES WORRALL
-[Y1_3RD]
-~r~Dritter mit ~1~ gewonnenen Checkpoints. ~r~Findest du das okay?
+[CRED109]
+AUDIO DIRECTED BY DAN HOUSER AND NAVID KHONSARI
-[Y1_LAST]
-~r~Du bist Letzter! ~r~Du vergeudest meine Zeit, BLÖDMANN!
+[CRED110]
+PRODUCED BY JAMIE KING
-[Y1_J1ST]
-~y~Du teilst dir den 1. Platz. ~1~ gewonnene Checkpoints. ~y~Gut, aber du musst der Beste sein, um für Queen Lizzy zu fahren!
+[CRD110A]
+TALENT PROCUREMENT: JAMIE KING, SEAN MACALUSO
-[Y1_J2ND]
-~r~Du teilst dir den 2. Platz. ~1~ gewonnene Checkpoints. Du Schläfer!
+[CRED111]
+CAST
-[Y1JLAST]
-~r~Du bist unter den Letzten! Wo hast du deinen Führerschein gemacht?
+[CRD111A]
+SUPPORTING CHARACTERS
-[Y1_TEST]
-AUTO IM WASSER!!
+[CRED112]
+TOMMY VERCETTI - RAY LIOTTA
-[YD2_A]
-~w~Ich will sehen, ob du die Drecksjobs für mich machen kannst.
+[CRED113]
+KEN ROSENBERG - WILLIAN FICHTNER
-[YD2_A1]
-Mal sehen, ob man dir trauen kann.
+[CRED114]
+SONNY FORELLI - TOM SIZEMORE
-[YD2_B]
-Gleich kommen zwei meiner Jungs und holen dich ab.
+[CRED115]
+STEVE SCOTT - DENNIS HOPPER
-[YD2_B1]
-Wollen sehen, ob du so gut bist, wie du sagst.
+[CRED116]
+AVERY CARRINGTON - BURT REYNOLDS
-[YD2_C]
-~w~Wir fahren nach Hepburn Heights und nehmen uns ein paar Diablos vor, die Queen Lizzy angemacht haben.
+[CRED117]
+RICARDO DIAZ - LUIS GUZMAN
-[YD2_CC]
-~w~Hier, du wirst 'ne Knarre brauchen.
+[CRED118]
+LANCE VANCE - PHILIP MICHAEL THOMAS
-[YD2_D]
-~w~Du fährst UND ballerst. Wir achten drauf, dass du keine kalten Füße kriegst.
+[CRED119]
+COLONEL JUAN CORTEZ - ROBERT DAVI
-[YD2_E]
-~w~Los geht's!!
+[CRED120]
+UMBERTO ROBINA - DANNY TREJO
-[YD2_F]
-~r~Er haut ab! Schnapp dir den Feigling!!!
+[CRED121]
+PHIL CASSIDY - GARY BUSEY
-[YD2_G1]
-~w~Hepburn Heights. Knöpf dir ein paar Diablos vor.
+[CRED122]
+MITCH BAKER - LEE MAJORS
-[YD2_G2]
-~w~Aber denk dran, ~r~du steigst nicht aus dem Wagen!!
+[CRED123]
+MERCEDES CORTEZ - FAIRUZA BALK
-[YD2_H]
-~w~Okay, fahr uns zurück auf Yardie-Gebiet! LOS, LOS, LOS!!
+[CRED124]
+KENT PAUL - DANNY DYER
-[YD2_L]
-~w~Gut gemacht, Sichler!
+[CRED125]
+JEZZ TORRENT - KEVIN MCKIDD
-[YD2_M]
-~r~Er hat mein Auto geschrottet! Mach ihn fertig!
+[CRED126]
+TAXI CONTROLLER - DEBORAH HARRY
-[YD2_N]
-~w~Steig sofort wieder in den Wagen!
+[CRED127]
+CANDY SUXX - JENNA JAMESON
-[YD3_A]
-Besorg ein paar Bandenautos,
+[CRED128]
+BJ SMITH - LAWRENCE TAYLOR
-[YD3_A1]
-damit wir auf Feindgebiet operieren können.
+[CRED129]
+AUNTIE POULET - YOUREE CLEOMILI HARRIS
-[YD3_B]
-Ich brauche einen Mafia Sentinel,
+[CRED130]
+SUPPLIER - ARMANDO RIESCO
-[YD3_B1]
-einen Yakuza Stinger und einen
+[CRED131]
+COUGAR - BLAYNE PERRY
-[YD3_B2]
-Diablo Stallion. So können wir jede Gang in Liberty angreifen.
+[CRED132]
+HILARY - CHARLES TUCKER
-[YD3_C]
-Stell sie in der Garage in Newport ab. Aber denk dran: ,
+[CRED133]
+CONGRESSMAN ALEX SHRUB - CHRIS LUCAS
-[YD3_C1]
-Geschrottet nützen sie uns nichts!!
+[CRED134]
+OLD MAN KELLY - GEORGE DICENZO
-[YD3_D]
-Spare text label
+[CRD134A]
+CAM JONES - GREG SIMS
-[YD3_E]
-~r~Du hast bereits einen Diablo-Wagen!
+[CRD134B]
+PSYCHO - HUNTER PLATIN
-[YD3_F]
-~r~Du hast bereits einen Mafia-Wagen!
+[CRD134C]
+MAUDE THE ICE CREAM LADY - JANE GENNARO
-[YD3_G]
-~r~Du hast bereits einen Yakuza-Wagen!
+[CRD134D]
+JETHRO - JOHN ZURHELLEN
-[YD3_H]
-~g~Diablo-Wagen besorgt!
+[CRD134E]
+GONZALES - JORGE PUPO
-[YD3_I]
-~g~Mafia-Wagen besorgt!
+[CRD134F]
+DWAYNE - NAVID KHONSARI
-[YD3_J]
-~g~Yakuza-Wagen besorgt!
+[CRD134G]
+DICK - PETER MCKAY
-[YD3_K]
-~r~Das Auto ist praktisch Schrott! Repariere es!
+[CRD134H]
+MIKE THE GOON & PORN GUY - ROBERT CIHRA
-[YD3_L]
-~g~Fahr das Auto zu der ~p~Garage!
+[CRD134I]
+PERCY - RUSSELL FOREMAN
-[YD3_M]
-~r~Du hast dich überschlagen! Besorg ein anderes Auto!
+[CRED135]
+MOTION CAPTURE
-[YD4_A]
-Hör zu!
+[CRED136]
+ANIMATED BY
-[YD4_A1]
-Komm nach Bedford Point.
+[CRD136A]
+TECHNICAL DIRECTION BY ALEX HORTON
-[YD4_A2]
-In einem alten Wagen ist etwas versteckt. Das brauche ich pronto!
+[CRED137]
+DIRECTED BY
-[YD4_B]
-BRIEF: Man hört, du bist ein viel beschäftigter Mann. Nun, ich bin eine viel beschäftigte Frau.
+[CRD137A]
+DIRECTED BY NAVID KHONSARI
-[YD4_C]
-Es wird Zeit, dass du die wahre Macht von 'SPANK' kennen lernst! Besos y fuderes, Catalina, xxx.
+[CRED138]
+PRODUCED BY
-[YD4_D]
-PS: FAHR ZUR HÖLLE!!
+[CRD138A]
+PRODUCED BY JAMIE KING
-[YD4_1]
-Irre auf SPANK!!
+[CRD138B]
+RENAUD SEBBANE
-[YD4_2]
-~g~Zerstöre die SPANK-Lieferwagen!!
+[CRED139]
+RECORDED AT PERSPECTIVE STUDIOS, BROOKLYN
-[HM_1]
-'DRIVE-BY ACTION'
+[CRED140]
+MOTION CAPTURE ACTORS
-[HM_2]
-'TÖDLICHES SPIELZEUG'
+[CRD140A]
+BLAYNE PERRY
-[HM_3]
-'DAS HÖLLENFAHRTSKOMMANDO'
+[CRD140B]
+JONATHON SALE
-[HM_5]
-'SHOWDOWN'
+[CRD140C]
+CHARLES TUCKER
-[HOOD1_A]
-Komm zu dem Fernsprecher in Wichita Gardens. Es gibt Arbeit.
+[CRD140D]
+EDDIE MARRERO
-[HM1_A]
-Yo! Hier spricht D-Ice von den Red Jacks!
+[CRD140E]
+WILLIAM MCCALL
-[HM1_C]
-Diese pubertären Idioten treiben sich hier rum und haben nichts als Knarren und SPANK im Sinn.
+[CRD140F]
+JORGE PUPO
-[HM1_3]
-~g~Die 'Nines' hängen in ihrem Gebiet in Wichita Gardens rum.
+[CRD140G]
+ROBERT JACKSON
-[HM2_3]
-Wenn du die Reifen eines Wagens triffst, explodiert der Buggy!
+[CRD140H]
+TARA RADCLIFFE
-[HM2_4]
-Wenn er außer Reichweite kommt, explodiert der Buggy!
+[CRD140I]
+JENIFER GAMBETESE
-[HM2_5]
-~r~Außer Reichweite!
+[CRD140J]
+KRIS ACHEVARRIA
-[HM3_1]
-~g~Fahr zur Garage. Aber Vorsicht: Wird der Wagen zu stark beschädigt, explodiert er!
+[CRD140K]
+ALI ORDOUBADI
-[HM3_2]
-~g~Bring den Wagen zurück. Er muss in 1A Zustand sein. Keine Delle!
+[CRD140L]
+KAHLEEM POOLE
-[HM3_3]
-~g~Repariere den Wagen!
+[CRED141]
+PEDESTRIAN DIALOGUE
-[HM4_D]
-~g~Besorg dir ein Fahrzeug!
+[CRD141A]
+WRITTEN BY DAN HOUSER, MARC FERNANDEZ, GILLIAN TELLING AND NAVID KHONSARI
-[HM4_E]
-TEXT NO LONGER REQUIRED
+[CRD141B]
+WITH HELP FROM JEREMY POPE, LANCE WILLIAMS, AND JENNY JEMISON
-[HM4_1]
-~g~Begib dich an den Ort, wo die Ladung herumliegt. Du musst 30 Goldbarren einsammeln.
+[CRED142]
+WRITTEN BY
-[HM4_2]
-~g~Denk dran: Wird der Wagen zu schwer und zu langsam, fahr in die Garage und lade das Zeug aus.
+[CRD142A]
+DAN HOUSER AND JAMES WORRALL
-[HM5_3]
-~r~Du solltest nur einen Baseball-Schläger verwenden!
+[CRED143]
+DIRECTED BY DAN HOUSER, CRAIG CONNER, MARC FERNANDEZ, AND ALLAN WALKER
-[HM5_4]
-~r~Deine Kontaktperson ist tot!
+[CRED144]
+PRODUCED BY RENAUD SEBANNE
-[MEA1]
-'DER ABKOCHER'
+[CRED145]
+PEDESTRIANS
-[MEA2]
-'DIE DIEBE'
+[CRED146]
+ADAM DAVIDSON, ADAM WATKINS, ALEJANDRO K. BROWN, ALEX ANTHONY SIOUKAS, ALEX GARCIA,
-[MEA3]
-'DIE FRAU'
+[CRED147]
+ALICE SALTZMAN, ALISON CIHRA, AMY SALIMA, AMY SALZMAN, ANDREA VIDELA, ANTHONY ATTI,
-[MEA4]
-'IHR LIEBHABER'
+[CRED148]
+ANTHONY RIVERA, BIJAN SHAMS, BLAYNE PERRY, BRETT BISOGNO, BREYE MATA, BRIAN PANEN,
-[MEAT1_A]
-Man sagt, du kannst mir bei einigen Problemen helfen. Wenn das so ist, komm zu dem Fernsprecher in Trenton.
+[CRED149]
+BROCK VODER, CAREY BERTINI, CHARISSE LAMBERT, CHRIS DIFAT, CHRIS REISENBERGER,
-[MEA1_B3]
-~g~Triff dich mit dem Bankier.
+[CRED150]
+CHRISTOPHER BRODAY, CHRISTOPHER CARRO, CYNTHIA GREENE, DAMARIES LOPEZ, DAN LEE,
-[MEA1_B6]
-~g~Fahr das Auto zur Schrottpresse, um Beweise zu beseitigen. Steig aus, der Kran hebt das Auto rein.
+[CRED151]
+DAN SCHNEIDER, DAN TOYAMA, DAVID DEAN CHALTFIELD, JR., DAVID HARRISON, DAVID WILEY,
-[MEA1_1]
-~r~Der Bankier ist tot!
+[CRED152]
+DEBORAH COLLINS, DEBRANDA CHANEY-GILES, DEMETRA KOUKOULAS, DENISE ROSADO,
-[MEA1_2]
-~r~Du solltest den Wagen doch verschrotten!
+[CRED153]
+DEVIN BENNETT, DEVIN WINTERBOTTOM, DORIS WOO, DOUGLAS HARRISON, DUNCAN COUTTS,
-[MEA1_3]
-~g~Steig aus dem Wagen!
+[CRED154]
+DUPE AJAYI, EDWIN AVELLANEDA, ELIZABETH HOWELL, ELIZABETH SATTERWHITE, ERIC NAGLE,
-[MEA1_4]
-~r~Du hast den Bankier nicht mitgenommen!
+[CRED155]
+ESTEBAN KARPLUS, F. FONT, FUTABA HAYASHI, GENE HILGREEN, GERALD COSGROVE,
-[MEA2_B3]
-~g~Triff dich mit den Dieben.
+[CRED156]
+GERARD LUNA, GILLIAN TELLING, GREGG CARLUCCI, GREGORY CLERVOIX, GREGORY SCHWEIZER,
-[MEA2_B4]
-~g~Bring sie zur Bitchin' Dog Food Fleischfabrik.
+[CRED157]
+HADLEY TOMICKI, J. ROSSETT, JAMEEL VEGA, JASON JONES, JEFF ROSA, JENNIFER JEMISON,
-[MEA2_B6]
-~g~Spritz den Wagen um, um Beweise zu beseitigen.
+[CRED158]
+JEREMY TAGGERT, JESSICA RIDER, JOSEPH GREENE,JOSEPH HOWELL, KATE DUKICH,
-[MEA2_1]
-~r~Du solltest den Wagen doch verschrotten!
+[CRED159]
+KEL O'NEILL, KEVIN HOPKINS, LADAWN JAMES, LANCE WILLIAMS, LAURA BUBBLES,
-[MEA2_2]
-~r~Ein Dieb ist tot!
+[CRED160]
+LAURA PATTERSON, LEE CUMMINGS, LETICIA L. YOUNG, LINDSAY KENNEDY, LISA ORITZ,
-[MEA2_4]
-~r~Du hast einen Dieb nicht mitgenommen!
+[CRED161]
+LORNA JORDAN, LUCIO AMADIO, MARCO FERNANDEZ, MARIKO TANAKA, MARLON MATTHEWS,
-[MEA3_B3]
-~g~Hole Mrs. Chonks ab.
+[CRED162]
+MARY TELLING, MASAYOSHI MITSUYAMA, MATTHEW CHUNG, MAX ALLSTADT, MAX BOGDANOV,
-[MEA3_B6]
-~g~Versenke den Wagen im Meer, um Beweismaterial zu beseitigen.
+[CRED163]
+MELISSA ALVAREZ, MICHAEL MAY, MICHAEL ROTHSTEIN, MIGUEL VIDAL, MIKE FEDERLINE,
-[MEA3_1]
-~r~Die Frau ist tot!
+[CRED164]
+NATALIE DESCALZO, N'GAI MEMBERS, NICOLAS MALLO, NOELLE SADLER, NORBERT MORIVAN,
-[MEA3_2]
-~r~Du solltest den Wagen doch im Meer versenken!
+[CRED165]
+OSWALD GREENE, JR., PETER MCKAY, PETER APPEL, PRESTON SAVARESE, RAFAEL GONZALES,
-[MEA3_3]
-~r~Du hast die Frau nicht mitgenommen!
+[CRED166]
+RANDY JOHNSON, REY CONCEPCION, RICHARD KROGER, ROB TIBBS, ROBERT JACKSON,
-[MEA4_B3]
-~g~Hol den Liebhaber seiner Frau ab.
+[CRED167]
+ROBERT SCHULER, ROSS A. MCINTYRE, RUSSELL FOREMAN, RUTH NUNEZ, SALVADORE SUAZO,
-[MEA4_B6]
-Dazu ist es jetzt zu spät, Marty. Du hattest deine Chance. Jetzt übernehme ich den Laden hier.
+[CRED168]
+SAM WHITE, SANTOS GONZALES, SCOTT SMITH, SEYMOUR FRAILMAN, SPELMAN BRAUMAN,
-[MEA4_1]
-~r~Carlos ist tot!
+[CRED169]
+STEPHANIE TELLING, STEVE KNEZEVICH, STEVE ROBERT, SUMIKO YASUDA, SUSAN LEWIS,
-[MEA4_3]
-~r~Du hast Carlos den Kredithai nicht mitgenommen!
+[CRED170]
+SYLVIA COLACIOS, TOMOKO MIYAZAKI, TRON, VERDEL HALE, YVES MONDESIR, ZENO LEINFELDER,
-[LOOK_A]
-Halte die ~h~~k~~VEHICLE_LOOKLEFT~-Taste ~w~oder die ~h~~k~~VEHICLE_LOOKRIGHT~-Taste~w~ gedrückt, um im Wagen sitzend nach ~h~links~w~ oder ~h~rechts~w~ zu sehen. Drücke beide Tasten, um nach ~h~hinten~w~ zu sehen.
+[CRED171]
+DAVID BEDDOES, CHRISTINE CHALMERS, BARRY CLARK, NEIL CORBETT, KIM GURNEY, NEIL MEIKLE,
-[LOVE6_1]
-~g~Locke jetzt die Cops vom Lagerhaus weg!
+[CRED172]
+CASSIE OLIVER, LORRAINE ROY, DAVID WATSON, KEVIN WONG, WILL MORTON
-[LOVE6_2]
-~r~Du hast die Cops nicht weit genug weggelockt!
+[CRED175]
+ADAM DAVIDSON
-[RM4_3]
-~r~Rays Partner ist entkommen!
+[CRED176]
+LANCE WILLIAMS
-[RM6_C]
-Die CIA scheint sich sehr für SPANK zu interessieren.
+[CRED177]
+NEIL MCCAFFREY
-[RM6_C1]
-Sie wollen, dass wir das Kartell in Ruhe lassen.
+[CRED178]
+LAURA PATERSON
-[C_PASS]
-BEDROHUNG AUSGERÄUMT!
+[CRED179]
+REY CONCEPCION
-[CTUTOR]
-Drücke die ~h~~k~~TOGGLE_SUBMISSIONS~-Taste~w~, um Bürgerwehr Missionen zu aktivieren oder zu deaktivieren.
+[CRED180]
+CHARLES HEROLD
-[CTUTOR2]
-Drücke die ~h~~k~~TOGGLE_SUBMISSIONS~-Taste~w~, um Bürgerwehr Missionen zu aktivieren oder zu deaktivieren.
+[CRED181]
+ANDREW GREENWALD
-[COPCART]
-~g~Du hast ~1~ Sekunden, um zu einem Polizeiwagen zurückzukehren, bevor die Mission endet.
+[CRED182]
+JAMES MIELKE
-[C_FAIL]
-Mission beendet!
+[CRED183]
+PETER SUCIU
-[C_CANC]
-~r~Bürgerwehr Mission abgebrochen!
+[CRED184]
+ALEX ODULIO
-[C_ESCP]
-~r~Der Verdächtige ist entwischt!
+[CRED185]
+DON NKRUMAH
-[C_TIME]
-~r~Deine Zeit als Gesetzeshüter ist vorbei!
+[CRED186]
+KENDALL PITTMAN
-[C_VIGIL]
-BÜRGERWEHR BONUS!!
+[CRED187]
+SAL SUAZO
-[A_FAIL2]
-~r~Deine Bummelei war tödlich für den Patienten!
+[CRED188]
+EREK MATEO
-[A_FAIL3]
-~r~Der Patient ist tot!!
+[CRED189]
+CHRIS DIFATE
-[A_PASS]
-Gerettet!
+[CRED190]
+LEILA MILTON
-[F_FAIL2]
-~r~Du kommst zu spät!
+[CRED191]
+DARREN ZOLTOWSKI
-[A_COMP2]
-Du ermüdest nie!
+[CRED192]
+VIRGINIA SMITH
-[RM2_M]
-Wenn du eine Waffe brauchst, komm vorbei und nimm dir aus den Kästen, was du brauchst.
+[CRED193]
+KEVIN CASSIN
-[HEAL_A]
-Dein ~h~Gesundheit~w~ wird rechts oben auf dem Bildschirm in Orange angezeigt.
+[CRED194]
+JASON SHIGEMORI
-[YD1_CNT]
-~1~ von 15!
+[CRED195]
+KELLY KINSELLA
-[FM1_9]
-~g~Da vorne ist die Party. Setz Maria vor dem Gebäude ab.
+[CRED196]
+MOLLIE STICKNEY
-[FM1_Y]
-~w~Das war seit langem mal wieder ein guter Abend. Und du hast mich wirklich gut behandelt, mit Respekt und so.
+[CRED197]
+STANTON SARJEANT
-[FM1_AA]
-~w~Oh, ich geh jetzt besser. Ich hoffe, wir sehen uns.
+[CRED198]
+LAURA WALSH
-[NOCONTE]
-Bitte stecken Sie einen Analog Controller (DUALSHOCK#) oder einen Analog Controller (DUALSHOCK#2) in Controller-Anschluss 1, um fortzufahren.
+[CRED199]
+MARK GARONE
-[WRCONT]
-Der Controller an Controller-Anschluss 1 wird nicht unterstützt. GTA3 benötigt einen Analog Controller (DUALSHOCK#) oder einen Analog Controller (DUALSHOCK#2).
+[CRED200]
+JOANNA SLY
-[WRCONTE]
-Der Controller an Controller-Anschluss 1 wird nicht unterstützt. GTA3 benötigt einen Analog Controller (DUALSHOCK#) oder einen Analog Controller (DUALSHOCK#2).
+[CRED201]
+ELIZABETH HOWELL
-[WRONGCD]
-Falsche DVD. Bitte legen Sie die richtige DVD ein.
+[CRED202]
+ANA HERCULES
-[NOCD]
-Die DVD-Lade ist leer. Bitte DVD einlegen.
+[CRED203]
+SHIRLEY IRICK
-[OPENCD]
-Die DVD-Lade ist offen. Bitte schließen.
+[CRED204]
+KASHONA FIELDS
-[CDERROR]
-Fehler beim Lesen der GTA3 DVD.
+[CRED205]
+JOEL M. LILJE
-[RESTART]
-Neues Spiel wird gestartet
+[CRED206]
+JOHN DIBENEDETTO
-[GA_3]
-Keine Gratisjobs mehr. Umspritzen kostet $1000!
+[CRED207]
+NANCY GILES
-[GA_1]
-So was heißes rühre ich nicht an!
+[CRED208]
+RYAN CROY
-[GA_1A]
-Komm wieder, wenn du nicht so viel zu tun hast...
+[CRED209]
+JENNIFER KOLBE
-[S_PROM2]
-In die Garage nebenan kann 1 Fahrzeug eingestellt werden, wenn du das Spiel speicherst.
+[CRED210]
+LIAM BURKE
-[STOCK]
-Nicht vorrätig
+[CRED211]
+SIGRID PREISSL
-[FM1_O]
-~w~Er ist beim Bahnhof am Chinatown-Ufer, glaube ich.
+[CRED212]
+ANITA FITZSIMONS
-[EBAL_B]
-Hier ist es! Los, wir tauchen ab und besorgen uns neue Klamotten!
+[CRED213]
+PHILIPPA RASELLI
-[EBAL_G]
-Hier ist Luigis Club. Wir gehen hinten rum und nehmen den Lieferanteneingang.
+[CRED214]
+WIL QUESNEL
-[AM4_3]
-Du musst Asukas neuer Botenjunge sein!
+[CRED215]
+FALKO BURKERT
-[AM4_4]
-Hast du das Geld? Die ganze Summe?
+[CRED216]
+SARA SEWELL
-[AM4_5]
-Ich weiß, was du denkst. Wieder so ein korrupter Cop.
+[CRED217]
+RADIO STATIONS AND MUSIC
-[AM4_6]
-Tja, die Welt ist schlecht.
+[CRED218]
+MUSIC CONSULTANCY
-[AM4_7]
-Nur weil ich ein paar Partner verloren habe, sitzen mir die Typen von der Dienstaufsicht im Genick.
+[CRD218A]
+HEINZ HENN
-[AM4_8]
-Die glauben, ich habe Dreck am Stecken.
+[CRD218B]
+STUART ROSS
-[AM4_9]
-Tja, die ganze Stadt ist ein einziges Dreckloch.
+[CRED219]
+SOUNDTRACK CO-ORDINATOR
-[AM4_10]
-Aber ich brauch Hilfe von außerhalb der Polizei.
+[CRED220]
+TERRY DONOVAN
-[AM4_11]
-Falls du interessiert bist... du weißt, wo du mich findest.
+[CRED221]
+PRODUCER FOR ROCKSTAR GAMES
-[CAM_A]
-Drücke die ~h~~k~~CAMERA_CHANGE_VIEW_ALL_SITUATIONS~-taste~w~, um den ~h~Blickwinkel ~w~zu verändern, wenn du zu Fuß oder in einem Fahrzeug unterwegs bist.
+[CRED222]
+DAN HOUSER AND LAZLOW
-[CAM_B]
-Drücke die ~h~Richtungstaste Oben~w~ und die ~h~Richtungstaste Unten~w~, um den ~h~Blickwinkel ~w~zu verändern, wenn du zu Fuß oder in einem Fahrzeug unterwegs bist.
+[CRED223]
+PRODUCER FOR ROCKSTAR NORTH
-[KM2_1]
-~g~Repariere den Wagen. Er muss top aussehen.
+[CRED224]
+CRAIG CONNER
-[LM3_6]
-Joey...
+[CRED225]
+ALLAN WALKER
-[LM3_6A]
-Na, ein bisschen Nahkampf mit deiner Braut gefällig?
+[CRED226]
+LAZLOW
-[LM3_9A]
-Vielleicht gibt's Arbeit für dich.
+[CRED227]
+DJ BANTER AND IMAGING
-[LM3_9B]
-Okay?
+[CRED228]
+WRITTEN BY DAN HOUSER AND LAZLOW
-[AWAY2]
-~r~Sie sind entkommen.
+[CRED229]
+FLASH FM
-[AWAY]
-~r~Er ist verschwunden!
+[CRD229A]
+TONI-MARIA CHAMBERS
-[JM6_1]
-Fahr zu der Bank auf dem Boulevard.
+[CRD229B]
+IMAGING VOICE AND PRODUCTION-JEFF BERLIN
-[GA_6B] { re3 change }
-Park die Karre, mach sie durch Drücken der ~h~~k~~VEHICLE_FIREWEAPON~-Taste~w~ scharf, und dann HAU AB!
+[CRED230]
+SPECIAL THANKS TO
-[GA_7B] { re3 change }
-Mach die Bombe mit der ~h~~k~~VEHICLE_FIREWEAPON~-Taste~w~ scharf. Sie geht hoch, wenn der Wagen angelassen wird.
+[CRED231]
+TOMMY MOTTOLA,
-[BAT1]
-~g~Nimm dir den Schläger!
+[CRED232]
+MICHELLE ANTHONY,
-[EBAL_O]
-Wenn du deine Sache gut machst, gibt's vielleicht noch mehr Jobs für dich. Und jetzt verschwinde!
+[CRED233]
+STEVE BARNETT,
-[HELP9_B]
-Drücke die ~h~~k~~PED_FIREWEAPON~-Taste~w~, um mit dem Präzisionsgewehr zu ~h~feuern~w~.
+[CRED234]
+CHUCK FLECKENSTEIN,
-[HELP9_C]
-Drücke die ~h~~k~~PED_FIREWEAPON~-Taste~w~, um mit dem Präzisionsgewehr zu ~h~feuern~w~.
+[CRED235]
+RITA LIBERATOR
-[JM6_8]
-~r~Du hast alle Räuber verloren!
+[CRED236]
+MARTIN & CLAIRE LOGAN
-[COLT_IN]
-Die Pistole ist jetzt im AmmuNation vorrätig!
+[CRED237]
+SANDRA HUTTON
-[TAXI2]
-~r~Die Zeit ist um!
+[CRED238]
+CHRISTINE DAVIDSON
-[TAXI3]
-~r~Dein Fahrgast ist entsetzt geflohen!
+[CRED239]
+ALAN, RED & BIGFOOT
-[TAXI7]
-~r~Dein Wagen ist Schrott. Repariere ihn.
+[CRED240]
+LE T
-[TAXI4]
-Fahrt abgeschlossen!
+[CRED241]
+COLIN DONALD
-[TAXI5]
-SPEED BONUS!!
+[CRED242]
+KERRY STALLWOOD
-[TAXI6]
-Taxi-Mission beendet
+[CRED243]
+ALAN MCGREGOR
-[FRANGO]
-~g~Salvatore sagt, du sollst zuerst Toni mit den Triaden helfen.
+[CRED244]
+CHRIS MORTON
-[PAGEB12]
-Polizei-Schmiergelder wurde im Versteck angeliefert.
+[CRED245]
+EMIL BUSSE
-[PAGEB13]
-Gesundheits-Powerups wurde im Versteck angeliefert.
+[CRED246]
+EMILY BAILLIE
-[PAGEB14]
-Adrenalin wurde im Versteck vorrätig.
+[CRED247]
+KEVIN ARCHIBALD
-[KM1_4]
-~g~Du brauchst einen Polizeiwagen für diesen Job!
+[CRED248]
+MORAG KERR
-[CAT1_B]
-dann bring $500 000 zu der Villa in Cedar Grove.
+[CRED249]
+CATH WALKER
-[JM2_C]
-Er hat eine Imbissbude in Chinatown.
+[CRED250]
+ISO BAR
-[RM6_1]
-Hier ist ein Schlüssel für eine Garage.
+[CRED251]
+WATERLINE
-[RM6_2]
-Darin findest du Bargeld und ein paar 'Requisiten' für alle Fälle.
+[CRED252]
+NEWS CAFE
-[RM6_3]
-Bis dann.
+[CRD251A]
+THE POND
-[FE_INIP]
-Initalisiere und lade Pausenmenü. Bitte warten.
+[CRD252A]
+PIVO
-[FESZ_CA]
-Abbrechen
+[CRED253]
+BUDGET VIDEO RENTALS
-[FESZ_QU]
-Beenden
+[CRED254]
+LORNA'S SCOOTER
-[FESZ_L1]
-Spiel erfolgreich gespeichert!
+[CRED255]
+GARETH MURFIN
-[FESZ_L2]
-Spiel gespeichert unter:
+[CRED256]
+ADDITIONAL ART
-[FESZ_OK]
-OK
+[CRED257]
+TONY PORTER
-[FES_LGA]
-Spiel laden
+[CRED258]
+CRAIG MOORE
-[FES_NGA]
-Neues Spiel
+[CRED259]
+CUT SCENE LIP-SYNC ANIMATION
-[FES_CAN]
-Abbrechen
+[CRED260]
+COSGROVE HALL FILMS
-[FESZ_QL]
-Alle nicht gespeicherten Daten des aktuellen Spiels werden verlorengehen. Ladevorgang fortsetzen?
+[CRED261]
+PRODUCER - OWEN BALLHATCHET
-[FESZ_QD]
-Dieses gespeicherte Spiel wirklich löschen?
+[CRED262]
+SENIOR ANIMATOR - JON TURNER
-[FESZ_QO]
-Dieses gespeicherte Spiel wirklich überschreiben?
+[CRED263]
+ANIMATORS - RICHARD DRUMM
-[FESZ_QR]
-Wirklich ein neues Spiel beginnen? Alle Daten seit dem letzten Speichern werden verlorengehen. Weiter?
+[CRED264]
+DAVE BROWN
-[FESZ_QS]
-SPEICHERN FORTSETZEN?
+[CRED265]
+MAIR THOMAS
-[SLONFP]
-MEMORY CARD-Steckplatz 1: Datei geschützt.
+[CRED266]
+PRASHANT PATEL
-[T4X4_1]
-'PATRIOT RALLYE'
+[CRED267]
+AUDIO TECHNOLOGY CONSULTANT
-[T4X4_2]
-'SPAZIERFAHRT IM PARK'
+[CRED268]
+RIK EDE FOR GAMESOUND LTD.
-[T4X4_3]
-'CHECKPOINT FIEBER'
+[CRED269]
+DTS INTEGRATION SUPPORT
-[MM_1]
-'VOLLGAS IM PARKHAUS'
+[CRED270]
+TED LAVERTY FOR DTS
-[T4X4_1A]
-~g~Du hast ~y~5 Minuten~g~, um ~y~15~g~ Checkpoints abzufahren. ~g~Die ~y~REIHENFOLGE IST BELIEBIG.
+[CRED271]
+CHRIS GREER FOR DTS
-[T4X4_1B]
-~1~ von 15!
+[CRED272]
+JASON PAGE FOR SCEE
-[T4X4_1C]
-~y~PASSIERE~g~ den ersten Checkpoint, dann läuft die Zeit. ~g~Jeder Checkpoint bringt dir ~y~20 SEKUNDEN~g~.
+[CRED273]
+RESEARCH AND ANALYSIS
-[T4X4_2A]
-~g~Du hast ~y~2 Minuten~g~, um ~y~12~g~ Checkpoints abzufahren. ~g~Die ~y~REIHENFOLGE IST BELIEBIG.
+[CRED274]
+VROCK
-[T4X4_2B]
-~1~ von 12!
+[CRED275]
+DJ: LAZLOW AS HIMSELF
-[T4X4_2C]
-~y~PASSIERE~g~ den ersten Checkpoint, dann läuft die Zeit. ~g~Jeder Checkpoint bringt dir ~y~10 SEKUNDEN~g~.
+[CRED276]
+IMAGING VOICE-JOE KELLY
-[T4X4_3A]
-~g~Du hast ~y~5 Minuten~g~, um ~y~20~g~ Checkpoints abzufahren. ~g~Die ~y~REIHENFOLGE IST BELIEBIG.
+[CRED277]
+IMAGING PRODUCTION-JONATHAN HANST
-[T4X4_3B]
-~y~PASSIERE~g~ den ersten Checkpoint, dann läuft die Zeit. ~g~Jeder Checkpoint bringt dir ~y~15 SEKUNDEN~g~.
+[CRED278]
+WAVE 103
-[T4X4_3C]
-~1~ von 20!
+[CRED279]
+DJ: ADAM FIRST-JAMIE CANFIELD
-[T4X4_F]
-~r~Du hast gekniffen! Schon überfordert?
+[CRED280]
+IMAGING VOICE-JEN SWEENEY
-[MM_1_A]
-~g~Du hast ~y~2 Minuten~g~, um ~y~20 Checkpoints~g~ in dem Parkhaus abzufahren! ~g~Die ~y~REIHENFOLGE IST BELIEBIG.
+[CRED281]
+IMAGING PRODUCTION-JONATHAN HANST
-[MM_1_B]
-~1~ von 20!
+[CRED282]
+FEVER 105
-[MM_1_C]
-~g~Das macht 20 Sekunden plus ~y~5 SEKUNDEN~g~ für jeden Checkpoint. ~g~Die Zeit läuft ~y~AB SOFORT.
+[CRED283]
+DJ: OLIVER 'LADYKILLER' BISCUIT-JULIUS DYSON
-[FM2_14]
-~r~Du warst zu nah dran und hast Curly aufgeschreckt!
+[CRED284]
+IMAGING VOICE MALE-ED MCMANN
-[FM2_15]
-~g~Nicht zu nahe ran, sonst schöpft Curly Verdacht!
+[CRED285]
+IMAGING VOICE FEMALE-SHAWNEE SMITH
-[UPSIDE]
-~r~Du hast dich überschlagen!
+[CRED286]
+IMAGING PRODUCTION- LISTEN KITCHEN
-[FM2_16]
-SCHRECK-O-METER:
+[CRED287]
+EMOTION 98.3
-[LM3_11]
-~g~Misty steigt in keinen Bus. Besorg ein anderes Fahrzeug!
+[CRED288]
+DJ: FERNANDO- FRANK CHAVEZ
-[LANDSTK]
-Landstalker
+[CRED289]
+IMAGING VOICE-JEN SWEENEY
-[IDAHO]
-Idaho
+[CRED290]
+IMAGING PRODUCTION-JONATHAN HANST
-[STINGER]
-Stinger
+[CRED291]
+RADIO ESPANTOSO
-[LINERUN]
-Linerunner
+[CRED292]
+DJ: PEPE-TONY CHILRODES
-[PEREN]
-Perennial
+[CRED293]
+WILDSTYLE
-[SENTINL]
-Sentinel
+[CRED294]
+DJ: MISTER MAGIC AS HIMSELF
-[PATRIOT]
-Patriot
+[CRED295]
+IMAGING VOICE-FRANK SILVESTRO
-[FIRETRK]
-Feuerwehrwagen
+[CRED296]
+IMAGING PRODUCTION-LAZLOW
-[TRASHM]
-Trashmaster
+[CRED297]
+KCHAT
-[STRETCH]
-Stretch
+[CRED298]
+WRITTEN BY DAN HOUSER AND LAZLOW
-[MANANA]
-Manana
+[CRED299]
+PRODUCED AND EDITED BY LAZLOW
-[INFERNS]
-Infernus
+[CRED300]
+DJ AMY SHECKENHAUSEN -LEYNA WEBER
-[BLISTA]
-Blista
+[CRED301]
+JEZ TORRENT-KEVIN MCKIDD
-[PONY]
-Pony
+[CRED302]
+MANDY -COLLEEN CORBETT
-[MULE]
-Mule
+[CRED303]
+MICHELLE CARAPADIS-MARY BIRDSONG
-[CHEETAH]
-Cheetah
+[CRED304]
+MR.ZOO-CARL DOWLING
-[AMBULAN]
-Krankenwagen
+[CRED305]
+GETHSEMANEE-LYNN LIPTON
-[FBICAR]
-F.B.I.
+[CRED306]
+CLAUDE MAGINOT-JOHN MAUCERI
-[MOONBM]
-Moonbeam
+[CRED307]
+BJ SMITH-LAWRENCE TAYLOR
-[ESPERAN]
-Esperanto
+[CRED308]
+THOR-FRANK FAVA
-[TAXI]
-Taxi
+[CRED309]
+RADIO CALLERS
-[KURUMA]
-Kuruma
+[CRED310]
+COUZIN ED, JOSH CLARK, JASON BUHRMESTER, JUAN ALLER, WAYNE OLIVER, SUSAN LEWIS, GILLIAN TELLING, TOM MURRAY, MIKE FERRANTE SR., EMMANUEL GOLDSTEIN, DAN HOUSER, NICK MANDELOS, GERRY COSGROVE, MIKE PALERMO, PORKCHOP, KEITH BROADAS
-[BOBCAT]
-Bobcat
+[CRED311]
+LEWIS, GILLIAN TELLING, TOM MURRAY, MIKE FERRANTE SR., EMMANUEL GOLDSTEIN,
-[WHOOPEE]
-Mr Whoopee
+[CRED312]
+DAN HOUSER, NICK MANDELOS, GERRY COSGROVE, MIKE PALERMO, PORKCHOP,
-[BFINJC]
-BF Injection
+[CRED313]
+KEITH BROADAS
-[POLICAR]
-Polizei
+[CRED314]
+VCPR
-[ENFORCR]
-Enforcer
+[CRED315]
+WRITTEN BY DAN HOUSER AND LAZLOW
-[SECURI]
-Securicar
+[CRED316]
+PRODUCED BY LAZLOW
-[BANSHEE]
-Banshee
+[CRED317]
+MAURICE CHAVEZ-PHILLIP ANTHONY RODRIGUEZ
-[PREDATR]
-Predator
+[CRED318]
+JONATHAN FREELOADER- PATRICK OLSEN
-[BUS]
-Bus
+[CRED319]
+MICHELLE MONTANIUS-KELLY GUEST
-[RHINO]
-Rhino
+[CRED320]
+REP. ALEX SHRUB- CHRIS LUCAS
-[BARRCKS]
-Barracks OL
+[CRED321]
+CALLUM CRAYSHAW- SEAN MODICA
-[TRAIN]
-Zug
+[CRED322]
+JOHN F. HICKORY- LJ GANSEN
-[HELI]
-Helikopter
+[CRED323]
+PASTOR RICHARDS- DAVID GREEN
-[DODO]
-Dodo
+[CRED324]
+JAN BROWN- MAUREEN SILLIMAN
-[COACH]
-Coach
+[CRED325]
+BARRY STARK- RENAUD SEBBANE
-[CABBIE]
-Cabbie
+[CRED326]
+JENNY LOUISE CRAB- MARY BIRDSONG
-[STALION]
-Stallion
+[CRED327]
+KONSTANTINOS SMITH- KONSTANTINOS.COM
-[RUMPO]
-Rumpo
+[CRED328]
+JEREMY ROBARD-PETER SILVESTRO
-[RCBANDT]
-RC Bandit
+[CRED329]
+RADIO COMMERCIALS
-[BELLYUP]
-Triad
+[CRED330]
+WRITTEN BY DAN HOUSER AND LAZLOW
-[MRWONGS]
-Mr Wongs
+[CRED331]
+PRODUCED BY LAZLOW
-[MAFIACR]
-Mafia
+[CRED332]
+ADDITIONAL JINGLES PRODUCED BY CRAIG CONNER
-[YARDICR]
-Yardie
+[CRED333]
+COMMERCIAL VOICES:
-[YAKUZCR]
-Yakuza
+[CRED334]
+ADAM DAVIDSON, ALEX ANTHONY, ALICE SALTZMAN, AMY SALZMAN, KATE DUKICH,
-[DIABLCR]
-Diablo
+[CRED335]
+ARAN RONICLE, BARB JONES, BEN KRECH, BRIAN THOMAS, BROCK YODER, CHRIS
-[COLOMCR]
-Cartel
+[CRED336]
+FERRANTE, CRAIG CONNER, DAVE RYAN, DAVID GREEN, DORIS WOO, DOUGLAS
-[HOODSCR]
-Hoods
+[CRED337]
+HARRISON, ED MCMANN, FRANK CHAVEZ, FRANK FAVA, GENE HILGREEN, GREG
-[AEROPL]
-Flugzeug
+[CRED338]
+SCHWEIZER, HUNTER PLATIN, JAMES FERRANTE, JEFF BERLIN, JEFF ROSA, JOE KELLY,
-[SPEEDER]
-Speeder
+[CRED339]
+JOHN MAUCERI, JOSH CLARK, JULIE WEMYSS, KEVIN STRALEY, KIM GURNEY, LANCE
-[REEFER]
-Reefer
+[CRED340]
+WILLIAMS, LAURA PATERSON, LAZLOW, LISA ORTIZ, LORNA JORDAN, LUCIEN JONES,
-[PANLANT]
-Panlantic
+[CRED341]
+MAUREEN SILLIMAN, MIKE FERRANTE JR., PETE GUSTIN, PETER SILVESTRO, RAFF
-[FLATBED]
-Flatbed
+[CRED342]
+CROLLA, RANDY JOHNSON, RICHARD KRUGER, RON REEVE, SHELLEY MILLER, SKY, TJ ALLARD
-[YANKEE]
-Yankee
+[CRD344A]
+AUDIO RECORDED AT DIGITAL ARTS STUDIOS,
-[BORGNIN]
-Borgnine
+[CRED344]
+NYC, TRACK 9 STUDIOS, NYC,
-[TOYZ]
-TOYZ
+[CRED345]
+WEDDINGTON MULTIMEDIA, LOS ANGELES,
-[FEST_DF]
-Zu Fuß zurückgel. Meilen
+[CRD345A]
+SYNC SOUND, NYC AND RADIO LAZLOW, LONG ISLAND.
-[FEST_DC]
-Mit Auto gefahrene Meilen
+[CRED346]
+THANKS TO AXEL ERICSON AND WON LEE AT DIGITAL ARTS, PAUL VASQUEZ AT TRACK 9 STUDIOS, JOHN BOWEN AND JOHN HASSLER AT SYNC SOUND
-[FESTDFM]
-Zu Fuß zurückgel. Meter
+[CRED347]
+MARK LLOYD
-[FESTDCM]
-Mit Auto gefahrene Meter
+[CRED348]
+TIM BATES
-[FEST_R1]
-Patriot Rallye in Sek.
+[CRED349]
+KIT BROWN
-[FEST_R2]
-Spazierfahrt im Park in Sek.
+[CRED350]
+ANDY MASON
-[FEST_R3]
-Checkpoint-Fieber in Sek.
+[CRED351]
+PHIL DEANE
-[FEST_RM]
-Vollgas durch die Parkgarage in Sek.
+[CRED352]
+PHIL ALEXANDER
-[FEST_LS]
-Mit Krankenwagen gerettete Menschen
+[CRED353]
+MATT HEWITT
-[FEST_CC]
-Kriminelle bei Bürgerwehr Mission
+[CRED354]
+DENBY GRACE
-[FEST_FE]
-Gelöschte Feuer gesamt
+[CRED355]
+ANTOINE CABROL
-[FEST_LF]
-Längster Flug in Dodo
+[CRED356]
+JONATHAN STONES
-[FEST_BD]
-Bestzeit Bombenentschärfung
+[CRED357]
+MIKE BLACKBURN
-[FEST_RP]
-Bestandene Amokfahrten
+[CRED358]
+TIM MCGAFF
-[FEST_MP]
-Erledigte Missionen
+[CINCAM]
+Cinematic-Kamera
-[FEST_BB]
-Schnelle Autos, Schnelles Geld:
+[RC4]
+'ROCK'N ROLL MIT RUMPO'
-[FEST_H0]
-Meiste Checkpoints
+[LEGAL]
+~g~Schalte die kriminelle Bedrohung aus!
-[FEST_GC]
-Geschrottete Gang-Autos:
+[GA_2]
+Neuer Motor und neue Lackierung. Die Cops werden dich nicht identifizieren!
-[FEST_H1]
-Im Dschungel der Diablos
+[HELP15]
+Wenn zu Fuß unterwegs, drücke die ~h~~k~~PED_LOOKBEHIND~~w~, um ~h~nach hinten zu sehen~w~. Benutze den ~h~rechten Analog-Stick~w~, um dich ~h~umzusehen~w~.
-[FEST_H2]
-Mafia-Massaker
+[FEC_LB4]
+Nach hinten sehen (R3-Taste)
-[FEST_H3]
-Der Casino-Coup
+[PERPIC]
+Versteckte Päckchen gefunden
-[FEST_H4]
-Rock'n'Roll mit Rumpo
+[CO_ONE]
+Verstecktes Päckchen ~1~ von ~1~
-[USJI1]
-TEXT NO LONGER REQUIRED
+[GA_21]
+In dieser Garage bringst du keine Autos mehr unter.
-[USJI2]
-TEXT NO LONGER REQUIRED
+[CHEAT1]
+Cheat aktiviert
-[USJI3]
-TEXT NO LONGER REQUIRED
+[CHEAT2]
+Waffen-Cheat
-[USJ]
-MONSTER-STUNT-BONUS!
+[CHEAT3]
+Health-Cheat
-[SPRAY]
-Fahre deinen Wagen in die Lackiererei, um deinen ~h~Fahndungslevel~w~ loszuwerden und das Auto zu ~h~reparieren~w~ und ~h~umzuspritzen~w~. Kosten - ~h~$1000.
+[CHEAT4]
+Panzerungs-Cheat
-[HM1_1]
-~g~Fertige 20 Purple Nines in 2 Min. 30 Sek. ab.
+[CHEAT5]
+Fahndungslevel-Cheat
-[KM1_8A] { re3 change }
-Drücke die~h~ ~k~~VEHICLE_FIREWEAPON~-Taste~w~ zum ~h~Zünden der Bombe~w~. Aber geh vorher in Deckung!
+[CHEAT6]
+Geld-Cheat
-[KM1_8D] { re3 change }
-Drücke die~h~ ~k~~VEHICLE_FIREWEAPON~-Taste~w~ zum ~h~Zünden der Bombe~w~. Aber geh vorher in Deckung!
+[CHEAT7]
+Wetter-Cheat
-[KM1_12]
-~g~Bring ihm zum Dojo, aber häng vorher die Cops ab!
+[USJ_ALL]
+ALLE MONSTER-STUNTS ABSOLVIERT!
-[RATNG1]
-Taschendieb
+[JAN]
+Jan
-[RATNG2]
-Laufbursche
+[FEB]
+Feb
-[RATNG3]
-Gauner
+[MAR]
+Mär
-[RATNG4]
-Soldat
+[APR]
+Apr
-[RATNG5]
-Profi
+[MAY]
+Mai
-[RATNG6]
-Fahrer
+[JUN]
+Jun
-[RATNG7]
-Gangster
+[JUL]
+Jul
-[RATNG8]
-Obergangster
+[AUG]
+Aug
-[RATNG9]
-Partner
+[SEP]
+Sept
-[RATNG10]
-Troubleshooter
+[OCT]
+Okt
-[RATNG11]
-Vollstrecker
+[NOV]
+Nov
-[RATNG12]
-Capo
+[DEC]
+Dez
-[RATNG13]
-Rechte Hand
+[DEFDT]
+--:---:---- --:--:--
-[RATNG14]
-Vize
+[BONUS]
+~g~BONUS $~1~
-[RATNG15]
-Boss
+[HORN1]
+Drück die ~h~~k~~VEHICLE_HORN~~w~, um zu ~h~hupen.
-[1010]
-~r~Dein Fahrzeug liegt auf dem Kopf
+[HORN2]
+Drück die ~h~~k~~VEHICLE_HORN~~w~, um zu ~h~hupen.
-[1011]
-~r~Dein Fahrzeug liegt auf dem Kopf
+[HORN3]
+Drück die ~h~~k~~VEHICLE_HORN~~w~, um zu ~h~hupen.
-[1012]
-~r~Dein Fahrzeug liegt auf dem Kopf
+[FEC_EXV]
+In Fahrzeug ein- und aussteigen.
-[1013]
-~r~Dein Fahrzeug liegt auf dem Kopf
+[TAXI_M]
+'TAXIFAHRER'
-[1014]
-~r~Dein Fahrzeug liegt auf dem Kopf
+[COP_M]
+'BÜRGERWEHR'
-[JM4_10]
-Okay, Junge. Fahr mich zuerst in die Wäscherei in Chinatown. Ich hab da was zu erledigen.
+[FIRE_M]
+'FEUERWEHRMANN'
-[JM4_11]
-Die Waschweiber da haben ihr Schutzgeld nicht bezahlt.
+[AMBUL_M]
+'SANITÄTER'
-[JM4_12]
-Und pass auf den Wagen auf. Joey hat ihn gerade repariert.
+[HJ_IS]
+IRRSINNS-STUNT-BONUS: $~1~
-[JM4_13]
-Also, keine Dummheiten, okay?
+[HJ_PIS]
+SUPER IRRSINNS-STUNT-BONUS: $~1~
-[KM4_11]
-~g~Bring das Geld ins Casino!
+[HJ_DIS]
+DOPPELTER IRRSINNS-STUNT-BONUS: $~1~
-[FEF_BR2]
-Orientiere dich, indem du alle bisherigen Einsatzbesprechungen durchsiehst.
+[HJ_PDIS]
+SUPER-DOPPEL-IRRSINNS-STUNT-BONUS: $~1~
-[TRAIN_1]
-Kurowski Station
+[HJ_TIS]
+DREIFACHER IRRSINNS-STUNT-BONUS: $~1~
-[TRAIN_2]
-Rothwell Station
+[HJ_PTIS]
+SUPER-DREIFACH-IRRSINNS-STUNT-BONUS: $~1~
-[TRAIN_3]
-Baillie Station
+[HJ_QIS]
+VIERFACHER IRRSINNS-STUNT-BONUS: $~1~
-[SUBWAY1]
-Portland Station
+[HJ_PQIS]
+SUPER-VIERFACH-IRRSINNS-STUNT-BONUS: $~1~
-[SUBWAY2]
-Rockford Station
+[FESZ_LS]
+Ladevorgang beendet.
-[SUBWAY3]
-Staunton South Station
+[HELI_1A]
+Teste dein Können mit dem 'Sparrow'. Probiere, wie schnell du den Kurs abfliegen kannst.
-[SUBWAY4]
-Shoreside Terminal
+[HELI_1B]
+Kurs absolviert!
-[MEA4_2]
-~r~Marty Chonks ist tot!
+[HELIODD]
+Helikopter-Jobs
-[SPRAY1]
-Fahre deinen Wagen in die Lackiererei, um deinen ~h~Fahndungslevel~w~ loszuwerden und das Auto zu ~h~reparieren~w~ und ~h~umzuspritzen~w~. Kosten - ~h~$1000~w~. Diesmal kostet es nichts.
+[LAW]
+DIE ANWALTSMISSIONEN
-[JM4_A]
-Ja, ich weiß, Toni, ich hab sie gut erzogen. Sie schnurrt, falls du verstehst, was ich meine.
+[LAW1_1]
+~g~Besorge dir neue Sachen in Rafaels Shop.
-[JM4_5]
-Komm später wieder, dann zeigen wir den Kerlen, was Sache ist.
+[LAW4_6]
+Nieder mit der Geschäftsleitung!
-[AMMU_A]
-Luigi sagt, du brauchst 'ne Knarre...
+[LAW4_7]
+Tod den Bossen!
-[AMMU_B]
-Joey sagt, ich soll dich 'ausrüsten'...
+[LAW4_8]
+Kampf, Kampf, Kampf, Kampf!
-[AMMU_C]
-Geh hinten um den Laden herum. Ich hab eine 9mm im Hof deponiert.
+[LAW4_9]
+Mehr Urlaub, weniger Arbeit!
-[AMMU_D]
-Ich hab alles, was man so zur Selbstverteidigung braucht.
+[LAW4_11]
+Kampf, Kampf, Kampf, Kampf!
-[AMMU_E]
-Willst du auch 'nen Waffenschein?
+[LAW4_12]
+Es lebe die Revolution!
-[AMMU_F]
-Auf den Ausweis verzichte ich. Du siehst vertrauenswürdig aus.
+[GENERAL]
+DIE COLONEL-MISSIONEN
-[DETON]
-DETONATION:
+[GEN3_4]
+Tommy Vercetti. Los, komm...
-[DRIVE_A] { re3 change }
-Halt eine Uzi im Anschlag, wenn du in ein Fahrzeug steigst. Schau dann nach links oder rechts und drücke die ~h~~k~~VEHICLE_FIREWEAPON~-Taste~w~, um zu feuern.
+[GEN3_13]
+Was ist los, Mann?! Steig auf das Dach gegenüber im Hof bevor sie kommen!
-[DRIVE_B] { re3 change }
-Halt eine Uzi im Anschlag, wenn du in ein Fahrzeug steigst. Schau dann nach links oder rechts und drücke die ~h~~k~~VEHICLE_FIREWEAPON~-Taste~w~, um zu feuern.
+[GEN3_17]
+Mist! Willst du mich umbringen?!
-[RECORD]
-~g~NEUER REKORD!!
+[GEN3_21]
+~g~Er hat Diaz' Geld! Stelle ihn und hole es zurück!
-[NRECORD]
-~r~KEIN NEUER REKORD!
+[GEN3_24]
+~r~Diaz hat's erwischt! Du hast versagt!
-[RCHELP] { re3 change }
-Drücke die ~k~~VEHICLE_FIREWEAPON~-Taste oder fahre das ferngesteuerte Auto in die Räder eines Fahrzeugs, um es zu sprengen.
+[GEN3_26]
+~r~Du hast Diaz erwischt!
-[RCHELPA] { re3 change }
-Drücke die ~k~~VEHICLE_FIREWEAPON~-Taste oder fahre das ferngesteuerte Auto in die Räder eines Fahrzeugs, um es zu sprengen.
+[GEN3_27]
+~r~Du hast Diaz' Bodyguards erwischt!
-[RC_1]
-Du hast 2 Minuten, um so viele Diablo-Autos wie möglich zu sprengen!
+[GEN3_31]
+~g~Begib dich zum Übergabeort und pass auf Diaz auf.
-[RC_2]
-Du hast 2 Minuten, um so viele Mafia-Autos wie möglich zu sprengen!
+[GEN3_32]
+~g~Begib dich zu deinem Beobachtungsposten auf dem Dach des Gebäudes gegenüber von Lance.
-[RC_3]
-Du hast 2 Minuten, um so viele Yakuza-Autos wie möglich zu sprengen!
+[COKE]
+DIE KOKS-BARON-MISSIONEN
-[RC_4]
-Du hast 2 Minuten, um so viele Yardie-Autos wie möglich zu sprengen!
+[COK1_3]
+Ich hoffe, du brichst dir das Genick!
-[RC_5]
-Du hast 2 Minuten, um so viele Hood-Autos wie möglich zu sprengen!
+[COK1_6]
+Ich hab diese Idioten satt!
-[RC_6]
-Du hast 2 Minuten, um so viele Kartell-Autos wie möglich zu sprengen!
+[COK2_7]
+Siehst du diese Bojen? Versuch, die Lichter auszuschießen.
-[RAMPAGE]
-AMOKLAUF!!
+[COK2_10]
+Eines ist sicher: Du schießt besser als du laberst.
-[RAMP_P]
-AMOKLAUF BEENDET!
+[COK2_11]
+Danke. Du bist ein echter Charmeur.
-[RAMP_F]
-AMOKLAUF FEHLGESCHLAGEN
+[COK2_12]
+Ich weiß, Tommy.
-[PAGE_00]
-.
+[COK2_18]
+Stehst du auf Kenny Loggins?
-[PAGE_01]
-Dein Job: ~1~ Diablos in 120 Sekunden!
+[COK2_19]
+Mann, ich liebe diese Scheibe.
-[PAGE_02]
-Zerstöre ~1~ Fahrzeuge in 120 Sekunden!
+[COK2_26]
+~r~Du hast Lance erwischt!
-[PAGE_03]
-Dein Job: ~1~ Mafiosi in 120 Sekunden!
+[COK3_1]
+Nicht schießen, Mann!
-[PAGE_04]
-Dein Job: ~1~ Triaden in 120 Sekunden!
+[COK3_2]
+Was ist in dem Zeug drin?
-[PAGE_05]
-Dein Job: ~1~ Triaden in 120 Sekunden!
+[COK3_3]
+Er klaut das Boot. Mist!
-[PAGE_06]
-Zerstöre ~1~ Fahrzeuge in 120 Sekunden!
+[COK3_4]
+Hilfe! Irgendein Irrer stiehlt das Boot, Mann!
-[PAGE_07]
-Dein Job: ~1~ Yardies in 120 Sekunden!
+[COK4_W]
+Uff! Das ist der letzte.
-[PAGE_08]
-Dein Job: ~1~Yakuza in 120 Sekunden!
+[COK4_X]
+Ich lass die Mühle an.
-[PAGE_09]
-Zerstöre ~1~ Fahrzeuge in 120 Sekunden!
+[COK4_Y]
+Ich glaube, wir haben ein paar neue Freunde.
-[PAGE_10]
-Zerstöre ~1~ Fahrzeuge in 120 Sekunden!
+[COK4_2]
+Ja.
-[PAGE_11]
-Dein Job: ~1~ Yardies in 120 Sekunden!
+[COK4_6]
+Weißt du, wo's lang geht?
-[PAGE_12]
-Dein Job: ~1~Yakuza in 120 Sekunden!
+[COK4_7]
+Haben wir uns verfahren?
-[PAGE_13]
-Dein Job: ~1~ Yardies in 120 Sekunden!
+[COK4_8]
+Wir haben Konkurrenz bekommen!
-[PAGE_14]
-Dein Job: ~1~ Kolumbianer in 120 Sekunden!
+[COK4_9]
+Knöpf sie dir vor!
-[PAGE_15]
-Dein Job: ~1~ Hoods in 120 Sekunden!
+[COK4_9A]
+Zeit für den Lance Vance Dance!
-[PAGE_16]
-Zerstöre ~1~ Fahrzeuge in 120 Sekunden!
+[COK4_10]
+Die sind Kleinholz! Und Fischfutter.
-[PAGE_17]
-Nimm dir mit einem Auto ~1~ Kolumbianer in 120 Sekunden vor!
+[COK4_11]
+Geschafft! Die anderen Schiffchen taugen nicht viel.
-[PAGE_18]
-Zerstöre ~1~ Fahrzeuge mit einem Drive-by in 120 Sekunden!
+[COK4_17]
+Die wollen's wissen!
-[PAGE_19]
-Dein Job: ~1~ Kolumbianer in 120 Sekunden!
+[COK4_18]
+Ich hab nasse Füße! WIR KRIEGEN WASSER INS BOOT!
-[PAGE_20]
-Dein Job: ~1~ Hoods in 120 Sekunden!
+[COK4_21]
+Achtung, Brücke!
-[JM1_A]
-Mir ist langweilig. Wann läuft hier endlich mal was ab?
+[COK4_22]
+Raus! Das Ding geht hoch!
-[JM1_B]
-Gleich, Schätzchen. Muss nur schnell was erledigen.
+[COK4_23]
+Gut geschossen.
-[JM1_C]
-Ich hab 'nen kleinen Job für dich.
+[COK4_29]
+~r~Du hast Lance erwischt!
-[JM1_D]
-Die Forelli Brüder zahlen ihre Schulden nicht.
+[ASS1_6]
+Geh nur, Tommy, ich komm schon zurecht!
-[JM1_E]
-Ich muss ihnen ein bisschen Respekt einbläuen.
+[ASS1_7]
+Das ist für euch, ihr verdammten Mörder!!
-[JM1_F]
-Lips Forelli stopft sich gerade in Marcos Bistro seinen fetten Bauch voll.
+[ASS1_8]
+Ich komm hier nicht weg!
-[JM1_G]
-Klau ihm sein Auto und bring es in 8-Balls Bombenwerkstatt in Harwood.
+[ASS1_9]
+Ich bin da, Tommy!
-[JM1_H]
-Du kennst doch 8-Ball, oder?
+[ASS1_10]
+Hey, das ist aber ein herzallerliebstes Beet.
-[JM1_I]
-Sobald er 'ne Bombe eingebaut hat, parkst du die Karre an ihrem alten Platz.
+[ASS1_11]
+Hey Tommy, krieg ich ein Zimmer mit Blick auf die Bucht?
-[JM1_J]
-Dann lehn dich zurück und sieh dir die Show an.
+[ASS1_12]
+Schön hohe Decken hat's hier...
-[JM1_K]
-Aber Beeilung. Der Typ isst nicht ewig.
+[ASS1_3]
+Lance! Ich brauche Deckung!
-[CAT2_A1]
-Komm schon, du dummes Luder!
+[ASS1_4]
+Diaz muss drinnen sein!
-[CAT2_A]
-Bist du eigentlich gekommen, um Maria zu retten, oder weil du heiß auf mich bist?
+[ASS1_5]
+Lance!
-[CAT2_B]
-Falls du's noch nicht weißt:
+[ASS1_15]
+~g~Stürme die Villa und erledige Diaz!
-[CAT2_B2]
-Die Dates mit dir waren Arbeit - dich fertig zu machen, wird ein Vergnügen.
+[ASS1_17]
+~g~Es führen mehrere Wege in die Villa.
-[CAT2_C]
-Du bist ein armes Würstchen, Amigo.
+[TAXWAR]
+TAXI-KRIEG-MISSIONEN
-[CAT2_D]
-Wirf die Kohle rüber!
+[NOTAXI]
+~g~Du brauchst ein Kaufman-Taxi, um diese Mission zu aktivieren.
-[CAT2_E]
-Du bist an sich ein fähiger Bursche.
+[TAXW1_5]
+~g~Du musst in einem Kaufman-Taxi sitzen!
-[CAT2_E2]
-Aber du kapierst nicht, dass man mir nicht trauen kann.
+[TAX2_4]
+Auf geht's, Tommy.
-[CAT2_E3]
-Macht den Idioten fertig.
+[TAX2_5]
+Polier ihm die Visage.
-[CAT2_J]
-Bring das Ding in die Luft!!
+[TAX2_6]
+Der hat nicht mal eine Lizenz.
-[HM5_1]
-Yo, Ice hat dich angekündigt. Es gibt hier Regeln. Nur Schläger. Keine Knarren, keine Autos.
+[TAX2_7]
+Verdammte Limo-Services.
-[HM5_5]
-Hier geht's um Respekt und Achtung, klar?
+[TAXW3_1]
+~g~Hole Mercedes ab.
-[HELP14]
-Um Waffen aufzunehmen, gehe darüber hinweg. Dies funktioniert nicht, wenn du in einem Fahrzeug sitzt.
+[RACE1]
+~g~3...2...1...LOS, LOS, LOS!
-[CRUSH]
-Parke in der markierten Zone und steig aus. Das Fahrzeug wird dann geschrottet.
+[RACE2]
+~g~3
-[DIAB2_B]
-Eine Bande von Taugenichtsen will mir ans Leder, falls ich sie nicht an meinen Geschäften beteilige.
+[RACE3]
+~g~2
-[DIAB2_C]
-Aber da sind sie an den Falschen geraten, Amigo.
+[RACE4]
+~g~1
-[DIAB2_D]
-Die haben eine Schwäche für Eiscreme.
+[RACE5]
+~g~LOS!
-[DIAB2_E]
-Hol die Bombe ab, die ich in Harwood versteckt habe,
+[FIRST]
+~b~1.
-[DIAB2_F]
-schnapp dir einen normalen Eis-Wagen, der rumfährt
+[SECOND]
+~b~2.
-[DIAB2_G]
-und locke diese Idioten mit dem Eis-Jingle in ihr Verderben.
+[THIRD]
+~b~3.
-[DIAB2_H]
-Sie verstecken sich in einem Lagerhaus auf den Atlantic Quays.
+[FOURTH]
+~b~4.
-[DIAB3_A]
-Irgendwelche frechen Triaden haben gestern Nacht meinen Traumwagen geklaut,
+[RACETM]
+~b~ZEIT: ~1~:~1~
-[DIAB3_B]
-geschrottet und ausbrennen lassen.
+[RACETM2]
+~b~ZEIT: ~1~:0~1~
-[DIAB3_C]
-Im Kofferraum waren einige sehr wertvolle Erinnerungsstücke,
+[RACEFA]
+~r~Du hast das Rennen verloren!
-[DIAB3_D]
-unersetzliche Sammlerstücke, mein Freund.
+[TEX1_5]
+~r~Er ist entkommen!
-[DIAB3_E]
-Ich hab eine ziemlich heiße Waffe am Rand von Chinatown versteckt.
+[SEG3_1]
+ZEIT:
-[DIAB3_F]
-Hol sie dir und lehre die Triaden, El Burros Zorn zu fürchten.
+[SEG3_2]
+~g~Begib dich zu dem Transporter mit dem RC Raider und den Zeitzünder-Bomben.
-[DIAB3_1]
-NIMM DIR 25 TRIADEN VOR
+[SEG3_3]
+~g~Du musst den RC Raider benutzen, um 4 Bomben zu 4 Zielzonen auf dem Grundstück zu bringen.
-[DIAB4_A]
-Ein mieser Dieb hat einen Transporter mit der gesamten neuen Ausgabe meines Magazins gestohlen!
+[SERG3_5]
+~g~Du kannst immer nur 1 Bombe transportieren und kannst erfolgreich platzierten Bomben nicht wieder aufnehmen.
-[DIAB4_B]
-Aber dieser SPANK-Junkie hat die Hecktüren offen gelassen
+[SEG3_7]
+~g~Sobald du die ERSTE Bombe platziert hast, läuft der Timer des Zeitzünders an. Du musst dann alle Bomben innerhalb dieses Zeitraums platzieren.
-[DIAB4_C]
-und jetzt verteilt sich mein wunderschönes,
+[SEG3_8]
+~g~Alle 4 Bomben müssen in den 4 Zielzonen platziert werden, um die Mission zu erfüllen und das Gebäude zu demolieren.
-[DIAB4_D]
-geschmackvoll fotografiertes Magazin gleichmäßig über ganz Liberty!
+[SEG3_9]
+~g~Zielzone getroffen! Noch 3 Bomben.
-[DIAB4_E]
-Nimm den Transporter, folge der Spur von 'Donkey Does Dallas' Nr. 1, 2 und 3.
+[SEG3_10]
+~g~Zielzone getroffen! Noch 2 Bomben.
-[DIAB4_F]
-Und sammle das Zeug wieder ein.
+[SEG3_11]
+~g~Zielzone getroffen! Noch 1 Bombe.
-[DIAB4_G]
-Wenn du bei diesem diebischen Junkie angekommen bist, nimm ihn dir vor!
+[SEG3_12]
+~r~Ziel verfehlt. Hol dir eine Bombe!
-[DIAB4_H]
-Und dann lieferst du meine Magazine an das XXX Mags im Rotlichtviertel.
+[SEG3_13]
+~g~Wirf die Bombe in einer Zielzone ab.
-[DIAB4_1]
-~g~Fahr den Transporter zur Rückseite des XXX Mags.
+[SEG3_14]
+~r~Die Zeit ist um. Demolierung des Gebäudes fehlgeschlagen.
-[HM1_E]
-Ich möchte, dass du diesen Vollidioten zeigst, wie ein echter Driveby aussieht.
+[SEG3_15]
+~r~Dein RC Raider ist zerstört. Wie willst du jetzt die Bomben transportieren?
-[HM1_H]
-Schaff mir diese Nines vom Hals!!
+[AVERY]
+AVERY-MISSIONEN
-[HM2_A]
-Die Nines bringen mich in die Klemme.
+[ASM]
+ATTENTÄTERMISSIONEN
-[HM2_B]
-Die Kerle haben gepanzerte Autos, und jetzt verhökern sie SPANK
+[ASM_1]
+ATTENTÄTERMISSION 1
-[HM2_C]
-an meine Brüder, als wäre das gar nichts.
+[ASM1_1]
+~g~Mr. Teal, Ihre Hilfe bei der Beseitigung der Landeier war äußerst wertvoll. Ich habe noch mehr Arbeit, die eine eher 'zupackende' Art verlangt. Ihr nächster Job klebt unter dem Telefon.
-[HM2_D]
-Auf dem Weg steht ein Wagen geparkt.
+[ASM1_2]
+~g~Begib zu dich dem Fernsprecher vor dem Einkaufszentrum in Washington.
-[HM2_E]
-Da ist was drin, was diesen Feiglingen Beine machen wird.
+[ASM1_3]
+~g~Carl Pearson, Pizza-Lieferant. Er darf seine Lieferungen nicht durchführen.
-[HM3_A]
-Irgend so ein Mistkerl hat 'ne Bombe in meine Karre eingebaut.
+[ASM1_4]
+~g~Schalte den Pizza-Lieferanten aus, bevor er seine Lieferungen abschließt.
-[HM3_B]
-Wenn ich die Karre verliere, stehe ich als Trottel da.
+[ASM_2]
+ATTENTÄTERMISSION 2
-[HM3_C]
-Hol meinen Wagen ab und bring ihn in die Werkstatt in St. Mark's.
+[ASM_3]
+ATTENTÄTERMISSION 3
-[HM3_D]
-Die sollen die Bombe da entschärfen.
+[ASM3_A]
+Marcus Hammond, Franco Carter, Dick Tanner, Nick Kong und Stuntman Driver gehören zu einem europäischen Syndikat und planen einen Überfall.
-[HM3_E]
-Die Uhr tickt und die Drähte sind locker.
+[ASM3_B]
+Sie sind alle bereits in Position. Schalten Sie sie aus, bevor es losgeht. Sie haben 9 Minuten. Ich habe in der Nähe Waffen deponiert, die Sie brauchen werden.
-[HM3_F]
-Ein Schlagloch zuviel, und das Ding geht hoch.
+[ASM3_1]
+~g~Hol dir die Waffe, die Mr. Black für dich deponiert hat.
-[HM3_G]
-Also, Beeilung!
+[ASM3_2]
+~g~Geh nicht zu dicht an die Zielperson heran, sonst bemerkt sie dich.
-[HM4_A]
-Yo, ein Flugzeug der Staatsbank ist gerade beim Francis Int. Airport abgestürzt.
+[ASM3_3]
+~g~Es geht schneller, wenn du dir eine günstige Position nahe ihrem Standort suchst und zuschlägst, ohne gesehen zu werden.
-[HM4_B]
-Auf dem ganzen Rollfeld liegt Platin rum
+[ASM3_4]
+~g~Er hat dich gesehen. Du musst ihn irgendwie ausschalten!
-[HM4_C]
-Schnapp dir ein Auto und sack so viel wie möglich davon ein.
+[ASM3_5]
+~g~Marcus Hammond befindet sich bei den Werbetafeln in Washington Beach.
-[HM4_F]
-Du kannst das Zeug in einer meiner Garagen abladen.
+[ASM3_6]
+~g~Franco Carter befindet sich bei DBP Security nahe dem Ocean Drive.
-[HM4_G]
-Platin ist verdammt schwer. Dein Auto wird etwas langsamer laufen.
+[ASM3_7]
+~g~Dick Tanner ist in der Nähe des Juweliers in Vice Point.
-[HM4_H]
-Also, lade regelmäßig etwas davon in einer Garage ab.
+[ASM3_8]
+~g~Nick Kong befindet sich nähe Washington Beach.
-[HM5_A]
-Die Nines sind nur noch ein versprengter Haufen...
+[ASM3_9]
+~g~Stuntman Driver ist in Washington.
-[HM5_B]
-aber sie machen immer noch Stress.
+[ASM3_10]
+Du hast nicht alle ausgeschaltet.
-[HM5_C]
-Jetzt wollen sie's endgültig wissen.
+[ASM_4]
+ATTENTÄTERMISSION 4
-[HM5_D]
-Eine Gang von denen gegen zwei von uns. Oder vielmehr...
+[ASM4_1]
+~g~Hol dir das Gewehr, das im Laub vor dem Flughafen-Terminal für dich deponiert wurde.
-[HM5_E]
-zwei von euch.
+[ASM4_2]
+~g~Verfehle dein Ziel nicht, du alarmierst sonst die Leibwächter. Und bleib auf Distanz, damit er dich nicht bemerkt.
-[HM5_F]
-Ich wäre ja dabei, aber...
+[ASM4_3]
+~g~Beobachte die Frau über den Check-in-Schaltern im Terminal. TU IHR NICHTS.
-[HM5_G]
-ich hab noch drei Monate Bewährung,
+[ASM4_4]
+~g~Erledige den Mann, dem sie den Aktenkoffer gibt, aber erst, NACHDEM ER IHN GENOMMEN HAT. Hole den Koffer und bringe ihn ins Ammu-Nation Downtown.
-[HM5_H]
-verstehst du, was ich meine?
+[ASM4_5]
+Hol dir den Aktenkoffer.
-[HM5_I]
-Triff dich mit meinem kleinen Bruder.
+[ASM4_6]
+~g~Bring den Aktenkoffer ins Ammu-Nation Downtown.
-[HM5_J]
-Er zeigt dir, wo der Fight stattfindet, okay?
+[ASM4_7]
+~r~Du hast die Frau erwischt, du Idiot!
-[MEA1_B]
-Mein Name ist Chonks, Marty Chonks.
+[ASM4_8]
+~r~Die Zielperson hat gehört, wie du geschossen hast. Der Deal ist geplatzt!
-[MEA1_C]
-Mir gehört die Bitchin' Dog Food Fleischfabrik um die Ecke.
+[ASM4_9]
+~r~Die Zielperson hat das Flugzeug bestiegen!
-[MEA1_D]
-Ich hab Geldsorgen, aber wer hat die nicht, was?
+[ASM4_11]
+~r~Die Zielperson hat dich gesehen! Der Deal ist geplatzt!
-[MEA1_E]
-Ich treff mich später mit meinem Banker.
+[ASM4_13]
+~g~Er hat dich bemerkt und flieht. Schalte ihn aus und hol dir den Aktenkoffer!
-[MEA1_F]
-Das ist ein linker Säger, der mir dauernd die Kreditraten raufsetzt, um sich 'ne Scheibe abzuschneiden.
+[ASM4_14]
+~g~Der Distanz-Balken am oberen rechten Bildschirmrand zeigt dir, wie nahe du der Zielperson bist. Lass ihn nicht voll werden, sonst sieht sie dich.
-[MEA1_G]
-Nimm mein Auto, hol ihn ab und bring ihn hierher.
+[ASM_5]
+ATTENTÄTERMISSION 5
-[MEA1_H]
-Ich habe eine kleine Überraschung für diesen Blutsauger!!
+[KICK]
+KICKSTART
-[MEA2_A]
-Ich hab Diebe angeheuert, um in meine Wohnung einzubrechen.
+[KICK1_3]
+~g~Anzahl, wie oft der Fuß abgesetzt wurde: ~1~
-[MEA2_C]
-Jetzt drohen diese Dreckskerle, sie erzählen alles der Versicherung,
+[KICK1_4]
+~g~Zeitstrafe: ~1~ Sekunden
-[MEA2_D]
-wenn ich sie nicht beteilige.
+[BANK]
+BANK-MISSIONEN
-[MEA2_E]
-Ist das zu fassen?
+[BANK1]
+BANK-MISSION 1
-[MEA2_F]
-Ich hab einen Wagen innerhalb der Fabrik abgestellt.
+[BANK2]
+BANK-MISSION 2
-[MEA2_G]
-Hol damit die Kerle in ihrem Revier im Rotlichtbezirk ab.
+[BJM2_21]
+~g~Triff so viele Ziele als möglich, solange deine Munition reicht.
-[MEA2_H]
-Bring sie in die Fabrik, damit ich ihnen meinen Standpunkt klarmachen kann.
+[BANK3]
+BANK-MISSION 3
-[MEA3_A]
-Wenn nicht bald ein Haufen Geld ins Haus kommt, gehe ich pleite.
+[BJM3_1]
+~g~Besorg dir ein schnelles Auto und fahre an den Start.
-[MEA3_B]
-Meine Frau hat eine Versicherung, aber mir hat sie immer nur das Geld aus der Tasche gezogen.
+[BNK4_2A]
+Die Mechaniker haben das Baby super hergerichtet.
-[MEA3_C]
-Ich hab ein Auto am gewohnten Ort abgestellt.
+[BNK4_3G]
+Oh, Mist, jetzt haben wir die Cops am Hals!
-[MEA3_D]
-Hol damit meine Frau vom Classic Nails Studio ab und bring sie in die Fabrik.
+[BNK4_3H]
+Und wir sind noch nicht mal da.
-[MEA4_A]
-Mist, ich steck in der Klemme!
+[BNK4_3K]
+Also, erst mal müssen wir die Cops abschütteln...
-[MEA4_B]
-Meine Frau hatte was mit einem Typen, dem ich Geld schulde.
+[BNK4_3L]
+Großer Gott, Tommy, willst du uns alle umbringen?!
-[MEA4_C]
-Der ist jetzt ziemlich sauer und will sich rächen!
+[BNK4_3N]
+Alles, was ich gern habe, geht kaputt!
-[MEA4_E]
-Der denkt, er kann mich erpressen...
+[BNK4_26]
+Verdammt! Da sind sie schon!
-[MEA4_F]
-aber ich glaube eher,
+[BNK4_32]
+Spreng die Schließfächer mit Sprengstoff auf.
-[MEA4_G]
-dass auch dieser gute Mann als Hundefutter enden wird.
+[BNK4_36]
+Wo ist Cam?
-[WELCOME]
-WILLKOMMEN IN
+[BNK4_37]
+In der Hölle.
-[HM1_2]
-~g~Besorg dir ein Fahrzeug. Beachte: Hier zählt nur die Uzi!
+[BNK4_38]
+Das ist der letzte! LOS! LOS! LOS!
-[HELP8_B]
-Drücke die ~h~~k~~PED_SNIPER_ZOOM_IN~-Taste~w~ zum ~h~Heranzoomen~w~ mit dem Gewehr, und die ~h~~k~~PED_SNIPER_ZOOM_OUT~-Taste~w~ zum ~h~Wegzoomen~w~.
+[BNK_39]
+Shit! Wo bleibt Hilary?
-[LRQC_1]
-Asuka und ich haben was zu besprechen.
+[BK4_40A]
+Ich werd was für seine Verlustängste tun!
-[LRQC_2]
-Fahr doch ein bisschen durch die Gegend.
+[BNK4_42]
+Hey, Jungs! Los, rein! Ich geb euch Deckung!
-[LRQC_3]
-Du wirst einen Unterschlupf brauchen.
+[BNK4_43]
+Ich hab alles im Griff! FAHR!
-[LRQC_4]
-Am Rand von Belleville ist ein Lagerhaus. Das könnte was für dich sein.
+[BNK4_44]
+Geschafft! Wir sind reich! REICH!
-[LRQC_5]
-Komm wieder hierher, wenn du fertig bist.
+[BNK4_45]
+Ein Jammer, dass Cam es nicht gepackt hat. Er war 'n guter Kerl.
-[LRQC_6]
-Dann können wir uns ein bisschen unterhalten.
+[BNK4_46]
+Ja. Andererseits, so bleibt mehr für uns!
-[JM6_5]
-~g~Du brauchst einen Fluchtwagen, du Idiot!
+[BNK4_47]
+Sehr richtig! YEEEEHAAAH!
-[JM2_F]
-Wenn du 'ne Knarre brauchst, geh zum Hintereingang vom AmmuNation gegenüber der U-Bahn.
+[BNK4_48]
+Tommy, eine Massage gefällig?
-[LOVE4_7]
-~g~Es gibt einen Bauhof auf Staunton Island. Vielleicht haben sie das Päckchen dorthin gebracht.
+[BNK4_49]
+Hi, Mercedes. Ja, ich bin ein bisschen verspannt...
-[LOVE4_8]
-~g~Du brauchst ein Auto, um die Garage zu öffnen.
+[BNK450A]
+Was hab ich gesagt, Tommy? Korrupte Bullen müssen sich vorsehen, wenn Kent Paul in der Stadt ist.
-[TSCORE]
-EINKÜNFTE: $~1~
+[BNK450B]
+Komm, gib mir 'nen größeren Batzen ab. Na komm. Ich brauch neue Klamotten.
-[AM1_9]
-~r~Salvatore hat sich in Luigis Club abgesetzt!
+[BNK4_51]
+Ich finde, du siehst ok aus.
-[AM1_6]
-~g~Wenn du vor Luigis Club rumhängst, bemerken dich die Mafiosi!
+[KENT]
+KENT PAUL-MISSIONEN
-[TM2_3]
-~g~Das ist eine Falle! Nimm sie dir alle vor!
+[KENT1]
+KENT PAUL-MISSION 1
-[FM4_1]
-Hier Maria. Das mit dem Wagen ist eine Falle! Komm zu dem Steg südlich der Callahan Bridge.
+[COUNT]
+FÄLSCHER-MISSIONEN
-[JM1_7]
-~g~Mach die Wagentür zu, sonst merkt er was!
+[COUNT1]
+FÄLSCHER-MISSION 1
-[KM5_1]
-~g~DEALER ERLEDIGT!!
+[COUNT2]
+FÄLSCHER-MISSION 2
-[KM5_6]
-~g~Du musst mind. 8 Yardie Dealer außer Gefecht setzen.
+[BIKE]
+DIE BIKER GANG-MISSIONEN
-[KM5_7]
-~g~Beeilung! Sobald sie ihr SPANK verhökert haben, verschwinden sie wieder.
+[BIKE1]
+BIKER-MISSION 1
-[RM3_8]
-~r~Dieser Wagen dient nur zur Ablenkung!!
+[BIKE2]
+BIKER-MISSION 2
-[LM3_8]
-Hi, ich bin Joey.
+[BIKE3]
+BIKER-MISSION 3
-[LM3_9]
-Luigi sagt, du bist verlässlich. Also komm später wieder.
+[GOAWAY1]
+Komm wieder, wenn du die Haiti-Gang-Missionen abgeschlossen hast.
-[KM3_5]
-~g~Drück die Hupe, damit der Deal in Gang kommt.
+[HAIT]
+DIE HAITI-GANG-MISSIONEN
-[LOVE7]
-LOVES VERSCHWINDEN
+[HAIT1]
+HAITI-MISSION 1
-[LOVE2_5]
-~g~Auftrag erledigt. Verschwinde aus Newport und dann weg mit dem Wagen!
+[HAIT2]
+HAITI-MISSION 2
-[AS2_11]
-~g~~1~ VON 9!
+[HAIT3]
+HAITI-MISSION 3
-[GARAGE1]
-~g~Steig aus und geh nach draußen.
+[HAM3_6]
+~g~Verwende das Präzisionsgewehr, das ich für dich besorgt habe.
-[KM3_11]
-~g~Das Kartell wurde angegriffen. Die Aktentasche wurde nicht sichergestellt.
+[ROCK]
+DIE ROCKBAND-GANG-MISSIONEN
-[KM3_12]
-~g~Nimm dir sämtliche Kolumbianer vor, zerstöre die Fahrzeuge und stell die Aktentasche sicher.
+[ROK1_4]
+~g~Ok, ich glaube, das ist es, was du suchst...
-[KM3_13]
-~g~Bring die Aktentasche ins Casino.
+[ROK1_1E]
+~g~Das kostet mehr als du hast!
-[RM5_6]
-~g~Er ist abgehauen! Zerstöre seine Panzerung mit einem Auto oder einer Explosion!!
+[ROK1_1F]
+~g~Komm wieder, wenn du die Kohle hast.
-[PBOAT_1] { re3 change }
-Drücke die ~h~~k~~VEHICLE_FIREWEAPON~-Taste~w~, um die Bordkanonen abzufeuern.
+[RBM2_6]
+~g~Wow! Die ist 'n Kerl! Halt ihn auf!
-[PBOAT_2] { re3 change }
-Drücke die ~h~~k~~VEHICLE_FIREWEAPON~-Taste~w~, um die Bordkanonen abzufeuern.
+[ROCK3]
+ROCKBAND-MISSION 3
-[DIAB1_B]
-Hier El Burro, von den Diablos.
+[ROK3_6D]
+~r~und IHR UND EUER KOPFPUTZ mit dazu!
-[DIAB1_D]
-Du bist neu in Liberty, aber du hast bereits eine guten Ruf auf der Straße.
+[ROK3_40]
+Neben dem Kühler für die Babynahrung?
-[DIAB1_E]
-Bei der alten Schulhalle nahe der Callahan Bridge findet ein Rennen statt.
+[RBM3_5]
+~g~Bring Love Fist zu ihrem Auftritt.
-[DIAB1_F]
-Besorg dir 'nen fahrbaren Untersatz. Wer als erster alle Checkpoints abfährt, ist Sieger.
+[CUBANM]
+DIE KUBA-GANG-MISSIONEN
-[HM2_1] { re3 change }
-Zerstöre die gepanzerten Fahrzeuge mit den Buggies. Zur Zündung drücke die ~h~~k~~VEHICLE_FIREWEAPON~-Taste~w~.
+[CUBAN1]
+KUBA-MISSION 1
-[HM2_1A] { re3 change }
-Zerstöre die gepanzerten Fahrzeuge mit den Buggies. Zur Zündung drücke die ~h~~k~~VEHICLE_FIREWEAPON~-Taste~w~.
+[CUBAN2]
+KUBA-MISSION 2
-[HM2_2]
-~r~Du hast nicht alle gepanzerten Fahrzeuge zerstört!
+[CUB2_10]
+~r~Du sollst Haitianer ausschalten, keine Kubaner!
-[HM2_6]
-~g~Gepanzertes Fahrzeug zerstört!
+[CUBAN3]
+KUBA-MISSION 3
-[RM3_A]
-Ich kenne einen wichtigen Mann in der Stadt, mit
+[CUBAN4]
+KUBA-MISSION 4
-[RM3_H]
-sagen wir mal, einem Sinn für's Exotische und dem nötigen Kleingeld dafür.
+[CUB4_04]
+~r~Du hast die Basis alarmiert. Jetzt kommen wir niemals rein!
-[RM3_B]
-Er steht unter Anklage und der Staatsanwalt hat einige ziemlich peinliche Fotos von ihm
+[CUB4_05]
+~r~Du solltest doch im Auto bleiben. Jetzt lassen sie uns niemals rein.
-[RM3_C]
-auf einer Friedhofsparty oder so.
+[CUB4_25]
+Okay, los geht's.
-[LOVE6_A]
-Kleine Lektion in Sachen Business, mein Freund:
+[PROT]
+SCHUTZGELD-MISSIONEN
-[LOVE6_E]
-Hast du eine hochinteressante Ware, wird Gott und die Welt sie dir abjagen wollen...
+[PRO1_02]
+~g~Verlasse das Einkaufszentrum.
-[LOVE6_C]
-Spezialeinheiten haben die Gegend um meinen Geschäftsfreund und das Päckchen abgeriegelt.
+[PRO3_06]
+~g~Häng die Cops ab.
-[LOVE6_D]
-Mach, dass du hinkommst, nimm den Transporter und lenk sie ab.
+[PORN]
+PORNO-MISSIONEN
-[LOVE6_F]
-Beschäftige die Typen, damit er sich absetzen kann.
+[PORN1]
+PORNO-MISSION 1
-[AM3_C]
-Vermutlich ist er in der Bucht draußen, während du dies liest. Nimm mein Boot und mach seiner Karriere ein Ende!
+[POR1_03]
+~r~Candy ist erledigt!
-[FESZ_UC]
-ABBRECHEN
+[PORN2]
+PORNO-MISSION 2
-[FEDS_SM]
-L1, R1-MENÜ WECHSELN
+[PORN3]
+PORNO-MISSION 3
-[FEDS_AS]
-;=-AUSWAHL ÄNDERN
+[POR3_18]
+Man hat dich bemerkt!
-[FEDSAS2]
-<>-AUSWAHL ÄNDERN
+[PORN4]
+PORNO-MISSON 4
-[FEDS_SS]
-L1, R1-AUSWAHL ÄNDERN
+[POR4_04]
+~g~Die Büros liegen auf der anderen Seite dieses Tors.
-[FEDSSC1]
-;-SCHNELLER BILDLAUF
+[PHIL]
+PHIL-MISSIONEN
-[FEDSSC2]
-=-BILDLAUF STOP
+[PHIL1]
+PHIL-MISSION 1
-[MEA2_3]
-~g~Bring das Auto zurück zur Fabrik.
+[PHIL2]
+PHIL-MISSION 2
-[RM1_3]
-~r~McAffrey ist entkommen!
+[PIZ1_A]
+PIZZABOTEN-MISSION
-[RM1_4]
-~g~Du hast alle Granaten verbraucht! Hol neue im AmmuNation!
+[PIZ1_03]
+~g~Fahr zurück zum Pizza-Service für weitere Bestellungen.
-[RM1_5]
-~g~Zurück! Zünde die sichere Wohnung an!
+[PIZ1_04]
+~g~Hier sind die neuen Bestellungen.
-[RM6_4]
-~g~Du musst zu der Garage und Rays Auto mit den Waffen holen.
+[PIZ1_10]
+Drücke die ~h~R3-Taste~w~, um die Pizza-Missionen abzubrechen.
-[RM6_5]
-~g~Die Brücke wird von der CIA überwacht. Such dir eine andere Route.
+[CNTBUY1]
+Druckerei gekauft: $ ~1~
-[HM2_F]
-Und zerstöre alle ihre gepanzerten Wagen.
+[CARBUY]
+Autohaus gekauft: $ ~1~
-[HM_4]
-'GOLDRAUSCH'
+[PORNBUY]
+Filmstudio gekauft: $ ~1~
-[MEA2_B5]
-TEXT NO LONGER NEEDED
+[ICEBUY]
+Eiscremefabrik gekauft: $ ~1~
-[MEA1_B5]
-TEXT NO LONGER NEEDED
+[TAXIBUY]
+Taxiunternehmen gekauft: $ ~1~
-[MEA3_B5]
-TEXT NO LONGER NEEDED
+[BANKBUY]
+Malibu Club gekauft: $ ~1~
-[MEA4_B7]
-aber wenn du in mein Büro kommst, könnte ich...
+[BOATBUY]
+Bootswerft gekauft: $ ~1~
-[MEA3_B4]
-Marty will mich sehen? Das muss aber schnell gehen, ich hab nämlich einen Friseurtermin.
+[PRNT_NO]
+Zurzeit kannst du die Druckerei nicht kaufen. Komm später wieder.
-[KM3_7]
-Das ist eine Falle der Yakuza, Mann!
+[CAR_NO]
+Zurzeit kannst du das Autohaus nicht kaufen. Komm später wieder.
-[FES_LOF]
-Laden fehlgeschlagen.
+[PORN_NO]
+Zurzeit kannst du das Filmstudio nicht kaufen. Komm später wieder.
-[P1INSA]
-Memory Card (PS2) in MEMORY CARD-Steckplatz 1: ~1~K freier Speicherplatz. Erforderlich: ~1~K.
+[ICE_NO]
+Zurzeit kannst du die Eiscremefabrik nicht kaufen. Komm später wieder.
-[P1INSN]
-Memory Card (PS2) in MEMORY CARD-Steckplatz 1: Kein freier Speicherplatz. Bitte einige Dateien löschen.
+[TAXI_NO]
+Zurzeit kannst du das Taxiunternehmen nicht kaufen. Komm später wieder.
-[FES_SLO]
-DATEI
+[BANK_NO]
+Zurzeit kannst du den Malibu Club nicht kaufen. Komm später wieder.
-[FES_ISC]
-IST BESCHÄDIGT
+[BOAT_NO]
+Zurzeit kannst du die Bootswerft nicht kaufen. Komm später wieder.
-[FESZ_TI]
-Z1 SPEICHERN
+[PRNT_R3]
+Drücke R3, um die Druckerei zu kaufen. Preis: $~1~
-[FESZ_SA]
-Spiel speichern
+[CAR_R3]
+Drücke R3, um das Autohaus zu kaufen. Preis: $~1~
-[P1NOIN]
-Keine Memory Card (PS2) in MEMORY CARD-Steckplatz 1
+[PORN_R3]
+Drücke R3, um das Filmstudio zu kaufen. Preis: $~1~
-[P1INSE]
-Memory Card (PS2) in MEMORY CARD-Steckplatz 1 vorhanden
+[ICE_R3]
+Drücke R3, um die Eiscremefabrik zu kaufen. Preis: $~1~
-[MC_LDFL]
-Laden fehlgeschlagen!
+[TAXI_R3]
+Drücke R3, um das Taxiunternehmen zu kaufen. Preis: $~1~
-[MC_NWRE]
-Spiel wird neu gestartet
+[BANK_R3]
+Drücke R3, um den Malibu Club zu kaufen. Preis: $~1~
-[LOVE6_3]
-~g~Du hast ~1~ Sekunden, um zu dem Securicar zurückzukehren, bevor die Mission fehlschlägt.
+[BOAT_R3]
+Drücke R3, um die Bootswerft zu kaufen. Preis: $~1~
-[LOVE6_4]
-~r~Du hast den falschen Securicar abgehängt!
+[COL2_6]
+Keine Bewegung, amerikanisches Imperialistenschwein!
-[HELP1]
-Halte in der Mitte der blauen Markierung.
+[COL2_6B]
+Das ist Eigentum des französischen Staates.
-[HELP12]
-Geh ins Zentrum der blauen Markierung, um eine Mission zu starten.
+[COL2_6C]
+Her damit!
-[HJSTAT]
-Distanz: ~1~.~1~m Höhe: ~1~.~1~m Saltos: ~1~ Drehungen: ~1~_
+[COL3_A]
+Thomas, schön, dass Sie da sind.
-[HJSTATW]
-Distanz: ~1~.~1~m Höhe: ~1~.~1~m Saltos: ~1~ Drehungen: ~1~_ Und was für eine Landung!
+[COL3_B]
+Verzeihen Sie, dass ich direkt zum Geschäftlichen komme.
-[DIAB1_5]
-ZEIT:
+[COL3_C]
+Diaz bat mich, eine kleine Transaktion für ihn zu überwachen.
-[LOVE3_4]
-~r~Du hast das Flugzeug zerstört!
+[COL3_D]
+Hoffentlich läuft es diesmal besser als zuletzt.
-[F_FAIL1]
-Feuerwehr -Mission beendet
+[COL3_E]
+Deshalb wende ich mich ja an Sie, mein Freund.
-[F_CANC]
-~r~Feuerwehr -Mission abgebrochen!
+[COL3_F]
+Ich habe im Parkhaus ein wenig Artillerie deponiert.
-[F_EXTIN]
-FEUER:
+[COL3_G]
+Holen Sie sich die und beschützen Sie Diaz' Männer bei der Übergabe.
-[A_COMP1]
-Krankenwagen Missionen abgeschlossen!
+[COL4_2]
+Ich weiß nicht, Sir!
-[A_CANC]
-~r~Krankenwagen Mission abgebrochen!
+[COL4_5]
+Sir, zu Befehl, Sir!
-[A_COMP3]
-Krankenwagen Missionen abgeschlossen! Du wirst beim Laufen nie ermüden!
+[COL4_10]
+Gehen wir ein paar Donuts essen.
-[ATUTOR]
-Drücke die ~h~~k~~TOGGLE_SUBMISSIONS~-Taste~w~, um Krankenwagen Missionen an- oder abzuschalten.
+[COL4_16]
+Fahrzeug wird weggeschafft, Sir!
-[ATUTOR3]
-Drücke die ~h~~k~~TOGGLE_SUBMISSIONS~-Taste~w~, um Krankenwagen Missionen an- oder abzuschalten.
+[COL4_25]
+Selbstzerstörung des Fahrzeugs eingeleitet!
-[ALEVEL]
-Krankenwagen Mission Level ~1~
+[COL5_6]
+Mercedes - dieses Kind bringt mich noch ins Grab.
-[A_FAIL1]
-Krankenwagen Mission beendet
+[COL5_8]
+Verdammte Bande!
-[FEST_HA]
-Höchster Krankenwagen Missions Level
+[COL5_5]
+Nehmt das, Franzosenschweine!
-[A_SAVES]
-GERETTETE MENSCHEN: ~1~
+[CNT2_1]
+Macht ihn fertig!
-[C_KILLS]
-KRIMINELLE: ~1~
+[CNT2_2]
+Hol die Platten!
-[HM1_B]
-Ich hab 'n Problem. Die wollen mich verscheißern.
+[CNT2_3]
+Beschütze den Kurier!
-[AM2_A]
-Sehr erfreulich, dass Salvatore nicht mehr unter uns weilt.
+[FINKILL]
+Ok, Jungs, macht ihn fertig!
-[AM2_A2]
-Du bist ein effizienter Mann - das gefällt mir.
+[FIN_1A]
+Komm her, du hinterhältiger Dreckskerl!
-[AM2_B]
-Das ist mein Bruder Kenji.
+[FIN_1B]
+Jetzt bist du fällig, du mieser Verräter!
-[AM2_C]
-Asuka hat einen kleinen Job für dich, aber wenn du fertig bist, komm in mein Casino, dann reden wir.
+[FIN_1C]
+Das wird dein letzter 'Dance', Lance Vance!
-[AM2_D]
-Typisch Kenji, immer will er mit meinen Spielsachen spielen.
+[FIN_2B]
+Ach, wirklich?
-[AM2_E]
-Mein Spitzel bei der Polizei hat mir gesteckt, dass die Mafia unsere Aktivitäten im Auge behält.
+[FIN_2C]
+Der dumme Spruch war schon im Kindergarten alt!
-[AM2_E2]
-Sie wollen dich aufstöbern.
+[FIN_3]
+Keiner da, um dich rauszuhauen, diesmal, hä, Tommy?
-[AM2_F]
-Wir müssen unsere Operationen ruhen lassen, bis wir ihnen das Handwerk gelegt haben.
+[FIN_4]
+Du bist am Ende, Tommy.
-[AM2_G]
-Zieh die Kerle aus dem Verkehr und mach dieser Vendetta ein für alle mal ein Ende.
+[FIN_5]
+Du hast dich auf die falsche Seite geschlagen, Lance...
-[F_START]
-~g~Brennendes Fahrzeug in der Gegend von ~a~ gemeldet. Lösche den Brand.
+[FIN_6]
+Sonny ist oben am Safe mit MEINEM Geld...
-[AM4_1A]
-Komm zu dem Fernsprecher im West Belleville Park.
+[FIN_10]
+Sonny? SONNY! Jetzt bist du fällig!
-[AM4_1B]
-Komm zu dem Fernsprecher auf dem Liberty Campus.
+[FIN_11A]
+Du hast mir 15 Jahre gestohlen, Sonny.
-[AM4_1C]
-Komm zu dem Fernsprecher im South Belleville Park.
+[FIN_11B]
+Und das wirst du mir jetzt büßen!
-[AM4_1D]
-Wir treffen uns im Toilettenhäuschen im Park.
+[FIN_12A]
+Du kapierst es immer noch nicht, oder?
-[HJSTATF]
-Distanz: ~1~Fuß Höhe: ~1~Fuß Saltos: ~1~ Drehungen: ~1~_
+[FIN_12B]
+Dein Arsch gehört mir, Tommy.
-[HJSTAWF]
-Distanz: ~1~Fuß Höhe: ~1~Fuß Saltos: ~1~ Drehungen: ~1~_ Und was für eine Landung!
+[FIN_12C]
+Diese 15 Jahre hast du anstelle von mir abgesessen!
-[HM1_F]
-Aber pass auf. Es werden Jacks da sein, und die werden denken, du willst auch ihnen ans Leder!
+[FIN_13]
+Schnappt ihn euch. Er hat nie was begriffen.
-[HM1_D]
-Sie nennen sich 'Nines' und ihre Farbe ist 'Lila'. Und jeder Tag im Zeichen dieser Farbe...
+[RACES_4]
+3
-[HM1_G]
-ist ein Tag, an dem die Jacks schlecht aussehen.
+[RACES_5]
+2
-[MEA2_B]
-Und stiehl ein paar Sachen, damit ich die Versicherung kassieren kann.
+[RACES_6]
+1
-[TM3_H]
-~w~Das hast du gut gemacht vorhin, wirklich gut, mein Junge.
+[RACES_7]
+LOS!
-[TM3_I]
-~w~Komm, wir stellen dich dem Don vor.
+[RACES_9]
+Zeit: ~1~:~1~
-[TM3_J]
-~w~Heeyyy! Luigi!
+[RACES]
+ZEIT:
-[TM3_K]
-~w~Meine Girls fragen andauernd nach dir, Salvatore. Du warst so lange nicht mehr bei uns.
+[RACES17]
+Neue Bestzeit: ~1~:~1~
-[TM3_L]
-~w~Sag ihnen, wenn diese lästige Geschichte hier vorbei ist,
+[RACES18]
+PREISGELD: $~1~
-[TM3_M]
-~w~gehen wir alle in den Club und feiern, okay?
+[RACES20]
+Neue Bestzeit: ~1~:0~1~
-[TM3_N]
-~w~Ah, mein Junge!
+[RACES21]
+Zeit: ~1~:0~1~
-[TM3_N2]
-~w~Hallo, Paps.
+[RCH1_1]
+~g~Benutze den ferngesteuerten Helikopter, den RC Raider, um die Checkpoints zu PASSIEREN.
-[TM3_O]
-~w~Hast du endlich eine Frau gefunden?
+[RCH1_2]
+~g~Die CHECKPOINTS sind überall auf dem Flughafen verteilt.
-[TM3_P]
-~w~Hey, Deine Mutter - Gott hab sie selig - würde sich im Grab umdrehen,
+[RCH1_3]
+~g~Du hast ~c~8 MINUTEN~g~, um alle ~c~20 zu passieren!
-[TM3_Q]
-~w~wenn du keine abkriegen würdest.
+[RCH1_5]
+Zeit
-[TM3_R]
-~w~Ich weiß, Paps, ich arbeite dran.
+[RCRC1_2]
+~g~Begib dich zur Startlinie!
-[TM3_S]
-~w~TONI! Wie geht's deiner Mamma?
+[RCRC1_4]
+~g~3
-[TM3_T]
-~w~Sie ist eine großartige Frau! Stark. Florentinerin eben.
+[RCRC1_5]
+~g~2
-[TM3_U]
-~w~Es geht ihr gut. Sehr gut.
+[RCRC1_6]
+~g~1
-[TM3_V]
-~w~Hervorragend. Okay, geht schon mal vor, ich hab was mit unserem neuen Freund hier zu bereden.
+[RCRC1_7]
+~g~LOS!
-[TM3_W]
-~w~Ich sehe goldene Zeiten auf dich zukommen, mein Junge...
+[RCRC1_8]
+~g~Absolvierte Zeit: ~1~ Sekunden
-[RM1_A]
-Dieser McAffrey! Der hat mehr Bestechungsgeld kassiert als jeder andere.
+[RCPL1_1]
+~g~Liefere dir mit 3 anderen RC Barons ein CHECKPOINT-RENNEN.
-[RM1_B]
-Jetzt denkt er, er wird ehrenhaft entlassen, wenn er als Kronzeuge aussagt.
+[RCPL1_2]
+~g~Du musst durch die ~o~MITTLERE MARKIERUNG ~g~hindurch, um einen Checkpoint zu passieren.
-[RM1_C]
-Er ist einfach ein Verräter.
+[RCPL1_3]
+~g~Begib dich zur Startlinie!
-[RM4_B]
-Wir müssen ihn zum Schweigen bringen - für immer.
+[ICC1_O]
+Was ist denn in Sie gefahren?
-[RM4_E]
-Er soll bei den Fischen schlafen, statt sie zu essen.
+[FEA_2SP]
+2 Boxen
-[LOVE3_B]
-Beim Landeanflug auf den Flughafen wird ein kleines Flugzeug die Bucht überfliegen.
+[FEA_4SP]
+Mehr als 2 Boxen
-[LOVE4_D]
-Leider hat sich die Hafenbehörde die Maschine geschnappt und wollte sie auseinandernehmen,
+[FEA_EAR]
+Kopfhörer
-[LOVE4_H]
-bis ich das mit erheblichen Unkosten verhindert habe.
+[FEA_NAH]
+KEINE AUDIO HARDWARE
-[LOVE4_E]
-Fahr über die Brücke nach Shoreside Vale und dann zum Francis Int. Airport.
+[FET_APP]
+ÜBERNEHMEN
-[GTAB_A]
-Hey, schaffen wir das hier weg. Weiß der Teufel, was das ist.
+[FES_SKN]
+SKIN-NAME
-[GTAB_B]
-Aber da er's unbedingt haben will, muss es wohl was wert sein.
+[FES_DAT]
+DATUM
-[GTAB_C]
-Wer zum Teufel...?
+[FES_SET]
+Skin verwenden
-[GTAB_D]
-DU!
+[FET_DEF]
+Standard wiederherst.
-[GTAB_E]
-Hey, ganz ruhig, Amigo! De nada! De nada!
+[FESZ_QZ]
+Dieses Spiel wirklich speichern?
-[GTAB_F]
-Ich dachte, ich hätte dich erledigt!
+[FES_SCG]
+Laufendes Spiel speichern?
-[GTAB_G]
-Nicht schießen, Amigo! Kein Problem. Wir sind alle Freunde. Hier, nimm.
+[FES_LCG]
+Spiel laden und weiterspielen?
-[GTAB_H]
-Nicht so memmenhaft!
+[FEC_FIR]
+Feuern
-[GTAB_I]
-Wir haben keine Wahl, Baby!
+[FEC_NWE]
+Nächste Waffe
-[GTAB_J]
-Wir haben immer eine Wahl, du dämlicher Idiot!
+[FEC_PWE]
+Vorherige Waffe
-[GTAB_K]
-Sorry wegen dem abgedrehten Flittchen, Mann. Die sind doch alle gleich. Por favor?
+[FEC_FOR]
+Vorwärts
-[GTAB_L]
-Das Luder ist also entwischt.
+[FEC_BAC]
+Rückwärts
-[GTAB_M]
-Aber du hast mir einen Gefallen getan.
+[FEC_LEF]
+Links
-[GTAB_N]
-Du bist nicht der einzige, der eine Rechnung mit dem Kartell offen hat.
+[FEC_RIG]
+Rechts
-[GTAB_O]
-Dieser Wurm hat meinen Bruder auf dem Gewissen!
+[FEC_ZIN]
+Heranzoomen
-[GTAB_P]
-I hab nie einen Yakuza umgebracht!
+[FEC_ZOT]
+Hinauszoomen
-[GTAB_Q]
-Lügner! Wir alle haben den Kartell-Attentäter gesehen.
+[FEC_EEX]
+Ein-/Aussteigen
-[GTAB_R]
-Wir werden euch kolumbianische Hunde alle erledigen!
+[FEC_RAD]
+Radio
-[GTAB_S]
-Ich befasse mich mit unserem Freund. Mal sehen, was ich aus ihm rauskriege.
+[FEC_SUB]
+Spezialmission
-[GTAB_T]
-Komm später wieder. Ich werde deine Dienste brauchen.
+[FEC_CMR]
+Blickwinkel ändern
-[GTAB_U]
-Bitte, Amigo, lass mich nicht hier bei ihr! Die ist 'n Psycho! Amigo? Hey, AMIIIGO!!!...Aiiieeeeaaargghh!
+[FEC_JMP]
+Springen
-[LOVE5_A]
-Du bist eine sichere Bank. So etwas ist selten in diesen schlechten Zeiten.
+[FEC_SPN]
+Sprinten
-[KM3_1]
-~g~Das Kartell erwartet eine Yardie Gang. Klau einen Yardie-Wagen! Fahr nach Norden. In Newport fndest du einen.
+[FEC_HND]
+Handbremse
-[LOVE1_1]
-~g~Mit einem Wagen der Kolumbianer kommst du in ihren Unterschlupf rein. Im Norden, in Fort Staunton, findest du einen.
+[FEC_LOL]
+Nach links sehen
-[FM1_Q1]
-~w~Na, kleine Erfrischung gefällig? Ein bisschen SPANK?
+[FEC_LOR]
+Nach rechts sehen
-[FM1_R]
-~w~Hi, Chico. Nein, nur das übliche.
+[FEC_NTR]
+Nächstes Ziel
-[FM1_T]
-~w~Danke, Chico. Bis bald.
+[FEC_PTT]
+Vorheriges Ziel
-[FM1_W]
-~w~Okay, Fiffi, du passt hier auf den Wagen auf, ich geh ein bisschen abtanzen.
+[FEC_LBA]
+Nach hinten sehen
-[FM1_X]
-~w~Okay, Fiffi, lass uns 'nen Abgang machen. Huuh!
+[FEC_CEN]
+Kamera zentrieren
-[FM1_Q]
-~w~Hey, Maria! Meine Traumfrau!
+[FET_CCN]
+Classic
-[FM1_S1]
-~w~Vielleicht solltest du mal die Party in der Lagerhalle am Ostende von Atlantic Quays auschecken.
+[FET_SCN]
+Standard
-[FM1_U]
-~w~Gracias. Und viel Spaß. Ist gutes Zeug.
+[FET_CFT]
+ZU FUSS
-[FM1_V]
-~w~Na los, Fiffi, sehen wir uns mal die Party an!
+[FET_CCR]
+IN FAHRZEUG
-[FM1_SS]
-~r~SCANNER: ~g~4-5 an alle Einheiten: Assistieren Sie bei der Rauschgift-Razzia in Atlantic Quays...
+[FET_CAC]
+AKTION
-[LOVE6_B]
-Auch wenn kaum einer weiß, wie viel sie wirklich wert ist.
+[FEC_IBT]
+-
-[TM3_A1]
-~r~Joey ist hinüber!
+[FEC_MXO]
+MXB1
-[TM3_A2]
-~r~Joey und Luigi sind hinüber!
+[FEC_MXT]
+MXB2
-[TM3_A3]
-~r~Joey, Luigi und Toni sind hinüber!
+[FEC_UNB]
+NICHT BEL.
-[FM4_2]
-Hör zu, Salvatore denkt, ich betrüge ihn mit dir,
+[FEC_TFL]
+Links sehen + Geschütz L
-[FM4_3]
-da hat er dem Kartell deinen Kopf angeboten, um einen Deal mit denen zu machen.
+[FEC_TFR]
+Rechts sehen + Geschütz R
-[FM4_4]
-Das kann ich nicht zulassen. Das ist alles meine Schuld.
+[FEC_MWF]
+MAUSRAD AUFW.
-[FM4_4B]
-Ich hab ihm erzählt, dass wir uns gut verstehen.
+[FEC_MWB]
+MAUSRAD ABW.
-[FM4_5]
-Frag mich nicht wieso. Ich weiß es nicht.
+[FEC_ORR]
+oder
-[FM4_6]
-Auf Mafia-Gebiet bist du Freiwild, und ich muss auch abhauen.
+[FEC_NUS]
+NICHT VERWENDET
-[FM4_6B]
-Ich hab genug von all der Gewalt, all dem Blut.
+[FEC_LUD]
+Aufw. sehen
-[FM4_7]
-Das ist eine Freundin von mir, eine alte Freundin. Sie heißt Asuka. Ihr können wir trauen.
+[FEC_LDU]
+Abw. sehen
-[FM4_8]
-Kommt. Genug geredet.
+[FEC_CMP]
+COMBO: L+R SEHEN
-[FM4_9]
-Wir verschwinden lieber, bevor uns noch mehr hysterische Italiener unbedingt wiedersehen möchten.
+[LAW_1A]
+law_1a
-[CRED001]
-ROCKSTAR STUDIOS
+[LAW_1B]
+law_1b
-[CRED002]
-PRODUCER
+[LAW_2A]
+law_2a
-[CRED003]
-LESLIE BENZIES
+[LAW_2B]
+law_2b
-[CRED004]
-ART DIRECTOR
+[FEH_STA]
+STATISTIKEN
-[CRED005]
-AARON GARBUT
+[FEH_LOA]
+LADEN
-[CRED006]
-TECHNICAL DIRECTION
+[FEH_CON]
+STEUERUNG
-[CRED007]
-OBBE VERMEIJ
+[FEH_AUD]
+AUDIO
-[CRED008]
-ADAM FOWLER
+[FEH_DIS]
+ANZEIGE
-[CRED009]
-DESIGN
+[FEH_LAN]
+SPRACHE
-[CRED010]
-CRAIG FILSHIE
+[FEH_SGA]
+NEUES SPIEL STARTEN
-[CRED011]
-WILLIAM MILLS
+[FEO_CON]
+Controller-Setup
-[CRED012]
-CHRIS ROTHWELL
+[FEO_AUD]
+Audio-Setup
-[CRED013]
-JAMES WORRALL
+[FEO_DIS]
+Anzeigen-Setup
-[CRED014]
-WRITTEN BY
+[FEO_LAN]
+Sprachen-Setup
-[CRED015]
-JAMES WORRALL
+[FEO_PLA]
+Spieler-Setup
-[CRED016]
-PAUL KUROWSKI
+[FEA_OUT]
+Ausgabe
-[CRED017]
-DAN HOUSER
+[FEA_ST]
+Stereo
-[CRED018]
-CHARACTERS
+[FEA_DTS]
+DTS
-[CRED019]
-IAN MCQUE
+[FEA_RSS]
+Radiosender
-[CRED020]
-ANIMATION & DIRECTION
+[FEA_NON]
+RADIO AUS
-[CRED021]
-ALEX HORTON
+[FEA_FM0]
+WILDSTYLE
-[CRED022]
-LEE MONTGOMERY
+[FEA_FM1]
+FLASH FM
-[CRED023]
-AUTO DESIGN
+[FEA_FM2]
+KCHAT
-[CRED024]
-PAUL KUROWSKI
+[FEA_FM3]
+FEVER 105
-[CRED025]
-ARTISTS
+[FEA_FM4]
+VROCK
-[CRED026]
-KEIRAN BAILLIE
+[FEA_FM5]
+VCPR
-[CRED027]
-ADAM COCHRANE
+[FEA_FM7]
+EMOTION 98.3
-[CRED028]
-GARY MCADAM
+[FEA_FM8]
+WAVE 103
-[CRED029]
-MICHAEL PIRSO
+[FED_BRI]
+Helligkeit
-[CRED030]
-ANDREW SOOSAY
+[FED_TRA]
+Unschärfe-FX
-[CRED031]
-ALISDAIR WOOD
+[FED_SUB]
+Untertitel
-[CRED032]
-CODERS
+[FED_WIS]
+Breitbild
-[CRED033]
-ALAN CAMPBELL
+[FED_POS]
+Anzeige-Position
-[CRED034]
-MARK HANLON
+[FEP_RES]
+Fortsetzen
-[CRED035]
-ANDRZEJ MADAJCZYK
+[FEP_STG]
+Spiel starten
-[CRED036]
-ALEXANDER ROGER
+[FEP_STA]
+Statistiken
-[CRED037]
-GRAEME WILLIAMSON
+[FEP_BRI]
+Missionsinfos
-[CRED038]
-SCORE
+[FEP_OPT]
+Optionen
-[CRED039]
-CRAIG CONNER
+[FEP_QUI]
+Spiel beenden
-[CRED040]
-STUART ROSS
+[FES_LOA]
+Spiel laden
-[CRED041]
-SOUND DESIGN & MASTERING
+[FES_DEL]
+Spiel löschen
-[CRED042]
-ALLAN WALKER
+[FEC_CSU]
+Controller-Setup
-[CRED043]
-AUDIO PROGRAMMING
+[FEC_RED]
+Steuerung ändern
-[CRED044]
-RAYMOND USHER
+[FEC_MOU]
+Maus-Einstellg.
-[CRED045]
-TEST MANAGER
+[DISTGOL]
+Mit Golfwagen zurückgel. Entfernung (Meilen)
-[CRED046]
-CRAIG ARBUTHNOTT
+[DISTGOM]
+Mit Golfwagen zurückgel. Entfernung (Meter)
-[CRED047]
-LEAD TESTERS
+[ST_FAVR]
+Lieblings-Radiosender
-[CRED048]
-ANDY DUTHIE
+[ST_WSTR]
+Unbeliebtester Radiosender
-[CRED049]
-JOHN HAIME
+[ST_FAVV]
+Lieblingsfahrzeug
-[CRED050]
-NEIL CORBETT
+[ST_STAR]
+Anzahl angehäufter Fahndungssterne
-[CRD050A]
-TESTERS
+[ST_HEAD]
+Anzahl Köpfe
-[CRED051]
-GRAEME JENNINGS
+[ST_GANG]
+Unbeliebteste Gang
-[CRED052]
-DAVID MURDOCH
+[ST_STGN]
+Anzahl losgewordener Fahndungssterne
-[CRED053]
-DAVID BEDDOES
+[TYREPOP]
+Zerschossene Reifen
-[CRED054]
-EDWIN SMITH
+[TYRESLA]
+Aufgeschlitzte Reifen
-[CRED055]
-MARK FLETT
+[ST_BRK]
+Erledigte Gegner im Chaos-Derby
-[CRED056]
-MICHAEL SUTHERLAND
+[ST_LTBR]
+Längste Zeit im Chaos-Derby (Sekunden)
-[CRED057]
-TECHNICAL SUPPORT
+[ST_GNG1]
+Kubaner
-[CRED058]
-LORRAINE ROY
+[ST_GNG2]
+Haitianer
-[CRED059]
-CHRISTINE CHALMERS
+[ST_GNG3]
+Möchtegern-Gangster
-[CRED060]
-ROCKSTAR
+[ST_GNG4]
+Diaz' Gang
-[CRED061]
-EXECUTIVE PRODUCER
+[ST_GNG5]
+Sicherheitsbeamte
-[CRED062]
-SAM HOUSER
+[ST_GNG6]
+Biker-Gang
-[CRED063]
-PRODUCER
+[ST_GNG7]
+Vercetti-Gang
-[CRED064]
-DAN HOUSER
+[ST_GNG8]
+Golfer
-[CRED065]
-DIRECTOR OF DEVELOPMENT
+[FEA_FM6]
+ESPANTOSO
-[CRED066]
-JAMIE KING
+[ST_ASSI]
+Ausgeführte Attentätermissionen
-[CRED067]
-TECHNICAL PRODUCER
+[DISTBIK]
+Mit Motorrad zurückgel. Strecke (Meilen)
-[CRED068]
-GARY J. FOREMAN
+[DISTBIM]
+Mit Motorrad zurückgel. Strecke (Meter)
-[CRED069]
-ASSOCIATE PRODUCER
+[HOTEL]
+Ocean View Hotel
-[CRED070]
-JEREMY POPE
+[KICK1_9]
+VERBLEIBENDE CHECKPOINTS:
-[CRED071]
-MUSIC SUPERVISOR
+[FIN_B6]
+Du hast nicht genug Geld, um diese Mission zu beginnen.
-[CRED072]
-TERRY DONOVAN
+[TEX3_9]
+~g~Steuere den Helikopter über eine Bombe, um sie aufzunehmen.
-[CRED073]
-ROCKSTAR PRODUCTION TEAM
+[HELP22]
+Begib dich zu dem grünen Haus-Symbol auf dem Radar.
-[CRED074]
-TERRY DONOVAN
+[FES_SSC]
+Daten wurden gespeichert. Weiter mit OK.
-[CRED075]
-JENNIFER KOLBE
+[FES_DSC]
+Daten wurden gelöscht. Weiter mit OK.
-[CRED076]
-JENEFER GROSS
+[FESZ_QC]
+Dieses beschädigte Spiel überschreiben?
-[CRED077]
-LAURA PATERSON
+[FES_CHE]
+Achtung! Ein oder mehrere Cheats sind aktiviert, dies kann sich auf die Speicherung auswirken. Es wird empfohlen, dieses Spiel nicht zu speichern.
-[CRED078]
-JEFF CASTANEDA
+[FET_SG]
+SPIEL SPEICHERN
-[CRED079]
-CHRIS CARRO
+[FEH_BRI]
+MISSIONSINFO
-[CRED080]
-ADAM TEDMAN
+[FEH_MAP]
+KARTE
-[CRED081]
-JUNG KWAK
+[FEM_OK]
+OK
-[CRED082]
-BRIAN WOOD
+[FEC_CRO]
+Ducken
-[CRED083]
-PAUL YEATES
+[FEC_CR3]
+Ducken (L3-Taste)
-[CRED084]
-STANTON SARJEANT
+[FEC_SMT]
+Spezialmission
-[CRED085]
-VP OF MARKETING
+[FEC_SM3]
+Spezialmission (R3-Taste)
-[CRED086]
-TERRY DONOVAN
+[FEC_RSC]
+Radiosender
-[CRED087]
-TECHNICAL COORDINATOR
+[ST_PR01]
+Flieger
-[CRED088]
-BRANDON ROSE
+[ST_PR02]
+Luftwaffensoldat
-[CRED089]
-QA MANAGER
+[ST_PR03]
+Gefreiter
-[CRED090]
-JEFF ROSA
+[ST_PR04]
+Unteroffizier
-[CRED091]
-LEAD ANALYST
+[ST_PR05]
+Leutnant
-[CRED092]
-ADAM DAVIDSON
+[ST_PR06]
+Stabsunteroffizier
-[CRED093]
-GAME ANALYST
+[ST_PR07]
+Hauptmann
-[CRED094]
-RICHARD HUIE
+[ST_PR08]
+Könner
-[CRED095]
-TEST TEAM
+[ST_PR09]
+Profi
-[CRED096]
-LANCE WILLIAMS
+[ST_PR10]
+Roter Baron
-[CRED097]
-JOE GREENE
+[ST_PR11]
+Wildgans
-[CRED098]
-BRIAN PLANER
+[ST_PR12]
+Viper
-[CRED099]
-OSWALD GREENE
+[ST_PR13]
+Falke
-[CRED100]
-LIBERTY TREE EDITORIAL
+[ST_PR14]
+Adler
-[CRED101]
-JAMES WORRALL
+[ST_PR15]
+Blitz
-[CRED102]
-DAN HOUSER
+[ST_PR16]
+Tornado
-[CRED103]
-ADAM TEDMAN
+[ST_PR17]
+Taifun
-[CRED104]
-PAUL YEATES
+[ST_PR18]
+Luftwaffengeneral
-[CRED105]
-JENEFER GROSS
+[ST_PR19]
+Ass
-[CRED106]
-LAURA PATERSON
+[FET_LG]
+SPIEL LADEN
-[CRED107]
-CUT-SCENES
+[CAR_EXP]
+Straßenfahrzeuge zerstört
-[CRED108]
-SCRIPT BY DAN HOUSER AND JAMES WORRALL
+[BOA_EXP]
+Boote zerstört
-[CRED109]
-AUDIO DIRECTED BY DAN HOUSER
+[HEL_DST]
+Flugzeuge & Helikopter zerstört
-[CRED110]
-AUDIO PRODUCED BY RENAUD SEBBANE
+[STFT_01]
+Schnellste Zeit bei 'Wheels of Steels'
-[CRED111]
-CAST
+[STFT_02]
+Schnellste Zeit bei 'Der Fahrer'
-[CRED112]
-FRANK VINCENT AS SALVATORE LEONE
+[STFT_03]
+Schnellste Zeit auf Geländemotorradstrecke
-[CRED113]
-JOE PANTOLIANO AS LUIGI GOTERELLI
+[STFT_04]
+Schnellste Zeit bei Modellflugzeug-Rennen
-[CRED114]
-MICHAEL MADSEN AS TONI CIPRIANI
+[STFT_05]
+Schnellste Zeit mit den ferngesteuerten Autos
-[CRED115]
-MICHAEL RAPAPORT AS JOEY LEONE
+[STFT_06]
+Schnellste Zeit bei Helikopter-Rennen
-[CRED116]
-DEBBI MAZAR AS MARIA
+[STFT_07]
+Schnellste Zeit bei 'Todeskaracho'
-[CRED117]
-KYLE MACLACHLAN AS DONALD LOVE
+[STFT_08]
+Schnellste Zeit bei 'Ocean Drive'
-[CRED118]
-ROBERT LOGGIA AS RAY MACHOWSKI
+[STFT_09]
+Schnellste Zeit bei 'Küsten-Rallye'
-[CRED119]
-GURU AS 8-BALL
+[STFT_10]
+Schnellste Zeit bei 'Capital Cruise'
-[CRED120]
-SONDRA JAMES AS MOMMA
+[STFT_11]
+Schnellste Zeit bei 'Tour!'
-[CRED121]
-LIANA PAI AS ASUKA
+[STFT_12]
+Schnellste Zeit bei 'V.C. Endurance'
-[CRED122]
-LES MAU AS KENJI
+[STHC_01]
+High-Score bei Schießstand-Mission
-[CRED123]
-CYNTHIA FARRELL AS CATALINA
+[STHC_02]
+Beste Trefferquote am Schießstand (in Prozent)
-[CRED124]
-AL ESPINOSA AS MIGUEL
+[STHC_03]
+Anzahl getätigter Drogendeals
-[CRED125]
-CHRIS PHILLIPS AS EL BURRO
+[HELP24]
+Du kannst jetzt Aufträge vom Colonel annehmen.
-[CRED126]
-HUNTER PLATIN AS CHICO
+[HELP25]
+Du kannst jetzt Aufträge von Avery Carrington annehmen.
-[CRED127]
-WALTER MUDU AS D-ICE
+[HELP29]
+Außerhalb eine Mision kannst du zu dem Bekleidungsgeschäft gehen.
-[CRED128]
-CURTIS MCCLARIN AS CURTLY
+[HELP30]
+Wenn du neue Klamotten kaufst, reduziert sich dein Fahndungslevel auf null.
-[CRED129]
-BILL FIORE AS DARKEL
+[ASM4_24]
+Entfernung:
-[CRED130]
-CHRIS PHILLIPS AS MARTY CHONKS
+[RBM1_6]
+~g~Bring Mercedes und den 'Love Juice' zu der Band ins Aufnahmestudio.
-[CRED131]
-HUNTER PLATIN AS CURLY BOB
+[RBM1_3]
+NICHT MEHR BENÖTIGT
-[CRED132]
-WALTER MUDU AS KING COURTNEY
+[HAM1_5]
+NICHT MEHR BENÖTIGT
-[CRED133]
-HUNTER PLATIN AS ONE-ARMED PHIL
+[RBM1_11]
+NICHT MEHR BENÖTIGT
-[CRED134]
-KIM GURNEY AS MISTY
+[HELP31]
+Um aus dem fahrenden Fahrzeug zu schießen, sieh zuerst mit ~k~~VEHICLE_LOOKLEFT~ oder ~k~~VEHICLE_LOOKRIGHT~ nach links oder rechts.
-[CRED135]
-MOTION CAPTURE
+[HELP34]
+Du brauchst eine Maschinenpistole für einen 'Drive-By'.
-[CRED136]
-ANIMATED BY
+[STRIP_1]
+~r~Nicht genug Cash, du windiger Geizhals!
-[CRD136A]
-ALEX HORTON
+[EXIT_1]
+~k~~PED_SPRINT~ zum Beenden.
-[CRED137]
-DIRECTED BY
+[ASM1_B]
+Ihr nächster Auftrag klebt unter dem Telefon.
-[CRD137A]
-NAVID KHONSARI
+[ASM1_C]
+Ich habe noch mehr Arbeit, die eine eher 'zupackende' Art verlangt.
-[CRED138]
-PRODUCED BY
+[SCARF]
+Apartment 3c
-[CRD138A]
-JAMIE KING
+[LAW4_10]
+Reiche Manager sind Schweine!
-[CRD138B]
-RENAUD SEBBANE
+[RCH1_6]
+~g~Benutze den ferngesteuerten Helikopter, um Checkpoints überall auf dem Flughafen abzufliegen.
-[CRED139]
-RECORDED AT MODERN UPRISING STUDIOS, BROOKLYN
+[RCH1_9]
+~b~GESAMTZEIT: ~1~:~1~
-[CRED140]
-ACTORS
+[RCH1_10]
+~b~GESAMTZEIT: ~1~:0~1~
-[CRD140A]
-RENAUD SEBBANE
+[WHEEL01]
+ZWEIRAD DOPPELBONUS: $ ~1~ Distanz: ~1~.~1~m Zeit: ~1~ Sekunden
-[CRD140B]
-GISELLE JONES
+[WHEEL02]
+ZWEIRAD DOPPELBONUS: $ ~1~ Distanz: ~1~ Fuß Zeit: ~1~ Sekunden
-[CRD140C]
-STEPHEN DANIELS
+[WHEEL03]
+ZWEIRAD BONUS: $ ~1~ Zeit: ~1~ Sekunden
-[CRD140D]
-ROBERT STIO
+[WHEEL04]
+ZWEIRAD BONUS: $ ~1~ Distanz: ~1~.~1~m
-[CRD140E]
-JENNY GROSS.
+[WHEEL05]
+ZWEIRAD BONUS: $ ~1~ Distanz: ~1~ Fuß
-[CRED141]
-PEDESTRIAN DIALOGUE
+[WHEEL06]
+WHEELIE BONUS: $ ~1~ Distanz: ~1~.~1~m Zeit: ~1~ Sekunden
-[CRED142]
-WRITTEN BY DAN HOUSER, NAVID KHONSARI & JAMES WORRALL
+[WHEEL07]
+WHEELIE BONUS: $ ~1~ Distanz: ~1~ Fuß Time: ~1~ Sekunden
-[CRED143]
-DIRECTED BY CRAIG CONNER, DAN HOUSER AND LAZLOW
+[WHEEL08]
+WHEELIE BONUS: $ ~1~ Zeit: ~1~ Sekunden
-[CRED144]
-PRODUCED BY RENAUD SEBBANE
+[WHEEL09]
+WHEELIE BONUS: $ ~1~ Distanz: ~1~.~1~m
-[CRED145]
-CAST
+[WHEEL10]
+WHEELIE BONUS: $ ~1~ Distanz: ~1~.~1~ Fuß
-[CRED146]
-HUNTER PLATIN
+[WHEEL11]
+VOLLBREMSUNGSBONUS: $ ~1~ Distanz: ~1~.~1~m Zeit: ~1~ Sekunden
-[CRED147]
-DAN HOUSER
+[WHEEL12]
+VOLLBREMSUNGSBONUS: $ ~1~ Distanz: ~1~ Fuß Zeit: ~1~ Sekunden
-[CRED148]
-RENAUD SEBBANE
+[WHEEL13]
+VOLLBREMSUNGSBONUS: $ ~1~ Zeit: ~1~ Sekunden
-[CRED149]
-MARIA CHAMBERS
+[WHEEL14]
+VOLLBREMSUNGSBONUS: $ ~1~ Distanz: ~1~.~1~m
-[CRED150]
-JEFF STANTON
+[WHEEL15]
+VOLLBREMSUNGSBONUS: $ ~1~ Distanz: ~1~ Fuß
-[CRED151]
-RYAN CROY
+[ROK3_72]
+Love Fist!
-[CRED152]
-DEENA BERMAN
+[ROK3_74]
+Ah, seht mal, was ist das? Hey, Tommy, leg mal dieses Band ein.
-[CRED153]
-MARIA CHAMBERS
+[POR1_19]
+Hey!
-[CRED154]
-ALICE B. SALTZMAN
+[DESPERA]
+Desperado
-[CRED155]
-ALEX ANTHONY SIOUKAS
+[MOB_99A]
+Begib dich zu dem Fernsprecher neben dem Einkaufszentrum in Washington Beach.
-[CRED156]
-SEAN R. LYNCH
+[MOB_98A]
+Begib dich zu dem Fernsprecher in Vice Point.
-[CRED157]
-AMY SALZMAN
+[MOB_96A]
+Begib dich zu dem Fernsprecher beim Flughafen-Terminal.
-[CRED158]
-COLIN MCSHANE
+[MOB_95A]
+Begib dich zu dem Fernsprecher in Little Havana.
-[CRED159]
-COREY WADE
+[BNK1_1]
+Kann ich Ihnen helfen, Sir?
-[CRED160]
-GERALD COSGROVE
+[BNK1_2]
+Der Typ ist verkleidet!
-[CRED161]
-STEPHANIE ROY
+[BNK1_3]
+Er ist verrückt geworden!
-[CRED162]
-DORIS WOO
+[BNK1_4]
+Wer zum Teufel sind Sie?
-[CRED163]
-JOSEPH GREENE
+[BNK1_5]
+Wo ist Ihre Dienstmarke?
-[CRED164]
-LAZLOW JONES
+[BNK1_6]
+Da sind sie! Feuer frei!
-[CRED165]
-HSIANG LIN
+[MOB_24A]
+Hallo, spricht da Mr. Vercetti?
-[CRED166]
-STEVE MICHAEL ROBERT
+[MOB_24B]
+Ja.
-[CRED167]
-MATHEW MURRAY
+[MOB_24C]
+Hier Cortez. Sie waren bei meiner Party.
-[CRED168]
-RICHARD HUIE
+[MOB_24D]
+Ja. Ich erinnere mich.
-[CRED169]
-GARVIN ATWELL
+[MOB_24E]
+Mr. Vercetti, es war höchst unglücklich, was da bei der Abwicklung Ihres Geschäfts vorgefallen ist.
-[CRED170]
-STEVE KNEZEVICH
+[MOB_24F]
+Ich weiß.
-[CRED171]
-YUKIMURA SATO
+[MOB_24G]
+Sie sollen wissen, dass ich und meine Leute alles tun, um der Sache auf den Grund zu gehen.
-[CRED172]
-FRANK CHAVEZ
+[MOB_24H]
+Falls Sie mit mir persönlich sprechen wollen, finden Sie mich auf dem Schiff. Guten Tag, Senor.
-[CRED173]
-LIEZL JACINTO
+[BNK2_6]
+Der Typ ist geisteskrank!
-[CRED174]
-CANAAN MCKOY
+[ANGEL]
+Angel
-[CRED175]
-ADAM DAVIDSON
+[CUBJET]
+Kubanischer Jetmax
-[CRED176]
-LANCE WILLIAMS
+[SANDKIN]
+Sandking
-[CRED177]
-NEIL MCCAFFREY
+[POLMAV]
+Polizei-Maverick
-[CRED178]
-LAURA PATERSON
+[BOXVILL]
+Boxville
-[CRED179]
-REY CONCEPCION
+[BENSON]
+Benson
-[CRED180]
-CHARLES HEROLD
+[HOTRINA]
+Hotring Racer
-[CRED181]
-ANDREW GREENWALD
+[HOTRINB]
+Hotring Racer
-[CRED182]
-JAMES MIELKE
+[BLOODRA]
+Chaos-Derby Banger
-[CRED183]
-PETER SUCIU
+[BLOODRB]
+Chaos-Derby Banger
-[CRED184]
-ALEX ODULIO
+[MAFIACR]
+Mafia Cruiser
-[CRED185]
-DON NKRUMAH
+[COP_M2]
+'EINSATZ IN VICE CITY'
-[CRED186]
-KENDALL PITTMAN
+[COP_M3]
+'DONNER ÜBER VICE CITY'
-[CRED187]
-SAL SUAZO
+[BNK3_2]
+Ich fahre nicht für dich, niemals. Das erzähle ich in der Therapie.
-[CRED188]
-EREK MATEO
+[FEM_SL1]
+Datei 1 nicht vorhanden
-[CRED189]
-CHRIS DIFATE
+[FEM_SL2]
+Datei 2 nicht vorhanden
-[CRED190]
-LEILA MILTON
+[FEM_SL3]
+Datei 3 nicht vorhanden
-[CRED191]
-DARREN ZOLTOWSKI
+[FEM_SL4]
+Datei 4 nicht vorhanden
-[CRED192]
-VIRGINIA SMITH
+[FEM_SL5]
+Datei 5 nicht vorhanden
-[CRED193]
-KEVIN CASSIN
+[FEM_SL6]
+Datei 6 nicht vorhanden
-[CRED194]
-JASON SHIGEMORI
+[FEM_SL7]
+Datei 7 nicht vorhanden
-[CRED195]
-KELLY KINSELLA
+[FEM_SL8]
+Datei 8 nicht vorhanden
-[CRED196]
-MOLLIE STICKNEY
+[FEA_CHA]
+Tonausgabe wird auf STEREO umgeschaltet. Bitte warten...
-[CRED197]
-STANTON SARJEANT
+[FEA_CHD]
+Achtung! Sie schalten die Tonausgabe von STEREO auf DTS um. Bitte warten...
-[CRED198]
-LAURA WALSH
+[FEI_SEL]
+Auswahl
-[CRED199]
-MARK GARONE
+[FEI_BAC]
+Zurück
-[CRED200]
-JOANNA SLY
+[FEI_RES]
+Weiter
-[CRED201]
-ELIZABETH HOWELL
+[FEI_NAV]
+Navigieren
-[CRED202]
-ANA HERCULES
+[FEI_BTX]
+/-Taste -
-[CRED203]
-SHIRLEY IRICK
+[FEI_BTT]
+"-Taste -
-[CRED204]
-KASHONA FIELDS
+[FEI_STA]
+START-Taste -
-[CRED205]
-JOEL M. LILJE
+[FEI_BTD]
+; = > < -
-[CRED206]
-JOHN DIBENEDETTO
+[FEI_STO]
+Stop
-[CRED207]
-NANCY GILES
+[MOB_68A]
+Tommy, Alter, ich hab eine Überraschung für dich.
-[CRED208]
-RYAN CROY
+[MOB_68B]
+Ich bin im Aufnahmestudio mit ein paar super Musikern.
-[CRED209]
-JENNIFER KOLBE
+[MOB_68C]
+Warum kommst du nicht kurz vorbei?
-[CRED210]
-LIAM BURKE
+[MOB_68D]
+Kannst dir denken, dass es sich lohnt, oder? Bis dann.
-[CRED211]
-SIGRID PREISSL
+[OUTFT1]
+Straße
-[CRED212]
-ANITA FITZSIMONS
+[OUTFT2]
+Abendgarderobe
-[CRED213]
-PHILIPPA RASELLI
+[OUTFT3]
+Overall
-[CRED214]
-WIL QUESNEL
+[OUTFT4]
+Country Club
-[CRED215]
-FALKO BURKERT
+[OUTFT5]
+Havana
-[CRED216]
-SARA SEWELL
+[OUTFT6]
+Cop
-[CRED217]
-RADIO STATIONS AND MUSIC
+[OUTFT7]
+Bankräuber
-[CRED218]
-PRODUCERS FOR ROCKSTAR UK
+[OUTFT8]
+Freizeit
-[CRD218A]
-CRAIG CONNER
+[OUTFT9]
+Mr. Vercetti
-[CRD218B]
-STUART ROSS
+[OUTFT10]
+Trainingsanzug
-[CRED219]
-SOUNDTRACK CO-ORDINATOR
+[OUTFT13]
+MC Tommy
-[CRED220]
-TERRY DONOVAN
+[CAR_AS1]
+AUTOHAUS ERWORBEN
-[CRED221]
-PRODUCER FOR ROCKSTAR GAMES
+[CAR_AS2]
+~g~Sunshine Autos generiert nun bis zu $~1~ Einkünfte. Hol dir das Geld regelmäßig ab.
-[CRED222]
-DAN HOUSER
+[BUYSAVE]
+~g~Außerhalb einer Mission kannst du dein Spiel hier umsonst speichern.
-[CRED223]
-EDITED BY
+[BUYGARG]
+~g~Du kannst in dieser Garage auch Autos abstellen.
-[CRED224]
-CRAIG CONNER
+[STRPBUY]
+Pole Position Club gekauft: $ ~1~
-[CRED225]
-ALLAN WALKER
+[STRP_R3]
+Drücke R3, um den Pole Position Club zu kaufen. Preis: $~1~
-[CRED226]
-LAZLOW
+[NBMN_R3]
+Drücke R3, um Elswanko Casa zu kaufen. Preis: $~1~
-[CRED227]
-DJ BANTER AND IMAGING WRITTEN BY
+[GA_4]
+Autobomben kosten $1000 pro Stück.
-[CRED228]
-DAN HOUSER
+[GA_5]
+In deinem Wagen ist schon eine Autobombe.
-[CRED229]
-LAZLOW
+[GA_6] { reVC update }
+Park die Karre, mach sie durch Drücken der ~h~~k~~VEHICLE_FIREWEAPON~~w~ scharf und dann HAU AB!
-[CRED230]
-SPECIAL THANKS TO
+[GA_7] { reVC update }
+Mach die Bombe mit der ~h~~k~~VEHICLE_FIREWEAPON~~w~ scharf. Dann geht sie hoch, wenn der Wagen angelassen wird.
-[CRED231]
-ADAM TEDMAN
+[GA_6B] { reVC update }
+Park die Karre, mach sie durch Drücken der ~h~~k~~VEHICLE_FIREWEAPON~~w~ scharf und dann HAU AB!
-[CRED232]
-ALEX MASON
+[GA_7B] { reVC update }
+Mach die Bombe mit der ~h~~k~~VEHICLE_FIREWEAPON~~w~ scharf. Dann geht sie hoch, wenn der Wagen angelassen wird.
-[CRED233]
-JUDY HENDERSON CASTING
+[MOB_70A]
+Tommy, ich bin's, Colonel Cortez. Hören Sie, Sie sind doch ein Mann, der Dinge zu erledigen weiß.
-[CRED234]
-HAMISH BROWN
+[MOB_70B]
+Sie finden mich auf dem Boot.
-[CRED235]
-CHRISSY HOBAN
+[PICK2]
+.357 in Verstecken angeliefert!
-[CRED236]
-INNES RICARD
+[PICK3]
+Kettensägen in Verstecken angeliefert!
-[CRED237]
-LILION BROZSKA
+[PICK4]
+Flammenwerfer in Verstecken angeliefert!
-[CRED238]
-BOB HILLARY
+[PICK5]
+.308 Präzisionsgewehr in Verstecken angeliefert!
-[CRED239]
-EMILY ANDERSON
+[PICK6]
+Mini-Kanonen in Verstecken angeliefert!
-[CRED240]
-RICHIE HENDERSON
+[PICK7]
+Raketenwerfer in Verstecken angeliefert!
-[CRED241]
-CHRSTIAN CANTAMESSA
+[PICK8]
+Sea Sparrow jetzt bei Vercetti Estate verfügbar!
-[CRED242]
-JERONIMO BARRERA
+[PICK9]
+Panzer jetzt in Army-Kaserne verfügbar!
-[CRED243]
-ALEXANDER ILLES
+[PICK10]
+Hunter jetzt in Army-Kaserne verfügbar!
-[CRED244]
-BARANE CHAN
+[CLOTH1]
+Abendgarderobe bei Rafaels in Ocean Beach erhältlich.
-[CRED245]
-DUNCAN SHIELDS
+[CLOTH2]
+Straßenkleidung in Verstecken angeliefert.
-[CRED246]
-BARANE CHAN
+[CLOTH3]
+Overall bei 'Tooled Up' im North Point Einkaufszentrum erhältlich.
-[CRED247]
-DEREK PAYNE
+[CLOTH4]
+Country Club-Bekleidung beim Golf Club in Leaf Links erhältlich.
-[CRED248]
-KEVIN WONG
+[CLOTH5]
+Havana-Outfit bei 'Little Havana Streetwear' in Little Havana erhältlich.
-[CRED249]
-ROSS ELLIOTT
+[CLOTH6]
+Polizeiuniform bei Polizeistation in Washington Beach erhältlich.
-[CRED250]
-ROSS BEAZLEY
+[CLOTH7]
+Freizeitbekleidung bei 'Gash' im North Point Einkaufszentrum erhältlich.
-[CRED251]
-ALEX BAZLINTON
+[CLOTH8]
+Mr. Vercetti-Outfit bei 'Collar & Cuffs'in Ocean Beach erhältlich.
-[CRED252]
-DAVE WATSON
+[CLOTH9]
+Trainingsanzug bei 'Jocksport' in Downtown erhältlich.
-[CRED253]
-MALCOLM SMITH
+[CLOTH10]
+Bankräuber-Outfit beim Malibu Club in Vice Point erhältlich.
-[CRED255]
-ANDREW SEMPLE
+[MOB_62A]
+Tommy, hier Ricardo Diaz. Ich wollte dir danken, dass du mich gerettet hast.
-[CRED256]
-ARTIST
+[MOB_62B]
+Ich hab den Trottel von Cortez gefragt. Er meint, du wärst ein Mann für alle Fälle. Komm doch mal bei mir vorbei.
-[CRED257]
-STUART PETRI
+[MOB_62C]
+Ich brauche einen Kerl wie dich. Ich hab nämlich nur Schwachköpfe.
-[CRED258]
-JERONIMO BARRERA
+[MOB_62D]
+Nur lauter Schwachköpfe. Ich mache dich schwer reich.
-[CRED259]
-CARLY SLATER
+[GOAWAY2]
+Komm wieder, wenn du die Biker Gang-Missionen abgeschlossen hast.
-[CRED260]
-GREG LAU
+[COL2_9]
+Du amerikanischer Idiot! Sie sind dir hierher gefolgt!
-[CRED261]
-STEVE KNEZEVICH
+[LOADCOL]
+Lade...
-[CRED262]
-DEVIN WINTERBOTTOM
+[STFT_17]
+Schnellste Zeit bei 'PCJ Rallye'
-[CRED263]
-JAMEEL VEGA
+[STFT_18]
+Schnellste Zeit bei 'Krasses Gelände'
-[CRED264]
-LEE CUMMINGS
+[STFT_19]
+Schnellste Zeit bei 'Teststrecke'
-[CRED265]
-DEVIN BENNET
+[NEW_REC]
+Neuer Rekord!! ~1~ Minuten und ~1~ Sekunden.
-[CRED266]
-ELIZABETH SATTERWHITE
+[BMX_HOW]
+~g~Fahr zwei Runden auf der Geländemotorradstrecke. ~y~Passiere dabei ~g~die ~y~CHECKPOINTS~g~!
-[CRED267]
-AARON RIGBY
+[BMXREW1]
+~g~Jedes Mal wenn du deine bisherige Bestzeit für die zwei Runden verbesserst,
-[CRED268]
-STEVE K.
+[BMXREW2]
+~g~bekommst du eine noch höhere ~y~BELOHNUNG~g~!
-[CRED269]
-GREG LAU
+[BMXRAIN]
+~g~Sieht nach Regen aus...
-[CINCAM]
-Cinematic-Kamera
+[ITBEG]
+Am Anfang...
-[KM1_13]
-Fahr das Fahrzeug in die Garage!
+[NBMNBUY]
+El Swanko Casa gekauft: $ ~1~
-[KM3_14]
-~r~Du bist gesehen worden. Der Deal fällt flach!
+[LNKVBUY]
+Links View Apartment gekauft: $ ~1~
-[EBAL_H]
-Warte hier. Ich gehe rein und rede mit Luigi.
+[HYCOBUY]
+Hyman Condo gekauft: $ ~1~
-[EBAL_M]
-Und merk dir: Finger weg von meinen Girls.
+[BUYGARS]
+~g~Du kannst in diesen Garagen auch Autos abstellen.
-[LM2_F]
-Dann schnapp dir seine Karre und spritze sie um.
+[OCHEBUY]
+Ocean Heights Apartment gekauft: $ ~1~
-[LM2_D]
-Hier. Hier, nimm.
+[WASHBUY]
+1102 Washington Street gekauft: $ ~1~
-[LM1_9]
-Hi. Ich bin Misty.
+[VCPTBUY]
+3321 Vice Point gekauft: $ ~1~
-[LM4_A]
-So ein Mistkerl von den Diablos hat in meinem Gebiet Mädchen laufen.
+[HELP6_C]
+Drücke die ~h~~k~~VEHICLE_HANDBRAKE~~w~, um die Handbremse anzuziehen.
-[FM2_B]
-Wir haben einen Verräter unter uns!
+[HELP2_A]
+Drücke die ~h~~k~~PED_SPRINT~~w~, um zu ~h~sprinten.
-[FM2_C]
-Er verdient kein Geld mit Mädchen oder Dealen, also wird er Informationen verkaufen.
+[HELP4_A]
+Drücke die ~h~~k~~VEHICLE_ACCELERATE~~w~, um zu beschleunigen.
-[FM3_CC]
-~w~Komm wieder, wenn du die Kohle hast, Bruder.
+[HELP5_A]
+Drücke die ~h~~k~~VEHICLE_BRAKE~~w~, um zu bremsen, oder um zurückzusetzen, wenn das Fahrzeug steht.
-[FEDS_AM]
-<>-MENÜ WECHSELN
+[HELP8_A]
+Drücke die ~h~~k~~PED_SNIPER_ZOOM_IN~~w~, um an das Ziel heranzuzoomen und die ~x~/-Taste~w~,um herauszuzoomen.
-[LOVE5_5]
-~r~Du hast es nicht geschafft, den Truck zu beschützen!
+[PBOAT_1] { reVC update }
+Drücke die~h~ ~k~~VEHICLE_FIREWEAPON~~w~, um die Bordkanonen abzufeuern.
-[RM6_6]
-~r~Ray ist tot!
+[SEG3_4] { reVC update }
+~g~Um Bomben aufzunehmen, steuere den RC Raider einfach nahe an sie heran. Um eine abzuwerfen, drücke die ~h~~k~~VEHICLE_FIREWEAPON~~g~-Taste.
-[RM6_7]
-~r~Ray hat seinen Flug verpasst.
+[RCR1_3] { reVC update }
+~g~Wenn du diese Mission abbrechen willst, drücke die ~h~~k~~VEHICLE_FIREWEAPON~~g~, um dein Auto zu sprengen.
-[RM6_8]
-~g~Du hast Ray zurückgelassen. Kehr um und hol ihn.
+[HELP32] { reVC update }
+Dann feuere mit der ~h~~k~~VEHICLE_FIREWEAPON~.
-[FM1_10]
-~g~Du hast Maria zurückgelassen. Kehr um und hol sie.
+[HELP33] { reVC update }
+Dann feuere mit der ~h~~k~~VEHICLE_FIREWEAPON~.
-[LOVE4_9]
-~r~Das Flugzeug ist zerstört worden!
+[TTUTOR]
+Drücke die ~h~~k~~TOGGLE_SUBMISSIONS~~w~, um Taxi-Missionen an- oder abzuschalten.
-[LOV4_10]
-~r~Die einzige Spur auf den Verbleib des Päckchens ist vernichtet worden.
+[TTUTOR2]
+Drücke die ~h~~k~~TOGGLE_SUBMISSIONS~~w~, um Taxi-Missionen an- oder abzuschalten.
-[KM2_D]
-Unnötig zu sagen, dass wir ihm die Autos schenken müssen, um meine Schuld bei ihm zu begleichen.
+[FTUTOR]
+Drücke die ~h~~k~~TOGGLE_SUBMISSIONS~~w~, um Feuerwehrwagen-Missionen an- oder abzuschalten.
-[KM4_B]
-Für Läden, die das Glück haben, unter unserem Schutz zu stehen, ist heute Zahltag.
+[FTUTOR2]
+Drücke die ~h~~k~~TOGGLE_SUBMISSIONS~~w~, um Feuerwehrwagen-Missionen an- oder abzuschalten.
-[KM2_E]
-Du musst die Autos auf der Liste besorgen und zu einer Garage hinter dem Parkplatz in Newport bringen.
+[CTUTOR]
+Drücke die ~h~~k~~TOGGLE_SUBMISSIONS~~w~, um Bürgerwehr-Missionen zu aktivieren oder zu deaktivieren.
-[FM3_8I]
-~w~Such dir eine günstige Position. Ich geh rein, wenn du den ersten Schuss abfeuerst.
+[CTUTOR2]
+Drücke die ~h~~k~~TOGGLE_SUBMISSIONS~~w~, um Bürgerwehr-Missionen zu aktivieren oder zu deaktivieren.
-[LOVE1_B]
-Ich weiß, dass einer wie du sehr loyal sein kann, wenn das Geld stimmt.
+[HELP8_B]
+Drücke die~h~ ~k~~PED_SNIPER_ZOOM_IN~~w~, um ~h~an das Ziel heranzuzoomen ~w~und die~h~ ~k~~PED_SNIPER_ZOOM_OUT~~w~, um ~h~herauszuzoomen~w~.
-[LOVE1_H]
-Aber je mehr Leute, desto größer die Gier.
+[ATUTOR3]
+Drücke die ~h~~k~~TOGGLE_SUBMISSIONS~~w~, um Krankenwagen-Missionen an- oder abzuschalten.
-[LOVE1_C]
-Ein werter Geschäftsfreund, ein alter Asiate,
+[GUN_H1]
+~w~Drück die~h~ ~k~~PED_SPRINT~~w~, um zu kaufen. ~w~Drück die~h~ ~k~~VEHICLE_ENTER_EXIT~~w~, um zu gehen.
-[LOVE1_I]
-wird von irgendwelchen Südamerikanern in Aspatria als Geisel festgehalten.
+[PU_CF3] { reVC update }
+Drück die ~h~~k~~PED_ANSWER_PHONE~~w~, um die augenblickliche Waffe in diesem Slot auszutauschen.
-[MEA4_D]
-Ich habe ein Treffen mit ihm vereinbart...
+[PU_CF4] { reVC update }
+Drück die ~h~~k~~PED_ANSWER_PHONE~~w~, um die augenblickliche Waffe in diesem Slot auszutauschen.
-[MEA4_B4]
-Marty schickt dich also? Dem Penner werde ich zeigen, was es heißt, mit mir Geschäfte zu machen.
+[HELP9_B]
+Drücke die~h~ ~k~~PED_FIREWEAPON~~w~, um das Präzisionsgewehr ~h~abzufeuern~w~.
-[MEA4_B5]
-Carl, hi. Ich, äh, ich brauche noch ein bisschen Zeit, um dein Geld aufzutreiben.
+[HELP37]
+Wenn du doch nicht in ein Auto einsteigen willst, das du im Begriff bist, zu klauen, drück die ~h~~k~~PED_SPRINT~.
-[MEA1_B4]
-Mr Chonks schickt dich also. Wollen wir dem Burschen doch mal einen Besuch abstatten.
+[HELP6_A]
+Drücke die ~h~~k~~VEHICLE_HANDBRAKE~~w~, um die Handbremse anzuziehen.
-[HM5_6]
-Dann wollen wir doch mal ein paar Leute aufmischen...
+[HELP6_D]
+Drücke die ~h~~k~~VEHICLE_HANDBRAKE~~w~, um die Handbremse anzuziehen.
-[LOVE1_5]
-~g~Häng hier nicht rum, besorg dir ein Auto der Kolumbianer und rette Loves Geschäftsfreund.
+[HELP26]
+Drücke die ~h~~k~~VEHICLE_ENTER_EXIT~~w~, um in ein Fahrzeug ein- oder auszusteigen.
-[AS1_D]
-~w~Spiel den Köder und locke die Killerkommandos nach Pine Creek,
+[HELP27]
+Drücke ~h~~k~~VEHICLE_TURRETUP~~w~ oder ~h~~k~~VEHICLE_TURRETDOWN~~w~ um dein Gewicht auf einem Motorrad zu verlagern.
-[AS1_E]
-~w~wo meine Leute sie erwarten werden.
+[HELP28]
+Drücke ~h~~k~~VEHICLE_TURRETUP~~w~ oder ~h~~k~~VEHICLE_TURRETDOWN~~w~ um dein Gewicht auf einem Motorrad zu verlagern.
-[AS2_C]
-~w~Das Kartell betreibt eine Scheinfirma zur Tarnung - das Kappa Coffee House.
+[HELP35]
+Benutze die ~h~~k~~GO_LEFT~~w~ oder ~h~~k~~GO_RIGHT~~w~ um das Fahrzeug zu steuern.
-[AS2_E]
-~w~Wir haben keine Wahl. Wir müssen diese Drogenbuden zerstören.
+[HELP36]
+Benutze die ~h~~k~~GO_LEFT~~w~ oder ~h~~k~~GO_RIGHT~~w~ um das Fahrzeug zu steuern.
-[AS2_F]
-~w~Zerleg diese Dinger!!
+[HELP42]
+Folge dem ~q~rosa Symbol~w~, um zum Hotel zu kommen.
-[AS2_A1]
-~w~Miguel ist ein echter Latin Lover. Der hat ein Stehvermögen!
+[HELP19]
+Stell dich in die ~q~rosa Markierung~w~, um weiterzumachen.
-[AS2_A2]
-~w~Ich bin völlig erschöpft.
+[HELP1]
+Halte in der Mitte der ~q~rosa Markierung.
-[SIREN_3]
-Um die Sirenen dieses Fahrzeugs einzuschalten, drücke die ~h~~k~~VEHICLE_HORN~-Taste~w~.
+[HELP12]
+Geh ins Zentrum der ~q~rosa Markierung~w~, um eine Mission zu starten.
-[SIREN_4]
-Um die Sirenen dieses Fahrzeugs einzuschalten, drücke die ~h~~k~~VEHICLE_HORN~-Taste~w~.
+[SEG3_6]
+~g~Um eine Zielzone zu treffen, musst du die Bombe innerhalb der ~q~rosa Markierung~g~ abwerfen. Die Reihenfolge spielt dabei keine Rolle.
-[AS3_C]
-~w~Iiiiiiiiiiih! Was ist denn das für ein gelbes Glibberzeug?
+[S_PROMP]
+Außerhalb einer Mission kannst du dein Spiel speichern, indem du das ~h~Cassetten-Symbol aufnimmst.
-[AS3_C1]
-~w~Oh, hi, Baby.
+[HELP16]
+Geh durch die Eingangstür, um das ~h~Ocean View Hotel~w~ zu betreten.
-[AS3_F]
-~w~Das Mädchen ist ein Naturtalent.
+[HELP43]
+~g~Begib dich zum ~h~Ocean View Hotel~g~ am Ocean Drive.
-[AS3_F1]
-~w~Sie hat unserem Gast eine kleine Info entlockt.
+[HELI_F1]
+~r~Heli-Ceckpoint-Mission abgebrochen!
-[AS3_G]
-~w~In 2 Stunden landet ein Flugzeug auf dem Francis Int. Airport.
+[AMMUHLP]
+Wenn du Waffen brauchst, geh zu ~h~AmmuNation~w~. Das ~h~Pistolensymbol~w~ auf dem Radar zeigt dir den Weg.
-[AS3_G1]
-~w~Es ist voll mit Catalinas Giftzeug.
+[HELI_1]
+Downtown Heli-Checkpoint
-[AS3_H]
-~w~Du entgehst den Security Checks am Flughafen, wenn du dir ein Boot besorgst, zu den Leuchtbojen rausfährst
+[HELI_2]
+Ocean Beach Heli-Checkpoint
-[AS3_H1]
-und die Maschine im Anflug abschießt.
+[HELI_3]
+Vice Point Heli-Checkpoint
-[AS3_I]
-~w~Krame die Ladung aus den Trümmern!
+[HELI_4]
+Little Haiti Heli-Checkpoint
-[AS3_J]
-~w~Und sei vorsichtig, okay, Baby?
+[FST_MFR]
+Lieblings-Radiosender
-[AS3_K]
-~w~Versuch's mal mit Chili-Öl...
+[FST_LFR]
+Unbeliebtester Radiosender
-[RM2_F1]
-Die Kolumbianer müssen jeden Moment hier sein!
+[FEI_HOL]
+Halten
-[RM2_K]
-Verdammt, da sind sie!! LOS, LADEN!!
+[FEI_ZOO]
+Zoom
-[LOVE2_7]
-~g~Jetzt lass den Wagen stehen!
+[FEI_BTR]
+> < -
-[LOVE2_8]
-~g~Jetzt verschwinde aus Newport!
+[FEI_NA]
+Nicht verfügbar
-[AM1_F]
-Salvatore Leone wird Luigis Club in zirka drei Stunden verlassen (~1~:~1~).
+[MESA]
+Mesa Grande
-[LOVE5_C]
-Folge ihm und sorg dafür, dass er und mein Päckchen wohlbehalten in Pike Creek ankommen.
+[STRP_NO]
+Zurzeit kannst du die Stripper-Bar nicht kaufen. Komm später wieder.
-[FESZ_SR]
-Speicherung fehlgeschlagen! Bitte Memory Card (PS2) in MEMORY CARD-Steckplatz 1 überprüfen und noch einmal versuchen.
+[CHSE]
+VERFOLGUNGSJAGD
-[FESZ_FO]
-Memory Card (PS2) in MEMORY CARD-Steckplatz 1 formatieren?
+[NBMN_L]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um El Swanko Casa zu kaufen. Preis: $~1~
-[FELZ_FO]
-Memory Card (PS2) in MEMORY CARD-Steckplatz 1 ist nicht formatiert.
+[NBMN_T]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um El Swanko Casa zu kaufen. Preis: $~1~
-[FES_NOC]
-Keine Memory Card (PS2) in MEMORY CARD-Steckplatz 1.
+[NBMN_C]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um El Swanko Casa zu kaufen. Preis: $~1~
-[FES_LOE]
-Laden fehlgeschlagen! Bitte Memory Card (PS2) in MEMORY CARD-Steckplatz 1 überprüfen und noch einmal versuchen.
+[LNKV_L]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um das Links View Apartment zu kaufen. Preis: $~1~
-[FES_DEE]
-Löschen fehlgeschlagen! Bitte Memory Card (PS2) in MEMORY CARD-Steckplatz 1 überprüfen und noch einmal versuchen.
+[LNKV_T]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um das Links View Apartment zu kaufen. Preis: $~1~
-[FORSUC]
-Memory Card (PS2) in MEMORY CARD-Steckplatz 1 wurde formatiert.
+[LNKV_C]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um das Links View Apartment zu kaufen. Preis: $~1~
-[ERFOUN]
-Memory Card (PS2) in MEMORY CARD-Steckplatz 1 konnte nicht formatiert werden.
+[HYCO_L]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um das Hyman Condo zu kaufen. Preis: $~1~
-[ERMCNP]
-Keine Memory Card (PS2) in MEMORY CARD-Steckplatz 1.
+[HYCO_T]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um das Hyman Condo zu kaufen. Preis: $~1~
-[SVMEM1]
-Speichern auf Memory Card (PS2) in MEMORY CARD-Steckplatz 1.
+[HYCO_C]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um das Hyman Condo zu kaufen. Preis: $~1~
-[FORSLO]
-Memory Card (PS2) in MEMORY CARD-Steckplatz 1 formatieren.
+[OCHE_L]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um das Ocean Heights Apartment zu kaufen. Preis: $~1~
-[SLONFM]
-Fehler beim Formatieren der Memory Card (PS2) in MEMORY CARD-Steckplatz 1.
+[OCHE_T]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um das Ocean Heights Apartment zu kaufen. Preis: $~1~
-[SLONDR]
-Nicht genug Speicherplatz. Bitte eine Memory Card (PS2) mit mindestens 500KB freiem Speicherplatz in MEMORY CARD-Steckplatz 1 einstecken.
+[OCHE_C]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um das Ocean Heights Apartment zu kaufen. Preis: $~1~
-[SLNSP]
-Nicht genug Speicherplatz. Bitte eine Memory Card (PS2) mit mindestens 200KB freiem Speicherplatz in MEMORY CARD-Steckplatz 1 einstecken.
+[WASH_L]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um 1102 Washington Street zu kaufen. Preis: $~1~
-[FEFD_WR]
-Formatiere Memory Card (PS2) in MEMORY CARD-Steckplatz 1. Bitte die Memory Card (PS2) nicht entfernen, kein Reset vornehmen und die Konsole nicht ausschalten.
+[WASH_T]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um 1102 Washington Street zu kaufen. Preis: $~1~
-[FES_ISF]
-NICHT VORHANDEN
+[WASH_C]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um 1102 Washington Street zu kaufen. Preis: $~1~
-[FES_SAG]
-VORHANDEN
+[VCPT_L]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um 3321 Vice Point zu kaufen. Preis: $~1~
-[SLONNO]
-Keine Memory Card (PS2) in MEMORY CARD-Steckplatz 1.
+[VCPT_T]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um 3321 Vice Point zu kaufen. Preis: $~1~
-[SLONNF]
-Memory Card (PS2) in MEMORY CARD-Steckplatz 1 ist nicht formatiert.
+[VCPT_C]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um 3321 Vice Point zu kaufen. Preis: $~1~
-[FESZ_FM]
-Memory Card (PS2) in MEMORY CARD-Steckplatz 1 ist nicht formatiert. Soll die Memory Card (PS2) in MEMORY CARD-Steckplatz 1 formatiert werden?
+[PRNT_L]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um die Druckerei zu kaufen. Preis: $~1~
-[FESZ_FF]
-Formatierung fehlgeschlagen. Bitte die Memory Card (PS2) in MEMORY CARD-Steckplatz 1 überprüfen und noch einmal versuchen.
+[PRNT_T]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um die Druckerei zu kaufen. Preis: $~1~
-[MCDNSP]
-Nicht genug Platz auf Memory Card (PS2) in MEMORY CARD-Steckplatz 1. Es werden mind. 500KB Speicherplatz benötigt, um Spieldaten zu speichern. Trotzdem starten? (JA oder NEIN)
+[PRNT_C]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um die Druckerei zu kaufen. Preis: $~1~
-[MCGNSP]
-Nicht genug Platz auf Memory Card (PS2) in MEMORY CARD-Steckplatz 1. Es werden mind. 200KB Speicherplatz benötigt, um Spieldaten zu speichern. Trotzdem starten? (JA oder NEIN)
+[CAR_L]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um das Autohaus zu kaufen. Preis: $~1~
-[FESZ_WR]
-Daten werden gespeichert. Bitte die Memory Card (PS2) in MEMORY CARD-Steckplatz 1 nicht entfernen, kein Reset vornehmen und die Konsole nicht ausschalten.
+[CAR_T]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um das Autohaus zu kaufen. Preis: $~1~
-[FESZ_OW]
-Daten werden überschrieben. Bitte die Memory Card (PS2) in MEMORY CARD-Steckplatz 1 nicht entfernen, kein Reset vornehmen und die Konsole nicht ausschalten.
+[CAR_C]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um das Autohaus zu kaufen. Preis: $~1~
-[FELD_WR]
-Daten werden geladen. Bitte die Memory Card (PS2) in MEMORY CARD-Steckplatz 1 nicht entfernen, kein Reset vornehmen und die Konsole nicht ausschalten.
+[PORN_L]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um das Filmstudio zu kaufen. Preis: $~1~
-[FEDL_WR]
-Daten werden gelöscht. Bitte die Memory Card (PS2) in MEMORY CARD-Steckplatz 1 nicht entfernen, kein Reset vornehmen und die Konsole nicht ausschalten.
+[PORN_T]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um das Filmstudio zu kaufen. Preis: $~1~
-[LM2_C]
-Luigi sagt, das soll ich dir geben...
+[PORN_C]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um das Filmstudio zu kaufen. Preis: $~1~
-[LM3_G]
-Joey ist einer, den man nicht warten lässt. Das ist deine Chance.
+[ICE_L]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um die Eiscremefabrik zu kaufen. Preis: $~1~
-[LM5_E]
-Bring so viele wie möglich hin, bevor die Cops ihr ganzes Geld versaufen.
+[ICE_T]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um die Eiscremefabrik zu kaufen. Preis: $~1~
-[JM5_C]
-Vor dem Cafe in der Nähe vom Callahan Point steht ein Auto mit einem Toten drin.
+[ICE_C]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um die Eiscremefabrik zu kaufen. Preis: $~1~
-[RM2_B]
-Wir waren zusammen in Nicaragua, als dieses Land noch wusste, was es tut.
+[TAXI_L]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um das Taxiunternehmen zu kaufen. Preis: $~1~
-[RM2_C]
-Irgendwelche Dreckskerle vom Kartell haben ihn gestern verprügelt und kommen heute wieder, um ihm seine Ware abzunehmen.
+[TAXI_T]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um das Taxiunternehmen zu kaufen. Preis: $~1~
-[RM2_D1]
-Ich würde es selbst machen, aber meine Bronchien melden sich wieder. Tja, äh, viel Glück.
+[TAXI_C]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um das Taxiunternehmen zu kaufen. Preis: $~1~
-[CATINF1]
-~g~Schnapp dir Catalina!
+[BANK_L]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um den Malibu Club zu kaufen. Preis: $~1~
-[CATINF2]
-~g~Um Catalina zu finden, folge dem Hubschrauber.
+[BANK_T]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um den Malibu Club zu kaufen. Preis: $~1~
-[BOATIN1]
-Spring auf ein Boot und drücke die ~h~~k~~VEHICLE_ENTER_EXIT~-Taste~w~, um hinein zu gelangen.
+[BANK_C]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um den Malibu Club zu kaufen. Preis: $~1~
-[BOATIN2]
-Wenn du in der Nähe eines Bootes bist, kannst du die ~h~~k~~VEHICLE_ENTER_EXIT~-Taste ~w~benutzen, um an Bord zu gelangen.
+[BOAT_L]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um die Bootswerft zu kaufen. Preis: $~1~
-[BOATIN3]
-Spring auf ein Boot und drücke die ~h~~k~~VEHICLE_ENTER_EXIT~-Taste~w~, um hinein zu gelangen.
+[BOAT_T]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um die Bootswerft zu kaufen. Preis: $~1~
-[BOATIN4]
-Wenn du in der Nähe eines Bootes bist, kannst du die ~h~~k~~VEHICLE_ENTER_EXIT~-Taste ~w~benutzen, um an Bord zu gelangen.
+[BOAT_C]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um die Bootswerft zu kaufen. Preis: $~1~
-[JM6]
-'DIE FLUCHT'
+[STRP_L]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um den Pole Position Club zu kaufen. Preis: $~1~
-[FM1]
-'AUF PISTE MIT MARIA'
+[STRP_T]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um den Pole Position Club zu kaufen. Preis: $~1~
-[JM1]
-'MIKE 'LIPS' LETZTE LASAGNE'
+[STRP_C]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um den Pole Position Club zu kaufen. Preis: $~1~
-[FM21]
-'DER BOMBENANSCHLAG, TEIL 1'
+[STOCK]
+~r~nicht vorrätig
-[FM3]
-'DER BOMBENANSCHLAG, TEIL 2'
+[HELP14]
+Um das Büro des Anwalts zu finden, folge dem ~h~'L'~w~ auf dem Radar.
-[AM1]
-'SAYONARA SALVATORE'
+[BOAT_AS]
+~g~Die Bootswerft generiert nun bis zu $~1~ Einkünfte. Hol dir das Geld regelmäßig ab.
-[AM2]
-'UNTER ÜBERWACHUNG'
+[BOAT_A2]
+BOOTSWERFT-MISSIONEN ERFÜLLT
-[KM2]
-'GTA'
+[BOAT_N]
+Checkpoint Charlie
-[AS3]
-'DER ABFANGJÄGER'
+[BOAT_P]
+~g~Sammle die Päckchen ein, ehe die Zeit um ist.
-[RM2]
-'DAS WAFFENARSENAL'
+[FEI_R1B]
+R1- \ R2-Taste -
-[LOVE6]
-'LOCKVOGEL'
+[HELP9_A]
+Drücke die ~h~~k~~PED_FIREWEAPON~~w~-Taste, um das Präzisionsgewehr abzufeuern.
-[LOVE1]
-'DIE BEFREIUNGSAKTION'
+[HELP21]
+Drücke die ~h~~k~~VEHICLE_ENTER_EXIT~~w~-Taste, um in ein Fahrzeug ein- oder auszusteigen.
-[RC1]
-'IM DSCHUNGEL DER DIABLOS'
+[CREAM]
+Stoff-Auslieferung
-[RC2]
-'DAS MAFIA-MASSAKER'
+[UMBERTO]
+Café Robina
-[RC3]
-'DER CASINO-COUP'
+[PU_CF1]
+Drück die ~h~~k~~PED_ANSWER_PHONE~~w~-Taste, um diese Waffe aufzunehmen. Falls du schon eine Waffe von diesem Typ hast, wird sie durch die neue ersetzt.
-[RC4]
-'ROCK'N ROLL MIT RUMPO'
+[FED_RDM]
+KARTE & SYMBOLE
-[RM2_E1]
-Unglaublich, dass die feigen Säcke mich wieder ohne ausreichenden Schutz ins Gefecht schicken.
+[FEC_ILU]
+Kamera invertieren :
-[GREN_1]
-Je länger du die ~h~~k~~PED_FIREWEAPON~-Taste~w~ gedrückt hältst, desto weiter kannst du die Granate werfen.
+[NITRO]
+Alle Taxis haben jetzt einen Jumper-Turbo! Du musst nur die Taste für die Hupe drücken.
-[GREN_2]
-Je länger du die ~h~~k~~PED_FIREWEAPON~-Taste~w~ gedrückt hältst, desto weiter kannst du die Granate werfen.
+[RATNG53]
+Windei
-[GREN_3]
-Je länger du die ~h~~k~~PED_FIREWEAPON~-Taste~w~ gedrückt hältst, desto weiter kannst du die Granate werfen.
+[RATNG54]
+Niete
-[LOVE4_G]
-Die Maschine mit meiner Ware steht im Zollhangar.
+[RATNG55]
+Hacker
-[KABOOM]
-KAWUMM!
+[RATNG56]
+Mogelpaket
-[SPLAT]
-WUSCH!
+[RATNG57]
+Totaler Lügner
-[PANCAK]
-PLATT!
+[STHC_04]
+High-Score beim Fußball-Hochhalten
-[SOAKED]
-AARGH!
+[STHC_05]
+Bestes Hotring-Resultat
-[HEAD]
-Head Radio
+[STFT_13]
+Schnellste Zeit bei Downtown Heli-Checkpoint
-[DBL_CLF]
-Double Clef FM
+[STFT_14]
+Schnellste Zeit Ocean Beach Heli-Checkpoint
-[FLASHB]
-Flashback FM
+[STFT_15]
+Schnellste Zeit bei Vice Point Heli-Checkpoint
-[RISE]
-Rise FM
+[STFT_16]
+Schnellste Zeit bei Little Haiti Heli-Checkpoint
-[LIPS]
-Lips 106
+[STFT_21]
+Schnellste Zeit bei Hotring
-[CHAT]
-Chatterbox FM
+[STFT_22]
+Schnellste Rundenzeit bei Hotring
-[K_JAH]
-K-Jah Radio
+[STFT_20]
+Schnellste Zeit bei 'Pylonen-Rallye'
-[GAM_FM]
-Game Radio FM
+[HELP44]
+Halte in der ~q~rosa Markierung.
-[MSX_FM]
-MSX FM
+[HELP45]
+Drücke die ~h~~k~~PED_DUCK~~w~ um dich zu ducken. Dadurch erhöht sich die Treffsicherheit der Waffen, die du hältst.
-[TUBE1]
-Wenn der U-Bahnhof öffnet, kannst du die U-Bahn nach Staunton Island nehmen.
+[RCR1_5]
+RC Bandit-Rennen
-[TUBE2]
-Wenn der U-Bahnhof in Shoreside Vale aufmacht, dann kannst du das Shoreside Terminal in Richtung Francis Int. Airport verlassen.
+[RCPL1_7]
+RC Baron-Rennen
-[TUBE_2]
-Um in eine U-Bahn einzusteigen, ~h~'Einsteigen'-Taste~w~ drücken.
+[RCH1_11]
+RC Raider Checkpoint-Jagd
-[LEGAL]
-~g~Schalte die kriminelle Bedrohung aus!
+[FEA_CTD]
+Achtung! Für diesen Modus muss DTS-kompatible Hardware angeschlosen sein. Fortfahren?
-[GA_2]
-Neuer Motor und neue Lackierung. Die Cops werden dich nicht identifizieren!
+[FEM_STE]
+AUF STEREO EINSTELLEN
-[LM1_8A]
-Warum nicht ein Taxi 'ausleihen', um dir was dazu zu verdienen...?
+[FEM_UDY]
+AUF DTS EINSTELLEN
-[TAXIH1]
-Halte neben einem gehighlighteten Fußgänger, um ihn einsteigen zu lassen, dann bringe ihn rechtzeitig an sein Fahrtziel.
+[GREET]
+Grüße aus...
-[LM5_7]
-~g~Wenn weniger als vier Girls bei dem ~p~Polizeiball~g~ auftauchen, wird Luigi sauer!
+[LANCE_1]
+Hey, Mann, fahr vorsichtiger!
-[KM2_3]
-~g~Die ~r~Autos~g~ müssen in 1A-Zustand sein, damit die ~p~Garage~g~ sie annimmt.
+[LANCE_2]
+Hey, pass doch auf, was du machst!
-[KM5_2]
-~g~Ein Yardie ist weg.
+[LANCE_3]
+Hey, wo fahren wir jetzt hin?
-[BETRA_A]
-Sorry, Baby.
+[LANCE_4]
+Was machen wir jetzt?
-[BETRA_B]
-Ich bin ein anspruchsvolles Mädchen und du...
+[LAW4_15]
+Mehr Geld!
-[BETRA_C]
-... du bist ein kleiner Fisch.
+[MERC_5]
+Schönes Auto, Mr. Vercetti.
-[JAILB_C]
-Noch gibt es keine näheren Informationen zu den Häftlingen, die mit dem Konvoi transportiert wurden,
+[MERC_26]
+SCHNELLER, SCHNELLER, SCHNELLER!
-[JAILB_E]
-Der Konvoi war am frühen Morgen vom Polizei-Hauptquartier aus
+[MERC_27]
+Vorsichtig, Tommy, ich hab mir erst letzten Monat die Nase korrigieren lassen.
-[JAILB_F]
-zu einem Gefangenentransport mit Ziel Haftanstalt Liberty aufgebrochen.
+[MERC_28]
+Tommy, fahr vorsichtig.
-[JAILB_G]
-Der Anschlag erfolgte an der Callahan-Brücke.
+[MERC_29]
+Tommy, fahr langsamer.
-[JAILB_P]
-ist Portland durch diese Katastrophe vom Rest der Stadt abgeschnitten.
+[MERC_30]
+Tommy, bring jemand anders um, aber bitte nicht mich.
-[JAILB_Q]
-Los jetzt!
+[MERC_31]
+Tommy, Baby, bring mich nicht um!
-[JAILB_R]
-Vollidiot!
+[MERC_32]
+Tommy, ich bin froh, dass du dieses Auto gestohlen hast!
-[JAILB_S]
-Kein Problem, dich alle zu machen.
+[MERC_40]
+Ich hatte so viel Spaß.
-[JAILB_T]
-Das wird dir noch leid tun.
+[MERC_43]
+Adios, mein Engel.
-[JAILB_U]
-Okay, okay. Hau ab.
+[MERC_44]
+Und mach schön weiter Bodybuilding, hörst du?
-[HELP15]
-Wenn zu Fuß unterwegs, drücke die ~h~~k~~PED_LOOKBEHIND~-Taste~w~, um ~h~nach hinten zu schauen~w~.
+[MERC_45]
+Ciao, mein Hübscher.
-[FEC_LB3]
-Nach hinten schauen
+[COL5_17]
+Oh, Gott, sie haben einen Helikopter!
-[FEC_R3]
-(R3-Taste)
+[COL5_18]
+Schießt den Helikopter ab!
-[FES_AFO]
-Diese Memory Card (PS2) ist bereits formatiert.
+[COL5_19]
+Tommy, schießen Sie den Helikopter ab!
-[FEA_UP]
-;
+[COL5_20]
+Da kommt er wieder! Schießt den Helikopter ab!
-[FEA_DO]
-=
+[COL5_21]
+Sieh dir diesen riesigen Helikopter an!
-[FEA_LE]
-<
+[COL5_22]
+Da kommt er wieder!
-[FEA_RI]
->
+[FEA_DSM]
+Achtung! Dieses Spiel ist auf DTS-Tonausgabe eingestellt. Dazu muss DTS-kompatible Hardware angeschlossen sein. Bitte wählen Sie, ob Sie mit DTS oder STEREO-Tonausgabe fortfahren wollen.
-[FEDSAS3]
-- AUSWAHL ÄNDERN
+[STFT_23]
+Schnellste Zeit bei Checkpoint Carlie
-[FEDSAS4]
-;=<> - AUSWAHL ÄNDERN
+[HELP50]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~-Taste, um die Spielerfigur von hinten zu sehen.
-[SPRAY_4] { re3 change }
-~h~~k~~VEHICLE_FIREWEAPON~-Taste ~w~benutzen, um die Wasserkanone abzufeuern.
+[HELP51]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~-Taste, um die Spielerfigur von hinten zu sehen.
-[SPRAY_1] { re3 change }
-~h~~k~~VEHICLE_FIREWEAPON~-Taste ~w~benutzen, um die Wasserkanone abzufeuern.
+[HELP52]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~-Taste, um die Spielerfigur von hinten zu sehen.
-[LITTLE]
-LITTLE T
+[HELP53]
+Benutze die ~h~~k~~PED_CYCLE_WEAPON_LEFT~~w~-Taste und die ~h~~k~~PED_CYCLE_WEAPON_RIGHT~~w~-Taste, um zwischen deinen Waffen zu wechseln.
-[NICK]
-NICK LOVE
+[HELP46]
+Es gibt acht verschiedene Waffentypen.
-[AM1_10]
-~g~Salvatore Leone wird Luigis Club um zirka 0~1~:~1~ verlassen.
+[HELP47]
+Du kannst von jedem Waffentyp immer nur eine bei dir tragen - also einen Typ Pistole, einen Typ Schrotflinte, usw.
-[JAILB_V]
-Liberty City ist heute vom Schrecken gezeichnet.
+[HELP54]
+~w~Preis: $~1~ ~r~Deine augenblickliche Waffe wird ersetzt, wenn du diese kaufst.
-[JAILB_A]
-Polizei und Noteinsatzkräfte arbeiten unter Hochdruck, nachdem heute morgen
+[HELP2A2]
+Drücke die ~h~~k~~PED_SPRINT~~w~-Taste, um zu ~h~sprinten.
-[JAILB_B]
-ein verheerender Anschlag auf einen Polizeikonvoi verübt wurde.
+[HLPSN_A]
+Das Präzisionsgewehr ermöglicht dir, an dein Ziel heranzuzoomen und auf größere Distanz mit hoher Genauigkeit zu schießen.
-[JAILB_W]
-Nach stundenlangen Ermittlungen wurde klar, dass der Anschlag das Werk von Profis war.
+[HLPSN_B]
+Halte die~h~ ~k~~PED_LOCK_TARGET~~w~-Taste gedrückt, um mit dem Präzisionsgewehr zu ~h~zielen~w~.
-[JAILB_K]
-Die Identifizierung der noch vermissten Kriminellen wurde darüber hinaus
+[HLPSN_C]
+Halte die~h~ ~k~~PED_LOCK_TARGET~~w~-Taste gedrückt, um mit dem Präzisionsgewehr zu ~h~zielen~w~.
-[JAILB_L]
-durch eine Hacker-Attacke auf den Zentral-Computer der Polizei erschwert.
+[HLPSN_D]
+Drücke die ~h~~k~~PED_SNIPER_ZOOM_IN~~w~-Taste, um ~h~an das Ziel heranzuzoomen ~w~und die~h~ ~k~~PED_SNIPER_ZOOM_OUT~~w~,um ~h~herauszuzoomen~w~.
-[JAILB_M]
-stellte Bürgermeister O'Donovan klar, dass die Polizei
+[HLPSN_E]
+Drücke die ~h~~k~~PED_FIREWEAPON~~w~-Taste, um das Präzisionsgewehr ~h~abzufeuern~w~.
-[JAILB_N]
-*
+[HLPSN_F]
+Drücke die ~h~~k~~PED_FIREWEAPON~~w~-Taste, um das Präzisionsgewehr ~h~abzufeuern~w~.
-[JAILB_O]
-Da die Fertigstellung des Porter Tunnels sich verzögert,
+[HLPSN_G]
+Drücke die ~h~~k~~PED_FIREWEAPON~~w~-Taste, um das Präzisionsgewehr ~h~abzufeuern~w~.
-[JAILB_X]
-In einer ersten Stellungnahme
+[PLANE_H]
+Benutze die ~h~~k~~VEHICLE_ACCELERATE~~w~-Taste, um zu beschleunigen. Links bzw. Rechts für Richtungswechsel.
-[FEDS_SE]
-/-Taste - AUSWAHL
+[PLANE_4] { reVC update }
+{Benutze die ~h~~k~~VEHICLE_ACCELERATE~~w~-Taste, um zu beschleunigen. Links bzw. Rechts für Richtungswechsel.}
+Benutze den rechten Analog-Stick, um zu beschleunigen. Ziehe den linken Analog-Stick, um zu steigen oder drücke ihn nach vorn, um zu sinken. Links bzw. Rechts für Richtungswechsel.
-[FEDS_SB]
-/-Taste - AUSWAHL "-Taste - ZURÜCK
+[HELP55]
+Drücke die ~h~~k~~PED_FIREWEAPON~~w~-Taste, um den Küchenchef anzugreifen.
-[TM4_A]
-~w~Ach, du bist es. Toni ist nicht da.
+[STPR_8]
+Pole Position Club
-[TM4_A2]
-~w~Aber er hat wieder ein Liebesbriefchen für dich hinterlassen.
+[STPR_9]
+3321 Vice Point
-[DIAB2_A]
-Ich habe mein Entertainment-Business mit nichts als dem üppigen Inhalt meiner Lederhose gestartet.
+[STPR_10]
+Links View Apartment
-[LM5_9]
-GIRLS:
+[STPR_11]
+El Swanko Casa
-[PERPIC]
-Versteckte Päckchen gefunden
+[STPR_12]
+1102 Washington Street
-[CO_ONE]
-Verstecktes Päckchen ~1~ von ~1~
+[STPR_13]
+Ocean Heights Apartment
-[LOVE3_3]
-~g~Das Flugzeug hat ~1~ von 6 Päckchen abgeworfen.
+[STPR_14]
+Skumole Shack
-[FARE11]
-~g~Fahrziel: ~w~'Baustelle' ~g~in Fort Staunton.
+[STPR_15]
+Hyman Condo
-[GA_21]
-In dieser Garage bringst du keine Autos mehr unter.
+[RCCANX]
+~r~Flugzeug-Mission abgebrochen.
-[CHEAT1]
-Cheat aktiviert
+[CLT_HL2]
+Wenn du neue Kleider aufnimmst, werden dadurch Fahndungslevel von einem bis zwei Sternen annulliert.
-[CHEAT2]
-Waffen-Cheat
+[CRED009]
+MISSION DESIGN
-[CHEAT3]
-Health-Cheat
+[CRED359]
+LEE JOHNSON
-[CHEAT4]
-Panzerungs-Cheat
+[CRED360]
+HENDRIK LESSER
-[CHEAT5]
-Fahndungslevel-Cheat
+[CRED361]
+PASQUALE STACCHIOTTI
-[CHEAT6]
-Geld-Cheat
+[CRED362]
+ENRIQUE FERNANDEZ
-[CHEAT7]
-Wetter-Cheat
+[CRED363]
+PAUL BYERS
-[AS1_H]
-~r~Es ist dir nicht gelungen, das Killerkommando in die Yakuza-Falle zu locken!
+[CRED364]
+MIKE EMENY
-[FEDS_BA]
-"-Taste - ZURÜCK
+[CRED365]
+ROB DUNKIN
-[RAMP_A]
-ALLE AMOKLÄUFE BEENDET!
+[CRED366]
+CHARLIE KINLOCH
-[USJ_ALL]
-ALLE MONSTER-STUNTS ABSOLVIERT!
+[CRED367]
+KEVIN HOBSON
-[FARE23]
-~g~Fahrtziel: ~w~'Import-Export Garage' ~g~im Cochrane Dam Distrikt.
+[CRED368]
+JIM CREE
-[L_TRN_1]
-Mit der U-Bahnlinie L kannst du in Portland herumfahren. Drücke die~h~ ~k~~VEHICLE_ENTER_EXIT~-Taste~w~, um in eine U-Bahn ~h~ein- oder auszusteigen~w~.
+[MOB_66A]
+Tommy, Tommy, Tommy, wieso bist du wieder zurückgekommen?
-[L_TRN_2]
-Mit der U-Bahnlinie L kannst du in Portland herumfahren. Drücke die ~h~~k~~VEHICLE_ENTER_EXIT~-Taste~w~, um in eine U-Bahn ~h~ein- oder auszusteigen~w~.
+[MOB_66B]
+Ich hab dir doch gesagt, wir wollen dich hier nicht mehr sehen.
-[S_TRN_1]
-Mit der U-Bahn kannst du in Liberty herumfahren. Drücke die ~h~~k~~VEHICLE_ENTER_EXIT~-Taste~w~, um in eine U-Bahn ~h~ein- oder auszusteigen~w~.
+[MOB_67A]
+Tommy, ich glaube, du solltest dich hier nicht mehr blicken lassen, hörst du?
-[S_TRN_2]
-Mit der U-Bahn kannst du in Liberty herumfahren. Drücke die ~h~~k~~VEHICLE_ENTER_EXIT~-Taste~w~, um in eine U-Bahn ~h~ein- oder auszusteigen~w~.
+[MOB_67B]
+Die Haitianer sind nicht sehr gut auf dich zu sprechen.
-[AS1_C]
-~w~Sie hat drei Killerkommandos in Liberty verteilt, die dich zur Strecke bringen sollen.
+[MOB_18A]
+Tommy, hier Paul. Wie geht's, Alter? Hey, ich dachte mir, das musst du hören...
-[AS1_G]
-~r~Alle Yakuza sind erledigt!
+[MOB_18B]
+Echt der Hammer. Du glaubst nicht, was mir für 'ne Puppe über den Weg gelaufen ist.
-[JAN]
-Jan
+[MOB_18C]
+'ne Bordsteinschwalbe, oder sowas. Unten in Little Havana.
-[FEB]
-Feb
+[MOB_18D]
+Sagt, sie heißt Mercedes oder so ähnlich.
-[MAR]
-Mär
+[MOB_18E]
+Wahnsinn, Alter. Die Puppe musst du dir geben.
-[APR]
-Apr
+[MOB_18F]
+Da würde 'nen Toter Hormonkoller kriegen. Sie sagt, ich wär der beste, den sie je hatte.
-[MAY]
-Mai
+[MOB_18G]
+Halt die Augen nach ihr offen. Bis dann.
-[JUN]
-Jun
+[MOB_72A]
+Tommy, ich bin's, Lance. Du hältst jetzt mal den Rand, Tommy, ich hab nämlich keine Zeit für Geschwätz.
-[JUL]
-Jul
+[MOB_72B]
+Interessiert mich auch nicht, was du zu sagen hast. Warum auch? Ich bin dir doch sowieso scheißegal, stimmt's?
-[AUG]
-Aug
+[MOB_72C]
+Du solltest dich mehr um mich kümmern. Mir einen fairen Anteil geben. Weißt du...
-[SEP]
-Sept
+[MOB_72D]
+Tommy... hör mal, Mann, es tut mir leid. Nur...
-[OCT]
-Okt
+[MOB_72E]
+ich werd schon mein Leben lang immer nur von oben herab behandelt, wie ein kleines Kind.
-[NOV]
-Nov
+[MOB_72F]
+Mein Bruder hat das auch immer gemacht. Bitte, mein Alter, mach du das nicht.
-[DEC]
-Dez
+[MOB_72G]
+Ich muss auflegen.
-[DEFDT]
---:---:---- --:--:--
+[MOB_63A]
+Tommy, hier Earnest. Earnest Kelly.
-[BUGGY]
-VERBLEIBENDE BUGGIES:
+[MOB_63B]
+Wie geht's?
-[BONUS]
-~g~BONUS $~1~
+[MOB_63C]
+Ganz gut. Werd zum Laufen 'nen Stock brauchen, müsste aber bald wieder arbeiten können.
-[HORN1]
-Drück die ~h~L3-Taste~w~, um zu ~h~hupen.
+[MOB_63D]
+Gut.
-[HORN2]
-Drück die ~h~L1-Taste~w~, um zu ~h~hupen.
+[MOB_63E]
+Ich hab das mit Lance gehört. Was für ein Schwein, hä?
-[HORN3]
-Drück die ~h~R1-Taste~w~, um zu ~h~hupen.
+[MOB_63F]
+Ja.
-[LM3_1A]
-Drück die ~h~~k~~VEHICLE_HORN~-Taste~w~, um zu ~h~hupen. So weiß Misty, dass du da bist.
+[MOB_63G]
+Trau nie einem Mann, der im Pyjama auf der Straße herumläuft. Gut, dass du ihn erledigt hast. Ich hoffe, es war nicht kurz und schmerzlos.
-[LM3_1B]
-Drück die~h~ ~k~~VEHICLE_HORN~-Taste~w~, um zu ~h~hupen. So weiß Misty, dass du da bist.
+[MOB_63H]
+Eher nicht. Ich hätte nur nicht gedacht, dass er so einer ist...
-[LM3_1C]
-Drück die~h~ ~k~~VEHICLE_HORN~-Taste~w~, um zu ~h~hupen. So weiß Misty, dass du da bist.
+[MOB_63I]
+Tommy, für einen wildgewordenen Irren bist du ziemlich naiv. Ich bin bald wieder an der Arbeit, dann bring ich dir mal ein paar Sachen übers Leben bei, ok?
-[RADIO_A]
-Drück die ~h~~k~~VEHICLE_CHANGE_RADIO_STATION~-Taste~w~, um die verschiedenen ~h~Radiosender zu hören.
+[MOB_63J]
+Lass dir Zeit, Earnest. Pass auf dich auf.
-[RADIO_B]
-Drück die ~h~~k~~VEHICLE_CHANGE_RADIO_STATION~-taste~w~, um die verschiedenen ~h~Radiosender zu hören.
+[MOB_16A]
+Tommy, hier Paul. Wie geht's, mein Freund?
-[RADIO_C]
-Drück die ~h~~k~~VEHICLE_CHANGE_RADIO_STATION~-Taste~w~, um die verschiedenen ~h~Radiosender zu hören.
+[MOB_16B]
+Was willst du, Paul? Ich brauch keine getürkten Designer-Klamotten.
-[RADIO_D]
-Drück die ~h~~k~~VEHICLE_CHANGE_RADIO_STATION~-Taste~w~, um die verschiedenen ~h~Radiosender zu hören.
+[MOB_16C]
+Sehr witzig. Du weißt, dass ich mit getürkter Ware nichts am Hut habe. Wollte nur hören, ob ich nicht 'ne Rolle in einem von deinen Filmen kriegen könnte.
-[FEC_EXV]
-In Fahrzeug ein-\aussteigen
+[MOB_16D]
+In England habe ich damals viel einschlägiges Zeug gedreht. Ich hab mehr zu bieten als du, mein Alter.
-[TAXI_M]
-'TAXI DRIVER'
+[MOB_16E]
+Paul, danke für das Angebot. Ich komm auf dich zurück.
-[COP_M]
-'BÜRGERWEHR'
+[MOB_16F]
+Lass mich nicht hängen. Denk dran, was ich alles für dich getan habe.
-[FIRE_M]
-'FEUERWEHR'
+[MOB_16G]
+Das versuch ich ja grade zu vergessen.
-[AMBUL_M]
-'KRANKENWAGEN'
+[MOB_17A]
+Tommy Vercetti. Wie geht's, großer Meister? Man hört so einiges über dich. Bist jetzt 'ne große Nummer in der Stadt, hä?
-[HJ_IS]
-IRRSINNS-STUNT-BONUS: $~1~
+[MOB_17B]
+Paul, du bist betrunken.
-[HJ_PIS]
-SUPER IRRSINNS-STUNT-BONUS: $~1~
+[MOB_17C]
+Nein, du Trottel, ich bin nicht betrunken. Hab mir nur ein paar Ladungen Stoff gegeben, war seit ein paar Tagen nicht im Bett.
-[HJ_DIS]
-DOPPELTER IRRSINNS-STUNT-BONUS: $~1~
+[MOB_17D]
+Und du brauchst mich nicht dumm anzureden. Ich bin nicht irgendwer. Wer hat dir denn in dieser Stadt den Weg geebnet? Ich!
-[HJ_PDIS]
-SUPER-DOPPEL-IRRSINNS-STUNT-BONUS: $~1~
+[MOB_17F]
+Tatsächlich?
-[HJ_TIS]
-DREIFACHER IRRSINNS-STUNT-BONUS: $~1~
+[MOB_17G]
+Komm mir nicht so! Ich hab dich mit den ganzen Leuten bekanntgemacht. Hab dir gezeigt, wie der Hase läuft, hab alles mögliche für dich getan, und so dankst du es mir?!
-[HJ_PTIS]
-SUPER-DREIFACH-IRRSINNS-STUNT-BONUS: $~1~
+[MOB_17H]
+Du ignorierst mich. Du gibst mir keine Chance, mitzumischen, nach allem, was ich für dich getan habe! Hältst du mich für einen Schwachkopf?
-[HJ_QIS]
-VIERFACHER IRRSINNS-STUNT-BONUS: $~1~
+[MOB_17I]
+Paul, reg dich ab. Ich hatte viel zu tun. Sei kein Idiot.
-[HJ_PQIS]
-SUPER-VIERFACH-IRRSINNS-STUNT-BONUS: $~1~
+[MOB_17J]
+Ich bin kein Idiot. Das haben sie schon im Jugendknast gesagt. Wenn du Ärger haben willst, Freundchen, den kannst du haben!
-[AM1_K]
-Salvatore Leone wird Luigis Club in zirka drei Stunden verlassen. (0~1~:~1~)
+[MOB_17K]
+Tommy, bitte! Du warst meine große Hoffnung. Bitte, mach dich nicht lustig über mich!
-[IMPEXPP]
-Import-Export Garage, Portland Harbor. Wir haben Bestellungen für verschiedene Fahrzeuge. Näheres steht auf unserem Schwarzen Brett.
+[MOB_17L]
+Paul, schlaf mal 'ne Runde. Im Ernst.
-[VANHSTP]
-Willst du noch mehr Securicars aufgebrochen haben? Bring sie zu unserer Garage in Portland Harbor.
+[MOB_73A]
+Tommy, hier Steve.
-[EMVHPUP]
-Zahlen Bestpreise für Neu- und Gebrauchtwagen. Bring sie zum Kran im Nordosten von Portland Harbor.
+[MOB_73B]
+Hey, Steve.
-[STANDS]
-ZERSTÖRTE ESPRESSOSTÄNDE:
+[MOB_73C]
+Hey, aber wie! Du bist ein Genie! Ich bin ein Genie! Sie lieben uns alle. Wir brechen alle Rekorde, mein Alter.
-[STASH]
-~g~Deponiere das SPANK auf der ~p~Baustelle!
+[MOB_73D]
+Uns winken ganz große Filmpreise. Jetzt kann ich endlich meinen alten Herrn ins Heim stecken und ihm sagen, er soll die Klappe halten.
-[MCSTNS]
-Keine Memory Card (PS2) in MEMORY CARD-Steckplatz 1. Trotzdem starten? (JA oder NEIN)
+[MOB_73E]
+Äh, das ist cool, Steve.
-[LOVE3_5]
-~g~Das Flugzeug ist jetzt in Reichweite.
+[MOB_73F]
+Cool? Mann, das ist heiß! Heiß! H.E.I.ß! Er hat nie an mich geglaubt. Hat immer gedacht, ich wäre kein Künstler, und jetzt hab ich's geschafft!
-[LOVE3_6]
-~r~Die Polizei war vor dir bei den Päckchen!
+[MOB_73G]
+Ich bin der größte Porno-Regisseur aller Zeiten, mein Freund. Wollte dir nur sagen, es ist mir eine Freude, dich kennengelernt zu haben.
-[SIREN_1]
-Um die Sirenen dieses Fahrzeugs einzuschalten, drücke die ~h~~k~~VEHICLE_HORN~-Taste~w~.
+[MOB_73H]
+Danke, Steve.
-[SIREN_2]
-Um die Sirenen dieses Fahrzeugs einzuschalten, drücke die ~h~~k~~VEHICLE_HORN~-Taste~w~.
+[MOB_73I]
+Ich liebe dich, Baby. Bleib bloß genau so wie du bist, ok?
-[FM3_8C]
-~w~Ich brauch $100 000 für Auslagen.
+[MOB_73J]
+Werd's mir merken. Ciao, Steve.
-[MCLOAD]
-Daten werden geladen. Bitte die Memory Card (PS2) in MEMORY CARD-Steckplatz 1 nicht entfernen, kein Reset vornehmen und die Konsole nicht ausschalten.
+[BOLLOX]
+Drücke die ~o~R1~w~-Taste, um eine Bombe abzuwerfen. Drücke die ~t~"~w~-Taste zum Abbrechen.
-[FES_GME]
-Fehler beim Lesen der Memory Card (PS2) in MEMORY CARD-Steckplatz 1! Bitte überprüfen und noch einmal versuchen.
+[BRID_OP]
+Sturmwarnung vorüber. Alle Brücken zum Festland sind wieder geöffnet.
-[FESZ_QF]
-Soll die Memory Card (PS2) in MEMORY CARD-Steckplatz 1 wirklich formatiert werden?
+[BRID_CL]
+Sturmwarnung: Alle Brücken zum Festland sind gesperrt.
-[FESZ_LS]
-Ladevorgang abgeschlossen.
+[LG_38]
+Ziel
-[RM3_5]
-~g~Du hast ~1~ von 6 Päckchen mit Beweisfotos.
+[ASSET_C]
+POLE POSITION ERWORBEN!
-[LOVE3_2]
-~g~Du hast alle Päckchen. Bring sie zu Donald Love.
+[ASSET_D]
+~g~Der Pole Position Club sorgt nun für ein Einkommen von bis zu $~1~ pro Tag. Hol dir dein Geld regelmässig!
-[LOVE4_4]
-~g~Bring das Päckchen zu Donald Love!
+[ST_WHEE]
+Längste 'Wheelie' Zeit (sekunden)
-[FEB_SAV]
-Laden
+[ST_STOP]
+Längste 'Stoppie' Zeit (sekunden)
-[FEP_SAV]
-SPIEL LADEN
+[ST_2WHE]
+Längste 2 Rad Zeit (sekunden)
-[AS2_12A]
-~g~Wenn du den ersten Espressostand zerstört hast, hast du 8 Minuten Zeit, bis das Kartell seine Dealer warnt!
+[ST_WHED]
+Längste 'Wheelie' Distanz (m)
-[AS3_1A]
-~g~Jetzt fahr zu der ~b~Markierungsboje!
+[ST_STOD]
+Längste 'Stoppie' Distanz (m)
-[NOCONT]
-Bitte stecken Sie einen Analog Controller (DUALSHOCK#) oder einen Analog Controller (DUALSHOCK#2) in Controller-Anschluss 1, um fortzufahren.
+[ST_2WHD]
+Längste 2 Rad Distanz (m)
-[BET_JB]
-VON CATALINA, SEINER GELIEBTEN, IM STICH GELASSEN, FÜR SCHULDIG BEFUNDEN UND VERURTEILT, BEFINDET ER SICH AUF DEM WEG INS GEFÄNGNIS VON LIBERTY CITY. DOCH IN SEINEM KOPF HÄMMERT EIN GEDANKE... MIT EUCH BIN ICH NOCH NICHT FERTIG!
+[OUTFT11]
+Trainer
-[END_A]
-Die Bewohner von Cedar Grove erholen sich langsam
+[OUTFT12]
+Frankie
-[END_B]
-von dem Schock der schrecklichen Ereignisse,
+[RELOAD]
+~g~Du hast die schnell Nachladefähigkeit gewonnen!
-[END_C]
-die sich gestern hier abgespielt haben.
+[APACHE]
+Hunter zur Heli Landeplattform am Ocean Beach geliefert.
-[END_D]
-Clive Denver, ein Augenzeuge, beschrieb der Polizei
+[CRED369]
+JOHN MCCARDLE
-[END_E]
-den Täter, den er zusammen mit einer dunkelhaarigen Frau flüchten sah.
+[CRED370]
+DAVID MURDOCH
-[END_F]
-Hör mal, wir werden sehr viel Spaß miteinander haben. Weißt du,
+[CRED371]
+CHRIS BROWN
-[END_G]
-ich liebe dich nämlich. Wirklich, du bist so groß und stark,
+[CRED372]
+PAUL GREEN
-[END_H]
-und genau so einen Mann brauche ich.
+[CRED373]
+KYLE MILNE
-[END_I]
-Jedenfalls - was wollte ich gerade sagen?
+[CUNTY]
+Neue Kleider wurden zum Vercetti Estate geliefert!
-[END_J]
-Weiß nicht mehr. Aber du verstehst doch, was ich meine, oder?
+[GOODBOY]
+$50 'Guter Bürger' Bonus!
-[END_K]
-Der Donner von Explosionen erschütterte umliegende Häuser. Menschen rannten in Deckung.
+[NEWCONT]
+Neuer Kontaktpunkt am Jachthafen am Ocean Beach!!
-[END_L]
-Mehrere Anwohner wurden verletzt, als es in dem Chaos zu einem Schusswechsel
+[FIRELVL]
+Feuerwehr-Mission Level ~1~
-[END_M]
-zwischen Bodeneinheiten und einem Helikopter kam, der über dem Damm kreiste.
+[HELP56]
+Drücke die ~h~~k~~CAMERA_CHANGE_VIEW_ALL_SITUATIONS~~w~-Taste, um den Blickwinkel zu ändern.
-[END_N]
-Ja, von hier in den Gärten konnten wir alles genau beobachten.
+[HELP57]
+Drücke die ~h~~k~~CAMERA_CHANGE_VIEW_ALL_SITUATIONS~~w~-Taste, um den Blickwinkel zu ändern.
-[END_O]
-Wie sie den Helikopter dann abgeschossen haben,
+[HELP58]
+Beim Zielen kann durch Drücken der ~h~~k~~PED_CYCLE_TARGET_LEFT~~w~-Taste zwischen Zielen hin- und her gewechselt werden.
-[END_P]
-das war ein ziemliches Feuerwerk.
+[HELP59]
+Beim Zielen kann durch Drücken der ~h~~k~~PED_CYCLE_TARGET_LEFT~~w~-Taste zwischen Zielen hin- und her gewechselt werden.
-[END_Q]
-Die Zahl der Toten ist inzwischen auf über 20 angestiegen
+[HELP60]
+Wenn du während eines Autodiebstahls die ~h~~k~~PED_SPRINT~ ~w~-Taste drückst, steigst du nicht in das Fahrzeug ein.
-[END_R]
-und die Polizei findet immer noch weitere Leichen.
+[HELP61]
+Du hast jetzt unbegrenzt Munition und doppelte Health für alle Fahrzeuge.
-[END_S]
-Die Gerüchte, dass es sich bei den Opfern um Angehörige des kolumbianischen Kartells
+[CRED374]
+KEVIN YUN
-[END_T]
-handelt, wurden von offizieller Seite bisher nicht dementiert.
+[CRED375]
+ERICK COBBS
-[END_U]
-Und es gibt nach wie vor keine Anhaltspunkte für das Motiv der Tat.
+[CRED376]
+RANDY BLAKE
-[END_V]
-Ich hab mir 'nen Fingernagel abgebrochen und meine Frisur ist hin!
+[CRED377]
+BRANDON LIM
-[END_W]
-Fünfzig Dollar im Eimer!
+[CRED378]
+BRANDON FENOL
-[PAPER1]
-GANGSTER VON KOMPLIZIN, DIE ER LIEBT, VERRATEN. GERICHT BEFINDET RÄUBER EINSTIMMIG FÜR SCHULDIG.
+[CRED379]
+MICHAEL MANOLE
-[PAPER2]
-ZEHN JAHRE AUS LIEBE!
+[CRED380]
+ALETHEIA SIMONSON
-[JAILB_D]
-und es hat sich bisher auch keine kriminelle Vereinigung zu dem Attentat bekannt.
+[CRED381]
+JOHN JANSEN
-[JAILB_H]
-Die meisten Zeugen kamen ums Leben und die Brücke wurde schwer beschädigt.
+[FEC_LB1]
+Schau
-[JAILB_I]
-Man geht davon aus, dass auch einige der Häftlinge bei der sich ereignenden Explosion umkamen.
+[FEC_LB2]
+nach hinten
-[JAILB_J]
-*
+[FEC_LB3]
+Nach hinten schauen
-[FEB_CPC]
-Konfiguration d. Steuerung
+[FEC_R3]
+(R3-Taste)
[FEC_PED]
Steuerung zu Fuß
@@ -7109,81 +7137,6 @@ Blickwinkel wechseln.
[FEC_TSS]
Screen Shot
-[FEN_NET]
-Netzwerk
-
-[FEN_CON]
-Verbindung
-
-[FEN_GAM]
-Spiel suchen
-
-[FEN_TYP]
-Spiel-Typ
-
-[FEN_TY0]
-Deathmatch
-
-[FEN_TY1]
-Deathmatch Stealth
-
-[FEN_TY2]
-Team Deathmatch
-
-[FEN_TY3]
-Team Deathmatch Stealth
-
-[FEN_TY4]
-Stash the Cash
-
-[FEN_TY5]
-Capture the Flag
-
-[FEN_TY6]
-Rat Race
-
-[FEN_TY7]
-Domination
-
-[FEN_NAM]
-Name:
-
-[FEN_GNA]
-Spiel-Name:
-
-[FEM_MAP]
-Karte auswählen
-
-[FEN_PLS]
-Spieler-Einstellungen
-
-[FEN_PLC]
-Spieler-Farbe
-
-[FEM_MA0]
-Liberty City
-
-[FEM_MA1]
-Rotlichtbezirk
-
-[FEM_MA2]
-Chinatown
-
-[FEM_MA3]
-Der Tower
-
-[FEM_MA4]
-Die Kanalisation
-
-[FEM_MA5]
-Industriepark
-
-[FEM_MA6]
-Docks
-
-[FEM_MA7]
-Staunton
-
[FEC_DBG]
Debug-Menü
@@ -7229,41 +7182,209 @@ Nur ein Joystick-Button pro Aktion erlaubt
[FEC_JBO]
JOY ~1~
-[NO_PAUZ]
-Pause in Multiplayer nicht möglich. Zum Beenden zwei Mal drücken!
+[FEC_WAR]
+Achtung!
-[FEM_SL1]
-Speicherplatz 1 ist frei
+[FEC_OKK]
+OK
-[FEM_SL2]
-Speicherplatz 2 ist frei
+[FEC_DLF]
+Löschen fehlgeschlagen.
-[FEM_SL3]
-Speicherplatz 3 ist frei
+[FEC_SVU]
+Speichern fehlgeschlagen.
-[FEM_SL4]
-Speicherplatz 4 ist frei
+[FEC_LUN]
+Laden fehlgeschlagen. Datei beschädigt. Bitte löschen.
-[FEM_SL5]
-Speicherplatz 5 ist frei
+[FEC_PAD]
+Gamepad
-[FEM_SL6]
-Speicherplatz 6 ist frei
+[FEC_JOY]
+Joystick
-[FEM_SL7]
-Speicherplatz 7 ist frei
+[FES_CSA]
+Wählen Sie eine Skin aus der Liste aus:
-[FEM_SL8]
-Speicherplatz 8 ist frei
+[FET_HRD]
+STANDARDEINSTLLG. WIEDERHERGESTELLT
+
+[FET_MST]
+MAUSSTEUERUNG
+
+[FEC_STR]
+NUM STERN
+
+[FET_MIG]
+LINKS,RECHTS,MAUSRAD ZUR EINSTLLG.
+
+[FET_CIG]
+RÜCKT. ZUM LÖSCHEN - LMT,RETURN ZUM ÄNDERN
+
+[FET_DSN]
+Standard-Player Skin.bmp
+
+[FET_RSO]
+ORIGINAL-EINSTELLG. WIEDERHERGESTELLT
+
+[FET_RSC]
+HARDWARE NICHT VERFÜGBAR - ORIGINAL-EINSTELLG. WIEDERHERGESTELLT
+
+[FEA_3DH]
+AUDIO HARDWARE
+
+[FEA_SPK]
+BOXEN KONFIGURATION
+
+[FEM_LOD]
+DISTANZ-DARSTELLG.
+
+[FEM_VSC]
+FRAME SYNC
+
+[FEM_FRM]
+FRAME LIMITER
[FEM_MM]
HAUPTMENÜ
-[FEM_SNG]
-Neues Spiel starten
+[FED_RES]
+BILDSCHIRMAUFLSG.
+
+[FET_CTL]
+CONTROLLER-SETUP
+
+[FET_OPT]
+OPTIONEN
+
+[FEC_MSH]
+MAUSEMPFINDLICHKEIT
+
+[FEC_IVV]
+MAUS VERTIKAL INVERTIEREN
+
+[FET_MTI]
+MAUS STEURUNGSKONFIG.
+
+[FEC_FNC]
+F~1~
+
+[FEC_IRT]
+EINFG
+
+[FEC_DLL]
+ENTF
+
+[FEC_HME]
+POS1
+
+[FEC_END]
+ENDE
+
+[FEC_PGU]
+BILD AUF
-[FEM_QTW]
-Beenden
+[FEC_PGD]
+BILD AB
+
+[FEC_UPA]
+AUF
+
+[FEC_DWA]
+AB
+
+[FEC_LFA]
+LINKS
+
+[FEC_RFA]
+RECHTS
+
+[FEC_NUM]
+NUM
+
+[FEC_NMN]
+NUM~1~
+
+[FEC_FWS]
+NUM /
+
+[FEC_PLS]
+NUM +
+
+[FEC_MIN]
+NUM -
+
+[FEC_DOT]
+NUM ,
+
+[FEC_NLK]
+NUMLOCK
+
+[FEC_ETR]
+ENT
+
+[FEC_SLK]
+ROLLEN
+
+[FEC_PSB]
+UNTBR
+
+[FEC_BSP]
+RÜCKT.
+
+[FEC_TAB]
+TAB
+
+[FEC_CLK]
+CAPSLOCK
+
+[FEC_RTN]
+RET
+
+[FEC_LSF]
+LUMSCHALT
+
+[FEC_RSF]
+RUMSCHALT
+
+[FEC_LCT]
+LSTRG
+
+[FEC_RCT]
+RSTRG
+
+[FEC_LAL]
+LALT
+
+[FEC_RAL]
+RALT
+
+[FEC_LWD]
+LWIN
+
+[FEC_RWD]
+RWIN
+
+[FEC_WRC]
+WINKLICK
+
+[FEC_SPC]
+LEERT.
+
+[WIN_TTL]
+GTA VC
+
+[WIN_95]
+GTA VC läuft nicht unter Windows 95
+
+[WIN_DX]
+GTA VC benötigt mind. DirectX Version 8.1
+
+[FET_EIG]
+KANN DIESER AKTION KEINE STEUERUNG ZUWEISEN
+
+[FET_DAM]
+DYNAMISCHE AKUSTIK
[FEQ_SRE]
Wirklich beenden? Alle Daten seit dem letzten Speichern werden verlorengehen. Weiter?
@@ -7271,736 +7392,7181 @@ Wirklich beenden? Alle Daten seit dem letzten Speichern werden verlorengehen. We
[FEQ_SRW]
Spiel wirklich beenden?
-[FEG_SRV]
-SERVER
+[FET_QG]
+SPIEL BEENDEN
-[FEG_MAP]
-KARTE
+[FEN_STA]
+SPIEL STARTEN
-[FEG_PLY]
-SPIELER
+[REPLAY]
+WIEDERHOLUNG
-[FEG_TYP]
-TYP
+[FET_PAU]
+PAUSENMENÜ
-[FEG_PNG]
-PING
+[FEC_ANS]
+Aktion
-[FET_FG]
-SPIEL SUCHEN
+[CVT_MSG]
+Texturen werden in optimales Format für Ihre Grafikkarte konvertiert
-[FET_SP]
-SINGLEPLAYER
+[FEC_SFT]
+UMSCHALT
-[FET_MP]
-MULTIPLAYER
+[CVT_ERR]
+Kein Platz mehr auf der Festplatte. Bitte schaffen Sie Speicherplatz, bevor Sie fortfahren. ESC zum Abbrechen.
+
+[FEH_VMP]
+KARTE ANSEHEN
-[FET_HG]
-SPIEL HOSTEN
+[FES_DEE]
+Löschen fehlgeschlagen! Bitte noch einmal versuchen.
+
+[FES_CMP]
+Speichern fehlgeschlagen! Bitte noch einmal versuchen.
+
+[FESZ_WR]
+Spiel wird gespeichert. Bitte warten...
+
+[FELD_WR]
+Spiel wird geladen. Bitte warten...
+
+[FEDL_WR]
+Gespeichertes Spiel wird gelöscht. Bitte warten...
+
+[PCRESRT]
+Neues Spiel wird gestartet. Bitte warten...
+
+[FET_STI]
+Standard-Steuerung
+
+[FET_CTI]
+Classic-Steuerung
[FET_PS]
-SPIELER SETUP
+SPIELER-SKIN SETUP
-[FET_CON]
-VERBINDUNG
+[FEH_NA]
+OPTION NICHT VERFÜGBAR
-[FET_AUD]
-AUDIO-SETUP
+[FEH_MPH]
+MAUS, CURSOR ZUM BEWEGEN - BILD AUFW., BILD ABW., MAUSRAD ZUM ZOOMEN, L - LEGENDE
-[FET_DIS]
-ANZEIGEN-SETUP
+[FEA_MP3]
+MP3 PLAYER
-[FET_LAN]
-SPRACHEN-SETUP
+[NO_PCCD]
+Bitte legen Sie die GTA Vice City Disk ein, oder drücken Sie ESC zum Abbrechen
-[FET_LG]
-SPIEL LADEN
+[FEH_SSA]
+CURSOR ZUM BEWEGEN - S UM ZU SPEICHERN
-[FET_DG]
-SPIEL LÖSCHEN
+[FES_CMI]
+LETZTE ERFÜLLTE MISSION
-[FET_NG]
-NEUES SPIEL
+[FET_STS]
+STATISTIKEN GESPEICHERT IN 'STATS.HTML' + 'STATS.TXT'
-[FET_SG]
-SPIEL SPEICHERN
+[WIN_VDM]
+Nicht genug verfügbarer Grafikspeicher für GTA Vice City vorhanden
-[FET_MAP]
-KARTE AUSWÄHLEN
+[FEC_ERI]
+Fehler! Eine oder mehrere Aktionen haben keine Tastenbelegungen. Bitte alle Aktionen belegen.
-[FET_GT]
-SPIEL-TYP
+[FEC_TFU]
+Geschütz + nach hinten neigen
-[FET_CTL]
-CONTROLLER-SETUP
+[FEC_TFD]
+Geschütz + nach vorne neigen
-[FET_OPT]
-OPTIONEN
+[FET_RIG]
+WÄHLEN SIE EINE NEUE TASTENBELEGUNG FÜR DIESE AKTION
-[FET_QG]
-SPIEL BEENDEN
+[FEA_NM3]
+KEINE MP3-DATEIEN GEFUNDEN
-[FET_STA]
-STATISTIK
+[FEA_MPB]
+MP3 LAUTSTÄRKE-BOOST
-[FET_BRE]
-MISSIONSINFOS
+[FEA_MUS]
+LAUTSTÄRKE MUSIK
-[FEC_WAR]
-Achtung!
+[FEA_SFX]
+LAUTSTÄRKE SFX
-[FEC_OKK]
-OK
+[FEA_ADP]
+AUTOMATISCHE HARDWARE ERKENNUNG
-[FED_CON]
-Löschen bestätigen
+{=================================== MISSION TABLE AMBULAE ===================================}
-[FES_SSC]
-Spiel wurde gespeichert.
+[A_COMP1:AMBULAE]
+Krankenwagen-Missionen abgeschlossen: $ ~1~
-[DEL_FNM]
-Datei wurde gelöscht.
+[ATUTOR2:AMBULAE]
+~g~Fahre die Patienten VORSICHTIG in die Klinik. Jede Erschütterung verringert ihre Überlebenschancen.
-[PCLOAD]
-Datei wird geladen
+[A_FULL:AMBULAE]
+~r~Krankenwagen voll!!
-[PCRESRT]
-GTA 3 wird neu gestartet
+[A_FAIL2:AMBULAE]
+~r~Deine Bummelei war tödlich für den Patienten!
-[FEC_DLF]
-Löschen fehlgeschlagen.
+[A_FAIL3:AMBULAE]
+~r~Der Patient ist tot!!
-[FEC_SVU]
-Speichern fehlgeschlagen.
+[A_PASS:AMBULAE]
+Gerettet!
-[FEC_LUN]
-Laden fehlgeschlagen. Datei beschädigt. Bitte löschen.
+[A_COMP2:AMBULAE]
+Du ermüdest nie!
-[FEN_PLA]
-Anzahl der Spieler:
+[A_CANC:AMBULAE]
+~r~Krankenwagen-Mission abgebrochen!
-[FET_NON]
-KEINE SPIELE VERFÜGBAR
+[A_COMP3:AMBULAE]
+Krankenwagen-Missionen abgeschlossen! Du wirst beim Rennen nie ermüden!
-[FET_SFG]
-SPIELE WERDEN GESUCHT...
+[ALEVEL:AMBULAE]
+Krankenwagen-Mission Level ~1~
-[FET_SRT]
-SPIELE WERDEN SORTIERT...
+[A_FAIL1:AMBULAE]
+Krankenwagen-Mission beendet.
-[FEF_LAN]
-LAN
+[A_SAVES:AMBULAE]
+GERETTETE MENSCHEN: ~1~
-[FEF_INT]
-INTERNET
+{=================================== MISSION TABLE ASSIN1 ===================================}
-[FET_REF]
-Aktualisieren
+[ASM1_5:ASSIN1]
+~r~Er hat seine Lieferungen abgeschlossen!
-[FET_FIL]
-Filter
+[ASM1_6:ASSIN1]
+Weitere Lieferungen:
-[FET_JG]
-Beitreten
+[ASM1_7:ASSIN1]
+~g~Carl Pearson, Pizza-Lieferant. Schalte ihn aus, bevor er seine Lieferungen abschließt.
-[FEC_NTW]
-Talk To Network
+[ASM1_A:ASSIN1]
+Mr. Teal, Ihre Hilfe bei der Beseitigung der Landeier war äußerst wertvoll. Ich habe noch mehr Arbeit, die eine eher 'zupackende' Art verlangt.
-[FEC_ESR]
-Esc-Taste nicht zugelassen
+[ASM1_D:ASSIN1]
+Mr. Teal, Ihre Hilfe bei der Beseitigung der Landeier war äußerst wertvoll.
-[FEC_GSL]
-Show head bob:
+{=================================== MISSION TABLE ASSIN2 ===================================}
-[FIL_FLT]
-SPIELE-LISTE FILTERN
+[ASM2_1:ASSIN2]
+~g~Mrs. Dawson verlässt bald den Juwelier in Vice Point. Schalte sie aus. Es muss wie ein Autounfall aussehen.
-[FET_SAN]
-NEUES SPIEL STARTEN
+[ASM2_3:ASSIN2]
+~g~Das Fahrzeug wird explodieren! Hau ab!
-[FIL_MAP]
-Karte:
+[ASM2_4:ASSIN2]
+~r~Du hast ihr Auto beschädigt, obwohl sie nicht drin saß! Jetzt wird sie nicht einsteigen!
-[FIL_SRV]
-Server:
+[ASM2_5:ASSIN2]
+~r~Sie ist entwischt!
-[FIL_TYP]
-Spiel-Typ
+[ASM2_6:ASSIN2]
+~r~Du warst zu nah am Unfallort!
-[FIL_SPC]
-Offene Spiele?
+[ASM2_7:ASSIN2]
+~g~Keine Waffen! Es soll wie ein Unfall aussehen! Dränge sie stattdessen von der Fahrbahn!
-[FIL_PNG]
-Ping:
+[ASM2_8:ASSIN2]
+~g~Das ganze muss wie ein Unfall aussehen. Benutze keine Waffen.
-[FEN_UKH]
-Unbekannter Host
+[ASM2_9:ASSIN2]
+Du brauchst einen fahrbaren Untersatz für diesen Job.
-[FEN_UKM]
-Map nicht gefunden
+[ASM2_10:ASSIN2]
+~g~Wenn ihr Auto in Flammen aufgeht, entferne dich so weit wie möglich von der Unfallstelle.
-[FEN_UKT]
-Spiel-Typ nicht gefunden
+[ASM2_11:ASSIN2]
+Hilfe!
-[FEN_NCI]
-KEINE INTERNET-VERBINDUNG
+[ASM2_12:ASSIN2]
+Hilf mir doch jemand!
-[FET_PAU]
-PAUSENMENÜ
+[ASM2_13:ASSIN2]
+Oh Gott!
-[FET_SGA]
-SPIEL STARTEN
+[ASM2_A:ASSIN2]
+Mein Kompliment für die gute Arbeit, Mr. Teal. Mein Kunde war sehr zufrieden.
-[FEC_PAD]
-Gamepad
+[ASM2_2:ASSIN2]
+Health:
-[FEC_JOY]
-Joystick
+{=================================== MISSION TABLE ASSIN3 ===================================}
-[FEC_WHL]
-Lenkrad
+[ASM3_11:ASSIN3]
+ZEIT:
-[FEC_CNT]
-Controller-Typ:
+[ASM3_C:ASSIN3]
+Eine europäische Gang plant einen Überfall auf eine Bank in Vice City. Meinen Arbeitgebern wäre sehr daran gelegen, dass das nicht passiert.
-[FET_APL]
-ÜBERNEHMEN
+[ASM3_D:ASSIN3]
+Alle Mitglieder der Gang haben eine Tarnung, solange sie sich hier in Vice City aufhalten. Manche haben Jobs, andere geben sich als Touristen aus.
-[FES_CSA]
-Wählen Sie eine Skin aus der Liste aus:
+[ASM3_E:ASSIN3]
+Infos über alle Zielpersonen und ihre wahrscheinlichen Aufenthaltsorte kleben unter dem Telefon.
-[FES_SKN]
-SKIN-NAME
+[ASM3_14:ASSIN3]
+~g~Dick Tanner hält sich bei DBP Security am Ocean Drive auf.
-[FES_DAT]
-DATUM
+[ASM3_15:ASSIN3]
+~g~Marc Hammond und Franco Carter halten sich in der Nähe des Juwelierladens in Vice Point auf.
-[FES_NON]
-KEINE SKINS VERFÜGBAR
+[ASM3_16:ASSIN3]
+~g~Nick Kong hält sich in der Nähe von Washington Beach auf.
-[FEA_FM9]
-SPIELER MP3
+[ASM3_18:ASSIN3]
+~g~Geh nicht zu nahe an deine Zielperson heran, sonst entdeckt sie dich und du musst hinter ihr herjagen.
-[FESZ_QZ]
-Dieses Spiel wirklich speichern?
+[ASM3_19:ASSIN3]
+~g~Er hat dich gesehen! Schalte ihn aus!
-[FES_CGA]
-Momentan verfügbare Speicherplätze:
+[ASM3_20:ASSIN3]
+~g~Sie haben dich gesehen! Schalte alle beide aus!
-[FES_SCG]
-Laufendes Spiel speichern?
+[ASM3_21:ASSIN3]
+~r~Du hast nicht alle Mitglieder der Gang rechtzeitig erledigt!
-[FES_LCG]
-Spiel laden und weiterspielen?
+[ASM3_22:ASSIN3]
+~g~Geh nicht zu nahe an deine Zielpersonen heran, sonst entdecken sie dich und versuchen zu fliehen.
-[FEC_FIR]
-Feuern
+[ASM3_12:ASSIN3]
+~g~In der Nähe sind einige Waffen für dich deponiert worden, falls du sie brauchen solltest. Du hast ~h~9 MINUTEN~g~, um alle Gang-Mitglieder auszuschalten.
-[FEC_NWE]
-Nächste Waffe
+[ASM3_13:ASSIN3]
+~g~Mike Griffin arbeitet an einer Plakatwand in Washington.
-[FEC_PWE]
-Vorherige Waffe
+[ASM3_17:ASSIN3]
+~g~Charlie Dilson fährt mit dem Motorrad in Washington herum.
-[FEC_FOR]
-Vorwärts
+{=================================== MISSION TABLE ASSIN4 ===================================}
-[FEC_BAC]
-Rückwärts
+[ASM4_10:ASSIN4]
+~g~Du warst anscheinend nicht der einzige, der hinter dem Aktenkoffer her war. Bring ihn schnell ins Ammu-Nation!
-[FEC_LEF]
-Links
+[ASM4_12:ASSIN4]
+Distanz:
-[FEC_RIG]
-Rechts
+[ASM4_15:ASSIN4]
+~g~Nimm das Präzisionsgewehr zu deiner Rechten.
-[FEC_ZIN]
-Heranzoomen
+[ASM4_16:ASSIN4]
+~g~Behalte die Frau auf der Empore im Auge. Sie wird die Rolltreppe hinuntergehen und die Zielperson nach der Uhrzeit fragen.
-[FEC_ZOT]
-Herauszoomen
+[ASM4_17:ASSIN4]
+~g~Schalte die Zielperson aus, NACHDEM die Frau mit ihr gesprochen hat. Aber erledige nicht die Frau.
-[FEC_EEX]
-Ein-/Aussteigen
+[ASM4_18:ASSIN4]
+~g~Wenn die Zielperson ausgeschaltet ist, nimm ihren Aktenkoffer und bringe ihn zum Ammu-Nation in Downtown.
-[FEC_RAD]
-Radio
+[ASM4_19:ASSIN4]
+~g~Halte Abstand von der Zielperson. Die Entfernungs-Anzeige rechts oben am Bildschirm zeigt an, wie nahe du an der Zielperson bist.
-[FEC_SUB]
-Spezialmission
+[ASM4_20:ASSIN4]
+~g~Lass den Anzeigebalken nicht an den Anschlag geraten, sonst sieht dich die Zielperson.
-[FEC_CMR]
-Blickwinkel ändern
+[ASM4_21:ASSIN4]
+~g~Schnapp dir den Aktenkoffer!
-[FEC_JMP]
-Springen
+[ASM4_22:ASSIN4]
+~g~Bring den Aktenkoffer zum Ammu-Nation in Downtown.
-[FEC_SPN]
-Sprinten
+[ASM4_23:ASSIN4]
+~g~Er hat dich entdeckt und versucht zu fliehen. Erledige ihn und schnapp dir den Aktenkoffer!
-[FEC_HND]
-Handbremse
+[ASM4_25:ASSIN4]
+~r~Du hast die Frau ausgeschaltet, du Idiot!
-[FEC_TUL]
-Geschütz links
+[ASM4_26:ASSIN4]
+~r~Die Zielperson hat das Flugzeug bestiegen!
-[FEC_TUR]
-Geschütz rechts
+[ASM4_27:ASSIN4]
+~r~Die Zielperson hat dich gesehen! Du hättest Abstand halten sollen!
-[FEC_LOL]
-Nach links schauen
+[ASM4_28:ASSIN4]
+~r~Die Zielperson hat dich gesehen! Er hat gehört, wie du geschossen hast!
-[FEC_LOR]
-Nach rechts schauen
+[ASM4_29:ASSIN4]
+~r~Schalte ihn erst aus, wenn er mit der Frau gesprochen hat!
-[FEC_NTR]
-Nächstes Ziel
+[ASM4_A:ASSIN4]
+Es wird Zeit für dickere Brocken, Mr. Teal. Unter dem Busch zu Ihrer Rechten ist ein Gewehr.
-[FEC_PTT]
-Vorheriges Ziel
+[ASM4_B:ASSIN4]
+Behalten Sie die Frau auf der Empore über dem Check-In im Auge. Sie wird durch die Menge gehen und jemanden nach der Uhrzeit fragen.
-[FEC_LBA]
-Nach hinten schauen
+[ASM4_C:ASSIN4]
+Sie müssen die betreffende Person ausschalten, ihren Aktenkoffer nehmen und ihn zu der Adresse, die unter dem Telefon klebt, bringen.
-[FEC_CEN]
-Kamera zentrieren
+{=================================== MISSION TABLE ASSIN5 ===================================}
-[FEC_UND]
-(NEIN)
+[ASM5_A:ASSIN5]
+Auf dem Dach der Cherry Popper-Eiscremefabrik findet eine Übergabe von wertvoller Ware statt.
-[FET_CFT]
-ZU FUSS
+[ASM5_B:ASSIN5]
+Erledigen Sie alle Beteiligten, klauen Sie die Ware und bringen Sie sie zum Heliport am Flughafen.
-[FET_CCR]
-IN FAHRZEUG
+[ASM5_C:ASSIN5]
+Links von Ihnen ist ein Tor, das zur Rückseite der Fabrik führt.
-[CVT_MSG]
-Texturen werden in optimales Format für Ihre Grafikkarte konvertiert
+[ASM5_1:ASSIN5]
+~g~Geh auf das Gelände hinter der Cherry Popper-Eiscremefabrik und dann auf das Dach, wo der Deal abgewickelt wird.
-[FET_CAC]
-AKTION
+[ASM5_2:ASSIN5]
+~g~Schnapp dir die Ware und bring sie zum Heliport am Flughafen.
-[FEC_IBT]
--
+[ASM5_3:ASSIN5]
+~g~Bring die Ware zum Heliport am Flughafen!
-[FEC_SPC]
-LEERT.
+{=================================== MISSION TABLE BANKJ1 ===================================}
-[FEC_MXO]
-MXB1
+[WANTED1:BANKJ1]
+~g~Schüttle die Cops ab. Verringere deinen Fahndungslevel.
-[FEC_MXT]
-MXB2
+[BJM1_A:BANKJ1]
+Tommy! Hey, Tommy, sieh mal, das ist super! Ich hab eine Minibar einbauen lassen!
-[FEC_UNB]
-NICHT BEL.
+[BJM1_B:BANKJ1]
+Wir haben unten eine ausgewachsene Bar, Ken.
-[FET_CME]
-STEUERUNGSART
+[BJM1_C:BANKJ1]
+Ja, ja, wie auch immer. Tja, ich hab die Tafel besorgt, die du haben wolltest.
-[FET_RDK]
-STEUERUNG ÄNDERN
+[BJM1_D:BANKJ1]
+Ah, das ist der Lohn des Jurastudiums: Die Fähigkeit, Anweisungen auszuführen.
-[FET_AMS]
-MAUS-EINSTELLG.
+[BJM1_E:BANKJ1]
+Also, ich brauche einen Safeknacker.
-[FET_STI]
-STANDARD STEURUNGSKONFIG.
+[BJM1_F:BANKJ1]
+Oh, ok, mal nachdenken...Safeknacker, Safeknacker...Ich hab's! Du wirst begeistert sein!
-[FET_CTI]
-CLASSIC STEURUNGSKONFIG.
+[BJM1_G:BANKJ1]
+Aah, nicht dieser Schwachkopf. Der sitzt doch.
-[FET_MTI]
-MAUS STEURUNGSKONFIG.
+[BJM1_H:BANKJ1]
+Wo sitzt er denn?
-[FET_DAM]
-DYNAMISCHE AKUSTIK
+[BJM1_I:BANKJ1]
+In einer Zelle in einem Polizeirevier. Er wartet auf seine Verlegung.
-[FEC_TFL]
-Geschütz Links
+[BJM1_J:BANKJ1]
+Ich glaube fast, er kommt auf Bewährung raus...
-[FEC_TFR]
-Geschütz Rechts
+[BJM1_1:BANKJ1]
+~g~Befreie Cam Jones aus der Haft!
-[FEC_TFU]
-Geschütz /Dodo aufwärts
+[BJM1_3:BANKJ1]
+~g~In der Umkleide des Reviers findest du etwas Nützliches.
-[FEC_TFD]
-Geschütz /Dodo abwärts
+[BJM1_21:BANKJ1]
+~g~Die Key Card zu den Zellen findet sich im Obergeschoss des Reviers.
-[FEC_MWF]
-RAD AUFW.
+[BNK1_7:BANKJ1]
+Cam Jones?
-[FEC_MWB]
-RAD ABW.
+[BNK1_8:BANKJ1]
+Ich hol dich hier raus.
-[FEC_ORR]
-oder
+[BNK1_10:BANKJ1]
+Ja, der bin ich...
-[FEC_NUS]
-NICHT VERWENDET
+[BNK1_11:BANKJ1]
+Ganz wie du meinst!
-[FEC_LUD]
-Aufw. Sehen
+[BNK1_13:BANKJ1]
+Ich ziehe einen Job durch, und du bist mein Safeknacker.
-[FEC_LDU]
-Abw. Sehen
+[BNK1_14:BANKJ1]
+Besser als in 'ner Zelle zu verrotten!
-[FEC_CMP]
-COMBO: L+R SEHEN
+[BJM1_22:BANKJ1]
+~g~Bring Cam nach Hause!
-[FEC_NTT]
-Noch kein Text für diese Taste
+[BJM1_23:BANKJ1]
+~g~Du brauchst zunächst die Magnetkarte für die Tür!
-[FEC_FNC]
-F~1~
+[BNK1_12:BANKJ1]
+Häng die Bullen ab und bring mich nach Hause!
-[FEC_IRT]
-EINFG
+[BJM1_20:BANKJ1]
+Die Waffe weg oder es passiert was!
-[FEC_DLL]
-ENTF
+[BJM1_5:BANKJ1]
+Zutritt ab hier nur für befugtes Personal.
-[FEC_HME]
-POS1
+[BJM1_2:BANKJ1]
+~r~Du solltest Cam die Freiheit bringen, nicht den Tod!
-[FEC_END]
-ENDE
+[BJM1_4:BANKJ1]
+Er ist bewaffnet! Erledigt ihn!
-[FEC_PGU]
-BILD AUF
+{=================================== MISSION TABLE BANKJ2 ===================================}
-[FEC_PGD]
-BILD AB
+[BJM2_A:BANKJ2]
+Wir brauchen einen Überfall-Experten. Kennt ihr einen?
-[FEC_UPA]
-AUF
+[BJM2_B:BANKJ2]
+Hey, Tommy, Tommy, Tommy, das Zeug bringt dich nach vorn, Mann.
-[FEC_DWA]
-AB
+[BJM2_C:BANKJ2]
+WoooOOOooo!
-[FEC_LFA]
-LINKS
+[BJM2_D:BANKJ2]
+Ich könnte dein Experte sein! Überfall! Überfall!
-[FEC_RFA]
-RECHTS
+[BJM2_E:BANKJ2]
+Du bist kein Experte, du bist ein Idiot.
-[FEC_NUM]
-NUM
+[BJM2_F:BANKJ2]
+Mach dir 'nen Drink und halt die Klappe.
-[FEC_NMN]
-NUM~1~
+[BJM2_G:BANKJ2]
+Hey, aus dem Weg!
-[FEC_FWS]
-NUM /
+[BJM2_H:BANKJ2]
+Cam, was meinst du?
-[FEC_PLS]
-NUM +
+[BJM2_I:BANKJ2]
+Tja, der beste Schütze in der Stadt ist ein Kerl namens Cassidy.
-[FEC_MIN]
-NUM -
+[BJM2_J:BANKJ2]
+Ach ja?
-[FEC_DOT]
-NUM ,
+[BJM2_K:BANKJ2]
+Ja. Soldat, oder wenigstens hält er sich dafür.
-[FEC_NLK]
-NUMLOCK
+[BJM2_L:BANKJ2]
+Ich bezweifle, dass er je bei der Army war, aber er kann mit der Knarre umgehen.
-[FEC_ETR]
-ENT
+[BJM2_M:BANKJ2]
+Wahrscheinlich ist er in der Schießanlage.
-[FEC_SLK]
-ROLLEN
+[BJM2_2A:BANKJ2]
+Bist du Phil Cassidy?
-[FEC_PSB]
-UNTBR
+[BJM2_2B:BANKJ2]
+Wieso?
-[FEC_BSP]
-RÜCKT.
+[BJM2_2C:BANKJ2]
+Ich suche einen, der mit der Kanone umgehen kann. Was ich hier so sehe, überzeugt mich nicht.
-[FEC_TAB]
-TAB
+[BJM2_2D:BANKJ2]
+Jungchen, ich schieße dir auf 25 Meter eine Fliege vom Kopf.
-[FEC_CLK]
-CAPSLOCK
+[BJM2_2E:BANKJ2]
+Ach wirklich?
-[FEC_RTN]
-RET
+[BJM2_2F:BANKJ2]
+Ja. Hab ich bei der Army gelernt.
-[FEC_LSF]
-LUMSCHALT
+[BJM2_2G:BANKJ2]
+Ist Fliegen-Schießen so beliebt in der Army? Gut, dass ich keine Steuern zahle.
-[FEC_RSF]
-RUMSCHALT
+[BJM2_2H:BANKJ2]
+Sollte das witzig sein, Jungchen?
-[FEC_LCT]
-LSTRG
+[BJM2_2I:BANKJ2]
+Ha ha ha ha ha!
-[FEC_RCT]
-RSTRG
+[BJM2_2J:BANKJ2]
+Lass uns schießen.
-[FEC_LAL]
-LALT
+[BJM2_1:BANKJ2]
+~g~Begib dich nach Downtown ins Ammu-Nation und sprich mit Phil Cassidy.
-[FEC_RAL]
-RALT
+[BJM2_3:BANKJ2]
+TREFFERQUOTE: ~1~%
-[FEC_LWD]
-LWIN
+[BJM2_4:BANKJ2]
+PUNKTE RUNDE EINS: ~1~
-[FEC_RWD]
-RWIN
+[BJM2_6:BANKJ2]
+PUNKTE RUNDE ZWEI: ~1~
-[FEC_WRC]
-WINKLICK
+[BJM2_7:BANKJ2]
+GESAMTPUNKTZAHL FÜR DAS SCHIESSEN: ~1~
-[WIN_TTL]
-GTA 3
+[BJM2_9:BANKJ2]
+~g~Begib dich zum Startpunkt für Runde Zwei.
-[WIN_95]
-GTA 3 läuft nicht unter Windows 95
+[BJM2_11:BANKJ2]
+~r~Phil ist erledigt!
-[WIN_DX]
-GTA 3 benötigt mind. DirectX Version 8.1
+[BJM2_12:BANKJ2]
+~r~Einer der Schützen ist erledigt!
-[WIN_VDM]
-GTA 3 benötigt mind. 12MB freien Grafikspeicher
+[BJM2_14:BANKJ2]
+~g~Begib dich zum nächsten Areal!
-[DIAB3_G]
-Arriba!
+[BJM2_15:BANKJ2]
+PUNKTE:
-[FEM_RES]
-SPIEL FORTSETZEN
+[BJM2_17:BANKJ2]
+~g~Sprich mit Phil.
-[FES_SNG]
-NEUES SPIEL STARTEN
+[BJM2_18:BANKJ2]
+ZU SCHLAGEN:
-[FEM_SP]
-SINGLEPLAYER
+[BJM2_19:BANKJ2]
+~g~Triff innerhalb des Zeitlimits so viele Ziele wie du kannst!
-[FEM_MP]
-MULTIPLAYER
+[BJM2_22:BANKJ2]
+~r~Du hast den Schießstand verlassen!
-[FEM_QT]
-SPIEL BEENDEN
+[BJM2_23:BANKJ2]
+~g~Wenn du den Schießstand während des Wettbewerbs verlässt, ist die Mission gescheitert.
-[FES_SG]
-NEUES SPIEL STARTEN
+[BJM2_24:BANKJ2]
+~g~Das nahegelegenste Ziel bringt 1 Punkt.
-[FES_LG]
-SPIEL LADEN
+[BJM2_25:BANKJ2]
+~g~Das mittlere Ziel bringt 2 Punkte.
-[FEM_HST]
-SPIEL HOSTEN
+[BJM2_27:BANKJ2]
+~g~Alle Ziele dieser Runde bringen 1 Punkt.
-[FEM_OPT]
-OPTIONEN
+[BNK2_2:BANKJ2]
+ZIELEN 3-2-1 FEUER!
-[FEM_DBG]
-DEBUG
+[BNK2_3:BANKJ2]
+AREAL KLAR!
-[FET_PSU]
-SPIELER SETUP
+[BNK2_4:BANKJ2]
+Huuuiii!
-[FET_DEF]
-STANDARD WIEDERHERST.
+[BNK2_5:BANKJ2]
+Der träfe nicht mal ein Scheunentor.
-[FED_BRI]
-HELLIGKEIT
+[BNK2_7:BANKJ2]
+Also, was ist jetzt, hilfst du mir bei dem Job?
-[FED_TRA]
-UNSCHÄRFE-FX
+[BNK2_8:BANKJ2]
+Jungchen, so wie du schießt, würde ich dich sogar heiraten.
-[FEM_LOD]
-DISTANZ-DARSTELLG.
+[BNK2_9A:BANKJ2]
+Junge, deine Sprüche und deine Hirngespinste kannst du dir sonst wohin stecken. Du bist ein lausiger Schütze.
-[FEM_VSC]
-FRAME SYNC
+[BNK2_9B:BANKJ2]
+Du bist ein lausiger Schütze.
-[FEM_FRM]
-FRAME LIMITER
+[BJM2_28:BANKJ2]
+PUNKTE RUNDE DREI: ~1~
-[FED_RES]
-BILDSCHIRMAUFLSG.
+[BJM2_20:BANKJ2]
+~g~Geht dir die ~w~Zeit ~g~oder die ~w~Munition ~g~aus, ist die Runde beendet!
-[FED_WIS]
-BREITBILD
+[BJM2_26:BANKJ2]
+~g~Das am weitesten entfernte Ziel bringt 3 Punkte.
-[FEDS_TB]
-ZURÜCK
+[BNK2_1:BANKJ2]
+SCHARFE MUNITION
-[FEA_MUS]
-MUSIK VOLUME
+[RANGE_1:BANKJ2]
+PUNKTZAHL SCHIESS-RUNDE:~1~
-[FEA_SFX]
-SFX VOLUME
+[BJM2_2:BANKJ2]
+~g~Um die Runde zu beenden, drücke die ~h~~k~~PED_JUMPING~.
-[FEA_RSS]
-RADIOSENDER
+[BJM2_N:BANKJ2]
+Nur die Ruhe.
-[FEL_ENG]
-ENGLISCH
+{=================================== MISSION TABLE BANKJ3 ===================================}
-[FEL_FRE]
-FRANZ.
+[BJM3_A:BANKJ3]
+Langsam fügt sich alles sehr schön zusammen hier.
-[FEL_GER]
-DEUTSCH
+[BJM3_B:BANKJ3]
+Was ist der Plan, Tommy? Was geht ab, Amigo?
-[FEL_ITA]
-ITALIEN.
+[BJM3_C:BANKJ3]
+Der Plan ist, dass du dich wie ein Vollidiot benimmst. Wir brauchen einen Fahrer.
-[FEL_SPA]
-SPANISCH
+[BJM3_D:BANKJ3]
+Tommy, ich mach's. Ich kann fahren.
-[FEA_3DH]
-AUDIO HARDWARE
+[BJM3_E:BANKJ3]
+Nimm Hilary, Boss, nicht diesen Labersack von einem Rechtverdreher.
-[FEA_SPK]
-BOXEN KONFIGURATION
+[BJM3_F:BANKJ3]
+Hilary ist der beste. So schnell wie den hast noch keinen fahren sehen. Ich rufe ihn mal an.
-[FEA_2SP]
-2 BOXEN
+[BJM3_G:BANKJ3]
+Hey, Hil, hier Phil. Wie läuft's? Nein, sag nichts. Dazu haben wir später Zeit. Tust du mir einen Gefallen?
-[FEA_4SP]
-MEHR ALS 2 BOXEN
+[BJM3_H:BANKJ3]
+Ich hab hier einen Typ aus dem Norden. Nein, ich glaub, er war nicht beim Militär. Aber er braucht einen Fahrer.
-[FEA_EAR]
-KOPFHÖRER
+[BJM3_I:BANKJ3]
+Für einen Job. Ok, verstehe.
-[FEA_NAH]
-KEINE AUDIO HARDWARE
+[BJM3_J:BANKJ3]
+Was hat er gesagt?
-[FET_SNG]
-NEUES SPIEL STARTEN
+[BJM3_K:BANKJ3]
+Er macht's. Kein Problem. Na ja, ein kleines vielleicht: Er leidet unter Verlustängsten.
-[FEN_STA]
-SPIEL STARTEN
+[BJM3_L:BANKJ3]
+Er arbeitet anscheinend nicht für Leute, die ihn nicht schlagen können. Hat was mit seiner Mutter zu tun.
-[GMLOAD]
-SPIEL LADEN
+[BJM3_M:BANKJ3]
+Jedenfalls will er erst ein Rennen gegen dich fahren. Er wartet draußen auf dich.
-[GMSAVE]
-SPIEL SPEICHERN
+[BJM3_2A:BANKJ3]
+Bist du Tommy? Klar bist du Tommy, ich meine,
-[FES_DGA]
-SPIEL LÖSCHEN
+[BJM3_2B:BANKJ3]
+wieso sollte sonst einer mit mir reden wollen?
-[FEM_NON]
-KEIN
+[BJM3_2C:BANKJ3]
+Ok. Das ganze läuft so ab:
-[FEC_IVV]
-MAUS VERTIKAL INVERTIEREN
+[BJM3_2D:BANKJ3]
+Ich fahre für dich, WENN und NUR WENN du selbst anständig fährst.
-[FEC_MSH]
-MAUSEMPFINDLICHKEIT
+[BJM3_2E:BANKJ3]
+Verlierst du mich, verzeihe ich dir das nie.
-[FET_CCN]
-STEUERUNG: CLASSIC
+[BJM3_2:BANKJ3]
+Hilary ist erledigt!
-[FET_SCN]
-STEUERUNG: STANDARD
+[BJM3_4:BANKJ3]
+~g~Du brauchst ein Auto, um mitzumachen.
-[FES_SET]
-SKIN VERWENDEN
+[BNK3_1:BANKJ3]
+Ok, ich fahre für dich. Aber bitte, behandle mich schlecht.
-[GHOST]
-Ghost
+[BNK3_3A:BANKJ3]
+Illegales Straßenrennen bei Vice Point.
-[WIN_RSZ]
-Neue Auflösung konnte nicht aktiviert werden
+[BNK3_3B:BANKJ3]
+An alle Einsatzkräfte.
-[FET_APP]
-LMT,RETURN,UM NEUE EINSTLLG. ZU SPEICHERN
+[BNK3_3C:BANKJ3]
+Straßenrennen sind verboten und illegal!
-[FET_HRD]
-STANDARDEINSTLLG. WIEDERHERGESTELLT
+{=================================== MISSION TABLE BANKJ4 ===================================}
-[FET_MST]
-MAUSSTEUERUNG
+[BNK4_A:BANKJ4]
+~w~Ihr seht Gentlemen, das wird leicht verdientes Geld für uns.
-[FEC_STR]
-NUM STERN
+[BNK4_B:BANKJ4]
+~w~Ernsthaft, Tommy, du solltest dir überlegen, Anwalt zu werden.
-[FET_MIG]
-LINKS,RECHTS,MAUSRAD ZUR EINSTLLG.
+[BNK4_C:BANKJ4]
+~w~Was zum Geier rauchst du eigentlich, Mann? Das ist kein simpler Plan.
-[FET_CIG]
-RÜCKT. ZUM LÖSCHEN - LMT,RETURN ZUM ÄNDERN
+[BNK4_D:BANKJ4]
+~w~Ach, wer braucht schon simple Pläne?
-[FET_RIG]
-NEUE STEUERUNG FÜR DIESE AKTION WÄHLEN ODER ESC FÜR ABBRUCH
+[BNK4_E:BANKJ4]
+~w~Der Kommunismus, das war ein simpler Plan. Hat Russland aber nicht viel genützt, hah?
-[FET_EIG]
-KANN DIESER AKTION KEINE STEUERUNG ZUWEISEN
+[BNK4_F:BANKJ4]
+~w~Ganz ruhig. Mit einem Team wie diesem ist das alles kein Problem.
-[NO_PCCD]
-Bitte legen Sie die GTA 3 Disk 2 ein oder drücken Sie ESC zum Abbrechen
+[BNK4_G:BANKJ4]
+~w~Cam übernimmt den Safe. Phil? Wir beide kümmern uns um die Sicherheit, und Hilary fährt den Fluchtwagen.
-[CVT_ERR]
-Kein Platz mehr auf der Festplatte. Bitte schaffen Sie Speicherplatz, bevor Sie fortfahren. ESC zum Abbrechen.
+[BNK4_H:BANKJ4]
+~w~Äh, hast du nicht jemanden vergessen? Jemanden, der dir unzählige Male geholfen hat in dieser Stadt? Jemanden...?
-[FED_SUB]
-UNTERTITEL
+[BNK4_I:BANKJ4]
+~w~Ken...Ken, richtig. Ken wäscht das Geld für uns und stellt schon mal die Drinks kalt.
-[FET_DSN]
-Standard-Player Skin.bmp
+[BNK4_J:BANKJ4]
+~w~Ich verstehe nicht, was ich hier soll.
-[EBAL]
-'GIB MIR LIBERTY'
+[BNK4_K:BANKJ4]
+~w~Ist doch ganz einfach. Warst du noch nie im Kino?
-[LM4]
-'PUMP-ACTION-THRILLER'
+[BNK4_L:BANKJ4]
+~w~Wir latschen in die Bank rein, fuchteln mit den Knarren rum und gehen stinkreich wieder raus.
-[REPLAY]
-WIEDERHOLUNG
+[P_DEAD:BANKJ4]
+~r~Phil ist erledigt!!
-[FEC_SFT]
-UMSCHALT
+[C_DEAD:BANKJ4]
+~r~Cam ist erledigt!!
-[CRED254]
-STUDIO MANAGER
+[H_DEAD:BANKJ4]
+~r~Hilary ist erledigt!!
-[CVT_CRT]
-Texturen können nicht für Ihre Grafikkarte konvertiert werden. Sie müssen sich als Administrator einloggen, damit dies möglich ist. Verlassen mit ESC.
+[P_HIND:BANKJ4]
+~r~Du hast Phil verloren!
-[FEM_ON]
-AN
+[C_HIND:BANKJ4]
+~r~Cam wurde abgehängt!
-[FEM_OFF]
-AUS
+[H_HIND:BANKJ4]
+~r~Hilary wurde im Stich gelassen!
-[FEM_YES]
-JA
+[GETCAR:BANKJ4]
+Steig in den Fluchtwagen und führe den Plan aus!
-[FEM_NO]
-NEIN
+[TRASHED:BANKJ4]
+~r~DU HAST DEN FLUCHTWAGEN GESCHROTTET!!
-[FES_WAR]
-Speichere Daten, bitte warten...
+[BNK4_1:BANKJ4]
+Ich fahre.
-[FED_DLW]
-Lösche Daten, bitte warten...
+[BNK4_2:BANKJ4]
+Na prima. Beifahrer. Wenn ich das in der Therapie erzähle.
-[FED_LDW]
-Lade Daten, bitte warten...
+[BNK4_3A:BANKJ4]
+Hey, pass auf, wo du hinfährst, Tommy!
-[FEC_SLC]
-Slot ist beschädigt
+[BNK4_3B:BANKJ4]
+Tommy, Hilary macht sich so breit!
-[FED_LFL]
-Spiel konnte nicht geladen werden. Das Spiel wird neu gestartet.
+[BNK4_3C:BANKJ4]
+Stimmt gar nicht!
-[FET_RSO]
-ORIGINAL-EINSTELLG. WIEDERHERGESTELLT
+[BNK4_3D:BANKJ4]
+Doch!
-[FET_RSC]
-HARDWARE NICHT VERFÜGBAR - ORIGINAL-EINSTELLG. WIEDERHERGESTELLT
+[BNK4_3E:BANKJ4]
+Hey, Klappe, ihr zwei, oder ihr könnt zu Fuß gehen.
-[CRED270]
-MIKE HONG
+[BNK4_3F:BANKJ4]
+Ja, Hilary.
+
+[BNK4_3I:BANKJ4]
+Herrgott, Phil, hör auf, mit diesem Ding rumzufuchteln!
+
+[BNK4_3J:BANKJ4]
+Ja, am Ende geht das noch ins Auge!
+
+[BNK4_3M:BANKJ4]
+Mein Baby! Alles Schrott!
+
+[BNK4_3O:BANKJ4]
+Du hängst zu sehr an der Illusion der Ewigkeit.
+
+[BNK4_3P:BANKJ4]
+Was?
+
+[BNK4_3Q:BANKJ4]
+Du denkst, alles bleibt ewig.
+
+[BNK4_3R:BANKJ4]
+Jugend, geliebte Menschen, Pizza,
+
+[BNK4_3S:BANKJ4]
+Alles geht mal vorbei, und das musst du akzeptieren.
+
+[BNK4_3T:BANKJ4]
+Hey, du hast recht. Danke, Cam.
+
+[BNK4_3U:BANKJ4]
+Nichts zu danken.
+
+[BNK4_3V:BANKJ4]
+Hey, Tommy, wieso halten wir?
+
+[BNK4_4A:BANKJ4]
+~w~Hilary, fahr ein bisschen um den Block.
+
+[BNK4_5:BANKJ4]
+~w~Ok, Tommy, ok.
+
+[BNK4_6:BANKJ4]
+~w~DIES IST EIN ÜBERFALL!
+
+[BNK4_7:BANKJ4]
+~w~KEINER BEWEGT SICH!
+
+[BNK4_8:BANKJ4]
+~w~ALLE AN DIE WAND!
+
+[BNK4_9:BANKJ4]
+Phil, halt die Stellung!
+
+[BNK4_10:BANKJ4]
+Verstanden!
+
+[BNK4_11:BANKJ4]
+Los Cam, der Tresor ist oben...
+
+[BK4_12A:BANKJ4]
+Verdammt, das ist ein Flange 9000!
+
+[BK4_12B:BANKJ4]
+Könnte Stunden dauern, den zu knacken.
+
+[BK4_12C:BANKJ4]
+Oder 5 Minuten, wenn du den Manager findest.
+
+[BNK4_13:BANKJ4]
+Ich seh nach, wo er sich verkrochen hat.
+
+[BK4_14A:BANKJ4]
+Phil, alles im grünen Bereich?
+
+[BNK4_15:BANKJ4]
+Klar. Im dunkelgrünen Bereich.
+
+[BNK4_16:BANKJ4]
+Du da! Mitkommen!
+
+[BNK4_17:BANKJ4]
+Ok! Ok! Nicht schießen!
+
+[BNK4_18:BANKJ4]
+ICH SAGTE, KEINER RÜHRT SICH!
+
+[BK4_19A:BANKJ4]
+Der Safe hat eine Zeitsperre,
+
+[BK4_19B:BANKJ4]
+ihr könnt ebenso gut gleich aufgeben!
+
+[BK4_20A:BANKJ4]
+Ach, die Zeitsperre kann ich umgehen.
+
+[BK4_20B:BANKJ4]
+Dann brauchen wir nur noch deinen Code und alles ist in Butter!
+
+[BNK4_21:BANKJ4]
+Bleib hier. Wenn du Zicken machst, bist du Fischfutter, klar?
+
+[BNK422A:BANKJ4]
+Cam, wie lange noch?
+
+[BK4_23A:BANKJ4]
+Gib mir noch 3 Minuten!
+
+[BK4_24A:BANKJ4]
+Ich seh mal nach Phil. Bin gleich wieder da.
+
+[BK4_24B:BANKJ4]
+Ich hab gesagt, Finger weg vom Alarm!
+
+[BNK4_25:BANKJ4]
+Das Spezialkommando muss gleich hier sein!
+
+[BNK4_27:BANKJ4]
+Ich könnte ein bisschen Hilfe brauchen, Tommy!
+
+[BNK4_28:BANKJ4]
+Vice City Spezialkommando! Sie sind umzingelt!
+
+[BNK4_29:BANKJ4]
+Umzingelt? HA HA HA HAAAAAaaa!
+
+[BNK4_30:BANKJ4]
+Die scheißen sich ein, die korrupten Schweine!
+
+[BK4_31A:BANKJ4]
+Tommy, der Tresor ist offen!
+
+[BK4_34A:BANKJ4]
+Ok, wir haben die Pensionskasse der Bullen. Los, raus hier!
+
+[BK4_34B:BANKJ4]
+Ok, ihr habt es so gewollt. Ihr hattet eure letzte Chance!
+
+[BK4_35A:BANKJ4]
+Die stürmen den Laden!
+
+[BK4_35B:BANKJ4]
+In Deckung!
+
+[BNK4_94:BANKJ4]
+~w~Ok, Jungs. Jeder hält sich an den Plan .
+
+[BM_DEAD:BANKJ4]
+~r~Du brauchst den Bank Manager lebend!!
+
+[ASSET_A:BANKJ4]
+BANK-MISSIONEN ERFÜLLT!
+
+[ASSET_B:BANKJ4]
+~g~Der Malibu Club generiert nun bis zu $~1~ Einkünfte. Hol dir das Geld regelmäßig ab.
+
+[IDIOT:BANKJ4]
+~r~Na super - angezogen wie ein Irrer durch die Gegend laufen und Aufmerksamkeit erregen, IDIOT!
+
+{=================================== MISSION TABLE BARON1 ===================================}
+
+[COK1_A:BARON1]
+Komm schon, Brauner, komm!
+
+[COK1_B:BARON1]
+Dämlicher Klepper! Dich mach ich einen Kopf kürzer!
+
+[COK1_C:BARON1]
+Wer ist der Blödmann?
+
+[COK1_D:BARON1]
+Tommy Vercetti, Sie erinnern sich.
+
+[COK1_E:BARON1]
+Tschuldigung, ich bin etwas nervös. Vertrau niemals einem verdammten Pferd!
+
+[COK1_F:BARON1]
+Du machst deine Sache gut. Du arbeitest jetzt für mich.
+
+[COK1_H:BARON1]
+Wie gesagt, Amigo, du arbeitest für mich. Basta. So ein Mistkerl hat mich betrogen.
+
+[COK1_I:BARON1]
+Er denkt, ich weiß nicht, wie viel Geld mir zusteht. Aber 3% zu klauen ist genauso schlimm wie 100% zu klauen.
+
+[COK1_J:BARON1]
+Niemand haut mich übers Ohr. NIEMAND!!
+
+[COK1_K:BARON1]
+Folge ihm von seiner Wohnung aus und sieh nach, wo er hin will. Später erledigen wir ihn.
+
+[COK1_1:BARON1]
+Oh, Shit!
+
+[COK1_2:BARON1]
+Zu langsam, Opa!
+
+[COK1_4:BARON1]
+Versager.
+
+[COK1_5:BARON1]
+Ich würde einen Zahn zulegen, du Mistsack!
+
+[COK1_8:BARON1]
+~g~Schnell! Schnapp dir einen Untersatz und folge ihm!
+
+[COK1_9:BARON1]
+~r~Du sollst ihn verfolgen, nicht umlegen!
+
+[COK1_10:BARON1]
+~r~Begib dich zum Haus des Diebes und such das Geldversteck.
+
+[COK1_11:BARON1]
+~g~Schau durch sein Fenster.
+
+[COK1_7:BARON1]
+~g~Er ist aufs Dach geflohen. Bleib ihm auf den Fersen, aber erledige ihn nicht.
+
+[COK1_G:BARON1]
+Ich arbeite gegen Geld.
+
+{=================================== MISSION TABLE BARON2 ===================================}
+
+[COK2_A:BARON2]
+Was bist du eigentlich für ein inkompetenter Narr?
+
+[COK2_B:BARON2]
+NARR! NARR! NARR! NARR!
+
+[COK2_C:BARON2]
+Tommy-
+
+[COK2_D:BARON2]
+Was, Ricardo?
+
+[COK2_E:BARON2]
+Diese Idioten - dauernd wollen sie einen reinlegen.
+
+[COK2_F:BARON2]
+Das ist der Fehler an dieser Branche.
+
+[COK2_G:BARON2]
+Was soll denn das? Aaaaah!
+
+[COK2_H:BARON2]
+Diese Mistkerle haben mich bitter enttäuscht.
+
+[COK2_I:BARON2]
+Bald denkt jeder Depp, er kann in Vice City Koks verkaufen.
+
+[COK2_J:BARON2]
+Was kommt als nächstes, hah? Die verstunkene Mafia?!
+
+[COK2_K:BARON2]
+Diese Bandengegend ist eine Festung ohne Mauern.
+
+[COK2_L:BARON2]
+Also: Quentin hier - Quentin! QUENTIN!
+
+[COK2_M:BARON2]
+Er fliegt dich über das Areal.
+
+[COK2_N:BARON2]
+Heb ihr Nest aus!
+
+[COK2_O:BARON2]
+Was soll denn das?
+
+[COK2_P:BARON2]
+Was willst du hier?
+
+[COK2_Q:BARON2]
+Hey, ich hab mich umgehört, und es ist klar,
+
+[COK2_R:BARON2]
+dass Diaz in den Deal reingeplatzt ist und meinen Bruder erledigt hat.
+
+[COK2_S:BARON2]
+Und dich erledigt er auch!
+
+[COK2_T:BARON2]
+Mit Diaz nehm ich's auf!
+
+[COK2_U:BARON2]
+Nein, hör zu! Ich übernehme Diaz -
+
+[COK2_V:BARON2]
+er beginnt mir zu vertrauen.
+
+[COK2_1:BARON2]
+Eines versteh ich nicht: Was soll das mit 'Quentin'!?
+
+[COK2_2:BARON2]
+Weiß nicht. Hat mir immer gefallen...Quentin Vance...
+
+[COK2_3:BARON2]
+Vance? Du heißt wirklich Lance Vance?!
+
+[COK2_4:BARON2]
+Hey! Das hab ich schon in der Schule oft genug gehört!
+
+[COK2_5:BARON2]
+Hast du so was schon mal aus einem Helikopter abgefeuert?
+
+[COK2_8:BARON2]
+Wo fliegen wir denn hier?
+
+[COK2_9:BARON2]
+Prawn Island.
+
+[COK2_13:BARON2]
+'Lance Vance'. Du armer Teufel.
+
+[COK2_14:BARON2]
+Ok, wir sind gleich da.
+
+[COK2_15:BARON2]
+Wir fliegen ein paar Mal drüber weg.
+
+[COK2_16:BARON2]
+Schalte so viele Kerle aus wie du kannst.
+
+[COK2_17:BARON2]
+Dann setze ich dich ab, und du bist auf dich allein gestellt.
+
+[COK2_20:BARON2]
+Shit! Das ist ja wie im Krieg hier! Schalt welche von den Schützen aus!
+
+[COK2_21:BARON2]
+Wir werden getroffen, Mann!
+
+[COK2_22:BARON2]
+Reparaturen an dem Kübel hier kosten! Schalt sie aus!
+
+[COK2_23:BARON2]
+Ok, von jetzt an bist du auf dich alleine gestellt. Viel Glück!
+
+[COK2_24:BARON2]
+Zustand Helikopter:
+
+[COK2_25:BARON2]
+~g~Hol das Geld auf dem Dach.
+
+[COK2_27:BARON2]
+Du bist auf MEINEM Gebiet, Mistkerl!
+
+[COK2_28:BARON2]
+Dich mach ich fertig!
+
+[COK2_6:BARON2]
+Nein. Aber ich kann ja unterwegs ein bisschen üben.
+
+[OPEN_B:BARON2]
+Die Straßensperren zum Festland sind aufgehoben worden.
+
+{=================================== MISSION TABLE BARON3 ===================================}
+
+[COK3_A:BARON3]
+Das gefällt euch nicht, was?!
+
+[COK3_B:BARON3]
+Ahahahahaa, Ahahahahaa.
+
+[COK3_C:BARON3]
+Vorsicht! Passen Sie auf, wo Sie damit hin zielen!
+
+[COK3_D:BARON3]
+Kein Taubendreck mehr auf MEINEM Dach, was Tommy?
+
+[COK3_E:BARON3]
+Sieht nicht so aus.
+
+[COK3_F:BARON3]
+Das kannst du laut sagen. Also, hör zu:
+
+[COK3_G:BARON3]
+Weißt du, wem das schnellste Boot an der Ostküste gehört?
+
+[COK3_H:BARON3]
+Nicht wirklich.
+
+[COK3_I:BARON3]
+MIR. Und das soll auch so bleiben.
+
+[COK3_J:BARON3]
+Jeder Schmuggler von hier bis Caracas hat EINEN Traum: ein schnelleres Boot.
+
+[COK3_K:BARON3]
+Es heißt, die Hull Werft hat gerade so ein Boot fertiggestellt,
+
+[COK3_L:BARON3]
+für irgendeinen costaricanischen Idioten.
+
+[COK3_M:BARON3]
+Und, Tommy...ICH WILL DIESES BOOT!!!
+
+[COK3_N:BARON3]
+Ich glaube, die Tauben sind wieder da.
+
+[COK3_O:BARON3]
+Ah! Ich dachte, ich hab euch erwischt. Wo kommst du denn her?
+
+[COK3_P:BARON3]
+Tauben! Boom! Aaaaah!
+
+[COK3_5:BARON3]
+~g~Suche den Schalter, um das Boot abzusenken.
+
+[COK3_6:BARON3]
+~g~Bringe das Boot zur Villa.
+
+[COK3_7:BARON3]
+~r~Du hast das Boot zerstört!
+
+[COK3_8:BARON3]
+~g~Begib dich zur Bootswerft an den Docks und klau das schnellste Boot.
+
+[COK3_9:BARON3]
+~g~Jetzt steig in das Boot.
+
+{=================================== MISSION TABLE BARON4 ===================================}
+
+[COK4_A:BARON4]
+Eject! PLASTIKMÜLL!
+
+[COK4_B:BARON4]
+Wie kannst du mir das antun?
+
+[COK4_C:BARON4]
+Was bildest du dir ein, du mieses Stück Plastikdreck! Aaargh!
+
+[COK4_D:BARON4]
+VERDAMMT!
+
+[COK4_E:BARON4]
+Wenn das Ding meinen Lieblings-El-Burro-Film frisst, ist Sense!
+
+[COK4_F:BARON4]
+Was kann ich noch tun?
+
+[COK4_G:BARON4]
+Ist wahrscheinlich nicht eingesteckt.
+
+[COK4_H:BARON4]
+Was?
+
+[COK4_I:BARON4]
+Verdammt. Egal, ich kann mir noch 100 davon kaufen.
+
+[COK4_J:BARON4]
+Also, Tommy,
+
+[COK4_K:BARON4]
+jeden Monat legt ein 'Freiberufler' mit seiner Jacht in Vice City an.
+
+[COK4_L:BARON4]
+Er verkauft seine Fracht an das erstbeste Schiff.
+
+[COK4_M:BARON4]
+Du schnappst dir das Rennboot,
+
+[COK4_N:BARON4]
+und bist vor allen anderen Pennern bei ihm.
+
+[COK4_O:BARON4]
+Dann bringst du die Fracht hierher, ok?
+
+[COK4_P:BARON4]
+Lass mich raten. Du dachtest, ich brauche einen Schutzengel.
+
+[COK4_Q:BARON4]
+Ich denke nur, du solltest mich mitnehmen, Mann.
+
+[COK4_R:BARON4]
+Du kannst lange den einsamen Macho-Helden markieren,
+
+[COK4_S:BARON4]
+aber eines Tages werde ich dir den Hintern retten
+
+[COK4_T:BARON4]
+und du wirst mich wahrscheinlich dafür küssen wollen.
+
+[COK4_U:BARON4]
+Spinner.
+
+[COK4_V:BARON4]
+Hahahaha!
+
+[COK4_1:BARON4]
+Tommy, wir wissen, es war Diaz, der unseren Deal platzen ließ.
+
+[COK4_3:BARON4]
+Wieso spielen wir dann die Laufburschen für ihn?
+
+[COK4_4:BARON4]
+Je mehr wir jetzt lernen, desto weniger müssen wir lernen, wenn wir diese Stadt übernehmen!
+
+[COK4_5:BARON4]
+Dein Stil gefällt mir. Echt erfrischend.
+
+[COK4_12:BARON4]
+Pass auf, die kommen von überall
+
+[COK4_13:BARON4]
+Erwischt! Fahr zu Diaz so schnell du kannst!
+
+[COK4_14:BARON4]
+Willst du was abhaben?
+
+[COK4_15:BARON4]
+Schönen Gruß an die Fische!
+
+[COK4_16:BARON4]
+Nimm das! Und das!
+
+[COK4_19:BARON4]
+Gleich kommt's noch dicker!
+
+[COK4_20:BARON4]
+Da sind Schützen auf dem Pier!
+
+[COK4_24:BARON4]
+Gut geschossen, mein Freund. Du bist ein erstklassiger Psycho.
+
+[COK4_25:BARON4]
+Danke sehr.
+
+[COK4_26:BARON4]
+Wir sehen uns, Tommy.
+
+[COK4_27:BARON4]
+Ok, Mr. Lance Vance Dance.
+
+[COK4_28:BARON4]
+~g~Sei vor den anderen Booten bei der Jacht!
+
+[COK4_31:BARON4]
+~g~Begib dich zum schnellsten Boot auf dem Pier!
+
+[COK4_32:BARON4]
+~r~Zu langsam!
+
+[COK4_33:BARON4]
+~r~Du hast das Boot zerstört!
+
+[COK4_34:BARON4]
+~g~Zieh diese Boote aus dem Verkehr!
+
+[COK4_35:BARON4]
+Zustand Boot:
+
+{=================================== MISSION TABLE BARON5 ===================================}
+
+[PROP_A:BARON5]
+OBJEKT ERWORBEN!
+
+[COK4_30:BARON5]
+~r~Lance ist erledigt!
+
+[ASS1_A:BARON5]
+Im Kofferraum sind ein paar Kanonen.
+
+[ASS1_B:BARON5]
+Wahnsinn! Wo hast du denn die alle her?
+
+[ASS1_C:BARON5]
+Hab ich für schlechte Zeiten zurückgelegt.
+
+[ASS1_D:BARON5]
+Zufrieden?
+
+[ASS1_E:BARON5]
+Ja. Und wie!
+
+[ASS1_F:BARON5]
+Ihr dämlichen Idioten!
+
+[ASS1_G:BARON5]
+Mein schönes Haus
+
+[ASS1_H:BARON5]
+Seht euch an, was ihr angestellt habt!
+
+[ASS1_I:BARON5]
+Das ist für meinen Bruder!
+
+[ASS1_J:BARON5]
+Ich habe dir vertraut, Tommy.
+
+[ASS1_K:BARON5]
+Ich hätte was aus dir gemacht...
+
+[ASS1_L:BARON5]
+Gute Nacht, Mr. Diaz.
+
+[ASS1_1:BARON5]
+Bald wimmelt's hier von Arschlöchern. Sei vorsichtig.
+
+[ASS1_2:BARON5]
+Keine Panik, Tommy, ich geb dir Deckung.
+
+[ASS1_13:BARON5]
+DIAZ?! Ich bin hier, um deinen Laden zu übernehmen!
+
+[ASS1_14:BARON5]
+TOMMY! Du Verräter...Du Idiot! Dich mache ich fix und fertig...
+
+[ASS1_16:BARON5]
+~g~Erledige Diaz!
+
+[BUD1:BARON5]
+Lance
+
+[ASS1_18:BARON5]
+~g~Die Tür ist verschlossen. Versuche es auf einem anderen Weg.
+
+[ASS1_19:BARON5]
+Da lang!
+
+[ASS1_20:BARON5]
+Tommy, ich hab ein Problem mit Quentin, nicht mit dir, Mann!
+
+{=================================== MISSION TABLE BIKE1 ===================================}
+
+[BM1_A:BIKE1]
+Wo ist Baker?
+
+[BM1_B:BIKE1]
+Ich suche Big Mitch Baker...
+
+[BM1_C:BIKE1]
+Wer sucht ihn?
+
+[BM1_D:BIKE1]
+Tommy Vercetti.
+
+[BM1_E:BIKE1]
+Vercetti.
+
+[BM1_F:BIKE1]
+Du siehst nicht wie ein Bulle aus, das heißt, du hast 1 Minute.
+
+[BM1_G:BIKE1]
+Also drück auf die Tube.
+
+[BM1_H:BIKE1]
+Kent Paul sagt, ihr wärt interessiert, die Security für einen Gig zu übernehmen, den er plant.
+
+[BM1_I:BIKE1]
+Kent Paul? Pfff! Kein Wunder, dass er dich schickt.
+
+[BM1_J:BIKE1]
+Als er das letzte Mal hier war, ist er durch Fenster wieder gegangen - und zwar splitternackt.
+
+[BM1_K:BIKE1]
+Seid ihr nun interessiert oder nicht?
+
+[BM1_L:BIKE1]
+Gefälligkeiten gibt's nur für Mitglieder.
+
+[BM1_M:BIKE1]
+Wie kann ich beitreten?
+
+[BM1_N:BIKE1]
+Wir sind hier kein Golfklub, Kleiner. Kannst du 'n Bike fahren?
+
+[BM1_O:BIKE1]
+Kannst du auf 'm Barhocker sitzen und saufen?
+
+[BM1_P:BIKE1]
+Cougar, Zeppelin, checkt mal ab, wie diese Sissy hier fährt.
+
+[BM1_2:BIKE1]
+~g~Du brauchst eine Freeway oder eine Angel, um mitzumachen!
+
+[BM1_3:BIKE1]
+~r~Die Fahrer wurden angegriffen!
+
+[BIKE1_1:BIKE1]
+Ok, Schickimickibürschchen, dann zeig mal, was du drauf hast.
+
+[BM1_1:BIKE1]
+~g~Schnapp dir eine Freeway oder eine Angel und geh in Startposition.
+
+{=================================== MISSION TABLE BIKE2 ===================================}
+
+[BM2_2:BIKE2]
+~g~Du musst den Chaosmesser in der vorgegebenen Zeit vollmachen, um uns zu zeigen, aus welchen Holz du bist!
+
+[BM2_4:BIKE2]
+~r~Du hast den Chaosmesser nicht rechtzeitig vollgemacht!
+
+[BM2_1:BIKE2]
+CHAOSMESSER:
+
+[BM2_A:BIKE2]
+Ha, ha, ha, hab dich wieder erwischt.
+
+[BM2_B:BIKE2]
+Hey, Vercetti.
+
+[BM2_C:BIKE2]
+Cougar meint, du fährst ziemlich gut.
+
+[BM2_D:BIKE2]
+Ja, wie lange soll ich noch hier rumgurken?
+
+[BM2_E:BIKE2]
+Ich bin ein sehr beschäftigter Mann.
+
+[BM2_F:BIKE2]
+Wenn ich mich kloppen soll, damit das klar geht, dann los.
+
+[BM2_G:BIKE2]
+Es geht bei uns nicht nur ums dreinschlagen. Man muss zur Familie gehören.
+
+[BM2_H:BIKE2]
+Ja, ich hab schon mal zu einer Familie gehört. Hat nicht funktioniert.
+
+[BM2_I:BIKE2]
+Klar. Aber unsere Familie kümmert sich um ihre Leute.
+
+[BM2_J:BIKE2]
+Wir verlangen nicht, dass einer die Drecksarbeit macht und danach 15 Jahre einsitzt.
+
+[BM2_K:BIKE2]
+Ja, ganz recht. Ich hab meine Hausaufgaben gemacht.
+
+[BM2_L:BIKE2]
+Das hier ist die größte Familie von Außenseitern, Outlaws und Unruhestiftern.
+
+[BM2_M:BIKE2]
+Ein paar von uns wurden sogar von ihrem eigenen Land verraten.
+
+[BM2_N:BIKE2]
+Während des Vietnamkriegs war ich eingelocht. Miese Sache.
+
+[BM2_O:BIKE2]
+Drum sollst du denen ja zeigen, was Sache ist.
+
+[BM2_P:BIKE2]
+Dieses ganze verdammte Land braucht einen Arschtritt, und wir geben ihm diesen Tritt.
+
+[BM2_Q:BIKE2]
+Also los, schnapp dir ein Bike und zeig der Stadt, wie sauer du bist.
+
+[BM2_R:BIKE2]
+Alles klar.
+
+[BM2_3:BIKE2]
+~g~Dieser Ton zeigt an, dass du einen Teil gefüllt hast. Mach ihn immer voller.
+
+{=================================== MISSION TABLE BIKE3 ===================================}
+
+[BM3_A:BIKE3]
+Hi, Mitch.
+
+[BM3_B:BIKE3]
+Ah, sieh an, 'Outlaw' Vercetti.
+
+[BM3_C:BIKE3]
+Jetzt will ich sehen, wie du für deine Kumpels kämpfst.
+
+[BM3_D:BIKE3]
+Eine Straßengang von hier hat den Fehler gemacht, meinen Hobel zu klauen.
+
+[BM3_E:BIKE3]
+Wollten wahrscheinlich zeigen, was für coole Machos sie sind.
+
+[BM3_F:BIKE3]
+Ich und die Jungs wollten ihnen eigentlich ein bisschen Respekt einbläuen.
+
+[BM3_G:BIKE3]
+Aber-
+
+[BM3_H:BIKE3]
+-dann dachte ich mir, das wäre doch ein guter Test für dich.
+
+[BM3_I:BIKE3]
+Bring mir meine Maschine zurück und Paul kriegt seine Security.
+
+[BM3_2:BIKE3]
+~r~Du solltest die Maschine zurückbringen, nicht schrotten!
+
+[BM3_3:BIKE3]
+~g~Bring die Maschine zur Bar!
+
+[BM3_4:BIKE3]
+~g~Setz dich auf die Maschine!
+
+[INTRUDE:BIKE3]
+~g~Man hat dich bemerkt!
+
+[BM3_6:BIKE3]
+~g~Sie sind Downtown hinter dem Ammu-Nation.
+
+[BM3_7:BIKE3]
+~g~Du brauchst eine schnelle Maschine, um auf das Dach zu gelangen.
+
+[BM3_8:BIKE3]
+~g~Spring mit dem Bike von diesen Stufen auf das Dach auf der anderen Seite der Straße.
+
+[BM3_1:BIKE3]
+~g~Eine Gang hat Mitch Bakers Maschine geklaut. Beschaff sie ihm wieder!
+
+[BM3_9:BIKE3]
+~g~Schnapp dir Mitchs Maschine und mach dich aus dem Staub!
+
+{=================================== MISSION TABLE BMX_1 ===================================}
+
+[GETBIK2:BMX_1]
+Du hast ~1~ Sekunden, um auf ein Geländemotorrad zu steigen!
+
+{=================================== MISSION TABLE BOATBUY ===================================}
+
+[DRUG_1:BOATBUY]
+Hallo? Hal-lo?! Hallo?
+
+[DRUG_13:BOATBUY]
+Meister?
+
+[DRUG_2:BOATBUY]
+Mach aus. Da kommt einer.
+
+[DRUG_3:BOATBUY]
+Tag, Herr Anzugmensch. Sie müssen der neue Eigentümer sein.
+
+[DRUG_4:BOATBUY]
+Ja. Welches von den Booten ist das schnellste?
+
+[DRUG_5:BOATBUY]
+Das ist schon im Wasser, Meister.
+
+[DRUG_6:BOATBUY]
+Dachte mir, dass Sie es mal testen wollen.
+
+[DRUG_7:BOATBUY]
+Das Ding hat jetzt schon 300 PS unter der Haube, Meister.
+
+[DRUG_8:BOATBUY]
+Und mit dem Fiberglas-Rumpf - das Ding pfeift nur so durch die Wellen!
+
+[DRUG_9:BOATBUY]
+In vier Sekunden von null auf sechzig Meilen, Meister.
+
+[DRUG_10:BOATBUY]
+Und im Rumpf kriegen Sie so 20 Ladungen vom besten jamaikanischen Gras unter.
+
+[DRUG_11:BOATBUY]
+Nur zu, Chef, machen Sie 'ne Spritztour!
+
+[DRUG_12:BOATBUY]
+Hey Anzugmensch, haben Sie mal Feuer?
+
+{=================================== MISSION TABLE CAP_1 ===================================}
+
+[CAP1_B1:CAP_1]
+~g~Die Mafia verlangt Schutzgeld von dir. Stöbere sie auf und erledige sie.
+
+[CAP1_B2:CAP_1]
+~g~Die Mafia verlangt von dir Schutzgeld für die Bootswerft!
+
+[CAP1_B3:CAP_1]
+~g~Die Mafia verlangt von dir Schutzgeld für die Eiscremefabrik!
+
+[CAP1_B4:CAP_1]
+~g~Die Mafia verlangt von dir Schutzgeld für das Autohaus!
+
+[CAP1_B5:CAP_1]
+~g~Die Mafia verlangt von dir Schutzgeld für das Taxiunternehmen!
+
+[CAP_01:CAP_1]
+Ok, wo brennt's denn?
+
+[CAP_02:CAP_1]
+Wer war das?
+
+[CAP_03:CAP_1]
+Tommy... ein paar Mafia-Typen... sie wollen wiederkommen, ihren Anteil abkassieren.
+
+[CAP_04:CAP_1]
+Ein gewisser Mr. Forello hätte dir Geld gegeben. Mir geht's schlecht.
+
+[CAP_05:CAP_1]
+Forelli? SONNY Forelli?
+
+[CAP_06:CAP_1]
+Ja, so heißt er, glaube ich... ich konnte nichts gegen sie ausrichten.
+
+[CAP_07:CAP_1]
+Keine Angst, mein Freund, ich mach dir keine Vorwürfe.
+
+[CAP_08:CAP_1]
+Bringt ihn ins Krankenhaus.
+
+[CAP_09:CAP_1]
+Tommy... mach den Kerl 'nen Kopf kürzer für mich...
+
+[CAP_10:CAP_1]
+Ich mach ihn zwei Köpfe kürzer...
+
+[CAP1_2:CAP_1]
+Du kennst die Regeln, Vercetti!
+
+[CAP1_3:CAP_1]
+Mr. Forelli bestellt schöne Grüße!
+
+[CAP1_4:CAP_1]
+Das ist der Harwood Butcher!
+
+[CAP1_5:CAP_1]
+Sag Sonny, er soll mir vom Leib bleiben!
+
+[CAP1_6:CAP_1]
+Vice City gehört nicht mehr ihm, sondern MIR!
+
+[CAP1_7:CAP_1]
+Du glaubst, du kannst mich vom Thron stürzen, Vercetti?
+
+[CAP1_8:CAP_1]
+Wir jagen dich bis ans Ende deiner Tage, Vercetti.
+
+[CAP1_9:CAP_1]
+Du hast keine Chance, du irrer Idiot!
+
+[CAP1_10:CAP_1]
+Ich mach dich fertig, Vercetti.
+
+[CAP1_11:CAP_1]
+Du warst schon immer ein Schwachkopf.
+
+[CAP1_12:CAP_1]
+Du wirst dran glauben, Vercetti.
+
+[CAP1_B6:CAP_1]
+~g~Du hast den Eintreiber gefunden, erledige ihn.
+
+[CAP1_B7:CAP_1]
+~g~Du hast den Eintreiber verloren.
+
+[CAP1_B8:CAP_1]
+~r~Der Eintreiber verlangt für all deine Geschäfte Schutzgeld.
+
+[CAP1_B9:CAP_1]
+~g~Die Mafia verlangt Schutzgeld für das Malibu!
+
+[CAP1_B0:CAP_1]
+~g~Die Mafia verlangt Schutzgeld für das Filmstudio!
+
+[CAP1_C2:CAP_1]
+~g~Die Mafia ist bei der Bootswerft angekommen!
+
+[CAP1_C3:CAP_1]
+~g~Die Mafia ist bei der Eiscremefabrik angekommen!
+
+[CAP1_C4:CAP_1]
+~g~Die Mafia ist bei dem Autohaus angekommen!
+
+[CAP1_C5:CAP_1]
+~g~Die Mafia ist bei dem Taxiunternehmen angekommen!
+
+[CAP1_C9:CAP_1]
+~g~Die Mafia ist im Malibu Club angekommen!
+
+[CAP1_C0:CAP_1]
+~g~Die Mafia ist im Filmstudio angekommen!
+
+[CAP1_D2:CAP_1]
+~g~Die Mafia verlässt die Bootswerft!
+
+[CAP1_D3:CAP_1]
+~g~Die Mafia verlässt die Eiscremefabrik!
+
+[CAP1_D4:CAP_1]
+~g~Die Mafia verlässt das Autohaus!
+
+[CAP1_D5:CAP_1]
+~g~Die Mafia verlässt das Taxiunternehmen!
+
+[CAP1_D9:CAP_1]
+~g~Die Mafia verlässt den Malibu Club!
+
+[CAP1_D0:CAP_1]
+~g~Die Mafia verlässt das Filmstudio!
+
+[CAP1B10:CAP_1]
+Du hast die Eintreiber erledigt. Es kommen weitere.
+
+{=================================== MISSION TABLE CARBUY ===================================}
+
+[CAR1_1:CARBUY]
+B.J. Smith. Und Sie müssen Mr. Vercetti sein.
+
+[CAR1_2:CARBUY]
+Soll ich Sie herumführen?
+
+[CAR1_3:CARBUY]
+Warum nicht?
+
+[CAR1_4:CARBUY]
+Tja, ich verkaufe das Autohaus ja eigentlich nur ungern.
+
+[CAR1_5:CARBUY]
+War meine erste Investition, nachdem ich Football-Profi wurde.
+
+[CAR1_6:CARBUY]
+Aber es wird Zeit für eine Luftveränderung.
+
+[CAR1_7:CARBUY]
+Sie verlassen die Stadt?
+
+[CAR1_8:CARBUY]
+Nicht in allzu großer Eile, hoffe ich doch?
+
+[CAR1_9:CARBUY]
+Nein, ich bereite mich nur auf mein Comeback als Football-Profi vor. Ich hatte schon aufgehört.
+
+[CAR1_10:CARBUY]
+Das Geschäft lief nicht allzu gut.
+
+[CAR1_11:CARBUY]
+Da haben sich meine Angestellten was einfallen lassen,
+
+[CAR1_12:CARBUY]
+um ein bisschen was 'nebenbei' zu erwirtschaften.
+
+[CAR1_13:CARBUY]
+Ich könnte den Laden auch dichtmachen, bevor ich ihn Ihnen verkaufe.
+
+[CAR1_14:CARBUY]
+Ich könnte die Bude bei Bedarf sogar abfackeln.
+
+[CAR1_15:CARBUY]
+Das ist erstklassiger Baugrund hier.
+
+[CAR1_16:CARBUY]
+Machen Sie sich mal keine Gedanken.
+
+[CAR1_17:CARBUY]
+Der Laden ist genau das, was ich brauche.
+
+[CAR1_18:CARBUY]
+Ja. Dann kommen wir also ins Geschäft?
+
+{=================================== MISSION TABLE CARPAR1 ===================================}
+
+[MM_1_A:CARPAR1]
+~g~Passiere ~y~5 checkpoints~r~ OHNE irgendwelche ~r~Hütchen ~g~umzufahren! ~g~Die ~y~REIHENFOLGE IST BELIEBIG.
+
+[CONE_1:CARPAR1]
+~r~Du hast ein Hütchen umgefahren!!
+
+[MM_1_C:CARPAR1]
+~y~PASSIERE~g~ einen Checkpoint, dann läuft die Zeit. ~g~Jeder Checkpoint bringt dir ~y~~1~ SEKUNDEN~g~.
+
+{=================================== MISSION TABLE COPCAR ===================================}
+
+[C_COMP1:COPCAR]
+Bürgerwehr-Mission Level 12 beendet: Deine max. Panzerung erhöht sich auf 150
+
+[CLEVEL:COPCAR]
+Bürgerwehr-Mission Level ~1~
+
+[C_PASS:COPCAR]
+BEDROHUNG AUSGERÄUMT: $ ~1~
+
+[KILLS:COPCAR]
+HITS:
+
+[C_BREIF:COPCAR]
+~g~Verdächtiger wurde zuletzt in der Gegend von ~a~ gesichtet.
+
+[COPCART:COPCAR]
+~g~Du hast ~1~ Sekunden, um zu einem Polizeifahrzeug zurückzukehren, bevor die Mission endet.
+
+[C_CANC:COPCAR]
+~r~Bürgerwehr-Mission abgebrochen!
+
+[C_TIME:COPCAR]
+~r~Deine Zeit als Gesetzeshüter ist vorbei!
+
+{=================================== MISSION TABLE COUNT1 ===================================}
+
+[CM1_A:COUNT1]
+Mr.Vercetti? Hey. Sie haben die alte Druckerei gekauft?
+
+[CM1_B:COUNT1]
+Ja, mein Vater hat an diesen Dingern gearbeitet.
+
+[CM1_C:COUNT1]
+Ich sollte in seine Fußstapfen treten, aber...es ist anders gekommen.
+
+[CM1_D:COUNT1]
+Wollen Sie die alten Maschinen verkaufen, das Werk abreißen?
+
+[CM1_E:COUNT1]
+Ich denke nach, ob wir was drucken sollten. Eine Zeitung, ein Magazin...
+
+[CM1_F:COUNT1]
+Ach, Blödsinn, absoluter Blödsinn. Ich drucke lieber Geld. Ist gar nicht so schwer.
+
+[CM1_G:COUNT1]
+In kleinerem Umfang mache ich das schon seit Jahren.
+
+[CM1_H:COUNT1]
+Tatsächlich?
+
+[CM1_I:COUNT1]
+Klar. Aber wir bräuchten gute Platten.
+
+[CM1_J:COUNT1]
+Natürlich! In Florida gibt es schon ein Geldfälscher-Syndikat.
+
+[CM1_K:COUNT1]
+Ein Syndikat?
+
+[CM1_L:COUNT1]
+Ja. Hab aber nur gerüchteweise davon gehört.
+
+[CM1_M:COUNT1]
+Ich kenne einen, der kennt sich mit Gerüchten aus...
+
+[CM1_N:COUNT1]
+Hab immer die Abende mit ihm verbracht, die Walzen reinigen.
+
+[CM1_2A:COUNT1]
+Sieh dir diesen Hintern an!
+
+[CM1_2B:COUNT1]
+Tja, Kleine, du weißt nicht, was dir entgeht!
+
+[CM1_2C:COUNT1]
+Na, alter Freund, wie läuft's so?
+
+[CM1_2D:COUNT1]
+Was weißt du über Geldfälscherei?
+
+[CM1_2E:COUNT1]
+'Oh, alles bestens, Paul, und bei dir?'
+
+[CM1_2F:COUNT1]
+Komm her!
+
+[CM1_2G:COUNT1]
+Ist ja gut, ist ja gut. Anscheinend bist du schwer beschäftigt.
+
+[CM1_2H:COUNT1]
+Über Falschgeld weiß ich nur, dass die Triaden die Platten liefern.
+
+[CM1_2I:COUNT1]
+Die haben eine Reederei unten bei den Docks.
+
+[CM1_2J:COUNT1]
+Der Boss weiß, wann die nächsten Platten reinkommen.
+
+[CM1_2K:COUNT1]
+Danke, Paul.
+
+[CM1_2L:COUNT1]
+Was ist bloß los mit dir, du Wahnsinniger!
+
+[CM1_2M:COUNT1]
+Gib mir noch einen Drink, hopp!
+
+[CM1_3:COUNT1]
+~g~Man hat dich bemerkt!
+
+[CM1_5:COUNT1]
+~g~Begib dich zu Kent Paul in den Malibu Club!
+
+[CNT1_1:COUNT1]
+Wer sind Sie? Uff! Aiiee! Nicht ins Gesicht! Nicht ins Gesicht!
+
+[CM1_1:COUNT1]
+~g~Begib dich zum Schiff der Chartered Libertine Lines bei den Docks.
+
+[CM1_2:COUNT1]
+~g~Der Reedereichef verfügt über die benötigten Informationen.
+
+[CNT1_2:COUNT1]
+Ok, ich rede ja! Ich rede!
+
+[CM1_6:COUNT1]
+~g~Begib dich mit den Informationen zurück in die Druckerei!
+
+{=================================== MISSION TABLE COUNT2 ===================================}
+
+[CNT2_B1:COUNT2]
+Ok, der Kurier holt die Druckplatten heute vom Hafen ab.
+
+[CNT2_B2:COUNT2]
+Ich fange ihn ab, schnapp mir die Platten, häng die Cops ab und komm wieder hierher.
+
+[CNT2_B3:COUNT2]
+Also, je nachdem wie es läuft, haben wir
+
+[CNT2_B4:COUNT2]
+entweder 5 Minuten zum Gelddrucken, bis das Fälschersyndikat uns findet, oder wir haben alle Zeit der Welt.
+
+[CNT2_B5:COUNT2]
+Jedenfalls will ich 5 Minuten nachdem ich hier bin, Scheinchen aus der Presse kommen sehen!
+
+[CNT2_B6:COUNT2]
+Keine Sorge, Tommy. Wir sind bereit.
+
+[CNT2_B7:COUNT2]
+Ich und die Jungs bleiben in der Nähe, falls die Cops dir in die Quere kommen.
+
+[CNT2_B8:COUNT2]
+Ok. Jeder weiß, was er zu tun hat? Gut. Bis später.
+
+[CNT2_01:COUNT2]
+~g~Der ~r~Kurier~g~ mit den Druckplatten kommt jeden Moment in einem Helikopter an den ~y~Docks~g~ an.
+
+[CNT2_02:COUNT2]
+~r~Der Kurier mit den Platten ist im Helikopter geflohen.
+
+[CNT2_03:COUNT2]
+~r~Der Kurier ist an seinem Ziel angekommen. Du kommst zu spät!
+
+[CNT2_04:COUNT2]
+~r~Du hast die Platten in der Explosion zerstört!
+
+[CNT2_05:COUNT2]
+~g~Du hast die Druckplatten. Bring sie in die Druckerei.
+
+[CNT2_06:COUNT2]
+~g~Der Kurier ist hinüber. Hol dir die Platten, ehe dir jemand zuvorkommt.
+
+[CNT2_07:COUNT2]
+~g~Eine der Wachen hat die Platten genommen. Lass ihn nicht entkommen!
+
+[CNT2_08:COUNT2]
+~g~Der ~r~Kurier~g~ mit den Platten ist an den Docks eingetroffen.
+
+[CNT2_4:COUNT2]
+Privatangelegenheit. Du hast hier nichts verloren!
+
+[CNT2_09:COUNT2]
+DRUCKEREI ERWORBEN
+
+[CNT2_10:COUNT2]
+~g~Die Druckerei generiert nun bis zu $~1~ Einkünfte. Hol dir das Geld regelmäßig ab.
+
+[CNT2_11:COUNT2]
+~r~Die Platten liegen auf dem Meeresgrund!
+
+{=================================== MISSION TABLE CUBAN1 ===================================}
+
+[CUB1_A:CUBAN1]
+Was ist, Mann?
+
+[CUB1_B:CUBAN1]
+Hey, langsam, Paps, der ist für mich. Bist du der Bursche?
+
+[CUB1_C:CUBAN1]
+Oh ja, du bist der Bursche. Glaub schon.
+
+[CUB1_D:CUBAN1]
+Nein, glaub ich nicht.
+
+[CUB1_E:CUBAN1]
+Ach ja? Komm her du Großmaul.
+
+[CUB1_F:CUBAN1]
+Meinst du, du kannst es mit mir aufnehmen?
+
+[CUB1_G:CUBAN1]
+Meinst du, du kannst mich für blöd verkaufen?
+
+[CUB1_H:CUBAN1]
+Nein, ich glaube, deine Blödheit reicht für uns beide.
+
+[CUB1_I:CUBAN1]
+Hey, er sagt, du bist dumm, mein Sohn.
+
+[CUB1_J:CUBAN1]
+Und ich sage, er ist ein kleines Mädchen, Paps.
+
+[CUB1_K:CUBAN1]
+Sieh dir doch an, wie er angezogen ist.
+
+[CUB1_L:CUBAN1]
+Was ist los? Ist heute Weiberabend?
+
+[CUB1_M:CUBAN1]
+Du willst ein harter Kerl sein und ziehst dich an wie ein Weib?
+
+[CUB1_N:CUBAN1]
+Hast du auch ein Höschen an, oder was?
+
+[CUB1_O:CUBAN1]
+Was hast du gegen Frauen? Ziehst du Männer vor?
+
+[CUB1_P:CUBAN1]
+Ich liebe Frauen! Ich liebe alle Frauen! Ich liebe meine Mutter, Chico.
+
+[CUB1_Q:CUBAN1]
+Ok, ok, ich glaub's dir ja.
+
+[CUB1_R:CUBAN1]
+Kannst du fahren, Amigo?
+
+[CUB1_S:CUBAN1]
+Ja...wie eine Frau.
+
+[CUB1_T:CUBAN1]
+Sehr witzig. Du gefällst mir, Großer. Vielleicht kannst du mir helfen.
+
+[CUB1_U:CUBAN1]
+Vielleicht kannst du beweisen, dass du ein Mann bist. Hah?
+
+[CUB1_V:CUBAN1]
+Schnapp dir das Boot.
+
+[CUB1_W:CUBAN1]
+Zeig mir, dass du ein ganzer Kerl bist,
+
+[CUB1_X:CUBAN1]
+und kein kleines Mädchen.
+
+[CUB1_02:CUBAN1]
+Ok Mann, behandle es wie eine Frau.
+
+[CUB1_03:CUBAN1]
+Nicht schlecht, du bist ein echter Mann.
+
+[CUB1_04:CUBAN1]
+Mann, du bist ein ganzer Kerl, Amigo.
+
+[CUB1_05:CUBAN1]
+Amigo, du bist ein Mann, Mann.
+
+[CUB1_06:CUBAN1]
+Du willst ein Mann sein, Mann?
+
+[CUB1_07:CUBAN1]
+Du bist ein feiges Würstchen, Kleiner, heul dich bei Mammi aus.
+
+[CUB1_08:CUBAN1]
+Du bist zu nichts zu gebrauchen. Macht einen auf harter Mann, aber fährt wie ein Idiot.
+
+[CUB1_09:CUBAN1]
+Mann, du bist der Hammer, Mann. Du gefällst mir. Du gefällst mir sehr.
+
+[CUB1_10:CUBAN1]
+Du bist gut, Mann. Weil du ein ganzer Kerl bist. Alle meine Freunde sind ganze Kerle.
+
+[CUB1_11:CUBAN1]
+Du hast Rico erledigt!
+
+[CUB1_12:CUBAN1]
+Fahre durch den ersten Checkpoint, um den Test zu beginnen.
+
+[CUB1_14:CUBAN1]
+Steig wieder ins Boot!
+
+[CUB1_15:CUBAN1]
+Du bist zu langsam, Mann.
+
+[CUB1_01:CUBAN1]
+Hi, ich bin Rico. Bist du der 'ganze Kerl'?
+
+[CUB1_13:CUBAN1]
+~g~Du hast drei Minuten, um den Rundkurs zu schaffen.
+
+{=================================== MISSION TABLE CUBAN2 ===================================}
+
+[CUB2_25:CUBAN2]
+ERLEDIGE ALLE HAITIANER!!
+
+[CUB2_M:CUBAN2]
+Wer sich mit mir anlegt, hat sich den stärksten der Stadt rausgesucht!
+
+[CUB2_A:CUBAN2]
+Eine Kaffee, bitte, Alberto.
+
+[CUB2_N:CUBAN2]
+Kein Problem, Tommy.
+
+[CUB2_B:CUBAN2]
+Paps! Es gibt ein Riesenproblem!
+
+[CUB2_O:CUBAN2]
+Umberto, mein Sohn, was ist passiert?
+
+[CUB2_C:CUBAN2]
+Die Haitianer! Ich hasse die Haitianer!
+
+[CUB2_D:CUBAN2]
+Die haben mir das letzte Mal ans Bein gepinkelt!
+
+[CUB2_E:CUBAN2]
+Diese Haitianer. Wir machen sie fertig!
+
+[CUB2_F:CUBAN2]
+Aber dazu brauchen wir Hilfe.
+
+[CUB2_G:CUBAN2]
+Ich hab dabei schon ein paar Brüder verloren.
+
+[CUB2_H:CUBAN2]
+Amigo, du fährst gut!
+
+[CUB2_I:CUBAN2]
+Für eine Frau, was?
+
+[CUB2_J:CUBAN2]
+Jetzt ist nicht die Zeit für Witze!
+
+[CUB2_K:CUBAN2]
+Komm, fahr noch mal für mich!
+
+[CUB2_L:CUBAN2]
+Bring meine Jungs da rüber, und dann erledigen wir diese Haitianer!
+
+[CUB2_01:CUBAN2]
+Da ist nicht genug Platz, Mann, du brauchst ein größeres Auto.
+
+[CUB2_02:CUBAN2]
+Wir brauchen Verstärkung aus dem Café!
+
+[CUB2_03:CUBAN2]
+~g~Besorg dir ein Auto und hole die Kubaner vor Robinas Café ab.
+
+[CUB2_04:CUBAN2]
+~g~Setze die Kubaner am Kampfort ab.
+
+[CUB2_05:CUBAN2]
+Schalte den feigen Heckenschützen aus!
+
+[CUB2_07:CUBAN2]
+Die kämpfen wie Weiber! In Deckung!
+
+[CUB2_09:CUBAN2]
+Heckenschütze auf dem Dach!
+
+[CUB2_11:CUBAN2]
+~r~Du Idiot! Das Auto hätten wir gebraucht!
+
+[CUB2_12:CUBAN2]
+Hey, Amigo! Schön zu sehen, dass du's geschafft hast!
+
+[CUB2_13:CUBAN2]
+Stinkendes Haitianer-Nest. Das werden wir komplett ausheben!
+
+[CUB2_14:CUBAN2]
+ANGRIFF!
+
+[CUB2_15:CUBAN2]
+Los, meine Brüder, ANGRIFF!!
+
+[CUB2_16:CUBAN2]
+Tommy, wir haben unseren mannhaften Mut bewiesen!
+
+[CUB2_17:CUBAN2]
+Lass uns diesen Wagen voller Stoff nehmen und abhauen!
+
+[CUB2_18:CUBAN2]
+~g~Besorge dir ein Auto und hole die Kubaner ab.
+
+[CUB2_19:CUBAN2]
+Wir werden kämpfen wie Männer!
+
+[CUB2_21:CUBAN2]
+Kämpfen wie ganze Kerle!
+
+[CUB2_22:CUBAN2]
+~g~Schalte die restlichen Haitianer aus, damit die Kubaner vorrücken können.
+
+[CUB2_23:CUBAN2]
+~g~In Little Haiti wird es von Haitianern wimmeln, die sich an den Kubanern rächen wollen. Sei vorsichtig.
+
+[CUB2_24:CUBAN2]
+~g~Kehre mit dem Van zu Robinas Café zurück und parke hinter dem Haus.
+
+{=================================== MISSION TABLE CUBAN3 ===================================}
+
+[CUB3_A:CUBAN3]
+Alberto? Einen Kaffee, Senor?
+
+[CUB3_B:CUBAN3]
+Paps, gib dieser falschen Schlange nichts.
+
+[CUB3_C:CUBAN3]
+Du hast zwei Gesichter, Tommy!
+
+[CUB3_D:CUBAN3]
+Du hast entweder zwei Gesichter oder du bist ein Feigling, Kleiner!
+
+[CUB3_E:CUBAN3]
+Die Haitianer, Mann, die lachen mich aus.
+
+[CUB3_F:CUBAN3]
+Ruhig, ruhig. Was gibt es für Probleme?
+
+[CUB3_G:CUBAN3]
+Sie lachen mich aus, Tommy. Mich!
+
+[CUB3_H:CUBAN3]
+Umberto Robina. Die tun, was sie wollen!
+
+[CUB3_I:CUBAN3]
+Die tun nicht, was sie wollen, Umberto. Sie tun, was du sie tun lässt.
+
+[CUB3_J:CUBAN3]
+Was?
+
+[CUB3_K:CUBAN3]
+Soll jemand aus dem Weg geräumt werden?
+
+[CUB3_L:CUBAN3]
+Ich kann das machen, aber es kostet.
+
+[CUB3_M:CUBAN3]
+Ich weiß, wir sind Brüder und alles, aber hier geht's um ein Geschäft.
+
+[CUB3_N:CUBAN3]
+Tommy. Du bist ein echter Mann. Ein Geschäftsmann, ein Gentleman.
+
+[CUB3_O:CUBAN3]
+Die Haitianer, sie erwarten eine Schiffladung Stoff, richtig gutes Zeug.
+
+[CUB3_P:CUBAN3]
+Wir schnappen es uns und erledigen sie.
+
+[CUB3_Q:CUBAN3]
+Du schnappst es dir, ich passe auf dich auf. Wie auf einen Bruder, einen Sohn.
+
+[CUB3_R:CUBAN3]
+Ich glaube, Cash ist mir lieber als auf deinen Knien zu reiten, Amigo.
+
+[CUB3_01:CUBAN3]
+Hey, Rico. Nettes Boot. Bist du bereit?
+
+[CUB3_03:CUBAN3]
+~g~Sammle alle Aktenkoffer mit Stoff und Geld ein.
+
+[CUB3_04:CUBAN3]
+~g~Bringe die Drogen und das Geld zu Umberto.
+
+[CUB3_05:CUBAN3]
+Ja, Tommy. Also, sei ein guter Kapitän heute.
+
+[CUB3_06:CUBAN3]
+Mein Boot nützt mir nichts, wenn es durchlöchert ist, ok?
+
+[CUB3_07:CUBAN3]
+~g~Begib dich zu Rico. Er fährt dich zum Treffpunkt.
+
+[CUB3_02:CUBAN3]
+~g~ERLEDIGE ALLE HAITIANER AUF DEN BOOTEN!!
+
+[CUB3_08:CUBAN3]
+Oh-oh... eine Bande Kubaner. Wir werden angegriffen!
+
+{=================================== MISSION TABLE CUBAN4 ===================================}
+
+[CUB4_A:CUBAN4]
+Hey, Ladies. Wisst ihr, was ich mache?
+
+[CUB4_B:CUBAN4]
+Ich erledige einen Haitianer. Und dann?
+
+[CUB4_C:CUBAN4]
+Dann mache ich Liebe wie ein Mann.
+
+[CUB4_D:CUBAN4]
+Weißt du, Kleine? So in der Art.
+
+[CUB4_E:CUBAN4]
+Penner!
+
+[CUB4_F:CUBAN4]
+Vollidiot.
+
+[CUB4_G:CUBAN4]
+Hey, Baby, dich würde ich nicht mit 'ner Kneifzange anfassen!
+
+[CUB4_H:CUBAN4]
+Umberto Robina mag Frauen, keine Ziege mit Rock!
+
+[CUB4_I:CUBAN4]
+Tommy!! Tommy, ich liebe dich, ich liebe dich! Lass uns gehen!
+
+[CUB4_J:CUBAN4]
+Wohin denn? Kann ich nicht noch einen Kaffee trinken?
+
+[CUB4_K:CUBAN4]
+Keine Zeit! Außerdem habe ich erst einen getrunken.
+
+[CUB4_L:CUBAN4]
+Wir nehmen uns die Haitianer vor.
+
+[CUB4_M:CUBAN4]
+Tommy, wie erledigt man eine Schlange?
+
+[CUB4_N:CUBAN4]
+Man beißt sie in den Hintern! Hahaha!
+
+[CUB4_O:CUBAN4]
+Wenn du es sagst, Umberto.
+
+[CUB4_P:CUBAN4]
+Tommy, geh und besorge uns ein kleines haitianisches Auto.
+
+[CUB4_Q:CUBAN4]
+Wenn du es hast, komm zurück und hol meinen Jungen ab
+
+[CUB4_R:CUBAN4]
+Pepe, und fahre ihn zu den Haitianern.
+
+[CUB4_S:CUBAN4]
+Dann begibst du dich zur Laboranlage der Haitianer und verwendest ihr Lösungsmittel als Sprengstoff.
+
+[CUB4_T:CUBAN4]
+Bumm! Bye bye!
+
+[CUB4_U:CUBAN4]
+Umberto, was ist mit dir?
+
+[CUB4_V:CUBAN4]
+Oh, ich halte mich raus und passe mit Paps auf das Café auf.
+
+[CUB4_W:CUBAN4]
+Er fühlt sich nicht besonders, weißt du.
+
+[CUB4_02:CUBAN4]
+~g~Die Bomben werden per Zeitzünder auf 45 sek. gestellt sein.
+
+[CUB4_07:CUBAN4]
+Zum Lösungsmittel geht's hintenrum, Amigo.
+
+[CUB4_08:CUBAN4]
+Hola, Amigos.
+
+[CUB4_09:CUBAN4]
+Bueno. Haitian Putas. Muerte.
+
+[CUB4_10:CUBAN4]
+Vamos.
+
+[CUB4_11:CUBAN4]
+Genau, vamos.
+
+[CUB4_12:CUBAN4]
+Hey, wir brauchen ein haitianisches Gang-Auto!
+
+[CUB4_13:CUBAN4]
+Oye, suchen wir unsere Muchachos!
+
+[CUB4_14:CUBAN4]
+Folge meinen Compadres.
+
+[CUB4_15:CUBAN4]
+Ok, nur immer rein...
+
+[CUB4_16:CUBAN4]
+Ich lege die Bombe. Gib mir Deckung.
+
+[CUB4_17:CUBAN4]
+RENN!
+
+[CUB4_18:CUBAN4]
+Mann, das ist ein schönes Viertel hier...
+
+[CUB4_19:CUBAN4]
+Das ist doch eine Müllhalde, Mann.
+
+[CUB4_20:CUBAN4]
+Ich kannte mal eine schöne Frau, die hat hier gewohnt.
+
+[CUB4_21:CUBAN4]
+Die machen gute Pizza hier.
+
+[CUB4_22:CUBAN4]
+Hey, Mann! Du fährst wie ein Verrückter!
+
+[CUB4_23:CUBAN4]
+Hast du dich verfahren, Mann?
+
+[CUB4_24:CUBAN4]
+Du hast Pepe vergessen, hole ihn.
+
+[CUB4_03:CUBAN4]
+~g~Bleib im Wagen, bis er sicher auf dem Gelände geparkt ist.
+
+[CUB4_26:CUBAN4]
+~g~Nimm dir Pepe, fahr Richtung Norden nach Little Haiti und klaue einen Voodoo.
+
+[CUB4_27:CUBAN4]
+~g~Triff dich mit Rico und den anderen Kubanern.
+
+[CUB4_28:CUBAN4]
+~g~Triff dich mit den anderen Kubanern bei der haitianischen Drogenfabrik.
+
+[CUB4_29:CUBAN4]
+~g~Gehe in jede der Markierungen, um an dieser Stelle eine Bombe zu legen.
+
+[CUB4_30:CUBAN4]
+~g~Wenn alle drei Bomben gelegt sind, entferne dich von der Fabrik bevor sie hochgeht.
+
+[CUB4_31:CUBAN4]
+~g~Mach, dass du von der Fabrik wegkommst!!
+
+[CUB4_32:CUBAN4]
+~g~Park den Wagen an der im Radar markierten Stelle und steig aus.
+
+[CUB4_06:CUBAN4]
+~r~Du bist nicht weit genug von der Basis weggekommen, wir mussten die Detonation abbrechen!
+
+{=================================== MISSION TABLE FINALE ===================================}
+
+[FIN1_01:FINALE]
+Was ist los?
+
+[FIN1_02:FINALE]
+Tommy! Ah, gut, gut. Hör zu. Hör zu...
+
+[FIN1_03:FINALE]
+Ich mag Fische. Ich liebe Fische.
+
+[FIN1_04:FINALE]
+Ich liebe sie als Haustiere oder auch lecker zubereitet.
+
+[FIN1_05:FINALE]
+Aber ich liebe sie nicht so sehr, dass ich als Fischfutter im Hafen enden will.
+
+[FIN1_06:FINALE]
+Und jetzt kommen auf einmal deine italienischen Brüder an und wollen mir Zementschuhe verpassen. Und ich...
+
+[FIN1_07:FINALE]
+Halt den Mund, Ken. Setz dich.
+
+[FIN1_08:FINALE]
+Lance, was läuft hier, verdammt?
+
+[FIN1_09:FINALE]
+Deine Freunde aus dem Norden, Tommy. Die sind nicht sehr froh, dass du ihren Mann erledigt hast.
+
+[FIN1_10:FINALE]
+Sie kommen heute, um nach dem Rechten zu sehen.
+
+[FIN1_11:FINALE]
+Sie haben länger gebraucht, als ich dachte...
+
+[FIN1_12:FINALE]
+Jungs, wir müssen denen ein für alle Mal klar machen, dass das mein Laden ist. MEINER!
+
+[FIN1_13:FINALE]
+Ken, hol die erste Ladung von dem Falschgeld und pack 20 Mios in Aktenkoffer.
+
+[FIN1_14:FINALE]
+Lance, du trommelst die anderen Jungs zusammen...
+
+[FIN2_01:FINALE]
+Tommy!
+
+[FIN2_02:FINALE]
+Was ist? Keine Umarmung für deinen alten Freund?
+
+[FIN2_03:FINALE]
+Ich war 15 Jahre weg vom Fenster,
+
+[FIN2_04:FINALE]
+bin nicht mehr auf dem Laufenden, was Manieren angeht.
+
+[FIN2_05:FINALE]
+Immer Wut im Bauch, hä, Tommy?
+
+[FIN2_06:FINALE]
+Ich sag's ja, dein Temperament wird dir nochmal schlecht bekommen.
+
+[FIN2_07:FINALE]
+In den Koffern sind 20 Millionen...
+
+[FIN2_08:FINALE]
+Wie viele waren es denn? Zehn? Nein, elf Männer.
+
+[FIN2_09:FINALE]
+So kommt man zu dem Spitznamen 'Harwood-Butcher'! Hehehe!
+
+[FIN2_10:FINALE]
+Ich sollte EINEN Mann für dich erledigen! Die wussten, dass ich komme, Sonny...
+
+[FIN2_11:FINALE]
+Wie redest du denn mit mir?
+
+[FIN2_12:FINALE]
+Wie kommst du darauf, mich für diesen unglücklichen Zufall verantwortlich zu machen?
+
+[FIN2_13:FINALE]
+Nimm einfach das Geld...
+
+[FIN2_14:FINALE]
+Holt das Geld!
+
+[FIN2_15:FINALE]
+Weißt du, Tommy, ich hab für dich getan, was nur ging. Himmel und Hölle in Bewegung gesetzt.
+
+[FIN2_16:FINALE]
+Ich war dein Freund. Ich dachte, du nimmst Vernunft an. Kapierst, was gut fürs Geschäft ist.
+
+[FIN2_17:FINALE]
+Ich hab dir vertraut, Tommy, und du hast mich enttäuscht.
+
+[FIN2_18:FINALE]
+Aber wenigstens einer in deiner mickrigen Organisation weiß, wie man Geschäfte macht.
+
+[FIN2_19:FINALE]
+Stimmt's, Lance?
+
+[FIN2_20:FINALE]
+Sorry, Tommy. So läuft's in Vice City. So läuft das Geschäft.
+
+[FIN2_21:FINALE]
+Du hast uns verraten...
+
+[FIN2_22:FINALE]
+Nein, ich hab DICH verraten, Tommy, nur DICH.
+
+[FIN2_23:FINALE]
+Die echten Piepen sind oben im Safe.
+
+[FIN2_24:FINALE]
+Tommy, wie hast du dir das denn vorgestellt?
+
+[FIN2_25:FINALE]
+Dachtest du, ich lass mich mit Blüten abspeisen?
+
+[FIN2_26:FINALE]
+Dass ich den Schwanz einziehe und abhaue, um nicht das Gesicht zu verlieren?
+
+[FIN2_27:FINALE]
+Nein.
+
+[FIN2_28:FINALE]
+Ich wollte dich nur noch ein bisschen ärgern, bevor ich dich fertig mache.
+
+[FIN3_01:FINALE]
+Tommy?
+
+[FIN3_02:FINALE]
+Oh Gott, Tommy! Was ist passiert?
+
+[FIN3_03:FINALE]
+Wonach sieht's denn aus?
+
+[FIN3_04:FINALE]
+Sieht aus, als wär dein Anzug ruiniert!
+
+[FIN3_05:FINALE]
+Und das war ein wunderbarer Anzug! Tommy, Herrgott, was ist passiert?
+
+[FIN3_06:FINALE]
+Kleine Meinungsverschiedenheit mit einem Geschäftsfreund. Wie das so ist.
+
+[FIN3_07:FINALE]
+Wenn ich eine Meinungsverschiedenheit mit einem Geschäftsfreund habe, schick ich ihm einen bösen Brief.
+
+[FIN3_08:FINALE]
+Oder ich pinkle ihm in den Briefkasten, aber ich fang nicht den 3. Weltkrieg an.
+
+[FIN3_09:FINALE]
+Vielleicht solltest du mal zu meinem Therapeuten gehen...
+
+[FIN3_10:FINALE]
+Dieser Dreckskerl von Lance...
+
+[FIN3_11:FINALE]
+Tommy, ich konnte den Kerl ja nie leiden.
+
+[FIN3_12:FINALE]
+Er ist neurotisch, unsicher, selbstsüchtig - Er ist ein Arschloch!
+
+[FIN3_13:FINALE]
+Gut, dass du ihn fertig gemacht hast!
+
+[FIN3_14:FINALE]
+Ich glaub auch nicht, dass wir nochmal Ärger mit denen aus dem Norden kriegen...
+
+[FIN3_15:FINALE]
+Die aus dem Norden gibt's nämlich nicht mehr.
+
+[FIN3_16:FINALE]
+Gibt nur noch die im Süden.
+
+[FIN3_17:FINALE]
+Moment, verstehe ich dich richtig, Tommy, Heißt das...?
+
+[FIN3_18:FINALE]
+Na, was meinst du, was das heißt?
+
+[FIN3_19:FINALE]
+Dass wir jetzt die Herren im Haus sind... ich meine, dass DU der Herr im Haus bist. Oh, Tommy...
+
+[FIN3_20:FINALE]
+Weißt du, Ken, das könnte der Beginn einer wunderbaren Geschäftsbeziehung sein...
+
+[FIN3_21:FINALE]
+Schließlich bist du ein hinterlistiger, mieser kleiner Dieb...
+
+[FIN3_22:FINALE]
+und ich bin ein verurteilter Psychopath und Dealer.
+
+[FIN3_23:FINALE]
+Ich weiß. Ist das nicht wunderbar?
+
+[FIN_B1:FINALE]
+~g~Erledige den Verräter ~y~Vance~g~.
+
+[FIN_B2:FINALE]
+~g~Erledige ~p~Sonny~g~, um die Sache ein für alle Mal zuende zu bringen.
+
+[FIN_B3:FINALE]
+~g~Die Mafia will dein Geld stehlen. Verteidige den Safe.
+
+[FIN_B4:FINALE]
+~g~Du hältst nicht mehr lange durch. Hol dir unten ein wenig ~w~Energie~g~.
+
+[FIN_B5:FINALE]
+~g~Die Mafia stiehlt dein Geld. Verteidige den ~c~Safe.
+
+[FIN_B7:FINALE]
+~r~Die Mafia hat dein gesamtes Geld gestohlen.
+
+[DEFSAFE:FINALE]
+~g~Geh zurück zum Safe und verteidige ihn.
+
+{=================================== MISSION TABLE FIRETRK ===================================}
+
+[F_PASS1:FIRETRK]
+Feuer gelöscht!
+
+[F_FAIL2:FIRETRK]
+~r~Du kommst zu spät!
+
+[F_CANC:FIRETRK]
+~r~Feuerwehr-Mission abgebrochen!
+
+[F_EXTIN:FIRETRK]
+FEUER:
+
+[F_START:FIRETRK]
+~g~Brennendes Fahrzeug in der Gegend von ~a~ gemeldet. Lösche den Brand.
+
+[SIREN_1:FIRETRK]
+Um die Sirenen dieses Fahrzeugs einzuschalten, drücke die ~h~~k~~VEHICLE_HORN~~w~.
+
+[SIREN_2:FIRETRK]
+Um die Sirenen dieses Fahrzeugs einzuschalten, drücke die ~h~~k~~VEHICLE_HORN~~w~.
+
+[FIREPRO:FIRETRK]
+Feuerwehr-Mission Level 12 abgeschlossen: Du bist jetzt absolut feuerfest!!
+
+[F_FAIL1:FIRETRK]
+Feuerwehr-Mission beendet.
+
+[F_STAR1:FIRETRK]
+~g~Brennende Fahrzeuge in der Gegend von ~a~ gemeldet. Lösche den Brand.
+
+[SPRAY_4:FIRETRK] { reVC update }
+Benutze die ~h~~k~~VEHICLE_FIREWEAPON~~w~-Taste, um die Wasserkanone abzufeuern und den ~h~~k~~VEHICLE_TURRETLEFT~~w~ und ~h~~k~~VEHICLE_TURRETRIGHT~~w~, um mit der Wasserkanone zu zielen.
+
+[SPRAY_1:FIRETRK] { reVC update }
+Benutze die ~h~~k~~VEHICLE_FIREWEAPON~~w~-Taste, um die Wasserkanone abzufeuern und den ~h~~k~~VEHICLE_TURRETLEFT~~w~ und ~h~~k~~VEHICLE_TURRETRIGHT~~w~, um mit der Wasserkanone zu zielen.
+
+{=================================== MISSION TABLE GENERA1 ===================================}
+
+[GEN1_I:GENERA1]
+Für diesen kleinen Gefallen werde ich Sie belohnen. Danach suchen wir Ihr Geld gemeinsam.
+
+[GEN1_A:GENERA1]
+Mr. Vercetti!
+
+[GEN1_B:GENERA1]
+Colonel.
+
+[GEN1_D:GENERA1]
+Nein danke.
+
+[GEN1_E:GENERA1]
+Es ist mir peinlich, aber es scheint, unser Problem ist zum Teil auf das lose Mundwerk einer mir vertrauten Person zurückzuführen.
+
+[GEN1_F:GENERA1]
+Seit Jahren schleppe ich Gonzalez mit, aber nun erreicht seine Unfähigkeit einen neuen Höhepunkt.
+
+[GEN1_G:GENERA1]
+Es ist nur gerecht, wenn Sie Gonzalez erledigen.
+
+[GEN1_H:GENERA1]
+War er es? Mir geht es in erster Linie um das Geld.
+
+[GEN1_J:GENERA1]
+Er ist in seinem Penthouse, vermutlich halb betrunken. Nehmen Sie das hier.
+
+[GEN1_06:GENERA1]
+Er hat eine Kettensäge!!
+
+[GEN1_07:GENERA1]
+Bleib mir vom Leib, du elender Mistkerl!
+
+[GEN1_08:GENERA1]
+Gütiger Himmel, mein Leben ist ruiniert, und mein Aussehen dazu!
+
+[GEN1_10:GENERA1]
+Ich werd dir dein Mundwerk stopfen!
+
+[GEN1_11:GENERA1]
+Bleib stehen, du Fettsack!
+
+[GEN1_12:GENERA1]
+Bleib stehen, und es geht ganz schnell!
+
+[GEN1_13:GENERA1]
+Hör auf zu jammern, das interessiert keinen, Fettsack!
+
+[GEN1_C:GENERA1]
+Danke für Ihr Kommen. Setzen Sie sich. Hummer?
+
+[GEN1_04:GENERA1]
+~g~Benutze den Eingang, um Zugang zu Gonzalez' Dachwohnung zu erhalten.
+
+[GEN1_05:GENERA1]
+~g~Erledige Gonzalez!
+
+[GEN1_09:GENERA1]
+Ich zahle dir das Doppelte, Tommy, das DOPPELTE!
+
+[GEN1_17:GENERA1]
+~g~Gonzalez versucht zu fliehen! Folge ihm durch die Türen und erledige ihn.
+
+[GEN1_18:GENERA1]
+~r~Gonzalez hat das Polizeirevier sicher erreicht!
+
+[GEN1_19:GENERA1]
+~g~Die Polizei von Vice City ist hinter dir her!
+
+[GEN1_20:GENERA1]
+~g~Steig in ein Fahrzeug.
+
+[GEN1_21:GENERA1]
+~g~Begib dich zur~h~ Pay 'N' Spray-Lackiererei~g~ in~h~ Vice Point~g~.
+
+[GEN1_22:GENERA1]
+~g~Bring dein Fahrzeug in die Lackiererei, um deinen ~h~Fahndungslevel~g~ loszuwerden und das Fahrzeug zu ~h~reparieren ~g~und ~h~umzuspritzen~g~. Kosten - ~h~$100~g~. Diesmal gratis.
+
+[GEN1_01:GENERA1]
+Um im Laufen eine Nahkampfattacke vorzubereiten, die~o~ |-Taste~w~ gedrückt halten.
+
+[GEN1_02:GENERA1]
+Um im Laufen eine Nahkampfattacke vorzubereiten, die~x~ /-Taste~w~ gedrückt halten.
+
+[GEN1_03:GENERA1]
+Um im Laufen eine Nahkampfattacke vorzubereiten, die~h~ R1-Taste~w~ gedrückt halten.
+
+[GEN1_14:GENERA1]
+Lass die~h~ ~k~~PED_FIREWEAPON~~w~ los, um die Attacke auszuführen.
+
+[GEN1_15:GENERA1]
+Lasse die~h~ ~k~~PED_FIREWEAPON~~w~ los, um die Attacke auszuführen.
+
+[GEN1_16:GENERA1]
+Lasse die~h~ ~k~~PED_FIREWEAPON~~w~ los, um die Attacke auszuführen.
+
+[GEN1_23:GENERA1]
+~g~Geh durch die Türen zurück ins Erdgeschoss.
+
+{=================================== MISSION TABLE GENERA2 ===================================}
+
+[COL2_A:GENERA2]
+Tommy! Setzen Sie sich zu mir.
+
+[COL2_B:GENERA2]
+Sieht das nicht köstlich aus? Tapirschnauze?
+
+[COL2_C:GENERA2]
+Äh... Nein. Nein, danke.
+
+[COL2_D:GENERA2]
+Tommy, Sie sind wie eine Pampas-Brise, die mich vom Gestank der Korruption befreit hat.
+
+[COL2_E:GENERA2]
+Natürlich muss ich so tun, als trauere ich um ihn und muss wie immer meine Arbeit machen.
+
+[COL2_F:GENERA2]
+Das bringt mich meinem Geld nicht näher...
+
+[COL2_G:GENERA2]
+Tommy, mein Freund, Sie sind hier nicht in Liberty. Hier regeln wir Dinge anders.
+
+[COL2_H:GENERA2]
+Ich werde weiter nachforschen, zunächst hätte ich aber ein lukratives Geschäft abzuschließen.
+
+[COL2_I:GENERA2]
+Freunden tu ich gern einen Gefallen, Cortez...
+
+[COL2_J:GENERA2]
+Sie sind ein guter Freund, Tommy. Ich wusste, ich kann auf Sie zählen.
+
+[COL2_K:GENERA2]
+Sie müssen sich mit einem Kurier treffen, der wertvolle 'Technologie' für mich beschafft hat.
+
+[COL2_1:GENERA2]
+Die Regen ist sich sehr nass um diese Jahreszeit...
+
+[COL2_2:GENERA2]
+Was?
+
+[COL2_3:GENERA2]
+Äh, comment?
+
+[COL2_4:GENERA2]
+Hören Sie, Cortez schickt mich. Geben Sie mir die verdammten Mikrochips.
+
+[COL2_5:GENERA2]
+Oh... ok.
+
+[COL2_B1:GENERA2]
+~g~Triff dich mit dem Kurier im Einkaufszentrum.
+
+[COL2_B2:GENERA2]
+~g~Der Kurier flieht mit den Lenkwaffen-Chips. Lass ihn nicht entkommen!
+
+[COL2_B3:GENERA2]
+~g~Bring die Lenkwaffen-Chips zum Colonel.
+
+[COL2_F1:GENERA2]
+~r~Du hast die Kontaktperson erledigt!
+
+[COL2_F2:GENERA2]
+~r~Der Kurier ist hinüber. Schnapp dir die Lenkwaffen-Chips.
+
+[COL2_6A:GENERA2]
+Keine Bewegung, amerikanisches Imperialistenschwein! Das ist Eigentum des französischen Staates. Her damit!
+
+[BLIPHLP:GENERA2]
+Das Radar zeigt ein nach oben zeigendes Dreieck, das bedeutet, dass das Ziel sich in größerer Höhe befindet als der Spieler.
+
+[COL2_F3:GENERA2]
+~r~Die Lenkwaffen-Chips liegen auf dem Meeresgrund.
+
+[COL2_F4:GENERA2]
+~r~Der Kurier ist entkommen! Du hast dir die Chips durch die Lappen gehen lassen.
+
+{=================================== MISSION TABLE GENERA3 ===================================}
+
+[GEN3_49:GENERA3]
+Lance' Gesundheitszustand:
+
+[GEN3_A:GENERA3]
+Thomas, danke, dass Sie kommen.
+
+[GEN3_B:GENERA3]
+Verzeihen Sie, wenn ich gleich zur Sache komme.
+
+[GEN3_C:GENERA3]
+Diaz bat mich, eine kleinere geschäftliche Transaktion zu überwachen.
+
+[GEN3_D:GENERA3]
+Wird hoffentlich besser laufen als die letzte, hah?
+
+[GEN3_E:GENERA3]
+Darum habe ich an Sie gedacht, mein Freund.
+
+[GEN3_F:GENERA3]
+Ich habe etwas zu Ihrem Schutz beim Parkhaus deponiert.
+
+[GEN3_G:GENERA3]
+Holen Sie es ab. Und dann bewachen Sie Diaz' Männer bei dem Deal.
+
+[GEN3_H:GENERA3]
+Danke, Amigo.
+
+[GEN3_1:GENERA3]
+Reißt sich alles selbst unter den Nagel, wie ich sehe.
+
+[GEN3_2:GENERA3]
+Sag mal, ist das alles, was du kannst, mir dauernd nachzuschnüffeln? Komm mit und zeig mir, dass du was drauf hast.
+
+[GEN3_3:GENERA3]
+Könnte ich machen. Ich heiße übrigens Lance.
+
+[GEN3_5:GENERA3]
+Du musst Cortez' neuer Mann sein.
+
+[GEN3_6:GENERA3]
+Bis ich was besseres finde...
+
+[GEN3_7:GENERA3]
+Sie müssen bald hier sein. Wir sollten uns gute Beobachtungsposten suchen.
+
+[GEN3_8:GENERA3]
+Ok! Ich nehm den Balkon, du kletterst auf das Dach drüben im Hof.
+
+[GEN3_9:GENERA3]
+Ich lebe! Idioten! Und das nur wegen dir! Wie heißt du?
+
+[GEN3_10:GENERA3]
+Tommy.
+
+[GEN3_11:GENERA3]
+Wir sehen uns bald wieder, glaube ich!
+
+[GEN3_12:GENERA3]
+Wo steckt denn Lance? Shit...
+
+[GEN3_14:GENERA3]
+Tommy! Ich brauch Hilfe!
+
+[GEN3_15:GENERA3]
+Keine Sorge, ich hab alles im Griff!
+
+[GEN3_16:GENERA3]
+Diaz' Männer werden umgemäht!
+
+[GEN3_19:GENERA3]
+~g~Haitianer! Sie greifen an! Beschütze Diaz!
+
+[GEN3_20:GENERA3]
+~g~Begib dich zum Parkhaus. Hol dir die Waffe, die der Colonel dort für dich deponiert hat.
+
+[GEN3_22:GENERA3]
+Diaz' Gesundheitszustand:
+
+[GEN3_23:GENERA3]
+~g~Du hast Lance vergessen. Hole ihn!
+
+[GEN3_25:GENERA3]
+~r~Lance hat's erwischt!
+
+[GEN3_28:GENERA3]
+~g~Bring den Aktenkoffer zu Diaz zurück.
+
+[GEN3_29:GENERA3]
+~g~Hol dir den Aktenkoffer und bringe ihn zu Diaz zurück.
+
+[GEN3_30:GENERA3]
+~r~Er ist mit dem Geld entwischt! Dafür macht Diaz dich kalt!
+
+[GEN3_33:GENERA3]
+~r~Du sollst Diaz und seine Männer bewachen, nicht beschießen!
+
+[GEN3_34:GENERA3]
+~r~Es gibt keinen Deal, wenn du die Kubaner erledigst!
+
+[GEN3_35:GENERA3]
+~g~Er hat Diaz' Geld gestohlen!
+
+[GEN3_36:GENERA3]
+~g~Schnapp dir das Motorrad, stelle ihn und hol Diaz' Geld zurück!
+
+[GEN3_37:GENERA3]
+~g~. Die Kubaner kommen. Überwache den Deal. Pass auf Diaz und Lance auf.
+
+[GEN3_38:GENERA3]
+~r~Diaz hat's erwischt! Du hast versagt!
+
+[GEN3_39:GENERA3]
+~g~Begib dich zu deinem Beobachtungsposten die Treppe hoch.
+
+[GEN3_44:GENERA3]
+~g~Begib dich mit Lance zum Übergabeort und pass auf Diaz auf.
+
+[GEN3_45:GENERA3]
+Sie müssen bald hier sein. Wir sollten uns gute Beobachtungsposten suchen.
+
+[GEN3_40:GENERA3] { reVC update }
+Um auf einem ~h~Motorrad ~w~sitzend ~h~geradeaus zu feuern~w~, drücke die ~h~~k~~VEHICLE_FIREWEAPON~.
+
+[GEN3_41:GENERA3] { reVC update }
+Um auf einem ~h~Motorrad ~w~sitzend ~h~geradeaus zu feuern~w~, drücke die ~h~~k~~VEHICLE_FIREWEAPON~.
+
+[GEN3_46:GENERA3]
+Scheiße!
+
+[GEN3_47:GENERA3]
+Tommy!
+
+[GEN3_48:GENERA3]
+Verdammt!
+
+[GEN3_50:GENERA3]
+~r~Du hast Diaz' Geld verloren! Versuch das nächste Mal, das Geld nicht zu vernichten!
+
+[GEN3_51:GENERA3]
+Noch mehr verdammte Haitianer in einem beschissenen Van!
+
+[GEN3_54:GENERA3]
+Steht nicht rum, ihr Idioten! Schnappt euch diesen haitianischen Mistkerl!
+
+[GEN3_55:GENERA3]
+Tommy! Ich bleibe hier und passe auf Diaz auf!
+
+[GEN3_18:GENERA3]
+~g~Die Kubaner kommen. Bleib in Diaz' Nähe. Überwache den Deal. Pass auf Diaz und Lance auf.
+
+[GEN3_56:GENERA3]
+~r~Diaz ist hinüber, er ist in einen Hinterhalt geraten. Pass das nächste Mal auf ihn auf!
+
+[GEN3_57:GENERA3]
+Die Kruger ist ein Sturmgewehr, das einem erlaubt, in der subjektiven Kamera-Einstellung manuell zu zielen.
+
+[GEN3_58:GENERA3]
+Halte die~h~ R1~w~-Taste gedrückt, um mit dem Sturmgewehr zu ~h~zielen~w~.
+
+[GEN3_59:GENERA3]
+Halte die~h~ L1~w~-Taste gedrückt, um mit dem Sturmgewehr zu ~h~zielen~w~.
+
+[GEN3_60:GENERA3]
+Drücke die ~h~~k~~PED_FIREWEAPON~~w~-Taste, um das Sturmgewehr ~h~abzufeuern~w~.
+
+[GEN3_61:GENERA3]
+Drücke die ~h~~k~~PED_FIREWEAPON~~w~-Taste, um das Sturmgewehr ~h~abzufeuern~w~.
+
+[GEN3_62:GENERA3]
+Drücke die ~h~~k~~PED_FIREWEAPON~~w~-Taste, um das Sturmgewehr ~h~abzufeuern~w~.
+
+[GEN3_63:GENERA3]
+Auf~h~ Motorrädern ~w~kann man nicht nur im Vorbeifahren seitlich auf Ziele schießen, man kann auch ~h~geradeaus feuern~w~.
+
+[GEN3_64:GENERA3] { reVC update }
+Um auf einem Motorrad sitzend geradeaus zu feuern, drücke die ~h~~k~~VEHICLE_FIREWEAPON~~w~-Taste.
+
+[GEN3_65:GENERA3] { reVC update }
+Um auf einem Motorrad sitzend geradeaus zu feuern, drücke die ~h~~k~~VEHICLE_FIREWEAPON~~w~-Taste.
+
+[GEN3_66:GENERA3] { reVC update }
+Um auf einem Motorrad sitzend geradeaus zu feuern, drücke die ~h~~k~~VEHICLE_FIREWEAPON~~w~-Taste.
+
+[GEN3_67:GENERA3]
+Du brauchst eine Maschinenpistole, um auf einem Motorrad sitzend geradeaus zu feuern.
+
+[GEN3_53:GENERA3]
+MEIN GELD!
+
+[GEN3_52:GENERA3]
+Diese Haitianer denken sie könnten RICARDO DIAZ stürzen!?!
+
+{=================================== MISSION TABLE GENERA4 ===================================}
+
+[DETON:GENERA4]
+DETONATION:
+
+[COL4_3:GENERA4]
+KONVOI HALT!
+
+[COL4_6:GENERA4]
+WIR STEHEN UNTER FEINDLICHEM BESCHUSS!
+
+[COL4_7:GENERA4]
+Weg da von dem Panzer, Zivilist!
+
+[COL4_8:GENERA4]
+ICH SAGTE, WEG DA! SOFORT!
+
+[COL4_9:GENERA4]
+AUF GEFECHTSPOSITIONEN!
+
+[COL4_11:GENERA4]
+Schaffen Sie den Zivilisten aus dem Weg, Soldat! - Sir, zu Befehl, Sir!
+
+[COL4_12:GENERA4]
+Zivilist im PANZER! HALTET IHN AUF!
+
+[COL4_13:GENERA4]
+Dies ist ein Militärkonvoi, machen Sie den Weg frei!
+
+[COL4_14:GENERA4]
+Erledigen sie ihn, Soldat.
+
+[COL4_15:GENERA4]
+Schaffen Sie das Zivilfahrzeug aus dem Weg! -Fahrzeug wird weggeschafft, Sir!
+
+[COL4_17:GENERA4]
+OK, EINHEIT WEITER!
+
+[COL4_18:GENERA4]
+Da ist jemand auf dem Panzer, Sir!
+
+[COL4_19:GENERA4]
+Gehen Sie ein paar Donuts holen, Soldat! - Zu Befehl, Sir!
+
+[COL4_20:GENERA4]
+Ziel erfasst, Sir.
+
+[COL4_21:GENERA4]
+HECKENSCHÜTZE!
+
+[COL4_22:GENERA4]
+Ich seh zu, dass ich hier wegkomme!
+
+[COL4_23:GENERA4]
+Einsatz durchgeführt! Einheit, wegtreten! - Gehen wir ein paar Donuts essen.
+
+[COL4_24:GENERA4]
+Sicherheitsmechanismus Delta India Echo aktiviert. Selbstzerstörung des Fahrzeugs eingeleitet!
+
+[COL4_26:GENERA4]
+Mach dein Testament, dreckiger Kommunist!
+
+[COL4_B2:GENERA4]
+~r~Der Panzer ist wohlbehalten an seinem Ziel angekommen!
+
+[COL4_B5:GENERA4]
+~r~Der Panzer ist zerstört worden!
+
+[COL4_01:GENERA4]
+Diaz war sehr angetan und würde Sie gerne wiedersehen.
+
+[COL4_02:GENERA4]
+Ist das eine gute Nachricht?
+
+[COL4_03:GENERA4]
+Aber sicher! Obwohl mich der Verdacht beschleicht, dass Diaz für unsere Verluste verantwortlich war...
+
+[COL4_04:GENERA4]
+Wie kommen Sie darauf?
+
+[COL4_05:GENERA4]
+Man erhebt keine Anschuldigungen gegen einen Mann wie Diaz. Ich habe nur laut nachgedacht.
+
+[COL4_06:GENERA4]
+Egal. Ich habe einen Vorschlag, der lukrativ für Sie sein könnte...
+
+[COL4_07:GENERA4]
+Ich habe keine Zeit für weitere Aufträge, Cortez.
+
+[COL4_08:GENERA4]
+Ein Mann mit solch bedrohlichen Schulden sollte doch um jede Verdienstmöglichkeit dankbar sein. Hören Sie mich wenigstens an.
+
+[COL4_09:GENERA4]
+Na gut...
+
+[COL410:GENERA4]
+Ich habe einen Käufer für ein 'Militärgerät', das durch die Stadt transportiert wird. Beschaffen Sie es!
+
+[COL411:GENERA4]
+Wenn Sie es haben, rufen Sie mich unverzüglich an...
+
+[COL4_B4:GENERA4]
+~g~Der Panzer ist abgeschlossen. Lass dir etwas einfallen, um die Besatzung herauszulocken.
+
+[COL4_1:GENERA4]
+Was ist mit dem Kanonier? - Weiß nicht, Sir!
+
+[COL4_4:GENERA4]
+Los, sehen Sie nach, Soldat! - Zu Befehl, Sir!
+
+[COL4_B1:GENERA4]
+~g~Besorge das militärische Fahrzeug, das durch die Stadt gefahren wird.
+
+[COL4_B3:GENERA4]
+~g~Liefere den Panzer in der Garage des Colonels ab, bevor er sich selbst zerstört.
+
+[COL4_B6:GENERA4]
+~g~Finde einen Weg, den Panzer zu klauen!
+
+[COL4_B7:GENERA4]
+~g~Fahr den Panzer in die Garage.
+
+[COL4_B8:GENERA4]
+~g~Steig aus dem Panzer und verlasse die Garage.
+
+{=================================== MISSION TABLE GENERA5 ===================================}
+
+[COL5A_1:GENERA5]
+Die Lage erfordert ein eiliges Verschwinden, Amigo.
+
+[COL5A_2:GENERA5]
+Was gibt's für ein Problem?
+
+[COL5A_3:GENERA5]
+Die Franzosen wollen ihre Lenkwaffen-Chips wieder und nach dem letzten Zwischenfall
+
+[COL5A_4:GENERA5]
+zieht es mich in sicherere Gefilde.
+
+[COL5A_5:GENERA5]
+Wäre es nicht sicherer zu fliegen?
+
+[COL5A_6:GENERA5]
+Ich wäre erledigt, bevor ich eingecheckt hätte. Außerdem muss ich Ware außer Landes schaffen.
+
+[COL5A_7:GENERA5]
+Brauchen Sie noch einen Bodyguard?
+
+[COL5A_8:GENERA5]
+Sie, mein Freund, sind zehn Bodyguards wert. Hahaha.
+
+[COL5B_1:GENERA5]
+Thomas, Sie haben mich beschützt und mir treu gedient.
+
+[COL5B_2:GENERA5]
+Aber jetzt müssen Sie uns verlassen, ehe wir das offene Meer erreichen.
+
+[COL5B_4:GENERA5]
+Danke, Colonel.
+
+[COL5B_5:GENERA5]
+Eine Bitte noch. Könnten Sie ein Auge auf Mercedes haben, solange ich weg bin?
+
+[COL5B_6:GENERA5]
+Ich glaub zwar, sie kann auf sich selbst aufpassen, aber klar.
+
+[COL5B_7:GENERA5]
+Danke, mein Freund. Bis zu meiner Rückkehr.
+
+[COL5B_8:GENERA5]
+Adios, Amigo.
+
+[COL5_7:GENERA5]
+Hören Sie auf, auf mich zu schießen!
+
+[COL5_9:GENERA5]
+Tommy, die sollen aufhören, auf mich zu schießen!
+
+[COL5_10:GENERA5]
+Ich genieße diplomatische Immunität.
+
+[COL5_11:GENERA5]
+Nicht schießen, ich bin ein Colonel!
+
+[COL5_12:GENERA5]
+Thomas, machen Sie sie fertig. Mein Land wird es Ihnen danken.
+
+[COL5_13:GENERA5]
+Tommy, wir werden von den Franzosen überrannt!
+
+[COL5_14:GENERA5]
+Tommy, wo ich hinsehe, überall Franzosen! Wie ich es hasse!
+
+[COL5_15:GENERA5]
+Tommy, alles in Ordnung?
+
+[COL5_16:GENERA5]
+Das ist für Piaf und Gainesbourg und für euer dämliches französisches Weißbrot!
+
+[COL5_1:GENERA5]
+Backbord! Backbord!
+
+[COL5_2:GENERA5]
+Sie greifen von Steuerbord an!
+
+[COL5_3:GENERA5]
+Die Brücke da vorn!
+
+[COL5_4:GENERA5]
+Sie haben einen Helikopter!
+
+[COL5_B1:GENERA5]
+~g~Beschütze den Colonel und seine Jacht um jeden Preis.
+
+[COL5_B2:GENERA5]
+~g~Geh nach vorn und räume der Jacht des Colonels den Weg frei.
+
+[COL5_B3:GENERA5]
+~r~Der Colonel ist hinüber!
+
+[COL5_B4:GENERA5]
+~g~Schieße den angreifenden Helikopter vom Himmel.
+
+[COL5B_3:GENERA5]
+Ich werde meine Privatbarkasse zu Wasser lassen. Sie gehört Ihnen, als Ausdruck meiner Dankbarkeit.
+
+[COL5_B5:GENERA5]
+~g~Schieß die Helikopter ab, gefährde nicht die Jacht.
+
+[COL5_B6:GENERA5]
+~g~Du hast keine Munition mehr. Hol dir an der Treppe des Oberdecks Nachschub.
+
+[COL5_B7:GENERA5]
+~g~Du hast nur noch wenig Energie. Hol dir an der Treppe des Oberdecks Nachschub.
+
+{=================================== MISSION TABLE HAIT1 ===================================}
+
+[HAM1_A:HAIT1]
+Hallo? Hallo?
+
+[HAM1_B:HAIT1]
+Komm rein, mein Lieber, und ruh dich aus.
+
+[HAM1_C:HAIT1]
+Du musst der große böse Mann sein, von dem mein Großvater erzählt hat.
+
+[HAM1_D:HAIT1]
+Er erzählte immer von dir, wenn er zu Besuch kam,
+
+[HAM1_E:HAIT1]
+und von den anderen, die auf dich warten.
+
+[HAM1_F:HAIT1]
+Tja, wir müssen alle mal sterben, aber du...
+
+[HAM1_G:HAIT1]
+....in deiner Haut möchte ich dann nicht stecken. Hehehe!
+
+[HAM1_H:HAIT1]
+Es hieß, ich soll hierher kommen.
+
+[HAM1_I:HAIT1]
+Kannst du sie hören?
+
+[HAM1_J:HAIT1]
+Sie rufen deinen Namen, Junge. Die müssen ziemlich scharf auf dich sein, was?
+
+[HAM1_K:HAIT1]
+Aber wenn du der alten Tante Poulet hilfst, hilft sie dir vielleicht auch.
+
+[HAM1_L:HAIT1]
+Vielleicht kann sie dir danach einen kleinen Talisman schenken.
+
+[HAM1_M:HAIT1]
+Ein bisschen Magie, die den Männern des Gesetzes schlechte Augen macht, hmm?
+
+[HAM1_N:HAIT1]
+Hören Sie, das ist alles sehr, äh... Sie geben mir was?
+
+[HAM1_O:HAIT1]
+Ich...ich...ich glaube, ich bin hier falsch.
+
+[HAM1_P:HAIT1]
+Erweise mir ein paar Gefälligkeiten, Tommy...
+
+[HAM1_Q:HAIT1]
+Die Kubaner, miese, hochnäsige Narren, hmmm,
+
+[HAM1_R:HAIT1]
+haben meine lieben Haiti-Boys sehr geärgert.
+
+[HAM1_S:HAIT1]
+Jetzt haben sie den Polizisten erzählt, wo ich meine Pülverchen versteckt habe.
+
+[HAM1_T:HAIT1]
+Sie denken, das sind Drogen, diese Dummköpfe.
+
+[HAM1_U:HAIT1]
+Sei ein braver Bub, Tommy, und hole Tante Poulet die Pülverchen.
+
+[HAM1_V:HAIT1]
+Ja, ja. Sicher, sicher.
+
+[HAM1_1:HAIT1]
+~g~Die Cops nähern sich dem Zeug. Hol es, bevor sie dort sind.
+
+[HAM1_2:HAIT1]
+~r~Die Cops waren schneller bei dem Zeug!
+
+[HAM1_3:HAIT1]
+~g~Bring das Zeug zum Unterschlupf!
+
+[HAM1_4:HAIT1]
+~g~Gut. Jetzt das nächste!
+
+[HAM1_6:HAIT1]
+~r~Das Zeug wurde vernichtet, du Idiot!
+
+[HAM1_7:HAIT1]
+~g~Die Cops haben das Zeug! Hol es dir wieder, bevor sie weg sind!
+
+[HAM1_8:HAIT1]
+~g~Die Cops sind unterwegs, um das Zeug abzuholen. Beeil dich!
+
+[HAT_1A:HAIT1]
+~g~Keine Bewegung, Freundchen!
+
+{=================================== MISSION TABLE HAIT2 ===================================}
+
+[HAT2_B1:HAIT2]
+~g~Begib dich zu dem Wagen, in dem die fliegenden Bomben sind.
+
+[HAT2_B2:HAIT2]
+Schalte die Kubaner aus...
+
+[HAT2_B4:HAIT2]
+.... und zerstöre ihre Boote!
+
+[HAT2_B5:HAIT2]
+~g~Die Kubaner hauen ab. Lass sie nicht entkommen!
+
+[HAT2_B6:HAIT2]
+~r~Das ferngesteuerte Flugzeug ist außer Reichweite!
+
+[HAT2_B7:HAIT2]
+~g~Einer der Kubaner flieht in einem Auto. Lass ihn nicht entkommen!
+
+[HAT2_B8:HAIT2]
+~r~Du hast keine ferngesteuerten Flugzeuge mehr!
+
+[HAT2_B9:HAIT2]
+Ferngesteuerte Flugzeuge:
+
+[HAT2_1:HAIT2]
+Oh. Entschuldigung, ich muss die falsche Adresse haben...
+
+[HAT2_2:HAIT2]
+Du kannst gern reinkommen und dich bei einer Tasse Tee ausruhen.
+
+[HAT2_3:HAIT2]
+Hast du etwas für mich, Tommy?
+
+[HAT2_4:HAIT2]
+Ja...
+
+[HAT2_5:HAIT2]
+Das kommt mir so bekannt vor hier. Ein Geruch aus meiner Kindheit - das muss ein Déjà-vu sein...
+
+[HAT2_6:HAIT2]
+Tommy, du kannst was für mich tun, ich werd's dir erklären. Hör gut zu, ja?
+
+[HAT2_7:HAIT2]
+Sie sehen aus wie jemand, den...
+
+[HAT2_8:HAIT2]
+Die Kubaner haben schnelle Boote, mit denen transportieren sie Drogen übers Meer.
+
+[HAT2_9:HAIT2]
+Davon leben sie.
+
+[HAT2_10:HAIT2]
+Mein Neffe hat kleine fliegende Bomben gebaut, um ihnen das Handwerk zu legen.
+
+[HAT2_11:HAIT2]
+Lass ihre Boote in die Luft fliegen.
+
+[HAT2_12:HAIT2]
+Tja, danke für den Tee.
+
+[HAT2_B3:HAIT2] { reVC update }
+Um eine Bombe abzuwerfen, drück die ~h~~k~~VEHICLE_FIREWEAPON~~w~-Taste. ~h~~k~~VEHICLE_ENTER_EXIT~~w~-Taste zum Beenden.
+
+{=================================== MISSION TABLE HAIT3 ===================================}
+
+[HAM3_A:HAIT3]
+Hallo, hallo, ich, äh, ich suche hier jemanden...
+
+[HAM3_B:HAIT3]
+Du siehst hungrig aus, Tommy.
+
+[HAM3_C:HAIT3]
+Kenne ich Sie?
+
+[HAM3_D:HAIT3]
+Sei jetzt still.
+
+[HAM3_E:HAIT3]
+Eine Gefälligkeit noch, dann lasse ich dich gehen, Tommy.
+
+[HAM3_F:HAIT3]
+Meine Jungs haben die Kubaner zum Kampf gefordert.
+
+[HAM3_G:HAIT3]
+Aber ohne Kanonen.
+
+[HAM3_H:HAIT3]
+Hmm, aber die Kubaner werden ihr blaues Wunder erleben.
+
+[HAM3_I:HAIT3]
+Wenn sie in den Straßen kämpfen, nimmst du dieses Gewehr und räumst auf.
+
+[HAM3_J:HAIT3]
+Keiner sieht dich, keiner hört dich.
+
+[HAM3_K:HAIT3]
+Wenn du das für mich tust, Tommy, dann kommst frei aus meinen Schürzenbändern.
+
+[HAM3_1:HAIT3]
+~g~Wir müssen gewinnen. Werden alle Haitianer erledigt, haben wir verloren.
+
+[HAM3_3:HAIT3]
+~g~Vermutlich werden die Kubaner schummeln. Sei auf der Hut!
+
+[HAM3_4:HAIT3]
+~r~Du wurdest entdeckt! Die Mission ist fehlgeschlagen!
+
+[HAM3_5:HAIT3]
+~g~Du musst die Kubaner aus der Distanz erwischen. Man darf dich nicht sehen.
+
+[HAM3_8:HAIT3]
+~g~Es gibt Verluste unter den Haitianern! Du musst besser zielen!
+
+[HAM3_7:HAIT3]
+~g~Vorsicht! Die Kubaner haben Verstärkung mitgebracht. Schalte sie alle aus!!
+
+[HAM3_2:HAIT3]
+~r~Die Haitianer sind weg vom Fenster!
+
+[HAM3_L:HAIT3]
+Okay, Tantchen...
+
+{=================================== MISSION TABLE HOTEL ===================================}
+
+[INTB_A:HOTEL]
+Tommy! Tommy, wir haben uns lange nicht gesehen.
+
+[INTB_B:HOTEL]
+Hallo, Sonny.
+
+[INTB_C:HOTEL]
+Ich weiß, ich weiß. Dir kommen vor Rührung die Tränen.
+
+[INTB_D:HOTEL]
+15 Jahre ist es her - dabei kommt's mir vor, als wär's gestern gewesen.
+
+[INTB_E:HOTEL]
+DU hast leicht reden.
+
+[INTB_F:HOTEL]
+Hey, für die Familie in den Knast zu gehen, ist kein Zuckerschlecken,
+
+[INTB_G:HOTEL]
+aber die Familie zeigt sich für sowas erkenntlich, ok?
+
+[INTB_H:HOTEL]
+Also, wie ist der Deal gelaufen - hast du Schnee an der Hand?
+
+[INTB_I:HOTEL]
+Sonny, wir sind reingelegt worden. Der Deal war eine Falle. Harry und Lee sind tot.
-{ re3 updates }
+[INTB_J:HOTEL]
+Das ist nicht dein Ernst, Tommy. Du hast doch hoffentlich noch das Geld.
+
+[INTB_K:HOTEL]
+Nein, Sonny... Ich hab das Geld nicht mehr.
+
+[INTB_L:HOTEL]
+Das war mein Geld, Tommy. MEIN GELD!
+
+[INTB_M:HOTEL]
+Versuch bloß nicht, mich reinzulegen, Tommy. Mich legt man nicht rein, das weißt du!
+
+[INTB_N:HOTEL]
+Warte, Sonny.
+
+[INTB_O:HOTEL]
+Du hast mein Wort darauf, dass ich dir dein Geld wiederbeschaffe. Und die Drogen.
+
+[INTB_P:HOTEL]
+Und ich liefere dir die Kerle, die dahinterstecken.
+
+[INTB_Q:HOTEL]
+Das weiß ich doch. Du bist kein Idiot, Tommy, aber ich warne dich - ich bin auch keiner.
+
+[INTB_R:HOTEL]
+Wenn du's nicht wärst - ein anderer wär längst fällig!
+
+[INTB_S:HOTEL]
+Aber uns beide verbindet eine alte Freundschaft. Ich lasse dich das regeln.
+
+[INTB_T:HOTEL]
+Sonny, du hast mein Ehrenwort.
+
+[INTB_U:HOTEL]
+Du hörst von mir.
+
+{=================================== MISSION TABLE ICECRE1 ===================================}
+
+[ICC1_1:ICECRE1]
+~g~Benutze deinen Eis-Wagen, um in Vice City Drogen zu verkaufen.
+
+[ICC1_2:ICECRE1]
+~g~Parke den Eis-Wagen und drücke ~h~~k~~VEHICLE_HORN~~w~, um den Eiscreme-Jingle abzuspielen, damit deine Kunden wissen, dass du Ware zu verkaufen hast.
+
+[ICC1_3:ICECRE1]
+~g~Für jede Transaktion bekommst du Geld. Aber je mehr Transaktionen du tätigst, desto stärker wird die Polizei auf dich aufmerksam.
+
+[ICC1_4:ICECRE1]
+~g~In dieser Gegend sind keine Kunden. Versuche es woanders.
+
+[ICC1_5:ICECRE1]
+Getätigte Deals:
+
+[ICC1_6:ICECRE1]
+~g~Nimm den Mr. Whopee, um in Vice City Cherry Popper-Produkte zu vertreiben.
+
+[ICC1_7:ICECRE1]
+~g~Für jede Transaktion bekommst du Geld. Aber je mehr Transaktionen du tätigst, desto stärker wird die Polizei auf dich aufmerksam.
+
+[ICC1_8:ICECRE1]
+~g~Um eine Transaktion zu tätigen, ~h~parke deinen Wagen ~g~und drücke die ~h~~k~~VEHICLE_HORN~~g~, um den Eiscreme-Jingle abzuspielen, damit deine Kunden wissen, dass du Ware zu verkaufen hast.
+
+[ICC1_9:ICECRE1]
+~g~Andere Gangs werden es nicht gern sehen, dass du in ihrem Revier Geschäfte machst, du musst also mit Feindseligkeiten rechnen.
+
+[ICC1_10:ICECRE1]
+~g~Du hast ~1~ Deals getätigt!
+
+[ICC1_11:ICECRE1]
+~g~Du hast ~1~ Deal getätigt.
+
+[ICC1_12:ICECRE1]
+OBJEKT ERWORBEN!
+
+[ICC1_13:ICECRE1]
+~r~Du hast keine Deals getätigt!
+
+[ICC1_14:ICECRE1]
+EISCREME-MISSIONEN ERFÜLLT
+
+[ICC1_15:ICECRE1]
+~g~Die Eiscremefabrik generiert nun bis zu $~1~ Einkünfte. Hol dir das Geld regelmäßig ab.
+
+[ICC1_16:ICECRE1]
+~g~Nimm den Mr. Whoopee, um in Vice City Cherry Popper-Produkte zu vertreiben.
+
+[ICE_AT1:ICECRE1]
+EISCREMEFABRIK-MISSIONEN ERFÜLLT
+
+[ICE_AT2:ICECRE1]
+~g~Die Cherry Popper-Fabrik generiert nun bis zu $~1~ Einkünfte. Hol dir das Geld regelmäßig ab.
+
+[ICC1_17:ICECRE1]
+Stoff-Auslieferungs-Mission beendet
+
+[ICC1_18:ICECRE1]
+Eiscremeverkauf insgesamt: $~1~
+
+[ICC1_19:ICECRE1]
+Insgesamt getätigte Deals: ~1~
+
+{=================================== MISSION TABLE ICECUT ===================================}
+
+[ICC1_M:ICECUT]
+Sie sind schmutzige, verrotzte, verlauste, eklige, sabbernde kleine...
+
+[ICC1_I:ICECUT]
+Ein Baby... ein widerwärtiges, gräßliches, ekelhaftes kleines Gör!
+
+[ICC1_J:ICECUT]
+Mammi liebt dich nicht. Du kleines Stück Scheiße!
+
+[ICC1_A:ICECUT]
+Wer sind Sie?
+
+[ICC1_B:ICECUT]
+Der neue Inhaber dieses Ladens.
+
+[ICC1_C:ICECUT]
+Sind Sie, oder waren Sie je ein Kind?
+
+[ICC1_D:ICECUT]
+Was soll denn das heißen?
+
+[ICC1_E:ICECUT]
+Waren Sie je ein Kind?
+
+[ICC1_F:ICECUT]
+Ja! Immer mit der Ruhe! Was ist denn mit Ihnen los?
+
+[ICC1_G:ICECUT]
+Ich wusste es. Ein Kind.
+
+[ICC1_H:ICECUT]
+Ein schmutziges, stinkendes, verrotztes, verlaustes, nölendes kleines Baby!
+
+[ICC1_K:ICECUT]
+Au! Beruhigen Sie sich doch!
+
+[ICC1_L:ICECUT]
+Ich HASSE Babies. Und ich hasse Kinder.
+
+[ICC1_N:ICECUT]
+Es reicht jetzt!
+
+[ICC1_P:ICECUT]
+Sie stellen doch Softeis her, oder? Das essen doch nur Kinder.
+
+[ICC1_Q:ICECUT]
+Sind Sie komplett irre?
+
+[ICC1_R:ICECUT]
+Erklären Sie mir das mal - warum Kinder glücklich machen, wenn Sie sie hassen?
+
+[ICC1_S:ICECUT]
+Oh, du dämliches, verrotztes, verlaustes-
+
+[ICC1_T:ICECUT]
+Schluss jetzt!
+
+[ICC1_U:ICECUT]
+- Gör!
+
+[ICC1_V:ICECUT]
+Das Eis ist nur Tarnung!
+
+[ICC1_W:ICECUT]
+Wir vertreiben auch andere Waren. Nicht-Milchprodukte.
+
+[ICC1_X:ICECUT]
+Und wenn ich ein Kind sehe, dann weiß ich, was ich mit ihm anfange.
+
+[ICC1_Y:ICECUT]
+Nicht wahr, Kinderchen? Ja, ja. Mammi hat euch gar nicht lieb.
+
+[ICC1_Z:ICECUT]
+Sie HASST euch!
+
+[ICC1_ZA:ICECUT]
+OBJEKT ERWORBEN!
+
+{=================================== MISSION TABLE INTRO ===================================}
+
+[INT1_A:INTRO]
+Tommy Vercetti...Hah! Shit.
+
+[INT1_B:INTRO]
+Hätte nicht gedacht, dass der noch mal rauskommt.
+
+[INT1_C:INTRO]
+Er hat den Kopf eingezogen. War fast vergessen.
+
+[INT1_D:INTRO]
+Aber bald wird man sich an ihn erinnern.
+
+[INT1_E:INTRO]
+Wenn man ihn wieder durch ihre Viertel tigern sieht.
+
+[INT1_F:INTRO]
+Wird schlecht fürs Geschäft sein.
+
+[INT1_G:INTRO]
+Tja, was sollen wir machen, Sonny?
+
+[INT1_H:INTRO]
+Wir machen auf alte Kumpels und schicken ihn woanders hin. Ok?
+
+[INT1_I:INTRO]
+Wir wollten doch sowieso nach Süden expandieren, oder?
+
+[INT1_J:INTRO]
+In Vice City liegt zurzeit das Geld auf der Straße.
+
+[INT1_K:INTRO]
+Die Kolumbianer, die Mexikaner,
+
+[INT1_L:INTRO]
+ja, sogar die kubanischen Flüchtlinge machen alle glänzende Geschäfte.
+
+[INT1_M:INTRO]
+Aber das geht nur mit Drogen, Sonny.
+
+[INT1_N:INTRO]
+Aber keine der Familien rührt dieses Zeug an!
+
+[INT1_O:INTRO]
+Die Zeiten ändern sich.
+
+[INT1_P:INTRO]
+Die Familien können nicht wegsehen, während unsere Feinde groß abkassieren.
+
+[INT1_Q:INTRO]
+Also schicken wir jemanden für die Drecksarbeit da runter
+
+[INT1_R:INTRO]
+und schneiden uns 'ne hübsche Scheibe ab. Ok?
+
+[INT1_S:INTRO]
+Wer ist unser Kontaktmann da unten?
+
+[INT1_T:INTRO]
+Ken Rosenberg, ein Idiot von einem Anwalt.
+
+[INT1_U:INTRO]
+Wie soll der Vercetti im Zaum halten?
+
+[INT1_V:INTRO]
+Muss er gar nicht.
+
+[INT1_W:INTRO]
+Wir lassen ihn einfach auf Vice City los.
+
+[INT1_X:INTRO]
+Wir geben ihm ein bisschen Startgeld, ok?
+
+[INT1_Y:INTRO]
+Wir warten ein paar Monate.
+
+[INT1_Z:INTRO]
+Dann fahren wir hin
+
+[INT1_A1:INTRO]
+und schauen mal bei ihm rein, klar?
+
+[INT1_A2:INTRO]
+Mal sehen, wie er sich macht.
+
+[INT2_A:INTRO]
+Hey, hey, Jungs! Ich bin, äh, Ken Rosenberg. Ha, ha, sehr gut, hey!
+
+[INT2_B:INTRO]
+Tja, äh, ich soll euch zu dem Trefffen fahren, okay?
+
+[INT2_C:INTRO]
+Ich hab mit den Lieferanten geredet, und die würden,
+
+[INT2_D:INTRO]
+liebend gern mit uns ins Geschäft kommen. Und, äh,
+
+[INT2_E:INTRO]
+wenn alles gut geht, dann dürfte da
+
+[INT2_F:INTRO]
+ein Haufen Kohle für uns drin sein. Und das ist doch, na ja...
+
+[INT2_G:INTRO]
+gut...
+
+[INT2_H:INTRO]
+Okay. Es sind zwei Brüder, ok?
+
+[INT2_I:INTRO]
+Der eine schmeißt, äh, den Laden,
+
+[INT2_J:INTRO]
+der andere macht die Flüge.
+
+[INT2_K:INTRO]
+Die arbeiten von Mexiko aus,
+
+[INT2_M:INTRO]
+Sie haben eine Farm in Panama.
+
+[INT2_N:INTRO]
+Okay, passt auf, Jungs,
+
+[INT2_O:INTRO]
+wenn wir dort ankommen, sollte ich im Auto bleiben,
+
+[INT2_P:INTRO]
+oder soll ich mit reinkommen?
+
+[INT2_Q:INTRO]
+Nein. Bleib im Wagen.
+
+[INT2_R:INTRO]
+Wisst ihr was, ich hab's mir überlegt.
+
+[INT2_S:INTRO]
+Ich pass auf den Wagen auf.
+
+[INT3_A:INTRO]
+Ok, das sind sie, da im Helikopter.
+
+[INT3_B:INTRO]
+Ok, das ganze läuft so ab:
+
+[INT3_C:INTRO]
+Die wollen eine saubere Übergabe auf offenem Gelände.
+
+[INT3_D:INTRO]
+Alles klar? Ok, dann wollen wir mal.
+
+[INT3_E:INTRO]
+Ok, ganz ruhig jetzt.
+
+[INT3_F:INTRO]
+Ich bin hier. Der Wagen läuft, Baby!
+
+[INT3_G:INTRO]
+Hast du's?
+
+[INT3_H:INTRO]
+100% astreines kolumbianisches Koks, mein Freund.
+
+[INT3_I:INTRO]
+Die Kohle?
+
+[INT3_J:INTRO]
+Zehner und Zwanziger. Gebrauchte Scheine.
+
+[INT3_L:INTRO]
+Los, los, weg hier! Fahr los!
+
+[INT4_A:INTRO]
+Gearscht. Wir sind voll gearscht!
+
+[INT4_B:INTRO]
+Das ist wieder typisch.
+
+[INT4_C:INTRO]
+Da passe ich eine einziges Mal nicht auf,
+
+[INT4_D:INTRO]
+und prompt kriege ich eins reingewürgt.
+
+[INT4_E:INTRO]
+Hier!
+
+[INT4_F:INTRO]
+Hör endlich auf zu jammern. Du lebst schließlich noch, oder?
+
+[INT4_G:INTRO]
+Lass mich hier raus.
+
+[INT4_H:INTRO]
+Schaff das Auto weg und leg dich schlafen.
+
+[INT4_I:INTRO]
+Ich komme morgen zu dir ins Büro, dann sehen wir weiter.
+
+[INT4_J:INTRO]
+Ok, gute Idee. Ich leg mich erstmal hin.
+
+[INT4_K:INTRO]
+Was hast du vor?
+
+[INT4_L:INTRO]
+Ich geh zurück in mein Hotel.
+
+[INT4_M:INTRO]
+Ich muss nachdenken, was schiefgelaufen ist.
+
+[INT4_N:INTRO]
+Ok.
+
+[INTRO1:INTRO]
+Da passe ich ein einziges Mal nicht auf, und prompt kriege ich eins reingewürgt.
+
+[INTRO2:INTRO]
+Leg dich schlafen.
+
+[INTRO3:INTRO]
+Was hast du vor?
+
+[INTRO4:INTRO]
+Ich komme morgen zu dir ins Büro, dann sehen wir weiter.
+
+[INT3_K:INTRO]
+Tja, der Deal kann steigen, mein Freund.
+
+[INT3_M:INTRO]
+Zeig her.
+
+[INT2_L:INTRO]
+Nein, nein, nein, wartet...
+
+{=================================== MISSION TABLE KENT1 ===================================}
+
+[KPM1_A:KENT1]
+Ok, du Knallkopf, ich werde deine Haut retten.
+
+[KPM1_B:KENT1]
+Was sagst du?
+
+[KPM1_C:KENT1]
+Du kennst doch Diaz, den Idioten, den Koks-König?
+
+[KPM1_D:KENT1]
+Er hat deinen Freund Lance. Es heißt, dein Kumpel wollte ihm an den Kragen.
+
+[KPM1_E:KENT1]
+Hat ihn aber fast den eigenen gekostet hat, falls du weißt, was ich meine.
+
+[KPM1_F:KENT1]
+Wo hat er ihn hingebracht? Im Klartext!
+
+[KPM1_G:KENT1]
+Mach dich mal locker! Sie haben ihn beim Schrottplatz erwischt.
+
+[KPM1_H:KENT1]
+Verdammt noch mal. Psycho.
+
+[KPM1_2:KENT1]
+~r~Du solltest Lance lebend da rausholen!
+
+[KPM1_3:KENT1]
+Lance' Gesundheitszustand:
+
+[RESC_1:KENT1]
+Kannst du eine Waffe halten?
+
+[RESC_2:KENT1]
+Klar, glaub schon. Freut mich, dich zu sehen.
+
+[RESC_3:KENT1]
+Los, wir verschwinden von hier.
+
+[RESC_4:KENT1]
+Dank dir ist mein ganzer schöner Plan im Eimer. Das hast du sauber vermasselt, Lance.
+
+[RESC_5:KENT1]
+Er hat meinen Bruder auf dem Gewissen. Soll ich ihm den Rasen mähen?
+
+[RESC_6:KENT1]
+Wir müssen diesen Diaz erledigen bevor er uns erledigt.
+
+[RESC_7:KENT1]
+Lass dich zusammenflicken, dann treffen wir uns auf der Brücke nach Star Island, ok?
+
+[RESC_8:KENT1]
+Ok, alles klar.
+
+[KPM1_1:KENT1]
+~g~Lance wird auf dem Schrottplatz gefangengehalten. Rette ihn!
+
+[KPM1_4:KENT1]
+~g~Bring Lance ins Krankenhaus!
+
+[M_PASSN:KENT1]
+MISSION ERFÜLLT!
+
+[KPM1_5:KENT1]
+~g~Diaz' Leute sind hinter euch her. Bring Lance ins Krankenhaus.
+
+{=================================== MISSION TABLE KICKSTT ===================================}
+
+[KICK1_2:KICKSTT]
+~r~Du warst nicht schnell genug bei der Maschine!
+
+[KICK1_7:KICKSTT]
+~r~Du hast die Maschine geschrottet!
+
+[KICK1_8:KICKSTT]
+~g~Setz dich auf das Motorrad!
+
+[KICK1_T:KICKSTT]
+BENÖTIGTE ZEIT:
+
+[KICKTM:KICKSTT]
+~b~ZEIT: ~1~:~1~
+
+[KICKTM2:KICKSTT]
+~b~ZEIT: ~1~:0~1~
+
+[GETBIKE:KICKSTT]
+~g~Du hast ~1~ Sekunden, um zu einer Geländemaschine zurückzukehren, bevor die Mission endet.
+
+[KICK1_1:KICKSTT]
+~g~Absolviere den Kurs so schnell wie möglich.
+
+[KICK1_6:KICKSTT]
+~g~Gut gemacht!
+
+[KICK_10:KICKSTT]
+~G~Nimm den Sanchez und absolviere den Kurs, indem du alle Checkpoints passierst.
+
+[KICK_12:KICKSTT]
+~r~Du hast es vermasselt!
+
+[KICK_13:KICKSTT]
+~r~Du hast zu lange gebraucht!
+
+[KICK_11:KICKSTT]
+~g~Um die Mission zu beenden, stell dich zu Fuß in die ~q~rosa Markierung~g~.
+
+{=================================== MISSION TABLE LAWYER1 ===================================}
+
+[LAW1_A:LAWYER1]
+Leg dich schlafen, sagt er -
+
+[LAW1_B:LAWYER1]
+- Ich sitz die ganze Nacht im Dunklen hier rum und trink Kaffee!
+
+[LAW1_C:LAWYER1]
+Das ist eine Katastrophe. Wir sind so gearscht, Mann!
+
+[LAW1_D:LAWYER1]
+Diese Gorillas, die kommen hier runter und reißen mir den Kopf ab. Es ist beinahe zum lachen!
+
+[LAW1_E:LAWYER1]
+Dafür habe ich NICHT Jura studiert. Ok, was sollen wir jetzt machen?
+
+[LAW1_F:LAWYER1]
+Sei still, setz dich hin und bleib ruhig. Ich sag dir, was wir machen.
+
+[LAW1_G:LAWYER1]
+Du findest raus, wer das Koks geklaut hat - und ich nehm ihn mir vor.
+
+[LAW1_H:LAWYER1]
+Gute Idee. SEHR gute Idee. Lass mich nachdenken, lass mich nachdenken.
+
+[LAW1_I:LAWYER1]
+OH! Da gibt es diesen Colonel a.D., Colonel Juan Garcia Cortez.
+
+[LAW1_J:LAWYER1]
+Der half mir, diesen Deal einzufädeln,
+
+[LAW1_K:LAWYER1]
+und zwar ohne Vice Citys Gangster-Establishment. Ok?
+
+[LAW1_L:LAWYER1]
+Pass auf, der gibt eine Party in der Bucht, auf seiner Luxusjacht
+
+[LAW1_M:LAWYER1]
+da kommt alles, was in Vice City Rang und Namen hat.
+
+[LAW1_N:LAWYER1]
+Ich hab natürlich eine Einladung, versteht sich,
+
+[LAW1_O:LAWYER1]
+aber mich kriegen keine zehn Pferde hier raus. Auf keinen Fall!
+
+[LAW1_P:LAWYER1]
+Halt die Klappe! Ich geh selbst hin...
+
+[LAW1_Q:LAWYER1]
+Moment! Hey, ich steh ja auch auf den 78er Look , aber das wird dort kein nostalgisches Saufgelage.
+
+[LAW1_R:LAWYER1]
+Ich meine, nichts gegen dich, aber mit den Klamotten wirst du dort ziemlich blöd angeschaut.
+
+[LAW1_S:LAWYER1]
+Wieso? Was ist mit meinen Sachen?
+
+[LAW1_T:LAWYER1]
+Pass auf. Fahr zu Rafael. Sag ihm, ich schicke dich, und er soll dich ordentlich einkleiden.
+
+[LAW1_U:LAWYER1]
+Ok, Los jetzt. Mach hinne...
+
+[LAWP_1:LAWYER1]
+Guten Abend.
+
+[LAWP_2:LAWYER1]
+Ich höre, Sie sind anstelle von Mr. Rosenberg hier.
+
+[LAWP_3:LAWYER1]
+Ich hoffe, gewisse Vorfälle haben seiner Gesundheit nicht geschadet,
+
+[LAWP_4:LAWYER1]
+oder seiner Psyche, Mr...äh?
+
+[LAWP_5:LAWYER1]
+Vercetti. Er leidet ein wenig an...Platzangst.
+
+[LAWP_6:LAWYER1]
+Ausgezeichnet, ausgezeichnet. Und Sie?
+
+[LAWP_7:LAWYER1]
+Ich will nur meine Ware.
+
+[LAWP_8:LAWYER1]
+Ah. Eine missliche Lage für alle Beteiligten.
+
+[LAWP_9:LAWYER1]
+Natürlich stelle ich selbst Nachforschungen an, aber
+
+[LAWP_10:LAWYER1]
+bei solch heiklen Sachen dauert das ein wenig.
+
+[LAWP_11:LAWYER1]
+Wir sprechen uns vielleicht später. Hm?
+
+[LAWP_12:LAWYER1]
+Inzwischen möchte ich Ihnen meine Tochter vorstellen,
+
+[LAWP_13:LAWYER1]
+Mercedes!
+
+[LAWP_14:LAWYER1]
+Könntest du dich um unseren Gast kümmern, während ich mich um andere Dinge
+
+[LAWP_15:LAWYER1]
+Natürlich, Daddy.
+
+[LAWP_16:LAWYER1]
+Entschuldigen Sie mich, bitte.
+
+[LAWP_17:LAWYER1]
+Mercedes!?
+
+[LAWP_18:LAWYER1]
+Leb du mal mit so 'nem Namen.
+
+[LAWP_19:LAWYER1]
+Na gut, ich zeig dir mal einige unserer bekannteren Gäste...
+
+[LAWP_20:LAWYER1]
+Das ist unser Abgeordneter Alex Shrub mit dem aufgehenden Sternchen Candy Suxx..
+
+[LAWP_21:LAWYER1]
+Und kennen Sie schon meine reizende Frau Laura? Nein?
+
+[LAWP_22:LAWYER1]
+Nun, leider ist sie in Alabama. Das hier ist Candy.
+
+[LAWP_23:LAWYER1]
+Und hier haben wir den Star-Verteidiger der Vice City Mambas, BJ.
+
+[LAWP_24:LAWYER1]
+Immer charmant.
+
+[LAWP_25:LAWYER1]
+Ich hab ihn voll geblockt. Der sitzt heute im Rollstuhl!
+
+[LAWP_26:LAWYER1]
+Haha, das ist gut!
+
+[LAWP_27:LAWYER1]
+Tja, ich bin an einem super Grundstück dran.
+
+[LAWP_28:LAWYER1]
+Und der Schleimbold dort ist Jezz Torrent,
+
+[LAWP_29:LAWYER1]
+Der Sänger von 'Love Fist'.
+
+[LAWP_30:LAWYER1]
+Wisst ihr, wie sie in Thailand Pingpong spielen?
+
+[LAWP_31:LAWYER1]
+Ich verrat's euch,
+
+[LAWP_32:LAWYER1]
+man spielt ohne Schläger, wenn ihr wisst, was ich meine!
+
+[LAWP_33:LAWYER1]
+Impotent.
+
+[LAWP_34:LAWYER1]
+Und das schwatzhafte Trio.
+
+[LAWP_35:LAWYER1]
+Diese schlafende Schweißfabrik ist Papas Obersklave, Gonzalez.
+
+[LAWP_36:LAWYER1]
+und die anderen beiden sind Pastor Richards
+
+[LAWP_37:LAWYER1]
+und der pseudo-intellektuelle Regisseur Steve Scott.
+
+[LAWP_38:LAWYER1]
+....leidenschaftlich mit den nymphomanischen Aliens
+
+[LAWP_39:LAWYER1]
+Da kommt der riesige Hai und
+
+[LAWP_40:LAWYER1]
+beißt ihnen ihr Ding ab!
+
+[LAWP_41:LAWYER1]
+Ha! So was hat doch die Welt noch nicht gesehen, oder?
+
+[LAWP_42:LAWYER1]
+Colonel!
+
+[LAWP_43:LAWYER1]
+Ihre Party ist wie immer fantastisch, hahahaha!
+
+[LAWP_44:LAWYER1]
+Ich entschuldige mich für die Verspätung.
+
+[LAWP_45:LAWYER1]
+Ah, nicht doch, Amigo. Wie geht es ihnen?
+
+[LAWP_46:LAWYER1]
+Unsere Geschäfte laufen schwierig - die Barbaren stehen vor den Toren.
+
+[LAWP_47:LAWYER1]
+Eine Zeit, Freunde zu belohnen und Feinde auszuschalten, Amigo.
+
+[LAWP_48:LAWYER1]
+Wer ist das Großmaul?
+
+[LAWP_49:LAWYER1]
+Ricardo Diaz. Er ist Mr. Koks.
+
+[LAWP_50:LAWYER1]
+Mercedes!
+
+[LAWP_51:LAWYER1]
+Oh, ich will gerade meinen Freund in die Stadt bringen.
+
+[LAWP_52:LAWYER1]
+Ein andermal, Ricardo!
+
+[LAWP_53:LAWYER1]
+Lass uns verschwinden.
+
+[LAWP_54:LAWYER1]
+Fahr mich zum Pole Position Club.
+
+[LAW1_2:LAWYER1]
+~g~Begib dich zur Jacht des Colonels.
+
+[LAW1_4:LAWYER1]
+~r~Du hast die Tochter des Colonels erledigt!
+
+[LAW1_5:LAWYER1]
+Wirst du für meinen Vater arbeiten?
+
+[LAW1_6:LAWYER1]
+Vielleicht.
+
+[LAW1_7:LAWYER1]
+Darf ich meine Hand in deinen Schoß legen?
+
+[LAW1_8:LAWYER1]
+Vielleicht...
+
+[LAW1_9:LAWYER1]
+Es ist schwer, einen so reichen, mächtigen Vater zu haben. Los.
+
+[LAW1_10:LAWYER1]
+Wir sehen uns, mein Hübscher!
+
+[LAW1_11:LAWYER1]
+Ganz bestimmt.
+
+[LAW1_12:LAWYER1]
+Hmm, netter Ofen.
+
+[LAW1_13:LAWYER1]
+Nein! Mein Motorrad!
+
+[LAW1_3:LAWYER1]
+~g~Bring die Tochter des Colonels zum Pole Position Club.
+
+[HELP20:LAWYER1]
+Folge dem ~h~T-shirt-Symbol~w~ auf dem Radar, um Rafael's zu finden.
+
+[LAW1_14:LAWYER1]
+Wow, das ist ja wirklich ein tolles Motorrad.
+
+[LAW1_15:LAWYER1]
+Ja, Baby, hab ich mir gerade bei Howlin' Pete's besorgt.
+
+{=================================== MISSION TABLE LAWYER2 ===================================}
+
+[LAW2_A:LAWYER2]
+Ah! Tja, ich hoffe, du amüsierst dich gut, während ich hier vor Angst halb umkomme. Was hast du rausgefunden?
+
+[LAW2_B:LAWYER2]
+Dass es in dieser Stadt mehr Gangster gibt als im Knast. Wir brauchen einen Tipp von der Straße...
+
+[LAW2_C:LAWYER2]
+Ok, lass mich nachdenken, lass mich nachdenken -
+
+[LAW2_D:LAWYER2]
+- AH! Ich hab's!
+
+[LAW2_E:LAWYER2]
+Ok, es gibt da so 'n Engländer, so 'n Idiot aus der Musikbranche.
+
+[LAW2_F:LAWYER2]
+Er nennt sich Kent Paul.
+
+[LAW2_G:LAWYER2]
+Und der ist in all den Kreisen von Vice City richtig dick drin.
+
+[LAW2_H:LAWYER2]
+Wenn einer weiß, wo 20 Kilo Koks abgeblieben sind,
+
+[LAW2_I:LAWYER2]
+dann dieser Typ. Er ist immer im Malibu.
+
+[LAW2_J:LAWYER2]
+Ich seh ihn mir mal an.
+
+[LAW2B_A:LAWYER2]
+Wo kommst du denn her?
+
+[LAW2B_B:LAWYER2]
+Nach einer wie dir suche ich schon seit Ewigkeiten.
+
+[LAW2B_C:LAWYER2]
+Kent Paul. Ja, ich bin hier die Nummer Eins.
+
+[LAW2B_D:LAWYER2]
+Ich suche einen Engländer...
+
+[LAW2B_E:LAWYER2]
+Ich ziehe hier die Strippen, verstehst du?
+
+[LAW2B_F:LAWYER2]
+Ich lade dich ein. Ich kann dir alles besorgen, Süße.
+
+[LAW2B_G:LAWYER2]
+Mach dir keine Gedanken.
+
+[LAW2B_H:LAWYER2]
+Verzieh dich, Schätzchen.
+
+[LAW2B_I:LAWYER2]
+Oi oi oi oi!
+
+[LAW2B_J:LAWYER2]
+Bist du Kent Paul? Ich bin ein Freund von Rosenberg...
+
+[LAW2B_K:LAWYER2]
+Rosenberg...Rosenberg... Ach, dieser abgedrehte Winkeladvokat!
+
+[LAW2B_L:LAWYER2]
+Der bringt noch den Unschuldigsten auf den elektrischen Stuhl!
+
+[LAW2B_M:LAWYER2]
+Mach uns noch 'nen Drink, mein Freund.
+
+[LAW2B_N:LAWYER2]
+Bist ein echter Komiker.
+
+[LAW2B_O:LAWYER2]
+Hör zu, ich vermisse 20 Kilo und einen Haufen Geld...
+
+[LAW2B_P:LAWYER2]
+Drogen? Das ist doch Schwachsinn.
+
+[LAW2B_Q:LAWYER2]
+Was weißt du darüber?
+
+[LAW2B_R:LAWYER2]
+Oi, oi! Gerade wollte ich's sagen...
+
+[LAW2B_S:LAWYER2]
+Es gibt da einen Koch, der verdealt Koks in der Küche eines Hotels am Ocean Drive.
+
+[LAW2B_T:LAWYER2]
+Macht einen ziemlich zufriedenen Eindruck in letzter Zeit. Solltest du mal auschecken.
+
+[LAW2B_U:LAWYER2]
+Mach ich. Und wir sehen uns.
+
+[LAW2B_V:LAWYER2]
+Ja, ja. Nur zu. Hau bloß ab, du Stinktier. Dir polier ich noch die Visage!
+
+[LAW2B_W:LAWYER2]
+Gib mir 'nen Drink. Und wo ist die Puppe?
+
+[LAW2C_A:LAWYER2]
+Oh, sehr gut, Rambo, schlag ihn ruhig zu Brei. Dann redet er ganz bestimmt.
+
+[LAW2C_B:LAWYER2]
+Willst du auch ein paar?
+
+[LAW2C_C:LAWYER2]
+Hey, ruhig. Ich will das gleiche wie du, Bruder.
+
+[LAW2C_D:LAWYER2]
+Ach ja? Und das wäre?
+
+[LAW2C_E:LAWYER2]
+Deine Kohle und den Stoff meines toten Bruders. Aber du hast gerade unsere Spur erledigt.
+
+[LAW2C_F:LAWYER2]
+Dumm gelaufen. Verzieh dich.
+
+[LAW2C_G:LAWYER2]
+Hey, hey! Kein Grund, hier den dicken Mann zu spielen.
+
+[LAW2C_H:LAWYER2]
+Sieh mal: Wir sind zwei Hombres in 'ner fremden Stadt. Wir sollten uns gegenseitig helfen.
+
+[LAW2C_I:LAWYER2]
+Ich helf mir selbst, Bruder.
+
+[LAW2C_J:LAWYER2]
+Bist du dir sicher? Hier nimm das.
+
+[LAW2C_K:LAWYER2]
+Komm mit!
+
+[LAW2_1:LAWYER2]
+Was glotzt du denn so?
+
+[LAW2_2:LAWYER2]
+Rede endlich...
+
+[LAW2_3:LAWYER2]
+Zwing mich doch dazu, du Pfeife!
+
+[LAW2_4:LAWYER2]
+Mir nach!
+
+[LAW2_5:LAWYER2]
+Ich seh zu, was ich rausfinde. Ich behalte dich im Auge, Tommy.
+
+[LAW2_6:LAWYER2]
+~g~Begib dich zum Malibu Club und suche Kent Paul.
+
+[LAW2_7:LAWYER2]
+~g~Suche den Küchenchef auf dem Ocean Drive.
+
+[LAW2_10:LAWYER2]
+~g~Fahre zurück zum Hotel.
+
+[LAW2_11:LAWYER2]
+~g~Nimm sein Handy.
+
+[LAW2_12:LAWYER2]
+Du hast jetzt ein Handy und kannst Telefongespräche entgegennehmen!
+
+[LAW2_13:LAWYER2]
+~g~Du hast Lance zurückgelassen! Geh ihn holen!
+
+[LAW2_14:LAWYER2]
+Verdammt, nichts wie weg hier!
+
+[GUN_2A:LAWYER2]
+Halte die ~h~~k~~PED_LOCK_TARGET~ ~w~gedrückt, um ~h~automatisch zu zielen~w~. Drücke die ~h~~k~~PED_FIREWEAPON~~w~, um zu ~h~feuern!
+
+[GUN_2C:LAWYER2]
+Halte die ~h~~k~~PED_LOCK_TARGET~ ~w~gedrückt, um ~h~automatisch zu zielen~w~. Drücke die ~h~~k~~PED_FIREWEAPON~~w~, um zu ~h~feuern!
+
+[GUN_2D:LAWYER2]
+Halte die ~h~~k~~PED_LOCK_TARGET~ ~w~gedrückt, um ~h~automatisch zu zielen~w~. Drücke die ~h~~k~~PED_FIREWEAPON~~w~, um zu ~h~feuern!
+
+[HELP17:LAWYER2]
+Drücke die ~h~~k~~PED_FIREWEAPON~~w~, um den Küchenchef anzugreifen.
+
+[HELP18:LAWYER2]
+Drücke die~h~ ~k~~PED_FIREWEAPON~~w~, um den Küchenchef anzugreifen.
+
+[LAW3_11:LAWYER2]
+Stell dich in die ~q~rosa Markierung~w~, um zu sehen, was im Angebot ist.
+
+[LAW3_12:LAWYER2]
+Du kannst Waffen auswählen, indem du die ~h~linke~w~ oder ~h~rechte~w~ ~h~Richtungstaste drückst.
+
+[LAW3_13:LAWYER2]
+Wenn du genug Geld hast, kannst du Waffen durch Drücken der ~h~~k~~PED_SPRINT~~w~ kaufen.
+
+[LAW3_14:LAWYER2]
+Um zu gehen, drücke die ~h~~k~~VEHICLE_ENTER_EXIT~
+
+[LAW3_15:LAWYER2]
+Folge dem ~h~Pistolensymbol~w~ auf dem Radar, so kommst du zu AmmuNation.
+
+[LAW2_15:LAWYER2]
+~g~Begib dich zu AmmuNation.
+
+[LAW2_K:LAWYER2]
+Nur die Ruhe.
+
+[LAW2_16:LAWYER2]
+Eins musst du wissen: In dieser Stadt darfst du nie unbewaffnet sein.
+
+[LAW2_17:LAWYER2]
+Komm, der nächste Waffenladen ist ein paar Blocks von hier.
+
+[LAW2_18:LAWYER2]
+Tommy, jeder Mann braucht ab und zu mal ein bisschen Entspannung.
+
+[LAW2_19:LAWYER2]
+Das ist die Pole Position Stripper-Bar. Solltest du bei Gelegenheit mal reinschauen.
+
+{=================================== MISSION TABLE LAWYER3 ===================================}
+
+[_A:LAWYER3]
+Arrgh! Ach, du lieber Gott! Du! Meine Güte, ich brauch 'ne neue Hose!
+
+[LAW3_B:LAWYER3]
+Hey, diese Psychos aus dem Norden haben angerufen. Sie kommen bald hier runter.
+
+[LAW3_C:LAWYER3]
+Also, wo ist das verdammte Geld?
+
+[LAW3_D:LAWYER3]
+Ganz ruhig. Soweit sind wir noch nicht.
+
+[LAW3_E:LAWYER3]
+Ich hab wirklich gedacht, du erledigst das.
+
+[LAW3_F:LAWYER3]
+Und jetzt sagen diese Gauner, wir sollen ihnen einen Gefallen tun.
+
+[LAW3_G:LAWYER3]
+Du meinst, ICH soll ihnen einen Gefallen tun.
+
+[LAW3_H:LAWYER3]
+Du sagst es. Sehe ich aus, als könnte ich Geschworene einschüchtern?
+
+[LAW3_I:LAWYER3]
+Ich kann nicht mal ein Kind einschüchtern. Ich hab's versucht.
+
+[LAW3_J:LAWYER3]
+Hör zu, wenn du kneifst, kriegt Forellis Cousin Georgio 5 Jahre wegen Betrugs.
+
+[LAW3_K:LAWYER3]
+Du musst diese Typen ausschalten.
+
+[LAW3_L:LAWYER3]
+Verstehe. Den Geschworenen helfen 'umzudenken'. Kein Problem.
+
+[LAW3_M:LAWYER3]
+Nein, nein, nein! Das hab ich schon versucht. Das ist nicht gelaufen,
+
+[LAW3_N:LAWYER3]
+ZWING sie dazu, umzudenken.
+
+[LAW3_1:LAWYER3]
+Georgio lässt grüßen.
+
+[LAW3_2:LAWYER3]
+Denk dran, 'Schuldig' ist ein hässliches Wort.
+
+[LAW3_3:LAWYER3]
+'Unschuldig', bis ich was anderes sage.
+
+[LAW3_4:LAWYER3]
+Er ist nicht schuldig.
+
+[LAW3_5:LAWYER3]
+Du kennst Georgio? Merk dir: Er ist nicht schuldig.
+
+[LAW3_6:LAWYER3]
+Nicht schuldig. Verstanden...gut.
+
+[LAW3_8:LAWYER3]
+~r~Du hast einen Geschworenen erledigt!
+
+[LAW3_9:LAWYER3]
+~g~Schrotte das Auto des Geschworenen, damit er aussteigt!
+
+[HELP40:LAWYER3]
+Du kannst Autos mit dem Hammer oder einer ähnlichen Waffe zertrümmern.
+
+[HELP41:LAWYER3]
+Oder du kannst sie mit einem Fahrzeug rammen.
+
+[LAW3_10:LAWYER3]
+~g~Eine Nahkampfwaffe kannst du im ~h~Eisenwarenladen~g~ kaufen.
+
+[LAW3_20:LAWYER3]
+~g~Schrotte das Auto des Geschworenen!
+
+[LAW3_21:LAWYER3]
+Das kann doch wohl nicht wahr sein!
+
+[LAW3_22:LAWYER3]
+Unglaublich!
+
+[LAW3_23:LAWYER3]
+Ok! Ok! Ich hab kapiert!
+
+[LAW3_24:LAWYER3]
+~g~Dieser Hammer wäre nützlich.
+
+[LAW3_7:LAWYER3]
+~g~Schüchtere die 2 Geschworenen ein, aber erledige sie NICHT!
+
+[HELP23:LAWYER3]
+Folge dem ~h~Hammer-Symbol~w~ auf dem Radar, wenn du beim Eisenwarenladen Nahkampfwaffen kaufen willst.
+
+[LAW3_16:LAWYER3]
+Dämlicher Florida-Idiot!
+
+[LAW3_17:LAWYER3]
+Aus dem Weg!
+
+{=================================== MISSION TABLE LAWYER4 ===================================}
+
+[LAW4_A:LAWYER4]
+Avery, es versteht sich von selbst... Tommy! Tommy! Fortschritte gemacht? Nein, erzähl's mir später.
+
+[LAW4_B:LAWYER4]
+Tommy, das ist Avery Carrington. Kennt ihr euch nicht von der Party?
+
+[LAW4_C:LAWYER4]
+Nicht persönlich.
+
+[LAW4_D:LAWYER4]
+Tagchen.
+
+[LAW4_E:LAWYER4]
+Avery hat einen Vorschlag für uns.
+
+[LAW4_F:LAWYER4]
+Haben wir nicht was besseres zu tun?
+
+[LAW4_G:LAWYER4]
+Ich versuch hier, unseren Hals zu retten. Also würdest du mich bitte ausreden lassen?
+
+[LAW4_H:LAWYER4]
+Ich hab Angst. Aber wenn ich schon Ende der Woche sterbe, möchte ich wenigstens nicht arm sterben.
+
+[LAW4_I:LAWYER4]
+Jetzt beruhigt euch, ihr beiden.
+
+[LAW4_J:LAWYER4]
+Junge, wenn du mir hilfst, sorge ich dafür, dass jeder, der dir Ärger macht, unter die Erde kommt.
+
+[LAW4_K:LAWYER4]
+Ok, was kann ich für Sie tun?
+
+[LAW4_L:LAWYER4]
+Eine Spedition hat ihr Lager auf einem Top-Grundstück - und will nicht verkaufen.
+
+[LAW4_M:LAWYER4]
+Die sitzen da drauf wie die Ratten in ihren Löchern. Also müssen wir dieses Ungeziefer ausräuchern.
+
+[LAW4_N:LAWYER4]
+Fahr hin und stich ein wenig ins Wespennest.
+
+[LAW4_O:LAWYER4]
+Das wird die Security beschäftigen. Dann schleichst du dich rein und machst den Laden platt.
+
+[LAW4_P:LAWYER4]
+Und du könntest dich bei Rafael's neu einkleiden. Kann 'ne Weile dauern, aber mach das ruhig mal.
+
+[LAW4_Q:LAWYER4]
+Das gibt ein Fest.
+
+[LAW4_R:LAWYER4]
+Wenn alles läuft wie geplant, komm mal zu mir ins Büro...
+
+[LAW4_1:LAWYER4]
+Bitte, geht auseinander! Die Geschäftsleitung wird sich aller Probleme annehmen!
+
+[LAW4_2:LAWYER4]
+Bitte, geht auseinander! Geht wieder nach Hause!
+
+[LAW4_3:LAWYER4]
+Bitte, geht auseinander! Das ist nicht akzeptabel!
+
+[LAW4_4:LAWYER4]
+Bitte, geht auseinander! Ihr landet alle auf der Straße!
+
+[LAW4_5:LAWYER4]
+Die Knüppel raus, Jungs! Diesen Kommis zeigten wir's!
+
+[LAW4_13:LAWYER4]
+Fange mit mind. 4 Arbeitern Streit an, um einen Aufruhr zu starten.
+
+[LAW4_14:LAWYER4]
+~g~Zerstöre die Transporter auf dem Gelände!
+
+[HELP38:LAWYER4]
+Wenn du jemanden ausschaltest, der eine Waffe trägt, lässt er sie fallen.
+
+[HELP39:LAWYER4]
+Du kannst explosive Fässer anvisieren und abschießen, aber bleib auf Distanz.
+
+{=================================== MISSION TABLE MIAMI_1 ===================================}
+
+[T4X4_1A:MIAMI_1]
+~g~Du hast ~1~ Sekunden, um ~y~24~g~ Checkpoints abzufahren. ~g~Die ~y~REIHENFOLGE IST BELIEBIG.
+
+[T4X4_1B:MIAMI_1]
+~y~PASSIERE~g~ den ersten Checkpoint, dann läuft die ~r~STOPPUHR.
+
+[T4X4_1C:MIAMI_1]
+~1~ von 24!
+
+[GETBIK1:MIAMI_1]
+Du hast ~1~ Sekunden, um auf eine PCJ 600 zu steigen!
+
+[GETBIK3:MIAMI_1]
+~r~Du brauchst eine PCJ 600, um diese Mission durchzuführen!
+
+{=================================== MISSION TABLE MM ===================================}
+
+[BLOD_04:MM]
+ZUSTAND AUTO:
+
+[BLOD_05:MM]
+~g~ZIELZEIT: ~1~ Minute
+
+[BLOD_06:MM]
+~g~ZIELZEIT: ~1~ Minuten
+
+[BLOD_07:MM]
+NEUE Bestzeit: ~1~ Sekunden
+
+[BLOD_08:MM]
+Zerstörte Autos: ~1~
+
+[BLOD_09:MM]
+$~1~
+
+[BLOD_10:MM]
+SIEGER!!
+
+[BLOD_01:MM]
+Fahr durch die Checkpoints, um deine Gesamtzeit zu verlängern.
+
+[BLOD_02:MM]
+Wenn die Gesamtzeit abgelaufen ist, hast du versagt.
+
+[BLOD_03:MM]
+Um zu gewinnen, muss deine Gesamtzeit die Zielzeit überschreiten!
+
+{=================================== MISSION TABLE OVALRIG ===================================}
+
+[HOTR_01:OVALRIG]
+~g~Das Rennen geht über 12 Runden. Nur die ersten drei Plätze qualifizeren für einen Gewinn.
+
+[HOTR_02:OVALRIG]
+~g~Wird dein Auto zerstört, wirst du disqualifiziert.
+
+[HOTR_03:OVALRIG]
+~g~Wird dein Auto beschädigt, kannst du es an der Box reparieren lassen.
+
+[HOTR_04:OVALRIG]
+~g~Da geht es aus dem Stadion raus.
+
+[HOTR_05:OVALRIG]
+Zustand Auto:
+
+[HOTR_06:OVALRIG]
+Runden:
+
+[HOTR_07:OVALRIG]
+Neue Bestzeit: ~1~:0~1~
+
+[HOTR_08:OVALRIG]
+Zeit: ~1~:~1~
+
+[HOTR_10:OVALRIG]
+Absolvierte Zeit:
+
+[HOTR_09:OVALRIG]
+Position:
+
+[HOTR_12:OVALRIG]
+~r~Dein Fahrzeug ist zerstört worden!
+
+[HOTR_13:OVALRIG]
+~r~Du hast das Rennen nicht gewonnen!
+
+[HOTR_14:OVALRIG]
+~r~Du bist disqualifiziert worden!
+
+[HOTR_15:OVALRIG]
+Zeit: ~1~:~1~
+
+[HOTR_16:OVALRIG]
+Zeit: ~1~:0~1~
+
+[HOTR_17:OVALRIG]
+Bestzeit: ~1~:~1~
+
+[HOTR_18:OVALRIG]
+Bestzeit: ~1~:0~1~
+
+[HOTR_19:OVALRIG]
+Bestzeit: Nicht verfügbar
+
+[HOTR_20:OVALRIG]
+Neue Bestzeit: ~1~:~1~
+
+[HOTR_21:OVALRIG]
+Neue Bestzeit: ~1~:0~1~
+
+[HOTR_22:OVALRIG]
+Beste Platzierung: Nicht verfügbar
+
+[HOTR_23:OVALRIG]
+Beste Platzierung: 1.
+
+[HOTR_24:OVALRIG]
+Beste Platzierung: 2.
+
+[HOTR_25:OVALRIG]
+Beste Platzierung: 3.
+
+[HOTR_26:OVALRIG]
+Beste Platzierung: ~1~.
+
+[HOTR_27:OVALRIG]
+Beste Rundenzeit: ~1~.~1~ Sekunden
+
+[HOTR_28:OVALRIG]
+Beste Rundenzeit: ~1~.0~1~ Sekunden
+
+[HOTR_29:OVALRIG]
+$~1~
+
+[HOTR_30:OVALRIG]
+1. PLATZ
+
+[HOTR_31:OVALRIG]
+2. PLATZ
+
+[HOTR_32:OVALRIG]
+3. PLATZ
+
+[HOTR_33:OVALRIG]
+Beste Rundenzeit: Nicht verfügbar
+
+[HOTR_11:OVALRIG]
+Neue beste Rundenzeit: ~1~.~1~ Sekunden
+
+[HOTR_34:OVALRIG]
+Neue beste Rundenzeit: ~1~.0~1~ Sekunden
+
+{=================================== MISSION TABLE PHIL1 ===================================}
+
+[PHI1_HP:PHIL1]
+Wenn du Granaten mit Fernzünder benutzt, wirf die Granate, dann löse die Explosion zu einem beliebigen Zeitpunkt aus.
+
+[PHIL1_A:PHIL1]
+Phil?
+
+[PHIL1_B:PHIL1]
+SCHNELL WEG!
+
+[PHIL1_C:PHIL1]
+Schnell weg!
+
+[PHIL1_E:PHIL1]
+Scheiße, Phil, das Zeug trinkst du?
+
+[PHIL1_F:PHIL1]
+Hey, du musst es nicht trinken.
+
+[PHIL1_G:PHIL1]
+Das haut schon rein, wenn du nur dran riechst.
+
+[PHIL1_H:PHIL1]
+Hör mal, Phil, du sagtest, du könntest mir Artillerie besorgen...
+
+[PHIL1_I:PHIL1]
+Klar.
+
+[PHIL1_J:PHIL1]
+In letzter Zeit macht mir ein mexikanischer Waffenschieber Konkurrenz.
+
+[PHIL1_K:PHIL1]
+Der müsste jetzt gerade auf seiner wöchentlichen Runde sein.
+
+[PHIL1_L:PHIL1]
+Ramm mit deiner Karre die Ware von seinem Wagen runter, bevor er wieder abtaucht.
+
+[PHIL1_M:PHIL1]
+Tust mir einen großen Gefallen damit.
+
+[PHIL1_N:PHIL1]
+Und dann mach ihn fertig.
+
+[PHI1_01:PHIL1]
+~g~Ramme die Waffen von der Ladefläche des Waffenschiebers.
+
+[PHI1_02:PHIL1]
+~g~Der Waffenhändler hat die Ladung verloren. Schlag die Kiste kaputt und nimm die Waffe.
+
+[PHI1_03:PHIL1]
+~g~Sie haben anscheinend Verstärkung gerufen.
+
+[PHI1_04:PHIL1]
+~g~Jetzt erledige die restlichen Waffenschieber.
+
+[PHI1_06:PHIL1]
+Pass doch auf, wo du hinfährst!
+
+[PHI1_07:PHIL1]
+Hey!
+
+[PHIL1_O:PHIL1]
+Huuuuhuuu!
+
+[PHIL1_D:PHIL1]
+Komm nie mit 'ner offenen Flamme in die Nähe von Phil Cassidys TNT-Whiskey!
+
+{=================================== MISSION TABLE PHIL2 ===================================}
+
+[PHIL2_A:PHIL2]
+Hey, Phil, wie geht's?
+
+[PHIL2_B:PHIL2]
+Hey, Tommy. Alles klar? Lange nicht gesehen...
+
+[PHIL2_C:PHIL2]
+Du solltest wirklich die Finger von dem TNT-Whiskey lassen.
+
+[PHIL2_D:PHIL2]
+Das Zeug riecht ja wie Terpentin. Mir brennen schon die Augen.
+
+[PHIL2_E:PHIL2]
+Lass stecken, Tommy.
+
+[PHIL2_F:PHIL2]
+Komm hier rüber, ich will dir nämlich was zeigen.
+
+[PHIL2_G:PHIL2]
+Wahnsinn! Das rieche ich ja schon von hier. Mir ist schon ganz schwindlig.
+
+[PHIL2_H:PHIL2]
+Kümmer dich nicht um den Geruch. Tommy, sieh dir das an.
+
+[PHIL2_I:PHIL2]
+Billige Schrottbatterien. Da auf der Bank sind noch welche.
+
+[PHIL2_J:PHIL2]
+Tata!
+
+[PHIL2_K:PHIL2]
+Oh, verflucht!
+
+[PHI2_01:PHIL2]
+~g~Schnell, bring Phil ins Krankenhaus.
+
+[PHI2_03:PHIL2]
+~r~Phil Cassidy ist tot!!! Wer soll Liberty nun mit Waffen versorgen?
+
+[PHI2_05:PHIL2]
+Nicht ins Krankenhaus, Mann! Zu viele Cops und Vietcong!
+
+[PHI2_06:PHIL2]
+Ich kenn 'nen Ex-Army-Arzt, der schuldet mir einen Gefallen und 'nen Rasenmäher.
+
+[PHI2_07:PHIL2]
+Er hat 'ne Praxis unten in Little Havana. Uh, guck mal, ein Riesenfisch.
+
+[PHI2_08:PHIL2]
+Achtung! Da in den Bäumen - Vietcong!
+
+[PHI2_09:PHIL2]
+Spinn ich, oder ist die Straße aus Gummi?
+
+[PHI2_10:PHIL2]
+Broken Spoon an Mother Hen, bitte kommen!
+
+[PHI2_11:PHIL2]
+Spooney Wooney Woo Woo Woooo!
+
+[PHI2_12:PHIL2]
+Er kommt mich holen, Jungchen!
+
+[PHI2_13:PHIL2]
+Schwarze Schwingen breiten sich über mir aus...
+
+[PHI2_14:PHIL2]
+Es ist wunderschön, Mann. Wunderschön... mir ist nur so kalt...
+
+[PHI2_15:PHIL2]
+Roger! Wir haben einen betrunkenen Fahrer.
+
+[PHI2_04:PHIL2]
+Phils Gesundheitszustand:
+
+[PHI_AS1:PHIL2]
+PHIL-MISSIONEN ERFÜLLT
+
+[PHI_AS2:PHIL2]
+~g~Bei Phil gibt es neue Waffen zu kaufen.
+
+{=================================== MISSION TABLE PIZZA ===================================}
+
+[PIZ1_01:PIZZA]
+~g~Liefere diese Pizzas aus. Du musst den Kunden die Pizzas zuwerfen, während du an ihnen vorbeifährst.
+
+[PIZ1_02:PIZZA]
+~g~Du hast alle Pizzas zugestellt. Fahr zurück und hole noch mehr.
+
+[PIZ1_05:PIZZA]
+~g~Du hast 5 Minuten, um die Pizzas zu liefern, sonst rufen die Kunden einen anderen Pizza-Service an.
+
+[PIZ1_07:PIZZA]
+~r~Du hast den Kunden erledigt! Du bist gefeuert.
+
+[PIZ1_08:PIZZA]
+~r~Die Zeit ist um. Du bist gefeuert.
+
+[PIZ1_09:PIZZA]
+~r~Du hast dein Motorrad geschrottet! Du bist gefeuert.
+
+[PIZ1_11:PIZZA]
+Hey! Steig wieder aufs Motorrad!
+
+[PIZ1_12:PIZZA]
+Verbleibende Pizzas:
+
+[PIZ1_06:PIZZA]
+Drücke die ~h~ R3-Taste~w~, wenn du auf einem Bike sitzt und die Mission abbrechen willst.
+
+[PIZ1_13:PIZZA]
+Liefere sie schön heiß ab.
+
+[PIZ1_14:PIZZA]
+Kumpel, Pizzas für dich.
+
+[PIZ1_15:PIZZA]
+Hey, na los, Mister, liefere sie schnell aus.
+
+[PIZ1_16:PIZZA]
+Worauf wartest du, Mister? Du sollst Pizzas liefern.
+
+[PIZ1_17:PIZZA]
+Ich weiß, du wolltest kein Pizza-Lieferant sein. Na ja, mir egal.
+
+[PIZ1_18:PIZZA]
+Liefere die aus.
+
+[PIZ1_19:PIZZA]
+Die müssen ausgeliefert werden.
+
+[PIZ1_20:PIZZA]
+Na los, Mister, liefere die Dinger aus, oder du fliegst.
+
+[PIZ1_21:PIZZA]
+Die Leute warten, Kumpel.
+
+[PIZ1_22:PIZZA]
+Wartest du auf bessere Zeiten? Die müssen ausgeliefert werden!
+
+[PIZ1_23:PIZZA]
+Liefer den verdammten Fraß aus, Mister.
+
+[PIZ1_24:PIZZA]
+Die müssen ausgeliefert werden, Kumpel.
+
+[PIZ1_25:PIZZA]
+Mann, kannst du die übernehmen?
+
+[PIZ1_26:PIZZA]
+Mister, liefere die Dinger schnell ab, hopp, Amigo.
+
+[PIZ1_27:PIZZA]
+Komm schon, wir sind unter Druck, liefere die Dinger aus.
+
+[PIZ1_28:PIZZA]
+Du schon wieder? Liefere die hier schnell aus, Kumpel.
+
+[PIZ1_29:PIZZA]
+Keine Trödelei diesmal, Kumpel.
+
+[PIZ1_30:PIZZA]
+Na los, du fauler Hund, liefere den Fraß rechtzeitig aus.
+
+[PIZ1_31:PIZZA]
+Du wirst nie befördert, wenn du diesmal nicht schneller machst.
+
+[PIZ1_32:PIZZA]
+~r~Ist dir die Pizza zu heiß?
+
+[PIZ1_33:PIZZA]
+~g~Kehre zum Restaurant zurück, um weitere Aufträge zu bekommen.
+
+[PIZ1_34:PIZZA]
+~g~Pizza geliefert, hier ist dein Geld.
+
+[PIZ_WON:PIZZA]
+Pizza-Mission abgeschlossen. Deine max. Gesundheit erhöht sich auf 150
+
+{=================================== MISSION TABLE PORN1 ===================================}
+
+[POR1_15:PORN1]
+Hey, Tommy, kommst du auf eine Aufwärmrunde mit rein!?
+
+[POR1_14:PORN1]
+Du bist engagiert!
+
+[POR1_A:PORN1]
+Action!
+
+[POR1_B:PORN1]
+Wow! Der ist aber groß!
+
+[POR1_C:PORN1]
+30cm, das ist Vorschrift, Baby.
+
+[POR1_D:PORN1]
+SCHNITT! Wer ist dieser Idiot? Du da! Was machst du in meinem Studio? Was willst du?
+
+[POR1_E:PORN1]
+Was soll das alles hier?
+
+[POR1_F:PORN1]
+Aliens? Angelruten?
+
+[POR1_G:PORN1]
+Wer hat jemals einen so großen Hai gesehen?
+
+[POR1_H:PORN1]
+Das muss alles raus hier.
+
+[POR1_I:PORN1]
+Wieso bist du in diese Branche gegangen, du Idiot?
+
+[POR1_J:PORN1]
+Hah?
+
+[POR1_K:PORN1]
+Wegen der Pussys, deswegen. Was ist das??
+
+[POR1_L:PORN1]
+Das ist meine Kunst- SICHERHEITSDIENST!
+
+[POR1_M:PORN1]
+Hör zu, du aufgeblasener Penner, du gehörst jetzt mir. Mir gehört das alles hier.
+
+[POR1_N:PORN1]
+Wir krempeln den Laden hier um.
+
+[POR1_O:PORN1]
+Ich mache dich reich.
+
+[POR1_P:PORN1]
+Äh, du...du bist Tommy Vercetti? Aber ich dachte, du wärst...
+
+[POR1_Q:PORN1]
+Ganz recht.
+
+[POR1_R:PORN1]
+Wir ändern hier ein paar Dinge und dann machen wir richtig Kohle.
+
+[POR1_S:PORN1]
+Hast du dir schon mal überlegt...
+
+[POR1_T:PORN1]
+Aber zuerst brauchen wir mal ein paar hübsche Mädels hier.
+
+[POR1_U:PORN1]
+Ja, Girls sind ok, aber du...wow!
+
+[POR1_02:PORN1]
+~g~Schalte Candys Agent aus, dann komm wieder und hole Candy.
+
+[POR1_04:PORN1]
+Hey, Candy. Ich suche Filmtalente. Interessiert?
+
+[POR1_05:PORN1]
+Klar! Aber da musst du mit meinem Agenten reden.
+
+[POR1_06:PORN1]
+Was zum Teufel soll das?
+
+[POR1_07:PORN1]
+Du hättest heute zu Hause bleiben sollen!
+
+[POR1_7B:PORN1]
+Was sagt man zu so 'nem Arschloch?
+
+[POR1_08:PORN1]
+Hey, Mercedes!
+
+[POR1_09:PORN1]
+Hi, Tommy. Na, ein bisschen feiern?
+
+[POR1_10:PORN1]
+Jetzt nicht, Süße. Bist du an Filmaufnahmen interessiert?
+
+[POR1_11:PORN1]
+Klar. Wenn's schön billig und dreckig ist.
+
+[POR1_13:PORN1]
+~g~Bring die Girls ins Studio zu Steve.
+
+[POR1_17:PORN1]
+Wow, cooler Hai!
+
+[POR1_18:PORN1]
+~r~Mercedes ist erledigt!
+
+[POR1_20:PORN1]
+Tommy, wo willst du hin? Komm zurück!
+
+[POR1_21:PORN1]
+Wo willst du hin?
+
+[POR1_22:PORN1]
+Tommy, wann sehen wir uns mal ganz allein, nur du und ich?
+
+[POR1_01:PORN1]
+~g~Candy Suxxx wäre perfekt für die Hauptrolle!
+
+[POR1_12:PORN1]
+~g~Nimm Candy mit zu deinem Treffen mit Mercedes.
+
+[POR1_16:PORN1]
+Vielleicht später, Schätzchen...
+
+[POR1_24:PORN1]
+~g~Geh zurück und hole Candy.
+
+[POR1_25:PORN1]
+~g~Du hast Candy vergessen. Geh sie holen.
+
+[POR1_23:PORN1]
+~g~Candy wird sich um das Geschäft in ~h~Downtown~g~ kümmern.
+
+[POR1_26:PORN1]
+~g~Da ist Candy. Sie scheint wieder mit dem Kongressabgeordneten Shrub zusammen gewesen zu sein.
+
+[POR1_27:PORN1]
+Los, gehen wir.
+
+[POR1_28:PORN1]
+Tommy, sei vorsichtig! Meine Implantate sind noch nicht versichert!
+
+[POR1_29:PORN1]
+Das nennst du fahren?
+
+[POR1_30:PORN1]
+Danach kann ich keinen Porno mehr machen!
+
+[POR1_31:PORN1]
+Was ist los? Willst du mich umbringen? Ich dachte, ich wäre der Star!
+
+{=================================== MISSION TABLE PORN2 ===================================}
+
+[POR2_A:PORN2]
+Was macht die Filmerei, Steve?
+
+[POR2_B:PORN2]
+Tja, Candy ist ein Naturtalent, und die Neue ist unersättlich!
+
+[POR2_C:PORN2]
+Die hatte schon vor der ersten Probe das halbe Team durch.
+
+[POR2_D:PORN2]
+Jedenfalls, morgen haben wir einen Außendreh. Wir schießen ein paar Boot-Szenen.
+
+[POR2_E:PORN2]
+Boot-Szenen? Was für Boot-Szenen?
+
+[POR2_F:PORN2]
+Die Fischer zappeln im Netz der Leidenschaft, als ein riesiger Hai daherkommt -
+
+[POR2_G:PORN2]
+Was habe ich über den Riesenhai gesagt?
+
+[POR2_H:PORN2]
+Ich sagte, 'KEIN RIESENHAI', ok?
+
+[POR2_I:PORN2]
+Halt die Kameras auf die Mädels gerichtet!
+
+[POR2_J:PORN2]
+Ok, ok. Hey, Tommy, probieren kann ich's ja mal, oder?
+
+[POR2_K:PORN2]
+Habt ihr die Flyer drucken lassen?
+
+[POR2_L:PORN2]
+Ja, aber man wird uns die Dinger nicht verteilen lassen. Ich meine,
+
+[POR2_M:PORN2]
+die sind einfach zu, äh, zu deutlich.
+
+[POR2_N:PORN2]
+Mach dir darüber keine Gedanken.
+
+[POR2_O:PORN2]
+Ich hab da so meine Ideen, wie wir die verteilen.
+
+[POR2_P:PORN2]
+Ok. Hey, Candy, äh, in meinen Wohnwagen.
+
+[POR2_01:PORN2]
+~g~Hinter den Studios steht ein altes Wasserflugzeug, das mal als Requisite für einen Indy-Film diente.
+
+[POR2_02:PORN2]
+~g~Suche dir einen Checkpoint aus, um mit dem Abwurf der Flyer zu beginnen.
+
+[POR2_03:PORN2]
+~g~Wirf die Flyer überall bis zum End-Checkpoint ab.
+
+[POR2_04:PORN2]
+~r~TREIBSTOFFMANGEL!!!
+
+[POR2_05:PORN2]
+Benutze es, um die Flyer in der Stadt zu verteilen.
+
+[DILDO:PORN2]
+Skimmer-Tankinhalt:
+
+[POR2_Q:PORN2]
+Oh, Mann.
+
+[PORN2_9:PORN2]
+~g~Du hast ~1~ Sekunden, um zu einer Skimmer zurückzukehren, bevor die Mission endet.
+
+{=================================== MISSION TABLE PORN3 ===================================}
+
+[POR3_A:PORN3]
+Ok, was ist jetzt wieder?
+
+[POR3_B:PORN3]
+Schsch!
+
+[POR3_C:PORN3]
+Nun, nach seiner Begegnung mit den Nympho-Aliens
+
+[POR3_D:PORN3]
+kann unser Held an nichts anderes denken, als an einen riesigen Phallusberg-
+
+[POR3_E:PORN3]
+und da wollen wir die Szene mit dem Bottich voll Kartoffelpüree drehen, aber dann...
+
+[POR3_F:PORN3]
+Das interessiert mich nicht die Bohne.
+
+[POR3_G:PORN3]
+D-Dreh einfach weiter. Weiter, weiter.
+
+[POR3_H:PORN3]
+Hey, Tommy...
+
+[POR3_I:PORN3]
+Du hast am Telefon was von rechtlichen Problemen gesagt?
+
+[POR3_J:PORN3]
+Ach ja! Der Kongressabgeordnete Alex Shrub ist auf Wahlkampftour und buhlt um Stimmen bei den Puritanern.
+
+[POR3_K:PORN3]
+Es heißt, er unterstützt ein Verbot der, sagen wir mal, eher
+
+[POR3_L:PORN3]
+fleischlichen Bereiche der großartigen Unterhaltungsindustrie unseres Landes.
+
+[POR3_M:PORN3]
+Großartig.
+
+[POR3_N:PORN3]
+Candy! Du kennst doch Shrub.
+
+[POR3_O:PORN3]
+Macht ihr auch ausgefallene Sachen?
+
+[POR3_P:PORN3]
+Oh ja, oh ja, oh ja! Ja, ja, ja, JA, Oooooooh!
+
+[POR3_Q:PORN3]
+Bitte sag, dass du das hast.
+
+[POR3_R:PORN3]
+Gehörte das zum, äh... oder war das die Antwort für...
+
+[POR3_S:PORN3]
+Hey, ich kann das nie unterscheiden. Jedenfalls...
+
+[POR3_T:PORN3]
+Das beste wird sein, du folgst ihr nach dem Dreh.
+
+[POR3_U:PORN3]
+Mal sehen, ob sie dich zu ihrem neuen Liebesnest führt.
+
+[POR3_V:PORN3]
+Hast du eine Kamera?
+
+[POR3_X:PORN3]
+Ja. Gebt ihm eine Kamera.
+
+[POR3_02:PORN3]
+~r~Du hast den Abgeordneten erledigt! Jetzt kannst du ihn nicht mehr erpressen.
+
+[POR3_03:PORN3]
+~r~Du hast die Bodyguards des Abgeordneten aufgescheucht. Sie werden ihn sofort wegbringen.
+
+[POR3_04:PORN3]
+Candy, könntest du mich Martha nennen?
+
+[POR3_05:PORN3]
+Oh, Alex - ich meine Martha - ich tu alles, was du willst.
+
+[POR3_06:PORN3]
+Martha, jemand sieht uns zu. Wie erregend.
+
+[POR3_07:PORN3]
+Sie da! Geben Sie mir die Kamera.
+
+[POR3_01:PORN3]
+~g~Folge Candys ~h~Stretch-Limo~g~.
+
+[POR3_15:PORN3]
+~r~Du hast Candys Stretch-Limo geschrottet!
+
+[POR3_17:PORN3]
+~g~Begib dich mit dem Film zurück ins Pornostudio.
+
+[POR3_19:PORN3]
+~r~Der Film ist alle!
+
+[POR3_21:PORN3]
+~g~Du hast Candys Stretch-Limo verloren!
+
+[POR3_22:PORN3]
+~g~Das WK Chariot Hotel gegenüber seines Balkons dürfte eine ideale Position zum Fotografieren bieten.
+
+[POR3_23:PORN3]
+~g~Es gibt eine Seitentür, durch die du in das Hotel kommst.
+
+[POR3_08:PORN3]
+Halte die~h~ ~k~~PED_LOCK_TARGET~ ~w~gedrückt, um mit der Kamera zu ~h~zielen~w~.
+
+[POR3_09:PORN3]
+Halte die~h~ ~k~~PED_LOCK_TARGET~ ~w~gedrückt, um mit der Kamera zu ~h~zielen~w~.
+
+[POR3_10:PORN3]
+Drücke die~h~ ~k~~PED_SNIPER_ZOOM_IN~~w~, um ~h~heranzuzoomen ~w~und die~h~ ~k~~PED_SNIPER_ZOOM_OUT~~w~, um wieder ~h~wegzuzoomen~w~.
+
+[POR3_11:PORN3]
+Drücke die~h~ ~k~~PED_SNIPER_ZOOM_IN~~w~, um ~h~heranzuzoomen ~w~und die~h~ ~k~~PED_SNIPER_ZOOM_OUT~~w~, um wieder ~h~wegzuzoomen~w~.
+
+[POR3_12:PORN3]
+Drücke die~h~ ~k~~PED_FIREWEAPON~~w~, um ein Bild zu machen.
+
+[POR3_13:PORN3]
+Drücke die~h~ ~k~~PED_FIREWEAPON~~w~, um ein Bild zu machen.
+
+[POR3_14:PORN3]
+Drücke die~h~ ~k~~PED_FIREWEAPON~~w~, um ein Bild zu machen.
+
+[POR3_20:PORN3]
+~g~Wenn du ein Transportmittel brauchst, nimm den ~h~Sparrow~g~ hinter dem Haus.
+
+[POR3_16:PORN3]
+~g~Du brauchst drei gute kompromittierende Fotos von Alex Shrub mit Candy.
+
+[POR3_24:PORN3]
+GESCHOSSENE FOTOS:
+
+{=================================== MISSION TABLE PORN4 ===================================}
+
+[POR4_A:PORN4]
+Tut mir leid, ich kann das jetzt nicht schlucken.
+
+[POR4_B:PORN4]
+Ach KOMM, Darling!
+
+[POR4_C:PORN4]
+Der ist ausgestattet wie ein Pottwal, Herrgott noch mal,
+
+[POR4_D:PORN4]
+wie kannst du dich da nicht einfühlen?!
+
+[POR4_E:PORN4]
+Aber Stevie...
+
+[POR4_F:PORN4]
+Wie geht's meinem Starregisseur?
+
+[POR4_G:PORN4]
+Oh Mann. Der Kampf zwischen künstlerischer Ambition und
+
+[POR4_H:PORN4]
+diesem Rumgenudle tobt unvermindert.
+
+[POR4_I:PORN4]
+Und bevor du fragst: Ja, alle vier Videos werden veröffentlicht, wenn...
+
+[POR4_J:PORN4]
+Schätzchen, kannst du BITTE die Anaconda im Bild halten,
+
+[POR4_K:PORN4]
+die kostet pro Stunde mehr als du!
+
+[POR4_L:PORN4]
+Oh, sorry, Steve.
+
+[POR4_M:PORN4]
+Ich hab mir gedacht, als Werbung für den Start brauchen wir einen richtigen Knaller.
+
+[POR4_N:PORN4]
+Irgendwas, was so richtig Furore macht in der Stadt. Hast du eine Idee?
+
+[POR4_O:PORN4]
+Na ja, früher gab's da immer Galas,
+
+[POR4_P:PORN4]
+Stars, Limos, riesige Suchscheinwerfer am Nachthimmel...
+
+[POR4_Q:PORN4]
+Suchscheinwerfer? Ich hab eine Idee...
+
+[POR4_R:PORN4]
+....ja, ja, ja. Die heißen Mädels mit ihren Paillettenkleidern und die Limos, oh, Premieren.
+
+[POR4_S:PORN4]
+O ja, Ma'am, natürlich, Ma'am,
+
+[POR4_T:PORN4]
+Und die Presse und die Lichter-Flut...
+
+[POR4_01:PORN4]
+~g~Begib dich nach ~y~Downtown~g~und richte den Scheinwerfer auf dem Gebäude aus.
+
+[POR4_02:PORN4]
+~g~Du brauchst ein schnelles Bike, um von Dach zu Dach zu springen. Der Wachmann fährt immer mit einer ~y~PCJ 600~g~zur Arbeit...
+
+[POR4_03:PORN4]
+~g~Du wirst auf die Gebäudedächer müssen. In eines der oberen Büros sollte ein Lift führen...
+
+[POR4_06:PORN4]
+~g~Kehre in das tiefer gelegene Büro zurück, wenn du noch mal auf die Dächer musst.
+
+[POR4_07:PORN4]
+~g~Du brauchst ein Motorrad, um von Gebäude zu Gebäude zu springen.
+
+[POR4_08:PORN4]
+~g~Brich durch das Fenster, um zu starten. Du hast bis 07:00 Zeit. Dann wird es zu hell, um ungesehen hinaufzukommen.
+
+[POR4_09:PORN4]
+~g~Die Pfeile zeigen dir, zu welchem Gebäude du als nächstes springen musst.
+
+[POR4_10:PORN4]
+~r~Es ist zu hell, um ungesehen dort hinaufzukommen.
+
+[POR4_11:PORN4]
+Kehre zur Leiter zurück, wenn du noch mal auf die Dächer musst.
+
+[POR4_05:PORN4]
+~g~Diese Treppe führt zu einem tiefer gelegenen Büro.
+
+[POR_AS1:PORN4]
+FILMSTUDIO-MISSIONEN ERFÜLLT
+
+[POR_AS2:PORN4]
+~g~Inter Global Films generiert nun bis zu $~1~ Einkünfte. Hol dir das Geld regelmäßig ab.
+
+{=================================== MISSION TABLE PROT1 ===================================}
+
+[PRO1_A:PROT1]
+Oh, wir müssen diesen Laden umbauen. Das muss älter aussehen.
+
+[PRO1_B:PROT1]
+Ich kann diesen Look nicht ab, Tommy. Was meinst du, sollen wir eine Bar einbauen..?
+
+[PRO1_D:PROT1]
+Hört mal.
+
+[PRO1_E:PROT1]
+Die Zeit ist gekommen, die Stadt zu übernehmen. Sie wartet nur auf uns.
+
+[PRO1_F:PROT1]
+Wir müssen langsam Gebiete einnehmen.
+
+[PRO1_G:PROT1]
+Vice City soll merken, dass wir die neuen Bosse sind, versteht ihr?
+
+[PRO1_H:PROT1]
+Jetzt beruhigt euch mal kurz. Allmählich kapiere ich schon, wie das ganze hier läuft.
+
+[PRO1_I:PROT1]
+Was du brauchst, ist eine legale Fassade, Tommy, Immobilien. Hat mir nicht geschadet.
+
+[PRO1_J:PROT1]
+Wir müssen die Muskeln spielen lassen, sonst war die ganze harte Arbeit umsonst.
+
+[PRO1_K:PROT1]
+Die Geschäftsleute hier wissen, dass Diaz weg ist und weigern sich, Schutzgeld zu zahlen.
+
+[PRO1_L:PROT1]
+Oh, wir könnten es mit Schmiergeld versuchen...
+
+[PRO1_M:PROT1]
+Schmiergeld? Blödsinn! Ich zeig euch, wie man denen Angst macht.
+
+[PRO1_01:PROT1]
+~g~Demoliere die Schaufenster der Läden und die Inhaber werden darum betteln, zahlen zu dürfen.
+
+[PRO1_03:PROT1]
+~r~Du sollst abhauen, nicht Kaffee trinken gehen.
+
+[PRO1_04:PROT1]
+Mein Lebenswerk! Zerstört!
+
+[PRO1_05:PROT1]
+Ich bin ruiniert...RUINIERT!!
+
+[PRO1_06:PROT1]
+Ich zahle einen Haufen Schutzgeld!
+
+[PRO1_07:PROT1]
+Mein schönes Schaufenster!
+
+[PRO1_08:PROT1]
+Mein Laden! Mein schöner Laden!
+
+[PRO1_09:PROT1]
+Vercetti. Merkt euch den Namen.
+
+[PRO1_10:PROT1]
+Ich bin jetzt der Boss in der Stadt. ICH!
+
+[BUYP1:PROT1]
+Du kannst jetzt in bestimmten Gegenden auf der Karte Objekte kaufen.
+
+[BUYP2:PROT1]
+Wenn du ein Gebäude mit grüner Markierung siehst, kannst du dieses kaufen.
+
+[PRO1_N:PROT1]
+Ich bin in fünf Minuten zurück...
+
+[PRO1_11:PROT1]
+~g~Begib dich zum ~y~North Point Einkaufszentrum~g~ in ~y~Vice Point~g~.
+
+[PRO1_12:PROT1]
+~g~Zerbrich die Schaufenster eines jeden Ladens, und die Inhaber werden um neuen Schutz betteln.
+
+[PRO1_C:PROT1]
+Du bist mein Anwalt, nicht mein Innenarchitekt. Klar?
+
+[BUYP3:PROT1]
+Stell dich in die Markierung und drücke die ~h~~k~~PED_ANSWER_PHONE~~w~-Taste, um das Objekt zu kaufen.
+
+[PRO1_13:PROT1]
+~g~Du hast fünf Minuten, um alle zu demolieren.
+
+{=================================== MISSION TABLE PROT2 ===================================}
+
+[PRO2_01:PROT2]
+~g~Schalte die Wachen aus, die die Front Page Bar beschützen und finde raus, wer hinter ihnen steckt.
+
+[PRO2_08:PROT2]
+~g~Die DBP Security wird wissen, dass du kommst. Schnapp sie dir, ehe sie abhauen.
+
+[PRO2_A:PROT2]
+Was gibt's für Probleme?
+
+[PRO2_B:PROT2]
+Eine Bar weigert sich zu zahlen.
+
+[PRO2_C:PROT2]
+Die glauben, die werden von so einer Schlägerbande beschützt.
+
+[PRO2_D:PROT2]
+Aber keine Sorge, Tommy, ich regle das.
+
+[PRO2_E:PROT2]
+Das nennst du regeln?
+
+[PRO2_F:PROT2]
+Ihr zwei. Hebt mal den Hintern...
+
+[PRO2_G:PROT2]
+Los.
+
+[PRO2_10:PROT2]
+Zwei sind abgehauen. Finde sie und bring die Sache zuende.
+
+[PRO2_11:PROT2]
+Steig in den Wagen, Nichtsnutz.
+
+[PRO2_02:PROT2]
+Dein Schutz braucht ein bisschen mehr Schutz.
+
+[PRO2_03:PROT2]
+Ach, verdammt! Nicht schon wieder! Das brauche ich wirklich nicht!
+
+[PRO2_04:PROT2]
+Diese Idioten arbeiten eigentlich für die DBP Security gleich um die Ecke.
+
+[PRO2_05:PROT2]
+Macht ihr das mal unter euch aus.
+
+[PRO2_06:PROT2]
+Wir sehen uns.
+
+[PRO2_07:PROT2]
+Ja, ja. Wenn's sein muss.
+
+[PRO2_09:PROT2]
+~g~Begib dich zur Front Page Bar und sprich mit dem Besitzer.
+
+{=================================== MISSION TABLE PROT3 ===================================}
+
+[PRO3_A:PROT3]
+Du Trottel! Was hast du dir dabei gedacht?!
+
+[PRO3_B:PROT3]
+Ist dir klar, was das bedeutet?!
+
+[PRO3_C:PROT3]
+Das könnte das Ende für uns alle sein!
+
+[PRO3_D:PROT3]
+Der Zeitzünder muss hin gewesen sein.
+
+[PRO3_E:PROT3]
+Der Laden war mit Sprengstoff vollgepackt wie eine Feuerwerkfabrik.
+
+[PRO3_F:PROT3]
+Dann hat jemand den Cops einen Tipp gegeben...
+
+[PRO3_G:PROT3]
+Was gibt's für Probleme, Jungs?
+
+[PRO3_H:PROT3]
+Mike sollte einen Laden im Einkaufszentrum abfackeln,
+
+[PRO3_I:PROT3]
+aber er hat's vermasselt und jetzt wimmelt es dort von Bullen.
+
+[PRO3_J:PROT3]
+Wir müssen unser Zeug holen und verschwinden!
+
+[PRO3_K:PROT3]
+Langsam, ihr beiden, lasst mich kurz nachdenken!
+
+[PRO3_L:PROT3]
+Tommy Vercetti läuft nicht einfach weg.
+
+[PRO3_M:PROT3]
+Die Cops werden das Gebäude sorgfältig durchkämmen, oder?
+
+[PRO3_N:PROT3]
+Aber das dauert.
+
+[PRO3_O:PROT3]
+Wir müssen den Laden selbst abfackeln.
+
+[PRO3_P:PROT3]
+Ja, aber...
+
+[PRO3_Q:PROT3]
+Nur ein Cop kommt auch nur in die Nähe von dem Laden!
+
+[PRO3_R:PROT3]
+Dann gehen wir eben als Cops.
+
+[PRO3_S:PROT3]
+Wir brauchen Uniformen und einen Streifenwagen.
+
+[PRO3_T:PROT3]
+Und das alles nur wegen dir, Mike.
+
+[PRO3_U:PROT3]
+Tut mir leid.
+
+[PRO3_V:PROT3]
+Ich hab's.
+
+[PRO3_W:PROT3]
+Wir müssen die Cops hereinlocken,
+
+[PRO3_X:PROT3]
+dann sperren wir sie ein
+
+[PRO3_Y:PROT3]
+und überwältigen sie.
+
+[PRO3_Z:PROT3]
+Guter Plan. Los geht's!
+
+[PRO3_A1:PROT3]
+Ok.
+
+[PRO3_01:PROT3]
+Ok, Lance, machen wir die Cops auf uns aufmerksam!
+
+[PRO3_02:PROT3]
+~g~ Nimm den Streifenwagen und lege die Bombe im Tarbrush Coffee Shop im Einkaufszentrum.
+
+[PRO3_03:PROT3]
+~g~Du hast Lance vergessen. Hole ihn.
+
+[PRO3_04:PROT3]
+~g~ Los geht's.
+
+[PRO3_05:PROT3]
+~r~Du hast Lance erledigt!
+
+[PRO3_07:PROT3]
+~g~Die Tarnung ist aufgeflogen. Beeilung, platziere die Bombe!
+
+[PRO3_09:PROT3]
+Fessle und kneble sie!
+
+[PRO3_10:PROT3]
+Uuh! Passt perfekt!
+
+[PRO3_11:PROT3]
+Bisschen eng im Schritt vielleicht...
+
+[PRO3_12:PROT3]
+Oh ja, ja. Meine auch, meine auch.
+
+[PRO3_13:PROT3]
+Vorsicht, Bruder! Kein Cop fährt so schlecht!
+
+[PRO3_14:PROT3]
+Denk dran, lächle die anderen Cops an.
+
+[PRO3_15:PROT3]
+Hallo, Officer. Hübsche Marke, hübsche Marke.
+
+[PRO3_16:PROT3]
+Ganz toll, Lance.
+
+[PRO3_17:PROT3]
+Ok, die Zünder sind auf 5 Sekunden gestellt.
+
+[PRO3_18:PROT3]
+5 Sekunden?!! Nichts wie raus hier!
+
+[PRO3_19:PROT3]
+Jetzt sind sie so richtig stocksauer.
+
+[PRO3_20:PROT3]
+~g~Bring 2 Cops dazu, dir in die Garage zu folgen.
+
+[PRO3_21:PROT3]
+~g~Beschaff dir einen Fahndungslevel, damit dir die Cops in die Garage folgen.
+
+[PRO3_22:PROT3]
+~g~Das Garagentor ist blockiert! Du musst es freiräumen, damit es schließen kann.
+
+[PRO3_23:PROT3]
+~g~Stell dich in die Markierung, um die Bombe zu platzieren.
+
+[PRO3_24:PROT3]
+~g~Verschwinde aus der Nähe des Cafés!
+
+[PRO_AS1:PROT3]
+SCHUTZGELD-MISSIONEN ERFÜLLT
+
+[PRO_AS2:PROT3]
+~g~Das Vercetti Estate generiert nun bis zu $~1~ Einkünfte. Hol dir das Geld regelmäßig ab.
+
+[PRO3_08:PROT3]
+~g~Du musst zurück zu ~h~Vercetti Estate~g~ auf ~h~Starfish Island~g~.
+
+{=================================== MISSION TABLE RACES ===================================}
+
+[RACES_2:RACES]
+~g~Du brauchst ein Fahrzeug! Das ist kein Wettlaufen!
+
+[RACES_3:RACES]
+3..2..1.. LOS, LOS, LOS!
+
+[RACES_8:RACES]
+~r~Du hast das Rennen nicht gewonnen!
+
+[RACES00:RACES]
+Rennen ~1~:
+
+[RACES01:RACES]
+Todeskaracho
+
+[RACES02:RACES]
+Ocean Drive
+
+[RACES03:RACES]
+Küsten-Rallye
+
+[RACES04:RACES]
+Capital Cruise
+
+[RACES05:RACES]
+Tour!
+
+[RACES06:RACES]
+V.C. Endurance
+
+[RACES07:RACES]
+Startgebühr: $~1~
+
+[RACES08:RACES]
+Bestzeit: ~1~:~1~
+
+[RACES09:RACES]
+Beste Platzierung: 1.
+
+[RACES10:RACES]
+Beste Platzierung: 2.
+
+[RACES11:RACES]
+Beste Platzierung: 3.
+
+[RACES12:RACES]
+Beste Platzierung: 4.
+
+[RACES13:RACES]
+Streckenlänge: ~1~.~1~ km
+
+[RACES15:RACES]
+Bestzeit: Nicht verfügbar
+
+[RACES16:RACES]
+Beste Platzierung: Nicht verfügbar
+
+[RACES19:RACES]
+Du hast nicht genug Geld, um an diesem Rennen teilzunehmen.
+
+[RACES22:RACES]
+Bestzeit: ~1~:0~1~
+
+[RACES23:RACES]
+Streckenlänge: ~1~.~1~ Meilen
+
+[RACES_1:RACES]
+~g~Schnapp dir ein schnelles Fahrzeug und begib dich zur Startlinie.
+
+[RACEHLP:RACES]
+~w~Drücke die~h~ ~k~~PED_SPRINT~~w~, um das ausgewählte Rennen zu starten. Drücke die~h~ ~k~~VEHICLE_ENTER_EXIT~~w~, um abzubrechen.
+
+{=================================== MISSION TABLE RCHELI1 ===================================}
+
+[WRECKED:RCHELI1]
+~r~Das Fahrzeug ist Schrott!
+
+[RCH1_4:RCHELI1]
+Verbleibende Checkpoints:
+
+[RCH1_7:RCHELI1]
+~g~Es gibt insgesamt 20 Checkpoints.
+
+[RCH1_12:RCHELI1]
+~g~Der ferngesteuerte Helikopter gerät außer Reichweite!
+
+[RCH1_13:RCHELI1]
+~r~Der ferngesteuerte Helikopter ist außer Reichweite!
+
+[RCH1_8:RCHELI1] { reVC update }
+~g~Wenn du diese Mission abbrechen willst, drücke die ~h~~k~~VEHICLE_FIREWEAPON~~g~, um deinen Heli zu sprengen.
+
+{=================================== MISSION TABLE RCPLNE1 ===================================}
+
+[RCPL1_4:RCPLNE1]
+~g~Miss dich mit 3 anderen ferngesteuerten Maschinen in einem CHECKPOINT RENNEN
+
+[RCPL1_5:RCPLNE1]
+~g~Flieg durch die Checkpoints, die über Vice City verteilt sind.
+
+[RCPL1_6:RCPLNE1] { reVC update }
+~g~Wenn du diese Mission abbrechen willst, drücke die ~h~~k~~VEHICLE_FIREWEAPON~~g~, um dein Flugzeug zu sprengen.
+
+[RCPL1_8:RCPLNE1]
+~g~Dein ferngesteuertes Flugzeug gerät außer Reichweite!
+
+[RCPL1_9:RCPLNE1]
+~r~Dein ferngesteuertes Flugzeug ist außer Reichweite!
+
+{=================================== MISSION TABLE RCRACE1 ===================================}
+
+[RCRC1_1:RCRACE1]
+~g~Liefere dir mit 3 anderen RC Bandits ein CHECKPOINT-RENNEN über 2 RUNDEN.
+
+[RCRC1_3:RCRACE1]
+~g~Letzte Runde!
+
+[RCR1_4:RCRACE1]
+Verbleibende Runden:
+
+[RCR1_1:RCRACE1]
+~g~Tritt in einem Checkpoint-Rennen gegen 3 andere ferngesteuerte Autos an.
+
+[RCR1_2:RCRACE1]
+~g~Du musst als erster 2 volle Runden auf dem Kurs fahren!
+
+[RCR1_6:RCRACE1]
+~g~Dein ferngesteuertes Auto gerät außer Reichweite!
+
+[RCR1_7:RCRACE1]
+~r~Dein ferngesteuertes Auto ist außer Reichweite!
+
+{=================================== MISSION TABLE ROCK1 ===================================}
+
+[RBM1_A:ROCK1]
+AllllllllRrrighttt!
+
+[RBM1_B:ROCK1]
+Fantastisch, einfach fantastisch!
+
+[RBM1_D:ROCK1]
+Hey, kennst du die Jungs von Love Fist?
+
+[RBM1_E:ROCK1]
+Nein, aber ihre Musik habe ich immer geliebt.
+
+[RBM1_F:ROCK1]
+Ich stelle dir die Band vor.
+
+[RBM1_G:ROCK1]
+Das ist P, Percy, Dick, und Willy ist auf dem Klo. Und das vorher in der Kabine war Jezz.
+
+[RBM1_H:ROCK1]
+Jungs, ich möchte euch einen guten Freund vorstellen.
+
+[RBM1_I:ROCK1]
+Das ist Tommy. Wir kennen uns schon ewig.
+
+[RBM1_J:ROCK1]
+Alles paletti, Mann.
+
+[RBM1_K:ROCK1]
+Und, äh, wie war dein Name noch mal?
+
+[RBM1_L:ROCK1]
+Lass das, Jezz. Merk dir eines,
+
+[RBM1_M:ROCK1]
+mit mir kannst du diese Spielchen nicht machen.
+
+[RBM1_N:ROCK1]
+Ich bin dir einfach über, Sonnenscheinchen.
+
+[RBM1_O:ROCK1]
+Die Sache ist die, Tom, die Jungs brauchen Hilfe.
+
+[RBM1_P:ROCK1]
+Die haben hier keine Connections, kein Vitamin B.
+
+[RBM1_Q:ROCK1]
+Wir brauchen Stoff, Alter.
+
+[RBM1_R:ROCK1]
+Damit wir den alten Love Fist Spirit finden, verstehst du?!
+
+[RBM1_S:ROCK1]
+Wir sind hier in Vice City, Mann. Wo liegt das Problem?
+
+[RBM1_U:ROCK1]
+Love Juice, Mann!
+
+[RBM1_V:ROCK1]
+Love Juice?
+
+[RBM1_W:ROCK1]
+Genau. 2 Teile TNT-Whiskey, 1 Teil Koks, 5 Päckchen Brause und 1 Liter Sprit.
+
+[RBM1_X:ROCK1]
+Kannst du uns weiterhelfen, Alter?
+
+[RBM1_Y:ROCK1]
+Es würde den Jungs wirklich viel bedeuten.
+
+[RBM1_Z:ROCK1]
+Du kannst den Jungs doch helfen, oder?
+
+[RBM1_7:ROCK1]
+~r~Du hast den Love Juice nicht rechtzeitig besorgt!
+
+[RBM1_8:ROCK1]
+~r~Mercedes ist erledigt!
+
+[RBM1_10:ROCK1]
+~r~Du Idiot! Du hast die Ware vernichtet!
+
+[RBM1_13:ROCK1]
+~g~Bring den Love Juice und Mercedes zu der Band bevor sie auf die Bühne muss.
+
+[RBM1_15:ROCK1]
+~r~Du hast den Dealer verloren, unser Geld und den Stoff!
+
+[RBM1_17:ROCK1]
+~g~Knöpf dir den Dealer vor und hol dir den Stoff!
+
+[MOB_07A:ROCK1]
+Hey, die Jungs könnten ein bisschen Gesellschaft vertragen, falls du weißt, was ich meine...
+
+[MOB_07B:ROCK1]
+Da kenne ich genau die richtige.
+
+[ROK1_5:ROCK1]
+Hey, Mercedes!
+
+[ROK1_6:ROCK1]
+Hi, Tommy. Na, wie läuft's so?
+
+[ROK1_7:ROCK1]
+Alles bestens. Hör mal, willst du die Jungs von Love Fist verführen?
+
+[ROK1_8:ROCK1]
+Ok, aber dafür bist du mir einen Gefallen schuldig.
+
+[RBM1_14:ROCK1]
+~g~Du brauchst ein Auto oder Motorrad!
+
+[RBM1_1:ROCK1]
+~g~Hol Mercedes in ihrer Wohnung ab.
+
+[RBM1_12:ROCK1]
+~g~Besorg die Zutaten für den 'Love Juice' von dem Dealer.
+
+[ROK1_2:ROCK1]
+NICHT MEHR BENÖTIGT
+
+[ROK1_3:ROCK1]
+NICHT MEHR BENÖTIGT
+
+[MERC_39:ROCK1]
+Wir sehen uns später, Big Boy.
+
+[RBM1_C:ROCK1]
+Hey, Tommy! Schön, dass du kommen konntest.
+
+[RBM1_9:ROCK1]
+~g~Besorg von dem Dealer Love Juice für Love Fist!
+
+[ROK1_1A:ROCK1]
+Suchst du was Bestimmtes? Ich habe genau, was du brauchst!
+
+[ROK1_9:ROCK1]
+Danke für die Kohle, du Trottel!
+
+[RBM1_T:ROCK1]
+Wir brauchen Love Juice, Mann, klar?
+
+{=================================== MISSION TABLE ROCK2 ===================================}
+
+[RBM2_A:ROCK2]
+Tommy, Mann, bin ich froh, dich zu sehen!
+
+[RBM2_B:ROCK2]
+Was ist los?
+
+[RBM2_C:ROCK2]
+Schlechte Vibes, Tommy...
+
+[RBM2_E:ROCK2]
+Da ist so 'n Typ, wir kennen ihn kaum, aber er kennt uns.
+
+[RBM2_F:ROCK2]
+So wie er da. Weiß alles über uns.
+
+[RBM2_G:ROCK2]
+Weiß, dass Willy auf Damenunterwäsche steht, eh!
+
+[RBM2_H:ROCK2]
+Oder dass Percy auf Duran Duran steht!
+
+[RBM2_K:ROCK2]
+Ja, die Liebesrakete, schon gut. Aber hör zu, dieser Typ...
+
+[RBM2_L:ROCK2]
+ja, ja, der Typ will Love Fist ausknipsen.
+
+[RBM2_M:ROCK2]
+Ausknipsen, Tommy.
+
+[RBM2_N:ROCK2]
+Love Fist soll verschwinden. Wie es immer heißt: Die Besten sterben jung.
+
+[RBM2_O:ROCK2]
+Aber Tommy, du musst Love Fist retten!
+
+[RBM2_P:ROCK2]
+Wir geben in zwei Stunden eine Autogrammstunde, und ich glaube...
+
+[RBM2_Q:ROCK2]
+Und die Jungs glauben, dass der Kerl dort irgendwas plant.
+
+[RBM2_1:ROCK2]
+~g~Fahre die Limo zum Ort der Autogrammstunde und versuche, den Irren zu finden.
+
+[RBM2_2:ROCK2]
+~r~Du hast den Wagen der Band geschrottet!
+
+[RBM2_3:ROCK2]
+~g~Geh zu der Autogrammstunde!
+
+[RBM2_4:ROCK2]
+~g~Erledige den Irren. Lass ihn nicht entkommen!
+
+[RBM2_5:ROCK2]
+~r~Du hast ihn verloren, du Idiot!
+
+[RBM2_7:ROCK2]
+~r~Die Fans wurden angegriffen. Der Irre wird nicht auftauchen!
+
+[RBM2_8:ROCK2]
+~r~Die Security-Leute wurden angegriffen. Der Irre wird nicht auftauchen!
+
+[PSYCH_1:ROCK2]
+Love Fist wird in der Hölle braten!
+
+[PSYCH_2:ROCK2]
+Love Fist hat mein Leben zerstört!
+
+[RBM2_I:ROCK2]
+Halt's Maul, du Irrer! Nur weil Jezz auf Schafe steht.
+
+[RBM2_R:ROCK2]
+Hey, Schnauze!
+
+[RBM2_D:ROCK2]
+Das ist kein Spaß, das ist 'ne brutale Geschichte, brutal, ok?
+
+[RBM2_J:ROCK2]
+Ich sage nur, die Liebesrakete, ok?
+
+{=================================== MISSION TABLE ROCK3 ===================================}
+
+[RBM3_A:ROCK3]
+Tommy! Tommy! Tommy, Mann, der Irre ist wieder da!
+
+[RBM3_B:ROCK3]
+Was ist denn los?
+
+[RBM3_C:ROCK3]
+Dieser Irre lässt Love Fist nicht in Ruhe!
+
+[RBM3_D:ROCK3]
+Du hast ihn nicht erwischt, Mann. Und jetzt ist er wieder da.
+
+[RBM3_E:ROCK3]
+Ja, ja, ja, und es ist nämlich so...
+
+[RBM3_F:ROCK3]
+wir brauchen für die Limo einen Fahrer, dem wir vertrauen können,
+
+[RBM3_G:ROCK3]
+weil der Irre uns ständig bedroht!
+
+[RBM3_I:ROCK3]
+Wir scheißen uns alle in die Hosen, Mann.
+
+[RBM3_J:ROCK3]
+Ok, Jungs, nur die Ruhe. Ich mach das schon.
+
+[RBM3_K:ROCK3]
+Normalerweise würde ich keine besoffenen, schottischen Tucken durch die Gegend kutschieren,
+
+[RBM3_L:ROCK3]
+aber für euch mache ich eine Ausnahme.
+
+[ROK3_03:ROCK3]
+Dann mach mir einen großen.
+
+[ROK3_04:ROCK3]
+Hey, Tommy, nun mach mal halblang, Mann.
+
+[ROK3_08:ROCK3]
+Langsam wird's langweilig.
+
+[ROK3_09:ROCK3]
+Halt bloß das Pedal durchgedrückt!!
+
+[ROK3_61:ROCK3]
+Wir müssen die Bombe finden!
+
+[ROK3_28:ROCK3]
+Ich werd Bass in der Hölle spielen.
+
+[ROK3_30:ROCK3]
+Tu doch einer was!
+
+[ROK3_32:ROCK3]
+Ok, Obermacho, dann tu du doch was!
+
+[ROK3_34:ROCK3]
+Willy könnte den TNT-Whiskey mit einem Strohhalm raussaugen.
+
+[ROK3_37:ROCK3]
+Gebt Willy einen Strohhalm!
+
+[ROK3_41:ROCK3]
+Welchen Draht, Tommy?
+
+[ROK3_42:ROCK3]
+Den grünen.
+
+[ROK3_43:ROCK3]
+Da ist kein grüner. Oder ist der hier grün?
+
+[ROK3_44:ROCK3]
+Sieht für dich einer von den Drähten grün aus?
+
+[ROK3_49:ROCK3]
+Ich hab euch doch jahrelang nur mitgeschleppt.
+
+[ROK3_51:ROCK3]
+Ein großes keifendes Weib.
+
+[ROK3_52:ROCK3]
+Ja.
+
+[ROK3_53:ROCK3]
+Klappe jetzt und zieht einen Draht raus.
+
+[ROK3_54:ROCK3]
+Welchen?
+
+[ROK3_55:ROCK3]
+Den da...
+
+[ROK3_56:ROCK3]
+NEIN!
+
+[ROK3_57:ROCK3]
+Mann, alles ok. Wir sind nicht hochgegangen, Alter. Tommy, Mann, gut gemacht. Rock 'n' Roll, Mann.
+
+[ROK3_58:ROCK3]
+Müssen wir nicht zu einem Gig? Krach machen? Groupies abgreifen?
+
+[ROK3_59:ROCK3]
+LOVE FIST!
+
+[ROK3_60:ROCK3]
+Bist du fertig mit der Pulle?
+
+[RBM3_4:ROCK3]
+~r~Love Fist ist Geschichte!
+
+[RBM3_6:ROCK3]
+DETONATION:
+
+[RBM3_1:ROCK3]
+~g~Chauffiere Love Fist zu ihrem Auftritt.
+
+[RBM3_2:ROCK3]
+Falls du versuchst, aus dem Auto auszusteigen, wenn die Bombe scharfgemacht ist, wird sie explodieren...
+
+[RBM3_3:ROCK3]
+Ist der Detonations-Balken am Anschlag, explodiert die Bombe.
+
+[RBM3_8:ROCK3]
+Je schneller du fährst, desto niedriger der Detonations-Balken.
+
+[RBM3_7:ROCK3]
+~g~BOMBE ENTSCHÄRFT!
+
+[ROK3_6A:ROCK3]
+~g~Love Fist. Ihr habt den Äther lange genug verschmutzt!
+
+[ROK3_6B:ROCK3]
+~g~Ich wollte euer Freund sein. Jetzt will ich, dass ihr untergeht.
+
+[ROK3_62:ROCK3]
+Wir dachten, wir zeigen dir mal unseren Rocktempel...
+
+[ROK3_63:ROCK3]
+Kannst dir die Power von Love Fist reinziehen!
+
+[ROK3_64:ROCK3]
+Hör sich das einer an, Mann. Das ist Pappmaché und Klebeband.
+
+[ROK3_65:ROCK3]
+Hey, für die Kids ist es ein Tempel, und wir sind die Priester!
+
+[ROK3_66:ROCK3]
+Tja, wenn die Kids es toll finden, dass ihre Priester dicht und unmusikalisch sind,
+
+[ROK3_67:ROCK3]
+was soll man da sagen?
+
+[ROK3_68:ROCK3]
+Oh, Mist, das Ding frisst schon wieder das Band.
+
+[ROK3_69:ROCK3]
+Wenn das so ist, müssen wir live spielen.
+
+[ROK3_70:ROCK3]
+Ooooh Shit! Mein Darm...
+
+[ROK3_01:ROCK3]
+Endlich, Mann, Zeit für einen wohlverdienten Drink.
+
+[ROK3_02:ROCK3]
+Die Halle ist nur 100 Meter die Straße runter.
+
+[ROK3_05:ROCK3]
+Ich werd irre, wenn ich keinen Sprit kriege.
+
+[ROK3_07:ROCK3]
+Tommy, mein Freund, wir müssen die Band retten!
+
+[ROK3_29:ROCK3]
+Tommy, bleib auf dem Gas, Alter.
+
+[ROK3_31:ROCK3]
+Ganz toll. 'Tu doch einer was.' Was ist denn das für eine Ansage? Da kenn ich mutigere Mädels.
+
+[ROK3_33:ROCK3]
+Alter, ich bin Musiker. Vom Bomben-Entschärfen hab ich keinen blassen Dunst.
+
+[ROK3_35:ROCK3]
+Eben, so was liegt dir doch, was ich so höre.
+
+[ROK3_38:ROCK3]
+Einen Strohhalm?! Dies ist der Tour-Bus von Love Fist!
+
+[ROK3_39:ROCK3]
+Wo zum Geier sollte hier ein Strohhalm sein?
+
+[ROK3_46:ROCK3]
+Ich hätte euch alle rausschmeißen sollen, als es noch ging, Mann.
+
+[ROK3_47:ROCK3]
+Kapitalist.
+
+[ROK3_48:ROCK3]
+Kameradenschwein.
+
+[ROK3_73:ROCK3]
+Jezz spielt das Band ab,
+
+[RBM3_9:ROCK3]
+Wenn du angehalten wirst oder langsam fährst, wächst der Detonations-Balken.
+
+[ROK3_50:ROCK3]
+Halt die Klappe. Du bist ein Idiot.
+
+[ROK3_36:ROCK3]
+Hey, ich war an dem Abend vielleicht komplett zugedröhnt!
+
+[RBM3_H:ROCK3]
+Ich scheiß mir in die Hose, Mann. Ich will zu meiner Mama!
+
+[ROK3_45:ROCK3]
+Oh nein. Im Angesicht des Todes sieht alles grün aus.
+
+[ROK3_6C:ROCK3]
+~g~Wenn ihr langsamer werdet, geht eure Limo hoch, IHR UND EURE HAARIGEN ÄRSCHE mit dazu!
+
+[ROK3_71:ROCK3]
+Wir müssen uns ranhalten. Danke nochmal, Tommy, du hast es echt drauf. Ciao.
+
+[ROK3_1:ROCK3]
+Endlich, Mann, Zeit für einen wohlverdienten Drink. Die Halle ist nur 100 Meter die Straße runter.
+
+[ROK3_2:ROCK3]
+Mach mir mal einen großen. Hey, Tommy, leg mal 'nen anderen Sound auf, Mann.
+
+[ROK3_3:ROCK3]
+Ich werd wirr im Kopf, wenn nichts zum Headbangen läuft. Hey, Tommy, leg mal dieses Band ein.
+
+[ROK3_4:ROCK3]
+Love Fist. Ihr habt den Äther lange genug verschmutzt! Ich wollte euer Freund sein.
+
+[ROK3_5:ROCK3]
+Jetzt will ich, dass ihr untergeht. Wenn ihr langsamer werdet, geht eure Limo hoch, IHR UND EURE HAARIGEN ÄRSCHE mit dazu!
+
+[ROK3_6:ROCK3]
+Tommy, mein Freund, du musst die Band retten! Langsam wird's langweilig. Halt bloß das Pedal durchgedrückt!!
+
+[ROK3_7:ROCK3]
+Wir müssen die Bombe finden! Können wir nicht einfach den ganzen Tag rumfahren? Wir haben jedenfalls jede Menge zu saufen.
+
+[ROK3_8:ROCK3]
+Könnte die Bombe nicht unter der Motorhaube sein? Da kommen wir nie ran, ohne anzuhalten! Wir werden alle sterben! Ich besauf mich!
+
+[ROK3_9:ROCK3]
+Hey, hier gibt's eine Warteschlange, Alter! Die Lösung liegt nicht in der Minibar! Weg da!
+
+[ROK3_10:ROCK3]
+Hey, aus der Wodkapulle kommen Drähte raus! Das ist kein Wodka, das ist TNT-WHISKEY!
+
+[ROK3_11:ROCK3]
+WAAAAAAGGGHHHH!!!! Das Ding ist scharfgemacht!! WAAAAAAAAAAGGGHHHHHH!!!!
+
+[ROK3_12:ROCK3]
+Man hat mir immer gesagt, der Alk wird mich killen... Das kenn ich aus dem Fernsehen. Du musst einen der Drähte rausziehen. Welchen Draht? Weiß ich doch nicht, Mann.
+
+[ROK3_13:ROCK3]
+Keinen Schimmer. Willy, sag doch mal was. Ich werd Bass in der Hölle spielen.
+
+[ROK3_14:ROCK3]
+Tommy, bleib auf dem Gas, Mann. Tu doch einer was! Ganz toll...
+
+[ROK3_15:ROCK3]
+'Tu doch einer was.' Was ist denn das für eine Ansage? Da kenn ich mutigere Mädchen. Ok, Obermacho, dann tu du doch was!
+
+[ROK3_16:ROCK3]
+Alter, ich bin Musiker. Mit Bomben kenne ich mich nicht aus. Willy könnte den TNT-Whiskey mit einem Strohhalm raussaugen.
+
+[ROK3_17:ROCK3]
+Eben, so was liegt dir doch, was ich so höre. Hey, ich war total blau an dem Abend, das wisst ihr ganz genau!
+
+[ROK3_18:ROCK3]
+Gebt Willy einen Strohhalm! Einen Strohhalm?! Wi sind im Band-Auto von Love Fist!
+
+[ROK3_19:ROCK3]
+Wo zum Geier sollte hier ein Strohhalm sein? Welchen Draht, Tommy? Den grünen. Da ist kein grüner.
+
+[ROK3_20:ROCK3]
+Oder ist der hier grün? Sieht für dich einer von den Drähten grün aus?
+
+[ROK3_21:ROCK3]
+Oh nein. Im Angesicht des Todes sieht alles grün aus. Ich hätte euch alle rausschmeißen sollen, als es noch ging, Mann.
+
+[ROK3_22:ROCK3]
+Kameradenschwein. Kapitalist. Ich hab euch doch jahrelang nur mitgeschleppt. Halt die Klappe. Du bist ein Idiot.
+
+[ROK3_23:ROCK3]
+Ein großes keifendes Weib. Ja. Klappe jetzt und zieht einen Draht raus. Welchen? Den da...
+
+[ROK3_24:ROCK3]
+NEIN! Mann, alles ok. Wir sind nicht hochgegangen, Alter.
+
+[ROK3_25:ROCK3]
+Tommy, Mann, gut gemacht. Rock 'n' Roll, Mann. Müssen wir nicht zu einem Gig?
+
+[ROK3_26:ROCK3]
+Krach machen? Groupies abgreifen? LOVE FIST!
+
+[ROK3_27:ROCK3]
+Bist du fertig mit der Pulle?
+
+{=================================== MISSION TABLE SERG1 ===================================}
+
+[TEX1_0:SERG1]
+~g~Die Zielperson ist auf der Driving Range. Sorg dafür, dass er seinen letzten Golfball geschlagen hat!
+
+[TEX1_A:SERG1]
+Komm rein und setz dich auf deinen Hintern, Junge.
+
+[TEX1_B:SERG1]
+Mein Daddy hat immer gesagt, einem geschenkten Gaul schaut man nicht ins Maul. Hat's auch nie getan.
+
+[TEX1_C:SERG1]
+Ein Gläschen alter Kentucky gefällig?
+
+[TEX1_D:SERG1]
+Nein danke.
+
+[TEX1_E:SERG1]
+Ein nüchterner Denker, das gefällt mir.
+
+[TEX1_F:SERG1]
+Im Immobiliengeschäft geht's nicht um hochtrabende Verträge.
+
+[TEX1_G:SERG1]
+Es geht um Land. Und darum, dieses Land zu kriegen. Kannst du mir folgen?
+
+[TEX1_H:SERG1]
+Oh, ja.
+
+[TEX1_I:SERG1]
+Ich will, dass so ein sturer Hund sein Land hergibt.
+
+[TEX1_J:SERG1]
+Mir scheint, du könntest ihn dazu überreden.
+
+[TEX1_K:SERG1]
+Ich bin der reinste Überredungskünstler.
+
+[TEX1_L:SERG1]
+Ja. Er wird im Country Club sein, auf dem Golfplatz.
+
+[TEX1_M:SERG1]
+Knarren sind dort verboten. Seine Bodyguards werden also unbewaffnet sein.
+
+[TEX1_N:SERG1]
+Du sollst ihn so richtig gründlich vermöbeln.
+
+[TEX1_O:SERG1]
+Hier, ich hab dir einen Mitgliedsausweis besorgt. Aber du brauchst passendere Kleidung.
+
+[TEX1_2:SERG1]
+~g~Begib dich jetzt zum Leaf Links Golf Club.
+
+[TEX1_3:SERG1]
+Wer ist der Kerl? Jungs, nehmt ihn euch vor.
+
+[TEX1_6:SERG1]
+Hübscher Hintern, Baby!
+
+[TEX1_7:SERG1]
+Bin ich das?
+
+[TEX1_8:SERG1]
+Jedesmal wenn du in einen Golfwagen steigst, erhältst du automatisch einen Golfschläger, vorausgesetzt, du hast nicht schon eine Nahkampfwaffe.
+
+[TEX1_9:SERG1]
+Schnapp ihn dir!
+
+[TEX1_10:SERG1]
+Mach den Irren fertig!
+
+[TEX1_1:SERG1]
+~g~Besorg dir bei Jocksport Golferklamotten.
+
+{=================================== MISSION TABLE SERG2 ===================================}
+
+[TEXEXIT:SERG2]
+~g~Jetzt verschwinde aus Little Haiti!
+
+[TEX_2A:SERG2]
+~g~Großartig! Sie haben dich bemerkt!
+
+[TEX_2B:SERG2]
+~r~Narr! Die Leute müssen SEHEN, dass der Täter ein Kubaner ist!
+
+[TEX_2C:SERG2]
+~g~Besorge dir bei Rafael's Kleidung in den Farben der kubanischen Gang.
+
+[TEX_2D:SERG2]
+~g~Nimm dir jetzt den Boss der Haitianer in Romeros Beerdigungsinstitut vor.
+
+[TEX2_A:SERG2]
+Tommy, das ist Donald Love. Donald, das ist Tommy Vercetti,
+
+[TEX2_B:SERG2]
+der neueste Draufgänger hier in der Stadt.
+
+[TEX2_C:SERG2]
+Ja...äh...
+
+[TEX2_D:SERG2]
+Donald, sei still und hör zu. Vielleicht kannst du was lernen.
+
+[TEX2_E:SERG2]
+Also. Nichts lässt Immobilienpreise schneller abstürzen als ein guter alter Bandenkrieg.
+
+[TEX2_F:SERG2]
+Außer vielleicht eine Katastrophe, eine biblische Plage oder so,
+
+[TEX2_G:SERG2]
+aber das ginge hier wohl zu weit.
+
+[TEX2_H:SERG2]
+Kannst du mir folgen, Brillenschlange?
+
+[TEX2_I:SERG2]
+Jüngst starb ein haitianischer Gang-Boss. Man tippt, es waren die Kubaner, aber keiner weiß es.
+
+[TEX2_J:SERG2]
+Aber wir wollen sicher gehen. Du verkleidest dich als kubanischer Hombre
+
+[TEX2_K:SERG2]
+und machst Krawall bei der Beerdigung. Misch sie auf und dann verzieh dich.
+
+[TEX2_L:SERG2]
+Kannst du mir folgen, Donald?
+
+[TEX2_M:SERG2]
+Das dürfte das Fass zum Überlaufen bringen, was?
+
+[TEX2_N:SERG2]
+Und wir lehnen uns zurück und sehen zu, wie die Preise purzeln.
+
+{=================================== MISSION TABLE SERG3 ===================================}
+
+[TEX3_A:SERG3]
+Pass auf, Junge. Ich habe ein Problem und denke, du könntest mir weiterhelfen.
+
+[TEX3_B:SERG3]
+Ich bin kein Bauunternehmer.
+
+[TEX3_C:SERG3]
+Nein, ich dachte mehr an deine Talente als Abrissunternehmer.
+
+[TEX3_D:SERG3]
+Das hier zeigt, was wir geplant haben. Und so-
+
+[TEX3_E:SERG3]
+-so sieht der betreffende Grund heute aus.
+
+[TEX3_F:SERG3]
+Sie wollen sagen, das neue Bürohaus da ist Ihnen im Weg.
+
+[TEX3_G:SERG3]
+Gut mitgedacht.
+
+[TEX3_H:SERG3]
+Also, ich verdrücke mich eine Weile aus der Stadt,
+
+[TEX3_I:SERG3]
+und wenn dieses Bürogebäude urplötzlich irreparable Schäden aufweist, dann...
+
+[TEX3_J:SERG3]
+....fühlen Sie sich als guter Mensch verpflichtet, einzuspringen und
+
+[TEX3_K:SERG3]
+-für die Neugestaltung eines wichtigen Gebiets der Stadt zu sorgen?
+
+[TEX3_L:SERG3]
+Wo finde ich mehr Männer wie dich?
+
+[TEX3_1:SERG3]
+~g~Benutze den ferngesteuerten Helikopter, um Bomben zu 4 Zielen an dem zur Sprengung vorgesehenen Gebäude zu transportieren.
+
+[TEX3_2:SERG3]
+~g~Du musst an jedem Ziel eine Bombe abwerfen. Die Reihenfolge ist beliebig.
+
+[TEX3_3:SERG3]
+~g~Steuere den Helikopter direkt über eine Bombe, um sie aufzunehmen. Die Bombe heftet sich dann automatisch an den Helikopter.
+
+[TEX3_5:SERG3]
+~g~Wenn eine Bombe ihr Ziel verfehlt, kannst du sie erneut aufnehmen und es nochmal versuchen.
+
+[TEX3_7:SERG3]
+~g~Dann hast du noch 7 Minuten, um die restlichen Bomben im Ziel zu platzieren.
+
+[TEX3_8:SERG3]
+~g~Du hast das Ziel verfehlt! Nimm die Bombe wieder auf und versuche es nochmal!
+
+[TEX3_10:SERG3]
+~g~Wirf die Bombe über einem der Ziele ab.
+
+[TEX3_11:SERG3]
+Verbleibende Ziele:
+
+[TEX3_17:SERG3]
+~r~Die Zeit ist um. Du hast es nicht geschafft, das Gebäude zu sprengen.
+
+[TEX3_18:SERG3]
+~r~Dein Helikopter wurde zerstört! Wie willst du jetzt die Bomben transportieren?
+
+[TEX3_19:SERG3]
+~r~Deine Bombe ist im Wasser gelandet! Du brauchst ALLE 4 Bomben, um die Sprengung vorzunehmen.
+
+[TEX3_20:SERG3]
+~g~Dein Helikopter ist fast außer Reichweite. Du musst zurück zur Baustelle, um deine Arbeit zuende zu bringen!
+
+[TEX3_21:SERG3]
+~r~Dein Helikopter befindet sich außer Reichweite!
+
+[TEX3_24:SERG3]
+Drücke ~h~~k~~VEHICLE_LOOKLEFT~~w~, um den Helikopter gegen den Uhrzeigersinn zu drehen.
+
+[TEX3_25:SERG3]
+Drücke ~h~~k~~VEHICLE_LOOKLEFT~~w~, um den Helikopter im Uhrzeigersinn zu drehen.
+
+[TEX3_27:SERG3]
+~g~Über eine Haupttreppe hat man Zugang zu allen Stockwerken des Gebäudes.
+
+[TEX3_31:SERG3]
+~r~Du hast den Wagen mit den Bomben und dem ferngesteuerten Helikopter zerstört!
+
+[TEX3_32:SERG3]
+Du kannst ~h~nach hinten sehen~w~, indem du ~h~gleichzeitig ~k~~VEHICLE_LOOKLEFT~ und ~k~~VEHICLE_LOOKRIGHT~ drückst~w~.
+
+[TEX3_4:SERG3] { reVC update }
+~g~Um eine Bombe abzuwerfen, drücke die~h~ ~k~~VEHICLE_FIREWEAPON~~w~.
+
+[TEX3_29:SERG3] { reVC update }
+Um eine Bombe abzuwerfen, drücke die~h~ ~k~~VEHICLE_FIREWEAPON~.
+
+[TEX3_26:SERG3]
+Drücke die ~h~~k~~VEHICLE_BRAKE~~w~, um die Rotorgeschwindigkeit zu verringern, der Helikopter ~h~verliert dann an Höhe.
+
+[TEX3_22:SERG3]
+Drücke die ~h~~k~~VEHICLE_ACCELERATE~~w~, um die Rotorgeschwindigkeit zu erhöhen, der Helikopter ~h~gewinnt dann an Höhe.
+
+[TEX3_16:SERG3]
+~g~Begib dich zu dem ~w~TOPFUN~g~-Wagen nahe dem zum Abriss vorgesehenen Gebäude.
+
+[TEX3_33:SERG3]
+Wenn du eine Bombe aufgenommen hast, zeigt dir das Radar die Position des Ziels in Relation zu dem ferngesteuerten Helikopter.
+
+[TEX3_34:SERG3]
+Ein ~h~nach oben zeigendes Dreieck ~w~bedeutet, dass das Ziel sich in ~h~größerer Höhe ~w~befindet als der Helikopter.
+
+[TEX3_35:SERG3]
+Ein ~h~nach unten zeigendes Dreieck ~w~bedeutet, dass das Ziel sich in ~h~geringerer Höhe ~w~befindet als der Helikopter.
+
+[TEX3_36:SERG3]
+Ein ~h~Viereck ~w~ bedeutet, dass das Ziel sich auf ~h~der gleichen Höhe ~w~befindet wie der Helikopter.
+
+[TEX3_6:SERG3]
+~g~Wenn du die erste Bombe aufgenommen hast, wird der Zeitzünder aktiviert.
+
+[TEX3_28:SERG3]
+Um ~h~eine Bombe aufzunehmen~w~, steuere den Helikopter direkt über sie. Der Helikopter kann immer nur eine Bombe tragen.
+
+[TEX3_30:SERG3]
+~g~Um eine Bombe aufzunehmen, steuere den Helikopter direkt über sie. Der Helikopter kann immer nur eine Bombe tragen.
+
+[TEX3_12:SERG3]
+~g~Bombe platziert! Es bleiben nur noch 3 Ziele! Hol die nächste Bombe.
+
+[TEX3_13:SERG3]
+~g~Bombe platziert! Es bleiben nur noch 2 Ziele! Hol die nächste Bombe.
+
+[TEX3_14:SERG3]
+~g~Bombe platziert! Es bleibt nur noch 1 Ziel! Hol die nächste Bombe.
+
+[TEX3_15:SERG3]
+~r~Zeitzünder aktiviert! ~g~ Du musst die ~w~4 Bomben ~g~in der verbleibenden Zeit platzieren.
+
+[TEX3_37:SERG3]
+Zieh den ~h~ Rechten Analog-Stick zurück~w~, um die Rotorgeschwindigkeit zu erhöhen, der Helikopter ~h~ gewinnt dann an Höhe.
+
+[TEX3_38:SERG3] { reVC update }
+{Drück den ~h~ ~k~~VEHICLE_ACCELERATE~~w~, um die Rotorgeschwindigkeit zu verringern, der Helikopter ~h~ verliert dann an Höhe.}
+Drück den ~h~ Rechten Analog-Stick nach vorn~w~, um die Rotorgeschwindigkeit zu verringern, der Helikopter ~h~ verliert dann an Höhe.
+
+[TEX3_39:SERG3]
+Um eine Bombe abzuwerfen, drücke die ~h~~k~~VEHICLE_HANDBRAKE~~g~-Taste.
+
+[TEX3_40:SERG3]
+Um eine Bombe abzuwerfen, drücke die ~h~~k~~VEHICLE_HANDBRAKE~~w~-Taste.
+
+[TEX3_23:SERG3]
+Mit ~h~~k~~VEHICLE_TURRETUP~~w~ und ~h~~k~~VEHICLE_TURRETDOWN~~w~ neigst du den Helikopter in die Richtung, in die du ihn steuern willst.
+
+{=================================== MISSION TABLE TAXI1 ===================================}
+
+[FARES:TAXI1]
+FAHRTEN:
+
+[TAXI1:TAXI1]
+~g~Besorg dir einen Fahrgast.
+
+[TSCORE2:TAXI1]
+$~1~
+
+[IN_ROW:TAXI1]
+~1~ SERIEN-Bonus! $~1~
+
+[TAXI3:TAXI1]
+~r~Dein Fahrgast ist entsetzt geflohen!
+
+[TAXI7:TAXI1]
+~r~Dein Wagen ist Schrott. Repariere ihn.
+
+[TAXI4:TAXI1]
+Fahrt abgeschlossen!
+
+[TAXI5:TAXI1]
+SPEED BONUS!!
+
+[TAXI6:TAXI1]
+Taxi-Mission beendet
+
+[TAXIH1:TAXI1]
+Halte neben einem markierten Fußgänger, um ihn einsteigen zu lassen, dann bringe ihn rechtzeitig an sein Fahrtziel.
+
+[FARE1:TAXI1]
+~g~Fahrtziel ~w~'Pole Position Club' ~g~in Ocean Beach.
+
+[FARE3:TAXI1]
+~g~Fahrtziel ~w~'Marina' ~g~in Ocean Beach.
+
+[FARE4:TAXI1]
+~g~Fahrtziel ~w~'Ammu-Nation' ~g~in Ocean Beach.
+
+[FARE5:TAXI1]
+~g~Fahrtziel ~w~'Eisenwarenladen' ~g~in Washington Beach.
+
+[FARE6:TAXI1]
+~g~Fahrtziel ~w~'North Point Einkaufszentrum' ~g~in Vice Point.
+
+[MFARE1:TAXI1]
+~g~Fahrtziel ~w~'Ammu-Nation' ~g~in Downtown.
+
+[MFARE2:TAXI1]
+~g~Fahrtziel ~w~'Terminal' ~g~im Escobar International Airport.
+
+[WFARE3:TAXI1]
+~g~Fahrtziel ~w~'Sunshine Autos' ~g~in Little Havana.
+
+[WFARE4:TAXI1]
+~g~Fahrtziel ~w~'Kaufman-Taxis' ~g~in Little Haiti.
+
+[WFARE5:TAXI1]
+~g~Fahrtziel ~w~'Eisenwarenladen' ~g~in Little Havana.
+
+[WFARE6:TAXI1]
+~g~Fahrtziel ~w~'Howlin Petes Bike Emporium' ~g~in Downtown.
+
+[FARE7:TAXI1]
+~g~Fahrtziel ~w~'die Juweliere' ~g~in Vice Point.
+
+[FARE8:TAXI1]
+~g~Fahrtziel ~w~'der Strand' ~g~in Ocean Beach.
+
+[FARE9:TAXI1]
+~g~Fahrtziel ~w~'der Strand' ~g~in Washington Beach.
+
+[FARE10:TAXI1]
+~g~Fahrtziel ~w~'der Strand' ~g~in Vice Point.
+
+[FARE11:TAXI1]
+~g~Fahrtziel ~w~'das Krankenhaus' ~g~in Ocean Beach.
+
+[FARE12:TAXI1]
+~g~Fahrtziel ~w~'das Krankenhaus' ~g~in Vice Point.
+
+[FARE13:TAXI1]
+~g~Fahrtziel ~w~'die Polizeistation' ~g~in Washington Beach.
+
+[FARE14:TAXI1]
+~g~Fahrtziel ~w~'die Polizeistation' ~g~in Vice Point.
+
+[FARE15:TAXI1]
+~g~Fahrtziel ~w~'die Pizzagaststätte' ~g~in Vice Point.
+
+[WFARE7:TAXI1]
+~g~Fahrtziel ~w~'die Polizeistation' ~g~in Little Havana.
+
+[WFARE8:TAXI1]
+~g~Fahrtziel ~w~'die Polizeistation' ~g~in Downtown.
+
+[WFARE9:TAXI1]
+~g~Fahrtziel ~w~'das Krankenhaus' ~g~in Downtown.
+
+[WFARE10:TAXI1]
+~g~Fahrtziel ~w~'das Krankenhaus' ~g~in Little Havana.
+
+[WFARE11:TAXI1]
+~g~Fahrtziel ~w~'der Stadium' ~g~in Downtown.
+
+[WFARE12:TAXI1]
+~g~Fahrtziel ~w~'die Pizzagaststätte' ~g~in Little Haiti.
+
+[WFARE13:TAXI1]
+~g~Fahrtziel ~w~'die Pizzagaststätte' ~g~in Downtown.
+
+[WFARE14:TAXI1]
+~g~Fahrtziel ~w~'die Docks' ~g~in Viceport.
+
+[WFARE15:TAXI1]
+~g~Fahrtziel ~w~'die Apotheke' ~g~in Little Haiti.
+
+[FARE2:TAXI1]
+~g~Fahrtziel ~w~'Malibu Club' ~g~in Vice Point.
+
+{=================================== MISSION TABLE TAXICUT ===================================}
+
+[TAXC_A:TAXICUT]
+Schätze, sie sind der neue Besitzer.
+
+[TAXC_B:TAXICUT]
+Sind Sie 'n Mafioso? Oder vom Kartell? Sehen nicht aus wie ein Mexikaner.
+
+[TAXC_C:TAXICUT]
+Egal. Halten Sie schon endlich Ihre Predigt von wegen 'Jetzt wird alles anders',
+
+[TAXC_D:TAXICUT]
+bedrohen Sie ein paar von den Fahrern-
+
+[TAXC_E:TAXICUT]
+aber nicht Ted, der ist gerade an der Leiste operiert.
+
+[TAXC_F:TAXICUT]
+Tja, also, hier wird sich einiges ändern, Lady.
+
+[TAXC_G:TAXICUT]
+Aber nicht doch, Jungchen. Überlassen Sie das lieber mir -
+
+[TAXC_H:TAXICUT]
+Ich mach das schon seit Jahren.
+
+[TAXC_I:TAXICUT]
+Alles mal herhören.
+
+[TAXC_J:TAXICUT]
+Wir haben eine neue Geschäftsleitung, und es wird sich wieder mal einiges ändern hier.
+
+[TAXC_K:TAXICUT]
+Unsere neue Geschäftsleitung, die-
+
+[TAXC_L:TAXICUT]
+Von welcher Gang sind Sie?
+
+[TAXC_M:TAXICUT]
+Ich gehöre keiner Gang an.
+
+[TAXC_N:TAXICUT]
+Und wie heißen Sie, junger Mann?
+
+[TAXC_O:TAXICUT]
+Vercetti, Tommy Vercetti.
+
+[TAXC_P:TAXICUT]
+Unsere neue Geschäftsleitung, die Vercetti Gang,
+
+[TAXC_Q:TAXICUT]
+wird dafür sorgen, dass wir keinen Ärger kriegen.
+
+[TAXC_R:TAXICUT]
+Capiche? Ende!
+
+[TAXC_S:TAXICUT]
+Wie fanden Sie das 'Capiche'? Ich fand's gut.
+
+[TAXC_T:TAXICUT]
+Also, so ist das immer gelaufen:
+
+[TAXC_U:TAXICUT]
+Wir führen die Firma weiter wie gewohnt.
+
+[TAXC_V:TAXICUT]
+Wenn die Konkurrenz Ärger macht, gebt ihr ihnen eines auf die Mütze.
+
+[TAXC_W:TAXICUT]
+Dann geben die uns eines auf die Mütze.
+
+[TAXC_X:TAXICUT]
+Dann geben sie denen eines auf die Mütze.
+
+[TAXC_Y:TAXICUT]
+Und so weiter, und so fort. Kapiert?
+
+[TAXC_Z:TAXICUT]
+Äh, ja, ich glaub schon.
+
+[TAXC_A1:TAXICUT]
+Schnappen Sie sich ein Taxi aus der Garage, wenn Sie Lust haben.
+
+{=================================== MISSION TABLE TAXIWA1 ===================================}
+
+[OUTTIME:TAXIWA1]
+~r~Zu langsam, Mann, zu langsam!
+
+[TAX1_1:TAXIWA1]
+Ok, eine V.I.P. müsste von Starfish Island abgeholt werden. Jemand interessiert?
+
+[TAX1_2:TAXIWA1]
+Tommy hier. Ich übernehme das.
+
+[TAX1_3:TAXIWA1]
+Das ist meine Fuhre. Hau ab!
+
+[TAX1_4:TAXIWA1]
+Los, los, steigen Sie ein. Schnell!
+
+[TAX1_5:TAXIWA1]
+Ok, ok! Aber tun Sie mir nichts!
+
+[TAXW1_1:TAXIWA1]
+~g~Hol die V.I.P. auf Starfish Island ab.
+
+[TAXW1_2:TAXIWA1]
+~g~Hol die V.I.P. zurück! Schalte den anderen Wagen aus!
+
+[TAXW1_3:TAXIWA1]
+~r~Die V.I.P. ist Geschichte!
+
+[TAXW1_4:TAXIWA1]
+~r~Die V.I.P. wurde abgesetzt!
+
+[TAXW1_6:TAXIWA1]
+~g~Bring die V.I.P zum Flughafen!
+
+{=================================== MISSION TABLE TAXIWA2 ===================================}
+
+[TAX2_1:TAXIWA2]
+An alle Wagen. Wir kriegen nirgends Fahrgäste. Was ist los mit euch?
+
+[TAX2_2:TAXIWA2]
+VC-Taxi ist dauernd schneller als wir. Die haben einfach zu viele Autos. Keine Chance.
+
+[TAX2_3:TAXIWA2]
+Mr. Vercetti, wenn Sie zufällig mithören: Sie müssen ein paar VC-Taxis ausschalten, sonst sind wir pleite!
+
+[TAXW2_1:TAXIWA2]
+~g~Schalte 3 Taxis der Konkurrenz aus!
+
+{=================================== MISSION TABLE TAXIWA3 ===================================}
+
+[TAX3_1:TAXIWA3]
+Wagen 13, eine Miss Cortez möchte von Ihnen ganz persönlich in Downtown abgeholt werden.
+
+[TAX3_2:TAXIWA3]
+Ok, verstanden. Wagen 13 Ende.
+
+[TAX3_3:TAXIWA3]
+Hmmm, keine Spur von Mercedes...
+
+[TAXW3_3:TAXIWA3]
+~g~Schalte das Taxi des Anführers aus!
+
+[TAXW3_2:TAXIWA3]
+~g~Halte durch, bis die Zeit abgelaufen ist.
+
+[TAX_AS1:TAXIWA3]
+TAXIUNTERNEHMEN ERWORBEN
+
+[TAX_AS2:TAXIWA3]
+~g~Kaufman-Taxis generiert nun bis zu $~1~ Einkünfte. Hol dir das Geld regelmäßig ab.
+
+[TAX3_4:TAXIWA3]
+Wird Zeit, dass der Schutzengel von Kaufman-Taxis eine vor den Latz kriegt!
+
+[TAX3_5:TAXIWA3]
+Hey, Freundchen, dir zieh ich das Fell über die Ohren!
+
+{ reVC updates }
{ new languages }
[FEL_JAP]
JAPANISCH
@@ -8022,7 +14588,7 @@ MIP MAPPING
KANTENGLÄTTUNG
[FED_FIL]
-TEXTURFILTER
+TEXTURFILTERUNG
[FED_BIL]
BILINEAR
@@ -8077,7 +14643,6 @@ MISSION WIEDERHOLEN
[FESZ_RM]
WIEDERHOLEN?
-{ more graphics }
[FED_VPL]
FAHRZEUG-PIPELINE
@@ -8117,19 +14682,11 @@ PS2
[FEM_XBX]
XBOX
-[FEM_AUT] { aspect ratio related }
-AUTO
-
-{ controls }
[FEC_IVP]
PAD VERTIKAL INVERTIEREN
-{ map }
-[FEM_TWP]
-Wegpunkt umschalten
-
-[FEA_FMN]
-RADIO AUS
+[FEM_NON]
+NONE
[FEC_DS2]
DUALSHOCK 2
@@ -8149,36 +14706,12 @@ XBOX ONE CONTROLLER
[FEC_TYP]
GAMEPAD-TYP
-[FEC_CCF]
-KONFIGURATION
-
-[FEC_CF1]
-KONFIGURATION 1
-
-[FEC_CF2]
-KONFIGURATION 2
-
-[FEC_CF3]
-KONFIGURATION 3
-
-[FEC_CF4]
-KONFIGURATION 4
-
-[FEC_CDP]
-CONTROLLER-ANZEIGE
-
-[FEC_ONF]
-Zu Fuß
-
-[FEC_INC]
-Im Auto
-
-[FEC_VIB]
-Vibration :
-
[FET_AGS]
KONTROLLEREINSTELLUNGEN
+[FEM_AUT] { aspect ratio related }
+AUTO
+
[FEM_PED]
PED DENSITY
diff --git a/utils/gxt/italian.txt b/utils/gxt/italian.txt
index 803b7fbf..da135892 100644
--- a/utils/gxt/italian.txt
+++ b/utils/gxt/italian.txt
@@ -5,155 +5,53 @@
unnecessary edits like rephasing because you think it suits better for your taste.
}
-[LETTER1]
-abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789"$,.'-?!!SDBFàèéìòùÀÈÉÌÒÙ
-
-[DEFNAM]
-Claude----------------------
-
[IN_VEH]
~g~Ehi! Torna nel veicolo!
-[IN_VEH2]
-~g~Avrai bisogno di un veicolo per questo lavoro!
-
-[IN_BOAT]
-~g~Hai bisogno di un'imbarcazione per questo lavoro!
-
[HEY]
~g~Non procedere da solo, stai insieme ai tuoi compagni!
-[HEY2]
-~g~Non dividetevi, tieni il gruppo compatto!
-
-[HEY3]
-~g~Hai abbandonato il tuo uomo! Torna indietro e recupera 8-Ball!
-
-[HEY4]
-~g~Se abbandoni Misty, Luigi ti fa a pezzi! Vai a recuperarla!
-
-[HEY5]
-~g~Manca una ragazza alla lista! Vai a recuperarla!
-
-[HEY6]
-~g~Hai perso l'onore insieme a Yakuza Kanbu. Devi proteggerlo!
-
-[HEY7]
-~g~Un'arma extra può tornare utile. Torna indietro e recupera il tuo contatto!
-
-[HEY8]
-~g~Forse non hai ben presente il concetto di protezione: non abbandonare il vecchietto orientale!
-
-[HEY9]
-~g~Vuoi sapere cosa si dice in giro? Fa'una visita al tuo contatto!
-
-[HELP2_A]
-Premi il ~h~tasto /~w~ mentre corri per effettuare uno ~h~scatto~w~.
-
[HELP3]
Ricorda che puoi eseguire uno scatto solo per brevi tratti.
-[HELP4_A]
-Premi il ~h~tasto ~k~~VEHICLE_ACCELERATE~~w~ per ~h~accelerare~w~.
-
[HELP4_D]
Sposta la ~h~levetta analogica destra~w~ verso l'alto per ~h~accelerare~w~.
-[HELP5_A]
-Premi il ~h~tasto ~k~~VEHICLE_BRAKE~~w~ per ~h~frenare~w~ o, se il veicolo è fermo, per inserire la ~h~retromarcia~w~.
-
[HELP5_D]
Sposta la ~h~levetta analogica destra~w~ verso il basso per ~h~frenare~w~ o, se il veicolo è fermo, per inserire la ~h~retromarcia~w~.
-[HELP6_A]
-Premi il ~h~tasto ~k~~VEHICLE_HANDBRAKE~~w~ per tirare il ~h~freno a mano~w~.
-
-[HELP6_C]
-Premi il ~h~tasto ~k~~VEHICLE_HANDBRAKE~~w~ per tirare il ~h~freno a mano~w~.
-
-[HELP6_D]
-Premi il ~h~tasto ~k~~VEHICLE_HANDBRAKE~~w~ per tirare il ~h~freno a mano~w~.
-
[HELP7_A]
-Tieni premuto il ~h~tasto ~k~~PED_LOCK_TARGET~~w~ per ~h~mirare~w~ con il fucile di precisione.
+Tieni premuto il ~h~~k~~PED_LOCK_TARGET~~w~ per ~h~mirare~w~ con il fucile di precisione.
[HELP7_D]
-Tieni premuto il ~h~tasto ~k~~PED_LOCK_TARGET~~w~ per ~h~mirare~w~ con il fucile di precisione.
-
-[HELP8_A]
-Premi il ~h~tasto ~k~~PED_SNIPER_ZOOM_IN~~w~ per ~h~zoomare~w~ col fucile e il ~h~tasto ~k~~PED_SNIPER_ZOOM_OUT~~w~ per ~h~allargare il campo~w~.
-
-[HELP9_A]
-Premi il ~h~tasto ~k~~PED_FIREWEAPON~~w~ per ~h~sparare~w~ con il fucile di precisione.
+Tieni premuto il ~h~~k~~PED_LOCK_TARGET~~w~ per ~h~mirare~w~ con il fucile di precisione.
[HELP10]
-Questo distintivo indica che hai un livello di sospetto.
+Questa stella indica il tuo livello di sospetto.
[HELP11]
-Più distintivi hai, maggiore è il tuo livello di sospetto.
+Più stelle hai, maggiore è il tuo livello di sospetto.
[HELP13]
-In alcuni casi potresti dover utilizzare passaggi non indicati sul radar.
+In alcuni casi potresti dover utilizzare passaggi non segnati sul radar.
[TIMER]
-Questa è una missione a tempo: devi completarla prima che il contatore raggiunga lo zero.
-
-[MISTY1]
-~r~Mistry è pronta per l'obitorio!
-
-[OUT_VEH]
-~g~Esci dal veicolo!
-
-[GARAGE]
-Porta l'auto dentro il garage e poi esci a piedi all'esterno.
-
-[WANTED1]
-~g~Semina i poliziotti per perdere il tuo livello di sospetto.
-
-[NODOORS]
-~g~Non sono sardine! Trova un veicolo con sedili a sufficienza.
-
-[TRASH]
-~g~Hai ridotto proprio male il tuo veicolo! Vedi di farlo riparare!
-
-[WRECKED]
-~g~Il veicolo è a pezzi!
+Questa è una missione a tempo: devi portarla a termine prima che il contatore raggiunga lo zero.
[HORN]
~g~Suona il clacson.
-[HORN4]
-Premi il ~h~tasto R3~w~ per attivare il ~h~clacson~w~.
-
[NOMONEY]
~g~Ti servono più soldi!
-[OUTTIME]
-~r~Troppo lento, troppo lento!
-
-[SPOTTED]
-~r~Ti hanno visto!
-
[REWARD]
RICOMPENSA ~1~$
-[GAMEOVR]
-GAME OVER
-
-[Z]
-Valore asse Z: ~1~
-
[M_FAIL]
MISSIONE FALLITA!
[M_PASS]
-MISSIONE COMPIUTA! ~1~$
-
-[O_PASS]
-LAVORO OCCASIONALE ESEGUITO!
-
-[O_FAIL]
-LAVORO OCCASIONALE FALLITO!
+MISSIONE COMPLETATA! ~1~$
[DEAD]
MASSACRATO!
@@ -161,15 +59,27 @@ MASSACRATO!
[BUSTED]
BECCATO!
-[S_PROMP]
-Quando non stai eseguendo una missione, puoi ~h~salvare la partita qui~w~ in questo modo il tempo avanzerà di sei ore.
+[WEATHE1]
+FORZA TEMPO SOLEGGIATO
+
+[WEATHE2]
+FORZA TEMPO MOLTO SOLEGGIATO
+
+[WEATHE3]
+FORZA TEMPO NUVOLOSO
+
+[WEATHE4]
+FORZA TEMPO PIOVOSO
+
+[WEATHE5]
+FORZA TEMPO NEBBIOSO
+
+[WEATHE6]
+TEMPO NORMALE
[NUMBER]
~1~
-[SCORE]
-~1~$
-
[LOADCAR]
CARICAMENTO VEICOLO... (PREMI L1 PER ANNULLARE)
@@ -177,10 +87,10 @@ CARICAMENTO VEICOLO... (PREMI L1 PER ANNULLARE)
Veicoli disabilitati.
[CARS_ON]
-Veicoli attivati.
+Veicoli abilitati.
[TEXTXYZ]
-Scrittura delle coordinate sul file...
+Scrittura coordinate sul file...
[CHEATON]
Modalità trucchi attivata
@@ -188,47 +98,14 @@ Modalità trucchi attivata
[CHEATOF]
Modalità trucchi disattivata
-[UZI_IN]
-L'Uzi adesso e' disponibile da AmmuNation!
-
[IMPORT1]
Esci fuori e aspetta il tuo veicolo.
-[PAGEB1]
-Pistola depositata nel nascondiglio
-
-[PAGEB2]
-Uzi depositato nel nascondiglio
-
-[PAGEB3]
-Armatura depositata nel nascondiglio
-
-[PAGEB4]
-Fucile a pompa depositato nel nascondiglio
-
-[PAGEB5]
-Granate depositate nel nascondiglio
-
-[PAGEB6]
-Molotov depositate nel nascondiglio
-
-[PAGEB7]
-AK47 depositato nel nascondiglio
-
-[PAGEB8]
-Fucile di precisione depositato nel nascondiglio
-
-[PAGEB9]
-M16 depositato nel nascondiglio
-
-[PAGEB10]
-Lanciamissili depositato nel nascondiglio
-
[PAGEB11]
Lanciafiamme depositato nel nascondiglio
[WANT_A]
-Non puoi essere arrestato se il tuo ~h~livello di sospetto~w~ è nullo.
+Verrai arrestato solo se hai un ~h~livello di sospetto~w~.
[WANT_B]
Il tuo ~h~livello di sospetto~w~ è rappresentato da una riga di stelle nell'angolo superiore destro dello schermo.
@@ -252,7 +129,7 @@ Se vieni ~h~'beccato'~w~, verrai portato alla più vicina stazione di polizia.
I poliziotti prenderanno tutte le tue armi e parte dei tuoi risparmi come bustarella.
[WANT_I]
-Qualsiasi missione stessi affrontando, sarà considerata fallita.
+Qualsiasi missione stavi affrontando verrà considerata come fallita.
[WANT_J]
Scoprirai alcuni modi per ridurre il tuo livello di sospetto procedendo nel gioco.
@@ -269,6719 +146,6927 @@ Perderai tutte le tue armi e i dottori prenderanno parte dei tuoi risparmi per r
[HEAL_E]
Scoprirai alcuni modi per curarti o per proteggerti dagli attacchi procedendo nel gioco.
-[DAM]
-DANNO:
+[SAVE1]
+Passa attraverso la corona per ~h~salvare la partita~w~. Non puoi salvare durante una missione.
-[KILLS]
-UCCISIONI:
+[SAVE2]
+Qualsiasi veicolo parcheggiato nel garage verrà salvato insieme alla partita.
-[FARES]
-CLIENTI:
+[AMMU]
+Entra in Ammu-Nation per comprare un'arma.
-[BULL]
-LINGOTTI:
+[R_TIME]
+TEMPO DI GARA:
-[EVID]
-PROVE:
+[PROP_1]
+Non hai abbastanza soldi per comprare questa proprietà.
-[HEALTH]
-CONDIZIONI VEICOLO:
+[PROP_2]
+Non puoi comprare una proprietà mentre sei in missione.
-[COLLECT]
-RACCOLTO:
+[IND_ZON]
+Vice City Beach
-[BOMB]
-Guida il veicolo dentro un'armeria per installare una ~h~bomba~w~. Costo - ~h~1000$~w~.
+[COM_ZON]
+Vice City Mainland
-[SAVE1]
-Passa attraverso la porta per ~h~salvare la partita~w~. Non puoi salvare durante una missione.
+[BEACH1]
+Ocean Beach
-[SAVE2]
-Qualsiasi veicolo parcheggiato nel garage verrà salvato insieme alla partita.
+[BEACH2]
+Washington Beach
-[AMMU]
-Entra in AmmuNation per comprare un'arma.
+[BEACH3]
+Vice Point
-[BRIDGE1]
-Quando verrà riparato il ponte Callahan, potrai raggiungere Staunton Island.
+[GOLFC]
+Leaf Links
-[TUNNEL]
-Quando il sottopassaggio Porter verrà inaugurato, potrai raggiungere Staunton Island.
+[STARI]
+Starfish Island
-[LUIGI]
-MISSIONI LUIGI
+[DOCKS]
+Porto
-[TONI]
-MISSIONI TONI
+[HAVANA]
+Little Havana
-[JOEY]
-MISSIONI JOEY
+[HAITI]
+Little Haiti
-[FRANK]
-MISSIONI SALVATORE
+[PORNI]
+Prawn Island
-[DIABLO]
-MISSIONI DIABLO
+[DTOWN]
+Downtown
-[ASUKA]
-MISSIONI ASUKA
+[VICE_C]
+Vice City
-[B_SITE]
-MISSIONI SUBURBANE ASUKA
+[A_PORT]
+Escobar International
-[KENJI]
-MISSIONI KENJI
+[JUNKY]
+Discarica
-[RAY]
-MISSIONI RAY
+[PISTOL]
+Pistola
-[LOVE]
-MISSIONI LOVE
+[PYTHON]
+.357
-[YARDIE]
-MISSIONI YARDIE
+[UZI]
+Uz-1
-[HOOD]
-MISSIONI HOOD
+[TEC9]
+Tec 9
-[CITYZON]
-Città di Liberty
+[M4]
+M4
-[IND_ZON]
-Portland
+[INGRAM]
+Mac
-[PORT_W]
-Callahan Point
+[MP5]
+MP
-[PORT_S]
-Molo atlantico
+[RUGER]
+Kruger
-[PORT_E]
-Porto di Portland
+[SNIPE]
+Fucile di precisione
-[PORT_I]
-Trenton
+[GRENADE]
+Granate
-[S_VIEW]
-Portland View
+[SHOTGN1]
+Fucile a pompa
-[CHINA]
-Chinatown
+[SHOTGN2]
+S.P.A.S. 12
-[EASTBAY]
-Spiaggia di Portland
+[SHOTGN3]
+Fucile a canne mozze
-[LITTLEI]
-Saint Mark
+[ARMOUR]
+Giubbotto antiproiettile
-[REDLIGH]
-Distretto a luci rosse
+[LASER]
+.308 Fucile di precisione
-[TOWERS]
-Hepburn Heights
+[BASEBAT]
+Mazza da baseball
-[HARWOOD]
-Harwood
+[HAMMER]
+Martello
-[ROADBR1]
-Ponte Callahan
+[SCREWD]
+Cacciavite
-[ROADBR2]
-Ponte Callahan
+[CLEVER]
+Mannaia
-[TUNNELP]
-Sottopassaggio Porter
+[MACHETE]
+Macete
-[BOMB1]
-Garage di 8-Ball
+[KNIFE]
+Coltello
-[COM_ZON]
-Staunton Island
+[KATANA]
+Katana
-[STADIUM]
-Aspatria
+[CHAINSA]
+Motosega
-[HOSPI_2]
-Rockford
+[G_COST]
+~1~$
-[UNIVERS]
-Campus Liberty
+[CAR_1]
+Ambulanza
-[CONSTRU]
-Fort Staunton
+[MALIBU]
+Il club Malibu
-[PARK]
-Parco Belleville
+[MANSION]
+Villa di Diaz
-[COM_EAS]
-Newport
+[TMANS]
+Chez Tommy
-[SHOPING]
-Bedford Point
+[STRIP]
+Il club Pole Position
-[YAKUSA]
-Torrington
+[MALL1]
+North Point Mall
-[SUB_ZON]
-Shoreside Vale
+[BANKINT]
+El Banco Corrupto Grande
-[AIRPORT]
-Aeroporto Francis
+[RANGE]
+Poligono di tiro
-[PROJECT]
-Giardini Wichita
+[POL_HQ]
+Polizia di VC
-[SUB_IND]
-Pike Creek
+[INT_B]
+Un vecchio amico
-[SWANKS]
-Cedar Grove
+[INTB_1]
+~g~Vai all'ufficio degli avvocati.
-[BIG_DAM]
-Diga Cochrane
+[LAW_1]
+Il party
-[SUB_ZO2]
-Shoreside Vale
+[LAW_2]
+Rissa nel vicolo
-[SUB_ZO3]
-Shoreside Vale
+[LAW_3]
+Furia sulla giuria
-[CAR_1]
-Ambulanza
+[LAW_4]
+Sommossa
-[CAR_2]
-Camion dei pompieri
+[COL_1]
+Fottuto traditore
-[CAR_3]
-Polizia
+[COL_2]
+Sparatoria al Mall
-[CAR_4]
-Cellulare
+[COL_3]
+Angeli custodi
-[CAR_5]
-Caserma
+[COL_4]
+Sissignore, signore!
-[CAR_6]
-Rhino
+[COL_5]
+Tutti sul ponte!
-[CAR_7]
-Auto dell'FBI
+[COK_1]
+L'inseguimento
-[CAR_8]
-Securicar
+[COK_2]
+Phnom Penh '86
-[CAR_9]
-Moonbeam
+[COK_3]
+La barca più veloce
-[CAR_10]
-Coach
+[COK_4]
+Domanda e offerta
-[CAR_11]
-Flatbed
+[KENT_1]
+Il braccio della morte
-[CAR_12]
-Linerunner
+[ASS_1]
+Eliminazione
-[CAR_13]
-Trashmaster
+[BUD_1]
+Estorsione
-[CAR_14]
-Patriot
+[BUD_2]
+Rissa al bar
-[CAR_15]
-Mr Whoopee
+[BUD_3]
+Cop Land
-[CAR_16]
-Mule
+[CAP_1]
+Fuori l'esattore
-[CAR_17]
-Yankee
+[FIN_1]
+Tieniti stretto gli amici...
-[CAR_18]
-Pony
+[BANK_1]
+Senza via di fuga?
-[CAR_19]
-Bobcat
+[BANK_2]
+Il tiratore
-[CAR_20]
-Rumpo
+[BANK_3]
+L'autista
-[CAR_21]
-Blista
+[BANK_4]
+La rapina
-[CAR_22]
-Dodo
+[CNT_1]
+Sfornare verdoni
-[CAR_23]
-Bus
+[CNT_2]
+Colpire il corriere
-[CAR_24]
-Sentinel
+[PORN_1]
+Giro di reclutamento
-[CAR_25]
-Cheetah
+[PORN_2]
+Il dodo del dildo
-[CAR_26]
-Banshee
+[PORN_3]
+La foto di Martha
-[CAR_27]
-Stinger
+[PORN_4]
+Riflettori sul punto G
-[CAR_28]
-Infernus
+[TAX_1]
+Taxi di Kaufman
-[CAR_29]
-Esperanto
+[TAXI_1]
+VIP
-[CAR_30]
-Kuruma
+[TAXI_2]
+Rivalità amichevole
-[CAR_31]
-Stretch
+[TAXI_3]
+Cabmaggedon
-[CAR_32]
-Familiare
+[ICE_1]
+Distribuzione
-[CAR_33]
-Landstalker
+[TEX_1]
+Ferro quattro
-[CAR_34]
-Manana
+[TEX_2]
+Due in un colpo
-[CAR_35]
-Idaho
+[TEX_3]
+Il demolitore
-[CAR_36]
-Stallion
+[PHIL_1]
+Corriere delle armi
-[CAR_37]
-Taxi
+[PHIL_2]
+Broda e Saigon
-[CAR_38]
-Vecchio taxi
+[BIKE_1]
+Due ruote d'acciaio
-[CAR_39]
-Maggiolino
+[BIKE_2]
+Bollire la pentola
-[LUIGIS]
-Club Luigi's
+[BIKE_3]
+Valla a prendere!
-[GOAWAY]
-~g~Stai già svolgendo una missione!
+[ROCK_1]
+Il succo dell'amore
-[LUIGGO]
-~g~Luigi sta intervistando delle nuove ragazze. Torna più tari!
+[ROCK_2]
+Killer psicotico
-[JOEYGO]
-~g~Joey è fuori città con Misty. Passa più tardi!
+[ROCK_3]
+Giro pubblicitario
-[TONIGO]
-~g~Toni ha portato sua madre a teatro. Passa un'altra volta!
+[ROCK_4]
+Love Fist!
-[KEMUGO]
-~g~Maria e Kemuri sono impegnati la momento. Passa più tardi!
+[HAT_1]
+Le polveri della zia
-[KENJGO]
-~g~Kenji è a una riunione della Yakuza. Passa un'altra volta!
+[HAT_2]
+Bombardamento!
-[RAYGO]
-~g~Ray è andato a un centro estetico. Passa un'altra volta!
+[HAT_3]
+Tutto di nascosto
-[LOVEGO]
-~g~Donald Love si sta occupando di affari urgenti. Prendi un appuntamento più tardi!
+[CUB_1]
+Gara sull'acqua
-[KENSGO]
-~g~Kenji e' occupato! Torna più tardi!
+[CUB_2]
+Carne da cannone
-[ASUSGO]
-~g~Asuka adesso non è disponibile!
+[CUB_3]
+Battaglia navale
-[HOODGO]
-~g~Gli Hood non sono disponibili!
+[CUB_4]
+Voodoo a doppio taglio
-[WRONGT1]
-~g~Passa tra le 05:00 e le 21:00 per un lavoro
+[JOB_1]
+Morte per strada
-[WRONGT2]
-~g~Passa tra le 06:00 e le 14:00 per un lavoro
+[JOB_2]
+Elimina la moglie
-[WRONGT3]
-~g~Passa tra le 15:00 e le 00:00 per un lavoro
+[JOB_3]
+Incidente...
-[GUN_1A]
-Usa il ~h~tasto ~k~~PED_CYCLE_WEAPON_RIGHT~~w~ e il ~h~tasto ~k~~PED_CYCLE_WEAPON_LEFT~~w~ per passare in rassegna le armi.
+[JOB_4]
+L'ultima partenza
-[GUN_2A]
-Tieni premuto il ~h~tasto ~k~~PED_LOCK_TARGET~~w~ per la ~h~mira automatica~w~ e premi il ~h~tasto ~k~~PED_FIREWEAPON~~w~ per sparare! Allenati con i bersagli...
+[JOB_5]
+Risoluzione
-[GUN_2C]
-Tieni premuto il ~h~tasto ~k~~PED_LOCK_TARGET~~w~ per la ~h~mira automatica~w~ e premi il ~h~tasto ~k~~PED_FIREWEAPON~~w~ per sparare! Allenati con i bersagli...
+[ANSWER]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per rispondere al cellulare.
-[GUN_2D]
-Tieni premuto il ~h~tasto ~k~~PED_LOCK_TARGET~~w~ per la ~h~mira automatica~w~ e premi il ~h~tasto ~k~~PED_FIREWEAPON~~w~ per sparare! Allenati con i bersagli...
+[MOB_01A]
+Ciao vecchio mio! Sono Paul. Potrei avere delle informazioni per te, ma ti voglio parlare in privato.
-[GUN_3A]
-Mentre tieni premuto il ~h~tasto ~k~~PED_LOCK_TARGET~~w~, premi il ~h~tasto ~k~~PED_CYCLE_TARGET_LEFT~~w~ o il ~h~tasto ~k~~PED_CYCLE_TARGET_RIGHT~~w~ per cambiare bersaglio.
+[MOB_01B]
+Mi sto godendo un aperitivo al Malibu.
-[GUN_3B]
-Mentre tieni premuto il ~h~tasto ~k~~PED_LOCK_TARGET~~w~, premi il ~h~tasto ~k~~PED_CYCLE_TARGET_LEFT~~w~ o il ~h~tasto ~k~~PED_CYCLE_TARGET_RIGHT~~w~ per cambiare bersaglio.
+[MOB_01C]
+Credo che mi dovrai un favore o due dopo questo, carino. Ci vediamo dopo.
-[GUN_4A]
-Mentre tieni premuto il ~h~tasto ~k~~PED_LOCK_TARGET~~w~, puoi camminare o correre tenendo sotto mira il bersaglio.
+[MOB_02A]
+Ssssnniiiiffffff! Ehi! Tommy? Ciao, Tommy!
-[GUN_4B]
-Mentre tieni premuto il ~h~tasto ~k~~PED_LOCK_TARGET~~w~, puoi camminare o correre tenendo sotto mira il bersaglio.
+[MOB_02B]
+Ci sono dei problemi alla stamperia. Faresti meglio ad andare a controllare.
-[GUN_5]
-Puoi far pratica sparando a questi bersagli di carta. Quando hai finito, riprendi la missione.
+[MOB_02C]
+Un qualche tipo di casino. C'è qualcosa che non va. Devo andare.
-[TAXI1]
-~g~Trova un passeggero.
+[MOB_03A]
+Mr. Vercetti? Ho qui davanti a me un pezzo di carta che afferma
-[FARE1]
-~g~Destinazione: ~w~'Meeouch Sex Kitten Club' ~g~nel distretto a luci rosse.
+[MOB_03B]
+che lei si è preso carico dei debiti di BJ's Auto.
-[FARE2]
-~g~Destinazione: ~w~'Supa Save' ~g~a Portland View.
+[MOB_03C]
+Con l'improvvisa scomparsa di BJ, non ho altra scelta
-[FARE3]
-~g~Destinazione: ~w~'l'auditorio della scuola' ~g~a Chinatown.
+[MOB_03D]
+che ritenerla responsabile delle sue debolezze finanziarie.
-[FARE4]
-~g~Destinazione: ~w~'Greasy Joe's Cafe' ~g~a Callahan Point.
+[MOB_03E]
+Finché questo debito non sarà ripagato,
-[FARE5]
-~g~Destinazione: ~w~'AmmuNation' ~g~nel distretto a luci rosse.
+[MOB_03F]
+dovrà considerare le strade di Vice City non molto amichevoli.
-[FARE6]
-~g~Destinazione: ~w~'Easy Credit Autos' ~g~a Saint Mark.
+[MOB_04A]
+Come butta, amico?
-[FARE7]
-~g~Destinazione: ~w~'Woody's topless bar' ~g~nel distretto a luci rosse.
+[MOB_04B]
+Ascolta Tommy, mi sono dimenticato di dirti che avremo bisogno di qualche gorilla extra per il concerto.
-[FARE8]
-~g~Destinazione: ~w~'Marcos Bistro' ~g~a Saint Mark.
+[MOB_04C]
+C'è una banda di motociclisti e sarebbero una perfetta pubblicità.
-[FARE9]
-~g~Destinazione: ~w~'Garage importazioni-esportazioni' ~g~al porto di Portland.
+[MOB_04D]
+Occupatene tu e ti farò accedere al back stage dello spettacolo, OK?
-[FARE10]
-~g~Destinazione: ~w~'Punk Noodles' ~g~a Chinatown.
+[MOB_05A]
+Ehi, sono Mitch! Ottimo lavoro, Tommy: è bello riavere indietro la mia vecchia bambina.
-[FARE12]
-~g~Destinazione: ~w~'lo stadio di football' ~g~in Aspatria.
+[MOB_05B]
+Dì a Mr. Kent Paul che avrà la sorveglianza per lo spettacolo.
-[FARE13]
-~g~Destinazione: ~w~'la chiesa' ~g~a Bedford Point.
+[MOB_05C]
+Hai la mia parola.
-[FARE14]
-~g~Destinazione: ~w~'il Casinò' ~g~in Torrington.
+[MOB_05D]
+Adesso tieniti fuori dai guai.
-[FARE15]
-~g~Destinazione: ~w~'università di Liberty' ~g~al campus di Liberty.
+[MOB_06A]
+Tommy, si è parlato molto di te, ragazzo.
-[FARE16]
-~g~Destinazione: ~w~'il grande magazzino' ~g~nel parco Belleville.
+[MOB_06B]
+Pensavo ti servisse un po' di calore, per cui la zia Poulet ti ha preparato una bella zuppa, hmmm?
-[FARE17]
-~g~Destinazione: ~w~'il museo' ~g~a Newport.
+[MOB_06C]
+Passa a trovarmi in cucina ogni tanto, OK Tommy?
-[FARE18]
-~g~Destinazione: ~w~'AmCo Building' ~g~a Torrington.
+[MOB_08A]
+Ehi, Tommy, ho pensato che ti potessero servire dei consigli.
-[FARE19]
-~g~Destinazione: ~w~'Bolt Burgers' ~g~a Bedford Point.
+[MOB_08B]
+Quando hai un'operazione in corso, dovrai passare a ritirare i soldi della settimana.
-[FARE20]
-~g~Destinazione: ~w~'il parco' ~g~a Belleville.
+[MOB_08C]
+Lascia pensare ai ragazzi che abbiano il controllo del posto e loro cercheranno di ridurne i profitti, OK?
-[FARE21]
-~g~Destinazione: ~w~'Aeroporto Francis'~g~.
+[MOB_08D]
+Ehi Ken, so come far funzionare le cose, OK.
-[FARE22]
-~g~Destinazione: ~w~'la diga di Cochrane'~g~.
+[MOB_08E]
+OK, OK! Lo so che lo sai. Lo so. Stavo solo...
-[FARE24]
-~g~Destinazione: ~w~'l'ospedale' ~g~a Pike Creek.
+[MOB_08F]
+Ti stavo solo ricordando che lo so, cioè che tu sai che io so.
-[FARE25]
-~g~Destinazione: ~w~'il parco' ~g~a Shoreside Vale.
+[MOB_08G]
+Solo per ricordartelo!
-[FARE26]
-~g~Destinazione: ~w~'North West Towers' ~g~ai giardini Wichita.
+[MOB_08H]
+Sì Ken, va bene...
-[NEW_TAX]
-PIÙ GRANDI! PIÙ VELOCI! PIÙ ROBUSTI! I nuovi taxi Borgnine disponibili ad Harwood. Chiamate subito il numero 555-BORGNINE!
+[MOB_09A]
+Ehi Leo! Ho del lavoro per te!
-[TSCORE2]
-~1~$
+[MOB_09B]
+Non sono Leo!
-[IN_ROW]
-Bonus ~1~ di seguito! ~1~$
+[MOB_09C]
+Ehi, se Leo scopre che hai il suo telefono, ti farà a pezzi!
-[TTUTOR]
-Premi il ~h~tasto ~k~~TOGGLE_SUBMISSIONS~~w~ per attivare o disattivare le missioni Taxi.
+[MOB_09D]
+Forse Leo è già morto. Forse ho ucciso Leo e ho preso il suo telefono: non ci hai pensato, idiota?
-[TTUTOR2]
-Premi il ~h~tasto ~k~~TOGGLE_SUBMISSIONS~~w~ per attivare o disattivare le missioni Taxi.
+[MOB_09E]
+Hai ucciso Leo? Devi avere due grandi cojones. Vuoi lavorare per me?
-[A_TIME]
-+~1~ secondi
+[MOB_09F]
+Passa dal bar di mio padre a Little Havana e ne possiamo parlare.
-[A_FULL]
-~r~Ambulanza piena!
+[MOB_10A]
+Tommy! Senti, devo chiederti un favore.
-[A_RANGE]
-~g~Sei fuori dal raggio d'azione della radio. Ritorna in prossimità dell'ospedale!
+[MOB_10B]
+Steve! Come va il film?
-[FTUTOR]
-Premi il ~h~tasto ~k~~TOGGLE_SUBMISSIONS~~w~ per attivare o disattivare le missioni Camion dei pompieri.
+[MOB_10C]
+Bene, bene. Senti ho, ehm, abbiamo bisogno di una scena di inseguimento, ma siamo a corto di denaro.
-[FTUTOR2]
-Premi il ~h~tasto ~k~~TOGGLE_SUBMISSIONS~~w~ per attivare o disattivare le missioni Camion dei pompieri.
+[MOB_10D]
+Ho lasciato qualche macchina in città. Sono certo che sai cosa fare.
-[F_PASS1]
-Incendio spento!
+[MOB_10E]
+OK Steve, terrò un occhio aperto. Ci vediamo!
-[F_RANGE]
-~g~Sei fuori dal raggio d'azione della radio. Ritorna in prossimità della stazione dei pompieri!
+[MOB_11A]
+Ciao figliolo, t'ho chiamato per darti un consiglio.
-[C_BREIF]
-~g~Sospetto visto in prossimità dell'area ~a~.
+[MOB_11B]
+Ciao Avery. Come butta?
-[C_RANGE]
-~g~Sei fuori dal raggio d'azione della radio. Ritorna in prossimità della stazione di polizia!
+[MOB_11C]
+Ci sono un sacco di opportunità in questa città se possiedi le proprietà giuste, mi segui?
-[DODO_FT]
-Hai volato per ~1~ secondi!
+[MOB_11D]
+Tutto chiaro...
-[EBAL_A]
-Conosco un posto nei dintorni del distretto a luci rosse dove si puo'parlare,
+[MOB_11E]
+Volevo dirti di tenere gli occhi aperti: potresti trovare l'occasione giusta per far soldi. Ci becchiamo!
-[EBAL_A1]
-ma le mie mani sono a pezzi, quindi è meglio se guidi te, fratello.
+[MOB_11F]
+Ciao, Avery.
-[EBAL_1]
-Premi il ~h~tasto ~k~~VEHICLE_ENTER_EXIT~~w~ per ~h~entrare~w~ o ~h~uscire~w~ da un veicolo.
+[MOB12_A]
+Ehi Tommy! Sono Avery! Ascolta: sono piuttosto incasinato al momento
-[EBAL_1B]
-Premi il ~h~tasto ~k~~VEHICLE_ENTER_EXIT~~w~ per ~h~entrare~w~ o ~h~uscire~w~ da un veicolo.
+[MOB12_B]
+e un mio rappresentante ha bisogno di un accompagnatore fino a Gator Keys.
-[EBAL_2]
-~g~Rientra in macchina!
+[MOB12_C]
+Sto cercando di acquistare del terreno da quelle parti, per cui mando qualcuno in avanscoperta.
-[EBAL_3]
-Questo è il ~h~radar~w~: usalo per orientarti nella città. Segui il ~h~puntino~w~ sul ~h~radar~w~ per trovare il nascondiglio!
+[MOB12_D]
+Mi faresti un favore? Potresti controllare che arrivi a destinazione tutto intero?
-[EBAL_D]
-Conosco un tipo, è nel giro. Si chiama Luigi.
+[MOB12_E]
+Certo, nessun problema Avery. Dove vuoi che lo passi a prendere?
-[EBAL_D1]
-Forza, raggiungiamolo, magari riesco a procurarti qualche lavoretto.
+[MOB12_F]
+Sta finendo un lavoro presso il cantiere. Gli ho detto che saresti passato lì.
-[EBAL_E]
-Forza, facciamo un salto. Te lo voglio presentare.
+[MOB12_G]
+Nessun problema. Ci vediamo, Avery.
-[EBAL_I]
-Il boss sara' con voi al più presto...
+[MOB13_A]
+Vercetti? VERCETTI!!! Maledizione, mi devi aiutare!
-[EBAL_J]
-8-Ball ha alcune faccende da sbrigare al piano di sopra.
+[MOB13_B]
+Mr. Moffat? Come sta la famiglia?
-[EBAL_K]
-Forse potresti farmi un favore.
+[MOB13_C]
+Brutto maledetto, BASTARDO! Mi hai sentito?
-[EBAL_L]
-Una delle mie ragazze ha bisogno di un passaggio, prendi una macchina, recupera Misty dalla clinica e portala qua.
+[MOB13_D]
+Beh, è stato un piacere chiacchierare...
-[EBAL_N]
-E tieni le mani sul volante!
+[MOB13_E]
+ASPETTA! Aspetta Vercetti... Tommy, posso chiamarti Tommy?
-[EBAL_4]
-~r~8-Ball è morto!
+[MOB13_F]
+Siamo entrambi professionisti, vero? Sono certo che sai riconoscere un affare, vero?
-[EBAL_5]
-~g~Trova un veicolo!
+[MOB13_G]
+Non ho tempo da perdere, arriva al punto.
-[EBAL_6]
-~g~Recupera Misty!
+[MOB13_H]
+SOLDI. I soldi sono il punto!
-[LM1]
-'LE RAGAZZE DI LUIGI'
+[MOB13_I]
+Sono fuggito nuovamente da quei maledetti, ma non ci metteranno molto a trovarmi... Pensano si tratti di uno stupido gioco!
-[LM2]
-'NIENTE SPANK PER LE RAGAZZE'
+[MOB13_J]
+Sono a un telefono pubblico da qualche parte in questo posto di merda.
-[LM3]
-'PORTA IN GIRO MISTY PER ME'
+[MOB13_K]
+Aiutami a scappare prima che mi prendano e... e... oddio...
-[LM5]
-'FESTA DEGLI SBIRRI'
+[MOB13_L]
+Beh, sono impegnato per i prossimi...
-[LM1_2]
-~g~Porta Misty al club Luigi's.
+[MOB13_M]
+No! Non fare lo stronzo con me, abbi cuore! Nessuno dovrebbe fare una... una cosa simile!
-[LM1_3]
-~g~Premi il clacson per far entrare la ragazza in macchina.
+[MOB13_N]
+Sono in ginocchio, Tommy: nella polvere a chiederti pietà...
-[LM1_6]
-~g~Torna in macchina!
+[MOB13_O]
+Beh, forse potrei passare da quelle parti, vediamo se riesco a trovarti...
-[LM1_7]
-~g~Ferma il veicolo in prossimità di Misty per permetterle di salire.
+[MOB13_P]
+Oddio, stanno arrivando! Ti supplico, muoviti, muoviti!
-[LM1_8]
-Puoi tornare da Luigi per altri lavori o gironzolare per la città di Liberty.
+[MOB_14A]
+Ehi, ciao Tommy: vedrai che mi adorerai!
-[LM2_A]
-C'è una nuova droga in giro per la città chiamata SPANK.
+[MOB_14B]
+Un piccolo uccellino mi ha detto che la divisione SWAT di Vice City ha un deposito presso un'importante banca,
-[LM2_E]
-Qualche farabutto ne ha passata un po' alle mie ragazze giù al porto di Portland.
+[MOB_14C]
+dove tengono tutte le bustarelle intascate nel corso degli anni,
-[LM2_B]
-Raggiungi lo spacciatore e gioca a baseball con la sua testa!
+[MOB_14D]
+un po' come una pensione per gli anni a venire.
-[LM2_G]
-Voglio soddisfazione per questo insulto!
+[MOB_14E]
+Logicamente, se questa informazione dovesse aiutarti a ottenere i soldi,
-[LM2_1]
-~g~Prendi la sua macchina e falla riverniciare.
+[MOB_14F]
+immagino che ti sentiresti obbligato a passarmene una parte...
-[LM2_2A]
-Usa il ~h~tasto ~k~~PED_FIREWEAPON~~w~ per tirare ~h~pugni~w~ e ~h~calci~w~ o per ~h~usare~w~ la mazza!
+[MOB_14G]
+Me lo ricorderò, grazie Kent.
-[LM2_2C]
-Usa il ~h~tasto ~k~~PED_FIREWEAPON~~w~ per tirare ~h~pugni~w~ e ~h~calci~w~ o per ~h~usare~w~ la mazza!
+[MOB_14H]
+Sono Paul. Vengo dal Kent, vicino a Londra, cretino.
-[LM2_2D]
-Usa il ~h~tasto ~k~~PED_FIREWEAPON~~w~ per tirare ~h~pugni~w~ e ~h~calci~w~ o per ~h~usare~w~ la mazza!
+[MOB_14I]
+Le mie conoscenze di geografia non sono mai state un gran che.
-[LM2_3]
-~g~Parcheggia la macchina nel rifugio di Luigi!
+[MOB15_A]
+Tommy, amico, sono Paul, dal Kent,
-[LM2_4]
-~g~Rivernicia la macchina!
+[MOB15_B]
+un paio di squinzie hanno il tuo nome scritto dappertutto giù al Malibu.
-[LM3_A]
-Ehi, devo parlarti... Va bene Mick, ne discutiamo più tardi.
+[MOB15_C]
+Di cosa stai parlando?
-[LM3_B]
-Come va ragazzo?
+[MOB15_D]
+Squinzie. Passere. Chiaro no? Strafighe. E anche ben messe, non credo fossero mignotte...
-[LM3_C]
-Il figlio del Don, Joey Leone, ha bisogno delle doti di Misty, la sua ragazza.
+[MOB15_E]
+Dovresti venire a dare un'occhiata.
-[LM3_D]
-Valla a prendere a Hepburn Heights...
+[MOB16_A]
+Tommy, sono Paulo, que pasa amigo?
-[LM3_E]
-ma fa attenzione: è il territorio dei Diablo.
+[MOB16_B]
+Che cosa vuoi Paul: non sono interessato a vestiti di marca taroccati.
-[LM3_F]
-Poi portala in fretta fino al suo garage in Trenton.
+[MOB16_C]
+Molto divertente, amico, ma lo sai che non tratto merce di seconda classe.
-[LM3_H]
-Mi raccomando, tieni gli occhi sulla strada e lontano da Misty!
+[MOB16_D]
+Nah, ti ho chiamato per sapere se potevo avere una parte nei tuoi film,
-[LM3_1D]
-Premi il ~h~tasto L3~w~ per suonare il ~h~clacson~w~ e avvertire Misty che sei arrivato.
+[MOB16_E]
+quando ero in Inghilterra ho fatto un sacco di cose, sai?
-[LM3_2]
-~g~Porta Misty da Joey.
+[MOB16_F]
+Ho attributi più forniti di te, amico.
-[LM3_4]
-~g~Vai a prendere Misty!
+[MOB16_G]
+Paul, grazie per l'offerta, lo terrò presente.
-[LM3_5]
-Adesso lavori regolarmente per Luigi, vero? Era ora che trovasse un autista di cui ci si può fidare!
+[MOB16_H]
+Davvero, non scordarti di me dopo tutto quello che ho fatto per te.
-[LM3_7]
-Sarò da te fra un minuto, stellina mia.
+[MOB16_I]
+È proprio ciò che sto cercando di dimenticare...
-[LM3_10]
-~g~Recupera un veicolo!
+[MOB17_A]
+Tommy Vercetti: come va, Mr. Pezzo Grosso?
-[LM4_B]
-Occupati di ciò che ti ho chiesto.
+[MOB17_B]
+Ho saputo le tue novità: un vero giocatore in città, eh...
-[LM4_C]
-Se ti serve un'arma, vai sul retro di AmmuNation dal lato opposto della metropolitana.
+[MOB17_C]
+Paul, sei ubriaco.
-[LM5_A]
-La festa degli sbirri viene tenuta in una vecchia scuola presso il ponte Callahan.
+[MOB17_D]
+No, idiota. Non sono ubriaco.
-[LM5_B]
-A quanto sembra vogliono un po' di azione vecchio stile...
+[MOB17_E]
+Solo un paio di bicchierini e qualche pillola: non dormo da un paio di giorni, sai...
-[LM5_C]
-Ora ho ragazze su tutti i marciapiedi della città.
+[MOB17_F]
+Comunque, niente prediche.
-[LM5_D]
-Portale alla festa il prima possibile.
+[MOB17_G]
+Non sono uno stupido. Chi ti ha portato in questa città? Chi? Io, ecco chi.
-[LM5_1]
-~g~Non sovraffollate il mezzo o mi sciuperai le ragazze! ~g~Scarica subito queste e poi vai a cercarne altre.
+[MOB17_H]
+Davvero?
-[LM5_2]
-~r~Una delle ragazze di Luigi è ridotta a pezzi!
+[MOB17_I]
+Davvero!
-[LM5_3]
-~g~Hai bisogno di un mezzo!
+[MOB17_J]
+Paul, sta' buono. Sono stato occupato, non fare l'idiota.
-[LM5_4]
-~g~Raccogli le ragazze che lavorano presso St. Marks.
+[MOB17_K]
+Non sono un idiota, chiaro? Questo è ciò che hanno detto in riformatorio.
-[LM5_5]
-~g~Porta le ragazze alla festa degli sbirri!
+[MOB17_L]
+Stai forse cercando guai, amico? Beh, stai per trovarli!
-[LM5_8]
-~g~Ragazze alla festa: ~1~
+[MOB17_M]
+Tommy, amico. Per favore. Sei la mia più grande speranza! Per favore, non ridere di me.
-[JM2]
-'ADDIO 'CHUNKY' LEE CHONG'
+[MOB17_N]
+Paul, cerca di dormire, davvero.
-[JM4]
-'L'AUTISTA DI CIPRIANI'
+[MOB18_A]
+Tommy, sono Paulo, come butta? Bene amico, comunque, volevo farti una chiamata.
-[JM5]
-'CADAVERE NEL BAGAGLIAIO'
+[MOB18_B]
+Ossignore, amico, non crederai mai che razza di strafiga ho appena incontrato.
-[JM1_1]
-~g~Porta la macchina di Forelli al garage di 8-Ball a nord di qui, dietro a 'Easy Credit Autos'.
+[MOB18_C]
+Non so esattamente chi fosse, ma passeggiava per Little Havana.
-[JM1_2]
-~g~Parcheggia la macchina nuovamente di fronte al Marco's Bistro.
+[MOB18_D]
+Ha detto che si chiamava Mercedes o qualcosa del genere. Oddio, dovresti proprio vedere questa gnocca.
-[JM1_3]
-~g~Attiva la bomba e vattene in fretta!
+[MOB18_E]
+Riuscirebbe a succhiare via la mina da una matita. Mi ha detto che ero il migliore che avesse mai avuto e via dicendo.
-[JM1_4]
-~g~Hai rovinato il veicolo! Fallo riparare!
+[MOB18_F]
+Dovresti farci un giro. Ci vediamo!
-[JM1_5]
-~g~La bomba non è stata piazzata!
+[MOB19_A]
+Tommy V, sono KP. Kent Paul. Gira voce che ti vogliano fare a pezzi.
-[JM1_6]
-~g~Parcheggia la macchina nel posto giusto.
+[MOB19_B]
+Tieni gli occhi bene aperti, amico e ricorda: io non ti ho detto niente al riguardo.
-[JM1_8A]
-~y~Ehi, amico mio!
+[MOB_20A]
+Ehi Tommy, sono Paul. Ho appena sentito che sei stato un ragazzaccio cattivo.
-[JM1_8B]
-~y~L'armeria è automatizzata: entra dentro, ferma la macchina e il resto dell'operazione verrà eseguito automaticamente.
+[MOB_20B]
+Qualcuno si è offeso per il tuo comportamento da grand'uomo, e adesso è davvero arrabbiato.
-[JM1_8C]
-~y~La prima volta è gratis, ma le altre volte dovrai pagare.
+[MOB_20C]
+Beh, non dire che non ti ho avvertito: vantarsi è un gioco pericoloso, amico.
-[JM2_A]
-Chunky Lee Chong sta spacciando SPANK per una nuova gang dalla Colombia... o dal Colorado...o qualcosa del genere...
+[MOB_20D]
+Comunque, ho anche sentito che c'è una taglia sulla tua testa e che qualcuno ti ha già preso di mira,
-[JM2_B]
-Non ricordo bene... ma del resto che importa?
+[MOB_20E]
+per cui guardati la schiena e ricordati di me, amico.
-[JM2_D]
-Quel verme ha venduto la sua roba per l'ultima volta.
+[MOB71_A]
+Tommy, Tommy, sono Cortez. Que pasa?
-[JM2_E]
-Voglio che tu lo elimini!
+[MOB71_B]
+La situazione è interessante. A lei come va?
-[JM2_G]
-Equipaggiati con una calibro nove: sai dove trovarla, vero?
+[MOB71_C]
+Tommy, qui è sempre una battaglia. Scusami per la battuta scontata, ma abbiamo sventato un altro golpe.
-[JM2_H]
-Guardati le spalle a Chinatown: è territorio della Triade.
+[MOB71_D]
+La gente non smette mai di pretendere di più.
-[JM3_A]
-Bene, colpiremo il furgone portavalori.
+[MOB71_E]
+Da quando sono tornato da Vice City, abbiamo avuto tre rivoluzioni e quattro golpe falliti.
-[JM3_B]
-Esce da Chinatown tutti i giorni.
+[MOB71_F]
+Fortunatamente, sono stato promosso ogni volta.
-[JM3_C]
-I proiettili non scalfiscono neanche la sua blindatura, per cui prendi una macchina e fallo uscire fuori strada.
+[MOB71_G]
+Ti volevo chiedere di Mercedes.
-[JM3_D]
-Colpiscilo forte e le guardie dovrebbero arrendersi.
+[MOB71_H]
+Sì? Cosa vuole sapere?
-[JM3_E]
-Ora portalo fino al magazzino vicino agli impianti portuali e i miei ragazzi si occuperanno del resto.
+[MOB71_I]
+Oh Tommy, ho sentito tutte queste storie e non so cosa pensare.
-[JM3_F]
-Ricorda che non starà in giro per delle ore, per cui non perdere tempo.
+[MOB71_J]
+Forse tutti si divertono a umiliarmi.
-[JM3_1]
-~g~Porta il furgone a destinazione.
+[MOB71_K]
+Forse pensa di poter fare ciò che vuole ma dimmi, Tommy: è tutto vero?
-[JM3_2]
-~g~Sperona il furgone finché non è danneggiato oltre al 70 percento.
+[MOB71_L]
+ma dimmi, Tommy: è tutto vero?
-[JM4_B]
-Oh! Ecco il tipo di cui ti stavo parlando.
+[MOB71_M]
+Che cosa?
-[JM4_C]
-Bene, ascolta: questo tipo non è italiano e non è un meccanico, ma sa come riparare le cose.
+[MOB71_N]
+Le storie che ho sentito: sta pensando davvero di diventare avvocato?
-[JM4_D]
-Il suo nome è Toni Cipriani.
+[MOB71_O]
+Oh Tommy, che vergogna. Noi Cortez siamo una famiglia all'antica e non permetteremo mai che una di noi diventasse avvocato.
-[JM4_E]
-Piacere, Toni Cipriani.
+[MOB71_P]
+Ti prego, dimmi che non è vero. Non credo resisterei al colpo.
-[JM4_F]
-Portalo al ristorante Momma's a St Marks, OK?
+[MOB71_Q]
+Colonnello, le assicuro che Mercedes non diventerà mai un avvocato. Non si preoccupi.
-[JM4_G]
-Adesso ascolta, sto pianificando un lavoro che richiede un buon autista, per cui passa a trovarmi un giorno di questi, OK?
+[MOB71_R]
+Grazie Tommy, la vergogna sarebbe schiacciante. Lei è una vera dama, non una parassita, capisci?
-[JM4_2]
-Aspetta qua! Tieni il motore acceso, potrebbero esserci grane.
+[MOB71_S]
+Capisco, Colonnello.
-[JM4_3]
-È un'imboscata della Triade! Portaci via di qua, ragazzo!
+[MOB71_T]
+Comunque, Tommy, devi scusarmi: è appena arrivato il nuovo ministro degli interni.
-[JM4_4]
-La Triade pensa di potersi prendere gioco di me, la Triade... di ME!
+[MOB71_U]
+Qualche anno fa, ho ucciso suo padre in un golpe fallito, per cui devo essere gentile. Buona giornata, amico.
-[JM4_6]
-Fai attenzione alla macchina! Ti ho detto di non fare stronzate.
+[MOB22_A]
+Tommy, ti stai rivelando molto utile, amico.
-[JM4_7]
-~g~Accompagna Toni al ristorante Momma's.
+[MOB22_B]
+Grazie, Cortez. Cosa mi dice del nostro accordo?
-[JM4_8]
-~r~Toni è stato ucciso!
+[MOB22_C]
+Tommy, sto lavorando senza sosta nel tentativo di raggiungere il fondo di questa fossa piena di bugie e inganni,
-[JM5_A]
-Perfetto! Semplicemente perfetto.
+[MOB22_D]
+hai la mia parola al riguardo, ma nel frattempo,
-[JM5_B]
-Sei proprio la persona di cui avevo bisogno!
+[MOB22_E]
+ti prego di accettare i più sinceri ringraziamenti da parte della gente per cui stai lavorando.
-[JM5_D]
-Uno dei Forelli ha voluto fare il furbo e si è beccato quello che si meritava.
+[MOB_25A]
+Tommy, sono Cortez. I Francesi mi stanno causando tutti i problemi possibili.
-[JM5_E]
-Porta il cadavere al rottamatore ad Hardwood, OK?
+[MOB_25B]
+Maledetti ipocriti. Hanno passato secoli a derubare la povera gente e adesso osano chiamare me ladro!
-[JM5_1]
-~g~Porta il cadavere al rottamatore!
+[MOB_25C]
+Avrò bisogno del tuo aiuto il prima possibile.
-[JM5_2]
-~g~Sono i fratelli Forelli!
+[MOB_25D]
+Sbrigati, Tommy: ho bisogno di te. Odio questi dannati Francesi.
-[JM6_A]
-Ci si prospetta una bella corsetta, vero?
+[MOB_26A]
+Ehi, Tommy?
-[JM6_B]
-Bene, recupera un veicolo e raggiungi il rifugio a St. Marks e recupera alcuni miei amici.
+[MOB_26B]
+Sì?
-[JM6_C]
-Stanno per fare un colpo a una banca e hanno bisogno dell'autista.
+[MOB_26C]
+Sono Baker. Volevo dirti che ho davvero apprezzato lo show.
-[JM6_D]
-Ho dato loro la mia parola che tu sei il migliore sul mercato.
+[MOB_26D]
+Io e i ragazzi vogliamo ringraziarti e ricordarti
-[JM6_E]
-Portali in banca prima delle cinque, non un minuto più tardi!
+[MOB_26E]
+che hai tutto il nostro rispetto. Buona giornata, continua così.
-[JM6_2]
-Tieni il motore acceso: torneremo in un attimo!
+[MOB_29A]
+Salve, parlo con Mr. Tommy Vercetti?
-[JM6_3]
-Portaci via di qua!!
+[MOB_29B]
+Sì.
-[JM6_4]
-Semina i poliziotti e portaci al rifugio!
+[MOB_29C]
+Beh, ho sentito dire che sei tu l'uomo da chiamare in caso di infestazione da parassiti.
-[JM6_6]
-~g~Prendi un veicolo meno appariscente!
+[MOB_29D]
+Forse...
-[JM6_7]
-~g~Hai bisogno di tutti e tre per rapinare la banca!
+[MOB_29E]
+Beh, ho in corso un'infestazione davvero pesante: Haitiani da tutte le parti.
-[TM1]
-'RIPULIRE LA LAVANDERIA'
+[MOB_29F]
+Mi chiamo Umberto Robina e vorrei incontrarmi con te al Cafe Robina il prima possibile,
-[TM2]
-'LA RACCOLTA'
+[MOB_29G]
+perché questa volta i fottuti Haitiani sono andati troppo oltre.
-[TM3]
-'SALVATORE RICHIEDE UN INCONTRO'
+[MOB_29H]
+Test
-[TM4]
-'TRIADE E TRIBOLAZIONE'
+[MOB_30A]
+Tommy, sono Umberto Robina.
-[TM5]
-'PESCE ESPLOSIVO'
+[MOB_30B]
+Come va al caffè?
-[TONI_P]
-Ho un lavoro urgente per te! -Toni
+[MOB_30C]
+Oh, meraviglioso. Incredibile, Tommy, incredibile. Niente perdenti, Tommy, solo veri uomini, sai no, e donne stupende.
-[TM1_A]
-~w~Prendi una sedia, ragazzo, prendi una maledetta sedia.
+[MOB_30D]
+Comunque, volevo dirti che per tutti noi adesso sei un vero Cubano.
-[TM1_B]
-~w~Allora la lavanderia non intende pagare il pizzo, eh?
+[MOB_30E]
+Hai provato di essere all'altezza. Hai provato di avere due grandi cojones.
-[TM1_C]
-~w~La Triade pensa di poter mettersi contro di me?
+[MOB_30F]
+Err... grazie, Umberto. Nessuno mi ha detto una cosa simile da quando ho lasciato la galera. Ci becchiamo in giro.
-[TM1_D]
-~w~Insegniamo a questi presuntuosi cosa significa fare sul serio.
+[MOB_33A]
+Tommy, sono Phil: smettila di perdere tempo con le vaccate e ascoltami, intesi?
-[TM1_E]
-~w~Sì, insegniamo loro un po' di rispetto. Nessun mio figliolo si fa fregare dalla Triade.
+[MOB_33B]
+Bene. Ho un bel po' di broda bella forte quasi a perfetta fermentazione e mi chiedevo se ne volevi assaggiare un po'.
-[TM1_F]
-Tuo padre, pace all'anima sua, non si è mai fatto fregare da quelli della Triade in Sicilia.
+[MOB_33C]
+Ti assicuro, Tommy, che se ami bere, o se devi rimuovere della vernice, questa è la roba che fa per te.
-[TM1_G]
-~w~Scusa mamma. Sì mamma.
+[MOB_33D]
+Per me è stata una bomba, anche se non ci vedo più bene da un occhio. Ti aspetto, ciao.
-[TM1_H]
-~w~Voglio che tu distrugga i furgoni della lavanderia
+[MOB_34A]
+Tommy, mi è davvero piaciuto lavorare con te. Non mi divertivo così dalle scorrerie in Vietnam, amico.
-[TM1_I]
-~w~e faccia a pezzi qualsiasi idiota della Triade che oserà mettersi in mezzo.
+[MOB_34B]
+Se mai ti servisse qualcosa, chiamami, capito?
-[TM1_J]
-~w~8-Ball ti fornirà qualsiasi cosa di cui tu possa aver bisogno.
+[MOB_34C]
+Ricordo sempre quelli coi quali ho prestato servizio,
-[TM2_A]
-~w~Toni vuole fare il duro,
+[MOB_34D]
+e sono sicuro di poterti dare una mano, chiaro?
-[TM2_AA]
-ma non riuscirà mai a eguagliare suo padre. Ha lasciato una nota per te sul tavolo.
+[MOB_35A]
+Tommy, la ferita si sta rimarginando bene. È divertente:
-[TM2_B]
-~w~La lavanderia ha accettato di pagare: bel lavoro, ragazzo!
+[MOB_35B]
+ho combattuti in sei campi di battaglia e sono sempre uscito senza un graffio... e adesso questo!
-[TM2_C]
-~w~Vai a recuperare i contanti e portali qua. Fai attenzione alla Triade.
+[MOB_35C]
+Phil senza un braccio. Comunque, ho una abbondante selezione di armi a una mano, per cui almeno non sarò disarmato!
-[TM2_D]
-~w~Potrebbero volerti ficcare qualche petardo nel sedere, ma tu non farti impressionare.
+[MOB_35D]
+Comunque, figliolo, lasciamo stare le stronzate sentimentali e vedi di scolarti qualcosa da parte mia!
-[TM2_E]
-~w~Nessuno, e intendo nessuno, fa le scarpe a TONI CIPRIANI!
+[MOB_36A]
+Tommy, sono Phil. Ti volevo ringraziare di essere stato sul campo, figliolo.
-[TM2_1]
-~g~Riporta i contanti a Toni!!!
+[MOB_36B]
+Maledetti Viet, non perdono occasione per farti un attentato...
-[TM2_2]
-~g~Li hai freddati tutti!
+[MOB_36C]
+Comunque, la ferita sta guarendo: adesso non mi sentirò più in colpa quando riceverò il mio consueto assegno per disabili. Grazie, amico.
-[TM3_MA]
-~w~Non so dove sia!
+[MOB_40A]
+Ehi, Tommy, sono Sonny. Come va l'abbronzatura?
-[TM3_MB]
-~w~Giuro che ogni tanto anche lui non si rende conto di cosa fa.
+[MOB_40B]
+Non ho preso il sole.
-[TM3_MC]
-~w~Suo padre invece era diverso. Sempre in prima linea, sempre in carica, coraggioso...
+[MOB_40C]
+Beh, non hai preso neanche i miei soldi, per cui mi chiedevo:
-[TM3_A]
-~w~Don Salvatore richiede un incontro.
+[MOB_40D]
+che cosa stai combinando? Dimmi un po', Tommy, che cosa fai?
-[TM3_B]
-~w~Recupera la limousine da suo garage e il suo ragazzo, Joey.
+[MOB_40E]
+Sto cercando i soldi, Sonny, non ti preoccupare.
-[TM3_C]
-~w~Poi passa a prendere Luigi dal suo club e torna qua a prendere me.
+[MOB_40F]
+Invece mi preoccupo, Tommy, è il mio stile,
-[TM3_D]
-~w~Poi andremo tutti assieme al luogo dell'incontro.
+[MOB_40G]
+poiché ho sempre dei problemi con gente che non ama rispettare i patti.
-[TM3_E]
-~w~Quelli della Triade non sanno quando è l'ora di fermarsi.
+[MOB_40H]
+Non diventare inaffidabile, Tommy, fallo per me...
-[TM3_F]
-~w~Se vogliono la guerra, avranno la guerra!
+[MOB_40I]
+Fai un favore a entrambi. Non vedo l'ora di ricevere buone nuove.
-[TM3_G]
-~w~Adesso muoviamoci.
+[MOB_41A]
+Tommy, ti ricordi di me?
-[TM3_1]
-~g~Prendi la limousine da Joey.
+[MOB_41B]
+Ehi, Sonny.
-[TM3_2]
-~g~Ora vai a prendere Luigi.
+[MOB_41C]
+Sì, sono proprio io, Sonny. Siamo vecchi amici,
-[TM3_3]
-~g~Ora vai a prendere Toni.
+[MOB_41D]
+e tu non mi scrivi mai, non mi chiami mai. Non vuoi più essere mio amico?
-[TM3_4]
-~g~Porta i tuoi passeggeri da Salvatore.
+[MOB_41E]
+Sono stato occupato a mettere le cose a posto. Non mi hai dato un gran che di aiuto da queste parti.
-[TM3_5]
-~y~Un'imboscata della Triade!!!
+[MOB_41F]
+Ah, è questa la mia colpa? Beh, ho sentito che sei stato molto occupato.
-[TM4_B]
-~w~Siamo in GUERRA! La Triade utilizza uno stabilimento per il pesce come facciata.
+[MOB_41G]
+Occupato a uccidere i baroni della droga. Occupato a prendere il potere.
-[TM4_C]
-~w~La maggior parte del loro lavoro si svolge nel mercato del pesce di Chinatown.
+[MOB_41H]
+Non dimenticarti di noi, Tommy, poiché, te lo assicuro, io non mi sono dimenticato di te.
-[TM4_D]
-~w~La lavanderia ha smesso nuovamente di pagarci il pizzo.
+[MOB_42A]
+Tommy.
-[TM4_E]
-~w~Pensano di essere sotto la protezione della Triade, per cui si meritano una punizione esemplare.
+[MOB_42B]
+Sonny.
-[TM4_F]
-~w~Prendi questi ragazzi e fai fuori i signori della Triade!
+[MOB_42C]
+Hai di sicuro dei problemi di udito, per cui proverò ancora...
-[TM4_G]
-~w~E se ne hai il tempo, elimina anche qualcuno dei loro scagnozzi.
+[MOB_42D]
+Tommy, dove sono i maledetti soldi, dov'è la maledetta roba e dov'è la mia parte dei tuoi ultimi guadagni?
-[TM4_GAT]
-~w~Avrai bisogno di un 'furgone del pesce della Triade' per riuscire a entrare.
+[MOB_42E]
+Tommy, mi stai facendo fare la figura dell'idiota, e io non sto ridendo.
-[TM5_A]
-TESTO NON PIÙ NECESSARIO
+[MOB_43A]
+Tommy, Tommy, Tommy, avevo Sonny al telefono... OK, sei con me?
-[TM5_B]
-~w~Basta, ne ho avuto abbastanza!
+[MOB_43B]
+Non so te, ma so che qualcuno sta minacciando di morte la mia famiglia,
-[TM5_C]
-~w~Elimineremo una volta per tutte la Triade da Liberty!
+[MOB_43C]
+il che mi sta davvero facendo cagare sotto. Che cosa intendi fare?
-[TM5_D]
-8-Ball ha messo una bomba in un camion della nettezza urbana.
+[MOB_43D]
+Stai calmo, Ken, andrà tutto bene.
-[TM5_E]
-~w~La bomba è collegata a un timer, per cui se fai errori non resteranno prove. Vai a prendere il camion.
+[MOB_43E]
+Io SONO calmo, calmo quanto un uomo in pericolo di vita!
-[TM5_F]
-~w~Fai attenzione: 8-Ball ha detto che il sistema è molto sensibile e potrebbe esplodere se prendi un colpo.
+[MOB_43F]
+Ken, ora come ora ho altre cose per la testa,
-[TM5_G]
-~w~Il loro stabilimento aprirà i cancelli al camion.
+[MOB_43G]
+ci occuperemo di Forelli al momento giusto.
-[TM5_H]
-~w~Parcheggia tra i due serbatoi del gas e allontanati in fretta!
+[MOB_43H]
+Io sono calmo. Non ti sembro calmo? Forse è la morte incombente che mi sta facendo tremare la voce.
-[TM5_I]
-~w~Voglio che piovano sgombri.
+[MOB45_A]
+Tommy, dobbiamo parlare di un po' di cose.
-[TM5_J]
-~w~Stiamo facendo le cose in grande, basta con gli scherzi.
+[MOB45_B]
+C'è qualche problema, Lance?
-[FM2]
-'TAGLIARE L'ERBA'
+[MOB45_C]
+Si tratta di te, amico, non mi sembra di ricevere la fetta che merito.
-[FM4]
-'ULTIME RICHIESTE'
+[MOB45_D]
+E inoltre, mi hai imbarazzato davanti ai ragazzi. Non lo posso permettere.
-[FM1_A]
-~w~Io e i ragazzi dobbiamo parlare di lavoro,
+[MOB45_E]
+Lance, non è andata così. Hai commesso degli errori.
-[FM1_B]
-~w~per cui dovrai occuparti della mia ragazza questa sera.
+[MOB45_F]
+Tommy, non sono il tuo fattorino. Non sono un tuo scagnozzo.
-[FM1_C]
-~w~EHI MARIA! MUOVI IL CULO!
+[MOB45_G]
+Lance, non fare casini e non avremo alcun problema. Se faccio un errore, me la puoi far pagare in qualsiasi momento.
-[FM1_D]
-~w~Quella vacca fa sempre così.
+[MOB45_H]
+Tommy, ho fatto tutto per te e mi tratti come un idiota. Non farlo.
-[FM1_E]
-~w~Ed eccola qua, la vera e unica regina di Sheba!
+[MOB45_I]
+Lance, non ti causerò problemi e non ti pugnalerò alle spalle, promesso.
-[FM1_F]
-~w~Cosa stavi facendo di sopra?
+[MOB45_J]
+Rilassati. La cosa è già abbastanza difficile senza che tu ti metta a fare il tenero con me.
-[FM1_G]
-~w~Qualsiasi cosa fosse, sono certo che mi è costato molto.
+[MOB45_K]
+Fidati: mi hai sentito, mi hai sentito?
-[FM1_H]
-~w~Beh, credevo non mi volessi attorno quando parli di lavoro, vero?
+[MOB45_L]
+Ti ho sentito, ma Tommy, non sopporterò ancora per lungo.
-[FM1_I]
-~w~Entra in macchina e tieni chiusa la boccaccia.
+[MOB45_M]
+Lance, non fare così: adesso sono io ad avvertirti.
-[FM1_J]
-~w~Prendi la limousine, ma riportala indietro come nuova, capito?
+[MOB45_N]
+Mi hai sentito? Rilassati, prenditi qualche giorno e poi ne riparliamo, OK?
-[FM1_K]
-~w~E fai attenzione alla ragazza, può causarti dei problemi.
+[MOB46_A]
+Tommy, sono Lance.
-[FM1_L]
-~w~Tranquillo, sono certa che il tuo nuovo cagnolino sa cosa deve fare:
+[MOB46_B]
+Sì?
-[FM1_M]
-~w~non è grande e grosso a sufficienza?
+[MOB46_C]
+Sono felice di sentirti Lance. Forza, stai tranquillo, stai tranquillo.
-[FM1_N]
-~w~Ehi, Fido: andiamo a far visita a Chico e prendiamo della roba per divertirci.
+[MOB46_D]
+Sono nel mezzo di un problema: ho bisogno di te.
-[FM1_P]
-~g~Ecco, quello è Chico. Fermati vicino a lui.
+[MOB46_E]
+Niente, giusto per dire. Tommy, ce ne possiamo occupare.
-[FM1_S]
-~w~Buongiorno signora.
+[MOB46_F]
+Io e te, nessun problema. Capisci ciò che intendo?
-[FM1_TT]
-~w~È UN RETATA DELLA POLIZZIA!
+[MOB46_G]
+Dobbiamo proprio farlo, se no siamo entrambi morti, Lance.
-[FM1_1]
-~g~Torna nella limousine!
+[MOB46_H]
+Siamo andati troppo oltre, ma grazie della chiamata. Ci sentiamo più tardi.
-[FM1_2]
-~g~Rientra nella limousine!
+[MOB_47A]
+Tommy, sono Lance. Abbiamo un problema serio. Vieni qui in fretta.
-[FM1_3]
-~r~Se abbandoni Maria, Salvatore ti farà ammazzare! Torna indietro a prenderla.
+[MOB52_A]
+Ehi, Leo, sembra ci sia un compratore per la roba di Diaz.
-[FM1_4]
-~g~Hai scaricato la donna del Don. Torna al magazzino e aspetta Maria!
+[MOB52_B]
+Devi fargli uno squillo, ragazzo, e preparare l'accordo, chiaro?
-[FM1_5]
-~g~Riporta Maria sana e salva a Salvatore!
+[MOB52_C]
+Dove ti trovi adesso?
-[FM1_6]
-~g~Chico non aspetterà per sempre. Porta Maria al porto.
+[MOB52_D]
+Stai bene Leo? Mi sembri un po' strano...
-[FM1_7]
-~r~Maria è morta! Salvatore non ne sarà entusiasta...
+[MOB52_E]
+Dimmi dove ti trovi.
-[FM1_8]
-~r~Hai fatto fuori lo spacciatore di Maria!
+[MOB52_F]
+Chi diavolo sei? Passami subito Leo!
-[FM2_J]
-Lasciaci da soli per un minuto.
+[MOB52_G]
+Leo se ne è andato per un po' e adesso sono io in carica.
-[FM2_A]
-Il Cartello Colombiano sta producendo SPANK da qualche parte a Liberty.
+[MOB52_H]
+Fottiti, stronzo!
-[FM2_K]
-Non sappiamo però dove, e loro sembrano conoscere ogni nostra mossa in anticipo.
+[MOB54_A]
+Ciao Tommy!
-[FM2_L]
-C'è un tipo chiamato Ricciolino Bob che lavora al bar di Luigi.
+[MOB54_B]
+Ciao Mercedes, come butta?
-[FM2_M]
-Sta spendendo molti più soldi di quanti ne guadagna.
+[MOB54_C]
+Ho un nuovo appartamento in Vice Point...
-[FM2_N]
-Normalmente prende un taxi per tornare a casa. Voglio che tu lo segua.
+[MOB54_D]
+magari un giorno di questi potresti farci un salto.
-[FM2_O]
-E se ci sta vendendo... fallo fuori!
+[MOB54_E]
+Mi piacerebbe, ci sentiamo.
-[FM2_F]
-Ecco il nostro caro amico: mister bocca larga.
+[MOB55_A]
+Tommy, sono io.
-[FM2_G]
-Sei stato seguito? Lo sai che questo deve restare un nostro segreto.
+[MOB55_B]
+Ciao Mercedes.
-[FM2_H]
-No, no... nessuno mi ha seguito. Hai la mia roba?
+[MOB55_C]
+Tommy, sono così annoiata: perché non ci divertiamo un po' insieme?
-[FM2_I]
-Ecco il tuo SPANK, e adesso parla!
+[MOB55_D]
+Cosa intendi dire?
-[FM2_P]
-OK, i Leone stanno combattendo su due fronti.
+[MOB55_E]
+Beh, lo so che sei occupato a combattere, uccidere e corrompere gente,
-[FM2_Q]
-Sono ai ferri corti con la Triade e sembra che nessuno dei due sia intenzionato a cedere.
+[MOB55_F]
+ma io ho voglia di divertirmi un po'. Non ti scordare di me, capito?
-[FM2_R]
-Contemporaneamente, Joey Leone si è fatto dei nemici tra i Forelli.
+[MOB56_A]
+Tommy, ho sentito che hai ucciso Ricardo Diaz.
-[FM2_S]
-Ogni giorno perdono uomini e influenza sulla città.
+[MOB56_B]
+C'è stato uno sfortunato incendio nella sua villa.
-[FM2_T]
-Salvatore sta diventando pericoloso e paranoico. Sospetta di tutto e di tutti.
+[MOB56_C]
+Credo sia morto bruciato nella sua camicia in acrilico.
-[FM2_U]
-Con persone fedeli come te, non capisco di cosa si preoccupi.
+[MOB56_D]
+Tommy, sono così fiera di te. Lo sapevo che eri un vero uomo.
-[FM2_1]
-~g~Ecco Ricciolino Bob!
+[MOB56_E]
+Era un inutile idiota senza testa: mi rendi orgogliosa di essere tua amica.
-[FM2_2]
-~g~Ricciolino ha lasciato il club: seguilo!
+[MOB56_F]
+No, lo so che sei impegnato a prendere il possesso di questa città,
-[FM2_5]
-~g~Andiamo al porto di Portland.
+[MOB56_G]
+ma non dimenticarti di me, capito?
-[FM2_6]
-~r~Ricciolino non salirà su un taxi distrutto!
+[MOB57_A]
+Sono Mercedes. Non ti amo più, Tommy.
-[FM2_7]
-~r~Ricciolino è spaventato! L'appuntamento è saltato!
+[MOB57_B]
+Proprio no, onestamente. Tu non sei più gentile con la tua Mercedes.
-[FM2_8]
-~g~Elimina Ricciolino Bob!
+[MOB57_C]
+Non mi tratti più come una signora: mi ignori e io ti odio.
-[FM2_9]
-~r~Ricciolino Bob è morto!
+[MOB57_D]
+Insisto che tu venga a trovarmi immediatamente!
-[FM2_10]
-~r~Ricciolino è scappato!
+[MOB58_A]
+Tommy.
-[FM2_11]
-~g~Parcheggia di fronte al club Luigi's: Ricciolino Bob uscirà fra poco.
+[MOB58_B]
+Ehi Mercedes.
-[FM2_12]
-~r~Ti ha seminato!
+[MOB58_C]
+Ehi sì, Mr. Tipo Duro. Sono davvero arrabbiata con te, Tommy.
-[FM3_A]
-~w~Dovremmo eliminare i fottuti Colombiani,
+[MOB58_D]
+Non farmi più passare le serate con Jezz Torrent.
-[FM3_B]
-~w~ma siamo già in guerra con la Triade e non siamo abbastanza forti.
+[MOB58_E]
+È davvero patetico. A metà delle scale ha iniziato a piagnucolare per il suo cane
-[FM3_C]
-~w~Il Cartello ha fondi infiniti grazie allo smercio dello SPANK.
+[MOB58_F]
+che è morto quando aveva sette anni e a ripetere che la mamma non lo ha mai amato.
-[FM3_D]
-~w~Se li attacchiamo apertamente, ci spazzeranno via come foglie secche.
+[MOB58_G]
+E Tommy, indossa una parrucca e un reggiseno quando è in intimità.
-[FM3_E]
-~w~Probalbimente producono lo SPANK sull'imbarcazione dove si è diretto Ricciolino.
+[MOB58_H]
+Non sono molto felice di te!
-[FM3_F]
-~w~Per cui dovremo usare la testa... meglio ancora la tua testa.
+[MOB59_A]
+Ooh Tommy, sono Mercedes.
-[FM3_G]
-~w~Ti chiedo di distruggere la fabbrica di SPANK come favore personale a me, Salvatore Leone.
+[MOB59_B]
+Volevo solo dirti che mi sono divertita così tanto sul set del film.
-[FM3_H]
-~w~Se ci riuscirai, sarai una persona felice: potrai avere tutto ciò che vuoi.
+[MOB59_C]
+Se hai qualcos'altro del genere, fammelo sapere.
-[FM3_I]
-~w~Vai a trovare 8-Ball: avrai bisogno della sua esperienza per far saltare l'imbarcazione.
+[MOB59_D]
+Lo penso davvero. Ho sempre desiderato fare l'attrice.
-[FM3_8A]
-~w~Ehi amico, Salvatore ha appena chiamato:
+[MOB59_E]
+Credo di aver imparato molto sull'approccio drammatico.
-[FM3_8B]
-~w~per un lavoro come questo avrai bisogno di una bella potenza di fuoco.
+[MOB59_F]
+È così illuminante! Grazie, grazie! Spero di vederti presto! Adios.
-[FM3_8D]
-~w~ma tu sai che sono soldi spesi bene.
+[MOB_99]
+Raggiungi il telefono pubblico.
-[FM3_8E]
-~w~OK, procediamo allora!
+[MOB_98]
+Raggiungi il telefono pubblico.
-[FM3_8F]
-~w~Posso impostare questo bambino e farlo esplodere, ma non posso sparare con queste mani.
+[MOB_97]
+Raggiungi il telefono pubblico.
-[FM3_8G]
-~w~Prendi questo fucile e fai saltare un po' di teste!
+[MOB_96]
+Raggiungi il telefono pubblico.
-[FM3_4]
-~g~Ferma il veicolo e fai scendere 8-Ball!
+[MOB_95]
+Raggiungi il telefono pubblico.
-[FM3_7]
-~r~8-Ball è stato freddato!
+[A_TIME]
++~1~ secondi
-[FM3_8]
-~r~Le guardie sono state messe in guardia!
+[F_RANGE]
+~g~Sei fuori dal raggio d'azione della radio. Avvicinati alla stazione dei pompieri!
-[FM4_A]
-~w~Sei l'uomo delle pulizie che preferisco.
+[DODO_FT]
+Hai volato per ~1~ secondi!
-[FM4_B]
-~w~Sono fiero di te, hai saputo prendere a calci quei maledetti!
+[GA_8]
+Usa il detonatore per attivare la bomba.
-[FM4_C]
-~w~Ho un ultimo lavoro per te prima di celebrare.
+[GA_10]
+Non male. Eccoti ~1~$
-[FM4_D]
-~w~C'è una macchina vicino al club Luigi's.
+[GA_11]
+Ne abbiamo già una. A noi non serve!
-[FM4_E]
-~w~All'interno è schizzato cervello dappertutto.
+[GA_12]
+Bomba innescata
-[FM4_F]
-~w~Abbiamo dovuto far ragionare un tipo e la cosa si è rilevata un po', ehm, sporca.
+[GA_13]
+Un furto da manuale. Completa la lista e ci sarà un bonus per te.
-[FM4_H]
-~w~Portala al rottamatore prima che la trovino i poliziotti.
+[GA_14]
+Hai portato tutte le macchine. BENE! Eccoti un bonus...
-[AM3]
-'STRONCA I PAPARAZZI'
+[GA_15]
+Spero che ti piaccia il nuovo colore.
-[AM4]
-'GIORNO DI PAGA PER RAY'
+[GA_16]
+La riverniciatura è gratuita.
-[AM5]
-'DOPPIA FACCIA'
+[GA_19]
+Non siamo interessati a questo modello.
-[AM1_A]
-Ci sono alcuni punti da chiarire prima di procedere con la nostra relazione di lavoro.
+[GA_20]
+Di questo modello ne abbiamo in abbondanza. Mi dispiace, non siamo interessati.
-[AM1_B]
-Direi che è il caso di mostrare le carte.
+[CHASE]
+Massima attenzione dei media
-[AM1_C]
-Io sono della Yakuza e so che hai lavorato per la famiglia di Salvatore Leone.
+[CHASE1]
+Ignoto
-[AM1_D]
-La mia organizzazione può darti lavoro,
+[CHASE2]
+Noioso
-[AM1_E]
-ma prima devi dimostrare che i tuoi legami con la Mafia sono definitivamente chiusi.
+[CHASE3]
+Appena interessante
-[AM1_G]
-Assicurati che non raggiunga vivo il suo club.
+[CHASE4]
+Giornale locale, pagina 7
-[AM1_H]
-Nel frattempo io e Maria discuteremo dei tempi passati.
+[CHASE5]
+Giornale locale, prima pagina
-[AM1_I]
-Oh... Asuka, hai un massaggiatore.
+[CHASE6]
+Vice Courier, 1 colonna
-[AM1_J]
-Non è un massaggiatore.
+[CHASE7]
+Vice Courier, prima pagina
-[AM1_1]
-~g~Salvatore sta lasciando adesso il club Luigi's!
+[CHASE8]
+TV locale, 3 AM
-[AM1_2]
-~r~Sei stato avvistato!
+[CHASE9]
+TV locale, news
-[AM1_3]
-~r~Hai mancato Salvatore!
+[CHASE10]
+TV locale, servizio in diretta
-[AM1_4]
-~r~Ma bravo, hai spaventato il bersaglio! E tu dovresti essere un professionista?
+[CHASE11]
+UFA Today, pagina 12
-[AM1_5]
-~g~Raggiungi il distretto a luci rosse e aspetta che Salvatore esca dal club.
+[CHASE12]
+UFA Today, pagina 4
-[AM1_7]
-~r~Salvatore è arrivato a casa e si sta bevendo un cocktail. Ma non ti chiamavano lo sciacallo?
+[CHASE13]
+Foto in UFA Today
-[AM1_8]
-~g~Salvatore uscirà dal club Luigi's attorno alle ~1~:~1~
+[CHASE14]
+TV nazionale, 4 AM
-[AM2_4]
-~g~Sei più appariscente di un elefante fluorescente!
+[CHASE15]
+TV nazionale, news
-[AM3_A]
-Un reporter ci è ronzato troppo attorno.
+[CHASE16]
+TV nazionale, servizio in diretta
-[AM3_B]
-Io e Maria ci prenderemo un po' di vacanza fino a quando non ti sarai liberato di questo guardone.
+[CHASE17]
+Avvenimento internazionale
-[AM4_A]
-Il mio truffatore preferito!
+[CHASE18]
+Crisi nazionale
-[AM4_B]
-Maria è molto presa al momento: le dirò che sei passato.
+[CHASE19]
+Crisi internazionale
-[AM4_C]
-Chi è? Asuka? Lo so, sono stata una bambina cattiva, ma devo andare in bagno! OK?
+[CHASE20]
+Evento mondiale
-[AM4_D]
-È giunta l'ora che incontri il nostro uomo nella polizia.
+[CHASE21]
+Roba da leggenda
-[AM4_E]
-Ecco la ricompensa per l'ultimo lavoro che ha svolto per noi.
+[CR_1]
+La gru non può alzare questo veicolo.
-[AM4_F]
-È un tipo molto cauto.
+[PU_MONY]
+Non hai abbastanza soldi.
-[AM4_G]
-Raggiungi in fretta il telefono pubblico a Torrington e aspetta le istruzioni.
+[CO_ALL]
+Li hai presi tutti. Eccoti un piccolo extra...
-[AM5_A]
-Maria e io siamo andati a fare spese.
+[FEM_ON]
+ON
-[AM5_B]
-La nostra fonte alla polizia ci ha informato che uno dei nostri autisti è un maledetto infiltrato!
+[FEM_OFF]
+OFF
-[AM5_C]
-Fuori dalla sua macchina è particolarmente vulnerabile: gli abbiamo posizionato addosso un tracciante.
+[FEM_YES]
+Sì
-[AM5_D]
-Fallo sanguinare!
+[FEM_NO]
+No
-[AM5_1]
-Ben fatto!
+[FEM_RET]
+Riprova
-[AS1]
-'ESCA'
+[FEC_NA]
+ND
-[AS2]
-'ESPRESSO E VIA!'
+[FEC_CWL]
+Scorri armi a sinistra
-[AS4]
-'RISCATTO'
+[FEC_CWR]
+Scorri armi a destra
-[AS1_A]
-~w~Miguel pensa non lo stia trattando correttamente.
+[FEC_LOF]
+Guarda avanti
-[AS1_B]
-~w~Ciò nonostante, mi ha rilevato quanta paura ha Catalina di una tua possibile vendetta.
+[FEC_TAR]
+Bersaglio
-[AS2_A]
-~w~Abbiamo sottovalutato i piani di Catalina per lo SPANK.
+[FEC_MOV]
+Movimento
-[AS2_B]
-~w~È ben più avanti dei Yardie nelle vendite per strada.
+[FEC_CAM]
+Modalità visuale
-[AS2_D]
-~w~Sembra spaccino lo SPANK attraverso i chioschi per strada.
+[FEC_PAU]
+Pausa
-[AS2_1]
-~g~Distrutti tutti i chioschi a Portland!!!
+[FEC_ENV]
+Sali sul veicolo
-[AS2_2]
-~g~Distrutti tutti i chioschi a Staunton Island!!!
+[FEC_JUM]
+Salta
-[AS2_3]
-~g~Distrutti tutti i chioschi a Shoreside Vale!!!
+[FEC_ATT]
+Attacca o fuoco con arma
-[AS2_4]
-~r~Il Cartello ha avvertito i loro spacciatori!
+[FEC_RUN]
+Corri
-[AS2_5]
-~g~Ci sono ancora dei chioschi a Shoreside Vale e a Staunton Island!
+[FEC_FPC]
+Visuale in prima persona
-[AS2_6]
-~g~Ci sono ancora dei chioschi a Shoreside Vale!
+[FEC_LL]
+Guarda a sinistra
-[AS2_7]
-~g~Ci sono ancora dei chioschi a Staunton Island!
+[FEC_LB]
+Guarda indietro
-[AS2_8]
-~g~Ci sono ancora dei chioschi a Portland!
+[FEC_LR]
+Guarda a destra
-[AS2_9]
-~g~Ci sono ancora dei chioschi a Portland e a Shoreside Vale!
+[FEC_HOR]
+Clacson
-[AS2_10]
-~g~Ci sono ancora dei chioschi a Portland e a Staunton Island!
+[FEC_VES]
+Comandi veicolo
-[AS2_12]
-~g~Gira per Liberty alla ricerca dei ~b~chioschi~g~!
+[FEC_BRA]
+Freno o retromarcia
-[AS3_A]
-~w~Dovremmo stringerlo ancora un po' o aspettare che diventi nero e cada?
+[FEC_HAB]
+Freno a mano
-[AS3_B]
-~w~Diamogli uno sprone...
+[FEC_CAW]
+Arma vettura
-[AS3_D]
-~w~Caro il mio truffatore!
+[FEC_ACC]
+Accelera
-[AS3_E]
-~w~Mi stavo annoiando, così sono venuto a fare compagnia a Asuka.
+[FEC_CCF]
+Configurazione :
-[AS3_1]
-~g~Trova una ~r~barca~g~ e raggiungi la ~b~boa segnalatrice~g~!
+[FEC_CF1]
+Config 1
-[AS3_3]
-~g~Attendi fino a quando l'~y~aeroplano~g~ non inizia l'atterraggio!
+[FEC_CF2]
+Config 2
-[AS3_5]
-~g~Raccogli il carico!
+[FEC_CF3]
+Config 3
-[AS3_4]
-~g~Usa un lanciamissili per abbattere l'~g~aeroplano~g~!!!
+[FEC_CF4]
+Config 4
-[AS3_2]
-~b~Raggiungi la boa di segnalazione della pista! ~y~L'aereo sta per atterrare!
+[FEC_CDP]
+Schermata controller :
-[AS3_6]
-~g~~1~ SU 8
+[FEC_ONF]
+A piedi
-[KM1]
-'LA FUGA DI KANBU'
+[FEC_INC]
+In macchina
-[KM3]
-'STRONCA IL PATTO'
+[FEC_VIB]
+Vibrazione :
-[KM4]
-'SHIMA'
+[FEL_ENG]
+Inglese
-[KM5]
-'VENDETTA'
+[FEL_FRE]
+Francese
-[KM1_A]
-Mia sorella mi ha parlato bene di te,
+[FEL_GER]
+Tedesco
-[KM1_E]
-anche se credo ancora che voi gaijin siete tutti quanti deludenti.
+[FEL_ITA]
+Italiano
-[KM1_B]
-Forse mi potresti aiutare a risolvere una situazione che si sta rilevando svantaggiosa.
+[FEL_SPA]
+Spagnolo
-[KM1_F]
-Chiaramente il fallimento ha le sue conseguenze.
+[FED_DBG]
+Menu Debug
-[KM1_C]
-Un Kambu della Yakuza è tenuto in custodia per essere processato.
+[FED_RID]
+Reload IDE
-[KM1_G]
-È un elemento importante della famiglia.
+[FED_RIP]
+Reload IPL
-[KM1_H]
-Liberalo e portalo al dojo a Bedford Point.
+[FED_PAH]
+Parse Heap
-[KM1_D]
-Grazie per la tua azione altruista. Se avrai mai bisogno di aiuto, il dojo sarà onorato di fornirti due uomini pronti ad affiancarti.
+[FED_DFL]
+CTheScripts::DbgFlag
-[KM1_1]
-~g~Ruba una macchina della polizia!
+[FED_DLS]
+Big White Debug Light Switched
-[KM1_2]
-Installa una bomba sulla macchina!
+[FED_SPR]
+Show Ped Road Groups
-[KM1_3]
-~g~Raggiungi il dojo della Yakuza.
+[FED_SCR]
+Show Car Road Grups
-[KM1_5]
-~g~Adesso raggiungi la stazione di polizia.
+[FED_SCZ]
+Show Cull Zones
-[KM1_6]
-Installa una bomba sulla macchina!
+[FED_DSR]
+Debug Streaming Requests
-[KM1_7]
-~g~Solo mezzi della polizia autorizzati!
+[FED_SCP]
+gbShowCollisionPolys
-[KM1_9]
-~r~Non hai utilizzato un'auto esplosiva per distruggere il muro!
+[PL_STAT]
+Statistiche giocatore
-[KM1_10]
-~r~Il Kandu della Yakuza è morto - insieme al tuo onore!
+[PE_WAST]
+Persone massacrate
-[KM1_11]
-~r~Hai attirato la sventura su di te!
+[PE_WSOT]
+Persone massacrate da altri
-[KM2_A]
-Non è consigliabile sottovalutare l'importanza dell'etichetta in questo ambiente.
+[TM_BUST]
+Arresti subiti
-[KM2_B]
-Un uomo mi ha fatto una volta un favore e io non ho avuto l'opportunità di ricambiare la sua gentilezza.
+[GNG_WST]
+Membri delle gang massacrati
-[KM2_C]
-La persona in questione ha la passione delle automobili e mi ha richiesto alcuni modelli per la sua collezione.
+[DED_CRI]
+Criminali massacrati
-[KM2_F]
-Il mio onore lo richiede.
+[PER_COM]
+Percentuale completata
-[KM2_2]
-~g~Macchine consegnate.
+[KGS_EXP]
+Kg di esplosivo utilizzati
-[KM3_A]
-Quando i problemi insorgono, lo stolto mostra la schiena mentre il saggio si prepara ad affrontarli.
+[ACCURA]
+Precisione
-[KM3_B]
-Il Cartello Colombiano ha ignorato ripetutamente le nostre richieste di non interferire con i nostri interessi a Liberty.
+[ST_WEAP]
+Budget armi
-[KM3_C]
-Adesso stanno negoziando con i Giamaicani per nel tentativo di umiliarci ulteriormente.
+[ST_PROP]
+Budget proprietà
-[KM3_D]
-Stanno completando un accordo in città.
+[ST_AUTO]
+Budget riparazioni e colorazione auto
-[KM3_F]
-Prendi uno dei miei uomini, ruba una macchina degli Yardie e vai a porgere i miei saluti ai Colombiani.
+[ST_PHOT]
+Fotografie scattate
-[KM3_E]
-Il nostro onore richiede che nessuno di loro sopravviva.
+[ST_LOAN]
+Visite degli usurai
-[KM3_2]
-~g~Vai a prendere il tuo contatto.
+[ST_STOR]
+Edifici razziati
-[KM3_3]
-~g~L'incontro si svolge nel parcheggio dell'ospedale a Rockford!
+[ST_MOVI]
+Stunt nei film
-[KM3_4]
-~r~Sono fuggiti!
+[ST_PIZZ]
+Pizze consegnate
-[KM3_6]
-~g~Uccidili, uccidili tutti quanti!
+[ST_GARB]
+Spazzatura raccolta
-[KM3_8]
-~g~Hai bisogno di una macchia degli Yardie per completare questa missione!
+[ST_ICEC]
+Gelati venduti
-[KM3_9]
-~r~Uno dei Colombiani è morto: l'accordo è saltato.
+[TOP_SHO]
+Miglior punteggio al poligono
-[KM3_10]
-~r~Il contatto è morto!
+[SHO_RAN]
+Graduatoria al poligono
-[KM4_A]
-Per essere veramente forte, non devi mai mostrare debolezze.
+[SEAGULL]
+Gabbiani abbattuti
-[KM4_C]
-Vai e raccogli immediatamente i soldi per farli riciclare dal Casinò.
+[PROPOWN]
+Proprietà posseduti
-[KM4_1]
-Non ti posso pagare e non lo fare neanche se potessi!
+[ST_TIME]
+Tempo di gioco
-[KM4_9]
-Alcuni delinquenti da strapazzo mi hanno appena rapinato! Hanno preso tutto quanto!
+[ST_FTIM]
+Ore di volo
-[KM4_2]
-La vostra protezione è nulla.
+[ST_PRAN]
+Graduatoria pilota
-[KM4_10]
-E tu saresti della Yakuza? Con quella faccia?
+[ST_RAN0]
+Apprendista
-[KM4_3]
-Non è per questo che vi pago; se volevo essere protetto così bene mi affidavo alla polizia.
+[ST_RAN1]
+Navigatore
-[KM4_4]
-~g~Punisci la gang responsabile del furto dei ~b~soldi~g~!
+[ST_RAN2]
+Copilota
-[KM4_7]
-~r~Il negoziante ha respirato per l'ultima volta!
+[ST_RAN3]
+Pratico
-[KM4_5]
-Donald Love vorrebbe che tu passassi a trovarlo nel suo giardino.
+[ST_RAN4]
+Competente
-[KM4_6]
-Ci sono soldi dappertutto!
+[ST_RAN5]
+Anziano
-[KM4_8]
-~g~Valigetta raccolta!
+[ST_RAN6]
+Asso
-[KM5_A]
-TU! Che piacevole coincidenza vedere il tuo sporco muso proprio adesso!
+[ST_RAN7]
+Barone Rosso
-[KM5_B]
-Sembrerebbe che i tuoi vani tentativi di dissuadere i Giamaicani
+[ST_DRWN]
+Pesci sfamati
-[KM5_B1]
-a collaborare con il Cartello siano miseramente falliti!
+[ST_FASH]
+Budget abbigliamento
-[KM5_C]
-Gli spacciatori Yardie stanno vendendo lo SPANK per ogni strada come se si trattasse di hotdog!
+[ST_DAMA]
+Proprietà distrutte
-[KM5_D]
-I maiali del Cartello stanno ridendoci dietro!
+[TM_DED]
+Visite all'ospedale
-[KM5_E]
-Ti darò un'ultima possibilità per provarmi che la fiducia a te data da mia sorella non era del tutto infondata.
+[DAYSPS]
+Giorni trascorsi nel gioco
-[KM5_F]
-Abbatti tutti i nostri avversari e lava il tuo onore nel loro sangue!!!
+[NUMSHV]
+Visite al rifugio
-[KM5_3]
-~r~Hai fallito nell'eliminare almeno ~1~ Yardie.
+[MXCARD]
+Distanza max salto FOLLE (ft)
-[KM5_4]
-~g~Congratulazioni, hai eliminato ~1~ Yardie.
+[MXCARJ]
+Altezza max salto FOLLE (ft)
-[KM5_5]
-~g~Congratulazioni, hai eliminato ~1~ Yardie. BONUS ~1~$
+[MXCARDM]
+Distanza max salto FOLLE (m)
-[RM1]
-'FAI TACERE L'UCCELLINO'
+[MXCARJM]
+Altezza max salto FOLLE (m)
-[RM3]
-'ELIMINA LE PROVE'
+[MXFLIP]
+Numero max ribaltamenti FOLLI
-[RM4]
-'FUORI A PESCARE'
+[MXJUMP]
+Numero max rotazioni FOLLI
-[RM5]
-'STRONCA L'INFILTRATO'
+[BUL_FIR]
+Colpi sparati
-[RM1_D]
-Si trova sotto protezione in un palazzo della sicurezza testimoni. Il suo appartamento è dietro al parcheggio.
+[BUL_HIT]
+Colpi a segno
-[RM1_E]
-Dai fuoco al palazzo per farlo uscire allo scoperto e fai in modo che non parli mai più.
+[SPRAYIN]
+Riverniciature
-[RM1_1]
-~g~Controlla l'appartamento della sicurezza testimoni.
+[BSTSTU]
+Migliore acrobazia FOLLE
-[RM1_2]
-~g~Elimina McAffrey!
+[INSTUN]
+Acrobazia folle
-[RM2_A1]
-Ehi ragazzo, da questa parte!
+[PRINST]
+Acrobazia folle perfetta
-[RM2_A]
-Un mio vecchio amico ha uno spaccio d'armi a Rockford.
+[DBINST]
+Doppia acrobazia folle
-[RM2_D]
-Ha bisogno di una mano ed è pronto a farti uno scontro sui migliori armamenti in circolazione.
+[DBPINS]
+Doppia acrobazia folle perfetta
-[RM2_E]
-Ray ha appena chiamato... non credevo però che saresti venuto da solo.
+[TRINST]
+Tripla acrobazia folle
-[RM2_F]
-Bene, tre pistole sono meglio di una: prendete ciò che vi serve.
+[PRTRST]
+Tripla acrobazia folle perfetta
-[RM2_G]
-~g~Vai a parlare con Phil!
+[QUINST]
+Quadrupla acrobazia folle
-[RM2_H]
-~r~Phil è stato ucciso!!!
+[PQUINS]
+Quadrupla acrobazia folle perfetta
-[RM2_L]
-Ehi! Se avessi avuto te come compagno in Nicaragua, probabilmente avrei ancora il braccio.
+[NOSTUC]
+Nessuna acrobazia FOLLE effettuata
-[RM2_N]
-Lascia qua il bottino e vattene: mi occuperò io dei poliziotti.
+[NOUNIF]
+Acrobazie uniche completate
-[RM3_D]
-Le prove sono trasportate da un veicolo attraverso la città.
+[NMISON]
+Missioni provate
-[RM3_E]
-Dovrai speronare quella macchina e raccogliere ogni prova che lascerà cadere.
+[PASDRO]
+Passeggeri scaricati
-[RM3_F]
-Quando le avrai raccolte tutte, lasciale in macchina e dalle fuoco.
+[MONTAX]
+Soldi guadagnati in taxi
-[RM3_G]
-Sono sicuro che non avrai problemi a gestire la faccenda.
+[DAYPLC]
+Spesa giornaliera polizia
-[RM3_1]
-~g~Lascia le prove in macchina e dalle fuoco.
+[CRIMRA]
+Livello criminalità:
-[RM3_4]
-~g~L'accusa ha fatto cadere delle prove!
+[STPR_1]
+Malibu
-[RM3_6]
-~r~Le foro saranno sparse per tutta Liberty!
+[STPR_2]
+Tipografia
-[RM3_7]
-~g~Adesso dai fuco alla macchina!
+[STPR_3]
+Studio cinematografico
-[RM4_A]
-Inizio a pensare che il mio socio sia una talpa.
+[STPR_4]
+Fabbrica di gelato
-[RM4_C]
-Esce fuori a pescare sulla sua imbarcazione quasi tutte le notti vicino al faro di Portland.
+[STPR_5]
+Lavaggio auto
-[RM4_D]
-Ruba una lancia della polizia e manda a fondo i suoi piani doppiogiochisti!
+[STPR_6]
+Compagnia di taxi
-[RM4_1]
-~g~Ruba una lancia della polizia.
+[STPR_7]
+Cantiere navale
-[RM4_2]
-~g~Raggiungi il faro e affonda il socio di Ray!
+[SET1EN]
+Config. 1. Abilitata.
-[RM5_A]
-Fottuto inutile!
+[GMSAVE]
+Salva partita
-[RM5_A1]
-Hai combinato un vero casino! Sono con il culo scoperto perché non sei neanche capace di ammazzare una mosca.
+[FEDS_TB]
+Indietro
-[RM5_B]
-Ti ho pagato profumatamente per eliminare il testimone ed è ancora vivo!
+[FEST_OO]
+su
-[RM5_B1]
-E oggi deve fare una deposizione ai federali!
+[FEC_TUC]
+Comandi torretta
-[RM5_C]
-Sta per essere trasferito dall'ospedale Carson fino a Rockford.
+[FEC_RS3]
+Stazioni radio (tasto L3)
-[RM5_D]
-Se canta sono fregato...
+[FEC_HO3]
+Clacson (tasto L3)
-[RM5_E]
-per cui vai ed esegui il lavoro per cui sei stato pagato!
+[C_FAIL]
+Missione Vigilante terminata!
-[RM5_1]
-~g~Intercetta l'ambulanza.
+[C_ESCP]
+~r~Il sospettato è fuggito!
-[RM5_2]
-~g~Sei stato individuato!!!
+[C_VIGIL]
+BONUS VIGILANTE!
-[RM5_3]
-~g~Era un diversivo!
+[HEAL_A]
+La tua ~h~salute~w~ è indicata in color arancione in alto a destra sullo schermo.
-[RM5_4]
-~g~I proiettili non scalfiranno la blindatura!!!
+[WRONGCD]
+Disco errato. Inserisci il disco corretto.
-[RM5_5]
-~g~La blindatura è ignifuga!!!
+[NOCD]
+Il cassetto del disco è vuoto. Inserisci il disco.
-[RM5_7]
-~r~Il testimone è arrivato a destinazione!!!
+[OPENCD]
+Il cassetto del disco è aperto: è necessario chiuderlo.
-[RM5_8]
-~g~Il testimone è affogato!!!
+[CDERROR]
+Errore di lettura dal DVD Grand Theft Auto: Vice City.
-[LOVE2]
-'SPAZZA VIA WAKA-GASHIRA'
+[RESTART]
+Avvio di una nuova partita
-[LOVE3]
-'UNA GOCCIA NELL'OCEANO'
+[GA_3]
+Niente più sconti. $100 per la riverniciatura!
-[LOVE1_A]
-Prima di tutto grazie per aver risolto il problema personale...
+[GA_1]
+Wow! Non tocco niente di COSÌ caldo!
-[LOVE1_F]
-La gente crede a tutto in questi giorni.
+[GA_1A]
+Torna quando non sarai così occupato...
-[LOVE1_D]
-Stanno cercando di estorcermi altri fondi, ma a me non piace chi ritratta all'ultimo minuto.
+[HELP9_C]
+Premi il ~h~~k~~PED_FIREWEAPON~~w~ per ~h~sparare~w~ col fucile di precisione.
-[LOVE1_E]
-Un patto è un patto, per cui non gli sgancerò neppure un altro penny.
+[TAXI2]
+~r~Tempo scaduto!
-[LOVE1_G]
-Vai a salvare il mio amico: fai tutto ciò che si rivelerà necessario.
+[PAGEB13]
+Salute consegnata al nascondiglio
-[LOVE1_2]
-~g~Salva il vecchietto orientale.
+[PAGEB14]
+Adrenalina consegnata al nascondiglio
-[LOVE1_3]
-~g~Riporta il vecchietto orientale all'edificio di Donald Love.
+[FESZ_CA]
+Annulla
-[LOVE1_4]
-~g~Il vecchietto orientale deve trovarsi in uno dei garage...
+[FES_NGA]
+Nuova partita
-[LOVE1_6]
-~r~Le interiora del vecchietto orientale sono sparse per tutta la strada!
+[FES_CAN]
+Annulla
-[LOVE1_7]
-~g~Il cancello verrà aperto solo per un'auto dei Colombiani.
+[FESZ_QL]
+Tutti i progressi della partita attuale non ancora salvati andranno perduti. Vuoi procedere con il caricamento?
-[LOVE2_A]
-Niente abbassa i prezzi degli immobili quanto una bella guerra fra gang...
+[FESZ_QD]
+Vuoi eliminare questa partita salvata?
-[LOVE2_B]
-tranne forse un'epidemia di peste... ma potrebbe non essere la soluzione migliore in questo caso.
+[FESZ_QO]
+Vuoi procedere con la sovrascrittura di questa partita salvata?
-[LOVE2_C]
-È evidente chi la Yakuza e i Colombiani non sono amici per la pelle.
+[FESZ_QR]
+Sei sicuro di voler iniziare una nuova partita? Tutti i progressi fatti fino all'ultimo salvataggio andranno perduti. Vuoi procedere?
-[LOVE2_D]
-Perché non investire in questa opportunità?
+[T4X4_1]
+'Parco divertimenti PCJ'
-[LOVE2_E]
-Voglio che tu uccida il Waka-Gashira della Yakuza, Kenji Kasen.
+[BMX_1]
+'Prova del fango'
-[LOVE2_F]
-Kenji partecipa a un incontro al parcheggio all'ultimo piano di un palazzo a Newport.
+[BMX_2]
+'Tracciato di prova'
-[LOVE2_G]
-Recupera una macchina del Cartello ed eliminalo!
+[BMXFAIL]
+~r~Non sei riuscito a stabilire un nuovo record!
-[LOVE2_H]
-La Yakuza deve dare la colpa al Cartello per questa dichiarazione di guerra.
+[T4X4_3]
+'TENUTA!'
-[LOVE2_1]
-~g~Raggiungi Fort Staunton e ruba una macchina dei Colombiani!
+[MM_1]
+'FOLLIA CONICA'
-[LOVE2_2]
-~g~Raggiungi il ~p~palazzo a Newport~g~ ed elimina Kenji!
+[T4X4_F]
+~r~Ti sei ritirato! Troppo difficile per te?
-[LOVE2_3]
-~r~Se procedi con una macchina non del Cartello, verrai identificato!!!
+[LANDSTK]
+Landstalker
-[LOVE2_4]
-~r~Gli uomini della Yakuza ti hanno identificato!!!
+[IDAHO]
+Idaho
-[LOVE2_6]
-~r~Hai ucciso tutti i testimoni!!!
+[STINGER]
+Stinger
-[LOVE3_A]
-In questi giorni di ipocrisia globale, alcune piacevoli comodità potrebbero essere difficili da importare.
+[LINERUN]
+Linerunner
-[LOVE3_C]
-Farò depositare alcuni pacchi in mare.
+[PEREN]
+Familiare
-[LOVE3_D]
-Assicurati di raccoglierli prima che qualcun altro lo faccia.
+[SENTINL]
+Sentinel
-[LOVE3_1]
-~g~Recupera un'~r~imbarcazione~g~ e insegui l'~y~aeroplano~g~!
+[RIO]
+Rio
-[LOVE4]
-'GRAND THEFT AERO'
+[PATRIOT]
+Patriot
-[LOVE5]
-'SERVIZIO DI SCORTA'
+[FIRETRK]
+Camion dei pompieri
-[LOVE4_A]
-Grazie per aver recuperato i pacchi, ma si trattava solo di un diversivo.
+[TRASHM]
+Nettezza urbana
-[LOVE4_B]
-Mi dispiace, ma sono gli inconvenienti del mestiere.
+[STRETCH]
+Stretch
-[LOVE4_C]
-Il mio vero obiettivo era nascosto all'interno dell'aereo.
+[MANANA]
+Manana
-[LOVE4_F]
-Ho corrotto gli ufficiali.
+[INFERNS]
+Infernus
-[LOVE4_1]
-~r~Il Cartello Colombiano è in zona!!!
+[VOODOO]
+Voodoo
-[LOVE4_2]
-~g~Il pacco è scomparso! Scova i Colombiani e recuperalo!
+[PONY]
+Pony
-[LOVE4_3]
-~g~Panlantic Construction...?
+[MULE]
+Mule
-[LOVE4_5]
-~g~Il pacco dovrebbe essere a bordo dell'aereo...
+[CHEETAH]
+Cheetah
-[LOVE4_6]
-~g~Prendi l'ascensore fino alla cima della torre!
+[AMBULAN]
+Ambulanza
-[LOVE5_B]
-Il mio amico orientale ha bisogno di una scorta mentre porta la mia ultima acquisizione a far autenticare.
+[FBICAR]
+FBI Washington
-[LOVE5_1]
-~g~Procedi!
+[MOONBM]
+Moonbeam
-[LOVE5_2]
-~g~Avrai bisogno di una macchina!
+[ESPERAN]
+Esperanto
-[LOVE5_3]
-~g~Vai avanti a esplorare l'uscita dal sottopassaggio!
+[TAXI]
+Taxi
-[LOVE5_4]
-~r~Proteggi il camion!
+[WASHING]
+Washington
-[RM6]
-'RICERCATO'
+[BOBCAT]
+Bobcat
-[RM6_A]
-Non sei stato seguito? Bene.
+[WHOOPEE]
+Mr Whoopee
-[RM6_B]
-Adesso basta, sono nei guai fino alla gola e sto iniziando a sprofondare!
+[BFINJC]
+BF a iniezione
-[RM6_D]
-Sono ricercato, me la batto.
+[HUNTER]
+Hunter
-[RM6_E]
-Portami al mio volo all'aeroporto e non te ne pentirai!
+[POLICAR]
+Polizia
-[RM6_666]
-Prenditi cura della mia Patriot antiproiettile. Ci vediamo a Miami! Ray
+[ENFORCR]
+Volante
-[CAT1]
-'RISCATTO'
+[SECURI]
+Securicar
-[CAT2]
-'LO SCAMBIO'
+[BANSHEE]
+Banshee
-[CAT1_A]
-Ho la tua cara Maria. Non credo tu voglia che la sua faccia finisca come una polpetta per cani, vero?
+[PREDATR]
+Predator
-[CAT2_F]
-Mi sono rotta un'unghia e i miei capelli sono un disastro. Ma ci puoi credere? Mi è costato 50 dollari!
+[BUS]
+Autobus
-[CAT2_G]
-Ero così spaventata, ma mi sono detta: adesso sei una signorina.
+[RHINO]
+Rhino
-[CAT2_H]
-Oh, ci divertiremo un mondo! Mia sorella mi ha detto che verrà a stare con me insieme ai suoi due figli
+[BARRCKS]
+Caserma OL
-[CAT2_I]
-poiché suo marito continua a tradirla a ogni occasione...
+[CUBAN]
+Cuban Hermes
-[CAT1_C]
-XXXX
+[HELI]
+Elicottero
-[CAT1_D]
-XXXX
+[DODO]
+Dodo
-[CAT1_E]
-XXXX
+[COACH]
+Pullman
-[CAT1_F]
-Raggiungi Catalina prima dello scadere del tempo!
+[CABBIE]
+Vecchio taxi
-[CAT1_G]
-XXXX
+[STALION]
+Stallion
-[CAT1_H]
-XXXX
+[RUMPO]
+Rumpo
-[CAT1_I]
-XXXX
+[RCBANDT]
+Bandit radiocomandato
-[CAT1_J]
-XXXX
+[ROMERO]
+Carro funebre di Romero
-[CAT1_K]
-XXXX
+[PACKER]
+Packer
-[CAT1_L]
-XXXX
+[ADMIRAL]
+Admiral
-[AS4_1]
-XXXX
+[SQUALO]
+Squalo
-[CAT_MON]
-~g~Non hai abbastanza soldi. Ti servono 500.000$.
+[SEASPAR]
+Sea Sparrow
-[BITCH_D]
-~g~Maria è morta!
+[PIZZABO]
+Pizza Boy
-[WEATHER]
-TEMPO AVVERSO
+[GANGBUR]
+Gang Burrito
-[WEATHE2]
-TEMPO NORMALE
+[TROPIC]
+Tropic
-[8001]
-Hai fallito miseramente!!!
+[SPEEDER]
+Speeder
-[1000]
-SEI MORTO
+[REEFER]
+Reefer
-[1001]
-SEI MORTO
+[FLATBED]
+Flatbed
-[1002]
-SEI MORTO
+[YANKEE]
+Yankee
-[1003]
-SEI MORTO
+[CADDY]
+Caddy
-[1004]
-SEI MORTO
+[ZEBRA]
+Taxi Zebra
-[1005]
-SEI STATO CATTURATO
+[TOPFUN]
+Top Fun
-[1006]
-SEI STATO CATTURATO
+[SKIMMER]
+Skimmer
-[1007]
-SEI STATO CATTURATO
+[PCJ600]
+PCJ 600
-[1008]
-SEI STATO CATTURATO
+[PHOENIX]
+Phoenix
-[1009]
-SEI STATO CATTURATO
+[FAGGIO]
+Faggio
-[GA_4]
-Le bombe per le macchine costano 1000$
+[FREEWAY]
+Freeway
-[GA_5]
-La tua macchina ha già una bomba installata.
+[RCBARON]
+Baron radiocomandato
-[GA_6] { re3 change }
-Parcheggiala, attivala premendo il ~h~tasto ~k~~VEHICLE_FIREWEAPON~~w~ e DATTELA A GAMBE!
+[RCRAIDE]
+Raider radiocomandato
-[GA_7] { re3 change }
-Arma la bomba con il ~h~tasto ~k~~VEHICLE_FIREWEAPON~~w~: esploderà non appena qualcuno cercherà di avviarla.
+[GLENDAL]
+Glendale
-[GA_8]
-Usa il detonatore per attivare la bomba.
+[OCEANIC]
+Oceanic
-[GA_9]
-Hai raccolto ~1~ su 10 macchine speciali
+[SANCHEZ]
+Sanchez
-[GA_10]
-Non male. Eccoti ~1~$
+[SPARROW]
+Sparrow
-[GA_11]
-Ne abbiamo già una. A noi non serve!
+[LOVEFIS]
+Love Fist
-[GA_12]
-Bomba innescata
+[COASTG]
+Coast Guard
-[GA_13]
-Un furto da manuale. Completa la lista e ci sarà un bonus per te.
+[DINGHY]
+Dinghy
-[GA_14]
-Hai portato tutte le macchine. BENE! Eccoti un riconoscimento...
+[HERMES]
+Hermes
-[GA_15]
-Spero che ti piaccia il nuovo colore.
+[SABRE]
+Sabre
-[GA_16]
-La riverniciatura non è necessaria.
+[SABRETU]
+Sabre Turbo
-[GA_19]
-Non siamo interessati a questo modello.
+[WALTON]
+Walton
-[GA_20]
-Di questo modello ne abbiamo in abbondanza. Mi dispiace, non siamo interessati.
+[REGINA]
+Regina
-[CR_1]
-La gru non può alzare questo veicolo.
+[COMET]
+Comet
-[PU_MONY]
-Non hai abbastanza soldi.
+[DELUXO]
+Deluxo
-[CO_ALL]
-Li hai presi tutti. Eccoti un piccolo extra...
+[BURRITO]
+Burrito
-[PAUSED]
-PAUSA
+[SPAND]
+Spandex Express
-[HEALTH1]
-Via di qui! Sei in perfetta forma.
+[MARQUIS]
+Marquis
-[HEALTH2]
-L'assistenza medica costa.
+[BAGGAGE]
+Baggage Handler
-[HEALTH3]
-Ti rimetterò in sesto.
+[KAUFMAN]
+Taxi Kaufman
-[HEALTH4]
-Fanno 250$.
+[COASTMA]
+Coastguard Maverick
-[FEB_STA]
-Statistiche
+[MAVERIC]
+Maverick
-[FEB_BRI]
-Briefing
+[RANCHER]
+Rancher
-[FEB_CON]
-Comandi
+[FBIRANC]
+FBI Rancher
-[FEB_AUD]
-Audio
+[VIRGO]
+Virgo
-[FEB_DIS]
-Video
+[GREENWO]
+Greenwood
-[FEB_LAN]
-Lingua
+[HOTRING]
+Hotring Racer
-[FEP_STA]
-STATISTICHE
+[BLISTAC]
+Blista Compact
-[FEP_BRI]
-BRIEFING
+[FEST_DF]
+Distanza a piedi (miglia)
-[FEP_CON]
-COMANDI
+[FEST_DC]
+Distanza in auto (miglia)
-[FEP_AUD]
-AUDIO
+[FESTDFM]
+Distanza a piedi (metri)
-[FEP_DIS]
-VIDEO
+[FESTDCM]
+Distanza in auto (metri)
-[FEP_LAN]
-LINGUA
+[TOT_DIS]
+Distanza totale (miglia)
-[FEF_ST1]
-Chi è il vero cattivo?
+[TOTDISM]
+Distanza totale (metri)
-[FEF_ST2]
-Che casino hai scatenato?
+[DISTHEL]
+Distanza in elicottero (miglia)
-[FEF_BR1]
-Hai perso il filo?
+[DISTHEM]
+Distanza in elicottero (metri)
-[FEF_CO1]
-Hai bisogno di altri controlli?
+[DISTBOA]
+Distanza in barca (miglia)
-[FEF_CO2]
-Scegli la configurazione più adatta al tuo stile di gioco
+[DISTBOM]
+Distanza in barca (metri)
-[FEF_SA1]
-Pensa alla tua posizione, salvala!
+[FEST_LS]
+Persone salvate in ambulanza
-[FEF_SA2]
-Salva e carica le partite
+[FEST_CC]
+Criminali uccisi in missioni Vigilante
-[FEF_AU1]
-Pompa il volume!
+[FEST_FE]
+Incendi estinti
-[FEF_AU2]
-Scegli la stazione radio e gli effetti
+[FEST_RP]
+Violenze eseguite
-[FEF_DI1]
-Cambia il gioco!
+[FEST_MP]
+Missioni completate
-[FEF_DI2]
-Personalizza il gioco per la tua TV
+[FEST_BB]
+Bling-bling Scramble:
-[FEF_LA1]
-What you talking about willis? Che cavolo stai dicendo Willis?
+[FEST_H0]
+Maggior numero di punti di controllo
-[FEF_LA2]
-Scegli il tuo gergo preferito
+[FEST_GC]
+Auto delle gang distrutte:
-[FEB_PMB]
-Brifing di missione precedenti:
+[FEST_H1]
+Distruzione Diablo
-[FEC_NA]
-NA
+[FEST_H2]
+Massacro Mafioso
-[FEC_CWL]
-Scorri armi a sinistra
+[FEST_H3]
+Calamità al Casinò
-[FEC_CWR]
-Scorri armi a destra
+[FEST_H4]
+Demolizioni Rumpo
-[FEC_LOF]
-Guarda avanti
+[USJ]
+BONUS ACROBAZIA UNICA!
-[FEC_TAR]
-Bersaglio
+[RATNG1]
+Cittadino onesto
-[FEC_MOV]
-Movimento
+[RATNG2]
+Sconosciuto
-[FEC_CAM]
-Modalità telecamera
+[RATNG3]
+Pezzente
-[FEC_PAU]
-Pausa
+[RATNG4]
+Furfantello
-[FEC_ENV]
-Sali sul veicolo
+[RATNG5]
+Vandalo
-[FEC_JUM]
-Salta
+[RATNG6]
+Fattorino
-[FEC_ATT]
-Attacca o fuoco con arma
+[RATNG7]
+Borsaiolo
-[FEC_RUN]
-Corri
+[RATNG8]
+Cleptomane
-[FEC_FPC]
-Visuale in prima persona
+[RATNG9]
+Teppista
-[FEC_LL]
-Guarda a sinistra
+[RATNG10]
+Ladruncolo
-[FEC_LB1]
-Guarda
+[RATNG11]
+Sanguisuga
-[FEC_LB2]
-indietro
+[RATNG12]
+Truffatore
-[FEC_LB]
-Guarda indietro
+[RATNG13]
+Farabutto
-[FEC_LR]
-Guarda a destra
+[RATNG14]
+Informatore
-[FEC_HOR]
-Clacson
+[RATNG15]
+Imbroglione
-[FEC_VES]
-Comandi veicolo
+[RATNG16]
+Bullo
-[FEC_RSC]
-Cambia stazione radio
+[RATNG17]
+Canaglia
-[FEC_BRA]
-Freno o retromarcia
+[RATNG18]
+Scapestrato
-[FEC_HAB]
-Freno a mano
+[RATNG19]
+Ruffiano
-[FEC_CAW]
-Arma vettura
+[RATNG20]
+Fuorilegge
-[FEC_ACC]
-Accelera
+[RATNG21]
+Delinquente
-[FEC_SMT]
-Attivatore missione speciale
+[RATNG22]
+Ladro
-[FEA_OUT]
-Uscita:
+[RATNG23]
+Scagnozzo
-[FEA_ST]
-Stereo
+[RATNG24]
+Tirapiedi
-[FEA_MNO]
-Mono
+[RATNG25]
+Avanzo di galera
-[FEA_NON]
-Nessuna
+[RATNG26]
+Ex galeotto
-[FEA_FM0]
-HEAD RADIO
+[RATNG27]
+Criminale
-[FEA_FM1]
-DOUBLE CLEFF FM
+[RATNG28]
+Picchiatore
-[FEA_FM2]
-JAH RADIO
+[RATNG29]
+Saggio
-[FEA_FM3]
-RISE FM
+[RATNG30]
+Autista
-[FEA_FM4]
-LIPS 106
+[RATNG31]
+Guardia del corpo
-[FEA_FM5]
-GAME FM
+[RATNG32]
+Attaccabrighe
-[FEA_FM6]
-MSX FM
+[RATNG33]
+Cacciatore di taglie
-[FEA_FM7]
-FLASHBACK 95.6
+[RATNG34]
+Vigilante
-[FEA_FM8]
-CHATTERBOX 109
+[RATNG35]
+Ronin
-[FED_DBG]
-Menu Debug
+[RATNG36]
+Riparatore
-[FED_RID]
-Reload IDE
+[RATNG37]
+Sicario
-[FED_RIP]
-Reload IPL
+[RATNG38]
+Socio
-[FED_PAH]
-Parse Heap
+[RATNG39]
+Macellaio
-[FED_RCD]
-CCullZones::RecalculateCullZoneData
+[RATNG40]
+Pulitore
-[FED_DFL]
-CTheScripts::DbgFlag
+[RATNG41]
+Assassino
-[FED_DLS]
-Big White Debug Light Switched
+[RATNG42]
+Consigliere
-[FED_SPR]
-Show Ped Road Groups
+[RATNG43]
+Consulente
-[FED_SCR]
-Show Car Road Grups
+[RATNG44]
+Braccio destro
-[FED_SCZ]
-Show Cull Zones
+[RATNG45]
+Esecutore
-[FED_DSR]
-Debug Streaming Requests
+[RATNG46]
+Tenente
-[FED_SCP]
-gbShowCollisionPolys
+[RATNG47]
+Aiutante del boss
-[FEM_MCM]
-Memory Card Menu
+[RATNG48]
+Capo
-[FEM_RMC]
-Registra MEMORY CARD uno
+[RATNG49]
+Boss
-[FEM_TFM]
-Test Format MemCard One
+[RATNG50]
+Intoccabile
-[FEM_TUM]
-Test UnFormat MemCard One
+[RATNG51]
+Don
-[FEM_CRD]
-Create Root Dir
+[RATNG52]
+Re della fottuta città
-[FEM_CLI]
-Crea e carica icone
+[PAGE_00]
+.
-[FEM_FFF]
-Riempi il primo file con fuffa
+[WELCOME]
+BENVENUTO A
-[FEM_SOG]
-Salva solo la partita
+[TSCORE]
+GUADAGNI: ~1~$
-[FEM_CES]
-Verifica ogni salvataggio 0kB4
+[PBOAT_2] { reVC update }
+Premi il ~h~~k~~VEHICLE_FIREWEAPON~~w~ per sparare con i cannoni della barca.
-[FEM_STG]
-Salva la partita
+[HJSTAT]
+Distanza: ~1~.~1~m Altezza: ~1~.~1~m Ribaltamenti: ~1~ Rotazioni: ~1~_
-[FEM_STS]
-Salva la partita con il nome GTA3
+[HJSTATW]
+Distanza: ~1~.~1~m Altezza: ~1~.~1~m Ribaltamenti: ~1~ Rotazioni: ~1~_ E che grande atterraggio!
-[FEM_CPD]
-Crea una cartella mag protetta
+[ATUTOR]
+Premi il ~h~~k~~TOGGLE_SUBMISSIONS~~w~ per attivare o disattivare le missioni Infermiere.
-[FEM_MC2]
-Memory Card Menu 2
+[FEST_HA]
+Livello massimo della missione Infermiere
-[FEM_TS]
-Prova salvataggio:
+[C_KILLS]
+CRIMINALI UCCISI: ~1~
-[FEM_TL]
-Prova caricamento:
+[HJSTATF]
+Distanza: ~1~ piedi Altezza: ~1~ piedi Ribaltamenti: ~1~ Rotazioni: ~1~_
-[FEM_TD]
-Prova eliminazione:
+[HJSTAWF]
+Distanza: ~1~ piedi Altezza: ~1~ piedi Ribaltamenti: ~1~ Rotazioni: ~1~_ E che grande atterraggio!
-[PL_STAT]
-Statistiche giocatore
+[CRED001]
+ROCKSTAR NORTH
-[PE_WAST]
-Persone massacrate
+[CRD001A]
+DIRETTORE DELLO STUDIO
-[PE_WSOT]
-Persone massacrate da altri
+[CRD001B]
+ANDREW SEMPLE
-[CAR_EXP]
-Macchine esplose
+[CRED002]
+PRODUTTORE
-[TM_BUST]
-Tempi battuti
+[CRD002A]
+DIRETTORE DI SVILUPPO
-[M_WASTE]
-Uomini civili massacrati
+[CRED003]
+LESLIE BENZIES
-[F_WASTE]
-Donne civili massacrate
+[CRED004]
+DIRETTORE ARTISTICO
-[PIG_WST]
-Poliziotti massacrati
+[CRED005]
+AARON GARBUT
-[GNG_WST]
-Membri delle gang massacrati
+[CRED006]
+DIRETTORI TECNICI
-[MED_WST]
-Medici massacrati
+[CRED007]
+OBBE VERMEIJ
-[FIRE_WS]
-Pompieri massacrati
+[CRED008]
+ADAM FOWLER
-[DED_CRI]
-Criminali massacrati
+[CRED010]
+ANDREW DUTHIE
-[DED_DED]
-Scrocconi massacrati
+[CRED011]
+CRAIG FILSHIE
-[DED_HOK]
-Prostitute massacrate
+[CRED012]
+WILLIAM MILLS
-[HEL_DST]
-Elicotteri distrutti
+[CRED013]
+CHRIS ROTHWELL
-[PER_COM]
-Percentuale completata
+[CRD013A]
+IMRAN SARWAR
-[KGS_EXP]
-Kg di esplosivi utilizzati
+[CRD013B]
+JAMES WORRALL
-[ACCURA]
-Accuratezza
+[CRD013C]
+JOHN HAIME
-[ELBURRO]
-Miglior tempo di corsa in sec
+[CRED014]
+SCRITTO DA
-[CAR_CRU]
-Macchine distrutte
+[CRED015]
+JAMES WORRALL
-[HED_EX]
-Teste esplose
+[CRED016]
+PAUL KUROWSKI
-[TM_DED]
-Visite in ospedale
+[CRED017]
+DAN HOUSER
-[DAYSPS]
-Giorni trascorsi nel gioco
+[CRED018]
+PROGETTAZIONE PERSONAGGI PRINCIPALI
-[MMRAIN]
-Pioggia caduta in mm
+[CRD018A]
+PROGETTAZIONE PERSONAGGI
-[MXCARD]
-Distanza max salto FOLLE (ft)
+[CRED019]
+IAN MCQUE
-[MXCARJ]
-Altezza max salto FOLLE (ft)
+[CRD019A]
+TOKS SOLARIN
-[MXCARDM]
-Distanza max salto FOLLE (m)
+[CRD019B]
+ALAN DAVIDSON
-[MXCARJM]
-Altezza max salto FOLLE (m)
+[CRED020]
+ANIMATORE CAPO
-[MXFLIP]
-Numero max ribaltamenti FOLLI in aria
+[CRED021]
+ALEX HORTON
-[MXJUMP]
-Numero max rotazioni FOLLI in aria
+[CRD022A]
+ANIMATORI
-[BSTSTU]
-Migliore acrobazia FOLLE:
+[CRED022]
+LEE MONTGOMERY
-[INSTUN]
-Acrobazia folle
+[CRD022B]
+DUNCAN SHIELDS
-[PRINST]
-Acrobazia folle perfetta
+[CRD022C]
+GUS BRAID
-[DBINST]
-Doppia acrobazia folle
+[CRED023]
+PROGETTAZIONE VEICOLI
-[DBPINS]
-Doppia acrobazia folle perfetta
+[CRD023A]
+JOLYON ORME
-[TRINST]
-Tripla acrobazia folle
+[CRD023B]
+ALAN DUNCAN
-[PRTRST]
-Tripla acrobazia folle perfetta
+[CRD024A]
+CAPO PROGETTAZIONE VEICOLI
-[QUINST]
-Quadrupla acrobazia folle
+[CRED024]
+PAUL KUROWSKI
-[PQUINS]
-Quadrupla acrobazia folle perfetta
+[CRED025]
+PROGETTAZIONE MAPPA
-[NOSTUC]
-Nessuna acrobazia FOLLE effettuata
+[CRED026]
+ADAM COCHRANE
-[NOUNIF]
-Acrobazie uniche effettuate
+[CRED027]
+NIK TAYLOR
-[NOUNGM]
-Acrobazie uniche complessive
+[CRED028]
+GARY MCADAM
-[NMISON]
-Missioni provate
+[CRED029]
+KEIRAN BAILLIE
-[NMMISP]
-Missioni superate
+[CRED030]
+ALISDAIR WOOD
-[PASDRO]
-Passeggeri scaricati
+[CRED031]
+ANDREW SOOSAY
-[MONTAX]
-Soldi guadagnati in taxi
+[CRD031A]
+STEVEN MULHOLLAND
-[DAYPLC]
-Spesa giornaliera polizia
+[CRD031B]
+WAYLAND STANDING
-[CRIMRA]
-Livello criminalità:
+[CRD031C]
+CAMPBELL J. DICK
-[GMSTOR]
-Negozio dei giochi
+[CRD031D]
+PROGETTAZIONE GRAFICA
-[PREBRF]
-Briefing precedenti
+[CRD031E]
+STUART PETRI
-[CNTLS]
-Comandi
+[CRED032]
+PROGRAMMATORE CAPO
-[MUSMEN]
-Musica-FX
+[CRD032A]
+PROGRAMMATORI
-[GAMSET]
-Impostazioni
+[CRED033]
+ALEXANDER ROGER
-[LANGUA]
-Lingua
+[CRED034]
+GRAEME WILLIAMSON
-[DSPLAY]
-Video
+[CRED035]
+BARANE CHAN
-[DEBUGM]
-Menu di debug
+[CRED036]
+DEREK PAYNE
-[QUITOP]
-Esci dalle opzioni
+[CRED037]
+GORDON YEOMAN
-[CONTRL]
-Configurazione comandi
+[CRD037A]
+ALAN CAMPBELL
-[SET1EN]
-Configurazione 1. Abilitata.
+[CRD037B]
+MARK HANLON
-[SET1]
-Configurazione 1
+[CRD037C]
+ANDRZEJ MADAJCZYK
-[SET2EN]
-Configurazione 2. Abilitata.
+[CRED038]
+CAPO PRODUZIONE MUSICA
-[SET2]
-Configurazione 2
+[CRED039]
+CRAIG CONNER
-[SET3EN]
-Configurazione 3. Abilitata.
+[CRED040]
+STUART ROSS
-[SET3]
-Configurazione 3
+[CRED041]
+CAPO INGEGNERE AUDIO
-[SET4EN]
-Configurazione 4. Abilitata.
+[CRED042]
+ALLAN WALKER
-[SET4]
-Configurazione 4
+[CRD041A]
+INGEGNERE AUDIO
-[GOBACK]
-Indietro
+[CRD041B]
+AUDIO
-[SOUND]
-SONORO
+[CRD042A]
+WILL MORTON
-[MUSVOL]
-Volume musica
+[CRED043]
+PROGRAMMATORE AUDIO
-[SFXVOL]
-Volume FX
+[CRED044]
+RAYMOND USHER
-[SCROPT]
-OPZIONI SCHERMO
+[CRED045]
+RESPONSABILE TESTING
-[CTRSCR]
-Centra schermo
+[CRED046]
+CRAIG ARBUTHNOTT
-[SCRFOR]
-Formato schermo
+[CRED047]
+CAPO CQ
-[GMSVLQ]
-SALVA-CARICA-ESCI
+[CRED048]
+NEIL CORBETT
-[GMREST]
-Ricomincia partita
+[CRED049]
+KEVIN WONG
-[NOGMSV]
-Puoi salvare solo al tuo nascondiglio.
+[CRED050]
+CQ
-[DLFILE]
-Elimina i file di Grand Theft Auto III
+[CRED051]
+DAVID BEDDOES
-[CHFILE]
-SCEGLI IL FILE DA CARICARE
+[CRED052]
+DAVID WATSON
-[CHCDLD]
-Choose Card to Load From
+[CRED053]
+BARRY CLARK
-[CDUNFR]
-Card is unformatted.
+[CRED054]
+ROSS SPARROW
-[CHFIDL]
-SCEGLI IL FILE DA CANCELLARE
+[CRED055]
+JAMES ALLAN
-[SVCONF]
-SALVA CONFERMA
+[CRED056]
+NEIL MEIKLE
-[SVFNAM]
-Il nome del tuo salvataggio è
+[CRD056A]
+GEORGE WILLIAMSON
-[SAVEDN]
-Errore. Salvataggio non completato.
+[CRD056B]
+MATT JONES
-[LANGSL]
-SCELTA LINGUA
+[CRD056C]
+ROB HARBOUR
-[ENGLIS]
-Inglese
+[CRD056D]
+TOM WHITTAKER
-[GERMAN]
-Tedesco
+[CRED057]
+CAPO SUPPORTO TECNICO
-[ITALIA]
-Italiano
+[CRED058]
+LORRAINE ROY
-[FRENCH]
-Francese
+[CRD057A]
+SUPPORTO TECNICO
-[SPAIN]
-Spagnolo
+[CRED059]
+CHRISTINE CHALMERS
-[RELIDE]
-ReLoadIde
+[CRD060A]
+SUPPORTO UFFICIO
-[RELIPE]
-ReLoadIpl
+[CRD060B]
+KIM GURNEY
-[PARSHP]
-Parse Heap
+[CRD060C]
+CASSIE OLIVER
-[DBGFON]
-CTheScripts::DbgFlag On
+[CRED060]
+ROCKSTAR NEW YORK
-[DBFOFF]
-CTheScripts::DbgFlag Off
+[CRED061]
+PRODUTTORE ESECUTIVO
-[BGWHON]
-Big White Debug Light Switched On
+[CRED062]
+SAM HOUSER
-[BGWOFF]
-Big White Debug Light Switched Off
+[CRED063]
+PRODUTTORE
-[DSTRON]
-Debug Streaming Requests On
+[CRED064]
+DAN HOUSER
-[DSTROFF]
-Debug Streaming Requests Off
+[CRED065]
+VP DI SVILUPPO
-[PDRGON]
-ShowPedRoadGroups On
+[CRED066]
+JAMIE KING
-[PRGOFF]
-ShowPedRoadGroups Off
+[CRED067]
+CAPO RESPONSABILE TECNOLOGICO
-[CRRGON]
-ShowCarRoadGroups On
+[CRED068]
+GARY J. FOREMAN
-[CRGOFF]
-ShowCarRoadGroups Off
+[CRED069]
+PRODUTTORE ASSOCIATO
-[CLZOON]
-Show Cull Zones On
+[CRED070]
+JEREMY POPE
-[CLZOOF]
-Show Cull Zones Off
+[CRD071A]
+DIRETTORE DEL CQ
-[SHPLON]
-gbShowCollisionPolys On
+[CRD072A]
+JEFF ROSA
-[SHPLOF]
-gbShowCollisionPolys Off
+[CRED071]
+SUPERVISORE MUSICA
-[CULREC]
-CCullZones::RecalculateCullZoneData()
+[CRED072]
+TERRY DONOVAN
-[FORMM1]
-FormatMemCard 1 (teststuff)
+[CRED073]
+SQUADRA DI PRODUZIONE
-[UNFRM1]
-UnFormatMemCard 1 (teststuff)
+[CRED074]
+TERRY DONOVAN
-[GORLEV]
-Livello violenza
+[CRED075]
+JENNIFER KOLBE
-[SICASS]
-Stupro
+[CRED076]
+JENEFER GROSS
-[SICSIC]
-Stupratore
+[CRED077]
+LAURA PATERSON
-[SCASSL]
-Stupro selezionato
+[CRED078]
+JEFF CASTANEDA
-[SCSCSL]
-Stupratore selezionato
+[CRED079]
+JERONIMO BARRERA
-[PRVMEN]
-Briefing di missione precedente
+[CRED080]
+CARLY SLATER
-[DOSVGM]
-Vuoi salvare la partita?
+[CRED081]
+JUNG KWAK
-[FORMEN]
-Format Menu
+[CRED082]
+BRIAN WOOD
-[MEMTST]
-MemoryCardTest screen
+[CRED083]
+RENAUD SEBANNE
-[REGCAR]
-Register MemoryCard One
+[CRED084]
+RICHARD KRUGER
-[TEFONE]
-Test Format MemCard One
+[CRD084A]
+DANIEL EINZIG
-[TEUFON]
-Test UnFormat MemCard One
+[CRD084B]
+JACEN BURROWS
-[CRROOT]
-CreaDirRoot
+[CRD084C]
+LINN PR
-[CRLDIC]
-Crea e carica icone
+[CRD084D]
+GRAFICA DI COPERTINA
-[FLFSGF]
-Riempi il primo file con fuffa
+[CRD084E]
+STEPHEN BLISS
-[PUSAVE]
-Salva solo il gioco
+[CRED085]
+KENT PAUL'S 80 NOSTALGIA ZONE
-[CHEVOK]
-VerificaOgniSalvataggioOKB4
+[CRED086]
+COMPOSTA DA DAN HOUSER
-[SVGMON]
-SalvaIlGioco
+[CRD086A]
+PRODOTTA DA ADAM TEDMAN
-[CNTSAV]
-Impossibile salvare il gioco, sei in missione.
+[CRED087]
+WWW.KENTPAUL.COM E WWW.VICECITY.COM
-[CNCSAV]
-Impossibile salvare il gioco, sei in macchina.
+[CRED088]
+CREATO DA
-[CRMGSV]
-Crea cartella magazine protetta
+[CRD088A]
+ADAM TEDMAN
-[MGSVCN]
-Cartella Magazine creata
+[CRD088B]
+DAVID YU
-[MGSVNC]
-Cartella Magazine non creata
+[CRD088C]
+JERRY LUNA
-[YES]
-Sì
+[CRD088D]
+STUART PETRI
-[NO]
-No
+[CRD088E]
+MICHAEL CARNEVALE
-[X]
-x
+[CRD088F]
+GREG LAU
-[LAST]
-Ultimo messaggio.
+[CRD088G]
+FUTABA HAYASHI
-[FEDS_XB]
-Selezione
+[CRED089]
+RESPONSABILE CQ
-[FEDS_ST]
-Tasto START - RIPRENDI
+[CRED090]
+CRAIG ARBUTHNOTT
-[FEST_OO]
-su
+[CRED091]
+CAPO ANALISTA
-[FEC_TUC]
-Torretta di controllo
+[CRED092]
+ADAM DAVIDSON
-[FEC_SM3]
-Attivazione missione speciale (tasto R3)
+[CRD092A]
+JOE HOWELL
-[FEC_RS3]
-Stazioni radio (tasto L3)
+[CRD092B]
+MARC FERNANDEZ
-[FEC_HO3]
-Clacson (tasto L3)
+[CRED093]
+ANALISTA DI GIOCO
-[DIAB1]
-'TURISMO'
+[CRED094]
+RICHARD HUIE
-[DIAB2]
-'IO GRIDO, TU GRIDI'
+[CRED095]
+SQUADRA TESTING ROCKSTAR
-[DIAB3]
-'BATTESIMO DEL FUOCO'
+[CRED096]
+LANCE WILLIAMS
-[DIAB4]
-'GROSSO E ARTERIOSO'
+[CRED097]
+JOE GREENE
-[DIAB1_A]
-El Burro ti vuole offrire un'opportunità. Vai alla cabina telefonica di Hepburn Heights se vuoi saperne di più.
+[CRED098]
+BRIAN PLANER
-[DIAB1_C]
-Sei un pilota provetto. Ripassa per la cabina telefonica, 'El Burro' potrebbe avere altro lavoro per te.
+[CRD098A]
+ELIZABETH SATTERWHITE
-[DIAB1_1]
-~g~3..2..1.. VIA VIA VIA!
+[CRD098B]
+JAMEEL VEGA
-[DIAB1_4]
-~g~Procurati un'auto veloce e vai alla griglia di partenza.
+[CRD098C]
+MIKE HONG
-[DIAB1_3]
-~r~Non riusciresti a vincere neanche una lotteria, FALLITO!
+[CRED099]
+LEE CUMMINGS
-[DIAB1_2]
-~g~Congratulazioni, hai vinto con l'incredibile tempo di ~1~ secondi.
+[CRED100]
+SCENEGGIATURA
-[FIRST]
-~g~Primo
+[CRED101]
+JAMES WORRALL
-[SECOND]
-~g~Secondo
+[CRED102]
+DAN HOUSER
-[THIRD]
-~g~Terzo
+[CRED103]
+ADAM TEDMAN
-[FOURTH]
-~g~Quarto
+[CRED104]
+PAUL YEATES
-[DIAB2_1]
-~g~Prendi la valigia ad Harwood.
+[CRED105]
+JENEFER GROSS
-[DIAB2_2]
-~g~Trova un furgone dei gelati.
+[CRED106]
+LAURA PATERSON
-[DIAB2_3]
-~g~Parcheggia il furgone dei gelati al molo atlantico.
+[CRED107]
+SEQUENZE ANIMATE
-[DIAB2_4]
-~g~Premi il ~w~tasto ~k~~VEHICLE_HORN~ ~g~per attivare il campanello.
+[CRED108]
+SCRITTE DA DAN HOUSER E JAMES WORRALL
-[DIAB2_6]
-~g~Premi il ~w~tasto ~k~~VEHICLE_HORN~ ~g~per attivare il campanello.
+[CRED109]
+DIREZIONE AUDIO DI DAN HOUSER E NAVID KHONSARI
-[DIAB2_7]
-~g~Premi il ~w~tasto ~k~~VEHICLE_HORN~ ~g~per attivare il campanello.
+[CRED110]
+PRODOTTE DA JAMIE KING
-[DIAB2_5]
-~g~Esci dal furgone dei gelati e usa il telecomando per farlo esplodere.
+[CRD110A]
+RICERCA TALENTI: JAMIE KING, SEAN MACALUSO
-[YD1]
-'BLING-BLING SCRAMBLE'
+[CRED111]
+CAST
-[YD2]
-'UZI RIDER'
+[CRD111A]
+PERSONAGGI PRINCIPALI
-[YD3]
-'CORSA TRA GANGSTER'
+[CRED112]
+TOMMY VERCETTI - RAY LIOTTA
-[YD4]
-'VENGA IL TUO REGNO'
+[CRED113]
+KEN ROSENBERG - WILLIAN FICHTNER
-[YD_P]
-King Courtney vuole parlarti. Vai alla cabina telefonica ad Aspatria!
+[CRED114]
+SONNY FORELLI - TOM SIZEMORE
-[YD1_A]
-~w~Sono King Courtney.
+[CRED115]
+STEVE SCOTT - DENNIS HOPPER
-[YD1_A1]
-~w~Alla mia cricca Yardie servirebbe un buon autista e tu hai un'ottima reputazione.
+[CRED116]
+AVERY CARRINGTON - BURT REYNOLDS
-[YD1_B]
-~w~Vai in macchina alla discarica dalla parte opposta dello stadio e aspetta gli altri aspiranti.
+[CRED117]
+RICARDO DIAZ - LUIS GUZMAN
-[YD1_C]
-~w~Ho uomini di guardia in postazioni sparse per tutta Staunton.
+[CRED118]
+LANCE VANCE - PHILIP MICHAEL THOMAS
-[YD1_D]
-~w~Il primo pilota che raggiunge una postazione prende $1000, e cosi via fino alla tappa successiva.
+[CRED119]
+COLONNELLO JUAN CORTEZ - ROBERT DAVI
-[YD1_D1]
-~w~Se raggiungi per primo più postazioni degli altri piloti, potrei avere del lavoro per te.
+[CRED120]
+UMBERTO ROBINA - DANNY TREJO
-[YD1_E]
-~g~Preparati alla gara!
+[CRED121]
+PHIL CASSIDY - GARY BUSEY
-[YD1_F]
-~g~Hai anticipato la partenza; mi piace il tuo stile!
+[CRED122]
+MITCH BAKER - LEE MAJORS
-[YD1_G]
-~r~È una GARA AUTOMOBILISTICA. Ti serve un'AUTO, idiota!
+[CRED123]
+MERCEDES CORTEZ - FAIRUZA BALK
-[YD1GO]
-~g~VIA!
+[CRED124]
+KENT PAUL - DANNY DYER
-[YD1_1]
-~r~1
+[CRED125]
+JEZZ TORRENT - KEVIN MCKIDD
-[YD1_2]
-~r~2
+[CRED126]
+CENTRALINISTA TAXI - DEBORAH HARRY
-[YD1_3]
-~r~3
+[CRED127]
+CANDY SUXX - JENNA JAMESON
-[YD1_BON]
-$1000!
+[CRED128]
+BJ SMITH - LAWRENCE TAYLOR
-[Y1_1ST]
-~g~Sei arrivato primo con ~1~ postazioni!
+[CRED129]
+AUNTIE POULET - YOUREE CLEOMILI HARRIS
-[Y1_2ND]
-~y~Sei arrivato secondo con ~1~ postazioni. ~y~Non male, ma non sei il migliore!
+[CRED130]
+SPACCIATORE - ARMANDO RIESCO
-[Y1_3RD]
-~r~Sei arrivato terzo con ~1~ postazioni. ~r~Credevo avessi detto di essere in gamba!
+[CRED131]
+COUGAR - BLAYNE PERRY
-[Y1_LAST]
-~r~Sei arrivato ultimo! ~r~Mi hai fatto perdere tempo, IDIOTA!
+[CRED132]
+HILARY - CHARLES TUCKER
-[Y1_J1ST]
-~y~Primo a pari merito con ~1~ postazioni. ~y~Bravo, ma devi essere il migliore per guidare per Queen Lizzy!
+[CRED133]
+DEPUTATO ALEX SHRUB - CHRIS LUCAS
-[Y1_J2ND]
-~r~Secondo a pari merito con ~1~ postazioni. Guidi come una scimmia impazzita!
+[CRED134]
+VECCHIO KELLY - GEORGE DICENZO
-[Y1JLAST]
-~r~Ultimo a pari merito! Sei più veloce con la lingua che con l'auto!
+[CRD134A]
+CAM JONES - GREG SIMS
-[Y1_TEST]
-AUTO IN ACQUA!
+[CRD134B]
+PSICOPATICO - HUNTER PLATIN
-[YD2_A]
-~w~Devo vedere se sei in grado di eseguire certi lavoretti per me.
+[CRD134C]
+MAUDE, LA SIGNORA DEI GELATI - JANE GENNARO
-[YD2_A1]
-~w~Vediamo se ci si può fidare di te.
+[CRD134D]
+JETHRO - JOHN ZURHELLEN
-[YD2_B]
-~w~Due dei miei ragazzi saranno lì a momenti per accompagnarti in un giro:
+[CRD134E]
+GONZALES - JORGE PUPO
-[YD2_B1]
-~w~vedremo se sei davvero chi dici di essere.
+[CRD134F]
+DWAYNE - NAVID KHONSARI
-[YD2_C]
-~w~Andiamo a fare un giro a Hepburn Heights: levaci di torno alcuni di quei luridi Diablo che mancano di rispetto a Queen Lizzy.
+[CRD134G]
+DICK - PETER MCKAY
-[YD2_CC]
-~w~Prendi, ti serviranno 'i ferri del mestiere'.
+[CRD134H]
+MIKE & PORNOSTAR - ROBERT CIHRA
-[YD2_D]
-~w~Dovrai guidare e sparare. Noi faremo in modo che tu non finisca al creatore.
+[CRD134I]
+PERCY - RUSSELL FOREMAN
-[YD2_E]
-~w~Comincia a guidare!
+[CRED135]
+MOTION CAPTURE
-[YD2_F]
-~r~Ci è scappato! Facciamo secco quel bastardo muso giallo!!!
+[CRED136]
+ANIMATO DA
-[YD2_G1]
-~w~Hepburn Heights... Facciamo fuori qualche lurido Diablo...
+[CRD136A]
+DIREZIONE TECNICA DI ALEX HORTON
-[YD2_G2]
-~w~Ma ricorda: ~r~non pensare di uscire da quest'auto!
+[CRED137]
+DIRETTO DA
-[YD2_H]
-~w~OK, riportaci nel territorio di Yardie! VIA VIA VIA!!!
+[CRD137A]
+DIRETTO DA NAVID KHONSARI
-[YD2_L]
-~w~Bel lavoro, Cecchino!
+[CRED138]
+PRODOTTO DA
-[YD2_M]
-~r~Ha distrutto la mia auto! Fallo secco!
+[CRD138A]
+PRODOTTO DA JAMIE KING
-[YD2_N]
-~w~Rimetti il culo in macchina!
+[CRD138B]
+RENAUD SEBBANE
-[YD3_A]
-Devi rubare alcune auto delle gang avversarie
+[CRED139]
+REGISTRATO PRESSO PERSPECTIVE STUDIOS, BROOKLYN
-[YD3_A1]
-per poter colpire nel loro territorio.
+[CRED140]
+ATTORI MOTION CAPTURE
-[YD3_B]
-Mi serve una Sentinel della Mafia,
+[CRD140A]
+BLAYNE PERRY
-[YD3_B1]
-una Stinger della Yakuza e uno
+[CRD140B]
+JONATHON SALE
-[YD3_B2]
-Stallion dei Diablo per poter attaccare qualunque gang di Liberty.
+[CRD140C]
+CHARLES TUCKER
-[YD3_C]
-Parcheggiale nel garage a Newport e ricorda,
+[CRD140D]
+EDDIE MARRERO
-[YD3_C1]
-se le distruggi sono inutilizzabili!
+[CRD140E]
+WILLIAM MCCALL
-[YD3_D]
-Etichetta testo aggiuntiva
+[CRD140F]
+JORGE PUPO
-[YD3_E]
-~r~Hai già rubato un'auto dei Diablo!
+[CRD140G]
+ROBERT JACKSON
-[YD3_F]
-~r~Hai già rubato un'auto della Mafia!
+[CRD140H]
+TARA RADCLIFFE
-[YD3_G]
-~r~Hai già rubato un'auto della Yakuza!
+[CRD140I]
+JENIFER GAMBETESE
-[YD3_H]
-~g~Auto dei Diablo rubata!
+[CRD140J]
+KRIS ACHEVARRIA
-[YD3_I]
-~g~Auto della Mafia rubata!
+[CRD140K]
+ALI ORDOUBADI
-[YD3_J]
-~g~Auto della Yakuza rubata!
+[CRD140L]
+KAHLEEM POOLE
-[YD3_K]
-~r~L'auto è quasi un rottame! Falla riparare!
+[CRED141]
+DIALOGHI PEDONI
-[YD3_L]
-~g~Portala al ~p~garage!
+[CRD141A]
+SCRITTI DA DAN HOUSER, MARC FERNANDEZ, GILLIAN TELLING E NAVID KHONSARI
-[YD3_M]
-~r~Hai cappottato l'auto! Procuratene un'altra!
+[CRD141B]
+CON L'AIUTO DI JEREMY POPE, LANCE WILLIAMS E JENNY JEMISON
-[YD4_A]
-Stammi a sentire!
+[CRED142]
+SCRITTI DA
-[YD4_A1]
-Arriva fino a Bedford Point.
+[CRD142A]
+DAN HOUSER E JAMES WORRALL
-[YD4_A2]
-C'è della roba nascosta in una vecchia automobile che mi serve subito!
+[CRED143]
+DIRETTI DA DAN HOUSER, CRAIG CONNER, MARC FERNANDEZ E ALLAN WALKER
-[YD4_B]
-LETTERA: Ho saputo che ti sei dato da fare. Beh mi sono data da fare anch'io.
+[CRED144]
+PRODOTTI DA RENAUD SEBANNE
-[YD4_C]
-Credo sia ora che tu provi il vero potere dello 'SPANK'! Baci e abbracci, Catalina, con amore.
+[CRED145]
+PEDONI
-[YD4_D]
-PS: MUORI CANE BASTARDO, MUORI!
+[CRED146]
+ADAM DAVIDSON, ADAM WATKINS, ALEJANDRO K. BROWN, ALEX ANTHONY SIOUKAS, ALEX GARCIA,
-[YD4_1]
-Pazzi strafatti di SPANK!
+[CRED147]
+ALICE SALTZMAN, ALISON CIHRA, AMY SALIMA, AMY SALZMAN, ANDREA VIDELA, ANTHONY ATTI,
-[YD4_2]
-Distruggi i camion di SPANK!
+[CRED148]
+ANTHONY RIVERA, BIJAN SHAMS, BLAYNE PERRY, BRETT BISOGNO, BREYE MATA, BRIAN PANEN,
-[HM_1]
-'SOLDI E UZI'
+[CRED149]
+BROCK VODER, CAREY BERTINI, CHARISSE LAMBERT, CHRIS DIFAT, CHRIS REISENBERGER,
-[HM_2]
-'STERMINATOR'
+[CRED150]
+CHRISTOPHER BRODAY, CHRISTOPHER CARRO, CYNTHIA GREENE, DAMARIES LOPEZ, DAN LEE,
-[HM_3]
-'PRONTO A ESPLODERE'
+[CRED151]
+DAN SCHNEIDER, DAN TOYAMA, DAVID DEAN CHALTFIELD, JR., DAVID HARRISON, DAVID WILEY,
-[HM_5]
-'RISSA'
+[CRED152]
+DEBORAH COLLINS, DEBRANDA CHANEY-GILES, DEMETRA KOUKOULAS, DENISE ROSADO,
-[HOOD1_A]
-Raggiungi il telefono pubblico dei giardini Wichita se vuoi parlare d'affari.
+[CRED153]
+DEVIN BENNETT, DEVIN WINTERBOTTOM, DORIS WOO, DOUGLAS HARRISON, DUNCAN COUTTS,
-[HM1_A]
-Ehi, sono D-Ice dei Red Jack!
+[CRED154]
+DUPE AJAYI, EDWIN AVELLANEDA, ELIZABETH HOWELL, ELIZABETH SATTERWHITE, ERIC NAGLE,
-[HM1_C]
-Questi stronzetti scorrazzano per le strade con nient'altro che armi e SPANK nella testa.
+[CRED155]
+ESTEBAN KARPLUS, F. FONT, FUTABA HAYASHI, GENE HILGREEN, GERALD COSGROVE,
-[HM1_3]
-~g~I 'Nine' controllano il territorio dei giardini Wichita.
+[CRED156]
+GERARD LUNA, GILLIAN TELLING, GREGG CARLUCCI, GREGORY CLERVOIX, GREGORY SCHWEIZER,
-[HM2_3]
-Se colpisci i pneumatici, il maggiolino radiocomandato esploderà!
+[CRED157]
+HADLEY TOMICKI, J. ROSSETT, JAMEEL VEGA, JASON JONES, JEFF ROSA, JENNIFER JEMISON,
-[HM2_4]
-Se supera la portata massima, il maggiolino radiocomandato esploderà!
+[CRED158]
+JEREMY TAGGERT, JESSICA RIDER, JOSEPH GREENE,JOSEPH HOWELL, KATE DUKICH,
-[HM2_5]
-~r~Fuori dalla portata massima!
+[CRED159]
+KEL O'NEILL, KEVIN HOPKINS, LADAWN JAMES, LANCE WILLIAMS, LAURA BUBBLES,
-[HM3_1]
-~g~Vai al garage, ma stai attento: se l'auto viene danneggiata troppo, salterà in aria!
+[CRED160]
+LAURA PATTERSON, LEE CUMMINGS, LETICIA L. YOUNG, LINDSAY KENNEDY, LISA ORITZ,
-[HM3_2]
-~g~Riporta l'auto in ottime condizioni: nessun danno!
+[CRED161]
+LORNA JORDAN, LUCIO AMADIO, MARCO FERNANDEZ, MARIKO TANAKA, MARLON MATTHEWS,
-[HM3_3]
-~g~Fai riparare l'auto!
+[CRED162]
+MARY TELLING, MASAYOSHI MITSUYAMA, MATTHEW CHUNG, MAX ALLSTADT, MAX BOGDANOV,
-[HM4_D]
-~g~Prendi un veicolo!
+[CRED163]
+MELISSA ALVAREZ, MICHAEL MAY, MICHAEL ROTHSTEIN, MIGUEL VIDAL, MIKE FEDERLINE,
-[HM4_E]
-TESTO NON PIÙ NECESSARIO
+[CRED164]
+NATALIE DESCALZO, N'GAI MEMBERS, NICOLAS MALLO, NOELLE SADLER, NORBERT MORIVAN,
-[HM4_1]
-~g~Dirigiti nel posto dove il carico s'è rovesciato: dovrai raccogliere almeno 30 lingotti.
+[CRED165]
+OSWALD GREENE, JR., PETER MCKAY, PETER APPEL, PRESTON SAVARESE, RAFAEL GONZALES,
-[HM4_2]
-~g~Ricorda di raggiungere il garage e depositare il carico quando il veicolo diventa troppo pesante e lento.
+[CRED166]
+RANDY JOHNSON, REY CONCEPCION, RICHARD KROGER, ROB TIBBS, ROBERT JACKSON,
-[HM5_3]
-~r~Dovevi usare solo una mazza da baseball!
+[CRED167]
+ROBERT SCHULER, ROSS A. MCINTYRE, RUSSELL FOREMAN, RUTH NUNEZ, SALVADORE SUAZO,
-[HM5_4]
-~r~Il tuo intermediario è morto!
+[CRED168]
+SAM WHITE, SANTOS GONZALES, SCOTT SMITH, SEYMOUR FRAILMAN, SPELMAN BRAUMAN,
-[MEA1]
-'L'IMBROGLIONE'
+[CRED169]
+STEPHANIE TELLING, STEVE KNEZEVICH, STEVE ROBERT, SUMIKO YASUDA, SUSAN LEWIS,
-[MEA2]
-'I LADRI'
+[CRED170]
+SYLVIA COLACIOS, TOMOKO MIYAZAKI, TRON, VERDEL HALE, YVES MONDESIR, ZENO LEINFELDER,
-[MEA3]
-'LA MOGLIE'
+[CRED171]
+DAVID BEDDOES, CHRISTINE CHALMERS, BARRY CLARK, NEIL CORBETT, KIM GURNEY, NEIL MEIKLE,
-[MEA4]
-'L'AMANTE'
+[CRED172]
+CASSIE OLIVER, LORRAINE ROY, DAVID WATSON, KEVIN WONG, WILL MORTON
-[MEAT1_A]
-Un amico mi ha detto che puoi risolvermi dei problemi. Vai alla cabina telefonica a Trenton se credi di essere la persona giusta.
+[CRED175]
+ADAM DAVIDSON
-[MEA1_B3]
-~g~Devi incontrare il direttore della banca.
+[CRED176]
+LANCE WILLIAMS
-[MEA1_B6]
-~g~Porta l'auto dal rottamatore per distruggere le prove: esci dall'auto e la gru la raccoglierà.
+[CRED177]
+NEIL MCCAFFREY
-[MEA1_1]
-~r~Il direttore della banca è morto!
+[CRED178]
+LAURA PATERSON
-[MEA1_2]
-~r~Ti era stato detto di rottamare il veicolo!
+[CRED179]
+REY CONCEPCION
-[MEA1_3]
-~g~Esci dalla macchina!
+[CRED180]
+CHARLES HEROLD
-[MEA1_4]
-~r~Ti sei dimenticato del direttore della banca!
+[CRED181]
+ANDREW GREENWALD
-[MEA2_B3]
-~g~Vai a incontrare i ladri.
+[CRED182]
+JAMES MIELKE
-[MEA2_B4]
-~g~Accompagnali alla fabbrica di cibo per cani Bitch'n' Dog.
+[CRED183]
+PETER SUCIU
-[MEA2_B6]
-~g~Fai riverniciare l'auto per eliminare ogni prova.
+[CRED184]
+ALEX ODULIO
-[MEA2_1]
-~r~Ti era stato detto di far rottamare il veicolo!
+[CRED185]
+DON NKRUMAH
-[MEA2_2]
-~r~Un ladro è morto!
+[CRED186]
+KENDALL PITTMAN
-[MEA2_4]
-~r~Ti sei dimenticato un ladro!
+[CRED187]
+SAL SUAZO
-[MEA3_B3]
-~g~Vai a prelevare la signora Chonks.
+[CRED188]
+EREK MATEO
-[MEA3_B6]
-~g~Prendi l'auto e scaricala in mare: questo cancellerà ogni prova.
+[CRED189]
+CHRIS DIFATE
-[MEA3_1]
-~r~La moglie è morta!
+[CRED190]
+LEILA MILTON
-[MEA3_2]
-~r~Dovevi scaricare il veicolo in mare!
+[CRED191]
+DARREN ZOLTOWSKI
-[MEA3_3]
-~r~Ti sei dimenticato di della moglie!
+[CRED192]
+VIRGINIA SMITH
-[MEA4_B3]
-~g~Vai a prendere l'amante della moglie.
+[CRED193]
+KEVIN CASSIN
-[MEA4_B6]
-È davvero troppo tardi per farlo, Marty. Ti ho dato una chance, ma adesso prenderò io il controllo del tuo business...
+[CRED194]
+JASON SHIGEMORI
-[MEA4_1]
-~r~Carlos è morto!
+[CRED195]
+KELLY KINSELLA
-[MEA4_3]
-~r~Ti sei dimenticato di Carlos lo strozzino!
+[CRED196]
+MOLLIE STICKNEY
-[LOOK_A]
-Tieni premuto il ~h~tasto ~k~~VEHICLE_LOOKLEFT~ ~w~o il ~h~tasto ~k~~VEHICLE_LOOKRIGHT~~w~ per guardare a ~h~sinistra~w~ o a ~h~destra~w~ mentre sei nel veicolo. Premi entrambi i tasti per guardare ~h~indietro~w~.
+[CRED197]
+STANTON SARJEANT
-[LOVE6_1]
-~g~Adesso attira gli sbirri lontano dai magazzini!
+[CRED198]
+LAURA WALSH
-[LOVE6_2]
-~r~Non sei riuscito ad attirare gli sbirri abbastanza lontano!
+[CRED199]
+MARK GARONE
-[RM4_3]
-~r~Il socio di Ray è fuggito!
+[CRED200]
+JOANNA SLY
-[RM6_C]
-La CIA sembra interessata allo SPANK
+[CRED201]
+ELIZABETH HOWELL
-[RM6_C1]
-e non vogliono che interferiamo con il Cartello.
+[CRED202]
+ANA HERCULES
-[C_PASS]
-MINACCIA ELIMINATA!
+[CRED203]
+SHIRLEY IRICK
-[CTUTOR]
-Premi il ~h~tasto ~k~~TOGGLE_SUBMISSIONS~~w~ per attivare o disattivare le missioni Vigilante.
+[CRED204]
+KASHONA FIELDS
-[CTUTOR2]
-Premi il ~h~tasto ~k~~TOGGLE_SUBMISSIONS~~w~ per attivare o disattivare le missioni Vigilante.
+[CRED205]
+JOEL M. LILJE
-[COPCART]
-~g~Hai ~1~ secondi per tornare a un mezzo della polizia prima che termini la missione.
+[CRED206]
+JOHN DIBENEDETTO
-[C_FAIL]
-Missione Vigilante terminata!
+[CRED207]
+NANCY GILES
-[C_CANC]
-~r~Missione Vigilante annullata!
+[CRED208]
+RYAN CROY
-[C_ESCP]
-~r~Il sospetto è fuggito!
+[CRED209]
+JENNIFER KOLBE
-[C_TIME]
-~r~È scaduto il tuo tempo come tutore della legge!
+[CRED210]
+LIAM BURKE
-[C_VIGIL]
-BONUS VIGILANTE!
+[CRED211]
+SIGRID PREISSL
-[A_FAIL2]
-~r~La tua scarsa sollecitudine è stata fatale al paziente!
+[CRED212]
+ANITA FITZSIMONS
-[A_FAIL3]
-~r~Il paziente è morto!
+[CRED213]
+PHILIPPA RASELLI
-[A_PASS]
-Salvato!
+[CRED214]
+WIL QUESNEL
-[F_FAIL2]
-~r~Sei arrivato tardi!
+[CRED215]
+FALKO BURKERT
-[A_COMP2]
-Non ti stancherai mai!
+[CRED216]
+SARA SEWELL
-[RM2_M]
-Se ti servono armi da fuoco, passa di qui e prendi ciò che ti serve dagli armadietti.
+[CRED217]
+STAZIONI RADIO E MUSICA
-[HEAL_A]
-La tua ~h~salute~w~ è indicata in color arancione in alto a destra sullo schermo.
+[CRED218]
+CONSULENZA MUSICALE
-[YD1_CNT]
-~1~ su 15!
+[CRD218A]
+HEINZ HENN
-[FM1_9]
-~g~Lì davanti c'è il party: fai scendere Maria all'ingresso.
+[CRD218B]
+STUART ROSS
-[FM1_Y]
-~w~Sai, non mi divertivo così tanto da una vita, e mi hai trattato proprio bene. Con molto rispetto.
+[CRED219]
+COORDINATORE TRACCE AUDIO
-[FM1_AA]
-~w~Oh, devo andare. Spero di rivederti.
+[CRED220]
+TERRY DONOVAN
-[NOCONTE]
-Ricollega il controller analogico (DUALSHOCK#) o controller analogico (DUALSHOCK#2) all'ingresso controller 1 per continuare.
+[CRED221]
+PRODUTTORI ROCKSTAR GAMES
-[WRCONT]
-Il controller collegato all'ingresso controller 1 non è supportato. Grand Theft Auto III richiede un controller analogico (DUALSHOCK#) o (DUALSHOCK#2).
+[CRED222]
+DAN HOUSER E LAZLOW
-[WRCONTE]
-Il controller collegato all'ingresso controller 1 non è supportato. Grand Theft Auto III richiede un controller analogico (DUALSHOCK#) o controller analogico (DUALSHOCK#2).
+[CRED223]
+PRODUTTORE ROCKSTAR NORTH
-[WRONGCD]
-Disco errato. Inserisci il disco corretto.
+[CRED224]
+CRAIG CONNER
-[NOCD]
-Il vano cassetto del disco è vuoto. Inserisci il disco.
+[CRED225]
+ALLAN WALKER
-[OPENCD]
-Il vano cassetto del disco è aperto. Chiudi il vano.
+[CRED226]
+LAZLOW
-[CDERROR]
-Errore di lettura del DVD Grand Theft Auto III.
+[CRED227]
+DJ BANTER E IMAGING
-[RESTART]
-Avvio di una nuova partita
+[CRED228]
+SCRITTO DA DAN HOUSER E LAZLOW
-[GA_3]
-Niente più sconti. $1000 per la riverniciatura!
+[CRED229]
+FLASH FM
-[GA_1]
-Wow! Non tocco niente di COSÌ caldo!
+[CRD229A]
+TONI-MARIA CHAMBERS
-[GA_1A]
-Torna quando non sarai così occupato...
+[CRD229B]
+VOCE E PRODUZIONE IMAGING - JEFF BERLIN
-[S_PROM2]
-Nel garage qua accanto puoi parcheggiare un veicolo quando salvi la partita.
+[CRED230]
+UN RINGRAZIAMENTO SPECIALE A
-[STOCK]
-scorte esaurite
+[CRED231]
+TOMMY MOTTOLA,
-[FM1_O]
-~w~Credo si trovi alla stazione vicino al porto di Chinatown.
+[CRED232]
+MICHELLE ANTHONY,
-[EBAL_B]
-Siamo arrivati, togliamoci dalla strada e cerchiamo di cambiarci d'abito!
+[CRED233]
+STEVE BARNETT,
-[EBAL_G]
-Questo è il club Luigi's. Passiamo dal retro attraverso la porta di servizio.
+[CRED234]
+CHUCK FLECKENSTEIN,
-[AM4_3]
-Tu devi essere il nuovo tuttofare di Asuka!
+[CRED235]
+RITA LIBERATOR
-[AM4_4]
-Hai i soldi? Tutto qui?
+[CRED236]
+MARTIN & CLAIRE LOGAN
-[AM4_5]
-So cosa pensi, un altro sbirro corrotto.
+[CRED237]
+SANDRA HUTTON
-[AM4_6]
-Beh, il mondo è corrotto.
+[CRED238]
+CHRISTINE DAVIDSON
-[AM4_7]
-Solo perché ho perso dei partner, quegli idioti degli Affari Interni hanno cominciato a curiosare.
+[CRED239]
+ALAN, RED & BIGFOOT
-[AM4_8]
-Immagino che sentano puzza di bruciato.
+[CRED240]
+LE T
-[AM4_9]
-Beh, questa città è una grande fogna.
+[CRED241]
+COLIN DONALD
-[AM4_10]
-Mi servirà aiuto anche fuori dai sindacati.
+[CRED242]
+KERRY STALLWOOD
-[AM4_11]
-Se sei interessato, sai dove trovarmi.
+[CRED243]
+ALAN MCGREGOR
-[CAM_A]
-Premi il ~h~tasto ~k~~CAMERA_CHANGE_VIEW_ALL_SITUATIONS~~w~ per cambiare le ~h~modalità di visuale ~w~quando sei a piedi o in un veicolo.
+[CRED244]
+CHRIS MORTON
-[CAM_B]
-Premi il ~h~tasto direzionale in alto~w~ e ~h~in basso~w~ per cambiare le ~h~modalità di visuale ~w~quando sei a piedi o in un veicolo.
+[CRED245]
+EMIL BUSSE
-[KM2_1]
-~g~Ripara l'auto, sarà come nuova.
+[CRED246]
+EMILY BAILLIE
-[LM3_6]
-Joey...
+[CRED247]
+KEVIN ARCHIBALD
-[LM3_6A]
-Mi farai giocare ancora col tuo pistone?
+[CRED248]
+MORAG KERR
-[LM3_9A]
-Potrebbe esserci del lavoro per te.
+[CRED249]
+CATH WALKER
-[LM3_9B]
-OK?
+[CRED250]
+ISO BAR
-[AWAY2]
-~r~Sono scappati.
+[CRED251]
+WATERLINE
-[AWAY]
-~r~È scomparso nel nulla!
+[CRED252]
+NEWS CAFE
-[JM6_1]
-Raggiungi la banca sulla strada principale.
+[CRD251A]
+THE POND
-[GA_6B] { re3 change }
-Parcheggiala, innesca la bomba schiacciando il ~h~tasto ~k~~VEHICLE_FIREWEAPON~~w~ e BATTITELA!
+[CRD252A]
+PIVO
-[GA_7B] { re3 change }
-Innescala col ~h~tasto ~k~~VEHICLE_FIREWEAPON~~w~. La bomba esploderà quando si tenterà di avviare il motore.
+[CRED253]
+BUDGET VIDEO RENTALS
-[BAT1]
-~g~Prendi la mazza!
+[CRED254]
+LORNA'S SCOOTER
-[EBAL_O]
-Se andrà tutto liscio, forse potrei darti altro lavoro. Adesso fuori di qui!
+[CRED255]
+GARETH MURFIN
-[HELP9_B]
-Premere il ~h~tasto ~k~~PED_FIREWEAPON~~w~ per ~h~sparare~w~ col fucile di precisione.
+[CRED256]
+GRAFICA ADDIZIONALE
-[HELP9_C]
-Premere il ~h~tasto ~k~~PED_FIREWEAPON~~w~ per ~h~sparare~w~ col fucile di precisione.
+[CRED257]
+TONY PORTER
-[JM6_8]
-~r~Hai perso tutti i rapinatori!
+[CRED258]
+CRAIG MOORE
-[COLT_IN]
-La pistola è adesso disponibile da AmmuNation!
+[CRED259]
+SINCRONIZZAZIONE LABIALE SEQUENZE
-[TAXI2]
-~r~Tempo scaduto!
+[CRED260]
+COSGROVE HALL FILMS
-[TAXI3]
-~r~Il passeggero è fuggito terrorizzato!
+[CRED261]
+PRODUTTORE - OWEN BALLHATCHET
-[TAXI7]
-~r~La tua auto è distrutta, falla riparare.
+[CRED262]
+ANIMATORE SENIOR- JON TURNER
-[TAXI4]
-Tariffa completa!
+[CRED263]
+ANIMATORI - RICHARD DRUMM
-[TAXI5]
-BONUS VELOCITÀ!
+[CRED264]
+DAVE BROWN
-[TAXI6]
-Missione taxi terminata
+[CRED265]
+MAIR THOMAS
-[FRANGO]
-~g~Salvatore vuole che tu aiuti prima Toni ad affrontare le Triadi!
+[CRED266]
+PRASHANT PATEL
-[PAGEB12]
-Tangente per la Polizia consegnata al nascondiglio
+[CRED267]
+CONSULENTE TECNOLOGICO AUDIO
-[PAGEB13]
-Salute consegnata al nascondiglio
+[CRED268]
+RIK EDE DI GAMESOUND LTD.
-[PAGEB14]
-Adrenalina consegnata al nascondiglio
+[CRED269]
+SUPPORTO INTEGRAZIONE DTS
-[KM1_4]
-~g~Ti serve un'auto della polizia per svolgere il lavoro!
+[CRED270]
+TED LAVERTY DI DTS
-[CAT1_B]
-Porta 500.000$ alla Villa a Cedar Grove.
+[CRED271]
+CHRIS GREER DI DTS
-[JM2_C]
-Ha un chiosco di spaghetti cinesi a China Town.
+[CRED272]
+JASON PAGE DI DTS
-[RM6_1]
-Eccoti la chiave di un deposito.
+[CRED273]
+RICERCA E ANALISI
-[RM6_2]
-Troverai del denaro e alcune 'dotazioni' da utilizzare nei momenti difficili.
+[CRED274]
+VROCK
-[RM6_3]
-Ci vediamo.
+[CRED275]
+DJ: LAZLOW COME SE STESSO
-[FE_INIP]
-Inizializzazione e caricamento menu pausa... Un momento.
+[CRED276]
+VOCE IMAGING - JOE KELLY
-[FESZ_CA]
-Annulla
+[CRED277]
+PRODUZIONE IMAGING - JONATHAN HANST
-[FESZ_QU]
-Esci
+[CRED278]
+WAVE 103
-[FESZ_L1]
-Partita salvata con successo!
+[CRED279]
+DJ: ADAM FIRST - JAMIE CANFIELD
-[FESZ_L2]
-Il nome del file salvato è:
+[CRED280]
+VOCE IMAGING - JEN SWEENEY
-[FESZ_OK]
-OK
+[CRED281]
+PRODUZIONE IMAGING - JONATHAN HANST
-[FES_LGA]
-Carica partita
+[CRED282]
+FEVER 105
-[FES_NGA]
-Nuova partita
+[CRED283]
+DJ: OLIVER 'LADYKILLER' BISCUIT - JULIUS DYSON
-[FES_CAN]
-Annulla
+[CRED284]
+VOCE IMAGING MASCHILE - ED MCMANN
-[FESZ_QL]
-Tutti i progressi della partita attuale non ancora salvati andranno perduti. Vuoi procedere con il caricamento?
+[CRED285]
+VOCE IMAGING FEMMINILE - SHAWNEE SMITH
-[FESZ_QD]
-Vuoi eliminare questa partita salvata?
+[CRED286]
+PRODUZIONE IMAGING - LISTEN KITCHEN
-[FESZ_QO]
-Vuoi procedere con la sovrascrittura di questa partita salvata?
+[CRED287]
+EMOTION 98.3
-[FESZ_QR]
-Sei sicuro di voler iniziare una nuova partita? Tutti i progressi fatti fino all'ultimo salvataggio andranno perduti. Vuoi procedere?
+[CRED288]
+DJ: FERNANDO - FRANK CHAVEZ
-[FESZ_QS]
-VUOI PROCEDERE CON IL SALVATAGGIO?
+[CRED289]
+VOCE IMAGING - JEN SWEENEY
-[SLONFP]
-Ingresso 1. File protetto.
+[CRED290]
+PRODUZIONE IMAGING - JONATHAN HANST
-[T4X4_1]
-'CAMPO DEL PATRIOTA'
+[CRED291]
+RADIO ESPANTOSO
-[T4X4_2]
-'UN GIRO NEL PARCO'
+[CRED292]
+DJ: PEPE - TONY CHILRODES
-[T4X4_3]
-'AFFERRATO'
+[CRED293]
+WILDSTYLE
-[MM_1]
-'MASSACRO NEL PALAZZO'
+[CRED294]
+DJ: MISTER MAGIC COME SE STESSO
-[T4X4_1A]
-~g~Hai ~y~5 minuti~g~ per attraversare ~y~15~g~ punti di controllo. ~g~Puoi attraversarli in ~y~QUALSIASI ORDINE~g~.
+[CRED295]
+VOCE IMAGING - FRANK SILVESTRO
-[T4X4_1B]
-~1~ su 15!
+[CRED296]
+PRODUZIONE IMAGING - LAZLOW
-[T4X4_1C]
-~y~ATTRAVERSA~g~ il primo punto di controllo per attivare il timer. ~g~Ogni punto di controllo ti fornirà ~y~20 SECONDI~g~ extra.
+[CRED297]
+KCHAT
-[T4X4_2A]
-~g~Hai ~y~2 minuti~g~ per attraversare ~y~12~g~ punti di controllo!!! ~g~Puoi attraversarli in ~y~QUALSIASI ORDINE~g~.
+[CRED298]
+SCRITTA DA DAN HOUSER E LAZLOW
-[T4X4_2B]
-~1~ su 12!
+[CRED299]
+PRODOTTA E MIXATA DA LAZLOW
-[T4X4_2C]
-~y~ATTRAVERSA~g~ il primo punto di controllo per attivare il timer. ~g~Ogni punto di controllo ti fornirà ~y~10 SECONDI~g~ extra.
+[CRED300]
+DJ AMY SHECKENHAUSEN - LEYNA WEBER
-[T4X4_3A]
-~g~Hai ~y~5 minuti~g~ per attraversare ~y~20~g~ punti di controllo!!! ~g~Puoi attraversarli in ~y~QUALSIASI ORDINE~g~.
+[CRED301]
+JEZ TORRENT - KEVIN MCKIDD
-[T4X4_3B]
-~y~ATTRAVERSA~g~ il primo punto di controllo per attivare il timer. ~g~Ogni punto di controllo ti fornirà ~y~10 SECONDI~g~ extra.
+[CRED302]
+MANDY - COLLEEN CORBETT
-[T4X4_3C]
-~1~ su 20!
+[CRED303]
+MICHELLE CARAPADIS - MARY BIRDSONG
-[T4X4_F]
-~r~Sei scappato! Troppo difficile per te?
+[CRED304]
+MR.ZOO - CARL DOWLING
-[MM_1_A]
-~g~Hai ~y~2 minuti~g~ per attraversare ~y~20 punti di controllo~g~ nel palazzo! ~g~Puoi attraversarli in ~y~QUALSIASI ORDINE~g~.
+[CRED305]
+GETHSEMANEE - LYNN LIPTON
-[MM_1_B]
-~1~ su 20!
+[CRED306]
+CLAUDE MAGINOT - JOHN MAUCERI
-[MM_1_C]
-~g~Sono 20 secondi più ~y~5 secondi~g~ per ogni punto di controllo. ~g~Il timer partirà ~y~IMMEDIATAMENTE~g~.
+[CRED307]
+BJ SMITH - LAWRENCE TAYLOR
-[FM2_14]
-~r~Ti sei avvicinato troppo e hai spaventato Ricciolino!
+[CRED308]
+THOR - FRANK FAVA
-[FM2_15]
-~g~Non ti avvicinare troppo o Ricciolino si insospettirà!
+[CRED309]
+VOCI PUBBLICITÀ
-[UPSIDE]
-~r~Hai cappottato la macchina!
+[CRED310]
+COUZIN ED, JOSH CLARK, JASON BUHRMESTER, JUAN ALLER, WAYNE OLIVER, SUSAN LEWIS, GILLIAN TELLING, TOM MURRAY, MIKE FERRANTE SR., EMMANUEL GOLDSTEIN, DAN HOUSER, NICK MANDELOS, GERRY COSGROVE, MIKE PALERMO, PORKCHOP, KEITH BROADAS
-[FM2_16]
-PAURIMETRO:
+[CRED311]
+LEWIS, GILLIAN TELLING, TOM MURRAY, MIKE FERRANTE SR., EMMANUEL GOLDSTEIN,
-[LM3_11]
-~g~Misty non sale su un autobus, prendi un altro veicolo!
+[CRED312]
+DAN HOUSER, NICK MANDELOS, GERRY COSGROVE, MIKE PALERMO, PORKCHOP,
-[LANDSTK]
-Landstalker
+[CRED313]
+KEITH BROADAS
-[IDAHO]
-Idaho
+[CRED314]
+VCPR
-[STINGER]
-Stinger
+[CRED315]
+SCRITTO DA DAN HOUSER E LAZLOW
-[LINERUN]
-Linerunner
+[CRED316]
+PRODOTTO DA LAZLOW
-[PEREN]
-Perennial
+[CRED317]
+MAURICE CHAVEZ - PHILLIP ANTHONY RODRIGUEZ
-[SENTINL]
-Sentinel
+[CRED318]
+JONATHAN FREELOADER - PATRICK OLSEN
-[PATRIOT]
-Patriot
+[CRED319]
+MICHELLE MONTANIUS - KELLY GUEST
-[FIRETRK]
-Camion dei pompieri
+[CRED320]
+DEP. ALEX SHRUB - CHRIS LUCAS
-[TRASHM]
-Trashmaster
+[CRED321]
+CALLUM CRAYSHAW - SEAN MODICA
-[STRETCH]
-Stretch
+[CRED322]
+JOHN F. HICKORY - LJ GANSEN
-[MANANA]
-Manana
+[CRED323]
+PASTOR RICHARDS - DAVID GREEN
-[INFERNS]
-Infernus
+[CRED324]
+JAN BROWN - MAUREEN SILLIMAN
-[BLISTA]
-Blista
+[CRED325]
+BARRY STARK - RENAUD SEBBANE
-[PONY]
-Pony
+[CRED326]
+JENNY LOUISE CRAB - MARY BIRDSONG
-[MULE]
-Mulo
+[CRED327]
+KONSTANTINOS SMITH - KONSTANTINOS.COM
-[CHEETAH]
-Cheetah
+[CRED328]
+JEREMY ROBARD - PETER SILVESTRO
-[AMBULAN]
-Ambulanza
+[CRED329]
+PUBBLICITÀ RADIO
-[FBICAR]
-F.B.I.
+[CRED330]
+SCRITTE DA DAN HOUSER E LAZLOW
-[MOONBM]
-Moonbeam
+[CRED331]
+PRODOTTE DA LAZLOW
-[ESPERAN]
-Esperanto
+[CRED332]
+JINGLE AGGIUNTIVI PRODOTTI DA CRAIG CONNER
-[TAXI]
-Taxi
+[CRED333]
+VOCI PUBBLICITÀ
-[KURUMA]
-Kuruma
+[CRED334]
+ADAM DAVIDSON, ALEX ANTHONY, ALICE SALTZMAN, AMY SALZMAN, KATE DUKICH,
-[BOBCAT]
-Bobcat
+[CRED335]
+ARAN RONICLE, BARB JONES, BEN KRECH, BRIAN THOMAS, BROCK YODER, CHRIS
-[WHOOPEE]
-Mr Whoopee
+[CRED336]
+FERRANTE, CRAIG CONNER, DAVE RYAN, DAVID GREEN, DORIS WOO, DOUGLAS
-[BFINJC]
-BF Injection
+[CRED337]
+HARRISON, ED MCMANN, FRANK CHAVEZ, FRANK FAVA, GENE HILGREEN, GREG
-[POLICAR]
-Polizia
+[CRED338]
+SCHWEIZER, HUNTER PLATIN, JAMES FERRANTE, JEFF BERLIN, JEFF ROSA, JOE KELLY,
-[ENFORCR]
-Cellulare
+[CRED339]
+JOHN MAUCERI, JOSH CLARK, JULIE WEMYSS, KEVIN STRALEY, KIM GURNEY, LANCE
-[SECURI]
-Securicar
+[CRED340]
+WILLIAMS, LAURA PATERSON, LAZLOW, LISA ORTIZ, LORNA JORDAN, LUCIEN JONES,
-[BANSHEE]
-Banshee
+[CRED341]
+MAUREEN SILLIMAN, MIKE FERRANTE JR., PETE GUSTIN, PETER SILVESTRO, RAFF
-[PREDATR]
-Predator
+[CRED342]
+CROLLA, RANDY JOHNSON, RICHARD KRUGER, RON REEVE, SHELLEY MILLER, SKY, TJ ALLARD
-[BUS]
-Bus
+[CRD344A]
+AUDIO REGISTRATO PRESSO DIGITAL ARTS STUDIOS,
-[RHINO]
-Rhino
+[CRED344]
+NYC, TRACK 9 STUDIOS, NYC,
-[BARRCKS]
-Caserma OL
+[CRED345]
+WEDDINGTON MULTIMEDIA, LOS ANGELES,
-[TRAIN]
-Treno
+[CRD345A]
+SYNC SOUND, NYC E RADIO LAZLOW, LONG ISLAND.
-[HELI]
-Elicottero
+[CRED346]
+UN RINGRAZIAMENTO A AXEL ERICSON E WON LEE DI DIGITAL ARTS, PAUL VASQUEZ DI TRACK 9 STUDIOS, JOHN BOWEN E JOHN HASSLER DI SYNC SOUND
-[DODO]
-Dodo
+[CRED347]
+MARK LLOYD
-[COACH]
-Coach
+[CRED348]
+TIM BATES
-[CABBIE]
-Cabbie
+[CRED349]
+KIT BROWN
-[STALION]
-Stallion
+[CRED350]
+ANDY MASON
-[RUMPO]
-Rumpo
+[CRED351]
+PHIL DEANE
-[RCBANDT]
-Bandito RC
+[CRED352]
+PHIL ALEXANDER
-[BELLYUP]
-Triad
+[CRED353]
+MATT HEWITT
-[MRWONGS]
-Mr Wongs
+[CRED354]
+DENBY GRACE
-[MAFIACR]
-Mafia
+[CRED355]
+ANTOINE CABROL
-[YARDICR]
-Yardie
+[CRED356]
+JONOTHAN STONES
-[YAKUZCR]
-Yakuza
+[CRED357]
+MIKE BLACKBURN
-[DIABLCR]
-Diablo
+[CRED358]
+TIM MCGAFF
-[COLOMCR]
-Cartel
+[CINCAM]
+Camera mobile
-[HOODSCR]
-Hoods
+[RC4]
+'LA FURIA DI RUMPO'
-[AEROPL]
-Aeroplano
+[LEGAL]
+~g~Elimina la minaccia criminale!
-[SPEEDER]
-Speeder
+[GA_2]
+Motore nuovo e carrozzeria riverniciata. Gli sbirri non ti riconosceranno!
-[REEFER]
-Reefer
+[HELP15]
+Quando sei a piedi, premi il ~h~~k~~PED_LOOKBEHIND~~w~ per ~h~guardare indietro~w~. Usa la ~h~levetta analogica destra~w~ per ~h~guardarti attorno~w~.
-[PANLANT]
-Panlantic
+[FEC_LB4]
+Guarda indietro (tasto R3)
-[FLATBED]
-Flatbed
+[PERPIC]
+Pacchetti speciali recuperati
-[YANKEE]
-Yankee
+[CO_ONE]
+Pacchetto speciale ~1~ su ~1~
-[BORGNIN]
-Borgnine
+[GA_21]
+Non puoi parcheggiare altri veicoli in questo garage.
-[TOYZ]
-TOYZ
+[CHEAT1]
+Trucco attivato
-[FEST_DF]
-Distanza percorsa a piedi (miglia)
+[CHEAT2]
+Trucco armi
-[FEST_DC]
-Distanza percorsa in auto (miglia)
+[CHEAT3]
+Trucco salute
-[FESTDFM]
-Distanza percorsa a piedi (m)
+[CHEAT4]
+Trucco armatura
-[FESTDCM]
-Distanza percorsa in auto (m)
+[CHEAT5]
+Trucco livello di sospetto
-[FEST_R1]
-Campo del Patriota (secondi)
+[CHEAT6]
+Trucco soldi
-[FEST_R2]
-un Giro nel Parco (secondi)
+[CHEAT7]
+Trucco tempo atmosferico
-[FEST_R3]
-Afferrato! (secondi)
+[USJ_ALL]
+TUTTE LE ACROBAZIE UNICHE COMPLETATE
-[FEST_RM]
-Massacro Multi-livello (secondi)
+[JAN]
+Gen
-[FEST_LS]
-Persone salvate in ambulanza
+[FEB]
+Feb
-[FEST_CC]
-Missione Vigilante - Criminali uccisi
+[MAR]
+Mar
-[FEST_FE]
-Totale incendi spenti
+[APR]
+Apr
-[FEST_LF]
-Volo più lungo nel Dodo
+[MAY]
+Mag
-[FEST_BD]
-Disinnesco bomba - Miglior tempo
+[JUN]
+Giu
-[FEST_RP]
-Violenze eseguite
+[JUL]
+Lug
-[FEST_MP]
-Missioni eseguite
+[AUG]
+Ago
-[FEST_BB]
-Bling-bling Scramble:
+[SEP]
+Set
-[FEST_H0]
-Maggior numero di checkpoints
+[OCT]
+Ott
-[FEST_GC]
-Auto delle gang distrutte:
+[NOV]
+Nov
-[FEST_H1]
-Distruzione Diablo
+[DEC]
+Dic
-[FEST_H2]
-Massacro Mafioso
+[DEFDT]
+--:---:---- --:--:--
-[FEST_H3]
-Calamità al Casinò
+[BONUS]
+~g~BONUS ~1~$
-[FEST_H4]
-Demolizioni Rumpo
+[HORN1]
+Premi il ~h~~k~~VEHICLE_HORN~~w~ per attivare il ~h~clacson~w~.
-[USJI1]
-TESTO NON PIÙ RICHIESTO
+[HORN2]
+Premi il ~h~~k~~VEHICLE_HORN~~w~ per attivare il ~h~clacson~w~.
-[USJI2]
-TESTO NON PIÙ RICHIESTO
+[HORN3]
+Premi il ~h~~k~~VEHICLE_HORN~~w~ per attivare il ~h~clacson~w~.
-[USJI3]
-TESTO NON PIÙ RICHIESTO
+[FEC_EXV]
+Esci dal veicolo
-[USJ]
-BONUS PER ACROBAZIA UNICA!
+[TAXI_M]
+'TAXI DRIVER'
-[SPRAY]
-Porta l'auto dal carrozziere per perdere il ~h~livello di sospetto~w~, ~h~riparare~w~ e ~h~riverniciare~w~ il veicolo. Costo - ~h~1000$~w~.
+[COP_M]
+'VIGILANTE'
-[HM1_1]
-~g~Fredda 20 Purple Nine in 2 minuti e 30 secondi.
+[FIRE_M]
+'POMPIERE'
-[KM1_8A] { re3 change }
-Premi il ~h~tasto ~k~~VEHICLE_FIREWEAPON~~w~ per ~h~attivare la bomba~w~: ricorda di toglierti di mezzo!
+[AMBUL_M]
+'INFERMIERE'
-[KM1_8D] { re3 change }
-Premi il ~h~tasto ~k~~VEHICLE_FIREWEAPON~~w~ per ~h~attivare la bomba~w~: e ricorda di toglierti di mezzo!
+[HJ_IS]
+BONUS ACROBAZIA FOLLE: ~1~$
-[KM1_12]
-~g~Portalo nel dojo, ma prima sbarazzati degli sbirri!
+[HJ_PIS]
+BONUS ACROBAZIA FOLLE PERFETTA: ~1~$
-[RATNG1]
-Borsaiolo
+[HJ_DIS]
+BONUS DOPPIA ACROBAZIA FOLLE: ~1~$
-[RATNG2]
-Prepotente
+[HJ_PDIS]
+BONUS DOPPIA ACROBAZIA FOLLE PERFETTA: ~1~$
-[RATNG3]
-Teppista
+[HJ_TIS]
+BONUS TRIPLA ACROBAZIA FOLLE: ~1~$
-[RATNG4]
-Attaccabrighe
+[HJ_PTIS]
+BONUS TRIPLA ACROBAZIA FOLLE PERFETTA: ~1~$
-[RATNG5]
-Gorilla
+[HJ_QIS]
+BONUS QUADRUPLA ACROBAZIA FOLLE: ~1~$
-[RATNG6]
-Autista
+[HJ_PQIS]
+BONUS QUADRUPLA ACROBAZIA FOLLE PERFETTA: ~1~$
-[RATNG7]
-Aiutante
+[FESZ_LS]
+Caricamento completato.
-[RATNG8]
-Riparatore
+[HELI_1A]
+Prova le tue abilità con lo Sparrow: scopri quanto velocemente riesci a completare il percorso.
-[RATNG9]
-Socio
+[HELI_1B]
+Percorso completato!
-[RATNG10]
-Uomo delle pulizie
+[HELIODD]
+Strani incarichi con l'elicottero
-[RATNG11]
-Assassino
+[INT2_M]
+Hanno una fattoria in Panama.
-[RATNG12]
-Braccio destro
+[INT2_N]
+OK, va bene, ascoltate:
-[RATNG13]
-Boia
+[INT2_O]
+quando arriviamo volete che resti in macchina
-[RATNG14]
-Capo
+[INT2_P]
+o preferite che venga con voi altri?
-[RATNG15]
-Boss
+[INT2_Q]
+No, resta in macchina.
-[1010]
-~r~Il tuo veicolo si è ribaltato
+[INT2_R]
+Lo sapete, ci ho pensato su.
-[1011]
-~r~Il tuo veicolo si è ribaltato
+[INT2_S]
+Penso proprio che resterò in macchina.
-[1012]
-~r~Il tuo veicolo si è ribaltato
+[INT4_A]
+Fottuti! Siamo fottuti!
-[1013]
-~r~Il tuo veicolo si è ribaltato
+[INT4_B]
+È sempre la stessa storia,
-[1014]
-~r~Il tuo veicolo si è ribaltato
+[INT4_C]
+metto fuori la testa per un maledetto secondo,
-[JM4_10]
-OK, ragazzo. Accompagnami prima alla lavanderia di Chinatown, devo occuparmi di alcuni affari.
+[INT4_D]
+e il fato mi tira palate di merda in faccia!
-[JM4_11]
-La donna della lavanderia non mi ha pagato i soldi del pizzo.
+[INT4_E]
+Bene, vaffanculo!
-[JM4_12]
-E bada all'auto: Joey ha appena riparato questo rottame.
+[INT4_F]
+Smettila di fare casino e di lamentarti. Siamo vivi, non è vero?
-[JM4_13]
-Quindi, niente colpi di testa, OK?
+[INT4_G]
+Fammi scendere qua.
-[KM4_11]
-~g~Riporta i soldi al Casinò!
+[INT4_H]
+Fai scomparire la macchina e fatti una bella dormita.
-[FEF_BR2]
-Ritrovalo leggendo i sommari di missione che hai già ricevuto.
+[INT4_I]
+Passerò domani a trovarti in ufficio e troveremo un modo per risolvere questo casino.
-[TRAIN_1]
-Stazione Kurowski
+[INT4_J]
+OK, mi sembra un'ottima idea, andrò a dormire.
-[TRAIN_2]
-Stazione Rothwell
+[INT4_K]
+Che cosa intendi fare?
-[TRAIN_3]
-Stazione Baillie
+[INT4_L]
+Tornare nella mia stanza,
-[SUBWAY1]
-Stazione Portland
+[INT4_M]
+schiarirmi le idee e risolvere questo casino.
-[SUBWAY2]
-Stazione Rockford
+[INT4_N]
+OK.
-[SUBWAY3]
-Stazione Sud Staunton
+[LAW]
+MISSIONI DELL'AVVOCATO
-[SUBWAY4]
-Capolinea Shoreside
+[LAW1_1]
+~g~Vai a prendere degli abiti nuovi dal negozio di vestiti Rafael's.
-[MEA4_2]
-~r~Marty Chonks è morto!
+[LAW4_6]
+Brucia l'amministrazione!
-[SPRAY1]
-Porta l'auto dal carrozziere per perdere il ~h~livello di sospetto~w~, ~h~riparare~w~ e ~h~rivernicirea~w~ il veicolo. Costo - ~h~1000$~w~. Per questa volta è gratis.
+[LAW4_7]
+Uccidi i responsabili!
-[JM4_A]
-Sì, lo so Toni, l'ho sistemata per bene. Il motore fa le fusa, non so se mi spiego.
+[LAW4_8]
+Combattere, combattere, combattere, combattere,.
-[JM4_5]
-Ripassa più tardi e darò loro qualcosa da lavare... i panni macchiati del loro sangue!
+[LAW4_9]
+Più ferie, meno lavoro!
-[AMMU_A]
-Luigi dice che ti serve 'un ferro del mestiere'...
+[LAW4_11]
+Combattere, combattere, combattere, combattere,.
-[AMMU_B]
-Joey mi ha detto di equipaggiarti...
+[LAW4_12]
+Viva la rivoluzione.
-[AMMU_C]
-Vai sul retro del negozio. Ti ho lasciato una calibro nove in cortile.
+[GENERAL]
+MISSIONI DEL COLONNELLO
-[AMMU_D]
-Ho tutto quello che ti serve per la tua auto-difesa.
+[GEN3_4]
+Tommy Vercetti. Andiamo...
-[AMMU_E]
-Vuoi anche una licenza?
+[GEN3_13]
+Che cosa diavolo ti prende? Vai sul tetto dall'altra parte del cortile prima che arrivino!
-[AMMU_F]
-Non mi serve che mi mostri i documenti, hai una faccia fidata.
+[GEN3_17]
+Meeerda! Stai cercando di ammazzarmi?
-[DETON]
-DETONAZIONE:
+[GEN3_21]
+~g~Ha preso i soldi di Diaz! Inseguilo e riprendili!
-[DRIVE_A] { re3 change }
-Seleziona un Uzi quando entri in un veicolo, poi guarda a destra o a sinistra e premi il ~h~tasto ~k~~VEHICLE_FIREWEAPON~~w~ per sparare.
+[GEN3_24]
+~r~Diaz è morto! Non sei riuscito a proteggerlo!
-[DRIVE_B] { re3 change }
-Seleziona un Uzi quando entri in un veicolo, poi guarda a destra o a sinistra e premi il ~h~tasto ~k~~VEHICLE_FIREWEAPON~~w~ per sparare.
+[GEN3_26]
+~r~Hai ucciso Diaz!
-[RECORD]
-~g~NUOVO RECORD!!!
+[GEN3_27]
+~r~Hai ucciso una guardia di Diaz!
-[NRECORD]
-~r~NESSUN NUOVO RECORD!
+[GEN3_31]
+~g~Vai all'appuntamento e proteggi Diaz.
-[RCHELP] { re3 change }
-Premi il tasto ~k~~VEHICLE_FIREWEAPON~ o dirigi l'auto radiocomandata contro i pneumatici di un veicolo per provocarne la detonazione.
+[GEN3_32]
+~g~Raggiungi il tetto nell'edificio di fronte a Lance e appostati.
-[RCHELPA] { re3 change }
-Premi il tasto ~k~~VEHICLE_FIREWEAPON~ o dirigi l'auto radiocomandata contro i pneumatici di un veicolo per provocarne la detonazione.
+[COKE]
+MISSIONI DEL BARONE DELLA COCA
-[RC_1]
-Hai 2 minuti per far esplodere quante più auto dei Diablo possibile!
+[COK1_3]
+Spero tu cada e ti rompa l'osso del collo!
-[RC_2]
-Hai 2 minuti per far esplodere quante più auto Mafiose possibile!
+[COK1_6]
+Sono stanco di tutto questo.
-[RC_3]
-Hai 2 minuti per far esplodere quante più auto della Yakuza possibile!
+[COK2_7]
+Vedi quei segnali, ragazzo? Cerca di colpire le luci!
-[RC_4]
-Hai 2 minuti per far esplodere quante più auto degli Yardie possibile!
+[COK2_10]
+Di certo sei più bravo a sparare che a parlare.
-[RC_5]
-Hai 2 minuti per far esplodere quante più auto degli Hood possibile!
+[COK2_11]
+Grazie. Anche tu hai una bella parlantina.
-[RC_6]
-Hai 2 minuti per far esplodere quante più auto del Cartello possibile!
+[COK2_12]
+Lo so, Tommy.
-[RAMPAGE]
-VIOLENZA!!
+[COK2_18]
+Ti diverti con Kenny Loggins.
-[RAMP_P]
-VIOLENZA COMPIUTA!
+[COK2_19]
+Cielo, adoro questo album!
-[RAMP_F]
-VIOLENZA FALLITA
+[COK2_26]
+~r~Hai ucciso Lance!
-[PAGE_00]
-.
+[COK3_1]
+Non sparare, amico!
-[PAGE_01]
-Uccidi ~1~ Diablo in 120 secondi!
+[COK3_2]
+Che cosa sta succedendo?
-[PAGE_02]
-Distruggi ~1~ veicoli in 120 secondi!
+[COK3_3]
+Sta prendendo la barca. Farabutto!
-[PAGE_03]
-Uccidi ~1~ Mafiosi in 120 secondi!
+[COK3_4]
+Aiuto! Un idiota sta rubando la barca!
-[PAGE_04]
-Uccidi ~1~ elementi della Triade in 120 secondi!
+[COK4_W]
+Uugghh! Questo è l'ultimo.
-[PAGE_05]
-Uccidi ~1~ elementi della Triade in 120 secondi!
+[COK4_X]
+Vado ad accendere...
-[PAGE_06]
-Distruggi ~1~ veicoli in 120 secondi!
+[COK4_Y]
+A quanto sembra abbiamo dei nuovi amici.
-[PAGE_07]
-Fai saltare la testa a ~1~ Yardie in 120 secondi!
+[COK4_2]
+Sì.
-[PAGE_08]
-Brucia ~1~ elementi della Yakuza in 120 secondi!
+[COK4_6]
+Sai dove stiamo andando?
-[PAGE_09]
-Distruggi ~1~ veicoli in 120 secondi!
+[COK4_7]
+Ci siamo persi?
-[PAGE_10]
-Distruggi ~1~ veicoli in 120 secondi!
+[COK4_8]
+Abbiamo un po' di competizione!
-[PAGE_11]
-Annienta ~1~ Yardie in 120 secondi!
+[COK4_9]
+Falli fuori!
-[PAGE_12]
-Carbonizza ~1~ elementi della Yakuza in 120 secondi!
+[COK4_9A]
+È giunta l'ora di un po' di Lance Vance Dance!
-[PAGE_13]
-Fai esplodere ~1~ Yardie in 120 secondi!
+[COK4_10]
+Sono pronti per il macero! E per sfamare i pesci.
-[PAGE_14]
-Fai fuori ~1~ ColombianI in 120 secondi!
+[COK4_11]
+Ce l'abbiamo fatta! Le altre imbarcazioni non sono della nostra classe.
-[PAGE_15]
-Polverizza ~1~ Hood in 120 secondi!
+[COK4_17]
+Stanno iniziando a pregare!
-[PAGE_16]
-Distruggi ~1~ veicoli in 120 secondi!
+[COK4_18]
+I miei piedi sono bagnati! STIAMO IMBARCANDO ACQUA!
-[PAGE_17]
-Investi in macchina ~1~ Colombiani in 120 secondi!
+[COK4_21]
+Ponte in arrivo!
-[PAGE_18]
-Distruggi guidando ~1~ veicoli in 120 secondi!
+[COK4_22]
+Lanciati, sta per esplodere!
-[PAGE_19]
-Stacca la testa a ~1~ Colombiani in 120 secondi!
+[COK4_23]
+Bel colpo!
-[PAGE_20]
-Decapita ~1~ Hood in 120 secondi!
+[COK4_29]
+~r~Hai ucciso Lance!
-[JOEY_1]
-TESTO NON PIÙ RICHIESTO
+[ASS1_6]
+Vai Tommy, andrà tutto bene!
-[JM1_A]
-Ehi, sono stufa, quand'è che si passa ai fatti?
+[ASS1_7]
+Beccatevi questo, maledetti assassini!
-[JM1_B]
-Tra un minuto, cocca, ho una cosetta da sbrigare.
+[ASS1_8]
+Sono bloccato!
-[JM1_C]
-Ho un lavoretto per te, amico.
+[ASS1_9]
+Ti copro io Tommy!
-[JM1_D]
-I fratelli Forelli mi devono soldi da troppo tempo
+[ASS1_10]
+Ehi, questo sì che è un bel confine alberato.
-[JM1_E]
-e occorre insegnargli un po' di rispetto.
+[ASS1_11]
+Ehi Tommy, posso avere la stanza con la vista sulla baia?
-[JM1_F]
-'Labbra' Forelli si sta ingozzando come un porco al St Mark's Bistro,
+[ASS1_12]
+Che bel soffitto alto che c'è qui...
-[JM1_G]
-quindi rubagli l'auto e portala nell'armeria di 8-Ball ad Harwood.
+[ASS1_3]
+Lance! Ho bisogno di copertura!
-[JM1_H]
-Conosci 8-Ball, vero?
+[ASS1_5]
+Lance!
-[JM1_I]
-Dopo che sarà stata installata una bomba, parcheggia l'auto dove l'hai trovata.
+[ASS1_15]
+~g~Distruggi la dimora e uccidi Diaz!
-[JM1_J]
-Poi rilassati e goditi lo spettacolo.
+[ASS1_17]
+~g~Sono disponibili più strade all'interno della villa.
-[JM1_K]
-Ma fai in fretta, non starà a pranzo una vita.
+[TAXWAR]
+MISSIONI GUERRA DEI TAXI
-[CAT2_A1]
-Forza, brutta deficiente!
+[NOTAXI]
+~g~Hai bisogno di un taxi Kaufman per attivare questa missione.
-[CAT2_A]
-La domanda è: sei venuto a salvare Maria o a riportarmi indietro?
+[TAXW1_5]
+~g~Devi avere un taxi Kaufman!
-[CAT2_B]
-Beh, stammi a sentire,
+[TAX2_4]
+Forza, Tommy.
-[CAT2_B2]
-spararti sarà un piacere, ma uscire con te è stato solo lavoro.
+[TAX2_5]
+Riempilo di botte!
-[CAT2_C]
-Sei il mio peccinno amigo!
+[TAX2_6]
+Non ha neppure il permesso.
-[CAT2_D]
-Butta qui la grana.
+[TAX2_7]
+Maledetti servizi di limousine.
-[CAT2_E]
-Ti sei dato molto da fare!
+[TAXW3_1]
+~g~Vai a prendere Mercedes.
-[CAT2_E2]
-Ma non hai imparato che non devi fidarti di me.
+[RACE1]
+~g~3..2..1.. VIA VIA VIA!
-[CAT2_E3]
-Ammazzate quell'idiota.
+[RACE2]
+~g~3
-[CAT2_J]
-Fai decollare questo affare!
+[RACE3]
+~g~2
-[HM5_1]
-Ehi, Ice mi ha detto che saresti arrivato. Ecco le regole. Solo mazze. Niente pistole, niente auto.
+[RACE4]
+~g~1
-[HM5_5]
-È una battaglia per il rispetto, chiaro?.
+[RACE5]
+~g~VIA!
-[HELP14]
-Per raccogliere le armi, passaci sopra a piedi. Non puoi raccoglierle mentre sei in un veicolo.
+[FIRST]
+~b~PRIMO
-[CRUSH]
-Parcheggia nell'area contrassegnata ed esci dal veicolo. Il veicolo verrà rottamato.
+[SECOND]
+~b~SECONDO
-[DIAB2_B]
-Un gruppo di gentaglia mi ha minacciato di asportare il mio attributo di tutto rispetto se non gli sgancio dei soldi.
+[THIRD]
+~b~TERZO
-[DIAB2_C]
-Hanno minacciato l'uomo sbagliato, amigo.
+[FOURTH]
+~b~QUARTO
-[DIAB2_D]
-Hanno un debole per il gelato.
+[RACETM]
+~b~TEMPO DI GARA: ~1~:~1~
-[DIAB2_E]
-Prendi la bomba che ho nascosto ad Harwood,
+[RACETM2]
+~b~TEMPO DI GARA: ~1~:0~1~
-[DIAB2_F]
-dirotta il furgone dei gelati durante i suoi spostamenti
+[RACEFA]
+~r~Non sei riuscito a vincere la gara!
-[DIAB2_G]
-e attira quegli idioti verso il loro destino con il campanello.
+[TEX1_5]
+~r~È riuscito a fuggire!
-[DIAB2_H]
-Si nascondono in un magazzino ad Atlantic Quay.
+[SEG3_1]
+TEMPO:
-[DIAB3_A]
-Qualche insolente della Triade ha rubato la mia stupenda macchina ieri notte,
+[SEG3_2]
+~g~Raggiungi il van che contiene il Raider radiocomandato e le bombe a tempo.
-[DIAB3_B]
-l'ha distrutta e carbonizzata.
+[SEG3_3]
+~g~Devi utilizzare il RAIDER RADIOCOMANDATO per trasportare le 4 bombe nelle 4 aree bersaglio all'interno del cantiere.
-[DIAB3_C]
-Uno dei miei più cari escrementi asinini si trovava nel bagagliaio
+[SERG3_5]
+~g~Puoi trasportare solo una bomba alla volta e non puoi raccogliere dell'esplosivo correttamente posizionato.
-[DIAB3_D]
-veri oggetti da collezione, insostituibili amico mio.
+[SEG3_7]
+~g~Una volta posizionata la PRIMA bomba con successo su di un bersaglio, partirà il conto alla rovescia, dovrai piazzare tutti gli esplosivi entro il tempo limite.
-[DIAB3_E]
-Ho nascosto un'arma lancinante alla periferia di Chinatown.
+[SEG3_8]
+~g~Le 4 bombe devono essere tutte posizionate su ognuno dei bersagli per passare la missione e demolire l'edificio.
-[DIAB3_F]
-Prendila e insegna ai vandali della Triade a temere l'ira super-dotata di El Burro!
+[SEG3_9]
+~g~Bomba piazzata! Ancora 3.
-[DIAB3_1]
-UCCIDI 25 ELEMENTI DELLA TRIADE
+[SEG3_10]
+~g~Bomba piazzata! Ancora 2.
-[DIAB4_A]
-Un ladruncolo approfittatore ha rubato un furgone carico di copie delle mie ultime pubblicazioni!
+[SEG3_11]
+~g~Bomba piazzata! Ne manca una sola.
-[DIAB4_B]
-Ma quell'idiota fatto di SPANK ha lasciato lo sportello posteriore aperto,
+[SEG3_12]
+~g~Bomba NON piazzata! Recupera l'esplosivo!
-[DIAB4_C]
-per cui tutto quello splendido capolavoro patinato
+[SEG3_13]
+~g~Piazza la bomba nella zona bersaglio.
-[DIAB4_D]
-con intriganti foto pornografiche è stato sparso per tutta Liberty!
+[SEG3_14]
+~r~Tempo esaurito: hai fallito nel demolire l'edificio.
-[DIAB4_E]
-Prendi il furgone e segui la scia di copie di Un Asino si fa Dallas volume 1, 2 e 3
+[SEG3_15]
+~r~Il Raider radiocomandato è stato distrutto! Come farai adesso a trasportare le bombe?
-[DIAB4_F]
-raccogliendole lungo la strada.
+[AVERY]
+MISSIONI DI AVERY
-[DIAB4_G]
-Quando raggiungi quel ladruncolo imbottito di SPANK, fallo fuori!
+[ASM]
+MISSIONI DA SICARIO
-[DIAB4_H]
-Poi consegna il mio materiale asinino a Riviste XXX nel quartiere a luci rosse.
+[ASM_1]
+MISSIONE DA SICARIO 1
-[DIAB4_1]
-~g~Porta il furgone nel retro di Riviste XXX.
+[ASM1_1]
+~g~Mr. Teal, il tuo aiuto nello sradicare gli stranieri è stato inestimabile per il nostro lavoro. Ho un altro lavoro con un contatto più 'diretto'. I dettagli sono stati attaccati sotto al telefono.
-[HM1_E]
-Devi far vedere a queste depravate come si fa una vera sparatoria.
+[ASM1_2]
+~g~Raggiungi il telefono pubblico presso il Mall in Washington Beach.
-[HM1_H]
-Togli di torno questi Nine!
+[ASM1_3]
+~g~Carl Pearson, fattorino di una pizzeria. Non deve completare le sue consegne.
-[HM2_A]
-Questi Nine mi stanno causando problemi.
+[ASM1_4]
+~g~Uccidi il fattorino prima che possa completare le sue consegne.
-[HM2_B]
-Queste stronze hanno auto blindate e adesso stanno spacciando SPANK...
+[ASM_2]
+MISSIONE DA SICARIO 2
-[HM2_C]
-e lo smerciano senza paura ai miei fratelli.
+[ASM_3]
+MISSIONE DA SICARIO 3
-[HM2_D]
-C'è un'auto parcheggiata in strada.
+[ASM3_A]
+Marcus Hammond, Franco Carter, Dick Tanner, Nick Kong e Stuntman Driver fanno tutti parte di un'associazione europea che si sta preparando a commettere una rapina.
-[HM2_E]
-Dentro c'è della roba che metterà le sorelline fuori combattimento...
+[ASM3_B]
+Si trovano tutti nella loro posizione pronti all'azione. Voglio che vengano tutti eliminati prima che inizi il colpo. Ho disposto delle utili armi nei paraggi.
-[HM3_A]
-Qualche bastardo ha messo una bomba nella mia auto.
+[ASM3_1]
+~g~Recupera le armi che Mr. Black ha lasciato per te.
-[HM3_B]
-Se perdo l'auto, la mia reputazione nel giro sarà finita.
+[ASM3_2]
+~g~Non avvicinarti troppo, se no il bersaglio potrebbe vederti.
-[HM3_C]
-Prendi la mia macchina e portala al garage a St. Marks, chiaro?
+[ASM3_3]
+~g~Per un'eliminazione più rapida, colpisci da una locazione vicino alle loro postazioni ed evita di farti vedere.
-[HM3_D]
-Fagli disinnescare la bomba, lascia che se ne occupino loro.
+[ASM3_4]
+~g~Ti ha visto! Fallo fuori il prima possibile!
-[HM3_E]
-Il tempo corre e l'ordigno è tutto incasinato.
+[ASM3_5]
+~g~Marcus Hammond si trova presso dei cartelli pubblicitari in Washington.
-[HM3_F]
-Se becchi una buca potrebbe saltare tutto in aria.
+[ASM3_6]
+~g~Franco Carter si trova presso la DBP Security vicino a Ocean Drive.
-[HM3_G]
-Adesso muoviti!
+[ASM3_7]
+~g~Dick Tanner si trova presso la gioielleria in Vice Point.
-[HM4_A]
-Ehi, un aereo federale portavalute si è appena schiantato all'aeroporto Francis.
+[ASM3_8]
+~g~Nick Kong si trova presso Washington Beach.
-[HM4_B]
-C'è del platino sparso per tutta la pista.
+[ASM3_9]
+~g~Stuntman Driver si trova presso Washington Beach.
-[HM4_C]
-Prendi un'auto e raccogline quanto ne puoi!
+[ASM3_10]
+~r~Non sei riuscito a eliminarli tutti quanti.
-[HM4_F]
-Puoi scaricare il malloppo in uno dei miei garage.
+[ASM_4]
+MISSIONE DA SICARIO 4
-[HM4_G]
-Il platino è molto pesante e rallenterà un po' l'automobile.
+[ASM4_1]
+~g~Recupera il fucile che ti abbiamo lasciato tra le foglie presso il terminal dell'aeroporto.
-[HM4_H]
-Quindi fai diverse consegne nel garage.
+[ASM4_2]
+~g~Non mancare il bersaglio o allarmerai le sue guardie del corpo: ricorda di tenere una certa distanza per evitare di essere visto.
-[HM5_A]
-Quei Nine sono rimasti in una manciata di rognosi...
+[ASM4_3]
+~g~Osserva la donna sul balcone sopra ai banconi del check-in dentro il terminal. NON UCCIDERLA.
-[HM5_B]
-ma insistono ancora.
+[ASM4_4]
+~g~Elimina l'uomo a cui passa la valigetta ma solo DOPO CHE L'AVRÀ RACCOLTA. Poi recupera la valigetta e portala ad Ammu-Nation in Downtown.
-[HM5_C]
-Ci siamo accordati per uno scontro.
+[ASM4_5]
+~g~Recupera la valigetta!
-[HM5_D]
-Un gruppo dei loro contro due di noi, anzi...
+[ASM4_6]
+~g~Porta la valigetta ad Ammu-Nation in Downtown
-[HM5_E]
-due di te.
+[ASM4_7]
+~r~Hai ucciso la donna, idiota!
-[HM5_F]
-Ti accompagnerei, ma...
+[ASM4_8]
+~r~Il bersaglio ha sentito il colpo d'arma da fuoco! L'accordo è saltato!
-[HM5_G]
-non sarò in libertà vigilata per altri tre mesi.
+[ASM4_9]
+~r~Il bersaglio è salito a bordo del volo!
-[HM5_H]
-Tu mi capisci, vero?
+[ASM4_10]
+~g~Sembra tu non sia l'unico interessato alla valigetta! Portala in fretta ad Ammu-Nation!
-[HM5_I]
-Vai a trovare il mio fratellino,
+[ASM4_11]
+~r~Il bersaglio ti ha visto! L'accordo è saltato!
-[HM5_J]
-Ti accompagnerà sul luogo della rissa, amico.
+[ASM4_13]
+~g~Ti ha visto e sta scappando! Uccidilo e recupera la valigetta!
-[MEA1_B]
-Mi chiamo Chonks, Marty Chonks.
+[ASM4_14]
+~g~L'indicatore della distanza nella parte superiore destra dello schermo ti tiene informato sulla distanza dal bersaglio. Se si riempirà, verrai avvistato.
-[MEA1_C]
-Gestisco la fabbrica di cibo per cani Bitch'n'Dog qui vicino.
+[ASM_5]
+MISSIONE DA SICARIO 5
-[MEA1_D]
-Ho dei problemi finanziari, ma in fondo chi non ne ha?
+[KICK]
+KICKSTART
-[MEA1_E]
-Più tardi mi incontrerò col direttore della mia banca.
+[KICK1_3]
+~g~Numero di volte che hai appoggiato i piedi: ~1~
-[MEA1_F]
-È un imbroglione schifoso che continua a far crescere gli interessi di un prestito per arricchirsi.
+[KICK1_4]
+~g~Penalità: ~1~ secondi
-[MEA1_G]
-Usa la mia auto, vallo a prendere e portalo qui.
+[BANK]
+MISSIONI RAPINA
-[MEA1_H]
-Ho una sorpresina per quella maledetta sanguisuga!
+[BANK1]
+MISSIONE RAPINA 1
-[MEA2_A]
-Ho assunto dei ladri per entrare nel mio appartamento...
+[BANK2]
+MISSIONE RAPINA 2
-[MEA2_C]
-Quei ladruncoli bastardi minacciano di dire tutto all'assicurazione,
+[BJM2_3]
+PERCENTUALE DI CENTRI: ~1~%
-[MEA2_D]
-se non do loro una percentuale.
+[BJM2_15]
+PUNTEGGIO:
-[MEA2_E]
-Roba da non credere!
+[BJM2_18]
+PUNTEGGIO DA BATTERE:
-[MEA2_F]
-Ho parcheggiato un'auto dietro i cancelli della fabbrica.
+[BJM2_19]
+~g~Colpisci il maggior numero di bersagli entro il tempo limite!
-[MEA2_G]
-Usala e valli a prelevare nel loro territorio nel quartiere a luci rosse.
+[BJM2_21]
+~g~Colpisci il maggior numero di bersagli finché hai ancora colpi.
-[MEA2_H]
-Poi portali qui in fabbrica così che comprendano il mio punto di vista.
+[BANK3]
+MISSIONE RAPINA 3
-[MEA3_A]
-L'azienda farà bancarotta se non riesco a procurarmi in fretta parecchi contanti.
+[BJM3_1]
+~g~Trova una macchina da corsa e posizionati sulla griglia di partenza.
-[MEA3_B]
-Mia moglie ha un'assicurazione e l'unica cosa che sa fare è sperperare i miei soldi.
+[BNK4_2A]
+I ragazzi dell'officina hanno fatto un ottimo lavoro su questa piccola.
-[MEA3_C]
-Ho lasciato un'auto al solito posto.
+[BNK4_3G]
+Ommerda, abbiamo la polizia alle calcagna!
-[MEA3_D]
-Vai a prendere mia moglie al salone di bellezza Classic Nails e accompagnala alla fabbrica.
+[BNK4_3H]
+...e non siamo ancora neanche arrivati.
-[MEA4_A]
-Maledizione, sono nei guai!
+[BNK4_3K]
+Dobbiamo seminare prima la polizia...
-[MEA4_B]
-Sembra che mia moglie avesse una storia con un tipo a cui devo dei soldi.
+[BNK4_3L]
+Cristo Tommy, stai cercando di farci fuori?
-[MEA4_C]
-È molto arrabiato e vuole vendetta!
+[BNK4_3N]
+Tutto ciò che amo finisce a pezzi!
-[MEA4_E]
-Lui si aspetta che cercherò di patteggiare...
+[BNK422A]
+Cam, quanto tempo?
-[MEA4_F]
-ma io credo che...
+[BK4_23A]
+Mi bastano 3 minuti!
-[MEA4_G]
-i cani di Liberty assaggeranno dei bocconcini extra questo mese!
+[BNK4_26]
+Maledizione! Ecco che arrivano!
-[WELCOME]
-BENVENUTI A
+[BNK4_32]
+Usa l'esplosivo per aprire le cassette di sicurezza!
-[HM1_2]
-~g~Prendi un veicolo e ricorda: contano solo le uccisioni fatte con l'Uzi mentre guidi!
+[BNK4_43]
+Vi copro io il culo, PARTI!
-[HELP8_B]
-Premi il ~h~tasto ~k~~PED_SNIPER_ZOOM_IN~ ~w~per ~h~zoomare ~w~col fucile e il~h~ tasto ~k~~PED_SNIPER_ZOOM_OUT~~w~ per ~h~allargare il campo~w~.
+[BNK4_51]
+A me sembri a posto.
-[LRQC_1]
-Asuka e io dobbiamo parlare, OK?
+[KENT]
+MISSIONI DI KENT PAUL
-[LRQC_2]
-Perché non ti fai un giro?
+[KENT1]
+MISSIONE DI KENT PAUL 1
-[LRQC_3]
-Ti servira un posto dove nasconderti.
+[COUNT]
+MISSIONI DI FALSIFICAZIONE
-[LRQC_4]
-C'è un magazzino al confine di Bellville che farà al caso tuo.
+[COUNT1]
+MISSIONE DI FALSIFICAZIONE 1
-[LRQC_5]
-Ritorna qui nel mio appartamento quando sei pronto,
+[COUNT2]
+MISSIONE DI FALSIFICAZIONE 2
-[LRQC_6]
-Così possiamo chiacchierare un po'.
+[BIKE]
+MISSIONI DEI MOTOCICLISTI
-[JM6_5]
-~g~Ti serve un veicolo per la fuga, idiota!
+[BIKE1]
+MISSIONE DEI MOTOCICLISTI 1
-[JM2_F]
-Se ti serve un'arma, vai sul retro di AmmuNation dal lato opposto della metropolitana.
+[BIKE2]
+MISSIONE DEI MOTOCICLISTI 2
-[LOVE4_7]
-~g~C'è un cantiere edile a Staunton Island, forse hanno portato lì il pacco.
+[BIKE3]
+MISSIONE DEI MOTOCICLISTI 3
-[LOVE4_8]
-~g~Ti servirà un'auto per accedere al garage.
+[GOAWAY1]
+Ritorna quando avrai completato le missioni per la gang di Haiti.
-[TSCORE]
-GUADAGNI: ~1~$
+[HAIT]
+MISSIONI DEGLI HAITIANI
-[AM1_9]
-~r~Salvatore è fuggito di nuovo dentro il club Luigi's!
+[HAIT1]
+MISSIONE DEGLI HAITIANI 1
-[AM1_6]
-~g~Se ti aggiri attorno al club Luigi's, la Mafia ti avvisterà!
+[HAIT2]
+MISSIONE DEGLI HAITIANI 2
-[TM2_3]
-~g~È una trappola! Falli fuori tutti!!!
+[HAIT3]
+MISSIONE DEGLI HAITIANI 3
-[FM4_1]
-Sono Maria. L'auto è una trappola! Incontriamoci alla rampa a sud del ponte Callahan.
+[HAM3_6]
+~g~Utilizza il fucile di precisione che ti ho lasciato per completare la missione.
-[JM1_7]
-~g~Chiudi la portiera! Lo noterà!
+[ROCK]
+MISSIONI DELLA BAND
-[KM5_1]
-~g~TRITATO DI SPACCIATORE!
+[ROK1_4]
+~g~OK, credo tu stessi cercando questo...
-[KM5_6]
-~g~Devi uccidere almeno 8 spacciatori Yardie.
+[ROK1_1E]
+~g~Ti costerà di più di quanto hai!
-[KM5_7]
-~g~Uccidili in fretta! Dopo aver venduto lo SPANK spariscono dalla circolazione.
+[ROK1_1F]
+~g~Ritorna quando avrai i soldi.
-[RM3_8]
-~r~Quell'auto è un tranello!!!
+[RBM2_6]
+~g~Wow! È un uomo, bloccalo!
-[LM3_8]
-Ehi, sono Joey.
+[ROCK3]
+MISSIONE DELLA BAND 3
-[LM3_9]
-Luigi mi ha detto che sei affidabile, quindi torna più tardi,
+[ROK3_6D]
+~r~insieme alle vostre GROSSE TESTE DA CAPELLONI!
-[KM3_5]
-~g~Suona il clacson per avviare l'affare.
+[ROK3_40]
+Vicino al fottuto minibar?
-[LOVE7]
-LA SCOMPARSA DI LOVE
+[RBM3_5]
+~g~Porta i Love Fist allo spettacolo.
-[LOVE2_5]
-~g~Kenji è un tritato di carne! Allontanati da Newport e abbandona l'auto!
+[CUBANM]
+MISSIONI DEI CUBANI
-[AS2_11]
-~g~~1~ SU 9!
+[CUBAN1]
+MISSIONE DEI CUBANI 1
-[GARAGE1]
-~g~Esci dal veicolo ed esci fuori.
+[CUBAN2]
+MISSIONE DEI CUBANI 2
-[KM3_11]
-~g~Il Cartello è stato attaccato e la valigia non è stata recuperata.
+[CUB2_10]
+~r~Dovresti uccidere gli Haitiani, non i Cubani.
-[KM3_12]
-~g~Uccidi tutti i Colombiani, distruggi i veicoli e recupera la valigia.
+[CUBAN3]
+MISSIONE DEI CUBANI 3
-[KM3_13]
-~g~Riconsegna la valigia al Casinò.
+[CUBAN4]
+MISSIONE DEI CUBANI 4
-[RM5_6]
-~g~Ci è scappato! Spaccagli la corazza con un veicolo o con una bella esplosione!
+[CUB4_05]
+~r~Ti avevo detto di restare in macchina! Adesso non riusciremo mai a entrare!
-[PBOAT_1] { re3 change }
-Premi il ~h~tasto ~k~~VEHICLE_FIREWEAPON~~w~ per sparare con i cannoni della barca.
+[CUB4_25]
+OK, andiamo.
-[PBOAT_2] { re3 change }
-Premi il ~h~tasto ~k~~VEHICLE_FIREWEAPON~~w~ per sparare con i cannoni della barca.
+[PROT]
+MISSIONI DI PROTEZIONE
-[DIAB1_B]
-Sono El Burro dei Diablo.
+[PRO1_H]
+Perché non ti calmi per un secondo, sto finalmente cominciando a capire come funzionano le cose da queste parti.
-[DIAB1_D]
-Sei da poco a Liberty, ma ti sei già guadagnato una reputazione in città.
+[PRO1_02]
+~g~Esci dal Mall.
-[DIAB1_E]
-C'e una corsa d'auto con inizio alla vecchia scuola vicino al ponte Callahan.
+[PRO3_06]
+~g~Fai perdere le tracce.
-[DIAB1_F]
-Procurati un mezzo, il primo che attraversa tutti i posti di blocco vince il premio.
+[PORN]
+MISSIONI PORNOGRAFIA
-[HM2_1] { re3 change }
-Usa i maggiolini radiocomandati per distruggere le auto blindate. Premi il ~h~tasto ~k~~VEHICLE_FIREWEAPON~~w~ per farli esplodere.
+[PORN1]
+MISSIONE PORNOGRAFIA 1
-[HM2_1A] { re3 change }
-Usa i maggiolini radiocomandati per distruggere le auto blindate. Premi il ~h~tasto ~k~~VEHICLE_FIREWEAPON~~w~ per farli esplodere.
+[POR1_03]
+~r~Candy è morta!
-[HM2_2]
-~r~Non sei riuscito a distruggere tutte le auto blindate!
+[PORN2]
+MISSIONE PORNOGRAFIA 2
-[HM2_6]
-~g~Auto blindata distrutta!
+[PORN3]
+MISSIONE PORNOGRAFIA 3
-[RM3_A]
-Conosco un uomo molto importante in città, di manica larga,
+[POR3_18]
+Sei stato visto!
-[RM3_H]
-con gusti, diciamo, esotici e i soldi per permetterseli.
+[PORN4]
+MISSIONE PORNOGRAFIA 4
-[RM3_B]
-È coinvolto in un processo e l'accusa ha delle sue foto piuttosto imbarazzanti
+[POR4_04]
+~g~Gli uffici sono dall'altra parte di questo cancello.
-[RM3_C]
-in cui appare in un party all'obitorio.
+[PHIL]
+MISSIONI DI PHIL
-[LOVE6_A]
-Una lezione d'affari, amico.
+[PHIL1]
+MISSIONE DI PHIL 1
-[LOVE6_E]
-Se possiedi qualcosa di unico, il mondo intero cercherà di strappartelo dalle mani...
+[PHI1_06]
+Ma che combini, come diavolo guidi?
-[LOVE6_C]
-Squadre speciali di polizia hanno circondato la zona attorno al mio socio e al pacco.
+[PHI1_07]
+Ehi!
-[LOVE6_D]
-Vai li, prendi il furgone e fuggi per attirarli dietro di te.
+[PHIL2]
+MISSIONE DI PHIL 2
-[LOVE6_F]
-Tienili occupati, così che lui possa sfuggire!
+[PIZ1_A]
+MISSIONE RECAPITO PIZZE
-[AM3_C]
-Probabilmente quando lo leggerai questo sarà in alto mare! Ruba un'imbarcazione della polizia e mandalo a picco!
+[PIZ1_03]
+~g~Ritorna alla pizzeria e prendi le nuove ordinazioni.
-[FESZ_UC]
-ANNULLA
+[PIZ1_04]
+~g~Ecco le nuove ordinazioni.
-[FEDS_SM]
-L1,R1-CAMBIA MENU
+[PIZ1_10]
+Premi il ~h~tasto R3~w~ per annullare la missione.
-[FEDS_AS]
-;=-CAMBIA SELEZIONE
+[CNTBUY1]
+Tipografia acquistata: ~1~$
-[FEDSAS2]
-<>-CAMBIA SELEZIONE
+[CARBUY]
+Concessionario acquistato: ~1~$
-[FEDS_SS]
-L1,R1-CAMBIA SELEZIONE
+[PORNBUY]
+Studio cinematografico acquistato: ~1~$
-[FEDSSC1]
-;-SCORRIMENTO RAPIDO
+[ICEBUY]
+Fabbrica di gelato acquistata: ~1~$
-[FEDSSC2]
-=-FERMA SCORRIMENTO
+[TAXIBUY]
+Compagnia di taxi acquistata: ~1~$
-[MEA2_3]
-~g~Riporta l'auto alla fabbrica.
+[BANKBUY]
+Malibu acquistato: ~1~$
-[RM1_3]
-~r~McAffrey è scappato!
+[BOATBUY]
+Cantiere navale acquistato: ~1~$
-[RM1_4]
-~g~Hai usato tutte le granate! Procuratene altre da AmmuNation!
+[PRNT_NO]
+Non puoi ancora comprare la tipografia, prova più tardi.
-[RM1_5]
-~g~Torna indietro e incendia il rifugio!
+[CAR_NO]
+Non puoi ancora comprare il concessionario, prova più tardi.
-[RM6_4]
-~g~Vai al nascondiglio e preleva la roba di Ray.
+[PORN_NO]
+Non puoi ancora comprare lo studio cinematografico, prova più tardi.
-[RM6_5]
-~g~La CIA ha messo il ponte sotto sorveglianza, trova un altro punto d'accesso.
+[ICE_NO]
+Non puoi ancora comprare la fabbrica di gelato, prova più tardi.
-[HM2_F]
-e distruggi tutte le loro attrezzature blindate.
+[TAXI_NO]
+Non puoi ancora comprare la compagnia di taxi, prova più tardi.
-[HM_4]
-'CORSA AL LINGOTTO'
+[BANK_NO]
+Non puoi ancora comprare il Malibu, prova più tardi.
-[MEA2_B5]
-TESTO NON PIÙ NECESSARIO
+[BOAT_NO]
+Non puoi ancora comprare il cantiere navale, prova più tardi.
-[MEA1_B5]
-TESTO NON PIÙ NECESSARIO
+[PRNT_R3]
+Premi il tasto R3 per acquistare la tipografia per ~1~$
-[MEA3_B5]
-TESTO NON PIÙ NECESSARIO
+[CAR_R3]
+Premi il tasto R3 per acquistare il concessionario per ~1~$
-[MEA4_B7]
-ma se entri un attimo nel mio ufficio...
+[PORN_R3]
+Premi il tasto R3 per acquistare lo studio cinematografico per ~1~$
-[MEA3_B4]
-Marty vuole vedermi? È meglio che si sbrighi perché devo acconciarmi i capelli.
+[ICE_R3]
+Premi il tasto R3 per acquistare la fabbrica di gelato per ~1~$
-[KM3_7]
-È un esperto in trappole della Yakuza!
+[TAXI_R3]
+Premi il tasto R3 per acquistare la compagnia di taxi per ~1~$
-[FES_LOF]
-Caricamento fallito.
+[BANK_R3]
+Premi il tasto R3 per acquistare il Malibu per ~1~$
-[P1INSA]
-Ingresso 1. memory card (PS2) inserita. ~1~ K di spazio disponibile per salvare. ~1~ K necessari.
+[BOAT_R3]
+Premi il tasto R3 per acquistare il cantiere navale per ~1~$
-[P1INSN]
-Ingresso 1. memory card (PS2). Spazio disponibile insufficiente. Elimina alcuni file.
+[COL2_6]
+Fermo, brutto maiale imperialista americano!
-[FES_SLO]
-SALVA FILE
+[COL2_6B]
+Questa è proprietà del governo francese.
-[FES_ISC]
-CORROTTO
+[COL2_6C]
+È finita!
-[FESZ_TI]
-SALVA Z1
+[COL3_A]
+Thomas, grazie per essere venuto.
-[FESZ_SA]
-Salva partita
+[COL3_B]
+Scusami se giungo subito al punto.
-[P1NOIN]
-Ingresso 1. memory card (PS2) non inserita
+[COL3_C]
+Diaz mi ha chiesto di sovrintendere una piccola transizione di lavoro.
-[P1INSE]
-Ingresso 1. memory card (PS2) inserita.
+[COL3_D]
+Speriamo vada meglio dell'ultima...
-[MC_LDFL]
-Caricamento fallito!
+[COL3_E]
+Ed è per questo che ho pensato a te, amico.
-[MC_NWRE]
-Partita in fase di riavvio.
+[COL3_F]
+Ho lasciato un po' di supporto al parcheggio multipiano.
-[LOVE6_3]
-~g~Hai ~1~ secondi per tornare alla Securicar prima di fallire la missione.
+[COL3_G]
+Raccogli il materiale, poi raggiungi e sorveglia gli uomini di Diaz all'incontro.
-[LOVE6_4]
-~r~Hai distrutto la Securicar da depistaggio!
+[COL4_2]
+Non so signore!
-[HELP1]
-Fermati nel centro del segnale blu.
+[COL4_5]
+Signorsì, signore!
-[HELP12]
-Cammina nel centro del segnale blu per attivare una missione.
+[COL4_10]
+Andiamo a prendere delle ciambelle.
-[HJSTAT]
-Distanza: ~1~.~1~m Altezza: ~1~.~1~m Ribaltamenti: ~1~ Rotazioni: ~1~_
+[COL4_16]
+Signore! Sposto il veicolo, signore!
-[HJSTATW]
-Distanza: ~1~.~1~m Altezza: ~1~.~1~m Ribaltamenti: ~1~ Rotazioni: ~1~_ E che grande atterraggio!
+[COL4_25]
+Autodistruzione del veicolo attivata!
-[DIAB1_5]
-TEMPO DI GARA:
+[COL5_6]
+Mercedes, quella ragazza sarà la mia rovina.
-[LOVE3_4]
-~r~Hai distrutto l'aereo!!!
+[COL5_8]
+Maledetti scarafaggi!
-[F_FAIL1]
-Missione Camion dei pompieri terminata.
+[COL5_5]
+Morite, maiali Francesi!
-[F_CANC]
-~r~Missione Pompieri annullata!
+[CNT2_1]
+Uccidetelo
-[F_EXTIN]
-INCENDI:
+[CNT2_2]
+Recuperate le matrici!
-[A_COMP1]
-Missioni Infermieri completate!
+[CNT2_3]
+Proteggete il corriere.
-[A_CANC]
-~r~Missione Infermieri annullata!
+[FINKILL]
+OK ragazzi, uccidetelo!
-[A_COMP3]
-Missioni Infermieri completate! Ora non ti stancherai mai mentre corri!
+[FIN_6]
+Sonny è interessato alla mia cassaforte e ai miei soldi...
-[ATUTOR]
-Premi il ~h~tasto ~k~~TOGGLE_SUBMISSIONS~~w~ per attivare o disattivare le missioni Infermieri.
+[FIN_10]
+Sonny? SONNY! Sto venendo a prenderti!
-[ATUTOR3]
-Premi il ~h~tasto ~k~~TOGGLE_SUBMISSIONS~~w~ per attivare o disattivare le missioni Infermieri.
+[RACES_4]
+3
-[ALEVEL]
-Missione Infermieri Livello ~1~
+[RACES_5]
+2
-[A_FAIL1]
-Missione Infermieri terminata.
+[RACES_6]
+1
-[FEST_HA]
-Missione Infermieri - Livello Max.
+[RACES_7]
+VIA!
-[A_SAVES]
-PERSONE SALVATE: ~1~
+[RACES_9]
+Tempo: ~1~:~1~
-[C_KILLS]
-CRIMINALI UCCISI: ~1~
+[RACES]
+TEMPO:
-[HM1_B]
-Ho un problema. Stanno cercando di farsi gioco di me.
+[RACES17]
+Nuovo miglior tempo: ~1~:~1~
-[AM2_A]
-La morte di Salvatore è un'ottima notizia,
+[RACES20]
+Nuovo miglior tempo: ~1~:0~1~
-[AM2_A2]
-sei un killer efficiente. Mi piace come qualità in un uomo.
+[RACES21]
+Tempo: ~1~:0~1~
-[AM2_B]
-Lui è mio fratello Kenji.
+[RCH1_1]
+~g~Usa l'elicottero radiocomandato, il Raider, per PASSARE ATTRAVERSO i punti di controllo.
-[AM2_C]
-Asuka ha un lavoretto per te: quando hai finito, passa al Casinò così parliamo.
+[RCH1_2]
+~g~I punti di controllo sono sparsi per tutto l'aeroporto.
-[AM2_D]
-Proprio come Kenji, che cerca sempre di usare i miei giocattoli.
+[RCH1_3]
+~g~Hai ~c~8 MINUTI~g~ per attraversarli tutti e ~c~20~g~!
-[AM2_E]
-La mia fonte alla polizia mi ha informato che la Mafia sta studiando le nostre operazioni nella città
+[RCH1_5]
+Tempo
-[AM2_E2]
-nel tentativo di scovarti.
+[RCRC1_1]
+~g~Sfida nella GARA A TAPPE altri 3 Bandit radiocomandati su 2 GIRI.
-[AM2_F]
-Non possiamo continuare le nostre operazioni fino a quando il problema non verrà risolto.
+[RCRC1_2]
+~g~Raggiungi subito la griglia di partenza!
-[AM2_G]
-Elimina questi insulsi spioni e termina questa vendetta una volta per tutte.
+[RCRC1_3]
+~g~Giro finale!
-[F_START]
-~g~Veicolo in fiamme avvistato nell'area ~a~. Vai a spegnere il fuoco.
+[RCRC1_4]
+~g~3
-[AM4_1A]
-Vai al telefono al parco Belleville ovest.
+[RCRC1_5]
+~g~2
-[AM4_1B]
-Vai al telefono nel campus Liberty.
+[RCRC1_6]
+~g~1
-[AM4_1C]
-Vai al telefono al parco Belleville sud.
+[RCRC1_7]
+~g~VIA!
-[AM4_1D]
-Incontriamoci nei bagni pubblici nel parco.
+[RCRC1_8]
+~g~Tempo di gara: ~1~ secondi
-[HJSTATF]
-Distanza: ~1~ piedi Altezza: ~1~ piedi Ribaltamenti: ~1~ Rotazioni: ~1~_
+[RCPL1_1]
+~g~Sfida nella GARA A TAPPE altri 3 Baron radiocomandati.
-[HJSTAWF]
-Distanza: ~1~ piedi Altezza: ~1~ piedi Ribaltamenti: ~1~ Rotazioni: ~1~_ E che grande atterraggio!
+[RCPL1_2]
+~g~Devi attraversare la ~o~CORONA CENTRALE~g~ per passare con successo un punto di controllo.
-[HM1_F]
-Stai in guardia, però. Ci saranno dei Jack in giro che penseranno che vuoi far fuori anche loro!
+[RCPL1_3]
+~g~Raggiungi subito la griglia di partenza!
-[HM1_D]
-'Nine' è il loro nome e la loro bandiera è porpora e ogni giorno che portano i loro colori...
+[FEA_2SP]
+2 altoparlanti
-[HM1_G]
-è un giorno in cui i 'Jack' appaiono rammolliti.
+[FEA_4SP]
+Più di 2 altoparlanti
-[MEA2_B]
-e ruba qualcosa così che io possa incassare l'assicurazione come fai tu.
+[FEA_EAR]
+Cuffie
-[TM3_H]
-~w~Hai fatto un bel lavoro laggiù, molto bravo.
+[FEA_NAH]
+NESSUNA PERIFERICA AUDIO
-[TM3_I]
-~w~Forza, adesso ti presento al Don.
+[FET_APP]
+APPLICA
-[TM3_J]
-~w~Eehi!!! Luigi!
+[FES_SKN]
+NOME SKIN
-[TM3_K]
-~w~Oh, le mie ragazze hanno sentito la sua mancanza, Don Salvatore, è mancato per molto tempo.
+[FES_DAT]
+DATA
-[TM3_L]
-~w~Dì loro che una volta risolta questa situazione spiacevole,
+[FES_SET]
+Usa skin
-[TM3_M]
-~w~andremo tutti al club a festeggiare, OK?
+[FET_DEF]
+Ripristina predefiniti
-[TM3_N]
-~w~Ecco il mio ragazzo!
+[FESZ_QZ]
+Sei sicuro di voler salvare la partita?
-[TM3_N2]
-~w~Come va, papà?
+[FES_SCG]
+Salvare la partita?
-[TM3_O]
-~w~Ti sei trovato una brava mogliettina?
+[FES_LCG]
+Vuoi caricare e continuare la partita?
-[TM3_P]
-~w~Ehi, tua madre, pace all'anima sua, si rivolterebbe nella tomba
+[FEC_FIR]
+Fuoco
-[TM3_Q]
-~w~vedendoti ancora senza moglie.
+[FEC_NWE]
+Arma successiva
-[TM3_R]
-~w~Lo so, papà, ci sto pensando su.
+[FEC_PWE]
+Arma precedente
-[TM3_S]
-~w~TONI! Come sta tua madre?
+[FEC_FOR]
+Avanti
-[TM3_T]
-~w~È una donna eccezionale. Forte.
+[FEC_BAC]
+Indietro
-[TM3_U]
-~w~Sta bene... tutto OK.
+[FEC_LEF]
+Sinistra
-[TM3_V]
-~w~Bene, bene. Voi ragazzi entrate pure, mentre io chiacchiero col nostro nuovo amico.
+[FEC_RIG]
+Destra
-[TM3_W]
-~w~Vedo un futuro roseo per te, figghiu miu...
+[FEC_ZIN]
+Ingrandisci
-[RM1_A]
-Quell'infame di McAffrey, si prende più bustarelle di chiunque.
+[FEC_ZOT]
+Riduci
-[RM1_B]
-Pensa di venir assolto dignitosamente presentando delle prove inequivocabili.
+[FEC_EEX]
+Entra o esci
-[RM1_C]
-Ha appena cantato!
+[FEC_RAD]
+Radio
-[RM4_B]
-Dobbiamo metterlo a tacere, per sempre.
+[FEC_SUB]
+Sottomissione
-[RM4_E]
-Voglio che dorma con i pesci, in senso letterale.
+[FEC_CMR]
+Cambia visuale
-[LOVE3_B]
-Avvicinandosi all'aeroporto stasera, un piccolo aereo sorvolerà la baia.
+[FEC_JMP]
+Salto
-[LOVE4_D]
-Sfortunatamente le autorità aeroportuali avevano già iniziato a smantellare l'aereo
+[FEC_SPN]
+Scatto
-[LOVE4_H]
-finché non sono intervenuto sborsando una fortuna.
+[FEC_HND]
+Freno a mano
-[LOVE4_E]
-Attraversa il ponte per Shoreside Vale e vai all'aeroporto internazionale Francis.
+[FEC_LOL]
+Sguardo a sinistra
-[GTAB_A]
-Ehi, portiamo questo fuori di qui. Dio solo sa cos'è
+[FEC_LOR]
+Sguardo a destra
-[GTAB_B]
-ma sembra che lui lo voglia davvero, quindi dovrà pur valere qualcosa.
+[FEC_NTR]
+Bersaglio successivo
-[GTAB_C]
-Chi diavolo è!
+[FEC_PTT]
+Bersaglio precedente
-[GTAB_D]
-TU!
+[FEC_LBA]
+Sguardo indietro
-[GTAB_E]
-Ehi, in gamba amigo, stai calmo, amigo! Di niente, di niente!
+[FEC_CEN]
+Centra visuale
-[GTAB_F]
-Ti ho lasciato sfogare!
+[FET_CCN]
+Classico
-[GTAB_G]
-Non sparare amigo. Nessun problema. Siamo tutti amici. Ecco, prendi questo.
+[FET_SCN]
+Predefinito
-[GTAB_H]
-Non fare la femminuccia!
+[FET_CFT]
+A PIEDI
-[GTAB_I]
-Non abbiamo scelta, baby!
+[FET_CCR]
+IN MACCHINA
-[GTAB_J]
-C'è sempre una scelta, stupido bastardo!
+[FET_CAC]
+AZIONE
-[GTAB_K]
-Mi spiace per quella cretina, amigo, sono tutte uguali... por favor?
+[FEC_IBT]
+-
-[GTAB_L]
-Allora la puttana è scappata.
+[FEC_MXO]
+MXB1
-[GTAB_M]
-Ma mi hai fatto un favore,
+[FEC_MXT]
+MXB2
-[GTAB_N]
-non sei il solo che ha un conto in sospeso col Cartello,
+[FEC_UNB]
+NON ASSEGNATO
-[GTAB_O]
-questo verme ha ucciso mio fratello!
+[FEC_TFL]
+Sguardo+Torretta a SX
-[GTAB_P]
-Non ho mai ucciso nessun Yakuza!
+[FEC_TFR]
+Sguardo+Torretta a DX
-[GTAB_Q]
-BUGIARDO! Abbiamo visto tutti l'assassino del Cartello.
+[FEC_MWF]
+VOLANTE SU
-[GTAB_R]
-Daremo la caccia ed elimineremo tutti voi cani Colombiani!
+[FEC_MWB]
+VOLANTE GIÙ
-[GTAB_S]
-Farò un'operazione al nostro amichetto per strappargli qualche informazione e per divertirmi.
+[FEC_ORR]
+o
-[GTAB_T]
-Tu, passa più tardi, sono certo che avrò bisogno del tuo aiuto.
+[FEC_NUS]
+NON USATO
-[GTAB_U]
-Ti prego, amigo, non lasciarmi con lei, è tutta matta! Amigo? Ehi Amiiigooo!!! Aieeeeeeaaaaahh!!!
+[FEC_LUD]
+Sguardo su
-[LOVE5_A]
-Ti stai dimostrando un buon investimento, cosa rara in questi giorni.
+[FEC_LDU]
+Sguardo giù
-[KM3_1]
-~g~Il Cartello aspetta una gang di Yardie. Vai a rubare una loro auto! Dirigiti a nord, ne troverai una a Newport.
+[FEC_CMP]
+COMBO: SGUARDO SX+DX
-[LOVE1_1]
-~g~Procurati un'auto dei gangster Colombiani per infiltrarti nel loro nascondiglio: dirigiti a nord, ne troverai una a Fort Staunton.
+[LAW_1A]
+law_1a
-[FM1_Q1]
-~w~Ti va di divertirti? Un po' di... hmmm? Un po' di SPANK?
+[LAW_1B]
+law_1b
-[FM1_R]
-~w~Ciao Chico. No, il solito.
+[LAW_2A]
+law_2a
-[FM1_T]
-~w~Grazie Chico, a presto.
+[LAW_2B]
+law_2b
-[FM1_W]
-~w~OK, Fido, aspetta qui e tieni d'occhio l'auto mentre io vado a sculettare un po'.
+[FEH_STA]
+STATISTICHE
-[FM1_X]
-~w~OK, Fido, andiamocene via di qui. Uuuhhh!
+[FEH_LOA]
+CARICA
-[FM1_Q]
-~w~Ehi, Maria! La mia ragazza preferita!
+[FEH_CON]
+COMANDI
-[FM1_S1]
-~w~Ehi, forse dovresti dare un'occhiata al party nei magazzini sulla costa est del molo atlantico.
+[FEH_AUD]
+AUDIO
-[FM1_U]
-~w~Gracias e buon divertimento. È roba buona.
+[FEH_DIS]
+VIDEO
-[FM1_V]
-~w~Forza, Fido, facciamo un salto a questo party!
+[FEH_LAN]
+LINGUA
-[FM1_SS]
-~r~SCANNER: ~g~4-5 a tutte le unità: rinforzi per l'operazione antinarcotici al molo atlantico...
+[FEH_SGA]
+NUOVA PARTITA
-[LOVE6_B]
-Anche se hanno scarsa comprensione del suo autentico valore.
+[FEO_CON]
+Impostazioni controller
-[TM3_A1]
-~r~Joey è spacciato!
+[FEO_AUD]
+Impostazioni audio
-[TM3_A2]
-~r~Joey e Luigi sono stati cremati!
+[FEO_DIS]
+Impostazioni video
-[TM3_A3]
-~r~Joey, Luigi e Toni sono fritti!
+[FEO_LAN]
+Impostazioni lingua
-[FM4_2]
-Ascolta, Salvatore pensa che vogliamo tradirlo,
+[FEO_PLA]
+Impostazioni giocatore
-[FM4_3]
-per cui ti stava per consegnare al Cartello per raggiungere un accordo.
+[FEA_OUT]
+Uscita
-[FM4_4]
-Non potevo lasciarglielo fare, e poi la cosa peggiore è che
+[FEA_ST]
+Stereo
-[FM4_4B]
-è tutta colpa mia... perché gli ho detto che stavamo insieme.
+[FEA_DTS]
+DTS
-[FM4_5]
-Non chiedermi il perché. Non lo so.
+[FEA_RSS]
+Stazione radio
-[FM4_6]
-Senti, sei un uomo spacciato in territorio mafioso, e anch'io devo svignarmela.
+[FEA_NON]
+NO RADIO
-[FM4_6B]
-Ho visto troppi omicidi. Troppo sangue!
+[FEA_FM0]
+WILDSTYLE
-[FM4_7]
-Questa è una mia vecchia amica, OK, di vecchia data. È Asuka, ed è una tipa fidata.
+[FEA_FM1]
+FLASH FM
-[FM4_8]
-Forza, basta con i discorsi.
+[FEA_FM2]
+KCHAT
-[FM4_9]
-Dovremmo andarcene prima che arrivino altri italiani isterici poco propensi a una discussione amichevole.
+[FEA_FM3]
+FEVER 105
-[CRED001]
-ROCKSTAR STUDIOS
+[FEA_FM4]
+VROCK
-[CRED002]
-PRODUTTORE
+[FEA_FM5]
+VCPR
-[CRED003]
-LESLIE BENZIES
+[FEA_FM7]
+EMOTION 98.3
-[CRED004]
-DIREZIONE ARTISTICA
+[FEA_FM8]
+WAVE 103
-[CRED005]
-AARON GARBUT
+[FED_BRI]
+Luminosità
-[CRED006]
-DIREZIONE TECNICA
+[FED_TRA]
+Tracce :
-[CRED007]
-OBBE VERMEIJ
+[FED_SUB]
+Sottotitoli
-[CRED008]
-ADAM FOWLER
+[FED_WIS]
+Panoramico
-[CRED009]
-DESIGN
+[FED_POS]
+Posizione schermo
-[CRED010]
-CRAIG FILSHIE
+[FEP_RES]
+Riprendi
-[CRED011]
-WILLIAM MILLS
+[FEP_STG]
+Avvia partita
-[CRED012]
-CHRIS ROTHWELL
+[FEP_STA]
+Statistiche
-[CRED013]
-JAMES WORRALL
+[FEP_BRI]
+Briefing
-[CRED014]
-SCRITTO DA
+[FEP_OPT]
+Opzioni
-[CRED015]
-JAMES WORRALL
+[FEP_QUI]
+Esci
-[CRED016]
-PAUL KUROWSKI
+[FES_LOA]
+Carica partita
-[CRED017]
-DAN HOUSER
+[FES_DEL]
+Elimina partita
-[CRED018]
-PERSONAGGI
+[FEC_CSU]
+Impostazioni controller
-[CRED019]
-IAN MCQUE
+[FEC_RED]
+Ridefinisci comandi
-[CRED020]
-ANIMAZIONE E REGIA
+[FEC_MOU]
+Impostazioni mouse
-[CRED021]
-ALEX HORTON
+[DISTGOL]
+Distanza percorsa su cart da golf (miglia)
-[CRED022]
-LEE MONTGOMERY
+[DISTGOM]
+Distanza percorsa su cart da golf (metri)
-[CRED023]
-DESIGN AUTOMOBILI
+[ST_FAVR]
+Stazione radio preferita
-[CRED024]
-PAUL KUROWSKI
+[ST_WSTR]
+Stazione radio meno amata
-[CRED025]
-GRAFICI
+[ST_FAVV]
+Veicolo preferito
-[CRED026]
-KEIRAN BAILLIE
+[ST_STAR]
+Totale stelle di sospetto
-[CRED027]
-ADAM COCHRANE
+[ST_HEAD]
+Colpi alla testa
-[CRED028]
-GARY MCADAM
+[ST_GANG]
+Gang meno amata
-[CRED029]
-MICHAEL PIRSO
+[ST_STGN]
+Totale stelle di sospetto evase
-[CRED030]
-ANDREW SOOSAY
+[TYREPOP]
+Pneumatici esplosi con proiettili
-[CRED031]
-ALISDAIR WOOD
+[TYRESLA]
+Pneumatici tagliati con una lama
-[CRED032]
-CODIFICATORI
+[ST_BRK]
+Numero di uccisioni nel Bloodring
-[CRED033]
-ALAN CAMPBELL
+[ST_LTBR]
+Permanenza massima nel Bloodring (sec)
-[CRED034]
-MARK HANLON
+[ST_GNG1]
+Cubani
-[CRED035]
-ANDRZEJ MADAJCZYK
+[ST_GNG2]
+Haitiani
-[CRED036]
-ALEXANDER ROGER
+[ST_GNG3]
+Teppistelli
-[CRED037]
-GRAEME WILLIAMSON
+[ST_GNG4]
+Gang di Diaz
-[CRED038]
-MUSICHE
+[ST_GNG5]
+Sorveglianza
-[CRED039]
-CRAIG CONNER
+[ST_GNG6]
+Gang di motociclisti
-[CRED040]
-STUART ROSS
+[ST_GNG7]
+Gang di Vercetti
-[CRED041]
-DESIGN AUDIO E MASTERIZZAZIONE
+[ST_GNG8]
+Giocatori di golf
-[CRED042]
-ALLAN WALKER
+[FEA_FM6]
+ESPANTOSO
-[CRED043]
-PROGRAMMAZIONE AUDIO
+[ST_ASSI]
+Contratti da sicario completati
-[CRED044]
-RAYMOND USHER
+[DISTBIK]
+Distanza percorsa in moto (miglia)
-[CRED045]
-DIRETTORE TESTING
+[DISTBIM]
+Distanza percorsa in moto (metri)
-[CRED046]
-CRAIG ARBUTHNOTT
+[HOTEL]
+Hotel Ocean View
-[CRED047]
-TESTER PRINCIPALI
+[ICC1_1]
+~g~Utilizza il camioncino dei gelati per distribuire droga in Vice City.
-[CRED048]
-ANDY DUTHIE
+[ICC1_2]
+~g~Parcheggia il camioncino e premi ~h~~k~~VEHICLE_HORN~~w~ per attivare il campanello e attrarre i clienti.
-[CRED049]
-JOHN HAIME
+[ICC1_3]
+~g~Riceverai soldi per ogni transizione, ma più ne esegui, maggiori saranno le probabilità di attirare l'attenzione della polizia.
-[CRED050]
-NEIL CORBETT
+[KICK1_9]
+PUNTI DI CONTROLLO RIMANENTI:
-[CRD050A]
-TESTER
+[FIN_B6]
+Non hai abbastanza soldi per avviare questa missione.
-[CRED051]
-GRAEME JENNINGS
+[TEX3_3]
+~g~Per raccogliere una bomba, avvicinati con l'elicottero: la bomba verrà automaticamente raccolta.
-[CRED052]
-DAVID MURDOCH
+[TEX3_9]
+~g~Raccogli una bomba avvicinandole l'elicottero.
-[CRED053]
-DAVID BEDDOES
+[HELP22]
+Raggiungi la casa verde sul radar.
-[CRED054]
-EDWIN SMITH
+[FES_FMS]
+Formattazione completata. Seleziona OK per continuare.
-[CRED055]
-MARK FLETT
+[FES_SSC]
+Salvataggio completato. Seleziona OK per continuare.
-[CRED056]
-MICHAEL SUTHERLAND
+[FES_DSC]
+Eliminazione completata. Seleziona OK per continuare.
-[CRED057]
-SUPPORTO TECNICO
+[FESZ_QC]
+Vuoi sovrascrivere il salvataggio corrotto?
-[CRED058]
-LORRAINE ROY
+[FES_CHE]
+Attenzione! Uno o più trucchi sono stati attivati: ciò influenzerà il salvataggio. Si consiglia di non salvare questa partita.
-[CRED059]
-CHRISTINE CHALMERS
+[FET_SG]
+SALVA PARTITA
-[CRED060]
-ROCKSTAR
+[FEH_BRI]
+BRIEFING
-[CRED061]
-PRODUTTORE ESECUTIVO
+[FEH_MAP]
+MAPPA
-[CRED062]
-SAM HOUSER
+[FEM_OK]
+OK
-[CRED063]
-PRODUTTORE
+[FEC_CRO]
+Abbassarsi
-[CRED064]
-DAN HOUSER
+[FEC_CR3]
+Abbassarsi (tasto L3)
-[CRED065]
-DIRETTORE DI SVILUPPO
+[FEC_SMT]
+Sottomissione
-[CRED066]
-JAMIE KING
+[FEC_SM3]
+Sottomissione (tasto R3)
-[CRED067]
-PRODUTTORE TECNICO
+[FEC_RSC]
+Stazioni radio
-[CRED068]
-GARY J. FOREMAN
+[ST_PR01]
+Apprendista
-[CRED069]
-PRODUTTORE ASSOCIATO
+[ST_PR02]
+Aviere
-[CRED070]
-JEREMY POPE
+[ST_PR03]
+Ufficiale
-[CRED071]
-SUPERVISORE MUSICHE
+[ST_PR04]
+Caporale
-[CRED072]
-TERRY DONOVAN
+[ST_PR05]
+Tenente
-[CRED073]
-ROCKSTAR PRODUCTION TEAM
+[ST_PR06]
+Sergente
-[CRED074]
-TERRY DONOVAN
+[ST_PR07]
+Capitano
-[CRED075]
-JENNIFER KOLBE
+[ST_PR08]
+Biggs
-[CRED076]
-JENEFER GROSS
+[ST_PR09]
+Wedge
-[CRED077]
-LAURA PATERSON
+[ST_PR10]
+Barone rosso
-[CRED078]
-JEFF CASTANEDA
+[ST_PR11]
+Goose
-[CRED079]
-CHRIS CARRO
+[ST_PR12]
+Viper
-[CRED080]
-ADAM TEDMAN
+[ST_PR13]
+Jester
-[CRED081]
-JUNG KWAK
+[ST_PR14]
+Chappy
-[CRED082]
-BRIAN WOOD
+[ST_PR15]
+Iceman
-[CRED083]
-PAUL YEATES
+[ST_PR16]
+Maverick
-[CRED084]
-STANTON SARJEANT
+[ST_PR17]
+Noops
-[CRED085]
-VICEPRESIDENTE MARKETING
+[ST_PR18]
+Maresciallo
-[CRED086]
-TERRY DONOVAN
+[ST_PR19]
+Asso
-[CRED087]
-COORDINATORE TECNICO
+[FET_LG]
+CARICA PARTITA
-[CRED088]
-BRANDON ROSE
+[CAR_EXP]
+Veicoli distrutti
-[CRED089]
-RESPONSABILE CONTROLLO QUALITÀ
+[BOA_EXP]
+Imbarcazioni distrutte
-[CRED090]
-JEFF ROSA
+[HEL_DST]
+Velivoli distrutti
-[CRED091]
-LEAD ANALYST
+[STFT_01]
+Tempo migliore in 'Due ruote d'acciaio'
-[CRED092]
-ADAM DAVIDSON
+[STFT_02]
+Tempo migliore in 'L'autista'
-[CRED093]
-ANALISTA DEL GIOCO
+[STFT_03]
+Tempo migliore nella prova del fango
-[CRED094]
-RICHARD HUIE
+[STFT_04]
+Tempo migliore con gli aerei radiocomandati
-[CRED095]
-SQUADRA TESTING
+[STFT_05]
+Tempo migliore con le macchine radiocomandate
-[CRED096]
-LANCE WILLIAMS
+[STFT_06]
+Tempo migliore di raccolta con l'elicottero
-[CRED097]
-JOE GREENE
+[STFT_07]
+Tempo migliore in 'Terminal Velocity'
-[CRED098]
-BRIAN PLANER
+[STFT_08]
+Tempo migliore in 'Ocean Drive'
-[CRED099]
-OSWALD GREENE
+[STFT_09]
+Tempo migliore in 'Border Run'
-[CRED100]
-PIANTA DI LIBERTY
+[STFT_10]
+Tempo migliore in 'Capital Cruise'
-[CRED101]
-JAMES WORRALL
+[STFT_11]
+Tempo migliore in 'Tour!'
-[CRED102]
-DAN HOUSER
+[STFT_12]
+Tempo migliore in 'V.C. Endurance'
-[CRED103]
-ADAM TEDMAN
+[STHC_01]
+Punteggio migliore al poligono
-[CRED104]
-PAUL YEATES
+[STHC_02]
+Miglior percentuale di colpi al poligono
-[CRED105]
-JENEFER GROSS
+[STHC_03]
+Numero di traffici di droga
-[CRED106]
-LAURA PATERSON
+[HELP24]
+Adesso puoi accettare le missioni del Colonnello.
-[CRED107]
-SEQUENZE ANIMATE
+[HELP25]
+Adesso puoi accettare le missioni di Avery Carrington.
-[CRED108]
-COPIONE SCRITTO DA DAN HOUSER E JAMES WORRALL
+[HELP29]
+Puoi far visita al negozio di abbigliamento quando non sei in missione.
-[CRED109]
-REGISTRAZIONE AUDIO DIRETTA DA DAN HOUSER
+[HELP30]
+Quando compri nuovi abiti, il tuo livello di sospetto scenderà a zero.
-[CRED110]
-AUDIO PRODOTTO DA RENAUD SEBBANE
+[BJM2_22]
+~r~Sei uscito dal poligono di tiro!
-[CRED111]
-CASTING
+[BJM2_23]
+~g~Se esci dal poligono di tiro durante la competizione, fallirai la missione.
-[CRED112]
-FRANK VINCENT NEL RUOLO DI SALVATORE LEONE
+[ASM4_24]
+Distanza:
-[CRED113]
-JOE PANTOLIANO NEL RUOLO DI LUIGI GOTERELLI
+[RBM1_6]
+~g~Porta Mercedes e la 'Love Juice' al gruppo nello studio di registrazione.
-[CRED114]
-MICHAEL MADSEN NEL RUOLO DI TONI CIPRIANI
+[RBM1_3]
+NON NECESSARIO
-[CRED115]
-MICHAEL RAPAPORT NEL RUOLO DI JOEY LEONE
+[HAM1_5]
+NON NECESSARIO
-[CRED116]
-DEBBI MAZAR NEL RUOLO DI MARIA
+[RBM1_11]
+NON NECESSARIO
-[CRED117]
-KYLE MACLACHLAN NEL RUOLO DI DONALD LOVE
+[HELP31]
+Per eseguire un assalto in macchina, guarda a destra o a sinistra premendo il tasto L2 o il tasto R2.
-[CRED118]
-ROBERT LOGGIA NEL RUOLO DI RAY MACHOWSKI
+[HELP34]
+Hai bisogno di una mitragliatrice per eseguire un assalto in macchina.
-[CRED119]
-GURU NEL RUOLO DI 8-BALL
+[STRIP_1]
+~r~Soldi insufficienti, brutto idiota.
-[CRED120]
-SONDRA JAMES NEL RUOLO DI MOMMA
+[EXIT_1]
+Premi ~k~~PED_SPRINT~ per uscire.
-[CRED121]
-LIANA PAI NEL RUOLO DI ASUKA
+[ASM1_A]
+Mr. Teal, il tuo aiuto nello sradicare gli stranieri è stato inestimabile per il nostro lavoro. Ho un altro compito con un contatto più 'diretto'.
-[CRED122]
-LES MAU NEL RUOLO DI KENJI
+[ASM1_B]
+I dettagli per il prossimo colpo sono stati attaccati sotto al telefono.
-[CRED123]
-CYNTHIA FARRELL NEL RUOLO DI CATALINA
+[ASM1_C]
+Ho un altro compito con un contatto più 'diretto'.
-[CRED124]
-AL ESPINOSA NEL RUOLO DI MIGUEL
+[SCARF]
+Appartamento 3c
-[CRED125]
-CHRIS PHILLIPS NEL RUOLO DI EL BURRO
+[LAW4_10]
+La ricca amministrazione ci ha rotto!
-[CRED126]
-HUNTER PLATIN NEL RUOLO DI CHICO
+[GEN1_04]
+~g~Attraversa la porta per accedere alla piattaforma sul tetto di Gonzalez.
-[CRED127]
-WALTER MUDU NEL RUOLO DI D-ICE
+[GEN1_17]
+~g~Gonzalez sta fuggendo! Seguilo attraverso le porte e finiscilo!
-[CRED128]
-CURTIS MCCLARIN NEL RUOLO DI CURTLY
+[RCH1_9]
+~b~TEMPO TOTALE: ~1~:~1~
-[CRED129]
-BILL FIORE NEL RUOLO DI DARKEL
+[RCH1_10]
+~b~TEMPO TOTALE: ~1~:0~1~
-[CRED130]
-CHRIS PHILLIPS NEL RUOLO DI MARTY CHONKS
+[WHEEL01]
+BONUS DOPPIO SU DUE RUOTE: ~1~$ Distanza: ~1~.~1~ m Tempo: ~1~ secondi
-[CRED131]
-HUNTER PLATIN NEL RUOLO DI RICCIOLINO BOB
+[WHEEL02]
+BONUS DOPPIO SU DUE RUOTE: ~1~$ Distanza: ~1~ piedi Tempo: ~1~ secondi
-[CRED132]
-WALTER MUDU NEL RUOLO DI KING COURTNEY
+[WHEEL03]
+BONUS SU DUE RUOTE: ~1~$ Tempo: ~1~ secondi
-[CRED133]
-HUNTER PLATIN NEL RUOLO DI ONE-ARMED PHIL
+[WHEEL04]
+BONUS SU DUE RUOTE: ~1~$ Distanza: ~1~.~1~ m
-[CRED134]
-KIM GURNEY NEL RUOLO DI MISTY
+[WHEEL05]
+BONUS SU DUE RUOTE: ~1~$ Distanza: ~1~ piedi
-[CRED135]
-MOTION CAPTURE
+[WHEEL06]
+BONUS IMPENNATA: ~1~$ Distanza: ~1~.~1~ m Tempo: ~1~ secondi
-[CRED136]
-ANIMATO DA
+[WHEEL07]
+BONUS IMPENNATA: ~1~$ Distanza: ~1~ piedi Tempo: ~1~ secondi
-[CRD136A]
-ALEX HORTON
+[WHEEL08]
+BONUS IMPENNATA: ~1~$ Tempo: ~1~ secondi
-[CRED137]
-DIRETTO DA
+[WHEEL09]
+BONUS IMPENNATA: ~1~$ Distanza: ~1~.~1~ m
-[CRD137A]
-NAVID KHONSARI
+[WHEEL10]
+BONUS IMPENNATA: ~1~$ Distanza: ~1~ piedi
-[CRED138]
-PRODOTTO DA
+[WHEEL11]
+BONUS FRENATA IN PUNTA: ~1~$ Distanza: ~1~.~1~ m Tempo: ~1~ secondi
-[CRD138A]
-JAMIE KING
+[WHEEL12]
+BONUS FRENATA IN PUNTA: ~1~$ Distanza: ~1~ piedi Tempo: ~1~ secondi
-[CRD138B]
-RENAUD SEBBANE
+[WHEEL13]
+BONUS FRENATA IN PUNTA: ~1~$ Tempo: ~1~ secondi
-[CRED139]
-REGISTRATO PRESSO GLI STUDI MODERN UPRISING, BROOKLYN
+[WHEEL14]
+BONUS FRENATA IN PUNTA: ~1~$ Distanza: ~1~.~1~ m
-[CRED140]
-ATTORI
+[WHEEL15]
+BONUS FRENATA IN PUNTA: ~1~$ Distanza: ~1~ piedi
-[CRD140A]
-RENAUD SEBBANE
+[ROK3_72]
+Love Fist!
-[CRD140B]
-GISELLE JONES
+[POR1_19]
+Ehi!
-[CRD140C]
-STEPHEN DANIELS
+[DESPERA]
+Desperado
-[CRD140D]
-ROBERT STIO
+[MOB_99A]
+Raggiungi il telefono pubblico vicino al Mall in Washington.
-[CRD140E]
-JENNY GROSS
+[MOB_98A]
+Raggiungi il telefono pubblico in Vice Point.
-[CRED141]
-DIALOGO DEI PEDONI
+[MOB_96A]
+Raggiungi il telefono pubblico al terminal dell'aeroporto.
-[CRED142]
-SCRITTO DA DAN HOUSER, NAVID KHONSARI & JAMES WORRALL
+[MOB_95A]
+Raggiungi il telefono pubblico in Little Havana.
-[CRED143]
-DIRETTO DA CRAIG CONNER, DAN HOUSER E LAZLOW
+[BNK1_1]
+La posso aiutare, signore?
-[CRED144]
-PRODOTTO DA RENAUD SEBBANE
+[BNK1_2]
+Un impostore!
-[CRED145]
-CAST
+[BNK1_3]
+È impazzito!
-[CRED146]
-HUNTER PLATIN
+[BNK1_4]
+Ma chi diavolo sei?
-[CRED147]
-DAN HOUSER
+[BNK1_5]
+Dov'è il tuo distintivo?
-[CRED148]
-RENAUD SEBBANE
+[BNK1_6]
+Eccoli là! Sparate per uccidere!
-[CRED149]
-MARIA CHAMBERS
+[MOB_24A]
+Salve: Mr Vercetti?
-[CRED150]
-JEFF STANTON
+[MOB_24B]
+Sì.
-[CRED151]
-RYAN CROY
+[MOB_24C]
+Sono Cortez. Eri invitato al mio party.
-[CRED152]
-DEENA BERMAN
+[MOB_24D]
+Sì, ricordo.
-[CRED153]
-MARIA CHAMBERS
+[MOB_24E]
+Mr. Vercetti, è stato davvero uno sfortunato incidente quello avvenuto al tuo accordo.
-[CRED154]
-ALICE B. SALTZMAN
+[MOB_24F]
+Lo so.
-[CRED155]
-ALEX ANTHONY SIOUKAS
+[MOB_24G]
+Sappi che io e la mia gente stiamo facendo il massimo per scoprire cosa è successo.
-[CRED156]
-SEAN R. LYNCH
+[MOB_24H]
+Se vuoi parlarne in prima persona, mi troverai sulla mia barca. Buona giornata, senor.
-[CRED157]
-AMY SALZMAN
+[BNK2_2]
+MIRARE 3-2-1 FUOCO!
-[CRED158]
-COLIN MCSHANE
+[BNK2_3]
+AREA RIPULITA!
-[CRED159]
-COREY WADE
+[BNK2_6]
+Questo tipo è pazzo!
-[CRED160]
-GERALD COSGROVE
+[ANGEL]
+Angel
-[CRED161]
-STEPHANIE ROY
+[CUBJET]
+Jetmax Cubano
-[CRED162]
-DORIS WOO
+[SANDKIN]
+Sandking
-[CRED163]
-JOSEPH GREENE
+[POLMAV]
+Maverick della polizia
-[CRED164]
-LAZLOW JONES
+[BOXVILL]
+Boxville
-[CRED165]
-HSIANG LIN
+[BENSON]
+Benson
-[CRED166]
-STEVE MICHAEL ROBERT
+[HOTRINA]
+Hotring Racer
-[CRED167]
-MATHEW MURRAY
+[HOTRINB]
+Hotring Racer
-[CRED168]
-RICHARD HUIE
+[BLOODRA]
+Bloodring Banger
-[CRED169]
-GARVIN ATWELL
+[BLOODRB]
+Bloodring Banger
-[CRED170]
-STEVE KNEZEVICH
+[MAFIACR]
+Cruiser della Mafia
-[CRED171]
-YUKIMURA SATO
+[COP_M2]
+'VICE SQUAD'
-[CRED172]
-FRANK CHAVEZ
+[COP_M3]
+'BROWN THUNDER'
-[CRED173]
-LIEZL JACINTO
+[BJM2_20]
+~g~Quando finisci il ~w~tempo~g~ o i ~w~colpi~g~, il turno è finito!
-[CRED174]
-CANAAN MCKOY
+[BNK3_2]
+Non intendo guidare per te, per niente, e lo dirò ai miei compagni di terapia.
-[CRED175]
-ADAM DAVIDSON
+[FEM_SL1]
+Salvataggio 1 non trovato
-[CRED176]
-LANCE WILLIAMS
+[FEM_SL2]
+Salvataggio 2 non trovato
-[CRED177]
-NEIL MCCAFFREY
+[FEM_SL3]
+Salvataggio 3 non trovato
-[CRED178]
-LAURA PATERSON
+[FEM_SL4]
+Salvataggio 4 non trovato
-[CRED179]
-REY CONCEPCION
+[FEM_SL5]
+Salvataggio 5 non trovato
-[CRED180]
-CHARLES HEROLD
+[FEM_SL6]
+Salvataggio 6 non trovato
-[CRED181]
-ANDREW GREENWALD
+[FEM_SL7]
+Salvataggio 7 non trovato
-[CRED182]
-JAMES MIELKE
+[FEM_SL8]
+Salvataggio 8 non trovato
-[CRED183]
-PETER SUCIU
+[FEA_CHA]
+Modifica uscita audio in STEREO. Attendere...
-[CRED184]
-ALEX ODULIO
+[FEA_CHD]
+Attenzione! Modifica uscita audio da STEREO a DTS. Attendere...
-[CRED185]
-DON NKRUMAH
+[FEI_SEL]
+Seleziona
-[CRED186]
-KENDALL PITTMAN
+[FEI_BAC]
+Indietro
-[CRED187]
-SAL SUAZO
+[FEI_RES]
+Riprendi
-[CRED188]
-EREK MATEO
+[FEI_NAV]
+Naviga
-[CRED189]
-CHRIS DIFATE
+[FEI_BTX]
+Tasto / -
-[CRED190]
-LEILA MILTON
+[FEI_BTT]
+Tasto " -
-[CRED191]
-DARREN ZOLTOWSKI
+[FEI_STA]
+Tasto START -
-[CRED192]
-VIRGINIA SMITH
+[FEI_BTD]
+; = > < -
-[CRED193]
-KEVIN CASSIN
+[FEI_STO]
+Stop
-[CRED194]
-JASON SHIGEMORI
+[MOB_68A]
+Ehi Tommy, ho una sorpresa per te.
-[CRED195]
-KELLY KINSELLA
+[MOB_68B]
+Sono allo studio cinematografico con dei grandi artisti.
-[CRED196]
-MOLLIE STICKNEY
+[MOB_68C]
+Perché non vieni a farci visita?
-[CRED197]
-STANTON SARJEANT
+[MOB_68D]
+Lo sai che è una buona idea, vero? Ci vediamo.
-[CRED198]
-LAURA WALSH
+[OUTFT1]
+Da strada
-[CRED199]
-MARK GARONE
+[OUTFT2]
+Eleganti
-[CRED200]
-JOANNA SLY
+[OUTFT3]
+Tuta
-[CRED201]
-ELIZABETH HOWELL
+[OUTFT4]
+Sportivo
-[CRED202]
-ANA HERCULES
+[OUTFT5]
+Havana
-[CRED203]
-SHIRLEY IRICK
+[OUTFT6]
+Da poliziotto
-[CRED204]
-KASHONA FIELDS
+[OUTFT7]
+Da rapina
-[CRED205]
-JOEL M. LILJE
+[OUTFT8]
+Casual
-[CRED206]
-JOHN DIBENEDETTO
+[OUTFT9]
+Mr. Vercetti
-[CRED207]
-NANCY GILES
+[OUTFT10]
+Da corsa
-[CRED208]
-RYAN CROY
+[OUTFT13]
+MC Tommy
-[CRED209]
-JENNIFER KOLBE
+[HOTR_07]
+Nuovo miglior tempo: ~1~:0~1~
-[CRED210]
-LIAM BURKE
+[HOTR_08]
+Tempo: ~1~:~1~
-[CRED211]
-SIGRID PREISSL
+[GEN3_45]
+Arriveranno fra pochi minuti: troviamo un buon punto dove appostarci...
-[CRED212]
-ANITA FITZSIMONS
+[CAR_AS1]
+BENI CONCESSIONARIA ACQUISITI
-[CRED213]
-PHILIPPA RASELLI
+[CAR_AS2]
+~g~La concessionaria d'ora in poi genererà introiti per un massimo di ~1~$. Ricordati di recuperarli regolarmente.
-[CRED214]
-WIL QUESNEL
+[BUYSAVE]
+~g~Se non sei in missione, potrai ora salvare la partita da qui gratuitamente.
-[CRED215]
-FALKO BURKERT
+[BUYGARG]
+~g~Potrai anche depositare i mezzi in questo garage.
-[CRED216]
-SARA SEWELL
+[STRPBUY]
+Club Pole Position acquistato: ~1~$
-[CRED217]
-STAZIONI RADIO E MUSICA
+[STRP_R3]
+Premi il tasto R3 per acquistare il club Pole Position per ~1~$
-[CRED218]
-PRODUTTORI PER ROCKSTAR UK
+[NBMN_R3]
+Premi il tasto R3 per acquistare Elswanko Casa per ~1~$
-[CRD218A]
-CRAIG CONNER
+[GA_4]
+Le bombe per le macchine costano 1000$
-[CRD218B]
-STUART ROSS
+[GA_5]
+La tua macchina ha già una bomba installata.
-[CRED219]
-COORDINATORE COLONNA SONORA
+[GA_6] { reVC update }
+Parcheggiala, attivala premendo il ~h~~k~~VEHICLE_FIREWEAPON~~w~ e DATTELA A GAMBE!
-[CRED220]
-TERRY DONOVAN
+[GA_7] { reVC update }
+Arma la bomba con il ~h~~k~~VEHICLE_FIREWEAPON~~w~: esploderà non appena qualcuno cercherà di avviarla.
-[CRED221]
-PRODUTTORE PER ROCKSTAR GAMES
+[GA_6B] { reVC update }
+Parcheggiala, attivala premendo il ~h~~k~~VEHICLE_FIREWEAPON~~w~ e DATTELA A GAMBE!
-[CRED222]
-DAN HOUSER
+[GA_7B] { reVC update }
+Arma la bomba con il ~h~~k~~VEHICLE_FIREWEAPON~~w~: esploderà non appena qualcuno cercherà di avviarla.
-[CRED223]
-POST-PRODOTTA DA
+[MOB_70A]
+Tommy, sono io, il Colonnello Cortez. Ascolta senor, credo tu sia una persona capace di risolvere i problemi.
-[CRED224]
-CRAIG CONNER
+[MOB_70B]
+Mi troverai sulla mia barca.
-[CRED225]
-ALLAN WALKER
+[PICK1]
+Giubbotto antiproiettile consegnato all'hotel Ocean View!
-[CRED226]
-LAZLOW
+[PICK2]
+.357 consegnato al nascondiglio!
-[CRED227]
-DJ BANTER E IMAGING SCRITTE DA
+[PICK3]
+Motosega consegnata al nascondiglio!
-[CRED228]
-DAN HOUSER
+[PICK4]
+Lanciafiamme consegnato al nascondiglio!
-[CRED229]
-LAZLOW
+[PICK5]
+.308 Fucile di precisione consegnato al nascondiglio!
-[CRED230]
-RINGRAZIAMENTI SPECIALI A
+[PICK6]
+Mitragliatore consegnato al nascondiglio!
-[CRED231]
-ADAM TEDMAN
+[PICK7]
+Lanciamissili consegnato al nascondiglio!
-[CRED232]
-ALEX MASON
+[PICK8]
+Sea Sparrow adesso disponibile alla villa!
-[CRED233]
-JUDY HENDERSON CASTING
+[PICK9]
+Carro armato adesso disponibile alle caserme!
-[CRED234]
-HAMISH BROWN
+[PICK10]
+Hunter adesso disponibile alle caserme!
-[CRED235]
-CHRISSY HOBAN
+[HELP41]
+o puoi speronarli con il tuo mezzo
-[CRED236]
-INNES RICARD
+[ICC1_6]
+~g~Utilizza il Mr. Whopee per distribuire i prodotti Cherry Poppers per Vice City.
-[CRED237]
-LILION BROZSKA
+[ICC1_12]
+PROPRIETÀ ACQUISTATA!
-[CRED238]
-BOB HILLARY
+[CLOTH1]
+Abiti eleganti consegnati a Rafaels in Ocean Beach.
-[CRED239]
-EMILY ANDERSON
+[CLOTH2]
+Abiti da strada consegnati al nascondiglio.
-[CRED240]
-RICHIE HENDERSON
+[CLOTH3]
+Tuta consegnata a Tooled Up nel Mall North Point.
-[CRED241]
-CHRSTIAN CANTAMESSA
+[CLOTH4]
+Abiti sportivi consegnati al club di Golf in Leafs Links.
-[CRED242]
-JERONIMO BARRERA
+[CLOTH5]
+Abiti havana consegnati a Little Havana Streetwear in Little Havana.
-[CRED243]
-ALEXANDER ILLES
+[CLOTH6]
+Abiti da poliziotto consegnati alla stazione di polizia in Washington Beach.
-[CRED244]
-BARANE CHAN
+[CLOTH7]
+Abiti casual consegnati a Gash nel Mall North Point.
-[CRED245]
-DUNCAN SHIELDS
+[CLOTH8]
+Abiti Mr. Vercetti consegnati a Collar & Cuffs in Ocean Beach.
-[CRED246]
-BARANE CHAN
+[CLOTH9]
+Abiti da corsa consegnati a Jocksport in Downtown.
-[CRED247]
-DEREK PAYNE
+[CLOTH10]
+Abiti da rapina consegnati al club Malibu in Vice Point.
-[CRED248]
-KEVIN WONG
+[RBM1_9]
+~g~Recupera della Love Juice dallo spacciatore per i Love Fist!
-[CRED249]
-ROSS ELLIOTT
+[MOB_62A]
+Tommy, sono Ricardo Diaz. Ti volevo ringraziare per l'aiuto ai miei uomini.
-[CRED250]
-ROSS BEAZLEY
+[MOB_62B]
+Ho chiesto a quel coglione di Cortez e mi ha detto che il vero affare sei tu. Amico, vienimi a trovare.
-[CRED251]
-ALEX BAZLINTON
+[MOB_62C]
+Ho bisogno di un tipo come te. Sono circondato da coglioni,
-[CRED252]
-DAVE WATSON
+[MOB_62D]
+coglioni dappertutto, davvero. Ti farò diventare ricco.
-[CRED253]
-MALCOLM SMITH
+[GOAWAY2]
+~g~Ritorna quando avrai completato le missioni dei motociclisti.
-[CRED255]
-ANDREW SEMPLE
+[COL2_9]
+Idiota di un americano! Ti sei fatto seguire!
-[CRED256]
-ARTIST
+[LOADCOL]
+Caricamento...
-[CRED257]
-STUART PETRI
+[STFT_17]
+Tempo migliore in 'Parco divertimenti PCJ'
-[CRED258]
-JERONIMO BARRERA
+[STFT_18]
+Tempo migliore in 'Prova del fango'
-[CRED259]
-CARLY SLATER
+[STFT_19]
+Tempo migliore in 'Tracciato di prova'
-[CRED260]
-GREG LAU
+[NEW_REC]
+Nuovo record!!! ~1~ minuti e ~1~ secondi.
-[CRED261]
-STEVE KNEZEVICH
+[BMX_HOW]
+~g~Fai due giri sul tracciato sterrato, ~y~passando attraverso~g~ i ~y~PUNTI DI CONTROLLO~g~!
-[CRED262]
-DEVIN WINTERBOTTOM
+[BMXREW1]
+~g~Ogni volta che batti il tuo record precedente per i due giri,
-[CRED263]
-JAMEEL VEGA
+[BMXREW2]
+~g~otterrai una ~y~RICOMPENSA~g~ più cospicua!
-[CRED264]
-LEE CUMMINGS
+[BMXRAIN]
+~g~È come se piovesse...
-[CRED265]
-DEVIN BENNET
+[ITBEG]
+All'inizio...
-[CRED266]
-ELIZABETH SATTERWHITE
+[NBMNBUY]
+El Swanko Casa acquistata: ~1~$
-[CRED267]
-AARON RIGBY
+[LNKVBUY]
+Appartamento Links View acquistato: ~1~$
-[CRED268]
-STEVE K.
+[HYCOBUY]
+Condominio Hyman acquistato: ~1~$
-[CRED269]
-GREG LAU
+[BUYGARS]
+~g~Puoi parcheggiare altri veicoli in questi garage.
-[CRED270]
-MIKE HONG
+[OCHEBUY]
+Appartamento Ocean Heights acquistato: ~1~$
-[CINCAM]
-Camera mobile
+[WASHBUY]
+1102 Washington Street acquistata: ~1~$
-[KM1_13]
-Entra in auto dentro il garage!
+[VCPTBUY]
+3321 Vice Point acquistata: ~1~$
-[KM3_14]
-~r~Sei stato scoperto, l'affare è saltato!
+[SKUMBUY]
+Skumole Shack acquistato: ~1~$
-[EBAL_H]
-Aspetta qui mentre entro a parlare con Luigi.
+[HELP6_C]
+Premi il ~h~~k~~VEHICLE_HANDBRAKE~~w~ per tirare il freno a mano.
-[EBAL_M]
-Ricorda, niente casini con le mie ragazze!
+[HELP2_A]
+Premi il ~h~~k~~PED_SPRINT~~w~ mentre corri per effettuare uno ~h~scatto~w~.
-[LM2_F]
-Poi prendi la sua macchina, riverniciala.
+[HELP4_A]
+Premi il ~h~~k~~VEHICLE_ACCELERATE~~w~ per ~h~accelerare~w~.
-[LM2_D]
-tieni, prendi.
+[HELP5_A]
+Premi il ~h~~k~~VEHICLE_BRAKE~~w~ per frenare o, se il veicolo è fermo, per inserire la retromarcia.
-[LM1_9]
-Ciao, sono Misty.
+[HELP8_A]
+Premi il ~h~~k~~PED_SNIPER_ZOOM_IN~~w~ per zoomare col fucile e il ~x~tasto /~w~ per allargare il campo.
-[LM4_A]
-I papponi dei Diablo hanno messo a battere le loro mignotte nella mia zona.
+[PBOAT_1] { reVC update }
+Premi il ~h~~k~~VEHICLE_FIREWEAPON~~w~ per sparare con i cannoni della barca.
-[FM2_B]
-C'è di mezzo una spia.
+[SEG3_4] { reVC update }
+~g~Puoi raccogliere una bomba avvicinando il Raider telecomandato. Per posizionare la bomba, premi il ~h~~k~~VEHICLE_FIREWEAPON~.
-[FM2_C]
-Non è ne un pusher ne un pappone, quindi dev'essere una spia.
+[RCR1_3] { reVC update }
+~g~Se desideri interrompere la missione, premi il ~h~~k~~VEHICLE_FIREWEAPON~~g~ per far esplodere la macchina.
-[FM3_CC]
-~w~Fratello, torna quando avrai i soldi.
+[HELP32] { reVC update }
+Poi spara con il ~h~~k~~VEHICLE_FIREWEAPON~~w~.
-[LOVE5_5]
-~r~Non sei riuscito a proteggere il camion!
+[HELP33] { reVC update }
+Poi spara con il ~h~~k~~VEHICLE_FIREWEAPON~~w~.
-[RM6_6]
-~r~Ray è morto!
+[TTUTOR]
+Premi il ~h~~k~~TOGGLE_SUBMISSIONS~~w~ per attivare o disattivare le missioni Taxi.
-[RM6_7]
-~r~Ray ha perso il volo.
+[TTUTOR2]
+Premi il ~h~~k~~TOGGLE_SUBMISSIONS~~w~ per attivare o disattivare le missioni Taxi.
-[RM6_8]
-~g~Ti sei dimenticato Ray, torna a prenderlo.
+[FTUTOR]
+Premi il ~h~~k~~TOGGLE_SUBMISSIONS~~w~ per attivare o disattivare le missioni Camion dei pompieri.
-[FM1_10]
-~g~Ti sei dimenticato Maria, torna a prenderla.
+[FTUTOR2]
+Premi il ~h~~k~~TOGGLE_SUBMISSIONS~~w~ per attivare o disattivare le missioni Camion dei pompieri.
-[LOVE4_9]
-~r~L'aereo è stato distrutto!
+[CTUTOR]
+Premi il ~h~~k~~TOGGLE_SUBMISSIONS~~w~ per attivare o disattivare le missioni Vigilante.
-[LOV4_10]
-~r~Il solo indizio che indicasse dov'è finito il pacco è stato distrutto!
+[CTUTOR2]
+Premi il ~h~~k~~TOGGLE_SUBMISSIONS~~w~ per attivare o disattivare le missioni Vigilante.
-[KM2_D]
-Non occorre dire che dobbiamo donargli le auto, per ripagare il debito che gli è dovuto.
+[HELP8_B]
+Premi il ~h~~k~~PED_SNIPER_ZOOM_IN~~w~ per ~h~zoomare~w~ col fucile e il ~h~~k~~PED_SNIPER_ZOOM_OUT~~w~ per ~h~allargare~w~ il campo.
-[KM4_B]
-Le imprese che godono della nostra protezione oggi salderanno i conti.
+[ATUTOR3]
+Premi il ~h~~k~~TOGGLE_SUBMISSIONS~~w~ per attivare o disattivare le missioni Infermiere.
-[KM2_E]
-Devi procurarti le auto nella lista e consegnarle nel garage dietro il parcheggio a Newport.
+[GUN_H1]
+~w~Premi il ~h~~k~~PED_SPRINT~~w~ per comprare. ~w~Premi il ~h~~k~~VEHICLE_ENTER_EXIT~~w~ per uscire.
-[FM3_8I]
-~w~Scegli una postazione vantaggiosa, poi io entrerò dopo che hai sparato il primo colpo.
+[PU_CF3] { reVC update }
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per sostituire l'arma attuale con quella presente in questo slot.
-[LOVE1_B]
-L'esperienza mi ha insegnato che un uomo come te sa essere molto leale se ben pagato,
+[PU_CF4] { reVC update }
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per sostituire l'arma attuale con quella presente in questo slot.
-[LOVE1_H]
-ma gruppi di uomini diventano avidi.
+[HELP9_B]
+Premi il ~h~~k~~PED_FIREWEAPON~~w~ per sparare con il fucile di precisione.
-[LOVE1_C]
-Un personaggio chiave, un vecchietto orientale che conosco,
+[HELP37]
+Se non vuoi entrare in un veicolo mentre stai assalendo un guidatore, premi il ~h~~k~~PED_SPRINT~~w~.
-[LOVE1_I]
-è ostaggio di alcuni sud-americani in Aspatria.
+[HELP6_A]
+Premi il ~h~~k~~VEHICLE_HANDBRAKE~~w~ per tirare il freno a mano.
-[MEA4_D]
-Ho preso accordi per vederlo...
+[HELP6_D]
+Premi il ~h~~k~~VEHICLE_HANDBRAKE~~w~ per tirare il freno a mano.
-[MEA4_B4]
-Ti manda Marty, eh? OK, mostrerò a quello schifoso il significato della parola affari.
+[HELP26]
+Premi il ~h~~k~~VEHICLE_ENTER_EXIT~~w~ per entrare o uscire da un veicolo.
-[MEA4_B5]
-Carl, ciao! Mi, uh, mi serve più tempo per pagarti.
+[HELP27]
+Premi il ~h~~k~~VEHICLE_TURRETUP~~w~ o ~h~~k~~VEHICLE_TURRETDOWN~~w~ per spostare il peso sulla moto.
-[MEA1_B4]
-Ah, ti manda il signor Chonk, vero? Andiamo a fargli un visita.
+[HELP28]
+Premi il ~h~~k~~VEHICLE_TURRETUP~~w~ o ~h~~k~~VEHICLE_TURRETDOWN~~w~ per spostare il peso sulla moto.
-[HM5_6]
-Andiamo a spaccare qualche cranio...
+[HELP35]
+Premi il ~h~~k~~GO_LEFT~~w~ o la ~h~~k~~GO_RIGHT~~w~ per sterzare.
-[LOVE1_5]
-~g~Non perdere altro tempo, procurati un'auto dei Colombiani e salva il socio di Love.
+[HELP36]
+Premi il ~h~~k~~GO_LEFT~~w~ o la ~h~~k~~GO_RIGHT~~w~ per sterzare.
-[AS1_D]
-~w~Agisci da esca e fatti inseguire dai plotoni d'esecuzione fino a Pike Creek
+[HELP42]
+Segui il ~q~segnalino rosa~w~ per trovare l'hotel.
-[AS1_E]
-~w~dove i miei uomini li aspetteranno.
+[HELP19]
+Cammina sul ~q~segnalino rosa~w~ per continuare.
-[AS2_C]
-~w~Il Cartello ha un negozio di copertura, la compagnia Kappa Coffee House.
+[HELP1]
+Fermati al centro del ~q~segnalino rosa~w~.
-[AS2_E]
-~w~Non abbiamo scelta, dobbiamo mettere questi spacciatori ambulanti fuori combattimento.
+[HELP12]
+Cammina nel centro del ~q~segnalino rosa~w~ per attivare una missione.
-[AS2_F]
-~w~Riducili in poltiglia!!
+[SEG3_6]
+~g~Per colpire con successo un bersaglio, devi sganciare la bomba nell'area con un ~q~segnalino rosa~g~. Puoi posizionare le bombe in un ordine qualsiasi.
-[AS2_A1]
-~w~Miguel ha di certo un po' di quella famosa prestanza latina.
+[S_PROMP]
+Quando non sei in missione, puoi salvare la partita raccogliendo il bonus ~h~audiocassetta~w~.
-[AS2_A2]
-~w~Io non ce la faccio più.
+[HELP16]
+Passa attraverso la porta principale dell'hotel ~h~Ocean View~w~ per entrare nell'edificio.
-[SIREN_3]
-Per attivare la sirena di questo veicolo premi il ~h~tasto ~k~~VEHICLE_HORN~~w~.
+[HELP43]
+~g~Raggiungi l'hotel ~h~Ocean View~g~ in Ocean Drive.
-[SIREN_4]
-Per attivare la sirena di questo veicolo premi il ~h~tasto ~k~~VEHICLE_HORN~~w~.
+[HELI_F1]
+~r~Gara a tappe con l'elicottero annullata!
-[AS3_C]
-~w~Eeeeyooo! Cos'è quella roba gialla e collosa?
+[AMMUHLP]
+Se hai bisogno di armi, fai un salto ad ~h~Ammu-Nation~w~. Segui il ~h~segnale a forma di pistola~w~ sul radar.
-[AS3_C1]
-~w~Oh, ciao pupa.
+[HELI_1]
+Tappa elicottero Downtown
-[AS3_F]
-~w~Ha un talento naturale questa ragazza.
+[HELI_2]
+Tappa elicottero Ocean Beach
-[AS3_F1]
-~w~È riuscita a strappare questa perla al nostro ospite.
+[HELI_3]
+Tappa elicottero Vice Point
-[AS3_G]
-~w~C'è un aereo in arrivo all'aeroporto internazionale Francis in 2 ore.
+[HELI_4]
+Tappa elicottero Little Haiti
-[AS3_G1]
-~w~È pieno del veleno di Catalina.
+[FST_MFR]
+Stazione radio preferita
-[AS3_H]
-~w~Puoi evitare la sicurezza dell'aeroporto andando in barca vicino alle boe di segnalazione della pista di atterraggio
+[FST_LFR]
+Stazione radio meno amata
-[AS3_H1]
-e abbattendo l'aereo quando si avvicina.
+[FEI_HOL]
+Trattieni
-[AS3_I]
-~w~Raccogli il carico dalle macerie!
+[FEI_ZOO]
+Zoom
-[AS3_J]
-~w~Oh, adesso fa attenzione, OK baby?
+[FEI_BTR]
+> < -
-[AS3_K]
-~w~Adesso prova l'olio di chili...
+[FEI_NA]
+N\D
-[RM2_F1]
-Quei Colombiani dovrebbero essere qui a momenti!
+[MESA]
+Mesa Grande
-[RM2_K]
-Maledizione, sono arrivati!!! CARICA LE ARMI!!!
+[STRP_NO]
+Non puoi ancora comprare il club a luci rosse, prova più tardi.
-[LOVE2_7]
-~g~Adesso abbandona l'auto!
+[CHSE]
+INSEGUI
-[LOVE2_8]
-~g~Ora allontanati da Newport!
+[NBMN_L]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare El Swanko Casa per ~1~$
-[AM1_F]
-Salvatore Leone lascerà Luigi's all'incirca alle ~1~:~1~.
+[NBMN_T]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare El Swanko Casa per ~1~$
-[LOVE5_C]
-Voglio che tu lo segua che ti accerti che lui e il mio pacco giungano a Pine Creex illesi.
+[NBMN_C]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare El Swanko Casa per ~1~$
-[FESZ_SR]
-Salvataggio fallito! Controlla la memory card (PS2) nell'ingresso MEMORY CARD 1 e riprova.
+[LNKV_L]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare l'appartamento Links View per ~1~$
-[FESZ_FO]
-Vuoi formattare la memory card (PS2) nell'ingresso MEMORY CARD 1?
+[LNKV_T]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare l'appartamento Links View per ~1~$
-[FELZ_FO]
-La memory card (PS2) nell'ingresso MEMORY CARD 1 non è formattata.
+[LNKV_C]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare l'appartamento Links View per ~1~$
-[FES_NOC]
-Nessuna memory card (PS2) nell'ingresso MEMORY CARD 1.
+[HYCO_L]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare il condominio Hyman per ~1~$
-[FES_LOE]
-Caricamento fallito! Controlla la memory card (PS2) nell'ingresso MEMORY CARD 1 e riprova.
+[HYCO_T]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare il condominio Hyman per ~1~$
-[FES_DEE]
-Eliminazione fallita! Controlla la memory card (PS2) nell'ingresso MEMORY CARD 1 e riprova.
+[HYCO_C]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare il condominio Hyman per ~1~$
-[FORSUC]
-Formattazione della memory card (PS2) nell'ingresso MEMORY CARD 1 completata.
+[OCHE_L]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare l'appartamento Ocean Heights per ~1~$
-[ERFOUN]
-Formattazione della memory card (PS2) nell'ingresso MEMORY CARD 1 fallita.
+[OCHE_T]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare l'appartamento Ocean Heights per ~1~$
-[ERMCNP]
-Nessuna memory card (PS2) nell'ingresso MEMORY CARD 1.
+[OCHE_C]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare l'appartamento Ocean Heights per ~1~$
-[SVMEM1]
-Salva sulla memory card (PS2) nell'ingresso MEMORY CARD 1.
+[WASH_L]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare 1102 Washington Street per ~1~$
-[FORSLO]
-Formatta la memory card (PS2) nell'ingresso MEMORY CARD 1.
+[WASH_T]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare 1102 Washington Street per ~1~$
-[SLONFM]
-Errore di formattazione della memory card (PS2) nell'ingresso MEMORY CARD 1.
+[WASH_C]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare 1102 Washington Street per ~1~$
-[SLONDR]
-Spazio insufficiente. Inserire una memory card (PS2) con almeno 500KB di spazio libero nell'ingresso MEMORY CARD 1.
+[VCPT_L]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare 3321 Vice Point per ~1~$
-[SLNSP]
-Spazio insufficiente. Inserire una memory card (PS2) con almeno 200KB di spazio libero nell'ingresso MEMORY CARD 1.
+[VCPT_T]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare 3321 Vice Point per ~1~$
-[FEFD_WR]
-Formattazione della memory card (PS2) nell'ingresso MEMORY CARD 1. Non rimuovere la memory card (PS2), riavviare o spegnere la console.
+[VCPT_C]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare 3321 Vice Point per ~1~$
-[FES_ISF]
-NON PRESENTE
+[SKUM_L]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare lo Skumole Shack per ~1~$
-[FES_SAG]
-PRESENTE
+[SKUM_T]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare lo Skumole Shack per ~1~$
-[SLONNO]
-Nessuna memory card (PS2) nell'ingresso MEMORY CARD 1.
+[SKUM_C]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare lo Skumole Shack per ~1~$
-[SLONNF]
-Memory card (PS2) nell'ingresso MEMORY CARD 1 non formattata.
+[PRNT_L]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare la tipografia per ~1~$
-[FESZ_FM]
-Memory card (PS2) nell'ingresso MEMORY CARD 1 non formattata. Vuoi formattare la memory card (PS2) nell'ingresso MEMORY CARD 1?
+[PRNT_T]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare la tipografia per ~1~$
-[FESZ_FF]
-Formattazione fallita! Controlla la memory card (PS2) nell'ingresso MEMORY CARD 1 e riprova.
+[PRNT_C]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare la tipografia per ~1~$
-[MCDNSP]
-Spazio insufficiente sulla memory card (PS2) nell'ingresso MEMORY CARD 1. Sono necessari almeno 500KB di spazio libero. Si desidera procedere? (SÌ o NO)
+[CAR_L]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare il concessionario per ~1~$
-[MCGNSP]
-Spazio insufficiente sulla memory card (PS2) nell'ingresso MEMORY CARD 1. Sono necessari almeno 200KB di spazio libero. Si desidera procedere? (SÌ o NO)
+[CAR_T]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare il concessionario per ~1~$
-[FESZ_WR]
-Salvataggio dati. Non rimuovere la memory card (PS2) dall'ingresso MEMORY CARD 1, riavviare o spegnere la console.
+[CAR_C]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare il concessionario per ~1~$
-[FESZ_OW]
-Sovrascrittura dati. Non rimuovere la memory card (PS2) dall'ingresso MEMORY CARD 1, riavviare o spegnere la console.
+[PORN_L]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare lo studio cinematografico per ~1~$
-[FELD_WR]
-Caricamento dati. Non rimuovere la memory card (PS2) dall'ingresso MEMORY CARD 1, riavviare o spegnere la console.
+[PORN_T]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare lo studio cinematografico per ~1~$
-[FEDL_WR]
-Eliminazione dati. Non rimuovere la memory card (PS2) dall'ingresso MEMORY CARD 1, riavviare o spegnere la console.
+[PORN_C]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare lo studio cinematografico per ~1~$
-[LM2_C]
-Luigi dice di, di darti questo, quindi...
+[ICE_L]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare la fabbrica di gelato per ~1~$
-[LM3_G]
-Joey non è tipo da aspettare: ricorda, questa è la tua grande occasione...
+[ICE_T]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare la fabbrica di gelato per ~1~$
-[LM5_E]
-Portane più che puoi prima che gli sbirri si bevano tutto lo stipendio.
+[ICE_C]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare la fabbrica di gelato per ~1~$
-[JM5_C]
-OK, c'è un'auto con ripieno di cadavere al bar vicino Callahan Point.
+[TAXI_L]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare la compagnia di taxi per ~1~$
-[RM2_B]
-Abbiamo visto i casini in Nicaragua, ai tempi in cui la nazione aveva ancora un senso.
+[TAXI_T]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare la compagnia di taxi per ~1~$
-[RM2_C]
-Qualche bastardo del Cartello l'ha maltrattato ieri e ha detto che ritornerà oggi per la sua merce.
+[TAXI_C]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare la compagnia di taxi per ~1~$
-[RM2_D1]
-Andrei io, ma la mia vecchia sciatica si fa sentire -cough cough- quindi, uhh, in bocca al lupo.
+[BANK_L]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare il Malibu per ~1~$
-[CATINF1]
-~g~Prendi Catalina!
+[BANK_T]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare il Malibu per ~1~$
-[CATINF2]
-~g~Segui l'elicottero per trovare Catalina.
+[BANK_C]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare il Malibu per ~1~$
-[BOATIN1]
-Salta su una barca e premi il ~h~tasto ~k~~VEHICLE_ENTER_EXIT~~w~ per entrare.
+[BOAT_L]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare il cantiere navale per ~1~$
-[BOATIN2]
-Se sei vicino a una barca, puoi premere il ~h~tasto ~k~~VEHICLE_ENTER_EXIT~~w~ per tirarla verso di te.
+[BOAT_T]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare il cantiere navale per ~1~$
-[BOATIN3]
-Salta su una barca e premi il ~h~tasto ~k~~VEHICLE_ENTER_EXIT~~w~ per entrare.
+[BOAT_C]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare il cantiere navale per ~1~$
-[BOATIN4]
-Se sei vicino a una barca, puoi premere il ~h~tasto ~k~~VEHICLE_ENTER_EXIT~~w~ per tirarla verso di te.
+[STRP_L]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare il club Pole Position per ~1~$
-[JM6]
-'LA PARTENZA'
+[STRP_T]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare il club Pole Position per ~1~$
-[FM1]
-L'AUTISTA
+[STRP_C]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare il club Pole Position per ~1~$
-[JM1]
-'L'ULTIMA CENA DI MIKE 'LABBRA''
+[STOCK]
+~r~scorte esaurite
-[FM21]
-'BOMBARDA LA BASE: ATTO PRIMO'
+[HELP14]
+Per trovare l'ufficio dell'avvocato, segui la ~h~L~w~ sul radar.
-[FM3]
-'BOMBARDA LA BASE: ATTO SECONDO'
+[RAMPAGE]
+VIOLENZA!
-[AM1]
-'SAYONARA SALVATORE'
+[RAMP_F]
+VIOLENZA FALLITA!
-[AM2]
-'SOTTO SORVEGLIANZA'
+[RAMP_P]
+VIOLENZA COMPIUTA!
-[KM2]
-'GRAND THEFT AUTO'
+[RAMP_A]
+TUTTE LE VIOLENZE COMPIUTE!
-[AS3]
-'S.A.M.'
+[PAGE_01]
+Uccidi ~1~ membri della gang in 2 minuti!
-[RM2]
-'A CORTO D'ARMI'
+[PAGE_02]
+Distruggi ~1~ veicoli in 2 minuti!
-[LOVE6]
-'TRANELLO'
+[PAGE_03]
+Uccidi sparando in corsa ~1~ membri della gang in 2 minuti!
-[LOVE1]
-'LIBERATORE'
+[PAGE_04]
+Travolgi ~1~ membri della gang in 2 minuti!
-[RC1]
-'DISTRUZIONE DEI DIABLO'
+[PAGE_05]
+Fai saltare la testa a ~1~ membri della gang in 2 minuti!
-[RC2]
-'MASSACRO MAFIOSO'
+[SENTXS]
+Sentinel XS
-[RC3]
-'CALAMITÀ AL CASINÒ'
+[MAP_LEG]
+Legenda
-[RC4]
-'LA FURIA DI RUMPO'
+[VCNMAV]
+VCN Maverick
-[RM2_E1]
-Non posso credere che quei bastardi musi gialli se ne siano andati lasciandomi di nuovo senza copertura!
+[LG_01]
+Posizione giocatore
-[GREN_1]
-Quanto più a lungo tieni premuto il ~h~tasto ~k~~PED_FIREWEAPON~~w~, tanto più lontano lancerai la granata.
+[LG_02]
+Avery Carrington
-[GREN_2]
-Quanto più a lungo tieni premuto il ~h~tasto ~k~~PED_FIREWEAPON~~w~, tanto più lontano lancerai la granata.
+[LG_03]
+Contatto motociclisti
-[GREN_3]
-Quanto più a lungo tieni premuto il ~h~tasto ~k~~PED_FIREWEAPON~~w~, tanto più lontano lancerai la granata.
+[LG_04]
+Colonnello Cortez
-[LOVE4_G]
-Le mie proprietà ti aspettano all'interno dell'aereo nell'hangar doganale.
+[LG_05]
+Ricardo Diaz
-[KABOOM]
-KABOOOM!
+[LG_06]
+Kent Paul
-[SPLAT]
-SPIACCICATO!
+[LG_07]
+Avvocato
-[PANCAK]
-SCHIACCIATO!
+[LG_08]
+Phil Cassidy
-[SOAKED]
-ANNEGATO!
+[LG_09]
+Cantiere navale
-[HEAD]
-Head Radio
+[LG_10]
+Club Malibu
-[DBL_CLF]
-Double Clef FM
+[LG_11]
+Cubani
-[FLASHB]
-Flashback FM
+[LG_12]
+Studio cinematografico
-[RISE]
-Rise FM
+[LG_13]
+AmmuNation
-[LIPS]
-Lips 106
+[LG_14]
+Haitiani
-[CHAT]
-Chatterbox FM
+[LG_15]
+Ferramenta
-[K_JAH]
-K-Jah Radio
+[LG_16]
+Nascondiglio
-[GAM_FM]
-Game Radio FM
+[LG_17]
+Fabbrica di gelato
-[MSX_FM]
-MSX FM
+[LG_18]
+Taxi Kaufman
-[TUBE1]
-Quando aprirà la metropolitana potrai prendere un treno verso Staunton Island.
+[LG_19]
+Love Fist
-[TUBE2]
-Quando aprirà Shoreside Vale potrai uscire dallo Shoreside terminal verso l'aeroporto internazionale Francis.
+[LG_20]
+Tipografia
-[TUBE_2]
-Per salire sulla metropolitana, premi il ~h~tasto 'entra nel veicolo'~w~.
+[LG_21]
+Proprietà
-[LEGAL]
-~g~Elimina la minaccia criminale!
+[LG_22]
+Pay 'n' Spray
-[GA_2]
-Motore nuovo e carrozzeria riverniciata. Gli sbirri non ti riconosceranno!
+[LG_23]
+Negozio di vestiario
-[LM1_8A]
-Per guadagnare qualche soldo extra, perché non 'prendere in prestito' un taxi...
+[LG_24]
+Dimora di Tommy
-[TAXIH1]
-Fermati vicino a un pedone evidenziato per farlo salire a bordo e portarlo a destinazione prima che scada il tempo.
+[LG_25]
+Telefono
-[LM5_7]
-~g~Se ci sono meno di quattro ragazze alla ~p~festa degli sbirri~g~, Luigi sarà nero!
+[LG_26]
+Stazione radio Wildstyle
-[KM2_3]
-~g~Ricorda, le ~r~macchine~g~ devono essere in condizioni eccellenti per essere accolte nel ~p~garage~g~.
+[LG_27]
+Stazione radio Flash FM
-[KM5_2]
-~g~Uno Yardie è in giro per strada.
+[LG_28]
+Stazione radio KChat
-[BETRA_A]
-Scusa baby.
+[LG_29]
+Stazione radio Fever 105
-[BETRA_B]
-Sono una ragazza ambiziosa e tu,
+[LG_30]
+Stazione radio VROck
-[BETRA_C]
-sei una mezza calzetta.
+[LG_31]
+Stazione radio VCPR
-[JAILB_C]
-Nessun dettaglio è stato fornito riguardo i prigionieri che venivano trasferiti dalla scorta,
+[LG_32]
+Stazione radio Espantoso
-[JAILB_E]
-La scorta aveva lasciato la centrale di polizia questa mattina presto...
+[LG_33]
+Stazione radio Emotion 98.3
-[JAILB_F]
-per un trasferimento ordinario verso il penitenziario di Liberty.
+[LG_34]
+Stazione radio Wave 103
-[JAILB_G]
-L'attacco è avvenuto sul ponte Callahan,
+[LG_36]
+Sun Yard
-[JAILB_I]
-Alcuni dei detenuti sembrerebbero essere deceduti a seguito dell'esplosione...
+[LG_37]
+Club a luci rosse
-[JAILB_P]
-questo disastro lascia Portland isolata dal resto della città.
+[MAP_YAH]
+TU SEI QUI
-[JAILB_Q]
-Forza!
+[TAXSHRT]
+~g~Puoi utilizzare questo taxi Kaufman per arrivare a destinazione invece di guidare. Ti costerà 9$.
-[JAILB_R]
-Signor stronzo!
+[FE_MLG]
+LEGENDA MAPPA
-[JAILB_S]
-Non è un problema ucciderti.
+[FED_RDR]
+RADAR
-[JAILB_T]
-Te ne pentirai.
+[FED_HUD]
+INTERFACCIA
-[JAILB_U]
-Va bene, va bene. Sparisci.
+[FED_RDL]
+GRANDE
-[HELP15]
-Quando sei a piedi, premi il ~h~tasto ~k~~PED_LOOKBEHIND~~w~ per ~h~guardare indietro~w~.
+[FED_RDB]
+SOLO SEGNALI
-[FEC_LB3]
-Guarda indietro
+[FED_HUF]
+DISSOLVENZA
-[FEC_R3]
-(tasto R3)
+[FEST_HV]
+Massimo livello missione Vigilante
-[FES_AFO]
-Questa memory card (PS2) è già formattata.
+[BRIBE1]
+Hai appena raccolto una bustarella della polizia: il tuo livello di sospetto è sceso di una stella.
-[FEA_UP]
-;
+[CLOHELP]
+Abiti puliti!
-[FEA_DO]
-=
+[SUNSHIN]
+Sunshine Autos
-[FEA_LE]
-<
+[CHERRYP]
+Gelateria Cherry Popper
-[FEA_RI]
->
+[KAUFCAB]
+Taxi Kaufman
-[FEDSAS3]
-- CAMBIA SELEZIONE
+[BOATYAR]
+Cantiere navale
-[FEDSAS4]
-;=<> - CAMBIA SELEZIONE
+[WANT_L]
+Il tuo livello di sospetto è sospeso: se commetterai un crimine mentre le stelle lampeggiano, il tuo livello di sospetto verrà ripristinato.
-[SPRAY_4] { re3 change }
-Usa il ~h~tasto ~k~~VEHICLE_FIREWEAPON~~w~ per sparare col cannone ad acqua.
+[HOTRNG]
+HOTRING
-[SPRAY_1] { re3 change }
-Usa il ~h~tasto ~k~~VEHICLE_FIREWEAPON~~w~ per sparare col cannone ad acqua.
+[BLODRNG]
+BLOODRING
-[LITTLE]
-LITTLE T
+[DIRTRNG]
+DIRTRING
-[NICK]
-NICK LOVE
+[FEC_ABR]
+Accelera, frena o inverti marcia
-[AM1_10]
-Salvatore uscirà da Luigi's attorno alle 0~1~:~1~.
+[FEI_BTU]
+; = -
-[JAILB_V]
-La città di Liberty è sotto shock.
+[FEI_SCR]
+Scorri
-[JAILB_A]
-Mentre la polizia e i servizi di emergenza affrontano le conseguenze...
+[LG_35]
+Destinazione
-[JAILB_B]
-di un devastante attacco alla scorta avvenuto questa mattina.
+[BOAT_AS]
+~g~Il cantiere navale d'ora in poi genererà introiti per un massimo di ~1~$. Ricordati di recuperarli regolarmente.
-[JAILB_W]
-Rivelazioni sulla professionalità dell'attacco hanno sconvolto le forze dell'ordine,
+[BOAT_A2]
+CANTIERE NAVALE COMPLETATO
-[JAILB_K]
-Inoltre, l'identificazione dei detenuti scomparsi è stata ulteriormente ostacolata...
+[BOAT_N]
+Tappa Charlie
-[JAILB_L]
-da un attacco informatico al computer principale della centrale di Polizia.
+[BOAT_P]
+~g~Raccogli i pacchi prima dello scadere del tempo.
-[JAILB_M]
-Il Sindaco O'Donovan ha dichiarato che la polizia considera l'attentato...
+[FEI_R1B]
+Tasto R1 \ R2 -
-[JAILB_N]
-*
+[HELP9_A]
+Premi il tasto ~h~~k~~PED_FIREWEAPON~~w~ per sparare con il fucile di precisione.
-[JAILB_O]
-Considerato il ritardo nella costruzione del sottopassaggio Porter,
+[HELP21]
+Premi il tasto ~h~~k~~VEHICLE_ENTER_EXIT~~w~ per entrare o uscire da un veicolo.
-[JAILB_X]
-In un'affermazione resa nota ieri,
+[CREAM]
+Distribuzione
-[FEDS_SE]
-Tasto / - SELEZIONA
+[UMBERTO]
+Cafe Robina
-[FEDS_SB]
-Tasto / - SELEZIONA Tasto " - INDIETRO
+[PU_CF1]
+Premi il tasto ~h~~k~~PED_ANSWER_PHONE~~w~ per raccogliere quest'arma e sostituirla con qualsiasi altra dello stesso tipo in tuo possesso.
-[TM4_A]
-~w~Oh, sei te. TONI non è qua.
+[FED_RDM]
+MAPPA E INDICATORI
-[TM4_A2]
-~w~Ma ha lasciato una delle sue dolci lettere per te.
+[FEC_ILU]
+Sguardo invertito in prima persona :
-[DIAB2_A]
-Ho iniziato a lavorare nel business dell'intrattenimento solo grazie al voluminoso contenuto dei miei pantaloni di pelle!
+[NITRO]
+Tutti i taxi adesso hanno il super salto! Premi il pulsante del clacson.
-[LM5_9]
-RAGAZZE:
+[RATNG53]
+Inaffidabile
-[PERPIC]
-Pacchetti speciali recuperati
+[RATNG54]
+Imbarazzante
-[CO_ONE]
-Pacchetto speciale ~1~ su ~1~
+[RATNG55]
+Hacker
-[LOVE3_3]
-~g~L'aeroplano ha fatto cadere ~1~ dei 6 pacchi.
+[RATNG56]
+Baro
-[FARE11]
-~g~Destinazione: ~w~'il cantiere costruzioni'~g~ a Fort Staunton.
+[RATNG57]
+Bugiardo assoluto
-[GA_21]
-Non puoi parcheggiare altri veicoli in questo garage.
+[STHC_04]
+Miglior punteggio con la palla sulla spiaggia
-[CHEAT1]
-Trucco attivato
+[STHC_05]
+Miglior risultato Hotring
-[CHEAT2]
-Trucco armi
+[STFT_13]
+Tempo migliore corsa in elicottero a Downtown
-[CHEAT3]
-Trucco salute
+[STFT_14]
+Tempo migliore corsa in elicottero a Ocean Beach
-[CHEAT4]
-Trucco armatura
+[STFT_15]
+Tempo migliore corsa in elicottero a Vice Point
-[CHEAT5]
-Trucco livello di sospetto
+[STFT_16]
+Tempo migliore corsa in elicottero a Little Haiti
-[CHEAT6]
-Trucco soldi
+[STFT_21]
+Tempo migliore nell'Hotring
-[CHEAT7]
-Trucco tempo atmosferico
+[STFT_22]
+Giro migliore nell'Hotring
-[AS1_H]
-~r~Hai fallito nel far cadere la squadra della morte nella trappola della Yakuza!!!
+[STFT_20]
+Tempo migliore in 'Cone Crazy'
-[FEDS_BA]
-Tasto " - INDIETRO
+[HELP44]
+Fermati nel ~q~ segnalino rosa.
-[RAMP_A]
-TUTTE LE VIOLENZE COMPLETATE!
+[HELP45]
+Premi il ~h~~k~~PED_DUCK~~w~ per abbassarti. In questo modo migliorerai la precisione con le armi da fuoco.
-[USJ_ALL]
-TUTTE LE ACROBAZIE UNICHE COMPLETATE
+[RCR1_5]
+Corsa Bandit radiocomandati
-[FARE23]
-~g~Destinazione: ~w~'Garage importazioni-esportazioni' ~g~nel distretto della diga Cochrane.
+[RCPL1_7]
+Corsa Baron radiocomandati
-[L_TRN_1]
-Puoi prendere il treno sopraelevato a Portland. Premi il ~h~tasto ~k~~VEHICLE_ENTER_EXIT~~w~ per ~h~entrare~w~ o ~h~uscire~w~ da un vagone.
+[RCH1_11]
+Raccolta Raider radiocomandato
-[L_TRN_2]
-Puoi prendere il treno sopraelevato a Portland. Premi il ~h~tasto ~k~~VEHICLE_ENTER_EXIT~~w~ per ~h~entrare~w~ o ~h~uscire~w~ da un vagone.
+[FEA_CTD]
+Attenzione! Questa caratteristica richiede delle periferiche compatibili DTS. Vuoi procedere?
-[S_TRN_1]
-Puoi prendere la metropolitana attraverso Liberty. Premi il ~h~tasto ~k~~VEHICLE_ENTER_EXIT~~w~ per ~h~entrare~w~ o ~h~uscire~w~ da un vagone.
+[FEM_STE]
+USA STEREO
-[S_TRN_2]
-Puoi prendere la metropolitana attraverso Liberty. Premi il ~h~tasto ~k~~VEHICLE_ENTER_EXIT~~w~ per ~h~entrare~w~ o ~h~uscire~w~ da un vagone.
+[FEM_UDY]
+USA DTS
-[AS1_C]
-~w~Ha tre squadre della morte in giro per Liberty il cui unico scopo è beccarti.
+[GREET]
+Saluti da...
-[AS1_G]
-~r~Tutti i membri della Yakuza sono morti!!!
+[LANCE_1]
+Ehi bello, guida con più prudenza!
-[JAN]
-Gen
+[LANCE_2]
+Ehi, guarda cosa hai combinato!
-[FEB]
-Feb
+[LANCE_3]
+Ehi, ma dove stai andando adesso?
-[MAR]
-Mar
+[LANCE_4]
+Cosa diavolo stai facendo?
-[APR]
-Apr
+[LAW4_15]
+Più soldi!
-[MAY]
-Mag
+[MERC_5]
+Bella machina, Mr. Vercetti.
-[JUN]
-Giu
+[MERC_26]
+PIÙ VELOCE, PIÙ VELOCE, PIÙ VELOCE!
-[JUL]
-Lug
+[MERC_27]
+Attento Tommy, mi hanno rifatto il naso il mese scorso.
-[AUG]
-Ago
+[MERC_28]
+Tommy, guida con attenzione.
-[SEP]
-Set
+[MERC_29]
+Tommy, vai più piano!
-[OCT]
-Ott
+[MERC_30]
+Tommy per favore, fai fuori qualcun altro!
-[NOV]
-Nov
+[MERC_31]
+Tommy, baby, non farmi fuori!
-[DEC]
-Dic
+[MERC_32]
+Tommy, sono felice che hai rubato questa macchina!
-[DEFDT]
-Nessun salvataggio valido
+[MERC_40]
+Mi sono davvero divertita.
-[BUGGY]
-MAGGIOLINI RIMASTI:
+[MERC_43]
+Adios, angioletto.
-[BONUS]
-~g~BONUS $~1~$
+[MERC_44]
+Continua a lavorarci, capito?
-[HORN1]
-Premi il ~h~tasto L3~w~ per suonare il ~h~clacson~w~.
+[MERC_45]
+Ciao, bellezza.
-[HORN2]
-Premi il ~h~tasto L1~w~ per suonare il ~h~clacson~w~.
+[COL5_17]
+Oddio, hanno un elicottero!
-[HORN3]
-Premi il ~h~tasto R1~w~ per suonare il ~h~clacson~w~.
+[COL5_18]
+Abbatti l'elicottero!
-[LM3_1A]
-Premi il ~h~tasto ~k~~VEHICLE_HORN~~w~ per suonare il ~h~clacson~w~ e avvertire Misty che sei arrivato.
+[COL5_19]
+Tommy, abbatti quell'elicottero!
-[LM3_1B]
-Premi il ~h~tasto ~k~~VEHICLE_HORN~~w~ per suonare il ~h~clacson~w~ e avvertire Misty che sei arrivato.
+[COL5_20]
+Sta tornando! Distruggi l'elicottero!
-[LM3_1C]
-Premi il ~h~tasto ~k~~VEHICLE_HORN~~w~ per suonare il ~h~clacson~w~ e avvertire Misty che sei arrivato.
+[COL5_21]
+Ma guarda quanto è grosso!
-[RADIO_A]
-Premi il ~h~tasto ~k~~VEHICLE_CHANGE_RADIO_STATION~~w~ per passare in rassegna le ~h~stazioni radio~w~.
+[COL5_22]
+Sta tornando di nuovo!
-[RADIO_B]
-Premi il ~h~tasto ~k~~VEHICLE_CHANGE_RADIO_STATION~~w~ per passare in rassegna le ~h~stazioni radio~w~.
+[FEA_DSM]
+Attenzione! Questo salvataggio utilizza il DTS e richiede periferiche compatibili. Scegli se vuoi procedere utilizzando l'uscita DTS o quella STEREO.
-[RADIO_C]
-Premi il ~h~tasto ~k~~VEHICLE_CHANGE_RADIO_STATION~~w~ per passare in rassegna le ~h~stazioni radio~w~.
+[STFT_23]
+Tempo migliore per la tappa Charlie
-[RADIO_D]
-Premi il ~h~tasto ~k~~VEHICLE_CHANGE_RADIO_STATION~~w~ per passare in rassegna le ~h~stazioni radio~w~.
+[HELP50]
+Premi il tasto ~h~~k~~PED_ANSWER_PHONE~~w~ per posizionare la visuale da dietro.
-[FEC_EXV]
-Entra o esci dal veicolo
+[HELP51]
+Premi il tasto ~h~~k~~PED_ANSWER_PHONE~~w ~ per posizionare la visuale da dietro.
-[TAXI_M]
-'TAXISTA'
+[HELP52]
+Premi il tasto ~h~~k~~PED_ANSWER_PHONE~~w ~ per posizionare la visuale da dietro.
-[COP_M]
-'VIGILANTE'
+[HELP53]
+Premi il tasto ~h~~k~~PED_CYCLE_WEAPON_LEFT~~w~ o il tasto ~h~~k~~PED_CYCLE_WEAPON_RIGHT~~w~ per passare in rassegna le armi disponibili.
-[FIRE_M]
-'POMPIERE'
+[HELP46]
+Sono disponibili otto diversi tipi di arma.
-[AMBUL_M]
-'PARAMEDICO'
+[HELP47]
+Puoi trasportare una sola arma per tipo alla volta: un tipo di pistola, un tipo di fucile a pompa...
-[HJ_IS]
-BONUS ACROBAZIA FOLLE: ~1~$
+[HELP54]
+~w~Costo: ~1~$ ~r~Comprando quest'arma sostituirai quella in uso.
-[HJ_PIS]
-BONUS ACROBAZIA FOLLE PERFETTA: $~1~
+[HELP2A2]
+Premi il tasto ~h~~k~~PED_SPRINT~~w~ mentre corri per effettuare uno ~h~scatto~w~.
-[HJ_DIS]
-BONUS DOPPIA ACROBAZIA FOLLE: $~1~
+[HLPSN_A]
+Il fucile di precisione ti permette di ingrandire l'immagine e colpire i bersagli con precisione dalla distanza.
-[HJ_PDIS]
-BONUS DOPPIA ACROBAZIA FOLLE PERFETTA: $~1~
+[HLPSN_B]
+Tieni premuto il tasto ~h~~k~~PED_LOCK_TARGET~~w~ per ~h~mirare~w~ col fucile di precisione.
-[HJ_TIS]
-BONUS TRIPLA ACROBAZIA FOLLE: $~1~
+[HLPSN_C]
+Tieni premuto il tasto ~h~L1~w~ per ~h~mirare~w~ col fucile di precisione.
-[HJ_PTIS]
-BONUS TRIPLA ACROBAZIA FOLLE PERFETTA: $~1~
+[HLPSN_D]
+Premi il tasto ~h~~k~~PED_SNIPER_ZOOM_IN~~w~ per ~h~zoomare~w~ col fucile e il tasto ~h~~k~~PED_SNIPER_ZOOM_OUT~~w~ per ~h~allargare il campo~w~.
-[HJ_QIS]
-BONUS QUADRUPLA ACROBAZIA FOLLE: $~1~
+[HLPSN_E]
+Premi il tasto ~h~~k~~PED_FIREWEAPON~~w~ per ~h~sparare~w~ col fucile di precisione.
-[HJ_PQIS]
-BONUS QUADRUPLA ACROBAZIA FOLLE PERFETTA: $~1~
+[HLPSN_F]
+Premi il tasto ~h~~k~~PED_FIREWEAPON~~w~ per ~h~sparare~w~ col fucile di precisione.
-[AM1_K]
-Salvatore Leone uscirà da Luigi's fra circa tre ore. (0~1~:~1~)
+[HLPSN_G]
+Premi il tasto ~h~~k~~PED_FIREWEAPON~~w~ per ~h~sparare~w~ col fucile di precisione.
-[IMPEXPP]
-Garage importazioni-esportazioni, porto di Portland. Abbiamo richieste per vari mezzi: consulta la bacheca per le saperne di più.
+[PLANE_H]
+Usa il tasto ~h~~k~~VEHICLE_ACCELERATE~~w~ per accelerare e a sinistra e a destra per curvare.
-[VANHSTP]
-Hai scassinato altre Securicar? Portale al nostro garage al porto di Portland.
+[PLANE_4] { reVC update }
+{Usa il tasto ~h~~k~~VEHICLE_ACCELERATE~~w~ per accelerare e a sinistra e a destra per curvare.}
+Usa la levetta analogica destra per accelerare, premi la levetta analogica sinistra in basso per salire, in alto per scendere e a sinistra e a destra per curvare.
-[EMVHPUP]
-Ottimi prezzi per veicoli di soccorso nuovi o usati. Portali vicino alla gru a nord est del porto di Portland.
+[HELP55]
+Premi il tasto ~h~~k~~PED_FIREWEAPON~~w~ per attaccare lo chef.
-[STANDS]
-CHIOSCHI DISTRUTTI:
+[STPR_8]
+Club Pole Position
-[STASH]
-~g~Nascondi lo SPANK nel ~p~cantiere edile~g~!
+[STPR_9]
+3321 Vice Point
-[MCSTNS]
-Nessuna memory card (PS2) nell'ingresso MEMORY CARD 1. Vuoi procedere comunque? (SÌ o NO)
+[STPR_10]
+Appartamento Links View
-[LOVE3_5]
-~g~L'aeroplano è a tiro.
+[STPR_11]
+El Swanko Casa
-[LOVE3_6]
-~r~La polizia è arrivata ai pacchi per prima!
+[STPR_12]
+1102 Washington Street
-[SIREN_1]
-Per accendere le sirene di questo veicolo, premi il ~h~tasto ~k~~VEHICLE_HORN~~w~.
+[STPR_13]
+Appartamento Ocean Heights
-[SIREN_2]
-Per accendere le sirene di questo veicolo, premi il ~h~tasto ~k~~VEHICLE_HORN~~w~.
+[STPR_14]
+Skumole Shack
-[FM3_8C]
-~w~Avrò bisogno di 100.000$ per coprire le spese,
+[STPR_15]
+Condominio Hyman
-[MCLOAD]
-Caricamento dati. Non rimuovere la memory card (PS2) dall'ingresso MEMORY CARD 1, riavviare o spegnere la console.
+[RCCANX]
+~r~Aereo radiocomandato annullato.
-[FES_GME]
-Errore di lettura della memory card (PS2) nell'ingresso MEMORY CARD 1! Controlla la memory card (PS2) e riprova.
+[CLT_HL2]
+Quando viene raccolto un bonus vestiti, vengono rimosse una o due stelle del livello di sospetto.
-[FESZ_QF]
-Sei sicuro di voler formattare la memory card (PS2) nell'ingresso MEMORY CARD 1?
+[CRED009]
+PROGETTAZIONE MISSIONI
-[FESZ_LS]
-Caricamento riuscito.
+[CRED359]
+LEE JOHNSON
-[RM3_5]
-~g~Hai raccolto ~1~ su 6 prove.
+[CRED360]
+HENDRIK LESSER
-[LOVE3_2]
-~g~Hai tutti i pacchi! Riportali subito a Donald Love.
+[CRED361]
+PASQUALE STACCHIOTTI
-[LOVE4_4]
-~g~Riporta il pacco a Donald Love.
+[CRED362]
+ENRIQUE FERNANDEZ
-[FEDS_AM]
-<>-CAMBIA MENU
+[CRED363]
+PAUL BYERS
-[FEB_SAV]
-Carica
+[CRED364]
+MIKE EMENY
-[FEP_SAV]
-CARICA PARTITA
+[CRED365]
+ROB DUNKIN
+
+[CRED366]
+CHARLIE KINLOCH
+
+[CRED367]
+KEVIN HOBSON
+
+[CRED368]
+JIM CREE
+
+[MOB_66A]
+Tommy, Tommy, Tommy, perché sei tornato qua?
+
+[MOB_66B]
+Te l'avevo detto che non vi volevamo più vedere.
+
+[MOB_67A]
+Tommy, credo che dovresti andartene, capito?
+
+[MOB_67B]
+I ragazzi Haitiani non sono molto felici di te.
+
+[MOB_18A]
+Tommy, sono Paulo, come stai? Bene amico, ascolta: volevo farti una chiamata.
+
+[MOB_18B]
+Ossignore, amico, non crederai mai che razza di strafiga ho appena incontrato.
+
+[MOB_18C]
+Una prostituta forse, passeggiava per Little Havana.
+
+[MOB_18D]
+Ha detto che si chiamava Mercedes o qualcosa del genere.
+
+[MOB_18E]
+Oddio, dovresti proprio vedere questa gnocca.
+
+[MOB_18F]
+Riuscirebbe a succhiare via la mina da una matita. Mi detto che ero il migliore che avesse mai avuto e via dicendo.
+
+[MOB_18G]
+Dovresti farci un giro. Ci vediamo!
+
+[MOB_72A]
+Tommy, sono io, Lance. Tieni la bocca chiusa Tommy, perché non ho tempo da perdere.
+
+[MOB_72B]
+Non mi importa cos'hai da dire. Perché dovrei? Non te ne frega niente di me, non è vero?
+
+[MOB_72C]
+Dovresti fare più attenzione a me. Dovresti darmi la fetta che merito. Lo sai...
+
+[MOB_72D]
+Tommy... senti amico, mi dispiace. È solo che...
+
+[MOB_72E]
+La gente mi ha sempre trattato con accondiscenda, come se fossi un bambino.
+
+[MOB_72F]
+Mio fratello lo farebbe. Per favore, amico, tu non farlo.
+
+[MOB_72G]
+Devo andare.
+
+[MOB_63A]
+Tommy, sono Earnest. Earnest Kelly.
+
+[MOB_63B]
+Come stai?
+
+[MOB_63C]
+Non male. Avrò bisogno di un bastone per camminare, ma dovrei tornare al lavoro ben presto.
+
+[MOB_63D]
+Bene.
+
+[MOB_63E]
+Ho sentito di Lance. Che brutto storno, eh?
+
+[MOB_63F]
+Sì.
+
+[MOB_63G]
+Mai fidarsi di qualcuno che cammina per strada in pigiama. Ecco cosa dico. Sono felice che l'hai fatto fuori. Spero che sia stato doloroso per lui.
+
+[MOB_63H]
+Credo di sì. Non credevo fosse quel genere di persona...
+
+[MOB_63I]
+Tommy, per essere un pazzo violento, sei piuttosto ingenuo. Tornerò presto al lavoro e ti insegnerò un paio di cose sulla vita. Ci sentiamo.
+
+[MOB_63J]
+Fai con calma, Earnest. Abbi cura di te.
+
+[MOB_16A]
+Tommy, sono Paulo, que pasa amigo?
+
+[MOB_16B]
+Che cosa vuoi Paul: non sono interessato a vestiti di marca taroccati.
+
+[MOB_16C]
+Molto divertente, amico, ma lo sai che non tratto merce di seconda classe. Nah, ti ho chiamato per sapere se potevo avere una parte nei tuoi film.
+
+[MOB_16D]
+Quando ero in Inghilterra ho fatto un sacco di cose, sai? Ho attributi più forniti di te, amico.
-[AS2_12A]
-~g~Dopo aver distrutto il primo chiosco, avrai 8 minuti prima che il Cartello informi i propri spacciatori!
+[MOB_16E]
+Paul, grazie per l'offerta, lo terrò presente.
-[AS3_1A]
-~g~Adesso raggiungi la ~b~boa segnalatrice~g~!
+[MOB_16F]
+Davvero, non scordarti di me dopo tutto quello che ho fatto per te.
-[NOCONT]
-Ricollega il controller analogico (DUALSHOCK#) o controller analogico (DUALSHOCK#2) all'ingresso controller 1 per continuare.
+[MOB_16G]
+È proprio ciò che sto cercando di dimenticare...
-[BET_JB]
-TRADITO DALLA SUA AMANTE CATALANA E ABBANDONATO MEZZO MORTO. GIUDICATO COLPEVOLE, INIZIA LA SUA AVVENTURA NEL PENITENZIARIO DELLA CITTÀ DI LIBERTY. HA UN SOLO PENSIERO FISSO NELLA TESTA... LA VENDETTA!
+[MOB_17A]
+Tommy Vercetti: come va, Mr. Pezzo Grosso? Ho saputo le tue novità: un vero giocatore in città, eh...
-[END_A]
-I residenti in Cedar Grove si sono finalmente ripresi
+[MOB_17B]
+Paul, sei ubriaco.
-[END_B]
-dallo spavento per i violenti scontri
+[MOB_17C]
+No, idiota. Non sono ubriaco. Solo un paio di bicchierini e qualche pillola: non dormo da un paio di giorni, sai...
-[END_C]
-avvenuti ieri nell'area.
+[MOB_17D]
+Comunque, niente prediche. Non sono uno stupido. Chi ti ha portato in questa città? Chi? Io, ecco chi.
-[END_D]
-Un abitante della zona, Clive Denver, ha dichiarato alla polizia
+[MOB_17F]
+Davvero?
-[END_E]
-di aver visto un uomo armato che sia allontanava dalla scena del crimine con una donna dai capelli neri.
+[MOB_17G]
+Niente prediche, smettila! Ti ho fatto conoscere la gente giusta, ti ho mostrato che corde tirare. Ho fatto molto per te e questo è il modo con cui mi ringrazi.
-[END_F]
-Oh, lo sai, vedrai che ci divertiremo, perché lo sai, cioè,
+[MOB_17H]
+Mi ignori. Non mi aiuti a entrare dopo tutto ciò che ho fatto per te! Cosa credi che sia? Un idiota?
-[END_G]
-io ti amo, io... io ti amo davvero perché sei un vero uomo
+[MOB_17I]
+Paul, sta' buono. Sono stato occupato, non fare l'idiota.
-[END_H]
-ed è ciò di cui ho bisogno.
+[MOB_17J]
+Non sono un idiota, chiaro? Questo è ciò che hanno detto in riformatorio. Stai forse cercando guai, amico? Beh, stai per trovarli!
-[END_I]
-Comunque, cosa stavo dicendo?
+[MOB_17K]
+Tommy, amico. Per favore. Sei la mia più grande speranza! Per favore, non ridere di me.
-[END_J]
-Oh, lo sai, me lo sono dimenticato. Sai com'è che succede, vero?
+[MOB_17L]
+Paul, cerca di dormire, davvero.
-[END_K]
-Il suono delle esplosioni ha fatto tremare le case mentre la gente correva al riparo.
+[MOB_73A]
+Tommy, sono Steve.
-[END_L]
-Molti cittadini sono rimasti feriti per il panico mentre venivano sparati colpi
+[MOB_73B]
+Ehi Steve.
-[END_M]
-tra le forze terrestri e l'elicottero che sorvolava la diga.
+[MOB_73C]
+Ehi, ciao genio. Sei uno spettacolo! Anch'io sono uno spettacolo! Ci adorano. Stiamo battendo tutti i record, amico.
-[END_N]
-Sì, c'è proprio una bella vista da qui in giardino.
+[MOB_73D]
+Stiamo ottenendo dei grandi riconoscimenti. Finalmente posso comprare una casa al mio vecchio così se ne starà zitto.
-[END_O]
-Quando hanno fatto saltare l'elicottero
+[MOB_73E]
+Eeer, mi sembra perfetto, Steve.
-[END_P]
-è stato meglio dei fuochi d'artificio del 4 luglio.
+[MOB_73F]
+Perfetto? È meraviglioso! Meraviglioso, MERAVIGLIOSO! Non ha mai creduto in me. Non pensava fossi un artista, ma adesso ce l'ho fatta.
-[END_Q]
-Il numero di cadaveri recuperati ha già superato la ventina,
+[MOB_73G]
+Sono il miglior direttore sadomaso di tutti i tempi, amico. Volevo solo dirti che è stato un piacere averti incontrato.
-[END_R]
-ma la polizia continua a trovare nuovi corpi.
+[MOB_73H]
+Grazie Steve.
-[END_S]
-Non sono state smentite le voci secondo cui
+[MOB_73I]
+Ti voglio bene, amico. Non cambiare, capito?
-[END_T]
-i morti appartenessero al Cartello Colombiano,
+[MOB_73J]
+Capito. Ci sentiamo Steve.
-[END_U]
-ciò nonostante, non ci sono indizi sulle ragioni di questa strage.
+[BOLLOX]
+Premi il tasto ~o~R1~w~ per sganciare una bomba. Premi il tasto ~t~"~w~ per annullare.
-[END_V]
-Mi sono rotta un'unghia e i miei capelli sono un disastro. Ma ci puoi credere?
+[BRID_OP]
+Pericolo uragano terminato: tutti i ponti per la terra ferma sono nuovamente aperti.
-[END_W]
-Mi è costato 50 dollari...
+[BRID_CL]
+Pericolo uragano: tutti i ponti per la terra ferma sono chiusi.
-[PAPER1]
-CRIMINALE FERITO DALLA FIDANZATA COMPLICE. LA CORTE GIUDICA IL RAPINATORE COLPEVOLE CON VERDETTO UNANIME.
+[LG_38]
+Bersaglio
+
+[ASSET_C]
+POLE POSITION COMPLETATA!
+
+[ASSET_D]
+~g~ Il Club Pole Position generera' un reddito fino ad un massimo di $~1~ al giorno. Ritira il denaro regolarmente!
+
+[ST_WHEE]
+Impennata più lunga (sec)
+
+[ST_STOP]
+Frenata in punta più lunga (sec)
+
+[ST_2WHE]
+Permanenza su 2 ruote più lunga (sec)
+
+[ST_WHED]
+Distanza piu' lunga in impennata (m)
+
+[ST_STOD]
+Distanza piu' lunga in frenata (m)
+
+[ST_2WHD]
+Distanza piu' lunga su 2 ruote (m)
+
+[OUTFT11]
+Tuta da ginnastica
+
+[OUTFT12]
+Frankie
+
+[RELOAD]
+~g~Hai vinto l'abilita' di ricarica veloce!
+
+[APACHE]
+Hunter consegnato all'eliporto di Ocean Beach
+
+[CRED369]
+JOHN MCCARDLE
+
+[CRED370]
+DAVID MURDOCH
+
+[CRED371]
+CHRIS BROWN
+
+[CRED372]
+PAUL GREEN
+
+[CRED373]
+KYLE MILNE
+
+[CUNTY]
+Nuovi vestiti consegnati alla Proprieta' di Vercetti!
-[PAPER2]
-DIECI ANNI PER L'AMORE!
+[GOODBOY]
+$50 Come Bonus Buon Cittadino!
-[JAILB_J]
-che è seguita all'attacco iniziale.
+[NEWCONT]
+Nuovo ~h~Punto di Contatto~w~ disponibile alla Marina di Ocean Beach!!
-[JAILB_D]
-E nessun gruppo ha rivendicato l'attentato.
+[FIRELVL]
+Missione Camion dei pompieri livello ~1~
+
+[HELP56]
+Premi il tasto ~h~~k~~CAMERA_CHANGE_VIEW_ALL_SITUATIONS~~w~ per cambiare la modalità di visuale.
+
+[HELP57]
+Premi il tasto ~h~~k~~CAMERA_CHANGE_VIEW_ALL_SITUATIONS~~w~ per cambiare la modalità di visuale.
+
+[HELP58]
+Mentre prendi la mira, premi il ~h~~k~~PED_CYCLE_TARGET_LEFT~~w~, ~h~~k~~PED_CYCLE_TARGET_RIGHT~~w~ per cambiare bersaglio.
+
+[HELP59]
+Mentre prendi la mira, premi il ~h~~k~~PED_CYCLE_TARGET_LEFT~~w~, ~h~~k~~PED_CYCLE_TARGET_RIGHT~~w~ per cambiare bersaglio.
+
+[HELP60]
+Se premi il tasto ~h~~k~~PED_SPRINT~~w~ mentre assalti una macchina, non entrerai nel veicolo.
+
+[HELP61]
+Adesso hai colpi infiniti e il doppio dell'energia su tutti i veicoli.
+
+[CRED374]
+KEVIN YUN
+
+[CRED375]
+ERICK COBBS
+
+[CRED376]
+RANDY BLAKE
+
+[CRED377]
+BRANDON LIM
+
+[CRED378]
+BRANDON FENOL
+
+[CRED379]
+MICHAEL MANOLE
+
+[CRED380]
+ALETHEIA SIMONSON
+
+[CRED381]
+JOHN JANSEN
+
+[FEC_LB1]
+Guarda
+
+[FEC_LB2]
+indietro
-[JAILB_H]
-lasciando pochi testimoni e il ponte stesso seriamente danneggiato.
+[FEC_LB3]
+Guarda indietro
-[FEB_CPC]
-Configurazione comandi
+[FEC_R3]
+(tasto R3)
[FEC_PED]
Comandi a piedi
@@ -7106,84 +7191,6 @@ Cambia la modalità di visuale in qualsiasi situazione
[FEC_TSS]
Salva un'immagine di gioco
-[FEN_NET]
-Rete
-
-[FEN_CON]
-Connessione
-
-[FEN_GAM]
-Trova partite
-
-[FEN_TYP]
-Modalità
-
-[FEN_TY0]
-Deathmatch
-
-[FEN_TY1]
-Deathmatch stealth
-
-[FEN_TY2]
-Deathmatch a squadre
-
-[FEN_TY3]
-Deathmatch stealth a squadre
-
-[FEN_TY4]
-Accumula denaro
-
-[FEN_TY5]
-Cattura la bandiera
-
-[FEN_TY6]
-Rat Race
-
-[FEN_TY7]
-Dominazione
-
-[FEN_NAM]
-Nome:
-
-[FEN_GNA]
-Nome partita:
-
-[FEM_MAP]
-Seleziona mappa
-
-[FEN_PLS]
-Impostazioni giocatore
-
-[FEN_PLC]
-Colore giocatore
-
-[FEM_MA0]
-Città di Liberty
-
-[FEM_MA1]
-Luci rosse
-
-[FEM_MA2]
-Chinatown
-
-[FEM_MA3]
-La torre
-
-[FEM_MA4]
-Le fogne
-
-[FEM_MA5]
-Area industriale
-
-[FEM_MA6]
-Porto
-
-[FEM_MA7]
-Staunton
-
-[FEC_EMS]
-Un tasto può essere assegnato a un solo comando!
-
[FEC_DBG]
Menu debug
@@ -7235,41 +7242,209 @@ Usa Guarda a sinistra con Guarda a destra
[FEC_JBO]
JOY ~1~
-[NO_PAUZ]
-Pausa non disponibile in modalità multigiocatore. Premi ancora per uscire.
+[FEC_WAR]
+Attenzione
-[FEM_SL1]
-Blocco 1 libero
+[FEC_OKK]
+OK
-[FEM_SL2]
-Blocco 2 libero
+[FEC_DLF]
+Eliminazione fallita.
-[FEM_SL3]
-Blocco 3 libero
+[FEC_SVU]
+Salvataggio fallito.
-[FEM_SL4]
-Blocco 4 libero
+[FEC_LUN]
+Caricamento fallito. File corrotto: è necessario eliminarlo.
-[FEM_SL5]
-Blocco 5 libero
+[FEC_PAD]
+Gamepad
-[FEM_SL6]
-Blocco 6 libero
+[FEC_JOY]
+Joystick
-[FEM_SL7]
-Blocco 7 libero
+[FES_CSA]
+Seleziona una skin dalla seguente lista:
-[FEM_SL8]
-Blocco 8 libero
+[FET_HRD]
+IMPOSTAZIONI PREDEFINITE RIPRISTINATE
+
+[FET_MST]
+STERZO VIA MOUSE
+
+[FEC_STR]
+NUM ASTERISCO
+
+[FET_MIG]
+SINISTRA, DESTRA, ROTELLA PER MODIFICARE
+
+[FET_CIG]
+INDIETRO PER AZZERARE - PULSANTE SX, INVIO PER MODIFICARE
+
+[FET_DSN]
+Skin predefinita.bmp
+
+[FET_RSO]
+RIPRISTINATE IMPOSTAZIONI ORIGINALI
+
+[FET_RSC]
+HARDWARE NON DISPONIBILE - RIPRISTINATE IMPOSTAZIONI ORIGINALI
+
+[FEA_3DH]
+HARDWARE AUDIO
+
+[FEA_SPK]
+CONFIGURAZIONE ALTOPARLANTI
+
+[FEM_LOD]
+DISTANZA VISUALE
+
+[FEM_VSC]
+SINCRONIA FRAME
+
+[FEM_FRM]
+LIMITATORE FRAME
[FEM_MM]
MENU PRINCIPALE
-[FEM_SNG]
-Nuova partita
+[FED_RES]
+RISOLUZIONE
-[FEM_QTW]
-Esci
+[FET_CTL]
+IMPOSTAZIONI DEI COMANDI
+
+[FET_OPT]
+OPZIONI
+
+[FEC_MSH]
+SENSIBILITÀ MOUSE
+
+[FEC_IVV]
+INVERTI MOUSE VERTICALMENTE
+
+[FET_MTI]
+CONFIGURAZIONE COL MOUSE
+
+[FEC_FNC]
+F~1~
+
+[FEC_IRT]
+INS
+
+[FEC_DLL]
+CANC
+
+[FEC_HME]
+HOME
+
+[FEC_END]
+FINE
+
+[FEC_PGU]
+PAG SU
+
+[FEC_PGD]
+PAG GIÙ
+
+[FEC_UPA]
+SU
+
+[FEC_DWA]
+GIÙ
+
+[FEC_LFA]
+SINISTRA
+
+[FEC_RFA]
+DESTRA
+
+[FEC_NUM]
+NUM
+
+[FEC_NMN]
+NUM~1~
+
+[FEC_FWS]
+NUM /
+
+[FEC_PLS]
+NUM +
+
+[FEC_MIN]
+NUM -
+
+[FEC_DOT]
+NUM .
+
+[FEC_NLK]
+BLOC NUM
+
+[FEC_ETR]
+INVIO
+
+[FEC_SLK]
+BLOC SCORR
+
+[FEC_PSB]
+PAUSA
+
+[FEC_BSP]
+INDIETRO
+
+[FEC_TAB]
+TAB
+
+[FEC_CLK]
+BLOC MAIUSC
+
+[FEC_RTN]
+RET
+
+[FEC_LSF]
+MAIUSC SX
+
+[FEC_RSF]
+MAIUSC DX
+
+[FEC_LCT]
+CTRL SX
+
+[FEC_RCT]
+CTRL DX
+
+[FEC_LAL]
+ALT SX
+
+[FEC_RAL]
+ALT DX
+
+[FEC_LWD]
+WIN SX
+
+[FEC_RWD]
+WIN DX
+
+[FEC_WRC]
+CLIC WIN
+
+[FEC_SPC]
+BARRA
+
+[WIN_TTL]
+Grand Theft Auto VC
+
+[WIN_95]
+Grand Theft Auto VC non è supportato da Windows 95
+
+[WIN_DX]
+Grand Theft Auto VC richiede DirectX versione 8.1 o superiore
+
+[FET_EIG]
+IMPOSSIBILE ASSEGNARE UN COMANDO A QUESTA AZIONE
+
+[FET_DAM]
+MODELLAZIONE ACUSTICA DINAMICA
[FEQ_SRE]
Sei sicuro di voler uscire? Tutti i progressi dall'ultimo salvataggio verranno persi. Vuoi procedere?
@@ -7277,740 +7452,7128 @@ Sei sicuro di voler uscire? Tutti i progressi dall'ultimo salvataggio verranno p
[FEQ_SRW]
Sei sicuro di voler uscire dal gioco?
-[FEG_SRV]
-SERVER
+[FET_QG]
+ESCI DAL GIOCO
-[FEG_MAP]
-MAPPA
+[FEN_STA]
+AVVIA LA PARTITA
+
+[FET_PAU]
+MENU PAUSA
-[FEG_PLY]
-GIOCATORI
+[REPLAY]
+REPLAY
+
+[FEC_ANS]
+Azione
-[FEG_TYP]
-MODALITÀ
+[CVT_MSG]
+Conversione texture per prestazioni ottimali con la tua scheda video
+
+[FEC_SFT]
+MAIUSC
+
+[FEH_VMP]
+VEDI MAPPA
+
+[FES_DEE]
+Eliminazione fallita! Prova nuovamente.
+
+[FES_CMP]
+Salvataggio fallito! Prova nuovamente.
+
+[FESZ_WR]
+Salvataggio partita. Un momento...
-[FEG_PNG]
-PING
+[FELD_WR]
+Caricamento partita. Un momento...
-[FET_FG]
-TROVA PARTITA
+[FEDL_WR]
+Eliminazione salvataggio. Un momento...
-[FET_SP]
-GIOCATORE SINGOLO
+[PCRESRT]
+Avvio nuova partita. Un momento...
-[FET_MP]
-MULTIGIOCATORE
+[FET_STI]
+Configurazione standard
-[FET_HG]
-OSPITA PARTITA
+[FET_CTI]
+Configurazione classica
[FET_PS]
-IMPOSTAZIONI GIOCATORE
+IMPOSTAZIONE SKIN GIOCATORE
-[FET_CON]
-CONNESSIONE
+[FEH_NA]
+OPZIONE NON DISPONIBILE
-[FET_AUD]
-IMPOSTAZIONI AUDIO
+[FEH_MPH]
+MOUSE, FRECCE PER MUOVERSI - PAGSU, PAGGIÙ, ROTELLINA PER LO ZOOM, L - LEGENDA
-[FET_DIS]
-IMPOSTAZIONI VIDEO
+[FEA_MP3]
+RIPRODUTTORE MP3
-[FET_LAN]
-IMPOSTAZIONI LINGUA
+[NO_PCCD]
+Inserisci il CD di GTA Vice City o premi Esc per annullare
-[FET_LG]
-CARICA PARTITA
+[FEH_SSA]
+FRECCE PER MUOVERSI - S PER SALVARE
-[FET_DG]
-ELIMINA PARTITA
+[FES_CMI]
+ULTIMA MISSIONE COMPLETATA
-[FET_NG]
-NUOVA PARTITA
+[FET_STS]
+STATISTICHE SALVATE NEL FILE 'STATS.HTML' + 'STATS.TXT'
-[FET_SG]
-SALVA PARTITA
+[WIN_VDM]
+Memoria video insufficiente per eseguire Grand Theft Auto VC
-[FET_MAP]
-SELEZIONA MAPPA
+[FEC_ERI]
+Errore! Uno o più azioni non sono assegnate a nessun tasto o pulsante. Assicurati che a tutte le azioni corrisponda un comando.
-[FET_GT]
-MODALITÀ DI GIOCO
+[FEC_TFU]
+Torretta + Inclina in su
-[FET_CTL]
-IMPOSTAZIONI DEI COMANDI
+[FEC_TFD]
+Torretta + Inclina in giù
-[FET_OPT]
-OPZIONI
+[FET_RIG]
+SELEZIONA IL NUOVO COMANDO PER QUESTA AZIONE
-[FET_QG]
-ESCI DAL GIOCO
+[FEA_NM3]
+NESSUN FILE MP3 TROVATO
-[FET_STA]
-STATISTICHE
+[FEA_MPB]
+INCREMENTO VOLUME MP3
-[FET_BRE]
-MISSIONI
+[FEA_MUS]
+VOLUME MUSICA
-[FEC_WAR]
-Attenzione
+[FEA_SFX]
+VOLUME EFFETTI
-[FEC_OKK]
-OK
+[CVT_ERR]
+Spazio su disco esaurito; è necessario liberare dello spazio prima di poter procedere. Premi ESC per annullare.
-[FED_CON]
-Conferma eliminazione file
+[FEA_ADP]
+RILEVAMENTO AUTOMATICO
-[FES_SSC]
-Partita salvata con successo
+{=================================== MISSION TABLE AMBULAE ===================================}
-[DEL_FNM]
-File eliminato con successo.
+[ATUTOR2:AMBULAE]
+~g~Conduci i pazienti all'ospedale guidando CON PRUDENZA! Qualsiasi scossone può ucciderli.
-[PCLOAD]
-Caricamento dati in corso
+[A_FULL:AMBULAE]
+~r~Ambulanza piena!
-[PCRESRT]
-Riavvio di Grand Theft Auto III
+[A_FAIL2:AMBULAE]
+~r~La tua scarsa sollecitudine è stata fatale al paziente!
-[FEC_DLF]
-Eliminazione fallita.
+[A_FAIL3:AMBULAE]
+~r~Il paziente è morto!
-[FEC_SVU]
-Salvataggio fallito.
+[A_PASS:AMBULAE]
+Salvato!
-[FEC_LUN]
-Caricamento fallito. File corrotto: è necessario eliminarlo.
+[A_COMP2:AMBULAE]
+Non ti stancherai mai!
-[FEN_PLA]
-Numero di giocatori:
+[A_COMP1:AMBULAE]
+Missioni Infermiere completate: ~1~$
-[FET_NON]
-NESSUNA PARTITA DISPONIBILE
+[A_CANC:AMBULAE]
+~r~Missione Infermiere annullata!
-[FET_SFG]
-RICERCA DI PARTITE...
+[A_COMP3:AMBULAE]
+Missione Infermiere completata! Non ti stancherai mentre corri!
-[FET_SRT]
-CLASSIFICAZIONE PARTITE...
+[ALEVEL:AMBULAE]
+Missione Infermiere livello ~1~
-[FEF_LAN]
-LAN
+[A_FAIL1:AMBULAE]
+Missione Infermiere terminata.
-[FEF_INT]
-INTERNET
+[A_SAVES:AMBULAE]
+PERSONE SALVATE: ~1~
-[FET_REF]
-Aggiorna
+{=================================== MISSION TABLE ASSIN1 ===================================}
-[FET_FIL]
-Filtra
+[ASM1_5:ASSIN1]
+~r~Ha completato le sue consegne!
-[FET_JG]
-Partecipa
+[ASM1_6:ASSIN1]
+Consegne rimanenti:
-[FEC_NTW]
-Talk To Network
+[ASM1_7:ASSIN1]
+~g~Carl Pearson, fattorino di una pizzeria. Uccidilo prima che completi le sue consegne.
-[FEC_ESR]
-Il tasto ESC è riservato
+[ASM1_D:ASSIN1]
+Mr. Teal, il tuo aiuto nello sradicare gli stranieri è stato inestimabile per il nostro lavoro.
-[FEC_GSL]
-Show head bob:
+{=================================== MISSION TABLE ASSIN2 ===================================}
-[FIL_FLT]
-FILTRA ELENCO PARTITE
+[ASM2_1:ASSIN2]
+~g~Mrs. Dawson lascerà presto la gioielleria in Vice Point. Devi ucciderla. Deve sembrare un incidente d'auto.
-[FET_SAN]
-NUOVA PARTITA
+[ASM2_3:ASSIN2]
+~g~Sta per esplodere! Allontanati!
-[FIL_MAP]
-Mappa:
+[ASM2_4:ASSIN2]
+~r~Hai danneggiato la sua auto, ma lei non è sopra! Adesso non ci entrerà di sicuro!
-[FIL_SRV]
-Server:
+[ASM2_5:ASSIN2]
+~r~È riuscita a scappare!
-[FIL_TYP]
-Modalità:
+[ASM2_6:ASSIN2]
+~r~Sei stato visto troppo vicino alla scena dell'incidente!
-[FIL_SPC]
-Partite non piene?
+[ASM2_7:ASSIN2]
+~g~Non utilizzare armi! Deve sembrare un incidente! Spingila fuori strada!
-[FIL_PNG]
-Ping:
+[ASM2_8:ASSIN2]
+~g~La morte di Mrs. Dawson deve sembrare un incidente. Non utilizzare armi.
-[FEN_UKH]
-Host sconosciuto
+[ASM2_9:ASSIN2]
+~g~Avrai bisogno di una vettura per questo lavoro!
-[FEN_UKM]
-Mappa non trovata
+[ASM2_10:ASSIN2]
+~g~Quando la sua macchina prende fuoco, allontanati il più possibile dal luogo dell'incidente.
-[FEN_UKT]
-Modalità non trovata
+[ASM2_11:ASSIN2]
+Aiuto!
-[FEN_NCI]
-NON CONNESSO A INTERNET
+[ASM2_12:ASSIN2]
+Qualcuno mi aiuti!
-[FET_PAU]
-MENU PAUSA
+[ASM2_13:ASSIN2]
+Oddio!
-[FET_SGA]
-AVVIA PARTITA
+[ASM2_A:ASSIN2]
+Complimenti per l'ottimo lavoro, Mr. Teal. Il mio cliente è molto soddisfatto.
-[FEC_SGJ]
-Imposta joystick
+[ASM2_2:ASSIN2]
+Salute:
-[FEC_PAD]
-Gamepad
+{=================================== MISSION TABLE ASSIN3 ===================================}
-[FEC_JOY]
-Joystick
+[ASM3_11:ASSIN3]
+TEMPO:
-[FEC_WHL]
-Volante
+[ASM3_C:ASSIN3]
+Una gang europea ha pianificato un furto in banca a Vice City. I miei clienti preferirebbero che il colpo non vada a segno.
-[FEC_CNT]
-Periferica di controllo:
+[ASM3_D:ASSIN3]
+Ogni membro della gang ha un nascondiglio nella città: alcuni hanno dei lavori di copertura, altri sono in vacanza.
-[FET_APL]
-APPLICA
+[ASM3_E:ASSIN3]
+Dettagli e posizione più probabile di ogni bersaglio sono riportati nel nastro sotto al telefono.
-[FES_CSA]
-Seleziona una skin dalla seguente lista:
+[ASM3_14:ASSIN3]
+~g~Dick Tanner si trova presso la DBP Security in Ocean Drive.
-[FES_SKN]
-NOME SKIN
+[ASM3_15:ASSIN3]
+~g~Marcus Hammond e Franco Carter si trovano presso la gioielleria in Vice Point.
-[FES_DAT]
-DATA
+[ASM3_16:ASSIN3]
+~g~Nick Kong si trova presso Washington Beach.
-[FES_NON]
-NESSUNA SKIN DISPONIBILE
+[ASM3_18:ASSIN3]
+~g~Non avvicinarti troppo, se no il bersaglio potrebbe vederti e sarai costretto a inseguirlo!
-[FEA_FM9]
-RIPRODUTTORE MP3
+[ASM3_19:ASSIN3]
+~g~Ti ha visto! Fallo fuori!
-[FESZ_QZ]
-Sei sicuro di voler salvare la partita?
+[ASM3_20:ASSIN3]
+~g~Ti hanno visto! Falli fuori entrambi!
-[FES_CGA]
-Blocchi di gioco disponibili:
+[ASM3_21:ASSIN3]
+~r~Non hai ucciso tutti i membri della gang in tempo!
-[FES_SCG]
-Vuoi salvare la partita attuale?
+[ASM3_22:ASSIN3]
+~g~Non avvicinarti troppo, se no i bersagli potrebbero vederti e cercare di scappare!
-[FES_LCG]
-Vuoi caricare e continuare la partita?
+[ASM3_12:ASSIN3]
+~g~Un assortimento di armi è stato lasciato per te nel caso di bisogno. Hai ~h~9 MINUTI~g~ per uccidere tutti i membri della gang.
-[FEC_FIR]
-Fuoco
+[ASM3_13:ASSIN3]
+~g~Mike Griffin lavora su un cartello pubblicitario in Washington.
-[FEC_NWE]
-Arma successiva
+[ASM3_17:ASSIN3]
+~g~Charlie Dilson è in macchina in Washington.
-[FEC_PWE]
-Arma precedente
+{=================================== MISSION TABLE ASSIN4 ===================================}
-[FEC_FOR]
-Avanti
+[ASM4_12:ASSIN4]
+Distanza:
-[FEC_BAC]
-Indietro
+[ASM4_15:ASSIN4]
+~g~Recupera il fucile di precisione alla tua destra.
-[FEC_LEF]
-Sinistra
+[ASM4_16:ASSIN4]
+~g~Osserva la donna sul balcone: scenderà per le scale e chiederà l'ora a un uomo.
-[FEC_RIG]
-Destra
+[ASM4_17:ASSIN4]
+~g~Solo quando la conversazione avrà termine, dovrai uccidere l'uomo con cui ha parlato ma NON la donna.
-[FEC_ZIN]
-Ingrandimento
+[ASM4_18:ASSIN4]
+~g~Una volta eliminato il bersaglio, recupera la sua valigetta e portala ad Ammu-Nation in Downtown.
-[FEC_ZOT]
-Riduzione
+[ASM4_19:ASSIN4]
+~g~Tieni la distanza dal bersaglio: la barra nella parte superiore destra dello schermo indica quanto gli sei vicino.
-[FEC_EEX]
-Entra/Esci
+[ASM4_20:ASSIN4]
+~g~Se si riempirà, verrai avvistato.
-[FEC_RAD]
-Radio
+[ASM4_21:ASSIN4]
+~g~Recupera la valigetta!
-[FEC_SUB]
-Sottomissioni
+[ASM4_22:ASSIN4]
+~g~Porta la valigetta ad Ammu-Nation in Downtown.
-[FEC_CMR]
-Cambia visuale
+[ASM4_23:ASSIN4]
+~g~Ti ha visto e sta fuggendo! Uccidilo e recupera la valigetta!
-[FEC_JMP]
-Salto
+[ASM4_25:ASSIN4]
+~r~Hai ucciso la donna, idiota!
-[FEC_SPN]
-Scatto
+[ASM4_26:ASSIN4]
+~r~Il bersaglio è salito a bordo del volo!
-[FEC_HND]
-Freno a mano
+[ASM4_27:ASSIN4]
+~r~Il bersaglio ti ha visto! Avresti dovuto tenerti a distanza!
-[FEC_TUL]
-Torretta a sx
+[ASM4_28:ASSIN4]
+~r~Il bersaglio ti ha visto! Ti ha sentito sparare!
-[FEC_TUR]
-Torretta a dx
+[ASM4_29:ASSIN4]
+~r~Dovevi ucciderlo solo dopo che aveva parlato con la donna!
-[FEC_LOL]
-Guarda a sinistra
+[ASM4_A:ASSIN4]
+È giunta l'ora di occuparsi di pesci più grossi, Mr Teal. Troverai un fucile tra le foglie alla tua destra.
-[FEC_LOR]
-Guarda a destra
+[ASM4_B:ASSIN4]
+Osserva la donna sul balcone sopra i banchi dei check-in: scenderà per le scale e chiederà l'ora a un uomo.
-[FEC_NTR]
-Bersaglio successivo
+[ASM4_C:ASSIN4]
+Dovrai uccidere questa persona, recuperare la sua valigetta e portarla nella locazione riportata sotto al telefono.
-[FEC_PTT]
-Bersaglio precedente
+{=================================== MISSION TABLE ASSIN5 ===================================}
-[FEC_LBA]
-Guarda indietro
+[ASM5_A:ASSIN5]
+C'è uno scambio di beni sopra il tetto della fabbrica di gelato Cherry Popper.
-[FEC_CEN]
-Centra visuale
+[ASM5_B:ASSIN5]
+Uccidi tutti gli elementi coinvolti, recupera la merce e portala all'eliporto presso l'aeroporto.
-[FEC_UND]
-(NO)
+[ASM5_C:ASSIN5]
+Alla tua sinistra troverai un cancello che porta al retro della fabbrica.
-[FET_CFT]
-A PIEDI
+[ASM5_1:ASSIN5]
+~g~Entra nel cortile dietro alla fabbrica di gelato Cherry Popper e apriti la strada fino al luogo dello scambio.
-[FET_CCR]
-IN MACCHINA
+[ASM5_2:ASSIN5]
+~g~Recupera la merce e portala all'eliporto presso l'aeroporto.
-[CVT_MSG]
-Conversione texture per prestazioni ottimali con la tua scheda video
+[ASM5_3:ASSIN5]
+~g~Porta la merce all'eliporto presso l'aeroporto!
-[FET_CAC]
-AZIONE
+{=================================== MISSION TABLE BANKJ1 ===================================}
-[FEC_IBT]
--
+[WANTED1:BANKJ1]
+~g~Semina i poliziotti per perdere il tuo livello di sospetto.
-[FEC_SPC]
-BARRA
+[BJM1_A:BANKJ1]
+Tommy! Ehi Tommy, guarda qua, è grandioso! Ho fatto installare un minibar!
-[FEC_MXO]
-P1MX
+[BJM1_B:BANKJ1]
+Abbiamo un intero bar al piano di sotto, Ken.
-[FEC_MXT]
-P2MX
+[BJM1_C:BANKJ1]
+Sì, sì, certo. Beh, ho portato quella lavagna che mi avevi richiesto.
-[FEC_UNB]
-NESSUNO
+[BJM1_D:BANKJ1]
+Ah, questi sono i benefici della scuola dell'obbligo: l'abilità di seguire le istruzioni.
-[FET_CME]
-METODO DI CONTROLLO
+[BJM1_E:BANKJ1]
+Adesso mi serve uno scassinatore.
-[FET_RDK]
-RIDEFINISCI COMANDI
+[BJM1_F:BANKJ1]
+Oh, va bene, beh, fammi pensare... scassinatore, scassinatore, scassinatore... Trovato! Questo tipo ti farà impazzire!
-[FET_AMS]
-IMPOSTAZIONI MOUSE
+[BJM1_G:BANKJ1]
+Ahh, nah, quello schmuck. È dentro.
-[FET_STI]
-CONFIGURAZIONE PREDEFINITA
+[BJM1_H:BANKJ1]
+Dentro dove?
-[FET_CTI]
-CONFIGURAZIONE CLASSICA
+[BJM1_I:BANKJ1]
+In una cella nel quartier generale della polizia in attesa di trasferimento.
-[FET_MTI]
-CONFIGURAZIONE COL MOUSE
+[BJM1_J:BANKJ1]
+Credo stia per essere rilasciato sulla parola...
-[FET_DAM]
-MODELLAZIONE ACUSTICA DINAMICA
+[BJM1_1:BANKJ1]
+~g~Fai fuggire Cam Jones dalla custodia della polizia!
-[FEC_TFL]
-Torretta a sinistra
+[BJM1_3:BANKJ1]
+~g~Troverai ciò che ti serve nello spogliatoio della stazione.
-[FEC_TFR]
-Torretta a destra
+[BJM1_21:BANKJ1]
+~g~La tessera per le celle si trova nel piano superiore della stazione.
-[FEC_TFU]
-Torretta /Aereo su
+[BNK1_7:BANKJ1]
+Cam Jones?
-[FEC_TFD]
-Torretta /Aereo giù
+[BNK1_8:BANKJ1]
+Ti sto facendo scappare!
-[FEC_MWF]
-VOLANTE SU
+[BNK1_10:BANKJ1]
+Sì, sono io...
-[FEC_MWB]
-VOLANTE GIÙ
+[BNK1_11:BANKJ1]
+Come vuoi!
-[FEC_ORR]
-o
+[BNK1_13:BANKJ1]
+Devo fare un lavoro e tu sarai il mio scassinatore.
-[FEC_NUS]
-NON USATO
+[BNK1_14:BANKJ1]
+Sempre meglio che restare col culo in galera!
-[FEC_LUD]
-Sguardo su
+[BJM1_22:BANKJ1]
+~g~Riporta Cam a casa sua!
-[FEC_LDU]
-Sguardo giù
+[BJM1_23:BANKJ1]
+~g~Prima devi recuperare la tessera!
-[FEC_CMP]
-COMBO: SGUARDO S+D
+[BNK1_12:BANKJ1]
+Fai perdere le tracce e riportami a casa!
-[FEC_NTT]
-Nessun testo assegnato a questo tasto
+[BJM1_20:BANKJ1]
+Metti via l'arma o ne pagherai le conseguenze!
-[FEC_FNC]
-F~1~
+[BJM1_5:BANKJ1]
+Solo personale autorizzato oltre a questo punto!
-[FEC_IRT]
-INS
+[BJM1_2:BANKJ1]
+~r~Dovevi far fuggire Cam, non farlo morire!
-[FEC_DLL]
-CANC
+[BJM1_4:BANKJ1]
+È armato! Uccidetelo!
-[FEC_HME]
-HOME
+{=================================== MISSION TABLE BANKJ2 ===================================}
-[FEC_END]
-FINE
+[BJM2_A:BANKJ2]
+Abbiamo bisogno di un tiratore. Ne conosci uno?
-[FEC_PGU]
-PAG SU
+[BJM2_B:BANKJ2]
+Ehi Tommy, Tommy, Tommy, questa roba ti tiene in forma, amico.
-[FEC_PGD]
-PAG GIÙ
+[BJM2_C:BANKJ2]
+WoooOOOooo!
-[FEC_UPA]
-SU
+[BJM2_D:BANKJ2]
+Potrei essere io il tuo tiratore! Spara! Spara!
-[FEC_DWA]
-GIÙ
+[BJM2_E:BANKJ2]
+Non sei un tiratore, sei un idiota.
-[FEC_LFA]
-SINISTRA
+[BJM2_F:BANKJ2]
+Fatti un drink e sta zitto.
-[FEC_RFA]
-DESTRA
+[BJM2_G:BANKJ2]
+Ehi, via dai miei piedi! Ye ye ye ow ow.
-[FEC_NUM]
-NUM
+[BJM2_H:BANKJ2]
+Cam, cosa mi dici?
-[FEC_NMN]
-NUM~1~
+[BJM2_I:BANKJ2]
+Beh, il miglior tiratore in città è un tipo chiamato Cassidy.
-[FEC_FWS]
-NUM /
+[BJM2_J:BANKJ2]
+Davvero?
-[FEC_PLS]
-NUM +
+[BJM2_K:BANKJ2]
+Sì. Un militare, o per lo meno crede di esserlo.
-[FEC_MIN]
-NUM -
+[BJM2_L:BANKJ2]
+Non credo sia mai stato nell'esercito, ma sicuramente sa come tenere in mano un'arma.
-[FEC_DOT]
-NUM .
+[BJM2_M:BANKJ2]
+Lo troverai di sicuro al poligono di tiro.
-[FEC_NLK]
-BLOC NUM
+[BJM2_2A:BANKJ2]
+Sei Phil Cassidy?
-[FEC_ETR]
-INVIO
+[BJM2_2B:BANKJ2]
+Perché?
-[FEC_SLK]
-BLOC SCORR
+[BJM2_2C:BANKJ2]
+Sto cercando un uomo che sappia come sparare. Da quello che vedo, non sono molto convinto...
-[FEC_PSB]
-PAUSA
+[BJM2_2D:BANKJ2]
+Figliolo, potrei colpire una mosca sulla tua testa a 30 metri di distanza.
-[FEC_BSP]
-INDIETRO
+[BJM2_2E:BANKJ2]
+Davvero?
-[FEC_TAB]
-TAB
+[BJM2_2F:BANKJ2]
+Certo. Ho fatto pratica nell'esercito.
-[FEC_CLK]
-BLOC MAIUSC
+[BJM2_2G:BANKJ2]
+Lo sparo alla mosca è così popolare nell'esercito? Per fortuna non pago le tasse.
-[FEC_RTN]
-RET
+[BJM2_2H:BANKJ2]
+Stai cercando di fare lo spiritoso?
-[FEC_LSF]
-MAIUSC SX
+[BJM2_2I:BANKJ2]
+Ah ah ah ah ah!
-[FEC_RSF]
-MAIUSC DX
+[BJM2_2J:BANKJ2]
+Spariamo.
-[FEC_LCT]
-CTRL SX
+[BJM2_1:BANKJ2]
+~g~Raggiungi Ammu-Nation in Downtown e parla con Phil Cassidy.
-[FEC_RCT]
-CTRL DX
+[BJM2_4:BANKJ2]
+PUNTEGGIO PRIMO TURNO: ~1~
-[FEC_LAL]
-ALT SX
+[BJM2_6:BANKJ2]
+PUNTEGGIO SECONDO TURNO: ~1~
-[FEC_RAL]
-ALT DX
+[BJM2_7:BANKJ2]
+PUNTEGGIO TOTALE: ~1~
-[FEC_LWD]
-WIN SX
+[BJM2_9:BANKJ2]
+~G~Raggiungi il punto di partenza del secondo turno.
-[FEC_RWD]
-WIN DX
+[BJM2_11:BANKJ2]
+~r~Phil è morto!
-[FEC_WRC]
-CLIC WIN
+[BJM2_12:BANKJ2]
+~r~Uno dei tiratori è morto!
-[WIN_TTL]
-Grand Theft Auto III
+[BJM2_14:BANKJ2]
+~g~Raggiungi la prossima area!
-[WIN_95]
-Grand Theft Auto III non è supportato da Windows 95
+[BJM2_17:BANKJ2]
+~g~Vai a parlare con Phil.
-[WIN_DX]
-Grand Theft Auto III richiede DirectX versione 8.1 o superiore
+[BJM2_24:BANKJ2]
+~g~Il bersaglio più vicino vale un punto.
-[WIN_VDM]
-Grand Theft Auto III richiede almeno 12 MB di memoria video disponibile
+[BJM2_25:BANKJ2]
+~g~Il bersaglio centrale vale due punti.
-[DIAB3_G]
-Arriba!
+[BJM2_27:BANKJ2]
+~g~In questo turno, tutti i bersagli valgono un punto.
-[FEM_RES]
-RIPRENDI PARTITA
+[BNK2_4:BANKJ2]
+Hoooeee!
-[FES_SNG]
-NUOVA PARTITA
+[BNK2_5:BANKJ2]
+Non riusciresti a colpire neanche un elefante!
-[FEM_SP]
-GIOCATORE SINGOLO
+[BNK2_7:BANKJ2]
+Fammi un favore, aiutami a mettere a segno un colpo.
-[FEM_MP]
-MULTIGIOCATORE
+[BNK2_8:BANKJ2]
+Figliolo, da come hai sparato, se mi chiedessi di sposarti direi di sì.
-[FEM_QT]
-ESCI DAL GIOCO
+[BNK2_9A:BANKJ2]
+Figliolo, ficcati la tua parlata e le tue grandi idee là dove non batte il sole. Non sai sparare per niente.
-[FES_SG]
-NUOVA PARTITA
+[BNK2_9B:BANKJ2]
+Non sai sparare per niente.
-[FES_LG]
-CARICA PARTITA
+[BJM2_28:BANKJ2]
+PUNTEGGIO TERZO TURNO: ~1~
-[FEM_HST]
-OSPITA PARTITA
+[BJM2_26:BANKJ2]
+~g~Il bersaglio più lontano vale tre punti.
-[FEM_OPT]
-OPZIONI
+[BNK2_1:BANKJ2]
+MUNIZIONI VERE
-[FEM_DBG]
-DEBUG
+[RANGE_1:BANKJ2]
+PUNTEGGIO PER COLPO: ~1~
-[FET_PSU]
-IMPOSTAZIONI GIOCATORE
+[BJM2_2:BANKJ2]
+~g~Per interrompere il turno, premi il ~h~~k~~PED_JUMPING~~g~.
-[FET_DEF]
-RIPRISTINA PREDEFINITI
+[BJM2_N:BANKJ2]
+Rilassati.
-[FED_BRI]
-LUMINOSITÀ
+{=================================== MISSION TABLE BANKJ3 ===================================}
-[FED_TRA]
-TRACCE
+[BJM3_A:BANKJ3]
+Le cose stanno iniziando a prendere forma.
-[FEM_LOD]
-DISTANZA VISUALE
+[BJM3_B:BANKJ3]
+Qual è il piano Tommy? Que pasa, amigo?
-[FEM_VSC]
-SINCRONIA FRAME
+[BJM3_C:BANKJ3]
+La tua parte consiste nel continuare a fare l'idiota. Comunque, adesso abbiamo bisogno di un pilota.
-[FEM_FRM]
-LIMITATORE FRAME
+[BJM3_D:BANKJ3]
+Tommy, lo farò io. Io so guidare bene.
-[FED_RES]
-RISOLUZIONE
+[BJM3_E:BANKJ3]
+Ti serve Hilary, capo. Di certo non un sapientone avvocato del cazzo.
-[FED_WIS]
-SCHERMO 16:9
+[BJM3_F:BANKJ3]
+Hilary è la persona giusta. Non troverai nessuno capace di guidare così veloce. Gli posso fare una chiamata.
-[FEDS_TB]
-INDIETRO
+[BJM3_G:BANKJ3]
+Ehi Hil, sono Phil. Come butta? No, lascia stare, ne parliamo un'altra volta. Mi faresti un favore?
-[FEA_MUS]
-VOLUME MUSICA
+[BJM3_H:BANKJ3]
+Ho qui un tipo del nord... No, no, non credo abbia fatto il servizio militare, ma ha bisogno di un guidatore.
-[FEA_SFX]
-VOLUME EFFETTI
+[BJM3_I:BANKJ3]
+Per un po' di azione. OK, capisco.
-[FEA_RSS]
-STAZIONE RADIO
+[BJM3_J:BANKJ3]
+Che cosa ha detto?
-[FEL_ENG]
-INGLESE
+[BJM3_K:BANKJ3]
+Beh, ci sta, nessun problema. Beh, un piccolo problema c'è: ha subito uno shock da abbandono.
-[FEL_FRE]
-FRANCESE
+[BJM3_L:BANKJ3]
+Sembra non voglia lavorare con nessuno che non sia capace di batterlo. Qualcosa che ha a che fare con la sua vecchia.
-[FEL_GER]
-TEDESCO
+[BJM3_M:BANKJ3]
+Comunque, vuole prima sfidarti in una corsa, ha detto che ci aspettava fuori...
-[FEL_ITA]
-ITALIANO
+[BJM3_2A:BANKJ3]
+Sei Tommy? Beh, certo che sei Tommy, cioè...
-[FEL_SPA]
-SPAGNOLO
+[BJM3_2B:BANKJ3]
+Per quale altro motivo qualcuno vorrebbe parlare con me?
-[FEA_3DH]
-HARDWARE AUDIO
+[BJM3_2C:BANKJ3]
+OK, vedila in questo modo...
-[FEA_SPK]
-CONFIGURAZIONE ALTOPARLANTI
+[BJM3_2D:BANKJ3]
+Io guiderò SE, e solo SE, tu sai guidare come si deve.
-[FEA_2SP]
-DUE CASSE
+[BJM3_2E:BANKJ3]
+Lasciami solo... e non te lo perdonerò mai.
-[FEA_4SP]
-PIÙ DI DUE CASSE
+[BJM3_2:BANKJ3]
+~r~Hilary è morto!
-[FEA_EAR]
-CUFFIE
+[BJM3_4:BANKJ3]
+~g~Hai bisogno di una vettura per partecipare!
-[FEA_NAH]
-NESSUN HARDWARE AUDIO
+[BNK3_1:BANKJ3]
+OK. Guiderò per te, ma per favore trattami male!
-[FET_SNG]
-NUOVA PARTITA
+[BNK3_3A:BANKJ3]
+Corsa illegale in corso presso Vice Point.
-[FEN_STA]
-AVVIA LA PARTITA
+[BNK3_3B:BANKJ3]
+A tutte le pattuglie.
-[GMLOAD]
-CARICA PARTITA
+[BNK3_3C:BANKJ3]
+Queste corse sono illegali e vietate!
-[GMSAVE]
-SALVA PARTITA
+{=================================== MISSION TABLE BANKJ4 ===================================}
-[FES_DGA]
-ELIMINA PARTITA
+[BNK4_A:BANKJ4]
+~w~Come potete vedere, signori, questi saranno i soldi più facili della storia.
-[FEM_NON]
-NESSUNO
+[BNK4_B:BANKJ4]
+~w~Tommy, seriamente, dovresti pensare di fare l'avvocato.
-[FEC_IVV]
-INVERTI MOUSE VERTICALMENTE
+[BNK4_C:BANKJ4]
+~w~Ma che cosa ti fumi, amico? Non è per niente un piano semplice!
-[FEC_MSH]
-SENSIBILITÀ MOUSE
+[BNK4_D:BANKJ4]
+~w~Beh, chi ha bisogno di un piano semplice?
-[FET_CCN]
-COMANDI: CLASSICO
+[BNK4_E:BANKJ4]
+~w~Prendi il comunismo, beh, quello era un piano semplice. Non ha fatto così bene alla Russia, no?
-[FET_SCN]
-COMANDI: PREDEFINITO
+[BNK4_F:BANKJ4]
+~w~Rilassatevi, OK? Con una squadra come la nostra, non ci saranno problemi.
-[FES_SET]
-USA SKIN
+[BNK4_G:BANKJ4]
+~w~Abbiamo Cam per la cassaforte. Phil? Noi ci occuperemo della sorveglianza, mentre Hilary guiderà l'auto per la fuga.
-[GHOST]
-Fantasma
+[BNK4_H:BANKJ4]
+~w~Uh, eh eh, non ti stai dimenticando qualcuno? Qualcuno che ti ha costantemente aiutato in questa città? Qualcuno...?
-[WIN_RSZ]
-Impossibile impostare la nuova risoluzione
+[BNK4_I:BANKJ4]
+~w~Ken... Ken, ma certo. Il nostro Ken si occuperà di lavare il denaro sporco e di tenere le birre al fresco.
-[FET_APP]
-PULSANTE SX, INVIO PER APPLICARE LE NUOVE IMPOSTAZIONI
+[BNK4_J:BANKJ4]
+~w~Non ho ancora capito cosa ci sto a fare io qua.
-[FET_HRD]
-IMPOSTAZIONI PREDEFINITE RIPRISTINATE
+[BNK4_K:BANKJ4]
+~w~Beh, è semplice: non hai mai visto un film d'azione?
-[FET_MST]
-STERZO VIA MOUSE
+[BNK4_L:BANKJ4]
+~w~Entriamo nella banca, sventoliamo in giro l'arma e usciamo molto ricchi.
-[FEC_STR]
-NUM ASTERISCO
+[P_DEAD:BANKJ4]
+~r~Phil è morto!
-[FET_MIG]
-SINISTRA, DESTRA, ROTELLA PER MODIFICARE
+[C_DEAD:BANKJ4]
+~r~Cam è morto!
-[FET_CIG]
-INDIETRO PER AZZERARE - PULSANTE SX, INVIO PER MODIFICARE
+[H_DEAD:BANKJ4]
+~r~Hilary è morto!
-[FET_RIG]
-SELEZIONA UN NUOVO COMANDO PER QUESTA AZIONE O PREMI ESC PER ANNULLARE
+[P_HIND:BANKJ4]
+~r~Hai perso Phil!
-[FET_EIG]
-IMPOSSIBILE ASSEGNARE UN COMANDO A QUESTA AZIONE
+[C_HIND:BANKJ4]
+~r~Cam è restato indietro!
-[NO_PCCD]
-Inserisci il disco 2 di Grand Theft Auto III nel lettore o premi ESC per annullare
+[H_HIND:BANKJ4]
+~r~Hai abbandonato Hilary!
-[CVT_ERR]
-Spazio su disco esaurito; è necessario liberare dello spazio prima di poter procedere. Premi ESC per annullare.
+[GETCAR:BANKJ4]
+~g~Entra nell'auto e preparati alla rapina!
-[FED_SUB]
-SOTTOTITOLI
+[TRASHED:BANKJ4]
+~r~HAI DISTRUTTO L'AUTO PER LA FUGA!!!
-[FET_DSN]
-Skin predefinita.bmp
+[BNK4_1:BANKJ4]
+Guido io.
-[JM3]
-'RAPINA AL FURGONE'
+[BNK4_2:BANKJ4]
+Ottimo. Un passeggero. Aspetta che lo dica al resto del gruppo.
-[EBAL]
-'GIVE ME LIBERTY'
+[BNK4_3A:BANKJ4]
+Ehi, fai attenzione alla macchina, Tommy!
-[LM4]
-'ARMI PRONTE ALL'AZIONE'
+[BNK4_3B:BANKJ4]
+Tommy, Hilary occupa troppo spazio!
-[ATUTOR2]
-~g~Porta i pazienti all'ospedale! Qualsiasi scossone ridurrà le probabilità che arrivino vivi.
+[BNK4_3C:BANKJ4]
+Non è vero!
-[REPLAY]
-REPLAY
+[BNK4_3D:BANKJ4]
+Invece sì!
-[FEC_SFT]
-MAIUSC
+[BNK4_3E:BANKJ4]
+Ehi, state entrambi zitti o ve ne andate a piedi.
-[CRED254]
-RESPONSABILE STUDIO
+[BNK4_3F:BANKJ4]
+Sì Hilary.
-[CVT_CRT]
-Impossibile convertire le texture per la scheda video. Deve collegarti come Amministratore per poterlo fare. Premi ESC per uscire.
+[BNK4_3I:BANKJ4]
+Perdio, Phil, smettila di sventolare quell'affare in giro!
-[FEM_ON]
-ON
+[BNK4_3J:BANKJ4]
+Sì, finirai col cavare un occhio a qualcuno!
-[FEM_OFF]
-OFF
+[BNK4_3M:BANKJ4]
+La mia bambina! È a pezzi!
-[FEM_YES]
-SÌ
+[BNK4_3O:BANKJ4]
+Sei accecato dall'illusione di permanenza.
-[FEM_NO]
-NO
+[BNK4_3P:BANKJ4]
+Cosa?
-[FES_WAR]
-Salvataggio, attendere...
+[BNK4_3Q:BANKJ4]
+Pensi che tutto duri per sempre.
-[FED_DLW]
-Eliminazione, attendere...
+[BNK4_3R:BANKJ4]
+La giovinezza, le persone care, la pizza...
-[FED_LDW]
-Caricamento, attendere...
+[BNK4_3S:BANKJ4]
+Ma tutto passa e finisce e tu lo devi accettare.
-[FEC_SLC]
-Slot non valido
+[BNK4_3T:BANKJ4]
+Ehi, hai ragione. Grazie Cam.
-[FED_LFL]
-Caricamento posizione salvata fallito. Il gioco verrà riavviato.
+[BNK4_3U:BANKJ4]
+È un piacere.
-[FET_RSO]
-RIPRISTINATE IMPOSTAZIONI ORIGINALI
+[BNK4_3V:BANKJ4]
+Ehi Tommy, perché ci siamo fermati?
-[FET_RSC]
-HARDWARE NON DISPONIBILE - RIPRISTINATE IMPOSTAZIONI ORIGINALI
+[BNK4_4A:BANKJ4]
+~w~Hilary, continua a guidare attorno al quartiere.
+
+[BNK4_5:BANKJ4]
+~w~OK Tommy, OK.
+
+[BNK4_6:BANKJ4]
+~w~QUESTA È UNA RAPINA!
+
+[BNK4_7:BANKJ4]
+~w~NESSUNO SI MUOVA!
+
+[BNK4_8:BANKJ4]
+~w~TUTTI CONTRO QUEL MURO!
+
+[BNK4_9:BANKJ4]
+Phil, mantieni il controllo!
+
+[BNK4_10:BANKJ4]
+Ricevuto capo!
+
+[BNK4_11:BANKJ4]
+Vieni Cam, la cassaforte è di sopra...
+
+[BK4_12A:BANKJ4]
+Maledizione! È una Flange 9000!
+
+[BK4_12B:BANKJ4]
+Potrei impiegare ore ad aprirla,
+
+[BK4_12C:BANKJ4]
+o cinque minuti se trovi l'amministratore.
+
+[BNK4_13:BANKJ4]
+Vado a scoprire dove si è rintanato.
+
+[BK4_14A:BANKJ4]
+Phil, va tutto bene?
+
+[BNK4_15:BANKJ4]
+Certo. Tutto liscio come l'olio.
+
+[BNK4_16:BANKJ4]
+Tu, tu vieni con me!
+
+[BNK4_17:BANKJ4]
+OK, OK! Ti prego, non sparare!
+
+[BNK4_18:BANKJ4]
+HO DETTO NESSUNO SI MUOVA!
+
+[BK4_19A:BANKJ4]
+L'apertura è temporizzata,
+
+[BK4_19B:BANKJ4]
+potete anche rinunciarci!
+
+[BK4_20A:BANKJ4]
+Diamine, posso aggirare l'apertura a tempo,
+
+[BK4_20B:BANKJ4]
+ma poi avremo bisogno del tuo codice per spalancarla!
+
+[BNK4_21:BANKJ4]
+Sta qua. Se fai uno scherzo diventi cibo per pesci. Chiaro?
+
+[BK4_24A:BANKJ4]
+Vado a controllare Phil, torno subito.
+
+[BK4_24B:BANKJ4]
+Te l'avevo detto di non toccare l'allarme!
+
+[BNK4_25:BANKJ4]
+La squadra SWAT sarà qui fra pochi minuti!
+
+[BNK4_27:BANKJ4]
+Un po' di aiuto non farebbe male, Tommy.
+
+[BNK4_28:BANKJ4]
+SWAT di Vice City! Siete completamente circondati!
+
+[BNK4_29:BANKJ4]
+Circondati? AH AH AH Aaaaaaaaaah!
+
+[BNK4_30:BANKJ4]
+Si stanno cagando addosso, corrotti bastardi!
+
+[BK4_31A:BANKJ4]
+Tommy! La cassaforte è aperta!
+
+[BK4_34A:BANKJ4]
+OK, abbiamo i fondi pensione della SWAT. Andiamocene da qui!
+
+[BK4_34B:BANKJ4]
+OK, l'avete voluto voi! Il tempo è scaduto!
+
+[BK4_35A:BANKJ4]
+Stanno assalendo l'edificio!
+
+[BK4_35B:BANKJ4]
+Al riparo!
+
+[BNK4_36:BANKJ4]
+Dov'è Cam?
+
+[BNK4_37:BANKJ4]
+Non ce l'ha fatta...
+
+[BNK4_38:BANKJ4]
+Questo è l'ultimo. VIA! VIA! VIA!
+
+[BNK_39:BANKJ4]
+Merda! Dov'è Hilary?
+
+[BK4_40A:BANKJ4]
+Gliela do io l'illusione di permanenza!
+
+[BNK4_42:BANKJ4]
+Ehi, ragazzi! Entrate, vi copro io!
+
+[BNK4_44:BANKJ4]
+Ce l'abbiamo fatta! Siamo ricchi, RICCHI!
+
+[BNK4_45:BANKJ4]
+Peccato che Cam non ce l'ha fatta, era un bravo ragazzo!
+
+[BNK4_46:BANKJ4]
+Sì, comunque... ora ce n'è più per noi!
+
+[BNK4_47:BANKJ4]
+Maledettamente vero! YEEEEHAAAH!
+
+[BNK4_48:BANKJ4]
+Tommy, vuoi un massaggio?
+
+[BNK4_49:BANKJ4]
+Ciao Mercedes! Sì, effettivamente sono un po' teso...
+
+[BNK450A:BANKJ4]
+Sai cosa ti dico Tommy? Sai cosa ti dico? I membri corrotti della SWAT faranno meglio a fare attenzione finché Kent Paul è in città.
+
+[BNK450B:BANKJ4]
+Eddai, dammene una fetta più grande! Amico, dai! Mi devo comprare dei vestiti nuovi!
+
+[BNK4_94:BANKJ4]
+~w~OK, ragazzi. Procediamo come pianificato.
+
+[BM_DEAD:BANKJ4]
+~r~Hai bisogno dell'amministratore vivo!
+
+[ASSET_A:BANKJ4]
+RAPINA ALLA BANCA COMPLETATA!
+
+[ASSET_B:BANKJ4]
+~g~Il Malibu d'ora in poi genererà introiti per un massimo di ~1~$. Ricordati di recuperarli regolarmente.
+
+[IDIOT:BANKJ4]
+~r~Vai in giro vestito come un pazzo e attiri l'attenzione! Sei un IDIOTA!
+
+{=================================== MISSION TABLE BARON1 ===================================}
+
+[COK1_A:BARON1]
+Forza, dai, forza! Yeh yeh aaaah...
+
+[COK1_B:BARON1]
+Stupido cavallo! Ti taglierò la testa!
+
+[COK1_C:BARON1]
+Chi è questo stronzo?
+
+[COK1_D:BARON1]
+Tommy Vercetti, ti ricorderai di me.
+
+[COK1_E:BARON1]
+Scusami, sono un po' ansioso. Mai fidarsi di un fottuto cavallo!
+
+[COK1_F:BARON1]
+Hai fatto un bel lavoro: adesso lavori per me.
+
+[COK1_H:BARON1]
+Come ti ho detto, amigo, lavori per me. Adesso sta zitto. Un qualche giuda mi ha tradito.
+
+[COK1_I:BARON1]
+Pensava non sapessi quanti soldi stessi facendo, ma rubarmi il 3% è come rubarmi il 100%.
+
+[COK1_J:BARON1]
+Nessuno fa questo a me. NESSUNO!!!
+
+[COK1_K:BARON1]
+Seguilo nel suo appartamento e scopri dove va! Successivamente, lo elimineremo noi.
+
+[COK1_1:BARON1]
+Ommerda!
+
+[COK1_2:BARON1]
+Troppo lento, nonnino!
+
+[COK1_4:BARON1]
+Perdente.
+
+[COK1_5:BARON1]
+Ti conviene continuare a correre, stronzo!
+
+[COK1_8:BARON1]
+~g~Svelto! Recupera un mezzo e inseguilo!
+
+[COK1_9:BARON1]
+~r~Dovevi inseguirlo, non ucciderlo!
+
+[COK1_10:BARON1]
+~r~Entra nella casa del ladro e scopri dove ha nascosto il denaro.
+
+[COK1_11:BARON1]
+~g~Dai un'occhiata da questa finestra.
+
+[COK1_7:BARON1]
+~g~È scappato sul tetto: stagli dietro ma non ucciderlo!
+
+[COK1_G:BARON1]
+Lavoro per soldi.
+
+{=================================== MISSION TABLE BARON2 ===================================}
+
+[COK2_A:BARON2]
+Ma che fottuti incompetenti non siete?
+
+[COK2_B:BARON2]
+IDIOTI! IDIOTI! IDIOTI! IDIOTI!
+
+[COK2_C:BARON2]
+Tommy,
+
+[COK2_D:BARON2]
+questi idioti... cercano sempre di fregarti.
+
+[COK2_E:BARON2]
+È questo il problema in questo business.
+
+[COK2_F:BARON2]
+Che cosa credi di fare? Aaaaah!
+
+[COK2_G:BARON2]
+Questi stronzi hanno fallito miseramente.
+
+[COK2_H:BARON2]
+Ben presto anche i papà e le mamme penseranno di poter spacciare coca in Vice City.
+
+[COK2_I:BARON2]
+Chi sarà il prossimo adesso? La fottuta mafia?
+
+[COK2_J:BARON2]
+La base della loro banda è una fortezza al piano terra,
+
+[COK2_K:BARON2]
+per cui Quentin... Quentin! QUENTIN!
+
+[COK2_L:BARON2]
+Lui ti porterà in volo sull'area!
+
+[COK2_M:BARON2]
+Sradicateli!
+
+[COK2_N:BARON2]
+Che cosa credi di fare?
+
+[COK2_O:BARON2]
+Che cosa fai qua?
+
+[COK2_P:BARON2]
+Ehi, ho chiesto in giro ed è ovvio
+
+[COK2_Q:BARON2]
+che Diaz ha fatto saltare l'accordo e ha freddato mio fratello.
+
+[COK2_R:BARON2]
+E ucciderà anche te!
+
+[COK2_S:BARON2]
+Io posso far fuori Diaz!
+
+[COK2_T:BARON2]
+No, ascoltami! Io mi occuperò di Diaz:
+
+[COK2_U:BARON2]
+sta cominciando a fidarsi di me.
+
+[COK2_1:BARON2]
+Ho una domanda, però: perché 'Quentin'?
+
+[COK2_2:BARON2]
+Non lo so, mi è sempre piaciuto... Quentin Vance...
+
+[COK2_3:BARON2]
+Vance? Tu sei Lance Vance?
+
+[COK2_4:BARON2]
+Ehi, ne ho avuto abbastanza a scuola!
+
+[COK2_5:BARON2]
+Hai mai provato a sparare con quelli da un elicottero?
+
+[COK2_8:BARON2]
+Dove ci stiamo dirigendo?
+
+[COK2_9:BARON2]
+Prawn Island.
+
+[COK2_13:BARON2]
+Lance Vance. Brutto bastardo.
+
+[COK2_14:BARON2]
+OK, siamo quasi arrivati.
+
+[COK2_15:BARON2]
+Faremo un paio di passaggi.
+
+[COK2_16:BARON2]
+Cerca di colpire il maggior numero di nemici possibile.
+
+[COK2_17:BARON2]
+Poi ti scarico e dovrai cavartela da solo.
+
+[COK2_20:BARON2]
+Merda! Siamo in una zona di guerra! Abbatti un po' di gente!
+
+[COK2_21:BARON2]
+Stiamo sotto tiro, amico!
+
+[COK2_22:BARON2]
+Questo affare è maledettamente costoso da riparare! Falli fuori!
+
+[COK2_23:BARON2]
+OK, adesso dovrai cavartela da solo... Buona fortuna, fratello!
+
+[COK2_24:BARON2]
+Condizioni elicottero:
+
+[COK2_25:BARON2]
+~g~Recupera i soldi sul tetto.
+
+[COK2_27:BARON2]
+Sei nel MIO territorio, stronzo!
+
+[COK2_28:BARON2]
+Stai per affondare!
+
+[COK2_6:BARON2]
+No. Farò un po' di pratica lungo la strada.
+
+[OPEN_B:BARON2]
+Il blocco stradale per la terraferma è stato rimosso.
+
+[COK2_V:BARON2]
+sta cominciando a fidarsi di me.
+
+{=================================== MISSION TABLE BARON3 ===================================}
+
+[COK3_A:BARON3]
+Scommetto che adesso non vi divertite più!
+
+[COK3_B:BARON3]
+Ah ah ah ah!
+
+[COK3_C:BARON3]
+Woh! Fai attenzione a dove punti quel coso.
+
+[COK3_D:BARON3]
+Basta con merda di piccione sulla MIA macchina, vero Tommy?
+
+[COK3_E:BARON3]
+Direi di sì.
+
+[COK3_F:BARON3]
+Hai proprio ragione. Adesso ascolta:
+
+[COK3_G:BARON3]
+sai chi possiede la barca più veloce della costa est?
+
+[COK3_H:BARON3]
+Non così su due piedi.
+
+[COK3_I:BARON3]
+IO. E voglio che la situazione non cambi.
+
+[COK3_J:BARON3]
+Ogni contrabbandiere da qui a Caracas ha un solo sogno: un'imbarcazione più veloce.
+
+[COK3_K:BARON3]
+Si mormora che il cantiere Hull-o-Caust ha appena finito di costruirne una
+
+[COK3_L:BARON3]
+per una testa di cazzo del Costa Rica.
+
+[COK3_M:BARON3]
+E Tommy... IO VOGLIO QUELLA BARCA!!!
+
+[COK3_N:BARON3]
+Credo che siano tornati i tuoi piccioni.
+
+[COK3_O:BARON3]
+Ah! Pensavo di averti preso. Da dove salti fuori?
+
+[COK3_P:BARON3]
+Piccioni! Boom! Ah ah ah!
+
+[COK3_5:BARON3]
+~g~Trova l'interruttore per abbassare l'imbarcazione.
+
+[COK3_6:BARON3]
+~g~Porta la barca alla villa di Diaz.
+
+[COK3_7:BARON3]
+~r~Hai distrutto la barca!
+
+[COK3_8:BARON3]
+~g~Raggiungi il cantiere al porto e ruba la barca più veloce.
+
+[COK3_9:BARON3]
+~g~Adesso entra nella barca.
+
+{=================================== MISSION TABLE BARON4 ===================================}
+
+[COK4_A:BARON4]
+Sputa fuori! CATORCIO DI PLASTICA!
+
+[COK4_B:BARON4]
+Come osi farmi questo?
+
+[COK4_C:BARON4]
+Chi credi di essere, brutto pezzo di merdosa plastica! Aaarrgh!
+
+[COK4_D:BARON4]
+VAFFANCULO!
+
+[COK4_E:BARON4]
+Se hai distrutto il mio film favorito di El Burro ti spacco!
+
+[COK4_F:BARON4]
+Che altro posso fare?
+
+[COK4_G:BARON4]
+Forse non è collegato...
+
+[COK4_H:BARON4]
+Cosa?
+
+[COK4_I:BARON4]
+Merda... non importa, ne posso comprare a centinaia.
+
+[COK4_J:BARON4]
+Adesso Tommy,
+
+[COK4_K:BARON4]
+ogni mese un freelance naviga fino a Vice City e ormeggia il suo yacht.
+
+[COK4_L:BARON4]
+Vende il suo carico alla prima imbarcazione.
+
+[COK4_M:BARON4]
+Voglio che tu prenda la barca più veloce,
+
+[COK4_N:BARON4]
+batta tutti gli altri stronzi
+
+[COK4_O:BARON4]
+e riporti qui il carico, OK?
+
+[COK4_P:BARON4]
+Fammi indovinare, pensavi mi avrebbe fatto comodo un angelo custode?
+
+[COK4_Q:BARON4]
+Vorrei solo che mi lasciassi venire, amico mio.
+
+[COK4_R:BARON4]
+Puoi continuare con queste stronzate alla rambo,
+
+[COK4_S:BARON4]
+ma sono sicuro che un giorno o l'altro ti salverò il culo.
+
+[COK4_T:BARON4]
+e allora vorrai baciarmi!
+
+[COK4_U:BARON4]
+Sei pazzo.
+
+[COK4_V:BARON4]
+Ah ah ah!
+
+[COK4_1:BARON4]
+Allora Tommy, sappiamo che è stato Diaz a far saltare il nostro affare...
+
+[COK4_3:BARON4]
+Allora per quale motivo continuiamo a lavorare per lui?
+
+[COK4_4:BARON4]
+Più cose scopriamo adesso, meno dovremo imparare quando ci impossesseremo di questa città!
+
+[COK4_5:BARON4]
+Mi piace il tuo stile, amico. Molto fico.
+
+[COK4_12:BARON4]
+Attento, stanno arrivando da tutte le parti!
+
+[COK4_13:BARON4]
+Preso! Torniamo da Diaz il più velocemente possibile!
+
+[COK4_14:BARON4]
+Ne vuoi un po'?
+
+[COK4_15:BARON4]
+Salutami i pesci!
+
+[COK4_16:BARON4]
+Prendi questo! E questo!
+
+[COK4_19:BARON4]
+Altri guai in arrivo!
+
+[COK4_20:BARON4]
+Ci stanno sparando da quel molo!
+
+[COK4_24:BARON4]
+Bel colpo, amico. Sei un vero pazzo di prima classe.
+
+[COK4_25:BARON4]
+Beh, grazie.
+
+[COK4_26:BARON4]
+Ci vediamo, Tommy.
+
+[COK4_27:BARON4]
+OK, Mr. Lance Vance Dance.
+
+[COK4_28:BARON4]
+~g~Raggiungi lo yacht prima delle altre imbarcazioni!
+
+[COK4_31:BARON4]
+~g~Raggiungi la barca più veloce attraccata al molo!
+
+[COK4_32:BARON4]
+~r~Troppo lento!
+
+[COK4_33:BARON4]
+~r~Hai distrutto la barca!
+
+[COK4_34:BARON4]
+~g~Affonda quelle imbarcazioni!
+
+[COK4_35:BARON4]
+Condizioni barca:
+
+{=================================== MISSION TABLE BARON5 ===================================}
+
+[PROP_A:BARON5]
+PROPRIETÀ ACQUISITA!
+
+[COK4_30:BARON5]
+~r~Lance è morto!
+
+[ASS1_A:BARON5]
+Ho messo un po' di cannoni nel bagagliaio.
+
+[ASS1_B:BARON5]
+Accidenti! Dove hai trovato tutta questa roba?
+
+[ASS1_C:BARON5]
+La tenevo da parte per una giornata di pioggia.
+
+[ASS1_D:BARON5]
+Ti piace?
+
+[ASS1_E:BARON5]
+Sì, mi piace.
+
+[ASS1_F:BARON5]
+Brutto idiota...
+
+[ASS1_G:BARON5]
+La mia bellissima casa...
+
+[ASS1_H:BARON5]
+Guarda cosa hai combinato!
+
+[ASS1_I:BARON5]
+Questo è per mio fratello!
+
+[ASS1_J:BARON5]
+Mi fidavo di te, Tommy!
+
+[ASS1_K:BARON5]
+Ti avrei fatto diventare...
+
+[ASS1_L:BARON5]
+Buona notte, Mr. Diaz.
+
+[ASS1_1:BARON5]
+Questo posto sarà zeppo di stronzi... fai attenzione...
+
+[ASS1_2:BARON5]
+Non preoccuparti, Tommy, ti copro io.
+
+[ASS1_4:BARON5]
+Diaz deve essere qui dentro!
+
+[ASS1_13:BARON5]
+DIAZ? Sono venuto a prendermi il tuo business!
+
+[ASS1_14:BARON5]
+TOMMY! Mi hai tradito... Idiota! Ti ucciderò fra un attimo!
+
+[ASS1_16:BARON5]
+~g~Uccidi Diaz!
+
+[BUD1:BARON5]
+Lance
+
+[ASS1_18:BARON5]
+~g~La porta è chiusa: trova un percorso alternativo.
+
+[ASS1_19:BARON5]
+Di qua!
+
+[ASS1_20:BARON5]
+Tommy, ho un problema con Quentin, non con te!
+
+{=================================== MISSION TABLE BIKE1 ===================================}
+
+[BM1_A:BIKE1]
+Dov'è Baker?
+
+[BM1_B:BIKE1]
+Sto cercando Big Mitch Baker...
+
+[BM1_C:BIKE1]
+Chi lo cerca?
+
+[BM1_D:BIKE1]
+Tommy Vercetti.
+
+[BM1_E:BIKE1]
+Vercetti.
+
+[BM1_F:BIKE1]
+Non mi sembri della polizia, il che ti ha fatto guadagnare un minuto.
+
+[BM1_G:BIKE1]
+Ti conviene parlare in fretta.
+
+[BM1_H:BIKE1]
+Kent Paul mi ha detto che saresti stato interessato a occuparti della sorveglianza di uno spettacolo che sta allestendo.
+
+[BM1_I:BIKE1]
+Kent Paul? Sheesh! Non mi stupisce abbia mandato te.
+
+[BM1_J:BIKE1]
+L'ultima volta che è stato qui è uscito dalla finestra con il vestitino che gli hanno dato alla nascita.
+
+[BM1_K:BIKE1]
+Sei interessato o no?
+
+[BM1_L:BIKE1]
+Facciamo solo favori tra compagni.
+
+[BM1_M:BIKE1]
+Come faccio a diventarlo?
+
+[BM1_N:BIKE1]
+Non è uno circolo sportivo, amico. Sai guidare una moto?
+
+[BM1_O:BIKE1]
+Sai sederti su uno sgabello e bere birra?
+
+[BM1_P:BIKE1]
+Cougar, Zeppelin, scoprite se questa ragazzina sa portare una moto...
+
+[BM1_2:BIKE1]
+~g~Hai bisogno di una Freeway o di un'Angel per gareggiare!
+
+[BM1_3:BIKE1]
+~r~I partecipanti sono stati attaccati!
+
+[BIKE1_1:BIKE1]
+Bene, bei vestiti. Vediamo cosa sai fare.
+
+[BM1_1:BIKE1]
+~g~Recupera una Freeway o un'Angel e posizionati sulla griglia di partenza.
+
+{=================================== MISSION TABLE BIKE2 ===================================}
+
+[BM2_1:BIKE2]
+CAOS:
+
+[BM2_A:BIKE2]
+Ah ah ah, ti ho preso di nuovo!
+
+[BM2_B:BIKE2]
+Ehi, Vercetti.
+
+[BM2_C:BIKE2]
+Cougar ha detto che sai portare la moto come si deve.
+
+[BM2_D:BIKE2]
+Già, quanti altri giretti devo ancora fare?
+
+[BM2_E:BIKE2]
+Sono un uomo molto impegnato.
+
+[BM2_F:BIKE2]
+Se serve una bella scazzottata per mettere le cose a posto, dillo chiaramente.
+
+[BM2_G:BIKE2]
+Essere uno di noi non significa solo azzuffarsi. Si tratta di far parte di una famiglia.
+
+[BM2_H:BIKE2]
+Sì, sono già stato parte di una famiglia. Non ha funzionato.
+
+[BM2_I:BIKE2]
+Sì, certo, ma questa famiglia si occupa dei suoi membri.
+
+[BM2_J:BIKE2]
+Non chiediamo a uno di fare il lavoro sporco per poi lasciarlo marcire quindici anni ai lavori forzati.
+
+[BM2_K:BIKE2]
+Sì, esatto. Ho fatto la mia parte.
+
+[BM2_L:BIKE2]
+Questa è la più grande famiglia di disadattati, reietti e derelitti.
+
+[BM2_M:BIKE2]
+Merda, alcuni di noi sono stati persino traditi dalla propria nazione.
+
+[BM2_N:BIKE2]
+Sono stato imprigionato durante il Vietnam. Brutta storia.
+
+[BM2_O:BIKE2]
+Ed è per questo che ti chiedo di far bollire la pentola.
+
+[BM2_P:BIKE2]
+Questa fottuta nazione ha bisogno di un bel calcio nel culo, e saremo noi a darglielo.
+
+[BM2_Q:BIKE2]
+Per cui esci, prendi una moto e mostra a questa città quanto siamo arrabbiati!
+
+[BM2_R:BIKE2]
+Va bene.
+
+[BM2_2:BIKE2]
+~g~Devi riempire l'indicatore del caos entro il tempo stabilito per mostrare quanto sei arrabbiato!
+
+[BM2_3:BIKE2]
+~g~Questo suono indica che hai riempito parte dell'indicatore, continua così.
+
+[BM2_4:BIKE2]
+~r~Non sei riuscito a riempire l'indicatore del caos in tempo!
+
+{=================================== MISSION TABLE BIKE3 ===================================}
+
+[BM3_A:BIKE3]
+Ehi, ciao Mitch.
+
+[BM3_B:BIKE3]
+Accidenti Vercetti, hai davvero le palle.
+
+[BM3_C:BIKE3]
+Adesso voglio vedere se sei pronto a combattere per la tua famiglia.
+
+[BM3_D:BIKE3]
+Una gang locale ha fatto l'errore di rubare il mio mezzo...
+
+[BM3_E:BIKE3]
+probabilmente come prova di coraggio o qualcosa del genere.
+
+[BM3_F:BIKE3]
+Io e i miei uomini stavamo per andare a dar loro una lezione sul rispetto.
+
+[BM3_G:BIKE3]
+Comunque,
+
+[BM3_H:BIKE3]
+ho pensato che sarebbe stata un'ottima occasione per la tua iniziazione.
+
+[BM3_I:BIKE3]
+Riportami indietro la mia moto e potrai dire a Paul che avrà la sua sorveglianza.
+
+[BM3_2:BIKE3]
+~r~Dovevi riportare indietro la moto, non distruggerla!
+
+[BM3_3:BIKE3]
+~g~Riporta la moto al bar!
+
+[BM3_4:BIKE3]
+~g~Sali sulla moto!
+
+[INTRUDE:BIKE3]
+~g~Ti hanno visto!
+
+[BM3_6:BIKE3]
+~g~Si sono rintanati dietro Ammu-Nation in Downtown.
+
+[BM3_7:BIKE3]
+~g~Avrai bisogno di una moto più veloce per accedere al tetto.
+
+[BM3_8:BIKE3]
+~g~Usa la moto per saltare da queste scale fino al tetto nella parte più lontana della strada.
+
+[BM3_1:BIKE3]
+~g~Una gang locale ha rubato la Angel di Mitch Baker: riportala indietro!
+
+[BM3_9:BIKE3]
+~g~Recupera l'Angel di Mitch Baker e vattene!
+
+{=================================== MISSION TABLE BMX_1 ===================================}
+
+[BMX_REC:BMX_1]
+~g~Nuovo record stabilito: ~1~!!
+
+[GETBIK2:BMX_1]
+Hai ~1~ secondi per salire su una Dirt Bike!
+
+{=================================== MISSION TABLE BOATBUY ===================================}
+
+[DRUG_1:BOATBUY]
+Salve? Saaalve? Salve?
+
+[DRUG_2:BOATBUY]
+Tranquillo amico, sono qua.
+
+[DRUG_3:BOATBUY]
+Ehi, damerino! Dimmi, sei il nuovo proprietario?
+
+[DRUG_4:BOATBUY]
+Sì. Qual è la barca più veloce?
+
+[DRUG_5:BOATBUY]
+È già in acqua, amico,
+
+[DRUG_6:BOATBUY]
+pensavo che la volessi provare.
+
+[DRUG_7:BOATBUY]
+Amico, ha già sopra un bel motore da 300 cavalli...
+
+[DRUG_8:BOATBUY]
+...e la struttura in vetroresina: vola davvero sull'acqua!
+
+[DRUG_9:BOATBUY]
+Può andare da zero a sessanta in quattro secondi spaccati...
+
+[DRUG_10:BOATBUY]
+e può tenere venti pacchi della migliore erba giamaicana nella stiva!
+
+[DRUG_11:BOATBUY]
+Dacci dentro, amico, è pronta a volare!
+
+[DRUG_12:BOATBUY]
+Yo yo, uh, ehi amico, hai da accendere?
+
+[DRUG_13:BOATBUY]
+Amico?
+
+{=================================== MISSION TABLE CAP_1 ===================================}
+
+[CAP1_B1:CAP_1]
+~g~La Mafia sta tassando il tuo business. Trovali e falli fuori.
+
+[CAP1_B2:CAP_1]
+~g~La Mafia ha tassato il tuo cantiere navale!
+
+[CAP1_B3:CAP_1]
+~g~La Mafia ha tassato la tua fabbrica di gelato!
+
+[CAP1_B4:CAP_1]
+~g~La Mafia ha tassato la concessionaria!
+
+[CAP1_B5:CAP_1]
+~g~La Mafia ha tassato la tua compagnia di taxi!
+
+[CAP_01:CAP_1]
+OK, qual è l'emergenza?
+
+[CAP_02:CAP_1]
+CHI?
+
+[CAP_03:CAP_1]
+Tommy... dei maledetti mafiosi... dicevano di essere venuti a prendere la loro fetta...
+
+[CAP_04:CAP_1]
+...dicevano che erano soldi di Mr. Forello... mi sento di merda.
+
+[CAP_05:CAP_1]
+Forelli? SONNY Forelli?
+
+[CAP_06:CAP_1]
+Sì, quel nome... credo... hanno davvero insistito...
+
+[CAP_07:CAP_1]
+Non preoccuparti amico, non sono arrabbiato con te.
+
+[CAP_08:CAP_1]
+Portalo all'ospedale.
+
+[CAP_09:CAP_1]
+Tommy... fai a quel tipo un nuovo buco da cui cagare...
+
+[CAP_10:CAP_1]
+Ho intenzione di fargliene due.
+
+[CAP1_2:CAP_1]
+Conosci le regole, Vercetti!
+
+[CAP1_3:CAP_1]
+Mr. Forelli manda i suoi saluti!
+
+[CAP1_4:CAP_1]
+È il macellaio di Harwood!
+
+[CAP1_5:CAP_1]
+Dì a Sonny di stare alla larga!
+
+[CAP1_6:CAP_1]
+Vice City è MIA adesso, NON sua.
+
+[CAP1_7:CAP_1]
+Pensi di potermi tagliar fuori, Vercetti?
+
+[CAP1_8:CAP_1]
+Ti inseguiremo fino a farti fuori, Vercetti.
+
+[CAP1_9:CAP_1]
+Non hai nessuna possibilità, brutto cazzone psicopatico.
+
+[CAP1_10:CAP_1]
+Ti ucciderò, Vercetti.
+
+[CAP1_11:CAP_1]
+Sei sempre stato uno stronzo.
+
+[CAP1_12:CAP_1]
+Ti ammazzo, Vercetti.
+
+[CAP1_B6:CAP_1]
+~g~Hai trovato l'esattore: uccidilo!
+
+[CAP1_B7:CAP_1]
+~g~Hai perso l'esattore.
+
+[CAP1_B8:CAP_1]
+~r~L'esattore ha tassato tutte le tue proprietà.
+
+[CAP1_B9:CAP_1]
+~g~La Mafia ha tassato il Malibu!
+
+[CAP1_B0:CAP_1]
+~g~La Mafia ha tassato lo studio cinematografico!
+
+[CAP1_C2:CAP_1]
+~g~La Mafia è arrivata al cantiere navale!
+
+[CAP1_C3:CAP_1]
+~g~La Mafia è arrivata alla fabbrica di gelato!
+
+[CAP1_C4:CAP_1]
+~g~La Mafia è arrivata al concessionario!
+
+[CAP1_C5:CAP_1]
+~g~La Mafia è arrivata alla compagnia di taxi!
+
+[CAP1_C9:CAP_1]
+~g~La Mafia è arrivata al Malibu!
+
+[CAP1_C0:CAP_1]
+~g~La Mafia è arrivata allo studio cinematografico!
+
+[CAP1_D2:CAP_1]
+~g~La Mafia sta abbandonando il cantiere navale!
+
+[CAP1_D3:CAP_1]
+~g~La Mafia sta abbandonando la fabbrica di gelato!
+
+[CAP1_D4:CAP_1]
+~g~La Mafia sta abbandonando il concessionario!
+
+[CAP1_D5:CAP_1]
+~g~La Mafia sta abbandonando la compagnia di taxi!
+
+[CAP1_D9:CAP_1]
+~g~La Mafia sta abbandonando il Malibu!
+
+[CAP1_D0:CAP_1]
+~g~La Mafia sta abbandonando lo studio cinematografico!
+
+[CAP1B10:CAP_1]
+Hai beccato gli esattori. Altri stanno arrivando.
+
+{=================================== MISSION TABLE CARBUY ===================================}
+
+[CAR1_1:CARBUY]
+B.J. Smith. E tu devi essere Mr. Vercetti.
+
+[CAR1_2:CARBUY]
+Ti andrebbe un giro?
+
+[CAR1_3:CARBUY]
+Perché no.
+
+[CAR1_4:CARBUY]
+Bene, mi dispiace un po' vendere il concessionario.
+
+[CAR1_5:CARBUY]
+È stato il mio primo investimento da quando mi sono messo in proprio.
+
+[CAR1_6:CARBUY]
+Ma adesso è giunta l'ora di andare avanti.
+
+[CAR1_7:CARBUY]
+Lasci la città?
+
+[CAR1_8:CARBUY]
+Non troppo in fretta, spero?
+
+[CAR1_9:CARBUY]
+No. Sto per prepararmi al pensionamento e ai miei futuri investimenti.
+
+[CAR1_10:CARBUY]
+Il mercato non tirava molto,
+
+[CAR1_11:CARBUY]
+e la mia squadra si è preoccupata personalmente di diventare
+
+[CAR1_12:CARBUY]
+più creativa nella produzione di contanti.
+
+[CAR1_13:CARBUY]
+Logicamente, potrei smantellare l'organizzazione prima di vendere.
+
+[CAR1_14:CARBUY]
+Diamine, potrei radere al suolo tutto quanto se volessi.
+
+[CAR1_15:CARBUY]
+Quest'area è in pieno sviluppo.
+
+[CAR1_16:CARBUY]
+Oh, non mi preoccuperei di ciò.
+
+[CAR1_17:CARBUY]
+Il posto mi sembra perfetto.
+
+[CAR1_18:CARBUY]
+Sì, lo è, allora siamo d'accordo?
+
+{=================================== MISSION TABLE CARPAR1 ===================================}
+
+[MM_1_A:CARPAR1]
+~g~Attraversa ~y~5 punti di controllo ~r~SENZA~g~ abbattere i ~r~CONI~g~! ~g~Puoi attraversarli in ~y~QUALSIASI ORDINE~g~.
+
+[CONE_1:CARPAR1]
+~r~Hai abbattuto un cono!
+
+[MM_1_C:CARPAR1]
+~y~ATTRAVERSA~g~ un punto di controllo per attivare il TIMER. ~g~Ogni punto di controllo ti fornirà ~y~~1~ SECONDI~g~ extra.
+
+{=================================== MISSION TABLE COPCAR ===================================}
+
+[KILLS:COPCAR]
+UCCISIONI:
+
+[C_BREIF:COPCAR]
+~g~Sospettato visto in prossimità dell'area ~a~.
+
+[C_PASS:COPCAR]
+MINACCIA ELIMINATA: ~1~$
+
+[COPCART:COPCAR]
+~g~Hai ~1~ secondi per tornare a un veicolo della polizia prima che la missione abbia termine.
+
+[C_CANC:COPCAR]
+~r~Missione Vigilante annullata!
+
+[C_TIME:COPCAR]
+~r~È scaduto il tuo tempo come tutore della legge!
+
+[C_COMP1:COPCAR]
+Missione Vigilante livello 12 completata: valore massimo dell'armatura aumentato a 150.
+
+[CLEVEL:COPCAR]
+Missione Vigilante livello ~1~
+
+{=================================== MISSION TABLE COUNT1 ===================================}
+
+[CM1_A:COUNT1]
+Mr. Vercetti? Ehi, hai comprato la vecchia tipografia?
+
+[CM1_B:COUNT1]
+Sì, il mio vecchio un tempo lavorava nel campo.
+
+[CM1_C:COUNT1]
+Avrei voluto seguire le sue orme, ma... ho deciso di vivere diversamente.
+
+[CM1_D:COUNT1]
+Stai progettando di vendere il vecchio macchinario smontandolo in pezzi?
+
+[CM1_E:COUNT1]
+Ho pensato che potremmo stampare ancora qualcosa... un giornale, una rivista...
+
+[CM1_F:COUNT1]
+Che merda, figliolo, roba di bassa qualità. Ho sempre sognato stampare soldi. Non è poi così difficile.
+
+[CM1_G:COUNT1]
+Sai, l'ho fatto su scala ridotta per anni.
+
+[CM1_H:COUNT1]
+Davvero?
+
+[CM1_I:COUNT1]
+Certo. Ma prima abbiamo bisogno di matrici di buona qualità.
+
+[CM1_J:COUNT1]
+Ma certo! C'è già un'organizzazione di falsificatori in azione in Florida.
+
+[CM1_K:COUNT1]
+Un'organizzazione?
+
+[CM1_L:COUNT1]
+Sì. Beh, ho sentito solo delle voci.
+
+[CM1_M:COUNT1]
+Conosco un tipo che si intende di voci...
+
+[CM1_N:COUNT1]
+Un tempo passavo le serate con lui, mentre pulivo i rulli...
+
+[CM1_2A:COUNT1]
+Accidenti che culo incredibile!
+
+[CM1_2B:COUNT1]
+Va bene, bellezza, sei tu che ci perdi!
+
+[CM1_2C:COUNT1]
+Ehi, ciao amico, come butta?
+
+[CM1_2D:COUNT1]
+Che cosa sai della falsificazione?
+
+[CM1_2E:COUNT1]
+Oh, sto bene Paul, e a te?
+
+[CM1_2F:COUNT1]
+Vieni qua.
+
+[CM1_2G:COUNT1]
+Va bene! Va bene! Va bene! Sei ovviamente un tipo impegnato.
+
+[CM1_2H:COUNT1]
+Tutto ciò che so sul campo è che la Triade fornisce le matrici.
+
+[CM1_2I:COUNT1]
+Hanno una società di spedizioni nel porto,
+
+[CM1_2J:COUNT1]
+il capo di certo saprà quando passeranno nuovamente delle matrici!
+
+[CM1_2K:COUNT1]
+Grazie Paul.
+
+[CM1_2L:COUNT1]
+Qual è il tuo problema, sei un maniaco!
+
+[CM1_2M:COUNT1]
+Dammi un altro drink, in fretta!
+
+[CM1_3:COUNT1]
+~g~Ti hanno visto!
+
+[CM1_5:COUNT1]
+~g~Incontrati con Kent Paul al Malibu Club!
+
+[CNT1_1:COUNT1]
+Chi sei? Oooof! Aaiieee! Non il viso! Non il viso!
+
+[CM1_1:COUNT1]
+~g~Vai alla compagnia marittima Chartered Libertine nel porto.
+
+[CM1_2:COUNT1]
+~g~L'ufficiale delle spedizioni è in possesso delle informazioni che ti servono.
+
+[CNT1_2:COUNT1]
+OK, parlerò, parlerò!
+
+[CM1_6:COUNT1]
+~g~Ritorna con le informazioni alla tipografia!
+
+{=================================== MISSION TABLE COUNT2 ===================================}
+
+[CNT2_B1:COUNT2]
+Bene, il corriere porterà le matrici al porto oggi stesso.
+
+[CNT2_B2:COUNT2]
+Ho intenzione di intercettare il corriere, recuperare le matrici, far perdere le tracce e tornare qua.
+
+[CNT2_B3:COUNT2]
+Bene. A seconda di quanto bene vadano le cose,
+
+[CNT2_B4:COUNT2]
+potremmo avere cinque minuti per stampare soldi prima che l'associazione dei falsificatori ci trovi, o potremmo avere tutto l'anno.
+
+[CNT2_B5:COUNT2]
+In ogni caso, voglio veder bigliettoni verdi uscire cinque minuti dopo che sarò tornato. Tutto chiaro?
+
+[CNT2_B6:COUNT2]
+Non preoccuparti, Tommy. Saremo pronti.
+
+[CNT2_B7:COUNT2]
+Io e i ragazzi saremo in giro per il quartiere se mai dovessi avere bisogno di una mano con gli inseguitori.
+
+[CNT2_B8:COUNT2]
+Ottimo: siete tutti pronti? Perfetto. Ci vediamo più tardi...
+
+[CNT2_01:COUNT2]
+~g~Il ~r~corriere~g~ con le matrici arriverà fra pochi attimi al ~y~porto~g~ in elicottero.
+
+[CNT2_02:COUNT2]
+~r~Il corriere è scappato con l'elicottero.
+
+[CNT2_03:COUNT2]
+~r~Il corriere è arrivato a destinazione sano e salvo. Sei in ritardo!
+
+[CNT2_04:COUNT2]
+~r~Hai distrutto le matrici nell'esplosione!
+
+[CNT2_05:COUNT2]
+~g~Hai preso le matrici. Riportale alla tipografia.
+
+[CNT2_06:COUNT2]
+~g~Il corriere è morto e ha lasciato cadere le matrici: raccoglile prima che lo faccia qualcun altro.
+
+[CNT2_07:COUNT2]
+~g~Una delle guardie ha raccolto le matrici: non lasciarlo scappare!
+
+[CNT2_08:COUNT2]
+~g~Il ~r~corriere~g~ con le matrici è arrivato al porto.
+
+[CNT2_4:COUNT2]
+Faccende private, non sei il ben venuto.
+
+[CNT2_09:COUNT2]
+BENI TIPOGRAFIA ACQUISITI
+
+[CNT2_10:COUNT2]
+~g~La tipografia d'ora in poi genererà introiti per un massimo di ~1~$. Ricordati di recuperarli regolarmente.
+
+[CNT2_11:COUNT2]
+~r~Le matrici adesso sono in fondo all'oceano!
+
+{=================================== MISSION TABLE CUBAN1 ===================================}
+
+[CUB1_A:CUBAN1]
+Sì amico?
+
+[CUB1_B:CUBAN1]
+Ehi, tranquillo papà, è venuto per me. Sei tu l'uomo?
+
+[CUB1_C:CUBAN1]
+Oh sì, sei tu l'uomo. Credo per lo meno, vero?
+
+[CUB1_D:CUBAN1]
+No, non credo.
+
+[CUB1_E:CUBAN1]
+Ah sì? Vieni qua, osso duro.
+
+[CUB1_F:CUBAN1]
+Pensi di potermi prendere in giro?
+
+[CUB1_G:CUBAN1]
+Credi di poter fare lo stupido con me?
+
+[CUB1_H:CUBAN1]
+No, credo tu stia facendo abbastanza lo stupido per entrambi.
+
+[CUB1_I:CUBAN1]
+Ehi figliolo, ha detto che sei stupido.
+
+[CUB1_J:CUBAN1]
+E io lo chiamo femminuccia, papà.
+
+[CUB1_K:CUBAN1]
+Guarda un po' come va in giro vestito.
+
+[CUB1_L:CUBAN1]
+Che cos'è questa? L'ultima moda femminile per la notte?
+
+[CUB1_M:CUBAN1]
+Perché un osso duro come te si veste da donnina?
+
+[CUB1_N:CUBAN1]
+Hai le mutandine come le signorine, eh?
+
+[CUB1_O:CUBAN1]
+Cos'hai contro le donne? Preferisci gli uomini, amico?
+
+[CUB1_P:CUBAN1]
+Mi piacciono le donne! Tutte le donne! Adoro mia madre, chico.
+
+[CUB1_Q:CUBAN1]
+Va bene, va bene, ti credo sulla parola.
+
+[CUB1_R:CUBAN1]
+Sai guidare, amigo?
+
+[CUB1_S:CUBAN1]
+Certo... come una donna.
+
+[CUB1_T:CUBAN1]
+Molto divertente. Mi piaci, ragazzo. Forse ci puoi aiutare.
+
+[CUB1_U:CUBAN1]
+Potresti provare di essere un uomo. Huh?
+
+[CUB1_V:CUBAN1]
+Porta fuori la barca.
+
+[CUB1_W:CUBAN1]
+Mostra di avere due grossi cojones,
+
+[CUB1_X:CUBAN1]
+e non piccoli minuscoli chiquita.
+
+[CUB1_02:CUBAN1]
+OK amico, trattala come una vera signora.
+
+[CUB1_03:CUBAN1]
+Non male, sei un vero uomo.
+
+[CUB1_04:CUBAN1]
+Accidenti, hai davvero due grossi cojones, amigo.
+
+[CUB1_05:CUBAN1]
+Amigo, sei un vero uomo.
+
+[CUB1_06:CUBAN1]
+E tu ti reputi un uomo?
+
+[CUB1_07:CUBAN1]
+Sei un piccolo gattino impaurito, bamboccio: vai a piangere dalla mamma!
+
+[CUB1_08:CUBAN1]
+Sei un grande spreco di spazio. Cammini come un uomo, parli come un uomo, ma guidi come un idiota.
+
+[CUB1_09:CUBAN1]
+Amico, sei tu l'uomo. Mi piaci, amico. Mi piaci molto.
+
+[CUB1_10:CUBAN1]
+A qualsiasi ora, amico, perché tu hai i cojones e tutti i miei amici hanno grandi cajones.
+
+[CUB1_11:CUBAN1]
+~r~Hai ucciso Rico!
+
+[CUB1_12:CUBAN1]
+Passa per il primo punto di controllo per cominciare il test.
+
+[CUB1_14:CUBAN1]
+Torna alla barca!
+
+[CUB1_15:CUBAN1]
+~r~Sei troppo lento, amico.
+
+[CUB1_01:CUBAN1]
+Ehi, sono Rico. Sei tu l'uomo con i grandi cojones?
+
+[CUB1_13:CUBAN1]
+~g~Hai tre minuti per completare il percorso.
+
+{=================================== MISSION TABLE CUBAN2 ===================================}
+
+[CUB2_A:CUBAN2]
+Un cafecito, por favor, Alberto...
+
+[CUB2_N:CUBAN2]
+Nessun problema, Tommy.
+
+[CUB2_B:CUBAN2]
+Papà! Un gran problema!
+
+[CUB2_O:CUBAN2]
+Umberto, figlio mio, cosa succede?
+
+[CUB2_C:CUBAN2]
+Gli Haitiani! Odio quei maledetti Haitiani!
+
+[CUB2_D:CUBAN2]
+Hanno osato crearmi problemi per l'ultima vota!
+
+[CUB2_E:CUBAN2]
+Questi Haitiani. Facciamoli fuori!
+
+[CUB2_F:CUBAN2]
+Avremo bisogno di supporto.
+
+[CUB2_G:CUBAN2]
+Ho già perso degli hermanos là fuori.
+
+[CUB2_H:CUBAN2]
+Amigo, tu guidi bene!
+
+[CUB2_I:CUBAN2]
+Per una donna, giusto?
+
+[CUB2_J:CUBAN2]
+Non è il momento degli scherzi!
+
+[CUB2_K:CUBAN2]
+Forza, guida nuovamente per me!
+
+[CUB2_L:CUBAN2]
+Porta i miei ragazzi in posizione e faremo fuori quegli Haitiani!
+
+[CUB2_M:CUBAN2]
+Si sono messi contro me, hanno scherzato con il pezzo grosso della città!
+
+[CUB2_01:CUBAN2]
+Troppo piccola, amico, devi prendere una macchina più grande.
+
+[CUB2_02:CUBAN2]
+Abbiamo bisogno di rinforzi dal café!
+
+[CUB2_03:CUBAN2]
+~g~Prendi una macchina e recupera i Cubani di fronte al café Robina.
+
+[CUB2_04:CUBAN2]
+~g~Scarica i Cubani sul luogo dello scontro.
+
+[CUB2_05:CUBAN2]
+Fai fuori quel codardo di un cecchino!
+
+[CUB2_07:CUBAN2]
+Combattono come donnicciole! Mettetevi al riparo!
+
+[CUB2_09:CUBAN2]
+Cecchino sul tetto!
+
+[CUB2_11:CUBAN2]
+~r~Idiota, avevamo bisogno della macchina.
+
+[CUB2_12:CUBAN2]
+Ehi amigo! Sono felice che ce l'hai fatta.
+
+[CUB2_13:CUBAN2]
+Covo puzzolente di Haitiani, li uccideremo tutti!
+
+[CUB2_14:CUBAN2]
+CAAARICAAAA!
+
+[CUB2_15:CUBAN2]
+Adesso, fratelli, CAAARICAAAA!
+
+[CUB2_16:CUBAN2]
+Tommy, abbiamo provato il nostro coraggio!
+
+[CUB2_17:CUBAN2]
+Rubiamo quel van pieno di droga e scappiamo in fretta!
+
+[CUB2_18:CUBAN2]
+~g~Recupera una macchina per caricare i Cubani.
+
+[CUB2_19:CUBAN2]
+Combatteremo come uomini!
+
+[CUB2_21:CUBAN2]
+Combattiamo come uomini con grandi cojones!
+
+[CUB2_22:CUBAN2]
+~g~Elimina il resto degli Haitiani così i Cubani potranno avanzare.
+
+[CUB2_23:CUBAN2]
+~g~Little Haiti sarà piena di Haitiani desiderosi di pareggiare il conto con i Cubani. Guardati la schiena.
+
+[CUB2_24:CUBAN2]
+~g~Torna al Café Robina con il van e parcheggialo sul retro.
+
+[CUB2_25:CUBAN2]
+UCCIDI TUTTI GLI HAITIANI!!!
+
+{=================================== MISSION TABLE CUBAN3 ===================================}
+
+[CUB3_A:CUBAN3]
+Alberto. Un caffè, senor.
+
+[CUB3_B:CUBAN3]
+Papà, non servire questo serpente nascosto nella paglia.
+
+[CUB3_C:CUBAN3]
+Sei un doppiogiochista, Tommy!
+
+[CUB3_D:CUBAN3]
+O fai il doppio gioco o sei un perdente, ragazzo!
+
+[CUB3_E:CUBAN3]
+Gli Haitiani! Merda, stanno ridendo di me.
+
+[CUB3_F:CUBAN3]
+Ehi. Calmati. Qual è il tuo problema?
+
+[CUB3_G:CUBAN3]
+Ridono di me, Tommy! Di me!
+
+[CUB3_H:CUBAN3]
+Umberto Robina! Fanno tutto ciò che vogliono!
+
+[CUB3_I:CUBAN3]
+Nessuno fa ciò che vuole, Umberto, fanno ciò che tu permetti loro di fare.
+
+[CUB3_J:CUBAN3]
+Cosa?
+
+[CUB3_K:CUBAN3]
+Vuoi che mi occupi di qualcuno?
+
+[CUB3_L:CUBAN3]
+Posso pensarci io, ma ti costerà.
+
+[CUB3_M:CUBAN3]
+Lo so che siamo come fratelli, ma stiamo parlando di affari.
+
+[CUB3_N:CUBAN3]
+Tommy, sei un vero uomo. Un vero businessman, un gentleman.
+
+[CUB3_O:CUBAN3]
+Questi Haitiani. Hanno un carico di merce in arrivo via mare, roba di prima qualità.
+
+[CUB3_P:CUBAN3]
+La prendiamo e li facciamo fuori.
+
+[CUB3_Q:CUBAN3]
+Tu la prendi, io ti copro. Come mio fratello, come mio figlio.
+
+[CUB3_R:CUBAN3]
+Preferisco i soldi che saltellare sulle tue gambe, amigo.
+
+[CUB3_01:CUBAN3]
+Ehi Rico, bella barca. Sei pronto?
+
+[CUB3_03:CUBAN3]
+~g~Raccogli tutte le valigette piene di soldi e droga.
+
+[CUB3_04:CUBAN3]
+~g~Riporta la droga e i soldi a Umberto.
+
+[CUB3_05:CUBAN3]
+Sì Tommy. Vedi di sparare come si deve oggi,
+
+[CUB3_06:CUBAN3]
+non voglio riempire la mia barca di buchi, OK?
+
+[CUB3_07:CUBAN3]
+~g~Incontrati con Rico, lui ti porterà fino alla locazione dell'incontro.
+
+[CUB3_02:CUBAN3]
+~g~UCCIDI TUTTI GLI HAITIANI SULLE BARCHE!!!
+
+[CUB3_08:CUBAN3]
+Uh oh... un gruppo di Cubani. Siamo sotto attacco!
+
+{=================================== MISSION TABLE CUBAN4 ===================================}
+
+[CUB4_A:CUBAN4]
+Ehi signorine, sapete che cosa voglio fare?
+
+[CUB4_B:CUBAN4]
+Voglio far fuori un Haitiano. E poi?
+
+[CUB4_C:CUBAN4]
+Poi voglio fare l'amore come un vero uomo.
+
+[CUB4_D:CUBAN4]
+Capito chica? Proprio così.
+
+[CUB4_E:CUBAN4]
+Fallito!
+
+[CUB4_F:CUBAN4]
+Cafone.
+
+[CUB4_G:CUBAN4]
+Ehi bella, non ti toccherei neanche con un bastone da lontano!
+
+[CUB4_H:CUBAN4]
+Umberto Robina, a lui piacciono le vere donne! Non delle capre in minigonna!
+
+[CUB4_I:CUBAN4]
+Tommy! Tommy, ti voglio bene, davvero! Andiamo!
+
+[CUB4_J:CUBAN4]
+Dove? Non posso prendere prima una tazza di caffè?
+
+[CUB4_K:CUBAN4]
+Non c'è tempo per il caffè! Inoltre, io l'ho già preso.
+
+[CUB4_L:CUBAN4]
+Dobbiamo far fuori gli Haitiani.
+
+[CUB4_M:CUBAN4]
+Tommy, come fai a uccidere un serpente?
+
+[CUB4_N:CUBAN4]
+Lo mordi sul culo! Ah ah ah!
+
+[CUB4_O:CUBAN4]
+Se lo dici te, Umberto.
+
+[CUB4_P:CUBAN4]
+Tommy, recupera una piccola auto Haitiana.
+
+[CUB4_Q:CUBAN4]
+Quando ce l'hai, torna qui e carica il mio ragazzo,
+
+[CUB4_R:CUBAN4]
+Pepe, e portalo fino agli Haitiani.
+
+[CUB4_S:CUBAN4]
+Poi aggiri l'impianto di lavorazione degli Haitiani e utilizzi il solvente come esplosivo.
+
+[CUB4_T:CUBAN4]
+Boom! Bye bye!
+
+[CUB4_U:CUBAN4]
+Umberto, e tu?
+
+[CUB4_V:CUBAN4]
+Oh, io resto nelle retrovie e controllo il café con papà.
+
+[CUB4_W:CUBAN4]
+Non si sente molto bene, sai?
+
+[CUB4_02:CUBAN4]
+~g~Le bombe verranno piazzate con un timer di 45 secondi.
+
+[CUB4_04:CUBAN4]
+~r~Hai allarmato la base, adesso non riusciremo mai a entrare!
+
+[CUB4_07:CUBAN4]
+Il solvente è sul retro, amigo.
+
+[CUB4_08:CUBAN4]
+Hola, Amigos.
+
+[CUB4_09:CUBAN4]
+Bueno. Haitiane Putas. Muerte.
+
+[CUB4_10:CUBAN4]
+Vamos.
+
+[CUB4_11:CUBAN4]
+Vamos davvero.
+
+[CUB4_12:CUBAN4]
+Ehi, abbiamo bisogno di un'auto degli Haitiani!
+
+[CUB4_13:CUBAN4]
+Oye, andiamo a trovare i nostri muchachos!
+
+[CUB4_14:CUBAN4]
+Seguimi, compadres.
+
+[CUB4_15:CUBAN4]
+OK, vai dentro...
+
+[CUB4_16:CUBAN4]
+Io posizionerò le bombe, coprimi!
+
+[CUB4_17:CUBAN4]
+CORRI!
+
+[CUB4_18:CUBAN4]
+Amico, questa sì che è una bella parte della città...
+
+[CUB4_19:CUBAN4]
+Questo luogo è una fogna.
+
+[CUB4_20:CUBAN4]
+Avevo una bella donna... viveva da queste parti.
+
+[CUB4_21:CUBAN4]
+Lo sai, fanno delle buone pizze da queste parti.
+
+[CUB4_22:CUBAN4]
+Whoa, amico. Guidi come un cavallo impazzito!
+
+[CUB4_23:CUBAN4]
+Ti sei perso, amico?
+
+[CUB4_24:CUBAN4]
+Hai lasciato indietro Pepe, vai a riprenderlo!
+
+[CUB4_03:CUBAN4]
+~g~Resta in macchina fino a quando questa non sarà parcheggiata all'interno.
+
+[CUB4_26:CUBAN4]
+~g~Prendi Pepe, dirigiti a nord verso Little Haiti e ruba una macchina Voodoo.
+
+[CUB4_27:CUBAN4]
+~g~Raggiungi Rico e gli altri Cubani.
+
+[CUB4_28:CUBAN4]
+~g~Unisciti agli altri Cubani presso la fabbrica di droga Haitiana.
+
+[CUB4_29:CUBAN4]
+~g~Cammina su ogni segnalino per posizionare una bomba.
+
+[CUB4_30:CUBAN4]
+~g~Dopo aver posizionato tutte e tre le bombe, scappa dalla fabbrica prima che esploda.
+
+[CUB4_31:CUBAN4]
+~g~Scappa dalla fabbrica!!!
+
+[CUB4_32:CUBAN4]
+~g~Parcheggia l'auto nel punto segnalato ed esci.
+
+[CUB4_06:CUBAN4]
+~r~Non ti sei allontanato a sufficienza dalla base e abbiamo dovuto interrompere l'esplosione!
+
+{=================================== MISSION TABLE FINALE ===================================}
+
+[FIN_1A:FINALE]
+Vieni qui brutto doppiogiochista di merda!
+
+[FIN_1B:FINALE]
+Ti faccio a pezzi, traditore del cazzo!
+
+[FIN_1C:FINALE]
+Questo è l'ultimo ballo per Lance Vance!
+
+[FIN_2B:FINALE]
+Oh, ma davvero!
+
+[FIN_2C:FINALE]
+Te l'avevo detto che ne avevo avuto abbastanza a scuola!
+
+[FIN_3:FINALE]
+Adesso chi ti coprirà il culo, eh Tommy?
+
+[FIN_4:FINALE]
+Sei storia, Tommy, storia!
+
+[FIN_5:FINALE]
+Hai scelto il lato sbagliato, Lance...
+
+[FIN_11A:FINALE]
+Sonny, mi hai rubato quindici anni di vita...
+
+[FIN_11B:FINALE]
+E adesso te la farò pagare!
+
+[FIN_12A:FINALE]
+Non hai ancora capito, vero?
+
+[FIN_12B:FINALE]
+Io ti POSSIEDO, Tommy.
+
+[FIN_12C:FINALE]
+Quei quindici anni erano miei!
+
+[FIN_13:FINALE]
+Prendetelo ragazzi, non ha mai capito niente.
+
+[FIN1_01:FINALE]
+Cosa sta succedendo?
+
+[FIN1_02:FINALE]
+Tommy! Oh bene, bene. Ascolta, ascolta. Uh, ascolta.
+
+[FIN1_03:FINALE]
+A me piacciono i pesci. Adoro i pesci.
+
+[FIN1_04:FINALE]
+Mi piacciono quando nuotano in una boccia o come cibo in un piatto,
+
+[FIN1_05:FINALE]
+ma per quanto li ami, non voglio dormire in loro compagnia.
+
+[FIN1_06:FINALE]
+Va bene, ma adesso i tuoi fratelli italiani stanno venendo per mettermi ai piedi delle belle scarpe in cemento e io...
+
+[FIN1_07:FINALE]
+Sta zitto Ken. Siediti.
+
+[FIN1_08:FINALE]
+Lance, di che diavolo stai parlando?
+
+[FIN1_09:FINALE]
+Sono i tuoi amici del nord, Tommy. Non sono felici di cosa hai fatto al loro uomo.
+
+[FIN1_10:FINALE]
+Oggi verranno giù per questioni di lavoro.
+
+[FIN1_11:FINALE]
+Ci hanno messo di più di quanto credessi...
+
+[FIN1_12:FINALE]
+Ragazzi, dobbiamo essere molto chiari. Non voglio che ci siano dubbi sul fatto che questa è la mia operazione. MIA!
+
+[FIN1_13:FINALE]
+Ken, recupera la prima partita di soldi falsi e metti venti milioni in delle valigette.
+
+[FIN1_14:FINALE]
+Lance, raduna i ragazzi...
+
+[FIN2_01:FINALE]
+Tommy!
+
+[FIN2_02:FINALE]
+Cosa? Niente abbraccio per un vecchio amico?
+
+[FIN2_03:FINALE]
+Sono stato per quindici anni fuori dal giro,
+
+[FIN2_04:FINALE]
+sono un po' arrugginito in fatto di etichetta familiare.
+
+[FIN2_05:FINALE]
+Sempre arrabbiato, vero Tommy?
+
+[FIN2_06:FINALE]
+Non ti avevo detto che il tuo carattere ti avrebbe messo nei guai, eh?
+
+[FIN2_07:FINALE]
+Ci sono venti milioni in quelle valigette...
+
+[FIN2_08:FINALE]
+Quanti hai detto? Dieci? No, undici uomini.
+
+[FIN2_09:FINALE]
+È così che sei diventato il macellaio di Harwood! Eh eh eh!
+
+[FIN2_10:FINALE]
+Mi hai inviato per uccidere un uomo, UN UOMO. Sapevano che stavo arrivando Sonny...
+
+[FIN2_11:FINALE]
+Modera il tono.
+
+[FIN2_12:FINALE]
+Qualcuno potrebbe pensare che stai incolpando me per le sfortunate circostanze.
+
+[FIN2_13:FINALE]
+Prendi i fottuti soldi...
+
+[FIN2_14:FINALE]
+Prendi i fottuti soldi?
+
+[FIN2_15:FINALE]
+Lo sai, Tommy? Ho fatto quello che ho potuto per te. Ho tirato i fili, ho chiesto favori.
+
+[FIN2_16:FINALE]
+Ero tuo amico, Tommy. Pensavo che avresti avuto buon senso, che avresti capito cosa è bene per il business.
+
+[FIN2_17:FINALE]
+Mi fidavo di te, Tommy. E tu mi hai deluso.
+
+[FIN2_18:FINALE]
+Ma alla fine qualcuno nella tua organizzazione del cazzo ha capito come si fa il business.
+
+[FIN2_19:FINALE]
+Non è vero, Lance?
+
+[FIN2_20:FINALE]
+Mi dispiace Tommy. Questa è Vice City. Questo è il suo business.
+
+[FIN2_21:FINALE]
+Ci hai venduto...
+
+[FIN2_22:FINALE]
+No. Ho venduto TE, Tommy, ho venduto TE.
+
+[FIN2_23:FINALE]
+I soldi veri sono di sopra nella cassaforte.
+
+[FIN2_24:FINALE]
+Allora Tommy, questo era il grande piano?
+
+[FIN2_25:FINALE]
+Pensavi davvero che avrei preso i soldi finti?
+
+[FIN2_26:FINALE]
+Salva la faccia e scappa con la coda tra le gambe!
+
+[FIN2_27:FINALE]
+No.
+
+[FIN2_28:FINALE]
+Volevo solo farti incazzare prima di ucciderti.
+
+[FIN3_01:FINALE]
+Tommy?
+
+[FIN3_02:FINALE]
+Oh mio Dio, Tommy! Che cosa è successo?
+
+[FIN3_03:FINALE]
+Che cosa ti sembra sia successo?
+
+[FIN3_04:FINALE]
+Mi sembra ti si sia rovinato l'abito!
+
+[FIN3_05:FINALE]
+Accidenti, Tommy, era così bello! Tommy, che diavolo è successo?
+
+[FIN3_06:FINALE]
+Ho avuto una divergenza di vedute con un socio in affari, sai come vanno queste cose.
+
+[FIN3_07:FINALE]
+Tommy, se io ho una divergenza con un socio, gli mando una lettera di insulti.
+
+[FIN3_08:FINALE]
+Forse gli piscio nella casella della posta. Ma non do il via alla terza guerra mondiale!
+
+[FIN3_09:FINALE]
+Lo sai, forse dovresti parlare con il mio strizzacervelli...
+
+[FIN3_10:FINALE]
+Quello stupido idiota, Lance...
+
+[FIN3_11:FINALE]
+Tommy, non mi è mai piaciuto quel tipo, OK?
+
+[FIN3_12:FINALE]
+È nevrotico, insicuro, egocentrico... quel tipo è un vero stronzo!
+
+[FIN3_13:FINALE]
+Sono felice che l'hai fatto fuori!
+
+[FIN3_14:FINALE]
+Non penso che riceveremo ulteriori problemi dal nord...
+
+[FIN3_15:FINALE]
+...fondamentalmente perché non c'è più un 'nord'.
+
+[FIN3_16:FINALE]
+Adesso è tutto a sud.
+
+[FIN3_17:FINALE]
+Aspetta, vuoi forse dire ciò che penso io, caro il mio Tommy?
+
+[FIN3_18:FINALE]
+Cosa credi che significhi?
+
+[FIN3_19:FINALE]
+Che siamo in carica... cioè, che sei in carica! Oh Tommy...
+
+[FIN3_20:FINALE]
+Lo sai, Ken, questo potrebbe essere l'inizio di uno splendido rapporto lavorativo...
+
+[FIN3_21:FINALE]
+Dopo tutto, tu sei un convincente, diffamante, fottuto ladro.
+
+[FIN3_22:FINALE]
+e io sono uno psicopatico assassino convinto e uno spacciatore.
+
+[FIN3_23:FINALE]
+Lo so, non è meraviglioso?
+
+[FIN_B1:FINALE]
+~g~Uccidi ~y~Vance~g~, il fottuto traditore.
+
+[FIN_B2:FINALE]
+~g~Trova ~p~Sonny~g~ e metti la parola fine a questa storia.
+
+[FIN_B3:FINALE]
+~g~La Mafia sta cercando di rubare i tuoi soldi. Difendi la cassaforte.
+
+[FIN_B4:FINALE]
+~g~Sei prossimo alla morte: recupera della ~w~salute~g~ dal basso.
+
+[FIN_B5:FINALE]
+~g~La Mafia sta rubando i tuoi soldi. Difendi la ~c~cassaforte~g~.
+
+[FIN_B7:FINALE]
+~r~La Mafia ha rubato i tuoi soldi!
+
+[DEFSAFE:FINALE]
+~g~Ritorna alla cassaforte e difendila.
+
+{=================================== MISSION TABLE FIRETRK ===================================}
+
+[F_PASS1:FIRETRK]
+Incendio spento!
+
+[F_FAIL2:FIRETRK]
+~r~Sei arrivato tardi!
+
+[F_CANC:FIRETRK]
+~r~Missione Pompieri annullata!
+
+[F_EXTIN:FIRETRK]
+INCENDI:
+
+[F_START:FIRETRK]
+~g~Veicolo in fiamme avvistato in ~a~. Vai a spegnere il fuoco.
+
+[SIREN_1:FIRETRK]
+Per attivare la sirena di questo veicolo premi il ~h~~k~~VEHICLE_HORN~~w~.
+
+[SIREN_2:FIRETRK]
+Per attivare la sirena di questo veicolo premi il ~h~~k~~VEHICLE_HORN~~w~.
+
+[FIREPRO:FIRETRK]
+Missione Camion dei pompieri livello 12 completata: adesso sei permanentemente ignifugo!!!
+
+[F_FAIL1:FIRETRK]
+Missione Camion dei pompieri terminata.
+
+[F_STAR1:FIRETRK]
+~g~Veicoli in fiamme presso l'area ~a~. Vai a spegnere l'incendio.
+
+[SPRAY_4:FIRETRK] { reVC update }
+Premi il tasto ~h~~k~~VEHICLE_FIREWEAPON~~w~ per sparare con il cannone ad acqua e la ~h~~k~~VEHICLE_TURRETLEFT~~w~ e ~h~~k~~VEHICLE_TURRETRIGHT~~w~ per mirare.
+
+[SPRAY_1:FIRETRK] { reVC update }
+Premi il tasto ~h~~k~~VEHICLE_FIREWEAPON~~w~ per sparare con il cannone ad acqua e la ~h~~k~~VEHICLE_TURRETLEFT~~w~ e ~h~~k~~VEHICLE_TURRETRIGHT~~w~ per mirare.
+
+{=================================== MISSION TABLE GENERA1 ===================================}
+
+[GEN1_A:GENERA1]
+Mr. Vercetti!
+
+[GEN1_B:GENERA1]
+Colonnello.
+
+[GEN1_D:GENERA1]
+No, grazie.
+
+[GEN1_E:GENERA1]
+Mi vergogno ad ammettere che una delle cause dei nostri problemi comuni sembra sia stata la linguaccia di una persona di cui credevo di potermi fidare.
+
+[GEN1_F:GENERA1]
+Mi sono tenuto Gonzalez per anni, ma ora la sua incompetenza ha raggiunto il fondo.
+
+[GEN1_G:GENERA1]
+Sarebbe solo un bene se eliminassi Gonzalez...
+
+[GEN1_H:GENERA1]
+È stato lui? A me importa solo dei miei soldi.
+
+[GEN1_I:GENERA1]
+Questa gentilezza verrà ricompensata dopo troveremo insieme i tuoi soldi.
+
+[GEN1_J:GENERA1]
+Lo troverai nella sua Penthouse, probabilmente mezzo ubriaco. Usa questo...
+
+[GEN1_06:GENERA1]
+Eeek! Ha una motosega!
+
+[GEN1_07:GENERA1]
+Stammi lontano, brutto bastardo!
+
+[GEN1_08:GENERA1]
+Oddio santo, ho distrutto la mia vita e il mio look!
+
+[GEN1_10:GENERA1]
+Ho deciso di chiudere quella tua maledetta boccaccia!
+
+[GEN1_11:GENERA1]
+Smettila di correre, brutto grassone!
+
+[GEN1_12:GENERA1]
+Stai fermo, così la facciamo finita!
+
+[GEN1_13:GENERA1]
+Smettila di strillare, non gliene frega a nessuno, grassone!
+
+[GEN1_C:GENERA1]
+Grazie per essere venuto. Siediti. Vuoi dell'aragosta?
+
+[GEN1_05:GENERA1]
+~g~Uccidi Gonzalez!
+
+[GEN1_09:GENERA1]
+Ti pagherò doppio, Tommy, DOPPIO!
+
+[GEN1_18:GENERA1]
+~r~Gonzalez ha raggiunto sano e salvo la stazione di polizia!
+
+[GEN1_19:GENERA1]
+~g~La polizia di Vice City ti sta inseguendo!
+
+[GEN1_20:GENERA1]
+~g~Prendi un veicolo.
+
+[GEN1_21:GENERA1]
+~g~Raggiungi il ~h~Pay 'N' Spray~g~ in ~h~Vice Point~g~.
+
+[GEN1_22:GENERA1]
+~g~Guida il tuo veicolo attraverso il carrozziere per perdere il ~h~livello di sospetto~g~, ~h~riparare~g~ e ~h~ricolorare~g~ il mezzo. Costo: ~h~100$~g~. Questa volta è gratis.
+
+[GEN1_01:GENERA1]
+Quando corri, tieni premuto il ~o~tasto |~w~ per preparare un attacco corpo a corpo.
+
+[GEN1_02:GENERA1]
+Quando corri, tieni premuto il ~x~tasto /~w~ per preparare un attacco corpo a corpo.
+
+[GEN1_03:GENERA1]
+Quando corri, tieni premuto il ~h~tasto R1~w~ per preparare un attacco corpo a corpo.
+
+[GEN1_14:GENERA1]
+Rilascia il ~h~~k~~PED_FIREWEAPON~~w~ per eseguire l'attacco.
+
+[GEN1_15:GENERA1]
+Rilascia il ~h~~k~~PED_FIREWEAPON~~w~ per eseguire l'attacco.
+
+[GEN1_16:GENERA1]
+Rilascia il ~h~~k~~PED_FIREWEAPON~~w~ per eseguire l'attacco.
+
+[GEN1_23:GENERA1]
+~g~Passa per le porte per tornare al piano terra.
+
+{=================================== MISSION TABLE GENERA2 ===================================}
+
+[COL2_A:GENERA2]
+Tommy! Vieni qui da me.
+
+[COL2_B:GENERA2]
+Non ti sembra delizioso, vero? Lingua di Tapia?
+
+[COL2_C:GENERA2]
+Eerr... No, no grazie.
+
+[COL2_D:GENERA2]
+Tommy, sei come un vento fresco della pampa che mi libera dall'olezzo della corruzione,
+
+[COL2_E:GENERA2]
+benché mi addolori la recente dipartita, devo continuare come sempre con il mio lavoro.
+
+[COL2_F:GENERA2]
+Non mi sembra ci stiamo avvicinando ai miei soldi...
+
+[COL2_G:GENERA2]
+Tommy, amico mio, non sei più a Liberty. Qui le cose vanno in modo diverso.
+
+[COL2_H:GENERA2]
+Continuerò le mie ricerche, ma nel frattempo ho un interessante accordo da proporti.
+
+[COL2_I:GENERA2]
+Un favore per un amico, Cortez.
+
+[COL2_J:GENERA2]
+Sei un vero amico, Tommy, Ero certo che non mi avresti deluso.
+
+[COL2_K:GENERA2]
+Ho bisogno che tu incontri un corriere che mi ha recuperato una tecnologia di cui ho bisogno...
+
+[COL2_1:GENERA2]
+La pioggia, è così très umido in questo periodo dell'anno...
+
+[COL2_2:GENERA2]
+Cosa?
+
+[COL2_3:GENERA2]
+Ah, comment?
+
+[COL2_4:GENERA2]
+Ascolta, mi manda Cortez. Dammi quei maledetti chip.
+
+[COL2_5:GENERA2]
+Oh... d'accord.
+
+[COL2_B1:GENERA2]
+~g~Incontra il corriere al Mall.
+
+[COL2_B2:GENERA2]
+~g~Il correre sta scappando con i chip: non farlo scappare!
+
+[COL2_B3:GENERA2]
+~g~Porta i chip al Colonnello.
+
+[COL2_F1:GENERA2]
+~r~Hai ucciso il contatto!
+
+[COL2_F2:GENERA2]
+~r~Il corriere è morto. Raccogli i chip.
+
+[COL2_6A:GENERA2]
+Fermo, brutto maiale imperialista americano! Questa è proprietà del governo francese. Passamela!
+
+[BLIPHLP:GENERA2]
+Se il segnale sul radar è un triangolo verso l'alto, significa che il bersaglio è in posizione più elevata rispetto al giocatore.
+
+[COL2_F3:GENERA2]
+~r~I chip adesso riposano in fondo all'oceano.
+
+[COL2_F4:GENERA2]
+~r~Il corriere è scappato! Non sei riuscito a recuperare i chip.
+
+{=================================== MISSION TABLE GENERA3 ===================================}
+
+[GEN3_A:GENERA3]
+Thomas, grazie per essere venuto.
+
+[GEN3_B:GENERA3]
+Perdonami se giungo subito al punto.
+
+[GEN3_C:GENERA3]
+Diaz mi ha chiesto di sovrintendere una piccola transizione di lavoro.
+
+[GEN3_D:GENERA3]
+Speriamo vada meglio dell'ultima...
+
+[GEN3_E:GENERA3]
+Ed è per questo che ho pensato a te, amico.
+
+[GEN3_F:GENERA3]
+Ho lasciato un po' di supporto al parcheggio multipiano.
+
+[GEN3_G:GENERA3]
+Raccogli il materiale, poi raggiungi e sorveglia gli uomini di Diaz all'incontro.
+
+[GEN3_H:GENERA3]
+Gracias, amigo.
+
+[GEN3_1:GENERA3]
+Ami l'azione, vedo...
+
+[GEN3_2:GENERA3]
+Senti, ti capita mai di fare qualcos'altro che non sia seguirmi dappertutto? Perché non vieni con me e mi dimostri di servire a qualcosa?
+
+[GEN3_3:GENERA3]
+Potrei anche farlo. A proposito, mi chiamo Lance.
+
+[GEN3_5:GENERA3]
+Devi essere il nuovo uomo di Cortez.
+
+[GEN3_6:GENERA3]
+Fino a quando non mi capiteranno opportunità più lucrose.
+
+[GEN3_7:GENERA3]
+Arriveranno fra pochi minuti: meglio trovare un buon punto dove appostarsi...
+
+[GEN3_8:GENERA3]
+OK! Io prendo il balcone, tu prendi il tetto dall'altra parte del cortile.
+
+[GEN3_9:GENERA3]
+Sono vivo, brutti stronzi! E tutto grazie a te! Come ti chiami?
+
+[GEN3_10:GENERA3]
+Tommy.
+
+[GEN3_11:GENERA3]
+Ci incontreremo di nuovo, credo!
+
+[GEN3_12:GENERA3]
+Dove diavolo è andato Lance? Merda...
+
+[GEN3_14:GENERA3]
+Tommy! Ho bisogno di aiuto!
+
+[GEN3_15:GENERA3]
+Non preoccuparti, ti copro io!
+
+[GEN3_16:GENERA3]
+Gli uomini di Diaz si stanno facendo massacrare!
+
+[GEN3_19:GENERA3]
+~g~Haitiani! Stanno mandando a monte l'affare! Proteggi Diaz!
+
+[GEN3_20:GENERA3]
+~g~Entra nel parcheggio multipiano e recupera ciò che il Colonnello ha lasciato per te.
+
+[GEN3_22:GENERA3]
+Salute di Diaz:
+
+[GEN3_23:GENERA3]
+~g~Hai lasciato Lance indietro! Vallo a prendere!
+
+[GEN3_25:GENERA3]
+~r~Lance è morto!
+
+[GEN3_28:GENERA3]
+~g~Riporta la valigetta a Diaz.
+
+[GEN3_29:GENERA3]
+~g~Raccogli la valigetta e riportala a Diaz.
+
+[GEN3_30:GENERA3]
+~r~È scappato con i soldi! Diaz ti strapperà le palle per questo!
+
+[GEN3_33:GENERA3]
+~r~Dovresti proteggere Diaz e i suoi uomini, non sparargli addosso!
+
+[GEN3_34:GENERA3]
+~r~Non ci sarà nessun accordo se spari ai Cubani!
+
+[GEN3_35:GENERA3]
+~g~Ha rubato i soldi di Diaz!
+
+[GEN3_36:GENERA3]
+~g~Prendi la moto, inseguilo e recupera i soldi di Diaz!
+
+[GEN3_37:GENERA3]
+~g~Stanno arrivando i Cubani. Assicurati che niente vada storto e proteggi Diaz e Lance.
+
+[GEN3_38:GENERA3]
+~r~Diaz è morto! Non sei riuscito a proteggerlo!
+
+[GEN3_39:GENERA3]
+~g~Raggiungi la tua postazione sopra alle scale.
+
+[GEN3_44:GENERA3]
+~g~Vai con Lance all'appuntamento e proteggi Diaz.
+
+[GEN3_40:GENERA3] { reVC update }
+Per ~h~sparare davanti~w~ su una ~h~moto~w~ premi il ~h~~k~~VEHICLE_FIREWEAPON~~w~.
+
+[GEN3_41:GENERA3] { reVC update }
+Per ~h~sparare davanti~w~ su una ~h~moto~w~ premi il ~h~~k~~VEHICLE_FIREWEAPON~~w~.
+
+[GEN3_46:GENERA3]
+Meerda!
+
+[GEN3_47:GENERA3]
+Tommy!
+
+[GEN3_48:GENERA3]
+Maledizione!
+
+[GEN3_49:GENERA3]
+SALUTE DI LANCE:
+
+[GEN3_50:GENERA3]
+~r~Hai distrutto i soldi di Diaz! La prossima volta cerca di non ridurre le banconote in cenere!
+
+[GEN3_51:GENERA3]
+Altri fottuti Haitiani in un merdoso van!
+
+[GEN3_54:GENERA3]
+Non restare lì impalato, idiota, insegui quello stronzo di un Haitiano!
+
+[GEN3_55:GENERA3]
+Tommy! Io resto qua a proteggere Diaz!
+
+[GEN3_18:GENERA3]
+~g~Stanno arrivando i Cubani, resta vicino a Diaz. Assicurati che niente vada storto e proteggi Diaz e Lance.
+
+[GEN3_56:GENERA3]
+~r~Diaz è stato assalito e ucciso! La prossima volta, cerca di proteggerlo!
+
+[GEN3_57:GENERA3]
+Il Kruger è un fucile d'assalto che permette di mirare in prima persona.
+
+[GEN3_58:GENERA3]
+Tieni premuto il tasto ~h~R1~w~ per ~h~mirare~w~ con il fucile d'assalto.
+
+[GEN3_59:GENERA3]
+Tieni premuto il tasto ~h~L1~w~ per ~h~mirare~w~ col fucile d'assalto.
+
+[GEN3_60:GENERA3]
+Premi il tasto ~h~~k~~PED_FIREWEAPON~~w~ per ~h~sparare~w~ col fucile d'assalto.
+
+[GEN3_61:GENERA3]
+Premi il tasto ~h~~k~~PED_FIREWEAPON~~w~ per ~h~sparare~w~ col fucile d'assalto.
+
+[GEN3_62:GENERA3]
+Premi il tasto ~h~~k~~PED_FIREWEAPON~~w~ per ~h~sparare~w~ col fucile d'assalto.
+
+[GEN3_63:GENERA3]
+Oltre a permetterti di sparare in corsa, con le ~h~moto~w~ puoi anche ~h~sparare in avanti~w~.
+
+[GEN3_64:GENERA3] { reVC update }
+Per sparare in avanti quando sei su una moto, premi il tasto ~h~~k~~VEHICLE_FIREWEAPON~~w~.
+
+[GEN3_65:GENERA3] { reVC update }
+Per sparare in avanti quando sei su una moto, premi il tasto ~h~~k~~VEHICLE_FIREWEAPON~~w~.
+
+[GEN3_66:GENERA3] { reVC update }
+Per sparare in avanti quando sei su una moto, premi il tasto ~h~~k~~VEHICLE_FIREWEAPON~~w~.
+
+[GEN3_67:GENERA3]
+Hai bisogno di una mitragliatrice per poter sparare in avanti.
+
+[GEN3_53:GENERA3]
+I MIEI SOLDI!
+
+[GEN3_52:GENERA3]
+Questi Haitiani pensano che possono farsi RICARDO DIAZ!?!
+
+{=================================== MISSION TABLE GENERA4 ===================================}
+
+[DETON:GENERA4]
+DETONAZIONE:
+
+[COL4_3:GENERA4]
+CONVOGLIO ALT!
+
+[COL4_6:GENERA4]
+SIAMO SOTTO FUOCO NEMICO!
+
+[COL4_7:GENERA4]
+Civile, si allontani dal carro armato!
+
+[COL4_8:GENERA4]
+HO DETTO, si allontani, IMMEDIATAMENTE!
+
+[COL4_9:GENERA4]
+POSIZIONI DIFENSIVE!
+
+[COL4_11:GENERA4]
+Porta via quel civile, soldato! - Signorsì, signore!
+
+[COL4_12:GENERA4]
+Civile nel CARRO ARMATO! FERMATELO!
+
+[COL4_13:GENERA4]
+Questo è un convoglio militare, non ostacoli il passaggio.
+
+[COL4_14:GENERA4]
+Fallo fuori, soldato.
+
+[COL4_15:GENERA4]
+Spostate quel veicolo civile via dalla strada! -Signore! Sposto il veicolo, signore!
+
+[COL4_17:GENERA4]
+OK, PLOTONE, IN MARCIA!
+
+[COL4_18:GENERA4]
+Qualcuno è entrato nel carro armato, signore!
+
+[COL4_19:GENERA4]
+Vai a prendere delle ciambelle, soldato! - Signorsì, signore!
+
+[COL4_20:GENERA4]
+Bersaglio acquisito, signore!
+
+[COL4_21:GENERA4]
+CECCHINO!
+
+[COL4_22:GENERA4]
+Io me la squaglio.
+
+[COL4_23:GENERA4]
+Obiettivo completato! Plotone riposo! -Andiamo a mangiarci qualche ciambella.
+
+[COL4_24:GENERA4]
+Protocollo di sicurezza Delta India Echo attivato! Autodistruzione del veicolo attivata!
+
+[COL4_26:GENERA4]
+Preparati a morire, maledetto comunista!
+
+[COL4_B2:GENERA4]
+~r~Il carro armato è arrivato con successo a destinazione!
+
+[COL4_B5:GENERA4]
+~r~Il carro armato è stato distrutto!
+
+[COL4_01:GENERA4]
+Diaz era soddisfatto e vorrebbe incontrarti nuovamente.
+
+[COL4_02:GENERA4]
+È un buon segno?
+
+[COL4_03:GENERA4]
+Ma certo! Benché credo che Diaz sia il responsabile della nostra sfortunata perdita...
+
+[COL4_04:GENERA4]
+Che cosa glielo fa pensare?
+
+[COL4_05:GENERA4]
+Nessuno accusa direttamente un uomo come Diaz... sto solo pensando a voce altra...
+
+[COL4_06:GENERA4]
+Non importa. Ho una proposta che potrebbe interessarti...
+
+[COL4_07:GENERA4]
+Non ho più tempo per i suoi lavori, Cortez.
+
+[COL4_08:GENERA4]
+Pensavo che un uomo con dei debiti così pericolosi fosse desideroso di opportunità. Per favore, Tommy, almeno ascoltami.
+
+[COL4_09:GENERA4]
+Mi dica...
+
+[COL410:GENERA4]
+Ho un acquirente per un mezzo militare che sta attraversando la città. Recuperalo per me...
+
+[COL411:GENERA4]
+e, quando lo avrai, vorrei che mi chiamassi immediatamente. Poi...
+
+[COL4_B4:GENERA4]
+~g~Il carro armato è chiuso. Trova un modo per far uscire gli occupanti.
+
+[COL4_1:GENERA4]
+Che cos'ha il mitragliatore? -Non so signore!
+
+[COL4_4:GENERA4]
+-Vai di sopra, soldato. -Signorsì, signore!
+
+[COL4_B1:GENERA4]
+~g~Impadronisciti del mezzo militare che sta attraversando la città.
+
+[COL4_B3:GENERA4]
+~g~Porta il carro armato al garage del Colonnello prima che si autodistrugga.
+
+[COL4_B6:GENERA4]
+~g~Trova un modo per rubare il carro armato!
+
+[COL4_B7:GENERA4]
+~g~Porta il carro armato dentro al garage.
+
+[COL4_B8:GENERA4]
+~g~Esci dal carro armato e abbandona il garage.
+
+{=================================== MISSION TABLE GENERA5 ===================================}
+
+[COL5A_1:GENERA5]
+Le circostanze richiedono una rapida partenza, amigo.
+
+[COL5A_2:GENERA5]
+Qual è il problema?
+
+[COL5A_3:GENERA5]
+Uh, i Francesi rivogliono la loro tecnologia missilistica indietro dopo quell'incidente...
+
+[COL5A_4:GENERA5]
+Sento che è giunta l'ora di partire per porti più sicuri.
+
+[COL5A_5:GENERA5]
+Non sarebbe meglio via aria?
+
+[COL5A_6:GENERA5]
+Sarei morto ancor prima di raggiungere il check-in. Inoltre, devo portare la mia merce fuori dal paese.
+
+[COL5A_7:GENERA5]
+Serve un'altra pistola?
+
+[COL5A_8:GENERA5]
+Tu, amico, vali come dieci pistole... ah ah ah!
+
+[COL5B_1:GENERA5]
+Thomas, mi hai protetto e servito bene.
+
+[COL5B_2:GENERA5]
+Ma adesso devi abbandonarci prima che raggiungiamo il mare aperto.
+
+[COL5B_4:GENERA5]
+Grazie mille, Colonnello.
+
+[COL5B_5:GENERA5]
+Un'ultima richiesta, mentre sono via: terresti un occhio su Mercedes per me?
+
+[COL5B_6:GENERA5]
+Credo sappia badare a sé stessa, ma certo, la terrò sott'occhio.
+
+[COL5B_7:GENERA5]
+Grazie mille, amico. A presto!
+
+[COL5B_8:GENERA5]
+Adios, amigo.
+
+[COL5_7:GENERA5]
+Smettila di spararmi!
+
+[COL5_9:GENERA5]
+Tommy, falli smettere di sparare!
+
+[COL5_10:GENERA5]
+Ho l'immunità diplomatica!
+
+[COL5_11:GENERA5]
+Non sparare, sono il Colonnello!
+
+[COL5_12:GENERA5]
+Thomas, uccidili: la mia nazione ti sarà riconoscente.
+
+[COL5_13:GENERA5]
+Tommy, siamo assaliti dai Francesi!
+
+[COL5_14:GENERA5]
+Tommy, dovunque guardo vedo dei Francesi. Io li odio!
+
+[COL5_15:GENERA5]
+Tommy, come stai?
+
+[COL5_16:GENERA5]
+Questo è per la Piaf e Gainesbourg e per le vostre stupide baguette!
+
+[COL5_1:GENERA5]
+A babordo! A babordo!
+
+[COL5_2:GENERA5]
+Ci attaccano da tribordo!
+
+[COL5_3:GENERA5]
+Il ponte qui davanti!
+
+[COL5_4:GENERA5]
+Hanno un elicottero!
+
+[COL5_B1:GENERA5]
+~g~Difendi a tutti i costi il Colonnello e il suo yacht.
+
+[COL5_B2:GENERA5]
+~g~Vai a prua e libera la strada per il passaggio dello yacht del Colonnello.
+
+[COL5_B3:GENERA5]
+~r~Il Colonnello è morto!
+
+[COL5_B4:GENERA5]
+~g~Abbatti l'elicottero!
+
+[COL5B_3:GENERA5]
+Farò calare la mia lancia personale. Tienila, amico, un pegno della mia gratitudine.
+
+[COL5_B5:GENERA5]
+~g~Abbatti gli elicotteri e proteggi lo yacht.
+
+[COL5_B6:GENERA5]
+~g~Hai finito i colpi: recuperane altri dalle scale al ponte superiore.
+
+[COL5_B7:GENERA5]
+~g~Sei a corto di salute: recuperane altra dalle scale al ponte superiore
+
+{=================================== MISSION TABLE HAIT1 ===================================}
+
+[HAM1_A:HAIT1]
+Permesso?
+
+[HAM1_B:HAIT1]
+Entra pure, caro, e riposa l'anima.
+
+[HAM1_C:HAIT1]
+Devi essere il grande uomo cattivo di cui parlava mio nonno.
+
+[HAM1_D:HAIT1]
+Mi ha raccontato di te, sai, quando mi fa visita,
+
+[HAM1_E:HAIT1]
+e degli altri che ti aspettano.
+
+[HAM1_F:HAIT1]
+Adesso, siamo tutti morti da tempo, ma tu sai,
+
+[HAM1_G:HAIT1]
+non vorrei essere nei tuoi panni, eh eh eh!
+
+[HAM1_H:HAIT1]
+Ho ricevuto un messaggio. Sono venuto.
+
+[HAM1_I:HAIT1]
+Li puoi sentire?
+
+[HAM1_J:HAIT1]
+Stanno chiamando il tuo nome, devono proprio volerti, non credi?
+
+[HAM1_K:HAIT1]
+Magari adesso dai una mano alla zia Poulet, uh, e forse lei ti aiuta.
+
+[HAM1_L:HAIT1]
+Forse potrà darti un piccolo juju dopo tutto questo.
+
+[HAM1_M:HAIT1]
+Un po' di magia per dare all'uomo di legge il malocchio, hmmm?
+
+[HAM1_N:HAIT1]
+Ascolta, tutto questo è, uhm... darmi cosa?
+
+[HAM1_O:HAIT1]
+Credo, credo proprio di aver sbagliato indirizzo...
+
+[HAM1_P:HAIT1]
+Fai per me questo favore, Tommy...
+
+[HAM1_Q:HAIT1]
+I Cubani, foofoo molto orgogliosi, hmmm,
+
+[HAM1_R:HAIT1]
+hanno dato molti grattacapi ai miei ragazzi Haitiani.
+
+[HAM1_S:HAIT1]
+Adesso hanno detto alla polizia dove nascondo le mie polveri.
+
+[HAM1_T:HAIT1]
+Pensano sia droga, gli stupidi.
+
+[HAM1_U:HAIT1]
+Adesso fai il bravo, Tommy, e vai a prendere le polveri per la zia Poulet.
+
+[HAM1_V:HAIT1]
+Sì, sì, certo, vado.
+
+[HAM1_1:HAIT1]
+~g~I poliziotti si stanno avvicinando alle nostre riserve. Fermali prima che ci riescano.
+
+[HAM1_2:HAIT1]
+~r~I poliziotti sono arrivati per primi alla riserva!
+
+[HAM1_3:HAIT1]
+~g~Riporta questa roba al nascondiglio!
+
+[HAM1_4:HAIT1]
+~g~Ottimo! Adesso pensa al prossimo!
+
+[HAM1_6:HAIT1]
+~r~La riserva è stata distrutta, idiota!
+
+[HAM1_7:HAIT1]
+~g~La polizia ha preso la nostra riserva! Recuperala prima che se ne vada!
+
+[HAM1_8:HAIT1]
+~g~I poliziotti sono vicini alla riserva: datti una mossa!
+
+[HAT_1A:HAIT1]
+~g~Non muoverti, allocco!
+
+{=================================== MISSION TABLE HAIT2 ===================================}
+
+[HAT2_B1:HAIT2]
+~g~Raggiungi il van che contiene le bombe volanti.
+
+[HAT2_B2:HAIT2]
+Uccidi i Cubani...
+
+[HAT2_B4:HAIT2]
+...e distruggi le loro imbarcazioni!
+
+[HAT2_B5:HAIT2]
+~g~I Cubani stanno fuggendo: non lasciarli scappare!
+
+[HAT2_B6:HAIT2]
+~r~L'aereo radiocomandato si sta allontanando dal raggio d'azione!
+
+[HAT2_B7:HAIT2]
+~g~Uno dei Cubani sta fuggendo in macchina. Non lasciare nessun testimone!
+
+[HAT2_B8:HAIT2]
+~g~Non hai più aerei radiocomandati!
+
+[HAT2_B9:HAIT2]
+Aerei radiocomandati:
+
+[HAT2_1:HAIT2]
+Oh. Scusa, devo aver sbagliato indirizzo...
+
+[HAT2_2:HAIT2]
+Puoi entrare comunque a riposare i piedi e a bere un po' di tè.
+
+[HAT2_3:HAIT2]
+Hai qualcosa per me, Tommy?
+
+[HAT2_4:HAIT2]
+Sì...
+
+[HAT2_5:HAIT2]
+Questo posto mi sembra familiare. Un odore della mia gioventù... un deja vu...
+
+[HAT2_6:HAIT2]
+Adesso Tommy, ti sussurrerò una piccola commissione che devi farmi. Ascoltami attentamente, va bene?
+
+[HAT2_7:HAIT2]
+Mi ricordi qualcuno che...
+
+[HAT2_8:HAIT2]
+I Cubani hanno imbarcazioni molto veloci che utilizzano per trasportare la droga via mare.
+
+[HAT2_9:HAIT2]
+È il loro modo di vivere.
+
+[HAT2_10:HAIT2]
+Mio nipote ha costruito delle simpatiche bombe per farli fuori.
+
+[HAT2_11:HAIT2]
+Fai esplodere le barche e inchioda le loro bare.
+
+[HAT2_12:HAIT2]
+Beh, grazie per il tè.
+
+[HAT2_B3:HAIT2] { reVC update }
+Premi il ~h~~k~~VEHICLE_FIREWEAPON~~w~ per sganciare una bomba. Premi il ~h~~k~~VEHICLE_ENTER_EXIT~ "~w~ per annullare.
+
+{=================================== MISSION TABLE HAIT3 ===================================}
+
+[HAM3_A:HAIT3]
+Salve, salve, io, uh... Stavo cercando qualcuno...
+
+[HAM3_B:HAIT3]
+Mi sembri affamato, Tommy.
+
+[HAM3_C:HAIT3]
+Ci conosciamo?
+
+[HAM3_D:HAIT3]
+Zitto ora.
+
+[HAM3_E:HAIT3]
+Un'ultima cosa e potrai andare, Tommy.
+
+[HAM3_F:HAIT3]
+I miei ragazzi sono in guerra con i Cubani.
+
+[HAM3_G:HAIT3]
+Ma niente pistole.
+
+[HAM3_H:HAIT3]
+Hmmm, ma i Cubani hanno una sorpresa in serbo.
+
+[HAM3_I:HAIT3]
+Mentre combattono per la strada, tu prendi questo fucile e li elimini durante la confusione.
+
+[HAM3_J:HAIT3]
+Nessuno ti vede, nessuno ti sente.
+
+[HAM3_K:HAIT3]
+Adesso, Tommy, fai questo per me e non sarai più aggrappato al mio grembiule.
+
+[HAM3_1:HAIT3]
+~g~Dobbiamo vincere questa battaglia. Se tutti gli Haitiani muoiono, sarà la fine.
+
+[HAM3_3:HAIT3]
+~g~Sospetto che i Cubani bareranno, per cui stai in guardia.
+
+[HAM3_4:HAIT3]
+~r~Ti hanno visto! La missione è fallita!
+
+[HAM3_5:HAIT3]
+~g~Devi eliminare i Cubani da lontano. Non devono vederti.
+
+[HAM3_8:HAIT3]
+~g~Gli Haitiani stanno morendo! Migliora la tua mira!
+
+[HAM3_7:HAIT3]
+~g~Attento! I Cubani hanno chiamato rinforzi. Uccidili tutti quanti!
+
+[HAM3_2:HAIT3]
+~r~Gli Haitiani sono morti!
+
+[HAM3_L:HAIT3]
+Sssì zia...
+
+{=================================== MISSION TABLE HOTEL ===================================}
+
+[INTB_A:HOTEL]
+Tommy! Tommy, quanto tempo è passato!
+
+[INTB_B:HOTEL]
+Ciao Sonny.
+
+[INTB_C:HOTEL]
+Lo so, lo so, sei sopraffatto dall'emozione.
+
+[INTB_D:HOTEL]
+Quindici anni... sembra come se fosse ieri.
+
+[INTB_E:HOTEL]
+Credo dipenda dal punto di vista.
+
+[INTB_F:HOTEL]
+Ehi, stare dentro per la famiglia non è una passeggiata,
+
+[INTB_G:HOTEL]
+ma la famiglia si preoccupa dei suoi, OK?
+
+[INTB_H:HOTEL]
+Allora, raccontami come è andata... Eri in ballo con l'oro bianco?
+
+[INTB_I:HOTEL]
+Ascolta Sonny, ci avevano incastrato. L'incontro era un'imboscata. Harry e Lee sono morti.
+
+[INTB_J:HOTEL]
+Basta con queste storie, Tommy. Hai ancora i soldi, vero?
+
+[INTB_K:HOTEL]
+...no Sonny... non ho i soldi.
+
+[INTB_L:HOTEL]
+Quelli erano i miei soldi, Tommy, I MIEI SOLDI!
+
+[INTB_M:HOTEL]
+Non cercare di fottermi, Tommy, perché sai che non sono una persona a cui piace essere presa per il culo!
+
+[INTB_N:HOTEL]
+Aspetta Sonny.
+
+[INTB_O:HOTEL]
+Hai la mia parola che recupererò i tuoi soldi e la droga.
+
+[INTB_P:HOTEL]
+E ti farò avere per posta l'uccello dei responsabili.
+
+[INTB_Q:HOTEL]
+Ehi, ne sono certo. Non sei uno stupido, Tommy, ma ti avverto: non lo sono neanch'io.
+
+[INTB_R:HOTEL]
+Se fosse stato qualcun altro, adesso sarebbe già MORTO.
+
+[INTB_S:HOTEL]
+Ma visto che sei tu, che ci conosciamo da tempo, ti permetterò di gestire la situazione.
+
+[INTB_T:HOTEL]
+Ehi, Sonny, hai la mia parola.
+
+[INTB_U:HOTEL]
+Mi farò vivo.
+
+{=================================== MISSION TABLE ICECRE1 ===================================}
+
+[ICC1_4:ICECRE1]
+~g~Non ci sono clienti in quest'area, prova in un'altra.
+
+[ICC1_5:ICECRE1]
+Transazioni effettuate:
+
+[ICC1_7:ICECRE1]
+~g~Riceverai soldi per ogni transazione, ma più ne esegui, maggiori saranno le probabilità di attirare l'attenzione della polizia.
+
+[ICC1_8:ICECRE1]
+~g~Per eseguire una transazione, ~h~parcheggia il camioncino~g~ e premi il ~h~~k~~VEHICLE_HORN~~g~ per suonare il campanello e attrarre i clienti.
+
+[ICC1_9:ICECRE1]
+~g~Le gang locali non apprezzeranno il tuo lavoro nel loro territorio, per cui aspettati azioni ostili.
+
+[ICC1_10:ICECRE1]
+~g~Hai portato a termine ~1~ transazioni!
+
+[ICC1_11:ICECRE1]
+~g~Hai portato a termine ~1~ transazione!
+
+[ICC1_13:ICECRE1]
+~r~Non hai portato a termine nessuna transazione.
+
+[ICC1_14:ICECRE1]
+BENI FABBRICA DI GELATO ACQUISITI
+
+[ICC1_15:ICECRE1]
+~g~La fabbrica di gelato d'ora in poi genererà introiti per un massimo di ~1~$. Ricordati di recuperarli regolarmente.
+
+[ICC1_16:ICECRE1]
+~g~Utilizza il Mr. Whoopee per distribuire i prodotti Cherry Poppers per Vice City.
+
+[ICE_AT1:ICECRE1]
+FABBRICA DI GELATO COMPLETATA
+
+[ICE_AT2:ICECRE1]
+~g~La fabbrica Cherry Popper d'ora in poi genererà introiti per un massimo di ~1~$. Ricordati di recuperarli regolarmente.
+
+[ICC1_17:ICECRE1]
+Missione di distribuzione terminata.
+
+[ICC1_18:ICECRE1]
+Vendita totale gelati: ~1~$
+
+[ICC1_19:ICECRE1]
+Transizioni totali eseguite: ~1~
+
+{=================================== MISSION TABLE ICECUT ===================================}
+
+[ICC1_A:ICECUT]
+Chi sei?
+
+[ICC1_B:ICECUT]
+Il nuovo proprietario.
+
+[ICC1_C:ICECUT]
+Sei per caso, o lo sei mai stato, un bambino?
+
+[ICC1_D:ICECUT]
+Ma di cosa stai parlando?
+
+[ICC1_E:ICECUT]
+Sei stato un bambino?
+
+[ICC1_F:ICECUT]
+Certo! Calmati! Che ti prende?
+
+[ICC1_G:ICECUT]
+Lo sapevo. Un bambino.
+
+[ICC1_H:ICECUT]
+Uno sporco, puzzolente, moccioso, lamentoso, vile, vomitevole, piagnucoloso piccolo bambino!
+
+[ICC1_I:ICECUT]
+Un bambino... un mostruoso, orribile disgustoso piccolo bambino. Boo hoo.
+
+[ICC1_J:ICECUT]
+La mamma non ti ama, brutto piccolo avanzo!
+
+[ICC1_K:ICECUT]
+Ow! Accidenti, calmati!
+
+[ICC1_L:ICECUT]
+Io ODIO i bambini, odio i poppanti.
+
+[ICC1_M:ICECUT]
+Sono sporchi, puzzolenti, mocciosi, vomitevoli piccoli...
+
+[ICC1_N:ICECUT]
+Ne ho avuto abbastanza!
+
+[ICC1_O:ICECUT]
+Ma che diavolo hai?
+
+[ICC1_P:ICECUT]
+Tu fai gelati, vero? Sono solo per bambini.
+
+[ICC1_Q:ICECUT]
+Ma che psicopatica sei?
+
+[ICC1_R:ICECUT]
+È così mi sono chiesta: perché fare felici i bambini se li odio?
+
+[ICC1_S:ICECUT]
+Oh, stupidi, schifosi, mocciosi...
+
+[ICC1_T:ICECUT]
+Sta zitta!
+
+[ICC1_U:ICECUT]
+...Monellaccio!
+
+[ICC1_V:ICECUT]
+La gelateria è solo una facciata.
+
+[ICC1_W:ICECUT]
+Noi distribuiamo altro, prodotti non caseari.
+
+[ICC1_X:ICECUT]
+E se vedo un bambino, non perdo occasione.
+
+[ICC1_Y:ICECUT]
+Non è vero, bambini? Sì, sì, lo faccio. La mamma non vi ama.
+
+[ICC1_Z:ICECUT]
+Lei vi ODIA!
+
+[ICC1_ZA:ICECUT]
+PROPRIETÀ ACQUISTATA!
+
+{=================================== MISSION TABLE INTRO ===================================}
+
+[INT1_A:INTRO]
+Tommy Vercetti... Ommerda!
+
+[INT1_B:INTRO]
+Pensavo non lo avrebbero mai rilasciato.
+
+[INT1_C:INTRO]
+Ha tenuto la testa bassa... molta gente ha dimenticato.
+
+[INT1_D:INTRO]
+Ma molti ricorderanno ben presto...
+
+[INT1_E:INTRO]
+Quando lo vedranno camminare per le strade del loro vicinato.
+
+[INT1_F:INTRO]
+Non sarà una cosa positiva per il business.
+
+[INT1_G:INTRO]
+Beh, che cosa facciamo, Sonny?
+
+[INT1_H:INTRO]
+Lo trattiamo come un amico e lo teniamo impegnato fuori città, OK?
+
+[INT1_I:INTRO]
+Parlavamo di espanderci verso sud, vero?
+
+[INT1_J:INTRO]
+Vice City è oro puro in questi giorni.
+
+[INT1_K:INTRO]
+I Colombiani, i Messicani, che diamine,
+
+[INT1_L:INTRO]
+anche i rifugiati Cubani si sono ritagliati una bella fetta della torta.
+
+[INT1_M:INTRO]
+Ma si tratta di droga, Sonny,
+
+[INT1_N:INTRO]
+nessuno delle famiglie toccherà quella merda!
+
+[INT1_O:INTRO]
+I tempi cambiano.
+
+[INT1_P:INTRO]
+Le famiglie non possono girare le spalle mentre i nostri nemici si godono il raccolto.
+
+[INT1_Q:INTRO]
+Per cui mandiamo qualcuno a fare il lavoro sporco
+
+[INT1_R:INTRO]
+e a prendere una bella fetta per noi, OK?
+
+[INT1_S:INTRO]
+Chi è il nostro contatto laggiù?
+
+[INT1_T:INTRO]
+Ken Rosenberg, uno schmuck di un avvocato.
+
+[INT1_U:INTRO]
+Come farà a tenere al guinzaglio Vercetti?
+
+[INT1_V:INTRO]
+Non dovrà farlo.
+
+[INT1_W:INTRO]
+Mandiamolo alla ribalta a Vice City
+
+[INT1_X:INTRO]
+con un po' di denaro per cominciare, OK?
+
+[INT1_Y:INTRO]
+Lasciamogli qualche mese.
+
+[INT1_Z:INTRO]
+Poi andiamo giù,
+
+[INT1_A1:INTRO]
+gli facciamo visita, giusto?
+
+[INT1_A2:INTRO]
+E vediamo come se la sta cavando...
+
+[INT2_A:INTRO]
+Ehi, ehi, amici! Sono, uh, Ken Rosenberg! Eh, eh, ottimo, ehi!
+
+[INT2_B:INTRO]
+Bene, uh, vi accompagno in auto all'appuntamento, OK?
+
+[INT2_C:INTRO]
+Ho parlato con i fornitori e loro sono molto, ehm,
+
+[INT2_D:INTRO]
+desiderosi di avviare una relazione commerciale, per cui, uh,
+
+[INT2_E:INTRO]
+se tutto dovesse andare come deve, noi, dovremmo, uh,
+
+[INT2_F:INTRO]
+ottenere dei buoni risultati economici, il che, cioè...
+
+[INT2_G:INTRO]
+è bene...
+
+[INT2_H:INTRO]
+OK allora. Sono fratelli, OK.
+
+[INT2_I:INTRO]
+Uno si occupa del, uh, business,
+
+[INT2_J:INTRO]
+mentre l'altro si occupa dei voli.
+
+[INT2_K:INTRO]
+Adesso operano dal Messico,
+
+[INT3_A:INTRO]
+OK, sono loro sull'elicottero.
+
+[INT3_B:INTRO]
+Bene, questo è l'accordo.
+
+[INT3_C:INTRO]
+Vogliono uno scambio diretto in campo aperto.
+
+[INT3_D:INTRO]
+Va bene? OK, nervi saldi, andiamo.
+
+[INT3_E:INTRO]
+Vedi di star calmo.
+
+[INT3_F:INTRO]
+Resto qui con l'auto pronta a partire!
+
+[INT3_G:INTRO]
+Chiaro?
+
+[INT3_H:INTRO]
+Colombiana 100% pura di prima classe, amici miei.
+
+[INT3_I:INTRO]
+I verdoni?
+
+[INT3_J:INTRO]
+Da dieci e da venti... usati.
+
+[INT3_L:INTRO]
+Forza, vieni qua! Muoviti!
+
+[INTRO1:INTRO]
+metto fuori la testa per un maledetto secondo, e il fato mi tira palate di merda in faccia!
+
+[INTRO2:INTRO]
+Vai a riposarti.
+
+[INTRO3:INTRO]
+Che cosa intendi fare?
+
+[INTRO4:INTRO]
+Passerò domani a trovarti in ufficio e troveremo un modo per risolvere questo casino.
+
+[INT3_K:INTRO]
+Siamo d'accordo allora, amico. AH AH!
+
+[INT3_M:INTRO]
+Fammi dare un'occhiata.
+
+[INT2_L:INTRO]
+no, no, no, aspetta...
+
+{=================================== MISSION TABLE KENT1 ===================================}
+
+[KPM1_A:KENT1]
+Ehi bello, ho delle informazioni sul tuo amico.
+
+[KPM1_B:KENT1]
+Ma di cosa stai parlando?
+
+[KPM1_C:KENT1]
+Conosci quel fallito di Diaz, il signore degli spacciatori?
+
+[KPM1_D:KENT1]
+Ha preso il tuo amico, Lance. Sembra che abbia cercato di scavalcarlo...
+
+[KPM1_E:KENT1]
+ma non ha saltato abbastanza in alto, se capisci cosa intendo.
+
+[KPM1_F:KENT1]
+Dove lo hanno portato? Senza giri di parole!
+
+[KPM1_G:KENT1]
+Stai calmo! Lo hanno trasportato attraverso la città fino alla discarica.
+
+[KPM1_H:KENT1]
+Maledizione... Brutto idiota.
+
+[KPM1_2:KENT1]
+~r~Dovevi portare Lance fuori vivo da lì!
+
+[KPM1_3:KENT1]
+SALUTE DI LANCE:
+
+[RESC_1:KENT1]
+Ce la fai a usare un'arma?
+
+[RESC_2:KENT1]
+Certo... credo... È bello rivederti!
+
+[RESC_3:KENT1]
+Andiamocene da qua.
+
+[RESC_4:KENT1]
+Bene, con questo hai mandato a puttane tutti i miei bei piani. L'hai proprio fatta grossa, Lance.
+
+[RESC_5:KENT1]
+Ha ucciso mio fratello. Che cosa ti aspettavi facessi, che gli tagliassi il prato?
+
+[RESC_6:KENT1]
+Dobbiamo far fuori quello stronzo di Diaz prima che sia lui a farlo.
+
+[RESC_7:KENT1]
+Preparati e incontriamoci al ponte di Star Island, OK?
+
+[RESC_8:KENT1]
+OK, ricevuto.
+
+[KPM1_1:KENT1]
+~g~Lance viene tenuto nella discarica: vai a salvarlo!
+
+[KPM1_4:KENT1]
+~g~Porta Lance all'ospedale!
+
+[M_PASSN:KENT1]
+MISSIONE COMPLETATA!
+
+[KPM1_5:KENT1]
+~g~Gli uomini di Diaz ti stanno dietro: porta Lance all'ospedale.
+
+{=================================== MISSION TABLE KICKSTT ===================================}
+
+[KICK1_2:KICKSTT]
+~r~Non sei tornato abbastanza velocemente alla tua moto!
+
+[KICK1_7:KICKSTT]
+~r~Hai distrutto la moto!
+
+[KICK1_8:KICKSTT]
+~g~Ritorna sulla moto!
+
+[KICK1_T:KICKSTT]
+TEMPO IMPIEGATO:
+
+[KICKTM:KICKSTT]
+~b~DURATA EVENTO: ~1~:~1~
+
+[KICKTM2:KICKSTT]
+~b~DURATA EVENTO: ~1~:0~1~
+
+[GETBIKE:KICKSTT]
+~g~Hai ~1~ secondi per tornare sulla tua moto prima che la missione abbia termine.
+
+[KICK1_1:KICKSTT]
+~g~Completa il tracciato il più velocemente possibile.
+
+[KICK1_6:KICKSTT]
+~g~Complimenti!
+
+[KICK_10:KICKSTT]
+~g~Usa il Sanchez per completare il percorso passando per tutti i punti di controllo.
+
+[KICK_12:KICKSTT]
+~g~Ti sei bloccato!
+
+[KICK_13:KICKSTT]
+~g~Ci hai messo troppo tempo!
+
+[KICK_11:KICKSTT]
+~g~Per abbandonare la missione, posizionati a piedi sul ~q~segnalino rosa~g~.
+
+{=================================== MISSION TABLE LAWYER1 ===================================}
+
+[LAW1_A:LAWYER1]
+Vai a riposarti un po', ha detto...
+
+[LAW1_B:LAWYER1]
+...ho passato tutta la sera su questa seggiola a bere caffè con la luce spenta.
+
+[LAW1_C:LAWYER1]
+È un disastro. Siamo veramente fottuti, amico!
+
+[LAW1_D:LAWYER1]
+Quei gorilla, non sto scherzando, verranno qui da me e mi staccheranno la testa. È ridicolo!
+
+[LAW1_E:LAWYER1]
+NON mi sono laureato in giurisprudenza per questo! Bene, dimmi un po': che cosa hai intenzione di fare?
+
+[LAW1_F:LAWYER1]
+Sta zitto, siediti e rilassati. Ti dirò che cosa faremo.
+
+[LAW1_G:LAWYER1]
+Tu dovrai scoprire chi ha preso la nostra cocaina... e io li farò fuori.
+
+[LAW1_H:LAWYER1]
+È una buona idea. Anzi, è un'OTTIMA idea. Fammici pensare, fammici pensare, fammici pensare.
+
+[LAW1_I:LAWYER1]
+Ah! C'è quel Colonnello in pensione, il Colonnello Juan Garcia Cortez.
+
+[LAW1_J:LAWYER1]
+È stato lui che mi ha aiutato a preparare il piano
+
+[LAW1_K:LAWYER1]
+ben lontano dai criminali di Vice City. OK?
+
+[LAW1_L:LAWYER1]
+Adesso ascolta: sta organizzando un party nella baia sul suo costoso yacht
+
+[LAW1_M:LAWYER1]
+e tutte le personalità di spicco di Vice City saranno presenti.
+
+[LAW1_N:LAWYER1]
+Io ho un invito, chiaramente ne ho uno...
+
+[LAW1_O:LAWYER1]
+ma non ho la minima intenzione di mettere la testa fuori dalla porta, per nessun motivo!
+
+[LAW1_P:LAWYER1]
+Te l'ho detto, sta zitto! Ci andrò io...
+
+[LAW1_Q:LAWYER1]
+Whoa, whoa, whoa! Ehi, anche a me piace lo stile del 78, ma, lo sai, non si tratta di una festa con birra e spogliarelliste.
+
+[LAW1_R:LAWYER1]
+Intendo dire, senza offesa, che molta gente potrebbe girarsi a guardarti per la ragione sbagliata...
+
+[LAW1_S:LAWYER1]
+Vuoi dire che c'è qualcosa che non va in come mi vesto?
+
+[LAW1_T:LAWYER1]
+OK, ascolta. Fermati da Rafael's, digli che ti mando io e lui si occuperà di renderti presentabile.
+
+[LAW1_U:LAWYER1]
+OK, forza, andiamo...
+
+[LAWP_1:LAWYER1]
+Buenas noches.
+
+[LAWP_2:LAWYER1]
+Da quanto ho capito, è qui per conto di Mr. Rosenberg.
+
+[LAWP_3:LAWYER1]
+Spero che gli avvenimenti recenti non abbiano avuto effetti sulla sua salute o, uh,
+
+[LAWP_4:LAWYER1]
+sulla sua sanità mentale, Mr...?
+
+[LAWP_5:LAWYER1]
+Vercetti. Ha solo avuto un attacco di... agorafobia.
+
+[LAWP_6:LAWYER1]
+Eccellente, eccellente. E lei?
+
+[LAWP_7:LAWYER1]
+Voglio solo la mia merce.
+
+[LAWP_8:LAWYER1]
+Ah. Si è trattato di sfortunate circostanze per tutte le persone coinvolte.
+
+[LAWP_9:LAWYER1]
+Chiaramente, ho dato il via a delle ricerche personali
+
+[LAWP_10:LAWYER1]
+ma una situazione così delicata richiede tempo.
+
+[LAWP_11:LAWYER1]
+Magari ne parleremo più tardi, va bene?
+
+[LAWP_12:LAWYER1]
+Nel frattempo, le presento mia figlia,
+
+[LAWP_13:LAWYER1]
+Mercedes!
+
+[LAWP_14:LAWYER1]
+Cara mia, perché non ti prendi cura del nostro ospite mentre io mi occupo delle mie cose?
+
+[LAWP_15:LAWYER1]
+Certamente, papà.
+
+[LAWP_16:LAWYER1]
+Mi scusi.
+
+[LAWP_17:LAWYER1]
+Mercedes?
+
+[LAWP_18:LAWYER1]
+Non è facile portare questo nome.
+
+[LAWP_19:LAWYER1]
+Comunque, lasci che le presenti alcuni dei nostri distinti ospiti...
+
+[LAWP_20:LAWYER1]
+Lui è Alex Shrub, il nostro deputato, con Candy Suxxx, la famosa star siliconata...
+
+[LAWP_21:LAWYER1]
+Avete conosciuto la mia dolce moglie, Laura?
+
+[LAWP_22:LAWYER1]
+Veramente questa è Candy, mia moglie si trova in Alabama ora.
+
+[LAWP_23:LAWYER1]
+E da quella parte abbiamo la stella dei Vice City Mambas, BJ.
+
+[LAWP_24:LAWYER1]
+un vero ammaliatore
+
+[LAWP_25:LAWYER1]
+L'ho placcato, davvero, e l'ho fatto finire su una sedia a rotelle!
+
+[LAWP_26:LAWYER1]
+Ah, ah, questa è buona!
+
+[LAWP_27:LAWYER1]
+Beh, adesso sto cercando di acquistare dei terreni di qualità.
+
+[LAWP_28:LAWYER1]
+E quella specie di anfibio da piscina è Jezz Torrent,
+
+[LAWP_29:LAWYER1]
+voce solista dei Love Fist.
+
+[LAWP_30:LAWYER1]
+Ve lo posso dire... sapete come giocano a ping-pong in Tailandia?
+
+[LAWP_31:LAWYER1]
+Da non crederci...
+
+[LAWP_32:LAWYER1]
+di certo, non richiede l'uso della racchetta, se capite cosa intendo!
+
+[LAWP_33:LAWYER1]
+Impotente.
+
+[LAWP_34:LAWYER1]
+E il loquace trio.
+
+[LAWP_35:LAWYER1]
+Quella pustola sudata e addormentata è il braccio destro di papà, Gonzalez,
+
+[LAWP_36:LAWYER1]
+mentre gli altri due sono il pastore Richards
+
+[LAWP_37:LAWYER1]
+e il regista pseudo-intellettuale, Steve Scott.
+
+[LAWP_38:LAWYER1]
+...pare che abbiano una passione per le ninfomani...
+
+[LAWP_39:LAWYER1]
+...quando lo squalo gigante arriva e
+
+[LAWP_40:LAWYER1]
+strappa a morsi i loro uccelli!
+
+[LAWP_41:LAWYER1]
+Ah! Non si è mai visto qualcosa del genere prima, vero?
+
+[LAWP_42:LAWYER1]
+Colonnello!
+
+[LAWP_43:LAWYER1]
+I suoi party sono sempre un successo! Ah ah ah!
+
+[LAWP_44:LAWYER1]
+Posso solo chiedere scusa per il mio ritardo.
+
+[LAWP_45:LAWYER1]
+Ah, de nada amigo. E come vanno gli affari?
+
+[LAWP_46:LAWYER1]
+Sai, sono molto difficili...i nemici sono sempre alle costole.
+
+[LAWP_47:LAWYER1]
+Il tempo di ricompensare gli amici e liquidare i nemici, amigo.
+
+[LAWP_48:LAWYER1]
+Chi è il chiacchierone?
+
+[LAWP_49:LAWYER1]
+Ricardo Diaz. È Mr. Coca.
+
+[LAWP_50:LAWYER1]
+Mercedes!
+
+[LAWP_51:LAWYER1]
+Oh, stavo giusto riaccompagnando i miei amici in città.
+
+[LAWP_52:LAWYER1]
+Un'altra volta, Ricardo!
+
+[LAWP_53:LAWYER1]
+Andiamocene.
+
+[LAWP_54:LAWYER1]
+Anzi, portatemi al club Pole Position.
+
+[LAW1_2:LAWYER1]
+~g~Raggiungi lo yacht del Colonnello.
+
+[LAW1_4:LAWYER1]
+~r~Hai ucciso la figlia del Colonnello!
+
+[LAW1_5:LAWYER1]
+Lavorerai per mio padre?
+
+[LAW1_6:LAWYER1]
+Forse.
+
+[LAW1_7:LAWYER1]
+Ti dispiace se appoggio la mano tra le tue gambe?
+
+[LAW1_8:LAWYER1]
+Forse...
+
+[LAW1_9:LAWYER1]
+È così difficile avere un padre ricco e potente. Vamos.
+
+[LAW1_10:LAWYER1]
+Ci vediamo in giro, stallone!
+
+[LAW1_11:LAWYER1]
+Sono sicuro di sì.
+
+[LAW1_12:LAWYER1]
+Hmmm... bella moto.
+
+[LAW1_13:LAWYER1]
+No! La mia moto!
+
+[LAW1_3:LAWYER1]
+~g~Porta la figlia del Colonnello al club Pole Position.
+
+[HELP20:LAWYER1]
+Segui il ~h~segnale a forma di maglietta~w~ per trovare Rafael's.
+
+[LAW1_14:LAWYER1]
+Accidenti, mi piace: la tua moto va alla grande.
+
+[LAW1_15:LAWYER1]
+Eh sì, l'ho appena presa da Howlin' Pete's.
+
+{=================================== MISSION TABLE LAWYER2 ===================================}
+
+[LAW2_A:LAWYER2]
+Ah! Beh, spero tu ti sia divertito. Io stavo quasi per impazzire dalla preoccupazione. Che cos'hai scoperto?
+
+[LAW2_B:LAWYER2]
+Che ci sono più criminali a piede libero in città che nella prigione. Abbiamo bisogno di qualcuno di strada...
+
+[LAW2_C:LAWYER2]
+OK, fammici pensare, fammici pensare, fammici pensare...
+
+[LAW2_D:LAWYER2]
+Ah! Trovato!
+
+[LAW2_E:LAWYER2]
+OK, c'è questo inglese, un tizio legato al campo della musica,
+
+[LAW2_F:LAWYER2]
+mi sembra si chiami Kent Paul.
+
+[LAW2_G:LAWYER2]
+Comunque, ha ficcato il naso nelle chiappe di metà della gente di Vice City
+
+[LAW2_H:LAWYER2]
+per cui, se qualcuno sa dove sono questi 20 chili di coca,
+
+[LAW2_I:LAWYER2]
+è sicuramente lui, chiaro? È sempre al Malibu.
+
+[LAW2_J:LAWYER2]
+Andrò a trovarlo.
+
+[LAW2B_A:LAWYER2]
+Ehi, da dove sbuchi?
+
+[LAW2B_B:LAWYER2]
+Ho cercato per anni un fiorellino come te, bellezza...
+
+[LAW2B_C:LAWYER2]
+Kent Paul, tesoro. Sì, sono il capo da queste parti.
+
+[LAW2B_D:LAWYER2]
+Sto cercando un tipo inglese...
+
+[LAW2B_E:LAWYER2]
+Risolvo i problemi, capisci cosa intendo?
+
+[LAW2B_F:LAWYER2]
+Ti tratterò bene: qualsiasi cosa tu voglia, te la farò avere, cara.
+
+[LAW2B_G:LAWYER2]
+Non preoccuparti di niente, bellezza.
+
+[LAW2B_H:LAWYER2]
+Vattene, tesoro.
+
+[LAW2B_I:LAWYER2]
+Oi oi oi oi oi!
+
+[LAW2B_J:LAWYER2]
+Sei Kent Paul? Sono un amico di Rosenberg...
+
+[LAW2B_K:LAWYER2]
+Rosenberg... Rosenberg... Oh, l'avvocato matto!
+
+[LAW2B_L:LAWYER2]
+Quel tipo potrebbe difendere un innocente fino alla sedia elettrica!
+
+[LAW2B_M:LAWYER2]
+Dacci un altro drink, amico.
+
+[LAW2B_N:LAWYER2]
+Un altro comico.
+
+[LAW2B_O:LAWYER2]
+Ascoltami: mi hanno soffiato venti chili e un sacco di contanti...
+
+[LAW2B_P:LAWYER2]
+Droga amico? È roba da delinquenti.
+
+[LAW2B_Q:LAWYER2]
+Che cosa ne sai?
+
+[LAW2B_R:LAWYER2]
+Oi oi! Ciò che volevo dire è
+
+[LAW2B_S:LAWYER2]
+che c'è uno chef che spaccia sottobanco nella cucina di un hotel su Ocean Drive.
+
+[LAW2B_T:LAWYER2]
+Recentemente, mi è sembrato molto felice di come gli buttava... Potresti passare a trovarlo e investigare...
+
+[LAW2B_U:LAWYER2]
+Lo farò... ci becchiamo in giro.
+
+[LAW2B_V:LAWYER2]
+Beh, sì certo! Vai, vai pure idiota. Ci penserò io a tenerti a bada!
+
+[LAW2B_W:LAWYER2]
+Dammi un bicchiere... e dov'è finita quella sgualdrina?
+
+[LAW2C_A:LAWYER2]
+Oh, ottimo lavoro, sei proprio un duro. Riducilo in poltiglia, questo sicuramente lo aiuterà a diventare più loquace!
+
+[LAW2C_B:LAWYER2]
+Ne vuoi anche tu?
+
+[LAW2C_C:LAWYER2]
+Ehi, calma. Quel che va bene a te, va bene a me, amico.
+
+[LAW2C_D:LAWYER2]
+Ah sì? E di cosa si tratta?
+
+[LAW2C_E:LAWYER2]
+I verdoni... e l'amica bianca del mio povero fratello. Sfortunatamente, hai appena fatto fuori il nostro contatto.
+
+[LAW2C_F:LAWYER2]
+Gli incidenti capitano. Scompari.
+
+[LAW2C_G:LAWYER2]
+Ehi, ehi, whoa. Non c'è bisogno di recitare la parte del 'Giustiziere solitario'.
+
+[LAW2C_H:LAWYER2]
+Io la vedo così: siamo due hombres in una strana città. Dobbiamo guardarci a vicenda le spalle.
+
+[LAW2C_I:LAWYER2]
+Le mie spalle stanno benissimo, fratello...
+
+[LAW2C_J:LAWYER2]
+Ne sei sicuro? Ehi, prendi questa.
+
+[LAW2C_K:LAWYER2]
+Seguimi!
+
+[LAW2_1:LAWYER2]
+Che cos'hai da guardare?
+
+[LAW2_2:LAWYER2]
+Ti conviene iniziare a parlare...
+
+[LAW2_3:LAWYER2]
+Maledetto stronzo!
+
+[LAW2_4:LAWYER2]
+Da questa parte!
+
+[LAW2_5:LAWYER2]
+Vediamo cosa riesco a scoprire. Ci vediamo, Tommy.
+
+[LAW2_6:LAWYER2]
+~g~Vai al Malibu e trova Kent Paul.
+
+[LAW2_7:LAWYER2]
+~g~Trova lo chef in Ocean Drive.
+
+[LAW2_10:LAWYER2]
+~g~Torna in macchina all'hotel.
+
+[LAW2_11:LAWYER2]
+~g~Raccogli il suo cellulare.
+
+[LAW2_12:LAWYER2]
+Cellulare acquisito! Adesso potrai ricevere telefonate!
+
+[LAW2_13:LAWYER2]
+~g~Hai lasciato Lance indietro! Vallo a prendere!
+
+[LAW2_14:LAWYER2]
+Andiamocene da qui!
+
+[GUN_2A:LAWYER2]
+Tieni premuto il ~h~~k~~PED_LOCK_TARGET~~w~ per la ~h~mira automatica~w~ e premi il ~h~~k~~PED_FIREWEAPON~~w~ per ~h~sparare~w~!
+
+[GUN_2C:LAWYER2]
+Tieni premuto il ~h~~k~~PED_LOCK_TARGET~~w~ per la ~h~mira automatica~w~ e premi il ~h~~k~~PED_FIREWEAPON~~w~ per ~h~sparare~w~!
+
+[GUN_2D:LAWYER2]
+Tieni premuto il ~h~~k~~PED_LOCK_TARGET~~w~ per la ~h~mira automatica~w~ e premi il ~h~~k~~PED_FIREWEAPON~~w~ per ~h~sparare~w~!
+
+[HELP17:LAWYER2]
+Premi il ~h~~k~~PED_FIREWEAPON~~w~ per attaccare lo chef.
+
+[HELP18:LAWYER2]
+Premi il ~h~~k~~PED_FIREWEAPON~~w~ per attaccare lo chef.
+
+[LAW3_11:LAWYER2]
+Posizionati sul ~q~segnalino rosa~w~ per vedere le armi in offerta.
+
+[LAW3_12:LAWYER2]
+Puoi selezionare l'arma premendo il ~h~tasto direzionale~w~ a ~h~sinistra~w~ o a ~h~destra~w~.
+
+[LAW3_13:LAWYER2]
+Se hai denaro a sufficienza puoi comprare armi premendo il ~h~~k~~PED_SPRINT~~w~.
+
+[LAW3_14:LAWYER2]
+Puoi uscire da un negozio premendo il ~h~~k~~VEHICLE_ENTER_EXIT~~w~.
+
+[LAW3_15:LAWYER2]
+Segui il ~h~segnale a forma di pistola~w~ per trovare ~h~Ammu-Nation~w~.
+
+[LAW2_15:LAWYER2]
+~g~Raggiungi Ammu-Nation.
+
+[LAW2_K:LAWYER2]
+Vedi di star calmo.
+
+[LAW2_16:LAWYER2]
+Devi sapere qualcosa su questa città: hai bisogno di potenza di fuoco.
+
+[LAW2_17:LAWYER2]
+Forza, l'armaiolo locale è solo a qualche isolato di distanza.
+
+[LAW2_18:LAWYER2]
+Tommy, tutti quanti hanno bisogno di un po' di relax ogni tanto.
+
+[LAW2_19:LAWYER2]
+Ecco il club a luci rosse Pole Position. Facci un salto ogni tanto.
+
+{=================================== MISSION TABLE LAWYER3 ===================================}
+
+[LAW3_A:LAWYER3]
+Aarrgh! Maledizione, sei tu! Oddio, avrò bisogno di un nuovo paio di pantaloni!
+
+[LAW3_B:LAWYER3]
+Ehi, quei psicopatici del nord hanno drizzato le orecchie e verranno a visitarci molto presto.
+
+[LAW3_C:LAWYER3]
+Dove diavolo sono i fottuti soldi?
+
+[LAW3_D:LAWYER3]
+Rilassati, rilassati. Non siamo ancora arrivati a questa parte.
+
+[LAW3_E:LAWYER3]
+Pensavo ti stessi prendendo cura di questo aspetto, davvero.
+
+[LAW3_F:LAWYER3]
+E adesso quei delinquenti si aspettano addirittura da noi un favore.
+
+[LAW3_G:LAWYER3]
+Vuoi dire che io devo far loro un favore.
+
+[LAW3_H:LAWYER3]
+Oh, beh, certo, proprio così. Credi davvero che potrei intimidire una giuria?
+
+[LAW3_I:LAWYER3]
+Non riuscirei a intimidire neppure un bambino... e credimi, ci ho provato.
+
+[LAW3_J:LAWYER3]
+Adesso o ci riusciamo, oppure il cugino di Forelli, Giorgio, si becca cinque anni per frode.
+
+[LAW3_K:LAWYER3]
+Devi CONVINCERE questi tipi!
+
+[LAW3_L:LAWYER3]
+Capisco. Devo aiutare la giuria a cambiare idea. Non preoccuparti...
+
+[LAW3_M:LAWYER3]
+No no no no NO! Ci ho provato. Le cose con la giuria non sono andate per il meglio,
+
+[LAW3_N:LAWYER3]
+per cui ASSICURATI che cambino davvero idea.
+
+[LAW3_1:LAWYER3]
+Giorgio ti manda i suoi saluti.
+
+[LAW3_2:LAWYER3]
+Ricorda: colpevole è una parolaccia.
+
+[LAW3_3:LAWYER3]
+Innocente fino a prova contraria... ecco cosa dire.
+
+[LAW3_4:LAWYER3]
+Lo sai che non è colpevole.
+
+[LAW3_5:LAWYER3]
+Ti ricordi di Giorgio? Ricordati che è innocente.
+
+[LAW3_6:LAWYER3]
+Non colpevole... Capito? Bene.
+
+[LAW3_8:LAWYER3]
+~r~Hai ucciso un giurato!
+
+[LAW3_9:LAWYER3]
+~g~Distruggi l'auto del giurato per farlo uscire!
+
+[HELP40:LAWYER3]
+Puoi distruggere le macchine utilizzando un martello o un'arma simile.
+
+[LAW3_10:LAWYER3]
+~g~Visita il ~h~ferramenta~g~ per comprare un'arma corpo a corpo.
+
+[LAW3_20:LAWYER3]
+~g~Distruggi la macchina del giurato!
+
+[LAW3_21:LAWYER3]
+Non posso credere che sta succedendo!
+
+[LAW3_22:LAWYER3]
+Incredibile!
+
+[LAW3_23:LAWYER3]
+OK! OK! Ho compreso il messaggio!
+
+[LAW3_24:LAWYER3]
+~g~Quel martello potrebbe tornare utile.
+
+[LAW3_7:LAWYER3]
+~g~Minaccia i due giurati, ma NON ucciderli!
+
+[HELP23:LAWYER3]
+Segui il ~h~segnale a forma di martello~w~ se vuoi comprare delle armi corpo a copro dal ferramenta.
+
+[LAW3_16:LAWYER3]
+Stupidi idioti del Florida.
+
+[LAW3_17:LAWYER3]
+Via dai piedi.
+
+{=================================== MISSION TABLE LAWYER4 ===================================}
+
+[LAW4_A:LAWYER4]
+Avery, è chiaro che... Tommy! Tommy! Qualche progresso? No no no, parliamone dopo, mi racconti dopo.
+
+[LAW4_B:LAWYER4]
+Tommy, ti presento Avery Carrington: credo tu lo abbia incontrato al party.
+
+[LAW4_C:LAWYER4]
+Non di persona.
+
+[LAW4_D:LAWYER4]
+Piacere.
+
+[LAW4_E:LAWYER4]
+Avery ha una proposta da farci.
+
+[LAW4_F:LAWYER4]
+Non ti sembra che abbiamo già altro da fare?
+
+[LAW4_G:LAWYER4]
+Sto cercando di tenere lontani i lupi dalla porta, per cui apprezzerei un po' di collaborazione.
+
+[LAW4_H:LAWYER4]
+Sono tirato come un filo e, anche se dovessi morire alla fine della settimana, desidererei non farlo da povero!
+
+[LAW4_I:LAWYER4]
+Adesso calmatevi, tutti e due.
+
+[LAW4_J:LAWYER4]
+Figliolo, dammi una mano e vedrò di mettere a nanna sottoterra qualsiasi stronzo vi stia dando problemi.
+
+[LAW4_K:LAWYER4]
+OK, cosa posso fare?
+
+[LAW4_L:LAWYER4]
+Questa società di consegne ha un deposito su un terreno di prima qualità. Non vogliono vendere.
+
+[LAW4_M:LAWYER4]
+Si sono rintanati come dei ratti di prateria, per cui vorrei andassi a trovarli e li facessi uscire con un po' di fumo.
+
+[LAW4_N:LAWYER4]
+Raggiungi il posto e fai scoppiare un vespaio:
+
+[LAW4_O:LAWYER4]
+mentre la sorveglianza sarà impegnata, entra dentro e mettili fuori gioco.
+
+[LAW4_P:LAWYER4]
+Passa pure da Rafael's per un cambio d'abito: ci potresti mettere un po', ma va bene lo stesso.
+
+[LAW4_Q:LAWYER4]
+Potrebbe funzionare una sommossa.
+
+[LAW4_R:LAWYER4]
+Se le cose vanno come devono, passa a trovarmi nel mio ufficio...
+
+[LAW4_1:LAWYER4]
+Disperdetevi! L'amministrazione discuterà qualsiasi rimostranza in modo appropriato!
+
+[LAW4_2:LAWYER4]
+Disperdetevi! Tornate a casa!
+
+[LAW4_3:LAWYER4]
+Disperdetevi! Questo comportamento è inaccettabile!
+
+[LAW4_4:LAWYER4]
+Disperdetevi! Rischiate di finire tutti per strada!
+
+[LAW4_5:LAWYER4]
+Forza, ragazzi! Spacchiamo il cranio a qualche rosso!
+
+[LAW4_13:LAWYER4]
+~g~Comincia a combattere con almeno 4 lavoratori per avviare la sommossa.
+
+[LAW4_14:LAWYER4]
+~g~Distruggi i van nell'autorimessa!
+
+[HELP38:LAWYER4]
+Se uccidi qualcuno con un'arma, la lascerà cadere.
+
+[HELP39:LAWYER4]
+Puoi far esplodere i barili di esplosivo, ma tieni la distanza!
+
+{=================================== MISSION TABLE MIAMI_1 ===================================}
+
+[T4X4_1A:MIAMI_1]
+~g~Hai ~1~ secondi per attraversare ~y~24~g~ punti di controllo. ~g~Puoi attraversarli in ~y~QUALSIASI ORDINE~g~.
+
+[T4X4_1B:MIAMI_1]
+~y~ATTRAVERSA~g~ il primo punto di controllo per attivare il ~r~TIMER~g~.
+
+[T4X4_1C:MIAMI_1]
+~1~ su 24!
+
+[GETBIK1:MIAMI_1]
+Hai ~1~ secondi per salire su una PCJ 600!
+
+[GETBIK3:MIAMI_1]
+~r~Hai bisogno di una PCJ 600 per affrontare questa missione!
+
+{=================================== MISSION TABLE MM ===================================}
+
+[BLOD_04:MM]
+CONDIZIONI MACCHINA:
+
+[BLOD_05:MM]
+~g~TEMPO BERSAGLIO: ~1~ minuto
+
+[BLOD_06:MM]
+~g~TEMPO BERSAGLIO: ~1~ minuti
+
+[BLOD_07:MM]
+NUOVO miglior tempo: ~1~ secondi
+
+[BLOD_08:MM]
+Veicoli distrutti: ~1~
+
+[BLOD_09:MM]
+~1~$
+
+[BLOD_10:MM]
+VINCITORE!!!
+
+[BLOD_01:MM]
+Guida attraverso i punti di controllo per aumentare il tuo tempo globale.
+
+[BLOD_02:MM]
+Fallirai se il tempo globale scadrà a zero.
+
+[BLOD_03:MM]
+Porta il tuo tempo globale sopra a quello bersaglio per vincere!
+
+{=================================== MISSION TABLE OVALRIG ===================================}
+
+[HOTR_01:OVALRIG]
+~g~La gara dura 12 giri: solo il primo, il secondo e il terzo si qualificheranno come vincitori.
+
+[HOTR_02:OVALRIG]
+~g~Se il tuo mezzo viene distrutto, sarai squalificato.
+
+[HOTR_03:OVALRIG]
+~g~Se danneggi il mezzo, potrai ripararlo ai box.
+
+[HOTR_04:OVALRIG]
+~g~Da qui potrai uscire dallo stadio.
+
+[HOTR_05:OVALRIG]
+Condizioni macchina:
+
+[HOTR_06:OVALRIG]
+Giri:
+
+[HOTR_10:OVALRIG]
+Tempo di gara:
+
+[HOTR_09:OVALRIG]
+Posizione:
+
+[HOTR_12:OVALRIG]
+~r~La tua macchina è stata distrutta!
+
+[HOTR_13:OVALRIG]
+~r~Non hai vinto la gara!
+
+[HOTR_14:OVALRIG]
+~r~Sei stato squalificato!
+
+[HOTR_15:OVALRIG]
+Tempo: ~1~:~1~
+
+[HOTR_16:OVALRIG]
+Tempo: ~1~:0~1~
+
+[HOTR_17:OVALRIG]
+Tempo migliore: ~1~:~1~
+
+[HOTR_18:OVALRIG]
+Tempo migliore: ~1~:0~1~
+
+[HOTR_19:OVALRIG]
+Tempo migliore: NA
+
+[HOTR_20:OVALRIG]
+Nuovo tempo migliore: ~1~:~1~
+
+[HOTR_21:OVALRIG]
+Nuovo tempo migliore: ~1~:0~1~
+
+[HOTR_22:OVALRIG]
+Miglior risultato: NA
+
+[HOTR_23:OVALRIG]
+Miglior risultato: PRIMO
+
+[HOTR_24:OVALRIG]
+Miglior risultato: SECONDO
+
+[HOTR_25:OVALRIG]
+Miglior risultato: TERZO
+
+[HOTR_26:OVALRIG]
+Miglior risultato: ~1~
+
+[HOTR_27:OVALRIG]
+Miglior giro: ~1~.~1~ secondi
+
+[HOTR_28:OVALRIG]
+Miglior giro: ~1~.0~1~ secondi
+
+[HOTR_29:OVALRIG]
+~1~$
+
+[HOTR_30:OVALRIG]
+PRIMA POSIZIONE
+
+[HOTR_31:OVALRIG]
+SECONDA POSIZIONE
+
+[HOTR_32:OVALRIG]
+TERZA POSIZIONE
+
+[HOTR_33:OVALRIG]
+Miglior giro: NA
+
+[HOTR_11:OVALRIG]
+Nuovo giro migliore: ~1~.~1~ secondi
+
+[HOTR_34:OVALRIG]
+Nuovo giro migliore: ~1~.0~1~ secondi
+
+{=================================== MISSION TABLE PHIL1 ===================================}
+
+[PHIL1_A:PHIL1]
+Phil?
+
+[PHIL1_B:PHIL1]
+CORRI!
+
+[PHIL1_C:PHIL1]
+Corri!
+
+[PHIL1_E:PHIL1]
+Merda Phil, tu bevi quella schifezza?
+
+[PHIL1_F:PHIL1]
+Accidenti, non la devi mica bere...
+
+[PHIL1_G:PHIL1]
+basta una sniffata per sballare.
+
+[PHIL1_H:PHIL1]
+Ascoltami Phil, mi hai detto che potevi fornirmi delle armi...
+
+[PHIL1_I:PHIL1]
+Stanne certo!
+
+[PHIL1_J:PHIL1]
+C'è un trafficante d'armi Messicano con cui ho fatto un po' di affari.
+
+[PHIL1_K:PHIL1]
+Fa la sua consegna settimanale più o meno adesso.
+
+[PHIL1_L:PHIL1]
+Sperona il suo camion e fai cadere le armi prima che scappi.
+
+[PHIL1_M:PHIL1]
+E già che ci sei, fammi un favore:
+
+[PHIL1_N:PHIL1]
+fallo fuori.
+
+[PHI1_01:PHIL1]
+~g~Fai cadere le armi dal camion del trafficante.
+
+[PHI1_02:PHIL1]
+~g~Il trafficante ha lasciato cadere il carico. Distruggi le casse e recupera le armi.
+
+[PHI1_03:PHIL1]
+~g~Sembra abbiano chiesto rinforzi.
+
+[PHI1_04:PHIL1]
+~g~Adesso finisci i trafficanti ancora vivi.
+
+[PHI1_HP:PHIL1]
+Quando utilizzi una granata a tempo, lanciala e poi falla esplodere in un secondo momento.
+
+[PHIL1_O:PHIL1]
+Hoooooweeeeee!
+
+[PHIL1_D:PHIL1]
+Nona avvicinare mai una fiamma alla broda di Phil Cassidy!
+
+{=================================== MISSION TABLE PHIL2 ===================================}
+
+[PHIL2_A:PHIL2]
+Ehi Phil, come butta?
+
+[PHIL2_B:PHIL2]
+Eeeeehi Tommy, Come va? E passcato moolto tempo...
+
+[PHIL2_C:PHIL2]
+Devi davvero smetterla con quella broda,
+
+[PHIL2_D:PHIL2]
+accidenti, puzza di solvente. Mi fa bruciare gli occhi...
+
+[PHIL2_E:PHIL2]
+Shshs shhh silenzio Tommy,
+
+[PHIL2_F:PHIL2]
+e vieni qua che ho qualcoscia da farti vedere... qualcoscia...
+
+[PHIL2_G:PHIL2]
+Woof! Oddio! Riuscirei a sniffarlo da qui in fondo! Mi gira già la testa!
+
+[PHIL2_H:PHIL2]
+Non preoccuparti per l'odore, Tommy, guarda quescto...
+
+[PHIL2_I:PHIL2]
+La fottuta batteria o qualcosc'altro... Scen'è un altra sulla mensola...
+
+[PHIL2_J:PHIL2]
+TA-DAAA!
+
+[PHIL2_K:PHIL2]
+Ommerda!
+
+[PHI2_01:PHIL2]
+~g~Forza, porta Phil all'ospedale.
+
+[PHI2_03:PHIL2]
+~r~Phil Cassidy è morto!!! Adesso chi ti rifornirà di armi?
+
+[PHI2_05:PHIL2]
+Non all'ospedale, amico! Troppi poliziotti e Viet Cong!
+
+[PHI2_06:PHIL2]
+C'è un vecchio ex-medico militare che mi deve qualche favore e una falciatrice.
+
+[PHI2_07:PHIL2]
+Si trova lungo Little Havana, oooh guarda, un pesce gigante.
+
+[PHI2_08:PHIL2]
+Attento! Nemico tra gli alberi!
+
+[PHI2_09:PHIL2]
+Mi sbaglio o le strade sono di gelatina?
+
+[PHI2_10:PHIL2]
+Cucchiaio Storto a Mamma Gallina, mi ricevi?
+
+[PHI2_11:PHIL2]
+Cucchiaione-ione Woo Woo Woooo!
+
+[PHI2_12:PHIL2]
+Sta venendo per me, amico!
+
+[PHI2_13:PHIL2]
+Piume nere che svolazzano dappertutto...
+
+[PHI2_14:PHIL2]
+È così bello, amico... così bello... ma così freddo...
+
+[PHI2_15:PHIL2]
+10-4, abbiamo un guidatore ubriaco.
+
+[PHI2_04:PHIL2]
+SALUTE DI PHIL:
+
+[PHI_AS1:PHIL2]
+PHILS PLACE COMPLETATO
+
+[PHI_AS2:PHIL2]
+~g~Nuove armi disponibili presso Phils Place.
+
+{=================================== MISSION TABLE PIZZA ===================================}
+
+[PIZ1_01:PIZZA]
+~g~Vai a consegnare queste pizze: devi lanciarle ai clienti. Fai un giro e tira le pizze.
+
+[PIZ1_02:PIZZA]
+~g~Hai lanciato tutte le pizze, torna indietro e prendine altre.
+
+[PIZ1_05:PIZZA]
+~g~Hai cinque minuti per consegnare le pizze prima che i clienti chiamino un altro negozio di consegne.
+
+[PIZ1_07:PIZZA]
+~r~Hai ucciso un cliente! Sei licenziato!
+
+[PIZ1_08:PIZZA]
+~r~Tempo scaduto. Sei licenziato!
+
+[PIZ1_09:PIZZA]
+~r~Hai distrutto il nostro mezzo! Sei licenziato!
+
+[PIZ1_11:PIZZA]
+Ehi! Rimettiti in sella!
+
+[PIZ1_12:PIZZA]
+Pizze mancanti:
+
+[PIZ1_06:PIZZA]
+Premi il ~h~~k~~TOGGLE_SUBMISSIONS~~w~ mentre sei in moto per interrompere la missione.
+
+[PIZ1_13:PIZZA]
+Consegnale belle calde e fragranti.
+
+[PIZ1_14:PIZZA]
+Amico, eccoti le pizze.
+
+[PIZ1_15:PIZZA]
+Ehi, amico, consegnale in fretta.
+
+[PIZ1_16:PIZZA]
+Che cosa stai aspettando, amico? Hai delle pizze da consegnare!
+
+[PIZ1_17:PIZZA]
+So che non volevi fare il fattorino delle pizze, ma non me ne frega niente.
+
+[PIZ1_18:PIZZA]
+Consegna queste.
+
+[PIZ1_19:PIZZA]
+Devi consegnare queste.
+
+[PIZ1_20:PIZZA]
+Forza, ragazzo, consegna queste o sei licenziato.
+
+[PIZ1_21:PIZZA]
+C'è gente in attesa, amico.
+
+[PIZ1_22:PIZZA]
+Che cosa stai aspettando? Devono essere consegnate!
+
+[PIZ1_23:PIZZA]
+Consegna queste maledette pizze.
+
+[PIZ1_24:PIZZA]
+Forza, consegnale calde.
+
+[PIZ1_25:PIZZA]
+Ehi, ti occuperesti di queste?
+
+[PIZ1_26:PIZZA]
+Ehi, consegna subito queste: forza amico.
+
+[PIZ1_27:PIZZA]
+Forza, siamo di fretta: consegnale subito.
+
+[PIZ1_28:PIZZA]
+Ancora tu? Bene, consegnale in fretta, amico.
+
+[PIZ1_29:PIZZA]
+Non c'è tempo da perdere, consegnale tutte.
+
+[PIZ1_30:PIZZA]
+Muoviti, brutto pelandrone, consegna questa roba in tempo.
+
+[PIZ1_31:PIZZA]
+Non otterrai una promozione se non ti muoverai più in fretta.
+
+[PIZ1_32:PIZZA]
+~r~La pizza è troppo calda per te?
+
+[PIZ1_33:PIZZA]
+~g~Torna alla pizzeria per altre ordinazioni.
+
+[PIZ1_34:PIZZA]
+~g~Pizze consegnate, ecco i soldi.
+
+[PIZ_WON:PIZZA]
+Missione Pizza completata. Valore massimo dell'salute aumentato a 150.
+
+{=================================== MISSION TABLE PORN1 ===================================}
+
+[POR1_A:PORN1]
+Azione!
+
+[POR1_B:PORN1]
+Whoa! Questo sì che è un bel...
+
+[POR1_C:PORN1]
+30 centimetri, è questa la norma, baby.
+
+[POR1_D:PORN1]
+TAGLIA! Chi è quell'idiota? Tu! TU! Che cosa stai facendo sul mio set? PERCHÉ?
+
+[POR1_E:PORN1]
+Cosa sono tute queste stronzate?
+
+[POR1_F:PORN1]
+Alieni? Canne da pesca?
+
+[POR1_G:PORN1]
+Chi ha mai visto uno squalo così grande?
+
+[POR1_H:PORN1]
+Tutta questa roba deve andarsene.
+
+[POR1_I:PORN1]
+Perché sei venuto a rompere, idiota?
+
+[POR1_J:PORN1]
+Eh?
+
+[POR1_K:PORN1]
+Per la passera, ecco perché! Che cos'è questo?
+
+[POR1_L:PORN1]
+Questa è la mia arte. SORVEGLIANZA!
+
+[POR1_M:PORN1]
+Ascolta, lurido fighettino, ti ho comprato. Ho comprato tutto questo.
+
+[POR1_N:PORN1]
+E ho intenzione di cambiare le cose da queste parti...
+
+[POR1_O:PORN1]
+Ti farò ricco.
+
+[POR1_P:PORN1]
+Uh. Tu sei... tu... tu sei Tommy Vercetti? Pensavo che tu fossi...
+
+[POR1_Q:PORN1]
+Esatto.
+
+[POR1_R:PORN1]
+Faremo numerosi cambiamenti da queste parte e inizieremo a fare soldi veri.
+
+[POR1_S:PORN1]
+Effettivamente, hai mai pensato che...
+
+[POR1_T:PORN1]
+Ma prima dobbiamo trovare delle tope che meritino.
+
+[POR1_U:PORN1]
+Sì. Le ragazze sono carine, ma sai... Wow!
+
+[POR1_02:PORN1]
+~g~Metti fuori gioco il pappone di Candy e poi passa a prenderla.
+
+[POR1_04:PORN1]
+Yo, Candy. Sto cercando delle attrici talentuose: sei interessata?
+
+[POR1_05:PORN1]
+Certo! Ma prima dovrai parlare con il mio agente...
+
+[POR1_06:PORN1]
+Che DIAVOLO stai facendo?
+
+[POR1_07:PORN1]
+Avresti fatto meglio a stare a casa oggi!
+
+[POR1_7B:PORN1]
+Ma hai visto questo stronzo?
+
+[POR1_08:PORN1]
+Ehi Mercedes!
+
+[POR1_09:PORN1]
+Ehi Tommy, vuoi divertirti?
+
+[POR1_10:PORN1]
+Non adesso, tesoro. Sei interessata a fare dei film?
+
+[POR1_11:PORN1]
+Certo, sempre che possano premiare il mio talento.
+
+[POR1_13:PORN1]
+~g~Porta le ragazze allo studio e presentale a Steve.
+
+[POR1_14:PORN1]
+Sei assunta!
+
+[POR1_15:PORN1]
+Ehi Tommy, vieni anche tu per un riscaldamento?
+
+[POR1_17:PORN1]
+Whoa, che bello squalo!
+
+[POR1_18:PORN1]
+~r~Mercedes è morta!
+
+[POR1_20:PORN1]
+Tommy, dove stai andando? Torna qui!
+
+[POR1_21:PORN1]
+Dove stai andando?
+
+[POR1_22:PORN1]
+Tommy, quando passeremo un po' di tempo io e te da soli?
+
+[POR1_01:PORN1]
+~g~Candy Suxxx sarebbe perfetta per il ruolo da protagonista!
+
+[POR1_12:PORN1]
+~g~Porta Candy con te all'appuntamento con Mercedes.
+
+[POR1_16:PORN1]
+Magari più tardi...
+
+[POR1_24:PORN1]
+~g~Torna indietro e prendi Candy.
+
+[POR1_25:PORN1]
+~g~Hai lasciato Candy indietro, torna a prenderla.
+
+[POR1_23:PORN1]
+~g~Candy starà lavorando in ~h~Downtown~g~.
+
+[POR1_26:PORN1]
+~g~Ecco Candy, sembra sia stata ancora con il deputato Shrub.
+
+[POR1_27:PORN1]
+Forza, andiamo.
+
+[POR1_28:PORN1]
+Tommy, fai attenzione! Il mio seno siliconato non è ancora assicurato!
+
+[POR1_29:PORN1]
+È questo il modo di guidare?
+
+[POR1_30:PORN1]
+Non posso recitare dopo tutto questo!
+
+[POR1_31:PORN1]
+Cosa? Stai cercando di uccidermi? Credevo di essere una star!
+
+{=================================== MISSION TABLE PORN2 ===================================}
+
+[POR2_A:PORN2]
+Come stanno andando le riprese, Steve?
+
+[POR2_B:PORN2]
+Beh, Candy è un talento naturale e l'altra ragazza... è insaziabile!
+
+[POR2_C:PORN2]
+Si è passata metà del cast e dello staff prima ancora che iniziassi a fare i controlli delle luci.
+
+[POR2_D:PORN2]
+Comunque, eh, domani andiamo fuori a registrare le scene sulla barca...
+
+[POR2_E:PORN2]
+Scene sulla barca? Quali scene sulla barca?
+
+[POR2_F:PORN2]
+I pescatori sono presi dalla passione quando lo squalo gigante arriva e...
+
+[POR2_G:PORN2]
+Che cosa ho detto sullo squalo gigante?
+
+[POR2_H:PORN2]
+Ho detto: 'NIENTE SQUALO GIGANTE', tutto chiaro?
+
+[POR2_I:PORN2]
+Lascia semplicemente le telecamere puntate sull'azione!
+
+[POR2_J:PORN2]
+OK, OK. Ehi Tommy, ci devo pure provare, no?
+
+[POR2_K:PORN2]
+Hai fatto stampare quei volantini?
+
+[POR2_L:PORN2]
+Sì, ma nessuno ci farà distribuire quella roba, cioè...
+
+[POR2_M:PORN2]
+Lasciano semplicemente troppo, uh... poco all'immaginazione.
+
+[POR2_N:PORN2]
+Non preoccuparti per quello.
+
+[POR2_O:PORN2]
+Ho le mie idee sulla distribuzione.
+
+[POR2_P:PORN2]
+OK. Ehi Candy, uh, nella mia roulotte.
+
+[POR2_01:PORN2]
+~g~C'è un idrovolante che è stato utilizzato nelle scene di alcuni vecchi film di Indy nel retro degli studi.
+
+[POR2_02:PORN2]
+~g~Passa sopra uno dei punti di controllo per cominciare a distribuire volantini.
+
+[POR2_03:PORN2]
+~g~Lancia i volantini fino alla fine del punto di controllo.
+
+[POR2_04:PORN2]
+~r~CARBURANTE AL MINIMO!!!
+
+[POR2_05:PORN2]
+Usalo per distribuire i volantini per la città.
+
+[DILDO:PORN2]
+Carburante:
+
+[POR2_Q:PORN2]
+Accidenti.
+
+[PORN2_9:PORN2]
+~g~Hai ~1~ secondi per tornare sulla tua Skimmer prima che la missione abbia termine.
+
+{=================================== MISSION TABLE PORN3 ===================================}
+
+[POR3_A:PORN3]
+OK, qual è il problema adesso?
+
+[POR3_B:PORN3]
+SSShhhh!
+
+[POR3_C:PORN3]
+Beh, dopo il suo incontro ravvicinato con le ninfo-invasori,
+
+[POR3_D:PORN3]
+il nostro eroe non riesce a pensare ad altro che a questa immensa montagna fallica...
+
+[POR3_E:PORN3]
+ed è qui che vogliamo girare la scena con la tinozza piena di puré, ma poi noi...
+
+[POR3_F:PORN3]
+Non me ne può fregar di meno,
+
+[POR3_G:PORN3]
+Basta che continui, continui, continui.
+
+[POR3_H:PORN3]
+Ehi Tommy...
+
+[POR3_I:PORN3]
+mi hai accennato qualcosa al telefono riguardo dei problemi legali...
+
+[POR3_J:PORN3]
+Ah sì! Il deputato Alex Shrub, lanciato verso la cattura di nuovi elettori, ha deciso di conquistare i puritani.
+
+[POR3_K:PORN3]
+Si mormora che voglia supportare delle misure per limitare, diciamo,
+
+[POR3_L:PORN3]
+l'aspetto più carnale della grande industria nazionale dell'intrattenimento.
+
+[POR3_M:PORN3]
+Ottimo.
+
+[POR3_N:PORN3]
+Candy! Conosci Shrub,
+
+[POR3_O:PORN3]
+voi ragazzi vi siete lanciati in qualcosa di perverso?
+
+[POR3_P:PORN3]
+Oh sì, oh sì, oh sì! Sì sì sì SÌ OOOoooh!
+
+[POR3_Q:PORN3]
+Ti prego, dimmi che lo hai ripreso.
+
+[POR3_R:PORN3]
+Faceva parte del... uh... o stava parlando con...
+
+[POR3_S:PORN3]
+Ehi, non saprei dire. Comunque...
+
+[POR3_T:PORN3]
+Ti consiglio vivamente di seguirla dopo le riprese,
+
+[POR3_U:PORN3]
+vedi se va dritta al suo nuovo nido d'amore.
+
+[POR3_V:PORN3]
+Hai una macchina fotografica?
+
+[POR3_X:PORN3]
+Certo, dategliene una.
+
+[POR3_02:PORN3]
+~r~Hai ucciso il deputato! Adesso come farai a ricattarlo?
+
+[POR3_03:PORN3]
+~r~Hai allarmato la sorveglianza del deputato: lo porteranno immediatamente via.
+
+[POR3_04:PORN3]
+Candy, mi chiameresti Martha?
+
+[POR3_05:PORN3]
+Oh Alex, cioè Martha. Tutto ciò che vuoi!
+
+[POR3_06:PORN3]
+Martha, qualcuno ci sta osservando... che cosa perversa.
+
+[POR3_07:PORN3]
+Ehi tu. Dammi quella macchina fotografica!
+
+[POR3_01:PORN3]
+~g~Segui la ~h~limousine~g~ di Candy.
+
+[POR3_15:PORN3]
+~r~Hai distrutto la limousine di Candy!
+
+[POR3_17:PORN3]
+~g~Torna allo studio con il rullino.
+
+[POR3_19:PORN3]
+~r~Hai finito il rullino!
+
+[POR3_21:PORN3]
+~g~Hai perso la limousine di Candy!
+
+[POR3_22:PORN3]
+~g~L'hotel WR Chariot di fronte al balcone dovrebbe essere un luogo ideale per scattare le foto.
+
+[POR3_23:PORN3]
+~g~C'è un ingresso laterale che ti permetterà di entrare nell'hotel.
+
+[POR3_08:PORN3]
+Tieni premuto il ~h~~k~~PED_LOCK_TARGET~~w~ per ~h~mirare~w~ con la macchina fotografica.
+
+[POR3_09:PORN3]
+Tieni premuto il ~h~~k~~PED_LOCK_TARGET~~w~ per ~h~mirare~w~ con la macchina fotografica.
+
+[POR3_10:PORN3]
+Premi il ~h~~k~~PED_SNIPER_ZOOM_IN~~w~ per ~h~zoomare~w~ con la macchina fotografica e il ~h~~k~~PED_SNIPER_ZOOM_OUT~~w~ per ~h~allargare il campo~w~.
+
+[POR3_11:PORN3]
+Premi il ~h~~k~~PED_SNIPER_ZOOM_IN~~w~ per ~h~zoomare~w~ con la macchina fotografica e il ~h~~k~~PED_SNIPER_ZOOM_OUT~~w~ per ~h~allargare il campo~w~.
+
+[POR3_12:PORN3]
+Premi il ~h~~k~~PED_FIREWEAPON~~w~ per scattare una foto.
+
+[POR3_13:PORN3]
+Premi il ~h~~k~~PED_FIREWEAPON~~w~ per scattare una foto.
+
+[POR3_14:PORN3]
+Premi il ~h~~k~~PED_FIREWEAPON~~w~ per scattare una foto.
+
+[POR3_20:PORN3]
+~g~Se hai bisogno di un mezzo, usa lo ~h~Sparrow~g~ sul retro.
+
+[POR3_16:PORN3]
+~g~Hai bisogno di tre foto di qualità di Alex Shrub con Candy.
+
+[POR3_24:PORN3]
+FOTO SCATTATE:
+
+{=================================== MISSION TABLE PORN4 ===================================}
+
+[POR4_A:PORN4]
+Mi dispiace, ma adesso proprio non riesco ad ingoiarlo.
+
+[POR4_B:PORN4]
+Oh EDDAI tesoro!
+
+[POR4_C:PORN4]
+È inalberato come un capodoglio, accidenti,
+
+[POR4_D:PORN4]
+come fai a non farti coinvolgere dalla parte?
+
+[POR4_E:PORN4]
+Ma Stevie...
+
+[POR4_F:PORN4]
+Come sta andando il mio regista?
+
+[POR4_G:PORN4]
+Oh, accidenti. Lo scontro tra l'integrità artistica e
+
+[POR4_H:PORN4]
+i sobbalzi e le pompanti azioni continua senza sosta.
+
+[POR4_I:PORN4]
+E, prima che tu me lo chieda, sì, tutti e quattro i film saranno pronti per...
+
+[POR4_J:PORN4]
+Dolcezza, potresti PER FAVORE tenere l'anaconda nell'inquadratura,
+
+[POR4_K:PORN4]
+mi costa più lei all'ora di te!
+
+[POR4_L:PORN4]
+Oh, scusa Steve.
+
+[POR4_M:PORN4]
+Pensavo, abbiamo bisogno di qualche grossa acrobazia per promuovere il lancio.
+
+[POR4_N:PORN4]
+Qualcosa che farà davvero impatto sulla città... ti viene in mente niente?
+
+[POR4_O:PORN4]
+Beh, nei vecchio tempi si facevano le feste di gala,
+
+[POR4_P:PORN4]
+attori, limousine, il cielo notturno illuminato dai riflettori...
+
+[POR4_Q:PORN4]
+Riflettori? Mi è venuta un'idea...
+
+[POR4_R:PORN4]
+...sì, sì, sì. I vestiti pieni di lustrini, e le limousine, oh, le prime visioni...
+
+[POR4_S:PORN4]
+Oh, sì signora, certo signora,
+
+[POR4_T:PORN4]
+e la stampa, e gli sbarramenti di luci...
+
+[POR4_01:PORN4]
+~g~Raggiungi ~y~Downtown~g~ e posiziona i riflettori sopra l'edificio.
+
+[POR4_02:PORN4]
+~g~Avrai bisogno di una moto veloce per saltare da un tetto all'altro. La guardia della sorveglianza possiede una ~y~PCJ 600~g~...
+
+[POR4_03:PORN4]
+~g~Devi raggiungere i tetti degli edifici. Ci dovrebbe essere un ascensore in uno degli uffici ai piani superiori...
+
+[POR4_06:PORN4]
+~g~Torna all'ufficio ai piani inferiori se vuoi accedere nuovamente ai tetti.
+
+[POR4_07:PORN4]
+~g~Avrai bisogno di una moto per saltare da un edificio all'altro.
+
+[POR4_08:PORN4]
+~g~Lanciati attraverso la finestra per avviare il percorso. Avrai tempo fino alle 07:00 prima che diventi troppo luminoso per muoverti non visto.
+
+[POR4_09:PORN4]
+~g~I bonus ti mostreranno il successivo edificio su cui saltare.
+
+[POR4_10:PORN4]
+~r~È troppo tardi per arrivare in cima non visto.
+
+[POR4_11:PORN4]
+Ritorna alla scala se vuoi accedere nuovamente ai tetti.
+
+[POR4_05:PORN4]
+~g~Queste scale portano a un ufficio ai piani inferiori.
+
+[POR_AS1:PORN4]
+STUDIO CINEMATOGRAFICO COMPLETATO
+
+[POR_AS2:PORN4]
+~g~L'Inter Global Films d'ora in poi genererà introiti per un massimo di ~1~$. Ricordati di recuperarli regolarmente.
+
+{=================================== MISSION TABLE PROT1 ===================================}
+
+[PRO1_B:PROT1]
+Non sopporto più questo aspetto. Tommy, che ne dici? E se mettessimo un bar...
+
+[PRO1_D:PROT1]
+Ascoltami,
+
+[PRO1_E:PROT1]
+è giunta l'ora di prendere in mano questa città. È tutto pronto per questo.
+
+[PRO1_F:PROT1]
+Dobbiamo cominciare a impadronirci del territorio
+
+[PRO1_G:PROT1]
+e far sapere a Vice City che ci sono nuovi giocatori in città, mi segui?
+
+[PRO1_I:PROT1]
+Tommy, ciò di cui hai bisogno è una facciata legale, delle proprietà. A me ha sempre fatto comodo.
+
+[PRO1_J:PROT1]
+Dobbiamo iniziare a mostrare i denti o tutto questo lavoro sarà stato vano.
+
+[PRO1_K:PROT1]
+I gruppi locali sanno che Diaz è morto e si rifiutano di pagare per la protezione!
+
+[PRO1_L:PROT1]
+Potremmo provare con la corruzione...
+
+[PRO1_M:PROT1]
+Corruzione? A fanculo la corruzione! Ti mostrerò io come si fa a spaventarli.
+
+[PRO1_01:PROT1]
+~g~Assali i negozi e fuggi: i proprietari chiederanno la tua protezione.
+
+[PRO1_03:PROT1]
+~r~Si trattava di un assali e fuggi, non di un assali e bevi un caffè.
+
+[PRO1_04:PROT1]
+Tutti i miei beni, distrutti!
+
+[PRO1_05:PROT1]
+Rovinato... ROVINATO!
+
+[PRO1_06:PROT1]
+Maledizione, devo pagare la protezione!
+
+[PRO1_07:PROT1]
+La mia meravigliosa vetrina!
+
+[PRO1_08:PROT1]
+Il mio negozio, il mio bellissimo negozio.
+
+[PRO1_09:PROT1]
+Vercetti, ricorda questo nome.
+
+[PRO1_10:PROT1]
+Adesso gestisco io questa città. IO!
+
+[BUYP1:PROT1]
+Non puoi comprare proprietà in certe aree della mappa.
+
+[BUYP2:PROT1]
+Se vedi un'icona a forma di casa verde, puoi comprare quella proprietà.
+
+[PRO1_N:PROT1]
+Sarò di ritorno fra cinque minuti...
+
+[PRO1_11:PROT1]
+~g~Raggiungi il ~y~Mall North Point~g~ in ~y~Vice Point~g~.
+
+[PRO1_12:PROT1]
+~g~Distruggi le vetrine di tutti i negozi e i proprietari saranno pronti a chiederti protezione.
+
+[PRO1_A:PROT1]
+Oh, dobbiamo ridecorare questo posto, deve sembrare più vecchio.
+
+[PRO1_C:PROT1]
+Sei il mio avvocato, Rosenberg, non il mio arredatore. Chiaro?
+
+[BUYP3:PROT1]
+Posizionati all'interno del simbolo e premi il tasto ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare la proprietà.
+
+[PRO1_13:PROT1]
+~g~Hai cinque minuti per distruggerli tutti.
+
+{=================================== MISSION TABLE PROT2 ===================================}
+
+[PRO2_A:PROT2]
+Qual è il problema?
+
+[PRO2_B:PROT2]
+Alcuni bar si rifiutano di pagare.
+
+[PRO2_C:PROT2]
+Dicono di essere protetti da una gang locale di malviventi.
+
+[PRO2_D:PROT2]
+Ma non preoccuparti, Tommy, me ne occupo io.
+
+[PRO2_E:PROT2]
+E tu te ne occupi in questo modo?
+
+[PRO2_F:PROT2]
+Voi due, alzate il culo...
+
+[PRO2_G:PROT2]
+Andiamo.
+
+[PRO2_01:PROT2]
+~g~Fai fuori le guardie che sorvegliano il Front Page Bar e scopri chi le ha rifornite.
+
+[PRO2_10:PROT2]
+~g~Altri due sono riusciti a scappare. Rintracciali e finisci questa storia.
+
+[PRO2_11:PROT2]
+Entra in macchina, idiota.
+
+[PRO2_02:PROT2]
+La tua protezione ha bisogno di più protezione.
+
+[PRO2_03:PROT2]
+Maledizione, non ancora! Non ne voglio sapere!
+
+[PRO2_04:PROT2]
+Questi idioti operano per la DBP Security, con sede dietro all'isolato.
+
+[PRO2_05:PROT2]
+Vedete di risolverla per i fatti vostri.
+
+[PRO2_06:PROT2]
+Ci si vede più tardi.
+
+[PRO2_07:PROT2]
+Sì, sì, certo.
+
+[PRO2_08:PROT2]
+~g~La DBP Security presto scoprirà le tue intenzioni: attacca prima che si ritiri.
+
+[PRO2_09:PROT2]
+~g~Vai a parlare con il proprietario del Front Page.
+
+{=================================== MISSION TABLE PROT3 ===================================}
+
+[PRO3_A:PROT3]
+Cretino! Ma a cosa pensavi?
+
+[PRO3_B:PROT3]
+Ti rendi conto che cosa hai combinato?
+
+[PRO3_C:PROT3]
+Potremmo essere tutti rovinati!
+
+[PRO3_D:PROT3]
+Il timer deve essersi inceppato.
+
+[PRO3_E:PROT3]
+Quel posto era stato minato per saltare come una fabbrica di fuochi d'artificio.
+
+[PRO3_F:PROT3]
+Ma qualcuno ha informato i poliziotti...
+
+[PRO3_G:PROT3]
+Qual è il problema, ragazzi?
+
+[PRO3_H:PROT3]
+Mike doveva dar fuoco a un locale del Mall,
+
+[PRO3_I:PROT3]
+ma ha fatto casino con i fusibili e adesso la polizia sta indagando.
+
+[PRO3_J:PROT3]
+Dobbiamo preparare la nostra roba e andarcene da qui!
+
+[PRO3_K:PROT3]
+Rilassatevi, tutti e due: fatemi pensare per un attimo!
+
+[PRO3_L:PROT3]
+Tommy Vercetti non scappa con la coda fra le gambe.
+
+[PRO3_M:PROT3]
+I poliziotti passeranno al setaccio l'intero edificio, giusto?
+
+[PRO3_N:PROT3]
+Ma tutto ciò richiede tempo.
+
+[PRO3_O:PROT3]
+Dobbiamo entrare e dar fuoco noi stessi al locale.
+
+[PRO3_P:PROT3]
+Sì, ma...
+
+[PRO3_Q:PROT3]
+Solo un poliziotto potrebbe avvicinarsi a meno di un chilometro dal luogo!
+
+[PRO3_R:PROT3]
+Allora andiamo come poliziotti.
+
+[PRO3_S:PROT3]
+Recupereremo delle uniformi... e avremo bisogno di una volante.
+
+[PRO3_T:PROT3]
+Tutto questo grazie a te, Mike.
+
+[PRO3_U:PROT3]
+Mi dispiace.
+
+[PRO3_V:PROT3]
+Ho capito.
+
+[PRO3_W:PROT3]
+Quello che dobbiamo fare è attirare i poliziotti con un gestaccio,
+
+[PRO3_X:PROT3]
+Metterli con le spalle al muro
+
+[PRO3_Y:PROT3]
+e sopraffarli.
+
+[PRO3_Z:PROT3]
+Ottimo piano, andiamo!
+
+[PRO3_A1:PROT3]
+Bene.
+
+[PRO3_01:PROT3]
+OK Lance, attira l'attenzione dei poliziotti!
+
+[PRO3_02:PROT3]
+~g~Prendi la macchina della polizia e vai a posizionare la bomba nel Tarbrush Café dentro al Mall.
+
+[PRO3_03:PROT3]
+~g~Hai lasciato Lance indietro, torna a prenderlo.
+
+[PRO3_04:PROT3]
+~g~Andiamo.
+
+[PRO3_05:PROT3]
+~r~Hai ucciso Lance!
+
+[PRO3_07:PROT3]
+~g~È saltata la vostra copertura. Muoviti a piazzare la bomba!
+
+[PRO3_09:PROT3]
+Legali e imbavagliali!
+
+[PRO3_10:PROT3]
+Oooh. Mi calza a pennello!
+
+[PRO3_11:PROT3]
+Un po' stretto sul pacco...
+
+[PRO3_12:PROT3]
+Oh sì, hai ragione, anche a me!
+
+[PRO3_13:PROT3]
+Tranquillo fratello: nessun poliziotto guida così male!
+
+[PRO3_14:PROT3]
+Ricorda: sorridi agli altri poliziotti!
+
+[PRO3_15:PROT3]
+Ehi agente, bel distintivo, bel distintivo.
+
+[PRO3_16:PROT3]
+Un po' più sciolto, Lance.
+
+[PRO3_17:PROT3]
+OK, i timer sono pronti, 5 secondi alla scadenza.
+
+[PRO3_18:PROT3]
+5 secondi? Dobbiamo scappare di corsa da qua!
+
+[PRO3_19:PROT3]
+Questo deve davvero averli irritati.
+
+[PRO3_20:PROT3]
+~g~Fatevi inseguire dai due poliziotti nel garage.
+
+[PRO3_21:PROT3]
+~g~Ottieni un livello di sospetto così i poliziotti ti inseguiranno fino al garage.
+
+[PRO3_22:PROT3]
+~g~La porta del garage è bloccata! Liberala così potrai chiuderla.
+
+[PRO3_23:PROT3]
+~g~Cammina sul segnalino per piazzare la bomba.
+
+[PRO3_24:PROT3]
+~g~Allontanati dal Café!
+
+[PRO_AS1:PROT3]
+CIRCOLO DI PROTEZIONE COMPLETATO
+
+[PRO_AS2:PROT3]
+~g~La proprietà di Vercetti d'ora in poi genererà introiti per un massimo di ~1~$. Ricordati di recuperarli regolarmente.
+
+[PRO3_08:PROT3]
+~g~Torna alla ~h~proprietà di Vercetti~g~ su ~h~Starfish Island~g~.
+
+{=================================== MISSION TABLE RACES ===================================}
+
+[RACES_2:RACES]
+~g~Hai bisogno di un veicolo per partecipare, non è mica una maratona!
+
+[RACES_3:RACES]
+3..2..1.. VIA VIA VIA!
+
+[RACES_8:RACES]
+~r~Non hai vinto la corsa!
+
+[RACES00:RACES]
+Corsa ~1~:
+
+[RACES01:RACES]
+Terminal Velocity
+
+[RACES02:RACES]
+Ocean Drive
+
+[RACES03:RACES]
+Border Run
+
+[RACES04:RACES]
+Capital Cruise
+
+[RACES05:RACES]
+Tour!
+
+[RACES06:RACES]
+V.C. Endurance
+
+[RACES07:RACES]
+Costo d'ingresso: ~1~$
+
+[RACES08:RACES]
+Tempo migliore: ~1~:~1~
+
+[RACES09:RACES]
+Miglior risultato: PRIMO
+
+[RACES10:RACES]
+Miglior risultato: SECONDO
+
+[RACES11:RACES]
+Miglior risultato: TERZO
+
+[RACES12:RACES]
+Miglior risultato: QUARTO
+
+[RACES13:RACES]
+Lunghezza tracciato: ~1~.~1~ km
+
+[RACES15:RACES]
+Miglior tempo: ND
+
+[RACES16:RACES]
+Miglior risultato: ND
+
+[RACES18:RACES]
+HAI VINTO: ~1~$
+
+[RACES19:RACES]
+Non puoi permetterti di partecipare a questa gara.
+
+[RACES22:RACES]
+Tempo migliore: ~1~:0~1~
+
+[RACES23:RACES]
+Lunghezza tracciato: ~1~.~1~ miglia
+
+[RACES_1:RACES]
+~g~Recupera un veicolo veloce e raggiungi la griglia di partenza.
+
+[RACEHLP:RACES]
+~w~Premi il ~h~~k~~PED_SPRINT~~w~ per avviare la corsa selezionata. ~w~Premi il ~h~~k~~VEHICLE_ENTER_EXIT~~w~ per uscire.
+
+{=================================== MISSION TABLE RCHELI1 ===================================}
+
+[WRECKED:RCHELI1]
+~r~Il veicolo è a pezzi!
+
+[RCH1_4:RCHELI1]
+Punti di controllo rimanenti:
+
+[RCH1_6:RCHELI1]
+~g~Usa l'elicottero radiocomandato per attraversare i punti di controllo nella zona dell'aeroporto.
+
+[RCH1_7:RCHELI1]
+~g~In totale ci sono 20 punti di controllo.
+
+[RCH1_12:RCHELI1]
+~r~L'elicottero radiocomandato si sta allontanando dal raggio d'azione!
+
+[RCH1_13:RCHELI1]
+~r~L'elicottero radiocomandato è fuori portata!
+
+[RCH1_8:RCHELI1] { reVC update }
+~g~Se desideri interrompere la missione, premi il ~h~~k~~VEHICLE_FIREWEAPON~~g~ per far esplodere l'elicottero.
+
+{=================================== MISSION TABLE RCPLNE1 ===================================}
+
+[RCPL1_4:RCPLNE1]
+~g~Sfida nella GARA A TAPPE altri 3 aerei radiocomandati.
+
+[RCPL1_5:RCPLNE1]
+~g~Vola attraverso i punti di controllo in Vice City.
+
+[RCPL1_6:RCPLNE1] { reVC update }
+~g~Se desideri interrompere la missione, premi il ~h~~k~~VEHICLE_FIREWEAPON~~g~ per far esplodere l'aereo.
+
+[RCPL1_8:RCPLNE1]
+~g~L'aereo radiocomandato è quasi fuori portata!
+
+[RCPL1_9:RCPLNE1]
+~r~L'aereo radiocomandato è fuori portata!
+
+{=================================== MISSION TABLE RCRACE1 ===================================}
+
+[RCR1_4:RCRACE1]
+Giri rimanenti:
+
+[RCR1_1:RCRACE1]
+~g~Sfida in una gara a tappe altre 3 macchine radiocomandate.
+
+[RCR1_2:RCRACE1]
+~g~Per vincere, completa per primo due giri del tracciato!
+
+[RCR1_6:RCRACE1]
+~g~La macchina radiocomandata è quasi fuori portata!
+
+[RCR1_7:RCRACE1]
+~r~La macchina radiocomandata è fuori portata!
+
+{=================================== MISSION TABLE ROCK1 ===================================}
+
+[RBM1_A:ROCK1]
+AllllllllRrrighttt!
+
+[RBM1_B:ROCK1]
+Brillante, davvero brillante!
+
+[RBM1_D:ROCK1]
+Ehi, hai già incontrato i Love Fist?
+
+[RBM1_E:ROCK1]
+No, non ancora, ma mi piace molto la vostra musica.
+
+[RBM1_F:ROCK1]
+Lascia che ti presenti la band.
+
+[RBM1_G:ROCK1]
+Questo è P, Percy, Dick. Willy è nel cesso! Jezz è invece il tipo che hai visto prima nella cabina di registrazione.
+
+[RBM1_H:ROCK1]
+Ragazzi, vorrei presentarvi un mio carissimo amico.
+
+[RBM1_I:ROCK1]
+Si chiama Tommy. Ci conosciamo da tempo.
+
+[RBM1_J:ROCK1]
+Ciao amico.
+
+[RBM1_K:ROCK1]
+E, ehm, qual era il tuo nome?
+
+[RBM1_L:ROCK1]
+Eddai Jezz che lo sai,
+
+[RBM1_M:ROCK1]
+non fare questi scherzetti con me, amico,
+
+[RBM1_N:ROCK1]
+sono troppo furbo per cascarci, tesoro!
+
+[RBM1_O:ROCK1]
+Vedi, la situazione Tom è che i ragazzi hanno bisogno di aiuto.
+
+[RBM1_P:ROCK1]
+Non hanno i contatti giusti da questa parte, del tipo 'come sta tuo padre'.
+
+[RBM1_Q:ROCK1]
+Abbiamo bisogno di droga, amico!
+
+[RBM1_R:ROCK1]
+Dobbiamo fare un po' di casino alla Love Fist, capito?
+
+[RBM1_S:ROCK1]
+Beh, questa è Vice City. Qual è il problema?
+
+[RBM1_U:ROCK1]
+Love Juice, sì!
+
+[RBM1_V:ROCK1]
+Love Juice?
+
+[RBM1_W:ROCK1]
+Sì, due parti di broda, una parte di polvere, cinque bombe effervescenti e un litro di petrolio.
+
+[RBM1_X:ROCK1]
+Ci puoi aiutare, amico?
+
+[RBM1_Y:ROCK1]
+Beh, significherebbe molto per i ragazzi.
+
+[RBM1_Z:ROCK1]
+Lo farai per loro, vero?
+
+[RBM1_7:ROCK1]
+~r~Non hai portato la Love Juice in tempo!
+
+[RBM1_8:ROCK1]
+~r~Mercedes è morta!
+
+[RBM1_10:ROCK1]
+~r~Idiota! Hai distrutto la merce!
+
+[RBM1_13:ROCK1]
+~g~Porta la 'Love Juice' e Mercedes alla band prima che salgano sul palco.
+
+[RBM1_15:ROCK1]
+~r~Hai perso lo spacciatore, i soldi e la droga!
+
+[RBM1_17:ROCK1]
+~g~Uccidi lo spacciatore e recupera la droga!
+
+[MOB_07A:ROCK1]
+Ehi amico, ai ragazzi non dispiacerebbe un po' di compagnia, se capisci cosa intendo...
+
+[MOB_07B:ROCK1]
+Conosco la ragazza giusta.
+
+[ROK1_5:ROCK1]
+Ehi Mercedes!
+
+[ROK1_6:ROCK1]
+Ciao Tommy, come stai?
+
+[ROK1_7:ROCK1]
+Non male. Senti, ti piacerebbe intrattenere i Love Fist?
+
+[ROK1_8:ROCK1]
+OK, ma per questo favore voglio una ricompensa...
+
+[RBM1_14:ROCK1]
+~g~Hai bisogno di una macchina o di una moto!
+
+[RBM1_1:ROCK1]
+~g~Vai a prendere Mercedes al suo appartamento.
+
+[RBM1_12:ROCK1]
+~g~Raccogli gli ingredienti per la 'Love Juice' dallo spacciatore.
+
+[ROK1_2:ROCK1]
+NON NECESSARIO
+
+[ROK1_3:ROCK1]
+NON NECESSARIO
+
+[MERC_39:ROCK1]
+Ci vediamo più tardi, tesoro.
+
+[RBM1_C:ROCK1]
+Ehi, Tommy! Sono felice che ce tu l'abbia fatta.
+
+[ROK1_1A:ROCK1]
+Stai cercando qualcosa di speciale? Ho proprio ciò che ti serve!
+
+[ROK1_9:ROCK1]
+Grazie per i soldi, idiota!
+
+[RBM1_T:ROCK1]
+Abbiamo bisogno di Love Juice, hai presente?
+
+{=================================== MISSION TABLE ROCK2 ===================================}
+
+[RBM2_A:ROCK2]
+Tommy, amico, sono felice di vederti!
+
+[RBM2_B:ROCK2]
+Cosa succede?
+
+[RBM2_C:ROCK2]
+Brutte vibrazioni, Tommy...
+
+[RBM2_E:ROCK2]
+C'è questo tipo, lo conosciamo appena, ma lui la sa lunga su di noi.
+
+[RBM2_F:ROCK2]
+Come questo tipo. Sa tutto su di noi.
+
+[RBM2_G:ROCK2]
+Sa che Willy ama la biancheria intima femminile, eh!
+
+[RBM2_H:ROCK2]
+O che a Percy piacciono i Duran Duran!
+
+[RBM2_K:ROCK2]
+Sì, come nella storia dei missili, esatto. Ma ascolta, questo bastardo...
+
+[RBM2_L:ROCK2]
+cioè, sì, questo tipo, vuole vedere i Love Fist morti.
+
+[RBM2_M:ROCK2]
+Morti, Tommy.
+
+[RBM2_N:ROCK2]
+Love Fist morti. Lo sai come si dice, i buoni muoiono giovani.
+
+[RBM2_O:ROCK2]
+Ma Tommy, devi salvare i Love Fist!
+
+[RBM2_P:ROCK2]
+Abbiamo un concerto fra due ore e credo...
+
+[RBM2_Q:ROCK2]
+I ragazzi credono che il maniaco stia architettando qualcosa di losco.
+
+[RBM2_1:ROCK2]
+~g~Guida la limousine al concerto e cerca di attirare allo scoperto lo psicopatico.
+
+[RBM2_2:ROCK2]
+~r~Hai distrutto l'auto della band!
+
+[RBM2_3:ROCK2]
+~g~Vai al concerto!
+
+[RBM2_4:ROCK2]
+~g~Becca lo psicopatico! Non farlo scappare!
+
+[RBM2_5:ROCK2]
+~r~Lo hai perso, idiota!
+
+[RBM2_7:ROCK2]
+~r~I fan sono stati attaccati: lo psicopatico non si farà vivo!
+
+[RBM2_8:ROCK2]
+~r~Le guardie della sorveglianza sono state attaccate: lo psicopatico non si farà vivo!
+
+[PSYCH_1:ROCK2]
+Vedrò i Love Fist bruciare!
+
+[PSYCH_2:ROCK2]
+I Love Fist hanno rovinato la mia vita!
+
+[RBM2_I:ROCK2]
+Sta zitto, idiota. Solo perché a Jezz piacciono le pecore.
+
+[RBM2_R:ROCK2]
+Ma sta' zitto!
+
+[RBM2_D:ROCK2]
+Certo, niente scherzi, è roba forte, davvero forte sai?
+
+[RBM2_J:ROCK2]
+È una questione di passione, sai?
+
+{=================================== MISSION TABLE ROCK3 ===================================}
+
+[RBM3_A:ROCK3]
+Tommy! Tommy! Tommy amico, lo psicopatico è tornato!
+
+[RBM3_B:ROCK3]
+Che succede?
+
+[RBM3_C:ROCK3]
+Quello psicopatico non vuole lasciar stare i Love Fist!
+
+[RBM3_D:ROCK3]
+Non lo hai ucciso, amico. E adesso è tornato.
+
+[RBM3_E:ROCK3]
+Sì, sì, sì e il problema è che...
+
+[RBM3_F:ROCK3]
+Il problema è che abbiamo bisogno di qualcuno di cui ci fidiamo per guidare la limousine,
+
+[RBM3_G:ROCK3]
+poiché il pazzo continua a minacciarci!
+
+[RBM3_I:ROCK3]
+Stiamo letteralmente cadendo a pezzi.
+
+[RBM3_J:ROCK3]
+OK ragazzi, calmatevi. Me ne occuperò io.
+
+[RBM3_K:ROCK3]
+Generalmente non perdo tempo a portare in giro un gruppo di ubriaconi scozzesi bisessuali,
+
+[RBM3_L:ROCK3]
+ma, nel vostro caso, farò un'eccezione.
+
+[ROK3_03:ROCK3]
+Conviene fare un giro più lungo.
+
+[ROK3_04:ROCK3]
+Ehi Tommy, cambia la stazione.
+
+[ROK3_08:ROCK3]
+Mi sto annoiando di tutto questo.
+
+[ROK3_09:ROCK3]
+Tieni premuto il maledetto pedale!
+
+[ROK3_61:ROCK3]
+Dobbiamo trovare la bomba!
+
+[ROK3_28:ROCK3]
+Suonerò il basso all'inferno.
+
+[ROK3_30:ROCK3]
+Qualcuno faccia qualcosa.
+
+[ROK3_32:ROCK3]
+OK, osso duro, fai qualcosa tu allora.
+
+[ROK3_34:ROCK3]
+Willy, potresti succhiare la broda con una cannuccia.
+
+[ROK3_37:ROCK3]
+Passa una cannuccia a Willy!
+
+[ROK3_41:ROCK3]
+Quale filo, Tommy?
+
+[ROK3_42:ROCK3]
+Quello verde.
+
+[ROK3_43:ROCK3]
+Non c'è un filo verde! Questo forse è verde...
+
+[ROK3_44:ROCK3]
+Qualcuno di questi fili ti sembra verde?
+
+[ROK3_49:ROCK3]
+Ti ho tenuto con me per anni.
+
+[ROK3_51:ROCK3]
+Una ragazzina isterica.
+
+[ROK3_52:ROCK3]
+Sì.
+
+[ROK3_53:ROCK3]
+Taci e taglia un filo.
+
+[ROK3_54:ROCK3]
+Quale filo?
+
+[ROK3_55:ROCK3]
+Questo qua...
+
+[ROK3_56:ROCK3]
+NO!
+
+[ROK3_57:ROCK3]
+Oddio, siamo vivi. Non siamo esplosi, amico. Tommy, bel lavoro. Rock and roll, ragazzi.
+
+[ROK3_58:ROCK3]
+Non abbiamo uno spettacolo a cui andare? Del casino da fare? Fans di cui abusare?
+
+[ROK3_59:ROCK3]
+LOVE FIST!
+
+[ROK3_60:ROCK3]
+Hai finito con quella bottiglia?
+
+[RBM3_4:ROCK3]
+~r~Hai ucciso i Love Fist!
+
+[RBM3_6:ROCK3]
+DETONAZIONE:
+
+[RBM3_1:ROCK3]
+~g~Trasporta i Love Fist al concerto.
+
+[RBM3_2:ROCK3]
+Mentre la bomba è innescata, esploderà se cercherai di lasciare la macchina...
+
+[RBM3_3:ROCK3]
+Se la barra di detonazione si riempie completamente, la bomba esploderà.
+
+[RBM3_8:ROCK3]
+Più velocemente guidi, più lentamente si riempirà.
+
+[RBM3_7:ROCK3]
+~g~BOMBA DISINNESCATA!
+
+[ROK3_6A:ROCK3]
+~g~Love Fist. Avete finito di inquinare l'etere.
+
+[ROK3_6B:ROCK3]
+~g~Vi ho dato la possibilità di essere amici. Adesso vi darò la possibilità di morire.
+
+[ROK3_62:ROCK3]
+Per cui abbiamo pensato di mostrarti il nostro Tempio del Rock.
+
+[ROK3_63:ROCK3]
+Per percepire il furore alla Love Fist!
+
+[ROK3_64:ROCK3]
+Ascolta come parli, amico. Si tratta di carta pesta e adesivo.
+
+[ROK3_65:ROCK3]
+Ehi, ragazzi, questo è il tempio e noi siamo i sacerdoti.
+
+[ROK3_66:ROCK3]
+Beh, se i ragazzi amano i loro sacerdoti a pezzi e mezzi sordi,
+
+[ROK3_67:ROCK3]
+chi sono per discutere?
+
+[ROK3_68:ROCK3]
+Oddio, si è rovinato nuovamente il nastro.
+
+[ROK3_69:ROCK3]
+Se andiamo avanti così, dovremo suonare dal vivo.
+
+[ROK3_70:ROCK3]
+Oooh merda! La pancia...
+
+[ROK3_74:ROCK3]
+Ah guarda: che cos'è? Ehi Tommy, metti su questo nastro.
+
+[ROK3_01:ROCK3]
+Finalmente, amico: è l'ora di un bel drink.
+
+[ROK3_02:ROCK3]
+Il concerto è a cento metri lungo la strada.
+
+[ROK3_05:ROCK3]
+Mi rimbambisco se non agito la testa.
+
+[ROK3_07:ROCK3]
+Tommy, amico, devi salvare la band!
+
+[ROK3_29:ROCK3]
+Tommy, continua a guidare senza rallentare!
+
+[ROK3_31:ROCK3]
+Bella: 'Qualcuno faccia qualcosa'. Ma che idiozia è questa? Ho conosciuto froci più coraggiosi.
+
+[ROK3_33:ROCK3]
+Ascolta, sono un musicista. Non ho la minima idea di come disarmare una bomba.
+
+[ROK3_35:ROCK3]
+Sì, mi è giunta voce che sei bravo in queste cose.
+
+[ROK3_38:ROCK3]
+Una cannuccia? Questo è il furgone da tour dei Love Fist!
+
+[ROK3_39:ROCK3]
+Dove diavolo la trovo una cannuccia, amico?
+
+[ROK3_46:ROCK3]
+Avrei dovuto scaricarti quando ne ho avuto la possibilità.
+
+[ROK3_47:ROCK3]
+Capitalista.
+
+[ROK3_48:ROCK3]
+Schiavo dalla gloria.
+
+[ROK3_73:ROCK3]
+Jezz sta riproducendo il nastro.
+
+[RBM3_9:ROCK3]
+Se ti fermi o guidi lentamente, la barra di detonazione aumenterà.
+
+[ROK3_50:ROCK3]
+Sta zitto. Sei un idiota.
+
+[ROK3_36:ROCK3]
+Ehi, ero completamente fuori di testa quella notte, e voi lo sapete!
+
+[RBM3_H:ROCK3]
+Mi sto cagando addosso, amico. Voglio la mamma!
+
+[ROK3_45:ROCK3]
+La fine imminente mi fa vedere tutto verde.
+
+[ROK3_6C:ROCK3]
+~g~Rallenta e la limousine esploderà, insieme ai vostri GROSSI CULI PELOSI!
+
+[ROK3_71:ROCK3]
+Dobbiamo andare avanti con quello che abbiamo. Grazie ancora Tommy. Cioè, sai cosa intendo, ciao!
+
+[ROK3_1:ROCK3]
+Alla fine è giunta l'ora di un meritato bicchierino. Lo spettacolo si tiene a circa cento metri lungo la strada.
+
+[ROK3_2:ROCK3]
+Conviene fare un giro più lungo. Ehi Tommy, cambia la stazione.
+
+[ROK3_3:ROCK3]
+Sì Tommy, mi rimbambisco se non agito la testa. Ehi guarda, cos'è questo? Ehi Tommy, metti su questa cassetta.
+
+[ROK3_4:ROCK3]
+Love Fist. Avete finito di inquinare l'etere. Vi ho dato la possibilità di essere amici.
+
+[ROK3_5:ROCK3]
+Adesso vi darò la possibilità di morire. Se rallentate, la vostra limousine esploderà, insieme ai vostri GROSSI CULI PELOSI!
+
+[ROK3_6:ROCK3]
+Tommy, devi salvare la band! Mi sto annoiando di tutto questo. Tieni premuto il maledetto pedale!
+
+[ROK3_7:ROCK3]
+Dobbiamo trovare la bomba! Perché? Non possiamo guidare tutto il giorno? È vero, c'è un sacco di roba da bere...
+
+[ROK3_8:ROCK3]
+La bomba non sarà nel motore? Dovremmo fermarci per prenderla! Moriremo tutti quanti! Credo che mi ubriacherò!
+
+[ROK3_9:ROCK3]
+Ehi, c'è una coda da rispettare, amico! La risposta non è nel minibar! Spostati!
+
+[ROK3_10:ROCK3]
+Ehi, dalla bottiglia di vodka escono un sacco di fili! Non è vodka, quella è BRODA!
+
+[ROK3_11:ROCK3]
+WAAAAAAGGGHHHH!!! Ed è predisposta per esplodere! WAAAAAAAAAAAAGGGHHHHHHHH!!!
+
+[ROK3_12:ROCK3]
+Lo dicevano che l'alcol mi avrebbe fatto fuori... L'ho visto in televisione, devi tagliare uno dei fili. Quale? Non lo so, amico.
+
+[ROK3_13:ROCK3]
+Non ne ho idea. Willy, dimmi qualcosa. Suonerò il basso all'inferno.
+
+[ROK3_14:ROCK3]
+Tommy, continua a guidare senza rallentare! Qualcuno faccia qualcosa. Bella!
+
+[ROK3_15:ROCK3]
+'Qualcuno faccia qualcosa'. Ma che idiozia è questa? Ho conosciuto froci più coraggiosi. OK, osso duro, fai qualcosa tu allora.
+
+[ROK3_16:ROCK3]
+Ascolta, io sono un musicista. Non ho la minima idea di come disarmare una bomba. Willy, potresti succhiare la broda con una cannuccia.
+
+[ROK3_17:ROCK3]
+Sì, mi è giunta voce che sei bravo in queste cose. Ehi, ero completamente fuori di testa quella notte, e voi lo sapete!
+
+[ROK3_18:ROCK3]
+Passa una cannuccia a Willy! Una cannuccia? Questo è il furgone da tour di Love Fist!
+
+[ROK3_19:ROCK3]
+Dove diavolo la trovo una cannuccia, non so se mi spiego? Quale filo, Tommy? Quello verde. Non c'è un filo verde!
+
+[ROK3_20:ROCK3]
+Questo forse è verde... Qualcuno di questi fili ti sembra verde?
+
+[ROK3_21:ROCK3]
+Ih no! La fine imminente mi fa vedere tutto verde! Avrei dovuto scaricarti quando ne ho avuto la possibilità.
+
+[ROK3_22:ROCK3]
+Accecato dalla gloria. Capitalista. Ti ho tenuto con me per anni. Sta zitto. Sei un idiota.
+
+[ROK3_23:ROCK3]
+Una ragazzina isterica. Sì. Taci e taglia un filo. Quale filo? Questo qua...
+
+[ROK3_24:ROCK3]
+NO! Oddio, siamo vivi. Non siamo esplosi, amico.
+
+[ROK3_25:ROCK3]
+Tommy, bel lavoro. Rock and roll, ragazzi. Non abbiamo uno spettacolo a cui andare?
+
+[ROK3_26:ROCK3]
+Del casino da fare? Fans di cui abusare? LOVE FIST!
+
+[ROK3_27:ROCK3]
+Hai finito con quella bottiglia?
+
+{=================================== MISSION TABLE SERG1 ===================================}
+
+[TEX1_A:SERG1]
+Vieni a metterti qui vicino a me, figliolo.
+
+[TEX1_B:SERG1]
+Diamine, mio padre diceva sempre 'A caval donato non si guarda in bocca' ed effettivamente non lo ha mai fatto.
+
+[TEX1_C:SERG1]
+Vuoi un goccio di sano Kentucky?
+
+[TEX1_D:SERG1]
+No, grazie.
+
+[TEX1_E:SERG1]
+Sei uno dalla testa lucida, mi piace.
+
+[TEX1_F:SERG1]
+Ora, il business dei terreni non ha niente a che fare con quello che dicono i giornali.
+
+[TEX1_G:SERG1]
+Si tratta solo di polvere! E la volontà di possederla! Mi segui, figliolo?
+
+[TEX1_H:SERG1]
+Sì, certo.
+
+[TEX1_J:SERG1]
+Tu mi sembri la persona giusta per convincerlo.
+
+[TEX1_K:SERG1]
+La persuasione è il mio forte.
+
+[TEX1_L:SERG1]
+Bene. Lo troverai al circolo sportivo, presso il campo da golf.
+
+[TEX1_M:SERG1]
+Non permettono di entrare con le armi, per cui le sue guardie del corpo non saranno armate.
+
+[TEX1_N:SERG1]
+Vai e riempilo di santissime mazzate.
+
+[TEX1_O:SERG1]
+Prendi, ti ho iscritto al club, inoltre, credo proprio avrai bisogno di abiti più adeguati.
+
+[TEX1_2:SERG1]
+~g~Raggiungi il club di golf Leaf Links.
+
+[TEX1_0:SERG1]
+~g~Il bersaglio si sta allenando a golf: assicurati che sia la sua ultima partita.
+
+[TEX1_3:SERG1]
+Chi è questo tipo? Ragazzi, occupatevene voi.
+
+[TEX1_6:SERG1]
+Bel culo bimba!
+
+[TEX1_7:SERG1]
+Ma sono io?
+
+[TEX1_I:SERG1]
+Bene, c'è un tenace bastardo che non si decide a vendere.
+
+[TEX1_8:SERG1]
+Ogni volta che entri su un cart da golf, ottieni automaticamente una mazza da golf, sempre se lo spazio per l'arma corpo a corpo è disponibile.
+
+[TEX1_9:SERG1]
+Prendilo!
+
+[TEX1_10:SERG1]
+Uccidi lo psicopatico!
+
+[TEX1_1:SERG1]
+~g~Recupera degli abiti da golf presso Jocksport's.
+
+{=================================== MISSION TABLE SERG2 ===================================}
+
+[TEX_2A:SERG2]
+~g~Eccellente! Ti hanno visto!
+
+[TEX_2B:SERG2]
+~r~Pazzo! La gente deve essere TESTIMONE di un attacco da parte di un Cubano!
+
+[TEX_2C:SERG2]
+~g~Vai a recuperare dei vestiti con i colori della gang dei Cubani da Rafael's!
+
+[TEX_2D:SERG2]
+~g~Adesso metti fuori gioco il capo della gang degli Haitiani presso l'impresa di pompe funebri Romero's.
+
+[TEX2_A:SERG2]
+Tommy, questo è Donald Love. Donald, questo è Tommy Vercetti,
+
+[TEX2_B:SERG2]
+l'ultimo cowboy arrivato da queste parti.
+
+[TEX2_C:SERG2]
+Yeh... uh...
+
+[TEX2_D:SERG2]
+Donald, sta zitto e ascoltami, potresti imparare qualcosa.
+
+[TEX2_E:SERG2]
+Adesso, niente fa calare i prezzi dei terreni come una bella guerra tra gang rivali.
+
+[TEX2_F:SERG2]
+Eccetto, forse, un disastro, come una piaga biblica o qualcosa del genere.
+
+[TEX2_G:SERG2]
+Ma per il caso in questione mi sembra un po' troppo.
+
+[TEX2_H:SERG2]
+Capisci, brutto idiota quattr'occhi?
+
+[TEX2_I:SERG2]
+Recentemente è morto un capo gang degli Haitiani e, a quanto sembra, sono stati i Cubani.
+
+[TEX2_J:SERG2]
+Togliamo loro qualsiasi dubbio, allora! Vestiti da ombre Cubano
+
+[TEX2_K:SERG2]
+e vai a disturbare il funerale. Fai un bel casino e dattela a gambe.
+
+[TEX2_L:SERG2]
+Hai capito, Donald?
+
+[TEX2_M:SERG2]
+Questo dovrebbe mettere il coyote nel pollaio, vero?
+
+[TEX2_N:SERG2]
+Dopodiché dovremo solo attendere e veder crollare i prezzi.
+
+[TEXEXIT:SERG2]
+~g~Vattene da Little Haiti!
+
+{=================================== MISSION TABLE SERG3 ===================================}
+
+[TEX3_A:SERG3]
+Guarda qua, figliolo. Ho un problema e sono certo tu possa darmi una mano.
+
+[TEX3_B:SERG3]
+Non sono un geometra.
+
+[TEX3_C:SERG3]
+No, mi riferivo principalmente alle tue doti di demolitore.
+
+[TEX3_D:SERG3]
+Ecco la faccenda: questo è il progetto approvato, e questo,
+
+[TEX3_E:SERG3]
+questo è il terreno che stiamo seguendo.
+
+[TEX3_F:SERG3]
+Stai cercando di dirmi che questo nuovo isolato di uffici è nel posto sbagliato.
+
+[TEX3_G:SERG3]
+Capisci al volo.
+
+[TEX3_H:SERG3]
+Adesso devo allontanarmi per un po' dalla città...
+
+[TEX3_I:SERG3]
+...e se la costruzione di quegli uffici dovesse subire un improvviso e insormontabile problema strutturale, beh, allora...
+
+[TEX3_J:SERG3]
+come ogni civile e ragionevole individuo, ti sentiresti obbligato a intervenire
+
+[TEX3_K:SERG3]
+per favorire il ringiovanimento di un'area così importante della città?
+
+[TEX3_L:SERG3]
+Dove posso ordinare altra gente come te?
+
+[TEX3_1:SERG3]
+~g~Utilizza l'elicottero radiocomandato per trasportare le bombe nelle quattro aree bersaglio dell'edificio.
+
+[TEX3_2:SERG3]
+~g~Devi posizionare una bomba su ogni bersaglio. Puoi piazzare l'esplosivo in qualsiasi ordine.
+
+[TEX3_5:SERG3]
+~g~Se fai cadere una bomba senza successo, potrai raccoglierla nuovamente e riprovare.
+
+[TEX3_7:SERG3]
+~g~Dovrai piazzare tutti gli esplosivi rimanenti in 7 minuti!
+
+[TEX3_8:SERG3]
+~g~Hai mancato il bersaglio! Raccogli la bomba e riprova!
+
+[TEX3_10:SERG3]
+~g~Fai cadere la bomba sul bersaglio.
+
+[TEX3_11:SERG3]
+Bersagli rimanenti:
+
+[TEX3_17:SERG3]
+~r~Il tempo è scaduto: non sei riuscito a demolire l'edificio!
+
+[TEX3_18:SERG3]
+~r~L'elicottero radiocomandato è stato distrutto! Come farai adesso a trasportare le bombe?
+
+[TEX3_19:SERG3]
+~r~Hai fatto cadere la bomba in acqua! Hai bisogno di tutte le 4 bombe per demolire il cantiere!
+
+[TEX3_20:SERG3]
+~g~L'elicottero radiocomandato è quasi fuori portata. Torna indietro al cantiere e completa il lavoro!
+
+[TEX3_21:SERG3]
+~r~L'elicottero radiocomandato è fuori portata!
+
+[TEX3_24:SERG3]
+Premi il ~h~~k~~VEHICLE_LOOKLEFT~~w~ per ruotare l'elicottero in senso antiorario.
+
+[TEX3_25:SERG3]
+Premi il ~h~~k~~VEHICLE_LOOKLEFT~~w~ per ruotare l'elicottero in senso orario.
+
+[TEX3_27:SERG3]
+~g~Le scale centrali ti permetteranno di accedere a tutti i piani dell'edificio.
+
+[TEX3_31:SERG3]
+~r~Hai distrutto il van contenente le bombe e l'elicottero radiocomandato!
+
+[TEX3_32:SERG3]
+Puoi ~h~guardare indietro~w~ premendo ~h~simultaneamente ~k~~VEHICLE_LOOKLEFT~ e ~k~~VEHICLE_LOOKRIGHT~~w~.
+
+[TEX3_4:SERG3] { reVC update }
+~g~Per sganciare una bomba, premi il ~h~~k~~VEHICLE_FIREWEAPON~~g~.
+
+[TEX3_29:SERG3] { reVC update }
+Per sganciare una bomba, premi il ~h~~k~~VEHICLE_FIREWEAPON~~w~.
+
+[TEX3_26:SERG3]
+Premi il ~h~~k~~VEHICLE_BRAKE~~w~ per ridurre la velocità del rotore dell'elicottero in modo da farlo abbassare.
+
+[TEX3_22:SERG3]
+Premi il ~h~~k~~VEHICLE_ACCELERATE~~w~ per aumentare la velocità del rotore dell'elicottero in modo da ~h~farlo alzare.
+
+[TEX3_16:SERG3]
+~g~Raggiungi il van ~w~TOPFUN~g~ presso il cantiere edile da demolire.
+
+[TEX3_33:SERG3]
+Una volta raccolta una bomba, il radar mostrerà la pozione del bersaglio rispetto all'elicottero radiocomandato.
+
+[TEX3_34:SERG3]
+Un ~h~triangolo verso l'alto~w~ indica che il bersaglio si trova ~h~più in alto~w~ dell'elicottero.
+
+[TEX3_35:SERG3]
+Un ~h~triangolo verso il basso~w~ indica che il bersaglio si trova ~h~più in basso~w~ dell'elicottero.
+
+[TEX3_36:SERG3]
+Un ~h~quadrato~w~ indica che il bersaglio si trova alla ~h~stessa altezza~w~ dell'elicottero.
+
+[TEX3_6:SERG3]
+~g~Una volta raccolta la prima bomba, comincerà il conto alla rovescia.
+
+[TEX3_28:SERG3]
+Per ~h~raccogliere una bomba~w~, avvicinaci l'elicottero radiocomandato. L'elicottero può trasportare una sola bomba alla volta.
+
+[TEX3_30:SERG3]
+Per raccogliere una bomba, avvicinaci l'elicottero radiocomandato. L'elicottero può trasportare una sola bomba alla volta.
+
+[TEX3_12:SERG3]
+~g~Bomba posizionata! Ancora 3 bersagli! Torna indietro e recupera un'altra bomba.
+
+[TEX3_13:SERG3]
+~g~Bomba posizionata! Ancora 2 bersagli! Torna indietro e recupera un'altra bomba.
+
+[TEX3_14:SERG3]
+~g~Bomba posizionata! Ancora 1 bersaglio! Torna indietro e recupera un'altra bomba.
+
+[TEX3_15:SERG3]
+~r~Conto alla rovescia avviato! ~g~Devi posizionare le ~w~4 bombe~g~ in tempo!
+
+[TEX3_37:SERG3]
+Sposta ~h~in basso la levetta analogica destra~w~ per aumentare la velocità del rotore e ~h~far salire~w~ l'elicottero.
+
+[TEX3_38:SERG3] { reVC update }
+{Sposta ~h~~k~~VEHICLE_ACCELERATE~~w~ per ridurre la velocità del rotore e ~h~far scendere~w~ l'elicottero.}
+Sposta ~h~in alto la levetta analogica destra~w~ per ridurre la velocità del rotore e ~h~far scendere~w~ l'elicottero.
+
+[TEX3_39:SERG3]
+~g~Per sganciare una bomba, premi il tasto ~h~~k~~VEHICLE_HANDBRAKE~~g~.
+
+[TEX3_40:SERG3]
+Per sganciare una bomba, premi il tasto ~h~~k~~VEHICLE_HANDBRAKE~~w~.
+
+[TEX3_23:SERG3]
+Premi i tasti ~h~~k~~VEHICLE_TURRETUP~~w~ e ~h~~k~~VEHICLE_TURRETDOWN~~w~ per inclinare l'elicottero nella direzione desiderata.
+
+{=================================== MISSION TABLE TAXI1 ===================================}
+
+[FARES:TAXI1]
+CLIENTI:
+
+[TAXI1:TAXI1]
+~g~Trova un passeggero.
+
+[TSCORE2:TAXI1]
+~1~$
+
+[IN_ROW:TAXI1]
+Bonus ~1~ DI SEGUITO! ~1~$
+
+[TAXI3:TAXI1]
+~r~Il passeggero è fuggito terrorizzato!
+
+[TAXI7:TAXI1]
+~r~La tua auto è distrutta, falla riparare.
+
+[TAXI4:TAXI1]
+Corsa completata!
+
+[TAXI5:TAXI1]
+BONUS VELOCITÀ!
+
+[TAXI6:TAXI1]
+Missione taxi terminata
+
+[TAXIH1:TAXI1]
+Fermati vicino a un pedone evidenziato per farlo salire a bordo e portarlo a destinazione prima che scada il tempo.
+
+[FARE1:TAXI1]
+~g~Destinazione: ~w~'Club Pole Position'~g~ in Ocean Beach.
+
+[FARE3:TAXI1]
+~g~Destinazione: ~w~'Marina'~g~ in Ocean Beach.
+
+[FARE4:TAXI1]
+~g~Destinazione: ~w~'Ammu-Nation'~g~ in Ocean Beach.
+
+[FARE5:TAXI1]
+~g~Destinazione: ~w~'Hardware store'~g~ in Washington Beach.
+
+[FARE6:TAXI1]
+~g~Destinazione: ~w~'Mall North Point'~g~ in Vice Point.
+
+[MFARE1:TAXI1]
+~g~Destinazione: ~w~'Ammu-Nation'~g~ in Downtown.
+
+[MFARE2:TAXI1]
+~g~Destinazione: ~w~'il terminal'~g~ all'aeroporto internazionale Escobar.
+
+[WFARE3:TAXI1]
+~g~Destinazione: ~w~'Sunshine Autos'~g~ in Little Havana.
+
+[WFARE4:TAXI1]
+~g~Destinazione: ~w~'Taxi Kaufman'~g~ in Little Haiti.
+
+[WFARE5:TAXI1]
+~g~Destinazione: ~w~'Hardware store'~g~ in Little Havana.
+
+[WFARE6:TAXI1]
+~g~Destinazione: ~w~'Howlin Petes Bike'~g~ in Downtown.
+
+[FARE7:TAXI1]
+~g~Destinazione: ~w~'il negozio dei gioiellieri'~g~ in Vice Point.
+
+[FARE8:TAXI1]
+~g~Destinazione: ~w~'la spiaggia'~g~ in Ocean Beach.
+
+[FARE9:TAXI1]
+~g~Destinazione: ~w~'la spiaggia'~g~ in Washington Beach.
+
+[FARE10:TAXI1]
+~g~Destinazione: ~w~'la spiaggia'~g~ in Vice Point.
+
+[FARE11:TAXI1]
+~g~Destinazione: ~w~'l'ospedale'~g~ in Ocean Beach.
+
+[FARE12:TAXI1]
+~g~Destinazione: ~w~'l'ospedale'~g~ in Vice Point.
+
+[FARE13:TAXI1]
+~g~Destinazione: ~w~'la stazione di polizia'~g~ in Washington Beach.
+
+[FARE14:TAXI1]
+~g~Destinazione: ~w~'la stazione di polizia'~g~ in Vice Point.
+
+[FARE15:TAXI1]
+~g~Destinazione: ~w~'il ristorante della pizza'~g~ in Vice Point.
+
+[WFARE7:TAXI1]
+~g~Destinazione: ~w~'la stazione di polizia'~g~ in Little Havana.
+
+[WFARE8:TAXI1]
+~g~Destinazione: ~w~'la stazione di polizia'~g~ in Downtown.
+
+[WFARE9:TAXI1]
+~g~Destinazione: ~w~'l'ospedale'~g~ in Downtown.
+
+[WFARE10:TAXI1]
+~g~Destinazione: ~w~'l'ospedale'~g~ in Little Havana.
+
+[WFARE11:TAXI1]
+~g~Destinazione: ~w~'lo stadio'~g~ in Downtown.
+
+[WFARE12:TAXI1]
+~g~Destinazione: ~w~'il ristorante della pizza'~g~ in Little Haiti.
+
+[WFARE13:TAXI1]
+~g~Destinazione: ~w~'il ristorante della pizza'~g~ in Downtown.
+
+[WFARE14:TAXI1]
+~g~Destinazione: ~w~'i bacini'~g~ in Viceport.
+
+[WFARE15:TAXI1]
+~g~Destinazione: ~w~'la farmacia'~g~ in Little Haiti.
+
+[FARE2:TAXI1]
+~g~Destinazione: ~w~'Club Malibu'~g~ in Vice Point.
+
+{=================================== MISSION TABLE TAXICUT ===================================}
+
+[TAXC_A:TAXICUT]
+Immagino tu sia il nuovo proprietario.
+
+[TAXC_B:TAXICUT]
+Di chi fai parte? Mafia? Cartello? Non sembri Messicano...
+
+[TAXC_C:TAXICUT]
+Comunque, immagino ora comincerai con la vecchia frase 'le cose stanno per cambiare da queste parti',
+
+[TAXC_D:TAXICUT]
+magari minaccerai uno degli autisti...
+
+[TAXC_E:TAXICUT]
+vacci piano con quello là, Ted, ha appena avuto un'ernia al disco.
+
+[TAXC_F:TAXICUT]
+Beh, sì. Le cose stanno per cambiare da queste parti, signora.
+
+[TAXC_G:TAXICUT]
+Che felicità, figliolo. Me ne occupo io...
+
+[TAXC_H:TAXICUT]
+Ormai lo faccio da anni.
+
+[TAXC_I:TAXICUT]
+Attenzione a tutti:
+
+[TAXC_J:TAXICUT]
+è cambiata la gestione e le cose stanno nuovamente per cambiare da queste parti.
+
+[TAXC_K:TAXICUT]
+Il nostro nuovo direttore, della...
+
+[TAXC_L:TAXICUT]
+Di quale gang fai parte?
+
+[TAXC_M:TAXICUT]
+Beh, non faccio parte di nessuna gang.
+
+[TAXC_N:TAXICUT]
+Allora qual è il tuo maledetto nome, ragazzo?
+
+[TAXC_O:TAXICUT]
+Vercetti, Tommy Vercetti.
+
+[TAXC_P:TAXICUT]
+In nostro nuovo direttore, della Vercetti Gang,
+
+[TAXC_Q:TAXICUT]
+si assicurerà che non ci succedano incidenti.
+
+[TAXC_R:TAXICUT]
+Capisce? Fine!
+
+[TAXC_S:TAXICUT]
+Ti è piaciuto il 'Capisce'? A me è piaciuto il 'Capisce'.
+
+[TAXC_T:TAXICUT]
+Allora è così che ha funzionato nel passato:
+
+[TAXC_U:TAXICUT]
+noi portiamo avanti l'azienda come sempre.
+
+[TAXC_V:TAXICUT]
+Se abbiamo problemi con la concorrenza, tu ti occupi di riempirli di botte.
+
+[TAXC_W:TAXICUT]
+Poi loro ci riempiono di botte,
+
+[TAXC_X:TAXICUT]
+poi tu riempi loro di botte nuovamente,
+
+[TAXC_Y:TAXICUT]
+eccetera, eccetera. Tutto chiaro?
+
+[TAXC_Z:TAXICUT]
+Uh, sì, almeno credo...
+
+[TAXC_A1:TAXICUT]
+Prendi un taxi dal garage se ti senti di lanciarti subito nella mischia.
+
+{=================================== MISSION TABLE TAXIWA1 ===================================}
+
+[OUTTIME:TAXIWA1]
+~r~Troppo lento, troppo lento!
+
+[TAX1_1:TAXIWA1]
+OK, abbiamo un cliente danaroso che richiede un taxi da Starfish Island: qualche volontario?
+
+[TAX1_2:TAXIWA1]
+Qui Tommy, lo prendo io!
+
+[TAX1_3:TAXIWA1]
+Questo cliente è mio, indietro!
+
+[TAX1_4:TAXIWA1]
+Forza, forza, entra in fretta!
+
+[TAX1_5:TAXIWA1]
+OK, OK! Ti prego, non farmi male!
+
+[TAXW1_1:TAXIWA1]
+~g~Passa a prendere il VIP su Starfish Island.
+
+[TAXW1_2:TAXIWA1]
+~g~Porta indietro il VIP! Metti fuori gioco l'altra macchina!
+
+[TAXW1_3:TAXIWA1]
+~r~Il VIP è morto!
+
+[TAXW1_4:TAXIWA1]
+~r~Il VIP è arrivato a destinazione!
+
+[TAXW1_6:TAXIWA1]
+~g~Porta il VIP all'aeroporto!
+
+{=================================== MISSION TABLE TAXIWA2 ===================================}
+
+[TAX2_1:TAXIWA2]
+Chiamata a tutti i veicoli: stiamo perdendo clienti in tutta la città. Che cosa sta succedendo?
+
+[TAX2_2:TAXIWA2]
+I taxi VC continuano a batterci sul tempo. Sono in troppi, non possiamo competere!
+
+[TAX2_3:TAXIWA2]
+Mr. Vercetti, se sei in ascolto, devi mettere fuori gioco un po' dei taxi VC, se no falliamo!
+
+[TAXW2_1:TAXIWA2]
+~g~Distruggi 3 taxi rivali!
+
+{=================================== MISSION TABLE TAXIWA3 ===================================}
+
+[TAX3_1:TAXIWA3]
+Taxi 13, la signorina Cortez ha bisogno di essere prelevata da Down Town e ha richiesto esplicitamente di te.
+
+[TAX3_2:TAXIWA3]
+OK, ricevuto. Taxi 13 chiudo.
+
+[TAX3_3:TAXIWA3]
+Hmmm, nessun segno di Mercedes...
+
+[TAXW3_3:TAXIWA3]
+~g~Metti fuori combattimento il capo dei taxisti!
+
+[TAXW3_2:TAXIWA3]
+~g~Resta vivo fino allo scadere del tempo.
+
+[TAX_AS1:TAXIWA3]
+BENI COMPAGNIA DEI TAXI ACQUISITI
+
+[TAX_AS2:TAXIWA3]
+La compagnia dei taxi d'ora in poi genererà introiti per un massimo di ~1~$. Ricordati di recuperarli regolarmente.
+
+[TAX3_4:TAXIWA3]
+È giunta l'ora che l'angelo custode dei Taxi Kaufman entri in azione!
+
+[TAX3_5:TAXIWA3]
+Ehi ragazzo, ti abbronzo il fondoschiena!
{ re3 updates }
{ new languages }
@@ -8025,7 +14588,7 @@ RUSSO
{ new display menus }
[FET_GFX]
-IMPOSTAZIONI GRAFICA
+GRAPHICS SETUP
[FED_MIP]
MIP MAPPING
@@ -8089,7 +14652,6 @@ RIGIOCA MISSIONE
[FESZ_RM]
RIGIOCA?
-{ more graphics }
[FED_VPL]
VEHICLE PIPELINE
@@ -8129,19 +14691,11 @@ PS2
[FEM_XBX]
XBOX
-[FEM_AUT] { aspect ratio related }
-AUTO
-
-{ controls }
[FEC_IVP]
INVERT PAD VERTICALLY
-{ map }
-[FEM_TWP]
-Toggle Waypoint
-
-[FEA_FMN]
-RADIO SPENTA
+[FEM_NON]
+NONE
[FEC_DS2]
DUALSHOCK 2
@@ -8161,36 +14715,12 @@ XBOX ONE CONTROLLER
[FEC_TYP]
GAMEPAD TYPE
-[FEC_CCF]
-CONFIGURAZIONE
-
-[FEC_CF1]
-CONFIGURAZIONE 1
-
-[FEC_CF2]
-CONFIGURAZIONE 2
-
-[FEC_CF3]
-CONFIGURAZIONE 3
-
-[FEC_CF4]
-CONFIGURAZIONE 4
-
-[FEC_CDP]
-SCHERMATA CONTROLLER
-
-[FEC_ONF]
-A PIEDI
-
-[FEC_INC]
-IN MACCHINA
-
-[FEC_VIB]
-VIBRAZIONE
-
[FET_AGS]
GAMEPAD SETTINGS
+[FEM_AUT] { aspect ratio related }
+AUTO
+
[FEM_PED]
PED DENSITY
diff --git a/utils/gxt/polish.txt b/utils/gxt/polish.txt
deleted file mode 100755
index 33716291..00000000
--- a/utils/gxt/polish.txt
+++ /dev/null
@@ -1,8114 +0,0 @@
-{
- New strings are at the bottom of file.
- Do not change the order of strings.
- You can fix the typos of existing translation but please refrain from
- unnecessary edits like rephasing because you think it suits better for your taste.
-}
-
-[LETTER1]
-abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789'$,.'-?!!SDBF
-
-[DEFNAM]
-Claude----------------------
-
-[IN_VEH]
-~g~Hej! Wracaj do samochodu!
-
-[IN_VEH2]
-~g~Do tej roboty jest ci potrzebna jakaś gablota!
-
-[IN_BOAT]
-~g~Do tej roboty jest ci potrzebna łódź!
-
-[HEY]
-~g~Nie idź sam, trzymaj się całej paczki!
-
-[HEY2]
-~g~Nie rozdzielajcie się, niech cała grupa porusza się razem!
-
-[HEY3]
-~g~Straciłeś z oczu swojego podopiecznego - wracaj i odszukaj 8-Balla!
-
-[HEY4]
-~g~Jeżeli stracisz Misty, to Luigi zadba, abyś stracił życie! Wracaj po nią!
-
-[HEY5]
-~g~One of the girls is AWOL, Go back and round her up!
-
-[HEY6]
-~g~Twój honor jest związany z osobą Kanbu z Yakuzy. Musisz go chronić!
-
-[HEY7]
-~g~Przydałaby się dodatkowa spluwa. Wracaj i zabierz ze sobą swój kontakt!
-
-[HEY8]
-~g~Ochrona oznacza właśnie to, co podejrzewasz - ochraniaj starego dżentelmena z dalekiego wschodu!
-
-[HEY9]
-~g~Chcesz posłuchać, co się dzieje w mieście? Odszukaj swój kontakt!
-
-[HELP2_A]
-Jeżeli w trakcie biegu chcesz ~h~przyspieszyć~h~, naciśnij klawisz ~h~/~w~.
-
-[HELP3]
-Sprintem można pokonywać wyłącznie krótkie odcinki, dopóki postać ma zapas sił.
-
-[HELP4_A]
-Aby ~h~przyspieszyć~w~, naciśnij klawisz ~h~ ~k~~VEHICLE_ACCELERATE~~w~.
-
-[HELP4_D]
-Aby ~h~przyspieszyć~w~, popchnij ~h~prawy drążek analogowy~w~ do góry.
-
-[HELP5_A]
-Naciśnij klawisz ~h~ ~k~~VEHICLE_BRAKE~~w~, aby ~h~zahamować~w~ lub włączyć ~h~wsteczny bieg~w~, jeżeli pojazd już stoi.
-
-[HELP5_D]
-Pociągnij ~h~prawy drążek analogowy~w~ do tyłu, aby ~h~zahamować~w~ lub włączyć ~h~wsteczny bieg~w~, jeżeli pojazd już stoi.
-
-[HELP6_A]
-Aby skorzystać z ~h~hamulca ręcznego~w~, naciśnij klawisz ~h~ ~k~~VEHICLE_HANDBRAKE~~w~.
-
-[HELP6_C]
-Aby skorzystać z ~h~hamulca ręcznego~w~, naciśnij klawisz ~h~ ~k~~VEHICLE_HANDBRAKE~~w~.
-
-[HELP6_D]
-Aby skorzystać z ~h~hamulca ręcznego~w~, naciśnij klawisz ~h~ ~k~~VEHICLE_HANDBRAKE~~w~.
-
-[HELP7_A]
-Aby ~h~wycelować~w~ karabin snajperski, naciśnij i przytrzymaj klawisz~h~ ~k~~PED_LOCK_TARGET~~w~.
-
-[HELP7_D]
-Aby ~h~wycelować~w~ karabin snajperski, naciśnij i przytrzymaj klawisz~h~ ~k~~PED_LOCK_TARGET~~w~.
-
-[HELP8_A]
-Naciśnij klawisz~h~ ~k~~PED_SNIPER_ZOOM_IN~~w~, aby ~h~przybliżyć ~w~widok przez lunetkę karabinu oraz klawisz~h~ ~k~~PED_SNIPER_ZOOM_OUT~~w~, aby ~h~oddalić~w~ widok.
-
-[HELP9_A]
-Naciśnij klawisz~h~ ~k~~PED_FIREWEAPON~~w~, aby oddać ~h~strzał~w~ z karabinu snajperskiego.
-
-[HELP10]
-Gwiazda szeryfa oznacza, że jesteś poszukiwany przez policję.
-
-[HELP11]
-Im więcej gwiazdek, tym wyższy jest poziom twojej złej sławy.
-
-[HELP13]
-Niekiedy trzeba będzie skorzystać z tras, które nie są zaznaczone na radarze.
-
-[TIMER]
-Jest to misja na czas - musisz ją wykonać, zanim licznik czasu osiągnie zero.
-
-[MISTY1]
-~r~Misty nadaje się już tylko na łóżko w kostnicy!
-
-[OUT_VEH]
-~g~Wysiądź z samochodu!
-
-[GARAGE]
-Wprowadź samochód do garażu, a potem wyjdź na zewnątrz.
-
-[WANTED1]
-~g~Zgub gliniarzy i obniż swój poziom złej sławy!
-
-[NODOORS]
-~g~To nie są sardynki! Załatw furę, która pomieści więcej osób.
-
-[TRASH]
-~g~Doprowadziłeś gablotę do ruiny! Połataj ją trochę!
-
-[WRECKED]
-~r~Samochód jest zniszczony!
-
-[HORN]
-~g~Naciśnij klakson.
-
-[NOMONEY]
-~g~Masz za mało forsy!
-
-[OUTTIME]
-~r~Za wolno, koleś, za wolno!
-
-[SPOTTED]
-~r~Gonią cię!
-
-[REWARD]
-NAGRODA $~1~
-
-[GAMEOVR]
-KONIEC GRY
-
-[Z]
-Wartość osi Z: ~1~
-
-[M_FAIL]
-MISJA NIEUDANA!
-
-[M_PASS]
-MISJA ZALICZONA! $~1~
-
-[O_PASS]
-ROBOTA ZAKOŃCZONA
-
-[O_FAIL]
-ROBOTA NIEUDANA
-
-[DEAD]
-KONIEC Z TOBĄ!
-
-[BUSTED]
-WPADKA!
-
-[S_PROMP]
-Kiedy nie jesteś w trakcie misji, możesz w tym miejscu ~h~zapisać stan gry~w~. Wiąże się to z upływem sześciu godzin w grze.
-
-[NUMBER]
-~1~
-
-[SCORE]
-$~1~
-
-[LOADCAR]
-ŁADOWANIE POJAZDU (NACIŚNIJ L1, ABY ANULOWAĆ)
-
-[CARSOFF]
-Wyłączone samochody:
-
-[CARS_ON]
-Uruchomione samochody:
-
-[TEXTXYZ]
-Zapisywanie współrzędnych w pliku...
-
-[CHEATON]
-Tryb ułatwień WŁĄCZONY
-
-[CHEATOF]
-Tryb ułatwień WYŁĄCZONY
-
-[UZI_IN]
-Amu-Nacja zaczyna sprzedawać uzi!
-
-[IMPORT1]
-Wyjdź na zewnątrz i poczekaj na swój samochód.
-
-[PAGEB1]
-Pistolet dostarczony do kryjówki
-
-[PAGEB2]
-Uzi dostarczone do kryjówki
-
-[PAGEB3]
-Pancerz dostarczony do kryjówki
-
-[PAGEB4]
-Obrzyn dostarczony do kryjówki
-
-[PAGEB5]
-Granaty dostarczone do kryjówki
-
-[PAGEB6]
-Koktajle Mołotowa dostarczone do kryjówki
-
-[PAGEB7]
-AK 47 dostarczony do kryjówki
-
-[PAGEB8]
-Karabin snajperski dostarczony do kryjówki
-
-[PAGEB9]
-M16 dostarczony do kryjówki
-
-[PAGEB10]
-Wyrzutnia rakiet dostarczona do kryjówki
-
-[PAGEB11]
-Miotacz ognia dostarczony do kryjówki
-
-[WANT_A]
-Aresztowanie grozi ci dopiero wtedy, kiedy posiadasz ~h~złą sławę.
-
-[WANT_B]
-Twój ~h~poziom złej sławy~w~ przedstawia rząd gwiazdek znajdujących się w prawym górnym rogu ekranu.
-
-[WANT_C]
-W tym momencie twój ~h~poziom złej sławy~w~ wynosi jeden...
-
-[WANT_D]
-dwa...
-
-[WANT_E]
-trzy...
-
-[WANT_F]
-W miarę wzrostu ~h~złej sławy~w~ ścigać cię będą coraz potężniejsze siły policyjne.
-
-[WANT_G]
-Kiedy zaliczysz ~h~'wpadkę'~w~, zostajesz odwieziony na najbliższy posterunek policji.
-
-[WANT_H]
-Gliniarze zarekwirują ci całą broń i będziesz musiał wypłacić im małą łapówkę.
-
-[WANT_I]
-Misja, którą właśnie wykonywałeś, zostanie uznana za nieudaną.
-
-[WANT_J]
-W miarę rozwoju gry odkryjesz sposoby zmniejszania swojego poziomu złej sławy.
-
-[WANT_K]
-Jeżeli jesdziesz samochodem, ~h~WARSZTATY LAKIERNICZE~w~ umożliwiają ~h~usunięcie złej sławy.
-
-[HEAL_B]
-Kiedy zostajesz ~h~'załatwiony'~w~, trafiasz do najbliższego szpitala.
-
-[HEAL_C]
-Tracisz całą broń oraz musisz zapłacić lekarzom trochę forsy za ich wysiłki.
-
-[HEAL_E]
-W trakcie gry poznasz rozmaite metody leczenia bądź chronienia głównego bohatera.
-
-[DAM]
-USZKODZENIA:
-
-[KILLS]
-OFIARY:
-
-[FARES]
-PRZEJAZDY:
-
-[BULL]
-SZTABKI:
-
-[EVID]
-DOWODY:
-
-[HEALTH]
-STAN POJAZDU:
-
-[COLLECT]
-ZEBRANO:
-
-[BOMB]
-Wprowadź samochód do garażu, aby przymocować do niego ~h~bombę~w~. Cena - ~h~$1000.
-
-[SAVE1]
-Aby ~h~zapisać stan gry~w~, przejdź przez drzwi. Jeżeli jesteś w trakcie misji, nie można zapisać gry.
-
-[SAVE2]
-Samochody pozostawione w tym garażu zostaną zachowane wraz z zapisem stanu gry.
-
-[AMMU]
-Wejdź do Amu-nacji, aby zakupić broń.
-
-[BRIDGE1]
-Kiedy naprawa Mostu Callahan zostanie ukończona, będziesz mógł przejechać nim na Wyspę Staunton.
-
-[TUNNEL]
-Kiedy Tunel Porter zostanie otwarty, będziesz mógł przejechać na Wyspę Staunton.
-
-[LUIGI]
-MISJE LUIGIEGO
-
-[TONI]
-MISJE TONIEGO
-
-[JOEY]
-MISJE JOEYA
-
-[FRANK]
-MISJE SALVATORE
-
-[DIABLO]
-MISJE DIABLO
-
-[ASUKA]
-MISJE ASUKI
-
-[B_SITE]
-MISJE PODMIEJSKIE ASUKI
-
-[KENJI]
-MISJE KENJIEGO
-
-[RAY]
-MISJE RAYA
-
-[LOVE]
-MISJE LOVE'A
-
-[YARDIE]
-MISJE DLA GANGU YARDIE
-
-[HOOD]
-MISJE DLA GANGU HOOD
-
-[CITYZON]
-Liberty City
-
-[IND_ZON]
-Portland
-
-[PORT_W]
-Callahan Point
-
-[PORT_S]
-Atlantic Quays
-
-[PORT_E]
-Portland Harbor
-
-[PORT_I]
-Trenton
-
-[S_VIEW]
-Portland View
-
-[CHINA]
-Chinatown
-
-[EASTBAY]
-Plaza Portland
-
-[LITTLEI]
-Saint Mark's
-
-[REDLIGH]
-Dz. Czerwonych Świateł
-
-[TOWERS]
-Wzgórza Hepburn
-
-[HARWOOD]
-Harwood
-
-[ROADBR1]
-Most Callahan
-
-[ROADBR2]
-Most Callahan
-
-[TUNNELP]
-Tunel Porter
-
-[BOMB1]
-Warsztat 8-Balla.
-
-[COM_ZON]
-Wyspa Staunton
-
-[STADIUM]
-Aspatria
-
-[HOSPI_2]
-Rockford
-
-[UNIVERS]
-Kampus Liberty
-
-[CONSTRU]
-Fort Staunton
-
-[PARK]
-Park Belleville
-
-[COM_EAS]
-Newport
-
-[SHOPING]
-Bedford Point
-
-[YAKUSA]
-Torrington
-
-[SUB_ZON]
-Shoreside Vale
-
-[AIRPORT]
-Port Lotniczy Francis
-
-[PROJECT]
-Wichita Gardens
-
-[SUB_IND]
-Pike Creek
-
-[SWANKS]
-Cedar Grove
-
-[BIG_DAM]
-Tama Cochrane
-
-[SUB_ZO2]
-Shoreside Vale
-
-[SUB_ZO3]
-Shoreside Vale
-
-[CAR_1]
-Karetka
-
-[CAR_2]
-Straż pożarna
-
-[CAR_3]
-Radiowóz
-
-[CAR_4]
-Enforcer
-
-[CAR_5]
-Barracks
-
-[CAR_6]
-Hipcio
-
-[CAR_7]
-Samochód FBI
-
-[CAR_8]
-Konwojowóz
-
-[CAR_9]
-Moonbeam
-
-[CAR_10]
-Autokar
-
-[CAR_11]
-Flatbed
-
-[CAR_12]
-Linerunner
-
-[CAR_13]
-Śmieciożer
-
-[CAR_14]
-Patriot
-
-[CAR_15]
-Pan Smakołyk
-
-[CAR_16]
-Muł
-
-[CAR_17]
-Yankee
-
-[CAR_18]
-Pony
-
-[CAR_19]
-Bobcat
-
-[CAR_20]
-Rumpo
-
-[CAR_21]
-Blista
-
-[CAR_22]
-Dodo
-
-[CAR_23]
-Autobus
-
-[CAR_24]
-Sentinel
-
-[CAR_25]
-Cheetah
-
-[CAR_26]
-Demon
-
-[CAR_27]
-Stinger
-
-[CAR_28]
-Infernus
-
-[CAR_29]
-Esperanto
-
-[CAR_30]
-Kuruma
-
-[CAR_31]
-Stretch
-
-[CAR_32]
-Perennial
-
-[CAR_33]
-Landstalker
-
-[CAR_34]
-Manana
-
-[CAR_35]
-Idaho
-
-[CAR_36]
-Ogier
-
-[CAR_37]
-Taksówka
-
-[CAR_38]
-Taksówka
-
-[CAR_39]
-Buggy
-
-[LUIGIS]
-Lokal Luigiego
-
-[GOAWAY]
-~g~Już podjąłeś się jednej misji!
-
-[LUIGGO]
-~g~Luigi sprawdza nowe dziewczyny. Przyjdź później!
-
-[JOEYGO]
-~g~Joey wyszedł do miasta z Misty. Przyjdź później.
-
-[TONIGO]
-~g~Toni zabrał swoją Mamuśkę do opery - wpadnij kiedy indziej!
-
-[KEMUGO]
-~g~Maria i Kemuri mają chwilowo inne obowiązki - wpadnij później!
-
-[KENJGO]
-~g~Kenji jest na naradzie Yakuzy. Wpadnij innym razem!
-
-[RAYGO]
-~g~Ray kręci się przy innych kiblach - wpadnij później!
-
-[LOVEGO]
-~g~Donald Love chwilowo zajmuje się innymi sprawami. Umów się z nim na późniejszą godzinę!
-
-[KENSGO]
-~g~Kenji jest zajęty! Wpadnij później!
-
-[HOODGO]
-~g~Hoods są aktualnie niedostępni!
-
-[WRONGT1]
-~g~Jeżeli szukasz zajęcia, wróć między 5:00 a 21:00.
-
-[WRONGT2]
-~g~Jeżeli szukasz zajęcia, wróć między 6:00 a 14:00.
-
-[WRONGT3]
-~g~Jeżeli szukasz zajęcia, wróć między 15:00 a 00:00.
-
-[GUN_1A]
-Użyj klawiszy ~h~~k~~PED_CYCLE_WEAPON_RIGHT~~w~ oraz ~h~~k~~PED_CYCLE_WEAPON_LEFT~ ~w~, aby przełączać się między kolejnymi rodzajami broni.
-
-[GUN_2A]
-Przytrzymaj klawisz ~h~~k~~PED_LOCK_TARGET~ ~w~, aby ~h~wykonać autocelowanie~w~ i naciśnij klawisz ~h~ ~k~~PED_FIREWEAPON~ ~w~, aby ~h~otworzyć ogień! Spróbuj postrzelać do celu...
-
-[GUN_2C]
-Przytrzymaj klawisz ~h~~k~~PED_LOCK_TARGET~ ~w~, aby ~h~wykonać autocelowanie~w~ i naciśnij klawisz ~h~ ~k~~PED_FIREWEAPON~ ~w~, aby ~h~otworzyć ogień! Spróbuj postrzelać do celu...
-
-[GUN_2D]
-Przytrzymaj klawisz ~h~~k~~PED_LOCK_TARGET~ ~w~, aby ~h~wykonać autocelowanie~w~ i naciśnij klawisz ~h~ ~k~~PED_FIREWEAPON~ ~w~, aby ~h~otworzyć ogień! Spróbuj postrzelać do celu...
-
-[GUN_3A]
-Trzymając wciśnięty klawisz ~h~~k~~PED_LOCK_TARGET~,~w~ naciśnij klawisz ~h~~k~~PED_CYCLE_TARGET_LEFT~~w~ lub klawisz ~h~~k~~PED_CYCLE_TARGET_RIGHT~ , aby przełączać się między celami.
-
-[GUN_3B]
-Trzymając wciśnięty klawisz ~h~~k~~PED_LOCK_TARGET~,~w~ naciśnij klawisz ~h~~k~~PED_CYCLE_TARGET_LEFT~~w~ lub klawisz ~h~~k~~PED_CYCLE_TARGET_RIGHT~ , aby przełączać się między celami.
-
-[GUN_4A]
-Trzymając wciśnięty klawisz ~h~~k~~PED_LOCK_TARGET~~w~, możesz chodzić lub biegać, a celownik cały czas pozostanie zablokowany na wybranym celu.
-
-[GUN_4B]
-Trzymając wciśnięty klawisz ~h~~k~~PED_LOCK_TARGET~~w~, możesz chodzić lub biegać, a celownik cały czas pozostanie zablokowany na wybranym celu.
-
-[GUN_5]
-Możesz przećwiczyć wybieranie celów i prowadzenie ognia na tych papierowych celach. Po treningu wróć do wykonywania misji.
-
-[TAXI1]
-~g~Poszukaj pasażera.
-
-[FARE1]
-~g~Cel podróży ~w~'Klub Seksownego Kociaka Miauu'~g~ w Dzielnicy Czerwonych Świateł.
-
-[FARE2]
-~g~Cel podróży ~w~Super Przecena~g~ w Portland View.
-
-[FARE3]
-~g~Cel podróży ~w~'stara szkoła'~g~ w Chinatown.
-
-[FARE4]
-~g~Cel podróży ~w~'kawiarenka Tłustego Joe'~g~ w Callahan Point.
-
-[FARE5]
-~g~Cel podróży ~w~'Amu-Nacja'~g~ w Dzielnicy Czerwonych Świateł.
-
-[FARE6]
-~g~Cel podróży ~w~'Auta na Kredyt'~g~ w Saint Mark's.
-
-[FARE7]
-~g~Cel podróży ~w~'bar topless 'U Woody'ego''~g~ w Dzielnicy Czerwonych Świateł.
-
-[FARE8]
-~g~Cel podróży ~w~'Bistro Marcos'~g~ w Saint Mark's.
-
-[FARE9]
-~g~Cel podróży ~w~'warsztat importowo-eksportowy'~g~ w Portland Harbor.
-
-[FARE10]
-~g~Cel podróży ~w~'Smażony Makaron'~g~ w Chinatown.
-
-[FARE12]
-~g~Cel podróży ~w~'stadion piłkarski'~g~ w Aspatrii.
-
-[FARE13]
-~g~Cel podróży ~w~'kościół'~g~ w Bedford Point.
-
-[FARE14]
-~g~Cel podróży ~w~'kasyno'~g~ w Torrington.
-
-[FARE15]
-~g~Cel podróży ~w~biblioteka Liberty~g~ w Kampusie Liberty.
-
-[FARE16]
-~g~Cel podróży ~w~galeria handlowa~g~ w okolicach Belville Park.
-
-[FARE17]
-~g~Cel podróży ~w~muzeum~g~ w Newport.
-
-[FARE18]
-~g~Cel podróży ~w~siedziba AmCo~g~ w Torrington.
-
-[FARE19]
-~g~Cel podróży ~w~Bolt Burgers~g~ w Bedford Point.
-
-[FARE20]
-~g~Cel podróży ~w~park~g~ w Belville.
-
-[FARE21]
-~g~Cel podróży ~w~Port Lotniczy im. Francisa.
-
-[FARE22]
-~g~Cel podróży ~w~'Tama Cochrane'.
-
-[FARE24]
-~g~Cel podróży ~w~'szpital' ~g~w Pike Creek.
-
-[FARE25]
-~g~Cel podróży ~w~'park'~g~ w Soherside Vale.
-
-[FARE26]
-~g~Cel podróży ~w~'North West Towers'~g~ w Wichita Gardens.
-
-[NEW_TAX]
-WIĘKSZE! SZYBSZE! MOCNIEJSZE! Nowe taksówki Borgnine rozpoczynają pracę w Harwood. Dzwoń już dziś: 555-BORGNINE.
-
-[TSCORE2]
-$~1~
-
-[IN_ROW]
-~1~Premia za SEKWENCJĘ! $~1~
-
-[TTUTOR]
-Naciśnij klawisz ~h~~k~~TOGGLE_SUBMISSIONS~~w~, aby włączyć lub wyłączyć misje w taksówce.
-
-[TTUTOR2]
-Naciśnij klawisz ~h~~k~~TOGGLE_SUBMISSIONS~~w~, aby włączyć lub wyłączyć misje taksówkarskie.
-
-[A_TIME]
-+~1~ sekund
-
-[A_FULL]
-~r~Karetka jest pełna!
-
-[A_RANGE]
-~g~Radiostacja w karetce ma zbyt mały zasięg, zbliż się bardziej w stronę szpitala!
-
-[FTUTOR]
-Naciśnij klawisz ~h~~k~~TOGGLE_SUBMISSIONS~~w~, aby włączyć lub wyłączyc misje strażackie.
-
-[FTUTOR2]
-Naciśnij klawisz ~h~~k~~TOGGLE_SUBMISSIONS~~w~, aby włączyć lub wyłączyc misje strażackie.
-
-[F_PASS1]
-Pożar ugaszony!
-
-[F_RANGE]
-~g~Radiostacja w samochodzie strażackim ma zbyt mały zasięg - zbliż się bardziej w stronę remizy!
-
-[C_BREIF]
-~g~Podejrzany ostatnio widziany był w rejonie ~a~.
-
-[C_RANGE]
-~g~Radiostacja w samochodzie ma zbyt mały zasięg, zbliż się bardziej w stronę komisariatu!
-
-[DODO_FT]
-Leciałeś przez ~1~ sekund!
-
-[EBAL_A]
-Znam takie miejsce na skraju Dzielnicy Czerwonych Świateł, w którym możemy się zamelinować na jakiś czas,
-
-[EBAL_A1]
-ale moje ręce są do niczego, więc lepiej ty prowadź, brachu.
-
-[EBAL_1]
-Naciśnij klawisz ~h~ ~k~~VEHICLE_ENTER_EXIT~~w~, aby ~h~wsiąść ~w~lub ~h~wysiąść~w~ z pojazdu.
-
-[EBAL_1B]
-Naciśnij klawisz ~h~ ~k~~VEHICLE_ENTER_EXIT~~w~, aby ~h~wsiąść ~w~lub ~h~wysiąść~w~ z pojazdu.
-
-[EBAL_2]
-~g~Wracaj do samochodu!
-
-[EBAL_3]
-To jest ~h~radar~w~. Korzystaj z niego podczas poruszania się po mieście. Jedź za ~h~kropką~w~ na ~h~radarze~w~, aby dotrzeć do kryjówki!
-
-[EBAL_D]
-Jest tu taki jeden gość, który zna kogo trzeba. Nazywa się Luigi.
-
-[EBAL_D1]
-Niejedno razem przeszliśmy. Dla ciebie też pewnie znajdzie się jakaś robota. Zajrzyjmy do niego!
-
-[EBAL_E]
-Wpadniemy tam, a ja przedstawię cię komu trzeba.
-
-[EBAL_I]
-Szef zaraz wyjdzie do ciebie...
-
-[EBAL_J]
-8-Ball ma jakiś interes na górze.
-
-[EBAL_K]
-Może zrobisz coś dla mnie?
-
-[EBAL_L]
-Trzeba podwieźć jedną z moich dziewczynek. Załatw gablotę i odbierz Misty z kliniki. Przywieź ją tutaj.
-
-[EBAL_N]
-I lepiej cały czas gap się tylko na drogę!
-
-[EBAL_4]
-~r~8-Ball nie żyje~!
-
-[EBAL_5]
-~g~Załatw samochód!
-
-[EBAL_6]
-~g~Zabierz Misty!
-
-[LM1]
-'DZIEWCZYNKI LUIGIEGO'
-
-[LM2]
-'MOJE DZIWKI NIE ĆPAJĄ!'
-
-[LM3]
-'WOŻĄC PANNĘ MISTY'
-
-[LM5]
-'ACH, CÓŻ TO BYŁ ZA BAL...'
-
-[LM1_2]
-~g~Zabierz Misty do klubu 'U Luigiego'.
-
-[LM1_3]
-~g~Naciśnij klakson, aby zaprosić dziewczynę do samochodu.
-
-[LM1_6]
-~g~Wracaj do samochodu!
-
-[LM1_7]
-Zatrzymaj samochód obok Misty i poczekaj, aż wsiądzie.
-
-[LM1_8]
-Możesz wrócić do Luigiego i zapytać go o pracę albo pozwiedzać Liberty City.
-
-[LM2_A]
-Na ulicy pojawił się nowy towar, HEROINA.
-
-[LM2_E]
-Jakiś mądrala wciska ten syf moim dziewczynkom na Portland Harbor.
-
-[LM2_B]
-Jedź tam i zapoznaj jego twarz z bejsbolem!
-
-[LM2_G]
-Należy mi się jakaś rekompensata za tę zniewagę!
-
-[LM2_1]
-~g~Weź jego samochód i przemaluj go.
-
-[LM2_2A]
-Użyj klawisza ~h~ ~k~~PED_FIREWEAPON~~w~, aby zadawać ciosy ~h~pięścią ~w~i ~h~nogą~w~ lub ~h~uderzyć kijem ~w~!
-
-[LM2_2C]
-Użyj klawisza ~h~ ~k~~PED_FIREWEAPON~~w~, aby zadawać ciosy ~h~pięścią ~w~i ~h~nogą~w~ lub ~h~uderzyć kijem ~w~!
-
-[LM2_2D]
-Użyj klawisza ~h~ ~k~~PED_FIREWEAPON~~w~, aby zadawać ciosy ~h~pięścią ~w~i ~h~nogą~w~ lub ~h~uderzyć kijem ~w~!
-
-[LM2_3]
-~g~Schowaj samochód w kryjówce Luigiego!
-
-[LM2_4]
-~g~Przemaluj samochód!
-
-[LM3_A]
-Ej, muszę z tobą pogadać... Spoko, Mick, dokończymy później.
-
-[LM3_B]
-Jak leci, młody?
-
-[LM3_C]
-Syn Dona, Joey, chce się zabawić ze swoją ulubioną dziewczynką, Misty.
-
-[LM3_D]
-Jedź po nią na Wzgórza Hepburn...
-
-[LM3_E]
-ale uważaj, to terytorium gangu Diablo.
-
-[LM3_F]
-Potem odwieź ją do warsztatu Joeya w Trenton, byle szybko.
-
-[LM3_H]
-więc gap się na drogę, a nie na cycki Misty!
-
-[LM3_2]
-~g~Zabierz Misty do Joeya.
-
-[LM3_4]
-~g~Jedź po Misty!
-
-[LM3_5]
-To ty pracujesz teraz jako szoferak dla Luigiego, co? Najwyższy czas, od dawna potrzebujemy zaufanego kierowcy!
-
-[LM3_7]
-Zajmę się tobą za chwilkę, iskierko.
-
-[LM3_10]
-~g~Zdobądź samochód!
-
-[LM4_B]
-Jedź tam i załatw dla mnie ten problem.
-
-[LM4_C]
-Jeżeli potrzebujesz spluwy, wpadnij na zaplecze sklepu Amu-Nacja, naprzeciwko stacji metra.
-
-[LM5_A]
-Przy Moście Callahan, w budynku starej szkoły trwa Bal Policjanta.
-
-[LM5_B]
-Skoro budynek jest stary, to i goście zapewne będą szukać rozrywek 'w starym stylu'.
-
-[LM5_C]
-Moje dziewczyny pracują na ulicach w całym mieście.
-
-[LM5_D]
-Zawieź je na bal, aby mogły solidnie popracować.
-
-[LM5_1]
-~g~Jeżeli zabierzesz za dużo dziewczyn, to się poobijają w środku!~g~ Najpierw wysadź te, które już masz, potem wróć po następne.
-
-[LM5_2]
-~r~Jedna z dziewczyn Luigiego jest już tylko kupą padliny!
-
-[LM5_3]
-~g~Jest ci potrzebny samochód!
-
-[LM5_4]
-~g~Zgarnij dziewczyny pracujące w St. Mark's.
-
-[LM5_5]
-~g~Zawieź dziewczyny na Bal Policjanta!
-
-[LM5_8]
-~g~Dziewczyny na balu: ~1~
-
-[JM2]
-'ŻEGNAJ 'OKRĄGŁY' LEE CHONG'
-
-[JM4]
-'SZOFER CIPRIANIEGO'
-
-[JM5]
-'TRUP W BAGAŻNIKU'
-
-[JM1_1]
-~g~Zabierz samochód Forelliego do warsztatu 8-Balla na północ stąd, zaraz za salonem 'Auta na Kredyt'.
-
-[JM1_2]
-~g~Potem zaparkuj wózek z powrotem na właściwym miejscu pod Bistro Marcos.
-
-[JM1_3]
-~g~Uaktywnij bombę i spadaj stamtąd!
-
-[JM1_4]
-~g~Niszczysz samochód! Napraw go!
-
-[JM1_5]
-~g~Bomba w samochodzie nie została uzbrojona!
-
-[JM1_6]
-~g~Zaparkuj samochód we właściwej pozycji.
-
-[JM1_8A]
-~y~Hej, przecież to mój kumpel!
-
-[JM1_8B]
-~y~Warsztat jest zautomatyzowany. Po prostu wjedź do środka, zatrzymaj samochód, a obsługa załatwi całą resztę.
-
-[JM1_8C]
-~y~Pierwszy raz montujemy ładunek za darmo, ale za każdym następnym razem będziesz musiał zapłacić.
-
-[JM2_A]
-'Okrągły' Lee Chong handluje prochami dla jakiegoś nowego gangu z Kolumbii... Czy z Kolorado... Nieważne...
-
-[JM2_B]
-Nie pamiętam. Zresztą, kogo to obchodzi.
-
-[JM2_D]
-Ten szczurek właśnie sprzedaje ostatnie sajgonki, rozumiesz?
-
-[JM2_E]
-Masz go zdmuchnąć!
-
-[JM2_G]
-Załatw sobie dziewiątkę. Znajdziesz ten sklep, nie?
-
-[JM2_H]
-Tylko pamiętaj, w Chinatown lepiej dobrze pilnować własnego dupska. To terytorium Triady.
-
-[JM3_A]
-W porządku, mam zamiar skubnąć ciężarówkę z wypłatami.
-
-[JM3_B]
-Codziennie wyjeżdża na miasto z okolic Chinatown.
-
-[JM3_C]
-Zwykłe kule nawet nie zarysują jej pancerza, więc musisz po prostu zdobyć ciężki samochód i zepchnąć ją z drogi.
-
-[JM3_D]
-Jak mocno walniesz, to ci tchórze z ochrony zwieją, gdzie pieprz rośnie.
-
-[JM3_E]
-Wtedy zabierz ciężarówkę do magazynu w dokach - moi ludzie już się nią tam zajmą.
-
-[JM3_F]
-Ciężarówka nie będzie na ciebie czekać, dlatego lepiej się streszczaj.
-
-[JM3_1]
-~g~Zabierz ciężarówkę do kryjówki.
-
-[JM3_2]
-~g~Taranuj ciężarówkę dopóki poziom jej uszkodzeń nie przekroczy 70 procent.
-
-[JM4_B]
-O, to jest ten gość, o którym ci mówiłem!
-
-[JM4_C]
-Posłuchaj, on nie jest Włochem i żaden z niego mechanik, ale potrafi radzić sobie z problemami.
-
-[JM4_D]
-To jest Pops Capo, a to Tony Cipriani.
-
-[JM4_E]
-Tak, Tony Cipriani to ja.
-
-[JM4_F]
-Podrzuć go do restauracji Mamuśki w St. Marks.
-
-[JM4_G]
-Jeszcze jedno. Posłuchaj, planuję taką robótkę, do której potrzebny jest dobry kierowca. Wpadnij później, to pogadamy, OK?
-
-[JM4_2]
-Zaczekaj tutaj. Nie gaś silnika - to nie jest wizyta towarzyska.
-
-[JM4_3]
-To pułapka Triad! Zabierz nas stąd, młody!
-
-[JM4_4]
-Triady myślą, że mogą ze mną zadzierać... ZE MNĄ!
-
-[JM4_6]
-Ostrożnie z tym wozem! Mówiłem, bez numerów!
-
-[JM4_7]
-~g~Zabierz Toniego do restauracji jego matki.
-
-[JM4_8]
-~r~Toni został załatwiony!
-
-[JM5_A]
-Pięknie! Po prostu pięknie.
-
-[JM5_B]
-Oto i facet, którego mi potrzeba!
-
-[JM5_D]
-Jeden z braci Forelli myślał, że jest bystrzejszy niż woda w kiblu, a więc doczekał się odpowiedniej kary.
-
-[JM5_E]
-Zabierz samochód z ciałem do zgniatarki w Harwood, OK?
-
-[JM5_1]
-~g~Zabierz samochód do zgniatarki!
-
-[JM5_2]
-~g~To bracia Forelli!
-
-[JM6_A]
-Ale z niej sztuka, co?
-
-[JM6_B]
-W porząsiu, posłuchaj. Załatw sobie gablotę i jedź do kryjówki w St. Marks. Tam zabierzesz paru moich kumpli.
-
-[JM6_C]
-Robią napad na bank i potrzebują kierowcy.
-
-[JM6_D]
-Dałem im słowo, że znasz się na tym fachu, więc nie spieprz sprawy, dobra?
-
-[JM6_E]
-Dowieź ich do banku przed godziną piątą i nie waż się spóźnić nawet minutę.
-
-[JM6_2]
-Nie gaś silnika, zaraz wracamy.
-
-[JM6_3]
-Zabierz nas stąd!!
-
-[JM6_4]
-Zgub gliniarzy i dowież nas do kryjówki!
-
-[JM6_6]
-~g~Skombinuj jakiś samochód, który będzie trochę mniej rzucał się w oczy.
-
-[JM6_7]
-~g~Musisz zabrać wszystkich 3 bandytów, aby móc przeprowadzić skok!
-
-[TM1]
-'ZABIERZ BRUDY DO PRALNI'
-
-[TM2]
-'HARACZ'
-
-[TM3]
-'SALVATORE ZWOŁUJE NARADĘ'
-
-[TM4]
-'TRIADY I TROSKI'
-
-[TM5]
-'SMAŻONE RYBY'
-
-[TONI_P]
-Mam dla ciebie pilną pracę, Toni!
-
-[TM1_A]
-~w~Siadaj, synu! Siadaj, zamknij jadaczkę i słuchaj.
-
-[TM1_B]
-~w~Więc pralnie nie chcą płacić haraczu, co?
-
-[TM1_C]
-~w~Triady myślą, że mogą mi podskakiwać?
-
-[TM1_D]
-~w~Nauczymy tych dmuchanych twardzieli, co to znaczy być prawdziwym twardzielem.
-
-[TM1_E]
-~w~Tak, damy im lekcję pokory. Mój syn nie będzie znosić upokorzeń od jakiejś Triady!
-
-[TM1_F]
-~w~Twój ojciec, Panie świeć nad jego duszą, jeszcze na Sycylii trzymał ich krótko i nie pozwalał, żeby Triady wciskały mu kit.v
-
-[TM1_G]
-~w~Przepraszam, Mamo. Tak jest, Mamo.
-
-[TM1_H]
-~w~Chcę, żebyś zniszczył ciężarówki z pralni
-
-[TM1_I]
-~w~i rozdeptał każdego sługusa Triad, który wejdzie ci w drogę.
-
-[TM1_J]
-~w~8-Ball załatwi ci wszystko, co jest potrzebne do tej roboty.
-
-[TM2_A]
-~w~TONI gdzieś polazł, znowu będzie straszyć ludzi albo przynajmniej usiłować kogoś przestraszyć.
-
-[TM2_AA]
-~w~Nigdy nie będzie nawet w połowie takim twardzielem jak jego Papa. Zostawił dla ciebie kartkę na stole.
-
-[TM2_B]
-~w~Pralnie zgodziły się zapłacić - spisałeś się dobrze, synu!
-
-[TM2_C]
-~w~Odbierz forsę i przywieź ją tutaj. Uważaj na Triady.
-
-[TM2_D]
-~w~Możliwe, że będą chcieli podłożyć nam świnię, ale nie daj sobie wciskać żadnego gówna.
-
-[TM2_E]
-~w~Nikt, powtarzam, nikt nie zadziera z TONIM CIPRIANI!
-
-[TM2_1]
-~g~Odwieź forsę Toniemu!!!
-
-[TM2_2]
-~g~Zdmuchnąłeś ich wszystkich!
-
-[TM3_MA]
-~w~Nie wiem, gdzie on się podziewa!
-
-[TM3_MB]
-~w~Jak pragnę zdrowia, ten mój chłopak czasami jest taki głupi.
-
-[TM3_MC]
-~w~Jego ojciec był zupełnie inny. Zawsze silny, męski, u steru wydarzeń...
-
-[TM3_A]
-~w~Don Salvatore zwołał naradę.
-
-[TM3_B]
-~w~Masz odebrać z warsztatu limuzynę i jego chłopaka, Joeya.
-
-[TM3_C]
-~w~Potem zabierz Luigiego z klubu i wróć tutaj po mnie.
-
-[TM3_D]
-~w~Razem pojedziemy do domu szefa.
-
-[TM3_E]
-~w~Triady nie znają umiaru.
-
-[TM3_F]
-~w~Chcą wojny, będą mieli wojnę.
-
-[TM3_G]
-~w~Teraz zmykaj.
-
-[TM3_1]
-~g~Odbierz limuzynę od Joeya.
-
-[TM3_2]
-~g~Teraz jedź po Luigiego.
-
-[TM3_3]
-~g~Teraz jedź po Toniego.
-
-[TM3_4]
-~g~Zawieź ferajnę do rezydencji Salvatore.
-
-[TM3_5]
-~y~Triady przygotowały zasadzkę!
-
-[TM4_B]
-~w~A więc WOJNA! Triady używają jako przykrywki fabryki przetwórstwa ryb.
-
-[TM4_C]
-~w~Większość ich interesów odbywa się na targu rybnym w chińskiej dzielnicy.
-
-[TM4_D]
-~w~Pralnie nadal wiszą nam haracz za ochronę.
-
-[TM4_E]
-~w~Żółtki myślą, że Triady ich obronią, więc czas wymierzyć im stosowną karę.
-
-[TM4_F]
-~w~Weź tych dwóch chłopaków i załatwcie szefów Triady!
-
-[TM4_G]
-~w~Tam, u diabła, jeżeli nadarzy się okazja, to załatwcie też paru żołnierzy Triady.
-
-[TM4_GAT]
-~g~Do środka może wjechać tylko ciężarówka Triad.
-
-[TM5_B]
-~w~Wystarczy już tego pitolenia.
-
-[TM5_C]
-~w~Czas wykończyć Triady w Liberty raz na zawsze!
-
-[TM5_D]
-8-Ball założył ładunek wybuchowy w śmieciarce.
-
-[TM5_E]
-~w~To jest bomba z zegarem czasowym, więc jak się spóźnisz, nie pozostanie po tobie żaden ślad. Jedź po śmieciarkę.
-
-[TM5_F]
-~w~Tylko ostrożnie, 8-Ball mówi, że mechanizm jest cholernie czuły i byle wstrząs może spowodować wybuch!
-
-[TM5_G]
-~w~Zaparkuj między cysternami z benzyną i znikaj stamtąd!
-
-[TM5_H]
-~w~Zaparkuj pomiędzy zbiornikami z gazem i spadaj gdzie pieprz rośnie!
-
-[TM5_I]
-~w~Chcę, żeby na miasto spadł deszcz makreli.
-
-[TM5_J]
-~w~Zobaczysz, tym razem to nie żadne wielkanocne bum-bum, tylko prawdziwa plaga biblijna!
-
-[FM2]
-'RÓWNO Z TRAWĄ'
-
-[FM4]
-'OSTATNIE PROŚBY'
-
-[FM1_A]
-~w~Ja i moi ludzie musimy obgadać parę kwestii,
-
-[FM1_B]
-~w~a więc ty zapewnisz mojej dziewczynie rozrywkę na wieczór.
-
-[FM1_C]
-~w~HEJ, MARIA! RUSZ DUPĘ!
-
-[FM1_D]
-~w~Głupia suka, zawsze się tak zachowuje.
-
-[FM1_E]
-~w~A oto i ona, jedyna w swoim rodzaju królowa piękności!
-
-[FM1_F]
-~w~Co tam robiłaś tyle czasu?
-
-[FM1_G]
-~w~Cokolwiek to było, na pewno straciłem na tym jakieś pieniądze.
-
-[FM1_H]
-~w~Chyba nie myślisz, że jestem tu, bo lubię z tobą gadać?
-
-[FM1_I]
-~w~Wsiadaj do samochodu i zamknij swoją wielką gębę.
-
-[FM1_J]
-~w~Możesz zabrać limuzynę, ale przyprowadź ją z powrotem w jednym kawałku, zrozumiano?
-
-[FM1_K]
-~w~I uważaj na nią! Ona lubi pakować się w kłopoty!
-
-[FM1_L]
-~w~Dość! Twój nowy piesek gończy na pewno zna już te historyjki,
-
-[FM1_M]
-~w~a poza tym to przecież kawał chłopa!
-
-[FM1_N]
-~w~Hej, piesku! Odwiedzimy Chico i załatwimy jakieś dopalacze na imprezę.
-
-[FM1_P]
-~g~To właśnie Chico, podjedź do niego.
-
-[FM1_S]
-~w~Jak sobie życzysz, moja pani.
-
-[FM1_TT]
-~w~NALOT POLICYJNY!
-
-[FM1_1]
-~g~Wracaj do limuzyny!
-
-[FM1_2]
-~g~Wsiadaj do limuzyny!
-
-[FM1_3]
-~r~Jeżeli zostawisz Marię, Salvatore każe cię obić jak psa! Zawróćj i zabierz ją ze sobą!
-
-[FM1_4]
-~g~Zostawiłeś kobietę Dona! Wracaj do magazynu i zaczekaj na Marię!
-
-[FM1_5]
-~g~Zawieź Marię do domu Salvatore tak, aby włos jej z głowy nie spadł!
-
-[FM1_6]
-~g~Chico nie będzie czekał wiecznie - zabierz Marię na wybrzeże!
-
-[FM1_7]
-~r~Maria nie żyje! Salvatore nie ucieszy się z tej wiadomości...
-
-[FM1_8]
-~r~Załatwiłeś dostawcę Marii!!!
-
-[FM2_J]
-Zostaw nas na chwilkę samych.
-
-[FM2_A]
-Kartel Kolumbijski produkuje HEROINĘ gdzieś na terenie Liberty.
-
-[FM2_K]
-ale nadal nie wiemy, gdzie, a oni działają tak, jakby z góry znali wszystkie nasze posunięcia.
-
-[FM2_L]
-Za barem 'U Luigiego' pracuje pewien gość. Nazywa się Kudłaty Bob.
-
-[FM2_M]
-Ostatnio wydaje więcej kasy niż mógłby zarobić.
-
-[FM2_N]
-Zazwyczaj po pracy wraca do domu taksówką. Jedź za nim.
-
-[FM2_O]
-A jeżeli okaże się, że to nasz kret... Zabij go!
-
-[FM2_F]
-Oto nasz mały przyjaciel, pan wielka gęba we własnej osobie.
-
-[FM2_G]
-Ktoś cię śledził? Wiesz, że to, co się tu dzieje, to nasz mały sekret.
-
-[FM2_H]
-Nie, nikt mnie nie śledził. Masz mój towar?
-
-[FM2_I]
-Masz swoje prochy, śmieciu, a teraz mów.
-
-[FM2_P]
-A więc rodzina Leone prowadzi teraz wojnę na dwa fronty.
-
-[FM2_Q]
-Z Triadami toczą wojnę o terytorium i wygląda na to, że żadna ze stron nie ma zamiaru się poddać.
-
-[FM2_R]
-Z drugiej strony, Joey Leone wplątał się w krwawe porachunki z rodziną Forellich.
-
-[FM2_S]
-Rodzina Leone z każdym dniem traci ludzi i wpływy w mieście.
-
-[FM2_T]
-Salvatore zaczyna zachowywać się jak niebezpieczny dla otoczenia paranoik. Podejrzewa wszystkich i wszędzie wietrzy spisek.
-
-[FM2_U]
-Ale jeżeli wszyscy są tak lojalni jak ty, to nie ma się o co martwić, prawda?
-
-[FM2_1]
-~g~To Kudłaty Bob!
-
-[FM2_2]
-~g~Kudłaty wyszedł z klubu - śledź go!
-
-[FM2_5]
-~g~Zabierz go do Portland Harbor.
-
-[FM2_6]
-~r~Kudłaty nie wsiądzie do porozbijanej taksówki!
-
-[FM2_7]
-~r~Kudłaty zwiał! Spotkanie odwołane!
-
-[FM2_8]
-~g~Walnij Kudłatego Boba!
-
-[FM2_9]
-~r~Kudłaty Bob nie żyje!
-
-[FM2_10]
-~r~Kudłaty ucieka!
-
-[FM2_11]
-~g~Zaparkuj przed klubem 'U Luigiego'! Kudłaty Bob powinien niedługo wyjść.
-
-[FM2_12]
-~r~Zgubiłeś go!
-
-[FM3_A]
-~w~Powinniśmy sprzątnąć tych łajdaków z Kartelu,
-
-[FM3_B]
-~w~ale dopóki mamy na głowie wojnę z Triadami, nie mamy na to dość sił.
-
-[FM3_C]
-~w~Kartel zarabia ogromne pieniądze na sprzedaży tej syfiastej HEROINY.
-
-[FM3_D]
-~w~Jeżeli przypuścimy otwarty atak, rozsmarują nas na miazgę.
-
-[FM3_E]
-~w~Zapewne produkują prochy na tym wielkim statku, do którego doprowadził cię Kudłaty.
-
-[FM3_F]
-~w~Dlatego właśnie musimy działać z głową. I to z twoją głową.
-
-[FM3_G]
-~w~Chciałbym prosić cię, abyś zrobił mi osobistą przysługę i zniszczył tę fabrykę HERY, Salvatore.
-
-[FM3_H]
-~w~Jeżeli to ci się uda, spędzisz resztę życia w dostatku.
-
-[FM3_I]
-~w~Spotkaj się z 8-Ballem. On zna się na dynamicie jak nikt inny - będziesz potrzebował jego doświadczenia.
-
-[FM3_8A]
-~w~Mój czarnuch! Salvatore już dzwonił,
-
-[FM3_8B]
-~w~ale do takiej roboty potrzeba będzie sporo fajerwerków.
-
-[FM3_8D]
-~w~ale chyba wiesz, że żaden dolar z tej sumy nie zostanie zmarnowany.
-
-[FM3_8E]
-~w~W porządku, zróbmy to!
-
-[FM3_8F]
-~w~Mogę nastawić to maleństwo na wybuch, ale rany na moich łapskach jeszcze się nie wygoiły i nie poradzę sobię z giwerą.
-
-[FM3_8G]
-~w~Weź karabin i rozwal parę łbów.
-
-[FM3_4]
-~g~Zatrzymaj samochód i wypuść 8-Balla!
-
-[FM3_7]
-~r~Zgubiłeś 8-Balla!
-
-[FM3_8]
-~r~Strażnicy podnieśli alarm!
-
-[FM4_A]
-~w~To mój ulubiony czyściciel.
-
-[FM4_B]
-~w~Jestem z ciebie dumny, chłopcze Wybiłeś tym tępakom to ich gówno z głów.
-
-[FM4_C]
-~w~Zanim będziemy mogli uczcić twój sukces, mam dla ciebie jeszcze jedną małą robótkę.
-
-[FM4_D]
-~w~Na następnej przecznicy stoi samochód z klubu Lugiego.
-
-[FM4_E]
-~w~W środku jest cały upaćkany mózgiem.
-
-[FM4_F]
-~w~Musieliśmy pomóc jednemu gościowi namyślić się nad paroma sprawami i wyszedł z tego niezły bałagan.
-
-[FM4_H]
-~w~Zabierz ten samochód do zgniatacza, zanim wypatrzą go gliniarze.
-
-[AM3]
-'PAPARAZZO NA DNIE'
-
-[AM4]
-'WYPŁATA DLA RAYA'
-
-[AM5]
-DWULICOWY TANNER
-
-[AM1_A]
-Zanim przejdziemy do jakichkolwiek interesów, musimy wyjaśnić sobie
-
-[AM1_B]
-pewne kwestie. Wyłóżmy nasze karty na stół.
-
-[AM1_C]
-Należę do Yakuzy i wiem, że pracowałeś dla rodziny Salvatore Leone.
-
-[AM1_D]
-Myślę, że znajdzie się dla ciebie miejsce w naszej organiacji.
-
-[AM1_E]
-Ale najpierw musisz udowodnić, że naprawdę zerwałeś wszystkie związki z Mafią.
-
-[AM1_G]
-Zadbaj, aby nie dotarł do celu żywy.
-
-[AM1_H]
-W międzyczasie, ja i Maria pogawędzimy o starych dobrych czasach.
-
-[AM1_I]
-Asuka, przyszedł twój masażysta.
-
-[AM1_J]
-To nie żaden masażysta.
-
-[AM1_1]
-~g~Salvatore wychodzi z knajpy 'U Luigiego'!
-
-[AM1_2]
-~r~Zostałeś zauważony!
-
-[AM1_3]
-~r~Spudłowałeś do Salvatore!
-
-[AM1_4]
-~r~Znakomicie, wystraszyłeś cel! I ty uważasz się za zawodowca?
-
-[AM1_5]
-~g~Jedź do Dzielnicy Czerwonych Świateł i poczekaj, aż Salvatore wyjdzie z klubu.
-
-[AM1_7]
-~r~Salvatore siedzi sobie bezpiecznie w domu i sączy swój koktajl. Nie spodziewaj się, że ktoś nazwie cię 'Szakalem'!
-
-[AM1_8]
-~g~Salvatore będzie wychodzić z klubu Luigiego około ~1~:~1~
-
-[AM2_4]
-~g~Skradałeś się z gracją słonia w składzie porcelany!
-
-[AM3_A]
-Jakiś nieproszony reporter wtykał tu swój nos
-
-[AM3_B]
-Maria i ja jedziemy razem na małe wakacje, a ty pozbądź się tego zboczonego podglądacza.
-
-[AM4_A]
-A oto i mój ulubiony człowiek do każdej roboty!
-
-[AM4_B]
-Maria chciałaby cię widzieć, ale... nie może podejść. Powiem jej, że pytałeś.
-
-[AM4_C]
-Kto tam? Asuka? Wiem, że byłam niegrzeczną dziewczynką, ale naprawdę muszę do toalety! OK?
-
-[AM4_D]
-Czas, abyś poznał naszą wtyczkę w tutejszej policji.
-
-[AM4_E]
-Tu masz zapłatę za ostatnią robótkę, jaką dla nas wykonał.
-
-[AM4_F]
-Facet jest bardzo ostrożny, to chyba jasne.
-
-[AM4_G]
-Jak najszybciej odszukaj budkę telefoniczną w Torrington i czekaj na instrukcje.
-
-[AM5_A]
-Maria i ja wyszliśmy na zakupy.
-
-[AM5_B]
-Nasze źródło w policji donosi, że jeden z naszych kierowców to policyjny tajniak.
-
-[AM5_C]
-Bez samochodu nie jest groźny. Przyczepiliśmy do jego gabloty nadajnik.
-
-[AM5_D]
-Niech się dowie, czym grozi taka zabawa.
-
-[AM5_1]
-Tanner chyba ma coś do ciebie!
-
-[AS1]
-'PRZYNĘTA'
-
-[AS2]
-'ESPRESSO NA WYNOS!'
-
-[AS4]
-'OKUP'
-
-[AS1_A]
-~w~Miguel chyba uważa, że źle go traktuję.
-
-[AS1_B]
-~w~Mimo to zdradził mi, jak bardzo Catalina obawia się twojej zemsty.
-
-[AS2_A]
-~w~Nie doceniliśmy planów, jakie Catalina wiąże ze swoją heroiną.
-
-[AS2_B]
-~w~Marzy jej się coś więcej niż banda Yardies sprzedająca prochy na rogu.
-
-[AS2_D]
-~w~Sprzedają herę w swojej sieci budek ulicznych.
-
-[AS2_1]
-~g~Wszystkie budki z espresso w Portland zostałyzniszczone!!
-
-[AS2_2]
-~g~Wszystkie budki z espresso na Wyspie Staunton zostały zniszczone!!
-
-[AS2_3]
-~g~Wszystkie budki z espresso w Shoreside Vale zostały zniszczone!!
-
-[AS2_4]
-~r~Kartel ostrzegł swoich dilerów!!
-
-[AS2_5]
-~g~W Shoreside Vale i na Wyspie Staunton nadal stoi kilka budek z espresso!
-
-[AS2_6]
-~g~W Shoreside Vale nadal stoi kilka budek z espresso!
-
-[AS2_7]
-~g~Na Wyspie Staunton nadal stoi kilka budek z espresso!
-
-[AS2_8]
-~g~W Portland nadal stoi kilka budek z espresso
-
-[AS2_9]
-~g~W Portland i Shoreside Vale nadal stoi kilka budek z espresso
-
-[AS2_10]
-~g~W Portland i na Wyspie Staunton nadal stoi kilka budek z espresso
-
-[AS2_12]
-~g~Badaj dzielnice miasta i szukaj budek Espresso-2-Go!
-
-[AS3_A]
-~W~Przyciskamy już teraz czy poczekamy, aż trochę osłabnie?
-
-[AS3_B]
-~w~Popieść go trochę...
-
-[AS3_D]
-~w~Mój Człowiek do Każdej Roboty!
-
-[AS3_E]
-~w~Nudziłam się, więc wpadłam żeby dotrzymać Asuce towarzystwa.
-
-[AS3_1]
-~g~Odszukaj ~r~łódź~g~ i dopłyń do ~b~boi!
-
-[AS3_3]
-~g~Odczekaj, aż ~y~samolot~g~ rozpocznie podejście!!
-
-[AS3_5]
-~g~Zbierz ładunek!
-
-[AS3_4]
-~g~Użyj wyrzutni rakietowej aby zestrzelić ~y~samolot~g~!!
-
-[AS3_2]
-~b~Płyń do boi wyznaczających lądowisko! ~y~Samolot wykonuje już ostatnie podejście!!
-
-[AS3_6]
-~g~~1~ Z 8!
-
-[KM1]
-'UCIECZKA KANBU'
-
-[KM3]
-'ZDUSIĆ UKŁADY'
-
-[KM4]
-'SHIMA'
-
-[KM5]
-'UDERZENIE'
-
-[KM1_A]
-Moja siostra ma o tobie dobre mniemanie,
-
-[KM1_E]
-choć nie mogę sobie wyobrazić, żeby gaijin mógł dać nam coś innego niż rozczarowania.
-
-[KM1_B]
-Być może mógłbyś pomóc w rozwiązaniu problemu, który leży mi na sercu.
-
-[KM1_F]
-Rzecz jasna, porażka oznacza utratę honoru.
-
-[KM1_C]
-Kanbu, członek Yakuzy, przebywa w areszcie, gdzie czeka na proces.
-
-[KM1_G]
-To ceniony członek rodziny.
-
-[KM1_H]
-Odbij go z aresztu i przywieź do dojo w Bedford Point.
-
-[KM1_D]
-Dziękujemy ci za twoje bezinteresowne działania. Jeżeli kiedykolwiek będziesz potrzebował pomocy, dojo z radością przydzieli ci dwóch wojowników, którzy staną u twego boku.
-
-[KM1_1]
-~g~Ukradnij radiowóz!
-
-[KM1_2]
-~g~Załóż bombę w samochodzie!
-
-[KM1_3]
-~g~Teraz zawieź go do dojo Yakuzy.
-
-[KM1_5]
-~g~W porządku, teraz jazda na posterunek.
-
-[KM1_6]
-~g~Zamontuj w samochodzie ładunek wybuchowy!
-
-[KM1_7]
-~g~Tylko dla pojazdów policyjnych!
-
-[KM1_9]
-~r~Nie użyłeś bomby samochodowej, aby zniszczyć mur.
-
-[KM1_10]
-~r~Kanbu z Yakuzy jest trupem - tak samo jak twój honor!
-
-[KM1_11]
-~r~Ściągnąłeś sobie na głowę kłopoty!
-
-[KM2_A]
-Nie sposób przecenić znaczenia etykiety w tej branży.
-
-[KM2_B]
-Na moją hańbę, pewien człowiek oddał mi kiedyś przysługę, a ja nigdy nie miałem okazji, aby mu się odwdzięczyć.
-
-[KM2_C]
-Konikiem tego człowieka są samochody. Poprosił mnie, abym zgromadził pewne modele aut do jego kolekcji.
-
-[KM2_F]
-Od tego zależy mój honor.
-
-[KM2_2]
-~g~Samochód dostarczony.
-
-[KM3_A]
-Kiedy nadciągają ciemne chmury, głupiec odwraca wzrok, a mędrzec stawia im czoła.
-
-[KM3_B]
-Kartel Kolumbijski zignorował liczne prośby, aby nie naruszać naszych interesów w Liberty City.
-
-[KM3_C]
-Teraz negocjują układ z Jamajczykami, aby jeszcze bardziej nas upokorzyć.
-
-[KM3_D]
-Właśnie finalizują układ o podziale wpływów w mieście.
-
-[KM3_F]
-Weź jednego z moich ludzi, ukradnij samochód gangu Yardie i jedź przekazać Kolumbijczykom nasze wyrazy szacunku.
-
-[KM3_E]
-Nasz honor wymaga, aby wszyscy umarli.
-
-[KM3_2]
-~g~Jedź po swój kontakt.
-
-[KM3_3]
-~g~Spotkanie odbędzie się na parkingu szpitalnym w Rockford!
-
-[KM3_4]
-~r~Uciekają!
-
-[KM3_6]
-~g~Zabij ich, zabij ich wszystkich!
-
-[KM3_8]
-~g~Aby wykonać zadanie, potrzebujesz samochodu gangu Yardie.
-
-[KM3_9]
-~r~Jeden z Kolumbiczyków nie żyje, układ odwołany.
-
-[KM3_10]
-~r~Twój kontakt nie żyje!
-
-[KM4_A]
-Jeżeli chcesz być naprawdę silny, nie możesz nigdy okazywać słabości.
-
-[KM4_C]
-Jak najszybciej odbierz pieniądze, abyśmy mogli wpłacić je na konto kasyna.
-
-[KM4_1]
-Nie mam wam czym zapłacić, ale nawet gdybym miał, to i tak bym tego nie zrobił!
-
-[KM4_9]
-Jakaś banda szczeniaków właśnie stąd uciekła! Zabrali wszystko!
-
-[KM4_2]
-Nie ma z was żadnego pożytku.
-
-[KM4_10]
-A czy ty w ogóle należysz do Yakuzy...?
-
-[KM4_3]
-Nie za to wam płacę, obwiesie. Gdybym chciał takiej ochrony, to zaprosiłbym cholerną policję.
-
-[KM4_4]
-~g~Wymierz karę gangowi odpowiedzialnemu za napad i odzyskaj ~b~opłatę za ochronę~g~!
-
-[KM4_7]
-~r~Sklepikarz wydał ostatnie tchnienie!
-
-[KM4_5]
-Donald Love zaprasza cię do swojego ogrodu herbacianego na rozmowę.
-
-[KM4_6]
-Tam są pieniądze!
-
-[KM4_8]
-~r~Teczka odebrana!
-
-[KM5_A]
-TO TY! Wybrałeś najwłaściwszy moment, aby pokazać swoją bezwartościową postać!
-
-[KM5_B]
-Zdaje się, że twoje marne próby, aby odwieść Jamajczyków
-
-[KM5_B1]
-od skumplowania się z Kartelem były całkowicie chybione!
-
-[KM5_C]
-Handlarze Yardie krążą po ulicach Liberty, sprzedając woreczki HERY tak, jakby sprzedawali hotdogi!
-
-[KM5_D]
-Te wieprze z Kartelu śmieją się z nas, ze mnie!
-
-[KM5_E]
-Dam ci ostatnią szansę, abyś mógł dowieść, że zaufanie, jakim obdarzyła cię moja siostra, nie było bezpodstawne.
-
-[KM5_F]
-Rozjedź tych śmieci i spłucz swoją hańbę w potokach krwi naszych wrogów!!!
-
-[KM5_3]
-~r~Nie udało ci się zabić co najmniej ~1~ członków gangu Yardie.
-
-[KM5_4]
-~g~Gratulacje, zabiłeś ~1~ członków gangu Yardie.
-
-[KM5_5]
-~g~Gratulacje, zabiłeś ~1~ członków gangu Yardie. PREMIA $~1~.
-
-[RM1]
-'UCISZYĆ KAPUSIA'
-
-[RM3]
-'GONIĄC DOWODY'
-
-[RM4]
-'NA RYBY'
-
-[RM5]
-'DOKOŃCZYĆ DZIEŁO'
-
-[RM1_D]
-Siedzi pod ochroną policji w budynku WitSec w Newport, w którymś z mieszkań za parkingiem.
-
-[RM1_E]
-Podpal tę budę, to powinno ich wypłoszyć. Wtedy na nich zapoluj - zadbaj, aby McAffrey już nigdy z nikim nie rozmawiał!
-
-[RM1_1]
-~g~Znajdź miejsce, w którym przebywa chroniony świadek.
-
-[RM1_2]
-~g~Wykończ McAffrey'a!
-
-[RM2_A1]
-Hej, synu, chodź tutaj!
-
-[RM2_A]
-Mój stary kumpel z wojska prowadzi sklepik w Rockford.
-
-[RM2_D]
-Potrzeba mu wsparcia. W zamian możesz liczyć na spore obniżki cen na spluwy, które ma na składzie.
-
-[RM2_E]
-Ray wspominał, że ktoś przyjdzie... ale nie myślałem, że przyśle takiego szczeniaka.
-
-[RM2_F]
-No cóż, trzy ramiona to zawsze więcej niż jedno, więc bierz broń według życzenia.
-
-[RM2_G]
-~g~Zasuwaj i pilnuj Phila!
-
-[RM2_H]
-~r~Phil zginął!
-
-[RM2_L]
-No, no! Gdybyś był z nami wtedy w Nikaragui, może jeszcze miałbym swoją rękę!
-
-[RM2_N]
-Zostaw forsę. Teraz lepiej znikaj, sam zajmę się policją.
-
-[RM3_D]
-Dowody będą przewożone przez miasto.
-
-[RM3_E]
-Musisz staranować ten samochód i zebrać wszystkie dowody, co do jednego!
-
-[RM3_F]
-Kiedy już je zbierzesz, zostaw je w samochodzie i podpal go.
-
-[RM3_G]
-Obaj będziemy mieć sporo korzyści, chłopcze.
-
-[RM3_1]
-~g~Zostaw dowody w samochodzie i podpal wóz.
-
-[RM3_4]
-~g~Samochód prokuratury zgubił dowody!
-
-[RM3_6]
-~r~Teraz te fotografie obejrzy całe miasto!
-
-[RM3_7]
-~g~Podpal samochód!
-
-[RM4_A]
-Podejrzewam, że mój wspólnik to kret.
-
-[RM4_C]
-On każdego wieczoru wypływa na morze, w okolice latarni przy Portland Rock, aby łowić ryby.
-
-[RM4_D]
-Podwędź policyjną łódź i dopilnuj, aby poszedł na dno razem ze swoimi zdradzieckimi planami!
-
-[RM4_1]
-~g~Ukradnij łódź policyjną!
-
-[RM4_2]
-~g~Płyń do latarni morskiej i załatw kolegę Raya!
-
-[RM5_A]
-Ty nieudaczny łajdaku!
-
-[RM5_A1]
-Schrzaniłeś robotę! Moja dupa już się zaczyna smażyć, a ty nie potrafisz zabić nawet cholernej muchy.
-
-[RM5_B]
-Zapłaciłem ci kupę szmalu, żebyś sprzątnął świadka, a on dalej żyje!
-
-[RM5_B1]
-Dzisiaj będzie składał pierwsze zeznania w Sądzie Federalnym!
-
-[RM5_C]
-Lada chwila będzie wyjeżdżał ze Szpitala Ogólnego Carson w Rockford.
-
-[RM5_D]
-Jeżeli on zacznie sypać, koniec ze mną...
-
-[RM5_E]
-więc lepiej zrób to, za co ci zapłaciłem!
-
-[RM5_1]
-~g~Przechwyć karetkę.
-
-[RM5_2]
-~g~Zostałeś rozpoznany!
-
-[RM5_3]
-~g~To była tylko przynęta!
-
-[RM5_4]
-~g~Kule nie przebiją pancernego kadłuba!
-
-[RM5_5]
-~g~Pancerna karoseria jest ognioodporna!
-
-[RM5_7]
-~r~Świadek dotarł na miejsce!
-
-[RM5_8]
-~g~Świadek poszedł na dno!
-
-[LOVE2]
-'SPRZĄTNĄĆ WAKA-GASHIRĘ'
-
-[LOVE3]
-'KROPLA W OCEANIE'
-
-[LOVE1_A]
-Przede wszystkim pozwól mi podziękować, że zechciałeś zająć się tą sprawą o charakterze osobistym.
-
-[LOVE1_F]
-W dzisiejszych czasach ludzie nie szanują żadnych porozumień.
-
-[LOVE1_D]
-Usiłują wymusić na mnie dodatkowe pieniądze, ale ja nie wierzę w renegocjacje.
-
-[LOVE1_E]
-Umowa to umowa, więc nie powinni spodziewać się ode mnie nawet grosza.
-
-[LOVE1_G]
-Uratuj mojego przyjaciela, zrób wszystko, co będzie trzeba.
-
-[LOVE1_2]
-~g~Uratuj starego pana z dalekiego wschodu.
-
-[LOVE1_3]
-~g~Zabierz starego pana z dalekiego wschodu do budynku Donalda Love'a.
-
-[LOVE1_4]
-~g~Stary pan z dalekiego wschodu musi się znajdować w jednym z tych garaży...
-
-[LOVE1_6]
-~r~Flaki starego pana z dalekiego wschodu zostały rozsmarowane po całej ulicy!
-
-[LOVE1_7]
-~g~Brama otworzy się wyłącznie przed samochodem gangu kolumbijskiego.
-
-[LOVE2_A]
-Nic tak nie wpływa na spadek cen nieruchomości, jak stara dobra wojna gangów.
-
-[LOVE2_B]
-No, może z wyjątkiem wybuchu epidemii... ale w tym wypadku nie trzeba się posuwać aż tak daleko.
-
-[LOVE2_C]
-Zauważyłem, że Yakuza i Kolumbijczycy nie są do siebie przyjaźnie nastawieni.
-
-[LOVE2_D]
-Skorzystajmy z tej szansy.
-
-[LOVE2_E]
-Masz zabić Waka-gashirę gangu Yakuzy, Kenji'ego Kasena.
-
-[LOVE2_F]
-Kenji właśnie jest na spotkaniu na szczycie parkingu piętrowego w Newport.
-
-[LOVE2_G]
-Załatw sobie samochód Kartelu i rozsmaruj go na ścianie!
-
-[LOVE2_H]
-Zrób to tak, aby Yakuza obciążyła Kartel za ten akt.
-
-[LOVE2_1]
-~g~Jedź do Fort Staunton i zwędź samochód gangu kolumbijskiego!
-
-[LOVE2_2]
-~g~Teraz jedź na ~p~parking wielopiętrowy w Newport~p~ i załatw Kenjiego!
-
-[LOVE2_3]
-~r~Jeżeli pojedziesz tam bez samochodu Kartelu, zostaniesz rozpoznany!
-
-[LOVE2_4]
-~r~Członkowie Yakuzy cię rozpoznali!
-
-[LOVE2_6]
-~r~Zabiłeś wszystkich świadków!!!
-
-[LOVE3_A]
-W czasach hipokryzji moralnej ciężko jest zdobyć niektóre cenne towary z zagranicy.
-
-[LOVE3_C]
-Pilot zrzuci do wody kilka pakunków.
-
-[LOVE3_D]
-Zbierz je, zanim wpadną w niepowołane ręce.
-
-[LOVE3_1]
-~g~Załatw sobie ~r~łódź~g~ i płyń za ~y~samolotem~g~!
-
-[LOVE4]
-'GRAND THEFT AERO'
-
-[LOVE5]
-'KONWOJENT'
-
-[LOVE4_A]
-Dziękuję za odzyskanie paczek. Przykro mi to mówić, ale była to jedynie przynęta.
-
-[LOVE4_B]
-Nie chciałem cię urazić, po prostu czasami w interesach trzeba tak postąpić.
-
-[LOVE4_C]
-Mój prawdziwy cel przez cały czas był ukryty w samolocie.
-
-[LOVE4_F]
-Przekupiłem kogo trzeba.
-
-[LOVE4_1]
-~r~Są tu ludzie z Kartelu Kolumbijskiego!
-
-[LOVE4_2]
-~g~Pakunek zniknął! Wyśledź Kolumbijczyków i odzyskaj ładunek.
-
-[LOVE4_3]
-~g~Firma budowlana Panlantic Construction?
-
-[LOVE4_5]
-~g~Paczka powinna nadal być w samolocie...
-
-[LOVE4_6]
-~g~Wjedź windą na wieżę!
-
-[LOVE5_B]
-Mój orientalny przyjaciel potrzebuje eskorty, kiedy będze wiózł mój najnowszy nabytek do specjalistów.
-
-[LOVE5_1]
-~g~Ruszamy!
-
-[LOVE5_2]
-~g~Potrzebujesz samochodu!
-
-[LOVE5_3]
-~g~Jedź przodem i zbadaj wylot tunelu!
-
-[LOVE5_4]
-~r~Osłaniaj ciężarówkę!
-
-[RM6]
-'NA WIDELCU'
-
-[RM6_A]
-Nikt cię nie śledził? To dobrze.
-
-[RM6_B]
-To już koniec. Jestem po uszy w gównie i nadal się zapadam.
-
-[RM6_D]
-Jestem na widelcu, więc postanowiłem zniknąć.
-
-[RM6_E]
-Zawieź mnie na mój samolot, a dobrze ci się odwdzięczę!
-
-[RM6_666]
-Zatroszcz się o mojego kuloodpornego Patriota. Do zobaczenia w Miami, Ray.
-
-[CAT1]
-'OKUP'
-
-[CAT2]
-'WYMIANA'
-
-[CAT1_A]
-Mam twoją słodziutką Marię. Jeżeli nie chcesz, żeby jej twarz wyglądała jak po randce z rzeźnikiem,
-
-[CAT2_F]
-Złamałam paznokieć i cała jestem potargana. Nie do wiary! Ta fryzura kosztowała mnie pięćdziesiąt dolców!
-
-[CAT2_G]
-Strasznie się bałam, ale w końcu powiedziałam sobie: jesteś już przecież dużą dziewczyną.
-
-[CAT2_H]
-Och, będziemy się wspaniale bawić, bo moja siostra powiedziała, że chciałaby wpaść do nas ze swoimi dziećmi,
-
-[CAT2_I]
-bo jej mąż znowu się gdzieś szwenda i...
-
-[CAT1_E]
-XXXX
-
-[CAT1_F]
-Dotrzyj do Cataliny sprzed upływem wyznaczonego czasu!
-
-[CAT_MON]
-~g~Nie masz jeszcze tyle pieniędzy. Potrzebujesz $500.000
-
-[BITCH_D]
-~g~Maria nie żyje!
-
-[WEATHER]
-POGODA WYMUSZONA
-
-[WEATHE2]
-ZWYKŁA POGODA
-
-[8001]
-Marnie kończysz!!
-
-[1000]
-JESTEŚ MARTWY
-
-[1001]
-JESTEŚ MARTWY
-
-[1002]
-JESTEŚ MARTWY
-
-[1003]
-JESTEŚ MARTWY
-
-[1004]
-JESTEŚ MARTWY
-
-[1005]
-WPADKA
-
-[1006]
-WPADKA
-
-[1007]
-WPADKA
-
-[1008]
-WPADKA
-
-[1009]
-WPADKA
-
-[GA_4]
-Bomby samochodowe kosztują 1000 dolarów za sztukę.
-
-[GA_5]
-W twoim samochodzie bomba już została zainstalowana.
-
-[GA_6] { re3 change }
-Zaparkuj wóz, włącz mechanizm klawiszem ~h~~k~~VEHICLE_FIREWEAPON~~w~ i W NOGI!
-
-[GA_7] { re3 change }
-Uaktywnij bombę za pomocą klawisza ~h~~k~~VEHICLE_FIREWEAPON~~w~. Bomba wybuchnie w momencie włączenia silnika.
-
-[GA_8]
-Użyj detonatora, aby aktywować bombę.
-
-[GA_9]
-Zgromadziłeś ~1~ z 10 samochodów specjalnych.
-
-[GA_10]
-Ładne cacko. Oto twoje ~1~$.
-
-[GA_11]
-Mamy już taki wózek. Dla nas jest on bez wartości.
-
-[GA_12]
-Bomba uzbrojona
-
-[GA_13]
-Robota zawodowca. Skombinuj dla mnie wszystkie wózki z listy, a czeka cię premia.
-
-[GA_14]
-Wszystkie samochody? DOSKONALE! Oto niespodzianka dla ciebie!
-
-[GA_15]
-Mam nadzieję, że podoba ci się nowy kolor.
-
-[GA_16]
-Lakierowanie zakończone.
-
-[GA_19]
-Nie interesuje nas ten model.
-
-[GA_20]
-Mamy tego więcej, niż możemy zepchnąć. Sorry, facet, ale nie wchodzę w to.
-
-[CR_1]
-Dźwig nie jest w stanie podnieść tego pojazdu.
-
-[PU_MONY]
-Nie masz dość forsy.
-
-[CO_ALL]
-Masz już wszystkie. Oto mała niespodzianka...
-
-[PAUSED]
-GRA ZATRZYMANA
-
-[HEALTH1]
-Spadaj stąd! Jesteś zdrów jak ryba.
-
-[HEALTH2]
-Koszty opieki medycznej.
-
-[HEALTH3]
-Trochę cię połatam.
-
-[HEALTH4]
-To kosztuje 250 dolarów.
-
-[FEB_STA]
-Statystyki
-
-[FEB_BRI]
-Zadania
-
-[FEB_CON]
-Sterowanie
-
-[FEB_AUD]
-Audio
-
-[FEB_DIS]
-Ekran
-
-[FEB_LAN]
-Język
-
-[FEP_STA]
-STATYSTYKI
-
-[FEP_BRI]
-CELE
-
-[FEP_CON]
-STEROWANIE
-
-[FEP_AUD]
-DŹWIĘK
-
-[FEP_DIS]
-EKRAN
-
-[FEP_LAN]
-JĘZYK
-
-[FEF_ST1]
-Kto tu jest złym facetem?
-
-[FEF_ST2]
-Ile paniki dzisiaj wzbudziłeś?
-
-[FEF_BR1]
-Straciłeś wątek?
-
-[FEF_CO1]
-Potrzebujesz lepszej kontroli, perfekcjonisto?
-
-[FEF_CO2]
-Określ taką konfigurację klawiszy sterujących, która najlepiej odpowiada preferowanemu stylowi gry.
-
-[FEF_SA1]
-Trzymaj wszystko na kupie!
-
-[FEF_SA2]
-Zapisuj i wczytuj swoje gry
-
-[FEF_AU1]
-Więcej czadu!
-
-[FEF_AU2]
-Wybierz stację radiową oraz efekty dźwiękowe
-
-[FEF_DI1]
-Zmień grę!
-
-[FEF_DI2]
-Dostosuj grę do odbiornika TV
-
-[FEF_LA1]
-O czym gadasz?
-
-[FEF_LA2]
-Wybierz preferowany język
-
-[FEB_PMB]
-Cele poprzednich misji:
-
-[FEC_NA]
-N.D.
-
-[FEC_CWL]
-Przełącz rodzaj broni w lewo
-
-[FEC_CWR]
-Przełącz rodzaj broni w prawo
-
-[FEC_LOF]
-Spójrz do przodu
-
-[FEC_TAR]
-Cel
-
-[FEC_MOV]
-Ruch
-
-[FEC_CAM]
-Tryby kamery
-
-[FEC_PAU]
-Pauza
-
-[FEC_ENV]
-Wsiadanie do pojazdu
-
-[FEC_JUM]
-Skok
-
-[FEC_ATT]
-Atak lub strzał z broni
-
-[FEC_RUN]
-Bieg
-
-[FEC_FPC]
-Kamera - widok z oczu postaci
-
-[FEC_LL]
-Spójrz w lewo
-
-[FEC_LB1]
-Spójrz
-
-[FEC_LB2]
-do tyłu
-
-[FEC_LB]
-Spójrz do tyłu
-
-[FEC_LR]
-Spójrz w prawo
-
-[FEC_HOR]
-Klakson
-
-[FEC_VES]
-Sterowanie w pojeździe
-
-[FEC_RSC]
-Przełącz stacje radiowe
-
-[FEC_BRA]
-Hamulec lub wsteczny
-
-[FEC_HAB]
-Hamulec ręczny
-
-[FEC_CAW]
-Broń w samochodzie
-
-[FEC_ACC]
-Przyspieszenie
-
-[FEC_SMT]
-Włączenie misji specjalnych
-
-[FEA_OUT]
-Wyjście:
-
-[FEA_ST]
-stereo
-
-[FEA_MNO]
-mono
-
-[FEA_NON]
-Brak
-
-[FEA_FM0]
-HEAD RADIO
-
-[FEA_FM1]
-DOUBLE CLEFF FM
-
-[FEA_FM2]
-JAH RADIO
-
-[FEA_FM3]
-RISE FM
-
-[FEA_FM4]
-LIPS 106
-
-[FEA_FM5]
-GAME FM
-
-[FEA_FM6]
-MSX FM
-
-[FEA_FM7]
-FLASHBACK 95.6
-
-[FEA_FM8]
-GADUŁA 109
-
-[FED_DBG]
-Menu debugowania
-
-[FED_RID]
-Ponowne wczytanie IDE
-
-[FED_RIP]
-Ponowne wczytanie IPL
-
-[FED_PAH]
-Parse Heap
-
-[FED_RCD]
-CCullZones::RecalculateCullZoneData
-
-[FED_DFL]
-CTheScripts::DbgFlag
-
-[FED_DLS]
-Big White Debug Light Switched
-
-[FED_SPR]
-Show Ped Road Groups
-
-[FED_SCR]
-Show Car Road Grups
-
-[FED_SCZ]
-Show Cull Zones
-
-[FED_DSR]
-Żądania przetworzenia w trybie debugowania
-
-[FED_SCP]
-gbShowCollisionPolys
-
-[FEM_MCM]
-Menu karty pamięci
-
-[FEM_RMC]
-Register MemCard One
-
-[FEM_TFM]
-Próbne formatowanie karty pamięci 1
-
-[FEM_TUM]
-Próbne odformatowanie karty pamięci 1
-
-[FEM_CRD]
-Utwórz katalog główny
-
-[FEM_CLI]
-Twórz i wczytuj ikony
-
-[FEM_FFF]
-Fill First File with Guff
-
-[FEM_SOG]
-Zapisz tylko grę
-
-[FEM_CES]
-Check Every 0kB4 Save
-
-[FEM_STG]
-Zapisz grę
-
-[FEM_STS]
-Zapisz grę pod nazwą GTA3
-
-[FEM_CPD]
-Utwórz chroniony katalog magazynowy
-
-[FEM_MC2]
-Menu karty pamięci 2
-
-[FEM_TS]
-Próbne zapisywanie:
-
-[FEM_TL]
-Próbne wczytywanie:
-
-[FEM_TD]
-Próbne kasowanie:
-
-[PL_STAT]
-Statystyki gracza
-
-[PE_WAST]
-Ludzie załatwieni przez gracza
-
-[PE_WSOT]
-Ludzie załatwieni przez innych
-
-[CAR_EXP]
-Wysadzone samochody:
-
-[TM_BUST]
-Liczba wpadek
-
-[M_WASTE]
-Załatwieni mężczyźni-cywile
-
-[F_WASTE]
-Załatwione kobiety-cywile:
-
-[PIG_WST]
-Załatwieni gliniarze
-
-[GNG_WST]
-Członkowie gangu załatwieni.
-
-[MED_WST]
-Załatwieni lekarze
-
-[FIRE_WS]
-Strażak załatwiony
-
-[DED_CRI]
-Załatwieni przestępcy:
-
-[DED_DED]
-Załatwione lumpy:
-
-[DED_HOK]
-Załatwione dziwki:
-
-[HEL_DST]
-Zniszczone helikoptery
-
-[PER_COM]
-Procent ukończenia gry
-
-[KGS_EXP]
-Użyte materiały wybuchowe (kg)
-
-[ACCURA]
-Dokładność
-
-[ELBURRO]
-Najlepsze czasy wyścigu w sekundach:
-
-[CAR_CRU]
-Zmiażdżone samochody:
-
-[HED_EX]
-Rozbite głowy
-
-[TM_DED]
-Wizyty w szpitalu
-
-[DAYSPS]
-Liczba dni, które upłynęły w grze:
-
-[MMRAIN]
-mm deszczu
-
-[MXCARD]
-Maks. odległość SZALONEGO skoku (w stopach)
-
-[MXCARJ]
-Maks. wysokość SZALONEGO skoku (w stopach)
-
-[MXCARDM]
-Maks. odległość SZALONEGO skoku (w metrach)
-
-[MXCARJM]
-Maks. wysokość SZALONEGO skoku (w metrach)
-
-[MXFLIP]
-Maks. liczba salt w SZALONYM skoku
-
-[MXJUMP]
-Maks. liczba obrotów w SZALONYM skoku
-
-[BSTSTU]
-Najlepszy SZALONY skok do tej pory:
-
-[INSTUN]
-Szalony skok
-
-[PRINST]
-Bezbłędny szalony skok
-
-[DBINST]
-Podwójny szalony skok
-
-[DBPINS]
-Bezbłędny podwójny szalony skok
-
-[TRINST]
-Potrójny szalony skok
-
-[PRTRST]
-Bezbłędny potrójny szalony skok
-
-[QUINST]
-Poczwórny szalony skok
-
-[PQUINS]
-Bezbłędny poczwórny szalony skok
-
-[NOSTUC]
-Nie wykonano żadnych SZALONYCH skoków
-
-[NOUNIF]
-Wyjątkowe skoki wykonane
-
-[NOUNGM]
-Wyjątkowe skoki razem
-
-[NMISON]
-Próby wykonania misji
-
-[NMMISP]
-Wykonane misje
-
-[PASDRO]
-Zgubieni pasażerowie
-
-[MONTAX]
-Forsa zarobiona w taksówce
-
-[DAYPLC]
-Dzienne wydatki policji:
-
-[CRIMRA]
-Ranking zbrodni:
-
-[GMSTOR]
-Zachowanie gry
-
-[PREBRF]
-Poprzednie zapisy
-
-[CNTLS]
-Sterowanie
-
-[MUSMEN]
-Muzyka/dźwięki
-
-[GAMSET]
-Ustawienia gry
-
-[LANGUA]
-Język
-
-[DSPLAY]
-Ekran
-
-[DEBUGM]
-Menu funkcji debugowania
-
-[QUITOP]
-Wyjście z menu opcji
-
-[CONTRL]
-Konfiguracja sterowania
-
-[SET1EN]
-SetUp 1. Enabled
-
-[SET1]
-SetUp 1.
-
-[SET2EN]
-SetUp 2. Enabled
-
-[SET2]
-SetUp 2
-
-[SET3EN]
-SetUp 3. Enabled
-
-[SET3]
-SetUp 3
-
-[SET4EN]
-SetUp 4. Enabled
-
-[SET4]
-SetUp 4
-
-[GOBACK]
-Wróć
-
-[SOUND]
-DŹWIĘK
-
-[MUSVOL]
-Głośność muzyki
-
-[SFXVOL]
-Głośność efektów dźwiękowych
-
-[SCROPT]
-OPCJE EKRANU
-
-[CTRSCR]
-Wyśrodkowanie Ekranu
-
-[SCRFOR]
-Format ekranu
-
-[GMSVLQ]
-WCZYTAJ-ZAPISZ-WYJDŹ Z GRY
-
-[GMREST]
-Ponowne uruchomienie gry
-
-[NOGMSV]
-Zapisywanie stanu gry jest możliwe tylko w kryjówce.
-
-[DLFILE]
-Skasować pliki Grand Theft Auto III
-
-[CHFILE]
-WYBIERZ PLIK, KTÓRY MA ZOSTAĆ WCZYTANY
-
-[CHFIDL]
-WYBIERZ PLIK, KTÓRY MA ZOSTAĆ SKASOWANY
-
-[SVCONF]
-POTWIERDZENIE ZAPISU
-
-[LANGSL]
-WYBÓR JĘZYKA
-
-[ENGLIS]
-Polski
-
-[GERMAN]
-Niemiecki
-
-[ITALIA]
-Włoski
-
-[FRENCH]
-Francuski
-
-[SPAIN]
-Hiszpański
-
-[RELIDE]
-ReLoadIde
-
-[RELIPE]
-ReLoadIpl
-
-[PARSHP]
-Parse Heap
-
-[DBGFON]
-CTheScripts::DbgFlag On
-
-[DBFOFF]
-CTheScripts::DbgFlag Off
-
-[BGWHON]
-Big White Debug Light - włączony
-
-[BGWOFF]
-Big White Debug Light - wyłączony
-
-[DSTRON]
-Debug Streaming Requests On
-
-[DSTROFF]
-Debug Streaming Requests Off
-
-[PDRGON]
-ShowPedRoadGroups On
-
-[PRGOFF]
-ShowPedRoadGroups Off
-
-[CRRGON]
-ShowCarRoad Group Włączone
-
-[CRGOFF]
-ShowCarRoadGroups Wyłączone
-
-[CLZOON]
-Wyłączone pokazywanie stref zniszczeń
-
-[CLZOOF]
-Włączone pokazywanie stref zniszczeń
-
-[SHPLON]
-gbShowCollisionPolys On
-
-[SHPLOF]
-gbShowCollisionPolys Off
-
-[CULREC]
-CCullZones::RecalculateCullZoneData()
-
-[FORMM1]
-FormatMemCard 1 (element testowy)
-
-[UNFRM1]
-UnFormatMemCard 1 (element próbny)
-
-[GORLEV]
-Poziom 'Krwawy'
-
-[SICASS]
-Sick Fuck
-
-[SICSIC]
-Sick Fucker
-
-[SCASSL]
-Sick Fuck wybrany
-
-[SCSCSL]
-Sick Fucker wybrany
-
-[PRVMEN]
-Cele poprzednich misji
-
-[FORMEN]
-Menu formatu
-
-[MEMTST]
-Ekran TestKartPamięci
-
-[REGCAR]
-Rejestracja KartaPamięci Jeden
-
-[TEFONE]
-Próbne formatowanie karty pamięci 1
-
-[TEUFON]
-Próbne odformatowanie karty pamięci 1
-
-[CRROOT]
-Utwórz Katalog Główny
-
-[CRLDIC]
-Tworzenie i wczytywanie ikon
-
-[FLFSGF]
-Fill First File With Guff
-
-[PUSAVE]
-Zapisz tylko grę
-
-[CHEVOK]
-CheckEveryOkB4Save
-
-[SVGMON]
-Zapisz grę
-
-[CNTSAV]
-Nie można zapisać stanu gry. Jesteś w trakcie misji.
-
-[CNCSAV]
-Nie można zapisać stanu gry. Jesteś w samochodzie.
-
-[CRMGSV]
-Utwórz chroniony katalog magazynowy
-
-[MGSVCN]
-Katalog magazynowy utworzony
-
-[MGSVNC]
-Katalog magazynowy nieutworzony
-
-[YES]
-Tak
-
-[NO]
-Nie
-
-[X]
-x
-
-[LAST]
-Ostatnia wiadomość
-
-[FEDS_XB]
-Wybierz
-
-[FEDS_ST]
-klawisz START - WZNÓW
-
-[FEST_OO]
-z
-
-[FEC_TUC]
-Sterowanie wieżyczką
-
-[FEC_SM3]
-Włączenie misji specjalnych (klawisz R3)
-
-[FEC_RS3]
-Przełącz stacje radiowe (klawisz L3)
-
-[FEC_HO3]
-Klakson (klawisz lewy SHIFT)
-
-[DIAB1]
-'WYŚCIG'
-
-[DIAB2]
-'PRZEŁAMAĆ LODY'
-
-[DIAB3]
-'PRÓBA OGNIA'
-
-[DIAB4]
-'WIELKI I ŻYLASTY'
-
-[DIAB1_A]
-El Burro ma dla ciebie propozycję. Jeżeli jesteś zainteresowany, odszukaj budkę telefoniczną w Hepburn Heights.
-
-[DIAB1_C]
-Niezły z ciebie kierowca! Jedź do wskazanej budki telefonicznej, a może El Burro da ci jakieś zajęcie.
-
-[DIAB1_1]
-~g~3... 2... 1... NAPRZÓD! NAPRZÓD! NAPRZÓD!
-
-[DIAB1_4]
-~g~Załatw sobie szybki wóz i jedź na miejsce startu.
-
-[DIAB1_3]
-~r~Nie wygrałbyś nawet z własną babcią, LESZCZU!
-
-[DIAB1_2]
-~g~Gratulacje, wygrywasz, uzyskując niesamowity czas: ~1~sekund.
-
-[FIRST]
-~g~pierwszy
-
-[SECOND]
-~g~drugi
-
-[THIRD]
-~g~trzeci
-
-[FOURTH]
-~g~4
-
-[DIAB2_1]
-~g~Zabierz teczkę z Harwood.
-
-[DIAB2_2]
-~g~Odszukaj półciężarówkę lodziarza.
-
-[DIAB2_3]
-~g~Zaparkuj samochód lodziarza na Atlantic Quays.
-
-[DIAB2_4]
-~g~Naciśnij klawisz ~w~~k~~VEHICLE_HORN~~g~, aby włączyć sygnał reklamujący lody.
-
-[DIAB2_6]
-~g~Naciśnij klawisz ~w~~k~~VEHICLE_HORN~~g~, aby włączyć sygnał reklamujący lody.
-
-[DIAB2_7]
-~g~Naciśnij klawisz ~w~~k~~VEHICLE_HORN~~g~, aby włączyć sygnał reklamujący lody.
-
-[DIAB2_5]
-~g~Wysiądź z samochodu, a następnie zdetonuj go za pomocą nadajnika.
-
-[YD1]
-'SZUKAJ PUNKTÓW!'
-
-[YD2]
-'RUCHOMY CEL'
-
-[YD3]
-'KOLEKCJONER WOZÓW'
-
-[YD4]
-'KRÓLESTWO NIEBIESKIE'
-
-[YD_P]
-King Courtney prosi cię na słówko. Znajdź budkę telefoniczną w Aspatrii!!
-
-[YD1_A]
-~w~Z tej strony King Courtney.
-
-[YD1_A1]
-~w~Moja paczka, Yardies, potrzebuje kierowcy, a ty masz reputację bystrego faceta.
-
-[YD1_B]
-~w~Jedź na wysypisko naprzeciwko stadionu i poczekaj na innych zawodników.
-
-[YD1_C]
-~w~Moi ludzie pilnują punktów kontrolnych w całym Staunton.
-
-[YD1_D]
-~w~Kierowca, który pierwszy dotrze do takiego miejsca, otrzymuje jeden punkt. Potem ścigamy się do następnego przystanku.
-
-[YD1_D1]
-~w~Jeżeli zaliczysz więcej punktów niż inni kierowcy, być może będę miał dla ciebie zadanie.
-
-[YD1_E]
-~g~Gotowi do wyścigu!
-
-[YD1_F]
-~g~Minąłeś punkt startu - podoba mi się twój styl!!!
-
-[YD1_G]
-~r~To jest WYŚCIG SAMOCHODOWY. Masz jechać SAMOCHODEM, IDIOTO!
-
-[YD1GO]
-~g~START!
-
-[YD1_1]
-~r~1
-
-[YD1_2]
-~r~2
-
-[YD1_3]
-~r~3
-
-[YD1_BON]
-$1000!!
-
-[Y1_1ST]
-~g~Kończysz na pierwszym miejscu i pomyślnie zaliczasz ~1~ punktów kontrolnych!
-
-[Y1_2ND]
-~y~Jesteś drugi, pomyślnie zaliczyłeś ~1~ punktów kontrolnych. ~r~Było blisko, ale trochę ci jeszcze brakuje.
-
-[Y1_3RD]
-~r~Jesteś trzeci, pomyślnie zaliczyłeś ~1~ punktów kontrolnych. ~r~A mówiłeś, że jesteś niezły!
-
-[Y1_LAST]
-~r~Jesteś ostatni! ~r~Tylko marnujesz mój czas, IDIOTO!
-
-[Y1_J1ST]
-~y~Pierwsze miejsce ex aequo, pomyślnie zaliczyłeś ~1~ punktów kontrolnych. ~y~Nieźle, ale musisz być najlepszy z najlepszych, aby móc jeździć dla Królowej Lizzy!
-
-[Y1_J2ND]
-~r~Drugie miejsce ex aequo, pomyślnie zaliczyłeś ~1~ punktów kontrolnych. Jechałeś jak wściekły goryl!
-
-[Y1JLAST]
-~r~Ostatnie miejsce ex aequo! Wymądrzałeś się jak stary kierowca, ale kierowałeś jak stary przemądrzalec!
-
-[Y1_TEST]
-SAMOCHÓD W WODZIE!!
-
-[YD2_A]
-~w~Muszę sprawdzić, czy dajesz sobie radę z mokrą robotą.
-
-[YD2_A1]
-~w~Zobaczymy, czy można ci zaufać.
-
-[YD2_B]
-~w~Dwóch moich chłopców zaraz po ciebie przyjedzie, żeby zabrać cię na przejażdżkę
-
-[YD2_B1]
-~w~i sprawdzić, czy naprawdę umiesz tyle, ile twierdzisz.
-
-[YD2_C]
-~w~Jedziemy na mały wypad na Wzgórza Hepburn, żeby sprzątnąc paru śmierdziuchów z gangu Diablo, którzy wkurzali Królową Lizzy.
-
-[YD2_CC]
-~w~Będziesz potrzebował gnata, trzymaj.
-
-[YD2_D]
-~w~Ty kierujesz i strzelasz. My zadbamy, żeby nie zabrakło ci odwagi.
-
-[YD2_E]
-~w~Jazda!
-
-[YD2_F]
-~w~Oszukał nas! Dorwać jego zdradliwą dupę!
-
-[YD2_G1]
-~w~Wzgórza Hepburn. Zabijmy paru śmierdzących Diablo...
-
-[YD2_G2]
-~w~Tylko pamiętaj, ~r~ masz nie wysiadać z samochodu!!!
-
-[YD2_H]
-~w~W porządku, wracamy na terytorium Yardies! JAZDA, SZYBCIEJ!!
-
-[YD2_L]
-~w~Dobrze się spisałeś, żniwiarzu!
-
-[YD2_M]
-~r~Rozwalił mój samochód! Załatwić go!
-
-[YD2_N]
-~w~Posadź tyłek z powrotem w samochodzie!
-
-[YD3_A]
-Masz porwać dla mnie kilka samochodów gangów tak,
-
-[YD3_A1]
-abyśmy mogli uderzyć we wrogów na ich własnym terytorium.
-
-[YD3_B]
-Potrzebuję mafijnego Sentinela,
-
-[YD3_B1]
-Stingera Yakuzy oraz
-
-[YD3_B2]
-Ogiera gangu Diablo. Wtedy będzie można uderzyć na każdego w Liberty.
-
-[YD3_C]
-Zostaw je przy garażu w Newport, ale pamiętaj,
-
-[YD3_C1]
-potrzebujemy tylko fury w dobrym stanie!!!
-
-[YD3_D]
-Wolne miejsce na tekst
-
-[YD3_E]
-~r~Już zdobyłeś samochód gangu Diablo!
-
-[YD3_F]
-~r~Już zdobyłeś samochód mafii!
-
-[YD3_G]
-~r~Już zdobyłeś samochód Yakuzy!
-
-[YD3_H]
-~r~Zdobyłeś samochód gangu Diablo!
-
-[YD3_I]
-~r~Zdobyłeś samochód mafii!
-
-[YD3_J]
-~r~Zdobyłeś samochód Yakuzy!
-
-[YD3_K]
-~r~Ten samochód to ruina! Musisz go naprawić!
-
-[YD3_L]
-~g~Zabierz samochód do garażu!
-
-[YD3_M]
-~r~Straciłeś wóz! Musisz zdobyć jeszcze jeden!
-
-[YD4_A]
-Posłuchaj!
-
-[YD4_A1]
-Jedź do Bedford Point.
-
-[YD4_A2]
-W starym samochodzie jest coś, czego potrzebuję, pronto!
-
-[YD4_B]
-LIST: Słyszałam, że ostatnio byłeś pilnym uczniem. Cóż, ja byłam pilną uczennicą.
-
-[YD4_C]
-Czas, abyś poznał prawdziwą siłę HEROINY! Besos y fuderes, Catalina, xxx.
-
-[YD4_D]
-PS. ZDYCHAJ KUNDLU!
-
-[YD4_1]
-~g~Naćpani szaleńcy!
-
-[YD4_2]
-~g~Zniszcz ciężarówki wariatów!
-
-[HM_1]
-'AGRESYWNA JAZDA'
-
-[HM_2]
-'ZABAWKOWY ZABÓJCA'
-
-[HM_3]
-'ZDĄŻYĆ PRZED WYBUCHEM'v
-
-[HM_5]
-'ROZRÓBA'
-
-[HOOD1_A]
-Znajdź budkę telefoniczną w Wichita Gardens, to pogadamy o interesach.
-
-[HM1_A]
-Yo! Z tej strony D-Ice z gangu Red Jacks!
-
-[HM1_C]
-Te szczeniaki wyłażą na ulice i myślą tylko o tym, kogo by tu zastrzelić i co zaćpać.
-
-[HM1_3]
-~g~'Dziewiątki' mają swoje terytorium w Wichita Gardens.
-
-[HM2_3]
-Jeżeli uderzysz zdalnie sterowanym samochodzikiem w koła pojazdu, ładunek wybuchnie!
-
-[HM2_4]
-Jeżeli samochodzik wyjedzie poza zasięg nadajnika, ładunek wybuchnie!
-
-[HM2_5]
-~r~Samochodzik poza zasięgiem!
-
-[HM3_1]
-~g~Zabierz samochód do warsztatu, ale uważaj! Jeżeli samochód zostanie mocno uszkodzony, ładunek może wybuchnąć!
-
-[HM3_2]
-~g~Zwróć samochód właścicielowi. Jedź ostrożnie, wóz musi być w doskonałym stanie!
-
-[HM3_3]
-~g~Napraw samochód!
-
-[HM4_D]
-~g~Zdobądź samochód!
-
-[HM4_E]
-TEKST NIEPOTRZEBNY
-
-[HM4_1]
-~g~Jedź do miejsca, w któym rozsypał się ładunek. Musisz zebrać 30 sztabek.
-
-[HM4_2]
-~g~Pamiętaj, kiedy samochód zrobi się ciężki, poturlaj się do garażu i wysyp ładunek.
-
-[HM5_3]
-~r~Miałeś używać wyłącznie kija bejsbolowego!
-
-[HM5_4]
-~r~Twój kontakt nie żyje!
-
-[MEA1]
-'CWANIAK'
-
-[MEA2]
-'ZŁODZIEJE'
-
-[MEA3]
-'ŻONA'
-
-[MEA4]
-'KOCHANEK'
-
-[MEAT1_A]
-Znajomy powiedział mi, że potrafisz rozwiązywać problemy. Jeżeli chcesz zająć się moimi kłopotami, znajdź budkę telefoniczną w Trenton.
-
-[MEA1_B3]
-~g~Spotkaj się z kierownikiem banku.
-
-[MEA1_B6]
-~g~Zabierz samochód do zgniatarki, aby pozbyć się dowodów. Wysiądź z samochodu, a dźwig już się wszystkim zajmie.
-
-[MEA1_1]
-~r~Kierownik banku nie żyje!
-
-[MEA1_2]
-~r~Miałeś zniszczyć ten pojazd!
-
-[MEA1_3]
-~g~Wysiądź z samochodu!
-
-[MEA1_4]
-~r~Zgubiłeś kierownika banku!
-
-[MEA2_B3]
-~g~Jedź po złodziei.
-
-[MEA2_B4]
-~g~Zabierz ich do fabryki Delikatesów Pod Psem.
-
-[MEA2_B6]
-~g~Przemaluj samochód, aby zatrzeć ślady.
-
-[MEA2_1]
-~r~Miałeś zniszczyć ten pojazd!
-
-[MEA2_2]
-~r~Złodziej nie żyje!
-
-[MEA2_4]
-~r~Zgubiłeś jednego ze złodziei!
-
-[MEA3_B3]
-~g~Jedź po panią Chonks.
-
-[MEA3_B6]
-~g~Zabierz samochód i wrzuć go do wody, aby pozbyć się dowodów.
-
-[MEA3_1]
-~r~Żona nie żyje!
-
-[MEA3_2]
-~r~Miałeś wrzucić samochód do wody!
-
-[MEA3_3]
-~r~Zgubiłeś żonę Marty'ego!
-
-[MEA4_B3]
-~g~Zabierz kochanka żony.
-
-[MEA4_B6]
-Na to już za późno, Marty. Miałeś szansę, ale teraz przejmuję twoją budę...
-
-[MEA4_1]
-~r~Carlos nie żyje!
-
-[MEA4_3]
-~r~Zgubiłeś Carlosa lichwiarza!
-
-[LOOK_A]
-Naciśnij i przytrzymaj klawisz ~h~~k~~VEHICLE_LOOKLEFT~ ~w~lub klawisz ~h~~k~~VEHICLE_LOOKRIGHT~ ~w~, aby spojrzeć ~h~w lewo~w~ lub ~h~w prawo~w~ przez szyby pojadu. Naciśnij oba klawisze naraz, aby spojrzeć ~h~do tyłu~w~.
-
-[LOVE6_1]
-~g~Teraz odciągnij gliniarzy od magazynu!
-
-[LOVE6_2]
-~r~Nie udało ci się odciągnąć glin na wystarczającą odległość!
-
-[RM4_3]
-~r~Kumpel Raya zwiał!
-
-[RM6_C]
-Zdaje się, że CIA ma jakiś swój interes w utrzymaniu handlu PROCHAMI
-
-[RM6_C1]
-i nie spodobało im się, że zadarliśmy z Kartelem.
-
-[C_PASS]
-ZAGROŻENIE ZLIKWIDOWANE
-
-[CTUTOR]
-Naciśnij klawisz ~h~~k~~TOGGLE_SUBMISSIONS~, aby włączyć lub wyłączyć misje patrolowe.
-
-[CTUTOR2]
-Naciśnij klawisz ~h~~k~~TOGGLE_SUBMISSIONS~, aby włączyć lub wyłączyć misje patrolowe.
-
-[COPCART]
-~g~Masz ~1~ sekund na powrót do radiowozu albo misja zakończy się.
-
-[C_FAIL]
-Misja patrolowa zakończona!
-
-[C_CANC]
-~r~Misja patrolowa anulowana!
-
-[C_ESCP]
-~r~Podejrzany uciekł!
-
-[C_TIME]
-~r~Twój czas w roli stróża prawa minął!
-
-[C_VIGIL]
-PREMIA PATROLOWA!!
-
-[A_FAIL2]
-~r~Twoje ślamazarność kosztowała pacjenta życie!
-
-[A_FAIL3]
-~r~Pacjent nie żyje!
-
-[A_PASS]
-Uratowany!
-
-[F_FAIL2]
-~r~Spóźniłeś się!
-
-[A_COMP2]
-Ty chyba nigdy się nie męczysz!
-
-[RM2_M]
-Jak będziesz potrzebował spluwy, wpadaj do mnie jak w dym i bierz z szafek, co ci się podoba.
-
-[HEAL_A]
-Twój ~h~poziom życia~w~ jest wyświetlony na pomarańczowo w prawym górnym narożniku ekranu.
-
-[YD1_CNT]
-~1~ z 15!
-
-[FM1_9]
-~g~Przed nami miejsce imprezy - wysadź Marię przed budynkiem.
-
-[FM1_Y]
-~w~Wiesz, dawno się tak dobrze nie bawiłam, a ty traktowałeś mnie naprawdę dobrze. Z szacunkiem i w ogóle..
-
-[FM1_AA]
-~w~Chyba już pójdę. W takim razie - do zobaczenia!
-
-[NOCONTE]
-Aby kontynuować, proszę ponownie umieścić wtyczki kontrolera analogowego (DUALSHOCK@) lub kontrolera analogowego (DUALSHOCK@2) w porcie kontrolerów gry nr 1.
-
-[WRCONT]
-Kontroler w porcie nr 1 nie jest rozpoznany. Gra Grand Theft Auto III wymaga kontrolera analogowego (DUALSHOCK@) lub kontrolera analogowego (DUALSHOCK@2).
-
-[WRCONTE]
-Kontroler w porcie nr 2 nie jest rozpoznany. Gra Grand Theft Auto III wymaga kontrolera analogowego (DUALSHOCK@) lub kontrolera analogowego (DUALSHOCK@2).
-
-[WRONGCD]
-Niewłaściwa płyta. Proszę włożyć właściwą płytę.
-
-[NOCD]
-Nie znaleziono GTAIII CD w czytniku.
-
-[OPENCD]
-Taca napędu jest wysunięta. Wsuń tacę napędu CD-ROM.
-
-[CDERROR]
-Błąd w odczycie płyty Grand Theft Auto III.
-
-[RESTART]
-Trwa rozpoczynanie nowej gry
-
-[GA_3]
-Koniec z promocjami. 1000 dolców za malowanie!
-
-[GA_1]
-Coś ty! Nawet nie dotknę takiego trefnego towaru!
-
-[GA_1A]
-Wróć, kiedy będziesz miał chwilę wolnego czasu...
-
-[S_PROM2]
-Garaż znajdujący się za sąsiednimi drzwiami służy do przechowywania pojazdów podczas zapisywania stanu gry.
-
-[STOCK]
-brak towaru
-
-[FM1_O]
-~w~Myślę, że znajdziemy go nad brzegiem morza, w okolicach Chinatown.
-
-[EBAL_B]
-To właśnie tu. Zjedźmy z ulicy i poszukajmy jakichś ciuchów, żeby zmienić te więzienne łachy!
-
-[EBAL_G]
-To jest właśnie klub 'U Luigiego'. Obejdziemy tę budę i skorzystamy z tylnych drzwi.
-
-[AM4_3]
-A więc to ty jesteś nowym chłopcem na posyłki Asuki?
-
-[AM4_4]
-Masz forsę? Mam nadzieję, że wszystko jest jak trzeba?
-
-[AM4_5]
-Wiem, co sobie myślisz, następny sprzedajny gliniarz.
-
-[AM4_6]
-Cóż, każdy orze jak może.
-
-[AM4_7]
-Straciłem ostatnio paru partnerów i ci frajerzy z wydziału wewnetrznego zaczęli coś przewąchiwać.
-
-[AM4_8]
-Żeby tylko nie wyniuchali moich śladów.
-
-[AM4_9]
-To miasto to jeden wielki otwarty ściek.
-
-[AM4_10]
-Przyda mi się pomoc kogoś niezrzeszonego.
-
-[AM4_11]
-Jeżeli masz jakiś interes, wiesz gdzie mnie znaleźć.
-
-[CAM_A]
-Wciskaj klawisz ~h~~k~~CAMERA_CHANGE_VIEW_ALL_SITUATIONS~~w~, aby zmieniać tryby pracy ~h~kamery ~w~, zarówno w samochodzie jak i poza nim.
-
-[CAM_B]
-Wciskaj klawisz ~h~strzałki w gorę~w~ oraz ~h~strzałki w dół~w~, aby zmieniać tryby pracy ~h~kamery ~w~, zarówno w pojeździe jak i poza nim.
-
-[KM2_1]
-~g~Napraw samochód. Wóz musi być w idealnym stanie.
-
-[LM3_6]
-Joey...
-
-[LM3_6A]
-Znowu będę mogła się pobawić twoim drągiem?
-
-[LM3_9A]
-może będę miał dla ciebie jakieś zajęcie.
-
-[LM3_9B]
-W porządku?
-
-[AWAY2]
-~r~Uciekli.
-
-[AWAY]
-~r~Zwiał stąd, gdzie pieprz rośnie!
-
-[JM6_1]
-Jedź do banku na głównej ulicy.
-
-[GA_6B] { re3 change }
-Zaparkuj wóz, włącz mechanizm klawiszem ~h~~k~~VEHICLE_FIREWEAPON~~w~ i W NOGI!
-
-[GA_7B] { re3 change }
-Uaktywnij bombę za pomocą klawisza ~h~~k~~VEHICLE_FIREWEAPON~~w~. Bomba wybuchnie w momencie włączenia silnika.
-
-[BAT1]
-~g~Podnieś kij bejsbolowy!
-
-[EBAL_O]
-Jeśli nic nie schrzanisz, może znajdzie się dla ciebie jakaś praca. A teraz zjeżdżaj!
-
-[HELP9_B]
-Naciśnij klawisz~h~ ~k~~PED_FIREWEAPON~~w~, aby oddać ~h~strzał~w~ z karabinu snajperskiego.
-
-[HELP9_C]
-Naciśnij klawisz~h~ ~k~~PED_FIREWEAPON~~w~, aby oddać ~h~strzał~w~ z karabinu snajperskiego.
-
-[JM6_8]
-~r~Straciłeś wszystkich złodziei!
-
-[COLT_IN]
-Ammu-nacja zaczyna sprzedaż pistoletów!
-
-[TAXI2]
-~r~Koniec czasu!
-
-[TAXI3]
-~r~Przerażony pasażer ucieka!
-
-[TAXI7]
-~r~Twoja taksówka to ruina, połataj ją trochę.
-
-[TAXI4]
-Kurs wykonany!
-
-[TAXI5]
-PREMIA ZA SZYBKOŚĆ!!!
-
-[TAXI6]
-Koniec misji w taksówce
-
-[FRANGO]
-~g~Salvatore chce, abyś najpierw pomógł Toniemu załatwić porachunki z Triadami!
-
-[PAGEB12]
-Łapówka policyjna dostarczona do kryjówki
-
-[PAGEB13]
-Życie dostarczone do kryjówki
-
-[PAGEB14]
-Adrenalina dostarczona do kryjówki
-
-[KM1_4]
-~g~Do tej roboty przydałby się radiowóz!
-
-[CAT1_B]
-przynieś 500.000 $ do Willi w Cedar Grove.
-
-[JM2_C]
-Gość ma budę z makaronem w Chinatown.
-
-[RM6_1]
-Tu masz klucz do dziupli.
-
-[RM6_2]
-Znajdziesz tam trochę forsy i 'zapasów', które zbierałem na czarną godzinę.
-
-[RM6_3]
-Trzymaj się.
-
-[FE_INIP]
-Inicjalizacja i wczytywanie menu pauzy... Proszę czekać.
-
-[FESZ_CA]
-Anuluj
-
-[FESZ_QU]
-Wyjście
-
-[FESZ_L1]
-Gra została pomyślnie zapisana.
-
-[FESZ_L2]
-Gra została zapisana w pliku o nazwie:
-
-[FESZ_OK]
-OK
-
-[FES_LGA]
-Wczytaj grę
-
-[FES_NGA]
-Nowa gra
-
-[FES_CAN]
-Anuluj
-
-[FESZ_QL]
-Wszelkie niezapisane osiągnięcia i zdobycze w trwającej grze zostaną utracone. Wczytać grę?
-
-[FESZ_QD]
-Czy skasować ten zapis gry?
-
-[FESZ_QO]
-Czy nadpisać tę grę na starszym pliku?
-
-[FESZ_QR]
-Czy jesteś pewien, że chcesz rozpocząć nową grę? Wszelkie osiągnięcia i postępy poczynione od momentu ostatniego zapisu gry zostaną utracone. Kontynuować?
-
-[FESZ_QS]
-KONTYNUOWAĆ ZAPIS?
-
-[T4X4_1]
-'PLAC ZABAW PATRIOTÓW'
-
-[T4X4_2]
-'PRZEJAŻDŻKA W PARKU'
-
-[T4X4_3]
-'W POTRZASKU!'
-
-[MM_1]
-'KOSZMAR WIELU PIĘTER'
-
-[T4X4_1A]
-~g~Masz ~y~5 minut~g~ na zaliczenie ~y~15~g~ punktów kontrolnych. ~g~Możesz zaliczać je w ~y~DOWOLNEJ KOLEJNOŚCI.
-
-[T4X4_1B]
-~1~ z 15!
-
-[T4X4_1C]
-~y~PRZEJEDŹ PRZEZ~g~ pierwszy punkt kontrolny, aby uruchomić odliczanie czasu. ~g~Zaliczenie każdego punktu jest premiowane dodatkowymi ~y~20 SEKUNDAMI~g~
-
-[T4X4_2A]
-~g~Masz ~y~2 minuty~g~ na zaliczenie ~y~12~g~ punktów kontrolnych. ~g~Możesz zaliczać je w ~y~DOWOLNEJ KOLEJNOŚCI.
-
-[T4X4_2B]
-~1~ z 12!
-
-[T4X4_2C]
-~y~PRZEJEDŹ PRZEZ~g~ pierwszy punkt kontrolny, aby uruchomić odliczanie czasu. ~g~Zaliczenie każdego punktu jest premiowane dodatkowymi ~y~10 SEKUNDAMI~g~
-
-[T4X4_3A]
-~g~Masz ~y~5 minut~g~ na zaliczenie ~y~20~g~ punktów kontrolnych. ~g~Możesz zaliczać je w ~y~DOWOLNEJ KOLEJNOŚCI.
-
-[T4X4_3B]
-~y~PRZEJEDŹ PRZEZ~g~ pierwszy punkt kontrolny, aby uruchomić odliczanie czasu. ~g~Zaliczenie każdego punktu jest premiowane dodatkowymi ~y~15 SEKUNDAMI~g~
-
-[T4X4_3C]
-~1~ z 20!
-
-[T4X4_F]
-~r~Wymiękasz! Może lepiej sprawdzisz się w wyścigach na hulajnodze?!
-
-[MM_1_A]
-~g~Masz ~y~2 minuty~g~ na zaliczenie ~y~20 punktów kontrolnych~g~ w całym obiekcie! ~g~Możesz zaliczać punkty w ~y~DOWOLNEJ KOLEJNOŚCI.
-
-[MM_1_B]
-~1~ z 20!
-
-[MM_1_C]
-~g~To oznacza 20 sekund plus ~y~5 SEKUND~g~ premii za każdy zaliczony punkt. ~g~Zegar zaczyna odliczanie ~y~NATYCHMIAST.
-
-[FM2_14]
-~r~Zbliżyłeś się za bardzo i wystraszyłeś Kudłatego!
-
-[FM2_15]
-~g~Nie zbliżaj się zbytnio, bo Kudłaty zacznie coś podejrzewać!
-
-[UPSIDE]
-~r~Przewróciłeś samochód!
-
-[FM2_16]
-STRACHOMETR:
-
-[LM3_11]
-~g~Misty nie będzie jeździć autobusem, załatw inny pojazd!
-
-[LANDSTK]
-Landstalker
-
-[IDAHO]
-Idaho
-
-[STINGER]
-Stinger
-
-[LINERUN]
-Linerunner
-
-[PEREN]
-Perennial
-
-[SENTINL]
-Sentinel
-
-[PATRIOT]
-Patriot
-
-[FIRETRK]
-Wóz strażacki
-
-[TRASHM]
-Śmieciożer
-
-[STRETCH]
-Stretch
-
-[MANANA]
-Manana
-
-[INFERNS]
-Infernus
-
-[BLISTA]
-Blista
-
-[PONY]
-Pony
-
-[MULE]
-Muł
-
-[CHEETAH]
-Cheetah
-
-[AMBULAN]
-Karetka pogotowia
-
-[FBICAR]
-Samochód FBI:
-
-[MOONBM]
-Moonbeam
-
-[ESPERAN]
-Esperanto
-
-[TAXI]
-Taksówka
-
-[KURUMA]
-KURUMA
-
-[BOBCAT]
-Bobcat
-
-[WHOOPEE]
-Pan Smakołyk
-
-[BFINJC]
-Zastrzyk BF
-
-[POLICAR]
-Policja
-
-[ENFORCR]
-Enforcer
-
-[SECURI]
-Konwojowóz
-
-[BANSHEE]
-Demon
-
-[PREDATR]
-Predator
-
-[BUS]
-Autobus
-
-[RHINO]
-Hipcio
-
-[BARRCKS]
-Koszary OL
-
-[TRAIN]
-Pociąg
-
-[HELI]
-Helikopter
-
-[DODO]
-Dodo
-
-[COACH]
-Autokar
-
-[CABBIE]
-Taksówka
-
-[STALION]
-Ogier
-
-[RUMPO]
-Rumpo
-
-[RCBANDT]
-Bandziorek
-
-[BELLYUP]
-Ciężarówka Triady
-
-[MRWONGS]
-Mr Wongs
-
-[MAFIACR]
-Sentinel mafii
-
-[YARDICR]
-Lobo gangu Yardie
-
-[YAKUZCR]
-Stinger gangu Yakuza
-
-[DIABLCR]
-Ogier gangu Diablo
-
-[COLOMCR]
-Krążownik Kartelu
-
-[HOODSCR]
-Rumpo XL gangu Hoods
-
-[AEROPL]
-Samolot
-
-[SPEEDER]
-Speeder
-
-[REEFER]
-Reefer
-
-[PANLANT]
-Panlantic
-
-[FLATBED]
-Flatbed
-
-[YANKEE]
-Yankee
-
-[BORGNIN]
-Borgnine
-
-[TOYZ]
-ZABAWKI
-
-[FEST_DF]
-Odległość przebyta pieszo (w milach)
-
-[FEST_DC]
-Odległość przebyta samochodem (w milach)
-
-[FESTDFM]
-Odległość przebyta pieszo (w metrach)
-
-[FESTDCM]
-Odległość przebyta samochodem (w metrach)
-
-[FEST_R1]
-Plac Zabaw Patriotów w sekundach
-
-[FEST_R2]
-Przejażdżka w parku w sekundach
-
-[FEST_R3]
-W Potrzasku! w sekundach
-
-[FEST_RM]
-Koszmar Wielu Pięter w sekundach
-
-[FEST_LS]
-Ludzie uratowani przez karetkę
-
-[FEST_CC]
-Przestępcy zabici podczas misji patrolowych
-
-[FEST_FE]
-Liczba ugaszonych pożarów
-
-[FEST_LF]
-Najdłuższy lot dodo
-
-[FEST_BD]
-Najlepszy czas rozbrojenia bomby
-
-[FEST_RP]
-Wykonane rozwałki:
-
-[FEST_MP]
-Wykonane misje
-
-[FEST_BB]
-Szukaj Punktów
-
-[FEST_H0]
-Najwięcej punktów kontrolnych
-
-[FEST_GC]
-Łączna liczba pojazdów gangów:
-
-[FEST_H1]
-Diabelska demolka
-
-[FEST_H2]
-Mafijna masakra
-
-[FEST_H3]
-Krwawe kasyno
-
-[FEST_H4]
-Rumpo-rozróba
-
-[USJI1]
-TEKST DŁUŻEJ NIEPOTRZEBNY
-
-[USJI2]
-TEKST DŁUŻEJ NIEPOTRZEBNY
-
-[USJI3]
-TEKST DŁUŻEJ NIEPOTRZEBNY
-
-[USJ]
-PREMIA ZA NIETYPOWY SKOK!
-
-[SPRAY]
-Wprowadź samochód do warsztatu lakierniczego, aby obniżyć swój ~h~poziom złek sławy~w~, ~h~naprawić~h~ oraz przemalować~w~ swój wóz. Koszt - ~h~$1000.
-
-[HM1_1]
-~g~Załatw 20 Purpurowych Dziewiątek w 2 minuty 30 sekund.
-
-[KM1_8A] { re3 change }
-Naciśnij klawisz ~h~ ~k~~VEHICLE_FIREWEAPON~ ~w~, aby ~h~aktywować bombę.~w~ Nie zapomnij oddalić się od miejsca eksplozji.
-
-[KM1_8D] { re3 change }
-Naciśnij klawisz ~h~ ~k~~VEHICLE_FIREWEAPON~ ~w~, aby ~h~aktywować bombę.~w~ Nie zapomnij oddalić się od miejsca eksplozji.
-
-[KM1_12]
-~g~Odwieź go do dojo, ale najpierw pozbądź się gliniarzy!
-
-[RATNG1]
-Kieszonkowiec
-
-[RATNG2]
-Mięśniak
-
-[RATNG3]
-Łotr
-
-[RATNG4]
-Hazardzista
-
-[RATNG5]
-Zbir
-
-[RATNG6]
-Kierowca
-
-[RATNG7]
-Twardziel do wynajęcia
-
-[RATNG8]
-Oszust
-
-[RATNG9]
-Współpracownik
-
-[RATNG10]
-Sprzątacz
-
-[RATNG11]
-Zabójca
-
-[RATNG12]
-Złota rączka
-
-[RATNG13]
-Egzekutor
-
-[RATNG14]
-Capo
-
-[RATNG15]
-Szef
-
-[1010]
-~r~Twój pojazd dachował
-
-[1011]
-~r~Twój pojazd dachował
-
-[1012]
-~r~Twój pojazd dachował
-
-[1013]
-~r~Twój pojazd dachował
-
-[1014]
-~r~Twój pojazd dachował
-
-[JM4_10]
-Słuchaj, młody! Najpierw zawieź mnie do pralni w chińskiej dzielnicy. Mam małą sprawę do załatwienia.
-
-[JM4_11]
-Praczki przestały płacić haracz za ochronę.
-
-[JM4_12]
-Tylko uważaj na wóz, Joey dopiero poskładał ten szmelc.
-
-[JM4_13]
-Więc bez żadnych numerów, OK?
-
-[KM4_11]
-~g~Odwieź pieniądze do kasyna!
-
-[FEF_BR2]
-Możesz przypomnieć sobie fabułę gry, czytając zebrane dotąd streszczenia celów misji.
-
-[TRAIN_1]
-Stacja Kurowski
-
-[TRAIN_2]
-Stacja Rothwell
-
-[TRAIN_3]
-Stacja Baillie
-
-[SUBWAY1]
-Portland Station
-
-[SUBWAY2]
-Rockford Station
-
-[SUBWAY3]
-Staunton South Station
-
-[SUBWAY4]
-Shoreside Terminal
-
-[MEA4_2]
-~r~Marty Chonks nie żyje!
-
-[SPRAY1]
-Wprowadź samochód do warsztatu lakierniczego, aby obniżyć swój ~h~poziom złej sławy~w~, ~h~naprawić~h~ oraz przemalować~w~ swój wóz. Koszt - ~h~$1000~w~. Tym razem zrobimy to za darmo.
-
-[JM4_A]
-Tak, wiem Toni, naprawdę nieźle ją sobie wychowałem. Aż mruczy z zadowolenia, kapujesz?
-
-[JM4_5]
-Wpadnij później to damy im coś do prania - ich własne pokrwawione gacie!
-
-[AMMU_A]
-Luigi mówił, że potrzebujesz gnata...
-
-[AMMU_B]
-Joey wspominał, że potrzebna ci artyleria...
-
-[AMMU_C]
-Idź na tył sklepu. Na podwórzu zostawiłem dla ciebie dziewiątkę.
-
-[AMMU_D]
-Mam wszystko, co potrzeba do obrony własnego gospodarstwa domowego.
-
-[AMMU_E]
-Chcesz jeszcze pozwolenie?
-
-[AMMU_F]
-Nie musisz pokazywać dowodu, wyglądasz na wiarygodnego gościa.
-
-[DETON]
-DETONACJA:
-
-[DRIVE_A] { re3 change }
-Wybierz jako broń uzi i wsiądź do pojazdu. Następnie spójrz w lewo lub w prawo - aby otworzyć ogień, naciśnij klawisz ~h~~k~~VEHICLE_FIREWEAPON~~w~.
-
-[DRIVE_B] { re3 change }
-Wybierz jako broń uzi i wsiądź do pojazdu. Następnie spójrz w lewo lub w prawo - aby otworzyć ogień, naciśnij klawisz ~h~~k~~VEHICLE_FIREWEAPON~~w~.
-
-[RECORD]
-~g~NOWY REKORD!
-
-[NRECORD]
-~r~NIE MA NOWEGO REKORDU!
-
-[RCHELP] { re3 change }
-Naciśnij klawisz ~k~~VEHICLE_FIREWEAPON~ lub uderz zdalnie sterowanym samochodzikiem w koła pojazdu, aby spowodować eksplozję.
-
-[RCHELPA] { re3 change }
-Naciśnij klawisz ~k~~VEHICLE_FIREWEAPON~ lub uderz zdalnie sterowanym samochodzikiem w koła pojazdu, aby spowodować eksplozję.
-
-[RC_1]
-Masz 2 minuty, aby wysadzić tyle samochodów gangu Diablo, ile tylko się da!
-
-[RC_2]
-Masz 2 minuty, aby wysadzić tyle samochodów mafii, ile tylko się da!
-
-[RC_3]
-Masz 2 minuty, aby wysadzić tyle samochodów Yakuzy, ile tylko się da!
-
-[RC_4]
-Masz 2 minuty, aby wysadzić tyle samochodów gangu Yardie, ile tylko się da!
-
-[RC_5]
-Masz 2 minuty, aby wysadzić tyle samochodów gangu Hoods, ile tylko się da!
-
-[RC_6]
-Masz 2 minuty, aby wysadzić tyle samochodów Kartelu, ile tylko się da!
-
-[RAMPAGE]
-ROZWAŁKA!!
-
-[RAMP_P]
-ROZWAŁKA WYKONANA!
-
-[RAMP_F]
-ROZWAŁKA NIEUDANA!
-
-[PAGE_00]
-.
-
-[PAGE_01]
-Załatw ~1~ludzi z gangu Diablo w 120 sekund!
-
-[PAGE_02]
-Zniszcz ~1~ pojazdów w ciągu 120 sekund!
-
-[PAGE_03]
-Zabij ~1~ członków mafii w ciągu 120 sekund!
-
-[PAGE_04]
-Zabij ~1~ członków Triady w ciągu 120 sekund!
-
-[PAGE_05]
-Zabij ~1~ członków Triady w ciągu 120 sekund!
-
-[PAGE_06]
-Zniszcz ~1~ pojazdów w ciągu 120 sekund!
-
-[PAGE_07]
-Rozwal ~1~ łebków z gangu Yardie w ciągu 120 sekund!
-
-[PAGE_08]
-Spal ~1~ członków Yakuzy w ciągu 120 sekund!
-
-[PAGE_09]
-Zniszcz ~1~ pojazdów w ciągu 120 sekund!
-
-[PAGE_10]
-Zniszcz ~1~ pojazdów w ciągu 120 sekund!
-
-[PAGE_11]
-Skasuj ~1~ członków gangu Yardie w ciągu 120 sekund!
-
-[PAGE_12]
-Podpal ~1~ członków Yakuzy w ciągu 120 sekund!
-
-[PAGE_13]
-Wysadź w powietrze ~1~ członków gangu Yardie w ciągu 120 sekund!
-
-[PAGE_14]
-Usmaż ~1~ Kolumbijczyków w ciągu 120 sekund.
-
-[PAGE_15]
-Rozjedź ~1~ członków gangu Hoods w ciągu 120 sekund!
-
-[PAGE_16]
-Zniszcz ~1~ pojazdów w ciągu 120 sekund!
-
-[PAGE_17]
-Rozjedź samochodem ~1~ Kolumbijczyków w ciągu 120 sekund!
-
-[PAGE_18]
-Rozjedź i zniszcz ~1~ pojazdów w ciągu 120 sekund!
-
-[PAGE_19]
-Urwij ~1~ głów Kolumbijczyków w ciągu 120 sekund!
-
-[PAGE_20]
-Obetnij głowy ~1~ członkom gangu Hoods w ciągu 120 sekund!
-
-[JM1_A]
-Hej, umieram z nudów! Kiedy w końcu mnie przelecisz?
-
-[JM1_B]
-Za chwileczkę, złotko! Muszę się zająć jedną drobną kwestią...
-
-[JM1_C]
-Mam dla ciebie robótkę, kolego.
-
-[JM1_D]
-Bracia Forelli od dawna wiszą mi kasę. Od zbyt dawna.
-
-[JM1_E]
-Trzeba dać im lekcję szacunku.
-
-[JM1_F]
-Buźka Forelli napycha właśnie swój bęben w Bistro w St. Marks,
-
-[JM1_G]
-więc ukradnij jego samochód i zabierz go do warsztatu 8-Balla w Harwood.
-
-[JM1_H]
-Znasz 8-Balla, nie?
-
-[JM1_I]
-Kiedy 8-Ball założy w samochodzie ładunek, odprowadź furę na to samo miejsce, z którego ją wziąłeś.
-
-[JM1_J]
-Potem usiądź w bezpiecznej odległości i podziwiaj fajerwerki.
-
-[JM1_K]
-Tylko się pospiesz, grubas nie będzie przecież jadł cały dzień.
-
-[CAT2_A1]
-Jazda, głupia dziwko!
-
-[CAT2_A]
-Trzeba zadać sobie pytanie: czy przyjechałeś ratować Marię czy też żeby spotkać się ze mną?
-
-[CAT2_B]
-Mam dla ciebie wiadomość:
-
-[CAT2_B2]
-romans z tobą to był wyłącznie interes, za to zastrzelę cię dla przyjemności.
-
-[CAT2_C]
-Jesteś muy peccino amigo!
-
-[CAT2_D]
-Rzuć forsę.
-
-[CAT2_E]
-Ostatnio byłeś bardzo pilnym uczniem!
-
-[CAT2_E2]
-Ale nic się nie nauczyłeś. Mnie nie wolno ufać.
-
-[CAT2_E3]
-Zabić tego idiotę.
-
-[CAT2_J]
-Poderwij ten złom w powietrze!
-
-[HM5_1]
-Yo, Ice mówił, że przyjdziesz. Teraz zasady: bierzemy tylko bejsbole - bez spluw i bez samochodów.
-
-[HM5_5]
-To bitwa o honor, czaisz?
-
-[HELP14]
-Aby podnieść broń, po prostu wejdź na nią. Nie możesz podnieść broni, jeżeli siedzisz w samochodzie.
-
-[CRUSH]
-Zaparkuj w oznaczonym miejscu i wysiądź z pojazdu. Samochód zostanie zgnieciony.
-
-[DIAB2_B]
-Gang brzydkich panów zagroził, że pozbawi mnie mojego gwiazdora, jeżeli nie odpalę im doli.
-
-[DIAB2_C]
-Zatańczyli z niewłaściwym człowiekiem, amigo.
-
-[DIAB2_D]
-Oni mają słabość do lodów.
-
-[DIAB2_E]
-Odszukaj bombę, którą zostawiłem w Harwood,
-
-[DIAB2_F]
-porwij jeden z samochodów sprzedających lody w całym mieście,
-
-[DIAB2_G]
-a potem zwab tych idiotów reklamowym sygnałem lodziarza.
-
-[DIAB2_H]
-Ukrywają się w magazynach przy Atlantic Quay.
-
-[DIAB3_A]
-Jacyś niegrzeczni członkowie Triady ukradli wczoraj w nocy mój samochód,
-
-[DIAB3_B]
-rozbili go i zostawili, aby się dopalił.
-
-[DIAB3_C]
-W bagażniku miałem kilka wyjątkowo cennych pamiątek -
-
-[DIAB3_D]
-prawdziwe rzadkie okazy, których nie da się niczym zastąpić, mój przyjacielu.
-
-[DIAB3_E]
-Na granicy Chinatown ukryłem dla ciebie naprawdę potężną broń.
-
-[DIAB3_F]
-Skorzystaj z niej i naucz wandali z Triady, co oznacza zasłużony gniew El Burro.
-
-[DIAB3_1]
-ZABIJ 25 CZŁONKÓW TRIADY
-
-[DIAB4_A]
-Jakiś marny złodziejaszek ukradł mi półciężarówkę z najnowszym wydaniem moich magazynów... Prosto z drukarni!
-
-[DIAB4_B]
-Ale ten zaćpany idiota nie zamknął tylnych drzwi
-
-[DIAB4_C]
-i teraz moja starannie opracowana literatura dla dorosłych,
-
-[DIAB4_D]
-opatrzona wysmakowanymi zdjęciami, wala się po całym Liberty!
-
-[DIAB4_E]
-Weź półciężarówkę i jedź śladem magazynów 'Donkey Daje Całemu Dallas' część 1, 2 i 3.
-
-[DIAB4_F]
-Zbieraj wszystko, co znajdziesz.
-
-[DIAB4_G]
-Kiedy dotrzesz po tropie do tego złodziejskiego ĆPUNA, załatw go!
-
-[DIAB4_H]
-A potem zawieź moje książeczki z Donkey do Magazynów XXX w Dzielnicy Czerwonych Świateł.
-
-[DIAB4_1]
-~g~Zabierz samochód na zaplecze Magazynów XXX.
-
-[HM1_E]
-Pokaż tym zaćpanym siuśkom, na czym polega prawdziwa jazda samochodem.
-
-[HM1_H]
-Usuń mi te 'Dziewiątki' z widoku!
-
-[HM2_A]
-Te 'Dziewiątki' nadal nadeptują mi na odcisk.
-
-[HM2_B]
-Szczeniaki załatwiły sobie samochody opancerzone i sprzedają PROCHY...
-
-[HM2_C]
-...naszym niewinnym czarnym braciom.
-
-[HM2_D]
-Zostawiłem dla ciebie samochód.
-
-[HM2_E]
-W środku znajdziesz parę zabawek, które pomogą ci dać siuśkom nauczkę...
-
-[HM3_A]
-Jakiś samobójca wsadził bombę do mojej gabloty.
-
-[HM3_B]
-Jeżeli stracę tę furę, mogę pożegnać się z moją reputacją na ulicach.
-
-[HM3_C]
-Weź mój wóz i zabierz go do warsztatu w St. Marks, brachu.
-
-[HM3_D]
-Niech chłopaki się nim zajmą i rozbroją bombę.
-
-[HM3_E]
-Zegar już odlicza czas, a bomba chyba jest uszkodzona.
-
-[HM3_F]
-Wpadniesz w jedną dziurę za dużo i to cacko wyleci w powietrze.
-
-[HM3_G]
-Na co jeszcze czekasz?
-
-[HM4_A]
-Yo, na lotnisku im. Francisa właśnie roztrzaskał się samolot Banku Narodowego.
-
-[HM4_B]
-Platyna wala się po całym pasie startowym.
-
-[HM4_C]
-Załatw samochód i zgarnij tyle, ile tylko się da.
-
-[HM4_F]
-Możesz wysypać platynę przy jednym z moich garaży.
-
-[HM4_G]
-Platyna jest cholernie ciężka, więc nie zdziw się, kiedy przeciążysz gablotę i fura będzie się wlokła jak ślimak.
-
-[HM4_H]
-Lepiej regularnie zrzucaj towar przy jakimś garażu.
-
-[HM5_A]
-Z gangu 'Dziewiątek' zostały już tylko niedobitki...
-
-[HM5_B]
-ale nadal chcą się pobawić.
-
-[HM5_C]
-Zgodzili się na pojedynek twarzą w twarz.
-
-[HM5_D]
-Ich banda przeciwko dwóm spośród nas, a raczej...
-
-[HM5_E]
-przeciwko tobie i jeszcze komuś
-
-[HM5_F]
-Poszedłbym z tobą, ale...
-
-[HM5_G]
-jeszcze przez trzy miesiące mam wyrok w zawieszeniu i nie mogę rozrabiać,
-
-[HM5_H]
-sam rozumiesz.
-
-[HM5_I]
-Weźmiesz ze sobą mojego młodszego brata.
-
-[HM5_J]
-On ci pokaże, gdzie jesteście umówieni.
-
-[MEA1_B]
-Nazywam się Chonks, Marty Chonks.
-
-[MEA1_C]
-Prowadzę Delikatesy Pod Psem, tuż za rogiem.
-
-[MEA1_D]
-Mam kłopoty z kasą, ale kto ich dzisiaj nie ma?
-
-[MEA1_E]
-Jestem umówiony z kierownikiem mojego banku.
-
-[MEA1_F]
-Ten cwaniaczek cały czas podnosi odsetki mojego kredytu, żeby móc odkroić swoją działkę.
-
-[MEA1_G]
-Weź mój samochód, jedź po niego i przywieź go tutaj.
-
-[MEA1_H]
-Mam małą niespodziankę dla tego krwiopijcy!!
-
-[MEA2_A]
-Wynająłem paru złodziejaszków, aby włamali się do mojego mieszkania
-
-[MEA2_C]
-Te złodziejskie szumowiny grożą, że zakapują mnie w firmie ubezpieczeniowej,
-
-[MEA2_D]
-jeżeli nie odpalę im doli.
-
-[MEA2_E]
-To się po prostu w głowie nie mieści!
-
-[MEA2_F]
-W fabryce zostawiłem samochód.
-
-[MEA2_G]
-Skorzystaj z niego i zabierz złodziei z Dzielnicy Czerwonych Świateł.
-
-[MEA2_H]
-Potem przywieź ich do fabryki. Tam wytłumaczę im mój punkt widzenia w tej sprawie.
-
-[MEA3_A]
-Mój interes zbankrutuje, jeżeli szybko nie dostanę do rąk większej gotówki.
-
-[MEA3_B]
-Moja żona ma sporą polisę ubezpieczeniową, a i tak przez całe życie tylko wyciągała ode mnie pieniądze.
-
-[MEA3_C]
-Zostawiłem samochód w umówionym miejscu.
-
-[MEA3_D]
-Jedź po moją żonę do pawilonu 'Klasyczny Manicure' i przywieź ją do fabryki.
-
-[MEA4_A]
-Cholera, wpakowałem się w tarapaty!
-
-[MEA4_B]
-Okazuje się, że moja żona romansowała z gościem, któremu wiszę pieniądze.
-
-[MEA4_C]
-Jest mocno wkurzony i chce mi się zrewanżować!
-
-[MEA4_E]
-on myśli, że chcę oddać mu kasę...
-
-[MEA4_F]
-ale mnie się zdaje...
-
-[MEA4_G]
-że do misek psów z Liberty jeszcze w tym miesiącu trafi kolejny rodzaj mięska!
-
-[WELCOME]
-WITAMY W
-
-[HM1_2]
-~g~Zdobądź samochód! Pamiętaj, że liczą się tylko kolesie rozjechani samochodem!
-
-[HELP8_B]
-Naciśnij klawisz~h~ ~k~~PED_SNIPER_ZOOM_IN~~w~, aby ~h~przybliżyć ~w~widok przez lunetkę karabinu oraz klawisz~h~ ~k~~PED_SNIPER_ZOOM_OUT~~w~, aby ~h~oddalić~w~ widok.
-
-[LRQC_1]
-Muszę, hm, porozmawiać z Asuką.
-
-[LRQC_2]
-Może wyskoczysz na spacer po mieście?
-
-[LRQC_3]
-Musisz znaleźć sobie jakąś kryjówkę.
-
-[LRQC_4]
-W Belville jest magazyn, który powinien ci odpowiadać.
-
-[LRQC_5]
-Kiedy będziesz gotowy, wróć do mojego apartamentu,
-
-[LRQC_6]
-to pogadamy, co robić dalej.
-
-[JM6_5]
-~g~Musisz załatwić pojazd, którym uciekniemy, idioto!
-
-[JM2_F]
-Jeżeli potrzebujesz giwery, to idź na zaplecze Amu-Nacji naprzeciwko stacji metra.
-
-[LOVE4_7]
-~g~Na Wyspie Staunton jest jakiś plac budowy, może to właśnie tam zabrali pakunek.
-
-[LOVE4_8]
-~g~Aby otworzyć ten garaż, musisz mieć samochód.
-
-[TSCORE]
-ZAROBEK: $~1~
-
-[AM1_9]
-~r~Salvatore uciekł z powrotem do klubu 'U Luigiego'!
-
-[AM1_6]
-~g~Jeżeli będziesz kręcił się wokół klubu Luigiego, to mafia z pewnością cię wypatrzy!
-
-[TM2_3]
-~g~To pułapka! Załatw ich!!!
-
-[FM4_1]
-Tu mówi Maria. Ten samochód to pułapka! Spotkaj się ze mną na południowym końcu Mostu Callahan.
-
-[JM1_7]
-~g~Zamknij drzwi samochodu! Mike może coś zwąchać!
-
-[KM5_1]
-~g~DILER ROZJECHANY!!!
-
-[KM5_6]
-~g~Musisz zamordować co najmniej 8 dilerów z gangu Yardie.
-
-[KM5_7]
-~g~Zabijaj jak najszybciej! Kiedy sprzedadzą cały towar, pochowają się w swoich norach!
-
-[RM3_8]
-~r~Ten samochód to tylko przynęta!!
-
-[LM3_8]
-Cześć, jestem Joey.
-
-[LM3_9]
-Luigi mówił, że można ci ufać, więc wpadnij później,
-
-[KM3_5]
-~g~Naciśnij klakson, aby zacząć rozmowy.
-
-[LOVE7]
-ZNIKNIĘCIE LOVE'A
-
-[LOVE2_5]
-~g~Z Kenji'ego została już tylko kupa mięsa na twoje masce! Uciekaj z Newport i pozbądź się samochodu!
-
-[AS2_11]
-~g~~1~ Z 9!
-
-[GARAGE1]
-~g~Wysiądź z samochodu i wyjdź na zewnątrz.
-
-[KM3_11]
-~g~Kartel został zaatakowany, a teczka nie została odzyskana.
-
-[KM3_12]
-~g~Zabij wszystkich Kolumbijczyków, zniszcz pojazdy i odzyskaj teczkę.
-
-[KM3_13]
-~g~Odwieź teczkę do kasyna.
-
-[RM5_6]
-~g~Prawie go masz! Staranuj jego wóz swoim pojazdem albo rozwal materiałami wybuchowymi!
-
-[PBOAT_1] { re3 change }
-Naciśnij klawisz ~h~~k~~VEHICLE_FIREWEAPON~~w~, aby otworzyć ogień z działek na łodzi.
-
-[PBOAT_2] { re3 change }
-Naciśnij klawisz ~h~~k~~VEHICLE_FIREWEAPON~~w~, aby otworzyć ogień z działek na łodzi.
-
-[DIAB1_B]
-Mówi El Burro z gangu Diablo.
-
-[DIAB1_D]
-Jesteś nowy w Liberty, ale na ulicach już zaczyna być o tobie głośno.
-
-[DIAB1_E]
-Organizuję dla rozrywki mały wyścig. Punkt startu znajduje się przy starej szkole w okolicach Mostu Callahan.
-
-[DIAB1_F]
-Skołuj sobie gablotę. Wygrywa ten, kto pierwszy zaliczy wszystkie punkty na trasie.
-
-[HM2_1] { re3 change }
-Użyj zdalnie sterowanych samochodzików, aby zniszczyć samochody opancerzone. Naciśnij klawisz ~h~~k~~VEHICLE_FIREWEAPON~~w~, aby zdetonować ładunek.
-
-[HM2_1A] { re3 change }
-Użyj zdalnie sterowanych samochodzików, aby zniszczyć samochody opancerzone. Naciśnij klawisz ~h~~k~~VEHICLE_FIREWEAPON~~w~, aby zdetonować ładunek.
-
-[HM2_2]
-~r~Nie udało ci się zniszczyć wszystkich samochodów opancerzonych!
-
-[HM2_6]
-~g~Samochód opancerzony został zniszczony!
-
-[RM3_A]
-Znam w tym mieście jednego bardzo ważnego faceta, prawdziwą grubą rybę,
-
-[RM3_H]
-który słynie ze swych, jak to ująć, nietypowych upodobań i wielkiej fortuny, jaką na nie wydaje.
-
-[RM3_B]
-Uwikłał się w proces sądowy, a prokuratura zdobyła kompromitujące go fotografie.
-
-[RM3_C]
-Zrobili je na imprezie w kostnicy czy coś takiego.
-
-[LOVE6_A]
-Przyjacielu, przyjmij ode mnie lekcję prowadzenia interesów.
-
-[LOVE6_E]
-Jeżeli posiadasz przedmiot jedyny w swoim rodzaju, to dokładnie wszyscy, nawet ze swoimi żonami, będą się ze wszystkich sił starać ci go odebrać,
-
-[LOVE6_C]
-Oddziały antyterrorystyczne otoczyły obszar, na którym znajduje się mój współpracownik wraz z pakunkiem.
-
-[LOVE6_D]
-Jedź tam i weź ciężarówkę. Posłużysz jako przynęta.
-
-[LOVE6_F]
-Odciągnij ich uwagę tak, aby mój przyjaciel mógł spokojnie opuścić to miejsce.
-
-[AM3_C]
-Teraz najprawdopodobniej czyha na zatoce! Ukradnij łódź policyjną i raz na zawsze zakończ jego karierę!
-
-[FESZ_UC]
-ANULUJ
-
-[FEDS_SM]
-L1, R1 - ZMIANA MENU
-
-[FEDS_AS]
-;= - ZMIANA WYBORU
-
-[FEDSAS2]
-<> - ZMIANA WYBORU
-
-[FEDS_SS]
-L1, R1 - ZMIANA WYBORU
-
-[FEDSSC1]
-; - SZYBSZE PRZEWIJANIE
-
-[FEDSSC2]
-Err:509
-
-[MEA2_3]
-~g~Odwieź samochód do fabryki.
-
-[RM1_3]
-~r~McAffrey zwiał!
-
-[RM1_4]
-~g~Zużyłeś wszystkie granaty! Wróć po nowy zapas do Amu-Nacji!
-
-[RM1_5]
-~g~Wracaj i podpal ten dom!
-
-[RM6_4]
-~g~Jedź do dziupli i zabierz rzeczy Raya.
-
-[RM6_5]
-~g~CIA nieustannie obserwuje most, znajdź inną trasę.
-
-[HM2_F]
-i sprzątnąć ich pancerny złom.
-
-[HM_4]
-'W POGONI ZA KASĄ'
-
-[MEA2_B5]
-TEKST JUŻ NIEPOTRZEBNY
-
-[MEA1_B5]
-TEKST JUŻ NIEPOTRZEBNY
-
-[MEA3_B5]
-TEKST JUŻ NIEPOTRZEBNY
-
-[MEA4_B7]
-ale jeżeli zechcesz wpaść do mojego biura...
-
-[MEA3_B4]
-Marty chce się ze mną widzieć? Lepiej niech się streszcza, bo muszę jeszcze zrobić sobie dzisiaj nową fryzurę.
-
-[KM3_7]
-Ludzie, to pułapka Yakuzy!
-
-[FES_LOF]
-Wczytywanie nieudane.
-
-[FES_SLO]
-ZAPISZ PLIK
-
-[FES_ISC]
-USZKODZONY
-
-[FESZ_TI]
-ZAPISZ Z1
-
-[FESZ_SA]
-Zapis gry
-
-[MC_LDFL]
-Wczytywanie nieudane!
-
-[MC_NWRE]
-Trwa ponowne uruchamianie gry.
-
-[LOVE6_3]
-~g~Masz ~1~ sekund na powrót do konwojowozu albo misja zakończy się porażką.
-
-[LOVE6_4]
-~r~Straciłeś fałszywy konwojowóz!
-
-[HELP1]
-Zatrzymaj się wewnątrz niebieskiego pola.
-
-[HELP12]
-Stań na niebieskim polu, aby rozpocząć misję.
-
-[HJSTAT]
-Odległość: ~1~,~1~m Wysokość:~1~,~1~m Salta: ~1~ Obroty: ~1~_
-
-[HJSTATW]
-Odległość: ~1~.~1~m Wysokość: ~1~.~1~m Salta: ~1~ Obroty: ~1~_ Plus doskonałe lądowanie!
-
-[DIAB1_5]
-CZAS WYŚCIGU:
-
-[LOVE3_4]
-~r~Zniszczyłeś samolot!
-
-[F_FAIL1]
-Misja strażacka zakończona.
-
-[F_CANC]
-~r~Misja strażacka anulowana!
-
-[F_EXTIN]
-POŻARY:
-
-[A_COMP1]
-Misja ratunkowa wykonana!
-
-[A_CANC]
-~R~Misja ratunkowa anulowana!
-
-[A_COMP3]
-Misja ratunkowa wykonana! Ty chyba nigdy się nie męczysz!
-
-[ATUTOR]
-Wciśnij klawisz ~h~~k~~TOGGLE_SUBMISSIONS~~w~, aby włączyć lub wyłączyć misje ratunkowe.
-
-[ATUTOR3]
-Wciśnij klawisz ~h~~k~~TOGGLE_SUBMISSIONS~~w~, aby włączyć lub wyłączyć misje ratunkowe.
-
-[ALEVEL]
-Misja Ratunkowa, Poziom ~1~
-
-[A_FAIL1]
-Misja ratunkowa zakończona.
-
-[FEST_HA]
-Najwyższy poziom misji ratunkowej
-
-[A_SAVES]
-URATOWANI LUDZIE:~1~
-
-[C_KILLS]
-ZABICI PRZESTĘPCY: ~1~
-
-[HM1_B]
-Mam problem z paroma frajerami.
-
-[AM2_A]
-Śmierć Salvatore to radosna wiadomość,
-
-[AM2_A2]
-widać, że jesteś dobrym zabójcą. Lubię tę cechę u ludzi.
-
-[AM2_B]
-To mój brat Kenji.
-
-[AM2_C]
-Asuka ma dla ciebie małą robótkę. Kiedy skończysz, wpadnij do mojego kasyna, to pogadamy.
-
-[AM2_D]
-Zupełnie jak Kenji, on też zawsze chce bawić się moimi zabawkami.
-
-[AM2_E]
-Moja wtyczka w policji donosi, że Mafia obserwuje nasze lokale w całym mieście.
-
-[AM2_E2]
-Prawdopodobnie usiłują cię wytropić.
-
-[AM2_F]
-Dopóki nie załatwimy tej sprawy, nie możemy prowadzić zwykłej działalności.
-
-[AM2_G]
-Załatw tych głupawych szpiegów i raz na zawsze zakończ tę wendettę.
-
-[F_START]
-~g~W okolicach ~a~ zauważono płonący pojazd. Udaj się tam i ugaś pożar.
-
-[AM4_1A]
-Odszukaj telefon na Park West Belleville.
-
-[AM4_1B]
-Odszukaj telefon na kampusie Liberty.
-
-[AM4_1C]
-Odszukaj telefon na Park South Belleville.
-
-[AM4_1D]
-Spotkajmy się w parku przy toaletach.
-
-[HJSTATF]
-Odległość: ~1~ stóp Wysokość: ~1~ stóp Salta: ~1~ Obroty: ~1~_
-
-[HJSTAWF]
-Odległość: ~1~.~1~ stóp Wysokość: ~1~.~1~ stóp Salta: ~1~ Obroty: ~1~_ Plus doskonałe lądowanie!
-
-[HM1_F]
-Lepiej uważaj - na ulicach będą też ludzie z Jacks, którzy mogą uznać, że polujesz również na nich!
-
-[HM1_D]
-Nazywają się 'Dziewiątki' i ubierają się na purpurowo. Każdy dzień, kiedy te leszcze obnoszą się ze swoim barwami,
-
-[HM1_G]
-to dzień wstydu dla mojego gangu.
-
-[MEA2_B]
-i ukradli parę rzeczy, co pozwoli mi wyciągnąć kasę z odszkodowania.
-
-[TM3_H]
-~w~Dobrze się spisałeś, młody, naprawdę dobrze.
-
-[TM3_I]
-~w~Chodź, Don chce cię poznać.
-
-[TM3_J]
-~w~Heeeej, Luigi!
-
-[TM3_K]
-~w~Moje dziewczynki tęsknią za tobą, Salvatore, dawno cię u nas nie było.
-
-[TM3_L]
-~w~Przekaż im ode mnie, że kiedy załatwimy całą tę nieszczęsną sprawę,
-
-[TM3_M]
-~w~razem pojedziemy do klubu i uczcimy zwycięstwo
-
-[TM3_N]
-~w~Oto i mój chłopak.
-
-[TM3_N2]
-~w~Jak się masz, tato?
-
-[TM3_O]
-~w~Znalazłeś już sobie przyzwoitą kobietę?
-
-[TM3_P]
-~w~Ech, twoja matka, wieczny odpoczynek racz jej dać Panie, przewraca się w grobie,
-
-[TM3_Q]
-~w~bo jej syn jeszcze nie ma żony.
-
-[TM3_R]
-~w~Wiem, tato. Pracuję nad tym.
-
-[TM3_S]
-~w~TONI! Jak twoja Mamuśka?
-
-[TM3_T]
-~w~To wspaniała kobieta. Silna. Firenze.
-
-[TM3_U]
-~w~Mama ma się dobrze... Znakomicie.
-
-[TM3_V]
-~w~Doskonale, doskonale. Posłuchajcie, panowie, rozgośćcie się w środku, a ja porozmawiam z naszym nowym przyjacielem.
-
-[TM3_W]
-~w~Widzę przed tobą wielką przyszłość, chłopcze...
-
-[RM1_A]
-Ta szuja McAffrey wziął więcej łapówek niż ktokolwiek inny.
-
-[RM1_B]
-Teraz myśli, że zasłuży na wygodną emeryturę, jeżeli zakapuje nas policji.
-
-[RM1_C]
-Właśnie nas wsypał!
-
-[RM4_B]
-Trzeba go uciszyć raz na zawsze.
-
-[RM4_E]
-Od jutra ma spać z rybami, a nie jadać je na kolację.
-
-[LOVE3_B]
-Dziś w nocy mały samolot przeleci nad zatoką, podchodząc do lądowania.
-
-[LOVE4_D]
-Niestety, władze lotniska przejęły samolot i zaczęły rozbierać go na części,
-
-[LOVE4_H]
-dopóki nie rzuciłem na szalę całego swojego autorytetu.
-
-[LOVE4_E]
-Przejedź przez most do Shoreside Vale i jedź na lotnisko im. Francisa.
-
-[GTAB_A]
-Lepiej stąd znikajmy. Cholera wie, co to jest,
-
-[GTAB_B]
-ale zdaje się, że temu facetowi bardzo na tym zależy, więc to z pewnością musi mieć jakąś wartość.
-
-[GTAB_C]
-Co, u diabła!
-
-[GTAB_D]
-TO TY!
-
-[GTAB_E]
-Hej, spokojnie, amigo! De nada! De nada!
-
-[GTAB_F]
-Kiedy ostatni raz cię widziałem, twoje truchło spływało do ścieków!
-
-[GTAB_G]
-Nie strzelaj, amigo. Nie ma problemu. My przyjaciele. Proszę, weź to sobie.
-
-[GTAB_H]
-Nie bądź taką ciotą!
-
-[GTAB_I]
-Nie mamy wyboru, kotku!
-
-[GTAB_J]
-Zawsze mamy wybór, tępaku!
-
-[GTAB_K]
-Przepraszam za tę głupią sukę, one wszystkie są jednakowe... por favor?
-
-[GTAB_L]
-Więc ta dziwka zwiała?
-
-[GTAB_M]
-Ale zrobiłeś mi przysługę,
-
-[GTAB_N]
-nie jesteś jedyną osobą, która ma rachunki do wyrównania z Kartelem.
-
-[GTAB_O]
-Ten gnidy zabiły mi brata!
-
-[GTAB_P]
-Nigdy nie zabiłem żadnego członka Yakuzy!
-
-[GTAB_Q]
-KŁAMIESZ! Wszyscy widzieliśmy zabójcę z Kartelu.
-
-[GTAB_R]
-Wytropimy i wytłuczemy was wszystkich, wy kolumbijskie kundle!
-
-[GTAB_S]
-Pobawię się z twoim przyjacielem, aby wydobyć z niego jakieś informacje i troszkę się rozerwać.
-
-[GTAB_T]
-Ej, wpadnij później, będe cię jeszcze potrzebował.
-
-[GTAB_U]
-Proszę, amigo, nie zostawiaj mnie z nią! Ta chica to wariatka! Amigo? Hej, AMIGOOO!!!... Aaaaaa!
-
-[LOVE5_A]
-Raz po raz dowodzisz, że warto w ciebie inwestować, a to rzadkość w dzisiejszych czasach kłamstwa i obłudy.
-
-[KM3_1]
-~g~Kartel spodziewa się kolesia z Yardies, więc idź i ukradnij samochód gangu Yardie! Powinieneś znaleźć ich w Newport, na północy.
-
-[LOVE1_1]
-~g~Podwędź samochód gangu kolumbijskiego, abyś mógł swobodnie przeniknąć do ich kryjówki. Samochód znajdziesz na północ stąd, w Fort Staunton.
-
-[FM1_Q1]
-~w~Szukasz mocnych wrażeń? Może odrobinę... Hm? Odrobinę HEROINY?
-
-[FM1_R]
-~w~Czołem, Chico. Nie, daj mi to, co zawsze.
-
-[FM1_T]
-~w~Dzięki, Chico. Na razie!
-
-[FM1_W]
-~w~W porządku, piesku! Posiedź tu i popilnuj samochodu, a ja wyskoczę i poruszam trochę tyłkiem.
-
-[FM1_X]
-~w~OK, piesku! Znikajmy stąd. Hau hau!
-
-[FM1_Q]
-~g~Cześć, Mario! Moja ulubiona klientka!
-
-[FM1_S1]
-~w~Hej, może wpadniesz na imprezę w tej pustej hali magazynowej na wschodnim krańcu Atlantic Quays?
-
-[FM1_U]
-~w~Gracias i życzę przyjemnych wrażeń. To niezły towar...
-
-[FM1_V]
-~w~Jazda, piesku! Jedziemy zajrzeć na tę imprezę!
-
-[FM1_SS]
-~r~NASŁUCH RADIOWY: ~g~Cztery-pięć do wszystkich jednostek: Zapewnić wsparcie akcji antynarkotykowej w Atlantic Quays...
-
-[LOVE6_B]
-nawet jeżeli mają tylko blade pojęcie na temat jego rzeczywistej wartości.
-
-[TM3_A1]
-~r~Joey się usmażył!
-
-[TM3_A2]
-~r~Joey i Lugi spiekli się na węgiel!
-
-[TM3_A3]
-~r~Joey, Luigi i Toni usmażeni!
-
-[FM4_2]
-Posłuchaj, Salvatore podejrzewa, że kombinujemy coś za jego plecami,
-
-[FM4_3]
-dlatego postanowił sprzedać cię Kartelowi.
-
-[FM4_4]
-Nie mogę do tego dopuścić. Najgorsze w tym wszystkim jest to,
-
-[FM4_4B]
-że to moja wina... To ja mu powiedziałam, że między nami coś jest...
-
-[FM4_5]
-Nie pytaj mnie, po co. Sama nie wiem.
-
-[FM4_6]
-Posłuchaj, na terytorium mafii jesteś poszukiwany, ja też chciałabym się stąd wyrwać.
-
-[FM4_6B]
-Widziałam już za dużo śmierci, zbyt wiele krwi!
-
-[FM4_7]
-Mam starą dobrą przyjaciółkę... Nazywa się Asuka. Możemy jej zaufać.
-
-[FM4_8]
-Dobra, wystarczy już tych przemówień.
-
-[FM4_9]
-Zbierajmy się stąd, zanim pojawią się tu całe wycieczki rozhisteryzowanych Włochów, którzy będą chcieli rozstrzygać z nami rodzinne zatargi.
-
-[CRED001]
-ROCKSTAR STUDIOS
-
-[CRED002]
-PRODUCENT
-
-[CRED003]
-LESLIE BENZIES
-
-[CRED004]
-KIEROWNIK ARTYSTYCZNY
-
-[CRED005]
-AARON GARBUT
-
-[CRED006]
-KIEROWNIK TECHNICZNY
-
-[CRED007]
-OBBE VERMEIJ
-
-[CRED008]
-ADAM FOWLER
-
-[CRED009]
-PROJEKT
-
-[CRED010]
-CRAIG FILSHIE
-
-[CRED011]
-WILLIAM MILLS
-
-[CRED012]
-CHRIS ROTHWELL
-
-[CRED013]
-JAMES WORRALL
-
-[CRED014]
-SCENARIUSZ
-
-[CRED015]
-JAMES WORRALL
-
-[CRED016]
-PAUL KUROWSKI
-
-[CRED017]
-DAN HOUSER
-
-[CRED018]
-POSTACI
-
-[CRED019]
-IAN MCQUE
-
-[CRED020]
-ANIMACJA & REŻYSERIA
-
-[CRED021]
-ALEX HORTON
-
-[CRED022]
-LEE MONTGOMERY
-
-[CRED023]
-PROJEKTY POJAZDÓW
-
-[CRED024]
-PAUL KUROWSKI
-
-[CRED025]
-GRAFICY
-
-[CRED026]
-KEIRAN BAILLIE
-
-[CRED027]
-ADAM COCHRANE
-
-[CRED028]
-GARY MCADAM
-
-[CRED029]
-MICHAEL PIRSO
-
-[CRED030]
-ANDREW SOOSAY
-
-[CRED031]
-ALISDAIR WOOD
-
-[CRED032]
-KODERZY
-
-[CRED033]
-ALAN CAMPBELL
-
-[CRED034]
-MARK HANLON
-
-[CRED035]
-ANDRZEJ MADAJCZYK
-
-[CRED036]
-ALEXANDER ROGER
-
-[CRED037]
-GRAEME WILLIAMSON
-
-[CRED038]
-MUZYKA
-
-[CRED039]
-CRAIG CONNER
-
-[CRED040]
-STUART ROSS
-
-[CRED041]
-KONCEPCJA I MASTERING DŹWIĘKU
-
-[CRED042]
-ALLAN WALKER
-
-[CRED043]
-PROGRAMOWANIE AUDIO
-
-[CRED044]
-RAYMOND USHER
-
-[CRED045]
-KIEROWNIK TESTÓW
-
-[CRED046]
-CRAIG ARBUTHNOTT
-
-[CRED047]
-GŁÓWNI TESTERZY
-
-[CRED048]
-ANDY DUTHIE
-
-[CRED049]
-JOHN HAIME
-
-[CRED050]
-NEIL CORBETT
-
-[CRD050A]
-TESTERZY
-
-[CRED051]
-GRAEME JENNINGS
-
-[CRED052]
-DAVID MURDOCH
-
-[CRED053]
-DAVID BEDDOES
-
-[CRED054]
-EDWIN SMITH
-
-[CRED055]
-MARK FLETT
-
-[CRED056]
-MICHAEL SUTHERLAND
-
-[CRED057]
-POMOC TECHNICZNA
-
-[CRED058]
-LORRAINE ROY
-
-[CRED059]
-CHRISTINE CHALMERS
-
-[CRED060]
-ROCKSTAR
-
-[CRED061]
-PRODUCENT WYKONAWCZY
-
-[CRED062]
-SAM HOUSER
-
-[CRED063]
-PRODUCENT
-
-[CRED064]
-DAN HOUSER
-
-[CRED065]
-DYREKTOR DS. ROZWOJU
-
-[CRED066]
-JAMIE KING
-
-[CRED067]
-PRODUCENT TECHNICZNY
-
-[CRED068]
-GARY J. FOREMAN
-
-[CRED069]
-PRODUCENT POMOCNICZY
-
-[CRED070]
-JEREMY POPE
-
-[CRED071]
-KOORDYNACJA MUZYCZNA
-
-[CRED072]
-TERRY DONOVAN
-
-[CRED073]
-ZESPÓŁ PRODUKCYJNY ROCKSTAR
-
-[CRED074]
-TERRY DONOVAN
-
-[CRED075]
-JENNIFER KOLBE
-
-[CRED076]
-JENEFER GROSS
-
-[CRED077]
-LAURA PATERSON
-
-[CRED078]
-JEFF CASTANEDA
-
-[CRED079]
-CHRIS CARRO
-
-[CRED080]
-ADAM TEDMAN
-
-[CRED081]
-JUNG KWAK
-
-[CRED082]
-BRIAN WOOD
-
-[CRED083]
-PAUL YEATES
-
-[CRED084]
-STANTON SARJEANT
-
-[CRED085]
-WICEPREZES DS. MARKETINGU
-
-[CRED086]
-TERRY DONOVAN
-
-[CRED087]
-KOORDYNACJA TECHNICZNA
-
-[CRED088]
-BRANDON ROSE
-
-[CRED089]
-KIEROWNIK DS. ZAPEWNIENIA JAKOŚCI
-
-[CRED090]
-JEFF ROSA
-
-[CRED091]
-GŁÓWNY ANALITYK
-
-[CRED092]
-ADAM DAVIDSON
-
-[CRED093]
-ANALITYK GRY
-
-[CRED094]
-RICHARD HUIE
-
-[CRED095]
-ZESPÓŁ TESTUJĄCY
-
-[CRED096]
-LANCE WILLIAMS
-
-[CRED097]
-JOE GREENE
-
-[CRED098]
-BRIAN PLANER
-
-[CRED099]
-OSWALD GREENE
-
-[CRED100]
-REDAKCJA 'LIBERTY TREE'
-
-[CRED101]
-JAMES WORRALL
-
-[CRED102]
-DAN HOUSER
-
-[CRED103]
-ADAM TEDMAN
-
-[CRED104]
-PAUL YEATES
-
-[CRED105]
-JENEFER GROSS
-
-[CRED106]
-LAURA PATERSON
-
-[CRED107]
-SEKWENCJE FILMOWE
-
-[CRED108]
-SCENARIUSZ: DAN HOUSER I JAMES WORALL
-
-[CRED109]
-REŻYSERIA DŹWIĘKU: DAN HOUSER
-
-[CRED110]
-PRODUKCJA DŹWIĘKU: RENAUD SEBBANE
-
-[CRED111]
-OBSADA
-
-[CRED112]
-FRANK VINCENT JAKO SALVATORE LEONE
-
-[CRED113]
-JOE PANTOLIANO JAKO LUIGI GOTERELLI
-
-[CRED114]
-MICHAEL MADSEN JAKO TONI CIPRIANI
-
-[CRED115]
-MICHAEL RAPAPORT JAKO JOEY LEONE
-
-[CRED116]
-DEBBI MAZAR JAKO MARIA
-
-[CRED117]
-KYLE MACLACHLAN JAKO DONALD LOVE
-
-[CRED118]
-ROBERT LOGGIA JAKO RAY MACHOWSKI
-
-[CRED119]
-GURU JAKO 8-BALL
-
-[CRED120]
-SONDRA JAMES JAKO MAMUŚKA
-
-[CRED121]
-LIANA PAI JAKO ASUKA
-
-[CRED122]
-LES MAU JAKO KENJI
-
-[CRED123]
-CYNTHIA FARRELL JAKO CATALINA
-
-[CRED124]
-AL. ESPINOSA JAKO MIGUEL
-
-[CRED125]
-CHRIS PHILLIPS JAKO EL BURRO
-
-[CRED126]
-HUNTER PLATIN JAKO CHICO
-
-[CRED127]
-WALTER MUDU JAKO D-ICE
-
-[CRED128]
-CURTIS MCCLARIN JAKO CURTLY
-
-[CRED129]
-BILL FIORE JAKO DARKEL
-
-[CRED130]
-CHRIS PHILLIPS JAKO MARTY CHONKS
-
-[CRED131]
-HUNTER PLATIN JAKO KUDŁATY BOB
-
-[CRED132]
-WALTER MUDU JAKO KING COURTNEY
-
-[CRED133]
-HUNTER PLATIN JAKO JEDNORĘKI PHIL
-
-[CRED134]
-KIM GURNEY JAKO MISTY
-
-[CRED135]
-MOTION CAPTURE
-
-[CRED136]
-ANIMACJA
-
-[CRD136A]
-ALEX HORTON
-
-[CRED137]
-REŻYSERIA
-
-[CRD137A]
-NAVID KHONSARI
-
-[CRED138]
-PRODUKCJA
-
-[CRD138A]
-JAMIE KING
-
-[CRD138B]
-RENAUD SEBBANE
-
-[CRED139]
-NAGRANIA PRZEPROWADZONO W MODERN UPRISINGS STUDIOS, BROOKLYN
-
-[CRED140]
-AKTORZY
-
-[CRD140A]
-MARTINEZ
-
-[CRD140B]
-GISELLE JONES
-
-[CRD140C]
-STEPHEN DANIELS
-
-[CRD140D]
-ROBERT STIO
-
-[CRD140E]
-JENNY GROSS.
-
-[CRED141]
-DIALOGI PRZECHODNIÓW
-
-[CRED142]
-TEKST: DAN HOUSER, NAVID KHONSARI I JAMES WORALL
-
-[CRED143]
-REŻYSERIA: CRAIG CONNER, DAN HOUSER I LAZLOW
-
-[CRED144]
-PRODUKCJA: RENAUD SEBBANE
-
-[CRED145]
-OBSADA
-
-[CRED146]
-HUNTER PLATIN
-
-[CRED147]
-DAN HOUSER
-
-[CRED148]
-RENAUD SEBBANE
-
-[CRED149]
-MARIA CHAMBERS
-
-[CRED150]
-JEFF STANTON
-
-[CRED151]
-RYAN CROY
-
-[CRED152]
-DEENA BERMAN
-
-[CRED153]
-MARIA CHAMBERS
-
-[CRED154]
-ALICE B. SALTZMAN
-
-[CRED155]
-ALEX ANTHONY SIOUKAS
-
-[CRED156]
-SEAN R. LYNCH
-
-[CRED157]
-AMY SALZMAN
-
-[CRED158]
-COLIN MCSHANE
-
-[CRED159]
-COREY WADE
-
-[CRED160]
-GERALD COSGROVE
-
-[CRED161]
-STEPHANIE ROY
-
-[CRED162]
-DORIS WOO
-
-[CRED163]
-JOSEPH GREENE
-
-[CRED164]
-LAZLOW JONES
-
-[CRED165]
-HSIANG LIN
-
-[CRED166]
-STEVE MICHAEL ROBERT
-
-[CRED167]
-MATHEW MURRAY
-
-[CRED168]
-RICHARD HUIE
-
-[CRED169]
-GARVIN ATWELL
-
-[CRED170]
-STEVE KNEZEVICH
-
-[CRED171]
-YUKIMURA SATO
-
-[CRED172]
-FRANK CHAVEZ
-
-[CRED173]
-LIEZL JACINTO
-
-[CRED174]
-CANAAN MCKOY
-
-[CRED175]
-ADAM DAVIDSON
-
-[CRED176]
-LANCE WILLIAMS
-
-[CRED177]
-NEIL MCCAFFREY
-
-[CRED178]
-LAURA PATERSON
-
-[CRED179]
-REY CONCEPCION
-
-[CRED180]
-CHARLES HEROLD
-
-[CRED181]
-ANDREW GREENWALD
-
-[CRED182]
-JAMES MIELKE
-
-[CRED183]
-PETER SUCIU
-
-[CRED184]
-ALEX ODULIO
-
-[CRED185]
-DON NKRUMAH
-
-[CRED186]
-KENDALL PITTMAN
-
-[CRED187]
-SAL SUAZO
-
-[CRED188]
-EREK MATEO
-
-[CRED189]
-CHRIS DIFATE
-
-[CRED190]
-LEILA MILTON
-
-[CRED191]
-DARREN ZOLTOWSKI
-
-[CRED192]
-VIRGINIA SMITH
-
-[CRED193]
-KEVIN CASSIN
-
-[CRED194]
-JASON SHIGEMORI
-
-[CRED195]
-KELLY KINSELLA
-
-[CRED196]
-MOLLIE STICKNEY
-
-[CRED197]
-STANTON SARJEANT
-
-[CRED198]
-LAURA WALSH
-
-[CRED199]
-MARK GARONE
-
-[CRED200]
-JOANNA SLY
-
-[CRED201]
-ELIZABETH HOWELL
-
-[CRED202]
-ANA HERCULES
-
-[CRED203]
-SHIRLEY IRICK
-
-[CRED204]
-KASHONA FIELDS
-
-[CRED205]
-JOEL M. LILJE
-
-[CRED206]
-JOHN DIBENEDETTO
-
-[CRED207]
-NANCY GILES
-
-[CRED208]
-RYAN CROY
-
-[CRED209]
-JENNIFER KOLBE
-
-[CRED210]
-LIAM BURKE
-
-[CRED211]
-SIGRID PREISSL
-
-[CRED212]
-ANITA FITZSIMONS
-
-[CRED213]
-PHILIPPA RASELLI
-
-[CRED214]
-WIL QUESNEL
-
-[CRED215]
-FALKO BURKERT
-
-[CRED216]
-SARA SEWELL
-
-[CRED217]
-STACJE RADIOWE ORAZ MUZYKA
-
-[CRED218]
-PRODUKCJA DLA ROCKSTAR UK
-
-[CRD218A]
-CRAIG CONNER
-
-[CRD218B]
-STUART ROSS
-
-[CRED219]
-KOORDYNATOR ŚCIEŻKI DŹWIĘKOWEJ
-
-[CRED220]
-TERRY DONOVAN
-
-[CRED221]
-PRODUKCJA DLA ROCKSTAR GAMES
-
-[CRED222]
-DAN HOUSER
-
-[CRED223]
-REDAKCJA
-
-[CRED224]
-CRAIG CONNER
-
-[CRED225]
-ALLAN WALKER
-
-[CRED226]
-LAZLOW
-
-[CRED227]
-TEKSTY I WIZERUNKI PREZENTERÓW:
-
-[CRED228]
-DAN HOUSER
-
-[CRED229]
-LAZLOW
-
-[CRED230]
-SPECJALNE PODZIĘKOWANIA DLA:
-
-[CRED231]
-ADAM TEDMAN
-
-[CRED232]
-ALEX MASON
-
-[CRED233]
-JUDY HENDERSON CASTING
-
-[CRED234]
-HAMISH BROWN
-
-[CRED235]
-CHRISSY HOBAN
-
-[CRED236]
-INNES RICARD
-
-[CRED237]
-LILION BROZSKA
-
-[CRED238]
-BOB HILLARY
-
-[CRED239]
-EMILY ANDERSON
-
-[CRED240]
-RICHIE HENDERSON
-
-[CRED241]
-CHRSTIAN CANTAMESSA
-
-[CRED242]
-JERONIMO BARRERA
-
-[CRED243]
-ALEXANDER ILLES
-
-[CRED244]
-BARANE CHAN
-
-[CRED245]
-DUNCAN SHIELDS
-
-[CRED246]
-BARANE CHAN
-
-[CRED247]
-DEREK PAYNE
-
-[CRED248]
-KEVIN WONG
-
-[CRED249]
-ROSS ELLIOTT
-
-[CRED250]
-ROSS BEAZLEY
-
-[CRED251]
-ALEX BAZLINTON
-
-[CRED252]
-DAVE WATSON
-
-[CRED253]
-MALCOLM SMITH
-
-[CRED255]
-ANDREW SEMPLE
-
-[CRED256]
-ARTYŚCI
-
-[CRED257]
-STUART PETRI
-
-[CRED258]
-JERONIMO BARRERA
-
-[CRED259]
-CARLY SLATER
-
-[CRED260]
-GREG LAU
-
-[CRED261]
-STEVE KNEZEVICH
-
-[CRED262]
-DEVIN WINTERBOTTOM
-
-[CRED263]
-JAMEEL VEGA
-
-[CRED264]
-LEE CUMMINGS
-
-[CRED265]
-DEVIN BENNET
-
-[CRED266]
-ELIZABETH SATTERWHITE
-
-[CRED267]
-AARON RIGBY
-
-[CRED268]
-STEVE K.
-
-[CRED269]
-GREG LAU
-
-[CRED270]
-MIKE HONG
-
-[CINCAM]
-Kamera Filmowa
-
-[KM1_13]
-Wprowadź samochód do garażu!
-
-[KM3_14]
-~r~Zostałeś zauważony, układ odwołany!
-
-[EBAL_H]
-Poczekaj tutaj, brachu, a ja pójdę do środka i pogadam z Luigim.
-
-[EBAL_M]
-Tylko pamiętaj - nic nie kombinuj z moimi dziewczynami!
-
-[LM2_F]
-Potem zabierz jego samochód i przemaluj go.
-
-[LM2_D]
-proszę bardzo.
-
-[LM1_9]
-Cześć, jestem Misty...
-
-[LM4_A]
-Jakaś gnida z gangu Diablo nasyła swoje brudne dziwki na moje terytorium.
-
-[FM2_B]
-Mamy kreta!
-
-[FM2_C]
-Żaden z niego alfons czy diler, więc pewnie dorabia na boku sprzedając informacje.
-
-[FM3_CC]
-~w~Bracie, wróć, kiedy będziesz miał pieniądze.
-
-[FEDS_AM]
-<> - ZMIANA MENU
-
-[LOVE5_5]
-~r~Nie udało cię się ochronić ciężarówki!
-
-[RM6_6]
-~r~Ray nie żyje!
-
-[RM6_7]
-~r~Ray spóźnił się na samolot.
-
-[RM6_8]
-~r~Zgubiłeś Raya, wracaj po niego.
-
-[FM1_10]
-~g~Zostawiłeś Marię - zawróć i ją zabierz.
-
-[LOVE4_9]
-~r~Samolot został zniszczony!
-
-[LOV4_10]
-~r~Jedyny ślad, który wskazywał, gdzie zniknęła paczka, został zniszczony!
-
-[KM2_D]
-Nie muszę chyba dodawać, że przekażę mu te samochody w darze, aby spłacić dług, który u niego zaciągnąłem.
-
-[KM4_B]
-Interes idzie na tyle dobrze, że dziś możemy odebrać należną nam opłatę za ochronę.
-
-[KM2_E]
-Zdobądź samochody z tej listy i dostarcz je do warsztatu za parkingiem w Newport.
-
-[FM3_8I]
-~w~Znajdź dobre stanowisko strzeleckie. Kiedy oddasz pierwszy strzał, ja zrobię to, co do mnie należy.
-
-[LOVE1_B]
-Doświadczenie uczy mnie, że ludzie tacy jak ty potrafią być niezwykle lojalni za odpowiednią cenę.
-
-[LOVE1_H]
-ale niektórzy ludzie robią się coraz bardziej chciwi.
-
-[LOVE1_C]
-Znam pewnego starszego pana, pochodzącego z krajów Orientu, który jest dla mnie niezwykle cenny.
-
-[LOVE1_I]
-Niestety został on porwany przez jakiś gang z Ameryki Południowej w okolicach Aspatrii.
-
-[MEA4_D]
-Zgodziłem się z nim spotkać...
-
-[MEA4_B4]
-Marty cię przysyła, co? W porząsiu, pokażę tej gliście, jak się robi interesy.
-
-[MEA4_B5]
-Carl, cześć! Ee, potrzebuję jeszcze trochę czasu, żeby zebrać dla ciebie pieniądze.
-
-[MEA1_B4]
-Ach, przysłał cię Chonks, prawda? Chodźmy odwiedzić naszego wspólnego przyjaciela.
-
-[HM5_6]
-Trzeba rozłupać parę łbów...
-
-[LOVE1_5]
-~g~Przestań się obijać, załatw samochód Kolumbijczyków i uratuj przyjaciela Love'a.
-
-[AS1_D]
-~w~Posłuzysz jako przynęta i ściągniesz szwadrony śmierci za sobą do Pike Creek,
-
-[AS1_E]
-~w~gdzie moi ludzie urzadzą im właściwe przyjęcie.
-
-[AS2_C]
-~w~Kartel działa pod przykrywką firmy Dom Kawy Kappa.
-
-[AS2_E]
-~w~Nie mamy wyjścia, trzeba wyłączyć z gry te punkty sprzedaży dragów.
-
-[AS2_F]
-~w~Rozwal je w drzazgi!!
-
-[AS2_A1]
-~w~Miguel to doskonały przykład słynnej latynoskiej odporności.
-
-[AS2_A2]
-~w~Ręce opadają mi ze zmęczenia.
-
-[SIREN_3]
-Aby włączyc syrenę pojazdu, naciśnij klawisz ~h~~k~~VEHICLE_HORN~ ~w~.
-
-[SIREN_4]
-Aby włączyc syrenę pojazdu, naciśnij klawisz ~h~~k~~VEHICLE_HORN~ ~w~.
-
-[AS3_C]
-~w~Eeej! Co to za lepkie żółte świństwo?
-
-[AS3_C1]
-~w~O, cześć, kochanie.
-
-[AS3_F]
-~w~Ta dziewczyna po prostu ma talent.
-
-[AS3_F1]
-~w~Udało jej się wydobyć z naszego gościa ten oto klejnocik.
-
-[AS3_G]
-~w~Za 2 godziny na Lotnisko Francisa przyleci pewien samolot.
-
-[AS3_G1]
-~w~Jest on wyładowany trucizną Cataliny.
-
-[AS3_H]
-~w~Możesz ominąć lotniskowe służby bezpieczeństwa, jeżeli popłyniesz łodzią
-
-[AS3_H1]
-do boi wyznaczających lądowisko i zestrzelisz lądujący samolot.
-
-[AS3_I]
-~w~Zabierz z wraku ładunek!
-
-[AS3_J]
-~w~Tylko bądź ostrożny, dobrze, kochanie?
-
-[AS3_K]
-~w~A teraz spróbujemy olejku chilli...
-
-[RM2_F1]
-Kolumbijczycy będą tutaj lada chwila!
-
-[RM2_K]
-Cholera, już tu są! OGNIA!
-
-[LOVE2_7]
-~g~Teraz pozbądź się samochodu!v
-
-[LOVE2_8]
-~g~Uciekaj z Newport!
-
-[AM1_F]
-Za około trzy godziny (~1~:~1~), Salvatore Leone będzie wychodził z klubu 'U Luigiego'.
-
-[LOVE5_C]
-Masz za nim jechać i pilnować, aby zarówno on, jak i mój pakunek dotarli do Pike Creek bez szwanku.
-
-[FESZ_SR]
-Zapisywanie zakończone niepowodzeniem! Sprawdź kartę pamięci (PS2) w gnieździe KART PAMIĘCI nr 1 i ponów próbę.
-
-[FESZ_FO]
-Czy chcesz sformatować kartę pamięci (PS2) w gnieździe KART PAMIĘCI nr 1?
-
-[FELZ_FO]
-Karta pamięci (PS2) w gnieździe KART PAMIĘCI nr 1 nie jest sformatowana.
-
-[FES_NOC]
-Brak karty pamięci (PS2) w gnieździe KART PAMIĘCI nr 1.
-
-[FES_LOE]
-Wczytywanie zakończone niepowodzeniem! Sprawdź kartę pamięci (PS2) w gnieździe KART PAMIĘCI nr 1 i ponów próbę.
-
-[FES_DEE]
-Kasowanie zakończone niepowodzeniem! Sprawdź kartę pamięci (PS2) w gnieździe KART PAMIĘCI nr 1 i ponów próbę.
-
-[SLONFM]
-Błąd podczas formatowania karty pamięci (PS2) w gnieździe KART PAMIĘCI nr 1.
-
-[SLONDR]
-Niewystarczająca ilość miejsca, aby zapisać stan gry. Proszę włożyć kartę pamięci (PS2) zawierającą co najmniej 500KB wolnego miejsca do gniazda KART PAMIĘCI nr 1.
-
-[SLNSP]
-Niewystarczająca ilość miejsca, aby zapisać stan gry. Proszę włożyć kartę pamięci (PS2) zawierającą co najmniej 200KB wolnego miejsca do gniazda KART PAMIĘCI nr 1.
-
-[FEFD_WR]
-Trwa formatowanie karty pamięci (PS2) w gnieździe KART PAMIĘCI nr 1. Proszę nie wyjmować karty pamięci (PS2), nie resetować ani nie wyłączać konsoli
-
-[FES_ISF]
-NIEOBECNY
-
-[FES_SAG]
-OBECNY
-
-[SLONNO]
-No Memory Card (PS2) in MEMORY CARD slot 1.
-
-[SLONNF]
-Brak karty pamięci (PS2) w gnieździe KART PAMIĘCI nr 1.
-
-[FESZ_FM]
-Karta pamięci (PS2) w gnieździe KART PAMIĘCI nr 1 nie jest sformatowana. Czy chcesz sformatować kartę pamięci (PS2) w gnieździe KART PAMIĘCI nr 1?
-
-[FESZ_FF]
-Formatowanie zakończone niepowodzeniem! Sprawdź kartę pamięci (PS2) w gnieździe KART PAMIĘCI nr 1 i ponów próbę.
-
-[MCDNSP]
-Na karcie pamięci (PS2) w gnieździe KART PAMIĘCI nr 1 jest zbyt mało wolnego miejsca. Aby zapisać dane aplikacji wymagane jest co najmniej 500KB. Czy chcesz kontynuować? (TAK lub NIE)
-
-[MCGNSP]
-Na karcie pamięci (PS2) w gnieździe KART PAMIĘCI nr 1 jest zbyt mało wolnego miejsca. Aby zapisać dane aplikacji wymagane jest co najmniej 200KB. Czy chcesz kontynuować? (TAK lub NIE)
-
-[FESZ_WR]
-Trwa zapisywanie danych. Proszę nie wyjmować karty pamięci (PS2) z gniazda KART PAMIĘCI nr 1, nie resetować ani nie wyłączać konsoli.
-
-[FESZ_OW]
-Trwa nadpisywanie danych. Proszę nie wyjmować karty pamięci (PS2) z gniazda KART PAMIĘCI nr 1, nie resetować ani nie wyłączać konsoli.
-
-[FELD_WR]
-Trwa wczytywanie danych. Proszę nie wyjmować karty pamięci (PS2), nie resetować ani nie wyłączać konsoli.
-
-[FEDL_WR]
-Trwa usuwanie danych. Proszę nie wyjmować karty pamięci (PS2) z gniazda KART PAMIĘCI nr 1, nie resetować ani nie wyłączać konsoli.
-
-[LM2_C]
-Luigi kazał ci to przekazać, więc...
-
-[LM3_G]
-Joey nie lubi czekać. Pamiętaj, to może być twoja szansa na karierę...
-
-[LM5_E]
-Zawieź tam jak najwięcej dziewczyn, zanim gliniarze przepiją wszystkie pieniądze!
-
-[JM5_C]
-Jest taka kwestia: przy kawiarni w Callahan Point stoi samochód z truposzem w środku.
-
-[RM2_B]
-Powąchaliśmy razem prochu w Nikaragui, kiedy w tym kraju jeszcze rządzili ludzie, którzy wiedzieli, o co chodzi.
-
-[RM2_C]
-Wczoraj groziły mu jakieś mendy z Kartelu. Powiedzieli, że wrócą i zabiorą mu towar.
-
-[RM2_D1]
-Poszedłbym sam, ale moje korzonki znowu się odzywają - więc, ee... Powodzenia!
-
-[CATINF1]
-~g~Dorwij Catalinę!
-
-[CATINF2]
-~g~Śledź helikopter, aby odszukać Catalinę.
-
-[BOATIN1]
-Wskakuj do łodzi i wciśnij klawisz ~h~~k~~VEHICLE_ENTER_EXIT~ button ~w~, aby zająć miejsce.
-
-[BOATIN2]
-Jeżeli jesteś w pobliżu łodzi, możesz wcisnąć klawisz ~h~~k~~VEHICLE_ENTER_EXIT~~w~, aby zająć w niej miejsce.
-
-[BOATIN3]
-Wskakuj do łodzi i wciśnij klawisz ~h~~k~~VEHICLE_ENTER_EXIT~ button ~w~, aby zająć miejsce.
-
-[BOATIN4]
-Jeżeli jesteś w pobliżu łodzi, możesz wcisnąć klawisz ~h~~k~~VEHICLE_ENTER_EXIT~~w~, aby zająć w niej miejsce.
-
-[JM6]
-'UCIECZKA'
-
-[FM1]
-'NIAŃKA'
-
-[JM1]
-'OSTATNI OBIAD MIKE'A BUŹKI'
-
-[FM21]
-'CIOS W SERCE: AKT I'
-
-[FM3]
-'CIOS W SERCE: AKT II'
-
-[AM1]
-'SAYONARA SALVATORE'
-
-[AM2]
-'POD OBSERWACJĄ'
-
-[KM2]
-'GRAND THEFT AUTO'
-
-[AS3]
-'WYRZUTNIA ZIEMIA-POWIETRZE'
-
-[RM2]
-'TOWARZYSZE BRONI'
-
-[LOVE6]
-'ZMYŁKA'
-
-[LOVE1]
-'WYZWOLICIEL'
-
-[RC1]
-'DIABELSKA DEMOLKA'
-
-[RC2]
-'MAFIJNA MASAKRA'
-
-[RC3]
-'KRWAWE KASYNO'
-
-[RC4]
-'RUMPO-ROZRÓBA'
-
-[RM2_E1]
-Nie mogę uwierzyć, że te żółte pokraki znowu zostawiły mnie bez ochrony.
-
-[GREN_1]
-Im dłużej przytrzymasz klawisz ~h~~k~~PED_FIREWEAPON~~w~, tym dalej rzucisz granatem.
-
-[GREN_2]
-Im dłużej przytrzymasz klawisz ~h~~k~~PED_FIREWEAPON~~w~, tym dalej rzucisz granatem.
-
-[GREN_3]
-Im dłużej przytrzymasz klawisz ~h~~k~~PED_FIREWEAPON~~w~, tym dalej rzucisz granatem.
-
-[LOVE4_G]
-Rzecz, która do mnie należy, będzie czekać na ciebie w hangarze celnym przy kadłubie samolotu.
-
-[KABOOM]
-BUM!
-
-[SPLAT]
-PLASK!
-
-[PANCAK]
-UPIECZONY!
-
-[SOAKED]
-DO SUCHEJ NITKI!
-
-[HEAD]
-Head Radio
-
-[DBL_CLF]
-Double Clef FM
-
-[FLASHB]
-Flashback FM
-
-[RISE]
-Rise FM
-
-[LIPS]
-Lips 106
-
-[CHAT]
-Gaduła FM
-
-[K_JAH]
-Radio K-Jah
-
-[GAM_FM]
-Game Radio FM
-
-[MSX_FM]
-MSX FM
-
-[TUBE1]
-Kiedy metro zostanie otwarte, będziesz mógł przejechać pociągiem na Wyspę Staunton.
-
-[TUBE2]
-Kiedy Shoreside Vale zostanie otwarte, będziesz mógł dotrzeć do stacji końcowej Shoreside Terminal i na Lotnisko Międzynarodowe im. Francisa.
-
-[TUBE_2]
-Aby wsiąść do metra, naciśnij klawisz ~h~'wsiadania do pojazdu'~w~.
-
-[LEGAL]
-~g~Wyeliminuj element przestępczy!
-
-[GA_2]
-Nowy silnik i lakier. Masz spokój z gliniarzami!
-
-[LM1_8A]
-Jeżeli chcesz trochę sobie dorobić, możesz spróbować 'pożyczyć' taksówkę...
-
-[TAXIH1]
-Zatrzymaj się w pobliżu podświetlonego przechodnia i pozwól mu wsiąść, a potem zawieź go pod wskazany adres przed upływem wyznaczonego czasu.
-
-[LM5_7]
-~g~Jeżeli na ~p~Balu Policjanta~g~ pojawią się mniej niż cztery dziewczyny, Luigi będzie niezadowolony!
-
-[KM2_3]
-~g~Pamiętaj, ~r~samochody~g~ muszą być w idealnym stanie albo nie zostaną przyjęte w ~p~warsztacie~g~.
-
-[KM5_2]
-~g~Yardies zniknęli z ulic.
-
-[BETRA_A]
-Przykro mi, kotku.
-
-[BETRA_B]
-Jestem ambitną dziewczyną,
-
-[BETRA_C]
-a ty jesteś tylko małą płotką.
-
-[JAILB_C]
-*
-
-[JAILB_D]
-*
-
-[JAILB_E]
-*
-
-[JAILB_F]
-*
-
-[JAILB_G]
-*
-
-[JAILB_H]
-*
-
-[JAILB_I]
-*
-
-[JAILB_J]
-*
-
-[JAILB_P]
-*
-
-[JAILB_Q]
-Jazda!
-
-[JAILB_R]
-Panie frajerze!
-
-[JAILB_S]
-Zabiję cię bez najmniejszego problemu.
-
-[JAILB_T]
-Pożałujesz tego.
-
-[JAILB_U]
-Dobrze, dobrze! Znikaj stąd.
-
-[HELP15]
-Jeżeli jesteś poza pojazdem i chcesz ~h~spojrzeć za siebie~w~, naciśnij klawisz ~h~~k~~PED_LOOKBEHIND~~w~.
-
-[FEC_LB3]
-Spójrz do tyłu
-
-[FEC_R3]
-(klawisz R3)
-
-[FES_AFO]
-Ta karta pamięci (PS2) jest już sformatowana.
-
-[FEA_UP]
-;
-
-[FEA_DO]
-=
-
-[FEA_LE]
-<
-
-[FEA_RI]
->
-
-[FEDSAS3]
-- ZMIANA WYBORU
-
-[FEDSAS4]
-;=<> - ZMIANA WYBORU
-
-[SPRAY_4] { re3 change }
-Użyj klawisza ~h~~k~~VEHICLE_FIREWEAPON~~w~, aby strzelać z armatki wodnej.
-
-[SPRAY_1] { re3 change }
-Użyj klawisza ~h~~k~~VEHICLE_FIREWEAPON~~w~, aby strzelać z armatki wodnej.
-
-[LITTLE]
-MAŁY T
-
-[NICK]
-NICK LOVE
-
-[AM1_10]
-~g~Salvatore opuści knajpę 'U Luigiego' około 0~1~:~1~
-
-[JAILB_V]
-*
-
-[JAILB_A]
-*
-
-[JAILB_B]
-*
-
-[JAILB_W]
-*
-
-[JAILB_K]
-*
-
-[JAILB_L]
-*
-
-[JAILB_M]
-*
-
-[JAILB_N]
-*
-
-[JAILB_O]
-*
-
-[JAILB_X]
-*
-
-[FEDS_SE]
-klawisz / - WYBIERZ
-
-[FEDS_SB]
-klawisz / - WYBIERZ klawisz ' - WSTECZ
-
-[TM4_A]
-~w~Ach, to ty. TONIEGO nie ma.
-
-[TM4_A2]
-~w~Ale zostawił na stole jeden ze swoich słodziutkich listów miłosnych do ciebie.
-
-[DIAB2_A]
-Kiedy zaczynałem robić interesy w branży rozrywek egzotycznych, nie miałem nic oprócz pokaźnej zawartości mojego rozporka!
-
-[LM5_9]
-DZIEWCZYNY:
-
-[PERPIC]
-Znalezione ukryte paczki
-
-[CO_ONE]
-Ukryta Paczka ~1~ z ~1~
-
-[LOVE3_3]
-~g~Samolot zrzucił ~1~ z 6 pakunków.
-
-[FARE11]
-~g~Cel podróży ~w~'Teren budowy'~g~ w Fort Staunton.
-
-[GA_21]
-W tym garażu nie możesz przechowywać więcej samochodów.
-
-[CHEAT1]
-Ułatwienie uaktywnione
-
-[CHEAT2]
-Ułatwienie - broń
-
-[CHEAT3]
-Ułatwienie - życie
-
-[CHEAT4]
-Ułatwienie - pancerz
-
-[CHEAT5]
-Ułatwienie - poziom wanted
-
-[CHEAT6]
-Ułatwienie - pieniądze
-
-[CHEAT7]
-Ułatwienie - pogoda
-
-[AS1_H]
-~w~Nie udało ci się wprowadzić Szwadronu Śmierci w pułapkę Yakuzy!!
-
-[FEDS_BA]
-klawisz ' - WSTECZ
-
-[RAMP_A]
-WSZYSTKIE ROZWAŁKI ZALICZONE!
-
-[USJ_ALL]
-WSZYSTKIE NIETYPOWE SKOKI WYKONANE!
-
-[FARE23]
-~g~Cel podróży ~w~'warsztat importowo-eksportowy'~g~ w okolicach Tamy Cochrane.
-
-[L_TRN_1]
-Po Portland możesz się też poruszać kolejką. Naciśnij klawisz ~h~ ~k~~VEHICLE_ENTER_EXIT~~w~, aby ~h~wsiąść ~w~lub ~h~wysiąść~w~ z pociągu.
-
-[L_TRN_2]
-Po Portland możesz się też poruszać kolejką. Naciśnij klawisz ~h~ ~k~~VEHICLE_ENTER_EXIT~~w~, aby ~h~wsiąść ~w~lub ~h~wysiąść~w~ z pociągu.
-
-[S_TRN_1]
-Przez Liberty możesz także podróżować metrem. Naciśnij klawisz~h~ ~k~~VEHICLE_ENTER_EXIT~~w~, aby ~h~wsiąść ~w~lub ~h~wysiąść~w~ z pociągu.
-
-[S_TRN_2]
-Przez Liberty możesz także podróżować metrem. Naciśnij klawisz~h~ ~k~~VEHICLE_ENTER_EXIT~~w~, aby ~h~wsiąść ~w~lub ~h~wysiąść~w~ z pociągu.
-
-[AS1_C]
-~w~Rozmieściła w całym Liberty trzy szwadrony śmierci, których zadaniem jest wytropić twój tyłek.
-
-[AS1_G]
-~w~Wszyscy członkowie Yakuzy nie żyją!!
-
-[JAN]
-stycz.
-
-[FEB]
-luty
-
-[MAR]
-marzec
-
-[APR]
-kwiec.
-
-[MAY]
-maj
-
-[JUN]
-czerw.
-
-[JUL]
-lip.
-
-[AUG]
-sierp.
-
-[SEP]
-wrz.
-
-[OCT]
-paźdz.
-
-[NOV]
-listop.
-
-[DEC]
-grudz.
-
-[DEFDT]
---:---:---- --:--:--
-
-[BUGGY]
-POZOSTAŁE GARBUSKI:
-
-[BONUS]
-~g~PREMIA $~1~v
-
-[HORN1]
-Naciśnij ~h~klawisz L3 ~w~, aby użyć ~h~klaksonu.
-
-[HORN2]
-Naciśnij ~h~klawisz L1 ~w~, aby użyć ~h~klaksonu.
-
-[HORN3]
-Naciśnij ~h~klawisz R1 ~w~, aby użyć ~h~klaksonu.
-
-[LM3_1A]
-Naciśnij klawisz~h~ ~k~~VEHICLE_HORN~~w~, aby użyć ~h~klaksonu~w~ i zaprosić Misty do środka.
-
-[LM3_1B]
-Naciśnij klawisz~h~ ~k~~VEHICLE_HORN~~w~, aby użyć ~h~klaksonu~w~ i zaprosić Misty do środka.
-
-[LM3_1C]
-Naciśnij klawisz~h~ ~k~~VEHICLE_HORN~~w~, aby użyć ~h~klaksonu~w~ i zaprosić Misty do środka.
-
-[RADIO_A]
-Naciśnij klawisz ~h~~k~~VEHICLE_CHANGE_RADIO_STATION~~w~, aby przełączać ~h~stacje radiowe.
-
-[RADIO_B]
-Naciśnij klawisz ~h~~k~~VEHICLE_CHANGE_RADIO_STATION~~w~, aby przełączać ~h~stacje radiowe.
-
-[RADIO_C]
-Naciśnij klawisz ~h~~k~~VEHICLE_CHANGE_RADIO_STATION~~w~, aby przełączać ~h~stacje radiowe.v
-
-[RADIO_D]
-Naciśnij klawisz ~h~~k~~VEHICLE_CHANGE_RADIO_STATION~~w~, aby przełączać ~h~stacje radiowe.
-
-[FEC_EXV]
-Wsiadanie i wysiadanie z pojazdu
-
-[TAXI_M]
-'TAKSÓWKARZ'
-
-[COP_M]
-'PATROL'
-
-[FIRE_M]
-'STRAŻAK'
-
-[AMBUL_M]
-'SANITARIUSZ'
-
-[HJ_IS]
-PREMIA ZA SZALONY SKOK: $~1~
-
-[HJ_PIS]
-PREMIA ZA BEZBŁĘDNY SZALONY SKOK: $~1~
-
-[HJ_DIS]
-PREMIA ZA PODWÓJNY SZALONY SKOK: $~1~
-
-[HJ_PDIS]
-PREMIA ZA BEZBŁĘDNY PODWÓJNY SZALONY SKOK: $~1~
-
-[HJ_TIS]
-PREMIA ZA POTRÓJNY SZALONY SKOK: $~1~
-
-[HJ_PTIS]
-PREMIA ZA BEZBŁĘDNY POTRÓJNY SZALONY SKOK: $~1~
-
-[HJ_QIS]
-PREMIA ZA POCZWÓRNY SZALONY SKOK: $~1~
-
-[HJ_PQIS]
-PREMIA ZA BEZBŁĘDNY POCZWÓRNY SZALONY SKOK: $~1~
-
-[AM1_K]
-Za około trzy godziny (0~1~:~1~), Salvatore Leone będzie wychodził z klubu 'U Luigiego'.
-
-[IMPEXPP]
-Warsztat import-eksport w Portland Harbor. Mamy zamówienia na różne pojazdy. Listę aktualnie skupowanych wozów znajdziesz na naszej tablicy ogłoszeniowej.
-
-[VANHSTP]
-Chcesz rozbić konwojowóz? Przywieź go do naszego warsztatu w Portland Harbor!
-
-[EMVHPUP]
-Doskonałe ceny za nowe i używane pojazdy służb miejskich! Skup odbywa się przy dźwigu na północny wschód od Portland Harbor.
-
-[STANDS]
-ROZBITE BUDKI:
-
-[STASH]
-~g~Odwieź PROCHY z powrotem na ~p~teren budowy!
-
-[MCSTNS]
-W gnieździe KART PAMIĘCI nr 1 nie ma karty pamięci (PS2). Czy chcesz kontynuować? (TAK lub NIE)
-
-[LOVE3_5]
-~g~Samolot jest w zasięgu.
-
-[LOVE3_6]
-~r~Policja dotarła do pakunków przed tobą!
-
-[SIREN_1]
-Aby włączyc syrenę pojazdu, naciśnij klawisz ~h~~k~~VEHICLE_HORN~ ~w~.
-
-[SIREN_2]
-Aby włączyc syrenę pojazdu, naciśnij klawisz ~h~~k~~VEHICLE_HORN~ ~w~.
-
-[FM3_8C]
-~w~Potrzebuję jakieś 100 000 dolarów na niezbędne wydatki,
-
-[MCLOAD]
-Trwa wczytywanie danych. Proszę nie wyjmować karty pamięci (PS2) z gniazda KART PAMIĘCI nr 1, nie resetować ani nie wyłączać konsoli.
-
-[FES_GME]
-Błąd odczytu danych z karty pamięci (PS2) w gnieździe KART PAMIĘCI nr 1. Sprawdź kartę i ponów próbę.
-
-[FESZ_QF]
-Czy na pewno chcesz sformatować kartę pamięci (PS2) w gnieździe KART PAMIĘCI nr 1?
-
-[FESZ_LS]
-Pomyślne wczytywanie
-
-[RM3_5]
-~g~Masz już ~1~ z 6 pakietów dowodów.
-
-[LOVE3_2]
-~g~Masz już wszystkie pakunki! Zawieź je do Donalda Love'a.
-
-[LOVE4_4]
-~g~Zabierz pakunek do Donalda Love'a!
-
-[FEB_SAV]
-Wczytanie
-
-[FEP_SAV]
-WCZYTAJ GRĘ
-
-[AS2_12A]
-~g~Od momentu rozwalenia pierwszej budki będziesz miał 8 minut, zanim Kartel ostrzeże swoich dilerów!
-
-[AS3_1A]
-~g~Teraz płyń do ~b~boi !
-
-[NOCONT]
-Aby kontynuować, proszę ponownie podłączyć kontroler analogowy (DUALSHOCK@) lub kontroler analogowy (DUALSHOCK@2) do portu kontrolerów gry nr 1.
-
-[BET_JB]
-CATALINA, JEGO KOCHANKA, ZDRADZIŁA GO I POZOSTAWIŁA NA PEWNĄ ŚMIERĆ. TERAZ, OSĄDZONY I SKAZANY, ROZPOCZYNA PODRÓŻ DO ZAKŁADU KARNEGO W LIBERTY CITY. ALE W JEGO ZBRODNICZYM UMYŚLE PŁONIE TYLKO JEDNA MYŚL......ZEMSTA!
-
-[END_A]
-Mieszkańcy Cedar Grove nadal dochodzą do siebie
-
-[END_B]
-po gwałtownych wydarzeniach, jakie rozegrały się wczoraj
-
-[END_C]
-w tej dzielnicy, a przypominały regularną wojnę.
-
-[END_D]
-Pan Clive Denver, mieszkający w tej okolicy od lat, opisał wczoraj policji
-
-[END_E]
-samotnego strzelca, który uciekał z miejsca przestępstwa z ciemnowłosą kobietą.
-
-[END_F]
-Och, będziemy się razem świetnie bawić! Bo... no, wiesz...
-
-[END_G]
-Ja cię kocham, naprawdę... Bo jesteś taki silny i w ogóle...
-
-[END_H]
-A właśnie kogoś takiego szukałam.
-
-[END_I]
-Ale... o czym to ja mówiłam?
-
-[END_J]
-Wyleciało mi z głowy! Ale wiesz, o co mi chodzi, prawda?
-
-[END_K]
-Odgłosy eksplozji wstrząsały okolicznymi budynkami, z których wybiegali przerażeni ludzie.
-
-[END_L]
-Kilkunastu obywateli doznało obrażań w wyniku wymiany ognia
-
-[END_M]
-między bandytami na ziemi a helikopterem krążącym nad tamą.
-
-[END_N]
-Tak, tutaj - z ogrodu - miałem na wszystko doskonały widok.
-
-[END_O]
-Kiedy helikopter w końcu został trafiony,
-
-[END_P]
-wyglądało to lepiej niż fajerwerki na Wielkanoc!
-
-[END_Q]
-Liczba zabitych przekroczyła już dwadzieścia osób,
-
-[END_R]
-ale policja ciągle odnajduje nowe ciała.
-
-[END_S]
-Jak dotąd nie wydano żadnego oficjalnego komunikatu, który zaprzeczyłby pogłoskom,
-
-[END_T]
-że ofiary to członkowie Kartelu Kolumbijskiego.
-
-[END_U]
-Nadal nie ma też żadnych informacji na temat przyczyn tej masakry.
-
-[END_V]
-Złamałam paznokieć i zrujnowałam sobie całą fryzurę. To skandal!
-
-[END_W]
-Kosztowała mnie pięćdziesiąt dolców...
-
-[PAPER1]
-*
-
-[PAPER2]
-*
-
-[PAPER3]
-*
-
-[FEB_CPC]
-Konfiguracja klawiszy sterujących
-
-[FEC_PED]
-Sterowanie postacią poza pojazdem
-
-[FEC_VEH]
-Klawisze sterujące pojazdem
-
-[FEC_FPR]
-Sterowanie dla trybu widoku z oczu postaci
-
-[FEC_CMM]
-Standardowe sterowanie
-
-[FEC_PWL]
-IDŹ w lewo
-
-[FEC_PWR]
-Idź w prawo
-
-[FEC_PWF]
-Idź do przodu
-
-[FEC_PWT]
-Idź w stronę kamery
-
-[FEC_PLB]
-Spójrz za siebie
-
-[FEC_PFR]
-Strzał z broni
-
-[FEC_CLE]
-Przełącz rodzaj broni w lewo
-
-[FEC_CRI]
-Przełącz rodzaj broni w prawo
-
-[FEC_LKT]
-Zablokuj cel
-
-[FEC_PJP]
-Skok
-
-[FEC_PSP]
-Szybki bieg
-
-[FEC_PSH]
-Strzał
-
-[FEC_TLF]
-Następny cel w lewo
-
-[FEC_TRG]
-Następny cel w prawo
-
-[FEC_CCM]
-Wyśrodkuj kamerę za graczem
-
-[FEC_SZI]
-Karabin snajperski - przybliżenie
-
-[FEC_SZO]
-Karabin snajperski - oddalenie
-
-[FEC_LKL]
-Spójrz w lewo w trybie widoku z oczu postaci
-
-[FEC_LRT]
-Spójrz w prawo w trybie widoku z oczu postaci
-
-[FEC_LUP]
-Spójrz w górę w trybie widoku z oczu postaci
-
-[FEC_LDN]
-Spójrz w dół w trybie widoku z oczu postaci
-
-[FEC_LBH]
-Spójrz przez tylną szybę
-
-[FEC_LLF]
-Spójrz przez lewą szybę
-
-[FEC_LRG]
-Spójrz przez prawą szybę
-
-[FEC_HRN]
-Klakson
-
-[FEC_HBR]
-Hamulec ręczny pojazdu
-
-[FEC_ACL]
-Przyspieszenie pojazdu
-
-[FEC_BRK]
-Hamulec pojazdu
-
-[FEC_TSM]
-Włącz podmisje
-
-[FEC_CRD]
-Zmiana stacji radiowej
-
-[FEC_ENT]
-Wsiadanie do pojazdu/wysiadanie z pojazdu
-
-[FEC_WPN]
-Strzał z broni
-
-[FEC_PAS]
-Pauza
-
-[FEC_FPO]
-Broń w trybie widoku z oczu postaci
-
-[FEC_SMS]
-Pokazuj kursor myszy
-
-[FEC_CMS]
-Zmiana trybu kamery dla wszystkich sytuacji.
-
-[FEC_TSS]
-Zapisz wygląd ekranu
-
-[FEN_NET]
-Sieć
-
-[FEN_CON]
-Połączenie
-
-[FEN_GAM]
-Szukaj sesji gry
-
-[FEN_TYP]
-Rodzaj gry
-
-[FEN_TY0]
-Tryb Deathmatch
-
-[FEN_TY1]
-Tryb Niewidzialny Deathmatch
-
-[FEN_TY2]
-Zespołowy tryb Deathmatch
-
-[FEN_TY3]
-Zespołowy tryb Niewidzialny Deathmatch
-
-[FEN_TY4]
-Gromadź szmal
-
-[FEN_TY5]
-Zdobądź flagę
-
-[FEN_TY6]
-Wyścig szczurów
-
-[FEN_TY7]
-Dominacja
-
-[FEN_NAM]
-Nazwa:
-
-[FEN_GNA]
-Nazwa gry:
-
-[FEM_MAP]
-Wybierz mapę
-
-[FEN_PLS]
-Ustawienia gracza
-
-[FEN_PLC]
-Kolor gracza
-
-[FEM_MA0]
-Liberty City
-
-[FEM_MA1]
-Dz. Czerwonych Świateł
-
-[FEM_MA2]
-Chinatown
-
-[FEM_MA3]
-Wieża
-
-[FEM_MA4]
-Kanały
-
-[FEM_MA5]
-Park Przemysłowy
-
-[FEM_MA6]
-Doki
-
-[FEM_MA7]
-Staunton
-
-[FEC_EMS]
-Tylko klawisze z klawiatur niestandardowych
-
-[FEC_DBG]
-MENU DEBUGOWANIA
-
-[FEC_TGD]
-Przełącznik gra/debugowanie
-
-[FEC_TDO]
-Wyłącz kamerę trybu debugowania
-
-[FEC_IVH]
-Odwróć osie myszy w poziomie:
-
-[FEC_MSL]
-Lewy przycisk myszy
-
-[FEC_MSM]
-Śr. przycisk myszy
-
-[FEC_MSR]
-Prawy przycisk myszy
-
-[FEC_QUE]
-???
-
-[FEC_TWO]
-Dozwolone są tylko dwa klawisze z klawiatury
-
-[FEC_UMS]
-Tylko przyciski myszy niestandardowych
-
-[FEC_OMS]
-Dozwolony jest tylko jeden przycisk myszy
-
-[FEC_UJS]
-Tylko przyciski joysticków niestandardowych
-
-[FEC_OJS]
-Dozwolony jest tylko jeden przycisk joysticka na daną czynność .
-
-[FEC_PTL]
-Użyj blokowania celu oraz przełączenia broni w lewo
-
-[FEC_PTR]
-Użyj blokowania celu oraz przełączenia broni w prawo
-
-[FEC_LBC]
-Użyj klawiszy 'spójrz w lewo' oraz 'spójrz w prawo'
-
-[FEC_JBO]
-JOY ~1~
-
-[NO_PAUZ]
-Nie można zatrzymać gry w trybie wieloosobowym. Dwukrotnie naciśnij klawisz, aby wyjść z gry!
-
-[FEM_SL1]
-Gniazdo 1 jest wolne
-
-[FEM_SL2]
-Gniazdo 2 jest wolne
-
-[FEM_SL3]
-Gniazdo 3 jest wolne
-
-[FEM_SL4]
-Gniazdo 4 jest wolne
-
-[FEM_SL5]
-Gniazdo 5 jest wolne
-
-[FEM_SL6]
-Gniazdo 6 jest wolne
-
-[FEM_SL7]
-Gniazdo 7 jest wolne
-
-[FEM_SL8]
-Gniazdo 8 jest wolne
-
-[FEM_MM]
-MENU GŁÓWNE
-
-[FEQ_SRE]
-Czy na pewno chcesz wyjść z gry? Efekty wszystkich działań podjętych od czasu ostatniego zapisu gry zostaną utracone. Kontynuować?
-
-[FEQ_SRW]
-Czy na pewno chcesz wyjść z gry?
-
-[FEG_SRV]
-SERWER
-
-[FEG_MAP]
-MAPA
-
-[FEG_PLY]
-GRACZE
-
-[FEG_TYP]
-RODZAJ
-
-[FEG_PNG]
-PING
-
-[FET_FG]
-ODSZUKAJ SESJĘ GRY
-
-[FET_SP]
-TRYB DLA JEDNEGO GRACZA
-
-[FET_MP]
-TRYB WIELOOSOBOWY
-
-[FET_HG]
-HOSTUJ GRĘ
-
-[FET_PS]
-KONFIGURACJA GRACZA
-
-[FET_CON]
-POŁĄCZENIE
-
-[FET_AUD]
-KONFIGURACJA DŻWIĘKU
-
-[FET_DIS]
-KONFIGURACJA EKRANU
-
-[FET_LAN]
-OKREŚL JĘZYK
-
-[FET_LG]
-WCZYTAJ GRĘ
-
-[FET_DG]
-USUŃ GRĘ
-
-[FET_NG]
-NOWA GRA
-
-[FET_SG]
-ZAPISZ GRĘ
-
-[FET_MAP]
-WYBIERZ MAPĘ
-
-[FET_GT]
-RODZAJ GRY
-
-[FET_CTL]
-KONFIGURACJA STEROWANIA
-
-[FET_OPT]
-OPCJE
-
-[FET_QG]
-WYJDŹ Z GRY
-
-[FET_STA]
-STATYSTYKI
-
-[FET_BRE]
-CELE
-
-[FEC_WAR]
-Ostrzeżenie
-
-[FEC_OKK]
-OK
-
-[FED_CON]
-Potwierdzenie usunięcia pliku
-
-[FES_SSC]
-Gra została pomyślnie zapisana.
-
-[DEL_FNM]
-Plik został pomyślnie usunięty.
-
-[PCLOAD]
-Wczytywanie danych z pliku
-
-[PCRESRT]
-Trwa uruchamianie Grand Theft Auto III
-
-[FEC_DLF]
-Kasowanie nieudane.
-
-[FEC_SVU]
-Zapis nieudany.
-
-[FEC_LUN]
-Wczytywanie nieudane. Plik uszkodzony. Proszę go usunąć.
-
-[FEN_PLA]
-Liczba graczy:
-
-[FET_NON]
-BRAK DOSTĘPNYCH GIER
-
-[FET_SFG]
-WYSZUKIWANIE SESJI GRY...
-
-[FET_SRT]
-SORTOWANIE SESJI GRY...
-
-[FEF_LAN]
-LAN
-
-[FEF_INT]
-INTERNET
-
-[FET_REF]
-Odśwież
-
-[FET_FIL]
-Filtr
-
-[FET_JG]
-Dołącz
-
-[FEC_NTW]
-Rozmowa przez sieć
-
-[FEC_ESR]
-Klawisz ESC jest zastrzeżony
-
-[FEC_GSL]
-Pokazuj wstrząsy głowy:
-
-[FIL_FLT]
-FILTR LISTY SESJI GRY
-
-[FET_SAN]
-ROZPOCZNIJ NOWĄ GRĘ
-
-[FIL_MAP]
-Mapa:
-
-[FIL_SRV]
-Serwer:
-
-[FIL_TYP]
-Rodzaj gry:
-
-[FIL_SPC]
-Gry z wolnym miejscem?
-
-[FIL_PNG]
-Ping:
-
-[FEN_UKH]
-Nieznany host
-
-[FEN_UKM]
-Nie odnaleziono mapy
-
-[FEN_UKT]
-Nie odnaleziono danego rodzaju gry
-
-[FEN_NCI]
-BRAK POŁĄCZENIA Z INTERNETEM
-
-[FET_PAU]
-MENU PAUZY
-
-[FET_SGA]
-ROZPOCZNIJ GRĘ
-
-[FEC_SGJ]
-Ustaw joystick do gry
-
-[FEC_PAD]
-Gamepad
-
-[FEC_JOY]
-Joystick
-
-[FEC_WHL]
-Kierownica
-
-[FEC_CNT]
-Typ sterownika:
-
-[FES_CSA]
-Wybierz 'skórę' z poniższej listy:
-
-[FES_SKN]
-NAZWA SKÓRY
-
-[FES_DAT]
-DATA
-
-[FES_NON]
-BRAK DOSTĘPNYCH 'SKÓR'
-
-[FEA_FM9]
-ODTWARZACZ MP3
-
-[FESZ_QZ]
-Czy jesteś pewien, że chcesz zapisać grę?
-
-[FES_CGA]
-Dostępne gniazda gry:
-
-[FES_SCG]
-Zapisać bieżącą grę?
-
-[FES_LCG]
-Wczytać grę i kontynuować rozgrywkę?
-
-[FEC_FIR]
-Strzał
-
-[FEC_NWE]
-Następna broń
-
-[FEC_PWE]
-Poprzednia broń
-
-[FEC_FOR]
-Do przodu
-
-[FEC_BAC]
-Do tyłu
-
-[FEC_LEF]
-W lewo
-
-[FEC_RIG]
-W prawo
-
-[FEC_ZIN]
-Przybliżenie
-
-[FEC_ZOT]
-Oddalenie
-
-[FEC_EEX]
-Wejście/wyjście
-
-[FEC_RAD]
-Radio
-
-[FEC_SUB]
-Podmisja
-
-[FEC_CMR]
-Zmiana kamery
-
-[FEC_JMP]
-Skok
-
-[FEC_SPN]
-Sprint
-
-[FEC_HND]
-Hamulec ręczny
-
-[FEC_TUL]
-Wieżyczka w lewo
-
-[FEC_TUR]
-Wieżyczka w prawo
-
-[FEC_LOL]
-Spójrz w lewo
-
-[FEC_LOR]
-Spójrz w prawo
-
-[FEC_NTR]
-Następny cel
-
-[FEC_PTT]
-Poprzedni cel
-
-[FEC_LBA]
-Spójrz do tyłu
-
-[FEC_CEN]
-Wyśrodkuj kamerę
-
-[FEC_UND]
-(NIE)
-
-[FET_CFT]
-PIESZO
-
-[FET_CCR]
-W AUCIE
-
-[CVT_MSG]
-Trwa konwersja tekstur do formatu optymalnego dla zainstalowanej karty graficznej.
-
-[FET_CAC]
-CZYNNOŚĆ
-
-[FEC_IBT]
--
-
-[FEC_SPC]
-SPACJA
-
-[FEC_MXO]
-MXB1
-
-[FEC_MXT]
-MXB2
-
-[FEC_UNB]
-UNBOUND
-
-[FET_CME]
-SPOSÓB STEROWANIA
-
-[FET_RDK]
-ZMIANA KLAWISZY STERUJĄCYCH
-
-[FET_AMS]
-USTAWIENIA MYSZY
-
-[FET_STI]
-ZWYKŁA KONFIGURACJA STEROWANIA
-
-[FET_CTI]
-STANDARDOWA KONFIGURACJA STEROWANIA
-
-[FET_MTI]
-KONFIGURACJA STEROWANIA MYSZĄ
-
-[FET_DAM]
-DYNAMICZNE MODELOWANIE AKUSTYCZNE
-
-[FEC_TFL]
-Wieżyczka w lewo
-
-[FEC_TFR]
-Wieżyczka w prawo
-
-[FEC_MWF]
-KÓŁKO W GÓRĘ
-
-[FEC_MWB]
-KÓŁKO W DÓŁ
-
-[FEC_ORR]
-lub
-
-[FEC_NUS]
-NIEUŻYWANY
-
-[FEC_LUD]
-Spójrz w górę
-
-[FEC_LDU]
-Spójrz w dół
-
-[FEC_CMP]
-KOMBINACJA: SPÓJRZ W LEWO + SPÓJRZ W PRAWO
-
-[FEC_NTT]
-Brak tekstu dla tego klawisza
-
-[FEC_FNC]
-F~1~
-
-[FEC_IRT]
-INSERT
-
-[FEC_DLL]
-DELETE
-
-[FEC_HME]
-HOME
-
-[FEC_END]
-END
-
-[FEC_PGU]
-PAGE UP
-
-[FEC_PGD]
-PAGE DOWN
-
-[FEC_UPA]
-STRZAŁKA W GÓRĘ
-
-[FEC_DWA]
-STRZAŁKA W DÓŁ
-
-[FEC_LFA]
-W LEWO
-
-[FEC_RFA]
-STRZAŁKA W PRAWO
-
-[FEC_NUM]
-NUM
-
-[FEC_NMN]
-NUM~1~
-
-[FEC_FWS]
-NUM /
-
-[FEC_PLS]
-NUM +
-
-[FEC_MIN]
-NUM -
-
-[FEC_DOT]
-NUM .
-
-[FEC_NLK]
-NUM LOCK
-
-[FEC_ETR]
-ENTER
-
-[FEC_SLK]
-SCROLL LOCK
-
-[FEC_PSB]
-PAUSE BREAK
-
-[FEC_BSP]
-BACKSPACE
-
-[FEC_TAB]
-TAB
-
-[FEC_CLK]
-CAPS LOCK
-
-[FEC_RTN]
-RETURN
-
-[FEC_LSF]
-LEWY SHIFT
-
-[FEC_RSF]
-PRAWY SHIFT
-
-[FEC_LCT]
-LEWY CTRL
-
-[FEC_RCT]
-PRAWY CTRL
-
-[FEC_LAL]
-LEWY ALT
-
-[FEC_RAL]
-PRAWY ALT
-
-[FEC_LWD]
-LEWY KLAWISZ WINDOWS
-
-[FEC_RWD]
-PRAWY KLAWISZ WINDOWS
-
-[FEC_WRC]
-WINCLICK
-
-[WIN_TTL]
-Grand Theft Auto III
-
-[WIN_95]
-Gra Grand Theft Auto III nie pracuje pod systemem Windows 95.
-
-[WIN_DX]
-Gra Grand Theft Auto III wymaga bibliotek DirectX w wersji 8.1 lub nowszych.
-
-[WIN_VDM]
-Gra Grand Theft Auto III wymaga karty graficznej z przynajmniej 12 MB RAM.
-
-[DIAB3_G]
-Arriba!
-
-[FEM_RES]
-WZNÓW GRĘ
-
-[FES_SNG]
-ROZPOCZNIJ NOWĄ GRĘ
-
-[FEM_SP]
-TRYB DLA JEDNEGO GRACZA
-
-[FEM_MP]
-TRYB WIELOOSOBOWY
-
-[FEM_QT]
-WYJDŹ Z GRY
-
-[FES_SG]
-ROZPOCZNIJ NOWĄ GRĘ
-
-[FES_LG]
-WCZYTAJ GRĘ
-
-[FEM_HST]
-HOST GRY
-
-[FEM_OPT]
-OPCJE
-
-[FEM_DBG]
-DEBUGOWANIE
-
-[FET_PSU]
-KONFIGURACJA GRACZA
-
-[FET_DEF]
-PRZYWRÓĆ USTAWIENIA DOMYŚLNE
-
-[FED_BRI]
-JASNOŚĆ
-
-[FED_TRA]
-ŚLADY
-
-[FEM_LOD]
-ODLEGŁOŚC RYSOWANIA
-
-[FEM_VSC]
-SYNCHRONIZACJA KLATEK
-
-[FEM_FRM]
-OGRANICZENIE KLATEK
-
-[FED_RES]
-ROZDZIELCZOŚĆ EKRANU
-
-[FED_WIS]
-SZEROKI EKRAN
-
-[FEDS_TB]
-WSTECZ
-
-[FEA_MUS]
-GŁOŚNOŚĆ MUZYKI
-
-[FEA_SFX]
-GŁOŚNOŚĆ EFEKTÓW
-
-[FEA_RSS]
-STACJA RADIOWA
-
-[FEL_ENG]
-ANGIELSKI
-
-[FEL_FRE]
-FRANCUSKI
-
-[FEL_GER]
-NIEMIECKI
-
-[FEL_ITA]
-WŁOSKI
-
-[FEL_SPA]
-HISZPAŃSKI
-
-[FEA_3DH]
-SPRZĘT AUDIO
-
-[FEA_SPK]
-KONFIGURACJA GŁOŚNIKÓW
-
-[FEA_2SP]
-DWA GŁOŚNIKI
-
-[FEA_4SP]
-WIĘCEJ NIŻ DWA GŁOŚNIKI
-
-[FEA_EAR]
-SŁUCHAWKI
-
-[FEA_NAH]
-BRAK SPRZĘTU AUDIO
-
-[FET_SNG]
-ROZPOCZNIJ NOWĄ GRĘ
-
-[FEN_STA]
-ROZPOCZNIJ GRĘ
-
-[GMLOAD]
-WCZYTAJ GRĘ
-
-[GMSAVE]
-ZAPISZ GRĘ
-
-[FES_DGA]
-USUŃ GRĘ
-
-[FEM_NON]
-BRAK
-
-[FEC_IVV]
-ODWRÓĆ OSIE MYSZY W PIONIE
-
-[FEC_MSH]
-CZUŁOŚĆ MYSZY
-
-[FET_CCN]
-STEROWANIE: STANDARDOWE
-
-[FET_SCN]
-STEROWANIE: ZWYKŁE
-
-[FES_SET]
-UŻYJ 'SKÓRY'
-
-[GHOST]
-Ghost
-
-[WIN_RSZ]
-Zmiana rozmiaru ekranu nieudana.
-
-[FEC_TFU]
-Wież./dodo w górę
-
-[FEC_TFD]
-Wież./dodo w dół
-
-[FET_APL]
-ZASTOSUJ
-
-[FET_APP]
-KLIKNIJ LPM LUB RETURN, ABY ZASTOSOWAĆ NOWE USTAWIENIA
-
-[FET_HRD]
-PRZYWRÓCONO USTAWIENIA DOMYŚLNE
-
-[FET_MST]
-STEROWANIE POJAZDAMI ZA POMOCĄ MYSZY
-
-[FEC_STR]
-NUM *
-
-[FET_MIG]
-STRZAŁKA W LEWO, W PRAWO, KÓŁKO MYSZY, ABY REGULOWAĆ
-
-[FET_CIG]
-BACKSPACE: USUWANIE - LPM, RETURN - ZMIANA
-
-[FET_RIG]
-WYBIERZ NOWY KLAWISZ LUB NACIŚNIJ ESC, ABY ANULOWAĆ
-
-[FET_EIG]
-NIE MOŻNA PRZYPISAĆ KLAWISZA TEJ CZYNNOŚCI
-
-[NO_PCCD]
-Włóż do napędu CD-ROM płytę z grą Grand Theft Auto III nr 2 albo naciśnij ESC, aby anulować.
-
-[CVT_ERR]
-Na dysku twardym zabrakło wolnego miejsca. Przed dalszą pracą z programem zwolnij odpowiednią ilość pamięci. Aby wyjść, naciśnij ESC.
-
-[FED_SUB]
-NAPISY
-
-[FET_DSN]
-Skin gracza.bmp
-
-[JM3]
-'SKOK NA KONWÓJ'
-
-[ATUTOR2]
-~g~OSTROŻNIE przewoź pacjentów do Szpitala. Każde zderzenie zmniejsza ich szanse przeżycia.
-
-[EBAL]
-'WOLNOŚĆ W LIBERTY'
-
-[LM4]
-'ALFONS'
-
-[REPLAY]
-POWTÓRKA
-
-[FEC_SFT]
-SHIFT
-
-[CRED254]
-KIEROWNIK STUDIA
-
-[CVT_CRT]
-Nie można dokonać konwersji tekstur dla zainstalowanej karty graficznej. W tym celu należy zalogować się na konto Administratora. Aby wyjść, naciśnij ESC.
-
-[FEM_ON]
-WŁ.
-
-[FEM_OFF]
-WYŁ.
-
-[FEM_YES]
-TAK
-
-[FEM_NO]
-NIE
-
-[FES_WAR]
-Trwa zapisywanie, proszę czekać...
-
-[FED_DLW]
-Trwa kasowanie, proszę czekać...
-
-[FED_LDW]
-Trwa wczytywanie, proszę czekać...
-
-[FEC_SLC]
-Gniazdo jest uszkodzone
-
-[FED_LFL]
-Nieudane wczytanie zapisanej gry. Za chwilę gra uruchomi się ponownie.
-
-[FET_RSO]
-PRZYWRÓCONO PIERWOTNE USTAWIENIA
-
-[FET_RSC]
-URZĄDZENIE NIEDOSTĘPNE - PRZYWRÓCONO PIERWOTNE USTAWIENIA
-
-{ re3 updates }
-{ new languages }
-[FEL_JAP]
-JAPOŃSKI
-
-[FEL_POL]
-POLSKI
-
-[FEL_RUS]
-ROSYJSKI
-
-{ new display menus }
-[FET_GFX]
-USTAWIENIA GRAFIKI
-
-[FED_MIP]
-MIPMAPPING
-
-[FED_AAS]
-WYGŁADZANIE KRAWĘDZI
-
-[FED_FIL]
-FILTROWANIE TEKSTUR
-
-[FED_BIL]
-DWULINIOWE
-
-[FED_TRL]
-TRÓJLINIOWE
-
-[FED_WND]
-OKIENKOWY
-
-[FED_FLS]
-PEŁNY EKRAN
-
-[FEM_CSB]
-RAMKI CUTSCENEK
-
-[FEM_SCF]
-FORMAT OBRAZU
-
-[FEM_ISL]
-PRZYPISZ WYKORZYSTANIE PAMIĘCI
-
-[FEM_LOW]
-NISKIE
-
-[FEM_MED]
-ŚREDNIE
-
-[FEM_HIG]
-WYSOKIE
-
-[FEM_2PR]
-ALFA TEST PS2
-
-[FEC_FRC]
-SWOBODNA KAMERA
-
-{ Linux joy detection }
-[FEC_JOD]
-WYKRYJ PADA
-
-[FEC_JPR]
-Naciśnij dowolny klawisz na padzie, którego chcesz użyć w grze.
-
-[FEC_JDE]
-Wykryto pada
-
-{ mission restart }
-[FET_RMS]
-PONÓW MISJĘ
-
-[FESZ_RM]
-PONOWIĆ?
-
-{ more graphics }
-[FED_VPL]
-POTOK POJAZDÓW
-
-[FED_PRM]
-PODŚWIETLENIE PED
-
-[FED_RGL]
-POŁYSK DROGI
-
-[FED_CLF]
-FILTR KOLORU
-
-[FED_WLM]
-LIGHTMAPY ŚWIATA
-
-[FED_MBL]
-ROZMYCIE RUCHU
-
-[FEM_SIM]
-PROSTE
-
-[FEM_NRM]
-NORMALNY
-
-[FEM_MOB]
-MOBILNY
-
-[FED_MFX]
-MATFX
-
-[FED_NEO]
-PODŚWIETLENIE
-
-[FEM_PS2]
-PS2
-
-[FEM_XBX]
-XBOX
-
-[FEM_AUT] { aspect ratio related }
-AUTO
-
-[FEC_IVP]
-ODWRÓĆ OŚ PADA W PIONIE
-
-{ map }
-[FEM_TWP]
-Toggle Waypoint
-
-[FEA_FMN]
-RADIO OFF
-
-[FEC_DS2]
-DUALSHOCK 2
-
-[FEC_DS3]
-DUALSHOCK 3
-
-[FEC_DS4]
-DUALSHOCK 4
-
-[FEC_360]
-XBOX 360 CONTROLLER
-
-[FEC_ONE]
-XBOX ONE CONTROLLER
-
-[FEC_TYP]
-GAMEPAD TYPE
-
-[FEC_CCF]
-KONFIGURACJA
-
-[FEC_CF1]
-SETUP1
-
-[FEC_CF2]
-SETUP2
-
-[FEC_CF3]
-SETUP3
-
-[FEC_CF4]
-SETUP4
-
-[FEC_CDP]
-STEROWNIK EKRANU
-
-[FEC_ONF]
-PIESZO
-
-[FEC_INC]
-W AUCIE
-
-[FEC_VIB]
-WIBRACJA
-
-[FET_AGS]
-GAMEPAD SETTINGS
-
-[FEM_PED]
-PED DENSITY
-
-[FEM_CAR]
-CAR DENSITY
-
-{ end of file }
-
-[DUMMY]
-
-THIS LABEL NEEDS TO BE HERE !!!
-AS THE LAST LABEL DOES NOT GET COMPILED \ No newline at end of file
diff --git a/utils/gxt/russian.txt b/utils/gxt/russian.txt
deleted file mode 100644
index 221e59f5..00000000
--- a/utils/gxt/russian.txt
+++ /dev/null
@@ -1,8115 +0,0 @@
-{
- New strings are at the bottom of file.
- Do not change the order of strings.
- You can fix the typos of existing translation but please refrain from
- unnecessary edits like rephasing because you think it suits better for your taste.
-}
-
-[1000]
-ТЫ ПОКОЙНИК
-
-[1001]
-ТЫ ПОКОЙНИК
-
-[1002]
-ТЫ ПОКОЙНИК
-
-[1003]
-ТЫ ПОКОЙНИК
-
-[1004]
-ТЫ ПОКОЙНИК
-
-[1005]
-АРЕСТОВАН
-
-[1006]
-АРЕСТОВАН
-
-[1007]
-АРЕСТОВАН
-
-[1008]
-АРЕСТОВАН
-
-[1009]
-АРЕСТОВАН
-
-[1010]
-~r~Твоя тачка перевернулась
-
-[1011]
-~r~Твоя тачка перевернулась
-
-[1012]
-~r~Твоя тачка перевернулась
-
-[1013]
-~r~Твоя тачка перевернулась
-
-[1014]
-~r~Твоя тачка перевернулась
-
-[8001]
-Тебе крупно не повезло!!
-
-[ACCURA]
-Меткость
-
-[AEROPL]
-Самолет
-
-[AIRPORT]
-Аэропорт Фрэнсис
-
-[ALEVEL]
-Скорая помощь. Задание ~1~
-
-[AM1]
-'САЙОНАРА, САЛЬВАТОРЕ'
-
-[AM1_1]
-~g~Сейчас Сальваторе выходит из клуба Луиджи!
-
-[AM1_10]
-~g~Сальваторе уйдет от Луиджи в 0~1~:~1~
-
-[AM1_2]
-~r~Тебя засекли!
-
-[AM1_3]
-~r~Ты упустил Сальваторе!
-
-[AM1_4]
-~r~Кретин, ты его спугнул! Какой ты к черту киллер?
-
-[AM1_5]
-~g~Отправляйся в квартал красных фонарей и жди, когда Сальваторе выйдет из клуба.
-
-[AM1_6]
-~g~Если ты будешь болтаться около клуба Луиджи, то тебя увидит мафия!
-
-[AM1_7]
-~r~Сальваторе дома в безопасности попивает коктейль. Все с тобой ясно, шакал!
-
-[AM1_8]
-~g~Сальваторе уйдет от Луиджи примерно в ~1~:~1~
-
-[AM1_9]
-~r~Сальваторе скрылся в клубе Луиджи!
-
-[AM1_A]
-Нам нужно кое что прояснить, прежде чем начнем налаживать какие-либо отношения,
-
-[AM1_B]
-деловые или нет. Давай раскроем карты.
-
-[AM1_C]
-Я из Якудзы и знаю, что ты работал на семью Сальваторе Леоне.
-
-[AM1_D]
-Я могу дать тебе работу в нашей организации,
-
-[AM1_E]
-но сначала тебе придется доказать, что ты на самом деле порвал с мафией.
-
-[AM1_F]
-Сальваторе Леоне выйдет от Луиджи примерно через три часа. (~1~:~1~)
-
-[AM1_G]
-Постарайся, чтобы он не добрался до дома живым.
-
-[AM1_H]
-Ну а мы с Марией пока вспомним былые времена.
-
-[AM1_I]
-О, Асука, у тебя новый массажист.
-
-[AM1_J]
-Это не массажист.
-
-[AM1_K]
-Сальваторе Леоне выйдет от Луиджи примерно в три часа. (0~1~:~1~)
-
-[AM2]
-'ПОД НАДЗОРОМ'
-
-[AM2_4]
-~g~Они тебя засекли, ты шел как слепой слон!
-
-[AM2_A]
-Смерть Сальваторе - очень приятная новость,
-
-[AM2_A2]
-ты отличный киллер. Мне нравятся такие мужики.
-
-[AM2_B]
-Это мой брат Кенжи.
-
-[AM2_C]
-У Асуки для тебя есть работа, но как только освободишься - загляни ко мне в казино.
-
-[AM2_D]
-Кенжи как всегда тянет руки к моим игрушкам.
-
-[AM2_E]
-Мои люди в полиции сообщили, что мафия следит за всеми нашими делами в городе,
-
-[AM2_E2]
-так они пытаются выйти на тебя.
-
-[AM2_F]
-Они мешают нам работать. Нужно устранить эту проблему.
-
-[AM2_G]
-Разберись с этими шпионами-самоучками и прекрати вендетту раз и навсегда.
-
-[AM3]
-'ПРОЩАЙ, ПАПАРАЦЦИ'
-
-[AM3_A]
-Тут один журналист что-то вынюхивает.
-
-[AM3_B]
-Мы с Марией немного отдохнем, пока ты не избавишься от этого назойливого писаки.
-
-[AM3_C]
-Пока ты это читаешь, он, вероятно, в гавани! Угони полицейский катер и 'потопи' его карьеру!
-
-[AM4]
-'ДЕНЬГИ ДЛЯ РЭЯ'
-
-[AM4_10]
-Знаешь, я тоже иногда могу подкинуть работенку.
-
-[AM4_11]
-Если что - ты знаешь, где меня найти.
-
-[AM4_1A]
-Доберись до телефона к западу от парка Бельвиль.
-
-[AM4_1B]
-Доберись до телефона в Учебном городке.
-
-[AM4_1C]
-Доберись до телефона к югу от парка Бельвиль.
-
-[AM4_1D]
-Встречаемся в туалете, расположенном в парке.
-
-[AM4_3]
-Ты, должно быть, новый посыльный Асуки!
-
-[AM4_4]
-Ты принес мне деньги? Это все?
-
-[AM4_5]
-Я знаю, ты думаешь - еще один продажный коп.
-
-[AM4_6]
-Да, мы живем в продажном мире.
-
-[AM4_7]
-Мной занялась служба внутреннего расследования только из-за того, что я потерял двух напарников.
-
-[AM4_8]
-Приходится быть начеку.
-
-[AM4_9]
-Да, весь этот город - одна большая помойная яма.
-
-[AM4_A]
-Да это же мой красавчик!
-
-[AM4_B]
-Мария сейчас очень занята, но я ей передам, что ты заходил.
-
-[AM4_C]
-Асука, кто это? Я бы и сама вышла, но я очень хочу писать, окей?
-
-[AM4_D]
-Ты должен встретиться с моим знакомым копом.
-
-[AM4_E]
-Это деньги за его последнюю работу, что он сделал для нас.
-
-[AM4_F]
-Разумеется, он очень осторожен.
-
-[AM4_G]
-Немедленно отправляйся к телефону-автомату в Торрингтоне и жди его инструкций.
-
-[AM5]
-'ДВУЛИКИЙ ТАННЕР'
-
-[AM5_1]
-Таннер у тебя на хвосте!
-
-[AM5_A]
-Мы с Марией пошли по магазинам.
-
-[AM5_B]
-Мой человек в полиции сообщил, что один из наших водил, на самом деле - полицейский под прикрытием!
-
-[AM5_C]
-Он не вылезает из своей тачки, поэтому мы прикрепили к ней маячок.
-
-[AM5_D]
-Пусти ему кровь!
-
-[AMBULAN]
-Скорая
-
-[AMBUL_M]
-'СКОРАЯ ПОМОЩЬ'
-
-[AMMU]
-Чтобы купить оружие - зайди в магазин.
-
-[AMMU_A]
-Луиджи сказал, тебе нужен ствол...
-
-[AMMU_B]
-Джоуи кое что для тебя заказал...
-
-[AMMU_C]
-Иди во двор магазина, я там тебе кое-что припас.
-
-[AMMU_D]
-У меня есть все что тебе понадобится.
-
-[AMMU_E]
-Тебе и лицензия нужна?
-
-[AMMU_F]
-Документов можешь не показывать, я и так тебе верю.
-
-[APR]
-Апр
-
-[AS1]
-'НАЖИВКА'
-
-[AS1_A]
-~w~Мигель считает, что я плохо с ним обращаюсь.
-
-[AS1_B]
-~w~Но он все-таки рассказал, что Каталина жутко боится твоей мести.
-
-[AS1_C]
-~w~Она послала в город три группы убийц, чтобы они выследили и прикончили тебя.
-
-[AS1_D]
-~w~Тебе придется побыть наживкой и постараться заманить их в Пайк Крик,
-
-[AS1_E]
-~w~там их уже будут поджидать мои люди.
-
-[AS1_G]
-~r~Все якудза перебиты!
-
-[AS1_H]
-~r~Тебе не удалось заманить убийц в ловушку Якудзы!
-
-[AS2]
-'КОФЕ НА ВЫНОС!'
-
-[AS2_1]
-~g~В Портланде уничтожены все кофейные ларьки!
-
-[AS2_10]
-~g~Кофейные ларьки еще стоят в Портланде и на острове Стаунтон.
-
-[AS2_11]
-~g~~1~ ИЗ 9!
-
-[AS2_12]
-~g~Объедь все районы города и отыщи ~b~кофейные ларьки~g~!
-
-[AS2_12A]
-~g~После того как ты уничтожишь первый ларек, у тебя будет 8 минут, прежде чем Картель забьет тревогу!
-
-[AS2_2]
-~g~На острове Стаунтон уничтожены все кофейные ларьки!
-
-[AS2_3]
-~g~В Шорсайд Вейл уничтожены все кофейные ларьки!
-
-[AS2_4]
-~r~Картель предупредил продавцов наркоты!
-
-[AS2_5]
-~g~Кофейные ларьки еще стоят в Шорсайд Вейл и на острове Стаунтон!
-
-[AS2_6]
-~g~Кофейные ларьки еще стоят в Шорсайд Вейл!
-
-[AS2_7]
-~g~Кофейные ларьки еще стоят на острове Стаунтон!
-
-[AS2_8]
-~g~Кофейные ларьки еще стоят в Портланде!
-
-[AS2_9]
-~g~Кофейные ларьки еще стоят в Портланде и в Шорсайд Вейл!
-
-[AS2_A]
-~w~Мы недооценили план Каталины по реализации СПАНКа.
-
-[AS2_A1]
-~w~Мигель вынослив, как настоящий латиноамериканец.
-
-[AS2_A2]
-~w~Я уже выдохлась.
-
-[AS2_B]
-~w~Ярди - торгующие СПАНКом по всему городу - это мелкие сошки.
-
-[AS2_C]
-~w~Картель действует через свою компанию 'The Kappa Coffee House'.
-
-[AS2_D]
-~w~Они продают СПАНК через сеть уличных ларьков.
-
-[AS2_E]
-~w~Нам не остается ничего другого, кроме как прикрыть все эти лавочки.
-
-[AS2_F]
-~w~Разнеси их в щепки!
-
-[AS3]
-'БЫЛО ВАШЕ, СТАЛО НАШЕ'
-
-[AS3_1]
-~g~Найди ~r~катер~g~ и встань около ~b~буя~g~!
-
-[AS3_1A]
-~g~Теперь двигайся к ~b~бую~g~!
-
-[AS3_2]
-~b~Двигайся к буям на посадочной полосе! ~y~Самолет уже на подлете!
-
-[AS3_3]
-~g~Подожди, пока не покажется ~y~самолет~g~!
-
-[AS3_4]
-~g~Сбей ~y~самолет~g~ из ракетницы!
-
-[AS3_5]
-~g~Собирай товар!
-
-[AS3_6]
-~g~~1~ ИЗ 8
-
-[AS3_A]
-~W~Ну что, затянем немного потуже, или просто подождем, пока почернеет и отвалится?
-
-[AS3_B]
-~w~Ну ка, давай посмотрим...
-
-[AS3_C]
-~w~Фууууууууу! что это за желтая липкая гадость?
-
-[AS3_C1]
-~w~Привет малыш.
-
-[AS3_D]
-~w~Мой работничек!
-
-[AS3_E]
-~w~Мне было скучно, и я решила составить Асуке компанию.
-
-[AS3_F]
-~w~Похоже она очень одаренная девочка.
-
-[AS3_F1]
-~w~Ей удалось узнать кое что важное у нашего гостя.
-
-[AS3_G]
-~w~В два часа в аэропорт Фрэнсис Интернешнл прибывает самолет.
-
-[AS3_G1]
-~w~Он просто набит отравой Каталины.
-
-[AS3_H]
-~w~Чтобы тебе не мешалась служба безопасности, возьми катер чтобы добраться до буев
-
-[AS3_H1]
-и взорвать самолет, когда тот пойдет на посадку.
-
-[AS3_I]
-~w~Найди среди обломков груз и забери его!
-
-[AS3_J]
-~w~Малыш, будь поосторожней там, Окей?
-
-[AS3_K]
-~w~Попробуй-ка соус чили...
-
-[AS4]
-'ВЫКУП'
-
-[ASUKA]
-ЗАДАНИЯ АСУКИ
-
-[ATUTOR]
-Чтобы получить задание Скорой или отказаться от него нажми ~h~~k~~TOGGLE_SUBMISSIONS~~w~.
-
-[ATUTOR2]
-~g~ОСТОРОЖНО отвози пациентов в больницу. Каждое столкновение ухудшает их состояние.
-
-[ATUTOR3]
-Чтобы получить задание Скорой или отказаться от него нажми ~h~~k~~TOGGLE_SUBMISSIONS~~w~.
-
-[AUG]
-Авг
-
-[AWAY]
-~r~Он свалил отсюда!
-
-[AWAY2]
-~r~Они свалили.
-
-[A_CANC]
-~r~Задание скорой отменено!
-
-[A_COMP1]
-Все задания скорой выполнены!
-
-[A_COMP2]
-Ты никогда не будешь уставать!
-
-[A_COMP3]
-Все задания скорой выполнены! Ты никогда не будешь уставать при быстром беге!
-
-[A_FAIL1]
-Задание скорой прервано.
-
-[A_FAIL2]
-~r~Из-за твоей медлительности скончался пациент!
-
-[A_FAIL3]
-~r~Пациент скончался!
-
-[A_FULL]
-~r~Скорая переполнена!
-
-[A_PASS]
-Спасен!
-
-[A_RANGE]
-~g~Рация в скорой не ловит сигнал, подъедь ближе к больнице!
-
-[A_SAVES]
-ЛЮДЕЙ СПАСЕНО: ~1~
-
-[A_TIME]
-+~1~ секунд
-
-[BANSHEE]
-Банши
-
-[BARRCKS]
-Барракс OL
-
-[BAT1]
-~g~Возьми биту!
-
-[BELLYUP]
-Фургон Триад
-
-[BETRA_A]
-Прости, детка.
-
-[BETRA_B]
-У меня свои планы, а ты...
-
-[BETRA_C]
-Ты мне больше не нужен.
-
-[BET_JB]
-ПРЕДАННЫЙ СВОЕЙ ВОЗЛЮБЛЕННОЙ КАТАЛИНОЙ, БРОСИВШЕЙ ЕГО УМИРАТЬ. ОСУЖДЕННЫЙ И ПРИГОВОРЕННЫЙ, ОН УЖЕ НА ПУТИ В ТЮРЬМУ. ОН НЕ МОЖЕТ ДУМАТЬ НИ О ЧЕМ ИНОМ, КРОМЕ...... МЕСТИ!
-
-[BFINJC]
-Иджэкшен BF
-
-[BGWHON]
-Big White Debug Light Switched On
-
-[BGWOFF]
-Big White Debug Light Switched Off
-
-[BIG_DAM]
-Плотина Кокрейн
-
-[BITCH_D]
-~g~Мария мертва!
-
-[BLISTA]
-Блиста
-
-[BOATIN1]
-Запрыгни в катер и нажми ~h~~k~~VEHICLE_ENTER_EXIT~~w~ чтобы сесть за руль.
-
-[BOATIN2]
-Если ты рядом с катером, то нажми ~h~~k~~VEHICLE_ENTER_EXIT~~w~, чтобы в него сесть.
-
-[BOATIN3]
-Запрыгни в катер и нажми ~h~~k~~VEHICLE_ENTER_EXIT~~w~ чтобы сесть за руль.
-
-[BOATIN4]
-Если ты рядом с катером, то нажми ~h~~k~~VEHICLE_ENTER_EXIT~~w~, чтобы в него сесть.
-
-[BOBCAT]
-Рысь
-
-[BOMB]
-Чтобы установить ~h~бомбу~w~ - поставь тачку в гараж. Стоимость бомбы - ~h~$1000~w~.
-
-[BOMB1]
-Гараж Лысого
-
-[BONUS]
-~g~ПРИЗ $~1~
-
-[BORGNIN]
-Борнини
-
-[BRIDGE1]
-Как только отремонтируют мост Каллахан, ты сможешь попасть на остров Стаунтон.
-
-[BSTSTU]
-Лучший БЕЗУМНЫЙ трюк:
-
-[BUGGY]
-ОСТАЛОСЬ:
-
-[BULL]
-СЛИТКОВ:
-
-[BUS]
-Автобус
-
-[BUSTED]
-АРЕСТОВАН!
-
-[B_SITE]
-ЗАДАНИЯ АСУКИ (ПРИГОРОД)
-
-[CABBIE]
-Кэб
-
-[CAM_A]
-Чтобы сменить расположение ~h~камеры~w~, нажми ~h~~k~~CAMERA_CHANGE_VIEW_ALL_SITUATIONS~~w~.
-
-[CAM_B]
-Чтобы сменить расположение ~h~камеры~w~, нажми ~h~~k~~CAMERA_CHANGE_VIEW_ALL_SITUATIONS~~w~.
-
-[CARSOFF]
-Машины выключены.
-
-[CARS_ON]
-Машины включены.
-
-[CAR_1]
-Ambulance
-
-[CAR_10]
-Coach
-
-[CAR_11]
-Flatbed
-
-[CAR_12]
-Linerunner
-
-[CAR_13]
-Trashmaster
-
-[CAR_14]
-Patriot
-
-[CAR_15]
-Mr Whoopee
-
-[CAR_16]
-Mule
-
-[CAR_17]
-Yankee
-
-[CAR_18]
-Pony
-
-[CAR_19]
-Bobcat
-
-[CAR_2]
-Firetruck
-
-[CAR_20]
-Rumpo
-
-[CAR_21]
-Blista
-
-[CAR_22]
-Dodo
-
-[CAR_23]
-Bus
-
-[CAR_24]
-Sentinel
-
-[CAR_25]
-Cheetah
-
-[CAR_26]
-Banshee
-
-[CAR_27]
-Stinger
-
-[CAR_28]
-Infernus
-
-[CAR_29]
-Esperanto
-
-[CAR_3]
-Police
-
-[CAR_30]
-Kuruma
-
-[CAR_31]
-Stretch
-
-[CAR_32]
-Perennial
-
-[CAR_33]
-Landstalker
-
-[CAR_34]
-Manana
-
-[CAR_35]
-Idaho
-
-[CAR_36]
-Stallion
-
-[CAR_37]
-Taxi
-
-[CAR_38]
-Cabbie
-
-[CAR_39]
-Buggy
-
-[CAR_4]
-Enforcer
-
-[CAR_5]
-Barracks
-
-[CAR_6]
-Rhino
-
-[CAR_7]
-FBIcar
-
-[CAR_8]
-Securicar
-
-[CAR_9]
-Moonbeam
-
-[CAR_CRU]
-Машин разбито
-
-[CAR_EXP]
-Машин взорвано
-
-[CAT1]
-'ВЫКУП'
-
-[CAT1_A]
-Твоя драгоценная Мария у меня. Если не хочешь, чтобы ее личико было похоже на мясной фарш,
-
-[CAT1_B]
-привези мне $500,000 на виллу в Кедровой роще.
-
-[CAT1_E]
-XXXX
-
-[CAT1_F]
-Езжай к Каталине, пока не вышло время!
-
-[CAT2]
-'ОБМЕН'
-
-[CAT2_A]
-Интересно, ты пришел ради того, чтобы спасти Марию или вернуться ко мне?
-
-[CAT2_A1]
-Да пошла ты, глупая сучка!
-
-[CAT2_B]
-Хочу сказать тебе кое-что,
-
-[CAT2_B2]
-мне так и хочется тебя пристрелить, но бизнес прежде всего.
-
-[CAT2_C]
-Ты просто находка для меня, амиго!
-
-[CAT2_D]
-Давай бабки.
-
-[CAT2_E]
-О, да ты без дела не шатался!
-
-[CAT2_E2]
-Но ты так и не понял, что мне нельзя верить.
-
-[CAT2_E3]
-Пристрелите кретина.
-
-[CAT2_F]
-Я сломала ноготь, и моя прическа растрепалась. А она обошлась мне в 50 долларов, представляешь?
-
-[CAT2_G]
-Я была так напугана, но потом я сказала себе - ты уже взрослая девочка.
-
-[CAT2_H]
-О, у нас будет так весело, потому что, ты знаешь, моя сестра сказала, что она поживет у нас со своими детьми,
-
-[CAT2_I]
-потому что у ее мужа снова интрижка и...
-
-[CAT2_J]
-Быстрее, взлетаем!
-
-[CATINF1]
-~g~Убей Каталину!
-
-[CATINF2]
-~g~Чтобы найти Каталину - следуй за вертушкой.
-
-[CAT_MON]
-~g~У тебя недостаточно зелени. Необходимо $500,000 баксов.
-
-[CDERROR]
-Ошибка чтения диска с игрой Grand Theft Auto III
-
-[CHAT]
-Chatterbox FM
-
-[CHEAT1]
-Чит-код активирован
-
-[CHEAT2]
-Чит-код: оружие
-
-[CHEAT3]
-Чит-код: здоровье
-
-[CHEAT4]
-Чит-код: броня
-
-[CHEAT5]
-Чит-код: в розыске
-
-[CHEAT6]
-Чит-код: деньги
-
-[CHEAT7]
-Чит-код: погода
-
-[CHEATOF]
-Режим чит-кодов Выкл.
-
-[CHEATON]
-Режим чит-кодов Вкл.
-
-[CHEETAH]
-Гепард
-
-[CHEVOK]
-CheckEveryOkB4Save
-
-[CHFIDL]
-ВЫБЕРИТЕ ЗАПИСЬ ДЛЯ УДАЛЕНИЯ
-
-[CHFILE]
-ВЫБЕРИТЕ ИГРУ ДЛЯ ЗАГРУЗКИ
-
-[CHINA]
-Чайнатаун
-
-[CINCAM]
-Вид из телекамеры
-
-[CITYZON]
-Либерти Сити
-
-[CLZOOF]
-Show Cull Zones Off
-
-[CLZOON]
-Show Cull Zones On
-
-[CNCSAV]
-Нельзя сохранить игру, сидя в тачке.
-
-[CNTLS]
-Управление
-
-[CNTSAV]
-Во время задания запись невозможна.
-
-[COACH]
-Автобус-люкс
-
-[COLLECT]
-СОБРАНО:
-
-[COLOMCR]
-Круизер картеля
-
-[COLT_IN]
-В магазин завезли пистолеты!
-
-[COM_EAS]
-Ньюпорт
-
-[COM_ZON]
-Остров Стаунтон
-
-[CONSTRU]
-Форт Стаунтон
-
-[CONTRL]
-Задание управления
-
-[COPCART]
-~g~У тебя есть ~1~ секунд чтобы вернуться в полицейскую машину, иначе задание будет отменено.
-
-[COP_M]
-'ПОЛИЦЕЙСКИЙ'
-
-[CO_ALL]
-Ты взял всех преступников. Вот тебе кое-что...
-
-[CO_ONE]
-Особые пакеты: ~1~ из ~1~
-
-[CRD050A]
-ТЕСТЕРЫ
-
-[CRD136A]
-ALEX HORTON
-
-[CRD137A]
-NAVID KHONSARI
-
-[CRD138A]
-JAMIE KING
-
-[CRD138B]
-RENAUD SEBBANE
-
-[CRD140A]
-RENAUD SEBBANE
-
-[CRD140B]
-GISELLE JONES
-
-[CRD140C]
-STEPHEN DANIELS
-
-[CRD140D]
-ROBERT STIO
-
-[CRD140E]
-JENNY GROSS.
-
-[CRD218A]
-CRAIG CONNER
-
-[CRD218B]
-STUART ROSS
-
-[CRED001]
-ROCKSTAR STUDIOS
-
-[CRED002]
-PRODUCER
-
-[CRED003]
-LESLIE BENZIES
-
-[CRED004]
-ART DIRECTOR
-
-[CRED005]
-AARON GARBUT
-
-[CRED006]
-TECHNICAL DIRECTION
-
-[CRED007]
-OBBE VERMEIJ
-
-[CRED008]
-ADAM FOWLER
-
-[CRED009]
-ДИЗАЙН
-
-[CRED010]
-CRAIG FILSHIE
-
-[CRED011]
-WILLIAM MILLS
-
-[CRED012]
-CHRIS ROTHWELL
-
-[CRED013]
-JAMES WORRALL
-
-[CRED014]
-АВТОРЫ СЮЖЕТА
-
-[CRED015]
-JAMES WORRALL
-
-[CRED016]
-PAUL KUROWSKI
-
-[CRED017]
-DAN HOUSER
-
-[CRED018]
-ГЕРОИ
-
-[CRED019]
-IAN MCQUE
-
-[CRED020]
-ANIMATION & DIRECTION
-
-[CRED021]
-ALEX HORTON
-
-[CRED022]
-LEE MONTGOMERY
-
-[CRED023]
-AUTO DESIGN
-
-[CRED024]
-PAUL KUROWSKI
-
-[CRED025]
-ARTISTS
-
-[CRED026]
-KEIRAN BAILLIE
-
-[CRED027]
-ADAM COCHRANE
-
-[CRED028]
-GARY MCADAM
-
-[CRED029]
-MICHAEL PIRSO
-
-[CRED030]
-ANDREW SOOSAY
-
-[CRED031]
-ALISDAIR WOOD
-
-[CRED032]
-CODERS
-
-[CRED033]
-ALAN CAMPBELL
-
-[CRED034]
-MARK HANLON
-
-[CRED035]
-ANDRZEJ MADAJCZYK
-
-[CRED036]
-ALEXANDER ROGER
-
-[CRED037]
-GRAEME WILLIAMSON
-
-[CRED038]
-SCORE
-
-[CRED039]
-CRAIG CONNER
-
-[CRED040]
-STUART ROSS
-
-[CRED041]
-SOUND DESIGN & MASTERING
-
-[CRED042]
-ALLAN WALKER
-
-[CRED043]
-AUDIO PROGRAMMING
-
-[CRED044]
-RAYMOND USHER
-
-[CRED045]
-TEST MANAGER
-
-[CRED046]
-CRAIG ARBUTHNOTT
-
-[CRED047]
-LEAD TESTERS
-
-[CRED048]
-ANDY DUTHIE
-
-[CRED049]
-JOHN HAIME
-
-[CRED050]
-NEIL CORBETT
-
-[CRED051]
-GRAEME JENNINGS
-
-[CRED052]
-DAVID MURDOCH
-
-[CRED053]
-DAVID BEDDOES
-
-[CRED054]
-EDWIN SMITH
-
-[CRED055]
-MARK FLETT
-
-[CRED056]
-MICHAEL SUTHERLAND
-
-[CRED057]
-TECHNICAL SUPPORT
-
-[CRED058]
-LORRAINE ROY
-
-[CRED059]
-CHRISTINE CHALMERS
-
-[CRED060]
-ROCKSTAR
-
-[CRED061]
-EXECUTIVE PRODUCER
-
-[CRED062]
-SAM HOUSER
-
-[CRED063]
-PRODUCER
-
-[CRED064]
-DAN HOUSER
-
-[CRED065]
-DIRECTOR OF DEVELOPMENT
-
-[CRED066]
-JAMIE KING
-
-[CRED067]
-TECHNICAL PRODUCER
-
-[CRED068]
-GARY J. FOREMAN
-
-[CRED069]
-ASSOCIATE PRODUCER
-
-[CRED070]
-JEREMY POPE
-
-[CRED071]
-MUSIC SUPERVISOR
-
-[CRED072]
-TERRY DONOVAN
-
-[CRED073]
-ROCKSTAR PRODUCTION TEAM
-
-[CRED074]
-TERRY DONOVAN
-
-[CRED075]
-JENNIFER KOLBE
-
-[CRED076]
-JENEFER GROSS
-
-[CRED077]
-LAURA PATERSON
-
-[CRED078]
-JEFF CASTANEDA
-
-[CRED079]
-CHRIS CARRO
-
-[CRED080]
-ADAM TEDMAN
-
-[CRED081]
-JUNG KWAK
-
-[CRED082]
-BRIAN WOOD
-
-[CRED083]
-PAUL YEATES
-
-[CRED084]
-STANTON SARJEANT
-
-[CRED085]
-VP OF MARKETING
-
-[CRED086]
-TERRY DONOVAN
-
-[CRED087]
-TECHNICAL COORDINATOR
-
-[CRED088]
-BRANDON ROSE
-
-[CRED089]
-QA MANAGER
-
-[CRED090]
-JEFF ROSA
-
-[CRED091]
-LEAD ANALYST
-
-[CRED092]
-ADAM DAVIDSON
-
-[CRED093]
-GAME ANALYST
-
-[CRED094]
-RICHARD HUIE
-
-[CRED095]
-TEST TEAM
-
-[CRED096]
-LANCE WILLIAMS
-
-[CRED097]
-JOE GREENE
-
-[CRED098]
-BRIAN PLANER
-
-[CRED099]
-OSWALD GREENE
-
-[CRED100]
-LIBERTY TREE EDITORIAL
-
-[CRED101]
-JAMES WORRALL
-
-[CRED102]
-DAN HOUSER
-
-[CRED103]
-ADAM TEDMAN
-
-[CRED104]
-PAUL YEATES
-
-[CRED105]
-JENEFER GROSS
-
-[CRED106]
-LAURA PATERSON
-
-[CRED107]
-CUT-SCENES
-
-[CRED108]
-SCRIPT BY DAN HOUSER AND JAMES WORRALL
-
-[CRED109]
-AUDIO DIRECTED BY DAN HOUSER
-
-[CRED110]
-AUDIO PRODUCED BY RENAUD SEBBANE
-
-[CRED111]
-CAST
-
-[CRED112]
-FRANK VINCENT AS SALVATORE LEONE
-
-[CRED113]
-JOE PANTOLIANO AS LUIGI GOTERELLI
-
-[CRED114]
-MICHAEL MADSEN AS TONI CIPRIANI
-
-[CRED115]
-MICHAEL RAPAPORT AS JOEY LEONE
-
-[CRED116]
-DEBBI MAZAR AS MARIA
-
-[CRED117]
-KYLE MACLACHLAN AS DONALD LOVE
-
-[CRED118]
-ROBERT LOGGIA AS RAY MACHOWSKI
-
-[CRED119]
-GURU AS 8-BALL
-
-[CRED120]
-SONDRA JAMES AS MOMMA
-
-[CRED121]
-LIANA PAI AS ASUKA
-
-[CRED122]
-LES MAU AS KENJI
-
-[CRED123]
-CYNTHIA FARRELL AS CATALINA
-
-[CRED124]
-AL ESPINOSA AS MIGUEL
-
-[CRED125]
-CHRIS PHILLIPS AS EL BURRO
-
-[CRED126]
-HUNTER PLATIN AS CHICO
-
-[CRED127]
-WALTER MUDU AS D-ICE
-
-[CRED128]
-CURTIS MCCLARIN AS CURTLY
-
-[CRED129]
-BILL FIORE AS DARKEL
-
-[CRED130]
-CHRIS PHILLIPS AS MARTY CHONKS
-
-[CRED131]
-HUNTER PLATIN AS CURLY BOB
-
-[CRED132]
-WALTER MUDU AS KING COURTNEY
-
-[CRED133]
-HUNTER PLATIN AS ONE-ARMED PHIL
-
-[CRED134]
-KIM GURNEY AS MISTY
-
-[CRED135]
-MOTION CAPTURE
-
-[CRED136]
-ANIMATED BY
-
-[CRED137]
-DIRECTED BY
-
-[CRED138]
-PRODUCED BY
-
-[CRED139]
-RECORDED AT MODERN UPRISING STUDIOS, BROOKLYN
-
-[CRED140]
-ACTORS
-
-[CRED141]
-PEDESTRIAN DIALOGUE
-
-[CRED142]
-WRITTEN BY DAN HOUSER, NAVID KHONSARI & JAMES WORRALL
-
-[CRED143]
-DIRECTED BY CRAIG CONNER, DAN HOUSER AND LAZLOW
-
-[CRED144]
-PRODUCED BY RENAUD SEBBANE
-
-[CRED145]
-CAST
-
-[CRED146]
-HUNTER PLATIN
-
-[CRED147]
-DAN HOUSER
-
-[CRED148]
-RENAUD SEBBANE
-
-[CRED149]
-MARIA CHAMBERS
-
-[CRED150]
-JEFF STANTON
-
-[CRED151]
-RYAN CROY
-
-[CRED152]
-DEENA BERMAN
-
-[CRED153]
-MARIA CHAMBERS
-
-[CRED154]
-ALICE B. SALTZMAN
-
-[CRED155]
-ALEX ANTHONY SIOUKAS
-
-[CRED156]
-SEAN R. LYNCH
-
-[CRED157]
-AMY SALZMAN
-
-[CRED158]
-COLIN MCSHANE
-
-[CRED159]
-COREY WADE
-
-[CRED160]
-GERALD COSGROVE
-
-[CRED161]
-STEPHANIE ROY
-
-[CRED162]
-DORIS WOO
-
-[CRED163]
-JOSEPH GREENE
-
-[CRED164]
-LAZLOW JONES
-
-[CRED165]
-HSIANG LIN
-
-[CRED166]
-STEVE MICHAEL ROBERT
-
-[CRED167]
-MATHEW MURRAY
-
-[CRED168]
-RICHARD HUIE
-
-[CRED169]
-GARVIN ATWELL
-
-[CRED170]
-STEVE KNEZEVICH
-
-[CRED171]
-YUKIMURA SATO
-
-[CRED172]
-FRANK CHAVEZ
-
-[CRED173]
-LIEZL JACINTO
-
-[CRED174]
-CANAAN MCKOY
-
-[CRED175]
-ADAM DAVIDSON
-
-[CRED176]
-LANCE WILLIAMS
-
-[CRED177]
-NEIL MCCAFFREY
-
-[CRED178]
-LAURA PATERSON
-
-[CRED179]
-REY CONCEPCION
-
-[CRED180]
-CHARLES HEROLD
-
-[CRED181]
-ANDREW GREENWALD
-
-[CRED182]
-JAMES MIELKE
-
-[CRED183]
-PETER SUCIU
-
-[CRED184]
-ALEX ODULIO
-
-[CRED185]
-DON NKRUMAH
-
-[CRED186]
-KENDALL PITTMAN
-
-[CRED187]
-SAL SUAZO
-
-[CRED188]
-EREK MATEO
-
-[CRED189]
-CHRIS DIFATE
-
-[CRED190]
-LEILA MILTON
-
-[CRED191]
-DARREN ZOLTOWSKI
-
-[CRED192]
-VIRGINIA SMITH
-
-[CRED193]
-KEVIN CASSIN
-
-[CRED194]
-JASON SHIGEMORI
-
-[CRED195]
-KELLY KINSELLA
-
-[CRED196]
-MOLLIE STICKNEY
-
-[CRED197]
-STANTON SARJEANT
-
-[CRED198]
-LAURA WALSH
-
-[CRED199]
-MARK GARONE
-
-[CRED200]
-JOANNA SLY
-
-[CRED201]
-ELIZABETH HOWELL
-
-[CRED202]
-ANA HERCULES
-
-[CRED203]
-SHIRLEY IRICK
-
-[CRED204]
-KASHONA FIELDS
-
-[CRED205]
-JOEL M. LILJE
-
-[CRED206]
-JOHN DIBENEDETTO
-
-[CRED207]
-NANCY GILES
-
-[CRED208]
-RYAN CROY
-
-[CRED209]
-JENNIFER KOLBE
-
-[CRED210]
-LIAM BURKE
-
-[CRED211]
-SIGRID PREISSL
-
-[CRED212]
-ANITA FITZSIMONS
-
-[CRED213]
-PHILIPPA RASELLI
-
-[CRED214]
-WIL QUESNEL
-
-[CRED215]
-FALKO BURKERT
-
-[CRED216]
-SARA SEWELL
-
-[CRED217]
-RADIO STATIONS AND MUSIC
-
-[CRED218]
-PRODUCERS FOR ROCKSTAR UK
-
-[CRED219]
-SOUNDTRACK CO-ORDINATOR
-
-[CRED220]
-TERRY DONOVAN
-
-[CRED221]
-PRODUCER FOR ROCKSTAR GAMES
-
-[CRED222]
-DAN HOUSER
-
-[CRED223]
-EDITED BY
-
-[CRED224]
-CRAIG CONNER
-
-[CRED225]
-ALLAN WALKER
-
-[CRED226]
-LAZLOW
-
-[CRED227]
-DJ BANTER AND IMAGING WRITTEN BY
-
-[CRED228]
-DAN HOUSER
-
-[CRED229]
-LAZLOW
-
-[CRED230]
-SPECIAL THANKS TO
-
-[CRED231]
-ADAM TEDMAN
-
-[CRED232]
-ALEX MASON
-
-[CRED233]
-JUDY HENDERSON CASTING
-
-[CRED234]
-HAMISH BROWN
-
-[CRED235]
-CHRISSY HOBAN
-
-[CRED236]
-INNES RICARD
-
-[CRED237]
-LILION BROZSKA
-
-[CRED238]
-BOB HILLARY
-
-[CRED239]
-EMILY ANDERSON
-
-[CRED240]
-RICHIE HENDERSON
-
-[CRED241]
-CHRSTIAN CANTAMESSA
-
-[CRED242]
-JERONIMO BARRERA
-
-[CRED243]
-ALEXANDER ILLES
-
-[CRED244]
-BARANE CHAN
-
-[CRED245]
-DUNCAN SHIELDS
-
-[CRED246]
-BARANE CHAN
-
-[CRED247]
-DEREK PAYNE
-
-[CRED248]
-KEVIN WONG
-
-[CRED249]
-ROSS ELLIOTT
-
-[CRED250]
-ROSS BEAZLEY
-
-[CRED251]
-ALEX BAZLINTON
-
-[CRED252]
-DAVE WATSON
-
-[CRED253]
-MALCOLM SMITH
-
-[CRED254]
-STUDIO MANAGER
-
-[CRED255]
-ANDREW SEMPLE
-
-[CRED256]
-ARTIST
-
-[CRED257]
-STUART PETRI
-
-[CRED258]
-JERONIMO BARRERA
-
-[CRED259]
-CARLY SLATER
-
-[CRED260]
-GREG LAU
-
-[CRED261]
-STEVE KNEZEVICH
-
-[CRED262]
-DEVIN WINTERBOTTOM
-
-[CRED263]
-JAMEEL VEGA
-
-[CRED264]
-LEE CUMMINGS
-
-[CRED265]
-DEVIN BENNET
-
-[CRED266]
-ELIZABETH SATTERWHITE
-
-[CRED267]
-AARON RIGBY
-
-[CRED268]
-STEVE K.
-
-[CRED269]
-GREG LAU
-
-[CRED270]
-MIKE HONG
-
-[CRGOFF]
-ShowCarRoadGroups Off
-
-[CRIMRA]
-Ваш рейтинг:
-
-[CRLDIC]
-Создание и загрузка иконок
-
-[CRMGSV]
-Create copy protected magazine directory
-
-[CRRGON]
-ShowCarRoadGroups On
-
-[CRROOT]
-CreateRootDir
-
-[CRUSH]
-Поставь машину в голубой круг и выйди из нее. После этого машина будет утилизирована.
-
-[CR_1]
-Кран не может поднять эту машину.
-
-[CTRSCR]
-Центровка экрана
-
-[CTUTOR]
-Нажми ~h~~k~~TOGGLE_SUBMISSIONS~~w~, чтобы заняться работой полицейского или отказаться от нее.
-
-[CTUTOR2]
-Нажми ~h~~k~~TOGGLE_SUBMISSIONS~~w~, чтобы заняться работой полицейского или отказаться от нее.
-
-[CULREC]
-CCullZones::RecalculateCullZoneData()
-
-[CVT_CRT]
-Конвертация текстур не выполнена. Чтобы ее выполнить, вам нужно войти под администраторским паролем. Нажмите ESC для отмены.
-
-[CVT_ERR]
-У вас закончилось место на жестком диске. Пожалуйста, освободите место перед запуском игры. Нажмите ESC для отмены.
-
-[CVT_MSG]
-Конвертация текстур в формат оптимальный для вашей видеокарты.
-
-[C_BREIF]
-~g~~a~ - там в последний раз видели подозреваемого.
-
-[C_CANC]
-~r~Миссия полицейского прервана!
-
-[C_ESCP]
-~r~Подозреваемый скрылся!
-
-[C_FAIL]
-Миссия полицейского не выполнена!
-
-[C_KILLS]
-ПРЕСТУПНИКОВ УБИТО: ~1~
-
-[C_PASS]
-СПРАВЕДЛИВОСТЬ ВОСТОРЖЕСТВОВАЛА!
-
-[C_RANGE]
-~g~Полицейская рация не ловит сигнал, надо подъехать ближе к участку!
-
-[C_TIME]
-~r~Время выполнения задания вышло!
-
-[C_VIGIL]
-НАГРАДА ОТ ПОЛИЦИИ!
-
-[DAM]
-ПОВРЕЖДЕНИЯ:
-
-[DAYPLC]
-Ежедневные расходы полиции
-
-[DAYSPS]
-Дней проведенных за игрой
-
-[DBFOFF]
-CTheScripts::DbgFlag Off
-
-[DBGFON]
-CTheScripts::DbgFlag On
-
-[DBINST]
-Двойной безумный трюк
-
-[DBL_CLF]
-Double Clef FM
-
-[DBPINS]
-Идеальный безумный трюк
-
-[DEAD]
-ВЫРУБИЛСЯ!
-
-[DEBUGM]
-Отладочное меню
-
-[DEC]
-Дек
-
-[DED_CRI]
-Убито преступников
-
-[DED_DED]
-Убито должников
-
-[DED_HOK]
-Убито шлюх
-
-[DEFDT]
---:---:---- --:--:--
-
-[DEFNAM]
-Клод----------------------
-
-[DEL_FNM]
-Файл удален.
-
-[DETON]
-ВЗРЫВ ЧЕРЕЗ:
-
-[DIAB1]
-'ГОНКА'
-
-[DIAB1_1]
-~g~3..2..1.. СТАРТ!
-
-[DIAB1_2]
-~g~Поздравляем, ты победил с отличным результатом: ~1~ секунд.
-
-[DIAB1_3]
-~r~Куда тебе с нами тягаться, НЕУДАЧНИК!
-
-[DIAB1_4]
-~g~Найди быструю тачку, и приезжай на старт.
-
-[DIAB1_5]
-ВРЕМЯ:
-
-[DIAB1_A]
-Эль Бурро хочет предложить тебе одно дельце. Двигай к телефону в Хепберн Хейтс, если тебя это заинтересовало.
-
-[DIAB1_B]
-Это Эль Бурро из банды Дьяволов.
-
-[DIAB1_C]
-Не так уж ты и крут. Подойди к телефону, и возможно Эль Бурро предложит тебе работенку.
-
-[DIAB1_D]
-Ты новичок в городе, но на улицах о тебе уже ходят слухи.
-
-[DIAB1_E]
-Мы решили устроить гонку, которая начнется у старой школы, что у моста Каллахан.
-
-[DIAB1_F]
-Достань себе тачку получше, и если выиграешь гонку, получишь приз.
-
-[DIAB2]
-'СМЕРТЬ ОТ МОРОЖЕНОГО'
-
-[DIAB2_1]
-~g~Возьми дипломат в Харвуде.
-
-[DIAB2_2]
-~g~Найди фургон с мороженым.
-
-[DIAB2_3]
-~g~Припаркуй фургон с мороженым на пристани Атлантик.
-
-[DIAB2_4]
-~g~Понажимай ~w~~k~~VEHICLE_HORN~~g~ чтобы включить на фургоне колокольчик.
-
-[DIAB2_5]
-~g~Выйди из фургона и затем с помощью дистанционника взорви его.
-
-[DIAB2_6]
-~g~Понажимай ~w~~k~~VEHICLE_HORN~~g~ чтобы включить на фургоне колокольчик.
-
-[DIAB2_7]
-~g~Понажимай ~w~~k~~VEHICLE_HORN~~g~ чтобы включить колокольчик на фургоне.
-
-[DIAB2_A]
-Когда я начал свой экзотический бизнес, моим единственным активом было содержимое моих кожаных штанов!
-
-[DIAB2_B]
-Одна банда стала угрожать, что лишит меня этой штуки, если я не буду отстегивать им процент.
-
-[DIAB2_C]
-Они не с тем связались, амиго.
-
-[DIAB2_D]
-Эти кретины западают на мороженое.
-
-[DIAB2_E]
-Возьми бомбу, что я спрятал в Харвуде,
-
-[DIAB2_F]
-и угони фургон с мороженым, что катается по городу.
-
-[DIAB2_G]
-Эти глупцы побегут на верную смерть, услышав колокольчик фургона.
-
-[DIAB2_H]
-Они прячутся на складе пристани Атлантик.
-
-[DIAB3]
-'ИСПЫТАНИЕ ОГНЕМ'
-
-[DIAB3_1]
-УБЕЙ 25 ТРИАДОВЦЕВ
-
-[DIAB3_A]
-Какой-то наглый триадовец прошлой ночью спер мою тачку,
-
-[DIAB3_B]
-разбил ее и бросил догорать.
-
-[DIAB3_C]
-В багажнике было несколько моих любимых безделушек -
-
-[DIAB3_D]
-настоящая гордость коллекционера, таких сейчас не достать.
-
-[DIAB3_E]
-Неподалеку от Чайнатауна я припрятал огнемет.
-
-[DIAB3_F]
-Возьми его и научи этих вандалов из Триады бояться грозного орудия Эль Бурро.
-
-[DIAB3_G]
-Арриба!
-
-[DIAB4]
-'ПОРНОКРАД'
-
-[DIAB4_1]
-~g~Подгони фургон на задний двор магазина порнухи.
-
-[DIAB4_A]
-Один слишком шустрый делец угнал фургон с последним тиражом моего издания!
-
-[DIAB4_B]
-Но этот обкурившийся кретин не закрыл дверцы фургона,
-
-[DIAB4_C]
-и теперь все мои прекрасные
-
-[DIAB4_D]
-порножурналы с изумительными фотографиями разбросаны по всему городу!
-
-[DIAB4_E]
-Садись в фургон и иди по следу 'Петушка из Портленда' выпусков 1, 2 и 3,
-
-[DIAB4_F]
-ну и собирай их заодно по пути.
-
-[DIAB4_G]
-Как только выследишь этого шустрого отморозка - разберись с ним!
-
-[DIAB4_H]
-Затем отгони мой фургон с грузом к сексшопу в квартале красных фонарей.
-
-[DIABLCR]
-Жеребец Дьяволов
-
-[DIABLO]
-ЗАДАНИЯ ДЬЯВОЛОВ
-
-[DLFILE]
-Удаление файлов игры GTA3
-
-[DODO]
-Додо
-
-[DODO_FT]
-Вы были в воздухе ~1~ секунд!
-
-[DRIVE_A] { re3 change }
-Садясь в машину, возьми в руки Узи. Посмотри вправо или влево и нажми ~h~~k~~VEHICLE_FIREWEAPON~~w~ для выстрела.
-
-[DRIVE_B] { re3 change }
-Садясь в машину, возьми в руки Узи. Посмотри вправо или влево и нажми ~h~~k~~VEHICLE_FIREWEAPON~~w~ для выстрела.
-
-[DSPLAY]
-Экран
-
-[DSTROFF]
-Debug Streaming Requests Off
-
-[DSTRON]
-Debug Streaming Requests On
-
-[EASTBAY]
-Портланд Бич
-
-[EBAL]
-'НА СВОБОДУ'
-
-[EBAL_1]
-Нажми ~h~~k~~VEHICLE_ENTER_EXIT~~w~, чтобы ~h~сесть за руль ~w~или ~h~выйти~w~ из машины.
-
-[EBAL_1B]
-Нажми ~h~~k~~VEHICLE_ENTER_EXIT~~w~, чтобы ~h~сесть за руль ~w~или ~h~выйти~w~ из машины.
-
-[EBAL_2]
-~g~Возвращайся в машину!
-
-[EBAL_3]
-Это ~h~радар~w~. Он очень полезен для навигации в городе. Сейчас ~h~цветная отметка~w~ на нем показывает расположение укрытия!
-
-[EBAL_4]
-~r~Лысый погиб!
-
-[EBAL_5]
-~g~Достань тачку!
-
-[EBAL_6]
-~g~Подбери Мисти!
-
-[EBAL_A]
-Я знаю место на углу квартала Красных фонарей, где мы сможем залечь,
-
-[EBAL_A1]
-но я хреновый водитель, так что, браток, лучше садись ты за руль.
-
-[EBAL_B]
-Вот и приехали. Давай зайдем внутрь и сменим эти чертовы шмотки!
-
-[EBAL_D]
-Я знаю одного парня с большими связями, его зовут Луиджи.
-
-[EBAL_D1]
-Я с ним работал раньше, так что, может, он и тебе работенку подкинет. Давай, съездим к нему.
-
-[EBAL_E]
-Давай, пошли, я тебя представлю.
-
-[EBAL_G]
-Это клуб Луиджи. Давай не будем светиться и пройдем через черный ход.
-
-[EBAL_H]
-Погоди меня тут, пока я схожу и потолкую с Луиджи.
-
-[EBAL_I]
-Босс решил выйти и взглянуть на тебя...
-
-[EBAL_J]
-У Лысого какие-то дела там наверху.
-
-[EBAL_K]
-Сделай мне одолжение, парень.
-
-[EBAL_L]
-Одной из моих девиц нужно прокатиться, так что бери тачку, забирай Мисти из клиники и вези сюда.
-
-[EBAL_M]
-Запомни, никто не лапает моих девок!
-
-[EBAL_N]
-Так что держи свои руки на баранке!
-
-[EBAL_O]
-Если не завалишь это дело, то может найтись и другая работенка. Все, проваливай!
-
-[ELBURRO]
-Лучший результат в гонке (сек)
-
-[EMVHPUP]
-Мы заплатим хорошие бабки за старые и новые машины скорой помощи. Подгони их к крану на северо-востоке порта Портланда.
-
-[END_A]
-Жители Кедровой рощи едва успели оправиться
-
-[END_B]
-от шока, вызванного настоящей криминальной войной,
-
-[END_C]
-всполошившей вчера весь район.
-
-[END_D]
-Местный житель Клив Денвер рассказал полиции,
-
-[END_E]
-что видел, как с места происшествия убегал бандит и какая-то брюнетка.
-
-[END_F]
-Ой, ты знаешь, нам будет так клево, потому что, ну... знаешь,
-
-[END_G]
-я люблю тебя, я, я, я правда люблю, потому что ты такой крутой сильный мужик
-
-[END_H]
-и ты именно тот, кто мне нужен.
-
-[END_I]
-Ой, о чем это я?
-
-[END_J]
-Ну вот, я забыла. Но ты понял, что я имела в виду, правда?
-
-[END_K]
-Люди бросились в укрытия, когда взрывы стали сотрясать ближайшие дома.
-
-[END_L]
-Несколько жителей пострадало во время ожесточенной перестрелки
-
-[END_M]
-между бандитами и вертолетом, кружившим над плотиной.
-
-[END_N]
-Да, из садов открывался отличный вид на это зрелище!
-
-[END_O]
-Когда вертолет наконец сбили,
-
-[END_P]
-был фейерверк получше, чем на Четвертое июля!
-
-[END_Q]
-Хотя найдено уже более двадцати тел,
-
-[END_R]
-полиция все еще находит останки.
-
-[END_S]
-Мы не получили официального опровержения слухов, о том,
-
-[END_T]
-что все тела принадлежат членам колумбийского Картеля.
-
-[END_U]
-Истинные причины этой бойни до сих пор неизвестны.
-
-[END_V]
-Представляешь, я сломала ноготь и испортила прическу!
-
-[END_W]
-А она обошлась мне в пятьдесят баксов...
-
-[ENFORCR]
-Энфорсер
-
-[ENGLIS]
-English
-
-[ESPERAN]
-Эсперанто
-
-[EVID]
-УЛИКИ:
-
-[FARE1]
-~g~Едем в ~w~'Клуб секс кошечек' ~g~в Квартале красных фонарей.
-
-[FARE10]
-~g~Едем в ~w~'Лапшу по-китайски' ~g~в Чайнатауне.
-
-[FARE11]
-~g~Едем на ~w~строительную площадку ~g~в форте Стаунтон.
-
-[FARE12]
-~g~Едем на ~w~футбольный стадион ~g~на Аспатрии.
-
-[FARE13]
-~g~Едем в ~w~церковь ~g~в Бедфорд Поинт.
-
-[FARE14]
-~g~Едем в ~w~казино ~g~в Торрингтоне.
-
-[FARE15]
-~g~Едем к ~w~зданию университета ~g~в учебном городке.
-
-[FARE16]
-~g~Едем в ~w~торговый комплекс ~g~в в Районе парка Бельвиль.
-
-[FARE17]
-~g~Едем в ~w~музей ~g~в Ньюпорте.
-
-[FARE18]
-~g~Едем к ~w~зданию 'Амко' ~g~в Торрингтоне.
-
-[FARE19]
-~g~Едем в ~w~'Болт Бургер' ~g~в Бедфорд Поинт.
-
-[FARE2]
-~g~Едем в ~w~'Сюпа Сейв' ~g~на Портланд Вью.
-
-[FARE20]
-~g~Едем в ~w~парк ~g~в Бельвиле.
-
-[FARE21]
-~g~Едем в ~w~аэропорт Фрэнсис~g~.
-
-[FARE22]
-~g~Едем к ~w~плотине Кокрейн~g~.
-
-[FARE23]
-~g~Едем к ~w~автосалону ~g~ рядом с плотиной Кокрейн.
-
-[FARE24]
-~g~Едем в ~w~больницу ~g~в Пайк Крик.
-
-[FARE25]
-~g~Едем в ~w~парк ~g~в Шорсайд Вейл.
-
-[FARE26]
-~g~Едем к ~w~Северо-западным башням ~g~в Садах Вичита.
-
-[FARE3]
-~g~Едем к ~w~старой школе ~g~в Чайнатауне.
-
-[FARE4]
-~g~Едем в ~w~'Кафе Грейзи Джо' ~g~на мысе Каллахан.
-
-[FARE5]
-~g~Едем в ~w~оружейный магазин ~g~в квартале красных фонарей.
-
-[FARE6]
-~g~Едем в ~w~'Автомобили в кредит' ~g~на Сент-Марк.
-
-[FARE7]
-~g~Едем в ~w~'Топлесс-Бар Вуди' ~g~в квартале красных фонарей.
-
-[FARE8]
-~g~Едем в ~w~бистро Марко ~g~на Сент-Марк.
-
-[FARE9]
-~g~Едем в ~w~Автосалон ~g~в гавани Портланда.
-
-[FARES]
-ОТВЕЗЕНО:
-
-[FBICAR]
-Машина ФБР
-
-[FEA_2SP]
-ДВЕ КОЛОНКИ
-
-[FEA_3DH]
-СПОСОБ ВЫВОДА ЗВУКА
-
-[FEA_4SP]
-БОЛЬШЕ ДВУХ КОЛОНОК
-
-[FEA_DO]
-=
-
-[FEA_EAR]
-НАУШНИКИ
-
-[FEA_FM0]
-HEAD RADIO
-
-[FEA_FM1]
-DOUBLE CLEFF FM
-
-[FEA_FM2]
-JAH RADIO
-
-[FEA_FM3]
-RISE FM
-
-[FEA_FM4]
-LIPS 106
-
-[FEA_FM5]
-GAME FM
-
-[FEA_FM6]
-MSX FM
-
-[FEA_FM7]
-FLASHBACK 95.6
-
-[FEA_FM8]
-ПУСТОМЕЛЯ 109
-
-[FEA_FM9]
-ПРОИГРЫВАТЕЛЬ MP3
-
-[FEA_LE]
-<
-
-[FEA_MNO]
-Моно
-
-[FEA_MUS]
-ГРОМКОСТЬ МУЗЫКИ
-
-[FEA_NAH]
-НЕТ ЗВУКОВОЙ КАРТЫ
-
-[FEA_NON]
-Нет
-
-[FEA_OUT]
-Выход:
-
-[FEA_RI]
->
-
-[FEA_RSS]
-РАДИОСТАНЦИЯ
-
-[FEA_SFX]
-ГРОМКОСТЬ ЗВУКОВ
-
-[FEA_SPK]
-ТИП АКУСТИКИ
-
-[FEA_ST]
-Стерео
-
-[FEA_UP]
-;
-
-[FEB]
-Фев
-
-[FEB_AUD]
-Аудио
-
-[FEB_BRI]
-Сообщения
-
-[FEB_CON]
-Управление
-
-[FEB_CPC]
-Настройка управления
-
-[FEB_DIS]
-Экран
-
-[FEB_LAN]
-Язык
-
-[FEB_PMB]
-Задание предыдущей миссии:
-
-[FEB_SAV]
-Загрузить
-
-[FEB_STA]
-Статистика
-
-[FEC_ACC]
-Газ
-
-[FEC_ACL]
-Педаль газа
-
-[FEC_ATT]
-Удар или выстрел из оружия
-
-[FEC_BAC]
-Назад
-
-[FEC_BRA]
-Тормоз / Задний ход
-
-[FEC_BRK]
-Педаль тормоза
-
-[FEC_BSP]
-ЗАБОЙ
-
-[FEC_CAM]
-Расположение камеры
-
-[FEC_CAW]
-Оружие в машине
-
-[FEC_CCM]
-Поставить камеру сзади игрока.
-
-[FEC_CEN]
-Центровка камеры
-
-[FEC_CLE]
-Прокрутка оружия влево
-
-[FEC_CLK]
-CAPSLOCK
-
-[FEC_CMM]
-Общее управления
-
-[FEC_CMP]
-ВМЕСТЕ: ВЗГЛЯД ВЛЕВО + ВЗГЛЯД ВПРАВО
-
-[FEC_CMR]
-Выбор позиции камеры
-
-[FEC_CMS]
-Изменение расположения камеры для всех вариантов.
-
-[FEC_CNT]
-Тип управления:
-
-[FEC_CRD]
-Перебор радиостанций
-
-[FEC_CRI]
-Прокрутка оружия вправо
-
-[FEC_CWL]
-Прокрутка оружия влево
-
-[FEC_CWR]
-Прокрутка оружия вправо
-
-[FEC_DBG]
-ОТЛАДОЧНОЕ МЕНЮ
-
-[FEC_DLF]
-Удаление невозможно.
-
-[FEC_DLL]
-DEL
-
-[FEC_DOT]
-ДОП.
-
-[FEC_DWA]
-СТРЕЛКА ВНИЗ
-
-[FEC_EEX]
-В машину /Из машины
-
-[FEC_EMS]
-Эту клавишу назначить нельзя.
-
-[FEC_END]
-END
-
-[FEC_ENT]
-В машину /Из машины
-
-[FEC_ENV]
-Сесть в машину
-
-[FEC_ESR]
-Клавишу ESC задавать нельзя
-
-[FEC_ETR]
-ДОП ВВОД
-
-[FEC_EXV]
-В машину /Из машины
-
-[FEC_FIR]
-Выстрел
-
-[FEC_FNC]
-F~1~
-
-[FEC_FOR]
-Вперед
-
-[FEC_FPC]
-Вид от первого лица
-
-[FEC_FPO]
-Оружие человека
-
-[FEC_FPR]
-Управление от первого лица
-
-[FEC_FWS]
-ДОП /
-
-[FEC_GSL]
-Покачивание камеры при ходьбе:
-
-[FEC_HAB]
-Ручной тормоз
-
-[FEC_HBR]
-Ручной тормоз машины
-
-[FEC_HME]
-HOME
-
-[FEC_HND]
-Тормоз
-
-[FEC_HO3]
-Сигнал (кнопка L3)
-
-[FEC_HOR]
-Сигнал
-
-[FEC_HRN]
-Сигнал
-
-[FEC_IBT]
--
-
-[FEC_IRT]
-INS
-
-[FEC_IVH]
-Инвертирование мыши по горизонтали:
-
-[FEC_IVV]
-ИНВЕРТИРОВАНИЕ МЫШИ ПО ВЕРТИКАЛИ
-
-[FEC_JBO]
-ДЖ. ~1~
-
-[FEC_JMP]
-Прыжок
-
-[FEC_JOY]
-Джойстик
-
-[FEC_JUM]
-Прыжок
-
-[FEC_LAL]
-ЛЕВ.ALT
-
-[FEC_LB]
-Оглянуться назад
-
-[FEC_LB1]
-Взгляд
-
-[FEC_LB2]
-назад
-
-[FEC_LB3]
-Оглянуться назад
-
-[FEC_LBA]
-Оглянуться назад
-
-[FEC_LBC]
-Нажать взгляд Влево и Вправо.
-
-[FEC_LBH]
-Посмотреть назад
-
-[FEC_LCT]
-ЛЕВ.CTRL
-
-[FEC_LDN]
-Посмотреть вниз
-
-[FEC_LDU]
-Посмотреть вниз
-
-[FEC_LEF]
-Влево
-
-[FEC_LFA]
-СТРЕЛКА ВЛЕВО
-
-[FEC_LKL]
-Посмотреть влево
-
-[FEC_LKT]
-Зафиксировать цель
-
-[FEC_LL]
-Посмотреть налево
-
-[FEC_LLF]
-Взгляд налево из машины
-
-[FEC_LOF]
-Посмотреть вперед
-
-[FEC_LOL]
-Посмотреть налево
-
-[FEC_LOR]
-Посмотреть направо
-
-[FEC_LR]
-Посмотреть направо
-
-[FEC_LRG]
-Взгляд вправо из машины
-
-[FEC_LRT]
-Посмотреть вправо
-
-[FEC_LSF]
-ЛЕВ.SHIFT
-
-[FEC_LUD]
-Посмотреть вверх
-
-[FEC_LUN]
-Загрузка невозможна. Файл поврежден, пожалуйста удалите эту запись.
-
-[FEC_LUP]
-Посмотреть вверх
-
-[FEC_LWD]
-ЛЕВ.WIN
-
-[FEC_MIN]
-ДОП -
-
-[FEC_MOV]
-Движение
-
-[FEC_MSH]
-ЧУВСТВИТЕЛЬНОСТЬ МЫШИ
-
-[FEC_MSL]
-ЛЕВ.КН.МЫШИ
-
-[FEC_MSM]
-СРЕД.КН.МЫШИ
-
-[FEC_MSR]
-ПРАВ.КН.МЫШИ
-
-[FEC_MWB]
-КОЛЕСО МЫШИ ВНИЗ
-
-[FEC_MWF]
-КОЛЕСО МЫШИ ВВЕРХ
-
-[FEC_MXO]
-MXB1
-
-[FEC_MXT]
-MXB2
-
-[FEC_NA]
-НЕТ
-
-[FEC_NLK]
-NUMLOCK
-
-[FEC_NMN]
-ДОП ~1~
-
-[FEC_NTR]
-Следующая цель
-
-[FEC_NTT]
-Неизвестная клавиша
-
-[FEC_NTW]
-Разговор по сети
-
-[FEC_NUM]
-ДОП
-
-[FEC_NUS]
-НЕ ИСПОЛЬЗУЕТСЯ
-
-[FEC_NWE]
-Следующее оружие
-
-[FEC_OJS]
-Для каждого действия можно назначить лишь одну кнопку джойстика
-
-[FEC_OKK]
-О.К.
-
-[FEC_OMS]
-Для действия можно задать лишь одну кнопку мыши
-
-
-[FEC_ORR]
-или
-
-[FEC_PAD]
-Геймпад
-
-[FEC_PAS]
-Пауза
-
-[FEC_PAU]
-Пауза
-
-[FEC_PED]
-Управление героем
-
-[FEC_PFR]
-Выстрел из оружия
-
-[FEC_PGD]
-PGDN
-
-[FEC_PGU]
-PGUP
-
-[FEC_PJP]
-Прыжок
-
-[FEC_PLB]
-Взгляд назад.
-
-[FEC_PLS]
-ДОП +
-
-[FEC_PSB]
-BREAK
-
-[FEC_PSH]
-Выстрел
-
-[FEC_PSP]
-Бежать
-
-[FEC_PTL]
-Use LockTarget with Weapon Switch Left.
-
-[FEC_PTR]
-Use LockTarget with Weapon Switch Right.
-
-[FEC_PTT]
-Предыдущая цель
-
-[FEC_PWE]
-Предыдущее оружие
-
-[FEC_PWF]
-Идти вперед
-
-[FEC_PWL]
-Идти влево
-
-[FEC_PWR]
-Идти вправо
-
-[FEC_PWT]
-Движение относительно камеры
-
-[FEC_QUE]
-???
-
-[FEC_R3]
-(R3 button)
-
-[FEC_RAD]
-Радио
-
-[FEC_RAL]
-ПР.ALT
-
-[FEC_RCT]
-ПР.CTRL
-
-[FEC_RFA]
-СТРЕЛКА ВПРАВО
-
-[FEC_RIG]
-Вправо
-
-[FEC_RS3]
-Перебор радиостанций (L3 button)
-
-[FEC_RSC]
-Перебор радиостанций
-
-[FEC_RSF]
-ПР.SHIFT
-
-[FEC_RTN]
-ВВОД
-
-[FEC_RUN]
-Бежать
-
-[FEC_RWD]
-ПР.WIN
-
-[FEC_SFT]
-SHIFT
-
-[FEC_SGJ]
-Настройка джойстика
-
-[FEC_SLC]
-Slot is corrupted
-
-[FEC_SLK]
-SCROLL LOCK
-
-[FEC_SM3]
-Special mission trigger (R3 button)
-
-[FEC_SMS]
-Показывать указатель мыши
-
-[FEC_SMT]
-Вызов спецзадания
-
-[FEC_SPC]
-ПРОБЕЛ
-
-[FEC_SPN]
-Бежать
-
-[FEC_STR]
-ДОП ЗВЕЗДОЧКА
-
-[FEC_SUB]
-Задание доп. миссий
-
-[FEC_SVU]
-Запись не удалась.
-
-[FEC_SZI]
-Снайперский прицел +
-
-[FEC_SZO]
-Снайперский прицел -
-
-[FEC_TAB]
-TAB
-
-[FEC_TAR]
-Цель
-
-[FEC_TDO]
-Камера отладки ВЫКЛ.
-
-[FEC_TFD]
-Башню /Додо вниз
-
-[FEC_TFL]
-Башню влево
-
-[FEC_TFR]
-Башню вправо
-
-[FEC_TFU]
-Башню /Додо вверх
-
-[FEC_TGD]
-Toggle Pad Game/Debug
-
-[FEC_TLF]
-Следующая цель слева
-
-[FEC_TRG]
-Следующая цель справа
-
-[FEC_TSM]
-Задание доп. миссий
-
-[FEC_TSS]
-Записать картинку с экрана
-
-[FEC_TUC]
-Управление башней
-
-[FEC_TUL]
-Башню влево
-
-[FEC_TUR]
-Башню вправо
-
-[FEC_TWO]
-Можно задать не более двух клавиш.
-
-[FEC_UJS]
-Эту кнопку джойстика назначить нельзя.
-
-[FEC_UMS]
-Эту кнопку мыши назначить нельзя.
-
-[FEC_UNB]
-НЕ ЗАДАНО
-
-[FEC_UND]
-(НЕТ)
-
-[FEC_UPA]
-СТРЕЛКА ВВЕРХ
-
-[FEC_VEH]
-Управление машиной
-
-[FEC_VES]
-Управление машиной
-
-[FEC_WAR]
-Внимание!
-
-[FEC_WHL]
-Рулевое управление
-
-[FEC_WPN]
-Выстрел из оружия
-
-[FEC_WRC]
-WINCLICK
-
-[FEC_ZIN]
-Приблизить
-
-[FEC_ZOT]
-Отдалить
-
-[FEDL_WR]
-Deleting data. Please do not remove the Memory Card (PS2) in MEMORY CARD slot 1, reset or switch off the console.
-
-[FEDSAS2]
-<>-CHANGE SELECTION
-
-[FEDSAS3]
-- CHANGE SELECTION
-
-[FEDSAS4]
-;=<> - CHANGE SELECTION
-
-[FEDSSC1]
-;-FASTER SCROLLING
-
-[FEDSSC2]
-=-STOP SCROLLING
-
-[FEDS_AM]
-<>-CHANGE MENU
-
-[FEDS_AS]
-;=-CHANGE SELECTION
-
-[FEDS_BA]
-" button - BACK
-
-[FEDS_SB]
-/ button - SELECT " button - BACK
-
-[FEDS_SE]
-/ button - SELECT
-
-[FEDS_SM]
-L1,R1-CHANGE MENU
-
-[FEDS_SS]
-L1,R1-CHANGE SELECTION
-
-[FEDS_ST]
-START button - RESUME
-
-[FEDS_TB]
-НАЗАД
-
-[FEDS_XB]
-Выбор
-
-[FED_BRI]
-ЯРКОСТЬ
-
-[FED_CON]
-Подтвердите удаление записи
-
-[FED_DBG]
-Отладочное меню
-
-[FED_DFL]
-CTheScripts::DbgFlag
-
-[FED_DLS]
-Большая отладочная лампа переключена
-
-[FED_DLW]
-Идет удаление. Пожалуйста, подождите...
-
-[FED_DSR]
-Debug Streaming Requests
-
-[FED_LDW]
-Идет загрузка. Пожалуйста, подождите...
-
-[FED_LFL]
-Игру загрузить не удалось. Игра будет перезапущена.
-
-[FED_PAH]
-Parse Heap
-
-[FED_RCD]
-CCullZones::RecalculateCullZoneData
-
-[FED_RES]
-РАЗРЕШЕНИЕ ЭКРАНА
-
-[FED_RID]
-Reload IDE
-
-[FED_RIP]
-Reload IPL
-
-[FED_SCP]
-gbShowCollisionPolys
-
-[FED_SCR]
-Show Car Road Grups
-
-[FED_SCZ]
-Show Cull Zones
-
-[FED_SPR]
-Show Ped Road Groups
-
-[FED_SUB]
-СУБТИТРЫ
-
-[FED_TRA]
-ШЛЕЙФ ОТ ДВИЖУЩИХСЯ ОБЪЕКТОВ
-
-[FED_WIS]
-ШИРОКИЙ ЭКРАН
-
-[FEFD_WR]
-Formatting Memory Card (PS2) in MEMORY CARD slot 1. Please do not remove the Memory Card (PS2), reset or switch off the console.
-
-[FEF_AU1]
-Прибавьте громкости!
-
-[FEF_AU2]
-Выберите радиостанцию и звуковой эффект
-
-[FEF_BR1]
-Не знаете, что делать?
-
-[FEF_BR2]
-Прочтите тексты последних заданий, отсортированных по дате.
-
-[FEF_CO1]
-Вас не устраивает такой способ управления?
-
-[FEF_CO2]
-Выберите наиболее удобное для вас управление
-
-[FEF_DI1]
-Игра изменена!
-
-[FEF_DI2]
-Настройка игры под ваш телевизор
-
-[FEF_INT]
-ИНТЕРНЕТ
-
-[FEF_LA1]
-О чем ты, черт побери, говоришь?
-
-[FEF_LA2]
-Выбери такую манеру выражаться, какая тебя устроит.
-
-[FEF_LAN]
-ЛОКАЛЬНАЯ СЕТЬ
-
-[FEF_SA1]
-Борись за свое место в списке!
-
-[FEF_SA2]
-Загрузка и сохранение вашей игры
-
-[FEF_ST1]
-Кто тут у нас плохой?
-
-[FEF_ST2]
-Сколько ты вызвал аварий
-
-[FEG_MAP]
-КАРТА
-
-[FEG_PLY]
-ИГРОКИ
-
-[FEG_PNG]
-ПИНГ
-
-[FEG_SRV]
-СЕРВЕР
-
-[FEG_TYP]
-ТИП
-
-[FELD_WR]
-Loading data. Please do not remove the Memory Card (PS2) in MEMORY CARD slot 1, reset or switch off the console.
-
-[FELZ_FO]
-Memory Card (PS2) in MEMORY CARD slot 1 is unformatted.
-
-[FEL_ENG]
-АНГЛИЙСКИЙ
-
-[FEL_FRE]
-ФРАНЦУЗСКИЙ
-
-[FEL_GER]
-НЕМЕЦКИЙ
-
-[FEL_ITA]
-ИТАЛЬЯНСКИЙ
-
-[FEL_SPA]
-ИСПАНСКИЙ
-
-[FEM_CES]
-Check Every 0kB4 Save
-
-[FEM_CLI]
-Создание и загрузка иконок
-
-[FEM_CPD]
-Create copy protected mag directory
-
-[FEM_CRD]
-Create Root Dir
-
-[FEM_DBG]
-ОТЛАДКА
-
-[FEM_FFF]
-Fill First File with Guff
-
-[FEM_FRM]
-ОГРАНИЧЕНИЕ КОЛИЧЕСТВА КАДРОВ
-
-[FEM_HST]
-СОЗДАТЕЛЬ ИГРЫ
-
-[FEM_LOD]
-ДАЛЬНОСТЬ ПРОРИСОВКИ
-
-[FEM_MA0]
-Либерти Сити
-
-[FEM_MA1]
-Кв. красных фонарей
-
-[FEM_MA2]
-Чайнатаун
-
-[FEM_MA3]
-Башня
-
-[FEM_MA4]
-Канализация
-
-[FEM_MA5]
-Промышленный парк
-
-[FEM_MA6]
-Доки
-
-[FEM_MA7]
-Стаунтон
-
-[FEM_MAP]
-Выбор карты
-
-[FEM_MC2]
-Memory Card Menu 2
-
-[FEM_MCM]
-Memory Card Menu
-
-[FEM_MM]
-ГЛАВНОЕ МЕНЮ
-
-[FEM_MP]
-ИГРА ПО СЕТИ
-
-[FEM_NO]
-НЕТ
-
-[FEM_NON]
-НЕТ
-
-[FEM_OFF]
-ВЫКЛ
-
-[FEM_ON]
-ВКЛ
-
-[FEM_OPT]
-НАСТРОЙКИ
-
-[FEM_QT]
-ВЫХОД
-
-[FEM_RES]
-ВЕРНУТЬСЯ В ИГРУ
-
-[FEM_RMC]
-Register MemCard One
-
-[FEM_SL1]
-Ячейка 1 свободна
-
-[FEM_SL2]
-Ячейка 2 свободна
-
-[FEM_SL3]
-Ячейка 3 свободна
-
-[FEM_SL4]
-Ячейка 4 свободна
-
-[FEM_SL5]
-Ячейка 5 свободна
-
-[FEM_SL6]
-Ячейка 6 свободна
-
-[FEM_SL7]
-Ячейка 7 свободна
-
-[FEM_SL8]
-Ячейка 8 свободна
-
-[FEM_SOG]
-Save Only The Game
-
-[FEM_SP]
-ОДИН ИГРОК
-
-[FEM_STG]
-Запись игры
-
-[FEM_STS]
-Save The Game under GTA3 name
-
-[FEM_TD]
-Test Delete:
-
-[FEM_TFM]
-Test Format MemCard One
-
-[FEM_TL]
-Test Load:
-
-[FEM_TS]
-Test Save:
-
-[FEM_TUM]
-Test UnFormat MemCard One
-
-[FEM_VSC]
-СИНХРОНИЗАЦИЯ КАДРОВ
-
-[FEM_YES]
-ДА
-
-[FEN_CON]
-Подключение
-
-[FEN_GAM]
-Поиск игр
-
-[FEN_GNA]
-Имя игры:
-
-[FEN_NAM]
-Имя:
-
-[FEN_NCI]
-НЕТ СВЯЗИ С ИНТЕРНЕТОМ
-
-[FEN_NET]
-Сеть
-
-[FEN_PLA]
-Число игроков:
-
-[FEN_PLC]
-Цвет игрока
-
-[FEN_PLS]
-Настройки игрока
-
-[FEN_STA]
-НАЧАТЬ ИГРУ
-
-[FEN_TY0]
-Сражение
-
-[FEN_TY1]
-Партизанская война
-
-[FEN_TY2]
-Командный бой
-
-[FEN_TY3]
-Командная партизанская война
-
-[FEN_TY4]
-Кража денег
-
-[FEN_TY5]
-Захват флага
-
-[FEN_TY6]
-Крысиные гонки
-
-[FEN_TY7]
-Доминатор
-
-[FEN_TYP]
-Тип игры
-
-[FEN_UKH]
-Неизвестный сервер
-
-[FEN_UKM]
-Карта не найдена
-
-[FEN_UKT]
-Неизвестный тип игры
-
-[FEP_AUD]
-ЗВУК
-
-[FEP_BRI]
-СООБЩЕНИЯ
-
-[FEP_CON]
-УПРАВЛЕНИЕ
-
-[FEP_DIS]
-ЭКРАН
-
-[FEP_LAN]
-ЯЗЫК
-
-[FEP_SAV]
-ПРОДОЛЖИТЬ ИГРУ
-
-[FEP_STA]
-СТАТИСТИКА
-
-[FEQ_SRE]
-Вы точно решили выйти? Все что вы успели сделать после последнего сохранения будет потеряно. Выходим?
-
-[FEQ_SRW]
-Вы точно решили выйти из игры?
-
-[FESTDCM]
-Расстояние, пройденное на машине (м)
-
-[FESTDFM]
-Расстояние, пройденное пешком (м)
-
-[FEST_BB]
-Быстрые тачки - легкие деньги:
-
-[FEST_BD]
-Лучшее время деактивации бомбы
-
-[FEST_CC]
-Убито преступников во время работы полицейским
-
-[FEST_DC]
-Расстояние, пройденное на машине (миль)
-
-[FEST_DF]
-Расстояние, пройденное пешком (миль)
-
-[FEST_FE]
-Потушено пожаров
-
-[FEST_GC]
-Взорвано бандитских машин:
-
-[FEST_H0]
-Пройдено контрольных точек
-
-[FEST_H1]
-Драка с Дьяволами
-
-[FEST_H2]
-Мордобой с мафией
-
-[FEST_H3]
-Катастрофа в казино
-
-[FEST_H4]
-Разборка с растаманами
-
-[FEST_HA]
-Максимальный уровень заданий 'скорой'
-
-[FEST_LF]
-Лучшее время полета на Додо
-
-[FEST_LS]
-Спасено людей во время работы на 'скорой'
-
-[FEST_MP]
-Заданий выполнено
-
-[FEST_OO]
-из
-
-[FEST_R1]
-'Пэтриот Ралли' (сек)
-
-[FEST_R2]
-'Гонка в парке' (сек)
-
-[FEST_R3]
-Догнал! за (сек)
-
-[FEST_RM]
-'Гонка по гаражу' (сек)
-
-[FEST_RP]
-Схваток завершено
-
-[FESZ_CA]
-Отмена
-
-[FESZ_FF]
-Format Failed! Check Memory Card (PS2) in MEMORY CARD slot 1 and please try again.
-
-[FESZ_FM]
-Memory Card (PS2) in MEMORY CARD slot 1 is unformatted. Would you like to format Memory Card (PS2) in MEMORY CARD slot 1?
-
-[FESZ_FO]
-Would you like to format the Memory Card (PS2) in MEMORY CARD slot 1?
-
-[FESZ_L1]
-Игра успешно сохранена!
-
-[FESZ_L2]
-Игра сохранена в файле:
-
-[FESZ_LS]
-Загрузка завершена.
-
-[FESZ_OK]
-OK
-
-[FESZ_OW]
-Overwriting data. Please do not remove the Memory Card (PS2) in MEMORY CARD slot 1, reset or switch off the console.
-
-[FESZ_QD]
-Вы точно решили удалить эту запись игры?
-
-[FESZ_QF]
-Are you sure you wish to format the Memory Card (PS2) in MEMORY CARD slot 1?
-
-[FESZ_QL]
-Все что вы успели сделать после последнего сохранения будет потеряно. Вы точно решили загрузить сохраненную игру?
-
-[FESZ_QO]
-Вы решили записать игру на место предыдущей записи?
-
-[FESZ_QR]
-Вы точно решили начать новую игру? Все что вы успели сделать после последнего сохранения будет потеряно. Начнем?
-
-[FESZ_QS]
-ЗАПИСАТЬ ИГРУ ?
-
-[FESZ_QU]
-Выход
-
-[FESZ_QZ]
-Вы уверены, что хотите сохранить игру?
-
-[FESZ_SA]
-Запись игры
-
-[FESZ_SR]
-Save Failed! Check Memory Card (PS2) in MEMORY CARD slot 1 and please try again.
-
-[FESZ_TI]
-SAVE Z1
-
-[FESZ_UC]
-ОТМЕНА
-
-[FESZ_WR]
-Saving data. Please do not remove the Memory Card (PS2) in MEMORY CARD slot 1, reset or switch off the console.
-
-[FES_AFO]
-This Memory Card (PS2) is already formatted.
-
-[FES_CAN]
-Отмена
-
-[FES_CGA]
-Доступные ячейки для сохранения:
-
-[FES_CSA]
-Выберите одежду из списка:
-
-[FES_DAT]
- ДАТА
-
-[FES_DEE]
-Deleting Failed! Check Memory Card (PS2) in MEMORY CARD slot 1 and please try again.
-
-[FES_DGA]
-УДАЛЕНИЕ ЗАПИСЕЙ
-
-[FES_GME]
-Error Reading Memory Card (PS2) in MEMORY CARD slot 1 please check and try again.
-
-[FES_ISC]
-ПОВРЕЖДЕН
-
-[FES_ISF]
-ОТСУТСТВУЕТ
-
-[FES_LCG]
-Продолжить игру с того места, где вы записались?
-
-[FES_LG]
-ЗАГРУЗКА ИГРЫ
-
-[FES_LGA]
-Загрузить игру
-
-[FES_LOE]
-Load Failed! Check Memory Card (PS2) in MEMORY CARD slot 1 and please try again.
-
-[FES_LOF]
-Загрузка не удалась.
-
-[FES_NGA]
-Новая игра
-
-[FES_NOC]
-No Memory Card (PS2) in MEMORY CARD slot 1.
-
-[FES_NON]
-ВАРИАНТЫ ОДЕЖДЫ ОТСУТСТВУЮТ
-
-[FES_SAG]
-ИМЕЕТСЯ
-
-[FES_SCG]
-Сохранить текущую игру?
-
-[FES_SET]
-ПЕРЕОДЕТЬСЯ
-
-[FES_SG]
-НАЧАТЬ НОВУЮ ИГРУ
-
-[FES_SKN]
-НАЗВАНИЕ ОДЕЖДЫ
-
-[FES_SLO]
-ФАЙЛ ЗАПИСИ
-
-[FES_SNG]
-НАЧАТЬ НОВУЮ ИГРУ
-
-[FES_SSC]
-Игра успешно сохранена.
-
-[FES_WAR]
-Идет запись, подождите...
-
-[FET_AMS]
-НАСТРОЙКА МЫШИ
-
-[FET_APL]
- ОК?
-
-[FET_APP]
-ЛЕВАЯ КНОПКА МЫШИ ИЛИ ВВОД ДЛЯ ПРИНЯТИЯ ИЗМЕНЕНИЙ
-
-[FET_AUD]
-НАСТРОЙКА ЗВУКА
-
-[FET_BRE]
-СООБЩЕНИЯ
-
-[FET_CAC]
-ДЕЙСТВИЯ
-
-[FET_CCN]
-УПРАВЛЕНИЕ: СТАНДАРТНОЕ
-
-[FET_CCR]
-В МАШИНЕ
-
-[FET_CFT]
-ПЕШКОМ
-
-[FET_CIG]
-ЗАБОЙ - УБРАТЬ КЛАВИШИ, ЛЕВАЯ КНОПКА МЫШИ ИЛИ ВВОД - ЗАДАТЬ
-
-[FET_CME]
-ТИП УПРАВЛЕНИЯ
-
-[FET_CON]
-СОЕДИНЕНИЕ
-
-[FET_CTI]
-СТАНДАРТНЫЙ ТИП УПРАВЛЕНИЯ
-
-[FET_CTL]
-НАСТРОЙКА УПРАВЛЕНИЯ
-
-[FET_DAM]
-ДИНАМИЧЕСКАЯ МОДЕЛЬ АКУСТИКИ
-
-[FET_DEF]
-СТАНДАРТНЫЕ НАСТРОЙКИ
-
-[FET_DG]
-УДАЛЕНИЕ ИГРЫ
-
-[FET_DIS]
-НАСТРОЙКА ДИСПЛЕЯ
-
-[FET_DSN]
-Обычная}одежда.bmp
-
-[FET_EIG]
-ДЛЯ ЭТОГО ДЕЙСТВИЯ НЕЛЬЗЯ ЗАДАТЬ КНОПКУ
-
-[FET_FG]
-НАЙТИ ИГРУ
-
-[FET_FIL]
-Фильтр
-
-[FET_GT]
-ТИП ИГРЫ
-
-[FET_HG]
-СОЗДАТЬ ИГРУ
-
-[FET_HRD]
-УСТАНОВЛЕНЫ СТАНДАРТНЫЕ НАСТРОЙКИ
-
-[FET_JG]
-Подключиться
-
-[FET_LAN]
-ВЫБОР ЯЗЫКА
-
-[FET_LG]
-ЗАГРУЗКА ИГРЫ
-
-[FET_MAP]
-ВЫБОР КАРТЫ
-
-[FET_MIG]
-ВЫБОР ПАРАМЕТРА СТРЕЛКАМИ ВЛЕВО, ВПРАВО И КОЛЕСИКОМ МЫШИ
-
-[FET_MP]
-ИГРА ПО СЕТИ
-
-[FET_MST]
-РУЛИТЬ МЫШЬЮ
-
-[FET_MTI]
-ЗАДАНИЕ ПАРАМЕТРОВ МЫШИ
-
-[FET_NG]
-НОВАЯ ИГРА
-
-[FET_NON]
-НЕТ ДОСТУПНЫХ ИГР
-
-[FET_OPT]
-НАСТРОЙКИ
-
-[FET_PAU]
-ПАУЗА В ИГРЕ
-
-[FET_PS]
-ВЫБОР ОДЕЖДЫ
-
-[FET_PSU]
-ВЫБОР ОДЕЖДЫ
-
-[FET_QG]
-ВЫХОД
-
-[FET_RDK]
-ЗАДАТЬ УПРАВЛЕНИЕ
-
-[FET_REF]
-Частота обновления
-
-[FET_RIG]
-ВЫБЕРИТЕ КНОПКУ ДЛЯ ЭТОГО ДЕЙСТВИЯ ИЛИ НАЖМИТЕ ESC ДЛЯ ОТМЕНЫ
-
-[FET_RSC]
-НЕВОЗМОЖНО УСТАНОВИТЬ ЭТОТ ПАРАМЕТР
-
-[FET_RSO]
-ВОССТАНОВЛЕНЫ СТАНДАРТНЫЕ НАСТРОЙКИ
-
-[FET_SAN]
-НАЧАТЬ НОВУЮ ИГРУ
-
-[FET_SCN]
-УПРАВЛЕНИЕ: ОБЫЧНОЕ
-
-[FET_SFG]
-ПОИСК ИГР...
-
-[FET_SG]
-СОХРАНЕНИЕ ИГРЫ
-
-[FET_SGA]
-НАЧАТЬ ИГРУ
-
-[FET_SNG]
-НАЧАТЬ НОВУЮ ИГРУ
-
-[FET_SP]
-ОДИН ИГРОК
-
-[FET_SRT]
-СОРТИРОВКА ИГР...
-
-[FET_STA]
-СТАТИСТИКА
-
-[FET_STI]
-ОБЫЧНЫЙ ТИП УПРАВЛЕНИЯ
-
-[FE_INIP]
-Инициализация и загрузка меню... Подождите.
-
-[FIL_FLT]
-ФИЛЬТР СПИСКА ИГР
-
-[FIL_MAP]
-Карта:
-
-[FIL_PNG]
-Пинг:
-
-[FIL_SPC]
-Доступна игра одному?
-
-[FIL_SRV]
-Создатель:
-
-[FIL_TYP]
-Тип игры:
-
-[FIRETRK]
-Пожарная
-
-[FIRE_M]
-'ПОЖАРНЫЙ'
-
-[FIRE_WS]
-Пожарник погиб
-
-[FIRST]
-~g~первый
-
-[FLASHB]
-Flashback FM
-
-[FLATBED]
-Флетбед
-
-[FLFSGF]
-Fill First File With Guff
-
-[FM1]
-'ПРОГУЛКА'
-
-[FM1_1]
-~g~Вернись назад в Стретч!
-
-[FM1_10]
-~g~Ты проехал мимо Марии, возвращайся и посади ее в машину.
-
-[FM1_2]
-~g~Залезай в Стретч!
-
-[FM1_3]
-~r~Вернись за Марией, иначе Сальваторе с тобой рассчитается.
-
-[FM1_4]
-~g~Ты бросил дочь дона! Возвращайся на склад и жди Марию!
-
-[FM1_5]
-~g~Отвези Марию назад к Сальваторе!
-
-[FM1_6]
-~g~Чико не будет ждать вечно! Отвези Марию на берег!
-
-[FM1_7]
-~r~Мария мертва! Сальваторе это не понравится...
-
-[FM1_8]
-~r~Ты замочил дилера Марии!
-
-[FM1_9]
-~g~Там какая-то гулянка, высади Марию неподалеку.
-
-[FM1_A]
-~w~Мне с приятелями нужно поговорить о деле,
-
-[FM1_AA]
-~w~Я лучше пойду. Надеюсь, увидимся попозже.
-
-[FM1_B]
-~w~Этим вечером тебе придется присматривать за моей девочкой.
-
-[FM1_C]
-~w~ЭЙ МАРИЯ! ПОДНИМАЙ СВОЮ ЗАДНИЦУ!
-
-[FM1_D]
-~w~Эту глупую девку постоянно приходится звать.
-
-[FM1_E]
-~w~А вот и она, единственная и неповторимая королева красоты!
-
-[FM1_F]
-~w~Чем ты там занималась?
-
-[FM1_G]
-~w~Наверняка просаживала мои деньги.
-
-[FM1_H]
-~w~Ну ты же не хочешь, чтобы я крутилась тут и мешала вашему разговору?
-
-[FM1_I]
-~w~Заткнись и иди в машину.
-
-[FM1_J]
-~w~Возьми мой лимузин, но верни его в целости и сохранности, понял?
-
-[FM1_K]
-~w~И смотри чтобы она не влипла в историю.
-
-[FM1_L]
-~w~Да, да, да! Я думаю, твой новый пес может обо мне позаботиться -
-
-[FM1_M]
-~w~вон он какой здоровый.
-
-[FM1_N]
-~w~Эй, Тузик, давай разживемся гостинцами у Чико!
-
-[FM1_O]
-~w~Я думаю, он где-то на железнодорожной станции, у берега Чайнатауна.
-
-[FM1_P]
-~g~А вот и Чико, давай рули к нему.
-
-[FM1_Q]
-~w~Привет, Мария! Прелесть моя!
-
-[FM1_Q1]
-~w~Хочешь поразвлечься? Ну немного... а? Может СПАНКа?
-
-[FM1_R]
-~w~Привет, Чико. Нет, я как обычно.
-
-[FM1_S]
-~w~Держи, золотце.
-
-[FM1_S1]
-~w~Эй, может ты заглянешь ко мне на вечеринку на складе к востоку от пристаней Атлантик.
-
-[FM1_SS]
-~r~РАЦИЯ: ~g~Четыре-пять всем подразделениям: Требуется помощь в облаве на наркоторговцев у пристаней Атлантик...
-
-[FM1_T]
-~w~Спасибо Чико. До скорого.
-
-[FM1_TT]
-~w~ЭТО ОБЛАВА!
-
-[FM1_U]
-~w~Благодарствую, наслаждайтесь. Это хороший товар.
-
-[FM1_V]
-~w~Давай, Тузик, скатаемся на его вечеринку!
-
-[FM1_W]
-~w~Хорошо, Тузик, присматривай за тачкой и жди меня, а я пока пойду подвигаю попой.
-
-[FM1_X]
-~w~Эй, Тузик, давай сматываться отсюда. Ихууу!
-
-[FM1_Y]
-~w~Знаешь, я уже давно так не веселилась, и ты хорошо со мной обращался. С уважением и все такое.
-
-[FM2]
-'СТРИЖКА ТРАВЫ'
-
-[FM21]
-'БОМБА НА БАЗЕ: ЧАСТЬ I'
-
-[FM2_1]
-~g~А вот и Кудрявый Боб!
-
-[FM2_10]
-~r~Кудрявый слинял!
-
-[FM2_11]
-~g~Встань у клуба Луиджи, Кудрявый Боб скоро выйдет.
-
-[FM2_12]
-~r~Он улизнул от тебя!
-
-[FM2_14]
-~r~Ты подошел слишком близко к Кудрявому и спугнул его!
-
-[FM2_15]
-~g~Не приближайся к Кудрявому, а то он заподозрит неладное!
-
-[FM2_16]
-ИСПУГ БОБА:
-
-[FM2_2]
-~g~Кудрявый вышел из клуба, начинай следить!
-
-[FM2_5]
-~g~Отвези его в гавань Портланда.
-
-[FM2_6]
-~r~Кудрявый не сядет в разбитое такси!
-
-[FM2_7]
-~r~Кудрявый испугался! Оне не пойдет на встречу!
-
-[FM2_8]
-~g~Разделайся с Кудрявым Бобом!
-
-[FM2_9]
-~r~Кудрявый Боб мертв!
-
-[FM2_A]
-Колумбийский картель производит СПАНК где-то в городе,
-
-[FM2_B]
-У нас завелась крыса!
-
-[FM2_C]
-Телками или дурью он не торгует - значит, стучит.
-
-[FM2_F]
-А вот и наш дружок - мистер Болтун.
-
-[FM2_G]
-За тобой следили? Лучше, чтобы никто не знал про наш маленький секрет.
-
-[FM2_H]
-Нет..нет, за мной нет хвоста. Дурь у тебя?
-
-[FM2_I]
-Вот твой СПАНК, нытик, теперь выкладывай.
-
-[FM2_J]
-Оставь нас одних, нам нужно поговорить.
-
-[FM2_K]
-но мы не знаем где, а вот они, похоже, знают о каждом нашем шаге, еще до того как мы его сделаем.
-
-[FM2_L]
-Есть один парень - Кудрявый Боб, он работает в баре у Луиджи.
-
-[FM2_M]
-Он тратит больше бабок, чем зарабатывает.
-
-[FM2_N]
-Домой он обычно ездит на такси. Выследи его,
-
-[FM2_O]
-и, если он и есть та самая крыса... прикончи его.
-
-[FM2_P]
-В общем, так: семья Леоне воюет на два фронта.
-
-[FM2_Q]
-Они дерутся за сферы влияния с Триадой, но пока ни одна из сторон не уступает.
-
-[FM2_R]
-А тем временем Джоуи Леоне пустил немного крови Форелли.
-
-[FM2_S]
-Каждый день они теряют людей и свое влияние в городе.
-
-[FM2_T]
-Сальваторе становится опасным параноиком. Он всюду видит одни заговоры.
-
-[FM2_U]
-С такими преданными людьми, как ты, ему не о чем беспокоиться.
-
-[FM3]
-'БОМБА НА БАЗЕ: ЧАСТЬ II'
-
-[FM3_4]
-~g~Останови тачку и дай Лысому выйти!
-
-[FM3_7]
-~r~Лысого замочили!
-
-[FM3_8]
-~r~Охранники подняли тревогу!
-
-[FM3_8A]
-~w~Здорово, друган! Сальваторе мне уже звонил.
-
-[FM3_8B]
-~w~Для этой работенки потребуется много взрывчатки.
-
-[FM3_8C]
-~w~Мне нужно $100,000, чтобы покрыть расходы,
-
-[FM3_8D]
-~w~но ты же знаешь, что я отработаю каждый доллар.
-
-[FM3_8E]
-~w~Окей, давай провернем это дельце!
-
-[FM3_8F]
-~w~Я бы взорвал эту крошку, но пока еще не могу удержать оружие в руках.
-
-[FM3_8G]
-~w~Вот, это ружьишко поможет тебе снести несколько голов!
-
-[FM3_8I]
-~w~Займи удобную позицию, я пойду сразу, после твоего первого выстрела.
-
-[FM3_A]
-~w~Мы должны убрать этих колумбийских ублюдков,
-
-[FM3_B]
-~w~но эта война с Триадой сильно истощила наши ряды.
-
-[FM3_C]
-~w~У Картеля очень много зелени, полученной с продажи этого СПАНКа.
-
-[FM3_CC]
-~w~Браток, приходи, когда наскребешь бабок.
-
-[FM3_D]
-~w~Если мы пойдем в открытую атаку, то они просто размажут нас по стенке.
-
-[FM3_E]
-~w~Похоже, они производят СПАНК на том большом корабле, к которому тебя вывел Кудрявый.
-
-[FM3_F]
-~w~Так что нам придется пораскинуть мозгами. Твоими мозгами.
-
-[FM3_G]
-~w~Я, Сальваторе Леоне, лично прошу тебя сделать мне одолжение и уничтожить эту фабрику по производству СПАНКа.
-
-[FM3_H]
-~w~Если ты провернешь для меня это дело - проси все что пожелаешь.
-
-[FM3_I]
-~w~Иди к Лысому. Без его помощи тебе эту работу не сделать.
-
-[FM4]
-'ПОСЛЕДНЯЯ ПРОСЬБА'
-
-[FM4_1]
-Это Мария. Эта машина - ловушка! Давай встретимся южнее моста Каллахан.
-
-[FM4_2]
-Послушай, Сальваторе думает что мы за его спиной крутим роман,
-
-[FM4_3]
-поэтому он заключил с картелем сделку и заложил тебя.
-
-[FM4_4]
-Я не могла этого допустить, ведь тебя бы прикончили,
-
-[FM4_4B]
-и это была бы моя вина... потому что я сказала, что мы были вместе.
-
-[FM4_5]
-Я сама не знаю, почему я это ему сказала.
-
-[FM4_6]
-Похоже теперь за тобой будет охотиться мафия, да и за мной, видимо, тоже.
-
-[FM4_6B]
-Я уже устала от убийств. От этих рек крови!
-
-[FM4_7]
-Это моя хорошая знакомая, она старый друг... это Асука, она из тех, кому можно доверять.
-
-[FM4_8]
-Пошли, хватит распинаться.
-
-[FM4_9]
-Нам лучше убираться, пока здесь не появились наши старые друзья, которым уже нельзя доверять.
-
-[FM4_A]
-~w~А, мой лучший чистильщик.
-
-[FM4_B]
-~w~Я горжусь тобой, мальчик, ты выбил дерьмо из этих жирных свиней.
-
-[FM4_C]
-~w~Но выполни еще одно маленькое задание, прежде чем мы отпразднуем победу.
-
-[FM4_D]
-~w~Рядом с клубом Луиджи стоит одна машина.
-
-[FM4_E]
-~w~Внутри все залито кровью.
-
-[FM4_F]
-~w~Мы вправили одному парню мозги, но получилось не очень аккуратно.
-
-[FM4_H]
-~w~Отгони машину в утилизатор, чтобы не смущать копов.
-
-[FORMEN]
-Format Menu
-
-[FORMM1]
-FormatMemCard 1 (teststuff)
-
-[FOURTH]
-~g~четвертый
-
-[FRANGO]
-~g~Сальваторе хочет, чтобы ты сперва помог Тони разобраться с Триадой!
-
-[FRANK]
-ЗАДАНИЯ САЛЬВАТОРЕ
-
-[FRENCH]
-Французский
-
-[FTUTOR]
-Нажми кнопку ~h~~k~~TOGGLE_SUBMISSIONS~~w~, чтобы заняться работой пожарного, или отказаться от нее.
-
-[FTUTOR2]
-Нажми кнопку ~h~~k~~TOGGLE_SUBMISSIONS~~w~, чтобы заняться работой пожарного, или отказаться от нее.
-
-[F_CANC]
-~r~Задание пожарного прервано!
-
-[F_EXTIN]
-ПОЖАРЫ:
-
-[F_FAIL1]
-Задание не выполнено.
-
-[F_FAIL2]
-~r~Ты опоздал!
-
-[F_PASS1]
-Огонь потушен!
-
-[F_RANGE]
-~g~Рация в машине не ловит сигнал, подъедь поближе к пожарной части!
-
-[F_START]
-~g~Место возгорания машины: ~a~. Езжай и сбей огонь.
-
-[F_WASTE]
-Женщин убито
-
-[GAMEOVR]
-ИГРА ОКОНЧЕНА
-
-[GAMSET]
-Настройки игры
-
-[GAM_FM]
-Радио Game FM
-
-[GARAGE]
-Поставь машину в гараж и выйди наружу.
-
-[GARAGE1]
-~g~Вылазь из машины и выходи из гаража.
-
-[GA_1]
-Ух, ты! Я не трогал ничего БОЛЕЕ горячего!
-
-[GA_10]
-Отлично. Вот тебе ~1~ баксов.
-
-[GA_11]
-У нас уже есть такая тачка. Больше нам уже не нужно!
-
-[GA_12]
-Бомба активирована
-
-[GA_13]
-Отличная работа! Пригонишь остальные - получишь вознаграждение.
-
-[GA_14]
-Все тачки. КРУТО! Вот тебе за это.
-
-[GA_15]
-Надеюсь, тебе понравится этот цвет.
-
-[GA_16]
-Перекраска бесплатно.
-
-[GA_19]
-Нам такая колымага не нужна.
-
-[GA_1A]
-Возвращайся, когда будешь свободен...
-
-[GA_2]
-Машина отремонтирована и перекрашена. Теперь копы тебя не узнают!
-
-[GA_20]
-У нас этого хлама больше чем нужно. Прости, сделка не состоится.
-
-[GA_21]
-Больше в этот гараж поставить машин нельзя.
-
-[GA_3]
-Подарков больше не будет. Окраска стоит $1000!
-
-[GA_4]
-Установка бомбы в машину стоит $1000
-
-[GA_5]
-Я уже поставил в бомбу в эту тачку.
-
-[GA_6] { re3 change }
-Припаркуй тачку на место, нажми ~h~~k~~VEHICLE_FIREWEAPON~~w~ и ДЕЛАЙ НОГИ!
-
-[GA_6B] { re3 change }
-Припаркуй тачку на место, нажми ~h~~k~~VEHICLE_FIREWEAPON~~w~ и ДЕЛАЙ НОГИ!
-
-[GA_7] { re3 change }
-Включи бомбу, нажав на ~h~~k~~VEHICLE_FIREWEAPON~~w~. Бомба взорвется как только заведется мотор.
-
-[GA_7B] { re3 change }
-Включи бомбу, нажав на ~h~~k~~VEHICLE_FIREWEAPON~~w~. Бомба взорвется как только заведется мотор.
-
-[GA_8]
-Взорви бомбу с помощью детонатора.
-
-[GA_9]
-Ты собрал ~1~ из 10 особых тачек
-
-[GERMAN]
-German
-
-[GHOST]
-Призрак
-
-[GMLOAD]
-ПРОДОЛЖИТЬ ИГРУ
-
-[GMREST]
-Перезапуск игры
-
-[GMSAVE]
-СОХРАНЕНИЕ ИГРЫ
-
-[GMSTOR]
-Game Store
-
-[GMSVLQ]
-GAME SAVE-LOAD-QUIT
-
-[GNG_WST]
-Убито членов банд
-
-[GOAWAY]
-~g~Ты уже на задании!
-
-[GOBACK]
-GoBack
-
-[GORLEV]
-Уровень крови
-
-[GREN_1]
-Чем дольше ты держишь ~h~~k~~PED_FIREWEAPON~~w~, тем дальше ты бросишь гранату.
-
-[GREN_2]
-Чем дольше ты держишь ~h~~k~~PED_FIREWEAPON~~w~, тем дальше ты бросишь гранату.
-
-[GREN_3]
-Чем дольше ты держишь ~h~~k~~PED_FIREWEAPON~~w~, тем дальше ты бросишь гранату.
-
-[GTAB_A]
-Эй, давайте уберите это отсюда. Черт его знает, что это такое,
-
-[GTAB_B]
-но раз он так хотел это заполучить, то это, наверное, что-то ценное.
-
-[GTAB_C]
-Что за черт!
-
-[GTAB_D]
-ТЫ!
-
-[GTAB_E]
-Успокойся, амиго! Де нада! Де нада!
-
-[GTAB_F]
-Я порежу тебя и брошу в канаву истекать кровью!
-
-[GTAB_G]
-Не стреляй, амиго. Без базара. Мы все друзья. Вот, забирай.
-
-[GTAB_H]
-Не будь таким засранцем!
-
-[GTAB_I]
-У нас нет выбора, крошка!
-
-[GTAB_J]
-Выбор есть всегда, ты чертов ублюдок!
-
-[GTAB_K]
-Прости, это все эта бешеная сучка, это все она...пор фавор?
-
-[GTAB_L]
-Итак, этой сучки больше нет.
-
-[GTAB_M]
-Но ты оказал мне услугу,
-
-[GTAB_N]
-ты не единственный, у кого есть счеты с Картелем,
-
-[GTAB_O]
-эта мразь убила моего брата!
-
-[GTAB_P]
-Я никогда не убивал якудза!
-
-[GTAB_Q]
-ЛЖЕЦ. Мы все видели убийцу Картеля.
-
-[GTAB_R]
-Мы выследим и убьем всех вас, колумбийских собак!
-
-[GTAB_S]
-Я поиграю немного с твоим другом, чтобы получить информацию и доставить себе удовольствие.
-
-[GTAB_T]
-Я жду тебя позже, я уверена, мне понадобятся твои услуги.
-
-[GTAB_U]
-Пожалуйста, амиго, не оставляй меня с ней, она ненормальная! Друг? Эй, ДРУУУГ!!!... Аииииаааахххх!
-
-[GUN_1A]
-Для смены оружия используй ~h~~k~~PED_CYCLE_WEAPON_RIGHT~~w~ и ~h~~k~~PED_CYCLE_WEAPON_LEFT~.
-
-[GUN_2A]
-Держи ~h~~k~~PED_LOCK_TARGET~~w~, чтобы ~h~прицелиться~w~, а затем нажимай ~h~~k~~PED_FIREWEAPON~~w~, чтобы выстрелить! Потренируйся на мишенях...
-
-[GUN_2C]
-Держи ~h~~k~~PED_LOCK_TARGET~~w~, чтобы ~h~прицелиться~w~, а затем нажимай ~h~~k~~PED_FIREWEAPON~~w~, чтобы выстрелить! Потренируйся на мишенях...
-
-[GUN_2D]
-Держи ~h~~k~~PED_LOCK_TARGET~~w~ чтобы ~h~прицелиться~w~, а затем нажимай ~h~~k~~PED_FIREWEAPON~~w~ чтобы выстрелить! Потренируйся на мишенях...
-
-[GUN_3A]
-Чтобы сменить цель, удерживая ~h~~k~~PED_LOCK_TARGET~~w~, нажимай ~h~~k~~PED_CYCLE_TARGET_LEFT~~w~ или ~h~~k~~PED_CYCLE_TARGET_RIGHT~~w~.
-
-[GUN_3B]
-Чтобы сменить цель, удерживая ~h~~k~~PED_LOCK_TARGET~~w~, нажимай ~h~~k~~PED_CYCLE_TARGET_LEFT~~w~ или ~h~~k~~PED_CYCLE_TARGET_RIGHT~~w~.
-
-[GUN_4A]
-Когда ты держишь ~h~~k~~PED_LOCK_TARGET~~w~, то можешь ходить или бегать, не выпуская цель из перекрестия.
-
-[GUN_4B]
-Когда ты держишь ~h~~k~~PED_LOCK_TARGET~~w~, то можешь ходить или бегать, не выпуская цель из перекрестия.
-
-[GUN_5]
-Ты можешь попрактиковаться на этих мишенях в прицеливании и стрельбе. Как только закончишь - возвращайся к заданию.
-
-[HARWOOD]
-Харвуд
-
-[HEAD]
-Head Radio
-
-[HEALTH]
-ЦЕЛОСТНОСТЬ:
-
-[HEALTH1]
-Проваливай! Ты полностью здоров.
-
-[HEALTH2]
-Лечение не бесплатное.
-
-[HEALTH3]
-Сейчас я тебя подлатаю.
-
-[HEALTH4]
-Это будет стоить тебе $250.
-
-[HEAL_A]
-Твое ~h~здоровье~w~ отображается оранжевыми цифрами в верхнем правом углу экрана.
-
-[HEAL_B]
-Когда ты ~h~вырубаешься,~w~ тебя отвозят в ближайший госпиталь
-
-[HEAL_C]
-При этом ты теряешь все свое оружие и доктора берут с тебя немного денег за лечение.
-
-[HEAL_E]
-Во время игры ты найдешь способы, как подлечиться или сберечь свое здоровье.
-
-[HED_EX]
-Голов расколото
-
-[HELI]
-Вертолет
-
-[HELP1]
-Остановите машину в центре голубого круга.
-
-[HELP10]
-Эти значки показывают, насколько сильно стремление копов арестовать тебя.
-
-[HELP11]
-Чем больше этих значков, тем более усердно тебя преследует полиция.
-
-[HELP12]
-Войди в голубой круг, чтобы получить новое задание.
-
-[HELP13]
-Иногда тебе придется ехать по дорогам, которые не показаны на радаре.
-
-[HELP14]
-Чтобы подобрать оружие, тебе нужно к нему подойти. Сидя в машине, ты оружие не возьмешь.
-
-[HELP15]
-Когда ты без машины, то, нажав ~h~~k~~PED_LOOKBEHIND~~w~, можешь ~h~оглянуться назад~w~.
-
-[HELP2_A]
-Чтобы ~h~разогнаться~w~, держи ~h~кнопку /~w~ во время бега.
-
-[HELP3]
-Мчаться ты можешь лишь до тех пор, пока не устанешь.
-
-[HELP4_A]
-Чтобы ~h~поехать вперед~w~, держи кнопку ~h~ ~k~~VEHICLE_ACCELERATE~~w~.
-
-[HELP4_D]
-Push the~h~ right analog stick~w~ up to ~h~accelerate.
-
-[HELP5_A]
-Держи кнопку~h~ ~k~~VEHICLE_BRAKE~~w~, чтобы ~h~затормозить~w~, или ~h~поехать назад~w~ после того, как машина остановится.
-
-[HELP5_D]
-Pull the ~h~right analog stick~w~ back to ~h~brake~w~, or to ~h~reverse~w~ if the vehicle has stopped.
-
-[HELP6_A]
-Держи кнопку~h~ ~k~~VEHICLE_HANDBRAKE~~w~, чтобы воспользоваться ~h~ручным тормозом.
-
-[HELP6_C]
-Держи кнопку~h~ ~k~~VEHICLE_HANDBRAKE~~w~, чтобы воспользоваться ~h~ручным тормозом.
-
-[HELP6_D]
-Держи кнопку~h~ ~k~~VEHICLE_HANDBRAKE~~w~, чтобы воспользоваться ~h~ручным тормозом.
-
-[HELP7_A]
-Нажми и удерживай~h~ ~k~~PED_LOCK_TARGET~~w~ кнопку, чтобы ~h~прицелиться~w~ из снайперской винтовки.
-
-[HELP7_D]
-Нажми и удерживай~h~ ~k~~PED_LOCK_TARGET~~w~ кнопку, чтобы ~h~прицелиться~w~ из снайперской винтовки.
-
-[HELP8_A]
-Нажми ~h~ ~k~~PED_SNIPER_ZOOM_IN~~w~, чтобы ~h~увеличить ~w~ изображение или ~h~ ~k~~PED_SNIPER_ZOOM_OUT~~w~, чтобы ~h~уменьшить~w~ его при прицеливании из снайперской винтовки.
-
-[HELP8_B]
-Нажми ~h~ ~k~~PED_SNIPER_ZOOM_IN~~w~, чтобы ~h~увеличить ~w~ изображение или ~h~ ~k~~PED_SNIPER_ZOOM_OUT~~w~, чтобы ~h~уменьшить~w~ его при прицеливании из снайперской винтовки.
-
-[HELP9_A]
-Нажми ~h~ ~k~~PED_FIREWEAPON~~w~, чтобы ~h~выстрелить~w~ из снайперской винтовки.
-
-[HELP9_B]
-Нажми ~h~ ~k~~PED_FIREWEAPON~~w~, чтобы ~h~выстрелить~w~ из снайперской винтовки.
-
-[HELP9_C]
-Нажми ~h~ ~k~~PED_FIREWEAPON~~w~, чтобы ~h~выстрелить~w~ из снайперской винтовки.
-
-[HEL_DST]
-Сбито вертолетов
-
-[HEY]
-~g~Не ходи в одиночку, иди с компанией!
-
-[HEY2]
-~g~Не разделяйтесь, идите вместе!
-
-[HEY3]
-~g~Ты потерял своего напарника, вернись к Лысому!
-
-[HEY4]
-~g~Потеряешь Мисти - к Луиджи лучше не возвращайся! Иди и найди ее!
-
-[HEY5]
-~g~Для полного кайфа не хватает еще одной телки. Сгоняй за ней!
-
-[HEY6]
-~g~Твоя честь зависит от якудза Канбу. Ты должен защищать его!
-
-[HEY7]
-~g~Возможно стоит получше вооружиться. Иди и забери своего напарника!
-
-[HEY8]
-~g~Защита - это значит 'защищать Старого Азиата'!
-
-[HEY9]
-~g~Хочешь совет? Иди, встреться с напарником!
-
-[HJSTAT]
-Дальность: ~1~.~1~м Высота: ~1~.~1~м Переворотов: ~1~ Поворот на: ~1~_
-
-[HJSTATF]
-Дальность: ~1~ft Высота: ~1~ft Переворотов: ~1~ Поворот на: ~1~_
-
-[HJSTATW]
-Дальность: ~1~.~1~м Высота: ~1~.~1~м Переворотов: ~1~ Поворот на: ~1~_ И отличное приземление!
-
-[HJSTAWF]
-Дальность: ~1~ft Высота: ~1~ft Переворотов: ~1~ Поворот на: ~1~_ И отличное приземление!
-
-[HJ_DIS]
-ПРИЗ ЗА ДВОЙНОЙ БЕЗУМНЫЙ ТРЮК: $~1~
-
-[HJ_IS]
-ПРИЗ ЗА БЕЗУМНЫЙ ТРЮК: $~1~
-
-[HJ_PDIS]
-ПРИЗ ЗА ИДЕАЛЬНЫЙ ДВОЙНОЙ БЕЗУМНЫЙ ТРЮК: $~1~
-
-[HJ_PIS]
-ПРИЗ ЗА ИДЕАЛЬНЫЙ БЕЗУМНЫЙ ТРЮК: $~1~
-
-[HJ_PQIS]
-ПРИЗ ЗА ИДЕАЛЬНЫЙ ЧЕТВЕРНОЙ БЕЗУМНЫЙ ТРЮК: $~1~
-
-[HJ_PTIS]
-ПРИЗ ЗА ИДЕАЛЬНЫЙ ТРОЙНОЙ БЕЗУМНЫЙ ТРЮК: $~1~
-
-[HJ_QIS]
-ПРИЗ ЗА ЧЕТВЕРНОЙ БЕЗУМНЫЙ ТРЮК: $~1~
-
-[HJ_TIS]
-ПРИЗ ЗА ТРОЙНОЙ БЕЗУМНЫЙ ТРЮК: $~1~
-
-[HM1_1]
-~g~Прикончи 20 Пурпурных Девяток за 2 минуты 30 секунд.
-
-[HM1_2]
-~g~Возьми тачку, но не забывай, что из машины можно стрелять лишь из Узи!
-
-[HM1_3]
-~g~'Девятки' любят шататься в Садах Вичита.
-
-[HM1_A]
-Йо! Это ДиАйс из Красных Валетов!
-
-[HM1_B]
-Тут кое кто решил со мной поиграть.
-
-[HM1_C]
-У этих молодых панков, что заполонили весь город, головы забиты лишь СПАНком и оружием.
-
-[HM1_D]
-'Девятка' - это их знак, они придумали себе пурпурный флаг и готовы трясти им целыми днями...
-
-[HM1_E]
-Я хочу, чтобы ты показал этим малолетним ублюдкам, как работают профессионалы.
-
-[HM1_F]
-Будь поосторожней. На улицах могут оказаться Валеты, которые решат, что ты и их решил заодно мочкануть!
-
-[HM1_G]
-эти засранцы начинают теснить 'Валетов'.
-
-[HM1_H]
-Сделай так, чтобы этих Девяток здесь не было!
-
-[HM2_1] { re3 change }
-Используй радиоуправляемые машинки, чтобы подорвать броневики. Взрыв бомбы - ~h~~k~~VEHICLE_FIREWEAPON~~w~.
-
-[HM2_1A] { re3 change }
-Используй радиоуправляемые машинки, чтобы подорвать броневики. Взрыв бомбы - ~h~~k~~VEHICLE_FIREWEAPON~~w~.
-
-[HM2_2]
-~r~Ты так и не смог подорвать все броневики!
-
-[HM2_3]
-Если машинка стукнется о колесо, то она взорвется!
-
-[HM2_4]
-Если машинка окажется вне действия радиоуправления, то она взорвется!
-
-[HM2_5]
-~r~Вне зоны приема сигнала!
-
-[HM2_6]
-~g~Броневик уничтожен!
-
-[HM2_A]
-Эти Девятки достали меня.
-
-[HM2_B]
-Уроды раздобыли где-то броневики и развозят на них СПАНК...
-
-[HM2_C]
-и без страха впаривают его желающим.
-
-[HM2_D]
-Выше по улице припаркована тачка.
-
-[HM2_E]
-В ней для тебя я кое-что припас, чтобы ты смог проучить этих тупиц...
-
-[HM2_F]
-и раздолбать их бронированные игрушки.
-
-[HM3_1]
-~g~Двигай к гаражу, но смотри, если сильно помнешь тачку - она взорвется!
-
-[HM3_2]
-~g~Забирай тачку, теперь она в полном порядке!
-
-[HM3_3]
-~g~Отремонтируй тачку!
-
-[HM3_A]
-Какая-то сволочь установила мне бомбу в тачку.
-
-[HM3_B]
-Если я потеряю колеса, то лишусь своей репутации в районе.
-
-[HM3_C]
-Давай отгони мою колымагу в гараж на Сент-Марк, ты понял, йо.
-
-[HM3_D]
-Как снять бомбу - это уже пусть они сами думают.
-
-[HM3_E]
-Часы уже тикают, давай, гони.
-
-[HM3_F]
-Но учти, одного столкновения достаточно, чтобы взлететь на воздух.
-
-[HM3_G]
-Ну же, вперед!
-
-[HM4_1]
-~g~Отправляйся к месту крушения самолета, тебе нужно собрать не менее 30 слитков.
-
-[HM4_2]
-~g~Запомни, по мере заполнения тачка будет тяжелеть и хуже слушаться руля, съезди в гараж и вывали там груз.
-
-[HM4_A]
-Йо, рейсовый самолет, перевозящий федеральные деньги разбился в аэропорту Фрэнсис.
-
-[HM4_B]
-Слитки платины валяются по всей взлетной полосе.
-
-[HM4_C]
-Бери тачку и сопри, сколько сможешь.
-
-[HM4_D]
-~g~Возьми тачку!
-
-[HM4_E]
-TEXT NO LONGER REQUIRED
-
-[HM4_F]
-Ты можешь возить слитки в один из моих гаражей.
-
-[HM4_G]
-Эти слитки чертовски тяжелые и будут замедлять движение.
-
-[HM4_H]
-Так что не забывай почаще сваливать груз.
-
-[HM5_1]
-Йо, Айс сказал ты придешь. Правила просты. Только биты. Никаких пушек, никаких машин.
-
-[HM5_3]
-~r~Тебе же сказали, что можно пускать в ход лишь биту!
-
-[HM5_4]
-~r~Твой напарник мертв!
-
-[HM5_5]
-Эта драка для поднятия авторитета, ты въехал?
-
-[HM5_6]
-Пошли, расколем несколько черепушек...
-
-[HM5_A]
-Эти Девятки уже в полном дерьме...
-
-[HM5_B]
-но им не терпится поквитаться.
-
-[HM5_C]
-Они согласились прийти на разборку.
-
-[HM5_D]
-Их банда против нас двоих, или точнее...
-
-[HM5_E]
-вас двоих,
-
-[HM5_F]
-я с тобой идти не могу...
-
-[HM5_G]
-мне еще три месяца нельзя светиться, у меня условное,
-
-[HM5_H]
-ты уловил, о чем я?
-
-[HM5_I]
-Мой младшенький встретит тебя,
-
-[HM5_J]
-он и покажет, где намечается устроить разборку, успехов, сынок.
-
-[HM_1]
-'РАБОТА ДЛЯ УЗИ'
-
-[HM_2]
-'ИГРУШЕЧНАЯ ВОЙНА'
-
-[HM_3]
-'ТАЧКА С БОМБОЙ'
-
-[HM_4]
-'МАННА НЕБЕСНАЯ'
-
-[HM_5]
-'РАЗБОРКА'
-
-[HOOD]
-ЗАДАНИЯ КАПЮШОНОВ
-
-[HOOD1_A]
-Сними трубку телефона стоящего в Садах Вичита, и мы обсудим одно дело.
-
-[HOODGO]
-~g~Сейчас у Капюшонов нет заданий!
-
-[HOODSCR]
-Рампо XL Капюшонов
-
-[HORN]
-~g~Посигналь.
-
-[HORN1]
-Press the ~h~L3 button ~w~to activate the ~h~horn.
-
-[HORN2]
-Press the ~h~L1 button ~w~to activate the ~h~horn
-
-[HORN3]
-Press the ~h~R1 button ~w~to activate the ~h~horn
-
-[HOSPI_2]
-Рокфорд
-
-[IDAHO]
-Айдахо
-
-[IMPEXPP]
-Автосалон в Портланде. Есть заказы на различные машины. Подробности - на нашей доске объявлений.
-
-[IMPORT1]
-Выйди наружу и жди, когда тебе подадут тачку.
-
-[IND_ZON]
-Портланд
-
-[INFERNS]
-Инфернус
-
-[INSTUN]
-Обычный безумный трюк
-
-[IN_BOAT]
-~g~Без катера тебе это задание не выполнить!
-
-[IN_ROW]
-Приз за ~1~ ПОДРЯД! $~1~
-
-[IN_VEH]
-~g~Эй! Ты куда? Давай садись за руль!
-
-[IN_VEH2]
-~g~Без машины тебе это задание не выполнить!
-
-[ITALIA]
-Italian
-
-[JAILB_A]
-Утром полиция и служба спасения напряженно работали над устранением
-
-[JAILB_B]
-чрезвычайной ситуации, вызванной нападением на полицейский конвой.
-
-[JAILB_C]
-У нас пока нет никаких сведений ни о том, кого сегодня перевозили,
-
-[JAILB_D]
-ни о том, какая преступная группировка ответственна за это дерзкое нападение.
-
-[JAILB_E]
-Как обычно, ранним утром полицейский конвой покинул участок,
-
-[JAILB_F]
-чтобы перевезти заключенных в городскую тюрьму.
-
-[JAILB_G]
-Нападение произошло на мосту Каллахан.
-
-[JAILB_H]
-Большинство свидетелей преступления погибло при взрыве, который сильно повредил мост.
-
-[JAILB_I]
-Полиция полагает, что при взрыве также могли погибнуть
-
-[JAILB_J]
-и некоторые заключенные.
-
-[JAILB_K]
-Выяснение личностей сбежавших преступников осложнено
-
-[JAILB_L]
-из-за атаки хакеров, испортивших базу данных полиции.
-
-[JAILB_M]
-Мэр ОТДонован объяснил, что полиция
-
-[JAILB_N]
-*
-
-[JAILB_O]
-Из-за этой катастрофы район Портланда оказался изолирован от города,
-
-[JAILB_P]
-так как прокладка туннеля Портер все еще не завершена.
-
-[JAILB_Q]
-Ну же, открывайте!
-
-[JAILB_R]
-А, мистер членоголовый!
-
-[JAILB_S]
-Я бы мог спокойно тебя пристрелить.
-
-[JAILB_T]
-Вы еще об этом пожалеете.
-
-[JAILB_U]
-Эй, вы, давайте, смывайтесь.
-
-[JAILB_V]
-Либерти Сити был потрясен сегодняшним преступлением.
-
-[JAILB_W]
-Полиция считает, что это нападение - несомненно, дело рук профессионалов.
-
-[JAILB_X]
-По предварительным данным
-
-[JAN]
-Янв
-
-[JM1]
-'ПОСЛЕДНИЙ УЖИН ГУБАСТОГО'
-
-[JM1_1]
-~g~Отгони машину Форелли в гараж к Лысому, он на севере отсюда за 'Автомобилями в кредит'.
-
-[JM1_2]
-~g~Припаркуй тачку на стоянке у бистро Марко.
-
-[JM1_3]
-~g~Включи бомбу и быстрее сваливай!
-
-[JM1_4]
-~g~Ты помял тачку! Ее нужно отремонтировать!
-
-[JM1_5]
-~g~Ты не включил бомбу!
-
-[JM1_6]
-~g~Поставь машину так, как она стояла раньше.
-
-[JM1_7]
-~g~Закрой дверцу машины, а то он заподозрит неладное!
-
-[JM1_8A]
-~y~Эй, это мой главный работник!
-
-[JM1_8B]
-~y~Здесь все автоматизировано. Просто заезжай внутрь и жди, пока установят бомбу.
-
-[JM1_8C]
-~y~Вот, первый раз даром, но потом плати бабки.
-
-[JM1_A]
-Эй, мне скучно, может, потрахаемся?
-
-[JM1_B]
-Погоди, дорогуша, мне тут нужно одно дельце провернуть.
-
-[JM1_C]
-Для тебя, друг, есть одна работенка.
-
-[JM1_D]
-Братья Форелли забыли мне вернуть старый должок.
-
-[JM1_E]
-Надо бы преподать им хороший урок, чтоб все знали.
-
-[JM1_F]
-Губастый Форелли сейчас набивает пузо в бистро на Сент-Марк,
-
-[JM1_G]
-отгони его машину в гараж Лысого, тот что в Харвуде.
-
-[JM1_H]
-Ты же знаком с Лысым?
-
-[JM1_I]
-Как только он установит бомбу, верни машину туда, где взял.
-
-[JM1_J]
-Ну а потом тебе останется только наблюдать.
-
-[JM1_K]
-Но давай живее, толстяк не будет жрать вечно.
-
-[JM2]
-'ПРОЩАЙ, ЧАНКИ ЛИ ЧОНГ'
-
-[JM2_A]
-Чанки Ли Чонг толкает СПАНК новой банде из Колумбии... или Колорадо... или как там...
-
-[JM2_B]
-Короче, я не знаю точно, да это и не важно.
-
-[JM2_C]
-У него киоск с лапшой в центре Чайнатауна.
-
-[JM2_D]
-Лучше бы этот крысеныш лишь свою жратву толкал.
-
-[JM2_E]
-Я хочу, чтобы ты с ним разобрался!
-
-[JM2_F]
-Если тебе нужен ствол, зайди во двор оружейного магазина, который рядом с метро.
-
-[JM2_G]
-Знаешь, где этот магазинчик? Возьмешь там пистолет.
-
-[JM2_H]
-Да, не забывай, что Чайнатаун - территория Триады, будь там поосторожней.
-
-[JM3]
-'ОГРАБЛЕНИЕ ФУРГОНА'
-
-[JM3_1]
-~g~Отгони фургон в гараж.
-
-[JM3_2]
-~g~Тарань фургон до тех пор, пока не разобьешь его на 70%.
-
-[JM3_A]
-Мы решили грабануть инкассаторский фургон.
-
-[JM3_B]
-Он каждый день выезжает из Чайнатауна.
-
-[JM3_C]
-Пули его броню не возьмут, так что тебе придется таранить его своей тачкой
-
-[JM3_D]
-Хорошенько его помни, и сраный охранник сам его бросит.
-
-[JM3_E]
-Потом отгони его на склад в доках, а мои парни сделают все остальное.
-
-[JM3_F]
-Давай за работу. Фургон не будет вечно кататься по городу.
-
-[JM4]
-'ШОФЕР СИПРИАНИ'
-
-[JM4_10]
-Окей, парень. Сначала мы заглянем в прачечную в Чайнатауне, у меня там есть кое-какие дела.
-
-[JM4_11]
-Эти прачки не желают платить крыше.
-
-[JM4_12]
-И поаккуратней веди, Джоуи только что починил эту развалюху.
-
-[JM4_13]
-Не превращай ее снова в груду металла, окей?
-
-[JM4_2]
-Подожди здесь! Не глуши мотор, мало ли что может случиться.
-
-[JM4_3]
-Это засада Триады! Парень, сваливаем отсюда!
-
-[JM4_4]
-Триада думает, что может безнаказанно перейти мне дорогу, Триада, МНЕ!
-
-[JM4_5]
-Зайди ко мне попозже, зададим им работенку - отстирывать с одежды собственную кровь!
-
-[JM4_6]
-Эй, аккуратней! Я же тебе говорил.
-
-[JM4_7]
-~g~Отвези Тони в мамочкин ресторан.
-
-[JM4_8]
-~r~Тони загасили!
-
-[JM4_A]
-Да, я знаю, Тони, я все отрегулировал. Она прямо мурлычет, послушай сам.
-
-[JM4_B]
-О! А вот и тот парень, о котором я тебе говорил!
-
-[JM4_C]
-Познакомься. Этот парень не итальянец, и не механик, но с работой справляется.
-
-[JM4_D]
-Это Папс Капо, Тони Сиприани.
-
-[JM4_E]
-Хай, я Тони Сиприани.
-
-[JM4_F]
-Отвези его в мамочкин ресторан на Сент-Марк, хорошо?
-
-[JM4_G]
-И еще, зайди ко мне попозже, я планирую одно дельце и мне понадобится хороший водила.
-
-[JM5]
-'КАТАФАЛК СО СКУНСОМ'
-
-[JM5_1]
-~g~Отвези его в утилизатор!
-
-[JM5_2]
-~g~Это братья Форелли!
-
-[JM5_A]
-Прекрасно! Просто великолепно.
-
-[JM5_B]
-Отлично, с тобой-то я и хотел поговорить!
-
-[JM5_C]
-В-общем, у кафе рядом с мысом Каллахан стоит катафалк со жмуриком.
-
-[JM5_D]
-Один из братьев Форелли решил, что он слишком умный, ну и получил за это по заслугам.
-
-[JM5_E]
-Отвези его тело к утилизатору в Харвуд, ладно?
-
-[JM6]
-'БЕГСТВО'
-
-[JM6_1]
-Поехали к банку по главной улице.
-
-[JM6_2]
-Не глуши мотор, мы по-быстрому. Туда и обратно.
-
-[JM6_3]
-Быстрее, сваливаем!
-
-[JM6_4]
-Стряхни копов с хвоста и гони в укрытие!
-
-[JM6_5]
-~g~Понадобится быстрая тачка, идиот!
-
-[JM6_6]
-~g~Иди, найди менее заметную тачку!
-
-[JM6_7]
-~g~Чтобы ограбить банк, тебе нужны все трое!
-
-[JM6_8]
-~r~Ты потерял всех налетчиков!
-
-[JM6_A]
-Классная будет тачка, да?
-
-[JM6_B]
-Короче слушай. Достань тачку получше и езжай к убежищу на Сент-Марк, где подберешь моих друзей.
-
-[JM6_C]
-Они решили взять банк, но им нужен водила.
-
-[JM6_D]
-Я замолвил за тебя словечко, так что не напортачь.
-
-[JM6_E]
-Отвези их к банку до пяти часов, и ни минутой позже.
-
-[JOEY]
-ЗАДАНИЯ ЗОУИ
-
-[JOEYGO]
-~g~Джоуи развлекается в городе вместе с Мисти. Приходи позже!
-
-[JUL]
-Июл
-
-[JUN]
-Июн
-
-[KABOOM]
-БАБАХ!
-
-[KEMUGO]
-~g~Мария и Кемури сейчас заняты. Загляни попозже!
-
-[KENJGO]
-~g~Кенжи сейчас на собрании Якудзы. Заходи как-нибудь потом!
-
-[KENJI]
-ЗАДАНИЯ КЕНДЖИ
-
-[KENSGO]
-~g~Кенжи занят! Зайди попозже!
-
-[KGS_EXP]
-Использовано взрывчатки (Кг.)
-
-[KILLS]
-УБИТО:
-
-[KM1]
-'ОСВОБОЖДЕНИЕ КАНБУ'
-
-[KM1_1]
-~g~Укради полицейскую машину!
-
-[KM1_10]
-~r~Якудза Канбу погиб - как и твоя честь!
-
-[KM1_11]
-~r~Ты поджарил сам себя!
-
-[KM1_12]
-~g~Отвези его к Доджо, но сперва разберись с полицейскими!
-
-[KM1_13]
-Поставь машину в гараж!
-
-[KM1_2]
-~g~Начини машину взрывчаткой!
-
-[KM1_3]
-~g~Теперь вези его к Доджо Якудзы.
-
-[KM1_4]
-~g~Для этого задания тебе понадобится полицейская машина!
-
-[KM1_5]
-~g~Отлично, теперь вали к полицейскому участку.
-
-[KM1_6]
-~g~Установи в машину бомбу!
-
-[KM1_7]
-~g~Проезд только для полицейских!
-
-[KM1_8A] { re3 change }
-Чтобы ~h~подорвать бомбу~w~, нажми ~h~~k~~VEHICLE_FIREWEAPON~~w~, но не забудь отойти подальше от машины.
-
-[KM1_8D] { re3 change }
-Чтобы ~h~подорвать бомбу~w~, нажми ~h~~k~~VEHICLE_FIREWEAPON~~w~, но не забудь отойти подальше от машины.
-
-[KM1_9]
-~r~Установленной в машине бомбой ты должен был взорвать стену!
-
-[KM1_A]
-Моя сестра хорошо о тебе отзывается,
-
-[KM1_B]
-Возможно, ты сможешь урегулировать одну ситуацию, которая ставит меня в неловкое положение.
-
-[KM1_C]
-Якудза Канбу сейчас в участке и ждет отправки в суд.
-
-[KM1_D]
-Мы благодарны тебе за такой самоотверженный поступок. Если тебе вдруг понадобится помощь, то Доджо даст тебе двух своих лучших людей.
-
-[KM1_E]
-но я, пока что, не видел от вас, гайдзинов, ничего, кроме разочарований.
-
-[KM1_F]
-Разумеется, в случае провала мы опозоримся.
-
-[KM1_G]
-Он очень ценный член семьи.
-
-[KM1_H]
-Вызволи его из заключения и отвези к Доджо на Бедфорд Поинт.
-
-[KM2]
-'ВЕЛИКИЙ АВТОВОР'
-
-[KM2_1]
-~g~Отремонтируй тачку, она должна сверкать.
-
-[KM2_2]
-~g~Тачка пригнана.
-
-[KM2_3]
-~g~Запомни, ~r~тачка~g~ должна быть в идеальном состоянии, иначе ее не примут в ~p~гараже~g~.
-
-[KM2_A]
-Ты даже не представляешь, сколько в нашей работе внимания приходится уделять этикету.
-
-[KM2_B]
-К моему великому стыду, один человек оказал мне услугу, а я так и не смог отплатить ему за его доброту.
-
-[KM2_C]
-Его слабость - машины. Он просил, чтобы мы приобрели для его коллекции несколько редких экземпляров.
-
-[KM2_D]
-Эти автомобили мы преподнесем ему как подарок, в счет погашения моего долга.
-
-[KM2_E]
-Ты должен раздобыть эти машины и доставить в гараж за стоянкой в Ньюпорте.
-
-[KM2_F]
-Для меня это дело чести.
-
-[KM3]
-'ДОГОВОР'
-
-[KM3_1]
-~g~Картель ожидает прибытия ямайцев, иди и укради тачку Ярди! Ты найдешь ее к северу отсюда, в Ньюпорте.
-
-[KM3_10]
-~r~Напарник убит!
-
-[KM3_11]
-~g~Картель атакован и дипломат забрать не удастся.
-
-[KM3_12]
-~g~Убей всех колумбийцев, взорви их тачки и забери дипломат.
-
-[KM3_13]
-~g~Отвези дипломат назад в казино.
-
-[KM3_14]
-~r~Тебя опознали, ты напортачил!
-
-[KM3_2]
-~g~Езжай и подбери своего напарника.
-
-[KM3_3]
-~g~Они встречаются на автостоянке больницы в Рокфорде!
-
-[KM3_4]
-~r~Они смылись!
-
-[KM3_5]
-~g~Чтобы дела пошли - посигналь.
-
-[KM3_6]
-~g~Убей их, убей их всех!
-
-[KM3_7]
-Это подстава Якудзы!
-
-[KM3_8]
-~g~Чтобы выполнить эту работу, тебе нужна тачка Ярди!
-
-[KM3_9]
-~r~Один из Колумбийцев мертв, дело не выгорит.
-
-[KM3_A]
-Дурак подставляет опасности спину, а умный смотрит ей в лицо.
-
-[KM3_B]
-Колумбийский Картель проигнорировал наши многочисленные требования убраться из нашей сферы влияния.
-
-[KM3_C]
-Сейчас они договариваются о сотрудничестве с Ямайцами, чтобы сообща выступить против нас.
-
-[KM3_D]
-Сейчас в городе они ведут последнюю стадию переговоров.
-
-[KM3_E]
-Это дело чести, чтобы ты их там всех порешил.
-
-[KM3_F]
-Возьми моего человека, укради машину Ярди, иди и окажи уважение Колумбийцам.
-
-[KM4]
-'ШИМА'
-
-[KM4_1]
-Мне нечем платить, но я не стал бы платить, даже если бы мог!
-
-[KM4_10]
-Да какие ВЫ к черту якудза...?
-
-[KM4_11]
-~g~Верни деньги назад в казино!
-
-[KM4_2]
-От вас никакого толка.
-
-[KM4_3]
-Я не за этим вам плачу. Если бы мне нужна была такая защита, я обратился бы к этим сраным копам.
-
-[KM4_4]
-~g~Разберись с этой бандой и верни ~b~дань~g~, принадлежащую Якудзе!
-
-[KM4_5]
-Дональд Лав желает принять тебя в своем чайном саду, и обсудить кое-какие дела.
-
-[KM4_6]
-Вот деньги, все как договаривались!
-
-[KM4_7]
-~r~Хозяин магазина сдох!
-
-[KM4_8]
-~g~Ты взял чемоданчик!
-
-[KM4_9]
-Какие-то юные бандиты обчистили это место! Они забрали все что было!
-
-[KM4_A]
-Чтобы быть действительно сильным, важно никогда не проявлять слабость.
-
-[KM4_B]
-Дела идут довольно успешно, сегодня как раз нужно собрать дань.
-
-[KM4_C]
-Иди и немедленно забери деньги, чтобы мы могли положить их на счет в казино.
-
-[KM5]
-'РАЗЪЯСНЕНИЯ'
-
-[KM5_1]
-~g~ПРОДАВЕЦ УБИТ!
-
-[KM5_2]
-~g~Ярди слинял.
-
-[KM5_3]
-~r~Ты не успел убить даже ~1~ Ярди.
-
-[KM5_4]
-~g~Поздравляем, ты прикончил ~1~ Ярди.
-
-[KM5_5]
-~g~Поздравляем, ты прикончил ~1~ Ярди. ПРИЗ $~1~
-
-[KM5_6]
-~g~Ты должен убить как минимум 8 торговцев-Ярди.
-
-[KM5_7]
-~g~Убивай их побыстрее! Продав СПАНК, они смоются.
-
-[KM5_A]
-ТЫ! Отличный момент чтобы прийти и показать свою тупую морду!
-
-[KM5_B]
-Ты в курсе, что твоя прошлая попытка объяснить ямайцам,
-
-[KM5_B1]
-что им не стоит водить дружбу с Картелем, не принесла никаких плодов?
-
-[KM5_C]
-Ярди заполонили весь город, и торгуют пакетиками со СПАНКом, словно горячими пирожками!
-
-[KM5_D]
-Эти Картельные свиньи смеются над нами, надо мной!
-
-[KM5_E]
-Я даю тебе последний шанс доказать, что моя сестра в тебе не ошиблась!
-
-[KM5_F]
-Иди же, прикончи этих подонков, и пусть твой позор смоют реки крови врагов!!!
-
-[KURUMA]
-Курума
-
-[K_JAH]
-Радио K-Jah
-
-[LANDSTK]
-Лэндсталкер
-
-[LANGSL]
-ВЫБОР ЯЗЫКА
-
-[LANGUA]
-Язык
-
-[LAST]
-Последнее сообщение.
-
-[LEGAL]
-~g~Разберитесь с преступником!
-
-[LETTER1]
-abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789"$,.'-?!!SDBFабвгдежзийклмнопрстуфхцчшщъыьэюяАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ
-
-[LINERUN]
-Лайнранер
-
-[LIPS]
-Губки 106
-
-[LITTLE]
-LITTLE T
-
-[LITTLEI]
-Сент-Марк
-
-[LM1]
-'ДЕВОЧКИ ЛУИДЖИ'
-
-[LM1_2]
-~g~Отвези Мисти в клуб к Луиджи.
-
-[LM1_3]
-~g~Посигналь, чтобы девица подошла к машине.
-
-[LM1_6]
-~g~Вернись в машину!
-
-[LM1_7]
-Остановись рядом с Мисти и подожди, пока она не сядет в тачку.
-
-[LM1_8]
-Ты можешь пойти к Луиджи и получить у него задание, или покататься по городу.
-
-[LM1_8A]
-Чтобы подзаработать немного деньжат, можно 'одолжить' такси...
-
-[LM1_9]
-Привет, я Мисти.
-
-[LM2]
-'ОТВАЛИ ОТ МОИХ ТЕЛОК'
-
-[LM2_1]
-~g~Отгони его тачку в мастерскую для перекраски.
-
-[LM2_2A]
-Нажав на ~h~ ~k~~PED_FIREWEAPON~~w~ ты ~h~ударишь~w~, ~h~пнешь~w~, или ~h~двинешь~w~ битой противника!
-
-[LM2_2C]
-Нажав на ~h~ ~k~~PED_FIREWEAPON~~w~ ты ~h~ударишь~w~, ~h~пнешь~w~, или ~h~двинешь~w~ битой противника!
-
-[LM2_2D]
-Нажав на ~h~ ~k~~PED_FIREWEAPON~~w~ ты ~h~ударишь~w~, ~h~пнешь~w~, или ~h~двинешь~w~ битой противника!
-
-[LM2_3]
-~g~Отгони машину в гараж к Луиджи!
-
-[LM2_4]
-~g~Перекрась машину!
-
-[LM2_A]
-На улицах появился новый наркотик под названием СПАНК.
-
-[LM2_B]
-Иди и впарь ему битой по морде!
-
-[LM2_C]
-Луиджи велел передать тебе...
-
-[LM2_D]
-вот это, держи.
-
-[LM2_E]
-Какой-то умник впаривает эту дрянь моим девкам в Портландской гавани.
-
-[LM2_F]
-Потом возьми его тачку и перекрась ее.
-
-[LM2_G]
-Я требую возмещения морального ущерба!
-
-[LM3]
-'ПРИВЕЗИ МНЕ МИСТИ'
-
-[LM3_10]
-~g~Достань тачку!
-
-[LM3_11]
-~g~Мисти в автобусе не ездит, достань нормальную тачку!
-
-[LM3_1A]
-Нажми ~h~ ~k~~VEHICLE_HORN~~w~, чтобы ~h~посигналить~w~ и вызвать Мисти из дома.
-
-[LM3_1B]
-Нажми ~h~ ~k~~VEHICLE_HORN~~w~, чтобы ~h~посигналить~w~ и вызвать Мисти из дома.
-
-[LM3_1C]
-Нажми ~h~ ~k~~VEHICLE_HORN~~w~, чтобы ~h~посигналить~w~ и вызвать Мисти из дома.
-
-[LM3_2]
-~g~Отвези Мисти к Джоуи.
-
-[LM3_4]
-~g~Отправляйся за Мисти!
-
-[LM3_5]
-Ты работаешь на Луиджи, да? Похоже, он наконец нашел водилу, которому можно доверять!
-
-[LM3_6]
-Джоуи...
-
-[LM3_6A]
-Твоя большая штука опять по мне соскучилась?
-
-[LM3_7]
-Иди, я сейчас, заводная моя.
-
-[LM3_8]
-Хай, я Джоуи.
-
-[LM3_9]
-Луиджи сказал, что ты свой парень, так что заходи как-нибудь,
-
-[LM3_9A]
-может, и у меня будет для тебя работенка.
-
-[LM3_9B]
-Ладно.
-
-[LM3_A]
-Эй, иди сюда, потолкуем... Мик, я с тобой попозже закончу.
-
-[LM3_B]
-Как поживаешь, парень?
-
-[LM3_C]
-Джоуи Леоне, сын дона, хочет поразвлечься со своей девчонкой Мисти.
-
-[LM3_D]
-Сгоняй за ней в Хепберн Хейтс...
-
-[LM3_E]
-но учти, этот район контролируют Дьяволы.
-
-[LM3_F]
-Отвези ее к нему в гараж на Трентоне, да поживее,
-
-[LM3_G]
-Джоуи не из тех, кто привык ждать, так что одна нога здесь...
-
-[LM3_H]
-да, и советую смотреть на дорогу, а не на Мисти!
-
-[LM4]
-'ОСАТАНЕЛЫЙ СУТЕНЕР'
-
-[LM4_A]
-Какой-то урод из Дьяволов поставил своих потаскух работать на моей территории.
-
-[LM4_B]
-Иди, разберись с этим козлом.
-
-[LM4_C]
-Если нужен ствол - возьми его во дворе магазина, который напротив метро.
-
-[LM5]
-'ВЕЧЕРИНКА У КОПОВ'
-
-[LM5_1]
-~g~У тебя телок в тачке, как сельдей в бочке! ~g~Отвези их на вечеринку и приезжай за новыми.
-
-[LM5_2]
-~r~Девка Луиджи теперь похожа на мешок с мясом!
-
-[LM5_3]
-~g~Тебе нужна тачка!
-
-[LM5_4]
-~g~Подбери телок работающих на бульваре Св.Марка.
-
-[LM5_5]
-~g~Отвези девок на вечеринку к копам!
-
-[LM5_7]
-~g~Луиджи хочет, чтобы на ~p~вечеринке у копов~g~ было не менее четырех девок!
-
-[LM5_8]
-~g~Телок на вечеринке: ~1~
-
-[LM5_9]
-ДЕВОЧЕК:
-
-[LM5_A]
-Копы решили устроить вечеринку в зале старой школы, которая рядом с мостом Каллахан,
-
-[LM5_B]
-и их теперь потянуло на старые школьные забавы.
-
-[LM5_C]
-Но сейчас все мои девки работают на панели.
-
-[LM5_D]
-Привези им побольше моих телок, доставь всем удовольствие.
-
-[LM5_E]
-Привези побольше, пока копы не пропили все свои бабки.
-
-[LOADCAR]
-LOADING VEHICLE... (PRESS L1 TO CANCEL)
-
-[LOOK_A]
-Удерживай кнопку ~h~~k~~VEHICLE_LOOKLEFT~~w~ или ~h~~k~~VEHICLE_LOOKRIGHT~~w~, чтобы посмотреть из машины ~h~налево~w~ или ~h~направо~w~. Если нажать обе, то посмотришь ~h~назад~w~.
-
-[LOV4_10]
-~r~Ты уничтожил единственный способ выяснить, куда делся пакет!
-
-[LOVE]
-ЗАДАНИЯ ДОНАЛЬДА
-
-[LOVE1]
-'СПАСИТЕЛЬ'
-
-[LOVE1_1]
-~g~Чтобы попасть в логово колумбийцев, тебе понадобится одна из их тачек. Возможно, ты ее найдешь в форте Стаунтона.
-
-[LOVE1_2]
-~g~Спасай Старого Азиата.
-
-[LOVE1_3]
-~g~Отвези старого азиата к Дональду Лаву.
-
-[LOVE1_4]
-~g~Старый Азиат должен быть в одном из этих гаражей...
-
-[LOVE1_5]
-~g~Хватит болтаться без дела, достань машину колумбийцев и спаси товарища Дональда.
-
-[LOVE1_6]
-~r~Да... теперь кишки азиата размазаны по всей улице!
-
-[LOVE1_7]
-~g~Через эти ворота пропускают лишь машины колумбийской банды.
-
-[LOVE1_A]
-Во первых, я хочу поблагодарить вас за ту услугу, которую вы мне оказали.
-
-[LOVE1_B]
-Но, жизненный опыт подсказывает мне, что преданность такого человека, как вы, можно купить,
-
-[LOVE1_C]
-У меня есть один очень ценный знакомый - старый азиат.
-
-[LOVE1_D]
-Они пытаются увеличить сумму назначенного ранее выкупа, но я не привык менять условия сделки.
-
-[LOVE1_E]
-Сделка есть сделка, они не получат ни пенса больше.
-
-[LOVE1_F]
-Люди всегда пытаются истолковать все по-своему.
-
-[LOVE1_G]
-Вы должны спасти моего друга любой ценой.
-
-[LOVE1_H]
-в отличие от преданности банды.
-
-[LOVE1_I]
-Его держат в заложниках какие-то южноамериканцы в Аспатрии.
-
-[LOVE2]
-'КОНЕЦ ВАКАГАСИРА!'
-
-[LOVE2_1]
-~g~Отправляйся в форт Стаунтон и достань тачку колумбийцев!
-
-[LOVE2_2]
-~g~Теперь заезжай в ~p~многоэтажный гараж в Ньюпорте~g~ и прихлопни Кенжи!
-
-[LOVE2_3]
-~r~Если ты будешь без машины Картеля, тебя сразу узнают!
-
-[LOVE2_4]
-~r~Якудза узнали тебя!
-
-[LOVE2_5]
-~g~Кенжи теперь похож на бифштекс! Сваливай из Ньюпорта и уничтожь машину!
-
-[LOVE2_6]
-~r~Ты замочил всех свидетелей!
-
-[LOVE2_7]
-~g~Теперь уничтожь машину!
-
-[LOVE2_8]
-~g~Быстрее сваливай из Ньюпорта!
-
-[LOVE2_A]
-Ничто так не сбивает цены на недвижимость, как старая добрая гангстерская война,
-
-[LOVE2_B]
-не считая, конечно, вспышки чумы......но она может доставить куда больше проблем.
-
-[LOVE2_C]
-Я слышал о натянутых отношениях между Якудзой и колумбийцами.
-
-[LOVE2_D]
-Нам стоит погреть руки на их дурацкой вражде.
-
-[LOVE2_E]
-Я хочу чтобы вы прикончили вакагасира, Кенжи Касена.
-
-[LOVE2_F]
-Сейчас у Кенжи деловая встреча на крыше многоэтажного гаража а Ньюпорте.
-
-[LOVE2_G]
-Достаньте машину Картеля и разделайтесь с ним!
-
-[LOVE2_H]
-Якудза решит, что это убийство - дело рук картеля, и объявит войну.
-
-[LOVE3]
-'ГРУЗ В ОКЕАНЕ'
-
-[LOVE3_1]
-~g~Возьми ~r~катер~g~ и следуй за ~y~самолетом~g~!
-
-[LOVE3_2]
-~g~Ты собрал весь груз! Отвези его Дональду Лаву.
-
-[LOVE3_3]
-~g~Самолет сбросил ~1~ из 6 упаковок.
-
-[LOVE3_4]
-~r~Ты уничтожил самолет!
-
-[LOVE3_5]
-~g~Самолет уже рядом.
-
-[LOVE3_6]
-~r~Упаковка досталась полиции!
-
-[LOVE3_A]
-Некоторые ценные товары очень сложно импортировать из-за лицемерия властей.
-
-[LOVE3_B]
-Сегодня ночью один маленький самолетик на подлете к аэродрому откроет свой трюм.
-
-[LOVE3_C]
-Он сбросит в воду несколько ценных упаковок.
-
-[LOVE3_D]
-Постарайтесь опередить полицию и собрать груз первым.
-
-[LOVE4]
-'ВЕЛИКИЙ АЭРОВОР'
-
-[LOVE4_1]
-~r~Картель уже здесь!
-
-[LOVE4_2]
-~g~Посылки нет! Выследи колумбийцев и забери у них груз.
-
-[LOVE4_3]
-~g~Панлантик Констракшн...?
-
-[LOVE4_4]
-~g~Доставь посылку к Дональду Лаву!
-
-[LOVE4_5]
-~g~Посылка должна быть в самолете....
-
-[LOVE4_6]
-~g~Отправляйся на лифте в башню!
-
-[LOVE4_7]
-~g~На острове Стаунтон есть одна стройка, возможно они повезли груз туда.
-
-[LOVE4_8]
-~g~Без машины ты в гараж не попадешь.
-
-[LOVE4_9]
-~r~Самолет уничтожен!
-
-[LOVE4_A]
-Спасибо, что привезли мне этот груз, но он был всего лишь приманкой.
-
-[LOVE4_B]
-Простите, но ради крупного дела на это приходится идти.
-
-[LOVE4_C]
-По настоящему важный груз до сих пор все еще в самолете.
-
-[LOVE4_D]
-К несчастью, власти аэропорта все же решили задержать и обыскать самолет,
-
-[LOVE4_E]
-Поезжайте через мост в Шорсайд Вейл и затем в Международный аэропорт Фрэнсис.
-
-[LOVE4_F]
-Деньги властям уже уплачены.
-
-[LOVE4_G]
-Моя посылка ожидает вас в фюзеляже самолета, который стоит в ангаре на таможне.
-
-[LOVE4_H]
-так что мне пришлось заплатить им за издержки.
-
-[LOVE5]
-'ЭСКОРТ'
-
-[LOVE5_1]
-~g~Поехали!
-
-[LOVE5_2]
-~g~Тебе нужна тачка!
-
-[LOVE5_3]
-~g~Езжай вперед и посмотри, что там в конце тоннеля!
-
-[LOVE5_4]
-~r~Защищай грузовик!
-
-[LOVE5_5]
-~r~Ты не сумел защитить грузовик!
-
-[LOVE5_A]
-На вас можно положиться, друг мой. Что ни говори, а это сейчас большая редкость.
-
-[LOVE5_B]
-Мой азиатский друг повезет доставленный вами товар по назначению, но ему потребуется эскорт.
-
-[LOVE5_C]
-Я бы хотел, чтобы вы помогли ему в целости и сохранности доставить этот груз в Пайк Крик
-
-[LOVE6]
-'ПРИМАНКА'
-
-[LOVE6_1]
-~g~Теперь уводи копов подальше от склада!
-
-[LOVE6_2]
-~r~Тебе не удалось увести полицию на достаточное расстояние!
-
-[LOVE6_3]
-У тебя ~1~ секунд, чтобы вернуться к инкассаторской машине, иначе задание будет провалено.
-
-[LOVE6_4]
-~r~Ты разбил приманку для копов!
-
-[LOVE6_A]
-Урок бизнеса, мой друг.
-
-[LOVE6_B]
-даже если она вообще не представляет его истинной ценности.
-
-[LOVE6_C]
-Полиция оцепила весь район, в котором сейчас находится мой друг с грузом.
-
-[LOVE6_D]
-Отправляйтесь туда и используйте фургон как приманку для копов.
-
-[LOVE6_E]
-Если у вас есть особый товар, то каждая собака будет пытаться его у вас отнять...
-
-[LOVE6_F]
-Пусть они за вами погоняются, а он тем временем уйдет.
-
-[LOVE7]
-ИСЧЕЗНОВЕНИЕ ЛАВА
-
-[LOVEGO]
-~g~У Дональда Лава возникли неотложные дела. Заходи попозже!
-
-[LRQC_1]
-Нам с Асукой нужно кое-что обсудить,
-
-[LRQC_2]
-а ты пока можешь тут осмотреться.
-
-[LRQC_3]
-Тебе нужно место, где бы ты мог залечь.
-
-[LRQC_4]
-На углу Бельвилля есть склад, в котором есть все, что тебе нужно.
-
-[LRQC_5]
-Приходи ко мне сюда, когда будешь готов,
-
-[LRQC_6]
-и я обсужу с тобой кое-какие дела.
-
-[LUIGGO]
-~g~Луиджи осматривает новых девочек. Загляни попозже!
-
-[LUIGI]
-ЗАДАНИЯ ЛУИДЖИ
-
-[LUIGIS]
-Жилище Луиджи
-
-[L_TRN_1]
-Ты можешь попасть в другой район Портланда, воспользовавшись метро. Нажми~h~ ~k~~VEHICLE_ENTER_EXIT~~w~, чтобы ~h~сесть~w~ или ~h~выйти~w~ из поезда.
-
-[L_TRN_2]
-Ты можешь попасть в другой район Портланда, воспользовавшись метро. Нажми~h~ ~k~~VEHICLE_ENTER_EXIT~~w~, чтобы ~h~сесть~w~ или ~h~выйти~w~ из поезда.
-
-[MAFIACR]
-Сентинел Мафии
-
-[MANANA]
-Манана
-
-[MAR]
-Мар
-
-[MAY]
-Май
-
-[MCDNSP]
-There is insufficient space on the Memory Card (PS2) in MEMORY CARD slot 1. At least 500KB is needed to save this application data. Do you wish to start? (YES or NO)
-
-[MCGNSP]
-There is insufficient space on the Memory Card (PS2) in MEMORY CARD slot 1. At least 200KB is needed to save this application data. Do you wish to start? (YES or NO)
-
-[MCLOAD]
-Loading Data. Please do not remove the Memory Card (PS2) in MEMORY CARD slot 1, reset or switch off the console.
-
-[MCSTNS]
-There is no Memory Card (PS2) in MEMORY CARD slot 1. Do you wish to start? (YES or NO)
-
-[MC_LDFL]
-Загрузка не прошла!
-
-[MC_NWRE]
-Идет перезапуск игры.
-
-[MEA1]
-'МОШЕННИК'
-
-[MEA1_1]
-~r~Управляющий банка мертв!
-
-[MEA1_2]
-~r~Тебе же сказали уничтожить машину!
-
-[MEA1_3]
-~g~Выбирайся из машины!
-
-[MEA1_4]
-~r~Ты проехал мимо управляющего банка!
-
-[MEA1_B]
-Я Чонкс, Марти Чонкс.
-
-[MEA1_B3]
-~g~Езжай и встреть управляющего банка.
-
-[MEA1_B4]
-А, тебя послал мистер Чонкс. Ну поехали, нанесем ему визит.
-
-[MEA1_B5]
-TEXT NO LONGER NEEDED
-
-[MEA1_B6]
-~g~Отгони машину в утилизатор, чтобы избавиться от улик. Выйди из машины и ее подцепит кран.
-
-[MEA1_C]
-Я тут на углу построил заводик по производству корма для кошек и собак.
-
-[MEA1_D]
-У меня возникли проблемы с финансами, но у кого их не бывает?
-
-[MEA1_E]
-Я собирался встретиться с управляющим из банка.
-
-[MEA1_F]
-Этот мерзкий мошенник решил поживиться за мой счет, и поднял процент займа.
-
-[MEA1_G]
-Возьми мою тачку, встреть его и привези сюда.
-
-[MEA1_H]
-Я приготовил небольшой сюрприз для этого кровопийцы!
-
-[MEA2]
-'КРАЖА'
-
-[MEA2_1]
-~r~Тебе же сказали уничтожить тачку!
-
-[MEA2_2]
-~r~Вор мертв!
-
-[MEA2_3]
-~g~Отгони машину назад на фабрику.
-
-[MEA2_4]
-~r~Ты проехал мимо вора!
-
-[MEA2_A]
-Я нанял воров, чтобы они забрались в мой офис...
-
-[MEA2_B]
-и кое-что вынесли. А я бы потом смог потребовать страховку.
-
-[MEA2_B3]
-~g~Езжай, встреть воров.
-
-[MEA2_B4]
-~g~Отвези их к фабрике по производству корма.
-
-[MEA2_B5]
-TEXT NO LONGER NEEDED
-
-[MEA2_B6]
-~g~Перекрась машину, чтобы избавиться от улик.
-
-[MEA2_C]
-Но эти ублюдки теперь угрожают тем, что расскажут все страховой компании,
-
-[MEA2_D]
-если я с ними не поделюсь.
-
-[MEA2_E]
-Нет, ты представляешь?
-
-[MEA2_F]
-За воротами фабрики я поставил машину.
-
-[MEA2_G]
-Возьми ее и сгоняй за ними. Они тусуются где-то в квартале красных фонарей.
-
-[MEA2_H]
-Привези их ко мне на фабрику и я покажу им кузькину мать.
-
-[MEA3]
-'ЖЕНА'
-
-[MEA3_1]
-~r~Жена мертва!
-
-[MEA3_2]
-~r~Ты должен был утопить тачку!
-
-[MEA3_3]
-~r~Ты проехал мимо его жены!
-
-[MEA3_A]
-Чтобы продолжить свой бизнес, мне нужно как быстрее решить финансовые проблемы.
-
-[MEA3_B]
-У моей жены хорошая страховка жизни, и к тому же она постоянно транжирит мои деньги.
-
-[MEA3_B3]
-~g~Езжай и подбери миссис Чонкс.
-
-[MEA3_B4]
-Марти хочет меня видеть? Давай быстрее, а то мне нужно еще успеть в парикмахерскую.
-
-[MEA3_B5]
-TEXT NO LONGER NEEDED
-
-[MEA3_B6]
-~g~Чтобы избавиться от улик, утопи тачку.
-
-[MEA3_C]
-Я поставил машину в обычном месте.
-
-[MEA3_D]
-Забери мою жену из маникюрного салона и привези ко мне на фабрику.
-
-[MEA4]
-'ЛЮБОВНИК'
-
-[MEA4_1]
-~r~Карлос мертв!
-
-[MEA4_2]
-~r~Марти Чонкс мертв!
-
-[MEA4_3]
-~r~Ты проехал мимо Карлоса!
-
-[MEA4_A]
-Проклятье, у меня проблемы!
-
-[MEA4_B]
-Оказалось, что моя жена спала с тем, кому я задолжал.
-
-[MEA4_B3]
-~g~Подбери любовника жены Чонкса.
-
-[MEA4_B4]
-Тебя послал Марти, да? Я объясню этой мерзкой крысе, что такое настоящий бизнес.
-
-[MEA4_B5]
-Карл, привет! Мне эээ... нужно время, чтобы отдать долг.
-
-[MEA4_B6]
-Нет, Марти, прошло и так много времени. У тебя был шанс, а теперь я забираю эту фабрику...
-
-[MEA4_B7]
-Ну ты хоть ко мне в офис зайди...
-
-[MEA4_C]
-Он очень зол и требует, чтобы я вернул ему деньги!
-
-[MEA4_D]
-Мне нужно с ним поговорить...
-
-[MEA4_E]
-он думает, что я отдам ему долг...
-
-[MEA4_F]
-но я решил...
-
-[MEA4_G]
-что в этом месяце городских дворняг ждет новое блюдо!
-
-[MEAT1_A]
-Друзья посоветовали мне обратиться к тебе, чтобы решить все мои проблемы. Если ты согласен, подойди к телефону в Трентоне.
-
-[MED_WST]
-Убито медиков
-
-[MEMTST]
-MemoryCardTest screen
-
-[MGSVCN]
-MagazineDirectory Created
-
-[MGSVNC]
-MagazineDirectory Not Created
-
-[MISTY1]
-~r~Мисти теперь лучше везти в морг!
-
-[MMRAIN]
-Количество выпавших осадков (мм)
-
-[MM_1]
-'ГОНКА ПО ГАРАЖУ'
-
-[MM_1_A]
-~g~У тебя ~y~2 минуты~g~, чтобы проехать ~y~20 контрольных пунктов~g~ в высотном гараже! ~g~Ты можешь проезжать их ~y~В ЛЮБОМ ПОРЯДКЕ~g~.
-
-[MM_1_B]
-~1~ из 20!
-
-[MM_1_C]
-~g~У тебя 20 секунд, после прохождения каждого контрольного пункта тебе будут добавлять по ~y~5 секунд~g~. ~g~Время ~y~УЖЕ~g~ пошло.
-
-[MONTAX]
-Денег заработано на такси
-
-[MOONBM]
-Лунный луч
-
-[MRWONGS]
-М-р.Вонг
-
-[MSX_FM]
-MSX FM
-
-[MULE]
-Тягач
-
-[MUSMEN]
-Музыка/Звуки
-
-[MUSVOL]
-Громкость музыки
-
-[MXCARD]
-Длина лучшего БЕЗУМНОГО прыжка (ft)
-
-[MXCARDM]
-Длина лучшего БЕЗУМНОГО прыжка (м)
-
-[MXCARJ]
-Высота лучшего БЕЗУМНОГО прыжка (ft)
-
-[MXCARJM]
-Высота лучшего БЕЗУМНОГО прыжка (м)
-
-[MXFLIP]
-Переворотов в лучшем БЕЗУМНОМ прыжке
-
-[MXJUMP]
-Разворот в лучшем БЕЗУМНОМ прыжке
-
-[M_FAIL]
-ЗАДАНИЕ ПРОВАЛЕНО!
-
-[M_PASS]
-ЗАДАНИЕ ВЫПОЛНЕНО! $~1~
-
-[M_WASTE]
-Мужчин убито
-
-[NEW_TAX]
-БОЛЬШЕ! БЫСТРЕЕ! ЛУЧШЕ! В Харвуде открылся новый таксопарк Борнини. Звоните 555-БОРНИНИ!
-
-[NICK]
-НИК ЛАВ
-
-[NMISON]
-Заданий начато
-
-[NMMISP]
-Заданий завершено
-
-[NO]
-Нет
-
-[NOCD]
-CD-привод пуст. Пожалуйста, вставьте диск.
-
-[NOCONT]
-Please reconnect an analog controller (DUALSHOCK@) or analog controller (DUALSHOCK@2). to controller port 1 to continue
-
-[NOCONTE]
-Please re-insert the analog controller (DUALSHOCK@) or analog controller (DUALSHOCK@2) in controller port 1 to continue
-
-[NODOORS]
-~g~Они все туда не влезут! Достань тачку попросторней!
-
-[NOGMSV]
-Записаться можно лишь в твоем гараже.
-
-[NOMONEY]
-~g~У тебя не хватает денег!
-
-[NOSTUC]
-Не выполнено ни одного БЕЗУМНОГО трюка
-
-[NOUNGM]
-Всего уникальных прыжков
-
-[NOUNIF]
-Выполнено уникальных прыжков
-
-[NOV]
-Ноя
-
-[NO_PAUZ]
-При игре по сети пауза не работает. Чтобы выйти нажми ESC дважды!
-
-[NO_PCCD]
-Пожалуйста, вставьте второй диск игры GTA3 в CDROM привод, или нажмите ESC для выхода из игры.
-
-[NRECORD]
-~r~РЕКОРД НЕ ПОБИТ!
-
-[NUMBER]
-~1~
-
-[OCT]
-Окт
-
-[OPENCD]
-CRDOM-привод открыт. Пожалуйста, закройте CDROM-привод.
-
-[OUTTIME]
-~r~Очень медленно, друг, очень медленно!
-
-[OUT_VEH]
-~g~Выйди из тачки!
-
-[O_FAIL]
-ДОПОЛНИТЕЛЬНОЕ ЗАДАНИЕ ПРОВАЛЕНО!
-
-[O_PASS]
-ДОПОЛНИТЕЛЬНОЕ ЗАДАНИЕ ВЫПОЛНЕНО!
-
-[PAGEB1]
-В убежище доставлен пистолет
-
-[PAGEB10]
-В убежище доставлена ракетница
-
-[PAGEB11]
-В убежище доставлен огнемет
-
-[PAGEB12]
-В убежище доставлена взятка для полиции
-
-[PAGEB13]
-В убежище доставлено лекарство
-
-[PAGEB14]
-В убежище доставлен адреналин
-
-[PAGEB2]
-В убежище доставлен 'Узи'
-
-[PAGEB3]
-В убежище доставлена броня
-
-[PAGEB4]
-В убежище доставлен дробовик
-
-[PAGEB5]
-В убежище доставлены гранаты
-
-[PAGEB6]
-В убежище доставлены коктейли Молотова
-
-[PAGEB7]
-В убежище доставлен AK-47
-
-[PAGEB8]
-В убежище доставлена снайперская винтовка
-
-[PAGEB9]
-В убежище доставлена винтовка M16
-
-[PAGE_00]
-.
-
-[PAGE_01]
-Убей ~1~ Дьяволов за 120 секунд!
-
-[PAGE_02]
-Уничтожь ~1~ машин за 120 секунд!
-
-[PAGE_03]
-Убей ~1~ мафиози за 120 секунд!
-
-[PAGE_04]
-Убей ~1~ триадовцев за 120 секунд!
-
-[PAGE_05]
-Убей ~1~ триадовцев за 120 секунд!
-
-[PAGE_06]
-Уничтожь ~1~ машин за 120 секунд!
-
-[PAGE_07]
-Расколи ~1~ голов Ярди за 120 секунд!
-
-[PAGE_08]
-Сожги ~1~ членов Якудзы за 120 секунд!
-
-[PAGE_09]
-Уничтож ~1~ машин за 120 секунд!
-
-[PAGE_10]
-Уничтожь ~1~ машин за 120 секунд!
-
-[PAGE_11]
-Истреби ~1~ Ярди за 120 секунд!
-
-[PAGE_12]
-Подожги ~1~ членов Якудзы за 120 секунд!
-
-[PAGE_13]
-Взорви ~1~ Ярди за 120 секунд!
-
-[PAGE_14]
-Поджарь ~1~ колумбийцев за 120 секунд!
-
-[PAGE_15]
-Задави ~1~ Капюшонов за 120 секунд!
-
-[PAGE_16]
-Уничтожь ~1~ машин за 120 секунд!
-
-[PAGE_17]
-Задави ~1~ колумбийцев за 120 секунд!
-
-[PAGE_18]
-Уничтожь ~1~ машин за 120 секунд!
-
-[PAGE_19]
-Лиши голов ~1~ колумбийцев за 120 секунд!
-
-[PAGE_20]
-Обезглавь ~1~ Капюшонов за 120 секунд!
-
-[PANCAK]
-РАСПЛЮЩИЛ!
-
-[PANLANT]
-Панлантик
-
-[PAPER1]
-*
-
-[PAPER2]
-*
-
-[PAPER3]
-*
-
-[PARK]
-Парк Бельвиль
-
-[PARSHP]
-Parse Heap
-
-[PASDRO]
-Потеряно пассажиров
-
-[PATRIOT]
-Пэтриот
-
-[PAUSED]
-ИГРА ОСТАНОВЛЕНА
-
-[PBOAT_1] { re3 change }
-Чтобы выстрелить из орудия катера нажми ~h~~k~~VEHICLE_FIREWEAPON~~w~.
-
-[PBOAT_2] { re3 change }
-Чтобы выстрелить из орудия катера нажми ~h~~k~~VEHICLE_FIREWEAPON~~w~.
-
-[PCLOAD]
-Loading File Data
-
-[PCRESRT]
-Перезапуск Grand Theft Auto III
-
-[PDRGON]
-ShowPedRoadGroups On
-
-[PEREN]
-Многолетник
-
-[PERPIC]
-Найдено особых пакетов
-
-[PER_COM]
-Процент завершения игры
-
-[PE_WAST]
-Убито вами людей
-
-[PE_WSOT]
-Убито преступниками людей
-
-[PIG_WST]
-Убито копов
-
-[PL_STAT]
-ДАННЫЕ ОБ ИГРОКЕ
-
-[POLICAR]
-Полицейская
-
-[PONY]
-Пони
-
-[PORT_E]
-Порт Портланда
-
-[PORT_I]
-Трентон
-
-[PORT_S]
-Пристань Атлантик
-
-[PORT_W]
-Мыс Каллахан
-
-[PQUINS]
-Идеальный четверной безумный трюк
-
-[PREBRF]
-Предыдущие сообщения
-
-[PREDATR]
-Хищник
-
-[PRGOFF]
-ShowPedRoadGroups Off
-
-[PRINST]
-Идеальный безумный трюк
-
-[PROJECT]
-Сады Вичита
-
-[PRTRST]
-Идеальный тройной безумный трюк
-
-[PRVMEN]
-Задание предыдущей миссии
-
-[PUSAVE]
-Save Only the game
-
-[PU_MONY]
-Не хватает денег.
-
-[QUINST]
-Четверной безумный трюк
-
-[QUITOP]
-Quit Options
-
-[RADIO_A]
-Нажимай ~h~~k~~VEHICLE_CHANGE_RADIO_STATION~ ~w~, чтобы менять ~h~ радиоволну.
-
-[RADIO_B]
-Нажимай ~h~~k~~VEHICLE_CHANGE_RADIO_STATION~ ~w~, чтобы менять ~h~ радиоволну.
-
-[RADIO_C]
-Нажимай ~h~~k~~VEHICLE_CHANGE_RADIO_STATION~ ~w~, чтобы менять ~h~ радиоволну.
-
-[RADIO_D]
-Нажимай ~h~~k~~VEHICLE_CHANGE_RADIO_STATION~ ~w~, чтобы менять ~h~ радиоволну.
-
-[RAMPAGE]
-СХВАТКА!!
-
-[RAMP_A]
-ВСЕ СХВАТКИ ПРОЙДЕНЫ!
-
-[RAMP_F]
-СХВАТКА ПРОИГРАНА
-
-[RAMP_P]
-СХВАТКА ВЫИГРАНА!
-
-[RATNG1]
-Воришка
-
-[RATNG10]
-Чистильщик
-
-[RATNG11]
-Профессионал
-
-[RATNG12]
-Киллер
-
-[RATNG13]
-Правая рука
-
-[RATNG14]
-Главарь
-
-[RATNG15]
-Босс
-
-[RATNG2]
-Мошенник
-
-[RATNG3]
-Хулиган
-
-[RATNG4]
-Шестерка
-
-[RATNG5]
-Грабитель
-
-[RATNG6]
-Громила
-
-[RATNG7]
-Бандит
-
-[RATNG8]
-Головорез
-
-[RATNG9]
-Братан
-
-[RAY]
-ЗАДАНИЯ РЭЯ
-
-[RAYGO]
-~g~Рэй пошел в другой туалет. Зайди сюда попозже!
-
-[RC1]
-'ДРАКА С ДЬЯВОЛАМИ'
-
-[RC2]
-'МОРДОБОЙ С МАФИЕЙ'
-
-[RC3]
-'КАТАСТРОФА В КАЗИНО'
-
-[RC4]
-'РАЗБОРКА С РАСТАМАНАМИ'
-
-[RCBANDT]
-Багги Бандит
-
-[RCHELP] { re3 change }
-Чтобы подорвать машинку, нажми ~k~~VEHICLE_FIREWEAPON~, или врежься в колесо жертвы.
-
-[RCHELPA] { re3 change }
-Чтобы подорвать машинку, нажми ~k~~VEHICLE_FIREWEAPON~, или врежься в колесо жертвы.
-
-[RC_1]
-У тебя 2 минуты, чтобы подорвать как можно больше машин Дьяволов!
-
-[RC_2]
-У тебя 2 минуты, чтобы подорвать как можно больше машин мафии!
-
-[RC_3]
-У тебя 2 минуты, чтобы подорвать как можно больше машин Якудзы!
-
-[RC_4]
-У тебя 2 минуты, чтобы подорвать как можно больше машин Ярди!
-
-[RC_5]
-У тебя 2 минуты, чтобы подорвать как можно больше машин Капюшонов!
-
-[RC_6]
-У тебя 2 минуты, чтобы подорвать как можно больше машин Картеля!
-
-[RECORD]
-~g~НОВЫЙ РЕКОРД!!
-
-[REDLIGH]
-Квартал красных фонарей
-
-[REEFER]
-Рифер
-
-[REGCAR]
-Register MemoryCard One
-
-[RELIDE]
-ReLoadIde
-
-[RELIPE]
-ReLoadIpl
-
-[REPLAY]
-ПОВТОР
-
-[RESTART]
-Новая игра
-
-[REWARD]
-НАГРАДА $~1~
-
-[RHINO]
-Носорог
-
-[RISE]
-Rise FM
-
-[RM1]
-'КОНЕЦ СТУКАЧА'
-
-[RM1_1]
-~g~Осмотри дом защиты свидетелей.
-
-[RM1_2]
-~g~Прикончи МакАффри!
-
-[RM1_3]
-~r~МакАффри скрылся!
-
-[RM1_4]
-~g~Ты использовал все гранаты! Иди купи в магазине еще!
-
-[RM1_5]
-~g~Вернись и подожги дом!
-
-[RM1_A]
-Этот подонок МакАффри брал взяток больше, чем кто-либо.
-
-[RM1_B]
-Он решил всех заложить, и таким образом оправдать все свои темные делишки.
-
-[RM1_C]
-Хренов стукач!
-
-[RM1_D]
-Он в центре Ньюпорта под вооруженной охраной в здании защиты свидетелей, которое позади стоянки.
-
-[RM1_E]
-Чтобы выкурить его наружу - подожги этот дом, ну а потом, я думаю, ты сможешь заставить его замолчать.
-
-[RM2]
-'РУКА ПОМОЩИ'
-
-[RM2_A]
-Мой старый армейский друг организовал бизнес в Рокфорде.
-
-[RM2_A1]
-Эй, парень, сюда!
-
-[RM2_B]
-Мы с ним были в Никарагуа в те годы, когда правительство знало, что делает. Ну так вот.
-
-[RM2_C]
-Его вчера избили какие-то сволочи из Картеля, и сказали что сегодня заберут кое-что из его товара.
-
-[RM2_D]
-Ему нужно помочь. Ну, а он в долгу тоже не останется - даст тебе затовариться 'скобяными изделиями'.
-
-[RM2_D1]
-Я бы, конечно, и сам помог ему, но старость не радость - кхе кхе - вот, в-общем, удачи тебе.
-
-[RM2_E]
-Рэй мне звонил... но я думал, он пришлет побольше народу.
-
-[RM2_E1]
-Я не могу поверить, что эти трусливые ублюдки снова оставили меня без прикрытия!
-
-[RM2_F]
-Ну, три руки лучше чем одна, так что бери все, что тебе пригодится.
-
-[RM2_F1]
-Колумбийцы прибудут с минуты на минуту!
-
-[RM2_G]
-~g~Проверь, как дела у Фила!
-
-[RM2_H]
-~r~Фила убили!
-
-[RM2_K]
-Проклятье, вот они! ПОЛУЧАЙТЕ!
-
-[RM2_L]
-Эй! Если бы ты тогда был в Никарагуа, глядишь, я и не потерял бы руку!
-
-[RM2_M]
-Если тебе понадобится оружие, то не стесняйся, бери все что нужно из ящиков.
-
-[RM2_N]
-Только не забудь заплатить. А сейчас сваливай, с копами я все улажу.
-
-[RM3]
-'УНИЧТОЖЕНИЕ УЛИК'
-
-[RM3_1]
-~g~Оставь улики в машине и подожги ее.
-
-[RM3_4]
-~g~Обвинение лишилось улик!
-
-[RM3_5]
-~g~У тебя ~1~ из 6 пакетов с уликами.
-
-[RM3_6]
-~r~Фотографии разлетятся по всему городу!
-
-[RM3_7]
-~g~Теперь поджигай тачку!
-
-[RM3_8]
-~r~Эта тачка была приманкой!
-
-[RM3_A]
-Я знаю одного очень важного человека в городе,
-
-[RM3_B]
-Против него выдвинуто обвинение. Есть какие-то непристойные фотки, где его сняли
-
-[RM3_C]
-на вечеринке в морге или еще где.
-
-[RM3_D]
-Улики скоро собираются везти в суд.
-
-[RM3_E]
-Тебе нужно протаранить машину с уликами и собрать все до одной выпавшие фотографии.
-
-[RM3_F]
-Как только соберешь все улики - оставь их в машине и взорви ее.
-
-[RM3_G]
-Если ты это провернешь, то все будут в плюсе.
-
-[RM3_H]
-с довольно экзотическим вкусом и деньгами для его удовлетворения.
-
-[RM4]
-'РЫБАЛКА'
-
-[RM4_1]
-~g~Тебе нужно угнать полицейский катер.
-
-[RM4_2]
-~g~Отправляйся к маяку и пусти напарника Рэя на корм рыбам!
-
-[RM4_3]
-~r~Партнер Рэя скрылся!
-
-[RM4_A]
-Думаю, мой напарник - стукач.
-
-[RM4_B]
-Нужно побыстрее заткнуть ему пасть.
-
-[RM4_C]
-На своем катере он вечерами ходит рыбачить к маяку на утесе Портланда.
-
-[RM4_D]
-Возьми полицейский катер и разберись с этим чертовым стукачем!
-
-[RM4_E]
-Хватит ему рыбу ловить. Пусть он ее теперь покормит.
-
-[RM5]
-'ЖИВАЯ МУМИЯ'
-
-[RM5_1]
-~g~Перехвати скорую.
-
-[RM5_2]
-~g~Тебя засекли!
-
-[RM5_3]
-~g~Это была приманка!
-
-[RM5_4]
-~g~Пули эту загипсованную куклу не берут!
-
-[RM5_5]
-~g~Этой загипсованной кукле огнемет не страшен!
-
-[RM5_6]
-~g~Он вывалился! Раскатай его по асфальту, или взорви гранатами!
-
-[RM5_7]
-~r~Свидетеля доставили на место!
-
-[RM5_8]
-~g~Свидетеля больше нет!
-
-[RM5_A]
-Ты никчемный ублюдок!
-
-[RM5_A1]
-Ты все завалил! Я уже на крючке, а ты даже не смог поджарить этого хренова шпиона.
-
-[RM5_B]
-Я же тебе хорошо заплатил за то, чтобы ты убрал этого стукача!
-
-[RM5_B1]
-Сегодня этот урод собирается давать показания!
-
-[RM5_C]
-Его с минуты на минуту собираются перевезти из госпиталя Карсон в участок Рокфорда.
-
-[RM5_D]
-Если он заговорит, мне конец...
-
-[RM5_E]
-так что иди, и доделывай свою работу!
-
-[RM6]
-'НА МУШКЕ'
-
-[RM6_1]
-Вот тебе ключ от тайника.
-
-[RM6_2]
-В нем я на черный день припрятал наличные и кое-какие полезные вещички.
-
-[RM6_3]
-Увидимся.
-
-[RM6_4]
-~g~Отправляйся к тайнику и забери вещички Рэя.
-
-[RM6_5]
-~g~Мост под наблюдением ЦРУ. Тебе придется найти другой путь.
-
-[RM6_6]
-~r~Рэй мертв!
-
-[RM6_666]
-Возьми мой пуленепробиваемый Пэтриот. Увидимся в Майами, Рэй
-
-[RM6_7]
-~r~Рэй опоздал на самолет.
-
-[RM6_8]
-~g~Ты проехал мимо Рэя, вернись и посади его.
-
-[RM6_A]
-За тобой хвоста нет? Хорошо.
-
-[RM6_B]
-Похоже, я прыгнул выше головы и перешел кое-кому дорогу!
-
-[RM6_C]
-Я так понял, что ЦРУ имеет долю от продажи СПАНКА
-
-[RM6_C1]
-и они убирают тех, кто мешает Картелю работать.
-
-[RM6_D]
-Я у них на мушке, мне нужно быстрее сваливать.
-
-[RM6_E]
-Мой самолет вот-вот отлетает, гони в аэропорт, я хорошо заплачу!
-
-[ROADBR1]
-Мост Каллахан
-
-[ROADBR2]
-Мост Каллахан
-
-[RUMPO]
-Рампо
-
-[SAVE1]
-Чтобы ~h~сохранить игру~w~ - пройди в дверь. Во время задания записаться нельзя.
-
-[SAVE2]
-Если в гараже оставить машину, то она будет сохранена при записи игры.
-
-[SCASSL]
-Sick Fuck Selected
-
-[SCORE]
-$~1~
-
-[SCRFOR]
-Screen format
-
-[SCROPT]
-НАСТРОЙКИ ЭКРАНА
-
-[SCSCSL]
-Sick Fucker Selected
-
-[SECOND]
-~g~второй
-
-[SECURI]
-Инкассатор
-
-[SENTINL]
-Сентинел
-
-[SEP]
-Сен
-
-[SET1]
-SetUp 1.
-
-[SET1EN]
-SetUp 1. Enabled
-
-[SET2]
-SetUp 2
-
-[SET2EN]
-SetUp 2. Enabled
-
-[SET3]
-SetUp 3
-
-[SET3EN]
-SetUp 3. Enabled
-
-[SET4]
-SetUp 4
-
-[SET4EN]
-SetUp 4. Enabled
-
-[SFXVOL]
-Громкость звуков
-
-[SHOPING]
-Бедфорд Поинт
-
-[SHPLOF]
-gbShowCollisionPolys Off
-
-[SHPLON]
-gbShowCollisionPolys On
-
-[SICASS]
-Sick Fuck
-
-[SICSIC]
-Sick Fucker
-
-[SIREN_1]
-Чтобы включить сирену, понажимай кнопку ~h~~k~~VEHICLE_HORN~~w~.
-
-[SIREN_2]
-Чтобы включить сирену, понажимай кнопку ~h~~k~~VEHICLE_HORN~~w~.
-
-[SIREN_3]
-Чтобы включить сирену, понажимай кнопку ~h~~k~~VEHICLE_HORN~~w~.
-
-[SIREN_4]
-Чтобы включить сирену, понажимай кнопку ~h~~k~~VEHICLE_HORN~~w~.
-
-[SLNSP]
-Insufficient space to save. Please insert a Memory Card (PS2) with at least 200KB of free space available into MEMORY CARD slot 1.
-
-[SLONDR]
-Insufficient space to save. Please insert a Memory Card (PS2) with at least 500KB of free space available into MEMORY CARD slot 1.
-
-[SLONFM]
-Error formatting Memory Card (PS2) in MEMORY CARD slot 1.
-
-[SLONNF]
-Memory Card (PS2) in MEMORY CARD slot 1 is unformatted.
-
-[SLONNO]
-No Memory Card (PS2) in MEMORY CARD slot 1.
-
-[SOAKED]
-ЧЕРТ!
-
-[SOUND]
-ЗВУК
-
-[SPAIN]
-Spanish
-
-[SPEEDER]
-Speeder
-
-[SPLAT]
-ГОТОВ!
-
-[SPOTTED]
-~r~Они у тебя на хвосте!
-
-[SPRAY]
-В мастерской твою тачку ~h~отремонтируют~w~ и ~h~перекрасят~w~. Копы тебя больше ~h~не узнают~w~. Стоимость - ~h~$1000~w~.
-
-[SPRAY1]
-В мастерской твою тачку ~h~отремонтируют~w~ и ~h~перекрасят~w~. Копы тебя больше ~h~не узнают~w~. Стоимость - ~h~$1000~w~. Первый раз это бесплатно.
-
-[SPRAY_1] { re3 change }
-Чтобы включить брандспойт, нажми на ~h~~k~~VEHICLE_FIREWEAPON~~w~.
-
-[SPRAY_4] { re3 change }
-Чтобы включить брандспойт, нажми на ~h~~k~~VEHICLE_FIREWEAPON~~w~.
-
-[STADIUM]
-Аспатрия
-
-[STALION]
-Жеребец
-
-[STANDS]
-ЛАРЬКОВ РАЗБИТО:
-
-[STASH]
-~g~Отвези СПАНК на ~p~стройку~g~!
-
-[STINGER]
-Стингер
-
-[STOCK]
-отсутствует
-
-[STRETCH]
-Стретч
-
-[SUBWAY1]
-Станция Портланд
-
-[SUBWAY2]
-Станция Рокфорд
-
-[SUBWAY3]
-Станция Южный Стаунтон
-
-[SUBWAY4]
-Вокзал Шорсайд
-
-[SUB_IND]
-Пайк Крик
-
-[SUB_ZO2]
-Шорсайд Вейл
-
-[SUB_ZO3]
-Шорсайд Вейл
-
-[SUB_ZON]
-Шорсайд Вейл
-
-[SVCONF]
-ПОДТВЕРДИТЕ ЗАПИСЬ
-
-[SVGMON]
-SaveTheGame
-
-[SWANKS]
-Кедровая роща
-
-[S_PROM2]
-Если в этот гараж поставить машину, то она будет сохранена при записи игры.
-
-[S_PROMP]
-Когда ты не на задании, то здесь можно ~h~сохранить игру~w~, но это добавит ко времени шесть часов.
-
-[S_TRN_1]
-Воспользовавшись метро, ты можешь попасть в другой район города. Нажми~h~ ~k~~VEHICLE_ENTER_EXIT~~w~ чтобы ~h~сесть~w~ или ~h~выйти~w~ из поезда.
-
-[S_TRN_2]
-Воспользовавшись метро, ты можешь попасть в другой район города. Нажми~h~ ~k~~VEHICLE_ENTER_EXIT~~w~ чтобы ~h~сесть~w~ или ~h~выйти~w~ из поезда.
-
-[S_VIEW]
-Портланд Вью
-
-[T4X4_1]
-'ПЭТРИОТ РАЛЛИ'
-
-[T4X4_1A]
-~g~У тебя ~y~5 минут~g~ чтобы пройти ~y~15 контрольных пунктов~g~. Ты можешь их проходить в ~y~ЛЮБОМ~g~ порядке.
-
-[T4X4_1B]
-~1~ из 15!
-
-[T4X4_1C]
-~g~Отсчет времени пойдет, как только ты ~y~ПРОЕДЕШЬ~g~ через первый контрольный пункт. После прохождения каждой точки тебе будет добавляться ~y~20 секунд~g~.
-
-[T4X4_2]
-'ГОНКА В ПАРКЕ'
-
-[T4X4_2A]
-~g~У тебя ~y~5 минут~g~ чтобы пройти ~y~12 контрольных пунктов~g~. Ты можешь их проходить в ~y~ЛЮБОМ~g~ порядке.
-
-[T4X4_2B]
-~1~ из 12!
-
-[T4X4_2C]
-~g~Отсчет времени пойдет, как только ты ~y~ПРОЕДЕШЬ~g~ через первый контрольный пункт. После прохождения каждой точке тебе будет добавляться ~y~10 секунд~g~.
-
-[T4X4_3]
-'ЖАРКАЯ ГОНКА'
-
-[T4X4_3A]
-~g~У тебя ~y~5 минут~g~, чтобы пройти ~y~20 контрольных пунктов~g~. Ты можешь их проходить в ~y~ЛЮБОМ~g~ порядке.
-
-[T4X4_3B]
-~g~Отсчет времени пойдет, как только ты ~y~ПРОЕДЕШЬ~g~ через первый контрольный пункт. После прохождения каждой точки тебе будет добавляться ~y~15 секунд~g~.
-
-[T4X4_3C]
-~1~ из 20!
-
-[T4X4_F]
-~r~Ты не успел! Слишком сложно для тебя?!
-
-[TAXI]
-Такси
-
-[TAXI1]
-~g~Ищи пассажира.
-
-[TAXI2]
-~r~Ты не успел вовремя!
-
-[TAXI3]
-~r~Твой пассажир бежал в ужасе!
-
-[TAXI4]
-Пассажир доставлен!
-
-[TAXI5]
-ПРИЗ ЗА СКОРОСТЬ!
-
-[TAXI6]
-Задание такси окончено
-
-[TAXI7]
-~r~Такси слишком помято, отремонтируй его.
-
-[TAXIH1]
-Остановись рядом с указанным пешеходом, подожди, пока он не сядет в такси и за указанное время отвези его куда он хочет.
-
-[TAXI_M]
-'ВОДИТЕЛЬ ТАКСИ'
-
-[TEFONE]
-Test Format MemCard One
-
-[TEUFON]
-Test UnFormat MemCard One
-
-[TEXTXYZ]
-Writing coordinates to file...
-
-[THIRD]
-~g~третий
-
-[TIMER]
-Это задание на время, ты должен успеть его выполнить, пока тикает таймер.
-
-[TM1]
-'БОЛЬШАЯ СТИРКА'
-
-[TM1_A]
-~w~Присаживайся, малыш, давай присаживайся.
-
-[TM1_B]
-~w~Итак, прачечная не хочет платить за защиту?
-
-[TM1_C]
-~w~Триадовцы думают, что могут тягаться со мной?
-
-[TM1_D]
-~w~Давай-ка покажем этим 'крутым парням', что значит быть действительно крутым.
-
-[TM1_E]
-~w~Да, преподай им урок. Еще никто из нас не отступал перед Триадой.
-
-[TM1_F]
-~w~Твой отец, упокой господь его душу, не цацкался с ними на Сицилии.
-
-[TM1_G]
-~w~Извини Ма. Да, Ма.
-
-[TM1_H]
-~w~Я хочу чтобы ты взорвал все фургоны прачечной
-
-[TM1_I]
-~w~и прикончил Триадовцев, что встанут у тебя на пути.
-
-[TM1_J]
-~w~Все, что для этого нужно, ты можешь взять у Лысого.
-
-[TM2]
-'МЗДА'
-
-[TM2_1]
-~g~Отвези деньги Тони!
-
-[TM2_2]
-~g~Ты загасил их всех!
-
-[TM2_3]
-~g~Это ловушка! Прикончи их!
-
-[TM2_A]
-~w~Тони пошел на очередное дело.
-
-[TM2_AA]
-~w~Он никогда не станет таким авторитетом, как отец. Вон тебе записка.
-
-[TM2_B]
-~w~Прачечная согласна платить - ты все сделал как нужно!
-
-[TM2_C]
-~w~Иди, забери деньги и принеси их мне. Но остерегайся триадовцев.
-
-[TM2_D]
-~w~Они решили поджарить твою задницу, но не бери это в голову, сынок.
-
-[TM2_E]
-~w~Никто, повторяю, никто не связывается с ТОНИ СИПРИАНИ!
-
-[TM3]
-'СОБРАНИЕ СЕМЬИ САЛЬВАТОРЕ'
-
-[TM3_1]
-~g~Возьми у Джоуи Стретч.
-
-[TM3_2]
-~g~Теперь езжай за Луиджи.
-
-[TM3_3]
-~g~Теперь забери Тони.
-
-[TM3_4]
-~g~Отвези приятелей в особняк Сальваторе.
-
-[TM3_5]
-~y~Это засада Триады!
-
-[TM3_A]
-~w~Дон Сальваторе решил нас всех собрать
-
-[TM3_A1]
-~r~Джоуи поджарился!
-
-[TM3_A2]
-~r~Джоуи и Луиджи кремированы!
-
-[TM3_A3]
-~r~Джоуи, Тони и Луиджи спеклись!
-
-[TM3_B]
-~w~Нужно заехать к Джоуи, и забрать лимузин и его самого из гаража.
-
-[TM3_C]
-~w~Затем отправишься в клуб за Луиджи, и потом заедешь за мной,
-
-[TM3_D]
-~w~Сегодня нам всем босс назначил встречу у него в особняке.
-
-[TM3_E]
-~w~Эти Триадовцы должны знать свое место.
-
-[TM3_F]
-~w~Им нужна война, они ее получат.
-
-[TM3_G]
-~w~Давай, отправляйся.
-
-[TM3_H]
-~w~Ты молодец, парень, просто молодец.
-
-[TM3_I]
-~w~Пошли, познакомлю тебя с доном.
-
-[TM3_J]
-~w~Эээй! Луиджи!
-
-[TM3_K]
-~w~О, Сальваторе, мои девочки по тебе уже соскучились, тебя так долго не было.
-
-[TM3_L]
-~w~Передай им, что как только мы закончим это небольшое дельце,
-
-[TM3_M]
-~w~то отправимся в клуб и отпразднуем, хорошо?
-
-[TM3_MA]
-~w~Да не знаю я, где он!
-
-[TM3_MB]
-~w~Я уверена, что он сам себя иногда не понимает.
-
-[TM3_MC]
-~w~Они с отцом такие разные. Отец, тот всегда при деле, решительный...
-
-[TM3_N]
-~w~Вот он, мой мальчик.
-
-[TM3_N2]
-~w~Как у тебя дела, пап?
-
-[TM3_O]
-~w~Ты еще не нашел себе хорошую девушку?
-
-[TM3_P]
-~w~Эй, твоя мама, упокой господь ее душу, перевернулась бы в могиле,
-
-[TM3_Q]
-~w~если бы увидела тебя без жены.
-
-[TM3_R]
-~w~Я знаю, па, я над этим работаю.
-
-[TM3_S]
-~w~Тони, как твоя мама?
-
-[TM3_T]
-~w~Знаешь, она чудесная женщина. Сильная. Умная.
-
-[TM3_U]
-~w~У нее все...хорошо.
-
-[TM3_V]
-~w~Прекрасно, прекрасно. Слушайте, парни, проходите внутрь, а я пока поговорю с нашим новым другом.
-
-[TM3_W]
-~w~Я смотрю ты многое для нас сделал, парень...
-
-[TM4]
-'ПЕРЕПОЛОХ В ЧАЙНАТАУНЕ'
-
-[TM4_A]
-~w~Ах, это ты. Тони сейчас нет.
-
-[TM4_A2]
-~w~Но он оставил тебе одно из своих любовных посланий.
-
-[TM4_B]
-~w~Мы в состоянии ВОЙНЫ! Триада использует рыбный завод в качестве прикрытия.
-
-[TM4_C]
-~w~Они проворачивают свои темные делишки на рыбном рынке в Чайнатауне.
-
-[TM4_D]
-~w~Прачечная опять задолжала нам деньги.
-
-[TM4_E]
-~w~Они считают, что за защиту лучше платить Триаде, так что придется их снова наказать.
-
-[TM4_F]
-~w~Накажи этих умников, и нанеси визит боссам Триады!
-
-[TM4_G]
-~w~Черт, если представится шанс, убей заодно и несколько их солдат.
-
-[TM4_GAT]
-~g~Чтобы тебя пропустили, возьми фургон Триады.
-
-[TM5]
-'ВЗРЫВ НА ЗАВОДЕ'
-
-[TM5_B]
-~w~OK, мне надоело это дерьмо.
-
-[TM5_C]
-~w~Нужно закончить разборки с Триадой раз и навсегда!
-
-[TM5_D]
-Лысый установил бомбу в мусоровоз.
-
-[TM5_E]
-~w~Бомба на таймере, так что много времени на размышления у тебя не будет. Бери машину.
-
-[TM5_F]
-~w~Будь осторожен на дороге, Лысый сказал. что бомба может рвануть от любого столкновения!
-
-[TM5_G]
-~w~Они откроют ворота для мусоровоза, так что ты без проблем проедешь на завод.
-
-[TM5_H]
-~w~Припаркуй мусорку между двумя резервуарами с бензином и быстрее уноси ноги!
-
-[TM5_I]
-~w~Пусть пойдет дождь из скумбрии.
-
-[TM5_J]
-~w~Нам нужен библейский апокалипсис, а не какая-то дешевка.
-
-[TM_BUST]
-Число ваших арестов
-
-[TM_DED]
-Число визитов в больницу
-
-[TONI]
-ЗАДАНИЯ ТОНИ
-
-[TONIGO]
-~g~Тони повез свою мамочку в оперу. Зайди позже!
-
-[TONI_P]
-У меня есть для тебя одно срочное дело! - Тони
-
-[TOWERS]
-Хепберн Хейтс
-
-[TOYZ]
-Фургон игрушек
-
-[TRAIN]
-Поезд
-
-[TRAIN_1]
-Станция Куровски
-
-[TRAIN_2]
-Станция Ротвелл
-
-[TRAIN_3]
-Станция Бейли
-
-[TRASH]
-~g~Ты сильно помял свою тачку! Езжай и отремонтируй ее!
-
-[TRASHM]
-Мусоровоз
-
-[TRINST]
-Тройной безумный трюк
-
-[TSCORE]
-ЗАРАБОТАНО: $~1~
-
-[TSCORE2]
-$~1~
-
-[TTUTOR]
-Чтобы заняться работой таксиста или отказаться от нее, нажми кнопку ~h~~k~~TOGGLE_SUBMISSIONS~~w~.
-
-[TTUTOR2]
-Чтобы заняться работой таксиста или отказаться от нее, нажми кнопку ~h~~k~~TOGGLE_SUBMISSIONS~~w~.
-
-[TUBE1]
-Как только откроется метро, ты сможешь на нем проехать на остров Стаунтон.
-
-[TUBE2]
-Как только откроется Шорсайд Вейл, ты сможешь выйти на вокзале Шорсайд, чтобы попасть в аэропорт Фрэнсис.
-
-[TUBE_2]
-чтобы сесть на электричку в метро - нажми ~h~~k~~VEHICLE_ENTER_EXIT~~w~.
-
-[TUNNEL]
-Как только откроется туннель Портер, ты сможешь проехать на остров Стаунтон.
-
-[TUNNELP]
-Туннель Портер
-
-[UNFRM1]
-UnFormatMemCard 1 (teststuff)
-
-[UNIVERS]
-Учебный городок
-
-[UPSIDE]
-~r~Ты перевернул тачку!
-
-[USJ]
-ПРИЗ ЗА ОСОБЫЙ ТРЮК!
-
-[USJI1]
-TEXT NO LONGER REQUIRED
-
-[USJI2]
-TEXT NO LONGER REQUIRED
-
-[USJI3]
-TEXT NO LONGER REQUIRED
-
-[USJ_ALL]
-ТЫ ИСПОЛНИЛ ВСЕ ОСОБЫЕ ТРЮКИ!
-
-[UZI_IN]
-В магазин оружия завезли 'Узи'!
-
-[VANHSTP]
-Решил вскрыть еще несколько Инкассаторов? Пригони их в наш гараж в гавани Портланда.
-
-[WANTED1]
-~g~Стряхни копов с хвоста и понизь их заинтересованность в тебе!
-
-[WANT_A]
-Тебя арестовывают лишь в том случае, если ты ~h~объявлен в розыск~w~.
-
-[WANT_B]
-Величина ~h~уровня розыска~w~ отображается строкой звездочек в верхнем правом углу экрана.
-
-[WANT_C]
-Сейчас твой ~h~уровень розыска~w~ равен одному...
-
-[WANT_D]
-двум...
-
-[WANT_E]
-трем...
-
-[WANT_F]
-Чем выше твой ~h~уровень розыска~w~, тем больше сил будет брошено на твой арест.
-
-[WANT_G]
-После ~h~ареста~w~ тебя отвозят в ближайший полицейский участок
-
-[WANT_H]
-Копы забирают у тебя все оружие и часть денег в качестве взятки.
-
-[WANT_I]
-Твое текущее задание будет считаться проваленным.
-
-[WANT_J]
-Во время игры ты найдешь разные способы понижать ~h~уровень розыска~w~.
-
-[WANT_K]
-~h~Уровень розыска~w~ сбрасывается после того, как машина будет ~h~ПЕРЕКРАШЕНА~w~.
-
-[WEATHE2]
-ОБЫЧНАЯ ПОГОДА
-
-[WEATHER]
-НЕНАСТЬЕ
-
-[WELCOME]
-ДОБРО ПОЖАЛОВАТЬ
-
-[WHOOPEE]
-М-р.Вупи
-
-[WIN_95]
-Grand Theft Auto III }u ~ytu‚ ~t Windows 95
-
-[WIN_DX]
-Grand Theft Auto III ‚Ђuqѓu‚ DirectX ruЂЃxx }u }xvu 8.1
-
-[WIN_RSZ]
-]u ѓtp{~ЃЊ ѓЃ‚p}~rx‚Њ }~r~u ЂpwЂu€u}xu ЌzЂp}p
-
-[WIN_TTL]
-Grand Theft Auto III
-
-[WIN_VDM]
-Grand Theft Auto III ‚Ђuqѓu‚ }p rxtu~zpЂ‚u }u |u}uu 12\q p|Џ‚x
-
-[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).
-
-[WRCONTE]
-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).
-
-[WRECKED]
-~r~Машина разбита!
-
-[WRONGCD]
-Неверный диск. Пожалуйста, вставьте нужный диск.
-
-[WRONGT1]
-~g~За работой приходи между 05:00 и 21:00
-
-[WRONGT2]
-~g~За работой приходи между 06:00 и 14:00
-
-[WRONGT3]
-~g~За работой приходи между 15:00 и 00:00
-
-[X]
-x
-
-[Y1JLAST]
-~r~Пришел последним! Ты болтаешь как водила, а водишь как болтун!
-
-[Y1_1ST]
-~g~Ты пришел первым, пройдя ~1~ контрольных пунктов!
-
-[Y1_2ND]
-~y~Ты пришел вторым, пройдя ~1~ контрольных пунктов. ~y~Неплохо, но ты не победил!
-
-[Y1_3RD]
-~r~Ты пришел третьим, пройдя ~1~ контрольных пунктов. ~r~Я был о тебе более высокого мнения!
-
-[Y1_J1ST]
-~y~Ты пришел первым, пройдя ~1~ контрольных пунктов. ~y~Хорошо, но ты должен быть лучшим, чтобы получить Королеву Лиззи!
-
-[Y1_J2ND]
-~r~Ты пришел вторым, пройдя ~1~ контрольных пунктов. Ты водишь как бешеная макака!
-
-[Y1_LAST]
-~r~Ты пришел последним! ~r~Ты просто тратишь мое время, ДУРАК!
-
-[Y1_TEST]
-МАШИНА В ВОДЕ!
-
-[YAKUSA]
-Торрингтон
-
-[YAKUZCR]
-Стингер Якудзы
-
-[YANKEE]
-Янки
-
-[YARDICR]
-Лобо Ярди
-
-[YARDIE]
-ЗАДАНИЯ ЯРДИ
-
-[YD1]
-'БЫСТРЫЕ ТАЧКИ - ЛЕГКИЕ ДЕНЬГИ'
-
-[YD1GO]
-~g~СТАРТ!
-
-[YD1_1]
-~r~ОДИН
-
-[YD1_2]
-~r~ДВА
-
-[YD1_3]
-~r~ТРИ
-
-[YD1_A]
-~w~Это король Куртни.
-
-[YD1_A1]
-~w~Мои Ярди хотят устроить хорошую гонку, а я слышал, что ты крутой водила.
-
-[YD1_B]
-~w~Приезжай на своей тачке на пустырь за стадионом и жди там других участников заезда.
-
-[YD1_BON]
-$1000!!
-
-[YD1_C]
-~w~Мои люди будут наблюдать за всеми контрольными точками.
-
-[YD1_CNT]
-~1~ из 15!
-
-[YD1_D]
-~w~Тот кто пройдет контрольный пункт первым - получит приз, и так далее.
-
-[YD1_D1]
-~w~Если ты проедешь больше контрольных пунктов, чем мои ребята, я дам тебе работу.
-
-[YD1_E]
-~g~Готовься к гонке!
-
-[YD1_F]
-~g~Мощный старт - мне нравится твой стиль!
-
-[YD1_G]
-~r~Это гонка на МАШИНАХ. Тебе нужна МАШИНА, кретин!
-
-[YD2]
-'РЕЙД С 'УЗИ'
-
-[YD2_A]
-~w~Посмотрим, сможешь ли ты сделать за меня грязную работу.
-
-[YD2_A1]
-~w~Узнаем, можно ли тебе доверять.
-
-[YD2_B]
-~w~Сейчас подойдут двое моих парней, и ты пойдешь покатаешься с ними,
-
-[YD2_B1]
-~w~посмотрим, чего ты стоишь на самом деле.
-
-[YD2_C]
-~w~Давай, покатайся по Хепберн Хейтс и прикончи нескольких Дьяволов - они надоедают королеве Лиззи.
-
-[YD2_CC]
-~w~Вот, это тебе пригодится.
-
-[YD2_D]
-~w~Вести и стрелять будешь ты, ну а мы проследим чтобы ты не скопытился.
-
-[YD2_E]
-~w~Поехали!
-
-[YD2_F]
-~r~Он имел что-то против нас, пореши этого ублюдка!
-
-[YD2_G1]
-~w~Хепберн Хейтс...Давай ка прикончи несколько тупых Дьяволов...
-
-[YD2_G2]
-~w~Но запомни, ~r~Из машины тебе выходить нельзя!
-
-[YD2_H]
-~w~Ок, возвращаемся на нашу территорию! ВПЕРЕД!
-
-[YD2_L]
-~w~Отличная работа, Жнец!
-
-[YD2_M]
-~r~Он разбил мою тачку! Прикончи его!
-
-[YD2_N]
-~w~У тебя 5 секунд, чтобы вернуться в тачку!
-
-[YD3]
-'МАШИНЫ БАНД'
-
-[YD3_A]
-Я хотел бы получить тачки некоторых банд
-
-[YD3_A1]
-чтобы без помех провернуть дела на их территории.
-
-[YD3_B]
-Мне нужен Сентинел Мафии,
-
-[YD3_B1]
-Стингер Якудзы и
-
-[YD3_B2]
-Жеребец Дьяволов, для маскировки под их людей.
-
-[YD3_C]
-Отгони их в мой гараж в Ньюпорте, но запомни,
-
-[YD3_C1]
-мне не нужны помятые тачки!
-
-[YD3_D]
-Перебей номера
-
-[YD3_E]
-~r~Ты уже своровал тачку Дьяволов!
-
-[YD3_F]
-~r~Ты уже своровал тачку Мафии!
-
-[YD3_G]
-~r~Ты уже своровал тачку Якудзы!
-
-[YD3_H]
-~g~Тачка Дьяволов сворована!
-
-[YD3_I]
-~g~Тачка мафии сворована!
-
-[YD3_J]
-~g~Тачка Якудзы сворована!
-
-[YD3_K]
-~r~Машина сильно помята! Отремонтируй ее!
-
-[YD3_L]
-~g~Отгони ее в ~p~гараж~g~!
-
-[YD3_M]
-~r~Ты перевернулся! Ищи другую тачку!
-
-[YD4]
-'ПОДСТАВА'
-
-[YD4_1]
-~g~Обкурившиеся психи!
-
-[YD4_2]
-~g~Взорви фургоны камикадзе!
-
-[YD4_A]
-Короче, слушай!
-
-[YD4_A1]
-Отправляйся в Бедфорд Поинт.
-
-[YD4_A2]
-Там у меня тайник в старой тачке, сгоняй за ней!
-
-[YD4_B]
-ПИСЬМО: Говорят, ты нашел себе работу. Я тоже не сидела сложа руки.
-
-[YD4_C]
-Пришло тебе время почувствовать тебе силу СПАНКа! Besos y fuderes, Каталина, xxx.
-
-[YD4_D]
-PS: УМРИ, ПАРШИВЫЙ ПЕС, УМРИ!
-
-[YD_P]
-С тобой хочет побазарить король Куртни. Подойди к телефону на Аспатрии!
-
-[YES]
-Да
-
-[Z]
-Значение по оси Z: ~1~
-
-{ re3 updates }
-{ new languages }
-[FEL_JAP]
-ЯПОНСКИЙ
-
-[FEL_POL]
-ПОЛЬСКИЙ
-
-[FEL_RUS]
-РУССКИЙ
-
-{ new display menus }
-[FET_GFX]
-НАСТРОЙКА ГРАФИКИ
-
-[FED_MIP]
-МИП-МАППИНГ
-
-[FED_AAS]
-СГЛАЖИВАНИЕ
-
-[FED_FIL]
-ТЕКСТУРНАЯ ФИЛЬТРАЦИЯ
-
-[FED_BIL]
-БИЛИНЕЙНАЯ
-
-[FED_TRL]
-ТРИЛИНЕЙНАЯ
-
-[FED_WND]
-ОКОННЫЙ
-
-[FED_FLS]
-ПОЛНОЭКРАННЫЙ
-
-[FEM_CSB]
-CUTSCENE BORDERS
-
-[FEM_SCF]
-ФОРМАТ ОКНА
-
-[FEM_ISL]
-MAP MEMORY USAGE
-
-[FEM_LOW]
-LOW
-
-[FEM_MED]
-MEDIUM
-
-[FEM_HIG]
-HIGH
-
-[FEM_2PR]
-PS2 ALPHA TEST
-
-[FEC_FRC]
-СВОБОДНАЯ КАМЕРА
-
-{ Linux joy detection }
-[FEC_JOD]
-DETECT JOYSTICK
-
-[FEC_JPR]
-Press any key on the joystick of your choice that you want to use on the game, and it will be selected.
-
-[FEC_JDE]
-Detected joystick
-
-{ mission restart }
-[FET_RMS]
-ПОВТОРИТЬ ЗАДАНИЕ
-
-[FESZ_RM]
-НАЧАТЬ ЗАНОВО?
-
-{ more graphics }
-[FED_VPL]
-VEHICLE PIPELINE
-
-[FED_PRM]
-PED RIM LIGHT
-
-[FED_RGL]
-ROAD GLOSS
-
-[FED_CLF]
-COLOUR FILTER
-
-[FED_WLM]
-WORLD LIGHTMAPS
-
-[FED_MBL]
-MOTION BLUR
-
-[FEM_SIM]
-SIMPLE
-
-[FEM_NRM]
-NORMAL
-
-[FEM_MOB]
-MOBILE
-
-[FED_MFX]
-MATFX
-
-[FED_NEO]
-NEO
-
-[FEM_PS2]
-PS2
-
-[FEM_XBX]
-XBOX
-
-[FEM_AUT] { aspect ratio related }
-АВТО
-
-{ controls }
-[FEC_IVP]
-ИНВЕРТИРОВАТЬ ВЕРТИКАЛЬНУЮ ОСЬ
-
-{ map }
-[FEM_TWP]
-Поставить метку
-
-[FEA_FMN]
-РАДИО ВЫКЛ
-
-[FEC_DS2]
-DUALSHOCK 2
-
-[FEC_DS3]
-DUALSHOCK 3
-
-[FEC_DS4]
-DUALSHOCK 4
-
-[FEC_360]
-КОНТРОЛЛЕР XBOX 360
-
-[FEC_ONE]
-КОНТРОЛЛЕР XBOX ONE
-
-[FEC_TYP]
-ГЕЙМПАД
-
-[FEC_CCF]
-КОНФИГУРАЦИЯ
-
-[FEC_CF1]
-СХЕМА 1
-
-[FEC_CF2]
-СХЕМА 2
-
-[FEC_CF3]
-СХЕМА 3
-
-[FEC_CF4]
-СХЕМА 4
-
-[FEC_CDP]
-ТИП УПРАВЛЕНИЯ
-
-[FEC_ONF]
-ПЕШКОМ
-
-[FEC_INC]
-В МАШИНЕ
-
-[FEC_VIB]
-ВИБРАЦИЯ
-
-[FET_AGS]
-НАСТРОЙКИ ГЕЙМПАДА
-
-[FEM_PED]
-PED DENSITY
-
-[FEM_CAR]
-CAR DENSITY
-
-{ end of file }
-
-[DUMMY]
-THIS LABEL NEEDS TO BE HERE !!!
-AS THE LAST LABEL DOES NOT GET COMPILED \ No newline at end of file
diff --git a/utils/gxt/spanish.txt b/utils/gxt/spanish.txt
index 5f108d3b..07d44c4c 100644
--- a/utils/gxt/spanish.txt
+++ b/utils/gxt/spanish.txt
@@ -10,147 +10,50 @@
a separate txt for it.
}
-{ Grand Theft Auto III Spanish (Spain) Translation }
+{ Grand Theft Auto Vice City Spanish (Spain) Translation }
{ Contains some of the official fixes made by Rockstar for the iOS port }
{ Additional translation rewrites, corrections and fixes by IlDucci }
-
-[LETTER1]
-abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789"$,.'-?!!SDBF
-
-[DEFNAM]
-Claude----------------------
-
[IN_VEH]
-~g~¡Oye! ¡Vuelve al vehículo!
-
-[IN_VEH2]
-~g~¡Necesitas un coche para realizar este trabajo!
-
-[IN_BOAT]
-~g~¡Necesitas una lancha para realizar este trabajo!
+~g~¡Eh! ¡Vuelve al vehículo!
[HEY]
-~g~¡No te vayas por tu cuenta! ¡Mantén a tu grupo unido!
-
-[HEY2]
-~g~¡No te separes del grupo!
-
-[HEY3]
-~g~¡Has perdido a tu colega! ¡Vuelve a por 8-Ball!
-
-[HEY4]
-~g~¡Si pierdes a Misty, Luigi te linchará! ¡Ve y recógela!
-
-[HEY5]
-~g~Una de las chicas se ha escapado, ¡vuelve y recógela!
-
-[HEY6]
-~g~Abandonaste tu honor con el kanbu de la yakuza. ¡Debes protegerlo!
-
-[HEY7]
-~g~Te vendría bien una ayudita. ¡Vuelve y encuentra a tu contacto!
-
-[HEY8]
-~g~Protección significa exactamente eso: ¡Protege al anciano oriental!
-
-[HEY9]
-~g~¿Sabes lo que tienes que hacer? ¡Ver a tu contacto!
-
-[HELP2_A]
-Pulsa el ~h~botón /~w~ mientras corres para ~h~esprintar~w~.
+~g~¡No vayas solo, mantén tu grupo unido!
[HELP3]
-Sólo puedes esprintar durante cortos periodos de tiempo antes de cansarte.
-
-[HELP4_A]
-Pulsa ~h~~k~~VEHICLE_ACCELERATE~~w~ para ~h~acelerar~w~.
+Solo puedes esprintar durante cortos periodos de tiempo, antes de cansarte.
[HELP4_D]
-Mueve el~h~ joystick analógico derecho~w~ hacia arriba para ~h~acelerar~w~.
-
-[HELP5_A]
-Pulsa ~h~~k~~VEHICLE_BRAKE~~w~ para ~h~frenar~w~ o para ~h~dar marcha atrás~w~ si el vehículo está detenido.
+Mueve el ~h~joystick analógico derecho~w~ hacia arriba para ~h~acelerar.
[HELP5_D]
-Mueve el ~h~joystick analógico derecho~w~ hacia atrás para ~h~frenar~w~ o para ~h~dar marcha atrás~w~ si el vehículo está detenido.
-
-[HELP6_A]
-Pulsa ~h~~k~~VEHICLE_HANDBRAKE~ ~w~para utilizar el ~h~freno de mano del vehículo~w~.
-
-[HELP6_C]
-Pulsa ~h~~k~~VEHICLE_HANDBRAKE~ ~w~para utilizar el ~h~freno de mano del vehículo~w~.
-
-[HELP6_D]
-Pulsa ~h~~k~~VEHICLE_HANDBRAKE~ ~w~para utilizar el ~h~freno de mano del vehículo~w~.
+Tira del ~h~joystick analógico derecho~w~ hacia atrás para ~h~frenar~w~, o para ~h~dar marcha atrás~w~ si el vehículo se ha detenido.
[HELP7_A]
-Mantén pulsado ~h~~k~~PED_LOCK_TARGET~ ~w~para ~h~apuntar~w~ con el fusil de francotirador.
+Pulsa y mantén pulsado el ~h~~k~~PED_LOCK_TARGET~ ~w~para ~h~apuntar~w~ con el rifle de francotirador.
[HELP7_D]
-Mantén pulsado ~h~~k~~PED_LOCK_TARGET~ ~w~para ~h~apuntar~w~ con el fusil de francotirador.
-
-[HELP8_A]
-Pulsa ~h~~k~~PED_SNIPER_ZOOM_IN~ ~w~para ~h~aumentar el zoom ~w~de la mira del fusil y ~h~~k~~PED_SNIPER_ZOOM_OUT~~w~ para ~h~reducirlo~w~.
-
-[HELP9_A]
-Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para ~h~disparar ~w~el fusil de francotirador.
+Pulsa y mantén pulsado el ~h~~k~~PED_LOCK_TARGET~ ~w~para ~h~apuntar~w~ con el rifle de francotirador.
[HELP10]
-Esta insignia indica que la policía te está buscando.
+Esta insignia indica que tienes un nivel de se busca por la policía.
[HELP11]
-Cuantas más insignias tengas, mayor será tu nivel de búsqueda.
+Cuantas más insignias tengas, mayor es tu nivel de se busca.
[HELP13]
-En ocasiones necesitarás ir por caminos que no aparecen en el radar.
+Algunas veces puedes necesitar ir por caminos que el radar no detecta.
[TIMER]
Ésta es una misión cronometrada, debes completarla antes de que el cronómetro llegue a cero.
-[MISTY1]
-~r~¡Misty está para el arrastre!
-
-[OUT_VEH]
-~g~¡Sal del vehículo!
-
-[GARAGE]
-Mete el vehículo dentro del garaje y sal andando.
-
-[WANTED1]
-~g~¡Despista a la poli y pierde tu nivel de búsqueda!
-
-[NODOORS]
-~g~¡No son sardinas! Consigue un vehículo con suficientes asientos.
-
-[TRASH]
-~g~¡Has dejado tu vehículo hecho unos zorros! ¡Haz que lo reparen!
-
-[WRECKED]
-~r~¡El vehículo está destrozado!
-
[HORN]
-~g~Toca el claxon.
-
-[HORN4]
-Pulsa el ~h~botón L3~w~ para tocar el ~h~claxon.
+~g~Toca la bocina.
[NOMONEY]
-~g~¡Necesitas más pasta!
-
-[OUTTIME]
-~r~¡Demasiado lento, tío, demasiado lento!
-
-[SPOTTED]
-~r~¡Te siguen la pista!
+~g~¡Necesitas más dinero!
[REWARD]
-RECOMPENSA: ~1~ $
-
-[GAMEOVR]
-FIN DE LA PARTIDA
-
-[Z]
-Valor del eje Z: ~1~
+RECOMPENSA ~1~ $
[M_FAIL]
¡MISIÓN FALLIDA!
@@ -158,92 +61,65 @@ Valor del eje Z: ~1~
[M_PASS]
¡MISIÓN SUPERADA! ~1~ $
-[O_PASS]
-¡TRABAJO ESPORÁDICO SUPERADO!
-
-[O_FAIL]
-¡TRABAJO ESPORÁDICO FRACASADO!
-
[DEAD]
¡ELIMINADO!
[BUSTED]
-¡TRINCADO!
+¡ARRESTADO!
-[S_PROMP]
-Cuando no estés en una misión, podrás ~h~guardar tu partida aquí~w~. Esto hará avanzar el tiempo seis horas.
+[WEATHE1]
+FORZAR TIEMPO SOLEADO
+
+[WEATHE2]
+FORZAR TIEMPO EXTREMADAMENTE SOLEADO
+
+[WEATHE3]
+FORZAR TIEMPO NUBLADO
+
+[WEATHE4]
+FORZAR TIEMPO LLUVIOSO
+
+[WEATHE5]
+FORZAR TIEMPO CON NIEBLA
+
+[WEATHE6]
+TIEMPO NORMAL
[NUMBER]
~1~
-[SCORE]
-~1~ $
-
[LOADCAR]
-CARGANDO VEHÍCULO... (PULSA EL BOTÓN L1 PARA CANCELAR)
+CARGANDO VEHÍCULO... (PULSA L1 PARA CANCELAR)
[CARSOFF]
-Coches activados.
+Coches desactivados.
[CARS_ON]
-Coches desactivados.
+Coches activados.
[TEXTXYZ]
-Escribiendo coordenadas al archivo...
+Escribiendo coordenadas en el archivo...
[CHEATON]
-Trucos ACTIVADOS
+Modo trucos ACTIVADO
[CHEATOF]
-Trucos DESACTIVADOS
-
-[UZI_IN]
-¡La Uzi ya está disponible en la tienda Ammu-Nation!
+Modo trucos DESACTIVADO
[IMPORT1]
-Sal y espera a tu vehículo.
-
-[PAGEB1]
-Pistola entregada en tu guarida.
-
-[PAGEB2]
-Uzi entregada en tu guarida.
-
-[PAGEB3]
-Chaleco antibalas entregado en tu guarida.
-
-[PAGEB4]
-Escopeta entregada en tu guarida.
-
-[PAGEB5]
-Granadas entregadas en tu guarida.
-
-[PAGEB6]
-Molotovs entregados en tu guarida.
-
-[PAGEB7]
-AK47 entregado en tu guarida.
-
-[PAGEB8]
-Fusil de francotirador entregado en tu guarida.
-
-[PAGEB9]
-M16 entregado en tu guarida.
-
-[PAGEB10]
-Lanzacohetes entregado en tu guarida.
+Ve fuera y espera tu vehículo.
[PAGEB11]
-Lanzallamas entregado en tu guarida.
+Entregado lanzallamas en el escondite
[WANT_A]
-Sólo serás arrestado si tienes un ~h~nivel de búsqueda~w~.
+Sólo serás arrestado si tienes un ~h~nivel de se busca.
[WANT_B]
-Tu ~h~nivel de búsqueda~w~ está representado por una hilera de estrellas en la parte superior derecha de la pantalla.
+Tu ~h~nivel de se busca~w~ viene representado por la fila de estrellas en la parte superior derecha de la pantalla.
[WANT_C]
-Ahora tienes un ~h~nivel de búsqueda~w~ de una estrella...
+Ahora tienes un ~h~nivel de se busca~w~ de una...
[WANT_D]
dos...
@@ -252,6717 +128,6745 @@ dos...
tres...
[WANT_F]
-A medida que aumente tu ~h~nivel de búsqueda~w~, serás perseguido por fuerzas con una mayor potencia de fuego.
+A medida que tu ~h~nivel de se busca~w~ aumente, atraerás a representantes más poderosos de las fuerzas policiales.
[WANT_G]
-Si te ~h~trinca~w~ la poli, te llevarán a la comisaría más cercana.
+Cuando te hayan ~h~''arrestado''~w~ serás conducido a la comisaría más cercana.
[WANT_H]
-Los agentes te requisarán todas tus armas y se quedarán con parte de tu dinero como soborno.
+Los polis te quitarán todas las armas y parte de tu dinero como soborno.
[WANT_I]
-Fracasarás cualquier misión que estuvieses llevando a cabo.
+Cualquier misión en la que estuvieses habrá fracasado.
[WANT_J]
-A medida que avances en el juego, encontrarás formas de reducir tu nivel de búsqueda.
+Encontrarás modos de reducir tu nivel de se busca cuanto más juegues.
[WANT_K]
-Si estás en un coche, los ~h~TALLERES DE PINTURA~w~ te quitarán ~h~tu nivel de búsqueda~w~.
+Si estás en un coche, el ~h~TALLER DE PINTURA~w~ limpiará ~h~tu nivel de búsqueda.
[HEAL_B]
-Cuando seas ~h~eliminado~w~, te llevarán al hospital más cercano.
+Cuando seas ~h~''eliminado''~w~ serás conducido al hospital más cercano.
[HEAL_C]
-Te quitarán tus armas y los médicos te cobrarán un dinero por curarte.
+Perderás tus armas y los médicos te quitarán algo de dinero por recomponerte.
[HEAL_E]
-A medida que avances en el juego, encontrarás modos de curarte o de protegerte.
+Encontrarás modos de curarte o de protegerte cuanto más juegues al juego.
-[DAM]
-DAÑO:
+[BRIBE1]
+Acabas de recoger un soborno de la policía, esto disminuirá en una estrella tu nivel de se busca.
-[KILLS]
-MUERTES:
+[SAVE1]
+Entra al corona para ~h~guardar la partida~w~. No puedes guardar durante una misión.
-[FARES]
-CARRERAS:
+[SAVE2]
+Cualquier vehículo que quede en este garaje será almacenado cuando se guarde la partida.
-[BULL]
-LINGOTES:
+[AMMU]
+Ve dentro de Ammu-Nation para comprar un arma.
-[EVID]
-PRUEBAS:
+[R_TIME]
+TIEMPO DE CARRERA:
-[HEALTH]
-ESTADO DEL COCHE:
+[PROP_1]
+No tienes suficiente dinero para adquirir esta propiedad
-[COLLECT]
-RECOGIDOS:
+[PROP_2]
+No puedes comprar propiedades mientras estás en una misión.
-[BOMB]
-Mete tu vehículo en la tienda de ~h~bombas~w~ para poner una. Coste: ~h~1.000 $~w~.
+[IND_ZON]
+Vice City Beach
-[SAVE1]
-Pasa por la puerta para ~h~guardar la partida~w~. No podrás guardar durante una misión.
+[COM_ZON]
+Península de Vice City
-[SAVE2]
-Cualquier vehículo que dejes en este garaje se conservará al guardar la partida.
+[BEACH1]
+Ocean Beach
-[AMMU]
-Entra en la tienda Ammu-Nation para comprar armas.
+[BEACH2]
+Washington Beach
-[BRIDGE1]
-Podrás conducir hasta Staunton Island cuando el puente Callahan esté reparado.
+[BEACH3]
+Vice Point
-[TUNNEL]
-Podrás conducir hasta Staunton Island cuando el túnel Porter esté abierto.
+[GOLFC]
+Leaf Links
-[LUIGI]
-MISIONES DE LUIGI
+[STARI]
+Starfish Island
-[TONI]
-MISIONES DE TONI
+[DOCKS]
+Viceport
-[JOEY]
-MISIONES DE JOEY
+[HAVANA]
+Little Havana
-[FRANK]
-MISIONES DE SALVATORE
+[HAITI]
+Little Haiti
-[DIABLO]
-MISIONES DE DIABLO
+[PORNI]
+Prawn Island
-[ASUKA]
-MISIONES DE ASUKA
+[DTOWN]
+Centro de la ciudad
-[B_SITE]
-MISIONES SUBURBANAS DE ASUKA
+[VICE_C]
+Vice City
-[KENJI]
-MISIONES DE KENJI
+[A_PORT]
+Escobar International
-[RAY]
-MISIONES DE RAY
+[JUNKY]
+Vertedero
-[LOVE]
-MISIONES DE LOVE
+[PISTOL]
+Pistola
-[YARDIE]
-MISIONES DE JAMAICANOS
+[PYTHON]
+.357
-[HOOD]
-MISIONES DE HOOD
+[UZI]
+Uz-1
-[CITYZON]
-Liberty City
+[TEC9]
+Tec 9
-[IND_ZON]
-Portland
+[M4]
+M4
-[PORT_W]
-Callahan Point
+[INGRAM]
+Mac
-[PORT_S]
-Muelle Atlantic
+[MP5]
+MP
-[PORT_E]
-Puerto de Portland
+[RUGER]
+Kruger
-[PORT_I]
-Trenton
+[SNIPE]
+Rifle de francotirador
-[S_VIEW]
-Portland View
+[GRENADE]
+Granadas
-[CHINA]
-Chinatown
+[SHOTGN1]
+Escopeta
-[EASTBAY]
-Playa de Portland
+[SHOTGN2]
+S.P.A.S. 12
-[LITTLEI]
-Saint Mark's
+[SHOTGN3]
+Escopeta de cañones recortados
-[REDLIGH]
-Red Light District
+[ARMOUR]
+Chaleco antibalas
-[TOWERS]
-Cerros de Hepburn
+[LASER]
+.308 Rifle de francotirador
-[HARWOOD]
-Harwood
+[BASEBAT]
+Bate de béisbol
-[ROADBR1]
-Puente Callahan
+[HAMMER]
+Martillo
-[ROADBR2]
-Puente Callahan
+[SCREWD]
+Destornillador
-[TUNNELP]
-Túnel Porter
+[CLEVER]
+Cuchillo de carnicero
-[BOMB1]
-Taller de 8-Ball
+[MACHETE]
+Machete
-[COM_ZON]
-Staunton Island
+[KNIFE]
+Cuchillo
-[STADIUM]
-Aspatria
+[KATANA]
+Katana
-[HOSPI_2]
-Rockford
+[CHAINSA]
+Sierra eléctrica
-[UNIVERS]
-Campus de Liberty
+[G_COST]
+~1~ $
-[CONSTRU]
-Fort Staunton
+[CAR_1]
+Ambulancia
-[PARK]
-Parque Belleville
+[MALIBU]
+El Club Malibú
-[COM_EAS]
-Newport
+[MANSION]
+Mansión de Díaz
-[SHOPING]
-Bedford Point
+[TMANS]
+Finca de Vercetti
-[YAKUSA]
-Torrington
+[STRIP]
+El Club Pole Position
-[SUB_ZON]
-Shoreside Vale
+[MALL1]
+Centro comercial North Point
-[AIRPORT]
-Aeropuerto Int. Francis
+[BANKINT]
+El Banco Corrupto Grande
-[PROJECT]
-Wichita Gardens
+[RANGE]
+Campo de tiro con rifle
-[SUB_IND]
-Pike Creek
+[POL_HQ]
+Cuartel general de VCPD
-[SWANKS]
-Cedar Grove
+[INT_B]
+Un viejo amigo
-[BIG_DAM]
-Presa Cochrane
+[INTB_1]
+~g~Ve a la oficina del Abogado.
-[SUB_ZO2]
-Shoreside Vale
+[LAW_1]
+La fiesta
-[SUB_ZO3]
-Shoreside Vale
+[LAW_2]
+Pelea en el callejón trasero
-[CAR_1]
-Ambulancia
+[LAW_3]
+Furia en el jurado
-[CAR_2]
-Camión de bomberos
+[LAW_4]
+Disturbios
-[CAR_3]
-Coche patrulla
+[COL_1]
+Cerdo traidor
-[CAR_4]
-Enforcer
+[COL_2]
+Tiros en el centro comercial
-[CAR_5]
-Barracks
+[COL_3]
+Ángeles guardianes
-[CAR_6]
-Rhino
+[COL_4]
+¡Señor, sí, señor!
-[CAR_7]
-Coche del FBI
+[COL_5]
+¡Todos con las manos arriba!
-[CAR_8]
-Securicar
+[COK_1]
+La caza
-[CAR_9]
-Moonbeam
+[COK_2]
+Phnom Penh '86
-[CAR_10]
-Coach
+[COK_3]
+El barco más rápido
-[CAR_11]
-Flatbed
+[COK_4]
+Oferta y demanda
-[CAR_12]
-Linerunner
+[KENT_1]
+El corredor de la muerte
-[CAR_13]
-Trashmaster
+[ASS_1]
+Borrar
-[CAR_14]
-Patriot
+[BUD_1]
+Extorsión
-[CAR_15]
-Mr. Whoopee
+[BUD_2]
+Pelea en el bar
-[CAR_16]
-Mule
+[BUD_3]
+Tierra de polis
-[CAR_17]
-Yankee
+[CAP_1]
+Liquida al cobrador
-[CAR_18]
-Pony
+[FIN_1]
+Mantén cerca a tus amigos...
-[CAR_19]
-Bobcat
+[BANK_1]
+¿Sin escapatoria?
-[CAR_20]
-Rumpo
+[BANK_2]
+El tirador
-[CAR_21]
-Blista
+[BANK_3]
+El conductor
-[CAR_22]
-Dodo
+[BANK_4]
+El atraco
-[CAR_23]
-Autobús
+[CNT_1]
+Descubriendo el pastel
-[CAR_24]
-Sentinel
+[CNT_2]
+Ataca al mensajero
-[CAR_25]
-Cheetah
+[PORN_1]
+Campaña de reclutamiento
-[CAR_26]
-Banshee
+[PORN_2]
+Consolador Dodo
-[CAR_27]
-Stinger
+[PORN_3]
+La foto policial de Marta
-[CAR_28]
-Infernus
+[PORN_4]
+Punto G
-[CAR_29]
-Esperanto
+[TAX_1]
+Taxis Kaufman
-[CAR_30]
-Kuruma
+[TAXI_1]
+V.I.P.
-[CAR_31]
-Stretch
+[TAXI_2]
+Rivalidad amistosa
-[CAR_32]
-Perennial
+[TAXI_3]
+Taxigedón
-[CAR_33]
-Landstalker
+[ICE_1]
+Distribución
-[CAR_34]
-Mañana
+[TEX_1]
+Hierro número cuatro
-[CAR_35]
-Idaho
+[TEX_2]
+Dos leves impactos
-[CAR_36]
-Stallion
+[TEX_3]
+Demoledor
-[CAR_37]
-Taxi
+[PHIL_1]
+Traficante de armas
-[CAR_38]
-Cabbie
+[PHIL_2]
+Boomshine Saigon
-[CAR_39]
-Buggy
+[BIKE_1]
+Moto con llantas de aleación
-[LUIGIS]
-Club de Luigi
+[BIKE_2]
+Incitando al macho
-[GOAWAY]
-~g~¡Ya estás en una misión!
+[BIKE_3]
+Moto robada
-[LUIGGO]
-~g~Luigi está entrevistando a unas chicas nuevas... ¡Vuelve más tarde!
+[ROCK_1]
+Love Juice
-[JOEYGO]
-~g~Joey ha salido con Misty. ¡Pásate más tarde!
+[ROCK_2]
+Asesino psicópata
-[TONIGO]
-~g~Toni ha llevado a su mamá a la ópera... ¡Vente en otro momento!
+[ROCK_3]
+Gira publicitaria
-[KEMUGO]
-~g~María y Kemuri están muy liadas... ¡Pásate más tarde!
+[ROCK_4]
+¡Love Fist!
-[KENJGO]
-~g~Kenji está reunido con la yakuza, ¡ven en otro momento!
+[HAT_1]
+Poción mágica
-[RAYGO]
-~g~Ray tiene otros baños por los que rondar, ¡ven en otro momento!
+[HAT_2]
+¡Bombas fuera!
-[LOVEGO]
-~g~Donald Love tiene otros asuntos que atender. ¡Pide una cita más tarde!
+[HAT_3]
+Juego sucio
-[KENSGO]
-~g~¡Kenji está ocupado! ¡Llama más tarde!
+[CUB_1]
+El desafío del barco trucado
-[ASUSGO]
-~g~¡Asuka no está disponible en este momento!
+[CUB_2]
+Carne de cañón
-[HOODGO]
-~g~¡Los Hoods no pueden atenderte en este momento!
+[CUB_3]
+Encuentro naval
-[WRONGT1]
-~g~Vuelve entre las 05:00 y las 21:00 para buscar trabajo.
+[CUB_4]
+Vudú troyano
-[WRONGT2]
-~g~Vuelve entre las 06:00 y las 14:00 para buscar trabajo.
+[JOB_1]
+Muerte en la carretera
-[WRONGT3]
-~g~Vuelve entre las 15:00 y las 00:00 para buscar trabajo.
+[JOB_2]
+Elimina a la esposa
-[GUN_1A]
-Pulsa ~h~~k~~PED_CYCLE_WEAPON_RIGHT~~w~ y ~h~~k~~PED_CYCLE_WEAPON_LEFT~ ~w~para cambiar de arma.
+[JOB_3]
+Autocidio
-[GUN_2A]
-¡Mantén pulsado ~h~~k~~PED_LOCK_TARGET~ ~w~para ~h~apuntar automáticamente~w~ y pulsa ~h~~k~~PED_FIREWEAPON~ ~w~para ~h~disparar! Intenta darle a las dianas...
+[JOB_4]
+Comprobar el registro
-[GUN_2C]
-¡Mantén pulsado ~h~~k~~PED_LOCK_TARGET~ ~w~para ~h~apuntar automáticamente~w~ y pulsa ~h~~k~~PED_FIREWEAPON~ ~w~para ~h~disparar! Intenta darle a las dianas...
+[JOB_5]
+Cabos sueltos
-[GUN_2D]
-¡Mantén pulsado ~h~~k~~PED_LOCK_TARGET~ ~w~para ~h~apuntar automáticamente~w~ y pulsa ~h~~k~~PED_FIREWEAPON~ ~w~para ~h~disparar! Intenta darle a las dianas...
+[ANSWER]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para responder a una llamada a tu teléfono móvil.
-[GUN_3A]
-Mientras mantienes pulsado ~h~~k~~PED_LOCK_TARGET~,~w~ pulsa ~h~~k~~PED_CYCLE_TARGET_LEFT~~w~ o ~h~~k~~PED_CYCLE_TARGET_RIGHT~ para cambiar de objetivo.
+[MOB_01A]
+¡Estás bien figura! Soy Paul. Puede que tenga algún resultado para ti, pero necesito hablar contigo cara a cara.
-[GUN_3B]
-Mientras mantienes pulsado ~h~~k~~PED_LOCK_TARGET~,~w~ pulsa ~h~~k~~PED_CYCLE_TARGET_LEFT~~w~ o ~h~~k~~PED_CYCLE_TARGET_RIGHT~ para cambiar de objetivo.
+[MOB_01B]
+Estoy de relax en el Malibu.
-[GUN_4A]
-Mientras mantienes pulsado ~h~~k~~PED_LOCK_TARGET~~w~, puedes moverte mientras sigues apuntando a tu objetivo.
+[MOB_01C]
+Creo que después de esto me vas a deber un favor o dos, guapo. Hasta luego.
-[GUN_4B]
-Mientras mantienes pulsado ~h~~k~~PED_LOCK_TARGET~~w~, puedes moverte mientras sigues apuntando a tu objetivo.
+[MOB_02A]
+Ssssnniiiiffffff... ¡Eh! Hola, ¿Tommy? ¡Tommy!
-[GUN_5]
-Puedes practicar disparando a estas dianas. Vuelve a la misión cuando hayas terminado.
+[MOB_02B]
+Tenemos un problema en la imprenta. Mejor que vayas y lo compruebes.
-[TAXI1]
-~g~Busca un cliente.
+[MOB_02C]
+Algún tipo de lío. Las cosas andan revueltas. Tengo que irme.
-[FARE1]
-~g~Ve al ~w~club Sex Kitten Meeouch ~g~en el Red Light District.
+[MOB_03A]
+¿Sr. Vercetti? Tengo un trozo de mierda firmada que dice
-[FARE2]
-~g~Ve a ~w~Supa Save ~g~en Portland View.
+[MOB_03B]
+que usted ha asumido todas las deudas de BJ's Auto.
-[FARE3]
-~g~Ve a ~w~la sala Clásica ~g~en Chinatown.
+[MOB_03C]
+Con la repentina desaparición de BJ no tengo más remedio
-[FARE4]
-~g~Ve a la ~w~cafetería Greasy Joe ~g~en Callahan Point.
+[MOB_03D]
+que hacerle responsable de su inestabilidad financiera
-[FARE5]
-~g~Ve a la ~w~tienda de armas Ammu-Nation ~g~en el Red Light District.
+[MOB_03E]
+Hasta que esta cuenta quede completamente saldada
-[FARE6]
-~g~Ve a ~w~Easy Credit Autos ~g~en Saint Mark's.
+[MOB_03F]
+debería considerar que las calles de Vice City son poco seguras.
-[FARE7]
-~g~Ve al ~w~bar de topless de Woody ~g~en el Red Light District.
+[MOB_04A]
+¿Cómo estás, tío? Soy Paulo.
-[FARE8]
-~g~Ve al ~w~restaurante Marcos ~g~en Saint Mark's.
+[MOB_04B]
+Mira, Tommy, me olvidé de mencionar que vamos a necesitar más seguridad para el concierto.
-[FARE9]
-~g~Ve al ~w~taller de importación y exportación ~g~en el puerto de Portland.
+[MOB_04C]
+Hay una banda de moteros liderada por Mitch Baker que serían la publicidad ideal.
-[FARE10]
-~g~Ve a ~w~Punk Noodles ~g~en Chinatown.
+[MOB_04D]
+Solucióname esto y te conseguiré un pase para la actuación, ¿vale?
-[FARE12]
-~g~Ve al ~w~estadio de fútbol ~g~en Aspatria.
+[MOB_05A]
+Soy Mitch. Hiciste un buen trabajo, Tommy. Es bueno volver a tener a mi pequeña en casa.
-[FARE13]
-~g~Ve a la ~w~iglesia ~g~de Bedford Point.
+[MOB_05B]
+Dile al Sr. Kent Paul que dispondrá de seguridad para la actuación.
-[FARE14]
-~g~Ve al ~w~casino ~g~de Torrington.
+[MOB_05C]
+Tiene mi palabra de ello.
-[FARE15]
-~g~Ve a la ~w~universidad ~g~en el Campus de Liberty.
+[MOB_05D]
+Intenta no meterte en problemas.
-[FARE16]
-~g~Ve al ~w~centro comercial ~g~en la zona del parque Belleville.
+[MOB_06A]
+Tommy, esos de abajo han estado rajando sobre ti, chico.
-[FARE17]
-~g~Ve al ~w~museo ~g~de Newport.
+[MOB_06B]
+Pensé que podrías necesitar consuelo casero así que la tía Poulet te preparará una sopa, ¿hmmm?
-[FARE18]
-~g~Ve al ~w~edificio de AmCo ~g~en Torrington.
+[MOB_06C]
+Pásate por mi cocina alguna vez, ¿de acuerdo Tommy?
-[FARE19]
-~g~Ve a ~w~Bolt Burgers ~g~en Bedford Point.
+[MOB_08A]
+Eh Tommy, pensé que podrías necesitar algún asesoramiento financiero.
-[FARE20]
-~g~Ve al ~w~parque ~g~de Belleville.
+[MOB_08B]
+Una vez que tengas la operación en marcha, tendrás que pasarte a recoger la recaudación de la semana.
-[FARE21]
-~g~Ve al ~w~Aeropuerto Internacional Francis.
+[MOB_08C]
+Deja que esos tipos crean que son los amos del lugar e intentarán cepillarse los beneficios... ¿vale?
-[FARE22]
-~g~Ve a la ~w~presa Cochrane~g~.
+[MOB_08D]
+Eh, sé como llevar el negocio, Ken.
-[FARE24]
-~g~Ve al ~w~hospital ~g~de Pike Creek.
+[MOB_08E]
+Vale, vale. Lo sé, ya sabes. Lo sé. Estaba,
-[FARE25]
-~g~Ve al ~w~parque ~g~de Shoreside Vale.
+[MOB_08F]
+Sólo estaba, ya sabes, diciéndote que sé, que tú sabes que yo lo sé.
-[FARE26]
-~g~Ve a las ~w~Torres del Noroeste ~g~de Wichita Gardens.
+[MOB_08G]
+¡Solo manteniéndolo a punto, nene!
-[NEW_TAX]
-¡MÁS GRANDES! ¡MÁS RÁPIDOS! ¡MÁS DUROS! Los nuevos taxis Borgnine abren sus puertas en Harwood. ¡Llame hoy al 555-BORGNINE!
+[MOB_08H]
+Lo que sea, Ken, lo que sea...
-[TSCORE2]
-~1~ $
+[MOB_09A]
+¡Eh, Leo! ¡Tengo trabajo para ti!
-[IN_ROW]
-¡Racha de ~1~ clientes! Premio de ~1~ $.
+[MOB_09B]
+No soy Leo.
-[TTUTOR]
-Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misiones de taxi.
+[MOB_09C]
+¡Eh, como Leo sepa que tienes su teléfono, te va a liquidar!
-[TTUTOR2]
-Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misiones de taxi.
+[MOB_09D]
+Quizás Leo ya esté muerto. Quizás yo le maté y cogí su teléfono, ¿te has parado a pensar eso, gilipollas?
-[ATUTOR2]
-~g~Lleva a los pacientes al hospital CON CUIDADO. Cada golpe reducirá sus posibilidades de supervivencia.
+[MOB_09E]
+¿Mataste a Leo? Debes tener unas pelotas muy grandes... ¿quieres trabajar para mí?
-[A_TIME]
-+~1~ segundos
+[MOB_09F]
+Pásate por el café de mi padre en Little Havana y podremos hablar de tú a tú.
-[A_FULL]
-~r~¡Ambulancia llena!
+[MOB_10A]
+¡Tommy! Mira, tengo que pedirte un favor.
-[A_RANGE]
-~g~La radio de la ambulancia está fuera de cobertura, ¡acércate a un hospital!
+[MOB_10B]
+¡Steve! ¿Cómo van con el rodaje?
-[FTUTOR]
-Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misiones del camión de bomberos.
+[MOB_10C]
+Bien, bien. Yo, je, NOSOTROS necesitamos una escena con una persecución de coches, pero nuestro presupuesto no da para más.
-[FTUTOR2]
-Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misiones del camión de bomberos.
+[MOB_10D]
+Me han dejado un coche en la ciudad. Tú sabrás qué hacer.
-[F_PASS1]
-¡Fuego apagado!
+[MOB_10E]
+De acuerdo, Steve, estaré al tanto. Te veo luego.
-[F_RANGE]
-~g~La radio del camión de bomberos está fuera de cobertura, ¡acércate a una estación de bomberos!
+[MOB_11A]
+¿Qué hay, hijo? Pensé sólo en llamarte para darte algún consejo.
-[C_BREIF]
-~g~Sospechoso visto por última vez en: ~a~.
+[MOB_11B]
+Hola, Avery. ¿Qué te preocupa?
-[C_RANGE]
-~g~La radio de la policía está fuera de cobertura, ¡acércate a una comisaría!
+[MOB_11C]
+Hay muchas oportunidades en esta ciudad si dispones de las propiedades adecuadas, ¿entiendes lo que quiero decir?
-[DODO_FT]
-¡Has volado durante ~1~ segundos!
+[MOB_11D]
+Creo que sí...
-[EBAL_A]
-Conozco un lugar en las afueras del Red Light District donde podemos escondernos,
+[MOB_11E]
+Lo que digo es que mantengas los ojos abiertos y podrás encontrar la oportunidad de negocio perfecta. Te veré luego.
-[EBAL_A1]
-pero mis manos están destrozadas, así que conduce tú, hermano.
+[MOB_11F]
+Nos vemos, Avery.
-[EBAL_1]
-Pulsa ~h~~k~~VEHICLE_ENTER_EXIT~~w~ para ~h~entrar ~w~o ~h~salir~w~ de un vehículo.
+[MOB12_A]
+¡Eh, Tommy, soy Avery! Ahora escucha, estoy muy liado en este momento
-[EBAL_1B]
-Pulsa ~h~~k~~VEHICLE_ENTER_EXIT~~w~ para ~h~entrar ~w~o ~h~salir~w~ de un vehículo.
+[MOB12_B]
+y uno de mis representantes necesita carabina para ir a Gator Keys.
-[EBAL_2]
-~g~¡Vuelve al coche!
+[MOB12_C]
+Estoy detrás de unas tierras por allí, así que voy a enviar alguien a que ablande el trato.
-[EBAL_3]
-Éste es el ~h~radar~w~. Utilízalo para guiarte por la ciudad. ¡Ve hasta la ~h~señal~w~ del ~h~radar~w~ para encontrar el escondite!
+[MOB12_D]
+Podrías hacerme un favor y asegurarte de que llega allí, ¿entendido?
-[EBAL_D]
-Conozco a un tipo con contactos, se llama Luigi.
+[MOB12_E]
+Sí, eso está hecho, Avery. ¿Dónde te gustaría que le recogiese?
-[EBAL_D1]
-Somos viejos amigos, así que podremos buscarte curro. Vamos a verlo.
+[MOB12_F]
+Está terminando algunos negocios en la obra. Le dije que le recogerías allí.
-[EBAL_E]
-Venga, vamos a pasarnos por allí y te presentaré.
+[MOB12_G]
+Ningún problema. Nos vemos, Avery.
-{ UNUSED }
+[MOB13_A]
+¿Vercetti? ¡VERCETTI! ¡Maldito seas, tío, tienes que ayudarme!
-[EBAL_I]
-El jefe os recibirá enseguida...
+[MOB13_B]
+¿Sr. Moffat? ¿Cómo le va la vida en familia?
-[EBAL_J]
-8-Ball tiene cosas que hacer arriba.
+[MOB13_C]
+Maldito seas, DEMONIOS, ¿me oyes?
-[EBAL_K]
-Quizá puedas hacerme un favor.
+[MOB13_D]
+Bueno, fue agradable charlar...
-[EBAL_L]
-Una de mis chicas necesita que la lleven, así que consigue un coche, recoge a Misty en la clínica y tráela aquí.
+[MOB13_E]
+¡ESPERA! Espera, Vercetti Tommy, ¿Puedo llamarte Tommy?
-[EBAL_N]
-¡Así que no quites las manos del volante!
+[MOB13_F]
+Los dos somos hombres de negocios, ¿verdad? Reconoces un buen negocio cuando lo ves.
-[EBAL_4]
-~r~¡8-Ball ha muerto!
+[MOB13_G]
+No tengo tiempo para charlar, vaya al grano.
-[EBAL_5]
-~g~¡Consigue un vehículo!
+[MOB13_H]
+DINERO. El dinero es el maldito asunto.
-[EBAL_6]
-~g~¡Recoge a Misty!
+[MOB13_I]
+Me escapado de la trena otra vez, pero nunca tardan mucho en encontrarme... ¡creen que es un maldito juego!
-[LM1]
-'LAS CHICAS DE LUIGI'
+[MOB13_J]
+Estoy en un teléfono público en alguna parte de este agujero de mierda olvidado de la mano de Dios.
-[LM2]
-'NO DROGUES A MI ZORRA'
+[MOB13_K]
+Sácame de aquí antes de que me lleven de vuelta y... oh... Dios...
-[LM3]
-'LLEVA A MISTY POR MÍ'
+[MOB13_L]
+Bueno, estoy ocupado durante las próximas...
-[LM5]
-'EL BAILE DE LA POLICÍA'
+[MOB13_M]
+¡No! ¡No me jodas, ten piedad! Ningún hombre debería tener que hacer esas, esas cosas.
-[LM1_2]
-~g~Lleva a Misty al club de Luigi.
+[MOB13_N]
+Estoy de rodillas, Tommy, en el fango, rogándote, por favor...
-[LM1_3]
-~g~Toca el claxon para que la chica entre en el coche.
+[MOB13_O]
+Supongo que podría desviarme hacia allí, veré si puedo localizarte...
-[LM1_6]
-~g~¡Vuelve al coche!
+[MOB13_P]
+Oh, Dios, ya vienen. Por el amor de Dios, date prisa, ¡date prisa!
-[LM1_7]
-Para el vehículo junto a Misty y déjala que suba.
+[MOB_14A]
+Hola, Tommy, me vas a adorar, amigo.
-[LM1_8]
-Puedes ir a ver a Luigi para que te dé más trabajo o explorar Liberty City.
+[MOB_14B]
+Un pajarito me ha dicho que la división SWAT de Vice City tiene un depósito en una entidad bancaria ciertamente grande,
-[LM2_A]
-Hay una nueva droga en la ciudad llamada SPANK.
+[MOB_14C]
+donde guardan todos los sobornos que han recibido durante estos años,
-[LM2_E]
-Algún listillo ha pasado esta basura a mis chicas en el puerto de Portland.
+[MOB_14D]
+¡como una especie de fondo de retiro para los veteranos!
-[LM2_B]
-¡Ve y repásale la cara con un bate de béisbol!
+[MOB_14E]
+Por supuesto, si esta información te ayudase a adquirir parte de ese dinero,
-[LM2_G]
-¡Quiero una compensación por este insulto!
+[MOB_14F]
+¿Supongo que te sentirías obligado a mandarme algo?
-[LM2_1]
-~g~Llévate su coche y repíntalo.
+[MOB_14G]
+Lo tendré en mente, gracias Kent.
-[LM2_2A]
-¡Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para ~h~dar puñetazos~w~, ~h~patadas~w~ o ~h~pegar ~w~con el bate!
+[MOB_14H]
+Es Paul. Soy de Kent, cerca de Londres, idiota.
-[LM2_2C]
-¡Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para ~h~dar puñetazos~w~, ~h~patadas~w~ o ~h~pegar ~w~con el bate!
+[MOB_14I]
+Mi conocimiento de la geografía provincial inglesa ya no es lo que era.
-[LM2_2D]
-¡Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para ~h~dar puñetazos~w~, ~h~patadas~w~ o ~h~pegar ~w~con el bate!
+[MOB15_A]
+Tommy, colega, soy Paul, de Kent,
-[LM2_3]
-~g~¡Mete el coche en el garaje de Luigi!
+[MOB15_B]
+un par de titis han escrito tu nombre por todas partes, en el Malibú.
-[LM2_4]
-~g~¡Vuelve a pintar el coche!
+[MOB15_C]
+¿De qué estás hablando?
-[LM3_A]
-Hola, tengo que hablar contigo... Bueno, Mick, ya hablaremos.
+[MOB15_D]
+Tías. Palomitas. Ya sabes. Chicas. De las buenas, no creas que son furcias ni nada por el estilo.
-[LM3_B]
-¿Cómo te va, chico?
+[MOB15_E]
+Tienes que venir a echarles un vistazo.
-[LM3_C]
-El hijo del Don, Joey Leone, quiere fiesta con su chica de siempre, Misty.
+[MOB16_A]
+Tommy, aquí Paulo, ¿qué pasa amigo?
-[LM3_D]
-Recógela en los cerros de Hepburn,
+[MOB16_B]
+¿Qué quieres Paul? No quiero ropa de imitación.
-[LM3_E]
-pero cuidado, ese es territorio de los Diablos.
+[MOB16_C]
+Muy divertido, colega, pero yo no toco la ropa falsificada.
-[LM3_F]
-Luego llévala rapidito hasta su taller en Trenton,
+[MOB16_D]
+Nada, sólo llamaba para ver si consigo un papel en una de tus películas,
-[LM3_H]
-¡así que fíjate en el camino y no en Misty!
+[MOB16_E]
+en Inglaterra hice un montón de porno, colega.
-[LM3_1D]
-Pulsa ~h~~k~~VEHICLE_HORN~~w~ para tocar el ~h~claxon~w~ y avisar a Misty.
+[MOB16_F]
+Guardo más fuego que tu, hijo mío.
-[LM3_2]
-~g~Lleva a Misty al local de Joey.
+[MOB16_G]
+Paul, gracias por la oferta, lo tendré en mente.
-[LM3_4]
-~g~¡Recoge a Misty!
+[MOB16_H]
+En serio, no te olvides de mí, después de todo lo que he hecho por ti.
-[LM3_5]
-Ahora trabajas para Luigi, ¿no? ¡Ya era hora de que tuviese un conductor de confianza!
+[MOB16_I]
+Eso es lo que estoy intentando olvidar.
-[LM3_7]
-Estaré contigo en un momento, bujía mía.
+[MOB19_A]
+Tommy V, aquí KP. Kent Paul. En las calles se dice que hay gente que te quiere despellejar.
-[LM3_10]
-~g~¡Consigue un vehículo!
+[MOB19_B]
+Mantén los ojos abiertos. Y recuerda, yo no te he dicho nada de esto.
-[LM4_B]
-Resuelve esto por mí.
+[MOB_20A]
+De acuerdo, Tommy, soy Paul. Me ha dicho un pajarito que has sido un chico muy malo.
-[LM4_C]
-Si necesitas un arma, ve a la parte de atrás del Ammu-Nation que está enfrente del metro.
+[MOB_20B]
+A alguien le ha ofendido que de repente estés actuando como si fueses el mandamás, dándote aires de grandeza.
-[LM5_A]
-El baile de la policía se está celebrando en la sala Clásica, cerca del puente,
+[MOB_20C]
+Bueno, no digas que nunca te advertí. Presumir es un juego de tontos, hijo.
-[LM5_B]
-y parece que tienen ganas de una fiesta más ''clásica''.
+[MOB_20D]
+En cualquier caso, oí que se ha puesto un precio a tu cabeza y que alguien te la va a partir,
-[LM5_C]
-Tengo chicas haciendo la calle.
+[MOB_20E]
+así que ten cuidado, y acuérdate de mí, colega.
-[LM5_D]
-Llévalas al baile, sacarán una buena tajada.
+[MOB21_A]
+Tommy, Thomas, soy Cortez. ¿Qué pasa?
-[LM5_1]
-~g~¡Tienes a las chicas tan embutidas que les van a salir moratones! Primero deja a las que llevas y luego ve a por más.
+[MOB21_B]
+Las cosas van bien. ¿Cómo estás?
-[LM5_2]
-~r~¡Una chica de Luigi la ha espichado!
+[MOB21_G]
+De todos modos, Tommy, quisiera preguntarte algo sobre Mercedes.
-[LM5_3]
-~g~¡Necesitas un coche!
+[MOB21_H]
+¿Sí? ¿Qué pasa con ella?
-[LM5_4]
-~g~Recoge a las chicas que trabajan en Saint Mark's.
+[MOB21_I]
+Oh Tommy, Tommy, oigo todas esas historias y no sé qué pensar.
-[LM5_5]
-~g~¡Lleva a las chicas al baile de la policía!
+[MOB21_K]
+Quizás ella piense que puede hacer lo que quiera ahora que pero dime, Tommy, ¿es verdad?
-[LM5_8]
-~g~Chicas trabajando en el baile: ~1~
+[MOB21_M]
+¿El qué es verdad?
-[JM2]
-'DESPEDIDA A LEE CHONG ''EL GORDO'''
+[MOB21_N]
+Las historias que he oído. ¿De verdad va a ser abogada?
-[JM4]
-'EL CHÓFER DE CIPRIANI'
+[MOB21_O]
+Oh Tommy, la vergüenza. Los Cortez somos una familia orgullosa
-[JM5]
-'FIAMBRE EN EL MALETERO'
+[MOB21_P]
+y nunca permitiríamos que una hija nuestra se convirtiese en abogada. Por favor, dime que no es así. No creo que pudiese soportarlo.
-[JM1_1]
-~g~Lleva el coche de Forelli al taller que tiene 8-Ball al norte, tras Easy Credit Autos.
+[MOB21_Q]
+Coronel, puedo asegurarle que Mercedes nunca será abogada. No tema.
-[JM1_2]
-~g~Vuelve a aparcar el coche frente al restaurante de Marco.
+[MOB21_R]
+Gracias, Tommy, gracias. La vergüenza sería insoportable.
-[JM1_3]
-~g~¡Activa la bomba del coche y luego sal de ahí!
+[MOB21_S]
+Lo sé, coronel.
-[JM1_4]
-~g~¡Te estás cargando el coche! ¡Repáralo!
+[MOB21_T]
+Bueno, Tommy, debes perdonarme, ha llegado el nuevo ministro de interior.
-[JM1_5]
-~g~¡La bomba del coche no está activada!
+[MOB21_U]
+Hace muchos años, yo maté a su padre en un golpe fallido así que debo ser cortés. Buenos días, amigo.
-[JM1_6]
-~g~Vuelve a aparcar el coche en el sitio correcto.
+[MOB21_C]
+Tommy, aquí siempre es una lucha. Siento el ruido, acabamos de tener otro golpe fallido.
-[JM1_8A]
-~y~¡Ey, pero si es mi colega!
+[MOB21_D]
+La gente es la señora más exigente de todas.
-[JM1_8B]
-~y~El taller de bombas está automatizado. Sólo tienes que meter el coche, pararlo y el taller hará el resto.
+[MOB21_E]
+Desde que he vuelto de Vice City y hasta ahora, hemos tenido tres revoluciones y cuatro golpes.
-[JM1_8C]
-~y~Ten, tu primer coche es gratis, pero los siguientes te los cobraré.
+[MOB21_F]
+Afortunadamente, me han ascendido cada vez.
-[JM2_A]
-Lee Chong ''el Gordo'' está traficando SPANK para una nueva banda de Colombia, o Colorado... O como se llame.
+[MOB21_J]
+Quizás todo el mundo me está humillando.
-[JM2_B]
-No me acuerdo. El caso es que no importa.
+[MOB21_L]
+pero dime, Tommy, ¿es verdad?
-[JM2_D]
-Ese cabrito ha vendido su último fideo.
+[MOB22_A]
+Tommy, estás demostrando ser muy útil, amigo mío.
-[JM2_E]
-¡Lo quiero muerto!
+[MOB22_B]
+Gracias, Cortez. ¿Qué hay de mi asunto?
-[JM2_G]
-Búscate un nueve, queda claro, ¿no?
+[MOB22_C]
+Tommy, estoy trabajando infatigablemente en tu nombre para conseguir llegar al fondo de esta zanja de apestosas mentiras y engaños,
-[JM2_H]
-Y recuerda, ve con ojo en Chinatown: es territorio de las Tríadas.
+[MOB22_D]
+tienes mi palabra al respecto, pero mientras tanto,
-[JM3_A]
-Vamos a robar un furgón blindado.
+[MOB22_E]
+por favor, acepta el estimable agradecimiento de mi gente por tu trabajo para nosotros.
-[JM3_B]
-Sale de Chinatown todos los días.
+[MOB_25A]
+Tommy, soy Cortez. Los franceses me están causando todo tipo de problemas.
-[JM3_C]
-Las balas ni siquiera abollarán el furgón, así que coge un coche y échalo de la carretera.
+[MOB_25B]
+Malditos hipócritas. ¡Se pasan cien años robando a países pobres y me llaman ladrón a mí!
-[JM3_D]
-Si lo zurras bien, los imbéciles de los guardias se achantarán.
+[MOB_25C]
+Voy a necesitar tu ayuda tan pronto como sea posible.
-[JM3_E]
-Luego llévalo al almacén de los muelles y mis chicos se encargarán del resto.
+[MOB_25D]
+Por favor, Tommy, date prisa, te necesito, ¿de acuerdo? Odio a esos malditos franceses.
-[JM3_F]
-El furgón no estará fuera todo el día, así que no pierdas el tiempo.
+[MOB_26A]
+Hola, ¿Tommy?
-[JM3_1]
-~g~Lleva el furgón al almacén.
+[MOB_26B]
+¿Sí?
-[JM3_2]
-~g~Carga contra el furgón hasta que su daño esté por debajo del 70 por ciento.
+[MOB_26C]
+Soy Baker. Sólo quería decirte que verdaderamente disfruté con el espectáculo.
-[JM4_B]
-¡Ah, aquí está el tío que te decía!
+[MOB_26D]
+Los chicos y yo queremos darte las gracias, y recordarte,
-[JM4_C]
-Bueno, éste no es italiano ni tampoco mecánico, pero sabe arreglar cosas.
+[MOB_26E]
+que te tienes nuestro respeto. Buenos días. Sigue cabalgando duro, chico.
-[JM4_D]
-Él es el capo de papá, Toni Cipriani.
+[MOB_29A]
+Hola, ¿hablo con el Sr. Tommy Vercetti?
-[JM4_E]
-Sí, soy Toni Cipriani.
+[MOB_29B]
+Sí.
-[JM4_F]
-Llévale al restaurante de Mamma en Saint Mark's, ¿va?
+[MOB_29C]
+Bueno, he oído por radio macuto que usted es el hombre que hay que buscar cuando alguien tiene una plaga de bichos.
-[JM4_G]
-Oye, estoy planeando un curro que necesita un buen conductor, pásate por aquí más tarde, ¿estamos?
+[MOB_29D]
+Puede...
-[JM4_2]
-¡Espera aquí! Deja el motor en marcha. Ésta no es una visita social.
+[MOB_29E]
+Bueno, yo tengo una plaga de bichos de verdad. Haitianos, por todas partes.
-[JM4_3]
-¡Es una emboscada de las Tríadas! ¡Sácanos de aquí, chico!
+[MOB_29F]
+Mi nombre es Umberto Robina y quiero que nos reunamos en el Café Robina lo antes posible,
-[JM4_4]
-Las Tríadas creen que pueden meterse conmigo. ¡Las Tríadas, CONMIGO!
+[MOB_29G]
+porque, como le digo, estos malditos haitianos se han pasado de la raya esta vez.
-[JM4_6]
-¡Mi coche! Dije que fueras con cuidado.
+[MOB_29H]
+Prueba
-[JM4_7]
-~g~Lleva a Toni al restaurante de Mamma.
+[MOB_30A]
+Tommy, soy Umberto Robina.
-[JM4_8]
-~r~¡Toni la ha palmado!
+[MOB_30B]
+¿Cómo está el café?
-[JM5_A]
-Guapo, muy guapo...
+[MOB_30C]
+Oh, maravilloso. Increíble. Tommy, increíble. Sin blandengues, Tommy, sólo hombres de verdad, ya sabes, ¡y las mujeres hermosas!
-[JM5_B]
-¡Justo te estaba buscando!
+[MOB_30D]
+De todos modos, quería decirte que para papá y para mí, para nosotros, ahora eres un cubano.
-[JM5_D]
-Uno de los Forelli se las daba de mafioso y se llevó su merecido.
+[MOB_30E]
+Has demostrado que tienes unas pelotas de cojones, tío.
-[JM5_E]
-Lleva el cuerpo a la trituradora en Harwood, ¿vale?
+[MOB_30F]
+Gracias, Umberto. Nadie me había dicho eso desde que salí de la cárcel. Nos vemos.
-[JM5_1]
-~g~¡Llévalo a la trituradora!
+[MOB_33A]
+Tommy, soy Phil, olvida toda esa mierda del pasado y escúchame, ¿me oyes?
-[JM5_2]
-~g~¡Son los hermanos Forelli!
+[MOB_33B]
+Bien. Tengo un pelotazo extra a punto de fermentar y me preguntaba si te apetecería probarlo.
-[JM6_A]
-Vaya cochazo, ¿eh?
+[MOB_33C]
+En serio, Tommy, si quieres una copa, o si necesitas ponerte a tono, este material hará de ti un hombre.
-[JM6_B]
-Bueno, escucha. Lleva un coche a la casa franca de Saint Mark's y recoge a unos colegas.
+[MOB_33D]
+A mí me pasó aunque todavía no puedo ver por un ojo. Te estaré esperando, lo que oyes.
-[JM6_C]
-Van a atracar un banco y necesitan un conductor.
+[MOB_34A]
+Tommy, de verdad que he disfrutado trabajando contigo. No me había divertido tanto desde la loma en Vietnam, colega.
-[JM6_D]
-Di mi palabra de que eras su hombre, así que no la cagues.
+[MOB_34B]
+De todas formas, si necesitas algo, llámame, ¿me oyes?
-[JM6_E]
-Llévalos al banco antes de las cinco en punto, ni un minuto después.
+[MOB_34C]
+Siempre me acuerdo de aquellos con los que he servido,
-[JM6_2]
-Mantén el motor en marcha, entraremos y saldremos enseguida.
+[MOB_34D]
+y estoy seguro de que puedo ayudarte, ¿me oyes?
-[JM6_3]
-¡Sácanos de aquí!
+[MOB_35A]
+Tommy, la herida está cicatrizando bien. Lo gracioso es
-[JM6_4]
-¡Líbrate de la poli y llévanos a la casa franca!
+[MOB_35B]
+que he luchado en 6 zonas de combate y siempre he salido sin un rasguño, ¡y ahora esto!
-[JM6_6]
-~g~¡Busca un vehículo menos llamativo!
+[MOB_35C]
+Phil el manco. Aún así, tengo una buena selección armas de fuego para mancos, así que nunca seré Phil el desarmado, lo que oyes.
-[JM6_7]
-~g~¡Necesitas a los 3 para robar el banco!
+[MOB_35D]
+Venga, hijo, corta con esa mierda sentimental y pídete una copa, ¡me oyes!
-[TM1]
-'SACANDO LA COLADA'
+[MOB_36A]
+Tommy, soy Phil, quiero darte las gracias por ayudarme allí, hijo,
-[TM2]
-'LA ENTREGA'
+[MOB_36B]
+maldito Charlie, siempre te tenderá una emboscada de un modo o de otro.
-[TM3]
-'SALVATORE HA CONVOCADO UNA REUNIÓN'
+[MOB_36C]
+Bueno, la herida está cicatrizando bien, y eso quiere decir que voy a dejar de estafar al gobierno con mi cheque de incapacidad. Gracias, colega.
-[TM4]
-'TRÍADAS Y TRIBULACIONES'
+[MOB_40A]
+Eh, Tommy, soy Sonny. ¿Qué tal el bronceado?
-[TM5]
-'LLUVIA DE PECES'
+[MOB_40B]
+No tengo bronceado.
-[TONI_P]
-¡Tengo un trabajo urgente para ti! -Toni
+[MOB_40C]
+Bueno, tampoco tienes mi dinero, así que me estoy preguntando,
-[TM1_A]
-Siéntate, chico, siéntate de una vez.
+[MOB_40D]
+¿qué estás haciendo? Así que, dime Tommy ¿qué estás haciendo?
-[TM1_B]
-La lavandería no quiere pagar la protección, ¿eh?
+[MOB_40E]
+Estoy buscando el dinero, Sonny. No te preocupes.
-[TM1_C]
-¿Las Tríadas creen que pueden meterse conmigo?
+[MOB_40F]
+Me estoy preocupando, Tommy, ese es mi estilo,
-[TM1_D]
-¡Se van a enterar esos aspirantes a tipos duros de lo que es ser un tipo duro!
+[MOB_40G]
+porque parece que en mi vida tengo este problema con gente que no es de confianza.
-[TM1_E]
-¡Eso, enséñales respeto! ¡Las Tríadas no se ríen de ninguno de mis hijos!
+[MOB_40H]
+No seas una persona poco fiable, Tommy, por favor.
-[TM1_F]
-Tu padre, Dios acoja su alma, no toleraba ni media a las Tríadas en Sicilia.
+[MOB_40I]
+Haznos un favor. Tengo muchas ganas de tener noticias tuyas.
-[TM1_G]
-Lo siento, mamá. Sí, mamá.
+[MOB_41A]
+Tommy, ¿te acuerdas de mí?
-[TM1_H]
-Quiero que te cargues sus furgonetas de lavandería
+[MOB_41B]
+Hola, Sonny.
-[TM1_I]
-y a cualquiera de las Tríadas que se cruce en tu camino.
+[MOB_41C]
+Sí, está bien, Sonny. Somos viejos amigos,
-[TM1_J]
-8-Ball te dará lo que necesites.
+[MOB_41D]
+y nunca me escribes, nunca llamas. ¿No quieres que sigamos siendo amigos?
-[TM2_A]
-Toni ha salido a partir cabezas, o a intentarlo...
+[MOB_41E]
+He estado muy ocupado intentando arreglar las cosas. No me diste mucho apoyo.
-[TM2_AA]
-Nunca será tan duro como su padre. Te dejó una nota en la mesa.
+[MOB_41F]
+Oh, y es culpa mía, ¿verdad? Bueno, he oído que has estado muy ocupado.
-[TM2_B]
-La lavandería ya quiere pagar. ¡Buen trabajo, chico!
+[MOB_41G]
+Ocupado matando a capos. Ocupado tomando el poder.
-[TM2_C]
-Ve a por el dinero y tráelo aquí. Cuidado con las Tríadas.
+[MOB_41H]
+No te olvides de nosotros, Tommy, porque puedo asegurarte que yo no me he olvidado de ti.
-[TM2_D]
-Puede que intenten metértela doblada, pero no te dejes.
+[MOB_42A]
+Tommy.
-[TM2_E]
-¡Nadie, quiero decir nadie, se mete con Toni Cipriani!
+[MOB_42B]
+Sonny.
-[TM2_1]
-~g~¡Lleva el dinero a Toni!
+[MOB_42C]
+Obviamente tienes un problema a la hora de escuchar a los demás, de modo que lo intentaré de nuevo.
-[TM2_2]
-~g~¡Los dejaste tiesos a todos!
+[MOB_42D]
+Tommy, ¿dónde está el maldito dinero, dónde está el maldito material y dónde está mi parte de tus nuevos golpes?
-[TM3_MA]
-¡No sé dónde está!
+[MOB_42E]
+Me estás haciendo quedar como un idiota, Tommy, y no me hace gracia.
-[TM3_MB]
-Te juro que mi hijo a veces no sabe lo que hace.
+[MOB_43A]
+Tommy, Tommy, Tommy, tenía a Sonny al teléfono, de acuerdo, ¿me sigues?
-[TM3_MC]
-Ahora bien, su padre era diferente. Siempre en la cumbre, pendiente de todo, valiente...
+[MOB_43B]
+No sé tú, pero hay algo sobre un hombre que amenaza con asesinar a mi familia
-[TM3_A]
-Don Salvatore ha convocado una reunión.
+[MOB_43C]
+que realmente me pone enfermo. ¿Qué vas a hacer?
-[TM3_B]
-Necesito que vayas a por la limusina y su hijo, Joey, a su taller.
+[MOB_43D]
+Ten calma, Ken, todo irá bien.
-[TM3_C]
-Luego recoge a Luigi en su club, ven a buscarme,
+[MOB_43E]
+¡ESTOY calmado, todo lo calmado que puede estar un hombre cuando teme por su vida!
-[TM3_D]
-y nos iremos todos juntos a la casa del jefe.
+[MOB_43F]
+Ken, ahora mismo tengo otras cosas en la cabeza,
-[TM3_E]
-Los de las Tríadas no saben cuándo parar...
+[MOB_43G]
+nos ocuparemos de Forelli cuando llegue el momento.
-[TM3_F]
-Si quieren guerra, la tendrán.
+[MOB_43H]
+Estoy calmado. ¿No te lo parece? Debe ser la muerte inminente la que le hace esto a mi voz.
-[TM3_G]
-Ponte en marcha.
+[MOB45_A]
+Tommy, tenemos cosas de las que hablar.
-[TM3_1]
-~g~Ve al taller de Joey a por la limusina.
+[MOB45_B]
+¿Cuál es el problema, Lance?
-[TM3_2]
-~g~Recoge a Luigi.
+[MOB45_C]
+Eres tú, amigo, creo que no me estás dando una tajada justa.
-[TM3_3]
-~g~Ahora recoge a Toni.
+[MOB45_D]
+Y lo que es más, me estás avergonzando delante de los chicos. No puedo permitirlo.
-[TM3_4]
-~g~Lleva a los mafiosos a la casa de Salvatore.
+[MOB45_E]
+Lance, las cosas no son así. Has estado cometiendo errores.
-[TM3_5]
-~y~¡Es una emboscada de las Tríadas!
+[MOB45_F]
+Tommy, no soy tu chico de los recados. No soy tu emisario.
-[TM4_B]
-¡Esto es la guerra! Las Tríadas tienen una piscifactoría como tapadera.
+[MOB45_G]
+Lance, no la cagues, y no tendremos ningún problema. Si la cago yo, entonces podrás venir a reprochármelo en cualquier momento.
-[TM4_C]
-Casi todos sus negocios pasan por la lonja de Chinatown.
+[MOB45_H]
+Tommy, he hecho de todo por ti, pero me tratas como si fuese estúpido. No hagas eso.
-[TM4_D]
-La lavandería todavía no ha pagado la protección.
+[MOB45_I]
+Lance no te voy a timar ni a apuñalarte por la espalda, de acuerdo.
-[TM4_E]
-Creen que está protegida por las Tríadas, así que creo que se merecen un castigo.
+[MOB45_J]
+Tómatelo con calma. Esto ya es lo suficientemente duro sin que te me pongas sentimental.
-[TM4_F]
-¡Llévate a estos chicos y elimina a los líderes de las Tríadas!
+[MOB45_K]
+Confía en mí. ¿Me oyes, me oyes?
-[TM4_G]
-Qué narices, si ves la oportunidad, cárgate también a unos cuántos de sus soldados.
+[MOB45_L]
+Te oigo, pero Tommy, no puedo aguantar esto por más tiempo.
-[TM4_GAT]
-~g~Necesitas un camión de pescado de las Tríadas para entrar.
+[MOB45_M]
+Lance, no seas así. Ahora te estoy dando un aviso.
-[TM5_B]
-Vale, ya me he hartado de esta mierda.
+[MOB45_N]
+¿Me oyes? Relájate, tómate unos días libres, y luego hablaremos, ¿vale?
-[TM5_C]
-¡Vamos a acabar con las Tríadas en Liberty de una vez por todas!
+[MOB46_A]
+¡Eh, Tommy! Soy Lance.
-[TM5_D]
-8-Ball ha instalado una bomba en un camión de la basura.
+[MOB46_B]
+¿Sí?
-[TM5_E]
-Lleva un temporizador, así que si te despistas, no quedará nada de ti. Ve a por el camión.
+[MOB46_C]
+Me alegro tanto de tener noticias tuyas, Lance. Venga, tío, enróllate, enróllate.
-[TM5_F]
-¡Cuidado, 8-Ball dice que es muy sensible y que cualquier golpe puede hacerlo estallar!
+[MOB46_D]
+Estoy ocupado. ¿Qué quieres?
-[TM5_G]
-Su piscifactoría abrirá sus puertas a uno de sus camiones, así que podrás entrar sin más.
+[MOB46_E]
+Nada. Solo llamo para decirte, ya sabes. Mira Tommy, podemos hacer esto.
-[TM5_H]
-¡Aparca entre los tanques de gas y lárgate de ahí!
+[MOB46_F]
+Tú y yo, sin ningún problema. ¿Sabes lo que quiero decir?
-[TM5_I]
-Quiero que llueva pescado.
+[MOB46_G]
+Vamos a tener que hacerlo, porque de otro modo, estaremos muertos, Lance.
-[TM5_J]
-En plan bíblico, nada de bajo presupuesto.
+[MOB46_H]
+Ya hemos ido demasiado lejos. Pero gracias por llamar. Hablaré contigo más tarde.
-[FM2]
-'CORTANDO LA HIERBA'
+[MOB_47A]
+Tommy, Lance, tenemos problemas serios. Ven aquí. Enseguida.
-[FM4]
-'ÚLTIMA VOLUNTAD'
+[MOB52_A]
+Eh, Leo, creo que tengo un comprador para la mercancía de Díaz.
-[FM1_A]
-Mis chicos y yo queremos hablar de negocios,
+[MOB52_B]
+Tienes que llamarle, tío, montar el trato, ¿sabes?
-[FM1_B]
-así que esta tarde vas a cuidar de mi chica.
+[MOB52_C]
+¿Dónde estás?
-[FM1_C]
-¡OYE, MARÍA! ¡MUEVE ESE CULO!
+[MOB52_D]
+¿Estás bien, Leo? Te noto un tanto diferente.
-[FM1_D]
-La muy idiota siempre hace lo mismo.
+[MOB52_E]
+Simplemente dime dónde estás.
-[FM1_E]
-Y aquí está, ¡la primera y única reina de Saba!
+[MOB52_F]
+¿Quién demonios eres? ¡Que se ponga Leo!
-[FM1_F]
-¿Qué hacías arriba?
+[MOB52_G]
+Leo se ha ido de viaje unos días, me dejó al cargo de todo.
-[FM1_G]
-Fuera lo que fuera, seguro que me cuesta dinero.
+[MOB52_H]
+¡Que te jodan, tío!
-[FM1_H]
-Bueno, no pensarás que estoy aquí para conversar, ¿o sí?
+[MOB54_A]
+¡Hola, Tommy!
-[FM1_I]
-Métete en el coche y cierra el pico.
+[MOB54_B]
+Hola, Mercedes, ¿cómo te va?
-[FM1_J]
-Llévate la limusina, pero devuélvela de una pieza, ¿me has oído?
+[MOB54_C]
+Tengo un apartamento nuevo en Vice Point,
-[FM1_K]
-Y cuidado con ella, es una lianta.
+[MOB54_D]
+pensé que quizás querrías pasarte en algún momento.
-[FM1_L]
-¡Sí, sí, sí! Seguro que tu nuevo perrito faldero está pendiente de todo.
+[MOB54_E]
+Me encantaría. Te veo luego.
-[FM1_M]
-¿No es fuerte y grande?
+[MOB55_A]
+Tommy, soy yo.
-[FM1_N]
-¡Oye, tú, vamos a ver a Chico para que nos dé unas pirulas!
+[MOB55_B]
+Hola, Mercedes.
-[FM1_P]
-~g~Ése de ahí es Chico, párate cerca.
+[MOB55_C]
+Tommy, estoy tan aburrida, ¿cuándo vamos a divertirnos un poco?
-[FM1_S]
-Aquí tienes, señorita.
+[MOB55_D]
+¿Qué quieres decir?
-[FM1_TT]
-¡UNA REDADA!
+[MOB55_E]
+Bueno, sé que estás ocupado luchando y matando y sobornando a gente,
-[FM1_1]
-~g~¡Vuelve al Stretch!
+[MOB55_F]
+pero yo sólo quiero divertirme un poco. Así que no te olvides de mí, ¿me oyes?
-[FM1_2]
-~g~¡Entra en el Stretch!
+[MOB56_A]
+Tommy, oí que te cargaste a Ricardo Díaz.
-[FM1_3]
-~r~Si abandonas a María, Salvatore hará que te maten. Vuelve a por ella.
+[MOB56_B]
+Hubo un desafortunado tiroteo en su mansión.
-[FM1_4]
-~g~¡Has dejado a la chica del Don tirada! ¡Vuelve al almacén y espera a María!
+[MOB56_C]
+Creo que se quemó hasta morir en su camisa acrílica.
-[FM1_5]
-~g~¡Lleva a María sana y salva con Salvatore!
+[MOB56_D]
+Tommy, estoy tan orgullosa de ti. Sabía que eras un hombre de verdad.
-[FM1_6]
-~g~¡Chico no estará esperando todo el día, lleva a María al muelle!
+[MOB56_E]
+Era un marrano en pantalones, me haces sentir muy orgullosa de ser tu amiga.
-[FM1_7]
-~r~¡María está muerta! A Salvatore le va a sentar muy mal...
+[MOB56_F]
+No, sé que vas a estar ocupado intentando tomar las riendas de esta ciudad,
-[FM1_8]
-~r~¡Te cargaste al camello de María!
+[MOB56_G]
+pero no te olvides de mí, ¿me oyes?
-[FM2_J]
-Déjanos a solas un momento.
+[MOB57_A]
+Soy Mercedes. Ya no te amo, Tommy.
-[FM2_A]
-El cártel colombiano fabrica SPANK en Liberty,
+[MOB57_B]
+Ya no lo hago. De verdad. Porque ya no eres amable con Mercedes.
-[FM2_K]
-pero no sabemos dónde y parece como si supieran qué vamos a hacer antes de que lo pensemos.
+[MOB57_C]
+Ya no la tratas como una dama. Me ignoras y te odio.
-[FM2_L]
-Hay un tipo llamado Curly Bob que trabaja en el bar de Luigi.
+[MOB57_D]
+¡Insisto en que vengas a verme enseguida!
-[FM2_M]
-Ha estado gastando más dinero del que gana.
+[MOB58_A]
+Tommy.
-[FM2_N]
-Suele ir del trabajo a casa en taxi, así que síguelo.
+[MOB58_B]
+Hola, Mercedes.
-[FM2_O]
-Y si nos está vendiendo..., mátalo.
+[MOB58_C]
+Hola, tipo duro. Estoy muy enfadada contigo, Tommy.
-[FM2_F]
-Aquí viene nuestro amiguito. El señor Bocón en persona.
+[MOB58_D]
+No me hagas ir nunca más por ahí con Jezz Torrent otra vez.
-[FM2_G]
-¿Te siguieron? Ya sabes que esto es nuestro secretito.
+[MOB58_E]
+Es patético. A mitad de camino, empieza a llorar por su perrito
-[FM2_H]
-No, no, no me han seguido. ¿Tienes lo mío?
+[MOB58_F]
+que murió cuando él tenía siete años y que si su madre nunca le había querido.
-[FM2_I]
-Toma tu SPANK, soplón, ahora habla.
+[MOB58_G]
+Y Tommy. En privado lleva peluca y sostén.
-[FM2_P]
-Vale, los Leone libran una guerra en dos frentes.
+[MOB58_H]
+¡No estoy muy contenta contigo!
-[FM2_Q]
-Tienen una guerra territorial con las Tríadas y no parece que ninguno se vaya a rendir.
+[MOB59_A]
+Ooh Tommy, soy Mercedes.
-[FM2_R]
-Mientras tanto, Joey Leone ha cabreado a los Forelli.
+[MOB59_B]
+Sólo quería decirte que me divertí mucho en el plató de rodaje.
-[FM2_S]
-Cada día pierden más hombres e influencia.
+[MOB59_C]
+Cualquier otra cosa que tengas así, me lo dices.
-[FM2_T]
-Salvatore se está volviendo peligroso y paranoico. Sospecha de todos y de todo.
+[MOB59_D]
+Lo digo de verdad. Siempre quise ser actriz.
-[FM2_U]
-Con lo leales que son algunos, ¿de qué tendría que preocuparse?
+[MOB59_E]
+Creo que aprendí mucho sobre el proceso dramático.
-[FM2_1]
-~g~¡Ahí está Curly Bob!
+[MOB59_F]
+¡Es tan instructivo! Gracias. Gracias. Hasta muy, muy pronto. Adiós.
-[FM2_2]
-~g~¡Curly ha salido del club, síguelo!
+[MOB_99]
+Ve al teléfono público del lugar.
-[FM2_5]
-~g~Llévale al puerto de Portland.
+[MOB_98]
+Ve al teléfono público del lugar.
-[FM2_6]
-~r~¡Curly no se meterá en un taxi cascado!
+[MOB_97]
+Ve al teléfono público del lugar.
-[FM2_7]
-~r~¡Curly se ha asustado! ¡Han cancelado la reunión!
+[MOB_96]
+Ve al teléfono público del lugar.
-[FM2_8]
-~g~¡Elimina a Curly Bob!
+[MOB_95]
+Ve al teléfono público del lugar.
-[FM2_9]
-~r~¡Curly Bob la ha espichado!
+[A_TIME]
++~1~ segundos
-[FM2_10]
-~r~¡Curly se ha largado!
+[DODO_FT]
+¡Volaste durante ~1~ segundos!
-[FM2_11]
-~g~Aparca enfrente del club de Luigi;Curly Bob saldrá pronto.
+[GA_8]
+Utiliza el detonador para activar la bomba.
-[FM2_12]
-~r~¡Te ha dado esquinazo!
+[GA_10]
+Muy bien. Aquí están tus ~1~ $.
-[FM3_A]
-Tenemos que despachar a esos puñeteros colombianos,
+[GA_11]
+Ya tenemos ese coche. ¡No nos sirve!
-[FM3_B]
-pero mientras estemos en guerra con las Tríadas, no tendremos la fuerza necesaria.
+[GA_12]
+Bomba activada.
-[FM3_C]
-El cártel tiene fondos ilimitados gracias a esa mierda del SPANK.
+[GA_13]
+Entregado como un profesional. Completa la lista y habrá una bonificación para ti.
-[FM3_D]
-Si les atacamos abiertamente, nos harán picadillo.
+[GA_14]
+Todos los coches. ¡ESTUPENDO! Aquí tienes una cosilla.
-[FM3_E]
-Estarán fabricando el SPANK en ese barco grande al que te llevó Curly.
+[GA_15]
+Espero que te guste el nuevo color.
-[FM3_F]
-Así que tenemos que actuar con cuidado, o mejor dicho, tú tienes que hacerlo.
+[GA_16]
+Volver a pintarlo es gratis.
-[FM3_G]
-Te estoy pidiendo que destruyas esa fábrica de SPANK como un favor personal para mí, Salvatore Leone.
+[GA_19]
+No estamos interesados en este modelo.
-[FM3_H]
-Si lo haces, entrarás en la familia. Tendrás todo lo que quieras.
+[GA_20]
+Tenemos más de eso de los que podemos colocar. Lo siento, tío, no hay trato.
-[FM3_I]
-Ve a ver a 8-Ball, necesitarás su ayuda para volar ese barco.
+[CHASE]
+Atención de la prensa
-[FM3_8A]
-¡Hombre, colega! Salvatore me avisó,
+[CHASE1]
+Ignorado
-[FM3_8B]
-pero este trabajo va a necesitar muchos fuegos artificiales.
+[CHASE2]
+Aburrido
-[FM3_8D]
-pero ya sabes que conmigo valdrá la pena.
+[CHASE3]
+Algo interesante
-[FM3_8E]
-Venga, ¡vamos allá!
+[CHASE4]
+Página 7 del periódico local
-[FM3_8F]
-Puedo reventar el barco, pero aún no puedo usar una pipa con estas manos.
+[CHASE5]
+Portada del periódico local
-[FM3_8G]
-¡Toma, con este fusil podrás reventar unas cuantas cabezas!
+[CHASE6]
+Página 2 del Vice Courier
-[FM3_4]
-~g~¡Para el coche y deja que 8-Ball salga!
+[CHASE7]
+Portada del Vice Courier
-[FM3_7]
-~r~¡8-Ball ha pasado a mejor vida!
+[CHASE8]
+TV Local a las 3 de la mañana
-[FM3_8]
-~r~¡Los guardias han sido alertados!
+[CHASE9]
+Noticias locales en TV
-[FM4_A]
-¡Mi socio favorito!
+[CHASE10]
+Cobertura en directo de la TV Local
-[FM4_B]
-Estoy orgulloso, hijo, pusiste finos a esos sudacas.
+[CHASE11]
+Página 12 del UFA Today
-[FM4_C]
-Tengo un trabajito más para ti antes de que podamos celebrarlo.
+[CHASE12]
+Página 4 del UFA Today
-[FM4_D]
-Hay un coche a la vuelta del edificio del club de Luigi.
+[CHASE13]
+Imagen en UFA Today
-[FM4_E]
-El interior está pringado de sesos.
+[CHASE14]
+TV Nacional a las 4 de la mañana
-[FM4_F]
-Tuvimos que ayudar a un tipo a que se decidiera y fue un poco... sucio.
+[CHASE15]
+Noticias de la TV Nacional
-[FM4_H]
-Llévalo a la trituradora antes de que lo encuentre la pasma.
+[CHASE16]
+Cobertura en directo de la TV Nacional
-[AM3]
-'PURGA DEL PAPARAZZI'
+[CHASE17]
+Noticias internacionales
-[AM4]
-'LA PAGA DE RAY'
+[CHASE18]
+Crisis nacional
-[AM5]
-'TANNER EL TRAIDOR'
+[CHASE19]
+Crisis internacional
-[AM1_A]
-Tenemos que aclarar ciertos temas antes de seguir con cualquier clase de relación,
+[CHASE20]
+Acontecimiento mundial
-[AM1_B]
-sea de negocios u otra. Pongamos las cartas sobre la mesa.
+[CHASE21]
+Leyenda
-[AM1_C]
-Soy yakuza y sé que trabajaste para la familia de Salvatore Leone.
+[CR_1]
+La grúa no puede levantar este vehículo
-[AM1_D]
-Puedo darte trabajo en nuestra organización,
+[PU_MONY]
+No tienes suficiente dinero.
-[AM1_E]
-pero primero debes demostrarme que has cortado todos tus lazos con la mafia.
+[CO_ALL]
+Los tienes todos. Aquí tienes una cosilla...
-[AM1_G]
-Asegúrate de que no salga con vida.
+[FEM_ON]
+SÍ
-[AM1_H]
-Mientras tanto, María y yo nos pondremos al día.
+[FEM_OFF]
+NO
-[AM1_I]
-Uy, Asuka, tienes un masajeador...
+[FEM_YES]
+Sí
-[AM1_J]
-Eso no es un masajeador.
+[FEM_NO]
+No
-[AM1_1]
-~g~¡Salvatore está saliendo del club de Luigi!
+[FEM_RET]
+REINTENTAR
-[AM1_2]
-~r~¡Te han descubierto!
+[FEC_NA]
+NO DISPONIBLE
-[AM1_3]
-~r~¡Has perdido a Salvatore!
+[FEC_CWL]
+Escoger arma hacia la izquierda
-[AM1_4]
-~r~Muy bonito, ¡has asustado al objetivo! ¿Y te consideras un asesino?
+[FEC_CWR]
+Escoger arma hacia la derecha
-[AM1_5]
-~g~Ve al Red Light District y espera a que Salvatore salga del club.
+[FEC_LOF]
+Mirar hacia adelante
-[AM1_7]
-~r~Salvatore está en su casita, sano y salvo, tomándose un cóctel. ¡Nadie te va a llamar ''Chacal''!
+[FEC_TAR]
+Objetivo
-[AM1_8]
-~g~Salvatore saldrá del club de Luigi sobre las ~1~:~1~.
+[FEC_MOV]
+Movimiento
-[AM2_4]
-~g~¡Has irrumpido como un elefante en una cacharrería!
+[FEC_CAM]
+Modos de cámara
-[AM3_A]
-Un periodista ha estado husmeando por aquí.
+[FEC_PAU]
+Pausa
-[AM3_B]
-María y yo nos hemos ido de vacaciones hasta que puedas librarte de ese mirón pervertido.
+[FEC_ENV]
+Entrar en el vehículo
-[AM4_A]
-¡Si es mi guapo manitas!
+[FEC_JUM]
+Saltar
-[AM4_B]
-María está un poquito liada, pero le diré que has venido.
+[FEC_ATT]
+Atacar o disparar arma
-[AM4_C]
-¿Quién es, Asuka? Sé que he sido muy traviesa, ¡pero necesito mear! ¿Vale?
+[FEC_RUN]
+Correr
-[AM4_D]
-Es hora de que conozcas a nuestro espía en la policía.
+[FEC_FPC]
+Cámara en primera persona
-[AM4_E]
-Aquí está su pago por el último trabajito que hizo para nosotros.
+[FEC_LL]
+Mirar a la izquierda
-[AM4_F]
-Él es comprensiblemente cauteloso.
+[FEC_LB]
+Retrovisor
-[AM4_G]
-Ve a la cabina en Torrington tan rápido como puedas y espera sus instrucciones.
+[FEC_LR]
+Mirar a la derecha
-[AM5_A]
-María y yo hemos ido de compras.
+[FEC_ABR]
+Acelerar, frenar o dar marcha atrás
-[AM5_B]
-¡Nuestro contacto en la policía nos ha informado de que uno de nuestros conductores es un poli infiltrado que se mueve de forma extraña!
+[FEC_HOR]
+Bocina
-[AM5_C]
-Sin un coche es prácticamente un inútil, así que le hemos puesto un localizador.
+[FEC_VES]
+Control del vehículo
-[AM5_D]
-¡Haz que sufra!
+[FEC_BRA]
+Freno o marcha atrás
-[AM5_1]
-¡Tanner te ha pillado!
+[FEC_HAB]
+Freno de mano
-[AS1]
-'CEBO'
+[FEC_CAW]
+Arma del vehículo
-[AS2]
-'CAFÉ PARA LLEVAR'
+[FEC_ACC]
+Acelerar
-[AS4]
-'RESCATE'
+[FEC_CCF]
+Configuración:
-[AS1_A]
-Parece que Miguel piensa que le maltrato.
+[FEC_CF1]
+Configuración 1
-[AS1_B]
-Pero ha revelado cuánto teme Catalina tu búsqueda de venganza.
+[FEC_CF2]
+Configuración 2
-[AS2_A]
-Subestimamos los planes que tiene Catalina para el SPANK.
+[FEC_CF3]
+Configuración 3
-[AS2_B]
-Va mucho más allá de hacer que los jamaicanos lo vendan en las esquinas.
+[FEC_CF4]
+Configuración 4
-[AS2_D]
-Vende SPANK en puestos callejeros.
+[FEC_CDP]
+Pantalla del mando
-[AS2_1]
-~g~¡Todos los puestos de café en Portland han sido destruidos!
+[FEC_ONF]
+A pie
-[AS2_2]
-~g~¡Todos los puestos de café en Staunton Island han sido destruidos!
+[FEC_INC]
+En coche
-[AS2_3]
-~g~¡Todos los puestos de café en Shoreside Vale han sido destruidos!
+[FEC_VIB]
+Vibración :
-[AS2_4]
-~r~¡El cártel ha avisado a sus camellos!
+[FEL_ENG]
+Inglés
-[AS2_5]
-~g~¡Todavía hay puestos de café en Shoreside Vale y en Staunton Island!
+[FEL_FRE]
+Francés
-[AS2_6]
-~g~¡Todavía hay puestos de café en Shoreside Vale!
+[FEL_GER]
+Alemán
-[AS2_7]
-~g~¡Todavía hay puestos de café en Staunton Island!
+[FEL_ITA]
+Italiano
-[AS2_8]
-~g~¡Todavía hay puestos de café en Portland!
+[FEL_SPA]
+Español
-[AS2_9]
-~g~¡Todavía hay puestos de café en Portland y en Shoreside Vale!
+[FED_DBG]
+Menú de soluciones técnicas
-[AS2_10]
-~g~¡Todavía hay puestos de café en Portland y en Staunton Island!
+[FED_RID]
+Recargar IDE
-[AS2_12]
-~g~¡Recorre los distritos de Liberty y busca puestos de café ~b~Espresso-2-Go~g~!
+[FED_RIP]
+Recargar IPL
-[AS3_A]
-¿Lo apretamos un poco más o esperamos a que se vuelva negro y se caiga?
+[FED_PAH]
+Parse Heap
-[AS3_B]
-Dale un toque rápido...
+[FED_DFL]
+CLos guiones::DbgBandera
-[AS3_D]
-¡Mi manitas!
+[FED_DLS]
+Gran luz blanca de solución técnica encendida
-[AS3_E]
-Me aburría, así que vine a hacer compañía a Asuka.
+[FED_SPR]
+Mostrar grupos de aceras
-[AS3_1]
-~g~¡Busca una ~r~lancha~g~ y ve a la ~b~boya señalada~g~!
+[FED_SCR]
+Mostrar grupos de carreteras
-[AS3_3]
-~g~¡Espera a que la ~y~avioneta~g~ comience a acercarse!
+[FED_SCZ]
+Mostrar zonas de desechos
-[AS3_5]
-~g~¡Recupera el cargamento!
+[FED_DSR]
+Solicitud de solución técnica del streaming
-[AS3_4]
-~g~¡Usa un lanzacohetes para derribar ~y~la avioneta~g~!
+[FED_SCP]
+gbMostrarcolisiónPolys
-[AS3_2]
-~b~¡Ve a la boya del aeropuerto señalada! ~y~¡El avión se está acercando!
+[PL_STAT]
+Estadísticas del jugador
-[AS3_6]
-~g~~1~ DE 8
+[PE_WAST]
+Gente que te has cargado
-[KM1]
-'LA FUGA DEL KANBU'
+[PE_WSOT]
+Gente eliminada por otros
-[KM3]
-'UN MAL TRATO'
+[TM_BUST]
+Veces detenido
-[KM4]
-'SHIMA'
+[GNG_WST]
+Miembros de la banda liquidados
-[KM5]
-'CONTRINCANTES TRAFICANTES'
+[DED_CRI]
+Criminales liquidados
-[KM1_A]
-Mi hermana te tiene en gran estima,
+[PER_COM]
+Porcentaje completado
-[KM1_E]
-pero yo no estoy convencido de que un gaijin pueda ofrecerme algo más que desilusiones.
+[KGS_EXP]
+Kilogramos de explosivos empleados
-[KM1_B]
-Tal vez puedas ayudar con una situación que me perjudica.
+[ACCURA]
+Precisión
-[KM1_F]
-Por supuesto, el fracaso conllevará una desgracia.
+[ST_WEAP]
+Presupuesto armamentístico
-[KM1_C]
-Un kanbu, o jefe de la yakuza, está bajo custodia a la espera de juicio.
+[ST_PROP]
+Presupuesto de propiedades
-[KM1_G]
-Es un miembro importante de la familia.
+[ST_AUTO]
+Presupuesto para reparación de coches y pintura
-[KM1_H]
-Libéralo y llévalo al dojo de Bedford Point.
+[ST_PHOT]
+Fotografías tomadas
-[KM1_D]
-Agradecemos tus generosas acciones. Si alguna vez necesitas ayuda, el dojo tendrá el honor de proporcionarte dos hombres que te ayudarán.
+[ST_LOAN]
+Visitas de usureros prestamistas
-[KM1_1]
-~g~¡Roba un coche de la policía!
+[ST_STOR]
+Almacenes desvalijados
-[KM1_2]
-~g~¡Instala una bomba en el coche!
+[ST_MOVI]
+Escenas de especialista
-[KM1_3]
-~g~Ahora llévalo al dojo de la yakuza.
+[ST_PIZZ]
+Pizzas entregadas
-[KM1_5]
-~g~Ahora ve a la comisaría.
+[ST_GARB]
+Recogidas de basura efectuadas
-[KM1_6]
-~g~¡Pon una bomba en el coche!
+[ST_ICEC]
+''Helado'' vendido
-[KM1_7]
-~g~¡Sólo pueden entrar vehículos de policía autorizados!
+[TOP_SHO]
+Puntuación máxima en el campo de tiro
-[KM1_9]
-~r~No destruiste la pared con un coche bomba.
+[SHO_RAN]
+Clasificación del campo de tiro
-[KM1_10]
-~r~El kanbu está muerto, ¡y tu honor también!
+[SEAGULL]
+Gaviotas disparadas
-[KM1_11]
-~r~¡La policía te ha seguido!
+[PROPOWN]
+Propiedad en posesión
-[KM2_A]
-Es imposible sobreestimar la importancia del protocolo en este trabajo.
+[ST_TIME]
+Tiempo de juego
-[KM2_B]
-Para mi vergüenza eterna, un hombre me hizo una vez un favor y nunca pude corresponder su amabilidad.
+[ST_FTIM]
+Horas de vuelo
-[KM2_C]
-Su debilidad son los coches y nos ha pedido que adquiramos ciertos modelos para su colección.
+[ST_PRAN]
+Clasificación de los pilotos
-[KM2_F]
-Mi honor lo exige.
+[ST_RAN0]
+Aprendiz
-[KM2_2]
-~g~Coche entregado.
+[ST_RAN1]
+Navegante
-[KM3_A]
-Cuando los problemas acechan, el tonto les da la espalda, mientras que el sabio los enfrenta.
+[ST_RAN2]
+Copiloto
-[KM3_B]
-El cártel colombiano ha ignorado nuestras repetidas peticiones de que dejen en paz nuestros intereses en Liberty.
+[ST_RAN3]
+Junior
-[KM3_C]
-Ahora están negociando con los jamaicanos para humillarnos aún más.
+[ST_RAN4]
+Competente
-[KM3_D]
-Están cerrando un trato en la ciudad.
+[ST_RAN5]
+Senior
-[KM3_F]
-Llévate a uno de mis hombres, roba un coche de los jamaicanos y presenta tus respetos a los colombianos.
+[ST_RAN6]
+As
-[KM3_E]
-¡Nuestro honor exige que no dejes a nadie vivo!
+[ST_RAN7]
+Barón rojo
-[KM3_2]
-~g~Recoge a tu contacto.
+[ST_DRWN]
+Peces alimentados
-[KM3_3]
-~g~¡La reunión está teniendo lugar en el aparcamiento del hospital de Rockford!
+[ST_FASH]
+Presupuesto para moda
-[KM3_4]
-~r~¡Han escapado!
+[ST_DAMA]
+Coste de propiedades destruidas
-[KM3_6]
-~g~¡Mátalos, mátalos a todos!
+[TM_DED]
+Visitas al hospital
-[KM3_8]
-~g~¡Necesitas un coche de los jamaicanos para este trabajo!
+[DAYSPS]
+Días transcurridos en el juego
-[KM3_9]
-~r~Uno de los colombianos ha muerto, se ha cancelado el trato.
+[NUMSHV]
+Visitas a pisos francos
-[KM3_10]
-~r~¡El contacto está muerto!
+[MXCARD]
+Max. Distancia de salto LOCO (pies)
-[KM4_A]
-Para ser verdaderamente fuerte, es importante no mostrar debilidad.
+[MXCARJ]
+Max. Altura de salto LOCO (pies)
-[KM4_C]
-Hazte con el dinero inmediatamente para que podamos ingresarlo en las cuentas del casino.
+[MXCARDM]
+Máxima distancia de salto LOCO (m)
-[KM4_1]
-¡Ni puedo pagarte, ni lo haría aunque pudiera!
+[MXCARJM]
+Máxima altura de salto LOCO (m)
-[KM4_9]
-¡Una banda de chavales acaba de arrasar el local! ¡Se han llevado todo!
+[MXFLIP]
+Máximas vueltas de salto LOCO
-[KM4_2]
-¡Sois inútiles!
+[MXJUMP]
+Máxima rotación de salto LOCO
-[KM4_10]
-Además, ¿qué clase de yakuza eres tú?
+[BUL_FIR]
+Balas disparadas
-{ Unused string? }
+[BUL_HIT]
+Aciertos
-[KM4_3]
-No pago a matones como vosotros para esto. Si quisiera esta clase de protección, llamaría a la policía, demonios.
+[SPRAYIN]
+Pintura
-[KM4_4]
-~g~¡Castiga a la banda responsable y recupera el ~b~dinero de la protección~g~!
+[BSTSTU]
+Mejor maniobra LOCA hasta ahora
-[KM4_7]
-~r~¡El tendero la acaba de palmar!
+[INSTUN]
+Maniobra loca
-[KM4_5]
-Donald Love desea que te pases por su terraza para tener una charla.
+[PRINST]
+Maniobra loca perfecta
-[KM4_6]
-¡Aquí está todo el dinero!
+[DBINST]
+Maniobra loca doble
-[KM4_8]
-~g~¡Maletín conseguido!
+[DBPINS]
+Maniobra loca doble perfecta
-[KM5_A]
-¡Tú! ¡Qué oportuno por tu parte que muestres ahora tu despreciable cara!
+[TRINST]
+Maniobra loca triple
-[KM5_B]
-¡Parece que tu ataque para disuadir a los jamaicanos
+[PRTRST]
+Maniobra loca triple perfecta
-[KM5_B1]
-de convertirse en aliados del cártel ha sido completamente inútil!
+[QUINST]
+Maniobra loca cuádruple
-[KM5_C]
-¡Los traficantes jamaicanos están vendiendo SPANK por las calles de Liberty como si fueran perritos calientes!
+[PQUINS]
+Maniobra loca cuádruple perfecta
-[KM5_D]
-Estos cerdos del cártel se están riendo de nosotros, ¡de mí!
+[NOSTUC]
+No se ha completado ninguna
-[KM5_E]
-¡Te daré una última oportunidad para demostrar que la fe que tiene mi hermana en ti está justificada!
+[NOUNIF]
+Saltos únicos completados
-[KM5_F]
-¡Aplasta a estos canallas y lava tu vergüenza en el río de la sangre de nuestros enemigos!
+[NMISON]
+Intentos de misión
-[KM5_3]
-~r~No has matado a ~1~ jamaicanos.
+[PASDRO]
+Pasajeros en destino
-[KM5_4]
-~g~Enhorabuena, has matado a ~1~ jamaicanos.
+[MONTAX]
+Dinero conseguido con el taxi
-[KM5_5]
-~g~Enhorabuena, has matado a ~1~ jamaicanos. PREMIO DE ~1~ $
+[DAYPLC]
+Gastos diarios provocados a la policía
-[RM1]
-'SILENCIA AL SOPLÓN'
+[CRIMRA]
+Tasa criminal:
-[RM3]
-'FALTA DE PRUEBAS'
+[STPR_1]
+El Malibú
-[RM4]
-'DE PESCA'
+[STPR_2]
+Imprenta
-[RM5]
-'DESESCAYOLADOR'
+[STPR_3]
+Estudio de cine
-[RM1_D]
-Se encuentra bajo protección armada en una propiedad de WitSec en el centro de Newport, en algún piso que hay detrás del aparcamiento.
+[STPR_4]
+Fábrica de helados
-[RM1_E]
-Quema el lugar, así saldrán y podrás cazarlos. Asegúrate de que no hable con nadie.
+[STPR_5]
+Salón de coches
-[RM1_1]
-~g~Ve a la casa de protección de testigos.
+[STPR_6]
+Compañía de taxis
-[RM1_2]
-~g~¡Cárgate a McAffrey!
+[STPR_7]
+Astillero
-[RM2_A1]
-¡Chico, estoy aquí!
+[SET1EN]
+Configuración 1. Activada
-[RM2_A]
-Un viejo colega del ejército tiene un negocio en Rockford.
+[GMSAVE]
+Guardar partida
-[RM2_D]
-Necesitará refuerzos y a cambio te venderá todo su material a precios de ganga.
+[FEDS_TB]
+Volver
-[RM2_E]
-Ray me avisó... Pero pensé que vendría más gente.
+[FEST_OO]
+de
-[RM2_F]
-Bueno, tres brazos son mejor que uno, así que sírvete.
+[FEC_TUC]
+Control de la torreta
-[RM2_G]
-~g~¡Ve a ver a Phil!
+[FEC_RS3]
+Cambiar emisora de radio (Botón L3)
-[RM2_H]
-~r~¡Phil ha muerto!
+[FEC_HO3]
+Bocina (Botón L3)
-[RM2_L]
-¡Caray! ¡Si hubieras estado a mi lado en Nicaragua, a lo mejor conservaría el brazo!
+[C_FAIL]
+¡Misión de justiciero terminada!
-[RM2_N]
-Deja el dinero en el suelo. Ahora vete, ya me ocupo yo de la poli.
+[C_ESCP]
+~r~¡El sospechoso ha escapado!
-[RM3_D]
-Están transportando las pruebas por la ciudad.
+[C_VIGIL]
+¡BONIFICACIÓN DE JUSTICIERO!
-[RM3_E]
-Tendrás que embestir al coche y recoger hasta la última prueba que se le caiga.
+[HEAL_A]
+Tu ~h~salud~w~ aparece en naranja en la parte superior derecha de la pantalla.
-[RM3_F]
-En cuanto tengas todas, déjalas en tu coche y préndele fuego.
+[WRONGCD]
+Disco incorrecto. Introduce el disco correcto.
-[RM3_G]
-Cuando acabes, nos irá mucho mejor, chico.
+[NOCD]
+La bandeja del disco está vacía. Por favor, inserta el disco.
-[RM3_1]
-~g~Deja las pruebas en un coche y después préndele fuego.
+[OPENCD]
+La bandeja del disco está abierta. Por favor, cierra la bandeja de disco.
-[RM3_4]
-~g~¡Al fiscal se le ha caído una prueba!
+[CDERROR]
+Error al leer el DVD de Grand Theft Auto: Vice City
-[RM3_6]
-~r~¡Las fotos circularán por toda la ciudad!
+[RESTART]
+Iniciando nueva partida
-[RM3_7]
-~g~¡Ahora préndele fuego al coche!
+[GA_3]
+No hay más regalitos. ¡100 $ para volver a pintar!
-[RM4_A]
-Creo que mi socio es un soplón.
+[GA_1]
+¡Hala! ¡Demasiado peligroso para mi gusto!
-[RM4_C]
-Casi todas las noches sale a pescar con su lancha cerca del faro que hay en Portland Rock.
+[GA_1A]
+Vuelve cuando no estés tan ocupado...
-[RM4_D]
-¡Roba una lancha de la policía y húndele las ganas de dar puñaladas traperas!
+[HELP9_C]
+Pulsa ~h~~k~~k~~PED_FIREWEAPON~~w~para ~h~disparar~w~ el fusil de francotirador.
-[RM4_1]
-~g~Roba una lancha de la policía.
+[TAXI2]
+~r~¡Te has quedado sin tiempo!
-[RM4_2]
-~g~¡Ve al faro y despacha al socio de Ray!
+[PAGEB13]
+Salud entregada en el escondite
-[RM5_A]
-¡Inútil de mierda!
+[PAGEB14]
+Adrenalina entregada en el escondite
-[RM5_A1]
-¡La has cagado! Me la estoy jugando y ni siquiera eres capaz de matar a una maldita mosca.
+[FESZ_CA]
+Cancelar
-[RM5_B]
-¡Te pagué una pasta para matar al testigo y aún sigue vivo!
+[FES_NGA]
+Nueva partida
-[RM5_B1]
-¡Y hoy va a declarar ante los federales!
+[FES_CAN]
+Cancelar
-[RM5_C]
-Está a punto de ser trasladado del hospital general Carson, en Rockford.
+[FESZ_QL]
+Todo el progreso no guardado de tu partida actual se perderá. ¿Continuar cargando?
-[RM5_D]
-¡Si él canta, yo canto!
+[FESZ_QD]
+¿Proceder a borrar esta partida guardada?
-[RM5_E]
-¡Así que termina el trabajo por el que te pagué!
+[FESZ_QO]
+¿Proceder para sobrescribir esta partida guardada?
-[RM5_1]
-~g~Intercepta la ambulancia.
+[FESZ_QR]
+¿Seguro que quieres empezar una nueva partida? Todo el progreso desde la última partida guardada se perderá. ¿Continuar?
-[RM5_2]
-~g~¡Te han descubierto!
+[T4X4_1]
+Prueba de PCJ
-[RM5_3]
-~g~¡Era un señuelo!
+[BMX_1]
+Trial de tierra
-[RM5_4]
-~g~¡Las balas no atraviesan esa escayola de cuerpo entero!
+[BMX_2]
+Pista de pruebas
-[RM5_5]
-~g~¡Esa escayola de cuerpo entero es ignífugo!
+[BMXFAIL]
+~r~¡No has conseguido un nuevo récord!
-[RM5_7]
-~r~¡El testigo está a salvo!
+[BMX_REC]
+~g~¡Nuevo récord establecido: ~1~!
-[RM5_8]
-~g~¡El testigo se ha ahogado!
+[T4X4_3]
+¡AGARRADO!
-[LOVE2]
-'¡EXTERMINA AL WAKA-GASHIRA!'
+[MM_1]
+CONOCIRCUITO
-[LOVE3]
-'UNA GOTA EN EL OCÉANO'
+[T4X4_F]
+~r~¡Te rajaste! ¿Demasiado duro para ti?
-[LOVE1_A]
-Antes que nada, permíteme agradecerte que te hayas ocupado de ese asunto personal.
+[LANDSTK]
+Landstalker
-[LOVE1_F]
-Últimamente la gente tiende a malinterpretar las cosas.
+[IDAHO]
+Idaho
-[LOVE1_D]
-Pretenden exigirme más de lo pactado, pero no me gusta renegociar.
+[STINGER]
+Stinger
-[LOVE1_E]
-Un trato es un trato, así que no van a ver ni un dólar mío.
+[LINERUN]
+Linerunner
-[LOVE1_G]
-Rescata a mi amigo cueste lo que cueste.
+[PEREN]
+Perennial
-[LOVE1_2]
-~g~Rescata al anciano oriental.
+[SENTINL]
+Sentinel
-[LOVE1_3]
-~g~Lleva al anciano oriental de vuelta al edificio de Donald Love.
+[RIO]
+Río
-[LOVE1_4]
-~g~El anciano oriental debe estar detrás de alguna de estas puertas...
+[PATRIOT]
+Patriot
-[LOVE1_6]
-~r~¡Las tripas del anciano oriental están desparramadas por las calles!
+[FIRETRK]
+Camión de bomberos
-[LOVE1_7]
-~g~La puerta sólo se abrirá ante un coche de los colombianos.
+[TRASHM]
+Trashmaster
-[LOVE2_A]
-No hay nada como una clásica guerra de bandas para hacer que bajen los precios de los bienes inmuebles,
+[STRETCH]
+Limusina
-[LOVE2_B]
-excepto una plaga... pero eso sería excesivo en este caso.
+[MANANA]
+Mañana
-[LOVE2_C]
-He observado que la yakuza y los colombianos no son precisamente buenos amigos.
+[INFERNS]
+Infernus
-[LOVE2_D]
-Vamos a aprovechar esta oportunidad de negocio.
+[VOODOO]
+Voodoo
-[LOVE2_E]
-Quiero que mates a Kenji Kasen, el waka-gashira (segundo al mando) de la yakuza.
+[PONY]
+Pony
-[LOVE2_F]
-Kenji está asistiendo a una reunión en lo alto del aparcamiento de Newport.
+[MULE]
+Mule
-[LOVE2_G]
-¡Hazte con un coche de la banda del cártel y elimínalo!
+[CHEETAH]
+Cheetah
-[LOVE2_H]
-La yakuza debe culpar al cártel de esta declaración de guerra.
+[AMBULAN]
+Ambulancia
-[LOVE2_1]
-~g~¡Ve a Fort Staunton y roba un coche de la banda de los colombianos!
+[FBICAR]
+FBI Washington
-[LOVE2_2]
-~g~¡Ahora ve al ~p~aparcamiento de Newport~g~ y cárgate a Kenji!
+[MOONBM]
+Moonbeam
-[LOVE2_3]
-~r~¡Si no llevas un coche del cártel, te descubrirán!
+[ESPERAN]
+Esperanto
-[LOVE2_4]
-~r~¡La yakuza te ha reconocido!
+[TAXI]
+Taxi
-[LOVE2_6]
-~r~¡Has matado a todos los testigos!
+[WASHING]
+Washington
-[LOVE3_A]
-En estos días de hipocresía moral, ciertos artículos pueden resultar difíciles de importar.
+[BOBCAT]
+Bobcat
-[LOVE3_C]
-Echará varios paquetes al agua.
+[WHOOPEE]
+Mr Whoopee
-[LOVE3_D]
-Asegúrate de los consigues antes que nadie.
+[BFINJC]
+BF Injection
-[LOVE3_1]
-~g~¡Consigue una ~r~lancha~g~ y sigue a la ~y~avioneta~g~!
+[HUNTER]
+Hunter
-[LOVE4]
-'ROBO DE ALTOS VUELOS'
+[POLICAR]
+Policía
-[LOVE5]
-'SERVICIO DE ESCOLTA'
+[ENFORCR]
+Enforcer
-[LOVE4_A]
-Gracias por conseguir esos paquetes, pero sólo eran un señuelo.
+[SECURI]
+Securicar
-[LOVE4_B]
-Lo siento, pero a veces los negocios son así.
+[BANSHEE]
+Banshee
-[LOVE4_C]
-Mi verdadero objetivo se ocultaba en la avioneta.
+[PREDATR]
+Predator
-[LOVE4_F]
-He sobornado a los funcionarios.
+[BUS]
+Autobús
-[LOVE4_1]
-~r~¡El cártel colombiano está aquí!
+[RHINO]
+Rhino
-[LOVE4_2]
-~g~¡El paquete ha desparecido! Síguele la pista a los colombianos y recupéralo.
+[BARRCKS]
+Barracks OL
-[LOVE4_3]
-~g~¿''Panlantic Construction''...?
+[CUBAN]
+Cuban Hermes
-[LOVE4_5]
-~g~El paquete debería estar en la avioneta...
+[HELI]
+Helicóptero
-[LOVE4_6]
-~g~¡Usa el ascensor!
+[DODO]
+Dodo
-[LOVE5_B]
-Mi amigo oriental necesita que le escolten mientras comprueba la autenticidad de mi última adquisición.
+[COACH]
+Autocar
-[LOVE5_1]
-~g~¡En marcha!
+[CABBIE]
+Taxi clásico
-[LOVE5_2]
-~g~¡Necesitas un coche!
+[STALION]
+Stallion
-[LOVE5_3]
-~g~¡Comprueba la salida del túnel!
+[RUMPO]
+Rumpo
-[LOVE5_4]
-~r~¡Protege el camión!
+[RCBANDT]
+Bandit RC
-[RM6]
-'HOMBRE MUERTO'
+[ROMERO]
+Romero's Hearse
-[RM6_A]
-¿No te han seguido? Bien.
+[PACKER]
+Packer
-[RM6_B]
-Se acabó, ¡esto se me va de las manos y estoy con la soga al cuello!
+[ADMIRAL]
+Admiral
-[RM6_D]
-Soy hombre muerto, así que tengo que largarme.
+[SQUALO]
+Squalo
-[RM6_E]
-¡Consigue que no pierda mi vuelo en el aeropuerto y haré que tu trabajo haya merecido la pena!
+[SEASPAR]
+Sea Sparrow
-[RM6_666]
-Cuida mi Patriot a prueba de balas. Nos vemos en Miami, Ray
+[PIZZABO]
+Pizza Boy
-[CAT1]
-'RESCATE'
+[GANGBUR]
+Gang Burrito
-[CAT2]
-'EL INTERCAMBIO'
+[TROPIC]
+Tropic
-[CAT1_A]
-Tengo a tu linda María. Si no quieres que parezca que un carnicero se ensañó con ella,
+[SPEEDER]
+Speeder
-{ UNUSED DUPLICATE }
+[REEFER]
+Reefer
-[CAT2_F]
-Me he roto una uña y se me ha estropeado el peinado. Es increíble. ¡Me había costado cincuenta dólares!
+[FLATBED]
+Flatbed
-{ UNUSED DUPLICATE }
+[YANKEE]
+Yankee
-[CAT2_G]
-Estaba muerta de miedo, pero luego me dije a mí misma: ''Ya eres mayorcita''.
+[CADDY]
+Caddy
-{ UNUSED DUPLICATE }
+[ZEBRA]
+Taxi cebra
-[CAT2_H]
-Oh, nos lo vamos a pasar a lo grande, porque, ¿sabes?, mi hermana dijo que quería venirse a vivir con sus dos hijos,
+[TOPFUN]
+Top Fun
-{ UNUSED DUPLICATE }
+[SKIMMER]
+Skimmer
-[CAT2_I]
-porque su marido a vuelto a enredar por ahí y...
+[PCJ600]
+PCJ 600
-[CAT1_F]
-¡Ve a donde está Catalina antes de que se acabe el tiempo!
+[PHOENIX]
+Phoenix
-[CAT_MON]
-~g~Todavía te falta dinero. Necesitas 500.000 dólares.
+[FAGGIO]
+Faggio
-[BITCH_D]
-~g~¡María está muerta!
+[FREEWAY]
+Freeway
-[WEATHER]
-FORZAR EL CLIMA
+[RCBARON]
+Barón RC
-[WEATHE2]
-CLIMA NORMAL
+[RCRAIDE]
+Raider RC
-[8001]
-¡Has fallado miserablemente!
+[GLENDAL]
+Glendale
-[1000]
-HAS MUERTO
+[OCEANIC]
+Oceanic
-[1001]
-HAS MUERTO
+[SANCHEZ]
+Sanchez
-[1002]
-HAS MUERTO
+[SPARROW]
+Sparrow
-[1003]
-HAS MUERTO
+[LOVEFIS]
+Love Fist
-[1004]
-HAS MUERTO
+[COASTG]
+Guardacostas
-[1005]
-TRINCADO
+[DINGHY]
+Dinghy
-[1006]
-TRINCADO
+[HERMES]
+Hermes
-[1007]
-TRINCADO
+[SABRE]
+Sabre
-[1008]
-TRINCADO
+[SABRETU]
+Sabre Turbo
-[1009]
-TRINCADO
+[WALTON]
+Walton
-[GA_4]
-Una bomba de coche vale 1.000 dólares.
+[REGINA]
+Regina
-[GA_5]
-Tu coche ya tiene una bomba instalada.
+[COMET]
+Comet
-[GA_6] { re3 change }
-¡Apárcalo, actívala pulsando ~h~~k~~VEHICLE_FIREWEAPON~~w~ y SAL PITANDO!
+[DELUXO]
+Deluxo
-[GA_7] { re3 change }
-Activa la bomba pulsando ~h~~k~~VEHICLE_FIREWEAPON~~w~. Estallará cuando se arranque el motor.
+[BURRITO]
+Burrito
-[GA_8]
-Utiliza el detonador para activar la bomba.
+[SPAND]
+Spand Express
-[GA_9]
-Ha conseguido ~1~ de los 10 coches especiales.
+[MARQUIS]
+Marquis
-[GA_10]
-Buen trabajo. Aquí tienes tus ~1~ dólares.
+[BAGGAGE]
+Mozo de equipaje
-[GA_11]
-Ya tenemos este modelo. ¡No nos sirve para nada!
+[KAUFMAN]
+Taxi Kaufman
-[GA_12]
-Bomba armada
+[COASTMA]
+Guardacostas Maverick
-[GA_13]
-Eres todo un profesional. Completa la lista y conseguirás una recompensa.
+[MAVERIC]
+Maverick
-[GA_14]
-Ya están todos los coches. ¡Estupendo! Toma un detallito.
+[RANCHER]
+Rancher
-[GA_15]
-Espero que te guste el nuevo color.
+[FBIRANC]
+FBI Rancher
-[GA_16]
-Esta mano de pintura es gratuita.
+[VIRGO]
+Virgo
-[GA_19]
-No nos interesa ese modelo.
+[GREENWO]
+Greenwood
-[GA_20]
-De ese modelo tenemos más de los que podemos colocar. Lo siento, tío, no hay trato.
+[HOTRING]
+Hotring Racer
-[CR_1]
-La grúa no puede levantar este vehículo.
+[BLISTAC]
+Blista Compact
-[PU_MONY]
-No tienes suficiente dinero.
+[FEST_DF]
+Dist. recorrida a pie (millas)
-[CO_ALL]
-Te has hecho con todos. Toma un detallito...
+[FEST_DC]
+Dist. recorrida en coche (millas)
-[PAUSED]
-PARTIDA EN PAUSA
+[FESTDFM]
+Distancia recorrida a pie (m)
-[HEALTH1]
-¡Largo! Estás completamente sano.
+[FESTDCM]
+Distancia recorrida en coche (m)
-[HEALTH2]
-La sanidad cuesta dinero.
+[TOT_DIS]
+Distancia total recorrida (millas)
-[HEALTH3]
-Te pondré como nuevo.
+[TOTDISM]
+Distancia total recorrida (m)
-[HEALTH4]
-Te va a costar 250 $.
+[DISTHEL]
+Dist. recorrida en helicóptero (millas)
-[FEB_STA]
-Estadísticas
+[DISTHEM]
+Distancia recorrida en helicóptero (m)
-[FEB_BRI]
-Resumen
+[DISTBOA]
+Dist. recorrida en barco (millas)
-[FEB_CON]
-Controles
+[DISTBOM]
+Distancia recorrida en barco (m)
-[FEB_AUD]
-Sonido
+[FEST_LS]
+Gente salvada en una ambulancia
-[FEB_DIS]
-Pantalla
+[FEST_CC]
+Criminales asesinados en misión Vigilante
-[FEB_LAN]
-Idioma
+[FEST_FE]
+Total de fuegos extinguidos
-[FEP_STA]
-ESTADÍSTICAS
+[FEST_RP]
+Masacres superadas
-[FEP_BRI]
-RESUMEN
+[FEST_MP]
+Misiones superadas
-[FEP_CON]
-CONTROLES
+[FEST_BB]
+Bling-bling Scramble:
-[FEP_AUD]
-SONIDO
+[FEST_H0]
+Mayoría de puntos de control
-[FEP_DIS]
-PANTALLA
+[FEST_GC]
+Total de coches de bandas:
-[FEP_LAN]
-IDIOMA
+[FEST_H1]
+Destrucción del diablo
-[FEF_ST1]
-¿Quién es el malo?
+[FEST_H2]
+Masacre de la mafia
-[FEF_ST2]
-Cuánta destrucción has producido
+[FEST_H3]
+Casino Calamity
-[FEF_BR1]
-¿Has perdido el hilo?
+[FEST_H4]
+Rumpo Wrecker
-[FEF_CO1]
-¿Necesitas más control?
+[USJ]
+¡BONIFICACIÓN POR MANIOBRA ÚNICA!
-[FEF_CO2]
-Elige la mejor configuración del mando para tu estilo de juego
+[USJ_DUN]
+MANIOBRA YA COMPLETADA
-[FEF_SA1]
-¡Mantén tu sitio en el bloque!
+[RATNG1]
+Ciudadano honrado
-[FEF_SA2]
-Guarda y carga tus partidas
+[RATNG2]
+Nadie en especial
-[FEF_AU1]
-¡Dale candela al volumen!
+[RATNG3]
+Basurero
-[FEF_AU2]
-Elige una emisora de radio y un efecto de sonido
+[RATNG4]
+Cleptómano
-[FEF_DI1]
-¡Cambia el juego!
+[RATNG5]
+Vándalo
-[FEF_DI2]
-Personaliza el juego para tu televisión
+[RATNG6]
+Chico de los recados
-[FEF_LA1]
-¿Qué dices de los Willis?
+[RATNG7]
+Carterista
-[FEF_LA2]
-Elige tu idioma preferido
+[RATNG8]
+Cleptómano
-[FEB_PMB]
-Resumen de la última misión:
+[RATNG9]
+Chivato
-[FEC_NA]
-No disponible
+[RATNG10]
+Rata
-[FEC_CWL]
-Siguiente arma
+[RATNG11]
+Lince
-[FEC_CWR]
-Arma anterior
+[RATNG12]
+Estafador
-[FEC_LOF]
-Mirar hacia delante
+[RATNG13]
+Timador
-{ !!!!!!!!!!!!!!!!!! ACHTUNG! THIS STRING IS USED FOR BOTH THE MAP'S CURRENT TARGET AS WELL AS FOR THE ACTION OF TARGETING WITH A GUN! THIS WILL SCREW AROUND TRANSLATIONS !!!!!!!!!!!!!!! }
-[FEC_TAR]
-Objetivo
+[RATNG14]
+Corredor de apuestas
-[FEC_MOV]
-Movimiento
+[RATNG15]
+Buscavidas
-[FEC_CAM]
-Cambiar cámara
+[RATNG16]
+Matón
-[FEC_PAU]
-Pausa
+[RATNG17]
+Chusma
-[FEC_ENV]
-Entrar en vehículo
+[RATNG18]
+Bribón
-[FEC_JUM]
-Saltar
+[RATNG19]
+Rufián
-[FEC_ATT]
-Atacar o disparar
+[RATNG20]
+Proscrito
-[FEC_RUN]
-Correr
+[RATNG21]
+Malhechor
-[FEC_FPC]
-Cámara en primera persona
+[RATNG22]
+Asesino
-[FEC_LL]
-Mirar a la izquierda
+[RATNG23]
+Super matón
-[FEC_LB1]
-Mirar
+[RATNG24]
+Matón
-[FEC_LB2]
-atrás
+[RATNG25]
+Presidiario
-[FEC_LB]
-Mirar atrás
+[RATNG26]
+Exconvicto
-[FEC_LR]
-Mirar a la derecha
+[RATNG27]
+Criminal
-[FEC_HOR]
-Claxon
+[RATNG28]
+Saqueador
-[FEC_VES]
-Controlar vehículo
+[RATNG29]
+Mafioso
-[FEC_RSC]
-Cambiar emisora de radio
+[RATNG30]
+Conductor
-[FEC_BRA]
-Freno o marcha atrás
+[RATNG31]
+Gorila
-[FEC_HAB]
-Freno de mano
+[RATNG32]
+Asesino profesional
-[FEC_CAW]
-Arma del vehículo
+[RATNG33]
+Asuntos internos
-[FEC_ACC]
-Acelerar
+[RATNG34]
+Agente
-[FEC_SMT]
-Activar misión especial
+[RATNG35]
+Ronin
-[FEA_OUT]
-Salida:
+[RATNG36]
+Manitas
-[FEA_ST]
-Estéreo
+[RATNG37]
+Asesino a sueldo
-[FEA_MNO]
-Mono
+[RATNG38]
+Asociado
-[FEA_NON]
-Ninguna
+[RATNG39]
+Carnicero
-[FEA_FM0]
-HEAD RADIO
+[RATNG40]
+Encargado de la limpieza
-[FEA_FM1]
-DOUBLE CLEF FM
+[RATNG41]
+Asesino
-[FEA_FM2]
-K-JAH RADIO
+[RATNG42]
+Consigliere
-[FEA_FM3]
-RISE FM
+[RATNG43]
+Maleante
-[FEA_FM4]
-LIPS 106
+[RATNG44]
+Mano derecha
-[FEA_FM5]
-GAME FM
+[RATNG45]
+Ejecutor
-[FEA_FM6]
-MSX FM
+[RATNG46]
+Teniente
-[FEA_FM7]
-FLASHBACK 95.6
+[RATNG47]
+Subjefe
-[FEA_FM8]
-CHATTERBOX FM
+[RATNG48]
+Capo
-[FED_DBG]
-Menú de depuración
+[RATNG49]
+Jefe
-[FED_RID]
-Recargar IDE
+[RATNG50]
+Negado
-[FED_RIP]
-Recargar IPL
+[RATNG51]
+Don
-[FED_PAH]
-Analizar pila
+[RATNG52]
+Rey de la Jodida Ciudad
-[FED_RCD]
-CCullZones::RecalculateCullZoneData
+[PAGE_00]
+.
-[FED_DFL]
-CTheScripts::DbgFlag
+[WELCOME]
+BIENVENIDO A
-[FED_DLS]
-Cambiar luz blanca grande de depuración
+[TSCORE]
+GANANCIAS: ~1~ $
-[FED_SPR]
-Mostrar rutas de aceras
+[PBOAT_2] { reVC update }
+Pulsa ~h~~k~~VEHICLE_FIREWEAPON~~w~ para disparar los cañones del barco.
-[FED_SCR]
-Mostrar rutas de carreteras
+[HJSTAT]
+Distancia: ~1~.~1~m Altura: ~1~.~1~m Vueltas: ~1~ Rotación: ~1~_
-[FED_SCZ]
-Mostrar zonas de máscara selectiva
+[HJSTATW]
+Distancia: ~1~.~1~m Altura: ~1~.~1~m Vueltas: ~1~ Rotación: ~1~_ ¡qué gran aterrizaje!
-[FED_DSR]
-Solicitudes de depuración de streaming
+[ATUTOR]
+Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misiones de ATS.
-[FED_SCP]
-gbShowCollisionPolys
+[FEST_HA]
+Nivel más alto de misión de ATS
-[FEM_MCM]
-Menú de Memory Card
+[C_KILLS]
+CRIMINALES ASESINADOS: ~1~
-[FEM_RMC]
-Registrar MemCard uno
+[HJSTATF]
+Distancia: ~1~ pies Altura: ~1~ pies Vueltas: ~1~ Rotación: ~1~_
-[FEM_TFM]
-Probar MemCard uno formateada
+[HJSTAWF]
+Distancia: ~1~ pies Altura: ~1~ pies Vueltas: ~1~ Rotación: ~1~_, ¡y qué gran aterrizaje!
-[FEM_TUM]
-Probar Memcard uno sin formato
+[CRED001]
+ROCKSTAR NORTH
-[FEM_CRD]
-Crear directorio raíz
+[CRD001A]
+DIRECTOR DEL ESTUDIO
-[FEM_CLI]
-Crear y cargar iconos
+[CRD001B]
+ANDREW SEMPLE
-[FEM_FFF]
-Llenar primer archivo con basura
+[CRED002]
+PRODUCTOR
-[FEM_SOG]
-Guardar sólo partida
+[CRD002A]
+DIRECTOR DE DESARROLLO
-[FEM_CES]
-Comprobar cada guardado de 0kB4
+[CRED003]
+LESLIE BENZIES
-[FEM_STG]
-Guardar partida
+[CRED004]
+DIRECTOR DE ARTE
-[FEM_STS]
-Guardar partida bajo el nombre GTA3
+[CRED005]
+AARON GARBUT
-[FEM_CPD]
-Crear copia protegida del directorio mag
+[CRED006]
+DIRECTORES TÉCNICOS
-[FEM_MC2]
-Menú de Memory Card 2
+[CRED007]
+OBBE VERMEIJ
-[FEM_TS]
-Prueba de guardado:
+[CRED008]
+ADAM FOWLER
-[FEM_TL]
-Prueba de carga:
+[CRED010]
+ANDREW DUTHIE
-[FEM_TD]
-Prueba de borrado:
+[CRED011]
+CRAIG FILSHIE
-[PL_STAT]
-Estadísticas de jugador
+[CRED012]
+WILLIAM MILLS
-[PE_WAST]
-Personas asesinadas
+[CRED013]
+CHRIS ROTHWELL
-[PE_WSOT]
-Personas asesinadas por otros
+[CRD013A]
+IMRAN SARWAR
-[CAR_EXP]
-Coches reventados
+[CRD013B]
+JAMES WORRALL
-[TM_BUST]
-Veces arrestado
+[CRD013C]
+JOHN HAIME
-[M_WASTE]
-Hombres civiles asesinados
+[CRED014]
+ESCRITO POR
-[F_WASTE]
-Mujeres civiles asesinadas
+[CRED015]
+JAMES WORRALL
-[PIG_WST]
-Polis asesinados
+[CRED016]
+PAUL KUROWSKI
-[GNG_WST]
-Miembros de bandas asesinados
+[CRED017]
+DAN HOUSER
-[MED_WST]
-Médicos asesinados
+[CRED018]
+DISEÑO DEL PERSONAJE PRINCIPAL
-[FIRE_WS]
-Bomberos asesinados
+[CRD018A]
+DISEÑO DE PERSONAJES
-[DED_CRI]
-Criminales asesinados
+[CRED019]
+IAN MCQUE
-[DED_DED]
-Vagabundos asesinados
+[CRD019A]
+TOKS SOLARIN
-[DED_HOK]
-Prostitutas asesinadas
+[CRD019B]
+ALAN DAVIDSON
-[HEL_DST]
-Helicópteros destruidos
+[CRED020]
+ANIMACIÓN PRINCIPAL
-[PER_COM]
-Porcentaje completado
+[CRED021]
+ALEX HORTON
-[KGS_EXP]
-Kgs de explosivos empleados
+[CRD022A]
+ANIMACIÓN
-[ACCURA]
-Precisión de tiro
+[CRED022]
+LEE MONTGOMERY
-[ELBURRO]
-Mejor tiempo de ''Turismo'' en segundos
+[CRD022B]
+DUNCAN SHIELDS
-[CAR_CRU]
-Coches destrozados
+[CRD022C]
+GUS BRAID
-[HED_EX]
-Cabezas explotadas
+[CRED023]
+DISEÑO DE VEHÍCULOS
-[TM_DED]
-Visitas al hospital
+[CRD023A]
+JOLYON ORME
-[DAYSPS]
-Días de juego transcurridos
+[CRD023B]
+ALAN DUNCAN
-[MMRAIN]
-mm de lluvia caídos
+[CRD024A]
+DISEÑO DEL VEHÍCULO PRINCIPAL
-[MXCARD]
-Dist. máx. de salto demencial (pies)
+[CRED024]
+PAUL KUROWSKI
-[MXCARJ]
-Altura máx. de salto demencial (pies)
+[CRED025]
+DISEÑO DE MAPAS
-[MXCARDM]
-Dist. máx. de salto demencial (metros)
+[CRED026]
+ADAM COCHRANE
-[MXCARJM]
-Altura máx. de salto demencial (metros)
+[CRED027]
+NIK TAYLOR
-[MXFLIP]
-Vueltas máximas en salto demencial
+[CRED028]
+GARY MCADAM
-[MXJUMP]
-Rotación máxima en salto demencial
+[CRED029]
+KEIRAN BAILLIE
-[BSTSTU]
-Mayor acrobacia demencial:
+[CRED030]
+ALISDAIR WOOD
-[INSTUN]
-Acrobacia demencial
+[CRED031]
+ANDREW SOOSAY
-[PRINST]
-Acrobacia demencial perfecta
+[CRD031A]
+STEVEN MULHOLLAND
-[DBINST]
-Acrobacia demencial doble
+[CRD031B]
+WAYLAND STANDING
-[DBPINS]
-Acrobacia demencial doble perfecta
+[CRD031C]
+CAMPBELL J. DICK
-[TRINST]
-Acrobacia demencial triple
+[CRD031D]
+DISEÑO GRÁFICO
-[PRTRST]
-Acrobacia demencial triple perfecta
+[CRD031E]
+STUART PETRI
-[QUINST]
-Acrobacia demencial cuádruple
+[CRED032]
+PROGRAMADOR JEFE
-[PQUINS]
-Acrobacia demencial cuádruple perfecta
+[CRD032A]
+PROGRAMADORES
-[NOSTUC]
-No se han hecho acrobacias
+[CRED033]
+ALEXANDER ROGER
-[NOUNIF]
-Saltos únicos completados
+[CRED034]
+GRAEME WILLIAMSON
-[NOUNGM]
-Saltos únicos
+[CRED035]
+BARANE CHAN
-[NMISON]
-Intentos de misión
+[CRED036]
+DEREK PAYNE
-[NMMISP]
-Misiones superadas
+[CRED037]
+GORDON YEOMAN
-[PASDRO]
-Pasajeros transportados
+[CRD037A]
+ALAN CAMPBELL
-[MONTAX]
-Dinero conseguido en taxi
+[CRD037B]
+MARK HANLON
-[DAYPLC]
-Gastos diarios provocados a la policía
+[CRD037C]
+ANDRZEJ MADAJCZYK
-[CRIMRA]
-Rango de criminal:
+[CRED038]
+PRODUCTOR JEFE MUSICAL
-[GMSTOR]
-Almacenar partida
+[CRED039]
+CRAIG CONNER
-[PREBRF]
-Resúmenes anteriores
+[CRED040]
+STUART ROSS
-[CNTLS]
-Controles
+[CRED041]
+INGENIERO JEFE DE AUDIO
-[MUSMEN]
-Música/Efectos
+[CRED042]
+ALLAN WALKER
-[GAMSET]
-Ajustes del juego
+[CRD041A]
+INGENIERO DE AUDIO
-[LANGUA]
-Idioma
+[CRD041B]
+AUDIO
-[DSPLAY]
-Pantalla
+[CRD042A]
+WILL MORTON
-[DEBUGM]
-Menú de depuración
+[CRED043]
+PROGRAMADOR DE AUDIO
-[QUITOP]
-Salir de las opciones
+[CRED044]
+RAYMOND USHER
-[CONTRL]
-Configuración de controles
+[CRED045]
+JEFE DE PRUEBAS
-[SET1EN]
-Ajuste 1. Activado
+[CRED046]
+CRAIG ARBUTHNOTT
-[SET1]
-Ajuste 1.
+[CRED047]
+CONTROL DE CALIDAD PRINCIPAL
-[SET2EN]
-Ajuste 2. Activado
+[CRED048]
+NEIL CORBETT
-[SET2]
-Ajuste 2
+[CRED049]
+KEVIN WONG
-[SET3EN]
-Ajuste 3. Activado
+[CRED050]
+CONTROL DE CALIDAD
-[SET3]
-Ajuste 3
+[CRED051]
+DAVID BEDDOES
-[SET4EN]
-Ajuste 4. Activado
+[CRED052]
+DAVID WATSON
-[SET4]
-Ajuste 4
+[CRED053]
+BARRY CLARK
-[GOBACK]
-Volver
+[CRED054]
+ROSS SPARROW
-[SOUND]
-SONIDO
+[CRED055]
+JAMES ALLAN
-[MUSVOL]
-Volumen de la música
+[CRED056]
+NEIL MEIKLE
-[SFXVOL]
-Volumen de los efectos
+[CRD056A]
+GEORGE WILLIAMSON
-[SCROPT]
-OPCIONES DE PANTALLA
+[CRD056B]
+MATT JONES
-[CTRSCR]
-Centrar pantalla
+[CRD056C]
+ROB HARBOUR
-[SCRFOR]
-Formato de imagen
+[CRD056D]
+TOM WHITTAKER
-[GMSVLQ]
-GUARDAR-CARGAR-SALIR
+[CRED057]
+SOPORTE TÉCNICO PRINCIPAL
-[GMREST]
-Reiniciar partida
+[CRED058]
+LORRAINE ROY
-[GMLOAD]
-CARGAR PARTIDA
+[CRD057A]
+SOPORTE TÉCNICO
-[NOGMSV]
-Sólo puedes guardar desde tu escondite.
+[CRED059]
+CHRISTINE CHALMERS
-[DLFILE]
-Borrar archivos de Grand Theft Auto III
+[CRD060A]
+SOPORTE DE OFICINA
-[CHFILE]
-ELEGIR ARCHIVO A CARGAR
+[CRD060B]
+KIM GURNEY
-[CHCDLD]
-ELEGIR MEMORY CARD A USAR
+[CRD060C]
+CASSIE OLIVER
-[CDUNFR]
-Memory Card sin formato.
+[CRED060]
+ROCKSTAR NUEVA YORK
-[CHFIDL]
-ELEGIR ARCHIVO A BORRAR
+[CRED061]
+GABINETE DE APOYO
-[SVCONF]
-CONFIRMACIÓN
+[CRED062]
+SAM HOUSER
-[SVFNAM]
-El nombre de tu archivo guardado es
+[CRED063]
+PRODUCTOR
-[SAVEDN]
-Error. Fallo al guardar.
+[CRED064]
+DAN HOUSER
-[LANGSL]
-SELECCIÓN DE IDIOMA
+[CRED065]
+VICEPRESIDENTE DE DESARROLLO
-[ENGLIS]
-Inglés
+[CRED066]
+JAMIE KING
-[GERMAN]
-Alemán
+[CRED067]
+OFICIAL JEFE DE TECNOLOGÍA
-[ITALIA]
-Italiano
+[CRED068]
+GARY J. FOREMAN
-[FRENCH]
-Francés
+[CRED069]
+PRODUCTOR ASOCIADO
-[SPAIN]
-Español
+[CRED070]
+JEREMY POPE
-[RELIDE]
-ReLoadIde
+[CRD071A]
+DIRECTOR DE CONTROL DE CALIDAD
-[RELIPE]
-ReLoadIpl
+[CRD072A]
+JEFF ROSA
-[PARSHP]
-Analizar pila
+[CRED071]
+SUPERVISOR MUSICAL
-[DBGFON]
-CTheScripts::DbgFlag activado
+[CRED072]
+TERRY DONOVAN
-[DBFOFF]
-CTheScripts::DbgFlag desactivado
+[CRED073]
+EQUIPO DE PRODUCCIÓN
-[BGWHON]
-Luz blanca grande de depuración activada
+[CRED074]
+TERRY DONOVAN
-[BGWOFF]
-Luz blanca grande de depuración desactivada
+[CRED075]
+JENNIFER KOLBE
-[DSTRON]
-Solicitudes de depuración de streaming activadas
+[CRED076]
+JENEFER GROSS
-[DSTROFF]
-Solicitudes de depuración de streaming desactivadas
+[CRED077]
+LAURA PATERSON
-[PDRGON]
-ShowPedRoadGroups activado
+[CRED078]
+JEFF CASTANEDA
-[PRGOFF]
-ShowPedRoadGroups desactivado
+[CRED079]
+JERONIMO BARRERA
-[CRRGON]
-ShowCarRoadGroups activado
+[CRED080]
+CARLY SLATER
-[CRGOFF]
-ShowCarRoadGroups desactivado
+[CRED081]
+JUNG KWAK
-[CLZOON]
-Zonas de máscara selectiva mostradas
+[CRED082]
+BRIAN WOOD
-[CLZOOF]
-Zonas de máscara selectiva ocultadas
+[CRED083]
+RENAUD SEBANNE
-[SHPLON]
-gbShowCollisionPolys activado
+[CRED084]
+RICHARD KRUGER
-[SHPLOF]
-gbShowCollisionPolys desactivado
+[CRD084A]
+DANIEL EINZIG
-[CULREC]
-CCullZones::RecalculateCullZoneData()
+[CRD084B]
+JACEN BURROWS
-[FORMM1]
-FormatMemCard 1 (prueba)
+[CRD084C]
+LINN PR
-[UNFRM1]
-UnFormatMemCard 1 (prueba)
+[CRD084D]
+DISEÑO DE PORTADA
-[GORLEV]
-Nivel de violencia
+[CRD084E]
+STEPHEN BLISS
-[SICASS]
-Puta locura
+[CRED085]
+KENT PAUL'S 80 NOSTALGIA ZONE
-[SICSIC]
-Puto manicomio
+[CRED086]
+ESCRITO POR DAN HOUSER
-[SCASSL]
-Seleccionado Puta locura
+[CRD086A]
+PRODUCIDO POR ADAM TEDMAN
-[SCSCSL]
-Seleccionado Puto manicomio
+[CRED087]
+WWW.KENTPAUL.COM AND WWW.VICECITY.COM
-[PRVMEN]
-Resúmenes de misiones anteriores
+[CRED088]
+CREADO POR
-[DOSVGM]
-¿Deseas guardar la partida?
+[CRD088A]
+ADAM TEDMAN
-[FORMEN]
-Menú de formato
+[CRD088B]
+DAVID YU
-[MEMTST]
-Pantalla MemoryCardTest
+[CRD088C]
+JERRY LUNA
-[REGCAR]
-Registrar MemoryCard uno
+[CRD088D]
+STUART PETRI
-[TEFONE]
-Probar MemCard uno con formato
+[CRD088E]
+MICHAEL CARNEVALE
-[TEUFON]
-Probar MemCard uno sin formato
+[CRD088F]
+GREG LAU
-[CRROOT]
-CreateRootDir
+[CRD088G]
+FUTABA HAYASHI
-[CRLDIC]
-Crear y cargar iconos
+[CRED089]
+JEFE DE CONTROL DE CALIDAD
-[FLFSGF]
-Llenar el primer archivo con basura
+[CRED090]
+CRAIG ARBUTHNOTT
-[PUSAVE]
-Guardar sólo la partida
+[CRED091]
+ANALISTA JEFE
-[CHEVOK]
-CheckEveryOkB4Save
+[CRED092]
+ADAM DAVIDSON
-[SVGMON]
-SaveTheGame
+[CRD092A]
+JOE HOWELL
-[CNTSAV]
-No se puede guardar la partida en una misión.
+[CRD092B]
+MARC FERNANDEZ
-[CNCSAV]
-No se puede guardar la partida dentro de un vehículo.
+[CRED093]
+ANALISTA DEL JUEGO
-[CRMGSV]
-Crear directorio de cargador con protección de copia
+[CRED094]
+RICHARD HUIE
-[MGSVNC]
-MagazineDirectory no creado
+[CRED095]
+EQUIPO DE PRUEBAS DE ROCKSTAR
-[MGSVCN]
-MagazineDirectory creado
+[CRED096]
+LANCE WILLIAMS
-[YES]
-Sí
+[CRED097]
+JOE GREENE
-[NO]
-No
+[CRED098]
+BRIAN PLANER
-[X]
-x
+[CRD098A]
+ELIZABETH SATTERWHITE
-[LAST]
-Último mensaje
+[CRD098B]
+JAMEEL VEGA
-[FEDS_XB]
-Seleccionar
+[CRD098C]
+MIKE HONG
-[FEDS_ST]
-Botón START - CONTINUAR
+[CRED099]
+LEE CUMMINGS
-[FEST_OO]
-de
+[CRED100]
+HISTORIA
-[FEC_TUC]
-Controlar torreta
+[CRED101]
+JAMES WORRALL
-[FEC_SM3]
-Activar misión secundaria (botón R3)
+[CRED102]
+DAN HOUSER
-[FEC_RS3]
-Cambiar emisora de radio (botón L3)
+[CRED103]
+ADAM TEDMAN
-[FEC_HO3]
-Claxon (botón L3)
+[CRED104]
+PAUL YEATES
-[DIAB1]
-'TURISMO'
+[CRED105]
+JENEFER GROSS
-[DIAB2]
-'IRA HELADA'
+[CRED106]
+LAURA PATERSON
-[DIAB3]
-'A LA HOGUERA'
+[CRED107]
+SECUENCIAS
-[DIAB4]
-'GRANDE Y VENOSA'
+[CRED108]
+ESCRITAS POR DAN HOUSER Y JAMES WORRALL
-[DIAB1_A]
-El Burro quiere ofrecerte una oportunidad. Ve al teléfono público de los cerros de Hepburn si te interesa.
+[CRED109]
+DIRECCIÓN DE AUDIO DE DAN HOUSER Y NAVID KHONSARI
-[DIAB1_C]
-Se te da bien correr. Pásate por el teléfono público y puede que El Burro tenga trabajo para ti.
+[CRED110]
+PRODUCIDAS POR JAMIE KING
-[DIAB1_1]
-~g~3... 2... 1... ¡ADELANTE!
+[CRD110A]
+SELECCIÓN DE ACTORES: JAMIE KING, SEAN MACALUSO
-[DIAB1_4]
-~g~Hazte con un coche rápido y ve a la parrilla de salida.
+[CRED111]
+REPARTO
-[DIAB1_3]
-~r~No sabes ganar ni una rifa, ¡FRACASADO!
+[CRD111A]
+PERSONAJES DE REPARTO
-[DIAB1_2]
-~g~Felicidades, has ganado con un tiempo increíble de ~1~ segundos.
+[CRED112]
+TOMMY VERCETTI - RAY LIOTTA
-[FIRST]
-~g~1
+[CRED113]
+KEN ROSENBERG - WILLIAN FICHTNER
-[SECOND]
-~g~2
+[CRED114]
+SONNY FORELLI - TOM SIZEMORE
-[THIRD]
-~g~3
+[CRED115]
+STEVE SCOTT - DENNIS HOPPER
-[FOURTH]
-~g~4
+[CRED116]
+AVERY CARRINGTON - BURT REYNOLDS
-[DIAB2_1]
-~g~Recoge el maletín en Harwood.
+[CRED117]
+RICARDO DÍAZ - LUIS GUZMÁN
-[DIAB2_2]
-~g~Encuentra un camión de helados.
+[CRED118]
+LANCE VANCE - PHILIP MICHAEL THOMAS
-[DIAB2_3]
-~g~Aparca el camión de helados en el muelle Atlantic.
+[CRED119]
+CORONEL JUAN CORTEZ - ROBERT DAVI
-[DIAB2_4]
-~g~Pulsa ~w~~k~~VEHICLE_HORN~~g~ para activar la melodía del camión de helados.
+[CRED120]
+UMBERTO ROBINA - DANNY TREJO
-[DIAB2_6]
-~g~Pulsa ~w~~k~~VEHICLE_HORN~~g~ para activar la melodía del camión de helados.
+[CRED121]
+PHIL CASSIDY - GARY BUSEY
-[DIAB2_7]
-~g~Pulsa ~w~~k~~VEHICLE_HORN~~g~ para activar la melodía del camión de helados.
+[CRED122]
+MITCH BAKER - LEE MAJORS
-[DIAB2_5]
-~g~Sal del camión y luego usa el mando a distancia para detonarlo.
+[CRED123]
+MERCEDES CORTEZ - FAIRUZA BALK
-[YD1]
-'CORRE A POR LA PASTA'
+[CRED124]
+KENT PAUL - DANNY DYER
-[YD2]
-'JINETE CON UZI'
+[CRED125]
+JEZZ TORRENT - KEVIN MCKIDD
-[YD3]
-'COLECCIONANDO COCHES DE BANDAS'
+[CRED126]
+SUPERVISOR TAXIS - DEBORAH HARRY
-[YD4]
-'POR LOS AIRES'
+[CRED127]
+CANDY SUXX - JENNA JAMESON
-[YD_P]
-El Rey Courtney quiere hablarte. ¡Ve al teléfono público de Aspatria!
+[CRED128]
+BJ SMITH - LAWRENCE TAYLOR
-[YD1_A]
-Habla el rey Courtney.
+[CRED129]
+TÍA POULET - YOUREE CLEOMILI HARRIS
-[YD1_A1]
-Mi banda jamaicana necesita un conductor y tú tienes buena reputación.
+[CRED130]
+PROVEEDOR - ARMANDO RIESCO
-[YD1_B]
-Ve en un coche al vertedero que hay detrás del estadio y espera a los otros candidatos.
+[CRED131]
+COUGAR - BLAYNE PERRY
-[YD1_C]
-Tengo hombres vigilando puntos de control por toda Staunton.
+[CRED132]
+HILARY - CHARLES TUCKER
-[YD1_D]
-El primer conductor que llegue a un punto de control se lleva mil pavos, y así de punto a punto.
+[CRED133]
+CONGRESISTA ALEX SHRUB - CHRIS LUCAS
-[YD1_D1]
-Si ganas más puntos de control que los demás, podría tener trabajo para ti.
+[CRED134]
+VIEJO KELLY - GEORGE DICENZO
-[YD1_E]
-~g~¡Prepárate!
+[CRD134A]
+CAM JONES - GREG SIMS
-[YD1_F]
-~g~Te has saltado la salida. ¡Me gusta tu estilo!
+[CRD134B]
+PSICÓPATA - HUNTER PLATIN
-[YD1_G]
-~r~Esto es una carrera DE COCHES. ¡Necesitas un COCHE, idiota!
+[CRD134C]
+MAUDE LA VENDEDORA DE HELADOS - JANE GENNARO
-[YD1GO]
-~g~¡VAMOS!
+[CRD134D]
+JETHRO - JOHN ZURHELLEN
-[YD1_1]
-~r~1
+[CRD134E]
+GONZÁLEZ - JORGE PUPO
-[YD1_2]
-~r~2
+[CRD134F]
+DWAYNE - NAVID KHONSARI
-[YD1_3]
-~r~3
+[CRD134G]
+DICK - PETER MCKAY
-[YD1_BON]
-¡1.000 $!
+[CRD134H]
+MIKE EL MATÓN & CHICO PORNO - ROBERT CIHRA
-[Y1_1ST]
-~G~¡Has quedado primero con ~1~ puntos de control!
+[CRD134I]
+PERCY - RUSSELL FOREMAN
-[Y1_2ND]
-~y~Eres el segundo con ~1~ puntos de control. ~y~¡Casi, pero no!
+[CRED135]
+CAPTURA DE MOVIMIENTOS
-[Y1_3RD]
-~r~Eres el tercero con ~1~ puntos de control. ~r~¿No decías que eras bueno?
+[CRED136]
+ANIMACIÓN DE
-[Y1_LAST]
-~r~¡Has quedado el último! ~r~¡Me has hecho perder el tiempo, IDIOTA!
+[CRD136A]
+DIRECCIÓN TÉCNICA DE ALEX HORTON
-[Y1_J1ST]
-~y~Has empatado el primero con ~1~ puntos de control. ~y~Bien, ¡pero debes ser el mejor si quieres conducir para la Reina Lizzy!
+[CRED137]
+DIRIGIDO POR
-[Y1_J2ND]
-~r~Has empatado el segundo con ~1~ puntos de control. ¡Conduces como un mono loco!
+[CRD137A]
+DIRIGIDO POR NAVID KHONSARI
-[Y1JLAST]
-~r~¡Has empatado el último! ¡Hablas como un conductor, pero conduces como un hablador!
+[CRED138]
+PRODUCIDO POR
-[Y1_TEST]
-¡COCHE AL AGUA!
+[CRD138A]
+PRODUCIDO POR JAMIE KING
-[YD2_A]
-Necesito ver si eres capaz de hacer mi trabajo sucio,
+[CRD138B]
+RENAUD SEBBANE
-[YD2_A1]
-si se puede confiar en ti.
+[CRED139]
+GRABADO EN PERSPECTIVE STUDIOS, BROOKLYN
-[YD2_B]
-Dos de mis chicos llegarán allí enseguida para llevarte de paseo,
+[CRED140]
+ACTORES DE CAPTURA DE MOVIMIENTOS
-[YD2_B1]
-a ver si eres quien dices que eres.
+[CRD140A]
+BLAYNE PERRY
-[YD2_C]
-Vamos a dar un paseíto por los cerros de Hepburn para cargarnos a los asquerosos Diablos que han estado metiéndose con la reina Lizzy.
+[CRD140B]
+JONATHON SALE
-[YD2_CC]
-Toma, necesitarás una pipa.
+[CRD140C]
+CHARLES TUCKER
-[YD2_D]
-Tú te ocupas de conducir y disparar. Nosotros nos aseguraremos de que no te eches atrás.
+[CRD140D]
+EDDIE MARRERO
-[YD2_E]
-¡Conduce!
+[CRD140E]
+WILLIAM MCCALL
-[YD2_F]
-~r~Se quiere escapar, ¡cárgatelo!
+[CRD140F]
+JORGE PUPO
-[YD2_G1]
-Los cerros de Hepburn... Vamos a matar a algunos asquerosos Diablos...
+[CRD140G]
+ROBERT JACKSON
-[YD2_G2]
-Pero recuerda, ~r~¡no salgas de este coche!
+[CRD140H]
+TARA RADCLIFFE
-[YD2_H]
-¡Vale, ya está! ¡Llévanos de vuelta a territorio jamaicano! ¡Vamos, vamos, vamos!
+[CRD140I]
+JENIFER GAMBETESE
-[YD2_L]
-¡Eres la Muerte personificada!
+[CRD140J]
+KRIS ACHEVARRIA
-[YD2_M]
-~r~¡Ha destrozado mi coche! ¡Liquídalo!
+[CRD140K]
+ALI ORDOUBADI
-[YD2_N]
-¡Vuelve al coche!
+[CRD140L]
+KAHLEEM POOLE
-[YD3_A]
-Quiero que robes coches de otras bandas
+[CRED141]
+DIÁLOGOS DE LOS PEATONES
-[YD3_A1]
-para que podamos atacar sus territorios.
+[CRD141A]
+ESCRITOS POR DAN HOUSER, MARC FERNÁNDEZ, GILLIAN TELLING Y NAVID KHONSARI
-[YD3_B]
-Necesito un Mafia Sentinel,
+[CRD141B]
+CON LA AYUDA DE JEREMY POPE, LANCE WILLIAMS, Y JENNY JEMISON
-[YD3_B1]
-un Yakuza Stinger y un
+[CRED142]
+ESCRITO POR
-[YD3_B2]
-Diablo Stallion para que podamos ir a por cualquier banda de Liberty.
+[CRD142A]
+DAN HOUSER Y JAMES WORRALL
-[YD3_C]
-Déjalos en el garaje de Newport y recuerda,
+[CRED143]
+DIRIGIDO POR DAN HOUSER, CRAIG CONNER, MARC FERNÁNDEZ, Y ALLAN WALKER
-[YD3_C1]
-¡dañados no nos sirven de nada!
+[CRED144]
+PRODUCIDO POR RENAUD SEBANNE
-[YD3_D]
-UNUSED
+[CRED145]
+PEATONES
-[YD3_E]
-~r~¡Ya has entregado un coche de los Diablos!
+[CRED146]
+ADAM DAVIDSON, ADAM WATKINS, ALEJANDRO K. BROWN, ALEX ANTHONY SIOUKAS, ALEX GARCÍA,
-[YD3_F]
-~r~¡Ya has entregado un coche de la mafia!
+[CRED147]
+ALICE SALTZMAN, ALISON CIHRA, AMY SALIMA, AMY SALZMAN, ANDREA VIDELA, ANTHONY ATTI,
-[YD3_G]
-~r~¡Ya has entregado un coche de la yakuza!
+[CRED148]
+ANTHONY RIVERA, BIJAN SHAMS, BLAYNE PERRY, BRETT BISOGNO, BREYE MATA, BRIAN PANEN,
-[YD3_H]
-~g~¡Coche de los Diablos entregado!
+[CRED149]
+BROCK VODER, CAREY BERTINI, CHARISSE LAMBERT, CHRIS DIFAT, CHRIS REISENBERGER,
-[YD3_I]
-~g~¡Coche de la mafia entregado!
+[CRED150]
+CHRISTOPHER BRODAY, CHRISTOPHER CARRO, CYNTHIA GREENE, DAMARIES LÓPEZ, DAN LEE,
-[YD3_J]
-~g~¡Coche de la yakuza entregado!
+[CRED151]
+DAN SCHNEIDER, DAN TOYAMA, DAVID DEAN CHALTFIELD, JR., DAVID HARRISON, DAVID WILEY,
-[YD3_K]
-~r~¡El coche está casi destrozado! ¡Haz que lo reparen!
+[CRED152]
+DEBORAH COLLINS, DEBRANDA CHANEY-GILES, DEMETRA KOUKOULAS, DENISE ROSADO,
-[YD3_L]
-~g~¡Llévalo al ~p~garaje~g~!
+[CRED153]
+DEVIN BENNETT, DEVIN WINTERBOTTOM, DORIS WOO, DOUGLAS HARRISON, DUNCAN COUTTS,
-[YD3_M]
-~r~¡Has volcado el vehículo! ¡Consigue otro!
+[CRED154]
+DUPE AJAYI, EDWIN AVELLANEDA, ELIZABETH HOWELL, ELIZABETH SATTERWHITE, ERIC NAGLE,
-[YD4_A]
-¡Escucha!
+[CRED155]
+ESTEBAN KARPLUS, F. FONT, FUTABA HAYASHI, GENE HILGREEN, GERALD COSGROVE,
-[YD4_A1]
-Mueve el culo a Bedford Point.
+[CRED156]
+GERARD LUNA, GILLIAN TELLING, GREGG CARLUCCI, GREGORY CLERVOIX, GREGORY SCHWEIZER,
-[YD4_A2]
-¡Hay un cargamento en una tartana que necesito pronto!
+[CRED157]
+HADLEY TOMICKI, J. ROSSETT, JAMEEL VEGA, JASON JONES, JEFF ROSA, JENNIFER JEMISON,
-[YD4_B]
-CARTA: Dicen que estuviste entretenido. Igual que yo.
+[CRED158]
+JEREMY TAGGERT, JESSICA RIDER, JOSEPH GREENE,JOSEPH HOWELL, KATE DUKICH,
-[YD4_C]
-¡Es hora de que seas testigo del verdadero poder del SPANK! Con mucho amor, Catalina.
+[CRED159]
+KEL O'NEILL, KEVIN HOPKINS, LADAWN JAMES, LANCE WILLIAMS, LAURA BUBBLES,
-[YD4_D]
-P.D. ¡MUERE, BASURA, MUERE!
+[CRED160]
+LAURA PATTERSON, LEE CUMMINGS, LETICIA L. YOUNG, LINDSAY KENNEDY, LISA ORITZ,
-[YD4_1]
-~g~¡Son psicópatas adictos al SPANK!
+[CRED161]
+LORNA JORDAN, LUCIO AMADIO, MARCO FERNÁNDEZ, MARIKO TANAKA, MARLON MATTHEWS,
-[YD4_2]
-~g~¡Destruye las furgonetas de SPANK!
+[CRED162]
+MARY TELLING, MASAYOSHI MITSUYAMA, MATTHEW CHUNG, MAX ALLSTADT, MAX BOGDANOV,
-[HM_1]
-'PASADA AMETRALLADA'
+[CRED163]
+MELISSA ÁLVAREZ, MICHAEL MAY, MICHAEL ROTHSTEIN, MIGUEL VIDAL, MIKE FEDERLINE,
-[HM_2]
-'BOMBINATOR'
+[CRED164]
+NATALIE DESCALZO, N'GAI MEMBERS, NICOLAS MALLO, NOELLE SADLER, NORBERT MORIVAN,
-[HM_3]
-'PREPARADO PARA ESTALLAR'
+[CRED165]
+OSWALD GREENE, JR., PETER MCKAY, PETER APPEL, PRESTON SAVARESE, RAFAEL GONZÁLEZ,
-[HM_5]
-'ENFRENTAMIENTO'
+[CRED166]
+RANDY JOHNSON, REY CONCEPCIÓN, RICHARD KROGER, ROB TIBBS, ROBERT JACKSON,
-[HOOD1_A]
-Ve al teléfono público de Wichita Gardens y hablaremos de negocios.
+[CRED167]
+ROBERT SCHULER, ROSS A. MCINTYRE, RUSSELL FOREMAN, RUTH NÚÑEZ, SALVADORE SUAZO,
-[HM1_A]
-¡Ey! ¡Soy D-Ice, de los Red Jacks!
+[CRED168]
+SAM WHITE, SANTOS GONZÁLEZ, SCOTT SMITH, SEYMOUR FRAILMAN, SPELMAN BRAUMAN,
-[HM1_C]
-Hay unos macarrillas en la calle que no piensan más que en pistolas y en SPANK.
+[CRED169]
+STEPHANIE TELLING, STEVE KNEZEVICH, STEVE ROBERT, SUMIKO YASUDA, SUSAN LEWIS,
-[HM1_3]
-~g~Los Nines tienen su territorio en Wichita Gardens.
+[CRED170]
+SYLVIA COLACIOS, TOMOKO MIYAZAKI, TRON, VERDEL HALE, YVES MONDESIR, ZENO LEINFELDER,
-[HM2_3]
-¡Si golpeas las ruedas de un vehículo, el coche teledirigido estallará!
+[CRED171]
+DAVID BEDDOES, CHRISTINE CHALMERS, BARRY CLARK, NEIL CORBETT, KIM GURNEY, NEIL MEIKLE,
-[HM2_4]
-¡Si el coche teledirigido sale fuera de cobertura, estallará solo!
+[CRED172]
+CASSIE OLIVER, LORRAINE ROY, DAVID WATSON, KEVIN WONG, WILL MORTON
-[HM2_5]
-~r~¡Te has ido de cobertura!
+[CRED175]
+ADAM DAVIDSON
-[HM3_1]
-~g~¡Ve al garaje, pero pon atención, porque el coche explotará si se daña demasiado!
+[CRED176]
+LANCE WILLIAMS
-[HM3_2]
-~g~Lleva el coche de vuelta. ¡Tiene que estar inmaculado!
+[CRED177]
+NEIL MCCAFFREY
-[HM3_3]
-~g~¡Haz que reparen el vehículo!
+[CRED178]
+LAURA PATERSON
-[HM4_D]
-~g~¡Hazte con un vehículo!
+[CRED179]
+REY CONCEPCIÓN
-[HM4_1]
-~g~Dirígete al lugar donde está el cargamento. Necesitas conseguir 30 lingotes.
+[CRED180]
+CHARLES HEROLD
-[HM4_2]
-~g~Recuerda: cuando el vehículo esté pesado y vaya más despacio, ve al garaje y deja el cargamento.
+[CRED181]
+ANDREW GREENWALD
-[HM5_3]
-~r~¡Te han dicho que uses sólo un bate de béisbol!
+[CRED182]
+JAMES MIELKE
-[HM5_4]
-~r~¡Tu contacto está muerto!
+[CRED183]
+PETER SUCIU
-[MEA1]
-'EL CRIMINAL'
+[CRED184]
+ALEX ODULIO
-[MEA2]
-'LOS LADRONES'
+[CRED185]
+DON NKRUMAH
-[MEA3]
-'LA MUJER'
+[CRED186]
+KENDALL PITTMAN
-[MEA4]
-'SU AMANTE'
+[CRED187]
+SAL SUAZO
-[MEAT1_A]
-Un amigo dijo que tú podías arreglar algunos problemas que tengo. Ve al teléfono público de Trenton si crees que puedes ayudar.
+[CRED188]
+EREK MATEO
-[MEA1_B3]
-~g~Reúnete con el director del banco.
+[CRED189]
+CHRIS DIFATE
-[MEA1_B6]
-~g~Lleva el coche a la trituradora para eliminar las pruebas, allí sal del coche y la grúa lo recogerá.
+[CRED190]
+LEILA MILTON
-[MEA1_1]
-~r~¡El director del banco está muerto!
+[CRED191]
+DARREN ZOLTOWSKI
-[MEA1_2]
-~r~¡Te dijeron que trituraras el coche!
+[CRED192]
+VIRGINIA SMITH
-[MEA1_3]
-~g~¡Sal del coche!
+[CRED193]
+KEVIN CASSIN
-[MEA1_4]
-~r~¡Has abandonado al director del banco!
+[CRED194]
+JASON SHIGEMORI
-[MEA2_B3]
-~g~Reúnete con los ladrones.
+[CRED195]
+KELLY KINSELLA
-[MEA2_B4]
-~g~Llévalos a la fábrica de comestibles Bitch'n' Dog.
+[CRED196]
+MOLLIE STICKNEY
-[MEA2_B6]
-~g~Haz que repinten el coche para borrar las pruebas.
+[CRED197]
+STANTON SARJEANT
-[MEA2_1]
-~r~¡Te dijeron que trituraras el vehículo!
+[CRED198]
+LAURA WALSH
-[MEA2_2]
-~r~¡Un ladrón ha muerto!
+[CRED199]
+MARK GARONE
-[MEA2_4]
-~r~¡Has abandonado a un ladrón!
+[CRED200]
+JOANNA SLY
-[MEA3_B3]
-~g~Recoge a la Sra. Chonks.
+[CRED201]
+ELIZABETH HOWELL
-[MEA3_B6]
-~g~Llévate el coche y tíralo al mar para eliminar las pruebas.
+[CRED202]
+ANA HÉRCULES
-[MEA3_1]
-~r~¡La mujer ha muerto!
+[CRED203]
+SHIRLEY IRICK
-[MEA3_2]
-~r~¡Se suponía que debías tirar el coche al agua!
+[CRED204]
+KASHONA FIELDS
-[MEA3_3]
-~r~¡Has abandonado a su mujer!
+[CRED205]
+JOEL M. LILJE
-[MEA4_B3]
-~g~Recoge al amante de su mujer.
+[CRED206]
+JOHN DIBENEDETTO
-[MEA4_B6]
-Ya es muy tarde, Marty. Tuviste tu oportunidad, pero ahora yo me ocuparé de tu negocio...
+[CRED207]
+NANCY GILES
-[MEA4_1]
-~r~¡Carlos está muerto!
+[CRED208]
+RYAN CROY
-[MEA4_3]
-~r~¡Has abandonado a Carlos, el usurero!
+[CRED209]
+JENNIFER KOLBE
-[LOOK_A]
-Mantén pulsado ~h~~k~~VEHICLE_LOOKLEFT~~w~ o ~h~~k~~VEHICLE_LOOKRIGHT~~w~ para mirar~h~ a la izquierda~w~ o ~h~a la derecha ~w~estando dentro de un vehículo. Pulsa ambos para mirar~h~ atrás~w~.
+[CRED210]
+LIAM BURKE
-[LOVE6_1]
-~g~¡Ahora aleja a los policías del almacén!
+[CRED211]
+SIGRID PREISSL
-[LOVE6_2]
-~r~¡No has distraído a la policía!
+[CRED212]
+ANITA FITZSIMONS
-[RM4_3]
-~r~¡El socio de Ray ha escapado!
+[CRED213]
+PHILIPPA RASELLI
-[RM6_C]
-La CIA parece tener intereses con el SPANK
+[CRED214]
+WIL QUESNEL
-[RM6_C1]
-y no les gusta que incordiemos al cártel.
+[CRED215]
+FALKO BURKERT
-[C_PASS]
-¡AMENAZA ELIMINADA!
+[CRED216]
+SARA SEWELL
-[CTUTOR]
-Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misiones de justiciero.
+[CRED217]
+EMISORAS DE RADIO Y MÚSICA
-[CTUTOR2]
-Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misiones de justiciero.
+[CRED218]
+ASESOR MUSICAL
-[COPCART]
-~g~Tienes ~1~ segundos para volver a un vehículo de la policía antes de que termine la misión.
+[CRD218A]
+HEINZ HENN
-[C_FAIL]
-¡Misión de justiciero terminada!
+[CRD218B]
+STUART ROSS
-[C_CANC]
-~r~¡Misión de justiciero cancelada!
+[CRED219]
+COORDINADOR DE LA BANDA SONORA
-[C_ESCP]
-~r~¡El sospechoso ha escapado!
+[CRED220]
+TERRY DONOVAN
-[C_TIME]
-~r~¡Tu trabajo como defensor de la ley ha terminado!
+[CRED221]
+PRODUCTOR DE ROCKSTAR GAMES
-[C_VIGIL]
-¡PREMIO POR JUSTICIERO!
+[CRED222]
+DAN HOUSER Y LAZLOW
-[A_FAIL2]
-~r~¡Tu falta de rapidez ha sido fatal para el paciente!
+[CRED223]
+PRODUCTOR DE ROCKSTAR NORTH
-[A_FAIL3]
-~r~¡Tu paciente ha muerto!
+[CRED224]
+CRAIG CONNER
-[A_PASS]
-¡Paciente a salvo!
+[CRED225]
+ALLAN WALKER
-[F_FAIL2]
-~r~¡Llegas demasiado tarde!
+[CRED226]
+LAZLOW
-[A_COMP2]
-¡Nunca te cansarás!
+[CRED227]
+DJ BANTER E IMÁGENES
-[RM2_M]
-Si necesitas armas nuevas, pasa por aquí y coge lo que necesites de las taquillas.
+[CRED228]
+ESCRITO POR DAN HOUSER Y LAZLOW
-[HEAL_A]
-Tu ~h~salud ~w~está indicada en naranja en la parte superior derecha de la pantalla.
+[CRED229]
+FLASH FM
-[YD1_CNT]
-¡~1~ de 15!
+[CRD229A]
+TONI-MARIA CHAMBERS
-[FM1_9]
-~g~La fiesta es allí. Deja a María enfrente.
+[CRD229B]
+VOCES FICTICIAS Y PRODUCCIÓN-JEFF BERLIN
-[FM1_Y]
-Quiero que sepas que me lo he pasado muy bien por primera vez en mucho tiempo y que me has tratado muy bien, con respeto.
+[CRED230]
+GRACIAS ESPECIALES A
-[FM1_AA]
-Bueno, será mejor que me vaya. Espero que nos veamos pronto.
+[CRED231]
+TOMMY MOTTOLA,
-[NOCONTE]
-Vuelve a conectar un mando analógico (DUALSHOCK#) o mando analógico (DUALSHOCK#2) en el puerto de mando 1 para continuar.
+[CRED232]
+MICHELLE ANTHONY,
-[WRCONT]
-El mando conectado al puerto de mando 1 es un mando no compatible. Grand Theft Auto III necesita un mando analógico (DUALSHOCK#) o mando analógico (DUALSHOCK#2).
+[CRED233]
+STEVE BARNETT,
-[WRCONTE]
-El mando conectado al puerto de mando 1 es un mando no compatible. Grand Theft Auto III necesita un mando analógico (DUALSHOCK#) o mando analógico (DUALSHOCK#2).
+[CRED234]
+CHUCK FLECKENSTEIN,
-[WRONGCD]
-Disco incorrecto. Introduce el disco correcto.
+[CRED235]
+RITA LIBERATOR
-[NOCD]
-La bandeja del disco está vacía. Introduce un disco.
+[CRED236]
+MARTIN & CLAIRE LOGAN
-[OPENCD]
-La bandeja del disco está abierta. Cierra la bandeja de disco.
+[CRED237]
+SANDRA HUTTON
-[CDERROR]
-Error al leer el DVD de Grand Theft Auto III
+[CRED238]
+CHRISTINE DAVIDSON
-[RESTART]
-Empezando una nueva partida
+[CRED239]
+ALAN, RED & BIGFOOT
-[GA_3]
-¡Ya no es gratis! ¡La mano de pintura son 1.000 dólares!
+[CRED240]
+LE T
-[GA_1]
-¡Hala! ¡Demasiado peligroso para mi gusto!
+[CRED241]
+COLIN DONALD
-[GA_1A]
-Vuelve cuando no estés tan ocupado...
+[CRED242]
+KERRY STALLWOOD
-[S_PROM2]
-Puedes alojar un vehículo en el garaje de al lado al guardar tu partida.
+[CRED243]
+ALAN MCGREGOR
-[STOCK]
-Mercancía agotada
+[CRED244]
+CHRIS MORTON
-[FM1_O]
-Creo que está en la estación de ferrocarril del muelle de Chinatown.
+[CRED245]
+EMIL BUSSE
-[EBAL_B]
-Es aquí, ¡entremos y cambiémonos de ropa!
+[CRED246]
+EMILY BAILLIE
-[EBAL_G]
-Éste es el club de Luigi. Vamos a la parte de atrás, a la puerta de servicio.
+[CRED247]
+KEVIN ARCHIBALD
-[AM4_3]
-¡Tú debes de ser el nuevo recadero de Asuka!
+[CRED248]
+MORAG KERR
-[AM4_4]
-¿Tienes el dinero? ¿Está todo?
+[CRED249]
+CATH WALKER
-[AM4_5]
-Sé lo que estás pensando: ''otro poli corrupto''.
+[CRED250]
+ISO BAR
-[AM4_6]
-Pues éste es un mundo corrupto.
+[CRED251]
+WATERLINE
-[AM4_7]
-He perdido a un par de socios y esos papanatas de Asuntos Internos ya se han puesto a husmear.
+[CRED252]
+NEWS CAFE
-[AM4_8]
-¡Y seguro que les llega mi olor!
+[CRD251A]
+THE POND
-[AM4_9]
-¡Pues esta ciudad es una gran alcantarilla!
+[CRD252A]
+PIVO
-[AM4_10]
-Pero voy a necesitar un ayudita ajena al cuerpo.
+[CRED253]
+BUDGET VIDEO RENTALS
-[AM4_11]
-Si estás interesado, ya sabes dónde encontrarme.
+[CRED254]
+LORNA'S SCOOTER
-[CAM_A]
-Pulsa ~h~~k~~CAMERA_CHANGE_VIEW_ALL_SITUATIONS~~w~ para cambiar la ~h~cámara ~w~cuando vayas a pie o estés en un vehículo.
+[CRED255]
+GARETH MURFIN
-[CAM_B]
-Pulsa el ~h~botón de dirección hacia arriba ~w~y ~h~abajo~w~ para cambiar la ~h~cámara ~w~cuando vayas a pie o estés en un vehículo.
+[CRED256]
+ARTE ADICIONAL
-[KM2_1]
-~g~Repara el coche, tiene que estar en perfecto estado.
+[CRED257]
+TONY PORTER
-[LM3_6]
-¡Joey...!
+[CRED258]
+CRAIG MOORE
-[LM3_6A]
-¿Voy a jugar con tu paquetín otra vez?
+[CRED259]
+ANIMACIÓN DE SINCRONIZACIÓN LABIAL DE LAS SECUENCIAS
-[LM3_9A]
-que tendré trabajo para ti.
+[CRED260]
+COSGROVE HALL FILMS
-[LM3_9B]
-¿De acuerdo?
+[CRED261]
+PRODUCTOR - OWEN BALLHATCHET
-[AWAY2]
-~r~Se ha escapado.
+[CRED262]
+ANIMADOR SENIOR - JON TURNER
-[AWAY]
-~r~¡Se ha pirado!
+[CRED263]
+ANIMADORES - RICHARD DRUMM
-[JM6_1]
-Llévanos al banco de la avenida principal.
+[CRED264]
+DAVE BROWN
-[GA_6B] { re3 change }
-¡Apárcalo, actívala pulsando ~h~~k~~VEHICLE_FIREWEAPON~~w~ y SAL PITANDO!
+[CRED265]
+MAIR THOMAS
-[GA_7B] { re3 change }
-Activa la bomba pulsando ~h~~k~~VEHICLE_FIREWEAPON~~w~. Estallará cuando se arranque el motor.
+[CRED266]
+PRASHANT PATEL
-[BAT1]
-~g~¡Coge el bate!
+[CRED267]
+ASESOR TECNOLOGÍA DE AUDIO
-[EBAL_O]
-Si no la cagas, puede que haya más trabajo para ti. ¡Ahora largo!
+[CRED268]
+RIK EDE PARA GAMESOUND LTD.
-[HELP9_B]
-Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para ~h~disparar ~w~el fusil de francotirador.
+[CRED269]
+SOPORTE DTS INTEGRATION
-[HELP9_C]
-Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para ~h~disparar ~w~el fusil de francotirador.
+[CRED270]
+TED LAVERTY DE DTS
-[JM6_8]
-~r~¡Has perdido a todos los ladrones!
+[CRED271]
+CHRIS GREER DE DTS
-[COLT_IN]
-¡La pistola ya está disponible en la tienda Ammu-Nation!
+[CRED272]
+JASON PAGE DE SCEE
-[TAXI2]
-~r~¡Se te acabó el tiempo!
+[CRED273]
+INVESTIGACIÓN Y ANÁLISIS
-[TAXI3]
-~r~¡Tu cliente ha salido por patas!
+[CRED274]
+VROCK
-[TAXI7]
-~r~Tu coche está destrozado, repáralo.
+[CRED275]
+DJ: LAZLOW COMO ÉL MISMO
-[TAXI4]
-¡Carrera terminada!
+[CRED276]
+VOZ-JOE KELLY
-[TAXI5]
-¡VIAJE RÁPIDO!
+[CRED277]
+PRODUCCIÓN-JONATHAN HANST
-[TAXI6]
-Misión de taxista cancelada
+[CRED278]
+WAVE 103
-[FRANGO]
-~g~¡Salvatore quiere que ayudes primero a Toni a ocuparse de las Tríadas!
+[CRED279]
+DJ: ADAM FIRST-JAMIE CANFIELD
-[PAGEB12]
-Soborno policial entregado en tu guarida.
+[CRED280]
+VOZ-JEN SWEENEY
-[PAGEB13]
-Salud entregada en tu guarida.
+[CRED281]
+PRODUCCIÓN-JONATHAN HANST
-[PAGEB14]
-Adrenalina entregada en tu guarida.
+[CRED282]
+FEVER 105
-[KM1_4]
-~g~¡Necesitas un coche de policía para hacer el trabajo!
+[CRED283]
+DJ: OLIVER 'LADYKILLER' BISCUIT-JULIUS DYSON
-[CAT1_B]
-lleva 500.000 dólares a la mansión de Cedar Grove.
+[CRED284]
+VOZ MASCULINA-ED MCMANN
-[JM2_C]
-Tiene un puesto de fideos en Chinatown.
+[CRED285]
+VOZ FEMENINA-SHAWNEE SMITH
-[RM6_1]
-Esta llave es de un almacén.
+[CRED286]
+PRODUCCIÓN- LISTEN KITCHEN
-[RM6_2]
-Encontrarás dinero en metálico y ''suministros'' que guardé por si las cosas se ponían feas.
+[CRED287]
+EMOTION 98.3
-[RM6_3]
-Hasta la vista.
+[CRED288]
+DJ: FERNANDO- FRANK CHAVEZ
-[FE_INIP]
-Iniciando y cargando el menú de pausa... Espera, por favor.
+[CRED289]
+VOZ-JEN SWEENEY
-[FESZ_CA]
-Cancelar
+[CRED290]
+PRODUCCIÓN-JONATHAN HANST
-[FESZ_QU]
-Abandonar
+[CRED291]
+RADIO ESPANTOSO
-[FESZ_L1]
-¡La partida se ha guardado!
+[CRED292]
+DJ: PEPE-TONY CHILRODES
-[FESZ_L2]
-El nombre guardado es:
+[CRED293]
+WILDSTYLE
-[FESZ_OK]
-ACEPTAR
+[CRED294]
+DJ: MISTER MAGIC AS HIMSELF
-[FES_NGA]
-Nueva partida
+[CRED295]
+VOZ-FRANK SILVESTRO
-[FES_CAN]
-Cancelar
+[CRED296]
+PRODUCCIÓN-LAZLOW
-[FESZ_QL]
-Perderás todo el progreso en tu partida actual. ¿Quieres continuar con la carga?
+[CRED297]
+KCHAT
-[FESZ_QD]
-¿Quieres borrar esta partida guardada?
+[CRED298]
+ESCRITO POR DAN HOUSER Y LAZLOW
-[FESZ_QO]
-¿Quieres sobreescribir esta partida guardada?
+[CRED299]
+PRODUCIDO Y EDITADO POR LAZLOW
-[FESZ_QR]
-¿Seguro que quieres empezar una nueva partida? Perderás todo el progreso desde la última partida guardada.
+[CRED300]
+DJ AMY SHECKENHAUSEN -LEYNA WEBER
-[FESZ_QS]
-¿QUIERES GUARDAR?
+[CRED301]
+JEZ TORRENT-KEVIN MCKIDD
-[SLONFP]
-Puerto 1. Archivo protegido.
+[CRED302]
+MANDY -COLLEEN CORBETT
-[T4X4_1]
-'PATIO DE RECREO DEL PATRIOT'
+[CRED303]
+MICHELLE CARAPADIS-MARY BIRDSONG
-[T4X4_2]
-'UN PASEO POR EL PARQUE'
+[CRED304]
+MR.ZOO-CARL DOWLING
-[T4X4_3]
-'¡AGARRADO!'
+[CRED305]
+GETHSEMANEE-LYNN LIPTON
-[MM_1]
-'CAOS EN EL APARCAMIENTO'
+[CRED306]
+CLAUDE MAGINOT-JOHN MAUCERI
-[T4X4_1A]
-~g~Tienes ~y~5 minutos~g~ para pasar por ~y~15~g~ puntos de control. ~g~Puedes atravesarlos en ~y~CUALQUIER ORDEN.
+[CRED307]
+BJ SMITH-LAWRENCE TAYLOR
-[T4X4_1B]
-¡~1~ de 15!
+[CRED308]
+THOR-FRANK FAVA
-[T4X4_1C]
-~y~ATRAVIESA~g~ el primer punto de control para poner en marcha el cronómetro. ~g~Cada punto de control te dará ~y~20 SEGUNDOS~g~ adicionales.
+[CRED309]
+PERSONAS LLAMANDO A LA RADIO
-[T4X4_2A]
-~g~¡Tienes ~y~2 minutos~g~ para pasar por ~y~12~g~ puntos de control! ~g~Puedes atravesarlos en ~y~CUALQUIER ORDEN.
+[CRED310]
+COUZIN ED, JOSH CLARK, JASON BUHRMESTER, JUAN ALLER, WAYNE OLIVER, SUSAN LEWIS, GILLIAN TELLING, TOM MURRAY, MIKE FERRANTE SR., EMMANUEL GOLDSTEIN, DAN HOUSER, NICK MANDELOS, GERRY COSGROVE, MIKE PALERMO, PORKCHOP, KEITH BROADAS
-[T4X4_2B]
-¡~1~ de 12!
+[CRED311]
+LEWIS, GILLIAN TELLING, TOM MURRAY, MIKE FERRANTE SR., EMMANUEL GOLDSTEIN,
-[T4X4_2C]
-~y~ATRAVIESA~g~ el primer punto de control para poner en marcha el cronómetro. ~g~Cada punto de control te dará ~y~10 SEGUNDOS~g~ adicionales.
+[CRED312]
+DAN HOUSER, NICK MANDELOS, GERRY COSGROVE, MIKE PALERMO, PORKCHOP,
-[T4X4_3A]
-~g~Tienes ~y~5 minutos~g~ para pasar por ~y~20~g~ puntos de control. ~g~Puedes atravesarlos en ~y~CUALQUIER ORDEN.
+[CRED313]
+KEITH BROADAS
-[T4X4_3B]
-~y~ATRAVIESA~g~ el primer punto de control para poner en marcha el cronómetro. ~g~Cada punto de control te dará ~y~15 SEGUNDOS~g~ adicionales.
+[CRED314]
+VCPR
-[T4X4_3C]
-¡~1~ de 20!
+[CRED315]
+ESCRITO POR DAN HOUSER Y LAZLOW
-[T4X4_F]
-~r~¡Te has escapado! ¿Demasiado difícil para ti?
+[CRED316]
+PRODUCIDO POR LAZLOW
-[MM_1_A]
-~g~¡Tienes ~y~2 minutos~g~ para pasar por ~y~20 puntos de control~g~ en el aparcamiento! ~g~Puedes atravesarlos en ~y~CUALQUIER ORDEN.
+[CRED317]
+MAURICE CHAVEZ-PHILLIP ANTHONY RODRIGUEZ
-[MM_1_B]
-¡~1~ de 20!
+[CRED318]
+JONATHAN FREELOADER- PATRICK OLSEN
-[MM_1_C]
-~g~Tendrás 20 segundos, más ~y~5 SEGUNDOS~g~ por cada punto de control. ~g~El cronómetro comenzará ~y~INMEDIATAMENTE.
+[CRED319]
+MICHELLE MONTANIUS-KELLY GUEST
-[FM2_14]
-~r~¡Te acercaste demasiado y asustaste a Curly!
+[CRED320]
+REP. ALEX SHRUB- CHRIS LUCAS
-[FM2_15]
-~g~No te acerques mucho, ¡o Curly sospechará!
+[CRED321]
+CALLUM CRAYSHAW- SEAN MODICA
-[UPSIDE]
-~r~¡Has volcado!
+[CRED322]
+JOHN F. HICKORY- LJ GANSEN
-[FM2_16]
-ASUSTÓMETRO:
+[CRED323]
+PASTOR RICHARDS- DAVID GREEN
-[LM3_11]
-~g~Misty no irá en un autobús, ¡hazte con otro vehículo!
+[CRED324]
+JAN BROWN- MAUREEN SILLIMAN
-[LANDSTK]
-Landstalker
+[CRED325]
+BARRY STARK- RENAUD SEBBANE
-[IDAHO]
-Idaho
+[CRED326]
+JENNY LOUISE CRAB- MARY BIRDSONG
-[STINGER]
-Stinger
+[CRED327]
+KONSTANTINOS SMITH- KONSTANTINOS.COM
-[LINERUN]
-Linerunner
+[CRED328]
+JEREMY ROBARD-PETER SILVESTRO
-[PEREN]
-Perennial
+[CRED329]
+ANUNCIOS DE RADIO
-[SENTINL]
-Sentinel
+[CRED330]
+ESCRITOS POR DAN HOUSER Y LAZLOW
-[PATRIOT]
-Patriot
+[CRED331]
+PRODUCIDOS POR LAZLOW
-[FIRETRK]
-Camión de bomberos
+[CRED332]
+JINGLES ADICIONALES PRODUCIDOS POR CRAIG CONNER
-[TRASHM]
-Trashmaster
+[CRED333]
+VOCES EN LOS ANUNCIOS:
-[STRETCH]
-Stretch
+[CRED334]
+ADAM DAVIDSON, ALEX ANTHONY, ALICE SALTZMAN, AMY SALZMAN, KATE DUKICH,
-[MANANA]
-Mañana
+[CRED335]
+ARAN RONICLE, BARB JONES, BEN KRECH, BRIAN THOMAS, BROCK YODER, CHRIS
-[INFERNS]
-Infernus
+[CRED336]
+FERRANTE, CRAIG CONNER, DAVE RYAN, DAVID GREEN, DORIS WOO, DOUGLAS
-[BLISTA]
-Blista
+[CRED337]
+HARRISON, ED MCMANN, FRANK CHÁVEZ, FRANK FAVA, GENE HILGREEN, GREG
-[PONY]
-Pony
+[CRED338]
+SCHWEIZER, HUNTER PLATIN, JAMES FERRANTE, JEFF BERLIN, JEFF ROSA, JOE KELLY,
-[MULE]
-Mule
+[CRED339]
+JOHN MAUCERI, JOSH CLARK, JULIE WEMYSS, KEVIN STRALEY, KIM GURNEY, LANCE
-[CHEETAH]
-Cheetah
+[CRED340]
+WILLIAMS, LAURA PATERSON, LAZLOW, LISA ORTIZ, LORNA JORDAN, LUCIEN JONES,
-[AMBULAN]
-Ambulancia
+[CRED341]
+MAUREEN SILLIMAN, MIKE FERRANTE JR., PETE GUSTIN, PETER SILVESTRO, RAFF
-[FBICAR]
-Coche del FBI
+[CRED342]
+CROLLA, RANDY JOHNSON, RICHARD KRUGER, RON REEVE, SHELLEY MILLER, SKY, TJ ALLARD
-[MOONBM]
-Moonbeam
+[CRD344A]
+AUDIO GRABADO EN DIGITAL ARTS STUDIOS,
-[ESPERAN]
-Esperanto
+[CRED344]
+NYC, TRACK 9 STUDIOS, NYC,
-[TAXI]
-Taxi
+[CRED345]
+WEDDINGTON MULTIMEDIA, LOS ANGELES,
-[KURUMA]
-Kuruma
+[CRD345A]
+SYNC SOUND, NYC Y RADIO LAZLOW, LONG ISLAND.
-[BOBCAT]
-Bobcat
+[CRED346]
+GRACIAS A AXEL ERICSON Y WON LEE EN DIGITAL ARTS, PAUL VÁSQUEZ EN TRACK 9 STUDIOS, JOHN BOWEN Y JOHN HASSLER EN SYNC SOUND
-[WHOOPEE]
-Mr. Whoopee
+[CRED347]
+MARK LLOYD
-[BFINJC]
-BF Injection
+[CRED348]
+TIM BATES
-[POLICAR]
-Coche patrulla
+[CRED349]
+KIT BROWN
-[ENFORCR]
-Enforcer
+[CRED350]
+ANDY MASON
-[SECURI]
-Securicar
+[CRED351]
+PHIL DEANE
-[BANSHEE]
-Banshee
+[CRED352]
+PHIL ALEXANDER
-[PREDATR]
-Predator
+[CRED353]
+MATT HEWITT
-[BUS]
-Autobús
+[CRED354]
+DENBY GRACE
-[RHINO]
-Rhino
+[CRED355]
+ANTOINE CABROL
-[BARRCKS]
-Barracks OL
+[CRED356]
+JONOTHAN STONES
-[TRAIN]
-Tren
+[CRED357]
+MIKE BLACKBURN
-[HELI]
-Helicóptero
+[CRED358]
+TIM MCGAFF
-[DODO]
-Dodo
+[CINCAM]
+Cámara cinemática
-[COACH]
-Coach
+[RC4]
+MASACRES RUMPO
-[CABBIE]
-Cabbie
+[LEGAL]
+~g~¡Elimina la amenaza criminal!
-[STALION]
-Stallion
+[GA_2]
+Nuevo motor y trabajo de pintura. ¡Los policías no te reconocerán!
-[RUMPO]
-Rumpo
+[HELP15]
+Cuando vayas a pie, pulsa ~h~~k~~PED_LOOKBEHIND~~w~ para ~h~mirar detrás~w~. Utiliza el ~h~joystick analógico derecho~w~ para ~h~mirar a tu alrededor~w~.
-[RCBANDT]
-Bandit RC
+[FEC_LB4]
+Mirar detrás (botón R3)
-[BELLYUP]
-Furgoneta de las Tríadas
+[PERPIC]
+Objetos ocultos encontrados
-[MRWONGS]
-Mr Wongs
+[CO_ONE]
+Objeto oculto ~1~ de ~1~
-[MAFIACR]
-Sentinel de la mafia
+[GA_21]
+No puedes almacenar más coches en este garaje.
-[YARDICR]
-Lobo jamaicano
+[CHEAT1]
+Truco activado
-[YAKUZCR]
-Stinger de la yakuza
+[CHEAT2]
+Truco de arma
-[DIABLCR]
-Stallion de los Diablos
+[CHEAT3]
+Truco de salud
-[COLOMCR]
-Cruiser del cártel
+[CHEAT4]
+Truco de blindaje
-[HOODSCR]
-Rumpo XL de los hood
+[CHEAT5]
+Truco de nivel de se busca
-[AEROPL]
-Avioneta
+[CHEAT6]
+Truco de dinero
-[SPEEDER]
-Speeder
+[CHEAT7]
+Truco de tiempo
-[REEFER]
-Reefer
+[USJ_ALL]
+¡TODAS LAS MANIOBRAS ÚNICAS COMPLETADAS!
+
+[JAN]
+Ene
-[PANLANT]
-Panlantic
+[FEB]
+Feb
-[FLATBED]
-Flatbed
+[MAR]
+Mar
-[YANKEE]
-Yankee
+[APR]
+Abr
-[BORGNIN]
-Borgnine
+[MAY]
+May
-[TOYZ]
-TOYZ
+[JUN]
+Jun
-[FEST_DF]
-Distancia recorrida a pie (millas)
+[JUL]
+Jul
-[FEST_DC]
-Distancia recorrida en coche (millas)
+[AUG]
+Ago
-[FESTDFM]
-Distancia recorrida a pie (metros)
+[SEP]
+Sep
-[FESTDCM]
-Distancia recorrida en coche (metros)
+[OCT]
+Oct
-[FEST_R1]
-''Patio de recreo del Patriot'' en segundos
+[NOV]
+Nov
-[FEST_R2]
-''Un paseo por el parque'' en segundos
+[DEC]
+Dic
-[FEST_R3]
-''¡Agarrado!'' en segundos
+[DEFDT]
+--:---:---- --:--:--
-[FEST_RM]
-''Caos en el aparcamiento'' en segundos
+[BONUS]
+~g~BONIFICACIÓN ~1~ $
-[FEST_LS]
-Personas salvadas con una ambulancia
+[HORN1]
+Pulsa ~h~~k~~VEHICLE_HORN~~w~para tocar el ~h~claxon.
-[FEST_CC]
-Criminales asesinados en misiones de justiciero
+[HORN2]
+Pulsa ~h~~k~~VEHICLE_HORN~~w~para tocar el ~h~claxon.
-[FEST_FE]
-Incendios extinguidos
+[HORN3]
+Pulsa ~h~~k~~VEHICLE_HORN~~w~para tocar el ~h~claxon.
-[FEST_LF]
-Vuelo más largo en Dodo
+[FEC_EXV]
+Entrar y salir de vehículo
-[FEST_BD]
-Mejor tiempo al desactivar la bomba
+[TAXI_M]
+'TAXISTA'
-[FEST_RP]
-Masacres superadas
+[COP_M]
+'JUSTICIERO'
-[FEST_MP]
-Misiones superadas
+[FIRE_M]
+'BOMBERO'
-[FEST_BB]
-''Corre a por la pasta'':
+[AMBUL_M]
+'ATS'
-[FEST_H0]
-Puntos de control alcanzados
+[HJ_IS]
+BONIFICACIÓN POR ACROBACIA: ~1~ $
-[FEST_GC]
-Coches de bandas destruidos:
+[HJ_PIS]
+BONIFICACIÓN POR ACROBACIA PERFECTA: ~1~ $
-[FEST_H1]
-Destrucción de los Diablos
+[HJ_DIS]
+BONIFICACIÓN POR ACROBACIA DOBLE: ~1~ $
-[FEST_H2]
-La masacre de la mafia
+[HJ_PDIS]
+BONIFICACIÓN POR ACROBACIA DOBLE PERFECTA: ~1~ $
-[FEST_H3]
-Calamidad en el casino
+[HJ_TIS]
+BONIFICACIÓN POR ACROBACIA TRIPLE: ~1~ $
-[FEST_H4]
-Exterminio de Rumpos
+[HJ_PTIS]
+BONIFICACIÓN POR ACROBACIA TRIPLE PERFECTA: ~1~ $
-[USJ]
-¡PREMIO POR ACROBACIA ÚNICA!
+[HJ_QIS]
+BONIFICACIÓN POR ACROBACIA CUÁDRUPLE: ~1~ $
-[SPRAY]
-Mete tu vehículo en el taller de pintura para perder tu ~h~nivel de búsqueda~w~, ~h~reparar~w~ y~h~ repintar~w~ tu vehículo. Coste: ~h~1.000 $~w~.
+[HJ_PQIS]
+BONIFICACIÓN POR ACROBACIA CUÁDRUPLE PERFECTA: ~1~ $
-[HM1_1]
-~g~Cepíllate a 20 Purple Nines en 2 minutos y 30 segundos.
+[FESZ_LS]
+Carga completada con éxito.
-[KM1_8A] { re3 change }
-Pulsa ~h~~k~~VEHICLE_FIREWEAPON~~w~ para ~h~activar la bomba~w~. Acuérdate de alejarte de ella.
+[HELI_1A]
+Prueba tus habilidades con el Sparrow, comprueba lo rápido que puedes completar el circuito.
-[KM1_8D] { re3 change }
-Pulsa ~h~~k~~VEHICLE_FIREWEAPON~~w~ para ~h~activar la bomba~w~. Acuérdate de alejarte de ella.
+[HELI_1B]
+¡Circuito completado! ~1~ $
-[KM1_12]
-~g~¡Llévalo al dojo, pero deshazte primero de la policía!
+[HELIODD]
+Trabajos esporádicos del helicóptero
-[RATNG1]
-Carterista
+[LAW]
+LAS MISIONES DEL ABOGADO
-[RATNG2]
-Abusón
+[LAW1_1]
+~g~Consigue unos trapos nuevos en la tienda de ropa de Rafael.
-[RATNG3]
-Chorizo
+[LAW4_6]
+¡Quemad la dirección!
-[RATNG4]
-Granuja
+[LAW4_7]
+¡Matad a los jefes!
-[RATNG5]
-Secuaz
+[LAW4_8]
+Luchad, luchad, luchad, luchad.
-[RATNG6]
-Conductor
+[LAW4_9]
+¡Más vacaciones, menos trabajo!
-[RATNG7]
-Guardaespaldas
+[LAW4_11]
+¡Luchad! ¡Luchad! ¡Luchad! ¡Luchad!
-[RATNG8]
-Negociador
+[LAW4_12]
+¡Viva la revolución!
-[RATNG9]
-Socio
+[GENERAL]
+LAS MISIONES DEL CORONEL
-[RATNG10]
-Sicario
+[GEN3_4]
+Tommy Vercetti. Vamos...
-[RATNG11]
-Asesino
+[GEN3_13]
+¿Cuál es tu problema, tío? ¡Sube al tejado al otro lado del patio antes de que aparezcan!
-[RATNG12]
-Mano derecha
+[GEN3_17]
+¡Mierda! ¿Intentas matarme?
-[RATNG13]
-Verdugo
+[GEN3_21]
+~g~¡Tiene el dinero de Díaz! ¡Ve tras él y recupéralo!
-[RATNG14]
-Capo
+[GEN3_24]
+~r~¡Díaz murió! ¡Has fracasado al protegerle!
-[RATNG15]
-Jefe
+[GEN3_26]
+~r~¡Le pegaste un tiro a Díaz!
-[1010]
-~r~Tu vehículo ha volcado
+[GEN3_27]
+~r~¡Disparaste a los guardaespaldas de Díaz!
-[1011]
-~r~Tu vehículo ha volcado
+[GEN3_31]
+~g~Ahora ve al punto de entrega y cuida de Díaz.
-[1012]
-~r~Tu vehículo ha volcado
+[GEN3_32]
+~g~Ve a tu posición elevada en el tejado del edificio opuesto a donde está Lance.
-[1013]
-~r~Tu vehículo ha volcado
+[COKE]
+LAS MISIONES DEL BARÓN DE LA NIEVE
-[1014]
-~r~Tu vehículo ha volcado
+[COK1_3]
+¡Espero que te caigas y te rompas el cuello!
-[JM4_10]
-Vale, chaval, llévame primero a la lavandería de Chinatown, tengo un asunto del que ocuparme.
+[COK1_6]
+Estoy cansado de estos mamones.
-[JM4_11]
-Las lavanderas no están pagando por su protección.
+[COK2_7]
+¿Veis esos marcadores chicos? ¡Probad a dar a las luces!
-[JM4_12]
-Y ojo con el coche, Joey acaba de arreglar esta chatarra.
+[COK2_10]
+Desde luego eres mejor disparando que charlando.
-[JM4_13]
-Así que ve con cuidado, ¿vale?
+[COK2_11]
+Gracias. Eres un verdadero encanto.
-[KM4_11]
-~g~¡Lleva el dinero de vuelta al casino!
+[COK2_12]
+Lo sé, Tommy.
-[FEF_BR2]
-Encuéntralo de nuevo leyendo los resúmenes de las misiones jugadas hasta la fecha.
+[COK2_18]
+¿Te gusta Kenny Loggins?
-[TRAIN_1]
-Estación Kurowski
+[COK2_19]
+Dios, ¡me encanta este disco!
-[TRAIN_2]
-Estación Rothwell
+[COK2_26]
+~r~¡Mataste a Lance!
-[TRAIN_3]
-Estación Baillie
+[COK3_1]
+¡No dispares tío!
-[SUBWAY1]
-Estación Portland
+[COK3_2]
+¿Qué hay ahí?
-[SUBWAY2]
-Estación Rockford
+[COK3_3]
+Se está llevando el barco. Gorrón.
-[SUBWAY3]
-Estación Staunton sur
+[COK3_4]
+¡Ayuda! ¡Un tipo me está robando el barco, tío!
-[SUBWAY4]
-Terminal Shoreside
+[COK4_W]
+¡Uugghh! Ése era el último.
-[MEA4_2]
-~r~¡Marty Chonks ha muerto!
+[COK4_X]
+Voy a arrancarlo
-[SPRAY1]
-Mete tu vehículo en el taller de pintura para perder tu ~h~nivel de búsqueda~w~, ~h~reparar~w~ y~h~ repintar~w~ tu vehículo. Coste: ~h~1.000 $~w~. Esta vez es gratis.
+[COK4_Y]
+Creo que tenemos algunos amigos nuevos.
-[JM4_A]
-Sí, Toni, ya está a punto. Ahora es una delicia, ¿sabes?
+[COK4_2]
+Sí.
-[JM4_5]
-Pasa más tarde y les daremos algo que lavar... ¡Su propia ropa manchada de sangre!
+[COK4_6]
+¿A dónde crees que vamos?
-[AMMU_A]
-Luigi dijo que necesitabas una pipa...
+[COK4_7]
+¿Nos hemos perdido?
-[AMMU_B]
-Joey me pidió que te armara...
+[COK4_8]
+¡Tenemos competencia!
-[AMMU_C]
-Ve a la parte de atrás. Te dejé un nueve en el patio.
+[COK4_9]
+¡Elimínales!
-[AMMU_D]
-Tengo todo lo necesario para defender tu casa.
+[COK4_9A]
+¡Es hora del baile de Lance Vance!
-[AMMU_E]
-¿También quieres una licencia?
+[COK4_10]
+¡Ya son astillas! Y comida para los peces.
-[AMMU_F]
-No necesito tu documentación, pareces de fiar.
+[COK4_11]
+¡Lo conseguimos! Esos otros barcos no son de la clase VIP.
-[DETON]
-DETONACIÓN:
+[COK4_17]
+¡Se están desesperando!
-[DRIVE_A] { re3 change }
-Ten una Uzi seleccionada cuando entres en un vehículo, luego mira a la izquierda o a la derecha y pulsa ~h~~k~~VEHICLE_FIREWEAPON~~w~ para disparar.
+[COK4_18]
+¡Mis malditos pies están mojados! ¡NOS ESTÁ ENTRANDO AGUA!
-[DRIVE_B] { re3 change }
-Ten una Uzi seleccionada cuando entres en un vehículo, luego mira a la izquierda o a la derecha y pulsa ~h~~k~~VEHICLE_FIREWEAPON~~w~ para disparar.
+[COK4_21]
+¡Subiendo el puente!
-[RECORD]
-~g~¡NUEVO RÉCORD!
+[COK4_22]
+¡Salta, está apunto de estallar!
-[NRECORD]
-~r~¡NO HAY UN NUEVO RÉCORD!
+[COK4_23]
+Buen disparo.
-[RCHELP] { re3 change }
-Pulsa ~k~~VEHICLE_FIREWEAPON~ o lleva el coche teledirigido hasta las ruedas de otro coche para detonarlo.
+[COK4_29]
+~r~¡Mataste a Lance!
-[RCHELPA] { re3 change }
-Pulsa ~k~~VEHICLE_FIREWEAPON~ o lleva el coche teledirigido hasta las ruedas de otro coche para detonarlo.
+[ASS1_6]
+¡Adelante Tommy, yo estaré bien!
-[RC_1]
-¡Tienes 2 minutos para destruir todos los coches de los Diablos que puedas!
+[ASS1_7]
+¡Comeos esto, asesinos hijos de puta!
-[RC_2]
-¡Tienes 2 minutos para destruir todos los coches de la mafia que puedas!
+[ASS1_8]
+¡Me han dado!
-[RC_3]
-¡Tienes 2 minutos para destruir todos los coches de la yakuza que puedas!
+[ASS1_9]
+¡Te tengo cubierto, Tommy!
-[RC_4]
-¡Tienes 2 minutos para destruir todos los coches de los jamaicanos que puedas!
+[ASS1_10]
+Eh, este seto es precioso.
-[RC_5]
-¡Tienes 2 minutos para destruir todos los coches de los Hood que puedas!
+[ASS1_11]
+Tommy, ¿puedo tener una habitación con vistas a la bahía?
-[RC_6]
-¡Tienes 2 minutos para destruir todos los coches del cártel que puedas!
+[ASS1_12]
+Unos techos altos muy bonitos...
-[RAMPAGE]
-¡MASACRE!
+[ASS1_3]
+¡Lance! ¡Necesito que me cubras!
-[RAMP_P]
-¡MASACRE COMPLETADA!
+[ASS1_4]
+¡Díaz debe de estar dentro!
-[RAMP_F]
-MASACRE FALLIDA
+[ASS1_5]
+¡Lance!
-[PAGE_00]
-.
+[TAXWAR]
+MISIONES DE LA GUERRA DE TAXIS
-[PAGE_01]
-¡Liquida a ~1~ Diablos en 120 segundos!
+[NOTAXI]
+~g~Necesitas un Taxi Kaufman para activar esta misión.
-[PAGE_02]
-¡Destruye ~1~ vehículos en 120 segundos!
+[TAXW1_5]
+~g~¡Necesitas estar en un taxi Kaufman!
-[PAGE_03]
-¡Mata a ~1~ mafiosos en 120 segundos!
+[TAX2_4]
+Adelante, Tommy.
-[PAGE_04]
-¡Mata a ~1~ Tríadas en 120 segundos!
+[TAX2_5]
+Dale una buena paliza.
-[PAGE_05]
-¡Mata a ~1~ Tríadas en 120 segundos!
+[TAX2_6]
+Ni siquiera tiene licencia.
-[PAGE_06]
-¡Destruye ~1~ vehículos en 120 segundos!
+[TAX2_7]
+Malditos servicios de limusina.
-[PAGE_07]
-¡Revienta ~1~ cabezas jamaicanas en 120 segundos!
+[TAXW3_1]
+~g~Ve y recoge a Mercedes.
-[PAGE_08]
-¡Quema a ~1~ yakuzas en 120 segundos!
+[RACE1]
+~g~3..2..1.. ¡VAMOS VAMOS VAMOS!
-[PAGE_09]
-¡Destruye ~1~ vehículos en 120 segundos!
+[RACE2]
+~g~3
-[PAGE_10]
-¡Destruye ~1~ vehículos en 120 segundos!
+[RACE3]
+~g~2
-[PAGE_11]
-¡Aniquila a ~1~ jamaicanos en 120 segundos!
+[RACE4]
+~g~1
-[PAGE_12]
-¡Quema a ~1~ yakuzas en 120 segundos!
+[RACE5]
+~g~¡ADELANTE!
-[PAGE_13]
-¡Vuela a ~1~ jamaicanos en 120 segundos!
+[FIRST]
+~b~1
-[PAGE_14]
-¡Fríe a ~1~ colombianos en 120 segundos!
+[SECOND]
+~b~2
-[PAGE_15]
-¡Machaca a ~1~ Hoods en 120 segundos!
+[THIRD]
+~b~3
-[PAGE_16]
-¡Destruye ~1~ vehículos en 120 segundos!
+[FOURTH]
+~b~4
-[PAGE_17]
-¡Arrolla a ~1~ colombianos con un coche en 120 segundos!
+[RACETM]
+~b~TIEMPO DE CARRERA: ~1~:~1~
-[PAGE_18]
-¡Destruye ~1~ vehículos disparando desde otro en 120 segundos!
+[RACETM2]
+~b~TIEMPO DE CARRERA: ~1~:0~1~
-[PAGE_19]
-¡Revienta ~1~ cabezas colombianas en 120 segundos!
+[RACEFA]
+~r~¡Has fracasado en ganar la carrera!
-[PAGE_20]
-¡Decapita a ~1~ Hoods en 120 segundos!
+[HOTRNG]
+HOTRING
-[JM1_A]
-Jo, me aburro, ¿cuándo me la vas a meter?
+[BLODRNG]
+BLOODRING
-[JM1_B]
-Dame un momento, cariño, que tengo un asuntillo que tratar.
+[DIRTRNG]
+DIRTRING
-[JM1_C]
-Tengo un trabajito para ti, colega.
+[TEX1_5]
+~r~¡Se escapó!
-[JM1_D]
-Los hermanos Forelli me deben dinero desde hace mucho tiempo
+[SEG3_1]
+TIEMPO:
-[JM1_E]
-y hay que enseñarles modales.
+[SEG3_2]
+~g~Ve a la camioneta que contiene el Helicótero RC y las bombas por control remoto con temporizador.
-[JM1_F]
-''Labios'' Forelli está atiborrándose en el restaurante de Saint Mark's,
+[SEG3_3]
+~g~Debes emplear el Helicótero RC para transportar 4 bombas hasta 4 objetivos en lugar del edificio.
-[JM1_G]
-así que róbale el coche y llévalo al taller de bombas de 8-Ball en Harwood.
+[SERG3_5]
+~g~Sólo puedes llevar una bomba en cada ocasión y no puedes recoger bombas colocadas con éxito.
-[JM1_H]
-Conoces a 8-Ball, ¿verdad?
+[SEG3_7]
+~g~Una vez que hayas soltado con éxito la PRIMERA bomba sobre una zona del objetivo, el cronómetro de detonación se pondrá en marcha; de modo que tendrás que soltar todas las bombas dentro de este período de tiempo.
-[JM1_I]
-En cuanto le ponga una bomba, aparca el coche donde lo encontraste.
+[SEG3_8]
+~g~Las 4 bombas deben estar colocadas en las 4 zonas objetivo para superar la misión y demoler el edificio.
-[JM1_J]
-Luego salte y disfruta del espectáculo.
+[SEG3_9]
+~g~¡Alcanzaste el objetivo! Quedan 3.
-[JM1_K]
-Pero cuidado, no va a estar comiendo toda la vida.
+[SEG3_10]
+~g~¡Alcanzaste el objetivo! Quedan 2.
-[CAT2_A1]
-¡Vamos, perra!
+[SEG3_11]
+~g~¡Alcanzaste el objetivo! ¡Sólo queda 1!
-[CAT2_A]
-La verdadera pregunta es: ¿vienes buscando a María o buscándome a mí?
+[SEG3_12]
+~r~¡Fallaste el blanco! ¡Ve a por una bomba!
-[CAT2_B]
-Tengo una noticia para ti:
+[SEG3_13]
+~g~Deja caer la bomba en una zona del objetivo.
-[CAT2_B2]
-matarte será un placer, pero salir contigo sólo fue un negocio.
+[SEG3_14]
+~r~Te quedaste sin tiempo y fracasaste en demoler el edificio.
-[CAT2_C]
-¡Eres muy pequeñito, amigo!
+[SEG3_15]
+~r~¡Tu Helicótero RC ha sido destruido! ¿Cómo vas a transportar las bombas ahora?
-[CAT2_D]
-Dame el dinero.
+[AVERY]
+MISIONES DE AVERY
-[CAT2_E]
-¡Has estado muy ocupado!
+[ASM]
+MISIONES DE ASESINO
-[CAT2_E2]
-Pero no has aprendido que yo no soy de fiar.
+[ASM_1]
+MISIÓN DE ASESINO 1
-[CAT2_E3]
-¡Mata al idiota!
+[ASM1_1]
+~g~Sr. Teal, su ayuda en la eliminación de los forasteros fue inestimablemente buena para el negocio. Tengo más trabajo para usted y más próximo a la ''intervención''. Encontrará su siguiente trabajo pegado con cinta adhesiva bajo el teléfono.
-[CAT2_J]
-¡Despega de una vez!
+[ASM1_2]
+~g~Ve a la cabina telefónica que hay frente al centro comercial de Washington.
-[HM5_1]
-Hola, Ice dijo que vendrías. Las reglas son sólo bates. Cero armas, cero coches.
+[ASM1_3]
+~g~Carl Pearson, un repartidor de pizza. No debe finalizar sus entregas.
-[HM5_5]
-Es una batalla por respeto, ¿vale?
+[ASM1_4]
+~g~Elimina al repartidor de pizza antes de que complete sus entregas.
-[HELP14]
-Para conseguir un arma, pasa sobre ella. No podrás recogerlas estando dentro de un vehículo.
+[ASM_2]
+MISIÓN DE ASESINO 2
-[CRUSH]
-Aparca en la zona señalada y sal de tu vehículo para que sea triturado.
+[ASM_3]
+MISIÓN DE ASESINO 3
-[DIAB2_B]
-Una banda de roñosos amenazó con quitarme a mi protagonista si no les pago.
+[ASM3_1]
+~g~Ve a coger el arma que el Sr. Black ha dejado para ti.
-[DIAB2_C]
-Amenazaron al hombre equivocado, amigo.
+[ASM3_2]
+~g~No te acerques demasiado al objetivo o podría verte.
-[DIAB2_D]
-Su debilidad son los helados.
+[ASM3_3]
+~g~Para un trabajo más rápido, colócate en lugares cercanos a su ubicación y evita ser visto. Esto te proporcionará una buena posición para eliminarles.
-[DIAB2_E]
-Hazte con la bomba que dejé en Harwood,
+[ASM3_4]
+~g~¡Te ha visto! ¡Mejor elimínale de cualquier modo que puedas!
-[DIAB2_F]
-secuestra la camioneta del heladero mientras hace su ronda
+[ASM3_5]
+~g~Marcus Hammond está situado cerca de los anuncios de Washington.
-[DIAB2_G]
-y engaña a esos idiotas con esa musiquita.
+[ASM3_6]
+~g~Franco Carter está situado en el DBP de Seguridad, cerca de Ocean Drive.
-[DIAB2_H]
-Se esconden en un almacén del muelle Atlantic.
+[ASM3_7]
+~g~Dick Tanner está cerca de la joyería de Vice Point.
-[DIAB3_A]
-¡Unas Tríadas insolentes robaron mi lindo carro anoche,
+[ASM3_8]
+~g~Nick Kong está colocado cerca de Washington Beach.
-[DIAB3_B]
-lo destrozaron y lo quemaron!
+[ASM3_9]
+~g~El conductor está situado en Washington.
-[DIAB3_C]
-En el baúl había algunas de mis más preciadas posesiones sobre burros...
+[ASM3_10]
+~r~Fallaste en matarles a todos.
-[DIAB3_D]
-Objetos de coleccionista irremplazables, amigo.
+[ASM_4]
+MISIÓN DE ASESINO 4
-[DIAB3_E]
-Escondí un arma caliente en el borde de Chinatown.
+[ASM4_1]
+~g~Ve a por el rifle que te han dejado entre el follaje que hay en las cercanías de la terminal del aeropuerto.
-[DIAB3_F]
-Tómala y enseña a esos vándalos de las Tríadas a tenerle miedo a la ira pijuda de El Burro.
+[ASM4_2]
+~g~No falles tu blanco o podrías alertar a sus guardaespaldas, y recuerda mantener las distancias para que no te detecte.
-[DIAB3_1]
-MATA A 25 TRÍADAS
+[ASM4_3]
+~g~Vigila a la mujer de la galería que hay sobre los mostradores de facturación, dentro de la terminal del aeropuerto. PERO NO LA MATES.
-[DIAB4_A]
-¡Un ladrón oportunista robó una camioneta con mi última publicación!
+[ASM4_4]
+~g~Mata al hombre al que ella dé el maletín, pero sólo DESPUÉS DE QUE ÉSTE LO RECOJA. Entonces recupera el maletín y llévalo a Ammu-Nation en el centro de la ciudad.
-[DIAB4_B]
-Pero ese idiota drogado de SPANK dejó las puertas de atrás abiertas,
+[ASM4_5]
+~g~¡Consigue el maletín!
-[DIAB4_C]
-¡y ahora mi literatura para adultos
+[ASM4_6]
+~g~Lleva al maletín a Ammu-Nation en el centro de la ciudad.
-[DIAB4_D]
-tan bellamente producida, tan gustosamente fotografiada, está siendo esparcida por toda Liberty!
+[ASM4_7]
+~r~¡Estúpido, has matado a la mujer!
-[DIAB4_E]
-Monta en la camioneta y sigue el rastro de los volúmenes 1, 2 y 3 de Donkey Does Dallas,
+[ASM4_8]
+~r~¡El blanco te oyó disparar el arma! ¡El trato queda anulado!
-[DIAB4_F]
-tomándolos por el camino.
+[ASM4_9]
+~r~¡El blanco ha embarcado en su vuelo!
-[DIAB4_G]
-¡Cuando alcances a ese bandido espaciado con SPANK, chíngatelo!
+[ASM4_11]
+~r~¡El blanco te ha visto! ¡El trato queda anulado!
-[DIAB4_H]
-Luego reparte mis revistas XXX por el Red Light District.
+[ASM4_13]
+~g~Te ha visto y está huyendo, ¡atrápale y consigue el maletín!
-[DIAB4_1]
-~g~Lleva la furgoneta a la parte de atrás de Revistas XXX.
+[ASM4_14]
+~g~La barra de distancia en la parte superior derecha de la pantalla te proporciona una indicación de lo cerca que estás de tu blanco. No permitas que se llene o éste te verá.
-[HM1_E]
-Quiero que esos mierdecillas sepan lo que es un verdadero tiroteo desde un vehículo.
+[ASM_5]
+MISIÓN DE ASESINO 5
-[HM1_H]
-¡Haz que esos Nines se larguen!
+[KICK]
+ARRANQUE
-[HM2_A]
-Los Nines me están presionando.
+[KICK1_3]
+~g~Número de veces que pusiste el pie: ~1~
-[HM2_B]
-Tienen coches blindados y ahora están pasando SPANK
+[KICK1_4]
+~g~Tiempo de penalización: ~1~ segundos
-[HM2_C]
-a los hermanos sin ningún pudor.
+[BANK]
+MISIONES DEL ATRACO AL BANCO
-[HM2_D]
-Hay un coche aparcado en la calle.
+[BANK1]
+MISIÓN DE ATRACO AL BANCO 1
-[HM2_E]
-Dentro lleva algo que te servirá para poner a esos gallinas en su sitio
+[BANK2]
+MISIÓN DE ATRACO AL BANCO 2
-[HM3_A]
-Algún cazurro me ha puesto una bomba en el coche.
+[BJM2_21]
+~g~Acierta a tantos blancos como puedas mientras te quede munición.
-[HM3_B]
-Si lo pierdo, mi reputación en la calle se irá a la porra.
+[BANK3]
+MISIÓN DE ATRACO AL BANCO 3
-[HM3_C]
-Coge mi coche y llévalo al taller de Saint Mark's, ¿valiendo?
+[BJM3_1]
+~g~Consigue un coche rápido y ve a la parrilla de salida.
-[HM3_D]
-Que se encarguen ellos de desarmar la bomba.
+[BNK4_2A]
+Los chicos hicieron un trabajo genial con este pequeño.
-[HM3_E]
-El tiempo corre y ese trasto es un peligro.
+[BNK4_3G]
+¡Oh, mierda, ahora los polis andan tras nosotros!
-[HM3_F]
-Un golpe más de la cuenta y podría saltar por los aires.
+[BNK4_3H]
+Y ni siquiera hemos llegado.
-[HM3_G]
-¡Tira!
+[BNK4_3K]
+Primero tendremos que despistar a los polis...
-[HM4_A]
-Tío, un vuelo de la Reserva Federal se la acaba de pegar en el Aeropuerto Francis.
+[BNK4_3L]
+Joder, Tommy, ¿intentas matarnos a todos?
-[HM4_B]
-Hay platino por toda la pista.
+[BNK4_3N]
+¡Todo lo que me importa acaba destrozado!
-[HM4_C]
-Consigue un coche y agarra todo lo que puedas.
+[BNK4_26]
+¡Maldición! ¡Aquí vienen!
-[HM4_F]
-Puedes dejar la mercancía en uno de mis garajes.
+[BNK4_32]
+¡Usa los explosivos para abrir las cajas de depósito!
-[HM4_G]
-El platino pesa un huevo y hará que tu buga vaya a paso de tortuga,
+[BNK4_36]
+¿Dónde está Cam?
-[HM4_H]
-así que ve dejándolo de vez en cuando en el garaje.
+[BNK4_37]
+Es historia...
-[HM5_A]
-Ya sólo quedan unos pocos Nines,
+[BNK4_38]
+Ése era el último. ¡Vamos! ¡Vamos! ¡Vamos!
-[HM5_B]
-pero todavía quieren guerra.
+[BNK_39]
+¡Mierda! ¿Dónde está Hilary?
-[HM5_C]
-Han aceptado un mano a mano.
+[BK4_40A]
+¡Ya le daré yo miedo al abandono!
-[HM5_D]
-Un puñado de los suyos contra dos de los nuestros,
+[BNK4_42]
+¡Eh, tíos! ¡Subid! ¡Yo os cubro!
-[HM5_E]
-o más bien, tú y uno más.
+[BNK4_43]
+¡Ya cubro yo nuestros culos, tú conduce!
-[HM5_F]
-Os ayudaría, pero...
+[BNK4_44]
+¡Lo conseguimos! ¡Somos ricos! ¡Ricos!
-[HM5_G]
-No quiero jugarme mi libertad condicional,
+[BNK4_45]
+Es una pena que Cam no lo consiguiese, ¡era un buen tipo!
-[HM5_H]
-¿me captas?
+[BNK4_46]
+Sí. Pero aún así... ¡más tajada para nosotros!
-[HM5_I]
-Reúnete con mi hermano pequeño,
+[BNK4_47]
+¡Claro que sí! ¡Sí!
-[HM5_J]
-él te enseñará dónde será la pelea.
+[BNK4_48]
+Tommy, ¿te gustaría un masaje?
-[MEA1_B]
-Me llamo Chonks, Marty Chonks.
+[BNK4_49]
+¡Hola, Mercedes! Sí, estoy un poco tenso...
-[MEA1_C]
-Soy el dueño de la fábrica de comestibles Bitch'n' Dog que está a la vuelta de la esquina.
+[BNK450A]
+¿Qué te dije, Tommy? ¿Qué te dije? Maldito SWAT, será mejor que tengas cuidado cuando Kent Paul esté en la ciudad.
-[MEA1_D]
-Tengo problemas económicos, ¿pero y quién no?
+[BNK450B]
+Vamos, dame una tajada más grande, colega, venga. Tengo que comprarme ropa nueva.
-[MEA1_E]
-He quedado con el director de mi banco.
+[BNK4_51]
+Yo creo que tienes buen aspecto.
-[MEA1_F]
-Es un chorizo que no para de inflar los intereses del préstamo para sacarme una buena tajada.
+[KENT]
+MISIONES DE KENT PAUL
-[MEA1_G]
-Coge mi coche, búscale y tráelo aquí.
+[KENT1]
+MISIÓN DE KENT PAUL 1
-[MEA1_H]
-¡Tengo una sorpresita para ese parásito chupasangre!
+[COUNT]
+MISIONES DE FALSIFICACIÓN
-[MEA2_A]
-Contraté a unos ladrones para que entraran en mi piso
+[COUNT1]
+MISIÓN DE FALSIFICACIÓN 1
-[MEA2_C]
-Ahora los muy cabritos me han amenazado con delatarme
+[COUNT2]
+MISIÓN DE FALSIFICACIÓN 2
-[MEA2_D]
-si no les doy una parte.
+[BIKE]
+LAS MISIONES DE LA PANDILLA DE MOTEROS
-[MEA2_E]
-¿Te lo puedes creer?
+[BIKE1]
+MISIÓN DE MOTORISTA 1
-[MEA2_F]
-He dejado un coche dentro de la fábrica.
+[BIKE2]
+MISIÓN DE MOTORISTA 2
-[MEA2_G]
-Ve a recogerles con él en su territorio, en el Red Light District.
+[BIKE3]
+MISIÓN DE MOTORISTA 3
-[MEA2_H]
-Luego tráelos a la fábrica para que conozcan la opinión de Marty.
+[GOAWAY1]
+Vuelve cuando hayas terminado con las misiones de la banda haitiana.
-[MEA3_A]
-El negocio se irá a pique si no consigo un pastizal muy pronto.
+[HAIT]
+LAS MISIONES DE LA BANDA HAITIANA
-[MEA3_B]
-Mi esposa tiene un seguro de vida y ella no ha hecho más que vaciarme los bolsillos.
+[HAIT1]
+MISIÓN HAITIANA 1
-[MEA3_C]
-He dejado un coche donde siempre.
+[HAIT2]
+MISIÓN HAITIANA 2
-[MEA3_D]
-Ve a por a mi esposa a Classic Nails y tráela a la fábrica.
+[HAIT3]
+MISIÓN HAITIANA 3
-[MEA4_A]
-Mierda, ¡la he liado!
+[HAM3_6]
+~g~Utiliza el rifle de francotirador que te he dejado para cumplir tu tarea.
-[MEA4_B]
-Resulta que mi esposa salía con uno al que debo dinero.
+[ROCK]
+LAS MISIONES DE LA BANDA DE ROCK
-[MEA4_C]
-¡Se ha cabreado y ahora quiere vengarse!
+[ROK1_4]
+~g~De acuerdo, creo que esto es lo que andabais buscando...
-[MEA4_E]
-y piensa que voy a devolverle el dinero.
+[ROK1_1E]
+~g~¡Costará más de lo que tienes!
-[MEA4_F]
-Pero creo...
+[ROK1_1F]
+~g~Vuelve cuando tengas el dinero.
-[MEA4_G]
-¡que los perros de Liberty van a disfrutar de un sabor nuevo este mes!
+[RBM2_6]
+~g~¡Guau! ¡Ella es un tío, detenle!
-[WELCOME]
-BIENVENIDO A
+[ROCK3]
+MISIONES DE LA BANDA DE ROCK 3
-[HM1_2]
-~g~Hazte con un vehículo y recuerda que sólo cuentan las muertes a tiros desde el coche.
+[RBM3_5]
+~g~Lleva a los Love Fist al escenario.
-[HELP8_B]
-Pulsa ~h~~k~~PED_SNIPER_ZOOM_IN~ ~w~para ~h~aumentar el zoom ~w~de la mira del fusil y ~h~~k~~PED_SNIPER_ZOOM_OUT~~w~ para ~h~reducirlo~w~.
+[CUBANM]
+LAS MISIONES DE LA BANDA CUBANA
-[LRQC_1]
-Asuka y yo tenemos que hablar...
+[CUBAN1]
+MISIÓN CUBANA 1
-[LRQC_2]
-¿Por qué no te das una vuelta?
+[CUBAN2]
+MISIÓN CUBANA 2
-[LRQC_3]
-Necesitarás un escondite.
+[CUB2_10]
+~r~¡Se supone que debes matar a haitianos, no a cubanos!
-[LRQC_4]
-Hay un almacén en la orilla de Belleville que podría servirte.
+[CUBAN3]
+MISIÓN CUBANA 3
-[LRQC_5]
-Regresa a mi apartamento cuando estés listo
+[CUBAN4]
+MISIÓN CUBANA 4
-[LRQC_6]
-y podremos tener una charla.
+[PROT]
+MISIONES DE PROTECCIÓN
-[JM6_5]
-~g~Necesitas un vehículo de fuga, ¡idiota!
+[PORN]
+MISIONES PORNO
-[JM2_F]
-Si necesitas una pipa, ve a la parte de atrás del Ammu-Nation que está enfrente del metro.
+[PORN1]
+MISIÓN PORNO 1
-[LOVE4_7]
-~g~Hay un edificio en construcción en Staunton Island, puede que hayan llevado el paquete allí.
+[POR1_03]
+~r~¡Candy está muerta!
-[LOVE4_8]
-~g~Necesitarás un coche para abrir el garaje.
+[PORN2]
+MISIÓN PORNO 2
-[TSCORE]
-GANANCIAS: ~1~ $
+[PORN3]
+MISIÓN PORNO 3
-[AM1_9]
-~r~¡Salvatore ha vuelto a meterse en el club de Luigi!
+[PORN4]
+MISIÓN PORNO 4
-[AM1_6]
-~g~Si te dejas ver por el club de Luigi, ¡la mafia te descubrirá!
+[PHIL]
+MISIONES DE PHIL
-[TM2_3]
-~g~¡Es una trampa! ¡Liquidadlos a todos!
+[PHIL1]
+MISIÓN DE PHIL 1
-[FM4_1]
-Soy María. ¡El coche es una trampa! Estoy en el lado sur del puente Callahan.
+[PHIL2]
+MISIÓN DE PHIL 2
-[JM1_7]
-~g~¡Cierra la puerta del coche o se dará cuenta!
+[PIZ1_A]
+MISIÓN DEL REPARTIDOR DE PIZZAS
-[KM5_1]
-~g~¡TRAFICANTE LIQUIDADO!
+[CNTBUY1]
+Compra de la imprenta: ~1~ $
-[KM5_6]
-~g~Debes matar a al menos 8 traficantes jamaicanos.
+[CARBUY]
+Compra del salón de coches: ~1~ $
-[KM5_7]
-~g~¡Mátalos rápido! En cuanto vendan el SPANK se retirarán de las calles.
+[PORNBUY]
+Compra del estudio cinematográfico: ~1~ $
-[RM3_8]
-~r~¡El coche es un señuelo!
+[ICEBUY]
+Compra de la fábrica de helados: ~1~ $
-[LM3_8]
-Hola, soy Joey.
+[TAXIBUY]
+Compra de la empresa de taxis: ~1~ $
-[LM3_9]
-Luigi dijo que eras de fiar, así que vuelve más tarde,
+[BANKBUY]
+Compra del Malibú: ~1~ $
-[KM3_5]
-~g~Toca el claxon para empezar con el trato.
+[BOATBUY]
+Compra del astillero: ~1~ $
-[LOVE7]
-'LA DESAPARICIÓN DE LOVE'
+[PRNT_NO]
+No puedes comprar la imprenta en este momento, vuelve más tarde.
-[LOVE2_5]
-~g~¡Kenji ha palmado! ¡Sal de Newport y deshazte del coche!
+[CAR_NO]
+No puedes comprar el salón de coches en este momento, vuelve más tarde.
-[AS2_11]
-~g~¡~1~ DE 9!
+[PORN_NO]
+No puedes comprar el estudio cinematográfico en este momento, vuelve más tarde.
-[GARAGE1]
-~g~Sal del vehículo y aléjate caminando.
+[ICE_NO]
+No puedes comprar la fábrica de helados en este momento, vuelve más tarde.
-[KM3_11]
-~g~El cártel ha sido atacado y el maletín no ha sido recuperado.
+[TAXI_NO]
+No puedes comprar la compañía de taxis en este momento, vuelve más tarde.
-[KM3_12]
-~g~Mata a todos los colombianos, destruye los vehículos y recupera el maletín.
+[BANK_NO]
+No puedes comprar el Malibú en este momento, vuelve más tarde.
-[KM3_13]
-~g~Lleva el maletín de vuelta al casino.
+[BOAT_NO]
+No puedes comprar el astillero en este momento, vuelve más tarde.
-[RM5_6]
-~g~¡Ha salido de la ambulancia! ¡Cárgate su escayola con un vehículo o una explosión!
+[COL2_6]
+¡Alto, cerdo imperialista americano!
-[PBOAT_1] { re3 change }
-Pulsa ~h~~k~~VEHICLE_FIREWEAPON~~w~ para disparar los cañones de la lancha.
+[COL2_6B]
+Eso es propiedad del gobierno francés.
-[PBOAT_2] { re3 change }
-Pulsa ~h~~k~~VEHICLE_FIREWEAPON~~w~ para disparar los cañones de la lancha.
+[COL2_6C]
+¡y se acabó!
-[DIAB1_B]
-Al habla El Burro, de los Diablos.
+[COL3_A]
+Thomas, aprecio que vinieses.
-[DIAB1_D]
-Eres nuevo en Liberty, pero ya te estás ganando una reputación en las calles.
+[COL3_B]
+Perdóname por ir directamente al asunto.
-[DIAB1_E]
-Hay una carrera que empezará junto a la sala Clásica, cerca del puente Callahan.
+[COL3_C]
+Diaz me ha pedido que supervise una transacción de un negocio menor.
-[DIAB1_F]
-Consíguete un buen carro y el primero que pase por todos los puntos de control se llevará el premio.
+[COL3_D]
+Esperemos que vaya mejor que la última vez.
-[HM2_1] { re3 change }
-Usa los coches teledirigidos para destruir los furgones blindados. Pulsa ~h~~k~~VEHICLE_FIREWEAPON~ ~w~para detonarlos.
+[COL3_E]
+Por eso es por lo que pensé en ti, amigo mío.
-[HM2_1A] { re3 change }
-Usa los coches teledirigidos para destruir los furgones blindados. Pulsa ~h~~k~~VEHICLE_FIREWEAPON~ ~w~para detonarlos.
+[COL3_F]
+He dejado algo de protección en el aparcamiento.
-[HM2_2]
-~r~¡No has destruido todos los furgones blindados!
+[COL3_G]
+Recógele y luego id a ver a los hombres de Diaz en el punto de entrega.
-[HM2_6]
-~g~¡Te has cargado un furgón blindado!
+[COL4_2]
+¡No lo sé, señor!
-[RM3_A]
-Conozco a un pez gordo de la ciudad, un tipo muy cándido,
+[COL4_5]
+¡Señor, sí, señor!
-[RM3_H]
-con, digamos... gustos exóticos y el dinero para pagárselos.
+[COL4_10]
+Vamos a comer unos donuts.
-[RM3_B]
-Está involucrado en un asunto legal y la fiscalía tiene fotos de él muy comprometedoras
+[COL4_16]
+¡Señor! ¡Moviendo el vehículo, señor!
-[RM3_C]
-en una fiesta en la morgue o algo así.
+[COL4_25]
+¡Iniciada autodestrucción del vehículo!
-[LOVE6_A]
-Una lección sobre negocios, amigo mío:
+[COL5_6]
+Mercedes, esa chica me matará.
-[LOVE6_E]
-Si tienes una mercancía única, todo el mundo tratará de arrebatártela,
+[COL5_8]
+¡Maldita cucaracha!
-[LOVE6_C]
-Unos SWAT han acordonado la zona donde se encuentran mi socio y el paquete.
+[COL5_5]
+¡Morid, cerdos franceses!
-[LOVE6_D]
-Ve allí, recoge la furgoneta y haz de señuelo.
+[CNT2_1]
+Matadle.
-[LOVE6_F]
-Mantenlos ocupados para que él pueda escapar.
+[CNT2_2]
+¡Conseguid las planchas!
-[AM3_C]
-Ahora mismo estará en la bahía. ¡Roba una lancha de la policía y hunde su carrera!
+[CNT2_3]
+¡Proteged al mensajero!
-[FESZ_UC]
-CANCELAR
+[FINKILL]
+¡De acuerdo, chicos, matadle!
-[FEDS_SM]
-L1, R1 - CAMBIAR MENÚ
+[FIN_1A]
+¡Ven aquí, traidor, pedazo de mierda!
-[FEDS_AS]
-;= - CAMBIAR SELECCIÓN
+[FIN_1B]
+¡Vas a caer, mamón traicionero!
-[FEDSAS2]
-<> - CAMBIAR SELECCIÓN
+[FIN_1C]
+¡Éste es el último baile para Lance Vance!
-[FEDS_SS]
-L1,R1 - CAMBIAR SELECCIÓN
+[FIN_2B]
+¡Oh, eso crees tú!
-[FEDSSC1]
-; - ACELERAR
+[FIN_2C]
+¡Ya tuve suficiente de eso en la escuela!
-[FEDSSC2]
-= - RALENTIZAR
+[FIN_3]
+Ahora no hay nadie para cubrirte el trasero, ¿eh, Tommy?
-[MEA2_3]
-~g~Lleva el coche de vuelta a la fábrica.
+[FIN_4]
+Eres historia, Tommy, historia.
-[RM1_3]
-~r~¡McAffrey se ha escapado!
+[FIN_5]
+Escogiste el lado equivocado, Lance...
-[RM1_4]
-~g~¡Has usado todas las granadas! ¡Consigue más en la tienda Ammu-Nation!
+[FIN_6]
+Sonny está arriba con la caja fuerte y mi dinero...
-[RM1_5]
-~g~¡Vuelve y quema la casa franca!
+[FIN_10]
+¿Sonny? ¡Sonny! ¡Voy por ti!
-[RM6_4]
-~g~Ve al almacén a por el cargamento de Ray.
+[FIN_11A]
+Me arrebataste quince años, Sonny...
-[RM6_5]
-~g~La CIA vigila el puente, busca otro camino.
+[FIN_11B]
+¡Y ahora voy a hacértelo pagar!
-[HM2_F]
-y cargarte sus blindados.
+[FIN_12A]
+Todavía no lo captas, ¿verdad?
-[HM_4]
-'FIEBRE DEL PLATINO'
+[FIN_12B]
+Eres de mi propiedad, Tommy.
-[MEA4_B7]
-Pero si pasas por mi oficina...
+[FIN_12C]
+¡Esos quince años eran míos para gastarlos!
-[MEA3_B4]
-¿Marty quiere verme? Bueno, pues que sea rápido, porque tengo que ir a la peluquería.
+[FIN_13]
+Atrapadle chicos, nunca comprendió nada.
-[KM3_7]
-¡Es una trampa de la yakuza, man!
+[RACES_4]
+3
-[FES_LOF]
-Fallo al cargar.
+[RACES_5]
+2
-[P1INSA]
-La Memory Card (PS2) insertada en la ranura para MEMORY CARD 1 tiene ~1~ KB de espacio disponible. Necesitas ~1~ KB para guardar.
+[RACES_6]
+1
-[P1INSN]
-La Memory Card (PS2) insertada en la ranura para MEMORY CARD 1 no tiene espacio suficiente. Por favor, borra algunos archivos.
+[RACES_7]
+¡ADELANTE!
-[FES_SLO]
-ARCHIVO
+[RACES_9]
+Tiempo: ~1~:~1~
-[FES_ISC]
-ESTÁ DAÑADO
+[RACES]
+TIEMPO:
-[FESZ_TI]
-ARCHIVO Z1
+[RACES17]
+Nuevo mejor tiempo: ~1~:~1~
-[FESZ_SA]
-Guardar partida
+[RACES18]
+HAS GANADO: ~1~ $
-[P1NOIN]
-No hay una Memory Card (PS2) insertada en la ranura para MEMORY CARD 1.
+[RACES20]
+Nuevo mejor tiempo: ~1~:0~1~
-[P1INSE]
-Memory Card (PS2) insertada en la ranura para MEMORY CARD 1.
+[RACES21]
+Tiempo: ~1~:0~1~
-[MC_LDFL]
-¡Fallo al cargar!
-[MC_NWRE]
-Reiniciando partida.
+[RCH1_2]
+~g~Los CONTROLES están esparcidos a lo largo del aeropuerto.
-[LOVE6_3]
-~g~Tienes ~1~ segundos para volver al Securicar antes de fracasar la misión.
+[RCH1_5]
+Tiempo:
-[LOVE6_4]
-~r~¡Has abandonado el Securicar señuelo!
+[RCRC1_2]
+~g~¡Ve a la parrilla de salida!
-[HELP1]
-Detente en el centro del marcador azul.
+[RCRC1_4]
+~g~3
-[HELP12]
-Entra en el marcador azul para comenzar una misión.
+[RCRC1_5]
+~g~2
-[HJSTAT]
-Distancia: ~1~,~1~ m. Altura: ~1~,~1~ m. Vueltas: ~1~. Rotación: ~1~_.
+[RCRC1_6]
+~g~1
-[HJSTATW]
-Distancia: ~1~,~1~ m. Altura: ~1~,~1~ m. Vueltas: ~1~. Rotación: ~1~_. ¡Y qué buen aterrizaje!
+[RCRC1_7]
+~g~¡ADELANTE!
-[DIAB1_5]
-TIEMPO DE CARRERA:
+[RCRC1_8]
+~g~Tiempo de carrera: ~1~ segundos
-[LOVE3_4]
-~r~¡Has destruido la avioneta!
+[RCPL1_1]
+~g~Compite en una CARRERA DE PUNTOS DE CONTROL con otros tres Barón RC.
-[F_FAIL1]
-¡Misión del camión de bomberos terminada!
+[RCPL1_2]
+~g~Debes atravesar la ~o~CORONA DEL CENTRO ~g~para pasar con éxito un punto de control.
-[F_CANC]
-~r~¡Misión del camión de bomberos cancelada!
+[RCPL1_3]
+~g~¡Ve ahora a la parrilla de salida!
-[F_EXTIN]
-INCENDIOS:
+[ICC1_O]
+¿Qué pasa contigo?
-[A_COMP1]
-¡Misiones de conductor de ambulancia completadas!
+[FEA_2SP]
+2 altavoces
-[A_CANC]
-~r~¡Misión de conductor de ambulancia cancelada!
+[FEA_4SP]
+Más de 2 altavoces
-[A_COMP3]
-¡Misiones de conductor de ambulancia completadas! ¡Ahora no te cansarás al esprintar!
+[FEA_EAR]
+Auriculares
-[ATUTOR]
-Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misiones de conductor de ambulancia.
+[FEA_NAH]
+NO HAY HARDWARE DE AUDIO
-[ATUTOR3]
-Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misiones de conductor de ambulancia.
+[FET_APP]
+APLICAR
-[ALEVEL]
-Nivel de misión de conductor de ambulancia: ~1~
+[FES_SKN]
+NOMBRE DE APARIENCIA
-[A_FAIL1]
-Misión de conductor de ambulancia terminada.
+[FES_DAT]
+FECHA
-[FEST_HA]
-Mayor nivel de misión de cond. de ambulancia
+[FES_SET]
+Utilizar apariencia
-[A_SAVES]
-PERSONAS SALVADAS: ~1~
+[FET_DEF]
+Restaurar valores por defecto
-[C_KILLS]
-CRIMINALES ABATIDOS: ~1~
+[FESZ_QZ]
+¿Seguro de que quieres guardar esta partida?
-[HM1_B]
-Tengo un problema, me la están liando.
+[FES_SCG]
+¿Guardar la partida actual?
-[AM2_A]
-La muerte de Salvatore es una placentera noticia,
+[FES_LCG]
+¿Cargar la partida y continuar jugando?
-[AM2_A2]
-eres un asesino eficaz. Eso me gusta en un hombre.
+[FEC_FIR]
+Disparar
-[AM2_B]
-Éste es mi hermano Kenji.
+[FEC_NWE]
+Siguiente arma
-[AM2_C]
-Asuka tiene un trabajito para ti, pero cuando acabes, pásate por mi casino y podremos hablar.
+[FEC_PWE]
+Arma anterior
-[AM2_D]
-Típico de Kenji, siempre está detrás de mis juguetes.
+[FEC_FOR]
+Avanzar
-{ The voiced dialogue doesn't match the English subtitle for the next string }
+[FEC_BAC]
+Retroceder
-[AM2_E]
-Mi contacto en la policía me dice que el FBI ha montado un operativo de vigilancia
+[FEC_LEF]
+Izquierda
-{ The voiced dialogue doesn't match the English subtitle for the next string }
+[FEC_RIG]
+Derecha
-[AM2_E2]
-en varios puntos de la ciudad.
+[FEC_ZIN]
+Acercar zoom
-{ The voiced dialogue doesn't match the English subtitle for the next string }
+[FEC_ZOT]
+Alejar zoom
-[AM2_F]
-No tenemos tiempo para contactar con nadie y evitar que nos incriminen.
+[FEC_EEX]
+Entrar y salir
-{ The voiced dialogue doesn't match the English subtitle for the next string }
+[FEC_RAD]
+Radio
-[AM2_G]
-Liquida a esos polis espías, pero cuidado: tendrán apoyo.
+[FEC_SUB]
+Misión secundaria
-[F_START]
-~g~Se ha avistado un vehículo en llamas en: ~a~. Ve y extingue el fuego.
+[FEC_CMR]
+Cambiar cámara
-[AM4_1A]
-Ve a la cabina al oeste del parque Belleville.
+[FEC_JMP]
+Saltar
-[AM4_1B]
-Ve a la cabina del campus de Liberty.
+[FEC_SPN]
+Esprintar
-[AM4_1C]
-Ve a la cabina al sur del parque Belleville.
+[FEC_HND]
+Freno de mano
-[AM4_1D]
-Ven a verme a los baños públicos del parque.
+[FEC_LOL]
+Mirar hacia la izquierda
-[HJSTATF]
-Distancia: ~1~ pies. Altura: ~1~ pies. Vueltas: ~1~. Rotación: ~1~_.
+[FEC_LOR]
+Mirar hacia la derecha
-[HJSTAWF]
-Distancia: ~1~ pies. Altura: ~1~ pies. Vueltas: ~1~. Rotación: ~1~_. ¡Y qué buen aterrizaje!
+[FEC_NTR]
+Siguiente objetivo
-[HM1_F]
-Pero ojo, también habrá Jacks que se creerán que vas a por ellos.
+[FEC_PTT]
+Objetivo anterior
-[HM1_D]
-Se llaman ''Nines'', van de púrpura, y cada día en el que se hacen notar
+[FEC_LBA]
+Mirar detrás
-[HM1_G]
-es otro día más que los Jacks parecemos blandos.
+[FEC_CEN]
+Centrar cámara
-[MEA2_B]
-y robaran cuanto pillaran para que yo pudiera reclamar a la aseguradora.
+[FET_CFT]
+A PIE
-[TM3_H]
-Buen trabajo, chaval, muy bueno.
+[FET_CCR]
+EN COCHE
-[TM3_I]
-Vente, te presentaré al Don.
+[FET_CAC]
+ACCIÓN
-[TM3_J]
-¡Hola! ¡Luigi!
+[FEC_IBT]
+-
-[TM3_K]
-Mis chicas te han echado de menos, Salvatore. Hace bastante que no te vemos.
+[FEC_MXO]
+MXB1
-[TM3_L]
-Diles que en cuanto resolvamos este desafortunado incidente
+[FEC_MXT]
+MXB2
-[TM3_M]
-iremos todos al club para celebrarlo, ¿vale?
+[FEC_UNB]
+ILIMITADO
-[TM3_N]
-¡Mi niño!
+[FEC_TFL]
+Mirar a izquierd+Torreta L
-[TM3_N2]
-¿Cómo estás, papá?
+[FEC_TFR]
+Mirar a derecha+Torreta R
-[TM3_O]
-¿Has encontrado ya una buena mujer?
+[FEC_MWF]
+RUEDA DEL RATÓN ARRIBA
-[TM3_P]
-Tu madre, que en paz descanse, se retorcería en la tumba
+[FEC_MWB]
+RUEDA DEL RATÓN ABAJO
-[TM3_Q]
-si te viera sin una mujer.
+[FEC_ORR]
+o
-[TM3_R]
-Lo sé, papá, estoy en ello.
+[FEC_NUS]
+NO UTILIZADO
-[TM3_S]
-¡Toni! ¿Cómo está tu madre?
+[FEC_LUD]
+Mirar arriba
-[TM3_T]
-Es una gran mujer, ¿sabes? Fuerte, ''firenze''.
+[FEC_LDU]
+Mirar abajo
-[TM3_U]
-Está bien, estupendamente.
+[FEC_CMP]
+COMBO: MIRAR I+d
-[TM3_V]
-Fantástico, fantástico. Bien, muchachos, entrad mientras yo hablo con nuestro nuevo amigo.
+[LAW_1A]
+law_1a
-[TM3_W]
-Tienes un gran futuro por delante, hijo mío...
+[LAW_1B]
+law_1b
-[RM1_A]
-¡Ese canalla de McAffrey...! ¡Aceptó más sobornos que nadie,
+[LAW_2A]
+law_2a
-[RM1_B]
-se piensa que le darán la pensión completa si se convierte en un testigo de cargo!
+[LAW_2B]
+law_2b
-[RM1_C]
-¡Y ha cantado!
+[FEH_STA]
+ESTADÍSTICAS
-[RM4_B]
-Tenemos que cerrarle la boca para siempre.
+[FEH_LOA]
+CARGAR
-[RM4_E]
-¡Quiero que deje de comer peces y se vaya a dormir con ellos!
+[FEH_CON]
+CONTROLES
-[LOVE3_B]
-Esta noche, durante su aproximación al aeropuerto, una avioneta sobrevolará la bahía.
+[FEH_AUD]
+SONIDO
-[LOVE4_D]
-Desgraciadamente, las autoridades aduaneras incautaron la avioneta y la comenzaron a desmontar
+[FEH_DIS]
+PANTALLA
-[LOVE4_H]
-hasta que yo intervine a través de mi fortuna.
+[FEH_LAN]
+IDIOMA
-[LOVE4_E]
-Cruza el puente hacia Shoreside Vale y ve al Aeropuerto Internacional Francis.
+[FEH_SGA]
+INICIAR NUEVA PARTIDA
-[GTAB_A]
-Oye, saquemos esto de aquí. Dios sabrá lo que será,
+[FEO_CON]
+Configuración del mando
-[GTAB_B]
-pero él lo quiere a toda costa, así que tendrá algún valor.
+[FEO_AUD]
+Configuración de sonido
-[GTAB_C]
-¡¿Qué diablos?!
+[FEO_DIS]
+Configuración de pantalla
-[GTAB_D]
-¡TÚ!
+[FEO_LAN]
+Configuración de idioma
-[GTAB_E]
-¡Tranquilo, amigo! ¡No es nada! ¡No es nada!
+[FEO_PLA]
+Configuración del jugador
-[GTAB_F]
-¡Te dejé desangrándote entre la basura!
+[FET_PS]
+CONFIGURACIÓN DE APARIENCIA
-[GTAB_G]
-No dispares, amigo. No hay problema. Somos amigos. Mira, coge esto.
+[FEA_OUT]
+Salida
-[GTAB_H]
-¡No seas cagón!
+[FEA_ST]
+Estéreo
-[GTAB_I]
-¡No tenemos elección, nena!
+[FEA_DTS]
+DTS
-[GTAB_J]
-¡Siempre la hay, imbécil!
+[FEA_RSS]
+Emisora de radio
-[GTAB_K]
-¡Siento mucho lo de esa perra enloquecida, todas son iguales...! ¿Por favor?
+[FEA_NON]
+RADIO APAGADA
-[GTAB_L]
-Así que la zorra se fue.
+[FEA_FM0]
+WILDSTYLE
-[GTAB_M]
-Pero me has hecho un favor,
+[FEA_FM1]
+FLASH FM
-[GTAB_N]
-no eres el único que tiene una cuenta pendiente con el cártel...
+[FEA_FM2]
+KCHAT
-[GTAB_O]
-¡Este gusano mató a mi hermano!
+[FEA_FM3]
+FEVER 105
-[GTAB_P]
-¡Nunca maté a ningún yakuza!
+[FEA_FM4]
+VROCK
-[GTAB_Q]
-¡Mientes! Todos vimos al asesino del cártel.
+[FEA_FM5]
+VCPR
-[GTAB_R]
-¡Vamos a cazaros y a mataros a todos, perros colombianos!
+[FEA_FM7]
+EMOTION 98.3
-[GTAB_S]
-Me trabajaré a nuestro querido amigo para extraerle información y un poco de placer.
+[FEA_FM8]
+WAVE 103
-[GTAB_T]
-Tú, ven más tarde, estoy segura de que voy a necesitar tus servicios.
+[FED_BRI]
+Brillo
-[GTAB_U]
-¡Por favor, amigo! ¡No me dejes con ella, esa chica está loca! ¿Amigo? ¡Oye, amigo! ¡Amigo...!
+[FED_TRA]
+Estelas
-[LOVE5_A]
-Estás demostrando ser una inversión segura, algo muy raro en estos días.
+[FED_SUB]
+Subtítulos
-[KM3_1]
-~g~El cártel espera a una banda jamaicana, ¡así que roba uno de sus coches! Dirígete al norte, encontrarás uno en Newport.
+[FED_WIS]
+Formato 16:9
-[LOVE1_1]
-~g~Roba un coche de la banda colombiana para que puedas entrar en su escondite. Ve al norte, encontrarás uno en Fort Staunton.
+[FED_POS]
+Posición de la pantalla
-[FM1_Q1]
-¿Quieres un poco de diversión? ¿Un poco de... hmmm, de SPANK?
+[FED_RDR]
+RADAR
-[FM1_R]
-Hola, Chico. No, sólo lo de siempre.
+[FED_HUD]
+MODO HUD
-[FM1_T]
-Gracias, Chico, nos vemos.
+[FED_RDB]
+SOLO ICONOS
-[FM1_W]
-Oye, tú, espera aquí y quédate pendiente del coche mientras yo voy a menear el esqueleto, ¿vale?
+[FE_MLG]
+LEYENDA DEL MAPA
-[FM1_X]
-¡Vale, tú, salgamos de aquí! ¡Uaaah!
+[FEI_SCR]
+Desplazarse
-[FM1_Q]
-¡Ay, mira, es mi chica favorita!
+[FEP_RES]
+Continuar
-[FM1_S1]
-Ey, deberías echar un vistazo a la fiesta del almacén en el lado este del muelle Atlantic.
+[FEP_STG]
+Iniciar partida
-[FM1_U]
-Gracias y disfruta. Es buen material.
+[FEP_STA]
+Estadísticas
-[FM1_V]
-¡Venga, tú, vamos a ver esa fiesta!
+[FEP_BRI]
+Resumen
-[FM1_SS]
-~r~ESCÁNER: ~g~Cuatro-cinco a todas las unidades: asistan redada de narcóticos en el muelle Atlantic.
+[FEP_OPT]
+Opciones
-[LOVE6_B]
-aun sin conocer su verdadera valía.
+[FEP_QUI]
+Salir del juego
-[TM3_A1]
-~r~¡Joey está frito!
+[FES_LOA]
+Cargar partida
-[TM3_A2]
-~r~¡Joey y Luigi han sido incinerados!
+[FES_DEL]
+Borrar partida
-[TM3_A3]
-~r~¡Joey, Luigi y Toni están calcinados!
+[FEC_CSU]
+Configuración del controlador
-[FM4_2]
-Mira, Salvatore cree que se la estamos jugando,
+[FEC_RED]
+Redefinir controles
-[FM4_3]
-así que te vendió al cártel para llegar a un trato.
+[FEC_MOU]
+Configuración del ratón
-[FM4_4]
-No podía permitírselo, o sea, lo peor es...
+[DISTGOL]
+Distancia recorrida en carro de golf (millas)
-[FM4_4B]
-que yo tengo la culpa, porque le dije que somos pareja.
+[DISTGOM]
+Distancia recorrida en carro de golf (m)
-[FM4_5]
-¡No me preguntes por qué, no lo sé!
+[ST_FAVR]
+Estación de radio favorita
-[FM4_6]
-Mira, la mafia te quiere muerto y yo también tengo que salir de aquí.
+[ST_WSTR]
+estación de radio que menos te gusta
-[FM4_6B]
-¡He visto demasiados asesinatos, demasiada sangre!
+[ST_FAVV]
+Vehículo favorito
-[FM4_7]
-Es una amiga mía, ¿vale?, una vieja amiga... Es Asuka, es de fiar.
+[ST_STAR]
+Número total de estrellas se busca conseguidas
-[FM4_8]
-Venga, dejémonos de discursos.
+[ST_HEAD]
+Número de disparos a la cabeza
-[FM4_9]
-Mejor nos vamos antes de que lleguen más italianos histéricos con intenciones menos amistosas.
+[ST_GANG]
+Banda que menos te gusta
-[CRED001]
-ROCKSTAR STUDIOS
+[ST_STGN]
+Número total de estrellas se busca evadidas
-[CRED002]
-PRODUCTOR
+[TYREPOP]
+Neumáticos reventados por disparos
-[CRED003]
-LESLIE BENZIES
+[TYRESLA]
+Neumáticos rajados con una navaja
-[CRED004]
-DIRECTOR DE ARTE
+[ST_BRK]
+Número de muertes en el anillo sangriento
-[CRED005]
-AARON GARBUT
+[ST_LTBR]
+Mayor tiempo en el anillo sangriento (segs.)
-[CRED006]
-DIRECCIÓN TÉCNICA
+[ST_GNG1]
+Cubanos
-[CRED007]
-OBBE VERMEIJ
+[ST_GNG2]
+Haitianos
-[CRED008]
-ADAM FOWLER
+[ST_GNG3]
+Aspirantes callejeros
-[CRED009]
-DISEÑO
+[ST_GNG4]
+Pandilleros de Díaz
-[CRED010]
-CRAIG FILSHIE
+[ST_GNG5]
+Guardias de seguridad
-[CRED011]
-WILLIAM MILLS
+[ST_GNG6]
+Banda de motoristas
-[CRED012]
-CHRIS ROTHWELL
+[ST_GNG7]
+Banda de Vercetti
-[CRED013]
-JAMES WORRALL
+[ST_GNG8]
+Golfistas
-[CRED014]
-GUIÓN
+[FEA_FM6]
+ESPANTOSO
-[CRED015]
-JAMES WORRALL
+[ST_ASSI]
+Contratos de asesinato completados
-[CRED016]
-PAUL KUROWSKI
+[DISTBIK]
+Dist. Recorrida en moto (millas)
-[CRED017]
-DAN HOUSER
+[DISTBIM]
+Distancia recorrida en moto (m)
-[CRED018]
-PERSONAJES
+[HOTEL]
+Ocean View
-[CRED019]
-IAN MCQUE
+[KICK1_9]
+PUNTOS DE CONTROL:
-[CRED020]
-ANIMACIÓN Y DIRECCIÓN
+[FIN_B6]
+No tienes suficiente dinero para empezar esta misión.
-[CRED021]
-ALEX HORTON
+[TEX3_9]
+~g~Recoge una bomba pasando con el helicóptero RC cerca de ella.
-[CRED022]
-LEE MONTGOMERY
+[HELP22]
+Ve a la señal de la casa verde que hay en el radar.
-[CRED023]
-DISEÑO DE VEHÍCULOS
+[FES_FMS]
+Éxito al formatear. Selecciona Aceptar para continuar.
-[CRED024]
-PAUL KUROWSKI
+[FES_SSC]
+Éxito al guardar. Selecciona Aceptar para continuar.
-[CRED025]
-ARTISTAS
+[FES_DSC]
+Éxito al borrar. Selecciona Aceptar para continuar.
-[CRED026]
-KEIRAN BAILLIE
+[FESZ_QC]
+¿Deseas sobreescribir esta partida guardada dañada?
-[CRED027]
-ADAM COCHRANE
+[FES_CHE]
+¡Atención! Se han activado uno o más trucos, esto puede afectar a tus partidas guardadas. Te recomendamos no guardar esta partida.
-[CRED028]
-GARY MCADAM
+[FET_SG]
+GUARDAR PARTIDA
-[CRED029]
-MICHAEL PIRSO
+[FEH_BRI]
+INFORME
-[CRED030]
-ANDREW SOOSAY
+[FEH_MAP]
+MAPA
-[CRED031]
-ALISDAIR WOOD
+[FEM_OK]
+Aceptar
-[CRED032]
-PROGRAMADORES
+[FEC_CRO]
+Agacharse
-[CRED033]
-ALAN CAMPBELL
+[FEC_CR3]
+Agacharse (Botón L3)
-[CRED034]
-MARK HANLON
+[FEC_SMT]
+Sub-misión
-[CRED035]
-ANDRZEJ MADAJCZYK
+[FEC_SM3]
+Sub-misión (Botón R3)
-[CRED036]
-ALEXANDER ROGER
+[FEC_RSC]
+Emisoras de radio
-[CRED037]
-GRAEME WILLIAMSON
+[ST_PR01]
+Aviador
-[CRED038]
-MÚSICA
+[ST_PR02]
+Piloto del ejército
-[CRED039]
-CRAIG CONNER
+[ST_PR03]
+Oficial piloto
-[CRED040]
-STUART ROSS
+[ST_PR04]
+Cabo
-[CRED041]
-DISEÑO DE SONIDO Y MÁSTER
+[ST_PR05]
+Teniente
-[CRED042]
-ALLAN WALKER
+[ST_PR06]
+Sargento
-[CRED043]
-PROGRAM. DE AUDIO
+[ST_PR07]
+Capitán
-[CRED044]
-RAYMOND USHER
+[ST_PR08]
+Biggs
-[CRED045]
-DIRECTOR DE PRUEBAS
+[ST_PR09]
+Wedge
-[CRED046]
-CRAIG ARBUTHNOTT
+[ST_PR10]
+Barón Rojo
-[CRED047]
-JEFES DE PRUEBAS
+[ST_PR11]
+Ganso
-[CRED048]
-ANDY DUTHIE
+[ST_PR12]
+Víbora
-[CRED049]
-JOHN HAIME
+[ST_PR13]
+Jester
-[CRED050]
-NEIL CORBETT
+[ST_PR14]
+Chappy
-[CRD050A]
-PROBADORES
+[ST_PR15]
+Iceman
-[CRED051]
-GRAEME JENNINGS
+[ST_PR16]
+Maverick
-[CRED052]
-DAVID MURDOCH
+[ST_PR17]
+Negado
-[CRED053]
-DAVID BEDDOES
+[ST_PR18]
+General de la Armada aérea
-[CRED054]
-EDWIN SMITH
+[ST_PR19]
+As
-[CRED055]
-MARK FLETT
+[FET_LG]
+CARGAR JUEGO
-[CRED056]
-MICHAEL SUTHERLAND
+[CAR_EXP]
+Vehículos destruidos
-[CRED057]
-SOPORTE TÉCNICO
+[BOA_EXP]
+Barcos destruidos
-[CRED058]
-LORRAINE ROY
+[HEL_DST]
+Aviones y helicópteros destruidos
-[CRED059]
-CHRISTINE CHALMERS
+[STFT_01]
+Tiempo más rápido de ''Moto con llantas de aleación''
-[CRED060]
-ROCKSTAR
+[STFT_02]
+Tiempo más rápido de ''El conductor''
-[CRED061]
-PRODUCTOR EJECUTIVO
+[STFT_03]
+Tiempo más rápido en el Circuito de Tierra
-[CRED062]
-SAM HOUSER
+[STFT_04]
+Tiempo más rápido en la Carrera de Aviones RC
-[CRED063]
-PRODUCTOR
+[STFT_05]
+Tiempo más rápido en la Carrera de Coches RC
-[CRED064]
-DAN HOUSER
+[STFT_06]
+Tiempo más rápido Control del Helicóptero RC
-[CRED065]
-DIRECTOR DE DESARROLLO
+[STFT_07]
+Tiempo más rápido en ''Velocidad terminal''
-[CRED066]
-JAMIE KING
+[STFT_08]
+Tiempo más rápido en ''Ocean Drive''
-[CRED067]
-PRODUCTOR TÉCNICO
+[STFT_09]
+Tiempo más rápido en ''Carrera por el borde''
-[CRED068]
-GARY J. FOREMAN
+[STFT_10]
+Tiempo más rápido en ''Capital Cruise''
-[CRED069]
-PRODUCTOR ASOCIADO
+[STFT_11]
+Tiempo más rápido en ''¡Tour!''
-[CRED070]
-JEREMY POPE
+[STFT_12]
+Tiempo más rápido en ''Aguante en V.C.''
-[CRED071]
-SUPERVISOR MUSICAL
+[STHC_01]
+Puntuación más alta en el campo de tiro
-[CRED072]
-TERRY DONOVAN
+[STHC_02]
+Mejor porcentaje de impactos en el campo de tiro
-[CRED073]
-EQUIPO DE PRODUCCIÓN DE ROCKSTAR
+[STHC_03]
+Ventas de droga realizadas
-[CRED074]
-TERRY DONOVAN
+[HELP24]
+Ahora puedes aceptar trabajos del Coronel.
-[CRED075]
-JENNIFER KOLBE
+[HELP25]
+Ahora puedes aceptar trabajos de Avery Carrington.
-[CRED076]
-JENEFER GROSS
+[HELP29]
+Puedes visitar la tienda de ropa cuando no estés en una misión.
-[CRED077]
-LAURA PATERSON
+[HELP30]
+Cuando compres ropa nueva, tu nivel de se busca se establecerá en cero.
-[CRED078]
-JEFF CASTANEDA
+[ASM4_24]
+distancia:
-[CRED079]
-CHRIS CARRO
+[RBM1_6]
+~g~Lleva a Mercedes y el ''love juice'' a la banda en el estudio de grabación.
-[CRED080]
-ADAM TEDMAN
+[HELP31]
+Para hacer una pasada, mira primero a izquierda o derecha con ~k~~VEHICLE_LOOKLEFT~ o ~k~~VEHICLE_LOOKRIGHT~.
-[CRED081]
-JUNG KWAK
+[HELP34]
+Para realizar una pasada deberás tener un subfusil.
-[CRED082]
-BRIAN WOOD
+[STRIP_1]
+~r~No tienes dinero suficiente, tacaño miserable.
-[CRED083]
-PAUL YEATES
+[EXIT_1]
+Pulsa ~k~~PED_SPRINT~ para salir.
-[CRED084]
-STANTON SARJEANT
+[ASM1_B]
+Encontrará su siguiente trabajo pegado con cinta adhesiva bajo el teléfono.
-[CRED085]
-V.P. DE MÁRKETING
+[ASM1_C]
+Tengo más trabajo para usted que requerirá tomar ''el volante'' de la situación.
-[CRED086]
-TERRY DONOVAN
+[SCARF]
+Apartamento 3c
-[CRED087]
-COORDINADOR TÉCNICO
+[LAW4_10]
+¡Mamones de directores!
-[CRED088]
-BRANDON ROSE
+[RCH1_6]
+~g~Utiliza el helicóptero RC para pasar por los puntos de control dispersados por el aeropuerto.
-[CRED089]
-DIRECTOR DE CONTROL DE CALIDAD
+[RCH1_9]
+~b~TIEMPO TOTAL: ~1~:~1~
-[CRED090]
-JEFF ROSA
+[RCH1_10]
+~b~TIEMPO TOTAL: ~1~:0~1~
-[CRED091]
-JEFE DE ANÁLISIS
+[WHEEL01]
+DOBLE BONIFICACIÓN EN DOS RUEDAS: ~1~ $ Distancia: ~1~,~1~m Tiempo: ~1~ segundos
-[CRED092]
-ADAM DAVIDSON
+[WHEEL02]
+DOBLE BONIFICACIÓN EN DOS RUEDAS: ~1~ $ Distancia: ~1~ pies Tiempo: ~1~ segundos
-[CRED093]
-ANALISTA DEL JUEGO
+[WHEEL03]
+BONIFICACIÓN EN DOS RUEDAS: ~1~ $ Tiempo: ~1~ segundos
-[CRED094]
-RICHARD HUIE
+[WHEEL04]
+BONIFICACIÓN EN DOS RUEDAS: ~1~ $ Distancia: ~1~,~1~m
-[CRED095]
-EQUIPO DE PRUEBAS
+[WHEEL05]
+BONIFICACIÓN EN DOS RUEDAS: ~1~ $ Distancia: ~1~ pies
-[CRED096]
-LANCE WILLIAMS
+[WHEEL06]
+BONIFICACIÓN EN CABALLITO: ~1~ $ Distancia: ~1~,~1~m Tiempo: ~1~ segundos
-[CRED097]
-JOE GREENE
+[WHEEL07]
+BONIFICACIÓN EN CABALLITO: ~1~ $ Distancia: ~1~ pies Tiempo: ~1~ segundos
-[CRED098]
-BRIAN PLANER
+[WHEEL08]
+BONIFICACIÓN EN CABALLITO: ~1~ $ Tiempo: ~1~ segundos
-[CRED099]
-OSWALD GREENE
+[WHEEL09]
+BONIFICACIÓN EN CABALLITO: ~1~ $ Distancia: ~1~,~1~m
-[CRED100]
-EDITORIAL DEL LIBERTY TREE
+[WHEEL10]
+BONIFICACIÓN EN CABALLITO: ~1~ $ Distancia: ~1~ pies
-[CRED101]
-JAMES WORRALL
+[WHEEL11]
+BONIFICACIÓN EN PARADA MÁS LARGA: ~1~ $ Distancia: ~1~,~1~m Tiempo: ~1~ segundos
-[CRED102]
-DAN HOUSER
+[WHEEL12]
+BONIFICACIÓN EN PARADA MÁS LARGA: ~1~ $ Distancia: ~1~ pies Tiempo: ~1~ segundos
-[CRED103]
-ADAM TEDMAN
+[WHEEL13]
+BONIFICACIÓN EN PARADA MÁS LARGA: ~1~ $ Tiempo: ~1~ segundos
-[CRED104]
-PAUL YEATES
+[WHEEL14]
+BONIFICACIÓN EN PARADA MÁS LARGA: ~1~ $ Distancia: ~1~,~1~m
-[CRED105]
-JENEFER GROSS
+[WHEEL15]
+BONIFICACIÓN EN PARADA MÁS LARGA: ~1~ $ Distancia: ~1~ pies
-[CRED106]
-LAURA PATERSON
+[ROK3_72]
+¡Love Fist!
-[CRED107]
-CINEMÁTICAS
+[POR1_19]
+¡Eh!
-[CRED108]
-GUIÓN DE DAN HOUSER Y JAMES WORRALL
+[DESPERA]
+Desesperado
-[CRED109]
-AUDIO DIRIGIDO POR DAN HOUSER
+[MOB_99A]
+Ve hasta el teléfono público junto al centro comercial en Washington.
-[CRED110]
-AUDIO PRODUCIDO POR RENAUD SEBBANE
+[MOB_98A]
+Ve hasta el teléfono público en Vice Point.
-[CRED111]
-REPARTO
+[MOB_96A]
+Ve hasta el teléfono público en la terminal del aeropuerto.
-[CRED112]
-FRANK VINCENT - SALVATORE LEONE
+[MOB_95A]
+Ve hasta el teléfono público en Little Havana.
-[CRED113]
-JOE PANTOLIANO - LUIGI GOTERELLI
+[BNK1_1]
+¿Le puedo ayudar, señor?
-[CRED114]
-MICHAEL MADSEN - TONI CIPRIANI
+[BNK1_2]
+¡Hay un impostor!
-[CRED115]
-MICHAEL RAPAPORT - JOEY LEONE
+[BNK1_3]
+¡Se ha vuelto loco!
-[CRED116]
-DEBBI MAZAR - MARÍA
+[BNK1_4]
+¿Quién demonios eres?
-[CRED117]
-KYLE MACLACHAN - DONALD LOVE
+[BNK1_5]
+¿Dónde está tu placa?
-[CRED118]
-ROBERT LOGGIA - RAY MACHOWSKI
+[BNK1_6]
+¡Ahí están! ¡Dispara a matar!
-[CRED119]
-GURU - 8-BALL
+[MOB_24A]
+Hola, ¿Sr. Vercetti?
-[CRED120]
-SONDRA JAMES - MAMMA
+[MOB_24B]
+Sí.
-[CRED121]
-LIANA PAI - ASUKA
+[MOB_24C]
+Soy Cortez. Usted estuvo en mi fiesta.
-[CRED122]
-LES MAU - KENJI
+[MOB_24D]
+Sí, lo recuerdo.
-[CRED123]
-CYNTHIA FARRELL - CATALINA
+[MOB_24E]
+Sr. Vercetti, ha sido un desgraciado incidente lo que ocurrió con su operación de negocios.
-[CRED124]
-AL ESPINOSA - MIGUEL
+[MOB_24F]
+Lo sé.
-[CRED125]
-CHRIS PHILLIPS - EL BURRO
+[MOB_24G]
+Quiero que sepa que tanto yo como mi gente estamos haciendo todo lo que podemos para llegar al fondo de este tema.
-[CRED126]
-HUNTER PLATIN - CHICO
+[MOB_24H]
+Si desea hablar conmigo de manera más privada, me podrá encontrar en el barco. Buenos días, señor.
-[CRED127]
-WALTER MUDU - D-ICE
+[BNK2_6]
+¡Este tío está chalado!
-[CRED128]
-CURTIS MCCLARIN - CURTLY
+[ANGEL]
+Ángel
-[CRED129]
-BILL FIORE - DARKEL
+[CUBJET]
+Jetmax Cubano
-[CRED130]
-CHRIS PHILLIPS - MARTY CHONKS
+[SANDKIN]
+Sandking
-[CRED131]
-HUNTER PLATIN - CURLY BOB
+[POLMAV]
+Maverick de la policía
-[CRED132]
-WALTER MUDU - REY COURTNEY
+[BOXVILL]
+Boxville
-[CRED133]
-HUNTER PLATIN - PHIL EL MANCO
+[BENSON]
+Benson
-[CRED134]
-KIM GURNEY - MISTY
+[HOTRINA]
+Corredor de Hotring
-[CRED135]
-CAPTURA DE MOVIM.
+[HOTRINB]
+Corredor de Hotring
-[CRED136]
-ANIMACIÓN
+[BLOODRA]
+Coche de Bloodring
-[CRD136A]
-ALEX HORTON
+[BLOODRB]
+Coche de Bloodring
-[CRED137]
-DIRECCIÓN
+[MAFIACR]
+Yate de la Mafia
-[CRD137A]
-NAVID KHONSARI
+[COP_M2]
+ANTI VICIO
-[CRED138]
-PRODUCCIÓN
+[COP_M3]
+TRUENO MARRÓN
-[CRD138A]
-JAMIE KING
+[BNK3_2]
+No voy a conducir por ti, ni soñando, voy a compartir esto con el grupo.
-[CRD138B]
-RENAUD SEBBANE
+[FEM_SL1]
+No hay archivo 1 guardado
-[CRED139]
-GRABADA EN MODERN UPRISING STUDIOS, BROOKLYN
+[FEM_SL2]
+No hay archivo 2 guardado
-[CRED140]
-ACTORES
+[FEM_SL3]
+No hay archivo 3 guardado
-[CRD140A]
-RENAUD SEBBANE
+[FEM_SL4]
+No hay archivo 4 guardado
-[CRD140B]
-GISELLE JONES
+[FEM_SL5]
+No hay archivo 5 guardado
-[CRD140C]
-STEPHEN DANIELS
+[FEM_SL6]
+No hay archivo 6 guardado
-[CRD140D]
-ROBERT STIO
+[FEM_SL7]
+No hay archivo 7 guardado
-[CRD140E]
-JENNY GROSS
+[FEM_SL8]
+No hay archivo 8 guardado
-[CRED141]
-DIÁLOGO DE PEATONES
+[FEA_CHA]
+Cambiando la salida de audio a ESTÉREO. Espera...
-[CRED142]
-ESCRITO POR DAN HOUSER, NAVID KHONSARI Y JAMES WORRALL
+[FEA_CHD]
+¡Aviso! Estás cambiando la salida de ESTÉREO a DTS. Espera...
-[CRED143]
-DIRIGIDO POR CRAIG CONNER, DAN HOUSER Y LAZLOW
+[FEI_SEL]
+Selec.
-[CRED144]
-PRODUCIDO POR RENAUD SEBBANE
+[FEI_BAC]
+Atrás
-[CRED145]
-REPARTO
+[FEI_RES]
+Reanudar
-[CRED146]
-HUNTER PLATIN
+[FEI_NAV]
+Navegar
-[CRED147]
-DAN HOUSER
+[FEI_BTX]
+botón / -
-[CRED148]
-RENAUD SEBBANE
+[FEI_BTT]
+botón " -
-[CRED149]
-MARIA CHAMBERS
+[FEI_STA]
+Botón START -
-[CRED150]
-JEFF STANTON
+[FEI_BTD]
+; = > < -
-[CRED151]
-RYAN CROY
+[FEI_STO]
+Parar
-[CRED152]
-DEENA BERMAN
+[MOB_68A]
+Tommy, tío, tengo una sorpresa para ti.
-[CRED153]
-MARIA CHAMBERS
+[MOB_68B]
+Me encuentro en el estudio de grabación con unos artistas importantes.
-[CRED154]
-ALICE B. SALTZMAN
+[MOB_68C]
+¿Por qué no te vienes por aquí?
-[CRED155]
-ALEX ANTHONY SIOUKAS
+[MOB_68D]
+Sabes que esto tiene sentido, ¿a que sí? Hasta dentro de un rato.
-[CRED156]
-SEAN R. LYNCH
+[OUTFT1]
+Calle
-[CRED157]
-AMY SALZMAN
+[OUTFT2]
+Etiqueta
-[CRED158]
-COLIN MCSHANE
+[OUTFT3]
+Mono de trabajo
-[CRED159]
-COREY WADE
+[OUTFT4]
+Club de campo
-[CRED160]
-GERALD COSGROVE
+[OUTFT5]
+Habana
-[CRED161]
-STEPHANIE ROY
+[OUTFT6]
+Policía
-[CRED162]
-DORIS WOO
+[OUTFT7]
+Atraco al banco
-[CRED163]
-JOSEPH GREENE
+[OUTFT8]
+Informal
-[CRED164]
-LAZLOW JONES
+[OUTFT9]
+Sr. Vercetti
-[CRED165]
-HSIANG LIN
+[OUTFT10]
+Chándal
-[CRED166]
-STEVE MICHAEL ROBERT
+[OUTFT13]
+MC Tommy
-[CRED167]
-MATHEW MURRAY
+[CAR_AS1]
+CONCESIONARIO DE COCHES CONSOLIDADO
-[CRED168]
-RICHARD HUIE
+[CAR_AS2]
+~g~El Concesionario de coches Sunshine generará ahora unos ingresos de hasta ~1~ $ máximo. Asegúrate de recaudarlos regularmente.
-[CRED169]
-GARVIN ATWELL
+[BUYSAVE]
+~g~A partir de ahora, podrás guardar tu partida aquí cuando no estés en una misión.
-[CRED170]
-STEVE KNEZEVICH
+[BUYGARG]
+~g~También puedes almacenar vehículos en este garaje.
-[CRED171]
-YUKIMURA SATO
+[STRPBUY]
+Adquirido el club Pole Position: ~1~ $
-[CRED172]
-FRANK CHAVEZ
+[GA_4]
+Las bombas de coche son 500 $ cada una.
-[CRED173]
-LIEZL JACINTO
+[GA_5]
+Tu coche ya está equipado con una bomba.
-[CRED174]
-CANAAN MCKOY
+[GA_6] { reVC update }
+¡Apárcalo, actívala pulsando ~h~~k~~VEHICLE_FIREWEAPON~~w~ y SAL PITANDO!
-[CRED175]
-ADAM DAVIDSON
+[GA_7] { reVC update }
+¡Ármalo pulsando ~h~~k~~VEHICLE_FIREWEAPON~~w~. La bomba explotará cuando se arranque el motor.
-[CRED176]
-LANCE WILLIAMS
+[GA_6B] { reVC update }
+¡Apárcalo, actívala pulsando ~h~~k~~VEHICLE_FIREWEAPON~~w~ y SAL PITANDO!
-[CRED177]
-NEIL MCCAFFREY
+[GA_7B] { reVC update }
+¡Ármalo pulsando ~h~~k~~VEHICLE_FIREWEAPON~~w~. La bomba explotará cuando se arranque el motor.
-[CRED178]
-LAURA PATERSON
+[MOB_70A]
+Tommy, soy yo, el coronel Cortez. Mira, me parece que eres la clase de hombre que lleva a cabo los trabajos. Así que ayúdame, por favor.
-[CRED179]
-REY CONCEPCION
+[MOB_70B]
+Me podrás encontrar en el barco.
-[CRED180]
-CHARLES HEROLD
+[PICK1]
+¡El chaleco antibalas ha sido entregado en el hotel Ocean View!
-[CRED181]
-ANDREW GREENWALD
+[PICK2]
+¡La .357 ha sido entregada en el hotel Ocean View!
-[CRED182]
-JAMES MIELKE
+[PICK3]
+¡La sierra mecánica ha sido entregada en el hotel Ocean View!
-[CRED183]
-PETER SUCIU
+[PICK4]
+¡El lanzallamas ha sido entregado en el hotel Ocean View!
-[CRED184]
-ALEX ODULIO
+[PICK5]
+¡El rifle de francotirador .308 ha sido entregado en el hotel Ocean View!
-[CRED185]
-DON NKRUMAH
+[PICK6]
+¡La Ametralladora Pesada ha sido entregada en el hotel Ocean View!
-[CRED186]
-KENDALL PITTMAN
+[PICK7]
+¡El lanzacohetes ha sido entregado en el hotel Ocean View!
-[CRED187]
-SAL SUAZO
+[PICK8]
+¡El Sea Sparrow está ahora disponible en la mansión de Starfish Island!
-[CRED188]
-EREK MATEO
+[PICK9]
+¡El tanque está ahora disponible en los cuarteles del ejército!
-[CRED189]
-CHRIS DIFATE
+[PICK10]
+¡El Hunter está ahora disponible en los cuarteles del ejército!
-[CRED190]
-LEILA MILTON
+[CLOTH1]
+El traje de etiqueta ha sido entregado en Rafaels en Ocean Beach.
-[CRED191]
-DARREN ZOLTOWSKI
+[CLOTH2]
+El traje de calle ha sido entregado en los pisos francos.
-[CRED192]
-VIRGINIA SMITH
+[CLOTH3]
+El mono de trabajo ha sido entregado en Tooled Up en el centro comercial de North Point.
-[CRED193]
-KEVIN CASSIN
+[CLOTH4]
+El traje del club de campo ha sido entregado en el club de golf de Leaf Links.
-[CRED194]
-JASON SHIGEMORI
+[CLOTH5]
+El traje Havana ha sido entregado en la tienda de ropa de Little Havana.
-[CRED195]
-KELLY KINSELLA
+[CLOTH6]
+El traje de policía ha sido entregado en la jefatura de policía de Washington Beach.
-[CRED196]
-MOLLIE STICKNEY
+[CLOTH7]
+El traje informal ha sido entregado en Gash del centro comercial de North Point.
-[CRED197]
-STANTON SARJEANT
+[CLOTH8]
+El traje del Sr. Vercetti ha sido entregado en Collar & Cuffs de Ocean Beach.
-[CRED198]
-LAURA WALSH
+[CLOTH9]
+El chándal ha sido entregado en Jocksport del centro de la ciudad.
-[CRED199]
-MARK GARONE
+[CLOTH10]
+El traje para el atraco al banco ha sido entregado en el Club Malibu de Vice Point.
-[CRED200]
-JOANNA SLY
+[MOB_62A]
+Tommy, soy Ricardo Díaz, quiero darte las gracias por cuidar de mí, tío.
-[CRED201]
-ELIZABETH HOWELL
+[MOB_62B]
+He preguntado al gilipollas de Cortez, y me ha dicho que eres bueno, amigo, ¿por qué no vienes a verme?
-[CRED202]
-ANA HERCULES
+[MOB_62C]
+Necesito un tío como tú. Todos los que tengo son gilipollas perdidos,
-[CRED203]
-SHIRLEY IRICK
+[MOB_62D]
+gilipollas por todas partes, tío. Yo te puedo hacer muy rico.
-[CRED204]
-KASHONA FIELDS
+[GOAWAY2]
+~g~Regresa cuando hayas terminado las misiones de la banda de moteros.
-[CRED205]
-JOEL M. LILJE
+[COL2_9]
+¡Estúpido americano! ¡Te han seguido hasta aquí!
-[CRED206]
-JOHN DIBENEDETTO
+[LOADCOL]
+Cargando...
-[CRED207]
-NANCY GILES
+[STFT_17]
+Tiempo más rápido en la ''Prueba PCJ''
-[CRED208]
-RYAN CROY
+[STFT_18]
+Tiempo más rápido en el ''Trial de tierra''
-[CRED209]
-JENNIFER KOLBE
+[STFT_19]
+Tiempo más rápido en la ''Pista de Pruebas''
-[CRED210]
-LIAM BURKE
+[NEW_REC]
+¡Nuevo récord establecido! ~w~~1~ minutos ~g~y ~w~~1~ segundos.
-[CRED211]
-SIGRID PREISSL
+[BMX_HOW]
+~g~¡Da dos vueltas a la pista de tierra, ~y~pasando por ~g~los ~y~PUNTOS DE CONTROL ~g~por el camino!
-[CRED212]
-ANITA FITZSIMONS
+[BMXREW1]
+~g~¡Cada vez que batas tu récord anterior de las dos vueltas
-[CRED213]
-PHILIPPA RASELLI
+[BMXREW2]
+~g~conseguirás una ~y~RECOMPENSA ~g~mejor!
-[CRED214]
-WIL QUESNEL
+[BMXRAIN]
+~g~Parece lluvia...
-[CRED215]
-FALKO BURKERT
+[ITBEG]
+Al principio...
-[CRED216]
-SARA SEWELL
+[NBMNBUY]
+Casa Swanko adquirida: ~1~ $
-[CRED217]
-EMISORAS DE RADIO Y MÚSICA
+[LNKVBUY]
+Apartamento en Links View adquirido: ~1~ $
-[CRED218]
-PRODUCTORES DE ROCKSTAR REINO UNIDO
+[HYCOBUY]
+Piso de Hyman adquirido: ~1~ $
-[CRD218A]
-CRAIG CONNER
+[BUYGARS]
+~g~Puedes guardar vehículos en estos garajes.
-[CRD218B]
-STUART ROSS
+[OCHEBUY]
+Apartamento de Ocean Heights adquirido: ~1~ $
-[CRED219]
-COORDINADOR DE BANDA SONORA
+[WASHBUY]
+1102 de la calle Washington adquirido: ~1~ $
-[CRED220]
-TERRY DONOVAN
+[VCPTBUY]
+3321 de Vice Point adquirido: ~1~ $
-[CRED221]
-PRODUCTOR DE ROCKSTAR GAMES
+[SKUMBUY]
+Chabola Skumole adquirida: ~1~ $
-[CRED222]
-DAN HOUSER
+[HELP6_C]
+Pulsa ~h~~k~~VEHICLE_HANDBRAKE~~w~ para usar el freno de mano del vehículo.
-[CRED223]
-EDICIÓN
+[HELP2_A]
+Pulsa ~h~~k~~PED_SPRINT~~w~~w~ cuando estés corriendo para ~h~esprintar.
-[CRED224]
-CRAIG CONNER
+[HELP4_A]
+Pulsa ~h~~k~~VEHICLE_ACCELERATE~~w~ para acelerar.
-[CRED225]
-ALLAN WALKER
+[HELP5_A]
+Pulsa ~h~~k~~VEHICLE_BRAKE~~w~ para frenar o para dar marcha atrás si el vehículo se ha detenido.
-[CRED226]
-LAZLOW
+[HELP8_A]
+Pulsa ~h~~k~~PED_SNIPER_ZOOM_IN~~w~ para hacer zoom con el rifle y ~h~~k~~PED_SNIPER_ZOOM_OUT~~w~ para alejar la vista.
-[CRED227]
-GUIÓN DE LOCUTORES Y CUÑAS
+[PBOAT_1] { reVC update }
+Pulsa ~h~ ~k~~VEHICLE_FIREWEAPON~~w~ para disparar los cañones del barco.
-[CRED228]
-DAN HOUSER
+[SEG3_4] { reVC update }
+~g~Puedes recoger bombas simplemente pilotando tu Helicóptero RC cerca de cada una de ellas, para soltar una bomba pulsa ~h~~k~~VEHICLE_FIREWEAPON~~g~.
-[CRED229]
-LAZLOW
+[RCR1_3] { reVC update }
+~g~Si quieres abandonar esta misión, pulsa ~h~~k~~VEHICLE_FIREWEAPON~~g~ para detonar tu coche RC.
-[CRED230]
-AGRADECIMIENTOS
+[HELP32] { reVC update }
+A continuación dispara pulsando ~h~~k~~VEHICLE_FIREWEAPON~.
-[CRED231]
-ADAM TEDMAN
+[HELP33] { reVC update }
+A continuación dispara pulsando ~h~~k~~VEHICLE_FIREWEAPON~.
-[CRED232]
-ALEX MASON
+[TTUTOR]
+Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para comenzar o cancelar las misiones de taxista.
-[CRED233]
-JUDY HENDERSON CASTING
+[TTUTOR2]
+Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para comenzar o cancelar las misiones de taxista.
-[CRED234]
-HAMISH BROWN
+[FTUTOR]
+Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para comenzar o cancelar las misiones del camión de bomberos.
-[CRED235]
-CHRISSY HOBAN
+[FTUTOR2]
+Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para comenzar o cancelar las misiones del camión de bomberos.
-[CRED236]
-INNES RICARD
+[CTUTOR]
+Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para comenzar o cancelar las misiones de justiciero.
-[CRED237]
-LILION BROZSKA
+[CTUTOR2]
+Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para comenzar o cancelar las misiones de justiciero.
-[CRED238]
-BOB HILLARY
+[HELP8_B]
+Pulsa ~h~~k~~PED_SNIPER_ZOOM_IN~ ~w~para ~h~acercar la vista ~w~con el rifle y ~h~~k~~PED_SNIPER_ZOOM_OUT~ ~w~para ~h~alejar la vista ~w~otra vez.
-[CRED239]
-EMILY ANDERSON
+[ATUTOR3]
+Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para comenzar o cancelar las misiones de ATS.
-[CRED240]
-RICHIE HENDERSON
+[GUN_H1]
+~w~Pulsa ~h~~k~~PED_SPRINT~~w~ para comprar. ~w~Pulsa ~h~~k~~VEHICLE_ENTER_EXIT~~w~ para salir.
-[CRED241]
-CHRISTIAN CANTAMESSA
+[PU_CF3] { reVC update }
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para reemplazar tu arma actual en esta ranura.
-[CRED242]
-JERONIMO BARRERA
+[PU_CF4] { reVC update }
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para reemplazar tu arma actual en esta ranura.
-[CRED243]
-ALEXANDER ILLES
+[HELP9_B]
+Pulsa ~h~~k~~PED_FIREWEAPON~ ~w~para ~h~disparar~w~ el rifle de francotirador.
-[CRED244]
-BARANE CHAN
+[HELP37]
+Si no quieres subir al coche mientras se lo estás robando a alguien, pulsa ~h~~k~~PED_SPRINT~.
-[CRED245]
-DUNCAN SHIELDS
+[HELP6_A]
+Pulsa ~h~~k~~VEHICLE_HANDBRAKE~~w~ para usar el freno de mano del vehículo.
-[CRED246]
-BARANE CHAN
+[HELP6_D]
+Pulsa ~h~~k~~VEHICLE_HANDBRAKE~~w~ para usar el freno de mano del vehículo.
-[CRED247]
-DEREK PAYNE
+[HELP26]
+Pulsa ~h~~k~~VEHICLE_ENTER_EXIT~~w~ para subir o bajar de un vehículo.
-[CRED248]
-KEVIN WONG
+[HELP27]
+Pulsa ~h~~k~~VEHICLE_TURRETUP~~w~ o ~h~~k~~VEHICLE_TURRETDOWN~~w~ para equilibrar tu peso en la moto.
-[CRED249]
-ROSS ELLIOTT
+[HELP28]
+Pulsa ~h~~k~~VEHICLE_TURRETUP~~w~ o ~h~~k~~VEHICLE_TURRETDOWN~~w~ para equilibrar tu peso en la moto.
-[CRED250]
-ROSS BEAZLEY
+[HELP35]
+Pulsa ~h~~k~~GO_LEFT~~w~ o ~h~~k~~GO_RIGHT~~w~ para conducir el vehículo.
-[CRED251]
-ALEX BAZLINTON
+[HELP36]
+Pulsa ~h~~k~~GO_LEFT~~w~ o ~h~~k~~GO_RIGHT~~w~ para conducir el vehículo.
-[CRED252]
-DAVE WATSON
+[HELP42]
+Ve al ~q~icono rosa~w~ para encontrar el hotel.
-[CRED253]
-MALCOLM SMITH
+[HELP19]
+Camina hasta el ~q~marcador rosa~w~ para continuar.
-[CRED255]
-ANDREW SEMPLE
+[HELP1]
+Párate en el centro del ~q~marcador rosa.
-[CRED256]
-ARTISTAS
+[HELP12]
+Camina hasta el centro del ~q~marcador rosa~w~ para activar una misión.
-[CRED257]
-STUART PETRI
+[SEG3_6]
+~g~Para acertar en una zona objetivo con éxito, deberás soltar una bomba en la zona representada por el ~q~marcador rosa~w~. Puedes soltar las bombas en cualquier orden.
-[CRED258]
-JERONIMO BARRERA
+[S_PROMP]
+Cuando no estés en una misión podrás guardar tu progreso recogiendo las ~h~cintas de cassette~w~.
-[CRED259]
-CARLY SLATER
+[HELP16]
+Cruza la puerta principal del hotel ~h~Ocean View~w~ para entrar en el edificio.
-[CRED260]
-GREG LAU
+[HELP43]
+~g~Ve al hotel ~h~Ocean View~g~ en Ocean Drive.
-[CRED261]
-STEVE KNEZEVICH
+[HELI_F1]
+~r~¡Misión de puntos de control cancelada!
-[CRED262]
-DEVIN WINTERBOTTOM
+[AMMUHLP]
+Si necesitas armas pásate por ~h~Ammu-Nation~w~. Está indicado en el radar como una ~h~pistola~w~ azul.
-[CRED263]
-JAMEEL VEGA
+[HELI_1]
+Control del Helicóptero de Centro de la ciudad
-[CRED264]
-LEE CUMMINGS
+[HELI_2]
+Control del Helicóptero de Ocean Beach
-[CRED265]
-DEVIN BENNET
+[HELI_3]
+Control del Helicóptero de Vice Point
-[CRED266]
-ELIZABETH SATTERWHITE
+[HELI_4]
+Control del Helicóptero de Little Haiti
-[CRED267]
-AARON RIGBY
+[FST_MFR]
+Emisora de radio preferida
-[CRED268]
-STEVE K.
+[FST_LFR]
+Emisora de radio menos escuchada
-[CRED269]
-GREG LAU
+[FEI_HOL]
+Mantener
-[CINCAM]
-Cámara cinematográfica
+[FEI_ZOO]
+Zoom
-[KM1_13]
-¡Mete el vehículo en el garaje!
+[FEI_BTR]
+> < -
-[KM3_14]
-~r~¡Te han descubierto, han cancelado el trato!
+[FEI_NA]
+N\A
-[EBAL_H]
-Espera, tío, que voy a hablar con Luigi.
+[MESA]
+Mesa Grande
-[EBAL_M]
-¡Recuerda: nadie se mete con mis chicas!
+[STRP_NO]
+No puedes comprar el club de striptease en este momento, vuelve luego.
-[LM2_F]
-Luego coge su coche y repíntalo.
+[CHSE]
+PERSECUCIÓN
-[LM2_D]
-Toma, toma, para ti.
+[NBMN_L]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar la casa Swanko por ~1~ $.
-[LM1_9]
-Hola, soy Misty.
+[NBMN_T]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar la casa Swanko por ~1~ $.
-[LM4_A]
-Algún Diablo de las narices ha estado vendiendo a sus putitas en mi territorio.
+[NBMN_C]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar la casa Swanko por ~1~ $.
-[FM2_B]
-¡Tenemos a un chivato!
+[LNKV_L]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el apartamento de Links View por ~1~ $.
-[FM2_C]
-No está ni chuleando ni traficando, así que estará cantando.
+[LNKV_T]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el apartamento de Linsk View por ~1~ $.
-[FM3_CC]
-Regresa cuando tengas el dinero.
+[LNKV_C]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el apartamento de Links View por ~1~ $.
-[FEDS_AM]
-<> - CAMBIAR MENÚ
+[HYCO_L]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el piso de Hyman por ~1~ $.
-[LOVE5_5]
-~r~¡No has protegido al camión!
+[HYCO_T]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el piso de Hyman por ~1~ $.
-[RM6_6]
-~r~¡Ray ha muerto!
+[HYCO_C]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el piso de Hyman por ~1~ $.
-[RM6_7]
-~r~¡Ray ha perdido su avión!
+[OCHE_L]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el apartamento de Ocean Heights por ~1~ $.
-[RM6_8]
-~g~Has abandonado a Ray, vuelve a por él.
+[OCHE_T]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el apartamento de Ocean Heights por ~1~ $.
-[FM1_10]
-~g~Has abandonado a María, vuelve a por ella.
+[OCHE_C]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el apartamento de Ocean Heights por ~1~ $.
-[LOVE4_9]
-~r~¡El avión ha sido destruido!
+[WASH_L]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el 1102 de la calle Washington por ~1~ $.
-[LOV4_10]
-~r~¡La única pista sobre dónde se encuentra el paquete ha sido destruida!
+[WASH_T]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el 1102 de la calle Washington por ~1~ $.
-[KM2_D]
-No hace falta decir que debemos darle los coches como un regalo para pagar mi deuda con él.
+[WASH_C]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el 1102 de la calle Washington por ~1~ $.
-[KM4_B]
-El negocio es lo bastante afortunado como para permitir que nuestra protección salde sus cuentas hoy mismo.
+[VCPT_L]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el 3321 de Vice Point por ~1~ $.
-[KM2_E]
-Debes obtener los coches de la lista y llevarlos a un garaje que hay tras el aparcamiento de Newport.
+[VCPT_T]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el 3321 de Vice Point por ~1~ $.
-[FM3_8I]
-Encuentra una posición elevada. Entraré cuando dispares el primer tiro.
+[VCPT_C]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el 3321 de Vice Point por ~1~ $.
-[LOVE1_B]
-La experiencia me ha enseñado que un hombre como tú puede ser muy leal por el precio correcto,
+[SKUM_L]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar la chabola Skumole por ~1~ $.
-[LOVE1_H]
-pero los grupos de hombres se vuelven codiciosos.
+[SKUM_T]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~para comprar la chabola Skumole por ~1~ $.
-[LOVE1_C]
-Un activo valioso, un anciano oriental que conozco,
+[SKUM_C]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~ ~w~ para comprar la chabola Skumole por ~1~ $.
-[LOVE1_I]
-está siendo retenido por unos sudamericanos en Aspatria.
+[PRNT_L]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar la imprenta por ~1~ $.
-[MEA4_D]
-He quedado con él,
+[PRNT_T]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar la imprenta por ~1~ $.
-[MEA4_B4]
-¿Te envía Marty? Vale, le voy a enseñar a ese sinvergüenza el significado de la palabra negocio.
+[PRNT_C]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar la imprenta por ~1~ $.
-[MEA4_B5]
-¡Carl, hola! Ehhh... Necesito más tiempo para conseguir tu dinero.
+[CAR_L]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el concesionario de coches por ~1~ $.
-[MEA1_B4]
-Ah, te envió el Sr. Chonks, ¿verdad? Vayamos a visitarlo.
+[CAR_T]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el concesionario de coches por ~1~ $.
-[HM5_6]
-Vamos a partir cabezas...
+[CAR_C]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el concesionario de coches por ~1~ $.
-[LOVE1_5]
-~g~Deja de perder el tiempo, hazte con un coche de los colombianos y rescata al socio de Love.
+[PORN_L]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar los estudios de cine por ~1~ $.
-[AS1_D]
-Haz de cebo y consigue que los escuadrones te sigan hasta Pike Creek,
+[PORN_T]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar los estudios de cine por ~1~ $.
-[AS1_E]
-donde estarán esperando algunos de mis hombres.
+[PORN_C]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar los estudios de cine por ~1~ $.
-[AS2_C]
-El cártel tiene una tapadera, el Kappa Coffee House.
+[ICE_L]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar la fábrica de helados por ~1~ $.
-[AS2_E]
-No tenemos otra opción más que sabotear esos puntos de venta.
+[ICE_T]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar la fábrica de helados por ~1~ $.
-[AS2_F]
-¡Redúcelos a cenizas!
+[ICE_C]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar la fábrica de helados por ~1~ $.
-[AS2_A1]
-¡Está claro que Miguel tiene esa famosa resistencia latina!
+[TAXI_L]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar la compañía de taxis por ~1~ $.
-[AS2_A2]
-Estoy agotada.
+[TAXI_T]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar la compañía de taxis por ~1~ $.
-[SIREN_3]
-Para activar la sirena de este vehículo, pulsa ~h~~k~~VEHICLE_HORN~~w~.
+[TAXI_C]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar la compañía de taxis por ~1~ $.
-[SIREN_4]
-Para activar la sirena de este vehículo, pulsa ~h~~k~~VEHICLE_HORN~~w~.
+[BANK_L]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el Malibú por ~1~ $.
+
+[BANK_T]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el Malibú por ~1~ $.
+
+[BANK_C]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el Malibú por ~1~ $.
-[AS3_C]
-¡Buaj! ¿Qué es esa cosa amarilla pegajosa?
+[BOAT_L]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el astillero por ~1~ $.
-[AS3_C1]
-¡Hola, guapo!
+[BOAT_T]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el astillero por ~1~ $.
-[AS3_F]
-Esta chica tiene un talento nato para la tortura.
+[BOAT_C]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el astillero por ~1~ $.
-[AS3_F1]
-Se las ha arreglado para extraerle esta joyita a nuestro invitado.
+[STRP_L]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el club Pole Position por ~1~ $.
-[AS3_G]
-Hay una avioneta que llegará al Aeropuerto Francis en dos horas.
+[STRP_T]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el club Pole Position por ~1~ $.
-[AS3_G1]
-Está llena del veneno de Catalina.
+[STRP_C]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el club Pole Position por ~1~ $.
-[AS3_H]
-Podrás evitar la seguridad del aeropuerto si conduces una lancha hasta las boyas luminosas,
+[STOCK]
+~r~Agotado
-[AS3_H1]
-así podrás disparar a la avioneta al aterrizar.
+[HELP14]
+Para encontrar el bufete del abogado, ve hacia la ~h~señal de la L~w~ que hay en el radar.
-[AS3_I]
-¡Recoge el cargamento de entre los escombros y tráelo!
+[RAMPAGE]
+¡MASACRE!
-[AS3_J]
-Ten cuidado, guapo, ¿vale?
+[RAMP_F]
+¡MASACRE FALLIDA!
-[AS3_K]
-Ahora prueba con el aceite picante...
+[RAMP_P]
+¡MASACRE COMPLETADA!
-[RM2_F1]
-¡Los colombianos llegarán en cualquier momento!
+[RAMP_A]
+¡TODAS LAS MASACRES COMPLETADAS!
-[RM2_K]
-Maldita sea, ¡están aquí! ¡FUEGO A DISCRECIÓN!
+[PAGE_01]
+¡Liquida a ~1~ criminales en 2 minutos!
-[LOVE2_7]
-~g~¡Ahora deshazte del coche!
+[PAGE_02]
+¡Destruye ~1~ vehículos en 2 minutos!
-[LOVE2_8]
-~g~¡Sal de Newport!
+[PAGE_03]
+¡Pasa en el coche y cárgate a ~1~ criminales en 2 minutos!
-[AM1_F]
-Salvatore Leone saldrá del club de Luigi dentro de unas tres horas. (~1~:~1~)
+[PAGE_04]
+¡Atropella y mata a ~1~ criminales en 2 minutos!
-[LOVE5_C]
-Quiero que le sigas y que te asegures de que tanto él como mi paquete llegan a Pike Creek sin daño alguno.
+[PAGE_05]
+¡Abate a tiros a ~1~ criminales en 2 minutos!
-[FESZ_SR]
-¡Error al guardar! Comprueba la Memory Card (PS2) de la ranura de MEMORY CARD 1 e inténtalo de nuevo.
+[SENTXS]
+Sentinel XS
-[FESZ_FO]
-¿Deseas formatear la Memory Card (PS2) en la ranura de MEMORY CARD 1?
+[MAP_LEG]
+Leyenda
-[FELZ_FO]
-La Memory Card (PS2) de la ranura de MEMORY CARD 1 no tiene formato.
+[VCNMAV]
+VCN Maverick
-[FES_NOC]
-No hay una Memory Card (PS2) insertada en la ranura para MEMORY CARD 1.
+[LG_01]
+Posición del jugador
-[FES_LOE]
-¡Fallo al cargar! Comprueba la Memory Card (PS2) de la ranura de MEMORY CARD 1 e inténtalo de nuevo.
+[LG_02]
+Avery Carrington
-[FES_DEE]
-¡Fallo al borrar! Comprueba la Memory Card (PS2) de la ranura de MEMORY CARD 1 e inténtalo de nuevo.
+[LG_03]
+Contacto del motero
-[FORSUC]
-Memory Card (PS2) de la ranura de MEMORY CARD 1 formateada con éxito.
+[LG_04]
+Coronel Cortez
-[ERFOUN]
-¡Error al formatear la Memory Card (PS2)!
+[LG_05]
+Ricardo Díaz
-[ERMCNP]
-No hay Memory Card (PS2) en la ranura de MEMORY CARD 1.
+[LG_06]
+Kent Paul
-[SVMEM1]
-Guardando en la Memory Card (PS2) de la ranura de MEMORY CARD 1.
+[LG_07]
+Abogado
-[FORSLO]
-Formateando Memory Card (PS2) de la ranura de MEMORY CARD 1.
+[LG_08]
+Phil Cassidy
-[SLONFM]
-¡Error al formatear la Memory Card (PS2)!
+[LG_09]
+Astillero
-[SLONDR]
-No hay espacio suficiente en la Memory Card (PS2). Inserta una Memory Card (PS2) con, al menos, 500KB de espacio libre en la ranura de MEMORY CARD 1.
+[LG_10]
+Club Malibú
-[SLNSP]
-No hay espacio suficiente en la Memory Card (PS2). Inserta una Memory Card (PS2) con, al menos, 200KB de espacio libre en la ranura de MEMORY CARD 1.
+[LG_11]
+Cubanos
-[FEFD_WR]
-Formateando la Memory Card (PS2) de la ranura de MEMORY CARD 1. No extraigas la Memory Card (PS2), ni reinicies o apagues la consola.
+[LG_12]
+Estudio Cinematográfico
-[FES_ISF]
-NO PRESENTE
+[LG_13]
+Ammu-Nation
-[FES_SAG]
-PRESENTE
+[LG_14]
+Haitianos
-[SLONNO]
-No hay una Memory Card (PS2) en la ranura de MEMORY CARD 1.
+[LG_15]
+Ferretería
-[SLONNF]
-La Memory Card (PS2) de la ranura de MEMORY CARD 1 no tiene formato.
+[LG_16]
+Piso franco
-[FESZ_FM]
-La Memory Card (PS2) de la ranura de MEMORY CARD 1 no tiene formato. ¿Deseas formatear la Memory Card (PS2)?
+[LG_17]
+Helado
-[FESZ_FF]
-¡Fallo al formatear! Comprueba la Memory Card (PS2) de la ranura de MEMORY CARD 1 e inténtalo de nuevo.
+[LG_18]
+Taxis Kaufman
-[MCDNSP]
-No hay espacio suficiente en la Memory Card (PS2) de la ranura de MEMORY CARD 1. Inserta una Memory Card (PS2) con, al menos, 500KB de espacio libre para guardar los datos de esta aplicación. ¿Deseas empezar? (SÍ o NO)
+[LG_19]
+Love Fist
-[MCGNSP]
-No hay espacio suficiente en la Memory Card (PS2) de la ranura de MEMORY CARD 1. Se necesitan al menos 200KB para guardar los datos de esta aplicación. ¿Deseas empezar? (SÍ o NO)
+[LG_20]
+Imprenta
-[FESZ_WR]
-Guardando datos. No extraigas la Memory Card (PS2) de la ranura de MEMORY CARD 1, ni reinicies o apagues la consola.
+[LG_21]
+Propiedad
-[FESZ_OW]
-Sobrescribiendo datos. No extraigas la Memory Card (PS2) de la ranura de MEMORY CARD 1, ni reinicies o apagues la consola.
+[LG_22]
+Taller de Pintura
-[FELD_WR]
-Cargando datos. No extraigas la Memory Card (PS2) de la ranura de MEMORY CARD 1, ni reinicies o apagues la consola.
+[LG_23]
+Tienda de ropa
-[FEDL_WR]
-Borrando datos. No extraigas la Memory Card (PS2) de la ranura de MEMORY CARD 1, ni reinicies o apagues la consola.
+[LG_24]
+Mansión de Tommy
-[LM2_C]
-Luigi dijo que... que te diera esto...
+[LG_25]
+Teléfono
-[LM3_G]
-que a Joey no le gusta esperar. Recuerda, tienes un pie dentro...
+[LG_26]
+Emisora de radio Wildstyle
-[LM5_E]
-Saca todo el dinero que puedas a los polis antes de que se lo beban.
+[LG_27]
+Emisora de radio Flash FM
-[JM5_C]
-Vale, hay un coche cargado con un fiambre en el bar cercano a Callahan Point.
+[LG_28]
+Emisora de radio Kchat
-[RM2_B]
-Combatimos juntos en Nicaragua, cuando el país sabía lo que hacía.
+[LG_29]
+Emisora de radio Fever 105
-[RM2_C]
-En fin, ayer unos cerdos del cártel lo zurraron y le dijeron que volverían hoy para quitarle parte de su género.
+[LG_30]
+Emisora de radio VRock
-[RM2_D1]
-Iría yo mismo, pero la ciática ya está en sus trece... ¡Cof, cof! Así que... buena suerte.
+[LG_31]
+Emisora de radio VCPR
-[CATINF1]
-~g~¡Liquida a Catalina!
+[LG_32]
+Emisora de radio Espantoso
-[CATINF2]
-~g~Sigue al helicóptero para dar con Catalina.
+[LG_33]
+Emisora de radio Emotion 98.3
-[BOATIN1]
-Sube a una lancha y pulsa ~h~~k~~VEHICLE_ENTER_EXIT~~w~ para ponerte a los mandos.
+[LG_34]
+Emisora de radio Wave 103
-[BOATIN2]
-Puedes pulsar ~h~~k~~VEHICLE_ENTER_EXIT~~w~ si estás cerca de una lancha para abordarla.
+[LG_35]
+Destino
-[BOATIN3]
-Sube a una lancha y pulsa ~h~~k~~VEHICLE_ENTER_EXIT~~w~ para ponerte a los mandos.
+[LG_36]
+Solarium
-[BOATIN4]
-Puedes pulsar ~h~~k~~VEHICLE_ENTER_EXIT~~w~ si estás cerca de una lancha para abordarla.
+[LG_37]
+Club de Striptease
-[JM6]
-'LA HUIDA'
+[LG_38]
+Objetivo
-[FM1]
-'CARABINA'
+[MAP_YAH]
+ESTÁS AQUÍ
-[JM1]
-'EL ÚLTIMO ALMUERZO DE MIKE ''LABIOS'' '
+[TAXSHRT]
+~g~Puedes coger este taxi Kaufman para ir a tu destino sin conducir. Te costará 9 $.
-[FM21]
-'BASE FUERA: ACTO I'
+[FEST_HV]
+Nivel más alto de misión de justiciero
-[FM3]
-'BASE FUERA: ACTO II'
+[CLOHELP]
+¡Ropa limpia!
-[AM1]
-'SAYONARA, SALVATORE'
+[SUNSHIN]
+Coches Sunshine
-[AM2]
-'BAJO VIGILANCIA'
+[CHERRYP]
+Helados Cherry Popper
-[KM2]
-'ROBO DE VEHÍCULOS'
+[KAUFCAB]
+Taxis Kaufman
-[AS3]
-'TIERRA-AIRE'
+[BOATYAR]
+El Astillero
-[RM2]
-'ESCASEZ DE MANOS'
+[WANT_L]
+Has perdido tu nivel de se busca, si cometes un crimen mientras las estrellas parpadean, tu nivel total de se busca se restablecerá.
-[LOVE6]
-'SEÑUELO'
+[FEI_BTU]
+; = -
-[LOVE1]
-'EL LIBERADOR'
+[BOAT_AS]
+~g~El astillero generará ahora unos ingresos hasta un máximo de ~1~ $. Asegúrate de recaudarlos de manera regular.
-[RC1]
-'DESTRUCCIÓN DE LOS DIABLOS'
+[BOAT_A2]
+ASTILLERO COMPLETADO
-[RC2]
-'LA MASACRE DE LA MAFIA'
+[BOAT_N]
+Punto de control Charlie
-[RC3]
-'CALAMIDAD EN EL CASINO'
+[BOAT_P]
+~g~Recoge los paquetes antes de que se acabe el tiempo.
-[RC4]
-'EXTERMINIO DE RUMPOS'
+[FEI_R1B]
+Botón R1 \ R2 -
-[RM2_E1]
-¡No puedo creer que esos mamones amarillos me hayan vuelto a dejar con el culo al aire!
+[HELP9_A]
+Pulsa ~h~~k~~PED_FIREWEAPON~ ~w~para disparar el rifle de francotirador.
-[GREN_1]
-Cuanto más tiempo mantengas pulsado ~h~~k~~PED_FIREWEAPON~~w~, más lejos lanzarás la granada.
+[HELP21]
+Pulsa ~h~~k~~VEHICLE_ENTER_EXIT~ ~w~para subir o bajar de un vehículo.
-[GREN_2]
-Cuanto más tiempo mantengas pulsado ~h~~k~~PED_FIREWEAPON~~w~, más lejos lanzarás la granada.
+[CREAM]
+Distribución
-[GREN_3]
-Cuanto más tiempo mantengas pulsado ~h~~k~~PED_FIREWEAPON~~w~, más lejos lanzarás la granada.
+[UMBERTO]
+Café Robina
-[LOVE4_G]
-Mis pertenencias estarán esperándote en el hangar de aduanas, dentro de la avioneta.
+[PU_CF1]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~ ~w~para recoger esta arma. Reemplazará cualquier arma del mismo tipo que tengas.
-[KABOOM]
-¡BUUUM!
+[FED_RDM]
+MAPA E ICONOS
-[SPLAT]
-¡PLOF!
+[FEC_ILU]
+Invertir vista en primera persona
-[PANCAK]
-¡APLASTADO!
+[NITRO]
+¡Ahora todos los taxis disponen de un impulsor de salto! Simplemente toca el claxon.
-[SOAKED]
-¡AHOGADO!
+[RATNG53]
+Informal
-[HEAD]
-Head Radio
+[RATNG54]
+Vergüenza
-[DBL_CLF]
-Double Clef FM
+[RATNG55]
+Hacker
-[FLASHB]
-Flashback FM
+[RATNG56]
+Liante
-[RISE]
-Rise FM
+[RATNG57]
+Mentiroso compulsivo
-[LIPS]
-Lips 106
+[STHC_04]
+Puntuación más alta por mantener la pelota en el aire en la playa
-[CHAT]
-Chatterbox FM
+[STHC_05]
+Mejor resultado de Hotring
-[K_JAH]
-K-Jah Radio
+[STFT_13]
+Mejor tiempo en el Control del Helicóptero del centro
-[GAM_FM]
-Game Radio FM
+[STFT_14]
+Mejor tiempo en el Control del Helicóptero de Ocean Beach
-[MSX_FM]
-MSX FM
+[STFT_15]
+Mejor tiempo en el Control del Helicóptero de Vice Point
-[TUBE1]
-Cuando abra el metro, podrás usarlo para ir a Staunton Island.
+[STFT_16]
+Mejor tiempo en el Control del Helicóptero de Little Haití
-[TUBE2]
-Cuando abra Shoreside Vale, podrás salir por la terminal Shoreside al Aeropuerto Internacional Francis.
+[STFT_21]
+Tiempo más rápido en Hotring
-[TUBE_2]
-Para subirte a un vagón, pulsa el ~h~botón Entrar al vehículo~w~.
+[STFT_22]
+Vuelta más rápida en Hotring
-[LEGAL]
-~g~¡Elimina la amenaza criminal!
+[STFT_20]
+Tiempo más rápido en el ''Conocircuito''
-[GA_2]
-He cambiado el motor y la mano de pintura. ¡La poli no te reconocerá!
+[HELP44]
+Detente en el ~q~marcador rosa.
-[LM1_8A]
-Si quieres ganar un dinerillo extra, siempre puedes ''coger prestado'' un taxi...
+[HELP45]
+Pulsa ~h~~k~~PED_DUCK~~w~ para agacharte. Esto aumentará tu puntería con las armas que llevas.
-[TAXIH1]
-Para cerca de un peatón señalado para recogerlo y llevarlo a su destino antes de que se acabe el tiempo.
+[RCR1_5]
+Carrera Bandit RC
-[LM5_7]
-~g~¡Luigi no estará contento si hay menos de cuatro chicas trabajando en el ~p~baile de la policía~g~!
+[RCPL1_7]
+Carrera Barón RC
-[KM2_3]
-~g~Recuerda que los ~r~coches ~g~tienen que estar en perfecto estado para ser aceptados en el ~p~garaje~g~.
+[RCH1_11]
+Recogidas del Raider RC
-[KM5_2]
-~g~Uno de los jamaicanos se ha ido.
+[FEA_CTD]
+¡Aviso! Esta característica requiere que el dispositivo compatible DTS esté conectado. ¿Continuar?
-[BETRA_A]
-Lo siento, cariño.
+[FEM_STE]
+UTILIZAR ESTÉREO
-[BETRA_B]
-Soy una chica ambiciosa, ¿pero tú?
+[GREET]
+Saludos desde...
-[BETRA_C]
-Eres un pez pequeñito.
+[LANCE_1]
+¡Venga, tío, conduce con más cuidado!
-[JAILB_Q]
-¡Ándele!
+[LANCE_2]
+¡Eh, mira lo que haces!
-[JAILB_R]
-¡Señor malparido!
+[LANCE_3]
+¿Eh, dónde vamos ahora?
-[JAILB_S]
-No nos importará matarte.
+[LANCE_4]
+¿Qué estamos haciendo ahora?
-[JAILB_T]
-Os vais a arrepentir.
+[LAW4_15]
+¡Más dinero!
-[JAILB_U]
-Bien, bien, piérdete.
+[MERC_5]
+Bonito coche, Mr. Vercetti.
-[HELP15]
-Cuando vayas a pie, mantén pulsado ~h~~k~~PED_LOOKBEHIND~~w~ para~h~ mirar atrás~w~.
+[MERC_26]
+¡DEPRISA, DEPRISA, DEPRISA!
-[FEC_LB3]
-Mirar atrás
+[MERC_27]
+Con cuidado Tommy, me arreglaron la nariz el mes pasado.
-[FEC_R3]
-(botón R3)
+[MERC_28]
+Conduce con cuidado Tommy.
-[FES_AFO]
-Esta Memory Card (PS2) ya está formateada.
+[MERC_29]
+Ve más despacio Tommy.
-[FEA_UP]
-;
+[MERC_30]
+Tommy, si no te importa mata a quien quieras menos a mí.
-[FEA_DO]
-=
+[MERC_31]
+¡Tommy, cielo, no me mates!
-[FEA_LE]
-<
+[MERC_32]
+¡Tommy, me alegro que robaras este coche!
-[FEA_RI]
->
+[MERC_40]
+Me he divertido tanto.
-[FEDSAS3]
-- CAMBIAR SELECCIÓN
+[MERC_43]
+Adiós, mi ángel.
-[FEDSAS4]
-;=<> - CAMBIAR SELECCIÓN
+[MERC_44]
+Ahora sigue machacándote, me oyes.
-[SPRAY_4] { re3 change }
-Pulsa ~h~~k~~VEHICLE_FIREWEAPON~~w~ para disparar el cañón de agua.
+[MERC_45]
+Ciao, guapetón.
-[SPRAY_1] { re3 change }
-Pulsa ~h~~k~~VEHICLE_FIREWEAPON~~w~ para disparar el cañón de agua.
+[COL5_17]
+¡Oh, Dios mío, tienen un helicóptero!
-[LITTLE]
-LITTLE T
+[COL5_18]
+¡Dispara al helicóptero!
-[NICK]
-NICK LOVE
+[COL5_19]
+Tommy, ¡hazte con ese helicóptero!
-[AM1_10]
-~g~Salvatore saldrá del club de Luigi sobre las 0~1~:~1~.
+[COL5_20]
+¡Ahí viene otra vez! ¡Derriba a ese helicóptero!
-[JAILB_V]
-Hoy, Liberty City se ha visto conmocionada.
+[COL5_21]
+¡Mira el tamaño de ese helicóptero!
-[JAILB_A]
-La policía y los servicios de emergencia lidian con las consecuencias
+[COL5_22]
+¡Ahí viene de nuevo!
-[JAILB_B]
-de un devastador ataque a un convoy policial ocurrido esta mañana.
+[FEA_DSM]
+¡Aviso! Esta partida guardada está configurada para utilizar DTS. Esto requiere que el dispositivo compatible DTS esté conectado. Por favor selecciona si quieres continuar usando el sistema DTS o ESTÉREO.
-[JAILB_C]
-No se ha informado de quiénes eran los prisioneros trasladados en el convoy
+[STFT_23]
+Tiempo más rápido en Punto de control Charlie
-[JAILB_D]
-y ningún grupo ha reconocido la autoría.
+[HELP50]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para colocar la cámara detrás de ti.
-[JAILB_E]
-El convoy abandonó las oficinas de la policía esta mañana
+[HELP51]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para colocar la cámara detrás de ti.
-[JAILB_F]
-para hacer una transferencia de reos a la penitenciaría de Liberty.
+[HELP52]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para colocar la cámara detrás de ti.
-[JAILB_G]
-El ataque se produjo en el puente Callahan,
+[HELP53]
+Pulsa ~h~~k~~PED_CYCLE_WEAPON_LEFT~~w~ o ~h~~k~~PED_CYCLE_WEAPON_RIGHT~~w~ para elegir entre todas tus armas disponibles.
-[JAILB_H]
-dejando pocos testigos y al puente seriamente dañado.
+[HELP46]
+Hay ocho categorías de armas diferentes.
-[JAILB_I]
-Se cree que algunos de los convictos han perecido en la explosión
+[HELP47]
+Puedes llevar una arma de cada categoría al mismo tiempo: un tipo de pistola, un tipo de rifle.
-[JAILB_J]
-posterior al ataque inicial.
+[HELP54]
+~w~Cuesta: ~1~ $. ~r~Si compras esta arma reemplazarás la actual.
-[JAILB_W]
-Pasadas las horas se hizo evidente que el ataque era obra de profesionales,
+[HELP2A2]
+Pulsa ~h~~k~~PED_SPRINT~~w~ cuando corras para ~h~esprintar.
-[JAILB_K]
-ya que la identificación de los prófugos se complicó
+[HLPSN_A]
+El rifle de francotirador te permite hacer zoom de acercamiento y disparar con más precisión a objetivos a una cierta distancia.
-[JAILB_L]
-cuando piratas informáticos atacaron las bases de datos de la policía.
+[HLPSN_B]
+Mantén pulsado ~h~~k~~PED_LOCK_TARGET~ ~w~para ~h~apuntar~w~ con el rifle de francotirador.
-[JAILB_O]
-Con el retraso del proyecto del túnel Porter,
+[HLPSN_C]
+Mantén pulsado ~h~~k~~PED_LOCK_TARGET~ ~w~para ~h~apuntar~w~ con el rifle de francotirador.
-[JAILB_P]
-este desastre deja a Portland aislada del resto de la ciudad.
+[HLPSN_D]
+Pulsa ~h~~k~~PED_SNIPER_ZOOM_IN~~w~ para ~h~acercar la vista ~w~con el rifle y ~h~~k~~PED_SNIPER_ZOOM_OUT~ ~w~para ~h~alejarla~w~.
-[JAILB_M]
-*
+[HLPSN_E]
+Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para ~h~disparar~w~ el rifle de francotirador.
-[JAILB_N]
-*
+[HLPSN_F]
+Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para ~h~disparar~w~ el rifle de francotirador.
-[JAILB_X]
-UNUSED
+[HLPSN_G]
+Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para ~h~disparar~w~ el rifle de francotirador.
-[FEDS_SE]
-Botón / - ELEGIR
+[PLANE_H]
+Mueve ~h~~k~~VEHICLE_ACCELERATE~~w~ hacia delante para acelerar y a izquierda o derecha para girar.
-[FEDS_SB]
-Botón / - ELEGIR Botón " - VOLVER
+[PLANE_4] { reVC update }
+{Mueve ~h~~k~~VEHICLE_ACCELERATE~~w~ hacia delante para acelerar y a izquierda o derecha para girar.}
+Utiliza el joystick analógico derecho para acelerar, tira hacia atrás el joystick analógico izquierdo para ascender, empújalo hacia adelante para descender. Para girar muévelo a izquierda o derecha.
-[TM4_A]
-Ah, eres tú. Toni no está.
+[HELP55]
+Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para atacar al chef.
-[TM4_A2]
-Pero te ha dejado una de sus cartitas de amor.
+[STPR_8]
+Club Pole Position
-[DIAB2_A]
-¡Empecé mi negocio de entretenimiento exótico sin nada más que lo que cabía en mis pantalones de cuero!
+[STPR_9]
+3321 de Vice Point
-[LM5_9]
-CHICAS:
+[STPR_10]
+Apartamento de Links View
-[PERPIC]
-Paquetes ocultos encontrados
+[STPR_11]
+Casa Swanko
-[CO_ONE]
-Paquete oculto ~1~ de ~1~
+[STPR_12]
+1102 de Washington Street
-[LOVE3_3]
-~g~La avioneta ha tirado ~1~ de los 6 paquetes.
+[STPR_13]
+Apartamento de Ocean Heights
-[FARE11]
-~g~Ve al ~w~edificio en construcción ~g~de Fort Staunton.
+[STPR_14]
+Chabola Skumole
-[GA_21]
-No puedes guardar más coches en este garaje.
+[STPR_15]
+Piso de Hyman
-[CHEAT1]
-Trucos activados
+[RCCANX]
+~r~Misión de avión RC cancelada.
-[CHEAT2]
-Arma trucada
+[CLT_HL2]
+Cuando recojas ropa, te librarás de una o dos estrellas del nivel de se busca.
-[CHEAT3]
-Salud trucada
+[CRED009]
+DISEÑO DE MISIONES
-[CHEAT4]
-Armadura trucada
+[CRED359]
+LEE JOHNSON
-[CHEAT5]
-Busca y captura trucado
+[CRED360]
+HENDRIK LESSER
-[CHEAT6]
-Dinero trucado
+[CRED361]
+PASQUALE STACCHIOTTI
-[CHEAT7]
-Clima trucado
+[CRED362]
+ENRIQUE FERNÁNDEZ
-[AS1_H]
-~r~¡No has llevado al escuadrón de la muerte hasta la trampa de la yakuza!
+[CRED363]
+PAUL BYERS
-[FEDS_BA]
-Botón " - VOLVER
+[CRED364]
+MIKE EMENY
-[RAMP_A]
-¡TODAS LAS MASACRES COMPLETADAS!
+[CRED365]
+ROB DUNKIN
-[USJ_ALL]
-¡TODAS LAS ACROBACIAS COMPLETADAS!
+[CRED366]
+CHARLIE KINLOCH
-[FARE23]
-~g~Ve al ~w~taller de importación/exportación~g~ en el distrito de la presa Cochrane.
+[CRED367]
+KEVIN HOBSON
-[L_TRN_1]
-Puedes coger el tren para recorrer Portland. Pulsa ~h~~k~~VEHICLE_ENTER_EXIT~~w~ para ~h~entrar ~w~o ~h~salir~w~ de un tren.
+[CRED368]
+JIM CREE
-[L_TRN_2]
-Puedes coger el tren para recorrer Portland. Pulsa ~h~~k~~VEHICLE_ENTER_EXIT~~w~ para ~h~entrar ~w~o ~h~salir~w~ de un tren.
+[MOB_66A]
+Tommy, Tommy, ¿para qué has vuelto?
-[S_TRN_1]
-Puedes coger el metro para recorrer Liberty City. Pulsa ~h~~k~~VEHICLE_ENTER_EXIT~~w~ para ~h~entrar ~w~o ~h~salir~w~ de un tren.
+[MOB_66B]
+Ya te he dicho que no queremos verte más.
-[S_TRN_2]
-Puedes coger el metro para recorrer Liberty City. Pulsa ~h~~k~~VEHICLE_ENTER_EXIT~~w~ para ~h~entrar ~w~o ~h~salir~w~ de un tren.
+[MOB_67A]
+Tommy, creo que no deberías acercarte, ¿me oyes?
-[AS1_C]
-Ella cuenta con tres escuadrones de la muerte que patrullan por Liberty con el único fin de darte caza.
+[MOB_67B]
+Los chicos haitianos no están muy contentos contigo.
-[AS1_G]
-~r~¡Todos los yakuza están muertos!
+[MOB_18A]
+Tommy, soy Paulo, ¿cómo estás? Vale hombre, bueno pensé que tenía que mandarte una nota.
-[JAN]
-Ene
+[MOB_18B]
+Oh Dios misericordioso, hijo mío, no te vas a creer la categoría de la furcia que acabo de conocer.
-[FEB]
-Feb
+[MOB_18C]
+Prostituta callejera o algo parecido, cerca de Little Havana, tío.
-[MAR]
-Mar
+[MOB_18D]
+Me dijo que se llamaba Mercedes o algo así.
-[APR]
-Abr
+[MOB_18E]
+Oh Dios, tío, tienes que probar a esa palomita.
-[MAY]
-May
+[MOB_18F]
+Sabe como ponerte a tono. Dijo que yo era el mejor tío con el que había estado en toda su vida.
-[JUN]
-Jun
+[MOB_18G]
+Estate al tanto por si la ves. Hasta luego.
-[JUL]
-Jul
+[MOB_72A]
+Tommy, soy yo, Lance. Mantén la boca cerrada Tommy porque no tengo ganas de hablar.
-[AUG]
-Ago
+[MOB_72B]
+No estoy interesado en lo que tengas que decir. ¿Por qué debería estarlo? ¿Te preocupas tú por mí?
-[SEP]
-Sept
+[MOB_72C]
+Tienes que cuidarme un poco mejor. Darme una buena tajada, ya sabes...
-[OCT]
-Oct
+[MOB_72D]
+Tommy... oh, mira, tío, Lo siento. Es solo que...
-[NOV]
-Nov
+[MOB_72E]
+La gente me ha estado sobreprotegiendo toda mi vida, tratándome como a un niño.
-[DEC]
-Dic
+[MOB_72F]
+Mi hermano haría eso. Por favor, tío, no lo hagas.
-[DEFDT]
---:---:---- --:--:--
+[MOB_72G]
+Tengo que irme.
-[BUGGY]
-COCHES RESTANTES:
+[MOB_63A]
+Tommy, soy Earnest. Earnest Kelly.
-[BONUS]
-~g~PRIMA DE ~1~ $
+[MOB_63B]
+¿Cómo estás?
-[HORN1]
-Pulsa el ~h~botón L3~w~ para tocar el ~h~claxon.
+[MOB_63C]
+Estoy bien. Necesitaré un bastón para andar pero muy pronto volveré al trabajo.
-[HORN2]
-Pulsa el ~h~botón L1~w~ para tocar el ~h~claxon.
+[MOB_63D]
+Bien.
-[HORN3]
-Pulsa el ~h~botón R1~w~ para tocar el ~h~claxon.
+[MOB_63E]
+Me enteré de lo de Lance. Vaya cabroncete, ¿eh?
-[LM3_1A]
-Pulsa ~h~~k~~VEHICLE_HORN~~w~ para tocar el ~h~claxon~w~ y avisar a Misty.
+[MOB_63F]
+Sí.
-[LM3_1B]
-Pulsa ~h~~k~~VEHICLE_HORN~~w~ para tocar el ~h~claxon~w~ y avisar a Misty.
+[MOB_63G]
+No te fíes nunca de un hombre que va por la calle en pijama. Y es lo que digo yo. Menos mal que lo mataste. Espero que el mamón sufriera.
-[LM3_1C]
-Pulsa ~h~~k~~VEHICLE_HORN~~w~ para tocar el ~h~claxon~w~ y avisar a Misty.
+[MOB_63H]
+Creo que sí. Lo que pasa es que yo no creí que...
-[RADIO_A]
-Pulsa ~h~~k~~VEHICLE_CHANGE_RADIO_STATION~~w~ para cambiar de ~h~emisora de radio.
+[MOB_63I]
+Tommy, para ser un chalado furioso, eres bastante ingenuo. Cuando vuelva a trabajar pronto te enseñaré un par de cosas sobre la vida, me oyes.
-[RADIO_B]
-Pulsa ~h~~k~~VEHICLE_CHANGE_RADIO_STATION~~w~ para cambiar de ~h~emisora de radio.
+[MOB_63J]
+Tómate tu tiempo, Earnest. Cuídate.
-[RADIO_C]
-Pulsa ~h~~k~~VEHICLE_CHANGE_RADIO_STATION~~w~ para cambiar de ~h~emisora de radio.
+[MOB_16A]
+Tommy, soy Paulo, ¿qué pasa amigo?
-[RADIO_D]
-Pulsa ~h~~k~~VEHICLE_CHANGE_RADIO_STATION~~w~ para cambiar de ~h~emisora de radio.
+[MOB_16B]
+Qué quieres Paul. No necesito ropa de marca de imitación.
-[FEC_EXV]
-Entrar/salir de vehículo
+[MOB_16C]
+Muy gracioso, tío, pero sabes que no toco nada de mercancía ilegal. No, sólo llamaba para ver si puedo conseguir un papel en una de tus películas.
-[TAXI_M]
-'TAXISTA'
+[MOB_16D]
+Allí en Inglaterra hice un montón de porno, colega. Soy bastante más ardiente que tú, pequeño.
-[COP_M]
-'JUSTICIERO'
+[MOB_16E]
+Paul, gracias por la oferta, lo tendré en cuenta.
-[FIRE_M]
-'BOMBERO'
+[MOB_16F]
+En serio, después de todo lo que he hecho por ti, no te olvides de mí.
-[AMBUL_M]
-'CONDUCTOR DE AMBULANCIA'
+[MOB_16G]
+Eso es lo que intento olvidar.
-[HJ_IS]
-PREMIO POR ACROBACIA DEMENCIAL: ~1~ $
+[MOB_17A]
+Tommy Vercetti, ¿Qué tal te va Sr. Influyente? He oído un montón de cosas sobre ti, así que ahora eres el que manda en la ciudad, eh...
-[HJ_PIS]
-PREMIO POR ACROBACIA DEMENCIAL PERFECTA: ~1~ $
+[MOB_17B]
+Paul, estás borracho.
-[HJ_DIS]
-PREMIO POR ACROBACIA DEMENCIAL DOBLE: ~1~ $
+[MOB_17C]
+No, imbécil, no estoy borracho. Sólo he tomado un par de copas y alguna que otra invitación, no me he acostado en los dos últimos días, sabes.
-[HJ_PDIS]
-PREMIO POR ACROBACIA DEMENCIAL DOBLE PERFECTA: ~1~ $
+[MOB_17D]
+En cualquier caso, no me vengas con esto. No soy tonto. ¿Quién te estableció en esta ciudad? ¿Quién? Yo. Que te enteres.
-[HJ_TIS]
-PREMIO POR ACROBACIA DEMENCIAL TRIPLE: ~1~ $
+[MOB_17F]
+¿De verdad?
-[HJ_PTIS]
-PREMIO POR ACROBACIA DEMENCIAL TRIPLE PERFECTA: ~1~ $
+[MOB_17G]
+No me vengas con esto. Yo te presenté a la gente. Te enseñé cómo hacer bien los trabajos, hice muchas cosas por ti, y así es como me lo pagas.
-[HJ_QIS]
-PREMIO POR ACROBACIA DEMENCIAL CUÁDRUPLE: ~1~ $
+[MOB_17H]
+Me ignoras. Ni siguieras me das acceso a nada, después de todo lo que hice por ti. ¿Quién te crees que soy? ¿Un retrasado mental o algo así?
-[HJ_PQIS]
-PREMIO POR ACROBACIA DEMENCIAL CUÁDRUPLE PERFECTA: ~1~ $
+[MOB_17I]
+Paul, tranquilízate. He estado muy ocupado, no te comportes como un idiota..
-[AM1_K]
-Salvatore Leone saldrá del club de Luigi dentro de unas tres horas. (0~1~:~1~)
+[MOB_17J]
+No soy un idiota, colega. Eso es lo que decían en el reformatorio. ¿Estás buscando bronca? ¡Porque la vas a tener!
-[IMPEXPP]
-Garaje de importación y exportación, puerto de Portland. Requerimos varios vehículos, revisa nuestro tablón de notas para saber más.
+[MOB_17K]
+Tommy, colega. Por favor. ¡Tú eras mi gran esperanza! Por favor, ¡no te rías de mí!
-[VANHSTP]
-¿Quieres abrir algún Securicar? Llévalo a nuestro garaje en el puerto de Portland.
+[MOB_17L]
+Paul, vete a dormir un poco, de verdad.
-[EMVHPUP]
-Se compran vehículos de emergencia nuevos y usados a buen precio. Llévalos a la grúa que hay al noroeste del puerto de Portland.
+[MOB_73A]
+Tommy, soy Steve.
-[STANDS]
-PUESTOS DESTROZADOS:
+[MOB_73B]
+Eh, Steve.
-[STASH]
-~g~¡Lleva el SPANK de vuelta al ~p~edificio en construcción~g~!
+[MOB_73C]
+¡Eres un portento! ¡Soy un portento! La gente está loca por nosotros. Vamos a entrar en la historia, amigo.
-[MCSTNS]
-No hay una Memory Card (PS2) insertada en la ranura para MEMORY CARD 1. ¿Quieres empezar? (SÍ o NO)
+[MOB_73D]
+Se trata de los premios más importantes. Podré llevar a mi padre a una residencia y no tener que escucharle nunca más.
-[LOVE3_5]
-~g~La avioneta ha llegado a la zona.
+[MOB_73E]
+Eso está bien, Steve.
-[LOVE3_6]
-~r~¡La bofia ha llegado a los paquetes antes que tú!
+[MOB_73F]
+Mejor que bien tío. Mejor, mucho mejor. Nunca creyó en mí. Nunca creyó que pudiera ser un artista y ahora lo he conseguido.
-[SIREN_1]
-Para activar la sirena de este vehículo, pulsa ~h~~k~~VEHICLE_HORN~~w~.
+[MOB_73G]
+Soy el mejor director de cine porno de todos los tiempos, amigo. Solo quería decirte que ha sido un placer conocerte.
-[SIREN_2]
-Para activar la sirena de este vehículo, pulsa ~h~~k~~VEHICLE_HORN~~w~.
+[MOB_73H]
+Gracias Steve.
-[FM3_8C]
-Necesitaré 100.000 dólares para cubrir gastos,
+[MOB_73I]
+Te quiero tío, No cambies, me oyes.
-[MCLOAD]
-Cargando datos. No extraigas la Memory Card (PS2) de la ranura de MEMORY CARD 1, ni reinicies o apagues la consola.
+[MOB_73J]
+Te oigo. Adiós Steve.
-[FES_GME]
-Fallo al leer la Memory Card (PS2) de la ranura de MEMORY CARD 1. Compruébala e inténtalo de nuevo.
+[BOLLOX]
+Pulsa ~h~~k~~VEHICLE_HANDBRAKE~ ~w~para soltar una bomba. Pulsa ~h~~k~~VEHICLE_ENTER_EXIT~ ~w~para cancelar.
-[FESZ_QF]
-¿Seguro que quieres formatear la Memory Card (PS2) de la ranura de MEMORY CARD 1?
+[BRID_OP]
+El temporal ha pasado, todos los puentes hacia la península están ahora abiertos.
-[FESZ_LS]
-Carga completada.
+[BRID_CL]
+Alerta de temporal: Cerrados todos los puentes hacia la península.
+
+[ASSET_C]
+¡CLUB POLE POSITION CONSOLIDADO!
+
+[ASSET_D]
+El club Pole Position generará ahora unos ingresos máximos de hasta ~1~ $ al día. ¡Asegúrate de recaudarlos regularmente!
-[RM3_5]
-~g~Tienes ~1~ de 6 paquetes de pruebas.
+[ST_WHEE]
+Mayor tiempo en caballito (seg)
-[LOVE3_2]
-~g~¡Tienes todos los paquetes! Llévaselos a Donald Love.
+[ST_STOP]
+Mayor tiempo en parada (seg)
-[LOVE4_4]
-~g~¡Lleva el paquete a Donald Love!
+[ST_2WHE]
+Mayor tiempo en dos ruedas (seg)
-[FEB_SAV]
-Cargar
+[ST_WHED]
+Mayor distancia en caballito (m)
-[FEP_SAV]
-CARGAR PARTIDA
+[ST_STOD]
+Mayor distancia en parada (m)
-[AS2_12A]
-~g~Cuando destruyas el primer puesto, ¡tendrás 8 mintutos antes que el cártel avise a sus camellos!
+[ST_2WHD]
+Mayor distancia en dos ruedas (m)
-[AS3_1A]
-~g~¡Ahora ve a la ~b~boya señalada~g~!
+[OUTFT11]
+Chándal
-[NOCONT]
-Vuelve a conectar un mando analógico (DUALSHOCK#) o mando analógico (DUALSHOCK#2) en el puerto de mando 1 para continuar.
+[OUTFT12]
+Frankie
-{ Possibly unused }
+[RELOAD]
+~g~¡Has conseguido la habilidad de recargar rápidamente!
-[BET_JB]
-TRAICIONADO POR SU AMANTE CATALINA Y DADO POR MUERTO. TRAS SER CONDENADO Y SENTENCIADO, INICIA SU VIAJE A LA PRISIÓN DE LIBERTY CITY. PERO SÓLO TIENE UN PENSAMIENTO... ¡VENGANZA!
+[APACHE]
+Hunter entregado en el helipuerto de Ocean Beach.
-[END_A]
-Los residentes de Cedar Grove todavía están asumiendo
+[CRED369]
+JOHN MCCARDLE
+
+[CRED370]
+DAVID MURDOCH
-[END_B]
-las consecuencias emocionales provocadas
+[CRED371]
+CHRIS BROWN
-[END_C]
-por la guerra que estalló ayer en la zona.
+[CRED372]
+PAUL GREEN
-[END_D]
-Un residente local, Clive Denver, dijo a la policía
+[CRED373]
+KYLE MILNE
-[END_E]
-que vio a un hombre armado huyendo de la escena, acompañado de una mujer de pelo negro.
+[CRED374]
+KEVIN YUN
-[END_F]
-¿Sabes? Vamos a pasar un buen rato, porque, como sabes...
+[CRED375]
+ERICK COBBS
-[END_G]
-¡Te amo! Yo, yo, yo realmente te amo, porque eres superfuerte,
+[CRED376]
+RANDY BLAKE
-[END_H]
-y eso es todo lo que necesito.
+[CRED377]
+BRANDON LIM
-[END_I]
-Bueno, ¿qué estaba diciendo?
+[CRED378]
+BRANDON FENOL
-[END_J]
-Lo he olvidado. Pero me entiendes, ¿verdad?
+[CRED379]
+MICHAEL MANOLE
-[END_K]
-Las explosiones sacudieron las casas más próximas mientra sus residentes buscaban refugio.
+[CRED380]
+ALETHEIA SIMONSON
-[END_L]
-Varios ciudadanos resultaron heridos entre el caos debido al tiroteo
+[CRED381]
+JOHN JANSEN
-[END_M]
-entre las fuerzas terrestres y un helicóptero que rodeaba a la presa.
+[CUNTY]
+¡Ropa nueva entregada en la finca de Vercetti!
-[END_N]
-Sí, en estos jardines tuvimos una vista excelente.
+[GOODBOY]
+¡Prima de 50 $ por comportamiento ejemplar!
-[END_O]
-El momento en el que derribaron el helicóptero
+[NEWCONT]
+¡Nuevo ~h~punto de contacto ~w~disponible en el puerto deportivo en Ocean Beach!
-[END_P]
-fue mejor que los fuegos artificiales del 4 de julio.
+[FIRELVL]
+Misión de camión de bomberos nivel ~1~
-[END_Q]
-El número de víctimas asciende a las veinte
-[END_R]
-mientras la policía sigue encontrando cuerpos.
+[HELP56]
+Pulsa ~h~~k~~CAMERA_CHANGE_VIEW_ALL_SITUATIONS~~w~ para ajustar la cámara.
-[END_S]
-No se han negado oficialmente los rumores
+[HELP57]
+Pulsa ~h~~k~~CAMERA_CHANGE_VIEW_ALL_SITUATIONS~~w~ para ajustar la cámara.
-[END_T]
-de que las víctimas eran miembros del cártel colombiano,
+[HELP58]
+Mientras estás apuntando, puedes pulsar ~h~~k~~PED_CYCLE_TARGET_LEFT~~w~ o ~h~~k~~PED_CYCLE_TARGET_RIGHT~~w~para cambiar de objetivo.
-[END_U]
-y aún no hay pistas que aclaren las causas de la masacre.
+[HELP59]
+Mientras estás apuntando, puedes pulsar ~h~~k~~PED_CYCLE_TARGET_LEFT~~w~ o ~h~~k~~PED_CYCLE_TARGET_RIGHT~~w~para cambiar de objetivo.
-[END_V]
-Me he roto una uña y me pelo está hecho un asco, ¿puedes creerlo?
+[HELP60]
+Si pulsas ~h~~k~~PED_SPRINT~ ~w~ mientras estás robando un coche, no te subirás en él.
-[PAPER1]
-CRIMINAL HERIDO DE BALA POR SU NOVIA Y CÓMPLICE; EL TRIBUNAL ENCUENTRA CULPABLE AL ATRACADOR CON UN VEREDICTO UNÁNIME.
+[HELP61]
+Ahora dispones de munición ilimitada y el doble de robustez en todos los vehículos.
-[PAPER2]
-¡DIEZ AÑOS POR AMOR!
+[FEC_LB1]
+Mirar
+
+[FEC_LB2]
+detrás
-[END_W]
-Me costó cincuenta dólares...
+[FEC_LB3]
+Mirar detrás
-[FEB_CPC]
-Configuración de controles
+[FEC_R3]
+(botón R3)
[FEC_PED]
Controles a pie
[FEC_VEH]
-Controles en vehículos
+Controles en vehículo
[FEC_FPR]
Controles en primera persona
@@ -6983,43 +6887,43 @@ Andar hacia delante
Andar hacia la cámara
[FEC_PLB]
-Mirar hacia atrás
+Mirar hacia atrás.
[FEC_PFR]
Disparar arma
[FEC_CLE]
-Arma de la izquierda
+Cambiar Arma a la Izq.
[FEC_CRI]
-Arma de la derecha
+Cambiar Arma a la Dcha.
[FEC_LKT]
-Fijar objetivo
+Bloquear objetivo
[FEC_PJP]
-Saltar a pie
+Salto Peatón
[FEC_PSP]
-Esprintar a pie
+Sprint Peatón
[FEC_PSH]
-Disparar a pie
+Disparar Peatón
[FEC_TLF]
-Objetivo a la izq.
+Siguiente objetivo a la izq.
[FEC_TRG]
-Objetivo a la dcha.
+Siguiente objetivo a la dcha.
[FEC_CCM]
-Centrar cámara tras jugador
+Centrar cámara detrás del jugador
[FEC_SZI]
-Acercar zoom de fusil
+Acercar vista rifle francotirador
[FEC_SZO]
-Alejar zoom de fusil
+Alejar vista rifle francotirador
[FEC_LKL]
Mirar izq. en primera persona
@@ -7061,7 +6965,7 @@ Misiones secundarias
Cambiar emisora de radio
[FEC_ENT]
-Entrar /salir de vehículo
+Entrar/salir de vehículo
[FEC_WPN]
Disparar arma
@@ -7070,105 +6974,25 @@ Disparar arma
Pausa
[FEC_FPO]
-Armas en primera persona
+Cambiar armas primera persona
[FEC_SMS]
Mostrar puntero del ratón
[FEC_CMS]
-Cambiar cámara en todas las situaciones
+Cambiar modo cámara en todas situaciones.
[FEC_TSS]
Capturar pantalla
-[FEN_STA]
-INICIAR PARTIDA
-[FEN_NET]
-Red
-
-[FEN_CON]
-Conexión
-
-[FEN_GAM]
-Buscar partida
-
-[FEN_TYP]
-Tipo de partida
-
-[FEN_TY0]
-Duelo a muerte
-
-[FEN_TY1]
-Duelo a muerte sigiloso
-
-[FEN_TY2]
-Duelo a muerte en equipo
-
-[FEN_TY3]
-Duelo a muerte sigiloso en equipo
-
-[FEN_TY4]
-Busca la pasta
-
-[FEN_TY5]
-Captura la bandera
-
-[FEN_TY6]
-Carrera de locos
-
-[FEN_TY7]
-Dominación
-
-[FEN_NAM]
-Nombre:
-
-[FEN_GNA]
-Nombre de partida:
-
-[FEM_MAP]
-Elegir mapa
-
-[FEN_PLS]
-Ajustes del jugador
-
-[FEN_PLC]
-Color del jugador
-
-[FEM_MA0]
-Liberty City
-
-[FEM_MA1]
-Red Light District
-
-[FEM_MA2]
-Chinatown
-
-[FEM_MA3]
-La Torre
-
-[FEM_MA4]
-Alcantarillas
-
-[FEM_MA5]
-Zona industrial
-
-[FEM_MA6]
-Muelles
-
-[FEM_MA7]
-Staunton
-
-[FEC_EMS]
-Sólo se permiten teclas del teclado.
-
[FEC_DBG]
-MENÚ DE DEPURACIÓN
+DEBUG MENU
[FEC_TGD]
Cambiar mando de juego/depuración
[FEC_TDO]
-Desactivar cámara de depuración
+Cambiar cámara depuración No
[FEC_IVH]
Invertir horizontalidad ratón
@@ -7183,28 +7007,28 @@ BCR
BDR
[FEC_QUE]
-¿?
+???
[FEC_TWO]
-Sólo se permiten dos teclas del teclado.
+Permitidas sólo dos teclas del teclado.
[FEC_UMS]
-Sólo se permiten botones del ratón.
+Por favor sólo teclas de ratón.
[FEC_OMS]
-Sólo se permite un botón del ratón.
+Permitida sólo una tecla del ratón.
[FEC_UJS]
-Sólo se permiten botones del joystick.
+Por favor sólo botones de joystick.
[FEC_OJS]
-Sólo se permite un botón del joystick por acción.
+Permitido sólo un botón de joystick por acción.
[FEC_PTL]
-Usar Fijar objetivo con Siguiente arma.
+Usar Bloquear objetivo al cambiar arma a izq.
[FEC_PTR]
-Usar Fijar objetivo con Arma anterior.
+Usar Bloquear objetivo al cambiar arma a dcha.
[FEC_LBC]
Usar Mirar a izq. con Mirar a la dcha.
@@ -7212,780 +7036,7232 @@ Usar Mirar a izq. con Mirar a la dcha.
[FEC_JBO]
JOY ~1~
-[NO_PAUZ]
-No se puede parar una partida multijugador. ¡Pulsa dos veces para salir!
+[FEC_WAR]
+Aviso
-[FEM_SL1]
-Espacio 1 libre
+[FEC_OKK]
+Aceptar
-[FEM_SL2]
-Espacio 2 libre
+[FEC_DLF]
+Error al borrar.
-[FEM_SL3]
-Espacio 3 libre
+[FEC_SVU]
+Error al guardar.
-[FEM_SL4]
-Espacio 4 libre
+[FEC_LUN]
+Error al cargar. Archivo dañado, por favor bórralo.
-[FEM_SL5]
-Espacio 5 libre
+[FEC_PAD]
+Gamepad
-[FEM_SL6]
-Espacio 6 libre
+[FEC_JOY]
+Joystick
-[FEM_SL7]
-Espacio 7 libre
+[FES_CSA]
+Seleccionar aspecto de la lista inferior:
-[FEM_SL8]
-Espacio 8 libre
+[FET_HRD]
+AJUSTES POR DEFECTO RESTAURADOS
+
+[FET_MST]
+CONDUCCIÓN CONTROLADA POR EL RATÓN
+
+[FEC_STR]
+NUM. INICIO
+
+[FET_MIG]
+IZQUIERDA, DERECHA, RUEDA DEL RATÓN PARA AJUSTAR
+
+[FET_CIG]
+RETROCESO PARA QUITAR - BIR, VOLVER A CAMBIAR
+
+[FET_DSN]
+Apariencia predeterminada del jugador.bmp
+
+[FET_RSO]
+RESTAURADO AJUSTE ORIGINAL
+
+[FET_RSC]
+HARDAWARE NO DISPONIBLE. RESTAURADO AJUSTE ORIGINAL
+
+[FEA_3DH]
+HARDWARE DE SONIDO
+
+[FEA_SPK]
+AJUSTE DE ALTAVOCES
+
+[FEM_LOD]
+DIST. DE REPRESENTACIÓN
+
+[FEM_VSC]
+SINCRONÍA DE IMAGEN
+
+[FEM_FRM]
+LIMITADOR DE CUADROS
[FEM_MM]
MENÚ PRINCIPAL
-[FEM_SNG]
-NUEVA PARTIDA
+[FED_RES]
+RESOLUCIÓN DE PANTALLA
-[FEM_QTW]
-Salir
+[FET_CTL]
+CONFIGURAR MANDO
-[FEQ_SRE]
-¿Seguro que quieres salir del juego? Se perderán todos los progresos desde la última partida guardada.
+[FET_OPT]
+OPCIONES
-[FEQ_SRW]
-¿Seguro que quieres salir del juego?
+[FEC_MSH]
+SENSIBILIDAD DEL RATÓN
-[FEG_SRV]
-SERVIDOR
+[FEC_IVV]
+INVERTIR VERTICALIDAD RATÓN
-[FEG_MAP]
-MAPA
+[FEC_FNC]
+F~1~
+
+[FEC_IRT]
+INSERT
+
+[FEC_DLL]
+SUPR
+
+[FEC_HME]
+INICIO
-[FEG_PLY]
-JUGADORES
+[FEC_END]
+FIN
-[FEG_TYP]
-TIPO
+[FEC_PGU]
+RE PÁG
-[FEG_PNG]
-PING
+[FEC_PGD]
+AV PÁG
-[FET_FG]
-ENCONTRAR PARTIDA
+[FEC_UPA]
+ARRIBA
-[FET_SP]
-UN JUGADOR
+[FEC_DWA]
+ABAJO
-[FET_MP]
-MULTIJUGADOR
+[FEC_LFA]
+IZDA
-[FET_HG]
-CREAR PARTIDA
+[FEC_RFA]
+DCHA
-[FET_PS]
-AJUSTES DE JUGADOR
+[FEC_NUM]
+NUM.
-[FET_CON]
-CONEXIÓN
+[FEC_NMN]
+NUM. ~1~
-[FET_AUD]
-AJUSTES DE AUDIO
+[FEC_FWS]
+NUM. /
-[FET_DIS]
-AJUSTES DE PANTALLA
+[FEC_PLS]
+NUM. +
-[FET_LAN]
-AJUSTES DE IDIOMA
+[FEC_MIN]
+NUM. -
-[FET_LG]
-CARGAR PARTIDA
+[FEC_DOT]
+NUM. .
-[FET_DG]
-BORRAR PARTIDA
+[FEC_NLK]
+BLOQ NUM
-[FET_NG]
-NUEVA PARTIDA
+[FEC_ETR]
+INTRO
-[FET_SG]
-GUARDAR PARTIDA
+[FEC_SLK]
+BLOQ DESPL
-[FET_MAP]
-ELEGIR MAPA
+[FEC_PSB]
+PAUSA INTER
-[FET_GT]
-TIPO DE JUEGO
+[FEC_BSP]
+RETROCESO
-[FET_CTL]
-AJUSTES DE CONTROL
+[FEC_TAB]
+TAB
-[FET_OPT]
-OPCIONES
+[FEC_CLK]
+BLOQ MAYÚS
+
+[FEC_RTN]
+INTRO
+
+[FEC_LSF]
+MAYÚS IZQ
+
+[FEC_RSF]
+MAYÚS DCH
+
+[FEC_LCT]
+CTRL I
+
+[FEC_RCT]
+CTRL D
+
+[FEC_LAL]
+ALT I
+
+[FEC_RAL]
+ALT D
+
+[FEC_LWD]
+WIN I
+
+[FEC_RWD]
+WIN D
+
+[FEC_WRC]
+APMENÚ
+
+[FEC_SPC]
+ESPACIO
+
+[WIN_TTL]
+Grand Theft Auto VC
+
+[WIN_95]
+Grand Theft Auto VC no se puede ejecutar bajo W95
+
+[WIN_DX]
+Grand Theft Auto VC necesita al menos la versión 8.1 de DirectX
+
+[FET_EIG]
+NO SE PUEDE DEFINIR UN CONTROL PARA ESTA ACCIÓN
+
+[FET_DAM]
+MODELADO ACÚSTICO DINÁMICO
+
+[FEQ_SRE]
+¿Seguro que quieres salir? Se perderán todos los progresos desde la última partida guardada. ¿Quieres proceder?
+
+[FEQ_SRW]
+¿Seguro que quieres salir del juego?
[FET_QG]
SALIR DEL JUEGO
-[FET_STA]
-ESTADÍSTICAS
+[FEN_STA]
+INICIAR JUEGO
-[FET_BRE]
-RESUMEN
+[FET_PAU]
+MENÚ PAUSA
-[FEC_WAR]
-Aviso
+[REPLAY]
+VOLVER A JUGAR
-[FEC_OKK]
-ACEPTAR
+[FEC_ANS]
+Acción
+
+[CVT_MSG]
+Convertir texturas a un formato óptimo para tu tarjeta de vídeo
-[FED_CON]
-Confirmación de borrado
+[FEC_SFT]
+MAYÚS
-[FES_SSC]
-Partida guardada.
+[FEH_VMP]
+VER MAPA
+
+[FES_DEE]
+¡Error al eliminar! Por favor, inténtalo de nuevo.
+
+[FES_CMP]
+¡Error al guardar! Por favor, inténtalo de nuevo.
+
+[FESZ_WR]
+Guardando partida actual. Por favor, espera...
-[DEL_FNM]
-Partida eliminada.
+[FELD_WR]
+Cargando el juego. Por favor, espera...
-[PCLOAD]
-Cargando datos de la partida
+[FEDL_WR]
+Eliminando partida guardada. Por favor, espera...
[PCRESRT]
-Reiniciando Grand Theft Auto III
+Iniciando nueva partida. Por favor, espera...
-[FEC_DLF]
-Fallo al borrar.
+[FET_STI]
+Controles estándar
-[FEC_SVU]
-Fallo al guardar.
+[FET_CTI]
+Controles clásicos
-[FEC_LUN]
-Fallo al cargar. Archivo dañado, por favor, bórralo.
+[FEH_NA]
+OPCIÓN NO DISPONIBLE
-[FEN_PLA]
-Número de jugadores:
+[FEH_MPH]
+RATÓN, CURSORES PARA MOVERSE - RE. PAG, AV. PAG, RUEDA RATÓN PARA ZOOM, L - LEYENDA
-[FET_NON]
-NO HAY PARTIDAS DISPONIBLES
+[FEA_MP3]
+REPRODUCTOR MP3
-[FET_SFG]
-BUSCANDO PARTIDAS...
+[NO_PCCD]
+Por favor, introduce tu CD de GTA Vice City o pulsa ESC para cancelar
-[FET_SRT]
-ORDENANDO PARTIDAS...
+[FEH_SSA]
+CURSORES PARA MOVERSE - S PARA GUARDAR EN UN ARCHIVO
-[FEF_LAN]
-RED LOCAL
+[FES_CMI]
+ÚLTIMA MISIÓN SUPERADA
-[FEF_INT]
-INTERNET
+[FET_STS]
+ESTADÍSTICAS GUARDADAS EN 'STATS.HTML' + 'STATS.TXT'
-[FET_REF]
-Actualizar
+[WIN_VDM]
+Grand Theft Auto VC no pudo encontrar suficiente memoria de vídeo disponible
-[FET_FIL]
-Filtrar
+[FEC_ERI]
+¡Error! Una o más acciones de control no están vinculadas a ninguna tecla o botón. Comprueba que todas las acciones de control estén definidas.
-[FET_JG]
-Unirse
+[FEC_TFU]
+Torreta + Inclinar arriba
-[FEC_NTW]
-Conectar con red
+[FEC_TFD]
+Torreta + Inclinar abajo
-[FEC_ESR]
-Tecla Esc limitada
+[FET_RIG]
+ELIGE UN NUEVO CONTROL PARA ESTA ACCIÓN
-[FEC_GSL]
-Balanceo de cabeza:
+[FEA_NM3]
+NO SE ENCONTRARON ARCHIVOS MP3
-[FIL_FLT]
-FILTRAR LISTAS DE PARTIDAS
+[FEA_MPB]
+SUBIR VOLUMEN DE MP3
-[FET_SAN]
-INICIAR NUEVA PARTIDA
+[FEA_MUS]
+VOLUMEN DE MÚSICA
-[FIL_MAP]
-Mapa:
+[FEA_SFX]
+VOLUMEN DE EFECTOS
-[FIL_SRV]
-Servidor:
+[CVT_ERR]
+Te has quedado sin espacio en el disco duro. Por favor, antes de seguir consigue algo de espacio en tu disco duro. Pulsa ESC para cancelar.
-[FIL_TYP]
-Tipo de juego:
+[FEA_ADP]
+DETECTAR EL HARDWARE AUTOMÁTICAMENTE
-[FIL_SPC]
-¿Partidas que no estén llenas?
+{=================================== MISSION TABLE AMBULAE ===================================}
-[FIL_PNG]
-Latencia:
+[ATUTOR2:AMBULAE]
+~g~Lleva a los pacientes al hospital CON CUIDADO. Cada bache reduce sus posibilidades de supervivencia.
-[FEN_UKH]
-Anfitrión desconocido
+[A_FULL:AMBULAE]
+~r~¡Ambulancia llena!
-[FEN_UKM]
-Mapa no encontrado
+[A_FAIL2:AMBULAE]
+~r~¡Tu falta de urgencia ha sido mortal para el paciente!
-[FEN_UKT]
-Tipo de juego no encontrado
+[A_FAIL3:AMBULAE]
+~r~¡El paciente está muerto!
-[FEN_NCI]
-NO CONECTADO A INTERNET
+[A_PASS:AMBULAE]
+¡Rescatado!
-[FET_PAU]
-MENÚ DE PAUSA
+[A_COMP2:AMBULAE]
+¡Nunca te cansarás!
-[FET_SGA]
-INICIAR PARTIDA
+[A_CANC:AMBULAE]
+~r~¡Misión de ATS cancelada!
-[FEC_SGJ]
-Establecer joystick de juego
+[A_COMP3:AMBULAE]
+¡Misiones de ATS completadas! ¡Nunca te cansarás cuando estés corriendo!
-[FEC_PAD]
-Mando
+[ALEVEL:AMBULAE]
+Misión de ATS nivel ~1~
-[FEC_JOY]
-Joystick
+[A_FAIL1:AMBULAE]
+Misión de ATS terminada.
-[FEC_WHL]
-Volante
+[A_SAVES:AMBULAE]
+PERSONAS SALVADAS: ~1~
-[FEC_CNT]
-Tipo de mando:
+[A_COMP1:AMBULAE]
+Misiones de ATS completas: ~1~ $
-[FET_APL]
-APLICAR
+{=================================== MISSION TABLE ASSIN1 ===================================}
-[FES_CSA]
-Selecciona una apariencia:
+[ASM1_5:ASSIN1]
+~r~¡Completó sus entregas!
-[FES_SKN]
-NOMBRE DE APARIENCIA
+[ASM1_6:ASSIN1]
+Entregas restantes:
-[FES_DAT]
-FECHA
+[ASM1_7:ASSIN1]
+~g~Carl Pearson, repartidor de pizza. Mátale antes que finalice el reparto.
-[FES_NON]
-NO HAY APARIENCIAS DISPONIBLES
+[ASM1_A:ASSIN1]
+Sr. Teal, su ayuda en erradicar a esos forasteros fue inestimable para el negocio. Tengo más trabajo para usted y más cercano a la ''intervención''.
-[FEA_FM9]
-REPRODUCTOR MP3
+[ASM1_D:ASSIN1]
+Sr. Teal, su ayuda en erradicar a esos forasteros fue inestimable para el negocio.
-[FESZ_QZ]
-¿Seguro que deseas guardar esta partida?
+{=================================== MISSION TABLE ASSIN2 ===================================}
-[FES_CGA]
-Espacios de partida disponibles:
+[ASM2_1:ASSIN2]
+~g~La Sra. Dawson dejará pronto la joyería de Vice Point. Mátala. Debe parecer un accidente de coche.
-[FES_SCG]
-¿Guardar la partida actual?
+[ASM2_3:ASSIN2]
+~g~¡Va a estallar! ¡Largo de aquí!
-[FES_LCG]
-¿Cargar la partida y seguir jugando?
+[ASM2_4:ASSIN2]
+~r~Dañaste su coche ¡y ni siquiera está en él! ¡Ahora no se subirá ahí!
-[FEC_FIR]
-Disparar
+[ASM2_5:ASSIN2]
+~r~¡Se escapó!
-[FEC_NWE]
-Siguiente arma
+[ASM2_6:ASSIN2]
+~r~¡Estabas demasiado cerca de la escena del ''accidente''!
-[FEC_PWE]
-Arma anterior
+[ASM2_7:ASSIN2]
+~g~¡No utilices armas! ¡Se supone que debe parecer un accidente! ¡En vez de eso, sácala de la carretera!
-[FEC_FOR]
-Avanzar
+[ASM2_8:ASSIN2]
+~g~Debes hacer que la muerte de la Sra. Dawson parezca un accidente. No utilices ningún arma.
-[FEC_BAC]
-Retroceder
+[ASM2_9:ASSIN2]
+~g~¡Necesitas un coche para este trabajo!
-[FEC_LEF]
-Izquierda
+[ASM2_10:ASSIN2]
+~g~Cuando el coche explote en llamas vete lo más lejos posible de la escena del accidente.
-[FEC_RIG]
-Derecha
+[ASM2_11:ASSIN2]
+¡Ayúdame!
-[FEC_ZIN]
-Acercar zoom
+[ASM2_12:ASSIN2]
+¡Que alguien me ayude!
-[FEC_ZOT]
-Alejar zoom
+[ASM2_13:ASSIN2]
+¡oh, Dios mío!
-[FEC_EEX]
-Entrar /salir
+[ASM2_A:ASSIN2]
+Felicidades por un trabajo bien hecho, Sr. Teal. Mi cliente está muy satisfecho.
-[FEC_RAD]
-Radio
+[ASM2_2:ASSIN2]
+salud:
-[FEC_SUB]
-Misión secundaria
+{=================================== MISSION TABLE ASSIN3 ===================================}
-[FEC_CMR]
-Cambiar cámara
+[ASM3_11:ASSIN3]
+TIEMPO:
-[FEC_JMP]
-Saltar
+[ASM3_C:ASSIN3]
+Una banda europea planea atracar un banco en Vice City. A mis jefes les gustaría que esto no sucediese.
-[FEC_SPN]
-Esprintar
+[ASM3_D:ASSIN3]
+Cada miembro de la banda tiene una tapadera mientras está aquí en Vice City. Algunos tienen trabajos sin importancia y otros están de vacaciones.
-[FEC_HND]
-Freno de mano
+[ASM3_E:ASSIN3]
+Cada objetivo y sus posibles paraderos están pegados con cinta adhesiva bajo el teléfono.
-[FEC_TUL]
-Torreta a izq.
+[ASM3_14:ASSIN3]
+~g~Dick Tanner está ubicado junto al DBP de Seguridad en Ocean Drive.
-[FEC_TUR]
-Torreta a dcha.
+[ASM3_15:ASSIN3]
+~g~Marcus Hammond y Franco Carter están ubicados junto a la joyería en Vice Point.
-[FEC_LOL]
-Mirar a izq.
+[ASM3_16:ASSIN3]
+~g~Nick Kong está en su barco cerca de Washington Beach.
-[FEC_LOR]
-Mirar a dcha.
+[ASM3_18:ASSIN3]
+~g~¡No te acerque demasiado al objetivo o te descubrirá y tendrás que perseguirle hasta atraparle!
-[FEC_NTR]
-Siguiente objetivo
+[ASM3_19:ASSIN3]
+~g~¡Te ha visto! ¡Acaba con él!
-[FEC_PTT]
-Objetivo anterior
+[ASM3_20:ASSIN3]
+~g~¡Te han visto! ¡Asegúrate de acabar con los dos!
-[FEC_LBA]
-Mirar atrás
+[ASM3_21:ASSIN3]
+~r~¡No mataste a todos los miembros de la banda a tiempo!
-[FEC_CEN]
-Centrar cámara
+[ASM3_22:ASSIN3]
+~g~¡No te acerques demasiado a los objetivos o te descubrirán e intentarán escapar.
-[FEC_UND]
-(NO)
+[ASM3_12:ASSIN3]
+~g~Se ha dejado cerca una selección de armas en caso de necesidad. Dispones de ~h~9 MINUTOS ~g~para matar a todos los miembros de la banda.
-[FET_CFT]
-A PIE
+[ASM3_13:ASSIN3]
+~g~Mike Griffin está trabajando en una valla de publicidad en Washington.
-[FET_CCR]
-EN VEHÍCULO
+[ASM3_17:ASSIN3]
+~g~Charlie Dilson está dando una vuelta en su moto en Washington.
-[CVT_MSG]
-Convirtiendo texturas a un formato óptimo para tu tarjeta de vídeo
+{=================================== MISSION TABLE ASSIN4 ===================================}
-[FET_CAC]
-ACCIÓN
+[ASM4_10:ASSIN4]
+~g~¡Parece que no eres el único que persigue el maletín! ¡Llévalo deprisa a Ammu- Nation!
-[FEC_IBT]
--
+[ASM4_12:ASSIN4]
+Distancia:
-[FEC_SPC]
-ESPACIO
+[ASM4_15:ASSIN4]
+~g~Busca el rifle de francotirador hacia tu derecha.
-[FEC_MXO]
-MXB1
+[ASM4_16:ASSIN4]
+~g~Observa a la mujer de la galería, bajará por las escaleras mecánicas y preguntará a alguien la hora.
-[FEC_MXT]
-MXB2
+[ASM4_17:ASSIN4]
+~g~Solamente cuando la conversación haya concluido, mata a la persona con la que habló, pero no la mates a ella.
-[FEC_UNB]
-SIN ASIGNAR
+[ASM4_18:ASSIN4]
+~g~Cuando el objetivo haya muerto, recupera el maletín y llévalo a Ammu-Nation, en el centro.
-[FET_CME]
-MÉTODO DE CONTROL
+[ASM4_19:ASSIN4]
+~g~Mantén tu distancia del objetivo, la barra de distancia de la parte superior de la pantalla te indica lo cerca que estás del objetivo.
-[FET_RDK]
-REDEFINIR CONTROLES
+[ASM4_20:ASSIN4]
+~g~No dejes que se llene o te verá.
-[FET_AMS]
-AJUSTES DEL RATÓN
+[ASM4_21:ASSIN4]
+~g~¡Recoge el maletín!
-[FET_STI]
-CONFIGURACIÓN DE CONTROL ESTÁNDAR
+[ASM4_22:ASSIN4]
+~g~Lleva el maletín a Ammu-Nation, en el centro.
-[FET_CTI]
-CONFIGURACIÓN DE CONTROL CLÁSICA
+[ASM4_23:ASSIN4]
+~g~¡Te ha visto y se escapa, atrápale y consigue el maletín!
-[FET_MTI]
-CONFIGURACIÓN DE CONTROL CON RATÓN
+[ASM4_25:ASSIN4]
+~r~¡Has matado a la mujer, idiota!
-[FET_DAM]
-MODELADO ACÚSTICO DINÁMICO
+[ASM4_26:ASSIN4]
+~r~¡El objetivo ha subido a su avión!
-[FEC_TFL]
-Torreta a izq.
+[ASM4_27:ASSIN4]
+~r~¡El objetivo te ha visto! ¡Deberías mantener tu distancia!
-[FEC_TFR]
-Torreta a dcha.
+[ASM4_28:ASSIN4]
+~r~¡El objetivo te ha visto! ¡Te ha escuchado disparar el arma!
-[FEC_TFU]
-Torreta /Dodo arriba
+[ASM4_29:ASSIN4]
+~r~¡Mátale sólo después que haya hablado con la mujer!
-[FEC_TFD]
-Torreta /Dodo abajo
+[ASM4_A:ASSIN4]
+Es hora de ir a por el pez gordo, Sr. Teal. Hay un rifle a su derecha, tras la maceta.
-[FEC_MWF]
-RUEDA ARR.
+[ASM4_B:ASSIN4]
+Observe a la mujer que está en la galería por encima de los mostradores de facturación. Caminará por entre la gente y le preguntará a alguien la hora.
-[FEC_MWB]
-RUEDA AB.
+[ASM4_C:ASSIN4]
+Debe matar a esa persona, recoger el maletín y llevarlo al lugar adherido con cinta bajo el teléfono.
-[FEC_ORR]
-o
+{=================================== MISSION TABLE ASSIN5 ===================================}
-[FEC_NUS]
-SIN USO
+[ASM5_A:ASSIN5]
+Un valioso canje va a tener lugar en el tejado de la compañía de helados Cherry Popper.
-[FEC_LUD]
-Mirar arriba
+[ASM5_B:ASSIN5]
+Liquide a todos los implicados, robe el maletín y llévelo al helipuerto del aeropuerto.
-[FEC_LDU]
-Mirar abajo
+[ASM5_C:ASSIN5]
+Hay una puerta a su izquierda que conduce a la parte trasera de la fábrica.
-[FEC_CMP]
-COMBO: MIRAR I+D
+[ASM5_1:ASSIN5]
+~g~Entra al complejo por detrás de la compañía de helados Cherry Popper y dirígete al tejado donde va a tener lugar el trato.
-[FEC_NTT]
-No hay texto para esta tecla
+[ASM5_2:ASSIN5]
+~g~Consigue el maletín y llévalo al helipuerto del aeropuerto.
-[FEC_FNC]
-F~1~
+[ASM5_3:ASSIN5]
+~g~¡Lleva el maletín al helipuerto del aeropuerto!
-[FEC_IRT]
-INSERT
+{=================================== MISSION TABLE BANKJ1 ===================================}
-[FEC_DLL]
-SUPR
+[WANTED1:BANKJ1]
+~g~¡Quítate de encima a los polis y pierde tu nivel de se busca!
-[FEC_HME]
-INICIO
+[BJM1_A:BANKJ1]
+¡Tommy! ¡Eh, Tommy, mira esto, es genial! ¡He hecho que nos instalen un minibar!
-[FEC_END]
-FIN
+[BJM1_B:BANKJ1]
+Tenemos todo un bar abajo, Ken.
-[FEC_PGU]
-RE PÁG
+[BJM1_C:BANKJ1]
+Sí, sí, vale. Bueno, tengo la pizarra que pediste.
-[FEC_PGD]
-AV PÁG
+[BJM1_D:BANKJ1]
+Eso es lo bueno de estudiar derecho: te enseñan a seguir las instrucciones.
-[FEC_UPA]
-ARRIBA
+[BJM1_E:BANKJ1]
+Necesito un hombre para la caja fuerte.
-[FEC_DWA]
-ABAJO
+[BJM1_F:BANKJ1]
+De acuerdo, bueno, déjame pensar... caja fuerte, caja fuerte, caja fuerte, caja fuerte... ¡Lo tengo! ¡Este tipo te va a encantar!
-[FEC_LFA]
-IZDA
+[BJM1_G:BANKJ1]
+Ah, ese idiota no. Está encerrado.
-[FEC_RFA]
-DCHA
+[BJM1_H:BANKJ1]
+¿Encerrado dónde?
-[FEC_NUM]
-NUM.
+[BJM1_I:BANKJ1]
+En la celda de una comisaría esperando el traslado.
-[FEC_NMN]
-NUM. ~1~
+[BJM1_J:BANKJ1]
+Creo que está a punto de conseguir la libertad condicional...
-[FEC_FWS]
-NUM. /
+[BJM1_1:BANKJ1]
+~g~¡Libera a Cam Jones de la comisaría de policía!
-[FEC_PLS]
-NUM. +
+[BJM1_3:BANKJ1]
+~g~Encontrarás algo útil en el vestuario de la comisaría.
-[FEC_MIN]
-NUM. -
+[BJM1_21:BANKJ1]
+~g~Puedes encontrar la llave de las celdas en el piso de arriba de la comisaría.
-[FEC_DOT]
-NUM. .
+[BNK1_7:BANKJ1]
+¿Cam Jones?
-[FEC_NLK]
-BLOQ NUM
+[BNK1_8:BANKJ1]
+¡Te voy a sacar de aquí!
-[FEC_ETR]
-INTRO
+[BNK1_10:BANKJ1]
+Sí, soy yo...
-[FEC_SLK]
-BLOQ DESPL
+[BNK1_11:BANKJ1]
+¡Lo que tú digas!
-[FEC_PSB]
-PAUSA/INTER
+[BNK1_13:BANKJ1]
+Voy a hacer un trabajo y tu serás mi revienta cajas fuertes.
-[FEC_BSP]
-RETROCESO
+[BNK1_14:BANKJ1]
+¡Eso es mejor que pudrirse en una celda!
-[FEC_TAB]
-TAB
+[BJM1_22:BANKJ1]
+~g~¡Lleva a Cam de vuelta a su casa!
-[FEC_CLK]
-BLOQ MAYÚS
+[BJM1_23:BANKJ1]
+~g~¡Necesitas coger la tarjeta llave primero!
-[FEC_RTN]
-INTRO
+[BNK1_12:BANKJ1]
+¡Piérdeles el rastro y llévame a mi casa!
-[FEC_LSF]
-MAYÚS IZQ
+[BJM1_20:BANKJ1]
+¡Guarda el arma o te enfréntate a las consecuencias!
-[FEC_RSF]
-MAYÚS DCHA
+[BJM1_5:BANKJ1]
+¡Sólo personal autorizado más allá de este punto!
-[FEC_LCT]
-CTRL IZQ
+[BJM1_2:BANKJ1]
+~r~¡Se supone que tenías que sacar a rastras a Cam, no matarle!
-[FEC_RCT]
-CTRL DCHO
+[BJM1_4:BANKJ1]
+¡Está armado! ¡Mátale!
-[FEC_LAL]
-ALT IZQ
+{=================================== MISSION TABLE BANKJ2 ===================================}
-[FEC_RAL]
-ALT DCHO
+[BJM2_A:BANKJ2]
+Necesitamos a un atracador. ¿Conoces a alguno?
-[FEC_LWD]
-WIN IZQ
+[BJM2_B:BANKJ2]
+Eh, Tommy, Tommy, Tommy, esta mierda te pone a tono, tío.
-[FEC_RWD]
-WIN DCHO
+[BJM2_C:BANKJ2]
+¡Guauuuuu!
-[FEC_WRC]
-APMENÚ
+[BJM2_D:BANKJ2]
+¡Yo podría ser tu atracador! ¡Manos arriba! ¡Manos arriba!
-[WIN_TTL]
-Grand Theft Auto III
+[BJM2_E:BANKJ2]
+Tú no eres un atracador, tú eres un idiota.
-[WIN_95]
-Grand Theft Auto III no se puede ejecutar bajo Windows 95
+[BJM2_F:BANKJ2]
+Ahora ponte una copa y cállate.
-[WIN_DX]
-Grand Theft Auto III necesita al menos la versión 8.1 de DirectX
+[BJM2_G:BANKJ2]
+Eh. ¡Quítate de mi camino! Sí, sí, sí, eh, eh.
-[WIN_VDM]
-Grand Theft Auto III necesita al menos 12 MB de memoria de vídeo
+[BJM2_H:BANKJ2]
+¿Cam, tú qué opinas?
-[DIAB3_G]
-¡Arriba!
+[BJM2_I:BANKJ2]
+Bueno, el mejor tirador de esta ciudad es un tipo llamado Cassidy.
-[FEM_RES]
-REANUDAR PARTIDA
+[BJM2_J:BANKJ2]
+¿Seguro?
-[FES_SNG]
-INICIAR NUEVA PARTIDA
+[BJM2_K:BANKJ2]
+Sí. Un militar, o al menos él piensa que lo es.
-[FEM_SP]
-UN JUGADOR
+[BJM2_L:BANKJ2]
+Dudo que estuviese alguna vez en el ejército, pero desde luego sabe manejar las armas.
-[FEM_MP]
-MULTIJUGADOR
+[BJM2_M:BANKJ2]
+Estará en el campo de tiro.
-[FEM_QT]
-SALIR
+[BJM2_2A:BANKJ2]
+¿Tú eres Phil Cassidy?
-[FES_SG]
-INICIAR NUEVA PARTIDA
+[BJM2_2B:BANKJ2]
+¿Por qué?
-[FES_LG]
-CARGAR PARTIDA
+[BJM2_2C:BANKJ2]
+Estoy buscando a un hombre que sepa manejar un arma. Pero ahora que te veo, no estoy muy convencido.
-[FEM_HST]
-CREAR PARTIDA
+[BJM2_2D:BANKJ2]
+Hijo, podría quitarte una mosca de la cabeza de un solo disparo a 100 metros.
-[FEM_OPT]
-OPCIONES
+[BJM2_2E:BANKJ2]
+Oh, ¿de verdad?
-[FEM_DBG]
-DEPURACIÓN
+[BJM2_2F:BANKJ2]
+Sí. Aprendí en el ejército.
-[FET_PSU]
-AJUSTES DE JUGADOR
+[BJM2_2G:BANKJ2]
+¿Se suele disparar a las moscas en el ejército? Me alegra no pagar impuestos.
-[FET_DEF]
-RESTAURAR PREDETERMINADOS
+[BJM2_2H:BANKJ2]
+¿Intentas ser gracioso?
-[FED_BRI]
-BRILLO
+[BJM2_2I:BANKJ2]
+~n~
-[FED_TRA]
-ESTELAS
+[BJM2_2J:BANKJ2]
+Vamos a disparar.
-[FEM_LOD]
-DISTANCIA DE DIBUJADO
+[BJM2_1:BANKJ2]
+~g~Ve a Ammu-Nation en el centro de la ciudad y habla con Phil Cassidy.
-[FEM_VSC]
-SINCRONIZAR IMAGEN
+[BJM2_3:BANKJ2]
+TASA DE IMPACTOS: ~1~%
-[FEM_FRM]
-LIMITADOR DE FOTOGRAMAS
+[BJM2_4:BANKJ2]
+PUNTUACIÓN PRIMERA FASE: ~1~
-[FED_RES]
-RESOLUCIÓN
+[BJM2_6:BANKJ2]
+PUNTUACIÓN SEGUNDA FASE: ~1~
-[FED_WIS]
-PANTALLA PANORÁMICA
+[BJM2_7:BANKJ2]
+PUNTUACIÓN TOTAL DE DISPARO: ~1~
-[FEDS_TB]
-ATRÁS
+[BJM2_9:BANKJ2]
+~g~Ve al punto de inicio de la segunda fase.
-[FEA_MUS]
-VOLUMEN DE MÚSICA
+[BJM2_11:BANKJ2]
+~r~¡Phil está muerto!
-[FEA_SFX]
-VOLUMEN DE EFECTOS
+[BJM2_12:BANKJ2]
+~r~¡Uno de los tiradores está muerto!
-[FEA_RSS]
-EMISORA DE RADIO
+[BJM2_14:BANKJ2]
+~g~¡Pasa a la siguiente fase!
-[FEL_ENG]
-INGLÉS
+[BJM2_15:BANKJ2]
+PUNTUACIÓN:
-[FEL_FRE]
-FRANCÉS
+[BJM2_17:BANKJ2]
+~g~Ve y habla con Phil.
-[FEL_GER]
-ALEMÁN
+[BJM2_18:BANKJ2]
+PUNTUACIÓN A SUPERAR:
-[FEL_ITA]
-ITALIANO
+[BJM2_19:BANKJ2]
+~g~¡Acierta a tantos blancos como puedas dentro del límite de tiempo!
-[FEL_SPA]
-ESPAÑOL
+[BJM2_22:BANKJ2]
+~r~¡Has abandonado el campo de tiro!
-[FEA_3DH]
-HARDWARE DE SONIDO
+[BJM2_23:BANKJ2]
+~g~Si abandonas el campo de tiro durante la competición, fracasarás en la misión.
-[FEA_SPK]
-CONFIGURACIÓN DE ALTAVOCES
+[BJM2_24:BANKJ2]
+~g~El objetivo más cercano vale un punto.
-[FEA_2SP]
-2 ALTAVOCES
+[BJM2_25:BANKJ2]
+~g~El objetivo del medio vale dos puntos.
-[FEA_4SP]
-MÁS DE 2 ALTAVOCES
+[BJM2_27:BANKJ2]
+~g~Todos los objetivos de esta ronda valen un punto.
-[FEA_EAR]
-AURICULARES
+[BNK2_2:BANKJ2]
+APUNTA, 3, 2, 1... ¡FUEGO!
-[FEA_NAH]
-NO HAY HARDWARE DE SONIDO
+[BNK2_3:BANKJ2]
+¡ZONA DESPEJADA!
-[FET_SNG]
-INICIAR NUEVA PARTIDA
+[BNK2_4:BANKJ2]
+¡Yupiiiiiii!
-[GMSAVE]
-GUARDAR PARTIDA
+[BNK2_5:BANKJ2]
+¡No podrías darle ni a un elefante a 2 metros!
-[FES_DGA]
-BORRAR PARTIDA
+[BNK2_7:BANKJ2]
+Entonces, ¿quieres hacerme un favor y ayudarme a preparar un atraco?
-{ STRING MISSING FROM THE OFFICIAL SPANISH TRANSLATION. }
+[BNK2_8:BANKJ2]
+Hijo, disparando de ese modo, si me pidieras que sea tu mujer, te diría que sí.
-[FEM_NON]
-NADA
+[BNK2_9A:BANKJ2]
+Hijo, mejor será que te vayas y te metas tus ideas y palabrería donde te quepan. Eres una mierda disparando.
-[FEC_IVV]
-INVERTIR VERTICALIDAD RATÓN
+[BNK2_9B:BANKJ2]
+Eres una mierda disparando.
-[FEC_MSH]
-SENSIBILIDAD DEL RATÓN
+[BJM2_28:BANKJ2]
+PUNTUACIÓN RONDA TRES: ~1~
-[FET_CCN]
-CONTROL: CLÁSICO
+[BJM2_20:BANKJ2]
+~g~¡La ronda se acabará cuando te quedes sin ~w~tiempo ~g~o ~w~munición~g~!
-[FET_SCN]
-CONTROL: ESTÁNDAR
+[BJM2_26:BANKJ2]
+~g~El objetivo más lejano vale tres puntos.
-[FES_SET]
-USAR APARIENCIA
+[BNK2_1:BANKJ2]
+MUNICIÓN CARGADA
-[GHOST]
-Ghost
+[RANGE_1:BANKJ2]
+PUNTUACIÓN POR DISPARO: ~1~
-[WIN_RSZ]
-Error al seleccionar la nueva resolución de pantalla
+[BJM2_2:BANKJ2]
+~g~Para abandonar la ronda, pulsa ~h~~k~~PED_JUMPING~.
-[FET_APP]
-BIR, INTRO: APLICAR AJUSTES
+[BJM2_N:BANKJ2]
+Tranqui.
-[FET_HRD]
-AJUSTES PREDETERMINADOS RESTAURADOS
+{=================================== MISSION TABLE BANKJ3 ===================================}
-[FET_MST]
-CONDUCCIÓN CONTROLADA POR EL RATÓN
+[BJM3_A:BANKJ3]
+Las cosas empiezan a ir bien.
-[FEC_STR]
-NUM. INICIO
+[BJM3_B:BANKJ3]
+¿Cuál es el plan, Tommy? ¿Qué pasa, amigo?
-[FET_MIG]
-IZQUIERDA, DERECHA, RUEDA DEL RATÓN: AJUSTAR
+[BJM3_C:BANKJ3]
+El plan es que tú sigas haciendo el imbécil. En fin, necesitamos a un conductor.
-[FET_CIG]
-RETROCESO: QUITAR - BIR, INTRO: CAMBIAR
+[BJM3_D:BANKJ3]
+Tommy, yo lo haré. Sé conducir.
-[FET_RIG]
-SELECCIONA UN NUEVO CONTROL O PULSA ESC PARA CANCELAR
+[BJM3_E:BANKJ3]
+Necesitamos a Hilary, señor, no a un picapleitos charlatán.
-[FET_EIG]
-NO SE PUEDE DEFINIR UN CONTROL PARA ESTA ACCIÓN
+[BJM3_F:BANKJ3]
+Hilary es nuestra mejor opción. Seguro que no has visto nunca conducir a nadie tan rápido. Voy a darle un toque.
-[NO_PCCD]
-Por favor, introduce el disco 2 de Grand Theft Auto III en la unidad o pulsa ESC para cancelar
+[BJM3_G:BANKJ3]
+Eh, Hil, soy Phil. ¿Cómo te va? No, no hables. Recordaremos los viejos tiempos más tarde. ¿Quieres hacerme un favor?
-[CVT_ERR]
-Te has quedado sin espacio en el disco duro. Por favor, libera espacio en tu disco duro antes de continuar. Pulsa ESC para cancelar.
+[BJM3_H:BANKJ3]
+Tengo a un tipo del norte... No, no, no creo que sirviese en el ejército, pero quiere un conductor.
-[FED_SUB]
-SUBTÍTULOS
+[BJM3_I:BANKJ3]
+Por un poco de acción. De acuerdo, comprendo.
-[FET_DSN]
-Apariencia predeterminada del jugador.bmp
+[BJM3_J:BANKJ3]
+¿Qué dijo?
-[JM3]
-'EL ROBO DEL FURGÓN'
+[BJM3_K:BANKJ3]
+Bueno, lo hará, no hay problema. Bueno, podría haber un pequeño problema... Verás, tiene miedo al abandono.
-[EBAL]
-'DAME LIBERTAD'
+[BJM3_L:BANKJ3]
+Y parece que no trabajará para nadie que no pueda derrotarle. Tiene algo que ver con su madre o algo así.
-[LM4]
-'UN CHULO Y SU ESCOPETA'
+[BJM3_M:BANKJ3]
+De todas formas primero quiere echarte una carrera, dice que se encontrará contigo fuera...
-[REPLAY]
-REPETICIÓN
+[BJM3_2A:BANKJ3]
+¿Eres Tommy? Por supuesto que eres Tommy, quiero decir,
-[FEC_SFT]
-MAYÚS
+[BJM3_2B:BANKJ3]
+¿quién más querría hablar conmigo?
-[CRED254]
-JEFE DEL ESTUDIO
+[BJM3_2C:BANKJ3]
+Vale. Esto es lo que hay.
-[CVT_CRT]
-No se pueden convertir las texturas para tu tarjeta de vídeo. Necesitas privilegios de administrador. Pulsa ESC para salir.
+[BJM3_2D:BANKJ3]
+Conduciré para ti solamente si me demuestras que conduces bien.
-[FEM_ON]
-SÍ
+[BJM3_2E:BANKJ3]
+Déjame tirado, y nunca te perdonaré.
-[FEM_OFF]
-NO
+[BJM3_2:BANKJ3]
+~r~¡Hilary está muerto!
-[FEM_YES]
-SÍ
+[BJM3_4:BANKJ3]
+~g~¡Necesitas un coche para participar!
-[FEM_NO]
-NO
+[BNK3_1:BANKJ3]
+Vale. Te llevaré pero por favor, machácame un poco.
-[FES_WAR]
-Guardando, espera...
+[BNK3_3A:BANKJ3]
+Carrera callejera ilegal en progreso en Vice Point.
-[FED_DLW]
-Borrando, espera...
+[BNK3_3B:BANKJ3]
+Llamando a todos los agentes.
-[FED_LDW]
-Cargando, espera...
+[BNK3_3C:BANKJ3]
+Corredores callejeros, ¡esto es ilegal y no está permitido!
-[FEC_SLC]
-Ranura dañada
+{=================================== MISSION TABLE BANKJ4 ===================================}
-[FED_LFL]
-Error al cargar la partida. El juego se reiniciará.
+[BNK4_A:BANKJ4]
+~w~Como podéis ver, caballeros, éste va a ser el dinero más fácil que hayamos ganado jamás.
-[FET_RSO]
-SE HAN REINICIADO LOS AJUSTES
+[BNK4_B:BANKJ4]
+~w~Tommy, de verdad, tienes que plantearte seriamente el meterte en la abogacía.
-[FET_RSC]
-HARDWARE NO DISPONIBLE. RESTAURADO AJUSTE ORIGINAL
+[BNK4_C:BANKJ4]
+~w~Pero, ¿qué coño te estás fumando, tío? ¡Este no es un plan sencillo!
-[CRED270]
-MIKE HONG
+[BNK4_D:BANKJ4]
+~w~Bueno, de todas formas, ¿quién necesita un plan sencillo?
+
+[BNK4_E:BANKJ4]
+~w~Mira el comunismo, bien, pues ese era un plan sencillo. Y jodió bien a Rusia ¿no?
+
+[BNK4_F:BANKJ4]
+~w~Cálmate, ¿vale? Con un equipo como éste, no va a haber problemas.
+
+[BNK4_G:BANKJ4]
+~w~Tenemos a Cam en la caja fuerte. ¿Phil? Tú y yo nos encargaremos de la seguridad y Hilary conducirá el coche de huída.
+
+[BNK4_H:BANKJ4]
+~w~Uh, je, je, ¿no te olvidas de alguien? ¿Alguien que te ayudó siempre en esta ciudad? ¿Alguien...?
+
+[BNK4_I:BANKJ4]
+~w~Ken... Ken, es cierto. Aquí Ken, él nos lavará el dinero y mantendrá las bebidas frías.
+
+[BNK4_J:BANKJ4]
+~w~No comprendo qué se supone que debo hacer aquí.
+
+[BNK4_K:BANKJ4]
+~w~Mira, es sencillo. ¿No has visto nunca una película?
+
+[BNK4_L:BANKJ4]
+~w~Entramos en el banco, enseñamos las armas y nos marchamos siendo hombres muy ricos.
+
+[P_DEAD:BANKJ4]
+~r~¡Phil está muerto!
+
+[C_DEAD:BANKJ4]
+~r~¡Cam está muerto!
+
+[H_DEAD:BANKJ4]
+~r~¡Hilary está muerto!
+
+[P_HIND:BANKJ4]
+~r~¡Has perdido a Phil!
+
+[C_HIND:BANKJ4]
+~r~¡Cam se ha quedado atrás!
+
+[H_HIND:BANKJ4]
+~r~¡Hilary ha sido abandonado!
+
+[GETCAR:BANKJ4]
+~g~¡Sube en el coche de escapada para hacer el trabajito del banco!
+
+[TRASHED:BANKJ4]
+~r~¡DESTROZASTE EL COCHE DE FUGA!
+
+[BNK4_1:BANKJ4]
+Yo conduciré.
+
+[BNK4_2:BANKJ4]
+Genial. Un pasajero. Espera a que les hable de esto al grupo.
+
+[BNK4_3A:BANKJ4]
+¡Eh, cuidado con las ruedas, Tommy!
+
+[BNK4_3B:BANKJ4]
+¡Tommy, Hilary está ocupando mucho espacio!
+
+[BNK4_3C:BANKJ4]
+¡No es verdad!
+
+[BNK4_3D:BANKJ4]
+¡Sí!
+
+[BNK4_3E:BANKJ4]
+Eh, callaos los dos o iréis andando.
+
+[BNK4_3F:BANKJ4]
+Sí, Hilary.
+
+[BNK4_3I:BANKJ4]
+Por el amor de Dios, Phil, deja de agitar esa cosa.
+
+[BNK4_3J:BANKJ4]
+¡Sí, le sacarás un ojo a alguien!
+
+[BNK4_3M:BANKJ4]
+¡Mi pequeña! ¡Está hecha un desastre!
+
+[BNK4_3O:BANKJ4]
+Te aferras a la ilusión de una permanencia perpetua...
+
+[BNK4_3P:BANKJ4]
+¿Qué?
+
+[BNK4_3Q:BANKJ4]
+Crees que todas las cosas durarán.
+
+[BNK4_3R:BANKJ4]
+La juventud, los seres queridos, la pizza...
+
+[BNK4_3S:BANKJ4]
+Todo pasará o terminará y debes aceptar eso.
+
+[BNK4_3T:BANKJ4]
+Sí, tienes razón. Gracias, Cam.
+
+[BNK4_3U:BANKJ4]
+No hay de que.
+
+[BNK4_3V:BANKJ4]
+Eh, Tommy, ¿por qué nos hemos detenido?
+
+[BNK4_4A:BANKJ4]
+~w~Hilary, sigue conduciendo en torno a la manzana.
+
+[BNK4_5:BANKJ4]
+~w~De acuerdo, Tommy, de acuerdo.
+
+[BNK4_6:BANKJ4]
+~w~¡ESTO ES UN ATRACO!
+
+[BNK4_7:BANKJ4]
+~w~¡QUE NADIE SE MUEVA!
+
+[BNK4_8:BANKJ4]
+~w~¡TODO EL MUNDO CONTRA ESA PARED!
+
+[BNK4_9:BANKJ4]
+¡Phil, quédate vigilando!
+
+[BNK4_10:BANKJ4]
+¡No problemo!
+
+[BNK4_11:BANKJ4]
+Vamos, Cam, la cámara acorazada está arriba...
+
+[BK4_12A:BANKJ4]
+¡Maldición! ¡Es una Flange 9000!
+
+[BK4_12B:BANKJ4]
+Podría tardar horas en abrirla,
+
+[BK4_12C:BANKJ4]
+o cinco minutos si encuentras al director.
+
+[BNK4_13:BANKJ4]
+Iré a averiguar en qué agujero se ha metido.
+
+[BK4_14A:BANKJ4]
+Phil, ¿van bien las cosas?
+
+[BNK4_15:BANKJ4]
+Sí. Todo está muy tranquilo.
+
+[BNK4_16:BANKJ4]
+¡Tú, ven conmigo!
+
+[BNK4_17:BANKJ4]
+¡De acuerdo! ¡De acuerdo! ¡Por favor, no dispare!
+
+[BNK4_18:BANKJ4]
+¡DIJE QUE NO SE MOVIESE NADIE!
+
+[BK4_19A:BANKJ4]
+Tiene un cierre temporizado.
+
+[BK4_19B:BANKJ4]
+¡Podríais rendiros ahora mismo!
+
+[BK4_20A:BANKJ4]
+Diablos, puedo hacer un puente en el cierre temporizado,
+
+[BK4_20B:BANKJ4]
+¡Así que solo necesitaremos tu código de acceso y ya está!
+
+[BNK4_21:BANKJ4]
+Quédate aquí. Intenta algo y serás comida para los peces. ¿Lo captas?
+
+[BNK422A:BANKJ4]
+Cam, ¿cuánto tiempo?
+
+[BK4_23A:BANKJ4]
+¡Dame cinco minutos!
+
+[BK4_24A:BANKJ4]
+Voy a comprobar qué tal va Phil, volveré.
+
+[BK4_24B:BANKJ4]
+¡Te dije que no tocases esa alarma!
+
+[BNK4_25:BANKJ4]
+¡Los de operaciones especiales estarán aquí en cualquier momento!
+
+[BNK4_27:BANKJ4]
+¡Me vendría bien un poco de ayuda aquí, Tommy!
+
+[BNK4_28:BANKJ4]
+¡SWAT de Vice City! ¡Estáis rodeados!
+
+[BNK4_29:BANKJ4]
+¿Rodeados?
+
+[BNK4_30:BANKJ4]
+La están cagando, ¡bastardos corruptos!
+
+[BK4_31A:BANKJ4]
+¡Tommy! ¡La cámara acorazada está abierta!
+
+[BK4_34A:BANKJ4]
+De acuerdo, tenemos el fondo de pensiones de los SWAT. ¡Salgamos de aquí!
+
+[BK4_34B:BANKJ4]
+¡De acuerdo, vosotros lo habéis pedido! ¡Habéis tenido vuestra última oportunidad!
+
+[BK4_35A:BANKJ4]
+¡Van a arrasar el lugar!
+
+[BK4_35B:BANKJ4]
+¡A cubierto!
+
+[BNK4_94:BANKJ4]
+~w~De acuerdo chicos. Ha sido tan fácil como lo habíamos planeado.
+
+[BM_DEAD:BANKJ4]
+~r~¡Necesitas al director del banco vivo!
+
+[ASSET_A:BANKJ4]
+¡ATRACO AL BANCO COMPLETADO!
+
+[ASSET_B:BANKJ4]
+~g~El Club Malibú generará ahora unos ingresos máximos de hasta ~1~ $ al día. ¡Asegúrate de recaudarlos regularmente!
+
+[IDIOT:BANKJ4]
+~r~ Eso es, ve por ahí vestido como un chiflado y llamando la atención, ¡IDIOTA!
+
+{=================================== MISSION TABLE BARON1 ===================================}
+
+[COK1_A:BARON1]
+Vamos nena, vamos, sí, ¡sí!
+
+[COK1_B:BARON1]
+¡Estúpido caballo! ¡Te cortaré la cabeza!
+
+[COK1_C:BARON1]
+¿Quién es este gilipollas?
+
+[COK1_D:BARON1]
+Tommy Vercetti, ¿me recuerdas?
+
+[COK1_E:BARON1]
+Perdóname, estoy un poco alterado. ¡Nunca te fíes de un maldito caballo!
+
+[COK1_F:BARON1]
+Hiciste un buen trabajo... ahora trabajas para mí.
+
+[COK1_H:BARON1]
+Como dije amigo, trabajas para mí. Ahora, cállate. Algún Judas me ha traicionado.
+
+[COK1_I:BARON1]
+Él cree que no sé cuando dinero debería sacar con esto, pero robar un 3% es tan malo como robar el 100%.
+
+[COK1_J:BARON1]
+Nadie me hace esto a mí. ¡NADIE!
+
+[COK1_K:BARON1]
+¡Le sigues desde su apartamento y ves a dónde va! Más tarde, le mataremos.
+
+[COK1_1:BARON1]
+¡Mierda!
+
+[COK1_2:BARON1]
+¡Demasiado lento, abuelo!
+
+[COK1_4:BARON1]
+Perdedor.
+
+[COK1_5:BARON1]
+¡Mejor sigue corriendo, gilipollas!
+
+[COK1_8:BARON1]
+~g~¡Rápido! ¡Consigue un vehículo y síguele!
+
+[COK1_9:BARON1]
+~r~¡Se supone que debes seguirle, no matarle!
+
+[COK1_10:BARON1]
+~r~Ve a la casa del ladrón y descubre dónde esconde el dinero.
+
+[COK1_11:BARON1]
+~g~Echa un vistazo por su ventana.
+
+[COK1_7:BARON1]
+~g~¡Se ha escapado por el tejado, ve tras él pero no le mates!
+
+[COK1_G:BARON1]
+Trabajo por dinero.
+
+{=================================== MISSION TABLE BARON2 ===================================}
+
+[COK2_A:BARON2]
+¿Qué clase de tonto incompetente eres?
+
+[COK2_B:BARON2]
+¡TONTO! ¡TONTO! ¡TONTO! ¡TONTO!
+
+[COK2_C:BARON2]
+Tommy...
+
+[COK2_D:BARON2]
+¿Qué pasa, Ricardo?
+
+[COK2_E:BARON2]
+Estos idiotas... Siempre intentan joderle a uno.
+
+[COK2_F:BARON2]
+Ese es el problema de este negocio.
+
+[COK2_G:BARON2]
+¿Qué crees que estás haciendo?
+
+[COK2_H:BARON2]
+Estos mamones me han fallado miserablemente.
+
+[COK2_I:BARON2]
+Pronto cualquier madre o padre creerán que pueden vender farlopa en Vice City.
+
+[COK2_J:BARON2]
+¿Y ahora qué, eh? ¿La apestosa Mafia?
+
+[COK2_K:BARON2]
+Ese antro de mafiosos es una fortaleza inexpugnable desde el suelo,
+
+[COK2_L:BARON2]
+así que Quentin... ¡Quentin! ¡QUENTIN!
+
+[COK2_M:BARON2]
+¡Volará sobre la zona!
+
+[COK2_N:BARON2]
+¡Hacedles desaparecer!
+
+[COK2_O:BARON2]
+¿Qué crees que estás haciendo?
+
+[COK2_P:BARON2]
+¿Qué haces aquí?
+
+[COK2_Q:BARON2]
+He estado haciendo preguntas por ahí, y es obvio
+
+[COK2_R:BARON2]
+que Diaz se saltó el trato y se cargó a mi hermano.
+
+[COK2_S:BARON2]
+¡Y te matará a ti también!
+
+[COK2_T:BARON2]
+¡Puedo encargarme de Diaz!
+
+[COK2_U:BARON2]
+No. ¡Escúchame! Yo me encargaré de Diaz...
+
+[COK2_V:BARON2]
+Está empezando a confiar en mí.
+
+[COK2_1:BARON2]
+Hay una cosa que me mosquea... ¿por qué Quentin?
+
+[COK2_2:BARON2]
+No sé, siempre me ha gustado... Quentin Vance...
+
+[COK2_3:BARON2]
+¿Vance? ¿Tu nombre es Lance Vance?
+
+[COK2_4:BARON2]
+¡Eh! ¡Ya tuve bastante con eso en la escuela!
+
+[COK2_5:BARON2]
+¿Alguna vez has disparado uno de esos desde un helicóptero?
+
+[COK2_8:BARON2]
+En fin, ¿a dónde nos dirigimos?
+
+[COK2_9:BARON2]
+A Prawn Island.
+
+[COK2_13:BARON2]
+Lance Vance. Pobre desgraciado.
+
+[COK2_14:BARON2]
+Bien, casi hemos llegado.
+
+[COK2_15:BARON2]
+Daremos un par de pasadas.
+
+[COK2_16:BARON2]
+Así que elimina a tantos como puedas.
+
+[COK2_17:BARON2]
+Después te dejaré abajo y te las arreglarás solo.
+
+[COK2_20:BARON2]
+¡Mierda! ¡Ésto es una zona de guerra! ¡Elimina a algunos de esos pistoleros!
+
+[COK2_21:BARON2]
+¡Nos están alcanzando, tío!
+
+[COK2_22:BARON2]
+¡Arreglar esta cosa no sale barato! ¡Elimínalos!
+
+[COK2_23:BARON2]
+Vale, de ahora en adelante es cosa tuya... ¡Buena suerte, hermano!
+
+[COK2_24:BARON2]
+Helicóptero:
+
+[COK2_25:BARON2]
+~g~Ve y recoge el dinero del tejado.
+
+[COK2_27:BARON2]
+¡Estás en mi territorio, gilipollas!
+
+[COK2_28:BARON2]
+¡Vas a desaparecer!
+
+[COK2_6:BARON2]
+No. Practicaré un poco por el camino.
+
+[OPEN_B:BARON2]
+Los controles policiales con dirección a la península han sido levantados
+
+{=================================== MISSION TABLE BARON3 ===================================}
+
+[COK3_A:BARON3]
+Ahora ya no os sentís tan complacidas, ¿eh?
+
+[COK3_B:BARON3]
+~n~
+
+[COK3_C:BARON3]
+¡Guau! Mira hacia donde mueves esa cosa.
+
+[COK3_D:BARON3]
+Ya no habrá más mierda de paloma en mi coche, ¿eh, Tommy?
+
+[COK3_E:BARON3]
+Supongo que no.
+
+[COK3_F:BARON3]
+Tienes toda la razón. Ahora escucha,
+
+[COK3_G:BARON3]
+¿sabes quién posee el barco más rápido de la costa este?
+
+[COK3_H:BARON3]
+Ni idea.
+
+[COK3_I:BARON3]
+Yo. Y quiero que siga siendo así.
+
+[COK3_J:BARON3]
+Cada traficante de aquí a Caracas tiene un sueño, un barco más rápido.
+
+[COK3_K:BARON3]
+Se rumorea que el astillero acaba de terminar un barco así
+
+[COK3_L:BARON3]
+para algún mamón costarricense.
+
+[COK3_M:BARON3]
+Y Tommy... ¡QUIERO ESE BARCO!
+
+[COK3_N:BARON3]
+Creo que han vuelto tus palomas.
+
+[COK3_O:BARON3]
+¡Ah! Pensé que te tenía. ¿De dónde has salido?
+
+[COK3_P:BARON3]
+¡Palomas! ¡Boom! ¡Aaaaah!
+
+[COK3_5:BARON3]
+~g~Localiza el interruptor para bajar el barco.
+
+[COK3_6:BARON3]
+~g~Lleva el barco a la mansión.
+
+[COK3_7:BARON3]
+~r~¡Destruiste el barco!
+
+[COK3_8:BARON3]
+~g~Ve al astillero, en los muelles y roba el barco más rápido.
+
+[COK3_9:BARON3]
+~g~Ahora sube al barco.
+
+{=================================== MISSION TABLE BARON4 ===================================}
+
+[COK4_A:BARON4]
+¡Expúlsala! ¡MIERDA DE PLÁSTICO!
+
+[COK4_B:BARON4]
+¿Por qué me haces esto?
+
+[COK4_C:BARON4]
+¿Quién te crees que eres, maldita mierda de plástico?
+
+[COK4_D:BARON4]
+¡QUE TE JODAN!
+
+[COK4_E:BARON4]
+Se traga mi película favorita de El burro, ¡se muere!
+
+[COK4_F:BARON4]
+¿Qué más podría haber hecho?
+
+[COK4_G:BARON4]
+Probablemente no estaba enchufado.
+
+[COK4_H:BARON4]
+¿Qué?
+
+[COK4_I:BARON4]
+Maldición... No importa, puedo comprar cien más.
+
+[COK4_J:BARON4]
+Ahora, Tommy,
+
+[COK4_K:BARON4]
+cada mes un camello autónomo navega hasta Vice City y amarra su yate.
+
+[COK4_L:BARON4]
+Vende su partida al primer barco.
+
+[COK4_M:BARON4]
+Quiero que cojas la lancha motora
+
+[COK4_N:BARON4]
+y que elimines a todos los otros cabrones,
+
+[COK4_O:BARON4]
+luego me traes aquí el alijo, ¿entendido?
+
+[COK4_P:BARON4]
+Déjame adivinar, pensaste que me podía venir bien un ángel guardián.
+
+[COK4_Q:BARON4]
+Solo digo que tienes que dejarme participar, tío.
+
+[COK4_R:BARON4]
+Ahora ya puedes contarme toda esa basura del 'chico duro solitario',
+
+[COK4_S:BARON4]
+pero sé que un día te voy a salvar el culo
+
+[COK4_T:BARON4]
+¡y probablemente querrás darme un beso!
+
+[COK4_U:BARON4]
+Colgado.
+
+[COK4_V:BARON4]
+~n~
+
+[COK4_1:BARON4]
+Así que Tommy, sabemos que fue Díaz quien jodió nuestro trato...
+
+[COK4_3:BARON4]
+Así que, ¿por qué coño vamos por ahí haciéndole recados?
+
+[COK4_4:BARON4]
+Cuanto más aprendamos ahora, ¡menos tendremos que aprender cuando tomemos el control de esta ciudad!
+
+[COK4_5:BARON4]
+Me encanta tu estilo, tío. Muy fresco.
+
+[COK4_12:BARON4]
+¡Cuidado, vienen de todas partes!
+
+[COK4_13:BARON4]
+Ya está. ¡Dirígete hacia Díaz tan rápido como puedas!
+
+[COK4_14:BARON4]
+¿Queréis un poco de esto?
+
+[COK4_15:BARON4]
+¡A dormir con los peces!
+
+[COK4_16:BARON4]
+¡Comed! ¡COMED!
+
+[COK4_19:BARON4]
+¡Más problemas ahí adelante!
+
+[COK4_20:BARON4]
+¡Hay más pistoleros en el malecón!
+
+[COK4_24:BARON4]
+Buen disparo, amigo mío. Eres un verdadero y auténtico lunático de categoría A.
+
+[COK4_25:BARON4]
+Bueno, gracias.
+
+[COK4_26:BARON4]
+Nos vemos, Tommy.
+
+[COK4_27:BARON4]
+Vale, Sr. Lance Vance.
+
+[COK4_28:BARON4]
+~g~¡Ve hasta el yate antes de que lleguen los otros barcos!
+
+[COK4_31:BARON4]
+~g~¡Ve al barco más rápido del embarcadero!
+
+[COK4_32:BARON4]
+~r~¡Demasiado lento!
+
+[COK4_33:BARON4]
+~r~¡Has destruido el barco!
+
+[COK4_34:BARON4]
+~g~¡Hunde esos barcos!
+
+[COK4_35:BARON4]
+Estado del barco:
+
+{=================================== MISSION TABLE BARON5 ===================================}
+
+[PROP_A:BARON5]
+¡PROPIEDAD ADQUIRIDA!
+
+[COK4_30:BARON5]
+~r~¡Lance está muerto!
+
+[ASS1_A:BARON5]
+He conseguido unos juguetes nuevos. Están en el maletero.
+
+[ASS1_B:BARON5]
+¡Mierda! ¿Dónde conseguiste todo este material?
+
+[ASS1_C:BARON5]
+Lo he estado guardando para un momento como éste.
+
+[ASS1_D:BARON5]
+¿Te gusta?
+
+[ASS1_E:BARON5]
+Sí, me gusta.
+
+[ASS1_F:BARON5]
+Estúpidos mamones...
+
+[ASS1_G:BARON5]
+Mi hermosa casa.
+
+[ASS1_H:BARON5]
+¡Mirad lo que le habéis hecho!
+
+[ASS1_I:BARON5]
+¡Esto es por mi hermano!
+
+[ASS1_J:BARON5]
+Confiaba en ti, Tommy.
+
+[ASS1_K:BARON5]
+Te hubiese convertido en...
+
+[ASS1_L:BARON5]
+Diga buenas noches, Sr. Díaz.
+
+[ASS1_1:BARON5]
+Este lugar va a estar hasta arriba de capullos... ten cuidado...
+
+[ASS1_2:BARON5]
+No te preocupes Tommy, te cubro.
+
+[ASS1_13:BARON5]
+¡DÍAZ! ¡He venido a encargarme de tu negocio!
+
+[ASS1_14:BARON5]
+¡TOMMY! Me has traicionado... ¡Imbécil! Voy a acabar contigo muy pronto...
+
+[ASS1_15:BARON5]
+~g~¡Arrasa esa mansión y mata a Diaz!
+
+[ASS1_16:BARON5]
+~g~¡Mata a Diaz!
+
+[ASS1_17:BARON5]
+~g~Hay múltiples caminos para entrar en la mansión.
+
+[BUD1:BARON5]
+Lance
+
+[ASS1_18:BARON5]
+~g~La puerta está cerrada con llave, intenta otra ruta.
+
+[ASS1_19:BARON5]
+¡Por aquí!
+
+[ASS1_20:BARON5]
+¡Tommy, mi problema es con Quentin, no contigo, tío!
+
+{=================================== MISSION TABLE BIKE1 ===================================}
+
+[BM1_A:BIKE1]
+¿Dónde está Baker?
+
+[BM1_B:BIKE1]
+Estoy buscando al gran Mitch Baker...
+
+[BM1_C:BIKE1]
+¿Quién le busca?
+
+[BM1_D:BIKE1]
+Tommy Vercetti.
+
+[BM1_E:BIKE1]
+Vercetti.
+
+[BM1_F:BIKE1]
+No pareces policía, así que eso te concede un minuto.
+
+[BM1_G:BIKE1]
+Habla rápido.
+
+[BM1_H:BIKE1]
+Kent Paul dijo que podrías estar interesado en llevar la seguridad de una gira que él ha organizado.
+
+[BM1_I:BIKE1]
+¿Kent Paul? No me extraña que te enviase en su lugar.
+
+[BM1_J:BIKE1]
+La última vez que estuvo aquí, se marchó por la ventana sin nada, tal cual le trajo su madre al mundo.
+
+[BM1_K:BIKE1]
+¿Estás interesado o no?
+
+[BM1_L:BIKE1]
+Sólo hacemos favores a los nuestros.
+
+[BM1_M:BIKE1]
+¿Cómo puedo unirme a vosotros?
+
+[BM1_N:BIKE1]
+Este no es un club de campo, chico. ¿Sabes montar en moto?
+
+[BM1_O:BIKE1]
+¿Sabes sentarte en un taburete y beber?
+
+[BM1_P:BIKE1]
+Cougar, Zeppelin, id a ver cómo se le da la moto a esta nenaza...
+
+[BM1_2:BIKE1]
+~g~¡Necesitas una Freeway o una Ángel para competir!
+
+[BM1_3:BIKE1]
+~r~¡Los corredores han sido atacados!
+
+[BIKE1_1:BIKE1]
+Bien, modelitos caros. Veamos qué puedes hacer.
+
+[BM1_1:BIKE1]
+~g~Consigue una Freeway o una Ángel y ve a la parrilla de salida.
+
+{=================================== MISSION TABLE BIKE2 ===================================}
+
+[BM2_1:BIKE2]
+CAOSMETRO:
+
+[BM2_A:BIKE2]
+Te he vuelto a ganar.
+
+[BM2_B:BIKE2]
+Eh, Vercetti.
+
+[BM2_C:BIKE2]
+Cougar dice que sabes manejar muy bien una moto.
+
+[BM2_D:BIKE2]
+Sí, ¿cuántos recados más voy a tener que hacer?
+
+[BM2_E:BIKE2]
+Soy un hombre muy ocupado.
+
+[BM2_F:BIKE2]
+Si es un combate lo que va arreglarlo todo, entonces adelante.
+
+[BM2_G:BIKE2]
+Ser uno de nosotros no va solo de fanfarronear. Va de ser parte de una familia.
+
+[BM2_H:BIKE2]
+Sí, he sido parte de una familia antes. No funcionó.
+
+[BM2_I:BIKE2]
+Sí, seguro, pero esta familia cuida de los suyos.
+
+[BM2_J:BIKE2]
+No le pedimos a un hombre que haga el trabajo sucio y luego le dejamos pasar quince años de sequía.
+
+[BM2_K:BIKE2]
+Sí, es verdad. He hecho mis deberes.
+
+[BM2_L:BIKE2]
+Ésta de aquí es la familia más grande de inadaptados, rebeldes y tipos duros.
+
+[BM2_M:BIKE2]
+Diablos, algunos de nosotros incluso hemos sido traicionados por nuestro propio país.
+
+[BM2_N:BIKE2]
+Estuve preso durante Vietnam. Un tema desagradable.
+
+[BM2_O:BIKE2]
+Por eso es por lo que voy a pedirte que vayas a armar jaleo.
+
+[BM2_P:BIKE2]
+Este maldito país necesita una patada en el culo, y nosotros se la vamos a dar.
+
+[BM2_Q:BIKE2]
+¡Así que sal de ahí, pilla una moto, demuestra a esta ciudad lo cabreado que estás!
+
+[BM2_R:BIKE2]
+De acuerdo.
+
+[BM2_2:BIKE2]
+~g~¡Debes llenar el Caosmetro en el tiempo determinado para demostrarnos lo duro que eres!
+
+[BM2_3:BIKE2]
+~g~Este sonido indica que has llenado una parte del contador, continúa así.
+
+[BM2_4:BIKE2]
+~r~¡Has fracasado en llenar el Caosmetro a tiempo!
+
+{=================================== MISSION TABLE BIKE3 ===================================}
+
+[BM3_A:BIKE3]
+Hola, Mitch.
+
+[BM3_B:BIKE3]
+Bueno, si es el ''tipo duro'' Vercetti.
+
+[BM3_C:BIKE3]
+Ahora quiero ver lo bien que sabes luchar por tu territorio.
+
+[BM3_D:BIKE3]
+Una banda callejera local cometió el error de robar mi moto,
+
+[BM3_E:BIKE3]
+probablemente para hacerse los machos o algo así.
+
+[BM3_F:BIKE3]
+Los chicos y yo iríamos a darles una lección sobre el respeto a las propiedades ajenas y todo eso.
+
+[BM3_G:BIKE3]
+En fin...
+
+[BM3_H:BIKE3]
+Entonces empecé a pensar que esto sería una buena iniciación para ti.
+
+[BM3_I:BIKE3]
+Devuélveme mi moto y puedes decirle a Paul que tiene su seguridad.
+
+[BM3_2:BIKE3]
+~r~¡Se suponía que debías traer de vuelta la moto, no destruirla!
+
+[BM3_3:BIKE3]
+~g~¡Lleva la moto de vuelta al bar!
+
+[BM3_4:BIKE3]
+~g~¡Sube a la moto!
+
+[INTRUDE:BIKE3]
+~g~¡Te han visto!
+
+[BM3_6:BIKE3]
+~g~Están refugiados detrás de Ammu-Nation en la zona del centro.
+
+[BM3_7:BIKE3]
+~g~Necesitarás una moto rápida para conseguir acceder al tejado.
+
+[BM3_8:BIKE3]
+~g~Utiliza la moto para saltar desde esas escaleras hasta el tejado que hay en el extremo opuesto de la carretera.
+
+[BM3_1:BIKE3]
+~g~Una banda local ha robado la Ángel de Mitch Baker. ¡Recupérala!
+
+[BM3_9:BIKE3]
+~g~¡Recupera la Ángel de Mitch y sal de ahí!
+
+{=================================== MISSION TABLE BMX_1 ===================================}
+
+[GETBIK2:BMX_1]
+¡Tienes ~1~ segundos para subirte a una moto de motocross!
+
+{=================================== MISSION TABLE BOATBUY ===================================}
+
+[DRUG_1:BOATBUY]
+¿Hola?
+
+[DRUG_2:BOATBUY]
+Apágalo. Hay un tipo ahí afuera.
+
+[DRUG_3:BOATBUY]
+¡Eh, el tipo del traje! Supongo que eres el nuevo propietario.
+
+[DRUG_4:BOATBUY]
+Sí. ¿Cuál de los barcos es el más rápido?
+
+[DRUG_5:BOATBUY]
+Ya está en el agua, tío,
+
+[DRUG_6:BOATBUY]
+Pensé que querrías probarlo.
+
+[DRUG_7:BOATBUY]
+Tío, funciona con un motor de 300 caballos...
+
+[DRUG_8:BOATBUY]
+y el casco es de fibra de vidrio, ¡sale disparado por las olas!
+
+[DRUG_9:BOATBUY]
+Puede ponerse de cero a noventa tan sólo en cuatro segundos, tío...
+
+[DRUG_10:BOATBUY]
+¡y puede llevar como veinte contenedores de la mejor hierba jamaicana justo en el casco!
+
+[DRUG_11:BOATBUY]
+Así que adelante, tío, ¡está preparada para volar!
+
+[DRUG_12:BOATBUY]
+Tipo trajeado, ¿tienes fuego?
+
+[DRUG_13:BOATBUY]
+¿Colega?
+
+{=================================== MISSION TABLE CAP_1 ===================================}
+
+[CAP1_B1:CAP_1]
+~g~La mafia está imponiendo impuestos a tus negocios. Encuéntrales y mátales.
+
+[CAP1_B2:CAP_1]
+~g~¡La mafia ha saqueado el astillero!
+
+[CAP1_B3:CAP_1]
+~g~¡La mafia ha saqueado la fábrica de helados!
+
+[CAP1_B4:CAP_1]
+~g~¡La mafia ha saqueado el salón de autos!
+
+[CAP1_B5:CAP_1]
+~g~¡La mafia ha saqueado la compañía de taxis!
+
+[CAP_01:CAP_1]
+¿Cuál es la emergencia?
+
+[CAP_02:CAP_1]
+¿QUIÉN?
+
+[CAP_03:CAP_1]
+Tommy... unos matones mafiosos... dijeron que vendrían a recoger su parte...
+
+[CAP_04:CAP_1]
+Dijeron que era dinero del Sr. Forello... me siento una basura.
+
+[CAP_05:CAP_1]
+¿Forelli? ¿SONNY Forelli?
+
+[CAP_06:CAP_1]
+Sí, ése es el tipo... creo... insistieron mucho...
+
+[CAP_07:CAP_1]
+No te preocupes, abuelo, no estoy enfadado contigo.
+
+[CAP_08:CAP_1]
+Llevadle al hospital.
+
+[CAP_09:CAP_1]
+Tommy... rájale un nuevo culo a ese tipo por mí...
+
+[CAP_10:CAP_1]
+Voy a rajarle en dos.
+
+[CAP1_2:CAP_1]
+¡Conoces las reglas, Vercetti!
+
+[CAP1_3:CAP_1]
+¡El Sr. Forelli envía sus saludos!
+
+[CAP1_4:CAP_1]
+¡Es el carnicero de Harwood!
+
+[CAP1_5:CAP_1]
+Decidle a Sonny... ¡Que permanezca alejado!
+
+[CAP1_6:CAP_1]
+Vice City ahora es MÍA, NO suya.
+
+[CAP1_7:CAP_1]
+¿Crees que puedes eliminarme, Vercetti?
+
+[CAP1_8:CAP_1]
+Seguiremos yendo tras de ti hasta que mueras, Vercetti.
+
+[CAP1_9:CAP_1]
+No tienes ni una oportunidad, mamón psicótico.
+
+[CAP1_10:CAP_1]
+Te mataré, Vercetti.
+
+[CAP1_11:CAP_1]
+Siempre fuiste un gilipollas.
+
+[CAP1_12:CAP_1]
+Vas a morir, Vercetti.
+
+[CAP1_B6:CAP_1]
+~g~Has encontrado al cobrador, remátale.
+
+[CAP1_B7:CAP_1]
+~g~Has perdido al cobrador.
+
+[CAP1_B8:CAP_1]
+~r~El cobrador ha saqueado todos tus negocios.
+
+[CAP1_B9:CAP_1]
+~g~¡La mafia ha saqueado a El Malibu!
+
+[CAP1_B0:CAP_1]
+~g~¡La mafia ha saqueado al estudio cinematográfico!
+
+[CAP1_C2:CAP_1]
+~g~¡La mafia ha llegado al astillero!
+
+[CAP1_C3:CAP_1]
+~g~¡La mafia ha llegado a la fábrica de helados!
+
+[CAP1_C4:CAP_1]
+~g~¡La mafia ha llegado al concesionario de coches!
+
+[CAP1_C5:CAP_1]
+~g~¡La mafia ha llegado a la compañía de taxis!
+
+[CAP1_C9:CAP_1]
+~g~¡La mafia ha llegado al Malibú!
+
+[CAP1_C0:CAP_1]
+~g~¡La mafia ha llegado al estudio cinematográfico!
+
+[CAP1_D2:CAP_1]
+~g~¡La mafia abandona el astillero!
+
+[CAP1_D3:CAP_1]
+~g~La mafia abandona la fábrica de helados!
+
+[CAP1_D4:CAP_1]
+~g~¡La mafia abandona el concesionario de coches!
+
+[CAP1_D5:CAP_1]
+~g~¡La mafia abandona la compañía de taxis!
+
+[CAP1_D9:CAP_1]
+~g~¡La mafia abandona el Malibú!
+
+[CAP1_D0:CAP_1]
+~g~¡La mafia abandona el estudio cinematográfico!
+
+[CAP1B10:CAP_1]
+Has puesto límite a los recaudadores. Vienen más de camino.
+
+{=================================== MISSION TABLE CARBUY ===================================}
+
+[CAR1_1:CARBUY]
+B.J. Smith. Y usted debe ser el Sr. Vercetti.
+
+[CAR1_2:CARBUY]
+¿Le gustaría dar una vuelta?
+
+[CAR1_3:CARBUY]
+Podría ser.
+
+[CAR1_4:CARBUY]
+Estoy muy triste por vender el negocio.
+
+[CAR1_5:CARBUY]
+Esta fue mi primera inversión después de convertirme en profesional.
+
+[CAR1_6:CARBUY]
+Pero es hora de que me mude.
+
+[CAR1_7:CARBUY]
+¿Deja la ciudad?
+
+[CAR1_8:CARBUY]
+No demasiado deprisa, espero.
+
+[CAR1_9:CARBUY]
+No. Me estoy retirando pero simplemente para preparar mi regreso.
+
+[CAR1_10:CARBUY]
+El negocio no era demasiado fuerte,
+
+[CAR1_11:CARBUY]
+y mi equipo quizás se puso demasiado
+
+[CAR1_12:CARBUY]
+creativo con la generación de la riqueza.
+
+[CAR1_13:CARBUY]
+Obviamente, habría podido desmantelar el negocio antes de cederlo.
+
+[CAR1_14:CARBUY]
+Diablos, podría haber quemado el sitio si hubiese querido.
+
+[CAR1_15:CARBUY]
+Esta es tierra para una urbanización de primera.
+
+[CAR1_16:CARBUY]
+Oh, yo no me preocuparía por nada de eso.
+
+[CAR1_17:CARBUY]
+Este lugar parece perfecto.
+
+[CAR1_18:CARBUY]
+Sí, así es, ¿así que entiendo que tenemos un trato?
+
+{=================================== MISSION TABLE CARPAR1 ===================================}
+
+[MM_1_A:CARPAR1]
+~g~Atraviesa ~y~5 puntos de control ~r~¡SIN ~g~aplastar ningún ~r~CONO! ~g~Puedes atravesarlos en ~y~CUALQUIER ORDEN.
+
+[CONE_1:CARPAR1]
+~r~¡Aplastaste un cono!
+
+[MM_1_C:CARPAR1]
+~y~PASA POR~g~ un punto de control para activar el temporizador. ~g~Cada punto de control te dará ~y~~1~ SEGUNDOS~g~.
+
+{=================================== MISSION TABLE COPCAR ===================================}
+
+[KILLS:COPCAR]
+MUERTES:
+
+[C_BREIF:COPCAR]
+~g~Sospechoso visto por última vez en la zona de ~a~.
+
+[C_PASS:COPCAR]
+AMENAZA ELIMINADA: ~1~ $
+
+[COPCART:COPCAR]
+~g~Tienes ~1~ segundos para volver al vehículo de policía antes de que termine la misión.
+
+[C_CANC:COPCAR]
+~r~¡Misión de justiciero cancelada!
+
+[C_TIME:COPCAR]
+~r~¡Tu tiempo como representante de la ley se ha terminado!
+
+[C_COMP1:COPCAR]
+Has completado el nivel 12 de la misión de justiciero: tu armadura personal máxima ha aumentado a 150.
+
+[CLEVEL:COPCAR]
+Misión de justiciero nivel ~1~
+
+{=================================== MISSION TABLE COUNT1 ===================================}
+
+[CM1_A:COUNT1]
+¿Sr. Vercetti? ¿Comprando la vieja imprenta?
+
+[CM1_B:COUNT1]
+Sí, mi viejo solía trabajar con ellas.
+
+[CM1_C:COUNT1]
+Iba a seguirle en el negocio, pero... viví una vida diferente.
+
+[CM1_D:COUNT1]
+¿Planea vender la vieja maquinaria o destruirla?
+
+[CM1_E:COUNT1]
+Estoy pensando que podíamos imprimir algo, un periódico, una revista...
+
+[CM1_F:COUNT1]
+Oh, mierda, hijo, todo eso es mierda de baja calidad. Siempre me ha apetecido imprimir dinero. No es tan difícil.
+
+[CM1_G:COUNT1]
+Ya sabes, llevo haciéndolo a pequeña escala durante años.
+
+[CM1_H:COUNT1]
+¿De verdad?
+
+[CM1_I:COUNT1]
+Claro. Pero necesitamos unas planchas de buena calidad.
+
+[CM1_J:COUNT1]
+¡Por supuesto! Hay un sindicato de la falsificación que opera ya en Florida.
+
+[CM1_K:COUNT1]
+¿Un sindicato?
+
+[CM1_L:COUNT1]
+Sí. He escuchado algunos rumores.
+
+[CM1_M:COUNT1]
+Conozco a un tipo que es bueno con los rumores...
+
+[CM1_N:COUNT1]
+Solía pasar las tardes con él, limpiando los rodillos...
+
+[CM1_2A:COUNT1]
+¡Menudo trasero!
+
+[CM1_2B:COUNT1]
+¡Vale chica, tú te lo pierdes!
+
+[CM1_2C:COUNT1]
+Buenas, figura, ¿cómo va todo?
+
+[CM1_2D:COUNT1]
+¿Qué sabes sobre falsificación?
+
+[CM1_2E:COUNT1]
+Estoy bien, Paul, ¿qué tal tú?
+
+[CM1_2F:COUNT1]
+¡Ven aquí!
+
+[CM1_2G:COUNT1]
+¡Vale! ¡Vale! Obviamente eres un hombre ocupado.
+
+[CM1_2H:COUNT1]
+Todo lo que sé sobre los asuntos turbios es que las tríadas suministran las planchas.
+
+[CM1_2I:COUNT1]
+Tienen una compañía de envíos en los muelles,
+
+[CM1_2J:COUNT1]
+¡el jefe sabrá cuándo vienen las próximas planchas!
+
+[CM1_2K:COUNT1]
+Gracias, Paul.
+
+[CM1_2L:COUNT1]
+¡Cuál es tu problema, lunático!
+
+[CM1_2M:COUNT1]
+¡Ponme otra copa, pronto!
+
+[CM1_3:COUNT1]
+~g~¡Te han visto!
+
+[CM1_5:COUNT1]
+~g~¡Ve a encontrarte con Kent Paul en el Club Malibú!
+
+[CNT1_1:COUNT1]
+¿Quién eres tú? ¡En la cara no! ¡En la cara no!
+
+[CM1_1:COUNT1]
+~g~Ve al barco de la línea charter Libertine en el muelle.
+
+[CM1_2:COUNT1]
+~g~El encargado de los envíos tendrá toda la información necesaria.
+
+[CNT1_2:COUNT1]
+Vale, ¡hablaré! ¡hablaré!
+
+[CM1_6:COUNT1]
+~g~¡Lleva toda la información de vuelta a la imprenta!
+
+{=================================== MISSION TABLE COUNT2 ===================================}
+
+[CNT2_B1:COUNT2]
+De acuerdo, hoy el mensajero moverá las planchas de los muelles.
+
+[CNT2_B2:COUNT2]
+Voy a interceptarles, coger las planchas, deshacerme de las pruebas, y volver aquí.
+
+[CNT2_B3:COUNT2]
+Dependiendo de lo bien que vaya esto,
+
+[CNT2_B4:COUNT2]
+podemos tener cinco minutos para imprimir el dinero antes de que el sindicato de falsificación nos encuentre, o puede que tengamos todo el año.
+
+[CNT2_B5:COUNT2]
+De cualquier modo, quiero que los verdes salgan de las prensas cinco minutos después de que vuelva. ¿Entendido?
+
+[CNT2_B6:COUNT2]
+No te preocupes, Tommy. Estaremos preparados.
+
+[CNT2_B7:COUNT2]
+Los otros chicos y yo estaremos por aquí en el vecindario, en caso de que necesites que nos ocupemos de cualquier problema.
+
+[CNT2_B8:COUNT2]
+De acuerdo, ¿todo el mundo está tranquilo? De acuerdo. Os veré luego...
+
+[CNT2_01:COUNT2]
+~g~El ~r~mensajero~g~ con las planchas de falsificación llegará en cualquier momento a los ~y~muelles~g~ en un helicóptero.
+
+[CNT2_02:COUNT2]
+~r~El mensajero de las planchas ha huido en el helicóptero.
+
+[CNT2_03:COUNT2]
+~r~¡El mensajero ha llegado a su destino sano y salvo, llegas demasiado tarde!
+
+[CNT2_04:COUNT2]
+~r~¡Has destruido las planchas en la explosión!
+
+[CNT2_05:COUNT2]
+~g~Tienes las planchas de falsificación. Llévalas a la imprenta.
+
+[CNT2_06:COUNT2]
+~g~El mensajero ha muerto y ha dejado caer las planchas, recógelas antes de que lo haga otro.
+
+[CNT2_07:COUNT2]
+~g~Una de las guardias ha recogido las planchas, no la dejes escapar.
+
+[CNT2_08:COUNT2]
+~g~El ~r~mensajero~g~ ha llegado a los muelles con las planchas.
+
+[CNT2_4:COUNT2]
+Negocio privado. ¡No eres bienvenido!
+
+[CNT2_09:COUNT2]
+IMPRENTA CONSOLIDADA
+
+[CNT2_10:COUNT2]
+~g~La imprenta generará ahora unos ingresos hasta un máximo de ~1~ $. Asegúrate que lo recaudas de manera regular.
+
+[CNT2_11:COUNT2]
+~r~¡Las planchas están en el fondo del mar!
+
+{=================================== MISSION TABLE CUBAN1 ===================================}
+
+[CUB1_A:CUBAN1]
+¿Sí, tío?
+
+[CUB1_B:CUBAN1]
+Eh, tranquilo papito, este hombre es para mí. Tú, ¿tú eres el chico?
+
+[CUB1_C:CUBAN1]
+Oh, sí. Tú eres el chico. Eso creo, ¿sabes?
+
+[CUB1_D:CUBAN1]
+No. No creo que lo sepa.
+
+[CUB1_E:CUBAN1]
+¿Oh, sí? Ven aquí, tipo duro.
+
+[CUB1_F:CUBAN1]
+¿Crees que puedes desafiarme?
+
+[CUB1_G:CUBAN1]
+¿Crees que puedes jugar a ese estúpido juego conmigo?
+
+[CUB1_H:CUBAN1]
+No, creo que ya lo estás haciendo tú lo suficientemente estúpido por los dos.
+
+[CUB1_I:CUBAN1]
+Eh, te llamó tonto, hijo.
+
+[CUB1_J:CUBAN1]
+Y yo le llamé niñita, papá.
+
+[CUB1_K:CUBAN1]
+Mírale, vestido así.
+
+[CUB1_L:CUBAN1]
+¿Qué es esto, un traje de noche?
+
+[CUB1_M:CUBAN1]
+¿Eres alguna clase de tipo duro y vistes como una mujer?
+
+[CUB1_N:CUBAN1]
+También llevas pantis como una mujer, ¿eh?
+
+[CUB1_O:CUBAN1]
+¿Qué tienes contra las mujeres? ¿Prefieres a los hombres, grandullón?
+
+[CUB1_P:CUBAN1]
+¡Me gustan las mujeres! ¡Me gustan las mujeres! ¡Amo a mi madre, chico!
+
+[CUB1_Q:CUBAN1]
+De acuerdo, de acuerdo. Aceptaré tu palabra.
+
+[CUB1_R:CUBAN1]
+¿Sabes conducir, amigo?
+
+[CUB1_S:CUBAN1]
+Sí... como una mujer.
+
+[CUB1_T:CUBAN1]
+Muy gracioso. Me gustas, grandullón. Quizás puedas ayudarme.
+
+[CUB1_U:CUBAN1]
+Quizás puedas demostrar que eres un hombre. ¿Eh?
+
+[CUB1_V:CUBAN1]
+Saca el barco.
+
+[CUB1_W:CUBAN1]
+Demuéstrame que tienes un par de cojones,
+
+[CUB1_X:CUBAN1]
+y no unos chiquitos de ratón.
+
+[CUB1_02:CUBAN1]
+De acuerdo, tío, trátalo como a una mujer.
+
+[CUB1_03:CUBAN1]
+No está mal, un hombre de verdad.
+
+[CUB1_04:CUBAN1]
+Tío, tienes unas pelotas bien grandes, amigo.
+
+[CUB1_05:CUBAN1]
+Amigo, eres un tío.
+
+[CUB1_06:CUBAN1]
+¿Puedes decir que eres un machote, tío?
+
+[CUB1_07:CUBAN1]
+Eres un ratón asustado, niñito, vete a llorar con tu mamá.
+
+[CUB1_08:CUBAN1]
+Eres una bazofia. Andas como un tío, hablas con un tío, pero conduces como un idiota.
+
+[CUB1_09:CUBAN1]
+Brother, eres un macho. Me gustas, tío. Me gustas un montón.
+
+[CUB1_10:CUBAN1]
+En cualquier momento, tío. Porque tienes un par. Y todos mis amigos tienen un buen par de cojones.
+
+[CUB1_11:CUBAN1]
+~r~¡Mataste a Rico!
+
+[CUB1_12:CUBAN1]
+Atraviesa el primer punto de control para comenzar la prueba.
+
+[CUB1_14:CUBAN1]
+¡Vuelve al bote!
+
+[CUB1_15:CUBAN1]
+~r~Brother, eres demasiado lento.
+
+[CUB1_01:CUBAN1]
+Eh, soy Rico. ¿Eres tú el tío de las pelotas grandes?
+
+[CUB1_13:CUBAN1]
+~g~Tienes tres minutos para recorrer el circuito.
+
+{=================================== MISSION TABLE CUBAN2 ===================================}
+
+[CUB2_A:CUBAN2]
+Un cafetito, por favor, Alberto...
+
+[CUB2_N:CUBAN2]
+Sin problema, Tommy.
+
+[CUB2_B:CUBAN2]
+¡Papá! ¡Un gran problema!
+
+[CUB2_O:CUBAN2]
+Umberto, mi hijo, ¿qué ocurre?
+
+[CUB2_C:CUBAN2]
+¡Los haitianos! ¡Odio a estos haitianos!
+
+[CUB2_D:CUBAN2]
+¡Me han molestado por última vez!
+
+[CUB2_E:CUBAN2]
+¡Nos desharemos de ellos!
+
+[CUB2_F:CUBAN2]
+Sólo necesitamos un poco de apoyo.
+
+[CUB2_G:CUBAN2]
+Ya he perdido algunos hermanos ahí fuera.
+
+[CUB2_H:CUBAN2]
+¡Amigo, tú conduces bien!
+
+[CUB2_I:CUBAN2]
+Para ser una mujer. ¿No?
+
+[CUB2_J:CUBAN2]
+¡Éste no es momento de bromear!
+
+[CUB2_K:CUBAN2]
+¡Vamos, maneja de nuevo para mí!
+
+[CUB2_L:CUBAN2]
+¡Lleva a mis chicos allí y eliminaremos a esos haitianos!
+
+[CUB2_M:CUBAN2]
+¡Se meten conmigo y se meten con el chico grande de la ciudad!
+
+[CUB2_01:CUBAN2]
+No hay suficiente espacio, brother, necesitas un coche más grande.
+
+[CUB2_02:CUBAN2]
+¡Necesitamos refuerzos del café!
+
+[CUB2_03:CUBAN2]
+~g~Consigue un coche y recoge a los cubanos frente al Café Robina.
+
+[CUB2_04:CUBAN2]
+~g~Ve y deja a los cubanos en la zona de combate.
+
+[CUB2_05:CUBAN2]
+¡Elimina a ese francotirador cobarde!
+
+[CUB2_07:CUBAN2]
+¡Luchan como nenas! ¡Ponte a cubierto!
+
+[CUB2_09:CUBAN2]
+¡Francotirador en el tejado!
+
+[CUB2_11:CUBAN2]
+~r~Estúpido, necesitábamos ese coche.
+
+[CUB2_12:CUBAN2]
+¡Eh, amigo! ¡Me alegro de que hayas podido venir!
+
+[CUB2_13:CUBAN2]
+¡Apestoso nido de haitianos, vamos a matarlos a todos!
+
+[CUB2_14:CUBAN2]
+¡A LA CARGA!
+
+[CUB2_15:CUBAN2]
+¡Ahora, hermanos, A LA CAAARGA!
+
+[CUB2_16:CUBAN2]
+¡Tommy, hemos demostrado nuestro valor y nuestra hombría!
+
+[CUB2_17:CUBAN2]
+¡Vamos a robar esa furgoneta llena de farlopa y pegarnos el piro!
+
+[CUB2_18:CUBAN2]
+~g~Consigue un coche y recoge a los cubanos.
+
+[CUB2_19:CUBAN2]
+¡Vamos a combatir como machos!
+
+[CUB2_21:CUBAN2]
+¡Luchad como machos con un par de cojones!
+
+[CUB2_22:CUBAN2]
+~g~Termina con el resto de los haitianos para que los cubanos puedan avanzar.
+
+[CUB2_23:CUBAN2]
+~g~Little Haiti estará atestado de haitianos intentando desquitarse con los cubanos. ¡Ten cuidado!
+
+[CUB2_24:CUBAN2]
+~g~Vuelve al Café Robina en la furgoneta y aparca en la parte trasera.
+
+[CUB2_25:CUBAN2]
+¡MATA A TODOS LOS HAITIANOS!
+
+{=================================== MISSION TABLE CUBAN3 ===================================}
+
+[CUB3_A:CUBAN3]
+Alberto. Un cafetito, señor.
+
+[CUB3_B:CUBAN3]
+Papaíto, no sirvas a esta sabandija.
+
+[CUB3_C:CUBAN3]
+¡Tienes dos caras, Tommy!
+
+[CUB3_D:CUBAN3]
+¡Tú, guapito de cara, o eres un falso o eres un calzonazos!
+
+[CUB3_E:CUBAN3]
+¡Los haitianos! Tío, se están riendo de mí.
+
+[CUB3_F:CUBAN3]
+Vale, vale. ¿Qué problema tienes?
+
+[CUB3_G:CUBAN3]
+Se están riendo de mí, Tommy. ¡De mí!
+
+[CUB3_H:CUBAN3]
+¡Umberto Robina! ¡Están haciendo lo que quieren!
+
+[CUB3_I:CUBAN3]
+Nadie hace lo que quiere, Umberto, hacen lo que les dejes hacer.
+
+[CUB3_J:CUBAN3]
+¿Qué?
+
+[CUB3_K:CUBAN3]
+¿Quieres que alguien se ocupe del asunto?
+
+[CUB3_L:CUBAN3]
+Puedo manejarlo, pero va a costarte.
+
+[CUB3_M:CUBAN3]
+Sé que somos hermanos y todo eso, pero esto es un negocio.
+
+[CUB3_N:CUBAN3]
+Tommy. Eres un verdadero macho. Un tío de negocios, un caballero.
+
+[CUB3_O:CUBAN3]
+Estos haitianos. Tienen un alijo de producto que va a venir desde alta mar, un material de primera.
+
+[CUB3_P:CUBAN3]
+Lo agarraremos y acabaremos con ellos.
+
+[CUB3_Q:CUBAN3]
+Tú lo agarrarás y yo cuidaré de ti. Como a un hermano. Como a un hijo.
+
+[CUB3_R:CUBAN3]
+Creo que prefiero el dinero a que me mezas en tus rodillas, amigo.
+
+[CUB3_01:CUBAN3]
+Eh, Rico. Bonito barco, ¿estás preparado?
+
+[CUB3_03:CUBAN3]
+~g~Recoge todos los maletines llenos de nieve y dinero.
+
+[CUB3_04:CUBAN3]
+~g~Lleva la nieve y la pasta de vuelta a Umberto.
+
+[CUB3_05:CUBAN3]
+Sí, Tommy. Tienes que apuntar bien.
+
+[CUB3_06:CUBAN3]
+Mi barco, no me sirve lleno de agujeros, ¿eh?
+
+[CUB3_07:CUBAN3]
+~g~Ve y reúnete con Rico. Te llevará al punto de encuentro.
+
+
+[CUB3_02:CUBAN3]
+~g~¡MATA A TODOS LOS HAITIANOS DEL BARCO!
+[CUB3_08:CUBAN3]
+Oh, oh... Una banda de cubanos. ¡Nos atacan!
+
+{=================================== MISSION TABLE CUBAN4 ===================================}
+
+[CUB4_A:CUBAN4]
+Ey, señoritas. ¿Sabéis qué voy a hacer?
+
+[CUB4_B:CUBAN4]
+Primero voy a matar un haitiano. ¿Y después?
+
+[CUB4_C:CUBAN4]
+Voy a hacer el amor como un hombre.
+
+[CUB4_D:CUBAN4]
+¿Sabes chica? Algo así.
+
+[CUB4_E:CUBAN4]
+¡Perdedor!
+
+[CUB4_F:CUBAN4]
+Mamón.
+
+[CUB4_G:CUBAN4]
+¡Ey, nena, no te tocaría ni con una pértiga de tres metros!
+
+[CUB4_H:CUBAN4]
+¡A Umberto Robina le gustan las damas! ¡No una cabra con faldas!
+
+[CUB4_I:CUBAN4]
+¡Tommy! ¡Tommy, te quiero, te quiero! ¡Vámonos!
+
+[CUB4_J:CUBAN4]
+¿Irnos a donde? ¿No me puedo tomar primero una taza de café?
+
+[CUB4_K:CUBAN4]
+¡No hay tiempo para café! Además, acabo de tomarme uno.
+
+[CUB4_L:CUBAN4]
+Vamos a eliminar a los haitianos.
+
+[CUB4_M:CUBAN4]
+Tommy, ¿qué tiene un elefante dentro de la trompa?
+
+[CUB4_N:CUBAN4]
+¡Dos metros de mocos! ¡Ja, ja, ja!
+
+[CUB4_O:CUBAN4]
+Lo que tú digas, Umberto.
+
+[CUB4_P:CUBAN4]
+Tommy, ve y consíguenos un cochecito haitiano.
+
+[CUB4_Q:CUBAN4]
+Cuando lo tengas, regresa y recoge a mi chico
+
+[CUB4_R:CUBAN4]
+Pepe, y llévale a donde los haitianos.
+
+[CUB4_S:CUBAN4]
+Luego te vas hasta la planta de procesamiento de los haitianos y utilizas su disolvente como explosivo.
+
+[CUB4_T:CUBAN4]
+¡Boom! Y ¡Bye bye!
+
+[CUB4_U:CUBAN4]
+Umberto, ¿qué hay de ti?
+
+[CUB4_V:CUBAN4]
+Oh, voy a quedarme atrás, a vigilar el café con papá.
+
+[CUB4_W:CUBAN4]
+No se siente muy bien, ¿sabes?
+
+[CUB4_02:CUBAN4]
+~g~Las bombas se colocarán con un temporizador de 45 segundos.
+
+[CUB4_04:CUBAN4]
+~r~¡Alertaste a la base, ahora no habrá modo de entrar!
+
+[CUB4_07:CUBAN4]
+El disolvente está a la vuelta, amigo.
+
+[CUB4_08:CUBAN4]
+Hola, amigos.
+
+[CUB4_09:CUBAN4]
+Bueno. Haitianos putas. Muerte.
+
+[CUB4_10:CUBAN4]
+Vamos.
+
+[CUB4_11:CUBAN4]
+Sí, vamos.
+
+[CUB4_12:CUBAN4]
+¡Ey, necesitamos un coche de la banda haitiana!
+
+[CUB4_13:CUBAN4]
+¡Oye, vamos a encontrar a nuestros muchachos!
+
+[CUB4_14:CUBAN4]
+Sigue a mis compadres.
+
+[CUB4_15:CUBAN4]
+De acuerdo, allá vas...
+
+[CUB4_16:CUBAN4]
+¡Voy a colocar la bomba, cubridme!
+
+[CUB4_17:CUBAN4]
+¡CORRED!
+
+[CUB4_18:CUBAN4]
+Tío, esta es una parte bonita de la ciudad...
+
+[CUB4_19:CUBAN4]
+Compadre, este lugar es un vertedero.
+
+[CUB4_20:CUBAN4]
+Yo tenía una hermosa mujer... vivía por este barrio.
+
+[CUB4_21:CUBAN4]
+Sabes, allí hacen unas buenas pizzas.
+
+[CUB4_22:CUBAN4]
+¡Tío! ¡Conduces como un loco!
+
+[CUB4_23:CUBAN4]
+¿Te has perdido tío?
+
+[CUB4_24:CUBAN4]
+Dejaste atrás a Pepe, ve a por él.
+
+[CUB4_03:CUBAN4]
+~g~Permanece en el coche hasta que puedas aparcar sin percances dentro del recinto.
+
+[CUB4_26:CUBAN4]
+~g~Recoge a Pepe, dirígete al norte a Little Haiti y roba un coche Voodoo.
+
+[CUB4_27:CUBAN4]
+~g~Ve y reúnete con Rico y los otros cubanos.
+
+[CUB4_28:CUBAN4]
+~g~Reúnete con los otros cubanos en el laboratorio de sustancias químicas haitiano.
+
+[CUB4_29:CUBAN4]
+~g~Camina hacia cada uno de los marcadores para colocar la bomba en ese lugar.
+
+[CUB4_30:CUBAN4]
+~g~Después de colocar las tres bombas, aléjate de la fábrica antes que salte por los aires.
+
+[CUB4_31:CUBAN4]
+~g~¡Aléjate de la fábrica!
+
+[CUB4_32:CUBAN4]
+~g~Aparca el coche en el marcador y bájate de él.
+
+[CUB4_06:CUBAN4]
+~r~No te alejaste lo suficiente de la base, ¡y hemos tenido que abortar la explosión!
+
+{=================================== MISSION TABLE FINALE ===================================}
+
+[FIN1_01:FINALE]
+¿Qué está pasando?
+
+[FIN1_02:FINALE]
+¡Tommy! Oh, bien, bien. Escucha, escucha. Uh, escucha,
+
+[FIN1_03:FINALE]
+me gusta el pescado. Me encanta el pescado.
+
+[FIN1_04:FINALE]
+Me encantan como mascotas en peceras, o como comida en un plato,
+
+[FIN1_05:FINALE]
+pero aunque los adoro, no quiero dormir con ellos.
+
+[FIN1_06:FINALE]
+De acuerdo, pero ahora mismo, tus hermanos italianos van a salir de ahí para ponerme esos zapatos de cemento y yo...
+
+[FIN1_07:FINALE]
+Cállate, Ken. Siéntate.
+
+[FIN1_08:FINALE]
+Lance, ¿qué demonios ocurre?
+
+[FIN1_09:FINALE]
+Es tu amigo del norte, Tommy. No está muy contento de que matases a su hombre.
+
+[FIN1_10:FINALE]
+Vienen hoy para ver el negocio.
+
+[FIN1_11:FINALE]
+Tardaron más de lo que pensaba...
+
+[FIN1_12:FINALE]
+Chicos, tenemos que acabar con esto y no dejar duda de que ésta es mi operación. ¡Mía!
+
+[FIN1_13:FINALE]
+Ken, pon tres millones de la primera tanda de dinero falsificado en maletines.
+
+[FIN1_14:FINALE]
+Lance, reúne a los muchachos...
+
+[FIN2_01:FINALE]
+¡Tommy!
+
+[FIN2_02:FINALE]
+¿Qué? ¿No hay un gran abrazo para tu viejo colega?
+
+[FIN2_03:FINALE]
+He pasado quince años fuera del negocio,
+
+[FIN2_04:FINALE]
+estoy un poco oxidado respecto a las costumbres de la familia.
+
+[FIN2_05:FINALE]
+Siempre enfadado, ¿eh? Tommy.
+
+[FIN2_06:FINALE]
+No te dije que tu temperamento te metería en problemas, ¿eh?
+
+[FIN2_07:FINALE]
+Hay tres millones en los maletines...
+
+[FIN2_08:FINALE]
+¿Cuántos fueron? ¿Diez? No, once hombres.
+
+[FIN2_09:FINALE]
+¡Así es como llegaron a llamarte el Carnicero de Harwood! ¡Je je je!
+
+[FIN2_10:FINALE]
+Me enviaste a matar a un hombre, UN HOMBRE. Sabían que iba para allá.
+
+[FIN2_11:FINALE]
+Vigila tu tono.
+
+[FIN2_12:FINALE]
+Cualquiera pensaría que me echas la culpa por ese desafortunado conjunto de circunstancias.
+
+[FIN2_13:FINALE]
+Simplemente coge el dinero...
+
+[FIN2_14:FINALE]
+¿Que coja el maldito dinero?
+
+[FIN2_15:FINALE]
+¿Sabes, Tommy? Hice lo que pude por ti, tiré de algunos hilos, pedí favores.
+
+[FIN2_16:FINALE]
+Yo era tu amigo, Tommy. Esperaba que entraras en razón, ver qué es bueno para el negocio.
+
+[FIN2_17:FINALE]
+Confié en ti, Tommy, y me decepcionaste.
+
+[FIN2_18:FINALE]
+Pero al menos alguno de tu organización de mierda sabe hacer negocios,
+
+[FIN2_19:FINALE]
+¿No es verdad, Lance?
+
+[FIN2_20:FINALE]
+Lo siento, Tommy. Esto es Vice City. Son negocios.
+
+[FIN2_21:FINALE]
+Nos vendiste.
+
+[FIN2_22:FINALE]
+No. Te vendí a TI, Tommy, te vendí a TI.
+
+[FIN2_23:FINALE]
+El dinero de verdad está arriba, en la caja fuerte.
+
+[FIN2_24:FINALE]
+Así que Tommy, ¿cuál es el gran plan?
+
+[FIN2_25:FINALE]
+¿Creías que solo me llevaría el dinero falso?
+
+[FIN2_26:FINALE]
+¿Salvar el culo y huir con el rabo entre las piernas?
+
+[FIN2_27:FINALE]
+No.
+
+[FIN2_28:FINALE]
+Solo quería joderte antes de matarte.
+
+[FIN3_01:FINALE]
+¿Tommy?
+
+[FIN3_02:FINALE]
+Oh, Dios mío, ¡Tommy! ¿Qué ha sucedido?
+
+[FIN3_03:FINALE]
+¿A ti qué te parece?
+
+[FIN3_04:FINALE]
+¡Parece que te han arruinado el traje!
+
+[FIN3_05:FINALE]
+¡Y Tommy, era un traje muy bonito! Tommy, ¿qué diablos ha ocurrido?
+
+[FIN3_06:FINALE]
+Tuve un desacuerdo con un socio del negocio, ya sabes cómo son estas cosas.
+
+[FIN3_07:FINALE]
+Tommy, cuando tengo un desacuerdo con un socio, le envío una carta muy enfadado.
+
+[FIN3_08:FINALE]
+Quizás me mee en su buzón. No empiezo la tercera guerra mundial.
+
+[FIN3_09:FINALE]
+¿Sabes? Quizás deberías hablar con mi psiquiatra...
+
+[FIN3_10:FINALE]
+Ése estúpido mamón, Lance...
+
+[FIN3_11:FINALE]
+Tommy. A mí nunca me gustó ese tipo, ¿de acuerdo?
+
+[FIN3_12:FINALE]
+Era neurótico, era inseguro, era egocéntrico... ¡ese tipo era un gilipollas!
+
+[FIN3_13:FINALE]
+¡Me alegro de que lo eliminases!
+
+[FIN3_14:FINALE]
+No creo que vayamos a tener más líos desde la parte norte...
+
+[FIN3_15:FINALE]
+porque ya no hay 'parte norte'.
+
+[FIN3_16:FINALE]
+Ahora es todo sur.
+
+[FIN3_17:FINALE]
+Espera, eso quiere decir lo que creo que quiere decir, Tommy, ¿nene?
+
+[FIN3_18:FINALE]
+¿Qué crees que significa?
+
+[FIN3_19:FINALE]
+Que estamos al mando... Quiero decir, que tú estás al mando. Oh, Tommy...
+
+[FIN3_20:FINALE]
+¿Sabes, Ken? Este podría ser el comienzo de una hermosa relación comercial...
+
+[FIN3_21:FINALE]
+Después de todo, eres un cómplice, traicionero, ladrón de tres al cuarto
+
+[FIN3_22:FINALE]
+y yo soy un asesino psicópata convicto y además paso farlopa.
+
+[FIN3_23:FINALE]
+Lo sé. ¿No es sencillamente hermoso?
+
+[FIN_B1:FINALE]
+~g~Ve y liquida al traidor de ~y~Lance Vance~g~.
+
+[FIN_B2:FINALE]
+~g~Liquida a ~p~Sonny~g~ y acaba con esto de una vez por todas.
+
+[FIN_B3:FINALE]
+~g~La mafia está intentando robarte el dinero. Protege la caja fuerte.
+
+[FIN_B4:FINALE]
+~g~Estás casi muerto, consigue ~w~salud~g~ en el piso de abajo.
+
+[FIN_B5:FINALE]
+~g~La mafia está robándote el dinero, protege la ~c~caja fuerte~g~.
+
+[FIN_B7:FINALE]
+~r~La mafia te ha robado todo el dinero.
+
+[DEFSAFE:FINALE]
+~g~Regresa a la caja fuerte y protégela.
+
+{=================================== MISSION TABLE FIRETRK ===================================}
+
+[F_PASS1:FIRETRK]
+¡Fuego extinguido!
+
+[F_FAIL2:FIRETRK]
+~r~¡Llegas demasiado tarde!
+
+[F_CANC:FIRETRK]
+~r~¡Misión de bombero cancelada!
+
+[F_EXTIN:FIRETRK]
+FUEGOS:
+
+[F_START:FIRETRK]
+~g~Se ha informado de un vehículo ardiendo en la zona de ~a~. Ve y extingue el fuego.
+
+[SIREN_1:FIRETRK]
+Para activar la sirena de este vehículo, pulsa ~h~~k~~VEHICLE_HORN~~w~.
+
+[SIREN_2:FIRETRK]
+Para activar la sirena de este vehículo, pulsa ~h~~k~~VEHICLE_HORN~~w~.
+
+[FIREPRO:FIRETRK]
+Nivel 12 de la misión del camión de bomberos completado. ¡Ahora eres completamente ignífugo!
+
+[F_FAIL1:FIRETRK]
+Misión de bombero terminada.
+
+[F_STAR1:FIRETRK]
+~g~Se ha informado de que hay vehículos ardiendo en la ~a~ zona. Ve y apaga el fuego.
+
+[SPRAY_4:FIRETRK] { reVC update }
+Pulsa ~h~~k~~VEHICLE_FIREWEAPON~ ~w~para disparar el cañón de agua y ~h~~k~~VEHICLE_TURRETLEFT~~w~ o ~h~~k~~VEHICLE_TURRETRIGHT~~w~ para apuntar con él.
+
+[SPRAY_1:FIRETRK] { reVC update }
+Pulsa ~h~~k~~VEHICLE_FIREWEAPON~ ~w~para disparar el cañón de agua y ~h~~k~~VEHICLE_TURRETLEFT~~w~ o ~h~~k~~VEHICLE_TURRETRIGHT~~w~ para apuntar con él.
+
+{=================================== MISSION TABLE GENERA1 ===================================}
+
+[GEN1_A:GENERA1]
+¡Sr. Vercetti!
+
+[GEN1_B:GENERA1]
+Coronel.
+
+[GEN1_D:GENERA1]
+No, gracias.
+
+[GEN1_E:GENERA1]
+Me avergüenza admitir que una de las causas de nuestro mutuo problema parece ser la lengua larga de un hombre en el que solía confiar.
+
+[GEN1_F:GENERA1]
+He tenido conmigo a González durante años, pero ahora su incompetencia alcanza nuevas cotas.
+
+[GEN1_G:GENERA1]
+Lo correcto es que mates a González...
+
+[GEN1_H:GENERA1]
+¿Lo hizo él? El dinero es lo único importante para mí.
+
+[GEN1_I:GENERA1]
+Por tu gentileza te compensaré y después buscaremos juntos tu dinero.
+
+[GEN1_J:GENERA1]
+Estará en su ático, probablemente medio borracho. Utiliza esto...
+
+[GEN1_K:GENERA1]
+Utiliza esto...
+
+[GEN1_06:GENERA1]
+¡Eh! ¡Tiene una sierra!
+
+[GEN1_07:GENERA1]
+¡Mantente alejado de mí, cabrón miserable!
+
+[GEN1_08:GENERA1]
+¡Maldición, he desperdiciado mi vida y mi belleza!
+
+[GEN1_10:GENERA1]
+¡Te voy a cerrar esa bocaza tuya!
+
+[GEN1_11:GENERA1]
+¡Deja de correr gorda bola de sebo!
+
+[GEN1_12:GENERA1]
+¡Estate quieto y haré que sea rápido!
+
+[GEN1_13:GENERA1]
+Deja de chillar, a nadie le importa, ¡gordo!
+
+[GEN1_C:GENERA1]
+Gracias por venir. Por favor siéntese. ¿Langosta?
+
+[GEN1_05:GENERA1]
+~g~¡Ve y liquida a González!
+
+[GEN1_09:GENERA1]
+Te pagaré el doble, Tommy, ¡EL DOBLE!
+
+[GEN1_18:GENERA1]
+~r~¡González ha conseguido llegar a la Jefatura de Policía!
+
+[GEN1_19:GENERA1]
+~g~¡La policía de Vice City viene a por ti!
+
+[GEN1_20:GENERA1]
+~g~Sube a un vehículo.
+
+[GEN1_21:GENERA1]
+~g~Ve al~h~ taller de pintura~g~ de~h~ Vice Point~g~.
+
+[GEN1_22:GENERA1]
+~g~Conduce tu vehículo hasta el interior del ~h~taller de pintura~w~ para perder tu ~h~nivel de se busca~w~, reparar y volver a pintar tu vehículo. El precio es ~h~100 $~g~. Esta vez es gratis.
+
+[GEN1_01:GENERA1]
+Cuando estés corriendo, mantén pulsado ~h~~k~~PED_FIREWEAPON~~w~ para preparar un ataque cuerpo a cuerpo.
+
+[GEN1_02:GENERA1]
+Cuando estés corriendo, mantén pulsado ~h~~k~~PED_FIREWEAPON~~w~ para preparar un ataque cuerpo a cuerpo.
+
+[GEN1_03:GENERA1]
+Cuando estés corriendo, mantén pulsado ~h~~k~~PED_FIREWEAPON~~w~ para preparar un ataque cuerpo a cuerpo.
+
+[GEN1_14:GENERA1]
+Suelta ~h~~k~~PED_FIREWEAPON~~w~ para atacar.
+
+[GEN1_15:GENERA1]
+Suelta ~h~~k~~PED_FIREWEAPON~~w~ para atacar.
+
+[GEN1_16:GENERA1]
+Suelta ~h~~k~~PED_FIREWEAPON~~w~ para atacar.
+
+[GEN1_23:GENERA1]
+~g~Vuelve pasando por las puertas para regresar a la planta baja.
+
+{=================================== MISSION TABLE GENERA2 ===================================}
+
+[COL2_A:GENERA2]
+¡Tommy! Ven, acércate.
+
+[COL2_B:GENERA2]
+Qué buena pinta, ¿eh? ¿Hocico de tapir?
+
+[COL2_C:GENERA2]
+No. No, gracias.
+
+[COL2_D:GENERA2]
+Tommy, eres como una brisa de la pampa que me ha liberado de la peste de la corrupción,
+
+[COL2_E:GENERA2]
+aunque, parece que debo llorar su paso y seguir con el negocio como siempre.
+
+[COL2_F:GENERA2]
+Esto no me está acercando mucho a mi dinero...
+
+[COL2_G:GENERA2]
+Tommy, amigo mío, ahora no estás en Liberty. Aquí hacemos las cosas de un modo diferente.
+
+[COL2_H:GENERA2]
+Continuaré con mis investigaciones pero mientras tanto tengo un valioso trato que cerrar.
+
+[COL2_I:GENERA2]
+Un favor para un amigo, Cortez.
+
+[COL2_J:GENERA2]
+Eres un buen amigo, Tommy. Sabía que no me decepcionarías.
+
+[COL2_K:GENERA2]
+Necesito que te encuentres con un mensajero que ha conseguido una tecnología valiosa para mí...
+
+[COL2_1:GENERA2]
+La lluvia, está muy húmeda esta época del año...
+
+[COL2_2:GENERA2]
+¿Qué?
+
+[COL2_3:GENERA2]
+Ah, comment?
+
+[COL2_4:GENERA2]
+Mira, me envía Cortez. Tan sólo dame los malditos chips.
+
+[COL2_5:GENERA2]
+Oh... d'accord.
+
+[COL2_B1:GENERA2]
+~g~Encuéntrate con el mensajero en el centro comercial.
+
+[COL2_B2:GENERA2]
+~g~El mensajero está huyendo con los chips guía, ¡no le dejes escapar!
+
+[COL2_B3:GENERA2]
+~g~Recupera los chips guía y llévaselos de vuelta al Coronel.
+
+[COL2_F1:GENERA2]
+~r~¡Mataste al contacto!
+
+[COL2_F2:GENERA2]
+~r~El mensajero está muerto. Coge los chips guía.
+
+[COL2_6A:GENERA2]
+¡Alto, cerdo imperialista americano! Eso es propiedad del gobierno francés. ¡Y se acabó!
+
+[BLIPHLP:GENERA2]
+Cuando el icono en el radar es un triángulo apuntando hacia arriba, indica que el objetivo está por encima del jugador.
+
+[COL2_F3:GENERA2]
+~r~Los chips de orientación están en el fondo del mar.
+
+[COL2_F4:GENERA2]
+~r~¡El mensajero ha escapado! Has fracasado en conseguir los chips de orientación.
+
+{=================================== MISSION TABLE GENERA3 ===================================}
+
+[GEN3_A:GENERA3]
+Thomas, agradezco que hayas venido.
+
+[GEN3_B:GENERA3]
+Perdóname por ir directamente a los negocios.
+
+[GEN3_C:GENERA3]
+Díaz me ha pedido que supervise una transacción comercial poco importante.
+
+[GEN3_D:GENERA3]
+Esperemos que vaya mejor que la última vez, ¿eh?
+
+[GEN3_E:GENERA3]
+Por eso es por lo que pensé en ti, amigo mío.
+
+[GEN3_F:GENERA3]
+He dejado protección en un aparcamiento de varias plantas.
+
+[GEN3_G:GENERA3]
+Recógela... luego ve a vigilar a los hombres de Díaz en el punto de entrega.
+
+[GEN3_H:GENERA3]
+Gracias, amigo.
+
+[GEN3_1:GENERA3]
+Monopolizando toda la acción, ya veo...
+
+[GEN3_2:GENERA3]
+Mira, ¿quieres dejar de seguirme a todas partes? ¿Por qué no vienes y me demuestras que vales para algo?
+
+[GEN3_3:GENERA3]
+Podría hacerlo. Mi nombre es Lance, por cierto.
+
+[GEN3_5:GENERA3]
+Tú debes de ser el nuevo matón de Cortez.
+
+[GEN3_6:GENERA3]
+Hasta que surjan oportunidades mejor pagadas.
+
+[GEN3_7:GENERA3]
+Estarán aquí en cualquier momento. Será mejor que consigamos una posición ventajosa...
+
+[GEN3_8:GENERA3]
+¡De acuerdo! Yo iré al balcón, tú sube a ese tejado al otro lado del patio.
+
+[GEN3_9:GENERA3]
+¡Estoy vivo! ¡Mamones! ¡Y todo gracias a ti! ¿Cómo te llamas?
+
+[GEN3_10:GENERA3]
+Tommy.
+
+[GEN3_11:GENERA3]
+Nos veremos pronto, ¡creo!
+
+[GEN3_12:GENERA3]
+Mierda. ¿Dónde está Lance?
+
+[GEN3_14:GENERA3]
+¡Tommy! ¡Necesito ayuda aquí!
+
+[GEN3_15:GENERA3]
+¡No te preocupes, te tengo cubierto!
+
+[GEN3_16:GENERA3]
+¡Los hombres de Díaz están siendo eliminados!
+
+[GEN3_19:GENERA3]
+~g~¡Haitianos! ¡Están saboteando el trato! ¡Protege a Díaz!
+
+[GEN3_20:GENERA3]
+~g~Ve al aparcamiento donde podrás recoger el arma que te dejó el Coronel.
+
+[GEN3_22:GENERA3]
+Salud de Díaz:
+
+[GEN3_23:GENERA3]
+~g~¡Has dejado a Lance atrás! ¡Ve a por él!
+
+[GEN3_25:GENERA3]
+~r~¡Lance murió!
+
+[GEN3_28:GENERA3]
+~g~Devuélvele el maletín a Díaz.
+
+[GEN3_29:GENERA3]
+~g~Recoge el maletín y llévaselo a Díaz.
+
+[GEN3_30:GENERA3]
+~r~¡Se escapó con el dinero! ¡Díaz te arrancará las pelotas por ésto!
+
+[GEN3_33:GENERA3]
+~r~¡Mira adónde disparas! Se supone que tienes que proteger a Díaz y a sus hombres, ¡no dispararles!
+
+[GEN3_34:GENERA3]
+~r~¡No va a haber ningún trato si disparas a los cubanos!
+
+[GEN3_35:GENERA3]
+~g~¡Ha robado el dinero de Díaz!
+
+[GEN3_36:GENERA3]
+~g~¡Pilla una moto, persíguele y recupera el dinero de Díaz!
+
+[GEN3_37:GENERA3]
+~g~Aquí vienen los cubanos. Vigila el trato y asegúrate que Díaz y Lance están a salvo.
+
+[GEN3_38:GENERA3]
+~r~¡Díaz ha muerto! ¡Has fallado en protegerle!
+
+[GEN3_39:GENERA3]
+~g~Ve a tu posición estratégica en el piso de arriba.
+
+[GEN3_44:GENERA3]
+~g~Ve con Lance al punto de entrega y vigila a Díaz.
+
+[GEN3_45:GENERA3]
+Estarán aquí en cualquier minuto, mejor será que vayamos tomando posiciones estratégicas.
+
+[GEN3_40:GENERA3] { reVC update }
+Para ~h~disparar hacia el frente ~w~sobre una ~h~moto ~w~pulsa ~h~~k~~VEHICLE_FIREWEAPON~~w~.
+
+[GEN3_41:GENERA3] { reVC update }
+Para ~h~disparar hacia el frente ~w~sobre una ~h~moto ~w~pulsa ~h~~k~~VEHICLE_FIREWEAPON~~w~.
+
+[GEN3_46:GENERA3]
+¡Mierda!
+
+[GEN3_47:GENERA3]
+¡Tommy!
+
+[GEN3_48:GENERA3]
+¡Maldición!
+
+[GEN3_49:GENERA3]
+Salud de Lance:
+
+[GEN3_50:GENERA3]
+~r~¡Has perdido el dinero de Díaz! ¡La próxima vez intenta no convertir mi dinero en cenizas!
+
+[GEN3_51:GENERA3]
+¡Más condenados haitianos en una furgoneta apestosa!
+
+[GEN3_54:GENERA3]
+¡No os quedéis ahí, panda de gilipollas, perseguid a ese haitiano cabrón!
+
+[GEN3_55:GENERA3]
+¡Tommy! ¡Yo me quedo aquí a proteger a Díaz!
+
+[GEN3_18:GENERA3]
+~g~Aquí llegan los cubanos, mantente cerca de Díaz. Asegúrate de que la negociación entre Díaz y Lance sea segura.
+
+[GEN3_56:GENERA3]
+~r~¡Díaz ha caído en una emboscada y ha muerto! ¡La próxima vez no le pierdas de vista!
+
+[GEN3_57:GENERA3]
+El Kruger es un rifle de asalto que te permite apuntar en primera persona manualmente.
+
+[GEN3_58:GENERA3]
+Mantén pulsado ~h~~k~~PED_LOCK_TARGET~~w~ para ~h~apuntar~w~ con un rifle de asalto.
+
+[GEN3_59:GENERA3]
+Mantén pulsado ~h~~k~~PED_LOCK_TARGET~~w~ para ~h~apuntar~w~ con un rifle de asalto.
+
+[GEN3_60:GENERA3]
+Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para ~h~disparar~w~ un rifle de asalto.
+
+[GEN3_61:GENERA3]
+Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para ~h~disparar~w~ un rifle de asalto.
+
+[GEN3_62:GENERA3]
+Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para ~h~disparar~w~ un rifle de asalto.
+
+[GEN3_63:GENERA3]
+Además de realizar maniobras de acercamiento,~h~ las motos ~w~te permiten ~h~disparar hacia adelante~w~.
+
+[GEN3_64:GENERA3] { reVC update }
+Para ~h~disparar hacia el frente ~w~sobre una ~h~moto ~w~pulsa ~h~~k~~VEHICLE_FIREWEAPON~~w~.
+
+[GEN3_65:GENERA3] { reVC update }
+Para ~h~disparar hacia el frente ~w~sobre una ~h~moto ~w~pulsa ~h~~k~~VEHICLE_FIREWEAPON~~w~.
+
+[GEN3_66:GENERA3] { reVC update }
+Para ~h~disparar hacia el frente ~w~sobre una ~h~moto ~w~pulsa ~h~~k~~VEHICLE_FIREWEAPON~~w~.
+
+[GEN3_67:GENERA3]
+Para disparar hacia el frente en una moto deberás tener un subfusil.
+
+[GEN3_53:GENERA3]
+¡Mi dinero!
+
+[GEN3_52:GENERA3]
+¿Esos haitianos creen que pueden enfrentarse a RICARDO DÍAZ?
+
+{=================================== MISSION TABLE GENERA4 ===================================}
+
+[DETON:GENERA4]
+DETONACIÓN:
+
+[COL4_3:GENERA4]
+¡CONVOY, ALTO!
+
+[COL4_6:GENERA4]
+¡NOS ESTÁN DISPARANDO!
+
+[COL4_7:GENERA4]
+¡Civil, aléjese del tanque!
+
+[COL4_8:GENERA4]
+¡DIJE, alejaos, INMEDIATAMENTE!
+
+[COL4_9:GENERA4]
+¡POSICIONES DEFENSIVAS!
+
+[COL4_11:GENERA4]
+- ¡Quite a esos civiles fuera de mi camino, soldado! - ¡Señor, sí, señor!
+
+[COL4_12:GENERA4]
+¡Civil en el TANQUE! ¡DETENEDLE!
+
+[COL4_13:GENERA4]
+Este es un convoy militar, no obstruyan nuestra ruta.
+
+[COL4_14:GENERA4]
+Tírelo, soldado.
+
+[COL4_15:GENERA4]
+- ¡Mueva ese vehículo civil fuera de nuestro camino! - ¡Señor! ¡Moviendo el vehículo, señor!
+
+[COL4_17:GENERA4]
+¡Bien, PELOTÓN, MUÉVANSE!
+
+[COL4_18:GENERA4]
+¡Hay alguien en el tanque, señor!
+
+[COL4_19:GENERA4]
+- ¡Vaya a conseguir unos donuts, soldado! - ¡Señor, sí, señor!
+
+[COL4_20:GENERA4]
+Blanco localizado, señor.
+
+[COL4_21:GENERA4]
+¡FRANCOTIRADOR!
+
+[COL4_22:GENERA4]
+Me voy de aquí.
+
+[COL4_23:GENERA4]
+- ¡Objetivo completado! ¡Pelotón, rompan filas! - Vamos a comer unos cuantos donuts.
+
+[COL4_24:GENERA4]
+¡Activado protocolo de seguridad Delta India Eco! ¡Iniciada autodestrucción del vehículo!
+
+[COL4_26:GENERA4]
+¡Prepárate para morir, basura comunista!
+
+[COL4_B2:GENERA4]
+~r~El tanque llegó a su destino a salvo!
+
+[COL4_B5:GENERA4]
+~r~¡El tanque ha sido destruido!
+
+[COL4_01:GENERA4]
+Díaz estaba complacido, y le gustaría verte de nuevo.
+
+[COL4_02:GENERA4]
+¿Es eso algo bueno?
+
+[COL4_03:GENERA4]
+¡Por supuesto! Aunque estoy empezando a pensar que Díaz fue el responsable de nuestra desafortunada pérdida...
+
+[COL4_04:GENERA4]
+¿Qué te hace decir eso?
+
+[COL4_05:GENERA4]
+Uno no esgrime acusaciones contra un hombre como Díaz... Solo estoy pensando en voz alta...
+
+[COL4_06:GENERA4]
+No importa. Tengo una propuesta de la que te podrías beneficiar...
+
+[COL4_07:GENERA4]
+No tengo tiempo para hacer más recados, Cortez.
+
+[COL4_08:GENERA4]
+Yo habría pensado que un hombre con unas deudas tan grandes estaría ansioso por encontrar oportunidades. Por favor, Tommy, al menos escúchame.
+
+[COL4_09:GENERA4]
+Adelante...
+
+[COL410:GENERA4]
+Tengo un comprador para una pieza de equipo militar que está siendo transportada a través de la ciudad. Recógela para mí...
+
+[COL411:GENERA4]
+y una vez que la tengas, quiero que me llames inmediatamente, entonces...
+
+[COL4_B4:GENERA4]
+~g~El tanque está bloqueado. Busca un modo de engañar a los ocupantes.
+
+[COL4_1:GENERA4]
+- ¿Que qué pasa con el artillero? - ¡No lo sé, señor!
+
+[COL4_4:GENERA4]
+- Ve arriba soldado. - ¡Sí, señor!
+
+[COL4_B1:GENERA4]
+~g~Ve y adquiere el vehículo militar que se está paseando por la ciudad.
+
+[COL4_B3:GENERA4]
+~g~Deja el tanque en el escondite del Coronel antes que se autodestruya.
+
+[COL4_B6:GENERA4]
+~g~¡Encuentra el modo de robar el tanque!
+
+[COL4_B7:GENERA4]
+~g~Conduce el tanque al garaje.
+
+[COL4_B8:GENERA4]
+~g~Bájate del tanque y sal del garaje.
+
+{=================================== MISSION TABLE GENERA5 ===================================}
+
+[COL5A_1:GENERA5]
+Las circunstancias fuerzan una apresurada partida, amigo.
+
+[COL5A_2:GENERA5]
+¿Cuál es el problema?
+
+[COL5A_3:GENERA5]
+Los franceses quieren recuperar la tecnología de sus misiles y después del último incidente,
+
+[COL5A_4:GENERA5]
+siento que es momento de encontrar puertos más seguros.
+
+[COL5A_5:GENERA5]
+¿No sería más seguro volar?
+
+[COL5A_6:GENERA5]
+Estaría muerto antes de alcanzar el mostrador de facturación de equipajes. Además, necesito sacar del país mi mercancía.
+
+[COL5A_7:GENERA5]
+¿Necesitas otro guardaespaldas?
+
+[COL5A_8:GENERA5]
+Tú, amigo mío, vales por diez guardaespaldas...
+
+[COL5B_1:GENERA5]
+Thomas, me has protegido y servido bien.
+
+[COL5B_2:GENERA5]
+Pero ahora debes dejarnos antes de que lleguemos a mar abierto.
+
+[COL5B_4:GENERA5]
+Gracias, Coronel.
+
+[COL5B_5:GENERA5]
+Una petición más, mientras estoy fuera, ¿podrías vigilar a Mercedes por mí?
+
+[COL5B_6:GENERA5]
+Creo que ella puede cuidarse por sí misma, pero seguro, la vigilaré.
+
+[COL5B_7:GENERA5]
+Gracias, amigo mío. Hasta luego.
+
+[COL5B_8:GENERA5]
+Adiós, amigo.
+
+[COL5_7:GENERA5]
+¡Deja de dispararme!
+
+[COL5_9:GENERA5]
+¡Tommy, haz que dejen de dispararme!
+
+[COL5_10:GENERA5]
+¡Tengo inmunidad diplomática!
+
+[COL5_11:GENERA5]
+¡No disparen, soy un Coronel!
+
+[COL5_12:GENERA5]
+Thomas, mátales, mi país te adorará.
+
+[COL5_13:GENERA5]
+¡Tommy, los franceses nos superan!
+
+[COL5_14:GENERA5]
+Tommy, mire a donde mire, hay franceses, ¡lo odio!
+
+[COL5_15:GENERA5]
+Tommy, ¿cómo estás?
+
+[COL5_16:GENERA5]
+¡Ésto es por Piaf y Gainesbourg y por vuestro estúpido pan francés!
+
+[COL5_1:GENERA5]
+¡A babor! ¡A babor!
+
+[COL5_2:GENERA5]
+¡Están atacando desde estribor!
+
+[COL5_3:GENERA5]
+¡El puente está ahí delante!
+
+[COL5_4:GENERA5]
+¡Tienen un helicóptero!
+
+[COL5_B1:GENERA5]
+~g~Protege al Coronel y su yate a toda costa.
+
+[COL5_B2:GENERA5]
+~g~Ponte delante y despeja la ruta del yate del Coronel.
+
+[COL5_B3:GENERA5]
+~r~¡El Coronel está muerto!
+
+[COL5_B4:GENERA5]
+~g~Destruye el helicóptero de ataque.
+
+[COL5B_3:GENERA5]
+Bajaré mi lancha personal. Quédatela, amigo, en señal de mi agradecimiento.
+
+[COL5_B5:GENERA5]
+~g~Dispara para abatir los helicópteros, no pongas en peligro el yate.
+
+[COL5_B6:GENERA5]
+~g~Te has quedado sin munición, consigue más de las escaleras en la cubierta superior.
+
+[COL5_B7:GENERA5]
+~g~Te estás quedando sin salud, consigue más de las escaleras en la cubierta superior.
+
+{=================================== MISSION TABLE HAIT1 ===================================}
+
+[HAM1_A:HAIT1]
+¿Hola? ¿Hola?
+
+[HAM1_B:HAIT1]
+Entra, cielo, y descansa los pies.
+
+[HAM1_C:HAIT1]
+Tú debes de ser el gran hombre malo sobre el que ha estado hablando mi abuelo.
+
+[HAM1_D:HAIT1]
+Me cuenta cosas sobre ti, ya sabes, cuando me visita,
+
+[HAM1_E:HAIT1]
+y sobre los otros que te esperan.
+
+[HAM1_F:HAIT1]
+Bien, todos llevamos muertos mucho tiempo, pero tú...
+
+[HAM1_G:HAIT1]
+No me gustaría estar en tu pellejo.
+
+[HAM1_H:HAIT1]
+Recibí un mensaje. Para que viniese aquí.
+
+[HAM1_I:HAIT1]
+¿Puedes oírles?
+
+[HAM1_J:HAIT1]
+Están diciendo tu nombre, deben quererte mucho, ¿no crees?
+
+[HAM1_K:HAIT1]
+Ahora ayudarás a la tía Poulet y quizás ella te ayude.
+
+[HAM1_L:HAIT1]
+Quizás ella pueda darte un pequeño talismán después de todo esto.
+
+[HAM1_M:HAIT1]
+¿Darte algo de magia para echar el mal de ojo a la policía?
+
+[HAM1_N:HAIT1]
+Mira, esto es todo muy... ¿darme qué?
+
+[HAM1_O:HAIT1]
+Yo, yo, creo que recibí la dirección equivocada...
+
+[HAM1_P:HAIT1]
+Haz esto por mí, Tommy...
+
+[HAM1_Q:HAIT1]
+Los cubanos, tontos orgullosos y desagradables,
+
+[HAM1_R:HAIT1]
+han estado causando problemas a mis encantadores chicos haitianos.
+
+[HAM1_S:HAIT1]
+Ahora le han dicho a la policía donde he estado almacenando mis polvos.
+
+[HAM1_T:HAIT1]
+Ellos piensan que es farlopa, pardillos.
+
+[HAM1_U:HAIT1]
+Ahora sé un buen chico, Tommy, y ve a conseguir los polvos para la tía Poulet.
+
+[HAM1_V:HAIT1]
+Sí, sí, seguro, seguro.
+
+[HAM1_1:HAIT1]
+~g~Los polis se están acercando a nuestros escondites. Ve y consíguelos antes que ellos lo hagan.
+
+[HAM1_2:HAIT1]
+~r~¡Los polis llegaron primero al escondite!
+
+[HAM1_3:HAIT1]
+~g~¡Lleva este material de vuelta al escondite!
+
+[HAM1_4:HAIT1]
+~g~¡Bien! ¡Ahora el siguiente!
+
+[HAM1_6:HAIT1]
+~r~¡Ese almacén está destruido, idiota!
+
+[HAM1_7:HAIT1]
+~g~¡Los polis han conseguido nuestro alijo! ¡Recupéralo antes de que se marchen!
+
+[HAM1_8:HAIT1]
+~g~Los polis están de camino para recoger el alijo, ¡date prisa!
+
+[HAT_1A:HAIT1]
+~g~¡No muevas ni un solo dedo!
+
+{=================================== MISSION TABLE HAIT2 ===================================}
+
+[HAT2_B1:HAIT2]
+~g~Ve hasta la camioneta que contiene las bombas aéreas.
+
+[HAT2_B2:HAIT2]
+Mata a los cubanos...
+
+[HAT2_B4:HAIT2]
+¡Y destruye sus barcos!
+
+[HAT2_B5:HAIT2]
+~g~Los cubanos están huyendo. ¡No les dejes escapar!
+
+[HAT2_B6:HAIT2]
+~r~¡El avión RC está yendo demasiado lejos del alcance!
+
+[HAT2_B7:HAIT2]
+~g~Uno de los cubanos está escapando en un coche. ¡No dejes ningún testigo!
+
+[HAT2_B8:HAIT2]
+~r~¡No te quedan aviones RC!
+
+[HAT2_B9:HAIT2]
+Aviones RC:
+
+[HAT2_1:HAIT2]
+Oh. Lo siento, debo tener la dirección equivocada...
+
+[HAT2_2:HAIT2]
+Bueno, también podrías entrar y descansar los pies y tomarte una taza de té.
+
+[HAT2_3:HAIT2]
+¿Tienes algo ahí para mí?
+
+[HAT2_4:HAIT2]
+Sí...
+
+[HAT2_5:HAIT2]
+Este lugar me parece familiar. Un olor de la niñez... un deja vu...
+
+[HAT2_6:HAIT2]
+Bien, Tommy, te voy a susurrar un pequeño recado para que lo hagas. Escúchame bien, ¿vale?
+
+[HAT2_7:HAIT2]
+Te pareces a alguien que yo...
+
+[HAT2_8:HAIT2]
+Los cubanos tienen barcos rápidos que usan para cruzar el charco cargados de polvo.
+
+[HAT2_9:HAIT2]
+Es su sustento.
+
+[HAT2_10:HAIT2]
+Mi sobrino ha estado preparando pequeñas bombas aéreas para eliminarles.
+
+[HAT2_11:HAIT2]
+Vuela los barcos y conviértelos en madera de ataúd.
+
+[HAT2_12:HAIT2]
+Muchas gracias por el té.
+
+[HAT2_B3:HAIT2] { reVC update }
+Pulsa ~h~~k~~VEHICLE_FIREWEAPON~~w~ para soltar una bomba. Pulsa ~h~~k~~VEHICLE_ENTER_EXIT~~w~ para cancelar.
+
+{=================================== MISSION TABLE HAIT3 ===================================}
+
+[HAM3_A:HAIT3]
+¿Hola? Hola, eh... Estaba buscando a alguien por aquí...
+
+[HAM3_B:HAIT3]
+Pareces hambriento, Tommy,
+
+[HAM3_C:HAIT3]
+¿Te conozco?
+
+[HAM3_D:HAIT3]
+Silencio.
+
+[HAM3_E:HAIT3]
+Una cosa más y te podré dejar marchar, Tommy.
+
+[HAM3_F:HAIT3]
+Mis chicos están en guerra con los cubanos.
+
+[HAM3_G:HAIT3]
+Pero sin armas.
+
+[HAM3_H:HAIT3]
+Pero los cubanos tienen una sorpresa por llegar.
+
+[HAM3_I:HAIT3]
+Mientras combaten en las calles, tú tomarás este rifle y los matarás en medio del alboroto.
+
+[HAM3_J:HAIT3]
+Nadie te verá, nadie te oirá.
+
+[HAM3_K:HAIT3]
+Tommy, si haces esto por mí, ya no estarás atado a los lazos de mi delantal.
+
+[HAM3_1:HAIT3]
+~g~Debemos ganar esta batalla. Si todos los haitianos mueren, perdemos nosotros.
+
+[HAM3_3:HAIT3]
+~g~Espero que los cubanos hagan trampas así que permanece alerta.
+
+[HAM3_4:HAIT3]
+~r~¡Te han visto! ¡La misión ha fracasado!
+
+[HAM3_5:HAIT3]
+~g~Debes matar a los cubanos desde lejos. No deben verte.
+
+[HAM3_8:HAIT3]
+~g~¡Los haitianos están muriendo! Mejora tu puntería.
+
+[HAM3_7:HAIT3]
+~g~¡Cuidado! Los cubanos han traído refuerzos. ¡¡Acaba con todos ellos!!
+
+[HAM3_2:HAIT3]
+~r~¡Los haitianos han muerto!
+
+[HAM3_L:HAIT3]
+Vale, tía...
+
+{=================================== MISSION TABLE HOTEL ===================================}
+
+[INTB_A:HOTEL]
+¡Tommy! Tommy, ha pasado tanto tiempo.
+
+[INTB_B:HOTEL]
+Hola, Sonny.
+
+[INTB_C:HOTEL]
+Lo sé, lo sé. Te abruma la emoción.
+
+[INTB_D:HOTEL]
+Quince años... si parece que fue ayer.
+
+[INTB_E:HOTEL]
+Supongo que es cuestión de perspectiva.
+
+[INTB_F:HOTEL]
+Eh, estar en el talego por la familia no es agradable,
+
+[INTB_G:HOTEL]
+aunque la familia cuida de los suyos, ¿no es verdad?
+
+[INTB_H:HOTEL]
+Y bien, cómo fue el negocio... ¿estás sentado en una pila de oro blanco?
+
+[INTB_I:HOTEL]
+Mira, Sonny, nos tendieron una trampa. El negocio fue una emboscada. Harry y Lee están muertos.
+
+[INTB_J:HOTEL]
+Me estás tomando el pelo, ¿no? Tommy. Dime que aún tienes el dinero.
+
+[INTB_K:HOTEL]
+No Sonny... no tengo el dinero.
+
+[INTB_L:HOTEL]
+Ése era mi dinero, Tommy, ¡mi dinero!
+
+[INTB_M:HOTEL]
+¡Espero que no me andes jodiendo, Tommy, porque sabes que soy un hombre con el que no se puede jugar!
+
+[INTB_N:HOTEL]
+Espera Sonny.
+
+[INTB_O:HOTEL]
+Tienes mi garantía personal de que voy a conseguir recuperar el dinero y el alijo.
+
+[INTB_P:HOTEL]
+Y te voy a enviar por correo las pelotas de los responsables.
+
+[INTB_Q:HOTEL]
+Eh, ya lo sé. No eres tonto, Tommy, pero te prevengo, yo tampoco lo soy.
+
+[INTB_R:HOTEL]
+Si se tratase de cualquier otro, ya estarías MUERTO.
+
+[INTB_S:HOTEL]
+Pero como se trata de ti, como hemos hecho historia, voy a dejar que te ocupes de esto.
+
+[INTB_T:HOTEL]
+Mira, Sonny, tienes mi palabra.
+
+[INTB_U:HOTEL]
+Estaremos en contacto.
+
+{=================================== MISSION TABLE ICECRE1 ===================================}
+
+[ICC1_1:ICECRE1]
+~g~Utiliza la furgoneta de los helados para distribuir perica en Vice City.
+
+[ICC1_3:ICECRE1]
+~g~Recibirás dinero por cada venta que hagas, pero cuantas más transacciones hagas más atraerás la atención de la policía.
+
+[ICC1_4:ICECRE1]
+~g~No hay ningún cliente en esta zona, inténtalo en otra.
+
+[ICC1_5:ICECRE1]
+Negocios hechos:
+
+[ICC1_6:ICECRE1]
+~g~Utiliza la furgoneta Mr. Whoopee para distribuir los productos Cherry Popper por Vice City.
+
+[ICC1_7:ICECRE1]
+~g~Por cada transacción que hagas recibirás dinero, aunque cuantas más operaciones lleves a cabo más atención provocarás de la policía.
+
+[ICC1_8:ICECRE1]
+~g~Para llevar a cabo el negocio ~h~aparca la furgoneta, ~g~y pulsa el ~h~~k~~VEHICLE_HORN~ ~g~para que suene la música que llamará la atención de la gente.
+
+[ICC1_9:ICECRE1]
+~g~A las bandas locales no les gustará que hagas negocios en su territorio así que si haces esto, prepárate para hostilidades.
+
+[ICC1_10:ICECRE1]
+~g~Has hecho ~1~ tratos!
+
+[ICC1_11:ICECRE1]
+~g~Has hecho ~1~ trato!
+
+[ICC1_12:ICECRE1]
+¡PROPIEDAD ADQUIRIDA!
+
+[ICC1_13:ICECRE1]
+~r~¡No conseguiste ningún trato!
+
+[ICC1_14:ICECRE1]
+FÁBRICA DE HELADOS CONSOLIDADA
+
+[ICC1_15:ICECRE1]
+~g~La fábrica de helados generará ahora unos ingresos máximos de hasta ~1~ $. Asegúrate de recaudarlos regularmente.
+
+[ICC1_2:ICECRE1]
+~g~Aparca la furgoneta y pulsa ~h~~k~~VEHICLE_HORN~~w~ para que suene la música indicando a los clientes que estás listo para hacer empezar.
+
+[ICC1_16:ICECRE1]
+~g~Utiliza la furgoneta Mr. Whoopee para distribuir los productos Cherry Popper por Vice City.
+
+[ICE_AT1:ICECRE1]
+FÁBRICA DE HELADOS CONSOLIDADA
+
+[ICE_AT2:ICECRE1]
+~g~La fábrica Cherry Popper generará ahora unos ingresos hasta un máximo de ~1~ $. Asegúrate de recaudarlos de manera regular.
+
+[ICC1_17:ICECRE1]
+Misión de Distribución finalizada
+
+[ICC1_18:ICECRE1]
+Venta total de helados: ~1~ $
+
+[ICC1_19:ICECRE1]
+Total de negocios hechos: ~1~
+
+{=================================== MISSION TABLE ICECUT ===================================}
+
+[ICC1_A:ICECUT]
+¿Quién eres tú?
+
+[ICC1_B:ICECUT]
+El nuevo propietario.
+
+[ICC1_C:ICECUT]
+¿Fuiste ahora o en cualquier momento un niño?
+
+[ICC1_D:ICECUT]
+¿De qué estás hablando?
+
+[ICC1_E:ICECUT]
+¿Fuiste niño?
+
+[ICC1_F:ICECUT]
+¡Sí! ¡Calma! ¿Qué pasa contigo?
+
+[ICC1_G:ICECUT]
+Lo sabía. Un niño.
+
+[ICC1_H:ICECUT]
+¡Un maldito, apestoso, lloriqueante, mocoso, vil, vomitivo y pequeño bebé chillón!
+
+[ICC1_I:ICECUT]
+Bebés... Criaturas repugnantes, horribles y espantosas.
+
+[ICC1_J:ICECUT]
+Mami no te quiere. ¡mierdecilla!
+
+[ICC1_K:ICECUT]
+Cálmate.
+
+[ICC1_L:ICECUT]
+ODIO los bebés, odio los niños.
+
+[ICC1_M:ICECUT]
+Son unos pequeños guarros, llorones, mocosos, perversos y vomitivos...
+
+[ICC1_N:ICECUT]
+¡Ya es suficiente!
+
+[ICC1_O:ICECUT]
+¿Qué pasa contigo?
-{ re3 updates }
+[ICC1_P:ICECUT]
+¿Fabricas helado, de acuerdo? Es básicamente para los niños.
+
+[ICC1_Q:ICECUT]
+¿Qué clase de psicópata eres tú?
+
+[ICC1_R:ICECUT]
+Solo para que lo entienda, ¿para qué hacer felices a los niños si los odias?
+
+[ICC1_S:ICECUT]
+Oh, estúpido, apestoso, lloriqueante...
+
+[ICC1_T:ICECUT]
+¡Cállate!
+
+[ICC1_U:ICECUT]
+¡Mocoso!
+
+[ICC1_V:ICECUT]
+El helado es una tapadera.
+
+[ICC1_W:ICECUT]
+Distribuimos otros productos no lácteos.
+
+[ICC1_X:ICECUT]
+Y si veo un niño, le saco provecho.
+
+[ICC1_Y:ICECUT]
+¿Verdad, niños? Sí, sí, lo hago. Mamá no os quiere.
+
+[ICC1_Z:ICECUT]
+¡Os ODIA!
+
+[ICC1_ZA:ICECUT]
+¡PROPIEDAD ADQUIRIDA!
+
+{=================================== MISSION TABLE INTRO ===================================}
+
+[INT1_A:INTRO]
+Tommy Vercetti... Mierda.
+
+[INT1_B:INTRO]
+No pensé que le fueran a soltar nunca.
+
+[INT1_C:INTRO]
+Mantuvo la cabeza gacha, ayuda a la gente a olvidar.
+
+[INT1_D:INTRO]
+La gente lo recordará antes de lo que crees.
+
+[INT1_E:INTRO]
+Cuando le vean paseando por las calles de su barrio.
+
+[INT1_F:INTRO]
+Será malo para el negocio.
+
+[INT1_G:INTRO]
+Bien, ¿qué vamos a hacer, Sonny?
+
+[INT1_H:INTRO]
+Le tratamos como a un viejo amigo y le tenemos ocupado fuera de la ciudad. ¿De acuerdo?
+
+[INT1_I:INTRO]
+Hemos estado hablando de expandirnos hacia el sur. ¿Verdad?
+
+[INT1_J:INTRO]
+Hoy en día Vice City es oro de veinticuatro quilates.
+
+[INT1_K:INTRO]
+Los colombianos, los mejicanos, demonios,
+
+[INT1_L:INTRO]
+incluso esos refugiados cubanos se están repartiendo un buen pedazo de la acción.
+
+[INT1_M:INTRO]
+Pero todo es por la nieve, Sonny.
+
+[INT1_N:INTRO]
+¡Ninguna de las familias tocará esa mierda!
+
+[INT1_O:INTRO]
+Los tiempos cambian.
+
+[INT1_P:INTRO]
+Las familias no pueden seguir dando la espalda mientras nuestros enemigos recogen las recompensas.
+
+[INT1_Q:INTRO]
+Así que enviaremos a alguien para que nos hagan el trabajo sucio
+
+[INT1_R:INTRO]
+y tranquilamente nos llevaremos un buen cacho. ¿Vale?
+
+[INT1_S:INTRO]
+¿Quién es nuestro contacto allí?
+
+[INT1_T:INTRO]
+Ken Rosenberg, un estúpido abogado.
+
+[INT1_U:INTRO]
+¿Cómo va a atar corto a Vercetti?
+
+[INT1_V:INTRO]
+No necesitamos que lo haga.
+
+[INT1_W:INTRO]
+Simplemente le soltaremos en Vice City
+
+[INT1_X:INTRO]
+y le daremos un poco de dinero para que empiece. ¿De acuerdo?
+
+[INT1_Y:INTRO]
+Le damos unos cuantos meses.
+
+[INT1_Z:INTRO]
+Luego vamos,
+
+[INT1_A1:INTRO]
+y le hacemos una pequeña visita, ¿de acuerdo?
+
+[INT1_A2:INTRO]
+Para ver cómo le va.
+
+[INT2_A:INTRO]
+¡Eh, eh, tíos! ¡Aquí, eh, Ken Rosenberg! ¡Je, je, genial!
+
+[INT2_B:INTRO]
+Bueno, voy a llevaros a la reunión, ¿vale?
+
+[INT2_C:INTRO]
+He hablado con los proveedores, y ellos están muy...
+
+[INT2_D:INTRO]
+interesados en empezar una relación de negocios, así que...
+
+[INT2_E:INTRO]
+si todo esto va bien, deberíamos...
+
+[INT2_F:INTRO]
+empezar a obtener beneficios, lo cual es, ya sabes...
+
+[INT2_G:INTRO]
+Bueno.
+
+[INT2_H:INTRO]
+Entonces. Son hermanos, ¿vale?
+
+[INT2_I:INTRO]
+Uno dirige el negocio,
+
+[INT2_J:INTRO]
+y el otro se encarga de los vuelos.
+
+[INT2_K:INTRO]
+Ahora operan fuera de Méjico
+
+[INT3_A:INTRO]
+Bien, son los del helicóptero.
+
+[INT3_B:INTRO]
+De acuerdo, este es el trato.
+
+[INT3_C:INTRO]
+Quieren un intercambio directo en campo abierto.
+
+[INT3_D:INTRO]
+¿De acuerdo? De acuerdo, permanece firme, vamos.
+
+[INT3_E:INTRO]
+De acuerdo, ahora con cuidado.
+
+[INT3_F:INTRO]
+Estoy aquí. ¡El coche está en marcha, nena!
+
+[INT3_G:INTRO]
+¿Lo tienes?
+
+[INT3_H:INTRO]
+Colombiana, 100% con un grado de pureza A, amigo.
+
+[INT3_I:INTRO]
+¿Los verdes?
+
+[INT3_J:INTRO]
+De diez y de veinte... usados.
+
+[INT3_L:INTRO]
+¡Vamos, fuera de aquí! ¡Arranca!
+
+[INT4_A:INTRO]
+¡Jodidos! ¡Estamos jodidos!
+
+[INT4_B:INTRO]
+Muy típico,
+
+[INT4_C:INTRO]
+saco la cabeza del agujero un jodido segundo,
+
+[INT4_D:INTRO]
+¡Y el destino me echa la mierda a la cara!
+
+[INT4_E:INTRO]
+Bueno, ¡jódete!
+
+[INT4_F:INTRO]
+Cierra el pico y deja de quejarte. Estás vivo, ¿no?
+
+[INT4_G:INTRO]
+Déjame justo aquí.
+
+[INT4_H:INTRO]
+Ve y abandona el coche y luego vete a dormir un poco.
+
+[INT4_I:INTRO]
+Mañana me pasaré por tu oficina y podemos empezar a solucionar esto.
+
+[INT4_J:INTRO]
+De acuerdo, es una buena idea, iré a dormir un poco.
+
+[INT4_K:INTRO]
+¿Qué vas a hacer tú.
+
+[INT4_L:INTRO]
+Me las arreglaré para volver a mi hotel.
+
+[INT4_M:INTRO]
+A despejar la mente y a pensar sobre esta mierda.
+
+[INT4_N:INTRO]
+Vale.
+
+[INTRO1:INTRO]
+Saco la cabeza del agujero un jodido segundo y el destino, ¡me echa la mierda en la cara!
+
+[INTRO2:INTRO]
+Vete a dormir un poco.
+
+[INTRO3:INTRO]
+¿Qué es lo que vas a hacer?
+
+[INTRO4:INTRO]
+Mañana me pasaré por tu oficina y empezaremos a solucionar todo este desorden.
+
+[INT3_K:INTRO]
+Creo que hemos llegado a un acuerdo, amigo mío.
+
+[INT3_M:INTRO]
+Déjame ver.
+
+[INT2_L:INTRO]
+no, no, no, espera...
+
+[INT3_N:INTRO]
+¡Mierda!
+
+{=================================== MISSION TABLE KENT1 ===================================}
+
+[KPM1_A:KENT1]
+A ver tío, te voy a salvar el culo, colega.
+
+[KPM1_B:KENT1]
+¿De qué coño me estás hablando?
+
+[KPM1_C:KENT1]
+Conoces a ese bastardo de Díaz, Don Farlopa.
+
+[KPM1_D:KENT1]
+Tiene a tu colega, Lance. Dicen que tu amigo intentó atacarle por sorpresa...
+
+[KPM1_E:KENT1]
+pero no fue lo suficientemente sorprendente, si entiendes lo que te quiero decir.
+
+[KPM1_F:KENT1]
+¿A dónde le llevó?
+
+[KPM1_G:KENT1]
+¡Tranquilo! Le hicieron cruzar la ciudad hasta el desguace.
+
+[KPM1_H:KENT1]
+Maldita sea... ¡Chalado!
+
+[KPM1_2:KENT1]
+~r~¡Se suponía que debías sacar con vida a Lance!
+
+[KPM1_3:KENT1]
+SALUD DE LANCE:
+
+[RESC_1:KENT1]
+¿Crees que puedes usar un arma?
+
+[RESC_2:KENT1]
+Sí... supongo... yo también me alegro de verte.
+
+[RESC_3:KENT1]
+Salgamos de aquí.
+
+[RESC_4:KENT1]
+Ahí va todo mi cuidadoso plan, directo a la mierda, gracias a ti. La jodiste bien.
+
+[RESC_5:KENT1]
+Mató a mi hermano. ¿Qué esperabas que hiciese, cortarle el césped?
+
+[RESC_6:KENT1]
+Vamos a tener que eliminar a ese mamón de Díaz antes de que él nos elimine a nosotros.
+
+[RESC_7:KENT1]
+Haz que te curen y encuéntrate conmigo en el puente que va a Star Island, ¿de acuerdo?
+
+[RESC_8:KENT1]
+De acuerdo, entendido.
+
+[KPM1_1:KENT1]
+~g~¡Lance está siendo retenido en el desguace, ve y libérale!
+
+[KPM1_4:KENT1]
+~g~¡Lleva a Lance al hospital!
+
+[M_PASSN:KENT1]
+¡MISIÓN SUPERADA!
+
+[KPM1_5:KENT1]
+~g~¡Los hombres de Díaz te están buscando! Lleva a Lance al hospital.
+
+{=================================== MISSION TABLE KICKSTT ===================================}
+
+[KICK1_2:KICKSTT]
+~r~¡No volviste a la moto lo suficientemente rápido!
+
+[KICK1_7:KICKSTT]
+~r~¡Has destrozado la moto!
+
+[KICK1_8:KICKSTT]
+~g~¡Sube a la moto!
+
+[KICK1_T:KICKSTT]
+TIEMPO EMPLEADO:
+
+[KICKTM:KICKSTT]
+~b~TIEMPO DE PRUEBA: ~1~:~1~
+
+[KICKTM2:KICKSTT]
+~b~TIEMPO DE PRUEBA: ~1~:0~1~
+
+[GETBIKE:KICKSTT]
+~g~Tienes ~1~ segundos para volver a subir a una moto antes de que termine la misión.
+
+[KICK1_1:KICKSTT]
+~g~Completa el circuito lo más rápidamente posible.
+
+[KICK1_6:KICKSTT]
+~g~¡Bien hecho!
+
+[KICK_10:KICKSTT]
+~g~Utiliza la Sanchez para completar el circuito pasando por todos los puntos de control.
+
+[KICK_12:KICKSTT]
+~r~¡La has cagado!
+
+[KICK_13:KICKSTT]
+~r~¡Has tardado mucho tiempo!
+
+[KICK_11:KICKSTT]
+~g~Para abandonar la misión, sitúate en el ~q~marcador rosa~g~.
+
+{=================================== MISSION TABLE LAWYER1 ===================================}
+
+[LAW1_A:LAWYER1]
+Ve a dormir un poco, dice...
+
+[LAW1_B:LAWYER1]
+¡Llevo sentado en esta silla toda la noche con las luces apagadas y bebiendo café!
+
+[LAW1_C:LAWYER1]
+Esto es un desastre. ¡Estamos muy jodidos, tío!
+
+[LAW1_D:LAWYER1]
+Estos gorilas, escúchame, van a venir aquí a arrancarme la cabeza. ¡Es ridículo!
+
+[LAW1_E:LAWYER1]
+¡NO fui a la universidad para ésto! De acuerdo, ¿ahora qué coño vamos a hacer?
+
+[LAW1_F:LAWYER1]
+Cállate, siéntate y relájate. Te diré lo que vamos a hacer.
+
+[LAW1_G:LAWYER1]
+Vas a descubrir quién se llevó nuestra nieve... y después voy a cargármelos.
+
+[LAW1_H:LAWYER1]
+Es una buena idea. Es una idea GENIAL. Déjame pensar, déjame pensar, déjame pensar.
+
+[LAW1_I:LAWYER1]
+¡Oh! Está este Coronel retirado, el coronel Juan García Cortez.
+
+[LAW1_J:LAWYER1]
+Él es el que me ayudó a montar esta operación
+
+[LAW1_K:LAWYER1]
+bien lejos de los matones establecidos de Vice City. ¿Entendido?
+
+[LAW1_L:LAWYER1]
+Bien, escucha. Está dando una fiesta en su lujoso yate en la bahía
+
+[LAW1_M:LAWYER1]
+y todos los hombres más importantes de Vice City van a estar allí.
+
+[LAW1_N:LAWYER1]
+Tengo invitación, por supuesto que tengo invitación,
+
+[LAW1_O:LAWYER1]
+pero no sueñes que vaya a asomar la cabeza por esa puerta... ¡ni lo sueñes!
+
+[LAW1_P:LAWYER1]
+¡Te lo dije, cállate! Iré yo mismo...
+
+[LAW1_Q:LAWYER1]
+A mí también me gusta el estilo de 1978, pero esto no va a ser una fiesta con cerveza y tías en pelotas.
+
+[LAW1_R:LAWYER1]
+Quiero decir, sin ánimo de ofender, creo que podrías hacer que la gente se volviese a mirar por razones equivocadas.
+
+[LAW1_S:LAWYER1]
+¿Qué hay de malo con cómo voy vestido?
+
+[LAW1_T:LAWYER1]
+Vale, mira, ten. Pásate por donde Rafael, dile que te envío yo, hará que parezcas respetable.
+
+[LAW1_U:LAWYER1]
+Bien, ve, vamos...
+
+[LAWP_1:LAWYER1]
+Buenas noches.
+
+[LAWP_2:LAWYER1]
+Tengo entendido que viene de parte del Sr. Rosenberg,
+
+[LAWP_3:LAWYER1]
+Espero que ningún problema reciente le haya afectado a su salud física, o uh,
+
+[LAWP_4:LAWYER1]
+o mental, Sr... ¿eh?
+
+[LAWP_5:LAWYER1]
+Vercetti. Tan sólo tiene un poco de... agorafobia.
+
+[LAWP_6:LAWYER1]
+Excelente, excelente. ¿Y usted?
+
+[LAWP_7:LAWYER1]
+Yo solo quiero mi farlopa.
+
+[LAWP_8:LAWYER1]
+Ah. Ha sido un desgraciado cúmulo de circunstancias para todos los interesados.
+
+[LAWP_9:LAWYER1]
+Por supuesto, he iniciado mis propias pesquisas
+
+[LAWP_10:LAWYER1]
+pero un asunto tan delicado llevará tiempo.
+
+[LAWP_11:LAWYER1]
+Quizás hablemos más tarde. ¿Eh?
+
+[LAWP_12:LAWYER1]
+Mientras tanto, permítame presentarle a mi hija.
+
+[LAWP_13:LAWYER1]
+¡Mercedes!
+
+[LAWP_14:LAWYER1]
+Cara mía, ¿podrías acompañar a nuestro invitado mientras atiendo a mis obligaciones?
+
+[LAWP_15:LAWYER1]
+Por supuesto, papá.
+
+[LAWP_16:LAWYER1]
+Por favor, discúlpeme.
+
+[LAWP_17:LAWYER1]
+¿Mercedes?
+
+[LAWP_18:LAWYER1]
+Intenta acostumbrarte.
+
+[LAWP_19:LAWYER1]
+En fin, déjame presentarte a algunos de nuestros invitados más distinguidos...
+
+[LAWP_20:LAWYER1]
+Ese es nuestro congresista Alex Shrub con la sonriente estrella de la silicona Candy Suxxx...
+
+[LAWP_21:LAWYER1]
+¿Conoces a mi encantadora esposa, Laura? ¿No?
+
+[LAWP_22:LAWYER1]
+Bueno, desafortunadamente ella está en Alabama. Te presento a Candy.
+
+[LAWP_23:LAWYER1]
+Y por ahí tenemos a la estirada estrella de las Mambas de Vice City, BJ.
+
+[LAWP_24:LAWYER1]
+Siempre tan encantador.
+
+[LAWP_25:LAWYER1]
+Le paré en seco, lo hice, ¡y le dejé en una silla de ruedas!
+
+[LAWP_26:LAWYER1]
+¡Ja, ja, ésa es buena!
+
+[LAWP_27:LAWYER1]
+Bien, ahora estoy mirando una verdadera propiedad de primera.
+
+[LAWP_28:LAWYER1]
+Y ese anfibio al lado de la piscina es Jezz Torrent,
+
+[LAWP_29:LAWYER1]
+cantante principal de Love Fist.
+
+[LAWP_30:LAWYER1]
+¿Sabéis cómo juegan al ping-pong en Tailandia?
+
+[LAWP_31:LAWYER1]
+Dejad que os lo cuente,
+
+[LAWP_32:LAWYER1]
+¡no hace falta una pala precisamente! ¿entendéis lo que quiero decir?
+
+[LAWP_33:LAWYER1]
+Impotente.
+
+[LAWP_34:LAWYER1]
+Y el trío charlatán.
+
+[LAWP_35:LAWYER1]
+Esa glándula sudorípara durmiente es la mano derecha de papá, González
+
+[LAWP_36:LAWYER1]
+y los otros dos son el pastor Richards
+
+[LAWP_37:LAWYER1]
+y el director de cine seudointelectual, Steve Scott.
+
+[LAWP_38:LAWYER1]
+Pasión con las invasoras ninfómanas,
+
+[LAWP_39:LAWYER1]
+entonces aparece el tiburón gigante y...
+
+[LAWP_40:LAWYER1]
+¡Les arranca las pollas de un mordisco!
+
+[LAWP_41:LAWYER1]
+Ja, bien. Nunca has visto nada igual, ¿Verdad?
+
+[LAWP_42:LAWYER1]
+¡Coronel!
+
+[LAWP_43:LAWYER1]
+¡Sus fiestas tienen siempre un gran éxito!
+
+[LAWP_44:LAWYER1]
+Sólo puedo pedir disculpas por mi tardía llegada.
+
+[LAWP_45:LAWYER1]
+Ah, de nada amigo. ¿Cómo nos encontramos?
+
+[LAWP_46:LAWYER1]
+Nuestro negocio es muy estresante, siempre intentan desbancarnos.
+
+[LAWP_47:LAWYER1]
+Hay un momento para recompensar a los amigos de uno y para liquidar a los enemigos, amigo.
+
+[LAWP_48:LAWYER1]
+¿Quién es el bocazas?
+
+[LAWP_49:LAWYER1]
+Ricardo Díaz, alias Don Farlopa.
+
+[LAWP_50:LAWYER1]
+¡Mercedes!
+
+[LAWP_51:LAWYER1]
+Oh, estaba a punto de llevar a mi amigo de vuelta a la ciudad.
+
+[LAWP_52:LAWYER1]
+¡En otro momento, Ricardo!
+
+[LAWP_53:LAWYER1]
+Salgamos de aquí.
+
+[LAWP_54:LAWYER1]
+Mejor llévame al club Pole Position.
+
+[LAW1_2:LAWYER1]
+~g~Ve al barco del Coronel.
+
+[LAW1_4:LAWYER1]
+~r~¡Mataste a la hija del Coronel!
+
+[LAW1_5:LAWYER1]
+¿Trabajarás para mi padre?
+
+[LAW1_6:LAWYER1]
+Quizás.
+
+[LAW1_7:LAWYER1]
+¿Te importa que pose mi mano en tu regazo?
+
+[LAW1_8:LAWYER1]
+Quizás...
+
+[LAW1_9:LAWYER1]
+Es tan difícil tener un padre rico y poderoso. Vamos.
+
+[LAW1_10:LAWYER1]
+¡Nos vemos, guapo!
+
+[LAW1_11:LAWYER1]
+Estoy seguro.
+
+[LAW1_12:LAWYER1]
+Bonita moto.
+
+[LAW1_13:LAWYER1]
+¡No! ¡Mi moto!
+
+[LAW1_3:LAWYER1]
+~g~Lleva a la hija del Coronel al club Pole Position.
+
+[HELP20:LAWYER1]
+Ve al icono de la ~h~camiseta~w~ que hay en el radar para encontrar la tienda de Rafael.
+
+[LAW1_14:LAWYER1]
+¡Guau!, Me encantaría probar tu moto.
+
+[LAW1_15:LAWYER1]
+Sí pequeño, pues recógela de Howlin' Pete's
+
+{=================================== MISSION TABLE LAWYER2 ===================================}
+
+[LAW2_A:LAWYER2]
+¡Ah! Espero que te lo estés pasando bien. Porque yo me estoy volviendo loco de preocupación. ¿Qué has descubierto?
+
+[LAW2_B:LAWYER2]
+Que hay más criminales en esta ciudad que en la cárcel. Necesitamos un confidente de las calles...
+
+[LAW2_C:LAWYER2]
+Vale, déjame pensar, déjame pensar, déjame pensar...
+
+[LAW2_D:LAWYER2]
+¡AH! ¡Lo tengo!
+
+[LAW2_E:LAWYER2]
+Está este inglés, un baboso de la industria musical,
+
+[LAW2_F:LAWYER2]
+se hace llamar Kent Paul.
+
+[LAW2_G:LAWYER2]
+Bueno, tiene la cabeza tan metida en la mayoría de los culos de Vice City
+
+[LAW2_H:LAWYER2]
+que si alguien sabe el paradero de 20 kilos de farlopa,
+
+[LAW2_I:LAWYER2]
+es este tío, ¿de acuerdo? Siempre está en el Malibú.
+
+[LAW2_J:LAWYER2]
+Le haré una visita.
+
+[LAW2B_A:LAWYER2]
+¿De dónde saliste?
+
+[LAW2B_B:LAWYER2]
+He estado buscando una chica como tú durante siglos, tía...
+
+[LAW2B_C:LAWYER2]
+Kent Paul, tía. Por aquí soy el que manda.
+
+[LAW2B_D:LAWYER2]
+Estoy buscando a un tipo inglés...
+
+[LAW2B_E:LAWYER2]
+Muevo hilos, ¿entiendes lo que quiero decir?
+
+[LAW2B_F:LAWYER2]
+Te invitaré. Lo que quieras, te lo conseguiré, chica.
+
+[LAW2B_G:LAWYER2]
+No te preocupes por nada, tía.
+
+[LAW2B_H:LAWYER2]
+Piérdete, guapa.
+
+[LAW2B_I:LAWYER2]
+¡Eh, eh, eh, eh, eh!
+
+[LAW2B_J:LAWYER2]
+¿Eres Kent Paul? Soy amigo de Rosenberg...
+
+[LAW2B_K:LAWYER2]
+Rosenberg... Rosenberg... ¡Oh, ese chalado abogado de pacotilla!
+
+[LAW2B_L:LAWYER2]
+¡Ese tipo podría defender a un inocente y mandarle directamente al corredor de la muerte!
+
+[LAW2B_M:LAWYER2]
+Ponnos otra copa, hermano.
+
+[LAW2B_N:LAWYER2]
+Todo el mundo es cómico.
+
+[LAW2B_O:LAWYER2]
+Escúchame, he perdido veinte kilos y un montón de pasta...
+
+[LAW2B_P:LAWYER2]
+¿Drogas, tío? Es un juego de tontos.
+
+[LAW2B_Q:LAWYER2]
+¿Qué sabes al respecto?
+
+[LAW2B_R:LAWYER2]
+¡Eh, eh! A lo que iba es que,
+
+[LAW2B_S:LAWYER2]
+hay un chef-camello que tiene su negocio en la cocina de un hotel en Ocean Drive.
+
+[LAW2B_T:LAWYER2]
+Últimamente parece muy satisfecho de sí mismo. ¿Podrías ir y tantearle?
+
+[LAW2B_U:LAWYER2]
+Lo haré... y ya nos veremos.
+
+[LAW2B_V:LAWYER2]
+Sí, está bien. Venga... vete, idiota. ¡Te voy a quitar las luces de un puñetazo!
+
+[LAW2B_W:LAWYER2]
+Ponme una copa... ¡y dónde está esa zorra!
+
+[LAW2C_A:LAWYER2]
+Oh, así se hace, tipo duro. Machácale. Eso debería hacerle muy parlanchín.
+
+[LAW2C_B:LAWYER2]
+¿Tú también quieres un poco?
+
+[LAW2C_C:LAWYER2]
+Eh, relájate. Quiero lo que tú quieres, hermano.
+
+[LAW2C_D:LAWYER2]
+¿Oh, sí? ¿Y qué es eso?
+
+[LAW2C_E:LAWYER2]
+Tu dinero... y la nieve de mi hermano muerto. Desgraciadamente, hiciste callar a nuestro contacto.
+
+[LAW2C_F:LAWYER2]
+Los accidentes ocurren. Piérdete.
+
+[LAW2C_G:LAWYER2]
+Eh, eh, guau. No hay necesidad de hacerte el llanero solitario conmigo.
+
+[LAW2C_H:LAWYER2]
+Tal y como yo lo veo... somos dos hombres en una ciudad extraña. Necesitamos cubrirnos las espaldas mutuamente.
+
+[LAW2C_I:LAWYER2]
+Mi espalda está bien, hermano...
+
+[LAW2C_J:LAWYER2]
+¿Estás seguro de eso? Ten, toma esto...
+
+[LAW2C_K:LAWYER2]
+¡Sígueme!
+
+[LAW2_1:LAWYER2]
+¿Qué estás mirando?
+
+[LAW2_2:LAWYER2]
+Mejor empieza a hablar...
+
+[LAW2_3:LAWYER2]
+¡Oblígame, mamón!
+
+[LAW2_4:LAWYER2]
+¡Por aquí!
+
+[LAW2_5:LAWYER2]
+Voy a ver qué puedo averiguar. Te estaré vigilando, Tommy.
+
+[LAW2_6:LAWYER2]
+~g~Ve al club Malibú y busca a Kent Paul.
+
+[LAW2_7:LAWYER2]
+~g~Ve y busca al chef en Ocean Drive.
+
+[LAW2_10:LAWYER2]
+~g~Regresa al hotel.
+
+[LAW2_11:LAWYER2]
+~g~Recoge su teléfono móvil.
+
+[LAW2_12:LAWYER2]
+¡Adquirido un teléfono móvil! Ahora puedes recibir llamadas telefónicas.
+
+[LAW2_13:LAWYER2]
+~g~¡Has dejado a Lance atrás! ¡Ve y tráele!
+
+[LAW2_14:LAWYER2]
+¡Tenemos que salir pitando de aquí!
+
+[GUN_2A:LAWYER2]
+¡Mantén ~h~~k~~PED_LOCK_TARGET~ ~w~para ~h~apuntar automáticamente~w~ y pulsa ~h~~k~~PED_FIREWEAPON~ ~w~para ~h~disparar!
+
+[GUN_2C:LAWYER2]
+¡Mantén ~h~~k~~PED_LOCK_TARGET~ ~w~para ~h~apuntar automáticamente~w~ y pulsa ~h~~k~~PED_FIREWEAPON~ ~w~para ~h~disparar!
+
+[GUN_2D:LAWYER2]
+¡Mantén ~h~~k~~PED_LOCK_TARGET~ ~w~para ~h~apuntar automáticamente~w~ y pulsa ~h~~k~~PED_FIREWEAPON~ ~w~para ~h~disparar!
+
+[HELP17:LAWYER2]
+Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para atacar al chef.
+
+[HELP18:LAWYER2]
+Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para atacar al chef.
+
+[LAW3_11:LAWYER2]
+Sitúate en el ~q~marcador rosa~w~ para ver las armas disponibles.
+
+[LAW3_12:LAWYER2]
+Puedes seleccionar armas pulsando ~h~izquierda~w~ o ~h~derecha~w~ en los ~h~botones de dirección~w~.
+
+[LAW3_13:LAWYER2]
+Si dispones de suficiente dinero, puedes comprar armas pulsando ~h~~k~~PED_SPRINT~~w~.
+
+[LAW3_14:LAWYER2]
+Puedes salir de la tienda pulsando ~h~~k~~VEHICLE_ENTER_EXIT~~w~.
+
+[LAW3_15:LAWYER2]
+Ve al ~h~icono de la pistola~w~ que hay en el radar para encontrar el ~h~Ammu-Nation~w~.
+
+[LAW2_15:LAWYER2]
+~g~Ve a Ammu-Nation.
+
+[LAW2_K:LAWYER2]
+Tómatelo con calma.
+
+[LAW2_16:LAWYER2]
+Tienes que entender una cosa sobre esta ciudad. Tienes que saber protegerte.
+
+[LAW2_17:LAWYER2]
+Venga, la tienda de armas local está a un par de manzanas de aquí.
+
+[LAW2_18:LAWYER2]
+Tommy, cada hombre necesita un poco de rock de vez en cuando.
+
+[LAW2_19:LAWYER2]
+Este de aquí es el club de striptease Pole Position. Quizás quieras entrar alguna vez.
+
+{=================================== MISSION TABLE LAWYER3 ===================================}
+
+[LAW3_A:LAWYER3]
+¡Aagh! ¡Oh, por el amor de Dios, eres tú! Oh, Jesús, ¡voy a necesitar pantalones nuevos!
+
+[LAW3_B:LAWYER3]
+Eh, esos psicópatas del norte han estado entrometiéndose y pronto vendrán aquí.
+
+[LAW3_C:LAWYER3]
+Bien, ¿dónde está el maldito dinero?
+
+[LAW3_D:LAWYER3]
+Relájate, relájate. Aún no hemos llegado a esa parte.
+
+[LAW3_E:LAWYER3]
+Pensé que te estabas ocupando de esto, de verdad que sí.
+
+[LAW3_F:LAWYER3]
+Y ahora esos tipos dicen que les tenemos que hacer un favor.
+
+[LAW3_G:LAWYER3]
+Quieres decir que yo tengo que hacerles un favor.
+
+[LAW3_H:LAWYER3]
+Oh, por supuesto, eso es lo que quiero decir. ¿Doy yo la impresión de poder intimidar a un jurado?
+
+[LAW3_I:LAWYER3]
+No podría intimidar a un niño y créeme, lo he intentado.
+
+[LAW3_J:LAWYER3]
+Ahora mira, es eso, o al primo de Forelli, Giorgio, le caerán cinco años por fraude.
+
+[LAW3_K:LAWYER3]
+¡Tienes que encargarte de esos tipos!
+
+[LAW3_L:LAWYER3]
+Comprendo. Ayuda al jurado a que cambie de idea. No te preocupes por ello.
+
+[LAW3_M:LAWYER3]
+¡No no no no... NO! Ya intenté eso. El caso del jurado no fue tan bien,
+
+[LAW3_N:LAWYER3]
+así que HAZ que cambien de idea.
+
+[LAW3_1:LAWYER3]
+Giorgio envía sus saludos.
+
+[LAW3_2:LAWYER3]
+Recuerda, ''culpable'' es una palabra fea.
+
+[LAW3_3:LAWYER3]
+Inocente hasta que yo diga lo contrario.
+
+[LAW3_4:LAWYER3]
+Sabes que no es culpable.
+
+[LAW3_5:LAWYER3]
+¿Recuerdas a Giorgio? Recuerda que es inocente.
+
+[LAW3_6:LAWYER3]
+No culpable. ¿Comprendido? Bien.
+
+[LAW3_8:LAWYER3]
+~r~¡Mataste a un miembro del jurado!
+
+[LAW3_9:LAWYER3]
+~g~¡Destroza el coche del miembro del jurado para sacarle de ahí!
+
+[HELP40:LAWYER3]
+Puedes destrozar coches usando el martillo o un arma similar.
+
+[HELP41:LAWYER3]
+o puedes aplastarlas con un vehículo
+
+[LAW3_20:LAWYER3]
+~g~¡Destroza el coche del miembro del jurado!
+
+[LAW3_21:LAWYER3]
+¡No puedo creer lo que está pasando!
+
+[LAW3_22:LAWYER3]
+¡Increíble!
+
+[LAW3_23:LAWYER3]
+¡Ya! ¡Ya! ¡Entendido!
+
+[LAW3_24:LAWYER3]
+~g~Ese martillo será útil.
+
+[LAW3_7:LAWYER3]
+~g~¡Ve y coacciona a los dos miembros del jurado pero NO los mates!
+
+[HELP23:LAWYER3]
+Puedes ir al ~h~icono del martillo~w~ que hay en el radar si quieres comprar armas blancas en la ferretería.
+
+[LAW3_16:LAWYER3]
+Estúpido cretino de Florida.
+
+[LAW3_17:LAWYER3]
+¡Quítate de en medio!
+
+{=================================== MISSION TABLE LAWYER4 ===================================}
+
+[LAW4_A:LAWYER4]
+Avery, ni que decir tiene... ¡Tommy! ¡Tommy! ¿Algún progreso? No, no, no... cuéntamelo luego, cuéntamelo luego.
+
+[LAW4_B:LAWYER4]
+Tommy, éste es Avery Carrington... ¿Creo que os conocisteis en la fiesta?
+
+[LAW4_C:LAWYER4]
+No en persona.
+
+[LAW4_D:LAWYER4]
+¿Qué tal?
+
+[LAW4_E:LAWYER4]
+Avery tiene una proposición.
+
+[LAW4_F:LAWYER4]
+¿No tenemos otras cosas en mente?
+
+[LAW4_G:LAWYER4]
+Estoy intentando mantener todo bajo control así que, ¿podrías darme un respiro?
+
+[LAW4_H:LAWYER4]
+Estoy tenso como un alambre e incluso si estoy muerto al final de la semana, me gustaría pensar que no moriré pobre.
+
+[LAW4_I:LAWYER4]
+Bien, calmaos, los dos.
+
+[LAW4_J:LAWYER4]
+Hijo, si me ayudas, me encargaré de que cualquier capullo que te esté molestando se eche una buena siesta.
+
+[LAW4_K:LAWYER4]
+De acuerdo, ¿qué puedo hacer por ti?
+
+[LAW4_L:LAWYER4]
+Esta compañía de reparto tiene el almacén en unos terrenos de primera. No venderán.
+
+[LAW4_M:LAWYER4]
+Están aguantando como una vieja rata de la pradera, así que tenemos que ir allí y ahumar a esas alimañas para hacerlas salir.
+
+[LAW4_N:LAWYER4]
+Ve allí y alborota el avispero.
+
+[LAW4_O:LAWYER4]
+Los de seguridad tendrán las manos ocupadas y entonces podrás colarte y dejarles fuera de combate.
+
+[LAW4_P:LAWYER4]
+Y podrías pasarte por Rafael para cambiarte de ropa. Podrías estar allí un rato, pero sí, ve.
+
+[LAW4_Q:LAWYER4]
+Debería ser un motín.
+
+[LAW4_R:LAWYER4]
+Si las cosas salen como deberían, pásate alguna vez por mi oficina...
+
+[LAW4_1:LAWYER4]
+Por favor, dispérsense. ¡La dirección discutirá cualquier queja de la forma apropiada!
+
+[LAW4_2:LAWYER4]
+Por favor, dispérsense. ¡Vuelvan a sus casas!
+
+[LAW4_3:LAWYER4]
+¡Por favor, dispérsense! ¡Esto no es apropiado!
+
+[LAW4_4:LAWYER4]
+Por favor, dispérsense. Todos acabaréis en la calle.
+
+[LAW4_5:LAWYER4]
+¡Desenfundad, chicos! ¡Vamos a romper unos cuantos cráneos comunistas!
+
+[LAW4_13:LAWYER4]
+~g~Empieza a luchar con al menos 4 trabajadores para iniciar una revuelta.
+
+[LAW4_14:LAWYER4]
+~g~¡Destruye las furgonetas del complejo!
+
+[HELP38:LAWYER4]
+Si matas a alguien que lleva un arma, la dejará caer.
+
+[HELP39:LAWYER4]
+Puedes disparar a los barriles explosivos, pero mantén la distancia.
+
+{=================================== MISSION TABLE MIAMI_1 ===================================}
+
+[T4X4_1A:MIAMI_1]
+~g~Tienes ~1~ segundos para pasar por ~y~24~g~ puntos de control. ~g~Puedes atravesarlos en ~y~CUALQUIER ORDEN.
+
+[T4X4_1B:MIAMI_1]
+~y~ATRAVIESA~g~ el primer punto de control para poner en marcha el ~r~CRONÓMETRO.
+
+[T4X4_1C:MIAMI_1]
+¡~1~ de 24!
+
+[GETBIK1:MIAMI_1]
+¡Tienes ~1~ segundos para subirte en una PCJ 600!
+
+[GETBIK3:MIAMI_1]
+~r~Necesitas una PCJ 600 para realizar esta misión!
+
+{=================================== MISSION TABLE MM ===================================}
+
+[BLOD_04:MM]
+ESTADO DEL COCHE:
+
+[BLOD_05:MM]
+~g~TIEMPO OBJETIVO: ~1~ Minuto
+
+[BLOD_06:MM]
+~g~TIEMPO OBJETIVO: ~1~ Minutos
+
+[BLOD_07:MM]
+NUEVO Mejor Tiempo: ~1~ Segundos
+
+[BLOD_08:MM]
+Coches destrozados: ~1~
+
+[BLOD_09:MM]
+~1~ $
+
+[BLOD_10:MM]
+¡GANADOR!
+
+[BLOD_01:MM]
+Pasa por todos los puntos de control para aumentar tu tiempo total.
+
+[BLOD_02:MM]
+Fracasarás si tu tiempo total llega a cero.
+
+[BLOD_03:MM]
+¡Consigue que tu tiempo total sean superior al objetivo a superar!
+
+{=================================== MISSION TABLE OVALRIG ===================================}
+
+[HOTR_01:OVALRIG]
+~g~La carrera dura 12 vueltas. Solamente los puestos 1, 2 y 3 obtienen premios en metálico.
+
+[HOTR_02:OVALRIG]
+~g~Si destrozas tu coche serás descalificado.
+
+[HOTR_03:OVALRIG]
+~g~Cuando tu coche sufra daños podrás repararlo en boxes.
+
+[HOTR_04:OVALRIG]
+~g~Este es el camino para salir del estadio.
+
+[HOTR_05:OVALRIG]
+Estado del coche:
+
+[HOTR_06:OVALRIG]
+Vueltas:
+
+[HOTR_07:OVALRIG]
+Nuevo mejor tiempo: ~1~:0~1~
+
+[HOTR_08:OVALRIG]
+Tiempo: ~1~:~1~
+
+[HOTR_10:OVALRIG]
+Tiempo de carrera:
+
+[HOTR_09:OVALRIG]
+Posición:
+
+[HOTR_12:OVALRIG]
+~r~¡Tu coche está destrozado!
+
+[HOTR_13:OVALRIG]
+~r~¡No ganaste la carrera!
+
+[HOTR_14:OVALRIG]
+~r~¡Has sido descalificado!
+
+[HOTR_15:OVALRIG]
+Tiempo: ~1~:~1~
+
+[HOTR_16:OVALRIG]
+Tiempo: ~1~:0~1~
+
+[HOTR_17:OVALRIG]
+Mejor Tiempo: ~1~:~1~
+
+[HOTR_18:OVALRIG]
+Mejor Tiempo: ~1~:0~1~
+
+[HOTR_19:OVALRIG]
+Mejor Tiempo: NA
+
+[HOTR_20:OVALRIG]
+Nuevo Mejor Tiempo: ~1~:~1~
+
+[HOTR_21:OVALRIG]
+Nuevo Mejor Tiempo: ~1~:0~1~
+
+[HOTR_22:OVALRIG]
+Mejor Resultado: NA
+
+[HOTR_23:OVALRIG]
+Mejor resultado: 1
+
+[HOTR_24:OVALRIG]
+Mejor resultado: 2
+
+[HOTR_25:OVALRIG]
+Mejor resultado: 3
+
+[HOTR_26:OVALRIG]
+Mejor resultado: ~1~
+
+[HOTR_27:OVALRIG]
+Mejor Tiempo de Vuelta: ~1~.~1~ segundos
+
+[HOTR_28:OVALRIG]
+Mejor Tiempo de Vuelta: ~1~.0~1~ segundos
+
+[HOTR_29:OVALRIG]
+~1~ $
+
+[HOTR_30:OVALRIG]
+PUESTO: 1
+
+[HOTR_31:OVALRIG]
+PUESTO: 2
+
+[HOTR_32:OVALRIG]
+PUESTO: 3
+
+[HOTR_33:OVALRIG]
+Mejor tiempo de vuelta: ninguno
+
+[HOTR_11:OVALRIG]
+Nuevo mejor tiempo de vuelta: ~1~,~1~ segundos
+
+[HOTR_34:OVALRIG]
+Nuevo mejor tiempo de vuelta: ~1~,0~1~ segundos
+
+{=================================== MISSION TABLE PHIL1 ===================================}
+
+[PHIL1_A:PHIL1]
+¿Phil?
+
+[PHIL1_B:PHIL1]
+¡CORRE!
+
+[PHIL1_C:PHIL1]
+¡Corre!
+
+[PHIL1_E:PHIL1]
+Mierda Phil, ¿te bebes ese mejunje?
+
+[PHIL1_F:PHIL1]
+Diablos, no tienes que bebértelo...
+
+[PHIL1_G:PHIL1]
+solo tienes que olerlo para colocarte.
+
+[PHIL1_H:PHIL1]
+Escucha, Phil, dijiste que podrías proporcionarme algo de potencia de fuego...
+
+[PHIL1_I:PHIL1]
+Por supuesto.
+
+[PHIL1_J:PHIL1]
+Hay un traficante de armas mejicano que me ha estado pisando el negocio últimamente.
+
+[PHIL1_K:PHIL1]
+Suele realizar su ronda semanal a esta hora.
+
+[PHIL1_L:PHIL1]
+Haz caer la mercancía de la parte de atrás de sus camiones antes de que acabe fuera de nuestro alcance.
+
+[PHIL1_M:PHIL1]
+Y mientras estás en ello me estarás haciendo un favor.
+
+[PHIL1_N:PHIL1]
+Luego acaba con él.
+
+[PHI1_01:PHIL1]
+~g~Ve y pilla las armas de la parte trasera de los camiones del traficante.
+
+[PHI1_02:PHIL1]
+~g~El traficante de armas ha perdido la carga. Destroza la caja y recoge el arma.
+
+[PHI1_03:PHIL1]
+~g~Parece que han llamado pidiendo refuerzos.
+
+[PHI1_04:PHIL1]
+~g~Ahora ve y acaba con el resto de los traficantes.
+
+[PHI1_HP:PHIL1]
+Cuando utilices Detonador de Granadas, lanza una granada y después provoca la explosión en cualquier momento.
+
+[PHIL1_O:PHIL1]
+¡Jooooodeeeeer!
+
+[PHIL1_D:PHIL1]
+¡Nunca acerques una llama a uno de los alambiques de boomshine de Phil Cassidy!
+
+{=================================== MISSION TABLE PHIL2 ===================================}
+
+[PHIL2_A:PHIL2]
+Hola, Phil, ¿cómo te va?
+
+[PHIL2_B:PHIL2]
+Ehhh, Tommy. ¿Cómo estás? Hace tanto tiempo...
+
+[PHIL2_C:PHIL2]
+Te juro que deberías dejar ese mejunje, tío.
+
+[PHIL2_D:PHIL2]
+Huele como decapante de pintura. Hace que me ardan los ojos...
+
+[PHIL2_E:PHIL2]
+Shhh, shhh, tú mismo, Tommy,
+
+[PHIL2_F:PHIL2]
+y ven aquí porque hay algo que quiero enseñarte... algo.
+
+[PHIL2_G:PHIL2]
+¡Dios! ¿Debería poder oler eso desde aquí? Me estoy mareando.
+
+[PHIL2_H:PHIL2]
+No te preocupes por el olor, Tommy, mira esto.
+
+[PHIL2_I:PHIL2]
+Las malditas pilas baratas o algo así. Hay más en el banco.
+
+[PHIL2_J:PHIL2]
+¡TA-DAAA!
+
+[PHIL2_K:PHIL2]
+¡Maldición!
+
+[PHI2_01:PHIL2]
+~g~Rápido, lleva a Phil al hospital.
+
+[PHI2_03:PHIL2]
+~r~¡Phil Cassidy está muerto! ¿Ahora quién va a suministrar armas en Vice City?
+
+[PHI2_05:PHIL2]
+¡Al hospital no, tío! ¡Demasiados polis y vietcongs!
+
+[PHI2_06:PHIL2]
+Hay un excirujano del ejército que me debe unos cuantos favores... y un cortador de césped.
+
+[PHI2_07:PHIL2]
+Tiene un lugar llamado Little Havana, oh mira, un pez gigante.
+
+[PHI2_08:PHIL2]
+¡Cuidado! ¡Charlies en la línea de los árboles!
+
+[PHI2_09:PHIL2]
+¿Soy yo o las carreteras están hechas de gelatina?
+
+[PHI2_10:PHIL2]
+Cuchara rota a madre gallina, ¿me recibes?
+
+[PHI2_11:PHIL2]
+¡Cucharita, rita, rit, rit!
+
+[PHI2_12:PHIL2]
+¡Viene a por mí, chico!
+
+[PHI2_13:PHIL2]
+Hay alas de plumas negras aleteando por todas partes...
+
+[PHI2_14:PHIL2]
+Es hermoso, tío... es hermoso... pero hace tanto frío...
+
+[PHI2_15:PHIL2]
+10-4 tenemos un conductor borracho.
+
+[PHI2_04:PHIL2]
+SALUD DE PHIL:
+
+[PHI_AS1:PHIL2]
+LOCAL DE PHIL CONSOLIDADO
+
+[PHI_AS2:PHIL2]
+~g~Nuevas armas disponibles para comprar en el Local de Phil.
+
+{=================================== MISSION TABLE PIZZA ===================================}
+
+[PIZ1_01:PIZZA]
+~g~Ve a entregar estas pizzas, debes lanzar la pizza a los clientes. Pasa cerca para lanzar las pizzas.
+
+[PIZ1_02:PIZZA]
+~g~Has lanzado todas tus pizzas, vuelve y recoge algunas más.
+
+[PIZ1_05:PIZZA]
+~g~Tienes cinco minutos para entregar los pedidos antes de que los clientes telefoneen a otra pizzería.
+
+[PIZ1_07:PIZZA]
+~r~¡Mataste al cliente! Estás despedido.
+
+[PIZ1_08:PIZZA]
+~r~Te has quedado sin tiempo. Estás despedido.
+
+[PIZ1_09:PIZZA]
+~r~¡Destruiste nuestra moto! Estás despedido.
+
+[PIZ1_11:PIZZA]
+¡Eh! ¡Vuelve a subir a la moto!
+
+[PIZ1_12:PIZZA]
+Pizzas restantes:
+
+[PIZ1_06:PIZZA]
+Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ cuando estés en la moto para cancelar la misión.
+
+[PIZ1_13:PIZZA]
+Reparte éstas bien calentitas.
+
+[PIZ1_14:PIZZA]
+Amigo, te toca repartir éstas.
+
+[PIZ1_15:PIZZA]
+A ver, tío, repártelas rápido.
+
+[PIZ1_16:PIZZA]
+¿Qué estás esperando, tío? Tienes pizzas que repartir.
+
+[PIZ1_17:PIZZA]
+Ya sé que no querías ser el chico de las pizzas, vale me importa un cuerno.
+
+[PIZ1_18:PIZZA]
+Reparte éstas.
+
+[PIZ1_19:PIZZA]
+Hay que repartir éstas.
+
+[PIZ1_20:PIZZA]
+Venga hombre, reparte estas cosas o estás despedido.
+
+[PIZ1_21:PIZZA]
+Tenemos gente esperando amigo.
+
+[PIZ1_22:PIZZA]
+¿Qué estás esperando? ¡Hay que repartir esto!
+
+[PIZ1_23:PIZZA]
+Haz el reparto de la maldita comida hombre.
+
+[PIZ1_24:PIZZA]
+Hay que repartir éstas, amigo.
+
+[PIZ1_25:PIZZA]
+Tío, ¿te puedes llevar éstas?
+
+[PIZ1_26:PIZZA]
+Oye, haz el reparto pronto, vamos amigo.
+
+[PIZ1_27:PIZZA]
+Venga, tenemos prisa, haz ya el reparto.
+
+[PIZ1_28:PIZZA]
+¿Otra vez tú? Bueno, reparte éstas deprisa, amigo.
+
+[PIZ1_29:PIZZA]
+No pierdas el tiempo amigo.
+
+[PIZ1_30:PIZZA]
+Venga ya vago hijo de puta, reparte esta mierda de una vez.
+
+[PIZ1_31:PIZZA]
+No tendrás nunca un ascenso a menos que te muevas más rápido esta vez.
+
+[PIZ1_32:PIZZA]
+~r~¿La pizza es demasiado caliente para encargarte de ella?
+
+[PIZ1_33:PIZZA]
+~g~Vuelve al restaurante a por más pedidos.
+
+[PIZ1_34:PIZZA]
+~g~Pizza repartida, aquí está tu dinero.
+
+[PIZ_WON:PIZZA]
+Misión de Pizza Completada. Tu salud Personal máxima ha aumentado a 150.
+
+{=================================== MISSION TABLE PORN1 ===================================}
+
+[POR1_A:PORN1]
+Acción.
+
+[POR1_B:PORN1]
+¡Guau! Eso sí que es grande.
+
+[POR1_C:PORN1]
+30 cm, eso es para pensárselo, nene.
+
+[POR1_D:PORN1]
+¡CORTEN! ¿Quién es este idiota? ¡Tú! ¡Tú! ¿Por qué estás en el set? ¿POR QUÉ?
+
+[POR1_E:PORN1]
+¿De qué va toda esta basura?
+
+[POR1_F:PORN1]
+¿Alienígenas? ¿Cañas de pescar?
+
+[POR1_G:PORN1]
+¿Quién ha visto alguna vez a un tiburón tan grande?
+
+[POR1_H:PORN1]
+Hay que desechar todo este material.
+
+[POR1_I:PORN1]
+¿Por qué te metiste en este negocio, mamón?
+
+[POR1_J:PORN1]
+¿Eh?
+
+[POR1_K:PORN1]
+¡Por los chochos, evidentemente! ¿Qué es esto?
+
+[POR1_L:PORN1]
+Éste es mi arte. ¡SEGURIDAD!
+
+[POR1_M:PORN1]
+Mira, pomposo gilipollas, ahora eres de mi propiedad. Yo poseo todo esto.
+
+[POR1_N:PORN1]
+Vamos a cambiar este lugar...
+
+[POR1_O:PORN1]
+Voy a hacerte rico.
+
+[POR1_P:PORN1]
+Usted es... Usted... ¿Usted es Tommy Vercetti? Pero yo creí que usted era...
+
+[POR1_Q:PORN1]
+Eso es.
+
+[POR1_R:PORN1]
+Vamos a hacer algunos cambios por aquí y vamos a empezar a hacer dinero de verdad.
+
+[POR1_S:PORN1]
+En realidad, alguna vez has pensado en...
+
+[POR1_T:PORN1]
+Pero primero, vamos a necesitar unas chicas guapas de verdad...
+
+[POR1_U:PORN1]
+Sí, las chicas están bien, pero tú... ¡guau!
+
+[POR1_02:PORN1]
+~g~ Ve y elimina al chulo de Candy, luego vuelve y recoge a Candy.
+
+[POR1_04:PORN1]
+Candy. Estoy buscando una estrella de cine. ¿Estás interesada?
+
+[POR1_05:PORN1]
+¡Claro! Pero tendrás que hablar con mi agente...
+
+[POR1_06:PORN1]
+¿Qué DEMONIOS estás haciendo?
+
+[POR1_07:PORN1]
+¡Hoy deberías haberte quedado en casa!
+
+[POR1_7B:PORN1]
+¿Puedes creer a este gilipollas?
+
+[POR1_08:PORN1]
+¡Eh, Mercedes!
+
+[POR1_09:PORN1]
+¡Eh, Tommy! ¿Quieres ir de fiesta?
+
+[POR1_10:PORN1]
+Ahora no, preciosa. ¿Te interesa hacer algunas películas?
+
+[POR1_11:PORN1]
+Por supuesto. Mientras que sea una peli barata y cutre.
+
+[POR1_13:PORN1]
+~g~Lleva a las chicas de vuelta al Estudio para que conozcan a Steve.
+
+[POR1_14:PORN1]
+¡Contratada!
+
+[POR1_15:PORN1]
+Eh Tommy, ¿¡qué, vienes a entrar en calor!?
+
+[POR1_17:PORN1]
+¡Guau, un tiburón genial!
+
+[POR1_18:PORN1]
+~r~¡Mercedes está muerta!
+
+[POR1_20:PORN1]
+Tommy, ¿a dónde vas? ¡Vuelve aquí!
+
+[POR1_21:PORN1]
+¿A dónde vas?
+
+[POR1_22:PORN1]
+Tommy, ¿cuando vamos a pasar algún tiempo a solas?
+
+[POR1_01:PORN1]
+~g~¡Candy Suxxx sería perfecta para el papel principal!
+
+[POR1_12:PORN1]
+~g~Ve con Candy a encontrarte con Mercedes.
+
+[POR1_16:PORN1]
+Quizás después, nena...
+
+[POR1_24:PORN1]
+~g~Vuelve y recoge a Candy.
+
+[POR1_25:PORN1]
+~g~Te has dejado atrás a Candy, ve y tráela.
+
+[POR1_23:PORN1]
+~g~Candy estará ocupándose de unos asuntos en el ~h~centro de la ciudad~g~.
+
+[POR1_26:PORN1]
+~g~Aquí está Candy, parece que ha estado otra vez con el congresista Shrub.
+
+[POR1_27:PORN1]
+Venga, vamos.
+
+[POR1_28:PORN1]
+¡Tommy ten cuidado! ¡Aún no he asegurado mis implantes!
+
+[POR1_29:PORN1]
+¿Y a esto le llamas conducir?
+
+[POR1_30:PORN1]
+¡No podré hacer ningún numerito porno después de esto!
+
+[POR1_31:PORN1]
+¿Qué? ¿Me estás intentando matar? ¡Creía que era la estrella era yo!
+
+{=================================== MISSION TABLE PORN2 ===================================}
+
+[POR2_A:PORN2]
+¿Cómo va el rodaje, Steve?
+
+[POR2_B:PORN2]
+Bien, Candy es una fuera de serie y esa chica nueva ¡es insaciable!
+
+[POR2_C:PORN2]
+Se repasó a la mitad del reparto antes de que pudiese medir la luz.
+
+[POR2_D:PORN2]
+De todas formas, eh, mañana vamos a exteriores a rodar las escenas del barco...
+
+[POR2_E:PORN2]
+¿Escenas del barco, qué escenas del barco?
+
+[POR2_F:PORN2]
+Los pescadores son presa de la pasión cuando aparece el tiburón gigante...
+
+[POR2_G:PORN2]
+¿Qué te dije del tiburón gigante?
+
+[POR2_H:PORN2]
+Dije, ''SIN TIBURÓN GIGANTE'', ¿de acuerdo?
+
+[POR2_I:PORN2]
+¡Tú solo tienes que mantener las cámaras apuntando a los conejos!
+
+[POR2_J:PORN2]
+De acuerdo, de acuerdo, eh Tommy, uno tiene que intentarlo, ¿de acuerdo?
+
+[POR2_K:PORN2]
+¿Has hecho que impriman esos folletos?
+
+[POR2_L:PORN2]
+Sí, pero nadie va a distribuir esas cosas, quiero decir que...
+
+[POR2_M:PORN2]
+son demasiado... poco imaginativos.
+
+[POR2_N:PORN2]
+No te preocupes por eso.
+
+[POR2_O:PORN2]
+Tengo mis propias ideas para la distribución.
+
+[POR2_P:PORN2]
+Vale. Candy, ven a mi caravana.
+
+[POR2_01:PORN2]
+~g~Hay un hidroavión que se utilizó como atrezzo en una antigua película independiente a la vuelta de los estudios.
+
+[POR2_02:PORN2]
+~g~Escoge uno de los puntos de control para empezar a dejar caer los folletos.
+
+[POR2_03:PORN2]
+~g~Deja caer los folletos por todo el camino hasta el último punto de control.
+
+[POR2_04:PORN2]
+~r~¡COMBUSTIBLE BAJO!
+
+[POR2_05:PORN2]
+Utilízalo para distribuir los folletos por toda la ciudad.
+
+[DILDO:PORN2]
+Combustible del Skimmer:
+
+[POR2_Q:PORN2]
+¡Jo!, tío.
+
+[PORN2_9:PORN2]
+~g~Tienes ~1~ segundos para volver a subir a una Skimmer antes de que termine la misión.
+
+{=================================== MISSION TABLE PORN3 ===================================}
+
+[POR3_A:PORN3]
+Vale, ¿cuál es el problema ahora?
+
+[POR3_B:PORN3]
+¡SSShhhh!
+
+[POR3_C:PORN3]
+Bien, después de este encuentro cercano con las invasoras ninfómanas
+
+[POR3_D:PORN3]
+nuestro héroe se encuentra incapaz de pensar en nada excepto en esta enorme montaña fálica...
+
+[POR3_E:PORN3]
+y es entonces cuando queremos hacer la escena con la tina de puré de patatas, pero entonces...
+
+[POR3_F:PORN3]
+¡Me importa una mierda!
+
+[POR3_G:PORN3]
+¡Sigue, sigue!
+
+[POR3_H:PORN3]
+Eh Tommy...
+
+[POR3_I:PORN3]
+¿Mencionaste algo sobre un problema legal al teléfono?
+
+[POR3_J:PORN3]
+¡Vaya que sí! El congresista Alex Shrub se ha subido al tren preelectoral y va tras el voto puritano.
+
+[POR3_K:PORN3]
+Hay rumores de que va a apoyar medidas restrictivas, digamos,
+
+[POR3_L:PORN3]
+para el aspecto más lujurioso de la gran industria del entretenimiento de esta nación.
+
+[POR3_M:PORN3]
+Genial.
+
+[POR3_N:PORN3]
+¡Candy! Tú conoces a Shrub,
+
+[POR3_O:PORN3]
+¿llegasteis a algo pervertido?
+
+[POR3_P:PORN3]
+¡Oh sí, oh sí, oh sí! ¡Sí sí sí SÍ! ¡OOOoooh!
+
+[POR3_Q:PORN3]
+Por favor dime que filmaste eso.
+
+[POR3_R:PORN3]
+¿Eso era parte del eh... o estaba hablando conmigo...?
+
+[POR3_S:PORN3]
+Eh, uno nunca podría decirlo... De todas formas...
+
+[POR3_T:PORN3]
+Probablemente sea mejor que la sigas después del rodaje,
+
+[POR3_U:PORN3]
+para ver si te lleva a su nuevo nido de amor.
+
+[POR3_V:PORN3]
+¿Tienes una cámara?
+
+[POR3_X:PORN3]
+Vale, conseguidle una cámara.
+
+[POR3_02:PORN3]
+~r~¡Has asesinado al Congresista! Ahora no habrá modo de que puedas chantajearle.
+
+[POR3_03:PORN3]
+~r~Has alertado a la protección del Congresista, le sacarán de aquí inmediatamente.
+
+[POR3_04:PORN3]
+Candy, ¿podrías llamarme Marta?
+
+[POR3_05:PORN3]
+Oh Alex, quiero decir Marta. Lo que tú digas.
+
+[POR3_06:PORN3]
+Marta, alguien está mirando... qué pervertido.
+
+[POR3_07:PORN3]
+Tú, el de ahí. Dame esa cámara.
+
+[POR3_01:PORN3]
+~g~Sigue la ~h~limusina~g~ de Candy.
+
+[POR3_15:PORN3]
+~r~¡Has destruido la limusina de Candy!
+
+[POR3_17:PORN3]
+~g~Regresa a la compañía de pornografía con las fotos.
+
+[POR3_19:PORN3]
+~r~¡Te has quedado sin película!
+
+[POR3_21:PORN3]
+~g~¡Has perdido la limusina de Candy!
+
+[POR3_22:PORN3]
+~g~El Hotel WK Chariot frente a este balcón debería proporcionar el lugar ideal para la sesión fotográfica.
+
+[POR3_23:PORN3]
+~g~Hay una puerta lateral que te permitirá acceder al hotel.
+
+[POR3_08:PORN3]
+Mantén pulsado ~h~~k~~PED_LOCK_TARGET~ ~w~para~h~ enfocar~w~ con la cámara.
+
+[POR3_09:PORN3]
+Mantén pulsado ~h~~k~~PED_LOCK_TARGET~ ~w~para~h~ enfocar~w~ con la cámara.
+
+[POR3_10:PORN3]
+Pulsa ~h~~k~~PED_SNIPER_ZOOM_IN~ ~w~para ~h~acercar el zoom ~w~con la cámara y ~h~~k~~PED_SNIPER_ZOOM_OUT~ ~w~para ~h~alejarlo ~w~de nuevo.
+
+[POR3_11:PORN3]
+Pulsa ~h~~k~~PED_SNIPER_ZOOM_IN~ ~w~para ~h~acercar el zoom ~w~con la cámara y ~h~~k~~PED_SNIPER_ZOOM_OUT~ ~w~para ~h~alejarlo ~w~de nuevo.
+
+[POR3_12:PORN3]
+Pulsa ~h~~k~~PED_FIREWEAPON~ ~w~para sacar una foto.
+
+[POR3_13:PORN3]
+Pulsa ~h~~k~~PED_FIREWEAPON~ ~w~para sacar una foto.
+
+[POR3_14:PORN3]
+Pulsa ~h~~k~~PED_FIREWEAPON~ ~w~para sacar una foto.
+
+[POR3_20:PORN3]
+~g~Si necesitas transporte, utiliza el ~h~Sparrow~g~ que está en la parte de atrás.
+
+[POR3_16:PORN3]
+~g~Necesitas tres buenas fotos de Alex Shrub con Candy para chantajearle.
+
+[POR3_24:PORN3]
+FOTOS HECHAS:
+
+{=================================== MISSION TABLE PORN4 ===================================}
+
+[POR4_A:PORN4]
+Lo siento, pero no puedo tragarme eso ahora.
+
+[POR4_B:PORN4]
+¡Oh, VENGA, cariño!
+
+[POR4_C:PORN4]
+La tiene como un cachalote, por el amor de Dios,
+
+[POR4_D:PORN4]
+¿cómo es que no puedes sentir el papel?
+
+[POR4_E:PORN4]
+Pero Stevie...
+
+[POR4_F:PORN4]
+¿Cómo está mi director estrella?
+
+[POR4_G:PORN4]
+Oh, tío. La lucha entre la integridad artística y
+
+[POR4_H:PORN4]
+la acción cargante y bombeante continúa sin perder intensidad.
+
+[POR4_I:PORN4]
+Y antes de que puedas preguntarlo, sí, los cuatro vídeos serán lanzados en sus...
+
+[POR4_J:PORN4]
+Cariño, podrías POR FAVOR mantener la anaconda dentro del plano,
+
+[POR4_K:PORN4]
+¡cuesta por hora más de lo que cuestas tú!
+
+[POR4_L:PORN4]
+Oh, lo siento, Steve.
+
+[POR4_M:PORN4]
+Estaba pensando, necesitamos algún tipo de gran truco publicitario para promover de verdad el lanzamiento.
+
+[POR4_N:PORN4]
+Algo que tenga un verdadero impacto en la ciudad, ¿tienes alguna idea?
+
+[POR4_O:PORN4]
+Bueno, en los viejos tiempos solían organizar fiestas,
+
+[POR4_P:PORN4]
+estrellas, limusinas, el cielo nocturno con los focos entrecruzados...
+
+[POR4_Q:PORN4]
+¿Focos? Tengo una idea...
+
+[POR4_R:PORN4]
+...sí, sí, sí. Los numeritos de lentejuelas, y las limusinas, oh, premieres.
+
+[POR4_S:PORN4]
+Oh, sí, madam, por supuesto madam,
+
+[POR4_T:PORN4]
+y la prensa, y el bombardeo de luces...
+
+[POR4_01:PORN4]
+~g~Ve al ~y~centro~g~ y ajusta los focos sobre lo alto del edificio.
+
+[POR4_02:PORN4]
+~g~Necesitarás una moto rápida para saltar de un tejado a otro. El guardia de seguridad normalmente lleva una ~y~PCJ 600~g~ para ir a trabajar...
+
+[POR4_03:PORN4]
+~g~Necesitarás subir a los tejados de los edificios. Debería de haber un ascensor que lleve a una de las oficinas superiores...
+
+[POR4_06:PORN4]
+~g~Vuelve a la oficina inferior si de nuevo necesitas acceso a los tejados.
+
+[POR4_07:PORN4]
+~g~Necesitarás una moto para poder saltar de un edificio a otro.
+
+[POR4_08:PORN4]
+~g~Atraviesa la ventana para empezar el recorrido. Tienes hasta las 07:00 antes de que haya demasiada luz como para subir allí sin ser visto.
+
+[POR4_09:PORN4]
+~g~Los marcadores rosas te mostrarán a qué edificio saltar después.
+
+[POR4_10:PORN4]
+~r~Hay demasiada luz como para subir ahí sin ser visto.
+
+[POR4_11:PORN4]
+~g~Vuelve a la escalera si necesitas acceder de nuevo a los tejados.
+
+[POR4_05:PORN4]
+~g~Estas escaleras llevan a una oficina en el piso inferior.
+
+[POR_AS1:PORN4]
+ESTUDIO CINEMATOGRÁFICO CONSOLIDADO
+
+[POR_AS2:PORN4]
+~g~Inter Global Films generará ahora unos ingresos máximos de hasta ~1~ $. Asegúrate que lo recaudas de forma regular.
+
+{=================================== MISSION TABLE PROT1 ===================================}
+
+[PRO1_B:PROT1]
+No puedo soportar este look. Tommy, ¿Tú que dices? ¿Qué te parece si ponemos un bar en...
+
+[PRO1_D:PROT1]
+Escúchame,
+
+[PRO1_E:PROT1]
+Es hora de tomar esta ciudad. Está ahí, esperándonos.
+
+[PRO1_F:PROT1]
+Necesitamos empezar a ampliar nuestro territorio,
+
+[PRO1_G:PROT1]
+vamos a dejar que Vice City sepa que somos los nuevos tíos importantes de la ciudad, ¿sabes a lo que me refiero?
+
+[PRO1_I:PROT1]
+Lo que necesitas es un frente legítimo, Tommy, una verdadera propiedad. A mí nunca me ha hecho daño.
+
+[PRO1_J:PROT1]
+Necesitamos empezar a utilizar la fuerza o podemos despedirnos de todo el trabajo duro que hemos hecho.
+
+[PRO1_K:PROT1]
+¡Los negociantes locales saben que Díaz está muerto, y se niegan a pagar la protección!
+
+[PRO1_L:PROT1]
+Oh. Podríamos intentar el soborno...
+
+[PRO1_M:PROT1]
+¿Soborno? ¡Que le jodan al soborno! Te mostraré cómo hacer que se asusten.
+
+[PRO1_01:PROT1]
+~g~Ve a atracar los escaparates de las tiendas y tendrás a los propietarios suplicando protección.
+
+[PRO1_03:PROT1]
+~r~Se suponía que deberías atacar y salir corriendo, no atacar y tomarte un café.
+
+[PRO1_04:PROT1]
+¡Mi sustento, destruido!
+
+[PRO1_05:PROT1]
+¡Arruinado... ESTOY ARRUINADO!
+
+[PRO1_06:PROT1]
+¡Pagaré lo que sea por protección!
+
+[PRO1_07:PROT1]
+¡Mi hermoso escaparate destruido!
+
+[PRO1_08:PROT1]
+Mi tienda. Mi maravillosa tienda.
+
+[PRO1_09:PROT1]
+Vercetti. Recuerda el nombre.
+
+[PRO1_10:PROT1]
+Ahora dirijo esta ciudad. ¡YO!
+
+[BUYP1:PROT1]
+Ahora puedes comprar propiedades en ciertas zonas de la ciudad.
+
+[BUYP2:PROT1]
+Si ves un indicador con una casa verde, puedes comprar esa propiedad.
+
+[PRO1_N:PROT1]
+Volveré aquí en cinco minutos...
+
+[PRO1_11:PROT1]
+~g~Ve al ~y~Centro Comercial North Point~g~ en ~y~Vice Point~g~.
+
+[PRO1_12:PROT1]
+~g~Destroza los escaparates de todas las tiendas y los propietarios te suplicarán para obtener nueva protección.
+
+[PRO1_A:PROT1]
+Oh, tenemos que volver a pintar este sitio. Tenemos que hacer que parezca más viejo.
+
+[PRO1_C:PROT1]
+Rosenberg, eres mi abogado, no mi diseñador de interiores, ¿lo entiendes?
+
+[BUYP3:PROT1]
+Sitúate en el marcador, a continuación pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar la propiedad.
+
+[PRO1_13:PROT1]
+~g~Dispones de cinco minutos para machacarlos a todos.
+
+{=================================== MISSION TABLE PROT2 ===================================}
+
+[PRO2_A:PROT2]
+¿Cuál es el problema?
+
+[PRO2_B:PROT2]
+Un bar se niega a pagar.
+
+[PRO2_C:PROT2]
+Creen que están protegidos por una banda de matones locales.
+
+[PRO2_D:PROT2]
+Pero no te preocupes, Tommy, yo me encargo.
+
+[PRO2_E:PROT2]
+¿Llamas a esto encargarte?
+
+[PRO2_F:PROT2]
+Vosotros dos, en pie...
+
+[PRO2_G:PROT2]
+Vamos.
+
+[PRO2_01:PROT2]
+~g~Elimina a los guardias que vigilan el Bar Front Page y descubre quién los ha puesto ahí.
+
+[PRO2_10:PROT2]
+~g~Dos más han huido. Sígueles la pista y acaba con ellos.
+
+[PRO2_11:PROT2]
+Sube al coche, inútil.
+
+[PRO2_02:PROT2]
+Tu seguridad necesita un poco más de seguridad.
+
+[PRO2_03:PROT2]
+¡Ahh! demonios, ¡otra vez no! ¡no necesito esta basura!
+
+[PRO2_04:PROT2]
+Estos idiotas pertenecen al DBP de Seguridad que hay a la vuelta de la esquina.
+
+[PRO2_05:PROT2]
+¡Eh tíos! Arregladlo entre vosotros.
+
+[PRO2_06:PROT2]
+Nos vemos en un rato.
+
+[PRO2_07:PROT2]
+Sí, vale, lo que tú digas.
+
+[PRO2_08:PROT2]
+~g~El DBP de Seguridad sabrá que estás de camino, ve y atrápalos antes que escapen.
+
+[PRO2_09:PROT2]
+~g~Ve y habla con el dueño del bar Front Page.
+
+{=================================== MISSION TABLE PROT3 ===================================}
+
+[PRO3_A:PROT3]
+¡Idiota! ¿En qué estabas pensando?
+
+[PRO3_B:PROT3]
+¿Te das cuenta de lo que significa ésto?
+
+[PRO3_C:PROT3]
+¡Podríamos estar todos hundidos!
+
+[PRO3_D:PROT3]
+El temporizador debe haberse jodido.
+
+[PRO3_E:PROT3]
+Ese lugar estaba preparado para estallar como una fábrica de fuegos artificiales.
+
+[PRO3_F:PROT3]
+Entonces alguien avisó a la poli...
+
+[PRO3_G:PROT3]
+¿Cuál es el problema, colegas?
+
+[PRO3_H:PROT3]
+Se suponía que Mike iba a quemar algún sitio en el centro comercial,
+
+[PRO3_I:PROT3]
+pero la cagó con los fusibles y ahora eso está plagado de polis.
+
+[PRO3_J:PROT3]
+¡Tenemos que conseguir nuestras cosas y salir de aquí!
+
+[PRO3_K:PROT3]
+¡Relajaos los dos, dejadme pensar un segundo!
+
+[PRO3_L:PROT3]
+Tommy Vercetti no corta por lo sano y huye.
+
+[PRO3_M:PROT3]
+Los polis van a repasar ese edificio con un buen cepillo de dientes, ¿verdad?
+
+[PRO3_N:PROT3]
+Pero eso lleva tiempo.
+
+[PRO3_O:PROT3]
+Tenemos que ir y quemar nosotros mismos ese sitio.
+
+[PRO3_P:PROT3]
+Sí, pero...
+
+[PRO3_Q:PROT3]
+¡Nadie excepto un poli podría acercarse a una milla de ese lugar!
+
+[PRO3_R:PROT3]
+Así que iremos como polis.
+
+[PRO3_S:PROT3]
+Tenemos que conseguir uniformes, y vamos a necesitar un coche patrulla.
+
+[PRO3_T:PROT3]
+Todo gracias a ti, Mike.
+
+[PRO3_U:PROT3]
+Lo siento.
+
+[PRO3_V:PROT3]
+Lo capto.
+
+[PRO3_W:PROT3]
+Lo que tenemos que hacer es atraer a los polis enseñándoles el dedo,
+
+[PRO3_X:PROT3]
+encerrarles
+
+[PRO3_Y:PROT3]
+y asaltarles.
+
+[PRO3_Z:PROT3]
+Buen plan. ¡Vamos!
+
+[PRO3_A1:PROT3]
+De acuerdo.
+
+[PRO3_01:PROT3]
+De acuerdo, Lance, ¡vamos a por los polis!
+
+[PRO3_02:PROT3]
+~g~ Roba el coche de policía y coloca la bomba en el Café Tarbrush del centro comercial.
+
+[PRO3_03:PROT3]
+~g~ Has dejado atrás a Lance, vuelve y recógele.
+
+[PRO3_04:PROT3]
+~g~ Vamos.
+
+[PRO3_05:PROT3]
+~r~¡Has matado a Lance!
+
+[PRO3_07:PROT3]
+~g~ Te has descubierto. ¡Date prisa y coloca la bomba!
+
+[PRO3_08:PROT3]
+~g~Vuelve a la ~h~finca de Vercetti~g~ en ~h~Starfish Island~g~.
+
+[PRO3_09:PROT3]
+¡Átales y amordázales!
+
+[PRO3_10:PROT3]
+¡Me queda como un guante!
+
+[PRO3_11:PROT3]
+Un poco ajustado en la entrepierna...
+
+[PRO3_12:PROT3]
+Oh, sí, sí, el mío también. El mío también.
+
+[PRO3_13:PROT3]
+¡Relájate, hermano! ¡Ningún poli conduce tan mal!
+
+[PRO3_14:PROT3]
+Recuerda, sonríe a los otros polis.
+
+[PRO3_15:PROT3]
+Hola, agente. Bonita placa, bonita placa.
+
+[PRO3_16:PROT3]
+Muy desenvuelto, Lance.
+
+[PRO3_17:PROT3]
+De acuerdo, los temporizadores están colocados, 5 segundos.
+
+[PRO3_18:PROT3]
+¿5 segundos? ¡Tenemos que salir de aquí pitando!
+
+[PRO3_19:PROT3]
+Ahora que los hemos enfadado de verdad.
+
+[PRO3_20:PROT3]
+~g~ Haz que dos polis te sigan hasta el garaje.
+
+[PRO3_21:PROT3]
+~g~Consigue un nivel de se busca suficiente para que los polis te sigan hasta el garaje.
+
+[PRO3_22:PROT3]
+~g~¡La puerta del garaje está bloqueada! El acceso tiene que estar despejado para que se pueda cerrar.
+
+[PRO3_23:PROT3]
+~g~Camina hacia el marcador para colocar la bomba.
+
+[PRO3_24:PROT3]
+~g~¡Aléjate del Café!
+
+[PRO_AS1:PROT3]
+ANILLO DE PROTECCIÓN COMPLETADO
+
+[PRO_AS2:PROT3]
+~g~La finca de Vercetti generará ahora unos ingresos máximos de hasta ~1~ $. Asegúrate de recaudarlo regularmente.
+
+{=================================== MISSION TABLE RACES ===================================}
+
+[RACES_2:RACES]
+~g~¡Necesitas un vehículo para correr, esto no es una carrera a pie!
+
+[RACES_3:RACES]
+3... 2... 1... ¡ADELANTE! ¡ADELANTE! ¡ADELANTE!
+
+[RACES_8:RACES]
+~r~¡No has ganado la carrera!
+
+[RACES00:RACES]
+Carrera ~1~:
+
+[RACES01:RACES]
+Velocidad terminal
+
+[RACES02:RACES]
+Ocean Drive
+
+[RACES03:RACES]
+Carrera por el borde
+
+[RACES04:RACES]
+Capital Cruise
+
+[RACES05:RACES]
+¡Tour!
+
+[RACES06:RACES]
+Aguante en V.C.
+
+[RACES07:RACES]
+Precio de entrada: ~1~ $
+
+[RACES08:RACES]
+Mejor tiempo: ~1~:~1~
+
+[RACES09:RACES]
+Mejor resultado: 1
+
+[RACES10:RACES]
+Mejor resultado: 2
+
+[RACES11:RACES]
+Mejor resultado: 3
+
+[RACES12:RACES]
+Mejor resultado: 4
+
+[RACES13:RACES]
+Longitud de pista: ~1~.~1~ km
+
+[RACES15:RACES]
+Mejor tiempo: NA
+
+[RACES16:RACES]
+Mejor resultado: NA
+
+[RACES19:RACES]
+No puedes permitirte entrar en esta carrera.
+
+[RACES22:RACES]
+Mejor tiempo: ~1~:0~1~
+
+[RACES23:RACES]
+Longitud de la pista: ~1~.~1~ millas
+
+[RACES_1:RACES]
+~g~Consigue un vehículo rápido y ve a la parrilla de salida.
+
+[RACEHLP:RACES]
+~w~Pulsa ~h~~k~~PED_SPRINT~~w~ para empezar la carrera seleccionada. Pulsa ~h~~k~~VEHICLE_ENTER_EXIT~~w~ para salir.
+
+{=================================== MISSION TABLE RCHELI1 ===================================}
+
+[WRECKED:RCHELI1]
+~r~¡El vehículo está destrozado!
+
+[RCH1_4:RCHELI1]
+Puntos de control:
+
+[RCH1_7:RCHELI1]
+~g~Hay 20 puntos de control en total.
+
+[RCH1_12:RCHELI1]
+~g~¡El helicóptero RC está saliendo fuera de su alcance de control!
+
+[RCH1_13:RCHELI1]
+~r~¡El helicóptero RC se ha salido de su radio de alcance!
+
+[RCH1_8:RCHELI1] { reVC update }
+~g~Si deseas abandonar esta misión, pulsa ~h~~k~~VEHICLE_FIREWEAPON~~g~ para detonar tu helicóptero RC.
+
+{=================================== MISSION TABLE RCPLNE1 ===================================}
+
+[RCPL1_4:RCPLNE1]
+~g~Compite en una CARRERA DE PUNTOS DE CONTROL contra otros tres aviones RC.
+
+[RCPL1_5:RCPLNE1]
+~g~Vuela a través de los puntos de control dispersados por Vice City.
+
+[RCPL1_6:RCPLNE1] { reVC update }
+~g~Si deseas abandonar esta misión, pulsa ~h~~k~~VEHICLE_FIREWEAPON~~g~ para detonar tu avión RC.
+
+[RCPL1_8:RCPLNE1]
+~g~¡Tu avión RC está saliendo fuera del alcance!
+
+[RCPL1_9:RCPLNE1]
+~r~¡Tu avión RC se salió del alcance!
+
+{=================================== MISSION TABLE RCRACE1 ===================================}
+
+[RCRC1_1:RCRACE1]
+~g~Compite en una CARRERA DE PUNTOS DE CONTROL contra 3 Barón RC durante dos vueltas.
+
+[RCRC1_3:RCRACE1]
+~g~¡Vuelta final!
+
+[RCR1_4:RCRACE1]
+vueltas restantes:
+
+[RCR1_1:RCRACE1]
+~g~Compite en una carrera de puntos de control contra otros tres coches RC.
+
+[RCR1_2:RCRACE1]
+~g~¡Consigue ser el primero en completar las dos vueltas del circuito para ganar!
+
+[RCR1_6:RCRACE1]
+~g~¡Tu coche RC se está saliendo fuera del alcance!
+
+[RCR1_7:RCRACE1]
+~r~¡Tu coche RC se salió del alcance!
+
+{=================================== MISSION TABLE ROCK1 ===================================}
+
+[RBM1_A:ROCK1]
+~n~
+
+[RBM1_B:ROCK1]
+¡Brillante, jodidamente brillante!
+
+[RBM1_D:ROCK1]
+¿Eh, habías conocido antes a los Love Fist?
+
+[RBM1_E:ROCK1]
+No, pero siempre me encantó vuestra música.
+
+[RBM1_F:ROCK1]
+Déjame presentarte a la banda.
+
+[RBM1_G:ROCK1]
+Estos son P, Percy, Dick, y Willy está en el kaze, y ese de antes de la cabina era Jezz,
+
+[RBM1_H:ROCK1]
+y tíos, quiero que conozcáis a un buen amigo mío.
+
+[RBM1_I:ROCK1]
+Este es Tommy. Nos conocemos desde hace mucho.
+
+[RBM1_J:ROCK1]
+De acuerdo, colega.
+
+[RBM1_K:ROCK1]
+Y, eh, ¿cuál era tu nombre?
+
+[RBM1_L:ROCK1]
+Déjalo, Jezz, lo recuerdas,
+
+[RBM1_M:ROCK1]
+no juegues a eso conmigo, colega,
+
+[RBM1_N:ROCK1]
+¡soy demasiado astuto para eso, encanto!
+
+[RBM1_O:ROCK1]
+Verás, Tom, la cosa es que los chicos necesitan algo de ayuda.
+
+[RBM1_P:ROCK1]
+No tienen muchos contactos en la zona, gente a la que preguntarle ''¿vienes mucho por aquí?'' y todo eso.
+
+[RBM1_Q:ROCK1]
+¡Necesitamos unos tiritos, colega!
+
+[RBM1_R:ROCK1]
+¿Vamos a pillar la vieja furia Love Fist, sabes?
+
+[RBM1_S:ROCK1]
+Bueno, esto es Vice City, tío. ¿Cuál es el problema?
+
+[RBM1_U:ROCK1]
+¡Love juice, tío!
+
+[RBM1_V:ROCK1]
+¿Love juice?
+
+[RBM1_W:ROCK1]
+Sí, dos partes de boomshine, una parte de farlopa, cinco caramelos con picapica y un litro de gasolina.
+
+[RBM1_X:ROCK1]
+¿Puedes ayudarnos, colega?
+
+[RBM1_Y:ROCK1]
+De verdad significaría mucho para los chicos.
+
+[RBM1_Z:ROCK1]
+Puedes hacer eso por los muchachos, ¿verdad?
+
+[RBM1_7:ROCK1]
+~r~¡No conseguiste a tiempo el ''love juice''!
+
+[RBM1_8:ROCK1]
+~r~¡Mercedes está muerta!
+
+[RBM1_10:ROCK1]
+~r~¡Idiota! ¡Has destruido el material!
+
+[RBM1_13:ROCK1]
+~g~Lleva el ''love juice'' y a Mercedes a la banda antes de que sean requeridos en el escenario.
+
+[RBM1_15:ROCK1]
+~r~¡Has perdido al camello, nuestra pasta y la nieve!
+
+[RBM1_17:ROCK1]
+~g~¡Mata al camello y consigue los ingredientes!
+
+[MOB_07A:ROCK1]
+Eh colega, a los chicos les vendría bien algo de compañía, si entiendes lo que quiero decir...
+
+[MOB_07B:ROCK1]
+Conozco a la chica apropiada.
+
+[ROK1_5:ROCK1]
+¡Hola, Mercedes!
+
+[ROK1_6:ROCK1]
+Hola, Tommy. ¿Cómo estás?
+
+[ROK1_7:ROCK1]
+Bien. Escucha, ¿te apetece acostarte con los Love Fist?
+
+[ROK1_8:ROCK1]
+De acuerdo, pero sólo como un favor que espero que me sea devuelto...
+
+[RBM1_14:ROCK1]
+~g~¡Necesitas un coche o una moto!
+
+[RBM1_1:ROCK1]
+~g~Ve y recoge a Mercedes en su apartamento.
+
+[RBM1_12:ROCK1]
+~g~Ve y reúnete con el camello para conseguir los ingredientes del ''love juice''.
+
+[ROK1_2:ROCK1]
+YA NO ES NECESARIO
+
+[ROK1_3:ROCK1]
+YA NO ES NECESARIO
+
+[MERC_39:ROCK1]
+Hasta luego grandullón.
+
+[RBM1_C:ROCK1]
+¡Eh, Tommy! Me alegro que pudieras venir.
+
+[RBM1_9:ROCK1]
+~g~¡Ve y reúnete con el camello de los Love Fist para conseguir algo de ''love juice''!
+
+[ROK1_1A:ROCK1]
+¿Buscas algo especial? ¡Yo tengo lo que necesitas!
+
+[ROK1_9:ROCK1]
+¡Gracias por el dinero, mamón!
+
+[RBM1_T:ROCK1]
+Necesitamos ''love juice'', tío, ¿sabes?
+
+{=================================== MISSION TABLE ROCK2 ===================================}
+
+[RBM2_A:ROCK2]
+Tommy, tío. ¡Me alegro de verte!
+
+[RBM2_B:ROCK2]
+¿Qué sucede?
+
+[RBM2_C:ROCK2]
+Malas vibraciones, Tommy...
+
+[RBM2_E:ROCK2]
+Hay un tipo, apenas le conocemos, pero él nos conoce a nosotros.
+
+[RBM2_F:ROCK2]
+Como este tipo, que lo sabe todo de nosotros.
+
+[RBM2_G:ROCK2]
+Sabe que a Willy le gusta ponerse ropa interior de mujeres.
+
+[RBM2_H:ROCK2]
+¡O que a Percy le gusta Duran Duran!
+
+[RBM2_K:ROCK2]
+Sí, bien, tu cohete del amor. Pero escucha, este tipo...
+
+[RBM2_L:ROCK2]
+El tipo, quiere ver a los Love Fist muertos.
+
+[RBM2_M:ROCK2]
+Muertos, Tommy.
+
+[RBM2_N:ROCK2]
+El final Love Fist. Ya sabes lo que dicen, los buenos mueren jóvenes.
+
+[RBM2_O:ROCK2]
+¡Pero Tommy, tienes que salvar a los Love Fist!
+
+[RBM2_P:ROCK2]
+Tenemos que firmar en dos horas y creo...
+
+[RBM2_Q:ROCK2]
+Los chicos creen que el sospechoso va a intentar hacer algún recibimiento infame.
+
+[RBM2_1:ROCK2]
+~g~Conduce la limusina a la firma de autógrafos e intenta encontrar al psicópata.
+
+[RBM2_2:ROCK2]
+~r~¡Destrozaste el coche de la banda!
+
+[RBM2_3:ROCK2]
+~g~¡Ve a la firma de autógrafos!
+
+[RBM2_4:ROCK2]
+~g~¡Atrapa al psicópata! ¡No le dejes escapar!
+
+[RBM2_5:ROCK2]
+~r~¡Lo perdiste, idiota!
+
+[RBM2_7:ROCK2]
+~r~¡Los fans han sido atacados, el psicópata no aparecerá!
+
+[RBM2_8:ROCK2]
+~r~¡Los guardas de seguridad han sido atacados, el psicópata no aparecerá!
+
+[PSYCH_1:ROCK2]
+¡Me encantaría ver arder a los Love Fist!
+
+[PSYCH_2:ROCK2]
+¡Los Love Fist arruinaron mi vida!
+
+[RBM2_I:ROCK2]
+Cállate, idiota. Sólo porque Jezz se folla ovejas.
+
+[RBM2_R:ROCK2]
+¡Eh, cierra la boca!
+
+[RBM2_D:ROCK2]
+Sí, no estoy de broma, es un tema muy gordo tío, muy gordo, ¿sabes?
+
+[RBM2_J:ROCK2]
+Es lo que atrae a mi cohete del amor, ¿entiendes?
+
+{=================================== MISSION TABLE ROCK3 ===================================}
+
+[RBM3_A:ROCK3]
+¡Tommy! ¡Tommy! ¡Tommy, tío, ese psicópata ha vuelto!
+
+[RBM3_B:ROCK3]
+¿Qué está pasando?
+
+[RBM3_C:ROCK3]
+¡Ese psicópata no dejará en paz a los Love Fist!
+
+[RBM3_D:ROCK3]
+No le mataste, tío. Y ahora ha vuelto.
+
+[RBM3_E:ROCK3]
+Sí, sí, sí, y la cuestión es...
+
+[RBM3_F:ROCK3]
+La cuestión es que necesitamos alguien en quien poder confiar para que conduzca la limo,
+
+[RBM3_G:ROCK3]
+¡porque ese chiflado sigue con las amenazas!
+
+[RBM3_I:ROCK3]
+Aquí estamos todos acojonados, tío.
+
+[RBM3_J:ROCK3]
+De acuerdo tíos, calmaos, yo me encargaré de esto.
+
+[RBM3_K:ROCK3]
+Normalmente, no me ocuparía de ir por ahí haciendo de chófer para una panda de bisexuales escoceses bebidos,
+
+[RBM3_L:ROCK3]
+pero, en vuestro caso, haré una excepción.
+
+[RBM3_4:ROCK3]
+~r~¡Has matado a los Love Fist!
+
+[RBM3_6:ROCK3]
+DETONACIÓN:
+
+[RBM3_1:ROCK3]
+~g~Conduce a los Love Fist al local del concierto.
+
+[RBM3_2:ROCK3]
+Si intentas abandonar el coche mientras la bomba está armada explotará...
+
+[RBM3_3:ROCK3]
+Si la barra de detonación se llena completamente la bomba explotará.
+
+[RBM3_8:ROCK3]
+Cuanto más rápido conduzcas más despacio se moverá la barra de detonación.
+
+[RBM3_7:ROCK3]
+~g~¡BOMBA DESACTIVADA!
+
+[ROK3_62:ROCK3]
+y pensamos que podríamos enseñarte nuestro Templo del Rock.
+
+[ROK3_63:ROCK3]
+¡Para que te vayas acostumbrando a la furia de Love Fist!
+
+[ROK3_64:ROCK3]
+Escúchate a ti mismo, tío. Es papel maché y cinta aislante.
+
+[ROK3_65:ROCK3]
+Eh, para los chavales, ¡esto es un templo y nosotros somos los sacerdotes!
+
+[ROK3_66:ROCK3]
+Si, vale, si a los chavales les gustan los sacerdotes colgados y sin oído musical,
+
+[ROK3_67:ROCK3]
+¿quién soy yo para discutirlo?
+
+[ROK3_68:ROCK3]
+Vaya por Dios, se está comiendo la cinta otra vez.
+
+[ROK3_69:ROCK3]
+Con este ritmo tendremos que tocar en directo.
+
+[ROK3_70:ROCK3]
+Oohh ¡mierda! Mis tripas...
+
+[ROK3_73:ROCK3]
+Jezz está escuchando la cinta,
+
+[RBM3_9:ROCK3]
+Si te paran o reduces la velocidad la barra de detonación aumentará.
+
+[RBM3_H:ROCK3]
+¡Me estoy cagando de miedo tío. Necesito a mi, mamá!
+
+[ROK3_71:ROCK3]
+Tenemos que seguir con esto. Gracias de nuevo Tommy, ya sabes lo que quiero decir, apúntate una, ¡adiós!
+
+[ROK3_1:ROCK3]
+Al fin tío, hora de un merecido trago. La sala de conciertos está solo a unos cientos de metros calle abajo.
+
+[ROK3_2:ROCK3]
+Mejor ponme uno doble. Eh Tommy, cambia los temas, tío.
+
+[ROK3_3:ROCK3]
+Me siento perdido si la cabeza no me estalla. Ah, mira, ¿Qué es esto? Eh Tommy, pon esta cinta.
+
+[ROK3_4:ROCK3]
+Love Fist. Vuestro tiempo contaminando las ondas se ha terminado. Os di la oportunidad de ser amigos.
+
+[ROK3_5:ROCK3]
+Ahora os doy la oportunidad de morir. ¡Intentad aminorar la marcha y vuestra limusina explotará junto con vuestros GRANDES Y PELUDOS CULOS!
+
+[ROK3_6:ROCK3]
+Tommy amigo, ¡tienes que salvar a la banda! Yo me estoy cansando de esto. ¡Mantén pisado el acelerador!
+
+[ROK3_7:ROCK3]
+¡Tenemos que encontrar la bomba! ¿Podremos conducir por ahí todo el día? Sí, tenemos suficiente bebida..
+
+[ROK3_8:ROCK3]
+¿La bomba no estará en el motor? Tendremos que parar y cogerla. ¡Vamos a morir todos! ¡Me voy a emborrachar!
+
+[ROK3_9:ROCK3]
+Eh, ¡amigo, aquí hay cola! ¡La respuesta no está en el mueble bar! ¡Sal de mi camino!
+
+[ROK3_10:ROCK3]
+Eh, ¡a la botella de vodka le salen unos cables! ¡Eso no es vodka!, ¡Eso es una BOMBA!
+
+[ROK3_11:ROCK3]
+¡Y está preparada para explotar!
+
+[ROK3_12:ROCK3]
+Siempre me dijeron que la bebida acabaría conmigo. He visto esto en la tele. Tienes que tirar de uno de los cables. ¿De qué cable? Pues no sé tío.
+
+[ROK3_13:ROCK3]
+No tengo ni idea. Willy, di algo. Voy a tocar el bajo en el otro mundo.
+
+[ROK3_14:ROCK3]
+Tommy tío, sigue conduciendo deprisa, amigo. Que alguien haga algo. Si, ¡qué listo!
+
+[ROK3_15:ROCK3]
+''Que alguien haga algo'', qué mierda es esa, he visto a niñas con más valor. Tipo duro, haz tú algo.
+
+[ROK3_16:ROCK3]
+Mira tío, yo toco un instrumento y no tengo ni idea de desactivar bombas. Willy podrías beberte el líquido de la bomba con una pajita.
+
+[ROK3_17:ROCK3]
+Sí, he oído que eres bueno en ese tipo de cosas. ¡Eh, aquella noche estaba muy colgado, como bien sabes!
+
+[ROK3_18:ROCK3]
+¡Anda pásale una pajita a Willy! ¿Una pajita? ¡Este es el autobús de la gira de los Love Fist!
+
+[ROK3_19:ROCK3]
+¿De dónde voy a sacar yo una pajita? ¿me entiendes? ¿Qué cable Tommy? El verde. No hay ninguno verde.
+
+[ROK3_20:ROCK3]
+¿O es que este es verde? ¿Te parece verde alguno de estos cables?
+
+[ROK3_21:ROCK3]
+¡Oh no! ¡La muerte está en las cartas! ¡Todo parece verde! Tenía que haberos dejado tirados cuando tuve la oportunidad.
+
+[ROK3_22:ROCK3]
+Buscador de gloria. Capitalista. He estado tirando de ti durante años. Cállate. Eres un espantajo.
+
+[ROK3_23:ROCK3]
+Una nena grande y chillona. Sí. Cállate y tira del cable. ¿Qué cable? Este...
+
+[ROK3_24:ROCK3]
+¡NO, tío! estamos bien. ¡No hemos saltado por los aires, amigo.
+
+[ROK3_25:ROCK3]
+Tommy, tío, chachi. Rock and roll, tío. ¿No tenemos que actuar?
+
+[ROK3_26:ROCK3]
+¿Meter bulla? ¿Abusar de las fans? ¡LOVE FIST!
+
+[ROK3_27:ROCK3]
+¿Has terminado con esa botella?
+
+{=================================== MISSION TABLE SERG1 ===================================}
+
+[TEX1_A:SERG1]
+Entra y disfruta de los asientos de cuero, hijo.
+
+[TEX1_B:SERG1]
+Demonios, mi padre solía decir, a caballo regalado no le mires el diente, y por Dios que nunca lo hizo.
+
+[TEX1_C:SERG1]
+¿Te gustaría un trago del viejo Kentucky?
+
+[TEX1_D:SERG1]
+No gracias.
+
+[TEX1_E:SERG1]
+Alguien con la mente despejada, me gusta eso.
+
+[TEX1_F:SERG1]
+El negocio de la propiedad no se trata solo de papeleo pretencioso.
+
+[TEX1_G:SERG1]
+¡Se trata de tierra! ¡Y el derecho a reclamarla! ¿Me sigues, hijo?
+
+[TEX1_H:SERG1]
+Sí.
+
+[TEX1_J:SERG1]
+Y yo creo que eres la clase de tío para persuadirle.
+
+[TEX1_K:SERG1]
+La persuasión es mi fuerte.
+
+[TEX1_L:SERG1]
+Sí, estará en el club de campo, en el campo de golf.
+
+[TEX1_M:SERG1]
+Allí no permiten armas, así que sus guardaespaldas no llevarán protección.
+
+[TEX1_N:SERG1]
+Ve y dale una paliza inolvidable.
+
+[TEX1_O:SERG1]
+Bien, toma... te he conseguido un carné de socio, y chico, vas a necesitar un tipo de ropa más apropiada.
+
+[TEX1_2:SERG1]
+~g~Ahora ve al Club de golf Leaf Links.
+
+[TEX1_0:SERG1]
+~g~El objetivo está en el campo de prácticas disfrutando de una partida de golf. ¡Asegúrate de que sea la última!
+
+[TEX1_3:SERG1]
+¿Quién es este tipo? Chicos, ocuparos de él.
+
+[TEX1_6:SERG1]
+¡Bonito culo nena!
+
+[TEX1_7:SERG1]
+¿Este soy yo?
+
+[TEX1_I:SERG1]
+Bueno, necesito algún cabrón obstinado que suelte algo de mierda.
+
+[TEX1_8:SERG1]
+Cada vez que subas a un Caddy recibirás automáticamente un palo de golf, siempre que la ranura de armas blancas esté vacía.
+
+[TEX1_9:SERG1]
+¡Atrapadle!
+
+[TEX1_10:SERG1]
+¡Mata a ese psicópata!
+
+[TEX1_1:SERG1]
+~g~Ve y consigue ropa de golf en Jocksports.
+
+{=================================== MISSION TABLE SERG2 ===================================}
+
+[TEX_2A:SERG2]
+~g~¡Excelente! ¡Te han visto!
+
+[TEX_2B:SERG2]
+~r~¡Idiota! ¡La gente debe PRESENCIAR a un cubano haciendo el trabajito!
+
+[TEX_2C:SERG2]
+~g~¡Ve y consígue algo con los colores de la banda cubana en Little Havana!
+
+[TEX_2D:SERG2]
+~g~¡Ahora elimina al capo de la banda haitiana en la Funeraria de Romero!
+
+[TEX2_A:SERG2]
+Tommy, este es Donald Love. Donald, te presento a Tommy Vercetti,
+
+[TEX2_B:SERG2]
+el último tirador más rápido en llegar a estos lares.
+
+[TEX2_C:SERG2]
+Si... eh...
+
+[TEX2_D:SERG2]
+Donald, ahora cállate y escucha, puede que aprendas algo.
+
+[TEX2_E:SERG2]
+Veamos. Nada hace que los precios de las propiedades bajen más rápido que una guerra entre bandas al viejo estilo.
+
+[TEX2_F:SERG2]
+Excepto un desastre quizás, como la peste de la que habla la biblia o algo así,
+
+[TEX2_G:SERG2]
+aunque puede que en este caso vayamos demasiado lejos.
+
+[TEX2_H:SERG2]
+¿Te estás enterando, capullo cuatro ojos?
+
+[TEX2_I:SERG2]
+Hace poco murió un capo de una banda haitiana. Al parecer lo hicieron los cubanos, nadie lo sabe.
+
+[TEX2_J:SERG2]
+¡Pero se lo haremos saber! Disfrázate de cubano
+
+[TEX2_K:SERG2]
+y ve a reventar el funeral. Crea confusión y después le sigues bien de cerca.
+
+[TEX2_L:SERG2]
+¿Te estás enterando, Donald?
+
+[TEX2_M:SERG2]
+Eso debería meter al zorro en el gallinero. ¿Eh?
+
+[TEX2_N:SERG2]
+y ahora sólo tenemos que sentarnos a esperar y ver cómo caen los precios.
+
+[TEXEXIT:SERG2]
+~g~¡Lárgate de Little Haiti ahora!
+
+{=================================== MISSION TABLE SERG3 ===================================}
+
+[TEX3_A:SERG3]
+Bien, mira, hijo. Tengo un problema y creo que podrías ayudarme con él.
+
+[TEX3_B:SERG3]
+No soy constructor.
+
+[TEX3_C:SERG3]
+No, estaba pensando más bien en tus habilidades para la demolición.
+
+[TEX3_D:SERG3]
+Bien, esto de aquí es el centro empresarial tal y como se ha planeado, y éste
+
+[TEX3_E:SERG3]
+es el solar que estamos buscando.
+
+[TEX3_F:SERG3]
+Intentas decir que este nuevo bloque de oficinas está en medio.
+
+[TEX3_G:SERG3]
+Lo captas rápido.
+
+[TEX3_H:SERG3]
+Bien, voy a irme de esta ciudad durante un tiempo
+
+[TEX3_I:SERG3]
+y si ese centro de oficinas se enfrentase a problemas estructurales repentinos e insalvables, entonces yo...
+
+[TEX3_J:SERG3]
+¿Como buen ciudadano se sentirá obligado a intervenir y
+
+[TEX3_K:SERG3]
+salvar la remodelación de una zona tan importante de la ciudad?
+
+[TEX3_L:SERG3]
+¿Dónde puedo conseguir más tipos como tú?
+
+[TEX3_1:SERG3]
+~g~Utiliza el helicóptero RC para transportar las bombas a los cuatro objetivos del edificio que debes demoler.
+
+[TEX3_2:SERG3]
+~g~Debes colocar una bomba en cada objetivo. Puedes colocarlas en cualquier orden.
+
+[TEX3_3:SERG3]
+~g~Para recoger una bomba, dirige el helicóptero RC hasta a ella. Solo puedes llevar las bombas de una en una.
+
+[TEX3_4:SERG3] { reVC update }
+~g~Para soltar una bomba pulsa ~h~~k~~VEHICLE_FIREWEAPON~~g~.
+
+[TEX3_5:SERG3]
+~g~Si fallas al colocar una bomba podrás recogerla e intentarlo de nuevo.
+
+[TEX3_6:SERG3]
+~g~Cuando hayas recogido una bomba por primera vez, el temporizador de detonación se pondrá en marcha.
+
+[TEX3_7:SERG3]
+~g~¡A continuación deberás conseguir colocar el resto de las bombas en 7 minutos!
+
+[TEX3_8:SERG3]
+~g~¡Has fallado en el objetivo! ¡Recoge la bomba e inténtalo de nuevo!
+
+[TEX3_10:SERG3]
+~g~Suelta la bomba en el objetivo.
+
+[TEX3_11:SERG3]
+objetivos restantes:
+
+[TEX3_17:SERG3]
+~r~¡Te has quedado sin tiempo!
+
+[TEX3_18:SERG3]
+~r~¡Tu helicóptero RC ha sido destruido!
+
+[TEX3_19:SERG3]
+~r~¡Has lanzado la bomba en el agua! ¡Esa no es manera de pescar!
+
+[TEX3_20:SERG3]
+~g~¡Tu Helicóptero RC está casi fuera del alcance del control remoto!
+
+[TEX3_21:SERG3]
+~r~¡Tu Helicóptero RC está fuera del alcance del control remoto!
+
+[TEX3_24:SERG3]
+Pulsa ~h~~k~~VEHICLE_LOOKLEFT~ ~w~para girar el helicóptero en sentido contrario a las agujas del reloj.
+
+[TEX3_25:SERG3]
+Pulsa ~h~~k~~VEHICLE_LOOKLEFT~ ~w~para girar el helicóptero en sentido de las agujas del reloj.
+
+[TEX3_27:SERG3]
+~g~Una escalera central permite el acceso a todas las plantas del edificio.
+
+[TEX3_31:SERG3]
+~r~¡Has destruido la furgoneta de TOPFUN que tenía las bombas y el helicóptero RC!
+
+[TEX3_32:SERG3]
+Puedes ~h~mirar atrás~w~ si ~h~pulsas simultáneamente ~k~~VEHICLE_LOOKLEFT~ y ~k~~VEHICLE_LOOKRIGHT~~w~.
+
+[TEX3_29:SERG3] { reVC update }
+~g~Para soltar una bomba pulsa ~h~~k~~VEHICLE_FIREWEAPON~~g~.
+
+[TEX3_26:SERG3]
+Pulsa ~h~~k~~VEHICLE_BRAKE~~w~ para disminuir la velocidad del rotor y ~h~descender~w~.
+
+[TEX3_22:SERG3]
+Pulsa ~h~~k~~VEHICLE_ACCELERATE~~w~ para aumentar la velocidad del rotor y así ~h~ascender~w~.
+
+[TEX3_16:SERG3]
+~g~Ve a la furgoneta ~w~TOPFUN ~g~cercana al solar de construcción que se va a demoler.
+
+[TEX3_33:SERG3]
+Una vez que recojas una bomba el radar te mostrará la posición del objetivo con relación al helicóptero RC.
+
+[TEX3_34:SERG3]
+Un ~h~icono triangular apuntando hacia arriba ~w~indica que el objetivo está ~h~por encima ~w~del helicóptero RC.
+
+[TEX3_35:SERG3]
+Un ~h~icono triangular apuntando hacia abajo ~w~indica que el objetivo está ~h~por debajo ~w~del helicóptero RC.
+
+[TEX3_36:SERG3]
+Un ~h~icono cuadrado ~w~indica que el objetivo está al ~h~mismo nivel ~w~que el helicóptero RC.
+
+[TEX3_28:SERG3]
+Para ~h~recoger una bomba~w~, simplemente dirige el helicóptero RC hasta ella. El helicóptero RC sólo puede transportar una bomba.
+
+[TEX3_30:SERG3]
+~g~Para recoger una bomba, simplemente dirige el helicóptero RC hasta ella. El helicóptero RC sólo puede transportar una bomba.
+
+[TEX3_12:SERG3]
+~g~¡Bomba colocada! ¡Quedan 3 objetivos más! Vuelve a por otra bomba.
+
+[TEX3_13:SERG3]
+~g~¡Bomba colocada! ¡Quedan 2 objetivos más! Vuelve a por otra bomba.
+
+[TEX3_14:SERG3]
+~g~¡Bomba colocada! ¡Queda 1 objetivo más! Vuelve a por otra bomba.
+
+[TEX3_15:SERG3]
+~r~¡El temporizador de detonación se ha puesto en marcha! ~g~Debes colocar las ~w~4 bombas ~g~en el tiempo restante!
+
+[TEX3_37:SERG3]
+Si empujas ~h~el joystick analógico derecho hacia atrás~w~, aumentarás la velocidad del rotor y así ~h~ascenderá~w~.
+
+[TEX3_38:SERG3] { reVC update }
+{Pulsa ~h~~k~~VEHICLE_ACCELERATE~~w~ para aumentar la velocidad del rotor y así ~h~ascender~w~.}
+Si empujas ~h~el joystick analógico derecho hacia adelante ~w~la velocidad del rotor aumenta, haciendo que el helicóptero ~h~descienda.
+
+[TEX3_39:SERG3]
+~g~Para soltar una bomba pulsa ~h~~k~~VEHICLE_HANDBRAKE~~w~.
+
+[TEX3_40:SERG3]
+~g~Para soltar una bomba pulsa ~h~~k~~VEHICLE_HANDBRAKE~~w~.
+
+[TEX3_23:SERG3]
+Pulsa ~h~~k~~VEHICLE_TURRETUP~~w~ y ~h~~k~~VEHICLE_TURRETDOWN~~w~ para inclinar el helicóptero en la dirección deseada.
+
+{=================================== MISSION TABLE TAXI1 ===================================}
+
+[FARES:TAXI1]
+CARRERAS:
+
+[TAXI1:TAXI1]
+~g~Busca un cliente.
+
+[TSCORE2:TAXI1]
+~1~ $
+
+[IN_ROW:TAXI1]
+~1~ ¡Racha de clientes! ~1~ $
+
+[TAXI3:TAXI1]
+~r~¡Tu pasajero huye aterrorizado!
+
+[TAXI7:TAXI1]
+~r~Tu coche está destrozado, haz que lo reparen.
+
+[TAXI4:TAXI1]
+¡Viaje completado!
+
+[TAXI5:TAXI1]
+¡VIAJE RÁPIDO!
+
+[TAXI6:TAXI1]
+Misión de taxista cancelada
+
+[TAXIH1:TAXI1]
+Detente cerca de un peatón que esté resaltado para recogerle y llevarle a su destino antes de que se agote el tiempo.
+
+[FARE1:TAXI1]
+~g~Destino ~w~''el club Pole Position'' ~g~en Ocean Beach.
+
+[FARE3:TAXI1]
+~g~Destino ~w~''el club náutico'' ~g~en Ocean Beach.
+
+[FARE4:TAXI1]
+~g~Destino ~w~''Ammu-Nation'' ~g~en Ocean Beach.
+
+[FARE5:TAXI1]
+~g~Destino ~w~''la ferretería'' ~g~en Washington Beach.
+
+[FARE6:TAXI1]
+~g~Destino ~w~''el centro comercial North Point'' ~g~en Vice Point.
+
+[MFARE1:TAXI1]
+~g~Destino ~w~''Ammu-Nation'' ~g~en el centro.
+
+[MFARE2:TAXI1]
+~g~Destino ~w~''la terminal'' ~g~en el aeropuerto Escobar International.
+
+[WFARE3:TAXI1]
+~g~Destino ~w~''Coches Sunshine'' ~g~en Little Havana.
+
+[WFARE4:TAXI1]
+~g~Destino ~w~''Taxis Kaufman'' ~g~en Little Haiti.
+
+[WFARE5:TAXI1]
+~g~Destino ~w~''la ferretería'' ~g~en Little Havana.
+
+[WFARE6:TAXI1]
+~g~Destino ~w~''Emporio Howlin Petes Bike'' ~g~en el centro.
+
+[FARE7:TAXI1]
+~g~Destino ~w~''la joyería'' ~g~en Vice Point.
+
+[FARE8:TAXI1]
+~g~Destino ~w~''la playa'' ~g~en Ocean Beach.
+
+[FARE9:TAXI1]
+~g~Destino ~w~''la playa'' ~g~en Washington Beach.
+
+[FARE10:TAXI1]
+~g~Destino ~w~''la playa'' ~g~en Vice Point.
+
+[FARE11:TAXI1]
+~g~Destino ~w~''el hospital'' ~g~en Ocean Beach.
+
+[FARE12:TAXI1]
+~g~Destino ~w~''el hospital'' ~g~en Vice Point.
+
+[FARE13:TAXI1]
+~g~Destino ~w~''la comisaría de policía'' ~g~en Washington Beach.
+
+[FARE14:TAXI1]
+~g~Destino ~w~''la comisaría de policía'' ~g~en Vice Point.
+
+[FARE15:TAXI1]
+~g~Destino ~w~''la pizzería'' ~g~en Vice Point.
+
+[WFARE7:TAXI1]
+~g~Destino ~w~''la comisaría de policía'' ~g~en Little Havana.
+
+[WFARE8:TAXI1]
+~g~Destino ~w~''la comisaría de policía'' ~g~en el centro de la ciudad.
+
+[WFARE9:TAXI1]
+~g~Destino ~w~''el hospital'' ~g~en el centro de la ciudad.
+
+[WFARE10:TAXI1]
+~g~Destino ~w~''el hospital'' ~g~en Little Havana.
+
+[WFARE11:TAXI1]
+~g~Destino ~w~''el estadio'' ~g~en el centro de la ciudad.
+
+[WFARE12:TAXI1]
+~g~Destino ~w~''la pizzería'' ~g~en Little Haiti.
+
+[WFARE13:TAXI1]
+~g~Destino ~w~''la pizzería'' ~g~en el centro de la ciudad.
+
+[WFARE14:TAXI1]
+~g~Destino ~w~''los muelles'' ~g~en Viceport.
+
+[WFARE15:TAXI1]
+~g~Destino ~w~''la farmacia'' ~g~en Little Haiti.
+
+[FARE2:TAXI1]
+~g~Destino ~w~''el club Malibú'' ~g~en Vice Point.
+
+{=================================== MISSION TABLE TAXICUT ===================================}
+
+[TAXC_A:TAXICUT]
+Supongo que eres el nuevo propietario.
+
+[TAXC_B:TAXICUT]
+¿Qué eres, mafioso? ¿Del cártel? No pareces mejicano...
+
+[TAXC_C:TAXICUT]
+En fin, será mejor que sueltes el rollo de ''las cosas van a cambiar por aquí'',
+
+[TAXC_D:TAXICUT]
+quizás amenazar a alguno de los conductores...
+
+[TAXC_E:TAXICUT]
+ve con calma con Ted, el de ahí, acaban de curarle la hernia.
+
+[TAXC_F:TAXICUT]
+Bueno, sí. Las cosas van a cambiar por aquí, señora.
+
+[TAXC_G:TAXICUT]
+Oh, mierda, hijo. Anda dejarme esto a mí...
+
+[TAXC_H:TAXICUT]
+Llevo haciéndolo años.
+
+[TAXC_I:TAXICUT]
+Ahora oíd esto.
+
+[TAXC_J:TAXICUT]
+Ahora tenemos una nueva dirección y las cosas van a cambiar por aquí.
+
+[TAXC_K:TAXICUT]
+Nuestra nueva dirección, los...
+
+[TAXC_L:TAXICUT]
+¿De qué banda eres?
+
+[TAXC_M:TAXICUT]
+Bueno, en realidad no formo parte de ninguna banda.
+
+[TAXC_N:TAXICUT]
+¿Cómo coño te llamas, muchacho?
+
+[TAXC_O:TAXICUT]
+Vercetti, Tommy Vercetti.
+
+[TAXC_P:TAXICUT]
+Nuestra nueva administración, la banda de Vercetti,
+
+[TAXC_Q:TAXICUT]
+se va a encargar de que no tengamos problemas.
+
+[TAXC_R:TAXICUT]
+¿Capiche? ¡Corto!
+
+[TAXC_S:TAXICUT]
+¿Te gustó el ''capiche''? A mí me gustó el ''capiche''.
+
+[TAXC_T:TAXICUT]
+Así que así es como funcionaban las cosas en el pasado,
+
+[TAXC_U:TAXICUT]
+Dirigimos la compañía como siempre.
+
+[TAXC_V:TAXICUT]
+Si tenemos algún problema con las compañías rivales, tú les das una somanta de palos.
+
+[TAXC_W:TAXICUT]
+Luego ellos nos la dan a nosotros,
+
+[TAXC_X:TAXICUT]
+y después, se la vuelves a dar a ellos,
+
+[TAXC_Y:TAXICUT]
+etcétera, etcétera. ¿Lo captas?
+
+[TAXC_Z:TAXICUT]
+Sí, supongo...
+
+[TAXC_A1:TAXICUT]
+Simplemente toma un taxi del garaje si tienes ganas de subir a bordo.
+
+{=================================== MISSION TABLE TAXIWA1 ===================================}
+
+[OUTTIME:TAXIWA1]
+~r~¡Demasiado lento, tío, demasiado lento!
+
+[TAX1_1:TAXIWA1]
+Tenemos un cliente importante que necesita que lo recojan en Starfish Island. ¿Alguien me recibe?
+
+[TAX1_2:TAXIWA1]
+¡Aquí Tommy, yo lo recogeré!
+
+[TAX1_3:TAXIWA1]
+¡Este es mi cliente, lárgate, gilipollas!
+
+[TAX1_4:TAXIWA1]
+Venga, venga, entre, ¡rápido!
+
+[TAX1_5:TAXIWA1]
+¡Vale, vale! ¡No me haga daño!
+
+[TAXW1_1:TAXIWA1]
+~g~Recoge al V.I.P. en Starfish Island.
+
+[TAXW1_2:TAXIWA1]
+~g~¡Recupera al V.I.P! ¡Destroza el otro coche!
+
+[TAXW1_3:TAXIWA1]
+~r~¡El V.I.P. está muerto!
+
+[TAXW1_4:TAXIWA1]
+~r~¡El V.I.P. se ha apeado!
+
+[TAXW1_6:TAXIWA1]
+~g~¡Lleva al V.I.P. al aeropuerto!
+
+{=================================== MISSION TABLE TAXIWA2 ===================================}
+
+[TAX2_1:TAXIWA2]
+Llamando a todos los taxis, estamos perdiendo clientes por toda la ciudad. ¿Qué os pasa, tíos?
+
+[TAX2_2:TAXIWA2]
+Taxis VC sigue llevándonos la delantera. ¡Tienen tantos coches que no podemos competir!
+
+[TAX2_3:TAXIWA2]
+Sr. Vercetti, si está ahí escuchando, ¡tiene que poner fuera de circulación unos cuantos Taxis VC antes de que nos hundan!
+
+[TAXW2_1:TAXIWA2]
+~g~¡Destruye 3 de los taxis rivales!
+
+{=================================== MISSION TABLE TAXIWA3 ===================================}
+
+[TAX3_1:TAXIWA3]
+Coche 13, tengo a una tal Señorita Cortez, preguntó especialmente por usted.
+
+[TAX3_2:TAXIWA3]
+Vale, entendido. ¡Coche 13 en ruta!
+
+[TAX3_3:TAXIWA3]
+No hay rastro de Mercedes...
+
+[TAXW3_3:TAXIWA3]
+~g~Destrulle al taxi principal!
+
+[TAXW3_2:TAXIWA3]
+~g~Permanece con vida hasta que se agote el temporizador.
+
+[TAX_AS1:TAXIWA3]
+COMPAÑÍA DE TAXIS CONSOLIDADA
+
+[TAX_AS2:TAXIWA3]
+~g~Los taxis Kaufman generarán ahora unos ingresos de hasta ~1~ $ máximo. Asegúrate de recaudarlos regularmente.
+
+[TAX3_4:TAXIWA3]
+¡Es hora que el ángel guardián de Taxis Kaufman coma algo del parachoques!
+
+[TAX3_5:TAXIWA3]
+¡Eh chico te voy a zurrar la badana!
+
+{ reVC updates }
{ new languages }
[FEL_JAP]
JAPONÉS
@@ -7998,7 +14274,7 @@ RUSO
{ new display menus }
[FET_GFX]
-AJUSTES GRÁFICOS
+CONFIGURACIÓN DE GRÁFICOS
[FED_MIP]
MIPMAPPING
@@ -8028,7 +14304,7 @@ BORDES EN CINEMÁTICAS
FORMATO DE IMAGEN
[FEM_ISL]
-USO DE MEMORIA DEL MAPA
+USO DE MEMORIA
[FEM_LOW]
BAJO
@@ -8063,10 +14339,10 @@ REPETIR MISIÓN
¿REINTENTAR?
[FED_VPL]
-RENDERIZADO DE VEHÍCULOS
+FLUJO DE VEHÍCULOS
[FED_PRM]
-ILUMINAR CONTORNOS DE PEATONES
+LUCES EN PEATONES
[FED_RGL]
BRILLO DE CARRETERAS
@@ -8078,7 +14354,7 @@ FILTRO DE COLOR
MAPAS DE LUZ DEL MUNDO
[FED_MBL]
-DESENFOQUE DE MOVIMIENTO
+DESENFOQ. MOVIMIENTO
[FEM_SIM]
SIMPLE
@@ -8101,17 +14377,11 @@ PS2
[FEM_XBX]
XBOX
-[FEM_AUT]
-AUTOM.
-
[FEC_IVP]
INVERTIR VERTICALIDAD MANDO
-[FEM_TWP]
-Poner o quitar punto de referencia
-
-[FEA_FMN]
-RADIO APAGADA
+[FEM_NON]
+NADA
[FEC_DS2]
DUALSHOCK 2
@@ -8131,36 +14401,12 @@ MANDO DE XBOX ONE
[FEC_TYP]
TIPO DE MANDO
-[FEC_CCF]
-CONFIGURACIÓN
-
-[FEC_CF1]
-AJUSTE 1
-
-[FEC_CF2]
-AJUSTE 2
-
-[FEC_CF3]
-AJUSTE 3
-
-[FEC_CF4]
-AJUSTE 4
-
-[FEC_CDP]
-CONTROLES A MOSTRAR
-
-[FEC_ONF]
-A PIE
-
-[FEC_INC]
-EN VEHÍCULO
-
-[FEC_VIB]
-VIBRACIÓN
-
[FET_AGS]
AJUSTES DE MANDO
+[FEM_AUT] { aspect ratio related }
+AUTO
+
[FEM_PED]
PED DENSITY
@@ -8168,7 +14414,6 @@ PED DENSITY
CAR DENSITY
{ end of file }
-
[DUMMY]
THIS LABEL NEEDS TO BE HERE !!!
AS THE LAST LABEL DOES NOT GET COMPILED \ No newline at end of file